LyoKICogKEMpIENvcHlyaWdodCAyMDAyCiAqIERhbmllbCBFbmdzdHL2bSwgT21pY3JvbiBDZXRpIEFCLCBkYW5pZWxAb21pY3Jvbi5zZQogKgogKiBTZWUgZmlsZSBDUkVESVRTIGZvciBsaXN0IG9mIHBlb3BsZSB3aG8gY29udHJpYnV0ZWQgdG8gdGhpcwogKiBwcm9qZWN0LgogKgogKiBUaGlzIHByb2dyYW0gaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yCiAqIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGFzCiAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXIgdmVyc2lvbiAyIG9mCiAqIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLgogKgogKiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwKICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YKICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZQogKiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQogKiBhbG9uZyB3aXRoIHRoaXMgcHJvZ3JhbTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZQogKiBGb3VuZGF0aW9uLCBJbmMuLCA1OSBUZW1wbGUgUGxhY2UsIFN1aXRlIDMzMCwgQm9zdG9uLAogKiBNQSAwMjExMS0xMzA3IFVTQQogKi8KCiNpbmNsdWRlIDxjb21tb24uaD4gCiNpbmNsdWRlIDxwY2kuaD4gCiNpbmNsdWRlIDxtYWxsb2MuaD4gCiNpbmNsdWRlIDxhc20vcHRyYWNlLmg+IAojaW5jbHVkZSA8YXNtL3JlYWxtb2RlLmg+IAojaW5jbHVkZSA8YXNtL2lvLmg+IAojaW5jbHVkZSA8YXNtL3BjaS5oPiAKCiN1bmRlZiBQQ0lfQklPU19ERUJVRwojdW5kZWYgVkdBX0JJT1NfREVCVUcKCiNpZmRlZglWR0FfQklPU19ERUJVRwojZGVmaW5lCVBSSU5URihmbXQsYXJncy4uLikJcHJpbnRmIChmbXQgLCMjYXJncykKI2Vsc2UKI2RlZmluZSBQUklOVEYoZm10LGFyZ3MuLi4pCiNlbmRpZgoKI2lmZGVmIENPTkZJR19QQ0kKCiNpZmRlZiBQQ0lfQklPU19ERUJVRwojZGVmaW5lIFJFTE9DXzE2KHNlZywgb2ZmKSAqKHUzMiopKHNlZyA8PCA0IHwgKHUzMikmb2ZmKSAKZXh0ZXJuIHUzMiBudW1fcGNpX2Jpb3NfcHJlc2VudDsKZXh0ZXJuIHUzMiBudW1fcGNpX2Jpb3NfZmluZF9kZXZpY2U7CmV4dGVybiB1MzIgbnVtX3BjaV9iaW9zX2ZpbmRfY2xhc3M7CmV4dGVybiB1MzIgbnVtX3BjaV9iaW9zX2dlbmVyYXRlX3NwZWNpYWxfY3ljbGU7CmV4dGVybiB1MzIgbnVtX3BjaV9iaW9zX3JlYWRfY2ZnX2J5dGU7CmV4dGVybiB1MzIgbnVtX3BjaV9iaW9zX3JlYWRfY2ZnX3dvcmQ7CmV4dGVybiB1MzIgbnVtX3BjaV9iaW9zX3JlYWRfY2ZnX2R3b3JkOwpleHRlcm4gdTMyIG51bV9wY2lfYmlvc193cml0ZV9jZmdfYnl0ZTsKZXh0ZXJuIHUzMiBudW1fcGNpX2Jpb3Nfd3JpdGVfY2ZnX3dvcmQ7CmV4dGVybiB1MzIgbnVtX3BjaV9iaW9zX3dyaXRlX2NmZ19kd29yZDsKZXh0ZXJuIHUzMiBudW1fcGNpX2Jpb3NfZ2V0X2lycV9yb3V0aW5nOwpleHRlcm4gdTMyIG51bV9wY2lfYmlvc19zZXRfaXJxOwpleHRlcm4gdTMyIG51bV9wY2lfYmlvc191bmtub3duX2Z1bmN0aW9uOwoKdm9pZCBwcmludF9iaW9zX2Jpb3Nfc3RhdCh2b2lkKQp7CglwcmludGYoIjE2IGJpdCBmdW5jdGlvbnM6XG4iKTsKCXByaW50ZigicGNpX2Jpb3NfcHJlc2VudDogICAgICAgICAgICAgICAgJWRcbiIsIFJFTE9DXzE2KDB4ZjAwMCwgbnVtX3BjaV9iaW9zX3ByZXNlbnQpKTsKCXByaW50ZigicGNpX2Jpb3NfZmluZF9kZXZpY2U6ICAgICAgICAgICAgJWRcbiIsIFJFTE9DXzE2KDB4ZjAwMCwgbnVtX3BjaV9iaW9zX2ZpbmRfZGV2aWNlKSk7CglwcmludGYoInBjaV9iaW9zX2ZpbmRfY2xhc3M6ICAgICAgICAgICAgICVkXG4iLCBSRUxPQ18xNigweGYwMDAsIG51bV9wY2lfYmlvc19maW5kX2NsYXNzKSk7CglwcmludGYoInBjaV9iaW9zX2dlbmVyYXRlX3NwZWNpYWxfY3ljbGU6ICVkXG4iLCBSRUxPQ18xNigweGYwMDAsIG51bV9wY2lfYmlvc19nZW5lcmF0ZV9zcGVjaWFsX2N5Y2xlKSk7CQoJcHJpbnRmKCJwY2lfYmlvc19yZWFkX2NmZ19ieXRlOiAgICAgICAgICAlZFxuIiwgUkVMT0NfMTYoMHhmMDAwLCBudW1fcGNpX2Jpb3NfcmVhZF9jZmdfYnl0ZSkpOwoJcHJpbnRmKCJwY2lfYmlvc19yZWFkX2NmZ193b3JkOiAgICAgICAgICAlZFxuIiwgUkVMT0NfMTYoMHhmMDAwLCBudW1fcGNpX2Jpb3NfcmVhZF9jZmdfd29yZCkpOwoJcHJpbnRmKCJwY2lfYmlvc19yZWFkX2NmZ19kd29yZDogICAgICAgICAlZFxuIiwgUkVMT0NfMTYoMHhmMDAwLCBudW1fcGNpX2Jpb3NfcmVhZF9jZmdfZHdvcmQpKTsKCXByaW50ZigicGNpX2Jpb3Nfd3JpdGVfY2ZnX2J5dGU6ICAgICAgICAgJWRcbiIsIFJFTE9DXzE2KDB4ZjAwMCwgbnVtX3BjaV9iaW9zX3dyaXRlX2NmZ19ieXRlKSk7CglwcmludGYoInBjaV9iaW9zX3dyaXRlX2NmZ193b3JkOiAgICAgICAgICVkXG4iLCBSRUxPQ18xNigweGYwMDAsIG51bV9wY2lfYmlvc193cml0ZV9jZmdfd29yZCkpOwoJcHJpbnRmKCJwY2lfYmlvc193cml0ZV9jZmdfZHdvcmQ6ICAgICAgICAlZFxuIiwgUkVMT0NfMTYoMHhmMDAwLCBudW1fcGNpX2Jpb3Nfd3JpdGVfY2ZnX2R3b3JkKSk7CglwcmludGYoInBjaV9iaW9zX2dldF9pcnFfcm91dGluZzogICAgICAgICVkXG4iLCBSRUxPQ18xNigweGYwMDAsIG51bV9wY2lfYmlvc19nZXRfaXJxX3JvdXRpbmcpKTsKCXByaW50ZigicGNpX2Jpb3Nfc2V0X2lycTogICAgICAgICAgICAgICAgJWRcbiIsIFJFTE9DXzE2KDB4ZjAwMCwgbnVtX3BjaV9iaW9zX3NldF9pcnEpKTsKCXByaW50ZigicGNpX2Jpb3NfdW5rbm93bl9mdW5jdGlvbjogICAgICAgJWRcbiIsIFJFTE9DXzE2KDB4ZjAwMCwgbnVtX3BjaV9iaW9zX3Vua25vd25fZnVuY3Rpb24pKTsKCn0KI2VuZGlmCgojZGVmaW5lIFBDSV9DTEFTU19WSURFTyAgICAgICAgICAgICAzCiNkZWZpbmUgUENJX0NMQVNTX1ZJREVPX1NURCAgICAgICAgIDAKI2RlZmluZSBQQ0lfQ0xBU1NfVklERU9fUFJPR19JRl9WR0EgMAoKCnN0YXRpYyB1MzIgcHJvYmVfcGNpX3ZpZGVvKHZvaWQpCnsKCXBjaV9kZXZfdCBkZXZidXNmbjsKCQoJaWYgKChkZXZidXNmbiA9IHBjaV9maW5kX2NsYXNzKFBDSV9DTEFTU19WSURFTywgCgkJCQkgICAgICAgUENJX0NMQVNTX1ZJREVPX1NURCwgCgkJCQkgICAgICAgUENJX0NMQVNTX1ZJREVPX1BST0dfSUZfVkdBLCAwKSkgIT0gLTEpIHsKCQl1MzIgb2xkOwoJCXUzMiBhZGRyOwoJCQoJCS8qIFBDSSB2aWRlbyBkZXZpY2UgZGV0ZWN0ZWQgKi8KCQlwcmludGYoIkZvdW5kIFBDSSBWR0EgZGV2aWNlIGF0ICUwMnguJTAyeC4leFxuIiwgCgkJICAgICAgIFBDSV9CVVMoZGV2YnVzZm4pLCBQQ0lfREVWKGRldmJ1c2ZuKSwgUENJX0ZVTkMoZGV2YnVzZm4pKTsKCQkKCQkvKiBFbmFibGUgSS9PIGRlY29kaW5nIGFzIHdlbGwsIFBDSSB2aXVkZW8gYm9hcmRzCgkJICogc3VwcG9ydCBJL08gYWNjZXNzZXMsIGJ1dCB0aGV5IHByb3ZpZGUgbm8KCQkgKiBiYXIgcmVnaXN0ZXIgZm9yIHRoaXMgc2luY2UgdGhlIHBvcnRzIGFyZSBmaXhlZC4KCQkgKi8KCQlwY2lfd3JpdGVfY29uZmlnX3dvcmQoZGV2YnVzZm4sIFBDSV9DT01NQU5ELCBQQ0lfQ09NTUFORF9NRU1PUlkgfCBQQ0lfQ09NTUFORF9JTyB8IFBDSV9DT01NQU5EX01BU1RFUik7CgkJCgkJLyogVGVzdCB0aGUgUk9NIGRlY29kZXIsIGRvIHRoZSBkZXZpY2Ugc3VwcG9ydCBhIHJvbT8gKi8KCQlwY2lfcmVhZF9jb25maWdfZHdvcmQoZGV2YnVzZm4sIFBDSV9ST01fQUREUkVTUywgJm9sZCk7CQkKCQlwY2lfd3JpdGVfY29uZmlnX2R3b3JkKGRldmJ1c2ZuLCBQQ0lfUk9NX0FERFJFU1MsIFBDSV9ST01fQUREUkVTU19NQVNLKTsKCQlwY2lfcmVhZF9jb25maWdfZHdvcmQoZGV2YnVzZm4sIFBDSV9ST01fQUREUkVTUywgJmFkZHIpOwoJCXBjaV93cml0ZV9jb25maWdfZHdvcmQoZGV2YnVzZm4sIFBDSV9ST01fQUREUkVTUywgb2xkKTsKCQkJCQoJCWlmICghYWRkcikgewoJCQlwcmludGYoIlBDSSBWR0EgaGF2ZSBubyBST00/XG4iKTsKCQkJcmV0dXJuIDA7CgkJfQoJCQoJCS8qIGRldmljZSBoYXZlIGEgcm9tICovCgkJaWYgKHBjaV9zaGFkb3dfcm9tKGRldmJ1c2ZuLCAodm9pZCopMHhjMDAwMCkpIHsgCgkJCXByaW50ZigiU2hhZG93aW5nIG9mIFBDSSBWR0EgQklPUyBmYWlsZWRcbiIpOwoJCQlyZXR1cm4gMDsKCQl9CgkJCgkJLyogTm93IGVuYWJsZSBsYWdhY3kgVkdBIHBvcnQgYWNjZXNzICovCgkJaWYgKHBjaV9lbmFibGVfbGVnYWN5X3ZpZGVvX3BvcnRzKHBjaV9idXNfdG9faG9zZShQQ0lfQlVTKGRldmJ1c2ZuKSkpKSB7CgkJCXByaW50ZigiUENJIFZHQSBlbmFibGUgZmFpbGVkXG4iKTsKCQkJcmV0dXJuIDA7CgkJfQoJCQkJCgkKCQkvKiByZXR1cm4gdGhlIHBjaSBkZXZpY2UgaW5mbywgdGhhdCB3ZSdsbCBuZWVkIGxhdGVyICovCgkJcmV0dXJuIFBDSV9CVVMoZGV2YnVzZm4pIDw8IDggfCAKCQkJUENJX0RFVihkZXZidXNmbikgPDwgMyB8IChQQ0lfRlVOQyhkZXZidXNmbikmNyk7Cgl9CgkKCXJldHVybiAwOwp9CgoKI2VuZGlmCgpzdGF0aWMgaW50IHByb2JlX2lzYV92aWRlbyh2b2lkKQp7Cgl1MzIgcHRyOwoJY2hhciAqYnVmOwkKCQoJaWYgKDAgPT0gKHB0ciA9IGlzYV9tYXBfcm9tKDB4YzAwMDAsIDB4ODAwMCkpKSB7CgkJcmV0dXJuIC0xOwoJfQoJaWYgKE5VTEwgPT0gKGJ1Zj1tYWxsb2MoMHg4MDAwKSkpIHsKCQlpc2FfdW5tYXBfcm9tKHB0cik7CgkJcmV0dXJuIC0xOwoJfQoJaWYgKHJlYWR3KHB0cikgIT0gMHhhYTU1KSB7CgkJZnJlZShidWYpOwoJCWlzYV91bm1hcF9yb20ocHRyKTsKCQlyZXR1cm4gLTE7Cgl9CgkKCS8qIHNoYWRvdyB0aGUgcm9tICovCgltZW1jcHkoYnVmLCAodm9pZCopcHRyLCAweDgwMDApOwoJaXNhX3VubWFwX3JvbShwdHIpOwoJbWVtY3B5KCh2b2lkKikweGMwMDAwLCBidWYsIDB4ODAwMCk7CgkKCWZyZWUoYnVmKTsKCQoJcmV0dXJuIDA7Cn0KCmludCB2aWRlb19iaW9zX2luaXQodm9pZCkKewoJc3RydWN0IHB0X3JlZ3MgcmVnczsKCgkvKiBjbGVhciB0aGUgdmlkZW8gYmlvcyBhcmVhIGluIGNhc2Ugd2Ugd2FybWJvb3RlZCAqLwoJbWVtc2V0KCh2b2lkKikweGMwMDAwLCAwLCAweDgwMDApOwkKCW1lbXNldCgmcmVncywgMCwgc2l6ZW9mKHN0cnVjdCBwdF9yZWdzKSk7CgkKCWlmIChwcm9iZV9pc2FfdmlkZW8oKSkgewoJCS8qIE5vIElTQSBib2FyZCBmb3VuZCwgdHJ5IHRoZSBQQ0kgYnVzICovCgkJcmVncy5lYXggPSBwcm9iZV9wY2lfdmlkZW8oKTsKCX0KCQoJLyogRGlkIHdlIHN1Y2NlZWQgaW4gbWFwcGluZyBhbnkgdmlkZW8gYmlvcyAqLwoJaWYgKHJlYWR3KDB4YzAwMDApID09IDB4YWE1NSkgewoJICAgICAgICBpbnQgc2l6ZTsKCQlpbnQgaTsKCQl1OCBzdW07CgkJCgkJUFJJTlRGKCJGb3VuZCB2aWRlbyBiaW9zIHNpZ25hdHVyZVxuIik7CgkJc2l6ZSA9IDUxMipyZWFkYigweGMwMDAyKTsKCQlQUklOVEYoInNpemUgJWRcbiIsIHNpemUpOwoJCXN1bT0wOwoJCWZvciAoaT0wO2k8c2l6ZTtpKyspIHsKCQkJc3VtICs9IHJlYWRiKDB4YzAwMDAgKyBpKTsKCQl9CgkJUFJJTlRGKCJDaGVja3N1bSBpcyAlc09LXG4iLHN1bT8iTk9UICI6IiIpOwoJCWlmIChzdW0pIHsKCQkJcmV0dXJuIDE7CgkJfQoJCQoJCS8qIHNvbWUgdmlkZW8gYmlvc2VzIChBVEkgTWFjaDY0KSBzZWVtIHRvIHRoaW5rIHRoYXQKCQkgKiB0aGUgb3JpZ2luYWwgaW50IDEwIGhhbmRsZXIgaXMgYWx3YXlzIGF0CgkJICogMHhmMDAwOjB4ZjA2NSAsIHBsYWNlIGFuIGlyZXQgaW5zdHJ1Y3Rpb24gdGhlcmUKCQkgKi8KCQl3cml0ZWIoMHhjZiwgMHhmZjA2NSk7CgkJCgkJcmVncy5lc3AgPSAweDgwMDA7CgkJcmVncy54c3MgPSAweDIwMDA7CgkJZW50ZXJfcmVhbG1vZGUoMHhjMDAwLCAzLCAmcmVncywgJnJlZ3MpOwoJCVBSSU5URigiSU5UIDB4MTAgdmVjdG9yIGFmdGVyOiAgJTA0eDolMDR4XG4iLAoJCSAgICAgICByZWFkdygweDQyKSwgcmVhZHcoMHg0MCkpOyAKCQlQUklOVEYoIkJJT1MgcmV0dXJuZWQgJXNjYXJyeVxuIiwgcmVncy5lZmxhZ3MgJiAxPyIiOiJOT1QgIik7CiNpZmRlZiBQQ0lfQklPU19ERUJVRwkJCgkJcHJpbnRfYmlvc19iaW9zX3N0YXQoKTsKI2VuZGlmCQkKCQlyZXR1cm4gKHJlZ3MuZWZsYWdzICYgMSk7CgkJCgl9CgkKCXJldHVybiAxOwoJCn0KCgo=