LyogZ2VyZGVzX2FtZDc5MzAuYyx2IDAuOTkgMjAwMS8xMC8wMgogKgogKiBnZXJkZXNfYW1kNzkzMC5jICAgICBBbWQgNzlDMzBBIGFuZCA3OUMzMkEgc3BlY2lmaWMgcm91dGluZXMKICogICAgICAgICAgICAgICAgICAgICAgKGJhc2VkIG9uIEhpU2F4IGRyaXZlciBieSBLYXJzdGVuIEtlaWwpCiAqCiAqIEF1dGhvciAgICAgICAgICAgICAgIENocmlzdG9waCBFcnNmZWxkIDxpbmZvQGZvcm11bGEtbi5kZT4KICogICAgICAgICAgICAgICAgICAgICAgRm9ybXVsYS1uIEV1cm9wZSBBRyAod3d3LmZvcm11bGEtbi5jb20pCiAqICAgICAgICAgICAgICAgICAgICAgIHByZXZpb3VzbHkgR2VyZGVzIEFHCiAqCiAqCiAqICAgICAgICAgICAgICAgICAgICAgIFRoaXMgZmlsZSBpcyAoYykgdW5kZXIgR05VIFBVQkxJQyBMSUNFTlNFCiAqCiAqCiAqIE5vdGVzOgogKiBWZXJzaW9uIDAuOTkgaXMgdGhlIGZpcnN0IHJlbGVhc2Ugb2YgdGhpcyBkcml2ZXIgYW5kIHRoZXJlIGFyZQogKiBjZXJ0YWlubHkgYSBmZXcgYnVncy4KICoKICogUGxlYXNlIGRvbid0IHJlcG9ydCBhbnkgbWFsZnVuY3Rpb24gdG8gbWUgd2l0aG91dCBzZW5kaW5nCiAqIChjb21wcmVzc2VkKSBkZWJ1Zy1sb2dzLgogKiBJdCB3b3VsZCBiZSBuZWFybHkgaW1wb3NzaWJsZSB0byByZXRyYWNlIGl0LgogKgogKiBMb2cgRC1jaGFubmVsLXByb2Nlc3NpbmcgYXMgZm9sbG93czoKICoKICogMS4gTG9hZCBoaXNheCB3aXRoIGNhcmQtc3BlY2lmaWMgcGFyYW1ldGVycywgdGhpcyBleGFtcGxlIGlzdCBmb3IKICogICAgRm9ybXVsYS1uIGVudGVyOm5vdyBJU0ROIFBDSSBhbmQgY29tcGF0aWJsZQogKiAgICAoZi5lLiBHZXJkZXMgUG93ZXIgSVNETiBQQ0kpCiAqCiAqICAgIG1vZHByb2JlIGhpc2F4IHR5cGU9NDEgcHJvdG9jb2w9MiBpZD1nZXJkZXMKICoKICogICAgaWYgeW91IGNob3NlIGFuIG90aGVyIHZhbHVlIGZvciBpZCwgeW91IG5lZWQgdG8gbW9kaWZ5IHRoZQogKiAgICBjb2RlIGJlbG93LCB0b28uCiAqCiAqIDIuIHNldCBkZWJ1Zy1sZXZlbAogKgogKiAgICBoaXNheGN0cmwgZ2VyZGVzIDEgMHgzZmYKICogICAgaGlzYXhjdHJsIGdlcmRlcyAxMSAweDRmCiAqICAgIGNhdCAvZGV2L2lzZG5jdHJsID4+IH4vbG9nICYKICoKICogUGxlYXNlIHRha2UgYWxzbyBhIGxvb2sgaW50byAvdmFyL2xvZy9tZXNzYWdlcyBpZiB0aGVyZSBpcwogKiBhbnl0aGluZyBpbXBvcnRhbmQgY29uY2VybmluZyBISVNBWC4KICoKICoKICogQ3JlZGl0czoKICogUHJvZ3JhbW1pbmcgdGhlIGRyaXZlciBmb3IgRm9ybXVsYS1uIGVudGVyOm5vdyBJU0ROIFBDSSBhbmQKICogbmVjZXNzYXJ5IHRoaXMgZHJpdmVyIGZvciB0aGUgdXNlZCBBbWQgNzkzMCBELWNoYW5uZWwtY29udHJvbGxlcgogKiB3YXMgc3Buc29yZWQgYnkgRm9ybXVsYS1uIEV1cm9wZSBBRy4KICogVGhhbmtzIHRvIEthcnN0ZW4gS2VpbCBhbmQgUGV0ciBOb3Zhaywgd2hvIGdhdmUgbWUgc3VwcG9ydCBpbgogKiBIaXNheC1zcGVjaWZpYyBxdWVzdGlvbnMuCiAqIEkgd2FudCBzbyBzYXkgc3BlY2lhbCB0aGFua3MgdG8gQ2FybC1GcmllZHJpY2ggQnJhdW4sIHdobyBoYWQgdG8KICogYW5zd2VyIGEgbG90IG9mIHF1ZXN0aW9ucyBhYm91dCBnZW5lcmFsbHkgSVNETiBhbmQgYWJvdXQgaGFuZGxpbmcKICogb2YgdGhlIEFtZC1DaGlwLgogKgogKi8KCgojaW5jbHVkZSAiaGlzYXguaCIKI2luY2x1ZGUgImlzZG5sMS5oIgojaW5jbHVkZSAiaXNhYy5oIgojaW5jbHVkZSAiYW1kNzkzMF9mbi5oIgojaW5jbHVkZSA8bGludXgvaW50ZXJydXB0Lmg+CiNpbmNsdWRlIDxsaW51eC9pbml0Lmg+CgpzdGF0aWMgdm9pZCBBbWQ3OTMwX25ld19waChzdHJ1Y3QgSXNkbkNhcmRTdGF0ZSAqY3MpOwoKc3RhdGljIFdPUkQgaW5pdEFNRFtdID0gewoJMHgwMTAwLAoKCTB4MDBBNSwgMywgMHgwMSwgMHg0MCwgMHg1OCwJCQkJLy8gTFBSLCBMTVIxLCBMTVIyCgkweDAwODYsIDEsIDB4MEIsCQkJCQkvLyBETVIxIChELUJ1ZmZlciBUSC1JbnRlcnJ1cHRzIG9uKQoJMHgwMDg3LCAxLCAweEZGLAkJCQkJLy8gRE1SMgoJMHgwMDkyLCAxLCAweDAzLAkJCQkJLy8gRUZDUiAoZXh0ZW5kZWQgbW9kZSBkLWNoYW5uZWwtZmlmbyBvbikKCTB4MDA5MCwgNCwgMHhGRSwgMHhGRiwgMHgwMiwgMHgwRiwJCQkvLyBGUkFSNCwgU1JBUjQsIERNUjMsIERNUjQgKGFkZHJlc3MgcmVjb2duaXRpb24gKQoJMHgwMDg0LCAyLCAweDgwLCAweDAwLAkJCQkJLy8gRFJMUgoJMHgwMEMwLCAxLCAweDQ3LAkJCQkJLy8gUFBDUjEKCTB4MDBDOCwgMSwgMHgwMSwJCQkJCS8vIFBQQ1IyCgoJMHgwMTAyLAoJMHgwMTA3LAoJMHgwMUExLCAxLAoJMHgwMTIxLCAxLAoJMHgwMTg5LCAyLAoKCTB4MDA0NSwgNCwgMHg2MSwgMHg3MiwgMHgwMCwgMHgwMCwJCQkvLyBNQ1IxLCBNQ1IyLCBNQ1IzLCBNQ1I0CgkweDAwNjMsIDIsIDB4MDgsIDB4MDgsCQkJCQkvLyBHWAoJMHgwMDY0LCAyLCAweDA4LCAweDA4LAkJCQkJLy8gR1IKCTB4MDA2NSwgMiwgMHg5OSwgMHgwMCwJCQkJCS8vIEdFUgoJMHgwMDY2LCAyLCAweDdDLCAweDhCLAkJCQkJLy8gU1RHCgkweDAwNjcsIDIsIDB4MDAsIDB4MDAsCQkJCQkvLyBGVEdSMSwgRlRHUjIKCTB4MDA2OCwgMiwgMHgyMCwgMHgyMCwJCQkJCS8vIEFUR1IxLCBBVEdSMgoJMHgwMDY5LCAxLCAweDRGLAkJCQkJLy8gTU1SMQoJMHgwMDZBLCAxLCAweDAwLAkJCQkJLy8gTU1SMgoJMHgwMDZDLCAxLCAweDQwLAkJCQkJLy8gTU1SMwoJMHgwMDIxLCAxLCAweDAyLAkJCQkJLy8gSU5JVAoJMHgwMEEzLCAxLCAweDQwLAkJCQkJLy8gTE1SMQoKCTB4RkZGRgp9OwoKCnN0YXRpYyB2b2lkIC8qIG1hY3JvIHdXb3JkQU1EICovCldyaXRlV29yZEFtZDc5MzAoc3RydWN0IElzZG5DYXJkU3RhdGUgKmNzLCBCWVRFIHJlZywgV09SRCB2YWwpCnsKICAgICAgICB3Qnl0ZUFNRChjcywgMHgwMCwgcmVnKTsKICAgICAgICB3Qnl0ZUFNRChjcywgMHgwMSwgTE9CWVRFKHZhbCkpOwogICAgICAgIHdCeXRlQU1EKGNzLCAweDAxLCBISUJZVEUodmFsKSk7Cn0KCnN0YXRpYyBXT1JEIC8qIG1hY3JvIHJXb3JkQU1EICovClJlYWRXb3JkQW1kNzkzMChzdHJ1Y3QgSXNkbkNhcmRTdGF0ZSAqY3MsIEJZVEUgcmVnKQp7CiAgICAgICAgV09SRCByZXM7CiAgICAgICAgLyogZGlyZWN0IGFjY2VzcyByZWdpc3RlciAqLwogICAgICAgIGlmKHJlZyA8IDgpIHsKICAgICAgICAJcmVzID0gckJ5dGVBTUQoY3MsIHJlZyk7CiAgICAgICAgICAgICAgICByZXMgKz0gMjU2KnJCeXRlQU1EKGNzLCByZWcpOwogICAgICAgIH0KICAgICAgICAvKiBpbmRpcmVjdCBhY2Nlc3MgcmVnaXN0ZXIgKi8KICAgICAgICBlbHNlIHsKICAgICAgICAgICAgICAgIHdCeXRlQU1EKGNzLCAweDAwLCByZWcpOwoJICAgICAgICByZXMgPSByQnl0ZUFNRChjcywgMHgwMSk7CiAgICAgICAgICAgICAgICByZXMgKz0gMjU2KnJCeXRlQU1EKGNzLCAweDAxKTsKICAgICAgICB9CglyZXR1cm4gKHJlcyk7Cn0KCgpzdGF0aWMgdm9pZApBbWQ3OTMwX3BoX2NvbW1hbmQoc3RydWN0IElzZG5DYXJkU3RhdGUgKmNzLCB1X2NoYXIgY29tbWFuZCwgY2hhciAqcykKewoJaWYgKGNzLT5kZWJ1ZyAmIEwxX0RFQl9JU0FDKQoJCWRlYnVnbDEoY3MsICJBTUQ3OTMwOiAlczogcGhfY29tbWFuZCAweCUwMlgiLCBzLCBjb21tYW5kKTsKCiAgICAgICAgY3MtPmRjLmFtZDc5MzAubG1yMSA9IGNvbW1hbmQ7CiAgICAgICAgd0J5dGVBTUQoY3MsIDB4QTMsIGNvbW1hbmQpOwp9CgoKCnN0YXRpYyBCWVRFIGk0MzBTdGF0ZXNbXSA9IHsKLy8gdG8gICByZXNldCAgRjMgICAgRjQgICAgRjUgICAgRjYgICAgRjcgICAgRjggICAgQVIgICAgIGZyb20KICAgICAgICAweDAxLCAweDAyLCAweDAwLCAweDAwLCAweDAwLCAweDA3LCAweDA1LCAweDAwLCAgIC8vIGluaXQKICAgICAgICAweDAxLCAweDAyLCAweDAwLCAweDAwLCAweDAwLCAweDA3LCAweDA1LCAweDAwLCAgIC8vIHJlc2V0CiAgICAgICAgMHgwMSwgMHgwMiwgMHgwMCwgMHgwMCwgMHgwMCwgMHgwOSwgMHgwNSwgMHgwNCwgICAvLyBGMwogICAgICAgIDB4MDEsIDB4MDIsIDB4MDAsIDB4MDAsIDB4MUIsIDB4MDAsIDB4MDAsIDB4MDAsICAgLy8gRjQKICAgICAgICAweDAxLCAweDAyLCAweDAwLCAweDAwLCAweDFCLCAweDAwLCAweDAwLCAweDAwLCAgIC8vIEY1CiAgICAgICAgMHgwMSwgMHgwMywgMHgwMCwgMHgwMCwgMHgwMCwgMHgwNiwgMHgwNSwgMHgwMCwgICAvLyBGNgogICAgICAgIDB4MTEsIDB4MTMsIDB4MDAsIDB4MDAsIDB4MUIsIDB4MDAsIDB4MTUsIDB4MDAsICAgLy8gRjcKICAgICAgICAweDAxLCAweDAzLCAweDAwLCAweDAwLCAweDAwLCAweDA2LCAweDAwLCAweDAwLCAgIC8vIEY4CiAgICAgICAgMHgwMSwgMHgwMywgMHgwMCwgMHgwMCwgMHgwMCwgMHgwOSwgMHgwMCwgMHgwQX07ICAvLyBBUgoKCi8qICAgICAgICAgICAgICAgICAgICBSb3cgICAgIGluaXQgICAgLSAgIHJlc2V0ICBGMyAgICBGNCAgICBGNSAgICBGNiAgICBGNyAgICBGOCAgICBBUiAqLwpzdGF0aWMgQllURSBzdGF0ZUhlbHBlcltdID0geyAweDAwLCAweDAwLCAweDAxLCAweDAyLCAweDAzLCAweDA0LCAweDA1LCAweDA2LCAweDA3LCAweDA4IH07CgoKCgpzdGF0aWMgdm9pZApBbWQ3OTMwX2dldF9zdGF0ZShzdHJ1Y3QgSXNkbkNhcmRTdGF0ZSAqY3MpIHsKICAgICAgICBCWVRFIGxzciA9IHJCeXRlQU1EKGNzLCAweEExKTsKICAgICAgICBjcy0+ZGMuYW1kNzkzMC5waF9zdGF0ZSA9IChsc3IgJiAweDcpICsgMjsKICAgICAgICBBbWQ3OTMwX25ld19waChjcyk7Cn0KCgoKc3RhdGljIHZvaWQKQW1kNzkzMF9uZXdfcGgoc3RydWN0IElzZG5DYXJkU3RhdGUgKmNzKQp7CiAgICAgICAgdV9jaGFyIGluZGV4ID0gc3RhdGVIZWxwZXJbY3MtPmRjLmFtZDc5MzAub2xkX3N0YXRlXSo4ICsgc3RhdGVIZWxwZXJbY3MtPmRjLmFtZDc5MzAucGhfc3RhdGVdLTE7CiAgICAgICAgdV9jaGFyIG1lc3NhZ2UgPSBpNDMwU3RhdGVzW2luZGV4XTsKCiAgICAgICAgaWYgKGNzLT5kZWJ1ZyAmIEwxX0RFQl9JU0FDKQoJCWRlYnVnbDEoY3MsICJBTUQ3OTMwOiBuZXdfcGggJWQsIG9sZF9waCAlZCwgbWVzc2FnZSAlZCwgaW5kZXggJWQiLAogICAgICAgICAgICAgICAgICAgICAgICBjcy0+ZGMuYW1kNzkzMC5waF9zdGF0ZSwgY3MtPmRjLmFtZDc5MzAub2xkX3N0YXRlLCBtZXNzYWdlICYgMHgwZiwgaW5kZXgpOwoKICAgICAgICBjcy0+ZGMuYW1kNzkzMC5vbGRfc3RhdGUgPSBjcy0+ZGMuYW1kNzkzMC5waF9zdGF0ZTsKCiAgICAgICAgLyogYWJvcnQgdHJhbnNtaXQgaWYgbmVzc2VzYXJ5ICovCiAgICAgICAgaWYgKChtZXNzYWdlICYgMHhmMCkgJiYgKGNzLT50eF9za2IpKSB7CiAgICAgICAgICAgICAgICB3Qnl0ZUFNRChjcywgMHgyMSwgMHhDMik7CiAgICAgICAgICAgICAgICB3Qnl0ZUFNRChjcywgMHgyMSwgMHgwMik7CiAgICAgICAgfQoKCXN3aXRjaCAobWVzc2FnZSAmIDB4MGYpIHsKCiAgICAgICAgICAgICAgICBjYXNlICgxKToKICAgICAgICAgICAgICAgICAgICAgICAgbDFfbXNnKGNzLCBIV19SRVNFVCB8IElORElDQVRJT04sIE5VTEwpOwogICAgICAgICAgICAgICAgICAgICAgICBBbWQ3OTMwX2dldF9zdGF0ZShjcyk7CiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSAoMik6IC8qIGluaXQsIENhcmQgc3RhcnRzIGluIEYzICovCiAgICAgICAgICAgICAgICAgICAgICAgIGwxX21zZyhjcywgSFdfREVBQ1RJVkFURSB8IENPTkZJUk0sIE5VTEwpOwogICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgKDMpOgogICAgICAgICAgICAgICAgICAgICAgICBsMV9tc2coY3MsIEhXX0RFQUNUSVZBVEUgfCBJTkRJQ0FUSU9OLCBOVUxMKTsKICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlICg0KToKICAgICAgICAgICAgICAgICAgICAgICAgbDFfbXNnKGNzLCBIV19QT1dFUlVQIHwgQ09ORklSTSwgTlVMTCk7CiAgICAgICAgICAgICAgICAgICAgICAgIEFtZDc5MzBfcGhfY29tbWFuZChjcywgMHg1MCwgIkhXX0VOQUJMRSBSRVFVRVNUIik7CiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSAoNSk6CgkJCWwxX21zZyhjcywgSFdfUlNZTkMgfCBJTkRJQ0FUSU9OLCBOVUxMKTsKICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlICg2KToKCQkJbDFfbXNnKGNzLCBIV19JTkZPNF9QOCB8IElORElDQVRJT04sIE5VTEwpOwogICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgKDcpOiAvKiBpbml0LCBDYXJkIHN0YXJ0cyBpbiBGNyAqLwoJCQlsMV9tc2coY3MsIEhXX1JTWU5DIHwgSU5ESUNBVElPTiwgTlVMTCk7CgkJCWwxX21zZyhjcywgSFdfSU5GTzRfUDggfCBJTkRJQ0FUSU9OLCBOVUxMKTsKICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlICg4KToKICAgICAgICAgICAgICAgICAgICAgICAgbDFfbXNnKGNzLCBIV19QT1dFUlVQIHwgQ09ORklSTSwgTlVMTCk7CiAgICAgICAgICAgICAgICAgICAgICAgIC8qIGZhbGwgdGhyb3VnaCAqLwogICAgICAgICAgICAgICAgY2FzZSAoOSk6CiAgICAgICAgICAgICAgICAgICAgICAgIEFtZDc5MzBfcGhfY29tbWFuZChjcywgMHg0MCwgIkhXX0VOQUJMRSBSRVEgY2xlYXJlZCBpZiBzZXQiKTsKCQkJbDFfbXNnKGNzLCBIV19SU1lOQyB8IElORElDQVRJT04sIE5VTEwpOwoJCQlsMV9tc2coY3MsIEhXX0lORk8yIHwgSU5ESUNBVElPTiwgTlVMTCk7CgkJCWwxX21zZyhjcywgSFdfSU5GTzRfUDggfCBJTkRJQ0FUSU9OLCBOVUxMKTsKICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlICgxMCk6CiAgICAgICAgICAgICAgICAgICAgICAgIEFtZDc5MzBfcGhfY29tbWFuZChjcywgMHg0MCwgIlQzIGV4cGlyZWQsIEhXX0VOQUJMRSBSRVEgY2xlYXJlZCIpOwogICAgICAgICAgICAgICAgICAgICAgICBjcy0+ZGMuYW1kNzkzMC5vbGRfc3RhdGUgPSAzOwogICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgKDExKToKCQkJbDFfbXNnKGNzLCBIV19JTkZPMiB8IElORElDQVRJT04sIE5VTEwpOwogICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKCQlkZWZhdWx0OgoJCQlicmVhazsKCX0KfQoKCgpzdGF0aWMgdm9pZApBbWQ3OTMwX2JoKHN0cnVjdCBJc2RuQ2FyZFN0YXRlICpjcykKewoKICAgICAgICBzdHJ1Y3QgUFN0YWNrICpzdHB0cjsKCglpZiAoIWNzKQoJCXJldHVybjsKCWlmICh0ZXN0X2FuZF9jbGVhcl9iaXQoRF9DTEVBUkJVU1ksICZjcy0+ZXZlbnQpKSB7CiAgICAgICAgICAgICAgICBpZiAoY3MtPmRlYnVnKQoJCQlkZWJ1Z2wxKGNzLCAiQW1kNzkzMDogYmgsIEQtQ2hhbm5lbCBCdXN5IGNsZWFyZWQiKTsKCQlzdHB0ciA9IGNzLT5zdGxpc3Q7CgkJd2hpbGUgKHN0cHRyICE9IE5VTEwpIHsKCQkJc3RwdHItPmwxLmwxbDIoc3RwdHIsIFBIX1BBVVNFIHwgQ09ORklSTSwgTlVMTCk7CgkJCXN0cHRyID0gc3RwdHItPm5leHQ7CgkJfQoJfQoJaWYgKHRlc3RfYW5kX2NsZWFyX2JpdChEX0wxU1RBVEVDSEFOR0UsICZjcy0+ZXZlbnQpKSB7CgkgICAgICAgIGlmIChjcy0+ZGVidWcgJiBMMV9ERUJfSVNBQykKCQkgICAgICAgIGRlYnVnbDEoY3MsICJBTUQ3OTMwOiBiaCwgRF9MMVNUQVRFQ0hBTkdFIik7CiAgICAgICAgICAgICAgICBBbWQ3OTMwX25ld19waChjcyk7CiAgICAgICAgfQoKICAgICAgICBpZiAodGVzdF9hbmRfY2xlYXJfYml0KERfUkNWQlVGUkVBRFksICZjcy0+ZXZlbnQpKSB7CgkgICAgICAgIGlmIChjcy0+ZGVidWcgJiBMMV9ERUJfSVNBQykKCQkgICAgICAgIGRlYnVnbDEoY3MsICJBTUQ3OTMwOiBiaCwgRF9SQ1ZCVUZSRUFEWSIpOwogICAgICAgICAgICAgICAgRENoYW5uZWxfcHJvY19yY3YoY3MpOwogICAgICAgIH0KCiAgICAgICAgaWYgKHRlc3RfYW5kX2NsZWFyX2JpdChEX1hNVEJVRlJFQURZLCAmY3MtPmV2ZW50KSkgewoJICAgICAgICBpZiAoY3MtPmRlYnVnICYgTDFfREVCX0lTQUMpCgkJICAgICAgICBkZWJ1Z2wxKGNzLCAiQU1ENzkzMDogYmgsIERfWE1UQlVGUkVBRFkiKTsKICAgICAgICAgICAgICAgIERDaGFubmVsX3Byb2NfeG10KGNzKTsKICAgICAgICB9Cn0KCnN0YXRpYyB2b2lkCkFtZDc5MzBfZW1wdHlfRGZpZm8oc3RydWN0IElzZG5DYXJkU3RhdGUgKmNzLCBpbnQgZmxhZykKewoKICAgICAgICBCWVRFIHN0YXQsIGRlcjsKCUJZVEUgKnB0cjsKCXN0cnVjdCBza19idWZmICpza2I7CgoKCWlmICgoY3MtPmRlYnVnICYgTDFfREVCX0lTQUMpICYmICEoY3MtPmRlYnVnICYgTDFfREVCX0lTQUNfRklGTykpCgkJZGVidWdsMShjcywgIkFtZDc5MzA6IGVtcHR5X0RmaWZvIik7CgoKCXB0ciA9IGNzLT5yY3ZidWYgKyBjcy0+cmN2aWR4OwoKCS8qIEFNRCBpbnRlcnJ1cHRzIG9mZiAqLwoJQW1kSXJxT2ZmKGNzKTsKCgkvKiByZWFkIEQtQ2hhbm5lbC1GaWZvKi8KCXN0YXQgPSByQnl0ZUFNRChjcywgMHgwNyk7IC8vIERTUjIKCgkJLyogd2hpbGUgRGF0YSBpbiBGaWZvIC4uLiAqLwoJCXdoaWxlICggKHN0YXQgJiAyKSAmJiAoKHB0ci1jcy0+cmN2YnVmKSA8IE1BWF9ERlJBTUVfTEVOX0wxKSApIHsKCQkJKnB0ciA9IHJCeXRlQU1EKGNzLCAweDA0KTsgLy8gRENSQgoJCQlwdHIrKzsKCSAgICAgICAgICAgICAgICBzdGF0ID0gckJ5dGVBTUQoY3MsIDB4MDcpOyAvLyBEU1IyCgkJCWNzLT5yY3ZpZHggPSBwdHIgLSBjcy0+cmN2YnVmOwoKICAgICAgICAgICAgICAgICAgICAgICAgLyogUGFrZXQgcmVhZHk/ICovCgkJCWlmIChzdGF0ICYgMSkgewoKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZXIgPSByV29yZEFNRChjcywgMHgwMyk7CgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIG5vIGVycm9ycywgcGFja2V0IG9rICovCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYoIWRlciAmJiAhZmxhZykgewoJCQkJCXJXb3JkQU1EKGNzLCAweDg5KTsgLy8gY2xlYXIgRFJDUgoKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICgoY3MtPnJjdmlkeCkgPiAwKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICghKHNrYiA9IGFsbG9jX3NrYihjcy0+cmN2aWR4LCBHRlBfQVRPTUlDKSkpCgkJCQkJCQlwcmludGsoS0VSTl9XQVJOSU5HICJIaVNheDogQW1kNzkzMDogZW1wdHlfRGZpZm8sIEQgcmVjZWl2ZSBvdXQgb2YgbWVtb3J5IVxuIik7CgkJCQkJCWVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIERlYnVnZ2luZyAqLwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChjcy0+ZGVidWcgJiBMMV9ERUJfSVNBQ19GSUZPKSB7CgkJCQkJCQkJY2hhciAqdCA9IGNzLT5kbG9nOwoKCQkJCQkJCQl0ICs9IHNwcmludGYodCwgIkFtZDc5MzA6IGVtcHR5X0RmaWZvIGNudDogJWQgfCIsIGNzLT5yY3ZpZHgpOwoJCQkJCQkJCVF1aWNrSGV4KHQsIGNzLT5yY3ZidWYsIGNzLT5yY3ZpZHgpOwoJCQkJCQkJCWRlYnVnbDEoY3MsIGNzLT5kbG9nKTsKCQkJCQkJCX0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBtb3ZlcyByZWNlaXZlZCBkYXRhIGluIHNrLWJ1ZmZlciAqLwoJCQkJCQkJbWVtY3B5KHNrYl9wdXQoc2tiLCBjcy0+cmN2aWR4KSwgY3MtPnJjdmJ1ZiwgY3MtPnJjdmlkeCk7CgkJCQkJCQlza2JfcXVldWVfdGFpbCgmY3MtPnJxLCBza2IpOwoJCQkJCQl9CgkJCQkJfQoKCQkJCX0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0aHJvdyBkYW1hZ2VkIHBhY2tldHMgYXdheSwgcmVzZXQgcmVjZWl2ZS1idWZmZXIsIGluZGljYXRlIFJYICovCgkJCQlwdHIgPSBjcy0+cmN2YnVmOwoJCQkJY3MtPnJjdmlkeCA9IDA7CgkJCQlzY2hlZHVsZV9ldmVudChjcywgRF9SQ1ZCVUZSRUFEWSk7CgkJCX0KICAgICAgICAgICAgICAgIH0KCQkvKiBQYWNrZXQgdG8gbG9uZywgb3ZlcmZsb3cgKi8KCQlpZihjcy0+cmN2aWR4ID49IE1BWF9ERlJBTUVfTEVOX0wxKSB7CgkJCWlmIChjcy0+ZGVidWcgJiBMMV9ERUJfV0FSTikKCQkJICAgICAgICBkZWJ1Z2wxKGNzLCAiQU1ENzkzMDogZW1wdHlfRGZpZm8gTDItRnJhbWVsZW5ndGggb3ZlcnJ1biIpOwoJCQljcy0+cmN2aWR4ID0gMDsKCQkJcmV0dXJuOwoJCX0KCS8qIEFNRCBpbnRlcnJ1cHRzIG9uICovCglBbWRJcnFPbihjcyk7Cn0KCgpzdGF0aWMgdm9pZApBbWQ3OTMwX2ZpbGxfRGZpZm8oc3RydWN0IElzZG5DYXJkU3RhdGUgKmNzKQp7CgogICAgICAgIFdPUkQgZHRjcnIsIGR0Y3J3LCBsZW4sIGNvdW50OwogICAgICAgIEJZVEUgdHhzdGF0LCBkbXIzOwogICAgICAgIEJZVEUgKnB0ciwgKmRlYl9wdHI7CgoJaWYgKChjcy0+ZGVidWcgJiBMMV9ERUJfSVNBQykgJiYgIShjcy0+ZGVidWcgJiBMMV9ERUJfSVNBQ19GSUZPKSkKCQlkZWJ1Z2wxKGNzLCAiQW1kNzkzMDogZmlsbF9EZmlmbyIpOwoKCWlmICgoIWNzLT50eF9za2IpIHx8IChjcy0+dHhfc2tiLT5sZW4gPD0gMCkpCgkJcmV0dXJuOwoKICAgICAgICBkdGNydyA9IDA7CiAgICAgICAgaWYoIWNzLT5kYy5hbWQ3OTMwLnR4X3htdGxlbikKICAgICAgICAgICAgICAgIC8qIG5ldyBGcmFtZSAqLwogICAgICAgICAgICAgICAgbGVuID0gZHRjcncgPSBjcy0+dHhfc2tiLT5sZW47CiAgICAgICAgLyogY29udGludWUgZnJhbWUgKi8KICAgICAgICBlbHNlIGxlbiA9IGNzLT5kYy5hbWQ3OTMwLnR4X3htdGxlbjsKCgoJLyogQU1EIGludGVycnVwdHMgb2ZmICovCglBbWRJcnFPZmYoY3MpOwoKICAgICAgICBkZWJfcHRyID0gcHRyID0gY3MtPnR4X3NrYi0+ZGF0YTsKCiAgICAgICAgLyogd2hpbGUgZnJlZSBwbGFjZSBpbiB0eC1maWZvIGF2YWlsYWJsZSBhbmQgZGF0YSBpbiBzay1idWZmZXIgKi8KICAgICAgICB0eHN0YXQgPSAweDEwOwogICAgICAgIHdoaWxlKCh0eHN0YXQgJiAweDEwKSAmJiAoY3MtPnR4X2NudCA8IGxlbikpIHsKICAgICAgICAgICAgICAgIHdCeXRlQU1EKGNzLCAweDA0LCAqcHRyKTsKICAgICAgICAgICAgICAgIHB0cisrOwogICAgICAgICAgICAgICAgY3MtPnR4X2NudCsrOwogICAgICAgICAgICAgICAgdHhzdGF0PSByQnl0ZUFNRChjcywgMHgwNyk7CiAgICAgICAgfQogICAgICAgIGNvdW50ID0gcHRyIC0gY3MtPnR4X3NrYi0+ZGF0YTsKCXNrYl9wdWxsKGNzLT50eF9za2IsIGNvdW50KTsKCgogICAgICAgIGR0Y3JyID0gcldvcmRBTUQoY3MsIDB4ODUpOyAvLyBEVENSCiAgICAgICAgZG1yMyAgPSByQnl0ZUFNRChjcywgMHg4RSk7CgoJaWYgKGNzLT5kZWJ1ZyAmIEwxX0RFQl9JU0FDKSB7CgkJZGVidWdsMShjcywgIkFtZDc5MzA6IGZpbGxfRGZpZm8sIERNUjM6IDB4JTAyWCwgRFRDUiByZWFkOiAweCUwNFggd3JpdGU6IDB4JTAyWCAweCUwMlgiLCBkbXIzLCBkdGNyciwgTE9CWVRFKGR0Y3J3KSwgSElCWVRFKGR0Y3J3KSk7CiAgICAgICAgfQoKICAgICAgICAvKiB3cml0ZWluZyBvZiBkdGNydyBzdGFydHMgdHJhbnNtaXQgKi8KICAgICAgICBpZighY3MtPmRjLmFtZDc5MzAudHhfeG10bGVuKSB7CiAgICAgICAgICAgICAgICB3V29yZEFNRChjcywgMHg4NSwgZHRjcncpOwogICAgICAgICAgICAgICAgY3MtPmRjLmFtZDc5MzAudHhfeG10bGVuID0gZHRjcnc7CiAgICAgICAgfQoKCWlmICh0ZXN0X2FuZF9zZXRfYml0KEZMR19EQlVTWV9USU1FUiwgJmNzLT5IV19GbGFncykpIHsKCQlkZWJ1Z2wxKGNzLCAiQW1kNzkzMDogZmlsbF9EZmlmbyBkYnVzeXRpbWVyIHJ1bm5pbmciKTsKCQlkZWxfdGltZXIoJmNzLT5kYnVzeXRpbWVyKTsKCX0KCWluaXRfdGltZXIoJmNzLT5kYnVzeXRpbWVyKTsKCWNzLT5kYnVzeXRpbWVyLmV4cGlyZXMgPSBqaWZmaWVzICsgKChEQlVTWV9USU1FUl9WQUxVRSAqIEhaKSAvIDEwMDApOwoJYWRkX3RpbWVyKCZjcy0+ZGJ1c3l0aW1lcik7CgoJaWYgKGNzLT5kZWJ1ZyAmIEwxX0RFQl9JU0FDX0ZJRk8pIHsKCQljaGFyICp0ID0gY3MtPmRsb2c7CgoJCXQgKz0gc3ByaW50Zih0LCAiQW1kNzkzMDogZmlsbF9EZmlmbyBjbnQ6ICVkIHwiLCBjb3VudCk7CgkJUXVpY2tIZXgodCwgZGViX3B0ciwgY291bnQpOwoJCWRlYnVnbDEoY3MsIGNzLT5kbG9nKTsKCX0KCS8qIEFNRCBpbnRlcnJ1cHRzIG9uICovCiAgICAgICAgQW1kSXJxT24oY3MpOwp9CgoKdm9pZCBBbWQ3OTMwX2ludGVycnVwdChzdHJ1Y3QgSXNkbkNhcmRTdGF0ZSAqY3MsIEJZVEUgaXJmbGFncykKewoJQllURSBkc3IxLCBkc3IyLCBsc3I7CiAgICAgICAgV09SRCBkZXI7Cgogd2hpbGUgKGlyZmxhZ3MpCiB7CgogICAgICAgIGRzcjEgPSByQnl0ZUFNRChjcywgMHgwMik7CiAgICAgICAgZGVyICA9IHJXb3JkQU1EKGNzLCAweDAzKTsKICAgICAgICBkc3IyID0gckJ5dGVBTUQoY3MsIDB4MDcpOwogICAgICAgIGxzciAgPSByQnl0ZUFNRChjcywgMHhBMSk7CgoJaWYgKGNzLT5kZWJ1ZyAmIEwxX0RFQl9JU0FDKQoJCWRlYnVnbDEoY3MsICJBbWQ3OTMwOiBpbnRlcnJ1cHQ6IGZsYWdzOiAweCUwMlgsIERTUjE6IDB4JTAyWCwgRFNSMjogMHglMDJYLCBMU1I6IDB4JTAyWCwgREVSPTB4JTA0WCIsIGlyZmxhZ3MsIGRzcjEsIGRzcjIsIGxzciwgZGVyKTsKCiAgICAgICAgLyogRCBlcnJvciAtPiByZWFkIERFUiBhbmQgRFNSMiBiaXQgMiAqLwoJaWYgKGRlciB8fCAoZHNyMiAmIDQpKSB7CgogICAgICAgICAgICAgICAgaWYgKGNzLT5kZWJ1ZyAmIEwxX0RFQl9XQVJOKQoJCQlkZWJ1Z2wxKGNzLCAiQW1kNzkzMDogaW50ZXJydXB0OiBEIGVycm9yIERFUj0weCUwNFgiLCBkZXIpOwoKICAgICAgICAgICAgICAgIC8qIFJYLCBUWCBhYm9ydCBpZiBjb2xsaXNpb24gZGV0ZWN0ZWQgKi8KICAgICAgICAgICAgICAgIGlmIChkZXIgJiAyKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHdCeXRlQU1EKGNzLCAweDIxLCAweEMyKTsKICAgICAgICAgICAgICAgICAgICAgICAgd0J5dGVBTUQoY3MsIDB4MjEsIDB4MDIpOwoJCQlpZiAodGVzdF9hbmRfY2xlYXJfYml0KEZMR19EQlVTWV9USU1FUiwgJmNzLT5IV19GbGFncykpCgkJCQlkZWxfdGltZXIoJmNzLT5kYnVzeXRpbWVyKTsKCQkJaWYgKHRlc3RfYW5kX2NsZWFyX2JpdChGTEdfTDFfREJVU1ksICZjcy0+SFdfRmxhZ3MpKQoJCQkJc2NoZWR1bGVfZXZlbnQoY3MsIERfQ0xFQVJCVVNZKTsKICAgICAgICAgICAgICAgICAgICAgICAgLyogcmVzdGFydCBmcmFtZSAqLwogICAgICAgICAgICAgICAgICAgICAgICBpZiAoY3MtPnR4X3NrYikgewoJCQkJc2tiX3B1c2goY3MtPnR4X3NrYiwgY3MtPnR4X2NudCk7CgkJCQljcy0+dHhfY250ID0gMDsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjcy0+ZGMuYW1kNzkzMC50eF94bXRsZW4gPSAwOwoJCQkJQW1kNzkzMF9maWxsX0RmaWZvKGNzKTsKCQkJfSBlbHNlIHsKCQkJCXByaW50ayhLRVJOX1dBUk5JTkcgIkhpU2F4OiBBbWQ3OTMwIEQtQ29sbGlzaW9uLCBubyBza2JcbiIpOwoJCQkJZGVidWdsMShjcywgIkFtZDc5MzA6IGludGVycnVwdDogRC1Db2xsaXNpb24sIG5vIHNrYiIpOwoJCQl9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAvKiByZW1vdmUgZGFtYWdlZCBkYXRhIGZyb20gZmlmbyAqLwoJCUFtZDc5MzBfZW1wdHlfRGZpZm8oY3MsIDEpOwoKCQlpZiAodGVzdF9hbmRfY2xlYXJfYml0KEZMR19EQlVTWV9USU1FUiwgJmNzLT5IV19GbGFncykpCgkJCWRlbF90aW1lcigmY3MtPmRidXN5dGltZXIpOwoJCWlmICh0ZXN0X2FuZF9jbGVhcl9iaXQoRkxHX0wxX0RCVVNZLCAmY3MtPkhXX0ZsYWdzKSkKCQkJc2NoZWR1bGVfZXZlbnQoY3MsIERfQ0xFQVJCVVNZKTsKICAgICAgICAgICAgICAgIC8qIHJlc3RhcnQgVFgtRnJhbWUgKi8KICAgICAgICAgICAgICAgIGlmIChjcy0+dHhfc2tiKSB7CgkJCXNrYl9wdXNoKGNzLT50eF9za2IsIGNzLT50eF9jbnQpOwoJCQljcy0+dHhfY250ID0gMDsKICAgICAgICAgICAgICAgICAgICAgICAgY3MtPmRjLmFtZDc5MzAudHhfeG10bGVuID0gMDsKCQkJQW1kNzkzMF9maWxsX0RmaWZvKGNzKTsKCQl9Cgl9CgogICAgICAgIC8qIEQgVFggRklGTyBlbXB0eSAtPiBmaWxsICovCglpZiAoaXJmbGFncyAmIDEpIHsKCQlpZiAoY3MtPmRlYnVnICYgTDFfREVCX0lTQUMpCgkJCWRlYnVnbDEoY3MsICJBbWQ3OTMwOiBpbnRlcnJ1cHQ6IGNsZWFyIFRpbWVyIGFuZCBmaWxsIEQtVFgtRklGTyBpZiBkYXRhIik7CgoJCS8qIEFNRCBpbnRlcnJ1cHRzIG9mZiAqLwogICAgICAgICAgICAgICAgQW1kSXJxT2ZmKGNzKTsKCiAgICAgICAgICAgICAgICBpZiAodGVzdF9hbmRfY2xlYXJfYml0KEZMR19EQlVTWV9USU1FUiwgJmNzLT5IV19GbGFncykpCgkJCWRlbF90aW1lcigmY3MtPmRidXN5dGltZXIpOwoJCWlmICh0ZXN0X2FuZF9jbGVhcl9iaXQoRkxHX0wxX0RCVVNZLCAmY3MtPkhXX0ZsYWdzKSkKCQkJc2NoZWR1bGVfZXZlbnQoY3MsIERfQ0xFQVJCVVNZKTsKCQlpZiAoY3MtPnR4X3NrYikgewoJCQlpZiAoY3MtPnR4X3NrYi0+bGVuKQoJCQkJQW1kNzkzMF9maWxsX0RmaWZvKGNzKTsKCQl9CgkJLyogQU1EIGludGVycnVwdHMgb24gKi8KICAgICAgICAgICAgICAgIEFtZElycU9uKGNzKTsKCX0KCgogICAgICAgIC8qIEQgUlggRklGTyBmdWxsIG9yIHRpbnkgcGFja2V0IGluIEZpZm8gLT4gZW1wdHkgKi8KCWlmICgoaXJmbGFncyAmIDIpIHx8IChkc3IxICYgMikpIHsKICAgICAgICAgICAgICAgIGlmIChjcy0+ZGVidWcgJiBMMV9ERUJfSVNBQykKCQkJZGVidWdsMShjcywgIkFtZDc5MzA6IGludGVycnVwdDogZW1wdHkgRC1GSUZPIik7CiAgICAgICAgICAgICAgICBBbWQ3OTMwX2VtcHR5X0RmaWZvKGNzLCAwKTsKCX0KCgogICAgICAgIC8qIEQtRnJhbWUgdHJhbnNtaXQgY29tcGxldGUgKi8KCWlmIChkc3IxICYgNjQpIHsKCQlpZiAoY3MtPmRlYnVnICYgTDFfREVCX0lTQUMpIHsKCQkJZGVidWdsMShjcywgIkFtZDc5MzA6IGludGVycnVwdDogdHJhbnNtaXQgcGFja2V0IHJlYWR5Iik7CiAgICAgICAgCX0KCQkvKiBBTUQgaW50ZXJydXB0cyBvZmYgKi8KICAgICAgICAgICAgICAgIEFtZElycU9mZihjcyk7CgogICAgICAgICAgICAgICAgaWYgKHRlc3RfYW5kX2NsZWFyX2JpdChGTEdfREJVU1lfVElNRVIsICZjcy0+SFdfRmxhZ3MpKQoJCQlkZWxfdGltZXIoJmNzLT5kYnVzeXRpbWVyKTsKCQlpZiAodGVzdF9hbmRfY2xlYXJfYml0KEZMR19MMV9EQlVTWSwgJmNzLT5IV19GbGFncykpCgkJCXNjaGVkdWxlX2V2ZW50KGNzLCBEX0NMRUFSQlVTWSk7CgogICAgICAgICAgICAgICAgaWYgKGNzLT50eF9za2IpIHsKICAgICAgICAJCWlmIChjcy0+ZGVidWcgJiBMMV9ERUJfSVNBQykKCSAgICAgICAgCQlkZWJ1Z2wxKGNzLCAiQW1kNzkzMDogaW50ZXJydXB0OiBUWC1QYWNrZXQgcmVhZHksIGZyZWVpbmcgc2tiIik7CiAgICAgICAgICAgICAgICAgICAgICAgIGRldl9rZnJlZV9za2JfaXJxKGNzLT50eF9za2IpOwoJCQljcy0+dHhfY250ID0gMDsKICAgICAgICAgICAgICAgICAgICAgICAgY3MtPmRjLmFtZDc5MzAudHhfeG10bGVuPTA7CgkJCWNzLT50eF9za2IgPSBOVUxMOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYgKChjcy0+dHhfc2tiID0gc2tiX2RlcXVldWUoJmNzLT5zcSkpKSB7CiAgICAgICAgCQlpZiAoY3MtPmRlYnVnICYgTDFfREVCX0lTQUMpCgkgICAgICAgIAkJZGVidWdsMShjcywgIkFtZDc5MzA6IGludGVycnVwdDogVFgtUGFja2V0IHJlYWR5LCBuZXh0IHBhY2tldCBkZXF1ZXVlZCIpOwoJICAgICAgICAJY3MtPnR4X2NudCA9IDA7CiAgICAgICAgICAgICAgICAgICAgICAgIGNzLT5kYy5hbWQ3OTMwLnR4X3htdGxlbj0wOwoJCQlBbWQ3OTMwX2ZpbGxfRGZpZm8oY3MpOwoJCX0KICAgICAgICAgICAgICAgIGVsc2UKCQkJc2NoZWR1bGVfZXZlbnQoY3MsIERfWE1UQlVGUkVBRFkpOwoJCS8qIEFNRCBpbnRlcnJ1cHRzIG9uICovCiAgICAgICAgICAgICAgICBBbWRJcnFPbihjcyk7CiAgICAgICAgfQoKCS8qIExJVSBzdGF0dXMgaW50ZXJydXB0IC0+IHJlYWQgTFNSLCBjaGVjayBzdGF0ZWNoYW5nZXMgKi8KCWlmIChsc3IgJiAweDM4KSB7CiAgICAgICAgICAgICAgICAvKiBBTUQgaW50ZXJydXB0cyBvZmYgKi8KICAgICAgICAgICAgICAgIEFtZElycU9mZihjcyk7CgoJCWlmIChjcy0+ZGVidWcgJiBMMV9ERUJfSVNBQykKCQkJZGVidWdsMShjcywgIkFtZDogaW50ZXJydXB0OiBMU1I9MHglMDJYLCBMSVUgaXMgaW4gc3RhdGUgJWQiLCBsc3IsICgobHNyICYgMHg3KSArMikpOwoKCQljcy0+ZGMuYW1kNzkzMC5waF9zdGF0ZSA9IChsc3IgJiAweDcpICsgMjsKCgkJc2NoZWR1bGVfZXZlbnQoY3MsIERfTDFTVEFURUNIQU5HRSk7CgkJLyogQU1EIGludGVycnVwdHMgb24gKi8KICAgICAgICAgICAgICAgIEFtZElycU9uKGNzKTsKCX0KCiAgICAgICAgLyogcmVhZHMgSW50ZXJydXB0LVJlZ2lzdGVyIGFnYWluLiBJZiB0aGVyZSBpcyBhIG5ldyBpbnRlcnJ1cHQtZmxhZzogcmVzdGFydCBoYW5kbGVyICovCiAgICAgICAgaXJmbGFncyA9IHJCeXRlQU1EKGNzLCAweDAwKTsKIH0KCn0KCnN0YXRpYyB2b2lkCkFtZDc5MzBfbDFodyhzdHJ1Y3QgUFN0YWNrICpzdCwgaW50IHByLCB2b2lkICphcmcpCnsKICAgICAgICBzdHJ1Y3QgSXNkbkNhcmRTdGF0ZSAqY3MgPSAoc3RydWN0IElzZG5DYXJkU3RhdGUgKikgc3QtPmwxLmhhcmR3YXJlOwoJc3RydWN0IHNrX2J1ZmYgKnNrYiA9IGFyZzsKCXVfbG9uZyBmbGFnczsKCiAgICAgICAgaWYgKGNzLT5kZWJ1ZyAmIEwxX0RFQl9JU0FDKQoJCWRlYnVnbDEoY3MsICJBbWQ3OTMwOiBsMWh3IGNhbGxlZCwgcHI6IDB4JTA0WCIsIHByKTsKCglzd2l0Y2ggKHByKSB7CgkJY2FzZSAoUEhfREFUQSB8IFJFUVVFU1QpOgogICAgICAgICAgICAgICAgICAgICAgICBpZiAoY3MtPmRlYnVnICYgREVCX0RMT0dfSEVYKQoJCQkJTG9nRnJhbWUoY3MsIHNrYi0+ZGF0YSwgc2tiLT5sZW4pOwoJCQlpZiAoY3MtPmRlYnVnICYgREVCX0RMT0dfVkVSQk9TRSkKCQkJCWRsb2dmcmFtZShjcywgc2tiLCAwKTsKCQkJc3Bpbl9sb2NrX2lycXNhdmUoJmNzLT5sb2NrLCBmbGFncyk7CgkJCWlmIChjcy0+dHhfc2tiKSB7CgkJCQlza2JfcXVldWVfdGFpbCgmY3MtPnNxLCBza2IpOwojaWZkZWYgTDJGUkFNRV9ERUJVRwkJLyogcHNhICovCgkJCQlpZiAoY3MtPmRlYnVnICYgTDFfREVCX0xBUEQpCgkJCQkJTG9nbDJGcmFtZShjcywgc2tiLCAiQW1kNzkzMDogbDFodzogUEhfREFUQSBRdWV1ZWQiLCAwKTsKI2VuZGlmCgkJCX0gZWxzZSB7CgkJCQljcy0+dHhfc2tiID0gc2tiOwoJCQkJY3MtPnR4X2NudCA9IDA7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY3MtPmRjLmFtZDc5MzAudHhfeG10bGVuPTA7CiNpZmRlZiBMMkZSQU1FX0RFQlVHCQkvKiBwc2EgKi8KCQkJCWlmIChjcy0+ZGVidWcgJiBMMV9ERUJfTEFQRCkKCQkJCQlMb2dsMkZyYW1lKGNzLCBza2IsICJBbWQ3OTMwOiBsMWh3OiBQSF9EQVRBIiwgMCk7CiNlbmRpZgoJCQkJQW1kNzkzMF9maWxsX0RmaWZvKGNzKTsKCQkJfQoJCQlzcGluX3VubG9ja19pcnFyZXN0b3JlKCZjcy0+bG9jaywgZmxhZ3MpOwoJCQlicmVhazsKCQljYXNlIChQSF9QVUxMIHwgSU5ESUNBVElPTik6CgkJCXNwaW5fbG9ja19pcnFzYXZlKCZjcy0+bG9jaywgZmxhZ3MpOwoJCQlpZiAoY3MtPnR4X3NrYikgewoJCQkJaWYgKGNzLT5kZWJ1ZyAmIEwxX0RFQl9XQVJOKQoJCQkJCWRlYnVnbDEoY3MsICJBbWQ3OTMwOiBsMWh3OiBsMmwxIHR4X3NrYiBleGlzdCB0aGlzIHNob3VsZG4ndCBoYXBwZW4iKTsKCQkJCXNrYl9xdWV1ZV90YWlsKCZjcy0+c3EsIHNrYik7CgkJCQlicmVhazsKCQkJfQoJCQlpZiAoY3MtPmRlYnVnICYgREVCX0RMT0dfSEVYKQoJCQkJTG9nRnJhbWUoY3MsIHNrYi0+ZGF0YSwgc2tiLT5sZW4pOwoJCQlpZiAoY3MtPmRlYnVnICYgREVCX0RMT0dfVkVSQk9TRSkKCQkJCWRsb2dmcmFtZShjcywgc2tiLCAwKTsKCQkJY3MtPnR4X3NrYiA9IHNrYjsKCQkJY3MtPnR4X2NudCA9IDA7CiAgICAgICAgICAgICAgICAgICAgICAgIGNzLT5kYy5hbWQ3OTMwLnR4X3htdGxlbj0wOwojaWZkZWYgTDJGUkFNRV9ERUJVRwkJLyogcHNhICovCgkJCWlmIChjcy0+ZGVidWcgJiBMMV9ERUJfTEFQRCkKCQkJCUxvZ2wyRnJhbWUoY3MsIHNrYiwgIkFtZDc5MzA6IGwxaHc6IFBIX0RBVEFfUFVMTEVEIiwgMCk7CiNlbmRpZgoJCQlBbWQ3OTMwX2ZpbGxfRGZpZm8oY3MpOwoJCQlzcGluX3VubG9ja19pcnFyZXN0b3JlKCZjcy0+bG9jaywgZmxhZ3MpOwoJCQlicmVhazsKCQljYXNlIChQSF9QVUxMIHwgUkVRVUVTVCk6CiNpZmRlZiBMMkZSQU1FX0RFQlVHCQkvKiBwc2EgKi8KCQkJaWYgKGNzLT5kZWJ1ZyAmIEwxX0RFQl9MQVBEKQoJCQkJZGVidWdsMShjcywgIkFtZDc5MzA6IGwxaHc6IC0+IFBIX1JFUVVFU1RfUFVMTCwgc2tiOiAlcyIsIChjcy0+dHhfc2tiKT8gInllcyI6Im5vIik7CiNlbmRpZgoJCQlpZiAoIWNzLT50eF9za2IpIHsKCQkJCXRlc3RfYW5kX2NsZWFyX2JpdChGTEdfTDFfUFVMTF9SRVEsICZzdC0+bDEuRmxhZ3MpOwoJCQkJc3QtPmwxLmwxbDIoc3QsIFBIX1BVTEwgfCBDT05GSVJNLCBOVUxMKTsKCQkJfSBlbHNlCgkJCQl0ZXN0X2FuZF9zZXRfYml0KEZMR19MMV9QVUxMX1JFUSwgJnN0LT5sMS5GbGFncyk7CgkJCWJyZWFrOwoJCWNhc2UgKEhXX1JFU0VUIHwgUkVRVUVTVCk6CgkJCXNwaW5fbG9ja19pcnFzYXZlKCZjcy0+bG9jaywgZmxhZ3MpOwoJCQlpZiAoKGNzLT5kYy5hbWQ3OTMwLnBoX3N0YXRlID09IDgpKSB7CgkJCQkvKiBiLWNoYW5uZWxzIG9mZiwgUEgtQVIgY2xlYXJlZAoJCQkJICogY2hhbmdlIHRvIEYzICovCgkJCQlBbWQ3OTMwX3BoX2NvbW1hbmQoY3MsIDB4MjAsICJIV19SRVNFVCBSRVFFU1QiKTsgLy9MTVIxIGJpdCA1CgkJCQlzcGluX3VubG9ja19pcnFyZXN0b3JlKCZjcy0+bG9jaywgZmxhZ3MpOwoJCQl9IGVsc2UgewoJCQkJQW1kNzkzMF9waF9jb21tYW5kKGNzLCAweDQwLCAiSFdfUkVTRVQgUkVRVUVTVCIpOwoJCQkJY3MtPmRjLmFtZDc5MzAucGhfc3RhdGUgPSAyOwoJCQkJc3Bpbl91bmxvY2tfaXJxcmVzdG9yZSgmY3MtPmxvY2ssIGZsYWdzKTsKCQkJCUFtZDc5MzBfbmV3X3BoKGNzKTsKCQkJfQoJCQlicmVhazsKCQljYXNlIChIV19FTkFCTEUgfCBSRVFVRVNUKToKICAgICAgICAgICAgICAgICAgICAgICAgY3MtPmRjLmFtZDc5MzAucGhfc3RhdGUgPSA5OwogICAgICAgICAgICAgICAgICAgICAgICBBbWQ3OTMwX25ld19waChjcyk7CgkJCWJyZWFrOwoJCWNhc2UgKEhXX0lORk8zIHwgUkVRVUVTVCk6CgkJCS8vIGF1dG9tYXRpYwoJCQlicmVhazsKCQljYXNlIChIV19URVNUTE9PUCB8IFJFUVVFU1QpOgoJCQkvKiBub3QgaW1wbGVtZW50ZWQgeWV0ICovCgkJCWJyZWFrOwoJCWNhc2UgKEhXX0RFQUNUSVZBVEUgfCBSRVNQT05TRSk6CiAgICAgICAgICAgICAgICAgICAgICAgIHNrYl9xdWV1ZV9wdXJnZSgmY3MtPnJxKTsKCQkJc2tiX3F1ZXVlX3B1cmdlKCZjcy0+c3EpOwoJCQlpZiAoY3MtPnR4X3NrYikgewoJCQkJZGV2X2tmcmVlX3NrYihjcy0+dHhfc2tiKTsKCQkJCWNzLT50eF9za2IgPSBOVUxMOwoJCQl9CgkJCWlmICh0ZXN0X2FuZF9jbGVhcl9iaXQoRkxHX0RCVVNZX1RJTUVSLCAmY3MtPkhXX0ZsYWdzKSkKCQkJCWRlbF90aW1lcigmY3MtPmRidXN5dGltZXIpOwoJCQlpZiAodGVzdF9hbmRfY2xlYXJfYml0KEZMR19MMV9EQlVTWSwgJmNzLT5IV19GbGFncykpCgkJCQlzY2hlZHVsZV9ldmVudChjcywgRF9DTEVBUkJVU1kpOwoJCQlicmVhazsKCQlkZWZhdWx0OgoJCQlpZiAoY3MtPmRlYnVnICYgTDFfREVCX1dBUk4pCgkJCQlkZWJ1Z2wxKGNzLCAiQW1kNzkzMDogbDFodzogdW5rbm93biAlMDR4IiwgcHIpOwoJCQlicmVhazsKCX0KfQoKc3RhdGljIHZvaWQKc2V0c3RhY2tfQW1kNzkzMChzdHJ1Y3QgUFN0YWNrICpzdCwgc3RydWN0IElzZG5DYXJkU3RhdGUgKmNzKQp7CgogICAgICAgIGlmIChjcy0+ZGVidWcgJiBMMV9ERUJfSVNBQykKCQlkZWJ1Z2wxKGNzLCAiQW1kNzkzMDogc2V0c3RhY2sgY2FsbGVkIik7CgogICAgICAgIHN0LT5sMS5sMWh3ID0gQW1kNzkzMF9sMWh3Owp9CgoKc3RhdGljIHZvaWQKRENfQ2xvc2VfQW1kNzkzMChzdHJ1Y3QgSXNkbkNhcmRTdGF0ZSAqY3MpIHsKICAgICAgICBpZiAoY3MtPmRlYnVnICYgTDFfREVCX0lTQUMpCgkJZGVidWdsMShjcywgIkFtZDc5MzA6IERDX0Nsb3NlIGNhbGxlZCIpOwp9CgoKc3RhdGljIHZvaWQKZGJ1c3lfdGltZXJfaGFuZGxlcihzdHJ1Y3QgSXNkbkNhcmRTdGF0ZSAqY3MpCnsKCXVfbG9uZyBmbGFnczsKCXN0cnVjdCBQU3RhY2sgKnN0cHRyOwogICAgICAgIFdPUkQgZHRjciwgZGVyOwogICAgICAgIEJZVEUgZHNyMSwgZHNyMjsKCgogICAgICAgIGlmIChjcy0+ZGVidWcgJiBMMV9ERUJfSVNBQykKCQlkZWJ1Z2wxKGNzLCAiQW1kNzkzMDogZGJ1c3lfdGltZXIgZXhwaXJlZCEiKTsKCglpZiAodGVzdF9iaXQoRkxHX0RCVVNZX1RJTUVSLCAmY3MtPkhXX0ZsYWdzKSkgewoJCXNwaW5fbG9ja19pcnFzYXZlKCZjcy0+bG9jaywgZmxhZ3MpOwogICAgICAgICAgICAgICAgLyogRCBUcmFuc21pdCBCeXRlIENvdW50IFJlZ2lzdGVyOgogICAgICAgICAgICAgICAgICogQ291bnRzIGRvd24gcGFja2V0J3MgbnVtYmVyIG9mIEJ5dGVzLCAwIGlmIHBhY2tldCByZWFkeSAqLwogICAgICAgICAgICAgICAgZHRjciA9IHJXb3JkQU1EKGNzLCAweDg1KTsKICAgICAgICAgICAgICAgIGRzcjEgPSByQnl0ZUFNRChjcywgMHgwMik7CiAgICAgICAgICAgICAgICBkc3IyID0gckJ5dGVBTUQoY3MsIDB4MDcpOwogICAgICAgICAgICAgICAgZGVyICA9IHJXb3JkQU1EKGNzLCAweDAzKTsKCgkgICAgICAgIGlmIChjcy0+ZGVidWcgJiBMMV9ERUJfSVNBQykKCQkJZGVidWdsMShjcywgIkFtZDc5MzA6IGRidXN5X3RpbWVyX2hhbmRsZXI6IERTUjE9MHglMDJYLCBEU1IyPTB4JTAyWCwgREVSPTB4JTA0WCwgY3MtPnR4X3NrYi0+bGVuPSV1LCB0eF9zdGF0PSV1LCBkdGNyPSV1LCBjcy0+dHhfY250PSV1IiwgZHNyMSwgZHNyMiwgZGVyLCBjcy0+dHhfc2tiLT5sZW4sIGNzLT5kYy5hbWQ3OTMwLnR4X3htdGxlbiwgZHRjciwgY3MtPnR4X2NudCk7CgoJCWlmICgoY3MtPmRjLmFtZDc5MzAudHhfeG10bGVuIC0gZHRjcikgPCBjcy0+dHhfY250KSB7CS8qIEQtQ2hhbm5lbCBCdXN5ICovCgkJCXRlc3RfYW5kX3NldF9iaXQoRkxHX0wxX0RCVVNZLCAmY3MtPkhXX0ZsYWdzKTsKCQkJc3RwdHIgPSBjcy0+c3RsaXN0OwoJCQlzcGluX3VubG9ja19pcnFyZXN0b3JlKCZjcy0+bG9jaywgZmxhZ3MpOwoJCQl3aGlsZSAoc3RwdHIgIT0gTlVMTCkgewoJCQkJc3RwdHItPmwxLmwxbDIoc3RwdHIsIFBIX1BBVVNFIHwgSU5ESUNBVElPTiwgTlVMTCk7CgkJCQlzdHB0ciA9IHN0cHRyLT5uZXh0OwoJCQl9CgoJCX0gZWxzZSB7CgkJCS8qIGRpc2NhcmQgZnJhbWU7IHJlc2V0IHRyYW5zY2VpdmVyICovCgkJCXRlc3RfYW5kX2NsZWFyX2JpdChGTEdfREJVU1lfVElNRVIsICZjcy0+SFdfRmxhZ3MpOwoJCQlpZiAoY3MtPnR4X3NrYikgewoJCQkJZGV2X2tmcmVlX3NrYl9hbnkoY3MtPnR4X3NrYik7CgkJCQljcy0+dHhfY250ID0gMDsKCQkJCWNzLT50eF9za2IgPSBOVUxMOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNzLT5kYy5hbWQ3OTMwLnR4X3htdGxlbiA9IDA7CgkJCX0gZWxzZSB7CgkJCQlwcmludGsoS0VSTl9XQVJOSU5HICJIaVNheDogQW1kNzkzMDogRC1DaGFubmVsIEJ1c3kgbm8gc2tiXG4iKTsKCQkJCWRlYnVnbDEoY3MsICJBbWQ3OTMwOiBELUNoYW5uZWwgQnVzeSBubyBza2IiKTsKCgkJCX0KCQkJLyogVHJhbnNtaXR0ZXIgcmVzZXQsIGFib3J0IHRyYW5zbWl0ICovCgkJCXdCeXRlQU1EKGNzLCAweDIxLCAweDgyKTsKCQkJd0J5dGVBTUQoY3MsIDB4MjEsIDB4MDIpOwoJCQlzcGluX3VubG9ja19pcnFyZXN0b3JlKCZjcy0+bG9jaywgZmxhZ3MpOwoJCQljcy0+aXJxX2Z1bmMoY3MtPmlycSwgY3MsIE5VTEwpOwoKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGNzLT5kZWJ1ZyAmIEwxX0RFQl9JU0FDKQoJCQkJZGVidWdsMShjcywgIkFtZDc5MzA6IGRidXN5X3RpbWVyX2hhbmRsZXI6IFRyYW5zbWl0dGVyIHJlc2V0Iik7CgkJfQoJfQp9CgoKCnZvaWQgX19kZXZpbml0CkFtZDc5MzBfaW5pdChzdHJ1Y3QgSXNkbkNhcmRTdGF0ZSAqY3MpCnsKICAgIFdPUkQgKnB0cjsKICAgIEJZVEUgY21kLCBjbnQ7CgogICAgICAgIGlmIChjcy0+ZGVidWcgJiBMMV9ERUJfSVNBQykKCQlkZWJ1Z2wxKGNzLCAiQW1kNzkzMDogaW5pdGFtZCBjYWxsZWQiKTsKCiAgICAgICAgY3MtPmRjLmFtZDc5MzAudHhfeG10bGVuID0gMDsKICAgICAgICBjcy0+ZGMuYW1kNzkzMC5vbGRfc3RhdGUgPSAwOwogICAgICAgIGNzLT5kYy5hbWQ3OTMwLmxtcjEgPSAweDQwOwogICAgICAgIGNzLT5kYy5hbWQ3OTMwLnBoX2NvbW1hbmQgPSBBbWQ3OTMwX3BoX2NvbW1hbmQ7Cgljcy0+c2V0c3RhY2tfZCA9IHNldHN0YWNrX0FtZDc5MzA7Cgljcy0+RENfQ2xvc2UgPSBEQ19DbG9zZV9BbWQ3OTMwOwoKCS8qIEFNRCBJbml0aWFsaXNhdGlvbiAqLwoJZm9yIChwdHIgPSBpbml0QU1EOyAqcHRyICE9IDB4RkZGRjsgKSB7CgkJY21kID0gTE9CWVRFKCpwdHIpOwoKICAgICAgICAgICAgICAgIC8qIHJlYWQgKi8KICAgICAgICAgICAgICAgIGlmICgqcHRyKysgPj0gMHgxMDApIHsKCQkJaWYgKGNtZCA8IDgpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogc2V0enQgUmVnaXN0ZXIgenVy/GNrICovCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgckJ5dGVBTUQoY3MsIGNtZCk7CgkJCWVsc2UgewoJCQkJd0J5dGVBTUQoY3MsIDB4MDAsIGNtZCk7CgkJCQlmb3IgKGNudCA9ICpwdHIrKzsgY250ID4gMDsgY250LS0pCgkJCQkJckJ5dGVBTUQoY3MsIDB4MDEpOwoJCQl9CgkJfQogICAgICAgICAgICAgICAgLyogd3JpdGUgKi8KICAgICAgICAgICAgICAgIGVsc2UgaWYgKGNtZCA8IDgpCgkJCXdCeXRlQU1EKGNzLCBjbWQsIExPQllURSgqcHRyKyspKTsKCgkJZWxzZSB7CgkJCXdCeXRlQU1EKGNzLCAweDAwLCBjbWQpOwoJCQlmb3IgKGNudCA9ICpwdHIrKzsgY250ID4gMDsgY250LS0pCgkJCQl3Qnl0ZUFNRChjcywgMHgwMSwgTE9CWVRFKCpwdHIrKykpOwoJCX0KCX0KfQoKdm9pZCBfX2RldmluaXQKc2V0dXBfQW1kNzkzMChzdHJ1Y3QgSXNkbkNhcmRTdGF0ZSAqY3MpCnsKICAgICAgICBJTklUX1dPUksoJmNzLT50cXVldWUsICh2b2lkICopKHZvaWQgKikgQW1kNzkzMF9iaCwgY3MpOwoJY3MtPmRidXN5dGltZXIuZnVuY3Rpb24gPSAodm9pZCAqKSBkYnVzeV90aW1lcl9oYW5kbGVyOwoJY3MtPmRidXN5dGltZXIuZGF0YSA9IChsb25nKSBjczsKCWluaXRfdGltZXIoJmNzLT5kYnVzeXRpbWVyKTsKfQo=