LyogZW50ZXJub3dfcGNpLmMsdiAwLjk5IDIwMDEvMTAvMDIKICoKICogZW50ZXJub3dfcGNpLmMgICAgICAgQ2FyZC1zcGVjaWZpYyByb3V0aW5lcyBmb3IKICogICAgICAgICAgICAgICAgICAgICAgRm9ybXVsYS1uIGVudGVyOm5vdyBJU0ROIFBDSSBhYgogKiAgICAgICAgICAgICAgICAgICAgICBHZXJkZXMgQUcgUG93ZXIgSVNETiBQQ0kKICogICAgICAgICAgICAgICAgICAgICAgV29lcmx0cm9uaWMgU0EgMTYgUENJCiAqICAgICAgICAgICAgICAgICAgICAgIChiYXNlZCBvbiBIaVNheCBkcml2ZXIgYnkgS2Fyc3RlbiBLZWlsKQogKgogKiBBdXRob3IgICAgICAgICAgICAgICBDaHJpc3RvcGggRXJzZmVsZCA8aW5mb0Bmb3JtdWxhLW4uZGU+CiAqICAgICAgICAgICAgICAgICAgICAgIEZvcm11bGEtbiBFdXJvcGUgQUcgKHd3dy5mb3JtdWxhLW4uY29tKQogKiAgICAgICAgICAgICAgICAgICAgICBwcmV2aW91c2x5IEdlcmRlcyBBRwogKgogKgogKiAgICAgICAgICAgICAgICAgICAgICBUaGlzIGZpbGUgaXMgKGMpIHVuZGVyIEdOVSBQVUJMSUMgTElDRU5TRQogKgogKiBOb3RlczoKICogVGhpcyBkcml2ZXIgaW50ZXJmYWNlcyB0byBuZXRqZXQuYyB3aGljaCBwZXJmb3JtcyBCLWNoYW5uZWwKICogcHJvY2Vzc2luZy4KICoKICogVmVyc2lvbiAwLjk5IGlzIHRoZSBmaXJzdCByZWxlYXNlIG9mIHRoaXMgZHJpdmVyIGFuZCB0aGVyZSBhcmUKICogY2VydGFpbmx5IGEgZmV3IGJ1Z3MuCiAqIEl0IGlzbid0IHRlc3RldCBvbiBsaW51eCAyLjQgeWV0LCBzbyBjb25zaWRlciB0aGlzIGNvZGUgdG8gYmUKICogYmV0YS4KICoKICogUGxlYXNlIGRvbid0IHJlcG9ydCBtZSBhbnkgbWFsZnVuY3Rpb24gd2l0aG91dCBzZW5kaW5nCiAqIChjb21wcmVzc2VkKSBkZWJ1Zy1sb2dzLgogKiBJdCB3b3VsZCBiZSBuZWFybHkgaW1wb3NzaWJsZSB0byByZXRyYWNlIGl0LgogKgogKiBMb2cgRC1jaGFubmVsLXByb2Nlc3NpbmcgYXMgZm9sbG93czoKICoKICogMS4gTG9hZCBoaXNheCB3aXRoIGNhcmQtc3BlY2lmaWMgcGFyYW1ldGVycywgdGhpcyBleGFtcGxlIGlzdCBmb3IKICogICAgRm9ybXVsYS1uIGVudGVyOm5vdyBJU0ROIFBDSSBhbmQgY29tcGF0aWJsZQogKiAgICAoZi5lLiBHZXJkZXMgUG93ZXIgSVNETiBQQ0kpCiAqCiAqICAgIG1vZHByb2JlIGhpc2F4IHR5cGU9NDEgcHJvdG9jb2w9MiBpZD1nZXJkZXMKICoKICogICAgaWYgeW91IGNob3NlIGFuIG90aGVyIHZhbHVlIGZvciBpZCwgeW91IG5lZWQgdG8gbW9kaWZ5IHRoZQogKiAgICBjb2RlIGJlbG93LCB0b28uCiAqCiAqIDIuIHNldCBkZWJ1Zy1sZXZlbAogKgogKiAgICBoaXNheGN0cmwgZ2VyZGVzIDEgMHgzZmYKICogICAgaGlzYXhjdHJsIGdlcmRlcyAxMSAweDRmCiAqICAgIGNhdCAvZGV2L2lzZG5jdHJsID4+IH4vbG9nICYKICoKICogUGxlYXNlIHRha2UgYWxzbyBhIGxvb2sgaW50byAvdmFyL2xvZy9tZXNzYWdlcyBpZiB0aGVyZSBpcwogKiBhbnl0aGluZyBpbXBvcnRhbmQgY29uY2VybmluZyBISVNBWC4KICoKICoKICogQ3JlZGl0czoKICogUHJvZ3JhbW1pbmcgdGhlIGRyaXZlciBmb3IgRm9ybXVsYS1uIGVudGVyOm5vdyBJU0ROIFBDSSBhbmQKICogbmVjZXNzYXJ5IHRoZSBkcml2ZXIgZm9yIHRoZSB1c2VkIEFtZCA3OTMwIEQtY2hhbm5lbC1jb250cm9sbGVyCiAqIHdhcyBzcG5zb3JlZCBieSBGb3JtdWxhLW4gRXVyb3BlIEFHLgogKiBUaGFua3MgdG8gS2Fyc3RlbiBLZWlsIGFuZCBQZXRyIE5vdmFrLCB3aG8gZ2F2ZSBtZSBzdXBwb3J0IGluCiAqIEhpc2F4LXNwZWNpZmljIHF1ZXN0aW9ucy4KICogSSB3YW50IHNvIHNheSBzcGVjaWFsIHRoYW5rcyB0byBDYXJsLUZyaWVkcmljaCBCcmF1biwgd2hvIGhhZCB0bwogKiBhbnN3ZXIgYSBsb3Qgb2YgcXVlc3Rpb25zIGFib3V0IGdlbmVyYWxseSBJU0ROIGFuZCBhYm91dCBoYW5kbGluZwogKiBvZiB0aGUgQW1kLUNoaXAuCiAqCiAqLwoKCiNpbmNsdWRlICJoaXNheC5oIgojaW5jbHVkZSAiaXNhYy5oIgojaW5jbHVkZSAiaXNkbmwxLmgiCiNpbmNsdWRlICJhbWQ3OTMwX2ZuLmgiCiNpbmNsdWRlIDxsaW51eC9pbnRlcnJ1cHQuaD4KI2luY2x1ZGUgPGxpbnV4L3BwcF9kZWZzLmg+CiNpbmNsdWRlIDxsaW51eC9wY2kuaD4KI2luY2x1ZGUgPGxpbnV4L2luaXQuaD4KI2luY2x1ZGUgIm5ldGpldC5oIgoKCgpzdGF0aWMgY29uc3QgY2hhciAqZW50ZXJub3dfcGNpX3JldiA9ICIkUmV2aXNpb246IDEuMS40LjUgJCI7CgoKLyogZvxyIFBvd2VySVNETiBQQ0kgKi8KI2RlZmluZSBUSl9BTURfSVJRICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDB4MjAKI2RlZmluZSBUSl9MRUQxICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDB4NDAKI2RlZmluZSBUSl9MRUQyICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDB4ODAKCgovKiBEYXMgRmVuc3RlciB6dW0gQU1ELi4uCiAqIEFiIEFkcmVzc2UgaHcubmpldC5iYXNlICsgVEpfQU1EX1BPUlQgd2VyZGVuIHZvbSBBTUQgamV3ZWlscyA4IEJpdCBpbgogKiBkZW4gVGlnZXJKZXQgaS9vLVJhdW0gZ2VtYXBwdAogKiAtPiAweDAxIGRlcyBBTUQgYmVpIGh3Lm5qZXQuYmFzZSArIDBDNCAqLwojZGVmaW5lIFRKX0FNRF9QT1JUICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMHhDMAoKCgovKiAqKioqKioqKioqKioqKioqKioqKioqKioqKiogSS9PLUludGVyZmFjZSBmdW5jdGlvbnMgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiAqLwoKCi8qIGNzLT5yZWFkaXNhYywgbWFjcm8gckJ5dGVBTUQgKi8Kc3RhdGljIHVuc2lnbmVkIGNoYXIKUmVhZEJ5dGVBbWQ3OTMwKHN0cnVjdCBJc2RuQ2FyZFN0YXRlICpjcywgdW5zaWduZWQgY2hhciBvZmZzZXQpCnsKCS8qIGRpcmVrdGVzIFJlZ2lzdGVyICovCglpZihvZmZzZXQgPCA4KQoJCXJldHVybiAoaW5iKGNzLT5ody5uamV0LmlzYWMgKyA0Km9mZnNldCkpOwoKCS8qIGluZGlyZWt0ZXMgUmVnaXN0ZXIgKi8KCWVsc2UgewoJCW91dGIob2Zmc2V0LCBjcy0+aHcubmpldC5pc2FjICsgNCpBTURfQ1IpOwoJCXJldHVybihpbmIoY3MtPmh3Lm5qZXQuaXNhYyArIDQqQU1EX0RSKSk7Cgl9Cn0KCi8qIGNzLT53cml0ZWlzYWMsIG1hY3JvIHdCeXRlQU1EICovCnN0YXRpYyB2b2lkCldyaXRlQnl0ZUFtZDc5MzAoc3RydWN0IElzZG5DYXJkU3RhdGUgKmNzLCB1bnNpZ25lZCBjaGFyIG9mZnNldCwgdW5zaWduZWQgY2hhciB2YWx1ZSkKewoJLyogZGlyZWt0ZXMgUmVnaXN0ZXIgKi8KCWlmKG9mZnNldCA8IDgpCgkJb3V0Yih2YWx1ZSwgY3MtPmh3Lm5qZXQuaXNhYyArIDQqb2Zmc2V0KTsKCgkvKiBpbmRpcmVrdGVzIFJlZ2lzdGVyICovCgllbHNlIHsKCQlvdXRiKG9mZnNldCwgY3MtPmh3Lm5qZXQuaXNhYyArIDQqQU1EX0NSKTsKCQlvdXRiKHZhbHVlLCBjcy0+aHcubmpldC5pc2FjICsgNCpBTURfRFIpOwoJfQp9CgoKc3RhdGljIHZvaWQKZW5wY2lfc2V0SXJxTWFzayhzdHJ1Y3QgSXNkbkNhcmRTdGF0ZSAqY3MsIHVuc2lnbmVkIGNoYXIgdmFsKSB7CiAgICAgICAgaWYgKCF2YWwpCgkgICAgICAgIG91dGIoMHgwMCwgY3MtPmh3Lm5qZXQuYmFzZStORVRKRVRfSVJRTUFTSzEpOwogICAgICAgIGVsc2UKCSAgICAgICAgb3V0YihUSl9BTURfSVJRLCBjcy0+aHcubmpldC5iYXNlK05FVEpFVF9JUlFNQVNLMSk7Cn0KCgpzdGF0aWMgdW5zaWduZWQgY2hhciBkdW1teXJyKHN0cnVjdCBJc2RuQ2FyZFN0YXRlICpjcywgaW50IGNoYW4sIHVuc2lnbmVkIGNoYXIgb2ZmKQp7CiAgICAgICAgcmV0dXJuKDUpOwp9CgpzdGF0aWMgdm9pZCBkdW1teXdyKHN0cnVjdCBJc2RuQ2FyZFN0YXRlICpjcywgaW50IGNoYW4sIHVuc2lnbmVkIGNoYXIgb2ZmLCB1bnNpZ25lZCBjaGFyIHZhbHVlKQp7Cgp9CgoKLyogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiogKi8KCgpzdGF0aWMgdm9pZApyZXNldF9lbnBjaShzdHJ1Y3QgSXNkbkNhcmRTdGF0ZSAqY3MpCnsKCWlmIChjcy0+ZGVidWcgJiBMMV9ERUJfSVNBQykKCQlkZWJ1Z2wxKGNzLCAiZW50ZXI6bm93IFBDSTogcmVzZXQiKTsKCgkvKiBSZXNldCBvbiwgKGFsc28gZm9yIEFNRCkgKi8KCWNzLT5ody5uamV0LmN0cmxfcmVnID0gMHgwNzsKCW91dGIoY3MtPmh3Lm5qZXQuY3RybF9yZWcsIGNzLT5ody5uamV0LmJhc2UgKyBORVRKRVRfQ1RSTCk7CgltZGVsYXkoMjApOwoJLyogUmVzZXQgb2ZmICovCgljcy0+aHcubmpldC5jdHJsX3JlZyA9IDB4MzA7CglvdXRiKGNzLT5ody5uamV0LmN0cmxfcmVnLCBjcy0+aHcubmpldC5iYXNlICsgTkVUSkVUX0NUUkwpOwoJLyogMjBtcyBkZWxheSAqLwoJbWRlbGF5KDIwKTsKCWNzLT5ody5uamV0LmF1eGQgPSAwOyAgLy8gTEVELXN0YXR1cwoJY3MtPmh3Lm5qZXQuZG1hY3RybCA9IDA7CglvdXRiKH5USl9BTURfSVJRLCBjcy0+aHcubmpldC5iYXNlICsgTkVUSkVUX0FVWENUUkwpOwoJb3V0YihUSl9BTURfSVJRLCBjcy0+aHcubmpldC5iYXNlICsgTkVUSkVUX0lSUU1BU0sxKTsKCW91dGIoY3MtPmh3Lm5qZXQuYXV4ZCwgY3MtPmh3Lm5qZXQuYXV4YSk7IC8vIExFRCBvZmYKfQoKCnN0YXRpYyBpbnQKZW5wY2lfY2FyZF9tc2coc3RydWN0IElzZG5DYXJkU3RhdGUgKmNzLCBpbnQgbXQsIHZvaWQgKmFyZykKewoJdV9sb25nIGZsYWdzOwogICAgICAgIHVuc2lnbmVkIGNoYXIgKmNoYW47CgoJaWYgKGNzLT5kZWJ1ZyAmIEwxX0RFQl9JU0FDKQoJCWRlYnVnbDEoY3MsICJlbnRlcjpub3cgUENJOiBjYXJkX21zZzogMHglMDRYIiwgbXQpOwoKICAgICAgICBzd2l0Y2ggKG10KSB7CgkJY2FzZSBDQVJEX1JFU0VUOgoJCQlzcGluX2xvY2tfaXJxc2F2ZSgmY3MtPmxvY2ssIGZsYWdzKTsKCQkJcmVzZXRfZW5wY2koY3MpOwogICAgICAgICAgICAgICAgICAgICAgICBBbWQ3OTMwX2luaXQoY3MpOwogICAgICAgICAgICAgICAgICAgICAgICBzcGluX3VubG9ja19pcnFyZXN0b3JlKCZjcy0+bG9jaywgZmxhZ3MpOwoJCQlicmVhazsKCQljYXNlIENBUkRfUkVMRUFTRToKCQkJcmVsZWFzZV9pb19uZXRqZXQoY3MpOwoJCQlicmVhazsKCQljYXNlIENBUkRfSU5JVDoKCQkJcmVzZXRfZW5wY2koY3MpOwoJCQlpbml0dGlnZXIoY3MpOwoJCQkvKiBpcnEgbXVzdCBiZSBvbiBoZXJlICovCgkJCUFtZDc5MzBfaW5pdChjcyk7CgkJCWJyZWFrOwoJCWNhc2UgQ0FSRF9URVNUOgoJCQlicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgTURMX0FTU0lHTjoKICAgICAgICAgICAgICAgICAgICAgICAgLyogVEVJIGFzc2lnbmVkLCBMRUQxIG9uICovCiAgICAgICAgICAgICAgICAgICAgICAgIGNzLT5ody5uamV0LmF1eGQgPSBUSl9BTURfSVJRIDw8IDE7CiAgICAgICAgICAgICAgICAgICAgICAgIG91dGIoY3MtPmh3Lm5qZXQuYXV4ZCwgY3MtPmh3Lm5qZXQuYmFzZSArIE5FVEpFVF9BVVhEQVRBKTsKICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlIE1ETF9SRU1PVkU6CiAgICAgICAgICAgICAgICAgICAgICAgIC8qIFRFSSByZW1vdmVkLCBMRURzIG9mZiAqLwoJICAgICAgICAgICAgICAgIGNzLT5ody5uamV0LmF1eGQgPSAwOwogICAgICAgICAgICAgICAgICAgICAgICBvdXRiKDB4MDAsIGNzLT5ody5uamV0LmJhc2UgKyBORVRKRVRfQVVYREFUQSk7CiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSBNRExfQkNfQVNTSUdOOgogICAgICAgICAgICAgICAgICAgICAgICAvKiBhY3RpdmF0ZSBCLWNoYW5uZWwgKi8KICAgICAgICAgICAgICAgICAgICAgICAgY2hhbiA9ICh1bnNpZ25lZCBjaGFyICopYXJnOwoKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGNzLT5kZWJ1ZyAmIEwxX0RFQl9JU0FDKQoJCSAgICAgICAgICAgICAgICBkZWJ1Z2wxKGNzLCAiZW50ZXI6bm93IFBDSTogYXNzaWduIHBoeXMuIEJDICVkIGluIEFNRCBMTVIxIiwgKmNoYW4pOwoKICAgICAgICAgICAgICAgICAgICAgICAgY3MtPmRjLmFtZDc5MzAucGhfY29tbWFuZChjcywgKGNzLT5kYy5hbWQ3OTMwLmxtcjEgfCAoKmNoYW4gKyAxKSksICJNRExfQkNfQVNTSUdOIik7CiAgICAgICAgICAgICAgICAgICAgICAgIC8qIGF0IGxlYXN0IG9uZSBiLWNoYW5uZWwgaW4gdXNlLCBMRUQgMiBvbiAqLwogICAgICAgICAgICAgICAgICAgICAgICBjcy0+aHcubmpldC5hdXhkIHw9IFRKX0FNRF9JUlEgPDwgMjsKICAgICAgICAgICAgICAgICAgICAgICAgb3V0Yihjcy0+aHcubmpldC5hdXhkLCBjcy0+aHcubmpldC5iYXNlICsgTkVUSkVUX0FVWERBVEEpOwogICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgTURMX0JDX1JFTEVBU0U6CiAgICAgICAgICAgICAgICAgICAgICAgIC8qIGRlYWN0aXZhdGUgQi1jaGFubmVsICovCiAgICAgICAgICAgICAgICAgICAgICAgIGNoYW4gPSAodW5zaWduZWQgY2hhciAqKWFyZzsKCiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChjcy0+ZGVidWcgJiBMMV9ERUJfSVNBQykKCQkgICAgICAgICAgICAgICAgZGVidWdsMShjcywgImVudGVyOm5vdyBQQ0k6IHJlbGVhc2UgcGh5cy4gQkMgJWQgaW4gQW1kIExNUjEiLCAqY2hhbik7CgogICAgICAgICAgICAgICAgICAgICAgICBjcy0+ZGMuYW1kNzkzMC5waF9jb21tYW5kKGNzLCAoY3MtPmRjLmFtZDc5MzAubG1yMSAmIH4oKmNoYW4gKyAxKSksICJNRExfQkNfUkVMRUFTRSIpOwogICAgICAgICAgICAgICAgICAgICAgICAvKiBubyBiLWNoYW5uZWwgYWN0aXZlIC0+IExFRDIgb2ZmICovCiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghKGNzLT5kYy5hbWQ3OTMwLmxtcjEgJiAzKSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNzLT5ody5uamV0LmF1eGQgJj0gfihUSl9BTURfSVJRIDw8IDIpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG91dGIoY3MtPmh3Lm5qZXQuYXV4ZCwgY3MtPmh3Lm5qZXQuYmFzZSArIE5FVEpFVF9BVVhEQVRBKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwoKCX0KCXJldHVybigwKTsKfQoKc3RhdGljIGlycXJldHVybl90CmVucGNpX2ludGVycnVwdChpbnQgaW50bm8sIHZvaWQgKmRldl9pZCkKewoJc3RydWN0IElzZG5DYXJkU3RhdGUgKmNzID0gZGV2X2lkOwoJdW5zaWduZWQgY2hhciBzMHZhbCwgczF2YWwsIGlyOwoJdV9sb25nIGZsYWdzOwoKCXNwaW5fbG9ja19pcnFzYXZlKCZjcy0+bG9jaywgZmxhZ3MpOwoJczF2YWwgPSBpbmIoY3MtPmh3Lm5qZXQuYmFzZSArIE5FVEpFVF9JUlFTVEFUMSk7CgogICAgICAgIC8qIEFNRCB0aHJldyBhbiBpbnRlcnJ1cHQgKi8KCWlmICghKHMxdmFsICYgVEpfQU1EX0lSUSkpIHsKICAgICAgICAgICAgICAgIC8qIHJlYWQgYW5kIGNsZWFyIGludGVycnVwdC1yZWdpc3RlciAqLwoJCWlyID0gUmVhZEJ5dGVBbWQ3OTMwKGNzLCAweDAwKTsKCQlBbWQ3OTMwX2ludGVycnVwdChjcywgaXIpOwoJCXMxdmFsID0gMTsKCX0gZWxzZQoJCXMxdmFsID0gMDsKCXMwdmFsID0gaW5iKGNzLT5ody5uamV0LmJhc2UgKyBORVRKRVRfSVJRU1RBVDApOwoJaWYgKChzMHZhbCB8IHMxdmFsKT09MCkgeyAvLyBzaGFyZWQgSVJRCgkJc3Bpbl91bmxvY2tfaXJxcmVzdG9yZSgmY3MtPmxvY2ssIGZsYWdzKTsKCQlyZXR1cm4gSVJRX05PTkU7Cgl9IAoJaWYgKHMwdmFsKQoJCW91dGIoczB2YWwsIGNzLT5ody5uamV0LmJhc2UgKyBORVRKRVRfSVJRU1RBVDApOwoKCS8qIERNQS1JbnRlcnJ1cHQ6IEItY2hhbm5lbC1zdHVmZiAqLwoJLyogc2V0IGJpdHMgaW4gc3ZhbCB0byBpbmRpY2F0ZSB3aGljaCBwYWdlIGlzIGZyZWUgKi8KCWlmIChpbmwoY3MtPmh3Lm5qZXQuYmFzZSArIE5FVEpFVF9ETUFfV1JJVEVfQURSKSA8CgkJaW5sKGNzLT5ody5uamV0LmJhc2UgKyBORVRKRVRfRE1BX1dSSVRFX0lSUSkpCgkJLyogdGhlIDJuZCB3cml0ZSBwYWdlIGlzIGZyZWUgKi8KCQlzMHZhbCA9IDB4MDg7CgllbHNlCS8qIHRoZSAxc3Qgd3JpdGUgcGFnZSBpcyBmcmVlICovCgkJczB2YWwgPSAweDA0OwoJaWYgKGlubChjcy0+aHcubmpldC5iYXNlICsgTkVUSkVUX0RNQV9SRUFEX0FEUikgPAoJCWlubChjcy0+aHcubmpldC5iYXNlICsgTkVUSkVUX0RNQV9SRUFEX0lSUSkpCgkJLyogdGhlIDJuZCByZWFkIHBhZ2UgaXMgZnJlZSAqLwoJCXMwdmFsID0gczB2YWwgfCAweDAyOwoJZWxzZQkvKiB0aGUgMXN0IHJlYWQgcGFnZSBpcyBmcmVlICovCgkJczB2YWwgPSBzMHZhbCB8IDB4MDE7CglpZiAoczB2YWwgIT0gY3MtPmh3Lm5qZXQubGFzdF9pczApIC8qIHdlIGhhdmUgYSBETUEgaW50ZXJydXB0ICovCgl7CgkJaWYgKHRlc3RfYW5kX3NldF9iaXQoRkxHX0xPQ0tfQVRPTUlDLCAmY3MtPkhXX0ZsYWdzKSkgewoJCQlzcGluX3VubG9ja19pcnFyZXN0b3JlKCZjcy0+bG9jaywgZmxhZ3MpOwoJCQlyZXR1cm4gSVJRX0hBTkRMRUQ7CgkJfQoJCWNzLT5ody5uamV0LmlycXN0YXQwID0gczB2YWw7CgkJaWYgKChjcy0+aHcubmpldC5pcnFzdGF0MCAmIE5FVEpFVF9JUlFNMF9SRUFEKSAhPQoJCQkoY3MtPmh3Lm5qZXQubGFzdF9pczAgJiBORVRKRVRfSVJRTTBfUkVBRCkpCgkJCS8qIHdlIGhhdmUgYSByZWFkIGRtYSBpbnQgKi8KCQkJcmVhZF90aWdlcihjcyk7CgkJaWYgKChjcy0+aHcubmpldC5pcnFzdGF0MCAmIE5FVEpFVF9JUlFNMF9XUklURSkgIT0KCQkJKGNzLT5ody5uamV0Lmxhc3RfaXMwICYgTkVUSkVUX0lSUU0wX1dSSVRFKSkKCQkJLyogd2UgaGF2ZSBhIHdyaXRlIGRtYSBpbnQgKi8KCQkJd3JpdGVfdGlnZXIoY3MpOwoJCXRlc3RfYW5kX2NsZWFyX2JpdChGTEdfTE9DS19BVE9NSUMsICZjcy0+SFdfRmxhZ3MpOwoJfQoJc3Bpbl91bmxvY2tfaXJxcmVzdG9yZSgmY3MtPmxvY2ssIGZsYWdzKTsKCXJldHVybiBJUlFfSEFORExFRDsKfQoKCnN0YXRpYyBzdHJ1Y3QgcGNpX2RldiAqZGV2X25ldGpldCBfX2RldmluaXRkYXRhID0gTlVMTDsKCi8qIGNhbGxlZCBieSBjb25maWcuYyAqLwppbnQgX19kZXZpbml0CnNldHVwX2VudGVybm93X3BjaShzdHJ1Y3QgSXNkbkNhcmQgKmNhcmQpCnsKCWludCBieXRlY250OwoJc3RydWN0IElzZG5DYXJkU3RhdGUgKmNzID0gY2FyZC0+Y3M7CgljaGFyIHRtcFs2NF07CgojaWZkZWYgQ09ORklHX1BDSQojaWZkZWYgX19CSUdfRU5ESUFOCiNlcnJvciAibm90IHJ1bm5pbmcgb24gYmlnIGVuZGlhbiBtYWNoaW5lcyBub3ciCiNlbmRpZgogICAgICAgIHN0cmNweSh0bXAsIGVudGVybm93X3BjaV9yZXYpOwoJcHJpbnRrKEtFUk5fSU5GTyAiSGlTYXg6IEZvcm11bGEtbiBFdXJvcGUgQUcgZW50ZXI6bm93IElTRE4gUENJIGRyaXZlciBSZXYuICVzXG4iLCBIaVNheF9nZXRyZXYodG1wKSk7CglpZiAoY3MtPnR5cCAhPSBJU0ROX0NUWVBFX0VOVEVSTk9XKQoJCXJldHVybigwKTsKCXRlc3RfYW5kX2NsZWFyX2JpdChGTEdfTE9DS19BVE9NSUMsICZjcy0+SFdfRmxhZ3MpOwoKCWZvciAoIDs7ICkKCXsKCQlpZiAoKGRldl9uZXRqZXQgPSBwY2lfZmluZF9kZXZpY2UoUENJX1ZFTkRPUl9JRF9USUdFUkpFVCwKCQkJUENJX0RFVklDRV9JRF9USUdFUkpFVF8zMDAsICBkZXZfbmV0amV0KSkpIHsKCQkJaWYgKHBjaV9lbmFibGVfZGV2aWNlKGRldl9uZXRqZXQpKQoJCQkJcmV0dXJuKDApOwoJCQljcy0+aXJxID0gZGV2X25ldGpldC0+aXJxOwoJCQlpZiAoIWNzLT5pcnEpIHsKCQkJCXByaW50ayhLRVJOX1dBUk5JTkcgImVudGVyOm5vdyBQQ0k6IE5vIElSUSBmb3IgUENJIGNhcmQgZm91bmRcbiIpOwoJCQkJcmV0dXJuKDApOwoJCQl9CgkJCWNzLT5ody5uamV0LmJhc2UgPSBwY2lfcmVzb3VyY2Vfc3RhcnQoZGV2X25ldGpldCwgMCk7CgkJCWlmICghY3MtPmh3Lm5qZXQuYmFzZSkgewoJCQkJcHJpbnRrKEtFUk5fV0FSTklORyAiZW50ZXI6bm93IFBDSTogTm8gSU8tQWRyIGZvciBQQ0kgY2FyZCBmb3VuZFxuIik7CgkJCQlyZXR1cm4oMCk7CgkJCX0KICAgICAgICAgICAgICAgICAgICAgICAgLyogY2hlY2tzIFN1Yi1WZW5kb3IgSUQgYmVjYXVzZSBzeXN0ZW0gY3Jhc2hlcyB3aXRoIFRyYXZlcnNlLUNhcmQgKi8KCQkJaWYgKChkZXZfbmV0amV0LT5zdWJzeXN0ZW1fdmVuZG9yICE9IDB4NTUpIHx8CgkJCQkoZGV2X25ldGpldC0+c3Vic3lzdGVtX2RldmljZSAhPSAweDAyKSkgewoJCQkJcHJpbnRrKEtFUk5fV0FSTklORyAiZW50ZXI6bm93OiBZb3UgdHJpZWQgdG8gbG9hZCB0aGlzIGRyaXZlciB3aXRoIGFuIGluY29tcGF0aWJsZSBUaWdlckpldC1jYXJkXG4iKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwcmludGsoS0VSTl9XQVJOSU5HICJVc2UgdHlwZT0yMCBmb3IgVHJhdmVyc2UgTmV0SmV0IFBDSSBDYXJkLlxuIik7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuKDApOwogICAgICAgICAgICAgICAgICAgICAgICB9CgkJfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgcHJpbnRrKEtFUk5fV0FSTklORyAiZW50ZXI6bm93IFBDSTogTm8gUENJIGNhcmQgZm91bmRcbiIpOwoJCQlyZXR1cm4oMCk7CgkJfQoKCQljcy0+aHcubmpldC5hdXhhID0gY3MtPmh3Lm5qZXQuYmFzZSArIE5FVEpFVF9BVVhEQVRBOwoJCWNzLT5ody5uamV0LmlzYWMgPSBjcy0+aHcubmpldC5iYXNlICsgMHhDMDsgLy8gRmVuc3RlciB6dW0gQU1ECgoJCS8qIFJlc2V0IGFuICovCgkJY3MtPmh3Lm5qZXQuY3RybF9yZWcgPSAweDA3OyAgLy8gZ2XkbmRlcnQgdm9uIDB4ZmYKCQlvdXRiKGNzLT5ody5uamV0LmN0cmxfcmVnLCBjcy0+aHcubmpldC5iYXNlICsgTkVUSkVUX0NUUkwpOwoJCS8qIDIwIG1zIFBhdXNlICovCgkJbWRlbGF5KDIwKTsKCgkJY3MtPmh3Lm5qZXQuY3RybF9yZWcgPSAweDMwOyAgLyogUmVzZXQgT2ZmIGFuZCBzdGF0dXMgcmVhZCBjbGVhciAqLwoJCW91dGIoY3MtPmh3Lm5qZXQuY3RybF9yZWcsIGNzLT5ody5uamV0LmJhc2UgKyBORVRKRVRfQ1RSTCk7CgkJbWRlbGF5KDEwKTsKCgkJY3MtPmh3Lm5qZXQuYXV4ZCA9IDB4MDA7IC8vIHdhciAweGMwCgkJY3MtPmh3Lm5qZXQuZG1hY3RybCA9IDA7CgoJCW91dGIoflRKX0FNRF9JUlEsIGNzLT5ody5uamV0LmJhc2UgKyBORVRKRVRfQVVYQ1RSTCk7CgkJb3V0YihUSl9BTURfSVJRLCBjcy0+aHcubmpldC5iYXNlICsgTkVUSkVUX0lSUU1BU0sxKTsKCQlvdXRiKGNzLT5ody5uamV0LmF1eGQsIGNzLT5ody5uamV0LmF1eGEpOwoKCQlicmVhazsKCX0KI2Vsc2UKCglwcmludGsoS0VSTl9XQVJOSU5HICJlbnRlcjpub3cgUENJOiBOT19QQ0lfQklPU1xuIik7CglwcmludGsoS0VSTl9XQVJOSU5HICJlbnRlcjpub3cgUENJOiB1bmFibGUgdG8gY29uZmlnIEZvcm11bGEtbiBlbnRlcjpub3cgSVNETiBQQ0kgYWJcbiIpOwoJcmV0dXJuICgwKTsKCiNlbmRpZiAvKiBDT05GSUdfUENJICovCgoJYnl0ZWNudCA9IDI1NjsKCglwcmludGsoS0VSTl9JTkZPCgkJImVudGVyOm5vdyBQQ0k6IFBDSSBjYXJkIGNvbmZpZ3VyZWQgYXQgMHglbHggSVJRICVkXG4iLAoJCWNzLT5ody5uamV0LmJhc2UsIGNzLT5pcnEpOwoJaWYgKCFyZXF1ZXN0X3JlZ2lvbihjcy0+aHcubmpldC5iYXNlLCBieXRlY250LCAiRm5fSVNETiIpKSB7CgkJcHJpbnRrKEtFUk5fV0FSTklORwoJCQkgICAiSGlTYXg6ICVzIGNvbmZpZyBwb3J0ICVseC0lbHggYWxyZWFkeSBpbiB1c2VcbiIsCgkJCSAgIENhcmRUeXBlW2NhcmQtPnR5cF0sCgkJCSAgIGNzLT5ody5uamV0LmJhc2UsCgkJCSAgIGNzLT5ody5uamV0LmJhc2UgKyBieXRlY250KTsKCQlyZXR1cm4gKDApOwoJfQoJc2V0dXBfQW1kNzkzMChjcyk7Cgljcy0+aHcubmpldC5sYXN0X2lzMCA9IDA7CiAgICAgICAgLyogbWFjcm8gckJ5dGVBTUQgKi8KICAgICAgICBjcy0+cmVhZGlzYWMgPSAmUmVhZEJ5dGVBbWQ3OTMwOwogICAgICAgIC8qIG1hY3JvIHdCeXRlQU1EICovCiAgICAgICAgY3MtPndyaXRlaXNhYyA9ICZXcml0ZUJ5dGVBbWQ3OTMwOwogICAgICAgIGNzLT5kYy5hbWQ3OTMwLnNldElycU1hc2sgPSAmZW5wY2lfc2V0SXJxTWFzazsKCiAgICAgICAgY3MtPkJDX1JlYWRfUmVnICA9ICZkdW1teXJyOwoJY3MtPkJDX1dyaXRlX1JlZyA9ICZkdW1teXdyOwoJY3MtPkJDX1NlbmRfRGF0YSA9ICZuZXRqZXRfZmlsbF9kbWE7Cgljcy0+Y2FyZG1zZyA9ICZlbnBjaV9jYXJkX21zZzsKCWNzLT5pcnFfZnVuYyA9ICZlbnBjaV9pbnRlcnJ1cHQ7Cgljcy0+aXJxX2ZsYWdzIHw9IElSUUZfU0hBUkVEOwoKICAgICAgICByZXR1cm4gKDEpOwp9Cg==