From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.ozlabs.org (lists.ozlabs.org [112.213.38.117]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 103B0C88E56 for ; Sat, 12 Sep 2026 18:53:32 +0000 (UTC) Received: from boromir.ozlabs.org (localhost [127.0.0.1]) by lists.ozlabs.org (Postfix) with ESMTP id 4hj0tM0Sg2z2y2h; Sun, 13 Sep 2026 04:53:31 +1000 (AEST) Authentication-Results: lists.ozlabs.org; arc=none smtp.remote-ip="2600:3c0a:e001:78e:0:1991:8:25" ARC-Seal: i=1; a=rsa-sha256; d=lists.ozlabs.org; s=201707; t=1789239210; cv=none; b=iu3IBC4JOqkvgG+pjqO0l/FBCeIadw9PYaf0ubUkXuGp2UioC7Meb82fzRupTWxSqal4T+RzjST2g04/OvUXR5MUXZrdErULqU+zaVhRx4k96H+Hk3rWRJLoBZW/8ojxGK+uRoeXkavesBI1GxoYesVWJ1YqRKuCPZ57w3iWagcmfI/Z8zUAe8Y2B9za+o/CD/TB4ucEeUfGOaOmyQ1AJeNqp7lH1mYC9PCMHZGrTh6Jhb8FntjlX2KkbSrtiMIPDVaeqtzaMhh6qcBvreUR1VixkT4zOldxmsnx5yhOA60SMCVhbdHByqXKfwVaOoCduvZh2RaLPdchLPnoQkRmYw== ARC-Message-Signature: i=1; a=rsa-sha256; d=lists.ozlabs.org; s=201707; t=1789239210; c=relaxed/relaxed; bh=pnYw8oV7PDO5JJNnfCNgZakByu1XteCUnWGxERqr7V4=; h=Message-ID:Date:MIME-Version:Subject:From:To:Cc:References: In-Reply-To:Content-Type; b=CH0kNo9+jbjvH9ekkt1eJ9Q9hF0FB77EqiIlfoUtFyaEn0hPZ+Ap3NBuSwqXcrNWFKOQqvO062up2QiDfq8OxpiD6MGPOXs6C0pHToJJwmaZSU6eNGzQo+/URaqaBy+2grMSaEYUr0OT4hMeQXx3TaRDC9lCwR2RM+z3v65E3MDoP7tcj3wg3uYC9j8K/JDeH6YBaWhp6kZaYdydCTihoRxp2k6z+OHa7WKCetqjOUAXRLxIDQvIiDiSYfxt+fyxgiuCeaqMTBlBz1PMziyC9Il1lsk4m/G30XYetpqcweQZGQtpwUw5z3CDrS5APwBh9LYTyTC0zrWxOKJuVL7cgg== ARC-Authentication-Results: i=1; lists.ozlabs.org; dmarc=pass (p=quarantine dis=none) header.from=kernel.org; dkim=pass (2048-bit key; unprotected) header.d=kernel.org header.i=@kernel.org header.a=rsa-sha256 header.s=k20260515 header.b=LrdvV2Eo; dkim-atps=neutral; spf=pass (client-ip=2600:3c0a:e001:78e:0:1991:8:25; helo=sea.source.kernel.org; envelope-from=chleroy@kernel.org; receiver=lists.ozlabs.org) smtp.mailfrom=kernel.org Authentication-Results: lists.ozlabs.org; dmarc=pass (p=quarantine dis=none) header.from=kernel.org Authentication-Results: lists.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=kernel.org header.i=@kernel.org header.a=rsa-sha256 header.s=k20260515 header.b=LrdvV2Eo; dkim-atps=neutral Authentication-Results: lists.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=kernel.org (client-ip=2600:3c0a:e001:78e:0:1991:8:25; helo=sea.source.kernel.org; envelope-from=chleroy@kernel.org; receiver=lists.ozlabs.org) Received: from sea.source.kernel.org (sea.source.kernel.org [IPv6:2600:3c0a:e001:78e:0:1991:8:25]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange x25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by lists.ozlabs.org (Postfix) with ESMTPS id 4hj0tK6CLJz2xWV for ; Sun, 13 Sep 2026 04:53:29 +1000 (AEST) Received: from smtp.kernel.org (quasi.space.kernel.org [100.103.45.18]) by sea.source.kernel.org (Postfix) with ESMTP id 888D74174B; Sat, 12 Sep 2026 18:53:25 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 36E931F00893; Sat, 12 Sep 2026 18:53:19 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1789239205; bh=pnYw8oV7PDO5JJNnfCNgZakByu1XteCUnWGxERqr7V4=; h=Date:Subject:From:To:Cc:References:In-Reply-To; b=LrdvV2EoAwqvph+f6BPThyZ2EUHBeXS5A4ViAyKyQzIRTRjD4+TIY7uk9QC14YzFD kopVm/CwYxzkzDRhDT+IrnF35QpG0aicyJBZVXF9kcM43pnoK4rjR8VPcs6SgrpVvg DywpldBL3OE85cJI8xG/ERzO1gCcCbbYdU6STM8Dbc7Jjqb2aEkse/dnMV6zygObkC uRohCFKBSiWN+l6+iOm/wEpBYqvAbGee5mU2lmX315izCLKyWjyK5/ji6p6O/6VTcS DY54SemGEI4A6nr58Lejxzeejy48+ZPp5SDeqcinjFvCgTBwDKPBQaZtSZfBsSbjjC TNF5uD9qGGixA== Message-ID: <3d327595-791c-4a7a-ae65-afae80c9c848@kernel.org> Date: Sat, 12 Sep 2026 20:53:16 +0200 X-Mailing-List: linuxppc-dev@lists.ozlabs.org List-Id: List-Help: List-Owner: List-Post: List-Archive: , List-Subscribe: , , List-Unsubscribe: Precedence: list MIME-Version: 1.0 User-Agent: Mozilla Thunderbird Subject: Re: [PATCH] powerpc/kasan: require memintrinsic prefix support for KASAN From: "Christophe Leroy (CS GROUP)" To: Mukesh Kumar Chaurasiya Cc: maddy@linux.ibm.com, mpe@ellerman.id.au, npiggin@gmail.com, ryabinin.a.a@gmail.com, glider@google.com, andreyknvl@gmail.com, dvyukov@google.com, vincenzo.frascino@arm.com, pjw@kernel.org, palmer@dabbelt.com, aou@eecs.berkeley.edu, alex@ghiti.fr, kees@kernel.org, amachhiw@linux.ibm.com, ritesh.list@gmail.com, robh@kernel.org, sayalip@linux.ibm.com, linuxppc-dev@lists.ozlabs.org, linux-kernel@vger.kernel.org, kasan-dev@googlegroups.com, linux-riscv@lists.infradead.org, linux-hardening@vger.kernel.org, Venkat Rao Bagalkote References: <20260908064948.999530-1-mkchauras@gmail.com> <2dedc7a9-95f5-4a7f-8d38-6b9351db402f@kernel.org> Content-Language: fr-FR In-Reply-To: <2dedc7a9-95f5-4a7f-8d38-6b9351db402f@kernel.org> Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 8bit Le 12/09/2026 à 19:35, Christophe Leroy (CS GROUP) a écrit : > Hi Mukesh, > > Le 11/09/2026 à 19:39, Mukesh Kumar Chaurasiya a écrit : >> >> [...] >>>> diff --git a/arch/powerpc/kernel/cputable.c b/arch/powerpc/kernel/ >>>> cputable.c >>>> index 6f6801da9dc1..44115f904c2c 100644 >>>> --- a/arch/powerpc/kernel/cputable.c >>>> +++ b/arch/powerpc/kernel/cputable.c >>>> @@ -36,8 +36,8 @@ void __init set_cur_cpu_spec(struct cpu_spec *s) >>>>        t = PTRRELOC(t); >>>>        /* >>>> -     * use memcpy() instead of *t = *s so that GCC replaces it >>>> -     * by __memcpy() when KASAN is active >>>> +     * use memcpy() instead of *t = *s so that the compiler >>>> replaces it >>>> +     * by __asan_memcpy() when KASAN is active >>>>         */ >>> >>> Does the initial problem still exist with the new __asan_memcpy() >>> approach ? >>> If not the comment should be removed. >>> >> Hey Christophe, >> >> Thanks for pointing it out, i took a deeper look into this, here's my >> understanding on it. >> >> On PowerPC during very early boot the kernel is loaded by the >> bootloader/firmware at some physical address, but the kernel was linked >> expecting it to run at KERNELBASE(virtual address like >> 0xc000000000000000). The MMU mapping that makes that virtual address >> valid hasn't been set up yet. So far for a window of early boot, code is >> executing at the physical load address while all symbol addresses in the >> binary refer to the virtual linked address. reloc_offset() computes the >> gap between these two and PTRRELOC applies it to any pointer. >> >> So PTRRELOC(&the_cpu_spec) gives the physical address where the struct >> actually lives in memory right now, not where the linker thinks it lives. >> >> Why *t = *s would be wrong? >> >> In set_cur_cpu_spec: >> >> struct cpu_spec *t = &the_cpu_spec;  // linked (virtual) address >> t = PTRRELOC(t);                     // physical address — where it >> actually is >> memcpy(t, s, sizeof(*t));            // copy into the right place >> >> If you wrote *t = *s instead, the compiler generates a struct assignment. >> For a large struct like cpu_spec, GCC is free to implement that however >> it likes — including emitting a call to memcpy(). But crucially, a >> compiler-generated memcpy call resolves through the GOT/PLT or direct >> symbol — which points to the linked virtual address of memcpy, not the >> physical address. At this point in boot, calling through the wrong >> address would jump to garbage or an unmapped page. >> >> memcpy(t, s, sizeof(*t)) written explicitly is different: t is already >> the corrected physical address, s points into the cpu_specs table which >> has also been PTRRELOC'd. The explicit call goes through the normal >> early-boot call mechanism which is safe. >> >> The original comment said: >> >> "use memcpy() instead of *t = *s so that GCC replaces it by __memcpy() >> when KASAN is active" >> >> This was added because under the old KASAN scheme >> (!CC_HAS_KASAN_MEMINTRINSIC_PREFIX), KASAN overrode the memset/memcpy >> linker symbols globally with C wrappers that called kasan_check_range(). >> If the compiler turned *t = *s into an implicit memcpy(), that would hit >> the KASAN wrapper — calling kasan_check_range() at a point in early boot >> where the KASAN shadow isn't mapped yet, causing a crash. >> >> Writing memcpy(t, s, sizeof(*t)) explicitly made GCC emit __memcpy() >> (the raw assembly alias exposed by _GLOBAL_KASAN) instead of the >> KASAN-wrapped memcpy(), bypassing the shadow check. >> >> That was the secondary reason. The primary reason that t is a >> PTRRELOC-adjusted physical pointer and the copy must go through it >> correctly was never stated. >> >> So the KASAN comment is not required but i think we still need to state >> why memcpy is required. For PTRRELOC adjustment, comment should reflect >> that. >> >> I'll update the comment and commit message and send out a new version. > > Explanation based on kernel v5.10 > > The problem was not linked to PTRRELOC, the t = PTRRELOC(t) followed by > *t = *s works well in term of adressing, regardless of whether > CONFIG_KASAN is enabled or not. > > The problem is that with *t = *s, gcc emits a call to memcpy(). When > CONFIG_KASAN is enabled, memcpy() is instrumented. But we don't want > cputable.o instrumented as we have KASAN_SANITIZE_cputable.o := n in > Makefile. > > In asm/string.h we have: > > #if defined(CONFIG_KASAN) && !defined(__SANITIZE_ADDRESS__) > /* >  * For files that are not instrumented (e.g. mm/slub.c) we >  * should use not instrumented version of mem* functions. >  */ > #define memcpy(dst, src, len) __memcpy(dst, src, len) > #define memmove(dst, src, len) __memmove(dst, src, len) > #define memset(s, c, n) __memset(s, c, n) > > Because in non-instrumented files like cputable.o we want memcpy() to be > replaced at buildtime by __memcpy() to skip KASAN instrumentation. But > this is resolved by pre-processing, and pre-processor doesn't know that > the compiler will emit a call to memcpy(). > > By replacing *t = *s by the memcpy(), the pre-processor replaces > memcpy() by __memcpy() when CONFIG_KASAN is enabled. > > See the difference: > > This is v5.10 > > 00000000 : >    0:    94 21 ff e0     stwu    r1,-32(r1) >    4:    7c 69 1b 78     mr      r9,r3 >    8:    bf c1 00 18     stmw    r30,24(r1) >    c:    3f e0 00 00     lis     r31,0 >             e: R_PPC_ADDR16_HA    .data..read_mostly >   10:    3b ff 00 00     addi    r31,r31,0 >             12: R_PPC_ADDR16_LO    .data..read_mostly >   14:    7c 08 02 a6     mflr    r0 >   18:    7d 3e 4b 78     mr      r30,r9 >   1c:    7f e3 fb 78     mr      r3,r31 >   20:    90 01 00 24     stw     r0,36(r1) >   24:    48 00 00 01     bl      24 >             24: R_PPC_REL24    add_reloc_offset >   28:    7f c4 f3 78     mr      r4,r30 >   2c:    38 a0 00 58     li      r5,88 >   30:    48 00 00 01     bl      30 >             30: R_PPC_REL24    __memcpy >   34:    38 7f 00 58     addi    r3,r31,88 >   38:    48 00 00 01     bl      38 >             38: R_PPC_REL24    add_reloc_offset >   3c:    93 e3 00 00     stw     r31,0(r3) >   40:    80 01 00 24     lwz     r0,36(r1) >   44:    83 c1 00 18     lwz     r30,24(r1) >   48:    83 e1 00 1c     lwz     r31,28(r1) >   4c:    7c 08 03 a6     mtlr    r0 >   50:    38 21 00 20     addi    r1,r1,32 >   54:    4e 80 00 20     blr > > This is v5.10 with commit adcf59187e270 reverted: > > 00000000 : >    0:    94 21 ff e0     stwu    r1,-32(r1) >    4:    7c 69 1b 78     mr      r9,r3 >    8:    bf c1 00 18     stmw    r30,24(r1) >    c:    3f e0 00 00     lis     r31,0 >             e: R_PPC_ADDR16_HA    .data..read_mostly >   10:    3b ff 00 00     addi    r31,r31,0 >             12: R_PPC_ADDR16_LO    .data..read_mostly >   14:    7c 08 02 a6     mflr    r0 >   18:    7d 3e 4b 78     mr      r30,r9 >   1c:    7f e3 fb 78     mr      r3,r31 >   20:    90 01 00 24     stw     r0,36(r1) >   24:    48 00 00 01     bl      24 >             24: R_PPC_REL24    add_reloc_offset >   28:    7f c4 f3 78     mr      r4,r30 >   2c:    38 a0 00 58     li      r5,88 >   30:    48 00 00 01     bl      30 >             30: R_PPC_REL24    memcpy >   34:    38 7f 00 58     addi    r3,r31,88 >   38:    48 00 00 01     bl      38 >             38: R_PPC_REL24    add_reloc_offset >   3c:    93 e3 00 00     stw     r31,0(r3) >   40:    80 01 00 24     lwz     r0,36(r1) >   44:    83 c1 00 18     lwz     r30,24(r1) >   48:    83 e1 00 1c     lwz     r31,28(r1) >   4c:    7c 08 03 a6     mtlr    r0 >   50:    38 21 00 20     addi    r1,r1,32 >   54:    4e 80 00 20     blr > > So my question is ? Do we still have this issue nowadays ? I now did the same test with v7.2 without and with adcf59187e270 reverted. I both cases I get memcpy(). Christophe From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 093D3C88E53 for ; Sat, 12 Sep 2026 18:53:55 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender:Content-Type: Content-Transfer-Encoding:List-Subscribe:List-Help:List-Post:List-Archive: List-Unsubscribe:List-Id:In-Reply-To:References:Cc:To:From:Subject: MIME-Version:Date:Message-ID:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=iiImPXBaOZ2dDLD5vzybh8ahnQGKFj+rL2ByLXOAPVk=; b=1CkuTODKsm/uGj mUD8bWT193RrrxDWhQTX2fF6h/OeTDMV4N9psN+AnwBz48VMc0M8YLsnzjaMg9rQzWpnqwmA3O41u eqj6KWLDozUu/9MMkHNfg/5ZSF3M9Qq+1sQPoZ4u8JUh0IyVSSL2nbnijYVJIELLkcLula2xj9Acj FqC+B7S8nbE5rV+I1AiIBQQ8W4MusGe8yO+Y3wunUJP1JROUc2qFBbzDHhE7t8Xq1uHDsoO2/kl5j k1lgeQAAGYZYvMpOSFsphNoFW5PfBFnk+LiBzpV14Fm7tbdB4sIuhP/VLsClR353SS++ewq7p7QqI 6CzUfTtehmZLgBOAYmhg==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.99.1 #2 (Red Hat Linux)) id 1x5Sqt-000000014ab-3mjp; Sat, 12 Sep 2026 18:53:27 +0000 Received: from sea.source.kernel.org ([172.234.252.31]) by bombadil.infradead.org with esmtps (Exim 4.99.1 #2 (Red Hat Linux)) id 1x5Sqs-000000014aV-1mp4 for linux-riscv@lists.infradead.org; Sat, 12 Sep 2026 18:53:26 +0000 Received: from smtp.kernel.org (quasi.space.kernel.org [100.103.45.18]) by sea.source.kernel.org (Postfix) with ESMTP id 888D74174B; Sat, 12 Sep 2026 18:53:25 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 36E931F00893; Sat, 12 Sep 2026 18:53:19 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1789239205; bh=pnYw8oV7PDO5JJNnfCNgZakByu1XteCUnWGxERqr7V4=; h=Date:Subject:From:To:Cc:References:In-Reply-To; b=LrdvV2EoAwqvph+f6BPThyZ2EUHBeXS5A4ViAyKyQzIRTRjD4+TIY7uk9QC14YzFD kopVm/CwYxzkzDRhDT+IrnF35QpG0aicyJBZVXF9kcM43pnoK4rjR8VPcs6SgrpVvg DywpldBL3OE85cJI8xG/ERzO1gCcCbbYdU6STM8Dbc7Jjqb2aEkse/dnMV6zygObkC uRohCFKBSiWN+l6+iOm/wEpBYqvAbGee5mU2lmX315izCLKyWjyK5/ji6p6O/6VTcS DY54SemGEI4A6nr58Lejxzeejy48+ZPp5SDeqcinjFvCgTBwDKPBQaZtSZfBsSbjjC TNF5uD9qGGixA== Message-ID: <3d327595-791c-4a7a-ae65-afae80c9c848@kernel.org> Date: Sat, 12 Sep 2026 20:53:16 +0200 MIME-Version: 1.0 User-Agent: Mozilla Thunderbird Subject: Re: [PATCH] powerpc/kasan: require memintrinsic prefix support for KASAN From: "Christophe Leroy (CS GROUP)" To: Mukesh Kumar Chaurasiya Cc: maddy@linux.ibm.com, mpe@ellerman.id.au, npiggin@gmail.com, ryabinin.a.a@gmail.com, glider@google.com, andreyknvl@gmail.com, dvyukov@google.com, vincenzo.frascino@arm.com, pjw@kernel.org, palmer@dabbelt.com, aou@eecs.berkeley.edu, alex@ghiti.fr, kees@kernel.org, amachhiw@linux.ibm.com, ritesh.list@gmail.com, robh@kernel.org, sayalip@linux.ibm.com, linuxppc-dev@lists.ozlabs.org, linux-kernel@vger.kernel.org, kasan-dev@googlegroups.com, linux-riscv@lists.infradead.org, linux-hardening@vger.kernel.org, Venkat Rao Bagalkote References: <20260908064948.999530-1-mkchauras@gmail.com> <2dedc7a9-95f5-4a7f-8d38-6b9351db402f@kernel.org> Content-Language: fr-FR In-Reply-To: <2dedc7a9-95f5-4a7f-8d38-6b9351db402f@kernel.org> X-BeenThere: linux-riscv@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Content-Transfer-Encoding: base64 Content-Type: text/plain; charset="utf-8"; Format="flowed" Sender: "linux-riscv" Errors-To: linux-riscv-bounces+linux-riscv=archiver.kernel.org@lists.infradead.org CgpMZSAxMi8wOS8yMDI2IMOgIDE5OjM1LCBDaHJpc3RvcGhlIExlcm95IChDUyBHUk9VUCkgYSDD qWNyaXTCoDoKPiBIaSBNdWtlc2gsCj4gCj4gTGUgMTEvMDkvMjAyNiDDoCAxOTozOSwgTXVrZXNo IEt1bWFyIENoYXVyYXNpeWEgYSDDqWNyaXTCoDoKPj4KPj4gWy4uLl0KPj4+PiBkaWZmIC0tZ2l0 IGEvYXJjaC9wb3dlcnBjL2tlcm5lbC9jcHV0YWJsZS5jIGIvYXJjaC9wb3dlcnBjL2tlcm5lbC8g Cj4+Pj4gY3B1dGFibGUuYwo+Pj4+IGluZGV4IDZmNjgwMWRhOWRjMS4uNDQxMTVmOTA0YzJjIDEw MDY0NAo+Pj4+IC0tLSBhL2FyY2gvcG93ZXJwYy9rZXJuZWwvY3B1dGFibGUuYwo+Pj4+ICsrKyBi L2FyY2gvcG93ZXJwYy9rZXJuZWwvY3B1dGFibGUuYwo+Pj4+IEBAIC0zNiw4ICszNiw4IEBAIHZv aWQgX19pbml0IHNldF9jdXJfY3B1X3NwZWMoc3RydWN0IGNwdV9zcGVjICpzKQo+Pj4+IMKgwqDC oMKgwqDCoCB0ID0gUFRSUkVMT0ModCk7Cj4+Pj4gwqDCoMKgwqDCoMKgIC8qCj4+Pj4gLcKgwqDC oMKgICogdXNlIG1lbWNweSgpIGluc3RlYWQgb2YgKnQgPSAqcyBzbyB0aGF0IEdDQyByZXBsYWNl cyBpdAo+Pj4+IC3CoMKgwqDCoCAqIGJ5IF9fbWVtY3B5KCkgd2hlbiBLQVNBTiBpcyBhY3RpdmUK Pj4+PiArwqDCoMKgwqAgKiB1c2UgbWVtY3B5KCkgaW5zdGVhZCBvZiAqdCA9ICpzIHNvIHRoYXQg dGhlIGNvbXBpbGVyIAo+Pj4+IHJlcGxhY2VzIGl0Cj4+Pj4gK8KgwqDCoMKgICogYnkgX19hc2Fu X21lbWNweSgpIHdoZW4gS0FTQU4gaXMgYWN0aXZlCj4+Pj4gwqDCoMKgwqDCoMKgwqAgKi8KPj4+ Cj4+PiBEb2VzIHRoZSBpbml0aWFsIHByb2JsZW0gc3RpbGwgZXhpc3Qgd2l0aCB0aGUgbmV3IF9f YXNhbl9tZW1jcHkoKSAKPj4+IGFwcHJvYWNoID8KPj4+IElmIG5vdCB0aGUgY29tbWVudCBzaG91 bGQgYmUgcmVtb3ZlZC4KPj4+Cj4+IEhleSBDaHJpc3RvcGhlLAo+Pgo+PiBUaGFua3MgZm9yIHBv aW50aW5nIGl0IG91dCwgaSB0b29rIGEgZGVlcGVyIGxvb2sgaW50byB0aGlzLCBoZXJlJ3MgbXkK Pj4gdW5kZXJzdGFuZGluZyBvbiBpdC4KPj4KPj4gT24gUG93ZXJQQyBkdXJpbmcgdmVyeSBlYXJs eSBib290IHRoZSBrZXJuZWwgaXMgbG9hZGVkIGJ5IHRoZQo+PiBib290bG9hZGVyL2Zpcm13YXJl IGF0IHNvbWUgcGh5c2ljYWwgYWRkcmVzcywgYnV0IHRoZSBrZXJuZWwgd2FzIGxpbmtlZAo+PiBl eHBlY3RpbmcgaXQgdG8gcnVuIGF0IEtFUk5FTEJBU0UodmlydHVhbCBhZGRyZXNzIGxpa2UKPj4g MHhjMDAwMDAwMDAwMDAwMDAwKS4gVGhlIE1NVSBtYXBwaW5nIHRoYXQgbWFrZXMgdGhhdCB2aXJ0 dWFsIGFkZHJlc3MKPj4gdmFsaWQgaGFzbid0IGJlZW4gc2V0IHVwIHlldC4gU28gZmFyIGZvciBh IHdpbmRvdyBvZiBlYXJseSBib290LCBjb2RlIGlzCj4+IGV4ZWN1dGluZyBhdCB0aGUgcGh5c2lj YWwgbG9hZCBhZGRyZXNzIHdoaWxlIGFsbCBzeW1ib2wgYWRkcmVzc2VzIGluIHRoZQo+PiBiaW5h cnkgcmVmZXIgdG8gdGhlIHZpcnR1YWwgbGlua2VkIGFkZHJlc3MuIHJlbG9jX29mZnNldCgpIGNv bXB1dGVzIHRoZQo+PiBnYXAgYmV0d2VlbiB0aGVzZSB0d28gYW5kIFBUUlJFTE9DIGFwcGxpZXMg aXQgdG8gYW55IHBvaW50ZXIuCj4+Cj4+IFNvIFBUUlJFTE9DKCZ0aGVfY3B1X3NwZWMpIGdpdmVz IHRoZSBwaHlzaWNhbCBhZGRyZXNzIHdoZXJlIHRoZSBzdHJ1Y3QKPj4gYWN0dWFsbHkgbGl2ZXMg aW4gbWVtb3J5IHJpZ2h0IG5vdywgbm90IHdoZXJlIHRoZSBsaW5rZXIgdGhpbmtzIGl0IGxpdmVz Lgo+Pgo+PiBXaHkgKnQgPSAqcyB3b3VsZCBiZSB3cm9uZz8KPj4KPj4gSW4gc2V0X2N1cl9jcHVf c3BlYzoKPj4KPj4gc3RydWN0IGNwdV9zcGVjICp0ID0gJnRoZV9jcHVfc3BlYzvCoCAvLyBsaW5r ZWQgKHZpcnR1YWwpIGFkZHJlc3MKPj4gdCA9IFBUUlJFTE9DKHQpO8KgwqDCoMKgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgLy8gcGh5c2ljYWwgYWRkcmVzcyDigJQgd2hlcmUgaXQg Cj4+IGFjdHVhbGx5IGlzCj4+IG1lbWNweSh0LCBzLCBzaXplb2YoKnQpKTvCoMKgwqDCoMKgwqDC oMKgwqDCoMKgIC8vIGNvcHkgaW50byB0aGUgcmlnaHQgcGxhY2UKPj4KPj4gSWYgeW91IHdyb3Rl ICp0ID0gKnMgaW5zdGVhZCwgdGhlIGNvbXBpbGVyIGdlbmVyYXRlcyBhIHN0cnVjdCBhc3NpZ25t ZW50Lgo+PiBGb3IgYSBsYXJnZSBzdHJ1Y3QgbGlrZSBjcHVfc3BlYywgR0NDIGlzIGZyZWUgdG8g aW1wbGVtZW50IHRoYXQgaG93ZXZlcgo+PiBpdCBsaWtlcyDigJQgaW5jbHVkaW5nIGVtaXR0aW5n IGEgY2FsbCB0byBtZW1jcHkoKS4gQnV0IGNydWNpYWxseSwgYQo+PiBjb21waWxlci1nZW5lcmF0 ZWQgbWVtY3B5IGNhbGwgcmVzb2x2ZXMgdGhyb3VnaCB0aGUgR09UL1BMVCBvciBkaXJlY3QKPj4g c3ltYm9sIOKAlCB3aGljaCBwb2ludHMgdG8gdGhlIGxpbmtlZCB2aXJ0dWFsIGFkZHJlc3Mgb2Yg bWVtY3B5LCBub3QgdGhlCj4+IHBoeXNpY2FsIGFkZHJlc3MuIEF0IHRoaXMgcG9pbnQgaW4gYm9v dCwgY2FsbGluZyB0aHJvdWdoIHRoZSB3cm9uZwo+PiBhZGRyZXNzIHdvdWxkIGp1bXAgdG8gZ2Fy YmFnZSBvciBhbiB1bm1hcHBlZCBwYWdlLgo+Pgo+PiBtZW1jcHkodCwgcywgc2l6ZW9mKCp0KSkg d3JpdHRlbiBleHBsaWNpdGx5IGlzIGRpZmZlcmVudDogdCBpcyBhbHJlYWR5Cj4+IHRoZSBjb3Jy ZWN0ZWQgcGh5c2ljYWwgYWRkcmVzcywgcyBwb2ludHMgaW50byB0aGUgY3B1X3NwZWNzIHRhYmxl IHdoaWNoCj4+IGhhcyBhbHNvIGJlZW4gUFRSUkVMT0MnZC4gVGhlIGV4cGxpY2l0IGNhbGwgZ29l cyB0aHJvdWdoIHRoZSBub3JtYWwKPj4gZWFybHktYm9vdCBjYWxsIG1lY2hhbmlzbSB3aGljaCBp cyBzYWZlLgo+Pgo+PiBUaGUgb3JpZ2luYWwgY29tbWVudCBzYWlkOgo+Pgo+PiAidXNlIG1lbWNw eSgpIGluc3RlYWQgb2YgKnQgPSAqcyBzbyB0aGF0IEdDQyByZXBsYWNlcyBpdCBieSBfX21lbWNw eSgpCj4+IHdoZW4gS0FTQU4gaXMgYWN0aXZlIgo+Pgo+PiBUaGlzIHdhcyBhZGRlZCBiZWNhdXNl IHVuZGVyIHRoZSBvbGQgS0FTQU4gc2NoZW1lCj4+ICghQ0NfSEFTX0tBU0FOX01FTUlOVFJJTlNJ Q19QUkVGSVgpLCBLQVNBTiBvdmVycm9kZSB0aGUgbWVtc2V0L21lbWNweQo+PiBsaW5rZXIgc3lt Ym9scyBnbG9iYWxseSB3aXRoIEMgd3JhcHBlcnMgdGhhdCBjYWxsZWQga2FzYW5fY2hlY2tfcmFu Z2UoKS4KPj4gSWYgdGhlIGNvbXBpbGVyIHR1cm5lZCAqdCA9ICpzIGludG8gYW4gaW1wbGljaXQg bWVtY3B5KCksIHRoYXQgd291bGQgaGl0Cj4+IHRoZSBLQVNBTiB3cmFwcGVyIOKAlCBjYWxsaW5n IGthc2FuX2NoZWNrX3JhbmdlKCkgYXQgYSBwb2ludCBpbiBlYXJseSBib290Cj4+IHdoZXJlIHRo ZSBLQVNBTiBzaGFkb3cgaXNuJ3QgbWFwcGVkIHlldCwgY2F1c2luZyBhIGNyYXNoLgo+Pgo+PiBX cml0aW5nIG1lbWNweSh0LCBzLCBzaXplb2YoKnQpKSBleHBsaWNpdGx5IG1hZGUgR0NDIGVtaXQg X19tZW1jcHkoKQo+PiAodGhlIHJhdyBhc3NlbWJseSBhbGlhcyBleHBvc2VkIGJ5IF9HTE9CQUxf S0FTQU4pIGluc3RlYWQgb2YgdGhlCj4+IEtBU0FOLXdyYXBwZWQgbWVtY3B5KCksIGJ5cGFzc2lu ZyB0aGUgc2hhZG93IGNoZWNrLgo+Pgo+PiBUaGF0IHdhcyB0aGUgc2Vjb25kYXJ5IHJlYXNvbi4g VGhlIHByaW1hcnkgcmVhc29uIHRoYXQgdCBpcyBhCj4+IFBUUlJFTE9DLWFkanVzdGVkIHBoeXNp Y2FsIHBvaW50ZXIgYW5kIHRoZSBjb3B5IG11c3QgZ28gdGhyb3VnaCBpdAo+PiBjb3JyZWN0bHkg d2FzIG5ldmVyIHN0YXRlZC4KPj4KPj4gU28gdGhlIEtBU0FOIGNvbW1lbnQgaXMgbm90IHJlcXVp cmVkIGJ1dCBpIHRoaW5rIHdlIHN0aWxsIG5lZWQgdG8gc3RhdGUKPj4gd2h5IG1lbWNweSBpcyBy ZXF1aXJlZC4gRm9yIFBUUlJFTE9DIGFkanVzdG1lbnQsIGNvbW1lbnQgc2hvdWxkIHJlZmxlY3QK Pj4gdGhhdC4KPj4KPj4gSSdsbCB1cGRhdGUgdGhlIGNvbW1lbnQgYW5kIGNvbW1pdCBtZXNzYWdl IGFuZCBzZW5kIG91dCBhIG5ldyB2ZXJzaW9uLgo+IAo+IEV4cGxhbmF0aW9uIGJhc2VkIG9uIGtl cm5lbCB2NS4xMAo+IAo+IFRoZSBwcm9ibGVtIHdhcyBub3QgbGlua2VkIHRvIFBUUlJFTE9DLCB0 aGUgdCA9IFBUUlJFTE9DKHQpIGZvbGxvd2VkIGJ5IAo+ICp0ID0gKnMgd29ya3Mgd2VsbCBpbiB0 ZXJtIG9mIGFkcmVzc2luZywgcmVnYXJkbGVzcyBvZiB3aGV0aGVyIAo+IENPTkZJR19LQVNBTiBp cyBlbmFibGVkIG9yIG5vdC4KPiAKPiBUaGUgcHJvYmxlbSBpcyB0aGF0IHdpdGggKnQgPSAqcywg Z2NjIGVtaXRzIGEgY2FsbCB0byBtZW1jcHkoKS4gV2hlbiAKPiBDT05GSUdfS0FTQU4gaXMgZW5h YmxlZCwgbWVtY3B5KCkgaXMgaW5zdHJ1bWVudGVkLiBCdXQgd2UgZG9uJ3Qgd2FudCAKPiBjcHV0 YWJsZS5vIGluc3RydW1lbnRlZCBhcyB3ZSBoYXZlIEtBU0FOX1NBTklUSVpFX2NwdXRhYmxlLm8g Oj0gbiBpbiAKPiBNYWtlZmlsZS4KPiAKPiBJbiBhc20vc3RyaW5nLmggd2UgaGF2ZToKPiAKPiAj aWYgZGVmaW5lZChDT05GSUdfS0FTQU4pICYmICFkZWZpbmVkKF9fU0FOSVRJWkVfQUREUkVTU19f KQo+IC8qCj4gIMKgKiBGb3IgZmlsZXMgdGhhdCBhcmUgbm90IGluc3RydW1lbnRlZCAoZS5nLiBt bS9zbHViLmMpIHdlCj4gIMKgKiBzaG91bGQgdXNlIG5vdCBpbnN0cnVtZW50ZWQgdmVyc2lvbiBv ZiBtZW0qIGZ1bmN0aW9ucy4KPiAgwqAqLwo+ICNkZWZpbmUgbWVtY3B5KGRzdCwgc3JjLCBsZW4p IF9fbWVtY3B5KGRzdCwgc3JjLCBsZW4pCj4gI2RlZmluZSBtZW1tb3ZlKGRzdCwgc3JjLCBsZW4p IF9fbWVtbW92ZShkc3QsIHNyYywgbGVuKQo+ICNkZWZpbmUgbWVtc2V0KHMsIGMsIG4pIF9fbWVt c2V0KHMsIGMsIG4pCj4gCj4gQmVjYXVzZSBpbiBub24taW5zdHJ1bWVudGVkIGZpbGVzIGxpa2Ug Y3B1dGFibGUubyB3ZSB3YW50IG1lbWNweSgpIHRvIGJlIAo+IHJlcGxhY2VkIGF0IGJ1aWxkdGlt ZSBieSBfX21lbWNweSgpIHRvIHNraXAgS0FTQU4gaW5zdHJ1bWVudGF0aW9uLiBCdXQgCj4gdGhp cyBpcyByZXNvbHZlZCBieSBwcmUtcHJvY2Vzc2luZywgYW5kIHByZS1wcm9jZXNzb3IgZG9lc24n dCBrbm93IHRoYXQgCj4gdGhlIGNvbXBpbGVyIHdpbGwgZW1pdCBhIGNhbGwgdG8gbWVtY3B5KCku Cj4gCj4gQnkgcmVwbGFjaW5nICp0ID0gKnMgYnkgdGhlIG1lbWNweSgpLCB0aGUgcHJlLXByb2Nl c3NvciByZXBsYWNlcyAKPiBtZW1jcHkoKSBieSBfX21lbWNweSgpIHdoZW4gQ09ORklHX0tBU0FO IGlzIGVuYWJsZWQuCj4gCj4gU2VlIHRoZSBkaWZmZXJlbmNlOgo+IAo+IFRoaXMgaXMgdjUuMTAK PiAKPiAwMDAwMDAwMCA8c2V0X2N1cl9jcHVfc3BlYz46Cj4gIMKgwqAgMDrCoMKgwqAgOTQgMjEg ZmYgZTDCoMKgwqDCoCBzdHd1wqDCoMKgIHIxLC0zMihyMSkKPiAgwqDCoCA0OsKgwqDCoCA3YyA2 OSAxYiA3OMKgwqDCoMKgIG1ywqDCoMKgwqDCoCByOSxyMwo+ICDCoMKgIDg6wqDCoMKgIGJmIGMx IDAwIDE4wqDCoMKgwqAgc3Rtd8KgwqDCoCByMzAsMjQocjEpCj4gIMKgwqAgYzrCoMKgwqAgM2Yg ZTAgMDAgMDDCoMKgwqDCoCBsaXPCoMKgwqDCoCByMzEsMAo+ICDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgIGU6IFJfUFBDX0FERFIxNl9IQcKgwqDCoCAuZGF0YS4ucmVhZF9tb3N0bHkKPiAgwqAgMTA6 wqDCoMKgIDNiIGZmIDAwIDAwwqDCoMKgwqAgYWRkacKgwqDCoCByMzEscjMxLDAKPiAgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoCAxMjogUl9QUENfQUREUjE2X0xPwqDCoMKgIC5kYXRhLi5yZWFkX21v c3RseQo+ICDCoCAxNDrCoMKgwqAgN2MgMDggMDIgYTbCoMKgwqDCoCBtZmxywqDCoMKgIHIwCj4g IMKgIDE4OsKgwqDCoCA3ZCAzZSA0YiA3OMKgwqDCoMKgIG1ywqDCoMKgwqDCoCByMzAscjkKPiAg wqAgMWM6wqDCoMKgIDdmIGUzIGZiIDc4wqDCoMKgwqAgbXLCoMKgwqDCoMKgIHIzLHIzMQo+ICDC oCAyMDrCoMKgwqAgOTAgMDEgMDAgMjTCoMKgwqDCoCBzdHfCoMKgwqDCoCByMCwzNihyMSkKPiAg wqAgMjQ6wqDCoMKgIDQ4IDAwIDAwIDAxwqDCoMKgwqAgYmzCoMKgwqDCoMKgIDI0IDxzZXRfY3Vy X2NwdV9zcGVjKzB4MjQ+Cj4gIMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgMjQ6IFJfUFBDX1JFTDI0 wqDCoMKgIGFkZF9yZWxvY19vZmZzZXQKPiAgwqAgMjg6wqDCoMKgIDdmIGM0IGYzIDc4wqDCoMKg wqAgbXLCoMKgwqDCoMKgIHI0LHIzMAo+ICDCoCAyYzrCoMKgwqAgMzggYTAgMDAgNTjCoMKgwqDC oCBsacKgwqDCoMKgwqAgcjUsODgKPiAgwqAgMzA6wqDCoMKgIDQ4IDAwIDAwIDAxwqDCoMKgwqAg YmzCoMKgwqDCoMKgIDMwIDxzZXRfY3VyX2NwdV9zcGVjKzB4MzA+Cj4gIMKgwqDCoMKgwqDCoMKg wqDCoMKgwqAgMzA6IFJfUFBDX1JFTDI0wqDCoMKgIF9fbWVtY3B5Cj4gIMKgIDM0OsKgwqDCoCAz OCA3ZiAwMCA1OMKgwqDCoMKgIGFkZGnCoMKgwqAgcjMscjMxLDg4Cj4gIMKgIDM4OsKgwqDCoCA0 OCAwMCAwMCAwMcKgwqDCoMKgIGJswqDCoMKgwqDCoCAzOCA8c2V0X2N1cl9jcHVfc3BlYysweDM4 Pgo+ICDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIDM4OiBSX1BQQ19SRUwyNMKgwqDCoCBhZGRfcmVs b2Nfb2Zmc2V0Cj4gIMKgIDNjOsKgwqDCoCA5MyBlMyAwMCAwMMKgwqDCoMKgIHN0d8KgwqDCoMKg IHIzMSwwKHIzKQo+ICDCoCA0MDrCoMKgwqAgODAgMDEgMDAgMjTCoMKgwqDCoCBsd3rCoMKgwqDC oCByMCwzNihyMSkKPiAgwqAgNDQ6wqDCoMKgIDgzIGMxIDAwIDE4wqDCoMKgwqAgbHd6wqDCoMKg wqAgcjMwLDI0KHIxKQo+ICDCoCA0ODrCoMKgwqAgODMgZTEgMDAgMWPCoMKgwqDCoCBsd3rCoMKg wqDCoCByMzEsMjgocjEpCj4gIMKgIDRjOsKgwqDCoCA3YyAwOCAwMyBhNsKgwqDCoMKgIG10bHLC oMKgwqAgcjAKPiAgwqAgNTA6wqDCoMKgIDM4IDIxIDAwIDIwwqDCoMKgwqAgYWRkacKgwqDCoCBy MSxyMSwzMgo+ICDCoCA1NDrCoMKgwqAgNGUgODAgMDAgMjDCoMKgwqDCoCBibHIKPiAKPiBUaGlz IGlzIHY1LjEwIHdpdGggY29tbWl0IGFkY2Y1OTE4N2UyNzAgcmV2ZXJ0ZWQ6Cj4gCj4gMDAwMDAw MDAgPHNldF9jdXJfY3B1X3NwZWM+Ogo+ICDCoMKgIDA6wqDCoMKgIDk0IDIxIGZmIGUwwqDCoMKg wqAgc3R3dcKgwqDCoCByMSwtMzIocjEpCj4gIMKgwqAgNDrCoMKgwqAgN2MgNjkgMWIgNzjCoMKg wqDCoCBtcsKgwqDCoMKgwqAgcjkscjMKPiAgwqDCoCA4OsKgwqDCoCBiZiBjMSAwMCAxOMKgwqDC oMKgIHN0bXfCoMKgwqAgcjMwLDI0KHIxKQo+ICDCoMKgIGM6wqDCoMKgIDNmIGUwIDAwIDAwwqDC oMKgwqAgbGlzwqDCoMKgwqAgcjMxLDAKPiAgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCBlOiBSX1BQ Q19BRERSMTZfSEHCoMKgwqAgLmRhdGEuLnJlYWRfbW9zdGx5Cj4gIMKgIDEwOsKgwqDCoCAzYiBm ZiAwMCAwMMKgwqDCoMKgIGFkZGnCoMKgwqAgcjMxLHIzMSwwCj4gIMKgwqDCoMKgwqDCoMKgwqDC oMKgwqAgMTI6IFJfUFBDX0FERFIxNl9MT8KgwqDCoCAuZGF0YS4ucmVhZF9tb3N0bHkKPiAgwqAg MTQ6wqDCoMKgIDdjIDA4IDAyIGE2wqDCoMKgwqAgbWZscsKgwqDCoCByMAo+ICDCoCAxODrCoMKg wqAgN2QgM2UgNGIgNzjCoMKgwqDCoCBtcsKgwqDCoMKgwqAgcjMwLHI5Cj4gIMKgIDFjOsKgwqDC oCA3ZiBlMyBmYiA3OMKgwqDCoMKgIG1ywqDCoMKgwqDCoCByMyxyMzEKPiAgwqAgMjA6wqDCoMKg IDkwIDAxIDAwIDI0wqDCoMKgwqAgc3R3wqDCoMKgwqAgcjAsMzYocjEpCj4gIMKgIDI0OsKgwqDC oCA0OCAwMCAwMCAwMcKgwqDCoMKgIGJswqDCoMKgwqDCoCAyNCA8c2V0X2N1cl9jcHVfc3BlYysw eDI0Pgo+ICDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIDI0OiBSX1BQQ19SRUwyNMKgwqDCoCBhZGRf cmVsb2Nfb2Zmc2V0Cj4gIMKgIDI4OsKgwqDCoCA3ZiBjNCBmMyA3OMKgwqDCoMKgIG1ywqDCoMKg wqDCoCByNCxyMzAKPiAgwqAgMmM6wqDCoMKgIDM4IGEwIDAwIDU4wqDCoMKgwqAgbGnCoMKgwqDC oMKgIHI1LDg4Cj4gIMKgIDMwOsKgwqDCoCA0OCAwMCAwMCAwMcKgwqDCoMKgIGJswqDCoMKgwqDC oCAzMCA8c2V0X2N1cl9jcHVfc3BlYysweDMwPgo+ICDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIDMw OiBSX1BQQ19SRUwyNMKgwqDCoCBtZW1jcHkKPiAgwqAgMzQ6wqDCoMKgIDM4IDdmIDAwIDU4wqDC oMKgwqAgYWRkacKgwqDCoCByMyxyMzEsODgKPiAgwqAgMzg6wqDCoMKgIDQ4IDAwIDAwIDAxwqDC oMKgwqAgYmzCoMKgwqDCoMKgIDM4IDxzZXRfY3VyX2NwdV9zcGVjKzB4Mzg+Cj4gIMKgwqDCoMKg wqDCoMKgwqDCoMKgwqAgMzg6IFJfUFBDX1JFTDI0wqDCoMKgIGFkZF9yZWxvY19vZmZzZXQKPiAg wqAgM2M6wqDCoMKgIDkzIGUzIDAwIDAwwqDCoMKgwqAgc3R3wqDCoMKgwqAgcjMxLDAocjMpCj4g IMKgIDQwOsKgwqDCoCA4MCAwMSAwMCAyNMKgwqDCoMKgIGx3esKgwqDCoMKgIHIwLDM2KHIxKQo+ ICDCoCA0NDrCoMKgwqAgODMgYzEgMDAgMTjCoMKgwqDCoCBsd3rCoMKgwqDCoCByMzAsMjQocjEp Cj4gIMKgIDQ4OsKgwqDCoCA4MyBlMSAwMCAxY8KgwqDCoMKgIGx3esKgwqDCoMKgIHIzMSwyOChy MSkKPiAgwqAgNGM6wqDCoMKgIDdjIDA4IDAzIGE2wqDCoMKgwqAgbXRscsKgwqDCoCByMAo+ICDC oCA1MDrCoMKgwqAgMzggMjEgMDAgMjDCoMKgwqDCoCBhZGRpwqDCoMKgIHIxLHIxLDMyCj4gIMKg IDU0OsKgwqDCoCA0ZSA4MCAwMCAyMMKgwqDCoMKgIGJscgo+IAo+IFNvIG15IHF1ZXN0aW9uIGlz ID8gRG8gd2Ugc3RpbGwgaGF2ZSB0aGlzIGlzc3VlIG5vd2FkYXlzID8KCkkgbm93IGRpZCB0aGUg c2FtZSB0ZXN0IHdpdGggdjcuMiB3aXRob3V0IGFuZCB3aXRoIGFkY2Y1OTE4N2UyNzAgCnJldmVy dGVkLiBJIGJvdGggY2FzZXMgSSBnZXQgbWVtY3B5KCkuCgpDaHJpc3RvcGhlCgpfX19fX19fX19f X19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fXwpsaW51eC1yaXNjdiBtYWlsaW5n IGxpc3QKbGludXgtcmlzY3ZAbGlzdHMuaW5mcmFkZWFkLm9yZwpodHRwOi8vbGlzdHMuaW5mcmFk ZWFkLm9yZy9tYWlsbWFuL2xpc3RpbmZvL2xpbnV4LXJpc2N2Cg==