LyoKICogQ29weXJpZ2h0IChjKSAxOTgyLCAxOTg2LCAxOTg4LCAxOTkwLCAxOTkzCiAqCVRoZSBSZWdlbnRzIG9mIHRoZSBVbml2ZXJzaXR5IG9mIENhbGlmb3JuaWEuICBBbGwgcmlnaHRzIHJlc2VydmVkLgogKgogKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCiAqIGFyZSBtZXQ6CiAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CiAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluIHRoZQogKiAgICBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUgZGlzdHJpYnV0aW9uLgogKiAzLiBBbGwgYWR2ZXJ0aXNpbmcgbWF0ZXJpYWxzIG1lbnRpb25pbmcgZmVhdHVyZXMgb3IgdXNlIG9mIHRoaXMgc29mdHdhcmUKICogICAgbXVzdCBkaXNwbGF5IHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ2VtZW50OgogKglUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZSBVbml2ZXJzaXR5IG9mCiAqCUNhbGlmb3JuaWEsIEJlcmtlbGV5IGFuZCBpdHMgY29udHJpYnV0b3JzLgogKiA0LiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBVbml2ZXJzaXR5IG5vciB0aGUgbmFtZXMgb2YgaXRzIGNvbnRyaWJ1dG9ycwogKiAgICBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUKICogICAgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCiAqCiAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIFJFR0VOVFMgQU5EIENPTlRSSUJVVE9SUyBgYEFTIElTJycgQU5ECiAqIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRQogKiBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRQogKiBBUkUgRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBSRUdFTlRTIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUKICogRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwKICogREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMKICogT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pCiAqIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUCiAqIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkKICogT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgogKiBTVUNIIERBTUFHRS4KICoKICoJQCgjKXRjcF9zdWJyLmMJOC4xIChCZXJrZWxleSkgNi8xMC85MwogKiB0Y3Bfc3Vici5jLHYgMS41IDE5OTQvMTAvMDggMjI6Mzk6NTggcGhrIEV4cAogKi8KCi8qCiAqIENoYW5nZXMgYW5kIGFkZGl0aW9ucyByZWxhdGluZyB0byBTTGlSUAogKiBDb3B5cmlnaHQgKGMpIDE5OTUgRGFubnkgR2FzcGFyb3Zza2kuCiAqIAogKiBQbGVhc2UgcmVhZCB0aGUgZmlsZSBDT1BZUklHSFQgZm9yIHRoZSAKICogdGVybXMgYW5kIGNvbmRpdGlvbnMgb2YgdGhlIGNvcHlyaWdodC4KICovCgojZGVmaW5lIFdBTlRfU1lTX0lPQ1RMX0gKI2luY2x1ZGUgPHNsaXJwLmg+CgovKiBwYXRjaGFibGUvc2V0dGFibGUgcGFyYW1ldGVycyBmb3IgdGNwICovCmludCAJdGNwX21zc2RmbHQgPSBUQ1BfTVNTOwppbnQgCXRjcF9ydHRkZmx0ID0gVENQVFZfU1JUVERGTFQgLyBQUl9TTE9XSFo7CmludAl0Y3BfZG9fcmZjMTMyMyA9IDA7CS8qIERvbid0IGRvIHJmYzEzMjMgcGVyZm9ybWFuY2UgZW5oYW5jZW1lbnRzICovCmludAl0Y3BfcmN2c3BhY2U7CS8qIFlvdSBtYXkgd2FudCB0byBjaGFuZ2UgdGhpcyAqLwppbnQJdGNwX3NuZHNwYWNlOwkvKiBLZWVwIHNtYWxsIGlmIHlvdSBoYXZlIGFuIGVycm9yIHByb25lIGxpbmsgKi8KCi8qCiAqIFRjcCBpbml0aWFsaXphdGlvbgogKi8Kdm9pZAp0Y3BfaW5pdCgpCnsKCXRjcF9pc3MgPSAxOwkJLyogd3JvbmcgKi8KCXRjYi5zb19uZXh0ID0gdGNiLnNvX3ByZXYgPSAmdGNiOwoJCgkvKiB0Y3BfcmN2c3BhY2UgPSBvdXIgV2luZG93IHdlIGFkdmVydGlzZSB0byB0aGUgcmVtb3RlICovCgl0Y3BfcmN2c3BhY2UgPSBUQ1BfUkNWU1BBQ0U7Cgl0Y3Bfc25kc3BhY2UgPSBUQ1BfU05EU1BBQ0U7CgkKCS8qIE1ha2Ugc3VyZSB0Y3Bfc25kc3BhY2UgaXMgYXQgbGVhc3QgMipNU1MgKi8KCWlmICh0Y3Bfc25kc3BhY2UgPCAyKihtaW4oaWZfbXR1LCBpZl9tcnUpIC0gc2l6ZW9mKHN0cnVjdCB0Y3BpcGhkcikpKQoJCXRjcF9zbmRzcGFjZSA9IDIqKG1pbihpZl9tdHUsIGlmX21ydSkgLSBzaXplb2Yoc3RydWN0IHRjcGlwaGRyKSk7Cn0KCi8qCiAqIENyZWF0ZSB0ZW1wbGF0ZSB0byBiZSB1c2VkIHRvIHNlbmQgdGNwIHBhY2tldHMgb24gYSBjb25uZWN0aW9uLgogKiBDYWxsIGFmdGVyIGhvc3QgZW50cnkgY3JlYXRlZCwgZmlsbHMKICogaW4gYSBza2VsZXRhbCB0Y3AvaXAgaGVhZGVyLCBtaW5pbWl6aW5nIHRoZSBhbW91bnQgb2Ygd29yawogKiBuZWNlc3Nhcnkgd2hlbiB0aGUgY29ubmVjdGlvbiBpcyB1c2VkLgogKi8KLyogc3RydWN0IHRjcGlwaGRyICogKi8Kdm9pZAp0Y3BfdGVtcGxhdGUodHApCglzdHJ1Y3QgdGNwY2IgKnRwOwp7CglzdHJ1Y3Qgc29ja2V0ICpzbyA9IHRwLT50X3NvY2tldDsKCXJlZ2lzdGVyIHN0cnVjdCB0Y3BpcGhkciAqbiA9ICZ0cC0+dF90ZW1wbGF0ZTsKCgluLT50aV9uZXh0ID0gbi0+dGlfcHJldiA9IDA7CgluLT50aV94MSA9IDA7CgluLT50aV9wciA9IElQUFJPVE9fVENQOwoJbi0+dGlfbGVuID0gaHRvbnMoc2l6ZW9mIChzdHJ1Y3QgdGNwaXBoZHIpIC0gc2l6ZW9mIChzdHJ1Y3QgaXApKTsKCW4tPnRpX3NyYyA9IHNvLT5zb19mYWRkcjsKCW4tPnRpX2RzdCA9IHNvLT5zb19sYWRkcjsKCW4tPnRpX3Nwb3J0ID0gc28tPnNvX2Zwb3J0OwoJbi0+dGlfZHBvcnQgPSBzby0+c29fbHBvcnQ7CgkKCW4tPnRpX3NlcSA9IDA7CgluLT50aV9hY2sgPSAwOwoJbi0+dGlfeDIgPSAwOwoJbi0+dGlfb2ZmID0gNTsKCW4tPnRpX2ZsYWdzID0gMDsKCW4tPnRpX3dpbiA9IDA7CgluLT50aV9zdW0gPSAwOwoJbi0+dGlfdXJwID0gMDsKfQoKLyoKICogU2VuZCBhIHNpbmdsZSBtZXNzYWdlIHRvIHRoZSBUQ1AgYXQgYWRkcmVzcyBzcGVjaWZpZWQgYnkKICogdGhlIGdpdmVuIFRDUC9JUCBoZWFkZXIuICBJZiBtID09IDAsIHRoZW4gd2UgbWFrZSBhIGNvcHkKICogb2YgdGhlIHRjcGlwaGRyIGF0IHRpIGFuZCBzZW5kIGRpcmVjdGx5IHRvIHRoZSBhZGRyZXNzZWQgaG9zdC4KICogVGhpcyBpcyB1c2VkIHRvIGZvcmNlIGtlZXAgYWxpdmUgbWVzc2FnZXMgb3V0IHVzaW5nIHRoZSBUQ1AKICogdGVtcGxhdGUgZm9yIGEgY29ubmVjdGlvbiB0cC0+dF90ZW1wbGF0ZS4gIElmIGZsYWdzIGFyZSBnaXZlbgogKiB0aGVuIHdlIHNlbmQgYSBtZXNzYWdlIGJhY2sgdG8gdGhlIFRDUCB3aGljaCBvcmlnaW5hdGVkIHRoZQogKiBzZWdtZW50IHRpLCBhbmQgZGlzY2FyZCB0aGUgbWJ1ZiBjb250YWluaW5nIGl0IGFuZCBhbnkgb3RoZXIKICogYXR0YWNoZWQgbWJ1ZnMuCiAqCiAqIEluIGFueSBjYXNlIHRoZSBhY2sgYW5kIHNlcXVlbmNlIG51bWJlciBvZiB0aGUgdHJhbnNtaXR0ZWQKICogc2VnbWVudCBhcmUgYXMgc3BlY2lmaWVkIGJ5IHRoZSBwYXJhbWV0ZXJzLgogKi8Kdm9pZAp0Y3BfcmVzcG9uZCh0cCwgdGksIG0sIGFjaywgc2VxLCBmbGFncykKCXN0cnVjdCB0Y3BjYiAqdHA7CglyZWdpc3RlciBzdHJ1Y3QgdGNwaXBoZHIgKnRpOwoJcmVnaXN0ZXIgc3RydWN0IG1idWYgKm07Cgl0Y3Bfc2VxIGFjaywgc2VxOwoJaW50IGZsYWdzOwp7CglyZWdpc3RlciBpbnQgdGxlbjsKCWludCB3aW4gPSAwOwoKCURFQlVHX0NBTEwoInRjcF9yZXNwb25kIik7CglERUJVR19BUkcoInRwID0gJWx4IiwgKGxvbmcpdHApOwoJREVCVUdfQVJHKCJ0aSA9ICVseCIsIChsb25nKXRpKTsKCURFQlVHX0FSRygibSA9ICVseCIsIChsb25nKW0pOwoJREVCVUdfQVJHKCJhY2sgPSAldSIsIGFjayk7CglERUJVR19BUkcoInNlcSA9ICV1Iiwgc2VxKTsKCURFQlVHX0FSRygiZmxhZ3MgPSAleCIsIGZsYWdzKTsKCQoJaWYgKHRwKQoJCXdpbiA9IHNic3BhY2UoJnRwLT50X3NvY2tldC0+c29fcmN2KTsKCWlmIChtID09IDApIHsKCQlpZiAoKG0gPSBtX2dldCgpKSA9PSBOVUxMKQoJCQlyZXR1cm47CiNpZmRlZiBUQ1BfQ09NUEFUXzQyCgkJdGxlbiA9IDE7CiNlbHNlCgkJdGxlbiA9IDA7CiNlbmRpZgoJCW0tPm1fZGF0YSArPSBpZl9tYXhsaW5raGRyOwoJCSptdG9kKG0sIHN0cnVjdCB0Y3BpcGhkciAqKSA9ICp0aTsKCQl0aSA9IG10b2QobSwgc3RydWN0IHRjcGlwaGRyICopOwoJCWZsYWdzID0gVEhfQUNLOwoJfSBlbHNlIHsKCQkvKiAKCQkgKiB0aSBwb2ludHMgaW50byBtIHNvIHRoZSBuZXh0IGxpbmUgaXMganVzdCBtYWtpbmcKCQkgKiB0aGUgbWJ1ZiBwb2ludCB0byB0aQoJCSAqLwoJCW0tPm1fZGF0YSA9IChjYWRkcl90KXRpOwoJCQoJCW0tPm1fbGVuID0gc2l6ZW9mIChzdHJ1Y3QgdGNwaXBoZHIpOwoJCXRsZW4gPSAwOwojZGVmaW5lIHhjaGcoYSxiLHR5cGUpIHsgdHlwZSB0OyB0PWE7IGE9YjsgYj10OyB9CgkJeGNoZyh0aS0+dGlfZHN0LnNfYWRkciwgdGktPnRpX3NyYy5zX2FkZHIsIHVfaW50MzJfdCk7CgkJeGNoZyh0aS0+dGlfZHBvcnQsIHRpLT50aV9zcG9ydCwgdV9pbnQxNl90KTsKI3VuZGVmIHhjaGcKCX0KCXRpLT50aV9sZW4gPSBodG9ucygodV9zaG9ydCkoc2l6ZW9mIChzdHJ1Y3QgdGNwaGRyKSArIHRsZW4pKTsKCXRsZW4gKz0gc2l6ZW9mIChzdHJ1Y3QgdGNwaXBoZHIpOwoJbS0+bV9sZW4gPSB0bGVuOwoKCXRpLT50aV9uZXh0ID0gdGktPnRpX3ByZXYgPSAwOwoJdGktPnRpX3gxID0gMDsKCXRpLT50aV9zZXEgPSBodG9ubChzZXEpOwoJdGktPnRpX2FjayA9IGh0b25sKGFjayk7Cgl0aS0+dGlfeDIgPSAwOwoJdGktPnRpX29mZiA9IHNpemVvZiAoc3RydWN0IHRjcGhkcikgPj4gMjsKCXRpLT50aV9mbGFncyA9IGZsYWdzOwoJaWYgKHRwKQoJCXRpLT50aV93aW4gPSBodG9ucygodV9pbnQxNl90KSAod2luID4+IHRwLT5yY3Zfc2NhbGUpKTsKCWVsc2UKCQl0aS0+dGlfd2luID0gaHRvbnMoKHVfaW50MTZfdCl3aW4pOwoJdGktPnRpX3VycCA9IDA7Cgl0aS0+dGlfc3VtID0gMDsKCXRpLT50aV9zdW0gPSBja3N1bShtLCB0bGVuKTsKCSgoc3RydWN0IGlwICopdGkpLT5pcF9sZW4gPSB0bGVuOwoKCWlmKGZsYWdzICYgVEhfUlNUKSAKCSAgKChzdHJ1Y3QgaXAgKil0aSktPmlwX3R0bCA9IE1BWFRUTDsKCWVsc2UgCgkgICgoc3RydWN0IGlwICopdGkpLT5pcF90dGwgPSBpcF9kZWZ0dGw7CgkKCSh2b2lkKSBpcF9vdXRwdXQoKHN0cnVjdCBzb2NrZXQgKikwLCBtKTsKfQoKLyoKICogQ3JlYXRlIGEgbmV3IFRDUCBjb250cm9sIGJsb2NrLCBtYWtpbmcgYW4KICogZW1wdHkgcmVhc3NlbWJseSBxdWV1ZSBhbmQgaG9va2luZyBpdCB0byB0aGUgYXJndW1lbnQKICogcHJvdG9jb2wgY29udHJvbCBibG9jay4KICovCnN0cnVjdCB0Y3BjYiAqCnRjcF9uZXd0Y3BjYihzbykKCXN0cnVjdCBzb2NrZXQgKnNvOwp7CglyZWdpc3RlciBzdHJ1Y3QgdGNwY2IgKnRwOwoJCgl0cCA9IChzdHJ1Y3QgdGNwY2IgKiltYWxsb2Moc2l6ZW9mKCp0cCkpOwoJaWYgKHRwID09IE5VTEwpCgkJcmV0dXJuICgoc3RydWN0IHRjcGNiICopMCk7CgkKCW1lbXNldCgoY2hhciAqKSB0cCwgMCwgc2l6ZW9mKHN0cnVjdCB0Y3BjYikpOwoJdHAtPnNlZ19uZXh0ID0gdHAtPnNlZ19wcmV2ID0gKHRjcGlwaGRycF8zMil0cDsKCXRwLT50X21heHNlZyA9IHRjcF9tc3NkZmx0OwoJCgl0cC0+dF9mbGFncyA9IHRjcF9kb19yZmMxMzIzID8gKFRGX1JFUV9TQ0FMRXxURl9SRVFfVFNUTVApIDogMDsKCXRwLT50X3NvY2tldCA9IHNvOwoJCgkvKgoJICogSW5pdCBzcnR0IHRvIFRDUFRWX1NSVFRCQVNFICgwKSwgc28gd2UgY2FuIHRlbGwgdGhhdCB3ZSBoYXZlIG5vCgkgKiBydHQgZXN0aW1hdGUuICBTZXQgcnR0dmFyIHNvIHRoYXQgc3J0dCArIDIgKiBydHR2YXIgZ2l2ZXMKCSAqIHJlYXNvbmFibGUgaW5pdGlhbCByZXRyYW5zbWl0IHRpbWUuCgkgKi8KCXRwLT50X3NydHQgPSBUQ1BUVl9TUlRUQkFTRTsKCXRwLT50X3J0dHZhciA9IHRjcF9ydHRkZmx0ICogUFJfU0xPV0haIDw8IDI7Cgl0cC0+dF9ydHRtaW4gPSBUQ1BUVl9NSU47CgoJVENQVF9SQU5HRVNFVCh0cC0+dF9yeHRjdXIsIAoJICAgICgoVENQVFZfU1JUVEJBU0UgPj4gMikgKyAoVENQVFZfU1JUVERGTFQgPDwgMikpID4+IDEsCgkgICAgVENQVFZfTUlOLCBUQ1BUVl9SRVhNVE1BWCk7CgoJdHAtPnNuZF9jd25kID0gVENQX01BWFdJTiA8PCBUQ1BfTUFYX1dJTlNISUZUOwoJdHAtPnNuZF9zc3RocmVzaCA9IFRDUF9NQVhXSU4gPDwgVENQX01BWF9XSU5TSElGVDsKCXRwLT50X3N0YXRlID0gVENQU19DTE9TRUQ7CgkKCXNvLT5zb190Y3BjYiA9IHRwOwoKCXJldHVybiAodHApOwp9CgovKgogKiBEcm9wIGEgVENQIGNvbm5lY3Rpb24sIHJlcG9ydGluZwogKiB0aGUgc3BlY2lmaWVkIGVycm9yLiAgSWYgY29ubmVjdGlvbiBpcyBzeW5jaHJvbml6ZWQsCiAqIHRoZW4gc2VuZCBhIFJTVCB0byBwZWVyLgogKi8Kc3RydWN0IHRjcGNiICp0Y3BfZHJvcChzdHJ1Y3QgdGNwY2IgKnRwLCBpbnQgZXJyKSAKewovKiB0Y3BfZHJvcCh0cCwgZXJybm8pCglyZWdpc3RlciBzdHJ1Y3QgdGNwY2IgKnRwOwoJaW50IGVycm5vOwp7CiovCgoJREVCVUdfQ0FMTCgidGNwX2Ryb3AiKTsKCURFQlVHX0FSRygidHAgPSAlbHgiLCAobG9uZyl0cCk7CglERUJVR19BUkcoImVycm5vID0gJWQiLCBlcnJubyk7CgkKCWlmIChUQ1BTX0hBVkVSQ1ZEU1lOKHRwLT50X3N0YXRlKSkgewoJCXRwLT50X3N0YXRlID0gVENQU19DTE9TRUQ7CgkJKHZvaWQpIHRjcF9vdXRwdXQodHApOwoJCXRjcHN0YXQudGNwc19kcm9wcysrOwoJfSBlbHNlCgkJdGNwc3RhdC50Y3BzX2Nvbm5kcm9wcysrOwovKglpZiAoZXJybm8gPT0gRVRJTUVET1VUICYmIHRwLT50X3NvZnRlcnJvcikKICoJCWVycm5vID0gdHAtPnRfc29mdGVycm9yOwogKi8KLyoJc28tPnNvX2Vycm9yID0gZXJybm87ICovCglyZXR1cm4gKHRjcF9jbG9zZSh0cCkpOwp9CgovKgogKiBDbG9zZSBhIFRDUCBjb250cm9sIGJsb2NrOgogKglkaXNjYXJkIGFsbCBzcGFjZSBoZWxkIGJ5IHRoZSB0Y3AKICoJZGlzY2FyZCBpbnRlcm5ldCBwcm90b2NvbCBibG9jawogKgl3YWtlIHVwIGFueSBzbGVlcGVycwogKi8Kc3RydWN0IHRjcGNiICoKdGNwX2Nsb3NlKHRwKQoJcmVnaXN0ZXIgc3RydWN0IHRjcGNiICp0cDsKewoJcmVnaXN0ZXIgc3RydWN0IHRjcGlwaGRyICp0OwoJc3RydWN0IHNvY2tldCAqc28gPSB0cC0+dF9zb2NrZXQ7CglyZWdpc3RlciBzdHJ1Y3QgbWJ1ZiAqbTsKCglERUJVR19DQUxMKCJ0Y3BfY2xvc2UiKTsKCURFQlVHX0FSRygidHAgPSAlbHgiLCAobG9uZyApdHApOwoJCgkvKiBmcmVlIHRoZSByZWFzc2VtYmx5IHF1ZXVlLCBpZiBhbnkgKi8KCXQgPSAoc3RydWN0IHRjcGlwaGRyICopIHRwLT5zZWdfbmV4dDsKCXdoaWxlICh0ICE9IChzdHJ1Y3QgdGNwaXBoZHIgKil0cCkgewoJCXQgPSAoc3RydWN0IHRjcGlwaGRyICopdC0+dGlfbmV4dDsKCQltID0gKHN0cnVjdCBtYnVmICopIFJFQVNTX01CVUYoKHN0cnVjdCB0Y3BpcGhkciAqKXQtPnRpX3ByZXYpOwoJCXJlbXF1ZV8zMigoc3RydWN0IHRjcGlwaGRyICopIHQtPnRpX3ByZXYpOwoJCW1fZnJlZW0obSk7Cgl9CgkvKiBJdCdzIHN0YXRpYyAqLwovKglpZiAodHAtPnRfdGVtcGxhdGUpCiAqCQkodm9pZCkgbV9mcmVlKGR0b20odHAtPnRfdGVtcGxhdGUpKTsKICovCi8qCWZyZWUodHAsIE1fUENCKTsgICovCglmcmVlKHRwKTsKCXNvLT5zb190Y3BjYiA9IDA7Cglzb2lzZmRpc2Nvbm5lY3RlZChzbyk7CgkvKiBjbG9iYmVyIGlucHV0IHNvY2tldCBjYWNoZSBpZiB3ZSdyZSBjbG9zaW5nIHRoZSBjYWNoZWQgY29ubmVjdGlvbiAqLwoJaWYgKHNvID09IHRjcF9sYXN0X3NvKQoJCXRjcF9sYXN0X3NvID0gJnRjYjsKCWNsb3Nlc29ja2V0KHNvLT5zKTsKCXNiZnJlZSgmc28tPnNvX3Jjdik7CglzYmZyZWUoJnNvLT5zb19zbmQpOwoJc29mcmVlKHNvKTsKCXRjcHN0YXQudGNwc19jbG9zZWQrKzsKCXJldHVybiAoKHN0cnVjdCB0Y3BjYiAqKTApOwp9Cgp2b2lkCnRjcF9kcmFpbigpCnsKCS8qIFhYWCAqLwp9CgovKgogKiBXaGVuIGEgc291cmNlIHF1ZW5jaCBpcyByZWNlaXZlZCwgY2xvc2UgY29uZ2VzdGlvbiB3aW5kb3cKICogdG8gb25lIHNlZ21lbnQuICBXZSB3aWxsIGdyYWR1YWxseSBvcGVuIGl0IGFnYWluIGFzIHdlIHByb2NlZWQuCiAqLwoKI2lmZGVmIG5vdGRlZgoKdm9pZAp0Y3BfcXVlbmNoKGksIGVycm5vKQoKCWludCBlcnJubzsKewoJc3RydWN0IHRjcGNiICp0cCA9IGludG90Y3BjYihpbnApOwoKCWlmICh0cCkKCQl0cC0+c25kX2N3bmQgPSB0cC0+dF9tYXhzZWc7Cn0KCiNlbmRpZiAvKiBub3RkZWYgKi8KCi8qCiAqIFRDUCBwcm90b2NvbCBpbnRlcmZhY2UgdG8gc29ja2V0IGFic3RyYWN0aW9uLgogKi8KCi8qCiAqIFVzZXIgaXNzdWVkIGNsb3NlLCBhbmQgd2lzaCB0byB0cmFpbCB0aHJvdWdoIHNodXRkb3duIHN0YXRlczoKICogaWYgbmV2ZXIgcmVjZWl2ZWQgU1lOLCBqdXN0IGZvcmdldCBpdC4gIElmIGdvdCBhIFNZTiBmcm9tIHBlZXIsCiAqIGJ1dCBoYXZlbid0IHNlbnQgRklOLCB0aGVuIGdvIHRvIEZJTl9XQUlUXzEgc3RhdGUgdG8gc2VuZCBwZWVyIGEgRklOLgogKiBJZiBhbHJlYWR5IGdvdCBhIEZJTiBmcm9tIHBlZXIsIHRoZW4gYWxtb3N0IGRvbmU7IGdvIHRvIExBU1RfQUNLCiAqIHN0YXRlLiAgSW4gYWxsIG90aGVyIGNhc2VzLCBoYXZlIGFscmVhZHkgc2VudCBGSU4gdG8gcGVlciAoZS5nLgogKiBhZnRlciBQUlVfU0hVVERPV04pLCBhbmQganVzdCBoYXZlIHRvIHBsYXkgdGVkaW91cyBnYW1lIHdhaXRpbmcKICogZm9yIHBlZXIgdG8gc2VuZCBGSU4gb3Igbm90IHJlc3BvbmQgdG8ga2VlcC1hbGl2ZXMsIGV0Yy4KICogV2UgY2FuIGxldCB0aGUgdXNlciBleGl0IGZyb20gdGhlIGNsb3NlIGFzIHNvb24gYXMgdGhlIEZJTiBpcyBhY2tlZC4KICovCnZvaWQKdGNwX3NvY2tjbG9zZWQodHApCglzdHJ1Y3QgdGNwY2IgKnRwOwp7CgoJREVCVUdfQ0FMTCgidGNwX3NvY2tjbG9zZWQiKTsKCURFQlVHX0FSRygidHAgPSAlbHgiLCAobG9uZyl0cCk7CgkKCXN3aXRjaCAodHAtPnRfc3RhdGUpIHsKCgljYXNlIFRDUFNfQ0xPU0VEOgoJY2FzZSBUQ1BTX0xJU1RFTjoKCWNhc2UgVENQU19TWU5fU0VOVDoKCQl0cC0+dF9zdGF0ZSA9IFRDUFNfQ0xPU0VEOwoJCXRwID0gdGNwX2Nsb3NlKHRwKTsKCQlicmVhazsKCgljYXNlIFRDUFNfU1lOX1JFQ0VJVkVEOgoJY2FzZSBUQ1BTX0VTVEFCTElTSEVEOgoJCXRwLT50X3N0YXRlID0gVENQU19GSU5fV0FJVF8xOwoJCWJyZWFrOwoKCWNhc2UgVENQU19DTE9TRV9XQUlUOgoJCXRwLT50X3N0YXRlID0gVENQU19MQVNUX0FDSzsKCQlicmVhazsKCX0KLyoJc29pc2ZkaXNjb25uZWN0aW5nKHRwLT50X3NvY2tldCk7ICovCglpZiAodHAgJiYgdHAtPnRfc3RhdGUgPj0gVENQU19GSU5fV0FJVF8yKQoJCXNvaXNmZGlzY29ubmVjdGVkKHRwLT50X3NvY2tldCk7CglpZiAodHApCgkJdGNwX291dHB1dCh0cCk7Cn0KCi8qIAogKiBDb25uZWN0IHRvIGEgaG9zdCBvbiB0aGUgSW50ZXJuZXQKICogQ2FsbGVkIGJ5IHRjcF9pbnB1dAogKiBPbmx5IGRvIGEgY29ubmVjdCwgdGhlIHRjcCBmaWVsZHMgd2lsbCBiZSBzZXQgaW4gdGNwX2lucHV0CiAqIHJldHVybiAwIGlmIHRoZXJlJ3MgYSByZXN1bHQgb2YgdGhlIGNvbm5lY3QsCiAqIGVsc2UgcmV0dXJuIC0xIG1lYW5zIHdlJ3JlIHN0aWxsIGNvbm5lY3RpbmcKICogVGhlIHJldHVybiB2YWx1ZSBpcyBhbG1vc3QgYWx3YXlzIC0xIHNpbmNlIHRoZSBzb2NrZXQgaXMKICogbm9uYmxvY2tpbmcuICBDb25uZWN0IHJldHVybnMgYWZ0ZXIgdGhlIFNZTiBpcyBzZW50LCBhbmQgZG9lcyAKICogbm90IHdhaXQgZm9yIEFDSytTWU4uCiAqLwppbnQgdGNwX2Zjb25uZWN0KHNvKQogICAgIHN0cnVjdCBzb2NrZXQgKnNvOwp7CiAgaW50IHJldD0wOwogIAogIERFQlVHX0NBTEwoInRjcF9mY29ubmVjdCIpOwogIERFQlVHX0FSRygic28gPSAlbHgiLCAobG9uZyApc28pOwoKICBpZiggKHJldD1zby0+cz1zb2NrZXQoQUZfSU5FVCxTT0NLX1NUUkVBTSwwKSkgPj0gMCkgewogICAgaW50IG9wdCwgcz1zby0+czsKICAgIHN0cnVjdCBzb2NrYWRkcl9pbiBhZGRyOwoKICAgIGZkX25vbmJsb2NrKHMpOwogICAgb3B0ID0gMTsKICAgIHNldHNvY2tvcHQocyxTT0xfU09DS0VULFNPX1JFVVNFQUREUiwoY2hhciAqKSZvcHQsc2l6ZW9mKG9wdCApKTsKICAgIG9wdCA9IDE7CiAgICBzZXRzb2Nrb3B0KHMsU09MX1NPQ0tFVCxTT19PT0JJTkxJTkUsKGNoYXIgKikmb3B0LHNpemVvZihvcHQgKSk7CiAgICAKICAgIGFkZHIuc2luX2ZhbWlseSA9IEFGX0lORVQ7CiAgICBpZiAoKHNvLT5zb19mYWRkci5zX2FkZHIgJiBodG9ubCgweGZmZmZmZjAwKSkgPT0gc3BlY2lhbF9hZGRyLnNfYWRkcikgewogICAgICAvKiBJdCdzIGFuIGFsaWFzICovCiAgICAgIHN3aXRjaChudG9obChzby0+c29fZmFkZHIuc19hZGRyKSAmIDB4ZmYpIHsKICAgICAgY2FzZSBDVExfRE5TOgoJYWRkci5zaW5fYWRkciA9IGRuc19hZGRyOwoJYnJlYWs7CiAgICAgIGNhc2UgQ1RMX0FMSUFTOgogICAgICBkZWZhdWx0OgoJYWRkci5zaW5fYWRkciA9IGxvb3BiYWNrX2FkZHI7CglicmVhazsKICAgICAgfQogICAgfSBlbHNlCiAgICAgIGFkZHIuc2luX2FkZHIgPSBzby0+c29fZmFkZHI7CiAgICBhZGRyLnNpbl9wb3J0ID0gc28tPnNvX2Zwb3J0OwogICAgCiAgICBERUJVR19NSVNDKChkZmQsICIgY29ubmVjdCgpaW5nLCBhZGRyLnNpbl9wb3J0PSVkLCAiCgkJImFkZHIuc2luX2FkZHIuc19hZGRyPSUuMTZzXG4iLCAKCQludG9ocyhhZGRyLnNpbl9wb3J0KSwgaW5ldF9udG9hKGFkZHIuc2luX2FkZHIpKSk7CiAgICAvKiBXZSBkb24ndCBjYXJlIHdoYXQgcG9ydCB3ZSBnZXQgKi8KICAgIHJldCA9IGNvbm5lY3Qocywoc3RydWN0IHNvY2thZGRyICopJmFkZHIsc2l6ZW9mIChhZGRyKSk7CiAgICAKICAgIC8qCiAgICAgKiBJZiBpdCdzIG5vdCBpbiBwcm9ncmVzcywgaXQgZmFpbGVkLCBzbyB3ZSBqdXN0IHJldHVybiAwLAogICAgICogd2l0aG91dCBjbGVhcmluZyBTU19OT0ZEUkVGCiAgICAgKi8KICAgIHNvaXNmY29ubmVjdGluZyhzbyk7CiAgfQoKICByZXR1cm4ocmV0KTsKfQoKLyoKICogQWNjZXB0IHRoZSBzb2NrZXQgYW5kIGNvbm5lY3QgdG8gdGhlIGxvY2FsLWhvc3QKICogCiAqIFdlIGhhdmUgYSBwcm9ibGVtLiBUaGUgY29ycmVjdCB0aGluZyB0byBkbyB3b3VsZCBiZQogKiB0byBmaXJzdCBjb25uZWN0IHRvIHRoZSBsb2NhbC1ob3N0LCBhbmQgb25seSBpZiB0aGUKICogY29ubmVjdGlvbiBpcyBhY2NlcHRlZCwgdGhlbiBkbyBhbiBhY2NlcHQoKSBoZXJlLgogKiBCdXQsIGEpIHdlIG5lZWQgdG8ga25vdyB3aG8ncyB0cnlpbmcgdG8gY29ubmVjdCAKICogdG8gdGhlIHNvY2tldCB0byBiZSBhYmxlIHRvIFNZTiB0aGUgbG9jYWwtaG9zdCwgYW5kCiAqIGIpIHdlIGFyZSBhbHJlYWR5IGNvbm5lY3RlZCB0byB0aGUgZm9yZWlnbiBob3N0IGJ5CiAqIHRoZSB0aW1lIGl0IGdldHMgdG8gYWNjZXB0KCksIHNvLi4uIFdlIHNpbXBseSBhY2NlcHQKICogaGVyZSBhbmQgU1lOIHRoZSBsb2NhbC1ob3N0LgogKi8gCnZvaWQKdGNwX2Nvbm5lY3QoaW5zbykKCXN0cnVjdCBzb2NrZXQgKmluc287CnsKCXN0cnVjdCBzb2NrZXQgKnNvOwoJc3RydWN0IHNvY2thZGRyX2luIGFkZHI7CglpbnQgYWRkcmxlbiA9IHNpemVvZihzdHJ1Y3Qgc29ja2FkZHJfaW4pOwoJc3RydWN0IHRjcGNiICp0cDsKCWludCBzLCBvcHQ7CgoJREVCVUdfQ0FMTCgidGNwX2Nvbm5lY3QiKTsKCURFQlVHX0FSRygiaW5zbyA9ICVseCIsIChsb25nKWluc28pOwoJCgkvKgoJICogSWYgaXQncyBhbiBTU19BQ0NFUFRPTkNFIHNvY2tldCwgbm8gbmVlZCB0byBzb2NyZWF0ZSgpCgkgKiBhbm90aGVyIHNvY2tldCwganVzdCB1c2UgdGhlIGFjY2VwdCgpIHNvY2tldC4KCSAqLwoJaWYgKGluc28tPnNvX3N0YXRlICYgU1NfRkFDQ0VQVE9OQ0UpIHsKCQkvKiBGQUNDRVBUT05DRSBhbHJlYWR5IGhhdmUgYSB0Y3BjYiAqLwoJCXNvID0gaW5zbzsKCX0gZWxzZSB7CgkJaWYgKChzbyA9IHNvY3JlYXRlKCkpID09IE5VTEwpIHsKCQkJLyogSWYgaXQgZmFpbGVkLCBnZXQgcmlkIG9mIHRoZSBwZW5kaW5nIGNvbm5lY3Rpb24gKi8KCQkJY2xvc2Vzb2NrZXQoYWNjZXB0KGluc28tPnMsKHN0cnVjdCBzb2NrYWRkciAqKSZhZGRyLCZhZGRybGVuKSk7CgkJCXJldHVybjsKCQl9CgkJaWYgKHRjcF9hdHRhY2goc28pIDwgMCkgewoJCQlmcmVlKHNvKTsgLyogTk9UIHNvZnJlZSAqLwoJCQlyZXR1cm47CgkJfQoJCXNvLT5zb19sYWRkciA9IGluc28tPnNvX2xhZGRyOwoJCXNvLT5zb19scG9ydCA9IGluc28tPnNvX2xwb3J0OwoJfQoJCgkodm9pZCkgdGNwX21zcyhzb3RvdGNwY2Ioc28pLCAwKTsKCglpZiAoKHMgPSBhY2NlcHQoaW5zby0+cywoc3RydWN0IHNvY2thZGRyICopJmFkZHIsJmFkZHJsZW4pKSA8IDApIHsKCQl0Y3BfY2xvc2Uoc290b3RjcGNiKHNvKSk7IC8qIFRoaXMgd2lsbCBzb2ZyZWUoKSBhcyB3ZWxsICovCgkJcmV0dXJuOwoJfQoJZmRfbm9uYmxvY2socyk7CglvcHQgPSAxOwoJc2V0c29ja29wdChzLFNPTF9TT0NLRVQsU09fUkVVU0VBRERSLChjaGFyICopJm9wdCxzaXplb2YoaW50KSk7CglvcHQgPSAxOwoJc2V0c29ja29wdChzLFNPTF9TT0NLRVQsU09fT09CSU5MSU5FLChjaGFyICopJm9wdCxzaXplb2YoaW50KSk7CglvcHQgPSAxOwoJc2V0c29ja29wdChzLElQUFJPVE9fVENQLFRDUF9OT0RFTEFZLChjaGFyICopJm9wdCxzaXplb2YoaW50KSk7CgkKCXNvLT5zb19mcG9ydCA9IGFkZHIuc2luX3BvcnQ7Cglzby0+c29fZmFkZHIgPSBhZGRyLnNpbl9hZGRyOwoJLyogVHJhbnNsYXRlIGNvbm5lY3Rpb25zIGZyb20gbG9jYWxob3N0IHRvIHRoZSByZWFsIGhvc3RuYW1lICovCglpZiAoc28tPnNvX2ZhZGRyLnNfYWRkciA9PSAwIHx8IHNvLT5zb19mYWRkci5zX2FkZHIgPT0gbG9vcGJhY2tfYWRkci5zX2FkZHIpCgkgICBzby0+c29fZmFkZHIgPSBhbGlhc19hZGRyOwoJCgkvKiBDbG9zZSB0aGUgYWNjZXB0KCkgc29ja2V0LCBzZXQgcmlnaHQgc3RhdGUgKi8KCWlmIChpbnNvLT5zb19zdGF0ZSAmIFNTX0ZBQ0NFUFRPTkNFKSB7CgkJY2xvc2Vzb2NrZXQoc28tPnMpOyAvKiBJZiB3ZSBvbmx5IGFjY2VwdCBvbmNlLCBjbG9zZSB0aGUgYWNjZXB0KCkgc29ja2V0ICovCgkJc28tPnNvX3N0YXRlID0gU1NfTk9GRFJFRjsgLyogRG9uJ3Qgc2VsZWN0IGl0IHlldCwgZXZlbiB0aG91Z2ggd2UgaGF2ZSBhbiBGRCAqLwoJCQkJCSAgIC8qIGlmIGl0J3Mgbm90IEZBQ0NFUFRPTkNFLCBpdCdzIGFscmVhZHkgTk9GRFJFRiAqLwoJfQoJc28tPnMgPSBzOwoJCglzby0+c29faXB0b3MgPSB0Y3BfdG9zKHNvKTsKCXRwID0gc290b3RjcGNiKHNvKTsKCgl0Y3BfdGVtcGxhdGUodHApOwoJCgkvKiBDb21wdXRlIHdpbmRvdyBzY2FsaW5nIHRvIHJlcXVlc3QuICAqLwovKgl3aGlsZSAodHAtPnJlcXVlc3Rfcl9zY2FsZSA8IFRDUF9NQVhfV0lOU0hJRlQgJiYKICoJCShUQ1BfTUFYV0lOIDw8IHRwLT5yZXF1ZXN0X3Jfc2NhbGUpIDwgc28tPnNvX3Jjdi5zYl9oaXdhdCkKICoJCXRwLT5yZXF1ZXN0X3Jfc2NhbGUrKzsKICovCgovKglzb2lzY29ubmVjdGluZyhzbyk7ICovIC8qIE5PRkRSRUYgdXNlZCBpbnN0ZWFkICovCgl0Y3BzdGF0LnRjcHNfY29ubmF0dGVtcHQrKzsKCQoJdHAtPnRfc3RhdGUgPSBUQ1BTX1NZTl9TRU5UOwoJdHAtPnRfdGltZXJbVENQVF9LRUVQXSA9IFRDUFRWX0tFRVBfSU5JVDsKCXRwLT5pc3MgPSB0Y3BfaXNzOyAKCXRjcF9pc3MgKz0gVENQX0lTU0lOQ1IvMjsKCXRjcF9zZW5kc2VxaW5pdCh0cCk7Cgl0Y3Bfb3V0cHV0KHRwKTsKfQoKLyoKICogQXR0YWNoIGEgVENQQ0IgdG8gYSBzb2NrZXQuCiAqLwppbnQKdGNwX2F0dGFjaChzbykKCXN0cnVjdCBzb2NrZXQgKnNvOwp7CglpZiAoKHNvLT5zb190Y3BjYiA9IHRjcF9uZXd0Y3BjYihzbykpID09IE5VTEwpCgkgICByZXR1cm4gLTE7CgkKCWluc3F1ZShzbywgJnRjYik7CgoJcmV0dXJuIDA7Cn0KCi8qCiAqIFNldCB0aGUgc29ja2V0J3MgdHlwZSBvZiBzZXJ2aWNlIGZpZWxkCiAqLwpzdHJ1Y3QgdG9zX3QgdGNwdG9zW10gPSB7CgkgIHswLCAyMCwgSVBUT1NfVEhST1VHSFBVVCwgMH0sCS8qIGZ0cCBkYXRhICovCgkgIHsyMSwgMjEsIElQVE9TX0xPV0RFTEFZLCAgRU1VX0ZUUH0sCS8qIGZ0cCBjb250cm9sICovCgkgIHswLCAyMywgSVBUT1NfTE9XREVMQVksIDB9LAkvKiB0ZWxuZXQgKi8KCSAgezAsIDgwLCBJUFRPU19USFJPVUdIUFVULCAwfSwJLyogV1dXICovCgkgIHswLCA1MTMsIElQVE9TX0xPV0RFTEFZLCBFTVVfUkxPR0lOfEVNVV9OT0NPTk5FQ1R9LAkvKiBybG9naW4gKi8KCSAgezAsIDUxNCwgSVBUT1NfTE9XREVMQVksIEVNVV9SU0h8RU1VX05PQ09OTkVDVH0sCS8qIHNoZWxsICovCgkgIHswLCA1NDQsIElQVE9TX0xPV0RFTEFZLCBFTVVfS1NIfSwJCS8qIGtzaGVsbCAqLwoJICB7MCwgNTQzLCBJUFRPU19MT1dERUxBWSwgMH0sCS8qIGtsb2dpbiAqLwoJICB7MCwgNjY2NywgSVBUT1NfVEhST1VHSFBVVCwgRU1VX0lSQ30sCS8qIElSQyAqLwoJICB7MCwgNjY2OCwgSVBUT1NfVEhST1VHSFBVVCwgRU1VX0lSQ30sCS8qIElSQyB1bmRlcm5ldCAqLwoJICB7MCwgNzA3MCwgSVBUT1NfTE9XREVMQVksIEVNVV9SRUFMQVVESU8gfSwgLyogUmVhbEF1ZGlvIGNvbnRyb2wgKi8KCSAgezAsIDExMywgSVBUT1NfTE9XREVMQVksIEVNVV9JREVOVCB9LCAvKiBpZGVudGQgcHJvdG9jb2wgKi8KCSAgezAsIDAsIDAsIDB9Cn07CgpzdHJ1Y3QgZW11X3QgKnRjcGVtdSA9IDA7CgkJCi8qCiAqIFJldHVybiBUT1MgYWNjb3JkaW5nIHRvIHRoZSBhYm92ZSB0YWJsZQogKi8KdV9pbnQ4X3QKdGNwX3RvcyhzbykKCXN0cnVjdCBzb2NrZXQgKnNvOwp7CglpbnQgaSA9IDA7CglzdHJ1Y3QgZW11X3QgKmVtdXA7CgkKCXdoaWxlKHRjcHRvc1tpXS50b3MpIHsKCQlpZiAoKHRjcHRvc1tpXS5mcG9ydCAmJiAobnRvaHMoc28tPnNvX2Zwb3J0KSA9PSB0Y3B0b3NbaV0uZnBvcnQpKSB8fAoJCSAgICAodGNwdG9zW2ldLmxwb3J0ICYmIChudG9ocyhzby0+c29fbHBvcnQpID09IHRjcHRvc1tpXS5scG9ydCkpKSB7CgkJCXNvLT5zb19lbXUgPSB0Y3B0b3NbaV0uZW11OwoJCQlyZXR1cm4gdGNwdG9zW2ldLnRvczsKCQl9CgkJaSsrOwoJfQoJCgkvKiBOb3BlLCBsZXRzIHNlZSBpZiB0aGVyZSdzIGEgdXNlci1hZGRlZCBvbmUgKi8KCWZvciAoZW11cCA9IHRjcGVtdTsgZW11cDsgZW11cCA9IGVtdXAtPm5leHQpIHsKCQlpZiAoKGVtdXAtPmZwb3J0ICYmIChudG9ocyhzby0+c29fZnBvcnQpID09IGVtdXAtPmZwb3J0KSkgfHwKCQkgICAgKGVtdXAtPmxwb3J0ICYmIChudG9ocyhzby0+c29fbHBvcnQpID09IGVtdXAtPmxwb3J0KSkpIHsKCQkJc28tPnNvX2VtdSA9IGVtdXAtPmVtdTsKCQkJcmV0dXJuIGVtdXAtPnRvczsKCQl9Cgl9CgkKCXJldHVybiAwOwp9CgppbnQgZG9fZWNobyA9IC0xOwoKLyoKICogRW11bGF0ZSBwcm9ncmFtcyB0aGF0IHRyeSBhbmQgY29ubmVjdCB0byB1cwogKiBUaGlzIGluY2x1ZGVzIGZ0cCAodGhlIGRhdGEgY29ubmVjdGlvbiBpcwogKiBpbml0aWF0ZWQgYnkgdGhlIHNlcnZlcikgYW5kIElSQyAoRENDIENIQVQgYW5kCiAqIERDQyBTRU5EKSBmb3Igbm93CiAqIAogKiBOT1RFOiBJdCdzIHBvc3NpYmxlIHRvIGNyYXNoIFNMaVJQIGJ5IHNlbmRpbmcgaXQKICogdW5zdGFuZGFyZCBzdHJpbmdzIHRvIGVtdWxhdGUuLi4gaWYgdGhpcyBpcyBhIHByb2JsZW0sCiAqIG1vcmUgY2hlY2tzIGFyZSBuZWVkZWQgaGVyZQogKgogKiBYWFggQXNzdW1lcyB0aGUgd2hvbGUgY29tbWFuZCBjYW1lIGluIG9uZSBwYWNrZXQKICoJCQkJCSAgICAKICogWFhYIFNvbWUgZnRwIGNsaWVudHMgd2lsbCBoYXZlIHRoZWlyIFRPUyBzZXQgdG8KICogTE9XREVMQVkgYW5kIHNvIE5hZ2VsIHdpbGwga2ljayBpbi4gIEJlY2F1c2Ugb2YgdGhpcywKICogd2UnbGwgZ2V0IHRoZSBmaXJzdCBsZXR0ZXIsIGZvbGxvd2VkIGJ5IHRoZSByZXN0LCBzbwogKiB3ZSBzaW1wbHkgc2NhbiBmb3IgT1JUIGluc3RlYWQgb2YgUE9SVC4uLgogKiBEQ0MgZG9lc24ndCBoYXZlIHRoaXMgcHJvYmxlbSBiZWNhdXNlIHRoZXJlJ3Mgb3RoZXIgc3R1ZmYKICogaW4gdGhlIHBhY2tldCBiZWZvcmUgdGhlIERDQyBjb21tYW5kLgogKiAKICogUmV0dXJuIDEgaWYgdGhlIG1idWYgbSBpcyBzdGlsbCB2YWxpZCBhbmQgc2hvdWxkIGJlIAogKiBzYmFwcGVuZCgpZWQKICogCiAqIE5PVEU6IGlmIHlvdSByZXR1cm4gMCB5b3UgTVVTVCBtX2ZyZWUoKSB0aGUgbWJ1ZiEKICovCmludAp0Y3BfZW11KHNvLCBtKQoJc3RydWN0IHNvY2tldCAqc287CglzdHJ1Y3QgbWJ1ZiAqbTsKewoJdV9pbnQgbjEsIG4yLCBuMywgbjQsIG41LCBuNjsKCWNoYXIgYnVmZlsyNTZdOwoJdV9pbnQzMl90IGxhZGRyOwoJdV9pbnQgbHBvcnQ7CgljaGFyICpicHRyOwoJCglERUJVR19DQUxMKCJ0Y3BfZW11Iik7CglERUJVR19BUkcoInNvID0gJWx4IiwgKGxvbmcpc28pOwoJREVCVUdfQVJHKCJtID0gJWx4IiwgKGxvbmcpbSk7CgkKCXN3aXRjaChzby0+c29fZW11KSB7CgkJaW50IHgsIGk7CgkJCgkgY2FzZSBFTVVfSURFTlQ6CgkJLyoKCQkgKiBJZGVudGlmaWNhdGlvbiBwcm90b2NvbCBhcyBwZXIgcmZjLTE0MTMKCQkgKi8KCQkKCQl7CgkJCXN0cnVjdCBzb2NrZXQgKnRtcHNvOwoJCQlzdHJ1Y3Qgc29ja2FkZHJfaW4gYWRkcjsKCQkJaW50IGFkZHJsZW4gPSBzaXplb2Yoc3RydWN0IHNvY2thZGRyX2luKTsKCQkJc3RydWN0IHNidWYgKnNvX3JjdiA9ICZzby0+c29fcmN2OwoJCQkKCQkJbWVtY3B5KHNvX3Jjdi0+c2Jfd3B0ciwgbS0+bV9kYXRhLCBtLT5tX2xlbik7CgkJCXNvX3Jjdi0+c2Jfd3B0ciArPSBtLT5tX2xlbjsKCQkJc29fcmN2LT5zYl9ycHRyICs9IG0tPm1fbGVuOwoJCQltLT5tX2RhdGFbbS0+bV9sZW5dID0gMDsgLyogTlVMTCB0ZXJtaW5hdGUgKi8KCQkJaWYgKHN0cmNocihtLT5tX2RhdGEsICdccicpIHx8IHN0cmNocihtLT5tX2RhdGEsICdcbicpKSB7CgkJCQlpZiAoc3NjYW5mKHNvX3Jjdi0+c2JfZGF0YSwgIiVkJSpbICxdJWQiLCAmbjEsICZuMikgPT0gMikgewoJCQkJCUhUT05TKG4xKTsKCQkJCQlIVE9OUyhuMik7CgkJCQkJLyogbjIgaXMgdGhlIG9uZSBvbiBvdXIgaG9zdCAqLwoJCQkJCWZvciAodG1wc28gPSB0Y2Iuc29fbmV4dDsgdG1wc28gIT0gJnRjYjsgdG1wc28gPSB0bXBzby0+c29fbmV4dCkgewoJCQkJCQlpZiAodG1wc28tPnNvX2xhZGRyLnNfYWRkciA9PSBzby0+c29fbGFkZHIuc19hZGRyICYmCgkJCQkJCSAgICB0bXBzby0+c29fbHBvcnQgPT0gbjIgJiYKCQkJCQkJICAgIHRtcHNvLT5zb19mYWRkci5zX2FkZHIgPT0gc28tPnNvX2ZhZGRyLnNfYWRkciAmJgoJCQkJCQkgICAgdG1wc28tPnNvX2Zwb3J0ID09IG4xKSB7CgkJCQkJCQlpZiAoZ2V0c29ja25hbWUodG1wc28tPnMsCgkJCQkJCQkJKHN0cnVjdCBzb2NrYWRkciAqKSZhZGRyLCAmYWRkcmxlbikgPT0gMCkKCQkJCQkJCSAgIG4yID0gbnRvaHMoYWRkci5zaW5fcG9ydCk7CgkJCQkJCQlicmVhazsKCQkJCQkJfQoJCQkJCX0KCQkJCX0KCQkJCXNvX3Jjdi0+c2JfY2MgPSBzcHJpbnRmKHNvX3Jjdi0+c2JfZGF0YSwgIiVkLCVkXHJcbiIsIG4xLCBuMik7CgkJCQlzb19yY3YtPnNiX3JwdHIgPSBzb19yY3YtPnNiX2RhdGE7CgkJCQlzb19yY3YtPnNiX3dwdHIgPSBzb19yY3YtPnNiX2RhdGEgKyBzb19yY3YtPnNiX2NjOwoJCQl9CgkJCW1fZnJlZShtKTsKCQkJcmV0dXJuIDA7CgkJfQoJCQojaWYgMAoJIGNhc2UgRU1VX1JMT0dJTjoKCQkvKgoJCSAqIFJsb2dpbiBlbXVsYXRpb24KCQkgKiBGaXJzdCB3ZSBhY2N1bXVsYXRlIGFsbCB0aGUgaW5pdGlhbCBvcHRpb24gbmVnb3RpYXRpb24sCgkJICogdGhlbiBmb3JrX2V4ZWMoKSBybG9naW4gYWNjb3JkaW5nIHRvIHRoZSAgb3B0aW9ucwoJCSAqLwoJCXsKCQkJaW50IGksIGkyLCBuOwoJCQljaGFyICpwdHI7CgkJCWNoYXIgYXJnc1sxMDBdOwoJCQljaGFyIHRlcm1bMTAwXTsKCQkJc3RydWN0IHNidWYgKnNvX3NuZCA9ICZzby0+c29fc25kOwoJCQlzdHJ1Y3Qgc2J1ZiAqc29fcmN2ID0gJnNvLT5zb19yY3Y7CgkJCQoJCQkvKiBGaXJzdCBjaGVjayBpZiB0aGV5IGhhdmUgYSBwcml2ZWxhZGdlZCBwb3J0LCBvciB0b28gbXVjaCBkYXRhIGhhcyBhcnJpdmVkICovCgkJCWlmIChudG9ocyhzby0+c29fbHBvcnQpID4gMTAyMyB8fCBudG9ocyhzby0+c29fbHBvcnQpIDwgNTEyIHx8CgkJCSAgICAobS0+bV9sZW4gKyBzb19yY3YtPnNiX3dwdHIpID4gKHNvX3Jjdi0+c2JfZGF0YSArIHNvX3Jjdi0+c2JfZGF0YWxlbikpIHsKCQkJCW1lbWNweShzb19zbmQtPnNiX3dwdHIsICJQZXJtaXNzaW9uIGRlbmllZFxuIiwgMTgpOwoJCQkJc29fc25kLT5zYl93cHRyICs9IDE4OwoJCQkJc29fc25kLT5zYl9jYyArPSAxODsKCQkJCXRjcF9zb2NrY2xvc2VkKHNvdG90Y3BjYihzbykpOwoJCQkJbV9mcmVlKG0pOwoJCQkJcmV0dXJuIDA7CgkJCX0KCQkJCgkJCS8qIEFwcGVuZCB0aGUgY3VycmVudCBkYXRhICovCgkJCW1lbWNweShzb19yY3YtPnNiX3dwdHIsIG0tPm1fZGF0YSwgbS0+bV9sZW4pOwoJCQlzb19yY3YtPnNiX3dwdHIgKz0gbS0+bV9sZW47CgkJCXNvX3Jjdi0+c2JfcnB0ciArPSBtLT5tX2xlbjsKCQkJbV9mcmVlKG0pOwoJCQkKCQkJLyoKCQkJICogQ2hlY2sgaWYgd2UgaGF2ZSBhbGwgdGhlIGluaXRpYWwgb3B0aW9ucywKCQkJICogYW5kIGJ1aWxkIGFyZ3VtZW50IGxpc3QgdG8gcmxvZ2luIHdoaWxlIHdlJ3JlIGhlcmUKCQkJICovCgkJCW4gPSAwOwoJCQlwdHIgPSBzb19yY3YtPnNiX2RhdGE7CgkJCWFyZ3NbMF0gPSAwOwoJCQl0ZXJtWzBdID0gMDsKCQkJd2hpbGUgKHB0ciA8IHNvX3Jjdi0+c2Jfd3B0cikgewoJCQkJaWYgKCpwdHIrKyA9PSAwKSB7CgkJCQkJbisrOwoJCQkJCWlmIChuID09IDIpIHsKCQkJCQkJc3ByaW50ZihhcmdzLCAicmxvZ2luIC1sICVzICVzIiwKCQkJCQkJCXB0ciwgaW5ldF9udG9hKHNvLT5zb19mYWRkcikpOwoJCQkJCX0gZWxzZSBpZiAobiA9PSAzKSB7CgkJCQkJCWkyID0gc29fcmN2LT5zYl93cHRyIC0gcHRyOwoJCQkJCQlmb3IgKGkgPSAwOyBpIDwgaTI7IGkrKykgewoJCQkJCQkJaWYgKHB0cltpXSA9PSAnLycpIHsKCQkJCQkJCQlwdHJbaV0gPSAwOwojaWZkZWYgSEFWRV9TRVRFTlYKCQkJCQkJCQlzcHJpbnRmKHRlcm0sICIlcyIsIHB0cik7CiNlbHNlCgkJCQkJCQkJc3ByaW50Zih0ZXJtLCAiVEVSTT0lcyIsIHB0cik7CiNlbmRpZgoJCQkJCQkJCXB0cltpXSA9ICcvJzsKCQkJCQkJCQlicmVhazsKCQkJCQkJCX0KCQkJCQkJfQoJCQkJCX0KCQkJCX0KCQkJfQoJCQkKCQkJaWYgKG4gIT0gNCkKCQkJICAgcmV0dXJuIDA7CgkJCQoJCQkvKiBXZSBoYXZlIGl0LCBzZXQgb3VyIHRlcm0gdmFyaWFibGUgYW5kIGZvcmtfZXhlYygpICovCiNpZmRlZiBIQVZFX1NFVEVOVgoJCQlzZXRlbnYoIlRFUk0iLCB0ZXJtLCAxKTsKI2Vsc2UKCQkJcHV0ZW52KHRlcm0pOwojZW5kaWYKCQkJZm9ya19leGVjKHNvLCBhcmdzLCAyKTsKCQkJdGVybVswXSA9IDA7CgkJCXNvLT5zb19lbXUgPSAwOwoJCQkKCQkJLyogQW5kIGZpbmFsbHksIHNlbmQgdGhlIGNsaWVudCBhIDAgY2hhcmFjdGVyICovCgkJCXNvX3NuZC0+c2Jfd3B0clswXSA9IDA7CgkJCXNvX3NuZC0+c2Jfd3B0cisrOwoJCQlzb19zbmQtPnNiX2NjKys7CgkJCQoJCQlyZXR1cm4gMDsKCQl9CgkJCgkgY2FzZSBFTVVfUlNIOgoJCS8qCgkJICogcnNoIGVtdWxhdGlvbgoJCSAqIEZpcnN0IHdlIGFjY3VtdWxhdGUgYWxsIHRoZSBpbml0aWFsIG9wdGlvbiBuZWdvdGlhdGlvbiwKCQkgKiB0aGVuIHJzaF9leGVjKCkgcnNoIGFjY29yZGluZyB0byB0aGUgIG9wdGlvbnMKCQkgKi8KCQl7CgkJCWludCAgbjsKCQkJY2hhciAqcHRyOwoJCQljaGFyICp1c2VyOwoJCQljaGFyICphcmdzOwoJCQlzdHJ1Y3Qgc2J1ZiAqc29fc25kID0gJnNvLT5zb19zbmQ7CgkJCXN0cnVjdCBzYnVmICpzb19yY3YgPSAmc28tPnNvX3JjdjsKCQkJCgkJCS8qIEZpcnN0IGNoZWNrIGlmIHRoZXkgaGF2ZSBhIHByaXZlbGFkZ2VkIHBvcnQsIG9yIHRvbyBtdWNoIGRhdGEgaGFzIGFycml2ZWQgKi8KCQkJaWYgKG50b2hzKHNvLT5zb19scG9ydCkgPiAxMDIzIHx8IG50b2hzKHNvLT5zb19scG9ydCkgPCA1MTIgfHwKCQkJICAgIChtLT5tX2xlbiArIHNvX3Jjdi0+c2Jfd3B0cikgPiAoc29fcmN2LT5zYl9kYXRhICsgc29fcmN2LT5zYl9kYXRhbGVuKSkgewoJCQkJbWVtY3B5KHNvX3NuZC0+c2Jfd3B0ciwgIlBlcm1pc3Npb24gZGVuaWVkXG4iLCAxOCk7CgkJCQlzb19zbmQtPnNiX3dwdHIgKz0gMTg7CgkJCQlzb19zbmQtPnNiX2NjICs9IDE4OwoJCQkJdGNwX3NvY2tjbG9zZWQoc290b3RjcGNiKHNvKSk7CgkJCQltX2ZyZWUobSk7CgkJCQlyZXR1cm4gMDsKCQkJfQoJCQkKCQkJLyogQXBwZW5kIHRoZSBjdXJyZW50IGRhdGEgKi8KCQkJbWVtY3B5KHNvX3Jjdi0+c2Jfd3B0ciwgbS0+bV9kYXRhLCBtLT5tX2xlbik7CgkJCXNvX3Jjdi0+c2Jfd3B0ciArPSBtLT5tX2xlbjsKCQkJc29fcmN2LT5zYl9ycHRyICs9IG0tPm1fbGVuOwoJCQltX2ZyZWUobSk7CgkJCQoJCQkvKgoJCQkgKiBDaGVjayBpZiB3ZSBoYXZlIGFsbCB0aGUgaW5pdGlhbCBvcHRpb25zLAoJCQkgKiBhbmQgYnVpbGQgYXJndW1lbnQgbGlzdCB0byBybG9naW4gd2hpbGUgd2UncmUgaGVyZQoJCQkgKi8KCQkJbiA9IDA7CgkJCXB0ciA9IHNvX3Jjdi0+c2JfZGF0YTsKCQkJdXNlcj0iIjsKCQkJYXJncz0iIjsKCQkJaWYgKHNvLT5leHRyYT09TlVMTCkgewoJCQkJc3RydWN0IHNvY2tldCAqbnM7CgkJCQlzdHJ1Y3QgdGNwY2IqIHRwOwoJCQkJaW50IHBvcnQ9YXRvaShwdHIpOwoJCQkJaWYgKHBvcnQgPD0gMCkgcmV0dXJuIDA7CiAgICAgICAgICAgICAgICBpZiAocG9ydCA+IDEwMjMgfHwgcG9ydCA8IDUxMikgewogICAgICAgICAgICAgICAgICBtZW1jcHkoc29fc25kLT5zYl93cHRyLCAiUGVybWlzc2lvbiBkZW5pZWRcbiIsIDE4KTsKICAgICAgICAgICAgICAgICAgc29fc25kLT5zYl93cHRyICs9IDE4OwogICAgICAgICAgICAgICAgICBzb19zbmQtPnNiX2NjICs9IDE4OwogICAgICAgICAgICAgICAgICB0Y3Bfc29ja2Nsb3NlZChzb3RvdGNwY2Ioc28pKTsKICAgICAgICAgICAgICAgICAgcmV0dXJuIDA7CiAgICAgICAgICAgICAgICB9CgkJCQlpZiAoKG5zPXNvY3JlYXRlKCkpID09IE5VTEwpCiAgICAgICAgICAgICAgICAgIHJldHVybiAwOwoJCQkJaWYgKHRjcF9hdHRhY2gobnMpPDApIHsKICAgICAgICAgICAgICAgICAgZnJlZShucyk7CiAgICAgICAgICAgICAgICAgIHJldHVybiAwOwoJCQkJfQoKCQkJCW5zLT5zb19sYWRkcj1zby0+c29fbGFkZHI7CgkJCQlucy0+c29fbHBvcnQ9aHRvbnMocG9ydCk7CgoJCQkJKHZvaWQpIHRjcF9tc3Moc290b3RjcGNiKG5zKSwgMCk7CgoJCQkJbnMtPnNvX2ZhZGRyPXNvLT5zb19mYWRkcjsKCQkJCW5zLT5zb19mcG9ydD1odG9ucyhJUFBPUlRfUkVTRVJWRUQtMSk7IC8qIFVzZSBhIGZha2UgcG9ydC4gKi8KCgkJCQlpZiAobnMtPnNvX2ZhZGRyLnNfYWRkciA9PSAwIHx8IAoJCQkJCW5zLT5zb19mYWRkci5zX2FkZHIgPT0gbG9vcGJhY2tfYWRkci5zX2FkZHIpCiAgICAgICAgICAgICAgICAgIG5zLT5zb19mYWRkciA9IGFsaWFzX2FkZHI7CgoJCQkJbnMtPnNvX2lwdG9zID0gdGNwX3Rvcyhucyk7CgkJCQl0cCA9IHNvdG90Y3BjYihucyk7CiAgICAgICAgICAgICAgICAKCQkJCXRjcF90ZW1wbGF0ZSh0cCk7CiAgICAgICAgICAgICAgICAKCQkJCS8qIENvbXB1dGUgd2luZG93IHNjYWxpbmcgdG8gcmVxdWVzdC4gICovCgkJCQkvKgl3aGlsZSAodHAtPnJlcXVlc3Rfcl9zY2FsZSA8IFRDUF9NQVhfV0lOU0hJRlQgJiYKCQkJCSAqCQkoVENQX01BWFdJTiA8PCB0cC0+cmVxdWVzdF9yX3NjYWxlKSA8IHNvLT5zb19yY3Yuc2JfaGl3YXQpCgkJCQkgKgkJdHAtPnJlcXVlc3Rfcl9zY2FsZSsrOwoJCQkJICovCgogICAgICAgICAgICAgICAgLypzb2lzZmNvbm5lY3RpbmcobnMpOyovCgoJCQkJdGNwc3RhdC50Y3BzX2Nvbm5hdHRlbXB0Kys7CgkJCQkJCgkJCQl0cC0+dF9zdGF0ZSA9IFRDUFNfU1lOX1NFTlQ7CgkJCQl0cC0+dF90aW1lcltUQ1BUX0tFRVBdID0gVENQVFZfS0VFUF9JTklUOwoJCQkJdHAtPmlzcyA9IHRjcF9pc3M7IAoJCQkJdGNwX2lzcyArPSBUQ1BfSVNTSU5DUi8yOwoJCQkJdGNwX3NlbmRzZXFpbml0KHRwKTsKCQkJCXRjcF9vdXRwdXQodHApOwoJCQkJc28tPmV4dHJhPW5zOwoJCQl9CgkJCXdoaWxlIChwdHIgPCBzb19yY3YtPnNiX3dwdHIpIHsKICAgICAgICAgICAgICBpZiAoKnB0cisrID09IDApIHsKICAgICAgICAgICAgICAgIG4rKzsKICAgICAgICAgICAgICAgIGlmIChuID09IDIpIHsKICAgICAgICAgICAgICAgICAgdXNlcj1wdHI7CiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKG4gPT0gMykgewogICAgICAgICAgICAgICAgICBhcmdzPXB0cjsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICB9CgkJCX0KCQkJCgkJCWlmIChuICE9IDQpCiAgICAgICAgICAgICAgcmV0dXJuIDA7CgkJCQoJCQlyc2hfZXhlYyhzbyxzby0+ZXh0cmEsIHVzZXIsIGluZXRfbnRvYShzby0+c29fZmFkZHIpLCBhcmdzKTsKCQkJc28tPnNvX2VtdSA9IDA7CgkJCXNvLT5leHRyYT1OVUxMOwoJCQkKCQkJLyogQW5kIGZpbmFsbHksIHNlbmQgdGhlIGNsaWVudCBhIDAgY2hhcmFjdGVyICovCgkJCXNvX3NuZC0+c2Jfd3B0clswXSA9IDA7CgkJCXNvX3NuZC0+c2Jfd3B0cisrOwoJCQlzb19zbmQtPnNiX2NjKys7CgkJCQoJCQlyZXR1cm4gMDsKCQl9CgoJIGNhc2UgRU1VX0NUTDoKCQl7CgkJCWludCBudW07CgkJCXN0cnVjdCBzYnVmICpzb19zbmQgPSAmc28tPnNvX3NuZDsKCQkJc3RydWN0IHNidWYgKnNvX3JjdiA9ICZzby0+c29fcmN2OwoJCQkKCQkJLyoKCQkJICogSWYgdGhlcmUgaXMgYmluYXJ5IGRhdGEgaGVyZSwgd2Ugc2F2ZSBpdCBpbiBzby0+c29fbQoJCQkgKi8KCQkJaWYgKCFzby0+c29fbSkgewoJCQkgIGludCByeGxlbjsKCQkJICBjaGFyICpyeGRhdGE7CgkJCSAgcnhkYXRhPW10b2QobSwgY2hhciAqKTsKCQkJICBmb3IgKHJ4bGVuPW0tPm1fbGVuOyByeGxlbjsgcnhsZW4tLSkgewoJCQkgICAgaWYgKCpyeGRhdGErKyAmIDB4ODApIHsKCQkJICAgICAgc28tPnNvX20gPSBtOwoJCQkgICAgICByZXR1cm4gMDsKCQkJICAgIH0KCQkJICB9CgkJCX0gLyogaWYoc28tPnNvX209PU5VTEwpICovCgkJCQoJCQkvKgoJCQkgKiBBcHBlbmQgdGhlIGxpbmUKCQkJICovCgkJCXNiYXBwZW5kc2Ioc29fcmN2LCBtKTsKCQkJCgkJCS8qIFRvIGF2b2lkIGdvaW5nIG92ZXIgdGhlIGVkZ2Ugb2YgdGhlIGJ1ZmZlciwgd2UgcmVzZXQgaXQgKi8KCQkJaWYgKHNvX3NuZC0+c2JfY2MgPT0gMCkKCQkJICAgc29fc25kLT5zYl93cHRyID0gc29fc25kLT5zYl9ycHRyID0gc29fc25kLT5zYl9kYXRhOwoJCQkKCQkJLyoKCQkJICogQSBiaXQgb2YgYSBoYWNrOgoJCQkgKiBJZiB0aGUgZmlyc3QgcGFja2V0IHdlIGdldCBoZXJlIGlzIDEgYnl0ZSBsb25nLCB0aGVuIGl0CgkJCSAqIHdhcyBkb25lIGluIHRlbG5ldCBjaGFyYWN0ZXIgbW9kZSwgdGhlcmVmb3JlIHdlIG11c3QgZWNobwoJCQkgKiB0aGUgY2hhcmFjdGVycyBhcyB0aGV5IGNvbWUuICBPdGhlcndpc2UsIHdlIGVjaG8gbm90aGluZywKCQkJICogYmVjYXVzZSBpbiBsaW5lbW9kZSwgdGhlIGxpbmUgaXMgYWxyZWFkeSBlY2hvZWQKCQkJICogWFhYIHR3byBvciBtb3JlIGNvbnRyb2wgY29ubmVjdGlvbnMgd29uJ3Qgd29yawoJCQkgKi8KCQkJaWYgKGRvX2VjaG8gPT0gLTEpIHsKCQkJCWlmIChtLT5tX2xlbiA9PSAxKSBkb19lY2hvID0gMTsKCQkJCWVsc2UgZG9fZWNobyA9IDA7CgkJCX0KCQkJaWYgKGRvX2VjaG8pIHsKCQkJICBzYmFwcGVuZHNiKHNvX3NuZCwgbSk7CgkJCSAgbV9mcmVlKG0pOwoJCQkgIHRjcF9vdXRwdXQoc290b3RjcGNiKHNvKSk7IC8qIFhYWCAqLwoJCQl9IGVsc2UKCQkJICBtX2ZyZWUobSk7CgkJCQoJCQludW0gPSAwOwoJCQl3aGlsZSAobnVtIDwgc28tPnNvX3Jjdi5zYl9jYykgewoJCQkJaWYgKCooc28tPnNvX3Jjdi5zYl9ycHRyICsgbnVtKSA9PSAnXG4nIHx8CgkJCQkgICAgKihzby0+c29fcmN2LnNiX3JwdHIgKyBudW0pID09ICdccicpIHsKCQkJCQlpbnQgbjsKCQkJCQkKCQkJCQkqKHNvX3Jjdi0+c2JfcnB0ciArIG51bSkgPSAwOwoJCQkJCWlmIChjdGxfcGFzc3dvcmQgJiYgIWN0bF9wYXNzd29yZF9vaykgewoJCQkJCQkvKiBOZWVkIGEgcGFzc3dvcmQgKi8KCQkJCQkJaWYgKHNzY2FuZihzb19yY3YtPnNiX3JwdHIsICJwYXNzICUyNTZzIiwgYnVmZikgPT0gMSkgewoJCQkJCQkJaWYgKHN0cmNtcChidWZmLCBjdGxfcGFzc3dvcmQpID09IDApIHsKCQkJCQkJCQljdGxfcGFzc3dvcmRfb2sgPSAxOwoJCQkJCQkJCW4gPSBzcHJpbnRmKHNvX3NuZC0+c2Jfd3B0ciwKCQkJCQkJCQkJICAgICJQYXNzd29yZCBPSy5cclxuIik7CgkJCQkJCQkJZ290byBkb19wcm9tcHQ7CgkJCQkJCQl9CgkJCQkJCX0KCQkJCQkJbiA9IHNwcmludGYoc29fc25kLT5zYl93cHRyLAoJCQkJCSAiRXJyb3I6IFBhc3N3b3JkIHJlcXVpcmVkLCBsb2cgb24gd2l0aCBcInBhc3MgUEFTU1dPUkRcIlxyXG4iKTsKCQkJCQkJZ290byBkb19wcm9tcHQ7CgkJCQkJfQoJCQkJCWNmZ19xdWl0dGluZyA9IDA7CgkJCQkJbiA9IGRvX2NvbmZpZyhzb19yY3YtPnNiX3JwdHIsIHNvLCBQUk5fU1BSSU5URik7CgkJCQkJaWYgKCFjZmdfcXVpdHRpbmcpIHsKCQkJCQkJLyogUmVnaXN0ZXIgdGhlIHByaW50ZWQgZGF0YSAqLwpkb19wcm9tcHQ6CgkJCQkJCXNvX3NuZC0+c2JfY2MgKz0gbjsKCQkJCQkJc29fc25kLT5zYl93cHRyICs9IG47CgkJCQkJCS8qIEFkZCBwcm9tcHQgKi8KCQkJCQkJbiA9IHNwcmludGYoc29fc25kLT5zYl93cHRyLCAiU2xpcnA+ICIpOwoJCQkJCQlzb19zbmQtPnNiX2NjICs9IG47CgkJCQkJCXNvX3NuZC0+c2Jfd3B0ciArPSBuOwoJCQkJCX0KCQkJCQkvKiBEcm9wIHNvX3JjdiBkYXRhICovCgkJCQkJc29fcmN2LT5zYl9jYyA9IDA7CgkJCQkJc29fcmN2LT5zYl93cHRyID0gc29fcmN2LT5zYl9ycHRyID0gc29fcmN2LT5zYl9kYXRhOwoJCQkJCXRjcF9vdXRwdXQoc290b3RjcGNiKHNvKSk7IC8qIFNlbmQgdGhlIHJlcGx5ICovCgkJCQl9CgkJCQludW0rKzsKCQkJfQoJCQlyZXR1cm4gMDsKCQl9CiNlbmRpZgkJCiAgICAgICAgY2FzZSBFTVVfRlRQOiAvKiBmdHAgKi8KCQkqKG0tPm1fZGF0YSttLT5tX2xlbikgPSAwOyAvKiBOVUxMIHRlcm1pbmF0ZSBmb3Igc3Ryc3RyICovCgkJaWYgKChicHRyID0gKGNoYXIgKilzdHJzdHIobS0+bV9kYXRhLCAiT1JUIikpICE9IE5VTEwpIHsKCQkJLyoKCQkJICogTmVlZCB0byBlbXVsYXRlIHRoZSBQT1JUIGNvbW1hbmQKCQkJICovCQkJCgkJCXggPSBzc2NhbmYoYnB0ciwgIk9SVCAlZCwlZCwlZCwlZCwlZCwlZFxyXG4lMjU2W15cMTc3XSIsIAoJCQkJICAgJm4xLCAmbjIsICZuMywgJm40LCAmbjUsICZuNiwgYnVmZik7CgkJCWlmICh4IDwgNikKCQkJICAgcmV0dXJuIDE7CgkJCQoJCQlsYWRkciA9IGh0b25sKChuMSA8PCAyNCkgfCAobjIgPDwgMTYpIHwgKG4zIDw8IDgpIHwgKG40KSk7CgkJCWxwb3J0ID0gaHRvbnMoKG41IDw8IDgpIHwgKG42KSk7CgkJCQoJCQlpZiAoKHNvID0gc29saXN0ZW4oMCwgbGFkZHIsIGxwb3J0LCBTU19GQUNDRVBUT05DRSkpID09IE5VTEwpCgkJCSAgIHJldHVybiAxOwoJCQkKCQkJbjYgPSBudG9ocyhzby0+c29fZnBvcnQpOwoJCQkKCQkJbjUgPSAobjYgPj4gOCkgJiAweGZmOwoJCQluNiAmPSAweGZmOwoJCQkKCQkJbGFkZHIgPSBudG9obChzby0+c29fZmFkZHIuc19hZGRyKTsKCQkJCgkJCW4xID0gKChsYWRkciA+PiAyNCkgJiAweGZmKTsKCQkJbjIgPSAoKGxhZGRyID4+IDE2KSAmIDB4ZmYpOwoJCQluMyA9ICgobGFkZHIgPj4gOCkgICYgMHhmZik7CgkJCW40ID0gIChsYWRkciAmIDB4ZmYpOwoJCQkKCQkJbS0+bV9sZW4gPSBicHRyIC0gbS0+bV9kYXRhOyAvKiBBZGp1c3QgbGVuZ3RoICovCgkJCW0tPm1fbGVuICs9IHNwcmludGYoYnB0ciwiT1JUICVkLCVkLCVkLCVkLCVkLCVkXHJcbiVzIiwgCgkJCQkJICAgIG4xLCBuMiwgbjMsIG40LCBuNSwgbjYsIHg9PTc/YnVmZjoiIik7CgkJCXJldHVybiAxOwoJCX0gZWxzZSBpZiAoKGJwdHIgPSAoY2hhciAqKXN0cnN0cihtLT5tX2RhdGEsICIyNyBFbnRlcmluZyIpKSAhPSBOVUxMKSB7CgkJCS8qCgkJCSAqIE5lZWQgdG8gZW11bGF0ZSB0aGUgUEFTViByZXNwb25zZQoJCQkgKi8KCQkJeCA9IHNzY2FuZihicHRyLCAiMjcgRW50ZXJpbmcgUGFzc2l2ZSBNb2RlICglZCwlZCwlZCwlZCwlZCwlZClcclxuJTI1NlteXDE3N10iLAoJCQkJICAgJm4xLCAmbjIsICZuMywgJm40LCAmbjUsICZuNiwgYnVmZik7CgkJCWlmICh4IDwgNikKCQkJICAgcmV0dXJuIDE7CgkJCQoJCQlsYWRkciA9IGh0b25sKChuMSA8PCAyNCkgfCAobjIgPDwgMTYpIHwgKG4zIDw8IDgpIHwgKG40KSk7CgkJCWxwb3J0ID0gaHRvbnMoKG41IDw8IDgpIHwgKG42KSk7CgkJCQoJCQlpZiAoKHNvID0gc29saXN0ZW4oMCwgbGFkZHIsIGxwb3J0LCBTU19GQUNDRVBUT05DRSkpID09IE5VTEwpCgkJCSAgIHJldHVybiAxOwoJCQkKCQkJbjYgPSBudG9ocyhzby0+c29fZnBvcnQpOwoJCQkKCQkJbjUgPSAobjYgPj4gOCkgJiAweGZmOwoJCQluNiAmPSAweGZmOwoJCQkKCQkJbGFkZHIgPSBudG9obChzby0+c29fZmFkZHIuc19hZGRyKTsKCQkJCgkJCW4xID0gKChsYWRkciA+PiAyNCkgJiAweGZmKTsKCQkJbjIgPSAoKGxhZGRyID4+IDE2KSAmIDB4ZmYpOwoJCQluMyA9ICgobGFkZHIgPj4gOCkgICYgMHhmZik7CgkJCW40ID0gIChsYWRkciAmIDB4ZmYpOwoJCQkKCQkJbS0+bV9sZW4gPSBicHRyIC0gbS0+bV9kYXRhOyAvKiBBZGp1c3QgbGVuZ3RoICovCgkJCW0tPm1fbGVuICs9IHNwcmludGYoYnB0ciwiMjcgRW50ZXJpbmcgUGFzc2l2ZSBNb2RlICglZCwlZCwlZCwlZCwlZCwlZClcclxuJXMiLAoJCQkJCSAgICBuMSwgbjIsIG4zLCBuNCwgbjUsIG42LCB4PT03P2J1ZmY6IiIpOwoJCQkKCQkJcmV0dXJuIDE7CgkJfQoJCQoJCXJldHVybiAxOwoJCQkJICAgCgkgY2FzZSBFTVVfS1NIOgoJCS8qCgkJICogVGhlIGtzaGVsbCAoS2VyYmVyb3MgcnNoKSBhbmQgc2hlbGwgc2VydmljZXMgYm90aCBwYXNzCgkJICogYSBsb2NhbCBwb3J0IHBvcnQgbnVtYmVyIHRvIGNhcnJ5IHNpZ25hbHMgdG8gdGhlIHNlcnZlcgoJCSAqIGFuZCBzdGRlcnIgdG8gdGhlIGNsaWVudC4gIEl0IGlzIHBhc3NlZCBhdCB0aGUgYmVnaW5uaW5nCgkJICogb2YgdGhlIGNvbm5lY3Rpb24gYXMgYSBOVUwtdGVybWluYXRlZCBkZWNpbWFsIEFTQ0lJIHN0cmluZy4KCQkgKi8KCQlzby0+c29fZW11ID0gMDsKCQlmb3IgKGxwb3J0ID0gMCwgaSA9IDA7IGkgPCBtLT5tX2xlbi0xOyArK2kpIHsKCQkJaWYgKG0tPm1fZGF0YVtpXSA8ICcwJyB8fCBtLT5tX2RhdGFbaV0gPiAnOScpCgkJCQlyZXR1cm4gMTsgICAgICAgLyogaW52YWxpZCBudW1iZXIgKi8KCQkJbHBvcnQgKj0gMTA7CgkJCWxwb3J0ICs9IG0tPm1fZGF0YVtpXSAtICcwJzsKCQl9CgkJaWYgKG0tPm1fZGF0YVttLT5tX2xlbi0xXSA9PSAnXDAnICYmIGxwb3J0ICE9IDAgJiYKCQkgICAgKHNvID0gc29saXN0ZW4oMCwgc28tPnNvX2xhZGRyLnNfYWRkciwgaHRvbnMobHBvcnQpLCBTU19GQUNDRVBUT05DRSkpICE9IE5VTEwpCgkJCW0tPm1fbGVuID0gc3ByaW50ZihtLT5tX2RhdGEsICIlZCIsIG50b2hzKHNvLT5zb19mcG9ydCkpKzE7CgkJcmV0dXJuIDE7CgkJCgkgY2FzZSBFTVVfSVJDOgoJCS8qCgkJICogTmVlZCB0byBlbXVsYXRlIERDQyBDSEFULCBEQ0MgU0VORCBhbmQgRENDIE1PVkUKCQkgKi8KCQkqKG0tPm1fZGF0YSttLT5tX2xlbikgPSAwOyAvKiBOVUxMIHRlcm1pbmF0ZSB0aGUgc3RyaW5nIGZvciBzdHJzdHIgKi8KCQlpZiAoKGJwdHIgPSAoY2hhciAqKXN0cnN0cihtLT5tX2RhdGEsICJEQ0MiKSkgPT0gTlVMTCkKCQkJIHJldHVybiAxOwoJCQoJCS8qIFRoZSAlMjU2cyBpcyBmb3IgdGhlIGJyb2tlbiBtSVJDICovCgkJaWYgKHNzY2FuZihicHRyLCAiRENDIENIQVQgJTI1NnMgJXUgJXUiLCBidWZmLCAmbGFkZHIsICZscG9ydCkgPT0gMykgewoJCQlpZiAoKHNvID0gc29saXN0ZW4oMCwgaHRvbmwobGFkZHIpLCBodG9ucyhscG9ydCksIFNTX0ZBQ0NFUFRPTkNFKSkgPT0gTlVMTCkKCQkJCXJldHVybiAxOwoJCQkKCQkJbS0+bV9sZW4gPSBicHRyIC0gbS0+bV9kYXRhOyAvKiBBZGp1c3QgbGVuZ3RoICovCgkJCW0tPm1fbGVuICs9IHNwcmludGYoYnB0ciwgIkRDQyBDSEFUIGNoYXQgJWx1ICV1JWNcbiIsCgkJCSAgICAgKHVuc2lnbmVkIGxvbmcpbnRvaGwoc28tPnNvX2ZhZGRyLnNfYWRkciksCgkJCSAgICAgbnRvaHMoc28tPnNvX2Zwb3J0KSwgMSk7CgkJfSBlbHNlIGlmIChzc2NhbmYoYnB0ciwgIkRDQyBTRU5EICUyNTZzICV1ICV1ICV1IiwgYnVmZiwgJmxhZGRyLCAmbHBvcnQsICZuMSkgPT0gNCkgewoJCQlpZiAoKHNvID0gc29saXN0ZW4oMCwgaHRvbmwobGFkZHIpLCBodG9ucyhscG9ydCksIFNTX0ZBQ0NFUFRPTkNFKSkgPT0gTlVMTCkKCQkJCXJldHVybiAxOwoJCQkKCQkJbS0+bV9sZW4gPSBicHRyIC0gbS0+bV9kYXRhOyAvKiBBZGp1c3QgbGVuZ3RoICovCgkJCW0tPm1fbGVuICs9IHNwcmludGYoYnB0ciwgIkRDQyBTRU5EICVzICVsdSAldSAldSVjXG4iLCAKCQkJICAgICAgYnVmZiwgKHVuc2lnbmVkIGxvbmcpbnRvaGwoc28tPnNvX2ZhZGRyLnNfYWRkciksCgkJCSAgICAgIG50b2hzKHNvLT5zb19mcG9ydCksIG4xLCAxKTsKCQl9IGVsc2UgaWYgKHNzY2FuZihicHRyLCAiRENDIE1PVkUgJTI1NnMgJXUgJXUgJXUiLCBidWZmLCAmbGFkZHIsICZscG9ydCwgJm4xKSA9PSA0KSB7CgkJCWlmICgoc28gPSBzb2xpc3RlbigwLCBodG9ubChsYWRkciksIGh0b25zKGxwb3J0KSwgU1NfRkFDQ0VQVE9OQ0UpKSA9PSBOVUxMKQoJCQkJcmV0dXJuIDE7CgkJCQoJCQltLT5tX2xlbiA9IGJwdHIgLSBtLT5tX2RhdGE7IC8qIEFkanVzdCBsZW5ndGggKi8KCQkJbS0+bV9sZW4gKz0gc3ByaW50ZihicHRyLCAiRENDIE1PVkUgJXMgJWx1ICV1ICV1JWNcbiIsCgkJCSAgICAgIGJ1ZmYsICh1bnNpZ25lZCBsb25nKW50b2hsKHNvLT5zb19mYWRkci5zX2FkZHIpLAoJCQkgICAgICBudG9ocyhzby0+c29fZnBvcnQpLCBuMSwgMSk7CgkJfQoJCXJldHVybiAxOwoKCSBjYXNlIEVNVV9SRUFMQVVESU86CiAgICAgICAgICAgICAgICAvKiAKCQkgKiBSZWFsQXVkaW8gZW11bGF0aW9uIC0gSlAuIFdlIG11c3QgdHJ5IHRvIHBhcnNlIHRoZSBpbmNvbWluZwoJCSAqIGRhdGEgYW5kIHRyeSB0byBmaW5kIHRoZSB0d28gY2hhcmFjdGVycyB0aGF0IGNvbnRhaW4gdGhlCgkJICogcG9ydCBudW1iZXIuIFRoZW4gd2UgcmVkaXJlY3QgYW4gdWRwIHBvcnQgYW5kIHJlcGxhY2UgdGhlCgkJICogbnVtYmVyIHdpdGggdGhlIHJlYWwgcG9ydCB3ZSBnb3QuCgkJICoKCQkgKiBUaGUgMS4wIGJldGEgdmVyc2lvbnMgb2YgdGhlIHBsYXllciBhcmUgbm90IHN1cHBvcnRlZAoJCSAqIGFueSBtb3JlLgoJCSAqIAoJCSAqIEEgdHlwaWNhbCBwYWNrZXQgZm9yIHBsYXllciB2ZXJzaW9uIDEuMCAocmVsZWFzZSB2ZXJzaW9uKToKCQkgKiAgICAgICAgCgkJICogMDAwMDo1MCA0RSA0MSAwMCAwNSAKCQkgKiAwMDAwOjAwIDAxIDAwIDAyIDFCIEQ3IDAwIDAwIDY3IEU2IDZDIERDIDYzIDAwIDEyIDUwIC4uLi4u1y4uZ+Zs3GMuLlAKCQkgKiAwMDEwOjRFIDQzIDRDIDQ5IDQ1IDRFIDU0IDIwIDMxIDMwIDMxIDIwIDQxIDRDIDUwIDQ4IE5DTElFTlQgMTAxIEFMUEgKCQkgKiAwMDIwOjQxIDZDIDAwIDAwIDUyIDAwIDE3IDcyIDYxIDY2IDY5IDZDIDY1IDczIDJGIDc2IEFsLi5SLi5yYWZpbGVzL3YKCQkgKiAwMDMwOjZGIDYxIDJGIDY1IDZFIDY3IDZDIDY5IDczIDY4IDVGIDJFIDcyIDYxIDc5IDQyIG9hL2VuZ2xpc2hfLnJheUIKCQkgKiAgICAgICAgIAoJCSAqIE5vdyB0aGUgcG9ydCBudW1iZXIgMHgxQkQ3IGlzIGZvdW5kIGF0IG9mZnNldCAweDA0IG9mIHRoZQoJCSAqIE5vdyB0aGUgcG9ydCBudW1iZXIgMHgxQkQ3IGlzIGZvdW5kIGF0IG9mZnNldCAweDA0IG9mIHRoZQoJCSAqIHNlY29uZCBwYWNrZXQuIFRoaXMgdGltZSB3ZSByZWNlaXZlZCBmaXZlIGJ5dGVzIGZpcnN0IGFuZAoJCSAqIHRoZW4gdGhlIHJlc3QuIFlvdSBuZXZlciBrbm93IGhvdyBtYW55IGJ5dGVzIHlvdSBnZXQuCgkJICoKCQkgKiBBIHR5cGljYWwgcGFja2V0IGZvciBwbGF5ZXIgdmVyc2lvbiAyLjAgKGJldGEpOgoJCSAqICAgICAgICAKCQkgKiAwMDAwOjUwIDRFIDQxIDAwIDA2IDAwIDAyIDAwIDAwIDAwIDAxIDAwIDAyIDFCIEMxIDAwIFBOQS4uLi4uLi4uLi4uwS4KCQkgKiAwMDEwOjAwIDY3IDc1IDc4IEY1IDYzIDAwIDBBIDU3IDY5IDZFIDMyIDJFIDMwIDJFIDMwIC5ndXj1Yy4uV2luMi4wLjAKCQkgKiAwMDIwOjJFIDM1IDZDIDAwIDAwIDUyIDAwIDFDIDcyIDYxIDY2IDY5IDZDIDY1IDczIDJGIC41bC4uUi4ucmFmaWxlcy8KCQkgKiAwMDMwOjc3IDY1IDYyIDczIDY5IDc0IDY1IDJGIDMyIDMwIDcyIDY1IDZDIDY1IDYxIDczIHdlYnNpdGUvMjByZWxlYXMKCQkgKiAwMDQwOjY1IDJFIDcyIDYxIDc5IDUzIDAwIDAwIDA2IDM2IDQyICAgICAgICAgICAgICAgIGUucmF5Uy4uLjZCCgkJICogICAgICAgIAoJCSAqIFBvcnQgbnVtYmVyIDB4MUJDMSBpcyBmb3VuZCBhdCBvZmZzZXQgMHgwZC4KCQkgKiAgICAgIAoJCSAqIFRoaXMgaXMganVzdCBhIGhvcnJpYmxlIHN3aXRjaCBzdGF0ZW1lbnQuIFZhcmlhYmxlIHJhIHRlbGxzCgkJICogdXMgd2hlcmUgd2UncmUgZ29pbmcuCgkJICovCgkJCgkJYnB0ciA9IG0tPm1fZGF0YTsKCQl3aGlsZSAoYnB0ciA8IG0tPm1fZGF0YSArIG0tPm1fbGVuKSB7CgkJCXVfc2hvcnQgcDsKCQkJc3RhdGljIGludCByYSA9IDA7CgkJCWNoYXIgcmFfdGJsWzRdOyAKCQkJCgkJCXJhX3RibFswXSA9IDB4NTA7CgkJCXJhX3RibFsxXSA9IDB4NGU7CgkJCXJhX3RibFsyXSA9IDB4NDE7CgkJCXJhX3RibFszXSA9IDA7CgkJCQoJCQlzd2l0Y2ggKHJhKSB7CgkJCSBjYXNlIDA6CgkJCSBjYXNlIDI6CgkJCSBjYXNlIDM6CgkJCQlpZiAoKmJwdHIrKyAhPSByYV90YmxbcmFdKSB7CgkJCQkJcmEgPSAwOwoJCQkJCWNvbnRpbnVlOwoJCQkJfQoJCQkJYnJlYWs7CgkJCQkKCQkJIGNhc2UgMToKCQkJCS8qCgkJCQkgKiBXZSBtYXkgZ2V0IDB4NTAgc2V2ZXJhbCB0aW1lcywgaWdub3JlIHRoZW0KCQkJCSAqLwoJCQkJaWYgKCpicHRyID09IDB4NTApIHsKCQkJCQlyYSA9IDE7CgkJCQkJYnB0cisrOwoJCQkJCWNvbnRpbnVlOwoJCQkJfSBlbHNlIGlmICgqYnB0cisrICE9IHJhX3RibFtyYV0pIHsKCQkJCQlyYSA9IDA7CgkJCQkJY29udGludWU7CgkJCQl9CgkJCQlicmVhazsKCQkJCQoJCQkgY2FzZSA0OiAKCQkJCS8qIAoJCQkJICogc2tpcCB2ZXJzaW9uIG51bWJlcgoJCQkJICovCgkJCQlicHRyKys7CgkJCQlicmVhazsKCQkJCQoJCQkgY2FzZSA1OiAKCQkJCS8qCgkJCQkgKiBUaGUgZGlmZmVyZW5jZSBiZXR3ZWVuIHZlcnNpb25zIDEuMCBhbmQKCQkJCSAqIDIuMCBpcyBoZXJlLiBGb3IgZnV0dXJlIHZlcnNpb25zIG9mCgkJCQkgKiB0aGUgcGxheWVyIHRoaXMgbWF5IG5lZWQgdG8gYmUgbW9kaWZpZWQuCgkJCQkgKi8KCQkJCWlmICgqKGJwdHIgKyAxKSA9PSAweDAyKQoJCQkJICAgYnB0ciArPSA4OwoJCQkJZWxzZQoJCQkJICAgYnB0ciArPSA0OwoJCQkJYnJlYWs7ICAgICAgICAgICAgICAgICAgICAgICAgICAKCQkJCQoJCQkgY2FzZSA2OgoJCQkJLyogVGhpcyBpcyB0aGUgZmllbGQgY29udGFpbmluZyB0aGUgcG9ydAoJCQkJICogbnVtYmVyIHRoYXQgUkEtcGxheWVyIGlzIGxpc3RlbmluZyB0by4KCQkJCSAqLwoJCQkJbHBvcnQgPSAoKCh1X2NoYXIqKWJwdHIpWzBdIDw8IDgpIAoJCQkJKyAoKHVfY2hhciAqKWJwdHIpWzFdOwoJCQkJaWYgKGxwb3J0IDwgNjk3MCkgICAgICAKCQkJCSAgIGxwb3J0ICs9IDI1NjsgICAvKiBkb24ndCBrbm93IHdoeSAqLwoJCQkJaWYgKGxwb3J0IDwgNjk3MCB8fCBscG9ydCA+IDcxNzApCgkJCQkgICByZXR1cm4gMTsgICAgICAgLyogZmFpbGVkICovCgkJCQkKCQkJCS8qIHRyeSB0byBnZXQgdWRwIHBvcnQgYmV0d2VlbiA2OTcwIC0gNzE3MCAqLwoJCQkJZm9yIChwID0gNjk3MDsgcCA8IDcwNzE7IHArKykgewoJCQkJCWlmICh1ZHBfbGlzdGVuKCBodG9ucyhwKSwKCQkJCQkJICAgICAgIHNvLT5zb19sYWRkci5zX2FkZHIsCgkJCQkJCSAgICAgICBodG9ucyhscG9ydCksCgkJCQkJCSAgICAgICBTU19GQUNDRVBUT05DRSkpIHsKCQkJCQkJYnJlYWs7CgkJCQkJfQoJCQkJfQoJCQkJaWYgKHAgPT0gNzA3MSkKCQkJCSAgIHAgPSAwOwoJCQkJKih1X2NoYXIgKilicHRyKysgPSAocCA+PiA4KSAmIDB4ZmY7CgkJCQkqKHVfY2hhciAqKWJwdHIrKyA9IHAgJiAweGZmOwoJCQkJcmEgPSAwOyAKCQkJCXJldHVybiAxOyAgIC8qIHBvcnQgcmVkaXJlY3RlZCwgd2UncmUgZG9uZSAqLwoJCQkJYnJlYWs7ICAKCQkJCQoJCQkgZGVmYXVsdDoKCQkJCXJhID0gMDsgICAgICAgICAgICAgICAgICAgICAgICAgCgkJCX0KCQkJcmErKzsKCQl9CgkJcmV0dXJuIDE7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKCQkKCSBkZWZhdWx0OgoJCS8qIE9vb3BzLCBub3QgZW11bGF0ZWQsIHdvbid0IGNhbGwgdGNwX2VtdSBhZ2FpbiAqLwoJCXNvLT5zb19lbXUgPSAwOwoJCXJldHVybiAxOwoJfQp9CgovKgogKiBEbyBtaXNjLiBjb25maWcgb2YgU0xpUlAgd2hpbGUgaXRzIHJ1bm5pbmcuCiAqIFJldHVybiAwIGlmIHRoaXMgY29ubmVjdGlvbnMgaXMgdG8gYmUgY2xvc2VkLCAxIG90aGVyd2lzZSwKICogcmV0dXJuIDIgaWYgdGhpcyBpcyBhIGNvbW1hbmQtbGluZSBjb25uZWN0aW9uCiAqLwppbnQKdGNwX2N0bChzbykKCXN0cnVjdCBzb2NrZXQgKnNvOwp7CglzdHJ1Y3Qgc2J1ZiAqc2IgPSAmc28tPnNvX3NuZDsKCWludCBjb21tYW5kOwogCXN0cnVjdCBleF9saXN0ICpleF9wdHI7CglpbnQgZG9fcHR5OwogICAgICAgIC8vCXN0cnVjdCBzb2NrZXQgKnRtcHNvOwoJCglERUJVR19DQUxMKCJ0Y3BfY3RsIik7CglERUJVR19BUkcoInNvID0gJWx4IiwgKGxvbmcgKXNvKTsKCQojaWYgMAoJLyoKCSAqIENoZWNrIGlmIHRoZXkncmUgYXV0aG9yaXNlZAoJICovCglpZiAoY3RsX2FkZHIuc19hZGRyICYmIChjdGxfYWRkci5zX2FkZHIgPT0gLTEgfHwgKHNvLT5zb19sYWRkci5zX2FkZHIgIT0gY3RsX2FkZHIuc19hZGRyKSkpIHsKCQlzYi0+c2JfY2MgPSBzcHJpbnRmKHNiLT5zYl93cHRyLCJFcnJvcjogUGVybWlzc2lvbiBkZW5pZWQuXHJcbiIpOwoJCXNiLT5zYl93cHRyICs9IHNiLT5zYl9jYzsKCQlyZXR1cm4gMDsKCX0KI2VuZGlmCQoJY29tbWFuZCA9IChudG9obChzby0+c29fZmFkZHIuc19hZGRyKSAmIDB4ZmYpOwoJCglzd2l0Y2goY29tbWFuZCkgewoJZGVmYXVsdDogLyogQ2hlY2sgZm9yIGV4ZWMncyAqLwoJCQoJCS8qCgkJICogQ2hlY2sgaWYgaXQncyBwdHlfZXhlYwoJCSAqLwoJCWZvciAoZXhfcHRyID0gZXhlY19saXN0OyBleF9wdHI7IGV4X3B0ciA9IGV4X3B0ci0+ZXhfbmV4dCkgewoJCQlpZiAoZXhfcHRyLT5leF9mcG9ydCA9PSBzby0+c29fZnBvcnQgJiYKCQkJICAgIGNvbW1hbmQgPT0gZXhfcHRyLT5leF9hZGRyKSB7CgkJCQlkb19wdHkgPSBleF9wdHItPmV4X3B0eTsKCQkJCWdvdG8gZG9fZXhlYzsKCQkJfQoJCX0KCQkKCQkvKgoJCSAqIE5vdGhpbmcgYm91bmQuLgoJCSAqLwoJCS8qIHRjcF9mY29ubmVjdChzbyk7ICovCgkJCgkJLyogRkFMTFRIUk9VR0ggKi8KCWNhc2UgQ1RMX0FMSUFTOgoJICBzYi0+c2JfY2MgPSBzcHJpbnRmKHNiLT5zYl93cHRyLAoJCQkgICAgICAiRXJyb3I6IE5vIGFwcGxpY2F0aW9uIGNvbmZpZ3VyZWQuXHJcbiIpOwoJICBzYi0+c2Jfd3B0ciArPSBzYi0+c2JfY2M7CgkgIHJldHVybigwKTsKCglkb19leGVjOgoJCURFQlVHX01JU0MoKGRmZCwgIiBleGVjdXRpbmcgJXMgXG4iLGV4X3B0ci0+ZXhfZXhlYykpOwoJCXJldHVybihmb3JrX2V4ZWMoc28sIGV4X3B0ci0+ZXhfZXhlYywgZG9fcHR5KSk7CgkJCiNpZiAwCgljYXNlIENUTF9DTUQ6CgkgICBmb3IgKHRtcHNvID0gdGNiLnNvX25leHQ7IHRtcHNvICE9ICZ0Y2I7IHRtcHNvID0gdG1wc28tPnNvX25leHQpIHsKCSAgICAgaWYgKHRtcHNvLT5zb19lbXUgPT0gRU1VX0NUTCAmJiAKCQkgISh0bXBzby0+c29fdGNwY2I/IAoJCSAgICh0bXBzby0+c29fdGNwY2ItPnRfc3RhdGUgJiAoVENQU19USU1FX1dBSVR8VENQU19MQVNUX0FDSykpCgkJICAgOjApKSB7CgkgICAgICAgLyogT29vcHMsIGNvbnRyb2wgY29ubmVjdGlvbiBhbHJlYWR5IGFjdGl2ZSAqLwoJICAgICAgIHNiLT5zYl9jYyA9IHNwcmludGYoc2ItPnNiX3dwdHIsIlNvcnJ5LCBhbHJlYWR5IGNvbm5lY3RlZC5cclxuIik7CgkgICAgICAgc2ItPnNiX3dwdHIgKz0gc2ItPnNiX2NjOwoJICAgICAgIHJldHVybiAwOwoJICAgICB9CgkgICB9CgkgICBzby0+c29fZW11ID0gRU1VX0NUTDsKCSAgIGN0bF9wYXNzd29yZF9vayA9IDA7CgkgICBzYi0+c2JfY2MgPSBzcHJpbnRmKHNiLT5zYl93cHRyLCAiU2xpcnAgY29tbWFuZC1saW5lIHJlYWR5ICh0eXBlIFwiaGVscFwiIGZvciBoZWxwKS5cclxuU2xpcnA+ICIpOwoJICAgc2ItPnNiX3dwdHIgKz0gc2ItPnNiX2NjOwoJICAgZG9fZWNobz0tMTsKCSAgIHJldHVybigyKTsKI2VuZGlmCgl9Cn0K