From mboxrd@z Thu Jan 1 00:00:00 1970 Content-Type: multipart/mixed; boundary="===============8454743800879368221==" MIME-Version: 1.0 From: Chih-Hung Hsieh To: elfutils-devel@lists.fedorahosted.org Subject: Re: [PATCH] Move nested functions in link_map.c to file scope. Date: Wed, 06 Jan 2016 11:35:46 -0800 Message-ID: In-Reply-To: 1451856346.13330.31.camel@redhat.com --===============8454743800879368221== Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Mark, Thanks for pushing several of my patches during the holidays. I have merged all of them and latest elfutils changes into Android open source project. We are getting closer to compile all needed elfutils files with clang/llvm for Android. I will continue to fix the remain elfutils issues after fixing a few other urgent unrelated Android problems. Thanks. On Sun, Jan 3, 2016 at 1:25 PM, Mark Wielaard wrote: > On Tue, 2015-11-17 at 14:45 -0800, Chih-Hung Hsieh wrote: > > * In libdwfl/link_map.c, nested functions check64, check32, > > For check64 and check32 the define plus static function extra args call > trick seems a good fit. I did push this part of the patch. > > > release_buffer, read_addrs, and consider_phdr are moved > > to file scope to compile with clang. > > But for the rest I feel it makes the code unnecessary messy. So I didn't > apply those. See below for some suggestions how to maybe get something > that doesn't create new functions with lots and lots of arguments (which > I find doesn't improve readability). > > > +static inline int > > +do_release_buffer (int result, Dwfl *dwfl, > > + void **pbuffer, size_t *pbuffer_available, > > + void *memory_callback_arg, > > + Dwfl_Memory_Callback *memory_callback) > > +{ > > + if (*pbuffer !=3D NULL) > > + (void) (*memory_callback) (dwfl, -1, pbuffer, pbuffer_available, 0, > 0, > > + memory_callback_arg); > > + return result; > > +} > > + > > +#define release_buffer(result) \ > > + do_release_buffer (result, dwfl, &buffer, &buffer_available, \ > > + memory_callback_arg, memory_callback) > > This is just 3 lines, and it is either used as "return release_buffer > (result)" to cleanup and return a result or as release_buffer (0) just > to cleanup the buffer (if not NULL). It seems better to make the define > just the function body. Assuming your compiler does know about statement > expressions https://gcc.gnu.org/onlinedocs/gcc/Statement-Exprs.html > Otherwise maybe just split it in two. Don't use an argument, just use it > as "cleanup_buffer()" plus a separate return line. > > > +static inline bool > > +do_read_addrs (GElf_Addr vaddr, size_t n, GElf_Addr *addrs, > > + uint_fast8_t elfdata, GElf_Addr *pread_vaddr, > > + int elfclass, Dwfl *dwfl, > > + void **pbuffer, size_t *pbuffer_available, > > + void *memory_callback_arg, > > + Dwfl_Memory_Callback *memory_callback) > > +{ > > + size_t nb =3D n * addrsize (elfclass); /* Address words -> bytes to > read. */ > > + > > + /* Read a new buffer if the old one doesn't cover these words. */ > > + if (*pbuffer =3D=3D NULL > > + || vaddr < *pread_vaddr > > + || vaddr - *pread_vaddr + nb > *pbuffer_available) > > + { > > + do_release_buffer (0, dwfl, pbuffer, pbuffer_available, > > + memory_callback_arg, memory_callback); > > + > > + *pread_vaddr =3D vaddr; > > + int segndx =3D INTUSE(dwfl_addrsegment) (dwfl, vaddr, NULL); > > + if (unlikely (segndx < 0) > > + || unlikely (! (*memory_callback) (dwfl, segndx, > > + pbuffer, pbuffer_available, > > + vaddr, nb, > memory_callback_arg))) > > + return true; > > + } > > + > > + Elf32_Addr (*a32)[n] =3D vaddr - *pread_vaddr + *pbuffer; > > + Elf64_Addr (*a64)[n] =3D (void *) a32; > > + > > + if (elfclass =3D=3D ELFCLASS32) > > + { > > + if (elfdata =3D=3D ELFDATA2MSB) > > + for (size_t i =3D 0; i < n; ++i) > > + addrs[i] =3D BE32 (read_4ubyte_unaligned_noncvt (&(*a32)[i])); > > + else > > + for (size_t i =3D 0; i < n; ++i) > > + addrs[i] =3D LE32 (read_4ubyte_unaligned_noncvt (&(*a32)[i])); > > + } > > + else > > + { > > + if (elfdata =3D=3D ELFDATA2MSB) > > + for (size_t i =3D 0; i < n; ++i) > > + addrs[i] =3D BE64 (read_8ubyte_unaligned_noncvt (&(*a64)[i])); > > + else > > + for (size_t i =3D 0; i < n; ++i) > > + addrs[i] =3D LE64 (read_8ubyte_unaligned_noncvt (&(*a64)[i])); > > + } > > + > > + return false; > > +} > > + > > +#define read_addrs(vaddr, n) \ > > + do_read_addrs (vaddr, n, addrs, elfdata, &read_vaddr, elfclass, dwfl, > \ > > + &buffer, &buffer_available, \ > > + memory_callback_arg, memory_callback) > > This very generic, but only used twice. Once to read 1 address and once > to read 4 addresses. Can't we make this a little simpler? Maybe just let > it handle reading one address. It might be a bit more hairy than needs > to because of the extra arguments needed to pass to the buffer cleanup. > > > +static inline bool > > +do_consider_phdr (GElf_Word type, GElf_Addr vaddr, GElf_Xword filesz, > > + Dwfl *dwfl, GElf_Addr phdr, GElf_Addr *pdyn_bias, > > + GElf_Addr *pdyn_vaddr, GElf_Xword *pdyn_filesz) > > +{ > > + switch (type) > > + { > > + case PT_PHDR: > > + if (*pdyn_bias =3D=3D (GElf_Addr) - 1 > > + /* Do a sanity check on the putative address. */ > > + && ((vaddr & (dwfl->segment_align - 1)) > > + =3D=3D (phdr & (dwfl->segment_align - 1)))) > > + { > > + *pdyn_bias =3D phdr - vaddr; > > + return *pdyn_vaddr !=3D 0; > > + } > > + break; > > + > > + case PT_DYNAMIC: > > + *pdyn_vaddr =3D vaddr; > > + *pdyn_filesz =3D filesz; > > + return *pdyn_bias !=3D (GElf_Addr) - 1; > > + } > > + > > + return false; > > +} > > + > > +#define consider_phdr(type, vaddr, filesz) \ > > + do_consider_phdr (type, vaddr, filesz, \ > > + dwfl, phdr, &dyn_bias, &dyn_vaddr, &dyn_filesz) > > This is just used twice in the function. Might be simpler to just inline > it twice and simplifying the switch by an if type =3D=3D PT_... check > instead of inventing a new function with 8 arguments. > > Thanks, > > Mark > > --===============8454743800879368221== Content-Type: text/html MIME-Version: 1.0 Content-Transfer-Encoding: base64 Content-Disposition: attachment; filename="attachment.html" PGRpdiBkaXI9Imx0ciI+TWFyayw8ZGl2Pjxicj48ZGl2PlRoYW5rcyBmb3IgcHVzaGluZyBzZXZl cmFsIG9mIG15IHBhdGNoZXMgZHVyaW5nIHRoZSBob2xpZGF5cy48L2Rpdj48L2Rpdj48ZGl2Pkkg aGF2ZSBtZXJnZWQgYWxsIG9mIHRoZW0gYW5kIGxhdGVzdCBlbGZ1dGlscyBjaGFuZ2VzIGludG8g QW5kcm9pZCBvcGVuIHNvdXJjZSBwcm9qZWN0LjwvZGl2PjxkaXY+V2UgYXJlIGdldHRpbmcgY2xv c2VyIHRvIGNvbXBpbGUgYWxsIG5lZWRlZCBlbGZ1dGlscyBmaWxlcyB3aXRoIGNsYW5nL2xsdm0g Zm9yIEFuZHJvaWQuPC9kaXY+PGRpdj48YnI+PC9kaXY+PGRpdj5JIHdpbGwgY29udGludWUgdG8g Zml4IHRoZSByZW1haW4gZWxmdXRpbHMgaXNzdWVzIGFmdGVyIGZpeGluZyBhIGZldyBvdGhlciB1 cmdlbnQgdW5yZWxhdGVkIEFuZHJvaWQgcHJvYmxlbXMuIFRoYW5rcy48L2Rpdj48ZGl2Pjxicj48 L2Rpdj48L2Rpdj48ZGl2IGNsYXNzPSJnbWFpbF9leHRyYSI+PGJyPjxkaXYgY2xhc3M9ImdtYWls X3F1b3RlIj5PbiBTdW4sIEphbiAzLCAyMDE2IGF0IDE6MjUgUE0sIE1hcmsgV2llbGFhcmQgPHNw YW4gZGlyPSJsdHIiPiZsdDs8YSBocmVmPSJtYWlsdG86bWp3QHJlZGhhdC5jb20iIHRhcmdldD0i X2JsYW5rIj5tandAcmVkaGF0LmNvbTwvYT4mZ3Q7PC9zcGFuPiB3cm90ZTo8YnI+PGJsb2NrcXVv dGUgY2xhc3M9ImdtYWlsX3F1b3RlIiBzdHlsZT0ibWFyZ2luOjAgMCAwIC44ZXg7Ym9yZGVyLWxl ZnQ6MXB4ICNjY2Mgc29saWQ7cGFkZGluZy1sZWZ0OjFleCI+PHNwYW4gY2xhc3M9IiI+T24gVHVl LCAyMDE1LTExLTE3IGF0IDE0OjQ1IC0wODAwLCBDaGloLUh1bmcgSHNpZWggd3JvdGU6PGJyPgom Z3Q7ICogSW4gbGliZHdmbC9saW5rX21hcC5jLCBuZXN0ZWQgZnVuY3Rpb25zIGNoZWNrNjQsIGNo ZWNrMzIsPGJyPgo8YnI+Cjwvc3Bhbj5Gb3IgY2hlY2s2NCBhbmQgY2hlY2szMiB0aGUgZGVmaW5l IHBsdXMgc3RhdGljIGZ1bmN0aW9uIGV4dHJhIGFyZ3MgY2FsbDxicj4KdHJpY2sgc2VlbXMgYSBn b29kIGZpdC4gSSBkaWQgcHVzaCB0aGlzIHBhcnQgb2YgdGhlIHBhdGNoLjxicj4KPHNwYW4gY2xh c3M9IiI+PGJyPgomZ3Q7wqAgwqByZWxlYXNlX2J1ZmZlciwgcmVhZF9hZGRycywgYW5kIGNvbnNp ZGVyX3BoZHIgYXJlIG1vdmVkPGJyPgomZ3Q7wqAgwqB0byBmaWxlIHNjb3BlIHRvIGNvbXBpbGUg d2l0aCBjbGFuZy48YnI+Cjxicj4KPC9zcGFuPkJ1dCBmb3IgdGhlIHJlc3QgSSBmZWVsIGl0IG1h a2VzIHRoZSBjb2RlIHVubmVjZXNzYXJ5IG1lc3N5LiBTbyBJIGRpZG4mIzM5O3Q8YnI+CmFwcGx5 IHRob3NlLiBTZWUgYmVsb3cgZm9yIHNvbWUgc3VnZ2VzdGlvbnMgaG93IHRvIG1heWJlIGdldCBz b21ldGhpbmc8YnI+CnRoYXQgZG9lc24mIzM5O3QgY3JlYXRlIG5ldyBmdW5jdGlvbnMgd2l0aCBs b3RzIGFuZCBsb3RzIG9mIGFyZ3VtZW50cyAod2hpY2g8YnI+CkkgZmluZCBkb2VzbiYjMzk7dCBp bXByb3ZlIHJlYWRhYmlsaXR5KS48YnI+CjxzcGFuIGNsYXNzPSIiPjxicj4KJmd0OyArc3RhdGlj IGlubGluZSBpbnQ8YnI+CiZndDsgK2RvX3JlbGVhc2VfYnVmZmVyIChpbnQgcmVzdWx0LCBEd2Zs ICpkd2ZsLDxicj4KJmd0OyArwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqB2b2lkICoqcGJ1 ZmZlciwgc2l6ZV90ICpwYnVmZmVyX2F2YWlsYWJsZSw8YnI+CiZndDsgK8KgIMKgIMKgIMKgIMKg IMKgIMKgIMKgIMKgIMKgdm9pZCAqbWVtb3J5X2NhbGxiYWNrX2FyZyw8YnI+CiZndDsgK8KgIMKg IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgRHdmbF9NZW1vcnlfQ2FsbGJhY2sgKm1lbW9yeV9jYWxs YmFjayk8YnI+CiZndDsgK3s8YnI+CiZndDsgK8KgIGlmICgqcGJ1ZmZlciAhPSBOVUxMKTxicj4K Jmd0OyArwqAgwqAgKHZvaWQpICgqbWVtb3J5X2NhbGxiYWNrKSAoZHdmbCwgLTEsIHBidWZmZXIs IHBidWZmZXJfYXZhaWxhYmxlLCAwLCAwLDxicj4KJmd0OyArwqAgwqAgwqAgwqAgwqAgwqAgwqAg wqAgwqAgwqAgwqAgwqAgwqAgwqAgbWVtb3J5X2NhbGxiYWNrX2FyZyk7PGJyPgomZ3Q7ICvCoCBy ZXR1cm4gcmVzdWx0Ozxicj4KJmd0OyArfTxicj4KJmd0OyArPGJyPgomZ3Q7ICsjZGVmaW5lIHJl bGVhc2VfYnVmZmVyKHJlc3VsdCkgXDxicj4KJmd0OyArwqAgZG9fcmVsZWFzZV9idWZmZXIgKHJl c3VsdCwgZHdmbCwgJmFtcDtidWZmZXIsICZhbXA7YnVmZmVyX2F2YWlsYWJsZSwgXDxicj4KJmd0 OyArwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqBtZW1vcnlfY2FsbGJhY2tfYXJnLCBt ZW1vcnlfY2FsbGJhY2spPGJyPgo8YnI+Cjwvc3Bhbj5UaGlzIGlzIGp1c3QgMyBsaW5lcywgYW5k IGl0IGlzIGVpdGhlciB1c2VkIGFzICZxdW90O3JldHVybiByZWxlYXNlX2J1ZmZlcjxicj4KKHJl c3VsdCkmcXVvdDsgdG8gY2xlYW51cCBhbmQgcmV0dXJuIGEgcmVzdWx0IG9yIGFzIHJlbGVhc2Vf YnVmZmVyICgwKSBqdXN0PGJyPgp0byBjbGVhbnVwIHRoZSBidWZmZXIgKGlmIG5vdCBOVUxMKS4g SXQgc2VlbXMgYmV0dGVyIHRvIG1ha2UgdGhlIGRlZmluZTxicj4KanVzdCB0aGUgZnVuY3Rpb24g Ym9keS4gQXNzdW1pbmcgeW91ciBjb21waWxlciBkb2VzIGtub3cgYWJvdXQgc3RhdGVtZW50PGJy PgpleHByZXNzaW9ucyA8YSBocmVmPSJodHRwczovL2djYy5nbnUub3JnL29ubGluZWRvY3MvZ2Nj L1N0YXRlbWVudC1FeHBycy5odG1sIiByZWw9Im5vcmVmZXJyZXIiIHRhcmdldD0iX2JsYW5rIj5o dHRwczovL2djYy5nbnUub3JnL29ubGluZWRvY3MvZ2NjL1N0YXRlbWVudC1FeHBycy5odG1sPC9h Pjxicj4KT3RoZXJ3aXNlIG1heWJlIGp1c3Qgc3BsaXQgaXQgaW4gdHdvLiBEb24mIzM5O3QgdXNl IGFuIGFyZ3VtZW50LCBqdXN0IHVzZSBpdDxicj4KYXMgJnF1b3Q7Y2xlYW51cF9idWZmZXIoKSZx dW90OyBwbHVzIGEgc2VwYXJhdGUgcmV0dXJuIGxpbmUuPGJyPgo8ZGl2PjxkaXYgY2xhc3M9Img1 Ij48YnI+CiZndDsgK3N0YXRpYyBpbmxpbmUgYm9vbDxicj4KJmd0OyArZG9fcmVhZF9hZGRycyAo R0VsZl9BZGRyIHZhZGRyLCBzaXplX3QgbiwgR0VsZl9BZGRyICphZGRycyw8YnI+CiZndDsgK8Kg IMKgIMKgIMKgIMKgIMKgIMKgIMKgdWludF9mYXN0OF90IGVsZmRhdGEsIEdFbGZfQWRkciAqcHJl YWRfdmFkZHIsPGJyPgomZ3Q7ICvCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoGludCBlbGZjbGFzcywg RHdmbCAqZHdmbCw8YnI+CiZndDsgK8KgIMKgIMKgIMKgIMKgIMKgIMKgIMKgdm9pZCAqKnBidWZm ZXIsIHNpemVfdCAqcGJ1ZmZlcl9hdmFpbGFibGUsPGJyPgomZ3Q7ICvCoCDCoCDCoCDCoCDCoCDC oCDCoCDCoHZvaWQgKm1lbW9yeV9jYWxsYmFja19hcmcsPGJyPgomZ3Q7ICvCoCDCoCDCoCDCoCDC oCDCoCDCoCDCoER3ZmxfTWVtb3J5X0NhbGxiYWNrICptZW1vcnlfY2FsbGJhY2spPGJyPgomZ3Q7 ICt7PGJyPgomZ3Q7ICvCoCBzaXplX3QgbmIgPSBuICogYWRkcnNpemUgKGVsZmNsYXNzKTsgLyog QWRkcmVzcyB3b3JkcyAtJmd0OyBieXRlcyB0byByZWFkLsKgICovPGJyPgomZ3Q7ICs8YnI+CiZn dDsgK8KgIC8qIFJlYWQgYSBuZXcgYnVmZmVyIGlmIHRoZSBvbGQgb25lIGRvZXNuJiMzOTt0IGNv dmVyIHRoZXNlIHdvcmRzLsKgICovPGJyPgomZ3Q7ICvCoCBpZiAoKnBidWZmZXIgPT0gTlVMTDxi cj4KJmd0OyArwqAgwqAgwqAgfHwgdmFkZHIgJmx0OyAqcHJlYWRfdmFkZHI8YnI+CiZndDsgK8Kg IMKgIMKgIHx8IHZhZGRyIC0gKnByZWFkX3ZhZGRyICsgbmIgJmd0OyAqcGJ1ZmZlcl9hdmFpbGFi bGUpPGJyPgomZ3Q7ICvCoCDCoCB7PGJyPgomZ3Q7ICvCoCDCoCDCoCBkb19yZWxlYXNlX2J1ZmZl ciAoMCwgZHdmbCwgcGJ1ZmZlciwgcGJ1ZmZlcl9hdmFpbGFibGUsPGJyPgomZ3Q7ICvCoCDCoCDC oCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoG1lbW9yeV9jYWxsYmFja19hcmcsIG1lbW9y eV9jYWxsYmFjayk7PGJyPgomZ3Q7ICs8YnI+CiZndDsgK8KgIMKgIMKgICpwcmVhZF92YWRkciA9 IHZhZGRyOzxicj4KJmd0OyArwqAgwqAgwqAgaW50IHNlZ25keCA9IElOVFVTRShkd2ZsX2FkZHJz ZWdtZW50KSAoZHdmbCwgdmFkZHIsIE5VTEwpOzxicj4KJmd0OyArwqAgwqAgwqAgaWYgKHVubGlr ZWx5IChzZWduZHggJmx0OyAwKTxicj4KJmd0OyArwqAgwqAgwqAgwqB8fCB1bmxpa2VseSAoISAo Km1lbW9yeV9jYWxsYmFjaykgKGR3ZmwsIHNlZ25keCw8YnI+CiZndDsgK8KgIMKgIMKgIMKgIMKg IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIHBidWZmZXIs IHBidWZmZXJfYXZhaWxhYmxlLDxicj4KJmd0OyArwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAg wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgdmFkZHIsIG5iLCBtZW1vcnlfY2Fs bGJhY2tfYXJnKSkpPGJyPgomZ3Q7ICvCoCDCoCDCoHJldHVybiB0cnVlOzxicj4KJmd0OyArwqAg wqAgfTxicj4KJmd0OyArPGJyPgomZ3Q7ICvCoCBFbGYzMl9BZGRyICgqYTMyKVtuXSA9IHZhZGRy IC0gKnByZWFkX3ZhZGRyICsgKnBidWZmZXI7PGJyPgomZ3Q7ICvCoCBFbGY2NF9BZGRyICgqYTY0 KVtuXSA9ICh2b2lkICopIGEzMjs8YnI+CiZndDsgKzxicj4KJmd0OyArwqAgaWYgKGVsZmNsYXNz ID09IEVMRkNMQVNTMzIpPGJyPgomZ3Q7ICvCoCDCoCB7PGJyPgomZ3Q7ICvCoCDCoCDCoCBpZiAo ZWxmZGF0YSA9PSBFTEZEQVRBMk1TQik8YnI+CiZndDsgK8KgIMKgIMKgZm9yIChzaXplX3QgaSA9 IDA7IGkgJmx0OyBuOyArK2kpPGJyPgomZ3Q7ICvCoCDCoCDCoCDCoGFkZHJzW2ldID0gQkUzMiAo cmVhZF80dWJ5dGVfdW5hbGlnbmVkX25vbmN2dCAoJmFtcDsoKmEzMilbaV0pKTs8YnI+CiZndDsg K8KgIMKgIMKgIGVsc2U8YnI+CiZndDsgK8KgIMKgIMKgZm9yIChzaXplX3QgaSA9IDA7IGkgJmx0 OyBuOyArK2kpPGJyPgomZ3Q7ICvCoCDCoCDCoCDCoGFkZHJzW2ldID0gTEUzMiAocmVhZF80dWJ5 dGVfdW5hbGlnbmVkX25vbmN2dCAoJmFtcDsoKmEzMilbaV0pKTs8YnI+CiZndDsgK8KgIMKgIH08 YnI+CiZndDsgK8KgIGVsc2U8YnI+CiZndDsgK8KgIMKgIHs8YnI+CiZndDsgK8KgIMKgIMKgIGlm IChlbGZkYXRhID09IEVMRkRBVEEyTVNCKTxicj4KJmd0OyArwqAgwqAgwqBmb3IgKHNpemVfdCBp ID0gMDsgaSAmbHQ7IG47ICsraSk8YnI+CiZndDsgK8KgIMKgIMKgIMKgYWRkcnNbaV0gPSBCRTY0 IChyZWFkXzh1Ynl0ZV91bmFsaWduZWRfbm9uY3Z0ICgmYW1wOygqYTY0KVtpXSkpOzxicj4KJmd0 OyArwqAgwqAgwqAgZWxzZTxicj4KJmd0OyArwqAgwqAgwqBmb3IgKHNpemVfdCBpID0gMDsgaSAm bHQ7IG47ICsraSk8YnI+CiZndDsgK8KgIMKgIMKgIMKgYWRkcnNbaV0gPSBMRTY0IChyZWFkXzh1 Ynl0ZV91bmFsaWduZWRfbm9uY3Z0ICgmYW1wOygqYTY0KVtpXSkpOzxicj4KJmd0OyArwqAgwqAg fTxicj4KJmd0OyArPGJyPgomZ3Q7ICvCoCByZXR1cm4gZmFsc2U7PGJyPgomZ3Q7ICt9PGJyPgom Z3Q7ICs8YnI+CiZndDsgKyNkZWZpbmUgcmVhZF9hZGRycyh2YWRkciwgbikgXDxicj4KJmd0OyAr wqAgZG9fcmVhZF9hZGRycyAodmFkZHIsIG4sIGFkZHJzLCBlbGZkYXRhLCAmYW1wO3JlYWRfdmFk ZHIsIGVsZmNsYXNzLCBkd2ZsLCBcPGJyPgomZ3Q7ICvCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDC oCZhbXA7YnVmZmVyLCAmYW1wO2J1ZmZlcl9hdmFpbGFibGUsIFw8YnI+CiZndDsgK8KgIMKgIMKg IMKgIMKgIMKgIMKgIMKgIMKgbWVtb3J5X2NhbGxiYWNrX2FyZywgbWVtb3J5X2NhbGxiYWNrKTxi cj4KPGJyPgo8L2Rpdj48L2Rpdj5UaGlzIHZlcnkgZ2VuZXJpYywgYnV0IG9ubHkgdXNlZCB0d2lj ZS4gT25jZSB0byByZWFkIDEgYWRkcmVzcyBhbmQgb25jZTxicj4KdG8gcmVhZCA0IGFkZHJlc3Nl cy4gQ2FuJiMzOTt0IHdlIG1ha2UgdGhpcyBhIGxpdHRsZSBzaW1wbGVyPyBNYXliZSBqdXN0IGxl dDxicj4KaXQgaGFuZGxlIHJlYWRpbmcgb25lIGFkZHJlc3MuIEl0IG1pZ2h0IGJlIGEgYml0IG1v cmUgaGFpcnkgdGhhbiBuZWVkczxicj4KdG8gYmVjYXVzZSBvZiB0aGUgZXh0cmEgYXJndW1lbnRz IG5lZWRlZCB0byBwYXNzIHRvIHRoZSBidWZmZXIgY2xlYW51cC48YnI+CjxkaXY+PGRpdiBjbGFz cz0iaDUiPjxicj4KJmd0OyArc3RhdGljIGlubGluZSBib29sPGJyPgomZ3Q7ICtkb19jb25zaWRl cl9waGRyIChHRWxmX1dvcmQgdHlwZSwgR0VsZl9BZGRyIHZhZGRyLCBHRWxmX1h3b3JkIGZpbGVz eiw8YnI+CiZndDsgK8KgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIER3ZmwgKmR3ZmwsIEdFbGZf QWRkciBwaGRyLCBHRWxmX0FkZHIgKnBkeW5fYmlhcyw8YnI+CiZndDsgK8KgIMKgIMKgIMKgIMKg IMKgIMKgIMKgIMKgIEdFbGZfQWRkciAqcGR5bl92YWRkciwgR0VsZl9Yd29yZCAqcGR5bl9maWxl c3opPGJyPgomZ3Q7ICt7PGJyPgomZ3Q7ICvCoCBzd2l0Y2ggKHR5cGUpPGJyPgomZ3Q7ICvCoCDC oCB7PGJyPgomZ3Q7ICvCoCDCoCBjYXNlIFBUX1BIRFI6PGJyPgomZ3Q7ICvCoCDCoCDCoCBpZiAo KnBkeW5fYmlhcyA9PSAoR0VsZl9BZGRyKSAtIDE8YnI+CiZndDsgK8KgIMKgIMKgIMKgLyogRG8g YSBzYW5pdHkgY2hlY2sgb24gdGhlIHB1dGF0aXZlIGFkZHJlc3MuwqAgKi88YnI+CiZndDsgK8Kg IMKgIMKgIMKgJmFtcDsmYW1wOyAoKHZhZGRyICZhbXA7IChkd2ZsLSZndDtzZWdtZW50X2FsaWdu IC0gMSkpPGJyPgomZ3Q7ICvCoCDCoCDCoCDCoCDCoCDCoD09IChwaGRyICZhbXA7IChkd2ZsLSZn dDtzZWdtZW50X2FsaWduIC0gMSkpKSk8YnI+CiZndDsgK8KgIMKgIMKgezxicj4KJmd0OyArwqAg wqAgwqAgwqAqcGR5bl9iaWFzID0gcGhkciAtIHZhZGRyOzxicj4KJmd0OyArwqAgwqAgwqAgwqBy ZXR1cm4gKnBkeW5fdmFkZHIgIT0gMDs8YnI+CiZndDsgK8KgIMKgIMKgfTxicj4KJmd0OyArwqAg wqAgwqAgYnJlYWs7PGJyPgomZ3Q7ICs8YnI+CiZndDsgK8KgIMKgIGNhc2UgUFRfRFlOQU1JQzo8 YnI+CiZndDsgK8KgIMKgIMKgICpwZHluX3ZhZGRyID0gdmFkZHI7PGJyPgomZ3Q7ICvCoCDCoCDC oCAqcGR5bl9maWxlc3ogPSBmaWxlc3o7PGJyPgomZ3Q7ICvCoCDCoCDCoCByZXR1cm4gKnBkeW5f YmlhcyAhPSAoR0VsZl9BZGRyKSAtIDE7PGJyPgomZ3Q7ICvCoCDCoCB9PGJyPgomZ3Q7ICs8YnI+ CiZndDsgK8KgIHJldHVybiBmYWxzZTs8YnI+CiZndDsgK308YnI+CiZndDsgKzxicj4KJmd0OyAr I2RlZmluZSBjb25zaWRlcl9waGRyKHR5cGUsIHZhZGRyLCBmaWxlc3opIFw8YnI+CiZndDsgK8Kg IGRvX2NvbnNpZGVyX3BoZHIgKHR5cGUsIHZhZGRyLCBmaWxlc3osIFw8YnI+CiZndDsgK8KgIMKg IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIGR3ZmwsIHBoZHIsICZhbXA7ZHluX2JpYXMsICZhbXA7 ZHluX3ZhZGRyLCAmYW1wO2R5bl9maWxlc3opPGJyPgo8YnI+CjwvZGl2PjwvZGl2PlRoaXMgaXMg anVzdCB1c2VkIHR3aWNlIGluIHRoZSBmdW5jdGlvbi4gTWlnaHQgYmUgc2ltcGxlciB0byBqdXN0 IGlubGluZTxicj4KaXQgdHdpY2UgYW5kIHNpbXBsaWZ5aW5nIHRoZSBzd2l0Y2ggYnkgYW4gaWYg dHlwZSA9PSBQVF8uLi4gY2hlY2s8YnI+Cmluc3RlYWQgb2YgaW52ZW50aW5nIGEgbmV3IGZ1bmN0 aW9uIHdpdGggOCBhcmd1bWVudHMuPGJyPgo8YnI+ClRoYW5rcyw8YnI+Cjxicj4KTWFyazxicj4K PGJyPgo8L2Jsb2NrcXVvdGU+PC9kaXY+PGJyPjwvZGl2Pgo= --===============8454743800879368221==--