LyoKICogY2FsbGJhY2suYzogQSBnZW5lcmljIGNhbGxiYWNrIG1lY2hhbmlzbSAKICovCi8qIFBvcnRpb25zIG9mIHRoaXMgZmlsZSBhcmUgc3ViamVjdCB0byB0aGUgZm9sbG93aW5nIGNvcHlyaWdodChzKS4gIFNlZQogKiB0aGUgTmV0LVNOTVAncyBDT1BZSU5HIGZpbGUgZm9yIG1vcmUgZGV0YWlscyBhbmQgb3RoZXIgY29weXJpZ2h0cwogKiB0aGF0IG1heSBhcHBseToKICovCi8qCiAqIFBvcnRpb25zIG9mIHRoaXMgZmlsZSBhcmUgY29weXJpZ2h0ZWQgYnk6CiAqIENvcHlyaWdodCCpIDIwMDMgU3VuIE1pY3Jvc3lzdGVtcywgSW5jLiBBbGwgcmlnaHRzIHJlc2VydmVkLgogKiBVc2UgaXMgc3ViamVjdCB0byBsaWNlbnNlIHRlcm1zIHNwZWNpZmllZCBpbiB0aGUgQ09QWUlORyBmaWxlCiAqIGRpc3RyaWJ1dGVkIHdpdGggdGhlIE5ldC1TTk1QIHBhY2thZ2UuCiAqLwovKiogQGRlZmdyb3VwIGNhbGxiYWNrIEEgZ2VuZXJpYyBjYWxsYmFjayBtZWNoYW5pc20gCiAqICBAaW5ncm91cCBsaWJyYXJ5CiAqIAogKiAgQHsKICovCiNpbmNsdWRlIDxuZXQtc25tcC9uZXQtc25tcC1jb25maWcuaD4KI2luY2x1ZGUgPHN5cy90eXBlcy5oPgojaW5jbHVkZSA8c3RkaW8uaD4KI2lmIEhBVkVfU1RETElCX0gKI2luY2x1ZGUgPHN0ZGxpYi5oPgojZW5kaWYKI2lmIEhBVkVfV0lOU09DS19ICiNpbmNsdWRlIDx3aW5zb2NrLmg+CiNlbmRpZgojaWYgSEFWRV9ORVRJTkVUX0lOX0gKI2luY2x1ZGUgPG5ldGluZXQvaW4uaD4KI2VuZGlmCiNpZiBIQVZFX1NUUklOR19ICiNpbmNsdWRlIDxzdHJpbmcuaD4KI2Vsc2UKI2luY2x1ZGUgPHN0cmluZ3MuaD4KI2VuZGlmCgojaWYgSEFWRV9VTklTVERfSAojaW5jbHVkZSA8dW5pc3RkLmg+CiNlbmRpZgojaWYgSEFWRV9ETUFMTE9DX0gKI2luY2x1ZGUgPGRtYWxsb2MuaD4KI2VuZGlmCgojaWYgSEFWRV9TWVNfU09DS0VUX0gKI2luY2x1ZGUgPHN5cy9zb2NrZXQuaD4KI2VuZGlmCiNpZiAhZGVmaW5lZChtaW5ndzMyKSAmJiBkZWZpbmVkKEhBVkVfU1lTX1RJTUVfSCkKI2luY2x1ZGUgPHN5cy90aW1lLmg+CiNlbmRpZgoKI2luY2x1ZGUgPG5ldC1zbm1wL3R5cGVzLmg+CiNpbmNsdWRlIDxuZXQtc25tcC9vdXRwdXRfYXBpLmg+CiNpbmNsdWRlIDxuZXQtc25tcC91dGlsaXRpZXMuaD4KCiNpbmNsdWRlIDxuZXQtc25tcC9saWJyYXJ5L2NhbGxiYWNrLmg+CiNpbmNsdWRlIDxuZXQtc25tcC9saWJyYXJ5L3NubXBfYXBpLmg+CgovKgogKiB0aGUgaW5saW5lIGNhbGxiYWNrIG1ldGhvZHMgdXNlIG1ham9yL21pbm9yIHRvIGluZGV4IGludG8gYXJyYXlzLgogKiBhbGwgdXNlcnMgaW4gdGhpcyBmdW5jdGlvbiBkbyByYW5nZSBjaGVja2luZyBiZWZvcmUgY2FsbGluZyB0aGVzZQogKiBmdW5jdGlvbnMsIHNvIGl0IGlzIHJlZHVuZGFudCBmb3IgdGhlbSB0byBjaGVjayBhZ2Fpbi4gQnV0IGlmIHlvdQogKiB3YW50IHRvIGJlIHBhcmFub2lkLCBkZWZpbmUgdGhpcyB2YXIsIGFuZCBhZGRpdGlvbmFsIHJhbmdlIGNoZWNrcwogKiB3aWxsIGJlIHBlcmZvcm1lZC4KICogI2RlZmluZSBORVRTTk1QX1BBUkFOT0lEX0xFVkVMX0hJR0ggMSAKICovCgpzdGF0aWMgaW50IF9jYWxsYmFja19uZWVkX2luaXQgPSAxOwpzdGF0aWMgc3RydWN0IHNubXBfZ2VuX2NhbGxiYWNrCiAgICAgICAgICAgICAgICp0aGVjYWxsYmFja3NbTUFYX0NBTExCQUNLX0lEU11bTUFYX0NBTExCQUNLX1NVQklEU107CgojZGVmaW5lIENBTExCQUNLX05BTUVfTE9HR0lORyAxCiNpZmRlZiBDQUxMQkFDS19OQU1FX0xPR0dJTkcKc3RhdGljIGNvbnN0IGNoYXIgKnR5cGVzW01BWF9DQUxMQkFDS19JRFNdID0geyAiTElCIiwgIkFQUCIgfTsKc3RhdGljIGNvbnN0IGNoYXIgKmxpYltNQVhfQ0FMTEJBQ0tfU1VCSURTXSA9IHsKICAgICJQT1NUX1JFQURfQ09ORklHIiwgLyogMCAqLwogICAgIlNUT1JFX0RBVEEiLCAvKiAxICovCiAgICAiU0hVVERPV04iLCAvKiAyICovCiAgICAiUE9TVF9QUkVNSUJfUkVBRF9DT05GSUciLCAvKiAzICovCiAgICAiTE9HR0lORyIsIC8qIDQgKi8KICAgICJTRVNTSU9OX0lOSVQiLCAvKiA1ICovCiAgICBOVUxMLCAvKiA2ICovCiAgICBOVUxMLCAvKiA3ICovCiAgICBOVUxMLCAvKiA4ICovCiAgICBOVUxMLCAvKiA5ICovCiAgICBOVUxMLCAvKiAxMCAqLwogICAgTlVMTCwgLyogMTEgKi8KICAgIE5VTEwsIC8qIDEyICovCiAgICBOVUxMLCAvKiAxMyAqLwogICAgTlVMTCwgLyogMTQgKi8KICAgIE5VTEwgLyogMTUgKi8KfTsKI2VuZGlmCgovKgogKiBleHRyZW1lbHkgc2ltcGxpc3RpYyBsb2NraW5nLCBqdXN0IHRvIGZpbmQgcHJvYmxlbXMgd2VyZSB0aGUKICogY2FsbGJhY2sgbGlzdCBpcyBtb2RpZmllZCB3aGlsZSBiZWluZyB0cmF2ZXJzZWQuIE5vdCBpbnRlbmRlZAogKiB0byBkbyBhbnkgcmVhbCBwcm90ZWN0aW9uLCBvciBpbiBhbnkgd2F5IGltcGx5IHRoYXQgdGhpcyBjb2RlCiAqIGhhcyBiZWVuIGV2YWx1YXRlZCBmb3IgdXNlIGluIGEgbXVsdGktdGhyZWFkZWQgZW52aXJvbm1lbnQuCiAqIEluIDUuMiwgaXQgd2FzIGEgc2luZ2xlIGxvY2suIEZvciA1LjMsIGl0IGhhcyBiZWVuIHVwZGF0ZWQgdG8KICogYSBsb2NrIHBlciBjYWxsYmFjaywgc2luY2UgYSBwYXJ0aWN1bGFyIGNhbGxiYWNrIG1heSB0cmlnZ2VyCiAqIHJlZ2lzdHJhdGlvbi91bnJlZ2lzdHJhdGlvbiBvZiBvdGhlciBjYWxsYmFja3MgKGVnIEFnZW50WAogKiBzdWJhZ2VudHMgZG8gdGhpcykuCiAqLwojZGVmaW5lIExPQ0tfUEVSX0NBTExCQUNLX1NVQklEIDEKI2lmZGVmIExPQ0tfUEVSX0NBTExCQUNLX1NVQklECnN0YXRpYyBpbnQgX2xvY2tzW01BWF9DQUxMQkFDS19JRFNdW01BWF9DQUxMQkFDS19TVUJJRFNdOwojZGVmaW5lIENBTExCQUNLX0xPQ0sobWFqLG1pbikgKytfbG9ja3NbbWFqXVttaW5dCiNkZWZpbmUgQ0FMTEJBQ0tfVU5MT0NLKG1haixtaW4pIC0tX2xvY2tzW21hal1bbWluXQojZGVmaW5lIENBTExCQUNLX0xPQ0tfQ09VTlQobWFqLG1pbikgX2xvY2tzW21hal1bbWluXQojZWxzZQpzdGF0aWMgaW50IF9sb2NrOwojZGVmaW5lIENBTExCQUNLX0xPQ0sobWFqLG1pbikgKytfbG9jawojZGVmaW5lIENBTExCQUNLX1VOTE9DSyhtYWosbWluKSAtLV9sb2NrCiNkZWZpbmUgQ0FMTEJBQ0tfTE9DS19DT1VOVChtYWosbWluKSBfbG9jawojZW5kaWYKCk5FVFNOTVBfU1RBVElDX0lOTElORSBpbnQKX2NhbGxiYWNrX2xvY2soaW50IG1ham9yLCBpbnQgbWlub3IsIGNvbnN0IGNoYXIqIHdhcm4sIGludCBhc3NlcnQpCnsKICAgIGludCBsb2NrX2hvbGRlZD0wOwogICAgc3RydWN0IHRpbWV2YWwgbG9ja190aW1lID0geyAwLCAxMDAwIH07CgojaWZkZWYgTkVUU05NUF9QQVJBTk9JRF9MRVZFTF9ISUdICiAgICBpZiAobWFqb3IgPj0gTUFYX0NBTExCQUNLX0lEUyB8fCBtaW5vciA+PSBNQVhfQ0FMTEJBQ0tfU1VCSURTKSB7CiAgICAgICAgbmV0c25tcF9hc3NlcnQoImJhZCBjYWxsYmFjayBpZCIpOwogICAgICAgIHJldHVybiAxOwogICAgfQojZW5kaWYKICAgIAojaWZkZWYgQ0FMTEJBQ0tfTkFNRV9MT0dHSU5HCiAgICBERUJVR01TR1RMKCgiOTpjYWxsYmFjazpsb2NrIiwgImxvY2tlZCAoJXMsJXMpXG4iLAogICAgICAgICAgICAgICAgdHlwZXNbbWFqb3JdLCAoU05NUF9DQUxMQkFDS19MSUJSQVJZID09IG1ham9yKSA/CiAgICAgICAgICAgICAgICBTTk1QX1NUUk9STlVMTChsaWJbbWlub3JdKSA6ICJudWxsIikpOwojZW5kaWYKICAgIHdoaWxlIChDQUxMQkFDS19MT0NLX0NPVU5UKG1ham9yLG1pbm9yKSA+PSAxICYmICsrbG9ja19ob2xkZWQgPCAxMDApCglzZWxlY3QoMCwgTlVMTCwgTlVMTCwgTlVMTCwgJmxvY2tfdGltZSk7CgogICAgaWYobG9ja19ob2xkZWQgPj0gMTAwKSB7CiAgICAgICAgaWYgKE5VTEwgIT0gd2FybikKICAgICAgICAgICAgc25tcF9sb2coTE9HX1dBUk5JTkcsCiAgICAgICAgICAgICAgICAgICAgICJsb2NrIGluIF9jYWxsYmFja19sb2NrIHNsZWVwcyBtb3JlIHRoYW4gMTAwIG1pbGxpc2Vjb25kcyBpbiAlc1xuIiwgd2Fybik7CiAgICAgICAgaWYgKGFzc2VydCkKICAgICAgICAgICAgbmV0c25tcF9hc3NlcnQobG9ja19ob2xkZWQgPCAxMDApOwogICAgICAgIAogICAgICAgIHJldHVybiAxOwogICAgfQoKICAgIENBTExCQUNLX0xPQ0sobWFqb3IsbWlub3IpOwogICAgcmV0dXJuIDA7Cn0KCk5FVFNOTVBfU1RBVElDX0lOTElORSB2b2lkCl9jYWxsYmFja191bmxvY2soaW50IG1ham9yLCBpbnQgbWlub3IpCnsKI2lmZGVmIE5FVFNOTVBfUEFSQU5PSURfTEVWRUxfSElHSAogICAgaWYgKG1ham9yID49IE1BWF9DQUxMQkFDS19JRFMgfHwgbWlub3IgPj0gTUFYX0NBTExCQUNLX1NVQklEUykgewogICAgICAgIG5ldHNubXBfYXNzZXJ0KCJiYWQgY2FsbGJhY2sgaWQiKTsKICAgICAgICByZXR1cm47CiAgICB9CiNlbmRpZgogICAgCiAgICBDQUxMQkFDS19VTkxPQ0sobWFqb3IsbWlub3IpOwoKI2lmZGVmIENBTExCQUNLX05BTUVfTE9HR0lORwogICAgREVCVUdNU0dUTCgoIjk6Y2FsbGJhY2s6bG9jayIsICJ1bmxvY2tlZCAoJXMsJXMpXG4iLAogICAgICAgICAgICAgICAgdHlwZXNbbWFqb3JdLCAoU05NUF9DQUxMQkFDS19MSUJSQVJZID09IG1ham9yKSA/CiAgICAgICAgICAgICAgICBTTk1QX1NUUk9STlVMTChsaWJbbWlub3JdKSA6ICJudWxsIikpOwojZW5kaWYKfQoKCi8qCiAqIHRoZSBjaGlja2VuLiBvciB0aGUgZWdnLiAgWW91IHBpY2suIAogKi8Kdm9pZAppbml0X2NhbGxiYWNrcyh2b2lkKQp7CiAgICAvKgogICAgICogKHBvc2VzIGEgcHJvYmxlbSBpZiB5b3UgcHV0IGluaXRfY2FsbGJhY2tzKCkgaW5zaWRlIG9mCiAgICAgKiBpbml0X3NubXAoKSBhbmQgdGhlbiB3YW50IHRoZSBhcHAgdG8gcmVnaXN0ZXIgYSBjYWxsYmFjayBiZWZvcmUKICAgICAqIGluaXRfc25tcCgpIGlzIGNhbGxlZCBpbiB0aGUgZmlyc3QgcGxhY2UuICAtLSBXZXMgCiAgICAgKi8KICAgIGlmICgwID09IF9jYWxsYmFja19uZWVkX2luaXQpCiAgICAgICAgcmV0dXJuOwogICAgCiAgICBfY2FsbGJhY2tfbmVlZF9pbml0ID0gMDsKICAgIAogICAgbWVtc2V0KHRoZWNhbGxiYWNrcywgMCwgc2l6ZW9mKHRoZWNhbGxiYWNrcykpOyAKI2lmZGVmIExPQ0tfUEVSX0NBTExCQUNLX1NVQklECiAgICBtZW1zZXQoX2xvY2tzLCAwLCBzaXplb2YoX2xvY2tzKSk7CiNlbHNlCiAgICBfbG9jayA9IDA7CiNlbmRpZgogICAgCiAgICBERUJVR01TR1RMKCgiY2FsbGJhY2siLCAiaW5pdGlhbGl6ZWRcbiIpKTsKfQoKLyoqCiAqIFRoaXMgZnVuY3Rpb24gcmVnaXN0ZXJzIGEgZ2VuZXJpYyBjYWxsYmFjayBmdW5jdGlvbi4gIFRoZSBtYWpvciBhbmQKICogbWlub3IgdmFsdWVzIGFyZSB1c2VkIHRvIHNldCB0aGUgbmV3X2NhbGxiYWNrIGZ1bmN0aW9uIGludG8gYSBnbG9iYWwgCiAqIHN0YXRpYyBtdWx0aS1kaW1lbnNpb25hbCBhcnJheSBvZiB0eXBlIHN0cnVjdCBzbm1wX2dlbl9jYWxsYmFjay4gIAogKiBUaGUgZnVuY3Rpb24gbWFrZXMgc3VyZSB0byBhcHBlbmQgdGhpcyBjYWxsYmFjayBmdW5jdGlvbiBhdCB0aGUgZW5kCiAqIG9mIHRoZSBsaW5rIGxpc3QsIHNubXBfZ2VuX2NhbGxiYWNrLT5uZXh0LgogKgogKiBAcGFyYW0gbWFqb3IgaXMgdGhlIFNOTVAgY2FsbGJhY2sgbWFqb3IgdHlwZSB1c2VkCiAqIAkJLSBTTk1QX0NBTExCQUNLX0xJQlJBUlkKICogICAgICAgICAgICAgIC0gU05NUF9DQUxMQkFDS19BUFBMSUNBVElPTgogKgogKiBAcGFyYW0gbWlub3IgaXMgdGhlIFNOTVAgY2FsbGJhY2sgbWlub3IgdHlwZSB1c2VkCiAqCQktIFNOTVBfQ0FMTEJBQ0tfUE9TVF9SRUFEX0NPTkZJRwogKgkJLSBTTk1QX0NBTExCQUNLX1NUT1JFX0RBVEEJICAgICAgICAKICoJCS0gU05NUF9DQUxMQkFDS19TSFVURE9XTgkJICAgICAgICAKICoJCS0gU05NUF9DQUxMQkFDS19QT1NUX1BSRU1JQl9SRUFEX0NPTkZJRwkKICoJCS0gU05NUF9DQUxMQkFDS19MT0dHSU5HCQkJCiAqCQktIFNOTVBfQ0FMTEJBQ0tfU0VTU0lPTl9JTklUCSAgICAgICAKICoKICogQHBhcmFtIG5ld19jYWxsYmFjayBpcyB0aGUgY2FsbGJhY2sgZnVuY3Rpb24gdGhhdCBpcyByZWdpc3RlcmVkLgogKgogKiBAcGFyYW0gYXJnIHdoZW4gbm90IE5VTEwgaXMgYSB2b2lkIHBvaW50ZXIgdXNlZCB3aGVuZXZlciBuZXdfY2FsbGJhY2sgCiAqCWZ1bmN0aW9uIGlzIGV4ZXJjaXNlZC4KICoKICogQHJldHVybiAKICoJUmV0dXJucyBTTk1QRVJSX0dFTkVSUiBpZiBtYWpvciBpcyA+PSBNQVhfQ0FMTEJBQ0tfSURTIG9yIG1pbm9yIGlzID49CiAqCU1BWF9DQUxMQkFDS19TVUJJRFMgb3IgYSBzbm1wX2dlbl9jYWxsYmFjayBwb2ludGVyIGNvdWxkIG5vdCBiZSAKICoJYWxsb2NhdGVkLCBvdGhlcndpc2UgU05NUEVSUl9TVUNDRVNTIGlzIHJldHVybmVkLgogKiAJLSBcI2RlZmluZSBNQVhfQ0FMTEJBQ0tfSURTICAgIDIKICoJLSBcI2RlZmluZSBNQVhfQ0FMTEJBQ0tfU1VCSURTIDE2CiAqCiAqIEBzZWUgc25tcF9jYWxsX2NhbGxiYWNrcwogKiBAc2VlIHNubXBfdW5yZWdpc3Rlcl9jYWxsYmFjawogKi8KaW50CnNubXBfcmVnaXN0ZXJfY2FsbGJhY2soaW50IG1ham9yLCBpbnQgbWlub3IsIFNOTVBDYWxsYmFjayAqIG5ld19jYWxsYmFjaywKICAgICAgICAgICAgICAgICAgICAgICB2b2lkICphcmcpCnsKICAgIHJldHVybiBuZXRzbm1wX3JlZ2lzdGVyX2NhbGxiYWNrKCBtYWpvciwgbWlub3IsIG5ld19jYWxsYmFjaywgYXJnLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5FVFNOTVBfQ0FMTEJBQ0tfREVGQVVMVF9QUklPUklUWSk7Cn0KCmludApuZXRzbm1wX3JlZ2lzdGVyX2NhbGxiYWNrKGludCBtYWpvciwgaW50IG1pbm9yLCBTTk1QQ2FsbGJhY2sgKiBuZXdfY2FsbGJhY2ssCiAgICAgICAgICAgICAgICAgICAgICAgICAgdm9pZCAqYXJnLCBpbnQgcHJpb3JpdHkpCnsKICAgIHN0cnVjdCBzbm1wX2dlbl9jYWxsYmFjayAqbmV3c2NwID0gTlVMTCwgKnNjcCA9IE5VTEw7CiAgICBzdHJ1Y3Qgc25tcF9nZW5fY2FsbGJhY2sgKipwcmV2TmV4dCA9ICYodGhlY2FsbGJhY2tzW21ham9yXVttaW5vcl0pOwoKICAgIGlmIChtYWpvciA+PSBNQVhfQ0FMTEJBQ0tfSURTIHx8IG1pbm9yID49IE1BWF9DQUxMQkFDS19TVUJJRFMpIHsKICAgICAgICByZXR1cm4gU05NUEVSUl9HRU5FUlI7CiAgICB9CgogICAgaWYgKF9jYWxsYmFja19uZWVkX2luaXQpCiAgICAgICAgaW5pdF9jYWxsYmFja3MoKTsKCiAgICBfY2FsbGJhY2tfbG9jayhtYWpvcixtaW5vciwgIm5ldHNubXBfcmVnaXN0ZXJfY2FsbGJhY2siLCAxKTsKICAgIAogICAgaWYgKChuZXdzY3AgPSBTTk1QX01BTExPQ19TVFJVQ1Qoc25tcF9nZW5fY2FsbGJhY2spKSA9PSBOVUxMKSB7CiAgICAgICAgX2NhbGxiYWNrX3VubG9jayhtYWpvcixtaW5vcik7CiAgICAgICAgcmV0dXJuIFNOTVBFUlJfR0VORVJSOwogICAgfSBlbHNlIHsKICAgICAgICBuZXdzY3AtPnByaW9yaXR5ID0gcHJpb3JpdHk7CiAgICAgICAgbmV3c2NwLT5zY19jbGllbnRfYXJnID0gYXJnOwogICAgICAgIG5ld3NjcC0+c2NfY2FsbGJhY2sgPSBuZXdfY2FsbGJhY2s7CiAgICAgICAgbmV3c2NwLT5uZXh0ID0gTlVMTDsKCiAgICAgICAgZm9yIChzY3AgPSB0aGVjYWxsYmFja3NbbWFqb3JdW21pbm9yXTsgc2NwICE9IE5VTEw7CiAgICAgICAgICAgICBzY3AgPSBzY3AtPm5leHQpIHsKICAgICAgICAgICAgaWYgKG5ld3NjcC0+cHJpb3JpdHkgPCBzY3AtPnByaW9yaXR5KSB7CiAgICAgICAgICAgICAgICBuZXdzY3AtPm5leHQgPSBzY3A7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgICAgICBwcmV2TmV4dCA9ICYoc2NwLT5uZXh0KTsKICAgICAgICB9CgogICAgICAgICpwcmV2TmV4dCA9IG5ld3NjcDsKCiAgICAgICAgREVCVUdNU0dUTCgoImNhbGxiYWNrIiwgInJlZ2lzdGVyZWQgKCVkLCVkKSBhdCAlcCB3aXRoIHByaW9yaXR5ICVkXG4iLAogICAgICAgICAgICAgICAgICAgIG1ham9yLCBtaW5vciwgbmV3c2NwLCBwcmlvcml0eSkpOwogICAgICAgIF9jYWxsYmFja191bmxvY2sobWFqb3IsbWlub3IpOwogICAgICAgIHJldHVybiBTTk1QRVJSX1NVQ0NFU1M7CiAgICB9Cn0KCi8qKgogKiBUaGlzIGZ1bmN0aW9uIGNhbGxzIHRoZSBjYWxsYmFjayBmdW5jdGlvbiBmb3IgZWFjaCByZWdpc3RlcmVkIGNhbGxiYWNrIG9mCiAqIHR5cGUgbWFqb3IgYW5kIG1pbm9yLgogKgogKiBAcGFyYW0gbWFqb3IgaXMgdGhlIFNOTVAgY2FsbGJhY2sgbWFqb3IgdHlwZSB1c2VkCiAqCiAqIEBwYXJhbSBtaW5vciBpcyB0aGUgU05NUCBjYWxsYmFjayBtaW5vciB0eXBlIHVzZWQKICoKICogQHBhcmFtIGNhbGxlcl9hcmcgaXMgYSB2b2lkIHBvaW50ZXIgd2hpY2ggaXMgc2VudCBpbiBhcyB0aGUgY2FsbGJhY2sncyAKICoJc2VydmVyYXJnIHBhcmFtZXRlciwgaWYgbmVlZGVkLgogKgogKiBAcmV0dXJuIFJldHVybnMgU05NUEVSUl9HRU5FUlIgaWYgbWFqb3IgaXMgPj0gTUFYX0NBTExCQUNLX0lEUyBvcgogKiBtaW5vciBpcyA+PSBNQVhfQ0FMTEJBQ0tfU1VCSURTLCBvdGhlcndpc2UgU05NUEVSUl9TVUNDRVNTIGlzIHJldHVybmVkLgogKgogKiBAc2VlIHNubXBfcmVnaXN0ZXJfY2FsbGJhY2sKICogQHNlZSBzbm1wX3VucmVnaXN0ZXJfY2FsbGJhY2sKICovCmludApzbm1wX2NhbGxfY2FsbGJhY2tzKGludCBtYWpvciwgaW50IG1pbm9yLCB2b2lkICpjYWxsZXJfYXJnKQp7CiAgICBzdHJ1Y3Qgc25tcF9nZW5fY2FsbGJhY2sgKnNjcDsKICAgIHVuc2lnbmVkIGludCAgICBjb3VudCA9IDA7CiAgICAKICAgIGlmIChtYWpvciA+PSBNQVhfQ0FMTEJBQ0tfSURTIHx8IG1pbm9yID49IE1BWF9DQUxMQkFDS19TVUJJRFMpIHsKICAgICAgICByZXR1cm4gU05NUEVSUl9HRU5FUlI7CiAgICB9CiAgICAKICAgIGlmIChfY2FsbGJhY2tfbmVlZF9pbml0KQogICAgICAgIGluaXRfY2FsbGJhY2tzKCk7CgojaWZkZWYgTE9DS19QRVJfQ0FMTEJBQ0tfU1VCSUQKICAgIF9jYWxsYmFja19sb2NrKG1ham9yLG1pbm9yLCJzbm1wX2NhbGxfY2FsbGJhY2tzIiwgMSk7CiNlbHNlCiAgICAvKgogICAgICogTm90ZXM6CiAgICAgKiAtIHRoaXMgZ2V0cyBoaXQgdGhlIGZpcnN0IHRpbWUgYSB0cmFwIGlzIHNlbnQgYWZ0ZXIgYSBuZXcgdHJhcAogICAgICogICBkZXN0aW5hdGlvbiBoYXMgYmVlbiBhZGRlZCAoc2Vzc2lvbiBpbml0IGNiIGR1cmluZyBzZW5kIHRyYXAgY2IpCiAgICAgKi8KICAgIF9jYWxsYmFja19sb2NrKG1ham9yLG1pbm9yLCBOVUxMLCAwKTsKI2VuZGlmCgogICAgREVCVUdNU0dUTCgoImNhbGxiYWNrIiwgIlNUQVJUIGNhbGxpbmcgY2FsbGJhY2tzIGZvciBtYWo9JWQgbWluPSVkXG4iLAogICAgICAgICAgICAgICAgbWFqb3IsIG1pbm9yKSk7CgogICAgLyoKICAgICAqIGZvciBlYWNoIHJlZ2lzdGVyZWQgY2FsbGJhY2sgb2YgdHlwZSBtYWpvciBhbmQgbWlub3IgCiAgICAgKi8KICAgIGZvciAoc2NwID0gdGhlY2FsbGJhY2tzW21ham9yXVttaW5vcl07IHNjcCAhPSBOVUxMOyBzY3AgPSBzY3AtPm5leHQpIHsKCiAgICAgICAgLyoKICAgICAgICAgKiBza2lwIHVucmVnaXN0ZXJlZCBjYWxsYmFja3MKICAgICAgICAgKi8KICAgICAgICBpZihOVUxMID09IHNjcC0+c2NfY2FsbGJhY2spCiAgICAgICAgICAgIGNvbnRpbnVlOwoKICAgICAgICBERUJVR01TR1RMKCgiY2FsbGJhY2siLCAiY2FsbGluZyBhIGNhbGxiYWNrIGZvciBtYWo9JWQgbWluPSVkXG4iLAogICAgICAgICAgICAgICAgICAgIG1ham9yLCBtaW5vcikpOwoKICAgICAgICAvKgogICAgICAgICAqIGNhbGwgdGhlbSAKICAgICAgICAgKi8KICAgICAgICAoKihzY3AtPnNjX2NhbGxiYWNrKSkgKG1ham9yLCBtaW5vciwgY2FsbGVyX2FyZywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNjcC0+c2NfY2xpZW50X2FyZyk7CiAgICAgICAgY291bnQrKzsKICAgIH0KCiAgICBERUJVR01TR1RMKCgiY2FsbGJhY2siLAogICAgICAgICAgICAgICAgIkVORCBjYWxsaW5nIGNhbGxiYWNrcyBmb3IgbWFqPSVkIG1pbj0lZCAoJWQgY2FsbGVkKVxuIiwKICAgICAgICAgICAgICAgIG1ham9yLCBtaW5vciwgY291bnQpKTsKCiAgICBfY2FsbGJhY2tfdW5sb2NrKG1ham9yLG1pbm9yKTsKICAgIHJldHVybiBTTk1QRVJSX1NVQ0NFU1M7Cn0KCmludApzbm1wX2NvdW50X2NhbGxiYWNrcyhpbnQgbWFqb3IsIGludCBtaW5vcikKewogICAgaW50ICAgICAgICAgICAgIGNvdW50ID0gMDsKICAgIHN0cnVjdCBzbm1wX2dlbl9jYWxsYmFjayAqc2NwOwoKICAgIGlmIChtYWpvciA+PSBNQVhfQ0FMTEJBQ0tfSURTIHx8IG1pbm9yID49IE1BWF9DQUxMQkFDS19TVUJJRFMpIHsKICAgICAgICByZXR1cm4gU05NUEVSUl9HRU5FUlI7CiAgICB9CiAgICAKICAgIGlmIChfY2FsbGJhY2tfbmVlZF9pbml0KQogICAgICAgIGluaXRfY2FsbGJhY2tzKCk7CgogICAgZm9yIChzY3AgPSB0aGVjYWxsYmFja3NbbWFqb3JdW21pbm9yXTsgc2NwICE9IE5VTEw7IHNjcCA9IHNjcC0+bmV4dCkgewogICAgICAgIGNvdW50Kys7CiAgICB9CgogICAgcmV0dXJuIGNvdW50Owp9CgppbnQKc25tcF9jYWxsYmFja19hdmFpbGFibGUoaW50IG1ham9yLCBpbnQgbWlub3IpCnsKICAgIGlmIChtYWpvciA+PSBNQVhfQ0FMTEJBQ0tfSURTIHx8IG1pbm9yID49IE1BWF9DQUxMQkFDS19TVUJJRFMpIHsKICAgICAgICByZXR1cm4gU05NUEVSUl9HRU5FUlI7CiAgICB9CiAgICAKICAgIGlmIChfY2FsbGJhY2tfbmVlZF9pbml0KQogICAgICAgIGluaXRfY2FsbGJhY2tzKCk7CgogICAgaWYgKHRoZWNhbGxiYWNrc1ttYWpvcl1bbWlub3JdICE9IE5VTEwpIHsKICAgICAgICByZXR1cm4gU05NUEVSUl9TVUNDRVNTOwogICAgfQoKICAgIHJldHVybiBTTk1QRVJSX0dFTkVSUjsKfQoKLyoqCiAqIFRoaXMgZnVuY3Rpb24gdW5yZWdpc3RlcnMgYSBzcGVjaWZpZWQgY2FsbGJhY2sgZnVuY3Rpb24gZ2l2ZW4gYSBtYWpvcgogKiBhbmQgbWlub3IgdHlwZS4KICoKICogTm90ZTogbm8gYm91bmQgY2hlY2tpbmcgb24gbWFqb3IgYW5kIG1pbm9yLgogKgogKiBAcGFyYW0gbWFqb3IgaXMgdGhlIFNOTVAgY2FsbGJhY2sgbWFqb3IgdHlwZSB1c2VkCiAqCiAqIEBwYXJhbSBtaW5vciBpcyB0aGUgU05NUCBjYWxsYmFjayBtaW5vciB0eXBlIHVzZWQKICoKICogQHBhcmFtIHRhcmdldCBpcyB0aGUgY2FsbGJhY2sgZnVuY3Rpb24gdGhhdCB3aWxsIGJlIHVucmVnaXN0ZXJlZC4KICoKICogQHBhcmFtIGFyZyBpcyBhIHZvaWQgcG9pbnRlciB1c2VkIGZvciBjb21wYXJpc29uIGFnYWluc3QgdGhlIHJlZ2lzdGVyZWQgCiAqCWNhbGxiYWNrJ3Mgc2NfY2xpZW50X2FyZyB2YXJpYWJsZS4KICoKICogQHBhcmFtIG1hdGNoYXJncyBpcyBhbiBpbnRlZ2VyIHVzZWQgdG8gYnlwYXNzIHRoZSBjb21wYXJpc29uIG9mIGFyZyBhbmQgdGhlCiAqCWNhbGxiYWNrJ3Mgc2NfY2xpZW50X2FyZyB2YXJpYWJsZSBvbmx5IHdoZW4gbWF0Y2hhcmdzIGlzIHNldCB0byAwLgogKgogKgogKiBAcmV0dXJuCiAqICAgICAgICBSZXR1cm5zIHRoZSBudW1iZXIgb2YgY2FsbGJhY2tzIHRoYXQgd2VyZSB1bnJlZ2lzdGVyZWQuCiAqCiAqIEBzZWUgc25tcF9yZWdpc3Rlcl9jYWxsYmFjawogKiBAc2VlIHNubXBfY2FsbF9jYWxsYmFja3MKICovCgppbnQKc25tcF91bnJlZ2lzdGVyX2NhbGxiYWNrKGludCBtYWpvciwgaW50IG1pbm9yLCBTTk1QQ2FsbGJhY2sgKiB0YXJnZXQsCiAgICAgICAgICAgICAgICAgICAgICAgICB2b2lkICphcmcsIGludCBtYXRjaGFyZ3MpCnsKICAgIHN0cnVjdCBzbm1wX2dlbl9jYWxsYmFjayAqc2NwID0gdGhlY2FsbGJhY2tzW21ham9yXVttaW5vcl07CiAgICBzdHJ1Y3Qgc25tcF9nZW5fY2FsbGJhY2sgKipwcmV2TmV4dCA9ICYodGhlY2FsbGJhY2tzW21ham9yXVttaW5vcl0pOwogICAgaW50ICAgICAgICAgICAgIGNvdW50ID0gMDsKCiAgICBpZiAobWFqb3IgPj0gTUFYX0NBTExCQUNLX0lEUyB8fCBtaW5vciA+PSBNQVhfQ0FMTEJBQ0tfU1VCSURTKQogICAgICAgIHJldHVybiBTTk1QRVJSX0dFTkVSUjsKCiAgICBpZiAoX2NhbGxiYWNrX25lZWRfaW5pdCkKICAgICAgICBpbml0X2NhbGxiYWNrcygpOwoKI2lmZGVmIExPQ0tfUEVSX0NBTExCQUNLX1NVQklECiAgICBfY2FsbGJhY2tfbG9jayhtYWpvcixtaW5vciwic25tcF91bnJlZ2lzdGVyX2NhbGxiYWNrIiwgMSk7CiNlbHNlCiAgICAvKgogICAgICogTm90ZXM7CiAgICAgKiAtIHRoaXMgZ2V0cyBoaXQgYXQgc2h1dGRvd24sIGR1cmluZyBjbGVhbnVwLiBObyBlYXN5IGZpeC4KICAgICAqLwogICAgX2NhbGxiYWNrX2xvY2sobWFqb3IsbWlub3IsInNubXBfdW5yZWdpc3Rlcl9jYWxsYmFjayIsIDApOwojZW5kaWYKCiAgICB3aGlsZSAoc2NwICE9IE5VTEwpIHsKICAgICAgICBpZiAoKHNjcC0+c2NfY2FsbGJhY2sgPT0gdGFyZ2V0KSAmJgogICAgICAgICAgICAoIW1hdGNoYXJncyB8fCAoc2NwLT5zY19jbGllbnRfYXJnID09IGFyZykpKSB7CiAgICAgICAgICAgIERFQlVHTVNHVEwoKCJjYWxsYmFjayIsICJ1bnJlZ2lzdGVyaW5nICglZCwlZCkgYXQgJXBcbiIsIG1ham9yLAogICAgICAgICAgICAgICAgICAgICAgICBtaW5vciwgc2NwKSk7CiAgICAgICAgICAgIGlmKDEgPT0gQ0FMTEJBQ0tfTE9DS19DT1VOVChtYWpvcixtaW5vcikpIHsKICAgICAgICAgICAgICAgICpwcmV2TmV4dCA9IHNjcC0+bmV4dDsKICAgICAgICAgICAgICAgIFNOTVBfRlJFRShzY3ApOwogICAgICAgICAgICAgICAgc2NwID0gKnByZXZOZXh0OwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UgewogICAgICAgICAgICAgICAgc2NwLT5zY19jYWxsYmFjayA9IE5VTEw7CiAgICAgICAgICAgICAgICAvKiogc2V0IGNsZWFudXAgZmxhZz8gKi8KICAgICAgICAgICAgfQogICAgICAgICAgICBjb3VudCsrOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHByZXZOZXh0ID0gJihzY3AtPm5leHQpOwogICAgICAgICAgICBzY3AgPSBzY3AtPm5leHQ7CiAgICAgICAgfQogICAgfQoKICAgIF9jYWxsYmFja191bmxvY2sobWFqb3IsbWlub3IpOwogICAgcmV0dXJuIGNvdW50Owp9CgovKioKICogZmluZCBhbmQgY2xlYXIgY2xpZW50IGFyZ3MgdGhhdCBtYXRjaCBwdHIKICoKICogQHBhcmFtIHB0ciAgcG9pbnRlciB0byBzZWFyY2ggZm9yCiAqIEBwYXJhbSBpICAgIGNhbGxiYWNrIGlkIHRvIHN0YXJ0IGF0CiAqIEBwYXJhbSBqICAgIGNhbGxiYWNrIHN1YmlkIHRvIHN0YXJ0IGF0CiAqLwppbnQKbmV0c25tcF9jYWxsYmFja19jbGVhcl9jbGllbnRfYXJnKHZvaWQgKnB0ciwgaW50IGksIGludCBqKQp7CiAgICBzdHJ1Y3Qgc25tcF9nZW5fY2FsbGJhY2sgKnNjcCA9IE5VTEw7CiAgICBpbnQgcmMgPSAwOwoKICAgIC8qCiAgICAgKiBkb24ndCBpbml0IGkgYW5kIGogYmVmb3JlIGxvb3AsIHNpbmNlIHRoZSBjYWxsZXIgc3BlY2lmaWVkCiAgICAgKiB0aGUgc3RhcnRpbmcgcG9pbnQgZXhwbGljaXRseS4gQnV0ICphZnRlciogdGhlIGkgbG9vcCBoYXMKICAgICAqIGZpbmlzaGVkIGV4ZWN1dGluZyBvbmNlLCBpbml0IGogdG8gMCBmb3IgdGhlIG5leHQgcGFzcwogICAgICogdGhyb3VnaCB0aGUgc3ViaWRzLgogICAgICovCiAgICBmb3IgKDsgaSA8IE1BWF9DQUxMQkFDS19JRFM7IGkrKyxqPTApIHsKICAgICAgICBmb3IgKDsgaiA8IE1BWF9DQUxMQkFDS19TVUJJRFM7IGorKykgewogICAgICAgICAgICBzY3AgPSB0aGVjYWxsYmFja3NbaV1bal07IAogICAgICAgICAgICB3aGlsZSAoc2NwICE9IE5VTEwpIHsKICAgICAgICAgICAgICAgIGlmICgoTlVMTCAhPSBzY3AtPnNjX2NhbGxiYWNrKSAmJgogICAgICAgICAgICAgICAgICAgIChzY3AtPnNjX2NsaWVudF9hcmcgIT0gTlVMTCkgJiYKICAgICAgICAgICAgICAgICAgICAoc2NwLT5zY19jbGllbnRfYXJnID09IHB0cikpIHsKICAgICAgICAgICAgICAgICAgICBERUJVR01TR1RMKCgiOTpjYWxsYmFjayIsICIgIGNsZWFyaW5nICVwIGF0IFslZCwlZF1cbiIsIHB0ciwgaSwgaikpOwogICAgICAgICAgICAgICAgICAgIHNjcC0+c2NfY2xpZW50X2FyZyA9IE5VTEw7CiAgICAgICAgICAgICAgICAgICAgKytyYzsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHNjcCA9IHNjcC0+bmV4dDsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICBpZiAoMCAhPSByYykgewogICAgICAgIERFQlVHTVNHVEwoKCJjYWxsYmFjayIsICJyZW1vdmVkICVkIGNsaWVudCBhcmdzXG4iLCByYykpOwogICAgfQoKICAgIHJldHVybiByYzsKfQoKdm9pZApjbGVhcl9jYWxsYmFjayh2b2lkKQp7CiAgICB1bnNpZ25lZCBpbnQgaSA9IDAsIGogPSAwOwogICAgc3RydWN0IHNubXBfZ2VuX2NhbGxiYWNrICpzY3AgPSBOVUxMOwoKICAgIGlmIChfY2FsbGJhY2tfbmVlZF9pbml0KQogICAgICAgIGluaXRfY2FsbGJhY2tzKCk7CgogICAgREVCVUdNU0dUTCgoImNhbGxiYWNrIiwgImNsZWFyIGNhbGxiYWNrXG4iKSk7CiAgICBmb3IgKGkgPSAwOyBpIDwgTUFYX0NBTExCQUNLX0lEUzsgaSsrKSB7CiAgICAgICAgZm9yIChqID0gMDsgaiA8IE1BWF9DQUxMQkFDS19TVUJJRFM7IGorKykgewogICAgICAgICAgICBfY2FsbGJhY2tfbG9jayhpLGosICJjbGVhcl9jYWxsYmFjayIsIDEpOwogICAgICAgICAgICBzY3AgPSB0aGVjYWxsYmFja3NbaV1bal07CiAgICAgICAgICAgIHdoaWxlIChzY3AgIT0gTlVMTCkgewogICAgICAgICAgICAgICAgdGhlY2FsbGJhY2tzW2ldW2pdID0gc2NwLT5uZXh0OwogICAgICAgICAgICAgICAgLyoKICAgICAgICAgICAgICAgICAqIGlmIHRoZXJlIGlzIGEgY2xpZW50IGFyZywgY2hlY2sgZm9yIGR1cGxpY2F0ZXMKICAgICAgICAgICAgICAgICAqIGFuZCB0aGVuIGZyZWUgaXQuCiAgICAgICAgICAgICAgICAgKi8KICAgICAgICAgICAgICAgIGlmICgoTlVMTCAhPSBzY3AtPnNjX2NhbGxiYWNrKSAmJgogICAgICAgICAgICAgICAgICAgIChzY3AtPnNjX2NsaWVudF9hcmcgIT0gTlVMTCkpIHsKICAgICAgICAgICAgICAgICAgICB2b2lkICp0bXBfYXJnOwogICAgICAgICAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAgICAgICAgICogc2F2ZSB0aGUgY2xpZW50IGFyZywgdGhlbiBzZXQgaXQgdG8gbnVsbCBzbyB0aGF0IGl0CiAgICAgICAgICAgICAgICAgICAgICogd29uJ3QgbG9vayBsaWtlIGEgZHVwbGljYXRlLCB0aGVuIGNoZWNrIGZvciBkdXBsaWNhdGVzCiAgICAgICAgICAgICAgICAgICAgICogc3RhcnRpbmcgYXQgdGhlIGN1cnJlbnQgaSxqIChlYXJsaWVyIGR1cHMgc2hvdWxkIGhhdmUKICAgICAgICAgICAgICAgICAgICAgKiBhbHJlYWR5IGJlZW4gZm91bmQpIGFuZCBmcmVlIHRoZSBwb2ludGVyLgogICAgICAgICAgICAgICAgICAgICAqLwogICAgICAgICAgICAgICAgICAgIHRtcF9hcmcgPSBzY3AtPnNjX2NsaWVudF9hcmc7CiAgICAgICAgICAgICAgICAgICAgc2NwLT5zY19jbGllbnRfYXJnID0gTlVMTDsKICAgICAgICAgICAgICAgICAgICBERUJVR01TR1RMKCgiOTpjYWxsYmFjayIsICIgIGZyZWVpbmcgJXAgYXQgWyVkLCVkXVxuIiwgdG1wX2FyZywgaSwgaikpOwogICAgICAgICAgICAgICAgICAgICh2b2lkKW5ldHNubXBfY2FsbGJhY2tfY2xlYXJfY2xpZW50X2FyZyh0bXBfYXJnLCBpLCBqKTsKICAgICAgICAgICAgICAgICAgICBmcmVlKHRtcF9hcmcpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgU05NUF9GUkVFKHNjcCk7CiAgICAgICAgICAgICAgICBzY3AgPSB0aGVjYWxsYmFja3NbaV1bal07CiAgICAgICAgICAgIH0KICAgICAgICAgICAgX2NhbGxiYWNrX3VubG9jayhpLGopOwogICAgICAgIH0KICAgIH0KfQoKc3RydWN0IHNubXBfZ2VuX2NhbGxiYWNrICoKc25tcF9jYWxsYmFja19saXN0KGludCBtYWpvciwgaW50IG1pbm9yKQp7CiAgICBpZiAoX2NhbGxiYWNrX25lZWRfaW5pdCkKICAgICAgICBpbml0X2NhbGxiYWNrcygpOwoKICAgIHJldHVybiAodGhlY2FsbGJhY2tzW21ham9yXVttaW5vcl0pOwp9Ci8qKiAgQH0gKi8K