LyoKICogQ29weXJpZ2h0IDIwMTYgQWR2YW5jZWQgTWljcm8gRGV2aWNlcywgSW5jLgogKgogKiBQZXJtaXNzaW9uIGlzIGhlcmVieSBncmFudGVkLCBmcmVlIG9mIGNoYXJnZSwgdG8gYW55IHBlcnNvbiBvYnRhaW5pbmcgYQogKiBjb3B5IG9mIHRoaXMgc29mdHdhcmUgYW5kIGFzc29jaWF0ZWQgZG9jdW1lbnRhdGlvbiBmaWxlcyAodGhlICJTb2Z0d2FyZSIpLAogKiB0byBkZWFsIGluIHRoZSBTb2Z0d2FyZSB3aXRob3V0IHJlc3RyaWN0aW9uLCBpbmNsdWRpbmcgd2l0aG91dCBsaW1pdGF0aW9uCiAqIHRoZSByaWdodHMgdG8gdXNlLCBjb3B5LCBtb2RpZnksIG1lcmdlLCBwdWJsaXNoLCBkaXN0cmlidXRlLCBzdWJsaWNlbnNlLAogKiBhbmQvb3Igc2VsbCBjb3BpZXMgb2YgdGhlIFNvZnR3YXJlLCBhbmQgdG8gcGVybWl0IHBlcnNvbnMgdG8gd2hvbSB0aGUKICogU29mdHdhcmUgaXMgZnVybmlzaGVkIHRvIGRvIHNvLCBzdWJqZWN0IHRvIHRoZSBmb2xsb3dpbmcgY29uZGl0aW9uczoKICoKICogVGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgYW5kIHRoaXMgcGVybWlzc2lvbiBub3RpY2Ugc2hhbGwgYmUgaW5jbHVkZWQgaW4KICogYWxsIGNvcGllcyBvciBzdWJzdGFudGlhbCBwb3J0aW9ucyBvZiB0aGUgU29mdHdhcmUuCiAqCiAqIFRIRSBTT0ZUV0FSRSBJUyBQUk9WSURFRCAiQVMgSVMiLCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSBLSU5ELCBFWFBSRVNTIE9SCiAqIElNUExJRUQsIElOQ0xVRElORyBCVVQgTk9UIExJTUlURUQgVE8gVEhFIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZLAogKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBTkQgTk9OSU5GUklOR0VNRU5ULiAgSU4gTk8gRVZFTlQgU0hBTEwKICogVEhFIENPUFlSSUdIVCBIT0xERVIoUykgT1IgQVVUSE9SKFMpIEJFIExJQUJMRSBGT1IgQU5ZIENMQUlNLCBEQU1BR0VTIE9SCiAqIE9USEVSIExJQUJJTElUWSwgV0hFVEhFUiBJTiBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsIFRPUlQgT1IgT1RIRVJXSVNFLAogKiBBUklTSU5HIEZST00sIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFNPRlRXQVJFIE9SIFRIRSBVU0UgT1IKICogT1RIRVIgREVBTElOR1MgSU4gVEhFIFNPRlRXQVJFLgogKgogKiBBdXRob3JzOiBBTUQKICoKICovCgojaW5jbHVkZSAiZG1fc2VydmljZXMuaCIKI2luY2x1ZGUgImRtX2hlbHBlcnMuaCIKI2luY2x1ZGUgImNvcmVfdHlwZXMuaCIKI2luY2x1ZGUgInJlc291cmNlLmgiCiNpbmNsdWRlICJkY2UvZGNlX2h3c2VxLmgiCiNpbmNsdWRlICJkY2UxMTAvZGNlMTEwX2h3X3NlcXVlbmNlci5oIgojaW5jbHVkZSAiZGNuMjFfaHdzZXEuaCIKI2luY2x1ZGUgInZtaWQuaCIKI2luY2x1ZGUgInJlZ19oZWxwZXIuaCIKI2luY2x1ZGUgImh3L2Nsa19tZ3IuaCIKI2luY2x1ZGUgImRjX2RtdWJfc3J2LmgiCiNpbmNsdWRlICJhYm0uaCIKCgojZGVmaW5lIERDX0xPR0dFUl9JTklUKGxvZ2dlcikKCiNkZWZpbmUgQ1RYIFwKCWh3cy0+Y3R4CiNkZWZpbmUgUkVHKHJlZylcCglod3MtPnJlZ3MtPnJlZwoKI3VuZGVmIEZOCiNkZWZpbmUgRk4ocmVnX25hbWUsIGZpZWxkX25hbWUpIFwKCWh3cy0+c2hpZnRzLT5maWVsZF9uYW1lLCBod3MtPm1hc2tzLT5maWVsZF9uYW1lCgovKiBUZW1wb3JhcnkgcmVhZCBzZXR0aW5ncywgZnV0dXJlIHdpbGwgZ2V0IHZhbHVlcyBmcm9tIGttZCBkaXJlY3RseSAqLwpzdGF0aWMgdm9pZCBtbWh1Yl91cGRhdGVfcGFnZV90YWJsZV9jb25maWcoc3RydWN0IGRjbl9odWJidWJfcGh5c19hZGRyX2NvbmZpZyAqY29uZmlnLAoJCXN0cnVjdCBkY2VfaHdzZXEgKmh3cykKewoJdWludDMyX3QgcGFnZV90YWJsZV9iYXNlX2hpOwoJdWludDMyX3QgcGFnZV90YWJsZV9iYXNlX2xvOwoKCVJFR19HRVQoVk1fQ09OVEVYVDBfUEFHRV9UQUJMRV9CQVNFX0FERFJfSEkzMiwKCQkJUEFHRV9ESVJFQ1RPUllfRU5UUllfSEkzMiwgJnBhZ2VfdGFibGVfYmFzZV9oaSk7CglSRUdfR0VUKFZNX0NPTlRFWFQwX1BBR0VfVEFCTEVfQkFTRV9BRERSX0xPMzIsCgkJCVBBR0VfRElSRUNUT1JZX0VOVFJZX0xPMzIsICZwYWdlX3RhYmxlX2Jhc2VfbG8pOwoKCWNvbmZpZy0+Z2FydF9jb25maWcucGFnZV90YWJsZV9iYXNlX2FkZHIgPSAoKHVpbnQ2NF90KXBhZ2VfdGFibGVfYmFzZV9oaSA8PCAzMikgfCBwYWdlX3RhYmxlX2Jhc2VfbG87Cgp9CgppbnQgZGNuMjFfaW5pdF9zeXNfY3R4KHN0cnVjdCBkY2VfaHdzZXEgKmh3cywgc3RydWN0IGRjICpkYywgc3RydWN0IGRjX3BoeV9hZGRyX3NwYWNlX2NvbmZpZyAqcGFfY29uZmlnKQp7CglzdHJ1Y3QgZGNuX2h1YmJ1Yl9waHlzX2FkZHJfY29uZmlnIGNvbmZpZzsKCgljb25maWcuc3lzdGVtX2FwZXJ0dXJlLmZiX3RvcCA9IHBhX2NvbmZpZy0+c3lzdGVtX2FwZXJ0dXJlLmZiX3RvcDsKCWNvbmZpZy5zeXN0ZW1fYXBlcnR1cmUuZmJfb2Zmc2V0ID0gcGFfY29uZmlnLT5zeXN0ZW1fYXBlcnR1cmUuZmJfb2Zmc2V0OwoJY29uZmlnLnN5c3RlbV9hcGVydHVyZS5mYl9iYXNlID0gcGFfY29uZmlnLT5zeXN0ZW1fYXBlcnR1cmUuZmJfYmFzZTsKCWNvbmZpZy5zeXN0ZW1fYXBlcnR1cmUuYWdwX3RvcCA9IHBhX2NvbmZpZy0+c3lzdGVtX2FwZXJ0dXJlLmFncF90b3A7Cgljb25maWcuc3lzdGVtX2FwZXJ0dXJlLmFncF9ib3QgPSBwYV9jb25maWctPnN5c3RlbV9hcGVydHVyZS5hZ3BfYm90OwoJY29uZmlnLnN5c3RlbV9hcGVydHVyZS5hZ3BfYmFzZSA9IHBhX2NvbmZpZy0+c3lzdGVtX2FwZXJ0dXJlLmFncF9iYXNlOwoJY29uZmlnLmdhcnRfY29uZmlnLnBhZ2VfdGFibGVfc3RhcnRfYWRkciA9IHBhX2NvbmZpZy0+Z2FydF9jb25maWcucGFnZV90YWJsZV9zdGFydF9hZGRyOwoJY29uZmlnLmdhcnRfY29uZmlnLnBhZ2VfdGFibGVfZW5kX2FkZHIgPSBwYV9jb25maWctPmdhcnRfY29uZmlnLnBhZ2VfdGFibGVfZW5kX2FkZHI7Cgljb25maWcuZ2FydF9jb25maWcucGFnZV90YWJsZV9iYXNlX2FkZHIgPSBwYV9jb25maWctPmdhcnRfY29uZmlnLnBhZ2VfdGFibGVfYmFzZV9hZGRyOwoKCW1taHViX3VwZGF0ZV9wYWdlX3RhYmxlX2NvbmZpZygmY29uZmlnLCBod3MpOwoKCXJldHVybiBkYy0+cmVzX3Bvb2wtPmh1YmJ1Yi0+ZnVuY3MtPmluaXRfZGNodWJfc3lzX2N0eChkYy0+cmVzX3Bvb2wtPmh1YmJ1YiwgJmNvbmZpZyk7Cn0KCi8vIHdvcmsgYXJvdW5kIGZvciBSZW5vaXIgczBpMywgaWYgcmVnaXN0ZXIgaXMgcHJvZ3JhbW1lZCwgYnlwYXNzIGdvbGRlbiBpbml0LgoKYm9vbCBkY24yMV9zMGkzX2dvbGRlbl9pbml0X3dhKHN0cnVjdCBkYyAqZGMpCnsKCXN0cnVjdCBkY2VfaHdzZXEgKmh3cyA9IGRjLT5od3NlcTsKCXVpbnQzMl90IHZhbHVlID0gMDsKCgl2YWx1ZSA9IFJFR19SRUFEKE1JQ1JPU0VDT05EX1RJTUVfQkFTRV9ESVYpOwoKCXJldHVybiB2YWx1ZSAhPSAweDAwMTIwNDY0Owp9Cgp2b2lkIGRjbjIxX2V4aXRfb3B0aW1pemVkX3B3cl9zdGF0ZSgKCQljb25zdCBzdHJ1Y3QgZGMgKmRjLAoJCXN0cnVjdCBkY19zdGF0ZSAqY29udGV4dCkKewoJZGMtPmNsa19tZ3ItPmZ1bmNzLT51cGRhdGVfY2xvY2tzKAoJCQlkYy0+Y2xrX21nciwKCQkJY29udGV4dCwKCQkJZmFsc2UpOwp9Cgp2b2lkIGRjbjIxX29wdGltaXplX3B3cl9zdGF0ZSgKCQljb25zdCBzdHJ1Y3QgZGMgKmRjLAoJCXN0cnVjdCBkY19zdGF0ZSAqY29udGV4dCkKewoJZGMtPmNsa19tZ3ItPmZ1bmNzLT51cGRhdGVfY2xvY2tzKAoJCQlkYy0+Y2xrX21nciwKCQkJY29udGV4dCwKCQkJdHJ1ZSk7Cn0KCi8qIElmIHVzZXIgaG90cGx1ZyBhIEhETUkgbW9uaXRvciB3aGlsZSBpbiBtb25pdG9yIG9mZiwKICogT1Mgd2lsbCBkbyBhIG1vZGUgc2V0ICh3aXRoIG91dHB1dCB0aW1pbmcpIGJ1dCBrZWVwIG91dHB1dCBvZmYuCiAqIEluIHRoaXMgY2FzZSBEQUwgd2lsbCBhc2sgdmJpb3MgdG8gcG93ZXIgdXAgdGhlIHBsbCBpbiB0aGUgUEhZLgogKiBJZiB1c2VyIHVucGx1ZyB0aGUgbW9uaXRvciAod2hpbGUgd2UgYXJlIG9uIG1vbml0b3Igb2ZmKSBvcgogKiBzeXN0ZW0gYXR0ZW1wdCB0byBlbnRlciBtb2Rlcm4gc3RhbmRieSAod2hpY2ggd2Ugd2lsbCBkaXNhYmxlIFBMTCksCiAqIFBIWSB3aWxsIGhhbmcgb24gdGhlIG5leHQgbW9kZSBzZXQgYXR0ZW1wdC4KICogaWYgZW5hYmxlIFBMTCBmb2xsb3cgYnkgZGlzYWJsZSBQTEwgKHdpdGhvdXQgZXhlY3V0aW5nIGxhbmUgZW5hYmxlL2Rpc2FibGUpLAogKiBSRFBDU19QSFlfRFBfTVBMTEJfU1RBVEUgcmVtYWlucyAxLAogKiB3aGljaCBpbmRpY2F0ZSB0aGF0IFBMTCBkaXNhYmxlIGF0dGVtcHQgYWN0dWFsbHkgZGlkbpJ0IGdvIHRocm91Z2guCiAqIEFzIGEgd29ya2Fyb3VuZCwgaW5zZXJ0IFBIWSBsYW5lIGVuYWJsZS9kaXNhYmxlIGJlZm9yZSBQTEwgZGlzYWJsZS4KICovCnZvaWQgZGNuMjFfUExBVF81ODg1Nl93YShzdHJ1Y3QgZGNfc3RhdGUgKmNvbnRleHQsIHN0cnVjdCBwaXBlX2N0eCAqcGlwZV9jdHgpCnsKCWlmICghcGlwZV9jdHgtPnN0cmVhbS0+ZHBtc19vZmYpCgkJcmV0dXJuOwoKCXBpcGVfY3R4LT5zdHJlYW0tPmRwbXNfb2ZmID0gZmFsc2U7Cgljb3JlX2xpbmtfZW5hYmxlX3N0cmVhbShjb250ZXh0LCBwaXBlX2N0eCk7Cgljb3JlX2xpbmtfZGlzYWJsZV9zdHJlYW0ocGlwZV9jdHgpOwoJcGlwZV9jdHgtPnN0cmVhbS0+ZHBtc19vZmYgPSB0cnVlOwp9CgpzdGF0aWMgYm9vbCBkbXViX2FibV9zZXRfcGlwZShzdHJ1Y3QgYWJtICphYm0sIHVpbnQzMl90IG90Z19pbnN0LCB1aW50MzJfdCBvcHRpb24sIHVpbnQzMl90IHBhbmVsX2luc3QpCnsKCXVuaW9uIGRtdWJfcmJfY21kIGNtZDsKCXN0cnVjdCBkY19jb250ZXh0ICpkYyA9IGFibS0+Y3R4OwoJdWludDMyX3QgcmFtcGluZ19ib3VuZGFyeSA9IDB4RkZGRjsKCgljbWQuYWJtX3NldF9waXBlLmhlYWRlci50eXBlID0gRE1VQl9DTURfX0FCTTsKCWNtZC5hYm1fc2V0X3BpcGUuaGVhZGVyLnN1Yl90eXBlID0gRE1VQl9DTURfX0FCTV9TRVRfUElQRTsKCWNtZC5hYm1fc2V0X3BpcGUuYWJtX3NldF9waXBlX2RhdGEub3RnX2luc3QgPSBvdGdfaW5zdDsKCWNtZC5hYm1fc2V0X3BpcGUuYWJtX3NldF9waXBlX2RhdGEuc2V0X3BpcGVfb3B0aW9uID0gb3B0aW9uOwoJY21kLmFibV9zZXRfcGlwZS5hYm1fc2V0X3BpcGVfZGF0YS5wYW5lbF9pbnN0ID0gcGFuZWxfaW5zdDsKCWNtZC5hYm1fc2V0X3BpcGUuYWJtX3NldF9waXBlX2RhdGEucmFtcGluZ19ib3VuZGFyeSA9IHJhbXBpbmdfYm91bmRhcnk7CgljbWQuYWJtX3NldF9waXBlLmhlYWRlci5wYXlsb2FkX2J5dGVzID0gc2l6ZW9mKHN0cnVjdCBkbXViX2NtZF9hYm1fc2V0X3BpcGVfZGF0YSk7CgoJZGNfZG11Yl9zcnZfY21kX3F1ZXVlKGRjLT5kbXViX3NydiwgJmNtZCk7CglkY19kbXViX3Nydl9jbWRfZXhlY3V0ZShkYy0+ZG11Yl9zcnYpOwoJZGNfZG11Yl9zcnZfd2FpdF9pZGxlKGRjLT5kbXViX3Nydik7CgoJcmV0dXJuIHRydWU7Cn0KCnZvaWQgZGNuMjFfc2V0X2FibV9pbW1lZGlhdGVfZGlzYWJsZShzdHJ1Y3QgcGlwZV9jdHggKnBpcGVfY3R4KQp7CglzdHJ1Y3QgYWJtICphYm0gPSBwaXBlX2N0eC0+c3RyZWFtX3Jlcy5hYm07Cgl1aW50MzJfdCBvdGdfaW5zdCA9IHBpcGVfY3R4LT5zdHJlYW1fcmVzLnRnLT5pbnN0OwoJc3RydWN0IHBhbmVsX2NudGwgKnBhbmVsX2NudGwgPSBwaXBlX2N0eC0+c3RyZWFtLT5saW5rLT5wYW5lbF9jbnRsOwoKCXN0cnVjdCBkbWN1ICpkbWN1ID0gcGlwZV9jdHgtPnN0cmVhbS0+Y3R4LT5kYy0+cmVzX3Bvb2wtPmRtY3U7CgoJaWYgKGRtY3UpIHsKCQlkY2UxMTBfc2V0X2FibV9pbW1lZGlhdGVfZGlzYWJsZShwaXBlX2N0eCk7CgkJcmV0dXJuOwoJfQoKCWlmIChhYm0gJiYgcGFuZWxfY250bCkKCQlkbXViX2FibV9zZXRfcGlwZShhYm0sIG90Z19pbnN0LCBTRVRfQUJNX1BJUEVfSU1NRURJQVRFTFlfRElTQUJMRSwKCQkJCXBhbmVsX2NudGwtPmluc3QpOwp9Cgp2b2lkIGRjbjIxX3NldF9waXBlKHN0cnVjdCBwaXBlX2N0eCAqcGlwZV9jdHgpCnsKCXN0cnVjdCBhYm0gKmFibSA9IHBpcGVfY3R4LT5zdHJlYW1fcmVzLmFibTsKCXVpbnQzMl90IG90Z19pbnN0ID0gcGlwZV9jdHgtPnN0cmVhbV9yZXMudGctPmluc3Q7CglzdHJ1Y3QgcGFuZWxfY250bCAqcGFuZWxfY250bCA9IHBpcGVfY3R4LT5zdHJlYW0tPmxpbmstPnBhbmVsX2NudGw7CglzdHJ1Y3QgZG1jdSAqZG1jdSA9IHBpcGVfY3R4LT5zdHJlYW0tPmN0eC0+ZGMtPnJlc19wb29sLT5kbWN1OwoKCWlmIChkbWN1KSB7CgkJZGNlMTEwX3NldF9waXBlKHBpcGVfY3R4KTsKCQlyZXR1cm47Cgl9CgoJaWYgKGFibSAmJiBwYW5lbF9jbnRsKQoJCWRtdWJfYWJtX3NldF9waXBlKGFibSwgb3RnX2luc3QsIFNFVF9BQk1fUElQRV9OT1JNQUwsIHBhbmVsX2NudGwtPmluc3QpOwp9Cgpib29sIGRjbjIxX3NldF9iYWNrbGlnaHRfbGV2ZWwoc3RydWN0IHBpcGVfY3R4ICpwaXBlX2N0eCwKCQl1aW50MzJfdCBiYWNrbGlnaHRfcHdtX3UxNl8xNiwKCQl1aW50MzJfdCBmcmFtZV9yYW1wKQp7Cgl1bmlvbiBkbXViX3JiX2NtZCBjbWQ7CglzdHJ1Y3QgZGNfY29udGV4dCAqZGMgPSBwaXBlX2N0eC0+c3RyZWFtLT5jdHg7CglzdHJ1Y3QgYWJtICphYm0gPSBwaXBlX2N0eC0+c3RyZWFtX3Jlcy5hYm07Cgl1aW50MzJfdCBvdGdfaW5zdCA9IHBpcGVfY3R4LT5zdHJlYW1fcmVzLnRnLT5pbnN0OwoJc3RydWN0IHBhbmVsX2NudGwgKnBhbmVsX2NudGwgPSBwaXBlX2N0eC0+c3RyZWFtLT5saW5rLT5wYW5lbF9jbnRsOwoKCWlmIChkYy0+ZGMtPnJlc19wb29sLT5kbWN1KSB7CgkJZGNlMTEwX3NldF9iYWNrbGlnaHRfbGV2ZWwocGlwZV9jdHgsIGJhY2tsaWdodF9wd21fdTE2XzE2LCBmcmFtZV9yYW1wKTsKCQlyZXR1cm4gdHJ1ZTsKCX0KCglpZiAoYWJtICYmIHBhbmVsX2NudGwpCgkJZG11Yl9hYm1fc2V0X3BpcGUoYWJtLCBvdGdfaW5zdCwgU0VUX0FCTV9QSVBFX05PUk1BTCwgcGFuZWxfY250bC0+aW5zdCk7CgoJY21kLmFibV9zZXRfYmFja2xpZ2h0LmhlYWRlci50eXBlID0gRE1VQl9DTURfX0FCTTsKCWNtZC5hYm1fc2V0X2JhY2tsaWdodC5oZWFkZXIuc3ViX3R5cGUgPSBETVVCX0NNRF9fQUJNX1NFVF9CQUNLTElHSFQ7CgljbWQuYWJtX3NldF9iYWNrbGlnaHQuYWJtX3NldF9iYWNrbGlnaHRfZGF0YS5mcmFtZV9yYW1wID0gZnJhbWVfcmFtcDsKCWNtZC5hYm1fc2V0X2JhY2tsaWdodC5hYm1fc2V0X2JhY2tsaWdodF9kYXRhLmJhY2tsaWdodF91c2VyX2xldmVsID0gYmFja2xpZ2h0X3B3bV91MTZfMTY7CgljbWQuYWJtX3NldF9iYWNrbGlnaHQuaGVhZGVyLnBheWxvYWRfYnl0ZXMgPSBzaXplb2Yoc3RydWN0IGRtdWJfY21kX2FibV9zZXRfYmFja2xpZ2h0X2RhdGEpOwoKCWRjX2RtdWJfc3J2X2NtZF9xdWV1ZShkYy0+ZG11Yl9zcnYsICZjbWQpOwoJZGNfZG11Yl9zcnZfY21kX2V4ZWN1dGUoZGMtPmRtdWJfc3J2KTsKCWRjX2RtdWJfc3J2X3dhaXRfaWRsZShkYy0+ZG11Yl9zcnYpOwoKCXJldHVybiB0cnVlOwp9Cgo=