LyoKICogKEMpIENvcHlyaWdodCAyMDAyCiAqIERhbmllbCBFbmdzdHL2bSwgT21pY3JvbiBDZXRpIEFCLCA8ZGFuaWVsQG9taWNyb24uc2U+CiAqCiAqIFNlZSBmaWxlIENSRURJVFMgZm9yIGxpc3Qgb2YgcGVvcGxlIHdobyBjb250cmlidXRlZCB0byB0aGlzCiAqIHByb2plY3QuCiAqCiAqIFRoaXMgcHJvZ3JhbSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IKICogbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgYXMKICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlciB2ZXJzaW9uIDIgb2YKICogdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uCiAqCiAqIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLAogKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZgogKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlCiAqIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIGFsb25nIHdpdGggdGhpcyBwcm9ncmFtOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlCiAqIEZvdW5kYXRpb24sIEluYy4sIDU5IFRlbXBsZSBQbGFjZSwgU3VpdGUgMzMwLCBCb3N0b24sCiAqIE1BIDAyMTExLTEzMDcgVVNBCiAqLwoKI2luY2x1ZGUgPGNvbW1vbi5oPgojaW5jbHVkZSA8cGNpLmg+CiNpbmNsdWRlIDxtYWxsb2MuaD4KI2luY2x1ZGUgPGFzbS9wdHJhY2UuaD4KI2luY2x1ZGUgPGFzbS9yZWFsbW9kZS5oPgojaW5jbHVkZSA8YXNtL2lvLmg+CiNpbmNsdWRlIDxhc20vcGNpLmg+CgojdW5kZWYgUENJX0JJT1NfREVCVUcKI3VuZGVmIFZHQV9CSU9TX0RFQlVHCgojaWZkZWYJVkdBX0JJT1NfREVCVUcKI2RlZmluZQlQUklOVEYoZm10LGFyZ3MuLi4pCXByaW50ZiAoZm10ICwjI2FyZ3MpCiNlbHNlCiNkZWZpbmUgUFJJTlRGKGZtdCxhcmdzLi4uKQojZW5kaWYKCiNpZmRlZiBDT05GSUdfUENJCgojaWZkZWYgUENJX0JJT1NfREVCVUcKI2RlZmluZSBSRUxPQ18xNihzZWcsIG9mZikgKih1MzIqKShzZWcgPDwgNCB8ICh1MzIpJm9mZikKZXh0ZXJuIHUzMiBudW1fcGNpX2Jpb3NfcHJlc2VudDsKZXh0ZXJuIHUzMiBudW1fcGNpX2Jpb3NfZmluZF9kZXZpY2U7CmV4dGVybiB1MzIgbnVtX3BjaV9iaW9zX2ZpbmRfY2xhc3M7CmV4dGVybiB1MzIgbnVtX3BjaV9iaW9zX2dlbmVyYXRlX3NwZWNpYWxfY3ljbGU7CmV4dGVybiB1MzIgbnVtX3BjaV9iaW9zX3JlYWRfY2ZnX2J5dGU7CmV4dGVybiB1MzIgbnVtX3BjaV9iaW9zX3JlYWRfY2ZnX3dvcmQ7CmV4dGVybiB1MzIgbnVtX3BjaV9iaW9zX3JlYWRfY2ZnX2R3b3JkOwpleHRlcm4gdTMyIG51bV9wY2lfYmlvc193cml0ZV9jZmdfYnl0ZTsKZXh0ZXJuIHUzMiBudW1fcGNpX2Jpb3Nfd3JpdGVfY2ZnX3dvcmQ7CmV4dGVybiB1MzIgbnVtX3BjaV9iaW9zX3dyaXRlX2NmZ19kd29yZDsKZXh0ZXJuIHUzMiBudW1fcGNpX2Jpb3NfZ2V0X2lycV9yb3V0aW5nOwpleHRlcm4gdTMyIG51bV9wY2lfYmlvc19zZXRfaXJxOwpleHRlcm4gdTMyIG51bV9wY2lfYmlvc191bmtub3duX2Z1bmN0aW9uOwoKdm9pZCBwcmludF9iaW9zX2Jpb3Nfc3RhdCh2b2lkKQp7CglwcmludGYoIjE2IGJpdCBmdW5jdGlvbnM6XG4iKTsKCXByaW50ZigicGNpX2Jpb3NfcHJlc2VudDogICAgICAgICAgICAgICAgJWRcbiIsIFJFTE9DXzE2KDB4ZjAwMCwgbnVtX3BjaV9iaW9zX3ByZXNlbnQpKTsKCXByaW50ZigicGNpX2Jpb3NfZmluZF9kZXZpY2U6ICAgICAgICAgICAgJWRcbiIsIFJFTE9DXzE2KDB4ZjAwMCwgbnVtX3BjaV9iaW9zX2ZpbmRfZGV2aWNlKSk7CglwcmludGYoInBjaV9iaW9zX2ZpbmRfY2xhc3M6ICAgICAgICAgICAgICVkXG4iLCBSRUxPQ18xNigweGYwMDAsIG51bV9wY2lfYmlvc19maW5kX2NsYXNzKSk7CglwcmludGYoInBjaV9iaW9zX2dlbmVyYXRlX3NwZWNpYWxfY3ljbGU6ICVkXG4iLCBSRUxPQ18xNigweGYwMDAsIG51bV9wY2lfYmlvc19nZW5lcmF0ZV9zcGVjaWFsX2N5Y2xlKSk7CglwcmludGYoInBjaV9iaW9zX3JlYWRfY2ZnX2J5dGU6ICAgICAgICAgICVkXG4iLCBSRUxPQ18xNigweGYwMDAsIG51bV9wY2lfYmlvc19yZWFkX2NmZ19ieXRlKSk7CglwcmludGYoInBjaV9iaW9zX3JlYWRfY2ZnX3dvcmQ6ICAgICAgICAgICVkXG4iLCBSRUxPQ18xNigweGYwMDAsIG51bV9wY2lfYmlvc19yZWFkX2NmZ193b3JkKSk7CglwcmludGYoInBjaV9iaW9zX3JlYWRfY2ZnX2R3b3JkOiAgICAgICAgICVkXG4iLCBSRUxPQ18xNigweGYwMDAsIG51bV9wY2lfYmlvc19yZWFkX2NmZ19kd29yZCkpOwoJcHJpbnRmKCJwY2lfYmlvc193cml0ZV9jZmdfYnl0ZTogICAgICAgICAlZFxuIiwgUkVMT0NfMTYoMHhmMDAwLCBudW1fcGNpX2Jpb3Nfd3JpdGVfY2ZnX2J5dGUpKTsKCXByaW50ZigicGNpX2Jpb3Nfd3JpdGVfY2ZnX3dvcmQ6ICAgICAgICAgJWRcbiIsIFJFTE9DXzE2KDB4ZjAwMCwgbnVtX3BjaV9iaW9zX3dyaXRlX2NmZ193b3JkKSk7CglwcmludGYoInBjaV9iaW9zX3dyaXRlX2NmZ19kd29yZDogICAgICAgICVkXG4iLCBSRUxPQ18xNigweGYwMDAsIG51bV9wY2lfYmlvc193cml0ZV9jZmdfZHdvcmQpKTsKCXByaW50ZigicGNpX2Jpb3NfZ2V0X2lycV9yb3V0aW5nOiAgICAgICAgJWRcbiIsIFJFTE9DXzE2KDB4ZjAwMCwgbnVtX3BjaV9iaW9zX2dldF9pcnFfcm91dGluZykpOwoJcHJpbnRmKCJwY2lfYmlvc19zZXRfaXJxOiAgICAgICAgICAgICAgICAlZFxuIiwgUkVMT0NfMTYoMHhmMDAwLCBudW1fcGNpX2Jpb3Nfc2V0X2lycSkpOwoJcHJpbnRmKCJwY2lfYmlvc191bmtub3duX2Z1bmN0aW9uOiAgICAgICAlZFxuIiwgUkVMT0NfMTYoMHhmMDAwLCBudW1fcGNpX2Jpb3NfdW5rbm93bl9mdW5jdGlvbikpOwoKfQojZW5kaWYKCiNpZmRlZiBDT05GSUdfVklERU8KCiNkZWZpbmUgUENJX0NMQVNTX1ZJREVPICAgICAgICAgICAgIDMKI2RlZmluZSBQQ0lfQ0xBU1NfVklERU9fU1REICAgICAgICAgMAojZGVmaW5lIFBDSV9DTEFTU19WSURFT19QUk9HX0lGX1ZHQSAwCgpzdGF0aWMgc3RydWN0IHBjaV9kZXZpY2VfaWQgc3VwcG9ydGVkW10gPSB7Cgl7UENJX1ZJREVPX1ZFTkRPUl9JRCwgUENJX1ZJREVPX0RFVklDRV9JRH0sCgl7fQp9OwoKc3RhdGljIHUzMiBwcm9iZV9wY2lfdmlkZW8odm9pZCkKewoJcGNpX2Rldl90IGRldmJ1c2ZuOwoKCWlmICgoZGV2YnVzZm4gPSBwY2lfZmluZF9kZXZpY2VzKHN1cHBvcnRlZCwgMCkgIT0gLTEpKSB7CgkJdTMyIG9sZDsKCQl1MzIgYWRkcjsKCgkJLyogUENJIHZpZGVvIGRldmljZSBkZXRlY3RlZCAqLwoJCXByaW50ZigiRm91bmQgUENJIFZHQSBkZXZpY2UgYXQgJTAyeC4lMDJ4LiV4XG4iLAoJCSAgICAgICBQQ0lfQlVTKGRldmJ1c2ZuKSwgUENJX0RFVihkZXZidXNmbiksIFBDSV9GVU5DKGRldmJ1c2ZuKSk7CgoJCS8qIEVuYWJsZSBJL08gZGVjb2RpbmcgYXMgd2VsbCwgUENJIHZpdWRlbyBib2FyZHMKCQkgKiBzdXBwb3J0IEkvTyBhY2Nlc3NlcywgYnV0IHRoZXkgcHJvdmlkZSBubwoJCSAqIGJhciByZWdpc3RlciBmb3IgdGhpcyBzaW5jZSB0aGUgcG9ydHMgYXJlIGZpeGVkLgoJCSAqLwoJCXBjaV93cml0ZV9jb25maWdfd29yZChkZXZidXNmbiwgUENJX0NPTU1BTkQsIFBDSV9DT01NQU5EX01FTU9SWSB8IFBDSV9DT01NQU5EX0lPIHwgUENJX0NPTU1BTkRfTUFTVEVSKTsKCgkJLyogVGVzdCB0aGUgUk9NIGRlY29kZXIsIGRvIHRoZSBkZXZpY2Ugc3VwcG9ydCBhIHJvbT8gKi8KCQlwY2lfcmVhZF9jb25maWdfZHdvcmQoZGV2YnVzZm4sIFBDSV9ST01fQUREUkVTUywgJm9sZCk7CgkJcGNpX3dyaXRlX2NvbmZpZ19kd29yZChkZXZidXNmbiwgUENJX1JPTV9BRERSRVNTLCAodTMyKVBDSV9ST01fQUREUkVTU19NQVNLKTsKCQlwY2lfcmVhZF9jb25maWdfZHdvcmQoZGV2YnVzZm4sIFBDSV9ST01fQUREUkVTUywgJmFkZHIpOwoJCXBjaV93cml0ZV9jb25maWdfZHdvcmQoZGV2YnVzZm4sIFBDSV9ST01fQUREUkVTUywgb2xkKTsKCgkJaWYgKCFhZGRyKSB7CgkJCXByaW50ZigiUENJIFZHQSBoYXZlIG5vIFJPTT9cbiIpOwoJCQlyZXR1cm4gMDsKCQl9CgoJCS8qIGRldmljZSBoYXZlIGEgcm9tICovCgkJaWYgKHBjaV9zaGFkb3dfcm9tKGRldmJ1c2ZuLCAodm9pZCopMHhjMDAwMCkpIHsKCQkJcHJpbnRmKCJTaGFkb3dpbmcgb2YgUENJIFZHQSBCSU9TIGZhaWxlZFxuIik7CgkJCXJldHVybiAwOwoJCX0KCgkJLyogTm93IGVuYWJsZSBsYWdhY3kgVkdBIHBvcnQgYWNjZXNzICovCgkJaWYgKHBjaV9lbmFibGVfbGVnYWN5X3ZpZGVvX3BvcnRzKHBjaV9idXNfdG9faG9zZShQQ0lfQlVTKGRldmJ1c2ZuKSkpKSB7CgkJCXByaW50ZigiUENJIFZHQSBlbmFibGUgZmFpbGVkXG4iKTsKCQkJcmV0dXJuIDA7CgkJfQoKCgkJLyogcmV0dXJuIHRoZSBwY2kgZGV2aWNlIGluZm8sIHRoYXQgd2UnbGwgbmVlZCBsYXRlciAqLwoJCXJldHVybiBQQ0lfQlVTKGRldmJ1c2ZuKSA8PCA4IHwKCQkJUENJX0RFVihkZXZidXNmbikgPDwgMyB8IChQQ0lfRlVOQyhkZXZidXNmbikmNyk7Cgl9CgoJcmV0dXJuIDA7Cn0KCnN0YXRpYyBpbnQgcHJvYmVfaXNhX3ZpZGVvKHZvaWQpCnsKCXUzMiBwdHI7CgljaGFyICpidWY7CgoJaWYgKDAgPT0gKHB0ciA9IGlzYV9tYXBfcm9tKDB4YzAwMDAsIDB4ODAwMCkpKSB7CgkJcmV0dXJuIC0xOwoJfQoJaWYgKE5VTEwgPT0gKGJ1Zj1tYWxsb2MoMHg4MDAwKSkpIHsKCQlpc2FfdW5tYXBfcm9tKHB0cik7CgkJcmV0dXJuIC0xOwoJfQoJaWYgKHJlYWR3KHB0cikgIT0gMHhhYTU1KSB7CgkJZnJlZShidWYpOwoJCWlzYV91bm1hcF9yb20ocHRyKTsKCQlyZXR1cm4gLTE7Cgl9CgoJLyogc2hhZG93IHRoZSByb20gKi8KCW1lbWNweShidWYsICh2b2lkKilwdHIsIDB4ODAwMCk7Cglpc2FfdW5tYXBfcm9tKHB0cik7CgltZW1jcHkoKHZvaWQqKTB4YzAwMDAsIGJ1ZiwgMHg4MDAwKTsKCglmcmVlKGJ1Zik7CgoJcmV0dXJuIDA7Cn0KCmludCB2aWRlb19iaW9zX2luaXQodm9pZCkKewoJc3RydWN0IHB0X3JlZ3MgcmVnczsKCgkvKiBjbGVhciB0aGUgdmlkZW8gYmlvcyBhcmVhIGluIGNhc2Ugd2Ugd2FybWJvb3RlZCAqLwoJbWVtc2V0KCh2b2lkKikweGMwMDAwLCAwLCAweDgwMDApOwoJbWVtc2V0KCZyZWdzLCAwLCBzaXplb2Yoc3RydWN0IHB0X3JlZ3MpKTsKCglpZiAocHJvYmVfaXNhX3ZpZGVvKCkpIHsKCQkvKiBObyBJU0EgYm9hcmQgZm91bmQsIHRyeSB0aGUgUENJIGJ1cyAqLwoJCXJlZ3MuZWF4ID0gcHJvYmVfcGNpX3ZpZGVvKCk7Cgl9CgoJLyogRGlkIHdlIHN1Y2NlZWQgaW4gbWFwcGluZyBhbnkgdmlkZW8gYmlvcyAqLwoJaWYgKHJlYWR3KDB4YzAwMDApID09IDB4YWE1NSkgewoJICAgICAgICBpbnQgc2l6ZTsKCQlpbnQgaTsKCQl1OCBzdW07CgoJCVBSSU5URigiRm91bmQgdmlkZW8gYmlvcyBzaWduYXR1cmVcbiIpOwoJCXNpemUgPSA1MTIqcmVhZGIoMHhjMDAwMik7CgkJUFJJTlRGKCJzaXplICVkXG4iLCBzaXplKTsKCQlzdW09MDsKCQlmb3IgKGk9MDtpPHNpemU7aSsrKSB7CgkJCXN1bSArPSByZWFkYigweGMwMDAwICsgaSk7CgkJfQoJCVBSSU5URigiQ2hlY2tzdW0gaXMgJXNPS1xuIixzdW0/Ik5PVCAiOiIiKTsKCQlpZiAoc3VtKSB7CgkJCXJldHVybiAxOwoJCX0KCgkJLyogc29tZSB2aWRlbyBiaW9zZXMgKEFUSSBNYWNoNjQpIHNlZW0gdG8gdGhpbmsgdGhhdAoJCSAqIHRoZSBvcmlnaW5hbCBpbnQgMTAgaGFuZGxlciBpcyBhbHdheXMgYXQKCQkgKiAweGYwMDA6MHhmMDY1ICwgcGxhY2UgYW4gaXJldCBpbnN0cnVjdGlvbiB0aGVyZQoJCSAqLwoJCXdyaXRlYigweGNmLCAweGZmMDY1KTsKCgkJcmVncy5lc3AgPSAweDgwMDA7CgkJcmVncy54c3MgPSAweDIwMDA7CgkJZW50ZXJfcmVhbG1vZGUoMHhjMDAwLCAzLCAmcmVncywgJnJlZ3MpOwoJCVBSSU5URigiSU5UIDB4MTAgdmVjdG9yIGFmdGVyOiAgJTA0eDolMDR4XG4iLAoJCSAgICAgICByZWFkdygweDQyKSwgcmVhZHcoMHg0MCkpOwoJCVBSSU5URigiQklPUyByZXR1cm5lZCAlc2NhcnJ5XG4iLCByZWdzLmVmbGFncyAmIDE/IiI6Ik5PVCAiKTsKI2lmZGVmIFBDSV9CSU9TX0RFQlVHCgkJcHJpbnRfYmlvc19iaW9zX3N0YXQoKTsKI2VuZGlmCgkJcmV0dXJuIChyZWdzLmVmbGFncyAmIDEpOwoKCX0KCglyZXR1cm4gMTsKCn0KI2VuZGlmCiNlbmRpZgo=