From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from forward500b.mail.yandex.net (forward500b.mail.yandex.net [IPv6:2a02:6b8:c02:900:1:45:d181:d500]) by sourceware.org (Postfix) with ESMTPS id 7A8323858D20 for ; Thu, 13 Apr 2023 22:50:15 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 7A8323858D20 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=yandex.ru Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=yandex.ru Received: from mail-nwsmtp-smtp-production-main-39.sas.yp-c.yandex.net (mail-nwsmtp-smtp-production-main-39.sas.yp-c.yandex.net [IPv6:2a02:6b8:c08:2087:0:640:7bf5:0]) by forward500b.mail.yandex.net (Yandex) with ESMTP id 50C5A5EF4B; Fri, 14 Apr 2023 01:50:13 +0300 (MSK) Received: by mail-nwsmtp-smtp-production-main-39.sas.yp-c.yandex.net (smtp/Yandex) with ESMTPSA id Aog7Fc7W1a60-TjTB3qWp; Fri, 14 Apr 2023 01:50:12 +0300 X-Yandex-Fwd: 1 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yandex.ru; s=mail; t=1681426212; bh=0YePaPt19ZnfvG6tYy9HZVUCNM9BiItmacNI3m7918k=; h=In-Reply-To:Cc:Date:References:To:Subject:Message-ID:From; b=ewJM8bjPFwcjwjmpoHElW3gtEPZvtIaqAL+0M4yb9mtzd8PKo7elkeR+e1f7wOHT7 bGROjJRUAV+ATF39x8LzZ27I34hmZEgMk8tCkKyBXVbeWKUU+oj1Gur1qe5GmGzTu2 7gpJ7cfcZybDxqcPwzS17c85Nq57GPzmjImmsTJw= Authentication-Results: mail-nwsmtp-smtp-production-main-39.sas.yp-c.yandex.net; dkim=pass header.i=@yandex.ru Content-Type: multipart/mixed; boundary="------------A3Q00wLwSZy3oUPzC4wnQMg7" Message-ID: Date: Fri, 14 Apr 2023 03:50:10 +0500 MIME-Version: 1.0 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:102.0) Gecko/20100101 Thunderbird/102.10.0 Subject: Re: [PATCH v9 0/13] implement dlmem() function Content-Language: en-US To: Zack Weinberg References: <20230318165110.3672749-1-stsp2@yandex.ru> <481ef2c5-a59f-dea4-7f5f-2fcd229a4c25@redhat.com> <7fab954f-4a3d-0df0-8211-a9697f3966c1@yandex.ru> <81d75bd3-147e-f85a-9955-0c7f0f2dfbeb@redhat.com> <09b644bc-3d6e-39cf-02c2-af5c5a72e248@yandex.ru> <23436bcf-a715-971b-db54-5d80634ca0ef@redhat.com> Cc: Carlos O'Donell , libc-alpha@sourceware.org, Jonathon Anderson , Adhemerval Zanella Netto , Szabolcs Nagy From: stsp In-Reply-To: <23436bcf-a715-971b-db54-5d80634ca0ef@redhat.com> X-Spam-Status: No, score=-4.3 required=5.0 tests=BAYES_00,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,FREEMAIL_ENVFROM_END_DIGIT,FREEMAIL_FROM,HTML_MESSAGE,NICE_REPLY_A,SPF_HELO_NONE,SPF_PASS,TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org List-Id: This is a multi-part message in MIME format. --------------A3Q00wLwSZy3oUPzC4wnQMg7 Content-Type: multipart/alternative; boundary="------------dWFQpQ4UaA68yODFRwQJgIN9" --------------dWFQpQ4UaA68yODFRwQJgIN9 Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 8bit Hi Zack, thanks for a reply. Have you forgot to CC the e-mail to me, or was it some spam filtering? Carlos have just told me about it. I'll use copy/paste from web interface to reply, and will monitor the web archive for a few days in case your mails to me are blocked somewhere. > Let me try to highlight specific issues from the feedback you've been > getting. It appears to me that your *API* proposal -- not any details > of its implementation, the API itself -- is unacceptable *BECAUSE*: > > * It introduces a callback from the dynamic loader into user code, that > is to be run with an internal lock held. glibc does already have > callbacks like that, but we do not want to introduce any more of > them, period. > * It assumes that the dynamic loader will always, in the future, operate > by creating a large initial mapping and then modifying protection > flags on it. Yes, those are the totally valid concerns raised by Szabolcs. They were very difficult to address actually, and eventually I came to this proposal: https://sourceware.org/pipermail/libc-alpha/2023-April/147243.html It is needed to address exactly those, but it may not be obvious yet how exactly they are related. I think this is not a problem, you'll see that in a next dlmem() draft. These problems will be solved. Most of dlmem() can be off-loaded to either proposed RTLD_NORELOC or something similar. > * It assumes that it the dynamic loader is, and will always be, capable > of taking a pointer to a block of memory -- no matter how it was > originally allocated -- and then chopping its virtual memory map up to > satisfy the requirements of the embedded ELF program header table, > without breaking anything else. I think you are talking about a premap callback here? It will be dropped per comment 1 of yours, so I think this is mostly a duplicate. > [On this specific note, I foresee > someone trying to write a dynamic module into memory allocated with > memalign() or even plain old malloc(); calling dlmem() on this is very > likely to apply PROT_NONE to address ranges containing malloc > metadata!] No-no, it never changes the protection of a source buffer! Nothing to worry about here. Also there are some recommendations in an API draft what mappings are supported as a source and what not - using memalign() space is very much unrecommended unless you know what you do (see api draft for details). But the protections are of course not altered. > For instance, maybe we could have an fdlopen variant that > called callback functions instead of mmap() and mprotect(). Unlike > your dlmem_premap_t, I think it ought to be possible to avoid doing > those specific operations with any locks held. But what such a callback would do? Plain read()? So. You are welcome to this lengthy thread. :) I am attaching an API draft in case you are curious about a details, but it was not yet updated to the removal of a callback. Sorry about that, just take my word on that for now. :) There are a few things that you miss about the proposed design (as every newcomer to this thread does), so let me show you an examples of fdlopen() and dlopen_with_offset() implemented on top of dlmem(). Most of things, like eg the source buffer usage, will be more clear after that: static void * fdlopen (int fd, int flags) {   off_t len;   void *addr;   void *handle;   len = lseek (fd, 0, SEEK_END);   lseek (fd, 0, SEEK_SET);   addr = mmap (NULL, len, PROT_READ, MAP_PRIVATE, fd, 0);   if (addr == MAP_FAILED)     return NULL;   handle = dlmem (addr, len, flags, NULL);   munmap (addr, len);   return handle; } If we run that example, then in /proc/self/maps we will see the correct references to an elf file: $ LD_LIBRARY_PATH=..:. ./tst-dlmem-fdlopen unaligned buf gives buffer not aligned: Invalid argument 7fb413101000-7fb413102000 r--p 00000000 00:28 17195405 /home/stas/src/glibc-dev/build/dlfcn/glreflib1.so 7fb413102000-7fb413103000 r-xp 00001000 00:28 17195405 /home/stas/src/glibc-dev/build/dlfcn/glreflib1.so 7fb413103000-7fb413104000 r--p 00002000 00:28 17195405 /home/stas/src/glibc-dev/build/dlfcn/glreflib1.so 7fb413104000-7fb413105000 r--p 00002000 00:28 17195405 /home/stas/src/glibc-dev/build/dlfcn/glreflib1.so 7fb413105000-7fb413106000 rw-p 00003000 00:28 17195405 /home/stas/src/glibc-dev/build/dlfcn/glreflib1.so As you an see, there is no reference to the full file, just to the elf segments. That's because the above code just munmap()s the source buffer after dlmem() returns. Its protection was never changed. Now, dlopen_with_offset() is slightly more difficult, but is suggested for a read too: /* Load the shared library from a container file. file - file name. offset - solib offset within a container file. Highly recommended to be page-aligned. length - solib file length (not a container file length). flags - dlopen() flags. */ void *dlopen_with_offset4 (const char *file, off_t offset, size_t length, int flags) { void *addr; void *handle; int fd; off_t pad_size = (offset & (getpagesize () - 1)); off_t aligned_offset = offset - pad_size; size_t map_length = length + pad_size; fd = open (file, O_RDONLY); if (fd == -1) return NULL; addr = mmap (NULL, map_length, PROT_READ, MAP_PRIVATE, fd, aligned_offset); close(fd); if (addr == MAP_FAILED) return NULL; if (pad_size) { /* We need to fix alignment by hands. :-( And for that we need a shared mapping. */ void *addr2 = mmap (NULL, length, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0); if (addr2 == MAP_FAILED) { munmap (addr, map_length); return NULL; } memcpy (addr2, addr + pad_size, length); munmap (addr, map_length); addr = addr2; map_length = length; } handle = dlmem (addr, length, flags, NULL); munmap (addr, map_length); return handle; } --------------dWFQpQ4UaA68yODFRwQJgIN9-- --------------A3Q00wLwSZy3oUPzC4wnQMg7 Content-Type: text/x-patch; charset=UTF-8; name="0000-cover-letter.patch" Content-Disposition: attachment; filename="0000-cover-letter.patch" Content-Transfer-Encoding: base64 RnJvbSA0NmU1MDk1ZWJmZTYzYmU0ZGNkODEzYzQyMzdkNmE0OTFhM2Y5NzY4 IE1vbiBTZXAgMTcgMDA6MDA6MDAgMjAwMQpGcm9tOiBTdGFzIFNlcmdlZXYg PHN0c3AyQHlhbmRleC5ydT4KRGF0ZTogTW9uLCAxMyBGZWIgMjAyMyAxODox NTozNCArMDUwMApTdWJqZWN0OiBbUEFUQ0ggdjEwIDAvMTJdIGltcGxlbWVu dCBkbG1lbSgpIGZ1bmN0aW9uCgpUaGlzIHBhdGNoLXNldCBpbXBsZW1lbnRz IHRoZSBkbG1lbSgpIGZ1bmN0aW9uIHRoYXQgYWxsb3dzIHRvIGxvYWQKdGhl IHNvbGliIGZyb20gdGhlIGZpbGUtbWFwcGVkIG9yIGFub255bW91c2x5LXNo YXJlZCBtZW1vcnkgYnVmZmVyLgpHZW5lcmljIG1lbW9yeSBidWZmZXIgaXMg YWxzbyBzdXBwb3J0ZWQgd2l0aCBETE1FTV9HRU5CVUZfU1JDIGZsYWcsCmJ1 dCBpdCBzaG91bGQgbm90IGJlIHByZWZlcnJlZC4gUHJpdmF0ZSBhbm9ueW1v dXMgbWFwcGluZyB1c2VkIGFzCmEgc291cmNlIGJ1ZmZlciwgYWxzbyBuZWVk cyB0aGlzIGZsYWcgdG8gYmUgc2V0LgoKZGxtZW0oKSBzdWl0cyBhcyBhIGJ1 aWxkaW5nIGJsb2NrIGZvciBpbXBsZW1lbnRpbmcgdGhlIGZ1bmN0aW9ucyBs aWtlCmZkbG9wZW4oKSBhbmQgZGxvcGVuX3dpdGhfb2Zmc2V0KCksIHdoaWNo IGFyZSBkZW1vLWltcGxlbWVudGVkIGluIGEKdGVzdC1jYXNlIGNhbGxlZCB0 c3QtZGxtZW0tZXh0Zm5zLgpUaGUgcmVhc29ucyB3aHkgaXQgc3VpdHMgd2Vs bCBmb3Igc3VjaCBmaWxlLWJhc2VkIGxvYWRlcnMsIGFyZSBiZWxvdzoKMS4g SXQgY29ycmVjdGx5IGhhbmRsZXMgdGhlIGZpbGUgYXNzb2NpYXRpb24gb2Yg dGhlIG9yaWdpbmFsIHNvbGliCiAgIGJ1ZmZlciBpZiBpdCB3YXMgbW1hcCdl ZCBmcm9tIGEgZmlsZSAodW5sZXNzIERMTUVNX0dFTkJVRl9TUkMKICAgb2Yg RExNRU1fRE9OVFJFUExBQ0UgZmxhZyBpcyBzZXQpLgoyLiBJdCBhbGxvd3Mg dG8gcHJvdmlkZSBhIHNvbGliIG5hbWUsIHdoaWNoIGNhbiBiZSB0aGUgZmls ZSBuYW1lLgoKV2l0aCB0aGUgYWJvdmUgcHJvcGVydGllcywgdGhlICJkaXJl Y3QiIGltcGxlbWVudGF0aW9uIG9mIHRoZXNlIGZ1bmN0aW9ucwpnaXZlcyBu byBhZHZhbnRhZ2VzIG92ZXIgaW1wbGVtZW50aW5nIHRoZW0gd2l0aCBkbG1l bSgpLgoKSW4gYWRkaXRpb24sIGRsbWVtKCkgaGFzIGxvdHMgb2Ygb3B0aW9u YWwgZnVuY3Rpb25hbGl0eSBmb3IgdGhlIGZpbmUtZ3JhaW5lZApjb250cm9s IG92ZXIgdGhlIGxvYWRpbmcgcHJvY2Vzcy4gSXQgYWxsb3dzIHlvdSB0byBz ZXQgbnNpZCAobGlrZSBkbG1vcGVuKCkpLApzcGVjaWZ5IHRoZSBzb2xpYiBy ZWxvY2F0aW9uIGFkZHJlc3MgYW5kIGV2ZW4gcmVsb2NhdGUgdGhlIHNvbGli IGludG8KdGhlIHVzZXIncyBidWZmZXIuIFRoYXQgImFkdmFuY2VkIiBmdW5j dGlvbmFsaXR5IGlzIG9ubHkgbmVlZGVkIGZvciB0aGUKdmVyeSBzcGVjaWZp YyB1c2UtY2FzZXMsIGxpa2UgdmlydHVhbGl6ZWQgZW52aXJvbm1lbnRzIHdo ZXJlIHRoZSByZWxvY2F0aW9uCmFkZHJlc3MgbWF5IGhhdmUgYSBzcGVjaWFs IGNvbnN0cmFpbnRzLCBlZyBNQVBfMzJCSVQuIEluIGFsbCBvdGhlciBjYXNl cwppdCBpcyBhZHZpc2VkIHRvIHNldCB0aGUgImRsbV9hcmdzIiBwb2ludGVy IG9mIGRsbWVtKCkgY2FsbCB0byBOVUxMLCBidXQKc2VlICJMaW1pdGF0aW9u cyIgYmVsb3cgdG8gZmluZCBvdXQgd2hlbiBpdHMgbm90IHRoZSBjYXNlLgoK VGhlIEFQSSBsb29rcyBhcyBiZWxvdzoKCi8qIENhbGxiYWNrIGZvciBkbG1l bS4gKi8KdHlwZWRlZiB2b2lkICoKKGRsbWVtX3ByZW1hcF90KSAodm9pZCAq bWFwcHJlZiwgc2l6ZV90IG1hcGxlbmd0aCwgc2l6ZV90IG1hcGFsaWduLAoJ ICAgICAgICAgIHZvaWQgKmNvb2tpZSk7CgovKiBEbyBub3QgcmVwbGFjZSBt YXBwaW5nIGNyZWF0ZWQgYnkgcHJlbWFwIGNhbGxiYWNrLgogICBkbG1lbSgp IHdpbGwgdGhlbiB1c2UgbWVtY3B5KCkuICovCiNkZWZpbmUgRExNRU1fRE9O VFJFUExBQ0UgMQovKiBUcmVhdCBzb3VyY2UgbWVtb3J5IGJ1ZmZlciBhcyBh IGdlbmVyaWMgdW5hbGlnbmVkIGJ1ZmZlciwgcmF0aGVyCiAgIHRoYW4gYSBm aWxlLWJhY2tlZCBvciBhbm9ueW1vdXNseS1zaGFyZWQgbWFwcGluZy4gQW5v bnltb3VzIHByaXZhdGUKICAgbWFwcGluZyBhbHNvIG5lZWRzIHRoaXMgZmxh ZyB0byBiZSBzZXQuICovCiNkZWZpbmUgRExNRU1fR0VOQlVGX1NSQyAyCgpz dHJ1Y3QgZGxtZW1fYXJncyB7CiAgLyogT3B0aW9uYWwgbmFtZSB0byBhc3Nv Y2lhdGUgd2l0aCB0aGUgbG9hZGVkIG9iamVjdC4gKi8KICBjb25zdCBjaGFy ICpzb25hbWU7CiAgLyogTmFtZXNwYWNlIHdoZXJlIHRvIGxvYWQgdGhlIG9i amVjdC4gKi8KICBMbWlkX3QgbnNpZDsKICAvKiBkbG1lbS1zcGVjaWZpYyBm bGFncy4gKi8KICB1bnNpZ25lZCBpbnQgZmxhZ3M7CiAgLyogT3B0aW9uYWwg cHJlbWFwIGNhbGxiYWNrLiAqLwogIGRsbWVtX3ByZW1hcF90ICpwcmVtYXA7 CiAgLyogT3B0aW9uYWwgYXJndW1lbnQgZm9yIHByZW1hcCBjYWxsYmFjay4g Ki8KICB2b2lkICpjb29raWU7Cn07CgovKiBMaWtlIGBkbG1vcGVuJywgYnV0 IGxvYWRzIHNoYXJlZCBvYmplY3QgZnJvbSBtZW1vcnkgYnVmZmVyLiAgKi8K ZXh0ZXJuIHZvaWQgKmRsbWVtIChjb25zdCB1bnNpZ25lZCBjaGFyICpidWZm ZXIsIHNpemVfdCBzaXplLCBpbnQgbW9kZSwKCQkgICAgc3RydWN0IGRsbWVt X2FyZ3MgKmRsbV9hcmdzKTsKCkFkdmFuY2VkIGZ1bmN0aW9uYWxpdHk6CgpJ biBtb3N0IGNhc2VzIGRsbV9hcmdzIHNob3VsZCBqdXN0IGJlIHNldCB0byBO VUxMLiBJdCBwcm92aWRlcyB0aGUKYWR2YW5jZWQgZnVuY3Rpb25hbGl0eSwg bW9zdCBvZiB3aGljaCBpcyBvYnZpb3VzIChzb25hbWUsIG5zaWQpLgpUaGUg b3B0aW9uYWwgcHJlbWFwIGNhbGxiYWNrIGFsbG93cyB0byBzZXQgdGhlIHJl bG9jYXRpb24gYWRkcmVzcyBmb3IKdGhlIHNvbGliIGJ5IG1hcHBpbmcgdGhl IGRlc3RpbmF0aW9uIHNwYWNlIGFuZCByZXR1cm5pbmcgaXRzIGFkZHJlc3Mu Ck1vcmUgc28sIGlmIERMTUVNX0RPTlRSRVBMQUNFIGZsYWcgaXMgdXNlZCwg dGhlbiB0aGUgbWFwcGluZwplc3RhYmxpc2hlZCBieSB0aGUgcHJlbWFwIGNh bGxiYWNrLCB3aWxsIG5vdCBiZSByZXBsYWNlZCB3aXRoIHRoZQpmaWxlLWJh Y2tlZCBtYXBwaW5nLiBJbiB0aGF0IGNhc2UgZGxtZW0oKSBoYXZlIHRvIHVz ZSBtZW1jcHkoKSwgd2hpY2gKaXMgbGlrZWx5IGV2ZW4gZmFzdGVyIHRoYW4g bW1hcHMoKSBidXQgZG9lc24ndCBlbmQgdXAgd2l0aCB0aGUgcHJvcGVyCi9w cm9jL3NlbGYvbWFwX2ZpbGVzIG9yIC9wcm9jL3NlbGYvbWFwcyBlbnRyaWVz LiBTbyBmb3IgZXhhbXBsZSBpZiB0aGUKcHJlbWFwIGNhbGxiYWNrIHVzZXMg TUFQX1NIQVJFRCwgdGhlbiB3aXRoIHRoZSB1c2Ugb2YgdGhlIERMTUVNX0RP TlRSRVBMQUNFCmZsYWcgeW91IGNhbiBnZXQgeW91ciBzb2xpYiByZWxvY2F0 ZWQgaW50byBhIHNoYXJlZCBtZW1vcnkgYnVmZmVyLgpOb3RlIHRoYXQgdGhl IHByZW1hcCBjYWxsYmFjayBtYXkgYmUgY2FsbGVkIHVuZGVyIGdsaWJjIGxv Y2tzLCBzbyBpdApzaG91bGQgcmVzdHJpY3QgaXRzZWxmIHRvIHRoZSBzeXNj YWxsIGZ1bmN0aW9uYWxpdHkuIENlcnRhaW5seSBubyBsaWJkbApmdW5jdGlv bnMgY2FuIGJlIHVzZWQuIG1tYXAoKSwgc2htX29wZW4oKSwgb3BlbigpLCBm dHJ1bmNhdGUoKSwKbWVtZmRfY3JlYXRlKCkgc2hvdWxkIGJlIHRoZSBzdWZm aWNpZW50IHNldCBvZiBmdW5jdGlvbnMgdGhhdCBtYXkKZXZlciBiZSBpbiB1 c2UgaW4gYSBwcmVtYXAgY2FsbGJhY2ssIGJ1dCBpbiBtb3N0IGNhc2VzIHRo ZSBjYWxsYmFjawpzaG91bGQganVzdCBiZSBkaXNhYmxlZC4KCgpMaW1pdGF0 aW9uczoKCi0gSWYgeW91IG5lZWQgdG8gbG9hZCB0aGUgc29saWIgZnJvbSBh bm9ueW1vdXNseS1tYXBwZWQgYnVmZmVyLCB5b3UgbmVlZAogIHRvIHVzZSBN QVBfU0hBUkVEfE1BUF9BTk9OWU1PVVMgbW1hcCBmbGFncyB3aGVuIGNyZWF0 aW5nIHRoYXQgYnVmZmVyLgogIElmIGl0IGlzIG5vdCBwb3NzaWJsZSBpbiB5 b3VyIHVzZS1jYXNlIGFuZCB0aGUgYnVmZmVyIHdhcyBjcmVhdGVkCiAgd2l0 aCBNQVBfUFJJVkFURXxNQVBfQU5PTllNT1VTIGZsYWdzLCB0aGVuIERMTUVN X0dFTkJVRl9TUkMgZmxhZwogIG5lZWRzIHRvIGJlIHNldCB3aGVuIGNhbGxp bmcgZGxtZW0oKS4KICBGYWlsdXJlIHRvIGZvbGxvdyB0aGF0IGd1aWRlLWxp bmUgcmVzdWx0cyBpbiBhbiBVQiAobG9hZGVyIHdpbGwgbm90CiAgYmUgYWJs ZSB0byBwcm9wZXJseSBsYXkgb3V0IGFuIGVsZiBzZWdtZW50cykuCgotIElm IHlvdSB1c2UgYSBwcml2YXRlIGZpbGUtYmFja2VkIG1hcHBpbmcsIHRoZW4g aXQgc2hvdWxkbid0IGJlCiAgbW9kaWZpZWQgYnkgaGFuZHMgYmVmb3JlIHBh c3NpbmcgdG8gZGxtZW0oKS4gSS5lLiB5b3UgY2FuJ3QgYXBwbHkKICBtcHJv dGVjdCgpIHRvIGl0IHRvIGNoYW5nZSBwcm90ZWN0aW9uIGJpdHMsIGFuZCB5 b3UgY2FuJ3QgYXBwbHkKICBtZW1tb3ZlKCkgdG8gaXQgdG8gbW92ZSB0aGUg c29saWIgdG8gdGhlIGJlZ2lubmluZyBvZiB0aGUgYnVmZmVyLAogIGFuZCBz byBvbi4gZGxtZW0oKSBjYW4gb25seSB3b3JrIHdpdGggInZpcmdpbiIgcHJp dmF0ZSBmaWxlLWJhY2tlZAogIG1hcHBpbmdzLiBZb3UgY2FuIHNldCBETE1F TV9HRU5CVUZfU1JDIGZsYWcgYXMgYSB3b3JrLWFyb3VuZCBpZgogIHRoZSBt YXBwaW5nIGlzIGFscmVhZHkgY29ycnVwdGVkLgogIEZhaWx1cmUgdG8gZm9s bG93IHRoYXQgZ3VpZGUtbGluZSByZXN1bHRzIGluIGFuIFVCIChsb2FkZXIg d2lsbCBub3QKICBiZSBhYmxlIHRvIHByb3Blcmx5IGxheSBvdXQgYW4gZWxm IHNlZ21lbnRzKS4KCi0gVGhlIG5lZWQgb2YgbWFwcGluZyB0aGUgZW50aXJl IHNvbGliICh3aXRoIGRlYnVnIGluZm8gZXRjKSBtYXkKICByZXByZXNlbnQg YSBwcm9ibGVtIG9uIGEgMzJiaXQgYXJjaGl0ZWN0dXJlcyBpZiB0aGUgc29s aWIgaGFzIGFuCiAgYWJzdXJkbHkgbGFyZ2Ugc2l6ZSwgbGlrZSAzR2Igb3Ig bW9yZS4KCi0gRm9yIHRoZSB2ZXJ5IHNhbWUgcmVhc29uIHRoZSBlZmZpY2ll bnQgaW1wbGVtZW50YXRpb24gb2YgQW5kcm9pZCdzCiAgZGxvcGVuX3dpdGhf b2Zmc2V0KCkgaXMgZGlmZmljdWx0LCBhcyBpbiB0aGF0IGNhc2UgeW91J2Qg bmVlZCB0bwogIG1hcCB0aGUgZW50aXJlIGZpbGUgY29udGFpbmVyLCBzdGFy dGluZyBmcm9tIHRoZSBuZWVkZWQgb2Zmc2V0LgogIFRoZSBkZW1vIGltcGxl bWVudGF0aW9uIGluIHRoaXMgcGF0Y2ggaW1wbGVtZW50cyBkbG9wZW5fd2l0 aF9vZmZzZXQ0KCkKICB0aGF0IGhhcyBhbiBhZGRpdGlvbmFsICJsZW5ndGgi IGFyZ3VtZW50IHdoZXJlIHRoZSBzb2xpYiBsZW5ndGgKICBzaG91bGQgYmUg cGFzc2VkLgoKLSBBcyBsaW51eCBkb2Vzbid0IGltcGxlbWVudCBNQVBfVU5B TElHTkVEIGFzIHNvbWUgdW5peGVzIGRpZCwgdGhlCiAgZWZmaWNpZW50IGlt cGxlbWVudGF0aW9uIG9mIGRsb3Blbl93aXRoX29mZnNldDQoKSBpcyBkaWZm aWN1bHQKICBpZiB0aGUgb2Zmc2V0IGlzIG5vdCBwYWdlLWFsaWduZWQuIERl bW8gaW4gdGhpcyBleGFtcGxlIGZpeGVzIHRoZQogIGFsaWdubWVudCBieSBo YW5kcywgdXNpbmcgdGhlIE1BUF9TSEFSRUR8TUFQX0FOT05ZTU9VUyBpbnRl cm1lZGlhdGUKICBidWZmZXIuIFRoZSBhbGlnbm1lbnQgY2Fubm90IGJlIGZp eGVkIGluIGFuIGV4aXN0aW5nIGJ1ZmZlciB3aXRoCiAgbWVtbW92ZSgpLCBh cyB0aGF0IHdpbGwgbWFrZSB0aGUgZmlsZS1iYWNrZWQgbWFwcGluZyB1bmFj Y2VwdGFibGUKICBmb3IgdGhlIHVzZSB3aXRoIGRsbWVtKCkuIEkgc3VzcGVj dCB0aGF0IGdvb2dsZSdzIGRsb3Blbl93aXRoX29mZnNldCgpCiAgaGFzIHNp bWlsYXIgbGltaXRhdGlvbiBiZWNhdXNlIG1tYXAoKSB3aXRoIHVuYWxpZ25l ZCBvZmZzZXQgaXMKICBub3QgcG9zc2libGUgaW4gYW55IGltcGxlbWVudGF0 aW9uLCBiZSBpdCBhICJkaXJlY3QiIGltcGxlbWVudGF0aW9uCiAgb3IgIm92 ZXItZGxtZW0iIGltcGxlbWVudGF0aW9uLgoKCkNoYW5nZXMgaW4gdjEwOgot IGFkZHJlc3NlZCByZXZpZXcgY29tbWVudHMgb2YgQWRoZW1lcnZhbCBaYW5l bGxhCi0gbW92ZWQgcmVmYWN0b3IgcGF0Y2hlcyB0byB0aGUgYmVnaW5uaW5n IG9mIHRoZSBzZXJpZSB0byBzaW1wbGlmeSByZXZpZXcKLSBmaXhlZCBhIGZl dyBidWdzIGluIGFuIGVsZiByZWxvY2F0aW9uIG1hY2hpbmVyeSBhZnRlciB2 YXJpb3VzIGhvdCBkaXNjdXNzaW9ucwotIGFkZGVkIGEgbmV3IHRlc3QgdHN0 LWRsbWVtLWV4dGZucyB0aGF0IGRlbW8taW1wbGVtZW50cyBkbG9wZW5fd2l0 aF9vZmZzZXQ0KCkKICBhbmQgZmRsb3BlbigpCi0gc3R1ZGllZCBhbmQgZG9j dW1lbnRlZCBhbGwgbGltaXRhdGlvbnMsIG1vc3QgaW1wb3J0YW50bHkgdGhv c2UgbGVhZGluZyB0byBVQgotIGJldHRlciBkb2N1bWVudGVkIHByZW1hcCBj YWxsYmFjayBhcyBzdWdnZXN0ZWQgYnkgU3phYm9sY3MgTmFneQotIGFkZGVk IERMTUVNX0dFTkJVRl9TUkMgZmxhZyBmb3IgdW5hbGlnbmVkIGdlbmVyaWMg bWVtb3J5IGJ1ZmZlcnMKCkNoYW5nZXMgaW4gdjk6Ci0gdXNlICJ6ZXJvLWNv cHkiIG1hY2hpbmVyeSBpbnN0ZWFkIG9mIG1lbWNweSgpLiBJdCB3b3JrcyBv biBsaW51eCA1LjEzCiAgYW5kIG5ld2VyLCBmYWxsaW5nIGJhY2sgdG8gbWVt Y3B5KCkgb3RoZXJ3aXNlLiBTdWdnZXN0ZWQgYnkgRmxvcmlhbiBXZWltZXIu Ci0gaW1wbGVtZW50IGZkbG9wZW4oKSB1c2luZyB0aGUgYWJvdmUgZnVuY3Rp b25hbGl0eS4gSXQgaXMgaW4gYSBuZXcgdGVzdAogIHRzdC1kbG1lbS1mZGxv cGVuLiBTdWdnZXN0ZWQgYnkgQ2FybG9zIE8nRG9uZWxsLgotIGFkZCBETE1F TV9ET05UUkVQTEFDRSBmbGFnIHRoYXQgZG9lc24ndCByZXBsYWNlIHRoZSBi YWNraW5nLXN0b3JlIG1hcHBpbmcuCiAgSXQgc3dpdGNoZXMgYmFjayB0byBt ZW1jcHkoKS4gVGVzdC1jYXNlIGlzIGNhbGxlZCB0c3QtZGxtZW0tc2htLgoK Q2hhbmdlcyBpbiB2ODoKLSBkcm9wIGF1ZGl0IG1hY2hpbmVyeSBhbmQgaW5z dGVhZCBhZGQgYW4gZXh0cmEgYXJnIChvcHRpb25hbCBwb2ludGVyCiAgdG8g YSBzdHJ1Y3QpIHRvIGRsbWVtKCkgaXRzZWxmIHRoYXQgYWxsb3dzIHRvIGlu c3RhbGwgYSBjdXN0b20gcHJlbWFwCiAgY2FsbGJhY2sgb3IgdG8gc3BlY2lm eSBuc2lkLiBBdWRpdCBtYWNoaW5lcnkgd2FzIG1lYW50IHRvIGFsbG93CiAg Y29udHJvbGluZyBvdmVyIHRoZSBwcmUtZXhpc3RpbmcgQVBJcyBsaWtlIGRs b3BlbigpLCBidXQgaWYgc29tZW9uZQogIGV2ZXIgbmVlZHMgc3VjaCBleHRl bnNpb25zIHRvIGRsb3BlbigpLCBoZSBjYW4gdHJpdmlhbGx5IGltcGxlbWVu dAogIGRsb3BlbigpIG9uIHRvcCBvZiBkbG1lbSgpLgoKQ2hhbmdlcyBpbiB2 NzoKLSBhZGQgX2RsX2F1ZGl0X3ByZW1hcCBhdWRpdCBleHRlbnNpb24gYW5k IGl0cyB1c2FnZSBleGFtcGxlCgpDaGFuZ2VzIGluIHY2OgotIHVzZSBfX3N0 cmR1cCgiIikgZm9yIGxfbmFtZSBhcyBzdWdnZXN0ZWQgYnkgQW5kcmVhcyBT Y2h3YWIKCkNoYW5nZXMgaW4gdjU6Ci0gYWRkZWQgX2RsX2F1ZGl0X3ByZW1h cF9kbG1lbSBhdWRpdCBleHRlbnNpb24gZm9yIGRsbWVtCi0gYWRkZWQgdHN0 LWF1ZGl0bW9kLWRsbWVtLmMgdGVzdC1jYXNlIHRoYXQgZmVlZHMgc2htIGZk IHRvIGRsbWVtKCkKCkNoYW5nZXMgaW4gdjQ6Ci0gcmUtdGFyZ2V0IHRvIEdM SUJDXzIuMzgKLSBhZGQgdHN0LWF1ZGl0ZGxtZW0uYyB0ZXN0LWNhc2UgdG8g dGVzdCBhdWRpdGluZwotIGRyb3AgbGVuZ3RoIHBhZ2UtYWxpZ25pbmcgaW4g dHN0LWRsbWVtOiBtbWFwKCkgYWxpZ25zIGxlbmd0aCBvbiBpdHMgb3duCi0g YnVnZml4OiBpbiBkb19tbWFwY3B5KCkgYWxsb3cgbW1hcHMgcGFzdCBlbmQg b2YgYnVmZmVyCgpDaGFuZ2VzIGluIHYzOgotIENoYW5nZWQgcHJvdG90eXBl IG9mIGRsbWVtKCkgKGFuZCBhbGwgdGhlIGludGVybmFsIG1hY2hpbmVyeSkg dG8KICB1c2UgImNvbnN0IHVuc2lnbmVkIGNoYXIgKmJ1ZmZlciIgaW5zdGVh ZCBvZiAiY29uc3QgY2hhciAqYnVmZmVyIi4KCkNoYW5nZXMgaW4gdjI6Ci0g dXNlIDxzdXBwb3J0L3Rlc3QtZHJpdmVyLmM+IGluc3RlYWQgb2YgIi4uL3Rl c3Qtc2tlbGV0b24uYyIKLSByZS10YXJnZXQgdG8gR0xJQkNfMi4zNwotIHVw ZGF0ZSBhbGwgbGliYy5hYmlsaXN0IGZpbGVzCgotLSAKMi4zNy4yCgo= --------------A3Q00wLwSZy3oUPzC4wnQMg7--