LyoKICogKEMpIENvcHlyaWdodCAyMDAyCiAqIERhbmllbCBFbmdzdHL2bSwgT21pY3JvbiBDZXRpIEFCLCBkYW5pZWxAb21pY3Jvbi5zZQogKgogKiAoQykgQ29weXJpZ2h0IDIwMDAKICogV29sZmdhbmcgRGVuaywgREVOWCBTb2Z0d2FyZSBFbmdpbmVlcmluZywgd2RAZGVueC5kZS4KICoKICogU2VlIGZpbGUgQ1JFRElUUyBmb3IgbGlzdCBvZiBwZW9wbGUgd2hvIGNvbnRyaWJ1dGVkIHRvIHRoaXMKICogcHJvamVjdC4KICoKICogVGhpcyBwcm9ncmFtIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vcgogKiBtb2RpZnkgaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBhcwogKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyIHZlcnNpb24gMiBvZgogKiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi4KICoKICogVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsCiAqIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mCiAqIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUKICogR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKICogYWxvbmcgd2l0aCB0aGlzIHByb2dyYW07IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUKICogRm91bmRhdGlvbiwgSW5jLiwgNTkgVGVtcGxlIFBsYWNlLCBTdWl0ZSAzMzAsIEJvc3RvbiwKICogTUEgMDIxMTEtMTMwNyBVU0EKICovCi8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKyAqLwoKLyoKICogVGhpcyBzb3VyY2UgY29kZSBoYXMgYmVlbiBtYWRlIGF2YWlsYWJsZSB0byB5b3UgYnkgSUJNIG9uIGFuIEFTLUlTCiAqIGJhc2lzLiAgQW55b25lIHJlY2VpdmluZyB0aGlzIHNvdXJjZSBpcyBsaWNlbnNlZCB1bmRlciBJQk0KICogY29weXJpZ2h0cyB0byB1c2UgaXQgaW4gYW55IHdheSBoZSBvciBzaGUgZGVlbXMgZml0LCBpbmNsdWRpbmcKICogY29weWluZyBpdCwgbW9kaWZ5aW5nIGl0LCBjb21waWxpbmcgaXQsIGFuZCByZWRpc3RyaWJ1dGluZyBpdCBlaXRoZXIKICogd2l0aCBvciB3aXRob3V0IG1vZGlmaWNhdGlvbnMuICBObyBsaWNlbnNlIHVuZGVyIElCTSBwYXRlbnRzIG9yCiAqIHBhdGVudCBhcHBsaWNhdGlvbnMgaXMgdG8gYmUgaW1wbGllZCBieSB0aGUgY29weXJpZ2h0IGxpY2Vuc2UuCiAqCiAqIEFueSB1c2VyIG9mIHRoaXMgc29mdHdhcmUgc2hvdWxkIHVuZGVyc3RhbmQgdGhhdCBJQk0gY2Fubm90IHByb3ZpZGUKICogdGVjaG5pY2FsIHN1cHBvcnQgZm9yIHRoaXMgc29mdHdhcmUgYW5kIHdpbGwgbm90IGJlIHJlc3BvbnNpYmxlIGZvcgogKiBhbnkgY29uc2VxdWVuY2VzIHJlc3VsdGluZyBmcm9tIHRoZSB1c2Ugb2YgdGhpcyBzb2Z0d2FyZS4KICoKICogQW55IHBlcnNvbiB3aG8gdHJhbnNmZXJzIHRoaXMgc291cmNlIGNvZGUgb3IgYW55IGRlcml2YXRpdmUgd29yawogKiBtdXN0IGluY2x1ZGUgdGhlIElCTSBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIHBhcmFncmFwaCwgYW5kIHRoZQogKiBwcmVjZWRpbmcgdHdvIHBhcmFncmFwaHMgaW4gdGhlIHRyYW5zZmVycmVkIHNvZnR3YXJlLgogKgogKiBDT1BZUklHSFQgICBJIEIgTSAgIENPUlBPUkFUSU9OIDE5OTUKICogTElDRU5TRUQgTUFURVJJQUwgIC0gIFBST0dSQU0gUFJPUEVSVFkgT0YgSSBCIE0KICovCi8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLwoKI2luY2x1ZGUgPGNvbW1vbi5oPgojaW5jbHVkZSA8d2F0Y2hkb2cuaD4KI2luY2x1ZGUgPGFzbS9pby5oPgojaW5jbHVkZSA8YXNtL2libXBjLmg+CgojaWZkZWYgQ09ORklHX1NFUklBTF9TT0ZUV0FSRV9GSUZPCiNpbmNsdWRlIDxtYWxsb2MuaD4KI2VuZGlmCgpERUNMQVJFX0dMT0JBTF9EQVRBX1BUUjsKCiNkZWZpbmUgVUFSVF9SQlIgICAgMHgwMAojZGVmaW5lIFVBUlRfVEhSICAgIDB4MDAKI2RlZmluZSBVQVJUX0lFUiAgICAweDAxCiNkZWZpbmUgVUFSVF9JSVIgICAgMHgwMgojZGVmaW5lIFVBUlRfRkNSICAgIDB4MDIKI2RlZmluZSBVQVJUX0xDUiAgICAweDAzCiNkZWZpbmUgVUFSVF9NQ1IgICAgMHgwNAojZGVmaW5lIFVBUlRfTFNSICAgIDB4MDUKI2RlZmluZSBVQVJUX01TUiAgICAweDA2CiNkZWZpbmUgVUFSVF9TQ1IgICAgMHgwNwojZGVmaW5lIFVBUlRfRExMICAgIDB4MDAKI2RlZmluZSBVQVJUX0RMTSAgICAweDAxCgovKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKwogIHwgTGluZSBTdGF0dXMgUmVnaXN0ZXIuCiAgKy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KI2RlZmluZSBhc3luY0xTUkRhdGFSZWFkeTEgICAgICAgICAgICAweDAxCiNkZWZpbmUgYXN5bmNMU1JPdmVycnVuRXJyb3IxICAgICAgICAgMHgwMgojZGVmaW5lIGFzeW5jTFNSUGFyaXR5RXJyb3IxICAgICAgICAgIDB4MDQKI2RlZmluZSBhc3luY0xTUkZyYW1pbmdFcnJvcjEgICAgICAgICAweDA4CiNkZWZpbmUgYXN5bmNMU1JCcmVha0ludGVycnVwdDEgICAgICAgMHgxMAojZGVmaW5lIGFzeW5jTFNSVHhIb2xkRW1wdHkxICAgICAgICAgIDB4MjAKI2RlZmluZSBhc3luY0xTUlR4U2hpZnRFbXB0eTEgICAgICAgICAweDQwCiNkZWZpbmUgYXN5bmNMU1JSeEZpZm9FcnJvcjEgICAgICAgICAgMHg4MAoKCiNpZmRlZiBDT05GSUdfU0VSSUFMX1NPRlRXQVJFX0ZJRk8KLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSsKICB8IEZpZm8KICArLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwp0eXBlZGVmIHN0cnVjdCB7CgljaGFyICpyeF9idWZmZXI7Cgl1bG9uZyByeF9wdXQ7Cgl1bG9uZyByeF9nZXQ7CglpbnQgY3RzOwp9IHNlcmlhbF9idWZmZXJfdDsKCnZvbGF0aWxlIHNlcmlhbF9idWZmZXJfdCBidWZfaW5mbzsKc3RhdGljIGludCBzZXJpYWxfYnVmZmVyX2FjdGl2ZT0wOwojZW5kaWYKCgpzdGF0aWMgaW50IHNlcmlhbF9kaXYoaW50IGJhdWRyYXRlKQp7CgoJc3dpdGNoIChiYXVkcmF0ZSkgewoJY2FzZSAxMjAwOgoJCXJldHVybiA5NjsKCWNhc2UgOTYwMDoKCQlyZXR1cm4gMTI7CgljYXNlIDE5MjAwOgoJCXJldHVybiA2OwoJY2FzZSAzODQwMDoKCQlyZXR1cm4gMzsKCWNhc2UgNTc2MDA6CgkJcmV0dXJuIDI7CgljYXNlIDExNTIwMDoKCQlyZXR1cm4gMTsKCX0KCglyZXR1cm4gMTI7Cn0KCgovKgogKiBNaW5pbWFsIHNlcmlhbCBmdW5jdGlvbnMgbmVlZGVkIHRvIHVzZSBvbmUgb2YgdGhlIFNNQyBwb3J0cwogKiBhcyBzZXJpYWwgY29uc29sZSBpbnRlcmZhY2UuCiAqLwoKaW50IHNlcmlhbF9pbml0KHZvaWQpCnsKCXZvbGF0aWxlIGNoYXIgdmFsOwoJaW50IGJkaXYgPSBzZXJpYWxfZGl2KGdkLT5iYXVkcmF0ZSk7CgoJb3V0YigweDgwLCBVQVJUMF9CQVNFICsgVUFSVF9MQ1IpOwkvKiBzZXQgRExBQiBiaXQgKi8KCW91dGIoYmRpdiwgVUFSVDBfQkFTRSArIFVBUlRfRExMKTsJLyogc2V0IGJhdWRyYXRlIGRpdmlzb3IgKi8KCW91dGIoYmRpdiA+PiA4LCBVQVJUMF9CQVNFICsgVUFSVF9ETE0pOy8qIHNldCBiYXVkcmF0ZSBkaXZpc29yICovCglvdXRiKDB4MDMsIFVBUlQwX0JBU0UgKyBVQVJUX0xDUik7CS8qIGNsZWFyIERMQUI7IHNldCA4IGJpdHMsIG5vIHBhcml0eSAqLwoJb3V0YigweDAxLCBVQVJUMF9CQVNFICsgVUFSVF9GQ1IpOwkvKiBlbmFibGUgRklGTyAqLwoJb3V0YigweDBiLCBVQVJUMF9CQVNFICsgVUFSVF9NQ1IpOwkvKiBTZXQgRFRSIGFuZCBSVFMgYWN0aXZlICovCgl2YWwgPSBpbmIoVUFSVDBfQkFTRSArIFVBUlRfTFNSKTsJLyogY2xlYXIgbGluZSBzdGF0dXMgKi8KCXZhbCA9IGluYihVQVJUMF9CQVNFICsgVUFSVF9SQlIpOwkvKiByZWFkIHJlY2VpdmUgYnVmZmVyICovCglvdXRiKDB4MDAsIFVBUlQwX0JBU0UgKyBVQVJUX1NDUik7CS8qIHNldCBzY3JhdGNocGFkICovCglvdXRiKDB4MDAsIFVBUlQwX0JBU0UgKyBVQVJUX0lFUik7CS8qIHNldCBpbnRlcnJ1cHQgZW5hYmxlIHJlZyAqLwoKCXJldHVybiAwOwp9CgoKdm9pZCBzZXJpYWxfc2V0YnJnKHZvaWQpCnsKCXVuc2lnbmVkIHNob3J0IGJkaXY7CgoJYmRpdiA9IHNlcmlhbF9kaXYoZ2QtPmJhdWRyYXRlKTsKCglvdXRiKDB4ODAsIFVBUlQwX0JBU0UgKyBVQVJUX0xDUik7CS8qIHNldCBETEFCIGJpdCAqLwoJb3V0YihiZGl2JjB4ZmYsIFVBUlQwX0JBU0UgKyBVQVJUX0RMTCk7CS8qIHNldCBiYXVkcmF0ZSBkaXZpc29yICovCglvdXRiKGJkaXYgPj4gOCwgVUFSVDBfQkFTRSArIFVBUlRfRExNKTsvKiBzZXQgYmF1ZHJhdGUgZGl2aXNvciAqLwoJb3V0YigweDAzLCBVQVJUMF9CQVNFICsgVUFSVF9MQ1IpOwkvKiBjbGVhciBETEFCOyBzZXQgOCBiaXRzLCBubyBwYXJpdHkgKi8KfQoKCnZvaWQgc2VyaWFsX3B1dGMoY29uc3QgY2hhciBjKQp7CglpbnQgaTsKCglpZiAoYyA9PSAnXG4nKQoJCXNlcmlhbF9wdXRjICgnXHInKTsKCgkvKiBjaGVjayBUSFJFIGJpdCwgd2FpdCBmb3IgdHJhbnNtaXRlciBhdmFpbGFibGUgKi8KCWZvciAoaSA9IDE7IGkgPCAzNTAwOyBpKyspIHsKCQlpZiAoKGluYiAoVUFSVDBfQkFTRSArIFVBUlRfTFNSKSAmIDB4MjApID09IDB4MjApIHsKCQkJYnJlYWs7CgkJfQoJCXVkZWxheSgxMDApOwoJfQoJb3V0YihjLCBVQVJUMF9CQVNFICsgVUFSVF9USFIpOwkvKiBwdXQgY2hhcmFjdGVyIG91dCAqLwp9CgoKdm9pZCBzZXJpYWxfcHV0cyhjb25zdCBjaGFyICpzKQp7Cgl3aGlsZSAoKnMpIHsKCQlzZXJpYWxfcHV0YygqcysrKTsKCX0KfQoKCmludCBzZXJpYWxfZ2V0Yyh2b2lkKQp7Cgl1bnNpZ25lZCBjaGFyIHN0YXR1cyA9IDA7CgojaWZkZWYgQ09ORklHX1NFUklBTF9TT0ZUV0FSRV9GSUZPCglpZiAoc2VyaWFsX2J1ZmZlcl9hY3RpdmUpIHsKCQlyZXR1cm4gc2VyaWFsX2J1ZmZlcmVkX2dldGMoKTsKCX0KI2VuZGlmCgoJd2hpbGUgKDEpIHsKI2lmIGRlZmluZWQoQ09ORklHX0hXX1dBVENIRE9HKQoJCVdBVENIRE9HX1JFU0VUKCk7CS8qIFJlc2V0IEhXIFdhdGNoZG9nLCBpZiBuZWVkZWQgKi8KI2VuZGlmCS8qIENPTkZJR19IV19XQVRDSERPRyAqLwoJCXN0YXR1cyA9IGluYihVQVJUMF9CQVNFICsgVUFSVF9MU1IpOwoJCWlmICgoc3RhdHVzICYgYXN5bmNMU1JEYXRhUmVhZHkxKSAhPSAweDApIHsKCQkJYnJlYWs7CgkJfQoJCWlmICgoc3RhdHVzICYgKCBhc3luY0xTUkZyYW1pbmdFcnJvcjEgfAoJCQkJYXN5bmNMU1JPdmVycnVuRXJyb3IxIHwKCQkJCWFzeW5jTFNSUGFyaXR5RXJyb3IxICB8CgkJCQlhc3luY0xTUkJyZWFrSW50ZXJydXB0MSApKSAhPSAwKSB7CgkJCW91dGIoYXN5bmNMU1JGcmFtaW5nRXJyb3IxIHwKCQkJICAgICAgYXN5bmNMU1JPdmVycnVuRXJyb3IxIHwKCQkJICAgICAgYXN5bmNMU1JQYXJpdHlFcnJvcjEgIHwKCQkJICAgICAgYXN5bmNMU1JCcmVha0ludGVycnVwdDEsIFVBUlQwX0JBU0UgKyBVQVJUX0xTUik7CgkJfQoJfQoJcmV0dXJuICgweDAwMDAwMGZmICYgKGludCkgaW5iIChVQVJUMF9CQVNFKSk7Cn0KCgppbnQgc2VyaWFsX3RzdGModm9pZCkKewoJdW5zaWduZWQgY2hhciBzdGF0dXM7CgojaWZkZWYgQ09ORklHX1NFUklBTF9TT0ZUV0FSRV9GSUZPCglpZiAoc2VyaWFsX2J1ZmZlcl9hY3RpdmUpIHsKCQlyZXR1cm4gc2VyaWFsX2J1ZmZlcmVkX3RzdGMoKTsKCX0KI2VuZGlmCgoJc3RhdHVzID0gaW5iKFVBUlQwX0JBU0UgKyBVQVJUX0xTUik7CglpZiAoKHN0YXR1cyAmIGFzeW5jTFNSRGF0YVJlYWR5MSkgIT0gMHgwKSB7CgkJcmV0dXJuICgxKTsKCX0KCWlmICgoc3RhdHVzICYgKCBhc3luY0xTUkZyYW1pbmdFcnJvcjEgfAoJCQlhc3luY0xTUk92ZXJydW5FcnJvcjEgfAoJCQlhc3luY0xTUlBhcml0eUVycm9yMSAgfAoJCQlhc3luY0xTUkJyZWFrSW50ZXJydXB0MSApKSAhPSAwKSB7CgkJb3V0Yihhc3luY0xTUkZyYW1pbmdFcnJvcjEgfAoJCSAgICAgIGFzeW5jTFNST3ZlcnJ1bkVycm9yMSB8CgkJICAgICAgYXN5bmNMU1JQYXJpdHlFcnJvcjEgIHwKCQkgICAgICBhc3luY0xTUkJyZWFrSW50ZXJydXB0MSwgVUFSVDBfQkFTRSArIFVBUlRfTFNSKTsKCX0KCXJldHVybiAwOwp9CgoKI2lmZGVmIENPTkZJR19TRVJJQUxfU09GVFdBUkVfRklGTwoKdm9pZCBzZXJpYWxfaXNyKHZvaWQgKmFyZykKewoJaW50IHNwYWNlOwoJaW50IGM7CglpbnQgcnhfcHV0ID0gYnVmX2luZm8ucnhfcHV0OwoKCWlmIChidWZfaW5mby5yeF9nZXQgPD0gcnhfcHV0KSB7CgkJc3BhY2UgPSBDT05GSUdfU0VSSUFMX1NPRlRXQVJFX0ZJRk8gLSAocnhfcHV0IC0gYnVmX2luZm8ucnhfZ2V0KTsKCX0gZWxzZSB7CgkJc3BhY2UgPSBidWZfaW5mby5yeF9nZXQgLSByeF9wdXQ7Cgl9CgoJd2hpbGUgKGluYihVQVJUMF9CQVNFICsgVUFSVF9MU1IpICYgMSkgewoJCWMgPSBpbmIoVUFSVDBfQkFTRSk7CgkJaWYgKHNwYWNlKSB7CgkJCWJ1Zl9pbmZvLnJ4X2J1ZmZlcltyeF9wdXQrK10gPSBjOwoJCQlzcGFjZS0tOwoKCQkJaWYgKHJ4X3B1dCA9PSBidWZfaW5mby5yeF9nZXQpIHsKCQkJCWJ1Zl9pbmZvLnJ4X2dldCsrOwoJCQkJaWYgKHJ4X3B1dCA9PSBDT05GSUdfU0VSSUFMX1NPRlRXQVJFX0ZJRk8pIHsKCQkJCQlidWZfaW5mby5yeF9nZXQgPSAwOwoJCQkJfQoJCQl9CgoJCQlpZiAocnhfcHV0ID09IENPTkZJR19TRVJJQUxfU09GVFdBUkVfRklGTykgewoJCQkJcnhfcHV0ID0gMDsKCQkJCWlmICgwID09IGJ1Zl9pbmZvLnJ4X2dldCkgewoJCQkJCWJ1Zl9pbmZvLnJ4X2dldCA9IDE7CgkJCQl9CgoJCQl9CgoJCX0KCQlpZiAoc3BhY2UgPCBDT05GSUdfU0VSSUFMX1NPRlRXQVJFX0ZJRk8gLyA0KSB7CgkJCS8qIFN0b3AgZmxvdyBieSBzZXR0aW5nIFJUUyBpbmFjdGl2ZSAqLwoJCQlvdXRiKGluYihVQVJUMF9CQVNFICsgVUFSVF9NQ1IpICYgKDB4RkYgXiAweDAyKSwKCQkJICAgICAgVUFSVDBfQkFTRSArIFVBUlRfTUNSKTsKCQl9Cgl9CglidWZfaW5mby5yeF9wdXQgPSByeF9wdXQ7Cn0KCnZvaWQgc2VyaWFsX2J1ZmZlcmVkX2luaXQodm9pZCkKewoJc2VyaWFsX3B1dHMgKCJTd2l0Y2hpbmcgdG8gaW50ZXJydXB0IGRyaXZlbiBzZXJpYWwgaW5wdXQgbW9kZS5cbiIpOwoJYnVmX2luZm8ucnhfYnVmZmVyID0gbWFsbG9jIChDT05GSUdfU0VSSUFMX1NPRlRXQVJFX0ZJRk8pOwoJYnVmX2luZm8ucnhfcHV0ID0gMDsKCWJ1Zl9pbmZvLnJ4X2dldCA9IDA7CgoJaWYgKGluYiAoVUFSVDBfQkFTRSArIFVBUlRfTVNSKSAmIDB4MTApIHsKCQlzZXJpYWxfcHV0cyAoIkNoZWNrIENUUyBzaWduYWwgcHJlc2VudCBvbiBzZXJpYWwgcG9ydDogT0suXG4iKTsKCQlidWZfaW5mby5jdHMgPSAxOwoJfSBlbHNlIHsKCQlzZXJpYWxfcHV0cyAoIldBUk5JTkc6IENUUyBzaWduYWwgbm90IHByZXNlbnQgb24gc2VyaWFsIHBvcnQuXG4iKTsKCQlidWZfaW5mby5jdHMgPSAwOwoJfQoKCWlycV9pbnN0YWxsX2hhbmRsZXIgKCBWRUNOVU1fVTAgLypVQVJUMCAqLyAvKmludCB2ZWMgKi8gLAoJCQkgICAgICBzZXJpYWxfaXNyIC8qaW50ZXJydXB0X2hhbmRsZXJfdCAqaGFuZGxlciAqLyAsCgkJCSAgICAgICh2b2lkICopICZidWZfaW5mbyAvKnZvaWQgKmFyZyAqLyApOwoKCS8qIEVuYWJsZSAiUlggRGF0YSBBdmFpbGFibGUiIEludGVycnVwdCBvbiBVQVJUICovCgkvKiBvdXRiKGluYihVQVJUMF9CQVNFICsgVUFSVF9JRVIpIHwweDAxLCBVQVJUMF9CQVNFICsgVUFSVF9JRVIpOyAqLwoJb3V0YigweDAxLCBVQVJUMF9CQVNFICsgVUFSVF9JRVIpOwoKCS8qIFNldCBEVFIgYW5kIFJUUyBhY3RpdmUsIGVuYWJsZSBpbnRlcnJ1cHRzICAqLwoJb3V0YihpbmIgKFVBUlQwX0JBU0UgKyBVQVJUX01DUikgfCAweDBiLCBVQVJUMF9CQVNFICsgVUFSVF9NQ1IpOwoKCS8qIFNldHVwIFVBUlQgRklGTzogUlggdHJpZ2dlciBsZXZlbDogMSBieXRlLCBFbmFibGUgRklGTyAqLwoJb3V0YiggLyooMSA8PCA2KSB8Ki8gIDEsIFVBUlQwX0JBU0UgKyBVQVJUX0ZDUik7CgoJc2VyaWFsX2J1ZmZlcl9hY3RpdmUgPSAxOwp9Cgp2b2lkIHNlcmlhbF9idWZmZXJlZF9wdXRjIChjb25zdCBjaGFyIGMpCnsKCWludCBpOwoJLyogV2FpdCBmb3IgQ1RTICovCiNpZiBkZWZpbmVkKENPTkZJR19IV19XQVRDSERPRykKCXdoaWxlICghKGluYiAoVUFSVDBfQkFTRSArIFVBUlRfTVNSKSAmIDB4MTApKQoJCVdBVENIRE9HX1JFU0VUICgpOwojZWxzZQoJaWYgKGJ1Zl9pbmZvLmN0cykgIHsKCQlmb3IgKGk9MDtpPDEwMDA7aSsrKSB7CgkJCWlmICgoaW5iIChVQVJUMF9CQVNFICsgVUFSVF9NU1IpICYgMHgxMCkpIHsKCQkJCWJyZWFrOwoJCQl9CgkJfQoJCWlmIChpIT0xMDAwKSB7CgkJCWJ1Zl9pbmZvLmN0cyA9IDA7CgkJfQoJfSBlbHNlIHsKCQlpZiAoKGluYiAoVUFSVDBfQkFTRSArIFVBUlRfTVNSKSAmIDB4MTApKSB7CgkJCWJ1Zl9pbmZvLmN0cyA9IDE7CgkJfQoJfQoKI2VuZGlmCglzZXJpYWxfcHV0YyAoYyk7Cn0KCnZvaWQgc2VyaWFsX2J1ZmZlcmVkX3B1dHMoY29uc3QgY2hhciAqcykKewoJc2VyaWFsX3B1dHMgKHMpOwp9CgppbnQgc2VyaWFsX2J1ZmZlcmVkX2dldGModm9pZCkKewoJaW50IHNwYWNlOwoJaW50IGM7CglpbnQgcnhfZ2V0ID0gYnVmX2luZm8ucnhfZ2V0OwoJaW50IHJ4X3B1dDsKCiNpZiBkZWZpbmVkKENPTkZJR19IV19XQVRDSERPRykKCXdoaWxlIChyeF9nZXQgPT0gYnVmX2luZm8ucnhfcHV0KQoJCVdBVENIRE9HX1JFU0VUICgpOwojZWxzZQoJd2hpbGUgKHJ4X2dldCA9PSBidWZfaW5mby5yeF9wdXQpOwojZW5kaWYKCWMgPSBidWZfaW5mby5yeF9idWZmZXJbcnhfZ2V0KytdOwoJaWYgKHJ4X2dldCA9PSBDT05GSUdfU0VSSUFMX1NPRlRXQVJFX0ZJRk8pIHsKCQlyeF9nZXQgPSAwOwoJfQoJYnVmX2luZm8ucnhfZ2V0ID0gcnhfZ2V0OwoKCXJ4X3B1dCA9IGJ1Zl9pbmZvLnJ4X3B1dDsKCWlmIChyeF9nZXQgPD0gcnhfcHV0KSB7CgkJc3BhY2UgPSBDT05GSUdfU0VSSUFMX1NPRlRXQVJFX0ZJRk8gLSAocnhfcHV0IC0gcnhfZ2V0KTsKCX0gZWxzZSB7CgkJc3BhY2UgPSByeF9nZXQgLSByeF9wdXQ7Cgl9CglpZiAoc3BhY2UgPiBDT05GSUdfU0VSSUFMX1NPRlRXQVJFX0ZJRk8gLyAyKSB7CgkJLyogU3RhcnQgZmxvdyBieSBzZXR0aW5nIFJUUyBhY3RpdmUgKi8KCQlvdXRiKGluYiAoVUFSVDBfQkFTRSArIFVBUlRfTUNSKSB8IDB4MDIsIFVBUlQwX0JBU0UgKyBVQVJUX01DUik7Cgl9CgoJcmV0dXJuIGM7Cn0KCmludCBzZXJpYWxfYnVmZmVyZWRfdHN0Yyh2b2lkKQp7CglyZXR1cm4gKGJ1Zl9pbmZvLnJ4X2dldCAhPSBidWZfaW5mby5yeF9wdXQpID8gMSA6IDA7Cn0KCiNlbmRpZgkvKiBDT05GSUdfU0VSSUFMX1NPRlRXQVJFX0ZJRk8gKi8KCgojaWYgKENPTkZJR19DT01NQU5EUyAmIENGR19DTURfS0dEQikKLyoKICBBUyBIQVJOT0lTIDogYWNjb3JkaW5nIHRvIENPTkZJR19LR0RCX1NFUl9JTkRFWCBrZ2RiIHVzZXMgc2VyaWFsIHBvcnQKICBudW1iZXIgMCBvciBudW1iZXIgMQogIC0gaWYgQ09ORklHX0tHREJfU0VSX0lOREVYID0gMSA9PiBzZXJpYWwgcG9ydCBudW1iZXIgMCA6CiAgY29uZmlndXJhdGlvbiBoYXMgYmVlbiBhbHJlYWR5IGRvbmUKICAtIGlmIENPTkZJR19LR0RCX1NFUl9JTkRFWCA9IDIgPT4gc2VyaWFsIHBvcnQgbnVtYmVyIDEgOgogIGNvbmZpZ3VyZSBwb3J0IDEgZm9yIHNlcmlhbCBJL08gd2l0aCByYXRlID0gQ09ORklHX0tHREJfQkFVRFJBVEUKKi8KI2lmIChDT05GSUdfS0dEQl9TRVJfSU5ERVggJiAyKQp2b2lkIGtnZGJfc2VyaWFsX2luaXQodm9pZCkKewoJdm9sYXRpbGUgY2hhciB2YWw7CgliZGl2ID0gc2VyaWFsX2RpdiAoQ09ORklHX0tHREJfQkFVRFJBVEUpOwoKCS8qCgkgKiBJbml0IG9uYm9hcmQgMTY1NTAgVUFSVAoJICovCglvdXRiKDB4ODAsIFVBUlQxX0JBU0UgKyBVQVJUX0xDUik7CS8qIHNldCBETEFCIGJpdCAqLwoJb3V0YihiZGl2ICYgMHhmZiksIFVBUlQxX0JBU0UgKyBVQVJUX0RMTCk7CS8qIHNldCBkaXZpc29yIGZvciA5NjAwIGJhdWQgKi8KCW91dGIoYmRpdiA+PiA4KSwgVUFSVDFfQkFTRSArIFVBUlRfRExNKTsJLyogc2V0IGRpdmlzb3IgZm9yIDk2MDAgYmF1ZCAqLwoJb3V0YigweDAzLCBVQVJUMV9CQVNFICsgVUFSVF9MQ1IpOwkvKiBsaW5lIGNvbnRyb2wgOCBiaXRzIG5vIHBhcml0eSAqLwoJb3V0YigweDAwLCBVQVJUMV9CQVNFICsgVUFSVF9GQ1IpOwkvKiBkaXNhYmxlIEZJRk8gKi8KCW91dGIoMHgwMCwgVUFSVDFfQkFTRSArIFVBUlRfTUNSKTsJLyogbm8gbW9kZW0gY29udHJvbCBEVFIgUlRTICovCgl2YWwgPSBpbmIoVUFSVDFfQkFTRSArIFVBUlRfTFNSKTsJLyogY2xlYXIgbGluZSBzdGF0dXMgKi8KCXZhbCA9IGluYihVQVJUMV9CQVNFICsgVUFSVF9SQlIpOwkvKiByZWFkIHJlY2VpdmUgYnVmZmVyICovCglvdXRiKDB4MDAsIFVBUlQxX0JBU0UgKyBVQVJUX1NDUik7CS8qIHNldCBzY3JhdGNocGFkICovCglvdXRiKDB4MDAsIFVBUlQxX0JBU0UgKyBVQVJUX0lFUik7CS8qIHNldCBpbnRlcnJ1cHQgZW5hYmxlIHJlZyAqLwp9CgoKdm9pZCBwdXREZWJ1Z0NoYXIoY29uc3QgY2hhciBjKQp7CglpZiAoYyA9PSAnXG4nKQoJCXNlcmlhbF9wdXRjICgnXHInKTsKCglvdXRiKGMsIFVBUlQxX0JBU0UgKyBVQVJUX1RIUik7CS8qIHB1dCBjaGFyYWN0ZXIgb3V0ICovCgoJLyogY2hlY2sgVEhSRSBiaXQsIHdhaXQgZm9yIHRyYW5zZmVyIGRvbmUgKi8KCXdoaWxlICgoaW5iKFVBUlQxX0JBU0UgKyBVQVJUX0xTUikgJiAweDIwKSAhPSAweDIwKTsKfQoKCnZvaWQgcHV0RGVidWdTdHIoY29uc3QgY2hhciAqcykKewoJd2hpbGUgKCpzKSB7CgkJc2VyaWFsX3B1dGMoKnMrKyk7Cgl9Cn0KCgppbnQgZ2V0RGVidWdDaGFyKHZvaWQpCnsKCXVuc2lnbmVkIGNoYXIgc3RhdHVzID0gMDsKCgl3aGlsZSAoMSkgewoJCXN0YXR1cyA9IGluYihVQVJUMV9CQVNFICsgVUFSVF9MU1IpOwoJCWlmICgoc3RhdHVzICYgYXN5bmNMU1JEYXRhUmVhZHkxKSAhPSAweDApIHsKCQkJYnJlYWs7CgkJfQoJCWlmICgoc3RhdHVzICYgKCBhc3luY0xTUkZyYW1pbmdFcnJvcjEgfAoJCQkJYXN5bmNMU1JPdmVycnVuRXJyb3IxIHwKCQkJCWFzeW5jTFNSUGFyaXR5RXJyb3IxICB8CgkJCQlhc3luY0xTUkJyZWFrSW50ZXJydXB0MSApKSAhPSAwKSB7CgkJCW91dGIoYXN5bmNMU1JGcmFtaW5nRXJyb3IxIHwKCQkJICAgICBhc3luY0xTUk92ZXJydW5FcnJvcjEgfAoJCQkgICAgIGFzeW5jTFNSUGFyaXR5RXJyb3IxICB8CgkJCSAgICAgYXN5bmNMU1JCcmVha0ludGVycnVwdDEsIFVBUlQxX0JBU0UgKyBVQVJUX0xTUik7CgkJfQoJfQoJcmV0dXJuICgweDAwMDAwMGZmICYgKGludCkgaW5iKFVBUlQxX0JBU0UpKTsKfQoKCnZvaWQga2dkYl9pbnRlcnJ1cHRpYmxlKGludCB5ZXMpCnsKCXJldHVybjsKfQoKI2Vsc2UJLyogISAoQ09ORklHX0tHREJfU0VSX0lOREVYICYgMikgKi8KCnZvaWQga2dkYl9zZXJpYWxfaW5pdCh2b2lkKQp7CglzZXJpYWxfcHJpbnRmICgiW29uIHNlcmlhbF0gIik7Cn0KCnZvaWQgcHV0RGVidWdDaGFyKGludCBjKQp7CglzZXJpYWxfcHV0YyAoYyk7Cn0KCnZvaWQgcHV0RGVidWdTdHIoY29uc3QgY2hhciAqc3RyKQp7CglzZXJpYWxfcHV0cyAoc3RyKTsKfQoKaW50IGdldERlYnVnQ2hhcih2b2lkKQp7CglyZXR1cm4gc2VyaWFsX2dldGMgKCk7Cn0KCnZvaWQga2dkYl9pbnRlcnJ1cHRpYmxlKGludCB5ZXMpCnsKCXJldHVybjsKfQojZW5kaWYJLyogKENPTkZJR19LR0RCX1NFUl9JTkRFWCAmIDIpICovCiNlbmRpZgkvKiBDRkdfQ01EX0tHREIgKi8K