From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-lf1-x12c.google.com (mail-lf1-x12c.google.com [IPv6:2a00:1450:4864:20::12c]) by sourceware.org (Postfix) with ESMTPS id 4222C3858400 for ; Thu, 11 Nov 2021 06:23:34 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 4222C3858400 Received: by mail-lf1-x12c.google.com with SMTP id l22so11715984lfg.7 for ; Wed, 10 Nov 2021 22:23:34 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:mime-version:references:in-reply-to:from:date :message-id:subject:to:cc; bh=WICbzi9g5wH98k1E5yDN+UDnXaN8HnqUBfnGkpPa/00=; b=1vj0gWCNhZLp1GFgQkhTQ9V3xZj2r+m20SXM19UoORr5fIsxhNpUPfTZ8T3ogVt/te ChZKXpdFhHokEp2x3wughwxsekpCdZpZIoME56Gu/6ttQrgSFbUIVPYzz4avZZvc40EX JJzTXknkdPKvy5MWxdTQ08ojrprZH8yNtDs1G2LeH50QM0RwHA6So19JoGkrWQr/GpN4 0JEco5JVBf4oH19+5MR74nd9lBwD5EegQdIvq0Ott7KYfrlnzviCYD0aHF9J9lbcE9Mf FUnIuSfmNXRjho90+ZTXW7qJRyAO4+YgV/2DuMrCe02GNi+96cqs/b1XJUSaI/HyKNjw UTWA== X-Gm-Message-State: AOAM531iycZw0CJI5WEWGjLL2GEKqgFKCODihNYqb7047+JuwmaRqk9/ Y6ekeSbAYGqCwPFAy2v0yrVmFuNSB6n8VfzG9VaWPsrUFTE= X-Google-Smtp-Source: ABdhPJzb2xphJj3c823hmY+KIO7IZRIzi1mJpD4PnZeOuhNyxAPKlv/BHkL6ExS47b06EagaXJMoXYvVU9XsNTszTjk= X-Received: by 2002:a05:6512:158a:: with SMTP id bp10mr3533056lfb.521.1636611812753; Wed, 10 Nov 2021 22:23:32 -0800 (PST) MIME-Version: 1.0 References: <09b881f7d70ea379a476898dbb01e812b1490bbd.camel@klomp.org> In-Reply-To: <09b881f7d70ea379a476898dbb01e812b1490bbd.camel@klomp.org> From: Jacob Burkholder Date: Wed, 10 Nov 2021 22:23:21 -0800 Message-ID: Subject: Re: unwind non-PC registers using elfutils To: Mark Wielaard Cc: elfutils-devel@sourceware.org Content-Type: multipart/mixed; boundary="000000000000bc1ffc05d07d6167" X-Spam-Status: No, score=-0.1 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, FREEMAIL_ENVFROM_END_DIGIT, FREEMAIL_FROM, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.4 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on server2.sourceware.org X-BeenThere: elfutils-devel@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Elfutils-devel mailing list List-Unsubscribe: , List-Archive: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 11 Nov 2021 06:23:36 -0000 --000000000000bc1ffc05d07d6167 Content-Type: text/plain; charset="UTF-8" Hi Mark, thanks for your mail. On Wed, Nov 10, 2021 at 6:09 AM Mark Wielaard wrote: > > Hi Jacob, > > On Sun, 2021-10-03 at 09:38 -0700, Jacob Burkholder via Elfutils-devel wrote: > > Hi, I'm trying to figure out how to unwind registers other than the PC > > using elfutils. I can use dwfl_module_register_names to get the register > > names, and then I'm trying to use dwarf_frame_register to get the register > > values for a given frame. I looked at the code in __libdwfl_frame_unwind > > and there's another example in addrcfi.c. dwarf_frame_register seems > > quite a low level dwarf API, I'm not sure how to use the ops that are > > returned, also the code used by __libdwfl_frame_unwind to evaluate the ops > > is all static or internal so not callable. Any guidance? Do I need to > > basically interpret the dwarf atoms in the ops returned by > > dwarf_frame_register? Any plans to make code like > > frame_unwind.c:expr_eval() used by frame_unwind.c:handle_cfi externally > > accessible? > > Sorry for the late reply. I missed this message earlier. As you > correctly observe the public API only supports unwinding of threads for > backtraces with just the PC. Internally most of the logic of unwinding > other registers is there, but we don't have a public API for it. We > really should. I filed: > https://sourceware.org/bugzilla/show_bug.cgi?id=28579 > > Could you add some requirements there? > The hard part is making sure the interface is actually useful. > What information do you have and what information do you want to get > out? I developed a patch against elfutils-0.185 which adds some APIs I use that do what I want, it also includes some bug fixes. It is just a proof of concept at this point. I exported __libdwfl_frame_reg_get and __libdwfl_frame_reg_set and I also added an exported wrapper function for expr_eval. I added dwfl_module_getebl as a convenience, any code that uses the disasm functions needs an ebl pointer, Dwfl_Module has one but there's no way to get at it and creating a new ebl instance just to disassemble can be error prone. Getting the unwound register values was easy, they're already unwound there's just no way to read them from the Dwfl_Frame. Unwinding function parameters and local variables was a bit harder and I needed to be able to call expr_eval. The basic usage model is pretty much the same as expr_eval is used inside of elfutils: 1. Call dwarf_getscopes with the pc of the frame of interest. 2. Find the enclosing DW_TAG_subprogram or DW_TAG_inlined_subroutine. 3. For each DW_TAG_formal_parameter or DW_TAG_variable child, find the DW_AT_location, then call dwarf_getlocations and find the location that corresponds to the pc. 4. Call __libdwfl_expr_eval and pass in the ops and nops, the value is returned. I currently always pass NULL for the Dwarf_Frame, it doesn't look that complicated to get the Dwarf_Frame to pass in but I'm not sure in which cases it is needed. There's some header mess adding these functions to libdwfl.h because the Dwarf types are defined in libdw.h. > > Thanks, > > Mark --000000000000bc1ffc05d07d6167 Content-Type: text/x-chdr; charset="US-ASCII"; name="0-libdwfl.h" Content-Disposition: attachment; filename="0-libdwfl.h" Content-Transfer-Encoding: base64 Content-ID: X-Attachment-Id: f_kvukd0zb0 ZGlmZiAtTnJ1IGVsZnV0aWxzLTAuMTg1Lm9yaWcvYmFja2VuZHMveDg2XzY0X2luaXQuYyBlbGZ1 dGlscy0wLjE4NS9iYWNrZW5kcy94ODZfNjRfaW5pdC5jCi0tLSBlbGZ1dGlscy0wLjE4NS5vcmln L2JhY2tlbmRzL3g4Nl82NF9pbml0LmMJMjAyMS0wNS0yMiAxMToyNToyNC4wMDAwMDAwMDAgLTA3 MDAKKysrIGVsZnV0aWxzLTAuMTg1L2JhY2tlbmRzL3g4Nl82NF9pbml0LmMJMjAyMS0xMC0wMyAy MjoxMTo0Ny4wNTA2NTE2NjEgLTA3MDAKQEAgLTYwLDcgKzYwLDcgQEAKICAgSE9PSyAoZWgsIGRp c2FzbSk7CiAgIEhPT0sgKGVoLCBhYmlfY2ZpKTsKICAgLyogZ2NjL2NvbmZpZy8gI2RlZmluZSBE V0FSRl9GUkFNRV9SRUdJU1RFUlMuICAqLwotICBlaC0+ZnJhbWVfbnJlZ3MgPSAxNzsKKyAgZWgt PmZyYW1lX25yZWdzID0gNjc7CiAgIEhPT0sgKGVoLCBzZXRfaW5pdGlhbF9yZWdpc3RlcnNfdGlk KTsKICAgSE9PSyAoZWgsIHVud2luZCk7CiAgIEhPT0sgKGVoLCBjaGVja19yZWxvY190YXJnZXRf dHlwZSk7CmRpZmYgLU5ydSBlbGZ1dGlscy0wLjE4NS5vcmlnL2JhY2tlbmRzL3g4Nl82NF9pbml0 cmVnLmMgZWxmdXRpbHMtMC4xODUvYmFja2VuZHMveDg2XzY0X2luaXRyZWcuYwotLS0gZWxmdXRp bHMtMC4xODUub3JpZy9iYWNrZW5kcy94ODZfNjRfaW5pdHJlZy5jCTIwMjEtMDUtMjIgMTE6MjU6 MjQuMDAwMDAwMDAwIC0wNzAwCisrKyBlbGZ1dGlscy0wLjE4NS9iYWNrZW5kcy94ODZfNjRfaW5p dHJlZy5jCTIwMjEtMTAtMDMgMjE6NTI6NDIuMjUxMTI5NzY0IC0wNzAwCkBAIC02OCw2ICs2OCwy MSBAQAogICBkd2FyZl9yZWdzWzE0XSA9IHVzZXJfcmVncy5yMTQ7CiAgIGR3YXJmX3JlZ3NbMTVd ID0gdXNlcl9yZWdzLnIxNTsKICAgZHdhcmZfcmVnc1sxNl0gPSB1c2VyX3JlZ3MucmlwOwotICBy ZXR1cm4gc2V0ZnVuYyAoMCwgMTcsIGR3YXJmX3JlZ3MsIGFyZyk7CisgIGlmICghc2V0ZnVuYyAo MCwgMTcsIGR3YXJmX3JlZ3MsIGFyZykpCisgICAgcmV0dXJuIGZhbHNlOworICBkd2FyZl9yZWdz WzBdID0gdXNlcl9yZWdzLmVmbGFnczsKKyAgZHdhcmZfcmVnc1sxXSA9IHVzZXJfcmVncy5lczsK KyAgZHdhcmZfcmVnc1syXSA9IHVzZXJfcmVncy5jczsKKyAgZHdhcmZfcmVnc1szXSA9IHVzZXJf cmVncy5zczsKKyAgZHdhcmZfcmVnc1s0XSA9IHVzZXJfcmVncy5kczsKKyAgZHdhcmZfcmVnc1s1 XSA9IHVzZXJfcmVncy5mczsKKyAgZHdhcmZfcmVnc1s2XSA9IHVzZXJfcmVncy5nczsKKyAgaWYg KCFzZXRmdW5jICg0OSwgNywgZHdhcmZfcmVncywgYXJnKSkKKyAgICByZXR1cm4gZmFsc2U7Cisg IGR3YXJmX3JlZ3NbMF0gPSB1c2VyX3JlZ3MuZnNfYmFzZTsKKyAgZHdhcmZfcmVnc1sxXSA9IHVz ZXJfcmVncy5nc19iYXNlOworICBpZiAoIXNldGZ1bmMgKDU4LCAyLCBkd2FyZl9yZWdzLCBhcmcp KQorICAgIHJldHVybiBmYWxzZTsKKyAgcmV0dXJuIHRydWU7CiAjZW5kaWYgLyogX194ODZfNjRf XyAqLwogfQpkaWZmIC1OcnUgZWxmdXRpbHMtMC4xODUub3JpZy9saWJhc20vZGlzYXNtX3N0ci5j IGVsZnV0aWxzLTAuMTg1L2xpYmFzbS9kaXNhc21fc3RyLmMKLS0tIGVsZnV0aWxzLTAuMTg1Lm9y aWcvbGliYXNtL2Rpc2FzbV9zdHIuYwkyMDIxLTA1LTIyIDExOjI1OjI0LjAwMDAwMDAwMCAtMDcw MAorKysgZWxmdXRpbHMtMC4xODUvbGliYXNtL2Rpc2FzbV9zdHIuYwkyMDIxLTEwLTEwIDEyOjEx OjQ1Ljg0MDM4MzA1OCAtMDcwMApAQCAtNTIsNyArNTIsNyBAQAogICAgIHJldHVybiBsZW4gLSBi dWZmZXItPmxlbjsKIAogICBidWZmZXItPmJ1ZiA9IG1lbXBjcHkgKGJ1ZmZlci0+YnVmLCBzdHIs IGxlbik7Ci0gIGJ1ZmZlci0+bGVuID0gbGVuOworICBidWZmZXItPmxlbiAtPSBsZW47CiAKICAg cmV0dXJuIDA7CiB9CmRpZmYgLU5ydSBlbGZ1dGlscy0wLjE4NS5vcmlnL2xpYmR3L2xpYmR3Lm1h cCBlbGZ1dGlscy0wLjE4NS9saWJkdy9saWJkdy5tYXAKLS0tIGVsZnV0aWxzLTAuMTg1Lm9yaWcv bGliZHcvbGliZHcubWFwCTIwMjEtMDUtMjIgMTE6MjU6MjQuMDAwMDAwMDAwIC0wNzAwCisrKyBl bGZ1dGlscy0wLjE4NS9saWJkdy9saWJkdy5tYXAJMjAyMS0xMC0xOCAyMjo0Njo1OS4wMzMwNzUw NjAgLTA3MDAKQEAgLTM2MCwzICszNjAsMTEgQEAKICAgICAjIHByZXN1bWUgdGhhdCBOVUxMIGlz IG9ubHkgcmV0dXJuZWQgb24gZXJyb3IgKG90aGVyd2lzZSBFTEZfS19OT05FKS4KICAgICBkd2Vs Zl9lbGZfYmVnaW47CiB9IEVMRlVUSUxTXzAuMTc1OworCitFTEZVVElMU18wLjE4NSB7CisgIGds b2JhbDoKKyAgICBfX2xpYmR3ZmxfZnJhbWVfcmVnX2dldDsKKyAgICBfX2xpYmR3ZmxfZnJhbWVf cmVnX3NldDsKKyAgICBkd2ZsX21vZHVsZV9nZXRlYmw7CisgICAgX19saWJkd2ZsX2V4cHJfZXZh bDsKK30gRUxGVVRJTFNfMC4xNzc7CmRpZmYgLU5ydSBlbGZ1dGlscy0wLjE4NS5vcmlnL2xpYmR3 ZmwvZHdmbF9tb2R1bGVfZ2V0ZHdhcmYuYyBlbGZ1dGlscy0wLjE4NS9saWJkd2ZsL2R3ZmxfbW9k dWxlX2dldGR3YXJmLmMKLS0tIGVsZnV0aWxzLTAuMTg1Lm9yaWcvbGliZHdmbC9kd2ZsX21vZHVs ZV9nZXRkd2FyZi5jCTIwMjEtMDUtMjIgMTE6MjU6MjQuMDAwMDAwMDAwIC0wNzAwCisrKyBlbGZ1 dGlscy0wLjE4NS9saWJkd2ZsL2R3ZmxfbW9kdWxlX2dldGR3YXJmLmMJMjAyMS0xMC0xMCAxMDo1 MjowNi4yMDQ2OTQ4MjEgLTA3MDAKQEAgLTEyOTYsNiArMTI5NiwxMiBAQAogICAgIH0KIH0KIAor dm9pZCAqCitkd2ZsX21vZHVsZV9nZXRlYmwgKER3ZmxfTW9kdWxlICptb2QpCit7CisgIF9fbGli ZHdmbF9tb2R1bGVfZ2V0ZWJsIChtb2QpOworICByZXR1cm4gbW9kLT5lYmw7Cit9CiAKIC8qIFRy eSB0byBvcGVuIGEgbGliZWJsIGJhY2tlbmQgZm9yIE1PRC4gICovCiBEd2ZsX0Vycm9yCmRpZmYg LU5ydSBlbGZ1dGlscy0wLjE4NS5vcmlnL2xpYmR3ZmwvZnJhbWVfdW53aW5kLmMgZWxmdXRpbHMt MC4xODUvbGliZHdmbC9mcmFtZV91bndpbmQuYwotLS0gZWxmdXRpbHMtMC4xODUub3JpZy9saWJk d2ZsL2ZyYW1lX3Vud2luZC5jCTIwMjEtMDUtMjIgMTE6MjU6MjQuMDAwMDAwMDAwIC0wNzAwCisr KyBlbGZ1dGlscy0wLjE4NS9saWJkd2ZsL2ZyYW1lX3Vud2luZC5jCTIwMjEtMTAtMTggMjI6NDM6 NTAuMzU3MjA5NjM0IC0wNzAwCkBAIC00NCw3ICs0NCw2IEBACiAjZGVmaW5lIERXQVJGX0VYUFJf U1RFUFNfTUFYIDB4MTAwMAogCiBib29sCi1pbnRlcm5hbF9mdW5jdGlvbgogX19saWJkd2ZsX2Zy YW1lX3JlZ19nZXQgKER3ZmxfRnJhbWUgKnN0YXRlLCB1bnNpZ25lZCByZWdubywgRHdhcmZfQWRk ciAqdmFsKQogewogICBFYmwgKmVibCA9IHN0YXRlLT50aHJlYWQtPnByb2Nlc3MtPmVibDsKQEAg LTYxLDcgKzYwLDYgQEAKIH0KIAogYm9vbAotaW50ZXJuYWxfZnVuY3Rpb24KIF9fbGliZHdmbF9m cmFtZV9yZWdfc2V0IChEd2ZsX0ZyYW1lICpzdGF0ZSwgdW5zaWduZWQgcmVnbm8sIER3YXJmX0Fk ZHIgdmFsKQogewogICBFYmwgKmVibCA9IHN0YXRlLT50aHJlYWQtPnByb2Nlc3MtPmVibDsKQEAg LTUwNyw2ICs1MDUsMTMgQEAKICN1bmRlZiBwb3AKIH0KIAorYm9vbAorX19saWJkd2ZsX2V4cHJf ZXZhbCAoRHdmbF9GcmFtZSAqc3RhdGUsIER3YXJmX0ZyYW1lICpmcmFtZSwgY29uc3QgRHdhcmZf T3AgKm9wcywKKyAgc2l6ZV90IG5vcHMsIER3YXJmX0FkZHIgKnJlc3VsdCwgRHdhcmZfQWRkciBi aWFzKQoreworICByZXR1cm4gZXhwcl9ldmFsKHN0YXRlLCBmcmFtZSwgb3BzLCBub3BzLCByZXN1 bHQsIGJpYXMpOworfQorCiBzdGF0aWMgRHdmbF9GcmFtZSAqCiBuZXdfdW53b3VuZCAoRHdmbF9G cmFtZSAqc3RhdGUpCiB7CmRpZmYgLU5ydSBlbGZ1dGlscy0wLjE4NS5vcmlnL2xpYmR3ZmwvbGli ZHdmbC5oIGVsZnV0aWxzLTAuMTg1L2xpYmR3ZmwvbGliZHdmbC5oCi0tLSBlbGZ1dGlscy0wLjE4 NS5vcmlnL2xpYmR3ZmwvbGliZHdmbC5oCTIwMjEtMDUtMjIgMTE6MjU6MjQuMDAwMDAwMDAwIC0w NzAwCisrKyBlbGZ1dGlscy0wLjE4NS9saWJkd2ZsL2xpYmR3ZmwuaAkyMDIxLTEwLTE4IDIyOjQ1 OjIzLjA2NTEzODg5OSAtMDcwMApAQCAtNzk1LDYgKzc5NSwyMyBAQAogYm9vbCBkd2ZsX2ZyYW1l X3BjIChEd2ZsX0ZyYW1lICpzdGF0ZSwgRHdhcmZfQWRkciAqcGMsIGJvb2wgKmlzYWN0aXZhdGlv bikKICAgX19ub25udWxsX2F0dHJpYnV0ZV9fICgxLCAyKTsKIAorLyogRmV0Y2ggdmFsdWUgZnJv bSBEd2ZsX0ZyYW1lLT5yZWdzIGluZGV4ZWQgYnkgRFdBUkYgUkVHTk8uCisgICBObyBlcnJvciBj b2RlIGlzIHNldCBpZiB0aGUgZnVuY3Rpb24gcmV0dXJucyBGQUxTRS4gICovCitib29sIF9fbGli ZHdmbF9mcmFtZV9yZWdfZ2V0IChEd2ZsX0ZyYW1lICpzdGF0ZSwgdW5zaWduZWQgcmVnbm8sCisJ CQkgICAgICBEd2FyZl9BZGRyICp2YWwpOworCisvKiBTdG9yZSB2YWx1ZSB0byBEd2ZsX0ZyYW1l LT5yZWdzIGluZGV4ZWQgYnkgRFdBUkYgUkVHTk8uCisgICBObyBlcnJvciBjb2RlIGlzIHNldCBp ZiB0aGUgZnVuY3Rpb24gcmV0dXJucyBGQUxTRS4gICovCitib29sIF9fbGliZHdmbF9mcmFtZV9y ZWdfc2V0IChEd2ZsX0ZyYW1lICpzdGF0ZSwgdW5zaWduZWQgcmVnbm8sCisJCQkgICAgICBEd2Fy Zl9BZGRyIHZhbCk7CisKK3ZvaWQgKmR3ZmxfbW9kdWxlX2dldGVibCAoRHdmbF9Nb2R1bGUgKm1v ZCk7CisKKyNpZmRlZiBfTElCRFdfSAorYm9vbCBfX2xpYmR3ZmxfZXhwcl9ldmFsIChEd2ZsX0Zy YW1lICpzdGF0ZSwgRHdhcmZfRnJhbWUgKmZyYW1lLAorICBjb25zdCBEd2FyZl9PcCAqb3BzLCBz aXplX3Qgbm9wcywgRHdhcmZfQWRkciAqcmVzdWx0LCBEd2FyZl9BZGRyIGJpYXMpOworI2VuZGlm CisKICNpZmRlZiBfX2NwbHVzcGx1cwogfQogI2VuZGlmCmRpZmYgLU5ydSBlbGZ1dGlscy0wLjE4 NS5vcmlnL2xpYmR3ZmwvbGliZHdmbFAuaCBlbGZ1dGlscy0wLjE4NS9saWJkd2ZsL2xpYmR3ZmxQ LmgKLS0tIGVsZnV0aWxzLTAuMTg1Lm9yaWcvbGliZHdmbC9saWJkd2ZsUC5oCTIwMjEtMDUtMjIg MTE6MjU6MjQuMDAwMDAwMDAwIC0wNzAwCisrKyBlbGZ1dGlscy0wLjE4NS9saWJkd2ZsL2xpYmR3 ZmxQLmgJMjAyMS0xMC0wMyAwOTo1MzozOC44ODcxMTk1OTYgLTA3MDAKQEAgLTI3NiwxOCArMjc2 LDYgQEAKICAgRHdhcmZfQWRkciByZWdzW107CiB9OwogCi0vKiBGZXRjaCB2YWx1ZSBmcm9tIER3 ZmxfRnJhbWUtPnJlZ3MgaW5kZXhlZCBieSBEV0FSRiBSRUdOTy4KLSAgIE5vIGVycm9yIGNvZGUg aXMgc2V0IGlmIHRoZSBmdW5jdGlvbiByZXR1cm5zIEZBTFNFLiAgKi8KLWJvb2wgX19saWJkd2Zs X2ZyYW1lX3JlZ19nZXQgKER3ZmxfRnJhbWUgKnN0YXRlLCB1bnNpZ25lZCByZWdubywKLQkJCSAg ICAgIER3YXJmX0FkZHIgKnZhbCkKLSAgaW50ZXJuYWxfZnVuY3Rpb247Ci0KLS8qIFN0b3JlIHZh bHVlIHRvIER3ZmxfRnJhbWUtPnJlZ3MgaW5kZXhlZCBieSBEV0FSRiBSRUdOTy4KLSAgIE5vIGVy cm9yIGNvZGUgaXMgc2V0IGlmIHRoZSBmdW5jdGlvbiByZXR1cm5zIEZBTFNFLiAgKi8KLWJvb2wg X19saWJkd2ZsX2ZyYW1lX3JlZ19zZXQgKER3ZmxfRnJhbWUgKnN0YXRlLCB1bnNpZ25lZCByZWdu bywKLQkJCSAgICAgIER3YXJmX0FkZHIgdmFsKQotICBpbnRlcm5hbF9mdW5jdGlvbjsKLQogLyog SW5mb3JtYXRpb24gY2FjaGVkIGFib3V0IGVhY2ggQ1UgaW4gRHdmbF9Nb2R1bGUuZHcuICAqLwog c3RydWN0IGR3ZmxfY3UKIHsK --000000000000bc1ffc05d07d6167--