LyogZ2VyZGVzX2FtZDc5MzAuYyx2IDAuOTkgMjAwMS8xMC8wMgogKgogKiBnZXJkZXNfYW1kNzkzMC5jICAgICBBbWQgNzlDMzBBIGFuZCA3OUMzMkEgc3BlY2lmaWMgcm91dGluZXMKICogICAgICAgICAgICAgICAgICAgICAgKGJhc2VkIG9uIEhpU2F4IGRyaXZlciBieSBLYXJzdGVuIEtlaWwpCiAqCiAqIEF1dGhvciAgICAgICAgICAgICAgIENocmlzdG9waCBFcnNmZWxkIDxpbmZvQGZvcm11bGEtbi5kZT4KICogICAgICAgICAgICAgICAgICAgICAgRm9ybXVsYS1uIEV1cm9wZSBBRyAod3d3LmZvcm11bGEtbi5jb20pCiAqICAgICAgICAgICAgICAgICAgICAgIHByZXZpb3VzbHkgR2VyZGVzIEFHCiAqCiAqCiAqICAgICAgICAgICAgICAgICAgICAgIFRoaXMgZmlsZSBpcyAoYykgdW5kZXIgR05VIFBVQkxJQyBMSUNFTlNFCiAqCiAqCiAqIE5vdGVzOgogKiBWZXJzaW9uIDAuOTkgaXMgdGhlIGZpcnN0IHJlbGVhc2Ugb2YgdGhpcyBkcml2ZXIgYW5kIHRoZXJlIGFyZQogKiBjZXJ0YWlubHkgYSBmZXcgYnVncy4KICoKICogUGxlYXNlIGRvbid0IHJlcG9ydCBhbnkgbWFsZnVuY3Rpb24gdG8gbWUgd2l0aG91dCBzZW5kaW5nCiAqIChjb21wcmVzc2VkKSBkZWJ1Zy1sb2dzLgogKiBJdCB3b3VsZCBiZSBuZWFybHkgaW1wb3NzaWJsZSB0byByZXRyYWNlIGl0LgogKgogKiBMb2cgRC1jaGFubmVsLXByb2Nlc3NpbmcgYXMgZm9sbG93czoKICoKICogMS4gTG9hZCBoaXNheCB3aXRoIGNhcmQtc3BlY2lmaWMgcGFyYW1ldGVycywgdGhpcyBleGFtcGxlIGlzdCBmb3IKICogICAgRm9ybXVsYS1uIGVudGVyOm5vdyBJU0ROIFBDSSBhbmQgY29tcGF0aWJsZQogKiAgICAoZi5lLiBHZXJkZXMgUG93ZXIgSVNETiBQQ0kpCiAqCiAqICAgIG1vZHByb2JlIGhpc2F4IHR5cGU9NDEgcHJvdG9jb2w9MiBpZD1nZXJkZXMKICoKICogICAgaWYgeW91IGNob3NlIGFuIG90aGVyIHZhbHVlIGZvciBpZCwgeW91IG5lZWQgdG8gbW9kaWZ5IHRoZQogKiAgICBjb2RlIGJlbG93LCB0b28uCiAqCiAqIDIuIHNldCBkZWJ1Zy1sZXZlbAogKgogKiAgICBoaXNheGN0cmwgZ2VyZGVzIDEgMHgzZmYKICogICAgaGlzYXhjdHJsIGdlcmRlcyAxMSAweDRmCiAqICAgIGNhdCAvZGV2L2lzZG5jdHJsID4+IH4vbG9nICYKICoKICogUGxlYXNlIHRha2UgYWxzbyBhIGxvb2sgaW50byAvdmFyL2xvZy9tZXNzYWdlcyBpZiB0aGVyZSBpcwogKiBhbnl0aGluZyBpbXBvcnRhbmQgY29uY2VybmluZyBISVNBWC4KICoKICoKICogQ3JlZGl0czoKICogUHJvZ3JhbW1pbmcgdGhlIGRyaXZlciBmb3IgRm9ybXVsYS1uIGVudGVyOm5vdyBJU0ROIFBDSSBhbmQKICogbmVjZXNzYXJ5IHRoaXMgZHJpdmVyIGZvciB0aGUgdXNlZCBBbWQgNzkzMCBELWNoYW5uZWwtY29udHJvbGxlcgogKiB3YXMgc3Buc29yZWQgYnkgRm9ybXVsYS1uIEV1cm9wZSBBRy4KICogVGhhbmtzIHRvIEthcnN0ZW4gS2VpbCBhbmQgUGV0ciBOb3Zhaywgd2hvIGdhdmUgbWUgc3VwcG9ydCBpbgogKiBIaXNheC1zcGVjaWZpYyBxdWVzdGlvbnMuCiAqIEkgd2FudCBzbyBzYXkgc3BlY2lhbCB0aGFua3MgdG8gQ2FybC1GcmllZHJpY2ggQnJhdW4sIHdobyBoYWQgdG8KICogYW5zd2VyIGEgbG90IG9mIHF1ZXN0aW9ucyBhYm91dCBnZW5lcmFsbHkgSVNETiBhbmQgYWJvdXQgaGFuZGxpbmcKICogb2YgdGhlIEFtZC1DaGlwLgogKgogKi8KCgojaW5jbHVkZSAiaGlzYXguaCIKI2luY2x1ZGUgImlzZG5sMS5oIgojaW5jbHVkZSAiaXNhYy5oIgojaW5jbHVkZSAiYW1kNzkzMF9mbi5oIgojaW5jbHVkZSA8bGludXgvaW50ZXJydXB0Lmg+CiNpbmNsdWRlIDxsaW51eC9pbml0Lmg+CgpzdGF0aWMgdm9pZCBBbWQ3OTMwX25ld19waChzdHJ1Y3QgSXNkbkNhcmRTdGF0ZSAqY3MpOwoKc3RhdGljIFdPUkQgaW5pdEFNRFtdID0gewoJMHgwMTAwLAoKCTB4MDBBNSwgMywgMHgwMSwgMHg0MCwgMHg1OCwJCQkJLy8gTFBSLCBMTVIxLCBMTVIyCgkweDAwODYsIDEsIDB4MEIsCQkJCQkvLyBETVIxIChELUJ1ZmZlciBUSC1JbnRlcnJ1cHRzIG9uKQoJMHgwMDg3LCAxLCAweEZGLAkJCQkJLy8gRE1SMgoJMHgwMDkyLCAxLCAweDAzLAkJCQkJLy8gRUZDUiAoZXh0ZW5kZWQgbW9kZSBkLWNoYW5uZWwtZmlmbyBvbikKCTB4MDA5MCwgNCwgMHhGRSwgMHhGRiwgMHgwMiwgMHgwRiwJCQkvLyBGUkFSNCwgU1JBUjQsIERNUjMsIERNUjQgKGFkZHJlc3MgcmVjb2duaXRpb24gKQoJMHgwMDg0LCAyLCAweDgwLCAweDAwLAkJCQkJLy8gRFJMUgoJMHgwMEMwLCAxLCAweDQ3LAkJCQkJLy8gUFBDUjEKCTB4MDBDOCwgMSwgMHgwMSwJCQkJCS8vIFBQQ1IyCgoJMHgwMTAyLAoJMHgwMTA3LAoJMHgwMUExLCAxLAoJMHgwMTIxLCAxLAoJMHgwMTg5LCAyLAoKCTB4MDA0NSwgNCwgMHg2MSwgMHg3MiwgMHgwMCwgMHgwMCwJCQkvLyBNQ1IxLCBNQ1IyLCBNQ1IzLCBNQ1I0CgkweDAwNjMsIDIsIDB4MDgsIDB4MDgsCQkJCQkvLyBHWAoJMHgwMDY0LCAyLCAweDA4LCAweDA4LAkJCQkJLy8gR1IKCTB4MDA2NSwgMiwgMHg5OSwgMHgwMCwJCQkJCS8vIEdFUgoJMHgwMDY2LCAyLCAweDdDLCAweDhCLAkJCQkJLy8gU1RHCgkweDAwNjcsIDIsIDB4MDAsIDB4MDAsCQkJCQkvLyBGVEdSMSwgRlRHUjIKCTB4MDA2OCwgMiwgMHgyMCwgMHgyMCwJCQkJCS8vIEFUR1IxLCBBVEdSMgoJMHgwMDY5LCAxLCAweDRGLAkJCQkJLy8gTU1SMQoJMHgwMDZBLCAxLCAweDAwLAkJCQkJLy8gTU1SMgoJMHgwMDZDLCAxLCAweDQwLAkJCQkJLy8gTU1SMwoJMHgwMDIxLCAxLCAweDAyLAkJCQkJLy8gSU5JVAoJMHgwMEEzLCAxLCAweDQwLAkJCQkJLy8gTE1SMQoKCTB4RkZGRgp9OwoKCnZvaWQgLyogbWFjcm8gd1dvcmRBTUQgKi8KV3JpdGVXb3JkQW1kNzkzMChzdHJ1Y3QgSXNkbkNhcmRTdGF0ZSAqY3MsIEJZVEUgcmVnLCBXT1JEIHZhbCkKewogICAgICAgIHdCeXRlQU1EKGNzLCAweDAwLCByZWcpOwogICAgICAgIHdCeXRlQU1EKGNzLCAweDAxLCBMT0JZVEUodmFsKSk7CiAgICAgICAgd0J5dGVBTUQoY3MsIDB4MDEsIEhJQllURSh2YWwpKTsKfQoKV09SRCAvKiBtYWNybyByV29yZEFNRCAqLwpSZWFkV29yZEFtZDc5MzAoc3RydWN0IElzZG5DYXJkU3RhdGUgKmNzLCBCWVRFIHJlZykKewogICAgICAgIFdPUkQgcmVzOwogICAgICAgIC8qIGRpcmVjdCBhY2Nlc3MgcmVnaXN0ZXIgKi8KICAgICAgICBpZihyZWcgPCA4KSB7CiAgICAgICAgCXJlcyA9IHJCeXRlQU1EKGNzLCByZWcpOwogICAgICAgICAgICAgICAgcmVzICs9IDI1NipyQnl0ZUFNRChjcywgcmVnKTsKICAgICAgICB9CiAgICAgICAgLyogaW5kaXJlY3QgYWNjZXNzIHJlZ2lzdGVyICovCiAgICAgICAgZWxzZSB7CiAgICAgICAgICAgICAgICB3Qnl0ZUFNRChjcywgMHgwMCwgcmVnKTsKCSAgICAgICAgcmVzID0gckJ5dGVBTUQoY3MsIDB4MDEpOwogICAgICAgICAgICAgICAgcmVzICs9IDI1NipyQnl0ZUFNRChjcywgMHgwMSk7CiAgICAgICAgfQoJcmV0dXJuIChyZXMpOwp9CgoKc3RhdGljIHZvaWQKQW1kNzkzMF9waF9jb21tYW5kKHN0cnVjdCBJc2RuQ2FyZFN0YXRlICpjcywgdV9jaGFyIGNvbW1hbmQsIGNoYXIgKnMpCnsKCWlmIChjcy0+ZGVidWcgJiBMMV9ERUJfSVNBQykKCQlkZWJ1Z2wxKGNzLCAiQU1ENzkzMDogJXM6IHBoX2NvbW1hbmQgMHglMDJYIiwgcywgY29tbWFuZCk7CgogICAgICAgIGNzLT5kYy5hbWQ3OTMwLmxtcjEgPSBjb21tYW5kOwogICAgICAgIHdCeXRlQU1EKGNzLCAweEEzLCBjb21tYW5kKTsKfQoKCgpzdGF0aWMgQllURSBpNDMwU3RhdGVzW10gPSB7Ci8vIHRvICAgcmVzZXQgIEYzICAgIEY0ICAgIEY1ICAgIEY2ICAgIEY3ICAgIEY4ICAgIEFSICAgICBmcm9tCiAgICAgICAgMHgwMSwgMHgwMiwgMHgwMCwgMHgwMCwgMHgwMCwgMHgwNywgMHgwNSwgMHgwMCwgICAvLyBpbml0CiAgICAgICAgMHgwMSwgMHgwMiwgMHgwMCwgMHgwMCwgMHgwMCwgMHgwNywgMHgwNSwgMHgwMCwgICAvLyByZXNldAogICAgICAgIDB4MDEsIDB4MDIsIDB4MDAsIDB4MDAsIDB4MDAsIDB4MDksIDB4MDUsIDB4MDQsICAgLy8gRjMKICAgICAgICAweDAxLCAweDAyLCAweDAwLCAweDAwLCAweDFCLCAweDAwLCAweDAwLCAweDAwLCAgIC8vIEY0CiAgICAgICAgMHgwMSwgMHgwMiwgMHgwMCwgMHgwMCwgMHgxQiwgMHgwMCwgMHgwMCwgMHgwMCwgICAvLyBGNQogICAgICAgIDB4MDEsIDB4MDMsIDB4MDAsIDB4MDAsIDB4MDAsIDB4MDYsIDB4MDUsIDB4MDAsICAgLy8gRjYKICAgICAgICAweDExLCAweDEzLCAweDAwLCAweDAwLCAweDFCLCAweDAwLCAweDE1LCAweDAwLCAgIC8vIEY3CiAgICAgICAgMHgwMSwgMHgwMywgMHgwMCwgMHgwMCwgMHgwMCwgMHgwNiwgMHgwMCwgMHgwMCwgICAvLyBGOAogICAgICAgIDB4MDEsIDB4MDMsIDB4MDAsIDB4MDAsIDB4MDAsIDB4MDksIDB4MDAsIDB4MEF9OyAgLy8gQVIKCgovKiAgICAgICAgICAgICAgICAgICAgUm93ICAgICBpbml0ICAgIC0gICByZXNldCAgRjMgICAgRjQgICAgRjUgICAgRjYgICAgRjcgICAgRjggICAgQVIgKi8Kc3RhdGljIEJZVEUgc3RhdGVIZWxwZXJbXSA9IHsgMHgwMCwgMHgwMCwgMHgwMSwgMHgwMiwgMHgwMywgMHgwNCwgMHgwNSwgMHgwNiwgMHgwNywgMHgwOCB9OwoKCgoKc3RhdGljIHZvaWQKQW1kNzkzMF9nZXRfc3RhdGUoc3RydWN0IElzZG5DYXJkU3RhdGUgKmNzKSB7CiAgICAgICAgQllURSBsc3IgPSByQnl0ZUFNRChjcywgMHhBMSk7CiAgICAgICAgY3MtPmRjLmFtZDc5MzAucGhfc3RhdGUgPSAobHNyICYgMHg3KSArIDI7CiAgICAgICAgQW1kNzkzMF9uZXdfcGgoY3MpOwp9CgoKCnN0YXRpYyB2b2lkCkFtZDc5MzBfbmV3X3BoKHN0cnVjdCBJc2RuQ2FyZFN0YXRlICpjcykKewogICAgICAgIHVfY2hhciBpbmRleCA9IHN0YXRlSGVscGVyW2NzLT5kYy5hbWQ3OTMwLm9sZF9zdGF0ZV0qOCArIHN0YXRlSGVscGVyW2NzLT5kYy5hbWQ3OTMwLnBoX3N0YXRlXS0xOwogICAgICAgIHVfY2hhciBtZXNzYWdlID0gaTQzMFN0YXRlc1tpbmRleF07CgogICAgICAgIGlmIChjcy0+ZGVidWcgJiBMMV9ERUJfSVNBQykKCQlkZWJ1Z2wxKGNzLCAiQU1ENzkzMDogbmV3X3BoICVkLCBvbGRfcGggJWQsIG1lc3NhZ2UgJWQsIGluZGV4ICVkIiwKICAgICAgICAgICAgICAgICAgICAgICAgY3MtPmRjLmFtZDc5MzAucGhfc3RhdGUsIGNzLT5kYy5hbWQ3OTMwLm9sZF9zdGF0ZSwgbWVzc2FnZSAmIDB4MGYsIGluZGV4KTsKCiAgICAgICAgY3MtPmRjLmFtZDc5MzAub2xkX3N0YXRlID0gY3MtPmRjLmFtZDc5MzAucGhfc3RhdGU7CgogICAgICAgIC8qIGFib3J0IHRyYW5zbWl0IGlmIG5lc3Nlc2FyeSAqLwogICAgICAgIGlmICgobWVzc2FnZSAmIDB4ZjApICYmIChjcy0+dHhfc2tiKSkgewogICAgICAgICAgICAgICAgd0J5dGVBTUQoY3MsIDB4MjEsIDB4QzIpOwogICAgICAgICAgICAgICAgd0J5dGVBTUQoY3MsIDB4MjEsIDB4MDIpOwogICAgICAgIH0KCglzd2l0Y2ggKG1lc3NhZ2UgJiAweDBmKSB7CgogICAgICAgICAgICAgICAgY2FzZSAoMSk6CiAgICAgICAgICAgICAgICAgICAgICAgIGwxX21zZyhjcywgSFdfUkVTRVQgfCBJTkRJQ0FUSU9OLCBOVUxMKTsKICAgICAgICAgICAgICAgICAgICAgICAgQW1kNzkzMF9nZXRfc3RhdGUoY3MpOwogICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgKDIpOiAvKiBpbml0LCBDYXJkIHN0YXJ0cyBpbiBGMyAqLwogICAgICAgICAgICAgICAgICAgICAgICBsMV9tc2coY3MsIEhXX0RFQUNUSVZBVEUgfCBDT05GSVJNLCBOVUxMKTsKICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlICgzKToKICAgICAgICAgICAgICAgICAgICAgICAgbDFfbXNnKGNzLCBIV19ERUFDVElWQVRFIHwgSU5ESUNBVElPTiwgTlVMTCk7CiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSAoNCk6CiAgICAgICAgICAgICAgICAgICAgICAgIGwxX21zZyhjcywgSFdfUE9XRVJVUCB8IENPTkZJUk0sIE5VTEwpOwogICAgICAgICAgICAgICAgICAgICAgICBBbWQ3OTMwX3BoX2NvbW1hbmQoY3MsIDB4NTAsICJIV19FTkFCTEUgUkVRVUVTVCIpOwogICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgKDUpOgoJCQlsMV9tc2coY3MsIEhXX1JTWU5DIHwgSU5ESUNBVElPTiwgTlVMTCk7CiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSAoNik6CgkJCWwxX21zZyhjcywgSFdfSU5GTzRfUDggfCBJTkRJQ0FUSU9OLCBOVUxMKTsKICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlICg3KTogLyogaW5pdCwgQ2FyZCBzdGFydHMgaW4gRjcgKi8KCQkJbDFfbXNnKGNzLCBIV19SU1lOQyB8IElORElDQVRJT04sIE5VTEwpOwoJCQlsMV9tc2coY3MsIEhXX0lORk80X1A4IHwgSU5ESUNBVElPTiwgTlVMTCk7CiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSAoOCk6CiAgICAgICAgICAgICAgICAgICAgICAgIGwxX21zZyhjcywgSFdfUE9XRVJVUCB8IENPTkZJUk0sIE5VTEwpOwogICAgICAgICAgICAgICAgICAgICAgICAvKiBmYWxsIHRocm91Z2ggKi8KICAgICAgICAgICAgICAgIGNhc2UgKDkpOgogICAgICAgICAgICAgICAgICAgICAgICBBbWQ3OTMwX3BoX2NvbW1hbmQoY3MsIDB4NDAsICJIV19FTkFCTEUgUkVRIGNsZWFyZWQgaWYgc2V0Iik7CgkJCWwxX21zZyhjcywgSFdfUlNZTkMgfCBJTkRJQ0FUSU9OLCBOVUxMKTsKCQkJbDFfbXNnKGNzLCBIV19JTkZPMiB8IElORElDQVRJT04sIE5VTEwpOwoJCQlsMV9tc2coY3MsIEhXX0lORk80X1A4IHwgSU5ESUNBVElPTiwgTlVMTCk7CiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSAoMTApOgogICAgICAgICAgICAgICAgICAgICAgICBBbWQ3OTMwX3BoX2NvbW1hbmQoY3MsIDB4NDAsICJUMyBleHBpcmVkLCBIV19FTkFCTEUgUkVRIGNsZWFyZWQiKTsKICAgICAgICAgICAgICAgICAgICAgICAgY3MtPmRjLmFtZDc5MzAub2xkX3N0YXRlID0gMzsKICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlICgxMSk6CgkJCWwxX21zZyhjcywgSFdfSU5GTzIgfCBJTkRJQ0FUSU9OLCBOVUxMKTsKICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CgkJZGVmYXVsdDoKCQkJYnJlYWs7Cgl9Cn0KCgoKc3RhdGljIHZvaWQKQW1kNzkzMF9iaChzdHJ1Y3QgSXNkbkNhcmRTdGF0ZSAqY3MpCnsKCiAgICAgICAgc3RydWN0IFBTdGFjayAqc3RwdHI7CgoJaWYgKCFjcykKCQlyZXR1cm47CglpZiAodGVzdF9hbmRfY2xlYXJfYml0KERfQ0xFQVJCVVNZLCAmY3MtPmV2ZW50KSkgewogICAgICAgICAgICAgICAgaWYgKGNzLT5kZWJ1ZykKCQkJZGVidWdsMShjcywgIkFtZDc5MzA6IGJoLCBELUNoYW5uZWwgQnVzeSBjbGVhcmVkIik7CgkJc3RwdHIgPSBjcy0+c3RsaXN0OwoJCXdoaWxlIChzdHB0ciAhPSBOVUxMKSB7CgkJCXN0cHRyLT5sMS5sMWwyKHN0cHRyLCBQSF9QQVVTRSB8IENPTkZJUk0sIE5VTEwpOwoJCQlzdHB0ciA9IHN0cHRyLT5uZXh0OwoJCX0KCX0KCWlmICh0ZXN0X2FuZF9jbGVhcl9iaXQoRF9MMVNUQVRFQ0hBTkdFLCAmY3MtPmV2ZW50KSkgewoJICAgICAgICBpZiAoY3MtPmRlYnVnICYgTDFfREVCX0lTQUMpCgkJICAgICAgICBkZWJ1Z2wxKGNzLCAiQU1ENzkzMDogYmgsIERfTDFTVEFURUNIQU5HRSIpOwogICAgICAgICAgICAgICAgQW1kNzkzMF9uZXdfcGgoY3MpOwogICAgICAgIH0KCiAgICAgICAgaWYgKHRlc3RfYW5kX2NsZWFyX2JpdChEX1JDVkJVRlJFQURZLCAmY3MtPmV2ZW50KSkgewoJICAgICAgICBpZiAoY3MtPmRlYnVnICYgTDFfREVCX0lTQUMpCgkJICAgICAgICBkZWJ1Z2wxKGNzLCAiQU1ENzkzMDogYmgsIERfUkNWQlVGUkVBRFkiKTsKICAgICAgICAgICAgICAgIERDaGFubmVsX3Byb2NfcmN2KGNzKTsKICAgICAgICB9CgogICAgICAgIGlmICh0ZXN0X2FuZF9jbGVhcl9iaXQoRF9YTVRCVUZSRUFEWSwgJmNzLT5ldmVudCkpIHsKCSAgICAgICAgaWYgKGNzLT5kZWJ1ZyAmIEwxX0RFQl9JU0FDKQoJCSAgICAgICAgZGVidWdsMShjcywgIkFNRDc5MzA6IGJoLCBEX1hNVEJVRlJFQURZIik7CiAgICAgICAgICAgICAgICBEQ2hhbm5lbF9wcm9jX3htdChjcyk7CiAgICAgICAgfQp9CgpzdGF0aWMgdm9pZApBbWQ3OTMwX2VtcHR5X0RmaWZvKHN0cnVjdCBJc2RuQ2FyZFN0YXRlICpjcywgaW50IGZsYWcpCnsKCiAgICAgICAgQllURSBzdGF0LCBkZXI7CglCWVRFICpwdHI7CglzdHJ1Y3Qgc2tfYnVmZiAqc2tiOwoKCglpZiAoKGNzLT5kZWJ1ZyAmIEwxX0RFQl9JU0FDKSAmJiAhKGNzLT5kZWJ1ZyAmIEwxX0RFQl9JU0FDX0ZJRk8pKQoJCWRlYnVnbDEoY3MsICJBbWQ3OTMwOiBlbXB0eV9EZmlmbyIpOwoKCglwdHIgPSBjcy0+cmN2YnVmICsgY3MtPnJjdmlkeDsKCgkvKiBBTUQgaW50ZXJydXB0cyBvZmYgKi8KCUFtZElycU9mZihjcyk7CgoJLyogcmVhZCBELUNoYW5uZWwtRmlmbyovCglzdGF0ID0gckJ5dGVBTUQoY3MsIDB4MDcpOyAvLyBEU1IyCgoJCS8qIHdoaWxlIERhdGEgaW4gRmlmbyAuLi4gKi8KCQl3aGlsZSAoIChzdGF0ICYgMikgJiYgKChwdHItY3MtPnJjdmJ1ZikgPCBNQVhfREZSQU1FX0xFTl9MMSkgKSB7CgkJCSpwdHIgPSByQnl0ZUFNRChjcywgMHgwNCk7IC8vIERDUkIKCQkJcHRyKys7CgkgICAgICAgICAgICAgICAgc3RhdCA9IHJCeXRlQU1EKGNzLCAweDA3KTsgLy8gRFNSMgoJCQljcy0+cmN2aWR4ID0gcHRyIC0gY3MtPnJjdmJ1ZjsKCiAgICAgICAgICAgICAgICAgICAgICAgIC8qIFBha2V0IHJlYWR5PyAqLwoJCQlpZiAoc3RhdCAmIDEpIHsKCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVyID0gcldvcmRBTUQoY3MsIDB4MDMpOwoKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBubyBlcnJvcnMsIHBhY2tldCBvayAqLwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmKCFkZXIgJiYgIWZsYWcpIHsKCQkJCQlyV29yZEFNRChjcywgMHg4OSk7IC8vIGNsZWFyIERSQ1IKCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoKGNzLT5yY3ZpZHgpID4gMCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoIShza2IgPSBhbGxvY19za2IoY3MtPnJjdmlkeCwgR0ZQX0FUT01JQykpKQoJCQkJCQkJcHJpbnRrKEtFUk5fV0FSTklORyAiSGlTYXg6IEFtZDc5MzA6IGVtcHR5X0RmaWZvLCBEIHJlY2VpdmUgb3V0IG9mIG1lbW9yeSFcbiIpOwoJCQkJCQllbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBEZWJ1Z2dpbmcgKi8KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoY3MtPmRlYnVnICYgTDFfREVCX0lTQUNfRklGTykgewoJCQkJCQkJCWNoYXIgKnQgPSBjcy0+ZGxvZzsKCgkJCQkJCQkJdCArPSBzcHJpbnRmKHQsICJBbWQ3OTMwOiBlbXB0eV9EZmlmbyBjbnQ6ICVkIHwiLCBjcy0+cmN2aWR4KTsKCQkJCQkJCQlRdWlja0hleCh0LCBjcy0+cmN2YnVmLCBjcy0+cmN2aWR4KTsKCQkJCQkJCQlkZWJ1Z2wxKGNzLCBjcy0+ZGxvZyk7CgkJCQkJCQl9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogbW92ZXMgcmVjZWl2ZWQgZGF0YSBpbiBzay1idWZmZXIgKi8KCQkJCQkJCW1lbWNweShza2JfcHV0KHNrYiwgY3MtPnJjdmlkeCksIGNzLT5yY3ZidWYsIGNzLT5yY3ZpZHgpOwoJCQkJCQkJc2tiX3F1ZXVlX3RhaWwoJmNzLT5ycSwgc2tiKTsKCQkJCQkJfQoJCQkJCX0KCgkJCQl9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdGhyb3cgZGFtYWdlZCBwYWNrZXRzIGF3YXksIHJlc2V0IHJlY2VpdmUtYnVmZmVyLCBpbmRpY2F0ZSBSWCAqLwoJCQkJcHRyID0gY3MtPnJjdmJ1ZjsKCQkJCWNzLT5yY3ZpZHggPSAwOwoJCQkJc2NoZWR1bGVfZXZlbnQoY3MsIERfUkNWQlVGUkVBRFkpOwoJCQl9CiAgICAgICAgICAgICAgICB9CgkJLyogUGFja2V0IHRvIGxvbmcsIG92ZXJmbG93ICovCgkJaWYoY3MtPnJjdmlkeCA+PSBNQVhfREZSQU1FX0xFTl9MMSkgewoJCQlpZiAoY3MtPmRlYnVnICYgTDFfREVCX1dBUk4pCgkJCSAgICAgICAgZGVidWdsMShjcywgIkFNRDc5MzA6IGVtcHR5X0RmaWZvIEwyLUZyYW1lbGVuZ3RoIG92ZXJydW4iKTsKCQkJY3MtPnJjdmlkeCA9IDA7CgkJCXJldHVybjsKCQl9CgkvKiBBTUQgaW50ZXJydXB0cyBvbiAqLwoJQW1kSXJxT24oY3MpOwp9CgoKc3RhdGljIHZvaWQKQW1kNzkzMF9maWxsX0RmaWZvKHN0cnVjdCBJc2RuQ2FyZFN0YXRlICpjcykKewoKICAgICAgICBXT1JEIGR0Y3JyLCBkdGNydywgbGVuLCBjb3VudDsKICAgICAgICBCWVRFIHR4c3RhdCwgZG1yMzsKICAgICAgICBCWVRFICpwdHIsICpkZWJfcHRyOwoKCWlmICgoY3MtPmRlYnVnICYgTDFfREVCX0lTQUMpICYmICEoY3MtPmRlYnVnICYgTDFfREVCX0lTQUNfRklGTykpCgkJZGVidWdsMShjcywgIkFtZDc5MzA6IGZpbGxfRGZpZm8iKTsKCglpZiAoKCFjcy0+dHhfc2tiKSB8fCAoY3MtPnR4X3NrYi0+bGVuIDw9IDApKQoJCXJldHVybjsKCiAgICAgICAgZHRjcncgPSAwOwogICAgICAgIGlmKCFjcy0+ZGMuYW1kNzkzMC50eF94bXRsZW4pCiAgICAgICAgICAgICAgICAvKiBuZXcgRnJhbWUgKi8KICAgICAgICAgICAgICAgIGxlbiA9IGR0Y3J3ID0gY3MtPnR4X3NrYi0+bGVuOwogICAgICAgIC8qIGNvbnRpbnVlIGZyYW1lICovCiAgICAgICAgZWxzZSBsZW4gPSBjcy0+ZGMuYW1kNzkzMC50eF94bXRsZW47CgoKCS8qIEFNRCBpbnRlcnJ1cHRzIG9mZiAqLwoJQW1kSXJxT2ZmKGNzKTsKCiAgICAgICAgZGViX3B0ciA9IHB0ciA9IGNzLT50eF9za2ItPmRhdGE7CgogICAgICAgIC8qIHdoaWxlIGZyZWUgcGxhY2UgaW4gdHgtZmlmbyBhdmFpbGFibGUgYW5kIGRhdGEgaW4gc2stYnVmZmVyICovCiAgICAgICAgdHhzdGF0ID0gMHgxMDsKICAgICAgICB3aGlsZSgodHhzdGF0ICYgMHgxMCkgJiYgKGNzLT50eF9jbnQgPCBsZW4pKSB7CiAgICAgICAgICAgICAgICB3Qnl0ZUFNRChjcywgMHgwNCwgKnB0cik7CiAgICAgICAgICAgICAgICBwdHIrKzsKICAgICAgICAgICAgICAgIGNzLT50eF9jbnQrKzsKICAgICAgICAgICAgICAgIHR4c3RhdD0gckJ5dGVBTUQoY3MsIDB4MDcpOwogICAgICAgIH0KICAgICAgICBjb3VudCA9IHB0ciAtIGNzLT50eF9za2ItPmRhdGE7Cglza2JfcHVsbChjcy0+dHhfc2tiLCBjb3VudCk7CgoKICAgICAgICBkdGNyciA9IHJXb3JkQU1EKGNzLCAweDg1KTsgLy8gRFRDUgogICAgICAgIGRtcjMgID0gckJ5dGVBTUQoY3MsIDB4OEUpOwoKCWlmIChjcy0+ZGVidWcgJiBMMV9ERUJfSVNBQykgewoJCWRlYnVnbDEoY3MsICJBbWQ3OTMwOiBmaWxsX0RmaWZvLCBETVIzOiAweCUwMlgsIERUQ1IgcmVhZDogMHglMDRYIHdyaXRlOiAweCUwMlggMHglMDJYIiwgZG1yMywgZHRjcnIsIExPQllURShkdGNydyksIEhJQllURShkdGNydykpOwogICAgICAgIH0KCiAgICAgICAgLyogd3JpdGVpbmcgb2YgZHRjcncgc3RhcnRzIHRyYW5zbWl0ICovCiAgICAgICAgaWYoIWNzLT5kYy5hbWQ3OTMwLnR4X3htdGxlbikgewogICAgICAgICAgICAgICAgd1dvcmRBTUQoY3MsIDB4ODUsIGR0Y3J3KTsKICAgICAgICAgICAgICAgIGNzLT5kYy5hbWQ3OTMwLnR4X3htdGxlbiA9IGR0Y3J3OwogICAgICAgIH0KCglpZiAodGVzdF9hbmRfc2V0X2JpdChGTEdfREJVU1lfVElNRVIsICZjcy0+SFdfRmxhZ3MpKSB7CgkJZGVidWdsMShjcywgIkFtZDc5MzA6IGZpbGxfRGZpZm8gZGJ1c3l0aW1lciBydW5uaW5nIik7CgkJZGVsX3RpbWVyKCZjcy0+ZGJ1c3l0aW1lcik7Cgl9Cglpbml0X3RpbWVyKCZjcy0+ZGJ1c3l0aW1lcik7Cgljcy0+ZGJ1c3l0aW1lci5leHBpcmVzID0gamlmZmllcyArICgoREJVU1lfVElNRVJfVkFMVUUgKiBIWikgLyAxMDAwKTsKCWFkZF90aW1lcigmY3MtPmRidXN5dGltZXIpOwoKCWlmIChjcy0+ZGVidWcgJiBMMV9ERUJfSVNBQ19GSUZPKSB7CgkJY2hhciAqdCA9IGNzLT5kbG9nOwoKCQl0ICs9IHNwcmludGYodCwgIkFtZDc5MzA6IGZpbGxfRGZpZm8gY250OiAlZCB8IiwgY291bnQpOwoJCVF1aWNrSGV4KHQsIGRlYl9wdHIsIGNvdW50KTsKCQlkZWJ1Z2wxKGNzLCBjcy0+ZGxvZyk7Cgl9CgkvKiBBTUQgaW50ZXJydXB0cyBvbiAqLwogICAgICAgIEFtZElycU9uKGNzKTsKfQoKCnZvaWQgQW1kNzkzMF9pbnRlcnJ1cHQoc3RydWN0IElzZG5DYXJkU3RhdGUgKmNzLCBCWVRFIGlyZmxhZ3MpCnsKCUJZVEUgZHNyMSwgZHNyMiwgbHNyOwogICAgICAgIFdPUkQgZGVyOwoKIHdoaWxlIChpcmZsYWdzKQogewoKICAgICAgICBkc3IxID0gckJ5dGVBTUQoY3MsIDB4MDIpOwogICAgICAgIGRlciAgPSByV29yZEFNRChjcywgMHgwMyk7CiAgICAgICAgZHNyMiA9IHJCeXRlQU1EKGNzLCAweDA3KTsKICAgICAgICBsc3IgID0gckJ5dGVBTUQoY3MsIDB4QTEpOwoKCWlmIChjcy0+ZGVidWcgJiBMMV9ERUJfSVNBQykKCQlkZWJ1Z2wxKGNzLCAiQW1kNzkzMDogaW50ZXJydXB0OiBmbGFnczogMHglMDJYLCBEU1IxOiAweCUwMlgsIERTUjI6IDB4JTAyWCwgTFNSOiAweCUwMlgsIERFUj0weCUwNFgiLCBpcmZsYWdzLCBkc3IxLCBkc3IyLCBsc3IsIGRlcik7CgogICAgICAgIC8qIEQgZXJyb3IgLT4gcmVhZCBERVIgYW5kIERTUjIgYml0IDIgKi8KCWlmIChkZXIgfHwgKGRzcjIgJiA0KSkgewoKICAgICAgICAgICAgICAgIGlmIChjcy0+ZGVidWcgJiBMMV9ERUJfV0FSTikKCQkJZGVidWdsMShjcywgIkFtZDc5MzA6IGludGVycnVwdDogRCBlcnJvciBERVI9MHglMDRYIiwgZGVyKTsKCiAgICAgICAgICAgICAgICAvKiBSWCwgVFggYWJvcnQgaWYgY29sbGlzaW9uIGRldGVjdGVkICovCiAgICAgICAgICAgICAgICBpZiAoZGVyICYgMikgewogICAgICAgICAgICAgICAgICAgICAgICB3Qnl0ZUFNRChjcywgMHgyMSwgMHhDMik7CiAgICAgICAgICAgICAgICAgICAgICAgIHdCeXRlQU1EKGNzLCAweDIxLCAweDAyKTsKCQkJaWYgKHRlc3RfYW5kX2NsZWFyX2JpdChGTEdfREJVU1lfVElNRVIsICZjcy0+SFdfRmxhZ3MpKQoJCQkJZGVsX3RpbWVyKCZjcy0+ZGJ1c3l0aW1lcik7CgkJCWlmICh0ZXN0X2FuZF9jbGVhcl9iaXQoRkxHX0wxX0RCVVNZLCAmY3MtPkhXX0ZsYWdzKSkKCQkJCXNjaGVkdWxlX2V2ZW50KGNzLCBEX0NMRUFSQlVTWSk7CiAgICAgICAgICAgICAgICAgICAgICAgIC8qIHJlc3RhcnQgZnJhbWUgKi8KICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGNzLT50eF9za2IpIHsKCQkJCXNrYl9wdXNoKGNzLT50eF9za2IsIGNzLT50eF9jbnQpOwoJCQkJY3MtPnR4X2NudCA9IDA7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY3MtPmRjLmFtZDc5MzAudHhfeG10bGVuID0gMDsKCQkJCUFtZDc5MzBfZmlsbF9EZmlmbyhjcyk7CgkJCX0gZWxzZSB7CgkJCQlwcmludGsoS0VSTl9XQVJOSU5HICJIaVNheDogQW1kNzkzMCBELUNvbGxpc2lvbiwgbm8gc2tiXG4iKTsKCQkJCWRlYnVnbDEoY3MsICJBbWQ3OTMwOiBpbnRlcnJ1cHQ6IEQtQ29sbGlzaW9uLCBubyBza2IiKTsKCQkJfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgLyogcmVtb3ZlIGRhbWFnZWQgZGF0YSBmcm9tIGZpZm8gKi8KCQlBbWQ3OTMwX2VtcHR5X0RmaWZvKGNzLCAxKTsKCgkJaWYgKHRlc3RfYW5kX2NsZWFyX2JpdChGTEdfREJVU1lfVElNRVIsICZjcy0+SFdfRmxhZ3MpKQoJCQlkZWxfdGltZXIoJmNzLT5kYnVzeXRpbWVyKTsKCQlpZiAodGVzdF9hbmRfY2xlYXJfYml0KEZMR19MMV9EQlVTWSwgJmNzLT5IV19GbGFncykpCgkJCXNjaGVkdWxlX2V2ZW50KGNzLCBEX0NMRUFSQlVTWSk7CiAgICAgICAgICAgICAgICAvKiByZXN0YXJ0IFRYLUZyYW1lICovCiAgICAgICAgICAgICAgICBpZiAoY3MtPnR4X3NrYikgewoJCQlza2JfcHVzaChjcy0+dHhfc2tiLCBjcy0+dHhfY250KTsKCQkJY3MtPnR4X2NudCA9IDA7CiAgICAgICAgICAgICAgICAgICAgICAgIGNzLT5kYy5hbWQ3OTMwLnR4X3htdGxlbiA9IDA7CgkJCUFtZDc5MzBfZmlsbF9EZmlmbyhjcyk7CgkJfQoJfQoKICAgICAgICAvKiBEIFRYIEZJRk8gZW1wdHkgLT4gZmlsbCAqLwoJaWYgKGlyZmxhZ3MgJiAxKSB7CgkJaWYgKGNzLT5kZWJ1ZyAmIEwxX0RFQl9JU0FDKQoJCQlkZWJ1Z2wxKGNzLCAiQW1kNzkzMDogaW50ZXJydXB0OiBjbGVhciBUaW1lciBhbmQgZmlsbCBELVRYLUZJRk8gaWYgZGF0YSIpOwoKCQkvKiBBTUQgaW50ZXJydXB0cyBvZmYgKi8KICAgICAgICAgICAgICAgIEFtZElycU9mZihjcyk7CgogICAgICAgICAgICAgICAgaWYgKHRlc3RfYW5kX2NsZWFyX2JpdChGTEdfREJVU1lfVElNRVIsICZjcy0+SFdfRmxhZ3MpKQoJCQlkZWxfdGltZXIoJmNzLT5kYnVzeXRpbWVyKTsKCQlpZiAodGVzdF9hbmRfY2xlYXJfYml0KEZMR19MMV9EQlVTWSwgJmNzLT5IV19GbGFncykpCgkJCXNjaGVkdWxlX2V2ZW50KGNzLCBEX0NMRUFSQlVTWSk7CgkJaWYgKGNzLT50eF9za2IpIHsKCQkJaWYgKGNzLT50eF9za2ItPmxlbikKCQkJCUFtZDc5MzBfZmlsbF9EZmlmbyhjcyk7CgkJfQoJCS8qIEFNRCBpbnRlcnJ1cHRzIG9uICovCiAgICAgICAgICAgICAgICBBbWRJcnFPbihjcyk7Cgl9CgoKICAgICAgICAvKiBEIFJYIEZJRk8gZnVsbCBvciB0aW55IHBhY2tldCBpbiBGaWZvIC0+IGVtcHR5ICovCglpZiAoKGlyZmxhZ3MgJiAyKSB8fCAoZHNyMSAmIDIpKSB7CiAgICAgICAgICAgICAgICBpZiAoY3MtPmRlYnVnICYgTDFfREVCX0lTQUMpCgkJCWRlYnVnbDEoY3MsICJBbWQ3OTMwOiBpbnRlcnJ1cHQ6IGVtcHR5IEQtRklGTyIpOwogICAgICAgICAgICAgICAgQW1kNzkzMF9lbXB0eV9EZmlmbyhjcywgMCk7Cgl9CgoKICAgICAgICAvKiBELUZyYW1lIHRyYW5zbWl0IGNvbXBsZXRlICovCglpZiAoZHNyMSAmIDY0KSB7CgkJaWYgKGNzLT5kZWJ1ZyAmIEwxX0RFQl9JU0FDKSB7CgkJCWRlYnVnbDEoY3MsICJBbWQ3OTMwOiBpbnRlcnJ1cHQ6IHRyYW5zbWl0IHBhY2tldCByZWFkeSIpOwogICAgICAgIAl9CgkJLyogQU1EIGludGVycnVwdHMgb2ZmICovCiAgICAgICAgICAgICAgICBBbWRJcnFPZmYoY3MpOwoKICAgICAgICAgICAgICAgIGlmICh0ZXN0X2FuZF9jbGVhcl9iaXQoRkxHX0RCVVNZX1RJTUVSLCAmY3MtPkhXX0ZsYWdzKSkKCQkJZGVsX3RpbWVyKCZjcy0+ZGJ1c3l0aW1lcik7CgkJaWYgKHRlc3RfYW5kX2NsZWFyX2JpdChGTEdfTDFfREJVU1ksICZjcy0+SFdfRmxhZ3MpKQoJCQlzY2hlZHVsZV9ldmVudChjcywgRF9DTEVBUkJVU1kpOwoKICAgICAgICAgICAgICAgIGlmIChjcy0+dHhfc2tiKSB7CiAgICAgICAgCQlpZiAoY3MtPmRlYnVnICYgTDFfREVCX0lTQUMpCgkgICAgICAgIAkJZGVidWdsMShjcywgIkFtZDc5MzA6IGludGVycnVwdDogVFgtUGFja2V0IHJlYWR5LCBmcmVlaW5nIHNrYiIpOwogICAgICAgICAgICAgICAgICAgICAgICBkZXZfa2ZyZWVfc2tiX2lycShjcy0+dHhfc2tiKTsKCQkJY3MtPnR4X2NudCA9IDA7CiAgICAgICAgICAgICAgICAgICAgICAgIGNzLT5kYy5hbWQ3OTMwLnR4X3htdGxlbj0wOwoJCQljcy0+dHhfc2tiID0gTlVMTDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlmICgoY3MtPnR4X3NrYiA9IHNrYl9kZXF1ZXVlKCZjcy0+c3EpKSkgewogICAgICAgIAkJaWYgKGNzLT5kZWJ1ZyAmIEwxX0RFQl9JU0FDKQoJICAgICAgICAJCWRlYnVnbDEoY3MsICJBbWQ3OTMwOiBpbnRlcnJ1cHQ6IFRYLVBhY2tldCByZWFkeSwgbmV4dCBwYWNrZXQgZGVxdWV1ZWQiKTsKCSAgICAgICAgCWNzLT50eF9jbnQgPSAwOwogICAgICAgICAgICAgICAgICAgICAgICBjcy0+ZGMuYW1kNzkzMC50eF94bXRsZW49MDsKCQkJQW1kNzkzMF9maWxsX0RmaWZvKGNzKTsKCQl9CiAgICAgICAgICAgICAgICBlbHNlCgkJCXNjaGVkdWxlX2V2ZW50KGNzLCBEX1hNVEJVRlJFQURZKTsKCQkvKiBBTUQgaW50ZXJydXB0cyBvbiAqLwogICAgICAgICAgICAgICAgQW1kSXJxT24oY3MpOwogICAgICAgIH0KCgkvKiBMSVUgc3RhdHVzIGludGVycnVwdCAtPiByZWFkIExTUiwgY2hlY2sgc3RhdGVjaGFuZ2VzICovCglpZiAobHNyICYgMHgzOCkgewogICAgICAgICAgICAgICAgLyogQU1EIGludGVycnVwdHMgb2ZmICovCiAgICAgICAgICAgICAgICBBbWRJcnFPZmYoY3MpOwoKCQlpZiAoY3MtPmRlYnVnICYgTDFfREVCX0lTQUMpCgkJCWRlYnVnbDEoY3MsICJBbWQ6IGludGVycnVwdDogTFNSPTB4JTAyWCwgTElVIGlzIGluIHN0YXRlICVkIiwgbHNyLCAoKGxzciAmIDB4NykgKzIpKTsKCgkJY3MtPmRjLmFtZDc5MzAucGhfc3RhdGUgPSAobHNyICYgMHg3KSArIDI7CgoJCXNjaGVkdWxlX2V2ZW50KGNzLCBEX0wxU1RBVEVDSEFOR0UpOwoJCS8qIEFNRCBpbnRlcnJ1cHRzIG9uICovCiAgICAgICAgICAgICAgICBBbWRJcnFPbihjcyk7Cgl9CgogICAgICAgIC8qIHJlYWRzIEludGVycnVwdC1SZWdpc3RlciBhZ2Fpbi4gSWYgdGhlcmUgaXMgYSBuZXcgaW50ZXJydXB0LWZsYWc6IHJlc3RhcnQgaGFuZGxlciAqLwogICAgICAgIGlyZmxhZ3MgPSByQnl0ZUFNRChjcywgMHgwMCk7CiB9Cgp9CgpzdGF0aWMgdm9pZApBbWQ3OTMwX2wxaHcoc3RydWN0IFBTdGFjayAqc3QsIGludCBwciwgdm9pZCAqYXJnKQp7CiAgICAgICAgc3RydWN0IElzZG5DYXJkU3RhdGUgKmNzID0gKHN0cnVjdCBJc2RuQ2FyZFN0YXRlICopIHN0LT5sMS5oYXJkd2FyZTsKCXN0cnVjdCBza19idWZmICpza2IgPSBhcmc7Cgl1X2xvbmcgZmxhZ3M7CgogICAgICAgIGlmIChjcy0+ZGVidWcgJiBMMV9ERUJfSVNBQykKCQlkZWJ1Z2wxKGNzLCAiQW1kNzkzMDogbDFodyBjYWxsZWQsIHByOiAweCUwNFgiLCBwcik7CgoJc3dpdGNoIChwcikgewoJCWNhc2UgKFBIX0RBVEEgfCBSRVFVRVNUKToKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGNzLT5kZWJ1ZyAmIERFQl9ETE9HX0hFWCkKCQkJCUxvZ0ZyYW1lKGNzLCBza2ItPmRhdGEsIHNrYi0+bGVuKTsKCQkJaWYgKGNzLT5kZWJ1ZyAmIERFQl9ETE9HX1ZFUkJPU0UpCgkJCQlkbG9nZnJhbWUoY3MsIHNrYiwgMCk7CgkJCXNwaW5fbG9ja19pcnFzYXZlKCZjcy0+bG9jaywgZmxhZ3MpOwoJCQlpZiAoY3MtPnR4X3NrYikgewoJCQkJc2tiX3F1ZXVlX3RhaWwoJmNzLT5zcSwgc2tiKTsKI2lmZGVmIEwyRlJBTUVfREVCVUcJCS8qIHBzYSAqLwoJCQkJaWYgKGNzLT5kZWJ1ZyAmIEwxX0RFQl9MQVBEKQoJCQkJCUxvZ2wyRnJhbWUoY3MsIHNrYiwgIkFtZDc5MzA6IGwxaHc6IFBIX0RBVEEgUXVldWVkIiwgMCk7CiNlbmRpZgoJCQl9IGVsc2UgewoJCQkJY3MtPnR4X3NrYiA9IHNrYjsKCQkJCWNzLT50eF9jbnQgPSAwOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNzLT5kYy5hbWQ3OTMwLnR4X3htdGxlbj0wOwojaWZkZWYgTDJGUkFNRV9ERUJVRwkJLyogcHNhICovCgkJCQlpZiAoY3MtPmRlYnVnICYgTDFfREVCX0xBUEQpCgkJCQkJTG9nbDJGcmFtZShjcywgc2tiLCAiQW1kNzkzMDogbDFodzogUEhfREFUQSIsIDApOwojZW5kaWYKCQkJCUFtZDc5MzBfZmlsbF9EZmlmbyhjcyk7CgkJCX0KCQkJc3Bpbl91bmxvY2tfaXJxcmVzdG9yZSgmY3MtPmxvY2ssIGZsYWdzKTsKCQkJYnJlYWs7CgkJY2FzZSAoUEhfUFVMTCB8IElORElDQVRJT04pOgoJCQlzcGluX2xvY2tfaXJxc2F2ZSgmY3MtPmxvY2ssIGZsYWdzKTsKCQkJaWYgKGNzLT50eF9za2IpIHsKCQkJCWlmIChjcy0+ZGVidWcgJiBMMV9ERUJfV0FSTikKCQkJCQlkZWJ1Z2wxKGNzLCAiQW1kNzkzMDogbDFodzogbDJsMSB0eF9za2IgZXhpc3QgdGhpcyBzaG91bGRuJ3QgaGFwcGVuIik7CgkJCQlza2JfcXVldWVfdGFpbCgmY3MtPnNxLCBza2IpOwoJCQkJYnJlYWs7CgkJCX0KCQkJaWYgKGNzLT5kZWJ1ZyAmIERFQl9ETE9HX0hFWCkKCQkJCUxvZ0ZyYW1lKGNzLCBza2ItPmRhdGEsIHNrYi0+bGVuKTsKCQkJaWYgKGNzLT5kZWJ1ZyAmIERFQl9ETE9HX1ZFUkJPU0UpCgkJCQlkbG9nZnJhbWUoY3MsIHNrYiwgMCk7CgkJCWNzLT50eF9za2IgPSBza2I7CgkJCWNzLT50eF9jbnQgPSAwOwogICAgICAgICAgICAgICAgICAgICAgICBjcy0+ZGMuYW1kNzkzMC50eF94bXRsZW49MDsKI2lmZGVmIEwyRlJBTUVfREVCVUcJCS8qIHBzYSAqLwoJCQlpZiAoY3MtPmRlYnVnICYgTDFfREVCX0xBUEQpCgkJCQlMb2dsMkZyYW1lKGNzLCBza2IsICJBbWQ3OTMwOiBsMWh3OiBQSF9EQVRBX1BVTExFRCIsIDApOwojZW5kaWYKCQkJQW1kNzkzMF9maWxsX0RmaWZvKGNzKTsKCQkJc3Bpbl91bmxvY2tfaXJxcmVzdG9yZSgmY3MtPmxvY2ssIGZsYWdzKTsKCQkJYnJlYWs7CgkJY2FzZSAoUEhfUFVMTCB8IFJFUVVFU1QpOgojaWZkZWYgTDJGUkFNRV9ERUJVRwkJLyogcHNhICovCgkJCWlmIChjcy0+ZGVidWcgJiBMMV9ERUJfTEFQRCkKCQkJCWRlYnVnbDEoY3MsICJBbWQ3OTMwOiBsMWh3OiAtPiBQSF9SRVFVRVNUX1BVTEwsIHNrYjogJXMiLCAoY3MtPnR4X3NrYik/ICJ5ZXMiOiJubyIpOwojZW5kaWYKCQkJaWYgKCFjcy0+dHhfc2tiKSB7CgkJCQl0ZXN0X2FuZF9jbGVhcl9iaXQoRkxHX0wxX1BVTExfUkVRLCAmc3QtPmwxLkZsYWdzKTsKCQkJCXN0LT5sMS5sMWwyKHN0LCBQSF9QVUxMIHwgQ09ORklSTSwgTlVMTCk7CgkJCX0gZWxzZQoJCQkJdGVzdF9hbmRfc2V0X2JpdChGTEdfTDFfUFVMTF9SRVEsICZzdC0+bDEuRmxhZ3MpOwoJCQlicmVhazsKCQljYXNlIChIV19SRVNFVCB8IFJFUVVFU1QpOgoJCQlzcGluX2xvY2tfaXJxc2F2ZSgmY3MtPmxvY2ssIGZsYWdzKTsKCQkJaWYgKChjcy0+ZGMuYW1kNzkzMC5waF9zdGF0ZSA9PSA4KSkgewoJCQkJLyogYi1jaGFubmVscyBvZmYsIFBILUFSIGNsZWFyZWQKCQkJCSAqIGNoYW5nZSB0byBGMyAqLwoJCQkJQW1kNzkzMF9waF9jb21tYW5kKGNzLCAweDIwLCAiSFdfUkVTRVQgUkVRRVNUIik7IC8vTE1SMSBiaXQgNQoJCQkJc3Bpbl91bmxvY2tfaXJxcmVzdG9yZSgmY3MtPmxvY2ssIGZsYWdzKTsKCQkJfSBlbHNlIHsKCQkJCUFtZDc5MzBfcGhfY29tbWFuZChjcywgMHg0MCwgIkhXX1JFU0VUIFJFUVVFU1QiKTsKCQkJCWNzLT5kYy5hbWQ3OTMwLnBoX3N0YXRlID0gMjsKCQkJCXNwaW5fdW5sb2NrX2lycXJlc3RvcmUoJmNzLT5sb2NrLCBmbGFncyk7CgkJCQlBbWQ3OTMwX25ld19waChjcyk7CgkJCX0KCQkJYnJlYWs7CgkJY2FzZSAoSFdfRU5BQkxFIHwgUkVRVUVTVCk6CiAgICAgICAgICAgICAgICAgICAgICAgIGNzLT5kYy5hbWQ3OTMwLnBoX3N0YXRlID0gOTsKICAgICAgICAgICAgICAgICAgICAgICAgQW1kNzkzMF9uZXdfcGgoY3MpOwoJCQlicmVhazsKCQljYXNlIChIV19JTkZPMyB8IFJFUVVFU1QpOgoJCQkvLyBhdXRvbWF0aWMKCQkJYnJlYWs7CgkJY2FzZSAoSFdfVEVTVExPT1AgfCBSRVFVRVNUKToKCQkJLyogbm90IGltcGxlbWVudGVkIHlldCAqLwoJCQlicmVhazsKCQljYXNlIChIV19ERUFDVElWQVRFIHwgUkVTUE9OU0UpOgogICAgICAgICAgICAgICAgICAgICAgICBza2JfcXVldWVfcHVyZ2UoJmNzLT5ycSk7CgkJCXNrYl9xdWV1ZV9wdXJnZSgmY3MtPnNxKTsKCQkJaWYgKGNzLT50eF9za2IpIHsKCQkJCWRldl9rZnJlZV9za2IoY3MtPnR4X3NrYik7CgkJCQljcy0+dHhfc2tiID0gTlVMTDsKCQkJfQoJCQlpZiAodGVzdF9hbmRfY2xlYXJfYml0KEZMR19EQlVTWV9USU1FUiwgJmNzLT5IV19GbGFncykpCgkJCQlkZWxfdGltZXIoJmNzLT5kYnVzeXRpbWVyKTsKCQkJaWYgKHRlc3RfYW5kX2NsZWFyX2JpdChGTEdfTDFfREJVU1ksICZjcy0+SFdfRmxhZ3MpKQoJCQkJc2NoZWR1bGVfZXZlbnQoY3MsIERfQ0xFQVJCVVNZKTsKCQkJYnJlYWs7CgkJZGVmYXVsdDoKCQkJaWYgKGNzLT5kZWJ1ZyAmIEwxX0RFQl9XQVJOKQoJCQkJZGVidWdsMShjcywgIkFtZDc5MzA6IGwxaHc6IHVua25vd24gJTA0eCIsIHByKTsKCQkJYnJlYWs7Cgl9Cn0KCnZvaWQKc2V0c3RhY2tfQW1kNzkzMChzdHJ1Y3QgUFN0YWNrICpzdCwgc3RydWN0IElzZG5DYXJkU3RhdGUgKmNzKQp7CgogICAgICAgIGlmIChjcy0+ZGVidWcgJiBMMV9ERUJfSVNBQykKCQlkZWJ1Z2wxKGNzLCAiQW1kNzkzMDogc2V0c3RhY2sgY2FsbGVkIik7CgogICAgICAgIHN0LT5sMS5sMWh3ID0gQW1kNzkzMF9sMWh3Owp9CgoKdm9pZApEQ19DbG9zZV9BbWQ3OTMwKHN0cnVjdCBJc2RuQ2FyZFN0YXRlICpjcykgewogICAgICAgIGlmIChjcy0+ZGVidWcgJiBMMV9ERUJfSVNBQykKCQlkZWJ1Z2wxKGNzLCAiQW1kNzkzMDogRENfQ2xvc2UgY2FsbGVkIik7Cn0KCgpzdGF0aWMgdm9pZApkYnVzeV90aW1lcl9oYW5kbGVyKHN0cnVjdCBJc2RuQ2FyZFN0YXRlICpjcykKewoJdV9sb25nIGZsYWdzOwoJc3RydWN0IFBTdGFjayAqc3RwdHI7CiAgICAgICAgV09SRCBkdGNyLCBkZXI7CiAgICAgICAgQllURSBkc3IxLCBkc3IyOwoKCiAgICAgICAgaWYgKGNzLT5kZWJ1ZyAmIEwxX0RFQl9JU0FDKQoJCWRlYnVnbDEoY3MsICJBbWQ3OTMwOiBkYnVzeV90aW1lciBleHBpcmVkISIpOwoKCWlmICh0ZXN0X2JpdChGTEdfREJVU1lfVElNRVIsICZjcy0+SFdfRmxhZ3MpKSB7CgkJc3Bpbl9sb2NrX2lycXNhdmUoJmNzLT5sb2NrLCBmbGFncyk7CiAgICAgICAgICAgICAgICAvKiBEIFRyYW5zbWl0IEJ5dGUgQ291bnQgUmVnaXN0ZXI6CiAgICAgICAgICAgICAgICAgKiBDb3VudHMgZG93biBwYWNrZXQncyBudW1iZXIgb2YgQnl0ZXMsIDAgaWYgcGFja2V0IHJlYWR5ICovCiAgICAgICAgICAgICAgICBkdGNyID0gcldvcmRBTUQoY3MsIDB4ODUpOwogICAgICAgICAgICAgICAgZHNyMSA9IHJCeXRlQU1EKGNzLCAweDAyKTsKICAgICAgICAgICAgICAgIGRzcjIgPSByQnl0ZUFNRChjcywgMHgwNyk7CiAgICAgICAgICAgICAgICBkZXIgID0gcldvcmRBTUQoY3MsIDB4MDMpOwoKCSAgICAgICAgaWYgKGNzLT5kZWJ1ZyAmIEwxX0RFQl9JU0FDKQoJCQlkZWJ1Z2wxKGNzLCAiQW1kNzkzMDogZGJ1c3lfdGltZXJfaGFuZGxlcjogRFNSMT0weCUwMlgsIERTUjI9MHglMDJYLCBERVI9MHglMDRYLCBjcy0+dHhfc2tiLT5sZW49JXUsIHR4X3N0YXQ9JXUsIGR0Y3I9JXUsIGNzLT50eF9jbnQ9JXUiLCBkc3IxLCBkc3IyLCBkZXIsIGNzLT50eF9za2ItPmxlbiwgY3MtPmRjLmFtZDc5MzAudHhfeG10bGVuLCBkdGNyLCBjcy0+dHhfY250KTsKCgkJaWYgKChjcy0+ZGMuYW1kNzkzMC50eF94bXRsZW4gLSBkdGNyKSA8IGNzLT50eF9jbnQpIHsJLyogRC1DaGFubmVsIEJ1c3kgKi8KCQkJdGVzdF9hbmRfc2V0X2JpdChGTEdfTDFfREJVU1ksICZjcy0+SFdfRmxhZ3MpOwoJCQlzdHB0ciA9IGNzLT5zdGxpc3Q7CgkJCXNwaW5fdW5sb2NrX2lycXJlc3RvcmUoJmNzLT5sb2NrLCBmbGFncyk7CgkJCXdoaWxlIChzdHB0ciAhPSBOVUxMKSB7CgkJCQlzdHB0ci0+bDEubDFsMihzdHB0ciwgUEhfUEFVU0UgfCBJTkRJQ0FUSU9OLCBOVUxMKTsKCQkJCXN0cHRyID0gc3RwdHItPm5leHQ7CgkJCX0KCgkJfSBlbHNlIHsKCQkJLyogZGlzY2FyZCBmcmFtZTsgcmVzZXQgdHJhbnNjZWl2ZXIgKi8KCQkJdGVzdF9hbmRfY2xlYXJfYml0KEZMR19EQlVTWV9USU1FUiwgJmNzLT5IV19GbGFncyk7CgkJCWlmIChjcy0+dHhfc2tiKSB7CgkJCQlkZXZfa2ZyZWVfc2tiX2FueShjcy0+dHhfc2tiKTsKCQkJCWNzLT50eF9jbnQgPSAwOwoJCQkJY3MtPnR4X3NrYiA9IE5VTEw7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY3MtPmRjLmFtZDc5MzAudHhfeG10bGVuID0gMDsKCQkJfSBlbHNlIHsKCQkJCXByaW50ayhLRVJOX1dBUk5JTkcgIkhpU2F4OiBBbWQ3OTMwOiBELUNoYW5uZWwgQnVzeSBubyBza2JcbiIpOwoJCQkJZGVidWdsMShjcywgIkFtZDc5MzA6IEQtQ2hhbm5lbCBCdXN5IG5vIHNrYiIpOwoKCQkJfQoJCQkvKiBUcmFuc21pdHRlciByZXNldCwgYWJvcnQgdHJhbnNtaXQgKi8KCQkJd0J5dGVBTUQoY3MsIDB4MjEsIDB4ODIpOwoJCQl3Qnl0ZUFNRChjcywgMHgyMSwgMHgwMik7CgkJCXNwaW5fdW5sb2NrX2lycXJlc3RvcmUoJmNzLT5sb2NrLCBmbGFncyk7CgkJCWNzLT5pcnFfZnVuYyhjcy0+aXJxLCBjcywgTlVMTCk7CgogICAgICAgICAgICAgICAgICAgICAgICBpZiAoY3MtPmRlYnVnICYgTDFfREVCX0lTQUMpCgkJCQlkZWJ1Z2wxKGNzLCAiQW1kNzkzMDogZGJ1c3lfdGltZXJfaGFuZGxlcjogVHJhbnNtaXR0ZXIgcmVzZXQiKTsKCQl9Cgl9Cn0KCgoKdm9pZCBfX2RldmluaXQKQW1kNzkzMF9pbml0KHN0cnVjdCBJc2RuQ2FyZFN0YXRlICpjcykKewogICAgV09SRCAqcHRyOwogICAgQllURSBjbWQsIGNudDsKCiAgICAgICAgaWYgKGNzLT5kZWJ1ZyAmIEwxX0RFQl9JU0FDKQoJCWRlYnVnbDEoY3MsICJBbWQ3OTMwOiBpbml0YW1kIGNhbGxlZCIpOwoKICAgICAgICBjcy0+ZGMuYW1kNzkzMC50eF94bXRsZW4gPSAwOwogICAgICAgIGNzLT5kYy5hbWQ3OTMwLm9sZF9zdGF0ZSA9IDA7CiAgICAgICAgY3MtPmRjLmFtZDc5MzAubG1yMSA9IDB4NDA7CiAgICAgICAgY3MtPmRjLmFtZDc5MzAucGhfY29tbWFuZCA9IEFtZDc5MzBfcGhfY29tbWFuZDsKCWNzLT5zZXRzdGFja19kID0gc2V0c3RhY2tfQW1kNzkzMDsKCWNzLT5EQ19DbG9zZSA9IERDX0Nsb3NlX0FtZDc5MzA7CgoJLyogQU1EIEluaXRpYWxpc2F0aW9uICovCglmb3IgKHB0ciA9IGluaXRBTUQ7ICpwdHIgIT0gMHhGRkZGOyApIHsKCQljbWQgPSBMT0JZVEUoKnB0cik7CgogICAgICAgICAgICAgICAgLyogcmVhZCAqLwogICAgICAgICAgICAgICAgaWYgKCpwdHIrKyA+PSAweDEwMCkgewoJCQlpZiAoY21kIDwgOCkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBzZXR6dCBSZWdpc3RlciB6dXL8Y2sgKi8KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByQnl0ZUFNRChjcywgY21kKTsKCQkJZWxzZSB7CgkJCQl3Qnl0ZUFNRChjcywgMHgwMCwgY21kKTsKCQkJCWZvciAoY250ID0gKnB0cisrOyBjbnQgPiAwOyBjbnQtLSkKCQkJCQlyQnl0ZUFNRChjcywgMHgwMSk7CgkJCX0KCQl9CiAgICAgICAgICAgICAgICAvKiB3cml0ZSAqLwogICAgICAgICAgICAgICAgZWxzZSBpZiAoY21kIDwgOCkKCQkJd0J5dGVBTUQoY3MsIGNtZCwgTE9CWVRFKCpwdHIrKykpOwoKCQllbHNlIHsKCQkJd0J5dGVBTUQoY3MsIDB4MDAsIGNtZCk7CgkJCWZvciAoY250ID0gKnB0cisrOyBjbnQgPiAwOyBjbnQtLSkKCQkJCXdCeXRlQU1EKGNzLCAweDAxLCBMT0JZVEUoKnB0cisrKSk7CgkJfQoJfQp9Cgp2b2lkIF9fZGV2aW5pdApzZXR1cF9BbWQ3OTMwKHN0cnVjdCBJc2RuQ2FyZFN0YXRlICpjcykKewogICAgICAgIElOSVRfV09SSygmY3MtPnRxdWV1ZSwgKHZvaWQgKikodm9pZCAqKSBBbWQ3OTMwX2JoLCBjcyk7Cgljcy0+ZGJ1c3l0aW1lci5mdW5jdGlvbiA9ICh2b2lkICopIGRidXN5X3RpbWVyX2hhbmRsZXI7Cgljcy0+ZGJ1c3l0aW1lci5kYXRhID0gKGxvbmcpIGNzOwoJaW5pdF90aW1lcigmY3MtPmRidXN5dGltZXIpOwp9Cg==