LyoKICogKEMpIENvcHlyaWdodCAyMDAwLTIwMDIKICogV29sZmdhbmcgRGVuaywgREVOWCBTb2Z0d2FyZSBFbmdpbmVlcmluZywgd2RAZGVueC5kZS4KICogKEMpIENvcHlyaWdodCAyMDAyCiAqIERhbmllbCBFbmdzdHL2bSwgT21pY3JvbiBDZXRpIEFCCiAqCiAqIFNlZSBmaWxlIENSRURJVFMgZm9yIGxpc3Qgb2YgcGVvcGxlIHdobyBjb250cmlidXRlZCB0byB0aGlzCiAqIHByb2plY3QuCiAqCiAqIFRoaXMgcHJvZ3JhbSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IKICogbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgYXMKICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlciB2ZXJzaW9uIDIgb2YKICogdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uCiAqCiAqIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLAogKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZgogKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlCiAqIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIGFsb25nIHdpdGggdGhpcyBwcm9ncmFtOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlCiAqIEZvdW5kYXRpb24sIEluYy4sIDU5IFRlbXBsZSBQbGFjZSwgU3VpdGUgMzMwLCBCb3N0b24sCiAqIE1BIDAyMTExLTEzMDcgVVNBCiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgogKiBMb3RzIG9mIGNvZGUgY29waWVkIGZyb206CiAqCiAqIG04eHhfcGNtY2lhLmMgLSBMaW51eCBQQ01DSUEgc29ja2V0IGRyaXZlciBmb3IgdGhlIG1wYzh4eCBzZXJpZXMuCiAqIChDKSAxOTk5LTIwMDAgTWFnbnVzIERhbW0gPGRhbW1AYml0c21hcnQuY29tPgogKgogKiAiVGhlIEV4Q0Egc3RhbmRhcmQgc3BlY2lmaWVzIHRoYXQgc29ja2V0IGNvbnRyb2xsZXJzIHNob3VsZCBwcm92aWRlCiAqIHR3byBJTyBhbmQgZml2ZSBtZW1vcnkgd2luZG93cyBwZXIgc29ja2V0LCB3aGljaCBjYW4gYmUgaW5kZXBlbmRlbnRseQogKiBjb25maWd1cmVkIGFuZCBwb3NpdGlvbmVkIGluIHRoZSBob3N0IGFkZHJlc3Mgc3BhY2UgYW5kIG1hcHBlZCB0bwogKiBhcmJpdHJhcnkgc2VnbWVudHMgb2YgY2FyZCBhZGRyZXNzIHNwYWNlLiAiIC0gRGF2aWQgQSBIaW5kcy4gMTk5OQogKgogKiBUaGlzIGNvbnRyb2xsZXIgZG9lcyBfbm90XyBtZWV0IHRoZSBFeENBIHN0YW5kYXJkLgogKgogKiBtOHh4IHBjbWNpYSBjb250cm9sbGVyIGJyaWVmIGluZm86CiAqICsgOCB3aW5kb3dzIChhdHRyaWIsIG1lbSwgaS9vKQogKiArIHVwIHRvIHR3byBzbG90cyAoU0xPVF9BIGFuZCBTTE9UX0IpCiAqICsgaW5wdXRwaW5zLCBvdXRwdXRwaW5zLCBldmVudCBhbmQgbWFzayByZWdpc3RlcnMuCiAqIC0gbm8gb2Zmc2V0IHJlZ2lzdGVyLiBzaWdoLgogKgogKiBCZWNhdXNlIG9mIHRoZSBsYWNraW5nIG9mZnNldCByZWdpc3RlciB3ZSBtdXN0IG1hcCB0aGUgd2hvbGUgY2FyZC4KICogV2UgYXNzaWduIGVhY2ggbWVtb3J5IHdpbmRvdyBQQ01DSUFfTUVNX1dJTl9TSVpFIGFkZHJlc3Mgc3BhY2UuCiAqIE1ha2Ugc3VyZSB0aGVyZSBpcyAoUENNQ0lBX01FTV9XSU5fU0laRSAqIFBDTUNJQV9NRU1fV0lOX05PCiAqICogUENNQ0lBX1NPQ0tFVFNfTk8pIGJ5dGVzIGF0IFBDTUNJQV9NRU1fV0lOX0JBU0UuCiAqIFRoZSBpL28gd2luZG93cyBhcmUgZHluYW1pY2FsbHkgYWxsb2NhdGVkIGF0IFBDTUNJQV9JT19XSU5fQkFTRS4KICogVGhleSBhcmUgbWF4aW11bSA2NEtCeXRlIGVhY2guLi4KICovCgoKI3VuZGVmIERFQlVHCQkvKiovCgovKgogKiBQQ01DSUEgc3VwcG9ydAogKi8KI2luY2x1ZGUgPGNvbW1vbi5oPgojaW5jbHVkZSA8Y29tbWFuZC5oPgojaW5jbHVkZSA8Y29uZmlnLmg+CiNpbmNsdWRlIDxwY2kuaD4KI2luY2x1ZGUgPGFzbS9pby5oPgoKI2luY2x1ZGUgPHBjbWNpYS5oPgoKI2lmIGRlZmluZWQoQ09ORklHX0NNRF9QQ01DSUEpCgppbnQgcGNtY2lhX29uKGludCBpZGVfYmFzZV9idXMpOwoKc3RhdGljIGludCAgaGFyZHdhcmVfZGlzYWJsZShpbnQgc2xvdCk7CnN0YXRpYyBpbnQgIGhhcmR3YXJlX2VuYWJsZShpbnQgc2xvdCk7CnN0YXRpYyBpbnQgIHZvbHRhZ2Vfc2V0KGludCBzbG90LCBpbnQgdmNjLCBpbnQgdnBwKTsKc3RhdGljIHZvaWQgcHJpbnRfZnVuY2lkKGludCBmdW5jKTsKc3RhdGljIHZvaWQgcHJpbnRfZml4ZWQodm9sYXRpbGUgY2hhciAqcCk7CnN0YXRpYyBpbnQgIGlkZW50aWZ5KHZvbGF0aWxlIGNoYXIgKnApOwpzdGF0aWMgaW50ICBjaGVja19pZGVfZGV2aWNlKGludCBzbG90LCBpbnQgaWRlX2Jhc2VfYnVzKTsKCgovKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovCgoKY29uc3QgY2hhciAqaW5kZW50ID0gIlx0ICAgIjsKCi8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi8KCgpzdGF0aWMgc3RydWN0IHBjaV9kZXZpY2VfaWQgc3VwcG9ydGVkW10gPSB7Cgl7IFBDSV9WRU5ET1JfSURfVEksIDB4YWM1MCB9LCAvKiBUaSBQQ0kxNDEwQSAqLwoJeyBQQ0lfVkVORE9SX0lEX1RJLCAweGFjNTYgfSwgLyogVGkgUENJMTUxMCAqLwoJeyB9Cn07CgpzdGF0aWMgcGNpX2Rldl90IGRldmJ1c2ZuOwpzdGF0aWMgdTMyIHNvY2tldF9iYXNlOwpzdGF0aWMgdTMyIHBjbWNpYV9jaXNfcHRyOwoKaW50IHBjbWNpYV9vbihpbnQgaWRlX2Jhc2VfYnVzKQp7Cgl1MTYgZGV2X2lkOwoJdTMyIHNvY2tldF9zdGF0dXM7CglpbnQgc2xvdCA9IDA7CglpbnQgY2lzX2xlbjsKCXUxNiBpb19iYXNlOwoJdTE2IGlvX2xlbjsKCgkvKgoJICogRmluZCB0aGUgQ2FyZEJ1cyBQQ0kgZGV2aWNlKHMpLgoJICovCglpZiAoKGRldmJ1c2ZuID0gcGNpX2ZpbmRfZGV2aWNlcyhzdXBwb3J0ZWQsIDApKSA8IDApIHsKCQlwcmludGYoIlRpIENhcmRCdXM6IG5vdCBmb3VuZFxuIik7CgkJcmV0dXJuIDE7Cgl9CgoJcGNpX3JlYWRfY29uZmlnX3dvcmQoZGV2YnVzZm4sIFBDSV9ERVZJQ0VfSUQsICZkZXZfaWQpOwoKCWlmIChkZXZfaWQgPT0gMHhhYzU2KSB7CgkJZGVidWcoIkVuYWJsZSBQQ01DSUEgVGkgUENJMTUxMFxuIik7Cgl9IGVsc2UgewoJCWRlYnVnKCJFbmFibGUgUENNQ0lBIFRpIFBDSTE0MTBBXG4iKTsKCX0KCglwY21jaWFfY2lzX3B0ciA9IENPTkZJR19TWVNfUENNQ0lBX0NJU19XSU47CgljaXNfbGVuID0gQ09ORklHX1NZU19QQ01DSUFfQ0lTX1dJTl9TSVpFOwoKCWlvX2Jhc2UgPSBDT05GSUdfU1lTX1BDTUNJQV9JT19XSU47Cglpb19sZW4gPSBDT05GSUdfU1lTX1BDTUNJQV9JT19XSU5fU0laRTsKCgkvKgoJICogU2V0dXAgdGhlIFBDSSBkZXZpY2UuCgkgKi8KCXBjaV9yZWFkX2NvbmZpZ19kd29yZChkZXZidXNmbiwgUENJX0JBU0VfQUREUkVTU18wLCAmc29ja2V0X2Jhc2UpOwoJc29ja2V0X2Jhc2UgJj0gfjB4ZjsKCglzb2NrZXRfc3RhdHVzID0gcmVhZGwoc29ja2V0X2Jhc2UrOCk7CglpZiAoKHNvY2tldF9zdGF0dXMgJiA2KSA9PSAwKSB7CgkJcHJpbnRmKCJDYXJkIFByZXNlbnQ6ICIpOwoKCQlzd2l0Y2ggKHNvY2tldF9zdGF0dXMgJiAweDNjMDApIHsKCgkJY2FzZSAweDQwMDoKCQkJcHJpbnRmKCI1ViAiKTsKCQkJYnJlYWs7CgkJY2FzZSAweDgwMDoKCQkJcHJpbnRmKCIzLjNWICIpOwoJCQlicmVhazsKCQljYXNlIDB4YzAwOgoJCQlwcmludGYoIjMuMy81ViAiKTsKCQkJYnJlYWs7CgkJZGVmYXVsdDoKCQkJcHJpbnRmKCJ1bnN1cHBvcnRlZCBWY2MgIik7CgkJCWJyZWFrOwoJCX0KCQlzd2l0Y2ggKHNvY2tldF9zdGF0dXMgJiAweDMwKSB7CgkJY2FzZSAweDEwOgoJCQlwcmludGYoIjE2Yml0IFBDLUNhcmRcbiIpOwoJCQlicmVhazsKCQljYXNlIDB4MjA6CgkJCXByaW50ZigiMzJiaXQgQ2FyZEJ1cyBDYXJkXG4iKTsKCQkJYnJlYWs7CgkJZGVmYXVsdDoKCQkJcHJpbnRmKCI4Yml0IFBDLUNhcmRcbiIpOwoJCQlicmVhazsKCQl9Cgl9CgoKCXdyaXRlYigweDQxLCBzb2NrZXRfYmFzZSArIDB4ODA2KTsgLyogRW5hYmxlIEkvTyB3aW5kb3cgMCBhbmQgbWVtb3J5IHdpbmRvdyAwICovCgl3cml0ZWIoMHgwZSwgc29ja2V0X2Jhc2UgKyAweDgwNyk7IC8qIFJlc2V0IEkvTyB3aW5kb3cgb3B0aW9ucyAqLwoKCS8qIENhcmVmdWw6IHRoZSBsaW51eCB5ZW50YSBkcml2ZXIgZG8gbm90IHNlZW0gdG8gcmVzZXQgdGhlIG9mZnNldAoJICogaW4gdGhlIGkvbyB3aW5kb3dzLCBzbyBsZWF2aW5nIHRoZW0gbm9uLXplcm8gaXMgYSBwcm9ibGVtICovCgoJd3JpdGViKGlvX2Jhc2UgJiAweGZmLCBzb2NrZXRfYmFzZSArIDB4ODA4KTsgLyogSS9PIHdpbmRvdyAwIGJhc2UgYWRkcmVzcyAqLwoJd3JpdGViKGlvX2Jhc2U+PjgsIHNvY2tldF9iYXNlICsgMHg4MDkpOwoJd3JpdGViKChpb19iYXNlICsgaW9fbGVuIC0gMSkgJiAweGZmLCBzb2NrZXRfYmFzZSArIDB4ODBhKTsgLyogSS9PIHdpbmRvdyAwIGVuZCBhZGRyZXNzICovCgl3cml0ZWIoKGlvX2Jhc2UgKyBpb19sZW4gLSAxKT4+OCwgc29ja2V0X2Jhc2UgKyAweDgwYik7Cgl3cml0ZWIoMHgwMCwgc29ja2V0X2Jhc2UgKyAweDgzNik7ICAgICAgLyogSS9PIHdpbmRvdyAwIG9mZnNldCBhZGRyZXNzIDB4MDAwICovCgl3cml0ZWIoMHgwMCwgc29ja2V0X2Jhc2UgKyAweDgzNyk7CgoKCXdyaXRlYigocGNtY2lhX2Npc19wdHImMHgwMDBmZjAwMCkgPj4gMTIsCgkgICAgICAgc29ja2V0X2Jhc2UgKyAweDgxMCk7IC8qIE1lbW9yeSB3aW5kb3cgMCBzdGFydCBhZGRyZXNzIGJpdHMgMTktMTIgKi8KCXdyaXRlYigocGNtY2lhX2Npc19wdHImMHgwMGYwMDAwMCkgPj4gMjAsCgkgICAgICAgc29ja2V0X2Jhc2UgKyAweDgxMSk7ICAvKiBNZW1vcnkgd2luZG93IDAgc3RhcnQgYWRkcmVzcyBiaXRzIDIzLTIwICovCgl3cml0ZWIoKChwY21jaWFfY2lzX3B0citjaXNfbGVuLTEpICYgMHgwMDBmZjAwMCkgPj4gMTIsCgkJc29ja2V0X2Jhc2UgKyAweDgxMik7IC8qIE1lbW9yeSB3aW5kb3cgMCBlbmQgYWRkcmVzcyBiaXRzIDE5LTEyKi8KCXdyaXRlYigoKHBjbWNpYV9jaXNfcHRyK2Npc19sZW4tMSkgJiAweDAwZjAwMDAwKSA+PiAyMCwKCQlzb2NrZXRfYmFzZSArIDB4ODEzKTsgLyogTWVtb3J5IHdpbmRvdyAwIGVuZCBhZGRyZXNzIGJpdHMgMjMtMjAqLwoJd3JpdGViKDB4MDAsIHNvY2tldF9iYXNlICsgMHg4MTQpOyAvKiBNZW1vcnkgd2luZG93IDAgb2Zmc2V0IGJpdHMgMTktMTIgKi8KCXdyaXRlYigweDQwLCBzb2NrZXRfYmFzZSArIDB4ODE1KTsgLyogTWVtb3J5IHdpbmRvdyAwIG9mZnNldCBiaXRzIDIzLTIwIGFuZAoJCQkJCSAgICAqIG9wdGlvbnMgKHJlYWQvd3JpdGUsIGF0dHJpYnV0ZSBhY2Nlc3MpICovCgl3cml0ZWIoMHgwMCwgc29ja2V0X2Jhc2UgKyAweDgxNik7IC8qIEV4Q0EgY2FyZC1kZXRlY3QgYW5kIGdlbmVyYWwgY29udHJvbCAgKi8KCXdyaXRlYigweDAwLCBzb2NrZXRfYmFzZSArIDB4ODFlKTsgLyogRXhDQSBnbG9iYWwgY29udHJvbCAoaW50ZXJydXB0IG1vZGVzKSAqLwoKCXdyaXRlYigocGNtY2lhX2Npc19wdHIgJiAweGZmMDAwMDAwKSA+PiAyNCwKCSAgICAgICBzb2NrZXRfYmFzZSArIDB4ODQwKTsgLyogTWVtb3J5IHdpbmRvdyBhZGRyZXNzIGJpdHMgMzEtMjQgKi8KCgoJLyogdHVybiBvZmYgdm9sdGFnZSAqLwoJaWYgKHZvbHRhZ2Vfc2V0KHNsb3QsIDAsIDApKSB7CgkJcmV0dXJuIDE7Cgl9CgoJLyogRW5hYmxlIGV4dGVybmFsIGhhcmR3YXJlICovCglpZiAoaGFyZHdhcmVfZW5hYmxlKHNsb3QpKSB7CgkJcmV0dXJuIDE7Cgl9CgoJaWYgKGNoZWNrX2lkZV9kZXZpY2Uoc2xvdCwgaWRlX2Jhc2VfYnVzKSkgewoJCXJldHVybiAxOwoJfQoKCXJldHVybiAwOwp9CgovKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovCgoKI2lmIGRlZmluZWQoQ09ORklHX0NNRF9QQ01DSUEpCmludCBwY21jaWFfb2ZmICh2b2lkKQp7CglpbnQgc2xvdCA9IDA7CgoJd3JpdGViKDB4MDAsIHNvY2tldF9iYXNlICsgMHg4MDYpOyAvKiBkaXNhYmxlIGFsbCBJL08gYW5kIG1lbW9yeSB3aW5kb3dzICovCgoJd3JpdGViKDB4MDAsIHNvY2tldF9iYXNlICsgMHg4MDgpOyAvKiBJL08gd2luZG93IDAgYmFzZSBhZGRyZXNzICovCgl3cml0ZWIoMHgwMCwgc29ja2V0X2Jhc2UgKyAweDgwOSk7Cgl3cml0ZWIoMHgwMCwgc29ja2V0X2Jhc2UgKyAweDgwYSk7IC8qIEkvTyB3aW5kb3cgMCBlbmQgYWRkcmVzcyAqLwoJd3JpdGViKDB4MDAsIHNvY2tldF9iYXNlICsgMHg4MGIpOwoJd3JpdGViKDB4MDAsIHNvY2tldF9iYXNlICsgMHg4MzYpOyAvKiBJL08gd2luZG93IDAgb2Zmc2V0IGFkZHJlc3MgICovCgl3cml0ZWIoMHgwMCwgc29ja2V0X2Jhc2UgKyAweDgzNyk7CgoJd3JpdGViKDB4MDAsIHNvY2tldF9iYXNlICsgMHg4MGMpOyAvKiBJL08gd2luZG93IDEgYmFzZSBhZGRyZXNzICAqLwoJd3JpdGViKDB4MDAsIHNvY2tldF9iYXNlICsgMHg4MGQpOwoJd3JpdGViKDB4MDAsIHNvY2tldF9iYXNlICsgMHg4MGUpOyAvKiBJL08gd2luZG93IDEgZW5kIGFkZHJlc3MgICovCgl3cml0ZWIoMHgwMCwgc29ja2V0X2Jhc2UgKyAweDgwZik7Cgl3cml0ZWIoMHgwMCwgc29ja2V0X2Jhc2UgKyAweDgzOCk7IC8qIEkvTyB3aW5kb3cgMSBvZmZzZXQgYWRkcmVzcyAgKi8KCXdyaXRlYigweDAwLCBzb2NrZXRfYmFzZSArIDB4ODM5KTsKCgl3cml0ZWIoMHgwMCwgc29ja2V0X2Jhc2UgKyAweDgxMCk7IC8qIE1lbW9yeSB3aW5kb3cgMCBzdGFydCBhZGRyZXNzICovCgl3cml0ZWIoMHgwMCwgc29ja2V0X2Jhc2UgKyAweDgxMSk7Cgl3cml0ZWIoMHgwMCwgc29ja2V0X2Jhc2UgKyAweDgxMik7IC8qIE1lbW9yeSB3aW5kb3cgMCBlbmQgYWRkcmVzcyAgKi8KCXdyaXRlYigweDAwLCBzb2NrZXRfYmFzZSArIDB4ODEzKTsKCXdyaXRlYigweDAwLCBzb2NrZXRfYmFzZSArIDB4ODE0KTsgLyogTWVtb3J5IHdpbmRvdyAwIG9mZnNldCAqLwoJd3JpdGViKDB4MDAsIHNvY2tldF9iYXNlICsgMHg4MTUpOwoKCXdyaXRlYigweGMwLCBzb2NrZXRfYmFzZSArIDB4ODQwKTsgLyogTWVtb3J5IHdpbmRvdyAwIHBhZ2UgYWRkcmVzcyAqLwoKCgkvKiB0dXJuIG9mZiB2b2x0YWdlICovCgl2b2x0YWdlX3NldChzbG90LCAwLCAwKTsKCgkvKiBkaXNhYmxlIGV4dGVybmFsIGhhcmR3YXJlICovCglwcmludGYgKCJTaHV0ZG93biBhbmQgUG93ZXJvZmYgVGkgUENJMTQxMEFcbiIpOwoJaGFyZHdhcmVfZGlzYWJsZShzbG90KTsKCglyZXR1cm4gMDsKfQoKI2VuZGlmCgovKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovCgoKI2RlZmluZQlNQVhfVFVQRUxfU1oJNTEyCiNkZWZpbmUgTUFYX0ZFQVRVUkVTCTQKaW50IGlkZV9kZXZpY2VzX2ZvdW5kOwpzdGF0aWMgaW50IGNoZWNrX2lkZV9kZXZpY2UoaW50IHNsb3QsIGludCBpZGVfYmFzZV9idXMpCnsKCXZvbGF0aWxlIGNoYXIgKmlkZW50ID0gTlVMTDsKCXZvbGF0aWxlIGNoYXIgKmZlYXR1cmVfcFtNQVhfRkVBVFVSRVNdOwoJdm9sYXRpbGUgY2hhciAqcCwgKnN0YXJ0OwoJaW50IG5fZmVhdHVyZXMgPSAwOwoJdWNoYXIgZnVuY19pZCA9IH4wOwoJdWNoYXIgY29kZSwgbGVuOwoJdXNob3J0IGNvbmZpZ19iYXNlID0gMDsKCWludCBmb3VuZCA9IDA7CglpbnQgaTsKCXUzMiBzb2NrZXRfc3RhdHVzOwoKCWRlYnVnICgiUENNQ0lBIE1FTTogJTA4WFxuIiwgcGNtY2lhX2Npc19wdHIpOwoKCXNvY2tldF9zdGF0dXMgPSByZWFkbChzb2NrZXRfYmFzZSs4KTsKCglpZiAoKHNvY2tldF9zdGF0dXMgJiA2KSAhPSAwIHx8IChzb2NrZXRfc3RhdHVzICYgMHgyMCkgIT0gMCkgewoJCXByaW50Zigibm8gY2FyZCBvciBDYXJkQnVzIGNhcmRcbiIpOwoJCXJldHVybiAxOwoJfQoKCXN0YXJ0ID0gcCA9ICh2b2xhdGlsZSBjaGFyICopIHBjbWNpYV9jaXNfcHRyOwoKCXdoaWxlICgocCAtIHN0YXJ0KSA8IE1BWF9UVVBFTF9TWikgewoKCQljb2RlID0gKnA7IHAgKz0gMjsKCgkJaWYgKGNvZGUgPT0gMHhGRikgeyAvKiBFbmQgb2YgY2hhaW4gKi8KCQkJYnJlYWs7CgkJfQoKCQlsZW4gPSAqcDsgcCArPSAyOwojaWYgZGVmaW5lZChERUJVRykgJiYgKERFQlVHID4gMSkKCQl7CgkJCXZvbGF0aWxlIHVjaGFyICpxID0gcDsKCQkJcHJpbnRmICgiXG5UdXBsZSBjb2RlICUwMnggIGxlbmd0aCAlZFxuXHREYXRhOiIsCgkJCQljb2RlLCBsZW4pOwoKCQkJZm9yIChpID0gMDsgaSA8IGxlbjsgKytpKSB7CgkJCQlwcmludGYgKCIgJTAyeCIsICpxKTsKCQkJCXErPSAyOwoJCQl9CgkJfQojZW5kaWYJLyogREVCVUcgKi8KCQlzd2l0Y2ggKGNvZGUpIHsKCQljYXNlIENJU1RQTF9WRVJTXzE6CgkJCWlkZW50ID0gcCArIDQ7CgkJCWJyZWFrOwoJCWNhc2UgQ0lTVFBMX0ZVTkNJRDoKCQkJLyogRml4IGZvciBicm9rZW4gU2FuRGlzayB3aGljaCBtYXkgaGF2ZSAweDgwIGJpdCBzZXQgKi8KCQkJZnVuY19pZCA9ICpwICYgMHg3RjsKCQkJYnJlYWs7CgkJY2FzZSBDSVNUUExfRlVOQ0U6CgkJCWlmIChuX2ZlYXR1cmVzIDwgTUFYX0ZFQVRVUkVTKQoJCQkJZmVhdHVyZV9wW25fZmVhdHVyZXMrK10gPSBwOwoJCQlicmVhazsKCQljYXNlIENJU1RQTF9DT05GSUc6CgkJCWNvbmZpZ19iYXNlID0gKCoocCs2KSA8PCA4KSArICgqKHArNCkpOwoJCQlkZWJ1ZyAoIlxuIyMgQ29uZmlnX2Jhc2UgPSAlMDR4ICMjI1xuIiwgY29uZmlnX2Jhc2UpOwoJCWRlZmF1bHQ6CgkJCWJyZWFrOwoJCX0KCQlwICs9IDIgKiBsZW47Cgl9CgoJZm91bmQgPSBpZGVudGlmeShpZGVudCk7CgoJaWYgKGZ1bmNfaWQgIT0gKCh1Y2hhcil+MCkpIHsKCQlwcmludF9mdW5jaWQgKGZ1bmNfaWQpOwoKCQlpZiAoZnVuY19pZCA9PSBDSVNUUExfRlVOQ0lEX0ZJWEVEKQoJCQlmb3VuZCA9IDE7CgkJZWxzZQoJCQlyZXR1cm4gMTsJLyogbm8gZGlzayBkcml2ZSAqLwoJfQoKCWZvciAoaT0wOyBpPG5fZmVhdHVyZXM7ICsraSkgewoJCXByaW50X2ZpeGVkKGZlYXR1cmVfcFtpXSk7Cgl9CgoJaWYgKCFmb3VuZCkgewoJCXByaW50ZigidW5rbm93biBjYXJkIHR5cGVcbiIpOwoJCXJldHVybiAxOwoJfQoKCS8qIHNlbGVjdCBjb25maWcgaW5kZXggMSAqLwoJd3JpdGViKDEsIHBjbWNpYV9jaXNfcHRyICsgY29uZmlnX2Jhc2UpOwoKI2lmIDAKCXByaW50ZigiQ29uZml1cmF0aW9uIE9wdGlvbiBSZWdpc3RlcjogJTAyeFxuIiwgcmVhZGIocGNtY2lhX2Npc19wdHIgKyBjb25maWdfYmFzZSkpOwoJcHJpbnRmKCJDYXJkIENvbmZpdXJhdGlvbiBhbmQgU3RhdHVzIFJlZ2lzdGVyOiAlMDJ4XG4iLCByZWFkYihwY21jaWFfY2lzX3B0ciArIGNvbmZpZ19iYXNlICsgMikpOwoJcHJpbnRmKCJQaW4gUmVwbGFjZW1lbnQgUmVnaXN0ZXIgUmVnaXN0ZXI6ICUwMnhcbiIsIHJlYWRiKHBjbWNpYV9jaXNfcHRyICsgY29uZmlnX2Jhc2UgKyA0KSk7CglwcmludGYoIlNvY2tldCBhbmQgQ29weSBSZWdpc3RlcjogJTAyeFxuIiwgcmVhZGIocGNtY2lhX2Npc19wdHIgKyBjb25maWdfYmFzZSArIDYpKTsKI2VuZGlmCglpZGVfZGV2aWNlc19mb3VuZCB8PSAoMSA8PCAoc2xvdCtpZGVfYmFzZV9idXMpKTsKCglyZXR1cm4gMDsKfQoKCnN0YXRpYyBpbnQgdm9sdGFnZV9zZXQoaW50IHNsb3QsIGludCB2Y2MsIGludCB2cHApCnsKCXUzMiBzb2NrZXRfY29udHJvbDsKCWludCByZWc9MDsKCglzd2l0Y2ggKHNsb3QpIHsKCWNhc2UgMDoKCQlyZWcgPSBzb2NrZXRfYmFzZSArIDB4MTA7CgkJYnJlYWs7CglkZWZhdWx0OgoJCXJldHVybiAxOwoJfQoKCXNvY2tldF9jb250cm9sID0gMDsKCgoJc3dpdGNoICh2Y2MpIHsKCWNhc2UgNTA6CgkJc29ja2V0X2NvbnRyb2wgfD0gMHgyMDsKCQlicmVhazsKCWNhc2UgMzM6CgkJc29ja2V0X2NvbnRyb2wgfD0gMHgzMDsKCQlicmVhazsKCWNhc2UgMDoKCWRlZmF1bHQ6IDsKCX0KCglzd2l0Y2ggKHZwcCkgewoJY2FzZSAxMjA6CgkJc29ja2V0X2NvbnRyb2wgfD0gMHgxOwoJCWJyZWFrOwoJY2FzZSA1MDoKCQlzb2NrZXRfY29udHJvbCB8PSAweDI7CgkJYnJlYWs7CgljYXNlIDMzOgoJCXNvY2tldF9jb250cm9sIHw9IDB4MzsKCQlicmVhazsKCWNhc2UgMDoKCWRlZmF1bHQ6IDsKCX0KCgl3cml0ZWwoc29ja2V0X2NvbnRyb2wsIHJlZyk7CgoJZGVidWcgKCJ2b2x0YWdlX3NldDogVGkgUENJMTQxMEEgU2xvdCAlZCwgVmNjPSVkLiVkLCBWcHA9JWQuJWRcbiIsCgkJc2xvdCwgdmNjLzEwLCB2Y2MlMTAsIHZwcC8xMCwgdnBwJTEwKTsKCgl1ZGVsYXkoNTAwKTsKCXJldHVybiAwOwp9CgoKc3RhdGljIGludCBoYXJkd2FyZV9lbmFibGUoaW50IHNsb3QpCnsKCXUzMiBzb2NrZXRfc3RhdHVzOwoJdTE2IGJyZ19jdHJsOwoJaW50IGlzXzgyMzY1c2w7CgoJc29ja2V0X3N0YXR1cyA9IHJlYWRsKHNvY2tldF9iYXNlKzgpOwoKCWlmICgoc29ja2V0X3N0YXR1cyAmIDYpID09IDApIHsKCgkJc3dpdGNoIChzb2NrZXRfc3RhdHVzICYgMHgzYzAwKSB7CgoJCWNhc2UgMHg0MDA6CgkJCXByaW50ZigiNVYgIik7CgkJCXZvbHRhZ2Vfc2V0KHNsb3QsIDUwLCAwKTsKCQkJYnJlYWs7CgkJY2FzZSAweDgwMDoKCQkJdm9sdGFnZV9zZXQoc2xvdCwgMzMsIDApOwoJCQlicmVhazsKCQljYXNlIDB4YzAwOgoJCQl2b2x0YWdlX3NldChzbG90LCAzMywgMCk7CgkJCWJyZWFrOwoJCWRlZmF1bHQ6CgkJCXZvbHRhZ2Vfc2V0KHNsb3QsIDAsIDApOwoJCQlicmVhazsKCQl9Cgl9IGVsc2UgewoJCXZvbHRhZ2Vfc2V0KHNsb3QsIDAsIDApOwoJfQoKCXBjaV9yZWFkX2NvbmZpZ193b3JkKGRldmJ1c2ZuLCBQQ0lfQlJJREdFX0NPTlRST0wsICZicmdfY3RybCk7CglicmdfY3RybCAmPSB+UENJX0JSSURHRV9DVExfQlVTX1JFU0VUOwoJcGNpX3dyaXRlX2NvbmZpZ193b3JkKGRldmJ1c2ZuLCBQQ0lfQlJJREdFX0NPTlRST0wsIGJyZ19jdHJsKTsKCWlzXzgyMzY1c2wgPSAoKHJlYWRiKHNvY2tldF9iYXNlKzB4ODAwKSAmIDB4MGYpID09IDIpOwoJd3JpdGViKGlzXzgyMzY1c2w/MHg5MDoweDk4LCBzb2NrZXRfYmFzZSsweDgwMik7Cgl3cml0ZWIoMHg2Nywgc29ja2V0X2Jhc2UrMHg4MDMpOwoJdWRlbGF5KDEwMDAwMCk7CiNpZiAwCglwcmludGYoIkV4Q0EgSWQgJTAyeCwgQ2FyZCBTdGF0dXMgJTAyeCwgUG93ZXIgY29uZmlnICUwMngsIEludGVycnVwdCBDb25maWcgJTAyeCwgYnJpZGdlIGNvbnRyb2wgJTA0eCAlZFxuIiwKCSAgICAgICByZWFkYihzb2NrZXRfYmFzZSsweDgwMCksIHJlYWRiKHNvY2tldF9iYXNlKzB4ODAxKSwKCSAgICAgICByZWFkYihzb2NrZXRfYmFzZSsweDgwMiksIHJlYWRiKHNvY2tldF9iYXNlKzB4ODAzKSwgYnJnX2N0cmwsIGlzXzgyMzY1c2wpOwojZW5kaWYKCglyZXR1cm4gKChyZWFkYihzb2NrZXRfYmFzZSsweDgwMSkmMHg2Yyk9PTB4NmMpPzA6MTsKfQoKCnN0YXRpYyBpbnQgaGFyZHdhcmVfZGlzYWJsZShpbnQgc2xvdCkKewoJdm9sdGFnZV9zZXQoc2xvdCwgMCwgMCk7CglyZXR1cm4gMDsKfQoKc3RhdGljIHZvaWQgcHJpbnRfZnVuY2lkKGludCBmdW5jKQp7CglwdXRzKGluZGVudCk7Cglzd2l0Y2ggKGZ1bmMpIHsKCWNhc2UgQ0lTVFBMX0ZVTkNJRF9NVUxUSToKCQlwdXRzKCIgTXVsdGktRnVuY3Rpb24iKTsKCQlicmVhazsKCWNhc2UgQ0lTVFBMX0ZVTkNJRF9NRU1PUlk6CgkJcHV0cygiIE1lbW9yeSIpOwoJCWJyZWFrOwoJY2FzZSBDSVNUUExfRlVOQ0lEX1NFUklBTDoKCQlwdXRzKCIgU2VyaWFsIFBvcnQiKTsKCQlicmVhazsKCWNhc2UgQ0lTVFBMX0ZVTkNJRF9QQVJBTExFTDoKCQlwdXRzKCIgUGFyYWxsZWwgUG9ydCIpOwoJCWJyZWFrOwoJY2FzZSBDSVNUUExfRlVOQ0lEX0ZJWEVEOgoJCXB1dHMoIiBGaXhlZCBEaXNrIik7CgkJYnJlYWs7CgljYXNlIENJU1RQTF9GVU5DSURfVklERU86CgkJcHV0cygiIFZpZGVvIEFkYXB0ZXIiKTsKCQlicmVhazsKCWNhc2UgQ0lTVFBMX0ZVTkNJRF9ORVRXT1JLOgoJCXB1dHMoIiBOZXR3b3JrIEFkYXB0ZXIiKTsKCQlicmVhazsKCWNhc2UgQ0lTVFBMX0ZVTkNJRF9BSU1TOgoJCXB1dHMoIiBBSU1TIENhcmQiKTsKCQlicmVhazsKCWNhc2UgQ0lTVFBMX0ZVTkNJRF9TQ1NJOgoJCXB1dHMoIiBTQ1NJIEFkYXB0ZXIiKTsKCQlicmVhazsKCWRlZmF1bHQ6CgkJcHV0cygiIFVua25vd24iKTsKCQlicmVhazsKCX0KCXB1dHMoIiBDYXJkXG4iKTsKfQoKLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLwoKc3RhdGljIHZvaWQgcHJpbnRfZml4ZWQodm9sYXRpbGUgY2hhciAqcCkKewoJaWYgKHAgPT0gTlVMTCkKCQlyZXR1cm47CgoJcHV0cyhpbmRlbnQpOwoKCXN3aXRjaCAoKnApIHsKCWNhc2UgQ0lTVFBMX0ZVTkNFX0lERV9JRkFDRToKCQl7ICAgdWNoYXIgaWZhY2UgPSAqKHArMik7CgoJCQlwdXRzICgoaWZhY2UgPT0gQ0lTVFBMX0lERV9JTlRFUkZBQ0UpID8gIiBJREUiIDogIiB1bmtub3duIik7CgkJCXB1dHMgKCIgaW50ZXJmYWNlICIpOwoJCQlicmVhazsKCQl9CgljYXNlIENJU1RQTF9GVU5DRV9JREVfTUFTVEVSOgoJY2FzZSBDSVNUUExfRlVOQ0VfSURFX1NMQVZFOgoJCXsKCQkJdWNoYXIgZjEgPSAqKHArMik7CgkJCXVjaGFyIGYyID0gKihwKzQpOwoKCQkJcHV0cygoZjEgJiBDSVNUUExfSURFX1NJTElDT04pID8gIiBbc2lsaWNvbl0iIDogIiBbcm90YXRpbmddIik7CgoJCQlpZiAoZjEgJiBDSVNUUExfSURFX1VOSVFVRSkgewoJCQkJcHV0cygiIFt1bmlxdWVdIik7CgkJCX0KCgkJCXB1dHMoKGYxICYgQ0lTVFBMX0lERV9EVUFMKSA/ICIgW2R1YWxdIiA6ICIgW3NpbmdsZV0iKTsKCgkJCWlmIChmMiAmIENJU1RQTF9JREVfSEFTX1NMRUVQKSB7CgkJCQlwdXRzKCIgW3NsZWVwXSIpOwoJCQl9CgoJCQlpZiAoZjIgJiBDSVNUUExfSURFX0hBU19TVEFOREJZKSB7CgkJCQlwdXRzKCIgW3N0YW5kYnldIik7CgkJCX0KCgkJCWlmIChmMiAmIENJU1RQTF9JREVfSEFTX0lETEUpIHsKCQkJCXB1dHMoIiBbaWRsZV0iKTsKCQkJfQoKCQkJaWYgKGYyICYgQ0lTVFBMX0lERV9MT1dfUE9XRVIpIHsKCQkJCXB1dHMoIiBbbG93IHBvd2VyXSIpOwoJCQl9CgoJCQlpZiAoZjIgJiBDSVNUUExfSURFX1JFR19JTkhJQklUKSB7CgkJCQlwdXRzKCIgW3JlZyBpbmhpYml0XSIpOwoJCQl9CgoJCQlpZiAoZjIgJiBDSVNUUExfSURFX0hBU19JTkRFWCkgewoJCQkJcHV0cygiIFtpbmRleF0iKTsKCQkJfQoKCQkJaWYgKGYyICYgQ0lTVFBMX0lERV9JT0lTMTYpIHsKCQkJCXB1dHMoIiBbSU9pczE2XSIpOwoJCQl9CgoJCQlicmVhazsKCQl9Cgl9CglwdXRjKCdcbicpOwp9CgovKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovCgojZGVmaW5lIE1BWF9JREVOVF9DSEFSUwkJNjQKI2RlZmluZQlNQVhfSURFTlRfRklFTERTCTQKCnN0YXRpYyBjaGFyICprbm93bl9jYXJkc1tdID0gewoJIkFSR09TWSBQblBJREUgRDUiLAoJTlVMTAp9OwoKc3RhdGljIGludCBpZGVudGlmeSh2b2xhdGlsZSBjaGFyICpwKQp7CgljaGFyIGlkX3N0cltNQVhfSURFTlRfQ0hBUlNdOwoJY2hhciBkYXRhOwoJY2hhciAqdDsKCWNoYXIgKipjYXJkOwoJaW50IGksIGRvbmU7CgoJaWYgKHAgPT0gTlVMTCkKCQlyZXR1cm4gKDApOwkvKiBEb24ndCBrbm93ICovCgoJdCA9IGlkX3N0cjsKCWRvbmUgPTA7CgoJZm9yIChpPTA7IGk8PTQgJiYgIWRvbmU7ICsraSwgcCs9MikgewoJCXdoaWxlICgoZGF0YSA9ICpwKSAhPSAnXDAnKSB7CgkJCWlmIChkYXRhID09IDB4RkYpIHsKCQkJCWRvbmUgPSAxOwoJCQkJYnJlYWs7CgkJCX0KCQkJKnQrKyA9IGRhdGE7CgkJCWlmICh0ID09ICZpZF9zdHJbTUFYX0lERU5UX0NIQVJTLTFdKSB7CgkJCQlkb25lID0gMTsKCQkJCWJyZWFrOwoJCQl9CgkJCXAgKz0gMjsKCQl9CgkJaWYgKCFkb25lKQoJCQkqdCsrID0gJyAnOwoJfQoJKnQgPSAnXDAnOwoJd2hpbGUgKC0tdCA+IGlkX3N0cikgewoJCWlmICgqdCA9PSAnICcpIHsKCQkJKnQgPSAnXDAnOwoJCX0gZWxzZSB7CgkJCWJyZWFrOwoJCX0KCX0KCXB1dHMoaWRfc3RyKTsKCXB1dGMoJ1xuJyk7CgoJZm9yIChjYXJkPWtub3duX2NhcmRzOyAqY2FyZDsgKytjYXJkKSB7CgkJZGVidWcgKCIjIyBDb21wYXJlIGFnYWluc3QgXCIlc1wiXG4iLCAqY2FyZCk7CgkJaWYgKHN0cmNtcCgqY2FyZCwgaWRfc3RyKSA9PSAwKSB7CS8qIGZvdW5kISAqLwoJCQlkZWJ1ZyAoIiMjIENBUkQgRk9VTkQgIyNcbiIpOwoJCQlyZXR1cm4gMTsKCQl9Cgl9CgoJcmV0dXJuIDA7CS8qIGRvbid0IGtub3cgKi8KfQoKI2VuZGlmIC8qIENPTkZJR19DTURfUENNQ0lBICovCg==