LyoKICogY2FsbGJhY2suYzogQSBnZW5lcmljIGNhbGxiYWNrIG1lY2hhbmlzbSAKICovCi8qIFBvcnRpb25zIG9mIHRoaXMgZmlsZSBhcmUgc3ViamVjdCB0byB0aGUgZm9sbG93aW5nIGNvcHlyaWdodChzKS4gIFNlZQogKiB0aGUgTmV0LVNOTVAncyBDT1BZSU5HIGZpbGUgZm9yIG1vcmUgZGV0YWlscyBhbmQgb3RoZXIgY29weXJpZ2h0cwogKiB0aGF0IG1heSBhcHBseToKICovCi8qCiAqIFBvcnRpb25zIG9mIHRoaXMgZmlsZSBhcmUgY29weXJpZ2h0ZWQgYnk6CiAqIENvcHlyaWdodCCpIDIwMDMgU3VuIE1pY3Jvc3lzdGVtcywgSW5jLiBBbGwgcmlnaHRzIHJlc2VydmVkLgogKiBVc2UgaXMgc3ViamVjdCB0byBsaWNlbnNlIHRlcm1zIHNwZWNpZmllZCBpbiB0aGUgQ09QWUlORyBmaWxlCiAqIGRpc3RyaWJ1dGVkIHdpdGggdGhlIE5ldC1TTk1QIHBhY2thZ2UuCiAqLwovKiogQGRlZmdyb3VwIGNhbGxiYWNrIEEgZ2VuZXJpYyBjYWxsYmFjayBtZWNoYW5pc20gCiAqICBAaW5ncm91cCBsaWJyYXJ5CiAqIAogKiAgQHsKICovCiNpbmNsdWRlIDxuZXQtc25tcC9uZXQtc25tcC1jb25maWcuaD4KI2luY2x1ZGUgPHN5cy90eXBlcy5oPgojaW5jbHVkZSA8c3RkaW8uaD4KI2lmIEhBVkVfU1RETElCX0gKI2luY2x1ZGUgPHN0ZGxpYi5oPgojZW5kaWYKI2lmIEhBVkVfTkVUSU5FVF9JTl9ICiNpbmNsdWRlIDxuZXRpbmV0L2luLmg+CiNlbmRpZgojaWYgSEFWRV9TVFJJTkdfSAojaW5jbHVkZSA8c3RyaW5nLmg+CiNlbHNlCiNpbmNsdWRlIDxzdHJpbmdzLmg+CiNlbmRpZgoKI2lmIEhBVkVfVU5JU1REX0gKI2luY2x1ZGUgPHVuaXN0ZC5oPgojZW5kaWYKI2lmIEhBVkVfRE1BTExPQ19ICiNpbmNsdWRlIDxkbWFsbG9jLmg+CiNlbmRpZgoKI2lmIEhBVkVfU1lTX1NPQ0tFVF9ICiNpbmNsdWRlIDxzeXMvc29ja2V0Lmg+CiNlbmRpZgojaWYgIWRlZmluZWQobWluZ3czMikgJiYgZGVmaW5lZChIQVZFX1NZU19USU1FX0gpCiNpbmNsdWRlIDxzeXMvdGltZS5oPgojZW5kaWYKCiNpbmNsdWRlIDxuZXQtc25tcC90eXBlcy5oPgojaW5jbHVkZSA8bmV0LXNubXAvb3V0cHV0X2FwaS5oPgojaW5jbHVkZSA8bmV0LXNubXAvdXRpbGl0aWVzLmg+CgojaW5jbHVkZSA8bmV0LXNubXAvbGlicmFyeS9jYWxsYmFjay5oPgojaW5jbHVkZSA8bmV0LXNubXAvbGlicmFyeS9zbm1wX2FwaS5oPgoKLyoKICogdGhlIGlubGluZSBjYWxsYmFjayBtZXRob2RzIHVzZSBtYWpvci9taW5vciB0byBpbmRleCBpbnRvIGFycmF5cy4KICogYWxsIHVzZXJzIGluIHRoaXMgZnVuY3Rpb24gZG8gcmFuZ2UgY2hlY2tpbmcgYmVmb3JlIGNhbGxpbmcgdGhlc2UKICogZnVuY3Rpb25zLCBzbyBpdCBpcyByZWR1bmRhbnQgZm9yIHRoZW0gdG8gY2hlY2sgYWdhaW4uIEJ1dCBpZiB5b3UKICogd2FudCB0byBiZSBwYXJhbm9pZCwgZGVmaW5lIHRoaXMgdmFyLCBhbmQgYWRkaXRpb25hbCByYW5nZSBjaGVja3MKICogd2lsbCBiZSBwZXJmb3JtZWQuCiAqICNkZWZpbmUgTkVUU05NUF9QQVJBTk9JRF9MRVZFTF9ISUdIIDEgCiAqLwoKc3RhdGljIGludCBfY2FsbGJhY2tfbmVlZF9pbml0ID0gMTsKc3RhdGljIHN0cnVjdCBzbm1wX2dlbl9jYWxsYmFjawogICAgICAgICAgICAgICAqdGhlY2FsbGJhY2tzW01BWF9DQUxMQkFDS19JRFNdW01BWF9DQUxMQkFDS19TVUJJRFNdOwoKI2RlZmluZSBDQUxMQkFDS19OQU1FX0xPR0dJTkcgMQojaWZkZWYgQ0FMTEJBQ0tfTkFNRV9MT0dHSU5HCnN0YXRpYyBjb25zdCBjaGFyICp0eXBlc1tNQVhfQ0FMTEJBQ0tfSURTXSA9IHsgIkxJQiIsICJBUFAiIH07CnN0YXRpYyBjb25zdCBjaGFyICpsaWJbTUFYX0NBTExCQUNLX1NVQklEU10gPSB7CiAgICAiUE9TVF9SRUFEX0NPTkZJRyIsIC8qIDAgKi8KICAgICJTVE9SRV9EQVRBIiwgLyogMSAqLwogICAgIlNIVVRET1dOIiwgLyogMiAqLwogICAgIlBPU1RfUFJFTUlCX1JFQURfQ09ORklHIiwgLyogMyAqLwogICAgIkxPR0dJTkciLCAvKiA0ICovCiAgICAiU0VTU0lPTl9JTklUIiwgLyogNSAqLwogICAgTlVMTCwgLyogNiAqLwogICAgTlVMTCwgLyogNyAqLwogICAgTlVMTCwgLyogOCAqLwogICAgTlVMTCwgLyogOSAqLwogICAgTlVMTCwgLyogMTAgKi8KICAgIE5VTEwsIC8qIDExICovCiAgICBOVUxMLCAvKiAxMiAqLwogICAgTlVMTCwgLyogMTMgKi8KICAgIE5VTEwsIC8qIDE0ICovCiAgICBOVUxMIC8qIDE1ICovCn07CiNlbmRpZgoKLyoKICogZXh0cmVtZWx5IHNpbXBsaXN0aWMgbG9ja2luZywganVzdCB0byBmaW5kIHByb2JsZW1zIHdlcmUgdGhlCiAqIGNhbGxiYWNrIGxpc3QgaXMgbW9kaWZpZWQgd2hpbGUgYmVpbmcgdHJhdmVyc2VkLiBOb3QgaW50ZW5kZWQKICogdG8gZG8gYW55IHJlYWwgcHJvdGVjdGlvbiwgb3IgaW4gYW55IHdheSBpbXBseSB0aGF0IHRoaXMgY29kZQogKiBoYXMgYmVlbiBldmFsdWF0ZWQgZm9yIHVzZSBpbiBhIG11bHRpLXRocmVhZGVkIGVudmlyb25tZW50LgogKiBJbiA1LjIsIGl0IHdhcyBhIHNpbmdsZSBsb2NrLiBGb3IgNS4zLCBpdCBoYXMgYmVlbiB1cGRhdGVkIHRvCiAqIGEgbG9jayBwZXIgY2FsbGJhY2ssIHNpbmNlIGEgcGFydGljdWxhciBjYWxsYmFjayBtYXkgdHJpZ2dlcgogKiByZWdpc3RyYXRpb24vdW5yZWdpc3RyYXRpb24gb2Ygb3RoZXIgY2FsbGJhY2tzIChlZyBBZ2VudFgKICogc3ViYWdlbnRzIGRvIHRoaXMpLgogKi8KI2RlZmluZSBMT0NLX1BFUl9DQUxMQkFDS19TVUJJRCAxCiNpZmRlZiBMT0NLX1BFUl9DQUxMQkFDS19TVUJJRApzdGF0aWMgaW50IF9sb2Nrc1tNQVhfQ0FMTEJBQ0tfSURTXVtNQVhfQ0FMTEJBQ0tfU1VCSURTXTsKI2RlZmluZSBDQUxMQkFDS19MT0NLKG1haixtaW4pICsrX2xvY2tzW21hal1bbWluXQojZGVmaW5lIENBTExCQUNLX1VOTE9DSyhtYWosbWluKSAtLV9sb2Nrc1ttYWpdW21pbl0KI2RlZmluZSBDQUxMQkFDS19MT0NLX0NPVU5UKG1haixtaW4pIF9sb2Nrc1ttYWpdW21pbl0KI2Vsc2UKc3RhdGljIGludCBfbG9jazsKI2RlZmluZSBDQUxMQkFDS19MT0NLKG1haixtaW4pICsrX2xvY2sKI2RlZmluZSBDQUxMQkFDS19VTkxPQ0sobWFqLG1pbikgLS1fbG9jawojZGVmaW5lIENBTExCQUNLX0xPQ0tfQ09VTlQobWFqLG1pbikgX2xvY2sKI2VuZGlmCgpORVRTTk1QX1NUQVRJQ19JTkxJTkUgaW50Cl9jYWxsYmFja19sb2NrKGludCBtYWpvciwgaW50IG1pbm9yLCBjb25zdCBjaGFyKiB3YXJuLCBpbnQgZG9fYXNzZXJ0KQp7CiAgICBpbnQgbG9ja19ob2xkZWQ9MDsKICAgIHN0cnVjdCB0aW1ldmFsIGxvY2tfdGltZSA9IHsgMCwgMTAwMCB9OwoKI2lmZGVmIE5FVFNOTVBfUEFSQU5PSURfTEVWRUxfSElHSAogICAgaWYgKG1ham9yID49IE1BWF9DQUxMQkFDS19JRFMgfHwgbWlub3IgPj0gTUFYX0NBTExCQUNLX1NVQklEUykgewogICAgICAgIG5ldHNubXBfYXNzZXJ0KCJiYWQgY2FsbGJhY2sgaWQiKTsKICAgICAgICByZXR1cm4gMTsKICAgIH0KI2VuZGlmCiAgICAKI2lmZGVmIENBTExCQUNLX05BTUVfTE9HR0lORwogICAgREVCVUdNU0dUTCgoIjk6Y2FsbGJhY2s6bG9jayIsICJsb2NrZWQgKCVzLCVzKVxuIiwKICAgICAgICAgICAgICAgIHR5cGVzW21ham9yXSwgKFNOTVBfQ0FMTEJBQ0tfTElCUkFSWSA9PSBtYWpvcikgPwogICAgICAgICAgICAgICAgU05NUF9TVFJPUk5VTEwobGliW21pbm9yXSkgOiAibnVsbCIpKTsKI2VuZGlmCiAgICB3aGlsZSAoQ0FMTEJBQ0tfTE9DS19DT1VOVChtYWpvcixtaW5vcikgPj0gMSAmJiArK2xvY2tfaG9sZGVkIDwgMTAwKQoJc2VsZWN0KDAsIE5VTEwsIE5VTEwsIE5VTEwsICZsb2NrX3RpbWUpOwoKICAgIGlmKGxvY2tfaG9sZGVkID49IDEwMCkgewogICAgICAgIGlmIChOVUxMICE9IHdhcm4pCiAgICAgICAgICAgIHNubXBfbG9nKExPR19XQVJOSU5HLAogICAgICAgICAgICAgICAgICAgICAibG9jayBpbiBfY2FsbGJhY2tfbG9jayBzbGVlcHMgbW9yZSB0aGFuIDEwMCBtaWxsaXNlY29uZHMgaW4gJXNcbiIsIHdhcm4pOwogICAgICAgIGlmIChkb19hc3NlcnQpCiAgICAgICAgICAgIG5ldHNubXBfYXNzZXJ0KGxvY2tfaG9sZGVkIDwgMTAwKTsKICAgICAgICAKICAgICAgICByZXR1cm4gMTsKICAgIH0KCiAgICBDQUxMQkFDS19MT0NLKG1ham9yLG1pbm9yKTsKICAgIHJldHVybiAwOwp9CgpORVRTTk1QX1NUQVRJQ19JTkxJTkUgdm9pZApfY2FsbGJhY2tfdW5sb2NrKGludCBtYWpvciwgaW50IG1pbm9yKQp7CiNpZmRlZiBORVRTTk1QX1BBUkFOT0lEX0xFVkVMX0hJR0gKICAgIGlmIChtYWpvciA+PSBNQVhfQ0FMTEJBQ0tfSURTIHx8IG1pbm9yID49IE1BWF9DQUxMQkFDS19TVUJJRFMpIHsKICAgICAgICBuZXRzbm1wX2Fzc2VydCgiYmFkIGNhbGxiYWNrIGlkIik7CiAgICAgICAgcmV0dXJuOwogICAgfQojZW5kaWYKICAgIAogICAgQ0FMTEJBQ0tfVU5MT0NLKG1ham9yLG1pbm9yKTsKCiNpZmRlZiBDQUxMQkFDS19OQU1FX0xPR0dJTkcKICAgIERFQlVHTVNHVEwoKCI5OmNhbGxiYWNrOmxvY2siLCAidW5sb2NrZWQgKCVzLCVzKVxuIiwKICAgICAgICAgICAgICAgIHR5cGVzW21ham9yXSwgKFNOTVBfQ0FMTEJBQ0tfTElCUkFSWSA9PSBtYWpvcikgPwogICAgICAgICAgICAgICAgU05NUF9TVFJPUk5VTEwobGliW21pbm9yXSkgOiAibnVsbCIpKTsKI2VuZGlmCn0KCgovKgogKiB0aGUgY2hpY2tlbi4gb3IgdGhlIGVnZy4gIFlvdSBwaWNrLiAKICovCnZvaWQKaW5pdF9jYWxsYmFja3Modm9pZCkKewogICAgLyoKICAgICAqIChwb3NlcyBhIHByb2JsZW0gaWYgeW91IHB1dCBpbml0X2NhbGxiYWNrcygpIGluc2lkZSBvZgogICAgICogaW5pdF9zbm1wKCkgYW5kIHRoZW4gd2FudCB0aGUgYXBwIHRvIHJlZ2lzdGVyIGEgY2FsbGJhY2sgYmVmb3JlCiAgICAgKiBpbml0X3NubXAoKSBpcyBjYWxsZWQgaW4gdGhlIGZpcnN0IHBsYWNlLiAgLS0gV2VzIAogICAgICovCiAgICBpZiAoMCA9PSBfY2FsbGJhY2tfbmVlZF9pbml0KQogICAgICAgIHJldHVybjsKICAgIAogICAgX2NhbGxiYWNrX25lZWRfaW5pdCA9IDA7CiAgICAKICAgIG1lbXNldCh0aGVjYWxsYmFja3MsIDAsIHNpemVvZih0aGVjYWxsYmFja3MpKTsgCiNpZmRlZiBMT0NLX1BFUl9DQUxMQkFDS19TVUJJRAogICAgbWVtc2V0KF9sb2NrcywgMCwgc2l6ZW9mKF9sb2NrcykpOwojZWxzZQogICAgX2xvY2sgPSAwOwojZW5kaWYKICAgIAogICAgREVCVUdNU0dUTCgoImNhbGxiYWNrIiwgImluaXRpYWxpemVkXG4iKSk7Cn0KCi8qKgogKiBUaGlzIGZ1bmN0aW9uIHJlZ2lzdGVycyBhIGdlbmVyaWMgY2FsbGJhY2sgZnVuY3Rpb24uICBUaGUgbWFqb3IgYW5kCiAqIG1pbm9yIHZhbHVlcyBhcmUgdXNlZCB0byBzZXQgdGhlIG5ld19jYWxsYmFjayBmdW5jdGlvbiBpbnRvIGEgZ2xvYmFsIAogKiBzdGF0aWMgbXVsdGktZGltZW5zaW9uYWwgYXJyYXkgb2YgdHlwZSBzdHJ1Y3Qgc25tcF9nZW5fY2FsbGJhY2suICAKICogVGhlIGZ1bmN0aW9uIG1ha2VzIHN1cmUgdG8gYXBwZW5kIHRoaXMgY2FsbGJhY2sgZnVuY3Rpb24gYXQgdGhlIGVuZAogKiBvZiB0aGUgbGluayBsaXN0LCBzbm1wX2dlbl9jYWxsYmFjay0+bmV4dC4KICoKICogQHBhcmFtIG1ham9yIGlzIHRoZSBTTk1QIGNhbGxiYWNrIG1ham9yIHR5cGUgdXNlZAogKiAJCS0gU05NUF9DQUxMQkFDS19MSUJSQVJZCiAqICAgICAgICAgICAgICAtIFNOTVBfQ0FMTEJBQ0tfQVBQTElDQVRJT04KICoKICogQHBhcmFtIG1pbm9yIGlzIHRoZSBTTk1QIGNhbGxiYWNrIG1pbm9yIHR5cGUgdXNlZAogKgkJLSBTTk1QX0NBTExCQUNLX1BPU1RfUkVBRF9DT05GSUcKICoJCS0gU05NUF9DQUxMQkFDS19TVE9SRV9EQVRBCSAgICAgICAgCiAqCQktIFNOTVBfQ0FMTEJBQ0tfU0hVVERPV04JCSAgICAgICAgCiAqCQktIFNOTVBfQ0FMTEJBQ0tfUE9TVF9QUkVNSUJfUkVBRF9DT05GSUcJCiAqCQktIFNOTVBfQ0FMTEJBQ0tfTE9HR0lORwkJCQogKgkJLSBTTk1QX0NBTExCQUNLX1NFU1NJT05fSU5JVAkgICAgICAgCiAqCiAqIEBwYXJhbSBuZXdfY2FsbGJhY2sgaXMgdGhlIGNhbGxiYWNrIGZ1bmN0aW9uIHRoYXQgaXMgcmVnaXN0ZXJlZC4KICoKICogQHBhcmFtIGFyZyB3aGVuIG5vdCBOVUxMIGlzIGEgdm9pZCBwb2ludGVyIHVzZWQgd2hlbmV2ZXIgbmV3X2NhbGxiYWNrIAogKglmdW5jdGlvbiBpcyBleGVyY2lzZWQuCiAqCiAqIEByZXR1cm4gCiAqCVJldHVybnMgU05NUEVSUl9HRU5FUlIgaWYgbWFqb3IgaXMgPj0gTUFYX0NBTExCQUNLX0lEUyBvciBtaW5vciBpcyA+PQogKglNQVhfQ0FMTEJBQ0tfU1VCSURTIG9yIGEgc25tcF9nZW5fY2FsbGJhY2sgcG9pbnRlciBjb3VsZCBub3QgYmUgCiAqCWFsbG9jYXRlZCwgb3RoZXJ3aXNlIFNOTVBFUlJfU1VDQ0VTUyBpcyByZXR1cm5lZC4KICogCS0gXCNkZWZpbmUgTUFYX0NBTExCQUNLX0lEUyAgICAyCiAqCS0gXCNkZWZpbmUgTUFYX0NBTExCQUNLX1NVQklEUyAxNgogKgogKiBAc2VlIHNubXBfY2FsbF9jYWxsYmFja3MKICogQHNlZSBzbm1wX3VucmVnaXN0ZXJfY2FsbGJhY2sKICovCmludApzbm1wX3JlZ2lzdGVyX2NhbGxiYWNrKGludCBtYWpvciwgaW50IG1pbm9yLCBTTk1QQ2FsbGJhY2sgKiBuZXdfY2FsbGJhY2ssCiAgICAgICAgICAgICAgICAgICAgICAgdm9pZCAqYXJnKQp7CiAgICByZXR1cm4gbmV0c25tcF9yZWdpc3Rlcl9jYWxsYmFjayggbWFqb3IsIG1pbm9yLCBuZXdfY2FsbGJhY2ssIGFyZywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBORVRTTk1QX0NBTExCQUNLX0RFRkFVTFRfUFJJT1JJVFkpOwp9CgppbnQKbmV0c25tcF9yZWdpc3Rlcl9jYWxsYmFjayhpbnQgbWFqb3IsIGludCBtaW5vciwgU05NUENhbGxiYWNrICogbmV3X2NhbGxiYWNrLAogICAgICAgICAgICAgICAgICAgICAgICAgIHZvaWQgKmFyZywgaW50IHByaW9yaXR5KQp7CiAgICBzdHJ1Y3Qgc25tcF9nZW5fY2FsbGJhY2sgKm5ld3NjcCA9IE5VTEwsICpzY3AgPSBOVUxMOwogICAgc3RydWN0IHNubXBfZ2VuX2NhbGxiYWNrICoqcHJldk5leHQgPSAmKHRoZWNhbGxiYWNrc1ttYWpvcl1bbWlub3JdKTsKCiAgICBpZiAobWFqb3IgPj0gTUFYX0NBTExCQUNLX0lEUyB8fCBtaW5vciA+PSBNQVhfQ0FMTEJBQ0tfU1VCSURTKSB7CiAgICAgICAgcmV0dXJuIFNOTVBFUlJfR0VORVJSOwogICAgfQoKICAgIGlmIChfY2FsbGJhY2tfbmVlZF9pbml0KQogICAgICAgIGluaXRfY2FsbGJhY2tzKCk7CgogICAgX2NhbGxiYWNrX2xvY2sobWFqb3IsbWlub3IsICJuZXRzbm1wX3JlZ2lzdGVyX2NhbGxiYWNrIiwgMSk7CiAgICAKICAgIGlmICgobmV3c2NwID0gU05NUF9NQUxMT0NfU1RSVUNUKHNubXBfZ2VuX2NhbGxiYWNrKSkgPT0gTlVMTCkgewogICAgICAgIF9jYWxsYmFja191bmxvY2sobWFqb3IsbWlub3IpOwogICAgICAgIHJldHVybiBTTk1QRVJSX0dFTkVSUjsKICAgIH0gZWxzZSB7CiAgICAgICAgbmV3c2NwLT5wcmlvcml0eSA9IHByaW9yaXR5OwogICAgICAgIG5ld3NjcC0+c2NfY2xpZW50X2FyZyA9IGFyZzsKICAgICAgICBuZXdzY3AtPnNjX2NhbGxiYWNrID0gbmV3X2NhbGxiYWNrOwogICAgICAgIG5ld3NjcC0+bmV4dCA9IE5VTEw7CgogICAgICAgIGZvciAoc2NwID0gdGhlY2FsbGJhY2tzW21ham9yXVttaW5vcl07IHNjcCAhPSBOVUxMOwogICAgICAgICAgICAgc2NwID0gc2NwLT5uZXh0KSB7CiAgICAgICAgICAgIGlmIChuZXdzY3AtPnByaW9yaXR5IDwgc2NwLT5wcmlvcml0eSkgewogICAgICAgICAgICAgICAgbmV3c2NwLT5uZXh0ID0gc2NwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcHJldk5leHQgPSAmKHNjcC0+bmV4dCk7CiAgICAgICAgfQoKICAgICAgICAqcHJldk5leHQgPSBuZXdzY3A7CgogICAgICAgIERFQlVHTVNHVEwoKCJjYWxsYmFjayIsICJyZWdpc3RlcmVkICglZCwlZCkgYXQgJXAgd2l0aCBwcmlvcml0eSAlZFxuIiwKICAgICAgICAgICAgICAgICAgICBtYWpvciwgbWlub3IsIG5ld3NjcCwgcHJpb3JpdHkpKTsKICAgICAgICBfY2FsbGJhY2tfdW5sb2NrKG1ham9yLG1pbm9yKTsKICAgICAgICByZXR1cm4gU05NUEVSUl9TVUNDRVNTOwogICAgfQp9CgovKioKICogVGhpcyBmdW5jdGlvbiBjYWxscyB0aGUgY2FsbGJhY2sgZnVuY3Rpb24gZm9yIGVhY2ggcmVnaXN0ZXJlZCBjYWxsYmFjayBvZgogKiB0eXBlIG1ham9yIGFuZCBtaW5vci4KICoKICogQHBhcmFtIG1ham9yIGlzIHRoZSBTTk1QIGNhbGxiYWNrIG1ham9yIHR5cGUgdXNlZAogKgogKiBAcGFyYW0gbWlub3IgaXMgdGhlIFNOTVAgY2FsbGJhY2sgbWlub3IgdHlwZSB1c2VkCiAqCiAqIEBwYXJhbSBjYWxsZXJfYXJnIGlzIGEgdm9pZCBwb2ludGVyIHdoaWNoIGlzIHNlbnQgaW4gYXMgdGhlIGNhbGxiYWNrJ3MgCiAqCXNlcnZlcmFyZyBwYXJhbWV0ZXIsIGlmIG5lZWRlZC4KICoKICogQHJldHVybiBSZXR1cm5zIFNOTVBFUlJfR0VORVJSIGlmIG1ham9yIGlzID49IE1BWF9DQUxMQkFDS19JRFMgb3IKICogbWlub3IgaXMgPj0gTUFYX0NBTExCQUNLX1NVQklEUywgb3RoZXJ3aXNlIFNOTVBFUlJfU1VDQ0VTUyBpcyByZXR1cm5lZC4KICoKICogQHNlZSBzbm1wX3JlZ2lzdGVyX2NhbGxiYWNrCiAqIEBzZWUgc25tcF91bnJlZ2lzdGVyX2NhbGxiYWNrCiAqLwppbnQKc25tcF9jYWxsX2NhbGxiYWNrcyhpbnQgbWFqb3IsIGludCBtaW5vciwgdm9pZCAqY2FsbGVyX2FyZykKewogICAgc3RydWN0IHNubXBfZ2VuX2NhbGxiYWNrICpzY3A7CiAgICB1bnNpZ25lZCBpbnQgICAgY291bnQgPSAwOwogICAgCiAgICBpZiAobWFqb3IgPj0gTUFYX0NBTExCQUNLX0lEUyB8fCBtaW5vciA+PSBNQVhfQ0FMTEJBQ0tfU1VCSURTKSB7CiAgICAgICAgcmV0dXJuIFNOTVBFUlJfR0VORVJSOwogICAgfQogICAgCiAgICBpZiAoX2NhbGxiYWNrX25lZWRfaW5pdCkKICAgICAgICBpbml0X2NhbGxiYWNrcygpOwoKI2lmZGVmIExPQ0tfUEVSX0NBTExCQUNLX1NVQklECiAgICBfY2FsbGJhY2tfbG9jayhtYWpvcixtaW5vciwic25tcF9jYWxsX2NhbGxiYWNrcyIsIDEpOwojZWxzZQogICAgLyoKICAgICAqIE5vdGVzOgogICAgICogLSB0aGlzIGdldHMgaGl0IHRoZSBmaXJzdCB0aW1lIGEgdHJhcCBpcyBzZW50IGFmdGVyIGEgbmV3IHRyYXAKICAgICAqICAgZGVzdGluYXRpb24gaGFzIGJlZW4gYWRkZWQgKHNlc3Npb24gaW5pdCBjYiBkdXJpbmcgc2VuZCB0cmFwIGNiKQogICAgICovCiAgICBfY2FsbGJhY2tfbG9jayhtYWpvcixtaW5vciwgTlVMTCwgMCk7CiNlbmRpZgoKICAgIERFQlVHTVNHVEwoKCJjYWxsYmFjayIsICJTVEFSVCBjYWxsaW5nIGNhbGxiYWNrcyBmb3IgbWFqPSVkIG1pbj0lZFxuIiwKICAgICAgICAgICAgICAgIG1ham9yLCBtaW5vcikpOwoKICAgIC8qCiAgICAgKiBmb3IgZWFjaCByZWdpc3RlcmVkIGNhbGxiYWNrIG9mIHR5cGUgbWFqb3IgYW5kIG1pbm9yIAogICAgICovCiAgICBmb3IgKHNjcCA9IHRoZWNhbGxiYWNrc1ttYWpvcl1bbWlub3JdOyBzY3AgIT0gTlVMTDsgc2NwID0gc2NwLT5uZXh0KSB7CgogICAgICAgIC8qCiAgICAgICAgICogc2tpcCB1bnJlZ2lzdGVyZWQgY2FsbGJhY2tzCiAgICAgICAgICovCiAgICAgICAgaWYoTlVMTCA9PSBzY3AtPnNjX2NhbGxiYWNrKQogICAgICAgICAgICBjb250aW51ZTsKCiAgICAgICAgREVCVUdNU0dUTCgoImNhbGxiYWNrIiwgImNhbGxpbmcgYSBjYWxsYmFjayBmb3IgbWFqPSVkIG1pbj0lZFxuIiwKICAgICAgICAgICAgICAgICAgICBtYWpvciwgbWlub3IpKTsKCiAgICAgICAgLyoKICAgICAgICAgKiBjYWxsIHRoZW0gCiAgICAgICAgICovCiAgICAgICAgKCooc2NwLT5zY19jYWxsYmFjaykpIChtYWpvciwgbWlub3IsIGNhbGxlcl9hcmcsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzY3AtPnNjX2NsaWVudF9hcmcpOwogICAgICAgIGNvdW50Kys7CiAgICB9CgogICAgREVCVUdNU0dUTCgoImNhbGxiYWNrIiwKICAgICAgICAgICAgICAgICJFTkQgY2FsbGluZyBjYWxsYmFja3MgZm9yIG1haj0lZCBtaW49JWQgKCVkIGNhbGxlZClcbiIsCiAgICAgICAgICAgICAgICBtYWpvciwgbWlub3IsIGNvdW50KSk7CgogICAgX2NhbGxiYWNrX3VubG9jayhtYWpvcixtaW5vcik7CiAgICByZXR1cm4gU05NUEVSUl9TVUNDRVNTOwp9CgppbnQKc25tcF9jb3VudF9jYWxsYmFja3MoaW50IG1ham9yLCBpbnQgbWlub3IpCnsKICAgIGludCAgICAgICAgICAgICBjb3VudCA9IDA7CiAgICBzdHJ1Y3Qgc25tcF9nZW5fY2FsbGJhY2sgKnNjcDsKCiAgICBpZiAobWFqb3IgPj0gTUFYX0NBTExCQUNLX0lEUyB8fCBtaW5vciA+PSBNQVhfQ0FMTEJBQ0tfU1VCSURTKSB7CiAgICAgICAgcmV0dXJuIFNOTVBFUlJfR0VORVJSOwogICAgfQogICAgCiAgICBpZiAoX2NhbGxiYWNrX25lZWRfaW5pdCkKICAgICAgICBpbml0X2NhbGxiYWNrcygpOwoKICAgIGZvciAoc2NwID0gdGhlY2FsbGJhY2tzW21ham9yXVttaW5vcl07IHNjcCAhPSBOVUxMOyBzY3AgPSBzY3AtPm5leHQpIHsKICAgICAgICBjb3VudCsrOwogICAgfQoKICAgIHJldHVybiBjb3VudDsKfQoKaW50CnNubXBfY2FsbGJhY2tfYXZhaWxhYmxlKGludCBtYWpvciwgaW50IG1pbm9yKQp7CiAgICBpZiAobWFqb3IgPj0gTUFYX0NBTExCQUNLX0lEUyB8fCBtaW5vciA+PSBNQVhfQ0FMTEJBQ0tfU1VCSURTKSB7CiAgICAgICAgcmV0dXJuIFNOTVBFUlJfR0VORVJSOwogICAgfQogICAgCiAgICBpZiAoX2NhbGxiYWNrX25lZWRfaW5pdCkKICAgICAgICBpbml0X2NhbGxiYWNrcygpOwoKICAgIGlmICh0aGVjYWxsYmFja3NbbWFqb3JdW21pbm9yXSAhPSBOVUxMKSB7CiAgICAgICAgcmV0dXJuIFNOTVBFUlJfU1VDQ0VTUzsKICAgIH0KCiAgICByZXR1cm4gU05NUEVSUl9HRU5FUlI7Cn0KCi8qKgogKiBUaGlzIGZ1bmN0aW9uIHVucmVnaXN0ZXJzIGEgc3BlY2lmaWVkIGNhbGxiYWNrIGZ1bmN0aW9uIGdpdmVuIGEgbWFqb3IKICogYW5kIG1pbm9yIHR5cGUuCiAqCiAqIE5vdGU6IG5vIGJvdW5kIGNoZWNraW5nIG9uIG1ham9yIGFuZCBtaW5vci4KICoKICogQHBhcmFtIG1ham9yIGlzIHRoZSBTTk1QIGNhbGxiYWNrIG1ham9yIHR5cGUgdXNlZAogKgogKiBAcGFyYW0gbWlub3IgaXMgdGhlIFNOTVAgY2FsbGJhY2sgbWlub3IgdHlwZSB1c2VkCiAqCiAqIEBwYXJhbSB0YXJnZXQgaXMgdGhlIGNhbGxiYWNrIGZ1bmN0aW9uIHRoYXQgd2lsbCBiZSB1bnJlZ2lzdGVyZWQuCiAqCiAqIEBwYXJhbSBhcmcgaXMgYSB2b2lkIHBvaW50ZXIgdXNlZCBmb3IgY29tcGFyaXNvbiBhZ2FpbnN0IHRoZSByZWdpc3RlcmVkIAogKgljYWxsYmFjaydzIHNjX2NsaWVudF9hcmcgdmFyaWFibGUuCiAqCiAqIEBwYXJhbSBtYXRjaGFyZ3MgaXMgYW4gaW50ZWdlciB1c2VkIHRvIGJ5cGFzcyB0aGUgY29tcGFyaXNvbiBvZiBhcmcgYW5kIHRoZQogKgljYWxsYmFjaydzIHNjX2NsaWVudF9hcmcgdmFyaWFibGUgb25seSB3aGVuIG1hdGNoYXJncyBpcyBzZXQgdG8gMC4KICoKICoKICogQHJldHVybgogKiAgICAgICAgUmV0dXJucyB0aGUgbnVtYmVyIG9mIGNhbGxiYWNrcyB0aGF0IHdlcmUgdW5yZWdpc3RlcmVkLgogKgogKiBAc2VlIHNubXBfcmVnaXN0ZXJfY2FsbGJhY2sKICogQHNlZSBzbm1wX2NhbGxfY2FsbGJhY2tzCiAqLwoKaW50CnNubXBfdW5yZWdpc3Rlcl9jYWxsYmFjayhpbnQgbWFqb3IsIGludCBtaW5vciwgU05NUENhbGxiYWNrICogdGFyZ2V0LAogICAgICAgICAgICAgICAgICAgICAgICAgdm9pZCAqYXJnLCBpbnQgbWF0Y2hhcmdzKQp7CiAgICBzdHJ1Y3Qgc25tcF9nZW5fY2FsbGJhY2sgKnNjcCA9IHRoZWNhbGxiYWNrc1ttYWpvcl1bbWlub3JdOwogICAgc3RydWN0IHNubXBfZ2VuX2NhbGxiYWNrICoqcHJldk5leHQgPSAmKHRoZWNhbGxiYWNrc1ttYWpvcl1bbWlub3JdKTsKICAgIGludCAgICAgICAgICAgICBjb3VudCA9IDA7CgogICAgaWYgKG1ham9yID49IE1BWF9DQUxMQkFDS19JRFMgfHwgbWlub3IgPj0gTUFYX0NBTExCQUNLX1NVQklEUykKICAgICAgICByZXR1cm4gU05NUEVSUl9HRU5FUlI7CgogICAgaWYgKF9jYWxsYmFja19uZWVkX2luaXQpCiAgICAgICAgaW5pdF9jYWxsYmFja3MoKTsKCiNpZmRlZiBMT0NLX1BFUl9DQUxMQkFDS19TVUJJRAogICAgX2NhbGxiYWNrX2xvY2sobWFqb3IsbWlub3IsInNubXBfdW5yZWdpc3Rlcl9jYWxsYmFjayIsIDEpOwojZWxzZQogICAgLyoKICAgICAqIE5vdGVzOwogICAgICogLSB0aGlzIGdldHMgaGl0IGF0IHNodXRkb3duLCBkdXJpbmcgY2xlYW51cC4gTm8gZWFzeSBmaXguCiAgICAgKi8KICAgIF9jYWxsYmFja19sb2NrKG1ham9yLG1pbm9yLCJzbm1wX3VucmVnaXN0ZXJfY2FsbGJhY2siLCAwKTsKI2VuZGlmCgogICAgd2hpbGUgKHNjcCAhPSBOVUxMKSB7CiAgICAgICAgaWYgKChzY3AtPnNjX2NhbGxiYWNrID09IHRhcmdldCkgJiYKICAgICAgICAgICAgKCFtYXRjaGFyZ3MgfHwgKHNjcC0+c2NfY2xpZW50X2FyZyA9PSBhcmcpKSkgewogICAgICAgICAgICBERUJVR01TR1RMKCgiY2FsbGJhY2siLCAidW5yZWdpc3RlcmluZyAoJWQsJWQpIGF0ICVwXG4iLCBtYWpvciwKICAgICAgICAgICAgICAgICAgICAgICAgbWlub3IsIHNjcCkpOwogICAgICAgICAgICBpZigxID09IENBTExCQUNLX0xPQ0tfQ09VTlQobWFqb3IsbWlub3IpKSB7CiAgICAgICAgICAgICAgICAqcHJldk5leHQgPSBzY3AtPm5leHQ7CiAgICAgICAgICAgICAgICBTTk1QX0ZSRUUoc2NwKTsKICAgICAgICAgICAgICAgIHNjcCA9ICpwcmV2TmV4dDsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlIHsKICAgICAgICAgICAgICAgIHNjcC0+c2NfY2FsbGJhY2sgPSBOVUxMOwogICAgICAgICAgICAgICAgLyoqIHNldCBjbGVhbnVwIGZsYWc/ICovCiAgICAgICAgICAgIH0KICAgICAgICAgICAgY291bnQrKzsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBwcmV2TmV4dCA9ICYoc2NwLT5uZXh0KTsKICAgICAgICAgICAgc2NwID0gc2NwLT5uZXh0OwogICAgICAgIH0KICAgIH0KCiAgICBfY2FsbGJhY2tfdW5sb2NrKG1ham9yLG1pbm9yKTsKICAgIHJldHVybiBjb3VudDsKfQoKLyoqCiAqIGZpbmQgYW5kIGNsZWFyIGNsaWVudCBhcmdzIHRoYXQgbWF0Y2ggcHRyCiAqCiAqIEBwYXJhbSBwdHIgIHBvaW50ZXIgdG8gc2VhcmNoIGZvcgogKiBAcGFyYW0gaSAgICBjYWxsYmFjayBpZCB0byBzdGFydCBhdAogKiBAcGFyYW0gaiAgICBjYWxsYmFjayBzdWJpZCB0byBzdGFydCBhdAogKi8KaW50Cm5ldHNubXBfY2FsbGJhY2tfY2xlYXJfY2xpZW50X2FyZyh2b2lkICpwdHIsIGludCBpLCBpbnQgaikKewogICAgc3RydWN0IHNubXBfZ2VuX2NhbGxiYWNrICpzY3AgPSBOVUxMOwogICAgaW50IHJjID0gMDsKCiAgICAvKgogICAgICogZG9uJ3QgaW5pdCBpIGFuZCBqIGJlZm9yZSBsb29wLCBzaW5jZSB0aGUgY2FsbGVyIHNwZWNpZmllZAogICAgICogdGhlIHN0YXJ0aW5nIHBvaW50IGV4cGxpY2l0bHkuIEJ1dCAqYWZ0ZXIqIHRoZSBpIGxvb3AgaGFzCiAgICAgKiBmaW5pc2hlZCBleGVjdXRpbmcgb25jZSwgaW5pdCBqIHRvIDAgZm9yIHRoZSBuZXh0IHBhc3MKICAgICAqIHRocm91Z2ggdGhlIHN1Ymlkcy4KICAgICAqLwogICAgZm9yICg7IGkgPCBNQVhfQ0FMTEJBQ0tfSURTOyBpKyssaj0wKSB7CiAgICAgICAgZm9yICg7IGogPCBNQVhfQ0FMTEJBQ0tfU1VCSURTOyBqKyspIHsKICAgICAgICAgICAgc2NwID0gdGhlY2FsbGJhY2tzW2ldW2pdOyAKICAgICAgICAgICAgd2hpbGUgKHNjcCAhPSBOVUxMKSB7CiAgICAgICAgICAgICAgICBpZiAoKE5VTEwgIT0gc2NwLT5zY19jYWxsYmFjaykgJiYKICAgICAgICAgICAgICAgICAgICAoc2NwLT5zY19jbGllbnRfYXJnICE9IE5VTEwpICYmCiAgICAgICAgICAgICAgICAgICAgKHNjcC0+c2NfY2xpZW50X2FyZyA9PSBwdHIpKSB7CiAgICAgICAgICAgICAgICAgICAgREVCVUdNU0dUTCgoIjk6Y2FsbGJhY2siLCAiICBjbGVhcmluZyAlcCBhdCBbJWQsJWRdXG4iLCBwdHIsIGksIGopKTsKICAgICAgICAgICAgICAgICAgICBzY3AtPnNjX2NsaWVudF9hcmcgPSBOVUxMOwogICAgICAgICAgICAgICAgICAgICsrcmM7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBzY3AgPSBzY3AtPm5leHQ7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgaWYgKDAgIT0gcmMpIHsKICAgICAgICBERUJVR01TR1RMKCgiY2FsbGJhY2siLCAicmVtb3ZlZCAlZCBjbGllbnQgYXJnc1xuIiwgcmMpKTsKICAgIH0KCiAgICByZXR1cm4gcmM7Cn0KCnZvaWQKY2xlYXJfY2FsbGJhY2sodm9pZCkKewogICAgdW5zaWduZWQgaW50IGkgPSAwLCBqID0gMDsKICAgIHN0cnVjdCBzbm1wX2dlbl9jYWxsYmFjayAqc2NwID0gTlVMTDsKCiAgICBpZiAoX2NhbGxiYWNrX25lZWRfaW5pdCkKICAgICAgICBpbml0X2NhbGxiYWNrcygpOwoKICAgIERFQlVHTVNHVEwoKCJjYWxsYmFjayIsICJjbGVhciBjYWxsYmFja1xuIikpOwogICAgZm9yIChpID0gMDsgaSA8IE1BWF9DQUxMQkFDS19JRFM7IGkrKykgewogICAgICAgIGZvciAoaiA9IDA7IGogPCBNQVhfQ0FMTEJBQ0tfU1VCSURTOyBqKyspIHsKICAgICAgICAgICAgX2NhbGxiYWNrX2xvY2soaSxqLCAiY2xlYXJfY2FsbGJhY2siLCAxKTsKICAgICAgICAgICAgc2NwID0gdGhlY2FsbGJhY2tzW2ldW2pdOwogICAgICAgICAgICB3aGlsZSAoc2NwICE9IE5VTEwpIHsKICAgICAgICAgICAgICAgIHRoZWNhbGxiYWNrc1tpXVtqXSA9IHNjcC0+bmV4dDsKICAgICAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAgICAgKiBpZiB0aGVyZSBpcyBhIGNsaWVudCBhcmcsIGNoZWNrIGZvciBkdXBsaWNhdGVzCiAgICAgICAgICAgICAgICAgKiBhbmQgdGhlbiBmcmVlIGl0LgogICAgICAgICAgICAgICAgICovCiAgICAgICAgICAgICAgICBpZiAoKE5VTEwgIT0gc2NwLT5zY19jYWxsYmFjaykgJiYKICAgICAgICAgICAgICAgICAgICAoc2NwLT5zY19jbGllbnRfYXJnICE9IE5VTEwpKSB7CiAgICAgICAgICAgICAgICAgICAgdm9pZCAqdG1wX2FyZzsKICAgICAgICAgICAgICAgICAgICAvKgogICAgICAgICAgICAgICAgICAgICAqIHNhdmUgdGhlIGNsaWVudCBhcmcsIHRoZW4gc2V0IGl0IHRvIG51bGwgc28gdGhhdCBpdAogICAgICAgICAgICAgICAgICAgICAqIHdvbid0IGxvb2sgbGlrZSBhIGR1cGxpY2F0ZSwgdGhlbiBjaGVjayBmb3IgZHVwbGljYXRlcwogICAgICAgICAgICAgICAgICAgICAqIHN0YXJ0aW5nIGF0IHRoZSBjdXJyZW50IGksaiAoZWFybGllciBkdXBzIHNob3VsZCBoYXZlCiAgICAgICAgICAgICAgICAgICAgICogYWxyZWFkeSBiZWVuIGZvdW5kKSBhbmQgZnJlZSB0aGUgcG9pbnRlci4KICAgICAgICAgICAgICAgICAgICAgKi8KICAgICAgICAgICAgICAgICAgICB0bXBfYXJnID0gc2NwLT5zY19jbGllbnRfYXJnOwogICAgICAgICAgICAgICAgICAgIHNjcC0+c2NfY2xpZW50X2FyZyA9IE5VTEw7CiAgICAgICAgICAgICAgICAgICAgREVCVUdNU0dUTCgoIjk6Y2FsbGJhY2siLCAiICBmcmVlaW5nICVwIGF0IFslZCwlZF1cbiIsIHRtcF9hcmcsIGksIGopKTsKICAgICAgICAgICAgICAgICAgICAodm9pZCluZXRzbm1wX2NhbGxiYWNrX2NsZWFyX2NsaWVudF9hcmcodG1wX2FyZywgaSwgaik7CiAgICAgICAgICAgICAgICAgICAgZnJlZSh0bXBfYXJnKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIFNOTVBfRlJFRShzY3ApOwogICAgICAgICAgICAgICAgc2NwID0gdGhlY2FsbGJhY2tzW2ldW2pdOwogICAgICAgICAgICB9CiAgICAgICAgICAgIF9jYWxsYmFja191bmxvY2soaSxqKTsKICAgICAgICB9CiAgICB9Cn0KCnN0cnVjdCBzbm1wX2dlbl9jYWxsYmFjayAqCnNubXBfY2FsbGJhY2tfbGlzdChpbnQgbWFqb3IsIGludCBtaW5vcikKewogICAgaWYgKF9jYWxsYmFja19uZWVkX2luaXQpCiAgICAgICAgaW5pdF9jYWxsYmFja3MoKTsKCiAgICByZXR1cm4gKHRoZWNhbGxiYWNrc1ttYWpvcl1bbWlub3JdKTsKfQovKiogIEB9ICovCg==