LyoKICogU3VuIFJQQyBpcyBhIHByb2R1Y3Qgb2YgU3VuIE1pY3Jvc3lzdGVtcywgSW5jLiBhbmQgaXMgcHJvdmlkZWQgZm9yCiAqIHVucmVzdHJpY3RlZCB1c2UgcHJvdmlkZWQgdGhhdCB0aGlzIGxlZ2VuZCBpcyBpbmNsdWRlZCBvbiBhbGwgdGFwZQogKiBtZWRpYSBhbmQgYXMgYSBwYXJ0IG9mIHRoZSBzb2Z0d2FyZSBwcm9ncmFtIGluIHdob2xlIG9yIHBhcnQuICBVc2VycwogKiBtYXkgY29weSBvciBtb2RpZnkgU3VuIFJQQyB3aXRob3V0IGNoYXJnZSwgYnV0IGFyZSBub3QgYXV0aG9yaXplZAogKiB0byBsaWNlbnNlIG9yIGRpc3RyaWJ1dGUgaXQgdG8gYW55b25lIGVsc2UgZXhjZXB0IGFzIHBhcnQgb2YgYSBwcm9kdWN0IG9yCiAqIHByb2dyYW0gZGV2ZWxvcGVkIGJ5IHRoZSB1c2VyLgogKgogKiBTVU4gUlBDIElTIFBST1ZJREVEIEFTIElTIFdJVEggTk8gV0FSUkFOVElFUyBPRiBBTlkgS0lORCBJTkNMVURJTkcgVEhFCiAqIFdBUlJBTlRJRVMgT0YgREVTSUdOLCBNRVJDSEFOVElCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUgogKiBQVVJQT1NFLCBPUiBBUklTSU5HIEZST00gQSBDT1VSU0UgT0YgREVBTElORywgVVNBR0UgT1IgVFJBREUgUFJBQ1RJQ0UuCiAqCiAqIFN1biBSUEMgaXMgcHJvdmlkZWQgd2l0aCBubyBzdXBwb3J0IGFuZCB3aXRob3V0IGFueSBvYmxpZ2F0aW9uIG9uIHRoZQogKiBwYXJ0IG9mIFN1biBNaWNyb3N5c3RlbXMsIEluYy4gdG8gYXNzaXN0IGluIGl0cyB1c2UsIGNvcnJlY3Rpb24sCiAqIG1vZGlmaWNhdGlvbiBvciBlbmhhbmNlbWVudC4KICoKICogU1VOIE1JQ1JPU1lTVEVNUywgSU5DLiBTSEFMTCBIQVZFIE5PIExJQUJJTElUWSBXSVRIIFJFU1BFQ1QgVE8gVEhFCiAqIElORlJJTkdFTUVOVCBPRiBDT1BZUklHSFRTLCBUUkFERSBTRUNSRVRTIE9SIEFOWSBQQVRFTlRTIEJZIFNVTiBSUEMKICogT1IgQU5ZIFBBUlQgVEhFUkVPRi4KICoKICogSW4gbm8gZXZlbnQgd2lsbCBTdW4gTWljcm9zeXN0ZW1zLCBJbmMuIGJlIGxpYWJsZSBmb3IgYW55IGxvc3QgcmV2ZW51ZQogKiBvciBwcm9maXRzIG9yIG90aGVyIHNwZWNpYWwsIGluZGlyZWN0IGFuZCBjb25zZXF1ZW50aWFsIGRhbWFnZXMsIGV2ZW4gaWYKICogU3VuIGhhcyBiZWVuIGFkdmlzZWQgb2YgdGhlIHBvc3NpYmlsaXR5IG9mIHN1Y2ggZGFtYWdlcy4KICoKICogU3VuIE1pY3Jvc3lzdGVtcywgSW5jLgogKiAyNTUwIEdhcmNpYSBBdmVudWUKICogTW91bnRhaW4gVmlldywgQ2FsaWZvcm5pYSAgOTQwNDMKICovCi8qCiAqIHN2Yy5jLCBTZXJ2ZXItc2lkZSByZW1vdGUgcHJvY2VkdXJlIGNhbGwgaW50ZXJmYWNlLgogKgogKiBUaGVyZSBhcmUgdHdvIHNldHMgb2YgcHJvY2VkdXJlcyBoZXJlLiAgVGhlIHhwcnQgcm91dGluZXMgYXJlCiAqIGZvciBoYW5kbGluZyB0cmFuc3BvcnQgaGFuZGxlcy4gIFRoZSBzdmMgcm91dGluZXMgaGFuZGxlIHRoZQogKiBsaXN0IG9mIHNlcnZpY2Ugcm91dGluZXMuCiAqCiAqIENvcHlyaWdodCAoQykgMTk4NCwgU3VuIE1pY3Jvc3lzdGVtcywgSW5jLgogKi8KCiNpbmNsdWRlIDxlcnJuby5oPgojaW5jbHVkZSA8dW5pc3RkLmg+CiNpbmNsdWRlIDxycGMvcnBjLmg+CiNpbmNsdWRlIDxycGMvc3ZjLmg+CiNpbmNsdWRlIDxycGMvcG1hcF9jbG50Lmg+CiNpbmNsdWRlIDxzeXMvcG9sbC5oPgoKI2lmZGVmIF9SUENfVEhSRUFEX1NBRkVfCiNkZWZpbmUgeHBvcnRzIFJQQ19USFJFQURfVkFSSUFCTEUoc3ZjX3hwb3J0c19zKQojZWxzZQpzdGF0aWMgU1ZDWFBSVCAqKnhwb3J0czsKI2VuZGlmCgojZGVmaW5lIE5VTExfU1ZDICgoc3RydWN0IHN2Y19jYWxsb3V0ICopMCkKI2RlZmluZQlSUUNSRURfU0laRQk0MDAJLyogdGhpcyBzaXplIGlzIGV4Y2Vzc2l2ZSAqLwoKLyogVGhlIHNlcnZpY2VzIGxpc3QKICAgRWFjaCBlbnRyeSByZXByZXNlbnRzIGEgc2V0IG9mIHByb2NlZHVyZXMgKGFuIHJwYyBwcm9ncmFtKS4KICAgVGhlIGRpc3BhdGNoIHJvdXRpbmUgdGFrZXMgcmVxdWVzdCBzdHJ1Y3RzIGFuZCBydW5zIHRoZQogICBhcHByb3ByaWF0ZSBwcm9jZWR1cmUuICovCnN0cnVjdCBzdmNfY2FsbG91dCB7CiAgc3RydWN0IHN2Y19jYWxsb3V0ICpzY19uZXh0OwogIHJwY3Byb2dfdCBzY19wcm9nOwogIHJwY3ZlcnNfdCBzY192ZXJzOwogIHZvaWQgKCpzY19kaXNwYXRjaCkgKHN0cnVjdCBzdmNfcmVxICosIFNWQ1hQUlQgKik7CiAgYm9vbF90IHNjX21hcHBlZDsKfTsKI2lmZGVmIF9SUENfVEhSRUFEX1NBRkVfCiNkZWZpbmUgc3ZjX2hlYWQgUlBDX1RIUkVBRF9WQVJJQUJMRShzdmNfaGVhZF9zKQojZWxzZQpzdGF0aWMgc3RydWN0IHN2Y19jYWxsb3V0ICpzdmNfaGVhZDsKI2VuZGlmCgovKiAqKioqKioqKioqKioqKiogIFNWQ1hQUlQgcmVsYXRlZCBzdHVmZiAqKioqKioqKioqKioqKioqICovCgovKiBBY3RpdmF0ZSBhIHRyYW5zcG9ydCBoYW5kbGUuICovCnZvaWQKeHBydF9yZWdpc3RlciAoU1ZDWFBSVCAqeHBydCkKewogIHJlZ2lzdGVyIGludCBzb2NrID0geHBydC0+eHBfc29jazsKICByZWdpc3RlciBpbnQgaTsKCiAgaWYgKHhwb3J0cyA9PSBOVUxMKQogICAgewogICAgICB4cG9ydHMgPSAoU1ZDWFBSVCAqKikgbWFsbG9jIChfcnBjX2R0YWJsZXNpemUgKCkgKiBzaXplb2YgKFNWQ1hQUlQgKikpOwogICAgICBpZiAoeHBvcnRzID09IE5VTEwpIC8qIERvbrR0IGFkZCBoYW5kbGUgKi8KCXJldHVybjsKICAgIH0KCiAgaWYgKHNvY2sgPCBfcnBjX2R0YWJsZXNpemUgKCkpCiAgICB7CiAgICAgIHN0cnVjdCBwb2xsZmQgKm5ld19zdmNfcG9sbGZkOwoKICAgICAgeHBvcnRzW3NvY2tdID0geHBydDsKICAgICAgaWYgKHNvY2sgPCBGRF9TRVRTSVpFKQoJRkRfU0VUIChzb2NrLCAmc3ZjX2Zkc2V0KTsKCiAgICAgIC8qIENoZWNrIGlmIHdlIGhhdmUgYW4gZW1wdHkgc2xvdCAqLwogICAgICBmb3IgKGkgPSAwOyBpIDwgc3ZjX21heF9wb2xsZmQ7ICsraSkKCWlmIChzdmNfcG9sbGZkW2ldLmZkID09IC0xKQoJICB7CgkgICAgc3ZjX3BvbGxmZFtpXS5mZCA9IHNvY2s7CgkgICAgc3ZjX3BvbGxmZFtpXS5ldmVudHMgPSAoUE9MTElOIHwgUE9MTFBSSSB8CgkJCQkgICAgUE9MTFJETk9STSB8IFBPTExSREJBTkQpOwoJICAgIHJldHVybjsKCSAgfQoKICAgICAgbmV3X3N2Y19wb2xsZmQgPSAoc3RydWN0IHBvbGxmZCAqKSByZWFsbG9jIChzdmNfcG9sbGZkLAoJCQkJCQkgIHNpemVvZiAoc3RydWN0IHBvbGxmZCkKCQkJCQkJICAqIChzdmNfbWF4X3BvbGxmZCArIDEpKTsKICAgICAgaWYgKG5ld19zdmNfcG9sbGZkID09IE5VTEwpIC8qIE91dCBvZiBtZW1vcnkgKi8KCXJldHVybjsKICAgICAgc3ZjX3BvbGxmZCA9IG5ld19zdmNfcG9sbGZkOwogICAgICArK3N2Y19tYXhfcG9sbGZkOwoKICAgICAgc3ZjX3BvbGxmZFtzdmNfbWF4X3BvbGxmZCAtIDFdLmZkID0gc29jazsKICAgICAgc3ZjX3BvbGxmZFtzdmNfbWF4X3BvbGxmZCAtIDFdLmV2ZW50cyA9IChQT0xMSU4gfCBQT0xMUFJJIHwKCQkJCQkgICAgICAgUE9MTFJETk9STSB8IFBPTExSREJBTkQpOwogICAgfQp9CmxpYmNfaGlkZGVuX2RlZiAoeHBydF9yZWdpc3RlcikKCi8qIERlLWFjdGl2YXRlIGEgdHJhbnNwb3J0IGhhbmRsZS4gKi8Kdm9pZAp4cHJ0X3VucmVnaXN0ZXIgKFNWQ1hQUlQgKnhwcnQpCnsKICByZWdpc3RlciBpbnQgc29jayA9IHhwcnQtPnhwX3NvY2s7CiAgcmVnaXN0ZXIgaW50IGk7CgogIGlmICgoc29jayA8IF9ycGNfZHRhYmxlc2l6ZSAoKSkgJiYgKHhwb3J0c1tzb2NrXSA9PSB4cHJ0KSkKICAgIHsKICAgICAgeHBvcnRzW3NvY2tdID0gKFNWQ1hQUlQgKikgMDsKCiAgICAgIGlmIChzb2NrIDwgRkRfU0VUU0laRSkKCUZEX0NMUiAoc29jaywgJnN2Y19mZHNldCk7CgogICAgICBmb3IgKGkgPSAwOyBpIDwgc3ZjX21heF9wb2xsZmQ7ICsraSkKCWlmIChzdmNfcG9sbGZkW2ldLmZkID09IHNvY2spCgkgIHN2Y19wb2xsZmRbaV0uZmQgPSAtMTsKICAgIH0KfQpsaWJjX2hpZGRlbl9kZWYgKHhwcnRfdW5yZWdpc3RlcikKCgovKiAqKioqKioqKioqKioqKioqKioqKioqIENBTExPVVQgbGlzdCByZWxhdGVkIHN0dWZmICoqKioqKioqKioqKiogKi8KCi8qIFNlYXJjaCB0aGUgY2FsbG91dCBsaXN0IGZvciBhIHByb2dyYW0gbnVtYmVyLCByZXR1cm4gdGhlIGNhbGxvdXQKICAgc3RydWN0LiAqLwpzdGF0aWMgc3RydWN0IHN2Y19jYWxsb3V0ICoKc3ZjX2ZpbmQgKHJwY3Byb2dfdCBwcm9nLCBycGN2ZXJzX3QgdmVycywgc3RydWN0IHN2Y19jYWxsb3V0ICoqcHJldikKewogIHJlZ2lzdGVyIHN0cnVjdCBzdmNfY2FsbG91dCAqcywgKnA7CgogIHAgPSBOVUxMX1NWQzsKICBmb3IgKHMgPSBzdmNfaGVhZDsgcyAhPSBOVUxMX1NWQzsgcyA9IHMtPnNjX25leHQpCiAgICB7CiAgICAgIGlmICgocy0+c2NfcHJvZyA9PSBwcm9nKSAmJiAocy0+c2NfdmVycyA9PSB2ZXJzKSkKCWdvdG8gZG9uZTsKICAgICAgcCA9IHM7CiAgICB9CmRvbmU6CiAgKnByZXYgPSBwOwogIHJldHVybiBzOwp9CgoKc3RhdGljIGJvb2xfdApzdmNfaXNfbWFwcGVkIChycGNwcm9nX3QgcHJvZywgcnBjdmVyc190IHZlcnMpCnsKICBzdHJ1Y3Qgc3ZjX2NhbGxvdXQgKnByZXY7CiAgcmVnaXN0ZXIgc3RydWN0IHN2Y19jYWxsb3V0ICpzOwogIHMgPSBzdmNfZmluZCAocHJvZywgdmVycywgJnByZXYpOwogIHJldHVybiBzIT0gTlVMTF9TVkMgJiYgcy0+c2NfbWFwcGVkOwp9CgoKLyogQWRkIGEgc2VydmljZSBwcm9ncmFtIHRvIHRoZSBjYWxsb3V0IGxpc3QuCiAgIFRoZSBkaXNwYXRjaCByb3V0aW5lIHdpbGwgYmUgY2FsbGVkIHdoZW4gYSBycGMgcmVxdWVzdCBmb3IgdGhpcwogICBwcm9ncmFtIG51bWJlciBjb21lcyBpbi4gKi8KYm9vbF90CnN2Y19yZWdpc3RlciAoU1ZDWFBSVCAqIHhwcnQsIHJwY3Byb2dfdCBwcm9nLCBycGN2ZXJzX3QgdmVycywKCSAgICAgIHZvaWQgKCpkaXNwYXRjaCkgKHN0cnVjdCBzdmNfcmVxICosIFNWQ1hQUlQgKiksCgkgICAgICBycGNwcm9jX3QgcHJvdG9jb2wpCnsKICBzdHJ1Y3Qgc3ZjX2NhbGxvdXQgKnByZXY7CiAgcmVnaXN0ZXIgc3RydWN0IHN2Y19jYWxsb3V0ICpzOwoKICBpZiAoKHMgPSBzdmNfZmluZCAocHJvZywgdmVycywgJnByZXYpKSAhPSBOVUxMX1NWQykKICAgIHsKICAgICAgaWYgKHMtPnNjX2Rpc3BhdGNoID09IGRpc3BhdGNoKQoJZ290byBwbWFwX2l0OwkJLyogaGUgaXMgcmVnaXN0ZXJpbmcgYW5vdGhlciB4cHRyICovCiAgICAgIHJldHVybiBGQUxTRTsKICAgIH0KICBzID0gKHN0cnVjdCBzdmNfY2FsbG91dCAqKSBtZW1fYWxsb2MgKHNpemVvZiAoc3RydWN0IHN2Y19jYWxsb3V0KSk7CiAgaWYgKHMgPT0gKHN0cnVjdCBzdmNfY2FsbG91dCAqKSAwKQogICAgcmV0dXJuIEZBTFNFOwoKICBzLT5zY19wcm9nID0gcHJvZzsKICBzLT5zY192ZXJzID0gdmVyczsKICBzLT5zY19kaXNwYXRjaCA9IGRpc3BhdGNoOwogIHMtPnNjX25leHQgPSBzdmNfaGVhZDsKICBzLT5zY19tYXBwZWQgPSBGQUxTRTsKICBzdmNfaGVhZCA9IHM7CgpwbWFwX2l0OgogIC8qIG5vdyByZWdpc3RlciB0aGUgaW5mb3JtYXRpb24gd2l0aCB0aGUgbG9jYWwgYmluZGVyIHNlcnZpY2UgKi8KICBpZiAocHJvdG9jb2wpCiAgICB7CiAgICAgIGlmICghIHBtYXBfc2V0IChwcm9nLCB2ZXJzLCBwcm90b2NvbCwgeHBydC0+eHBfcG9ydCkpCglyZXR1cm4gRkFMU0U7CgogICAgICBzLT5zY19tYXBwZWQgPSBUUlVFOwogICAgfQoKICByZXR1cm4gVFJVRTsKfQpsaWJjX2hpZGRlbl9kZWYgKHN2Y19yZWdpc3RlcikKCi8qIFJlbW92ZSBhIHNlcnZpY2UgcHJvZ3JhbSBmcm9tIHRoZSBjYWxsb3V0IGxpc3QuICovCnZvaWQKc3ZjX3VucmVnaXN0ZXIgKHJwY3Byb2dfdCBwcm9nLCBycGN2ZXJzX3QgdmVycykKewogIHN0cnVjdCBzdmNfY2FsbG91dCAqcHJldjsKICByZWdpc3RlciBzdHJ1Y3Qgc3ZjX2NhbGxvdXQgKnM7CgogIGlmICgocyA9IHN2Y19maW5kIChwcm9nLCB2ZXJzLCAmcHJldikpID09IE5VTExfU1ZDKQogICAgcmV0dXJuOwoKICBpZiAocHJldiA9PSBOVUxMX1NWQykKICAgIHN2Y19oZWFkID0gcy0+c2NfbmV4dDsKICBlbHNlCiAgICBwcmV2LT5zY19uZXh0ID0gcy0+c2NfbmV4dDsKCiAgcy0+c2NfbmV4dCA9IE5VTExfU1ZDOwogIG1lbV9mcmVlICgoY2hhciAqKSBzLCAodV9pbnQpIHNpemVvZiAoc3RydWN0IHN2Y19jYWxsb3V0KSk7CiAgLyogbm93IHVucmVnaXN0ZXIgdGhlIGluZm9ybWF0aW9uIHdpdGggdGhlIGxvY2FsIGJpbmRlciBzZXJ2aWNlICovCiAgaWYgKCEgc3ZjX2lzX21hcHBlZCAocHJvZywgdmVycykpCiAgICBwbWFwX3Vuc2V0IChwcm9nLCB2ZXJzKTsKfQpsaWJjX2hpZGRlbl9kZWYgKHN2Y191bnJlZ2lzdGVyKQoKLyogKioqKioqKioqKioqKioqKioqKiBSRVBMWSBHRU5FUkFUSU9OIFJPVVRJTkVTICAqKioqKioqKioqKiogKi8KCi8qIFNlbmQgYSByZXBseSB0byBhbiBycGMgcmVxdWVzdCAqLwpib29sX3QKc3ZjX3NlbmRyZXBseSAocmVnaXN0ZXIgU1ZDWFBSVCAqeHBydCwgeGRycHJvY190IHhkcl9yZXN1bHRzLAoJICAgICAgIGNhZGRyX3QgeGRyX2xvY2F0aW9uKQp7CiAgc3RydWN0IHJwY19tc2cgcnBseTsKCiAgcnBseS5ybV9kaXJlY3Rpb24gPSBSRVBMWTsKICBycGx5LnJtX3JlcGx5LnJwX3N0YXQgPSBNU0dfQUNDRVBURUQ7CiAgcnBseS5hY3B0ZWRfcnBseS5hcl92ZXJmID0geHBydC0+eHBfdmVyZjsKICBycGx5LmFjcHRlZF9ycGx5LmFyX3N0YXQgPSBTVUNDRVNTOwogIHJwbHkuYWNwdGVkX3JwbHkuYXJfcmVzdWx0cy53aGVyZSA9IHhkcl9sb2NhdGlvbjsKICBycGx5LmFjcHRlZF9ycGx5LmFyX3Jlc3VsdHMucHJvYyA9IHhkcl9yZXN1bHRzOwogIHJldHVybiBTVkNfUkVQTFkgKHhwcnQsICZycGx5KTsKfQpJTlRERUYgKHN2Y19zZW5kcmVwbHkpCgovKiBObyBwcm9jZWR1cmUgZXJyb3IgcmVwbHkgKi8Kdm9pZApzdmNlcnJfbm9wcm9jIChyZWdpc3RlciBTVkNYUFJUICp4cHJ0KQp7CiAgc3RydWN0IHJwY19tc2cgcnBseTsKCiAgcnBseS5ybV9kaXJlY3Rpb24gPSBSRVBMWTsKICBycGx5LnJtX3JlcGx5LnJwX3N0YXQgPSBNU0dfQUNDRVBURUQ7CiAgcnBseS5hY3B0ZWRfcnBseS5hcl92ZXJmID0geHBydC0+eHBfdmVyZjsKICBycGx5LmFjcHRlZF9ycGx5LmFyX3N0YXQgPSBQUk9DX1VOQVZBSUw7CiAgU1ZDX1JFUExZICh4cHJ0LCAmcnBseSk7Cn0KCi8qIENhbid0IGRlY29kZSBhcmdzIGVycm9yIHJlcGx5ICovCnZvaWQKc3ZjZXJyX2RlY29kZSAocmVnaXN0ZXIgU1ZDWFBSVCAqeHBydCkKewogIHN0cnVjdCBycGNfbXNnIHJwbHk7CgogIHJwbHkucm1fZGlyZWN0aW9uID0gUkVQTFk7CiAgcnBseS5ybV9yZXBseS5ycF9zdGF0ID0gTVNHX0FDQ0VQVEVEOwogIHJwbHkuYWNwdGVkX3JwbHkuYXJfdmVyZiA9IHhwcnQtPnhwX3ZlcmY7CiAgcnBseS5hY3B0ZWRfcnBseS5hcl9zdGF0ID0gR0FSQkFHRV9BUkdTOwogIFNWQ19SRVBMWSAoeHBydCwgJnJwbHkpOwp9CklOVERFRiAoc3ZjZXJyX2RlY29kZSkKCi8qIFNvbWUgc3lzdGVtIGVycm9yICovCnZvaWQKc3ZjZXJyX3N5c3RlbWVyciAocmVnaXN0ZXIgU1ZDWFBSVCAqeHBydCkKewogIHN0cnVjdCBycGNfbXNnIHJwbHk7CgogIHJwbHkucm1fZGlyZWN0aW9uID0gUkVQTFk7CiAgcnBseS5ybV9yZXBseS5ycF9zdGF0ID0gTVNHX0FDQ0VQVEVEOwogIHJwbHkuYWNwdGVkX3JwbHkuYXJfdmVyZiA9IHhwcnQtPnhwX3ZlcmY7CiAgcnBseS5hY3B0ZWRfcnBseS5hcl9zdGF0ID0gU1lTVEVNX0VSUjsKICBTVkNfUkVQTFkgKHhwcnQsICZycGx5KTsKfQoKLyogQXV0aGVudGljYXRpb24gZXJyb3IgcmVwbHkgKi8Kdm9pZApzdmNlcnJfYXV0aCAoU1ZDWFBSVCAqeHBydCwgZW51bSBhdXRoX3N0YXQgd2h5KQp7CiAgc3RydWN0IHJwY19tc2cgcnBseTsKCiAgcnBseS5ybV9kaXJlY3Rpb24gPSBSRVBMWTsKICBycGx5LnJtX3JlcGx5LnJwX3N0YXQgPSBNU0dfREVOSUVEOwogIHJwbHkucmpjdGVkX3JwbHkucmpfc3RhdCA9IEFVVEhfRVJST1I7CiAgcnBseS5yamN0ZWRfcnBseS5yal93aHkgPSB3aHk7CiAgU1ZDX1JFUExZICh4cHJ0LCAmcnBseSk7Cn0KbGliY19oaWRkZW5fZGVmIChzdmNlcnJfYXV0aCkKCi8qIEF1dGggdG9vIHdlYWsgZXJyb3IgcmVwbHkgKi8Kdm9pZApzdmNlcnJfd2Vha2F1dGggKFNWQ1hQUlQgKnhwcnQpCnsKICBzdmNlcnJfYXV0aCAoeHBydCwgQVVUSF9UT09XRUFLKTsKfQoKLyogUHJvZ3JhbSB1bmF2YWlsYWJsZSBlcnJvciByZXBseSAqLwp2b2lkCnN2Y2Vycl9ub3Byb2cgKHJlZ2lzdGVyIFNWQ1hQUlQgKnhwcnQpCnsKICBzdHJ1Y3QgcnBjX21zZyBycGx5OwoKICBycGx5LnJtX2RpcmVjdGlvbiA9IFJFUExZOwogIHJwbHkucm1fcmVwbHkucnBfc3RhdCA9IE1TR19BQ0NFUFRFRDsKICBycGx5LmFjcHRlZF9ycGx5LmFyX3ZlcmYgPSB4cHJ0LT54cF92ZXJmOwogIHJwbHkuYWNwdGVkX3JwbHkuYXJfc3RhdCA9IFBST0dfVU5BVkFJTDsKICBTVkNfUkVQTFkgKHhwcnQsICZycGx5KTsKfQpsaWJjX2hpZGRlbl9kZWYgKHN2Y2Vycl9ub3Byb2cpCgovKiBQcm9ncmFtIHZlcnNpb24gbWlzbWF0Y2ggZXJyb3IgcmVwbHkgKi8Kdm9pZApzdmNlcnJfcHJvZ3ZlcnMgKHJlZ2lzdGVyIFNWQ1hQUlQgKnhwcnQsIHJwY3ZlcnNfdCBsb3dfdmVycywKCQkgcnBjdmVyc190IGhpZ2hfdmVycykKewogIHN0cnVjdCBycGNfbXNnIHJwbHk7CgogIHJwbHkucm1fZGlyZWN0aW9uID0gUkVQTFk7CiAgcnBseS5ybV9yZXBseS5ycF9zdGF0ID0gTVNHX0FDQ0VQVEVEOwogIHJwbHkuYWNwdGVkX3JwbHkuYXJfdmVyZiA9IHhwcnQtPnhwX3ZlcmY7CiAgcnBseS5hY3B0ZWRfcnBseS5hcl9zdGF0ID0gUFJPR19NSVNNQVRDSDsKICBycGx5LmFjcHRlZF9ycGx5LmFyX3ZlcnMubG93ID0gbG93X3ZlcnM7CiAgcnBseS5hY3B0ZWRfcnBseS5hcl92ZXJzLmhpZ2ggPSBoaWdoX3ZlcnM7CiAgU1ZDX1JFUExZICh4cHJ0LCAmcnBseSk7Cn0KbGliY19oaWRkZW5fZGVmIChzdmNlcnJfcHJvZ3ZlcnMpCgovKiAqKioqKioqKioqKioqKioqKioqIFNFUlZFUiBJTlBVVCBTVFVGRiAqKioqKioqKioqKioqKioqKioqICovCgovKgogKiBHZXQgc2VydmVyIHNpZGUgaW5wdXQgZnJvbSBzb21lIHRyYW5zcG9ydC4KICoKICogU3RhdGVtZW50IG9mIGF1dGhlbnRpY2F0aW9uIHBhcmFtZXRlcnMgbWFuYWdlbWVudDoKICogVGhpcyBmdW5jdGlvbiBvd25zIGFuZCBtYW5hZ2VzIGFsbCBhdXRoZW50aWNhdGlvbiBwYXJhbWV0ZXJzLCBzcGVjaWZpY2FsbHkKICogdGhlICJyYXciIHBhcmFtZXRlcnMgKG1zZy5ybV9jYWxsLmNiX2NyZWQgYW5kIG1zZy5ybV9jYWxsLmNiX3ZlcmYpIGFuZAogKiB0aGUgImNvb2tlZCIgY3JlZGVudGlhbHMgKHJxc3QtPnJxX2NsbnRjcmVkKS4KICogSG93ZXZlciwgdGhpcyBmdW5jdGlvbiBkb2VzIG5vdCBrbm93IHRoZSBzdHJ1Y3R1cmUgb2YgdGhlIGNvb2tlZAogKiBjcmVkZW50aWFscywgc28gaXQgbWFrZSB0aGUgZm9sbG93aW5nIGFzc3VtcHRpb25zOgogKiAgIGEpIHRoZSBzdHJ1Y3R1cmUgaXMgY29udGlndW91cyAobm8gcG9pbnRlcnMpLCBhbmQKICogICBiKSB0aGUgY3JlZCBzdHJ1Y3R1cmUgc2l6ZSBkb2VzIG5vdCBleGNlZWQgUlFDUkVEX1NJWkUgYnl0ZXMuCiAqIEluIGFsbCBldmVudHMsIGFsbCB0aHJlZSBwYXJhbWV0ZXJzIGFyZSBmcmVlZCB1cG9uIGV4aXQgZnJvbSB0aGlzIHJvdXRpbmUuCiAqIFRoZSBzdG9yYWdlIGlzIHRyaXZpYWxseSBtYW5hZ2VtZW50IG9uIHRoZSBjYWxsIHN0YWNrIGluIHVzZXIgbGFuZCwgYnV0CiAqIGlzIG1hbGxvY2F0ZWQgaW4ga2VybmVsIGxhbmQuCiAqLwoKdm9pZApzdmNfZ2V0cmVxIChpbnQgcmRmZHMpCnsKICBmZF9zZXQgcmVhZGZkczsKCiAgRkRfWkVSTyAoJnJlYWRmZHMpOwogIHJlYWRmZHMuZmRzX2JpdHNbMF0gPSByZGZkczsKICBJTlRVU0Uoc3ZjX2dldHJlcXNldCkgKCZyZWFkZmRzKTsKfQpJTlRERUYgKHN2Y19nZXRyZXEpCgp2b2lkCnN2Y19nZXRyZXFzZXQgKGZkX3NldCAqcmVhZGZkcykKewogIHJlZ2lzdGVyIGZkX21hc2sgbWFzazsKICByZWdpc3RlciBmZF9tYXNrICptYXNrcDsKICByZWdpc3RlciBpbnQgc2V0c2l6ZTsKICByZWdpc3RlciBpbnQgc29jazsKICByZWdpc3RlciBpbnQgYml0OwoKICBzZXRzaXplID0gX3JwY19kdGFibGVzaXplICgpOwogIGlmIChzZXRzaXplID4gRkRfU0VUU0laRSkKICAgIHNldHNpemUgPSBGRF9TRVRTSVpFOwogIG1hc2twID0gcmVhZGZkcy0+ZmRzX2JpdHM7CiAgZm9yIChzb2NrID0gMDsgc29jayA8IHNldHNpemU7IHNvY2sgKz0gTkZEQklUUykKICAgIGZvciAobWFzayA9ICptYXNrcCsrOyAoYml0ID0gZmZzbCAobWFzaykpOyBtYXNrIF49ICgxTCA8PCAoYml0IC0gMSkpKQogICAgICBJTlRVU0Uoc3ZjX2dldHJlcV9jb21tb24pIChzb2NrICsgYml0IC0gMSk7Cn0KSU5UREVGIChzdmNfZ2V0cmVxc2V0KQoKdm9pZApzdmNfZ2V0cmVxX3BvbGwgKHN0cnVjdCBwb2xsZmQgKnBmZHAsIGludCBwb2xscmV0dmFsKQp7CiAgaWYgKHBvbGxyZXR2YWwgPT0gMCkKICAgIHJldHVybjsKCiAgcmVnaXN0ZXIgaW50IGZkc19mb3VuZDsKICBmb3IgKGludCBpID0gZmRzX2ZvdW5kID0gMDsgaSA8IHN2Y19tYXhfcG9sbGZkOyArK2kpCiAgICB7CiAgICAgIHJlZ2lzdGVyIHN0cnVjdCBwb2xsZmQgKnAgPSAmcGZkcFtpXTsKCiAgICAgIGlmIChwLT5mZCAhPSAtMSAmJiBwLT5yZXZlbnRzKQoJewoJICAvKiBmZCBoYXMgaW5wdXQgd2FpdGluZyAqLwoJICBpZiAocC0+cmV2ZW50cyAmIFBPTExOVkFMKQoJICAgIHhwcnRfdW5yZWdpc3RlciAoeHBvcnRzW3AtPmZkXSk7CgkgIGVsc2UKCSAgICBJTlRVU0Uoc3ZjX2dldHJlcV9jb21tb24pIChwLT5mZCk7CgoJICBpZiAoKytmZHNfZm91bmQgPj0gcG9sbHJldHZhbCkKCSAgICBicmVhazsKCX0KICAgIH0KfQpJTlRERUYgKHN2Y19nZXRyZXFfcG9sbCkKCgp2b2lkCnN2Y19nZXRyZXFfY29tbW9uIChjb25zdCBpbnQgZmQpCnsKICBlbnVtIHhwcnRfc3RhdCBzdGF0OwogIHN0cnVjdCBycGNfbXNnIG1zZzsKICByZWdpc3RlciBTVkNYUFJUICp4cHJ0OwogIGNoYXIgY3JlZF9hcmVhWzIgKiBNQVhfQVVUSF9CWVRFUyArIFJRQ1JFRF9TSVpFXTsKICBtc2cucm1fY2FsbC5jYl9jcmVkLm9hX2Jhc2UgPSBjcmVkX2FyZWE7CiAgbXNnLnJtX2NhbGwuY2JfdmVyZi5vYV9iYXNlID0gJihjcmVkX2FyZWFbTUFYX0FVVEhfQllURVNdKTsKCiAgeHBydCA9IHhwb3J0c1tmZF07CiAgLyogRG8gd2UgY29udHJvbCBmZD8gKi8KICBpZiAoeHBydCA9PSBOVUxMKQogICAgIHJldHVybjsKCiAgLyogbm93IHJlY2VpdmUgbXNncyBmcm9tIHhwcnRwcnQgKHN1cHBvcnQgYmF0Y2ggY2FsbHMpICovCiAgZG8KICAgIHsKICAgICAgaWYgKFNWQ19SRUNWICh4cHJ0LCAmbXNnKSkKCXsKCSAgLyogbm93IGZpbmQgdGhlIGV4cG9ydGVkIHByb2dyYW0gYW5kIGNhbGwgaXQgKi8KCSAgc3RydWN0IHN2Y19jYWxsb3V0ICpzOwoJICBzdHJ1Y3Qgc3ZjX3JlcSByOwoJICBlbnVtIGF1dGhfc3RhdCB3aHk7CgkgIHJwY3ZlcnNfdCBsb3dfdmVyczsKCSAgcnBjdmVyc190IGhpZ2hfdmVyczsKCSAgaW50IHByb2dfZm91bmQ7CgoJICByLnJxX2NsbnRjcmVkID0gJihjcmVkX2FyZWFbMiAqIE1BWF9BVVRIX0JZVEVTXSk7CgkgIHIucnFfeHBydCA9IHhwcnQ7CgkgIHIucnFfcHJvZyA9IG1zZy5ybV9jYWxsLmNiX3Byb2c7CgkgIHIucnFfdmVycyA9IG1zZy5ybV9jYWxsLmNiX3ZlcnM7CgkgIHIucnFfcHJvYyA9IG1zZy5ybV9jYWxsLmNiX3Byb2M7CgkgIHIucnFfY3JlZCA9IG1zZy5ybV9jYWxsLmNiX2NyZWQ7CgoJICAvKiBmaXJzdCBhdXRoZW50aWNhdGUgdGhlIG1lc3NhZ2UgKi8KCSAgLyogQ2hlY2sgZm9yIG51bGwgZmxhdm9yIGFuZCBieXBhc3MgdGhlc2UgY2FsbHMgaWYgcG9zc2libGUgKi8KCgkgIGlmIChtc2cucm1fY2FsbC5jYl9jcmVkLm9hX2ZsYXZvciA9PSBBVVRIX05VTEwpCgkgICAgewoJICAgICAgci5ycV94cHJ0LT54cF92ZXJmLm9hX2ZsYXZvciA9IF9udWxsX2F1dGgub2FfZmxhdm9yOwoJICAgICAgci5ycV94cHJ0LT54cF92ZXJmLm9hX2xlbmd0aCA9IDA7CgkgICAgfQoJICBlbHNlIGlmICgod2h5ID0gSU5UVVNFKF9hdXRoZW50aWNhdGUpICgmciwgJm1zZykpICE9IEFVVEhfT0spCgkgICAgewoJICAgICAgc3ZjZXJyX2F1dGggKHhwcnQsIHdoeSk7CgkgICAgICBnb3RvIGNhbGxfZG9uZTsKCSAgICB9CgoJICAvKiBub3cgbWF0Y2ggbWVzc2FnZSB3aXRoIGEgcmVnaXN0ZXJlZCBzZXJ2aWNlICovCgkgIHByb2dfZm91bmQgPSBGQUxTRTsKCSAgbG93X3ZlcnMgPSAwIC0gMTsKCSAgaGlnaF92ZXJzID0gMDsKCgkgIGZvciAocyA9IHN2Y19oZWFkOyBzICE9IE5VTExfU1ZDOyBzID0gcy0+c2NfbmV4dCkKCSAgICB7CgkgICAgICBpZiAocy0+c2NfcHJvZyA9PSByLnJxX3Byb2cpCgkJewoJCSAgaWYgKHMtPnNjX3ZlcnMgPT0gci5ycV92ZXJzKQoJCSAgICB7CgkJICAgICAgKCpzLT5zY19kaXNwYXRjaCkgKCZyLCB4cHJ0KTsKCQkgICAgICBnb3RvIGNhbGxfZG9uZTsKCQkgICAgfQoJCSAgLyogZm91bmQgY29ycmVjdCB2ZXJzaW9uICovCgkJICBwcm9nX2ZvdW5kID0gVFJVRTsKCQkgIGlmIChzLT5zY192ZXJzIDwgbG93X3ZlcnMpCgkJICAgIGxvd192ZXJzID0gcy0+c2NfdmVyczsKCQkgIGlmIChzLT5zY192ZXJzID4gaGlnaF92ZXJzKQoJCSAgICBoaWdoX3ZlcnMgPSBzLT5zY192ZXJzOwoJCX0KCSAgICAgIC8qIGZvdW5kIGNvcnJlY3QgcHJvZ3JhbSAqLwoJICAgIH0KCSAgLyogaWYgd2UgZ290IGhlcmUsIHRoZSBwcm9ncmFtIG9yIHZlcnNpb24KCSAgICAgaXMgbm90IHNlcnZlZCAuLi4gKi8KCSAgaWYgKHByb2dfZm91bmQpCgkgICAgc3ZjZXJyX3Byb2d2ZXJzICh4cHJ0LCBsb3dfdmVycywgaGlnaF92ZXJzKTsKCSAgZWxzZQoJICAgIHN2Y2Vycl9ub3Byb2cgKHhwcnQpOwoJICAvKiBGYWxsIHRocm91Z2ggdG8gLi4uICovCgl9CiAgICBjYWxsX2RvbmU6CiAgICAgIGlmICgoc3RhdCA9IFNWQ19TVEFUICh4cHJ0KSkgPT0gWFBSVF9ESUVEKQoJewoJICBTVkNfREVTVFJPWSAoeHBydCk7CgkgIGJyZWFrOwoJfQogICAgfQogIHdoaWxlIChzdGF0ID09IFhQUlRfTU9SRVJFUVMpOwp9CklOVERFRiAoc3ZjX2dldHJlcV9jb21tb24pCgojaWZkZWYgX1JQQ19USFJFQURfU0FGRV8KCnZvaWQKX19ycGNfdGhyZWFkX3N2Y19jbGVhbnVwICh2b2lkKQp7CiAgc3RydWN0IHN2Y19jYWxsb3V0ICpzdmNwOwoKICB3aGlsZSAoKHN2Y3AgPSBzdmNfaGVhZCkgIT0gTlVMTCkKICAgIHN2Y191bnJlZ2lzdGVyIChzdmNwLT5zY19wcm9nLCBzdmNwLT5zY192ZXJzKTsKfQoKI2VuZGlmIC8qIF9SUENfVEhSRUFEX1NBRkVfICovCg==