From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 89734 invoked by alias); 24 Oct 2019 06:25:51 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Received: (qmail 89718 invoked by uid 89); 24 Oct 2019 06:25:50 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-23.9 required=5.0 tests=AWL,BAYES_00,GIT_PATCH_0,GIT_PATCH_1,GIT_PATCH_2,GIT_PATCH_3,RCVD_IN_DNSWL_NONE,SPF_HELO_PASS,SPF_PASS autolearn=ham version=3.3.1 spammy= X-HELO: NAM04-SN1-obe.outbound.protection.outlook.com Received: from mail-eopbgr700108.outbound.protection.outlook.com (HELO NAM04-SN1-obe.outbound.protection.outlook.com) (40.107.70.108) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Thu, 24 Oct 2019 06:25:46 +0000 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=Tisv1pfayGBt0RZObs49wcUz4ikRuuOF/RdSbeQ/oE6YRrJqJWWuyocViI10IVZg3j+iU85NlXPIMTf6+nty1F/ML+aSolrg2f+xmRmonHSVSQQuAT5cYoXuBegfAe/ycItr91KRFDB3XWOo93ypFsCz8g1O89aJgN537uw7nGdg5CgQZlJAIF1YA5rNwj1K3j44hhDU6DfCesYkUhkPArHviLRoLX79MDr2NI13wzgA9qDRqrPT961qyRGgjCVDhl+hLRSWq4dUH3pA5rTGbd1oGfTuIHYFnAF3eyiAYtURkIPcBYLiZB8kl74FlL3uSxiprfmJ9ivBkyjTuT75QA== 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=RVWsQU3vyMfIy93HKdv8eiap2FEf1LpTJvesrFL2nfY=; b=J6KCcBeLGrZJMrvWMll/ApMhXAL4tWu7/9u3XOuD1vD4ZzhQUY4k990rSMUWEio1fdCevnktR6JJHG4d0r3MXPregQ5KJNKXQDyMSLmuqNZnIZxgFO2CFWTlxp6zDbWiUfM5ZHYaKjVzxbwH/W8oE23GYsrAEmwQ03s5bMQaNGDD6JctYHp6UmLQkjjxFxbu4sKx2NzpkJaHl4ubVkbu5nyCQmzT+HajKFLY5i2yB5IgU60oqjnnTatdG/a2cowFXAqmhSoIK4j3UGUa+JGClkDE4CaHWR2zmifuP+lBL11po86+yfrnvur7PWxtiEjKODBWKJy6HNlk1MJCDyj6rA== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=os.amperecomputing.com; dmarc=pass action=none header.from=os.amperecomputing.com; dkim=pass header.d=os.amperecomputing.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=os.amperecomputing.com; s=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=RVWsQU3vyMfIy93HKdv8eiap2FEf1LpTJvesrFL2nfY=; b=K5O5EwsFCqmb2oWTbRe2EoCCn73L8JHR8EHZtP4n0YCviDDfUV5cqmC70+f3EZdTDbk5toLsdv3aFhUJpEWMmnV4qVfBSMZdPxUfV0My6IdtwewsLLUD40zdBshH5sGwRqOgKWCW+nUWJX6wJ5u/wEFzcqXo8FWTqzak/mdtob0= Received: from BYAPR01MB4869.prod.exchangelabs.com (20.177.226.139) by BYAPR01MB4278.prod.exchangelabs.com (52.135.240.93) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.2387.22; Thu, 24 Oct 2019 06:25:40 +0000 Received: from BYAPR01MB4869.prod.exchangelabs.com ([fe80::a984:9c86:cc04:f50c]) by BYAPR01MB4869.prod.exchangelabs.com ([fe80::a984:9c86:cc04:f50c%5]) with mapi id 15.20.2347.030; Thu, 24 Oct 2019 06:25:34 +0000 From: Feng Xue OS To: luoxhu , "gcc-patches@gcc.gnu.org" , Jan Hubicka , Martin Jambor Subject: Re: [PATCH] Support multi-versioning on self-recursive function (ipa/92133) Date: Thu, 24 Oct 2019 06:57:00 -0000 Message-ID: References: , In-Reply-To: authentication-results: spf=none (sender IP is ) smtp.mailfrom=fxue@os.amperecomputing.com; x-ms-oob-tlc-oobclassifiers: OLM:6790; received-spf: None (protection.outlook.com: os.amperecomputing.com does not designate permitted sender hosts) x-ms-exchange-senderadcheck: 1 x-ms-exchange-transport-forked: True Content-Type: multipart/mixed; boundary="_002_BYAPR01MB48691A96BE0A2BECB51A5D70F76A0BYAPR01MB4869prod_" MIME-Version: 1.0 X-MS-Exchange-CrossTenant-mailboxtype: HOSTED X-MS-Exchange-CrossTenant-userprincipalname: DPtTV8Nbx4fqyI0D7/PhEsQr4EBbjW+DRvqJJRdwdQGRwDdP/ZdTdzaRRuZrkKxU85hkB1ApllhFkzGbBjz9v87RXUgBIpTCelx4wVW1h8o= X-IsSubscribed: yes X-SW-Source: 2019-10/txt/msg01712.txt.bz2 --_002_BYAPR01MB48691A96BE0A2BECB51A5D70F76A0BYAPR01MB4869prod_ Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable Content-length: 13318 Hi, Actually, this patch is not final one. Since the previous cp-by-ref patch= is still on the way to the trunk, I tailored it to only handle by-value recursion, so that it is decoupled wi= th the previous patch, and can be reviewed independently. I attached the final patch, you can have a try. CP propagation stage might generate values outside of recursion ranges, bu= t cloning stage will not make a duplicate for invalid recursion value, with which we do not need ext= ra code for recursion range analysis. Feng ________________________________________ From: luoxhu Sent: Thursday, October 24, 2019 1:44 PM To: Feng Xue OS; gcc-patches@gcc.gnu.org; Jan Hubicka; Martin Jambor Subject: Re: [PATCH] Support multi-versioning on self-recursive function (i= pa/92133) Hi, On 2019/10/17 16:23, Feng Xue OS wrote: > IPA does not allow constant propagation on parameter that is used to cont= rol > function recursion. > > recur_fn (i) > { > if ( !terminate_recursion (i)) > { > ... > recur_fn (i + 1); > ... > } > ... > } > > This patch is composed to enable multi-versioning for self-recursive func= tion, > and versioning copies is limited by a specified option. > > Feng > --- > diff --git a/gcc/ipa-cp.c b/gcc/ipa-cp.c > index 045072e02ec..6255a766e4d 100644 > --- a/gcc/ipa-cp.c > +++ b/gcc/ipa-cp.c > @@ -229,7 +229,9 @@ public: > inline bool set_contains_variable (); > bool add_value (valtype newval, cgraph_edge *cs, > ipcp_value *src_val =3D NULL, > - int src_idx =3D 0, HOST_WIDE_INT offset =3D -1); > + int src_idx =3D 0, HOST_WIDE_INT offset =3D -1, > + ipcp_value **val_pos_p =3D NULL, > + bool unlimited =3D false); > void print (FILE * f, bool dump_sources, bool dump_benefits); > }; > > @@ -1579,22 +1581,37 @@ allocate_and_init_ipcp_value (ipa_polymorphic_cal= l_context source) > /* Try to add NEWVAL to LAT, potentially creating a new ipcp_value for = it. CS, > SRC_VAL SRC_INDEX and OFFSET are meant for add_source and have the s= ame > meaning. OFFSET -1 means the source is scalar and not a part of an > - aggregate. */ > + aggregate. If non-NULL, VAL_POS_P specifies position in value list, > + after which newly created ipcp_value will be inserted, and it is also > + used to record address of the added ipcp_value before function return= s. > + UNLIMITED means whether value count should not exceed the limit given > + by PARAM_IPA_CP_VALUE_LIST_SIZE. */ > > template > bool > ipcp_lattice::add_value (valtype newval, cgraph_edge *cs, > ipcp_value *src_val, > - int src_idx, HOST_WIDE_INT offset) > + int src_idx, HOST_WIDE_INT offset, > + ipcp_value **val_pos_p, > + bool unlimited) > { > ipcp_value *val; > > + if (val_pos_p) > + { > + for (val =3D values; val && val !=3D *val_pos_p; val =3D val->next= ); > + gcc_checking_assert (val); > + } > + > if (bottom) > return false; > > for (val =3D values; val; val =3D val->next) > if (values_equal_for_ipcp_p (val->value, newval)) > { > + if (val_pos_p) > + *val_pos_p =3D val; > + > if (ipa_edge_within_scc (cs)) > { > ipcp_value_source *s; > @@ -1609,7 +1626,8 @@ ipcp_lattice::add_value (valtype newval, c= graph_edge *cs, > return false; > } > > - if (values_count =3D=3D PARAM_VALUE (PARAM_IPA_CP_VALUE_LIST_SIZE)) > + if (!unlimited > + && values_count =3D=3D PARAM_VALUE (PARAM_IPA_CP_VALUE_LIST_SIZE)) > { > /* We can only free sources, not the values themselves, because s= ources > of other values in this SCC might point to them. */ > @@ -1623,6 +1641,9 @@ ipcp_lattice::add_value (valtype newval, c= graph_edge *cs, > } > } > > + if (val_pos_p) > + *val_pos_p =3D NULL; > + > values =3D NULL; > return set_to_bottom (); > } > @@ -1630,8 +1651,54 @@ ipcp_lattice::add_value (valtype newval, = cgraph_edge *cs, > values_count++; > val =3D allocate_and_init_ipcp_value (newval); > val->add_source (cs, src_val, src_idx, offset); > - val->next =3D values; > - values =3D val; > + if (val_pos_p) > + { > + val->next =3D (*val_pos_p)->next; > + (*val_pos_p)->next =3D val; > + *val_pos_p =3D val; > + } > + else > + { > + val->next =3D values; > + values =3D val; > + } > + > + return true; > +} > + > +/* Return true, if a ipcp_value VAL is orginated from parameter value of > + self-feeding recursive function by applying non-passthrough arithmetic > + transformation. */ > + > +static bool > +self_recursively_generated_p (ipcp_value *val) > +{ > + class ipa_node_params *info =3D NULL; > + > + for (ipcp_value_source *src =3D val->sources; src; src =3D src->= next) > + { > + cgraph_edge *cs =3D src->cs; > + > + if (!src->val || cs->caller !=3D cs->callee->function_symbol () > + || src->val =3D=3D val) > + return false; > + > + if (!info) > + info =3D IPA_NODE_REF (cs->caller); > + > + class ipcp_param_lattices *plats =3D ipa_get_parm_lattices (info, > + src->index); > + ipcp_lattice *src_lat =3D src->offset =3D=3D -1 ? &plats->it= self > + : plats->aggs; Thanks for the patch. This function doesn't handle the by-ref case after rebasing this patch to y= our previous ipa-cp by-ref of arith patch as below (Also some conflicts need fi= x): foo (int * p) { ... return foo(*(&p) + 1); } It will cause value explosion. Secondly, the self_recursive doesn't check or break if the value is above t= han the recursive boundary, which seems would generate redundant nodes? IMHO, It may be helpful if adding more comments before the return and dump = log for dump-ipa-cp-all-details when adding new values and new sources like bel= ow for debugging and others can understand the code easier? :) newval, src_val, src_val->sources, *src_val->sources, caller, callee 1, (ipcp_value *) 0x12bc1828, (ipcp_value_source *)= 0x12bae800, {offset =3D -1, cs =3D 0x3fffb5602768, val =3D 0x0, next =3D = 0x0, index =3D 0}, "main", recur_fn" 2, (ipcp_value *) 0x12bc1880, (ipcp_value_source *)= 0x12bae830, {offset =3D -1, cs =3D 0x3fffb5602630, val =3D 0x12bc1828, ne= xt =3D 0x0, index =3D 0},"recur_fn","recur_fn" ... 1, (ipcp_value *) 0x12bc1828, (ipcp_value_source *)= 0x12baea70, {offset =3D -1, cs =3D 0x3fffb5602630, val =3D 0x12bc1c48, nex= t =3D 0x12bae800, index =3D 0} "recur_fn","recur_fn" 2, (ipcp_value *) 0x12bc1880, (ipcp_value_source *)= 0x12bae830, {offset =3D -1, cs =3D 0x3fffb5602630, val =3D 0x12bc1828, nex= t =3D 0x0, index =3D 0} "recur_fn","recur_fn" Xiong Hu Thanks > + ipcp_value *src_val; > + > + for (src_val =3D src_lat->values; src_val && src_val !=3D val; > + src_val =3D src_val->next); > + > + if (!src_val) > + return false; > + } > + > return true; > } > > @@ -1649,20 +1716,72 @@ propagate_vals_across_pass_through (cgraph_edge *= cs, ipa_jump_func *jfunc, > ipcp_value *src_val; > bool ret =3D false; > > - /* Do not create new values when propagating within an SCC because if = there > - are arithmetic functions with circular dependencies, there is infin= ite > - number of them and we would just make lattices bottom. If this con= dition > - is ever relaxed we have to detect self-feeding recursive calls in > - cgraph_edge_brings_value_p in a smarter way. */ > + /* Due to circular dependencies, propagating within an SCC through ari= thmetic > + transformation would create infinite number of values. But for > + self-feeding recursive function, we could allow propagation in a li= mited > + count, and this can enable a simple kind of recursive function vers= ioning. > + For other scenario, we would just make lattices bottom. */ > if ((ipa_get_jf_pass_through_operation (jfunc) !=3D NOP_EXPR) > && ipa_edge_within_scc (cs)) > - ret =3D dest_lat->set_contains_variable (); > + { > + if (src_lat !=3D dest_lat) > + return dest_lat->set_contains_variable (); > + > + auto_vec *, 8> val_seeds; > + > + for (src_val =3D src_lat->values; src_val; src_val =3D src_val->ne= xt) > + { > + /* Now we do not use self-recursively generated value as propagat= ion > + source, this is absolutely conservative, but could avoid explo= sion > + of lattice's value space, especially when one recursive functi= on > + calls another recursive. */ > + if (self_recursively_generated_p (src_val)) > + { > + /* If the lattice has already been propagated for the call si= te, > + no need to do that again. */ > + for (ipcp_value_source *s =3D src_val->sources; s; > + s =3D s->next) > + if (s->cs =3D=3D cs) > + return dest_lat->set_contains_variable (); > + } > + else > + val_seeds.safe_push (src_val); > + } > + > + int clone_copies =3D PARAM_VALUE (PARAM_IPA_CP_MAX_RECURSION_COPIE= S); > + int i; > + > + /* Recursively generate lattice values with a limited count. */ > + FOR_EACH_VEC_ELT (val_seeds, i, src_val) > + { > + for (int j =3D 1; j < clone_copies; j++) > + { > + tree cstval =3D ipa_get_jf_pass_through_result (jfunc, > + src_val->value, > + parm_type); > + if (!cstval) > + break; > + > + /* Try to place the new lattice value after its source, which > + can decrease iterations of propagate stage. */ > + ret |=3D dest_lat->add_value (cstval, cs, src_val, src_idx, > + -1, &src_val, true); > + gcc_checking_assert (src_val); > + } > + } > + ret |=3D dest_lat->set_contains_variable (); > + } > else > for (src_val =3D src_lat->values; src_val; src_val =3D src_val->nex= t) > { > + /* Now we do not use self-recursively generated value as propagat= ion > + source, otherwise it is easy to make value space of normal lat= tice > + overflow. */ > + if (self_recursively_generated_p (src_val)) > + continue; > + > tree cstval =3D ipa_get_jf_pass_through_result (jfunc, src_val->val= ue, > parm_type); > - > if (cstval) > ret |=3D dest_lat->add_value (cstval, cs, src_val, src_idx); > else > @@ -3635,6 +3754,9 @@ get_info_about_necessary_edges (ipcp_value= *val, cgraph_node *dest, > hot |=3D cs->maybe_hot_p (); > if (cs->caller !=3D dest) > non_self_recursive =3D true; > + else if (src->val) > + gcc_assert (values_equal_for_ipcp_p (src->val->value, > + val->value)); > } > cs =3D get_next_cgraph_edge_clone (cs); > } > diff --git a/gcc/params.def b/gcc/params.def > index 322c37f8b96..3e242e09f01 100644 > --- a/gcc/params.def > +++ b/gcc/params.def > @@ -1135,6 +1135,11 @@ DEFPARAM (PARAM_IPA_CP_RECURSION_PENALTY, > "are evaluated for cloning.", > 40, 0, 100) > > +DEFPARAM (PARAM_IPA_CP_MAX_RECURSION_COPIES, > + "ipa-cp-max-recursion-copies", > + "Maximum function versioning copies for a self-recursive function= .", > + 8, 0, 0) > + > DEFPARAM (PARAM_IPA_CP_SINGLE_CALL_PENALTY, > "ipa-cp-single-call-penalty", > "Percentage penalty functions containing a single call to another= " > diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-clone-2.c b/gcc/testsuite/gcc.d= g/ipa/ipa-clone-2.c > new file mode 100644 > index 00000000000..7c1c01047c6 > --- /dev/null > +++ b/gcc/testsuite/gcc.dg/ipa/ipa-clone-2.c > @@ -0,0 +1,47 @@ > +/* { dg-do compile } */ > +/* { dg-options "-O3 -fdump-ipa-cp-details -fno-early-inlining" } */ > + > +int fn(); > + > +int data[100]; > + > +int recur_fn (int i) > +{ > + int j; > + > + if (i =3D=3D 6) > + { > + fn(); > + fn(); > + fn(); > + fn(); > + fn(); > + fn(); > + fn(); > + fn(); > + fn(); > + fn(); > + fn(); > + fn(); > + return 10; > + } > + > + data[i] =3D i; > + > + for (j =3D 0; j < 100; j++) > + recur_fn (i + 1); > + > + return i; > +} > + > +int main () > +{ > + int i; > + > + for (i =3D 0; i < 100; i++) > + recur_fn (1) + recur_fn (-5); > + > + return 1; > +} > + > +/* { dg-final { scan-ipa-dump-times "Creating a specialized node of recu= r_fn/\[0-9\]*\\." 12 "cp" } } */ > --_002_BYAPR01MB48691A96BE0A2BECB51A5D70F76A0BYAPR01MB4869prod_ Content-Type: text/x-patch; name="clone.patch" Content-Description: clone.patch Content-Disposition: attachment; filename="clone.patch"; size=10367; creation-date="Thu, 24 Oct 2019 06:24:15 GMT"; modification-date="Thu, 24 Oct 2019 06:24:15 GMT" Content-Transfer-Encoding: base64 Content-length: 14055 RnJvbSA1MWU3OTkzM2Y1MjY0ZWMzNTI3NmMzMDU4ZWQyYjVhZWIyZjI4MTI4 IE1vbiBTZXAgMTcgMDA6MDA6MDAgMjAwMQpGcm9tOiBGZW5nIFh1ZSA8Znh1 ZUBvcy5hbXBlcmVjb21wdXRpbmcuY29tPgpEYXRlOiBUdWUsIDI0IFNlcCAy MDE5IDExOjQ4OjI2ICswODAwClN1YmplY3Q6IFtQQVRDSF0gY29zdAoKLS0t CiBnY2MvaXBhLWNwLmMgICAgICAgICAgICAgICAgICAgICAgICAgICB8IDE3 MSArKysrKysrKysrKysrKysrKysrKysrLS0tCiBnY2MvcGFyYW1zLmRlZiAg ICAgICAgICAgICAgICAgICAgICAgICB8ICAgNSArCiBnY2MvdGVzdHN1aXRl L2djYy5kZy9pcGEvaXBhLWNsb25lLTIuYyB8ICA0NyArKysrKysrCiAzIGZp bGVzIGNoYW5nZWQsIDIwNCBpbnNlcnRpb25zKCspLCAxOSBkZWxldGlvbnMo LSkKIGNyZWF0ZSBtb2RlIDEwMDY0NCBnY2MvdGVzdHN1aXRlL2djYy5kZy9p cGEvaXBhLWNsb25lLTIuYwoKZGlmZiAtLWdpdCBhL2djYy9pcGEtY3AuYyBi L2djYy9pcGEtY3AuYwppbmRleCBiM2U5MjgwNTJkYy4uZGZmOWVhZGI2NGIg MTAwNjQ0Ci0tLSBhL2djYy9pcGEtY3AuYworKysgYi9nY2MvaXBhLWNwLmMK QEAgLTIyOSw3ICsyMjksOSBAQCBwdWJsaWM6CiAgIGlubGluZSBib29sIHNl dF9jb250YWluc192YXJpYWJsZSAoKTsKICAgYm9vbCBhZGRfdmFsdWUgKHZh bHR5cGUgbmV3dmFsLCBjZ3JhcGhfZWRnZSAqY3MsCiAJCSAgaXBjcF92YWx1 ZTx2YWx0eXBlPiAqc3JjX3ZhbCA9IE5VTEwsCi0JCSAgaW50IHNyY19pZHgg PSAwLCBIT1NUX1dJREVfSU5UIG9mZnNldCA9IC0xKTsKKwkJICBpbnQgc3Jj X2lkeCA9IDAsIEhPU1RfV0lERV9JTlQgb2Zmc2V0ID0gLTEsCisJCSAgaXBj cF92YWx1ZTx2YWx0eXBlPiAqKnZhbF9wb3NfcCA9IE5VTEwsCisJCSAgYm9v bCB1bmxpbWl0ZWQgPSBmYWxzZSk7CiAgIHZvaWQgcHJpbnQgKEZJTEUgKiBm LCBib29sIGR1bXBfc291cmNlcywgYm9vbCBkdW1wX2JlbmVmaXRzKTsKIH07 CiAKQEAgLTE3MzMsMjIgKzE3MzUsMzcgQEAgYWxsb2NhdGVfYW5kX2luaXRf aXBjcF92YWx1ZSAoaXBhX3BvbHltb3JwaGljX2NhbGxfY29udGV4dCBzb3Vy Y2UpCiAvKiBUcnkgdG8gYWRkIE5FV1ZBTCB0byBMQVQsIHBvdGVudGlhbGx5 IGNyZWF0aW5nIGEgbmV3IGlwY3BfdmFsdWUgZm9yIGl0LiAgQ1MsCiAgICBT UkNfVkFMIFNSQ19JTkRFWCBhbmQgT0ZGU0VUIGFyZSBtZWFudCBmb3IgYWRk X3NvdXJjZSBhbmQgaGF2ZSB0aGUgc2FtZQogICAgbWVhbmluZy4gIE9GRlNF VCAtMSBtZWFucyB0aGUgc291cmNlIGlzIHNjYWxhciBhbmQgbm90IGEgcGFy dCBvZiBhbgotICAgYWdncmVnYXRlLiAgKi8KKyAgIGFnZ3JlZ2F0ZS4gIElm IG5vbi1OVUxMLCBWQUxfUE9TX1Agc3BlY2lmaWVzIHBvc2l0aW9uIGluIHZh bHVlIGxpc3QsCisgICBhZnRlciB3aGljaCBuZXdseSBjcmVhdGVkIGlwY3Bf dmFsdWUgd2lsbCBiZSBpbnNlcnRlZCwgYW5kIGl0IGlzIGFsc28KKyAgIHVz ZWQgdG8gcmVjb3JkIGFkZHJlc3Mgb2YgdGhlIGFkZGVkIGlwY3BfdmFsdWUg YmVmb3JlIGZ1bmN0aW9uIHJldHVybnMuCisgICBVTkxJTUlURUQgbWVhbnMg d2hldGhlciB2YWx1ZSBjb3VudCBzaG91bGQgbm90IGV4Y2VlZCB0aGUgbGlt aXQgZ2l2ZW4KKyAgIGJ5IFBBUkFNX0lQQV9DUF9WQUxVRV9MSVNUX1NJWkUu ICAqLwogCiB0ZW1wbGF0ZSA8dHlwZW5hbWUgdmFsdHlwZT4KIGJvb2wKIGlw Y3BfbGF0dGljZTx2YWx0eXBlPjo6YWRkX3ZhbHVlICh2YWx0eXBlIG5ld3Zh bCwgY2dyYXBoX2VkZ2UgKmNzLAogCQkJCSAgaXBjcF92YWx1ZTx2YWx0eXBl PiAqc3JjX3ZhbCwKLQkJCQkgIGludCBzcmNfaWR4LCBIT1NUX1dJREVfSU5U IG9mZnNldCkKKwkJCQkgIGludCBzcmNfaWR4LCBIT1NUX1dJREVfSU5UIG9m ZnNldCwKKwkJCQkgIGlwY3BfdmFsdWU8dmFsdHlwZT4gKip2YWxfcG9zX3As CisJCQkJICBib29sIHVubGltaXRlZCkKIHsKICAgaXBjcF92YWx1ZTx2YWx0 eXBlPiAqdmFsOwogCisgIGlmICh2YWxfcG9zX3ApCisgICAgeworICAgICAg Zm9yICh2YWwgPSB2YWx1ZXM7IHZhbCAmJiB2YWwgIT0gKnZhbF9wb3NfcDsg dmFsID0gdmFsLT5uZXh0KTsKKyAgICAgIGdjY19jaGVja2luZ19hc3NlcnQg KHZhbCk7CisgICAgfQorCiAgIGlmIChib3R0b20pCiAgICAgcmV0dXJuIGZh bHNlOwogCiAgIGZvciAodmFsID0gdmFsdWVzOyB2YWw7IHZhbCA9IHZhbC0+ bmV4dCkKICAgICBpZiAodmFsdWVzX2VxdWFsX2Zvcl9pcGNwX3AgKHZhbC0+ dmFsdWUsIG5ld3ZhbCkpCiAgICAgICB7CisJaWYgKHZhbF9wb3NfcCkKKwkg ICp2YWxfcG9zX3AgPSB2YWw7CisKIAlpZiAoaXBhX2VkZ2Vfd2l0aGluX3Nj YyAoY3MpKQogCSAgewogCSAgICBpcGNwX3ZhbHVlX3NvdXJjZTx2YWx0eXBl PiAqczsKQEAgLTE3NjMsNyArMTc4MCw4IEBAIGlwY3BfbGF0dGljZTx2YWx0 eXBlPjo6YWRkX3ZhbHVlICh2YWx0eXBlIG5ld3ZhbCwgY2dyYXBoX2VkZ2Ug KmNzLAogCXJldHVybiBmYWxzZTsKICAgICAgIH0KIAotICBpZiAodmFsdWVz X2NvdW50ID09IFBBUkFNX1ZBTFVFIChQQVJBTV9JUEFfQ1BfVkFMVUVfTElT VF9TSVpFKSkKKyAgaWYgKCF1bmxpbWl0ZWQKKyAgICAgICYmIHZhbHVlc19j b3VudCA9PSBQQVJBTV9WQUxVRSAoUEFSQU1fSVBBX0NQX1ZBTFVFX0xJU1Rf U0laRSkpCiAgICAgewogICAgICAgLyogV2UgY2FuIG9ubHkgZnJlZSBzb3Vy Y2VzLCBub3QgdGhlIHZhbHVlcyB0aGVtc2VsdmVzLCBiZWNhdXNlIHNvdXJj ZXMKIAkgb2Ygb3RoZXIgdmFsdWVzIGluIHRoaXMgU0NDIG1pZ2h0IHBvaW50 IHRvIHRoZW0uICAgKi8KQEAgLTE3NzcsNiArMTc5NSw5IEBAIGlwY3BfbGF0 dGljZTx2YWx0eXBlPjo6YWRkX3ZhbHVlICh2YWx0eXBlIG5ld3ZhbCwgY2dy YXBoX2VkZ2UgKmNzLAogCSAgICB9CiAJfQogCisgICAgICBpZiAodmFsX3Bv c19wKQorCSp2YWxfcG9zX3AgPSBOVUxMOworCiAgICAgICB2YWx1ZXMgPSBO VUxMOwogICAgICAgcmV0dXJuIHNldF90b19ib3R0b20gKCk7CiAgICAgfQpA QCAtMTc4NCwxMSArMTgwNSw3NCBAQCBpcGNwX2xhdHRpY2U8dmFsdHlwZT46 OmFkZF92YWx1ZSAodmFsdHlwZSBuZXd2YWwsIGNncmFwaF9lZGdlICpjcywK ICAgdmFsdWVzX2NvdW50Kys7CiAgIHZhbCA9IGFsbG9jYXRlX2FuZF9pbml0 X2lwY3BfdmFsdWUgKG5ld3ZhbCk7CiAgIHZhbC0+YWRkX3NvdXJjZSAoY3Ms IHNyY192YWwsIHNyY19pZHgsIG9mZnNldCk7Ci0gIHZhbC0+bmV4dCA9IHZh bHVlczsKLSAgdmFsdWVzID0gdmFsOworICBpZiAodmFsX3Bvc19wKQorICAg IHsKKyAgICAgIHZhbC0+bmV4dCA9ICgqdmFsX3Bvc19wKS0+bmV4dDsKKyAg ICAgICgqdmFsX3Bvc19wKS0+bmV4dCA9IHZhbDsKKyAgICAgICp2YWxfcG9z X3AgPSB2YWw7CisgICAgfQorICBlbHNlCisgICAgeworICAgICAgdmFsLT5u ZXh0ID0gdmFsdWVzOworICAgICAgdmFsdWVzID0gdmFsOworICAgIH0KKwor ICByZXR1cm4gdHJ1ZTsKK30KKworLyogUmV0dXJuIHRydWUsIGlmIGEgaXBj cF92YWx1ZSBWQUwgaXMgb3JnaW5hdGVkIGZyb20gcGFyYW1ldGVyIHZhbHVl IG9mCisgICBzZWxmLWZlZWRpbmcgcmVjdXJzaXZlIGZ1bmN0aW9uIGJ5IGFw cGx5aW5nIG5vbi1wYXNzdGhyb3VnaCBhcml0aG1ldGljCisgICB0cmFuc2Zv cm1hdGlvbi4gICovCisKK3N0YXRpYyBib29sCitzZWxmX3JlY3Vyc2l2ZWx5 X2dlbmVyYXRlZF9wIChpcGNwX3ZhbHVlPHRyZWU+ICp2YWwpCit7CisgIGNs YXNzIGlwYV9ub2RlX3BhcmFtcyAqaW5mbyA9IE5VTEw7CisKKyAgZm9yIChp cGNwX3ZhbHVlX3NvdXJjZTx0cmVlPiAqc3JjID0gdmFsLT5zb3VyY2VzOyBz cmM7IHNyYyA9IHNyYy0+bmV4dCkKKyAgICB7CisgICAgICBjZ3JhcGhfZWRn ZSAqY3MgPSBzcmMtPmNzOworCisgICAgICBpZiAoIXNyYy0+dmFsIHx8IGNz LT5jYWxsZXIgIT0gY3MtPmNhbGxlZS0+ZnVuY3Rpb25fc3ltYm9sICgpCisJ ICB8fCBzcmMtPnZhbCA9PSB2YWwpCisJcmV0dXJuIGZhbHNlOworCisgICAg ICBpZiAoIWluZm8pCisJaW5mbyA9IElQQV9OT0RFX1JFRiAoY3MtPmNhbGxl cik7CisKKyAgICAgIGNsYXNzIGlwY3BfcGFyYW1fbGF0dGljZXMgKnBsYXRz ID0gaXBhX2dldF9wYXJtX2xhdHRpY2VzIChpbmZvLAorCQkJCQkJCQlzcmMt PmluZGV4KTsKKyAgICAgIGlwY3BfbGF0dGljZTx0cmVlPiAqc3JjX2xhdCA9 IHNyYy0+b2Zmc2V0ID09IC0xID8gJnBsYXRzLT5pdHNlbGYKKwkJCQkJCSAg ICAgIDogcGxhdHMtPmFnZ3M7CisgICAgICBpcGNwX3ZhbHVlPHRyZWU+ICpz cmNfdmFsOworCisgICAgICBmb3IgKHNyY192YWwgPSBzcmNfbGF0LT52YWx1 ZXM7IHNyY192YWwgJiYgc3JjX3ZhbCAhPSB2YWw7CisJICAgc3JjX3ZhbCA9 IHNyY192YWwtPm5leHQpOworCisgICAgICBpZiAoIXNyY192YWwpCisJcmV0 dXJuIGZhbHNlOworICAgIH0KKwogICByZXR1cm4gdHJ1ZTsKIH0KIAorc3Rh dGljIHRyZWUKK2dldF92YWxfYWNyb3NzX2FyaXRoX29wIChlbnVtIHRyZWVf Y29kZSBvcGNvZGUsCisJCQkgdHJlZSBvcG5kMV90eXBlLAorCQkJIHRyZWUg b3BuZDIsCisJCQkgaXBjcF92YWx1ZTx0cmVlPiAqc3JjX3ZhbCwKKwkJCSB0 cmVlIHJlc190eXBlKQoreworICB0cmVlIG9wbmQxID0gc3JjX3ZhbC0+dmFs dWU7CisKKyAgLyogU2tpcCBzb3VyY2UgdmFsdWVzIHRoYXQgaXMgaW5jb21w YXRpYmxlIHdpdGggc3BlY2lmaWVkIHR5cGUuICAqLworICBpZiAob3BuZDFf dHlwZQorICAgICAgJiYgIXVzZWxlc3NfdHlwZV9jb252ZXJzaW9uX3AgKG9w bmQxX3R5cGUsIFRSRUVfVFlQRSAob3BuZDEpKSkKKyAgICByZXR1cm4gTlVM TF9UUkVFOworCisgIHJldHVybiBpcGFfZ2V0X2pmX2FyaXRoX3Jlc3VsdCAo b3Bjb2RlLCBvcG5kMSwgb3BuZDIsIHJlc190eXBlKTsKK30KKwogLyogUHJv cGFnYXRlIHZhbHVlcyB0aHJvdWdoIGFuIGFyaXRobWV0aWMgdHJhbnNmb3Jt YXRpb24gZGVzY3JpYmVkIGJ5IGEganVtcAogICAgZnVuY3Rpb24gYXNzb2Np YXRlZCB3aXRoIGVkZ2UgQ1MsIHRha2luZyB2YWx1ZXMgZnJvbSBTUkNfTEFU IGFuZCBwdXR0aW5nCiAgICB0aGVtIGludG8gREVTVF9MQVQuICBPUE5EMV9U WVBFIGlzIGV4cGVjdGVkIHR5cGUgZm9yIHRoZSB2YWx1ZXMgaW4gU1JDX0xB VC4KQEAgLTE4MTIsMjQgKzE4OTYsNzAgQEAgcHJvcGFnYXRlX3ZhbHNfYWNy b3NzX2FyaXRoX2pmdW5jIChjZ3JhcGhfZWRnZSAqY3MsCiAgIGlwY3BfdmFs dWU8dHJlZT4gKnNyY192YWw7CiAgIGJvb2wgcmV0ID0gZmFsc2U7CiAKLSAg LyogRG8gbm90IGNyZWF0ZSBuZXcgdmFsdWVzIHdoZW4gcHJvcGFnYXRpbmcg d2l0aGluIGFuIFNDQyBiZWNhdXNlIGlmIHRoZXJlCi0gICAgIGFyZSBhcml0 aG1ldGljIGZ1bmN0aW9ucyB3aXRoIGNpcmN1bGFyIGRlcGVuZGVuY2llcywg dGhlcmUgaXMgaW5maW5pdGUKLSAgICAgbnVtYmVyIG9mIHRoZW0gYW5kIHdl IHdvdWxkIGp1c3QgbWFrZSBsYXR0aWNlcyBib3R0b20uICBJZiB0aGlzIGNv bmRpdGlvbgotICAgICBpcyBldmVyIHJlbGF4ZWQgd2UgaGF2ZSB0byBkZXRl Y3Qgc2VsZi1mZWVkaW5nIHJlY3Vyc2l2ZSBjYWxscyBpbgotICAgICBjZ3Jh cGhfZWRnZV9icmluZ3NfdmFsdWVfcCBpbiBhIHNtYXJ0ZXIgd2F5LiAgKi8K KyAgLyogRHVlIHRvIGNpcmN1bGFyIGRlcGVuZGVuY2llcywgcHJvcGFnYXRp bmcgd2l0aGluIGFuIFNDQyB0aHJvdWdoIGFyaXRobWV0aWMKKyAgICAgdHJh bnNmb3JtYXRpb24gd291bGQgY3JlYXRlIGluZmluaXRlIG51bWJlciBvZiB2 YWx1ZXMuICBCdXQgZm9yCisgICAgIHNlbGYtZmVlZGluZyByZWN1cnNpdmUg ZnVuY3Rpb24sIHdlIGNvdWxkIGFsbG93IHByb3BhZ2F0aW9uIGluIGEgbGlt aXRlZAorICAgICBjb3VudCwgYW5kIHRoaXMgY2FuIGVuYWJsZSBhIHNpbXBs ZSBraW5kIG9mIHJlY3Vyc2l2ZSBmdW5jdGlvbiB2ZXJzaW9uaW5nLgorICAg ICBGb3Igb3RoZXIgc2NlbmFyaW8sIHdlIHdvdWxkIGp1c3QgbWFrZSBsYXR0 aWNlcyBib3R0b20uICAqLwogICBpZiAob3Bjb2RlICE9IE5PUF9FWFBSICYm IGlwYV9lZGdlX3dpdGhpbl9zY2MgKGNzKSkKLSAgICByZXQgPSBkZXN0X2xh dC0+c2V0X2NvbnRhaW5zX3ZhcmlhYmxlICgpOworICAgIHsKKyAgICAgIGlm IChzcmNfbGF0ICE9IGRlc3RfbGF0KQorCXJldHVybiBkZXN0X2xhdC0+c2V0 X2NvbnRhaW5zX3ZhcmlhYmxlICgpOworCisgICAgICBhdXRvX3ZlYzxpcGNw X3ZhbHVlPHRyZWU+ICosIDg+IHZhbF9zZWVkczsKKworICAgICAgZm9yIChz cmNfdmFsID0gc3JjX2xhdC0+dmFsdWVzOyBzcmNfdmFsOyBzcmNfdmFsID0g c3JjX3ZhbC0+bmV4dCkKKwl7CisJICAvKiBOb3cgd2UgZG8gbm90IHVzZSBz ZWxmLXJlY3Vyc2l2ZWx5IGdlbmVyYXRlZCB2YWx1ZSBhcyBwcm9wYWdhdGlv bgorCSAgICAgc291cmNlLCB0aGlzIGlzIGFic29sdXRlbHkgY29uc2VydmF0 aXZlLCBidXQgY291bGQgYXZvaWQgZXhwbG9zaW9uCisJICAgICBvZiBsYXR0 aWNlJ3MgdmFsdWUgc3BhY2UsIGVzcGVjaWFsbHkgd2hlbiBvbmUgcmVjdXJz aXZlIGZ1bmN0aW9uCisJICAgICBjYWxscyBhbm90aGVyIHJlY3Vyc2l2ZS4g ICovCisJICBpZiAoc2VsZl9yZWN1cnNpdmVseV9nZW5lcmF0ZWRfcCAoc3Jj X3ZhbCkpCisJICAgIHsKKwkgICAgICAvKiBJZiB0aGUgbGF0dGljZSBoYXMg YWxyZWFkeSBiZWVuIHByb3BhZ2F0ZWQgZm9yIHRoZSBjYWxsIHNpdGUsCisJ CSBubyBuZWVkIHRvIGRvIHRoYXQgYWdhaW4uICAqLworCSAgICAgIGZvciAo aXBjcF92YWx1ZV9zb3VyY2U8dHJlZT4gKnMgPSBzcmNfdmFsLT5zb3VyY2Vz OyBzOworCQkgICBzID0gcy0+bmV4dCkKKwkJaWYgKHMtPmNzID09IGNzKQor CQkgIHJldHVybiBkZXN0X2xhdC0+c2V0X2NvbnRhaW5zX3ZhcmlhYmxlICgp OworCSAgICB9CisJICBlbHNlCisJICAgIHZhbF9zZWVkcy5zYWZlX3B1c2gg KHNyY192YWwpOworCX0KKworICAgICAgaW50IGNsb25lX2NvcGllcyA9IFBB UkFNX1ZBTFVFIChQQVJBTV9JUEFfQ1BfTUFYX1JFQ1VSU0lPTl9DT1BJRVMp OworICAgICAgaW50IGk7CisKKyAgICAgIC8qIFJlY3Vyc2l2ZWx5IGdlbmVy YXRlIGxhdHRpY2UgdmFsdWVzIHdpdGggYSBsaW1pdGVkIGNvdW50LiAgKi8K KyAgICAgIEZPUl9FQUNIX1ZFQ19FTFQgKHZhbF9zZWVkcywgaSwgc3JjX3Zh bCkKKwl7CisJICBmb3IgKGludCBqID0gMTsgaiA8IGNsb25lX2NvcGllczsg aisrKQorCSAgICB7CisJICAgICAgdHJlZSBjc3R2YWwgPSBnZXRfdmFsX2Fj cm9zc19hcml0aF9vcCAob3Bjb2RlLCBvcG5kMV90eXBlLCBvcG5kMiwKKwkJ CQkJCSAgICAgc3JjX3ZhbCwgcmVzX3R5cGUpOworCSAgICAgIGlmICghY3N0 dmFsKQorCQlicmVhazsKKworCSAgICAgIC8qIFRyeSB0byBwbGFjZSB0aGUg bmV3IGxhdHRpY2UgdmFsdWUgYWZ0ZXIgaXRzIHNvdXJjZSwgd2hpY2gKKwkJ IGNhbiBkZWNyZWFzZSBpdGVyYXRpb25zIG9mIHByb3BhZ2F0ZSBzdGFnZS4g ICovCisJICAgICAgcmV0IHw9IGRlc3RfbGF0LT5hZGRfdmFsdWUgKGNzdHZh bCwgY3MsIHNyY192YWwsIHNyY19pZHgsCisJCQkJCSAgc3JjX29mZnNldCwg JnNyY192YWwsIHRydWUpOworCSAgICAgIGdjY19jaGVja2luZ19hc3NlcnQg KHNyY192YWwpOworCSAgICB9CisJfQorICAgICAgcmV0IHw9IGRlc3RfbGF0 LT5zZXRfY29udGFpbnNfdmFyaWFibGUgKCk7CisgICAgfQogICBlbHNlCiAg ICAgZm9yIChzcmNfdmFsID0gc3JjX2xhdC0+dmFsdWVzOyBzcmNfdmFsOyBz cmNfdmFsID0gc3JjX3ZhbC0+bmV4dCkKICAgICAgIHsKLQl0cmVlIG9wbmQx ID0gc3JjX3ZhbC0+dmFsdWU7Ci0JdHJlZSBjc3R2YWwgPSBOVUxMX1RSRUU7 Ci0KLQkvKiBTa2lwIHNvdXJjZSB2YWx1ZXMgdGhhdCBpcyBpbmNvbXBhdGli bGUgd2l0aCBzcGVjaWZpZWQgdHlwZS4gICovCi0JaWYgKCFvcG5kMV90eXBl Ci0JICAgIHx8IHVzZWxlc3NfdHlwZV9jb252ZXJzaW9uX3AgKG9wbmQxX3R5 cGUsIFRSRUVfVFlQRSAob3BuZDEpKSkKLQkgIGNzdHZhbCA9IGlwYV9nZXRf amZfYXJpdGhfcmVzdWx0IChvcGNvZGUsIG9wbmQxLCBvcG5kMiwgcmVzX3R5 cGUpOworCSAgLyogTm93IHdlIGRvIG5vdCB1c2Ugc2VsZi1yZWN1cnNpdmVs eSBnZW5lcmF0ZWQgdmFsdWUgYXMgcHJvcGFnYXRpb24KKwkgICAgIHNvdXJj ZSwgb3RoZXJ3aXNlIGl0IGlzIGVhc3kgdG8gbWFrZSB2YWx1ZSBzcGFjZSBv ZiBub3JtYWwgbGF0dGljZQorCSAgICAgb3ZlcmZsb3cuICAqLworCWlmIChz ZWxmX3JlY3Vyc2l2ZWx5X2dlbmVyYXRlZF9wIChzcmNfdmFsKSkKKwkgIGNv bnRpbnVlOwogCisJdHJlZSBjc3R2YWwgPSBnZXRfdmFsX2Fjcm9zc19hcml0 aF9vcCAob3Bjb2RlLCBvcG5kMV90eXBlLCBvcG5kMiwKKwkJCQkJICAgICAg IHNyY192YWwsIHJlc190eXBlKTsKIAlpZiAoY3N0dmFsKQogCSAgcmV0IHw9 IGRlc3RfbGF0LT5hZGRfdmFsdWUgKGNzdHZhbCwgY3MsIHNyY192YWwsIHNy Y19pZHgsCiAJCQkJICAgICAgc3JjX29mZnNldCk7CkBAIC0zODUxLDYgKzM5 ODEsOSBAQCBnZXRfaW5mb19hYm91dF9uZWNlc3NhcnlfZWRnZXMgKGlwY3Bf dmFsdWU8dmFsdHlwZT4gKnZhbCwgY2dyYXBoX25vZGUgKmRlc3QsCiAJICAg ICAgaG90IHw9IGNzLT5tYXliZV9ob3RfcCAoKTsKIAkgICAgICBpZiAoY3Mt PmNhbGxlciAhPSBkZXN0KQogCQlub25fc2VsZl9yZWN1cnNpdmUgPSB0cnVl OworCSAgICAgIGVsc2UgaWYgKHNyYy0+dmFsKQorCQlnY2NfYXNzZXJ0ICh2 YWx1ZXNfZXF1YWxfZm9yX2lwY3BfcCAoc3JjLT52YWwtPnZhbHVlLAorCQkJ CQkJICAgICB2YWwtPnZhbHVlKSk7CiAJICAgIH0KIAkgIGNzID0gZ2V0X25l eHRfY2dyYXBoX2VkZ2VfY2xvbmUgKGNzKTsKIAl9CmRpZmYgLS1naXQgYS9n Y2MvcGFyYW1zLmRlZiBiL2djYy9wYXJhbXMuZGVmCmluZGV4IDMyMmMzN2Y4 Yjk2Li4zZTI0MmUwOWYwMSAxMDA2NDQKLS0tIGEvZ2NjL3BhcmFtcy5kZWYK KysrIGIvZ2NjL3BhcmFtcy5kZWYKQEAgLTExMzUsNiArMTEzNSwxMSBAQCBE RUZQQVJBTSAoUEFSQU1fSVBBX0NQX1JFQ1VSU0lPTl9QRU5BTFRZLAogCSAg ImFyZSBldmFsdWF0ZWQgZm9yIGNsb25pbmcuIiwKIAkgIDQwLCAwLCAxMDAp CiAKK0RFRlBBUkFNIChQQVJBTV9JUEFfQ1BfTUFYX1JFQ1VSU0lPTl9DT1BJ RVMsCisJICAiaXBhLWNwLW1heC1yZWN1cnNpb24tY29waWVzIiwKKwkgICJN YXhpbXVtIGZ1bmN0aW9uIHZlcnNpb25pbmcgY29waWVzIGZvciBhIHNlbGYt cmVjdXJzaXZlIGZ1bmN0aW9uLiIsCisJICA4LCAwLCAwKQorCiBERUZQQVJB TSAoUEFSQU1fSVBBX0NQX1NJTkdMRV9DQUxMX1BFTkFMVFksCiAJICAiaXBh LWNwLXNpbmdsZS1jYWxsLXBlbmFsdHkiLAogCSAgIlBlcmNlbnRhZ2UgcGVu YWx0eSBmdW5jdGlvbnMgY29udGFpbmluZyBhIHNpbmdsZSBjYWxsIHRvIGFu b3RoZXIgIgpkaWZmIC0tZ2l0IGEvZ2NjL3Rlc3RzdWl0ZS9nY2MuZGcvaXBh L2lwYS1jbG9uZS0yLmMgYi9nY2MvdGVzdHN1aXRlL2djYy5kZy9pcGEvaXBh LWNsb25lLTIuYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAw MDAwMC4uZjcwZmIxMTBjNjcKLS0tIC9kZXYvbnVsbAorKysgYi9nY2MvdGVz dHN1aXRlL2djYy5kZy9pcGEvaXBhLWNsb25lLTIuYwpAQCAtMCwwICsxLDQ3 IEBACisvKiB7IGRnLWRvIGNvbXBpbGUgfSAqLworLyogeyBkZy1vcHRpb25z ICItTzMgLWZkdW1wLWlwYS1jcC1kZXRhaWxzIC1mbm8tZWFybHktaW5saW5p bmcgLS1wYXJhbSBpcGEtY3AtbWF4LXJlY3Vyc2lvbi1jb3BpZXM9OCIgfSAq LworCitpbnQgZm4oKTsKKworaW50IGRhdGFbMTAwXTsKKworaW50IHJlY3Vy X2ZuIChpbnQgaSkKK3sKKyAgaW50IGo7CisgICAKKyAgaWYgKGkgPT0gNikK KyAgICB7CisgICAgICBmbigpOworICAgICAgZm4oKTsKKyAgICAgIGZuKCk7 CisgICAgICBmbigpOworICAgICAgZm4oKTsKKyAgICAgIGZuKCk7CisgICAg ICBmbigpOworICAgICAgZm4oKTsKKyAgICAgIGZuKCk7CisgICAgICBmbigp OworICAgICAgZm4oKTsKKyAgICAgIGZuKCk7CisgICAgICByZXR1cm4gMTA7 CisgICAgfQorCisgIGRhdGFbaV0gPSBpOyAKKworICBmb3IgKGogPSAwOyBq IDwgMTAwOyBqKyspCisgICAgcmVjdXJfZm4gKGkgKyAxKTsKKworICByZXR1 cm4gaTsgCit9CisKK2ludCBtYWluICgpCit7CisgIGludCBpOworCisgIGZv ciAoaSA9IDA7IGkgPCAxMDA7IGkrKykKKyAgICByZWN1cl9mbiAoMSkgKyBy ZWN1cl9mbiAoLTUpOworCisgIHJldHVybiAxOworfQorCisvKiB7IGRnLWZp bmFsIHsgc2Nhbi1pcGEtZHVtcC10aW1lcyAiQ3JlYXRpbmcgYSBzcGVjaWFs aXplZCBub2RlIG9mIHJlY3VyX2ZuL1xbMC05XF0qXFwuIiAxMiAiY3AiIH0g fSAqLwotLSAKMi4xNy4xCgo= --_002_BYAPR01MB48691A96BE0A2BECB51A5D70F76A0BYAPR01MB4869prod_--