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 X-Spam-Level: X-Spam-Status: No, score=-8.0 required=3.0 tests=DKIM_INVALID,DKIM_SIGNED, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_PATCH,MAILING_LIST_MULTI, MSGID_FROM_MTA_HEADER,SIGNED_OFF_BY,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED, USER_AGENT_SANE_1 autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id D0BB2C10F27 for ; Tue, 10 Mar 2020 07:45:26 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 7370224677 for ; Tue, 10 Mar 2020 07:45:26 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (1024-bit key) header.d=virtuozzo.com header.i=@virtuozzo.com header.b="eWZ2LNk/" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 7370224677 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=virtuozzo.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Received: from localhost ([::1]:54718 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1jBZZt-0000QY-GI for qemu-devel@archiver.kernel.org; Tue, 10 Mar 2020 03:45:25 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:47275) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1jBZZA-0008L4-8m for qemu-devel@nongnu.org; Tue, 10 Mar 2020 03:44:43 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1jBZZ7-000786-IV for qemu-devel@nongnu.org; Tue, 10 Mar 2020 03:44:40 -0400 Received: from mail-db8eur05on2118.outbound.protection.outlook.com ([40.107.20.118]:23329 helo=EUR05-DB8-obe.outbound.protection.outlook.com) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1jBZYy-0006sH-RG; Tue, 10 Mar 2020 03:44:29 -0400 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=MqAxZTvasyOnFZ1VNP/qmTYzwQoXEkwr/R6Y8AU1/nEdGup6IZqMDv6WvT+GM2b5r+4XHB97aNvxjCdMHHiAYSi9dfnKk5iYhHsFN+lG2jBi7BgGRuJfYsuCX77zBMQdnbVibku9tbeQZK3hiwC325PK6eIniE5iCAFGwwmD82vtPkdtL2gejDNidLRkRsDHdAShrnlWle7wVvBoQ7lcrgwedbU2CVCmhDZbnp7JGRFGBM6fG9CPI4xg0sG9yArSbVHduKAloi+VO7c5w0yNLMvhV3SJ9piVDMbvJo2l1KUjgIuYh7vTowJt3pX1Afm8sYGPs7pH9rN2YVhEGoOybA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=D1DArs3hULPds8mFTUJzEMnW6wW5lnk6t0D8MYKCJYI=; b=kUWfvSh+INsJcBCgdVu5WdTtkAKjq4lhDk4VeJ/o2WMhOkmBSpslFoHD89IQ9xnBOy0yW0JuXKLC1nav7MbYMubb37wMiX1TOfMVagJDEk3affEZMGV5WBp+1eT88inPdaWV9aSmRJVtd/KX0lD62mbrqvVuYv2XMFWb+NnCapL9XCyfFkol8mIMms4VMEaGWxOoj1fJOlAShswRoQIEaMMiFiLtj3DHWjWtVckQPKQxkR192EhUZKGwhCBJyRdeMeNy5+hRmvrOHisrfmXFJPFjhd9gV7Sl1m0t4/LZrGnZj0mjyr48BUq0lRiVifMNFaPC9HAPIbXlcimrXNeRQg== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=virtuozzo.com; dmarc=pass action=none header.from=virtuozzo.com; dkim=pass header.d=virtuozzo.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=virtuozzo.com; s=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=D1DArs3hULPds8mFTUJzEMnW6wW5lnk6t0D8MYKCJYI=; b=eWZ2LNk/xCnm7AV5rFQ/RK4+MiVb05eOdvf7ZlE63xyQfwCA3++9KjApUKGjJYTzB9HYJW2+ZskyHeM13HU7QsKHNn8Ajo6IxayYBwRCEyS9fEstPcr1WcGZijLaogsUgzeqcnPnGhZQ4B+h/opljBe/sNqzbhMIv6tLfoIbJFw= Authentication-Results: spf=none (sender IP is ) smtp.mailfrom=vsementsov@virtuozzo.com; Received: from AM6PR08MB4423.eurprd08.prod.outlook.com (20.179.7.140) by AM6PR08MB5206.eurprd08.prod.outlook.com (10.255.122.18) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.2793.16; Tue, 10 Mar 2020 07:44:25 +0000 Received: from AM6PR08MB4423.eurprd08.prod.outlook.com ([fe80::e05a:63af:818c:b664]) by AM6PR08MB4423.eurprd08.prod.outlook.com ([fe80::e05a:63af:818c:b664%4]) with mapi id 15.20.2793.018; Tue, 10 Mar 2020 07:44:25 +0000 Subject: Re: [PATCH v8 02/10] scripts: add coccinelle script to use auto propagated errp To: Markus Armbruster References: <20200306051536.27803-1-vsementsov@virtuozzo.com> <20200306051536.27803-3-vsementsov@virtuozzo.com> <87lfo997hs.fsf@dusky.pond.sub.org> From: Vladimir Sementsov-Ogievskiy X-Tagtoolbar-Keys: D20200310104422742 Message-ID: Date: Tue, 10 Mar 2020 10:44:22 +0300 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Thunderbird/60.2.1 In-Reply-To: <87lfo997hs.fsf@dusky.pond.sub.org> Content-Type: text/plain; charset=utf-8; format=flowed Content-Language: en-US Content-Transfer-Encoding: quoted-printable X-ClientProxiedBy: HE1PR07CA0040.eurprd07.prod.outlook.com (2603:10a6:7:66::26) To AM6PR08MB4423.eurprd08.prod.outlook.com (2603:10a6:20b:bf::12) MIME-Version: 1.0 X-MS-Exchange-MessageSentRepresentingType: 1 Received: from [172.16.24.200] (185.231.240.5) by HE1PR07CA0040.eurprd07.prod.outlook.com (2603:10a6:7:66::26) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.2814.6 via Frontend Transport; Tue, 10 Mar 2020 07:44:24 +0000 X-Tagtoolbar-Keys: D20200310104422742 X-Originating-IP: [185.231.240.5] X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: 2b33c834-7f2e-4142-ccde-08d7c4c6db17 X-MS-TrafficTypeDiagnostic: AM6PR08MB5206: X-Microsoft-Antispam-PRVS: X-MS-Oob-TLC-OOBClassifiers: OLM:5516; X-Forefront-PRVS: 033857D0BD X-Forefront-Antispam-Report: SFV:NSPM; SFS:(10019020)(346002)(39850400004)(366004)(376002)(396003)(136003)(189003)(199004)(52116002)(6916009)(86362001)(26005)(8936002)(8676002)(4326008)(81156014)(81166006)(478600001)(5660300002)(54906003)(316002)(2906002)(16576012)(31686004)(7416002)(36756003)(6486002)(66946007)(186003)(16526019)(30864003)(2616005)(956004)(66476007)(66556008)(31696002)(2004002); DIR:OUT; SFP:1102; SCL:1; SRVR:AM6PR08MB5206; H:AM6PR08MB4423.eurprd08.prod.outlook.com; FPR:; SPF:None; LANG:en; PTR:InfoNoRecords; MX:1; A:1; Received-SPF: None (protection.outlook.com: virtuozzo.com does not designate permitted sender hosts) X-MS-Exchange-SenderADCheck: 1 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: Hi6F09e1JOZFVYHcC8mG119n3W4JxX0oq68k+hNnx//zsgjWwv4vofmXkI4Gz7FrtfCB2z19lfUPc4Csurnln5+pVQVF0qoGhoi4S7F45HUs2H/OaboOn/x4EUyvIWZ4CJCVmYDxbh8oKbaykJyuSNGQLTHNQZq5iPW0AT8QZbhrSXecRK1ZaQ9J1ZnDwR/UHTBfJg+O3XbbItUTExajtcFhTxum0pJKtFS2cbds/6qrU4ErpJxhIC5cp9OpMDACgvsPcZzeZ+Q1ecbiEULcmI60kZXBfiDvBaDi6rgL0l0XT1sGP6YwOh1HXK8D3LzZnqrrEK0fIND16MbvjGHr6GtwtmsNmW4/2cHllgu43gxwhfKiUq1DhRAZdkYT3CWLBYOR/nMJhk03LIn4f3NNLWSkmpF98tUUH+s1RC48v+mDdgZ+1EfZHBY7HicD1B1p9b0kQS7TwoVfxQ/WVTKwE4pO9bGp9oYQL6YnNKQBBp0bQ2ilOTUuk9S2Z89S2Wgr2WdSI8xTEqD9xGaivR8EUS3AIh0gEmIg7I2AwfKeADmowFutcyfpwx1CaBlHlXNA X-MS-Exchange-AntiSpam-MessageData: u6zlm/Dh/r8/wGQ9j2v0gox0p4FaGgYL1Vz+cTRZjGES3hTQpxa1f42ucVcc0A28vclLi2QodJPWPIH3foWGbQWtPgBp2qJkRIPvGIvy7oTnQFuaK6f0XzmywkoIoIQOV9sAC6prxRQCenm15f0Izw== X-OriginatorOrg: virtuozzo.com X-MS-Exchange-CrossTenant-Network-Message-Id: 2b33c834-7f2e-4142-ccde-08d7c4c6db17 X-MS-Exchange-CrossTenant-OriginalArrivalTime: 10 Mar 2020 07:44:25.7581 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 0bc7f26d-0264-416e-a6fc-8352af79c58f X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: Q+7KkSU5SH9zuw0C05mAoLt9Gn0xWv1qfEWJRRp/WbsXRjGVR4GuBlXtZQIouNB1hGrbEzBFXFx2OOuqgrCh8AWAeLc/Y6tjVliocxQLZuo= X-MS-Exchange-Transport-CrossTenantHeadersStamped: AM6PR08MB5206 X-detected-operating-system: by eggs.gnu.org: Windows NT kernel [generic] [fuzzy] X-Received-From: 40.107.20.118 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Kevin Wolf , Stefano Stabellini , Michael Roth , qemu-block@nongnu.org, Paul Durrant , Laszlo Ersek , Christian Schoenebeck , qemu-devel@nongnu.org, Greg Kurz , Gerd Hoffmann , Stefan Hajnoczi , Anthony Perard , xen-devel@lists.xenproject.org, Max Reitz , =?UTF-8?Q?Philippe_Mathieu-Daud=c3=a9?= , Stefan Berger Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" 09.03.2020 12:56, Markus Armbruster wrote: > Suggest >=20 > scripts: Coccinelle script to use auto-propagated errp >=20 > or >=20 > scripts: Coccinelle script to use ERRP_AUTO_PROPAGATE() >=20 > Vladimir Sementsov-Ogievskiy writes: >=20 >> Script adds ERRP_AUTO_PROPAGATE macro invocation where appropriate and >> does corresponding changes in code (look for details in >> include/qapi/error.h) >> >> Usage example: >> spatch --sp-file scripts/coccinelle/auto-propagated-errp.cocci \ >> --macro-file scripts/cocci-macro-file.h --in-place --no-show-diff \ >> blockdev-nbd.c qemu-nbd.c {block/nbd*,nbd/*,include/block/nbd*}.[hc] >=20 > Suggest FILES... instead of a specific set of files. >=20 >> Signed-off-by: Vladimir Sementsov-Ogievskiy >> --- >> >> Cc: Eric Blake >> Cc: Kevin Wolf >> Cc: Max Reitz >> Cc: Greg Kurz >> Cc: Christian Schoenebeck >> Cc: Stefano Stabellini >> Cc: Anthony Perard >> Cc: Paul Durrant >> Cc: Stefan Hajnoczi >> Cc: "Philippe Mathieu-Daud=C3=A9" >> Cc: Laszlo Ersek >> Cc: Gerd Hoffmann >> Cc: Stefan Berger >> Cc: Markus Armbruster >> Cc: Michael Roth >> Cc: qemu-block@nongnu.org >> Cc: qemu-devel@nongnu.org >> Cc: xen-devel@lists.xenproject.org >> >> include/qapi/error.h | 3 + >> scripts/coccinelle/auto-propagated-errp.cocci | 231 ++++++++++++++++++ >> 2 files changed, 234 insertions(+) >> create mode 100644 scripts/coccinelle/auto-propagated-errp.cocci >> >> diff --git a/include/qapi/error.h b/include/qapi/error.h >> index bb9bcf02fb..fbfc6f1c0b 100644 >> --- a/include/qapi/error.h >> +++ b/include/qapi/error.h >> @@ -211,6 +211,9 @@ >> * } >> * ... >> * } >> + * >> + * For mass conversion use script >=20 > mass-conversion (we're not converting mass, we're converting en masse) >=20 >> + * scripts/coccinelle/auto-propagated-errp.cocci >> */ >> =20 >> #ifndef ERROR_H >> diff --git a/scripts/coccinelle/auto-propagated-errp.cocci b/scripts/coc= cinelle/auto-propagated-errp.cocci >> new file mode 100644 >> index 0000000000..bff274bd6d >> --- /dev/null >> +++ b/scripts/coccinelle/auto-propagated-errp.cocci >=20 > Preface to my review of this script: may aim isn't to make it > bullet-proof. I want to (1) make it good enough (explained in a > jiffie), and (2) automatically identify the spots where it still isn't > obviously safe for manual review. >=20 > The latter may involve additional scripting. That's okay. >=20 > The script is good enough when the number of possibly unsafe spots is > low enough for careful manual review. >=20 > When I ask for improvements that, in your opinion, go beyond "good > enough", please push back. I'm sure we can work it out together. >=20 >> @@ -0,0 +1,231 @@ >> +// Use ERRP_AUTO_PROPAGATE (see include/qapi/error.h) >> +// >> +// Copyright (c) 2020 Virtuozzo International GmbH. >> +// >> +// This program is free software; you can redistribute it and/or modify >> +// it under the terms of the GNU General Public License as published by >> +// the Free Software Foundation; either version 2 of the License, or >> +// (at your option) any later version. >> +// >> +// This program is distributed in the hope that it will be useful, >> +// but WITHOUT ANY WARRANTY; without even the implied warranty of >> +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the >> +// GNU General Public License for more details. >> +// >> +// You should have received a copy of the GNU General Public License >> +// along with this program. If not, see = . >> +// >> +// Usage example: >> +// spatch --sp-file scripts/coccinelle/auto-propagated-errp.cocci \ >> +// --macro-file scripts/cocci-macro-file.h --in-place --no-show-diff \ >> +// --max-width 80 blockdev-nbd.c qemu-nbd.c \ >=20 > You have --max-width 80 here, but not in the commit message. Default > seems to be 78. Any particular reason to change it to 80? Hmm. As I remember, without this parameter, reindenting doesn't work correc= tly. So, I'm OK with "--max-width 78", but I doubt that it will work without a p= arameter. Still, may be I'm wrong, we can check it. >=20 >> +// {block/nbd*,nbd/*,include/block/nbd*}.[hc] >> + >> +// Switch unusual (Error **) parameter names to errp >=20 > Let's drop the parenthesis around Error ** >=20 >> +// (this is necessary to use ERRP_AUTO_PROPAGATE). >=20 > Perhaps ERRP_AUTO_PROPAGATE() should be ERRP_AUTO_PROPAGATE(errp) to > make the fact we're messing with @errp more obvious. Too late; I > shouldn't rock the boat that much now. >=20 >> +// >> +// Disable optional_qualifier to skip functions with "Error *const *err= p" >> +// parameter. >> +// >> +// Skip functions with "assert(_errp && *_errp)" statement, as they hav= e >> +// non generic semantics and may have unusual Error ** argument name fo= r purpose >=20 > non-generic >=20 > for a purpose >=20 > Wrap comment lines around column 70, please. It's easier to read. >=20 > Maybe >=20 > // Skip functions with "assert(_errp && *_errp)" statement, because t= hat > // signals unusual semantics, and the parameter name may well serve a > // purpose. Sounds good. >=20 >> +// (like nbd_iter_channel_error()). >> +// >> +// Skip util/error.c to not touch, for example, error_propagate and >> +// error_propagate_prepend(). >=20 > error_propagate() >=20 > I much appreciate your meticulous explanation of what you skip and why. >=20 >> +@ depends on !(file in "util/error.c") disable optional_qualifier@ >> +identifier fn; >> +identifier _errp !=3D errp; >> +@@ >> + >> + fn(..., >> +- Error **_errp >> ++ Error **errp >> + ,...) >> + { >> +( >> + ... when !=3D assert(_errp && *_errp) >> +& >> + <... >> +- _errp >> ++ errp >> + ...> >> +) >> + } >=20 > This rule is required to make the actual transformations (below) work > even for parameters with names other than @errp. I believe it's not > used in this series. In fact, I can't see a use for it in the entire > tree right now. Okay anyway. >=20 >> + >> +// Add invocation of ERRP_AUTO_PROPAGATE to errp-functions where necess= ary >> +// >> +// Note, that without "when any" final "..." may not want to mach somet= hing >=20 > s/final "..." may not mach/the final "..." does not match/ >=20 >> +// matched by previous pattern, i.e. the rule will not match double >> +// error_prepend in control flow like in vfio_set_irq_signaling(). >=20 > Can't say I fully understand Coccinelle there. I figure you came to > this knowledge the hard way. It's follows from smpl grammar document: "Implicitly, =E2=80=9C...=E2=80=9D matches the shortest path between someth= ing that matches the pattern before the dots (or the beginning of the funct= ion, if there is nothing before the dots) and something that matches the pa= ttern after the dots (or the end of the function, if there is nothing after= the dots)." ... "_when any_ removes the aforementioned constraint that =E2=80=9C...=E2=80= =9D matches the shortest path" >=20 >> +// >> +// Note, "exists" says that we want apply rule even if it matches not o= n >> +// all possible control flows (otherwise, it will not match standard pa= ttern >> +// when error_propagate() call is in if branch). >=20 > Learned something new. Example: kvm_set_kvm_shadow_mem(). >=20 > Spelling it "exists disable optional_qualifier" would avoid giving > readers the idea we're disabling "exists", but Coccinelle doesn't let > us. Oh well. >=20 >> +@ disable optional_qualifier exists@ >> +identifier fn, local_err, errp; >=20 > I believe this causes >=20 > warning: line 98: errp, previously declared as a metavariable, is us= ed as an identifier > warning: line 104: errp, previously declared as a metavariable, is u= sed as an identifier > warning: line 106: errp, previously declared as a metavariable, is u= sed as an identifier > warning: line 131: errp, previously declared as a metavariable, is u= sed as an identifier > warning: line 192: errp, previously declared as a metavariable, is u= sed as an identifier > warning: line 195: errp, previously declared as a metavariable, is u= sed as an identifier > warning: line 228: errp, previously declared as a metavariable, is u= sed as an identifier >=20 > Making @errp symbol instead of identifier should fix this. Hmm, I didn't see these warnings.. But yes, it should be symbol. >=20 >> +@@ >> + >> + fn(..., Error **errp, ...) >> + { >> ++ ERRP_AUTO_PROPAGATE(); >> + ... when !=3D ERRP_AUTO_PROPAGATE(); >> +( >> + error_append_hint(errp, ...); >> +| >> + error_prepend(errp, ...); >> +| >> + error_vprepend(errp, ...); >> +| >> + Error *local_err =3D NULL; >> + ... >> +( >> + error_propagate_prepend(errp, local_err, ...); >> +| >> + error_propagate(errp, local_err); >> +) >> +) >> + ... when any >> + } >> + >> + >> +// Match scenarios with propagation of local error to errp. >> +@rule1 disable optional_qualifier exists@ >> +identifier fn, local_err; >> +symbol errp; >> +@@ >> + >> + fn(..., Error **errp, ...) >> + { >> + ... >> + Error *local_err =3D NULL; >> + ... >> +( >> + error_propagate_prepend(errp, local_err, ...); >> +| >> + error_propagate(errp, local_err); >> +) >=20 > Indentation off by one. >=20 >> + ... >> + } >> + >> +// Convert special case with goto in separate. >=20 > s/in separate/separately/ >=20 >> +// We can probably merge this into the following hunk with help of ( | = ) >> +// operator, but it significantly reduce performance on block.c parsing= (or it >=20 > s/reduce/reduces/ >=20 >> +// hangs, I don't know) >=20 > Sounds like you tried to merge this into the following hunk, but then > spatch took so long on block.c that you killed it. Correct? Yes. >=20 >> +// >> +// Note interesting thing: if we don't do it here, and try to fixup "ou= t: }" >> +// things later after all transformations (the rule will be the same, j= ust >> +// without error_propagate() call), coccinelle fails to match this "out= : }". >=20 > Weird, but not worth further investigation. It partially match to the idea which I saw somewhere in coccinelle document= ation, that coccinelle converts correct C code to correct C code. "out: }" is an e= xample of incorrect, impossible code flow, and coccinelle can't work with it... Bu= t it's just a thought. >=20 >> +@@ >> +identifier rule1.fn, rule1.local_err, out; >> +symbol errp; >> +@@ >> + >> + fn(...) >> + { >> + <... >> +- goto out; >> ++ return; >> + ...> >> +- out: >> +- error_propagate(errp, local_err); >=20 > You neglect to match error_propagate_prepend(). Okay, because (1) that > pattern doesn't occur in the tree right now, and (2) if it gets added, > gcc will complain. No, because it should not removed. error_propagate_prepend should be conver= ted to prepend, not removed. So, corresponding gotos should not be removed as w= ell. >=20 >> + } >> + >> +// Convert most of local_err related staff. >=20 > s/staff/stuff/ >=20 >> +// >> +// Note, that we update everything related to matched by rule1 function= name >> +// and local_err name. We may match something not related to the patter= n >> +// matched by rule1. For example, local_err may be defined with the sam= e name >> +// in different blocks inside one function, and in one block follow the >> +// propagation pattern and in other block doesn't. Or we may have sever= al >> +// functions with the same name (for different configurations). >=20 > Context: rule1 matches functions that have all three of >=20 > * an Error **errp parameter >=20 > * an Error *local_err =3D NULL variable declaration >=20 > * an error_propagate(errp, local_err) or error_propagate_prepend(errp, > local_err, ...) expression, where @errp is the parameter and > @local_err is the variable. >=20 > If I understand you correctly, you're pointing out two potential issues: >=20 > 1. This rule can match functions rule1 does not match if there is > another function with the same name that rule1 does match. >=20 > 2. This rule matches in the entire function matched by rule1, even when > parts of that function use a different @errp or @local_err. >=20 > I figure these apply to all rules with identifier rule1.fn, not just > this one. Correct? Yes. >=20 > Regarding 1. There must be a better way to chain rules together, but I > don't know it. > Can we make Coccinelle at least warn us when it converts > multiple functions with the same name? What about this: >=20 > @initialize:python@ > @@ > fnprev =3D {} >=20 > def pr(fn, p): > print("### %s:%s: %s()" % (p[0].file, p[0].line, fn)) >=20 > @r@ > identifier rule1.fn; > position p; > @@ > fn(...)@p > { > ... > } > @script:python@ > fn << rule1.fn; > p << r.p; > @@ > if fn not in fnprev: > fnprev[fn] =3D p > else: > if fnprev[fn]: hmm, the condition can't be false > pr(fn, fnprev[fn]) > fnprev[fn] =3D None > pr(fn, p) and we'll miss next duplication.. But I like the idea. >=20 > For each function @fn matched by rule1, fncnt[fn] is an upper limit of > the number of functions with the same name we touch. If it's more than > one, we print. >=20 > Reports about a dozen function names for the whole tree in my testing. > Inspecting the changes to them manually is feasible. None of them are > in files touched by this series. >=20 > The line printed for the first match is pretty useless for me: it points > to a Coccinelle temporary file *shrug*. >=20 > Regarding 2. Shadowing @errp or @local_err would be in bad taste, and I > sure hope we don't do that. Multiple @local_err variables... hmm. > Perhaps we could again concoct some script rules to lead us to spots to > check manually. See below for my attempt. >=20 > What's the worst that could happen if we blindly converted such code? > The answer to that question tells us how hard to work on finding and > checking these guys. >=20 >> +// >> +// Note also that errp-cleaning functions >> +// error_free_errp >> +// error_report_errp >> +// error_reportf_errp >> +// warn_report_errp >> +// warn_reportf_errp >> +// are not yet implemented. They must call corresponding Error* - freei= ng >> +// function and then set *errp to NULL, to avoid further propagation to >> +// original errp (consider ERRP_AUTO_PROPAGATE in use). >> +// For example, error_free_errp may look like this: >> +// >> +// void error_free_errp(Error **errp) >> +// { >> +// error_free(*errp); >> +// *errp =3D NULL; >> +// } >> +@ exists@ >> +identifier rule1.fn, rule1.local_err; >> +expression list args; >> +symbol errp; >> +@@ >> + >> + fn(...) >> + { >> + <... >> +( >=20 > Each of the following patterns applies anywhere in the function. >=20 > First pattern: delete @local_err >=20 >> +- Error *local_err =3D NULL; >=20 > Common case: occurs just once, not nested. Anything else is suspicious. >=20 > Both can be detected in the resulting patches with a bit of AWK > wizardry: >=20 > $ git-diff -U0 master..review-error-v8 | awk '/^@@ / { ctx =3D $5; f= or (i =3D 6; i <=3D NF; i++) ctx =3D ctx " " $i; if (ctx !=3D octx) { octx = =3D ctx; n =3D 0 } } /^- *Error *\* *[A-Za-z0-9_]+ *=3D *NULL;/ { if (index= ($0, "E") > 6) print "nested\n " ctx; if (n) print "more than one\n "= ctx; n++ }' > nested > static void xen_block_drive_destroy(XenBlockDrive *drive, Error = **errp) > nested > static void xen_block_device_destroy(XenBackendInstance *backend= , > nested > static void xen_block_device_destroy(XenBackendInstance *backend= , > more than one > static void xen_block_device_destroy(XenBackendInstance *backend= , >=20 > Oh. >=20 > xen_block_drive_destroy() nests its Error *local_err in a conditional. >=20 > xen_block_device_destroy() has multiple Error *local_err. >=20 > In both cases, manual review is required to ensure the conversion is > okay. I believe it is. >=20 > Note that the AWK script relies on diff showing the function name in @@ > lines, which doesn't always work due to our coding style. >=20 > For the whole tree, I get some 30 spots. Feasible. >=20 >> +| >=20 > Second pattern: clear @errp after freeing it >=20 >> + >> +// Convert error clearing functions >=20 > Suggest: Ensure @local_err is cleared on free >=20 >> +( >> +- error_free(local_err); >> ++ error_free_errp(errp); >> +| >> +- error_report_err(local_err); >> ++ error_report_errp(errp); >> +| >> +- error_reportf_err(local_err, args); >> ++ error_reportf_errp(errp, args); >> +| >> +- warn_report_err(local_err); >> ++ warn_report_errp(errp); >> +| >> +- warn_reportf_err(local_err, args); >> ++ warn_reportf_errp(errp, args); >> +) >=20 > As you mention above, these guys don't exist, yet. Builds anyway, > because this part of the rule is not used in this patch series. You > don't want to omit it, because then the script becomes unsafe to use. >=20 > We could also open-code: >=20 > // Convert error clearing functions > ( > - error_free(local_err); > + error_free(*errp); > + *errp =3D NULL; > | > ... and so forth ... > ) >=20 > Matter of taste. Whatever is easier to explain in the comments. Since > you already wrote one... I just feel that using helper functions is safer way.. >=20 > We talked about extending this series slightly so these guys are used. > I may still look into that. >=20 >> +?- local_err =3D NULL; >> + >=20 > The new helpers clear @local_err. Assignment now redundant, delete. > Okay. >=20 >> +| >=20 > Third and fourth pattern: delete error_propagate() >=20 >> +- error_propagate_prepend(errp, local_err, args); >> ++ error_prepend(errp, args); >> +| >> +- error_propagate(errp, local_err); >> +| >=20 > Fifth pattern: use @errp directly >=20 >> +- &local_err >> ++ errp >> +) >> + ...> >> + } >> + >> +// Convert remaining local_err usage. It should be different kinds of e= rror >> +// checking in if operators. We can't merge this into previous hunk, as= this >=20 > In if conditionals, I suppose. It's the case for this patch. If I > apply the script to the whole tree, the rule gets also applied in other > contexts. The sentence might mislead as much as it helps. Keep it or > delete it? Maybe, just be more honest: "It should be ..., but it may be any other patt= ern, be careful" >=20 >> +// conflicts with other substitutions in it (at least with "- local_err= =3D NULL"). >> +@@ >> +identifier rule1.fn, rule1.local_err; >> +symbol errp; >> +@@ >> + >> + fn(...) >> + { >> + <... >> +- local_err >> ++ *errp >> + ...> >> + } >> + >> +// Always use the same patter for checking error >=20 > s/patter/pattern/ >=20 >> +@@ >> +identifier rule1.fn; >> +symbol errp; >> +@@ >> + >> + fn(...) >> + { >> + <... >> +- *errp !=3D NULL >> ++ *errp >> + ...> >> + } >=20 --=20 Best regards, Vladimir 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 X-Spam-Level: X-Spam-Status: No, score=-8.0 required=3.0 tests=DKIM_INVALID,DKIM_SIGNED, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_PATCH,MAILING_LIST_MULTI, MSGID_FROM_MTA_HEADER,SIGNED_OFF_BY,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED, USER_AGENT_SANE_1 autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id DFF0DC10F27 for ; Tue, 10 Mar 2020 07:45:02 +0000 (UTC) Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 9F77624677 for ; Tue, 10 Mar 2020 07:45:02 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (1024-bit key) header.d=virtuozzo.com header.i=@virtuozzo.com header.b="eWZ2LNk/" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 9F77624677 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=virtuozzo.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=xen-devel-bounces@lists.xenproject.org Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.89) (envelope-from ) id 1jBZZ1-0003vF-Im; Tue, 10 Mar 2020 07:44:31 +0000 Received: from us1-rack-iad1.inumbo.com ([172.99.69.81]) by lists.xenproject.org with esmtp (Exim 4.89) (envelope-from ) id 1jBZZ0-0003vA-Ua for xen-devel@lists.xenproject.org; Tue, 10 Mar 2020 07:44:30 +0000 X-Inumbo-ID: f8107be4-62a2-11ea-b383-bc764e2007e4 Received: from EUR05-DB8-obe.outbound.protection.outlook.com (unknown [2a01:111:f400:7e1a::706]) by us1-rack-iad1.inumbo.com (Halon) with ESMTPS id f8107be4-62a2-11ea-b383-bc764e2007e4; Tue, 10 Mar 2020 07:44:27 +0000 (UTC) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=MqAxZTvasyOnFZ1VNP/qmTYzwQoXEkwr/R6Y8AU1/nEdGup6IZqMDv6WvT+GM2b5r+4XHB97aNvxjCdMHHiAYSi9dfnKk5iYhHsFN+lG2jBi7BgGRuJfYsuCX77zBMQdnbVibku9tbeQZK3hiwC325PK6eIniE5iCAFGwwmD82vtPkdtL2gejDNidLRkRsDHdAShrnlWle7wVvBoQ7lcrgwedbU2CVCmhDZbnp7JGRFGBM6fG9CPI4xg0sG9yArSbVHduKAloi+VO7c5w0yNLMvhV3SJ9piVDMbvJo2l1KUjgIuYh7vTowJt3pX1Afm8sYGPs7pH9rN2YVhEGoOybA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=D1DArs3hULPds8mFTUJzEMnW6wW5lnk6t0D8MYKCJYI=; b=kUWfvSh+INsJcBCgdVu5WdTtkAKjq4lhDk4VeJ/o2WMhOkmBSpslFoHD89IQ9xnBOy0yW0JuXKLC1nav7MbYMubb37wMiX1TOfMVagJDEk3affEZMGV5WBp+1eT88inPdaWV9aSmRJVtd/KX0lD62mbrqvVuYv2XMFWb+NnCapL9XCyfFkol8mIMms4VMEaGWxOoj1fJOlAShswRoQIEaMMiFiLtj3DHWjWtVckQPKQxkR192EhUZKGwhCBJyRdeMeNy5+hRmvrOHisrfmXFJPFjhd9gV7Sl1m0t4/LZrGnZj0mjyr48BUq0lRiVifMNFaPC9HAPIbXlcimrXNeRQg== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=virtuozzo.com; dmarc=pass action=none header.from=virtuozzo.com; dkim=pass header.d=virtuozzo.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=virtuozzo.com; s=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=D1DArs3hULPds8mFTUJzEMnW6wW5lnk6t0D8MYKCJYI=; b=eWZ2LNk/xCnm7AV5rFQ/RK4+MiVb05eOdvf7ZlE63xyQfwCA3++9KjApUKGjJYTzB9HYJW2+ZskyHeM13HU7QsKHNn8Ajo6IxayYBwRCEyS9fEstPcr1WcGZijLaogsUgzeqcnPnGhZQ4B+h/opljBe/sNqzbhMIv6tLfoIbJFw= Authentication-Results: spf=none (sender IP is ) smtp.mailfrom=vsementsov@virtuozzo.com; Received: from AM6PR08MB4423.eurprd08.prod.outlook.com (20.179.7.140) by AM6PR08MB5206.eurprd08.prod.outlook.com (10.255.122.18) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.2793.16; Tue, 10 Mar 2020 07:44:25 +0000 Received: from AM6PR08MB4423.eurprd08.prod.outlook.com ([fe80::e05a:63af:818c:b664]) by AM6PR08MB4423.eurprd08.prod.outlook.com ([fe80::e05a:63af:818c:b664%4]) with mapi id 15.20.2793.018; Tue, 10 Mar 2020 07:44:25 +0000 To: Markus Armbruster References: <20200306051536.27803-1-vsementsov@virtuozzo.com> <20200306051536.27803-3-vsementsov@virtuozzo.com> <87lfo997hs.fsf@dusky.pond.sub.org> From: Vladimir Sementsov-Ogievskiy X-Tagtoolbar-Keys: D20200310104422742 Message-ID: Date: Tue, 10 Mar 2020 10:44:22 +0300 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Thunderbird/60.2.1 In-Reply-To: <87lfo997hs.fsf@dusky.pond.sub.org> Content-Language: en-US X-ClientProxiedBy: HE1PR07CA0040.eurprd07.prod.outlook.com (2603:10a6:7:66::26) To AM6PR08MB4423.eurprd08.prod.outlook.com (2603:10a6:20b:bf::12) MIME-Version: 1.0 X-MS-Exchange-MessageSentRepresentingType: 1 Received: from [172.16.24.200] (185.231.240.5) by HE1PR07CA0040.eurprd07.prod.outlook.com (2603:10a6:7:66::26) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.2814.6 via Frontend Transport; Tue, 10 Mar 2020 07:44:24 +0000 X-Tagtoolbar-Keys: D20200310104422742 X-Originating-IP: [185.231.240.5] X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: 2b33c834-7f2e-4142-ccde-08d7c4c6db17 X-MS-TrafficTypeDiagnostic: AM6PR08MB5206: X-Microsoft-Antispam-PRVS: X-MS-Oob-TLC-OOBClassifiers: OLM:5516; X-Forefront-PRVS: 033857D0BD X-Forefront-Antispam-Report: SFV:NSPM; SFS:(10019020)(346002)(39850400004)(366004)(376002)(396003)(136003)(189003)(199004)(52116002)(6916009)(86362001)(26005)(8936002)(8676002)(4326008)(81156014)(81166006)(478600001)(5660300002)(54906003)(316002)(2906002)(16576012)(31686004)(7416002)(36756003)(6486002)(66946007)(186003)(16526019)(30864003)(2616005)(956004)(66476007)(66556008)(31696002)(2004002); DIR:OUT; SFP:1102; SCL:1; SRVR:AM6PR08MB5206; H:AM6PR08MB4423.eurprd08.prod.outlook.com; FPR:; SPF:None; LANG:en; PTR:InfoNoRecords; MX:1; A:1; Received-SPF: None (protection.outlook.com: virtuozzo.com does not designate permitted sender hosts) X-MS-Exchange-SenderADCheck: 1 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: Hi6F09e1JOZFVYHcC8mG119n3W4JxX0oq68k+hNnx//zsgjWwv4vofmXkI4Gz7FrtfCB2z19lfUPc4Csurnln5+pVQVF0qoGhoi4S7F45HUs2H/OaboOn/x4EUyvIWZ4CJCVmYDxbh8oKbaykJyuSNGQLTHNQZq5iPW0AT8QZbhrSXecRK1ZaQ9J1ZnDwR/UHTBfJg+O3XbbItUTExajtcFhTxum0pJKtFS2cbds/6qrU4ErpJxhIC5cp9OpMDACgvsPcZzeZ+Q1ecbiEULcmI60kZXBfiDvBaDi6rgL0l0XT1sGP6YwOh1HXK8D3LzZnqrrEK0fIND16MbvjGHr6GtwtmsNmW4/2cHllgu43gxwhfKiUq1DhRAZdkYT3CWLBYOR/nMJhk03LIn4f3NNLWSkmpF98tUUH+s1RC48v+mDdgZ+1EfZHBY7HicD1B1p9b0kQS7TwoVfxQ/WVTKwE4pO9bGp9oYQL6YnNKQBBp0bQ2ilOTUuk9S2Z89S2Wgr2WdSI8xTEqD9xGaivR8EUS3AIh0gEmIg7I2AwfKeADmowFutcyfpwx1CaBlHlXNA X-MS-Exchange-AntiSpam-MessageData: u6zlm/Dh/r8/wGQ9j2v0gox0p4FaGgYL1Vz+cTRZjGES3hTQpxa1f42ucVcc0A28vclLi2QodJPWPIH3foWGbQWtPgBp2qJkRIPvGIvy7oTnQFuaK6f0XzmywkoIoIQOV9sAC6prxRQCenm15f0Izw== X-OriginatorOrg: virtuozzo.com X-MS-Exchange-CrossTenant-Network-Message-Id: 2b33c834-7f2e-4142-ccde-08d7c4c6db17 X-MS-Exchange-CrossTenant-OriginalArrivalTime: 10 Mar 2020 07:44:25.7581 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 0bc7f26d-0264-416e-a6fc-8352af79c58f X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: Q+7KkSU5SH9zuw0C05mAoLt9Gn0xWv1qfEWJRRp/WbsXRjGVR4GuBlXtZQIouNB1hGrbEzBFXFx2OOuqgrCh8AWAeLc/Y6tjVliocxQLZuo= X-MS-Exchange-Transport-CrossTenantHeadersStamped: AM6PR08MB5206 Subject: Re: [Xen-devel] [PATCH v8 02/10] scripts: add coccinelle script to use auto propagated errp X-BeenThere: xen-devel@lists.xenproject.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Cc: Kevin Wolf , Stefano Stabellini , Michael Roth , qemu-block@nongnu.org, Paul Durrant , Laszlo Ersek , Christian Schoenebeck , qemu-devel@nongnu.org, Greg Kurz , Gerd Hoffmann , Stefan Hajnoczi , Anthony Perard , xen-devel@lists.xenproject.org, Max Reitz , =?UTF-8?Q?Philippe_Mathieu-Daud=c3=a9?= , Stefan Berger Content-Transfer-Encoding: base64 Content-Type: text/plain; charset="utf-8"; Format="flowed" Errors-To: xen-devel-bounces@lists.xenproject.org Sender: "Xen-devel" MDkuMDMuMjAyMCAxMjo1NiwgTWFya3VzIEFybWJydXN0ZXIgd3JvdGU6Cj4gU3VnZ2VzdAo+IAo+ ICAgICAgc2NyaXB0czogQ29jY2luZWxsZSBzY3JpcHQgdG8gdXNlIGF1dG8tcHJvcGFnYXRlZCBl cnJwCj4gCj4gb3IKPiAKPiAgICAgIHNjcmlwdHM6IENvY2NpbmVsbGUgc2NyaXB0IHRvIHVzZSBF UlJQX0FVVE9fUFJPUEFHQVRFKCkKPiAKPiBWbGFkaW1pciBTZW1lbnRzb3YtT2dpZXZza2l5IDx2 c2VtZW50c292QHZpcnR1b3p6by5jb20+IHdyaXRlczoKPiAKPj4gU2NyaXB0IGFkZHMgRVJSUF9B VVRPX1BST1BBR0FURSBtYWNybyBpbnZvY2F0aW9uIHdoZXJlIGFwcHJvcHJpYXRlIGFuZAo+PiBk b2VzIGNvcnJlc3BvbmRpbmcgY2hhbmdlcyBpbiBjb2RlIChsb29rIGZvciBkZXRhaWxzIGluCj4+ IGluY2x1ZGUvcWFwaS9lcnJvci5oKQo+Pgo+PiBVc2FnZSBleGFtcGxlOgo+PiBzcGF0Y2ggLS1z cC1maWxlIHNjcmlwdHMvY29jY2luZWxsZS9hdXRvLXByb3BhZ2F0ZWQtZXJycC5jb2NjaSBcCj4+ ICAgLS1tYWNyby1maWxlIHNjcmlwdHMvY29jY2ktbWFjcm8tZmlsZS5oIC0taW4tcGxhY2UgLS1u by1zaG93LWRpZmYgXAo+PiAgIGJsb2NrZGV2LW5iZC5jIHFlbXUtbmJkLmMge2Jsb2NrL25iZCos bmJkLyosaW5jbHVkZS9ibG9jay9uYmQqfS5baGNdCj4gCj4gU3VnZ2VzdCBGSUxFUy4uLiBpbnN0 ZWFkIG9mIGEgc3BlY2lmaWMgc2V0IG9mIGZpbGVzLgo+IAo+PiBTaWduZWQtb2ZmLWJ5OiBWbGFk aW1pciBTZW1lbnRzb3YtT2dpZXZza2l5IDx2c2VtZW50c292QHZpcnR1b3p6by5jb20+Cj4+IC0t LQo+Pgo+PiBDYzogRXJpYyBCbGFrZSA8ZWJsYWtlQHJlZGhhdC5jb20+Cj4+IENjOiBLZXZpbiBX b2xmIDxrd29sZkByZWRoYXQuY29tPgo+PiBDYzogTWF4IFJlaXR6IDxtcmVpdHpAcmVkaGF0LmNv bT4KPj4gQ2M6IEdyZWcgS3VyeiA8Z3JvdWdAa2FvZC5vcmc+Cj4+IENjOiBDaHJpc3RpYW4gU2No b2VuZWJlY2sgPHFlbXVfb3NzQGNydWRlYnl0ZS5jb20+Cj4+IENjOiBTdGVmYW5vIFN0YWJlbGxp bmkgPHNzdGFiZWxsaW5pQGtlcm5lbC5vcmc+Cj4+IENjOiBBbnRob255IFBlcmFyZCA8YW50aG9u eS5wZXJhcmRAY2l0cml4LmNvbT4KPj4gQ2M6IFBhdWwgRHVycmFudCA8cGF1bEB4ZW4ub3JnPgo+ PiBDYzogU3RlZmFuIEhham5vY3ppIDxzdGVmYW5oYUByZWRoYXQuY29tPgo+PiBDYzogIlBoaWxp cHBlIE1hdGhpZXUtRGF1ZMOpIiA8cGhpbG1kQHJlZGhhdC5jb20+Cj4+IENjOiBMYXN6bG8gRXJz ZWsgPGxlcnNla0ByZWRoYXQuY29tPgo+PiBDYzogR2VyZCBIb2ZmbWFubiA8a3JheGVsQHJlZGhh dC5jb20+Cj4+IENjOiBTdGVmYW4gQmVyZ2VyIDxzdGVmYW5iQGxpbnV4LmlibS5jb20+Cj4+IENj OiBNYXJrdXMgQXJtYnJ1c3RlciA8YXJtYnJ1QHJlZGhhdC5jb20+Cj4+IENjOiBNaWNoYWVsIFJv dGggPG1kcm90aEBsaW51eC52bmV0LmlibS5jb20+Cj4+IENjOiBxZW11LWJsb2NrQG5vbmdudS5v cmcKPj4gQ2M6IHFlbXUtZGV2ZWxAbm9uZ251Lm9yZwo+PiBDYzogeGVuLWRldmVsQGxpc3RzLnhl bnByb2plY3Qub3JnCj4+Cj4+ICAgaW5jbHVkZS9xYXBpL2Vycm9yLmggICAgICAgICAgICAgICAg ICAgICAgICAgIHwgICAzICsKPj4gICBzY3JpcHRzL2NvY2NpbmVsbGUvYXV0by1wcm9wYWdhdGVk LWVycnAuY29jY2kgfCAyMzEgKysrKysrKysrKysrKysrKysrCj4+ICAgMiBmaWxlcyBjaGFuZ2Vk LCAyMzQgaW5zZXJ0aW9ucygrKQo+PiAgIGNyZWF0ZSBtb2RlIDEwMDY0NCBzY3JpcHRzL2NvY2Np bmVsbGUvYXV0by1wcm9wYWdhdGVkLWVycnAuY29jY2kKPj4KPj4gZGlmZiAtLWdpdCBhL2luY2x1 ZGUvcWFwaS9lcnJvci5oIGIvaW5jbHVkZS9xYXBpL2Vycm9yLmgKPj4gaW5kZXggYmI5YmNmMDJm Yi4uZmJmYzZmMWMwYiAxMDA2NDQKPj4gLS0tIGEvaW5jbHVkZS9xYXBpL2Vycm9yLmgKPj4gKysr IGIvaW5jbHVkZS9xYXBpL2Vycm9yLmgKPj4gQEAgLTIxMSw2ICsyMTEsOSBAQAo+PiAgICAqICAg ICAgICAgfQo+PiAgICAqICAgICAgICAgLi4uCj4+ICAgICogICAgIH0KPj4gKyAqCj4+ICsgKiBG b3IgbWFzcyBjb252ZXJzaW9uIHVzZSBzY3JpcHQKPiAKPiBtYXNzLWNvbnZlcnNpb24gKHdlJ3Jl IG5vdCBjb252ZXJ0aW5nIG1hc3MsIHdlJ3JlIGNvbnZlcnRpbmcgZW4gbWFzc2UpCj4gCj4+ICsg KiAgIHNjcmlwdHMvY29jY2luZWxsZS9hdXRvLXByb3BhZ2F0ZWQtZXJycC5jb2NjaQo+PiAgICAq Lwo+PiAgIAo+PiAgICNpZm5kZWYgRVJST1JfSAo+PiBkaWZmIC0tZ2l0IGEvc2NyaXB0cy9jb2Nj aW5lbGxlL2F1dG8tcHJvcGFnYXRlZC1lcnJwLmNvY2NpIGIvc2NyaXB0cy9jb2NjaW5lbGxlL2F1 dG8tcHJvcGFnYXRlZC1lcnJwLmNvY2NpCj4+IG5ldyBmaWxlIG1vZGUgMTAwNjQ0Cj4+IGluZGV4 IDAwMDAwMDAwMDAuLmJmZjI3NGJkNmQKPj4gLS0tIC9kZXYvbnVsbAo+PiArKysgYi9zY3JpcHRz L2NvY2NpbmVsbGUvYXV0by1wcm9wYWdhdGVkLWVycnAuY29jY2kKPiAKPiBQcmVmYWNlIHRvIG15 IHJldmlldyBvZiB0aGlzIHNjcmlwdDogbWF5IGFpbSBpc24ndCB0byBtYWtlIGl0Cj4gYnVsbGV0 LXByb29mLiAgSSB3YW50IHRvICgxKSBtYWtlIGl0IGdvb2QgZW5vdWdoIChleHBsYWluZWQgaW4g YQo+IGppZmZpZSksIGFuZCAoMikgYXV0b21hdGljYWxseSBpZGVudGlmeSB0aGUgc3BvdHMgd2hl cmUgaXQgc3RpbGwgaXNuJ3QKPiBvYnZpb3VzbHkgc2FmZSBmb3IgbWFudWFsIHJldmlldy4KPiAK PiBUaGUgbGF0dGVyIG1heSBpbnZvbHZlIGFkZGl0aW9uYWwgc2NyaXB0aW5nLiAgVGhhdCdzIG9r YXkuCj4gCj4gVGhlIHNjcmlwdCBpcyBnb29kIGVub3VnaCB3aGVuIHRoZSBudW1iZXIgb2YgcG9z c2libHkgdW5zYWZlIHNwb3RzIGlzCj4gbG93IGVub3VnaCBmb3IgY2FyZWZ1bCBtYW51YWwgcmV2 aWV3Lgo+IAo+IFdoZW4gSSBhc2sgZm9yIGltcHJvdmVtZW50cyB0aGF0LCBpbiB5b3VyIG9waW5p b24sIGdvIGJleW9uZCAiZ29vZAo+IGVub3VnaCIsIHBsZWFzZSBwdXNoIGJhY2suICBJJ20gc3Vy ZSB3ZSBjYW4gd29yayBpdCBvdXQgdG9nZXRoZXIuCj4gCj4+IEBAIC0wLDAgKzEsMjMxIEBACj4+ ICsvLyBVc2UgRVJSUF9BVVRPX1BST1BBR0FURSAoc2VlIGluY2x1ZGUvcWFwaS9lcnJvci5oKQo+ PiArLy8KPj4gKy8vIENvcHlyaWdodCAoYykgMjAyMCBWaXJ0dW96em8gSW50ZXJuYXRpb25hbCBH bWJILgo+PiArLy8KPj4gKy8vIFRoaXMgcHJvZ3JhbSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2Fu IHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5Cj4+ICsvLyBpdCB1bmRlciB0aGUgdGVybXMg b2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieQo+PiArLy8g dGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyIHZlcnNpb24gMiBvZiB0aGUgTGlj ZW5zZSwgb3IKPj4gKy8vIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uCj4+ICsv Lwo+PiArLy8gVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQg d2lsbCBiZSB1c2VmdWwsCj4+ICsvLyBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQg ZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZgo+PiArLy8gTUVSQ0hBTlRBQklMSVRZIG9yIEZJ VE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZQo+PiArLy8gR05VIEdlbmVy YWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy4KPj4gKy8vCj4+ICsvLyBZb3Ugc2hv dWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5z ZQo+PiArLy8gYWxvbmcgd2l0aCB0aGlzIHByb2dyYW0uICBJZiBub3QsIHNlZSA8aHR0cDovL3d3 dy5nbnUub3JnL2xpY2Vuc2VzLz4uCj4+ICsvLwo+PiArLy8gVXNhZ2UgZXhhbXBsZToKPj4gKy8v IHNwYXRjaCAtLXNwLWZpbGUgc2NyaXB0cy9jb2NjaW5lbGxlL2F1dG8tcHJvcGFnYXRlZC1lcnJw LmNvY2NpIFwKPj4gKy8vICAtLW1hY3JvLWZpbGUgc2NyaXB0cy9jb2NjaS1tYWNyby1maWxlLmgg LS1pbi1wbGFjZSAtLW5vLXNob3ctZGlmZiBcCj4+ICsvLyAgLS1tYXgtd2lkdGggODAgYmxvY2tk ZXYtbmJkLmMgcWVtdS1uYmQuYyBcCj4gCj4gWW91IGhhdmUgLS1tYXgtd2lkdGggODAgaGVyZSwg YnV0IG5vdCBpbiB0aGUgY29tbWl0IG1lc3NhZ2UuICBEZWZhdWx0Cj4gc2VlbXMgdG8gYmUgNzgu ICBBbnkgcGFydGljdWxhciByZWFzb24gdG8gY2hhbmdlIGl0IHRvIDgwPwoKSG1tLiBBcyBJIHJl bWVtYmVyLCB3aXRob3V0IHRoaXMgcGFyYW1ldGVyLCByZWluZGVudGluZyBkb2Vzbid0IHdvcmsg Y29ycmVjdGx5LgpTbywgSSdtIE9LIHdpdGggIi0tbWF4LXdpZHRoIDc4IiwgYnV0IEkgZG91YnQg dGhhdCBpdCB3aWxsIHdvcmsgd2l0aG91dCBhIHBhcmFtZXRlci4KU3RpbGwsIG1heSBiZSBJJ20g d3JvbmcsIHdlIGNhbiBjaGVjayBpdC4KCj4gCj4+ICsvLyAge2Jsb2NrL25iZCosbmJkLyosaW5j bHVkZS9ibG9jay9uYmQqfS5baGNdCj4+ICsKPj4gKy8vIFN3aXRjaCB1bnVzdWFsIChFcnJvciAq KikgcGFyYW1ldGVyIG5hbWVzIHRvIGVycnAKPiAKPiBMZXQncyBkcm9wIHRoZSBwYXJlbnRoZXNp cyBhcm91bmQgRXJyb3IgKioKPiAKPj4gKy8vICh0aGlzIGlzIG5lY2Vzc2FyeSB0byB1c2UgRVJS UF9BVVRPX1BST1BBR0FURSkuCj4gCj4gUGVyaGFwcyBFUlJQX0FVVE9fUFJPUEFHQVRFKCkgc2hv dWxkIGJlIEVSUlBfQVVUT19QUk9QQUdBVEUoZXJycCkgdG8KPiBtYWtlIHRoZSBmYWN0IHdlJ3Jl IG1lc3Npbmcgd2l0aCBAZXJycCBtb3JlIG9idmlvdXMuICBUb28gbGF0ZTsgSQo+IHNob3VsZG4n dCByb2NrIHRoZSBib2F0IHRoYXQgbXVjaCBub3cuCj4gCj4+ICsvLwo+PiArLy8gRGlzYWJsZSBv cHRpb25hbF9xdWFsaWZpZXIgdG8gc2tpcCBmdW5jdGlvbnMgd2l0aCAiRXJyb3IgKmNvbnN0ICpl cnJwIgo+PiArLy8gcGFyYW1ldGVyLgo+PiArLy8KPj4gKy8vIFNraXAgZnVuY3Rpb25zIHdpdGgg ImFzc2VydChfZXJycCAmJiAqX2VycnApIiBzdGF0ZW1lbnQsIGFzIHRoZXkgaGF2ZQo+PiArLy8g bm9uIGdlbmVyaWMgc2VtYW50aWNzIGFuZCBtYXkgaGF2ZSB1bnVzdWFsIEVycm9yICoqIGFyZ3Vt ZW50IG5hbWUgZm9yIHB1cnBvc2UKPiAKPiBub24tZ2VuZXJpYwo+IAo+IGZvciBhIHB1cnBvc2UK PiAKPiBXcmFwIGNvbW1lbnQgbGluZXMgYXJvdW5kIGNvbHVtbiA3MCwgcGxlYXNlLiAgSXQncyBl YXNpZXIgdG8gcmVhZC4KPiAKPiBNYXliZQo+IAo+ICAgICAvLyBTa2lwIGZ1bmN0aW9ucyB3aXRo ICJhc3NlcnQoX2VycnAgJiYgKl9lcnJwKSIgc3RhdGVtZW50LCBiZWNhdXNlIHRoYXQKPiAgICAg Ly8gc2lnbmFscyB1bnVzdWFsIHNlbWFudGljcywgYW5kIHRoZSBwYXJhbWV0ZXIgbmFtZSBtYXkg d2VsbCBzZXJ2ZSBhCj4gICAgIC8vIHB1cnBvc2UuCgpTb3VuZHMgZ29vZC4KCj4gCj4+ICsvLyAo bGlrZSBuYmRfaXRlcl9jaGFubmVsX2Vycm9yKCkpLgo+PiArLy8KPj4gKy8vIFNraXAgdXRpbC9l cnJvci5jIHRvIG5vdCB0b3VjaCwgZm9yIGV4YW1wbGUsIGVycm9yX3Byb3BhZ2F0ZSBhbmQKPj4g Ky8vIGVycm9yX3Byb3BhZ2F0ZV9wcmVwZW5kKCkuCj4gCj4gZXJyb3JfcHJvcGFnYXRlKCkKPiAK PiBJIG11Y2ggYXBwcmVjaWF0ZSB5b3VyIG1ldGljdWxvdXMgZXhwbGFuYXRpb24gb2Ygd2hhdCB5 b3Ugc2tpcCBhbmQgd2h5Lgo+IAo+PiArQCBkZXBlbmRzIG9uICEoZmlsZSBpbiAidXRpbC9lcnJv ci5jIikgZGlzYWJsZSBvcHRpb25hbF9xdWFsaWZpZXJACj4+ICtpZGVudGlmaWVyIGZuOwo+PiAr aWRlbnRpZmllciBfZXJycCAhPSBlcnJwOwo+PiArQEAKPj4gKwo+PiArIGZuKC4uLiwKPj4gKy0g ICBFcnJvciAqKl9lcnJwCj4+ICsrICAgRXJyb3IgKiplcnJwCj4+ICsgICAgLC4uLikKPj4gKyB7 Cj4+ICsoCj4+ICsgICAgIC4uLiB3aGVuICE9IGFzc2VydChfZXJycCAmJiAqX2VycnApCj4+ICsm Cj4+ICsgICAgIDwuLi4KPj4gKy0gICAgX2VycnAKPj4gKysgICAgZXJycAo+PiArICAgICAuLi4+ Cj4+ICspCj4+ICsgfQo+IAo+IFRoaXMgcnVsZSBpcyByZXF1aXJlZCB0byBtYWtlIHRoZSBhY3R1 YWwgdHJhbnNmb3JtYXRpb25zIChiZWxvdykgd29yawo+IGV2ZW4gZm9yIHBhcmFtZXRlcnMgd2l0 aCBuYW1lcyBvdGhlciB0aGFuIEBlcnJwLiAgSSBiZWxpZXZlIGl0J3Mgbm90Cj4gdXNlZCBpbiB0 aGlzIHNlcmllcy4gIEluIGZhY3QsIEkgY2FuJ3Qgc2VlIGEgdXNlIGZvciBpdCBpbiB0aGUgZW50 aXJlCj4gdHJlZSByaWdodCBub3cuICBPa2F5IGFueXdheS4KPiAKPj4gKwo+PiArLy8gQWRkIGlu dm9jYXRpb24gb2YgRVJSUF9BVVRPX1BST1BBR0FURSB0byBlcnJwLWZ1bmN0aW9ucyB3aGVyZSBu ZWNlc3NhcnkKPj4gKy8vCj4+ICsvLyBOb3RlLCB0aGF0IHdpdGhvdXQgIndoZW4gYW55IiBmaW5h bCAiLi4uIiBtYXkgbm90IHdhbnQgdG8gbWFjaCBzb21ldGhpbmcKPiAKPiBzL2ZpbmFsICIuLi4i IG1heSBub3QgbWFjaC90aGUgZmluYWwgIi4uLiIgZG9lcyBub3QgbWF0Y2gvCj4gCj4+ICsvLyBt YXRjaGVkIGJ5IHByZXZpb3VzIHBhdHRlcm4sIGkuZS4gdGhlIHJ1bGUgd2lsbCBub3QgbWF0Y2gg ZG91YmxlCj4+ICsvLyBlcnJvcl9wcmVwZW5kIGluIGNvbnRyb2wgZmxvdyBsaWtlIGluIHZmaW9f c2V0X2lycV9zaWduYWxpbmcoKS4KPiAKPiBDYW4ndCBzYXkgSSBmdWxseSB1bmRlcnN0YW5kIENv Y2NpbmVsbGUgdGhlcmUuICBJIGZpZ3VyZSB5b3UgY2FtZSB0bwo+IHRoaXMga25vd2xlZGdlIHRo ZSBoYXJkIHdheS4KCkl0J3MgZm9sbG93cyBmcm9tIHNtcGwgZ3JhbW1hciBkb2N1bWVudDoKCiJJ bXBsaWNpdGx5LCDigJwuLi7igJ0gbWF0Y2hlcyB0aGUgc2hvcnRlc3QgcGF0aCBiZXR3ZWVuIHNv bWV0aGluZyB0aGF0IG1hdGNoZXMgdGhlIHBhdHRlcm4gYmVmb3JlIHRoZSBkb3RzIChvciB0aGUg YmVnaW5uaW5nIG9mIHRoZSBmdW5jdGlvbiwgaWYgdGhlcmUgaXMgbm90aGluZyBiZWZvcmUgdGhl IGRvdHMpIGFuZCBzb21ldGhpbmcgdGhhdCBtYXRjaGVzIHRoZSBwYXR0ZXJuIGFmdGVyIHRoZSBk b3RzIChvciB0aGUgZW5kIG9mIHRoZSBmdW5jdGlvbiwgaWYgdGhlcmUgaXMgbm90aGluZyBhZnRl ciB0aGUgZG90cykuIgouLi4KIl93aGVuIGFueV8gcmVtb3ZlcyB0aGUgYWZvcmVtZW50aW9uZWQg Y29uc3RyYWludCB0aGF0IOKAnC4uLuKAnSBtYXRjaGVzIHRoZSBzaG9ydGVzdCBwYXRoIgoKPiAK Pj4gKy8vCj4+ICsvLyBOb3RlLCAiZXhpc3RzIiBzYXlzIHRoYXQgd2Ugd2FudCBhcHBseSBydWxl IGV2ZW4gaWYgaXQgbWF0Y2hlcyBub3Qgb24KPj4gKy8vIGFsbCBwb3NzaWJsZSBjb250cm9sIGZs b3dzIChvdGhlcndpc2UsIGl0IHdpbGwgbm90IG1hdGNoIHN0YW5kYXJkIHBhdHRlcm4KPj4gKy8v IHdoZW4gZXJyb3JfcHJvcGFnYXRlKCkgY2FsbCBpcyBpbiBpZiBicmFuY2gpLgo+IAo+IExlYXJu ZWQgc29tZXRoaW5nIG5ldy4gIEV4YW1wbGU6IGt2bV9zZXRfa3ZtX3NoYWRvd19tZW0oKS4KPiAK PiBTcGVsbGluZyBpdCAiZXhpc3RzIGRpc2FibGUgb3B0aW9uYWxfcXVhbGlmaWVyIiB3b3VsZCBh dm9pZCBnaXZpbmcKPiByZWFkZXJzIHRoZSBpZGVhIHdlJ3JlIGRpc2FibGluZyAiZXhpc3RzIiwg YnV0IENvY2NpbmVsbGUgZG9lc24ndCBsZXQKPiB1cy4gIE9oIHdlbGwuCj4gCj4+ICtAIGRpc2Fi bGUgb3B0aW9uYWxfcXVhbGlmaWVyIGV4aXN0c0AKPj4gK2lkZW50aWZpZXIgZm4sIGxvY2FsX2Vy ciwgZXJycDsKPiAKPiBJIGJlbGlldmUgdGhpcyBjYXVzZXMKPiAKPiAgICAgIHdhcm5pbmc6IGxp bmUgOTg6IGVycnAsIHByZXZpb3VzbHkgZGVjbGFyZWQgYXMgYSBtZXRhdmFyaWFibGUsIGlzIHVz ZWQgYXMgYW4gaWRlbnRpZmllcgo+ICAgICAgd2FybmluZzogbGluZSAxMDQ6IGVycnAsIHByZXZp b3VzbHkgZGVjbGFyZWQgYXMgYSBtZXRhdmFyaWFibGUsIGlzIHVzZWQgYXMgYW4gaWRlbnRpZmll cgo+ICAgICAgd2FybmluZzogbGluZSAxMDY6IGVycnAsIHByZXZpb3VzbHkgZGVjbGFyZWQgYXMg YSBtZXRhdmFyaWFibGUsIGlzIHVzZWQgYXMgYW4gaWRlbnRpZmllcgo+ICAgICAgd2FybmluZzog bGluZSAxMzE6IGVycnAsIHByZXZpb3VzbHkgZGVjbGFyZWQgYXMgYSBtZXRhdmFyaWFibGUsIGlz IHVzZWQgYXMgYW4gaWRlbnRpZmllcgo+ICAgICAgd2FybmluZzogbGluZSAxOTI6IGVycnAsIHBy ZXZpb3VzbHkgZGVjbGFyZWQgYXMgYSBtZXRhdmFyaWFibGUsIGlzIHVzZWQgYXMgYW4gaWRlbnRp Zmllcgo+ICAgICAgd2FybmluZzogbGluZSAxOTU6IGVycnAsIHByZXZpb3VzbHkgZGVjbGFyZWQg YXMgYSBtZXRhdmFyaWFibGUsIGlzIHVzZWQgYXMgYW4gaWRlbnRpZmllcgo+ICAgICAgd2Fybmlu ZzogbGluZSAyMjg6IGVycnAsIHByZXZpb3VzbHkgZGVjbGFyZWQgYXMgYSBtZXRhdmFyaWFibGUs IGlzIHVzZWQgYXMgYW4gaWRlbnRpZmllcgo+IAo+IE1ha2luZyBAZXJycCBzeW1ib2wgaW5zdGVh ZCBvZiBpZGVudGlmaWVyIHNob3VsZCBmaXggdGhpcy4KCkhtbSwgSSBkaWRuJ3Qgc2VlIHRoZXNl IHdhcm5pbmdzLi4gQnV0IHllcywgaXQgc2hvdWxkIGJlIHN5bWJvbC4KCj4gCj4+ICtAQAo+PiAr Cj4+ICsgZm4oLi4uLCBFcnJvciAqKmVycnAsIC4uLikKPj4gKyB7Cj4+ICsrICAgRVJSUF9BVVRP X1BST1BBR0FURSgpOwo+PiArICAgIC4uLiAgd2hlbiAhPSBFUlJQX0FVVE9fUFJPUEFHQVRFKCk7 Cj4+ICsoCj4+ICsgICAgZXJyb3JfYXBwZW5kX2hpbnQoZXJycCwgLi4uKTsKPj4gK3wKPj4gKyAg ICBlcnJvcl9wcmVwZW5kKGVycnAsIC4uLik7Cj4+ICt8Cj4+ICsgICAgZXJyb3JfdnByZXBlbmQo ZXJycCwgLi4uKTsKPj4gK3wKPj4gKyAgICBFcnJvciAqbG9jYWxfZXJyID0gTlVMTDsKPj4gKyAg ICAuLi4KPj4gKygKPj4gKyAgICBlcnJvcl9wcm9wYWdhdGVfcHJlcGVuZChlcnJwLCBsb2NhbF9l cnIsIC4uLik7Cj4+ICt8Cj4+ICsgICAgZXJyb3JfcHJvcGFnYXRlKGVycnAsIGxvY2FsX2Vycik7 Cj4+ICspCj4+ICspCj4+ICsgICAgLi4uIHdoZW4gYW55Cj4+ICsgfQo+PiArCj4+ICsKPj4gKy8v IE1hdGNoIHNjZW5hcmlvcyB3aXRoIHByb3BhZ2F0aW9uIG9mIGxvY2FsIGVycm9yIHRvIGVycnAu Cj4+ICtAcnVsZTEgZGlzYWJsZSBvcHRpb25hbF9xdWFsaWZpZXIgZXhpc3RzQAo+PiAraWRlbnRp ZmllciBmbiwgbG9jYWxfZXJyOwo+PiArc3ltYm9sIGVycnA7Cj4+ICtAQAo+PiArCj4+ICsgZm4o Li4uLCBFcnJvciAqKmVycnAsIC4uLikKPj4gKyB7Cj4+ICsgICAgIC4uLgo+PiArICAgICBFcnJv ciAqbG9jYWxfZXJyID0gTlVMTDsKPj4gKyAgICAgLi4uCj4+ICsoCj4+ICsgICAgZXJyb3JfcHJv cGFnYXRlX3ByZXBlbmQoZXJycCwgbG9jYWxfZXJyLCAuLi4pOwo+PiArfAo+PiArICAgIGVycm9y X3Byb3BhZ2F0ZShlcnJwLCBsb2NhbF9lcnIpOwo+PiArKQo+IAo+IEluZGVudGF0aW9uIG9mZiBi eSBvbmUuCj4gCj4+ICsgICAgIC4uLgo+PiArIH0KPj4gKwo+PiArLy8gQ29udmVydCBzcGVjaWFs IGNhc2Ugd2l0aCBnb3RvIGluIHNlcGFyYXRlLgo+IAo+IHMvaW4gc2VwYXJhdGUvc2VwYXJhdGVs eS8KPiAKPj4gKy8vIFdlIGNhbiBwcm9iYWJseSBtZXJnZSB0aGlzIGludG8gdGhlIGZvbGxvd2lu ZyBodW5rIHdpdGggaGVscCBvZiAoIHwgKQo+PiArLy8gb3BlcmF0b3IsIGJ1dCBpdCBzaWduaWZp Y2FudGx5IHJlZHVjZSBwZXJmb3JtYW5jZSBvbiBibG9jay5jIHBhcnNpbmcgKG9yIGl0Cj4gCj4g cy9yZWR1Y2UvcmVkdWNlcy8KPiAKPj4gKy8vIGhhbmdzLCBJIGRvbid0IGtub3cpCj4gCj4gU291 bmRzIGxpa2UgeW91IHRyaWVkIHRvIG1lcmdlIHRoaXMgaW50byB0aGUgZm9sbG93aW5nIGh1bmss IGJ1dCB0aGVuCj4gc3BhdGNoIHRvb2sgc28gbG9uZyBvbiBibG9jay5jIHRoYXQgeW91IGtpbGxl ZCBpdC4gIENvcnJlY3Q/CgpZZXMuCgo+IAo+PiArLy8KPj4gKy8vIE5vdGUgaW50ZXJlc3Rpbmcg dGhpbmc6IGlmIHdlIGRvbid0IGRvIGl0IGhlcmUsIGFuZCB0cnkgdG8gZml4dXAgIm91dDogfSIK Pj4gKy8vIHRoaW5ncyBsYXRlciBhZnRlciBhbGwgdHJhbnNmb3JtYXRpb25zICh0aGUgcnVsZSB3 aWxsIGJlIHRoZSBzYW1lLCBqdXN0Cj4+ICsvLyB3aXRob3V0IGVycm9yX3Byb3BhZ2F0ZSgpIGNh bGwpLCBjb2NjaW5lbGxlIGZhaWxzIHRvIG1hdGNoIHRoaXMgIm91dDogfSIuCj4gCj4gV2VpcmQs IGJ1dCBub3Qgd29ydGggZnVydGhlciBpbnZlc3RpZ2F0aW9uLgoKSXQgcGFydGlhbGx5IG1hdGNo IHRvIHRoZSBpZGVhIHdoaWNoIEkgc2F3IHNvbWV3aGVyZSBpbiBjb2NjaW5lbGxlIGRvY3VtZW50 YXRpb24sCnRoYXQgY29jY2luZWxsZSBjb252ZXJ0cyBjb3JyZWN0IEMgY29kZSB0byBjb3JyZWN0 IEMgY29kZS4gIm91dDogfSIgaXMgYW4gZXhhbXBsZQpvZiBpbmNvcnJlY3QsIGltcG9zc2libGUg Y29kZSBmbG93LCBhbmQgY29jY2luZWxsZSBjYW4ndCB3b3JrIHdpdGggaXQuLi4gQnV0IGl0J3MK anVzdCBhIHRob3VnaHQuCgo+IAo+PiArQEAKPj4gK2lkZW50aWZpZXIgcnVsZTEuZm4sIHJ1bGUx LmxvY2FsX2Vyciwgb3V0Owo+PiArc3ltYm9sIGVycnA7Cj4+ICtAQAo+PiArCj4+ICsgZm4oLi4u KQo+PiArIHsKPj4gKyAgICAgPC4uLgo+PiArLSAgICBnb3RvIG91dDsKPj4gKysgICAgcmV0dXJu Owo+PiArICAgICAuLi4+Cj4+ICstIG91dDoKPj4gKy0gICAgZXJyb3JfcHJvcGFnYXRlKGVycnAs IGxvY2FsX2Vycik7Cj4gCj4gWW91IG5lZ2xlY3QgdG8gbWF0Y2ggZXJyb3JfcHJvcGFnYXRlX3By ZXBlbmQoKS4gIE9rYXksIGJlY2F1c2UgKDEpIHRoYXQKPiBwYXR0ZXJuIGRvZXNuJ3Qgb2NjdXIg aW4gdGhlIHRyZWUgcmlnaHQgbm93LCBhbmQgKDIpIGlmIGl0IGdldHMgYWRkZWQsCj4gZ2NjIHdp bGwgY29tcGxhaW4uCgpObywgYmVjYXVzZSBpdCBzaG91bGQgbm90IHJlbW92ZWQuIGVycm9yX3By b3BhZ2F0ZV9wcmVwZW5kIHNob3VsZCBiZSBjb252ZXJ0ZWQKdG8gcHJlcGVuZCwgbm90IHJlbW92 ZWQuIFNvLCBjb3JyZXNwb25kaW5nIGdvdG9zIHNob3VsZCBub3QgYmUgcmVtb3ZlZCBhcyB3ZWxs LgoKPiAKPj4gKyB9Cj4+ICsKPj4gKy8vIENvbnZlcnQgbW9zdCBvZiBsb2NhbF9lcnIgcmVsYXRl ZCBzdGFmZi4KPiAKPiBzL3N0YWZmL3N0dWZmLwo+IAo+PiArLy8KPj4gKy8vIE5vdGUsIHRoYXQg d2UgdXBkYXRlIGV2ZXJ5dGhpbmcgcmVsYXRlZCB0byBtYXRjaGVkIGJ5IHJ1bGUxIGZ1bmN0aW9u IG5hbWUKPj4gKy8vIGFuZCBsb2NhbF9lcnIgbmFtZS4gV2UgbWF5IG1hdGNoIHNvbWV0aGluZyBu b3QgcmVsYXRlZCB0byB0aGUgcGF0dGVybgo+PiArLy8gbWF0Y2hlZCBieSBydWxlMS4gRm9yIGV4 YW1wbGUsIGxvY2FsX2VyciBtYXkgYmUgZGVmaW5lZCB3aXRoIHRoZSBzYW1lIG5hbWUKPj4gKy8v IGluIGRpZmZlcmVudCBibG9ja3MgaW5zaWRlIG9uZSBmdW5jdGlvbiwgYW5kIGluIG9uZSBibG9j ayBmb2xsb3cgdGhlCj4+ICsvLyBwcm9wYWdhdGlvbiBwYXR0ZXJuIGFuZCBpbiBvdGhlciBibG9j ayBkb2Vzbid0LiBPciB3ZSBtYXkgaGF2ZSBzZXZlcmFsCj4+ICsvLyBmdW5jdGlvbnMgd2l0aCB0 aGUgc2FtZSBuYW1lIChmb3IgZGlmZmVyZW50IGNvbmZpZ3VyYXRpb25zKS4KPiAKPiBDb250ZXh0 OiBydWxlMSBtYXRjaGVzIGZ1bmN0aW9ucyB0aGF0IGhhdmUgYWxsIHRocmVlIG9mCj4gCj4gKiBh biBFcnJvciAqKmVycnAgcGFyYW1ldGVyCj4gCj4gKiBhbiBFcnJvciAqbG9jYWxfZXJyID0gTlVM TCB2YXJpYWJsZSBkZWNsYXJhdGlvbgo+IAo+ICogYW4gZXJyb3JfcHJvcGFnYXRlKGVycnAsIGxv Y2FsX2Vycikgb3IgZXJyb3JfcHJvcGFnYXRlX3ByZXBlbmQoZXJycCwKPiAgICBsb2NhbF9lcnIs IC4uLikgZXhwcmVzc2lvbiwgd2hlcmUgQGVycnAgaXMgdGhlIHBhcmFtZXRlciBhbmQKPiAgICBA bG9jYWxfZXJyIGlzIHRoZSB2YXJpYWJsZS4KPiAKPiBJZiBJIHVuZGVyc3RhbmQgeW91IGNvcnJl Y3RseSwgeW91J3JlIHBvaW50aW5nIG91dCB0d28gcG90ZW50aWFsIGlzc3VlczoKPiAKPiAxLiBU aGlzIHJ1bGUgY2FuIG1hdGNoIGZ1bmN0aW9ucyBydWxlMSBkb2VzIG5vdCBtYXRjaCBpZiB0aGVy ZSBpcwo+IGFub3RoZXIgZnVuY3Rpb24gd2l0aCB0aGUgc2FtZSBuYW1lIHRoYXQgcnVsZTEgZG9l cyBtYXRjaC4KPiAKPiAyLiBUaGlzIHJ1bGUgbWF0Y2hlcyBpbiB0aGUgZW50aXJlIGZ1bmN0aW9u IG1hdGNoZWQgYnkgcnVsZTEsIGV2ZW4gd2hlbgo+IHBhcnRzIG9mIHRoYXQgZnVuY3Rpb24gdXNl IGEgZGlmZmVyZW50IEBlcnJwIG9yIEBsb2NhbF9lcnIuCj4gCj4gSSBmaWd1cmUgdGhlc2UgYXBw bHkgdG8gYWxsIHJ1bGVzIHdpdGggaWRlbnRpZmllciBydWxlMS5mbiwgbm90IGp1c3QKPiB0aGlz IG9uZS4gIENvcnJlY3Q/CgpZZXMuCgo+IAo+IFJlZ2FyZGluZyAxLiAgVGhlcmUgbXVzdCBiZSBh IGJldHRlciB3YXkgdG8gY2hhaW4gcnVsZXMgdG9nZXRoZXIsIGJ1dCBJCj4gZG9uJ3Qga25vdyBp dC4KPiAgQ2FuIHdlIG1ha2UgQ29jY2luZWxsZSBhdCBsZWFzdCB3YXJuIHVzIHdoZW4gaXQgY29u dmVydHMKPiBtdWx0aXBsZSBmdW5jdGlvbnMgd2l0aCB0aGUgc2FtZSBuYW1lPyAgV2hhdCBhYm91 dCB0aGlzOgo+IAo+ICAgICBAaW5pdGlhbGl6ZTpweXRob25ACj4gICAgIEBACj4gICAgIGZucHJl diA9IHt9Cj4gCj4gICAgIGRlZiBwcihmbiwgcCk6Cj4gICAgICAgICBwcmludCgiIyMjICVzOiVz OiAlcygpIiAlIChwWzBdLmZpbGUsIHBbMF0ubGluZSwgZm4pKQo+IAo+ICAgICBAckAKPiAgICAg aWRlbnRpZmllciBydWxlMS5mbjsKPiAgICAgcG9zaXRpb24gcDsKPiAgICAgQEAKPiAgICAgIGZu KC4uLilAcAo+ICAgICAgewo+ICAgICAgICAgIC4uLgo+ICAgICAgfQo+ICAgICBAc2NyaXB0OnB5 dGhvbkAKPiAgICAgICAgIGZuIDw8IHJ1bGUxLmZuOwo+ICAgICAgICAgcCA8PCByLnA7Cj4gICAg IEBACj4gICAgIGlmIGZuIG5vdCBpbiBmbnByZXY6Cj4gICAgICAgICBmbnByZXZbZm5dID0gcAo+ ICAgICBlbHNlOgo+ICAgICAgICAgaWYgZm5wcmV2W2ZuXToKCmhtbSwgdGhlIGNvbmRpdGlvbiBj YW4ndCBiZSBmYWxzZQoKPiAgICAgICAgICAgICBwcihmbiwgZm5wcmV2W2ZuXSkKPiAgICAgICAg ICAgICBmbnByZXZbZm5dID0gTm9uZQo+ICAgICAgICAgcHIoZm4sIHApCgphbmQgd2UnbGwgbWlz cyBuZXh0IGR1cGxpY2F0aW9uLi4KCkJ1dCBJIGxpa2UgdGhlIGlkZWEuCgo+IAo+IEZvciBlYWNo IGZ1bmN0aW9uIEBmbiBtYXRjaGVkIGJ5IHJ1bGUxLCBmbmNudFtmbl0gaXMgYW4gdXBwZXIgbGlt aXQgb2YKPiB0aGUgbnVtYmVyIG9mIGZ1bmN0aW9ucyB3aXRoIHRoZSBzYW1lIG5hbWUgd2UgdG91 Y2guICBJZiBpdCdzIG1vcmUgdGhhbgo+IG9uZSwgd2UgcHJpbnQuCj4gCj4gUmVwb3J0cyBhYm91 dCBhIGRvemVuIGZ1bmN0aW9uIG5hbWVzIGZvciB0aGUgd2hvbGUgdHJlZSBpbiBteSB0ZXN0aW5n Lgo+IEluc3BlY3RpbmcgdGhlIGNoYW5nZXMgdG8gdGhlbSBtYW51YWxseSBpcyBmZWFzaWJsZS4g IE5vbmUgb2YgdGhlbSBhcmUKPiBpbiBmaWxlcyB0b3VjaGVkIGJ5IHRoaXMgc2VyaWVzLgo+IAo+ IFRoZSBsaW5lIHByaW50ZWQgZm9yIHRoZSBmaXJzdCBtYXRjaCBpcyBwcmV0dHkgdXNlbGVzcyBm b3IgbWU6IGl0IHBvaW50cwo+IHRvIGEgQ29jY2luZWxsZSB0ZW1wb3JhcnkgZmlsZSAqc2hydWcq Lgo+IAo+IFJlZ2FyZGluZyAyLiAgU2hhZG93aW5nIEBlcnJwIG9yIEBsb2NhbF9lcnIgd291bGQg YmUgaW4gYmFkIHRhc3RlLCBhbmQgSQo+IHN1cmUgaG9wZSB3ZSBkb24ndCBkbyB0aGF0LiAgTXVs dGlwbGUgQGxvY2FsX2VyciB2YXJpYWJsZXMuLi4gaG1tLgo+IFBlcmhhcHMgd2UgY291bGQgYWdh aW4gY29uY29jdCBzb21lIHNjcmlwdCBydWxlcyB0byBsZWFkIHVzIHRvIHNwb3RzIHRvCj4gY2hl Y2sgbWFudWFsbHkuICBTZWUgYmVsb3cgZm9yIG15IGF0dGVtcHQuCj4gCj4gV2hhdCdzIHRoZSB3 b3JzdCB0aGF0IGNvdWxkIGhhcHBlbiBpZiB3ZSBibGluZGx5IGNvbnZlcnRlZCBzdWNoIGNvZGU/ Cj4gVGhlIGFuc3dlciB0byB0aGF0IHF1ZXN0aW9uIHRlbGxzIHVzIGhvdyBoYXJkIHRvIHdvcmsg b24gZmluZGluZyBhbmQKPiBjaGVja2luZyB0aGVzZSBndXlzLgo+IAo+PiArLy8KPj4gKy8vIE5v dGUgYWxzbyB0aGF0IGVycnAtY2xlYW5pbmcgZnVuY3Rpb25zCj4+ICsvLyAgIGVycm9yX2ZyZWVf ZXJycAo+PiArLy8gICBlcnJvcl9yZXBvcnRfZXJycAo+PiArLy8gICBlcnJvcl9yZXBvcnRmX2Vy cnAKPj4gKy8vICAgd2Fybl9yZXBvcnRfZXJycAo+PiArLy8gICB3YXJuX3JlcG9ydGZfZXJycAo+ PiArLy8gYXJlIG5vdCB5ZXQgaW1wbGVtZW50ZWQuIFRoZXkgbXVzdCBjYWxsIGNvcnJlc3BvbmRp bmcgRXJyb3IqIC0gZnJlZWluZwo+PiArLy8gZnVuY3Rpb24gYW5kIHRoZW4gc2V0ICplcnJwIHRv IE5VTEwsIHRvIGF2b2lkIGZ1cnRoZXIgcHJvcGFnYXRpb24gdG8KPj4gKy8vIG9yaWdpbmFsIGVy cnAgKGNvbnNpZGVyIEVSUlBfQVVUT19QUk9QQUdBVEUgaW4gdXNlKS4KPj4gKy8vIEZvciBleGFt cGxlLCBlcnJvcl9mcmVlX2VycnAgbWF5IGxvb2sgbGlrZSB0aGlzOgo+PiArLy8KPj4gKy8vICAg IHZvaWQgZXJyb3JfZnJlZV9lcnJwKEVycm9yICoqZXJycCkKPj4gKy8vICAgIHsKPj4gKy8vICAg ICAgICBlcnJvcl9mcmVlKCplcnJwKTsKPj4gKy8vICAgICAgICAqZXJycCA9IE5VTEw7Cj4+ICsv LyAgICB9Cj4+ICtAIGV4aXN0c0AKPj4gK2lkZW50aWZpZXIgcnVsZTEuZm4sIHJ1bGUxLmxvY2Fs X2VycjsKPj4gK2V4cHJlc3Npb24gbGlzdCBhcmdzOwo+PiArc3ltYm9sIGVycnA7Cj4+ICtAQAo+ PiArCj4+ICsgZm4oLi4uKQo+PiArIHsKPj4gKyAgICAgPC4uLgo+PiArKAo+IAo+IEVhY2ggb2Yg dGhlIGZvbGxvd2luZyBwYXR0ZXJucyBhcHBsaWVzIGFueXdoZXJlIGluIHRoZSBmdW5jdGlvbi4K PiAKPiBGaXJzdCBwYXR0ZXJuOiBkZWxldGUgQGxvY2FsX2Vycgo+IAo+PiArLSAgICBFcnJvciAq bG9jYWxfZXJyID0gTlVMTDsKPiAKPiBDb21tb24gY2FzZTogb2NjdXJzIGp1c3Qgb25jZSwgbm90 IG5lc3RlZC4gIEFueXRoaW5nIGVsc2UgaXMgc3VzcGljaW91cy4KPiAKPiBCb3RoIGNhbiBiZSBk ZXRlY3RlZCBpbiB0aGUgcmVzdWx0aW5nIHBhdGNoZXMgd2l0aCBhIGJpdCBvZiBBV0sKPiB3aXph cmRyeToKPiAKPiAgICAgICQgZ2l0LWRpZmYgLVUwIG1hc3Rlci4ucmV2aWV3LWVycm9yLXY4IHwg YXdrICcvXkBAIC8geyBjdHggPSAkNTsgZm9yIChpID0gNjsgaSA8PSBORjsgaSsrKSBjdHggPSBj dHggIiAiICRpOyBpZiAoY3R4ICE9IG9jdHgpIHsgb2N0eCA9IGN0eDsgbiA9IDAgfSB9IC9eLSAq RXJyb3IgKlwqICpbQS1aYS16MC05X10rICo9ICpOVUxMOy8geyBpZiAoaW5kZXgoJDAsICJFIikg PiA2KSBwcmludCAibmVzdGVkXG4gICAgIiBjdHg7IGlmIChuKSBwcmludCAibW9yZSB0aGFuIG9u ZVxuICAgICIgY3R4OyBuKysgfScKPiAgICAgIG5lc3RlZAo+ICAgICAgICAgIHN0YXRpYyB2b2lk IHhlbl9ibG9ja19kcml2ZV9kZXN0cm95KFhlbkJsb2NrRHJpdmUgKmRyaXZlLCBFcnJvciAqKmVy cnApCj4gICAgICBuZXN0ZWQKPiAgICAgICAgICBzdGF0aWMgdm9pZCB4ZW5fYmxvY2tfZGV2aWNl X2Rlc3Ryb3koWGVuQmFja2VuZEluc3RhbmNlICpiYWNrZW5kLAo+ICAgICAgbmVzdGVkCj4gICAg ICAgICAgc3RhdGljIHZvaWQgeGVuX2Jsb2NrX2RldmljZV9kZXN0cm95KFhlbkJhY2tlbmRJbnN0 YW5jZSAqYmFja2VuZCwKPiAgICAgIG1vcmUgdGhhbiBvbmUKPiAgICAgICAgICBzdGF0aWMgdm9p ZCB4ZW5fYmxvY2tfZGV2aWNlX2Rlc3Ryb3koWGVuQmFja2VuZEluc3RhbmNlICpiYWNrZW5kLAo+ IAo+IE9oLgo+IAo+IHhlbl9ibG9ja19kcml2ZV9kZXN0cm95KCkgbmVzdHMgaXRzIEVycm9yICps b2NhbF9lcnIgaW4gYSBjb25kaXRpb25hbC4KPiAKPiB4ZW5fYmxvY2tfZGV2aWNlX2Rlc3Ryb3ko KSBoYXMgbXVsdGlwbGUgRXJyb3IgKmxvY2FsX2Vyci4KPiAKPiBJbiBib3RoIGNhc2VzLCBtYW51 YWwgcmV2aWV3IGlzIHJlcXVpcmVkIHRvIGVuc3VyZSB0aGUgY29udmVyc2lvbiBpcwo+IG9rYXku ICBJIGJlbGlldmUgaXQgaXMuCj4gCj4gTm90ZSB0aGF0IHRoZSBBV0sgc2NyaXB0IHJlbGllcyBv biBkaWZmIHNob3dpbmcgdGhlIGZ1bmN0aW9uIG5hbWUgaW4gQEAKPiBsaW5lcywgd2hpY2ggZG9l c24ndCBhbHdheXMgd29yayBkdWUgdG8gb3VyIGNvZGluZyBzdHlsZS4KPiAKPiBGb3IgdGhlIHdo b2xlIHRyZWUsIEkgZ2V0IHNvbWUgMzAgc3BvdHMuICBGZWFzaWJsZS4KPiAKPj4gK3wKPiAKPiBT ZWNvbmQgcGF0dGVybjogY2xlYXIgQGVycnAgYWZ0ZXIgZnJlZWluZyBpdAo+IAo+PiArCj4+ICsv LyBDb252ZXJ0IGVycm9yIGNsZWFyaW5nIGZ1bmN0aW9ucwo+IAo+IFN1Z2dlc3Q6IEVuc3VyZSBA bG9jYWxfZXJyIGlzIGNsZWFyZWQgb24gZnJlZQo+IAo+PiArKAo+PiArLSAgICBlcnJvcl9mcmVl KGxvY2FsX2Vycik7Cj4+ICsrICAgIGVycm9yX2ZyZWVfZXJycChlcnJwKTsKPj4gK3wKPj4gKy0g ICAgZXJyb3JfcmVwb3J0X2Vycihsb2NhbF9lcnIpOwo+PiArKyAgICBlcnJvcl9yZXBvcnRfZXJy cChlcnJwKTsKPj4gK3wKPj4gKy0gICAgZXJyb3JfcmVwb3J0Zl9lcnIobG9jYWxfZXJyLCBhcmdz KTsKPj4gKysgICAgZXJyb3JfcmVwb3J0Zl9lcnJwKGVycnAsIGFyZ3MpOwo+PiArfAo+PiArLSAg ICB3YXJuX3JlcG9ydF9lcnIobG9jYWxfZXJyKTsKPj4gKysgICAgd2Fybl9yZXBvcnRfZXJycChl cnJwKTsKPj4gK3wKPj4gKy0gICAgd2Fybl9yZXBvcnRmX2Vycihsb2NhbF9lcnIsIGFyZ3MpOwo+ PiArKyAgICB3YXJuX3JlcG9ydGZfZXJycChlcnJwLCBhcmdzKTsKPj4gKykKPiAKPiBBcyB5b3Ug bWVudGlvbiBhYm92ZSwgdGhlc2UgZ3V5cyBkb24ndCBleGlzdCwgeWV0LiAgQnVpbGRzIGFueXdh eSwKPiBiZWNhdXNlIHRoaXMgcGFydCBvZiB0aGUgcnVsZSBpcyBub3QgdXNlZCBpbiB0aGlzIHBh dGNoIHNlcmllcy4gIFlvdQo+IGRvbid0IHdhbnQgdG8gb21pdCBpdCwgYmVjYXVzZSB0aGVuIHRo ZSBzY3JpcHQgYmVjb21lcyB1bnNhZmUgdG8gdXNlLgo+IAo+IFdlIGNvdWxkIGFsc28gb3Blbi1j b2RlOgo+IAo+ICAgICAvLyBDb252ZXJ0IGVycm9yIGNsZWFyaW5nIGZ1bmN0aW9ucwo+ICAgICAo Cj4gICAgIC0gICAgZXJyb3JfZnJlZShsb2NhbF9lcnIpOwo+ICAgICArICAgIGVycm9yX2ZyZWUo KmVycnApOwo+ICAgICArICAgICplcnJwID0gTlVMTDsKPiAgICAgfAo+ICAgICAuLi4gYW5kIHNv IGZvcnRoIC4uLgo+ICAgICApCj4gCj4gTWF0dGVyIG9mIHRhc3RlLiAgV2hhdGV2ZXIgaXMgZWFz aWVyIHRvIGV4cGxhaW4gaW4gdGhlIGNvbW1lbnRzLiAgU2luY2UKPiB5b3UgYWxyZWFkeSB3cm90 ZSBvbmUuLi4KCkkganVzdCBmZWVsIHRoYXQgdXNpbmcgaGVscGVyIGZ1bmN0aW9ucyBpcyBzYWZl ciB3YXkuLgoKPiAKPiBXZSB0YWxrZWQgYWJvdXQgZXh0ZW5kaW5nIHRoaXMgc2VyaWVzIHNsaWdo dGx5IHNvIHRoZXNlIGd1eXMgYXJlIHVzZWQuCj4gSSBtYXkgc3RpbGwgbG9vayBpbnRvIHRoYXQu Cj4gCj4+ICs/LSAgICBsb2NhbF9lcnIgPSBOVUxMOwo+PiArCj4gCj4gVGhlIG5ldyBoZWxwZXJz IGNsZWFyIEBsb2NhbF9lcnIuICBBc3NpZ25tZW50IG5vdyByZWR1bmRhbnQsIGRlbGV0ZS4KPiBP a2F5Lgo+IAo+PiArfAo+IAo+IFRoaXJkIGFuZCBmb3VydGggcGF0dGVybjogZGVsZXRlIGVycm9y X3Byb3BhZ2F0ZSgpCj4gCj4+ICstICAgIGVycm9yX3Byb3BhZ2F0ZV9wcmVwZW5kKGVycnAsIGxv Y2FsX2VyciwgYXJncyk7Cj4+ICsrICAgIGVycm9yX3ByZXBlbmQoZXJycCwgYXJncyk7Cj4+ICt8 Cj4+ICstICAgIGVycm9yX3Byb3BhZ2F0ZShlcnJwLCBsb2NhbF9lcnIpOwo+PiArfAo+IAo+IEZp ZnRoIHBhdHRlcm46IHVzZSBAZXJycCBkaXJlY3RseQo+IAo+PiArLSAgICAmbG9jYWxfZXJyCj4+ ICsrICAgIGVycnAKPj4gKykKPj4gKyAgICAgLi4uPgo+PiArIH0KPj4gKwo+PiArLy8gQ29udmVy dCByZW1haW5pbmcgbG9jYWxfZXJyIHVzYWdlLiBJdCBzaG91bGQgYmUgZGlmZmVyZW50IGtpbmRz IG9mIGVycm9yCj4+ICsvLyBjaGVja2luZyBpbiBpZiBvcGVyYXRvcnMuIFdlIGNhbid0IG1lcmdl IHRoaXMgaW50byBwcmV2aW91cyBodW5rLCBhcyB0aGlzCj4gCj4gSW4gaWYgY29uZGl0aW9uYWxz LCBJIHN1cHBvc2UuICBJdCdzIHRoZSBjYXNlIGZvciB0aGlzIHBhdGNoLiAgSWYgSQo+IGFwcGx5 IHRoZSBzY3JpcHQgdG8gdGhlIHdob2xlIHRyZWUsIHRoZSBydWxlIGdldHMgYWxzbyBhcHBsaWVk IGluIG90aGVyCj4gY29udGV4dHMuICBUaGUgc2VudGVuY2UgbWlnaHQgbWlzbGVhZCBhcyBtdWNo IGFzIGl0IGhlbHBzLiAgS2VlcCBpdCBvcgo+IGRlbGV0ZSBpdD8KCk1heWJlLCBqdXN0IGJlIG1v cmUgaG9uZXN0OiAiSXQgc2hvdWxkIGJlIC4uLiwgYnV0IGl0IG1heSBiZSBhbnkgb3RoZXIgcGF0 dGVybiwgYmUgY2FyZWZ1bCIKCj4gCj4+ICsvLyBjb25mbGljdHMgd2l0aCBvdGhlciBzdWJzdGl0 dXRpb25zIGluIGl0IChhdCBsZWFzdCB3aXRoICItIGxvY2FsX2VyciA9IE5VTEwiKS4KPj4gK0BA Cj4+ICtpZGVudGlmaWVyIHJ1bGUxLmZuLCBydWxlMS5sb2NhbF9lcnI7Cj4+ICtzeW1ib2wgZXJy cDsKPj4gK0BACj4+ICsKPj4gKyBmbiguLi4pCj4+ICsgewo+PiArICAgICA8Li4uCj4+ICstICAg IGxvY2FsX2Vycgo+PiArKyAgICAqZXJycAo+PiArICAgICAuLi4+Cj4+ICsgfQo+PiArCj4+ICsv LyBBbHdheXMgdXNlIHRoZSBzYW1lIHBhdHRlciBmb3IgY2hlY2tpbmcgZXJyb3IKPiAKPiBzL3Bh dHRlci9wYXR0ZXJuLwo+IAo+PiArQEAKPj4gK2lkZW50aWZpZXIgcnVsZTEuZm47Cj4+ICtzeW1i b2wgZXJycDsKPj4gK0BACj4+ICsKPj4gKyBmbiguLi4pCj4+ICsgewo+PiArICAgICA8Li4uCj4+ ICstICAgICplcnJwICE9IE5VTEwKPj4gKysgICAgKmVycnAKPj4gKyAgICAgLi4uPgo+PiArIH0K PiAKCgotLSAKQmVzdCByZWdhcmRzLApWbGFkaW1pcgoKX19fX19fX19fX19fX19fX19fX19fX19f X19fX19fX19fX19fX19fX19fX19fX18KWGVuLWRldmVsIG1haWxpbmcgbGlzdApYZW4tZGV2ZWxA bGlzdHMueGVucHJvamVjdC5vcmcKaHR0cHM6Ly9saXN0cy54ZW5wcm9qZWN0Lm9yZy9tYWlsbWFu L2xpc3RpbmZvL3hlbi1kZXZlbA==