LyoKICogYWdlbnRfdHJhcC5jCiAqLwovKiBQb3J0aW9ucyBvZiB0aGlzIGZpbGUgYXJlIHN1YmplY3QgdG8gdGhlIGZvbGxvd2luZyBjb3B5cmlnaHQocykuICBTZWUKICogdGhlIE5ldC1TTk1QJ3MgQ09QWUlORyBmaWxlIGZvciBtb3JlIGRldGFpbHMgYW5kIG90aGVyIGNvcHlyaWdodHMKICogdGhhdCBtYXkgYXBwbHk6CiAqLwovKgogKiBQb3J0aW9ucyBvZiB0aGlzIGZpbGUgYXJlIGNvcHlyaWdodGVkIGJ5OgogKiBDb3B5cmlnaHQgqSAyMDAzIFN1biBNaWNyb3N5c3RlbXMsIEluYy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KICogVXNlIGlzIHN1YmplY3QgdG8gbGljZW5zZSB0ZXJtcyBzcGVjaWZpZWQgaW4gdGhlIENPUFlJTkcgZmlsZQogKiBkaXN0cmlidXRlZCB3aXRoIHRoZSBOZXQtU05NUCBwYWNrYWdlLgogKi8KLyoqIEBkZWZncm91cCBhZ2VudF90cmFwIFRyYXAgZ2VuZXJhdGlvbiByb3V0aW5lcyBmb3IgbWliIG1vZHVsZXMgdG8gdXNlCiAqICBAaW5ncm91cCBhZ2VudAogKgogKiBAewogKi8KCiNpbmNsdWRlIDxuZXQtc25tcC9uZXQtc25tcC1jb25maWcuaD4KI2luY2x1ZGUgPG5ldC1zbm1wL25ldC1zbm1wLWZlYXR1cmVzLmg+CgojaWYgSEFWRV9VTklTVERfSAojaW5jbHVkZSA8dW5pc3RkLmg+CiNlbmRpZgojaWYgSEFWRV9ORVREQl9ICiNpbmNsdWRlIDxuZXRkYi5oPgojZW5kaWYKI2lmIEhBVkVfU1RETElCX0gKI2luY2x1ZGUgPHN0ZGxpYi5oPgojZW5kaWYKI2lmIEhBVkVfU1RSSU5HX0gKI2luY2x1ZGUgPHN0cmluZy5oPgojZWxzZQojaW5jbHVkZSA8c3RyaW5ncy5oPgojZW5kaWYKI2lmIFRJTUVfV0lUSF9TWVNfVElNRQojIGluY2x1ZGUgPHN5cy90aW1lLmg+CiMgaW5jbHVkZSA8dGltZS5oPgojZWxzZQojIGlmIEhBVkVfU1lTX1RJTUVfSAojICBpbmNsdWRlIDxzeXMvdGltZS5oPgojIGVsc2UKIyAgaW5jbHVkZSA8dGltZS5oPgojIGVuZGlmCiNlbmRpZgojaWYgSEFWRV9TWVNfU09DS0VUX0gKI2luY2x1ZGUgPHN5cy9zb2NrZXQuaD4KI2VuZGlmCiNpZiBIQVZFX05FVElORVRfSU5fSAojaW5jbHVkZSA8bmV0aW5ldC9pbi5oPgojZW5kaWYKI2luY2x1ZGUgPG5ldC1zbm1wL3V0aWxpdGllcy5oPgoKI2luY2x1ZGUgPG5ldC1zbm1wL25ldC1zbm1wLWluY2x1ZGVzLmg+CiNpbmNsdWRlIDxuZXQtc25tcC9hZ2VudC9uZXQtc25tcC1hZ2VudC1pbmNsdWRlcy5oPgojaW5jbHVkZSA8bmV0LXNubXAvYWdlbnQvYWdlbnRfdHJhcC5oPgojaW5jbHVkZSA8bmV0LXNubXAvYWdlbnQvc25tcF9hZ2VudC5oPgojaW5jbHVkZSA8bmV0LXNubXAvYWdlbnQvYWdlbnRfY2FsbGJhY2tzLmg+CgojaW5jbHVkZSA8bmV0LXNubXAvYWdlbnQvYWdlbnRfbW9kdWxlX2NvbmZpZy5oPgojaW5jbHVkZSA8bmV0LXNubXAvYWdlbnQvbWliX21vZHVsZV9jb25maWcuaD4KCiNpZmRlZiBVU0lOR19BR0VOVFhfUFJPVE9DT0xfTU9EVUxFCiNpbmNsdWRlICJhZ2VudHgvcHJvdG9jb2wuaCIKI2VuZGlmCgpuZXRzbm1wX2ZlYXR1cmVfY2hpbGRfb2YoYWdlbnRfdHJhcF9hbGwsIGxpYm5ldHNubXBhZ2VudCkKCm5ldHNubXBfZmVhdHVyZV9jaGlsZF9vZih0cmFwX3ZhcnNfd2l0aF9jb250ZXh0LCBhZ2VudF90cmFwX2FsbCkKbmV0c25tcF9mZWF0dXJlX2NoaWxkX29mKHJlbW92ZV90cmFwX3Nlc3Npb24sIGFnZW50X3RyYXBfYWxsKQoKbmV0c25tcF9mZWF0dXJlX2NoaWxkX29mKHNlbmRfdjN0cmFwLG5ldHNubXBfdW51c2VkKQpuZXRzbm1wX2ZlYXR1cmVfY2hpbGRfb2Yoc2VuZF90cmFwX3BkdSxuZXRzbm1wX3VudXNlZCkKCnN0cnVjdCB0cmFwX3NpbmsgewogICAgbmV0c25tcF9zZXNzaW9uICpzZXNwOwogICAgc3RydWN0IHRyYXBfc2luayAqbmV4dDsKICAgIGludCAgICAgICAgICAgICBwZHV0eXBlOwogICAgaW50ICAgICAgICAgICAgIHZlcnNpb247Cn07CgpzdHJ1Y3QgdHJhcF9zaW5rICpzaW5rcyA9IE5VTEw7Cgpjb25zdCBvaWQgICAgICAgb2JqaWRfZW50ZXJwcmlzZXRyYXBbXSA9IHsgTkVUU05NUF9OT1RJRklDQVRJT05fTUlCIH07CmNvbnN0IG9pZCAgICAgICB0cmFwX3ZlcnNpb25faWRbXSA9IHsgTkVUU05NUF9TWVNURU1fTUlCIH07CmNvbnN0IGludCAgICAgICBlbnRlcnByaXNldHJhcF9sZW4gPSBPSURfTEVOR1RIKG9iamlkX2VudGVycHJpc2V0cmFwKTsKY29uc3QgaW50ICAgICAgIHRyYXBfdmVyc2lvbl9pZF9sZW4gPSBPSURfTEVOR1RIKHRyYXBfdmVyc2lvbl9pZCk7CgojZGVmaW5lIFNOTVBWMl9UUkFQU19QUkVGSVgJU05NUF9PSURfU05NUE1PRFVMRVMsMSwxLDUKY29uc3Qgb2lkICAgICAgIHRyYXBfcHJlZml4W10gICAgPSB7IFNOTVBWMl9UUkFQU19QUkVGSVggfTsKY29uc3Qgb2lkICAgICAgIGNvbGRfc3RhcnRfb2lkW10gPSB7IFNOTVBWMl9UUkFQU19QUkVGSVgsIDEgfTsgIC8qIFNOTVB2Mi1NSUIgKi8KCiNkZWZpbmUgU05NUFYyX1RSQVBfT0JKU19QUkVGSVgJU05NUF9PSURfU05NUE1PRFVMRVMsMSwxLDQKY29uc3Qgb2lkICAgICAgIHNubXB0cmFwX29pZFtdID0geyBTTk1QVjJfVFJBUF9PQkpTX1BSRUZJWCwgMSwgMCB9Owpjb25zdCBvaWQgICAgICAgc25tcHRyYXBlbnRlcnByaXNlX29pZFtdID0geyBTTk1QVjJfVFJBUF9PQkpTX1BSRUZJWCwgMywgMCB9Owpjb25zdCBvaWQgICAgICAgc3lzdXB0aW1lX29pZFtdID0geyBTTk1QX09JRF9NSUIyLCAxLCAzLCAwIH07CmNvbnN0IHNpemVfdCAgICBzbm1wdHJhcF9vaWRfbGVuID0gT0lEX0xFTkdUSChzbm1wdHJhcF9vaWQpOwpjb25zdCBzaXplX3QgICAgc25tcHRyYXBlbnRlcnByaXNlX29pZF9sZW4gPSBPSURfTEVOR1RIKHNubXB0cmFwZW50ZXJwcmlzZV9vaWQpOwpjb25zdCBzaXplX3QgICAgc3lzdXB0aW1lX29pZF9sZW4gPSBPSURfTEVOR1RIKHN5c3VwdGltZV9vaWQpOwoKI2RlZmluZSBTTk1QVjJfQ09NTV9PQkpTX1BSRUZJWAlTTk1QX09JRF9TTk1QTU9EVUxFUywxOCwxCmNvbnN0IG9pZCAgICAgICBhZ2VudGFkZHJfb2lkW10gPSB7IFNOTVBWMl9DT01NX09CSlNfUFJFRklYLCAzLCAwIH07CmNvbnN0IHNpemVfdCAgICBhZ2VudGFkZHJfb2lkX2xlbiA9IE9JRF9MRU5HVEgoYWdlbnRhZGRyX29pZCk7CmNvbnN0IG9pZCAgICAgICBjb21tdW5pdHlfb2lkW10gPSB7IFNOTVBWMl9DT01NX09CSlNfUFJFRklYLCA0LCAwIH07CmNvbnN0IHNpemVfdCAgICBjb21tdW5pdHlfb2lkX2xlbiA9IE9JRF9MRU5HVEgoY29tbXVuaXR5X29pZCk7CiNpZiAhZGVmaW5lZChORVRTTk1QX0RJU0FCTEVfU05NUFYxKSB8fCAhZGVmaW5lZChORVRTTk1QX0RJU0FCTEVfU05NUFYyQykKY2hhciAgICAgICAgICAgKnNubXBfdHJhcGNvbW11bml0eSA9IE5VTEw7CiNlbmRpZgoKCiNkZWZpbmUgU05NUF9BVVRIRU5USUNBVEVEX1RSQVBTX0VOQUJMRUQJMQojZGVmaW5lIFNOTVBfQVVUSEVOVElDQVRFRF9UUkFQU19ESVNBQkxFRAkyCgpsb25nICAgICAgICAgICAgc25tcF9lbmFibGVhdXRoZW50cmFwcyA9IFNOTVBfQVVUSEVOVElDQVRFRF9UUkFQU19ESVNBQkxFRDsKaW50ICAgICAgICAgICAgIHNubXBfZW5hYmxlYXV0aGVudHJhcHNzZXQgPSAwOwoKLyoKICogUHJvdG90eXBlcyAKICovCiAvKgogICogc3RhdGljIGludCBjcmVhdGVfdjFfdHJhcF9zZXNzaW9uIChjb25zdCBjaGFyICosIHVfc2hvcnQsIGNvbnN0IGNoYXIgKik7CiAgKiBzdGF0aWMgaW50IGNyZWF0ZV92Ml90cmFwX3Nlc3Npb24gKGNvbnN0IGNoYXIgKiwgdV9zaG9ydCwgY29uc3QgY2hhciAqKTsKICAqIHN0YXRpYyBpbnQgY3JlYXRlX3YyX2luZm9ybV9zZXNzaW9uIChjb25zdCBjaGFyICosIHVfc2hvcnQsIGNvbnN0IGNoYXIgKik7CiAgKiBzdGF0aWMgdm9pZCBmcmVlX3RyYXBfc2Vzc2lvbiAoc3RydWN0IHRyYXBfc2luayAqc3ApOwogICogc3RhdGljIHZvaWQgc2VuZF92MV90cmFwIChuZXRzbm1wX3Nlc3Npb24gKiwgaW50LCBpbnQpOwogICogc3RhdGljIHZvaWQgc2VuZF92Ml90cmFwIChuZXRzbm1wX3Nlc3Npb24gKiwgaW50LCBpbnQsIGludCk7CiAgKi8KCgogICAgICAgIC8qKioqKioqKioqKioqKioqKioqCgkgKgoJICogVHJhcCBzZXNzaW9uIGhhbmRsaW5nCgkgKgoJICoqKioqKioqKioqKioqKioqKiovCgp2b2lkCmluaXRfdHJhcHModm9pZCkKewp9CgpzdGF0aWMgdm9pZApmcmVlX3RyYXBfc2Vzc2lvbihzdHJ1Y3QgdHJhcF9zaW5rICpzcCkKewogICAgREVCVUdNU0dUTCgoInRyYXAiLCAiZnJlZWluZyBjYWxsYmFjayB0cmFwIHNlc3Npb24gKCVwLCAlcClcbiIsIHNwLCBzcC0+c2VzcCkpOwogICAgc25tcF9jbG9zZShzcC0+c2VzcCk7CiAgICBmcmVlKHNwKTsKfQoKaW50CmFkZF90cmFwX3Nlc3Npb24obmV0c25tcF9zZXNzaW9uICogc3MsIGludCBwZHV0eXBlLCBpbnQgY29uZmlybSwKICAgICAgICAgICAgICAgICBpbnQgdmVyc2lvbikKewogICAgaWYgKHNubXBfY2FsbGJhY2tfYXZhaWxhYmxlKFNOTVBfQ0FMTEJBQ0tfQVBQTElDQVRJT04sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU05NUERfQ0FMTEJBQ0tfUkVHSVNURVJfTk9USUZJQ0FUSU9OUykgPT0KICAgICAgICBTTk1QRVJSX1NVQ0NFU1MpIHsKICAgICAgICAvKgogICAgICAgICAqIHNvbWV0aGluZyBlbHNlIHdhbnRzIHRvIGhhbmRsZSBub3RpZmljYXRpb24gcmVnaXN0cmF0aW9ucyAKICAgICAgICAgKi8KICAgICAgICBzdHJ1Y3QgYWdlbnRfYWRkX3RyYXBfYXJncyBhcmdzOwogICAgICAgIERFQlVHTVNHVEwoKCJ0cmFwIiwgImFkZGluZyBjYWxsYmFjayB0cmFwIHNpbmsgKCVwKVxuIiwgc3MpKTsKICAgICAgICBhcmdzLnNzID0gc3M7CiAgICAgICAgYXJncy5jb25maXJtID0gY29uZmlybTsKICAgICAgICBzbm1wX2NhbGxfY2FsbGJhY2tzKFNOTVBfQ0FMTEJBQ0tfQVBQTElDQVRJT04sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBTTk1QRF9DQUxMQkFDS19SRUdJU1RFUl9OT1RJRklDQVRJT05TLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgKHZvaWQgKikgJmFyZ3MpOwogICAgfSBlbHNlIHsKICAgICAgICAvKgogICAgICAgICAqIG5vIG90aGVyIHN1cHBvcnQgZXhpc3RzLCBoYW5kbGUgaXQgb3Vyc2VsdmVzLiAKICAgICAgICAgKi8KICAgICAgICBzdHJ1Y3QgdHJhcF9zaW5rICpuZXdfc2luazsKCiAgICAgICAgREVCVUdNU0dUTCgoInRyYXAiLCAiYWRkaW5nIGludGVybmFsIHRyYXAgc2lua1xuIikpOwogICAgICAgIG5ld19zaW5rID0gKHN0cnVjdCB0cmFwX3NpbmsgKikgbWFsbG9jKHNpemVvZigqbmV3X3NpbmspKTsKICAgICAgICBpZiAobmV3X3NpbmsgPT0gTlVMTCkKICAgICAgICAgICAgcmV0dXJuIDA7CgogICAgICAgIG5ld19zaW5rLT5zZXNwID0gc3M7CiAgICAgICAgbmV3X3NpbmstPnBkdXR5cGUgPSBwZHV0eXBlOwogICAgICAgIG5ld19zaW5rLT52ZXJzaW9uID0gdmVyc2lvbjsKICAgICAgICBuZXdfc2luay0+bmV4dCA9IHNpbmtzOwogICAgICAgIHNpbmtzID0gbmV3X3Npbms7CiAgICB9CiAgICByZXR1cm4gMTsKfQoKI2lmbmRlZiBORVRTTk1QX0ZFQVRVUkVfUkVNT1ZFX1JFTU9WRV9UUkFQX1NFU1NJT04KaW50CnJlbW92ZV90cmFwX3Nlc3Npb24obmV0c25tcF9zZXNzaW9uICogc3MpCnsKICAgIHN0cnVjdCB0cmFwX3NpbmsgKnNwID0gc2lua3MsICpwcmV2ID0gTlVMTDsKCiAgICBERUJVR01TR1RMKCgidHJhcCIsICJyZW1vdmluZyB0cmFwIHNlc3Npb25zXG4iKSk7CiAgICB3aGlsZSAoc3ApIHsKICAgICAgICBpZiAoc3AtPnNlc3AgPT0gc3MpIHsKICAgICAgICAgICAgaWYgKHByZXYpIHsKICAgICAgICAgICAgICAgIHByZXYtPm5leHQgPSBzcC0+bmV4dDsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIHNpbmtzID0gc3AtPm5leHQ7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgLyoKICAgICAgICAgICAgICogSSBkb24ndCBiZWxpZXZlIHlvdSAqcmVhbGx5KiB3YW50IHRvIGNsb3NlIHRoZSBzZXNzaW9uIGhlcmU7CiAgICAgICAgICAgICAqIGl0IG1heSBzdGlsbCBiZSBpbiB1c2UgZm9yIG90aGVyIHB1cnBvc2VzLiAgSW4gcGFydGljdWxhciB0aGlzCiAgICAgICAgICAgICAqIGlzIGF3a3dhcmQgZm9yIEFnZW50WCwgc2luY2Ugd2Ugd2FudCB0byBjYWxsIHRoaXMgZnVuY3Rpb24KICAgICAgICAgICAgICogZnJvbSB0aGUgc2Vzc2lvbidzIGNhbGxiYWNrLiAgTGV0J3MganVzdCBmcmVlIHRoZSB0cmFwc2luawogICAgICAgICAgICAgKiBkYXRhIHN0cnVjdHVyZS4gIFtqYnBuXSAgCiAgICAgICAgICAgICAqLwogICAgICAgICAgICAvKgogICAgICAgICAgICAgKiBmcmVlX3RyYXBfc2Vzc2lvbihzcCk7ICAKICAgICAgICAgICAgICovCiAgICAgICAgICAgIERFQlVHTVNHVEwoKCJ0cmFwIiwgInJlbW92aW5nIHRyYXAgc2Vzc2lvbiAoJXAsICVwKVxuIiwgc3AsIHNwLT5zZXNwKSk7CiAgICAgICAgICAgIGZyZWUoc3ApOwogICAgICAgICAgICByZXR1cm4gMTsKICAgICAgICB9CiAgICAgICAgcHJldiA9IHNwOwogICAgICAgIHNwID0gc3AtPm5leHQ7CiAgICB9CiAgICByZXR1cm4gMDsKfQojZW5kaWYgLyogTkVUU05NUF9GRUFUVVJFX1JFTU9WRV9SRU1PVkVfVFJBUF9TRVNTSU9OICovCgojaWYgIWRlZmluZWQoTkVUU05NUF9ESVNBQkxFX1NOTVBWMSkgfHwgIWRlZmluZWQoTkVUU05NUF9ESVNBQkxFX1NOTVBWMkMpCnN0YXRpYyBpbnQKY3JlYXRlX3RyYXBfc2Vzc2lvbjIoY29uc3QgY2hhciAqc2luaywgY29uc3QgY2hhciogc2lua3BvcnQsCgkJICAgICBjaGFyICpjb20sIGludCB2ZXJzaW9uLCBpbnQgcGR1dHlwZSkKewogICAgbmV0c25tcF90cmFuc3BvcnQgKnQ7CiAgICBuZXRzbm1wX3Nlc3Npb24gc2Vzc2lvbiwgKnNlc3A7CgogICAgbWVtc2V0KCZzZXNzaW9uLCAwLCBzaXplb2YobmV0c25tcF9zZXNzaW9uKSk7CiAgICBzZXNzaW9uLnZlcnNpb24gPSB2ZXJzaW9uOwogICAgaWYgKGNvbSkgewogICAgICAgIHNlc3Npb24uY29tbXVuaXR5ID0gKHVfY2hhciAqKSBjb207CiAgICAgICAgc2Vzc2lvbi5jb21tdW5pdHlfbGVuID0gc3RybGVuKGNvbSk7CiAgICB9CgogICAgLyoKICAgICAqIGZvciBpbmZvcm1zLCBzZXQgcmV0cmllcyB0byBkZWZhdWx0CiAgICAgKi8KICAgIGlmIChTTk1QX01TR19JTkZPUk0gPT0gcGR1dHlwZSkgewogICAgICAgIHNlc3Npb24udGltZW91dCA9IFNOTVBfREVGQVVMVF9USU1FT1VUOwogICAgICAgIHNlc3Npb24ucmV0cmllcyA9IFNOTVBfREVGQVVMVF9SRVRSSUVTOwogICAgfQoKICAgIC8qCiAgICAgKiBpZiB0aGUgc2luayBpcyBsb2NhbGhvc3QsIGJpbmQgdG8gbG9jYWxob3N0LCB0byByZWR1Y2Ugb3BlbiBwb3J0cy4KICAgICAqLwogICAgaWYgKChOVUxMID09IG5ldHNubXBfZHNfZ2V0X3N0cmluZyhORVRTTk1QX0RTX0xJQlJBUllfSUQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5FVFNOTVBfRFNfTElCX0NMSUVOVF9BRERSKSkgJiYgCiAgICAgICAgKCgwID09IHN0cmNtcCgibG9jYWxob3N0IixzaW5rKSkgfHwgKDAgPT0gc3RyY21wKCIxMjcuMC4wLjEiLHNpbmspKSkpCiAgICAgICAgc2Vzc2lvbi5sb2NhbG5hbWUgPSBzdHJkdXAoImxvY2FsaG9zdCIpOwoKICAgIHQgPSBuZXRzbm1wX3Rkb21haW5fdHJhbnNwb3J0X2Z1bGwoInNubXB0cmFwIiwgc2luaywgMCwgTlVMTCwgc2lua3BvcnQpOwogICAgaWYgKHQgIT0gTlVMTCkgewoJc2VzcCA9IHNubXBfYWRkKCZzZXNzaW9uLCB0LCBOVUxMLCBOVUxMKTsKCglpZiAoc2VzcCkgewoJICAgIHJldHVybiBhZGRfdHJhcF9zZXNzaW9uKHNlc3AsIHBkdXR5cGUsCgkJCQkgICAgKHBkdXR5cGUgPT0gU05NUF9NU0dfSU5GT1JNKSwgdmVyc2lvbik7Cgl9CiAgICB9CiAgICAvKgogICAgICogZGlhZ25vc2Ugc25tcF9vcGVuIGVycm9ycyB3aXRoIHRoZSBpbnB1dCBuZXRzbm1wX3Nlc3Npb24gcG9pbnRlciAKICAgICAqLwogICAgc25tcF9zZXNzX3BlcnJvcigic25tcGQ6IGNyZWF0ZV90cmFwX3Nlc3Npb24iLCAmc2Vzc2lvbik7CiAgICByZXR1cm4gMDsKfQoKaW50CmNyZWF0ZV90cmFwX3Nlc3Npb24oY2hhciAqc2luaywgdV9zaG9ydCBzaW5rcG9ydCwKCQkgICAgY2hhciAqY29tLCBpbnQgdmVyc2lvbiwgaW50IHBkdXR5cGUpCnsKICAgIGNoYXIgYnVmW3NpemVvZihzaW5rcG9ydCkgKiAzICsgMl07CiAgICBpZiAoc2lua3BvcnQgIT0gMCkgewoJc3ByaW50ZihidWYsICI6JWh1Iiwgc2lua3BvcnQpOwoJc25tcF9sb2coTE9HX05PVElDRSwKCQkgIlVzaW5nIGEgc2VwYXJhdGUgcG9ydCBudW1iZXIgaXMgZGVwcmVjYXRlZCwgcGxlYXNlIGNvcnJlY3QgIgoJCSAidGhlIHNpbmsgc3BlY2lmaWNhdGlvbiBpbnN0ZWFkIik7CiAgICB9CiAgICByZXR1cm4gY3JlYXRlX3RyYXBfc2Vzc2lvbjIoc2luaywgc2lua3BvcnQgPyBidWYgOiBOVUxMLCBjb20sIHZlcnNpb24sCgkJCQlwZHV0eXBlKTsKfQoKI2VuZGlmIC8qIHN1cHBvcnQgZm9yIGNvbW11bml0eSBiYXNlZCBTTk1QICovCgojaWZuZGVmIE5FVFNOTVBfRElTQUJMRV9TTk1QVjEKc3RhdGljIGludApjcmVhdGVfdjFfdHJhcF9zZXNzaW9uKGNoYXIgKnNpbmssIGNvbnN0IGNoYXIgKnNpbmtwb3J0LCBjaGFyICpjb20pCnsKICAgIHJldHVybiBjcmVhdGVfdHJhcF9zZXNzaW9uMihzaW5rLCBzaW5rcG9ydCwgY29tLAoJCQkJU05NUF9WRVJTSU9OXzEsIFNOTVBfTVNHX1RSQVApOwp9CiNlbmRpZgoKI2lmbmRlZiBORVRTTk1QX0RJU0FCTEVfU05NUFYyQwpzdGF0aWMgaW50CmNyZWF0ZV92Ml90cmFwX3Nlc3Npb24oY29uc3QgY2hhciAqc2luaywgY29uc3QgY2hhciAqc2lua3BvcnQsIGNoYXIgKmNvbSkKewogICAgcmV0dXJuIGNyZWF0ZV90cmFwX3Nlc3Npb24yKHNpbmssIHNpbmtwb3J0LCBjb20sCgkJCQlTTk1QX1ZFUlNJT05fMmMsIFNOTVBfTVNHX1RSQVAyKTsKfQoKc3RhdGljIGludApjcmVhdGVfdjJfaW5mb3JtX3Nlc3Npb24oY29uc3QgY2hhciAqc2luaywgY29uc3QgY2hhciAqc2lua3BvcnQsIGNoYXIgKmNvbSkKewogICAgcmV0dXJuIGNyZWF0ZV90cmFwX3Nlc3Npb24yKHNpbmssIHNpbmtwb3J0LCBjb20sCgkJCQlTTk1QX1ZFUlNJT05fMmMsIFNOTVBfTVNHX0lORk9STSk7Cn0KI2VuZGlmCgp2b2lkCnNubXBkX2ZyZWVfdHJhcHNpbmtzKHZvaWQpCnsKICAgIHN0cnVjdCB0cmFwX3NpbmsgKnNwID0gc2lua3M7CiAgICBERUJVR01TR1RMKCgidHJhcCIsICJmcmVlaW5nIHRyYXAgc2Vzc2lvbnNcbiIpKTsKICAgIHdoaWxlIChzcCkgewogICAgICAgIHNpbmtzID0gc2lua3MtPm5leHQ7CiAgICAgICAgZnJlZV90cmFwX3Nlc3Npb24oc3ApOwogICAgICAgIHNwID0gc2lua3M7CiAgICB9Cn0KCiAgICAgICAgLyoqKioqKioqKioqKioqKioqKioKCSAqCgkgKiBUcmFwIGhhbmRsaW5nCgkgKgoJICoqKioqKioqKioqKioqKioqKiovCgoKbmV0c25tcF9wZHUqCmNvbnZlcnRfdjJwZHVfdG9fdjEoIG5ldHNubXBfcGR1KiB0ZW1wbGF0ZV92MnBkdSApCnsKICAgIG5ldHNubXBfcGR1ICAgICAgICAgICAqdGVtcGxhdGVfdjFwZHU7CiAgICBuZXRzbm1wX3ZhcmlhYmxlX2xpc3QgKmZpcnN0X3ZiLCAqdmJsaXN0OwogICAgbmV0c25tcF92YXJpYWJsZV9saXN0ICp2YXI7CgogICAgLyoKICAgICAqIE1ha2UgYSBjb3B5IG9mIHRoZSB2MiBUcmFwIFBEVQogICAgICogICBiZWZvcmUgc3RhcnRpbmcgdG8gY29udmVydCB0aGlzCiAgICAgKiAgIGludG8gYSB2MSBUcmFwIFBEVS4KICAgICAqLwogICAgdGVtcGxhdGVfdjFwZHUgPSBzbm1wX2Nsb25lX3BkdSggdGVtcGxhdGVfdjJwZHUpOwogICAgaWYgKCF0ZW1wbGF0ZV92MXBkdSkgewogICAgICAgIHNubXBfbG9nKExPR19XQVJOSU5HLAogICAgICAgICAgICAgICAgICJzZW5kX3RyYXA6IGZhaWxlZCB0byBjb3B5IHYxIHRlbXBsYXRlIFBEVVxuIik7CiAgICAgICAgcmV0dXJuIE5VTEw7CiAgICB9CiAgICB0ZW1wbGF0ZV92MXBkdS0+Y29tbWFuZCA9IFNOTVBfTVNHX1RSQVA7CiAgICBmaXJzdF92YiA9IHRlbXBsYXRlX3YxcGR1LT52YXJpYWJsZXM7CiAgICB2Ymxpc3QgICA9IHRlbXBsYXRlX3YxcGR1LT52YXJpYWJsZXM7CgogICAgLyoKICAgICAqIFRoZSBmaXJzdCB2YXJiaW5kIHNob3VsZCBiZSB0aGUgc3lzdGVtIHVwdGltZS4KICAgICAqLwogICAgaWYgKCF2Ymxpc3QgfHwKICAgICAgICBzbm1wX29pZF9jb21wYXJlKHZibGlzdC0+bmFtZSwgIHZibGlzdC0+bmFtZV9sZW5ndGgsCiAgICAgICAgICAgICAgICAgICAgICAgICBzeXN1cHRpbWVfb2lkLCBzeXN1cHRpbWVfb2lkX2xlbikpIHsKICAgICAgICBzbm1wX2xvZyhMT0dfV0FSTklORywKICAgICAgICAgICAgICAgICAic2VuZF90cmFwOiBubyB2MiBzeXNVcHRpbWUgdmFyYmluZCB0byBzZXQgZnJvbVxuIik7CiAgICAgICAgc25tcF9mcmVlX3BkdSh0ZW1wbGF0ZV92MXBkdSk7CiAgICAgICAgcmV0dXJuIE5VTEw7CiAgICB9CiAgICB0ZW1wbGF0ZV92MXBkdS0+dGltZSA9ICp2Ymxpc3QtPnZhbC5pbnRlZ2VyOwogICAgdmJsaXN0ID0gdmJsaXN0LT5uZXh0X3ZhcmlhYmxlOwogICAgICAgICAgICAKICAgIC8qCiAgICAgKiBUaGUgc2Vjb25kIHZhcmJpbmQgc2hvdWxkIGJlIHRoZSBzbm1wVHJhcE9JRC4KICAgICAqLwogICAgaWYgKCF2Ymxpc3QgfHwKICAgICAgICBzbm1wX29pZF9jb21wYXJlKHZibGlzdC0+bmFtZSwgdmJsaXN0LT5uYW1lX2xlbmd0aCwKICAgICAgICAgICAgICAgICAgICAgICAgIHNubXB0cmFwX29pZCwgc25tcHRyYXBfb2lkX2xlbikpIHsKICAgICAgICBzbm1wX2xvZyhMT0dfV0FSTklORywKICAgICAgICAgICAgICAgICAic2VuZF90cmFwOiBubyB2MiB0cmFwT0lEIHZhcmJpbmQgdG8gc2V0IGZyb21cbiIpOwogICAgICAgIHNubXBfZnJlZV9wZHUodGVtcGxhdGVfdjFwZHUpOwogICAgICAgIHJldHVybiBOVUxMOwogICAgfQoKICAgIC8qCiAgICAgKiBDaGVjayB0aGUgdjIgdmFyYmluZCBsaXN0IGZvciBhbnkgdmFyYmluZHMKICAgICAqICB0aGF0IGFyZSBub3QgdmFsaWQgaW4gYW4gU05NUHYxIHRyYXAuCiAgICAgKiAgVGhpcyBiYXNpY2FsbHkgbWVhbnMgQ291bnRlcjY0IHZhbHVlcy4KICAgICAqCiAgICAgKiBSRkMgMjA4OSBzYWlkIHRvIG9taXQgc3VjaCB2YXJiaW5kcyBmcm9tIHRoZSBsaXN0LgogICAgICogUkZDIDI1NzYvMzU4NCBzYXkgdG8gZHJvcCB0aGUgdHJhcCBjb21wbGV0ZWx5LgogICAgICovCiAgICBmb3IgKHZhciA9IHZibGlzdC0+bmV4dF92YXJpYWJsZTsgdmFyOyB2YXIgPSB2YXItPm5leHRfdmFyaWFibGUpIHsKICAgICAgICBpZiAoIHZhci0+dHlwZSA9PSBBU05fQ09VTlRFUjY0ICkgewogICAgICAgICAgICBzbm1wX2xvZyhMT0dfV0FSTklORywKICAgICAgICAgICAgICAgICAgICAgInNlbmRfdHJhcDogdjEgdHJhcHMgY2FuJ3QgY2FycnkgQ291bnRlcjY0IHZhcmJpbmRzXG4iKTsKICAgICAgICAgICAgc25tcF9mcmVlX3BkdSh0ZW1wbGF0ZV92MXBkdSk7CiAgICAgICAgICAgIHJldHVybiBOVUxMOwogICAgICAgIH0KICAgIH0KCiAgICAvKgogICAgICogU2V0IHRoZSBnZW5lcmljICYgc3BlY2lmaWMgdHJhcCB0eXBlcywKICAgICAqICAgIGFuZCB0aGUgZW50ZXJwcmlzZSBmaWVsZCBmcm9tIHRoZSB2MiB2YXJiaW5kIGxpc3QuCiAgICAgKiBJZiB0aGVyZSdzIGFuIGFnZW50SVBBZGRyZXNzIHZhcmJpbmQsIHNldCB0aGUgYWdlbnRfYWRkciB0b28KICAgICAqLwogICAgaWYgKCFzbm1wX29pZF9jb21wYXJlKHZibGlzdC0+dmFsLm9iamlkLCBPSURfTEVOR1RIKHRyYXBfcHJlZml4KSwKICAgICAgICAgICAgICAgICAgICAgICAgICB0cmFwX3ByZWZpeCwgICAgICAgT0lEX0xFTkdUSCh0cmFwX3ByZWZpeCkpKSB7CiAgICAgICAgLyoKICAgICAgICAgKiBGb3IgJ3N0YW5kYXJkJyB0cmFwcywgZXh0cmFjdCB0aGUgZ2VuZXJpYyB0cmFwIHR5cGUKICAgICAgICAgKiAgIGZyb20gdGhlIHNubXBUcmFwT0lEIHZhbHVlLCBhbmQgdGFrZSB0aGUgZW50ZXJwcmlzZQogICAgICAgICAqICAgdmFsdWUgZnJvbSB0aGUgJ3NubXBFbnRlcnByaXNlJyB2YXJiaW5kLgogICAgICAgICAqLwogICAgICAgIHRlbXBsYXRlX3YxcGR1LT50cmFwX3R5cGUgPQogICAgICAgICAgICB2Ymxpc3QtPnZhbC5vYmppZFtPSURfTEVOR1RIKHRyYXBfcHJlZml4KV0gLSAxOwogICAgICAgIHRlbXBsYXRlX3YxcGR1LT5zcGVjaWZpY190eXBlID0gMDsKCiAgICAgICAgdmFyID0gZmluZF92YXJiaW5kX2luX2xpc3QoIHZibGlzdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzbm1wdHJhcGVudGVycHJpc2Vfb2lkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNubXB0cmFwZW50ZXJwcmlzZV9vaWRfbGVuKTsKICAgICAgICBpZiAodmFyKSB7CiAgICAgICAgICAgIHRlbXBsYXRlX3YxcGR1LT5lbnRlcnByaXNlX2xlbmd0aCA9IHZhci0+dmFsX2xlbi9zaXplb2Yob2lkKTsKICAgICAgICAgICAgdGVtcGxhdGVfdjFwZHUtPmVudGVycHJpc2UgPQogICAgICAgICAgICAgICAgc25tcF9kdXBsaWNhdGVfb2JqaWQodmFyLT52YWwub2JqaWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0ZW1wbGF0ZV92MXBkdS0+ZW50ZXJwcmlzZV9sZW5ndGgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHRlbXBsYXRlX3YxcGR1LT5lbnRlcnByaXNlICAgICAgICA9IE5VTEw7CiAgICAgICAgICAgIHRlbXBsYXRlX3YxcGR1LT5lbnRlcnByaXNlX2xlbmd0aCA9IDA7CQkvKiBYWFggPz8/ICovCiAgICAgICAgfQogICAgfSBlbHNlIHsKICAgICAgICAvKgogICAgICAgICAqIEZvciBlbnRlcnByaXNlLXNwZWNpZmljIHRyYXBzLCBzcGxpdCB0aGUgc25tcFRyYXBPSUQgdmFsdWUKICAgICAgICAgKiAgIGludG8gZW50ZXJwcmlzZSBhbmQgc3BlY2lmaWMgdHJhcAogICAgICAgICAqLwogICAgICAgIHNpemVfdCBsZW4gPSB2Ymxpc3QtPnZhbF9sZW4gLyBzaXplb2Yob2lkKTsKICAgICAgICBpZiAoIGxlbiA8PSAyICkgewogICAgICAgICAgICBzbm1wX2xvZyhMT0dfV0FSTklORywKICAgICAgICAgICAgICAgICAgICAgInNlbmRfdHJhcDogdjIgdHJhcE9JRCB0b28gc2hvcnQgKCVkKVxuIiwgKGludClsZW4pOwogICAgICAgICAgICBzbm1wX2ZyZWVfcGR1KHRlbXBsYXRlX3YxcGR1KTsKICAgICAgICAgICAgcmV0dXJuIE5VTEw7CiAgICAgICAgfQogICAgICAgIHRlbXBsYXRlX3YxcGR1LT50cmFwX3R5cGUgICAgID0gU05NUF9UUkFQX0VOVEVSUFJJU0VTUEVDSUZJQzsKICAgICAgICB0ZW1wbGF0ZV92MXBkdS0+c3BlY2lmaWNfdHlwZSA9IHZibGlzdC0+dmFsLm9iamlkW2xlbiAtIDFdOwogICAgICAgIGxlbi0tOwogICAgICAgIGlmICh2Ymxpc3QtPnZhbC5vYmppZFtsZW4tMV0gPT0gMCkKICAgICAgICAgICAgbGVuLS07CiAgICAgICAgU05NUF9GUkVFKHRlbXBsYXRlX3YxcGR1LT5lbnRlcnByaXNlKTsKICAgICAgICB0ZW1wbGF0ZV92MXBkdS0+ZW50ZXJwcmlzZSA9CiAgICAgICAgICAgIHNubXBfZHVwbGljYXRlX29iamlkKHZibGlzdC0+dmFsLm9iamlkLCBsZW4pOwogICAgICAgIHRlbXBsYXRlX3YxcGR1LT5lbnRlcnByaXNlX2xlbmd0aCA9IGxlbjsKICAgIH0KICAgIHZhciA9IGZpbmRfdmFyYmluZF9pbl9saXN0KCB2Ymxpc3QsIGFnZW50YWRkcl9vaWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhZ2VudGFkZHJfb2lkX2xlbik7CiAgICBpZiAodmFyKSB7CiAgICAgICAgbWVtY3B5KHRlbXBsYXRlX3YxcGR1LT5hZ2VudF9hZGRyLAogICAgICAgICAgICAgICB2YXItPnZhbC5zdHJpbmcsIDQpOwogICAgfQoKICAgIC8qCiAgICAgKiBUaGUgcmVtYWluZGVyIG9mIHRoZSB2MiB2YXJiaW5kIGxpc3QgaXMga2VwdAogICAgICogYXMgdGhlIHYyIHZhcmJpbmQgbGlzdC4gIFVwZGF0ZSB0aGUgUERVIGFuZAogICAgICogZnJlZSB0aGUgdHdvIHJlZHVuZGFudCB2YXJiaW5kcy4KICAgICAqLwogICAgdGVtcGxhdGVfdjFwZHUtPnZhcmlhYmxlcyA9IHZibGlzdC0+bmV4dF92YXJpYWJsZTsKICAgIHZibGlzdC0+bmV4dF92YXJpYWJsZSA9IE5VTEw7CiAgICBzbm1wX2ZyZWVfdmFyYmluZCggZmlyc3RfdmIgKTsKICAgICAgICAgICAgCiAgICByZXR1cm4gdGVtcGxhdGVfdjFwZHU7Cn0KCm5ldHNubXBfcGR1Kgpjb252ZXJ0X3YxcGR1X3RvX3YyKCBuZXRzbm1wX3BkdSogdGVtcGxhdGVfdjFwZHUgKQp7CiAgICBuZXRzbm1wX3BkdSAgICAgICAgICAgKnRlbXBsYXRlX3YycGR1OwogICAgbmV0c25tcF92YXJpYWJsZV9saXN0ICp2YXI7CiAgICBvaWQgICAgICAgICAgICAgICAgICAgIGVudGVycHJpc2VbTUFYX09JRF9MRU5dOwogICAgc2l6ZV90ICAgICAgICAgICAgICAgICBlbnRlcnByaXNlX2xlbjsKCiAgICAvKgogICAgICogTWFrZSBhIGNvcHkgb2YgdGhlIHYxIFRyYXAgUERVCiAgICAgKiAgIGJlZm9yZSBzdGFydGluZyB0byBjb252ZXJ0IHRoaXMKICAgICAqICAgaW50byBhIHYyIFRyYXAgUERVLgogICAgICovCiAgICB0ZW1wbGF0ZV92MnBkdSA9IHNubXBfY2xvbmVfcGR1KCB0ZW1wbGF0ZV92MXBkdSk7CiAgICBpZiAoIXRlbXBsYXRlX3YycGR1KSB7CiAgICAgICAgc25tcF9sb2coTE9HX1dBUk5JTkcsCiAgICAgICAgICAgICAgICAgInNlbmRfdHJhcDogZmFpbGVkIHRvIGNvcHkgdjIgdGVtcGxhdGUgUERVXG4iKTsKICAgICAgICByZXR1cm4gTlVMTDsKICAgIH0KICAgIHRlbXBsYXRlX3YycGR1LT5jb21tYW5kID0gU05NUF9NU0dfVFJBUDI7CgogICAgLyoKICAgICAqIEluc2VydCBhbiBzbm1wVHJhcE9JRCB2YXJiaW5kIGJlZm9yZSB0aGUgb3JpZ2luYWwgdjEgdmFyYmluZCBsaXN0CiAgICAgKiAgIGVpdGhlciB1c2luZyBvbmUgb2YgdGhlIHN0YW5kYXJkIGRlZmluZWQgdHJhcCBPSURzLAogICAgICogICBvciBjb25zdHJ1Y3RpbmcgdGhpcyBmcm9tIHRoZSBQRFUgZW50ZXJwcmlzZSAmIHNwZWNpZmljIHRyYXAgZmllbGRzCiAgICAgKi8KICAgIGlmICh0ZW1wbGF0ZV92MXBkdS0+dHJhcF90eXBlID09IFNOTVBfVFJBUF9FTlRFUlBSSVNFU1BFQ0lGSUMpIHsKICAgICAgICBtZW1jcHkoZW50ZXJwcmlzZSwgdGVtcGxhdGVfdjFwZHUtPmVudGVycHJpc2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHRlbXBsYXRlX3YxcGR1LT5lbnRlcnByaXNlX2xlbmd0aCpzaXplb2Yob2lkKSk7CiAgICAgICAgZW50ZXJwcmlzZV9sZW4gICAgICAgICAgICAgICA9IHRlbXBsYXRlX3YxcGR1LT5lbnRlcnByaXNlX2xlbmd0aDsKICAgICAgICBlbnRlcnByaXNlW2VudGVycHJpc2VfbGVuKytdID0gMDsKICAgICAgICBlbnRlcnByaXNlW2VudGVycHJpc2VfbGVuKytdID0gdGVtcGxhdGVfdjFwZHUtPnNwZWNpZmljX3R5cGU7CiAgICB9IGVsc2UgewogICAgICAgIG1lbWNweShlbnRlcnByaXNlLCBjb2xkX3N0YXJ0X29pZCwgc2l6ZW9mKGNvbGRfc3RhcnRfb2lkKSk7CgllbnRlcnByaXNlWzldICA9IHRlbXBsYXRlX3YxcGR1LT50cmFwX3R5cGUrMTsKICAgICAgICBlbnRlcnByaXNlX2xlbiA9IHNpemVvZihjb2xkX3N0YXJ0X29pZCkvc2l6ZW9mKG9pZCk7CiAgICB9CgogICAgdmFyID0gTlVMTDsKICAgIGlmICghc25tcF92YXJsaXN0X2FkZF92YXJpYWJsZSggJnZhciwKICAgICAgICAgICAgIHNubXB0cmFwX29pZCwgc25tcHRyYXBfb2lkX2xlbiwKICAgICAgICAgICAgIEFTTl9PQkpFQ1RfSUQsCiAgICAgICAgICAgICAodV9jaGFyKillbnRlcnByaXNlLCBlbnRlcnByaXNlX2xlbipzaXplb2Yob2lkKSkpIHsKICAgICAgICBzbm1wX2xvZyhMT0dfV0FSTklORywKICAgICAgICAgICAgICAgICAic2VuZF90cmFwOiBmYWlsZWQgdG8gaW5zZXJ0IGNvcGllZCBzbm1wVHJhcE9JRCB2YXJiaW5kXG4iKTsKICAgICAgICBzbm1wX2ZyZWVfcGR1KHRlbXBsYXRlX3YycGR1KTsKICAgICAgICByZXR1cm4gTlVMTDsKICAgIH0KICAgIHZhci0+bmV4dF92YXJpYWJsZSAgICAgICAgPSB0ZW1wbGF0ZV92MnBkdS0+dmFyaWFibGVzOwogICAgdGVtcGxhdGVfdjJwZHUtPnZhcmlhYmxlcyA9IHZhcjsKCiAgICAvKgogICAgICogSW5zZXJ0IGEgc3lzVXB0aW1lIHZhcmJpbmQgYXQgdGhlIGhlYWQgb2YgdGhlIHYyIHZhcmJpbmQgbGlzdAogICAgICovCiAgICB2YXIgPSBOVUxMOwogICAgaWYgKCFzbm1wX3Zhcmxpc3RfYWRkX3ZhcmlhYmxlKCAmdmFyLAogICAgICAgICAgICAgc3lzdXB0aW1lX29pZCwgc3lzdXB0aW1lX29pZF9sZW4sCiAgICAgICAgICAgICBBU05fVElNRVRJQ0tTLAogICAgICAgICAgICAgKHVfY2hhciopJih0ZW1wbGF0ZV92MXBkdS0+dGltZSksIAogICAgICAgICAgICAgc2l6ZW9mKHRlbXBsYXRlX3YxcGR1LT50aW1lKSkpIHsKICAgICAgICBzbm1wX2xvZyhMT0dfV0FSTklORywKICAgICAgICAgICAgICAgICAic2VuZF90cmFwOiBmYWlsZWQgdG8gaW5zZXJ0IGNvcGllZCBzeXNVcHRpbWUgdmFyYmluZFxuIik7CiAgICAgICAgc25tcF9mcmVlX3BkdSh0ZW1wbGF0ZV92MnBkdSk7CiAgICAgICAgcmV0dXJuIE5VTEw7CiAgICB9CiAgICB2YXItPm5leHRfdmFyaWFibGUgICAgICAgID0gdGVtcGxhdGVfdjJwZHUtPnZhcmlhYmxlczsKICAgIHRlbXBsYXRlX3YycGR1LT52YXJpYWJsZXMgPSB2YXI7CgogICAgLyoKICAgICAqIEFwcGVuZCB0aGUgb3RoZXIgdGhyZWUgY29udmVyc2lvbiB2YXJiaW5kcywKICAgICAqICAoc25tcFRyYXBBZ2VudEFkZHIsIHNubXBUcmFwQ29tbXVuaXR5ICYgc25tcFRyYXBFbnRlcnByaXNlKQogICAgICogIGlmIHRoZXkncmUgbm90IGFscmVhZHkgcHJlc2VudC4KICAgICAqICBCdXQgZG9uJ3QgYm9tYiBvdXQgY29tcGxldGVseSBpZiB0aGVyZSBhcmUgcHJvYmxlbXMuCiAgICAgKi8KICAgIHZhciA9IGZpbmRfdmFyYmluZF9pbl9saXN0KCB0ZW1wbGF0ZV92MnBkdS0+dmFyaWFibGVzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFnZW50YWRkcl9vaWQsIGFnZW50YWRkcl9vaWRfbGVuKTsKICAgIGlmICghdmFyICYmICh0ZW1wbGF0ZV92MXBkdS0+YWdlbnRfYWRkclswXQogICAgICAgICAgICAgIHx8IHRlbXBsYXRlX3YxcGR1LT5hZ2VudF9hZGRyWzFdCiAgICAgICAgICAgICAgfHwgdGVtcGxhdGVfdjFwZHUtPmFnZW50X2FkZHJbMl0KICAgICAgICAgICAgICB8fCB0ZW1wbGF0ZV92MXBkdS0+YWdlbnRfYWRkclszXSkpIHsKICAgICAgICBpZiAoIXNubXBfdmFybGlzdF9hZGRfdmFyaWFibGUoICYodGVtcGxhdGVfdjJwZHUtPnZhcmlhYmxlcyksCiAgICAgICAgICAgICAgICAgYWdlbnRhZGRyX29pZCwgYWdlbnRhZGRyX29pZF9sZW4sCiAgICAgICAgICAgICAgICAgQVNOX0lQQUREUkVTUywKICAgICAgICAgICAgICAgICAodV9jaGFyKikmKHRlbXBsYXRlX3YxcGR1LT5hZ2VudF9hZGRyKSwgCiAgICAgICAgICAgICAgICAgc2l6ZW9mKHRlbXBsYXRlX3YxcGR1LT5hZ2VudF9hZGRyKSkpCiAgICAgICAgICAgIHNubXBfbG9nKExPR19XQVJOSU5HLAogICAgICAgICAgICAgICAgICJzZW5kX3RyYXA6IGZhaWxlZCB0byBhcHBlbmQgc25tcFRyYXBBZGRyIHZhcmJpbmRcbiIpOwogICAgfQogICAgdmFyID0gZmluZF92YXJiaW5kX2luX2xpc3QoIHRlbXBsYXRlX3YycGR1LT52YXJpYWJsZXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29tbXVuaXR5X29pZCwgY29tbXVuaXR5X29pZF9sZW4pOwogICAgaWYgKCF2YXIgJiYgdGVtcGxhdGVfdjFwZHUtPmNvbW11bml0eSkgewogICAgICAgIGlmICghc25tcF92YXJsaXN0X2FkZF92YXJpYWJsZSggJih0ZW1wbGF0ZV92MnBkdS0+dmFyaWFibGVzKSwKICAgICAgICAgICAgICAgICBjb21tdW5pdHlfb2lkLCBjb21tdW5pdHlfb2lkX2xlbiwKICAgICAgICAgICAgICAgICBBU05fT0NURVRfU1RSLAogICAgICAgICAgICAgICAgIHRlbXBsYXRlX3YxcGR1LT5jb21tdW5pdHksIAogICAgICAgICAgICAgICAgIHRlbXBsYXRlX3YxcGR1LT5jb21tdW5pdHlfbGVuKSkKICAgICAgICAgICAgc25tcF9sb2coTE9HX1dBUk5JTkcsCiAgICAgICAgICAgICAgICAgInNlbmRfdHJhcDogZmFpbGVkIHRvIGFwcGVuZCBzbm1wVHJhcENvbW11bml0eSB2YXJiaW5kXG4iKTsKICAgIH0KICAgIHZhciA9IGZpbmRfdmFyYmluZF9pbl9saXN0KCB0ZW1wbGF0ZV92MnBkdS0+dmFyaWFibGVzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNubXB0cmFwZW50ZXJwcmlzZV9vaWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc25tcHRyYXBlbnRlcnByaXNlX29pZF9sZW4pOwogICAgaWYgKCF2YXIpIHsKICAgICAgICBpZiAoIXNubXBfdmFybGlzdF9hZGRfdmFyaWFibGUoICYodGVtcGxhdGVfdjJwZHUtPnZhcmlhYmxlcyksCiAgICAgICAgICAgICAgICAgc25tcHRyYXBlbnRlcnByaXNlX29pZCwgc25tcHRyYXBlbnRlcnByaXNlX29pZF9sZW4sCiAgICAgICAgICAgICAgICAgQVNOX09CSkVDVF9JRCwKICAgICAgICAgICAgICAgICAodV9jaGFyKil0ZW1wbGF0ZV92MXBkdS0+ZW50ZXJwcmlzZSwgCiAgICAgICAgICAgICAgICAgdGVtcGxhdGVfdjFwZHUtPmVudGVycHJpc2VfbGVuZ3RoKnNpemVvZihvaWQpKSkKICAgICAgICAgICAgc25tcF9sb2coTE9HX1dBUk5JTkcsCiAgICAgICAgICAgICAgICAgInNlbmRfdHJhcDogZmFpbGVkIHRvIGFwcGVuZCBzbm1wRW50ZXJwcmlzZSB2YXJiaW5kXG4iKTsKICAgIH0KICAgIHJldHVybiB0ZW1wbGF0ZV92MnBkdTsKfQoKLyoqCiAqIFRoaXMgZnVuY3Rpb24gYWxsb3dzIHlvdSB0byBtYWtlIGEgZGlzdGluY3Rpb24gYmV0d2VlbiBnZW5lcmljIAogKiB0cmFwcyBmcm9tIGRpZmZlcmVudCBjbGFzc2VzIG9mIGVxdWlwbWVudC4gRm9yIGV4YW1wbGUsIHlvdSBtYXkgd2FudCAKICogdG8gaGFuZGxlIGEgU05NUF9UUkFQX0xJTktET1dOIHRyYXAgZm9yIGEgcGFydGljdWxhciBkZXZpY2UgaW4gYSAKICogZGlmZmVyZW50IG1hbm5lciB0byBhIGdlbmVyaWMgc3lzdGVtIFNOTVBfVFJBUF9MSU5LRE9XTiB0cmFwLgogKiAgIAogKgogKiBAcGFyYW0gdHJhcCBpcyB0aGUgZ2VuZXJpYyB0cmFwIHR5cGUuICBUaGUgdHJhcCB0eXBlcyBhcmU6CiAqCQktIFNOTVBfVFJBUF9DT0xEU1RBUlQ6CiAqCQkJY29sZCBzdGFydAogKgkJLSBTTk1QX1RSQVBfV0FSTVNUQVJUOgogKgkJCXdhcm0gc3RhcnQKICoJCS0gU05NUF9UUkFQX0xJTktET1dOOgogKgkJCWxpbmsgZG93bgogKgkJLSBTTk1QX1RSQVBfTElOS1VQOgogKgkJCWxpbmsgdXAKICoJCS0gU05NUF9UUkFQX0FVVEhGQUlMOgogKgkJCWF1dGhlbnRpY2F0aW9uIGZhaWx1cmUKICoJCS0gU05NUF9UUkFQX0VHUE5FSUdIQk9STE9TUzoKICoJCQllZ3AgbmVpZ2hib3IgbG9zcwogKgkJLSBTTk1QX1RSQVBfRU5URVJQUklTRVNQRUNJRklDOgogKgkJCWVudGVycHJpc2Ugc3BlY2lmaWMKICoJCQkKICogQHBhcmFtIHNwZWNpZmljIGlzIHRoZSBzcGVjaWZpYyB0cmFwIHZhbHVlLgogKgogKiBAcGFyYW0gZW50ZXJwcmlzZSBpcyBhbiBlbnRlcnByaXNlIG9pZCBpbiB3aGljaCB5b3Ugd2FudCB0byBzZW5kIHNwZWNpZmljIAogKgl0cmFwcyBmcm9tLiAKICoKICogQHBhcmFtIGVudGVycHJpc2VfbGVuZ3RoIGlzIHRoZSBsZW5ndGggb2YgdGhlIGVudGVycHJpc2Ugb2lkLCB1c2UgbWFjcm8sCiAqCU9JRF9MRU5HVEgsIHRvIGNvbXB1dGUgbGVuZ3RoLgogKgogKiBAcGFyYW0gdmFycyBpcyB1c2VkIHRvIHN1cHBseSBsaXN0IG9mIHZhcmlhYmxlIGJpbmRpbmdzIHRvIGZvcm0gYW4gU05NUHYyIAogKgl0cmFwLgogKgogKiBAcGFyYW0gY29udGV4dCBjdXJyZW50bHkgdW51c2VkIAogKgogKiBAcGFyYW0gZmxhZ3MgY3VycmVudGx5IHVudXNlZCAKICoKICogQHJldHVybiB2b2lkCiAqCiAqIEBzZWUgc2VuZF9lYXN5X3RyYXAKICogQHNlZSBzZW5kX3YydHJhcAogKi8KaW50Cm5ldHNubXBfc2VuZF90cmFwcyhpbnQgdHJhcCwgaW50IHNwZWNpZmljLAogICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IG9pZCAqIGVudGVycHJpc2UsIGludCBlbnRlcnByaXNlX2xlbmd0aCwKICAgICAgICAgICAgICAgICAgICAgICAgICBuZXRzbm1wX3ZhcmlhYmxlX2xpc3QgKiB2YXJzLAogICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNoYXIgKiBjb250ZXh0LCBpbnQgZmxhZ3MpCnsKICAgIG5ldHNubXBfcGR1ICAgICAgICAgICAqdGVtcGxhdGVfdjFwZHU7CiAgICBuZXRzbm1wX3BkdSAgICAgICAgICAgKnRlbXBsYXRlX3YycGR1OwogICAgbmV0c25tcF92YXJpYWJsZV9saXN0ICp2Ymxpc3QgPSBOVUxMOwogICAgbmV0c25tcF92YXJpYWJsZV9saXN0ICp0cmFwX3ZiOwogICAgbmV0c25tcF92YXJpYWJsZV9saXN0ICp2YXI7CiAgICBpbl9hZGRyX3QgICAgICAgICAgICAgKnBkdV9pbl9hZGRyX3Q7CiAgICB1X2xvbmcgICAgICAgICAgICAgICAgIHVwdGltZTsKICAgIHN0cnVjdCB0cmFwX3NpbmsgKnNpbms7CiAgICBjb25zdCBjaGFyICAgICAgICAgICAgKnYxdHJhcGFkZHJlc3M7CiAgICBpbnQgICAgICAgICAgICAgICAgICAgIHJlcyA9IDA7CgogICAgREVCVUdNU0dUTCgoICJ0cmFwIiwgInNlbmRfdHJhcCAlZCAlZCAiLCB0cmFwLCBzcGVjaWZpYykpOwogICAgREVCVUdNU0dPSUQoKCJ0cmFwIiwgZW50ZXJwcmlzZSwgZW50ZXJwcmlzZV9sZW5ndGgpKTsKICAgIERFQlVHTVNHKCggInRyYXAiLCAiXG4iKSk7CgogICAgaWYgKHZhcnMpIHsKICAgICAgICB2Ymxpc3QgPSBzbm1wX2Nsb25lX3ZhcmJpbmQoIHZhcnMgKTsKICAgICAgICBpZiAoIXZibGlzdCkgewogICAgICAgICAgICBzbm1wX2xvZyhMT0dfV0FSTklORywKICAgICAgICAgICAgICAgICAgICAgInNlbmRfdHJhcDogZmFpbGVkIHRvIGNsb25lIHZhcmJpbmQgbGlzdFxuIik7CiAgICAgICAgICAgIHJldHVybiAtMTsKICAgICAgICB9CiAgICB9CgogICAgaWYgKCB0cmFwID09IC0xICkgewogICAgICAgIC8qCiAgICAgICAgICogQ29uc3RydWN0IHRoZSBTTk1QdjItc3R5bGUgbm90aWZpY2F0aW9uIFBEVQogICAgICAgICAqLwogICAgICAgIGlmICghdmJsaXN0KSB7CiAgICAgICAgICAgIHNubXBfbG9nKExPR19XQVJOSU5HLAogICAgICAgICAgICAgICAgICAgICAic2VuZF90cmFwOiBjYWxsZWQgd2l0aCBOVUxMIHYyIGluZm9ybWF0aW9uXG4iKTsKICAgICAgICAgICAgcmV0dXJuIC0xOwogICAgICAgIH0KICAgICAgICB0ZW1wbGF0ZV92MnBkdSA9IHNubXBfcGR1X2NyZWF0ZShTTk1QX01TR19UUkFQMik7CiAgICAgICAgaWYgKCF0ZW1wbGF0ZV92MnBkdSkgewogICAgICAgICAgICBzbm1wX2xvZyhMT0dfV0FSTklORywKICAgICAgICAgICAgICAgICAgICAgInNlbmRfdHJhcDogZmFpbGVkIHRvIGNvbnN0cnVjdCB2MiB0ZW1wbGF0ZSBQRFVcbiIpOwogICAgICAgICAgICBzbm1wX2ZyZWVfdmFyYmluZCh2Ymxpc3QpOwogICAgICAgICAgICByZXR1cm4gLTE7CiAgICAgICAgfQoKICAgICAgICAvKgogICAgICAgICAqIENoZWNrIHRoZSB2YXJiaW5kIGxpc3Qgd2UndmUgYmVlbiBnaXZlbi4KICAgICAgICAgKiBJZiBpdCBzdGFydHMgd2l0aCBhICdzeXNVcHRpbWUuMCcgdmFyYmluZCwgdGhlbiB1c2UgdGhhdC4KICAgICAgICAgKiBPdGhlcndpc2UsIHByZXBlbmQgYSBzdWl0YWJsZSAnc3lzVXB0aW1lLjAnIHZhcmJpbmQuCiAgICAgICAgICovCiAgICAgICAgaWYgKCFzbm1wX29pZF9jb21wYXJlKCB2Ymxpc3QtPm5hbWUsICAgIHZibGlzdC0+bmFtZV9sZW5ndGgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzeXN1cHRpbWVfb2lkLCBzeXN1cHRpbWVfb2lkX2xlbiApKSB7CiAgICAgICAgICAgIHRlbXBsYXRlX3YycGR1LT52YXJpYWJsZXMgPSB2Ymxpc3Q7CiAgICAgICAgICAgIHRyYXBfdmIgID0gdmJsaXN0LT5uZXh0X3ZhcmlhYmxlOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHVwdGltZSAgID0gbmV0c25tcF9nZXRfYWdlbnRfdXB0aW1lKCk7CiAgICAgICAgICAgIHZhciA9IE5VTEw7CiAgICAgICAgICAgIHNubXBfdmFybGlzdF9hZGRfdmFyaWFibGUoICZ2YXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHN5c3VwdGltZV9vaWQsIHN5c3VwdGltZV9vaWRfbGVuLAogICAgICAgICAgICAgICAgICAgICAgICAgICBBU05fVElNRVRJQ0tTLCAodV9jaGFyKikmdXB0aW1lLCBzaXplb2YodXB0aW1lKSk7CiAgICAgICAgICAgIGlmICghdmFyKSB7CiAgICAgICAgICAgICAgICBzbm1wX2xvZyhMT0dfV0FSTklORywKICAgICAgICAgICAgICAgICAgICAgInNlbmRfdHJhcDogZmFpbGVkIHRvIGluc2VydCBzeXNVcHRpbWUgdmFyYmluZFxuIik7CiAgICAgICAgICAgICAgICBzbm1wX2ZyZWVfcGR1KHRlbXBsYXRlX3YycGR1KTsKICAgICAgICAgICAgICAgIHNubXBfZnJlZV92YXJiaW5kKHZibGlzdCk7CiAgICAgICAgICAgICAgICByZXR1cm4gLTE7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgdGVtcGxhdGVfdjJwZHUtPnZhcmlhYmxlcyA9IHZhcjsKICAgICAgICAgICAgdmFyLT5uZXh0X3ZhcmlhYmxlICAgICAgICA9IHZibGlzdDsKICAgICAgICAgICAgdHJhcF92YiAgPSB2Ymxpc3Q7CiAgICAgICAgfQoKICAgICAgICAvKgogICAgICAgICAqICd0cmFwX3ZiJyBzaG91bGQgcG9pbnQgdG8gdGhlIHNubXBUcmFwT0lELjAgdmFyYmluZCwKICAgICAgICAgKiAgIGlkZW50aWZ5aW5nIHRoZSByZXF1ZXN0ZWQgdHJhcC4gIElmIG5vdCB0aGVuIGJvbWIgb3V0LgogICAgICAgICAqIElmIGl0J3MgYSAnc3RhbmRhcmQnIHRyYXAsIHRoZW4gd2UgbmVlZCB0byBhcHBlbmQgYW4KICAgICAgICAgKiAgIHNubXBFbnRlcnByaXNlIHZhcmJpbmQgKGlmIHRoZXJlIGlzbid0IGFscmVhZHkgb25lKS4KICAgICAgICAgKi8KICAgICAgICBpZiAoIXRyYXBfdmIgfHwKICAgICAgICAgICAgc25tcF9vaWRfY29tcGFyZSh0cmFwX3ZiLT5uYW1lLCB0cmFwX3ZiLT5uYW1lX2xlbmd0aCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzbm1wdHJhcF9vaWQsICBzbm1wdHJhcF9vaWRfbGVuKSkgewogICAgICAgICAgICBzbm1wX2xvZyhMT0dfV0FSTklORywKICAgICAgICAgICAgICAgICAgICAgInNlbmRfdHJhcDogbm8gdjIgdHJhcE9JRCB2YXJiaW5kIHByb3ZpZGVkXG4iKTsKICAgICAgICAgICAgc25tcF9mcmVlX3BkdSh0ZW1wbGF0ZV92MnBkdSk7CiAgICAgICAgICAgIHJldHVybiAtMTsKICAgICAgICB9CiAgICAgICAgaWYgKCFzbm1wX29pZF9jb21wYXJlKHZibGlzdC0+dmFsLm9iamlkLCBPSURfTEVOR1RIKHRyYXBfcHJlZml4KSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJhcF9wcmVmaXgsICAgICAgIE9JRF9MRU5HVEgodHJhcF9wcmVmaXgpKSkgewogICAgICAgICAgICB2YXIgPSBmaW5kX3ZhcmJpbmRfaW5fbGlzdCggdGVtcGxhdGVfdjJwZHUtPnZhcmlhYmxlcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNubXB0cmFwZW50ZXJwcmlzZV9vaWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzbm1wdHJhcGVudGVycHJpc2Vfb2lkX2xlbik7CiAgICAgICAgICAgIGlmICghdmFyICYmCiAgICAgICAgICAgICAgICAhc25tcF92YXJsaXN0X2FkZF92YXJpYWJsZSggJih0ZW1wbGF0ZV92MnBkdS0+dmFyaWFibGVzKSwKICAgICAgICAgICAgICAgICAgICAgc25tcHRyYXBlbnRlcnByaXNlX29pZCwgc25tcHRyYXBlbnRlcnByaXNlX29pZF9sZW4sCiAgICAgICAgICAgICAgICAgICAgIEFTTl9PQkpFQ1RfSUQsCiAgICAgICAgICAgICAgICAgICAgIGVudGVycHJpc2UsIGVudGVycHJpc2VfbGVuZ3RoKnNpemVvZihvaWQpKSkgewogICAgICAgICAgICAgICAgc25tcF9sb2coTE9HX1dBUk5JTkcsCiAgICAgICAgICAgICAgICAgICAgICJzZW5kX3RyYXA6IGZhaWxlZCB0byBhZGQgc25tcEVudGVycHJpc2UgdG8gdjIgdHJhcFxuIik7CiAgICAgICAgICAgICAgICBzbm1wX2ZyZWVfcGR1KHRlbXBsYXRlX3YycGR1KTsKICAgICAgICAgICAgICAgIHJldHVybiAtMTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICAgICAgCgogICAgICAgIC8qCiAgICAgICAgICogSWYgZXZlcnl0aGluZydzIE9LLCBjb252ZXJ0IHRoZSB2MiB0ZW1wbGF0ZSBpbnRvIGFuIFNOTVB2MSB0cmFwIFBEVS4KICAgICAgICAgKi8KICAgICAgICB0ZW1wbGF0ZV92MXBkdSA9IGNvbnZlcnRfdjJwZHVfdG9fdjEoIHRlbXBsYXRlX3YycGR1ICk7CiAgICAgICAgaWYgKCF0ZW1wbGF0ZV92MXBkdSkgewogICAgICAgICAgICBzbm1wX2xvZyhMT0dfV0FSTklORywKICAgICAgICAgICAgICAgICAgICAgInNlbmRfdHJhcDogZmFpbGVkIHRvIGNvbnZlcnQgdjItPnYxIHRlbXBsYXRlIFBEVVxuIik7CiAgICAgICAgfQoKICAgIH0gZWxzZSB7CiAgICAgICAgLyoKICAgICAgICAgKiBDb25zdHJ1Y3QgdGhlIFNOTVB2MSB0cmFwIFBEVS4uLi4KICAgICAgICAgKi8KICAgICAgICB0ZW1wbGF0ZV92MXBkdSA9IHNubXBfcGR1X2NyZWF0ZShTTk1QX01TR19UUkFQKTsKICAgICAgICBpZiAoIXRlbXBsYXRlX3YxcGR1KSB7CiAgICAgICAgICAgIHNubXBfbG9nKExPR19XQVJOSU5HLAogICAgICAgICAgICAgICAgICAgICAic2VuZF90cmFwOiBmYWlsZWQgdG8gY29uc3RydWN0IHYxIHRlbXBsYXRlIFBEVVxuIik7CiAgICAgICAgICAgIHNubXBfZnJlZV92YXJiaW5kKHZibGlzdCk7CiAgICAgICAgICAgIHJldHVybiAtMTsKICAgICAgICB9CiAgICAgICAgdGVtcGxhdGVfdjFwZHUtPnRyYXBfdHlwZSAgICAgPSB0cmFwOwogICAgICAgIHRlbXBsYXRlX3YxcGR1LT5zcGVjaWZpY190eXBlID0gc3BlY2lmaWM7CiAgICAgICAgdGVtcGxhdGVfdjFwZHUtPnRpbWUgICAgICAgICAgPSBuZXRzbm1wX2dldF9hZ2VudF91cHRpbWUoKTsKCiAgICAgICAgaWYgKHNubXBfY2xvbmVfbWVtKCh2b2lkICoqKSAmdGVtcGxhdGVfdjFwZHUtPmVudGVycHJpc2UsCiAgICAgICAgICAgICAgICAgICAgICAgZW50ZXJwcmlzZSwgZW50ZXJwcmlzZV9sZW5ndGggKiBzaXplb2Yob2lkKSkpIHsKICAgICAgICAgICAgc25tcF9sb2coTE9HX1dBUk5JTkcsCiAgICAgICAgICAgICAgICAgICAgICJzZW5kX3RyYXA6IGZhaWxlZCB0byBzZXQgdjEgZW50ZXJwcmlzZSBPSURcbiIpOwogICAgICAgICAgICBzbm1wX2ZyZWVfdmFyYmluZCh2Ymxpc3QpOwogICAgICAgICAgICBzbm1wX2ZyZWVfcGR1KHRlbXBsYXRlX3YxcGR1KTsKICAgICAgICAgICAgcmV0dXJuIC0xOwogICAgICAgIH0KICAgICAgICB0ZW1wbGF0ZV92MXBkdS0+ZW50ZXJwcmlzZV9sZW5ndGggPSBlbnRlcnByaXNlX2xlbmd0aDsKCiAgICAgICAgdGVtcGxhdGVfdjFwZHUtPmZsYWdzICAgIHw9IFVDRF9NU0dfRkxBR19GT1JDRV9QRFVfQ09QWTsKICAgICAgICB0ZW1wbGF0ZV92MXBkdS0+dmFyaWFibGVzID0gdmJsaXN0OwoKICAgICAgICAvKgogICAgICAgICAqIC4uLiBhbmQgY29udmVydCBpdCBpbnRvIGFuIFNOTVB2Mi1zdHlsZSBub3RpZmljYXRpb24gUERVLgogICAgICAgICAqLwoKICAgICAgICB0ZW1wbGF0ZV92MnBkdSA9IGNvbnZlcnRfdjFwZHVfdG9fdjIoIHRlbXBsYXRlX3YxcGR1ICk7CiAgICAgICAgaWYgKCF0ZW1wbGF0ZV92MnBkdSkgewogICAgICAgICAgICBzbm1wX2xvZyhMT0dfV0FSTklORywKICAgICAgICAgICAgICAgICAgICAgInNlbmRfdHJhcDogZmFpbGVkIHRvIGNvbnZlcnQgdjEtPnYyIHRlbXBsYXRlIFBEVVxuIik7CiAgICAgICAgfQogICAgfQoKICAgIC8qCiAgICAgKiBDaGVjayB3aGV0aGVyIHdlJ3JlIGlnbm9yaW5nIGF1dGhGYWlsIHRyYXBzCiAgICAgKi8KICAgIGlmICh0ZW1wbGF0ZV92MXBkdSkgewogICAgICBpZiAodGVtcGxhdGVfdjFwZHUtPnRyYXBfdHlwZSA9PSBTTk1QX1RSQVBfQVVUSEZBSUwgJiYKICAgICAgICBzbm1wX2VuYWJsZWF1dGhlbnRyYXBzID09IFNOTVBfQVVUSEVOVElDQVRFRF9UUkFQU19ESVNBQkxFRCkgewogICAgICAgIHNubXBfZnJlZV9wZHUodGVtcGxhdGVfdjFwZHUpOwogICAgICAgIHNubXBfZnJlZV9wZHUodGVtcGxhdGVfdjJwZHUpOwogICAgICAgIHJldHVybiAwOwogICAgICB9CgogICAgLyoKICAgICAqIEVuc3VyZSB0aGF0IHRoZSB2MSB0cmFwIFBEVSBpbmNsdWRlcyB0aGUgbG9jYWwgSVAgYWRkcmVzcwogICAgICovCiAgICAgICBwZHVfaW5fYWRkcl90ID0gKGluX2FkZHJfdCAqKSB0ZW1wbGF0ZV92MXBkdS0+YWdlbnRfYWRkcjsKICAgICAgIHYxdHJhcGFkZHJlc3MgPSBuZXRzbm1wX2RzX2dldF9zdHJpbmcoTkVUU05NUF9EU19BUFBMSUNBVElPTl9JRCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTkVUU05NUF9EU19BR0VOVF9UUkFQX0FERFIpOwogICAgICAgaWYgKHYxdHJhcGFkZHJlc3MgIT0gTlVMTCkgewogICAgICAgICAgIC8qICJ2MXRyYXBhZGRyZXNzIiB3YXMgc3BlY2lmaWVkIGluIGNvbmZpZywgdHJ5IHRvIHJlc29sdmUgaXQgKi8KICAgICAgICAgICByZXMgPSBuZXRzbm1wX2dldGhvc3RieW5hbWVfdjQodjF0cmFwYWRkcmVzcywgcGR1X2luX2FkZHJfdCk7CiAgICAgICB9CiAgICAgICBpZiAodjF0cmFwYWRkcmVzcyA9PSBOVUxMIHx8IHJlcyA8IDApIHsKICAgICAgICAgICAvKiAidjF0cmFwYWRkcmVzcyIgd2FzIG5vdCBzcGVjaWZpZWQgaW4gY29uZmlnIG9yIHRoZSByZXNvbHV0aW9uIGZhaWxlZCwKICAgICAgICAgICAgKiB0cnkgYW55IGxvY2FsIGFkZHJlc3MgKi8KICAgICAgICAgICAqcGR1X2luX2FkZHJfdCA9IGdldF9teWFkZHIoKTsKICAgICAgIH0KCiAgICB9CgogICAgaWYgKHRlbXBsYXRlX3YycGR1KSB7CgkvKiBBIGNvbnRleHQgbmFtZSB3YXMgcHJvdmlkZWQsIHNvIGNvcHkgaXQgYW5kIGl0cyBsZW5ndGggdG8gdGhlIHYyIHBkdQoJICogdGVtcGxhdGUuICovCglpZiAoY29udGV4dCAhPSBOVUxMKQoJewoJCXRlbXBsYXRlX3YycGR1LT5jb250ZXh0TmFtZSAgICA9IHN0cmR1cChjb250ZXh0KTsKCQl0ZW1wbGF0ZV92MnBkdS0+Y29udGV4dE5hbWVMZW4gPSBzdHJsZW4oY29udGV4dCk7Cgl9CiAgICB9CgogICAgLyoKICAgICAqICBOb3cgbG9vcCB0aHJvdWdoIHRoZSBsaXN0IG9mIHRyYXAgc2lua3MKICAgICAqICAgYW5kIGNhbGwgdGhlIHRyYXAgY2FsbGJhY2sgcm91dGluZXMsCiAgICAgKiAgIHByb3ZpZGluZyBhbiBhcHByb3ByaWF0ZWx5IGZvcm1hdHRlZCBQRFUgaW4gZWFjaCBjYXNlCiAgICAgKi8KICAgIGZvciAoc2luayA9IHNpbmtzOyBzaW5rOyBzaW5rID0gc2luay0+bmV4dCkgewojaWZuZGVmIE5FVFNOTVBfRElTQUJMRV9TTk1QVjEKICAgICAgICBpZiAoc2luay0+dmVyc2lvbiA9PSBTTk1QX1ZFUlNJT05fMSkgewogICAgICAgICAgaWYgKHRlbXBsYXRlX3YxcGR1KSB7CiAgICAgICAgICAgIHNlbmRfdHJhcF90b19zZXNzKHNpbmstPnNlc3AsIHRlbXBsYXRlX3YxcGR1KTsKICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgewojZW5kaWYKICAgICAgICAgIGlmICh0ZW1wbGF0ZV92MnBkdSkgewogICAgICAgICAgICB0ZW1wbGF0ZV92MnBkdS0+Y29tbWFuZCA9IHNpbmstPnBkdXR5cGU7CiAgICAgICAgICAgIHNlbmRfdHJhcF90b19zZXNzKHNpbmstPnNlc3AsIHRlbXBsYXRlX3YycGR1KTsKICAgICAgICAgIH0KI2lmbmRlZiBORVRTTk1QX0RJU0FCTEVfU05NUFYxCiAgICAgICAgfQojZW5kaWYKICAgIH0KICAgIGlmICh0ZW1wbGF0ZV92MXBkdSkKICAgICAgICBzbm1wX2NhbGxfY2FsbGJhY2tzKFNOTVBfQ0FMTEJBQ0tfQVBQTElDQVRJT04sCiAgICAgICAgICAgICAgICAgICAgICAgIFNOTVBEX0NBTExCQUNLX1NFTkRfVFJBUDEsIHRlbXBsYXRlX3YxcGR1KTsKICAgIGlmICh0ZW1wbGF0ZV92MnBkdSkKICAgICAgICBzbm1wX2NhbGxfY2FsbGJhY2tzKFNOTVBfQ0FMTEJBQ0tfQVBQTElDQVRJT04sCiAgICAgICAgICAgICAgICAgICAgICAgIFNOTVBEX0NBTExCQUNLX1NFTkRfVFJBUDIsIHRlbXBsYXRlX3YycGR1KTsKICAgIHNubXBfZnJlZV9wZHUodGVtcGxhdGVfdjFwZHUpOwogICAgc25tcF9mcmVlX3BkdSh0ZW1wbGF0ZV92MnBkdSk7CiAgICByZXR1cm4gMDsKfQoKCnZvaWQKc2VuZF9lbnRlcnByaXNlX3RyYXBfdmFycyhpbnQgdHJhcCwKICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgc3BlY2lmaWMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgb2lkICogZW50ZXJwcmlzZSwgaW50IGVudGVycHJpc2VfbGVuZ3RoLAogICAgICAgICAgICAgICAgICAgICAgICAgIG5ldHNubXBfdmFyaWFibGVfbGlzdCAqIHZhcnMpCnsKICAgIG5ldHNubXBfc2VuZF90cmFwcyh0cmFwLCBzcGVjaWZpYywKICAgICAgICAgICAgICAgICAgICAgICBlbnRlcnByaXNlLCBlbnRlcnByaXNlX2xlbmd0aCwKICAgICAgICAgICAgICAgICAgICAgICB2YXJzLCBOVUxMLCAwKTsKICAgIHJldHVybjsKfQoKLyoqCiAqIENhcHR1cmVzIHJlc3BvbnNlcyBvciB0aGUgbGFjayB0aGVyZSBvZiBmcm9tIElORk9STXMgdGhhdCB3ZXJlIHNlbnQKICogMSkgYSByZXNwb25zZSBpcyByZWNlaXZlZCBmcm9tIGFuIElORk9STQogKiAyKSBvbmUgaXNuJ3QgcmVjZWl2ZWQgYW5kIHRoZSByZXRyaWVzL3RpbWVvdXRzIGhhdmUgZmFpbGVkCiovCmludApoYW5kbGVfaW5mb3JtX3Jlc3BvbnNlKGludCBvcCwgbmV0c25tcF9zZXNzaW9uICogc2Vzc2lvbiwKICAgICAgICAgICAgICAgICAgICAgICBpbnQgcmVxaWQsIG5ldHNubXBfcGR1ICpwZHUsCiAgICAgICAgICAgICAgICAgICAgICAgdm9pZCAqbWFnaWMpCnsKICAgIC8qIFhYWDogcG9zc2libHkgc3RhdHMgdXBkYXRlICovCiAgICBzd2l0Y2ggKG9wKSB7CgogICAgY2FzZSBORVRTTk1QX0NBTExCQUNLX09QX1JFQ0VJVkVEX01FU1NBR0U6CiAgICAgICAgc25tcF9pbmNyZW1lbnRfc3RhdGlzdGljKFNUQVRfU05NUElOUEtUUyk7CiAgICAgICAgREVCVUdNU0dUTCgoInRyYXAiLCAicmVjZWl2ZWQgdGhlIGluZm9ybSByZXNwb25zZSBmb3IgcmVxaWQ9JWRcbiIsCiAgICAgICAgICAgICAgICAgICAgcmVxaWQpKTsKICAgICAgICBicmVhazsKCiAgICBjYXNlIE5FVFNOTVBfQ0FMTEJBQ0tfT1BfVElNRURfT1VUOgogICAgICAgIERFQlVHTVNHVEwoKCJ0cmFwIiwKICAgICAgICAgICAgICAgICAgICAicmVjZWl2ZWQgYSB0aW1lb3V0IHNlbmRpbmcgYW4gaW5mb3JtIGZvciByZXFpZD0lZFxuIiwKICAgICAgICAgICAgICAgICAgICByZXFpZCkpOwogICAgICAgIGJyZWFrOwoKICAgIGNhc2UgTkVUU05NUF9DQUxMQkFDS19PUF9TRU5EX0ZBSUxFRDoKICAgICAgICBERUJVR01TR1RMKCgidHJhcCIsCiAgICAgICAgICAgICAgICAgICAgImZhaWxlZCB0byBzZW5kIGFuIGluZm9ybSBmb3IgcmVxaWQ9JWRcbiIsCiAgICAgICAgICAgICAgICAgICAgcmVxaWQpKTsKICAgICAgICBicmVhazsKCiAgICBkZWZhdWx0OgogICAgICAgIERFQlVHTVNHVEwoKCJ0cmFwIiwgInJlY2VpdmVkIG9wPSVkIGZvciByZXFpZD0lZCB3aGVuIHRyeWluZyB0byBzZW5kIGFuIGluZm9ybVxuIiwgb3AsIHJlcWlkKSk7CiAgICB9CgogICAgcmV0dXJuIDE7Cn0KCgovKgogKiBzZW5kX3RyYXBfdG9fc2Vzczogc2VuZHMgYSB0cmFwIHRvIGEgc2Vzc2lvbiBidXQgYXNzdW1lcyB0aGF0IHRoZQogKiBwZHUgaXMgY29uc3RydWN0ZWQgY29ycmVjdGx5IGZvciB0aGUgc2Vzc2lvbiB0eXBlLiAKICovCnZvaWQKc2VuZF90cmFwX3RvX3Nlc3MobmV0c25tcF9zZXNzaW9uICogc2VzcywgbmV0c25tcF9wZHUgKnRlbXBsYXRlX3BkdSkKewogICAgbmV0c25tcF9wZHUgICAgKnBkdTsKICAgIGludCAgICAgICAgICAgIHJlc3VsdDsKCiAgICBpZiAoIXNlc3MgfHwgIXRlbXBsYXRlX3BkdSkKICAgICAgICByZXR1cm47CgogICAgREVCVUdNU0dUTCgoInRyYXAiLCAic2VuZGluZyB0cmFwIHR5cGU9JWQsIHZlcnNpb249JWxkXG4iLAogICAgICAgICAgICAgICAgdGVtcGxhdGVfcGR1LT5jb21tYW5kLCBzZXNzLT52ZXJzaW9uKSk7CgojaWZuZGVmIE5FVFNOTVBfRElTQUJMRV9TTk1QVjEKICAgIGlmIChzZXNzLT52ZXJzaW9uID09IFNOTVBfVkVSU0lPTl8xICYmCiAgICAgICAgKHRlbXBsYXRlX3BkdS0+Y29tbWFuZCAhPSBTTk1QX01TR19UUkFQKSkKICAgICAgICByZXR1cm47ICAgICAgICAgICAgICAgICAvKiBTa2lwIHYxIHNpbmtzIGZvciB2MiBvbmx5IHRyYXBzICovCiAgICBpZiAoc2Vzcy0+dmVyc2lvbiAhPSBTTk1QX1ZFUlNJT05fMSAmJgogICAgICAgICh0ZW1wbGF0ZV9wZHUtPmNvbW1hbmQgPT0gU05NUF9NU0dfVFJBUCkpCiAgICAgICAgcmV0dXJuOyAgICAgICAgICAgICAgICAgLyogU2tpcCB2Misgc2lua3MgZm9yIHYxIG9ubHkgdHJhcHMgKi8KI2VuZGlmCiAgICB0ZW1wbGF0ZV9wZHUtPnZlcnNpb24gPSBzZXNzLT52ZXJzaW9uOwogICAgcGR1ID0gc25tcF9jbG9uZV9wZHUodGVtcGxhdGVfcGR1KTsKICAgIHBkdS0+c2Vzc2lkID0gc2Vzcy0+c2Vzc2lkOyAvKiBBZ2VudFggb25seSA/ICovCgogICAgaWYgKCB0ZW1wbGF0ZV9wZHUtPmNvbW1hbmQgPT0gU05NUF9NU0dfSU5GT1JNCiNpZmRlZiBVU0lOR19BR0VOVFhfUFJPVE9DT0xfTU9EVUxFCiAgICAgICAgIHx8IHRlbXBsYXRlX3BkdS0+Y29tbWFuZCA9PSBBR0VOVFhfTVNHX05PVElGWQojZW5kaWYKICAgICAgICkgewogICAgICAgIHJlc3VsdCA9CiAgICAgICAgICAgIHNubXBfYXN5bmNfc2VuZChzZXNzLCBwZHUsICZoYW5kbGVfaW5mb3JtX3Jlc3BvbnNlLCBOVUxMKTsKICAgICAgICAKICAgIH0gZWxzZSB7CiAgICAgICAgaWYgKChzZXNzLT52ZXJzaW9uID09IFNOTVBfVkVSU0lPTl8zKSAmJgogICAgICAgICAgICAgICAgKHBkdS0+Y29tbWFuZCA9PSBTTk1QX01TR19UUkFQMikgJiYKICAgICAgICAgICAgICAgIChzZXNzLT5zZWN1cml0eUVuZ2luZUlETGVuID09IDApKSB7CiAgICAgICAgICAgIHVfY2hhciAgICAgICAgICB0bXBbU1BSSU5UX01BWF9MRU5dOwoKICAgICAgICAgICAgaW50IGxlbiA9IHNubXB2M19nZXRfZW5naW5lSUQodG1wLCBzaXplb2YodG1wKSk7CiAgICAgICAgICAgIHBkdS0+c2VjdXJpdHlFbmdpbmVJRCA9IG5ldHNubXBfbWVtZHVwKHRtcCwgbGVuKTsKICAgICAgICAgICAgcGR1LT5zZWN1cml0eUVuZ2luZUlETGVuID0gbGVuOwogICAgICAgIH0KCiAgICAgICAgcmVzdWx0ID0gc25tcF9zZW5kKHNlc3MsIHBkdSk7CiAgICB9CgogICAgaWYgKHJlc3VsdCA9PSAwKSB7CiAgICAgICAgc25tcF9zZXNzX3BlcnJvcigic25tcGQ6IHNlbmRfdHJhcCIsIHNlc3MpOwogICAgICAgIHNubXBfZnJlZV9wZHUocGR1KTsKICAgIH0gZWxzZSB7CiAgICAgICAgc25tcF9pbmNyZW1lbnRfc3RhdGlzdGljKFNUQVRfU05NUE9VVFRSQVBTKTsKICAgICAgICBzbm1wX2luY3JlbWVudF9zdGF0aXN0aWMoU1RBVF9TTk1QT1VUUEtUUyk7CiAgICB9Cn0KCnZvaWQKc2VuZF90cmFwX3ZhcnMoaW50IHRyYXAsIGludCBzcGVjaWZpYywgbmV0c25tcF92YXJpYWJsZV9saXN0ICogdmFycykKewogICAgaWYgKHRyYXAgPT0gU05NUF9UUkFQX0VOVEVSUFJJU0VTUEVDSUZJQykKICAgICAgICBzZW5kX2VudGVycHJpc2VfdHJhcF92YXJzKHRyYXAsIHNwZWNpZmljLCBvYmppZF9lbnRlcnByaXNldHJhcCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE9JRF9MRU5HVEgob2JqaWRfZW50ZXJwcmlzZXRyYXApLCB2YXJzKTsKICAgIGVsc2UKICAgICAgICBzZW5kX2VudGVycHJpc2VfdHJhcF92YXJzKHRyYXAsIHNwZWNpZmljLCB0cmFwX3ZlcnNpb25faWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBPSURfTEVOR1RIKHRyYXBfdmVyc2lvbl9pZCksIHZhcnMpOwp9CgojaWZuZGVmIE5FVFNOTVBfRkVBVFVSRV9SRU1PVkVfVFJBUF9WQVJTX1dJVEhfQ09OVEVYVAovKiBTZW5kIGEgdHJhcCB1bmRlciBhIGNvbnRleHQgKi8Kdm9pZCBzZW5kX3RyYXBfdmFyc193aXRoX2NvbnRleHQoaW50IHRyYXAsIGludCBzcGVjaWZpYywgCiAgICAgICAgICAgICAgbmV0c25tcF92YXJpYWJsZV9saXN0ICp2YXJzLCBjb25zdCBjaGFyICpjb250ZXh0KQp7CiAgICBpZiAodHJhcCA9PSBTTk1QX1RSQVBfRU5URVJQUklTRVNQRUNJRklDKQogICAgICAgIG5ldHNubXBfc2VuZF90cmFwcyh0cmFwLCBzcGVjaWZpYywgb2JqaWRfZW50ZXJwcmlzZXRyYXAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBPSURfTEVOR1RIKG9iamlkX2VudGVycHJpc2V0cmFwKSwgdmFycywKCQkJCQkJCQkgIGNvbnRleHQsIDApOwogICAgZWxzZQogICAgICAgIG5ldHNubXBfc2VuZF90cmFwcyh0cmFwLCBzcGVjaWZpYywgdHJhcF92ZXJzaW9uX2lkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgT0lEX0xFTkdUSCh0cmFwX3ZlcnNpb25faWQpLCB2YXJzLCAKCQkJCQkJCQkgIGNvbnRleHQsIDApOwogICAgCQp9CiNlbmRpZiAvKiBORVRTTk1QX0ZFQVRVUkVfUkVNT1ZFX1RSQVBfVkFSU19XSVRIX0NPTlRFWFQgKi8KCi8qKgogKiBTZW5kcyBhbiBTTk1QdjEgdHJhcCAob3IgdGhlIFNOTVB2MiBlcXVpdmFsZW50KSB0byB0aGUgbGlzdCBvZiAgCiAqIGNvbmZpZ3VyZWQgdHJhcCBkZXN0aW5hdGlvbnMgKG9yICJzaW5rcyIpLCB1c2luZyB0aGUgcHJvdmlkZWQgCiAqIHZhbHVlcyBmb3IgdGhlIGdlbmVyaWMgdHJhcCB0eXBlIGFuZCBzcGVjaWZpYyB0cmFwIHZhbHVlLgogKgogKiBUaGlzIGZ1bmN0aW9uIGV2ZW50dWFsbHkgY2FsbHMgc2VuZF9lbnRlcnByaXNlX3RyYXBfdmFycy4gIElmIHRoZQogKiB0cmFwIHR5cGUgaXMgbm90IHNldCB0byBTTk1QX1RSQVBfRU5URVJQUklTRVNQRUNJRklDIHRoZSBlbnRlcnByaXNlIAogKiBhbmQgZW50ZXJwcmlzZV9sZW5ndGggcGFyYW1hdGVyIGlzIHNldCB0byB0aGUgcHJlIGRlZmluZWQgTkVUU05NUF9TWVNURU1fTUlCIAogKiBvaWQgYW5kIGxlbmd0aCByZXNwZWN0aXZlbHkuICBJZiB0aGUgdHJhcCB0eXBlIGlzIHNldCB0byAKICogU05NUF9UUkFQX0VOVEVSUFJJU0VTUEVDSUZJQyB0aGUgZW50ZXJwcmlzZSBhbmQgZW50ZXJwcmlzZV9sZW5ndGggCiAqIHBhcmFtZXRlcnMgYXJlIHNldCB0byB0aGUgcHJlLWRlZmluZWQgTkVUU05NUF9OT1RJRklDQVRJT05fTUlCIG9pZCBhbmQgbGVuZ3RoIAogKiByZXNwZWN0aXZlbHkuCiAqCiAqIEBwYXJhbSB0cmFwIGlzIHRoZSBnZW5lcmljIHRyYXAgdHlwZS4KICoKICogQHBhcmFtIHNwZWNpZmljIGlzIHRoZSBzcGVjaWZpYyB0cmFwIHZhbHVlLgogKgogKiBAcmV0dXJuIHZvaWQKICoKICogQHNlZSBzZW5kX2VudGVycHJpc2VfdHJhcF92YXJzCiAqIEBzZWUgc2VuZF92MnRyYXAKICovCiAgICAgICAJCnZvaWQKc2VuZF9lYXN5X3RyYXAoaW50IHRyYXAsIGludCBzcGVjaWZpYykKewogICAgc2VuZF90cmFwX3ZhcnModHJhcCwgc3BlY2lmaWMsIE5VTEwpOwp9CgovKioKICogVXNlcyB0aGUgc3VwcGxpZWQgbGlzdCBvZiB2YXJpYWJsZSBiaW5kaW5ncyB0byBmb3JtIGFuIFNOTVB2MiB0cmFwLCAKICogd2hpY2ggaXMgc2VudCB0byBTTk1QdjItY2FwYWJsZSBzaW5rcyAgb24gIHRoZSAgY29uZmlndXJlZCAgbGlzdC4gIAogKiBBbiBlcXVpdmFsZW50IElORk9STSBpcyBzZW50IHRvIHRoZSBjb25maWd1cmVkIGxpc3Qgb2YgaW5mb3JtIHNpbmtzLiAgCiAqIFNpbmtzIHRoYXQgY2FuIG9ubHkgaGFuZGxlIFNOTVB2MSB0cmFwcyBhcmUgc2tpcHBlZC4KICoKICogVGhpcyBmdW5jdGlvbiBldmVudHVhbGx5IGNhbGxzIHNlbmRfZW50ZXJwcmlzZV90cmFwX3ZhcnMuICBJZiB0aGUKICogdHJhcCB0eXBlIGlzIG5vdCBzZXQgdG8gU05NUF9UUkFQX0VOVEVSUFJJU0VTUEVDSUZJQyB0aGUgZW50ZXJwcmlzZSAKICogYW5kIGVudGVycHJpc2VfbGVuZ3RoIHBhcmFtYXRlciBpcyBzZXQgdG8gdGhlIHByZSBkZWZpbmVkIE5FVFNOTVBfU1lTVEVNX01JQiAKICogb2lkIGFuZCBsZW5ndGggcmVzcGVjdGl2ZWx5LiAgSWYgdGhlIHRyYXAgdHlwZSBpcyBzZXQgdG8gCiAqIFNOTVBfVFJBUF9FTlRFUlBSSVNFU1BFQ0lGSUMgdGhlIGVudGVycHJpc2UgYW5kIGVudGVycHJpc2VfbGVuZ3RoIAogKiBwYXJhbWV0ZXJzIGFyZSBzZXQgdG8gdGhlIHByZS1kZWZpbmVkIE5FVFNOTVBfTk9USUZJQ0FUSU9OX01JQiBvaWQgYW5kIGxlbmd0aCAKICogcmVzcGVjdGl2ZWx5LgogKgogKiBAcGFyYW0gdmFycyBpcyB1c2VkIHRvIHN1cHBseSBsaXN0IG9mIHZhcmlhYmxlIGJpbmRpbmdzIHRvIGZvcm0gYW4gU05NUHYyIAogKgl0cmFwLgogKgogKiBAcmV0dXJuIHZvaWQKICoKICogQHNlZSBzZW5kX2Vhc3lfdHJhcAogKiBAc2VlIHNlbmRfZW50ZXJwcmlzZV90cmFwX3ZhcnMKICovCgp2b2lkCnNlbmRfdjJ0cmFwKG5ldHNubXBfdmFyaWFibGVfbGlzdCAqIHZhcnMpCnsKICAgIHNlbmRfdHJhcF92YXJzKC0xLCAtMSwgdmFycyk7Cn0KCi8qKgogKiBTaW1pbGFyIHRvIHNlbmRfdjJ0cmFwKCksIHdpdGggdGhlIGFkZGVkIGFiaWxpdHkgdG8gc3BlY2lmeSBhIGNvbnRleHQuICBJZgogKiB0aGUgbGFzdCBwYXJhbWV0ZXIgaXMgTlVMTCwgdGhlbiB0aGlzIGNhbGwgaXMgZXF1aXZhbGVudCB0byBzZW5kX3YydHJhcCgpLgogKgogKiBAcGFyYW0gdmFycyBpcyB1c2VkIHRvIHN1cHBseSB0aGUgbGlzdCBvZiB2YXJpYWJsZSBiaW5kaW5ncyBmb3IgdGhlIHRyYXAuCiAqIAogKiBAcGFyYW0gY29udGV4dCBpcyB1c2VkIHRvIHNwZWNpZnkgdGhlIGNvbnRleHQgb2YgdGhlIHRyYXAuCiAqCiAqIEByZXR1cm4gdm9pZAogKgogKiBAc2VlIHNlbmRfdjJ0cmFwCiAqLwojaWZuZGVmIE5FVFNOTVBfRkVBVFVSRV9SRU1PVkVfU0VORF9WM1RSQVAKdm9pZCBzZW5kX3YzdHJhcChuZXRzbm1wX3ZhcmlhYmxlX2xpc3QgKnZhcnMsIGNvbnN0IGNoYXIgKmNvbnRleHQpCnsKICAgIG5ldHNubXBfc2VuZF90cmFwcygtMSwgLTEsIAogICAgICAgICAgICAgICAgICAgICAgIHRyYXBfdmVyc2lvbl9pZCwgT0lEX0xFTkdUSCh0cmFwX3ZlcnNpb25faWQpLAogICAgICAgICAgICAgICAgICAgICAgIHZhcnMsIGNvbnRleHQsIDApOwp9CiNlbmRpZiAvKiBORVRTTk1QX0ZFQVRVUkVfUkVNT1ZFX1NFTkRfVjNUUkFQICovCgojaWZuZGVmIE5FVFNOTVBfRkVBVFVSRV9SRU1PVkVfU0VORF9UUkFQX1BEVQp2b2lkCnNlbmRfdHJhcF9wZHUobmV0c25tcF9wZHUgKnBkdSkKewogICAgc2VuZF90cmFwX3ZhcnMoLTEsIC0xLCBwZHUtPnZhcmlhYmxlcyk7Cn0KI2VuZGlmIC8qIE5FVFNOTVBfRkVBVFVSRV9SRU1PVkVfU0VORF9UUkFQX1BEVSAqLwoKCgogICAgICAgIC8qKioqKioqKioqKioqKioqKioqCgkgKgoJICogQ29uZmlnIGZpbGUgaGFuZGxpbmcKCSAqCgkgKioqKioqKioqKioqKioqKioqKi8KCnZvaWQKc25tcGRfcGFyc2VfY29uZmlnX2F1dGh0cmFwKGNvbnN0IGNoYXIgKnRva2VuLCBjaGFyICpjcHRyKQp7CiAgICBpbnQgICAgICAgICAgICAgaTsKCiAgICBpID0gYXRvaShjcHRyKTsKICAgIGlmIChpID09IDApIHsKICAgICAgICBpZiAoc3RyY21wKGNwdHIsICJlbmFibGUiKSA9PSAwKSB7CiAgICAgICAgICAgIGkgPSBTTk1QX0FVVEhFTlRJQ0FURURfVFJBUFNfRU5BQkxFRDsKICAgICAgICB9IGVsc2UgaWYgKHN0cmNtcChjcHRyLCAiZGlzYWJsZSIpID09IDApIHsKICAgICAgICAgICAgaSA9IFNOTVBfQVVUSEVOVElDQVRFRF9UUkFQU19ESVNBQkxFRDsKICAgICAgICB9CiAgICB9CiAgICBpZiAoaSA8IDEgfHwgaSA+IDIpIHsKICAgICAgICBjb25maWdfcGVycm9yKCJhdXRodHJhcGVuYWJsZSBtdXN0IGJlIDEgb3IgMiIpOwogICAgfSBlbHNlIHsKICAgICAgICBpZiAoc3RyY21wKHRva2VuLCAicGF1dGh0cmFwZW5hYmxlIikgPT0gMCkgewogICAgICAgICAgICBpZiAoc25tcF9lbmFibGVhdXRoZW50cmFwc3NldCA8IDApIHsKICAgICAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAgICAgKiBUaGlzIGlzIGJvZ3VzIChhbmQgc2hvdWxkbid0IGhhcHBlbiBhbnl3YXkpIC0tIHRoZSB2YWx1ZQogICAgICAgICAgICAgICAgICogb2Ygc25tcEVuYWJsZUF1dGhlblRyYXBzLjAgaXMgYWxyZWFkeSBjb25maWd1cmVkCiAgICAgICAgICAgICAgICAgKiByZWFkLW9ubHkuICAKICAgICAgICAgICAgICAgICAqLwogICAgICAgICAgICAgICAgc25tcF9sb2coTE9HX1dBUk5JTkcsCiAgICAgICAgICAgICAgICAgICAgICAgICAiaWdub3JpbmcgYXR0ZW1wdGVkIG92ZXJyaWRlIG9mIHJlYWQtb25seSBzbm1wRW5hYmxlQXV0aGVuVHJhcHMuMFxuIik7CiAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBzbm1wX2VuYWJsZWF1dGhlbnRyYXBzc2V0Kys7CiAgICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBpZiAoc25tcF9lbmFibGVhdXRoZW50cmFwc3NldCA+IDApIHsKICAgICAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAgICAgKiBUaGlzIGlzIGJvZ3VzIChhbmQgc2hvdWxkbid0IGhhcHBlbiBhbnl3YXkpIC0tIHdlIGFscmVhZHkKICAgICAgICAgICAgICAgICAqIHJlYWQgYSBwZXJzaXN0ZW50IHZhbHVlIG9mIHNubXBFbmFibGVBdXRoZW5UcmFwcy4wLCB3aGljaAogICAgICAgICAgICAgICAgICogd2Ugc2hvdWxkIGlnbm9yZSBpbiBmYXZvdXIgb2YgdGhpcyBvbmUuICAKICAgICAgICAgICAgICAgICAqLwogICAgICAgICAgICAgICAgc25tcF9sb2coTE9HX1dBUk5JTkcsCiAgICAgICAgICAgICAgICAgICAgICAgICAiaWdub3JpbmcgYXR0ZW1wdGVkIG92ZXJyaWRlIG9mIHJlYWQtb25seSBzbm1wRW5hYmxlQXV0aGVuVHJhcHMuMFxuIik7CiAgICAgICAgICAgICAgICAvKgogICAgICAgICAgICAgICAgICogRmFsbCB0aHJvdWdoIGFuZCBjb3B5IGluIHRoaXMgdmFsdWUuICAKICAgICAgICAgICAgICAgICAqLwogICAgICAgICAgICB9CiAgICAgICAgICAgIHNubXBfZW5hYmxlYXV0aGVudHJhcHNzZXQgPSAtMTsKICAgICAgICB9CiAgICAgICAgc25tcF9lbmFibGVhdXRoZW50cmFwcyA9IGk7CiAgICB9Cn0KCiNpZm5kZWYgTkVUU05NUF9ESVNBQkxFX1NOTVBWMQp2b2lkCnNubXBkX3BhcnNlX2NvbmZpZ190cmFwc2luayhjb25zdCBjaGFyICp0b2tlbiwgY2hhciAqY3B0cikKewogICAgY2hhciAgICAgICAgICAgKnNwLCAqY3AsICpwcCA9IE5VTEw7CiAgICBjaGFyICAgICAgICAgICAgKnN0OwoKICAgIGlmICghc25tcF90cmFwY29tbXVuaXR5KQogICAgICAgIHNubXBfdHJhcGNvbW11bml0eSA9IHN0cmR1cCgicHVibGljIik7CiAgICBzcCA9IHN0cnRva19yKGNwdHIsICIgXHRcbiIsICZzdCk7CiAgICBjcCA9IHN0cnRva19yKE5VTEwsICIgXHRcbiIsICZzdCk7CiAgICBpZiAoY3ApCiAgICAgICAgcHAgPSBzdHJ0b2tfcihOVUxMLCAiIFx0XG4iLCAmc3QpOwogICAgaWYgKHBwKQoJY29uZmlnX3B3YXJuKCJUaGUgc2VwYXJhdGUgcG9ydCBhcmd1bWVudCB0byB0cmFwc2luayBpcyBkZXByZWNhdGVkIik7CiAgICBpZiAoY3JlYXRlX3YxX3RyYXBfc2Vzc2lvbihzcCwgcHAsIGNwID8gY3AgOiBzbm1wX3RyYXBjb21tdW5pdHkpID09IDApIHsKCW5ldHNubXBfY29uZmlnX2Vycm9yKCJjYW5ub3QgY3JlYXRlIHRyYXBzaW5rOiAlcyIsIGNwdHIpOwogICAgfQp9CiNlbmRpZgoKI2lmbmRlZiBORVRTTk1QX0RJU0FCTEVfU05NUFYyQwp2b2lkCnNubXBkX3BhcnNlX2NvbmZpZ190cmFwMnNpbmsoY29uc3QgY2hhciAqd29yZCwgY2hhciAqY3B0cikKewogICAgY2hhciAgICAgICAgICAgKnN0LCAqc3AsICpjcCwgKnBwID0gTlVMTDsKCiAgICBpZiAoIXNubXBfdHJhcGNvbW11bml0eSkKICAgICAgICBzbm1wX3RyYXBjb21tdW5pdHkgPSBzdHJkdXAoInB1YmxpYyIpOwogICAgc3AgPSBzdHJ0b2tfcihjcHRyLCAiIFx0XG4iLCAmc3QpOwogICAgY3AgPSBzdHJ0b2tfcihOVUxMLCAiIFx0XG4iLCAmc3QpOwogICAgaWYgKGNwKQogICAgICAgIHBwID0gc3RydG9rX3IoTlVMTCwgIiBcdFxuIiwgJnN0KTsKICAgIGlmIChwcCkKCWNvbmZpZ19wd2FybigiVGhlIHNlcGFyYXRlIHBvcnQgYXJndW1lbnQgdG8gdHJhcHNpbmsyIGlzIGRlcHJlY2F0ZWQiKTsKICAgIGlmIChjcmVhdGVfdjJfdHJhcF9zZXNzaW9uKHNwLCBwcCwgY3AgPyBjcCA6IHNubXBfdHJhcGNvbW11bml0eSkgPT0gMCkgewoJbmV0c25tcF9jb25maWdfZXJyb3IoImNhbm5vdCBjcmVhdGUgdHJhcDJzaW5rOiAlcyIsIGNwdHIpOwogICAgfQp9Cgp2b2lkCnNubXBkX3BhcnNlX2NvbmZpZ19pbmZvcm1zaW5rKGNvbnN0IGNoYXIgKndvcmQsIGNoYXIgKmNwdHIpCnsKICAgIGNoYXIgICAgICAgICAgICpzdCwgKnNwLCAqY3AsICpwcCA9IE5VTEw7CgogICAgaWYgKCFzbm1wX3RyYXBjb21tdW5pdHkpCiAgICAgICAgc25tcF90cmFwY29tbXVuaXR5ID0gc3RyZHVwKCJwdWJsaWMiKTsKICAgIHNwID0gc3RydG9rX3IoY3B0ciwgIiBcdFxuIiwgJnN0KTsKICAgIGNwID0gc3RydG9rX3IoTlVMTCwgIiBcdFxuIiwgJnN0KTsKICAgIGlmIChjcCkKICAgICAgICBwcCA9IHN0cnRva19yKE5VTEwsICIgXHRcbiIsICZzdCk7CiAgICBpZiAocHApCgljb25maWdfcHdhcm4oIlRoZSBzZXBhcmF0ZSBwb3J0IGFyZ3VtZW50IHRvIGluZm9ybXNpbmsgaXMgZGVwcmVjYXRlZCIpOwogICAgaWYgKGNyZWF0ZV92Ml9pbmZvcm1fc2Vzc2lvbihzcCwgcHAsIGNwID8gY3AgOiBzbm1wX3RyYXBjb21tdW5pdHkpID09IDApIHsKCW5ldHNubXBfY29uZmlnX2Vycm9yKCJjYW5ub3QgY3JlYXRlIGluZm9ybXNpbms6ICVzIiwgY3B0cik7CiAgICB9Cn0KI2VuZGlmCgovKgogKiB0aGlzIG11c3QgYmUgc3RhbmRhcmRpemVkIHNvbWV3aGVyZSwgcmlnaHQ/IAogKi8KI2RlZmluZSBNQVhfQVJHUyAxMjgKCnN0YXRpYyBpbnQgICAgICB0cmFwdHlwZTsKCnN0YXRpYyB2b2lkCnRyYXBPcHRQcm9jKGludCBhcmdjLCBjaGFyICpjb25zdCAqYXJndiwgaW50IG9wdCkKewogICAgc3dpdGNoIChvcHQpIHsKICAgIGNhc2UgJ0MnOgogICAgICAgIHdoaWxlICgqb3B0YXJnKSB7CiAgICAgICAgICAgIHN3aXRjaCAoKm9wdGFyZysrKSB7CiAgICAgICAgICAgIGNhc2UgJ2knOgogICAgICAgICAgICAgICAgdHJhcHR5cGUgPSBTTk1QX01TR19JTkZPUk07CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgIGNvbmZpZ19wZXJyb3IoInVua25vd24gYXJndW1lbnQgcGFzc2VkIHRvIC1DIik7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBicmVhazsKICAgIH0KfQoKCnZvaWQKc25tcGRfcGFyc2VfY29uZmlnX3RyYXBzZXNzKGNvbnN0IGNoYXIgKndvcmQsIGNoYXIgKmNwdHIpCnsKICAgIGNoYXIgICAgICAgICAgICphcmd2W01BWF9BUkdTXSwgKmNwID0gY3B0cjsKICAgIGludCAgICAgICAgICAgICBhcmduLCByYzsKICAgIG5ldHNubXBfc2Vzc2lvbiBzZXNzaW9uLCAqc3M7CiAgICBuZXRzbm1wX3RyYW5zcG9ydCAqdHJhbnNwb3J0OwogICAgc2l6ZV90ICAgICAgICAgIGxlbjsKCiAgICAvKgogICAgICogaW5mb3JtIG9yIHRyYXA/ICBkZWZhdWx0IHRvIHRyYXAgCiAgICAgKi8KICAgIHRyYXB0eXBlID0gU05NUF9NU0dfVFJBUDI7CgogICAgLyoKICAgICAqIGNyZWF0ZSB0aGUgYXJndltdIGxpa2UgYXJyYXkgCiAgICAgKi8KICAgIGFyZ3ZbMF0gPSBzdHJkdXAoInNubXBkLXRyYXBzZXNzIik7IC8qIGJvZ3VzIGVudHJ5IGZvciBnZXRvcHQoKSAqLwogICAgZm9yIChhcmduID0gMTsgY3AgJiYgYXJnbiA8IE1BWF9BUkdTOyBhcmduKyspIHsKICAgICAgICBjaGFyICAgICAgICAgICAgdG1wW1NQUklOVF9NQVhfTEVOXTsKCiAgICAgICAgY3AgPSBjb3B5X253b3JkKGNwLCB0bXAsIFNQUklOVF9NQVhfTEVOKTsKICAgICAgICBhcmd2W2FyZ25dID0gc3RyZHVwKHRtcCk7CiAgICB9CgogICAgbmV0c25tcF9wYXJzZV9hcmdzKGFyZ24sIGFyZ3YsICZzZXNzaW9uLCAiQzoiLCB0cmFwT3B0UHJvYywKICAgICAgICAgICAgICAgICAgICAgICBORVRTTk1QX1BBUlNFX0FSR1NfTk9MT0dHSU5HIHwKICAgICAgICAgICAgICAgICAgICAgICBORVRTTk1QX1BBUlNFX0FSR1NfTk9aRVJPKTsKCiAgICB0cmFuc3BvcnQgPSBuZXRzbm1wX3RyYW5zcG9ydF9vcGVuX2NsaWVudCgic25tcHRyYXAiLCBzZXNzaW9uLnBlZXJuYW1lKTsKICAgIGlmICh0cmFuc3BvcnQgPT0gTlVMTCkgewogICAgICAgIGNvbmZpZ19wZXJyb3IoInNubXBkOiBmYWlsZWQgdG8gcGFyc2UgdGhpcyBsaW5lLiIpOwogICAgICAgIHJldHVybjsKICAgIH0KICAgIGlmICgocmMgPSBuZXRzbm1wX3Nlc3NfY29uZmlnX2FuZF9vcGVuX3RyYW5zcG9ydCgmc2Vzc2lvbiwgdHJhbnNwb3J0KSkKICAgICAgICAhPSBTTk1QRVJSX1NVQ0NFU1MpIHsKICAgICAgICBzZXNzaW9uLnNfc25tcF9lcnJubyA9IHJjOwogICAgICAgIHNlc3Npb24uc19lcnJubyA9IDA7CiAgICAgICAgcmV0dXJuOwogICAgfQogICAgc3MgPSBzbm1wX2FkZCgmc2Vzc2lvbiwgdHJhbnNwb3J0LCBOVUxMLCBOVUxMKTsKICAgIGZvciAoOyBhcmduID4gMDsgYXJnbi0tKSB7CiAgICAgICAgZnJlZShhcmd2W2FyZ24gLSAxXSk7CiAgICB9CgogICAgaWYgKCFzcykgewogICAgICAgIGNvbmZpZ19wZXJyb3IKICAgICAgICAgICAgKCJzbm1wZDogZmFpbGVkIHRvIHBhcnNlIHRoaXMgbGluZSBvciB0aGUgcmVtb3RlIHRyYXAgcmVjZWl2ZXIgaXMgZG93bi4gIFBvc3NpYmxlIGNhdXNlOiIpOwogICAgICAgIHNubXBfc2Vzc19wZXJyb3IoInNubXBkOiBzbm1wZF9wYXJzZV9jb25maWdfdHJhcHNlc3MoKSIsICZzZXNzaW9uKTsKICAgICAgICByZXR1cm47CiAgICB9CgogICAgLyoKICAgICAqIElmIHRoaXMgaXMgYW4gU05NUHYzIFRSQVAgc2Vzc2lvbiwgdGhlbiB0aGUgYWdlbnQgaXMKICAgICAqICAgdGhlIGF1dGhvcml0YXRpdmUgZW5naW5lLCBzbyBzZXQgdGhlIGVuZ2luZUlEIGFjY29yZGluZ2x5CiAgICAgKi8KICAgIGlmIChzcy0+dmVyc2lvbiA9PSBTTk1QX1ZFUlNJT05fMyAmJgogICAgICAgIHRyYXB0eXBlICE9IFNOTVBfTVNHX0lORk9STSAgICYmCiAgICAgICAgc3MtPnNlY3VyaXR5RW5naW5lSURMZW4gPT0gMCkgewogICAgICAgICAgICB1X2NoYXIgICAgICAgICAgdG1wW1NQUklOVF9NQVhfTEVOXTsKCiAgICAgICAgICAgIGxlbiA9IHNubXB2M19nZXRfZW5naW5lSUQoIHRtcCwgc2l6ZW9mKHRtcCkpOwogICAgICAgICAgICBzcy0+c2VjdXJpdHlFbmdpbmVJRCA9IG5ldHNubXBfbWVtZHVwKHRtcCwgbGVuKTsKICAgICAgICAgICAgc3MtPnNlY3VyaXR5RW5naW5lSURMZW4gPSBsZW47CiAgICB9CgojaWZuZGVmIE5FVFNOTVBfRElTQUJMRV9TTk1QVjEKICAgIGlmIChzcy0+dmVyc2lvbiA9PSBTTk1QX1ZFUlNJT05fMSkKICAgICAgICB0cmFwdHlwZSA9IFNOTVBfTVNHX1RSQVA7CiNlbmRpZgogICAgYWRkX3RyYXBfc2Vzc2lvbihzcywgdHJhcHR5cGUsICh0cmFwdHlwZSA9PSBTTk1QX01TR19JTkZPUk0pLCBzcy0+dmVyc2lvbik7Cn0KCiNpZiAhZGVmaW5lZChORVRTTk1QX0RJU0FCTEVfU05NUFYxKSB8fCAhZGVmaW5lZChORVRTTk1QX0RJU0FCTEVfU05NUFYyQykKdm9pZApzbm1wZF9wYXJzZV9jb25maWdfdHJhcGNvbW11bml0eShjb25zdCBjaGFyICp3b3JkLCBjaGFyICpjcHRyKQp7CiAgICBpZiAoc25tcF90cmFwY29tbXVuaXR5ICE9IE5VTEwpIHsKICAgICAgICBmcmVlKHNubXBfdHJhcGNvbW11bml0eSk7CiAgICB9CiAgICBzbm1wX3RyYXBjb21tdW5pdHkgPSAoY2hhciAqKSBtYWxsb2Moc3RybGVuKGNwdHIpICsgMSk7CiAgICBpZiAoc25tcF90cmFwY29tbXVuaXR5ICE9IE5VTEwpIHsKICAgICAgICBjb3B5X253b3JkKGNwdHIsIHNubXBfdHJhcGNvbW11bml0eSwgc3RybGVuKGNwdHIpICsgMSk7CiAgICB9Cn0KCnZvaWQKc25tcGRfZnJlZV90cmFwY29tbXVuaXR5KHZvaWQpCnsKICAgIGlmIChzbm1wX3RyYXBjb21tdW5pdHkpIHsKICAgICAgICBmcmVlKHNubXBfdHJhcGNvbW11bml0eSk7CiAgICAgICAgc25tcF90cmFwY29tbXVuaXR5ID0gTlVMTDsKICAgIH0KfQojZW5kaWYKLyoqIEB9ICovCg==