From mboxrd@z Thu Jan 1 00:00:00 1970 From: Chao Du Date: Fri, 1 Mar 2024 15:27:18 +0800 (GMT+08:00) Subject: [PATCH v2 1/3] RISC-V: KVM: Implement kvm_arch_vcpu_ioctl_set_guest_debug() In-Reply-To: References: <20240301013545.10403-1-duchao@eswincomputing.com> <20240301013545.10403-2-duchao@eswincomputing.com> <1f31ec16.1447.18df8b97f73.Coremail.duchao@eswincomputing.com> Message-ID: <698f58e.1490.18df8e9084f.Coremail.duchao@eswincomputing.com> List-Id: To: kvm-riscv@lists.infradead.org MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit On 2024-03-01 15:29, Anup Patel wrote: > > On Fri, Mar 1, 2024 at 12:05?PM Chao Du wrote: > > > > On 2024-03-01 13:00, Anup Patel wrote: > > > > > > On Fri, Mar 1, 2024 at 7:08?AM Chao Du wrote: > > > > > > > > kvm_vm_ioctl_check_extension(): Return 1 if KVM_CAP_SET_GUEST_DEBUG is > > > > been checked. > > > > > > > > kvm_arch_vcpu_ioctl_set_guest_debug(): Update the guest_debug flags > > > > from userspace accordingly. Route the breakpoint exceptions to HS mode > > > > if the VCPU is being debugged by userspace, by clearing the > > > > corresponding bit in hedeleg. Write the actual CSR in > > > > kvm_arch_vcpu_load(). > > > > > > > > Signed-off-by: Chao Du > > > > --- > > > > arch/riscv/include/asm/kvm_host.h | 17 +++++++++++++++++ > > > > arch/riscv/include/uapi/asm/kvm.h | 1 + > > > > arch/riscv/kvm/main.c | 18 ++---------------- > > > > arch/riscv/kvm/vcpu.c | 15 +++++++++++++-- > > > > arch/riscv/kvm/vm.c | 1 + > > > > 5 files changed, 34 insertions(+), 18 deletions(-) > > > > > > > > diff --git a/arch/riscv/include/asm/kvm_host.h b/arch/riscv/include/asm/kvm_host.h > > > > index 484d04a92fa6..9ee3f03ba5d1 100644 > > > > --- a/arch/riscv/include/asm/kvm_host.h > > > > +++ b/arch/riscv/include/asm/kvm_host.h > > > > @@ -43,6 +43,22 @@ > > > > KVM_ARCH_REQ_FLAGS(5, KVM_REQUEST_WAIT | KVM_REQUEST_NO_WAKEUP) > > > > #define KVM_REQ_STEAL_UPDATE KVM_ARCH_REQ(6) > > > > > > > > +#define KVM_HEDELEG_DEFAULT ((_AC(1, UL) << EXC_INST_MISALIGNED) | \ > > > > + (_AC(1, UL) << EXC_BREAKPOINT) | \ > > > > + (_AC(1, UL) << EXC_SYSCALL) | \ > > > > + (_AC(1, UL) << EXC_INST_PAGE_FAULT) | \ > > > > + (_AC(1, UL) << EXC_LOAD_PAGE_FAULT) | \ > > > > + (_AC(1, UL) << EXC_STORE_PAGE_FAULT)) > > > > > > Use BIT(xyz) here. For example: BIT(EXC_INST_MISALIGNED) > > > > Thanks, I will use BIT() instead in next revision. > > > > > > > > > > Also, BIT(EXC_BREAKPOINT) should not be part of KVM_HEDELEG_DEFAULT. > > > > I think the bit EXC_BREAKPOINT should be set by default, like what you > > already did in kvm_arch_hardware_enable(). Then the VS could get the ebreak > > and handle it accordingly. > > > > If the guest_debug is enabled, ebreak instructions are inserted by the > > userspace(QEMU). So KVM should 'intercept' the ebreak and exit to QEMU. > > Bit EXC_BREAKPOINT should be cleared in this case. > > If EXC_BREAKPOINT is delegated by default then it is not consistent with > vcpu->guest_debug which is not enabled by default. To enable the guest_debug corresponding to NOT delegate the EXC_BREAKPOINT. They are somehow 'opposite'. This 'kvm_guest_debug' feature is different from "debug in the guest". The later requires the delegation of EXC_BREAKPOINT. The former does not. > > > > > > > > > > +#define KVM_HEDELEG_GUEST_DEBUG ((_AC(1, UL) << EXC_INST_MISALIGNED) | \ > > > > + (_AC(1, UL) << EXC_SYSCALL) | \ > > > > + (_AC(1, UL) << EXC_INST_PAGE_FAULT) | \ > > > > + (_AC(1, UL) << EXC_LOAD_PAGE_FAULT) | \ > > > > + (_AC(1, UL) << EXC_STORE_PAGE_FAULT)) > > > > > > No need for KVM_HEDELEG_GUEST_DEBUG, see below. > > > > > > > + > > > > +#define KVM_HIDELEG_DEFAULT ((_AC(1, UL) << IRQ_VS_SOFT) | \ > > > > + (_AC(1, UL) << IRQ_VS_TIMER) | \ > > > > + (_AC(1, UL) << IRQ_VS_EXT)) > > > > + > > > > > > Same as above, use BIT(xyz) here. > > > > > > > enum kvm_riscv_hfence_type { > > > > KVM_RISCV_HFENCE_UNKNOWN = 0, > > > > KVM_RISCV_HFENCE_GVMA_VMID_GPA, > > > > @@ -169,6 +185,7 @@ struct kvm_vcpu_csr { > > > > struct kvm_vcpu_config { > > > > u64 henvcfg; > > > > u64 hstateen0; > > > > + unsigned long hedeleg; > > > > }; > > > > > > > > struct kvm_vcpu_smstateen_csr { > > > > diff --git a/arch/riscv/include/uapi/asm/kvm.h b/arch/riscv/include/uapi/asm/kvm.h > > > > index 7499e88a947c..39f4f4b9dede 100644 > > > > --- a/arch/riscv/include/uapi/asm/kvm.h > > > > +++ b/arch/riscv/include/uapi/asm/kvm.h > > > > @@ -17,6 +17,7 @@ > > > > > > > > #define __KVM_HAVE_IRQ_LINE > > > > #define __KVM_HAVE_READONLY_MEM > > > > +#define __KVM_HAVE_GUEST_DEBUG > > > > > > > > #define KVM_COALESCED_MMIO_PAGE_OFFSET 1 > > > > > > > > diff --git a/arch/riscv/kvm/main.c b/arch/riscv/kvm/main.c > > > > index 225a435d9c9a..bab2ec34cd87 100644 > > > > --- a/arch/riscv/kvm/main.c > > > > +++ b/arch/riscv/kvm/main.c > > > > @@ -22,22 +22,8 @@ long kvm_arch_dev_ioctl(struct file *filp, > > > > > > > > int kvm_arch_hardware_enable(void) > > > > { > > > > - unsigned long hideleg, hedeleg; > > > > - > > > > - hedeleg = 0; > > > > - hedeleg |= (1UL << EXC_INST_MISALIGNED); > > > > - hedeleg |= (1UL << EXC_BREAKPOINT); > > > > - hedeleg |= (1UL << EXC_SYSCALL); > > > > - hedeleg |= (1UL << EXC_INST_PAGE_FAULT); > > > > - hedeleg |= (1UL << EXC_LOAD_PAGE_FAULT); > > > > - hedeleg |= (1UL << EXC_STORE_PAGE_FAULT); > > > > - csr_write(CSR_HEDELEG, hedeleg); > > > > - > > > > - hideleg = 0; > > > > - hideleg |= (1UL << IRQ_VS_SOFT); > > > > - hideleg |= (1UL << IRQ_VS_TIMER); > > > > - hideleg |= (1UL << IRQ_VS_EXT); > > > > - csr_write(CSR_HIDELEG, hideleg); > > > > + csr_write(CSR_HEDELEG, KVM_HEDELEG_DEFAULT); > > > > + csr_write(CSR_HIDELEG, KVM_HIDELEG_DEFAULT); > > > > > > > > /* VS should access only the time counter directly. Everything else should trap */ > > > > csr_write(CSR_HCOUNTEREN, 0x02); > > > > diff --git a/arch/riscv/kvm/vcpu.c b/arch/riscv/kvm/vcpu.c > > > > index b5ca9f2e98ac..242076c2227f 100644 > > > > --- a/arch/riscv/kvm/vcpu.c > > > > +++ b/arch/riscv/kvm/vcpu.c > > > > @@ -475,8 +475,15 @@ int kvm_arch_vcpu_ioctl_set_mpstate(struct kvm_vcpu *vcpu, > > > > int kvm_arch_vcpu_ioctl_set_guest_debug(struct kvm_vcpu *vcpu, > > > > struct kvm_guest_debug *dbg) > > > > { > > > > - /* TODO; To be implemented later. */ > > > > - return -EINVAL; > > > > > > if (vcpu->arch.ran_atleast_once) > > > return -EBUSY; > > > > If we enabled the guest_debug in QEMU side, then the KVM_SET_GUEST_DEBUG ioctl > > will come before the first KVM_RUN. This will always cause an ERROR. > > The check ensures that KVM user space can only enable/disable > guest debug before the VCPU is run. I don't see why this would > fail for QEMU. In the current implementation of GDB and QEMU, the userspace will enable/disable guest_debug frequently during the debugging (almost every step). The sequence should like: KVM_SET_GUEST_DEBUG enable KVM_RUN KVM_SET_GUEST_DEBUG disable KVM_SET_GUEST_DEBUG enable KVM_RUN KVM_SET_GUEST_DEBUG disable KVM_SET_GUEST_DEBUG enable KVM_RUN KVM_SET_GUEST_DEBUG disable ... > > > > > > > > > > > > > + if (dbg->control & KVM_GUESTDBG_ENABLE) { > > > > + vcpu->guest_debug = dbg->control; > > > > + vcpu->arch.cfg.hedeleg = KVM_HEDELEG_GUEST_DEBUG; > > > > + } else { > > > > + vcpu->guest_debug = 0; > > > > + vcpu->arch.cfg.hedeleg = KVM_HEDELEG_DEFAULT; > > > > + } > > > > > > Don't update vcpu->arch.cfg.hedeleg here since it should be only done > > > in kvm_riscv_vcpu_setup_config(). > > > > > > > + > > > > + return 0; > > > > } > > > > > > > > static void kvm_riscv_vcpu_setup_config(struct kvm_vcpu *vcpu) > > > > @@ -505,6 +512,9 @@ static void kvm_riscv_vcpu_setup_config(struct kvm_vcpu *vcpu) > > > > if (riscv_isa_extension_available(isa, SMSTATEEN)) > > > > cfg->hstateen0 |= SMSTATEEN0_SSTATEEN0; > > > > } > > > > + > > > > + if (!vcpu->guest_debug) > > > > + cfg->hedeleg = KVM_HEDELEG_DEFAULT; > > > > > > This should be: > > > > > > cfg->hedeleg = KVM_HEDELEG_DEFAULT; > > > if (vcpu->guest_debug) > > > cfg->hedeleg |= BIT(EXC_BREAKPOINT); > > > > Like above, here the logic should be: > > > > cfg->hedeleg = KVM_HEDELEG_DEFAULT; // with BIT(EXC_BREAKPOINT) > > if (vcpu->guest_debug) > > cfg->hedeleg &= ~BIT(EXC_BREAKPOINT); > > > > Another approach is: > > initialize the cfg->hedeleg as KVM_HEDELEG_DEFAULT during kvm_arch_vcpu_create(). > > Besides that, only update the cfg->hedeleg in kvm_arch_vcpu_ioctl_set_guest_debug(). > > I disagree. We should handle hedeleg just like we handle henvcfg. OK, let's only update the cfg->hedeleg in kvm_riscv_vcpu_setup_config(). > > > > > > > > > > } > > > > > > > > void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu) > > > > @@ -519,6 +529,7 @@ void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu) > > > > csr_write(CSR_VSEPC, csr->vsepc); > > > > csr_write(CSR_VSCAUSE, csr->vscause); > > > > csr_write(CSR_VSTVAL, csr->vstval); > > > > + csr_write(CSR_HEDELEG, cfg->hedeleg); > > > > csr_write(CSR_HVIP, csr->hvip); > > > > csr_write(CSR_VSATP, csr->vsatp); > > > > csr_write(CSR_HENVCFG, cfg->henvcfg); > > > > diff --git a/arch/riscv/kvm/vm.c b/arch/riscv/kvm/vm.c > > > > index ce58bc48e5b8..7396b8654f45 100644 > > > > --- a/arch/riscv/kvm/vm.c > > > > +++ b/arch/riscv/kvm/vm.c > > > > @@ -186,6 +186,7 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext) > > > > case KVM_CAP_READONLY_MEM: > > > > case KVM_CAP_MP_STATE: > > > > case KVM_CAP_IMMEDIATE_EXIT: > > > > + case KVM_CAP_SET_GUEST_DEBUG: > > > > r = 1; > > > > break; > > > > case KVM_CAP_NR_VCPUS: > > > > -- > > > > 2.17.1 > > > > > > > > > > Regards, > > > Anup > > > > Thanks, > > Chao > > Regards, > Anup Thanks, Chao From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from zg8tndyumtaxlji0oc4xnzya.icoremail.net (zg8tndyumtaxlji0oc4xnzya.icoremail.net [46.101.248.176]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 4520969317 for ; Fri, 1 Mar 2024 07:28:10 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=46.101.248.176 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1709278096; cv=none; b=bmSnL9ErRzhWjgzz86i6S0qoDNXbpYT+6rXfz+rHFg7sQ51wz7Yej2qT8flMQAcFMomTLXjDSRLylEZC6c6pXhMn1WdoLARCdk/PiVvWipMDduR7qCA9Q9i3axx7MB+mgOnGw4RJVWwJc7CeM0GmlmtkRy0K3HDkDs749JNFaHE= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1709278096; c=relaxed/simple; bh=vkniOUjShb6Jj6qEfCSLAz0baXcoMyGlCj1WgESN0Is=; h=Date:From:To:Cc:Subject:In-Reply-To:References:Content-Type: MIME-Version:Message-ID; b=i4aSU5QMJDNNh7Sw6Xjy57ChfpVFG2K9FgfnLkQOr/YGBCXJkuPYYawAKyv/2QPbbeQ3iKro/rwz7Rv8YfgDO0g0if1Mn/iFkWbQDdQAsTJBSS9GS06XdejLc/6ruBfMM0vGd6Dw34h294hO1H2dJvbrA6qnbMQ+BXrlPdzaBJE= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=eswincomputing.com; spf=pass smtp.mailfrom=eswincomputing.com; arc=none smtp.client-ip=46.101.248.176 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=eswincomputing.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=eswincomputing.com Received: from duchao$eswincomputing.com ( [10.64.113.11] ) by ajax-webmail-app2 (Coremail) ; Fri, 1 Mar 2024 15:27:18 +0800 (GMT+08:00) Date: Fri, 1 Mar 2024 15:27:18 +0800 (GMT+08:00) X-CM-HeaderCharset: UTF-8 From: "Chao Du" To: "Anup Patel" Cc: kvm@vger.kernel.org, kvm-riscv@lists.infradead.org, atishp@atishpatra.org, pbonzini@redhat.com, shuah@kernel.org, dbarboza@ventanamicro.com, paul.walmsley@sifive.com, palmer@dabbelt.com, aou@eecs.berkeley.edu, duchao713@qq.com Subject: Re: [PATCH v2 1/3] RISC-V: KVM: Implement kvm_arch_vcpu_ioctl_set_guest_debug() X-Priority: 3 X-Mailer: Coremail Webmail Server Version XT6.0.3 build 20220420(169d3f8c) Copyright (c) 2002-2024 www.mailtech.cn mispb-72143050-eaf5-4703-89e0-86624513b4ce-eswincomputing.com In-Reply-To: References: <20240301013545.10403-1-duchao@eswincomputing.com> <20240301013545.10403-2-duchao@eswincomputing.com> <1f31ec16.1447.18df8b97f73.Coremail.duchao@eswincomputing.com> Content-Transfer-Encoding: base64 Content-Type: text/plain; charset=UTF-8 Precedence: bulk X-Mailing-List: kvm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-ID: <698f58e.1490.18df8e9084f.Coremail.duchao@eswincomputing.com> X-Coremail-Locale: en_US X-CM-TRANSID:TQJkCgDHVdRWg+FlvjAdAA--.10071W X-CM-SenderInfo: xgxfxt3r6h245lqf0zpsxwx03jof0z/1tbiAgEDDGXgo9IgTQABsU X-Coremail-Antispam: 1Ur529EdanIXcx71UUUUU7IcSsGvfJ3iIAIbVAYjsxI4VW3Jw CS07vEb4IE77IF4wCS07vE1I0E4x80FVAKz4kxMIAIbVAFxVCaYxvI4VCIwcAKzIAtYxBI daVFxhVjvjDU= T24gMjAyNC0wMy0wMSAxNToyOSwgQW51cCBQYXRlbCA8YW51cEBicmFpbmZhdWx0Lm9yZz4gd3Jv dGU6Cj4gCj4gT24gRnJpLCBNYXIgMSwgMjAyNCBhdCAxMjowNeKAr1BNIENoYW8gRHUgPGR1Y2hh b0Blc3dpbmNvbXB1dGluZy5jb20+IHdyb3RlOgo+ID4KPiA+IE9uIDIwMjQtMDMtMDEgMTM6MDAs IEFudXAgUGF0ZWwgPGFudXBAYnJhaW5mYXVsdC5vcmc+IHdyb3RlOgo+ID4gPgo+ID4gPiBPbiBG cmksIE1hciAxLCAyMDI0IGF0IDc6MDjigK9BTSBDaGFvIER1IDxkdWNoYW9AZXN3aW5jb21wdXRp bmcuY29tPiB3cm90ZToKPiA+ID4gPgo+ID4gPiA+IGt2bV92bV9pb2N0bF9jaGVja19leHRlbnNp b24oKTogUmV0dXJuIDEgaWYgS1ZNX0NBUF9TRVRfR1VFU1RfREVCVUcgaXMKPiA+ID4gPiBiZWVu IGNoZWNrZWQuCj4gPiA+ID4KPiA+ID4gPiBrdm1fYXJjaF92Y3B1X2lvY3RsX3NldF9ndWVzdF9k ZWJ1ZygpOiBVcGRhdGUgdGhlIGd1ZXN0X2RlYnVnIGZsYWdzCj4gPiA+ID4gZnJvbSB1c2Vyc3Bh Y2UgYWNjb3JkaW5nbHkuIFJvdXRlIHRoZSBicmVha3BvaW50IGV4Y2VwdGlvbnMgdG8gSFMgbW9k ZQo+ID4gPiA+IGlmIHRoZSBWQ1BVIGlzIGJlaW5nIGRlYnVnZ2VkIGJ5IHVzZXJzcGFjZSwgYnkg Y2xlYXJpbmcgdGhlCj4gPiA+ID4gY29ycmVzcG9uZGluZyBiaXQgaW4gaGVkZWxlZy4gV3JpdGUg dGhlIGFjdHVhbCBDU1IgaW4KPiA+ID4gPiBrdm1fYXJjaF92Y3B1X2xvYWQoKS4KPiA+ID4gPgo+ ID4gPiA+IFNpZ25lZC1vZmYtYnk6IENoYW8gRHUgPGR1Y2hhb0Blc3dpbmNvbXB1dGluZy5jb20+ Cj4gPiA+ID4gLS0tCj4gPiA+ID4gIGFyY2gvcmlzY3YvaW5jbHVkZS9hc20va3ZtX2hvc3QuaCB8 IDE3ICsrKysrKysrKysrKysrKysrCj4gPiA+ID4gIGFyY2gvcmlzY3YvaW5jbHVkZS91YXBpL2Fz bS9rdm0uaCB8ICAxICsKPiA+ID4gPiAgYXJjaC9yaXNjdi9rdm0vbWFpbi5jICAgICAgICAgICAg IHwgMTggKystLS0tLS0tLS0tLS0tLS0tCj4gPiA+ID4gIGFyY2gvcmlzY3Yva3ZtL3ZjcHUuYyAg ICAgICAgICAgICB8IDE1ICsrKysrKysrKysrKystLQo+ID4gPiA+ICBhcmNoL3Jpc2N2L2t2bS92 bS5jICAgICAgICAgICAgICAgfCAgMSArCj4gPiA+ID4gIDUgZmlsZXMgY2hhbmdlZCwgMzQgaW5z ZXJ0aW9ucygrKSwgMTggZGVsZXRpb25zKC0pCj4gPiA+ID4KPiA+ID4gPiBkaWZmIC0tZ2l0IGEv YXJjaC9yaXNjdi9pbmNsdWRlL2FzbS9rdm1faG9zdC5oIGIvYXJjaC9yaXNjdi9pbmNsdWRlL2Fz bS9rdm1faG9zdC5oCj4gPiA+ID4gaW5kZXggNDg0ZDA0YTkyZmE2Li45ZWUzZjAzYmE1ZDEgMTAw NjQ0Cj4gPiA+ID4gLS0tIGEvYXJjaC9yaXNjdi9pbmNsdWRlL2FzbS9rdm1faG9zdC5oCj4gPiA+ ID4gKysrIGIvYXJjaC9yaXNjdi9pbmNsdWRlL2FzbS9rdm1faG9zdC5oCj4gPiA+ID4gQEAgLTQz LDYgKzQzLDIyIEBACj4gPiA+ID4gICAgICAgICBLVk1fQVJDSF9SRVFfRkxBR1MoNSwgS1ZNX1JF UVVFU1RfV0FJVCB8IEtWTV9SRVFVRVNUX05PX1dBS0VVUCkKPiA+ID4gPiAgI2RlZmluZSBLVk1f UkVRX1NURUFMX1VQREFURSAgICAgICAgICAgS1ZNX0FSQ0hfUkVRKDYpCj4gPiA+ID4KPiA+ID4g PiArI2RlZmluZSBLVk1fSEVERUxFR19ERUZBVUxUICAgICAgICAgICAgKChfQUMoMSwgVUwpIDw8 IEVYQ19JTlNUX01JU0FMSUdORUQpIHwgXAo+ID4gPiA+ICsgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgKF9BQygxLCBVTCkgPDwgRVhDX0JSRUFLUE9JTlQpIHwgXAo+ID4g PiA+ICsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKF9BQygxLCBVTCkg PDwgRVhDX1NZU0NBTEwpIHwgXAo+ID4gPiA+ICsgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgKF9BQygxLCBVTCkgPDwgRVhDX0lOU1RfUEFHRV9GQVVMVCkgfCBcCj4gPiA+ ID4gKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoX0FDKDEsIFVMKSA8 PCBFWENfTE9BRF9QQUdFX0ZBVUxUKSB8IFwKPiA+ID4gPiArICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgIChfQUMoMSwgVUwpIDw8IEVYQ19TVE9SRV9QQUdFX0ZBVUxUKSkK PiA+ID4KPiA+ID4gVXNlIEJJVCh4eXopIGhlcmUuIEZvciBleGFtcGxlOiBCSVQoRVhDX0lOU1Rf TUlTQUxJR05FRCkKPiA+Cj4gPiBUaGFua3MsIEkgd2lsbCB1c2UgQklUKCkgaW5zdGVhZCBpbiBu ZXh0IHJldmlzaW9uLgo+ID4KPiA+ID4KPiA+Cj4gPiA+IEFsc28sIEJJVChFWENfQlJFQUtQT0lO VCkgc2hvdWxkIG5vdCBiZSBwYXJ0IG9mIEtWTV9IRURFTEVHX0RFRkFVTFQuCj4gPgo+ID4gSSB0 aGluayB0aGUgYml0IEVYQ19CUkVBS1BPSU5UIHNob3VsZCBiZSBzZXQgYnkgZGVmYXVsdCwgbGlr ZSB3aGF0IHlvdQo+ID4gYWxyZWFkeSBkaWQgaW4ga3ZtX2FyY2hfaGFyZHdhcmVfZW5hYmxlKCku IFRoZW4gdGhlIFZTIGNvdWxkIGdldCB0aGUgZWJyZWFrCj4gPiBhbmQgaGFuZGxlIGl0IGFjY29y ZGluZ2x5Lgo+ID4KPiA+IElmIHRoZSBndWVzdF9kZWJ1ZyBpcyBlbmFibGVkLCBlYnJlYWsgaW5z dHJ1Y3Rpb25zIGFyZSBpbnNlcnRlZCBieSB0aGUKPiA+IHVzZXJzcGFjZShRRU1VKS4gU28gS1ZN IHNob3VsZCAnaW50ZXJjZXB0JyB0aGUgZWJyZWFrIGFuZCBleGl0IHRvIFFFTVUuCj4gPiBCaXQg RVhDX0JSRUFLUE9JTlQgc2hvdWxkIGJlIGNsZWFyZWQgaW4gdGhpcyBjYXNlLgo+IAo+IElmIEVY Q19CUkVBS1BPSU5UIGlzIGRlbGVnYXRlZCBieSBkZWZhdWx0IHRoZW4gaXQgaXMgbm90IGNvbnNp c3RlbnQgd2l0aAo+IHZjcHUtPmd1ZXN0X2RlYnVnIHdoaWNoIGlzIG5vdCBlbmFibGVkIGJ5IGRl ZmF1bHQuCgpUbyBlbmFibGUgdGhlIGd1ZXN0X2RlYnVnIGNvcnJlc3BvbmRpbmcgdG8gTk9UIGRl bGVnYXRlIHRoZSBFWENfQlJFQUtQT0lOVC4KVGhleSBhcmUgc29tZWhvdyAnb3Bwb3NpdGUnLgoK VGhpcyAna3ZtX2d1ZXN0X2RlYnVnJyBmZWF0dXJlIGlzIGRpZmZlcmVudCBmcm9tICJkZWJ1ZyBp biB0aGUgZ3Vlc3QiLgpUaGUgbGF0ZXIgcmVxdWlyZXMgdGhlIGRlbGVnYXRpb24gb2YgRVhDX0JS RUFLUE9JTlQuClRoZSBmb3JtZXIgZG9lcyBub3QuCgo+IAo+ID4KPiA+ID4KPiA+ID4gPiArI2Rl ZmluZSBLVk1fSEVERUxFR19HVUVTVF9ERUJVRyAgICAgICAgICAgICAgICAoKF9BQygxLCBVTCkg PDwgRVhDX0lOU1RfTUlTQUxJR05FRCkgfCBcCj4gPiA+ID4gKyAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAoX0FDKDEsIFVMKSA8PCBFWENfU1lTQ0FMTCkgfCBcCj4gPiA+ ID4gKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoX0FDKDEsIFVMKSA8 PCBFWENfSU5TVF9QQUdFX0ZBVUxUKSB8IFwKPiA+ID4gPiArICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgIChfQUMoMSwgVUwpIDw8IEVYQ19MT0FEX1BBR0VfRkFVTFQpIHwg XAo+ID4gPiA+ICsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKF9BQygx LCBVTCkgPDwgRVhDX1NUT1JFX1BBR0VfRkFVTFQpKQo+ID4gPgo+ID4gPiBObyBuZWVkIGZvciBL Vk1fSEVERUxFR19HVUVTVF9ERUJVRywgc2VlIGJlbG93Lgo+ID4gPgo+ID4gPiA+ICsKPiA+ID4g PiArI2RlZmluZSBLVk1fSElERUxFR19ERUZBVUxUICAgICAgICAgICAgKChfQUMoMSwgVUwpIDw8 IElSUV9WU19TT0ZUKSB8IFwKPiA+ID4gPiArICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgIChfQUMoMSwgVUwpIDw8IElSUV9WU19USU1FUikgfCBcCj4gPiA+ID4gKyAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoX0FDKDEsIFVMKSA8PCBJUlFfVlNf RVhUKSkKPiA+ID4gPiArCj4gPiA+Cj4gPiA+IFNhbWUgYXMgYWJvdmUsIHVzZSBCSVQoeHl6KSBo ZXJlLgo+ID4gPgo+ID4gPiA+ICBlbnVtIGt2bV9yaXNjdl9oZmVuY2VfdHlwZSB7Cj4gPiA+ID4g ICAgICAgICBLVk1fUklTQ1ZfSEZFTkNFX1VOS05PV04gPSAwLAo+ID4gPiA+ICAgICAgICAgS1ZN X1JJU0NWX0hGRU5DRV9HVk1BX1ZNSURfR1BBLAo+ID4gPiA+IEBAIC0xNjksNiArMTg1LDcgQEAg c3RydWN0IGt2bV92Y3B1X2NzciB7Cj4gPiA+ID4gIHN0cnVjdCBrdm1fdmNwdV9jb25maWcgewo+ ID4gPiA+ICAgICAgICAgdTY0IGhlbnZjZmc7Cj4gPiA+ID4gICAgICAgICB1NjQgaHN0YXRlZW4w Owo+ID4gPiA+ICsgICAgICAgdW5zaWduZWQgbG9uZyBoZWRlbGVnOwo+ID4gPiA+ICB9Owo+ID4g PiA+Cj4gPiA+ID4gIHN0cnVjdCBrdm1fdmNwdV9zbXN0YXRlZW5fY3NyIHsKPiA+ID4gPiBkaWZm IC0tZ2l0IGEvYXJjaC9yaXNjdi9pbmNsdWRlL3VhcGkvYXNtL2t2bS5oIGIvYXJjaC9yaXNjdi9p bmNsdWRlL3VhcGkvYXNtL2t2bS5oCj4gPiA+ID4gaW5kZXggNzQ5OWU4OGE5NDdjLi4zOWY0ZjRi OWRlZGUgMTAwNjQ0Cj4gPiA+ID4gLS0tIGEvYXJjaC9yaXNjdi9pbmNsdWRlL3VhcGkvYXNtL2t2 bS5oCj4gPiA+ID4gKysrIGIvYXJjaC9yaXNjdi9pbmNsdWRlL3VhcGkvYXNtL2t2bS5oCj4gPiA+ ID4gQEAgLTE3LDYgKzE3LDcgQEAKPiA+ID4gPgo+ID4gPiA+ICAjZGVmaW5lIF9fS1ZNX0hBVkVf SVJRX0xJTkUKPiA+ID4gPiAgI2RlZmluZSBfX0tWTV9IQVZFX1JFQURPTkxZX01FTQo+ID4gPiA+ ICsjZGVmaW5lIF9fS1ZNX0hBVkVfR1VFU1RfREVCVUcKPiA+ID4gPgo+ID4gPiA+ICAjZGVmaW5l IEtWTV9DT0FMRVNDRURfTU1JT19QQUdFX09GRlNFVCAxCj4gPiA+ID4KPiA+ID4gPiBkaWZmIC0t Z2l0IGEvYXJjaC9yaXNjdi9rdm0vbWFpbi5jIGIvYXJjaC9yaXNjdi9rdm0vbWFpbi5jCj4gPiA+ ID4gaW5kZXggMjI1YTQzNWQ5YzlhLi5iYWIyZWMzNGNkODcgMTAwNjQ0Cj4gPiA+ID4gLS0tIGEv YXJjaC9yaXNjdi9rdm0vbWFpbi5jCj4gPiA+ID4gKysrIGIvYXJjaC9yaXNjdi9rdm0vbWFpbi5j Cj4gPiA+ID4gQEAgLTIyLDIyICsyMiw4IEBAIGxvbmcga3ZtX2FyY2hfZGV2X2lvY3RsKHN0cnVj dCBmaWxlICpmaWxwLAo+ID4gPiA+Cj4gPiA+ID4gIGludCBrdm1fYXJjaF9oYXJkd2FyZV9lbmFi bGUodm9pZCkKPiA+ID4gPiAgewo+ID4gPiA+IC0gICAgICAgdW5zaWduZWQgbG9uZyBoaWRlbGVn LCBoZWRlbGVnOwo+ID4gPiA+IC0KPiA+ID4gPiAtICAgICAgIGhlZGVsZWcgPSAwOwo+ID4gPiA+ IC0gICAgICAgaGVkZWxlZyB8PSAoMVVMIDw8IEVYQ19JTlNUX01JU0FMSUdORUQpOwo+ID4gPiA+ IC0gICAgICAgaGVkZWxlZyB8PSAoMVVMIDw8IEVYQ19CUkVBS1BPSU5UKTsKPiA+ID4gPiAtICAg ICAgIGhlZGVsZWcgfD0gKDFVTCA8PCBFWENfU1lTQ0FMTCk7Cj4gPiA+ID4gLSAgICAgICBoZWRl bGVnIHw9ICgxVUwgPDwgRVhDX0lOU1RfUEFHRV9GQVVMVCk7Cj4gPiA+ID4gLSAgICAgICBoZWRl bGVnIHw9ICgxVUwgPDwgRVhDX0xPQURfUEFHRV9GQVVMVCk7Cj4gPiA+ID4gLSAgICAgICBoZWRl bGVnIHw9ICgxVUwgPDwgRVhDX1NUT1JFX1BBR0VfRkFVTFQpOwo+ID4gPiA+IC0gICAgICAgY3Ny X3dyaXRlKENTUl9IRURFTEVHLCBoZWRlbGVnKTsKPiA+ID4gPiAtCj4gPiA+ID4gLSAgICAgICBo aWRlbGVnID0gMDsKPiA+ID4gPiAtICAgICAgIGhpZGVsZWcgfD0gKDFVTCA8PCBJUlFfVlNfU09G VCk7Cj4gPiA+ID4gLSAgICAgICBoaWRlbGVnIHw9ICgxVUwgPDwgSVJRX1ZTX1RJTUVSKTsKPiA+ ID4gPiAtICAgICAgIGhpZGVsZWcgfD0gKDFVTCA8PCBJUlFfVlNfRVhUKTsKPiA+ID4gPiAtICAg ICAgIGNzcl93cml0ZShDU1JfSElERUxFRywgaGlkZWxlZyk7Cj4gPiA+ID4gKyAgICAgICBjc3Jf d3JpdGUoQ1NSX0hFREVMRUcsIEtWTV9IRURFTEVHX0RFRkFVTFQpOwo+ID4gPiA+ICsgICAgICAg Y3NyX3dyaXRlKENTUl9ISURFTEVHLCBLVk1fSElERUxFR19ERUZBVUxUKTsKPiA+ID4gPgo+ID4g PiA+ICAgICAgICAgLyogVlMgc2hvdWxkIGFjY2VzcyBvbmx5IHRoZSB0aW1lIGNvdW50ZXIgZGly ZWN0bHkuIEV2ZXJ5dGhpbmcgZWxzZSBzaG91bGQgdHJhcCAqLwo+ID4gPiA+ICAgICAgICAgY3Ny X3dyaXRlKENTUl9IQ09VTlRFUkVOLCAweDAyKTsKPiA+ID4gPiBkaWZmIC0tZ2l0IGEvYXJjaC9y aXNjdi9rdm0vdmNwdS5jIGIvYXJjaC9yaXNjdi9rdm0vdmNwdS5jCj4gPiA+ID4gaW5kZXggYjVj YTlmMmU5OGFjLi4yNDIwNzZjMjIyN2YgMTAwNjQ0Cj4gPiA+ID4gLS0tIGEvYXJjaC9yaXNjdi9r dm0vdmNwdS5jCj4gPiA+ID4gKysrIGIvYXJjaC9yaXNjdi9rdm0vdmNwdS5jCj4gPiA+ID4gQEAg LTQ3NSw4ICs0NzUsMTUgQEAgaW50IGt2bV9hcmNoX3ZjcHVfaW9jdGxfc2V0X21wc3RhdGUoc3Ry dWN0IGt2bV92Y3B1ICp2Y3B1LAo+ID4gPiA+ICBpbnQga3ZtX2FyY2hfdmNwdV9pb2N0bF9zZXRf Z3Vlc3RfZGVidWcoc3RydWN0IGt2bV92Y3B1ICp2Y3B1LAo+ID4gPiA+ICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICBzdHJ1Y3Qga3ZtX2d1ZXN0X2RlYnVnICpkYmcpCj4g PiA+ID4gIHsKPiA+ID4gPiAtICAgICAgIC8qIFRPRE87IFRvIGJlIGltcGxlbWVudGVkIGxhdGVy LiAqLwo+ID4gPiA+IC0gICAgICAgcmV0dXJuIC1FSU5WQUw7Cj4gPiA+Cj4gPiA+IGlmICh2Y3B1 LT5hcmNoLnJhbl9hdGxlYXN0X29uY2UpCj4gPiA+ICAgICAgICAgcmV0dXJuIC1FQlVTWTsKPiA+ Cj4gPiBJZiB3ZSBlbmFibGVkIHRoZSBndWVzdF9kZWJ1ZyBpbiBRRU1VIHNpZGUsIHRoZW4gdGhl IEtWTV9TRVRfR1VFU1RfREVCVUcgaW9jdGwKPiA+IHdpbGwgY29tZSBiZWZvcmUgdGhlIGZpcnN0 IEtWTV9SVU4uIFRoaXMgd2lsbCBhbHdheXMgY2F1c2UgYW4gRVJST1IuCj4gCj4gVGhlIGNoZWNr IGVuc3VyZXMgdGhhdCBLVk0gdXNlciBzcGFjZSBjYW4gb25seSBlbmFibGUvZGlzYWJsZQo+IGd1 ZXN0IGRlYnVnIGJlZm9yZSB0aGUgVkNQVSBpcyBydW4uIEkgZG9uJ3Qgc2VlIHdoeSB0aGlzIHdv dWxkCj4gZmFpbCBmb3IgUUVNVS4KCkluIHRoZSBjdXJyZW50IGltcGxlbWVudGF0aW9uIG9mIEdE QiBhbmQgUUVNVSwgdGhlIHVzZXJzcGFjZSB3aWxsIGVuYWJsZS9kaXNhYmxlCmd1ZXN0X2RlYnVn IGZyZXF1ZW50bHkgZHVyaW5nIHRoZSBkZWJ1Z2dpbmcgKGFsbW9zdCBldmVyeSBzdGVwKS4gClRo ZSBzZXF1ZW5jZSBzaG91bGQgbGlrZToKCktWTV9TRVRfR1VFU1RfREVCVUcgZW5hYmxlCktWTV9S VU4KS1ZNX1NFVF9HVUVTVF9ERUJVRyBkaXNhYmxlCktWTV9TRVRfR1VFU1RfREVCVUcgZW5hYmxl CktWTV9SVU4KS1ZNX1NFVF9HVUVTVF9ERUJVRyBkaXNhYmxlCktWTV9TRVRfR1VFU1RfREVCVUcg ZW5hYmxlCktWTV9SVU4KS1ZNX1NFVF9HVUVTVF9ERUJVRyBkaXNhYmxlCi4uLgoKPiAKPiA+Cj4g PiA+Cj4gPiA+Cj4gPiA+ID4gKyAgICAgICBpZiAoZGJnLT5jb250cm9sICYgS1ZNX0dVRVNUREJH X0VOQUJMRSkgewo+ID4gPiA+ICsgICAgICAgICAgICAgICB2Y3B1LT5ndWVzdF9kZWJ1ZyA9IGRi Zy0+Y29udHJvbDsKPiA+ID4gPiArICAgICAgICAgICAgICAgdmNwdS0+YXJjaC5jZmcuaGVkZWxl ZyA9IEtWTV9IRURFTEVHX0dVRVNUX0RFQlVHOwo+ID4gPiA+ICsgICAgICAgfSBlbHNlIHsKPiA+ ID4gPiArICAgICAgICAgICAgICAgdmNwdS0+Z3Vlc3RfZGVidWcgPSAwOwo+ID4gPiA+ICsgICAg ICAgICAgICAgICB2Y3B1LT5hcmNoLmNmZy5oZWRlbGVnID0gS1ZNX0hFREVMRUdfREVGQVVMVDsK PiA+ID4gPiArICAgICAgIH0KPiA+ID4KPiA+ID4gRG9uJ3QgdXBkYXRlIHZjcHUtPmFyY2guY2Zn LmhlZGVsZWcgaGVyZSBzaW5jZSBpdCBzaG91bGQgYmUgb25seSBkb25lCj4gPiA+IGluIGt2bV9y aXNjdl92Y3B1X3NldHVwX2NvbmZpZygpLgo+ID4gPgo+ID4gPiA+ICsKPiA+ID4gPiArICAgICAg IHJldHVybiAwOwo+ID4gPiA+ICB9Cj4gPiA+ID4KPiA+ID4gPiAgc3RhdGljIHZvaWQga3ZtX3Jp c2N2X3ZjcHVfc2V0dXBfY29uZmlnKHN0cnVjdCBrdm1fdmNwdSAqdmNwdSkKPiA+ID4gPiBAQCAt NTA1LDYgKzUxMiw5IEBAIHN0YXRpYyB2b2lkIGt2bV9yaXNjdl92Y3B1X3NldHVwX2NvbmZpZyhz dHJ1Y3Qga3ZtX3ZjcHUgKnZjcHUpCj4gPiA+ID4gICAgICAgICAgICAgICAgIGlmIChyaXNjdl9p c2FfZXh0ZW5zaW9uX2F2YWlsYWJsZShpc2EsIFNNU1RBVEVFTikpCj4gPiA+ID4gICAgICAgICAg ICAgICAgICAgICAgICAgY2ZnLT5oc3RhdGVlbjAgfD0gU01TVEFURUVOMF9TU1RBVEVFTjA7Cj4g PiA+ID4gICAgICAgICB9Cj4gPiA+ID4gKwo+ID4gPiA+ICsgICAgICAgaWYgKCF2Y3B1LT5ndWVz dF9kZWJ1ZykKPiA+ID4gPiArICAgICAgICAgICAgICAgY2ZnLT5oZWRlbGVnID0gS1ZNX0hFREVM RUdfREVGQVVMVDsKPiA+ID4KPiA+ID4gVGhpcyBzaG91bGQgYmU6Cj4gPiA+Cj4gPiA+IGNmZy0+ aGVkZWxlZyA9IEtWTV9IRURFTEVHX0RFRkFVTFQ7Cj4gPiA+IGlmICh2Y3B1LT5ndWVzdF9kZWJ1 ZykKPiA+ID4gICAgICAgICBjZmctPmhlZGVsZWcgfD0gQklUKEVYQ19CUkVBS1BPSU5UKTsKPiA+ Cj4gPiBMaWtlIGFib3ZlLCBoZXJlIHRoZSBsb2dpYyBzaG91bGQgYmU6Cj4gPgo+ID4gY2ZnLT5o ZWRlbGVnID0gS1ZNX0hFREVMRUdfREVGQVVMVDsgLy8gd2l0aCBCSVQoRVhDX0JSRUFLUE9JTlQp Cj4gPiBpZiAodmNwdS0+Z3Vlc3RfZGVidWcpCj4gPiAgICAgICAgIGNmZy0+aGVkZWxlZyAmPSB+ QklUKEVYQ19CUkVBS1BPSU5UKTsKPiA+Cj4gPiBBbm90aGVyIGFwcHJvYWNoIGlzOgo+ID4gaW5p dGlhbGl6ZSB0aGUgY2ZnLT5oZWRlbGVnIGFzIEtWTV9IRURFTEVHX0RFRkFVTFQgZHVyaW5nIGt2 bV9hcmNoX3ZjcHVfY3JlYXRlKCkuCj4gPiBCZXNpZGVzIHRoYXQsIG9ubHkgdXBkYXRlIHRoZSBj ZmctPmhlZGVsZWcgaW4ga3ZtX2FyY2hfdmNwdV9pb2N0bF9zZXRfZ3Vlc3RfZGVidWcoKS4KPiAK PiBJIGRpc2FncmVlLiBXZSBzaG91bGQgaGFuZGxlIGhlZGVsZWcganVzdCBsaWtlIHdlIGhhbmRs ZSBoZW52Y2ZnLgoKT0ssIGxldCdzIG9ubHkgdXBkYXRlIHRoZSBjZmctPmhlZGVsZWcgaW4ga3Zt X3Jpc2N2X3ZjcHVfc2V0dXBfY29uZmlnKCkuCgo+IAo+ID4KPiA+ID4KPiA+ID4gPiAgfQo+ID4g PiA+Cj4gPiA+ID4gIHZvaWQga3ZtX2FyY2hfdmNwdV9sb2FkKHN0cnVjdCBrdm1fdmNwdSAqdmNw dSwgaW50IGNwdSkKPiA+ID4gPiBAQCAtNTE5LDYgKzUyOSw3IEBAIHZvaWQga3ZtX2FyY2hfdmNw dV9sb2FkKHN0cnVjdCBrdm1fdmNwdSAqdmNwdSwgaW50IGNwdSkKPiA+ID4gPiAgICAgICAgIGNz cl93cml0ZShDU1JfVlNFUEMsIGNzci0+dnNlcGMpOwo+ID4gPiA+ICAgICAgICAgY3NyX3dyaXRl KENTUl9WU0NBVVNFLCBjc3ItPnZzY2F1c2UpOwo+ID4gPiA+ICAgICAgICAgY3NyX3dyaXRlKENT Ul9WU1RWQUwsIGNzci0+dnN0dmFsKTsKPiA+ID4gPiArICAgICAgIGNzcl93cml0ZShDU1JfSEVE RUxFRywgY2ZnLT5oZWRlbGVnKTsKPiA+ID4gPiAgICAgICAgIGNzcl93cml0ZShDU1JfSFZJUCwg Y3NyLT5odmlwKTsKPiA+ID4gPiAgICAgICAgIGNzcl93cml0ZShDU1JfVlNBVFAsIGNzci0+dnNh dHApOwo+ID4gPiA+ICAgICAgICAgY3NyX3dyaXRlKENTUl9IRU5WQ0ZHLCBjZmctPmhlbnZjZmcp Owo+ID4gPiA+IGRpZmYgLS1naXQgYS9hcmNoL3Jpc2N2L2t2bS92bS5jIGIvYXJjaC9yaXNjdi9r dm0vdm0uYwo+ID4gPiA+IGluZGV4IGNlNThiYzQ4ZTViOC4uNzM5NmI4NjU0ZjQ1IDEwMDY0NAo+ ID4gPiA+IC0tLSBhL2FyY2gvcmlzY3Yva3ZtL3ZtLmMKPiA+ID4gPiArKysgYi9hcmNoL3Jpc2N2 L2t2bS92bS5jCj4gPiA+ID4gQEAgLTE4Niw2ICsxODYsNyBAQCBpbnQga3ZtX3ZtX2lvY3RsX2No ZWNrX2V4dGVuc2lvbihzdHJ1Y3Qga3ZtICprdm0sIGxvbmcgZXh0KQo+ID4gPiA+ICAgICAgICAg Y2FzZSBLVk1fQ0FQX1JFQURPTkxZX01FTToKPiA+ID4gPiAgICAgICAgIGNhc2UgS1ZNX0NBUF9N UF9TVEFURToKPiA+ID4gPiAgICAgICAgIGNhc2UgS1ZNX0NBUF9JTU1FRElBVEVfRVhJVDoKPiA+ ID4gPiArICAgICAgIGNhc2UgS1ZNX0NBUF9TRVRfR1VFU1RfREVCVUc6Cj4gPiA+ID4gICAgICAg ICAgICAgICAgIHIgPSAxOwo+ID4gPiA+ICAgICAgICAgICAgICAgICBicmVhazsKPiA+ID4gPiAg ICAgICAgIGNhc2UgS1ZNX0NBUF9OUl9WQ1BVUzoKPiA+ID4gPiAtLQo+ID4gPiA+IDIuMTcuMQo+ ID4gPiA+Cj4gPiA+Cj4gPiA+IFJlZ2FyZHMsCj4gPiA+IEFudXAKPiA+Cj4gPiBUaGFua3MsCj4g PiBDaGFvCj4gCj4gUmVnYXJkcywKPiBBbnVwCgpUaGFua3MsCkNoYW8K