LyoKICogc3ZjLmMsIFNlcnZlci1zaWRlIHJlbW90ZSBwcm9jZWR1cmUgY2FsbCBpbnRlcmZhY2UuCiAqCiAqIFRoZXJlIGFyZSB0d28gc2V0cyBvZiBwcm9jZWR1cmVzIGhlcmUuICBUaGUgeHBydCByb3V0aW5lcyBhcmUKICogZm9yIGhhbmRsaW5nIHRyYW5zcG9ydCBoYW5kbGVzLiAgVGhlIHN2YyByb3V0aW5lcyBoYW5kbGUgdGhlCiAqIGxpc3Qgb2Ygc2VydmljZSByb3V0aW5lcy4KICoKICogQ29weXJpZ2h0IChjKSAyMDEwLCBPcmFjbGUgQW1lcmljYSwgSW5jLgogKgogKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQogKiBtZXQ6CiAqCiAqICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CiAqICAgICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KICogICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQogKiAgICAgICBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZwogKiAgICAgICBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMKICogICAgICAgcHJvdmlkZWQgd2l0aCB0aGUgZGlzdHJpYnV0aW9uLgogKiAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSAiT3JhY2xlIEFtZXJpY2EsIEluYy4iIG5vciB0aGUgbmFtZXMgb2YgaXRzCiAqICAgICAgIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZAogKiAgICAgICBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCiAqCiAqICAgVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUwogKiAgICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCiAqICAgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MKICogICBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRQogKiAgIENPUFlSSUdIVCBIT0xERVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwKICogICBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMCiAqICAgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUKICogICBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTCiAqICAgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksCiAqICAgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HCiAqICAgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQogKiAgIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCiAqLwoKI2luY2x1ZGUgPGVycm5vLmg+CiNpbmNsdWRlIDx1bmlzdGQuaD4KI2luY2x1ZGUgPHJwYy9ycGMuaD4KI2luY2x1ZGUgPHJwYy9zdmMuaD4KI2luY2x1ZGUgPHJwYy9wbWFwX2NsbnQuaD4KI2luY2x1ZGUgPHN5cy9wb2xsLmg+CgojaWZkZWYgX1JQQ19USFJFQURfU0FGRV8KI2RlZmluZSB4cG9ydHMgUlBDX1RIUkVBRF9WQVJJQUJMRShzdmNfeHBvcnRzX3MpCiNlbHNlCnN0YXRpYyBTVkNYUFJUICoqeHBvcnRzOwojZW5kaWYKCiNkZWZpbmUgTlVMTF9TVkMgKChzdHJ1Y3Qgc3ZjX2NhbGxvdXQgKikwKQojZGVmaW5lCVJRQ1JFRF9TSVpFCTQwMAkvKiB0aGlzIHNpemUgaXMgZXhjZXNzaXZlICovCgovKiBUaGUgc2VydmljZXMgbGlzdAogICBFYWNoIGVudHJ5IHJlcHJlc2VudHMgYSBzZXQgb2YgcHJvY2VkdXJlcyAoYW4gcnBjIHByb2dyYW0pLgogICBUaGUgZGlzcGF0Y2ggcm91dGluZSB0YWtlcyByZXF1ZXN0IHN0cnVjdHMgYW5kIHJ1bnMgdGhlCiAgIGFwcHJvcHJpYXRlIHByb2NlZHVyZS4gKi8Kc3RydWN0IHN2Y19jYWxsb3V0IHsKICBzdHJ1Y3Qgc3ZjX2NhbGxvdXQgKnNjX25leHQ7CiAgcnBjcHJvZ190IHNjX3Byb2c7CiAgcnBjdmVyc190IHNjX3ZlcnM7CiAgdm9pZCAoKnNjX2Rpc3BhdGNoKSAoc3RydWN0IHN2Y19yZXEgKiwgU1ZDWFBSVCAqKTsKICBib29sX3Qgc2NfbWFwcGVkOwp9OwojaWZkZWYgX1JQQ19USFJFQURfU0FGRV8KI2RlZmluZSBzdmNfaGVhZCBSUENfVEhSRUFEX1ZBUklBQkxFKHN2Y19oZWFkX3MpCiNlbHNlCnN0YXRpYyBzdHJ1Y3Qgc3ZjX2NhbGxvdXQgKnN2Y19oZWFkOwojZW5kaWYKCi8qICoqKioqKioqKioqKioqKiAgU1ZDWFBSVCByZWxhdGVkIHN0dWZmICoqKioqKioqKioqKioqKiogKi8KCi8qIEFjdGl2YXRlIGEgdHJhbnNwb3J0IGhhbmRsZS4gKi8Kdm9pZAp4cHJ0X3JlZ2lzdGVyIChTVkNYUFJUICp4cHJ0KQp7CiAgcmVnaXN0ZXIgaW50IHNvY2sgPSB4cHJ0LT54cF9zb2NrOwogIHJlZ2lzdGVyIGludCBpOwoKICBpZiAoeHBvcnRzID09IE5VTEwpCiAgICB7CiAgICAgIHhwb3J0cyA9IChTVkNYUFJUICoqKSBtYWxsb2MgKF9ycGNfZHRhYmxlc2l6ZSAoKSAqIHNpemVvZiAoU1ZDWFBSVCAqKSk7CiAgICAgIGlmICh4cG9ydHMgPT0gTlVMTCkgLyogRG9utHQgYWRkIGhhbmRsZSAqLwoJcmV0dXJuOwogICAgfQoKICBpZiAoc29jayA8IF9ycGNfZHRhYmxlc2l6ZSAoKSkKICAgIHsKICAgICAgc3RydWN0IHBvbGxmZCAqbmV3X3N2Y19wb2xsZmQ7CgogICAgICB4cG9ydHNbc29ja10gPSB4cHJ0OwogICAgICBpZiAoc29jayA8IEZEX1NFVFNJWkUpCglGRF9TRVQgKHNvY2ssICZzdmNfZmRzZXQpOwoKICAgICAgLyogQ2hlY2sgaWYgd2UgaGF2ZSBhbiBlbXB0eSBzbG90ICovCiAgICAgIGZvciAoaSA9IDA7IGkgPCBzdmNfbWF4X3BvbGxmZDsgKytpKQoJaWYgKHN2Y19wb2xsZmRbaV0uZmQgPT0gLTEpCgkgIHsKCSAgICBzdmNfcG9sbGZkW2ldLmZkID0gc29jazsKCSAgICBzdmNfcG9sbGZkW2ldLmV2ZW50cyA9IChQT0xMSU4gfCBQT0xMUFJJIHwKCQkJCSAgICBQT0xMUkROT1JNIHwgUE9MTFJEQkFORCk7CgkgICAgcmV0dXJuOwoJICB9CgogICAgICBuZXdfc3ZjX3BvbGxmZCA9IChzdHJ1Y3QgcG9sbGZkICopIHJlYWxsb2MgKHN2Y19wb2xsZmQsCgkJCQkJCSAgc2l6ZW9mIChzdHJ1Y3QgcG9sbGZkKQoJCQkJCQkgICogKHN2Y19tYXhfcG9sbGZkICsgMSkpOwogICAgICBpZiAobmV3X3N2Y19wb2xsZmQgPT0gTlVMTCkgLyogT3V0IG9mIG1lbW9yeSAqLwoJcmV0dXJuOwogICAgICBzdmNfcG9sbGZkID0gbmV3X3N2Y19wb2xsZmQ7CiAgICAgICsrc3ZjX21heF9wb2xsZmQ7CgogICAgICBzdmNfcG9sbGZkW3N2Y19tYXhfcG9sbGZkIC0gMV0uZmQgPSBzb2NrOwogICAgICBzdmNfcG9sbGZkW3N2Y19tYXhfcG9sbGZkIC0gMV0uZXZlbnRzID0gKFBPTExJTiB8IFBPTExQUkkgfAoJCQkJCSAgICAgICBQT0xMUkROT1JNIHwgUE9MTFJEQkFORCk7CiAgICB9Cn0KbGliY19oaWRkZW5fZGVmICh4cHJ0X3JlZ2lzdGVyKQoKLyogRGUtYWN0aXZhdGUgYSB0cmFuc3BvcnQgaGFuZGxlLiAqLwp2b2lkCnhwcnRfdW5yZWdpc3RlciAoU1ZDWFBSVCAqeHBydCkKewogIHJlZ2lzdGVyIGludCBzb2NrID0geHBydC0+eHBfc29jazsKICByZWdpc3RlciBpbnQgaTsKCiAgaWYgKChzb2NrIDwgX3JwY19kdGFibGVzaXplICgpKSAmJiAoeHBvcnRzW3NvY2tdID09IHhwcnQpKQogICAgewogICAgICB4cG9ydHNbc29ja10gPSAoU1ZDWFBSVCAqKSAwOwoKICAgICAgaWYgKHNvY2sgPCBGRF9TRVRTSVpFKQoJRkRfQ0xSIChzb2NrLCAmc3ZjX2Zkc2V0KTsKCiAgICAgIGZvciAoaSA9IDA7IGkgPCBzdmNfbWF4X3BvbGxmZDsgKytpKQoJaWYgKHN2Y19wb2xsZmRbaV0uZmQgPT0gc29jaykKCSAgc3ZjX3BvbGxmZFtpXS5mZCA9IC0xOwogICAgfQp9CmxpYmNfaGlkZGVuX2RlZiAoeHBydF91bnJlZ2lzdGVyKQoKCi8qICoqKioqKioqKioqKioqKioqKioqKiogQ0FMTE9VVCBsaXN0IHJlbGF0ZWQgc3R1ZmYgKioqKioqKioqKioqKiAqLwoKLyogU2VhcmNoIHRoZSBjYWxsb3V0IGxpc3QgZm9yIGEgcHJvZ3JhbSBudW1iZXIsIHJldHVybiB0aGUgY2FsbG91dAogICBzdHJ1Y3QuICovCnN0YXRpYyBzdHJ1Y3Qgc3ZjX2NhbGxvdXQgKgpzdmNfZmluZCAocnBjcHJvZ190IHByb2csIHJwY3ZlcnNfdCB2ZXJzLCBzdHJ1Y3Qgc3ZjX2NhbGxvdXQgKipwcmV2KQp7CiAgcmVnaXN0ZXIgc3RydWN0IHN2Y19jYWxsb3V0ICpzLCAqcDsKCiAgcCA9IE5VTExfU1ZDOwogIGZvciAocyA9IHN2Y19oZWFkOyBzICE9IE5VTExfU1ZDOyBzID0gcy0+c2NfbmV4dCkKICAgIHsKICAgICAgaWYgKChzLT5zY19wcm9nID09IHByb2cpICYmIChzLT5zY192ZXJzID09IHZlcnMpKQoJZ290byBkb25lOwogICAgICBwID0gczsKICAgIH0KZG9uZToKICAqcHJldiA9IHA7CiAgcmV0dXJuIHM7Cn0KCgpzdGF0aWMgYm9vbF90CnN2Y19pc19tYXBwZWQgKHJwY3Byb2dfdCBwcm9nLCBycGN2ZXJzX3QgdmVycykKewogIHN0cnVjdCBzdmNfY2FsbG91dCAqcHJldjsKICByZWdpc3RlciBzdHJ1Y3Qgc3ZjX2NhbGxvdXQgKnM7CiAgcyA9IHN2Y19maW5kIChwcm9nLCB2ZXJzLCAmcHJldik7CiAgcmV0dXJuIHMhPSBOVUxMX1NWQyAmJiBzLT5zY19tYXBwZWQ7Cn0KCgovKiBBZGQgYSBzZXJ2aWNlIHByb2dyYW0gdG8gdGhlIGNhbGxvdXQgbGlzdC4KICAgVGhlIGRpc3BhdGNoIHJvdXRpbmUgd2lsbCBiZSBjYWxsZWQgd2hlbiBhIHJwYyByZXF1ZXN0IGZvciB0aGlzCiAgIHByb2dyYW0gbnVtYmVyIGNvbWVzIGluLiAqLwpib29sX3QKc3ZjX3JlZ2lzdGVyIChTVkNYUFJUICogeHBydCwgcnBjcHJvZ190IHByb2csIHJwY3ZlcnNfdCB2ZXJzLAoJICAgICAgdm9pZCAoKmRpc3BhdGNoKSAoc3RydWN0IHN2Y19yZXEgKiwgU1ZDWFBSVCAqKSwKCSAgICAgIHJwY3Byb2NfdCBwcm90b2NvbCkKewogIHN0cnVjdCBzdmNfY2FsbG91dCAqcHJldjsKICByZWdpc3RlciBzdHJ1Y3Qgc3ZjX2NhbGxvdXQgKnM7CgogIGlmICgocyA9IHN2Y19maW5kIChwcm9nLCB2ZXJzLCAmcHJldikpICE9IE5VTExfU1ZDKQogICAgewogICAgICBpZiAocy0+c2NfZGlzcGF0Y2ggPT0gZGlzcGF0Y2gpCglnb3RvIHBtYXBfaXQ7CQkvKiBoZSBpcyByZWdpc3RlcmluZyBhbm90aGVyIHhwdHIgKi8KICAgICAgcmV0dXJuIEZBTFNFOwogICAgfQogIHMgPSAoc3RydWN0IHN2Y19jYWxsb3V0ICopIG1lbV9hbGxvYyAoc2l6ZW9mIChzdHJ1Y3Qgc3ZjX2NhbGxvdXQpKTsKICBpZiAocyA9PSAoc3RydWN0IHN2Y19jYWxsb3V0ICopIDApCiAgICByZXR1cm4gRkFMU0U7CgogIHMtPnNjX3Byb2cgPSBwcm9nOwogIHMtPnNjX3ZlcnMgPSB2ZXJzOwogIHMtPnNjX2Rpc3BhdGNoID0gZGlzcGF0Y2g7CiAgcy0+c2NfbmV4dCA9IHN2Y19oZWFkOwogIHMtPnNjX21hcHBlZCA9IEZBTFNFOwogIHN2Y19oZWFkID0gczsKCnBtYXBfaXQ6CiAgLyogbm93IHJlZ2lzdGVyIHRoZSBpbmZvcm1hdGlvbiB3aXRoIHRoZSBsb2NhbCBiaW5kZXIgc2VydmljZSAqLwogIGlmIChwcm90b2NvbCkKICAgIHsKICAgICAgaWYgKCEgcG1hcF9zZXQgKHByb2csIHZlcnMsIHByb3RvY29sLCB4cHJ0LT54cF9wb3J0KSkKCXJldHVybiBGQUxTRTsKCiAgICAgIHMtPnNjX21hcHBlZCA9IFRSVUU7CiAgICB9CgogIHJldHVybiBUUlVFOwp9CmxpYmNfaGlkZGVuX2RlZiAoc3ZjX3JlZ2lzdGVyKQoKLyogUmVtb3ZlIGEgc2VydmljZSBwcm9ncmFtIGZyb20gdGhlIGNhbGxvdXQgbGlzdC4gKi8Kdm9pZApzdmNfdW5yZWdpc3RlciAocnBjcHJvZ190IHByb2csIHJwY3ZlcnNfdCB2ZXJzKQp7CiAgc3RydWN0IHN2Y19jYWxsb3V0ICpwcmV2OwogIHJlZ2lzdGVyIHN0cnVjdCBzdmNfY2FsbG91dCAqczsKCiAgaWYgKChzID0gc3ZjX2ZpbmQgKHByb2csIHZlcnMsICZwcmV2KSkgPT0gTlVMTF9TVkMpCiAgICByZXR1cm47CgogIGlmIChwcmV2ID09IE5VTExfU1ZDKQogICAgc3ZjX2hlYWQgPSBzLT5zY19uZXh0OwogIGVsc2UKICAgIHByZXYtPnNjX25leHQgPSBzLT5zY19uZXh0OwoKICBzLT5zY19uZXh0ID0gTlVMTF9TVkM7CiAgbWVtX2ZyZWUgKChjaGFyICopIHMsICh1X2ludCkgc2l6ZW9mIChzdHJ1Y3Qgc3ZjX2NhbGxvdXQpKTsKICAvKiBub3cgdW5yZWdpc3RlciB0aGUgaW5mb3JtYXRpb24gd2l0aCB0aGUgbG9jYWwgYmluZGVyIHNlcnZpY2UgKi8KICBpZiAoISBzdmNfaXNfbWFwcGVkIChwcm9nLCB2ZXJzKSkKICAgIHBtYXBfdW5zZXQgKHByb2csIHZlcnMpOwp9CmxpYmNfaGlkZGVuX2RlZiAoc3ZjX3VucmVnaXN0ZXIpCgovKiAqKioqKioqKioqKioqKioqKioqIFJFUExZIEdFTkVSQVRJT04gUk9VVElORVMgICoqKioqKioqKioqKiAqLwoKLyogU2VuZCBhIHJlcGx5IHRvIGFuIHJwYyByZXF1ZXN0ICovCmJvb2xfdApzdmNfc2VuZHJlcGx5IChyZWdpc3RlciBTVkNYUFJUICp4cHJ0LCB4ZHJwcm9jX3QgeGRyX3Jlc3VsdHMsCgkgICAgICAgY2FkZHJfdCB4ZHJfbG9jYXRpb24pCnsKICBzdHJ1Y3QgcnBjX21zZyBycGx5OwoKICBycGx5LnJtX2RpcmVjdGlvbiA9IFJFUExZOwogIHJwbHkucm1fcmVwbHkucnBfc3RhdCA9IE1TR19BQ0NFUFRFRDsKICBycGx5LmFjcHRlZF9ycGx5LmFyX3ZlcmYgPSB4cHJ0LT54cF92ZXJmOwogIHJwbHkuYWNwdGVkX3JwbHkuYXJfc3RhdCA9IFNVQ0NFU1M7CiAgcnBseS5hY3B0ZWRfcnBseS5hcl9yZXN1bHRzLndoZXJlID0geGRyX2xvY2F0aW9uOwogIHJwbHkuYWNwdGVkX3JwbHkuYXJfcmVzdWx0cy5wcm9jID0geGRyX3Jlc3VsdHM7CiAgcmV0dXJuIFNWQ19SRVBMWSAoeHBydCwgJnJwbHkpOwp9CklOVERFRiAoc3ZjX3NlbmRyZXBseSkKCi8qIE5vIHByb2NlZHVyZSBlcnJvciByZXBseSAqLwp2b2lkCnN2Y2Vycl9ub3Byb2MgKHJlZ2lzdGVyIFNWQ1hQUlQgKnhwcnQpCnsKICBzdHJ1Y3QgcnBjX21zZyBycGx5OwoKICBycGx5LnJtX2RpcmVjdGlvbiA9IFJFUExZOwogIHJwbHkucm1fcmVwbHkucnBfc3RhdCA9IE1TR19BQ0NFUFRFRDsKICBycGx5LmFjcHRlZF9ycGx5LmFyX3ZlcmYgPSB4cHJ0LT54cF92ZXJmOwogIHJwbHkuYWNwdGVkX3JwbHkuYXJfc3RhdCA9IFBST0NfVU5BVkFJTDsKICBTVkNfUkVQTFkgKHhwcnQsICZycGx5KTsKfQoKLyogQ2FuJ3QgZGVjb2RlIGFyZ3MgZXJyb3IgcmVwbHkgKi8Kdm9pZApzdmNlcnJfZGVjb2RlIChyZWdpc3RlciBTVkNYUFJUICp4cHJ0KQp7CiAgc3RydWN0IHJwY19tc2cgcnBseTsKCiAgcnBseS5ybV9kaXJlY3Rpb24gPSBSRVBMWTsKICBycGx5LnJtX3JlcGx5LnJwX3N0YXQgPSBNU0dfQUNDRVBURUQ7CiAgcnBseS5hY3B0ZWRfcnBseS5hcl92ZXJmID0geHBydC0+eHBfdmVyZjsKICBycGx5LmFjcHRlZF9ycGx5LmFyX3N0YXQgPSBHQVJCQUdFX0FSR1M7CiAgU1ZDX1JFUExZICh4cHJ0LCAmcnBseSk7Cn0KSU5UREVGIChzdmNlcnJfZGVjb2RlKQoKLyogU29tZSBzeXN0ZW0gZXJyb3IgKi8Kdm9pZApzdmNlcnJfc3lzdGVtZXJyIChyZWdpc3RlciBTVkNYUFJUICp4cHJ0KQp7CiAgc3RydWN0IHJwY19tc2cgcnBseTsKCiAgcnBseS5ybV9kaXJlY3Rpb24gPSBSRVBMWTsKICBycGx5LnJtX3JlcGx5LnJwX3N0YXQgPSBNU0dfQUNDRVBURUQ7CiAgcnBseS5hY3B0ZWRfcnBseS5hcl92ZXJmID0geHBydC0+eHBfdmVyZjsKICBycGx5LmFjcHRlZF9ycGx5LmFyX3N0YXQgPSBTWVNURU1fRVJSOwogIFNWQ19SRVBMWSAoeHBydCwgJnJwbHkpOwp9CgovKiBBdXRoZW50aWNhdGlvbiBlcnJvciByZXBseSAqLwp2b2lkCnN2Y2Vycl9hdXRoIChTVkNYUFJUICp4cHJ0LCBlbnVtIGF1dGhfc3RhdCB3aHkpCnsKICBzdHJ1Y3QgcnBjX21zZyBycGx5OwoKICBycGx5LnJtX2RpcmVjdGlvbiA9IFJFUExZOwogIHJwbHkucm1fcmVwbHkucnBfc3RhdCA9IE1TR19ERU5JRUQ7CiAgcnBseS5yamN0ZWRfcnBseS5yal9zdGF0ID0gQVVUSF9FUlJPUjsKICBycGx5LnJqY3RlZF9ycGx5LnJqX3doeSA9IHdoeTsKICBTVkNfUkVQTFkgKHhwcnQsICZycGx5KTsKfQpsaWJjX2hpZGRlbl9kZWYgKHN2Y2Vycl9hdXRoKQoKLyogQXV0aCB0b28gd2VhayBlcnJvciByZXBseSAqLwp2b2lkCnN2Y2Vycl93ZWFrYXV0aCAoU1ZDWFBSVCAqeHBydCkKewogIHN2Y2Vycl9hdXRoICh4cHJ0LCBBVVRIX1RPT1dFQUspOwp9CgovKiBQcm9ncmFtIHVuYXZhaWxhYmxlIGVycm9yIHJlcGx5ICovCnZvaWQKc3ZjZXJyX25vcHJvZyAocmVnaXN0ZXIgU1ZDWFBSVCAqeHBydCkKewogIHN0cnVjdCBycGNfbXNnIHJwbHk7CgogIHJwbHkucm1fZGlyZWN0aW9uID0gUkVQTFk7CiAgcnBseS5ybV9yZXBseS5ycF9zdGF0ID0gTVNHX0FDQ0VQVEVEOwogIHJwbHkuYWNwdGVkX3JwbHkuYXJfdmVyZiA9IHhwcnQtPnhwX3ZlcmY7CiAgcnBseS5hY3B0ZWRfcnBseS5hcl9zdGF0ID0gUFJPR19VTkFWQUlMOwogIFNWQ19SRVBMWSAoeHBydCwgJnJwbHkpOwp9CmxpYmNfaGlkZGVuX2RlZiAoc3ZjZXJyX25vcHJvZykKCi8qIFByb2dyYW0gdmVyc2lvbiBtaXNtYXRjaCBlcnJvciByZXBseSAqLwp2b2lkCnN2Y2Vycl9wcm9ndmVycyAocmVnaXN0ZXIgU1ZDWFBSVCAqeHBydCwgcnBjdmVyc190IGxvd192ZXJzLAoJCSBycGN2ZXJzX3QgaGlnaF92ZXJzKQp7CiAgc3RydWN0IHJwY19tc2cgcnBseTsKCiAgcnBseS5ybV9kaXJlY3Rpb24gPSBSRVBMWTsKICBycGx5LnJtX3JlcGx5LnJwX3N0YXQgPSBNU0dfQUNDRVBURUQ7CiAgcnBseS5hY3B0ZWRfcnBseS5hcl92ZXJmID0geHBydC0+eHBfdmVyZjsKICBycGx5LmFjcHRlZF9ycGx5LmFyX3N0YXQgPSBQUk9HX01JU01BVENIOwogIHJwbHkuYWNwdGVkX3JwbHkuYXJfdmVycy5sb3cgPSBsb3dfdmVyczsKICBycGx5LmFjcHRlZF9ycGx5LmFyX3ZlcnMuaGlnaCA9IGhpZ2hfdmVyczsKICBTVkNfUkVQTFkgKHhwcnQsICZycGx5KTsKfQpsaWJjX2hpZGRlbl9kZWYgKHN2Y2Vycl9wcm9ndmVycykKCi8qICoqKioqKioqKioqKioqKioqKiogU0VSVkVSIElOUFVUIFNUVUZGICoqKioqKioqKioqKioqKioqKiogKi8KCi8qCiAqIEdldCBzZXJ2ZXIgc2lkZSBpbnB1dCBmcm9tIHNvbWUgdHJhbnNwb3J0LgogKgogKiBTdGF0ZW1lbnQgb2YgYXV0aGVudGljYXRpb24gcGFyYW1ldGVycyBtYW5hZ2VtZW50OgogKiBUaGlzIGZ1bmN0aW9uIG93bnMgYW5kIG1hbmFnZXMgYWxsIGF1dGhlbnRpY2F0aW9uIHBhcmFtZXRlcnMsIHNwZWNpZmljYWxseQogKiB0aGUgInJhdyIgcGFyYW1ldGVycyAobXNnLnJtX2NhbGwuY2JfY3JlZCBhbmQgbXNnLnJtX2NhbGwuY2JfdmVyZikgYW5kCiAqIHRoZSAiY29va2VkIiBjcmVkZW50aWFscyAocnFzdC0+cnFfY2xudGNyZWQpLgogKiBIb3dldmVyLCB0aGlzIGZ1bmN0aW9uIGRvZXMgbm90IGtub3cgdGhlIHN0cnVjdHVyZSBvZiB0aGUgY29va2VkCiAqIGNyZWRlbnRpYWxzLCBzbyBpdCBtYWtlIHRoZSBmb2xsb3dpbmcgYXNzdW1wdGlvbnM6CiAqICAgYSkgdGhlIHN0cnVjdHVyZSBpcyBjb250aWd1b3VzIChubyBwb2ludGVycyksIGFuZAogKiAgIGIpIHRoZSBjcmVkIHN0cnVjdHVyZSBzaXplIGRvZXMgbm90IGV4Y2VlZCBSUUNSRURfU0laRSBieXRlcy4KICogSW4gYWxsIGV2ZW50cywgYWxsIHRocmVlIHBhcmFtZXRlcnMgYXJlIGZyZWVkIHVwb24gZXhpdCBmcm9tIHRoaXMgcm91dGluZS4KICogVGhlIHN0b3JhZ2UgaXMgdHJpdmlhbGx5IG1hbmFnZW1lbnQgb24gdGhlIGNhbGwgc3RhY2sgaW4gdXNlciBsYW5kLCBidXQKICogaXMgbWFsbG9jYXRlZCBpbiBrZXJuZWwgbGFuZC4KICovCgp2b2lkCnN2Y19nZXRyZXEgKGludCByZGZkcykKewogIGZkX3NldCByZWFkZmRzOwoKICBGRF9aRVJPICgmcmVhZGZkcyk7CiAgcmVhZGZkcy5mZHNfYml0c1swXSA9IHJkZmRzOwogIElOVFVTRShzdmNfZ2V0cmVxc2V0KSAoJnJlYWRmZHMpOwp9CklOVERFRiAoc3ZjX2dldHJlcSkKCnZvaWQKc3ZjX2dldHJlcXNldCAoZmRfc2V0ICpyZWFkZmRzKQp7CiAgcmVnaXN0ZXIgZmRfbWFzayBtYXNrOwogIHJlZ2lzdGVyIGZkX21hc2sgKm1hc2twOwogIHJlZ2lzdGVyIGludCBzZXRzaXplOwogIHJlZ2lzdGVyIGludCBzb2NrOwogIHJlZ2lzdGVyIGludCBiaXQ7CgogIHNldHNpemUgPSBfcnBjX2R0YWJsZXNpemUgKCk7CiAgaWYgKHNldHNpemUgPiBGRF9TRVRTSVpFKQogICAgc2V0c2l6ZSA9IEZEX1NFVFNJWkU7CiAgbWFza3AgPSByZWFkZmRzLT5mZHNfYml0czsKICBmb3IgKHNvY2sgPSAwOyBzb2NrIDwgc2V0c2l6ZTsgc29jayArPSBORkRCSVRTKQogICAgZm9yIChtYXNrID0gKm1hc2twKys7IChiaXQgPSBmZnNsIChtYXNrKSk7IG1hc2sgXj0gKDFMIDw8IChiaXQgLSAxKSkpCiAgICAgIElOVFVTRShzdmNfZ2V0cmVxX2NvbW1vbikgKHNvY2sgKyBiaXQgLSAxKTsKfQpJTlRERUYgKHN2Y19nZXRyZXFzZXQpCgp2b2lkCnN2Y19nZXRyZXFfcG9sbCAoc3RydWN0IHBvbGxmZCAqcGZkcCwgaW50IHBvbGxyZXR2YWwpCnsKICBpZiAocG9sbHJldHZhbCA9PSAwKQogICAgcmV0dXJuOwoKICByZWdpc3RlciBpbnQgZmRzX2ZvdW5kOwogIGZvciAoaW50IGkgPSBmZHNfZm91bmQgPSAwOyBpIDwgc3ZjX21heF9wb2xsZmQ7ICsraSkKICAgIHsKICAgICAgcmVnaXN0ZXIgc3RydWN0IHBvbGxmZCAqcCA9ICZwZmRwW2ldOwoKICAgICAgaWYgKHAtPmZkICE9IC0xICYmIHAtPnJldmVudHMpCgl7CgkgIC8qIGZkIGhhcyBpbnB1dCB3YWl0aW5nICovCgkgIGlmIChwLT5yZXZlbnRzICYgUE9MTE5WQUwpCgkgICAgeHBydF91bnJlZ2lzdGVyICh4cG9ydHNbcC0+ZmRdKTsKCSAgZWxzZQoJICAgIElOVFVTRShzdmNfZ2V0cmVxX2NvbW1vbikgKHAtPmZkKTsKCgkgIGlmICgrK2Zkc19mb3VuZCA+PSBwb2xscmV0dmFsKQoJICAgIGJyZWFrOwoJfQogICAgfQp9CklOVERFRiAoc3ZjX2dldHJlcV9wb2xsKQoKCnZvaWQKc3ZjX2dldHJlcV9jb21tb24gKGNvbnN0IGludCBmZCkKewogIGVudW0geHBydF9zdGF0IHN0YXQ7CiAgc3RydWN0IHJwY19tc2cgbXNnOwogIHJlZ2lzdGVyIFNWQ1hQUlQgKnhwcnQ7CiAgY2hhciBjcmVkX2FyZWFbMiAqIE1BWF9BVVRIX0JZVEVTICsgUlFDUkVEX1NJWkVdOwogIG1zZy5ybV9jYWxsLmNiX2NyZWQub2FfYmFzZSA9IGNyZWRfYXJlYTsKICBtc2cucm1fY2FsbC5jYl92ZXJmLm9hX2Jhc2UgPSAmKGNyZWRfYXJlYVtNQVhfQVVUSF9CWVRFU10pOwoKICB4cHJ0ID0geHBvcnRzW2ZkXTsKICAvKiBEbyB3ZSBjb250cm9sIGZkPyAqLwogIGlmICh4cHJ0ID09IE5VTEwpCiAgICAgcmV0dXJuOwoKICAvKiBub3cgcmVjZWl2ZSBtc2dzIGZyb20geHBydHBydCAoc3VwcG9ydCBiYXRjaCBjYWxscykgKi8KICBkbwogICAgewogICAgICBpZiAoU1ZDX1JFQ1YgKHhwcnQsICZtc2cpKQoJewoJICAvKiBub3cgZmluZCB0aGUgZXhwb3J0ZWQgcHJvZ3JhbSBhbmQgY2FsbCBpdCAqLwoJICBzdHJ1Y3Qgc3ZjX2NhbGxvdXQgKnM7CgkgIHN0cnVjdCBzdmNfcmVxIHI7CgkgIGVudW0gYXV0aF9zdGF0IHdoeTsKCSAgcnBjdmVyc190IGxvd192ZXJzOwoJICBycGN2ZXJzX3QgaGlnaF92ZXJzOwoJICBpbnQgcHJvZ19mb3VuZDsKCgkgIHIucnFfY2xudGNyZWQgPSAmKGNyZWRfYXJlYVsyICogTUFYX0FVVEhfQllURVNdKTsKCSAgci5ycV94cHJ0ID0geHBydDsKCSAgci5ycV9wcm9nID0gbXNnLnJtX2NhbGwuY2JfcHJvZzsKCSAgci5ycV92ZXJzID0gbXNnLnJtX2NhbGwuY2JfdmVyczsKCSAgci5ycV9wcm9jID0gbXNnLnJtX2NhbGwuY2JfcHJvYzsKCSAgci5ycV9jcmVkID0gbXNnLnJtX2NhbGwuY2JfY3JlZDsKCgkgIC8qIGZpcnN0IGF1dGhlbnRpY2F0ZSB0aGUgbWVzc2FnZSAqLwoJICAvKiBDaGVjayBmb3IgbnVsbCBmbGF2b3IgYW5kIGJ5cGFzcyB0aGVzZSBjYWxscyBpZiBwb3NzaWJsZSAqLwoKCSAgaWYgKG1zZy5ybV9jYWxsLmNiX2NyZWQub2FfZmxhdm9yID09IEFVVEhfTlVMTCkKCSAgICB7CgkgICAgICByLnJxX3hwcnQtPnhwX3ZlcmYub2FfZmxhdm9yID0gX251bGxfYXV0aC5vYV9mbGF2b3I7CgkgICAgICByLnJxX3hwcnQtPnhwX3ZlcmYub2FfbGVuZ3RoID0gMDsKCSAgICB9CgkgIGVsc2UgaWYgKCh3aHkgPSBJTlRVU0UoX2F1dGhlbnRpY2F0ZSkgKCZyLCAmbXNnKSkgIT0gQVVUSF9PSykKCSAgICB7CgkgICAgICBzdmNlcnJfYXV0aCAoeHBydCwgd2h5KTsKCSAgICAgIGdvdG8gY2FsbF9kb25lOwoJICAgIH0KCgkgIC8qIG5vdyBtYXRjaCBtZXNzYWdlIHdpdGggYSByZWdpc3RlcmVkIHNlcnZpY2UgKi8KCSAgcHJvZ19mb3VuZCA9IEZBTFNFOwoJICBsb3dfdmVycyA9IDAgLSAxOwoJICBoaWdoX3ZlcnMgPSAwOwoKCSAgZm9yIChzID0gc3ZjX2hlYWQ7IHMgIT0gTlVMTF9TVkM7IHMgPSBzLT5zY19uZXh0KQoJICAgIHsKCSAgICAgIGlmIChzLT5zY19wcm9nID09IHIucnFfcHJvZykKCQl7CgkJICBpZiAocy0+c2NfdmVycyA9PSByLnJxX3ZlcnMpCgkJICAgIHsKCQkgICAgICAoKnMtPnNjX2Rpc3BhdGNoKSAoJnIsIHhwcnQpOwoJCSAgICAgIGdvdG8gY2FsbF9kb25lOwoJCSAgICB9CgkJICAvKiBmb3VuZCBjb3JyZWN0IHZlcnNpb24gKi8KCQkgIHByb2dfZm91bmQgPSBUUlVFOwoJCSAgaWYgKHMtPnNjX3ZlcnMgPCBsb3dfdmVycykKCQkgICAgbG93X3ZlcnMgPSBzLT5zY192ZXJzOwoJCSAgaWYgKHMtPnNjX3ZlcnMgPiBoaWdoX3ZlcnMpCgkJICAgIGhpZ2hfdmVycyA9IHMtPnNjX3ZlcnM7CgkJfQoJICAgICAgLyogZm91bmQgY29ycmVjdCBwcm9ncmFtICovCgkgICAgfQoJICAvKiBpZiB3ZSBnb3QgaGVyZSwgdGhlIHByb2dyYW0gb3IgdmVyc2lvbgoJICAgICBpcyBub3Qgc2VydmVkIC4uLiAqLwoJICBpZiAocHJvZ19mb3VuZCkKCSAgICBzdmNlcnJfcHJvZ3ZlcnMgKHhwcnQsIGxvd192ZXJzLCBoaWdoX3ZlcnMpOwoJICBlbHNlCgkgICAgc3ZjZXJyX25vcHJvZyAoeHBydCk7CgkgIC8qIEZhbGwgdGhyb3VnaCB0byAuLi4gKi8KCX0KICAgIGNhbGxfZG9uZToKICAgICAgaWYgKChzdGF0ID0gU1ZDX1NUQVQgKHhwcnQpKSA9PSBYUFJUX0RJRUQpCgl7CgkgIFNWQ19ERVNUUk9ZICh4cHJ0KTsKCSAgYnJlYWs7Cgl9CiAgICB9CiAgd2hpbGUgKHN0YXQgPT0gWFBSVF9NT1JFUkVRUyk7Cn0KSU5UREVGIChzdmNfZ2V0cmVxX2NvbW1vbikKCiNpZmRlZiBfUlBDX1RIUkVBRF9TQUZFXwoKdm9pZApfX3JwY190aHJlYWRfc3ZjX2NsZWFudXAgKHZvaWQpCnsKICBzdHJ1Y3Qgc3ZjX2NhbGxvdXQgKnN2Y3A7CgogIHdoaWxlICgoc3ZjcCA9IHN2Y19oZWFkKSAhPSBOVUxMKQogICAgc3ZjX3VucmVnaXN0ZXIgKHN2Y3AtPnNjX3Byb2csIHN2Y3AtPnNjX3ZlcnMpOwp9CgojZW5kaWYgLyogX1JQQ19USFJFQURfU0FGRV8gKi8K