LyogZW50ZXJub3dfcGNpLmMsdiAwLjk5IDIwMDEvMTAvMDIKICoKICogZW50ZXJub3dfcGNpLmMgICAgICAgQ2FyZC1zcGVjaWZpYyByb3V0aW5lcyBmb3IKICogICAgICAgICAgICAgICAgICAgICAgRm9ybXVsYS1uIGVudGVyOm5vdyBJU0ROIFBDSSBhYgogKiAgICAgICAgICAgICAgICAgICAgICBHZXJkZXMgQUcgUG93ZXIgSVNETiBQQ0kKICogICAgICAgICAgICAgICAgICAgICAgV29lcmx0cm9uaWMgU0EgMTYgUENJCiAqICAgICAgICAgICAgICAgICAgICAgIChiYXNlZCBvbiBIaVNheCBkcml2ZXIgYnkgS2Fyc3RlbiBLZWlsKQogKgogKiBBdXRob3IgICAgICAgICAgICAgICBDaHJpc3RvcGggRXJzZmVsZCA8aW5mb0Bmb3JtdWxhLW4uZGU+CiAqICAgICAgICAgICAgICAgICAgICAgIEZvcm11bGEtbiBFdXJvcGUgQUcgKHd3dy5mb3JtdWxhLW4uY29tKQogKiAgICAgICAgICAgICAgICAgICAgICBwcmV2aW91c2x5IEdlcmRlcyBBRwogKgogKgogKiAgICAgICAgICAgICAgICAgICAgICBUaGlzIGZpbGUgaXMgKGMpIHVuZGVyIEdOVSBQVUJMSUMgTElDRU5TRQogKgogKiBOb3RlczoKICogVGhpcyBkcml2ZXIgaW50ZXJmYWNlcyB0byBuZXRqZXQuYyB3aGljaCBwZXJmb3JtcyBCLWNoYW5uZWwKICogcHJvY2Vzc2luZy4KICoKICogVmVyc2lvbiAwLjk5IGlzIHRoZSBmaXJzdCByZWxlYXNlIG9mIHRoaXMgZHJpdmVyIGFuZCB0aGVyZSBhcmUKICogY2VydGFpbmx5IGEgZmV3IGJ1Z3MuCiAqIEl0IGlzbid0IHRlc3RldCBvbiBsaW51eCAyLjQgeWV0LCBzbyBjb25zaWRlciB0aGlzIGNvZGUgdG8gYmUKICogYmV0YS4KICoKICogUGxlYXNlIGRvbid0IHJlcG9ydCBtZSBhbnkgbWFsZnVuY3Rpb24gd2l0aG91dCBzZW5kaW5nCiAqIChjb21wcmVzc2VkKSBkZWJ1Zy1sb2dzLgogKiBJdCB3b3VsZCBiZSBuZWFybHkgaW1wb3NzaWJsZSB0byByZXRyYWNlIGl0LgogKgogKiBMb2cgRC1jaGFubmVsLXByb2Nlc3NpbmcgYXMgZm9sbG93czoKICoKICogMS4gTG9hZCBoaXNheCB3aXRoIGNhcmQtc3BlY2lmaWMgcGFyYW1ldGVycywgdGhpcyBleGFtcGxlIGlzdCBmb3IKICogICAgRm9ybXVsYS1uIGVudGVyOm5vdyBJU0ROIFBDSSBhbmQgY29tcGF0aWJsZQogKiAgICAoZi5lLiBHZXJkZXMgUG93ZXIgSVNETiBQQ0kpCiAqCiAqICAgIG1vZHByb2JlIGhpc2F4IHR5cGU9NDEgcHJvdG9jb2w9MiBpZD1nZXJkZXMKICoKICogICAgaWYgeW91IGNob3NlIGFuIG90aGVyIHZhbHVlIGZvciBpZCwgeW91IG5lZWQgdG8gbW9kaWZ5IHRoZQogKiAgICBjb2RlIGJlbG93LCB0b28uCiAqCiAqIDIuIHNldCBkZWJ1Zy1sZXZlbAogKgogKiAgICBoaXNheGN0cmwgZ2VyZGVzIDEgMHgzZmYKICogICAgaGlzYXhjdHJsIGdlcmRlcyAxMSAweDRmCiAqICAgIGNhdCAvZGV2L2lzZG5jdHJsID4+IH4vbG9nICYKICoKICogUGxlYXNlIHRha2UgYWxzbyBhIGxvb2sgaW50byAvdmFyL2xvZy9tZXNzYWdlcyBpZiB0aGVyZSBpcwogKiBhbnl0aGluZyBpbXBvcnRhbmQgY29uY2VybmluZyBISVNBWC4KICoKICoKICogQ3JlZGl0czoKICogUHJvZ3JhbW1pbmcgdGhlIGRyaXZlciBmb3IgRm9ybXVsYS1uIGVudGVyOm5vdyBJU0ROIFBDSSBhbmQKICogbmVjZXNzYXJ5IHRoZSBkcml2ZXIgZm9yIHRoZSB1c2VkIEFtZCA3OTMwIEQtY2hhbm5lbC1jb250cm9sbGVyCiAqIHdhcyBzcG5zb3JlZCBieSBGb3JtdWxhLW4gRXVyb3BlIEFHLgogKiBUaGFua3MgdG8gS2Fyc3RlbiBLZWlsIGFuZCBQZXRyIE5vdmFrLCB3aG8gZ2F2ZSBtZSBzdXBwb3J0IGluCiAqIEhpc2F4LXNwZWNpZmljIHF1ZXN0aW9ucy4KICogSSB3YW50IHNvIHNheSBzcGVjaWFsIHRoYW5rcyB0byBDYXJsLUZyaWVkcmljaCBCcmF1biwgd2hvIGhhZCB0bwogKiBhbnN3ZXIgYSBsb3Qgb2YgcXVlc3Rpb25zIGFib3V0IGdlbmVyYWxseSBJU0ROIGFuZCBhYm91dCBoYW5kbGluZwogKiBvZiB0aGUgQW1kLUNoaXAuCiAqCiAqLwoKCiNpbmNsdWRlIDxsaW51eC9jb25maWcuaD4KI2luY2x1ZGUgImhpc2F4LmgiCiNpbmNsdWRlICJpc2FjLmgiCiNpbmNsdWRlICJpc2RubDEuaCIKI2luY2x1ZGUgImFtZDc5MzBfZm4uaCIKI2luY2x1ZGUgImVudGVybm93LmgiCiNpbmNsdWRlIDxsaW51eC9pbnRlcnJ1cHQuaD4KI2luY2x1ZGUgPGxpbnV4L3BwcF9kZWZzLmg+CiNpbmNsdWRlIDxsaW51eC9wY2kuaD4KI2luY2x1ZGUgPGxpbnV4L2luaXQuaD4KI2luY2x1ZGUgIm5ldGpldC5oIgoKCgpjb25zdCBjaGFyICplbnRlcm5vd19wY2lfcmV2ID0gIiRSZXZpc2lvbjogMS4xLjQuNSAkIjsKCgovKiAqKioqKioqKioqKioqKioqKioqKioqKioqKiogSS9PLUludGVyZmFjZSBmdW5jdGlvbnMgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiAqLwoKCi8qIGNzLT5yZWFkaXNhYywgbWFjcm8gckJ5dGVBTUQgKi8KQllURQpSZWFkQnl0ZUFtZDc5MzAoc3RydWN0IElzZG5DYXJkU3RhdGUgKmNzLCBCWVRFIG9mZnNldCkKewoJLyogZGlyZWt0ZXMgUmVnaXN0ZXIgKi8KCWlmKG9mZnNldCA8IDgpCgkJcmV0dXJuIChJbkJ5dGUoY3MtPmh3Lm5qZXQuaXNhYyArIDQqb2Zmc2V0KSk7CgoJLyogaW5kaXJla3RlcyBSZWdpc3RlciAqLwoJZWxzZSB7CgkJT3V0Qnl0ZShjcy0+aHcubmpldC5pc2FjICsgNCpBTURfQ1IsIG9mZnNldCk7CgkJcmV0dXJuKEluQnl0ZShjcy0+aHcubmpldC5pc2FjICsgNCpBTURfRFIpKTsKCX0KfQoKLyogY3MtPndyaXRlaXNhYywgbWFjcm8gd0J5dGVBTUQgKi8Kdm9pZApXcml0ZUJ5dGVBbWQ3OTMwKHN0cnVjdCBJc2RuQ2FyZFN0YXRlICpjcywgQllURSBvZmZzZXQsIEJZVEUgdmFsdWUpCnsKCS8qIGRpcmVrdGVzIFJlZ2lzdGVyICovCglpZihvZmZzZXQgPCA4KQoJCU91dEJ5dGUoY3MtPmh3Lm5qZXQuaXNhYyArIDQqb2Zmc2V0LCB2YWx1ZSk7CgoJLyogaW5kaXJla3RlcyBSZWdpc3RlciAqLwoJZWxzZSB7CgkJT3V0Qnl0ZShjcy0+aHcubmpldC5pc2FjICsgNCpBTURfQ1IsIG9mZnNldCk7CgkJT3V0Qnl0ZShjcy0+aHcubmpldC5pc2FjICsgNCpBTURfRFIsIHZhbHVlKTsKCX0KfQoKCnZvaWQKZW5wY2lfc2V0SXJxTWFzayhzdHJ1Y3QgSXNkbkNhcmRTdGF0ZSAqY3MsIEJZVEUgdmFsKSB7CiAgICAgICAgaWYgKCF2YWwpCgkgICAgICAgIE91dEJ5dGUoY3MtPmh3Lm5qZXQuYmFzZStORVRKRVRfSVJRTUFTSzEsIDB4MDApOwogICAgICAgIGVsc2UKCSAgICAgICAgT3V0Qnl0ZShjcy0+aHcubmpldC5iYXNlK05FVEpFVF9JUlFNQVNLMSwgVEpfQU1EX0lSUSk7Cn0KCgpzdGF0aWMgQllURSBkdW1teXJyKHN0cnVjdCBJc2RuQ2FyZFN0YXRlICpjcywgaW50IGNoYW4sIEJZVEUgb2ZmKQp7CiAgICAgICAgcmV0dXJuKDUpOwp9CgpzdGF0aWMgdm9pZCBkdW1teXdyKHN0cnVjdCBJc2RuQ2FyZFN0YXRlICpjcywgaW50IGNoYW4sIEJZVEUgb2ZmLCBCWVRFIHZhbHVlKQp7Cgp9CgoKLyogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiogKi8KCgpzdGF0aWMgdm9pZApyZXNldF9lbnBjaShzdHJ1Y3QgSXNkbkNhcmRTdGF0ZSAqY3MpCnsKCWlmIChjcy0+ZGVidWcgJiBMMV9ERUJfSVNBQykKCQlkZWJ1Z2wxKGNzLCAiZW50ZXI6bm93IFBDSTogcmVzZXQiKTsKCgkvKiBSZXNldCBvbiwgKGFsc28gZm9yIEFNRCkgKi8KCWNzLT5ody5uamV0LmN0cmxfcmVnID0gMHgwNzsKCU91dEJ5dGUoY3MtPmh3Lm5qZXQuYmFzZSArIE5FVEpFVF9DVFJMLCBjcy0+aHcubmpldC5jdHJsX3JlZyk7CgltZGVsYXkoMjApOwoJLyogUmVzZXQgb2ZmICovCgljcy0+aHcubmpldC5jdHJsX3JlZyA9IDB4MzA7CglPdXRCeXRlKGNzLT5ody5uamV0LmJhc2UgKyBORVRKRVRfQ1RSTCwgY3MtPmh3Lm5qZXQuY3RybF9yZWcpOwoJLyogMjBtcyBkZWxheSAqLwoJbWRlbGF5KDIwKTsKCWNzLT5ody5uamV0LmF1eGQgPSAwOyAgLy8gTEVELXN0YXR1cwoJY3MtPmh3Lm5qZXQuZG1hY3RybCA9IDA7CglPdXRCeXRlKGNzLT5ody5uamV0LmJhc2UgKyBORVRKRVRfQVVYQ1RSTCwgflRKX0FNRF9JUlEpOwoJT3V0Qnl0ZShjcy0+aHcubmpldC5iYXNlICsgTkVUSkVUX0lSUU1BU0sxLCBUSl9BTURfSVJRKTsKCU91dEJ5dGUoY3MtPmh3Lm5qZXQuYXV4YSwgY3MtPmh3Lm5qZXQuYXV4ZCk7IC8vIExFRCBvZmYKfQoKCnN0YXRpYyBpbnQKZW5wY2lfY2FyZF9tc2coc3RydWN0IElzZG5DYXJkU3RhdGUgKmNzLCBpbnQgbXQsIHZvaWQgKmFyZykKewoJdV9sb25nIGZsYWdzOwogICAgICAgIEJZVEUgKmNoYW47CgoJaWYgKGNzLT5kZWJ1ZyAmIEwxX0RFQl9JU0FDKQoJCWRlYnVnbDEoY3MsICJlbnRlcjpub3cgUENJOiBjYXJkX21zZzogMHglMDRYIiwgbXQpOwoKICAgICAgICBzd2l0Y2ggKG10KSB7CgkJY2FzZSBDQVJEX1JFU0VUOgoJCQlzcGluX2xvY2tfaXJxc2F2ZSgmY3MtPmxvY2ssIGZsYWdzKTsKCQkJcmVzZXRfZW5wY2koY3MpOwogICAgICAgICAgICAgICAgICAgICAgICBBbWQ3OTMwX2luaXQoY3MpOwogICAgICAgICAgICAgICAgICAgICAgICBzcGluX3VubG9ja19pcnFyZXN0b3JlKCZjcy0+bG9jaywgZmxhZ3MpOwoJCQlicmVhazsKCQljYXNlIENBUkRfUkVMRUFTRToKCQkJcmVsZWFzZV9pb19uZXRqZXQoY3MpOwoJCQlicmVhazsKCQljYXNlIENBUkRfSU5JVDoKCQkJcmVzZXRfZW5wY2koY3MpOwoJCQlpbml0dGlnZXIoY3MpOwoJCQkvKiBpcnEgbXVzdCBiZSBvbiBoZXJlICovCgkJCUFtZDc5MzBfaW5pdChjcyk7CgkJCWJyZWFrOwoJCWNhc2UgQ0FSRF9URVNUOgoJCQlicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgTURMX0FTU0lHTjoKICAgICAgICAgICAgICAgICAgICAgICAgLyogVEVJIGFzc2lnbmVkLCBMRUQxIG9uICovCiAgICAgICAgICAgICAgICAgICAgICAgIGNzLT5ody5uamV0LmF1eGQgPSBUSl9BTURfSVJRIDw8IDE7CiAgICAgICAgICAgICAgICAgICAgICAgIE91dEJ5dGUoY3MtPmh3Lm5qZXQuYmFzZSArIE5FVEpFVF9BVVhEQVRBLCBjcy0+aHcubmpldC5hdXhkKTsKICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlIE1ETF9SRU1PVkU6CiAgICAgICAgICAgICAgICAgICAgICAgIC8qIFRFSSByZW1vdmVkLCBMRURzIG9mZiAqLwoJICAgICAgICAgICAgICAgIGNzLT5ody5uamV0LmF1eGQgPSAwOwogICAgICAgICAgICAgICAgICAgICAgICBPdXRCeXRlKGNzLT5ody5uamV0LmJhc2UgKyBORVRKRVRfQVVYREFUQSwgMHgwMCk7CiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSBNRExfQkNfQVNTSUdOOgogICAgICAgICAgICAgICAgICAgICAgICAvKiBhY3RpdmF0ZSBCLWNoYW5uZWwgKi8KICAgICAgICAgICAgICAgICAgICAgICAgY2hhbiA9IChCWVRFICopYXJnOwoKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGNzLT5kZWJ1ZyAmIEwxX0RFQl9JU0FDKQoJCSAgICAgICAgICAgICAgICBkZWJ1Z2wxKGNzLCAiZW50ZXI6bm93IFBDSTogYXNzaWduIHBoeXMuIEJDICVkIGluIEFNRCBMTVIxIiwgKmNoYW4pOwoKICAgICAgICAgICAgICAgICAgICAgICAgY3MtPmRjLmFtZDc5MzAucGhfY29tbWFuZChjcywgKGNzLT5kYy5hbWQ3OTMwLmxtcjEgfCAoKmNoYW4gKyAxKSksICJNRExfQkNfQVNTSUdOIik7CiAgICAgICAgICAgICAgICAgICAgICAgIC8qIGF0IGxlYXN0IG9uZSBiLWNoYW5uZWwgaW4gdXNlLCBMRUQgMiBvbiAqLwogICAgICAgICAgICAgICAgICAgICAgICBjcy0+aHcubmpldC5hdXhkIHw9IFRKX0FNRF9JUlEgPDwgMjsKICAgICAgICAgICAgICAgICAgICAgICAgT3V0Qnl0ZShjcy0+aHcubmpldC5iYXNlICsgTkVUSkVUX0FVWERBVEEsIGNzLT5ody5uamV0LmF1eGQpOwogICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgTURMX0JDX1JFTEVBU0U6CiAgICAgICAgICAgICAgICAgICAgICAgIC8qIGRlYWN0aXZhdGUgQi1jaGFubmVsICovCiAgICAgICAgICAgICAgICAgICAgICAgIGNoYW4gPSAoQllURSAqKWFyZzsKCiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChjcy0+ZGVidWcgJiBMMV9ERUJfSVNBQykKCQkgICAgICAgICAgICAgICAgZGVidWdsMShjcywgImVudGVyOm5vdyBQQ0k6IHJlbGVhc2UgcGh5cy4gQkMgJWQgaW4gQW1kIExNUjEiLCAqY2hhbik7CgogICAgICAgICAgICAgICAgICAgICAgICBjcy0+ZGMuYW1kNzkzMC5waF9jb21tYW5kKGNzLCAoY3MtPmRjLmFtZDc5MzAubG1yMSAmIH4oKmNoYW4gKyAxKSksICJNRExfQkNfUkVMRUFTRSIpOwogICAgICAgICAgICAgICAgICAgICAgICAvKiBubyBiLWNoYW5uZWwgYWN0aXZlIC0+IExFRDIgb2ZmICovCiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghKGNzLT5kYy5hbWQ3OTMwLmxtcjEgJiAzKSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNzLT5ody5uamV0LmF1eGQgJj0gfihUSl9BTURfSVJRIDw8IDIpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE91dEJ5dGUoY3MtPmh3Lm5qZXQuYmFzZSArIE5FVEpFVF9BVVhEQVRBLCBjcy0+aHcubmpldC5hdXhkKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwoKCX0KCXJldHVybigwKTsKfQoKc3RhdGljIGlycXJldHVybl90CmVucGNpX2ludGVycnVwdChpbnQgaW50bm8sIHZvaWQgKmRldl9pZCwgc3RydWN0IHB0X3JlZ3MgKnJlZ3MpCnsKCXN0cnVjdCBJc2RuQ2FyZFN0YXRlICpjcyA9IGRldl9pZDsKCUJZVEUgczB2YWwsIHMxdmFsLCBpcjsKCXVfbG9uZyBmbGFnczsKCglzcGluX2xvY2tfaXJxc2F2ZSgmY3MtPmxvY2ssIGZsYWdzKTsKCXMxdmFsID0gSW5CeXRlKGNzLT5ody5uamV0LmJhc2UgKyBORVRKRVRfSVJRU1RBVDEpOwoKICAgICAgICAvKiBBTUQgdGhyZXcgYW4gaW50ZXJydXB0ICovCglpZiAoIShzMXZhbCAmIFRKX0FNRF9JUlEpKSB7CiAgICAgICAgICAgICAgICAvKiByZWFkIGFuZCBjbGVhciBpbnRlcnJ1cHQtcmVnaXN0ZXIgKi8KCQlpciA9IFJlYWRCeXRlQW1kNzkzMChjcywgMHgwMCk7CgkJQW1kNzkzMF9pbnRlcnJ1cHQoY3MsIGlyKTsKCQlzMXZhbCA9IDE7Cgl9IGVsc2UKCQlzMXZhbCA9IDA7CglzMHZhbCA9IEluQnl0ZShjcy0+aHcubmpldC5iYXNlICsgTkVUSkVUX0lSUVNUQVQwKTsKCWlmICgoczB2YWwgfCBzMXZhbCk9PTApIHsgLy8gc2hhcmVkIElSUQoJCXNwaW5fdW5sb2NrX2lycXJlc3RvcmUoJmNzLT5sb2NrLCBmbGFncyk7CgkJcmV0dXJuIElSUV9OT05FOwoJfSAKCWlmIChzMHZhbCkKCQlPdXRCeXRlKGNzLT5ody5uamV0LmJhc2UgKyBORVRKRVRfSVJRU1RBVDAsIHMwdmFsKTsKCgkvKiBETUEtSW50ZXJydXB0OiBCLWNoYW5uZWwtc3R1ZmYgKi8KCS8qIHNldCBiaXRzIGluIHN2YWwgdG8gaW5kaWNhdGUgd2hpY2ggcGFnZSBpcyBmcmVlICovCglpZiAoaW5sKGNzLT5ody5uamV0LmJhc2UgKyBORVRKRVRfRE1BX1dSSVRFX0FEUikgPAoJCWlubChjcy0+aHcubmpldC5iYXNlICsgTkVUSkVUX0RNQV9XUklURV9JUlEpKQoJCS8qIHRoZSAybmQgd3JpdGUgcGFnZSBpcyBmcmVlICovCgkJczB2YWwgPSAweDA4OwoJZWxzZQkvKiB0aGUgMXN0IHdyaXRlIHBhZ2UgaXMgZnJlZSAqLwoJCXMwdmFsID0gMHgwNDsKCWlmIChpbmwoY3MtPmh3Lm5qZXQuYmFzZSArIE5FVEpFVF9ETUFfUkVBRF9BRFIpIDwKCQlpbmwoY3MtPmh3Lm5qZXQuYmFzZSArIE5FVEpFVF9ETUFfUkVBRF9JUlEpKQoJCS8qIHRoZSAybmQgcmVhZCBwYWdlIGlzIGZyZWUgKi8KCQlzMHZhbCA9IHMwdmFsIHwgMHgwMjsKCWVsc2UJLyogdGhlIDFzdCByZWFkIHBhZ2UgaXMgZnJlZSAqLwoJCXMwdmFsID0gczB2YWwgfCAweDAxOwoJaWYgKHMwdmFsICE9IGNzLT5ody5uamV0Lmxhc3RfaXMwKSAvKiB3ZSBoYXZlIGEgRE1BIGludGVycnVwdCAqLwoJewoJCWlmICh0ZXN0X2FuZF9zZXRfYml0KEZMR19MT0NLX0FUT01JQywgJmNzLT5IV19GbGFncykpIHsKCQkJc3Bpbl91bmxvY2tfaXJxcmVzdG9yZSgmY3MtPmxvY2ssIGZsYWdzKTsKCQkJcmV0dXJuIElSUV9IQU5ETEVEOwoJCX0KCQljcy0+aHcubmpldC5pcnFzdGF0MCA9IHMwdmFsOwoJCWlmICgoY3MtPmh3Lm5qZXQuaXJxc3RhdDAgJiBORVRKRVRfSVJRTTBfUkVBRCkgIT0KCQkJKGNzLT5ody5uamV0Lmxhc3RfaXMwICYgTkVUSkVUX0lSUU0wX1JFQUQpKQoJCQkvKiB3ZSBoYXZlIGEgcmVhZCBkbWEgaW50ICovCgkJCXJlYWRfdGlnZXIoY3MpOwoJCWlmICgoY3MtPmh3Lm5qZXQuaXJxc3RhdDAgJiBORVRKRVRfSVJRTTBfV1JJVEUpICE9CgkJCShjcy0+aHcubmpldC5sYXN0X2lzMCAmIE5FVEpFVF9JUlFNMF9XUklURSkpCgkJCS8qIHdlIGhhdmUgYSB3cml0ZSBkbWEgaW50ICovCgkJCXdyaXRlX3RpZ2VyKGNzKTsKCQl0ZXN0X2FuZF9jbGVhcl9iaXQoRkxHX0xPQ0tfQVRPTUlDLCAmY3MtPkhXX0ZsYWdzKTsKCX0KCXNwaW5fdW5sb2NrX2lycXJlc3RvcmUoJmNzLT5sb2NrLCBmbGFncyk7CglyZXR1cm4gSVJRX0hBTkRMRUQ7Cn0KCgpzdGF0aWMgc3RydWN0IHBjaV9kZXYgKmRldl9uZXRqZXQgX19pbml0ZGF0YSA9IE5VTEw7CgovKiBjYWxsZWQgYnkgY29uZmlnLmMgKi8KaW50IF9faW5pdApzZXR1cF9lbnRlcm5vd19wY2koc3RydWN0IElzZG5DYXJkICpjYXJkKQp7CglpbnQgYnl0ZWNudDsKCXN0cnVjdCBJc2RuQ2FyZFN0YXRlICpjcyA9IGNhcmQtPmNzOwoJY2hhciB0bXBbNjRdOwoKI2lmZGVmIENPTkZJR19QQ0kKI2lmZGVmIF9fQklHX0VORElBTgojZXJyb3IgIm5vdCBydW5uaW5nIG9uIGJpZyBlbmRpYW4gbWFjaGluZXMgbm93IgojZW5kaWYKICAgICAgICBzdHJjcHkodG1wLCBlbnRlcm5vd19wY2lfcmV2KTsKCXByaW50ayhLRVJOX0lORk8gIkhpU2F4OiBGb3JtdWxhLW4gRXVyb3BlIEFHIGVudGVyOm5vdyBJU0ROIFBDSSBkcml2ZXIgUmV2LiAlc1xuIiwgSGlTYXhfZ2V0cmV2KHRtcCkpOwoJaWYgKGNzLT50eXAgIT0gSVNETl9DVFlQRV9FTlRFUk5PVykKCQlyZXR1cm4oMCk7Cgl0ZXN0X2FuZF9jbGVhcl9iaXQoRkxHX0xPQ0tfQVRPTUlDLCAmY3MtPkhXX0ZsYWdzKTsKCglmb3IgKCA7OyApCgl7CgkJaWYgKChkZXZfbmV0amV0ID0gcGNpX2ZpbmRfZGV2aWNlKFBDSV9WRU5ET1JfSURfVElHRVJKRVQsCgkJCVBDSV9ERVZJQ0VfSURfVElHRVJKRVRfMzAwLCAgZGV2X25ldGpldCkpKSB7CgkJCWlmIChwY2lfZW5hYmxlX2RldmljZShkZXZfbmV0amV0KSkKCQkJCXJldHVybigwKTsKCQkJY3MtPmlycSA9IGRldl9uZXRqZXQtPmlycTsKCQkJaWYgKCFjcy0+aXJxKSB7CgkJCQlwcmludGsoS0VSTl9XQVJOSU5HICJlbnRlcjpub3cgUENJOiBObyBJUlEgZm9yIFBDSSBjYXJkIGZvdW5kXG4iKTsKCQkJCXJldHVybigwKTsKCQkJfQoJCQljcy0+aHcubmpldC5iYXNlID0gcGNpX3Jlc291cmNlX3N0YXJ0KGRldl9uZXRqZXQsIDApOwoJCQlpZiAoIWNzLT5ody5uamV0LmJhc2UpIHsKCQkJCXByaW50ayhLRVJOX1dBUk5JTkcgImVudGVyOm5vdyBQQ0k6IE5vIElPLUFkciBmb3IgUENJIGNhcmQgZm91bmRcbiIpOwoJCQkJcmV0dXJuKDApOwoJCQl9CiAgICAgICAgICAgICAgICAgICAgICAgIC8qIGNoZWNrcyBTdWItVmVuZG9yIElEIGJlY2F1c2Ugc3lzdGVtIGNyYXNoZXMgd2l0aCBUcmF2ZXJzZS1DYXJkICovCgkJCWlmICgoZGV2X25ldGpldC0+c3Vic3lzdGVtX3ZlbmRvciAhPSAweDU1KSB8fAoJCQkJKGRldl9uZXRqZXQtPnN1YnN5c3RlbV9kZXZpY2UgIT0gMHgwMikpIHsKCQkJCXByaW50ayhLRVJOX1dBUk5JTkcgImVudGVyOm5vdzogWW91IHRyaWVkIHRvIGxvYWQgdGhpcyBkcml2ZXIgd2l0aCBhbiBpbmNvbXBhdGlibGUgVGlnZXJKZXQtY2FyZFxuIik7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJpbnRrKEtFUk5fV0FSTklORyAiVXNlIHR5cGU9MjAgZm9yIFRyYXZlcnNlIE5ldEpldCBQQ0kgQ2FyZC5cbiIpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybigwKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQoJCX0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHByaW50ayhLRVJOX1dBUk5JTkcgImVudGVyOm5vdyBQQ0k6IE5vIFBDSSBjYXJkIGZvdW5kXG4iKTsKCQkJcmV0dXJuKDApOwoJCX0KCgkJY3MtPmh3Lm5qZXQuYXV4YSA9IGNzLT5ody5uamV0LmJhc2UgKyBORVRKRVRfQVVYREFUQTsKCQljcy0+aHcubmpldC5pc2FjID0gY3MtPmh3Lm5qZXQuYmFzZSArIDB4QzA7IC8vIEZlbnN0ZXIgenVtIEFNRAoKCQkvKiBSZXNldCBhbiAqLwoJCWNzLT5ody5uamV0LmN0cmxfcmVnID0gMHgwNzsgIC8vIGdl5G5kZXJ0IHZvbiAweGZmCgkJT3V0Qnl0ZShjcy0+aHcubmpldC5iYXNlICsgTkVUSkVUX0NUUkwsIGNzLT5ody5uamV0LmN0cmxfcmVnKTsKCQkvKiAyMCBtcyBQYXVzZSAqLwoJCW1kZWxheSgyMCk7CgoJCWNzLT5ody5uamV0LmN0cmxfcmVnID0gMHgzMDsgIC8qIFJlc2V0IE9mZiBhbmQgc3RhdHVzIHJlYWQgY2xlYXIgKi8KCQlPdXRCeXRlKGNzLT5ody5uamV0LmJhc2UgKyBORVRKRVRfQ1RSTCwgY3MtPmh3Lm5qZXQuY3RybF9yZWcpOwoJCW1kZWxheSgxMCk7CgoJCWNzLT5ody5uamV0LmF1eGQgPSAweDAwOyAvLyB3YXIgMHhjMAoJCWNzLT5ody5uamV0LmRtYWN0cmwgPSAwOwoKCQlPdXRCeXRlKGNzLT5ody5uamV0LmJhc2UgKyBORVRKRVRfQVVYQ1RSTCwgflRKX0FNRF9JUlEpOwoJCU91dEJ5dGUoY3MtPmh3Lm5qZXQuYmFzZSArIE5FVEpFVF9JUlFNQVNLMSwgVEpfQU1EX0lSUSk7CgkJT3V0Qnl0ZShjcy0+aHcubmpldC5hdXhhLCBjcy0+aHcubmpldC5hdXhkKTsKCgkJYnJlYWs7Cgl9CiNlbHNlCgoJcHJpbnRrKEtFUk5fV0FSTklORyAiZW50ZXI6bm93IFBDSTogTk9fUENJX0JJT1NcbiIpOwoJcHJpbnRrKEtFUk5fV0FSTklORyAiZW50ZXI6bm93IFBDSTogdW5hYmxlIHRvIGNvbmZpZyBGb3JtdWxhLW4gZW50ZXI6bm93IElTRE4gUENJIGFiXG4iKTsKCXJldHVybiAoMCk7CgojZW5kaWYgLyogQ09ORklHX1BDSSAqLwoKCWJ5dGVjbnQgPSAyNTY7CgoJcHJpbnRrKEtFUk5fSU5GTwoJCSJlbnRlcjpub3cgUENJOiBQQ0kgY2FyZCBjb25maWd1cmVkIGF0IDB4JWx4IElSUSAlZFxuIiwKCQljcy0+aHcubmpldC5iYXNlLCBjcy0+aXJxKTsKCWlmICghcmVxdWVzdF9yZWdpb24oY3MtPmh3Lm5qZXQuYmFzZSwgYnl0ZWNudCwgIkZuX0lTRE4iKSkgewoJCXByaW50ayhLRVJOX1dBUk5JTkcKCQkJICAgIkhpU2F4OiAlcyBjb25maWcgcG9ydCAlbHgtJWx4IGFscmVhZHkgaW4gdXNlXG4iLAoJCQkgICBDYXJkVHlwZVtjYXJkLT50eXBdLAoJCQkgICBjcy0+aHcubmpldC5iYXNlLAoJCQkgICBjcy0+aHcubmpldC5iYXNlICsgYnl0ZWNudCk7CgkJcmV0dXJuICgwKTsKCX0KCXNldHVwX0FtZDc5MzAoY3MpOwoJY3MtPmh3Lm5qZXQubGFzdF9pczAgPSAwOwogICAgICAgIC8qIG1hY3JvIHJCeXRlQU1EICovCiAgICAgICAgY3MtPnJlYWRpc2FjID0gJlJlYWRCeXRlQW1kNzkzMDsKICAgICAgICAvKiBtYWNybyB3Qnl0ZUFNRCAqLwogICAgICAgIGNzLT53cml0ZWlzYWMgPSAmV3JpdGVCeXRlQW1kNzkzMDsKICAgICAgICBjcy0+ZGMuYW1kNzkzMC5zZXRJcnFNYXNrID0gJmVucGNpX3NldElycU1hc2s7CgogICAgICAgIGNzLT5CQ19SZWFkX1JlZyAgPSAmZHVtbXlycjsKCWNzLT5CQ19Xcml0ZV9SZWcgPSAmZHVtbXl3cjsKCWNzLT5CQ19TZW5kX0RhdGEgPSAmbmV0amV0X2ZpbGxfZG1hOwoJY3MtPmNhcmRtc2cgPSAmZW5wY2lfY2FyZF9tc2c7Cgljcy0+aXJxX2Z1bmMgPSAmZW5wY2lfaW50ZXJydXB0OwoJY3MtPmlycV9mbGFncyB8PSBTQV9TSElSUTsKCiAgICAgICAgcmV0dXJuICgxKTsKfQo=