LyogZW50ZXJub3dfcGNpLmMsdiAwLjk5IDIwMDEvMTAvMDIKICoKICogZW50ZXJub3dfcGNpLmMgICAgICAgQ2FyZC1zcGVjaWZpYyByb3V0aW5lcyBmb3IKICogICAgICAgICAgICAgICAgICAgICAgRm9ybXVsYS1uIGVudGVyOm5vdyBJU0ROIFBDSSBhYgogKiAgICAgICAgICAgICAgICAgICAgICBHZXJkZXMgQUcgUG93ZXIgSVNETiBQQ0kKICogICAgICAgICAgICAgICAgICAgICAgV29lcmx0cm9uaWMgU0EgMTYgUENJCiAqICAgICAgICAgICAgICAgICAgICAgIChiYXNlZCBvbiBIaVNheCBkcml2ZXIgYnkgS2Fyc3RlbiBLZWlsKQogKgogKiBBdXRob3IgICAgICAgICAgICAgICBDaHJpc3RvcGggRXJzZmVsZCA8aW5mb0Bmb3JtdWxhLW4uZGU+CiAqICAgICAgICAgICAgICAgICAgICAgIEZvcm11bGEtbiBFdXJvcGUgQUcgKHd3dy5mb3JtdWxhLW4uY29tKQogKiAgICAgICAgICAgICAgICAgICAgICBwcmV2aW91c2x5IEdlcmRlcyBBRwogKgogKgogKiAgICAgICAgICAgICAgICAgICAgICBUaGlzIGZpbGUgaXMgKGMpIHVuZGVyIEdOVSBQVUJMSUMgTElDRU5TRQogKgogKiBOb3RlczoKICogVGhpcyBkcml2ZXIgaW50ZXJmYWNlcyB0byBuZXRqZXQuYyB3aGljaCBwZXJmb3JtcyBCLWNoYW5uZWwKICogcHJvY2Vzc2luZy4KICoKICogVmVyc2lvbiAwLjk5IGlzIHRoZSBmaXJzdCByZWxlYXNlIG9mIHRoaXMgZHJpdmVyIGFuZCB0aGVyZSBhcmUKICogY2VydGFpbmx5IGEgZmV3IGJ1Z3MuCiAqIEl0IGlzbid0IHRlc3RldCBvbiBsaW51eCAyLjQgeWV0LCBzbyBjb25zaWRlciB0aGlzIGNvZGUgdG8gYmUKICogYmV0YS4KICoKICogUGxlYXNlIGRvbid0IHJlcG9ydCBtZSBhbnkgbWFsZnVuY3Rpb24gd2l0aG91dCBzZW5kaW5nCiAqIChjb21wcmVzc2VkKSBkZWJ1Zy1sb2dzLgogKiBJdCB3b3VsZCBiZSBuZWFybHkgaW1wb3NzaWJsZSB0byByZXRyYWNlIGl0LgogKgogKiBMb2cgRC1jaGFubmVsLXByb2Nlc3NpbmcgYXMgZm9sbG93czoKICoKICogMS4gTG9hZCBoaXNheCB3aXRoIGNhcmQtc3BlY2lmaWMgcGFyYW1ldGVycywgdGhpcyBleGFtcGxlIGlzdCBmb3IKICogICAgRm9ybXVsYS1uIGVudGVyOm5vdyBJU0ROIFBDSSBhbmQgY29tcGF0aWJsZQogKiAgICAoZi5lLiBHZXJkZXMgUG93ZXIgSVNETiBQQ0kpCiAqCiAqICAgIG1vZHByb2JlIGhpc2F4IHR5cGU9NDEgcHJvdG9jb2w9MiBpZD1nZXJkZXMKICoKICogICAgaWYgeW91IGNob3NlIGFuIG90aGVyIHZhbHVlIGZvciBpZCwgeW91IG5lZWQgdG8gbW9kaWZ5IHRoZQogKiAgICBjb2RlIGJlbG93LCB0b28uCiAqCiAqIDIuIHNldCBkZWJ1Zy1sZXZlbAogKgogKiAgICBoaXNheGN0cmwgZ2VyZGVzIDEgMHgzZmYKICogICAgaGlzYXhjdHJsIGdlcmRlcyAxMSAweDRmCiAqICAgIGNhdCAvZGV2L2lzZG5jdHJsID4+IH4vbG9nICYKICoKICogUGxlYXNlIHRha2UgYWxzbyBhIGxvb2sgaW50byAvdmFyL2xvZy9tZXNzYWdlcyBpZiB0aGVyZSBpcwogKiBhbnl0aGluZyBpbXBvcnRhbmQgY29uY2VybmluZyBISVNBWC4KICoKICoKICogQ3JlZGl0czoKICogUHJvZ3JhbW1pbmcgdGhlIGRyaXZlciBmb3IgRm9ybXVsYS1uIGVudGVyOm5vdyBJU0ROIFBDSSBhbmQKICogbmVjZXNzYXJ5IHRoZSBkcml2ZXIgZm9yIHRoZSB1c2VkIEFtZCA3OTMwIEQtY2hhbm5lbC1jb250cm9sbGVyCiAqIHdhcyBzcG5zb3JlZCBieSBGb3JtdWxhLW4gRXVyb3BlIEFHLgogKiBUaGFua3MgdG8gS2Fyc3RlbiBLZWlsIGFuZCBQZXRyIE5vdmFrLCB3aG8gZ2F2ZSBtZSBzdXBwb3J0IGluCiAqIEhpc2F4LXNwZWNpZmljIHF1ZXN0aW9ucy4KICogSSB3YW50IHNvIHNheSBzcGVjaWFsIHRoYW5rcyB0byBDYXJsLUZyaWVkcmljaCBCcmF1biwgd2hvIGhhZCB0bwogKiBhbnN3ZXIgYSBsb3Qgb2YgcXVlc3Rpb25zIGFib3V0IGdlbmVyYWxseSBJU0ROIGFuZCBhYm91dCBoYW5kbGluZwogKiBvZiB0aGUgQW1kLUNoaXAuCiAqCiAqLwoKCiNpbmNsdWRlICJoaXNheC5oIgojaW5jbHVkZSAiaXNhYy5oIgojaW5jbHVkZSAiaXNkbmwxLmgiCiNpbmNsdWRlICJhbWQ3OTMwX2ZuLmgiCiNpbmNsdWRlIDxsaW51eC9pbnRlcnJ1cHQuaD4KI2luY2x1ZGUgPGxpbnV4L3BwcF9kZWZzLmg+CiNpbmNsdWRlIDxsaW51eC9wY2kuaD4KI2luY2x1ZGUgPGxpbnV4L2luaXQuaD4KI2luY2x1ZGUgIm5ldGpldC5oIgoKCgpzdGF0aWMgY29uc3QgY2hhciAqZW50ZXJub3dfcGNpX3JldiA9ICIkUmV2aXNpb246IDEuMS40LjUgJCI7CgoKLyogZvxyIFBvd2VySVNETiBQQ0kgKi8KI2RlZmluZSBUSl9BTURfSVJRICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDB4MjAKI2RlZmluZSBUSl9MRUQxICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDB4NDAKI2RlZmluZSBUSl9MRUQyICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDB4ODAKCgovKiBEYXMgRmVuc3RlciB6dW0gQU1ELi4uCiAqIEFiIEFkcmVzc2UgaHcubmpldC5iYXNlICsgVEpfQU1EX1BPUlQgd2VyZGVuIHZvbSBBTUQgamV3ZWlscyA4IEJpdCBpbgogKiBkZW4gVGlnZXJKZXQgaS9vLVJhdW0gZ2VtYXBwdAogKiAtPiAweDAxIGRlcyBBTUQgYmVpIGh3Lm5qZXQuYmFzZSArIDBDNCAqLwojZGVmaW5lIFRKX0FNRF9QT1JUICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMHhDMAoKCgovKiAqKioqKioqKioqKioqKioqKioqKioqKioqKiogSS9PLUludGVyZmFjZSBmdW5jdGlvbnMgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiAqLwoKCi8qIGNzLT5yZWFkaXNhYywgbWFjcm8gckJ5dGVBTUQgKi8Kc3RhdGljIHVuc2lnbmVkIGNoYXIKUmVhZEJ5dGVBbWQ3OTMwKHN0cnVjdCBJc2RuQ2FyZFN0YXRlICpjcywgdW5zaWduZWQgY2hhciBvZmZzZXQpCnsKCS8qIGRpcmVrdGVzIFJlZ2lzdGVyICovCglpZihvZmZzZXQgPCA4KQoJCXJldHVybiAoaW5iKGNzLT5ody5uamV0LmlzYWMgKyA0Km9mZnNldCkpOwoKCS8qIGluZGlyZWt0ZXMgUmVnaXN0ZXIgKi8KCWVsc2UgewoJCW91dGIob2Zmc2V0LCBjcy0+aHcubmpldC5pc2FjICsgNCpBTURfQ1IpOwoJCXJldHVybihpbmIoY3MtPmh3Lm5qZXQuaXNhYyArIDQqQU1EX0RSKSk7Cgl9Cn0KCi8qIGNzLT53cml0ZWlzYWMsIG1hY3JvIHdCeXRlQU1EICovCnN0YXRpYyB2b2lkCldyaXRlQnl0ZUFtZDc5MzAoc3RydWN0IElzZG5DYXJkU3RhdGUgKmNzLCB1bnNpZ25lZCBjaGFyIG9mZnNldCwgdW5zaWduZWQgY2hhciB2YWx1ZSkKewoJLyogZGlyZWt0ZXMgUmVnaXN0ZXIgKi8KCWlmKG9mZnNldCA8IDgpCgkJb3V0Yih2YWx1ZSwgY3MtPmh3Lm5qZXQuaXNhYyArIDQqb2Zmc2V0KTsKCgkvKiBpbmRpcmVrdGVzIFJlZ2lzdGVyICovCgllbHNlIHsKCQlvdXRiKG9mZnNldCwgY3MtPmh3Lm5qZXQuaXNhYyArIDQqQU1EX0NSKTsKCQlvdXRiKHZhbHVlLCBjcy0+aHcubmpldC5pc2FjICsgNCpBTURfRFIpOwoJfQp9CgoKc3RhdGljIHZvaWQKZW5wY2lfc2V0SXJxTWFzayhzdHJ1Y3QgSXNkbkNhcmRTdGF0ZSAqY3MsIHVuc2lnbmVkIGNoYXIgdmFsKSB7CiAgICAgICAgaWYgKCF2YWwpCgkgICAgICAgIG91dGIoMHgwMCwgY3MtPmh3Lm5qZXQuYmFzZStORVRKRVRfSVJRTUFTSzEpOwogICAgICAgIGVsc2UKCSAgICAgICAgb3V0YihUSl9BTURfSVJRLCBjcy0+aHcubmpldC5iYXNlK05FVEpFVF9JUlFNQVNLMSk7Cn0KCgpzdGF0aWMgdW5zaWduZWQgY2hhciBkdW1teXJyKHN0cnVjdCBJc2RuQ2FyZFN0YXRlICpjcywgaW50IGNoYW4sIHVuc2lnbmVkIGNoYXIgb2ZmKQp7CiAgICAgICAgcmV0dXJuKDUpOwp9CgpzdGF0aWMgdm9pZCBkdW1teXdyKHN0cnVjdCBJc2RuQ2FyZFN0YXRlICpjcywgaW50IGNoYW4sIHVuc2lnbmVkIGNoYXIgb2ZmLCB1bnNpZ25lZCBjaGFyIHZhbHVlKQp7Cgp9CgoKLyogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiogKi8KCgpzdGF0aWMgdm9pZApyZXNldF9lbnBjaShzdHJ1Y3QgSXNkbkNhcmRTdGF0ZSAqY3MpCnsKCWlmIChjcy0+ZGVidWcgJiBMMV9ERUJfSVNBQykKCQlkZWJ1Z2wxKGNzLCAiZW50ZXI6bm93IFBDSTogcmVzZXQiKTsKCgkvKiBSZXNldCBvbiwgKGFsc28gZm9yIEFNRCkgKi8KCWNzLT5ody5uamV0LmN0cmxfcmVnID0gMHgwNzsKCW91dGIoY3MtPmh3Lm5qZXQuY3RybF9yZWcsIGNzLT5ody5uamV0LmJhc2UgKyBORVRKRVRfQ1RSTCk7CgltZGVsYXkoMjApOwoJLyogUmVzZXQgb2ZmICovCgljcy0+aHcubmpldC5jdHJsX3JlZyA9IDB4MzA7CglvdXRiKGNzLT5ody5uamV0LmN0cmxfcmVnLCBjcy0+aHcubmpldC5iYXNlICsgTkVUSkVUX0NUUkwpOwoJLyogMjBtcyBkZWxheSAqLwoJbWRlbGF5KDIwKTsKCWNzLT5ody5uamV0LmF1eGQgPSAwOyAgLy8gTEVELXN0YXR1cwoJY3MtPmh3Lm5qZXQuZG1hY3RybCA9IDA7CglvdXRiKH5USl9BTURfSVJRLCBjcy0+aHcubmpldC5iYXNlICsgTkVUSkVUX0FVWENUUkwpOwoJb3V0YihUSl9BTURfSVJRLCBjcy0+aHcubmpldC5iYXNlICsgTkVUSkVUX0lSUU1BU0sxKTsKCW91dGIoY3MtPmh3Lm5qZXQuYXV4ZCwgY3MtPmh3Lm5qZXQuYXV4YSk7IC8vIExFRCBvZmYKfQoKCnN0YXRpYyBpbnQKZW5wY2lfY2FyZF9tc2coc3RydWN0IElzZG5DYXJkU3RhdGUgKmNzLCBpbnQgbXQsIHZvaWQgKmFyZykKewoJdV9sb25nIGZsYWdzOwogICAgICAgIHVuc2lnbmVkIGNoYXIgKmNoYW47CgoJaWYgKGNzLT5kZWJ1ZyAmIEwxX0RFQl9JU0FDKQoJCWRlYnVnbDEoY3MsICJlbnRlcjpub3cgUENJOiBjYXJkX21zZzogMHglMDRYIiwgbXQpOwoKICAgICAgICBzd2l0Y2ggKG10KSB7CgkJY2FzZSBDQVJEX1JFU0VUOgoJCQlzcGluX2xvY2tfaXJxc2F2ZSgmY3MtPmxvY2ssIGZsYWdzKTsKCQkJcmVzZXRfZW5wY2koY3MpOwogICAgICAgICAgICAgICAgICAgICAgICBBbWQ3OTMwX2luaXQoY3MpOwogICAgICAgICAgICAgICAgICAgICAgICBzcGluX3VubG9ja19pcnFyZXN0b3JlKCZjcy0+bG9jaywgZmxhZ3MpOwoJCQlicmVhazsKCQljYXNlIENBUkRfUkVMRUFTRToKCQkJcmVsZWFzZV9pb19uZXRqZXQoY3MpOwoJCQlicmVhazsKCQljYXNlIENBUkRfSU5JVDoKCQkJcmVzZXRfZW5wY2koY3MpOwoJCQlpbml0dGlnZXIoY3MpOwoJCQkvKiBpcnEgbXVzdCBiZSBvbiBoZXJlICovCgkJCUFtZDc5MzBfaW5pdChjcyk7CgkJCWJyZWFrOwoJCWNhc2UgQ0FSRF9URVNUOgoJCQlicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgTURMX0FTU0lHTjoKICAgICAgICAgICAgICAgICAgICAgICAgLyogVEVJIGFzc2lnbmVkLCBMRUQxIG9uICovCiAgICAgICAgICAgICAgICAgICAgICAgIGNzLT5ody5uamV0LmF1eGQgPSBUSl9BTURfSVJRIDw8IDE7CiAgICAgICAgICAgICAgICAgICAgICAgIG91dGIoY3MtPmh3Lm5qZXQuYXV4ZCwgY3MtPmh3Lm5qZXQuYmFzZSArIE5FVEpFVF9BVVhEQVRBKTsKICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlIE1ETF9SRU1PVkU6CiAgICAgICAgICAgICAgICAgICAgICAgIC8qIFRFSSByZW1vdmVkLCBMRURzIG9mZiAqLwoJICAgICAgICAgICAgICAgIGNzLT5ody5uamV0LmF1eGQgPSAwOwogICAgICAgICAgICAgICAgICAgICAgICBvdXRiKDB4MDAsIGNzLT5ody5uamV0LmJhc2UgKyBORVRKRVRfQVVYREFUQSk7CiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSBNRExfQkNfQVNTSUdOOgogICAgICAgICAgICAgICAgICAgICAgICAvKiBhY3RpdmF0ZSBCLWNoYW5uZWwgKi8KICAgICAgICAgICAgICAgICAgICAgICAgY2hhbiA9ICh1bnNpZ25lZCBjaGFyICopYXJnOwoKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGNzLT5kZWJ1ZyAmIEwxX0RFQl9JU0FDKQoJCSAgICAgICAgICAgICAgICBkZWJ1Z2wxKGNzLCAiZW50ZXI6bm93IFBDSTogYXNzaWduIHBoeXMuIEJDICVkIGluIEFNRCBMTVIxIiwgKmNoYW4pOwoKICAgICAgICAgICAgICAgICAgICAgICAgY3MtPmRjLmFtZDc5MzAucGhfY29tbWFuZChjcywgKGNzLT5kYy5hbWQ3OTMwLmxtcjEgfCAoKmNoYW4gKyAxKSksICJNRExfQkNfQVNTSUdOIik7CiAgICAgICAgICAgICAgICAgICAgICAgIC8qIGF0IGxlYXN0IG9uZSBiLWNoYW5uZWwgaW4gdXNlLCBMRUQgMiBvbiAqLwogICAgICAgICAgICAgICAgICAgICAgICBjcy0+aHcubmpldC5hdXhkIHw9IFRKX0FNRF9JUlEgPDwgMjsKICAgICAgICAgICAgICAgICAgICAgICAgb3V0Yihjcy0+aHcubmpldC5hdXhkLCBjcy0+aHcubmpldC5iYXNlICsgTkVUSkVUX0FVWERBVEEpOwogICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgTURMX0JDX1JFTEVBU0U6CiAgICAgICAgICAgICAgICAgICAgICAgIC8qIGRlYWN0aXZhdGUgQi1jaGFubmVsICovCiAgICAgICAgICAgICAgICAgICAgICAgIGNoYW4gPSAodW5zaWduZWQgY2hhciAqKWFyZzsKCiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChjcy0+ZGVidWcgJiBMMV9ERUJfSVNBQykKCQkgICAgICAgICAgICAgICAgZGVidWdsMShjcywgImVudGVyOm5vdyBQQ0k6IHJlbGVhc2UgcGh5cy4gQkMgJWQgaW4gQW1kIExNUjEiLCAqY2hhbik7CgogICAgICAgICAgICAgICAgICAgICAgICBjcy0+ZGMuYW1kNzkzMC5waF9jb21tYW5kKGNzLCAoY3MtPmRjLmFtZDc5MzAubG1yMSAmIH4oKmNoYW4gKyAxKSksICJNRExfQkNfUkVMRUFTRSIpOwogICAgICAgICAgICAgICAgICAgICAgICAvKiBubyBiLWNoYW5uZWwgYWN0aXZlIC0+IExFRDIgb2ZmICovCiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghKGNzLT5kYy5hbWQ3OTMwLmxtcjEgJiAzKSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNzLT5ody5uamV0LmF1eGQgJj0gfihUSl9BTURfSVJRIDw8IDIpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG91dGIoY3MtPmh3Lm5qZXQuYXV4ZCwgY3MtPmh3Lm5qZXQuYmFzZSArIE5FVEpFVF9BVVhEQVRBKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwoKCX0KCXJldHVybigwKTsKfQoKc3RhdGljIGlycXJldHVybl90CmVucGNpX2ludGVycnVwdChpbnQgaW50bm8sIHZvaWQgKmRldl9pZCwgc3RydWN0IHB0X3JlZ3MgKnJlZ3MpCnsKCXN0cnVjdCBJc2RuQ2FyZFN0YXRlICpjcyA9IGRldl9pZDsKCXVuc2lnbmVkIGNoYXIgczB2YWwsIHMxdmFsLCBpcjsKCXVfbG9uZyBmbGFnczsKCglzcGluX2xvY2tfaXJxc2F2ZSgmY3MtPmxvY2ssIGZsYWdzKTsKCXMxdmFsID0gaW5iKGNzLT5ody5uamV0LmJhc2UgKyBORVRKRVRfSVJRU1RBVDEpOwoKICAgICAgICAvKiBBTUQgdGhyZXcgYW4gaW50ZXJydXB0ICovCglpZiAoIShzMXZhbCAmIFRKX0FNRF9JUlEpKSB7CiAgICAgICAgICAgICAgICAvKiByZWFkIGFuZCBjbGVhciBpbnRlcnJ1cHQtcmVnaXN0ZXIgKi8KCQlpciA9IFJlYWRCeXRlQW1kNzkzMChjcywgMHgwMCk7CgkJQW1kNzkzMF9pbnRlcnJ1cHQoY3MsIGlyKTsKCQlzMXZhbCA9IDE7Cgl9IGVsc2UKCQlzMXZhbCA9IDA7CglzMHZhbCA9IGluYihjcy0+aHcubmpldC5iYXNlICsgTkVUSkVUX0lSUVNUQVQwKTsKCWlmICgoczB2YWwgfCBzMXZhbCk9PTApIHsgLy8gc2hhcmVkIElSUQoJCXNwaW5fdW5sb2NrX2lycXJlc3RvcmUoJmNzLT5sb2NrLCBmbGFncyk7CgkJcmV0dXJuIElSUV9OT05FOwoJfSAKCWlmIChzMHZhbCkKCQlvdXRiKHMwdmFsLCBjcy0+aHcubmpldC5iYXNlICsgTkVUSkVUX0lSUVNUQVQwKTsKCgkvKiBETUEtSW50ZXJydXB0OiBCLWNoYW5uZWwtc3R1ZmYgKi8KCS8qIHNldCBiaXRzIGluIHN2YWwgdG8gaW5kaWNhdGUgd2hpY2ggcGFnZSBpcyBmcmVlICovCglpZiAoaW5sKGNzLT5ody5uamV0LmJhc2UgKyBORVRKRVRfRE1BX1dSSVRFX0FEUikgPAoJCWlubChjcy0+aHcubmpldC5iYXNlICsgTkVUSkVUX0RNQV9XUklURV9JUlEpKQoJCS8qIHRoZSAybmQgd3JpdGUgcGFnZSBpcyBmcmVlICovCgkJczB2YWwgPSAweDA4OwoJZWxzZQkvKiB0aGUgMXN0IHdyaXRlIHBhZ2UgaXMgZnJlZSAqLwoJCXMwdmFsID0gMHgwNDsKCWlmIChpbmwoY3MtPmh3Lm5qZXQuYmFzZSArIE5FVEpFVF9ETUFfUkVBRF9BRFIpIDwKCQlpbmwoY3MtPmh3Lm5qZXQuYmFzZSArIE5FVEpFVF9ETUFfUkVBRF9JUlEpKQoJCS8qIHRoZSAybmQgcmVhZCBwYWdlIGlzIGZyZWUgKi8KCQlzMHZhbCA9IHMwdmFsIHwgMHgwMjsKCWVsc2UJLyogdGhlIDFzdCByZWFkIHBhZ2UgaXMgZnJlZSAqLwoJCXMwdmFsID0gczB2YWwgfCAweDAxOwoJaWYgKHMwdmFsICE9IGNzLT5ody5uamV0Lmxhc3RfaXMwKSAvKiB3ZSBoYXZlIGEgRE1BIGludGVycnVwdCAqLwoJewoJCWlmICh0ZXN0X2FuZF9zZXRfYml0KEZMR19MT0NLX0FUT01JQywgJmNzLT5IV19GbGFncykpIHsKCQkJc3Bpbl91bmxvY2tfaXJxcmVzdG9yZSgmY3MtPmxvY2ssIGZsYWdzKTsKCQkJcmV0dXJuIElSUV9IQU5ETEVEOwoJCX0KCQljcy0+aHcubmpldC5pcnFzdGF0MCA9IHMwdmFsOwoJCWlmICgoY3MtPmh3Lm5qZXQuaXJxc3RhdDAgJiBORVRKRVRfSVJRTTBfUkVBRCkgIT0KCQkJKGNzLT5ody5uamV0Lmxhc3RfaXMwICYgTkVUSkVUX0lSUU0wX1JFQUQpKQoJCQkvKiB3ZSBoYXZlIGEgcmVhZCBkbWEgaW50ICovCgkJCXJlYWRfdGlnZXIoY3MpOwoJCWlmICgoY3MtPmh3Lm5qZXQuaXJxc3RhdDAgJiBORVRKRVRfSVJRTTBfV1JJVEUpICE9CgkJCShjcy0+aHcubmpldC5sYXN0X2lzMCAmIE5FVEpFVF9JUlFNMF9XUklURSkpCgkJCS8qIHdlIGhhdmUgYSB3cml0ZSBkbWEgaW50ICovCgkJCXdyaXRlX3RpZ2VyKGNzKTsKCQl0ZXN0X2FuZF9jbGVhcl9iaXQoRkxHX0xPQ0tfQVRPTUlDLCAmY3MtPkhXX0ZsYWdzKTsKCX0KCXNwaW5fdW5sb2NrX2lycXJlc3RvcmUoJmNzLT5sb2NrLCBmbGFncyk7CglyZXR1cm4gSVJRX0hBTkRMRUQ7Cn0KCgpzdGF0aWMgc3RydWN0IHBjaV9kZXYgKmRldl9uZXRqZXQgX19pbml0ZGF0YSA9IE5VTEw7CgovKiBjYWxsZWQgYnkgY29uZmlnLmMgKi8KaW50IF9faW5pdApzZXR1cF9lbnRlcm5vd19wY2koc3RydWN0IElzZG5DYXJkICpjYXJkKQp7CglpbnQgYnl0ZWNudDsKCXN0cnVjdCBJc2RuQ2FyZFN0YXRlICpjcyA9IGNhcmQtPmNzOwoJY2hhciB0bXBbNjRdOwoKI2lmZGVmIENPTkZJR19QQ0kKI2lmZGVmIF9fQklHX0VORElBTgojZXJyb3IgIm5vdCBydW5uaW5nIG9uIGJpZyBlbmRpYW4gbWFjaGluZXMgbm93IgojZW5kaWYKICAgICAgICBzdHJjcHkodG1wLCBlbnRlcm5vd19wY2lfcmV2KTsKCXByaW50ayhLRVJOX0lORk8gIkhpU2F4OiBGb3JtdWxhLW4gRXVyb3BlIEFHIGVudGVyOm5vdyBJU0ROIFBDSSBkcml2ZXIgUmV2LiAlc1xuIiwgSGlTYXhfZ2V0cmV2KHRtcCkpOwoJaWYgKGNzLT50eXAgIT0gSVNETl9DVFlQRV9FTlRFUk5PVykKCQlyZXR1cm4oMCk7Cgl0ZXN0X2FuZF9jbGVhcl9iaXQoRkxHX0xPQ0tfQVRPTUlDLCAmY3MtPkhXX0ZsYWdzKTsKCglmb3IgKCA7OyApCgl7CgkJaWYgKChkZXZfbmV0amV0ID0gcGNpX2ZpbmRfZGV2aWNlKFBDSV9WRU5ET1JfSURfVElHRVJKRVQsCgkJCVBDSV9ERVZJQ0VfSURfVElHRVJKRVRfMzAwLCAgZGV2X25ldGpldCkpKSB7CgkJCWlmIChwY2lfZW5hYmxlX2RldmljZShkZXZfbmV0amV0KSkKCQkJCXJldHVybigwKTsKCQkJY3MtPmlycSA9IGRldl9uZXRqZXQtPmlycTsKCQkJaWYgKCFjcy0+aXJxKSB7CgkJCQlwcmludGsoS0VSTl9XQVJOSU5HICJlbnRlcjpub3cgUENJOiBObyBJUlEgZm9yIFBDSSBjYXJkIGZvdW5kXG4iKTsKCQkJCXJldHVybigwKTsKCQkJfQoJCQljcy0+aHcubmpldC5iYXNlID0gcGNpX3Jlc291cmNlX3N0YXJ0KGRldl9uZXRqZXQsIDApOwoJCQlpZiAoIWNzLT5ody5uamV0LmJhc2UpIHsKCQkJCXByaW50ayhLRVJOX1dBUk5JTkcgImVudGVyOm5vdyBQQ0k6IE5vIElPLUFkciBmb3IgUENJIGNhcmQgZm91bmRcbiIpOwoJCQkJcmV0dXJuKDApOwoJCQl9CiAgICAgICAgICAgICAgICAgICAgICAgIC8qIGNoZWNrcyBTdWItVmVuZG9yIElEIGJlY2F1c2Ugc3lzdGVtIGNyYXNoZXMgd2l0aCBUcmF2ZXJzZS1DYXJkICovCgkJCWlmICgoZGV2X25ldGpldC0+c3Vic3lzdGVtX3ZlbmRvciAhPSAweDU1KSB8fAoJCQkJKGRldl9uZXRqZXQtPnN1YnN5c3RlbV9kZXZpY2UgIT0gMHgwMikpIHsKCQkJCXByaW50ayhLRVJOX1dBUk5JTkcgImVudGVyOm5vdzogWW91IHRyaWVkIHRvIGxvYWQgdGhpcyBkcml2ZXIgd2l0aCBhbiBpbmNvbXBhdGlibGUgVGlnZXJKZXQtY2FyZFxuIik7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJpbnRrKEtFUk5fV0FSTklORyAiVXNlIHR5cGU9MjAgZm9yIFRyYXZlcnNlIE5ldEpldCBQQ0kgQ2FyZC5cbiIpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybigwKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQoJCX0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHByaW50ayhLRVJOX1dBUk5JTkcgImVudGVyOm5vdyBQQ0k6IE5vIFBDSSBjYXJkIGZvdW5kXG4iKTsKCQkJcmV0dXJuKDApOwoJCX0KCgkJY3MtPmh3Lm5qZXQuYXV4YSA9IGNzLT5ody5uamV0LmJhc2UgKyBORVRKRVRfQVVYREFUQTsKCQljcy0+aHcubmpldC5pc2FjID0gY3MtPmh3Lm5qZXQuYmFzZSArIDB4QzA7IC8vIEZlbnN0ZXIgenVtIEFNRAoKCQkvKiBSZXNldCBhbiAqLwoJCWNzLT5ody5uamV0LmN0cmxfcmVnID0gMHgwNzsgIC8vIGdl5G5kZXJ0IHZvbiAweGZmCgkJb3V0Yihjcy0+aHcubmpldC5jdHJsX3JlZywgY3MtPmh3Lm5qZXQuYmFzZSArIE5FVEpFVF9DVFJMKTsKCQkvKiAyMCBtcyBQYXVzZSAqLwoJCW1kZWxheSgyMCk7CgoJCWNzLT5ody5uamV0LmN0cmxfcmVnID0gMHgzMDsgIC8qIFJlc2V0IE9mZiBhbmQgc3RhdHVzIHJlYWQgY2xlYXIgKi8KCQlvdXRiKGNzLT5ody5uamV0LmN0cmxfcmVnLCBjcy0+aHcubmpldC5iYXNlICsgTkVUSkVUX0NUUkwpOwoJCW1kZWxheSgxMCk7CgoJCWNzLT5ody5uamV0LmF1eGQgPSAweDAwOyAvLyB3YXIgMHhjMAoJCWNzLT5ody5uamV0LmRtYWN0cmwgPSAwOwoKCQlvdXRiKH5USl9BTURfSVJRLCBjcy0+aHcubmpldC5iYXNlICsgTkVUSkVUX0FVWENUUkwpOwoJCW91dGIoVEpfQU1EX0lSUSwgY3MtPmh3Lm5qZXQuYmFzZSArIE5FVEpFVF9JUlFNQVNLMSk7CgkJb3V0Yihjcy0+aHcubmpldC5hdXhkLCBjcy0+aHcubmpldC5hdXhhKTsKCgkJYnJlYWs7Cgl9CiNlbHNlCgoJcHJpbnRrKEtFUk5fV0FSTklORyAiZW50ZXI6bm93IFBDSTogTk9fUENJX0JJT1NcbiIpOwoJcHJpbnRrKEtFUk5fV0FSTklORyAiZW50ZXI6bm93IFBDSTogdW5hYmxlIHRvIGNvbmZpZyBGb3JtdWxhLW4gZW50ZXI6bm93IElTRE4gUENJIGFiXG4iKTsKCXJldHVybiAoMCk7CgojZW5kaWYgLyogQ09ORklHX1BDSSAqLwoKCWJ5dGVjbnQgPSAyNTY7CgoJcHJpbnRrKEtFUk5fSU5GTwoJCSJlbnRlcjpub3cgUENJOiBQQ0kgY2FyZCBjb25maWd1cmVkIGF0IDB4JWx4IElSUSAlZFxuIiwKCQljcy0+aHcubmpldC5iYXNlLCBjcy0+aXJxKTsKCWlmICghcmVxdWVzdF9yZWdpb24oY3MtPmh3Lm5qZXQuYmFzZSwgYnl0ZWNudCwgIkZuX0lTRE4iKSkgewoJCXByaW50ayhLRVJOX1dBUk5JTkcKCQkJICAgIkhpU2F4OiAlcyBjb25maWcgcG9ydCAlbHgtJWx4IGFscmVhZHkgaW4gdXNlXG4iLAoJCQkgICBDYXJkVHlwZVtjYXJkLT50eXBdLAoJCQkgICBjcy0+aHcubmpldC5iYXNlLAoJCQkgICBjcy0+aHcubmpldC5iYXNlICsgYnl0ZWNudCk7CgkJcmV0dXJuICgwKTsKCX0KCXNldHVwX0FtZDc5MzAoY3MpOwoJY3MtPmh3Lm5qZXQubGFzdF9pczAgPSAwOwogICAgICAgIC8qIG1hY3JvIHJCeXRlQU1EICovCiAgICAgICAgY3MtPnJlYWRpc2FjID0gJlJlYWRCeXRlQW1kNzkzMDsKICAgICAgICAvKiBtYWNybyB3Qnl0ZUFNRCAqLwogICAgICAgIGNzLT53cml0ZWlzYWMgPSAmV3JpdGVCeXRlQW1kNzkzMDsKICAgICAgICBjcy0+ZGMuYW1kNzkzMC5zZXRJcnFNYXNrID0gJmVucGNpX3NldElycU1hc2s7CgogICAgICAgIGNzLT5CQ19SZWFkX1JlZyAgPSAmZHVtbXlycjsKCWNzLT5CQ19Xcml0ZV9SZWcgPSAmZHVtbXl3cjsKCWNzLT5CQ19TZW5kX0RhdGEgPSAmbmV0amV0X2ZpbGxfZG1hOwoJY3MtPmNhcmRtc2cgPSAmZW5wY2lfY2FyZF9tc2c7Cgljcy0+aXJxX2Z1bmMgPSAmZW5wY2lfaW50ZXJydXB0OwoJY3MtPmlycV9mbGFncyB8PSBTQV9TSElSUTsKCiAgICAgICAgcmV0dXJuICgxKTsKfQo=