LyoKICogIE1hdGNoIGEgc3RyaW5nIGFnYWluc3QgYSBsaXN0IG9mIHBhdHRlcm5zL3JlZ2V4ZXMuCiAqCiAqICBDb3B5cmlnaHQgKEMpIDIwMDYtMjAwNyBU9nL2ayBFZHZpbiA8ZWR3aW5AY2xhbWF2Lm5ldD4KICoKICogIFRoaXMgcHJvZ3JhbSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5CiAqICBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBhcyAKICogIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgogKgogKiAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsCiAqICBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZgogKiAgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZQogKiAgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy4KICoKICogIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqICBhbG9uZyB3aXRoIHRoaXMgcHJvZ3JhbTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZQogKiAgRm91bmRhdGlvbiwgSW5jLiwgNTEgRnJhbmtsaW4gU3RyZWV0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLAogKiAgTUEgMDIxMTAtMTMwMSwgVVNBLgogKgogKi8KCiNpZiBIQVZFX0NPTkZJR19ICiNpbmNsdWRlICJjbGFtYXYtY29uZmlnLmgiCiNlbmRpZgoKI2lmbmRlZiBDTF9ERUJVRwojZGVmaW5lIE5ERUJVRwojZW5kaWYKCiNpZmRlZiBDTF9USFJFQURfU0FGRQojaWZuZGVmIF9SRUVOVFJBTlQKI2RlZmluZSBfUkVFTlRSQU5UCiNlbmRpZgojZW5kaWYKCgovKiBUT0RPOiB3aGVuIGltcGxlbWVudGF0aW9uIG9mIG5ldyB2ZXJzaW9uIGlzIGNvbXBsZXRlLCBlbmFibGUgaXQgaW4gQ0xfRVhQRVJJTUVOVEFMICovCiNpZmRlZiBDTF9FWFBFUklNRU5UQUwKLyojZGVmaW5lIFVTRV9ORVdfVkVSU0lPTiovCiNlbmRpZgoKI2lmbmRlZiBVU0VfTkVXX1ZFUlNJT04KLyp0aGlzIGlzIHRoZSBvbGQgdmVyc2lvbiBvZiByZWdleF9saXN0LmMKICpyZWFzb24gZm9yIHJlZGVzaWduOiB0aGVyZSBpcyBvbmx5IG9uZSBub2RlIHR5cGUgdGhhdCBoYXMgdG8gaGFuZGxlIGFsbCB0aGUgY2FzZXM6IGJpbmFyeSBzZWFyY2ggYW1vbmcgY2hpbGRyZW4sIGFsdGVybmF0aXZlcyBsaXN0LCBtYXRjaC4KICogVGhpcyBkZXNpZ24gaXMgdmVyeSBlcnJvci1wcm9uZS4qLwoKI2luY2x1ZGUgPHN0ZGlvLmg+CiNpbmNsdWRlIDxzdGRsaWIuaD4KI2luY2x1ZGUgPHN0cmluZy5oPgojaW5jbHVkZSA8Y3R5cGUuaD4KCiNpbmNsdWRlIDxsaW1pdHMuaD4KI2luY2x1ZGUgPHN5cy90eXBlcy5oPgoKI2luY2x1ZGUgInJlZ2V4LmgiCgoKI2luY2x1ZGUgImNsYW1hdi5oIgojaW5jbHVkZSAib3RoZXJzLmgiCiNpbmNsdWRlICJyZWdleF9saXN0LmgiCiNpbmNsdWRlICJtYXRjaGVyLWFjLmgiCiNpbmNsdWRlICJzdHIuaCIKCi8qVHJlZSovCmVudW0gdG9rZW5fb3BfdCB7T1BfQ0hBUixPUF9TVERDTEFTUyxPUF9DVVNUT01DTEFTUyxPUF9ET1QsT1BfTEVBRixPUF9ST09ULE9QX1BBUkNMT1NFfTsKdHlwZWRlZiB1bnNpZ25lZCBjaGFyKiBjaGFyX2JpdG1hcF9wOwovKgogKgogKiBPUF9DSEFSOiAxIGNoYXJhY3RlciwgYyA9IGNoYXJhY3RlcgogKiBjb21wbGV4IHN0dWZmOgogKiBPUF9TVERDTEFTUzogc3RhbmRhcmQgY2hhcmFjdGVyIGNsYXNzLCBjID0gY2hhciBjbGFzcywgY2xhc3M6IDE8PChpbmRleCBpbnRvIHN0ZF9jbGFzcyBvZiBjbGFzcyBuYW1lKQogKiBPUF9DVVNUT01DTEFTUzogY3VzdG9tIGNoYXJhY3RlciBjbGFzcywgZmlyc3QgcG9pbnRlciBpbiBwdHIgYXJyYXkgaXMgYSBwb2ludGVyIHRvIHRoZSBiaXRtYXAgdGFibGUgZm9yIHRoaXMgY2xhc3MKICogT1BfRE9UOiBzaW5nbGUgLiBtYXRjaGluZyBhbnkgY2hhcmFjdGVyIGV4Y2VwdCBcbgogKiBPUF9MRUFGOiB0aGlzIGlzIGEgbGVhZiBub2RlLCByZWludGVycHJldCBzdHJ1Y3R1cmUKICovCnN0cnVjdCB0cmVlX25vZGUgewoJc3RydWN0IHRyZWVfbm9kZSogbmV4dDsvKiBuZXh0IHJlZ2V4L2NvbXBsZXggc2libGluZywgb3IgcGFyZW50LCBpZiBubyBtb3JlIHNpYmxpbmdzICwgY2FuJ3QgYmUgTlVMTCBleGNlcHQgZm9yIHJvb3Qgbm9kZSovCgl1bnNpZ25lZCBjaGFyIGM7CgllbnVtIHRva2VuX29wX3Qgb3A7CgljaGFyIGFsdGVybmF0aXZlczsvKiBudW1iZXIgb2YgKG5vbi1yZWdleCkgY2hpbGRyZW4gb2Ygbm9kZSwgaS5lLiBzaXplb2YoY2hpbGRyZW4pKi8KCWNoYXIgbGlzdGVuZDsvKiBubyBtb3JlIHNpYmxpbmdzLCBuZXh0IHBvaW50ZXIgaXMgcG9pbnRlciB0byBwYXJlbnQqLwoJdW5pb24gewoJCXN0cnVjdCB0cmVlX25vZGUqKiBjaGlsZHJlbjsvKiBhbHRlcm5hdGl2ZXMgbnIuIG9mIGNoaWxkcmVuLCBmb2xsb3dlZCBieSAoYSBudWxsIHBvaW50ZXIgdGVybWluYXRlZCkgcmVnZXggbGVhZiBub2RlIHBvaW50ZXJzKSAqLwoJCWNoYXJfYml0bWFwX3AqIGJpdG1hcDsKCQlzdHJ1Y3QgbGVhZl9pbmZvKiAgbGVhZjsKCX0gdTsKfTsKCnN0cnVjdCBsZWFmX2luZm8gewoJY2hhciogaW5mbzsvKiB3aGF0IGRvZXMgaXQgbWVhbiB0aGF0IHdlIHJlYWNoZWQgdGhlIGxlYWYuLi4qLwoJcmVnZXhfdCogcHJlZzsvKiB0aGlzIGlzIE5VTEwgaWYgbGVhZiBub2RlLCBhbmQgbm9uLXJlZ2V4Ki8KfTsKCi8qIENoYXJhY3RlciBjbGFzc2VzICovCnN0YXRpYyBjb25zdCBjaGFyKiBzdGRfY2xhc3NbXSA9IHsKCSJbOmFsbnVtOl0iLAoJIls6ZGlnaXQ6XSIsCgkiWzpwdW5jdDpdIiwKCSJbOmFscGhhOl0iLAoJIls6Z3JhcGg6XSIsCgkiWzpzcGFjZTpdIiwKCSJbOmJsYW5rOl0iLAoJIls6bG93ZXI6XSIsIAoJIls6dXBwZXI6XSIsCgkiWzpjbnRybDpdIiwKCSJbOnByaW50Ol0iLAoJIls6eGRpZ2l0Ol0iCgkvKiBkb24ndCBjaGFuZ2UgdGhlIG9yZGVyIG9mIHRoZXNlIHN0cmluZ3MsIHVubGVzcyB5b3UgY2hhbmdlIHRoZW0gaW4gZ2VuZXJhdGVfdGFibGVzLmMgdG9vLCBhbmQgcmVnZW5lcmF0ZSB0aGUgdGFibGVzKi8KfTsKCgojZGVmaW5lIFNURF9DTEFTU19DTlQgc2l6ZW9mKHN0ZF9jbGFzcykvc2l6ZW9mKHN0ZF9jbGFzc1swXSkKCi8qIGdlbmVyYXRlZCBieSBjb250cmliL3BoaXNoaW5nL2dlbmVyYXRlX3RhYmxlcy5jICovCnN0YXRpYyBjb25zdCB1bnNpZ25lZCBjaGFyIGNoYXJfY2xhc3NfYml0bWFwW1NURF9DTEFTU19DTlRdWzMyXSA9IHsKICAgICAgICB7MHgwMCwgMHgwMCwgMHgwMCwgMHgwMCwgMHgwMCwgMHgwMCwgMHhmZiwgMHgwMywgCiAgICAgICAgIDB4ZmUsIDB4ZmYsIDB4ZmYsIDB4MDcsIDB4ZmUsIDB4ZmYsIDB4ZmYsIDB4MDcsIAogICAgICAgICAweDAwLCAweDAwLCAweDAwLCAweDAwLCAweDAwLCAweDAwLCAweDAwLCAweDAwLCAKICAgICAgICAgMHgwMCwgMHgwMCwgMHgwMCwgMHgwMCwgMHgwMCwgMHgwMCwgMHgwMCwgMHgwMH0sCgogICAgICAgIHsweDAwLCAweDAwLCAweDAwLCAweDAwLCAweDAwLCAweDAwLCAweGZmLCAweDAzLCAKICAgICAgICAgMHgwMCwgMHgwMCwgMHgwMCwgMHgwMCwgMHgwMCwgMHgwMCwgMHgwMCwgMHgwMCwgCiAgICAgICAgIDB4MDAsIDB4MDAsIDB4MDAsIDB4MDAsIDB4MDAsIDB4MDAsIDB4MDAsIDB4MDAsIAogICAgICAgICAweDAwLCAweDAwLCAweDAwLCAweDAwLCAweDAwLCAweDAwLCAweDAwLCAweDAwfSwKCiAgICAgICAgezB4MDAsIDB4MDAsIDB4MDAsIDB4MDAsIDB4ZmUsIDB4ZmYsIDB4MDAsIDB4ZmMsIAogICAgICAgICAweDAxLCAweDAwLCAweDAwLCAweGY4LCAweDAxLCAweDAwLCAweDAwLCAweDc4LCAKICAgICAgICAgMHgwMCwgMHgwMCwgMHgwMCwgMHgwMCwgMHgwMCwgMHgwMCwgMHgwMCwgMHgwMCwgCiAgICAgICAgIDB4MDAsIDB4MDAsIDB4MDAsIDB4MDAsIDB4MDAsIDB4MDAsIDB4MDAsIDB4MDB9LAoKICAgICAgICB7MHgwMCwgMHgwMCwgMHgwMCwgMHgwMCwgMHgwMCwgMHgwMCwgMHgwMCwgMHgwMCwgCiAgICAgICAgIDB4ZmUsIDB4ZmYsIDB4ZmYsIDB4MDcsIDB4ZmUsIDB4ZmYsIDB4ZmYsIDB4MDcsIAogICAgICAgICAweDAwLCAweDAwLCAweDAwLCAweDAwLCAweDAwLCAweDAwLCAweDAwLCAweDAwLCAKICAgICAgICAgMHgwMCwgMHgwMCwgMHgwMCwgMHgwMCwgMHgwMCwgMHgwMCwgMHgwMCwgMHgwMH0sCgogICAgICAgIHsweDAwLCAweDAwLCAweDAwLCAweDAwLCAweGZlLCAweGZmLCAweGZmLCAweGZmLCAKICAgICAgICAgMHhmZiwgMHhmZiwgMHhmZiwgMHhmZiwgMHhmZiwgMHhmZiwgMHhmZiwgMHg3ZiwgCiAgICAgICAgIDB4MDAsIDB4MDAsIDB4MDAsIDB4MDAsIDB4MDAsIDB4MDAsIDB4MDAsIDB4MDAsIAogICAgICAgICAweDAwLCAweDAwLCAweDAwLCAweDAwLCAweDAwLCAweDAwLCAweDAwLCAweDAwfSwKCiAgICAgICAgezB4MDAsIDB4M2UsIDB4MDAsIDB4MDAsIDB4MDEsIDB4MDAsIDB4MDAsIDB4MDAsIAogICAgICAgICAweDAwLCAweDAwLCAweDAwLCAweDAwLCAweDAwLCAweDAwLCAweDAwLCAweDAwLCAKICAgICAgICAgMHgwMCwgMHgwMCwgMHgwMCwgMHgwMCwgMHgwMCwgMHgwMCwgMHgwMCwgMHgwMCwgCiAgICAgICAgIDB4MDAsIDB4MDAsIDB4MDAsIDB4MDAsIDB4MDAsIDB4MDAsIDB4MDAsIDB4MDB9LAoKICAgICAgICB7MHgwMCwgMHgwMiwgMHgwMCwgMHgwMCwgMHgwMSwgMHgwMCwgMHgwMCwgMHgwMCwgCiAgICAgICAgIDB4MDAsIDB4MDAsIDB4MDAsIDB4MDAsIDB4MDAsIDB4MDAsIDB4MDAsIDB4MDAsIAogICAgICAgICAweDAwLCAweDAwLCAweDAwLCAweDAwLCAweDAwLCAweDAwLCAweDAwLCAweDAwLCAKICAgICAgICAgMHgwMCwgMHgwMCwgMHgwMCwgMHgwMCwgMHgwMCwgMHgwMCwgMHgwMCwgMHgwMH0sCgogICAgICAgIHsweDAwLCAweDAwLCAweDAwLCAweDAwLCAweDAwLCAweDAwLCAweDAwLCAweDAwLCAKICAgICAgICAgMHgwMCwgMHgwMCwgMHgwMCwgMHgwMCwgMHhmZSwgMHhmZiwgMHhmZiwgMHgwNywgCiAgICAgICAgIDB4MDAsIDB4MDAsIDB4MDAsIDB4MDAsIDB4MDAsIDB4MDAsIDB4MDAsIDB4MDAsIAogICAgICAgICAweDAwLCAweDAwLCAweDAwLCAweDAwLCAweDAwLCAweDAwLCAweDAwLCAweDAwfSwKCiAgICAgICAgezB4MDAsIDB4MDAsIDB4MDAsIDB4MDAsIDB4MDAsIDB4MDAsIDB4MDAsIDB4MDAsIAogICAgICAgICAweGZlLCAweGZmLCAweGZmLCAweDA3LCAweDAwLCAweDAwLCAweDAwLCAweDAwLCAKICAgICAgICAgMHgwMCwgMHgwMCwgMHgwMCwgMHgwMCwgMHgwMCwgMHgwMCwgMHgwMCwgMHgwMCwgCiAgICAgICAgIDB4MDAsIDB4MDAsIDB4MDAsIDB4MDAsIDB4MDAsIDB4MDAsIDB4MDAsIDB4MDB9LAoKICAgICAgICB7MHhmZiwgMHhmZiwgMHhmZiwgMHhmZiwgMHgwMCwgMHgwMCwgMHgwMCwgMHgwMCwgCiAgICAgICAgIDB4MDAsIDB4MDAsIDB4MDAsIDB4MDAsIDB4MDAsIDB4MDAsIDB4MDAsIDB4ODAsIAogICAgICAgICAweDAwLCAweDAwLCAweDAwLCAweDAwLCAweDAwLCAweDAwLCAweDAwLCAweDAwLCAKICAgICAgICAgMHgwMCwgMHgwMCwgMHgwMCwgMHgwMCwgMHgwMCwgMHgwMCwgMHgwMCwgMHgwMH0sCgogICAgICAgIHsweDAwLCAweDAwLCAweDAwLCAweDAwLCAweGZmLCAweGZmLCAweGZmLCAweGZmLCAKICAgICAgICAgMHhmZiwgMHhmZiwgMHhmZiwgMHhmZiwgMHhmZiwgMHhmZiwgMHhmZiwgMHg3ZiwgCiAgICAgICAgIDB4MDAsIDB4MDAsIDB4MDAsIDB4MDAsIDB4MDAsIDB4MDAsIDB4MDAsIDB4MDAsIAogICAgICAgICAweDAwLCAweDAwLCAweDAwLCAweDAwLCAweDAwLCAweDAwLCAweDAwLCAweDAwfSwKCiAgICAgICAgezB4MDAsIDB4MDAsIDB4MDAsIDB4MDAsIDB4MDAsIDB4MDAsIDB4ZmYsIDB4MDMsIAogICAgICAgICAweDdlLCAweDAwLCAweDAwLCAweDAwLCAweDdlLCAweDAwLCAweDAwLCAweDAwLCAKICAgICAgICAgMHgwMCwgMHgwMCwgMHgwMCwgMHgwMCwgMHgwMCwgMHgwMCwgMHgwMCwgMHgwMCwgCiAgICAgICAgIDB4MDAsIDB4MDAsIDB4MDAsIDB4MDAsIDB4MDAsIDB4MDAsIDB4MDAsIDB4MDB9Cn07CgpzdGF0aWMgY29uc3QgdW5zaWduZWQgc2hvcnQgaW50IGNoYXJfY2xhc3NbMjU2XSA9IHsKICAgICAgICAweDIwMCwgMHgyMDAsIDB4MjAwLCAweDIwMCwgMHgyMDAsIDB4MjAwLCAweDIwMCwgMHgyMDAsIDB4MjAwLCAweDI2MCwgMHgyMjAsIDB4MjIwLCAweDIyMCwgMHgyMjAsIDB4MjAwLCAweDIwMCwgCiAgICAgICAgMHgyMDAsIDB4MjAwLCAweDIwMCwgMHgyMDAsIDB4MjAwLCAweDIwMCwgMHgyMDAsIDB4MjAwLCAweDIwMCwgMHgyMDAsIDB4MjAwLCAweDIwMCwgMHgyMDAsIDB4MjAwLCAweDIwMCwgMHgyMDAsIAogICAgICAgIDB4NDYwLCAweDQxNCwgMHg0MTQsIDB4NDE0LCAweDQxNCwgMHg0MTQsIDB4NDE0LCAweDQxNCwgMHg0MTQsIDB4NDE0LCAweDQxNCwgMHg0MTQsIDB4NDE0LCAweDQxNCwgMHg0MTQsIDB4NDE0LCAKICAgICAgICAweGMxMywgMHhjMTMsIDB4YzEzLCAweGMxMywgMHhjMTMsIDB4YzEzLCAweGMxMywgMHhjMTMsIDB4YzEzLCAweGMxMywgMHg0MTQsIDB4NDE0LCAweDQxNCwgMHg0MTQsIDB4NDE0LCAweDQxNCwgCiAgICAgICAgMHg0MTQsIDB4ZDE5LCAweGQxOSwgMHhkMTksIDB4ZDE5LCAweGQxOSwgMHhkMTksIDB4NTE5LCAweDUxOSwgMHg1MTksIDB4NTE5LCAweDUxOSwgMHg1MTksIDB4NTE5LCAweDUxOSwgMHg1MTksIAogICAgICAgIDB4NTE5LCAweDUxOSwgMHg1MTksIDB4NTE5LCAweDUxOSwgMHg1MTksIDB4NTE5LCAweDUxOSwgMHg1MTksIDB4NTE5LCAweDUxOSwgMHg0MTQsIDB4NDE0LCAweDQxNCwgMHg0MTQsIDB4NDE0LCAKICAgICAgICAweDQxNCwgMHhjOTksIDB4Yzk5LCAweGM5OSwgMHhjOTksIDB4Yzk5LCAweGM5OSwgMHg0OTksIDB4NDk5LCAweDQ5OSwgMHg0OTksIDB4NDk5LCAweDQ5OSwgMHg0OTksIDB4NDk5LCAweDQ5OSwgCiAgICAgICAgMHg0OTksIDB4NDk5LCAweDQ5OSwgMHg0OTksIDB4NDk5LCAweDQ5OSwgMHg0OTksIDB4NDk5LCAweDQ5OSwgMHg0OTksIDB4NDk5LCAweDQxNCwgMHg0MTQsIDB4NDE0LCAweDQxNCwgMHgyMDAsIAogICAgICAgIDB4MDAwLCAweDAwMCwgMHgwMDAsIDB4MDAwLCAweDAwMCwgMHgwMDAsIDB4MDAwLCAweDAwMCwgMHgwMDAsIDB4MDAwLCAweDAwMCwgMHgwMDAsIDB4MDAwLCAweDAwMCwgMHgwMDAsIDB4MDAwLCAKICAgICAgICAweDAwMCwgMHgwMDAsIDB4MDAwLCAweDAwMCwgMHgwMDAsIDB4MDAwLCAweDAwMCwgMHgwMDAsIDB4MDAwLCAweDAwMCwgMHgwMDAsIDB4MDAwLCAweDAwMCwgMHgwMDAsIDB4MDAwLCAweDAwMCwgCiAgICAgICAgMHgwMDAsIDB4MDAwLCAweDAwMCwgMHgwMDAsIDB4MDAwLCAweDAwMCwgMHgwMDAsIDB4MDAwLCAweDAwMCwgMHgwMDAsIDB4MDAwLCAweDAwMCwgMHgwMDAsIDB4MDAwLCAweDAwMCwgMHgwMDAsIAogICAgICAgIDB4MDAwLCAweDAwMCwgMHgwMDAsIDB4MDAwLCAweDAwMCwgMHgwMDAsIDB4MDAwLCAweDAwMCwgMHgwMDAsIDB4MDAwLCAweDAwMCwgMHgwMDAsIDB4MDAwLCAweDAwMCwgMHgwMDAsIDB4MDAwLCAKICAgICAgICAweDAwMCwgMHgwMDAsIDB4MDAwLCAweDAwMCwgMHgwMDAsIDB4MDAwLCAweDAwMCwgMHgwMDAsIDB4MDAwLCAweDAwMCwgMHgwMDAsIDB4MDAwLCAweDAwMCwgMHgwMDAsIDB4MDAwLCAweDAwMCwgCiAgICAgICAgMHgwMDAsIDB4MDAwLCAweDAwMCwgMHgwMDAsIDB4MDAwLCAweDAwMCwgMHgwMDAsIDB4MDAwLCAweDAwMCwgMHgwMDAsIDB4MDAwLCAweDAwMCwgMHgwMDAsIDB4MDAwLCAweDAwMCwgMHgwMDAsIAogICAgICAgIDB4MDAwLCAweDAwMCwgMHgwMDAsIDB4MDAwLCAweDAwMCwgMHgwMDAsIDB4MDAwLCAweDAwMCwgMHgwMDAsIDB4MDAwLCAweDAwMCwgMHgwMDAsIDB4MDAwLCAweDAwMCwgMHgwMDAsIDB4MDAwLCAKICAgICAgICAweDAwMCwgMHgwMDAsIDB4MDAwLCAweDAwMCwgMHgwMDAsIDB4MDAwLCAweDAwMCwgMHgwMDAsIDB4MDAwLCAweDAwMCwgMHgwMDAsIDB4MDAwLCAweDAwMCwgMHgwMDAsIDB4MDAwLCAweDAwMAp9OwoKc3RhdGljIGNvbnN0IHNpemVfdCBzdGRfY2xhc3NfY250ID0gIHNpemVvZihzdGRfY2xhc3MpL3NpemVvZihzdGRfY2xhc3NbMF0pOwoKLyogUHJvdG90eXBlcyAqLwpzdGF0aWMgaW50IGFkZF9wYXR0ZXJuKHN0cnVjdCByZWdleF9tYXRjaGVyKiBtYXRjaGVyLGNvbnN0IHVuc2lnbmVkIGNoYXIqIHBhdCxjb25zdCBjaGFyKiBpbmZvLGludCBob3N0T25seSk7CnN0YXRpYyBpbnQgbWF0Y2hfbm9kZShzdHJ1Y3QgdHJlZV9ub2RlKiBub2RlLGNvbnN0IHVuc2lnbmVkIGNoYXIqIGMsc2l6ZV90IGxlbixjb25zdCBjaGFyKiogaW5mbyk7CnN0YXRpYyB2b2lkIGRlc3Ryb3lfdHJlZShzdHJ1Y3QgcmVnZXhfbWF0Y2hlciogbWF0Y2hlcik7CnN0YXRpYyBzdHJ1Y3QgdHJlZV9ub2RlKiB0cmVlX3Jvb3RfYWxsb2Modm9pZCk7CnN0YXRpYyBpbnQgYnVpbGRfcmVnZXhfbGlzdChzdHJ1Y3QgcmVnZXhfbWF0Y2hlciogbWF0Y2hlcik7CnN0YXRpYyB2b2lkIHN0YWNrX2Rlc3Ryb3koc3RydWN0IG5vZGVfc3RhY2sqIHN0YWNrKTsKCiNpZm5kZWYgTkRFQlVHCnZvaWQgZHVtcF90cmVlKHN0cnVjdCB0cmVlX25vZGUqIHJvb3QpOwojZW5kaWYKCiNkZWZpbmUgTUFUQ0hfU1VDQ0VTUyAwIAojZGVmaW5lIE1BVENIX0ZBSUxFRCAgLTEKCi8qCiAqIENhbGwgdGhpcyBmdW5jdGlvbiB3aGVuIGFuIHVucmVjb3ZlcmFibGUgZXJyb3IgaGFzIG9jY3VyZWQsIChpbnN0ZWFkIG9mIGV4aXQpLgogKi8Kc3RhdGljIHZvaWQgZmF0YWxfZXJyb3Ioc3RydWN0IHJlZ2V4X21hdGNoZXIqIG1hdGNoZXIpCnsKCXJlZ2V4X2xpc3RfZG9uZShtYXRjaGVyKTsKCW1hdGNoZXItPmxpc3RfaW5pdGVkID0gLTE7LyogdGhlIHBoaXNoaW5nIG1vZHVsZSB3aWxsIGtub3cgd2UgdHJpZWQgdG8gbG9hZCBhIHdoaXRlbGlzdCwgYW5kIGZhaWxlZCwgc28gaXQgd2lsbCBkaXNhYmxlIGl0c2VsZiB0b28qLwp9CgoKc3RhdGljIGlubGluZSBzaXplX3QgZ2V0X2NoYXJfYXRfcG9zX3dpdGhfc2tpcChjb25zdCBzdHJ1Y3QgcHJlX2ZpeHVwX2luZm8qIGluZm8sIGNvbnN0IGNoYXIqIGJ1ZmZlciwgc2l6ZV90IHBvcykKewoJY29uc3QgY2hhciogc3RyOwoJc2l6ZV90IHJlYWxwb3MgPSAwOwoJaWYoIWluZm8pIHsKCQlyZXR1cm4gKHBvcyA8PSBzdHJsZW4oYnVmZmVyKSkgPyBidWZmZXJbcG9zPjAgPyBwb3MtMTowXSA6ICdcMCc7Cgl9CglzdHIgPSBpbmZvLT5wcmVfZGlzcGxheUxpbmsuZGF0YTsKCWNsaV9kYmdtc2coImNhbGNfcG9zX3dpdGhfc2tpcDogc2tpcDolbHUsICVsdSAtICVsdSBcIiVzXCIsXCIlc1wiXG4iLCBwb3MsIGluZm8tPmhvc3Rfc3RhcnQsIGluZm8tPmhvc3RfZW5kLCBzdHIsIGJ1ZmZlcik7Cglwb3MgKz0gaW5mby0+aG9zdF9zdGFydDsKCXdoaWxlKHN0cltyZWFscG9zXSAmJiAhaXNhbG51bShzdHJbcmVhbHBvc10pKSByZWFscG9zKys7Cglmb3IoOyBzdHJbcmVhbHBvc10gJiYgKHBvcz4wKTsgcG9zLS0pIHsKCQl3aGlsZShzdHJbcmVhbHBvc109PScgJykgcmVhbHBvcysrOwoJCXJlYWxwb3MrKzsKCX0KCXdoaWxlKHN0cltyZWFscG9zXT09JyAnKSByZWFscG9zKys7CgljbGlfZGJnbXNnKCJjYWxjX3Bvc193aXRoX3NraXA6JXNcbiIsc3RyK3JlYWxwb3MpOwkKCXJldHVybiAocG9zPjAgJiYgIXN0cltyZWFscG9zXSkgPyAnXDAnIDogc3RyW3JlYWxwb3M+MD9yZWFscG9zLTE6MF07Cn0KCi8qCiAqIEBtYXRjaGVyIC0gbWF0Y2hlciBzdHJ1Y3R1cmUgdG8gdXNlCiAqIEByZWFsX3VybCAtIGhyZWYgdGFyZ2V0CiAqIEBkaXNwbGF5X3VybCAtIDxhPiB0YWcgY29udGVudHMKICogQGhvc3RPbmx5IC0gaWYgeW91IHdhbnQgdG8gbWF0Y2ggb25seSB0aGUgaG9zdCBwYXJ0CiAqIEBpc193aGl0ZWxpc3QgLSBpcyB0aGlzIGEgbG9va3VwIGluIHdoaXRlbGlzdD8KICoKICogQHJldHVybiAtIENMX1NVQ0NFU1MgLSB1cmwgZG9lc24ndCBtYXRjaAogKiAgICAgICAgIC0gQ0xfVklSVVMgLSB1cmwgbWF0Y2hlcyBsaXN0CiAqCiAqIERvIG5vdCBzZW5kIE5VTEwgcG9pbnRlcnMgdG8gdGhpcyBmdW5jdGlvbiEhCiAqCiAqLwppbnQgcmVnZXhfbGlzdF9tYXRjaChzdHJ1Y3QgcmVnZXhfbWF0Y2hlciogbWF0Y2hlcixjaGFyKiByZWFsX3VybCxjb25zdCBjaGFyKiBkaXNwbGF5X3VybCxjb25zdCBzdHJ1Y3QgcHJlX2ZpeHVwX2luZm8qIHByZV9maXh1cCxpbnQgaG9zdE9ubHksY29uc3QgY2hhcioqIGluZm8saW50IGlzX3doaXRlbGlzdCkKewoJbWFzc2VydChtYXRjaGVyKTsKCW1hc3NlcnQocmVhbF91cmwpOwoJbWFzc2VydChkaXNwbGF5X3VybCk7CgltYXNzZXJ0KGluZm8pOwoJaWYoIW1hdGNoZXItPmxpc3RfaW5pdGVkKQoJCXJldHVybiAwOwoJbWFzc2VydChtYXRjaGVyLT5saXN0X2J1aWx0KTsKCXsKCQlzaXplX3QgcmVhbF9sZW4gICAgPSBzdHJsZW4ocmVhbF91cmwpOwoJCXNpemVfdCBkaXNwbGF5X2xlbiA9IHN0cmxlbihkaXNwbGF5X3VybCk7CgkJc2l6ZV90IGJ1ZmZlcl9sZW4gID0gKGhvc3RPbmx5ICYmICFpc193aGl0ZWxpc3QpID8gcmVhbF9sZW4gOiByZWFsX2xlbiArIGRpc3BsYXlfbGVuICsgMSArIChpc193aGl0ZWxpc3QgPyAxIDogMCk7CgkJY2hhciogIGJ1ZmZlciA9IGNsaV9tYWxsb2MoYnVmZmVyX2xlbisxKTsKCQlzaXplX3QgaTsKCQlpbnQgcmMgPSAwOwoJCXN0cnVjdCBjbGlfYWNfZGF0YSBtZGF0YTsKCgkJaWYoIWJ1ZmZlcikKCQkJcmV0dXJuIENMX0VNRU07CgoJCXN0cm5jcHkoYnVmZmVyLHJlYWxfdXJsLHJlYWxfbGVuKTsKCQlidWZmZXJbcmVhbF9sZW5dPSAoIWlzX3doaXRlbGlzdCAmJiBob3N0T25seSkgPyAnXDAnIDogJzonOwoJCWlmKCFob3N0T25seSB8fCBpc193aGl0ZWxpc3QpIHsKCQkJc3RybmNweShidWZmZXIrcmVhbF9sZW4rMSxkaXNwbGF5X3VybCxkaXNwbGF5X2xlbik7CgkJCWlmKGlzX3doaXRlbGlzdCkgCgkJCQlidWZmZXJbYnVmZmVyX2xlbiAtIDFdID0gJy8nOwoJCQlidWZmZXJbYnVmZmVyX2xlbl09MDsKCQl9CgkJY2xpX2RiZ21zZygiTG9va2luZyB1cCBpbiByZWdleF9saXN0OiAlc1xuIiwgYnVmZmVyKTsKCgkJaWYoaG9zdE9ubHkpIHsKCQkJaWYoKHJjID0gY2xpX2FjX2luaXRkYXRhKCZtZGF0YSwgMCwgQUNfREVGQVVMVF9UUkFDS0xFTikpKQoJCQkJcmV0dXJuIHJjOwoJCQlyYyA9IDA7CgoJCQlmb3IoaSA9IDA7IGkgPCBtYXRjaGVyLT5yb290X2hvc3RzX2NudDsgaSsrKSB7CgkJCQkvKiBkb2Vzbid0IG5lZWQgdG8gbWF0Y2ggdGVybWluYXRpbmcgXDAqLwoJCQkJcmMgPSBjbGlfYWNfc2NhbmJ1ZmYoKHVuc2lnbmVkIGNoYXIqKWJ1ZmZlcixidWZmZXJfbGVuLGluZm8sICZtYXRjaGVyLT5yb290X2hvc3RzW2ldICwmbWRhdGEsMCwwLDAsLTEsTlVMTCk7CgkJCQljbGlfYWNfZnJlZWRhdGEoJm1kYXRhKTsKCQkJCWlmKHJjKSB7CgkJCQkJY2hhciBjOwoJCQkJCWNvbnN0IGNoYXIqIG1hdGNoZWQgPSBzdHJjaHIoKmluZm8sJzonKTsJCgkJCQkJY29uc3Qgc2l6ZV90IG1hdGNoX2xlbiA9IG1hdGNoZWQgPyBzdHJsZW4obWF0Y2hlZCsxKSA6IDA7CgkJCQkJaWYoKChjPWdldF9jaGFyX2F0X3Bvc193aXRoX3NraXAocHJlX2ZpeHVwLGJ1ZmZlcixidWZmZXJfbGVuKzEpKT09JyAnIHx8IGM9PSdcMCcgfHwgYz09Jy8nIHx8IGM9PSc/JykgJiYKCQkJCQkJKG1hdGNoX2xlbiA9PSBidWZmZXJfbGVuIHx8IC8qIGZ1bGwgbWF0Y2ggKi8KCQkJCQkgICAgICAgIChtYXRjaF9sZW4gPCBidWZmZXJfbGVuICYmCgkJCQkJCSgoYz1nZXRfY2hhcl9hdF9wb3Nfd2l0aF9za2lwKHByZV9maXh1cCxidWZmZXIsYnVmZmVyX2xlbi1tYXRjaF9sZW4pKT09Jy4nIHx8IChjPT0nICcpKSApIAoJCQkJCQkvKiBzdWJkb21haW4gbWF0Y2hlZCovKSkgewoKCQkJCQkJY2xpX2RiZ21zZygiR290IGEgbWF0Y2g6ICVzIHdpdGggJXNcbiIsYnVmZmVyLCppbmZvKTsKCQkJCQkJY2xpX2RiZ21zZygiQmVmb3JlIGluc2VydGluZyAuOiAlc1xuIixyZWFsX3VybCk7CgkJCQkJCWlmKHJlYWxfbGVuID49IG1hdGNoX2xlbiArIDEpIHsKCQkJCQkJCXJlYWxfdXJsW3JlYWxfbGVuLW1hdGNoX2xlbi0xXT0nLic7CgkJCQkJCQljbGlfZGJnbXNnKCJBZnRlciBpbnNlcnRpbmcgLjogJXNcbiIscmVhbF91cmwpOwoJCQkJCQl9CgkJCQkJCWJyZWFrOwoJCQkJCX0KCQkJCQljbGlfZGJnbXNnKCJJZ25vcmluZyBmYWxzZSBtYXRjaDogJXMgd2l0aCAlcywlY1xuIixidWZmZXIsKmluZm8sYyk7CgkJCQkJcmM9MDsKCQkJCX0KCQkJfQoJCX0gZWxzZQoJCQlyYyA9IDA7CiAgICAKCQlpZighcmMpIAoJCQlyYyA9IG1hdGNoX25vZGUoaG9zdE9ubHkgPyBtYXRjaGVyLT5yb290X3JlZ2V4X2hvc3Rvbmx5IDogbWF0Y2hlci0+cm9vdF9yZWdleCwodW5zaWduZWQgY2hhciopYnVmZmVyLGJ1ZmZlcl9sZW4saW5mbykgPT0gTUFUQ0hfU1VDQ0VTUyA/IENMX1ZJUlVTIDogQ0xfU1VDQ0VTUzsKCQlmcmVlKGJ1ZmZlcik7CgkJaWYoIXJjKQoJCQljbGlfZGJnbXNnKCJMb29rdXAgcmVzdWx0OiBub3QgaW4gcmVnZXggbGlzdFxuIik7CgkJZWxzZQoJCQljbGlfZGJnbXNnKCJMb29rdXAgcmVzdWx0OiBpbiByZWdleCBsaXN0XG4iKTsKCQlyZXR1cm4gcmM7Cgl9Cn0KCi8qIG5vZGUgc3RhY2sgKi8KI2RlZmluZSBOT0RFX1NUQUNLX0lOSVRJQUwgMTAyNAojZGVmaW5lIE5PREVfU1RBQ0tfR1JPVyAgICA0MDk2Ci8qIEluaXRpYWxpemUgQHN0YWNrICovCnN0YXRpYyBpbnQgc3RhY2tfaW5pdChzdHJ1Y3Qgbm9kZV9zdGFjayogc3RhY2spCnsKCW1hc3NlcnQoc3RhY2spOwoKCXN0YWNrLT5jbnQgPSAwOwoJc3RhY2stPmNhcGFjaXR5ID0gTk9ERV9TVEFDS19JTklUSUFMOwoJc3RhY2stPmRhdGEgPSBjbGlfbWFsbG9jKHN0YWNrLT5jYXBhY2l0eSAqIHNpemVvZigqc3RhY2stPmRhdGEpKTsKCWlmKCFzdGFjay0+ZGF0YSkKCQlyZXR1cm4gQ0xfRU1FTTsKCWVsc2UKCQlyZXR1cm4gQ0xfU1VDQ0VTUzsKfQoKLyogUmVzZXQgQHN0YWNrIHBvaW50ZXIsIGJ1dCBkb24ndCByZWFsbG9jICovCnN0YXRpYyB2b2lkIHN0YWNrX3Jlc2V0KHN0cnVjdCBub2RlX3N0YWNrKiBzdGFjaykKewoJbWFzc2VydChzdGFjayk7CgoJc3RhY2stPmNudCA9IDA7Cn0KCi8qIFB1c2ggQG5vZGUgb24gQHN0YWNrLCBncm93aW5nIGl0IGlmIG5lY2Vzc2FycnkgKi8Kc3RhdGljIGludCBzdGFja19wdXNoKHN0cnVjdCBub2RlX3N0YWNrKiBzdGFjayxzdHJ1Y3QgdHJlZV9ub2RlKiBub2RlKQp7CgltYXNzZXJ0KHN0YWNrKTsKCW1hc3NlcnQoc3RhY2stPmRhdGEpOwoKCWlmKHN0YWNrLT5jbnQgPT0gc3RhY2stPmNhcGFjaXR5KSB7CgkJc3RhY2stPmNhcGFjaXR5ICs9IE5PREVfU1RBQ0tfR1JPVzsKCQlzdGFjay0+ZGF0YSA9IGNsaV9yZWFsbG9jMihzdGFjay0+ZGF0YSxzdGFjay0+Y2FwYWNpdHkqc2l6ZW9mKCpzdGFjay0+ZGF0YSkpOwoJCWlmKCFzdGFjay0+ZGF0YSkKCQkJcmV0dXJuIENMX0VNRU07Cgl9CglzdGFjay0+ZGF0YVtzdGFjay0+Y250KytdID0gbm9kZTsKCXJldHVybiBDTF9TVUNDRVNTOwp9CgovKiBQb3BzIG5vZGUgZnJvbSBAc3RhY2ssIGRvZXNuJ3QgcmVhbGxvYyAqLwpzdGF0aWMgc3RydWN0IHRyZWVfbm9kZSogc3RhY2tfcG9wKHN0cnVjdCBub2RlX3N0YWNrKiBzdGFjaykKewoJbWFzc2VydChzdGFjayk7CgltYXNzZXJ0KHN0YWNrLT5kYXRhKTsKCW1hc3NlcnQoc3RhY2stPmNudCk7Lypkb24ndCBwb3AgZnJvbSBlbXB0eSBzdGFjayAqLwoKCXJldHVybiBzdGFjay0+Y250ID8gc3RhY2stPmRhdGFbLS1zdGFjay0+Y250XSA6IE5VTEw7Cn0KCi8qIEluaXRpYWxpemF0aW9uICYgbG9hZGluZyAqLwovKiBJbml0aWFsaXplcyBAbWF0Y2hlciwgYWxsb2NhdGluZyBuZWNlc2Fycnkgc3Vic3RydWN0dXJlcyAqLwppbnQgaW5pdF9yZWdleF9saXN0KHN0cnVjdCByZWdleF9tYXRjaGVyKiBtYXRjaGVyKQp7CglpbnQgcmM7CgoJbWFzc2VydChtYXRjaGVyKTsKCW1hdGNoZXItPmxpc3RfaW5pdGVkID0gMDsKIAltYXRjaGVyLT5yb290X2hvc3RzX2NudCA9IDA7CiAJbWF0Y2hlci0+cm9vdF9ob3N0cyA9IE5VTEw7CiAJbWF0Y2hlci0+cm9vdF9ob3N0c19jbnQgPSAwOwoKCW1hdGNoZXItPnJvb3RfcmVnZXggPSB0cmVlX3Jvb3RfYWxsb2MoKTsKCWlmKCFtYXRjaGVyLT5yb290X3JlZ2V4KSB7CgkJcmV0dXJuIENMX0VNRU07Cgl9CgoJbWF0Y2hlci0+cm9vdF9yZWdleF9ob3N0b25seSA9IHRyZWVfcm9vdF9hbGxvYygpOwoJaWYoIW1hdGNoZXItPnJvb3RfcmVnZXhfaG9zdG9ubHkpIHsKCQlmcmVlKG1hdGNoZXItPnJvb3RfcmVnZXgpOwoJCXJldHVybiBDTF9FTUVNOwoJfQoKCWlmKCggcmMgPSBzdGFja19pbml0KCZtYXRjaGVyLT5ub2RlX3N0YWNrKSApKSB7CgkJZnJlZShtYXRjaGVyLT5yb290X3JlZ2V4X2hvc3Rvbmx5KTsKCQlmcmVlKG1hdGNoZXItPnJvb3RfcmVnZXgpOwoJCXJldHVybiByYzsKCX0KCWlmKCggcmMgPSBzdGFja19pbml0KCZtYXRjaGVyLT5ub2RlX3N0YWNrX2FsdCkgKSkgewoJCWZyZWUobWF0Y2hlci0+cm9vdF9yZWdleF9ob3N0b25seSk7CgkJZnJlZShtYXRjaGVyLT5yb290X3JlZ2V4KTsKCQlzdGFja19kZXN0cm95KCZtYXRjaGVyLT5ub2RlX3N0YWNrKTsKCQlyZXR1cm4gcmM7Cgl9CgoJbWF0Y2hlci0+bGlzdF9pbml0ZWQ9MTsKCW1hdGNoZXItPmxpc3RfYnVpbHQ9MTsvKiBpdHMgZW1wdHksIGJ1dCBwcmV0ZW5kIGl0cyBidWlsdCwgc28gdGhhdCBsb2FkXyB3aWxsIHJlYWxsb2Mgcm9vdF9ob3N0cyAqLwoJbWF0Y2hlci0+bGlzdF9sb2FkZWQ9MDsKCglyZXR1cm4gQ0xfU1VDQ0VTUzsKfQoKLyogaW5zZXJ0cyBAcGF0dGVybiBpbnRvIEByb290LCB1c2luZyBhYy1tYXRjaGVyIAogKiBhbHRob3VnaCB0aGUgbmFtZSBtaWdodCBiZSBjb25mdXNpbmcsIEBwYXR0ZXJuIGlzIG5vdCBhIHJlZ2V4ISovCnN0YXRpYyBpbnQgYWRkX3JlZ2V4X2xpc3RfZWxlbWVudChzdHJ1Y3QgY2xpX21hdGNoZXIqIHJvb3QsY29uc3QgY2hhciogcGF0dGVybixjaGFyKiBpbmZvKQp7CiAgICAgICBpbnQgcmV0OwogICAgICAgc3RydWN0IGNsaV9hY19wYXR0ICpuZXcgPSBjbGlfY2FsbG9jKDEsc2l6ZW9mKCpuZXcpKTsKICAgICAgIHNpemVfdCBsZW4saTsKCiAgICAgICBpZighbmV3KQoJICAgICAgIHJldHVybiBDTF9FTUVNOwogICAgICAgbWFzc2VydChyb290KTsKICAgICAgIG1hc3NlcnQocGF0dGVybik7CgogICAgICAgbGVuID0gc3RybGVuKHBhdHRlcm4pOwogICAgICAgLyogbmVlZCBub3QgdG8gbWF0Y2ggXDAgdG9vICovCiAgICAgICBuZXctPnR5cGUgPSAwOwogICAgICAgbmV3LT5zaWdpZCA9IDA7CiAgICAgICBuZXctPnBhcnRzID0gMDsKICAgICAgIG5ldy0+cGFydG5vID0gMDsKICAgICAgIG5ldy0+bWluZGlzdCA9IDA7CiAgICAgICBuZXctPm1heGRpc3QgPSAwOwogICAgICAgbmV3LT5vZmZzZXQgPSAwOwogICAgICAgbmV3LT50YXJnZXQgPSAwOwogICAgICAgbmV3LT5sZW5ndGggPSBsZW47CiAgICAgICBpZihuZXctPmxlbmd0aCA+IHJvb3QtPm1heHBhdGxlbikKICAgICAgICAgICAgICAgcm9vdC0+bWF4cGF0bGVuID0gbmV3LT5sZW5ndGg7CgogICAgICAgbmV3LT5wYXR0ZXJuID0gY2xpX21hbGxvYyhzaXplb2YobmV3LT5wYXR0ZXJuWzBdKSpsZW4pOwogICAgICAgaWYoIW5ldy0+cGF0dGVybikgewoJICAgICAgIGZyZWUobmV3KTsKCSAgICAgICByZXR1cm4gQ0xfRU1FTTsKICAgICAgIH0KICAgICAgIGZvcihpPTA7aTxsZW47aSsrKQoJICAgICAgIG5ldy0+cGF0dGVybltpXT1wYXR0ZXJuW2ldOy8qbmV3LT5wYXR0ZXJuIGlzIHNob3J0IGludCogKi8KCgkKICAgICAgIG5ldy0+dmlybmFtZSA9IGNsaV9zdHJkdXAoaW5mbyk7CiAgICAgICBpZigocmV0ID0gY2xpX2FjX2FkZHBhdHQocm9vdCxuZXcpKSkgewoJICAgICAgIGZyZWUobmV3LT52aXJuYW1lKTsKICAgICAgICAgICAgICAgZnJlZShuZXctPnBhdHRlcm4pOwogICAgICAgICAgICAgICBmcmVlKG5ldyk7CiAgICAgICAgICAgICAgIHJldHVybiByZXQ7CiAgICAgICB9CiAgICAgICByZXR1cm4gQ0xfU1VDQ0VTUzsKfQoKc3RhdGljIGludCBmdW5jdGlvbmFsaXR5X2xldmVsX2NoZWNrKGNoYXIqIGxpbmUpCnsKCWNoYXIqIHB0bWluOwoJY2hhciogcHRtYXg7CglzaXplX3QgajsKCglwdG1pbiA9IHN0cnJjaHIobGluZSwnOicpOwoJaWYoIXB0bWluKSAKCQlyZXR1cm4gQ0xfU1VDQ0VTUzsKCQoJcHRtaW4rKzsKCglwdG1heCA9IHN0cmNocihwdG1pbiwnLScpOwoJaWYoIXB0bWF4KSAKCQlyZXR1cm4gQ0xfU1VDQ0VTUzsvKiB0aGVyZSBpcyBubyBmdW5jdGlvbmFsaXR5IGxldmVsIHNwZWNpZmllZCwgc28gd2UncmUgb2sgKi8KCWVsc2UgewoJCXNpemVfdCBtaW4sIG1heDsKCQlwdG1heCsrOwoJCWZvcihqPTA7aitwdG1pbisxIDwgcHRtYXg7aisrKQoJCQlpZighaXNkaWdpdChwdG1pbltqXSkpIAoJCQkJcmV0dXJuIENMX1NVQ0NFU1M7Lyogbm90IG51bWJlcnMsIG5vdCBmdW5jdGlvbmFsaXR5IGxldmVsICovCgkJZm9yKGo9MDtqPHN0cmxlbihwdG1heCk7aisrKQoJCQlpZighaXNkaWdpdChwdG1heFtqXSkpIAoJCQkJcmV0dXJuIENMX1NVQ0NFU1M7Lyogc2VlIGFib3ZlICovCgkJcHRtYXhbLTFdPSdcMCc7CgkJbWluID0gYXRvaShwdG1pbik7CgkJaWYoc3RybGVuKHB0bWF4KT09MCkKIAkJCW1heCA9IElOVF9NQVg7IAkJCgkJZWxzZQoJCQltYXggPSBhdG9pKHB0bWF4KTsKCgkJaWYobWluID4gY2xfcmV0ZmxldmVsKCkpIHsKCQkJY2xpX2RiZ21zZygicmVnZXggbGlzdCBsaW5lICVzIG5vdCBsb2FkZWQgKHJlcXVpcmVkIGYtbGV2ZWw6ICV1KVxuIixsaW5lLCh1bnNpZ25lZCBpbnQpbWluKTsKCQkJcmV0dXJuIENMX0VNQUxGREI7IAoJCX0KCgkJaWYobWF4IDwgY2xfcmV0ZmxldmVsKCkpIAoJCQlyZXR1cm4gQ0xfRU1BTEZEQjsKCQlwdG1pblstMV09J1wwJzsKCQlyZXR1cm4gQ0xfU1VDQ0VTUzsKCX0JCQp9CgoKLyogTG9hZCBwYXR0ZXJucy9yZWdleGVzIGZyb20gZmlsZSAqLwppbnQgbG9hZF9yZWdleF9tYXRjaGVyKHN0cnVjdCByZWdleF9tYXRjaGVyKiBtYXRjaGVyLEZJTEUqIGZkLHVuc2lnbmVkIGludCBvcHRpb25zLGludCBpc193aGl0ZWxpc3QpCnsKCWludCByYyxsaW5lPTA7CgljaGFyIGJ1ZmZlcltGSUxFQlVGRl07CgoJbWFzc2VydChtYXRjaGVyKTsKCW1hc3NlcnQoZmQpOwoKCWlmKG1hdGNoZXItPmxpc3RfaW5pdGVkPT0tMSkKCQlyZXR1cm4gQ0xfRU1BTEZEQjsgLyogYWxyZWFkeSBmYWlsZWQgdG8gbG9hZCAqLwovKglpZihtYXRjaGVyLT5saXN0X2xvYWRlZCkgewoJCWNsaV93YXJubXNnKCJSZWdleCBsaXN0IGhhcyBhbHJlYWR5IGJlZW4gbG9hZGVkLCBpZ25vcmluZyBmdXJ0aGVyIHJlcXVlc3RzIGZvciBsb2FkXG4iKTsKCQlyZXR1cm4gQ0xfU1VDQ0VTUzsKCX0qLwoJaWYoIWZkKSB7CgkJY2xpX2Vycm1zZygiVW5hYmxlIHRvIGxvYWQgcmVnZXggbGlzdCAobnVsbCBmaWxlKVxuIik7CgkJcmV0dXJuIENMX0VJTzsKCX0KCgljbGlfZGJnbXNnKCJMb2FkaW5nIHJlZ2V4X2xpc3RcbiIpOwoJaWYoIW1hdGNoZXItPmxpc3RfaW5pdGVkKSB7CgkJcmMgPSBpbml0X3JlZ2V4X2xpc3QobWF0Y2hlcik7CgkJaWYgKCFtYXRjaGVyLT5saXN0X2luaXRlZCkgewoJCQljbGlfZXJybXNnKCJSZWdleCBsaXN0IGZhaWxlZCB0byBpbml0aWFsaXplIVxuIik7CgkJCWZhdGFsX2Vycm9yKG1hdGNoZXIpOwoJCQlyZXR1cm4gcmM7CgkJfQoJCS8qYXRleGl0KHJlZ2V4X2xpc3RfZG9uZSk7IFRPRE86IGRlc3Ryb3kgdGhpcyBpbiBtYW5hZ2VyLmMgKi8KCX0KCS8qCgkgKiBSZWdleGxpc3QgZGIgZm9ybWF0IChjb21tb24gdG8gLndkYih3aGl0ZWxpc3QpIGFuZCAucGRiKGRvbWFpbmxpc3QpIGZpbGVzOgoJICogTXVsdGlwbGUgbGluZXMgb2YgZm9ybSwgKGVtcHR5IGxpbmVzIGFyZSBza2lwcGVkKToKIAkgKiBGbGFncyBSZWFsVVJMIERpc3BsYXllZFVSTAoJICogV2hlcmU6CgkgKiBGbGFnczogCgkgKgoJICogLnBkYiBmaWxlczoKCSAqIFIgLSByZWdleCwgSCAtIGhvc3Qtb25seSwgZm9sbG93ZWQgYnkgKG9wdGlvbmFsKSAzLWRpZ2l0IGhleG51bWJlciByZXByZXNlbnRpbmcgCgkgKiBmbGFncyB0aGF0IHNob3VsZCBiZSBmaWx0ZXJlZC4KCSAqIFtpLmUuIHBoaXNoY2hlY2sgdXJscy5mbGFncyB0aGF0IHdlIGRvbid0IHdhbnQgdG8gYmUgZG9uZSBmb3IgdGhpcyBwYXJ0aWN1bGFyIGhvc3RdCgkgKiAKCSAqIC53ZGIgZmlsZXM6CgkgKiBYIC0gZnVsbCBVUkwgcmVnZXggCgkgKiBZIC0gaG9zdC1vbmx5IHJlZ2V4CgkgKiBNIC0gaG9zdCBzaW1wbGUgcGF0dGVybgoJICoKCSAqIElmIGEgbGluZSBpbiB0aGUgZmlsZSBkb2Vzbid0IGNvbmZvcm0gdG8gdGhpcyBmb3JtYXQsIGxvYWRpbmcgZmFpbHMKCSAqIAoJICovCgl3aGlsZShmZ2V0cyhidWZmZXIsRklMRUJVRkYsZmQpKSB7CgkJY2hhciogcGF0dGVybjsKCQljaGFyKiBmbGFnczsKCQljbGlfY2hvbXAoYnVmZmVyKTsKCQlpZighKmJ1ZmZlcikKCQkJY29udGludWU7Lyogc2tpcCBlbXB0eSBsaW5lcyAqLwoKCQlpZihmdW5jdGlvbmFsaXR5X2xldmVsX2NoZWNrKGJ1ZmZlcikpIAoJCQljb250aW51ZTsKCgkJbGluZSsrOwoJCXBhdHRlcm4gPSBzdHJjaHIoYnVmZmVyLCc6Jyk7CgkJaWYoIXBhdHRlcm4pIHsKCQkJY2xpX2Vycm1zZygiTWFsZm9ybWVkIHJlZ2V4IGxpc3QgbGluZSAlZFxuIixsaW5lKTsKCQkJZmF0YWxfZXJyb3IobWF0Y2hlcik7CgkJCXJldHVybiBDTF9FTUFMRkRCOwoJCX0KCQkvKnBhdHRlcm5bMF09J1wwJzsqLwoJCWZsYWdzID0gYnVmZmVyKzE7CgkJcGF0dGVybisrOwoKCQlpZihpc193aGl0ZWxpc3QpIHsKCQkJY29uc3Qgc2l6ZV90IHBhdHRlcm5fbGVuID0gc3RybGVuKHBhdHRlcm4pOwoJCQlpZihwYXR0ZXJuX2xlbiA8IEZJTEVCVUZGKSB7CgkJCQlwYXR0ZXJuW3BhdHRlcm5fbGVuXSA9ICcvJzsKCQkJCXBhdHRlcm5bcGF0dGVybl9sZW4rMV0gPSAnXDAnOwoJCQl9CgkJCWVsc2UgewoJCQkJY2xpX2Vycm1zZygiT3ZlcmxvbmcgcmVnZXggbGluZSAlZFxuIixsaW5lKTsKCQkJCWZhdGFsX2Vycm9yKG1hdGNoZXIpOwoJCQkJcmV0dXJuIENMX0VNQUxGREI7CgkJCX0KCQl9CgoJCWlmKChidWZmZXJbMF0gPT0gJ1InICYmICFpc193aGl0ZWxpc3QpIHx8ICgoYnVmZmVyWzBdID09ICdYJyB8fCBidWZmZXJbMF0gPT0gJ1knKSAmJiBpc193aGl0ZWxpc3QpKSB7LypyZWdleCovCgkJCWlmKCggcmMgPSBhZGRfcGF0dGVybihtYXRjaGVyLChjb25zdCB1bnNpZ25lZCBjaGFyKilwYXR0ZXJuLGZsYWdzLCBidWZmZXJbMF0gPT0gJ1knKSApKQoJCQkJcmV0dXJuIHJjPT1DTF9FTUVNID8gQ0xfRU1FTSA6IENMX0VNQUxGREI7CgkJfQoJCWVsc2UgaWYoICggYnVmZmVyWzBdID09ICdIJyAmJiAhaXNfd2hpdGVsaXN0KSB8fCAoYnVmZmVyWzBdID09ICdNJyAmJiBpc193aGl0ZWxpc3QpKSB7LyptYXRjaGVzIGRpc3BsYXllZCBob3N0Ki8KCQkJc3RydWN0IGNsaV9tYXRjaGVyKiByb290OwogCQkJaWYobWF0Y2hlci0+bGlzdF9idWlsdCkgewogCQkJCXN0cnVjdCBjbGlfbWF0Y2hlciogb2xkX2hvc3RzID0gbWF0Y2hlci0+cm9vdF9ob3N0czsKIAkJCQltYXRjaGVyLT5yb290X2hvc3RzX2NudCsrOwogCiAJCQkJbWF0Y2hlci0+cm9vdF9ob3N0cyA9IGNsaV9yZWFsbG9jKG1hdGNoZXItPnJvb3RfaG9zdHMsIG1hdGNoZXItPnJvb3RfaG9zdHNfY250ICogc2l6ZW9mKCptYXRjaGVyLT5yb290X2hvc3RzKSk7CiAJCQkJaWYoIW1hdGNoZXItPnJvb3RfaG9zdHMpIHsKIAkJCQkJbWF0Y2hlci0+cm9vdF9ob3N0cyA9IG9sZF9ob3N0czsvKiBhY2NvcmRpbmcgdG8gbWFucGFnZSB0aGlzIG11c3Qgc3RpbGwgYmUgdmFsaWQqLwogCQkJCQlyZXR1cm4gQ0xfRU1FTTsKCQkJCX0gCgoJCQkJcm9vdCA9ICZtYXRjaGVyLT5yb290X2hvc3RzW21hdGNoZXItPnJvb3RfaG9zdHNfY250LTFdOwogCQkJCW1lbXNldChyb290LCAwLCBzaXplb2Yoc3RydWN0IGNsaV9tYXRjaGVyKSk7CgoJCQkJY2xpX2RiZ21zZygicmVnZXhfbGlzdDogSW5pdGlhbGlzaW5nIEFDIHBhdHRlcm4gbWF0Y2hlclxuIik7CgkJCQlpZigocmMgPSBjbGlfYWNfaW5pdChyb290LCBjbGlfYWNfbWluZGVwdGgsIGNsaV9hY19tYXhkZXB0aCkpKSB7CgkJCQkJLyogbm8gbmVlZCB0byBmcmVlIHByZXZpb3VzbHkgYWxsb2NhdGVkIG1lbW9yeSBoZXJlICovCgkJCQkJY2xpX2Vycm1zZygicmVnZXhfbGlzdDogQ2FuJ3QgaW5pdGlhbGlzZSBBQyBwYXR0ZXJuIG1hdGNoZXJcbiIpOwoJCQkJCXJldHVybiByYzsKCQkJCX0KIAkJCQltYXRjaGVyLT5saXN0X2J1aWx0ID0gMDsKIAkJCX0KCQkJZWxzZSB7CgkJCQlyb290ID0gJm1hdGNoZXItPnJvb3RfaG9zdHNbbWF0Y2hlci0+cm9vdF9ob3N0c19jbnQtMV07CgkJCX0KIAkJCWlmKCggcmMgPSBhZGRfcmVnZXhfbGlzdF9lbGVtZW50KHJvb3QscGF0dGVybixmbGFncykgKSkKCQkJCXJldHVybiByYz09Q0xfRU1FTSA/IENMX0VNRU0gOiBDTF9FTUFMRkRCOwoJCX0KCQllbHNlIHsKCQkJcmV0dXJuIENMX0VNQUxGREI7CgkJCS8qIHRoaXMgaXMgdXNlbGVzcywgd2UgaGF2ZSBob3N0LCBhbmQgcmVnZXggbWF0Y2hlcwoJCQlpZigoIHJjID0gYWRkX3JlZ2V4X2xpc3RfZWxlbWVudChtYXRjaGVyLT5yb290X3VybHMscGF0dGVybixmbGFncykgKSkKCQkJCXJldHVybiByYz09Q0xfRU1FTSA/IENMX0VNRU0gOiBDTF9FTUFMRkRCOyovCgkJfQoJfQoJbWF0Y2hlci0+bGlzdF9sb2FkZWQgPSAxOwoJaWYoKCByYyA9IGJ1aWxkX3JlZ2V4X2xpc3QobWF0Y2hlcikgKSkKCQlyZXR1cm4gcmM7CgojaWZuZGVmIE5ERUJVRwovKgkJCWR1bXBfdHJlZShtYXRjaGVyLT5yb290X3JlZ2V4KTsqLwojZW5kaWYKCWlmKCFtYXRjaGVyLT5saXN0X2J1aWx0KSB7CgkJY2xpX2Vycm1zZygiUmVnZXggbGlzdCBub3QgbG9hZGVkOiBidWlsZCBmYWlsZWQhXG4iKTsKCQlmYXRhbF9lcnJvcihtYXRjaGVyKTsKCQlyZXR1cm4gQ0xfRU1BTEZEQjsKCX0KCXJlZ2V4X2xpc3RfY2xlYW51cChtYXRjaGVyKTsKCXJldHVybiBDTF9TVUNDRVNTOwp9CgoKc3RhdGljIHN0cnVjdCB0cmVlX25vZGUgKiogdHJlZV9ub2RlX2dldF9jaGlsZHJlbihjb25zdCBzdHJ1Y3QgdHJlZV9ub2RlKiBub2RlKQp7CglyZXR1cm4gbm9kZS0+b3A9PU9QX0NVU1RPTUNMQVNTID8gKG5vZGUtPnUuY2hpbGRyZW5bMV0gPyBub2RlLT51LmNoaWxkcmVuKzEgOiBOVUxMKSA6bm9kZS0+dS5jaGlsZHJlbjsKfQoKLyogQnVpbGQgdGhlIG1hdGNoZXIgbGlzdCAqLwpzdGF0aWMgaW50IGJ1aWxkX3JlZ2V4X2xpc3Qoc3RydWN0IHJlZ2V4X21hdGNoZXIqIG1hdGNoZXIpCnsKCWludCByYzsKCWlmKCFtYXRjaGVyLT5saXN0X2luaXRlZCB8fCAhbWF0Y2hlci0+bGlzdF9sb2FkZWQpIHsKCQljbGlfZXJybXNnKCJSZWdleCBsaXN0IG5vdCBsb2FkZWQhXG4iKTsKCQlyZXR1cm4gLTE7LypUT0RPOiBiZXR0ZXIgZXJyb3IgY29kZSAqLwoJfQoJY2xpX2RiZ21zZygiQnVpbGRpbmcgcmVnZXggbGlzdFxuIik7CglpZihtYXRjaGVyLT5yb290X2hvc3RzKQoJCWlmKCggcmMgPSBjbGlfYWNfYnVpbGR0cmllKCZtYXRjaGVyLT5yb290X2hvc3RzW21hdGNoZXItPnJvb3RfaG9zdHNfY250LTFdKSApKQogCQkJcmV0dXJuIHJjOwoJbWF0Y2hlci0+bGlzdF9idWlsdD0xOwoKCXJldHVybiBDTF9TVUNDRVNTOwp9CgovKiBEb25lIHdpdGggdGhpcyBtYXRjaGVyLCBmcmVlIHJlc291cmNlcyAqLwp2b2lkIHJlZ2V4X2xpc3RfZG9uZShzdHJ1Y3QgcmVnZXhfbWF0Y2hlciogbWF0Y2hlcikKewoJbWFzc2VydChtYXRjaGVyKTsKCglyZWdleF9saXN0X2NsZWFudXAobWF0Y2hlcik7CglpZihtYXRjaGVyLT5saXN0X2xvYWRlZCkgewoJCWlmKG1hdGNoZXItPnJvb3RfaG9zdHMpIHsKCQkJc2l6ZV90IGk7CgkJCWZvcihpPTA7aTxtYXRjaGVyLT5yb290X2hvc3RzX2NudDtpKyspIAoJCQkJY2xpX2FjX2ZyZWUoJm1hdGNoZXItPnJvb3RfaG9zdHNbaV0pOwoJCQlmcmVlKG1hdGNoZXItPnJvb3RfaG9zdHMpOwoJCQltYXRjaGVyLT5yb290X2hvc3RzPU5VTEw7CgkJfQoKCQltYXRjaGVyLT5yb290X2hvc3RzX2NudD0wOwoJCW1hdGNoZXItPmxpc3RfYnVpbHQ9MDsKCQlkZXN0cm95X3RyZWUobWF0Y2hlcik7CgkJbWF0Y2hlci0+bGlzdF9sb2FkZWQ9MDsKCX0KCWlmKG1hdGNoZXItPmxpc3RfaW5pdGVkKSB7CgkJbWF0Y2hlci0+bGlzdF9pbml0ZWQ9MDsKCX0KCXN0YWNrX2Rlc3Ryb3koJm1hdGNoZXItPm5vZGVfc3RhY2spOwoJc3RhY2tfZGVzdHJveSgmbWF0Y2hlci0+bm9kZV9zdGFja19hbHQpOwp9CgovKiBUcmVlIG1hdGNoZXIgYWxnb3JpdGhtICovCnN0cnVjdCB0b2tlbl90CnsKCXVuaW9uIHsKCQljb25zdCB1bnNpZ25lZCBjaGFyKiBzdGFydDsKCQljaGFyX2JpdG1hcF9wICBiaXRtYXA7CgkJdW5zaWduZWQgY2hhciAgYzsKCX0gdTsKCXNpemVfdCBsZW47CgljaGFyICAgdHlwZTsKfTsKCmVudW0ge1RPS0VOX0NIQVIsVE9LRU5fRE9ULFRPS0VOX1BBUl9PUEVOLFRPS0VOX1BBUl9DTE9TRSxUT0tFTl9CUkFDS0VULFRPS0VOX0FMVCxUT0tFTl9SRUdFWCxUT0tFTl9ET05FfTsKCnN0YXRpYyBjb25zdCB1bnNpZ25lZCBjaGFyKiBnZXROZXh0VG9rZW4oY29uc3QgdW5zaWduZWQgY2hhciogcGF0LHN0cnVjdCB0b2tlbl90KiB0b2tlbikKewoJbWFzc2VydChwYXQpOwoJbWFzc2VydCh0b2tlbik7CgoJc3dpdGNoKCpwYXQpIHsKCQljYXNlICdcXCc6CgkJCXRva2VuLT50eXBlPVRPS0VOX0NIQVI7CgkJCXRva2VuLT51LmMgPSAqKCsrcGF0KTsKCQkJaWYoaXNsb3dlcih0b2tlbi0+dS5jKSkgewoJCQkJLyogaGFuZGxlIFxuLCBcdCwgZXRjLiAqLwoJCQkJY2hhciBmbXRbM10gPSB7J1xcJywgJ1wwJywgJ1wwJ307CgkJCQljaGFyIGM7CgoJCQkJZm10WzFdID0gdG9rZW4tPnUuYzsKCQkJCWlmKHNucHJpbnRmKCZjLDEsZm10KSE9MSkgewoJCQkJCXRva2VuLT50eXBlPVRPS0VOX1JFR0VYOwoJCQkJCXRva2VuLT51LnN0YXJ0ID0gcGF0OwoJCQkJfQoJCQkJZWxzZQoJCQkJCXRva2VuLT51LmM9YzsKCQkJfQoJCQl0b2tlbi0+bGVuID0gMTsKCQkJYnJlYWs7CgkJY2FzZSAnfCc6CgkJCXRva2VuLT50eXBlPVRPS0VOX0FMVDsKCQkJYnJlYWs7CgkJY2FzZSAnKic6CgkJY2FzZSAnKyc6CgkJY2FzZSAnPyc6CgkJY2FzZSAneyc6CgkJY2FzZSAnfSc6CgkJCXRva2VuLT50eXBlPVRPS0VOX1JFR0VYOwoJCQlicmVhazsKCQljYXNlICdbJzoKCQkJewoJCQkvKlRPRE86IGltcGxlbWVudCovCgkJCS8qc2VlIGlmIGl0IGlzIHNvbWV0aGluZyBzaW1wbGUgbGlrZSBhIGxpc3Qgb2YgY2hhcmFjdGVycywgYSByYW5nZSwgb3IgbmVnYXRlZCAuLi4qLwoJCQljb25zdCB1bnNpZ25lZCBjaGFyKiBvbGQ9cGF0Kys7Lyogc2F2ZSB0aGlzIGluIGNhc2Ugd2UgY2hhbmdlIG91ciBtaW5kIGFuZCBkZWNpZGUgdGhpcyBpcyB0b28gY29tcGxpY2F0ZWQgZm9yIHVzIHRvIGhhbmRsZSovCgkJCXVuc2lnbmVkIGNoYXIgcmFuZ2Vfc3RhcnQ9MDsKCQkJaW50IGhhc3ByZXYgPSAwOwoJCQljaGFyX2JpdG1hcF9wIGJpdG1hcCA9IGNsaV9tYWxsb2MoMzIpOwoJCQlpZighYml0bWFwKQoJCQkJcmV0dXJuIE5VTEw7CgkJCWlmICgqcGF0PT0nXicpIHsKCQkJCW1lbXNldChiaXRtYXAsMHhGRiwzMik7LyptYXRjaCBjaGFycyBub3QgaW4gYnJhY2tldHMqLwoJCQkJcGF0Kys7CgkJCX0KCQkJZWxzZQoJCQkJbWVtc2V0KGJpdG1hcCwweDAwLDMyKTsKCQkJZG8gewoJCQkJLyogbGl0ZXJhbCBdIGNhbiBiZSBmaXJzdCBjaGFyYWN0ZXIsIHNvIHRlc3QgZm9yIGl0IGF0IHRoZSBlbmQgb2YgdGhlIGxvb3AsIGZvciBleGFtcGxlOiBbXV0gKi8KCQkJCWlmICgqcGF0PT0nLScgJiYgaGFzcHJldikgewoJCQkJCS8qIGl0IGlzIGEgcmFuZ2UqLwoJCQkJCXVuc2lnbmVkIGNoYXIgcmFuZ2VfZW5kOwoJCQkJCXVuc2lnbmVkIGludCBjOwoJCQkJCW1hc3NlcnQocmFuZ2Vfc3RhcnQpOwoJCQkJCXBhdCsrOwoJCQkJCWlmIChwYXRbMF09PSdbJykKCQkJCQkJaWYgKHBhdFsxXT09Jy4nKSB7CgkJCQkJCQlpZihwYXRbMl09PSctJyAmJiBwYXRbM109PScuJyAmJiBwYXRbNF09PSddJykKCQkJCQkJCQlyYW5nZV9lbmQgPSAnLSc7CgkJCQkJCQllbHNlIHsKCQkJCQkJCQkvKiB0aGlzIGlzIGdldHRpbmcgY29tcGxpY2F0ZWQsIGJhaWwgb3V0ICovCgkJCQkJCQkJY2xpX3dhcm5tc2coImNvbmZ1c2VkIGFib3V0IGNvbGxhdGluZyBzZXF1ZW5jZXMgaW4gcmVnZXgsYmFpbGluZyBvdXQiKTsKCQkJCQkJCQlwYXQ9b2xkOwoJCQkJCQkJCXRva2VuLT50eXBlPVRPS0VOX1JFR0VYOwoJCQkJCQkJCWJyZWFrOwoJCQkJCQkJfQoJCQkJCQl9CgkJCQkJCWVsc2UgCgkJCQkJCQlyYW5nZV9lbmQgPSAqcGF0OwoJCQkJCWVsc2UKCQkJCQkJcmFuZ2VfZW5kID0gKnBhdDsKCQkJCQlmb3IoYz1yYW5nZV9zdGFydCsxO2M8PXJhbmdlX2VuZDtjKyspCgkJCQkJCWJpdG1hcFtjPj4zXSBePSAxPDwoYyYweDcpOwoJCQkJCWhhc3ByZXYgPSAwOwoJCQkJfQoJCQkJZWxzZSBpZiAocGF0WzBdPT0nWycgJiYgcGF0WzFdPT0nOicpIHsKCQkJCQkJCWNvbnN0IHVuc2lnbmVkIGNoYXIqIGVuZDsKCQkJCQkJCWludCBsZW4sZm91bmQ9LTE7CgkJCQkJCQlzaXplX3QgaTsKCgkJCQkJCQlwYXQrPTI7CgkJCQkJCQllbmQ9KHVuc2lnbmVkIGNoYXIqKXN0cnN0cigoY29uc3QgY2hhciopcGF0LCI6XSIpOwoJCQkJCQkJaWYoIWVuZCkgewoJCQkJCQkJCWNsaV93YXJubXNnKCJjb25mdXNlZCBhYm91dCBzdGQgY2hhciBjbGFzcyBzeW50YXggcmVnZXgsYmFpbGluZyBvdXQiKTsKCQkJCQkJCQlwYXQ9b2xkOwoJCQkJCQkJCXRva2VuLT50eXBlPVRPS0VOX1JFR0VYOwoJCQkJCQkJCWJyZWFrOwoJCQkJCQkJfQoKCQkJCQkJCWxlbiA9IGVuZC1wYXQ7CgkJCQkJCQlmb3IoaT0wO2k8c3RkX2NsYXNzX2NudDtpKyspCgkJCQkJCQkJaWYoIXN0cm5jbXAoKGNvbnN0IGNoYXIqKXBhdCxzdGRfY2xhc3NbaV0sbGVuKSkgewoJCQkJCQkJCQlmb3VuZD1pOwoJCQkJCQkJCQlicmVhazsKCQkJCQkJCQl9CgkJCQkJCQlpZihmb3VuZCE9LTEpIHsKCQkJCQkJCQlmb3IoaT0wO2k8MjU2O2krKykKCQkJCQkJCQkJaWYoY2hhcl9jbGFzc1tpXSYoMTw8Zm91bmQpKQoJCQkJCQkJCQkJYml0bWFwW2k+PjNdIF49IDE8PChpJjB4Nyk7CgkJCQkJCQl9CgkJCQkJCQllbHNlIHsKCQkJCQkJCQkvKnVua25vd24gY2xhc3MqLwoJCQkJCQkJCWNsaV93YXJubXNnKCJjb25mdXNlZCBhYm91dCByZWdleCBicmFja2V0IGV4cHJlc3Npb24sIGJhaWxpbmcgb3V0Iik7CgkJCQkJCQkJcGF0PW9sZDsKCQkJCQkJCQl0b2tlbi0+dHlwZT1UT0tFTl9SRUdFWDsKCQkJCQkJCQlicmVhazsKCQkJCQkJCX0KCQkJCQkJfQoJCQkJZWxzZSB7CgkJCQkJYml0bWFwWypwYXQ+PjNdIF49IDE8PCgqcGF0JjB4Nyk7CgkJCQkJcGF0Kys7CgkJCQkJcmFuZ2Vfc3RhcnQgPSAqcGF0OwoJCQkJCWhhc3ByZXYgPSAxOwoJCQkJfQoJCQl9IHdoaWxlKCpwYXQhPSddJyk7CgkJCS8qVE9ETzogc2VlIGlmIHRoaXMgYml0bWFwIGFscmVhZHkgZXhpc3RzLCB0aGVuIHJldXNlKi8JCQkKCQkJdG9rZW4tPnR5cGUgPSBUT0tFTl9CUkFDS0VUOwoJCQl0b2tlbi0+dS5iaXRtYXAgPSBiaXRtYXA7CgkJCWJyZWFrOwoJCQl9CgkJY2FzZSAnXSc6CgkJCW1hc3NlcnQoMCAmJiAiRW5jb3VudGVyZWQgXSB3aXRob3V0IG1hdGNoaW5nIFsiKTsKCQkJLyogYmFkIHN0YXRlICovCgkJCWJyZWFrOwoJCWNhc2UgJy4nOgoJCQl0b2tlbi0+dHlwZT1UT0tFTl9ET1Q7CgkJCWJyZWFrOwoJCWNhc2UgJygnOgoJCQl0b2tlbi0+dHlwZT1UT0tFTl9QQVJfT1BFTjsKCQkJYnJlYWs7CgkJY2FzZSAnKSc6CgkJCXRva2VuLT50eXBlPVRPS0VOX1BBUl9DTE9TRTsKCQkJYnJlYWs7CgkJZGVmYXVsdDoKCQkJdG9rZW4tPnR5cGU9VE9LRU5fQ0hBUjsKCQkJdG9rZW4tPnUuYyA9ICpwYXQ7CgkJCXRva2VuLT5sZW49MTsKCQkJYnJlYWs7Cgl9CglyZXR1cm4gKytwYXQ7Cn0KCiNkZWZpbmUgSU5JVElBTF9BTFRfU1RBQ0sgMTAKI2RlZmluZSBBTFRfU1RBQ0tfR1JPVyAyMAoKc3RhdGljIGNvbnN0IHVuc2lnbmVkIGNoYXIqIGZpbmRfcmVnZXhfc3RhcnQoY29uc3QgdW5zaWduZWQgY2hhciogcGF0KQp7CglzdHJ1Y3QgdG9rZW5fdCB0b2tlbjsKCS8qVE9ETzogZmluZCB3aGVyZSB0aGUgcmVnZXggcGFydCBiZWdpbnMsIGZvciBleDoKCSAqIGFiY2QrLCByZWdleCBiZWdpbnMgYXQgJ2QnCgkgKiAqLwoJY29uc3QgdW5zaWduZWQgY2hhciogbGFzdD1OVUxMOwoJY29uc3QgdW5zaWduZWQgY2hhciogdG1wPU5VTEw7Cgljb25zdCB1bnNpZ25lZCBjaGFyKiogYWx0cG9zaXRpb25zID0gY2xpX21hbGxvYyhJTklUSUFMX0FMVF9TVEFDSypzaXplb2YoKmFsdHBvc2l0aW9ucykpOwoJc2l6ZV90IGFsdHBvc2l0aW9uc19jYXBhY2l0eSA9IElOSVRJQUxfQUxUX1NUQUNLOwoJc2l6ZV90IGFsdHBvc2l0aW9uc19jbnQgPSAwOwoJY2hhciBsYXN0dHlwZSA9IC0xOwoJaWYoIWFsdHBvc2l0aW9ucykKCQlyZXR1cm4gTlVMTDsKCW1hc3NlcnQocGF0KTsKCgkvKiBUcnkgdG8gcGFyc2UgcGF0dGVybiB0aWxsIHNwZWNpYWwgcmVnZXggY2hhcnMgYXJlIGVuY291bnRlcmVkLCB0aGF0IHRoZSB0cmVlLW1hdGNoZXIgZG9lc24ndCBoYW5kbGUsIGxpa2U6ICssKix7fS4KCSAqIFRoZSB0cmlja3kgcGFydCBpcyB0aGF0IG9uY2Ugd2UgZW5jb3VudGVyIHRoZXNlLCB0aGUgcHJldmlvdXMgJ2F0b20nIGhhcyB0byBiZSBwYXNzZWQgb24gdG8gdGhlIHJlZ2V4IG1hdGNoZXIsIHNvIHdlIGhhdmUgdG8KCSAqIGJhY2sgdXAgdG8gdGhlIGxhc3Qga25vd24gZ29vZCBwb3NpdGlvbgoJICogRXhhbXBsZSwgaWYgd2UgaGF2ZTogYWJjKGRlZmcpKywgdGhlbiBvbmx5IGFiYyBjYW4gYmUgaGFuZGxlZCBieSB0cmVlIHBhcnNlciwgc28gd2UgaGF2ZSB0byByZXR1cm4gdGhlIHBvc2l0aW9uIG9mICguCgkgKiBBbm90aGVyIGV4YW1wbGU6IGFiYyhkZWZnfHh5enxveit8cGRvKSwgdGhlIGxhc3Qga25vd24gZ29vZCBwb3NpdGlvbiBpcyB8LCBhZnRlciB4eXoKCSAqIFRPRE86IHdoYXQgYWJvdXQgb3BlbiBwYXJhbnRoZXNlcz8gbWF5YmUgb25jZSB3ZSBmb3VuZCBhIHNwZWNpYWwgY2hhciwgd2UgaGF2ZSB0b3AgYmFjayBvdXQgYmVmb3JlIHRoZSBmaXJzdCAoPwoJICogKi8KCWRvIHsJCgkJdG1wID0gcGF0OwoJCXBhdCA9IGdldE5leHRUb2tlbihwYXQsJnRva2VuKTsKCQlpZih0b2tlbi50eXBlIT1UT0tFTl9SRUdFWCkgewoJCQlsYXN0ID0gdG1wOwoJCQlsYXN0dHlwZSA9IHRva2VuLnR5cGU7CgkJCWlmKHRva2VuLnR5cGU9PVRPS0VOX0JSQUNLRVQgJiYgdG9rZW4udS5iaXRtYXApCgkJCQlmcmVlKHRva2VuLnUuYml0bWFwKTsKCQkJaWYodG9rZW4udHlwZT09VE9LRU5fQUxUIHx8IHRva2VuLnR5cGU9PVRPS0VOX1BBUl9PUEVOKSB7CgkJCQkvKiBzYXZlIHRoaXMgcG9zaXRpb24gb24gc3RhY2ssIHN1Y2Nlc2Z1bGx5IHBhcnNlZCB0aWxsIGhlcmUqLwoJCQkJaWYoYWx0cG9zaXRpb25zX2NudCAmJiBhbHRwb3NpdGlvbnNbYWx0cG9zaXRpb25zX2NudC0xXVswXT09J3wnKQoJCQkJCS8qIGVuY291bnRlcmVkIGFub3RoZXIgYWx0ZXJuYXRlICh8KSBvcGVyYXRvciwgb3ZlcnJpZGUgcHJldmlvdXMgfCBwb3NpdGlvbiBzdG9yZWQgKi8KCQkJCQlhbHRwb3NpdGlvbnNbYWx0cG9zaXRpb25zX2NudC0xXT1sYXN0OwoJCQkJZWxzZSB7CgkJCQkJYWx0cG9zaXRpb25zW2FsdHBvc2l0aW9uc19jbnQrK10gPSBsYXN0OwoJCQkJCWlmKGFsdHBvc2l0aW9uc19jbnQgPT0gYWx0cG9zaXRpb25zX2NhcGFjaXR5KSB7CgkJCQkJCWFsdHBvc2l0aW9uc19jYXBhY2l0eSArPSBBTFRfU1RBQ0tfR1JPVzsKCQkJCQkJYWx0cG9zaXRpb25zID0gY2xpX3JlYWxsb2MyKGFsdHBvc2l0aW9ucyxhbHRwb3NpdGlvbnNfY2FwYWNpdHkqc2l6ZW9mKCphbHRwb3NpdGlvbnMpKTsKCQkJCQkJaWYoIWFsdHBvc2l0aW9ucykKCQkJCQkJCXJldHVybiBOVUxMOwoJCQkJCX0KCQkJCX0KCQkJfSBlbHNlIGlmIChsYXN0dHlwZT09VE9LRU5fUEFSX0NMT1NFKSB7CgkJCQkvKiByZW1vdmUgbGFzdCBzdG9yZWQgcG9zaXRpb24gZnJvbSBzdGFjaywgc3VjY2VzZnVsbHkgdGhpcyBsYXN0IGdyb3VwICovCgkJCQlhbHRwb3NpdGlvbnNfY250LS07CgkJCQltYXNzZXJ0KGFsdHBvc2l0aW9uc19jbnQ+MCk7CgkJCX0KCQl9CgkJZWxzZSB7CgkJCWlmKGFsdHBvc2l0aW9uc19jbnQpCgkJCQlsYXN0ID0gYWx0cG9zaXRpb25zWzAgLyphbHRwb3NpdGlvbnNfY250LTEqL107LypUT0RPOiB3aGljaCBpbmRleCBoZXJlPywgc2VlIGFib3ZlIFRPRE8uLi4gKi8KCQkJLypsYXN0IHN0b3JlZCAnc2FmZScgcG9zaXRpb24gd2hlcmUgbm8gc3BlY2lhbCAoKywqLHt9KSByZWdleCBjaGFycyB3ZXJlIGVuY291bnRlcmVkKi8KCQl9Cgl9IHdoaWxlKCpwYXQgJiYgdG9rZW4udHlwZSE9VE9LRU5fUkVHRVgpOwoJZnJlZShhbHRwb3NpdGlvbnMpOwoJcmV0dXJuICpwYXQgPyBsYXN0IDogbGFzdCsxOwp9CgpzdGF0aWMgc3RydWN0IHRyZWVfbm9kZSogdHJlZV9ub2RlX2FsbG9jKHN0cnVjdCB0cmVlX25vZGUqIG5leHQsY2hhciBsaXN0ZW5kKQp7CglzdHJ1Y3QgdHJlZV9ub2RlKiBub2RlID0gY2xpX21hbGxvYyhzaXplb2YoKm5vZGUpKTsKCWlmKG5vZGUpIHsKCQlub2RlLT5hbHRlcm5hdGl2ZXM9MDsKCQlub2RlLT5uZXh0PW5leHQ7CgkJbm9kZS0+bGlzdGVuZD1saXN0ZW5kOwoJCW5vZGUtPnUuY2hpbGRyZW49TlVMTDsKCX0KCXJldHVybiBub2RlOwp9CgpzdGF0aWMgc3RydWN0IHRyZWVfbm9kZSogdHJlZV9yb290X2FsbG9jKHZvaWQpCnsKCXN0cnVjdCB0cmVlX25vZGUqIHJvb3Q9dHJlZV9ub2RlX2FsbG9jKE5VTEwsMSk7CglpZihyb290KSB7CgkJcm9vdC0+b3A9T1BfUk9PVDsKCQlyb290LT5jPTA7CgkJcm9vdC0+bmV4dD1OVUxMOwoJCXJvb3QtPmxpc3RlbmQ9MTsKCX0KCXJldHVybiByb290Owp9CgpzdGF0aWMgc3RydWN0IHRyZWVfbm9kZSogdHJlZV9ub2RlX2NoYXJfYmluc2VhcmNoKGNvbnN0IHN0cnVjdCB0cmVlX25vZGUqIG5vZGUsY29uc3QgY2hhciBjc2VhcmNoLGludCogbGVmdCkKewoJaW50IHJpZ2h0OwoJc3RydWN0IHRyZWVfbm9kZSAqKmNoaWxkcmVuOwoJbWFzc2VydChub2RlKTsKCW1hc3NlcnQobGVmdCk7CgoJY2hpbGRyZW4gPSB0cmVlX25vZGVfZ2V0X2NoaWxkcmVuKG5vZGUpOwoJcmlnaHQgPSBub2RlLT5hbHRlcm5hdGl2ZXMtMTsKCSpsZWZ0ID0gMDsKCWlmKCFub2RlLT5hbHRlcm5hdGl2ZXMpCgkJcmV0dXJuIE5VTEw7CgltYXNzZXJ0KGNoaWxkcmVuKTsKCXdoaWxlKCpsZWZ0PD1yaWdodCkgewoJCWludCBtaWQgID0gKmxlZnQrKHJpZ2h0LSpsZWZ0KS8yOwoJCWlmKGNoaWxkcmVuW21pZF0tPmMgPT0gY3NlYXJjaCkKCQkJcmV0dXJuIGNoaWxkcmVuW21pZF07IAoJCWVsc2UgaWYoY2hpbGRyZW5bbWlkXS0+YyA8IGNzZWFyY2gpCgkJCSpsZWZ0PW1pZCsxOwoJCWVsc2UKCQkJcmlnaHQ9bWlkLTE7Cgl9CglyZXR1cm4gTlVMTDsKfQoKc3RhdGljIHN0cnVjdCB0cmVlX25vZGUqIHRyZWVfZ2V0X25leHQoc3RydWN0IHRyZWVfbm9kZSogbm9kZSkKewoJc3RydWN0IHRyZWVfbm9kZSoqIGNoaWxkcmVuOwoJbWFzc2VydChub2RlKTsKCWNoaWxkcmVuID0gdHJlZV9ub2RlX2dldF9jaGlsZHJlbihub2RlKTsKCglpZighbm9kZS0+YWx0ZXJuYXRpdmVzICYmIGNoaWxkcmVuICYmIGNoaWxkcmVuWzBdKQoJCXJldHVybiBjaGlsZHJlblswXTsKCWVsc2UgaWYobm9kZS0+YWx0ZXJuYXRpdmVzPD0xKQoJCXJldHVybiBub2RlOwoJZWxzZQoJCXJldHVybiBjaGlsZHJlblswXS0+bmV4dDsKfQoKc3RhdGljIHNpemVfdCB0cmVlX25vZGVfZ2V0X2FycmF5X3NpemUoY29uc3Qgc3RydWN0IHRyZWVfbm9kZSogbm9kZSkKewoJbWFzc2VydChub2RlKTsKCS8qIGlmIG9wIGlzIENVU1RPTUNMQVNTLCB0aGVuIGZpcnN0IHBvaW50ZXIgaXMgcG9pbnRlciB0byBiaXRtYXAsIHNvIGFycmF5IHNpemUgaXMgKzEgKi8KCXJldHVybiAobm9kZS0+YWx0ZXJuYXRpdmVzICsgKG5vZGUtPm9wPT1PUF9DVVNUT01DTEFTUyA/IDEgOiAwKSkgKiBzaXplb2Yobm9kZS0+dS5jaGlsZHJlblswXSk7Cn0KCnN0YXRpYyBzdHJ1Y3QgdHJlZV9ub2RlKiB0cmVlX25vZGVfY2hhcl9pbnNlcnQoc3RydWN0IHRyZWVfbm9kZSogbm9kZSxjb25zdCBjaGFyIGMsaW50IGxlZnQpCnsKCXN0cnVjdCB0cmVlX25vZGUqIG5ldywgKmFsdCA9IHRyZWVfZ2V0X25leHQobm9kZSk7CglzdHJ1Y3QgdHJlZV9ub2RlICoqY2hpbGRyZW47Cglub2RlLT5hbHRlcm5hdGl2ZXMrKzsKCW5vZGUtPnUuY2hpbGRyZW4gPSBjbGlfcmVhbGxvYzIobm9kZS0+dS5jaGlsZHJlbix0cmVlX25vZGVfZ2V0X2FycmF5X3NpemUobm9kZSkpOwoJaWYoIW5vZGUtPnUuY2hpbGRyZW4pCgkJcmV0dXJuIE5VTEw7CgoJY2hpbGRyZW4gPSBub2RlLT5vcD09T1BfQ1VTVE9NQ0xBU1MgPyBub2RlLT51LmNoaWxkcmVuKzEgOiBub2RlLT51LmNoaWxkcmVuOwoKCW5ldyA9IHRyZWVfbm9kZV9hbGxvYyhhbHQgLCBub2RlID09IGFsdCApOwoJaWYobmV3KSB7CgkJbmV3LT5vcD1PUF9DSEFSOwoJCW5ldy0+Yz1jOwoJfQoKCWlmKG5vZGUtPmFsdGVybmF0aXZlcy1sZWZ0LTE+MCkKCQkJbWVtbW92ZSgmY2hpbGRyZW5bbGVmdCsxXSwmY2hpbGRyZW5bbGVmdF0sKG5vZGUtPmFsdGVybmF0aXZlcy1sZWZ0LTEpKnNpemVvZihub2RlLT51LmNoaWxkcmVuWzBdKSk7CgljaGlsZHJlbltsZWZ0XSA9IG5ldzsJCgoJcmV0dXJuIG5ldzsKfQoKc3RhdGljIHZvaWQgdHJlZV9ub2RlX2luc2VydF9ub25iaW4oc3RydWN0IHRyZWVfbm9kZSogbm9kZSwgc3RydWN0IHRyZWVfbm9kZSogbmV3KQp7CglzdHJ1Y3QgdHJlZV9ub2RlICoqY2hpbGRyZW47CgltYXNzZXJ0KG5vZGUpOwoJbWFzc2VydChuZXcpOwoKCWNoaWxkcmVuID0gdHJlZV9ub2RlX2dldF9jaGlsZHJlbihub2RlKTsKCWlmKG5vZGUtPmFsdGVybmF0aXZlcykgewoJCW1hc3NlcnQoY2hpbGRyZW4pOwoJICAgICAgIAlpZihjaGlsZHJlblswXS0+bmV4dCA9PSBub2RlKSB7CgkJCWludCBpOwoJCQluZXctPmxpc3RlbmQgPSAxOwoJCQlmb3IoaT0wO2k8bm9kZS0+YWx0ZXJuYXRpdmVzO2krKykgewoJCQkJY2hpbGRyZW5baV0tPm5leHQgPSBuZXc7CgkJCQljaGlsZHJlbltpXS0+bGlzdGVuZCA9IDA7CgkJCX0KCQl9CgkJZWxzZSB7CgkJCXN0cnVjdCB0cmVlX25vZGUqIHA7CgkJCWZvcihwID0gY2hpbGRyZW5bMF0tPm5leHQgOyBwLT5uZXh0ICE9IG5vZGUgOyBwID0gcC0+bmV4dCkKCQkJCW1hc3NlcnQoIXAtPmxpc3RlbmQpOwoJCQluZXctPmxpc3RlbmQgPSAxOwoJCQlwLT5saXN0ZW5kID0gMDsKCQkJcC0+bmV4dCA9IG5ldzsKCQl9Cgl9CgllbHNlIHsKCQlpbnQgaWR4ID0gbm9kZS0+b3A9PU9QX0NVU1RPTUNMQVNTID8gMSA6IDA7CgkJaWYobm9kZS0+dS5jaGlsZHJlbikKCQkJaWYobm9kZS0+dS5jaGlsZHJlbltpZHhdKSB7CgkJCQlub2RlID0gbm9kZS0+dS5jaGlsZHJlbltpZHhdOwoJCQkJd2hpbGUobm9kZS0+bmV4dCAmJiAhbm9kZS0+bGlzdGVuZCkKCQkJCQlub2RlID0gbm9kZS0+bmV4dDsKCQkJCW5vZGUtPmxpc3RlbmQgPSAwOwoJCQkJbmV3LT5uZXh0ID0gbm9kZS0+bmV4dDsKCQkJCW5vZGUtPm5leHQgPSBuZXc7CgkJCQluZXctPmxpc3RlbmQ9MTsKCQkJCXJldHVybjsKCQkJfQoJCW5vZGUtPnUuY2hpbGRyZW4gPSBjbGlfcmVhbGxvYzIobm9kZS0+dS5jaGlsZHJlbixzaXplb2Yobm9kZS0+dS5jaGlsZHJlblswXSkqKDIpKTsKCQlpZihub2RlLT51LmNoaWxkcmVuKSB7CgkJCW5vZGUtPnUuY2hpbGRyZW5baWR4XSA9IG5ldzsKCQl9Cgl9Cn0KCnN0YXRpYyB1bnNpZ25lZCBjaGFyIGNoYXJfZ2V0Y2xhc3MoY29uc3QgdW5zaWduZWQgY2hhciogYml0bWFwKQp7CglzaXplX3QgaTsKCW1hc3NlcnQoYml0bWFwKTsKCglmb3IoaT0wO2k8c3RkX2NsYXNzX2NudDtpKyspCgkJaWYoIW1lbWNtcChiaXRtYXAsY2hhcl9jbGFzc19iaXRtYXBbaV0sMjU2Pj4zKSkKCQkJcmV0dXJuIGk7CglyZXR1cm4gc3RkX2NsYXNzX2NudDsKfQoKc3RhdGljIHZvaWQgc3RhY2tfZGVzdHJveShzdHJ1Y3Qgbm9kZV9zdGFjayogc3RhY2spCnsKCW1hc3NlcnQoc3RhY2spOwoJaWYoc3RhY2stPmRhdGEpCgkJZnJlZShzdGFjay0+ZGF0YSk7CglzdGFjay0+ZGF0YSA9IE5VTEw7CglzdGFjay0+Y2FwYWNpdHkgPSAwOwp9CgovKiBjYWxsIHRoaXMgYWZ0ZXIgd2hpdGVsaXN0IGxvYWQgaXMgY29tcGxldGUsIGFuZCB0aGUgdHJlZSBpcyBubyBsb25nZXIgZ29pbmcgdG8gYmUgbW9kaWZpZWQgKi8Kdm9pZCByZWdleF9saXN0X2NsZWFudXAoc3RydWN0IHJlZ2V4X21hdGNoZXIqIG1hdGNoZXIpCnsKCW1hc3NlcnQobWF0Y2hlcik7CgoJc3RhY2tfZGVzdHJveSgmbWF0Y2hlci0+bm9kZV9zdGFjayk7CglzdGFja19kZXN0cm95KCZtYXRjaGVyLT5ub2RlX3N0YWNrX2FsdCk7CglzdGFja19pbml0KCZtYXRjaGVyLT5ub2RlX3N0YWNrKTsKCXN0YWNrX2luaXQoJm1hdGNoZXItPm5vZGVfc3RhY2tfYWx0KTsKfQoKaW50IGlzX3JlZ2V4X29rKHN0cnVjdCByZWdleF9tYXRjaGVyKiBtYXRjaGVyKQp7CgltYXNzZXJ0KG1hdGNoZXIpOwoJcmV0dXJuICghbWF0Y2hlci0+bGlzdF9pbml0ZWQgfHwgbWF0Y2hlci0+bGlzdF9pbml0ZWQhPS0xKTsvKiBlaXRoZXIgd2UgZG9uJ3QgaGF2ZSBhIHJlZ2V4bGlzdCwgb3Igd2UgaW5pdGlhbGl6ZWQgaXQgc3VjY2Vzc2Z1bGx5ICovCn0KCi8qIHJldHVybnMgMCBvbiBzdWNjZXNzLCByZWdleGVjIGVycm9yIGNvZGUgb3RoZXJ3aXNlICovCQkJCQkJCnN0YXRpYyBpbnQgYWRkX3BhdHRlcm4oc3RydWN0IHJlZ2V4X21hdGNoZXIqIG1hdGNoZXIsY29uc3QgdW5zaWduZWQgY2hhciogcGF0LGNvbnN0IGNoYXIqIGluZm8sIGludCBob3N0b25seSkKewoJaW50IGJvbD0xOwoJY29uc3QgdW5zaWduZWQgY2hhciogcGF0X2VuZCA9IGZpbmRfcmVnZXhfc3RhcnQocGF0KTsKCXN0cnVjdCB0b2tlbl90IHRva2VuOwoJc3RydWN0IHRyZWVfbm9kZSogbm9kZTsKCQoJbWFzc2VydChtYXRjaGVyKTsKCglub2RlID0gaG9zdG9ubHkgPyBtYXRjaGVyLT5yb290X3JlZ2V4X2hvc3Rvbmx5IDogbWF0Y2hlci0+cm9vdF9yZWdleDsKCglzdGFja19yZXNldCgmbWF0Y2hlci0+bm9kZV9zdGFjayk7CglzdGFja19yZXNldCgmbWF0Y2hlci0+bm9kZV9zdGFja19hbHQpOwoJc3RhY2tfcHVzaCgmbWF0Y2hlci0+bm9kZV9zdGFjayxub2RlKTsKCglmb3IoO25vZGUtPm9wIT1PUF9MRUFGOyl7CgkJaWYocGF0PHBhdF9lbmQpCgkJCXBhdCAgPSBnZXROZXh0VG9rZW4ocGF0LCZ0b2tlbik7CgkJZWxzZSBpZigqcGF0KSB7CgkJCXRva2VuLnR5cGUgPSBUT0tFTl9SRUdFWDsKCQkJdG9rZW4udS5zdGFydD1wYXQ7CgkJfQoJCWVsc2UKCQkJdG9rZW4udHlwZSA9IFRPS0VOX0RPTkU7CgoJCXN3aXRjaCh0b2tlbi50eXBlKSB7CgkJCWNhc2UgVE9LRU5fQ0hBUjogCgkJCQl7CgkJCQkJLyogc2VhcmNoIGZvciBjaGFyIGluIHRyZWUgKi8KCQkJCQlpbnQgbGVmdDsKCQkJCQlzdHJ1Y3QgdHJlZV9ub2RlKiBuZXdub2RlID0gdHJlZV9ub2RlX2NoYXJfYmluc2VhcmNoKG5vZGUsdG9rZW4udS5jLCZsZWZ0KTsKCQkJCQlpZihuZXdub2RlKQoJCQkJCQlub2RlID0gbmV3bm9kZTsKCQkJCQllbHNlIHsKCQkJCQkJLyogbm90IGZvdW5kLCBpbnNlcnQgaXQgKi8KCQkJCQkJbm9kZSA9IHRyZWVfbm9kZV9jaGFyX2luc2VydChub2RlLHRva2VuLnUuYyxsZWZ0KTsKCQkJCQl9CgkJCQkJYnJlYWs7CgkJCQl9CgoJCQljYXNlIFRPS0VOX1BBUl9PUEVOOgoJCQkJc3RhY2tfcHVzaCgmbWF0Y2hlci0+bm9kZV9zdGFja19hbHQsTlVMTCk7LyogbWFya2VyICovCgkJCQlzdGFja19wdXNoKCZtYXRjaGVyLT5ub2RlX3N0YWNrLG5vZGUpOwoJCQkJYnJlYWs7CgoJCQljYXNlIFRPS0VOX1BBUl9DTE9TRTogewoJCQkJCQkgICAgICAvKlRPRE86IHRlc3QgdGhpcyEhISovCgkJCQkJCSAgICAgIHN0cnVjdCB0cmVlX25vZGUqIG5vZGVfYWx0ID0gbm9kZTsKCQkJCQkJICAgICAgbm9kZSA9IHRyZWVfbm9kZV9hbGxvYyhOVUxMLDEpOwoJCQkJCQkgICAgICBub2RlLT5vcD1PUF9QQVJDTE9TRTsKCQkJCQkJICAgICAgbm9kZS0+Yz0wOwoJCQkJCQkgICAgICBub2RlLT5saXN0ZW5kPTE7CgkJCQkJCSAgICAgIHRyZWVfbm9kZV9pbnNlcnRfbm9uYmluKG5vZGVfYWx0LG5vZGUpOwoJCQkJCQkgICAgICB3aGlsZSAoKCBub2RlX2FsdCA9IHN0YWNrX3BvcCgmbWF0Y2hlci0+bm9kZV9zdGFja19hbHQpICkpIHsKCQkJCQkJCSAgICAgIHRyZWVfbm9kZV9pbnNlcnRfbm9uYmluKG5vZGVfYWx0LG5vZGUpOwoJCQkJCQkgICAgICB9CgkJCQkgICAgICAJCSAgICAgIHN0YWNrX3BvcCgmbWF0Y2hlci0+bm9kZV9zdGFjayk7CQkJCQkgICAgICAKCQkgICAgICAJCQkJICAgICAgYnJlYWs7CgkJCQkJICAgICAgfQoKCQkJY2FzZSBUT0tFTl9BTFQ6CgkJCQlzdGFja19wdXNoKCZtYXRjaGVyLT5ub2RlX3N0YWNrX2FsdCxub2RlKTsKCQkJCW5vZGUgPSBzdGFja19wb3AoJm1hdGNoZXItPm5vZGVfc3RhY2spOwoJCQkJc3RhY2tfcHVzaCgmbWF0Y2hlci0+bm9kZV9zdGFjayxub2RlKTsKCQkJCWJyZWFrOwoKCQkJY2FzZSBUT0tFTl9CUkFDS0VUOgoJCQkJewoJCQkJCXN0cnVjdCB0cmVlX25vZGUqIG5ldyA9IHRyZWVfbm9kZV9hbGxvYyh0cmVlX2dldF9uZXh0KG5vZGUpLDEpOwoJCQkJCXVuc2lnbmVkIGNoYXIgY2hhcmNsYXNzID0gY2hhcl9nZXRjbGFzcyh0b2tlbi51LmJpdG1hcCk7CgkJCQkJaWYoY2hhcmNsYXNzID09IHN0ZF9jbGFzc19jbnQpIHsvKm5vdCBhIHN0ZCBjaGFyIGNsYXNzKi8KCQkJCQkJbmV3LT5vcCA9IE9QX0NVU1RPTUNMQVNTOwoJCQkJCQluZXctPnUuY2hpbGRyZW4gPSBjbGlfbWFsbG9jKHNpemVvZihuZXctPnUuY2hpbGRyZW5bMF0pKjIpOwoJCQkJCQlpZighbmV3LT51LmNoaWxkcmVuKQoJCQkJCQkJcmV0dXJuIENMX0VNRU07CgkJCQkJCW5ldy0+dS5iaXRtYXBbMF0gPSB0b2tlbi51LmJpdG1hcDsKCQkJCQkJbmV3LT51LmJpdG1hcFsxXSA9IE5VTEw7CgkJCQkJCXRyZWVfbm9kZV9pbnNlcnRfbm9uYmluKG5vZGUsbmV3KTsKCQkJCQkJbm9kZSA9IG5ldzsKCQkJCQl9CgkJCQkJZWxzZSB7CgkJCQkJCW5ldy0+b3AgPSBPUF9TVERDTEFTUzsKCQkJCQkJbmV3LT5jID0gY2hhcmNsYXNzOwoJCQkJCQl0cmVlX25vZGVfaW5zZXJ0X25vbmJpbihub2RlLG5ldyk7CgkJCQkJCW5vZGU9bmV3OwoJCQkJCX0KCQkJCQlicmVhazsKCQkJCX0KCgkJCWNhc2UgVE9LRU5fRE9UOgoJCQkJewoJCQkJCXN0cnVjdCB0cmVlX25vZGUqIG5ldyA9IHRyZWVfbm9kZV9hbGxvYyh0cmVlX2dldF9uZXh0KG5vZGUpLDEpOwoJCQkJCW5ldy0+b3AgPSBPUF9ET1Q7CgkJCQkJdHJlZV9ub2RlX2luc2VydF9ub25iaW4obm9kZSxuZXcpOwoJCQkJCW5vZGU9bmV3OwoJCQkJCWJyZWFrOwoJCQkJfQoKCQkJY2FzZSBUT0tFTl9SRUdFWDoKCQkJY2FzZSBUT0tFTl9ET05FOiB7CgkJCQkJCSBzdHJ1Y3QgbGVhZl9pbmZvKiBsZWFmPWNsaV9tYWxsb2Moc2l6ZW9mKCpsZWFmKSk7CgkJCQkJCSBpZighbGVhZikKCQkJCQkJCSByZXR1cm4gQ0xfRU1FTTsKCQkJCQkJIGxlYWYtPmluZm8gPSBjbGlfc3RyZHVwKGluZm8pOwoJCQkJCQkgaWYodG9rZW4udHlwZT09VE9LRU5fUkVHRVgpIHsKCQkJCQkJCSBpbnQgcmM7CgkJCQkJCQkgc3RydWN0IHRyZWVfbm9kZSogbmV3OwoJCQkJCQkJIHJlZ2V4X3QqIHByZWc7CgkJCQkJCQkgcHJlZz1jbGlfbWFsbG9jKHNpemVvZigqcHJlZykpOwoJCQkJCQkJIGlmKCFwcmVnKQoJCQkJCQkJCSByZXR1cm4gQ0xfRU1FTTsKCQkJCQkJCSByYyA9IGNsaV9yZWdjb21wKHByZWcsKGNvbnN0IGNoYXIqKXRva2VuLnUuc3RhcnQsUkVHX0VYVEVOREVEfChib2w/MDpSRUdfTk9UQk9MKSk7CgkJCQkJCQkgbGVhZi0+cHJlZz1wcmVnOwoJCQkJCQkJIGlmKHJjKQoJCQkJCQkJCSByZXR1cm4gcmM7CgkJCQkJCQkgbmV3PWNsaV9tYWxsb2Moc2l6ZW9mKCpuZXcpKTsKCQkJCQkJCSBpZighbmV3KQoJCQkJCQkJCSByZXR1cm4gQ0xfRU1FTTsKCQkJCQkJCSBuZXctPm9wPU9QX0xFQUY7CgkJCQkJCQkgbmV3LT5uZXh0PW5vZGU7CgkJCQkJCQkgbmV3LT5hbHRlcm5hdGl2ZXM9MDsKCQkJCQkJCSBuZXctPnUubGVhZj1sZWFmOwoJCQkJCQkJIG5ldy0+bGlzdGVuZD0xOwoJCQkJCQkJIHRyZWVfbm9kZV9pbnNlcnRfbm9uYmluKG5vZGUsbmV3KTsKCQkJCQkJIH0KCQkJCQkJIGVsc2UgewoJCQkJCQkJIGxlYWYtPnByZWc9TlVMTDsKCQkJCQkJCSBub2RlLT5hbHRlcm5hdGl2ZXM9MDsKCQkJCQkJCSBub2RlLT51LmxlYWY9bGVhZjsKCQkJCQkJCSBub2RlLT5vcD1PUF9MRUFGOwoJCQkJCQkgfQoJCQkJCQkgcmV0dXJuIDA7CgkJCQkJIH0KCQl9CgoJCWJvbD0wOwoJfQoJcmV0dXJuIDA7Cn0KCi8qIGMgaGFzIHRvIGJlIHVuc2lnbmVkIGNoYXIgaGVyZSEhICovCnN0YXRpYyBpbnQgbWF0Y2hfbm9kZShzdHJ1Y3QgdHJlZV9ub2RlKiBub2RlLGNvbnN0IHVuc2lnbmVkIGNoYXIqIGMsc2l6ZV90IGxlbixjb25zdCBjaGFyKiogaW5mbykKewoJc3RydWN0IHRyZWVfbm9kZSoqIGNoaWxkcmVuOwoJaW50IHJjOwoKCW1hc3NlcnQobm9kZSk7CgltYXNzZXJ0KGMpOwoJbWFzc2VydChpbmZvKTsKCglpZighbm9kZS0+dS5jaGlsZHJlbikKCQlyZXR1cm4gTUFUQ0hfRkFJTEVEOy8qIHRyZWUgZW1wdHkgKi8KCSppbmZvID0gTlVMTDsKCWxlbisrOwoJYy0tOwoJZm9yKDs7KSB7CgkJbWFzc2VydChub2RlKTsKCQljaGlsZHJlbiA9IG5vZGUtPnUuY2hpbGRyZW47CgkJc3dpdGNoKG5vZGUtPm9wKSB7CgkJCWNhc2UgT1BfUk9PVDoKCQkJCXJjPTE7CgkJCQlicmVhazsKCQkJY2FzZSBPUF9QQVJDTE9TRToKCQkJCS8qdGhpcyBpc24ndCBhIHJlYWwgY2hhcmFjdGVyLCBzbyBkb24ndCBtb3ZlKi8KCQkJCWMtLTsKCQkJCWxlbisrOwoJCQkJcmM9MTsKCQkJCWJyZWFrOwoJCQljYXNlIE9QX0NIQVI6CgkJCQltYXNzZXJ0KCpjPT1ub2RlLT5jICYmICJXZSBrbm93IHRoaXMgaGFzIHRvIG1hdGNoIik7CgkJCQlyYyA9IDE7LyogKmM9PW5vZGUtPmM7LSB3ZSBrbm93IGl0IGhhcyBtYXRjaGVkICovCgkJCQlicmVhazsKCQkJY2FzZSBPUF9ET1Q6CQoJCQkJcmMgPSAqYyE9J1xuJzsKCQkJCWJyZWFrOwoJCQljYXNlIE9QX1NURENMQVNTOgoJCQkJcmMgPSBjaGFyX2NsYXNzWypjXSYobm9kZS0+Yyk7CgkJCQlicmVhazsKCQkJY2FzZSBPUF9DVVNUT01DTEFTUzoKCQkJewoJCQkJY2hhcl9iaXRtYXBfcCBiaXRtYXA7CgkJCQltYXNzZXJ0KGNoaWxkcmVuKTsKCQkJCWJpdG1hcCA9IChjaGFyX2JpdG1hcF9wKW5vZGUtPnUuYml0bWFwWzBdOwoJCQkJY2hpbGRyZW4rKzsKCQkJCXJjID0gYml0bWFwWypjPj4zXSYoMTw8KCpjJjB4NykpOwoJCQkJYnJlYWs7CgkJCX0KCQkJY2FzZSBPUF9MRUFGOgoJCQl7CgkJCQljb25zdCBzdHJ1Y3QgbGVhZl9pbmZvKiBsZWFmID0gbm9kZS0+dS5sZWFmOwoJCQkJLyppc2xlYWYgPSAxOyovCgkJCQlpZihsZWFmLT5wcmVnKSB7CgkJCQkJcmMgPSAhY2xpX3JlZ2V4ZWMobGVhZi0+cHJlZywoY29uc3QgY2hhciopYywwLE5VTEwsMCk7CgkJCQl9CgkJCQllbHNlICB7CgkJCQkJbWFzc2VydCgqYz09bm9kZS0+YyAmJiAiV2Uga25vdyB0aGlzIGhhcyB0byBtYXRjaFsyXSIpOwoJCQkJCXJjID0gMTsKCQkJCX0KCQkJCWlmKHJjKSB7CgkJCQkJKmluZm8gPSBsZWFmLT5pbmZvOwoJCQkJCXJldHVybiBNQVRDSF9TVUNDRVNTOwoJCQkJfQoJCQkJYnJlYWs7CgkJCX0KCQkJZGVmYXVsdDoKCQkJCS8qIGltcG9zc2libGUgKi8KCQkJCWNsaV9lcnJtc2coIkVuY291bnRlcmVkIGludmFsaWQgb3BlcmF0b3IgaW4gdHJlZTolZFxuIixub2RlLT5vcCk7CgkJCQlleGl0KDEpOwoJCX0KCQlsZW4tLTsKCQlpZighbGVuKSByYz0wOwoJCWMrKzsKCQlpZihyYykgewoJCQljb25zdCBjaGFyIGNzZWFyY2ggPSAqYzsKCQkJaW50IGxlZnQgPSAwLHJpZ2h0ID0gbm9kZS0+YWx0ZXJuYXRpdmVzLTE7CgkJCWludCBtaWQ7CgkJCS8qbWF0Y2hlZCBzbyBmYXIsIGdvIGRlZXBlciovCgkJCS8qZG8gYSBiaW5hcnkgc2VhcmNoIGJldHdlZW4gY2hpbGRyZW4gKi8KCQkJbWFzc2VydChjaGlsZHJlbik7CgkJCXdoaWxlKGxlZnQ8PXJpZ2h0KSB7CgkJCQltaWQgID0gbGVmdCsocmlnaHQtbGVmdCkvMjsKCQkJCWlmIChjaGlsZHJlblttaWRdLT5jID09IGNzZWFyY2gpCgkJCQkJYnJlYWs7CgkJCQllbHNlIGlmKGNoaWxkcmVuW21pZF0tPmMgPCBjc2VhcmNoKQoJCQkJCWxlZnQ9bWlkKzE7CgkJCQllbHNlCgkJCQkJcmlnaHQ9bWlkLTE7CgkJCX0KCQkJaWYobGVmdDw9cmlnaHQpIHsKCQkJCW5vZGUgPSBjaGlsZHJlblttaWRdOwoJCQkJbWFzc2VydChub2RlKTsKCQkJfQoJCQllbHNlIHsKCQkJCWlmKG5vZGUtPmFsdGVybmF0aXZlcykgewoJCQkJCWlmKCFjaGlsZHJlblswXS0+bGlzdGVuZCkgewoJCQkJCQlub2RlID0gY2hpbGRyZW5bMF07CgkJCQkJCWMrKzsKCQkJCQkJbGVuLS07CgkJCQkJfQoJCQkJCXdoaWxlKG5vZGUgJiYgbm9kZS0+bGlzdGVuZCkgewoJCQkJCQlub2RlID0gbm9kZS0+bmV4dDsvKiBjbGltYiB1cCAqLwoJCQkJCQljLS07CgkJCQkJCWxlbisrOwoJCQkJCX0KCQkJCQlpZighbm9kZSB8fCAhbm9kZS0+bmV4dCkgCgkJCQkJCXJldHVybiBNQVRDSF9GQUlMRUQ7LyogcmVhY2hlZCByb290IG5vZGUgKi8KCQkJCQlub2RlPW5vZGUtPm5leHQ7CgkJCQkJYy0tOwoJCQkJCWxlbisrOwoJCQkJfQoJCQkJZWxzZSBpZihub2RlLT51LmNoaWxkcmVuKSB7CgkJCQkJc3RydWN0IHRyZWVfbm9kZSogcmV3cml0ZV9uZXh0ID0gTlVMTDsKCQkJCQlpZihub2RlLT5vcD09T1BfUEFSQ0xPU0UpIAoJCQkJCQlyZXdyaXRlX25leHQgPSBub2RlOwoJCQkJCW5vZGUgPSBjaGlsZHJlblswXTsKCQkJCQltYXNzZXJ0KG5vZGUpOwoJCQkJCW1hc3NlcnQobm9kZS0+b3AhPU9QX0NIQVIpOwoJCQkJCWlmKHJld3JpdGVfbmV4dCkKCQkJCQkJbm9kZS0+bmV4dCA9IHJld3JpdGVfbmV4dDsvKiB0aGlzIG5vZGUgaXMgcG9pbnRlZCB0byBieSBzZXZlcmFsIHBhcmVudCBub2RlcywgCgkJCQkJCQkJCSAgICAgd2UgbmVlZCB0byBrbm93IAoJCQkJCQkJCQkgICAgIGZyb20gd2hpY2ggb25lIHdlIGNhbWUsIHNvIHdlIGNhbiBmaW5kIG91dCB3YXkgYmFjawoJCQkJCQkJCQkgICAgIHNob3VsZCB3ZSBmYWlsIHRvIG1hdGNoIHNvbWV3aGVyZSBkZWVwZXIqLwoJCQkJfQoJCQl9CgkJfQoJCWVsc2UgewoJCQkvKiB0aGlzIG5vZGUgZGlkbid0IG1hdGNoLCB0cnkgc2libGluZywgb3IgcGFyZW50IChpZiBubyBtb3JlIHNpYmxpbmdzKSAqLwoJCQl3aGlsZShub2RlICYmIG5vZGUtPmxpc3RlbmQpIHsKCQkJCW5vZGUgPSBub2RlLT5uZXh0Oy8qIHNpYmxpbmcgb2YgcGFyZW50ICovCgkJCQljLS07CgkJCQlsZW4rKzsKCQkJfQoJCQlpZighbm9kZSB8fCAhbm9kZS0+bmV4dCkgLyogcmVhY2hlZCByb290IG5vZGUsIGl0IGhhcyBubyBuZXh0ICovCgkJCQlyZXR1cm4gTUFUQ0hfRkFJTEVEOwoJCQllbHNlIHsKCQkJCWMtLTsKCQkJCWxlbisrOwoJCQkJbm9kZT1ub2RlLT5uZXh0OwoJCQl9CgkJfQoJfQoJcmV0dXJuIE1BVENIX0ZBSUxFRDsKfQoKLyogcHVzaCBub2RlIG9uIHN0YWNrLCBvbmx5IGlmIGl0IGlzbid0IHRoZXJlIGFscmVhZHkgKi8Kc3RhdGljIHZvaWQgc3RhY2tfcHVzaF9vbmNlKHN0cnVjdCBub2RlX3N0YWNrKiBzdGFjayxzdHJ1Y3QgdHJlZV9ub2RlKiBub2RlKQp7CglzaXplX3QgaTsKCW1hc3NlcnQoc3RhY2spOwoJbWFzc2VydChub2RlKTsKCglmb3IoaT0wO2kgPCBzdGFjay0+Y250O2krKykKCQlpZihzdGFjay0+ZGF0YVtpXT09bm9kZSkKCQkJcmV0dXJuOwoJc3RhY2tfcHVzaChzdGFjayxub2RlKTsKfQoKc3RhdGljIHZvaWQgZGVzdHJveV90cmVlX2ludGVybmFsKHN0cnVjdCByZWdleF9tYXRjaGVyKiBtYXRjaGVyLHN0cnVjdCB0cmVlX25vZGUqIG5vZGUpCnsKCXN0cnVjdCB0cmVlX25vZGUgKipjaGlsZHJlbjsKCW1hc3NlcnQobWF0Y2hlcik7CgltYXNzZXJ0KG5vZGUpOwoKCWNoaWxkcmVuID0gdHJlZV9ub2RlX2dldF9jaGlsZHJlbihub2RlKTsKCWlmKG5vZGUtPm9wPT1PUF9MRUFGKSB7CgkJc3RydWN0IGxlYWZfaW5mbyogbGVhZiA9IG5vZGUtPnUubGVhZjsKCQlpZihub2RlLT5uZXh0ICYmICFub2RlLT5saXN0ZW5kKQoJCQlkZXN0cm95X3RyZWVfaW50ZXJuYWwobWF0Y2hlcixub2RlLT5uZXh0KTsKCQlzdGFja19wdXNoX29uY2UoJm1hdGNoZXItPm5vZGVfc3RhY2ssKHN0cnVjdCB0cmVlX25vZGUqKW5vZGUtPnUubGVhZik7LyogY2FzdCB0byBtYWtlIGNvbXBpbGVyIGhhcHB5LCBhbmQgdG8gbm90IG1ha2UgYW5vdGhlciBzdGFjayBpbXBsZW1lbnRhdGlvbiBmb3Igc3RvcmluZyB2b2lkKiAqLwoJCXN0YWNrX3B1c2hfb25jZSgmbWF0Y2hlci0+bm9kZV9zdGFjayxub2RlKTsKCQlpZihsZWFmLT5wcmVnKSB7CgkJCWNsaV9yZWdmcmVlKGxlYWYtPnByZWcpOwoJCQlmcmVlKGxlYWYtPnByZWcpOwoJCQlsZWFmLT5wcmVnPU5VTEw7CgkJfQoJCWlmKGxlYWYtPmluZm8pIHsKCQkJZnJlZShsZWFmLT5pbmZvKTsKCQkJbGVhZi0+aW5mbz1OVUxMOwoJCX0KCS8qCXJldHVybjsqLwoJfQoJaWYobm9kZS0+YWx0ZXJuYXRpdmVzKSB7CgkJaW50IGk7CgkJc3RydWN0IHRyZWVfbm9kZSogcDsKCQltYXNzZXJ0KGNoaWxkcmVuKTsKCQlwID0gY2hpbGRyZW5bMF0tPm9wPT1PUF9MRUFGID8gTlVMTCA6IGNoaWxkcmVuWzBdLT5uZXh0OwoJCWZvcihpPTA7aTxub2RlLT5hbHRlcm5hdGl2ZXM7aSsrKQoJCQlkZXN0cm95X3RyZWVfaW50ZXJuYWwobWF0Y2hlcixjaGlsZHJlbltpXSk7CgkJaWYocCAmJiBwIT1ub2RlKQoJCQlkZXN0cm95X3RyZWVfaW50ZXJuYWwobWF0Y2hlcixwKTsvKj8/IGlzIHRoaXMgb2ssIG9yIHdpdGhvdXQgX2ludGVybmFsPyovCgl9CgllbHNlIHsKCQlpZihjaGlsZHJlbikgewoJCQlpZihjaGlsZHJlblswXSkKCQkJCWRlc3Ryb3lfdHJlZV9pbnRlcm5hbChtYXRjaGVyLGNoaWxkcmVuWzBdKTsJCQoJCX0KCX0KCWlmKG5vZGUtPm9wIT1PUF9MRUFGICYmIG5vZGUtPm5leHQgJiYgIW5vZGUtPmxpc3RlbmQpCgkJZGVzdHJveV90cmVlX2ludGVybmFsKG1hdGNoZXIsbm9kZS0+bmV4dCk7CglpZihub2RlLT51LmNoaWxkcmVuKQoJCXN0YWNrX3B1c2hfb25jZSgmbWF0Y2hlci0+bm9kZV9zdGFjaywoc3RydWN0IHRyZWVfbm9kZSopbm9kZS0+dS5jaGlsZHJlbik7LyogY2FzdCB0byBtYWtlIGNvbXBpbGVyIGhhcHB5LCBpdCBpc24ndCByZWFsbHkgYSB0cmVlX25vZGUqICovCglpZihub2RlLT5vcD09T1BfQ1VTVE9NQ0xBU1MgJiYgbm9kZS0+dS5jaGlsZHJlblswXSkgewoJCWZyZWUobm9kZS0+dS5jaGlsZHJlblswXSk7CgkJbm9kZS0+dS5jaGlsZHJlblswXT1OVUxMOwoJfQoJc3RhY2tfcHVzaF9vbmNlKCZtYXRjaGVyLT5ub2RlX3N0YWNrLG5vZGUpOwp9CgpzdGF0aWMgdm9pZCBkZXN0cm95X3RyZWUoc3RydWN0IHJlZ2V4X21hdGNoZXIqIG1hdGNoZXIpCnsKCS8qIHdlIG1pZ2h0IGhhdmUgdGhlIHNhbWUgbm9kZSBsaW5rZWQgYnkgZGlmZmVyZW50IG5vZGVzLCBzbyBhIHJlY3Vyc2l2ZSB3YWxrJmZyZWUgZG9lc24ndCB3b3JrIGluIGFsbCBzaXR1YXRpb25zLAoJICogaS5lLiBpdCBtaWdodCBkb3VibGUtZnJlZSwgc28gaW5zdGVhZCBvZiBmcmVlaW5nLCBqdXN0IHB1c2ggdGhlIG5vZGVzIG9uIGEgc3RhY2ssIGFuZCBsYXRlciBmcmVlIHRoZSBub2RlcyBpbiB0aGF0IHN0YWNrLAoJICogKGFuZCBwdXNoIHRvIHN0YWNrIG9ubHkgaWYgaXQgZG9lc24ndCBjb250YWluIGl0IGFscmVhZHkqLwoJbWFzc2VydChtYXRjaGVyKTsKCglzdGFja19yZXNldCgmbWF0Y2hlci0+bm9kZV9zdGFjayk7CglkZXN0cm95X3RyZWVfaW50ZXJuYWwobWF0Y2hlcixtYXRjaGVyLT5yb290X3JlZ2V4KTsKCWRlc3Ryb3lfdHJlZV9pbnRlcm5hbChtYXRjaGVyLG1hdGNoZXItPnJvb3RfcmVnZXhfaG9zdG9ubHkpOwoJd2hpbGUgKG1hdGNoZXItPm5vZGVfc3RhY2suY250KSB7CgkJc3RydWN0IHRyZWVfbm9kZSogbm9kZSA9IHN0YWNrX3BvcCgmbWF0Y2hlci0+bm9kZV9zdGFjayk7CgkJaWYobm9kZSkKCQkJZnJlZShub2RlKTsKCX0KfQojaWZuZGVmIE5ERUJVRwpzdGF0aWMgdm9pZCBkdW1wX25vZGUoc3RydWN0IHRyZWVfbm9kZSogbm9kZSkKewoJaW50IGk7CglzdHJ1Y3QgdHJlZV9ub2RlKiBwLCoqY2hpbGRyZW47CgltYXNzZXJ0KG5vZGUpOwoJaWYobm9kZS0+b3A9PU9QX0xFQUYpIHsKCQlpZihub2RlLT51LmxlYWYtPnByZWcpCgkJCXByaW50ZigibiVwIFtsYWJlbD1cInJlZ2V4XFxubGVhZlwiXSIsKHZvaWQqKW5vZGUpOwoJCWVsc2UKCQkJcHJpbnRmKCJuJXAgW2xhYmVsPVwiJWNcXG5sZWFmXCJdO1xuIiwodm9pZCopbm9kZSxub2RlLT5jKTsKCQlpZihub2RlLT5uZXh0ICYmICFub2RlLT5saXN0ZW5kKSB7CgkJCXByaW50ZigibiVwIC0+IG4lcDtcbiIsKHZvaWQqKW5vZGUsKHZvaWQqKW5vZGUtPm5leHQpOwoJCQlkdW1wX25vZGUobm9kZS0+bmV4dCk7CgkJfQoJCXJldHVybjsKCX0KCXByaW50ZigibiVwIFtsYWJlbD1cIiVjXFxuJWRcXG5saXN0ZW5kOiVkXCJdO1xuIiwodm9pZCopbm9kZSwobm9kZS0+b3A9PU9QX1JPT1R8fG5vZGUtPm9wPT1PUF9QQVJDTE9TRSkgPydAJyA6bm9kZS0+Yyxub2RlLT5vcCxub2RlLT5saXN0ZW5kKTsKCWlmKG5vZGUtPm5leHQpCgkJcHJpbnRmKCJuJXAgLT4gbiVwO1xuIiwodm9pZCopbm9kZSwodm9pZCopbm9kZS0+bmV4dCk7CglwcmludGYoIm4lcCAtPiB7Iiwodm9pZCopbm9kZSk7Lyp1c2luZyBhZGRyZXNzIG9mIG5vZGUgYXMgaWQqLwoJY2hpbGRyZW4gPSB0cmVlX25vZGVfZ2V0X2NoaWxkcmVuKG5vZGUpOwoJaWYobm9kZS0+YWx0ZXJuYXRpdmVzKQoJCW1hc3NlcnQoY2hpbGRyZW4pOwoJZm9yKGk9MDtpPG5vZGUtPmFsdGVybmF0aXZlcztpKyspCgkJcHJpbnRmKCJuJXAgIiwodm9pZCopY2hpbGRyZW5baV0pOwoJaWYobm9kZS0+YWx0ZXJuYXRpdmVzICYmIGNoaWxkcmVuWzBdLT5vcCE9T1BfTEVBRikKCQlmb3IocD1jaGlsZHJlblswXS0+bmV4dDtwIT1ub2RlO3A9cC0+bmV4dCkKCQl7CgkJCW1hc3NlcnQocCk7CgkJCXByaW50ZigibiVwICIsKHZvaWQqKXApOwoJCQlpZihwLT5vcD09T1BfTEVBRiB8fCBwLT5saXN0ZW5kKQoJCQkJYnJlYWs7CgkJfQoJaWYoIW5vZGUtPmFsdGVybmF0aXZlcyAmJiBjaGlsZHJlbiAmJiBjaGlsZHJlblswXSkKCQlwcmludGYoIm4lcCAiLCh2b2lkKiljaGlsZHJlblswXSk7CglwcmludGYoIn07XG4iKTsKCXByaW50Zigie3Jhbms9c2FtZTsiKTsKCWZvcihpPTA7aTxub2RlLT5hbHRlcm5hdGl2ZXM7aSsrKQoJCXByaW50ZigibiVwICIsKHZvaWQqKW5vZGUtPnUuY2hpbGRyZW5baV0pOwoJaWYobm9kZS0+YWx0ZXJuYXRpdmVzICYmIGNoaWxkcmVuWzBdLT5vcCE9T1BfTEVBRikKCQlmb3IocD1jaGlsZHJlblswXS0+bmV4dDtwIT1ub2RlO3A9cC0+bmV4dCkgCgkJewoJCQlwcmludGYoIm4lcCAiLCh2b2lkKilwKTsJCgkJCWlmKHAtPm9wPT1PUF9MRUFGIHx8IHAtPmxpc3RlbmQpCgkJCQlicmVhazsKCQl9CglpZighbm9kZS0+YWx0ZXJuYXRpdmVzICYmIGNoaWxkcmVuICYmIGNoaWxkcmVuWzBdKQoJCXByaW50ZigibiVwICIsKHZvaWQqKWNoaWxkcmVuWzBdKTsKCXByaW50ZigifTtcbiIpOwoJZm9yKGk9MDtpPG5vZGUtPmFsdGVybmF0aXZlcztpKyspCgkJZHVtcF9ub2RlKGNoaWxkcmVuW2ldKTsKCWlmKG5vZGUtPmFsdGVybmF0aXZlcyAmJiBjaGlsZHJlblswXS0+b3AhPU9QX0xFQUYpCgkJZm9yKHA9Y2hpbGRyZW5bMF0tPm5leHQ7cCE9bm9kZTtwPXAtPm5leHQpCgkJewoJCQlkdW1wX25vZGUocCk7CgkJCWlmKHAtPm9wPT1PUF9MRUFGIHx8IHAtPmxpc3RlbmQpCgkJCQlicmVhazsKCQl9CglpZighbm9kZS0+YWx0ZXJuYXRpdmVzICYmIGNoaWxkcmVuICYmIGNoaWxkcmVuWzBdKQoJCWR1bXBfbm9kZShjaGlsZHJlblswXSk7Cn0KCnZvaWQgZHVtcF90cmVlKHN0cnVjdCB0cmVlX25vZGUqIHJvb3QpCnsKCS8qdXNlIGRvdC9kb3R0eSBmcm9tIGdyYXBodml6IHRvIHZpZXcgaXQqLwoJbWFzc2VydChyb290KTsKCXByaW50ZigiZGlncmFwaCB0cmVlIHtcbiIpOwoJZHVtcF9ub2RlKHJvb3QpOwoJcHJpbnRmKCJ9XG4iKTsKfQojZW5kaWYKCgojZWxzZQovKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLU5ldyB2ZXJzaW9uIG9mIHJlZ2V4X2xpc3QuYy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCgovKiBSZWdleF9saXN0LmM6IAogKiBBIHNjYWxhYmxlLCB0cmllLWJhc2VkIGltcGxlbWVudGF0aW9uIGZvciBtYXRjaGluZyBhZ2FpbnN0IAogKiBhIGxpc3Qgb2YgcmVndWxhciBleHByZXNzaW9ucy4KICoKICogQSB0cml2aWFsIHdheSB0byBpbXBsZW1lbnQgbWF0Y2hpbmcgYWdhaW5zdCBhIGxpc3Qgb2YgcmVndWxhciBleHByZXNzaW9ucyAKICogd291bGQgaGF2ZSBiZWVuIHRvIGNvbnN0cnVjdCBhIHNpbmdsZSByZWd1bGFyIGV4cHJlc3Npb24sIGJ5IGNvbmNhdGVuYXRpbmcgCiAqIHRoZSBsaXN0IHdpdGggdGhlIGFsdGVybmF0ZSAofCkgb3BlcmF0b3IuCiAqIEJVVCBhIHVzdWFsIERGQSBpbXBsZW1lbnRhdGlvbiBvZiByZWd1bGFyIGV4cHJlc3Npb24gbWF0Y2hpbmcgKGVnLjogR05VIGxpYmMpCiAqIGxlYWRzIHRvICJzdGF0ZSBleHBsb3Npb24iIHdoZW4gdGhlcmUgYXJlIG1hbnkgKDUwMDArKSBhbHRlcm5hdGUgKHwpIG9wZXJhdG9ycy4KICogVGhpcyBpcyB0aGUgcmVhc29uIGZvciB1c2luZyBhIHRyaWUtYmFzZWQgaW1wbGVtZW50YXRpb24uCiAqCiAqCiAqIERlc2lnbiBjb25zaWRlcmF0aW9uczoKICoKICogUmVjdXJzaXZlIGNhbGwgcG9pbnRzOiB0aGVyZSBhcmUgc2l0dWF0aW9ucyB3aGVuIG1hdGNoIGhhcyB0byBiZSByZXRyaWVkIG9uIGEgZGlmZmVyZW50IHN1Yi10cmllLCBvciB3aXRoIGEgZGlmZmVyZW50IHJlcGVhdCBjb3VudC4KICogQWx0ZXJuYXRlIG9wZXJhdG9ycywgYW5kIHJlcGVhdC9yYW5nZSBvcGVyYXRvcnMgKCssKix7fSkgYXJlIHJlY3Vyc2l2IGNhbGwgcG9pbnRzLiBXaGVuIGEgZmFpbHVyZSBpcyBlbmNvdW50ZXJlZCBkdXJpbmcgYSBtYXRjaCwKICogdGhlIGZ1bmN0aW9uIHNpbXBseSByZXR1cm5zIGZyb20gdGhlIHJlY3Vyc2l2ZSBjYWxsLCBhbmQgZW5kcyB1cCBhdCBhIGZhaWx1cmUgcG9pbnQgKHJlY3Vyc2l2ZSBjYWxsIHBvaW50KS4KICoKICogImdvIHRvIHBhcmVudCIgYmVsb3cgYWN0dWFsbHkgbWVhbnMsIHJldHVybiBmcm9tIHJlY3Vyc2l2ZSBjYWxsLgogKgogKiBmYWlsX2FjdGlvbjogd2UgbmVlZCB0byByZXR1cm4gdG8gY2xvc2VzdCBmYWlsdXJlIHBvaW50IChyZWN1cnNpdmUgY2FsbCBwb2ludCksCiAqICBhbmQgc3dpdGNoIGN1cnJlbnQgbm9kZSB0byBub2RlIHBvaW50ZWQgYnkgZmFpbF9hY3Rpb24KICoKICogTm9kZSB0eXBlczoKICogCU9QX1JPT1Q6IGNvbnRhaW5zIGluZm9ybWF0aW9uIHRoYXQgYXBwbGllcyB0byB0aGUgZW50aXJlIHRyaWUuCiAqIAkJaXQgY2FuIG9ubHkgYXBwZWFyIGFzIHJvb3Qgbm9kZSwgYW5kIG5vdCBhcyBjaGlsZCBub2RlLgogKiAJCU9uIGNoaWxkIGZhaWw6IG1hdGNoIGhhcyBmYWlsZWQKICogCQlUaGlzIGlzIE5PVCBhIHJlY3Vyc2l2ZSBjYWxsIHBvaW50CiAqIAlPUF9DSEFSX0JJTkFSWV9TRUFSQ0g6IGNob29zZXMgYSBzdWItdHJpZSwgYmFzZWQgb24gY3VycmVudCBjaGFyYWN0ZXI7IAogKiAJCQl1c2luZyBiaW5hcnktc2VhcmNoCiAqIAkJCU9uIGZhaWw6IGdvIHRvIG5vZGUgaW5kaWNhdGVkIGJ5IGZhaWxfYWN0aW9uLCBvciBpZiAKICogCQkJCWZhaWxfYWN0aW9uIGlzIE5VTEwsIHRvIHBhcmVudAogKiAJCQlPbiBjaGlsZCBmYWlsOiBleGVjdXRlIGZhaWwgb2YgY3VycmVudCBub2RlCiAqIAlPUF9BTFRFUk5BVElWRVM6IHRyeSBtYXRjaGluZyBlYWNoIHN1Yi10cmllLCBpZiBhbGwgZmFpbHMgZXhlY3V0ZSBmYWlsCiAqIAkJYWN0aW9uIG9mIGN1cnJlbnQgbm9kZS4gVGhpcyBpcyBhIHJlY3Vyc2l2ZSBjYWxsIHBvaW50CiAqIAlPUF9DSEFSX1JFUEVBVDogcmVwZWF0IHNwZWNpZmllZCBjaGFyYWN0ZXIgYSBudW1iZXIgb2YgdGltZXMgaW4gcmFuZ2U6CiAqCQlbbWluX3JhbmdlLCBtYXhfcmFuZ2VdOyAKICoJCQltaW5fcmFuZ2U6IDAgZm9yICogb3BlcmF0b3IKICoJCQkJICAgMSBmb3IgKyBvcGVyYXRvcgogKgkJCW1heF9yYW5nZTogcmVtYWluaW5nIGxlbmd0aCBvZiBjdXJyZW50IHN0cmluZyBmb3IgKiwrIG9wZXJhdG9yCiAqCQkJT1I6IG1pbl9yYW5nZSwgbWF4X3JhbmdlIGFzIHNwZWNpZmllZCBieSB0aGUge21pbixtYXh9IG9wZXJhdG9yCiAqCQlPbiBmYWlsOiBmYWlsX2FjdGlvbiwgb3IgcGFyZW50IGlmIE5VTEwKICoJCU9uIGNoaWxkIGZhaWw6IHJlZHVjZSBtYXRjaCByZXBlYXQgY291bnQsIHRyeSBhZ2FpbiBvbiBjaGlsZCwgaWYKICoJCQlyZXBlYXQgY291bnQ8bWluX3JhbmdlLCBleGVjdXRlIGZhaWwgb2YgY3VycmVudCBub2RlCiAqCQlBbHNvIGhhcyBhIGJpdG1hcCBvbiB3aGF0IGNoYXJhY3RlcnMgYXJlIGFjY2VwdGVkIGJleW9uZCBpdCwKICoJCWFzIGFuIG9wdGltaXphdGlvbnMgZm9yIHRoZSBjYXNlLCB3aGVuIGEgbWF4aW11bSBtYXRjaCBpc24ndCBwb3NzaWJsZQogKgkJTm90IHJlY29tZW5kZWQgdG8gdXNlIHRoaXMgd2hlbiBtaW5fcmFuZ2U9bWF4X3JhbmdlPTEKICoJCVRoaXMgaXMgYSByZWN1cnNpdmUgY2FsbCBwb2ludAogKglPUF9ET1RfUkVQRUFUOiBsaWtlIE9QX0NIQVJfUkVQRUFUIGJ1dCBhY2NlcHQgYW55IGNoYXJhY3RlcgogKgkJTm90IHJlY29tZW5kZWQgdG8gdXNlIHRoaXMgd2hlbiBtaW5fcmFuZ2U9bWF4X3JhbmdlPTEKICoJCVRoaXMgaXMgYSByZWN1cnNpdmUgY2FsbCBwb2ludAogKglPUF9HUk9VUF9TVEFSVDogc3RhcnQgb2YgYSBncm91cCAiKCIsIGFsc28gc3BlY2lmaWVzIGdyb3VwIGZsYWdzOgogKgkJcmVwZWF0OiBpc19yZXBlYXQsIG1pbl9yYW5nZSwgbWF4X3JhbmdlCiAqCQlUaGlzIGlzIGEgcmVjdXJzaXZlIGNhbGwgcG9pbnQgaWYgaXNfcmVwZWF0CiAqCU9QX0dST1VQX0VORDogZW5kIG9mIGdyb3VwICIpIgogKiAgICAgIE9QX1NUUkNNUDogY29tcGFyZSB3aXRoIHNwZWNpZmllZCBzdHJpbmcsCiAqICAgICAgCSAgIGl0IGhhcyBhbiBhcnJheSBvZiBmYWlsIGFjdGlvbnMsIG9uZSBmb3IgZWFjaCBjaGFyYWN0ZXIKICogICAgICAJICAgZGVmYXVsdCBmYWlsIGFjdGlvbjogZ28gdG8gcGFyZW50CiAqICAgICAgCSAgIFRoaXMgd2FzIGludHJvZHVjZWQgZnJvbSBtZW1vcnktIGFuZCBzcGVlZC1lZmZpY2llbmN5CiAqICAgICAgCSAgIGNvbnNpZGVyYXRpb25zLiAKICogICAgICBPUF9DSEFSX0NMQVNTX1JFUEVBVDogbWF0Y2ggY2hhcmFjdGVyIHdpdGggY2hhcmFjdGVyIGNsYXNzCiAqICAgICAgCW1pbl9yYW5nZSwgbWF4X3JhbmdlCiAqICAgICAgCUZvciBhIHNpbmdsZSBjaGFyYWN0ZXIgY2xhc3MgbWluX3JhbmdlPW1heF9yYW5nZT0xCiAqCU9QX01BVENIX09LOiBtYXRjaCBoYXMgc3VjY2VlZGVkCiAqCiAqIFRPRE86IG1heWJlIHdlJ2xsIG5lZWQgYSBtb3JlIGVmZmljaWVudCB3YXkgdG8gY2hvb3NlIGJldHdlZW4gY2hhcmFjdGVyIGNsYXNzZXMuCiAqICAgICAgIE9QX0RPVF9SRVBFQVQvT1BfQ0hBUl9SRVBFQVQgbmVlZHMgYSBtb3JlIGVmZmljaWVudCBzcGVjaWZpY2F0aW9uIG9mIGl0cyBmYWlsdXJlIGZ1bmN0aW9uLCBpbnN0ZWFkIG9mIHVzaW5nCiAqICAgICAgIGJhY2t0cmFja2luZyBhcHByb2FjaC4KICoKICogVGhlIGZhaWx1cmUgZnVuY3Rpb24vYWN0aW9uIGlzIGp1c3QgZm9yIG9wdGltaXphdGlvbiwgdGhlIG1hdGNoIGFsZ29yaXRobXMgd29ya3MgZXZlbiB3aXRob3V0IGl0LgogKiBUT0RPOkluIHRoaXMgZmlyc3QgZHJhZnQgZmFpbCBhY3Rpb24gd2lsbCBhbHdheXMgYmUgTlVMTCwgaW4gYSBsYXRlciB2ZXJzaW9uIEknbGwgaW1wbGVtZW50IGZhaWwgYWN0aW9ucyB0b28uCiAqCiAqCiAqLyAKCiNpbmNsdWRlIDxzdHJpbmcuaD4KI2luY2x1ZGUgImNsdHlwZXMuaCIKI2luY2x1ZGUgIm90aGVycy5oIgoKLyogb2Zmc2V0b2YgaXMgbm90IEFOU0kgQyAqLwojaWZuZGVmIG9mZnNldG9mCiMgICBkZWZpbmUgb2Zmc2V0b2YodHlwZSxtZW1iKSAoKHNpemVfdCkmKCh0eXBlKikwKS0+bWVtYikKI2VuZGlmCgojZGVmaW5lIGNvbnRhaW5lcl9vZihwdHIsIHR5cGUsIG1lbWJlcikgKCAodHlwZSAqKSAoKGNoYXIgKilwdHIgLSBvZmZzZXRvZih0eXBlLCBtZW1iZXIpKSApCiNkZWZpbmUgY29udGFpbmVyX29mX2NvbnN0KHB0ciwgdHlwZSwgbWVtYmVyKSAoICh0eXBlICopICgoY29uc3QgY2hhciAqKXB0ciAtIG9mZnNldG9mKHR5cGUsIG1lbWJlcikpICkKCmVudW0gdHJpZV9ub2RlX3R5cGUgewoJT1BfUk9PVCwKCU9QX0NIQVJfQklOQVJZX1NFQVJDSCwKCU9QX0FMVEVSTkFUSVZFUywKCU9QX0NIQVJfUkVQRUFULAoJT1BfRE9UX1JFUEVBVCwKCU9QX0NIQVJfQ0xBU1NfUkVQRUFULAoJT1BfU1RSQ01QLAoJT1BfR1JPVVBfU1RBUlQsCglPUF9HUk9VUF9FTkQsCglPUF9NQVRDSF9PSwp9OwoKCi8qIHRoZSBjb21vbiBkZWZpbml0aW9uIG9mIGEgdHJpZSBub2RlICovCnN0cnVjdCB0cmllX25vZGUKewoJZW51bSB0cmllX25vZGVfdHlwZSB0eXBlOwp9OwoKc3RydWN0IHRyaWVfbm9kZV9tYXRjaCB7CglzdHJ1Y3QgdHJpZV9ub2RlIG5vZGU7CgkvKiBhZGRpdGlvbmFsIG1hdGNoIGluZm8gKi8KfTsKCnN0cnVjdCB0cmllX25vZGVfcm9vdAp7CglzdHJ1Y3QgdHJpZV9ub2RlIG5vZGU7CglzdHJ1Y3QgdHJpZV9ub2RlKiBjaGlsZDsKfTsKCnN0cnVjdCB0cmllX25vZGVfYmluYXJ5X3NlYXJjaAp7CglzdHJ1Y3QgdHJpZV9ub2RlIG5vZGU7Cgl1aW50OF90IGNoaWxkcmVuX2NvdW50Oy8qIG51bWJlciBvZiBjaGlsZHJlbiB0byBzZWFyY2ggYW1vbmcgLTEhIDI1NSA9IDI1NiBjaGlsZHJlbiovCQoJc3RydWN0IHRyaWVfbm9kZSogZmFpbF9hY3Rpb247Cgl1bnNpZ25lZCBjaGFyKiBjaGFyX2Nob2ljZXM7LyogY2hpbGRyZW5fY291bnQgZWxlbWVudHMgKi8KCXN0cnVjdCB0cmllX25vZGUqKiBjaGlsZHJlbjsvKmNoaWxkcmVuX2NvdW50IGVsZW1lbnRzICovCn07CgpzdHJ1Y3QgdHJpZV9ub2RlX2FsdGVybmF0aXZlcwp7CglzdHJ1Y3QgdHJpZV9ub2RlIG5vZGU7Cgl1aW50MzJfdCBhbHRlcm5hdGl2ZXNfY291bnQ7CgkvKiBuZWVkIHRvIHN1cHBvcnQgbm9kZSB3aXRoIGxvdHMgb2YgYWx0ZXJuYXRpdmVzLCAKCSAqIGZvciBhIHdvcnN0LWNhc2Ugc2NlbmFyaW8gd2hlcmUgZWFjaCBsaW5lIGVuZHMgdXAgYXMgYSBzdWItdHJpZSBvZiBPUF9BTFRFUk5BVElWRVMqLwoJc3RydWN0IHRyaWVfbm9kZSogZmFpbF9hY3Rpb247CglzdHJ1Y3QgdHJpZV9ub2RlKiogY2hpbGRyZW47Cn07CgpzdHJ1Y3QgdHJpZV9ub2RlX2NoYXJfcmVwZWF0CnsKCXN0cnVjdCB0cmllX25vZGUgbm9kZTsKCXVuc2lnbmVkIGNoYXIgY2hhcmFjdGVyOwoJdWludDhfdCByYW5nZV9taW4sIHJhbmdlX21heDsvKiBhY2NvcmRpbmcgdG8gUE9TSVggd2UgbmVlZCBub3Qgc3VwcG9ydCBtb3JlIHRoYW4gMjU1IHJlcGV0aXRpb25zKi8KCXN0cnVjdCBjaGFyX2JpdG1hcCogYml0bWFwX2FjY2VwdF9hZnRlcjsvKiBiaXRtYXAgb2YgY2hhcmFjdGVycyBhY2NlcHRlZCBhZnRlciB0aGlzLCAKCQkJCQkJICAgdG8gb3B0aW1pemUgcmVwZWF0IDwgbWF4X3JhbmdlIGNhc2U7IGlmIGl0cyBOVUxMCgkJCQkJCSAgIHRoZXJlIGlzIG5vIG9wdGltaXphdGlvbiovCglzdHJ1Y3QgdHJpZV9ub2RlKiBjaGlsZDsKCXN0cnVjdCB0cmllX25vZGUqIGZhaWxfYWN0aW9uOwp9OwoKc3RydWN0IHRyaWVfbm9kZV9kb3RfcmVwZWF0CnsKCXN0cnVjdCB0cmllX25vZGUgbm9kZTsKCXVpbnQ4X3QgcmFuZ2VfbWluLCByYW5nZV9tYXg7LyogYWNjb3JkaW5nIHRvIFBPU0lYIHdlIG5lZWQgbm90IHN1cHBvcnQgbW9yZSB0aGFuIDI1NSByZXBldGl0aW9ucyovCglzdHJ1Y3QgY2hhcl9iaXRtYXAqIGJpdG1hcF9hY2NlcHRfYWZ0ZXI7LyogYml0bWFwIG9mIGNoYXJhY3RlcnMgYWNjZXB0ZWQgYWZ0ZXIgdGhpcywgCgkJCQkJCSAgIHRvIG9wdGltaXplIHJlcGVhdCA8IG1heF9yYW5nZSBjYXNlOyBpZiBpdHMgTlVMTAoJCQkJCQkgICB0aGVyZSBpcyBubyBvcHRpbWl6YXRpb24qLwoJc3RydWN0IHRyaWVfbm9kZSogY2hpbGQ7CglzdHJ1Y3QgdHJpZV9ub2RlKiBmYWlsX2FjdGlvbjsKfTsKCnN0cnVjdCB0cmllX25vZGVfZ3JvdXBfc3RhcnQKewoJc3RydWN0IHRyaWVfbm9kZSBub2RlOwoJdWludDhfdCByYW5nZV9taW4sIHJhbmdlX21heDsvKiBpZiByYW5nZV9taW49PXJhbmdlX21heD09MSwgdGhlbiB0aGlzIGlzIE5PVCBhIHJlcGVhdCwgdGh1cyBub3QgYSByZWN1cnNpdmUgY2FsbCBwb2ludCovCglzdHJ1Y3QgdHJpZV9ub2RlKiBjaGlsZDsKCXN0cnVjdCB0cmllX25vZGUqIGZhaWxfYWN0aW9uOwkKfTsKCnN0cnVjdCB0cmllX25vZGVfZ3JvdXBfZW5kCnsKCXN0cnVjdCB0cmllX25vZGUgbm9kZTsKCXN0cnVjdCB0cmllX25vZGUqIGNoaWxkOwp9OwoKc3RydWN0IHRyaWVfbm9kZV9zdHJjbXAKewoJc3RydWN0IHRyaWVfbm9kZSBub2RlOwoJdWludDhfdCBzdHJpbmdfbGVuZ3RoOy8qIGZvciBsb25nZXIgc3RyaW5ncyBhIHNlcXVlbmNlIG9mIG5vZGVfc3RyY21wIHNob3VsZCBiZSB1c2VkICovCgl1bnNpZ25lZCBjaGFyKiBzdHJpbmc7CglzdHJ1Y3QgdHJpZV9ub2RlKiBjaGlsZDsKCXN0cnVjdCB0cmllX25vZGUqKiBmYWlsX2FjdGlvbnM7LyogdGhpcyBoYXMgc3RyaW5nX2xlbmd0aCBlbGVtZW50cywgb3IgTlVMTCBpZiBubyBmYWlsX2FjdGlvbnMgYXJlIGNvbXB1dGVkICovCn07CgpzdHJ1Y3QgdHJpZV9ub2RlX2NoYXJfY2xhc3NfcmVwZWF0CnsKCXN0cnVjdCB0cmllX25vZGUgbm9kZTsKCXN0cnVjdCBjaGFyX2JpdG1hcCogYml0bWFwOwoJc3RydWN0IGNoYXJfYml0bWFwKiBiaXRtYXBfYWNjZXB0X2FmdGVyOwoJdWludDhfdCByYW5nZV9taW4sIHJhbmdlX21heDsKCXN0cnVjdCB0cmllX25vZGUqIGNoaWxkOwoJc3RydWN0IHRyaWVfbm9kZSogZmFpbF9hY3Rpb247Cn07CgpzdGF0aWMgaW5saW5lIGludCBiaXRtYXBfYWNjZXB0cyhjb25zdCBzdHJ1Y3QgY2hhcl9iaXRtYXAqIGJpdG1hcCwgY29uc3QgY2hhciBjKQp7CgkvKiBUT0RPOiBjaGVjayBpZiBjIGlzIGFjY2VwdGVkIGJ5IGJpdG1hcCAqLwoJcmV0dXJuIDA7Cn0KCiNkZWZpbmUgTUFUQ0hfRkFJTEVEIDAKI2RlZmluZSBNQVRDSF9PSyAgICAgMQoKI2RlZmluZSBGQUlMX0FDVElPTiggZmFpbF9ub2RlICkgKCpmYWlsX2FjdGlvbiA9IChmYWlsX25vZGUpLCBNQVRDSF9GQUlMRUQpCgoKI2lmbmRlZiBNSU4KI2RlZmluZSBNSU4oYSxiKSAoKGEpPChiKSA/IChhKSA6IChiKSkKI2VuZGlmCgpzdGF0aWMgaW50IG1hdGNoX25vZGUoY29uc3Qgc3RydWN0IHRyaWVfbm9kZSogbm9kZSwgY29uc3QgdW5zaWduZWQgY2hhciogdGV4dCwgY29uc3QgdW5zaWduZWQgY2hhciogdGV4dF9lbmQsIGNvbnN0IHN0cnVjdCB0cmllX25vZGUqKiBmYWlsX2FjdGlvbik7CgpzdGF0aWMgaW50IG1hdGNoX3JlcGVhdChjb25zdCB1bnNpZ25lZCBjaGFyKiB0ZXh0LCBjb25zdCB1bnNpZ25lZCBjaGFyKiB0ZXh0X2VuZCwgY29uc3Qgc2l6ZV90IHJhbmdlX21pbiwgY29uc3Qgc2l6ZV90IHJlcGVhdF9zdGFydCwgCgkJY29uc3Qgc3RydWN0IGNoYXJfYml0bWFwKiBiaXRtYXBfYWNjZXB0X2FmdGVyLCBjb25zdCBzdHJ1Y3QgdHJpZV9ub2RlKiBjaGlsZCwgY29uc3Qgc3RydWN0IHRyaWVfbm9kZSoqIGZhaWxfYWN0aW9uLAoJCWNvbnN0IHN0cnVjdCB0cmllX25vZGUqIHRoaXNfZmFpbF9hY3Rpb24pCnsKCXNpemVfdCBpOwoJZm9yKGkgPSByZXBlYXRfc3RhcnQ7aSA+IHJhbmdlX21pbjtpLS0pIHsKCQlpZighYml0bWFwX2FjY2VwdF9hZnRlciB8fCBiaXRtYXBfYWNjZXB0cyggYml0bWFwX2FjY2VwdF9hZnRlciwgdGV4dFtpLTFdKSkgewoJCQlpbnQgcmMgPSBtYXRjaF9ub2RlKGNoaWxkLCAmdGV4dFtpXSwgdGV4dF9lbmQsIGZhaWxfYWN0aW9uKTsKCQkJLyogaWdub3JlIGZhaWxfYWN0aW9uIGZvciBub3csIHdlIGhhdmUgdGhlIGJpdG1hcF9hY2NlcHRzX2FmdGVyIG9wdGltaXphdGlvbiAqLwoJCQlpZihyYykgewoJCQkJcmV0dXJuIE1BVENIX09LOwoJCQl9CgkJfQkJCQkJCQoJfQoJaWYoIXJhbmdlX21pbikgewoJCS8qIHRoaXMgbWF0Y2ggaXMgb3B0aW9uYWwsIHRyeSBjaGlsZCBvbmx5ICovCgkJaW50IHJjID0gbWF0Y2hfbm9kZShjaGlsZCwgdGV4dCwgdGV4dF9lbmQsIGZhaWxfYWN0aW9uKTsKCQlpZihyYykgewoJCQlyZXR1cm4gTUFUQ0hfT0s7CgkJfQoJfQoJcmV0dXJuIEZBSUxfQUNUSU9OKHRoaXNfZmFpbF9hY3Rpb24pOwp9CgovKiB0ZXh0X2VuZCBwb2ludHMgdG8gXDAgaW4gdGV4dCAqLwpzdGF0aWMgaW50IG1hdGNoX25vZGUoY29uc3Qgc3RydWN0IHRyaWVfbm9kZSogbm9kZSwgY29uc3QgdW5zaWduZWQgY2hhciogdGV4dCwgY29uc3QgdW5zaWduZWQgY2hhciogdGV4dF9lbmQsIGNvbnN0IHN0cnVjdCB0cmllX25vZGUqKiBmYWlsX2FjdGlvbikKewoJd2hpbGUobm9kZSAmJiB0ZXh0IDwgdGV4dF9lbmQpIHsJCgkJc3dpdGNoKG5vZGUtPnR5cGUpIHsKCQkJY2FzZSBPUF9ST09UOgoJCQkJewkKCQkJCQljb25zdCBzdHJ1Y3QgdHJpZV9ub2RlX3Jvb3QqIHJvb3Rfbm9kZSA9IGNvbnRhaW5lcl9vZl9jb25zdChub2RlLCBjb25zdCBzdHJ1Y3QgdHJpZV9ub2RlX3Jvb3QsIG5vZGUpOwoJCQkJCW5vZGUgPSByb290X25vZGUtPmNoaWxkOwoJCQkJCWJyZWFrOwoJCQkJfQoJCQljYXNlIE9QX0NIQVJfQklOQVJZX1NFQVJDSDoKCQkJCXsJCQkJCQoJCQkJCWNvbnN0IHN0cnVjdCB0cmllX25vZGVfYmluYXJ5X3NlYXJjaCogYmluX25vZGUgPSBjb250YWluZXJfb2ZfY29uc3Qobm9kZSwgY29uc3Qgc3RydWN0IHRyaWVfbm9kZV9iaW5hcnlfc2VhcmNoLCBub2RlKTsKCQkJCQljb25zdCB1bnNpZ25lZCBjaGFyIGNzZWFyY2ggPSAqdGV4dDsKCQkJCQlzaXplX3QgbWlkLCBsZWZ0ID0gMCwgcmlnaHQgPSBiaW5fbm9kZS0+Y2hpbGRyZW5fY291bnQtMTsJCQkJCQoJCQkJCXdoaWxlKGxlZnQ8PXJpZ2h0KSB7CgkJCQkJCW1pZCA9IGxlZnQrKHJpZ2h0LWxlZnQpLzI7CgkJCQkJCWlmKGJpbl9ub2RlLT5jaGFyX2Nob2ljZXNbbWlkXSA9PSBjc2VhcmNoKQoJCQkJCQkJYnJlYWs7CgkJCQkJCWVsc2UgaWYoYmluX25vZGUtPmNoYXJfY2hvaWNlc1ttaWRdIDwgY3NlYXJjaCkKCQkJCQkJCWxlZnQgPSBtaWQrMTsKCQkJCQkJZWxzZQoJCQkJCQkJcmlnaHQgPSBtaWQtMTsKCQkJCQl9CgkJCQkJaWYobGVmdCA8PSByaWdodCkgewoJCQkJCQkvKiBtYXRjaCBzdWNjZXNzZnVsICovCgkJCQkJCW5vZGUgPSBiaW5fbm9kZS0+Y2hpbGRyZW5bbWlkXTsKCQkJCQkJKyt0ZXh0OwoJCQkJCX0KCQkJCQllbHNlIHsKCQkJCQkJcmV0dXJuIEZBSUxfQUNUSU9OKCBiaW5fbm9kZS0+ZmFpbF9hY3Rpb24gKTsKCQkJCQl9CgkJCQkJYnJlYWs7CgkJCQl9CgkJCWNhc2UgT1BfQUxURVJOQVRJVkVTOgoJCQkJewoJCQkJCWNvbnN0IHN0cnVjdCB0cmllX25vZGVfYWx0ZXJuYXRpdmVzKiBhbHRfbm9kZSA9IGNvbnRhaW5lcl9vZl9jb25zdChub2RlLCBjb25zdCBzdHJ1Y3QgdHJpZV9ub2RlX2FsdGVybmF0aXZlcywgbm9kZSk7CgkJCQkJc2l6ZV90IGk7CgkJCQkJKmZhaWxfYWN0aW9uID0gTlVMTDsKCQkJCQlmb3IoaT0wO2kgPCBhbHRfbm9kZS0+YWx0ZXJuYXRpdmVzX2NvdW50O2krKykgewoJCQkJCQlpbnQgcmMgPSBtYXRjaF9ub2RlKGFsdF9ub2RlLT5jaGlsZHJlbltpXSwgdGV4dCwgdGV4dF9lbmQsIGZhaWxfYWN0aW9uKTsKCQkJCQkJaWYocmMpIHsJCQkJCQkJCgkJCQkJCQlyZXR1cm4gTUFUQ0hfT0s7CgkJCQkJCX0KCQkJCQkJLyogc3VwcG9ydGluZyBmYWlsX2FjdGlvbnMgaXMgdHJpY2t5LAoJCQkJCQkgKiAgaWYgd2UganVzdCBnbyB0byB0aGUgbm9kZSBzcGVjaWZpZWQsIHdoYXQgaGFwcGVucyBpZiB0aGUgbWF0Y2ggZmFpbHMsIGFuZCBubwoJCQkJCQkgKiAgZnVydGhlciBmYWlsX2FjdGlvbiBpcyBzcGVjaWZpZWQ/IFdlIHNob3VsZCBrbm93IHdoZXJlIHRvIGNvbnRpbnVlIHRoZSBzZWFyY2guCgkJCQkJCSAqIEZvciBub3cgZmFpbF9hY3Rpb24gaXNuJ3Qgc3VwcG9ydGVkIGZvciBPUF9BTFRFUk5BVElWRVMqLwkJCQkJCQoJCQkJCX0KCQkJCQlicmVhazsKCQkJCX0KCQkJY2FzZSBPUF9DSEFSX1JFUEVBVDoKCQkJCXsKCQkJCQljb25zdCBzdHJ1Y3QgdHJpZV9ub2RlX2NoYXJfcmVwZWF0KiBjaGFyX3JlcF9ub2RlID0gY29udGFpbmVyX29mX2NvbnN0KG5vZGUsIGNvbnN0IHN0cnVjdCB0cmllX25vZGVfY2hhcl9yZXBlYXQsIG5vZGUpOwoJCQkJCWNvbnN0IHNpemVfdCBtYXhfbGVuID0gTUlOKCB0ZXh0X2VuZCAtIHRleHQsIGNoYXJfcmVwX25vZGUtPnJhbmdlX21heC0xKTsKCQkJCQkvKiB0b2RvOiB3aGF0IGFib3V0IHRoZSA4IGJpdCBsaW1pdGF0aW9uIG9mIHJhbmdlX21heCwgYW5kIHdoYXQgYWJvdXQgaW5mICgrLCopPyAqLwoJCQkJCWNvbnN0IGNoYXIgY2FjY2VwdCA9IGNoYXJfcmVwX25vZGUtPmNoYXJhY3RlcjsKCQkJCQlzaXplX3QgcmVwOwoKCQkJCQlpZihtYXhfbGVuIDwgY2hhcl9yZXBfbm9kZS0+cmFuZ2VfbWluKQoJCQkJCQlyZXR1cm4gRkFJTF9BQ1RJT04oY2hhcl9yZXBfbm9kZS0+ZmFpbF9hY3Rpb24pOwoKCQkJCQlmb3IocmVwPTA7cmVwIDwgbWF4X2xlbjtyZXArKykgewoJCQkJCQlpZih0ZXh0W3JlcF0gIT0gY2FjY2VwdCkgewoJCQkJCQkJYnJlYWs7CgkJCQkJCX0KCQkJCQl9CgoJCQkJCXJldHVybiBtYXRjaF9yZXBlYXQodGV4dCwgdGV4dF9lbmQsIGNoYXJfcmVwX25vZGUtPnJhbmdlX21pbiwgcmVwLAoJCQkJCQkJY2hhcl9yZXBfbm9kZS0+Yml0bWFwX2FjY2VwdF9hZnRlciwgY2hhcl9yZXBfbm9kZS0+Y2hpbGQsIGZhaWxfYWN0aW9uLAoJCQkJCQkJY2hhcl9yZXBfbm9kZS0+ZmFpbF9hY3Rpb24pOwoJCQkJfQoJCQljYXNlIE9QX0RPVF9SRVBFQVQ6CgkJCQl7CgkJCQkJY29uc3Qgc3RydWN0IHRyaWVfbm9kZV9kb3RfcmVwZWF0KiBkb3RfcmVwX25vZGUgPSBjb250YWluZXJfb2ZfY29uc3Qobm9kZSwgY29uc3Qgc3RydWN0IHRyaWVfbm9kZV9kb3RfcmVwZWF0LCBub2RlKTsKCQkJCQljb25zdCBzaXplX3QgbWF4X2xlbiA9IE1JTiggdGV4dF9lbmQgLSB0ZXh0LCBkb3RfcmVwX25vZGUtPnJhbmdlX21heC0xKTsKCQkJCQkvKiB0b2RvOiB3aGF0IGFib3V0IHRoZSA4IGJpdCBsaW1pdGF0aW9uIG9mIHJhbmdlX21heCwgYW5kIHdoYXQgYWJvdXQgaW5mICgrLCopPyAqLwoKCQkJCQlpZihtYXhfbGVuIDwgZG90X3JlcF9ub2RlLT5yYW5nZV9taW4pCgkJCQkJCXJldHVybiBGQUlMX0FDVElPTihkb3RfcmVwX25vZGUtPmZhaWxfYWN0aW9uKTsKCgkJCQkJcmV0dXJuIG1hdGNoX3JlcGVhdCh0ZXh0LCB0ZXh0X2VuZCwgZG90X3JlcF9ub2RlLT5yYW5nZV9taW4sIG1heF9sZW4sCgkJCQkJCQlkb3RfcmVwX25vZGUtPmJpdG1hcF9hY2NlcHRfYWZ0ZXIsIGRvdF9yZXBfbm9kZS0+Y2hpbGQsIGZhaWxfYWN0aW9uLAoJCQkJCQkJZG90X3JlcF9ub2RlLT5mYWlsX2FjdGlvbik7CgkJCQl9CgkJCWNhc2UgT1BfQ0hBUl9DTEFTU19SRVBFQVQ6CgkJCQl7CgkJCQkJY29uc3Qgc3RydWN0IHRyaWVfbm9kZV9jaGFyX2NsYXNzX3JlcGVhdCogY2xhc3NfcmVwX25vZGUgPSBjb250YWluZXJfb2ZfY29uc3Qobm9kZSwgY29uc3Qgc3RydWN0IHRyaWVfbm9kZV9jaGFyX2NsYXNzX3JlcGVhdCwgbm9kZSk7CgkJCQkJY29uc3Qgc2l6ZV90IG1heF9sZW4gPSBNSU4oIHRleHRfZW5kIC0gdGV4dCwgY2xhc3NfcmVwX25vZGUtPnJhbmdlX21heC0xKTsKCQkJCQkvKiB0b2RvOiB3aGF0IGFib3V0IHRoZSA4IGJpdCBsaW1pdGF0aW9uIG9mIHJhbmdlX21heCwgYW5kIHdoYXQgYWJvdXQgaW5mICgrLCopPyAqLwoJCQkJCXNpemVfdCByZXA7CgoJCQkJCWlmKG1heF9sZW4gPCBjbGFzc19yZXBfbm9kZS0+cmFuZ2VfbWluKQoJCQkJCQlyZXR1cm4gRkFJTF9BQ1RJT04oY2xhc3NfcmVwX25vZGUtPmZhaWxfYWN0aW9uKTsKCgkJCQkJZm9yKHJlcD0wO3JlcCA8IG1heF9sZW47cmVwKyspIHsKCQkJCQkJaWYoIWJpdG1hcF9hY2NlcHRzKCBjbGFzc19yZXBfbm9kZS0+Yml0bWFwLCB0ZXh0W3JlcF0pKSB7CgkJCQkJCQlicmVhazsKCQkJCQkJfQoJCQkJCX0KCgkJCQkJcmV0dXJuIG1hdGNoX3JlcGVhdCh0ZXh0LCB0ZXh0X2VuZCwgY2xhc3NfcmVwX25vZGUtPnJhbmdlX21pbiwgcmVwLAoJCQkJCQkJY2xhc3NfcmVwX25vZGUtPmJpdG1hcF9hY2NlcHRfYWZ0ZXIsIGNsYXNzX3JlcF9ub2RlLT5jaGlsZCwgZmFpbF9hY3Rpb24sCgkJCQkJCQljbGFzc19yZXBfbm9kZS0+ZmFpbF9hY3Rpb24pOwoJCQkJCWJyZWFrOwoJCQkJfQoJCQljYXNlIE9QX1NUUkNNUDoKCQkJCXsKCQkJCQljb25zdCBzdHJ1Y3QgdHJpZV9ub2RlX3N0cmNtcCogc3RyY21wX25vZGUgPSBjb250YWluZXJfb2ZfY29uc3Qobm9kZSwgY29uc3Qgc3RydWN0IHRyaWVfbm9kZV9zdHJjbXAsIG5vZGUpOwoJCQkJCXNpemVfdCBpOwoJCQkJCWlmKHN0cmNtcF9ub2RlLT5mYWlsX2FjdGlvbnMpIHsKCQkJCQkJY29uc3Qgc2l6ZV90IG1heF9sZW4gPSBNSU4oc3RyY21wX25vZGUtPnN0cmluZ19sZW5ndGgsIHRleHRfZW5kLXRleHQpOwoJCQkJCQkvKiB3ZSBkb24ndCB1c2Ugc3RybmNtcCwgYmVjYXVzZSB3ZSBuZWVkIHRoZSBleGFjdCBtYXRjaC1mYWlsIHBvaW50ICovCgkJCQkJCWZvcihpPTA7aSA8IG1heF9sZW47aSsrKSB7CgkJCQkJCQlpZih0ZXh0W2ldICE9IHN0cmNtcF9ub2RlLT5zdHJpbmdbaV0pIHsKCQkJCQkJCQlyZXR1cm4gRkFJTF9BQ1RJT04oIHN0cmNtcF9ub2RlLT5mYWlsX2FjdGlvbnNbaV0gKTsKCQkJCQkJCX0KCQkJCQkJfQoJCQkJCQlpZihtYXhfbGVuIDwgc3RyY21wX25vZGUtPnN0cmluZ19sZW5ndGgpIHsKCQkJCQkJCS8qIGZhaWxlZCwgYmVjYXVzZSB0ZXh0IHdhcyBzaG9ydGVyICovCgkJCQkJCQlyZXR1cm4gRkFJTF9BQ1RJT04oIHN0cmNtcF9ub2RlLT5mYWlsX2FjdGlvbnNbbWF4X2xlbl0gKTsKCQkJCQkJfQoJCQkJCX0KCQkJCQllbHNlIHsKCQkJCQkJLyogbm8gZmFpbF9hY3Rpb25zIGNvbXB1dGVkLCBzb21lIHNob3J0Y3V0cyBwb3NzaWJsZSBvbiBjb21wYXJlICovCgkJCQkJCWlmKCh0ZXh0X2VuZCAtIHRleHQgPCBzdHJjbXBfbm9kZS0+c3RyaW5nX2xlbmd0aCkgfHwKCQkJCQkJCQlzdHJuY21wKChjb25zdCBjaGFyKil0ZXh0LCAoY29uc3QgY2hhciopc3RyY21wX25vZGUtPnN0cmluZywgc3RyY21wX25vZGUtPnN0cmluZ19sZW5ndGgpKSB7CgoJCQkJCQkJcmV0dXJuIEZBSUxfQUNUSU9OKCBOVUxMICk7CgkJCQkJCX0KCQkJCQl9CgkJCQkJLyogbWF0Y2ggc3VjY2Vzc2Z1bCAqLwoJCQkJCW5vZGUgPSBzdHJjbXBfbm9kZS0+Y2hpbGQ7CgkJCQkJdGV4dCArPSBzdHJjbXBfbm9kZS0+c3RyaW5nX2xlbmd0aDsKCQkJCQlicmVhazsKCQkJCX0KCQkJY2FzZSBPUF9HUk9VUF9TVEFSVDoKCQkJCXsKCQkJCQljb25zdCBzdHJ1Y3QgdHJpZV9ub2RlX2dyb3VwX3N0YXJ0KiBncm91cF9zdGFydF9ub2RlID0gY29udGFpbmVyX29mX2NvbnN0KG5vZGUsIGNvbnN0IHN0cnVjdCB0cmllX25vZGVfZ3JvdXBfc3RhcnQsIG5vZGUpOwoJCQkJCS8qIFRPRE86IGltcGxlbWVudCAqLwoJCQkJCWJyZWFrOwoJCQkJfQoJCQljYXNlIE9QX0dST1VQX0VORDoKCQkJCXsJCQkJCQoJCQkJCWNvbnN0IHN0cnVjdCB0cmllX25vZGVfZ3JvdXBfZW5kKiBncm91cF9lbmRfbm9kZSA9IGNvbnRhaW5lcl9vZl9jb25zdChub2RlLCBjb25zdCBzdHJ1Y3QgdHJpZV9ub2RlX2dyb3VwX2VuZCwgbm9kZSk7CgkJCQkJLyogVE9ETzogaW1wbGVtZW50ICovCgkJCQkJYnJlYWs7CgkJCQl9CgkJCWNhc2UgT1BfTUFUQ0hfT0s6CgkJCQl7CgkJCQkJcmV0dXJuIE1BVENIX09LOwoJCQkJfQoJCX0KCX0KCS8qIGlmIGZhaWxfYWN0aW9uIHdhcyBOVUxMLCBvciB0ZXh0IGVuZGVkKi8KCXJldHVybiBNQVRDSF9GQUlMRUQ7Cn0KCiNlbmRpZgoK