LyoKICogQ29weXJpZ2h0IChjKSAyMDExLTIwMTcgVGhlIExpbnV4IEZvdW5kYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqCiAqIFByZXZpb3VzbHkgbGljZW5zZWQgdW5kZXIgdGhlIElTQyBsaWNlbnNlIGJ5IFF1YWxjb21tIEF0aGVyb3MsIEluYy4KICoKICoKICogUGVybWlzc2lvbiB0byB1c2UsIGNvcHksIG1vZGlmeSwgYW5kL29yIGRpc3RyaWJ1dGUgdGhpcyBzb2Z0d2FyZSBmb3IKICogYW55IHB1cnBvc2Ugd2l0aCBvciB3aXRob3V0IGZlZSBpcyBoZXJlYnkgZ3JhbnRlZCwgcHJvdmlkZWQgdGhhdCB0aGUKICogYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBhcHBlYXIgaW4gYWxsCiAqIGNvcGllcy4KICoKICogVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEICJBUyBJUyIgQU5EIFRIRSBBVVRIT1IgRElTQ0xBSU1TIEFMTAogKiBXQVJSQU5USUVTIFdJVEggUkVHQVJEIFRPIFRISVMgU09GVFdBUkUgSU5DTFVESU5HIEFMTCBJTVBMSUVECiAqIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTLiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUKICogQVVUSE9SIEJFIExJQUJMRSBGT1IgQU5ZIFNQRUNJQUwsIERJUkVDVCwgSU5ESVJFQ1QsIE9SIENPTlNFUVVFTlRJQUwKICogREFNQUdFUyBPUiBBTlkgREFNQUdFUyBXSEFUU09FVkVSIFJFU1VMVElORyBGUk9NIExPU1MgT0YgVVNFLCBEQVRBIE9SCiAqIFBST0ZJVFMsIFdIRVRIRVIgSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNULCBORUdMSUdFTkNFIE9SIE9USEVSCiAqIFRPUlRJT1VTIEFDVElPTiwgQVJJU0lORyBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBVU0UgT1IKICogUEVSRk9STUFOQ0UgT0YgVEhJUyBTT0ZUV0FSRS4KICovCgovKgogKiBUaGlzIGZpbGUgd2FzIG9yaWdpbmFsbHkgZGlzdHJpYnV0ZWQgYnkgUXVhbGNvbW0gQXRoZXJvcywgSW5jLgogKiB1bmRlciBwcm9wcmlldGFyeSB0ZXJtcyBiZWZvcmUgQ29weXJpZ2h0IG93bmVyc2hpcCB3YXMgYXNzaWduZWQKICogdG8gdGhlIExpbnV4IEZvdW5kYXRpb24uCiAqLwoKLyoqCiAqIFxmaWxlIGxpbV9zZW5kX21hbmFnZW1lbnRfZnJhbWVzLmMKICoKICogXGJyaWVmIENvZGUgZm9yIHByZXBhcmluZyBhbmQgc2VuZGluZyA4MDIuMTEgTWFuYWdlbWVudCBmcmFtZXMKICoKICoKICovCgojaW5jbHVkZSAic2lyX2FwaS5oIgojaW5jbHVkZSAiYW5pX2dsb2JhbC5oIgojaW5jbHVkZSAic2lyX21hY19wcm90X2RlZi5oIgojaW5jbHVkZSAiY2ZnX2FwaS5oIgojaW5jbHVkZSAidXRpbHNfYXBpLmgiCiNpbmNsdWRlICJsaW1fdHlwZXMuaCIKI2luY2x1ZGUgImxpbV91dGlscy5oIgojaW5jbHVkZSAibGltX3NlY3VyaXR5X3V0aWxzLmgiCiNpbmNsdWRlICJsaW1fcHJvcF9leHRzX3V0aWxzLmgiCiNpbmNsdWRlICJkb3QxMWYuaCIKI2luY2x1ZGUgImxpbV9zdGFfaGFzaF9hcGkuaCIKI2luY2x1ZGUgInNjaF9hcGkuaCIKI2luY2x1ZGUgImxpbV9zZW5kX21lc3NhZ2VzLmgiCiNpbmNsdWRlICJsaW1fYXNzb2NfdXRpbHMuaCIKI2luY2x1ZGUgImxpbV9mdC5oIgojaWZkZWYgV0xBTl9GRUFUVVJFXzExVwojaW5jbHVkZSAid25pX2NmZy5oIgojZW5kaWYKCiNpbmNsdWRlICJsaW1fZnRfZGVmcy5oIgojaW5jbHVkZSAibGltX3Nlc3Npb24uaCIKI2luY2x1ZGUgInFkZl90eXBlcy5oIgojaW5jbHVkZSAicWRmX3RyYWNlLmgiCiNpbmNsdWRlICJjZHNfdXRpbHMuaCIKI2luY2x1ZGUgInNtZV90cmFjZS5oIgojaW5jbHVkZSAicnJtX2FwaS5oIgoKI2luY2x1ZGUgIndtYV90eXBlcy5oIgojaW5jbHVkZSA8Y2RwX3R4cnhfY21uLmg+CiNpbmNsdWRlIDxjZHBfdHhyeF9wZWVyX29wcy5oPgoKLyoqCiAqCiAqIFxicmllZiBUaGlzIGZ1bmN0aW9uIGlzIGNhbGxlZCB0byBhZGQgdGhlIHNlcXVlbmNlIG51bWJlciB0byB0aGUKICogbWFuYWdlbWVudCBmcmFtZXMKICoKICogXHBhcmFtICBwTWFjIFBvaW50ZXIgdG8gR2xvYmFsIE1BQyBzdHJ1Y3R1cmUKICoKICogXHBhcmFtICBwTWFjSGRyIFBvaW50ZXIgdG8gTUFDIG1hbmFnZW1lbnQgaGVhZGVyCiAqCiAqIFRoZSBwTWFjSGRyIGFyZ3VtZW50IHBvaW50cyB0byB0aGUgTUFDIG1hbmFnZW1lbnQgaGVhZGVyLiBUaGUKICogc2VxdWVuY2UgbnVtYmVyIHN0b3JlZCBpbiB0aGUgcE1hYyBzdHJ1Y3R1cmUgd2lsbCBiZSBpbmNyZW1lbnRlZAogKiBhbmQgdXBkYXRlZCB0byB0aGUgTUFDIG1hbmFnZW1lbnQgaGVhZGVyLiBUaGUgc3RhcnQgc2VxdWVuY2UKICogbnVtYmVyIGlzIFdMQU5fSE9TVF9TRVFfTlVNX01JTiBhbmQgdGhlIGVuZCB2YWx1ZSBpcwogKiBXTEFOX0hPU1RfU0VRX05VTV9NQVguIEFmdGVyIHJlYWNoaW5nIHRoZSBNQVggdmFsdWUsIHRoZSBzZXF1ZW5jZQogKiBudW1iZXIgd2lsbCByb2xsIG92ZXIuCiAqCiAqLwpzdGF0aWMgdm9pZCBsaW1fYWRkX21nbXRfc2VxX251bSh0cEFuaVNpckdsb2JhbCBwTWFjLCB0cFNpck1hY01nbXRIZHIgcE1hY0hkcikKewoJaWYgKHBNYWMtPm1nbXRTZXFOdW0gPj0gV0xBTl9IT1NUX1NFUV9OVU1fTUFYKSB7CgkJcE1hYy0+bWdtdFNlcU51bSA9IFdMQU5fSE9TVF9TRVFfTlVNX01JTiAtIDE7Cgl9CgoJcE1hYy0+bWdtdFNlcU51bSsrOwoKCXBNYWNIZHItPnNlcUNvbnRyb2wuc2VxTnVtTG8gPSAocE1hYy0+bWdtdFNlcU51bSAmIExPV19TRVFfTlVNX01BU0spOwoJcE1hY0hkci0+c2VxQ29udHJvbC5zZXFOdW1IaSA9CgkJKChwTWFjLT5tZ210U2VxTnVtICYgSElHSF9TRVFfTlVNX01BU0spID4+IEhJR0hfU0VRX05VTV9PRkZTRVQpOwp9CgovKioKICoKICogXGJyaWVmIFRoaXMgZnVuY3Rpb24gaXMgY2FsbGVkIGJlZm9yZSBzZW5kaW5nIGEgcDJwIGFjdGlvbiBmcmFtZQogKiBpbm9yZGVyIHRvIGFkZCBzZXF1ZW5jZSBudW1iZXJzIHRvIGFjdGlvbiBwYWNrZXRzCiAqCiAqIFxwYXJhbSAgcE1hYyBQb2ludGVyIHRvIEdsb2JhbCBNQUMgc3RydWN0dXJlCiAqCiAqIFxwYXJhbSBwQkQgUG9pbnRlciB0byB0aGUgZnJhbWUgYnVmZmVyIHRoYXQgbmVlZHMgdG8gYmUgcG9wdWxhdGUKICoKICogVGhlIHBNYWNIZHIgYXJndW1lbnQgcG9pbnRzIHRvIHRoZSBNQUMgbWFuYWdlbWVudCBoZWFkZXIuIFRoZQogKiBzZXF1ZW5jZSBudW1iZXIgc3RvcmVkIGluIHRoZSBwTWFjIHN0cnVjdHVyZSB3aWxsIGJlIGluY3JlbWVudGVkCiAqIGFuZCB1cGRhdGVkIHRvIHRoZSBNQUMgbWFuYWdlbWVudCBoZWFkZXIuIFRoZSBzdGFydCBzZXF1ZW5jZQogKiBudW1iZXIgaXMgV0xBTl9IT1NUX1NFUV9OVU1fTUlOIGFuZCB0aGUgZW5kIHZhbHVlIGlzCiAqIFdMQU5fSE9TVF9TRVFfTlVNX01BWC4gQWZ0ZXIgcmVhY2hpbmcgdGhlIE1BWCB2YWx1ZSwgdGhlIHNlcXVlbmNlCiAqIG51bWJlciB3aWxsIHJvbGwgb3Zlci4KICoKICovCnZvaWQgbGltX3BvcHVsYXRlX3AycF9tYWNfaGVhZGVyKHRwQW5pU2lyR2xvYmFsIHBNYWMsIHVpbnQ4X3QgKnBCRCkKewoJdHBTaXJNYWNNZ210SGRyIHBNYWNIZHI7CgoJLyogLyBQcmVwYXJlIE1BQyBtYW5hZ2VtZW50IGhlYWRlciAqLwoJcE1hY0hkciA9ICh0cFNpck1hY01nbXRIZHIpIChwQkQpOwoKCS8qIFByZXBhcmUgc2VxdWVuY2UgbnVtYmVyICovCglsaW1fYWRkX21nbXRfc2VxX251bShwTWFjLCBwTWFjSGRyKTsKCXBlX2RlYnVnKCJzZXFOdW1Mbz0lZCwgc2VxTnVtSGk9JWQsIG1nbXRTZXFOdW09JWQiLAoJCXBNYWNIZHItPnNlcUNvbnRyb2wuc2VxTnVtTG8sCgkJcE1hY0hkci0+c2VxQ29udHJvbC5zZXFOdW1IaSwgcE1hYy0+bWdtdFNlcU51bSk7Cn0KCi8qKgogKiBsaW1fcG9wdWxhdGVfbWFjX2hlYWRlcigpIC0gRmlsbCBpbiA4MDIuMTEgaGVhZGVyIG9mIGZyYW1lCiAqCiAqIEBtYWNfY3R4OiBQb2ludGVyIHRvIEdsb2JhbCBNQUMgc3RydWN0dXJlCiAqIEBidWY6IFBvaW50ZXIgdG8gdGhlIGZyYW1lIGJ1ZmZlciB0aGF0IG5lZWRzIHRvIGJlIHBvcHVsYXRlCiAqIEB0eXBlOiA4MDIuMTEgVHlwZSBvZiB0aGUgZnJhbWUKICogQHN1Yl90eXBlOiA4MDIuMTEgU3VidHlwZSBvZiB0aGUgZnJhbWUKICogQHBlZXJfYWRkcjogZHN0IGFkZHJlc3MKICogQHNlbGZfbWFjX2FkZHI6IGxvY2FsIG1hYyBhZGRyZXNzCiAqCiAqIFRoaXMgZnVuY3Rpb24gaXMgY2FsbGVkIGJ5IHZhcmlvdXMgTElNIG1vZHVsZXMgdG8gcHJlcGFyZSB0aGUKICogODAyLjExIGZyYW1lIE1BQyBoZWFkZXIKICoKICogVGhlIGJ1ZiBhcmd1bWVudCBwb2ludHMgdG8gdGhlIGJlZ2lubmluZyBvZiB0aGUgZnJhbWUgYnVmZmVyIHRvCiAqIHdoaWNoIC0gYSkgVGhlIDgwMi4xMSBNQUMgaGVhZGVyIGlzIHNldCBiKSBGb2xsb3dpbmcgdGhpcyBNQUMgaGVhZGVyCiAqIHdpbGwgYmUgdGhlIE1HTVQgZnJhbWUgcGF5bG9hZCBUaGUgcGF5bG9hZCBpdHNlbGYgaXMgcG9wdWxhdGVkIGJ5IHRoZQogKiBjYWxsZXIgQVBJCiAqCiAqIFJldHVybjogTm9uZQogKi8KCnZvaWQgbGltX3BvcHVsYXRlX21hY19oZWFkZXIodHBBbmlTaXJHbG9iYWwgbWFjX2N0eCwgdWludDhfdCAqYnVmLAoJCXVpbnQ4X3QgdHlwZSwgdWludDhfdCBzdWJfdHlwZSwgdFNpck1hY0FkZHIgcGVlcl9hZGRyLAoJCXRTaXJNYWNBZGRyIHNlbGZfbWFjX2FkZHIpCnsKCXRwU2lyTWFjTWdtdEhkciBtYWNfaGRyOwoKCS8qIFByZXBhcmUgTUFDIG1hbmFnZW1lbnQgaGVhZGVyICovCgltYWNfaGRyID0gKHRwU2lyTWFjTWdtdEhkcikgKGJ1Zik7CgoJLyogUHJlcGFyZSBGQyAqLwoJbWFjX2hkci0+ZmMucHJvdFZlciA9IFNJUl9NQUNfUFJPVE9DT0xfVkVSU0lPTjsKCW1hY19oZHItPmZjLnR5cGUgPSB0eXBlOwoJbWFjX2hkci0+ZmMuc3ViVHlwZSA9IHN1Yl90eXBlOwoKCS8qIFByZXBhcmUgQWRkcmVzcyAxICovCglxZGZfbWVtX2NvcHkoKHVpbnQ4X3QgKikgbWFjX2hkci0+ZGEsCgkJICAgICAodWludDhfdCAqKSBwZWVyX2FkZHIsIHNpemVvZih0U2lyTWFjQWRkcikpOwoKCS8qIFByZXBhcmUgQWRkcmVzcyAyICovCglzaXJfY29weV9tYWNfYWRkcihtYWNfaGRyLT5zYSwgc2VsZl9tYWNfYWRkcik7CgoJLyogUHJlcGFyZSBBZGRyZXNzIDMgKi8KCXFkZl9tZW1fY29weSgodWludDhfdCAqKSBtYWNfaGRyLT5ic3NJZCwKCQkgICAgICh1aW50OF90ICopIHBlZXJfYWRkciwgc2l6ZW9mKHRTaXJNYWNBZGRyKSk7CgoJLyogUHJlcGFyZSBzZXF1ZW5jZSBudW1iZXIgKi8KCWxpbV9hZGRfbWdtdF9zZXFfbnVtKG1hY19jdHgsIG1hY19oZHIpOwoJcGVfZGVidWcoInNlcU51bUxvPSVkLCBzZXFOdW1IaT0lZCwgbWdtdFNlcU51bT0lZCIsCgkJbWFjX2hkci0+c2VxQ29udHJvbC5zZXFOdW1MbywKCQltYWNfaGRyLT5zZXFDb250cm9sLnNlcU51bUhpLCBtYWNfY3R4LT5tZ210U2VxTnVtKTsKfQoKLyoqCiAqIGxpbV9zZW5kX3Byb2JlX3JlcV9tZ210X2ZyYW1lKCkgLSBzZW5kIHByb2JlIHJlcXVlc3QgbWFuYWdlbWVudCBmcmFtZQogKiBAbWFjX2N0eDogUG9pbnRlciB0byBHbG9iYWwgTUFDIHN0cnVjdHVyZQogKiBAc3NpZDogU1NJRCB0byBiZSBzZW50IGluIFByb2JlIFJlcXVlc3QgZnJhbWUKICogQGJzc2lkOiBCU1NJRCB0byBiZSBzZW50IGluIFByb2JlIFJlcXVlc3QgZnJhbWUKICogQGNoYW5uZWw6IENoYW5uZWwgIyBvbiB3aGljaCB0aGUgUHJvYmUgUmVxdWVzdCBpcyBnb2luZyBvdXQKICogQHNlbGZfbWFjYWRkcjogc2VsZiBNQUMgYWRkcmVzcwogKiBAZG90MTFtb2RlOiBzZWxmIGRvdGxsbW9kZQogKiBAYWRkaXRpb25hbF9pZWxlbjogaWYgbm9uLXplcm8sIGluY2x1ZGUgYWRkaXRpb25hbF9pZSBpbiB0aGUgUHJvYmUgUmVxdWVzdAogKiAgICAgICAgICAgICAgICAgICBmcmFtZQogKiBAYWRkaXRpb25hbF9pZTogaWYgYWRkaXRpb25hbF9pZWxlbiBpcyBub24gemVybywgaW5jbHVkZSB0aGlzIGZpZWxkIGluIHRoZQogKiAgICAgICAgICAgICAgICBQcm9iZSBSZXF1ZXN0IGZyYW1lCiAqCiAqIFRoaXMgZnVuY3Rpb24gaXMgY2FsbGVkIGJ5IHZhcmlvdXMgTElNIG1vZHVsZXMgdG8gc2VuZCBQcm9iZSBSZXF1ZXN0IGZyYW1lCiAqIGR1cmluZyBhY3RpdmUgc2Nhbi9sZWFybiBwaGFzZS4KICogUHJvYmUgcmVxdWVzdCBpcyBzZW50IG91dCBpbiB0aGUgZm9sbG93aW5nIHNjZW5hcmlvczoKICogLS1oZWFydGJlYXQgZmFpbHVyZTogIHNlc3Npb24gbmVlZGVkCiAqIC0tam9pbiByZXE6ICAgICAgICAgICBzZXNzaW9uIG5lZWRlZAogKiAtLWZvcmVncm91bmQgc2NhbjogICAgbm8gc2Vzc2lvbgogKiAtLWJhY2tncm91bmQgc2NhbjogICAgbm8gc2Vzc2lvbgogKiAtLXNjaF9iZWFjb25fcHJvY2Vzc2luZzogIHRvIGdldCBFRENBIHBhcmFtZXRlcnM6ICBzZXNzaW9uIG5lZWRlZAogKgogKiBSZXR1cm46IHRTaXJSZXRTdGF0dXMgKGVTSVJfU1VDQ0VTUyBvbiBzdWNjZXNzIGFuZCBlcnJvciBjb2RlcyBvdGhlcndpc2UpCiAqLwp0U2lyUmV0U3RhdHVzCmxpbV9zZW5kX3Byb2JlX3JlcV9tZ210X2ZyYW1lKHRwQW5pU2lyR2xvYmFsIG1hY19jdHgsCgkJCSAgICAgIHRTaXJNYWNTU2lkICpzc2lkLAoJCQkgICAgICB0U2lyTWFjQWRkciBic3NpZCwKCQkJICAgICAgdWludDhfdCBjaGFubmVsLAoJCQkgICAgICB0U2lyTWFjQWRkciBzZWxmX21hY2FkZHIsCgkJCSAgICAgIHVpbnQzMl90IGRvdDExbW9kZSwKCQkJICAgICAgdWludDMyX3QgYWRkaXRpb25hbF9pZWxlbiwgdWludDhfdCAqYWRkaXRpb25hbF9pZSkKewoJdERvdDExZlByb2JlUmVxdWVzdCBwcjsKCXVpbnQzMl90IHN0YXR1cywgYnl0ZXMsIHBheWxvYWQ7Cgl1aW50OF90ICpmcmFtZTsKCXZvaWQgKnBhY2tldDsKCVFERl9TVEFUVVMgcWRmX3N0YXR1czsKCXRwUEVTZXNzaW9uIHBlc2Vzc2lvbjsKCXVpbnQ4X3Qgc2Vzc2lvbmlkOwoJdWludDhfdCAqcDJwaWUgPSBOVUxMOwoJdWludDhfdCB0eGZsYWcgPSAwOwoJdWludDhfdCBzbWVfc2Vzc2lvbmlkID0gMDsKCWJvb2wgaXNfdmh0X2VuYWJsZWQgPSBmYWxzZTsKCXVpbnQ4X3QgdHhQb3dlcjsKCXVpbnQxNl90IGFkZG5faWVsZW4gPSBhZGRpdGlvbmFsX2llbGVuOwoJYm9vbCBleHRyYWN0ZWRfZXh0X2NhcF9mbGFnID0gZmFsc2U7Cgl0RG90MTFmSUVFeHRDYXAgZXh0cmFjdGVkX2V4dF9jYXA7Cgl0U2lyUmV0U3RhdHVzIHNpcl9zdGF0dXM7CgoJLyogVGhlIHByb2JlIHJlcSBzaG91bGQgbm90IHNlbmQgMTFhYyBjYXBhYmlsaWV0aWVzIGlmIGJhbmQgaXMgMi40R0h6LAoJICogdW5sZXNzIGVuYWJsZVZodEZvcjI0R0h6IGlzIGVuYWJsZWQgaW4gSU5JLiBTbyBpZiBlbmFibGVWaHRGb3IyNEdIegoJICogaXMgZmFsc2UgYW5kIGRvdDExbW9kZSBpcyAxMWFjIHNldCBpdCB0byAxMW4uCgkgKi8KCWlmIChjaGFubmVsIDw9IFNJUl8xMUJfQ0hBTk5FTF9FTkQgJiYKCSAgICAoZmFsc2UgPT0gbWFjX2N0eC0+cm9hbS5jb25maWdQYXJhbS5lbmFibGVWaHRGb3IyNEdIeikgJiYKCSAgICAoV05JX0NGR19ET1QxMV9NT0RFXzExQUMgPT0gZG90MTFtb2RlIHx8CgkgICAgIFdOSV9DRkdfRE9UMTFfTU9ERV8xMUFDX09OTFkgPT0gZG90MTFtb2RlKSkKCQlkb3QxMW1vZGUgPSBXTklfQ0ZHX0RPVDExX01PREVfMTFOOwoJLyoKCSAqIHNlc3Npb24gY29udGV4dCBtYXkgb3IgbWF5IG5vdCBiZSBwcmVzZW50LCB3aGVuIHByb2JlIHJlcXVlc3QgbmVlZHMKCSAqIHRvIGJlIHNlbnQgb3V0LiBGb2xsb3dpbmcgY2FzZXMgZXhpc3Q6CgkgKiAtLWhlYXJ0YmVhdCBmYWlsdXJlOiAgc2Vzc2lvbiBuZWVkZWQKCSAqIC0tam9pbiByZXE6ICAgICAgICAgICBzZXNzaW9uIG5lZWRlZAoJICogLS1mb3JlZ3JvdW5kIHNjYW46ICAgIG5vIHNlc3Npb24KCSAqIC0tYmFja2dyb3VuZCBzY2FuOiAgICBubyBzZXNzaW9uCgkgKiAtLXNjaF9iZWFjb25fcHJvY2Vzc2luZzogIHRvIGdldCBFRENBIHBhcmFtZXRlcnM6ICBzZXNzaW9uIG5lZWRlZAoJICogSWYgc2Vzc2lvbiBjb250ZXh0IGRvZXMgbm90IGV4aXN0LCBzb21lIElFcyB3aWxsIGJlIHBvcHVsYXRlZCBmcm9tCgkgKiBDRkdzLCBlLmcuIFN1cHBvcnRlZCBhbmQgRXh0ZW5kZWQgcmF0ZSBzZXQgSUVzCgkgKi8KCXBlc2Vzc2lvbiA9IHBlX2ZpbmRfc2Vzc2lvbl9ieV9ic3NpZChtYWNfY3R4LCBic3NpZCwgJnNlc3Npb25pZCk7CgoJaWYgKHBlc2Vzc2lvbiAhPSBOVUxMKQoJCXNtZV9zZXNzaW9uaWQgPSBwZXNlc3Npb24tPnNtZVNlc3Npb25JZDsKCgkvKiBUaGUgc2NoZW1lIGhlcmUgaXMgdG8gZmlsbCBvdXQgYSAndERvdDExZlByb2JlUmVxdWVzdCcgc3RydWN0dXJlICovCgkvKiBhbmQgdGhlbiBoYW5kIGl0IG9mZiB0byAnZG90MTFmX3BhY2tfcHJvYmVfcmVxdWVzdCcgKGZvciAqLwoJLyogc2VyaWFsaXphdGlvbikuICBXZSBzdGFydCBieSB6ZXJvLWluaXRpYWxpemluZyB0aGUgc3RydWN0dXJlOiAqLwoJcWRmX21lbV9zZXQoKHVpbnQ4X3QgKikgJnByLCBzaXplb2YocHIpLCAwKTsKCgkvKiAmIGRlbGVnYXRpbmcgdG8gYXNzb3J0ZWQgaGVscGVyczogKi8KCXBvcHVsYXRlX2RvdDExZl9zc2lkKG1hY19jdHgsIHNzaWQsICZwci5TU0lEKTsKCglpZiAoYWRkbl9pZWxlbiAmJiBhZGRpdGlvbmFsX2llKQoJCXAycGllID0gbGltR2V0UDJwSUVQdHIobWFjX2N0eCwgYWRkaXRpb25hbF9pZSwgYWRkbl9pZWxlbik7CgoJLyoKCSAqIERvbid0IGluY2x1ZGUgMTFiIHJhdGUgaWYgaXQgaXMgYSBQMlAgc2VyYWNoIG9yIHByb2JlIHJlcXVlc3QgaXMKCSAqIHNlbnQgYnkgUDJQIENsaWVudAoJICovCglpZiAoKFdOSV9DRkdfRE9UMTFfTU9ERV8xMUIgIT0gZG90MTFtb2RlKSAmJiAocDJwaWUgIT0gTlVMTCkgJiYKCSAgICAoKChtYWNfY3R4LT5saW0uZ3BMaW1NbG1TY2FuUmVxICE9IE5VTEwpICYmCgkgICAgICBtYWNfY3R4LT5saW0uZ3BMaW1NbG1TY2FuUmVxLT5wMnBTZWFyY2gpIHx8CgkgICAgICgocGVzZXNzaW9uICE9IE5VTEwpICYmCgkgICAgICAoUURGX1AyUF9DTElFTlRfTU9ERSA9PSBwZXNlc3Npb24tPnBlUGVyc29uYSkpCgkgICAgKQoJICAgKSB7CgkJLyoKCQkgKiBJbiB0aGUgYmVsb3cgQVBJIHBhc3MgY2hhbm5lbCBudW1iZXIgPiAxNCwgZG8gdGhhdCBpdCBmaWxscwoJCSAqIG9ubHkgMTFhIHJhdGVzIGluIHN1cHBvcnRlZCByYXRlcwoJCSAqLwoJCXBvcHVsYXRlX2RvdDExZl9zdXBwX3JhdGVzKG1hY19jdHgsIDE1LCAmcHIuU3VwcFJhdGVzLAoJCQkJCSAgIHBlc2Vzc2lvbik7Cgl9IGVsc2UgewoJCXBvcHVsYXRlX2RvdDExZl9zdXBwX3JhdGVzKG1hY19jdHgsIGNoYW5uZWwsCgkJCQkJICAgJnByLlN1cHBSYXRlcywgcGVzZXNzaW9uKTsKCgkJaWYgKFdOSV9DRkdfRE9UMTFfTU9ERV8xMUIgIT0gZG90MTFtb2RlKSB7CgkJCXBvcHVsYXRlX2RvdDExZl9leHRfc3VwcF9yYXRlczEobWFjX2N0eCwgY2hhbm5lbCwKCQkJCQkJCSZwci5FeHRTdXBwUmF0ZXMpOwoJCX0KCX0KCgkvKgoJICogVGFibGUgNy0xNCBpbiBJRUVFIFN0ZC4gODAyLjExay0yMDA4IHNheXMKCSAqIERTIHBhcmFtcyAiY2FuIiBiZSBwcmVzZW50IGluIFJSTSBpcyBkaXNhYmxlZCBhbmQgImlzIiBwcmVzZW50IGlmCgkgKiBSUk0gaXMgZW5hYmxlZC4gSXQgc2hvdWxkIGJlIG9rIGV2ZW4gaWYgd2UgYWRkIGl0IGludG8gcHJvYmUgcmVxIHdoZW4KCSAqIFJSTSBpcyBub3QgZW5hYmxlZC4KCSAqLwoJcG9wdWxhdGVfZG90MTFmX2RzX3BhcmFtcyhtYWNfY3R4LCAmcHIuRFNQYXJhbXMsIGNoYW5uZWwpOwoJLyogQ2FsbCBSUk0gbW9kdWxlIHRvIGdldCB0aGUgdHggcG93ZXIgZm9yIG1hbmFnZW1lbnQgdXNlZC4gKi8KCXR4UG93ZXIgPSAodWludDhfdCkgcnJtX2dldF9tZ210X3R4X3Bvd2VyKG1hY19jdHgsIHBlc2Vzc2lvbik7Cglwb3B1bGF0ZV9kb3QxMWZfd2ZhdHBjKG1hY19jdHgsICZwci5XRkFUUEMsIHR4UG93ZXIsIDApOwoKCglpZiAocGVzZXNzaW9uICE9IE5VTEwpIHsKCQlwZXNlc3Npb24tPmh0Q2FwYWJpbGl0eSA9IElTX0RPVDExX01PREVfSFQoZG90MTFtb2RlKTsKCQkvKiBJbmNsdWRlIEhUIENhcGFiaWxpdHkgSUUgKi8KCQlpZiAocGVzZXNzaW9uLT5odENhcGFiaWxpdHkpCgkJCXBvcHVsYXRlX2RvdDExZl9odF9jYXBzKG1hY19jdHgsIHBlc2Vzc2lvbiwgJnByLkhUQ2Fwcyk7Cgl9IGVsc2UgeyAgICAgICAgICAgICAgICAvKiBwZXNlc3Npb24gPT0gTlVMTCAqLwoJCWlmIChJU19ET1QxMV9NT0RFX0hUKGRvdDExbW9kZSkpCgkJCXBvcHVsYXRlX2RvdDExZl9odF9jYXBzKG1hY19jdHgsIE5VTEwsICZwci5IVENhcHMpOwoJfQoKCS8qCgkgKiBTZXQgY2hhbm5lbGJvbmRpbmcgaW5mb3JtYXRpb24gYXMgImRpc2FibGVkIiB3aGVuIHR1bm5lZCB0byBhCgkgKiAyLjQgR0h6IGNoYW5uZWwKCSAqLwoJaWYgKGNoYW5uZWwgPD0gU0lSXzExQl9DSEFOTkVMX0VORCkgewoJCWlmIChtYWNfY3R4LT5yb2FtLmNvbmZpZ1BhcmFtLmNoYW5uZWxCb25kaW5nTW9kZTI0R0h6CgkJICAgID09IFBIWV9TSU5HTEVfQ0hBTk5FTF9DRU5URVJFRCkgewoJCQlwci5IVENhcHMuc3VwcG9ydGVkQ2hhbm5lbFdpZHRoU2V0ID0KCQkJCWVIVF9DSEFOTkVMX1dJRFRIXzIwTUhaOwoJCQlwci5IVENhcHMuc2hvcnRHSTQwTUh6ID0gMDsKCQl9IGVsc2UgewoJCQlwci5IVENhcHMuc3VwcG9ydGVkQ2hhbm5lbFdpZHRoU2V0ID0KCQkJCWVIVF9DSEFOTkVMX1dJRFRIXzQwTUhaOwoJCX0KCX0KCWlmIChwZXNlc3Npb24gIT0gTlVMTCkgewoJCXBlc2Vzc2lvbi0+dmh0Q2FwYWJpbGl0eSA9IElTX0RPVDExX01PREVfVkhUKGRvdDExbW9kZSk7CgkJLyogSW5jbHVkZSBWSFQgQ2FwYWJpbGl0eSBJRSAqLwoJCWlmIChwZXNlc3Npb24tPnZodENhcGFiaWxpdHkpIHsKCQkJcG9wdWxhdGVfZG90MTFmX3ZodF9jYXBzKG1hY19jdHgsIHBlc2Vzc2lvbiwKCQkJCQkJICZwci5WSFRDYXBzKTsKCQkJaXNfdmh0X2VuYWJsZWQgPSB0cnVlOwoJCX0KCX0gZWxzZSB7CgkJaWYgKElTX0RPVDExX01PREVfVkhUKGRvdDExbW9kZSkpIHsKCQkJcG9wdWxhdGVfZG90MTFmX3ZodF9jYXBzKG1hY19jdHgsIHBlc2Vzc2lvbiwKCQkJCQkJICZwci5WSFRDYXBzKTsKCQkJaXNfdmh0X2VuYWJsZWQgPSB0cnVlOwoJCX0KCX0KCWlmIChwZXNlc3Npb24gIT0gTlVMTCkKCQlwb3B1bGF0ZV9kb3QxMWZfZXh0X2NhcChtYWNfY3R4LCBpc192aHRfZW5hYmxlZCwgJnByLkV4dENhcCwKCQkJcGVzZXNzaW9uKTsKCglpZiAobWFjX2N0eC0+cm9hbS5jb25maWdQYXJhbS5xY25faWVfc3VwcG9ydCkKCQlwb3B1bGF0ZV9kb3QxMWZfcWNuX2llKCZwci5RQ05fSUUpOwoKCWlmIChJU19ET1QxMV9NT0RFX0hFKGRvdDExbW9kZSkgJiYgTlVMTCAhPSBwZXNlc3Npb24pCgkJbGltX3VwZGF0ZV9zZXNzaW9uX2hlX2NhcGFibGUobWFjX2N0eCwgcGVzZXNzaW9uKTsKCglwZV9kZWJ1ZygiUG9wdWxhdGUgSEUgSUVzIik7Cglwb3B1bGF0ZV9kb3QxMWZfaGVfY2FwcyhtYWNfY3R4LCBwZXNlc3Npb24sICZwci52ZW5kb3JfaGVfY2FwKTsKCglpZiAoYWRkbl9pZWxlbikgewoJCXFkZl9tZW1femVybygodWludDhfdCAqKSZleHRyYWN0ZWRfZXh0X2NhcCwKCQkJc2l6ZW9mKHREb3QxMWZJRUV4dENhcCkpOwoJCXNpcl9zdGF0dXMgPSBsaW1fc3RyaXBfZXh0Y2FwX3VwZGF0ZV9zdHJ1Y3QobWFjX2N0eCwKCQkJCQlhZGRpdGlvbmFsX2llLAoJCQkJCSZhZGRuX2llbGVuLAoJCQkJCSZleHRyYWN0ZWRfZXh0X2NhcCk7CgkJaWYgKGVTSVJfU1VDQ0VTUyAhPSBzaXJfc3RhdHVzKSB7CgkJCXBlX2RlYnVnKCJVbmFibGUgdG8gU3RyaXBvZmYgRXh0Q2FwIElFIGZyb20gUHJvYmUgUmVxIik7CgkJfSBlbHNlIHsKCQkJc3RydWN0IHNfZXh0X2NhcCAqcF9leHRfY2FwID0KCQkJCShzdHJ1Y3Qgc19leHRfY2FwICopCgkJCQkJZXh0cmFjdGVkX2V4dF9jYXAuYnl0ZXM7CgkJCWlmIChwX2V4dF9jYXAtPmludGVyd29ya2luZ19zZXJ2aWNlKQoJCQkJcF9leHRfY2FwLT5xb3NfbWFwID0gMTsKCQkJZXh0cmFjdGVkX2V4dF9jYXAubnVtX2J5dGVzID0KCQkJCWxpbV9jb21wdXRlX2V4dF9jYXBfaWVfbGVuZ3RoCgkJCQkJKCZleHRyYWN0ZWRfZXh0X2NhcCk7CgkJCWV4dHJhY3RlZF9leHRfY2FwX2ZsYWcgPQoJCQkJKGV4dHJhY3RlZF9leHRfY2FwLm51bV9ieXRlcyA+IDApOwoJCX0KCX0KCgkvKgoJICogRXh0Y2FwIElFIG5vdyBzdXBwb3J0IHZhcmlhYmxlIGxlbmd0aCwgbWVyZ2UgRXh0Y2FwIElFIGZyb20gYWRkbl9pZQoJICogbWF5IGNoYW5nZSB0aGUgZnJhbWUgc2l6ZS4gVGhlcmVmb3JlLCBNVVNUIG1lcmdlIEV4dENhcCBJRSBiZWZvcmUKCSAqIGRvdDExZiBnZXQgcGFja2VkIHBheWxvYWQgc2l6ZS4KCSAqLwoJaWYgKGV4dHJhY3RlZF9leHRfY2FwX2ZsYWcpCgkJbGltX21lcmdlX2V4dGNhcF9zdHJ1Y3QoJnByLkV4dENhcCwgJmV4dHJhY3RlZF9leHRfY2FwLCB0cnVlKTsKCgkvKiBUaGF0J3MgaXQtLSBub3cgd2UgcGFjayBpdC4gIEZpcnN0LCBob3cgbXVjaCBzcGFjZSBhcmUgd2UgZ29pbmcgdG8gKi8KCXN0YXR1cyA9IGRvdDExZl9nZXRfcGFja2VkX3Byb2JlX3JlcXVlc3Rfc2l6ZShtYWNfY3R4LCAmcHIsICZwYXlsb2FkKTsKCWlmIChET1QxMUZfRkFJTEVEKHN0YXR1cykpIHsKCQlwZV9lcnIoIkZhaWxlZCB0byBjYWxjdWxhdGUgdGhlIHBhY2tlZCBzaXplIGZvciBhIFByb2JlIFJlcXVlc3QgKDB4JTA4eCkiLAoJCQlzdGF0dXMpOwoJCS8qIFdlJ2xsIGZhbGwgYmFjayBvbiB0aGUgd29yc3QgY2FzZSBzY2VuYXJpbzogKi8KCQlwYXlsb2FkID0gc2l6ZW9mKHREb3QxMWZQcm9iZVJlcXVlc3QpOwoJfSBlbHNlIGlmIChET1QxMUZfV0FSTkVEKHN0YXR1cykpIHsKCQlwZV93YXJuKCJUaGVyZSB3ZXJlIHdhcm5pbmdzIHdoaWxlIGNhbGN1bGF0aW5nIHRoZSBwYWNrZWQgc2l6ZSBmb3IgYSBQcm9iZSBSZXF1ZXN0ICgweCUwOHgpIiwKCQkJc3RhdHVzKTsKCX0KCglieXRlcyA9IHBheWxvYWQgKyBzaXplb2YodFNpck1hY01nbXRIZHIpICsgYWRkbl9pZWxlbjsKCgkvKiBPay0tIHRyeSB0byBhbGxvY2F0ZSBzb21lIG1lbW9yeTogKi8KCXFkZl9zdGF0dXMgPSBjZHNfcGFja2V0X2FsbG9jKCh1aW50MTZfdCkgYnl0ZXMsICh2b2lkICoqKSZmcmFtZSwKCQkJCSAgICAgICh2b2lkICoqKSZwYWNrZXQpOwoJaWYgKCFRREZfSVNfU1RBVFVTX1NVQ0NFU1MocWRmX3N0YXR1cykpIHsKCQlwZV9lcnIoIkZhaWxlZCB0byBhbGxvY2F0ZSAlZCBieXRlcyBmb3IgYSBQcm9iZSBSZXF1ZXN0IiwgYnl0ZXMpOwoJCXJldHVybiBlU0lSX01FTV9BTExPQ19GQUlMRUQ7Cgl9CgkvKiBQYXJhbm9pYTogKi8KCXFkZl9tZW1fc2V0KGZyYW1lLCBieXRlcywgMCk7CgoJLyogTmV4dCwgd2UgZmlsbCBvdXQgdGhlIGJ1ZmZlciBkZXNjcmlwdG9yOiAqLwoJbGltX3BvcHVsYXRlX21hY19oZWFkZXIobWFjX2N0eCwgZnJhbWUsIFNJUl9NQUNfTUdNVF9GUkFNRSwKCQlTSVJfTUFDX01HTVRfUFJPQkVfUkVRLCBic3NpZCwgc2VsZl9tYWNhZGRyKTsKCgkvKiBUaGF0IGRvbmUsIHBhY2sgdGhlIFByb2JlIFJlcXVlc3Q6ICovCglzdGF0dXMgPSBkb3QxMWZfcGFja19wcm9iZV9yZXF1ZXN0KG1hY19jdHgsICZwciwgZnJhbWUgKwoJCQkJCSAgICBzaXplb2YodFNpck1hY01nbXRIZHIpLAoJCQkJCSAgICBwYXlsb2FkLCAmcGF5bG9hZCk7CglpZiAoRE9UMTFGX0ZBSUxFRChzdGF0dXMpKSB7CgkJcGVfZXJyKCJGYWlsZWQgdG8gcGFjayBhIFByb2JlIFJlcXVlc3QgKDB4JTA4eCkiLCBzdGF0dXMpOwoJCWNkc19wYWNrZXRfZnJlZSgodm9pZCAqKXBhY2tldCk7CgkJcmV0dXJuIGVTSVJfRkFJTFVSRTsgICAgLyogYWxsb2NhdGVkISAqLwoJfSBlbHNlIGlmIChET1QxMUZfV0FSTkVEKHN0YXR1cykpIHsKCQlwZV93YXJuKCJUaGVyZSB3ZXJlIHdhcm5pbmdzIHdoaWxlIHBhY2tpbmcgYSBQcm9iZSBSZXF1ZXN0ICgweCUwOHgpIiwgc3RhdHVzKTsKCX0KCS8qIEFwcGVuZCBhbnkgQWRkSUUgaWYgcHJlc2VudC4gKi8KCWlmIChhZGRuX2llbGVuKSB7CgkJcWRmX21lbV9jb3B5KGZyYW1lICsgc2l6ZW9mKHRTaXJNYWNNZ210SGRyKSArIHBheWxvYWQsCgkJCSAgICAgYWRkaXRpb25hbF9pZSwgYWRkbl9pZWxlbik7CgkJcGF5bG9hZCArPSBhZGRuX2llbGVuOwoJfQoKCS8qIElmIHRoaXMgcHJvYmUgcmVxdWVzdCBpcyBzZW50IGR1cmluZyBQMlAgU2VhcmNoIFN0YXRlLCB0aGVuIHdlIG5lZWQKCSAqIHRvIHNlbmQgaXQgYXQgT0ZETSByYXRlLgoJICovCglpZiAoKFNJUl9CQU5EXzVfR0haID09IGxpbV9nZXRfcmZfYmFuZChjaGFubmVsKSkKCSAgICB8fCAoKG1hY19jdHgtPmxpbS5ncExpbU1sbVNjYW5SZXEgIT0gTlVMTCkgJiYKCQltYWNfY3R4LT5saW0uZ3BMaW1NbG1TY2FuUmVxLT5wMnBTZWFyY2gpCgkJLyoKCQkgKiBGb3IgdW5pY2FzdCBwcm9iZSByZXEgbWdtdCBmcm9tIEpvaW4gZnVuY3Rpb24gd2UgZG9uJ3Qgc2V0CgkJICogYWJvdmUgdmFyaWFibGVzLiBTbyB3ZSBuZWVkIHRvIGFkZCBvbmUgbW9yZSBjaGVjayB3aGV0aGVyIGl0CgkJICogaXMgcGVQZXJzb25hIGlzIFAyUF9DTElFTlQgb3Igbm90CgkJICovCgkgICAgfHwgKChwZXNlc3Npb24gIT0gTlVMTCkgJiYKCQkoUURGX1AyUF9DTElFTlRfTU9ERSA9PSBwZXNlc3Npb24tPnBlUGVyc29uYSkpCgkgICAgKSB7CgkJdHhmbGFnIHw9IEhBTF9VU0VfQkRfUkFURTJfRk9SX01BTkFHRU1FTlRfRlJBTUU7Cgl9CgoJcWRmX3N0YXR1cyA9CgkJd21hX3R4X2ZyYW1lKG1hY19jdHgsIHBhY2tldCwKCQkJICAgKHVpbnQxNl90KSBzaXplb2YodFNpck1hY01nbXRIZHIpICsgcGF5bG9hZCwKCQkJICAgVFhSWF9GUk1fODAyXzExX01HTVQsIEFOSV9UWERJUl9UT0RTLCA3LAoJCQkgICBsaW1fdHhfY29tcGxldGUsIGZyYW1lLCB0eGZsYWcsIHNtZV9zZXNzaW9uaWQsCgkJCSAgIDApOwoJaWYgKCFRREZfSVNfU1RBVFVTX1NVQ0NFU1MocWRmX3N0YXR1cykpIHsKCQlwZV9lcnIoImNvdWxkIG5vdCBzZW5kIFByb2JlIFJlcXVlc3QgZnJhbWUhIik7CgkJLyogUGt0IHdpbGwgYmUgZnJlZWQgdXAgYnkgdGhlIGNhbGxiYWNrICovCgkJcmV0dXJuIGVTSVJfRkFJTFVSRTsKCX0KCglyZXR1cm4gZVNJUl9TVUNDRVNTOwp9IC8qIEVuZCBsaW1fc2VuZF9wcm9iZV9yZXFfbWdtdF9mcmFtZS4gKi8KCnN0YXRpYyB0U2lyUmV0U3RhdHVzIGxpbV9nZXRfYWRkbl9pZV9mb3JfcHJvYmVfcmVzcCh0cEFuaVNpckdsb2JhbCBwTWFjLAoJCQkJCSAgICAgdWludDhfdCAqYWRkSUUsIHVpbnQxNl90ICphZGRuSUVMZW4sCgkJCQkJICAgICB1aW50OF90IHByb2JlUmVxUDJwSWUpCnsKCS8qIElmIFByb2JlIHJlcXVlc3QgZG9lc24ndCBoYXZlIFAyUCBJRSwgdGhlbiB0YWtlIG91dCBQMlAgSUUKCSAgIGZyb20gYWRkaXRpb25hbCBJRSAqLwoJaWYgKCFwcm9iZVJlcVAycEllKSB7CgkJdWludDhfdCAqdGVtcGJ1ZiA9IE5VTEw7CgkJdWludDE2X3QgdGVtcExlbiA9IDA7CgkJaW50IGxlZnQgPSAqYWRkbklFTGVuOwoJCXVpbnQ4X3QgKnB0ciA9IGFkZElFOwoJCXVpbnQ4X3QgZWxlbV9pZCwgZWxlbV9sZW47CgoJCWlmIChOVUxMID09IGFkZElFKSB7CgkJCXBlX2VycigiTlVMTCBhZGRJRSBwb2ludGVyIik7CgkJCXJldHVybiBlU0lSX0ZBSUxVUkU7CgkJfQoKCQl0ZW1wYnVmID0gcWRmX21lbV9tYWxsb2MobGVmdCk7CgkJaWYgKE5VTEwgPT0gdGVtcGJ1ZikgewoJCQlwZV9lcnIoIlVuYWJsZSB0byBhbGxvY2F0ZSBtZW1vcnkgdG8gc3RvcmUgYWRkbiBJRSIpOwoJCQlyZXR1cm4gZVNJUl9NRU1fQUxMT0NfRkFJTEVEOwoJCX0KCgkJd2hpbGUgKGxlZnQgPj0gMikgewoJCQllbGVtX2lkID0gcHRyWzBdOwoJCQllbGVtX2xlbiA9IHB0clsxXTsKCQkJbGVmdCAtPSAyOwoJCQlpZiAoZWxlbV9sZW4gPiBsZWZ0KSB7CgkJCQlwZV9lcnIoIkludmFsaWQgSUVzIGVpZDogJWQgZWxlbV9sZW46ICVkIGxlZnQ6ICVkIiwKCQkJCQllbGVtX2lkLCBlbGVtX2xlbiwgbGVmdCk7CgkJCQlxZGZfbWVtX2ZyZWUodGVtcGJ1Zik7CgkJCQlyZXR1cm4gZVNJUl9GQUlMVVJFOwoJCQl9CgkJCWlmICghKChTSVJfTUFDX0VJRF9WRU5ET1IgPT0gZWxlbV9pZCkgJiYKCQkJICAgICAgKG1lbWNtcAoJCQkJICAgICAgICgmcHRyWzJdLCBTSVJfTUFDX1AyUF9PVUksCgkJCQkgICAgICAgU0lSX01BQ19QMlBfT1VJX1NJWkUpID09IDApKSkgewoJCQkJcWRmX21lbV9jb3B5KHRlbXBidWYgKyB0ZW1wTGVuLCAmcHRyWzBdLAoJCQkJCSAgICAgZWxlbV9sZW4gKyAyKTsKCQkJCXRlbXBMZW4gKz0gKGVsZW1fbGVuICsgMik7CgkJCX0KCQkJbGVmdCAtPSBlbGVtX2xlbjsKCQkJcHRyICs9IChlbGVtX2xlbiArIDIpOwoJCX0KCQlxZGZfbWVtX2NvcHkoYWRkSUUsIHRlbXBidWYsIHRlbXBMZW4pOwoJCSphZGRuSUVMZW4gPSB0ZW1wTGVuOwoJCXFkZl9tZW1fZnJlZSh0ZW1wYnVmKTsKCX0KCXJldHVybiBlU0lSX1NVQ0NFU1M7Cn0KCi8qKgogKiBsaW1fc2VuZF9wcm9iZV9yc3BfbWdtdF9mcmFtZSgpIC0gU2VuZCBwcm9iZSByZXNwb25zZQogKgogKiBAbWFjX2N0eDogSGFuZGxlIGZvciBtYWMgY29udGV4dAogKiBAcGVlcl9tYWNhZGRyOiBNYWMgYWRkcmVzcyBvZiByZXF1ZXN0aW5nIHBlZXIKICogQHNzaWQ6IFNTSUQgZm9yIHJlc3BvbnNlCiAqIEBuX3N0YWlkOiBTdGF0aW9uIElELCBjdXJyZW50bHkgdW51c2VkLgogKiBAcGVfc2Vzc2lvbjogUEUgc2Vzc2lvbiBpZAogKiBAa2VlcGFsaXZlOiBLZWVwIGFsaXZlIGZsYWcuIEN1cnJlbnRseSB1bnVzZWQuCiAqIEBwcmVxX3AycGllOiBQMlAgSUUgaW4gaW5jb21pbmcgcHJvYmUgcmVxdWVzdAogKgogKiBCdWlsZHMgYW5kIHNlbmRzIHByb2JlIHJlc3BvbnNlIGZyYW1lIHRvIHRoZSByZXF1ZXN0aW5nIHBlZXIKICoKICogUmV0dXJuOiB2b2lkCiAqLwoKdm9pZApsaW1fc2VuZF9wcm9iZV9yc3BfbWdtdF9mcmFtZSh0cEFuaVNpckdsb2JhbCBtYWNfY3R4LAoJCQkgICAgICB0U2lyTWFjQWRkciBwZWVyX21hY2FkZHIsCgkJCSAgICAgIHRwQW5pU1NJRCBzc2lkLAoJCQkgICAgICBzaG9ydCBuX3N0YWlkLAoJCQkgICAgICB1aW50OF90IGtlZXBhbGl2ZSwKCQkJICAgICAgdHBQRVNlc3Npb24gcGVfc2Vzc2lvbiwgdWludDhfdCBwcmVxX3AycGllKQp7Cgl0RG90MTFmUHJvYmVSZXNwb25zZSAqZnJtOwoJdFNpclJldFN0YXR1cyBzaXJfc3RhdHVzOwoJdWludDMyX3QgY2ZnLCBwYXlsb2FkLCBieXRlcyA9IDAsIHN0YXR1czsKCXRwU2lyTWFjTWdtdEhkciBtYWNfaGRyOwoJdWludDhfdCAqZnJhbWU7Cgl2b2lkICpwYWNrZXQgPSBOVUxMOwoJUURGX1NUQVRVUyBxZGZfc3RhdHVzOwoJdWludDMyX3QgYWRkbl9pZV9wcmVzZW50ID0gZmFsc2U7CgoJdWludDE2X3QgYWRkbl9pZV9sZW4gPSAwOwoJdWludDMyX3Qgd3BzX2FwID0gMCwgdG1wOwoJdWludDhfdCB0eF9mbGFnID0gMDsKCXVpbnQ4X3QgKmFkZF9pZSA9IE5VTEw7Cgl1aW50OF90ICpwMnBfaWUgPSBOVUxMOwoJdWludDhfdCBub2FsZW4gPSAwOwoJdWludDhfdCB0b3RhbF9ub2FsZW4gPSAwOwoJdWludDhfdCBub2Ffc3RyZWFtW1NJUl9NQVhfTk9BX0FUVFJfTEVOICsgU0lSX1AyUF9JRV9IRUFERVJfTEVOXTsKCXVpbnQ4X3Qgbm9hX2llW1NJUl9NQVhfTk9BX0FUVFJfTEVOICsgU0lSX1AyUF9JRV9IRUFERVJfTEVOXTsKCXVpbnQ4X3Qgc21lX3Nlc3Npb25pZCA9IDA7Cglib29sIGlzX3ZodF9lbmFibGVkID0gZmFsc2U7Cgl0RG90MTFmSUVFeHRDYXAgZXh0cmFjdGVkX2V4dF9jYXAgPSB7MH07Cglib29sIGV4dHJhY3RlZF9leHRfY2FwX2ZsYWcgPSBmYWxzZTsKCgkvKiBXZSBkb24ndCBhbnN3ZXIgcmVxdWVzdHMgaW4gdGhpcyBjYXNlKi8KCWlmIChBTklfRFJJVkVSX1RZUEUobWFjX2N0eCkgPT0gZURSSVZFUl9UWVBFX01GRykKCQlyZXR1cm47CgoJaWYgKE5VTEwgPT0gcGVfc2Vzc2lvbikKCQlyZXR1cm47CgoJLyoKCSAqIEluIGNhc2Ugd2hlbiBjYWMgdGltZXIgaXMgcnVubmluZyBmb3IgdGhpcyBTQVAgc2Vzc2lvbiB0aGVuCgkgKiBhdm9pZCBzZW5kaW5nIHByb2JlIHJzcCBvdXQuIEl0IGlzIHZpb2xhdGlvbiBvZiBkZnMgc3BlY2lmaWNhdGlvbi4KCSAqLwoJaWYgKCgocGVfc2Vzc2lvbi0+cGVQZXJzb25hID09IFFERl9TQVBfTU9ERSkgfHwKCSAgICAocGVfc2Vzc2lvbi0+cGVQZXJzb25hID09IFFERl9QMlBfR09fTU9ERSkpICYmCgkgICAgKHRydWUgPT0gbWFjX2N0eC0+c2FwLlNhcERmc0luZm8uaXNfZGZzX2NhY190aW1lcl9ydW5uaW5nKSkgewoJCVFERl9UUkFDRShRREZfTU9EVUxFX0lEX1NBUCwgUURGX1RSQUNFX0xFVkVMX0lORk8sCgkJCSAgRkwoIkNBQyB0aW1lciBpcyBydW5uaW5nLCBwcm9iZSByZXNwb25zZSBkcm9wcGVkIikpOwoJCXJldHVybjsKCX0KCXNtZV9zZXNzaW9uaWQgPSBwZV9zZXNzaW9uLT5zbWVTZXNzaW9uSWQ7Cglmcm0gPSBxZGZfbWVtX21hbGxvYyhzaXplb2YodERvdDExZlByb2JlUmVzcG9uc2UpKTsKCWlmIChOVUxMID09IGZybSkgewoJCXBlX2VycigiVW5hYmxlIHRvIGFsbG9jYXRlIG1lbW9yeSIpOwoJCXJldHVybjsKCX0KCgkvKgoJICogRmlsbCBvdXQgJ2ZybScsIGFmdGVyIHdoaWNoIHdlJ2xsIGp1c3QgaGFuZCB0aGUgc3RydWN0IG9mZiB0bwoJICogJ2RvdDExZl9wYWNrX3Byb2JlX3Jlc3BvbnNlJy4KCSAqLwoJcWRmX21lbV9zZXQoKHVpbnQ4X3QgKikgZnJtLCBzaXplb2YodERvdDExZlByb2JlUmVzcG9uc2UpLCAwKTsKCgkvKgoJICogVGltZXN0YW1wIHRvIGJlIHVwZGF0ZWQgYnkgVEZQLCBiZWxvdy4KCSAqCgkgKiBCZWFjb24gSW50ZXJ2YWw6CgkgKi8KCWlmIChMSU1fSVNfQVBfUk9MRShwZV9zZXNzaW9uKSkgewoJCWZybS0+QmVhY29uSW50ZXJ2YWwuaW50ZXJ2YWwgPQoJCQltYWNfY3R4LT5zY2guc2NoT2JqZWN0LmdTY2hCZWFjb25JbnRlcnZhbDsKCX0gZWxzZSB7CgkJc2lyX3N0YXR1cyA9IHdsYW5fY2ZnX2dldF9pbnQobWFjX2N0eCwKCQkJCVdOSV9DRkdfQkVBQ09OX0lOVEVSVkFMLCAmY2ZnKTsKCQlpZiAoZVNJUl9TVUNDRVNTICE9IHNpcl9zdGF0dXMpIHsKCQkJcGVfZXJyKCJGYWlsZWQgdG8gZ2V0IFdOSV9DRkdfQkVBQ09OX0lOVEVSVkFMICglZCkiLAoJCQkJc2lyX3N0YXR1cyk7CgkJCWdvdG8gZXJyX3JldDsKCQl9CgkJZnJtLT5CZWFjb25JbnRlcnZhbC5pbnRlcnZhbCA9ICh1aW50MTZfdCkgY2ZnOwoJfQoKCXBvcHVsYXRlX2RvdDExZl9jYXBhYmlsaXRpZXMobWFjX2N0eCwgJmZybS0+Q2FwYWJpbGl0aWVzLCBwZV9zZXNzaW9uKTsKCXBvcHVsYXRlX2RvdDExZl9zc2lkKG1hY19jdHgsICh0U2lyTWFjU1NpZCAqKSBzc2lkLCAmZnJtLT5TU0lEKTsKCXBvcHVsYXRlX2RvdDExZl9zdXBwX3JhdGVzKG1hY19jdHgsIFBPUFVMQVRFX0RPVDExRl9SQVRFU19PUEVSQVRJT05BTCwKCQkmZnJtLT5TdXBwUmF0ZXMsIHBlX3Nlc3Npb24pOwoKCXBvcHVsYXRlX2RvdDExZl9kc19wYXJhbXMobWFjX2N0eCwgJmZybS0+RFNQYXJhbXMsCgkJcGVfc2Vzc2lvbi0+Y3VycmVudE9wZXJDaGFubmVsKTsKCXBvcHVsYXRlX2RvdDExZl9pYnNzX3BhcmFtcyhtYWNfY3R4LCAmZnJtLT5JQlNTUGFyYW1zLCBwZV9zZXNzaW9uKTsKCglpZiAoTElNX0lTX0FQX1JPTEUocGVfc2Vzc2lvbikpIHsKCQlpZiAocGVfc2Vzc2lvbi0+d3BzX3N0YXRlICE9IFNBUF9XUFNfRElTQUJMRUQpCgkJCXBvcHVsYXRlX2RvdDExZl9wcm9iZV9yZXNfd3BzaV9lcyhtYWNfY3R4LAoJCQkJJmZybS0+V3NjUHJvYmVSZXMsCgkJCQlwZV9zZXNzaW9uKTsKCX0gZWxzZSB7CgkJaWYgKHdsYW5fY2ZnX2dldF9pbnQobWFjX2N0eCwgKHVpbnQxNl90KSBXTklfQ0ZHX1dQU19FTkFCTEUsCgkJCSZ0bXApICE9IGVTSVJfU1VDQ0VTUykKCQkJcGVfZXJyKCJGYWlsZWQgdG8gY2ZnIGdldCBpZCAlZCIsIFdOSV9DRkdfV1BTX0VOQUJMRSk7CgoJCXdwc19hcCA9IHRtcCAmIFdOSV9DRkdfV1BTX0VOQUJMRV9BUDsKCgkJaWYgKHdwc19hcCkKCQkJcG9wdWxhdGVfZG90MTFmX3dzY19pbl9wcm9iZV9yZXMobWFjX2N0eCwKCQkJCSZmcm0tPldzY1Byb2JlUmVzKTsKCgkJaWYgKG1hY19jdHgtPmxpbS53c2NJZUluZm8ucHJvYmVSZXNwV3NjRW5yb2xsbWVudFN0YXRlID09CgkJICAgIGVMSU1fV1NDX0VOUk9MTF9CRUdJTikgewoJCQlwb3B1bGF0ZV9kb3QxMWZfd3NjX3JlZ2lzdHJhcl9pbmZvX2luX3Byb2JlX3JlcyhtYWNfY3R4LAoJCQkJJmZybS0+V3NjUHJvYmVSZXMpOwoJCQltYWNfY3R4LT5saW0ud3NjSWVJbmZvLnByb2JlUmVzcFdzY0Vucm9sbG1lbnRTdGF0ZSA9CgkJCQllTElNX1dTQ19FTlJPTExfSU5fUFJPR1JFU1M7CgkJfQoKCQlpZiAobWFjX2N0eC0+bGltLndzY0llSW5mby53c2NFbnJvbGxtZW50U3RhdGUgPT0KCQkgICAgZUxJTV9XU0NfRU5ST0xMX0VORCkgewoJCQlkZV9wb3B1bGF0ZV9kb3QxMWZfd3NjX3JlZ2lzdHJhcl9pbmZvX2luX3Byb2JlX3JlcygKCQkJCW1hY19jdHgsICZmcm0tPldzY1Byb2JlUmVzKTsKCQkJbWFjX2N0eC0+bGltLndzY0llSW5mby5wcm9iZVJlc3BXc2NFbnJvbGxtZW50U3RhdGUgPQoJCQkJZUxJTV9XU0NfRU5ST0xMX05PT1A7CgkJfQoJfQoKCXBvcHVsYXRlX2RvdDExZl9jb3VudHJ5KG1hY19jdHgsICZmcm0tPkNvdW50cnksIHBlX3Nlc3Npb24pOwoJcG9wdWxhdGVfZG90MTFmX2VkY2FfcGFyYW1fc2V0KG1hY19jdHgsICZmcm0tPkVEQ0FQYXJhbVNldCwgcGVfc2Vzc2lvbik7CgoJaWYgKHBlX3Nlc3Npb24tPmRvdDExbW9kZSAhPSBXTklfQ0ZHX0RPVDExX01PREVfMTFCKQoJCXBvcHVsYXRlX2RvdDExZl9lcnBfaW5mbyhtYWNfY3R4LCAmZnJtLT5FUlBJbmZvLCBwZV9zZXNzaW9uKTsKCglwb3B1bGF0ZV9kb3QxMWZfZXh0X3N1cHBfcmF0ZXMobWFjX2N0eCwKCQlQT1BVTEFURV9ET1QxMUZfUkFURVNfT1BFUkFUSU9OQUwsCgkJJmZybS0+RXh0U3VwcFJhdGVzLCBwZV9zZXNzaW9uKTsKCgkvKiBQb3B1bGF0ZSBIVCBJRXMsIHdoZW4gb3BlcmF0aW5nIGluIDExbiAqLwoJaWYgKHBlX3Nlc3Npb24tPmh0Q2FwYWJpbGl0eSkgewoJCXBvcHVsYXRlX2RvdDExZl9odF9jYXBzKG1hY19jdHgsIHBlX3Nlc3Npb24sICZmcm0tPkhUQ2Fwcyk7CgkJcG9wdWxhdGVfZG90MTFmX2h0X2luZm8obWFjX2N0eCwgJmZybS0+SFRJbmZvLCBwZV9zZXNzaW9uKTsKCX0KCWlmIChwZV9zZXNzaW9uLT52aHRDYXBhYmlsaXR5KSB7CgkJcGVfZGVidWcoIlBvcHVsYXRlIFZIVCBJRSBpbiBQcm9iZSBSZXNwb25zZSIpOwoJCXBvcHVsYXRlX2RvdDExZl92aHRfY2FwcyhtYWNfY3R4LCBwZV9zZXNzaW9uLCAmZnJtLT5WSFRDYXBzKTsKCQlwb3B1bGF0ZV9kb3QxMWZfdmh0X29wZXJhdGlvbihtYWNfY3R4LCBwZV9zZXNzaW9uLAoJCQkmZnJtLT5WSFRPcGVyYXRpb24pOwoJCS8qCgkJICogd2UgZG8gbm90IHN1cHBvcnQgbXVsdGkgdXNlcnMgeWV0LgoJCSAqIHBvcHVsYXRlX2RvdDExZl92aHRfZXh0X2Jzc19sb2FkKCBtYWNfY3R4LAoJCSAqICAgICAgICAgJmZybS5WSFRFeHRCc3NMb2FkICk7CgkJICovCgkJaXNfdmh0X2VuYWJsZWQgPSB0cnVlOwoJfQoKCWlmIChsaW1faXNfc2Vzc2lvbl9oZV9jYXBhYmxlKHBlX3Nlc3Npb24pKSB7CgkJcGVfZGVidWcoIlBvcHVsYXRlIEhFIElFcyIpOwoJCXBvcHVsYXRlX2RvdDExZl9oZV9jYXBzKG1hY19jdHgsIHBlX3Nlc3Npb24sCgkJCQkJJmZybS0+dmVuZG9yX2hlX2NhcCk7CgkJcG9wdWxhdGVfZG90MTFmX2hlX29wZXJhdGlvbihtYWNfY3R4LCBwZV9zZXNzaW9uLAoJCQkJCSAgICAgJmZybS0+dmVuZG9yX2hlX29wKTsKCX0KCglwb3B1bGF0ZV9kb3QxMWZfZXh0X2NhcChtYWNfY3R4LCBpc192aHRfZW5hYmxlZCwgJmZybS0+RXh0Q2FwLAoJCXBlX3Nlc3Npb24pOwoKCWlmIChwZV9zZXNzaW9uLT5wTGltU3RhcnRCc3NSZXEpIHsKCQlwb3B1bGF0ZV9kb3QxMWZfd3BhKG1hY19jdHgsCgkJCSYocGVfc2Vzc2lvbi0+cExpbVN0YXJ0QnNzUmVxLT5yc25JRSksCgkJCSZmcm0tPldQQSk7CgkJcG9wdWxhdGVfZG90MTFmX3Jzbl9vcGFxdWUobWFjX2N0eCwKCQkJJihwZV9zZXNzaW9uLT5wTGltU3RhcnRCc3NSZXEtPnJzbklFKSwKCQkJJmZybS0+UlNOT3BhcXVlKTsKCX0KCglwb3B1bGF0ZV9kb3QxMWZfd21tKG1hY19jdHgsICZmcm0tPldNTUluZm9BcCwgJmZybS0+V01NUGFyYW1zLAoJCSZmcm0tPldNTUNhcHMsIHBlX3Nlc3Npb24pOwoKI2lmIGRlZmluZWQoRkVBVFVSRV9XTEFOX1dBUEkpCglpZiAocGVfc2Vzc2lvbi0+cExpbVN0YXJ0QnNzUmVxKQoJCXBvcHVsYXRlX2RvdDExZl93YXBpKG1hY19jdHgsCgkJCSYocGVfc2Vzc2lvbi0+cExpbVN0YXJ0QnNzUmVxLT5yc25JRSksCgkJCSZmcm0tPldBUEkpOwojZW5kaWYgLyogZGVmaW5lZChGRUFUVVJFX1dMQU5fV0FQSSkgKi8KCglpZiAobWFjX2N0eC0+bGltLmdwTGltUmVtYWluT25DaGFuUmVxKQoJCWJ5dGVzICs9IChtYWNfY3R4LT5saW0uZ3BMaW1SZW1haW5PbkNoYW5SZXEtPmxlbmd0aCAtCgkJCSBzaXplb2YodFNpclJlbWFpbk9uQ2huUmVxKSk7CgllbHNlCgkJLyoKCQkgKiBPbmx5IHVzZSBDRkcgZm9yIG5vbi1saXN0ZW4gbW9kZS4gVGhpcyBDRkcgaXMgbm90IHdvcmtpbmcgZm9yCgkJICogY29uY3VycmVuY3kuIEluIGxpc3RlbmluZyBtb2RlLCBwcm9iZSByc3AgSUVzIGlzIHBhc3NlZCBpbgoJCSAqIHRoZSBtZXNzYWdlIGZyb20gU01FIHRvIFBFLgoJCSAqLwoJCWFkZG5faWVfcHJlc2VudCA9CgkJCShwZV9zZXNzaW9uLT5hZGRJZVBhcmFtcy5wcm9iZVJlc3BEYXRhTGVuICE9IDApOwoKCWlmIChhZGRuX2llX3ByZXNlbnQpIHsKCgkJYWRkX2llID0gcWRmX21lbV9tYWxsb2MoCgkJCQlwZV9zZXNzaW9uLT5hZGRJZVBhcmFtcy5wcm9iZVJlc3BEYXRhTGVuKTsKCQlpZiAoTlVMTCA9PSBhZGRfaWUpIHsKCQkJcGVfZXJyKCJhZGRfaWUgYWxsb2NhdGlvbiBmYWlsZWQiKTsKCQkJZ290byBlcnJfcmV0OwoJCX0KCgkJcWRmX21lbV9jb3B5KGFkZF9pZSwKCQkJICAgICBwZV9zZXNzaW9uLT5hZGRJZVBhcmFtcy5wcm9iZVJlc3BEYXRhX2J1ZmYsCgkJCSAgICAgcGVfc2Vzc2lvbi0+YWRkSWVQYXJhbXMucHJvYmVSZXNwRGF0YUxlbik7CgkJYWRkbl9pZV9sZW4gPSBwZV9zZXNzaW9uLT5hZGRJZVBhcmFtcy5wcm9iZVJlc3BEYXRhTGVuOwoKCQlpZiAoZVNJUl9TVUNDRVNTICE9IGxpbV9nZXRfYWRkbl9pZV9mb3JfcHJvYmVfcmVzcChtYWNfY3R4LAoJCQkJCWFkZF9pZSwgJmFkZG5faWVfbGVuLCBwcmVxX3AycGllKSkgewoJCQlwZV9lcnIoIlVuYWJsZSB0byBnZXQgYWRkbl9pZSIpOwoJCQlnb3RvIGVycl9yZXQ7CgkJfQoKCQlzaXJfc3RhdHVzID0gbGltX3N0cmlwX2V4dGNhcF91cGRhdGVfc3RydWN0KG1hY19jdHgsCgkJCQkJYWRkX2llLCAmYWRkbl9pZV9sZW4sCgkJCQkJJmV4dHJhY3RlZF9leHRfY2FwKTsKCQlpZiAoZVNJUl9TVUNDRVNTICE9IHNpcl9zdGF0dXMpIHsKCQkJcGVfZGVidWcoIlVuYWJsZSB0byBzdHJpcCBvZmYgRXh0Q2FwIElFIik7CgkJfSBlbHNlIHsKCQkJZXh0cmFjdGVkX2V4dF9jYXBfZmxhZyA9IHRydWU7CgkJfQoKCQlieXRlcyA9IGJ5dGVzICsgYWRkbl9pZV9sZW47CgoJCWlmIChwcmVxX3AycGllKQoJCQlwMnBfaWUgPSBsaW1HZXRQMnBJRVB0cihtYWNfY3R4LCAmYWRkX2llWzBdLAoJCQkJCWFkZG5faWVfbGVuKTsKCgkJaWYgKHAycF9pZSAhPSBOVUxMKSB7CgkJCS8qIGdldCBOb0EgYXR0cmlidXRlIHN0cmVhbSBQMlAgSUUgKi8KCQkJbm9hbGVuID0gbGltX2dldF9ub2FfYXR0cl9zdHJlYW0obWFjX2N0eCwKCQkJCQlub2Ffc3RyZWFtLCBwZV9zZXNzaW9uKTsKCQkJaWYgKG5vYWxlbiAhPSAwKSB7CgkJCQl0b3RhbF9ub2FsZW4gPQoJCQkJCWxpbV9idWlsZF9wMnBfaWUobWFjX2N0eCwgJm5vYV9pZVswXSwKCQkJCQkJJm5vYV9zdHJlYW1bMF0sIG5vYWxlbik7CgkJCQlieXRlcyA9IGJ5dGVzICsgdG90YWxfbm9hbGVuOwoJCQl9CgkJfQoJfQoKCS8qCgkgKiBFeHRjYXAgSUUgbm93IHN1cHBvcnQgdmFyaWFibGUgbGVuZ3RoLCBtZXJnZSBFeHRjYXAgSUUgZnJvbSBhZGRuX2llCgkgKiBtYXkgY2hhbmdlIHRoZSBmcmFtZSBzaXplLiBUaGVyZWZvcmUsIE1VU1QgbWVyZ2UgRXh0Q2FwIElFIGJlZm9yZQoJICogZG90MTFmIGdldCBwYWNrZWQgcGF5bG9hZCBzaXplLgoJICovCglpZiAoZXh0cmFjdGVkX2V4dF9jYXBfZmxhZykKCQlsaW1fbWVyZ2VfZXh0Y2FwX3N0cnVjdCgmZnJtLT5FeHRDYXAsICZleHRyYWN0ZWRfZXh0X2NhcCwKCQkJCQl0cnVlKTsKCglzdGF0dXMgPSBkb3QxMWZfZ2V0X3BhY2tlZF9wcm9iZV9yZXNwb25zZV9zaXplKG1hY19jdHgsIGZybSwgJnBheWxvYWQpOwoJaWYgKERPVDExRl9GQUlMRUQoc3RhdHVzKSkgewoJCXBlX2VycigiUHJvYmUgUmVzcG9uc2Ugc2l6ZSBlcnJvciAoMHglMDh4KSIsCgkJCXN0YXR1cyk7CgkJLyogV2UnbGwgZmFsbCBiYWNrIG9uIHRoZSB3b3JzdCBjYXNlIHNjZW5hcmlvOiAqLwoJCXBheWxvYWQgPSBzaXplb2YodERvdDExZlByb2JlUmVzcG9uc2UpOwoJfSBlbHNlIGlmIChET1QxMUZfV0FSTkVEKHN0YXR1cykpIHsKCQlwZV93YXJuKCJQcm9iZSBSZXNwb25zZSBzaXplIHdhcm5pbmcgKDB4JTA4eCkiLAoJCQlzdGF0dXMpOwoJfQoKCWJ5dGVzICs9IHBheWxvYWQgKyBzaXplb2YodFNpck1hY01nbXRIZHIpOwoKCXFkZl9zdGF0dXMgPSBjZHNfcGFja2V0X2FsbG9jKCh1aW50MTZfdCkgYnl0ZXMsICh2b2lkICoqKSZmcmFtZSwKCQkJCSAgICAgICh2b2lkICoqKSZwYWNrZXQpOwoJaWYgKCFRREZfSVNfU1RBVFVTX1NVQ0NFU1MocWRmX3N0YXR1cykpIHsKCQlwZV9lcnIoIlByb2JlIFJlc3BvbnNlIGFsbG9jYXRpb24gZmFpbGVkIik7CgkJZ290byBlcnJfcmV0OwoJfQoJLyogUGFyYW5vaWE6ICovCglxZGZfbWVtX3NldChmcmFtZSwgYnl0ZXMsIDApOwoKCS8qIE5leHQsIHdlIGZpbGwgb3V0IHRoZSBidWZmZXIgZGVzY3JpcHRvcjogKi8KCWxpbV9wb3B1bGF0ZV9tYWNfaGVhZGVyKG1hY19jdHgsIGZyYW1lLCBTSVJfTUFDX01HTVRfRlJBTUUsCgkJU0lSX01BQ19NR01UX1BST0JFX1JTUCwgcGVlcl9tYWNhZGRyLAoJCXBlX3Nlc3Npb24tPnNlbGZNYWNBZGRyKTsKCgltYWNfaGRyID0gKHRwU2lyTWFjTWdtdEhkcikgZnJhbWU7CgoJc2lyX2NvcHlfbWFjX2FkZHIobWFjX2hkci0+YnNzSWQsIHBlX3Nlc3Npb24tPmJzc0lkKTsKCgkvKiBUaGF0IGRvbmUsIHBhY2sgdGhlIFByb2JlIFJlc3BvbnNlOiAqLwoJc3RhdHVzID0KCQlkb3QxMWZfcGFja19wcm9iZV9yZXNwb25zZShtYWNfY3R4LCBmcm0sCgkJCWZyYW1lICsgc2l6ZW9mKHRTaXJNYWNNZ210SGRyKSwKCQkJcGF5bG9hZCwgJnBheWxvYWQpOwoJaWYgKERPVDExRl9GQUlMRUQoc3RhdHVzKSkgewoJCXBlX2VycigiUHJvYmUgUmVzcG9uc2UgcGFjayBmYWlsdXJlICgweCUwOHgpIiwKCQkJc3RhdHVzKTsKCQkJZ290byBlcnJfcmV0OwoJfSBlbHNlIGlmIChET1QxMUZfV0FSTkVEKHN0YXR1cykpIHsKCQlwZV93YXJuKCJQcm9iZSBSZXNwb25zZSBwYWNrIHdhcm5pbmcgKDB4JTA4eCkiLCBzdGF0dXMpOwoJfQoKCXBlX2RlYnVnKCJTZW5kaW5nIFByb2JlIFJlc3BvbnNlIGZyYW1lIHRvIik7CglsaW1fcHJpbnRfbWFjX2FkZHIobWFjX2N0eCwgcGVlcl9tYWNhZGRyLCBMT0dEKTsKCglpZiAobWFjX2N0eC0+bGltLmdwTGltUmVtYWluT25DaGFuUmVxKQoJCXFkZl9tZW1fY29weShmcmFtZSArIHNpemVvZih0U2lyTWFjTWdtdEhkcikgKyBwYXlsb2FkLAoJCQkgICAgIG1hY19jdHgtPmxpbS5ncExpbVJlbWFpbk9uQ2hhblJlcS0+cHJvYmVSc3BJZSwKCQkJICAgICAobWFjX2N0eC0+bGltLmdwTGltUmVtYWluT25DaGFuUmVxLT5sZW5ndGggLQoJCQkgICAgICBzaXplb2YodFNpclJlbWFpbk9uQ2huUmVxKSkpOwoKCWlmIChhZGRuX2llX3ByZXNlbnQpCgkJcWRmX21lbV9jb3B5KGZyYW1lICsgc2l6ZW9mKHRTaXJNYWNNZ210SGRyKSArIHBheWxvYWQsCgkJCSAgICAgJmFkZF9pZVswXSwgYWRkbl9pZV9sZW4pOwoKCWlmIChub2FsZW4gIT0gMCkgewoJCWlmICh0b3RhbF9ub2FsZW4gPgoJCSAgICAoU0lSX01BWF9OT0FfQVRUUl9MRU4gKyBTSVJfUDJQX0lFX0hFQURFUl9MRU4pKSB7CgkJCXBlX2VycigiTm90IGFibGUgdG8gaW5zZXJ0IE5vQSwgdG90YWwgbGVuPSVkIiwKCQkJCXRvdGFsX25vYWxlbik7CgkJCWdvdG8gZXJyX3JldDsKCQl9IGVsc2UgewoJCQlxZGZfbWVtX2NvcHkoJmZyYW1lW2J5dGVzIC0gKHRvdGFsX25vYWxlbildLAoJCQkJICAgICAmbm9hX2llWzBdLCB0b3RhbF9ub2FsZW4pOwoJCX0KCX0KCglpZiAoKFNJUl9CQU5EXzVfR0haID09IGxpbV9nZXRfcmZfYmFuZChwZV9zZXNzaW9uLT5jdXJyZW50T3BlckNoYW5uZWwpKQoJICAgIHx8IChwZV9zZXNzaW9uLT5wZVBlcnNvbmEgPT0gUURGX1AyUF9DTElFTlRfTU9ERSkgfHwKCSAgICAocGVfc2Vzc2lvbi0+cGVQZXJzb25hID09IFFERl9QMlBfR09fTU9ERSkKCSAgICApCgkJdHhfZmxhZyB8PSBIQUxfVVNFX0JEX1JBVEUyX0ZPUl9NQU5BR0VNRU5UX0ZSQU1FOwoKCS8qIFF1ZXVlIFByb2JlIFJlc3BvbnNlIGZyYW1lIGluIGhpZ2ggcHJpb3JpdHkgV1EgKi8KCXFkZl9zdGF0dXMgPSB3bWFfdHhfZnJhbWUoKHRIYWxIYW5kbGUpIG1hY19jdHgsIHBhY2tldCwKCQkJCSh1aW50MTZfdCkgYnl0ZXMsCgkJCQlUWFJYX0ZSTV84MDJfMTFfTUdNVCwKCQkJCUFOSV9UWERJUl9UT0RTLAoJCQkJNywgbGltX3R4X2NvbXBsZXRlLCBmcmFtZSwgdHhfZmxhZywKCQkJCXNtZV9zZXNzaW9uaWQsIDApOwoKCS8qIFBrdCB3aWxsIGJlIGZyZWVkIHVwIGJ5IHRoZSBjYWxsYmFjayAqLwoJaWYgKCFRREZfSVNfU1RBVFVTX1NVQ0NFU1MocWRmX3N0YXR1cykpCgkJcGVfZXJyKCJDb3VsZCBub3Qgc2VuZCBQcm9iZSBSZXNwb25zZSIpOwoKCWlmIChhZGRfaWUgIT0gTlVMTCkKCQlxZGZfbWVtX2ZyZWUoYWRkX2llKTsKCglxZGZfbWVtX2ZyZWUoZnJtKTsKCXJldHVybjsKCmVycl9yZXQ6CglpZiAoYWRkX2llICE9IE5VTEwpCgkJcWRmX21lbV9mcmVlKGFkZF9pZSk7CglpZiAoZnJtICE9IE5VTEwpCgkJcWRmX21lbV9mcmVlKGZybSk7CglpZiAocGFja2V0ICE9IE5VTEwpCgkJY2RzX3BhY2tldF9mcmVlKCh2b2lkICopcGFja2V0KTsKCXJldHVybjsKCn0gLyogRW5kIGxpbV9zZW5kX3Byb2JlX3JzcF9tZ210X2ZyYW1lLiAqLwoKdm9pZApsaW1fc2VuZF9hZGR0c19yZXFfYWN0aW9uX2ZyYW1lKHRwQW5pU2lyR2xvYmFsIHBNYWMsCgkJCQl0U2lyTWFjQWRkciBwZWVyTWFjQWRkciwKCQkJCXRTaXJBZGR0c1JlcUluZm8gKnBBZGRUUywgdHBQRVNlc3Npb24gcHNlc3Npb25FbnRyeSkKewoJdWludDE2X3QgaTsKCXVpbnQ4X3QgKnBGcmFtZTsKCXREb3QxMWZBZGRUU1JlcXVlc3QgQWRkVFNSZXE7Cgl0RG90MTFmV01NQWRkVFNSZXF1ZXN0IFdNTUFkZFRTUmVxOwoJdWludDMyX3QgblBheWxvYWQsIG5CeXRlcywgblN0YXR1czsKCXRwU2lyTWFjTWdtdEhkciBwTWFjSGRyOwoJdm9pZCAqcFBhY2tldDsKI2lmZGVmIEZFQVRVUkVfV0xBTl9FU0UKCXVpbnQzMl90IHBoeU1vZGU7CiNlbmRpZgoJUURGX1NUQVRVUyBxZGZfc3RhdHVzOwoJdWludDhfdCB0eEZsYWcgPSAwOwoJdWludDhfdCBzbWVTZXNzaW9uSWQgPSAwOwoKCWlmIChOVUxMID09IHBzZXNzaW9uRW50cnkpIHsKCQlyZXR1cm47Cgl9CgoJc21lU2Vzc2lvbklkID0gcHNlc3Npb25FbnRyeS0+c21lU2Vzc2lvbklkOwoKCWlmICghcEFkZFRTLT53bWVUc3BlY1ByZXNlbnQpIHsKCQlxZGZfbWVtX3NldCgodWludDhfdCAqKSAmQWRkVFNSZXEsIHNpemVvZihBZGRUU1JlcSksIDApOwoKCQlBZGRUU1JlcS5BY3Rpb24uYWN0aW9uID0gU0lSX01BQ19RT1NfQUREX1RTX1JFUTsKCQlBZGRUU1JlcS5EaWFsb2dUb2tlbi50b2tlbiA9IHBBZGRUUy0+ZGlhbG9nVG9rZW47CgkJQWRkVFNSZXEuQ2F0ZWdvcnkuY2F0ZWdvcnkgPSBTSVJfTUFDX0FDVElPTl9RT1NfTUdNVDsKCQlpZiAocEFkZFRTLT5sbGVUc3BlY1ByZXNlbnQpIHsKCQkJcG9wdWxhdGVfZG90MTFmX3RzcGVjKCZwQWRkVFMtPnRzcGVjLCAmQWRkVFNSZXEuVFNQRUMpOwoJCX0gZWxzZSB7CgkJCXBvcHVsYXRlX2RvdDExZl93bW10c3BlYygmcEFkZFRTLT50c3BlYywKCQkJCQkJICZBZGRUU1JlcS5XTU1UU1BFQyk7CgkJfQoKCQlpZiAocEFkZFRTLT5sbGVUc3BlY1ByZXNlbnQpIHsKCQkJQWRkVFNSZXEubnVtX1dNTVRDTEFTID0gMDsKCQkJQWRkVFNSZXEubnVtX1RDTEFTID0gcEFkZFRTLT5udW1UY2xhczsKCQkJZm9yIChpID0gMDsgaSA8IHBBZGRUUy0+bnVtVGNsYXM7ICsraSkgewoJCQkJcG9wdWxhdGVfZG90MTFmX3RjbGFzKHBNYWMsICZwQWRkVFMtPnRjbGFzSW5mb1tpXSwKCQkJCQkJICAgICAgJkFkZFRTUmVxLlRDTEFTW2ldKTsKCQkJfQoJCX0gZWxzZSB7CgkJCUFkZFRTUmVxLm51bV9UQ0xBUyA9IDA7CgkJCUFkZFRTUmVxLm51bV9XTU1UQ0xBUyA9IHBBZGRUUy0+bnVtVGNsYXM7CgkJCWZvciAoaSA9IDA7IGkgPCBwQWRkVFMtPm51bVRjbGFzOyArK2kpIHsKCQkJCXBvcHVsYXRlX2RvdDExZl93bW10Y2xhcyhwTWFjLAoJCQkJCQkJICZwQWRkVFMtPnRjbGFzSW5mb1tpXSwKCQkJCQkJCSAmQWRkVFNSZXEuV01NVENMQVNbaV0pOwoJCQl9CgkJfQoKCQlpZiAocEFkZFRTLT50Y2xhc1Byb2NQcmVzZW50KSB7CgkJCWlmIChwQWRkVFMtPmxsZVRzcGVjUHJlc2VudCkgewoJCQkJQWRkVFNSZXEuVENMQVNTUFJPQy5wcm9jZXNzaW5nID0KCQkJCQlwQWRkVFMtPnRjbGFzUHJvYzsKCQkJCUFkZFRTUmVxLlRDTEFTU1BST0MucHJlc2VudCA9IDE7CgkJCX0gZWxzZSB7CgkJCQlBZGRUU1JlcS5XTU1UQ0xBU1BST0MudmVyc2lvbiA9IDE7CgkJCQlBZGRUU1JlcS5XTU1UQ0xBU1BST0MucHJvY2Vzc2luZyA9CgkJCQkJcEFkZFRTLT50Y2xhc1Byb2M7CgkJCQlBZGRUU1JlcS5XTU1UQ0xBU1BST0MucHJlc2VudCA9IDE7CgkJCX0KCQl9CgoJCW5TdGF0dXMgPQoJCQlkb3QxMWZfZ2V0X3BhY2tlZF9hZGRfdHNfcmVxdWVzdF9zaXplKHBNYWMsICZBZGRUU1JlcSwgJm5QYXlsb2FkKTsKCQlpZiAoRE9UMTFGX0ZBSUxFRChuU3RhdHVzKSkgewoJCQlwZV9lcnIoIkZhaWxlZCB0byBjYWxjdWxhdGUgdGhlIHBhY2tlZCBzaXplIGZvciBhbiBBZGQgVFMgUmVxdWVzdCAoMHglMDh4KSIsCgkJCQluU3RhdHVzKTsKCQkJLyogV2UnbGwgZmFsbCBiYWNrIG9uIHRoZSB3b3JzdCBjYXNlIHNjZW5hcmlvOiAqLwoJCQluUGF5bG9hZCA9IHNpemVvZih0RG90MTFmQWRkVFNSZXF1ZXN0KTsKCQl9IGVsc2UgaWYgKERPVDExRl9XQVJORUQoblN0YXR1cykpIHsKCQkJcGVfd2FybigiVGhlcmUgd2VyZSB3YXJuaW5ncyB3aGlsZSBjYWxjdWxhdGluZyB0aGUgcGFja2VkIHNpemUgZm9yIGFuIEFkZCBUUyBSZXF1ZXN0ICgweCUwOHgpIiwKCQkJCW5TdGF0dXMpOwoJCX0KCX0gZWxzZSB7CgkJcWRmX21lbV9zZXQoKHVpbnQ4X3QgKikgJldNTUFkZFRTUmVxLCBzaXplb2YoV01NQWRkVFNSZXEpLCAwKTsKCgkJV01NQWRkVFNSZXEuQWN0aW9uLmFjdGlvbiA9IFNJUl9NQUNfUU9TX0FERF9UU19SRVE7CgkJV01NQWRkVFNSZXEuRGlhbG9nVG9rZW4udG9rZW4gPSBwQWRkVFMtPmRpYWxvZ1Rva2VuOwoJCVdNTUFkZFRTUmVxLkNhdGVnb3J5LmNhdGVnb3J5ID0gU0lSX01BQ19BQ1RJT05fV01FOwoKCQkvKiBXTU0gc3BlYyAyLjIuMTAgLSBzdGF0dXMgY29kZSBpcyBvbmx5IGZpbGxlZCBpbiBmb3IgQUREVFMgcmVzcG9uc2UgKi8KCQlXTU1BZGRUU1JlcS5TdGF0dXNDb2RlLnN0YXR1c0NvZGUgPSAwOwoKCQlwb3B1bGF0ZV9kb3QxMWZfd21tdHNwZWMoJnBBZGRUUy0+dHNwZWMsICZXTU1BZGRUU1JlcS5XTU1UU1BFQyk7CiNpZmRlZiBGRUFUVVJFX1dMQU5fRVNFCgkJbGltX2dldF9waHlfbW9kZShwTWFjLCAmcGh5TW9kZSwgcHNlc3Npb25FbnRyeSk7CgoJCWlmIChwaHlNb2RlID09IFdOSV9DRkdfUEhZX01PREVfMTFHCgkJICAgIHx8IHBoeU1vZGUgPT0gV05JX0NGR19QSFlfTU9ERV8xMUEpIHsKCQkJcEFkZFRTLT50c3JzSUUucmF0ZXNbMF0gPSBUU1JTXzExQUdfUkFURV82TUJQUzsKCQl9IGVsc2UgewoJCQlwQWRkVFMtPnRzcnNJRS5yYXRlc1swXSA9IFRTUlNfMTFCX1JBVEVfNV81TUJQUzsKCQl9CgkJcG9wdWxhdGVfZG90MTFfdHNyc2llKHBNYWMsICZwQWRkVFMtPnRzcnNJRSwKCQkJCSAgICAgICZXTU1BZGRUU1JlcS5FU0VUcmFmU3RybVJhdGVTZXQsCgkJCQkgICAgICBzaXplb2YodWludDhfdCkpOwojZW5kaWYKCQkvKiBmaWxsV21lVHNwZWNJRSAqLwoKCQluU3RhdHVzID0KCQkJZG90MTFmX2dldF9wYWNrZWRfd21tX2FkZF90c19yZXF1ZXN0X3NpemUocE1hYywgJldNTUFkZFRTUmVxLAoJCQkJCQkJCSAgJm5QYXlsb2FkKTsKCQlpZiAoRE9UMTFGX0ZBSUxFRChuU3RhdHVzKSkgewoJCQlwZV9lcnIoIkZhaWxlZCB0byBjYWxjdWxhdGUgdGhlIHBhY2tlZCBzaXplIGZvciBhIFdNTSBBZGQgVFMgUmVxdWVzdCAoMHglMDh4KSIsCgkJCQluU3RhdHVzKTsKCQkJLyogV2UnbGwgZmFsbCBiYWNrIG9uIHRoZSB3b3JzdCBjYXNlIHNjZW5hcmlvOiAqLwoJCQluUGF5bG9hZCA9IHNpemVvZih0RG90MTFmQWRkVFNSZXF1ZXN0KTsKCQl9IGVsc2UgaWYgKERPVDExRl9XQVJORUQoblN0YXR1cykpIHsKCQkJcGVfd2FybigiVGhlcmUgd2VyZSB3YXJuaW5ncyB3aGlsZSBjYWxjdWxhdGluZyB0aGUgcGFja2VkIHNpemUgZm9yIGEgV01NIEFkZCBUUyBSZXF1ZXN0ICgweCUwOHgpIiwKCQkJCW5TdGF0dXMpOwoJCX0KCX0KCgluQnl0ZXMgPSBuUGF5bG9hZCArIHNpemVvZih0U2lyTWFjTWdtdEhkcik7CgoJcWRmX3N0YXR1cyA9IGNkc19wYWNrZXRfYWxsb2MoKHVpbnQxNl90KSBuQnl0ZXMsICh2b2lkICoqKSZwRnJhbWUsCgkJCQkgICAgICAodm9pZCAqKikmcFBhY2tldCk7CglpZiAoIVFERl9JU19TVEFUVVNfU1VDQ0VTUyhxZGZfc3RhdHVzKSkgewoJCXBlX2VycigiRmFpbGVkIHRvIGFsbG9jYXRlICVkIGJ5dGVzIGZvciBhbiBBZGQgVFMgUmVxdWVzdCIsCgkJCW5CeXRlcyk7CgkJcmV0dXJuOwoJfQoJLyogUGFyYW5vaWE6ICovCglxZGZfbWVtX3NldChwRnJhbWUsIG5CeXRlcywgMCk7CgoJLyogTmV4dCwgd2UgZmlsbCBvdXQgdGhlIGJ1ZmZlciBkZXNjcmlwdG9yOiAqLwoJbGltX3BvcHVsYXRlX21hY19oZWFkZXIocE1hYywgcEZyYW1lLCBTSVJfTUFDX01HTVRfRlJBTUUsCgkJU0lSX01BQ19NR01UX0FDVElPTiwgcGVlck1hY0FkZHIsIHBzZXNzaW9uRW50cnktPnNlbGZNYWNBZGRyKTsKCXBNYWNIZHIgPSAodHBTaXJNYWNNZ210SGRyKSBwRnJhbWU7CgoJc2lyX2NvcHlfbWFjX2FkZHIocE1hY0hkci0+YnNzSWQsIHBzZXNzaW9uRW50cnktPmJzc0lkKTsKCiNpZmRlZiBXTEFOX0ZFQVRVUkVfMTFXCglsaW1fc2V0X3Byb3RlY3RlZF9iaXQocE1hYywgcHNlc3Npb25FbnRyeSwgcGVlck1hY0FkZHIsIHBNYWNIZHIpOwojZW5kaWYKCgkvKiBUaGF0IGRvbmUsIHBhY2sgdGhlIHN0cnVjdDogKi8KCWlmICghcEFkZFRTLT53bWVUc3BlY1ByZXNlbnQpIHsKCQluU3RhdHVzID0gZG90MTFmX3BhY2tfYWRkX3RzX3JlcXVlc3QocE1hYywgJkFkZFRTUmVxLAoJCQkJCQkgICAgIHBGcmFtZSArCgkJCQkJCSAgICAgc2l6ZW9mKHRTaXJNYWNNZ210SGRyKSwKCQkJCQkJICAgICBuUGF5bG9hZCwgJm5QYXlsb2FkKTsKCQlpZiAoRE9UMTFGX0ZBSUxFRChuU3RhdHVzKSkgewoJCQlwZV9lcnIoIkZhaWxlZCB0byBwYWNrIGFuIEFkZCBUUyBSZXF1ZXN0ICIKCQkJCSIoMHglMDh4KSIsIG5TdGF0dXMpOwoJCQljZHNfcGFja2V0X2ZyZWUoKHZvaWQgKilwUGFja2V0KTsKCQkJcmV0dXJuOyAvKiBhbGxvY2F0ZWQhICovCgkJfSBlbHNlIGlmIChET1QxMUZfV0FSTkVEKG5TdGF0dXMpKSB7CgkJCXBlX3dhcm4oIlRoZXJlIHdlcmUgd2FybmluZ3Mgd2hpbGUgcGFja2luZyBhbiBBZGQgVFMgUmVxdWVzdCAoMHglMDh4KSIsCgkJCQluU3RhdHVzKTsKCQl9Cgl9IGVsc2UgewoJCW5TdGF0dXMgPSBkb3QxMWZfcGFja193bW1fYWRkX3RzX3JlcXVlc3QocE1hYywgJldNTUFkZFRTUmVxLAoJCQkJCQkJIHBGcmFtZSArCgkJCQkJCQkgc2l6ZW9mKHRTaXJNYWNNZ210SGRyKSwKCQkJCQkJCSBuUGF5bG9hZCwgJm5QYXlsb2FkKTsKCQlpZiAoRE9UMTFGX0ZBSUxFRChuU3RhdHVzKSkgewoJCQlwZV9lcnIoIkZhaWxlZCB0byBwYWNrIGEgV01NIEFkZCBUUyBSZXF1ZXN0ICgweCUwOHgpIiwKCQkJCW5TdGF0dXMpOwoJCQljZHNfcGFja2V0X2ZyZWUoKHZvaWQgKilwUGFja2V0KTsKCQkJcmV0dXJuOyAvKiBhbGxvY2F0ZWQhICovCgkJfSBlbHNlIGlmIChET1QxMUZfV0FSTkVEKG5TdGF0dXMpKSB7CgkJCXBlX3dhcm4oIlRoZXJlIHdlcmUgd2FybmluZ3Mgd2hpbGUgcGFja2luZyBhIFdNTSBBZGQgVFMgUmVxdWVzdCAoMHglMDh4KSIsCgkJCQluU3RhdHVzKTsKCQl9Cgl9CgoJcGVfZGVidWcoIlNlbmRpbmcgYW4gQWRkIFRTIFJlcXVlc3QgZnJhbWUgdG8iKTsKCWxpbV9wcmludF9tYWNfYWRkcihwTWFjLCBwZWVyTWFjQWRkciwgTE9HRCk7CgoJaWYgKChTSVJfQkFORF81X0dIWiA9PQoJICAgICBsaW1fZ2V0X3JmX2JhbmQocHNlc3Npb25FbnRyeS0+Y3VycmVudE9wZXJDaGFubmVsKSkKCSAgICB8fCAocHNlc3Npb25FbnRyeS0+cGVQZXJzb25hID09IFFERl9QMlBfQ0xJRU5UX01PREUpCgkgICAgfHwgKHBzZXNzaW9uRW50cnktPnBlUGVyc29uYSA9PSBRREZfUDJQX0dPX01PREUpCgkgICAgKSB7CgkJdHhGbGFnIHw9IEhBTF9VU0VfQkRfUkFURTJfRk9SX01BTkFHRU1FTlRfRlJBTUU7Cgl9CgoJTVRSQUNFKHFkZl90cmFjZShRREZfTU9EVUxFX0lEX1BFLCBUUkFDRV9DT0RFX1RYX01HTVQsCgkJCSBwc2Vzc2lvbkVudHJ5LT5wZVNlc3Npb25JZCwgcE1hY0hkci0+ZmMuc3ViVHlwZSkpOwoKCS8qIFF1ZXVlIEFkZHRzIFJlc3BvbnNlIGZyYW1lIGluIGhpZ2ggcHJpb3JpdHkgV1EgKi8KCXFkZl9zdGF0dXMgPSB3bWFfdHhfZnJhbWUocE1hYywgcFBhY2tldCwgKHVpbnQxNl90KSBuQnl0ZXMsCgkJCQlUWFJYX0ZSTV84MDJfMTFfTUdNVCwKCQkJCUFOSV9UWERJUl9UT0RTLAoJCQkJNywgbGltX3R4X2NvbXBsZXRlLCBwRnJhbWUsIHR4RmxhZywKCQkJCXNtZVNlc3Npb25JZCwgMCk7CglNVFJBQ0UocWRmX3RyYWNlKFFERl9NT0RVTEVfSURfUEUsIFRSQUNFX0NPREVfVFhfQ09NUExFVEUsCgkJCSBwc2Vzc2lvbkVudHJ5LT5wZVNlc3Npb25JZCwgcWRmX3N0YXR1cykpOwoKCWlmICghUURGX0lTX1NUQVRVU19TVUNDRVNTKHFkZl9zdGF0dXMpKQoJCXBlX2VycigiQ291bGQgbm90IHNlbmQgYW4gQWRkIFRTIFJlcXVlc3QgKCVYIiwKCQkJcWRmX3N0YXR1cyk7Cn0gLyogRW5kIGxpbV9zZW5kX2FkZHRzX3JlcV9hY3Rpb25fZnJhbWUuICovCgovKioKICogbGltX3NlbmRfYXNzb2NfcnNwX21nbXRfZnJhbWUoKSAtIFNlbmQgYXNzb2MgcmVzcG9uc2UKICogQG1hY19jdHg6IEhhbmRsZSBmb3IgbWFjIGNvbnRleHQKICogQHN0YXR1c19jb2RlOiBTdGF0dXMgY29kZSBmb3IgYXNzb2MgcmVzcG9uc2UgZnJhbWUKICogQGFpZDogQXNzb2NpYXRpb24gSUQKICogQHBlZXJfYWRkcjogTWFjIGFkZHJlc3Mgb2YgcmVxdWVzdGluZyBwZWVyCiAqIEBzdWJ0eXBlOiBBc3NvYy9SZWFzc29jCiAqIEBzdGE6IFBvaW50ZXIgdG8gc3RhdGlvbiBub2RlCiAqIEBwZV9zZXNzaW9uOiBQRSBzZXNzaW9uIGlkLgogKgogKiBCdWlsZHMgYW5kIHNlbmRzIGFzc29jaWF0aW9uIHJlc3BvbnNlIGZyYW1lIHRvIHRoZSByZXF1ZXN0aW5nIHBlZXIuCiAqCiAqIFJldHVybjogdm9pZAogKi8KCnZvaWQKbGltX3NlbmRfYXNzb2NfcnNwX21nbXRfZnJhbWUodHBBbmlTaXJHbG9iYWwgbWFjX2N0eCwKCXVpbnQxNl90IHN0YXR1c19jb2RlLCB1aW50MTZfdCBhaWQsIHRTaXJNYWNBZGRyIHBlZXJfYWRkciwKCXVpbnQ4X3Qgc3VidHlwZSwgdHBEcGhIYXNoTm9kZSBzdGEsIHRwUEVTZXNzaW9uIHBlX3Nlc3Npb24pCnsKCXN0YXRpYyB0RG90MTFmQXNzb2NSZXNwb25zZSBmcm07Cgl1aW50OF90ICpmcmFtZTsKCXRwU2lyTWFjTWdtdEhkciBtYWNfaGRyOwoJdFNpclJldFN0YXR1cyBzaXJfc3RhdHVzOwoJdWludDhfdCBsbGVfbW9kZSA9IDAsIGFkZHRzOwoJdEhhbEJpdFZhbCBxb3NfbW9kZSwgd21lX21vZGU7Cgl1aW50MzJfdCBwYXlsb2FkLCBieXRlcyA9IDAsIHN0YXR1czsKCXZvaWQgKnBhY2tldDsKCVFERl9TVEFUVVMgcWRmX3N0YXR1czsKCXRVcGRhdGVCZWFjb25QYXJhbXMgYmVhY29uX3BhcmFtczsKCXVpbnQ4X3QgdHhfZmxhZyA9IDA7Cgl1aW50MzJfdCBhZGRuX2llX2xlbiA9IDA7Cgl1aW50OF90IGFkZF9pZVtXTklfQ0ZHX0FTU09DX1JTUF9BREROSUVfREFUQV9MRU5dOwoJdHBTaXJBc3NvY1JlcSBhc3NvY19yZXEgPSBOVUxMOwoJdWludDhfdCBzbWVfc2Vzc2lvbiA9IDA7Cglib29sIGlzX3ZodCA9IGZhbHNlOwoJdWludDE2X3Qgc3RyaXBvZmZfbGVuID0gMDsKCXREb3QxMWZJRUV4dENhcCBleHRyYWN0ZWRfZXh0X2NhcDsKCWJvb2wgZXh0cmFjdGVkX2ZsYWcgPSBmYWxzZTsKI2lmZGVmIFdMQU5fRkVBVFVSRV8xMVcKCXVpbnQzMl90IHJldHJ5X2ludDsKCXVpbnQzMl90IG1heF9yZXRyaWVzOwojZW5kaWYKCglpZiAoTlVMTCA9PSBwZV9zZXNzaW9uKSB7CgkJcGVfZXJyKCJwZV9zZXNzaW9uIGlzIE5VTEwiKTsKCQlyZXR1cm47Cgl9CgoJc21lX3Nlc3Npb24gPSBwZV9zZXNzaW9uLT5zbWVTZXNzaW9uSWQ7CgoJcWRmX21lbV9zZXQoKHVpbnQ4X3QgKikgJmZybSwgc2l6ZW9mKGZybSksIDApOwoKCWxpbUdldFFvc01vZGUocGVfc2Vzc2lvbiwgJnFvc19tb2RlKTsKCWxpbUdldFdtZU1vZGUocGVfc2Vzc2lvbiwgJndtZV9tb2RlKTsKCgkvKgoJICogQW4gQWRkIFRTIElFIGlzIGFkZGVkIG9ubHkgaWYgdGhlIEFQIHN1cHBvcnRzIGl0IGFuZAoJICogdGhlIHJlcXVlc3RpbmcgU1RBIHNlbnQgYSB0cmFmZmljIHNwZWMuCgkgKi8KCWFkZHRzID0gKHFvc19tb2RlICYmIHN0YSAmJiBzdGEtPnFvcy5hZGR0c1ByZXNlbnQpID8gMSA6IDA7CgoJZnJtLlN0YXR1cy5zdGF0dXMgPSBzdGF0dXNfY29kZTsKCglmcm0uQUlELmFzc29jaWQgPSBhaWQgfCBMSU1fQUlEX01BU0s7CgoJaWYgKE5VTEwgPT0gc3RhKSB7CgkJcG9wdWxhdGVfZG90MTFmX3N1cHBfcmF0ZXMobWFjX2N0eCwKCQkJUE9QVUxBVEVfRE9UMTFGX1JBVEVTX09QRVJBVElPTkFMLAoJCQkmZnJtLlN1cHBSYXRlcywgcGVfc2Vzc2lvbik7CgkJcG9wdWxhdGVfZG90MTFmX2V4dF9zdXBwX3JhdGVzKG1hY19jdHgsCgkJCVBPUFVMQVRFX0RPVDExRl9SQVRFU19PUEVSQVRJT05BTCwKCQkJJmZybS5FeHRTdXBwUmF0ZXMsIHBlX3Nlc3Npb24pOwoJfSBlbHNlIHsKCQlwb3B1bGF0ZV9kb3QxMWZfYXNzb2NfcnNwX3JhdGVzKG1hY19jdHgsICZmcm0uU3VwcFJhdGVzLAoJCQkmZnJtLkV4dFN1cHBSYXRlcywKCQkJc3RhLT5zdXBwb3J0ZWRSYXRlcy5sbGJSYXRlcywKCQkJc3RhLT5zdXBwb3J0ZWRSYXRlcy5sbGFSYXRlcyk7Cgl9CgoJaWYgKExJTV9JU19BUF9ST0xFKHBlX3Nlc3Npb24pICYmIHN0YSAhPSBOVUxMICYmCgkgICAgZVNJUl9TVUNDRVNTID09IHN0YXR1c19jb2RlKSB7CgkJYXNzb2NfcmVxID0gKHRwU2lyQXNzb2NSZXEpCgkJCXBlX3Nlc3Npb24tPnBhcnNlZEFzc29jUmVxW3N0YS0+YXNzb2NJZF07CgkJLyoKCQkgKiBwb3B1bGF0ZSBQMlAgSUUgaW4gQXNzb2NSc3Agd2hlbiBhc3NvY1JlcSBmcm9tIHRoZSBwZWVyCgkJICogaW5jbHVkZXMgUDJQIElFCgkJICovCgkJaWYgKGFzc29jX3JlcSAhPSBOVUxMICYmIGFzc29jX3JlcS0+YWRkSUVQcmVzZW50KQoJCQlwb3B1bGF0ZV9kb3QxMV9hc3NvY19yZXNfcDJwX2llKG1hY19jdHgsCgkJCQkmZnJtLlAyUEFzc29jUmVzLAoJCQkJYXNzb2NfcmVxKTsKCX0KCglpZiAoTlVMTCAhPSBzdGEpIHsKCQlpZiAoZUhBTF9TRVQgPT0gcW9zX21vZGUpIHsKCQkJaWYgKHN0YS0+bGxlRW5hYmxlZCkgewoJCQkJbGxlX21vZGUgPSAxOwoJCQkJcG9wdWxhdGVfZG90MTFmX2VkY2FfcGFyYW1fc2V0KG1hY19jdHgsCgkJCQkJJmZybS5FRENBUGFyYW1TZXQsIHBlX3Nlc3Npb24pOwoJCQl9CgkJfQoKCQlpZiAoKCFsbGVfbW9kZSkgJiYgKGVIQUxfU0VUID09IHdtZV9tb2RlKSAmJiBzdGEtPndtZUVuYWJsZWQpIHsKCQkJcG9wdWxhdGVfZG90MTFmX3dtbV9wYXJhbXMobWFjX2N0eCwgJmZybS5XTU1QYXJhbXMsCgkJCQlwZV9zZXNzaW9uKTsKCgkJCWlmIChzdGEtPndzbUVuYWJsZWQpCgkJCQlwb3B1bGF0ZV9kb3QxMWZfd21tX2NhcHMoJmZybS5XTU1DYXBzKTsKCQl9CgoJCWlmIChzdGEtPm1sbVN0YUNvbnRleHQuaHRDYXBhYmlsaXR5ICYmCgkJICAgIHBlX3Nlc3Npb24tPmh0Q2FwYWJpbGl0eSkgewoJCQlwZV9kZWJ1ZygiUG9wdWxhdGUgSFQgSUVzIGluIEFzc29jIFJlc3BvbnNlIik7CgkJCXBvcHVsYXRlX2RvdDExZl9odF9jYXBzKG1hY19jdHgsIHBlX3Nlc3Npb24sCgkJCQkmZnJtLkhUQ2Fwcyk7CgkJCS8qCgkJCSAqIENoZWNrIHRoZSBTVEEgY2FwYWJpbGl0eSBhbmQKCQkJICogdXBkYXRlIHRoZSBIVENhcHMgYWNjb3JkaW5nbHkKCQkJICovCgkJCWZybS5IVENhcHMuc3VwcG9ydGVkQ2hhbm5lbFdpZHRoU2V0ID0gKAoJCQkJc3RhLT5odFN1cHBvcnRlZENoYW5uZWxXaWR0aFNldCA8CgkJCQkgICAgIHBlX3Nlc3Npb24tPmh0U3VwcG9ydGVkQ2hhbm5lbFdpZHRoU2V0KSA/CgkJCQkgICAgICBzdGEtPmh0U3VwcG9ydGVkQ2hhbm5lbFdpZHRoU2V0IDoKCQkJCSAgICAgICBwZV9zZXNzaW9uLT5odFN1cHBvcnRlZENoYW5uZWxXaWR0aFNldDsKCQkJaWYgKCFmcm0uSFRDYXBzLnN1cHBvcnRlZENoYW5uZWxXaWR0aFNldCkKCQkJCWZybS5IVENhcHMuc2hvcnRHSTQwTUh6ID0gMDsKCgkJCXBvcHVsYXRlX2RvdDExZl9odF9pbmZvKG1hY19jdHgsICZmcm0uSFRJbmZvLAoJCQkJcGVfc2Vzc2lvbik7CgkJfQoJCXBlX2RlYnVnKCJTdXBwb3J0ZWRDaG5sV2lkdGg6ICVkLCBtaW1vUFM6ICVkLCBHRjogJWQsIHNob3J0IEdJMjA6JWQsIHNob3J0R0k0MDogJWQsIGRzc3NDY2s6ICVkLCBBTVBEVSBQYXJhbTogJXgiLAoJCQlmcm0uSFRDYXBzLnN1cHBvcnRlZENoYW5uZWxXaWR0aFNldCwKCQkJZnJtLkhUQ2Fwcy5taW1vUG93ZXJTYXZlLAoJCQlmcm0uSFRDYXBzLmdyZWVuRmllbGQsIGZybS5IVENhcHMuc2hvcnRHSTIwTUh6LAoJCQlmcm0uSFRDYXBzLnNob3J0R0k0ME1IeiwKCQkJZnJtLkhUQ2Fwcy5kc3NzQ2NrTW9kZTQwTUh6LAoJCQlmcm0uSFRDYXBzLm1heFJ4QU1QRFVGYWN0b3IpOwoKCQlpZiAoc3RhLT5tbG1TdGFDb250ZXh0LnZodENhcGFiaWxpdHkgJiYKCQkgICAgcGVfc2Vzc2lvbi0+dmh0Q2FwYWJpbGl0eSkgewoJCQlwZV9kZWJ1ZygiUG9wdWxhdGUgVkhUIElFcyBpbiBBc3NvYyBSZXNwb25zZSIpOwoJCQlwb3B1bGF0ZV9kb3QxMWZfdmh0X2NhcHMobWFjX2N0eCwgcGVfc2Vzc2lvbiwKCQkJCSZmcm0uVkhUQ2Fwcyk7CgkJCXBvcHVsYXRlX2RvdDExZl92aHRfb3BlcmF0aW9uKG1hY19jdHgsIHBlX3Nlc3Npb24sCgkJCQkJJmZybS5WSFRPcGVyYXRpb24pOwoJCQlpc192aHQgPSB0cnVlOwoJCX0gZWxzZSB7CgkJCS8qCgkJCSAqIDJHLUFTIHBsYXRmb3JtOiBTQVAgYXNzb2NpYXRlcyB3aXRoIEhUICgxMW4pY2xpZW50cwoJCQkgKiBhcyAyeDEgaW4gMkcgYW5kIDJYMiBpbiA1RwoJCQkgKiBOb24tMkctQVMgcGxhdGZvcm06IFNBUCBhc3NvY2lhdGVzIHdpdGggSFQgKDExbikKCQkJICogY2xpZW50cyBhcyAyWDIgaW4gMkcgYW5kIDVHCgkJCSAqIDVHLUFTOiBEb26SdCBjYXJlCgkJCSAqLwoJCQlpZiAoIXBvbGljeV9tZ3JfaXNfaHdfZGJzXzJ4Ml9jYXBhYmxlKG1hY19jdHgtPnBzb2MpICYmCgkJCQlmcm0uSFRDYXBzLnByZXNlbnQgJiYgbWFjX2N0eC0+aHdfZGJzX2NhcGFibGUgJiYKCQkJCW1hY19jdHgtPmx0ZUNvZXhBbnRTaGFyZSAmJgoJCQkJSVNfMjRHX0NIKHBlX3Nlc3Npb24tPmN1cnJlbnRPcGVyQ2hhbm5lbCkpCgkJCQlmcm0uSFRDYXBzLnN1cHBvcnRlZE1DU1NldFsxXSA9IDA7CgkJfQoJCWlmIChwZV9zZXNzaW9uLT52aHRDYXBhYmlsaXR5ICYmCgkJICAgIHBlX3Nlc3Npb24tPnZlbmRvcl92aHRfc2FwICYmCgkJICAgIChhc3NvY19yZXEgIT0gTlVMTCkgJiYKCQkgICAgYXNzb2NfcmVxLT52ZW5kb3Jfdmh0X2llLlZIVENhcHMucHJlc2VudCkgewoJCQlwZV9kZWJ1ZygiUG9wdWxhdGUgVmVuZG9yIFZIVCBJRXMgaW4gQXNzb2MgUnNwb25zZSIpOwoJCQlmcm0udmVuZG9yX3ZodF9pZS5wcmVzZW50ID0gMTsKCQkJZnJtLnZlbmRvcl92aHRfaWUudHlwZSA9CgkJCQlwZV9zZXNzaW9uLT52ZW5kb3Jfc3BlY2lmaWNfdmh0X2llX3R5cGU7CgkJCWZybS52ZW5kb3Jfdmh0X2llLnN1Yl90eXBlID0KCQkJCXBlX3Nlc3Npb24tPnZlbmRvcl9zcGVjaWZpY192aHRfaWVfc3ViX3R5cGU7CgoJCQlmcm0udmVuZG9yX3ZodF9pZS5WSFRDYXBzLnByZXNlbnQgPSAxOwoJCQlwb3B1bGF0ZV9kb3QxMWZfdmh0X2NhcHMobWFjX2N0eCwgcGVfc2Vzc2lvbiwKCQkJCSZmcm0udmVuZG9yX3ZodF9pZS5WSFRDYXBzKTsKCQkJaXNfdmh0ID0gdHJ1ZTsKCQl9CgkJcG9wdWxhdGVfZG90MTFmX2V4dF9jYXAobWFjX2N0eCwgaXNfdmh0LCAmZnJtLkV4dENhcCwKCQkJcGVfc2Vzc2lvbik7CgoJCWlmIChsaW1faXNfc3RhX2hlX2NhcGFibGUoc3RhKSAmJgoJCSAgICBsaW1faXNfc2Vzc2lvbl9oZV9jYXBhYmxlKHBlX3Nlc3Npb24pKSB7CgkJCXBlX2RlYnVnKCJQb3B1bGF0ZSBIRSBJRXMiKTsKCQkJcG9wdWxhdGVfZG90MTFmX2hlX2NhcHMobWFjX2N0eCwgcGVfc2Vzc2lvbiwKCQkJCQkJJmZybS52ZW5kb3JfaGVfY2FwKTsKCQkJcG9wdWxhdGVfZG90MTFmX2hlX29wZXJhdGlvbihtYWNfY3R4LCBwZV9zZXNzaW9uLAoJCQkJCQkgICAgICZmcm0udmVuZG9yX2hlX29wKTsKCQl9CiNpZmRlZiBXTEFOX0ZFQVRVUkVfMTFXCgkJaWYgKGVTSVJfTUFDX1RSWV9BR0FJTl9MQVRFUiA9PSBzdGF0dXNfY29kZSkgewoJCQlpZiAod2xhbl9jZmdfZ2V0X2ludAoJCQkJICAgIChtYWNfY3R4LCBXTklfQ0ZHX1BNRl9TQV9RVUVSWV9NQVhfUkVUUklFUywKCQkJCSAgICAmbWF4X3JldHJpZXMpICE9IGVTSVJfU1VDQ0VTUykKCQkJCXBlX2VycigiZ2V0IFdOSV9DRkdfUE1GX1NBX1FVRVJZX01BWF9SRVRSSUVTIGZhaWx1cmUiKTsKCQkJZWxzZSBpZiAod2xhbl9jZmdfZ2V0X2ludAoJCQkJCSAobWFjX2N0eCwKCQkJCQkgV05JX0NGR19QTUZfU0FfUVVFUllfUkVUUllfSU5URVJWQUwsCgkJCQkJICZyZXRyeV9pbnQpICE9IGVTSVJfU1VDQ0VTUykKCQkJCXBlX2VycigiZ2V0IFdOSV9DRkdfUE1GX1NBX1FVRVJZX1JFVFJZX0lOVEVSVkFMIGZhaWx1cmUiKTsKCQkJZWxzZQoJCQkJcG9wdWxhdGVfZG90MTFmX3RpbWVvdXRfaW50ZXJ2YWwobWFjX2N0eCwKCQkJCQkmZnJtLlRpbWVvdXRJbnRlcnZhbCwKCQkJCQlTSVJfTUFDX1RJX1RZUEVfQVNTT0NfQ09NRUJBQ0ssCgkJCQkJKG1heF9yZXRyaWVzIC0KCQkJCQkJc3RhLT5wbWZTYVF1ZXJ5UmV0cnlDb3VudCkKCQkJCQkJKiByZXRyeV9pbnQpOwoJCX0KI2VuZGlmCgl9CgoJcWRmX21lbV9zZXQoKHVpbnQ4X3QgKikgJmJlYWNvbl9wYXJhbXMsIHNpemVvZihiZWFjb25fcGFyYW1zKSwgMCk7CgoJaWYgKExJTV9JU19BUF9ST0xFKHBlX3Nlc3Npb24pICYmCgkJKHBlX3Nlc3Npb24tPmdMaW1Qcm90ZWN0aW9uQ29udHJvbCAhPQoJCSAgICBXTklfQ0ZHX0ZPUkNFX1BPTElDWV9QUk9URUNUSU9OX0RJU0FCTEUpKQoJCQlsaW1fZGVjaWRlX2FwX3Byb3RlY3Rpb24obWFjX2N0eCwgcGVlcl9hZGRyLAoJCQkJJmJlYWNvbl9wYXJhbXMsIHBlX3Nlc3Npb24pOwoKCWxpbV91cGRhdGVfc2hvcnRfcHJlYW1ibGUobWFjX2N0eCwgcGVlcl9hZGRyLCAmYmVhY29uX3BhcmFtcywKCQlwZV9zZXNzaW9uKTsKCWxpbV91cGRhdGVfc2hvcnRfc2xvdF90aW1lKG1hY19jdHgsIHBlZXJfYWRkciwgJmJlYWNvbl9wYXJhbXMsCgkJcGVfc2Vzc2lvbik7CgoJLyoKCSAqIFBvcHVsYXRlIERvMTFjYXBhYmlsaXRpZXMgYWZ0ZXIgdXBkYXRpbmcgc2Vzc2lvbiB3aXRoCgkgKiBBc3NvcyByZXEgZGV0YWlscwoJICovCglwb3B1bGF0ZV9kb3QxMWZfY2FwYWJpbGl0aWVzKG1hY19jdHgsICZmcm0uQ2FwYWJpbGl0aWVzLCBwZV9zZXNzaW9uKTsKCgliZWFjb25fcGFyYW1zLmJzc0lkeCA9IHBlX3Nlc3Npb24tPmJzc0lkeDsKCgkvKiBTZW5kIG1lc3NhZ2UgdG8gSEFMIGFib3V0IGJlYWNvbiBwYXJhbWV0ZXIgY2hhbmdlLiAqLwoJaWYgKChmYWxzZSA9PSBtYWNfY3R4LT5zYXAuU2FwRGZzSW5mby5pc19kZnNfY2FjX3RpbWVyX3J1bm5pbmcpCgkgICAgJiYgYmVhY29uX3BhcmFtcy5wYXJhbUNoYW5nZUJpdG1hcCkgewoJCXNjaF9zZXRfZml4ZWRfYmVhY29uX2ZpZWxkcyhtYWNfY3R4LCBwZV9zZXNzaW9uKTsKCQlsaW1fc2VuZF9iZWFjb25fcGFyYW1zKG1hY19jdHgsICZiZWFjb25fcGFyYW1zLCBwZV9zZXNzaW9uKTsKCX0KCglpZiAoYXNzb2NfcmVxICE9IE5VTEwpIHsKCQlhZGRuX2llX2xlbiA9IHBlX3Nlc3Npb24tPmFkZEllUGFyYW1zLmFzc29jUmVzcERhdGFMZW47CgoJCS8qIE5vbnplcm8gbGVuZ3RoIGluZGljYXRlcyBBc3NvYyByc3AgSUUgYXZhaWxhYmxlICovCgkJaWYgKGFkZG5faWVfbGVuID4gMCAmJgoJCSAgICBhZGRuX2llX2xlbiA8PSBXTklfQ0ZHX0FTU09DX1JTUF9BREROSUVfREFUQV9MRU4gJiYKCQkgICAgKGJ5dGVzICsgYWRkbl9pZV9sZW4pIDw9IFNJUl9NQVhfUEFDS0VUX1NJWkUpIHsKCQkJcWRmX21lbV9jb3B5KGFkZF9pZSwKCQkJCXBlX3Nlc3Npb24tPmFkZEllUGFyYW1zLmFzc29jUmVzcERhdGFfYnVmZiwKCQkJCXBlX3Nlc3Npb24tPmFkZEllUGFyYW1zLmFzc29jUmVzcERhdGFMZW4pOwoKCQkJcWRmX21lbV9zZXQoKHVpbnQ4X3QgKikgJmV4dHJhY3RlZF9leHRfY2FwLAoJCQkJICAgIHNpemVvZihleHRyYWN0ZWRfZXh0X2NhcCksIDApOwoKCQkJc3RyaXBvZmZfbGVuID0gYWRkbl9pZV9sZW47CgkJCXNpcl9zdGF0dXMgPQoJCQkJbGltX3N0cmlwX2V4dGNhcF91cGRhdGVfc3RydWN0CgkJCQkJKG1hY19jdHgsICZhZGRfaWVbMF0sICZzdHJpcG9mZl9sZW4sCgkJCQkJJmV4dHJhY3RlZF9leHRfY2FwKTsKCQkJaWYgKGVTSVJfU1VDQ0VTUyAhPSBzaXJfc3RhdHVzKSB7CgkJCQlwZV9kZWJ1Zygic3RyaXAgb2ZmIGV4dGNhcCBJRSBmYWlsZWQiKTsKCQkJfSBlbHNlIHsKCQkJCWFkZG5faWVfbGVuID0gc3RyaXBvZmZfbGVuOwoJCQkJZXh0cmFjdGVkX2ZsYWcgPSB0cnVlOwoJCQl9CgkJCWJ5dGVzID0gYnl0ZXMgKyBhZGRuX2llX2xlbjsKCQl9CgkJcGVfZGVidWcoImFkZG5faWVfbGVuOiAlZCBmb3IgQXNzb2MgUmVzcDogJWQiLAoJCQlhZGRuX2llX2xlbiwgYXNzb2NfcmVxLT5hZGRJRVByZXNlbnQpOwoJfQoKCS8qCgkgKiBFeHRjYXAgSUUgbm93IHN1cHBvcnQgdmFyaWFibGUgbGVuZ3RoLCBtZXJnZSBFeHRjYXAgSUUgZnJvbSBhZGRuX2llCgkgKiBtYXkgY2hhbmdlIHRoZSBmcmFtZSBzaXplLiBUaGVyZWZvcmUsIE1VU1QgbWVyZ2UgRXh0Q2FwIElFIGJlZm9yZQoJICogZG90MTFmIGdldCBwYWNrZWQgcGF5bG9hZCBzaXplLgoJICovCglpZiAoZXh0cmFjdGVkX2ZsYWcpCgkJbGltX21lcmdlX2V4dGNhcF9zdHJ1Y3QoJihmcm0uRXh0Q2FwKSwgJmV4dHJhY3RlZF9leHRfY2FwLAoJCQkJCXRydWUpOwoKCS8qIEFsbG9jYXRlIGEgYnVmZmVyIGZvciB0aGlzIGZyYW1lOiAqLwoJc3RhdHVzID0gZG90MTFmX2dldF9wYWNrZWRfYXNzb2NfcmVzcG9uc2Vfc2l6ZShtYWNfY3R4LCAmZnJtLCAmcGF5bG9hZCk7CglpZiAoRE9UMTFGX0ZBSUxFRChzdGF0dXMpKSB7CgkJcGVfZXJyKCJnZXQgQXNzb2NpYXRpb24gUmVzcG9uc2Ugc2l6ZSBmYWlsdXJlICgweCUwOHgpIiwKCQkJc3RhdHVzKTsKCQlyZXR1cm47Cgl9IGVsc2UgaWYgKERPVDExRl9XQVJORUQoc3RhdHVzKSkgewoJCXBlX3dhcm4oImdldCBBc3NvY2lhdGlvbiBSZXNwb25zZSBzaXplIHdhcm5pbmcgKDB4JTA4eCkiLAoJCQlzdGF0dXMpOwoJfQoKCWJ5dGVzICs9IHNpemVvZih0U2lyTWFjTWdtdEhkcikgKyBwYXlsb2FkOwoKCXFkZl9zdGF0dXMgPSBjZHNfcGFja2V0X2FsbG9jKCh1aW50MTZfdCkgYnl0ZXMsICh2b2lkICoqKSZmcmFtZSwKCQkJCSAgICAgICh2b2lkICoqKSZwYWNrZXQpOwoJaWYgKCFRREZfSVNfU1RBVFVTX1NVQ0NFU1MocWRmX3N0YXR1cykpIHsKCQlwZV9lcnIoImNkc19wYWNrZXRfYWxsb2MgZmFpbGVkIik7CgkJcmV0dXJuOwoJfQoJLyogUGFyYW5vaWE6ICovCglxZGZfbWVtX3NldChmcmFtZSwgYnl0ZXMsIDApOwoKCS8qIE5leHQsIHdlIGZpbGwgb3V0IHRoZSBidWZmZXIgZGVzY3JpcHRvcjogKi8KCWxpbV9wb3B1bGF0ZV9tYWNfaGVhZGVyKG1hY19jdHgsIGZyYW1lLCBTSVJfTUFDX01HTVRfRlJBTUUsCgkJKExJTV9BU1NPQyA9PSBzdWJ0eXBlKSA/CgkJCVNJUl9NQUNfTUdNVF9BU1NPQ19SU1AgOiBTSVJfTUFDX01HTVRfUkVBU1NPQ19SU1AsCgkJCXBlZXJfYWRkciwKCQkJcGVfc2Vzc2lvbi0+c2VsZk1hY0FkZHIpOwoJbWFjX2hkciA9ICh0cFNpck1hY01nbXRIZHIpIGZyYW1lOwoKCXNpcl9jb3B5X21hY19hZGRyKG1hY19oZHItPmJzc0lkLCBwZV9zZXNzaW9uLT5ic3NJZCk7CgoJc3RhdHVzID0gZG90MTFmX3BhY2tfYXNzb2NfcmVzcG9uc2UobWFjX2N0eCwgJmZybSwKCQkJCQkgICAgIGZyYW1lICsgc2l6ZW9mKHRTaXJNYWNNZ210SGRyKSwKCQkJCQkgICAgIHBheWxvYWQsICZwYXlsb2FkKTsKCWlmIChET1QxMUZfRkFJTEVEKHN0YXR1cykpIHsKCQlwZV9lcnIoIkFzc29jaWF0aW9uIFJlc3BvbnNlIHBhY2sgZmFpbHVyZSgweCUwOHgpIiwKCQkJc3RhdHVzKTsKCQljZHNfcGFja2V0X2ZyZWUoKHZvaWQgKilwYWNrZXQpOwoJCXJldHVybjsKCX0gZWxzZSBpZiAoRE9UMTFGX1dBUk5FRChzdGF0dXMpKSB7CgkJcGVfd2FybigiQXNzb2NpYXRpb24gUmVzcG9uc2UgcGFjayB3YXJuaW5nICgweCUwOHgpIiwKCQkJc3RhdHVzKTsKCX0KCglpZiAoc3VidHlwZSA9PSBMSU1fQVNTT0MpCgkJcGVfZGVidWcoIioqKiBTZW5kaW5nIEFzc29jIFJlc3Agc3RhdHVzICVkIGFpZCAlZCB0byIsCgkJCXN0YXR1c19jb2RlLCBhaWQpOwoJZWxzZQoJCXBlX2RlYnVnKCIqKiogU2VuZGluZyBSZUFzc29jIFJlc3Agc3RhdHVzICVkIGFpZCAlZCB0byIsCgkJCXN0YXR1c19jb2RlLCBhaWQpOwoKCWxpbV9wcmludF9tYWNfYWRkcihtYWNfY3R4LCBtYWNfaGRyLT5kYSwgTE9HMSk7CgoJaWYgKGFkZG5faWVfbGVuICYmIGFkZG5faWVfbGVuIDw9IFdOSV9DRkdfQVNTT0NfUlNQX0FERE5JRV9EQVRBX0xFTikKCQlxZGZfbWVtX2NvcHkoZnJhbWUgKyBzaXplb2YodFNpck1hY01nbXRIZHIpICsgcGF5bG9hZCwKCQkJICAgICAmYWRkX2llWzBdLCBhZGRuX2llX2xlbik7CgoJaWYgKChTSVJfQkFORF81X0dIWiA9PQoJCWxpbV9nZXRfcmZfYmFuZChwZV9zZXNzaW9uLT5jdXJyZW50T3BlckNoYW5uZWwpKSB8fAoJCQkocGVfc2Vzc2lvbi0+cGVQZXJzb25hID09IFFERl9QMlBfQ0xJRU5UX01PREUpIHx8CgkJCShwZV9zZXNzaW9uLT5wZVBlcnNvbmEgPT0gUURGX1AyUF9HT19NT0RFKSkKCQl0eF9mbGFnIHw9IEhBTF9VU0VfQkRfUkFURTJfRk9SX01BTkFHRU1FTlRfRlJBTUU7CgoJTVRSQUNFKHFkZl90cmFjZShRREZfTU9EVUxFX0lEX1BFLCBUUkFDRV9DT0RFX1RYX01HTVQsCgkJCSBwZV9zZXNzaW9uLT5wZVNlc3Npb25JZCwgbWFjX2hkci0+ZmMuc3ViVHlwZSkpOwoJLyogUXVldWUgQXNzb2NpYXRpb24gUmVzcG9uc2UgZnJhbWUgaW4gaGlnaCBwcmlvcml0eSBXUSAqLwoJcWRmX3N0YXR1cyA9IHdtYV90eF9mcmFtZShtYWNfY3R4LCBwYWNrZXQsICh1aW50MTZfdCkgYnl0ZXMsCgkJCQlUWFJYX0ZSTV84MDJfMTFfTUdNVCwKCQkJCUFOSV9UWERJUl9UT0RTLAoJCQkJNywgbGltX3R4X2NvbXBsZXRlLCBmcmFtZSwgdHhfZmxhZywKCQkJCXNtZV9zZXNzaW9uLCAwKTsKCU1UUkFDRShxZGZfdHJhY2UoUURGX01PRFVMRV9JRF9QRSwgVFJBQ0VfQ09ERV9UWF9DT01QTEVURSwKCQkJIHBlX3Nlc3Npb24tPnBlU2Vzc2lvbklkLCBxZGZfc3RhdHVzKSk7CgoJLyogUGt0IHdpbGwgYmUgZnJlZWQgdXAgYnkgdGhlIGNhbGxiYWNrICovCglpZiAoIVFERl9JU19TVEFUVVNfU1VDQ0VTUyhxZGZfc3RhdHVzKSkKCQlwZV9lcnIoIkNvdWxkIG5vdCBTZW5kIFJlL0Fzc29jUnNwLCByZXRDb2RlPSVYIiwKCQkJcWRmX3N0YXR1cyk7CgoJLyoKCSAqIHVwZGF0ZSB0aGUgQU5JIHBlZXIgc3RhdGlvbiBjb3VudC4KCSAqIEZJWE1FX1BST1RFQ1RJT04gOiB0YWtlIGNhcmUgb2YgZGlmZmVyZW50IHR5cGUgb2Ygc3RhdGlvbgoJICogY291bnRlciBpbnNpZGUgdGhpcyBmdW5jdGlvbi4KCSAqLwoJbGltX3V0aWxfY291bnRfc3RhX2FkZChtYWNfY3R4LCBzdGEsIHBlX3Nlc3Npb24pOwoKfQoKdm9pZApsaW1fc2VuZF9kZWx0c19yZXFfYWN0aW9uX2ZyYW1lKHRwQW5pU2lyR2xvYmFsIHBNYWMsCgkJCQl0U2lyTWFjQWRkciBwZWVyLAoJCQkJdWludDhfdCB3bW1Uc3BlY1ByZXNlbnQsCgkJCQl0U2lyTWFjVFNJbmZvICpwVHNpbmZvLAoJCQkJdFNpck1hY1RzcGVjSUUgKnBUc3BlY0llLCB0cFBFU2Vzc2lvbiBwc2Vzc2lvbkVudHJ5KQp7Cgl1aW50OF90ICpwRnJhbWU7Cgl0cFNpck1hY01nbXRIZHIgcE1hY0hkcjsKCXREb3QxMWZEZWxUUyBEZWxUUzsKCXREb3QxMWZXTU1EZWxUUyBXTU1EZWxUUzsKCXVpbnQzMl90IG5CeXRlcywgblBheWxvYWQsIG5TdGF0dXM7Cgl2b2lkICpwUGFja2V0OwoJUURGX1NUQVRVUyBxZGZfc3RhdHVzOwoJdWludDhfdCB0eEZsYWcgPSAwOwoJdWludDhfdCBzbWVTZXNzaW9uSWQgPSAwOwoKCWlmIChOVUxMID09IHBzZXNzaW9uRW50cnkpIHsKCQlyZXR1cm47Cgl9CgoJc21lU2Vzc2lvbklkID0gcHNlc3Npb25FbnRyeS0+c21lU2Vzc2lvbklkOwoKCWlmICghd21tVHNwZWNQcmVzZW50KSB7CgkJcWRmX21lbV9zZXQoKHVpbnQ4X3QgKikgJkRlbFRTLCBzaXplb2YoRGVsVFMpLCAwKTsKCgkJRGVsVFMuQ2F0ZWdvcnkuY2F0ZWdvcnkgPSBTSVJfTUFDX0FDVElPTl9RT1NfTUdNVDsKCQlEZWxUUy5BY3Rpb24uYWN0aW9uID0gU0lSX01BQ19RT1NfREVMX1RTX1JFUTsKCQlwb3B1bGF0ZV9kb3QxMWZfdHNfaW5mbyhwVHNpbmZvLCAmRGVsVFMuVFNJbmZvKTsKCgkJblN0YXR1cyA9IGRvdDExZl9nZXRfcGFja2VkX2RlbF90c19zaXplKHBNYWMsICZEZWxUUywgJm5QYXlsb2FkKTsKCQlpZiAoRE9UMTFGX0ZBSUxFRChuU3RhdHVzKSkgewoJCQlwZV9lcnIoIkZhaWxlZCB0byBjYWxjdWxhdGUgdGhlIHBhY2tlZCBzaXplIGZvciBhIERlbCBUUyAoMHglMDh4KSIsIG5TdGF0dXMpOwoJCQkvKiBXZSdsbCBmYWxsIGJhY2sgb24gdGhlIHdvcnN0IGNhc2Ugc2NlbmFyaW86ICovCgkJCW5QYXlsb2FkID0gc2l6ZW9mKHREb3QxMWZEZWxUUyk7CgkJfSBlbHNlIGlmIChET1QxMUZfV0FSTkVEKG5TdGF0dXMpKSB7CgkJCXBlX3dhcm4oIlRoZXJlIHdlcmUgd2FybmluZ3Mgd2hpbGUgY2FsY3VsYXRpbmcgdGhlIHBhY2tlZCBzaXplIGZvciBhIERlbCBUUyAoMHglMDh4KSIsCgkJCQluU3RhdHVzKTsKCQl9Cgl9IGVsc2UgewoJCXFkZl9tZW1fc2V0KCh1aW50OF90ICopICZXTU1EZWxUUywgc2l6ZW9mKFdNTURlbFRTKSwgMCk7CgoJCVdNTURlbFRTLkNhdGVnb3J5LmNhdGVnb3J5ID0gU0lSX01BQ19BQ1RJT05fV01FOwoJCVdNTURlbFRTLkFjdGlvbi5hY3Rpb24gPSBTSVJfTUFDX1FPU19ERUxfVFNfUkVROwoJCVdNTURlbFRTLkRpYWxvZ1Rva2VuLnRva2VuID0gMDsKCQlXTU1EZWxUUy5TdGF0dXNDb2RlLnN0YXR1c0NvZGUgPSAwOwoJCXBvcHVsYXRlX2RvdDExZl93bW10c3BlYyhwVHNwZWNJZSwgJldNTURlbFRTLldNTVRTUEVDKTsKCQluU3RhdHVzID0KCQkJZG90MTFmX2dldF9wYWNrZWRfd21tX2RlbF90c19zaXplKHBNYWMsICZXTU1EZWxUUywgJm5QYXlsb2FkKTsKCQlpZiAoRE9UMTFGX0ZBSUxFRChuU3RhdHVzKSkgewoJCQlwZV9lcnIoIkZhaWxlZCB0byBjYWxjdWxhdGUgdGhlIHBhY2tlZCBzaXplIGZvciBhIFdNTSBEZWwgVFMgKDB4JTA4eCkiLCBuU3RhdHVzKTsKCQkJLyogV2UnbGwgZmFsbCBiYWNrIG9uIHRoZSB3b3JzdCBjYXNlIHNjZW5hcmlvOiAqLwoJCQluUGF5bG9hZCA9IHNpemVvZih0RG90MTFmRGVsVFMpOwoJCX0gZWxzZSBpZiAoRE9UMTFGX1dBUk5FRChuU3RhdHVzKSkgewoJCQlwZV93YXJuKCJUaGVyZSB3ZXJlIHdhcm5pbmdzIHdoaWxlIGNhbGN1bGF0aW5nIHRoZSBwYWNrZWQgc2l6ZSBmb3IgYSBXTU0gRGVsIFRTICgweCUwOHgpIiwKCQkJCW5TdGF0dXMpOwoJCX0KCX0KCgluQnl0ZXMgPSBuUGF5bG9hZCArIHNpemVvZih0U2lyTWFjTWdtdEhkcik7CgoJcWRmX3N0YXR1cyA9CgkJY2RzX3BhY2tldF9hbGxvYygodWludDE2X3QpIG5CeXRlcywgKHZvaWQgKiopJnBGcmFtZSwKCQkJCSAodm9pZCAqKikmcFBhY2tldCk7CglpZiAoIVFERl9JU19TVEFUVVNfU1VDQ0VTUyhxZGZfc3RhdHVzKSkgewoJCXBlX2VycigiRmFpbGVkIHRvIGFsbG9jYXRlICVkIGJ5dGVzIGZvciBhbiBBZGQgVFMgUmVzcG9uc2UiLAoJCQluQnl0ZXMpOwoJCXJldHVybjsKCX0KCS8qIFBhcmFub2lhOiAqLwoJcWRmX21lbV9zZXQocEZyYW1lLCBuQnl0ZXMsIDApOwoKCS8qIE5leHQsIHdlIGZpbGwgb3V0IHRoZSBidWZmZXIgZGVzY3JpcHRvcjogKi8KCWxpbV9wb3B1bGF0ZV9tYWNfaGVhZGVyKHBNYWMsIHBGcmFtZSwgU0lSX01BQ19NR01UX0ZSQU1FLAoJCVNJUl9NQUNfTUdNVF9BQ1RJT04sIHBlZXIsIHBzZXNzaW9uRW50cnktPnNlbGZNYWNBZGRyKTsKCXBNYWNIZHIgPSAodHBTaXJNYWNNZ210SGRyKSBwRnJhbWU7CgoJc2lyX2NvcHlfbWFjX2FkZHIocE1hY0hkci0+YnNzSWQsIHBzZXNzaW9uRW50cnktPmJzc0lkKTsKCiNpZmRlZiBXTEFOX0ZFQVRVUkVfMTFXCglsaW1fc2V0X3Byb3RlY3RlZF9iaXQocE1hYywgcHNlc3Npb25FbnRyeSwgcGVlciwgcE1hY0hkcik7CiNlbmRpZgoKCS8qIFRoYXQgZG9uZSwgcGFjayB0aGUgc3RydWN0OiAqLwoJaWYgKCF3bW1Uc3BlY1ByZXNlbnQpIHsKCQluU3RhdHVzID0gZG90MTFmX3BhY2tfZGVsX3RzKHBNYWMsICZEZWxUUywKCQkJCQkgICAgIHBGcmFtZSArIHNpemVvZih0U2lyTWFjTWdtdEhkciksCgkJCQkJICAgICBuUGF5bG9hZCwgJm5QYXlsb2FkKTsKCQlpZiAoRE9UMTFGX0ZBSUxFRChuU3RhdHVzKSkgewoJCQlwZV9lcnIoIkZhaWxlZCB0byBwYWNrIGEgRGVsIFRTIGZyYW1lICgweCUwOHgpIiwKCQkJCW5TdGF0dXMpOwoJCQljZHNfcGFja2V0X2ZyZWUoKHZvaWQgKilwUGFja2V0KTsKCQkJcmV0dXJuOyAvKiBhbGxvY2F0ZWQhICovCgkJfSBlbHNlIGlmIChET1QxMUZfV0FSTkVEKG5TdGF0dXMpKSB7CgkJCXBlX3dhcm4oIlRoZXJlIHdlcmUgd2FybmluZ3Mgd2hpbGUgcGFja2luZyBhIERlbCBUUyBmcmFtZSAoMHglMDh4KSIsCgkJCQluU3RhdHVzKTsKCQl9Cgl9IGVsc2UgewoJCW5TdGF0dXMgPSBkb3QxMWZfcGFja193bW1fZGVsX3RzKHBNYWMsICZXTU1EZWxUUywKCQkJCQkJIHBGcmFtZSArIHNpemVvZih0U2lyTWFjTWdtdEhkciksCgkJCQkJCSBuUGF5bG9hZCwgJm5QYXlsb2FkKTsKCQlpZiAoRE9UMTFGX0ZBSUxFRChuU3RhdHVzKSkgewoJCQlwZV9lcnIoIkZhaWxlZCB0byBwYWNrIGEgV01NIERlbCBUUyBmcmFtZSAoMHglMDh4KSIsCgkJCQluU3RhdHVzKTsKCQkJY2RzX3BhY2tldF9mcmVlKCh2b2lkICopcFBhY2tldCk7CgkJCXJldHVybjsgLyogYWxsb2NhdGVkISAqLwoJCX0gZWxzZSBpZiAoRE9UMTFGX1dBUk5FRChuU3RhdHVzKSkgewoJCQlwZV93YXJuKCJUaGVyZSB3ZXJlIHdhcm5pbmdzIHdoaWxlIHBhY2tpbmcgYSBXTU0gRGVsIFRTIGZyYW1lICgweCUwOHgpIiwKCQkJCW5TdGF0dXMpOwoJCX0KCX0KCglwZV9kZWJ1ZygiU2VuZGluZyBERUxUUyBSRVEgKHNpemUgJWQpIHRvICIsIG5CeXRlcyk7CglsaW1fcHJpbnRfbWFjX2FkZHIocE1hYywgcE1hY0hkci0+ZGEsIExPR0QpOwoKCWlmICgoU0lSX0JBTkRfNV9HSFogPT0KCSAgICAgbGltX2dldF9yZl9iYW5kKHBzZXNzaW9uRW50cnktPmN1cnJlbnRPcGVyQ2hhbm5lbCkpCgkgICAgfHwgKHBzZXNzaW9uRW50cnktPnBlUGVyc29uYSA9PSBRREZfUDJQX0NMSUVOVF9NT0RFKQoJICAgIHx8IChwc2Vzc2lvbkVudHJ5LT5wZVBlcnNvbmEgPT0gUURGX1AyUF9HT19NT0RFKQoJICAgICkgewoJCXR4RmxhZyB8PSBIQUxfVVNFX0JEX1JBVEUyX0ZPUl9NQU5BR0VNRU5UX0ZSQU1FOwoJfQoKCU1UUkFDRShxZGZfdHJhY2UoUURGX01PRFVMRV9JRF9QRSwgVFJBQ0VfQ09ERV9UWF9NR01ULAoJCQkgcHNlc3Npb25FbnRyeS0+cGVTZXNzaW9uSWQsIHBNYWNIZHItPmZjLnN1YlR5cGUpKTsKCXFkZl9zdGF0dXMgPSB3bWFfdHhfZnJhbWUocE1hYywgcFBhY2tldCwgKHVpbnQxNl90KSBuQnl0ZXMsCgkJCQlUWFJYX0ZSTV84MDJfMTFfTUdNVCwKCQkJCUFOSV9UWERJUl9UT0RTLAoJCQkJNywgbGltX3R4X2NvbXBsZXRlLCBwRnJhbWUsIHR4RmxhZywKCQkJCXNtZVNlc3Npb25JZCwgMCk7CglNVFJBQ0UocWRmX3RyYWNlKFFERl9NT0RVTEVfSURfUEUsIFRSQUNFX0NPREVfVFhfQ09NUExFVEUsCgkJCSBwc2Vzc2lvbkVudHJ5LT5wZVNlc3Npb25JZCwgcWRmX3N0YXR1cykpOwoJLyogUGt0IHdpbGwgYmUgZnJlZWQgdXAgYnkgdGhlIGNhbGxiYWNrICovCglpZiAoIVFERl9JU19TVEFUVVNfU1VDQ0VTUyhxZGZfc3RhdHVzKSkKCQlwZV9lcnIoIkZhaWxlZCB0byBzZW5kIERlbCBUUyAoJVgpISIsIHFkZl9zdGF0dXMpOwoKfSAvKiBFbmQgbGltX3NlbmRfZGVsdHNfcmVxX2FjdGlvbl9mcmFtZS4gKi8KCi8qKgogKiBsaW1fc2VuZF9hc3NvY19yZXFfbWdtdF9mcmFtZSgpIC0gU2VuZCBhc3NvY2lhdGlvbiByZXF1ZXN0CiAqIEBtYWNfY3R4OiBIYW5kbGUgdG8gTUFDIGNvbnRleHQKICogQG1sbV9hc3NvY19yZXE6IEFzc29jaWF0aW9uIHJlcXVlc3QgaW5mb3JtYXRpb24KICogQHBlX3Nlc3Npb246IFBFIHNlc3Npb24gaW5mb3JtYXRpb24KICoKICogQnVpbGRzIGFuZCB0cmFuc21pdHMgYXNzb2NpYXRpb24gcmVxdWVzdCBmcmFtZSB0byBBUC4KICoKICogUmV0dXJuOiBWb2lkCiAqLwoKdm9pZApsaW1fc2VuZF9hc3NvY19yZXFfbWdtdF9mcmFtZSh0cEFuaVNpckdsb2JhbCBtYWNfY3R4LAoJCQkgICAgICB0TGltTWxtQXNzb2NSZXEgKm1sbV9hc3NvY19yZXEsCgkJCSAgICAgIHRwUEVTZXNzaW9uIHBlX3Nlc3Npb24pCnsKCXREb3QxMWZBc3NvY1JlcXVlc3QgKmZybTsKCXVpbnQxNl90IGNhcHM7Cgl1aW50OF90ICpmcmFtZTsKCXRTaXJSZXRTdGF0dXMgc2lyX3N0YXR1czsKCXRMaW1NbG1Bc3NvY0NuZiBhc3NvY19jbmY7Cgl1aW50MzJfdCBieXRlcyA9IDAsIHBheWxvYWQsIHN0YXR1czsKCXVpbnQ4X3QgcW9zX2VuYWJsZWQsIHdtZV9lbmFibGVkLCB3c21fZW5hYmxlZDsKCXZvaWQgKnBhY2tldDsKCVFERl9TVEFUVVMgcWRmX3N0YXR1czsKCXVpbnQxNl90IGFkZF9pZV9sZW47Cgl1aW50OF90ICphZGRfaWU7Cgl1aW50OF90ICp3cHNfaWUgPSBOVUxMOwoJdWludDhfdCBwb3dlcl9jYXBzID0gZmFsc2U7Cgl1aW50OF90IHR4X2ZsYWcgPSAwOwoJdWludDhfdCBzbWVfc2Vzc2lvbmlkID0gMDsKCWJvb2wgdmh0X2VuYWJsZWQgPSBmYWxzZTsKCXREb3QxMWZJRUV4dENhcCBleHRyX2V4dF9jYXA7Cglib29sIGV4dHJfZXh0X2ZsYWcgPSB0cnVlOwoJdHBTaXJNYWNNZ210SGRyIG1hY19oZHI7Cgl1aW50MzJfdCBpZV9vZmZzZXQgPSAwOwoJdWludDhfdCAqcF9leHRfY2FwID0gTlVMTDsKCXREb3QxMWZJRUV4dENhcCBiY25fZXh0X2NhcDsKCXVpbnQ4X3QgKmJjbl9pZSA9IE5VTEw7Cgl1aW50MzJfdCBiY25faWVfbGVuID0gMDsKCglpZiAoTlVMTCA9PSBwZV9zZXNzaW9uKSB7CgkJcGVfZXJyKCJwZV9zZXNzaW9uIGlzIE5VTEwiKTsKCQlxZGZfbWVtX2ZyZWUobWxtX2Fzc29jX3JlcSk7CgkJcmV0dXJuOwoJfQoKCXNtZV9zZXNzaW9uaWQgPSBwZV9zZXNzaW9uLT5zbWVTZXNzaW9uSWQ7CgoJLyogY2hlY2sgdGhpcyBlYXJseSB0byBhdm9pZCB1bm5jZXNzYXJ5IG9wZXJhdGlvbiAqLwoJaWYgKE5VTEwgPT0gcGVfc2Vzc2lvbi0+cExpbUpvaW5SZXEpIHsKCQlwZV9lcnIoInBlX3Nlc3Npb24tPnBMaW1Kb2luUmVxIGlzIE5VTEwiKTsKCQlxZGZfbWVtX2ZyZWUobWxtX2Fzc29jX3JlcSk7CgkJcmV0dXJuOwoJfQoJYWRkX2llX2xlbiA9IHBlX3Nlc3Npb24tPnBMaW1Kb2luUmVxLT5hZGRJRUFzc29jLmxlbmd0aDsKCWFkZF9pZSA9IHBlX3Nlc3Npb24tPnBMaW1Kb2luUmVxLT5hZGRJRUFzc29jLmFkZElFZGF0YTsKCglmcm0gPSBxZGZfbWVtX21hbGxvYyhzaXplb2YodERvdDExZkFzc29jUmVxdWVzdCkpOwoJaWYgKE5VTEwgPT0gZnJtKSB7CgkJcGVfZXJyKCJVbmFibGUgdG8gYWxsb2NhdGUgbWVtb3J5Iik7CgkJcWRmX21lbV9mcmVlKG1sbV9hc3NvY19yZXEpOwoJCXJldHVybjsKCX0KCXFkZl9tZW1fc2V0KCh1aW50OF90ICopIGZybSwgc2l6ZW9mKHREb3QxMWZBc3NvY1JlcXVlc3QpLCAwKTsKCglpZiAoYWRkX2llX2xlbiAmJiBwZV9zZXNzaW9uLT5pc19leHRfY2Fwc19wcmVzZW50KSB7CgkJcWRmX21lbV9zZXQoKHVpbnQ4X3QgKikgJmV4dHJfZXh0X2NhcCwgc2l6ZW9mKHREb3QxMWZJRUV4dENhcCksCgkJCSAgICAwKTsKCQlzaXJfc3RhdHVzID0gbGltX3N0cmlwX2V4dGNhcF91cGRhdGVfc3RydWN0KG1hY19jdHgsCgkJCQkJYWRkX2llLCAmYWRkX2llX2xlbiwgJmV4dHJfZXh0X2NhcCk7CgkJaWYgKGVTSVJfU1VDQ0VTUyAhPSBzaXJfc3RhdHVzKSB7CgkJCWV4dHJfZXh0X2ZsYWcgPSBmYWxzZTsKCQkJcGVfZGVidWcoIlVuYWJsZSB0byBTdHJpcG9mZiBFeHRDYXAgSUUgZnJvbSBBc3NvYyBSZXEiKTsKCQl9IGVsc2UgewoJCQlzdHJ1Y3Qgc19leHRfY2FwICpwX2V4dF9jYXAgPSAoc3RydWN0IHNfZXh0X2NhcCAqKQoJCQkJCQkJZXh0cl9leHRfY2FwLmJ5dGVzOwoKCQkJaWYgKHBfZXh0X2NhcC0+aW50ZXJ3b3JraW5nX3NlcnZpY2UpCgkJCQlwX2V4dF9jYXAtPnFvc19tYXAgPSAxOwoJCQlleHRyX2V4dF9jYXAubnVtX2J5dGVzID0KCQkJCWxpbV9jb21wdXRlX2V4dF9jYXBfaWVfbGVuZ3RoKCZleHRyX2V4dF9jYXApOwoJCQlleHRyX2V4dF9mbGFnID0gKGV4dHJfZXh0X2NhcC5udW1fYnl0ZXMgPiAwKTsKCQl9Cgl9IGVsc2UgewoJCXBlX2RlYnVnKCJObyBhZGRuIElFIG9yIHBlZXIgZG9zZW4ndCBzdXBwb3J0IGFkZG5JRSBmb3IgQXNzb2MgUmVxIik7CgkJZXh0cl9leHRfZmxhZyA9IGZhbHNlOwoJfQoKCWNhcHMgPSBtbG1fYXNzb2NfcmVxLT5jYXBhYmlsaXR5SW5mbzsKI2lmIGRlZmluZWQoRkVBVFVSRV9XTEFOX1dBUEkpCgkvKgoJICogQWNjb3JkaW5nIHRvIFdBUEkgc3RhbmRhcmQ6CgkgKiA3LjMuMS40IENhcGFiaWxpdHkgSW5mb3JtYXRpb24gZmllbGQKCSAqIEluIFdBUEksIG5vbi1BUCBTVEFzIHdpdGhpbiBhbiBFU1Mgc2V0IHRoZSBQcml2YWN5IHN1YmZpZWxkIHRvIDAKCSAqIGluIHRyYW5zbWl0dGVkIEFzc29jaWF0aW9uIG9yIFJlYXNzb2NpYXRpb24gbWFuYWdlbWVudCBmcmFtZXMuCgkgKiBBUHMgaWdub3JlIHRoZSBQcml2YWN5IHN1YmZpZWxkIHdpdGhpbiByZWNlaXZlZCBBc3NvY2lhdGlvbiBhbmQKCSAqIFJlYXNzb2NpYXRpb24gbWFuYWdlbWVudCBmcmFtZXMuCgkgKi8KCWlmIChwZV9zZXNzaW9uLT5lbmNyeXB0VHlwZSA9PSBlU0lSX0VEX1dQSSkKCQkoKHRTaXJNYWNDYXBhYmlsaXR5SW5mbyAqKSAmY2FwcyktPnByaXZhY3kgPSAwOwojZW5kaWYKCXN3YXBfYml0X2ZpZWxkMTYoY2FwcywgKHVpbnQxNl90ICopICZmcm0tPkNhcGFiaWxpdGllcyk7CgoJZnJtLT5MaXN0ZW5JbnRlcnZhbC5pbnRlcnZhbCA9IG1sbV9hc3NvY19yZXEtPmxpc3RlbkludGVydmFsOwoJcG9wdWxhdGVfZG90MTFmX3NzaWQyKG1hY19jdHgsICZmcm0tPlNTSUQpOwoJcG9wdWxhdGVfZG90MTFmX3N1cHBfcmF0ZXMobWFjX2N0eCwgUE9QVUxBVEVfRE9UMTFGX1JBVEVTX09QRVJBVElPTkFMLAoJCSZmcm0tPlN1cHBSYXRlcywgcGVfc2Vzc2lvbik7CgoJcW9zX2VuYWJsZWQgPSAocGVfc2Vzc2lvbi0+bGltUW9zRW5hYmxlZCkgJiYKCQkgICAgICBTSVJfTUFDX0dFVF9RT1MocGVfc2Vzc2lvbi0+bGltQ3VycmVudEJzc0NhcHMpOwoKCXdtZV9lbmFibGVkID0gKHBlX3Nlc3Npb24tPmxpbVdtZUVuYWJsZWQpICYmCgkJICAgICAgTElNX0JTU19DQVBTX0dFVChXTUUsIHBlX3Nlc3Npb24tPmxpbUN1cnJlbnRCc3NRb3NDYXBzKTsKCgkvKiBXZSBwcmVmZXIgLjExZSBhc29jaWF0aW9uczogKi8KCWlmIChxb3NfZW5hYmxlZCkKCQl3bWVfZW5hYmxlZCA9IGZhbHNlOwoKCXdzbV9lbmFibGVkID0gKHBlX3Nlc3Npb24tPmxpbVdzbUVuYWJsZWQpICYmIHdtZV9lbmFibGVkICYmCgkJICAgICAgTElNX0JTU19DQVBTX0dFVChXU00sIHBlX3Nlc3Npb24tPmxpbUN1cnJlbnRCc3NRb3NDYXBzKTsKCglpZiAocGVfc2Vzc2lvbi0+bGltMTFoRW5hYmxlICYmCgkgICAgcGVfc2Vzc2lvbi0+cExpbUpvaW5SZXEtPnNwZWN0cnVtTWd0SW5kaWNhdG9yID09IHRydWUpIHsKCQlwb3dlcl9jYXBzID0gdHJ1ZTsKCgkJcG9wdWxhdGVfZG90MTFmX3Bvd2VyX2NhcHMobWFjX2N0eCwgJmZybS0+UG93ZXJDYXBzLAoJCQlMSU1fQVNTT0MsIHBlX3Nlc3Npb24pOwoJCXBvcHVsYXRlX2RvdDExZl9zdXBwX2NoYW5uZWxzKG1hY19jdHgsICZmcm0tPlN1cHBDaGFubmVscywKCQkJTElNX0FTU09DLCBwZV9zZXNzaW9uKTsKCgl9CglpZiAobWFjX2N0eC0+cnJtLnJybVBFQ29udGV4dC5ycm1FbmFibGUgJiYKCSAgICBTSVJfTUFDX0dFVF9SUk0ocGVfc2Vzc2lvbi0+bGltQ3VycmVudEJzc0NhcHMpKSB7CgkJaWYgKHBvd2VyX2NhcHMgPT0gZmFsc2UpIHsKCQkJcG93ZXJfY2FwcyA9IHRydWU7CgkJCXBvcHVsYXRlX2RvdDExZl9wb3dlcl9jYXBzKG1hY19jdHgsICZmcm0tPlBvd2VyQ2FwcywKCQkJCUxJTV9BU1NPQywgcGVfc2Vzc2lvbik7CgkJfQoJfQoJaWYgKHFvc19lbmFibGVkKQoJCXBvcHVsYXRlX2RvdDExZl9xb3NfY2Fwc19zdGF0aW9uKG1hY19jdHgsIHBlX3Nlc3Npb24sCgkJCQkJCSZmcm0tPlFPU0NhcHNTdGF0aW9uKTsKCglwb3B1bGF0ZV9kb3QxMWZfZXh0X3N1cHBfcmF0ZXMobWFjX2N0eCwKCQlQT1BVTEFURV9ET1QxMUZfUkFURVNfT1BFUkFUSU9OQUwsICZmcm0tPkV4dFN1cHBSYXRlcywKCQlwZV9zZXNzaW9uKTsKCglpZiAobWFjX2N0eC0+cnJtLnJybVBFQ29udGV4dC5ycm1FbmFibGUgJiYKCSAgICBTSVJfTUFDX0dFVF9SUk0ocGVfc2Vzc2lvbi0+bGltQ3VycmVudEJzc0NhcHMpKQoJCXBvcHVsYXRlX2RvdDExZl9ycm1faWUobWFjX2N0eCwgJmZybS0+UlJNRW5hYmxlZENhcCwKCQkJcGVfc2Vzc2lvbik7CgoJLyoKCSAqIFRoZSBqb2luIHJlcXVlc3QgKnNob3VsZCogY29udGFpbiB6ZXJvIG9yIG9uZSBvZiB0aGUgV1BBIGFuZCBSU04KCSAqIElFcy4gIFRoZSBwYXlsb2FkIHNlbmQgYWxvbmcgd2l0aCB0aGUgcmVxdWVzdCBpcyBhCgkgKiAndFNpclNtZUpvaW5SZXEnOyB0aGUgSUUgcG9ydGlvbiBpcyBoZWxkIGluc2lkZSBhICd0U2lyUlNOaWUnOgoJICogICAgIHR5cGVkZWYgc3RydWN0IHNTaXJSU05pZQoJICogICAgIHsKCSAqICAgICAgICAgdWludDE2X3QgICAgICAgbGVuZ3RoOwoJICogICAgICAgICB1aW50OF90ICAgICAgICByc25JRWRhdGFbU0lSX01BQ19NQVhfSUVfTEVOR1RIKzJdOwoJICogICAgIH0gdFNpclJTTmllLCAqdHBTaXJSU05pZTsKCSAqIFNvLCB3ZSBzaG91bGQgYmUgYWJsZSB0byBtYWtlIHRoZSBmb2xsb3dpbmcgdHdvIGNhbGxzIGhhcm1sZXNzbHksCgkgKiBzaW5jZSB0aGV5IGRvIG5vdGhpbmcgaWYgdGhleSBkb24ndCBmaW5kIHRoZSBnaXZlbiBJRSBpbiB0aGUKCSAqIGJ5dGVzdHJlYW0gd2l0aCB3aGljaCB0aGV5J3JlIHByb3ZpZGVkLgoJICogVGhlIG5ldCBlZmZlY3Qgb2YgdGhpcyB3aWxsIGJlIHRvIGZhaXRoZnVsbHkgdHJhbnNtaXQgd2hhdGV2ZXIKCSAqIHNlY3VyaXR5IElFIGlzIGluIHRoZSBqb2luIHJlcXVlc3QuCgkgKiBIb3dldmVyLCBpZiB3ZSdyZSBhc3NvY2lhdGluZyBmb3IgdGhlIHB1cnBvc2Ugb2YgV1BTCgkgKiBlbnJvbGxtZW50LCBhbmQgd2UndmUgYmVlbiBjb25maWd1cmVkIHRvIGluZGljYXRlIHRoYXQgYnkKCSAqIGVsaWRpbmcgdGhlIFdQQSBvciBSU04gSUUsIHdlIGp1c3Qgc2tpcCB0aGlzOgoJICovCglpZiAoYWRkX2llX2xlbiAmJiBhZGRfaWUpCgkJd3BzX2llID0gbGltR2V0V3NjSUVQdHIobWFjX2N0eCwgYWRkX2llLCBhZGRfaWVfbGVuKTsKCglpZiAoTlVMTCA9PSB3cHNfaWUpIHsKCQlwb3B1bGF0ZV9kb3QxMWZfcnNuX29wYXF1ZShtYWNfY3R4LAoJCQkmKHBlX3Nlc3Npb24tPnBMaW1Kb2luUmVxLT5yc25JRSksCgkJCSZmcm0tPlJTTk9wYXF1ZSk7CgkJcG9wdWxhdGVfZG90MTFmX3dwYV9vcGFxdWUobWFjX2N0eCwKCQkJJihwZV9zZXNzaW9uLT5wTGltSm9pblJlcS0+cnNuSUUpLAoJCQkmZnJtLT5XUEFPcGFxdWUpOwojaWYgZGVmaW5lZChGRUFUVVJFX1dMQU5fV0FQSSkKCQlwb3B1bGF0ZV9kb3QxMWZfd2FwaV9vcGFxdWUobWFjX2N0eCwKCQkJJihwZV9zZXNzaW9uLT5wTGltSm9pblJlcS0+cnNuSUUpLAoJCQkmZnJtLT5XQVBJT3BhcXVlKTsKI2VuZGlmIC8qIGRlZmluZWQoRkVBVFVSRV9XTEFOX1dBUEkpICovCgl9CgkvKiBpbmNsdWRlIFdNRSBFRENBIElFIGFzIHdlbGwgKi8KCWlmICh3bWVfZW5hYmxlZCkgewoJCXBvcHVsYXRlX2RvdDExZl93bW1faW5mb19zdGF0aW9uX3Blcl9zZXNzaW9uKG1hY19jdHgsCgkJCXBlX3Nlc3Npb24sICZmcm0tPldNTUluZm9TdGF0aW9uKTsKCgkJaWYgKHdzbV9lbmFibGVkKQoJCQlwb3B1bGF0ZV9kb3QxMWZfd21tX2NhcHMoJmZybS0+V01NQ2Fwcyk7Cgl9CgoJLyoKCSAqIFBvcHVsYXRlIEhUIElFcywgd2hlbiBvcGVyYXRpbmcgaW4gMTFuIGFuZAoJICogd2hlbiBBUCBpcyBhbHNvIG9wZXJhdGluZyBpbiAxMW4gbW9kZQoJICovCglpZiAocGVfc2Vzc2lvbi0+aHRDYXBhYmlsaXR5ICYmCgkgICAgbWFjX2N0eC0+bGltLmh0Q2FwYWJpbGl0eVByZXNlbnRJbkJlYWNvbikgewoJCXBlX2RlYnVnKCJQb3B1bGF0ZSBIVCBDYXBzIGluIEFzc29jIFJlcXVlc3QiKTsKCQlwb3B1bGF0ZV9kb3QxMWZfaHRfY2FwcyhtYWNfY3R4LCBwZV9zZXNzaW9uLCAmZnJtLT5IVENhcHMpOwoJCVFERl9UUkFDRV9IRVhfRFVNUChRREZfTU9EVUxFX0lEX1BFLCBRREZfVFJBQ0VfTEVWRUxfREVCVUcsCgkJCQkgICAmZnJtLT5IVENhcHMsIHNpemVvZihmcm0tPkhUQ2FwcykpOwoJfQoJcGVfZGVidWcoIlN1cHBvcnRlZENobmxXaWR0aDogJWQsIG1pbW9QUzogJWQsIEdGOiAlZCwgc2hvcnQgR0kyMDolZCwgc2hvcnRHSTQwOiAlZCwgZHNzc0NjazogJWQsIEFNUERVIFBhcmFtOiAleCIsCgkJZnJtLT5IVENhcHMuc3VwcG9ydGVkQ2hhbm5lbFdpZHRoU2V0LAoJCWZybS0+SFRDYXBzLm1pbW9Qb3dlclNhdmUsCgkJZnJtLT5IVENhcHMuZ3JlZW5GaWVsZCwgZnJtLT5IVENhcHMuc2hvcnRHSTIwTUh6LAoJCWZybS0+SFRDYXBzLnNob3J0R0k0ME1IeiwKCQlmcm0tPkhUQ2Fwcy5kc3NzQ2NrTW9kZTQwTUh6LAoJCWZybS0+SFRDYXBzLm1heFJ4QU1QRFVGYWN0b3IpOwoKCWlmIChwZV9zZXNzaW9uLT52aHRDYXBhYmlsaXR5ICYmCgkgICAgcGVfc2Vzc2lvbi0+dmh0Q2FwYWJpbGl0eVByZXNlbnRJbkJlYWNvbikgewoJCXBlX2RlYnVnKCJQb3B1bGF0ZSBWSFQgSUVzIGluIEFzc29jIFJlcXVlc3QiKTsKCQlwb3B1bGF0ZV9kb3QxMWZfdmh0X2NhcHMobWFjX2N0eCwgcGVfc2Vzc2lvbiwgJmZybS0+VkhUQ2Fwcyk7CgkJUURGX1RSQUNFX0hFWF9EVU1QKFFERl9NT0RVTEVfSURfUEUsIFFERl9UUkFDRV9MRVZFTF9ERUJVRywKCQkJCSAgICZmcm0tPlZIVENhcHMsIHNpemVvZihmcm0tPlZIVENhcHMpKTsKCQl2aHRfZW5hYmxlZCA9IHRydWU7CgkJaWYgKHBlX3Nlc3Npb24tPmVuYWJsZUh0U21wcyAmJgoJCQkJIXBlX3Nlc3Npb24tPnN1cHBvcnRlZF9uc3NfMXgxKSB7CgkJCXBlX2VycigiVkhUIE9QIG1vZGUgSUUgaW4gQXNzb2MgUmVxIik7CgkJCXBvcHVsYXRlX2RvdDExZl9vcGVyYXRpbmdfbW9kZShtYWNfY3R4LAoJCQkJCSZmcm0tPk9wZXJhdGluZ01vZGUsIHBlX3Nlc3Npb24pOwoJCX0KCX0KCWlmICghdmh0X2VuYWJsZWQgJiYKCQkJcGVfc2Vzc2lvbi0+aXNfdmVuZG9yX3NwZWNpZmljX3ZodGNhcHMpIHsKCQlwZV9kZWJ1ZygiUG9wdWxhdGUgVmVuZG9yIFZIVCBJRXMgaW4gQXNzb2MgUmVxdWVzdCIpOwoJCWZybS0+dmVuZG9yX3ZodF9pZS5wcmVzZW50ID0gMTsKCQlmcm0tPnZlbmRvcl92aHRfaWUudHlwZSA9CgkJCXBlX3Nlc3Npb24tPnZlbmRvcl9zcGVjaWZpY192aHRfaWVfdHlwZTsKCQlmcm0tPnZlbmRvcl92aHRfaWUuc3ViX3R5cGUgPQoJCQlwZV9zZXNzaW9uLT52ZW5kb3Jfc3BlY2lmaWNfdmh0X2llX3N1Yl90eXBlOwoKCQlmcm0tPnZlbmRvcl92aHRfaWUuVkhUQ2Fwcy5wcmVzZW50ID0gMTsKCQlwb3B1bGF0ZV9kb3QxMWZfdmh0X2NhcHMobWFjX2N0eCwgcGVfc2Vzc2lvbiwKCQkJCSZmcm0tPnZlbmRvcl92aHRfaWUuVkhUQ2Fwcyk7CgkJdmh0X2VuYWJsZWQgPSB0cnVlOwoJfQoJaWYgKHBlX3Nlc3Npb24tPmlzX2V4dF9jYXBzX3ByZXNlbnQpCgkJcG9wdWxhdGVfZG90MTFmX2V4dF9jYXAobWFjX2N0eCwgdmh0X2VuYWJsZWQsCgkJCQkmZnJtLT5FeHRDYXAsIHBlX3Nlc3Npb24pOwoKCWlmIChtYWNfY3R4LT5yb2FtLmNvbmZpZ1BhcmFtLnFjbl9pZV9zdXBwb3J0KQoJCXBvcHVsYXRlX2RvdDExZl9xY25faWUoJmZybS0+UUNOX0lFKTsKCglpZiAobGltX2lzX3Nlc3Npb25faGVfY2FwYWJsZShwZV9zZXNzaW9uKSkgewoJCXBlX2RlYnVnKCJQb3B1bGF0ZSBIRSBJRXMiKTsKCQlwb3B1bGF0ZV9kb3QxMWZfaGVfY2FwcyhtYWNfY3R4LCBwZV9zZXNzaW9uLAoJCQkJCSZmcm0tPnZlbmRvcl9oZV9jYXApOwoJfQoKCWlmIChwZV9zZXNzaW9uLT5wTGltSm9pblJlcS0+aXMxMVJjb25uZWN0aW9uKSB7CgkJdFNpckJzc0Rlc2NyaXB0aW9uICpic3NkZXNjcjsKCgkJYnNzZGVzY3IgPSAmcGVfc2Vzc2lvbi0+cExpbUpvaW5SZXEtPmJzc0Rlc2NyaXB0aW9uOwoJCXBlX2RlYnVnKCJtZGllID0gJTAyeCAlMDJ4ICUwMngiLAoJCQkodW5zaWduZWQgaW50KSBic3NkZXNjci0+bWRpZVswXSwKCQkJKHVuc2lnbmVkIGludCkgYnNzZGVzY3ItPm1kaWVbMV0sCgkJCSh1bnNpZ25lZCBpbnQpIGJzc2Rlc2NyLT5tZGllWzJdKTsKCQlwb3B1bGF0ZV9tZGllKG1hY19jdHgsICZmcm0tPk1vYmlsaXR5RG9tYWluLAoJCQlwZV9zZXNzaW9uLT5wTGltSm9pblJlcS0+YnNzRGVzY3JpcHRpb24ubWRpZSk7Cgl9IGVsc2UgewoJCS8qIE5vIDExciBJRXMgZG9udCBzZW5kIGFueSBNRElFICovCgkJcGVfZGVidWcoIk1ESUUgbm90IHByZXNlbnQiKTsKCX0KCiNpZmRlZiBGRUFUVVJFX1dMQU5fRVNFCgkvKgoJICogRVNFIFZlcnNpb24gSUUgd2lsbCBiZSBpbmNsdWRlZCBpbiBhc3NvY2lhdGlvbiByZXF1ZXN0CgkgKiB3aGVuIEVTRSBpcyBlbmFibGVkIG9uIERVVCB0aHJvdWdoIGluaSBhbmQgaXQgaXMgYWxzbwoJICogYWR2ZXJ0aXNlZCBieSB0aGUgcGVlciBBUCB0byB3aGljaCB3ZSBhcmUgdHJ5aW5nIHRvCgkgKiBhc3NvY2lhdGUgdG8uCgkgKi8KCWlmIChwZV9zZXNzaW9uLT5pc19lc2VfdmVyc2lvbl9pZV9wcmVzZW50ICYmCgkJbWFjX2N0eC0+cm9hbS5jb25maWdQYXJhbS5pc0VzZUluaUZlYXR1cmVFbmFibGVkKQoJCXBvcHVsYXRlX2RvdDExZl9lc2VfdmVyc2lvbigmZnJtLT5FU0VWZXJzaW9uKTsKCS8qIEZvciBFU0UgQXNzb2NpYXRpb25zIGZpbGwgdGhlIEVTRSBJRXMgKi8KCWlmIChwZV9zZXNzaW9uLT5pc0VTRWNvbm5lY3Rpb24gJiYKCSAgICBwZV9zZXNzaW9uLT5wTGltSm9pblJlcS0+aXNFU0VGZWF0dXJlSW5pRW5hYmxlZCkgewojaWZuZGVmIEZFQVRVUkVfRElTQUJMRV9STQoJCXBvcHVsYXRlX2RvdDExZl9lc2VfcmFkX21nbXRfY2FwKCZmcm0tPkVTRVJhZE1nbXRDYXApOwojZW5kaWYKCX0KI2VuZGlmCgoJLyoKCSAqIEV4dGNhcCBJRSBub3cgc3VwcG9ydCB2YXJpYWJsZSBsZW5ndGgsIG1lcmdlIEV4dGNhcCBJRSBmcm9tIGFkZG5faWUKCSAqIG1heSBjaGFuZ2UgdGhlIGZyYW1lIHNpemUuIFRoZXJlZm9yZSwgTVVTVCBtZXJnZSBFeHRDYXAgSUUgYmVmb3JlCgkgKiBkb3QxMWYgZ2V0IHBhY2tlZCBwYXlsb2FkIHNpemUuCgkgKi8KCWlmIChleHRyX2V4dF9mbGFnKQoJCWxpbV9tZXJnZV9leHRjYXBfc3RydWN0KCZmcm0tPkV4dENhcCwgJmV4dHJfZXh0X2NhcCwgdHJ1ZSk7CgoJLyogQ2xlYXIgdGhlIGJpdHMgaW4gRVhUQ0FQIElFIGlmIEFQIG5vdCBhZHZlcnRpc2UgaXQgaW4gYmVhY29uICovCglpZiAoZnJtLT5FeHRDYXAucHJlc2VudCAmJiBwZV9zZXNzaW9uLT5pc19leHRfY2Fwc19wcmVzZW50KSB7CgkJaWVfb2Zmc2V0ID0gRE9UMTFGX0ZGX1RJTUVTVEFNUF9MRU4gKwoJCQkJRE9UMTFGX0ZGX0JFQUNPTklOVEVSVkFMX0xFTiArCgkJCQlET1QxMUZfRkZfQ0FQQUJJTElUSUVTX0xFTjsKCgkJcWRmX21lbV96ZXJvKCh1aW50OF90ICopJmJjbl9leHRfY2FwLCBzaXplb2YodERvdDExZklFRXh0Q2FwKSk7CgkJaWYgKHBlX3Nlc3Npb24tPmJlYWNvbiAmJiBwZV9zZXNzaW9uLT5iY25MZW4gPiBpZV9vZmZzZXQpIHsKCQkJYmNuX2llID0gcGVfc2Vzc2lvbi0+YmVhY29uICsgaWVfb2Zmc2V0OwoJCQliY25faWVfbGVuID0gcGVfc2Vzc2lvbi0+YmNuTGVuIC0gaWVfb2Zmc2V0OwoJCQlwX2V4dF9jYXAgPSBsaW1fZ2V0X2llX3B0cl9uZXcobWFjX2N0eCwKCQkJCQkJCWJjbl9pZSwKCQkJCQkJCWJjbl9pZV9sZW4sCgkJCQkJCQlET1QxMUZfRUlEX0VYVENBUCwKCQkJCQkJCU9ORV9CWVRFKTsKCQkJbGltX3VwZGF0ZV9leHRjYXBfc3RydWN0KG1hY19jdHgsIHBfZXh0X2NhcCwKCQkJCQkJCSZiY25fZXh0X2NhcCk7CgkJCWxpbV9tZXJnZV9leHRjYXBfc3RydWN0KCZmcm0tPkV4dENhcCwgJmJjbl9leHRfY2FwLAoJCQkJCQkJZmFsc2UpOwoJCX0KCX0KCglpZiAoZVNJUl9TVUNDRVNTICE9IGxpbV9zdHJpcF9zdXBwX29wX2NsYXNzX3VwZGF0ZV9zdHJ1Y3QobWFjX2N0eCwKCQkJYWRkX2llLCAmYWRkX2llX2xlbiwgJmZybS0+U3VwcE9wZXJhdGluZ0NsYXNzZXMpKQoJCXBlX2RlYnVnKCJVbmFibGUgdG8gU3RyaXBvZmYgc3VwcCBvcCBjbGFzc2VzIElFIGZyb20gQXNzb2MgUmVxIik7CgoJc3RhdHVzID0gZG90MTFmX2dldF9wYWNrZWRfYXNzb2NfcmVxdWVzdF9zaXplKG1hY19jdHgsIGZybSwgJnBheWxvYWQpOwoJaWYgKERPVDExRl9GQUlMRUQoc3RhdHVzKSkgewoJCXBlX2VycigiQXNzb2NpYXRpb24gUmVxdWVzdCBwYWNrZXQgc2l6ZSBmYWlsdXJlKDB4JTA4eCkiLAoJCQlzdGF0dXMpOwoJCS8qIFdlJ2xsIGZhbGwgYmFjayBvbiB0aGUgd29yc3QgY2FzZSBzY2VuYXJpbzogKi8KCQlwYXlsb2FkID0gc2l6ZW9mKHREb3QxMWZBc3NvY1JlcXVlc3QpOwoJfSBlbHNlIGlmIChET1QxMUZfV0FSTkVEKHN0YXR1cykpIHsKCQlwZV93YXJuKCJBc3NvY2lhdGlvbiByZXF1ZXN0IHBhY2tldCBzaXplIHdhcm5pbmcgKDB4JTA4eCkiLAoJCQlzdGF0dXMpOwoJfQoKCWJ5dGVzID0gcGF5bG9hZCArIHNpemVvZih0U2lyTWFjTWdtdEhkcikgKyBhZGRfaWVfbGVuOwoKCXFkZl9zdGF0dXMgPSBjZHNfcGFja2V0X2FsbG9jKCh1aW50MTZfdCkgYnl0ZXMsICh2b2lkICoqKSZmcmFtZSwKCQkJCSh2b2lkICoqKSZwYWNrZXQpOwoJaWYgKCFRREZfSVNfU1RBVFVTX1NVQ0NFU1MocWRmX3N0YXR1cykpIHsKCQlwZV9lcnIoIkZhaWxlZCB0byBhbGxvY2F0ZSAlZCBieXRlcyIsIGJ5dGVzKTsKCgkJcGVfc2Vzc2lvbi0+bGltTWxtU3RhdGUgPSBwZV9zZXNzaW9uLT5saW1QcmV2TWxtU3RhdGU7CgkJTVRSQUNFKHFkZl90cmFjZShRREZfTU9EVUxFX0lEX1BFLCBUUkFDRV9DT0RFX01MTV9TVEFURSwKCQkJCSBwZV9zZXNzaW9uLT5wZVNlc3Npb25JZCwKCQkJCSBwZV9zZXNzaW9uLT5saW1NbG1TdGF0ZSkpOwoKCQkvKiBVcGRhdGUgUEUgc2Vzc2lvbiBpZCAqLwoJCWFzc29jX2NuZi5zZXNzaW9uSWQgPSBwZV9zZXNzaW9uLT5wZVNlc3Npb25JZDsKCgkJYXNzb2NfY25mLnJlc3VsdENvZGUgPSBlU0lSX1NNRV9SRVNPVVJDRVNfVU5BVkFJTEFCTEU7CgoJCWNkc19wYWNrZXRfZnJlZSgodm9pZCAqKXBhY2tldCk7CgoJCWxpbV9wb3N0X3NtZV9tZXNzYWdlKG1hY19jdHgsIExJTV9NTE1fQVNTT0NfQ05GLAoJCQkodWludDMyX3QgKikgJmFzc29jX2NuZik7CgoJCWdvdG8gZW5kOwoJfQoJLyogUGFyYW5vaWE6ICovCglxZGZfbWVtX3NldChmcmFtZSwgYnl0ZXMsIDApOwoKCS8qIE5leHQsIHdlIGZpbGwgb3V0IHRoZSBidWZmZXIgZGVzY3JpcHRvcjogKi8KCWxpbV9wb3B1bGF0ZV9tYWNfaGVhZGVyKG1hY19jdHgsIGZyYW1lLCBTSVJfTUFDX01HTVRfRlJBTUUsCgkJU0lSX01BQ19NR01UX0FTU09DX1JFUSwgcGVfc2Vzc2lvbi0+YnNzSWQsCgkJcGVfc2Vzc2lvbi0+c2VsZk1hY0FkZHIpOwoJLyogVGhhdCBkb25lLCBwYWNrIHRoZSBBc3NvYyBSZXF1ZXN0OiAqLwoJc3RhdHVzID0gZG90MTFmX3BhY2tfYXNzb2NfcmVxdWVzdChtYWNfY3R4LCBmcm0sCgkJCWZyYW1lICsgc2l6ZW9mKHRTaXJNYWNNZ210SGRyKSwgcGF5bG9hZCwgJnBheWxvYWQpOwoJaWYgKERPVDExRl9GQUlMRUQoc3RhdHVzKSkgewoJCXBlX2VycigiQXNzb2MgcmVxdWVzdCBwYWNrIGZhaWx1cmUgKDB4JTA4eCkiLCBzdGF0dXMpOwoJCWNkc19wYWNrZXRfZnJlZSgodm9pZCAqKXBhY2tldCk7CgkJZ290byBlbmQ7Cgl9IGVsc2UgaWYgKERPVDExRl9XQVJORUQoc3RhdHVzKSkgewoJCXBlX3dhcm4oIkFzc29jIHJlcXVlc3QgcGFjayB3YXJuaW5nICgweCUwOHgpIiwgc3RhdHVzKTsKCX0KCglwZV9kZWJ1ZygiU2VuZGluZyBBc3NvY2lhdGlvbiBSZXF1ZXN0IGxlbmd0aCAlZCB0byAiLCBieXRlcyk7CglpZiAocGVfc2Vzc2lvbi0+YXNzb2NSZXEgIT0gTlVMTCkgewoJCXFkZl9tZW1fZnJlZShwZV9zZXNzaW9uLT5hc3NvY1JlcSk7CgkJcGVfc2Vzc2lvbi0+YXNzb2NSZXEgPSBOVUxMOwoJCXBlX3Nlc3Npb24tPmFzc29jUmVxTGVuID0gMDsKCX0KCglpZiAoYWRkX2llX2xlbikgewoJCXFkZl9tZW1fY29weShmcmFtZSArIHNpemVvZih0U2lyTWFjTWdtdEhkcikgKyBwYXlsb2FkLAoJCQkgICAgIGFkZF9pZSwgYWRkX2llX2xlbik7CgkJcGF5bG9hZCArPSBhZGRfaWVfbGVuOwoJfQoKCXBlX3Nlc3Npb24tPmFzc29jUmVxID0gcWRmX21lbV9tYWxsb2MocGF5bG9hZCk7CglpZiAoTlVMTCA9PSBwZV9zZXNzaW9uLT5hc3NvY1JlcSkgewoJCXBlX2VycigiVW5hYmxlIHRvIGFsbG9jYXRlIG1lbW9yeSIpOwoJfSBlbHNlIHsKCQkvKgoJCSAqIFN0b3JlIHRoZSBBc3NvYyByZXF1ZXN0LiBUaGlzIGlzIHNlbnQgdG8gY3NyL2hkZCBpbgoJCSAqIGpvaW4gY25mIHJlc3BvbnNlLgoJCSAqLwoJCXFkZl9tZW1fY29weShwZV9zZXNzaW9uLT5hc3NvY1JlcSwKCQkJICAgICBmcmFtZSArIHNpemVvZih0U2lyTWFjTWdtdEhkciksIHBheWxvYWQpOwoJCXBlX3Nlc3Npb24tPmFzc29jUmVxTGVuID0gcGF5bG9hZDsKCX0KCglpZiAoKFNJUl9CQU5EXzVfR0haID09IGxpbV9nZXRfcmZfYmFuZChwZV9zZXNzaW9uLT5jdXJyZW50T3BlckNoYW5uZWwpKQoJICAgIHx8IChwZV9zZXNzaW9uLT5wZVBlcnNvbmEgPT0gUURGX1AyUF9DTElFTlRfTU9ERSkKCSAgICB8fCAocGVfc2Vzc2lvbi0+cGVQZXJzb25hID09IFFERl9QMlBfR09fTU9ERSkKCSAgICApCgkJdHhfZmxhZyB8PSBIQUxfVVNFX0JEX1JBVEUyX0ZPUl9NQU5BR0VNRU5UX0ZSQU1FOwoKCWlmIChwZV9zZXNzaW9uLT5wZVBlcnNvbmEgPT0gUURGX1AyUF9DTElFTlRfTU9ERSB8fAoJCXBlX3Nlc3Npb24tPnBlUGVyc29uYSA9PSBRREZfU1RBX01PREUpCgkJdHhfZmxhZyB8PSBIQUxfVVNFX1BFRVJfU1RBX1JFUVVFU1RFRF9NQVNLOwoKI2lmZGVmIEZFQVRVUkVfV0xBTl9ESUFHX1NVUFBPUlQKCWxpbV9kaWFnX2V2ZW50X3JlcG9ydChtYWNfY3R4LCBXTEFOX1BFX0RJQUdfQVNTT0NfU1RBUlRfRVZFTlQsCgkJCSAgICAgIHBlX3Nlc3Npb24sIGVTSVJfU1VDQ0VTUywgZVNJUl9TVUNDRVNTKTsKI2VuZGlmCgltYWNfaGRyID0gKHRwU2lyTWFjTWdtdEhkcikgZnJhbWU7CglNVFJBQ0UocWRmX3RyYWNlKFFERl9NT0RVTEVfSURfUEUsIFRSQUNFX0NPREVfVFhfTUdNVCwKCQkJIHBlX3Nlc3Npb24tPnBlU2Vzc2lvbklkLCBtYWNfaGRyLT5mYy5zdWJUeXBlKSk7CglxZGZfc3RhdHVzID0KCQl3bWFfdHhfZnJhbWUobWFjX2N0eCwgcGFja2V0LAoJCQkgICAodWludDE2X3QpIChzaXplb2YodFNpck1hY01nbXRIZHIpICsgcGF5bG9hZCksCgkJCSAgIFRYUlhfRlJNXzgwMl8xMV9NR01ULCBBTklfVFhESVJfVE9EUywgNywKCQkJICAgbGltX3R4X2NvbXBsZXRlLCBmcmFtZSwgdHhfZmxhZywgc21lX3Nlc3Npb25pZCwgMCk7CglNVFJBQ0UocWRmX3RyYWNlCgkJICAgICAgIChRREZfTU9EVUxFX0lEX1BFLCBUUkFDRV9DT0RFX1RYX0NPTVBMRVRFLAoJCSAgICAgICBwZV9zZXNzaW9uLT5wZVNlc3Npb25JZCwgcWRmX3N0YXR1cykpOwoJaWYgKCFRREZfSVNfU1RBVFVTX1NVQ0NFU1MocWRmX3N0YXR1cykpIHsKCQlwZV9lcnIoIkZhaWxlZCB0byBzZW5kIEFzc29jaWF0aW9uIFJlcXVlc3QgKCVYKSEiLAoJCQlxZGZfc3RhdHVzKTsKCQkvKiBQa3Qgd2lsbCBiZSBmcmVlZCB1cCBieSB0aGUgY2FsbGJhY2sgKi8KCX0KZW5kOgoJLyogRnJlZSB1cCBidWZmZXIgYWxsb2NhdGVkIGZvciBtbG1fYXNzb2NfcmVxICovCglxZGZfbWVtX2ZyZWUobWxtX2Fzc29jX3JlcSk7CgltbG1fYXNzb2NfcmVxID0gTlVMTDsKCXFkZl9tZW1fZnJlZShmcm0pOwoJcmV0dXJuOwp9CgovKioKICogbGltX2F1dGhfdHhfY29tcGxldGVfY25mKCktIENvbmZpcm1hdGlvbiBmb3IgYXV0aCBzZW50IG92ZXIgdGhlIGFpcgogKiBAY29udGV4dDogcG9pbnRlciB0byBnbG9iYWwgbWFjCiAqIEBidWY6IGJ1ZmZlcgogKiBAdHhfY29tcGxldGUgOiBTZW50IHN0YXR1cwogKiBAcGFyYW1zOyB0eCBjb21wbGV0aW9uIHBhcmFtcwogKgogKiBSZXR1cm46IFRoaXMgcmV0dXJucyBRREZfU1RBVFVTCiAqLwoKc3RhdGljIFFERl9TVEFUVVMgbGltX2F1dGhfdHhfY29tcGxldGVfY25mKHZvaWQgKmNvbnRleHQsCgkJCQkJICAgcWRmX25idWZfdCBidWYsCgkJCQkJICAgdWludDMyX3QgdHhfY29tcGxldGUsCgkJCQkJICAgdm9pZCAqcGFyYW1zKQp7Cgl0cEFuaVNpckdsb2JhbCBtYWNfY3R4ID0gKHRwQW5pU2lyR2xvYmFsKWNvbnRleHQ7CgoJcGVfZGVidWcoInR4X2NvbXBsZXRlPSAlZCIsIHR4X2NvbXBsZXRlKTsKCWlmICh0eF9jb21wbGV0ZSkgewoJCW1hY19jdHgtPmF1dGhfYWNrX3N0YXR1cyA9IExJTV9BVVRIX0FDS19SQ0RfU1VDQ0VTUzsKCQkvKiAnQ2hhbmdlJyB0aW1lciBmb3IgZnV0dXJlIGFjdGl2YXRpb25zICovCgkJbGltX2RlYWN0aXZhdGVfYW5kX2NoYW5nZV90aW1lcihtYWNfY3R4LCBlTElNX0FVVEhfUkVUUllfVElNRVIpOwoJfSBlbHNlIHsKCQltYWNfY3R4LT5hdXRoX2Fja19zdGF0dXMgPSBMSU1fQVVUSF9BQ0tfUkNEX0ZBSUxVUkU7Cgl9CgoJaWYgKGJ1ZikKCQlxZGZfbmJ1Zl9mcmVlKGJ1Zik7CgoJcmV0dXJuIFFERl9TVEFUVVNfU1VDQ0VTUzsKfQoKLyoqCiAqIGxpbV9zZW5kX2F1dGhfbWdtdF9mcmFtZSgpIC0gU2VuZCBhbiBBdXRoZW50aWNhdGlvbiBmcmFtZQogKgogKiBAbWFjX2N0eDogUG9pbnRlciB0byBHbG9iYWwgTUFDIHN0cnVjdHVyZQogKiBAYXV0aF9mcmFtZTogUG9pbnRlciB0byBBdXRoZW50aWNhdGlvbiBmcmFtZSBzdHJ1Y3R1cmUKICogQHBlZXJfYWRkcjogTUFDIGFkZHJlc3Mgb2YgZGVzdGluYXRpb24gcGVlcgogKiBAd2VwX2JpdDogd2VwIGJpdCBpbiBmcmFtZSBjb250cm9sIGZvciBBdXRoZW50aWNhdGlvbiBmcmFtZTMKICogQHNlc3Npb246IFBFIHNlc3Npb24gaW5mb3JtYXRpb24KICoKICogVGhpcyBmdW5jdGlvbiBpcyBjYWxsZWQgYnkgbGltX3Byb2Nlc3NfbWxtX21lc3NhZ2VzKCkuIEF1dGhlbnRpY2F0aW9uIGZyYW1lCiAqIGlzIGZvcm1hdHRlZCBhbmQgc2VudCB3aGVuIHRoaXMgZnVuY3Rpb24gaXMgY2FsbGVkLgogKgogKiBSZXR1cm46IHZvaWQKICovCgp2b2lkCmxpbV9zZW5kX2F1dGhfbWdtdF9mcmFtZSh0cEFuaVNpckdsb2JhbCBtYWNfY3R4LAoJCQkgdHBTaXJNYWNBdXRoRnJhbWVCb2R5IGF1dGhfZnJhbWUsCgkJCSB0U2lyTWFjQWRkciBwZWVyX2FkZHIsCgkJCSB1aW50OF90IHdlcF9iaXQsCgkJCSB0cFBFU2Vzc2lvbiBzZXNzaW9uLCBib29sIHdhaXRfZm9yX2FjaykKewoJdWludDhfdCAqZnJhbWUsICpib2R5OwoJdWludDMyX3QgZnJhbWVfbGVuID0gMCwgYm9keV9sZW4gPSAwOwoJdHBTaXJNYWNNZ210SGRyIG1hY19oZHI7Cgl2b2lkICpwYWNrZXQ7CglRREZfU1RBVFVTIHFkZl9zdGF0dXM7Cgl1aW50OF90IHR4X2ZsYWcgPSAwOwoJdWludDhfdCBzbWVfc2Vzc2lvbmlkID0gMDsKCXVpbnQxNl90IGZ0X2llc19sZW5ndGggPSAwOwoJYm9vbCBjaGFsbGVuZ2VfcmVxID0gZmFsc2U7CgoJaWYgKE5VTEwgPT0gc2Vzc2lvbikgewoJCXBlX2VycigiRXJyb3I6IHBzZXNzaW9uIEVudHJ5IGlzIE5VTEwiKTsKCQlyZXR1cm47Cgl9CgoJc21lX3Nlc3Npb25pZCA9IHNlc3Npb24tPnNtZVNlc3Npb25JZDsKCglpZiAod2VwX2JpdCA9PSBMSU1fV0VQX0lOX0ZDKSB7CgkJLyoKCQkgKiBBdXRoIGZyYW1lMyB0byBiZSBzZW50IHdpdGggZW5jcnlwdGVkIGZyYW1lYm9keQoJCSAqCgkJICogQWxsb2NhdGUgYnVmZmVyIGZvciBBdXRoZW50aWNhdG9uIGZyYW1lIG9mIHNpemUKCQkgKiBlcXVhbCB0byBtYW5hZ2VtZW50IGZyYW1lIGhlYWRlciBsZW5ndGggcGx1cyAyIGJ5dGVzCgkJICogZWFjaCBmb3IgYXV0aCBhbGdvcml0aG0gbnVtYmVyLCB0cmFuc2FjdGlvbiBudW1iZXIsCgkJICogc3RhdHVzIGNvZGUsIDEyOCBieXRlcyBmb3IgY2hhbGxlbmdlIHRleHQgYW5kCgkJICogNCBieXRlcyBlYWNoIGZvciBJViAmIElDVi4KCQkgKi8KCQlwZV9kZWJ1ZygiU2VuZGluZyBlbmNyeXB0ZWQgYXV0aCBmcmFtZSB0byAiIE1BQ19BRERSRVNTX1NUUiwKCQkJCU1BQ19BRERSX0FSUkFZKHBlZXJfYWRkcikpOwoKCQlib2R5X2xlbiA9IExJTV9FTkNSX0FVVEhfQk9EWV9MRU47CgkJZnJhbWVfbGVuID0gc2l6ZW9mKHRTaXJNYWNNZ210SGRyKSArIGJvZHlfbGVuOwoKCQlnb3RvIGFsbG9jX3BhY2tldDsKCX0KCglwZV9pbmZvKCJTZW5kaW5nIEF1dGggc2VxIyAlZCBzdGF0dXMgJWQgKCVkKSB3YWl0X2Zvcl9hY2sgJWQgdG8gIgoJCU1BQ19BRERSRVNTX1NUUiwKCQlhdXRoX2ZyYW1lLT5hdXRoVHJhbnNhY3Rpb25TZXFOdW1iZXIsCgkJYXV0aF9mcmFtZS0+YXV0aFN0YXR1c0NvZGUsCgkJKGF1dGhfZnJhbWUtPmF1dGhTdGF0dXNDb2RlID09IGVTSVJfTUFDX1NVQ0NFU1NfU1RBVFVTKSwKCQl3YWl0X2Zvcl9hY2ssCgkJTUFDX0FERFJfQVJSQVkocGVlcl9hZGRyKSk7CgoJc3dpdGNoIChhdXRoX2ZyYW1lLT5hdXRoVHJhbnNhY3Rpb25TZXFOdW1iZXIpIHsKCWNhc2UgU0lSX01BQ19BVVRIX0ZSQU1FXzE6CgkJLyoKCQkgKiBBbGxvY2F0ZSBidWZmZXIgZm9yIEF1dGhlbnRpY2F0b24gZnJhbWUgb2Ygc2l6ZQoJCSAqIGVxdWFsIHRvIG1hbmFnZW1lbnQgZnJhbWUgaGVhZGVyIGxlbmd0aCBwbHVzIDIgYnl0ZXMKCQkgKiBlYWNoIGZvciBhdXRoIGFsZ29yaXRobSBudW1iZXIsIHRyYW5zYWN0aW9uIG51bWJlcgoJCSAqIGFuZCBzdGF0dXMgY29kZS4KCQkgKi8KCgkJYm9keV9sZW4gPSBTSVJfTUFDX0FVVEhfRlJBTUVfSU5GT19MRU47CgkJZnJhbWVfbGVuID0gc2l6ZW9mKHRTaXJNYWNNZ210SGRyKSArIGJvZHlfbGVuOwoKCQlpZiAoYXV0aF9mcmFtZS0+YXV0aEFsZ29OdW1iZXIgPT0gZVNJUl9GVF9BVVRIKSB7CgkJCWlmIChOVUxMICE9IHNlc3Npb24tPmZ0UEVDb250ZXh0LnBGVFByZUF1dGhSZXEgJiYKCQkJICAgIDAgIT0gc2Vzc2lvbi0+ZnRQRUNvbnRleHQucEZUUHJlQXV0aFJlcS0+CgkJCQlmdF9pZXNfbGVuZ3RoKSB7CgkJCQlmdF9pZXNfbGVuZ3RoID0gc2Vzc2lvbi0+ZnRQRUNvbnRleHQuCgkJCQkJcEZUUHJlQXV0aFJlcS0+ZnRfaWVzX2xlbmd0aDsKCQkJCWZyYW1lX2xlbiArPSBmdF9pZXNfbGVuZ3RoOwoJCQkJcGVfZGVidWcoIkF1dGggZnJhbWUsIEZUSUVTIGxlbmd0aCBhZGRlZD0lZCIsCgkJCQkJZnRfaWVzX2xlbmd0aCk7CgkJCX0gZWxzZSB7CgkJCQlwZV9kZWJ1ZygiQXV0aCBmcmFtZSwgRG9lcyBub3QgY29udGFpbiBGVElFUyEiKTsKCQkJCWZyYW1lX2xlbiArPSAoMiArIFNJUl9NRElFX1NJWkUpOwoJCQl9CgkJfQoJCWJyZWFrOwoKCWNhc2UgU0lSX01BQ19BVVRIX0ZSQU1FXzI6CgkJaWYgKChhdXRoX2ZyYW1lLT5hdXRoQWxnb051bWJlciA9PSBlU0lSX09QRU5fU1lTVEVNKSB8fAoJCSAgICAoKGF1dGhfZnJhbWUtPmF1dGhBbGdvTnVtYmVyID09IGVTSVJfU0hBUkVEX0tFWSkgJiYKCQkJKGF1dGhfZnJhbWUtPmF1dGhTdGF0dXNDb2RlICE9CgkJCSBlU0lSX01BQ19TVUNDRVNTX1NUQVRVUykpKSB7CgkJCS8qCgkJCSAqIEFsbG9jYXRlIGJ1ZmZlciBmb3IgQXV0aGVudGljYXRvbiBmcmFtZSBvZiBzaXplCgkJCSAqIGVxdWFsIHRvIG1hbmFnZW1lbnQgZnJhbWUgaGVhZGVyIGxlbmd0aCBwbHVzCgkJCSAqIDIgYnl0ZXMgZWFjaCBmb3IgYXV0aCBhbGdvcml0aG0gbnVtYmVyLAoJCQkgKiB0cmFuc2FjdGlvbiBudW1iZXIgYW5kIHN0YXR1cyBjb2RlLgoJCQkgKi8KCgkJCWJvZHlfbGVuID0gU0lSX01BQ19BVVRIX0ZSQU1FX0lORk9fTEVOOwoJCQlmcmFtZV9sZW4gPSBzaXplb2YodFNpck1hY01nbXRIZHIpICsgYm9keV9sZW47CgkJfSBlbHNlIHsKCQkJLyoKCQkJICogU2hhcmVkIEtleSBhbGdvcml0aG0gd2l0aCBjaGFsbGVuZ2UgdGV4dAoJCQkgKiB0byBiZSBzZW50LgoJCQkgKgoJCQkgKiBBbGxvY2F0ZSBidWZmZXIgZm9yIEF1dGhlbnRpY2F0b24gZnJhbWUgb2Ygc2l6ZQoJCQkgKiBlcXVhbCB0byBtYW5hZ2VtZW50IGZyYW1lIGhlYWRlciBsZW5ndGggcGx1cwoJCQkgKiAyIGJ5dGVzIGVhY2ggZm9yIGF1dGggYWxnb3JpdGhtIG51bWJlciwKCQkJICogdHJhbnNhY3Rpb24gbnVtYmVyLCBzdGF0dXMgY29kZSBhbmQgMTI4IGJ5dGVzCgkJCSAqIGZvciBjaGFsbGVuZ2UgdGV4dC4KCQkJICovCgoJCQljaGFsbGVuZ2VfcmVxID0gdHJ1ZTsKCQkJYm9keV9sZW4gPSBTSVJfTUFDX0FVVEhfRlJBTUVfSU5GT19MRU4gKwoJCQkJCVNJUl9NQUNfQVVUSF9DSEFMTEVOR0VfQk9EWV9MRU47CgkJCWZyYW1lX2xlbiA9IHNpemVvZih0U2lyTWFjTWdtdEhkcikgKyBib2R5X2xlbjsKCQl9CgkJYnJlYWs7CgoJY2FzZSBTSVJfTUFDX0FVVEhfRlJBTUVfMzoKCQkvKgoJCSAqIEF1dGggZnJhbWUzIHRvIGJlIHNlbnQgd2l0aG91dCBlbmNyeXB0ZWQgZnJhbWVib2R5CgkJICoKCQkgKiBBbGxvY2F0ZSBidWZmZXIgZm9yIEF1dGhlbnRpY2F0b24gZnJhbWUgb2Ygc2l6ZSBlcXVhbAoJCSAqIHRvIG1hbmFnZW1lbnQgZnJhbWUgaGVhZGVyIGxlbmd0aCBwbHVzIDIgYnl0ZXMgZWFjaAoJCSAqIGZvciBhdXRoIGFsZ29yaXRobSBudW1iZXIsIHRyYW5zYWN0aW9uIG51bWJlciBhbmQKCQkgKiBzdGF0dXMgY29kZS4KCQkgKi8KCgkJYm9keV9sZW4gPSBTSVJfTUFDX0FVVEhfRlJBTUVfSU5GT19MRU47CgkJZnJhbWVfbGVuID0gc2l6ZW9mKHRTaXJNYWNNZ210SGRyKSArIGJvZHlfbGVuOwoJCWJyZWFrOwoKCWNhc2UgU0lSX01BQ19BVVRIX0ZSQU1FXzQ6CgkJLyoKCQkgKiBBbGxvY2F0ZSBidWZmZXIgZm9yIEF1dGhlbnRpY2F0b24gZnJhbWUgb2Ygc2l6ZSBlcXVhbAoJCSAqIHRvIG1hbmFnZW1lbnQgZnJhbWUgaGVhZGVyIGxlbmd0aCBwbHVzIDIgYnl0ZXMgZWFjaAoJCSAqIGZvciBhdXRoIGFsZ29yaXRobSBudW1iZXIsIHRyYW5zYWN0aW9uIG51bWJlciBhbmQKCQkgKiBzdGF0dXMgY29kZS4KCQkgKi8KCgkJYm9keV9sZW4gPSBTSVJfTUFDX0FVVEhfRlJBTUVfSU5GT19MRU47CgkJZnJhbWVfbGVuID0gc2l6ZW9mKHRTaXJNYWNNZ210SGRyKSArIGJvZHlfbGVuOwoKCQlicmVhazsKCWRlZmF1bHQ6CgkJcGVfZXJyKCJJbnZhbGlkIGF1dGggdHJhbnNhY3Rpb24gc2VxIG51bSIpOwoJCXJldHVybjsKCX0gLyogc3dpdGNoIChhdXRoX2ZyYW1lLT5hdXRoVHJhbnNhY3Rpb25TZXFOdW1iZXIpICovCgphbGxvY19wYWNrZXQ6CglxZGZfc3RhdHVzID0gY2RzX3BhY2tldF9hbGxvYygodWludDE2X3QpIGZyYW1lX2xlbiwgKHZvaWQgKiopJmZyYW1lLAoJCQkJICh2b2lkICoqKSZwYWNrZXQpOwoKCWlmICghUURGX0lTX1NUQVRVU19TVUNDRVNTKHFkZl9zdGF0dXMpKSB7CgkJcGVfZXJyKCJjYWxsIHRvIGJ1ZkFsbG9jIGZhaWxlZCBmb3IgQVVUSCBmcmFtZSIpOwoJCXJldHVybjsKCX0KCglxZGZfbWVtX3plcm8oZnJhbWUsIGZyYW1lX2xlbik7CgoJLyogUHJlcGFyZSBCRCAqLwoJbGltX3BvcHVsYXRlX21hY19oZWFkZXIobWFjX2N0eCwgZnJhbWUsIFNJUl9NQUNfTUdNVF9GUkFNRSwKCQlTSVJfTUFDX01HTVRfQVVUSCwgcGVlcl9hZGRyLCBzZXNzaW9uLT5zZWxmTWFjQWRkcik7CgltYWNfaGRyID0gKHRwU2lyTWFjTWdtdEhkcikgZnJhbWU7CgltYWNfaGRyLT5mYy53ZXAgPSB3ZXBfYml0OwoKCS8qIFByZXBhcmUgQlNTSWQgKi8KCWlmIChMSU1fSVNfQVBfUk9MRShzZXNzaW9uKSkKCQlxZGZfbWVtX2NvcHkoKHVpbnQ4X3QgKikgbWFjX2hkci0+YnNzSWQsCgkJCSAgICAgKHVpbnQ4X3QgKikgc2Vzc2lvbi0+YnNzSWQsCgkJCSAgICAgc2l6ZW9mKHRTaXJNYWNBZGRyKSk7CgoJLyogUHJlcGFyZSBBdXRoZW50aWNhdGlvbiBmcmFtZSBib2R5ICovCglib2R5ID0gZnJhbWUgKyBzaXplb2YodFNpck1hY01nbXRIZHIpOwoKCWlmICh3ZXBfYml0ID09IExJTV9XRVBfSU5fRkMpIHsKCQlxZGZfbWVtX2NvcHkoYm9keSwgKHVpbnQ4X3QgKikgYXV0aF9mcmFtZSwgYm9keV9sZW4pOwoKCQlwZV9kZWJ1ZygiU2VuZGluZyBBdXRoIHNlcSMgMyB0byAiIE1BQ19BRERSRVNTX1NUUiwKCQkJTUFDX0FERFJfQVJSQVkobWFjX2hkci0+ZGEpKTsKCgl9IGVsc2UgewoJCSooKHVpbnQxNl90ICopIChib2R5KSkgPQoJCQlzaXJfc3dhcF91MTZpZl9uZWVkZWQoYXV0aF9mcmFtZS0+YXV0aEFsZ29OdW1iZXIpOwoJCWJvZHkgKz0gc2l6ZW9mKHVpbnQxNl90KTsKCQlib2R5X2xlbiAtPSBzaXplb2YodWludDE2X3QpOwoKCQkqKCh1aW50MTZfdCAqKSAoYm9keSkpID0KCQkJc2lyX3N3YXBfdTE2aWZfbmVlZGVkKAoJCQkJYXV0aF9mcmFtZS0+YXV0aFRyYW5zYWN0aW9uU2VxTnVtYmVyKTsKCQlib2R5ICs9IHNpemVvZih1aW50MTZfdCk7CgkJYm9keV9sZW4gLT0gc2l6ZW9mKHVpbnQxNl90KTsKCgkJKigodWludDE2X3QgKikgKGJvZHkpKSA9CgkJCXNpcl9zd2FwX3UxNmlmX25lZWRlZChhdXRoX2ZyYW1lLT5hdXRoU3RhdHVzQ29kZSk7CgkJYm9keSArPSBzaXplb2YodWludDE2X3QpOwoJCWJvZHlfbGVuIC09IHNpemVvZih1aW50MTZfdCk7CgoJCWlmIChjaGFsbGVuZ2VfcmVxKSB7CgkJCWlmIChib2R5X2xlbiA8IFNJUl9NQUNfQVVUSF9DSEFMTEVOR0VfQk9EWV9MRU4pIHsKCQkJCXFkZl9tZW1fY29weShib2R5LCAodWludDhfdCAqKSZhdXRoX2ZyYW1lLT50eXBlLAoJCQkJCSAgICAgYm9keV9sZW4pOwoJCQkJcGVfZXJyKCJJbmNvbXBsZXRlIGNoYWxsZW5nZSBpbmZvOiBsZW5ndGg6ICVkLCBleHBlY3RlZDogJWQiLAoJCQkJICAgICAgIGJvZHlfbGVuLAoJCQkJICAgICAgIFNJUl9NQUNfQVVUSF9DSEFMTEVOR0VfQk9EWV9MRU4pOwoJCQkJYm9keSArPSBib2R5X2xlbjsKCQkJCWJvZHlfbGVuID0gMDsKCQkJfSBlbHNlIHsKCQkJCS8qIGNvcHkgY2hhbGxlbmdlIElFIGlkLCBsZW4sIGNoYWxsZW5nZSB0ZXh0ICovCgkJCQkqYm9keSA9IGF1dGhfZnJhbWUtPnR5cGU7CgkJCQlib2R5Kys7CgkJCQkqYm9keSA9IGF1dGhfZnJhbWUtPmxlbmd0aDsKCQkJCWJvZHkrKzsKCQkJCXFkZl9tZW1fY29weShib2R5LCBhdXRoX2ZyYW1lLT5jaGFsbGVuZ2VUZXh0LAoJCQkJCSAgICAgU0lSX01BQ19BVVRIX0NIQUxMRU5HRV9MRU5HVEgpOwoJCQkJYm9keSArPSBTSVJfTUFDX0FVVEhfQ0hBTExFTkdFX0xFTkdUSDsKCgkJCQlib2R5X2xlbiAtPSBTSVJfTUFDX0FVVEhfQ0hBTExFTkdFX0JPRFlfTEVOOwoJCQl9CgkJfQoKCQlpZiAoKGF1dGhfZnJhbWUtPmF1dGhBbGdvTnVtYmVyID09IGVTSVJfRlRfQVVUSCkgJiYKCQkgICAgKGF1dGhfZnJhbWUtPmF1dGhUcmFuc2FjdGlvblNlcU51bWJlciA9PQoJCSAgICAgU0lSX01BQ19BVVRIX0ZSQU1FXzEpICYmCgkJICAgICAoc2Vzc2lvbi0+ZnRQRUNvbnRleHQucEZUUHJlQXV0aFJlcSAhPSBOVUxMKSkgewoKCQkJaWYgKGZ0X2llc19sZW5ndGggPiAwKSB7CgkJCQlxZGZfbWVtX2NvcHkoYm9keSwKCQkJCQlzZXNzaW9uLT5mdFBFQ29udGV4dC4KCQkJCQkJcEZUUHJlQXV0aFJlcS0+ZnRfaWVzLAoJCQkJCWZ0X2llc19sZW5ndGgpOwoJCQkJcGVfZGVidWcoIkF1dGgxIEZyYW1lIEZUSUUgaXM6ICIpOwoJCQkJUURGX1RSQUNFX0hFWF9EVU1QKFFERl9NT0RVTEVfSURfUEUsCgkJCQkJCSAgIFFERl9UUkFDRV9MRVZFTF9ERUJVRywKCQkJCQkJICAgKHVpbnQ4X3QgKikgYm9keSwKCQkJCQkJICAgZnRfaWVzX2xlbmd0aCk7CgkJCX0gZWxzZSBpZiAoTlVMTCAhPSBzZXNzaW9uLT5mdFBFQ29udGV4dC4KCQkJCQlwRlRQcmVBdXRoUmVxLT5wYnNzRGVzY3JpcHRpb24pIHsKCQkJCS8qIE1ESUQgYXR0ciBpcyA1NCAqLwoJCQkJKmJvZHkgPSBTSVJfTURJRV9FTEVNRU5UX0lEOwoJCQkJYm9keSsrOwoJCQkJKmJvZHkgPSBTSVJfTURJRV9TSVpFOwoJCQkJYm9keSsrOwoJCQkJcWRmX21lbV9jb3B5KGJvZHksCgkJCQkJJnNlc3Npb24tPmZ0UEVDb250ZXh0LnBGVFByZUF1dGhSZXEtPgoJCQkJCQlwYnNzRGVzY3JpcHRpb24tPm1kaWVbMF0sCgkJCQkJU0lSX01ESUVfU0laRSk7CgkJCX0KCQl9CgoJCXBlX2RlYnVnKCIqKiogU2VuZGluZyBBdXRoIHNlcSMgJWQgc3RhdHVzICVkICglZCkgdG8gIgoJCQkJTUFDX0FERFJFU1NfU1RSLAoJCQlhdXRoX2ZyYW1lLT5hdXRoVHJhbnNhY3Rpb25TZXFOdW1iZXIsCgkJCWF1dGhfZnJhbWUtPmF1dGhTdGF0dXNDb2RlLAoJCQkoYXV0aF9mcmFtZS0+YXV0aFN0YXR1c0NvZGUgPT0KCQkJCWVTSVJfTUFDX1NVQ0NFU1NfU1RBVFVTKSwKCQkJTUFDX0FERFJfQVJSQVkobWFjX2hkci0+ZGEpKTsKCX0KCVFERl9UUkFDRV9IRVhfRFVNUChRREZfTU9EVUxFX0lEX1BFLAoJCQkgICBRREZfVFJBQ0VfTEVWRUxfREVCVUcsCgkJCSAgIGZyYW1lLCBmcmFtZV9sZW4pOwoKCWlmICgoTlVMTCAhPSBzZXNzaW9uLT5mdFBFQ29udGV4dC5wRlRQcmVBdXRoUmVxKSAmJgoJICAgIChTSVJfQkFORF81X0dIWiA9PSBsaW1fZ2V0X3JmX2JhbmQoCgkgICAgIHNlc3Npb24tPmZ0UEVDb250ZXh0LnBGVFByZUF1dGhSZXEtPnByZUF1dGhjaGFubmVsTnVtKSkpCgkJdHhfZmxhZyB8PSBIQUxfVVNFX0JEX1JBVEUyX0ZPUl9NQU5BR0VNRU5UX0ZSQU1FOwoJZWxzZSBpZiAoKFNJUl9CQU5EXzVfR0haID09CgkJICBsaW1fZ2V0X3JmX2JhbmQoc2Vzc2lvbi0+Y3VycmVudE9wZXJDaGFubmVsKSkKCQkgIHx8IChzZXNzaW9uLT5wZVBlcnNvbmEgPT0gUURGX1AyUF9DTElFTlRfTU9ERSkKCQkgIHx8IChzZXNzaW9uLT5wZVBlcnNvbmEgPT0gUURGX1AyUF9HT19NT0RFKSkKCQl0eF9mbGFnIHw9IEhBTF9VU0VfQkRfUkFURTJfRk9SX01BTkFHRU1FTlRfRlJBTUU7CgoJaWYgKHNlc3Npb24tPnBlUGVyc29uYSA9PSBRREZfUDJQX0NMSUVOVF9NT0RFIHx8CgkJc2Vzc2lvbi0+cGVQZXJzb25hID09IFFERl9TVEFfTU9ERSkKCQl0eF9mbGFnIHw9IEhBTF9VU0VfUEVFUl9TVEFfUkVRVUVTVEVEX01BU0s7CgoJTVRSQUNFKHFkZl90cmFjZShRREZfTU9EVUxFX0lEX1BFLCBUUkFDRV9DT0RFX1RYX01HTVQsCgkJCSBzZXNzaW9uLT5wZVNlc3Npb25JZCwgbWFjX2hkci0+ZmMuc3ViVHlwZSkpOwoKCWlmICh3YWl0X2Zvcl9hY2spIHsKCQltYWNfY3R4LT5hdXRoX2Fja19zdGF0dXMgPSBMSU1fQVVUSF9BQ0tfTk9UX1JDRDsKCQlxZGZfc3RhdHVzID0gd21hX3R4X2ZyYW1lV2l0aFR4Q29tcGxldGUobWFjX2N0eCwgcGFja2V0LAoJCQkJCSAodWludDE2X3QpZnJhbWVfbGVuLAoJCQkJCSBUWFJYX0ZSTV84MDJfMTFfTUdNVCwgQU5JX1RYRElSX1RPRFMsCgkJCQkJIDcsIGxpbV90eF9jb21wbGV0ZSwgZnJhbWUsCgkJCQkJIGxpbV9hdXRoX3R4X2NvbXBsZXRlX2NuZiwKCQkJCQkgdHhfZmxhZywgc21lX3Nlc3Npb25pZCwgZmFsc2UsIDApOwoJCU1UUkFDRShxZGZfdHJhY2UoUURGX01PRFVMRV9JRF9QRSwgVFJBQ0VfQ09ERV9UWF9DT01QTEVURSwKCQkJc2Vzc2lvbi0+cGVTZXNzaW9uSWQsIHFkZl9zdGF0dXMpKTsKCQlpZiAoIVFERl9JU19TVEFUVVNfU1VDQ0VTUyhxZGZfc3RhdHVzKSkgewoJCQlwZV9lcnIoIioqKiBDb3VsZCBub3Qgc2VuZCBBdXRoIGZyYW1lLCByZXRDb2RlPSVYICoqKiIsCgkJCQlxZGZfc3RhdHVzKTsKCQkJbWFjX2N0eC0+YXV0aF9hY2tfc3RhdHVzID0gTElNX0FVVEhfQUNLX1JDRF9GQUlMVVJFOwoJCS8qIFBrdCB3aWxsIGJlIGZyZWVkIHVwIGJ5IHRoZSBjYWxsYmFjayAqLwoJCX0KCX0gZWxzZSB7CgkJLyogUXVldWUgQXV0aGVudGljYXRpb24gZnJhbWUgaW4gaGlnaCBwcmlvcml0eSBXUSAqLwoJCXFkZl9zdGF0dXMgPSB3bWFfdHhfZnJhbWUobWFjX2N0eCwgcGFja2V0LCAodWludDE2X3QpIGZyYW1lX2xlbiwKCQkJCQlUWFJYX0ZSTV84MDJfMTFfTUdNVCwKCQkJCQlBTklfVFhESVJfVE9EUywgNywgbGltX3R4X2NvbXBsZXRlLAoJCQkJCWZyYW1lLCB0eF9mbGFnLCBzbWVfc2Vzc2lvbmlkLCAwKTsKCQlNVFJBQ0UocWRmX3RyYWNlKFFERl9NT0RVTEVfSURfUEUsIFRSQUNFX0NPREVfVFhfQ09NUExFVEUsCgkJCQkgc2Vzc2lvbi0+cGVTZXNzaW9uSWQsIHFkZl9zdGF0dXMpKTsKCQlpZiAoIVFERl9JU19TVEFUVVNfU1VDQ0VTUyhxZGZfc3RhdHVzKSkKCQkJcGVfZXJyKCIqKiogQ291bGQgbm90IHNlbmQgQXV0aCBmcmFtZSwgcmV0Q29kZT0lWCAqKioiLAoJCQkJcWRmX3N0YXR1cyk7Cgl9CglyZXR1cm47Cn0KClFERl9TVEFUVVMgbGltX3NlbmRfZGVhdXRoX2NuZih0cEFuaVNpckdsb2JhbCBwTWFjKQp7Cgl1aW50MTZfdCBhaWQ7Cgl0cERwaEhhc2hOb2RlIHBTdGFEczsKCXRMaW1NbG1EZWF1dGhSZXEgKnBNbG1EZWF1dGhSZXE7Cgl0TGltTWxtRGVhdXRoQ25mIG1sbURlYXV0aENuZjsKCXRwUEVTZXNzaW9uIHBzZXNzaW9uRW50cnk7CgoJcE1sbURlYXV0aFJlcSA9IHBNYWMtPmxpbS5saW1EaXNhc3NvY0RlYXV0aENuZlJlcS5wTWxtRGVhdXRoUmVxOwoJaWYgKHBNbG1EZWF1dGhSZXEpIHsKCQlpZiAodHhfdGltZXJfcnVubmluZygmcE1hYy0+bGltLmxpbVRpbWVycy5nTGltRGVhdXRoQWNrVGltZXIpKSB7CgkJCWxpbV9kZWFjdGl2YXRlX2FuZF9jaGFuZ2VfdGltZXIocE1hYywKCQkJCQkJCWVMSU1fREVBVVRIX0FDS19USU1FUik7CgkJfQoKCQlwc2Vzc2lvbkVudHJ5ID0gcGVfZmluZF9zZXNzaW9uX2J5X3Nlc3Npb25faWQocE1hYywKCQkJCXBNbG1EZWF1dGhSZXEtPnNlc3Npb25JZCk7CgkJaWYgKHBzZXNzaW9uRW50cnkgPT0gTlVMTCkgewoJCQlwZV9lcnIoInNlc3Npb24gZG9lcyBub3QgZXhpc3QgZm9yIGdpdmVuIHNlc3Npb25JZCIpOwoJCQltbG1EZWF1dGhDbmYucmVzdWx0Q29kZSA9CgkJCQllU0lSX1NNRV9JTlZBTElEX1BBUkFNRVRFUlM7CgkJCWdvdG8gZW5kOwoJCX0KCgkJcFN0YURzID0KCQkJZHBoX2xvb2t1cF9oYXNoX2VudHJ5KHBNYWMsCgkJCQkJICAgICAgcE1sbURlYXV0aFJlcS0+cGVlcl9tYWNhZGRyLmJ5dGVzLAoJCQkJCSAgICAgICZhaWQsCgkJCQkJICAgICAgJnBzZXNzaW9uRW50cnktPmRwaC5kcGhIYXNoVGFibGUpOwoJCWlmIChwU3RhRHMgPT0gTlVMTCkgewoJCQltbG1EZWF1dGhDbmYucmVzdWx0Q29kZSA9IGVTSVJfU01FX0lOVkFMSURfUEFSQU1FVEVSUzsKCQkJZ290byBlbmQ7CgkJfQoKCQkvKiAvIFJlY2VpdmUgcGF0aCBjbGVhbnVwIHdpdGggZHVtbXkgcGFja2V0ICovCgkJbGltX2Z0X2NsZWFudXBfcHJlX2F1dGhfaW5mbyhwTWFjLCBwc2Vzc2lvbkVudHJ5KTsKCQlsaW1fY2xlYW51cF9yeF9wYXRoKHBNYWMsIHBTdGFEcywgcHNlc3Npb25FbnRyeSk7CgkJaWYgKChwc2Vzc2lvbkVudHJ5LT5saW1TeXN0ZW1Sb2xlID09IGVMSU1fU1RBX1JPTEUpICYmCgkJCQkoCiNpZmRlZiBGRUFUVVJFX1dMQU5fRVNFCgkJCQkgKHBzZXNzaW9uRW50cnktPmlzRVNFY29ubmVjdGlvbikgfHwKI2VuZGlmCgkJCQkgKHBzZXNzaW9uRW50cnktPmlzRmFzdFJvYW1JbmlGZWF0dXJlRW5hYmxlZCkgfHwKCQkJCSAocHNlc3Npb25FbnRyeS0+aXMxMVJjb25uZWN0aW9uKSkpIHsKCQkJcGVfZGVidWcoIkZUIFByZWF1dGggKCVwLCVkKSBEZWF1dGggcmMgJWQgc3JjID0gJWQiLAoJCQkJCXBzZXNzaW9uRW50cnksCgkJCQkJcHNlc3Npb25FbnRyeS0+cGVTZXNzaW9uSWQsCgkJCQkJcE1sbURlYXV0aFJlcS0+cmVhc29uQ29kZSwKCQkJCQlwTWxtRGVhdXRoUmVxLT5kZWF1dGhUcmlnZ2VyKTsKCQkJbGltX2Z0X2NsZWFudXAocE1hYywgcHNlc3Npb25FbnRyeSk7CgkJfSBlbHNlIHsKCQkJcGVfZGVidWcoIk5vIEZUIFByZWF1dGggU2Vzc2lvbiBDbGVhbnVwIGluIHJvbGUgJWQiCiNpZmRlZiBGRUFUVVJFX1dMQU5fRVNFCgkJCQkiIGlzRVNFICVkIgojZW5kaWYKCQkJCSIgaXNMRlIgJWQiCgkJCQkiIGlzMTFyICVkLCBEZWF1dGggcmVhc29uICVkIFRyaWdnZXIgPSAlZCIsCgkJCQlwc2Vzc2lvbkVudHJ5LT5saW1TeXN0ZW1Sb2xlLAojaWZkZWYgRkVBVFVSRV9XTEFOX0VTRQoJCQkJcHNlc3Npb25FbnRyeS0+aXNFU0Vjb25uZWN0aW9uLAojZW5kaWYKCQkJCXBzZXNzaW9uRW50cnktPmlzRmFzdFJvYW1JbmlGZWF0dXJlRW5hYmxlZCwKCQkJCXBzZXNzaW9uRW50cnktPmlzMTFSY29ubmVjdGlvbiwKCQkJCXBNbG1EZWF1dGhSZXEtPnJlYXNvbkNvZGUsCgkJCQlwTWxtRGVhdXRoUmVxLT5kZWF1dGhUcmlnZ2VyKTsKCQl9CgkJLyogRnJlZSB1cCBidWZmZXIgYWxsb2NhdGVkIGZvciBtbG1EZWF1dGhSZXEgKi8KCQlxZGZfbWVtX2ZyZWUocE1sbURlYXV0aFJlcSk7CgkJcE1hYy0+bGltLmxpbURpc2Fzc29jRGVhdXRoQ25mUmVxLnBNbG1EZWF1dGhSZXEgPSBOVUxMOwoJfQoJcmV0dXJuIFFERl9TVEFUVVNfU1VDQ0VTUzsKZW5kOgoJcWRmX2NvcHlfbWFjYWRkcigmbWxtRGVhdXRoQ25mLnBlZXJfbWFjYWRkciwKCQkJICZwTWxtRGVhdXRoUmVxLT5wZWVyX21hY2FkZHIpOwoJbWxtRGVhdXRoQ25mLmRlYXV0aFRyaWdnZXIgPSBwTWxtRGVhdXRoUmVxLT5kZWF1dGhUcmlnZ2VyOwoJbWxtRGVhdXRoQ25mLmFpZCA9IHBNbG1EZWF1dGhSZXEtPmFpZDsKCW1sbURlYXV0aENuZi5zZXNzaW9uSWQgPSBwTWxtRGVhdXRoUmVxLT5zZXNzaW9uSWQ7CgoJLyogRnJlZSB1cCBidWZmZXIgYWxsb2NhdGVkICovCgkvKiBmb3IgbWxtRGVhdXRoUmVxICovCglxZGZfbWVtX2ZyZWUocE1sbURlYXV0aFJlcSk7CgoJbGltX3Bvc3Rfc21lX21lc3NhZ2UocE1hYywKCQkJICAgICBMSU1fTUxNX0RFQVVUSF9DTkYsICh1aW50MzJfdCAqKSAmbWxtRGVhdXRoQ25mKTsKCXJldHVybiBRREZfU1RBVFVTX1NVQ0NFU1M7Cn0KCi8qKgogKiBsaW1fc2VuZF9kaXNhc3NvY19jbmYoKSAtIFNlbmQgZGlzYXNzb2MgY29uZmlybWF0aW9uIHRvIFNNRQogKgogKiBAbWFjX2N0eDogSGFuZGxlIHRvIE1BQyBjb250ZXh0CiAqCiAqIFNlbmRzIGRpc2Fzc29jIGNvbmZpcm1hdGlvbiB0byBTTUUuIFJlbW92ZXMgZGlzYXNzb2MgcmVxdWVzdCBzdG9yZWQKICogaW4gbGltLgogKgogKiBSZXR1cm46IFFERl9TVEFUVVNfU1VDQ0VTUwogKi8KClFERl9TVEFUVVMgbGltX3NlbmRfZGlzYXNzb2NfY25mKHRwQW5pU2lyR2xvYmFsIG1hY19jdHgpCnsKCXVpbnQxNl90IGFpZDsKCXRwRHBoSGFzaE5vZGUgc3RhX2RzOwoJdExpbU1sbURpc2Fzc29jQ25mIGRpc2Fzc29jX2NuZjsKCXRwUEVTZXNzaW9uIHBlX3Nlc3Npb247Cgl0TGltTWxtRGlzYXNzb2NSZXEgKmRpc2Fzc29jX3JlcTsKCglkaXNhc3NvY19yZXEgPSBtYWNfY3R4LT5saW0ubGltRGlzYXNzb2NEZWF1dGhDbmZSZXEucE1sbURpc2Fzc29jUmVxOwoJaWYgKGRpc2Fzc29jX3JlcSkgewoJCWlmICh0eF90aW1lcl9ydW5uaW5nKAoJCQkmbWFjX2N0eC0+bGltLmxpbVRpbWVycy5nTGltRGlzYXNzb2NBY2tUaW1lcikpCgkJCWxpbV9kZWFjdGl2YXRlX2FuZF9jaGFuZ2VfdGltZXIobWFjX2N0eCwKCQkJCWVMSU1fRElTQVNTT0NfQUNLX1RJTUVSKTsKCgkJcGVfc2Vzc2lvbiA9IHBlX2ZpbmRfc2Vzc2lvbl9ieV9zZXNzaW9uX2lkKAoJCQkJCW1hY19jdHgsIGRpc2Fzc29jX3JlcS0+c2Vzc2lvbklkKTsKCQlpZiAocGVfc2Vzc2lvbiA9PSBOVUxMKSB7CgkJCXBlX2VycigiTm8gc2Vzc2lvbiBmb3IgZ2l2ZW4gc2Vzc2lvbklkIik7CgkJCWRpc2Fzc29jX2NuZi5yZXN1bHRDb2RlID0KCQkJCWVTSVJfU01FX0lOVkFMSURfUEFSQU1FVEVSUzsKCQkJZ290byBlbmQ7CgkJfQoKCQlzdGFfZHMgPSBkcGhfbG9va3VwX2hhc2hfZW50cnkobWFjX2N0eCwKCQkJCWRpc2Fzc29jX3JlcS0+cGVlcl9tYWNhZGRyLmJ5dGVzLCAmYWlkLAoJCQkJJnBlX3Nlc3Npb24tPmRwaC5kcGhIYXNoVGFibGUpOwoJCWlmIChzdGFfZHMgPT0gTlVMTCkgewoJCQlwZV9lcnIoIlN0YURzIE51bGwiKTsKCQkJZGlzYXNzb2NfY25mLnJlc3VsdENvZGUgPSBlU0lSX1NNRV9JTlZBTElEX1BBUkFNRVRFUlM7CgkJCWdvdG8gZW5kOwoJCX0KCQkvKiBSZWNlaXZlIHBhdGggY2xlYW51cCB3aXRoIGR1bW15IHBhY2tldCAqLwoJCWlmIChlU0lSX1NVQ0NFU1MgIT0KCQkgICAgbGltX2NsZWFudXBfcnhfcGF0aChtYWNfY3R4LCBzdGFfZHMsIHBlX3Nlc3Npb24pKSB7CgkJCWRpc2Fzc29jX2NuZi5yZXN1bHRDb2RlID0KCQkJCWVTSVJfU01FX1JFU09VUkNFU19VTkFWQUlMQUJMRTsKCQkJcGVfZXJyKCJjbGVhbnVwX3J4X3BhdGggZXJyb3IiKTsKCQkJZ290byBlbmQ7CgkJfQoJCWlmIChMSU1fSVNfU1RBX1JPTEUocGVfc2Vzc2lvbikgJiYKCQkJKGRpc2Fzc29jX3JlcS0+cmVhc29uQ29kZSAhPQoJCQkJZVNJUl9NQUNfRElTQVNTT0NfRFVFX1RPX0ZUSEFORE9GRl9SRUFTT04pKSB7CgkJCXBlX2RlYnVnKCJGVCBQcmVhdXRoIFNlc3Npb24gKCVwICVkKSBDbGVhbiB1cCIsCgkJCQkJcGVfc2Vzc2lvbiwgcGVfc2Vzc2lvbi0+cGVTZXNzaW9uSWQpOwoKCQkJLyogRGVsZXRlIEZUIHNlc3Npb24gaWYgdGhlcmUgZXhpc3RzIG9uZSAqLwoJCQlsaW1fZnRfY2xlYW51cF9wcmVfYXV0aF9pbmZvKG1hY19jdHgsIHBlX3Nlc3Npb24pOwoJCX0KCQkvKiBGcmVlIHVwIGJ1ZmZlciBhbGxvY2F0ZWQgZm9yIG1sbURpc2Fzc29jUmVxICovCgkJcWRmX21lbV9mcmVlKGRpc2Fzc29jX3JlcSk7CgkJbWFjX2N0eC0+bGltLmxpbURpc2Fzc29jRGVhdXRoQ25mUmVxLnBNbG1EaXNhc3NvY1JlcSA9IE5VTEw7CgkJcmV0dXJuIFFERl9TVEFUVVNfU1VDQ0VTUzsKCX0gZWxzZSB7CgkJcmV0dXJuIFFERl9TVEFUVVNfU1VDQ0VTUzsKCX0KZW5kOgoJcWRmX21lbV9jb3B5KCh1aW50OF90ICopICZkaXNhc3NvY19jbmYucGVlck1hY0FkZHIsCgkJICAgICAodWludDhfdCAqKSBkaXNhc3NvY19yZXEtPnBlZXJfbWFjYWRkci5ieXRlcywKCQkgICAgIFFERl9NQUNfQUREUl9TSVpFKTsKCWRpc2Fzc29jX2NuZi5haWQgPSBkaXNhc3NvY19yZXEtPmFpZDsKCWRpc2Fzc29jX2NuZi5kaXNhc3NvY1RyaWdnZXIgPSBkaXNhc3NvY19yZXEtPmRpc2Fzc29jVHJpZ2dlcjsKCgkvKiBVcGRhdGUgUEUgc2Vzc2lvbiBJRCAqLwoJZGlzYXNzb2NfY25mLnNlc3Npb25JZCA9IGRpc2Fzc29jX3JlcS0+c2Vzc2lvbklkOwoKCWlmIChkaXNhc3NvY19yZXEgIT0gTlVMTCkgewoJCS8qIC8gRnJlZSB1cCBidWZmZXIgYWxsb2NhdGVkIGZvciBtbG1EaXNhc3NvY1JlcSAqLwoJCXFkZl9tZW1fZnJlZShkaXNhc3NvY19yZXEpOwoJCW1hY19jdHgtPmxpbS5saW1EaXNhc3NvY0RlYXV0aENuZlJlcS5wTWxtRGlzYXNzb2NSZXEgPSBOVUxMOwoJfQoKCWxpbV9wb3N0X3NtZV9tZXNzYWdlKG1hY19jdHgsIExJTV9NTE1fRElTQVNTT0NfQ05GLAoJCSh1aW50MzJfdCAqKSAmZGlzYXNzb2NfY25mKTsKCXJldHVybiBRREZfU1RBVFVTX1NVQ0NFU1M7Cn0KClFERl9TVEFUVVMgbGltX2Rpc2Fzc29jX3R4X2NvbXBsZXRlX2NuZih2b2lkICpjb250ZXh0LAoJCQkJCXFkZl9uYnVmX3QgYnVmLAoJCQkJCXVpbnQzMl90IHR4Q29tcGxldGVTdWNjZXNzLAoJCQkJCXZvaWQgKnBhcmFtcykKewoJdHBBbmlTaXJHbG9iYWwgcE1hYyA9ICh0cEFuaVNpckdsb2JhbCljb250ZXh0OwoKCXBlX2RlYnVnKCJ0eENvbXBsZXRlU3VjY2VzczogJWQiLCB0eENvbXBsZXRlU3VjY2Vzcyk7CgoJaWYgKGJ1ZikKCQlxZGZfbmJ1Zl9mcmVlKGJ1Zik7CgoJcmV0dXJuIGxpbV9zZW5kX2Rpc2Fzc29jX2NuZihwTWFjKTsKfQoKUURGX1NUQVRVUyBsaW1fZGVhdXRoX3R4X2NvbXBsZXRlX2NuZih2b2lkICpjb250ZXh0LAoJCQkJICAgICAgcWRmX25idWZfdCBidWYsCgkJCQkgICAgICB1aW50MzJfdCB0eENvbXBsZXRlU3VjY2VzcywKCQkJCSAgICAgIHZvaWQgKnBhcmFtcykKewoJdHBBbmlTaXJHbG9iYWwgcE1hYyA9ICh0cEFuaVNpckdsb2JhbCljb250ZXh0OwoKCXBlX2RlYnVnKCJ0eENvbXBsZXRlU3VjY2VzczogJWQiLCB0eENvbXBsZXRlU3VjY2Vzcyk7CgoJaWYgKGJ1ZikKCQlxZGZfbmJ1Zl9mcmVlKGJ1Zik7CgoJcmV0dXJuIGxpbV9zZW5kX2RlYXV0aF9jbmYocE1hYyk7Cn0KCi8qKgogKiBcYnJpZWYgVGhpcyBmdW5jdGlvbiBpcyBjYWxsZWQgdG8gc2VuZCBEaXNhc3NvY2lhdGUgZnJhbWUuCiAqCiAqCiAqIFxwYXJhbSBwTWFjIFBvaW50ZXIgdG8gR2xvYmFsIE1BQyBzdHJ1Y3R1cmUKICoKICogXHBhcmFtIG5SZWFzb24gSW5kaWNhdGVzIHRoZSByZWFzb24gdGhhdCBuZWVkIHRvIGJlIHNlbnQgaW4KICogRGlzYXNzb2NpYXRpb24gZnJhbWUKICoKICogXHBhcmFtIHBlZXJNYWNBZGRyIE1BQyBhZGRyZXNzIG9mIHRoZSBTVEEgdG8gd2hpY2ggRGlzYXNzb2NpYXRpb24gZnJhbWUgaXMKICogc2VudAogKgogKgogKi8KCnZvaWQKbGltX3NlbmRfZGlzYXNzb2NfbWdtdF9mcmFtZSh0cEFuaVNpckdsb2JhbCBwTWFjLAoJCQkgICAgIHVpbnQxNl90IG5SZWFzb24sCgkJCSAgICAgdFNpck1hY0FkZHIgcGVlciwKCQkJICAgICB0cFBFU2Vzc2lvbiBwc2Vzc2lvbkVudHJ5LCBib29sIHdhaXRGb3JBY2spCnsKCXREb3QxMWZEaXNhc3NvY2lhdGlvbiBmcm07Cgl1aW50OF90ICpwRnJhbWU7Cgl0cFNpck1hY01nbXRIZHIgcE1hY0hkcjsKCXVpbnQzMl90IG5CeXRlcywgblBheWxvYWQsIG5TdGF0dXM7Cgl2b2lkICpwUGFja2V0OwoJUURGX1NUQVRVUyBxZGZfc3RhdHVzOwoJdWludDhfdCB0eEZsYWcgPSAwOwoJdWludDMyX3QgdmFsID0gMDsKCXVpbnQ4X3Qgc21lU2Vzc2lvbklkID0gMDsKCWlmIChOVUxMID09IHBzZXNzaW9uRW50cnkpIHsKCQlyZXR1cm47Cgl9CgoJLyoKCSAqIEluIGNhc2Ugd2hlbiBjYWMgdGltZXIgaXMgcnVubmluZyBmb3IgdGhpcyBTQVAgc2Vzc2lvbiB0aGVuCgkgKiBhdm9pZCBzZW5kaW5nIGRpc2Fzc29jIG91dC4gSXQgaXMgdmlvbGF0aW9uIG9mIGRmcyBzcGVjaWZpY2F0aW9uLgoJICovCglpZiAoKChwc2Vzc2lvbkVudHJ5LT5wZVBlcnNvbmEgPT0gUURGX1NBUF9NT0RFKSB8fAoJICAgIChwc2Vzc2lvbkVudHJ5LT5wZVBlcnNvbmEgPT0gUURGX1AyUF9HT19NT0RFKSkgJiYKCSAgICAodHJ1ZSA9PSBwTWFjLT5zYXAuU2FwRGZzSW5mby5pc19kZnNfY2FjX3RpbWVyX3J1bm5pbmcpKSB7CgkJUURGX1RSQUNFKFFERl9NT0RVTEVfSURfU0FQLCBRREZfVFJBQ0VfTEVWRUxfSU5GTywKCQkJICBGTAoJCQkJICAoIkNBQyB0aW1lciBpcyBydW5uaW5nLCBkcm9wIGRpc2Fzc29jIGZyb20gZ29pbmcgb3V0IikpOwoJCXJldHVybjsKCX0KCXNtZVNlc3Npb25JZCA9IHBzZXNzaW9uRW50cnktPnNtZVNlc3Npb25JZDsKCglxZGZfbWVtX3NldCgodWludDhfdCAqKSAmZnJtLCBzaXplb2YoZnJtKSwgMCk7CgoJZnJtLlJlYXNvbi5jb2RlID0gblJlYXNvbjsKCgluU3RhdHVzID0gZG90MTFmX2dldF9wYWNrZWRfZGlzYXNzb2NpYXRpb25fc2l6ZShwTWFjLCAmZnJtLCAmblBheWxvYWQpOwoJaWYgKERPVDExRl9GQUlMRUQoblN0YXR1cykpIHsKCQlwZV9lcnIoIkZhaWxlZCB0byBjYWxjdWxhdGUgdGhlIHBhY2tlZCBzaXplIGZvciBhIERpc2Fzc29jaWF0aW9uICgweCUwOHgpIiwKCQkJblN0YXR1cyk7CgkJLyogV2UnbGwgZmFsbCBiYWNrIG9uIHRoZSB3b3JzdCBjYXNlIHNjZW5hcmlvOiAqLwoJCW5QYXlsb2FkID0gc2l6ZW9mKHREb3QxMWZEaXNhc3NvY2lhdGlvbik7Cgl9IGVsc2UgaWYgKERPVDExRl9XQVJORUQoblN0YXR1cykpIHsKCQlwZV93YXJuKCJUaGVyZSB3ZXJlIHdhcm5pbmdzIHdoaWxlIGNhbGN1bGF0aW5nIHRoZSBwYWNrZWQgc2l6ZSBmb3IgYSBEaXNhc3NvY2lhdGlvbiAoMHglMDh4KSIsCgkJCW5TdGF0dXMpOwoJfQoKCW5CeXRlcyA9IG5QYXlsb2FkICsgc2l6ZW9mKHRTaXJNYWNNZ210SGRyKTsKCglxZGZfc3RhdHVzID0gY2RzX3BhY2tldF9hbGxvYygodWludDE2X3QpIG5CeXRlcywgKHZvaWQgKiopJnBGcmFtZSwKCQkJCSAgICAgICh2b2lkICoqKSZwUGFja2V0KTsKCWlmICghUURGX0lTX1NUQVRVU19TVUNDRVNTKHFkZl9zdGF0dXMpKSB7CgkJcGVfZXJyKCJGYWlsZWQgdG8gYWxsb2NhdGUgJWQgYnl0ZXMgZm9yIGEgRGlzYXNzb2NpYXRpb24iLAoJCQluQnl0ZXMpOwoJCXJldHVybjsKCX0KCS8qIFBhcmFub2lhOiAqLwoJcWRmX21lbV9zZXQocEZyYW1lLCBuQnl0ZXMsIDApOwoKCS8qIE5leHQsIHdlIGZpbGwgb3V0IHRoZSBidWZmZXIgZGVzY3JpcHRvcjogKi8KCWxpbV9wb3B1bGF0ZV9tYWNfaGVhZGVyKHBNYWMsIHBGcmFtZSwgU0lSX01BQ19NR01UX0ZSQU1FLAoJCVNJUl9NQUNfTUdNVF9ESVNBU1NPQywgcGVlciwgcHNlc3Npb25FbnRyeS0+c2VsZk1hY0FkZHIpOwoJcE1hY0hkciA9ICh0cFNpck1hY01nbXRIZHIpIHBGcmFtZTsKCgkvKiBQcmVwYXJlIHRoZSBCU1NJRCAqLwoJc2lyX2NvcHlfbWFjX2FkZHIocE1hY0hkci0+YnNzSWQsIHBzZXNzaW9uRW50cnktPmJzc0lkKTsKCiNpZmRlZiBXTEFOX0ZFQVRVUkVfMTFXCglsaW1fc2V0X3Byb3RlY3RlZF9iaXQocE1hYywgcHNlc3Npb25FbnRyeSwgcGVlciwgcE1hY0hkcik7CiNlbmRpZgoKCW5TdGF0dXMgPSBkb3QxMWZfcGFja19kaXNhc3NvY2lhdGlvbihwTWFjLCAmZnJtLCBwRnJhbWUgKwoJCQkJCSAgICAgc2l6ZW9mKHRTaXJNYWNNZ210SGRyKSwKCQkJCQkgICAgIG5QYXlsb2FkLCAmblBheWxvYWQpOwoJaWYgKERPVDExRl9GQUlMRUQoblN0YXR1cykpIHsKCQlwZV9lcnIoIkZhaWxlZCB0byBwYWNrIGEgRGlzYXNzb2NpYXRpb24gKDB4JTA4eCkiLAoJCQluU3RhdHVzKTsKCQljZHNfcGFja2V0X2ZyZWUoKHZvaWQgKilwUGFja2V0KTsKCQlyZXR1cm47Cgl9IGVsc2UgaWYgKERPVDExRl9XQVJORUQoblN0YXR1cykpIHsKCQlwZV93YXJuKCJUaGVyZSB3ZXJlIHdhcm5pbmdzIHdoaWxlIHBhY2tpbmcgYSBEaXNhc3NvY2lhdGlvbiAoMHglMDh4KSIsCgkJCW5TdGF0dXMpOwoJfQoKCXBlX2RlYnVnKCIqKipTZXNzaW9uaWQgJWQgU2VuZGluZyBEaXNhc3NvY2lhdGlvbiBmcmFtZSB3aXRoICIKCQkgICAicmVhc29uICV1IGFuZCB3YWl0Rm9yQWNrICVkIHRvICIgTUFDX0FERFJFU1NfU1RSICIgLEZyb20gIgoJCSAgIE1BQ19BRERSRVNTX1NUUiwgcHNlc3Npb25FbnRyeS0+cGVTZXNzaW9uSWQsIG5SZWFzb24sCgkJd2FpdEZvckFjaywgTUFDX0FERFJfQVJSQVkocE1hY0hkci0+ZGEpLAoJCU1BQ19BRERSX0FSUkFZKHBzZXNzaW9uRW50cnktPnNlbGZNYWNBZGRyKSk7CgoJaWYgKChTSVJfQkFORF81X0dIWiA9PSBsaW1fZ2V0X3JmX2JhbmQocHNlc3Npb25FbnRyeS0+Y3VycmVudE9wZXJDaGFubmVsKSkKCSAgICB8fCAocHNlc3Npb25FbnRyeS0+cGVQZXJzb25hID09IFFERl9QMlBfQ0xJRU5UX01PREUpIHx8CgkgICAgKHBzZXNzaW9uRW50cnktPnBlUGVyc29uYSA9PSBRREZfUDJQX0dPX01PREUpCgkgICAgKSB7CgkJdHhGbGFnIHw9IEhBTF9VU0VfQkRfUkFURTJfRk9SX01BTkFHRU1FTlRfRlJBTUU7Cgl9CgoJdHhGbGFnIHw9IEhBTF9VU0VfUEVFUl9TVEFfUkVRVUVTVEVEX01BU0s7CgoJaWYgKHdhaXRGb3JBY2spIHsKCQlNVFJBQ0UocWRmX3RyYWNlKFFERl9NT0RVTEVfSURfUEUsIFRSQUNFX0NPREVfVFhfTUdNVCwKCQkJCSBwc2Vzc2lvbkVudHJ5LT5wZVNlc3Npb25JZCwKCQkJCSBwTWFjSGRyLT5mYy5zdWJUeXBlKSk7CgkJLyogUXVldWUgRGlzYXNzb2NpYXRpb24gZnJhbWUgaW4gaGlnaCBwcmlvcml0eSBXUSAqLwoJCS8qIGdldCB0aGUgZHVyYXRpb24gZnJvbSB0aGUgcmVxdWVzdCAqLwoJCXFkZl9zdGF0dXMgPQoJCQl3bWFfdHhfZnJhbWVXaXRoVHhDb21wbGV0ZShwTWFjLCBwUGFja2V0LCAodWludDE2X3QpIG5CeXRlcywKCQkJCQkgVFhSWF9GUk1fODAyXzExX01HTVQsCgkJCQkJIEFOSV9UWERJUl9UT0RTLCA3LCBsaW1fdHhfY29tcGxldGUsCgkJCQkJIHBGcmFtZSwgbGltX2Rpc2Fzc29jX3R4X2NvbXBsZXRlX2NuZiwKCQkJCQkgdHhGbGFnLCBzbWVTZXNzaW9uSWQsIGZhbHNlLCAwKTsKCQlNVFJBQ0UocWRmX3RyYWNlCgkJCSAgICAgICAoUURGX01PRFVMRV9JRF9QRSwgVFJBQ0VfQ09ERV9UWF9DT01QTEVURSwKCQkJICAgICAgIHBzZXNzaW9uRW50cnktPnBlU2Vzc2lvbklkLCBxZGZfc3RhdHVzKSk7CgoJCXZhbCA9IFNZU19NU19UT19USUNLUyhMSU1fRElTQVNTT0NfREVBVVRIX0FDS19USU1FT1VUKTsKCgkJaWYgKHR4X3RpbWVyX2NoYW5nZQoJCQkgICAgKCZwTWFjLT5saW0ubGltVGltZXJzLmdMaW1EaXNhc3NvY0Fja1RpbWVyLCB2YWwsIDApCgkJICAgICE9IFRYX1NVQ0NFU1MpIHsKCQkJcGVfZXJyKCJVbmFibGUgdG8gY2hhbmdlIERpc2Fzc29jIGFjayBUaW1lciB2YWwiKTsKCQkJcmV0dXJuOwoJCX0gZWxzZSBpZiAoVFhfU1VDQ0VTUyAhPQoJCQkgICB0eF90aW1lcl9hY3RpdmF0ZSgmcE1hYy0+bGltLmxpbVRpbWVycy4KCQkJCQkgICAgIGdMaW1EaXNhc3NvY0Fja1RpbWVyKSkgewoJCQlwZV9lcnIoIlVuYWJsZSB0byBhY3RpdmF0ZSBEaXNhc3NvYyBhY2sgVGltZXIiKTsKCQkJbGltX2RlYWN0aXZhdGVfYW5kX2NoYW5nZV90aW1lcihwTWFjLAoJCQkJCQkJZUxJTV9ESVNBU1NPQ19BQ0tfVElNRVIpOwoJCQlyZXR1cm47CgkJfQoJfSBlbHNlIHsKCQlNVFJBQ0UocWRmX3RyYWNlKFFERl9NT0RVTEVfSURfUEUsIFRSQUNFX0NPREVfVFhfTUdNVCwKCQkJCSBwc2Vzc2lvbkVudHJ5LT5wZVNlc3Npb25JZCwKCQkJCSBwTWFjSGRyLT5mYy5zdWJUeXBlKSk7CgkJLyogUXVldWUgRGlzYXNzb2NpYXRpb24gZnJhbWUgaW4gaGlnaCBwcmlvcml0eSBXUSAqLwoJCXFkZl9zdGF0dXMgPSB3bWFfdHhfZnJhbWUocE1hYywgcFBhY2tldCwgKHVpbnQxNl90KSBuQnl0ZXMsCgkJCQkJVFhSWF9GUk1fODAyXzExX01HTVQsCgkJCQkJQU5JX1RYRElSX1RPRFMsCgkJCQkJNywKCQkJCQlsaW1fdHhfY29tcGxldGUsIHBGcmFtZSwgdHhGbGFnLAoJCQkJCXNtZVNlc3Npb25JZCwgMCk7CgkJTVRSQUNFKHFkZl90cmFjZQoJCQkgICAgICAgKFFERl9NT0RVTEVfSURfUEUsIFRSQUNFX0NPREVfVFhfQ09NUExFVEUsCgkJCSAgICAgICBwc2Vzc2lvbkVudHJ5LT5wZVNlc3Npb25JZCwgcWRmX3N0YXR1cykpOwoJCWlmICghUURGX0lTX1NUQVRVU19TVUNDRVNTKHFkZl9zdGF0dXMpKSB7CgkJCXBlX2VycigiRmFpbGVkIHRvIHNlbmQgRGlzYXNzb2NpYXRpb24gKCVYKSEiLAoJCQkJcWRmX3N0YXR1cyk7CgkJCS8qIFBrdCB3aWxsIGJlIGZyZWVkIHVwIGJ5IHRoZSBjYWxsYmFjayAqLwoJCX0KCX0KfSAvKiBFbmQgbGltX3NlbmRfZGlzYXNzb2NfbWdtdF9mcmFtZS4gKi8KCi8qKgogKiBcYnJpZWYgVGhpcyBmdW5jdGlvbiBpcyBjYWxsZWQgdG8gc2VuZCBhIERlYXV0aGVudGljYXRlIGZyYW1lCiAqCiAqCiAqIFxwYXJhbSBwTWFjIFBvaW50ZXIgdG8gZ2xvYmFsIE1BQyBzdHJ1Y3R1cmUKICoKICogXHBhcmFtIG5SZWFzb24gSW5kaWNhdGVzIHRoZSByZWFzb24gdGhhdCBuZWVkIHRvIGJlIHNlbnQgaW4gdGhlCiAqIERlYXV0aGVudGljYXRlIGZyYW1lCiAqCiAqIFxwYXJhbSBwZWVlciBhZGRyZXNzIG9mIHRoZSBTVEEgdG8gd2hpY2ggdGhlIGZyYW1lIGlzIHRvIGJlIHNlbnQKICoKICoKICovCgp2b2lkCmxpbV9zZW5kX2RlYXV0aF9tZ210X2ZyYW1lKHRwQW5pU2lyR2xvYmFsIHBNYWMsCgkJCSAgIHVpbnQxNl90IG5SZWFzb24sCgkJCSAgIHRTaXJNYWNBZGRyIHBlZXIsCgkJCSAgIHRwUEVTZXNzaW9uIHBzZXNzaW9uRW50cnksIGJvb2wgd2FpdEZvckFjaykKewoJdERvdDExZkRlQXV0aCBmcm07Cgl1aW50OF90ICpwRnJhbWU7Cgl0cFNpck1hY01nbXRIZHIgcE1hY0hkcjsKCXVpbnQzMl90IG5CeXRlcywgblBheWxvYWQsIG5TdGF0dXM7Cgl2b2lkICpwUGFja2V0OwoJUURGX1NUQVRVUyBxZGZfc3RhdHVzOwoJdWludDhfdCB0eEZsYWcgPSAwOwoJdWludDMyX3QgdmFsID0gMDsKI2lmZGVmIEZFQVRVUkVfV0xBTl9URExTCgl1aW50MTZfdCBhaWQ7Cgl0cERwaEhhc2hOb2RlIHBTdGFEczsKI2VuZGlmCgl1aW50OF90IHNtZVNlc3Npb25JZCA9IDA7CgoJaWYgKE5VTEwgPT0gcHNlc3Npb25FbnRyeSkgewoJCXJldHVybjsKCX0KCgkvKgoJICogSW4gY2FzZSB3aGVuIGNhYyB0aW1lciBpcyBydW5uaW5nIGZvciB0aGlzIFNBUCBzZXNzaW9uIHRoZW4KCSAqIGF2b2lkIGRlYXV0aCBmcmFtZSBvdXQuIEl0IGlzIHZpb2xhdGlvbiBvZiBkZnMgc3BlY2lmaWNhdGlvbi4KCSAqLwoJaWYgKCgocHNlc3Npb25FbnRyeS0+cGVQZXJzb25hID09IFFERl9TQVBfTU9ERSkgfHwKCSAgICAocHNlc3Npb25FbnRyeS0+cGVQZXJzb25hID09IFFERl9QMlBfR09fTU9ERSkpICYmCgkgICAgKHRydWUgPT0gcE1hYy0+c2FwLlNhcERmc0luZm8uaXNfZGZzX2NhY190aW1lcl9ydW5uaW5nKSkgewoJCVFERl9UUkFDRShRREZfTU9EVUxFX0lEX1NBUCwgUURGX1RSQUNFX0xFVkVMX0lORk8sCgkJCSAgRkwKCQkJCSAgKCJDQUMgdGltZXIgaXMgcnVubmluZywgZHJvcCB0aGUgZGVhdXRoIGZyb20gZ29pbmcgb3V0IikpOwoJCXJldHVybjsKCX0KCXNtZVNlc3Npb25JZCA9IHBzZXNzaW9uRW50cnktPnNtZVNlc3Npb25JZDsKCglxZGZfbWVtX3NldCgodWludDhfdCAqKSAmZnJtLCBzaXplb2YoZnJtKSwgMCk7CgoJZnJtLlJlYXNvbi5jb2RlID0gblJlYXNvbjsKCgluU3RhdHVzID0gZG90MTFmX2dldF9wYWNrZWRfZGVfYXV0aF9zaXplKHBNYWMsICZmcm0sICZuUGF5bG9hZCk7CglpZiAoRE9UMTFGX0ZBSUxFRChuU3RhdHVzKSkgewoJCXBlX2VycigiRmFpbGVkIHRvIGNhbGN1bGF0ZSB0aGUgcGFja2VkIHNpemUgZm9yIGEgRGUtQXV0aGVudGljYXRpb24gKDB4JTA4eCkiLAoJCQluU3RhdHVzKTsKCQkvKiBXZSdsbCBmYWxsIGJhY2sgb24gdGhlIHdvcnN0IGNhc2Ugc2NlbmFyaW86ICovCgkJblBheWxvYWQgPSBzaXplb2YodERvdDExZkRlQXV0aCk7Cgl9IGVsc2UgaWYgKERPVDExRl9XQVJORUQoblN0YXR1cykpIHsKCQlwZV93YXJuKCJUaGVyZSB3ZXJlIHdhcm5pbmdzIHdoaWxlIGNhbGN1bGF0aW5nIHRoZSBwYWNrZWQgc2l6ZSBmb3IgYSBEZS1BdXRoZW50aWNhdGlvbiAoMHglMDh4KSIsCgkJCW5TdGF0dXMpOwoJfQoKCW5CeXRlcyA9IG5QYXlsb2FkICsgc2l6ZW9mKHRTaXJNYWNNZ210SGRyKTsKCglxZGZfc3RhdHVzID0gY2RzX3BhY2tldF9hbGxvYygodWludDE2X3QpIG5CeXRlcywgKHZvaWQgKiopJnBGcmFtZSwKCQkJCSAgICAgICh2b2lkICoqKSZwUGFja2V0KTsKCWlmICghUURGX0lTX1NUQVRVU19TVUNDRVNTKHFkZl9zdGF0dXMpKSB7CgkJcGVfZXJyKCJGYWlsZWQgdG8gYWxsb2NhdGUgJWQgYnl0ZXMgZm9yIGEgRGUtQXV0aGVudGljYXRpb24iLAoJCQluQnl0ZXMpOwoJCXJldHVybjsKCX0KCS8qIFBhcmFub2lhOiAqLwoJcWRmX21lbV9zZXQocEZyYW1lLCBuQnl0ZXMsIDApOwoKCS8qIE5leHQsIHdlIGZpbGwgb3V0IHRoZSBidWZmZXIgZGVzY3JpcHRvcjogKi8KCWxpbV9wb3B1bGF0ZV9tYWNfaGVhZGVyKHBNYWMsIHBGcmFtZSwgU0lSX01BQ19NR01UX0ZSQU1FLAoJCVNJUl9NQUNfTUdNVF9ERUFVVEgsIHBlZXIsIHBzZXNzaW9uRW50cnktPnNlbGZNYWNBZGRyKTsKCXBNYWNIZHIgPSAodHBTaXJNYWNNZ210SGRyKSBwRnJhbWU7CgoJLyogUHJlcGFyZSB0aGUgQlNTSUQgKi8KCXNpcl9jb3B5X21hY19hZGRyKHBNYWNIZHItPmJzc0lkLCBwc2Vzc2lvbkVudHJ5LT5ic3NJZCk7CgojaWZkZWYgV0xBTl9GRUFUVVJFXzExVwoJbGltX3NldF9wcm90ZWN0ZWRfYml0KHBNYWMsIHBzZXNzaW9uRW50cnksIHBlZXIsIHBNYWNIZHIpOwojZW5kaWYKCgluU3RhdHVzID0gZG90MTFmX3BhY2tfZGVfYXV0aChwTWFjLCAmZnJtLCBwRnJhbWUgKwoJCQkJICAgICAgc2l6ZW9mKHRTaXJNYWNNZ210SGRyKSwgblBheWxvYWQsICZuUGF5bG9hZCk7CglpZiAoRE9UMTFGX0ZBSUxFRChuU3RhdHVzKSkgewoJCXBlX2VycigiRmFpbGVkIHRvIHBhY2sgYSBEZUF1dGhlbnRpY2F0aW9uICgweCUwOHgpIiwKCQkJblN0YXR1cyk7CgkJY2RzX3BhY2tldF9mcmVlKCh2b2lkICopcFBhY2tldCk7CgkJcmV0dXJuOwoJfSBlbHNlIGlmIChET1QxMUZfV0FSTkVEKG5TdGF0dXMpKSB7CgkJcGVfd2FybigiVGhlcmUgd2VyZSB3YXJuaW5ncyB3aGlsZSBwYWNraW5nIGEgRGUtQXV0aGVudGljYXRpb24gKDB4JTA4eCkiLAoJCQluU3RhdHVzKTsKCX0KCXBlX2RlYnVnKCIqKipTZXNzaW9uaWQgJWQgU2VuZGluZyBEZWF1dGggZnJhbWUgd2l0aCAiCgkJICAgICAgICJyZWFzb24gJXUgYW5kIHdhaXRGb3JBY2sgJWQgdG8gIiBNQUNfQUREUkVTU19TVFIKCQkgICAgICAgIiAsRnJvbSAiIE1BQ19BRERSRVNTX1NUUiwKCQlwc2Vzc2lvbkVudHJ5LT5wZVNlc3Npb25JZCwgblJlYXNvbiwgd2FpdEZvckFjaywKCQlNQUNfQUREUl9BUlJBWShwTWFjSGRyLT5kYSksCgkJTUFDX0FERFJfQVJSQVkocHNlc3Npb25FbnRyeS0+c2VsZk1hY0FkZHIpKTsKCglpZiAoKFNJUl9CQU5EXzVfR0haID09IGxpbV9nZXRfcmZfYmFuZChwc2Vzc2lvbkVudHJ5LT5jdXJyZW50T3BlckNoYW5uZWwpKQoJICAgIHx8IChwc2Vzc2lvbkVudHJ5LT5wZVBlcnNvbmEgPT0gUURGX1AyUF9DTElFTlRfTU9ERSkgfHwKCSAgICAocHNlc3Npb25FbnRyeS0+cGVQZXJzb25hID09IFFERl9QMlBfR09fTU9ERSkKCSAgICApIHsKCQl0eEZsYWcgfD0gSEFMX1VTRV9CRF9SQVRFMl9GT1JfTUFOQUdFTUVOVF9GUkFNRTsKCX0KCgl0eEZsYWcgfD0gSEFMX1VTRV9QRUVSX1NUQV9SRVFVRVNURURfTUFTSzsKI2lmZGVmIEZFQVRVUkVfV0xBTl9URExTCglwU3RhRHMgPQoJCWRwaF9sb29rdXBfaGFzaF9lbnRyeShwTWFjLCBwZWVyLCAmYWlkLAoJCQkJICAgICAgJnBzZXNzaW9uRW50cnktPmRwaC5kcGhIYXNoVGFibGUpOwojZW5kaWYKCglpZiAod2FpdEZvckFjaykgewoJCU1UUkFDRShxZGZfdHJhY2UoUURGX01PRFVMRV9JRF9QRSwgVFJBQ0VfQ09ERV9UWF9NR01ULAoJCQkJIHBzZXNzaW9uRW50cnktPnBlU2Vzc2lvbklkLAoJCQkJIHBNYWNIZHItPmZjLnN1YlR5cGUpKTsKCQkvKiBRdWV1ZSBEaXNhc3NvY2lhdGlvbiBmcmFtZSBpbiBoaWdoIHByaW9yaXR5IFdRICovCgkJcWRmX3N0YXR1cyA9CgkJCXdtYV90eF9mcmFtZVdpdGhUeENvbXBsZXRlKHBNYWMsIHBQYWNrZXQsICh1aW50MTZfdCkgbkJ5dGVzLAoJCQkJCSBUWFJYX0ZSTV84MDJfMTFfTUdNVCwKCQkJCQkgQU5JX1RYRElSX1RPRFMsIDcsIGxpbV90eF9jb21wbGV0ZSwKCQkJCQkgcEZyYW1lLCBsaW1fZGVhdXRoX3R4X2NvbXBsZXRlX2NuZiwKCQkJCQkgdHhGbGFnLCBzbWVTZXNzaW9uSWQsIGZhbHNlLCAwKTsKCQlNVFJBQ0UocWRmX3RyYWNlCgkJCSAgICAgICAoUURGX01PRFVMRV9JRF9QRSwgVFJBQ0VfQ09ERV9UWF9DT01QTEVURSwKCQkJICAgICAgIHBzZXNzaW9uRW50cnktPnBlU2Vzc2lvbklkLCBxZGZfc3RhdHVzKSk7CgkJLyogUGt0IHdpbGwgYmUgZnJlZWQgdXAgYnkgdGhlIGNhbGxiYWNrIGxpbV90eF9jb21wbGV0ZSAqLwoJCWlmICghUURGX0lTX1NUQVRVU19TVUNDRVNTKHFkZl9zdGF0dXMpKSB7CgkJCXBlX2VycigiRmFpbGVkIHRvIHNlbmQgRGUtQXV0aGVudGljYXRpb24gKCVYKSEiLAoJCQkJcWRmX3N0YXR1cyk7CgoJCQkvKiBDYWxsIGxpbV9wcm9jZXNzX2RlYXV0aF9hY2tfdGltZW91dCB3aGljaCB3aWxsIHNlbmQKCQkJICogRGVhdXRoQ25mIGZvciB0aGlzIGZyYW1lCgkJCSAqLwoJCQlsaW1fcHJvY2Vzc19kZWF1dGhfYWNrX3RpbWVvdXQocE1hYyk7CgkJCXJldHVybjsKCQl9CgoJCXZhbCA9IFNZU19NU19UT19USUNLUyhMSU1fRElTQVNTT0NfREVBVVRIX0FDS19USU1FT1VUKTsKCgkJaWYgKHR4X3RpbWVyX2NoYW5nZQoJCQkgICAgKCZwTWFjLT5saW0ubGltVGltZXJzLmdMaW1EZWF1dGhBY2tUaW1lciwgdmFsLCAwKQoJCSAgICAhPSBUWF9TVUNDRVNTKSB7CgkJCXBlX2VycigiVW5hYmxlIHRvIGNoYW5nZSBEZWF1dGggYWNrIFRpbWVyIHZhbCIpOwoJCQlyZXR1cm47CgkJfSBlbHNlIGlmIChUWF9TVUNDRVNTICE9CgkJCSAgIHR4X3RpbWVyX2FjdGl2YXRlKCZwTWFjLT5saW0ubGltVGltZXJzLgoJCQkJCSAgICAgZ0xpbURlYXV0aEFja1RpbWVyKSkgewoJCQlwZV9lcnIoIlVuYWJsZSB0byBhY3RpdmF0ZSBEZWF1dGggYWNrIFRpbWVyIik7CgkJCWxpbV9kZWFjdGl2YXRlX2FuZF9jaGFuZ2VfdGltZXIocE1hYywKCQkJCQkJCWVMSU1fREVBVVRIX0FDS19USU1FUik7CgkJCXJldHVybjsKCQl9Cgl9IGVsc2UgewoJCU1UUkFDRShxZGZfdHJhY2UoUURGX01PRFVMRV9JRF9QRSwgVFJBQ0VfQ09ERV9UWF9NR01ULAoJCQkJIHBzZXNzaW9uRW50cnktPnBlU2Vzc2lvbklkLAoJCQkJIHBNYWNIZHItPmZjLnN1YlR5cGUpKTsKI2lmZGVmIEZFQVRVUkVfV0xBTl9URExTCgkJaWYgKChOVUxMICE9IHBTdGFEcykKCQkgICAgJiYgKFNUQV9FTlRSWV9URExTX1BFRVIgPT0gcFN0YURzLT5zdGFUeXBlKSkgewoJCQkvKiBRdWV1ZSBEaXNhc3NvY2lhdGlvbiBmcmFtZSBpbiBoaWdoIHByaW9yaXR5IFdRICovCgkJCXFkZl9zdGF0dXMgPQoJCQkJd21hX3R4X2ZyYW1lKHBNYWMsIHBQYWNrZXQsICh1aW50MTZfdCkgbkJ5dGVzLAoJCQkJCSAgIFRYUlhfRlJNXzgwMl8xMV9NR01ULCBBTklfVFhESVJfSUJTUywKCQkJCQkgICA3LCBsaW1fdHhfY29tcGxldGUsIHBGcmFtZSwgdHhGbGFnLAoJCQkJCSAgIHNtZVNlc3Npb25JZCwgMCk7CgkJfSBlbHNlIHsKI2VuZGlmCgkJLyogUXVldWUgRGlzYXNzb2NpYXRpb24gZnJhbWUgaW4gaGlnaCBwcmlvcml0eSBXUSAqLwoJCXFkZl9zdGF0dXMgPQoJCQl3bWFfdHhfZnJhbWUocE1hYywgcFBhY2tldCwgKHVpbnQxNl90KSBuQnl0ZXMsCgkJCQkgICBUWFJYX0ZSTV84MDJfMTFfTUdNVCwgQU5JX1RYRElSX1RPRFMsCgkJCQkgICA3LCBsaW1fdHhfY29tcGxldGUsIHBGcmFtZSwgdHhGbGFnLAoJCQkJICAgc21lU2Vzc2lvbklkLCAwKTsKI2lmZGVmIEZFQVRVUkVfV0xBTl9URExTCgl9CiNlbmRpZgoJCU1UUkFDRShxZGZfdHJhY2UoUURGX01PRFVMRV9JRF9QRSwgVFJBQ0VfQ09ERV9UWF9DT01QTEVURSwKCQkJCSBwc2Vzc2lvbkVudHJ5LT5wZVNlc3Npb25JZCwgcWRmX3N0YXR1cykpOwoJCWlmICghUURGX0lTX1NUQVRVU19TVUNDRVNTKHFkZl9zdGF0dXMpKSB7CgkJCXBlX2VycigiRmFpbGVkIHRvIHNlbmQgRGUtQXV0aGVudGljYXRpb24gKCVYKSEiLAoJCQkJcWRmX3N0YXR1cyk7CgkJCS8qIFBrdCB3aWxsIGJlIGZyZWVkIHVwIGJ5IHRoZSBjYWxsYmFjayAqLwoJCX0KCX0KCn0gLyogRW5kIGxpbV9zZW5kX2RlYXV0aF9tZ210X2ZyYW1lLiAqLwoKI2lmZGVmIEFOSV9TVVBQT1JUXzExSAovKioKICogXGJyaWVmIFNlbmQgYSBNZWFzdXJlbWVudCBSZXBvcnQgQWN0aW9uIGZyYW1lCiAqCiAqCiAqIFxwYXJhbSBwTWFjIFBvaW50ZXIgdG8gdGhlIGdsb2JhbCBNQUMgc3RydWN0dXJlCiAqCiAqIFxwYXJhbSBwTWVhc1JlcUZyYW1lIEFkZHJlc3Mgb2YgYSB0U2lyTWFjTWVhc1JlcUFjdGlvbkZyYW1lCiAqCiAqIFxyZXR1cm4gZVNJUl9TVUNDRVNTIG9uIHN1Y2Nlc3MsIGVTSVJfRkFJTFVSRSBlbHNlCiAqCiAqCiAqLwoKdFNpclJldFN0YXR1cwpsaW1fc2VuZF9tZWFzX3JlcG9ydF9mcmFtZSh0cEFuaVNpckdsb2JhbCBwTWFjLAoJCQkgICB0cFNpck1hY01lYXNSZXFBY3Rpb25GcmFtZSBwTWVhc1JlcUZyYW1lLAoJCQkgICB0U2lyTWFjQWRkciBwZWVyLCB0cFBFU2Vzc2lvbiBwc2Vzc2lvbkVudHJ5KQp7Cgl0RG90MTFmTWVhc3VyZW1lbnRSZXBvcnQgZnJtOwoJdWludDhfdCAqcEZyYW1lOwoJdFNpclJldFN0YXR1cyBuU2lyU3RhdHVzOwoJdHBTaXJNYWNNZ210SGRyIHBNYWNIZHI7Cgl1aW50MzJfdCBuQnl0ZXMsIG5QYXlsb2FkLCBuU3RhdHVzOwoJdm9pZCAqcFBhY2tldDsKCVFERl9TVEFUVVMgcWRmX3N0YXR1czsKCglxZGZfbWVtX3NldCgodWludDhfdCAqKSAmZnJtLCBzaXplb2YoZnJtKSwgMCk7CgoJZnJtLkNhdGVnb3J5LmNhdGVnb3J5ID0gU0lSX01BQ19BQ1RJT05fU1BFQ1RSVU1fTUdNVDsKCWZybS5BY3Rpb24uYWN0aW9uID0gU0lSX01BQ19BQ1RJT05fTUVBU1VSRV9SRVBPUlRfSUQ7Cglmcm0uRGlhbG9nVG9rZW4udG9rZW4gPSBwTWVhc1JlcUZyYW1lLT5hY3Rpb25IZWFkZXIuZGlhbG9nVG9rZW47CgoJc3dpdGNoIChwTWVhc1JlcUZyYW1lLT5tZWFzUmVxSUUubWVhc1R5cGUpIHsKCWNhc2UgU0lSX01BQ19CQVNJQ19NRUFTVVJFTUVOVF9UWVBFOgoJCW5TaXJTdGF0dXMgPQoJCQlwb3B1bGF0ZV9kb3QxMWZfbWVhc3VyZW1lbnRfcmVwb3J0MChwTWFjLCBwTWVhc1JlcUZyYW1lLAoJCQkJCQkJICAgICZmcm0uTWVhc3VyZW1lbnRSZXBvcnQpOwoJCWJyZWFrOwoJY2FzZSBTSVJfTUFDX0NDQV9NRUFTVVJFTUVOVF9UWVBFOgoJCW5TaXJTdGF0dXMgPQoJCQlwb3B1bGF0ZV9kb3QxMWZfbWVhc3VyZW1lbnRfcmVwb3J0MShwTWFjLCBwTWVhc1JlcUZyYW1lLAoJCQkJCQkJICAgICZmcm0uTWVhc3VyZW1lbnRSZXBvcnQpOwoJCWJyZWFrOwoJY2FzZSBTSVJfTUFDX1JQSV9NRUFTVVJFTUVOVF9UWVBFOgoJCW5TaXJTdGF0dXMgPQoJCQlwb3B1bGF0ZV9kb3QxMWZfbWVhc3VyZW1lbnRfcmVwb3J0MihwTWFjLCBwTWVhc1JlcUZyYW1lLAoJCQkJCQkJICAgICZmcm0uTWVhc3VyZW1lbnRSZXBvcnQpOwoJCWJyZWFrOwoJZGVmYXVsdDoKCQlwZV9lcnIoIlVua25vd24gbWVhc3VyZW1lbnQgdHlwZSAlZCBpbiBsaW1TZW4iCgkJICAgICAgICJkTWVhc1JlcG9ydEZyYW1lIiwKCQkJcE1lYXNSZXFGcmFtZS0+bWVhc1JlcUlFLm1lYXNUeXBlKTsKCQlyZXR1cm4gZVNJUl9GQUlMVVJFOwoJfQoKCWlmIChlU0lSX1NVQ0NFU1MgIT0gblNpclN0YXR1cykKCQlyZXR1cm4gZVNJUl9GQUlMVVJFOwoKCW5TdGF0dXMgPSBkb3QxMWZfZ2V0X3BhY2tlZF9tZWFzdXJlbWVudF9yZXBvcnRfc2l6ZShwTWFjLCAmZnJtLCAmblBheWxvYWQpOwoJaWYgKERPVDExRl9GQUlMRUQoblN0YXR1cykpIHsKCQlwZV9lcnIoIkZhaWxlZCB0byBjYWxjdWxhdGUgdGhlIHBhY2tlZCBzaXplIGZvciBhIE1lYXN1cmVtZW50IFJlcG9ydCAoMHglMDh4KSIsCgkJCW5TdGF0dXMpOwoJCS8qIFdlJ2xsIGZhbGwgYmFjayBvbiB0aGUgd29yc3QgY2FzZSBzY2VuYXJpbzogKi8KCQluUGF5bG9hZCA9IHNpemVvZih0RG90MTFmTWVhc3VyZW1lbnRSZXBvcnQpOwoJfSBlbHNlIGlmIChET1QxMUZfV0FSTkVEKG5TdGF0dXMpKSB7CgkJcGVfd2FybigiVGhlcmUgd2VyZSB3YXJuaW5ncyB3aGlsZSBjYWxjdWxhdGluZyB0aGUgcGFja2VkIHNpemUgZm9yIGEgTWVhc3VyZW1lbnQgUmVwb3J0ICgweCUwOHgpIiwKCQkJblN0YXR1cyk7Cgl9CgoJbkJ5dGVzID0gblBheWxvYWQgKyBzaXplb2YodFNpck1hY01nbXRIZHIpOwoKCXFkZl9zdGF0dXMgPQoJCWNkc19wYWNrZXRfYWxsb2MocE1hYy0+aEhkZCwgVFhSWF9GUk1fODAyXzExX01HTVQsCgkJCQkgKHVpbnQxNl90KSBuQnl0ZXMsICh2b2lkICoqKSZwRnJhbWUsCgkJCQkgKHZvaWQgKiopJnBQYWNrZXQpOwoJaWYgKCFRREZfSVNfU1RBVFVTX1NVQ0NFU1MocWRmX3N0YXR1cykpIHsKCQlwZV9lcnIoIkZhaWxlZCB0byBhbGxvY2F0ZSAlZCBieXRlcyBmb3IgYSAiCgkJICAgICAgICJEZS1BdXRoZW50aWNhdGlvbiIsIG5CeXRlcyk7CgkJcmV0dXJuIGVTSVJfRkFJTFVSRTsKCX0KCS8qIFBhcmFub2lhOiAqLwoJcWRmX21lbV9zZXQocEZyYW1lLCBuQnl0ZXMsIDApOwoKCS8qIE5leHQsIHdlIGZpbGwgb3V0IHRoZSBidWZmZXIgZGVzY3JpcHRvcjogKi8KCWxpbV9wb3B1bGF0ZV9tYWNfaGVhZGVyKHBNYWMsIHBGcmFtZSwgU0lSX01BQ19NR01UX0ZSQU1FLAoJCVNJUl9NQUNfTUdNVF9BQ1RJT04sIHBlZXIpOwoJcE1hY0hkciA9ICh0cFNpck1hY01nbXRIZHIpIHBGcmFtZTsKCglxZGZfbWVtX2NvcHkocE1hY0hkci0+YnNzSWQsIHBzZXNzaW9uRW50cnktPmJzc0lkLCBzaXplb2YodFNpck1hY0FkZHIpKTsKCiNpZmRlZiBXTEFOX0ZFQVRVUkVfMTFXCglsaW1fc2V0X3Byb3RlY3RlZF9iaXQocE1hYywgcHNlc3Npb25FbnRyeSwgcGVlciwgcE1hY0hkcik7CiNlbmRpZgoKCW5TdGF0dXMgPSBkb3QxMWZfcGFja19tZWFzdXJlbWVudF9yZXBvcnQocE1hYywgJmZybSwgcEZyYW1lICsKCQkJCQkJIHNpemVvZih0U2lyTWFjTWdtdEhkciksCgkJCQkJCSBuUGF5bG9hZCwgJm5QYXlsb2FkKTsKCWlmIChET1QxMUZfRkFJTEVEKG5TdGF0dXMpKSB7CgkJcGVfZXJyKCJGYWlsZWQgdG8gcGFjayBhIE1lYXN1cmVtZW50IFJlcG9ydCAoMHglMDh4KSIsCgkJCW5TdGF0dXMpOwoJCWNkc19wYWNrZXRfZnJlZShwTWFjLT5oSGRkLCBUWFJYX0ZSTV84MDJfMTFfTUdNVCwKCQkJCSh2b2lkICopcEZyYW1lLCAodm9pZCAqKXBQYWNrZXQpOwoJCXJldHVybiBlU0lSX0ZBSUxVUkU7ICAgIC8qIGFsbG9jYXRlZCEgKi8KCX0gZWxzZSBpZiAoRE9UMTFGX1dBUk5FRChuU3RhdHVzKSkgewoJCXBlX3dhcm4oIlRoZXJlIHdlcmUgd2FybmluZ3Mgd2hpbGUgcGFja2luZyBhIE1lYXN1cmVtZW50IFJlcG9ydCAoMHglMDh4KSIsCgkJCW5TdGF0dXMpOwoJfQoKCU1UUkFDRShxZGZfdHJhY2UoUURGX01PRFVMRV9JRF9QRSwgVFJBQ0VfQ09ERV9UWF9NR01ULAoJCQkgKChwc2Vzc2lvbkVudHJ5KSA/IHBzZXNzaW9uRW50cnktPgoJCQkgIHBlU2Vzc2lvbklkIDogTk9fU0VTU0lPTiksIHBNYWNIZHItPmZjLnN1YlR5cGUpKTsKCXFkZl9zdGF0dXMgPQoJCXdtYV90eF9mcmFtZShwTWFjLCBwUGFja2V0LCAodWludDE2X3QpIG5CeXRlcywKCQkJICAgVFhSWF9GUk1fODAyXzExX01HTVQsIEFOSV9UWERJUl9UT0RTLCA3LAoJCQkgICBsaW1fdHhfY29tcGxldGUsIHBGcmFtZSwgMCwgMCk7CglNVFJBQ0UocWRmX3RyYWNlCgkJICAgICAgIChRREZfTU9EVUxFX0lEX1BFLCBUUkFDRV9DT0RFX1RYX0NPTVBMRVRFLAoJCSAgICAgICAoKHBzZXNzaW9uRW50cnkpID8gcHNlc3Npb25FbnRyeS0+cGVTZXNzaW9uSWQgOiBOT19TRVNTSU9OKSwKCQkgICAgICAgcWRmX3N0YXR1cykpOwoJaWYgKCFRREZfSVNfU1RBVFVTX1NVQ0NFU1MocWRmX3N0YXR1cykpIHsKCQlwZV9lcnIoIkZhaWxlZCB0byBzZW5kIGEgTWVhc3VyZW1lbnQgUmVwb3J0ICglWCkhIiwKCQkJcWRmX3N0YXR1cyk7CgkJLyogUGt0IHdpbGwgYmUgZnJlZWQgdXAgYnkgdGhlIGNhbGxiYWNrICovCgkJcmV0dXJuIGVTSVJfRkFJTFVSRTsgICAgLyoganVzdCBhbGxvY2F0ZWQuLi4gKi8KCX0KCglyZXR1cm4gZVNJUl9TVUNDRVNTOwoKfSAvKiBFbmQgbGltX3NlbmRfbWVhc19yZXBvcnRfZnJhbWUuICovCgovKioKICogXGJyaWVmIFNlbmQgYSBUUEMgUmVxdWVzdCBBY3Rpb24gZnJhbWUKICoKICoKICogXHBhcmFtIHBNYWMgUG9pbnRlciB0byB0aGUgZ2xvYmFsIE1BQyBkYXRhc3RydWN0dXJlCiAqCiAqIFxwYXJhbSBwZWVyIE1BQyBhZGRyZXNzIHRvIHdoaWNoIHRoZSBmcmFtZSBzaG91bGQgYmUgc2VudAogKgogKgogKi8KCnZvaWQKbGltX3NlbmRfdHBjX3JlcXVlc3RfZnJhbWUodHBBbmlTaXJHbG9iYWwgcE1hYywKCQkJICAgdFNpck1hY0FkZHIgcGVlciwgdHBQRVNlc3Npb24gcHNlc3Npb25FbnRyeSkKewoJdERvdDExZlRQQ1JlcXVlc3QgZnJtOwoJdWludDhfdCAqcEZyYW1lOwoJdHBTaXJNYWNNZ210SGRyIHBNYWNIZHI7Cgl1aW50MzJfdCBuQnl0ZXMsIG5QYXlsb2FkLCBuU3RhdHVzOwoJdm9pZCAqcFBhY2tldDsKCVFERl9TVEFUVVMgcWRmX3N0YXR1czsKCglxZGZfbWVtX3NldCgodWludDhfdCAqKSAmZnJtLCBzaXplb2YoZnJtKSwgMCk7CgoJZnJtLkNhdGVnb3J5LmNhdGVnb3J5ID0gU0lSX01BQ19BQ1RJT05fU1BFQ1RSVU1fTUdNVDsKCWZybS5BY3Rpb24uYWN0aW9uID0gU0lSX01BQ19BQ1RJT05fVFBDX1JFUVVFU1RfSUQ7Cglmcm0uRGlhbG9nVG9rZW4udG9rZW4gPSAxOwoJZnJtLlRQQ1JlcXVlc3QucHJlc2VudCA9IDE7CgoJblN0YXR1cyA9IGRvdDExZl9nZXRfcGFja2VkX3RwY19yZXF1ZXN0X3NpemUocE1hYywgJmZybSwgJm5QYXlsb2FkKTsKCWlmIChET1QxMUZfRkFJTEVEKG5TdGF0dXMpKSB7CgkJcGVfZXJyKCJGYWlsZWQgdG8gY2FsY3VsYXRlIHRoZSBwYWNrZWQgc2l6ZSBmb3IgYSBUUEMgUmVxdWVzdCAoMHglMDh4KSIsIG5TdGF0dXMpOwoJCS8qIFdlJ2xsIGZhbGwgYmFjayBvbiB0aGUgd29yc3QgY2FzZSBzY2VuYXJpbzogKi8KCQluUGF5bG9hZCA9IHNpemVvZih0RG90MTFmVFBDUmVxdWVzdCk7Cgl9IGVsc2UgaWYgKERPVDExRl9XQVJORUQoblN0YXR1cykpIHsKCQlwZV93YXJuKCJUaGVyZSB3ZXJlIHdhcm5pbmdzIHdoaWxlIGNhbGN1bGF0aW5nIHRoZSBwYWNrZWQgc2l6ZSBmb3IgYSBUUEMgUmVxdWVzdCAoMHglMDh4KSIsCgkJCW5TdGF0dXMpOwoJfQoKCW5CeXRlcyA9IG5QYXlsb2FkICsgc2l6ZW9mKHRTaXJNYWNNZ210SGRyKTsKCglxZGZfc3RhdHVzID0KCQljZHNfcGFja2V0X2FsbG9jKHBNYWMtPmhIZGQsIFRYUlhfRlJNXzgwMl8xMV9NR01ULAoJCQkJICh1aW50MTZfdCkgbkJ5dGVzLCAodm9pZCAqKikmcEZyYW1lLAoJCQkJICh2b2lkICoqKSZwUGFja2V0KTsKCWlmICghUURGX0lTX1NUQVRVU19TVUNDRVNTKHFkZl9zdGF0dXMpKSB7CgkJcGVfZXJyKCJGYWlsZWQgdG8gYWxsb2NhdGUgJWQgYnl0ZXMgZm9yIGEgVFBDIgoJCQkiIFJlcXVlc3QiLCBuQnl0ZXMpOwoJCXJldHVybjsKCX0KCS8qIFBhcmFub2lhOiAqLwoJcWRmX21lbV9zZXQocEZyYW1lLCBuQnl0ZXMsIDApOwoKCS8qIE5leHQsIHdlIGZpbGwgb3V0IHRoZSBidWZmZXIgZGVzY3JpcHRvcjogKi8KCWxpbV9wb3B1bGF0ZV9tYWNfaGVhZGVyKHBNYWMsIHBGcmFtZSwgU0lSX01BQ19NR01UX0ZSQU1FLAoJCVNJUl9NQUNfTUdNVF9BQ1RJT04sIHBlZXIpOwoJcE1hY0hkciA9ICh0cFNpck1hY01nbXRIZHIpIHBGcmFtZTsKCglxZGZfbWVtX2NvcHkocE1hY0hkci0+YnNzSWQsIHBzZXNzaW9uRW50cnktPmJzc0lkLCBzaXplb2YodFNpck1hY0FkZHIpKTsKCiNpZmRlZiBXTEFOX0ZFQVRVUkVfMTFXCglsaW1fc2V0X3Byb3RlY3RlZF9iaXQocE1hYywgcHNlc3Npb25FbnRyeSwgcGVlciwgcE1hY0hkcik7CiNlbmRpZgoKCW5TdGF0dXMgPSBkb3QxMWZfcGFja190cGNfcmVxdWVzdChwTWFjLCAmZnJtLCBwRnJhbWUgKwoJCQkJCSAgc2l6ZW9mKHRTaXJNYWNNZ210SGRyKSwKCQkJCQkgIG5QYXlsb2FkLCAmblBheWxvYWQpOwoJaWYgKERPVDExRl9GQUlMRUQoblN0YXR1cykpIHsKCQlwZV9lcnIoIkZhaWxlZCB0byBwYWNrIGEgVFBDIFJlcXVlc3QgKDB4JTA4eCkiLAoJCQluU3RhdHVzKTsKCQljZHNfcGFja2V0X2ZyZWUocE1hYy0+aEhkZCwgVFhSWF9GUk1fODAyXzExX01HTVQsCgkJCQkodm9pZCAqKXBGcmFtZSwgKHZvaWQgKilwUGFja2V0KTsKCQlyZXR1cm47ICAgICAgICAgLyogYWxsb2NhdGVkISAqLwoJfSBlbHNlIGlmIChET1QxMUZfV0FSTkVEKG5TdGF0dXMpKSB7CgkJcGVfd2FybigiVGhlcmUgd2VyZSB3YXJuaW5ncyB3aGlsZSBwYWNraW5nIGEgVFBDIFJlcXVlc3QgKDB4JTA4eCkiLAoJCQluU3RhdHVzKTsKCX0KCglNVFJBQ0UocWRmX3RyYWNlKFFERl9NT0RVTEVfSURfUEUsIFRSQUNFX0NPREVfVFhfTUdNVCwKCQkJICgocHNlc3Npb25FbnRyeSkgPyBwc2Vzc2lvbkVudHJ5LT4KCQkJICBwZVNlc3Npb25JZCA6IE5PX1NFU1NJT04pLCBwTWFjSGRyLT5mYy5zdWJUeXBlKSk7CglxZGZfc3RhdHVzID0KCQl3bWFfdHhfZnJhbWUocE1hYywgcFBhY2tldCwgKHVpbnQxNl90KSBuQnl0ZXMsCgkJCSAgIFRYUlhfRlJNXzgwMl8xMV9NR01ULCBBTklfVFhESVJfVE9EUywgNywKCQkJICAgbGltX3R4X2NvbXBsZXRlLCBwRnJhbWUsIDAsIDApOwoJTVRSQUNFKHFkZl90cmFjZQoJCSAgICAgICAoUURGX01PRFVMRV9JRF9QRSwgVFJBQ0VfQ09ERV9UWF9DT01QTEVURSwKCQkgICAgICAgKChwc2Vzc2lvbkVudHJ5KSA/IHBzZXNzaW9uRW50cnktPnBlU2Vzc2lvbklkIDogTk9fU0VTU0lPTiksCgkJICAgICAgIHFkZl9zdGF0dXMpKTsKCWlmICghUURGX0lTX1NUQVRVU19TVUNDRVNTKHFkZl9zdGF0dXMpKSB7CgkJcGVfZXJyKCJGYWlsZWQgdG8gc2VuZCBhIFRQQyBSZXF1ZXN0ICglWCkhIiwKCQkJcWRmX3N0YXR1cyk7CgkJLyogUGt0IHdpbGwgYmUgZnJlZWQgdXAgYnkgdGhlIGNhbGxiYWNrICovCgl9Cgp9IC8qIEVuZCBsaW1fc2VuZF90cGNfcmVxdWVzdF9mcmFtZS4gKi8KCi8qKgogKiBcYnJpZWYgU2VuZCBhIFRQQyBSZXBvcnQgQWN0aW9uIGZyYW1lCiAqCiAqCiAqIFxwYXJhbSBwTWFjIFBvaW50ZXIgdG8gdGhlIGdsb2JhbCBNQUMgZGF0YXN0cnVjdHVyZQogKgogKiBccGFyYW0gcFRwY1JlcUZyYW1lIFBvaW50ZXIgdG8gdGhlIHJlY2VpdmVkIFRQQyBSZXF1ZXN0CiAqCiAqIFxyZXR1cm4gZVNJUl9TVUNDRVNTIG9uIHN1Y2Nlc3MsIGVTSVJfRkFJTFVSRSBlbHNlCiAqCiAqCiAqLwoKdFNpclJldFN0YXR1cwpsaW1fc2VuZF90cGNfcmVwb3J0X2ZyYW1lKHRwQW5pU2lyR2xvYmFsIHBNYWMsCgkJCSAgdHBTaXJNYWNUcGNSZXFBY3Rpb25GcmFtZSBwVHBjUmVxRnJhbWUsCgkJCSAgdFNpck1hY0FkZHIgcGVlciwgdHBQRVNlc3Npb24gcHNlc3Npb25FbnRyeSkKewoJdERvdDExZlRQQ1JlcG9ydCBmcm07Cgl1aW50OF90ICpwRnJhbWU7Cgl0cFNpck1hY01nbXRIZHIgcE1hY0hkcjsKCXVpbnQzMl90IG5CeXRlcywgblBheWxvYWQsIG5TdGF0dXM7Cgl2b2lkICpwUGFja2V0OwoJUURGX1NUQVRVUyBxZGZfc3RhdHVzOwoKCXFkZl9tZW1fc2V0KCh1aW50OF90ICopICZmcm0sIHNpemVvZihmcm0pLCAwKTsKCglmcm0uQ2F0ZWdvcnkuY2F0ZWdvcnkgPSBTSVJfTUFDX0FDVElPTl9TUEVDVFJVTV9NR01UOwoJZnJtLkFjdGlvbi5hY3Rpb24gPSBTSVJfTUFDX0FDVElPTl9UUENfUkVQT1JUX0lEOwoJZnJtLkRpYWxvZ1Rva2VuLnRva2VuID0gcFRwY1JlcUZyYW1lLT5hY3Rpb25IZWFkZXIuZGlhbG9nVG9rZW47CgoJZnJtLlRQQ1JlcG9ydC50eF9wb3dlciA9IDA7Cglmcm0uVFBDUmVwb3J0LmxpbmtfbWFyZ2luID0gMDsKCWZybS5UUENSZXBvcnQucHJlc2VudCA9IDE7CgoJblN0YXR1cyA9IGRvdDExZl9nZXRfcGFja2VkX3RwY19yZXBvcnRfc2l6ZShwTWFjLCAmZnJtLCAmblBheWxvYWQpOwoJaWYgKERPVDExRl9GQUlMRUQoblN0YXR1cykpIHsKCQlwZV9lcnIoIkZhaWxlZCB0byBjYWxjdWxhdGUgdGhlIHBhY2tlZCBzaXplIGZvciBhIFRQQyBSZXBvcnQgKDB4JTA4eCkiLCBuU3RhdHVzKTsKCQkvKiBXZSdsbCBmYWxsIGJhY2sgb24gdGhlIHdvcnN0IGNhc2Ugc2NlbmFyaW86ICovCgkJblBheWxvYWQgPSBzaXplb2YodERvdDExZlRQQ1JlcG9ydCk7Cgl9IGVsc2UgaWYgKERPVDExRl9XQVJORUQoblN0YXR1cykpIHsKCQlwZV93YXJuKCJUaGVyZSB3ZXJlIHdhcm5pbmdzIHdoaWxlIGNhbGN1bGF0aW5nIHRoZSBwYWNrZWQgc2l6ZSBmb3IgYSBUUEMgUmVwb3J0ICgweCUwOHgpIiwKCQkJblN0YXR1cyk7Cgl9CgoJbkJ5dGVzID0gblBheWxvYWQgKyBzaXplb2YodFNpck1hY01nbXRIZHIpOwoKCXFkZl9zdGF0dXMgPQoJCWNkc19wYWNrZXRfYWxsb2MocE1hYy0+aEhkZCwgVFhSWF9GUk1fODAyXzExX01HTVQsCgkJCQkgKHVpbnQxNl90KSBuQnl0ZXMsICh2b2lkICoqKSZwRnJhbWUsCgkJCQkgKHZvaWQgKiopJnBQYWNrZXQpOwoJaWYgKCFRREZfSVNfU1RBVFVTX1NVQ0NFU1MocWRmX3N0YXR1cykpIHsKCQlwZV9lcnIoIkZhaWxlZCB0byBhbGxvY2F0ZSAlZCBieXRlcyBmb3IgYSBUUEMiCgkJCSIgUmVwb3J0IiwgbkJ5dGVzKTsKCQlyZXR1cm4gZVNJUl9GQUlMVVJFOwoJfQoJLyogUGFyYW5vaWE6ICovCglxZGZfbWVtX3NldChwRnJhbWUsIG5CeXRlcywgMCk7CgoJLyogTmV4dCwgd2UgZmlsbCBvdXQgdGhlIGJ1ZmZlciBkZXNjcmlwdG9yOiAqLwoJbGltX3BvcHVsYXRlX21hY19oZWFkZXIocE1hYywgcEZyYW1lLCBTSVJfTUFDX01HTVRfRlJBTUUsCgkJU0lSX01BQ19NR01UX0FDVElPTiwgcGVlcik7CgoJcE1hY0hkciA9ICh0cFNpck1hY01nbXRIZHIpIHBGcmFtZTsKCglxZGZfbWVtX2NvcHkocE1hY0hkci0+YnNzSWQsIHBzZXNzaW9uRW50cnktPmJzc0lkLCBzaXplb2YodFNpck1hY0FkZHIpKTsKCiNpZmRlZiBXTEFOX0ZFQVRVUkVfMTFXCglsaW1fc2V0X3Byb3RlY3RlZF9iaXQocE1hYywgcHNlc3Npb25FbnRyeSwgcGVlciwgcE1hY0hkcik7CiNlbmRpZgoKCW5TdGF0dXMgPSBkb3QxMWZfcGFja190cGNfcmVwb3J0KHBNYWMsICZmcm0sIHBGcmFtZSArCgkJCQkJIHNpemVvZih0U2lyTWFjTWdtdEhkciksCgkJCQkJIG5QYXlsb2FkLCAmblBheWxvYWQpOwoJaWYgKERPVDExRl9GQUlMRUQoblN0YXR1cykpIHsKCQlwZV9lcnIoIkZhaWxlZCB0byBwYWNrIGEgVFBDIFJlcG9ydCAoMHglMDh4KSIsCgkJCW5TdGF0dXMpOwoJCWNkc19wYWNrZXRfZnJlZShwTWFjLT5oSGRkLCBUWFJYX0ZSTV84MDJfMTFfTUdNVCwKCQkJCSh2b2lkICopcEZyYW1lLCAodm9pZCAqKXBQYWNrZXQpOwoJCXJldHVybiBlU0lSX0ZBSUxVUkU7ICAgIC8qIGFsbG9jYXRlZCEgKi8KCX0gZWxzZSBpZiAoRE9UMTFGX1dBUk5FRChuU3RhdHVzKSkgewoJCXBlX3dhcm4oIlRoZXJlIHdlcmUgd2FybmluZ3Mgd2hpbGUgcGFja2luZyBhIFRQQyBSZXBvcnQgKDB4JTA4eCkiLAoJCQluU3RhdHVzKTsKCglNVFJBQ0UocWRmX3RyYWNlKFFERl9NT0RVTEVfSURfUEUsIFRSQUNFX0NPREVfVFhfTUdNVCwKCQkJICgocHNlc3Npb25FbnRyeSkgPyBwc2Vzc2lvbkVudHJ5LT4KCQkJICBwZVNlc3Npb25JZCA6IE5PX1NFU1NJT04pLCBwTWFjSGRyLT5mYy5zdWJUeXBlKSk7CglxZGZfc3RhdHVzID0KCQl3bWFfdHhfZnJhbWUocE1hYywgcFBhY2tldCwgKHVpbnQxNl90KSBuQnl0ZXMsCgkJCSAgIFRYUlhfRlJNXzgwMl8xMV9NR01ULCBBTklfVFhESVJfVE9EUywgNywKCQkJICAgbGltX3R4X2NvbXBsZXRlLCBwRnJhbWUsIDAsIDApOwoJTVRSQUNFKHFkZl90cmFjZQoJCShRREZfTU9EVUxFX0lEX1BFLCBUUkFDRV9DT0RFX1RYX0NPTVBMRVRFLAoJCSgocHNlc3Npb25FbnRyeSkgPyBwc2Vzc2lvbkVudHJ5LT5wZVNlc3Npb25JZCA6IE5PX1NFU1NJT04pLAoJCXFkZl9zdGF0dXMpKTsKCWlmICghUURGX0lTX1NUQVRVU19TVUNDRVNTKHFkZl9zdGF0dXMpKSB7CgkJcGVfZXJyKCJGYWlsZWQgdG8gc2VuZCBhIFRQQyBSZXBvcnQgKCVYKSEiLAoJCQlxZGZfc3RhdHVzKTsKCQkvKiBQa3Qgd2lsbCBiZSBmcmVlZCB1cCBieSB0aGUgY2FsbGJhY2sgKi8KCQlyZXR1cm4gZVNJUl9GQUlMVVJFOyAgICAvKiBqdXN0IGFsbG9jYXRlZC4uLiAqLwoJfQoKCXJldHVybiBlU0lSX1NVQ0NFU1M7Cgp9IC8qIEVuZCBsaW1fc2VuZF90cGNfcmVwb3J0X2ZyYW1lLiAqLwojZW5kaWYgLyogQU5JX1NVUFBPUlRfMTFIICovCgovKioKICogXGJyaWVmIFNlbmQgYSBDaGFubmVsIFN3aXRjaCBBbm5vdW5jZW1lbnQKICoKICoKICogXHBhcmFtIHBNYWMgUG9pbnRlciB0byB0aGUgZ2xvYmFsIE1BQyBkYXRhc3RydWN0dXJlCiAqCiAqIFxwYXJhbSBwZWVyIE1BQyBhZGRyZXNzIHRvIHdoaWNoIHRoaXMgZnJhbWUgd2lsbCBiZSBzZW50CiAqCiAqIFxwYXJhbSBuTW9kZQogKgogKiBccGFyYW0gbk5ld0NoYW5uZWwKICoKICogXHBhcmFtIG5Db3VudAogKgogKiBccmV0dXJuIGVTSVJfU1VDQ0VTUyBvbiBzdWNjZXNzLCBlU0lSX0ZBSUxVUkUgZWxzZQogKgogKgogKi8KCnRTaXJSZXRTdGF0dXMKbGltX3NlbmRfY2hhbm5lbF9zd2l0Y2hfbWdtdF9mcmFtZSh0cEFuaVNpckdsb2JhbCBwTWFjLAoJCQkJICAgdFNpck1hY0FkZHIgcGVlciwKCQkJCSAgIHVpbnQ4X3Qgbk1vZGUsCgkJCQkgICB1aW50OF90IG5OZXdDaGFubmVsLAoJCQkJICAgdWludDhfdCBuQ291bnQsIHRwUEVTZXNzaW9uIHBzZXNzaW9uRW50cnkpCnsKCXREb3QxMWZDaGFubmVsU3dpdGNoIGZybTsKCXVpbnQ4X3QgKnBGcmFtZTsKCXRwU2lyTWFjTWdtdEhkciBwTWFjSGRyOwoJdWludDMyX3QgbkJ5dGVzLCBuUGF5bG9hZCwgblN0YXR1czsgICAgIC8qICwgbkNmZzsgKi8KCXZvaWQgKnBQYWNrZXQ7CglRREZfU1RBVFVTIHFkZl9zdGF0dXM7Cgl1aW50OF90IHR4RmxhZyA9IDA7CgoJdWludDhfdCBzbWVTZXNzaW9uSWQgPSAwOwoKCWlmIChwc2Vzc2lvbkVudHJ5ID09IE5VTEwpIHsKCQlwZV9lcnIoIlNlc3Npb24gZW50cnkgaXMgTlVMTCEhISIpOwoJCXJldHVybiBlU0lSX0ZBSUxVUkU7Cgl9CglzbWVTZXNzaW9uSWQgPSBwc2Vzc2lvbkVudHJ5LT5zbWVTZXNzaW9uSWQ7CgoJcWRmX21lbV9zZXQoKHVpbnQ4X3QgKikgJmZybSwgc2l6ZW9mKGZybSksIDApOwoKCWZybS5DYXRlZ29yeS5jYXRlZ29yeSA9IFNJUl9NQUNfQUNUSU9OX1NQRUNUUlVNX01HTVQ7Cglmcm0uQWN0aW9uLmFjdGlvbiA9IFNJUl9NQUNfQUNUSU9OX0NIQU5ORUxfU1dJVENIX0lEOwoJZnJtLkNoYW5Td2l0Y2hBbm4uc3dpdGNoTW9kZSA9IG5Nb2RlOwoJZnJtLkNoYW5Td2l0Y2hBbm4ubmV3Q2hhbm5lbCA9IG5OZXdDaGFubmVsOwoJZnJtLkNoYW5Td2l0Y2hBbm4uc3dpdGNoQ291bnQgPSBuQ291bnQ7Cglmcm0uQ2hhblN3aXRjaEFubi5wcmVzZW50ID0gMTsKCgluU3RhdHVzID0gZG90MTFmX2dldF9wYWNrZWRfY2hhbm5lbF9zd2l0Y2hfc2l6ZShwTWFjLCAmZnJtLCAmblBheWxvYWQpOwoJaWYgKERPVDExRl9GQUlMRUQoblN0YXR1cykpIHsKCQlwZV9lcnIoIkZhaWxlZCB0byBjYWxjdWxhdGUgdGhlIHBhY2tlZCBzaXplIGZvciBhIENoYW5uZWwgU3dpdGNoICgweCUwOHgpIiwKCQkJblN0YXR1cyk7CgkJLyogV2UnbGwgZmFsbCBiYWNrIG9uIHRoZSB3b3JzdCBjYXNlIHNjZW5hcmlvOiAqLwoJCW5QYXlsb2FkID0gc2l6ZW9mKHREb3QxMWZDaGFubmVsU3dpdGNoKTsKCX0gZWxzZSBpZiAoRE9UMTFGX1dBUk5FRChuU3RhdHVzKSkgewoJCXBlX3dhcm4oIlRoZXJlIHdlcmUgd2FybmluZ3Mgd2hpbGUgY2FsY3VsYXRpbmcgdGhlIHBhY2tlZCBzaXplIGZvciBhIENoYW5uZWwgU3dpdGNoICgweCUwOHgpIiwKCQkJblN0YXR1cyk7Cgl9CgoJbkJ5dGVzID0gblBheWxvYWQgKyBzaXplb2YodFNpck1hY01nbXRIZHIpOwoKCXFkZl9zdGF0dXMgPQoJCWNkc19wYWNrZXRfYWxsb2MoKHVpbnQxNl90KSBuQnl0ZXMsICh2b2lkICoqKSZwRnJhbWUsCgkJCQkgKHZvaWQgKiopJnBQYWNrZXQpOwoJaWYgKCFRREZfSVNfU1RBVFVTX1NVQ0NFU1MocWRmX3N0YXR1cykpIHsKCQlwZV9lcnIoIkZhaWxlZCB0byBhbGxvY2F0ZSAlZCBieXRlcyBmb3IgYSBUUEMgUmVwb3J0IiwgbkJ5dGVzKTsKCQlyZXR1cm4gZVNJUl9GQUlMVVJFOwoJfQoJLyogUGFyYW5vaWE6ICovCglxZGZfbWVtX3NldChwRnJhbWUsIG5CeXRlcywgMCk7CgoJLyogTmV4dCwgd2UgZmlsbCBvdXQgdGhlIGJ1ZmZlciBkZXNjcmlwdG9yOiAqLwoJbGltX3BvcHVsYXRlX21hY19oZWFkZXIocE1hYywgcEZyYW1lLCBTSVJfTUFDX01HTVRfRlJBTUUsCgkJU0lSX01BQ19NR01UX0FDVElPTiwgcGVlciwKCQlwc2Vzc2lvbkVudHJ5LT5zZWxmTWFjQWRkcik7CglwTWFjSGRyID0gKHRwU2lyTWFjTWdtdEhkcikgcEZyYW1lOwoJcWRmX21lbV9jb3B5KCh1aW50OF90ICopIHBNYWNIZHItPmJzc0lkLAoJCSAgICAgKHVpbnQ4X3QgKikgcHNlc3Npb25FbnRyeS0+YnNzSWQsIHNpemVvZih0U2lyTWFjQWRkcikpOwoKI2lmZGVmIFdMQU5fRkVBVFVSRV8xMVcKCWxpbV9zZXRfcHJvdGVjdGVkX2JpdChwTWFjLCBwc2Vzc2lvbkVudHJ5LCBwZWVyLCBwTWFjSGRyKTsKI2VuZGlmCgoJblN0YXR1cyA9IGRvdDExZl9wYWNrX2NoYW5uZWxfc3dpdGNoKHBNYWMsICZmcm0sIHBGcmFtZSArCgkJCQkJICAgICBzaXplb2YodFNpck1hY01nbXRIZHIpLAoJCQkJCSAgICAgblBheWxvYWQsICZuUGF5bG9hZCk7CglpZiAoRE9UMTFGX0ZBSUxFRChuU3RhdHVzKSkgewoJCXBlX2VycigiRmFpbGVkIHRvIHBhY2sgYSBDaGFubmVsIFN3aXRjaCAoMHglMDh4KSIsCgkJCW5TdGF0dXMpOwoJCWNkc19wYWNrZXRfZnJlZSgodm9pZCAqKXBQYWNrZXQpOwoJCXJldHVybiBlU0lSX0ZBSUxVUkU7ICAgIC8qIGFsbG9jYXRlZCEgKi8KCX0gZWxzZSBpZiAoRE9UMTFGX1dBUk5FRChuU3RhdHVzKSkgewoJCXBlX3dhcm4oIlRoZXJlIHdlcmUgd2FybmluZ3Mgd2hpbGUgcGFja2luZyBhIENoYW5uZWwgU3dpdGNoICgweCUwOHgpIiwKCQkJblN0YXR1cyk7Cgl9CgoJaWYgKChTSVJfQkFORF81X0dIWiA9PSBsaW1fZ2V0X3JmX2JhbmQocHNlc3Npb25FbnRyeS0+Y3VycmVudE9wZXJDaGFubmVsKSkKCSAgICB8fCAocHNlc3Npb25FbnRyeS0+cGVQZXJzb25hID09IFFERl9QMlBfQ0xJRU5UX01PREUpIHx8CgkgICAgKHBzZXNzaW9uRW50cnktPnBlUGVyc29uYSA9PSBRREZfUDJQX0dPX01PREUpCgkgICAgKSB7CgkJdHhGbGFnIHw9IEhBTF9VU0VfQkRfUkFURTJfRk9SX01BTkFHRU1FTlRfRlJBTUU7Cgl9CgoJTVRSQUNFKHFkZl90cmFjZShRREZfTU9EVUxFX0lEX1BFLCBUUkFDRV9DT0RFX1RYX01HTVQsCgkJCSBwc2Vzc2lvbkVudHJ5LT5wZVNlc3Npb25JZCwgcE1hY0hkci0+ZmMuc3ViVHlwZSkpOwoJcWRmX3N0YXR1cyA9IHdtYV90eF9mcmFtZShwTWFjLCBwUGFja2V0LCAodWludDE2X3QpIG5CeXRlcywKCQkJCVRYUlhfRlJNXzgwMl8xMV9NR01ULAoJCQkJQU5JX1RYRElSX1RPRFMsCgkJCQk3LCBsaW1fdHhfY29tcGxldGUsIHBGcmFtZSwgdHhGbGFnLAoJCQkJc21lU2Vzc2lvbklkLCAwKTsKCU1UUkFDRShxZGZfdHJhY2UoUURGX01PRFVMRV9JRF9QRSwgVFJBQ0VfQ09ERV9UWF9DT01QTEVURSwKCQkJIHBzZXNzaW9uRW50cnktPnBlU2Vzc2lvbklkLCBxZGZfc3RhdHVzKSk7CglpZiAoIVFERl9JU19TVEFUVVNfU1VDQ0VTUyhxZGZfc3RhdHVzKSkgewoJCXBlX2VycigiRmFpbGVkIHRvIHNlbmQgYSBDaGFubmVsIFN3aXRjaCAoJVgpISIsCgkJCXFkZl9zdGF0dXMpOwoJCS8qIFBrdCB3aWxsIGJlIGZyZWVkIHVwIGJ5IHRoZSBjYWxsYmFjayAqLwoJCXJldHVybiBlU0lSX0ZBSUxVUkU7Cgl9CgoJcmV0dXJuIGVTSVJfU1VDQ0VTUzsKCn0gLyogRW5kIGxpbV9zZW5kX2NoYW5uZWxfc3dpdGNoX21nbXRfZnJhbWUuICovCgovKioKICogbGltX3NlbmRfZXh0ZW5kZWRfY2hhbl9zd2l0Y2hfYWN0aW9uX2ZyYW1lKCktIGZ1bmN0aW9uIHRvIHNlbmQgRUNTQQogKiBhY3Rpb24gZnJhbWUgb3ZlciB0aGUgYWlyIC4KICogQG1hY19jdHg6IHBvaW50ZXIgdG8gZ2xvYmFsIG1hYyBzdHJ1Y3R1cmUKICogQHBlZXI6IERlc3RpbmF0aW9uIG1hYy4KICogQG1vZGU6IGNoYW5uZWwgc3dpdGNoIG1vZGUKICogQG5ld19vcF9jbGFzczogbmV3IG9wIGNsYXNzCiAqIEBuZXdfY2hhbm5lbDogbmV3IGNoYW5uZWwgdG8gc3dpdGNoCiAqIEBjb3VudDogY2hhbm5lbCBzd2l0Y2ggY291bnQKICoKICogVGhpcyBmdW5jdGlvbiBpcyBjYWxsZWQgdG8gc2VuZCBFQ1NBIGZyYW1lLgogKgogKiBSZXR1cm46IHN1Y2Nlc3MgaWYgZnJhbWUgaXMgc2VudCBlbHNlIHJldHVybiBmYWlsdXJlCiAqLwoKdFNpclJldFN0YXR1cwpsaW1fc2VuZF9leHRlbmRlZF9jaGFuX3N3aXRjaF9hY3Rpb25fZnJhbWUodHBBbmlTaXJHbG9iYWwgbWFjX2N0eCwKCQl0U2lyTWFjQWRkciBwZWVyLCB1aW50OF90IG1vZGUsIHVpbnQ4X3QgbmV3X29wX2NsYXNzLAoJCXVpbnQ4X3QgbmV3X2NoYW5uZWwsIHVpbnQ4X3QgY291bnQsIHRwUEVTZXNzaW9uIHNlc3Npb25fZW50cnkpCnsKCXREb3QxMWZleHRfY2hhbm5lbF9zd2l0Y2hfYWN0aW9uX2ZyYW1lIGZybTsKCXVpbnQ4X3QgICAgICAgICAgICAgICAgICAqZnJhbWU7Cgl0cFNpck1hY01nbXRIZHIgICAgICAgICAgbWFjX2hkcjsKCXVpbnQzMl90ICAgICAgICAgICAgICAgICBudW1fYnl0ZXMsIG5fcGF5bG9hZCwgc3RhdHVzOwoJdm9pZCAgICAgICAgICAgICAgICAgICAgICpwYWNrZXQ7CglRREZfU1RBVFVTICAgICAgICAgICAgICAgcWRmX3N0YXR1czsKCXVpbnQ4X3QgICAgICAgICAgICAgICAgICB0eEZsYWcgPSAwOwoJdWludDhfdCAgICAgICAgICAgICAgICAgIHNtZV9zZXNzaW9uX2lkID0gMDsKCglpZiAoc2Vzc2lvbl9lbnRyeSA9PSBOVUxMKSB7CgkJcGVfZXJyKCJTZXNzaW9uIGVudHJ5IGlzIE5VTEwhISEiKTsKCQlyZXR1cm4gZVNJUl9GQUlMVVJFOwoJfQoKCXNtZV9zZXNzaW9uX2lkID0gc2Vzc2lvbl9lbnRyeS0+c21lU2Vzc2lvbklkOwoKCXFkZl9tZW1fc2V0KCZmcm0sIHNpemVvZihmcm0pLCAwKTsKCglmcm0uQ2F0ZWdvcnkuY2F0ZWdvcnkgICAgID0gU0lSX01BQ19BQ1RJT05fUFVCTElDX1VTQUdFOwoJZnJtLkFjdGlvbi5hY3Rpb24gICAgICAgICA9IFNJUl9NQUNfQUNUSU9OX0VYVF9DSEFOTkVMX1NXSVRDSF9JRDsKCglmcm0uZXh0X2NoYW5fc3dpdGNoX2Fubl9hY3Rpb24uc3dpdGNoX21vZGUgPSBtb2RlOwoJZnJtLmV4dF9jaGFuX3N3aXRjaF9hbm5fYWN0aW9uLm9wX2NsYXNzID0gbmV3X29wX2NsYXNzOwoJZnJtLmV4dF9jaGFuX3N3aXRjaF9hbm5fYWN0aW9uLm5ld19jaGFubmVsID0gbmV3X2NoYW5uZWw7Cglmcm0uZXh0X2NoYW5fc3dpdGNoX2Fubl9hY3Rpb24uc3dpdGNoX2NvdW50ID0gY291bnQ7CgoKCXN0YXR1cyA9IGRvdDExZl9nZXRfcGFja2VkX2V4dF9jaGFubmVsX3N3aXRjaF9hY3Rpb25fZnJhbWVfc2l6ZShtYWNfY3R4LAoJCQkJCQkJICAgICZmcm0sICZuX3BheWxvYWQpOwoJaWYgKERPVDExRl9GQUlMRUQoc3RhdHVzKSkgewoJCXBlX2VycigiRmFpbGVkIHRvIGdldCBwYWNrZWQgc2l6ZSBmb3IgQ2hhbm5lbCBTd2l0Y2ggMHglMDh4IiwKCQkJCSBzdGF0dXMpOwoJCS8qIFdlJ2xsIGZhbGwgYmFjayBvbiB0aGUgd29yc3QgY2FzZSBzY2VuYXJpbyovCgkJbl9wYXlsb2FkID0gc2l6ZW9mKHREb3QxMWZleHRfY2hhbm5lbF9zd2l0Y2hfYWN0aW9uX2ZyYW1lKTsKCX0gZWxzZSBpZiAoRE9UMTFGX1dBUk5FRChzdGF0dXMpKSB7CgkJcGVfd2FybigiVGhlcmUgd2VyZSB3YXJuaW5ncyB3aGlsZSBjYWxjdWxhdGluZyB0aGUgcGFja2VkIHNpemUgZm9yIGEgRXh0IENoYW5uZWwgU3dpdGNoICgweCUwOHgpIiwKCQkgc3RhdHVzKTsKCX0KCgludW1fYnl0ZXMgPSBuX3BheWxvYWQgKyBzaXplb2YodFNpck1hY01nbXRIZHIpOwoKCXFkZl9zdGF0dXMgPSBjZHNfcGFja2V0X2FsbG9jKCh1aW50MTZfdCludW1fYnl0ZXMsCgkJCQkodm9pZCAqKikgJmZyYW1lLCAodm9pZCAqKikgJnBhY2tldCk7CgoJaWYgKCFRREZfSVNfU1RBVFVTX1NVQ0NFU1MocWRmX3N0YXR1cykpIHsKCQlwZV9lcnIoIkZhaWxlZCB0byBhbGxvY2F0ZSAlZCBieXRlcyBmb3IgYSBFeHQgQ2hhbm5lbCBTd2l0Y2giLAoJCQkJCQkJCSBudW1fYnl0ZXMpOwoJCXJldHVybiBlU0lSX0ZBSUxVUkU7Cgl9CgoJLyogUGFyYW5vaWEqLwoJcWRmX21lbV9zZXQoZnJhbWUsIG51bV9ieXRlcywgMCk7CgoJLyogTmV4dCwgd2UgZmlsbCBvdXQgdGhlIGJ1ZmZlciBkZXNjcmlwdG9yICovCglsaW1fcG9wdWxhdGVfbWFjX2hlYWRlcihtYWNfY3R4LCBmcmFtZSwgU0lSX01BQ19NR01UX0ZSQU1FLAoJCVNJUl9NQUNfTUdNVF9BQ1RJT04sIHBlZXIsIHNlc3Npb25fZW50cnktPnNlbGZNYWNBZGRyKTsKCW1hY19oZHIgPSAodHBTaXJNYWNNZ210SGRyKSBmcmFtZTsKCXFkZl9tZW1fY29weSgodWludDhfdCAqKSBtYWNfaGRyLT5ic3NJZCwKCQkJCSAgICh1aW50OF90ICopIHNlc3Npb25fZW50cnktPmJzc0lkLAoJCQkJICAgc2l6ZW9mKHRTaXJNYWNBZGRyKSk7CgoJc3RhdHVzID0gZG90MTFmX3BhY2tfZXh0X2NoYW5uZWxfc3dpdGNoX2FjdGlvbl9mcmFtZShtYWNfY3R4LCAmZnJtLAoJCWZyYW1lICsgc2l6ZW9mKHRTaXJNYWNNZ210SGRyKSwgbl9wYXlsb2FkLCAmbl9wYXlsb2FkKTsKCWlmIChET1QxMUZfRkFJTEVEKHN0YXR1cykpIHsKCQlwZV9lcnIoIkZhaWxlZCB0byBwYWNrIGEgQ2hhbm5lbCBTd2l0Y2ggMHglMDh4Iiwgc3RhdHVzKTsKCQljZHNfcGFja2V0X2ZyZWUoKHZvaWQgKilwYWNrZXQpOwoJCXJldHVybiBlU0lSX0ZBSUxVUkU7Cgl9IGVsc2UgaWYgKERPVDExRl9XQVJORUQoc3RhdHVzKSkgewoJCXBlX3dhcm4oIlRoZXJlIHdlcmUgd2FybmluZ3Mgd2hpbGUgcGFja2luZyBhIENoYW5uZWwgU3dpdGNoIDB4JTA4eCIsCgkJIHN0YXR1cyk7Cgl9CgoJaWYgKChTSVJfQkFORF81X0dIWiA9PQoJCWxpbV9nZXRfcmZfYmFuZChzZXNzaW9uX2VudHJ5LT5jdXJyZW50T3BlckNoYW5uZWwpKSB8fAoJCShzZXNzaW9uX2VudHJ5LT5wZVBlcnNvbmEgPT0gUURGX1AyUF9DTElFTlRfTU9ERSkgfHwKCQkoc2Vzc2lvbl9lbnRyeS0+cGVQZXJzb25hID09IFFERl9QMlBfR09fTU9ERSkpIHsKCQl0eEZsYWcgfD0gSEFMX1VTRV9CRF9SQVRFMl9GT1JfTUFOQUdFTUVOVF9GUkFNRTsKCX0KCglwZV9kZWJ1ZygiU2VuZCBFeHQgY2hhbm5lbCBTd2l0Y2ggdG8gOiJNQUNfQUREUkVTU19TVFIiIHdpdGggc3djb3VudCAlZCwgc3dtb2RlICVkICwgbmV3Y2hhbm5lbCAlZCBuZXdvcHMgJWQiLAoJCU1BQ19BRERSX0FSUkFZKG1hY19oZHItPmRhKSwKCQlmcm0uZXh0X2NoYW5fc3dpdGNoX2Fubl9hY3Rpb24uc3dpdGNoX2NvdW50LAoJCWZybS5leHRfY2hhbl9zd2l0Y2hfYW5uX2FjdGlvbi5zd2l0Y2hfbW9kZSwKCQlmcm0uZXh0X2NoYW5fc3dpdGNoX2Fubl9hY3Rpb24ubmV3X2NoYW5uZWwsCgkJCSBmcm0uZXh0X2NoYW5fc3dpdGNoX2Fubl9hY3Rpb24ub3BfY2xhc3MpOwoKCU1UUkFDRShxZGZfdHJhY2UoUURGX01PRFVMRV9JRF9QRSwgVFJBQ0VfQ09ERV9UWF9NR01ULAoJCQlzZXNzaW9uX2VudHJ5LT5wZVNlc3Npb25JZCwgbWFjX2hkci0+ZmMuc3ViVHlwZSkpOwoJcWRmX3N0YXR1cyA9IHdtYV90eF9mcmFtZShtYWNfY3R4LCBwYWNrZXQsICh1aW50MTZfdCkgbnVtX2J5dGVzLAoJCQkJCQkgVFhSWF9GUk1fODAyXzExX01HTVQsCgkJCQkJCSBBTklfVFhESVJfVE9EUywKCQkJCQkJIDcsCgkJCQkJCSBsaW1fdHhfY29tcGxldGUsIGZyYW1lLAoJCQkJCQkgdHhGbGFnLCBzbWVfc2Vzc2lvbl9pZCwgMCk7CglNVFJBQ0UocWRmX3RyYWNlKFFERl9NT0RVTEVfSURfUEUsIFRSQUNFX0NPREVfVFhfQ09NUExFVEUsCgkJCXNlc3Npb25fZW50cnktPnBlU2Vzc2lvbklkLCBxZGZfc3RhdHVzKSk7CglpZiAoIVFERl9JU19TVEFUVVNfU1VDQ0VTUyhxZGZfc3RhdHVzKSkgewoJCXBlX2VycigiRmFpbGVkIHRvIHNlbmQgYSBFeHQgQ2hhbm5lbCBTd2l0Y2ggJVghIiwKCQkJCQkJCSBxZGZfc3RhdHVzKTsKCQkvKiBQa3Qgd2lsbCBiZSBmcmVlZCB1cCBieSB0aGUgY2FsbGJhY2sgKi8KCQlyZXR1cm4gZVNJUl9GQUlMVVJFOwoJfQoJcmV0dXJuIGVTSVJfU1VDQ0VTUzsKfSAvKiBFbmQgbGltX3NlbmRfZXh0ZW5kZWRfY2hhbl9zd2l0Y2hfYWN0aW9uX2ZyYW1lICovCgoKLyoqCiAqIGxpbV9vcGVyX2NoYW5fY2hhbmdlX2NvbmZpcm1fdHhfY29tcGxldGVfY25mKCktIENvbmZpcm1hdGlvbiBmb3Igb3Blcl9jaGFuX2NoYW5nZV9jb25maXJtCiAqIHNlbnQgb3ZlciB0aGUgYWlyCiAqCiAqIEBjb250ZXh0OiBwb2ludGVyIHRvIGdsb2JhbCBtYWMKICogQGJ1ZjogYnVmZmVyCiAqIEB0eF9jb21wbGV0ZSA6IFNlbnQgc3RhdHVzCiAqIEBwYXJhbXM6IHR4IGNvbXBsZXRpb24gcGFyYW1zCiAqCiAqIFJldHVybjogVGhpcyByZXR1cm5zIFFERl9TVEFUVVMKICovCgpzdGF0aWMgUURGX1NUQVRVUyBsaW1fb3Blcl9jaGFuX2NoYW5nZV9jb25maXJtX3R4X2NvbXBsZXRlX2NuZigKCQkJdm9pZCAqY29udGV4dCwKCQkJcWRmX25idWZfdCBidWYsCgkJCXVpbnQzMl90IHR4X2NvbXBsZXRlLAoJCQl2b2lkICpwYXJhbXMpCnsKCXBlX2RlYnVnKCJ0eF9jb21wbGV0ZTogJWQiLCB0eF9jb21wbGV0ZSk7CglyZXR1cm4gUURGX1NUQVRVU19TVUNDRVNTOwp9CgovKioKICogbGltX3AycF9vcGVyX2NoYW5fY2hhbmdlX2NvbmZpcm1fYWN0aW9uX2ZyYW1lKCktIGZ1bmN0aW9uIHRvIHNlbmQKICogcDJwIG9wZXIgY2hhbiBjaGFuZ2UgY29uZmlybSBhY3Rpb24gZnJhbWUKICogQG1hY19jdHg6IHBvaW50ZXIgdG8gZ2xvYmFsIG1hYyBzdHJ1Y3R1cmUKICogQHBlZXI6IERlc3RpbmF0aW9uIG1hYy4KICogQHNlc3Npb25fZW50cnk6IHNlc3Npb24gZW50cnkKICoKICogVGhpcyBmdW5jdGlvbiBpcyBjYWxsZWQgdG8gc2VuZCBwMnAgb3BlciBjaGFuIGNoYW5nZSBjb25maXJtIGFjdGlvbiBmcmFtZS4KICoKICogUmV0dXJuOiBzdWNjZXNzIGlmIGZyYW1lIGlzIHNlbnQgZWxzZSByZXR1cm4gZmFpbHVyZQogKi8KCnRTaXJSZXRTdGF0dXMKbGltX3AycF9vcGVyX2NoYW5fY2hhbmdlX2NvbmZpcm1fYWN0aW9uX2ZyYW1lKHRwQW5pU2lyR2xvYmFsIG1hY19jdHgsCgkJdFNpck1hY0FkZHIgcGVlciwgdHBQRVNlc3Npb24gc2Vzc2lvbl9lbnRyeSkKewoJdERvdDExZnAycF9vcGVyX2NoYW5fY2hhbmdlX2NvbmZpcm0gZnJtOwoJdWludDhfdCAgICAgICAgICAgICAgICAgICpmcmFtZTsKCXRwU2lyTWFjTWdtdEhkciAgICAgICAgICBtYWNfaGRyOwoJdWludDMyX3QgICAgICAgICAgICAgICAgIG51bV9ieXRlcywgbl9wYXlsb2FkLCBzdGF0dXM7Cgl2b2lkICAgICAgICAgICAgICAgICAgICAgKnBhY2tldDsKCVFERl9TVEFUVVMgICAgICAgICAgICAgICBxZGZfc3RhdHVzOwoJdWludDhfdCAgICAgICAgICAgICAgICAgIHR4X2ZsYWcgPSAwOwoJdWludDhfdCAgICAgICAgICAgICAgICAgIHNtZV9zZXNzaW9uX2lkID0gMDsKCglpZiAoc2Vzc2lvbl9lbnRyeSA9PSBOVUxMKSB7CgkJcGVfZXJyKCJTZXNzaW9uIGVudHJ5IGlzIE5VTEwhISEiKTsKCQlyZXR1cm4gZVNJUl9GQUlMVVJFOwoJfQoKCXNtZV9zZXNzaW9uX2lkID0gc2Vzc2lvbl9lbnRyeS0+c21lU2Vzc2lvbklkOwoKCXFkZl9tZW1fc2V0KCZmcm0sIHNpemVvZihmcm0pLCAwKTsKCglmcm0uQ2F0ZWdvcnkuY2F0ZWdvcnkgICAgID0gU0lSX01BQ19BQ1RJT05fVkVORE9SX1NQRUNJRklDX0NBVEVHT1JZOwoKCXFkZl9tZW1fY29weShmcm0ucDJwX2FjdGlvbl9vdWkub3VpX2RhdGEsCgkJU0lSX01BQ19QMlBfT1VJLCBTSVJfTUFDX1AyUF9PVUlfU0laRSk7Cglmcm0ucDJwX2FjdGlvbl9zdWJ0eXBlLnN1YnR5cGUgPSAweDA0OwoJZnJtLkRpYWxvZ1Rva2VuLnRva2VuID0gMHgwOwoKCWlmIChzZXNzaW9uX2VudHJ5LT5odENhcGFiaWxpdHkpIHsKCQlwZV9kZWJ1ZygiUG9wdWxhdGUgSFQgQ2FwcyBpbiBBc3NvYyBSZXF1ZXN0Iik7CgkJcG9wdWxhdGVfZG90MTFmX2h0X2NhcHMobWFjX2N0eCwgc2Vzc2lvbl9lbnRyeSwgJmZybS5IVENhcHMpOwoJfQoKCWlmIChzZXNzaW9uX2VudHJ5LT52aHRDYXBhYmlsaXR5KSB7CgkJcGVfZGVidWcoIlBvcHVsYXRlIFZIVCBDYXBzIGluIEFzc29jIFJlcXVlc3QiKTsKCQlwb3B1bGF0ZV9kb3QxMWZfdmh0X2NhcHMobWFjX2N0eCwgc2Vzc2lvbl9lbnRyeSwgJmZybS5WSFRDYXBzKTsKCQlwb3B1bGF0ZV9kb3QxMWZfb3BlcmF0aW5nX21vZGUobWFjX2N0eCwKCQkJCQkmZnJtLk9wZXJhdGluZ01vZGUsIHNlc3Npb25fZW50cnkpOwoJfQoKCXN0YXR1cyA9IGRvdDExZl9nZXRfcGFja2VkX3AycF9vcGVyX2NoYW5fY2hhbmdlX2NvbmZpcm1TaXplKG1hY19jdHgsCgkJCQkJCQkgICAgJmZybSwgJm5fcGF5bG9hZCk7CglpZiAoRE9UMTFGX0ZBSUxFRChzdGF0dXMpKSB7CgkJcGVfZXJyKCJGYWlsZWQgdG8gZ2V0IHBhY2tlZCBzaXplIDB4JTA4eCIsIHN0YXR1cyk7CgkJLyogV2UnbGwgZmFsbCBiYWNrIG9uIHRoZSB3b3JzdCBjYXNlIHNjZW5hcmlvKi8KCQluX3BheWxvYWQgPSBzaXplb2YodERvdDExZnAycF9vcGVyX2NoYW5fY2hhbmdlX2NvbmZpcm0pOwoJfSBlbHNlIGlmIChET1QxMUZfV0FSTkVEKHN0YXR1cykpIHsKCQlwZV93YXJuKCJUaGVyZSB3ZXJlIHdhcm5pbmdzIHdoaWxlIGNhbGN1bGF0aW5nIHRoZSBwYWNrZWQgc2l6ZSAoMHglMDh4KSIsCgkJCXN0YXR1cyk7Cgl9CgoJbnVtX2J5dGVzID0gbl9wYXlsb2FkICsgc2l6ZW9mKHRTaXJNYWNNZ210SGRyKTsKCglxZGZfc3RhdHVzID0gY2RzX3BhY2tldF9hbGxvYygodWludDE2X3QpbnVtX2J5dGVzLAoJCQkJKHZvaWQgKiopICZmcmFtZSwgKHZvaWQgKiopICZwYWNrZXQpOwoKCWlmICghUURGX0lTX1NUQVRVU19TVUNDRVNTKHFkZl9zdGF0dXMpKSB7CgkJcGVfZXJyKCJGYWlsZWQgdG8gYWxsb2NhdGUgJWQgYnl0ZXMiLCBudW1fYnl0ZXMpOwoJCXJldHVybiBlU0lSX0ZBSUxVUkU7Cgl9CgoJcWRmX21lbV9zZXQoZnJhbWUsIG51bV9ieXRlcywgMCk7CgoJLyogTmV4dCwgZmlsbCBvdXQgdGhlIGJ1ZmZlciBkZXNjcmlwdG9yICovCglsaW1fcG9wdWxhdGVfbWFjX2hlYWRlcihtYWNfY3R4LCBmcmFtZSwgU0lSX01BQ19NR01UX0ZSQU1FLAoJCVNJUl9NQUNfTUdNVF9BQ1RJT04sIHBlZXIsIHNlc3Npb25fZW50cnktPnNlbGZNYWNBZGRyKTsKCW1hY19oZHIgPSAodHBTaXJNYWNNZ210SGRyKSBmcmFtZTsKCXFkZl9tZW1fY29weSgodWludDhfdCAqKSBtYWNfaGRyLT5ic3NJZCwKCQkJCSAgICh1aW50OF90ICopIHNlc3Npb25fZW50cnktPmJzc0lkLAoJCQkJICAgc2l6ZW9mKHRTaXJNYWNBZGRyKSk7CgoJc3RhdHVzID0gZG90MTFmX3BhY2tfcDJwX29wZXJfY2hhbl9jaGFuZ2VfY29uZmlybShtYWNfY3R4LCAmZnJtLAoJCWZyYW1lICsgc2l6ZW9mKHRTaXJNYWNNZ210SGRyKSwgbl9wYXlsb2FkLCAmbl9wYXlsb2FkKTsKCWlmIChET1QxMUZfRkFJTEVEKHN0YXR1cykpIHsKCQlwZV9lcnIoIkZhaWxlZCB0byBwYWNrIDB4JTA4eCIsIHN0YXR1cyk7CgkJY2RzX3BhY2tldF9mcmVlKCh2b2lkICopcGFja2V0KTsKCQlyZXR1cm4gZVNJUl9GQUlMVVJFOwoJfSBlbHNlIGlmIChET1QxMUZfV0FSTkVEKHN0YXR1cykpIHsKCQlwZV93YXJuKCJUaGVyZSB3ZXJlIHdhcm5pbmdzIHdoaWxlIHBhY2tpbmcgMHglMDh4IiwKCQkgc3RhdHVzKTsKCX0KCglpZiAoKFNJUl9CQU5EXzVfR0haID09CgkJbGltX2dldF9yZl9iYW5kKHNlc3Npb25fZW50cnktPmN1cnJlbnRPcGVyQ2hhbm5lbCkpIHx8CgkJKHNlc3Npb25fZW50cnktPnBlUGVyc29uYSA9PSBRREZfUDJQX0NMSUVOVF9NT0RFKSB8fAoJCShzZXNzaW9uX2VudHJ5LT5wZVBlcnNvbmEgPT0gUURGX1AyUF9HT19NT0RFKSkgewoJCXR4X2ZsYWcgfD0gSEFMX1VTRV9CRF9SQVRFMl9GT1JfTUFOQUdFTUVOVF9GUkFNRTsKCX0KCXBlX2RlYnVnKCJTZW5kIGZyYW1lIG9uIGNoYW5uZWwgJWQgdG8gbWFjICIKCQlNQUNfQUREUkVTU19TVFIsIHNlc3Npb25fZW50cnktPmN1cnJlbnRPcGVyQ2hhbm5lbCwKCQlNQUNfQUREUl9BUlJBWShwZWVyKSk7CgoJTVRSQUNFKHFkZl90cmFjZShRREZfTU9EVUxFX0lEX1BFLCBUUkFDRV9DT0RFX1RYX01HTVQsCgkJCXNlc3Npb25fZW50cnktPnBlU2Vzc2lvbklkLCBtYWNfaGRyLT5mYy5zdWJUeXBlKSk7CgoJcWRmX3N0YXR1cyA9IHdtYV90eF9mcmFtZVdpdGhUeENvbXBsZXRlKG1hY19jdHgsIHBhY2tldCwKCQkJKHVpbnQxNl90KW51bV9ieXRlcywKCQkJVFhSWF9GUk1fODAyXzExX01HTVQsIEFOSV9UWERJUl9UT0RTLAoJCQk3LCBsaW1fdHhfY29tcGxldGUsIGZyYW1lLAoJCQlsaW1fb3Blcl9jaGFuX2NoYW5nZV9jb25maXJtX3R4X2NvbXBsZXRlX2NuZiwKCQkJdHhfZmxhZywgc21lX3Nlc3Npb25faWQsIGZhbHNlLCAwKTsKCglNVFJBQ0UocWRmX3RyYWNlKFFERl9NT0RVTEVfSURfUEUsIFRSQUNFX0NPREVfVFhfQ09NUExFVEUsCgkJCXNlc3Npb25fZW50cnktPnBlU2Vzc2lvbklkLCBxZGZfc3RhdHVzKSk7CglpZiAoIVFERl9JU19TVEFUVVNfU1VDQ0VTUyhxZGZfc3RhdHVzKSkgewoJCXBlX2VycigiRmFpbGVkIHRvIHNlbmQgc3RhdHVzICVYISIsIHFkZl9zdGF0dXMpOwoJCS8qIFBrdCB3aWxsIGJlIGZyZWVkIHVwIGJ5IHRoZSBjYWxsYmFjayAqLwoJCXJldHVybiBlU0lSX0ZBSUxVUkU7Cgl9CgkJcmV0dXJuIGVTSVJfU1VDQ0VTUzsKfQoKCnRTaXJSZXRTdGF0dXMKbGltX3NlbmRfdmh0X29wbW9kZV9ub3RpZmljYXRpb25fZnJhbWUodHBBbmlTaXJHbG9iYWwgcE1hYywKCQkJCSAgICAgICB0U2lyTWFjQWRkciBwZWVyLAoJCQkJICAgICAgIHVpbnQ4X3Qgbk1vZGUsIHRwUEVTZXNzaW9uIHBzZXNzaW9uRW50cnkpCnsKCXREb3QxMWZPcGVyYXRpbmdNb2RlIGZybTsKCXVpbnQ4X3QgKnBGcmFtZTsKCXRwU2lyTWFjTWdtdEhkciBwTWFjSGRyOwoJdWludDMyX3QgbkJ5dGVzLCBuUGF5bG9hZCA9IDAsIG5TdGF0dXM7IC8qICwgbkNmZzsgKi8KCXZvaWQgKnBQYWNrZXQ7CglRREZfU1RBVFVTIHFkZl9zdGF0dXM7Cgl1aW50OF90IHR4RmxhZyA9IDA7CgoJdWludDhfdCBzbWVTZXNzaW9uSWQgPSAwOwoKCWlmIChwc2Vzc2lvbkVudHJ5ID09IE5VTEwpIHsKCQlwZV9lcnIoIlNlc3Npb24gZW50cnkgaXMgTlVMTCEhISIpOwoJCXJldHVybiBlU0lSX0ZBSUxVUkU7Cgl9CglzbWVTZXNzaW9uSWQgPSBwc2Vzc2lvbkVudHJ5LT5zbWVTZXNzaW9uSWQ7CgoJcWRmX21lbV9zZXQoKHVpbnQ4X3QgKikgJmZybSwgc2l6ZW9mKGZybSksIDApOwoKCWZybS5DYXRlZ29yeS5jYXRlZ29yeSA9IFNJUl9NQUNfQUNUSU9OX1ZIVDsKCWZybS5BY3Rpb24uYWN0aW9uID0gU0lSX01BQ19WSFRfT1BNT0RFX05PVElGSUNBVElPTjsKCWZybS5PcGVyYXRpbmdNb2RlLmNoYW5XaWR0aCA9IG5Nb2RlOwoJZnJtLk9wZXJhdGluZ01vZGUucnhOU1MgPSAwOwoJZnJtLk9wZXJhdGluZ01vZGUucnhOU1NUeXBlID0gMDsKCgluU3RhdHVzID0gZG90MTFmX2dldF9wYWNrZWRfb3BlcmF0aW5nX21vZGVfc2l6ZShwTWFjLCAmZnJtLCAmblBheWxvYWQpOwoJaWYgKERPVDExRl9GQUlMRUQoblN0YXR1cykpIHsKCQlwZV9lcnIoIkZhaWxlZCB0byBjYWxjdWxhdGUgdGhlIHBhY2tlZCBzaXplIGZvciBhIE9wZXJhdGluZyBNb2RlICgweCUwOHgpIiwKCQkJblN0YXR1cyk7CgkJLyogV2UnbGwgZmFsbCBiYWNrIG9uIHRoZSB3b3JzdCBjYXNlIHNjZW5hcmlvOiAqLwoJCW5QYXlsb2FkID0gc2l6ZW9mKHREb3QxMWZPcGVyYXRpbmdNb2RlKTsKCX0gZWxzZSBpZiAoRE9UMTFGX1dBUk5FRChuU3RhdHVzKSkgewoJCXBlX3dhcm4oIlRoZXJlIHdlcmUgd2FybmluZ3Mgd2hpbGUgY2FsY3VsYXRpbmcgdGhlIHBhY2tlZCBzaXplIGZvciBhIE9wZXJhdGluZyBNb2RlICgweCUwOHgpIiwKCQkJblN0YXR1cyk7Cgl9CgoJbkJ5dGVzID0gblBheWxvYWQgKyBzaXplb2YodFNpck1hY01nbXRIZHIpOwoKCXFkZl9zdGF0dXMgPQoJCWNkc19wYWNrZXRfYWxsb2MoKHVpbnQxNl90KSBuQnl0ZXMsICh2b2lkICoqKSZwRnJhbWUsCgkJCQkgKHZvaWQgKiopJnBQYWNrZXQpOwoJaWYgKCFRREZfSVNfU1RBVFVTX1NVQ0NFU1MocWRmX3N0YXR1cykpIHsKCQlwZV9lcnIoIkZhaWxlZCB0byBhbGxvY2F0ZSAlZCBieXRlcyBmb3IgYSBPcGVyYXRpbmcgTW9kZSBSZXBvcnQiLAoJCQluQnl0ZXMpOwoJCXJldHVybiBlU0lSX0ZBSUxVUkU7Cgl9CgkvKiBQYXJhbm9pYTogKi8KCXFkZl9tZW1fc2V0KHBGcmFtZSwgbkJ5dGVzLCAwKTsKCgkvKiBOZXh0LCB3ZSBmaWxsIG91dCB0aGUgYnVmZmVyIGRlc2NyaXB0b3I6ICovCglpZiAocHNlc3Npb25FbnRyeS0+cGVQZXJzb25hID09IFFERl9TQVBfTU9ERSkKCQlsaW1fcG9wdWxhdGVfbWFjX2hlYWRlcihwTWFjLCBwRnJhbWUsIFNJUl9NQUNfTUdNVF9GUkFNRSwKCQkJU0lSX01BQ19NR01UX0FDVElPTiwgcGVlciwKCQkJcHNlc3Npb25FbnRyeS0+c2VsZk1hY0FkZHIpOwoJZWxzZQoJCWxpbV9wb3B1bGF0ZV9tYWNfaGVhZGVyKHBNYWMsIHBGcmFtZSwgU0lSX01BQ19NR01UX0ZSQU1FLAoJCQlTSVJfTUFDX01HTVRfQUNUSU9OLCBwc2Vzc2lvbkVudHJ5LT5ic3NJZCwKCQkJcHNlc3Npb25FbnRyeS0+c2VsZk1hY0FkZHIpOwoJcE1hY0hkciA9ICh0cFNpck1hY01nbXRIZHIpIHBGcmFtZTsKCXFkZl9tZW1fY29weSgodWludDhfdCAqKSBwTWFjSGRyLT5ic3NJZCwKCQkgICAgICh1aW50OF90ICopIHBzZXNzaW9uRW50cnktPmJzc0lkLCBzaXplb2YodFNpck1hY0FkZHIpKTsKCW5TdGF0dXMgPSBkb3QxMWZfcGFja19vcGVyYXRpbmdfbW9kZShwTWFjLCAmZnJtLCBwRnJhbWUgKwoJCQkJCSAgICAgc2l6ZW9mKHRTaXJNYWNNZ210SGRyKSwKCQkJCQkgICAgIG5QYXlsb2FkLCAmblBheWxvYWQpOwoJaWYgKERPVDExRl9GQUlMRUQoblN0YXR1cykpIHsKCQlwZV9lcnIoIkZhaWxlZCB0byBwYWNrIGEgT3BlcmF0aW5nIE1vZGUgKDB4JTA4eCkiLAoJCQluU3RhdHVzKTsKCQljZHNfcGFja2V0X2ZyZWUoKHZvaWQgKilwUGFja2V0KTsKCQlyZXR1cm4gZVNJUl9GQUlMVVJFOyAgICAvKiBhbGxvY2F0ZWQhICovCgl9IGVsc2UgaWYgKERPVDExRl9XQVJORUQoblN0YXR1cykpIHsKCQlwZV93YXJuKCJUaGVyZSB3ZXJlIHdhcm5pbmdzIHdoaWxlIHBhY2tpbmcgYSBPcGVyYXRpbmcgTW9kZSAoMHglMDh4KSIsCgkJCW5TdGF0dXMpOwoJfQoJaWYgKChTSVJfQkFORF81X0dIWiA9PSBsaW1fZ2V0X3JmX2JhbmQocHNlc3Npb25FbnRyeS0+Y3VycmVudE9wZXJDaGFubmVsKSkKCSAgICB8fCAocHNlc3Npb25FbnRyeS0+cGVQZXJzb25hID09IFFERl9QMlBfQ0xJRU5UX01PREUpIHx8CgkgICAgKHBzZXNzaW9uRW50cnktPnBlUGVyc29uYSA9PSBRREZfUDJQX0dPX01PREUpCgkgICAgKSB7CgkJdHhGbGFnIHw9IEhBTF9VU0VfQkRfUkFURTJfRk9SX01BTkFHRU1FTlRfRlJBTUU7Cgl9CgoJTVRSQUNFKHFkZl90cmFjZShRREZfTU9EVUxFX0lEX1BFLCBUUkFDRV9DT0RFX1RYX01HTVQsCgkJCSBwc2Vzc2lvbkVudHJ5LT5wZVNlc3Npb25JZCwgcE1hY0hkci0+ZmMuc3ViVHlwZSkpOwoJcWRmX3N0YXR1cyA9IHdtYV90eF9mcmFtZShwTWFjLCBwUGFja2V0LCAodWludDE2X3QpIG5CeXRlcywKCQkJCVRYUlhfRlJNXzgwMl8xMV9NR01ULAoJCQkJQU5JX1RYRElSX1RPRFMsCgkJCQk3LCBsaW1fdHhfY29tcGxldGUsIHBGcmFtZSwgdHhGbGFnLAoJCQkJc21lU2Vzc2lvbklkLCAwKTsKCU1UUkFDRShxZGZfdHJhY2UoUURGX01PRFVMRV9JRF9QRSwgVFJBQ0VfQ09ERV9UWF9DT01QTEVURSwKCQkJIHBzZXNzaW9uRW50cnktPnBlU2Vzc2lvbklkLCBxZGZfc3RhdHVzKSk7CglpZiAoIVFERl9JU19TVEFUVVNfU1VDQ0VTUyhxZGZfc3RhdHVzKSkgewoJCXBlX2VycigiRmFpbGVkIHRvIHNlbmQgYSBDaGFubmVsIFN3aXRjaCAoJVgpISIsCgkJCXFkZl9zdGF0dXMpOwoJCS8qIFBrdCB3aWxsIGJlIGZyZWVkIHVwIGJ5IHRoZSBjYWxsYmFjayAqLwoJCXJldHVybiBlU0lSX0ZBSUxVUkU7Cgl9CgoJcmV0dXJuIGVTSVJfU1VDQ0VTUzsKfQoKLyoqCiAqIFxicmllZiBTZW5kIGEgTmVpZ2hib3IgUmVwb3J0IFJlcXVlc3QgQWN0aW9uIGZyYW1lCiAqCiAqCiAqIFxwYXJhbSBwTWFjIFBvaW50ZXIgdG8gdGhlIGdsb2JhbCBNQUMgc3RydWN0dXJlCiAqCiAqIFxwYXJhbSBwTmVpZ2hib3JSZXEgQWRkcmVzcyBvZiBhIHRTaXJNYWNOZWlnaGJvclJlcG9ydFJlcQogKgogKiBccGFyYW0gcGVlciBtYWMgYWRkcmVzcyBvZiBwZWVyIHN0YXRpb24uCiAqCiAqIFxwYXJhbSBwc2Vzc2lvbkVudHJ5IGFkZHJlc3Mgb2Ygc2Vzc2lvbiBlbnRyeS4KICoKICogXHJldHVybiBlU0lSX1NVQ0NFU1Mgb24gc3VjY2VzcywgZVNJUl9GQUlMVVJFIGVsc2UKICoKICoKICovCgp0U2lyUmV0U3RhdHVzCmxpbV9zZW5kX25laWdoYm9yX3JlcG9ydF9yZXF1ZXN0X2ZyYW1lKHRwQW5pU2lyR2xvYmFsIHBNYWMsCgkJCQkgICAgICAgdHBTaXJNYWNOZWlnaGJvclJlcG9ydFJlcSBwTmVpZ2hib3JSZXEsCgkJCQkgICAgICAgdFNpck1hY0FkZHIgcGVlciwgdHBQRVNlc3Npb24gcHNlc3Npb25FbnRyeSkKewoJdFNpclJldFN0YXR1cyBzdGF0dXNDb2RlID0gZVNJUl9TVUNDRVNTOwoJdERvdDExZk5laWdoYm9yUmVwb3J0UmVxdWVzdCBmcm07Cgl1aW50OF90ICpwRnJhbWU7Cgl0cFNpck1hY01nbXRIZHIgcE1hY0hkcjsKCXVpbnQzMl90IG5CeXRlcywgblBheWxvYWQsIG5TdGF0dXM7Cgl2b2lkICpwUGFja2V0OwoJUURGX1NUQVRVUyBxZGZfc3RhdHVzOwoJdWludDhfdCB0eEZsYWcgPSAwOwoJdWludDhfdCBzbWVTZXNzaW9uSWQgPSAwOwoKCWlmIChwc2Vzc2lvbkVudHJ5ID09IE5VTEwpIHsKCQlwZV9lcnIoIihwc2Vzc2lvbiA9PSBOVUxMKSBpbiBSZXF1ZXN0IHRvIHNlbmQgTmVpZ2hib3IgUmVwb3J0IHJlcXVlc3QgYWN0aW9uIGZyYW1lIik7CgkJcmV0dXJuIGVTSVJfRkFJTFVSRTsKCX0KCXNtZVNlc3Npb25JZCA9IHBzZXNzaW9uRW50cnktPnNtZVNlc3Npb25JZDsKCXFkZl9tZW1fc2V0KCh1aW50OF90ICopICZmcm0sIHNpemVvZihmcm0pLCAwKTsKCglmcm0uQ2F0ZWdvcnkuY2F0ZWdvcnkgPSBTSVJfTUFDX0FDVElPTl9SUk07Cglmcm0uQWN0aW9uLmFjdGlvbiA9IFNJUl9NQUNfUlJNX05FSUdIQk9SX1JFUTsKCWZybS5EaWFsb2dUb2tlbi50b2tlbiA9IHBOZWlnaGJvclJlcS0+ZGlhbG9nVG9rZW47CgoJaWYgKHBOZWlnaGJvclJlcS0+c3NpZF9wcmVzZW50KSB7CgkJcG9wdWxhdGVfZG90MTFmX3NzaWQocE1hYywgJnBOZWlnaGJvclJlcS0+c3NpZCwgJmZybS5TU0lEKTsKCX0KCgluU3RhdHVzID0KCQlkb3QxMWZfZ2V0X3BhY2tlZF9uZWlnaGJvcl9yZXBvcnRfcmVxdWVzdF9zaXplKHBNYWMsICZmcm0sICZuUGF5bG9hZCk7CglpZiAoRE9UMTFGX0ZBSUxFRChuU3RhdHVzKSkgewoJCXBlX2VycigiRmFpbGVkIHRvIGNhbGN1bGF0ZSB0aGUgcGFja2VkIHNpemUgZm9yIGEgTmVpZ2hib3IgUmVwb3J0IFJlcXVlc3QoMHglMDh4KSIsCgkJCW5TdGF0dXMpOwoJCS8qIFdlJ2xsIGZhbGwgYmFjayBvbiB0aGUgd29yc3QgY2FzZSBzY2VuYXJpbzogKi8KCQluUGF5bG9hZCA9IHNpemVvZih0RG90MTFmTmVpZ2hib3JSZXBvcnRSZXF1ZXN0KTsKCX0gZWxzZSBpZiAoRE9UMTFGX1dBUk5FRChuU3RhdHVzKSkgewoJCXBlX3dhcm4oIlRoZXJlIHdlcmUgd2FybmluZ3Mgd2hpbGUgY2FsY3VsYXRpbmcgdGhlIHBhY2tlZCBzaXplIGZvciBhIE5laWdoYm9yIFJlcG9ydCBSZXF1ZXN0KDB4JTA4eCkiLAoJCQluU3RhdHVzKTsKCX0KCgluQnl0ZXMgPSBuUGF5bG9hZCArIHNpemVvZih0U2lyTWFjTWdtdEhkcik7CgoJcWRmX3N0YXR1cyA9CgkJY2RzX3BhY2tldF9hbGxvYygodWludDE2X3QpIG5CeXRlcywgKHZvaWQgKiopJnBGcmFtZSwKCQkJCSAodm9pZCAqKikmcFBhY2tldCk7CglpZiAoIVFERl9JU19TVEFUVVNfU1VDQ0VTUyhxZGZfc3RhdHVzKSkgewoJCXBlX2VycigiRmFpbGVkIHRvIGFsbG9jYXRlICVkIGJ5dGVzIGZvciBhIE5laWdoYm9yICIKCQkJICAgIlJlcG9ydCBSZXF1ZXN0IiwgbkJ5dGVzKTsKCQlyZXR1cm4gZVNJUl9GQUlMVVJFOwoJfQoJLyogUGFyYW5vaWE6ICovCglxZGZfbWVtX3NldChwRnJhbWUsIG5CeXRlcywgMCk7CgoJLyogQ29weSBuZWNlc3NhcnkgaW5mbyB0byBCRCAqLwoJbGltX3BvcHVsYXRlX21hY19oZWFkZXIocE1hYywgcEZyYW1lLCBTSVJfTUFDX01HTVRfRlJBTUUsCgkJU0lSX01BQ19NR01UX0FDVElPTiwgcGVlciwgcHNlc3Npb25FbnRyeS0+c2VsZk1hY0FkZHIpOwoKCS8qIFVwZGF0ZSBBMyB3aXRoIHRoZSBCU1NJRCAqLwoJcE1hY0hkciA9ICh0cFNpck1hY01nbXRIZHIpIHBGcmFtZTsKCglzaXJfY29weV9tYWNfYWRkcihwTWFjSGRyLT5ic3NJZCwgcHNlc3Npb25FbnRyeS0+YnNzSWQpOwoKI2lmZGVmIFdMQU5fRkVBVFVSRV8xMVcKCWxpbV9zZXRfcHJvdGVjdGVkX2JpdChwTWFjLCBwc2Vzc2lvbkVudHJ5LCBwZWVyLCBwTWFjSGRyKTsKI2VuZGlmCgoJLyogTm93LCB3ZSdyZSByZWFkeSB0byAicGFjayIgdGhlIGZyYW1lcyAqLwoJblN0YXR1cyA9IGRvdDExZl9wYWNrX25laWdoYm9yX3JlcG9ydF9yZXF1ZXN0KHBNYWMsCgkJCQkJCSAgICAgICZmcm0sCgkJCQkJCSAgICAgIHBGcmFtZSArCgkJCQkJCSAgICAgIHNpemVvZih0U2lyTWFjTWdtdEhkciksCgkJCQkJCSAgICAgIG5QYXlsb2FkLCAmblBheWxvYWQpOwoKCWlmIChET1QxMUZfRkFJTEVEKG5TdGF0dXMpKSB7CgkJcGVfZXJyKCJGYWlsZWQgdG8gcGFjayBhbiBOZWlnaGJvciBSZXBvcnQgUmVxdWVzdCAoMHglMDh4KSIsCgkJCW5TdGF0dXMpOwoKCQkvKiBGSVhNRSAtIE5lZWQgdG8gY29udmVydCB0byB0U2lyUmV0U3RhdHVzICovCgkJc3RhdHVzQ29kZSA9IGVTSVJfRkFJTFVSRTsKCQlnb3RvIHJldHVybkFmdGVyRXJyb3I7Cgl9IGVsc2UgaWYgKERPVDExRl9XQVJORUQoblN0YXR1cykpIHsKCQlwZV93YXJuKCJUaGVyZSB3ZXJlIHdhcm5pbmdzIHdoaWxlIHBhY2tpbmcgTmVpZ2hib3IgUmVwb3J0IFJlcXVlc3QgKDB4JTA4eCkiLAoJCQluU3RhdHVzKTsKCX0KCglwZV9kZWJ1ZygiU2VuZGluZyBhIE5laWdoYm9yIFJlcG9ydCBSZXF1ZXN0IHRvIik7CglsaW1fcHJpbnRfbWFjX2FkZHIocE1hYywgcGVlciwgTE9HRCk7CgoJaWYgKChTSVJfQkFORF81X0dIWiA9PSBsaW1fZ2V0X3JmX2JhbmQocHNlc3Npb25FbnRyeS0+Y3VycmVudE9wZXJDaGFubmVsKSkKCSAgICB8fCAocHNlc3Npb25FbnRyeS0+cGVQZXJzb25hID09IFFERl9QMlBfQ0xJRU5UX01PREUpIHx8CgkgICAgKHBzZXNzaW9uRW50cnktPnBlUGVyc29uYSA9PSBRREZfUDJQX0dPX01PREUpCgkgICAgKSB7CgkJdHhGbGFnIHw9IEhBTF9VU0VfQkRfUkFURTJfRk9SX01BTkFHRU1FTlRfRlJBTUU7Cgl9CgoJTVRSQUNFKHFkZl90cmFjZShRREZfTU9EVUxFX0lEX1BFLCBUUkFDRV9DT0RFX1RYX01HTVQsCgkJCSBwc2Vzc2lvbkVudHJ5LT5wZVNlc3Npb25JZCwgcE1hY0hkci0+ZmMuc3ViVHlwZSkpOwoJcWRmX3N0YXR1cyA9IHdtYV90eF9mcmFtZShwTWFjLAoJCQkJcFBhY2tldCwKCQkJCSh1aW50MTZfdCkgbkJ5dGVzLAoJCQkJVFhSWF9GUk1fODAyXzExX01HTVQsCgkJCQlBTklfVFhESVJfVE9EUywKCQkJCTcsIGxpbV90eF9jb21wbGV0ZSwgcEZyYW1lLCB0eEZsYWcsCgkJCQlzbWVTZXNzaW9uSWQsIDApOwoJTVRSQUNFKHFkZl90cmFjZShRREZfTU9EVUxFX0lEX1BFLCBUUkFDRV9DT0RFX1RYX0NPTVBMRVRFLAoJCQkgcHNlc3Npb25FbnRyeS0+cGVTZXNzaW9uSWQsIHFkZl9zdGF0dXMpKTsKCWlmIChRREZfU1RBVFVTX1NVQ0NFU1MgIT0gcWRmX3N0YXR1cykgewoJCXBlX2Vycigid21hX3R4X2ZyYW1lIEZBSUxFRCEgU3RhdHVzIFslZF0iLCBxZGZfc3RhdHVzKTsKCQlzdGF0dXNDb2RlID0gZVNJUl9GQUlMVVJFOwoJCS8qIFBrdCB3aWxsIGJlIGZyZWVkIHVwIGJ5IHRoZSBjYWxsYmFjayAqLwoJCXJldHVybiBzdGF0dXNDb2RlOwoJfSBlbHNlCgkJcmV0dXJuIGVTSVJfU1VDQ0VTUzsKCnJldHVybkFmdGVyRXJyb3I6CgljZHNfcGFja2V0X2ZyZWUoKHZvaWQgKilwUGFja2V0KTsKCglyZXR1cm4gc3RhdHVzQ29kZTsKfSAvKiBFbmQgbGltX3NlbmRfbmVpZ2hib3JfcmVwb3J0X3JlcXVlc3RfZnJhbWUuICovCgovKioKICogXGJyaWVmIFNlbmQgYSBMaW5rIFJlcG9ydCBBY3Rpb24gZnJhbWUKICoKICoKICogXHBhcmFtIHBNYWMgUG9pbnRlciB0byB0aGUgZ2xvYmFsIE1BQyBzdHJ1Y3R1cmUKICoKICogXHBhcmFtIHBMaW5rUmVwb3J0IEFkZHJlc3Mgb2YgYSB0U2lyTWFjTGlua1JlcG9ydAogKgogKiBccGFyYW0gcGVlciBtYWMgYWRkcmVzcyBvZiBwZWVyIHN0YXRpb24uCiAqCiAqIFxwYXJhbSBwc2Vzc2lvbkVudHJ5IGFkZHJlc3Mgb2Ygc2Vzc2lvbiBlbnRyeS4KICoKICogXHJldHVybiBlU0lSX1NVQ0NFU1Mgb24gc3VjY2VzcywgZVNJUl9GQUlMVVJFIGVsc2UKICoKICoKICovCgp0U2lyUmV0U3RhdHVzCmxpbV9zZW5kX2xpbmtfcmVwb3J0X2FjdGlvbl9mcmFtZSh0cEFuaVNpckdsb2JhbCBwTWFjLAoJCQkJICB0cFNpck1hY0xpbmtSZXBvcnQgcExpbmtSZXBvcnQsCgkJCQkgIHRTaXJNYWNBZGRyIHBlZXIsIHRwUEVTZXNzaW9uIHBzZXNzaW9uRW50cnkpCnsKCXRTaXJSZXRTdGF0dXMgc3RhdHVzQ29kZSA9IGVTSVJfU1VDQ0VTUzsKCXREb3QxMWZMaW5rTWVhc3VyZW1lbnRSZXBvcnQgZnJtOwoJdWludDhfdCAqcEZyYW1lOwoJdHBTaXJNYWNNZ210SGRyIHBNYWNIZHI7Cgl1aW50MzJfdCBuQnl0ZXMsIG5QYXlsb2FkLCBuU3RhdHVzOwoJdm9pZCAqcFBhY2tldDsKCVFERl9TVEFUVVMgcWRmX3N0YXR1czsKCXVpbnQ4X3QgdHhGbGFnID0gMDsKCXVpbnQ4X3Qgc21lU2Vzc2lvbklkID0gMDsKCglpZiAocHNlc3Npb25FbnRyeSA9PSBOVUxMKSB7CgkJcGVfZXJyKCIocHNlc3Npb24gPT0gTlVMTCkgaW4gUmVxdWVzdCB0byBzZW5kIExpbmsgUmVwb3J0IGFjdGlvbiBmcmFtZSIpOwoJCXJldHVybiBlU0lSX0ZBSUxVUkU7Cgl9CgoJcWRmX21lbV9zZXQoKHVpbnQ4X3QgKikgJmZybSwgc2l6ZW9mKGZybSksIDApOwoKCWZybS5DYXRlZ29yeS5jYXRlZ29yeSA9IFNJUl9NQUNfQUNUSU9OX1JSTTsKCWZybS5BY3Rpb24uYWN0aW9uID0gU0lSX01BQ19SUk1fTElOS19NRUFTVVJFTUVOVF9SUFQ7Cglmcm0uRGlhbG9nVG9rZW4udG9rZW4gPSBwTGlua1JlcG9ydC0+ZGlhbG9nVG9rZW47CgoJLyogSUVFRSBTdGQuIDgwMi4xMSA3LjMuMi4xOC4gZm9yIHRoZSByZXBvcnQgZWxlbWVudC4gKi8KCS8qIEV2ZW4gdGhvdWdoIFRQQyByZXBvcnQgYW4gSUUsIGl0IGlzIHJlcHJlc2VudGVkIHVzaW5nIGZpeGVkIGZpZWxkcyBzaW5jZSBpdCBpcyBwb3NpdGlvbmVkICovCgkvKiBpbiB0aGUgbWlkZGxlIG9mIG90aGVyIGZpeGVkIGZpZWxkcyBpbiB0aGUgbGluayByZXBvcnQgZnJhbWUoSUVFRSBTdGQuIDgwMi4xMWsgc2VjdGlvbjcuNC42LjQgKi8KCS8qIGFuZCBmcmFtZSBwYXJzZXIgYWx3YXlzIGV4cGVjdHMgSUVzIHRvIGNvbWUgYWZ0ZXIgYWxsIGZpeGVkIGZpZWxkcy4gSXQgaXMgZWFzaWVyIHRvIGhhbmRsZSAqLwoJLyogc3VjaCBjYXNlIHRoaXMgd2F5IHRoYW4gY2hhbmdpbmcgdGhlIGZyYW1lIHBhcnNlci4gKi8KCWZybS5UUENFbGVJRC5UUENJZCA9IFNJUl9NQUNfVFBDX1JQVF9FSUQ7Cglmcm0uVFBDRWxlTGVuLlRQQ0xlbiA9IDI7Cglmcm0uVHhQb3dlci50eFBvd2VyID0gcExpbmtSZXBvcnQtPnR4UG93ZXI7Cglmcm0uTGlua01hcmdpbi5saW5rTWFyZ2luID0gMDsKCglmcm0uUnhBbnRlbm5hSWQuYW50ZW5uYUlkID0gcExpbmtSZXBvcnQtPnJ4QW50ZW5uYTsKCWZybS5UeEFudGVubmFJZC5hbnRlbm5hSWQgPSBwTGlua1JlcG9ydC0+dHhBbnRlbm5hOwoJZnJtLlJDUEkucmNwaSA9IHBMaW5rUmVwb3J0LT5yY3BpOwoJZnJtLlJTTkkucnNuaSA9IHBMaW5rUmVwb3J0LT5yc25pOwoKCW5TdGF0dXMgPQoJCWRvdDExZl9nZXRfcGFja2VkX2xpbmtfbWVhc3VyZW1lbnRfcmVwb3J0X3NpemUocE1hYywgJmZybSwgJm5QYXlsb2FkKTsKCWlmIChET1QxMUZfRkFJTEVEKG5TdGF0dXMpKSB7CgkJcGVfZXJyKCJGYWlsZWQgdG8gY2FsY3VsYXRlIHRoZSBwYWNrZWQgc2l6ZSBmb3IgYSBMaW5rIFJlcG9ydCAoMHglMDh4KSIsIG5TdGF0dXMpOwoJCS8qIFdlJ2xsIGZhbGwgYmFjayBvbiB0aGUgd29yc3QgY2FzZSBzY2VuYXJpbzogKi8KCQluUGF5bG9hZCA9IHNpemVvZih0RG90MTFmTGlua01lYXN1cmVtZW50UmVwb3J0KTsKCX0gZWxzZSBpZiAoRE9UMTFGX1dBUk5FRChuU3RhdHVzKSkgewoJCXBlX3dhcm4oIlRoZXJlIHdlcmUgd2FybmluZ3Mgd2hpbGUgY2FsY3VsYXRpbmcgdGhlIHBhY2tlZCBzaXplIGZvciBhIExpbmsgUmVwb3J0ICgweCUwOHgpIiwKCQkJblN0YXR1cyk7Cgl9CgoJbkJ5dGVzID0gblBheWxvYWQgKyBzaXplb2YodFNpck1hY01nbXRIZHIpOwoKCXFkZl9zdGF0dXMgPQoJCWNkc19wYWNrZXRfYWxsb2MoKHVpbnQxNl90KSBuQnl0ZXMsICh2b2lkICoqKSZwRnJhbWUsCgkJCQkgKHZvaWQgKiopJnBQYWNrZXQpOwoJaWYgKCFRREZfSVNfU1RBVFVTX1NVQ0NFU1MocWRmX3N0YXR1cykpIHsKCQlwZV9lcnIoIkZhaWxlZCB0byBhbGxvY2F0ZSAlZCBieXRlcyBmb3IgYSBMaW5rICIKCQkJIlJlcG9ydCIsIG5CeXRlcyk7CgkJcmV0dXJuIGVTSVJfRkFJTFVSRTsKCX0KCS8qIFBhcmFub2lhOiAqLwoJcWRmX21lbV9zZXQocEZyYW1lLCBuQnl0ZXMsIDApOwoKCS8qIENvcHkgbmVjZXNzYXJ5IGluZm8gdG8gQkQgKi8KCWxpbV9wb3B1bGF0ZV9tYWNfaGVhZGVyKHBNYWMsIHBGcmFtZSwgU0lSX01BQ19NR01UX0ZSQU1FLAoJCVNJUl9NQUNfTUdNVF9BQ1RJT04sIHBlZXIsIHBzZXNzaW9uRW50cnktPnNlbGZNYWNBZGRyKTsKCgkvKiBVcGRhdGUgQTMgd2l0aCB0aGUgQlNTSUQgKi8KCXBNYWNIZHIgPSAodHBTaXJNYWNNZ210SGRyKSBwRnJhbWU7CgoJc2lyX2NvcHlfbWFjX2FkZHIocE1hY0hkci0+YnNzSWQsIHBzZXNzaW9uRW50cnktPmJzc0lkKTsKCiNpZmRlZiBXTEFOX0ZFQVRVUkVfMTFXCglsaW1fc2V0X3Byb3RlY3RlZF9iaXQocE1hYywgcHNlc3Npb25FbnRyeSwgcGVlciwgcE1hY0hkcik7CiNlbmRpZgoKCS8qIE5vdywgd2UncmUgcmVhZHkgdG8gInBhY2siIHRoZSBmcmFtZXMgKi8KCW5TdGF0dXMgPSBkb3QxMWZfcGFja19saW5rX21lYXN1cmVtZW50X3JlcG9ydChwTWFjLAoJCQkJCQkgICAgICAmZnJtLAoJCQkJCQkgICAgICBwRnJhbWUgKwoJCQkJCQkgICAgICBzaXplb2YodFNpck1hY01nbXRIZHIpLAoJCQkJCQkgICAgICBuUGF5bG9hZCwgJm5QYXlsb2FkKTsKCglpZiAoRE9UMTFGX0ZBSUxFRChuU3RhdHVzKSkgewoJCXBlX2VycigiRmFpbGVkIHRvIHBhY2sgYW4gTGluayBSZXBvcnQgKDB4JTA4eCkiLCBuU3RhdHVzKTsKCgkJLyogRklYTUUgLSBOZWVkIHRvIGNvbnZlcnQgdG8gdFNpclJldFN0YXR1cyAqLwoJCXN0YXR1c0NvZGUgPSBlU0lSX0ZBSUxVUkU7CgkJZ290byByZXR1cm5BZnRlckVycm9yOwoJfSBlbHNlIGlmIChET1QxMUZfV0FSTkVEKG5TdGF0dXMpKSB7CgkJcGVfd2FybigiVGhlcmUgd2VyZSB3YXJuaW5ncyB3aGlsZSBwYWNraW5nIExpbmsgUmVwb3J0ICgweCUwOHgpIiwKCQkJblN0YXR1cyk7Cgl9CgoJcGVfd2FybigiU2VuZGluZyBhIExpbmsgUmVwb3J0IHRvIik7CglsaW1fcHJpbnRfbWFjX2FkZHIocE1hYywgcGVlciwgTE9HVyk7CgoJaWYgKChTSVJfQkFORF81X0dIWiA9PSBsaW1fZ2V0X3JmX2JhbmQocHNlc3Npb25FbnRyeS0+Y3VycmVudE9wZXJDaGFubmVsKSkKCSAgICB8fCAocHNlc3Npb25FbnRyeS0+cGVQZXJzb25hID09IFFERl9QMlBfQ0xJRU5UX01PREUpIHx8CgkgICAgKHBzZXNzaW9uRW50cnktPnBlUGVyc29uYSA9PSBRREZfUDJQX0dPX01PREUpKSB7CgkJdHhGbGFnIHw9IEhBTF9VU0VfQkRfUkFURTJfRk9SX01BTkFHRU1FTlRfRlJBTUU7Cgl9CgoJTVRSQUNFKHFkZl90cmFjZShRREZfTU9EVUxFX0lEX1BFLCBUUkFDRV9DT0RFX1RYX01HTVQsCgkJCSBwc2Vzc2lvbkVudHJ5LT5wZVNlc3Npb25JZCwgcE1hY0hkci0+ZmMuc3ViVHlwZSkpOwoJcWRmX3N0YXR1cyA9IHdtYV90eF9mcmFtZShwTWFjLAoJCQkJcFBhY2tldCwKCQkJCSh1aW50MTZfdCkgbkJ5dGVzLAoJCQkJVFhSWF9GUk1fODAyXzExX01HTVQsCgkJCQlBTklfVFhESVJfVE9EUywKCQkJCTcsIGxpbV90eF9jb21wbGV0ZSwgcEZyYW1lLCB0eEZsYWcsCgkJCQlzbWVTZXNzaW9uSWQsIDApOwoJTVRSQUNFKHFkZl90cmFjZShRREZfTU9EVUxFX0lEX1BFLCBUUkFDRV9DT0RFX1RYX0NPTVBMRVRFLAoJCQkgcHNlc3Npb25FbnRyeS0+cGVTZXNzaW9uSWQsIHFkZl9zdGF0dXMpKTsKCWlmIChRREZfU1RBVFVTX1NVQ0NFU1MgIT0gcWRmX3N0YXR1cykgewoJCXBlX2Vycigid21hX3R4X2ZyYW1lIEZBSUxFRCEgU3RhdHVzIFslZF0iLCBxZGZfc3RhdHVzKTsKCQlzdGF0dXNDb2RlID0gZVNJUl9GQUlMVVJFOwoJCS8qIFBrdCB3aWxsIGJlIGZyZWVkIHVwIGJ5IHRoZSBjYWxsYmFjayAqLwoJCXJldHVybiBzdGF0dXNDb2RlOwoJfSBlbHNlCgkJcmV0dXJuIGVTSVJfU1VDQ0VTUzsKCnJldHVybkFmdGVyRXJyb3I6CgljZHNfcGFja2V0X2ZyZWUoKHZvaWQgKilwUGFja2V0KTsKCglyZXR1cm4gc3RhdHVzQ29kZTsKfSAvKiBFbmQgbGltX3NlbmRfbGlua19yZXBvcnRfYWN0aW9uX2ZyYW1lLiAqLwoKLyoqCiAqIFxicmllZiBTZW5kIGEgQmVhY29uIFJlcG9ydCBBY3Rpb24gZnJhbWUKICoKICoKICogXHBhcmFtIHBNYWMgUG9pbnRlciB0byB0aGUgZ2xvYmFsIE1BQyBzdHJ1Y3R1cmUKICoKICogXHBhcmFtIGRpYWxvZ190b2tlbiBkaWFsb2cgdG9rZW4gdG8gYmUgdXNlZCBpbiB0aGUgYWN0aW9uIGZyYW1lLgogKgogKiBccGFyYW0gbnVtX3JlcG9ydCBudW1iZXIgb2YgcmVwb3J0cyBpbiBwUlJNUmVwb3J0LgogKgogKiBccGFyYW0gcFJSTVJlcG9ydCBBZGRyZXNzIG9mIGEgdFNpck1hY1JhZGlvTWVhc3VyZVJlcG9ydC4KICoKICogXHBhcmFtIHBlZXIgbWFjIGFkZHJlc3Mgb2YgcGVlciBzdGF0aW9uLgogKgogKiBccGFyYW0gcHNlc3Npb25FbnRyeSBhZGRyZXNzIG9mIHNlc3Npb24gZW50cnkuCiAqCiAqIFxyZXR1cm4gZVNJUl9TVUNDRVNTIG9uIHN1Y2Nlc3MsIGVTSVJfRkFJTFVSRSBlbHNlCiAqCiAqCiAqLwoKdFNpclJldFN0YXR1cwpsaW1fc2VuZF9yYWRpb19tZWFzdXJlX3JlcG9ydF9hY3Rpb25fZnJhbWUodHBBbmlTaXJHbG9iYWwgcE1hYywKCQkJCQkgICB1aW50OF90IGRpYWxvZ190b2tlbiwKCQkJCQkgICB1aW50OF90IG51bV9yZXBvcnQsCgkJCQkJICAgdHBTaXJNYWNSYWRpb01lYXN1cmVSZXBvcnQgcFJSTVJlcG9ydCwKCQkJCQkgICB0U2lyTWFjQWRkciBwZWVyLAoJCQkJCSAgIHRwUEVTZXNzaW9uIHBzZXNzaW9uRW50cnkpCnsKCXRTaXJSZXRTdGF0dXMgc3RhdHVzQ29kZSA9IGVTSVJfU1VDQ0VTUzsKCXVpbnQ4X3QgKnBGcmFtZTsKCXRwU2lyTWFjTWdtdEhkciBwTWFjSGRyOwoJdWludDMyX3QgbkJ5dGVzLCBuUGF5bG9hZCwgblN0YXR1czsKCXZvaWQgKnBQYWNrZXQ7CglRREZfU1RBVFVTIHFkZl9zdGF0dXM7Cgl1aW50OF90IGk7Cgl1aW50OF90IHR4RmxhZyA9IDA7Cgl1aW50OF90IHNtZVNlc3Npb25JZCA9IDA7CgoJdERvdDExZlJhZGlvTWVhc3VyZW1lbnRSZXBvcnQgKmZybSA9CgkJcWRmX21lbV9tYWxsb2Moc2l6ZW9mKHREb3QxMWZSYWRpb01lYXN1cmVtZW50UmVwb3J0KSk7CglpZiAoIWZybSkgewoJCXBlX2VycigiTm90IGVub3VnaCBtZW1vcnkgdG8gYWxsb2NhdGUgdERvdDExZlJhZGlvTWVhc3VyZW1lbnRSZXBvcnQiKTsKCQlyZXR1cm4gZVNJUl9NRU1fQUxMT0NfRkFJTEVEOwoJfQoKCWlmIChwc2Vzc2lvbkVudHJ5ID09IE5VTEwpIHsKCQlwZV9lcnIoIihwc2Vzc2lvbiA9PSBOVUxMKSBpbiBSZXF1ZXN0IHRvIHNlbmQgQmVhY29uIFJlcG9ydCBhY3Rpb24gZnJhbWUiKTsKCQlxZGZfbWVtX2ZyZWUoZnJtKTsKCQlyZXR1cm4gZVNJUl9GQUlMVVJFOwoJfQoKCXBlX2RlYnVnKCJkaWFsb2dfdG9rZW4gJWQgbnVtX3JlcG9ydCAlZCIsCgkJCWRpYWxvZ190b2tlbiwgbnVtX3JlcG9ydCk7CgoJZnJtLT5DYXRlZ29yeS5jYXRlZ29yeSA9IFNJUl9NQUNfQUNUSU9OX1JSTTsKCWZybS0+QWN0aW9uLmFjdGlvbiA9IFNJUl9NQUNfUlJNX1JBRElPX01FQVNVUkVfUlBUOwoJZnJtLT5EaWFsb2dUb2tlbi50b2tlbiA9IGRpYWxvZ190b2tlbjsKCglmcm0tPm51bV9NZWFzdXJlbWVudFJlcG9ydCA9CgkJKG51bV9yZXBvcnQgPgoJCSBSQURJT19SRVBPUlRTX01BWF9JTl9BX0ZSQU1FKSA/IFJBRElPX1JFUE9SVFNfTUFYX0lOX0FfRlJBTUUgOgoJCW51bV9yZXBvcnQ7CgoJZm9yIChpID0gMDsgaSA8IGZybS0+bnVtX01lYXN1cmVtZW50UmVwb3J0OyBpKyspIHsKCQlmcm0tPk1lYXN1cmVtZW50UmVwb3J0W2ldLnR5cGUgPSBwUlJNUmVwb3J0W2ldLnR5cGU7CgkJZnJtLT5NZWFzdXJlbWVudFJlcG9ydFtpXS50b2tlbiA9IHBSUk1SZXBvcnRbaV0udG9rZW47CgkJZnJtLT5NZWFzdXJlbWVudFJlcG9ydFtpXS5sYXRlID0gMDsgICAgIC8qIElFRUUgODAyLjExayBzZWN0aW9uIDcuMy4yMi4gKGFsd2F5cyB6ZXJvIGluIHJybSkgKi8KCQlzd2l0Y2ggKHBSUk1SZXBvcnRbaV0udHlwZSkgewoJCWNhc2UgU0lSX01BQ19SUk1fQkVBQ09OX1RZUEU6CgkJCXBvcHVsYXRlX2RvdDExZl9iZWFjb25fcmVwb3J0KHBNYWMsCgkJCQkJCSAgICAgICZmcm0tPk1lYXN1cmVtZW50UmVwb3J0W2ldLAoJCQkJCQkgICAgICAmcFJSTVJlcG9ydFtpXS5yZXBvcnQuCgkJCQkJCSAgICAgIGJlYWNvblJlcG9ydCk7CgkJCWZybS0+TWVhc3VyZW1lbnRSZXBvcnRbaV0uaW5jYXBhYmxlID0KCQkJCXBSUk1SZXBvcnRbaV0uaW5jYXBhYmxlOwoJCQlmcm0tPk1lYXN1cmVtZW50UmVwb3J0W2ldLnJlZnVzZWQgPQoJCQkJcFJSTVJlcG9ydFtpXS5yZWZ1c2VkOwoJCQlmcm0tPk1lYXN1cmVtZW50UmVwb3J0W2ldLnByZXNlbnQgPSAxOwoJCQlicmVhazsKCQlkZWZhdWx0OgoJCQlmcm0tPk1lYXN1cmVtZW50UmVwb3J0W2ldLmluY2FwYWJsZSA9CgkJCQlwUlJNUmVwb3J0W2ldLmluY2FwYWJsZTsKCQkJZnJtLT5NZWFzdXJlbWVudFJlcG9ydFtpXS5yZWZ1c2VkID0KCQkJCXBSUk1SZXBvcnRbaV0ucmVmdXNlZDsKCQkJZnJtLT5NZWFzdXJlbWVudFJlcG9ydFtpXS5wcmVzZW50ID0gMTsKCQkJYnJlYWs7CgkJfQoJfQoKCW5TdGF0dXMgPQoJCWRvdDExZl9nZXRfcGFja2VkX3JhZGlvX21lYXN1cmVtZW50X3JlcG9ydF9zaXplKHBNYWMsIGZybSwgJm5QYXlsb2FkKTsKCWlmIChET1QxMUZfRkFJTEVEKG5TdGF0dXMpKSB7CgkJcGVfZXJyKCJGYWlsZWQgdG8gY2FsY3VsYXRlIHRoZSBwYWNrZWQgc2l6ZSBmb3IgYSBSYWRpbyBNZWFzdXJlIFJlcG9ydCAoMHglMDh4KSIsCgkJCW5TdGF0dXMpOwoJCS8qIFdlJ2xsIGZhbGwgYmFjayBvbiB0aGUgd29yc3QgY2FzZSBzY2VuYXJpbzogKi8KCQluUGF5bG9hZCA9IHNpemVvZih0RG90MTFmTGlua01lYXN1cmVtZW50UmVwb3J0KTsKCQlxZGZfbWVtX2ZyZWUoZnJtKTsKCQlyZXR1cm4gZVNJUl9GQUlMVVJFOwoJfSBlbHNlIGlmIChET1QxMUZfV0FSTkVEKG5TdGF0dXMpKSB7CgkJcGVfd2FybigiVGhlcmUgd2VyZSB3YXJuaW5ncyB3aGlsZSBjYWxjdWxhdGluZyB0aGUgcGFja2VkIHNpemUgZm9yIGEgUmFkaW8gTWVhc3VyZSBSZXBvcnQgKDB4JTA4eCkiLAoJCQluU3RhdHVzKTsKCX0KCgluQnl0ZXMgPSBuUGF5bG9hZCArIHNpemVvZih0U2lyTWFjTWdtdEhkcik7CgoJcWRmX3N0YXR1cyA9CgkJY2RzX3BhY2tldF9hbGxvYygodWludDE2X3QpIG5CeXRlcywgKHZvaWQgKiopJnBGcmFtZSwKCQkJCSAodm9pZCAqKikmcFBhY2tldCk7CglpZiAoIVFERl9JU19TVEFUVVNfU1VDQ0VTUyhxZGZfc3RhdHVzKSkgewoJCXBlX2VycigiRmFpbGVkIHRvIGFsbG9jYXRlICVkIGJ5dGVzIGZvciBhIFJhZGlvIE1lYXN1cmUgIgoJCQkgICAiUmVwb3J0IiwgbkJ5dGVzKTsKCQlxZGZfbWVtX2ZyZWUoZnJtKTsKCQlyZXR1cm4gZVNJUl9GQUlMVVJFOwoJfQoJLyogUGFyYW5vaWE6ICovCglxZGZfbWVtX3NldChwRnJhbWUsIG5CeXRlcywgMCk7CgoJLyogQ29weSBuZWNlc3NhcnkgaW5mbyB0byBCRCAqLwoJbGltX3BvcHVsYXRlX21hY19oZWFkZXIocE1hYywgcEZyYW1lLCBTSVJfTUFDX01HTVRfRlJBTUUsCgkJU0lSX01BQ19NR01UX0FDVElPTiwgcGVlciwgcHNlc3Npb25FbnRyeS0+c2VsZk1hY0FkZHIpOwoKCS8qIFVwZGF0ZSBBMyB3aXRoIHRoZSBCU1NJRCAqLwoJcE1hY0hkciA9ICh0cFNpck1hY01nbXRIZHIpIHBGcmFtZTsKCglzaXJfY29weV9tYWNfYWRkcihwTWFjSGRyLT5ic3NJZCwgcHNlc3Npb25FbnRyeS0+YnNzSWQpOwoKI2lmZGVmIFdMQU5fRkVBVFVSRV8xMVcKCWxpbV9zZXRfcHJvdGVjdGVkX2JpdChwTWFjLCBwc2Vzc2lvbkVudHJ5LCBwZWVyLCBwTWFjSGRyKTsKI2VuZGlmCgoJLyogTm93LCB3ZSdyZSByZWFkeSB0byAicGFjayIgdGhlIGZyYW1lcyAqLwoJblN0YXR1cyA9IGRvdDExZl9wYWNrX3JhZGlvX21lYXN1cmVtZW50X3JlcG9ydChwTWFjLAoJCQkJCQkgICAgICAgZnJtLAoJCQkJCQkgICAgICAgcEZyYW1lICsKCQkJCQkJICAgICAgIHNpemVvZih0U2lyTWFjTWdtdEhkciksCgkJCQkJCSAgICAgICBuUGF5bG9hZCwgJm5QYXlsb2FkKTsKCglpZiAoRE9UMTFGX0ZBSUxFRChuU3RhdHVzKSkgewoJCXBlX2VycigiRmFpbGVkIHRvIHBhY2sgYW4gUmFkaW8gTWVhc3VyZSBSZXBvcnQgKDB4JTA4eCkiLAoJCQluU3RhdHVzKTsKCgkJLyogRklYTUUgLSBOZWVkIHRvIGNvbnZlcnQgdG8gdFNpclJldFN0YXR1cyAqLwoJCXN0YXR1c0NvZGUgPSBlU0lSX0ZBSUxVUkU7CgkJZ290byByZXR1cm5BZnRlckVycm9yOwoJfSBlbHNlIGlmIChET1QxMUZfV0FSTkVEKG5TdGF0dXMpKSB7CgkJcGVfd2FybigiVGhlcmUgd2VyZSB3YXJuaW5ncyB3aGlsZSBwYWNraW5nIFJhZGlvIE1lYXN1cmUgUmVwb3J0ICgweCUwOHgpIiwKCQkJblN0YXR1cyk7Cgl9CgoJcGVfd2FybigiU2VuZGluZyBhIFJhZGlvIE1lYXN1cmUgUmVwb3J0IHRvIik7CglsaW1fcHJpbnRfbWFjX2FkZHIocE1hYywgcGVlciwgTE9HVyk7CgoJaWYgKChTSVJfQkFORF81X0dIWiA9PSBsaW1fZ2V0X3JmX2JhbmQocHNlc3Npb25FbnRyeS0+Y3VycmVudE9wZXJDaGFubmVsKSkKCSAgICB8fCAocHNlc3Npb25FbnRyeS0+cGVQZXJzb25hID09IFFERl9QMlBfQ0xJRU5UX01PREUpIHx8CgkgICAgKHBzZXNzaW9uRW50cnktPnBlUGVyc29uYSA9PSBRREZfUDJQX0dPX01PREUpCgkgICAgKSB7CgkJdHhGbGFnIHw9IEhBTF9VU0VfQkRfUkFURTJfRk9SX01BTkFHRU1FTlRfRlJBTUU7Cgl9CgoJTVRSQUNFKHFkZl90cmFjZShRREZfTU9EVUxFX0lEX1BFLCBUUkFDRV9DT0RFX1RYX01HTVQsCgkJCSBwc2Vzc2lvbkVudHJ5LT5wZVNlc3Npb25JZCwgcE1hY0hkci0+ZmMuc3ViVHlwZSkpOwoJcWRmX3N0YXR1cyA9IHdtYV90eF9mcmFtZShwTWFjLAoJCQkJcFBhY2tldCwKCQkJCSh1aW50MTZfdCkgbkJ5dGVzLAoJCQkJVFhSWF9GUk1fODAyXzExX01HTVQsCgkJCQlBTklfVFhESVJfVE9EUywKCQkJCTcsIGxpbV90eF9jb21wbGV0ZSwgcEZyYW1lLCB0eEZsYWcsCgkJCQlzbWVTZXNzaW9uSWQsIDApOwoJTVRSQUNFKHFkZl90cmFjZShRREZfTU9EVUxFX0lEX1BFLCBUUkFDRV9DT0RFX1RYX0NPTVBMRVRFLAoJCQkgcHNlc3Npb25FbnRyeS0+cGVTZXNzaW9uSWQsIHFkZl9zdGF0dXMpKTsKCWlmIChRREZfU1RBVFVTX1NVQ0NFU1MgIT0gcWRmX3N0YXR1cykgewoJCXBlX2Vycigid21hX3R4X2ZyYW1lIEZBSUxFRCEgU3RhdHVzIFslZF0iLCBxZGZfc3RhdHVzKTsKCQlzdGF0dXNDb2RlID0gZVNJUl9GQUlMVVJFOwoJCS8qIFBrdCB3aWxsIGJlIGZyZWVkIHVwIGJ5IHRoZSBjYWxsYmFjayAqLwoJCXFkZl9tZW1fZnJlZShmcm0pOwoJCXJldHVybiBzdGF0dXNDb2RlOwoJfSBlbHNlIHsKCQlxZGZfbWVtX2ZyZWUoZnJtKTsKCQlyZXR1cm4gZVNJUl9TVUNDRVNTOwoJfQoKcmV0dXJuQWZ0ZXJFcnJvcjoKCXFkZl9tZW1fZnJlZShmcm0pOwoJY2RzX3BhY2tldF9mcmVlKCh2b2lkICopcFBhY2tldCk7CglyZXR1cm4gc3RhdHVzQ29kZTsKfQoKI2lmZGVmIFdMQU5fRkVBVFVSRV8xMVcKLyoqCiAqIFxicmllZiBTZW5kIFNBIHF1ZXJ5IHJlcXVlc3QgYWN0aW9uIGZyYW1lIHRvIHBlZXIKICoKICogXHNhIGxpbV9zZW5kX3NhX3F1ZXJ5X3JlcXVlc3RfZnJhbWUKICoKICoKICogXHBhcmFtIHBNYWMgICAgVGhlIGdsb2JhbCB0cEFuaVNpckdsb2JhbCBvYmplY3QKICoKICogXHBhcmFtIHRyYW5zSWQgVHJhbnNhY3Rpb24gaWRlbnRpZmllcgogKgogKiBccGFyYW0gcGVlciAgICBUaGUgTWFjIGFkZHJlc3Mgb2YgdGhlIHN0YXRpb24gdG8gd2hpY2ggdGhpcyBhY3Rpb24gZnJhbWUgaXMgYWRkcmVzc2VkCiAqCiAqIFxwYXJhbSBwc2Vzc2lvbkVudHJ5IFRoZSBQRSBzZXNzaW9uIGVudHJ5CiAqCiAqIFxyZXR1cm4gZVNJUl9TVUNDRVNTIGlmIHNldHVwIGNvbXBsZXRlcyBzdWNjZXNzZnVsbHkKICogICAgICAgICBlU0lSX0ZBSUxVUkUgaXMgc29tZSBwcm9ibGVtIGlzIGVuY291bnRlcmVkCiAqLwoKdFNpclJldFN0YXR1cyBsaW1fc2VuZF9zYV9xdWVyeV9yZXF1ZXN0X2ZyYW1lKHRwQW5pU2lyR2xvYmFsIHBNYWMsIHVpbnQ4X3QgKnRyYW5zSWQsCgkJCQkJICAgICAgdFNpck1hY0FkZHIgcGVlciwKCQkJCQkgICAgICB0cFBFU2Vzc2lvbiBwc2Vzc2lvbkVudHJ5KQp7CgoJdERvdDExZlNhUXVlcnlSZXEgZnJtOyAgLyogU0EgcXVlcnkgcmVxdWVzdCBhY3Rpb24gZnJhbWUgKi8KCXVpbnQ4X3QgKnBGcmFtZTsKCXRTaXJSZXRTdGF0dXMgblNpclN0YXR1czsKCXRwU2lyTWFjTWdtdEhkciBwTWFjSGRyOwoJdWludDMyX3QgbkJ5dGVzLCBuUGF5bG9hZCwgblN0YXR1czsKCXZvaWQgKnBQYWNrZXQ7CglRREZfU1RBVFVTIHFkZl9zdGF0dXM7Cgl1aW50OF90IHR4RmxhZyA9IDA7Cgl1aW50OF90IHNtZVNlc3Npb25JZCA9IDA7CgoJcWRmX21lbV9zZXQoKHVpbnQ4X3QgKikgJmZybSwgc2l6ZW9mKGZybSksIDApOwoJZnJtLkNhdGVnb3J5LmNhdGVnb3J5ID0gU0lSX01BQ19BQ1RJT05fU0FfUVVFUlk7CgkvKiAxMXcgYWN0aW9uICBmaWVsZCBpcyA6CgkgICBhY3Rpb246IDAgLS0+IFNBIFF1ZXJ5IFJlcXVlc3QgYWN0aW9uIGZyYW1lCgkgICBhY3Rpb246IDEgLS0+IFNBIFF1ZXJ5IFJlc3BvbnNlIGFjdGlvbiBmcmFtZSAqLwoJZnJtLkFjdGlvbi5hY3Rpb24gPSBTSVJfTUFDX1NBX1FVRVJZX1JFUTsKCS8qIDExdyBTQSBRdWVyeSBSZXF1ZXN0IHRyYW5zSWQgKi8KCXFkZl9tZW1fY29weSgmZnJtLlRyYW5zYWN0aW9uSWQudHJhbnNJZFswXSwgJnRyYW5zSWRbMF0sIDIpOwoKCW5TdGF0dXMgPSBkb3QxMWZfZ2V0X3BhY2tlZF9zYV9xdWVyeV9yZXFfc2l6ZShwTWFjLCAmZnJtLCAmblBheWxvYWQpOwoJaWYgKERPVDExRl9GQUlMRUQoblN0YXR1cykpIHsKCQlwZV9lcnIoIkZhaWxlZCB0byBjYWxjdWxhdGUgdGhlIHBhY2tlZCBzaXplIGZvciBhbiBTQSBRdWVyeSBSZXF1ZXN0ICgweCUwOHgpIiwKCQkJblN0YXR1cyk7CgkJLyogV2UnbGwgZmFsbCBiYWNrIG9uIHRoZSB3b3JzdCBjYXNlIHNjZW5hcmlvOiAqLwoJCW5QYXlsb2FkID0gc2l6ZW9mKHREb3QxMWZTYVF1ZXJ5UmVxKTsKCX0gZWxzZSBpZiAoRE9UMTFGX1dBUk5FRChuU3RhdHVzKSkgewoJCXBlX3dhcm4oIlRoZXJlIHdlcmUgd2FybmluZ3Mgd2hpbGUgY2FsY3VsYXRpbmcgdGhlIHBhY2tlZCBzaXplIGZvciBhbiBTQSBRdWVyeSBSZXF1ZXN0ICgweCUwOHgpIiwKCQkJblN0YXR1cyk7Cgl9CgoJbkJ5dGVzID0gblBheWxvYWQgKyBzaXplb2YodFNpck1hY01nbXRIZHIpOwoJcWRmX3N0YXR1cyA9CgkJY2RzX3BhY2tldF9hbGxvYyhuQnl0ZXMsICh2b2lkICoqKSZwRnJhbWUsICh2b2lkICoqKSZwUGFja2V0KTsKCWlmICghUURGX0lTX1NUQVRVU19TVUNDRVNTKHFkZl9zdGF0dXMpKSB7CgkJcGVfZXJyKCJGYWlsZWQgdG8gYWxsb2NhdGUgJWQgYnl0ZXMgZm9yIGEgU0EgUXVlcnkgUmVxdWVzdCAiCgkJCSAgICJhY3Rpb24gZnJhbWUiLCBuQnl0ZXMpOwoJCXJldHVybiBlU0lSX0ZBSUxVUkU7Cgl9CgkvKiBQYXJhbm9pYTogKi8KCXFkZl9tZW1fc2V0KHBGcmFtZSwgbkJ5dGVzLCAwKTsKCgkvKiBDb3B5IG5lY2Vzc2FyeSBpbmZvIHRvIEJEICovCglsaW1fcG9wdWxhdGVfbWFjX2hlYWRlcihwTWFjLCBwRnJhbWUsIFNJUl9NQUNfTUdNVF9GUkFNRSwKCQlTSVJfTUFDX01HTVRfQUNUSU9OLCBwZWVyLCBwc2Vzc2lvbkVudHJ5LT5zZWxmTWFjQWRkcik7CgoJLyogVXBkYXRlIEEzIHdpdGggdGhlIEJTU0lEICovCglwTWFjSGRyID0gKHRwU2lyTWFjTWdtdEhkcikgcEZyYW1lOwoKCXNpcl9jb3B5X21hY19hZGRyKHBNYWNIZHItPmJzc0lkLCBwc2Vzc2lvbkVudHJ5LT5ic3NJZCk7CgoJLyogU2luY2UgdGhpcyBpcyBhIFNBIFF1ZXJ5IFJlcXVlc3QsIHNldCB0aGUgInByb3RlY3QiIChha2EgV0VQKSBiaXQgKi8KCS8qIGluIHRoZSBGQyAqLwoJbGltX3NldF9wcm90ZWN0ZWRfYml0KHBNYWMsIHBzZXNzaW9uRW50cnksIHBlZXIsIHBNYWNIZHIpOwoKCS8qIFBhY2sgMTF3IFNBIFF1ZXJ5IFJlcXVlc3QgZnJhbWUgKi8KCW5TdGF0dXMgPSBkb3QxMWZfcGFja19zYV9xdWVyeV9yZXEocE1hYywKCQkJCQkgICAmZnJtLAoJCQkJCSAgIHBGcmFtZSArIHNpemVvZih0U2lyTWFjTWdtdEhkciksCgkJCQkJICAgblBheWxvYWQsICZuUGF5bG9hZCk7CgoJaWYgKERPVDExRl9GQUlMRUQoblN0YXR1cykpIHsKCQlwZV9lcnIoIkZhaWxlZCB0byBwYWNrIGFuIFNBIFF1ZXJ5IFJlcXVlc3QgKDB4JTA4eCkiLAoJCQluU3RhdHVzKTsKCQkvKiBGSVhNRSAtIE5lZWQgdG8gY29udmVydCB0byB0U2lyUmV0U3RhdHVzICovCgkJblNpclN0YXR1cyA9IGVTSVJfRkFJTFVSRTsKCQlnb3RvIHJldHVybkFmdGVyRXJyb3I7Cgl9IGVsc2UgaWYgKERPVDExRl9XQVJORUQoblN0YXR1cykpIHsKCQlwZV93YXJuKCJUaGVyZSB3ZXJlIHdhcm5pbmdzIHdoaWxlIHBhY2tpbmcgU0EgUXVlcnkgUmVxdWVzdCAoMHglMDh4KSIsCgkJCW5TdGF0dXMpOwoJfQoKCXBlX2RlYnVnKCJTZW5kaW5nIGFuIFNBIFF1ZXJ5IFJlcXVlc3QgdG8iKTsKCWxpbV9wcmludF9tYWNfYWRkcihwTWFjLCBwZWVyLCBMT0dEKTsKCXBlX2RlYnVnKCJTZW5kaW5nIGFuIFNBIFF1ZXJ5IFJlcXVlc3QgZnJvbSAiKTsKCWxpbV9wcmludF9tYWNfYWRkcihwTWFjLCBwc2Vzc2lvbkVudHJ5LT5zZWxmTWFjQWRkciwgTE9HRCk7CgoJaWYgKChTSVJfQkFORF81X0dIWiA9PSBsaW1fZ2V0X3JmX2JhbmQocHNlc3Npb25FbnRyeS0+Y3VycmVudE9wZXJDaGFubmVsKSkKI2lmZGVmIFdMQU5fRkVBVFVSRV9QMlAKCSAgICB8fCAocHNlc3Npb25FbnRyeS0+cGVQZXJzb25hID09IFFERl9QMlBfQ0xJRU5UX01PREUpIHx8CgkgICAgKHBzZXNzaW9uRW50cnktPnBlUGVyc29uYSA9PSBRREZfUDJQX0dPX01PREUpCiNlbmRpZgoJICAgICkgewoJCXR4RmxhZyB8PSBIQUxfVVNFX0JEX1JBVEUyX0ZPUl9NQU5BR0VNRU5UX0ZSQU1FOwoJfQoJc21lU2Vzc2lvbklkID0gcHNlc3Npb25FbnRyeS0+c21lU2Vzc2lvbklkOwoKCXFkZl9zdGF0dXMgPSB3bWFfdHhfZnJhbWUocE1hYywKCQkJCXBQYWNrZXQsCgkJCQkodWludDE2X3QpIG5CeXRlcywKCQkJCVRYUlhfRlJNXzgwMl8xMV9NR01ULAoJCQkJQU5JX1RYRElSX1RPRFMsCgkJCQk3LCBsaW1fdHhfY29tcGxldGUsIHBGcmFtZSwgdHhGbGFnLAoJCQkJc21lU2Vzc2lvbklkLCAwKTsKCWlmIChRREZfU1RBVFVTX1NVQ0NFU1MgIT0gcWRmX3N0YXR1cykgewoJCXBlX2Vycigid21hX3R4X2ZyYW1lIEZBSUxFRCEgU3RhdHVzIFslZF0iLCBxZGZfc3RhdHVzKTsKCQluU2lyU3RhdHVzID0gZVNJUl9GQUlMVVJFOwoJCS8qIFBrdCB3aWxsIGJlIGZyZWVkIHVwIGJ5IHRoZSBjYWxsYmFjayAqLwoJCXJldHVybiBuU2lyU3RhdHVzOwoJfSBlbHNlIHsKCQlyZXR1cm4gZVNJUl9TVUNDRVNTOwoJfQoKcmV0dXJuQWZ0ZXJFcnJvcjoKCWNkc19wYWNrZXRfZnJlZSgodm9pZCAqKXBQYWNrZXQpOwoJcmV0dXJuIG5TaXJTdGF0dXM7Cn0gLyogRW5kIGxpbV9zZW5kX3NhX3F1ZXJ5X3JlcXVlc3RfZnJhbWUgKi8KCi8qKgogKiBcYnJpZWYgU2VuZCBTQSBxdWVyeSByZXNwb25zZSBhY3Rpb24gZnJhbWUgdG8gcGVlcgogKgogKiBcc2EgbGltX3NlbmRfc2FfcXVlcnlfcmVzcG9uc2VfZnJhbWUKICoKICoKICogXHBhcmFtIHBNYWMgICAgVGhlIGdsb2JhbCB0cEFuaVNpckdsb2JhbCBvYmplY3QKICoKICogXHBhcmFtIHRyYW5zSWQgVHJhbnNhY3Rpb24gaWRlbnRpZmllciByZWNlaXZlZCBpbiBTQSBxdWVyeSByZXF1ZXN0IGFjdGlvbiBmcmFtZQogKgogKiBccGFyYW0gcGVlciAgICBUaGUgTWFjIGFkZHJlc3Mgb2YgdGhlIEFQIHRvIHdoaWNoIHRoaXMgYWN0aW9uIGZyYW1lIGlzIGFkZHJlc3NlZAogKgogKiBccGFyYW0gcHNlc3Npb25FbnRyeSBUaGUgUEUgc2Vzc2lvbiBlbnRyeQogKgogKiBccmV0dXJuIGVTSVJfU1VDQ0VTUyBpZiBzZXR1cCBjb21wbGV0ZXMgc3VjY2Vzc2Z1bGx5CiAqICAgICAgICAgZVNJUl9GQUlMVVJFIGlzIHNvbWUgcHJvYmxlbSBpcyBlbmNvdW50ZXJlZAogKi8KCnRTaXJSZXRTdGF0dXMgbGltX3NlbmRfc2FfcXVlcnlfcmVzcG9uc2VfZnJhbWUodHBBbmlTaXJHbG9iYWwgcE1hYywKCQkJCQkgICAgICAgdWludDhfdCAqdHJhbnNJZCwgdFNpck1hY0FkZHIgcGVlciwKCQkJCQkgICAgICAgdHBQRVNlc3Npb24gcHNlc3Npb25FbnRyeSkKewoKCXREb3QxMWZTYVF1ZXJ5UnNwIGZybTsgIC8qIFNBIHF1ZXJ5IHJlcG9uc2UgYWN0aW9uIGZyYW1lICovCgl1aW50OF90ICpwRnJhbWU7Cgl0U2lyUmV0U3RhdHVzIG5TaXJTdGF0dXM7Cgl0cFNpck1hY01nbXRIZHIgcE1hY0hkcjsKCXVpbnQzMl90IG5CeXRlcywgblBheWxvYWQsIG5TdGF0dXM7Cgl2b2lkICpwUGFja2V0OwoJUURGX1NUQVRVUyBxZGZfc3RhdHVzOwoJdWludDhfdCB0eEZsYWcgPSAwOwoJdWludDhfdCBzbWVTZXNzaW9uSWQgPSAwOwoKCXNtZVNlc3Npb25JZCA9IHBzZXNzaW9uRW50cnktPnNtZVNlc3Npb25JZDsKCglxZGZfbWVtX3NldCgodWludDhfdCAqKSAmZnJtLCBzaXplb2YoZnJtKSwgMCk7Cglmcm0uQ2F0ZWdvcnkuY2F0ZWdvcnkgPSBTSVJfTUFDX0FDVElPTl9TQV9RVUVSWTsKCS8qMTF3IGFjdGlvbiAgZmllbGQgaXMgOgoJICAgYWN0aW9uOiAwIC0tPiBTQSBxdWVyeSByZXF1ZXN0IGFjdGlvbiBmcmFtZQoJICAgYWN0aW9uOiAxIC0tPiBTQSBxdWVyeSByZXNwb25zZSBhY3Rpb24gZnJhbWUgKi8KCWZybS5BY3Rpb24uYWN0aW9uID0gU0lSX01BQ19TQV9RVUVSWV9SU1A7CgkvKjExdyBTQSBxdWVyeSByZXNwb25zZSB0cmFuc0lkIGlzIHNhbWUgYXMKCSAgIFNBIHF1ZXJ5IHJlcXVlc3QgdHJhbnNJZCAqLwoJcWRmX21lbV9jb3B5KCZmcm0uVHJhbnNhY3Rpb25JZC50cmFuc0lkWzBdLCAmdHJhbnNJZFswXSwgMik7CgoJblN0YXR1cyA9IGRvdDExZl9nZXRfcGFja2VkX3NhX3F1ZXJ5X3JzcF9zaXplKHBNYWMsICZmcm0sICZuUGF5bG9hZCk7CglpZiAoRE9UMTFGX0ZBSUxFRChuU3RhdHVzKSkgewoJCXBlX2VycigiRmFpbGVkIHRvIGNhbGN1bGF0ZSB0aGUgcGFja2VkIHNpemUgZm9yIGEgU0EgUXVlcnkgUmVzcG9uc2UgKDB4JTA4eCkiLAoJCQluU3RhdHVzKTsKCQkvKiBXZSdsbCBmYWxsIGJhY2sgb24gdGhlIHdvcnN0IGNhc2Ugc2NlbmFyaW86ICovCgkJblBheWxvYWQgPSBzaXplb2YodERvdDExZlNhUXVlcnlSc3ApOwoJfSBlbHNlIGlmIChET1QxMUZfV0FSTkVEKG5TdGF0dXMpKSB7CgkJcGVfd2FybigiVGhlcmUgd2VyZSB3YXJuaW5ncyB3aGlsZSBjYWxjdWxhdGluZyB0aGUgcGFja2VkIHNpemUgZm9yIGFuIFNBIFF1ZXJ5IFJlc3BvbnNlICgweCUwOHgpIiwKCQkJblN0YXR1cyk7Cgl9CgoJbkJ5dGVzID0gblBheWxvYWQgKyBzaXplb2YodFNpck1hY01nbXRIZHIpOwoJcWRmX3N0YXR1cyA9CgkJY2RzX3BhY2tldF9hbGxvYyhuQnl0ZXMsICh2b2lkICoqKSZwRnJhbWUsICh2b2lkICoqKSZwUGFja2V0KTsKCWlmICghUURGX0lTX1NUQVRVU19TVUNDRVNTKHFkZl9zdGF0dXMpKSB7CgkJcGVfZXJyKCJGYWlsZWQgdG8gYWxsb2NhdGUgJWQgYnl0ZXMgZm9yIGEgU0EgcXVlcnkgcmVzcG9uc2UiCgkJCSAgICIgYWN0aW9uIGZyYW1lIiwgbkJ5dGVzKTsKCQlyZXR1cm4gZVNJUl9GQUlMVVJFOwoJfQoJLyogUGFyYW5vaWE6ICovCglxZGZfbWVtX3NldChwRnJhbWUsIG5CeXRlcywgMCk7CgoJLyogQ29weSBuZWNlc3NhcnkgaW5mbyB0byBCRCAqLwoJbGltX3BvcHVsYXRlX21hY19oZWFkZXIocE1hYywgcEZyYW1lLCBTSVJfTUFDX01HTVRfRlJBTUUsCgkJU0lSX01BQ19NR01UX0FDVElPTiwgcGVlciwgcHNlc3Npb25FbnRyeS0+c2VsZk1hY0FkZHIpOwoKCS8qIFVwZGF0ZSBBMyB3aXRoIHRoZSBCU1NJRCAqLwoJcE1hY0hkciA9ICh0cFNpck1hY01nbXRIZHIpIHBGcmFtZTsKCglzaXJfY29weV9tYWNfYWRkcihwTWFjSGRyLT5ic3NJZCwgcHNlc3Npb25FbnRyeS0+YnNzSWQpOwoKCS8qIFNpbmNlIHRoaXMgaXMgYSBTQSBRdWVyeSBSZXNwb25zZSwgc2V0IHRoZSAicHJvdGVjdCIgKGFrYSBXRVApIGJpdCAqLwoJLyogaW4gdGhlIEZDICovCglsaW1fc2V0X3Byb3RlY3RlZF9iaXQocE1hYywgcHNlc3Npb25FbnRyeSwgcGVlciwgcE1hY0hkcik7CgoJLyogUGFjayAxMXcgU0EgcXVlcnkgcmVzcG9uc2UgZnJhbWUgKi8KCW5TdGF0dXMgPSBkb3QxMWZfcGFja19zYV9xdWVyeV9yc3AocE1hYywKCQkJCQkgICAmZnJtLAoJCQkJCSAgIHBGcmFtZSArIHNpemVvZih0U2lyTWFjTWdtdEhkciksCgkJCQkJICAgblBheWxvYWQsICZuUGF5bG9hZCk7CgoJaWYgKERPVDExRl9GQUlMRUQoblN0YXR1cykpIHsKCQlwZV9lcnIoIkZhaWxlZCB0byBwYWNrIGFuIFNBIFF1ZXJ5IFJlc3BvbnNlICgweCUwOHgpIiwKCQkJblN0YXR1cyk7CgkJLyogRklYTUUgLSBOZWVkIHRvIGNvbnZlcnQgdG8gdFNpclJldFN0YXR1cyAqLwoJCW5TaXJTdGF0dXMgPSBlU0lSX0ZBSUxVUkU7CgkJZ290byByZXR1cm5BZnRlckVycm9yOwoJfSBlbHNlIGlmIChET1QxMUZfV0FSTkVEKG5TdGF0dXMpKSB7CgkJcGVfd2FybigiVGhlcmUgd2VyZSB3YXJuaW5ncyB3aGlsZSBwYWNraW5nIFNBIFF1ZXJ5IFJlc3BvbnNlICgweCUwOHgpIiwKCQkJblN0YXR1cyk7Cgl9CgoJcGVfZGVidWcoIlNlbmRpbmcgYSBTQSBRdWVyeSBSZXNwb25zZSB0byIpOwoJbGltX3ByaW50X21hY19hZGRyKHBNYWMsIHBlZXIsIExPR0QpOwoKCWlmICgoU0lSX0JBTkRfNV9HSFogPT0gbGltX2dldF9yZl9iYW5kKHBzZXNzaW9uRW50cnktPmN1cnJlbnRPcGVyQ2hhbm5lbCkpCiNpZmRlZiBXTEFOX0ZFQVRVUkVfUDJQCgkgICAgfHwgKHBzZXNzaW9uRW50cnktPnBlUGVyc29uYSA9PSBRREZfUDJQX0NMSUVOVF9NT0RFKSB8fAoJICAgIChwc2Vzc2lvbkVudHJ5LT5wZVBlcnNvbmEgPT0gUURGX1AyUF9HT19NT0RFKQojZW5kaWYKCSAgICApIHsKCQl0eEZsYWcgfD0gSEFMX1VTRV9CRF9SQVRFMl9GT1JfTUFOQUdFTUVOVF9GUkFNRTsKCX0KCglNVFJBQ0UocWRmX3RyYWNlKFFERl9NT0RVTEVfSURfUEUsIFRSQUNFX0NPREVfVFhfTUdNVCwKCQkJIHBzZXNzaW9uRW50cnktPnBlU2Vzc2lvbklkLCBwTWFjSGRyLT5mYy5zdWJUeXBlKSk7CglxZGZfc3RhdHVzID0gd21hX3R4X2ZyYW1lKHBNYWMsCgkJCQlwUGFja2V0LAoJCQkJKHVpbnQxNl90KSBuQnl0ZXMsCgkJCQlUWFJYX0ZSTV84MDJfMTFfTUdNVCwKCQkJCUFOSV9UWERJUl9UT0RTLAoJCQkJNywgbGltX3R4X2NvbXBsZXRlLCBwRnJhbWUsIHR4RmxhZywKCQkJCXNtZVNlc3Npb25JZCwgMCk7CglNVFJBQ0UocWRmX3RyYWNlKFFERl9NT0RVTEVfSURfUEUsIFRSQUNFX0NPREVfVFhfQ09NUExFVEUsCgkJCSBwc2Vzc2lvbkVudHJ5LT5wZVNlc3Npb25JZCwgcWRmX3N0YXR1cykpOwoJaWYgKFFERl9TVEFUVVNfU1VDQ0VTUyAhPSBxZGZfc3RhdHVzKSB7CgkJcGVfZXJyKCJ3bWFfdHhfZnJhbWUgRkFJTEVEISBTdGF0dXMgWyVkXSIsIHFkZl9zdGF0dXMpOwoJCW5TaXJTdGF0dXMgPSBlU0lSX0ZBSUxVUkU7CgkJLyogUGt0IHdpbGwgYmUgZnJlZWQgdXAgYnkgdGhlIGNhbGxiYWNrICovCgkJcmV0dXJuIG5TaXJTdGF0dXM7Cgl9IGVsc2UgewoJCXJldHVybiBlU0lSX1NVQ0NFU1M7Cgl9CgpyZXR1cm5BZnRlckVycm9yOgoJY2RzX3BhY2tldF9mcmVlKCh2b2lkICopcFBhY2tldCk7CglyZXR1cm4gblNpclN0YXR1czsKfSAvKiBFbmQgbGltX3NlbmRfc2FfcXVlcnlfcmVzcG9uc2VfZnJhbWUgKi8KI2VuZGlmCgovKioKICogbGltX3NlbmRfYWRkYmFfcmVzcG9uc2VfZnJhbWUoKTogU2VuZCBBRERCQSByZXNwb25zZSBhY3Rpb24gZnJhbWUgdG8gcGVlcgogKiBAbWFjX2N0eDogbWFjIGNvbnRleHQKICogQHBlZXJfbWFjOiBQZWVyIE1BQyBhZGRyZXNzCiAqIEB0aWQ6IFRJRCBmb3Igd2hpY2ggYWRkYmEgcmVzcG9uc2UgaXMgYmVpbmcgc2VudAogKiBAc2Vzc2lvbjogUEUgc2Vzc2lvbiBlbnRyeQogKgogKiBUaGlzIGZ1bmN0aW9uIGlzIGNhbGxlZCB3aGVuIEFEREJBIHJlcXVlc3QgaXMgc3VjY2Vzc2Z1bC4gQUREQkEgcmVzcG9uc2UgaXMKICogc2V0dXAgYnkgY2FsbGluZyBhZGRiYV9yZXNwb25zZV9zZXR1cCBBUEkgYW5kIGZyYW1lIGlzIHRoZW4gc2VudCBvdXQgT1RBLgogKgogKiBSZXR1cm46IFFERl9TVEFUVVMKICovClFERl9TVEFUVVMgbGltX3NlbmRfYWRkYmFfcmVzcG9uc2VfZnJhbWUodHBBbmlTaXJHbG9iYWwgbWFjX2N0eCwKCQkJdFNpck1hY0FkZHIgcGVlcl9tYWMsIHVpbnQxNl90IHRpZCwgdHBQRVNlc3Npb24gc2Vzc2lvbikKewoKCXREb3QxMWZhZGRiYV9yc3AgZnJtOwoJdWludDhfdCAqZnJhbWVfcHRyOwoJdHBTaXJNYWNNZ210SGRyIG1nbXRfaGRyOwoJdWludDMyX3QgbnVtX2J5dGVzLCBwYXlsb2FkX3NpemUsIHN0YXR1czsKCXZvaWQgKnBrdF9wdHI7CglRREZfU1RBVFVTIHFkZl9zdGF0dXM7Cgl1aW50OF90IHR4X2ZsYWcgPSAwOwoJdWludDhfdCBzbWVfc2Vzc2lvbmlkID0gMDsKCXVpbnQxNl90IGJ1ZmZfc2l6ZSwgc3RhdHVzX2NvZGUsIGJhdGltZW91dDsKCXVpbnQ4X3QgcGVlcl9pZCwgZGlhbG9nX3Rva2VuOwoJdm9pZCAqc29jID0gY2RzX2dldF9jb250ZXh0KFFERl9NT0RVTEVfSURfU09DKTsKCXZvaWQgKnBlZXIsICpwZGV2OwoKCXNtZV9zZXNzaW9uaWQgPSBzZXNzaW9uLT5zbWVTZXNzaW9uSWQ7CgoJcGRldiA9IGNkc19nZXRfY29udGV4dChRREZfTU9EVUxFX0lEX1RYUlgpOwoJaWYgKCFwZGV2KSB7CgkJcGVfZXJyKCJwZGV2IGlzIE5VTEwiKTsKCQlyZXR1cm4gUURGX1NUQVRVU19FX0ZBSUxVUkU7Cgl9CgoJcGVlciA9IGNkcF9wZWVyX2ZpbmRfYnlfYWRkcihzb2MsIHBkZXYsIHBlZXJfbWFjLCAmcGVlcl9pZCk7CglpZiAoIXBlZXIpIHsKCQlwZV9lcnIoIlBFRVIgWyVwTV0gbm90IGZvdW5kIiwgcGVlcl9tYWMpOwoJCXJldHVybiBRREZfU1RBVFVTX0VfRkFJTFVSRTsKCX0KCgljZHBfYWRkYmFfcmVzcG9uc2VzZXR1cChzb2MsIHBlZXIsIHRpZCwgJmRpYWxvZ190b2tlbiwKCQkmc3RhdHVzX2NvZGUsICZidWZmX3NpemUsICZiYXRpbWVvdXQpOwoKCXFkZl9tZW1fc2V0KCh1aW50OF90ICopICZmcm0sIHNpemVvZihmcm0pLCAwKTsKCWZybS5DYXRlZ29yeS5jYXRlZ29yeSA9IFNJUl9NQUNfQUNUSU9OX0JMS0FDSzsKCWZybS5BY3Rpb24uYWN0aW9uID0gU0lSX01BQ19BRERCQV9SU1A7CgoJZnJtLkRpYWxvZ1Rva2VuLnRva2VuID0gZGlhbG9nX3Rva2VuOwoJZnJtLlN0YXR1cy5zdGF0dXMgPSBzdGF0dXNfY29kZTsKCWZybS5hZGRiYV9wYXJhbV9zZXQudGlkID0gdGlkOwoJZnJtLmFkZGJhX3BhcmFtX3NldC5idWZmX3NpemUgPSBidWZmX3NpemU7Cglmcm0uYWRkYmFfcGFyYW1fc2V0LmFtc2R1X3N1cHAgPSBTSVJfTUFDX0JBX1BPTElDWV9JTU1FRElBVEU7Cglmcm0uYWRkYmFfcGFyYW1fc2V0LnBvbGljeSA9IFNJUl9NQUNfQkFfQU1TRFVfU1VQUE9SVEVEOwoJZnJtLmJhX3RpbWVvdXQudGltZW91dCA9IGJhdGltZW91dDsKCglwZV9kZWJ1ZygiU2VuZGluZyBhIEFEREJBIFJlc3BvbnNlIGZyb20gJXBNIHRvICVwTSIsCgkJc2Vzc2lvbi0+c2VsZk1hY0FkZHIsIHBlZXJfbWFjKTsKCXBlX2RlYnVnKCJ0aWQ6ICVkLCBkaWFsb2dfdG9rZW46ICVkLCBzdGF0dXM6ICVkLCBidWZmX3NpemU6ICVkIiwKCQl0aWQsIGZybS5EaWFsb2dUb2tlbi50b2tlbiwgZnJtLlN0YXR1cy5zdGF0dXMsCgkJZnJtLmFkZGJhX3BhcmFtX3NldC5idWZmX3NpemUpOwoKCXN0YXR1cyA9IGRvdDExZl9nZXRfcGFja2VkX2FkZGJhX3JzcF9zaXplKG1hY19jdHgsICZmcm0sICZwYXlsb2FkX3NpemUpOwoJaWYgKERPVDExRl9GQUlMRUQoc3RhdHVzKSkgewoJCXBlX2VycigiRmFpbGVkIHRvIGNhbGN1bGF0ZSB0aGUgcGFja2VkIHNpemUgZm9yIGEgQUREQkEgUmVzcG9uc2UgKDB4JTA4eCkuIiwKCQkJc3RhdHVzKTsKCQkvKiBXZSdsbCBmYWxsIGJhY2sgb24gdGhlIHdvcnN0IGNhc2Ugc2NlbmFyaW86ICovCgkJcGF5bG9hZF9zaXplID0gc2l6ZW9mKHREb3QxMWZhZGRiYV9yc3ApOwoJfSBlbHNlIGlmIChET1QxMUZfV0FSTkVEKHN0YXR1cykpIHsKCQlwZV93YXJuKCJUaGVyZSB3ZXJlIHdhcm5pbmdzIHdoaWxlIGNhbGN1bGF0aW5nIHRoZSBwYWNrZWQgc2l6ZSBmb3IgYSBBRERCQSBSZXNwb25zZSAoMHglMDh4KS4iLCBzdGF0dXMpOwoJfQoKCW51bV9ieXRlcyA9IHBheWxvYWRfc2l6ZSArIHNpemVvZigqbWdtdF9oZHIpOwoJcWRmX3N0YXR1cyA9IGNkc19wYWNrZXRfYWxsb2MobnVtX2J5dGVzLCAodm9pZCAqKikmZnJhbWVfcHRyLAoJCQkJICAgICAgKHZvaWQgKiopJnBrdF9wdHIpOwoJaWYgKCFRREZfSVNfU1RBVFVTX1NVQ0NFU1MocWRmX3N0YXR1cykpIHsKCQlwZV9lcnIoIkZhaWxlZCB0byBhbGxvY2F0ZSAlZCBieXRlcyBmb3IgYSBBRERCQSByZXNwb25zZSBhY3Rpb24gZnJhbWUiLAoJCQludW1fYnl0ZXMpOwoJCXJldHVybiBRREZfU1RBVFVTX0VfRkFJTFVSRTsKCX0KCXFkZl9tZW1fc2V0KGZyYW1lX3B0ciwgbnVtX2J5dGVzLCAwKTsKCglsaW1fcG9wdWxhdGVfbWFjX2hlYWRlcihtYWNfY3R4LCBmcmFtZV9wdHIsIFNJUl9NQUNfTUdNVF9GUkFNRSwKCQlTSVJfTUFDX01HTVRfQUNUSU9OLCBwZWVyX21hYywgc2Vzc2lvbi0+c2VsZk1hY0FkZHIpOwoKCS8qIFVwZGF0ZSBBMyB3aXRoIHRoZSBCU1NJRCAqLwoJbWdtdF9oZHIgPSAodHBTaXJNYWNNZ210SGRyKSBmcmFtZV9wdHI7CglzaXJfY29weV9tYWNfYWRkcihtZ210X2hkci0+YnNzSWQsIHNlc3Npb24tPmJzc0lkKTsKCgkvKiBBRERCQSBSZXNwb25zZSBpcyBhIHJvYnVzdCBtZ210IGFjdGlvbiBmcmFtZSwKCSAqIHNldCB0aGUgInByb3RlY3QiIChha2EgV0VQKSBiaXQgaW4gdGhlIEZDCgkgKi8KCWxpbV9zZXRfcHJvdGVjdGVkX2JpdChtYWNfY3R4LCBzZXNzaW9uLCBwZWVyX21hYywgbWdtdF9oZHIpOwoKCXN0YXR1cyA9IGRvdDExZl9wYWNrX2FkZGJhX3JzcChtYWNfY3R4LCAmZnJtLAoJCQlmcmFtZV9wdHIgKyBzaXplb2YodFNpck1hY01nbXRIZHIpLCBwYXlsb2FkX3NpemUsCgkJCSZwYXlsb2FkX3NpemUpOwoKCWlmIChET1QxMUZfRkFJTEVEKHN0YXR1cykpIHsKCQlwZV9lcnIoIkZhaWxlZCB0byBwYWNrIGEgQUREQkEgUmVzcG9uc2UgKDB4JTA4eCkiLAoJCQlzdGF0dXMpOwoJCXFkZl9zdGF0dXMgPSBRREZfU1RBVFVTX0VfRkFJTFVSRTsKCQlnb3RvIGVycm9yX2FkZGJhX3JzcDsKCX0gZWxzZSBpZiAoRE9UMTFGX1dBUk5FRChzdGF0dXMpKSB7CgkJcGVfd2FybigiVGhlcmUgd2VyZSB3YXJuaW5ncyB3aGlsZSBwYWNraW5nIEFEREJBIFJlc3BvbnNlICgweCUwOHgpIiwKCQkJc3RhdHVzKTsKCX0KCgoJaWYgKChTSVJfQkFORF81X0dIWiA9PSBsaW1fZ2V0X3JmX2JhbmQoc2Vzc2lvbi0+Y3VycmVudE9wZXJDaGFubmVsKSkKI2lmZGVmIFdMQU5fRkVBVFVSRV9QMlAKCSAgICB8fCAoc2Vzc2lvbi0+cGVQZXJzb25hID09IFFERl9QMlBfQ0xJRU5UX01PREUpIHx8CgkgICAgKHNlc3Npb24tPnBlUGVyc29uYSA9PSBRREZfUDJQX0dPX01PREUpCiNlbmRpZgoJICAgICkgewoJCXR4X2ZsYWcgfD0gSEFMX1VTRV9CRF9SQVRFMl9GT1JfTUFOQUdFTUVOVF9GUkFNRTsKCX0KCglNVFJBQ0UocWRmX3RyYWNlKFFERl9NT0RVTEVfSURfUEUsIFRSQUNFX0NPREVfVFhfTUdNVCwKCQkJIHNlc3Npb24tPnBlU2Vzc2lvbklkLCBtZ210X2hkci0+ZmMuc3ViVHlwZSkpOwoJcWRmX3N0YXR1cyA9IHdtYV90eF9mcmFtZShtYWNfY3R4LCBwa3RfcHRyLCAodWludDE2X3QpIG51bV9ieXRlcywKCQkJVFhSWF9GUk1fODAyXzExX01HTVQsIEFOSV9UWERJUl9UT0RTLCA3LAoJCQlsaW1fdHhfY29tcGxldGUsIGZyYW1lX3B0ciwgdHhfZmxhZywgc21lX3Nlc3Npb25pZCwgMCk7CglNVFJBQ0UocWRmX3RyYWNlKFFERl9NT0RVTEVfSURfUEUsIFRSQUNFX0NPREVfVFhfQ09NUExFVEUsCgkJCSBzZXNzaW9uLT5wZVNlc3Npb25JZCwgcWRmX3N0YXR1cykpOwoJaWYgKFFERl9TVEFUVVNfU1VDQ0VTUyAhPSBxZGZfc3RhdHVzKSB7CgkJcGVfZXJyKCJ3bWFfdHhfZnJhbWUgRkFJTEVEISBTdGF0dXMgWyVkXSIsCgkJCXFkZl9zdGF0dXMpOwoJCXFkZl9zdGF0dXMgPSBRREZfU1RBVFVTX0VfRkFJTFVSRTsKCQkvKgoJCSAqIHdtYV90eF9mcmFtZSBmcmVlIG1lbW9yeSBpbiBjZXJ0YWluIGNhc2VzLCBmcmVlIHBrdF9wdHIKCQkgKiBvbmx5IGlmIG5vdCBmcmVlZCBhbHJlYWR5LgoJCSAqLwoJCWlmIChwa3RfcHRyKQoJCQljZHNfcGFja2V0X2ZyZWUoKHZvaWQgKilwa3RfcHRyKTsKCQlyZXR1cm4gcWRmX3N0YXR1czsKCX0gZWxzZSB7CgkJcmV0dXJuIGVTSVJfU1VDQ0VTUzsKCX0KCmVycm9yX2FkZGJhX3JzcDoKCWNkc19wYWNrZXRfZnJlZSgodm9pZCAqKXBrdF9wdHIpOwoJcmV0dXJuIHFkZl9zdGF0dXM7Cn0K