X-Authentication-Warning: delorie.com: mail set sender to djgpp-bounces using -f X-Recipient: djgpp AT delorie DOT com X-Original-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:in-reply-to:references:date:message-id:subject:from:to :content-type; bh=J6sUQg5soSCdA6mjfU19w3yXSHxVtjwPq0+SgLCU6RA=; b=fhLslnDksFUsFDO5Np0IaaZ9p4mHGA9XGXoCUFcIiNDdX1rjsO/ICh6s6nzp+nISmN q+cE6tsroteCWATfuWBonSgicroeXn12IKr19H95giGImJtWxBRUwxA1Xl8pSZ6gV7Eu TEZafWZQEqU9wBl1DnTLKByV4k4kFwfki/GNylYW4Ae7TR6xMoISNy7iXNgmWIMBsd0F 6OCbOk2A0U1Q2I3zr9hvQNP8nRrPIqBf+ozInQ+kPZOXdxtd3iw3acOspl5xON2hpdbh EzLmCETWJ+79p4vaTtuXRczQnDUFoLtjCeZSEsfqkJT4oSwvviUJwyeHWK7g+vEljC4J bhYw== MIME-Version: 1.0 X-Received: by 10.50.79.229 with SMTP id m5mr5846908igx.1.1443979458916; Sun, 04 Oct 2015 10:24:18 -0700 (PDT) In-Reply-To: References: <952a68b4-223b-4222-b456-35514bb8b7eb AT googlegroups DOT com> <561101C4 DOT 7040701 AT gmx DOT de> <56111BF6 DOT 8040408 AT gmx DOT de> Date: Sun, 4 Oct 2015 20:24:18 +0300 Message-ID: Subject: Re: dlclose not removing dependency dxes From: "Ozkan Sezer (sezeroz AT gmail DOT com) [via djgpp AT delorie DOT com]" To: djgpp AT delorie DOT com Content-Type: multipart/mixed; boundary=089e0122a3fab63a0d05214aaaf6 Reply-To: djgpp AT delorie DOT com Errors-To: nobody AT delorie DOT com X-Mailing-List: djgpp AT delorie DOT com X-Unsubscribes-To: listserv AT delorie DOT com Precedence: bulk --089e0122a3fab63a0d05214aaaf6 Content-Type: text/plain; charset=UTF-8 On 10/4/15, Ozkan Sezer wrote: > On 10/4/15, Ozkan Sezer wrote: >> On 10/4/15, Juan Manuel Guerrero (juan DOT guerrero AT gmx DOT de) [via >> djgpp AT delorie DOT com] wrote: >>> Am 04.10.2015 12:39, schrieb Juan Manuel Guerrero (juan DOT guerrero AT gmx DOT de) >>> [via djgpp AT delorie DOT com]: >>> >>> [snip] >>>> Below is a patch that will implement ref-counting for implicitly loaded >>>> modules >>>> by other ones. Please not that this ref-counting only works for >>>> dlopen/dlclose. >>>> There may be other loading mechanisms that suffer from the same issue >>>> and >>>> that >>>> will not be fixed by this modification. >>>> The patch is intended for the main branch but should work on v2_05_1 as >>>> well. [snip] > > Here are my concerns about the patch: > > > 1. It is possible that we mis-record a dep handle: dlopen() always > returns dxe_chain, i.e. the top of the open dxes list, unless it is > an already open module. Consider this deps scenario: > > a.dxe -> b.dxe -> c.dxe -> d.dxe, and additionally a.dxe -> d.dxe > > This implementation will mis-record the d.dxe as b.dxe, because we are > recording dxe_chain and not the handle itself returned by dlopen(). > Upon a dlclose() of a.dxe, d.dxe will remain open: > > dxe3gen -o a.dxe -P b.dxe -P d.dxe -U a.o > dxe3gen -o b.dxe -P c.dxe -U b.o > dxe3gen -o c.dxe -P d.dxe -U c.o > dxe3gen -o d.dxe -U d.o > > $ cat 0.c > #include > #include > > void *my_dxe1; > void *p; > > void test_dxes(void) { > if ((p = dlsym(RTLD_DEFAULT,"_func_a"))!=NULL) > printf("a.dxe still active\n"); > if ((p = dlsym(RTLD_DEFAULT,"_func_b"))!=NULL) > printf("b.dxe still active\n"); > if ((p = dlsym(RTLD_DEFAULT,"_func_c"))!=NULL) > printf("c.dxe still active\n"); > if ((p = dlsym(RTLD_DEFAULT,"_func_d"))!=NULL) > printf("d.dxe still active\n"); > } > > int main (void) { > my_dxe1 = dlopen("a.dxe",RTLD_GLOBAL); > if (!my_dxe1) { > printf("dlopen() failed\n"); > test_dxes(); > return 1; > } > dlclose(my_dxe1); > test_dxes(); > > return 0; > } > > Running a.exe prints "d.dxe still active" > The a.dxe portion of dxe_chain.txt looks like this: > dxe_chain : 0x9fa70 > next : 0x9f908 > fname : C:\A.DXE > mode : RTLD_GLOBAL > inuse : 1 > n_exp_syms : 1 > exp_table : 0x9ef00 > exp_table[0]->offset : 0 > exp_table[0]->name : _func_a > header : 0x9ee30 > section : 0x9ee40 > _fini : 48 > deps : 0x9fa40 > handle : 0x9f908 > handle->fname : C:\B.DXE > > deps : 0x9fa58 > handle : 0x9f908 > handle->fname : C:\B.DXE > > > 2. Consider the dependency chain above again, this time assume that > c.dxe or one or more of the deeper dependencies is missing: dlopen() > does not do a cleanup for implicitly opened modules and will leak > memory. > > > 3. I am not sure about this part: in dlclose(), we are first closing > the deps, and then ejecting our dxe from dxe_chain. However, recursive > dlclose() calls will modify dxe_chain, so how safe is this? I would > suggest that we first eject the handle from dxe_chain, and then do the > cleanup for its dependencies. > And another: 4. If malloc() fails for deps list, it goes to midwayerror label instead of unrecoverable and leaves discardable not freed. Here is a quick update of the patch which seems to address all four of the concerns I noted. (also attached as a file: dlopen3.patch) Certainly need more of careful eyes to detect more possible issues. Index: src/libc/dxe/dlopen.c =================================================================== RCS file: /cvs/djgpp/djgpp/src/libc/dxe/dlopen.c,v retrieving revision 1.11 diff -U 5 -p -r1.11 dlopen.c --- src/libc/dxe/dlopen.c 4 Oct 2015 10:27:28 -0000 1.11 +++ src/libc/dxe/dlopen.c 4 Oct 2015 17:15:05 -0000 @@ -36,14 +36,16 @@ #ifndef ELOOP #define ELOOP EMLINK #endif +#define DEBUG_DXE3 0 /* Prints struct __dxe_handle members. Always commited as 0. */ + /* private stack */ -typedef struct stk_node { +typedef struct __stk_node { const char *name; - struct stk_node *next; + struct __stk_node *next; } stk_node; /* Exported symbols table entry */ typedef struct { @@ -57,10 +59,16 @@ typedef struct unsigned short n_rel_relocs; unsigned short n_abs_relocs; char name [1]; /* expanded as needed */ } __attribute__((packed)) unres_table_entry; +/* This is a linked list of implicitly loaded dxe modules. */ +typedef struct __llist { + struct __dxe_handle *handle; /* last implicitly opened module */ + struct __llist *next; +} dxe_list; + /* This is the private dxe_h structure */ typedef struct __dxe_handle { struct __dxe_handle *next; /* Pointer to next module in chain */ char fname[FILENAME_MAX]; /* Full module pathname */ @@ -69,10 +77,11 @@ typedef struct __dxe_handle int n_exp_syms; /* Number of entries in export table */ exp_table_entry **exp_table; /* Exported symbols table */ char *header; /* The resident portion of header */ char *section; /* code+data+bss section */ long _fini; /* finalization */ + dxe_list *deps; /* Linked list of implicitly open module by this module or NULL */ } dxe_handle, *dxe_h; /* Last-resort symbol resolver */ void *(*_dlsymresolver) (const char *symname) = NULL; /* Last-error unresolved symbol count */ @@ -110,10 +119,12 @@ void *dlopen(const char *filename, int m char *discardable; stk_node *node; static stk_node *stk_top = NULL; + dxe_list *deps; + #ifndef __GNUC__ static int cleanup = 0; #endif _dl_unresolved_count = 0; @@ -205,10 +216,11 @@ found: /* O.k, fill the module handle structure */ strcpy(dxe.fname, realfn); dxe.inuse = 1; dxe.mode = mode; dxe.n_exp_syms = dxehdr.n_exp_syms; + dxe.deps = NULL; /* Read DXE tables and the data section */ hdrsize = dxehdr.symbol_offset - sizeof(dxehdr); discardsize = dxehdr.dep_size + dxehdr.unres_size + dxehdr.nrelocs * sizeof(long); if ((dxe.header = malloc(hdrsize + dxehdr.sec_size)) == NULL) @@ -240,26 +252,49 @@ found: /* Fill the unfilled portion of code+data+bss segment with zeros */ memset(dxe.section + dxehdr.sec_f_size, 0, dxehdr.sec_size - dxehdr.sec_f_size); /* Load the dependencies */ scan = discardable; - for (i = 0; i < dxehdr.n_deps; i++) + for (deps = NULL, i = 0; i < dxehdr.n_deps; i++) { stk_node tmp; + dxe_h dep_h; + tmp.name = realfn; tmp.next = stk_top; stk_top = &tmp; - if (dlopen(scan, RTLD_GLOBAL) == NULL) + if ((dep_h = dlopen(scan, RTLD_GLOBAL)) == NULL) { stk_top = tmp.next; goto unrecoverable; } + else + { + dxe_list *next; + + stk_top = tmp.next; - stk_top = tmp.next; + scan = strchr(scan, 0) + 1; - scan = strchr(scan, 0) + 1; + /* Register all implicitly open modules by this one. */ + if ((next = malloc(sizeof(dxe_list))) == NULL) + { + errno = ENOMEM; + goto unrecoverable; + } + next->handle = dep_h; + next->next = NULL; + + if (deps) + { + deps->next = next; + deps = deps->next; + } + else + dxe.deps = deps = next; + } } /* Allright, now we're ready to resolve all unresolved symbols */ _dl_unresolved_count = dxehdr.n_unres_syms; _dl_unresolved_symbol[0] = 0; @@ -325,10 +360,50 @@ found: errno = ENOMEM; goto midwayerror; } memcpy(dxe_chain, &dxe, sizeof(dxe_handle)); +#if (DEBUG_DXE3 -0) == 1 + { + FILE *f = fopen("c:/tmp/dxe_chain.txt", "a"); + + if (f) + { + fprintf(f, "dxe_chain : 0x%p\n" + " next : 0x%p\n" + " fname : %s\n" + " mode : %s\n" + " inuse : %d\n" + " n_exp_syms : %d\n" + " exp_table : 0x%p\n", + dxe_chain, dxe_chain->next, dxe_chain->fname, + dxe_chain->mode == RTLD_LAZY ? "RTLD_LAZY" : + dxe_chain->mode == RTLD_NOW ? "RTLD_NOW" : + dxe_chain->mode == RTLD_LOCAL ? "RTLD_LOCAL" : + dxe_chain->mode == RTLD_GLOBAL ? "RTLD_GLOBAL" : "unknown", + dxe_chain->inuse, dxe_chain->n_exp_syms, dxe_chain->exp_table); + for (i = 0; i < dxe_chain->n_exp_syms; i++) + fprintf(f, " exp_table[%d]->offset : %ld\n" + " exp_table[%d]->name : %s\n", + i, dxe_chain->exp_table[i]->offset, i, dxe_chain->exp_table[i]->name); + fprintf(f, " header : 0x%p\n" + " section : 0x%p\n" + " _fini : %ld\n", + dxe_chain->header, dxe_chain->section, dxe_chain->_fini); + if ((deps = dxe_chain->deps)) + for (; deps; deps = deps->next) + fprintf(f, " deps : 0x%p\n" + " handle : 0x%p\n" + " handle->fname : %s\n\n", + deps, deps->handle, deps->handle->fname); + else + fprintf(f, " deps : 0x00000000\n\n"); + fclose(f); + } + } +#endif + #ifndef __GNUC__ if (!cleanup) { cleanup = !0; atexit(_closeall); @@ -340,10 +415,19 @@ found: unrecoverable: free(discardable); midwayerror: free(dxe.header); + if ((deps = dxe.deps) != NULL) + { + dxe_list *next = deps->next; + + dlclose(deps->handle); + free(deps); + deps = next; + } + return NULL; } int dlclose(void *dxe) { @@ -366,10 +450,23 @@ int dlclose(void *dxe) *cur = ((dxe_h)dxe)->next; break; } } + /* remove all implicitly loaded modules by this module. */ + { + dxe_list *deps = ((dxe_h)dxe)->deps; + while (deps) + { + dxe_list *next = deps->next; + + dlclose(deps->handle); + free(deps); + deps = next; + } + } + free(((dxe_h)dxe)->header); free(((dxe_h)dxe)->exp_table); free(dxe); return 0; -- O.S. --089e0122a3fab63a0d05214aaaf6 Content-Type: application/octet-stream; name="dlopen3.patch" Content-Disposition: attachment; filename="dlopen3.patch" Content-Transfer-Encoding: base64 X-Attachment-Id: file0 SW5kZXg6IHNyYy9saWJjL2R4ZS9kbG9wZW4uYwo9PT09PT09PT09PT09PT09PT09PT09PT09PT09 PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09ClJDUyBmaWxlOiAvY3ZzL2Rq Z3BwL2RqZ3BwL3NyYy9saWJjL2R4ZS9kbG9wZW4uYyx2CnJldHJpZXZpbmcgcmV2aXNpb24gMS4x MQpkaWZmIC1VIDUgLXAgLXIxLjExIGRsb3Blbi5jCi0tLSBzcmMvbGliYy9keGUvZGxvcGVuLmMJ NCBPY3QgMjAxNSAxMDoyNzoyOCAtMDAwMAkxLjExCisrKyBzcmMvbGliYy9keGUvZGxvcGVuLmMJ NCBPY3QgMjAxNSAxNzoxNTowNSAtMDAwMApAQCAtMzYsMTQgKzM2LDE2IEBACiAKICNpZm5kZWYg RUxPT1AKICNkZWZpbmUgRUxPT1AgRU1MSU5LCiAjZW5kaWYKIAorI2RlZmluZSBERUJVR19EWEUz IDAJLyogUHJpbnRzIHN0cnVjdCBfX2R4ZV9oYW5kbGUgbWVtYmVycy4gIEFsd2F5cyBjb21taXRl ZCBhcyAwLiAqLworCiAvKiBwcml2YXRlIHN0YWNrICovCi10eXBlZGVmIHN0cnVjdCBzdGtfbm9k ZSB7Cit0eXBlZGVmIHN0cnVjdCBfX3N0a19ub2RlIHsKICAgY29uc3QgY2hhciAqbmFtZTsKLSAg c3RydWN0IHN0a19ub2RlICpuZXh0OworICBzdHJ1Y3QgX19zdGtfbm9kZSAqbmV4dDsKIH0gc3Rr X25vZGU7CiAKIC8qIEV4cG9ydGVkIHN5bWJvbHMgdGFibGUgZW50cnkgKi8KIHR5cGVkZWYgc3Ry dWN0CiB7CkBAIC01NywxMCArNTksMTYgQEAgdHlwZWRlZiBzdHJ1Y3QKICAgdW5zaWduZWQgc2hv cnQgbl9yZWxfcmVsb2NzOwogICB1bnNpZ25lZCBzaG9ydCBuX2Fic19yZWxvY3M7CiAgIGNoYXIg bmFtZSBbMV07CQkvKiBleHBhbmRlZCBhcyBuZWVkZWQgKi8KIH0gX19hdHRyaWJ1dGVfXygocGFj a2VkKSkgdW5yZXNfdGFibGVfZW50cnk7CiAKKy8qIFRoaXMgaXMgYSBsaW5rZWQgbGlzdCBvZiBp bXBsaWNpdGx5IGxvYWRlZCBkeGUgbW9kdWxlcy4gICovCit0eXBlZGVmIHN0cnVjdCBfX2xsaXN0 IHsKKyAgc3RydWN0IF9fZHhlX2hhbmRsZSAqaGFuZGxlOwkvKiBsYXN0IGltcGxpY2l0bHkgb3Bl bmVkIG1vZHVsZSAgKi8KKyAgc3RydWN0IF9fbGxpc3QgKm5leHQ7Cit9IGR4ZV9saXN0OworCiAv KiBUaGlzIGlzIHRoZSBwcml2YXRlIGR4ZV9oIHN0cnVjdHVyZSAqLwogdHlwZWRlZiBzdHJ1Y3Qg X19keGVfaGFuZGxlCiB7CiAgIHN0cnVjdCBfX2R4ZV9oYW5kbGUgKm5leHQ7CQkvKiBQb2ludGVy IHRvIG5leHQgbW9kdWxlIGluIGNoYWluICovCiAgIGNoYXIgZm5hbWVbRklMRU5BTUVfTUFYXTsJ CS8qIEZ1bGwgbW9kdWxlIHBhdGhuYW1lICovCkBAIC02OSwxMCArNzcsMTEgQEAgdHlwZWRlZiBz dHJ1Y3QgX19keGVfaGFuZGxlCiAgIGludCBuX2V4cF9zeW1zOwkJCS8qIE51bWJlciBvZiBlbnRy aWVzIGluIGV4cG9ydCB0YWJsZSAqLwogICBleHBfdGFibGVfZW50cnkgKipleHBfdGFibGU7CQkv KiBFeHBvcnRlZCBzeW1ib2xzIHRhYmxlICovCiAgIGNoYXIgKmhlYWRlcjsJCQkJLyogVGhlIHJl c2lkZW50IHBvcnRpb24gb2YgaGVhZGVyICovCiAgIGNoYXIgKnNlY3Rpb247CQkJLyogY29kZStk YXRhK2JzcyBzZWN0aW9uICovCiAgIGxvbmcgX2Zpbmk7CQkJCS8qIGZpbmFsaXphdGlvbiAqLwor ICBkeGVfbGlzdCAqZGVwczsJCQkvKiBMaW5rZWQgbGlzdCBvZiBpbXBsaWNpdGx5IG9wZW4gbW9k dWxlIGJ5IHRoaXMgbW9kdWxlIG9yIE5VTEwgKi8KIH0gZHhlX2hhbmRsZSwgKmR4ZV9oOwogCiAv KiBMYXN0LXJlc29ydCBzeW1ib2wgcmVzb2x2ZXIgKi8KIHZvaWQgKigqX2Rsc3ltcmVzb2x2ZXIp IChjb25zdCBjaGFyICpzeW1uYW1lKSA9IE5VTEw7CiAvKiBMYXN0LWVycm9yIHVucmVzb2x2ZWQg c3ltYm9sIGNvdW50ICovCkBAIC0xMTAsMTAgKzExOSwxMiBAQCB2b2lkICpkbG9wZW4oY29uc3Qg Y2hhciAqZmlsZW5hbWUsIGludCBtCiAgIGNoYXIgKmRpc2NhcmRhYmxlOwogCiAgIHN0a19ub2Rl ICpub2RlOwogICBzdGF0aWMgc3RrX25vZGUgKnN0a190b3AgPSBOVUxMOwogCisgIGR4ZV9saXN0 ICpkZXBzOworCiAjaWZuZGVmIF9fR05VQ19fCiAgIHN0YXRpYyBpbnQgY2xlYW51cCA9IDA7CiAj ZW5kaWYKIAogICBfZGxfdW5yZXNvbHZlZF9jb3VudCA9IDA7CkBAIC0yMDUsMTAgKzIxNiwxMSBA QCBmb3VuZDoKICAgLyogTy5rLCBmaWxsIHRoZSBtb2R1bGUgaGFuZGxlIHN0cnVjdHVyZSAqLwog ICBzdHJjcHkoZHhlLmZuYW1lLCByZWFsZm4pOwogICBkeGUuaW51c2UgPSAxOwogICBkeGUubW9k ZSA9IG1vZGU7CiAgIGR4ZS5uX2V4cF9zeW1zID0gZHhlaGRyLm5fZXhwX3N5bXM7CisgIGR4ZS5k ZXBzID0gTlVMTDsKIAogICAvKiBSZWFkIERYRSB0YWJsZXMgYW5kIHRoZSBkYXRhIHNlY3Rpb24g Ki8KICAgaGRyc2l6ZSA9IGR4ZWhkci5zeW1ib2xfb2Zmc2V0IC0gc2l6ZW9mKGR4ZWhkcik7CiAg IGRpc2NhcmRzaXplID0gZHhlaGRyLmRlcF9zaXplICsgZHhlaGRyLnVucmVzX3NpemUgKyBkeGVo ZHIubnJlbG9jcyAqIHNpemVvZihsb25nKTsKICAgaWYgKChkeGUuaGVhZGVyID0gbWFsbG9jKGhk cnNpemUgKyBkeGVoZHIuc2VjX3NpemUpKSA9PSBOVUxMKQpAQCAtMjQwLDI2ICsyNTIsNDkgQEAg Zm91bmQ6CiAgIC8qIEZpbGwgdGhlIHVuZmlsbGVkIHBvcnRpb24gb2YgY29kZStkYXRhK2JzcyBz ZWdtZW50IHdpdGggemVyb3MgKi8KICAgbWVtc2V0KGR4ZS5zZWN0aW9uICsgZHhlaGRyLnNlY19m X3NpemUsIDAsIGR4ZWhkci5zZWNfc2l6ZSAtIGR4ZWhkci5zZWNfZl9zaXplKTsKIAogICAvKiBM b2FkIHRoZSBkZXBlbmRlbmNpZXMgKi8KICAgc2NhbiA9IGRpc2NhcmRhYmxlOwotICBmb3IgKGkg PSAwOyBpIDwgZHhlaGRyLm5fZGVwczsgaSsrKQorICBmb3IgKGRlcHMgPSBOVUxMLCBpID0gMDsg aSA8IGR4ZWhkci5uX2RlcHM7IGkrKykKICAgewogICAgIHN0a19ub2RlIHRtcDsKKyAgICBkeGVf aCBkZXBfaDsKKwogICAgIHRtcC5uYW1lID0gcmVhbGZuOwogICAgIHRtcC5uZXh0ID0gc3RrX3Rv cDsKICAgICBzdGtfdG9wID0gJnRtcDsKIAotICAgIGlmIChkbG9wZW4oc2NhbiwgUlRMRF9HTE9C QUwpID09IE5VTEwpCisgICAgaWYgKChkZXBfaCA9IGRsb3BlbihzY2FuLCBSVExEX0dMT0JBTCkp ID09IE5VTEwpCiAgICAgewogICAgICAgc3RrX3RvcCA9IHRtcC5uZXh0OwogICAgICAgZ290byB1 bnJlY292ZXJhYmxlOwogICAgIH0KKyAgICBlbHNlCisgICAgeworICAgICAgZHhlX2xpc3QgKm5l eHQ7CisKKyAgICAgIHN0a190b3AgPSB0bXAubmV4dDsKIAotICAgIHN0a190b3AgPSB0bXAubmV4 dDsKKyAgICAgIHNjYW4gPSBzdHJjaHIoc2NhbiwgMCkgKyAxOwogCi0gICAgc2NhbiA9IHN0cmNo cihzY2FuLCAwKSArIDE7CisgICAgICAvKiBSZWdpc3RlciBhbGwgaW1wbGljaXRseSBvcGVuIG1v ZHVsZXMgYnkgdGhpcyBvbmUuICAqLworICAgICAgaWYgKChuZXh0ID0gbWFsbG9jKHNpemVvZihk eGVfbGlzdCkpKSA9PSBOVUxMKQorICAgICAgeworICAgICAgICBlcnJubyA9IEVOT01FTTsKKyAg ICAgICAgZ290byB1bnJlY292ZXJhYmxlOworICAgICAgfQorICAgICAgbmV4dC0+aGFuZGxlID0g ZGVwX2g7CisgICAgICBuZXh0LT5uZXh0ID0gTlVMTDsKKworICAgICAgaWYgKGRlcHMpCisgICAg ICB7CisgICAgICAgIGRlcHMtPm5leHQgPSBuZXh0OworICAgICAgICBkZXBzID0gZGVwcy0+bmV4 dDsKKyAgICAgIH0KKyAgICAgIGVsc2UKKyAgICAgICAgZHhlLmRlcHMgPSBkZXBzID0gbmV4dDsK KyAgICB9CiAgIH0KIAogICAvKiBBbGxyaWdodCwgbm93IHdlJ3JlIHJlYWR5IHRvIHJlc29sdmUg YWxsIHVucmVzb2x2ZWQgc3ltYm9scyAqLwogICBfZGxfdW5yZXNvbHZlZF9jb3VudCA9IGR4ZWhk ci5uX3VucmVzX3N5bXM7CiAgIF9kbF91bnJlc29sdmVkX3N5bWJvbFswXSA9IDA7CkBAIC0zMjUs MTAgKzM2MCw1MCBAQCBmb3VuZDoKICAgICBlcnJubyA9IEVOT01FTTsKICAgICBnb3RvIG1pZHdh eWVycm9yOwogICB9CiAgIG1lbWNweShkeGVfY2hhaW4sICZkeGUsIHNpemVvZihkeGVfaGFuZGxl KSk7CiAKKyNpZiAoREVCVUdfRFhFMyAtMCkgPT0gMQorICB7CisgICAgRklMRSAqZiA9IGZvcGVu KCJjOi90bXAvZHhlX2NoYWluLnR4dCIsICJhIik7CisKKyAgICBpZiAoZikKKyAgICB7CisgICAg ICBmcHJpbnRmKGYsICJkeGVfY2hhaW4gICAgICAgICAgICAgICAgICAgIDogMHglcFxuIgorICAg ICAgICAgICAgICAgICAiICBuZXh0ICAgICAgICAgICAgICAgICAgICAgICA6IDB4JXBcbiIKKyAg ICAgICAgICAgICAgICAgIiAgZm5hbWUgICAgICAgICAgICAgICAgICAgICAgOiAlc1xuIgorICAg ICAgICAgICAgICAgICAiICBtb2RlICAgICAgICAgICAgICAgICAgICAgICA6ICVzXG4iCisgICAg ICAgICAgICAgICAgICIgIGludXNlICAgICAgICAgICAgICAgICAgICAgIDogJWRcbiIKKyAgICAg ICAgICAgICAgICAgIiAgbl9leHBfc3ltcyAgICAgICAgICAgICAgICAgOiAlZFxuIgorICAgICAg ICAgICAgICAgICAiICBleHBfdGFibGUgICAgICAgICAgICAgICAgICA6IDB4JXBcbiIsCisgICAg ICAgICAgICAgICAgIGR4ZV9jaGFpbiwgZHhlX2NoYWluLT5uZXh0LCBkeGVfY2hhaW4tPmZuYW1l LAorICAgICAgICAgICAgICAgICBkeGVfY2hhaW4tPm1vZGUgPT0gUlRMRF9MQVpZID8gIlJUTERf TEFaWSIgOgorICAgICAgICAgICAgICAgICBkeGVfY2hhaW4tPm1vZGUgPT0gUlRMRF9OT1cgPyAi UlRMRF9OT1ciIDoKKyAgICAgICAgICAgICAgICAgZHhlX2NoYWluLT5tb2RlID09IFJUTERfTE9D QUwgPyAiUlRMRF9MT0NBTCIgOgorICAgICAgICAgICAgICAgICBkeGVfY2hhaW4tPm1vZGUgPT0g UlRMRF9HTE9CQUwgPyAiUlRMRF9HTE9CQUwiIDogInVua25vd24iLAorICAgICAgICAgICAgICAg ICBkeGVfY2hhaW4tPmludXNlLCBkeGVfY2hhaW4tPm5fZXhwX3N5bXMsIGR4ZV9jaGFpbi0+ZXhw X3RhYmxlKTsKKyAgICAgIGZvciAoaSA9IDA7IGkgPCBkeGVfY2hhaW4tPm5fZXhwX3N5bXM7IGkr KykKKyAgICAgICAgZnByaW50ZihmLCAiICAgIGV4cF90YWJsZVslZF0tPm9mZnNldCAgICAgOiAl bGRcbiIKKyAgICAgICAgICAgICAgICAgICAiICAgIGV4cF90YWJsZVslZF0tPm5hbWUgICAgICAg OiAlc1xuIiwKKyAgICAgICAgICAgICAgICAgICBpLCBkeGVfY2hhaW4tPmV4cF90YWJsZVtpXS0+ b2Zmc2V0LCBpLCBkeGVfY2hhaW4tPmV4cF90YWJsZVtpXS0+bmFtZSk7CisgICAgICBmcHJpbnRm KGYsICIgIGhlYWRlciAgICAgICAgICAgICAgICAgICAgIDogMHglcFxuIgorICAgICAgICAgICAg ICAgICAiICBzZWN0aW9uICAgICAgICAgICAgICAgICAgICA6IDB4JXBcbiIKKyAgICAgICAgICAg ICAgICAgIiAgX2ZpbmkgICAgICAgICAgICAgICAgICAgICAgOiAlbGRcbiIsCisgICAgICAgICAg ICAgICAgIGR4ZV9jaGFpbi0+aGVhZGVyLCBkeGVfY2hhaW4tPnNlY3Rpb24sIGR4ZV9jaGFpbi0+ X2ZpbmkpOworICAgICAgaWYgKChkZXBzID0gZHhlX2NoYWluLT5kZXBzKSkKKyAgICAgICAgZm9y ICg7IGRlcHM7IGRlcHMgPSBkZXBzLT5uZXh0KQorICAgICAgICAgIGZwcmludGYoZiwgIiAgZGVw cyAgICAgICAgICAgICAgICAgICAgICAgOiAweCVwXG4iCisgICAgICAgICAgICAgICAgICAgICAi ICAgIGhhbmRsZSAgICAgICAgICAgICAgICAgICA6IDB4JXBcbiIKKyAgICAgICAgICAgICAgICAg ICAgICIgICAgaGFuZGxlLT5mbmFtZSAgICAgICAgICAgIDogJXNcblxuIiwKKyAgICAgICAgICAg ICAgICAgICAgIGRlcHMsIGRlcHMtPmhhbmRsZSwgZGVwcy0+aGFuZGxlLT5mbmFtZSk7CisgICAg ICBlbHNlCisgICAgICAgIGZwcmludGYoZiwgIiAgZGVwcyAgICAgICAgICAgICAgICAgICAgICAg OiAweDAwMDAwMDAwXG5cbiIpOworICAgICAgZmNsb3NlKGYpOworICAgIH0KKyAgfQorI2VuZGlm CisKICNpZm5kZWYgX19HTlVDX18KICAgaWYgKCFjbGVhbnVwKQogICB7CiAgICAgY2xlYW51cCA9 ICEwOwogICAgIGF0ZXhpdChfY2xvc2VhbGwpOwpAQCAtMzQwLDEwICs0MTUsMTkgQEAgZm91bmQ6 CiB1bnJlY292ZXJhYmxlOgogICBmcmVlKGRpc2NhcmRhYmxlKTsKIG1pZHdheWVycm9yOgogICBm cmVlKGR4ZS5oZWFkZXIpOwogCisgIGlmICgoZGVwcyA9IGR4ZS5kZXBzKSAhPSBOVUxMKQorICB7 CisgICAgICBkeGVfbGlzdCAqbmV4dCA9IGRlcHMtPm5leHQ7CisKKyAgICAgIGRsY2xvc2UoZGVw cy0+aGFuZGxlKTsKKyAgICAgIGZyZWUoZGVwcyk7CisgICAgICBkZXBzID0gbmV4dDsKKyAgfQor CiAgIHJldHVybiBOVUxMOwogfQogCiBpbnQgZGxjbG9zZSh2b2lkICpkeGUpCiB7CkBAIC0zNjYs MTAgKzQ1MCwyMyBAQCBpbnQgZGxjbG9zZSh2b2lkICpkeGUpCiAgICAgICAgICpjdXIgPSAoKGR4 ZV9oKWR4ZSktPm5leHQ7CiAgICAgICAgIGJyZWFrOwogICAgICAgfQogICB9CiAKKyAgLyogcmVt b3ZlIGFsbCBpbXBsaWNpdGx5IGxvYWRlZCBtb2R1bGVzIGJ5IHRoaXMgbW9kdWxlLiAgKi8KKyAg eworICAgIGR4ZV9saXN0ICpkZXBzID0gKChkeGVfaClkeGUpLT5kZXBzOworICAgIHdoaWxlIChk ZXBzKQorICAgIHsKKyAgICAgIGR4ZV9saXN0ICpuZXh0ID0gZGVwcy0+bmV4dDsKKworICAgICAg ZGxjbG9zZShkZXBzLT5oYW5kbGUpOworICAgICAgZnJlZShkZXBzKTsKKyAgICAgIGRlcHMgPSBu ZXh0OworICAgIH0KKyAgfQorCiAgIGZyZWUoKChkeGVfaClkeGUpLT5oZWFkZXIpOwogICBmcmVl KCgoZHhlX2gpZHhlKS0+ZXhwX3RhYmxlKTsKICAgZnJlZShkeGUpOwogCiAgIHJldHVybiAwOwo= --089e0122a3fab63a0d05214aaaf6--