LyoKICogKEMpIENvcHlyaWdodCAyMDAyCiAqIERhbmllbCBFbmdzdHL2bSwgT21pY3JvbiBDZXRpIEFCLCBkYW5pZWxAb21pY3Jvbi5zZQogKgogKiAoQykgQ29weXJpZ2h0IDIwMDAKICogV29sZmdhbmcgRGVuaywgREVOWCBTb2Z0d2FyZSBFbmdpbmVlcmluZywgd2RAZGVueC5kZS4KICoKICogU2VlIGZpbGUgQ1JFRElUUyBmb3IgbGlzdCBvZiBwZW9wbGUgd2hvIGNvbnRyaWJ1dGVkIHRvIHRoaXMKICogcHJvamVjdC4KICoKICogVGhpcyBwcm9ncmFtIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vcgogKiBtb2RpZnkgaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBhcwogKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyIHZlcnNpb24gMiBvZgogKiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi4KICoKICogVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsCiAqIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mCiAqIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUKICogR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKICogYWxvbmcgd2l0aCB0aGlzIHByb2dyYW07IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUKICogRm91bmRhdGlvbiwgSW5jLiwgNTkgVGVtcGxlIFBsYWNlLCBTdWl0ZSAzMzAsIEJvc3RvbiwKICogTUEgMDIxMTEtMTMwNyBVU0EKICovCi8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKyAqLwoKLyoKICogVGhpcyBzb3VyY2UgY29kZSBoYXMgYmVlbiBtYWRlIGF2YWlsYWJsZSB0byB5b3UgYnkgSUJNIG9uIGFuIEFTLUlTCiAqIGJhc2lzLiAgQW55b25lIHJlY2VpdmluZyB0aGlzIHNvdXJjZSBpcyBsaWNlbnNlZCB1bmRlciBJQk0KICogY29weXJpZ2h0cyB0byB1c2UgaXQgaW4gYW55IHdheSBoZSBvciBzaGUgZGVlbXMgZml0LCBpbmNsdWRpbmcKICogY29weWluZyBpdCwgbW9kaWZ5aW5nIGl0LCBjb21waWxpbmcgaXQsIGFuZCByZWRpc3RyaWJ1dGluZyBpdCBlaXRoZXIKICogd2l0aCBvciB3aXRob3V0IG1vZGlmaWNhdGlvbnMuICBObyBsaWNlbnNlIHVuZGVyIElCTSBwYXRlbnRzIG9yCiAqIHBhdGVudCBhcHBsaWNhdGlvbnMgaXMgdG8gYmUgaW1wbGllZCBieSB0aGUgY29weXJpZ2h0IGxpY2Vuc2UuCiAqCiAqIEFueSB1c2VyIG9mIHRoaXMgc29mdHdhcmUgc2hvdWxkIHVuZGVyc3RhbmQgdGhhdCBJQk0gY2Fubm90IHByb3ZpZGUKICogdGVjaG5pY2FsIHN1cHBvcnQgZm9yIHRoaXMgc29mdHdhcmUgYW5kIHdpbGwgbm90IGJlIHJlc3BvbnNpYmxlIGZvcgogKiBhbnkgY29uc2VxdWVuY2VzIHJlc3VsdGluZyBmcm9tIHRoZSB1c2Ugb2YgdGhpcyBzb2Z0d2FyZS4KICoKICogQW55IHBlcnNvbiB3aG8gdHJhbnNmZXJzIHRoaXMgc291cmNlIGNvZGUgb3IgYW55IGRlcml2YXRpdmUgd29yawogKiBtdXN0IGluY2x1ZGUgdGhlIElCTSBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIHBhcmFncmFwaCwgYW5kIHRoZQogKiBwcmVjZWRpbmcgdHdvIHBhcmFncmFwaHMgaW4gdGhlIHRyYW5zZmVycmVkIHNvZnR3YXJlLgogKgogKiBDT1BZUklHSFQgICBJIEIgTSAgIENPUlBPUkFUSU9OIDE5OTUKICogTElDRU5TRUQgTUFURVJJQUwgIC0gIFBST0dSQU0gUFJPUEVSVFkgT0YgSSBCIE0KICovCi8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLwoKI2luY2x1ZGUgPGNvbW1vbi5oPgojaW5jbHVkZSA8d2F0Y2hkb2cuaD4KI2luY2x1ZGUgPGFzbS9pby5oPgojaW5jbHVkZSA8YXNtL2libXBjLmg+CgojaWZkZWYgQ09ORklHX1NFUklBTF9TT0ZUV0FSRV9GSUZPCiNpbmNsdWRlIDxtYWxsb2MuaD4KI2VuZGlmCgpERUNMQVJFX0dMT0JBTF9EQVRBX1BUUjsKCiNkZWZpbmUgVUFSVF9SQlIgICAgMHgwMAojZGVmaW5lIFVBUlRfVEhSICAgIDB4MDAKI2RlZmluZSBVQVJUX0lFUiAgICAweDAxCiNkZWZpbmUgVUFSVF9JSVIgICAgMHgwMgojZGVmaW5lIFVBUlRfRkNSICAgIDB4MDIKI2RlZmluZSBVQVJUX0xDUiAgICAweDAzCiNkZWZpbmUgVUFSVF9NQ1IgICAgMHgwNAojZGVmaW5lIFVBUlRfTFNSICAgIDB4MDUKI2RlZmluZSBVQVJUX01TUiAgICAweDA2CiNkZWZpbmUgVUFSVF9TQ1IgICAgMHgwNwojZGVmaW5lIFVBUlRfRExMICAgIDB4MDAKI2RlZmluZSBVQVJUX0RMTSAgICAweDAxCgovKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKwogIHwgTGluZSBTdGF0dXMgUmVnaXN0ZXIuCiAgKy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KI2RlZmluZSBhc3luY0xTUkRhdGFSZWFkeTEgICAgICAgICAgICAweDAxCiNkZWZpbmUgYXN5bmNMU1JPdmVycnVuRXJyb3IxICAgICAgICAgMHgwMgojZGVmaW5lIGFzeW5jTFNSUGFyaXR5RXJyb3IxICAgICAgICAgIDB4MDQKI2RlZmluZSBhc3luY0xTUkZyYW1pbmdFcnJvcjEgICAgICAgICAweDA4CiNkZWZpbmUgYXN5bmNMU1JCcmVha0ludGVycnVwdDEgICAgICAgMHgxMAojZGVmaW5lIGFzeW5jTFNSVHhIb2xkRW1wdHkxICAgICAgICAgIDB4MjAKI2RlZmluZSBhc3luY0xTUlR4U2hpZnRFbXB0eTEgICAgICAgICAweDQwCiNkZWZpbmUgYXN5bmNMU1JSeEZpZm9FcnJvcjEgICAgICAgICAgMHg4MAoKCiNpZmRlZiBDT05GSUdfU0VSSUFMX1NPRlRXQVJFX0ZJRk8KLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSsKICB8IEZpZm8KICArLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwp0eXBlZGVmIHN0cnVjdCB7CgljaGFyICpyeF9idWZmZXI7Cgl1bG9uZyByeF9wdXQ7Cgl1bG9uZyByeF9nZXQ7CglpbnQgY3RzOwp9IHNlcmlhbF9idWZmZXJfdDsKCnZvbGF0aWxlIHNlcmlhbF9idWZmZXJfdCBidWZfaW5mbzsKc3RhdGljIGludCBzZXJpYWxfYnVmZmVyX2FjdGl2ZT0wOwojZW5kaWYKCgpzdGF0aWMgaW50IHNlcmlhbF9kaXYoaW50IGJhdWRyYXRlKQp7CgoJc3dpdGNoIChiYXVkcmF0ZSkgewoJY2FzZSAxMjAwOgoJCXJldHVybiA5NjsKCWNhc2UgOTYwMDoKCQlyZXR1cm4gMTI7CgljYXNlIDE5MjAwOgoJCXJldHVybiA2OwoJY2FzZSAzODQwMDoKCQlyZXR1cm4gMzsKCWNhc2UgNTc2MDA6CgkJcmV0dXJuIDI7CgljYXNlIDExNTIwMDoKCQlyZXR1cm4gMTsKCX0KCglyZXR1cm4gMTI7Cn0KCgovKgogKiBNaW5pbWFsIHNlcmlhbCBmdW5jdGlvbnMgbmVlZGVkIHRvIHVzZSBvbmUgb2YgdGhlIFNNQyBwb3J0cwogKiBhcyBzZXJpYWwgY29uc29sZSBpbnRlcmZhY2UuCiAqLwoKaW50IHNlcmlhbF9pbml0KHZvaWQpCnsKCXZvbGF0aWxlIGNoYXIgdmFsOwoJaW50IGJkaXYgPSBzZXJpYWxfZGl2KGdkLT5iYXVkcmF0ZSk7CgoJb3V0YigweDgwLCBVQVJUMF9CQVNFICsgVUFSVF9MQ1IpOwkvKiBzZXQgRExBQiBiaXQgKi8KCW91dGIoYmRpdiwgVUFSVDBfQkFTRSArIFVBUlRfRExMKTsJLyogc2V0IGJhdWRyYXRlIGRpdmlzb3IgKi8KCW91dGIoYmRpdiA+PiA4LCBVQVJUMF9CQVNFICsgVUFSVF9ETE0pOy8qIHNldCBiYXVkcmF0ZSBkaXZpc29yICovCglvdXRiKDB4MDMsIFVBUlQwX0JBU0UgKyBVQVJUX0xDUik7CS8qIGNsZWFyIERMQUI7IHNldCA4IGJpdHMsIG5vIHBhcml0eSAqLwoJb3V0YigweDAxLCBVQVJUMF9CQVNFICsgVUFSVF9GQ1IpOwkvKiBlbmFibGUgRklGTyAqLwoJb3V0YigweDBiLCBVQVJUMF9CQVNFICsgVUFSVF9NQ1IpOwkvKiBTZXQgRFRSIGFuZCBSVFMgYWN0aXZlICovCgl2YWwgPSBpbmIoVUFSVDBfQkFTRSArIFVBUlRfTFNSKTsJLyogY2xlYXIgbGluZSBzdGF0dXMgKi8KCXZhbCA9IGluYihVQVJUMF9CQVNFICsgVUFSVF9SQlIpOwkvKiByZWFkIHJlY2VpdmUgYnVmZmVyICovCglvdXRiKDB4MDAsIFVBUlQwX0JBU0UgKyBVQVJUX1NDUik7CS8qIHNldCBzY3JhdGNocGFkICovCglvdXRiKDB4MDAsIFVBUlQwX0JBU0UgKyBVQVJUX0lFUik7CS8qIHNldCBpbnRlcnJ1cHQgZW5hYmxlIHJlZyAqLwoKCXJldHVybiAwOwp9CgoKdm9pZCBzZXJpYWxfc2V0YnJnKHZvaWQpCnsKCXVuc2lnbmVkIHNob3J0IGJkaXY7CgoJYmRpdiA9IHNlcmlhbF9kaXYoZ2QtPmJhdWRyYXRlKTsKCglvdXRiKDB4ODAsIFVBUlQwX0JBU0UgKyBVQVJUX0xDUik7CS8qIHNldCBETEFCIGJpdCAqLwoJb3V0YihiZGl2JjB4ZmYsIFVBUlQwX0JBU0UgKyBVQVJUX0RMTCk7CS8qIHNldCBiYXVkcmF0ZSBkaXZpc29yICovCglvdXRiKGJkaXYgPj4gOCwgVUFSVDBfQkFTRSArIFVBUlRfRExNKTsvKiBzZXQgYmF1ZHJhdGUgZGl2aXNvciAqLwoJb3V0YigweDAzLCBVQVJUMF9CQVNFICsgVUFSVF9MQ1IpOwkvKiBjbGVhciBETEFCOyBzZXQgOCBiaXRzLCBubyBwYXJpdHkgKi8KfQoKCnZvaWQgc2VyaWFsX3B1dGMoY29uc3QgY2hhciBjKQp7CglpbnQgaTsKCglpZiAoYyA9PSAnXG4nKQoJCXNlcmlhbF9wdXRjICgnXHInKTsKCgkvKiBjaGVjayBUSFJFIGJpdCwgd2FpdCBmb3IgdHJhbnNtaXRlciBhdmFpbGFibGUgKi8KCWZvciAoaSA9IDE7IGkgPCAzNTAwOyBpKyspIHsKCQlpZiAoKGluYiAoVUFSVDBfQkFTRSArIFVBUlRfTFNSKSAmIDB4MjApID09IDB4MjApIHsKCQkJYnJlYWs7CgkJfQoJCXVkZWxheSgxMDApOwoJfQoJb3V0YihjLCBVQVJUMF9CQVNFICsgVUFSVF9USFIpOwkvKiBwdXQgY2hhcmFjdGVyIG91dCAqLwp9CgoKdm9pZCBzZXJpYWxfcHV0cyhjb25zdCBjaGFyICpzKQp7Cgl3aGlsZSAoKnMpIHsKCQlzZXJpYWxfcHV0YygqcysrKTsKCX0KfQoKCmludCBzZXJpYWxfZ2V0Yyh2b2lkKQp7Cgl1bnNpZ25lZCBjaGFyIHN0YXR1cyA9IDA7CgojaWZkZWYgQ09ORklHX1NFUklBTF9TT0ZUV0FSRV9GSUZPCglpZiAoc2VyaWFsX2J1ZmZlcl9hY3RpdmUpIHsKCQlyZXR1cm4gc2VyaWFsX2J1ZmZlcmVkX2dldGMoKTsKCX0KI2VuZGlmCgoJd2hpbGUgKDEpIHsKI2lmIGRlZmluZWQoQ09ORklHX0hXX1dBVENIRE9HKQoJCVdBVENIRE9HX1JFU0VUKCk7CS8qIFJlc2V0IEhXIFdhdGNoZG9nLCBpZiBuZWVkZWQgKi8KI2VuZGlmCS8qIENPTkZJR19IV19XQVRDSERPRyAqLwoJCXN0YXR1cyA9IGluYihVQVJUMF9CQVNFICsgVUFSVF9MU1IpOwoJCWlmICgoc3RhdHVzICYgYXN5bmNMU1JEYXRhUmVhZHkxKSAhPSAweDApIHsKCQkJYnJlYWs7CgkJfQoJCWlmICgoc3RhdHVzICYgKCBhc3luY0xTUkZyYW1pbmdFcnJvcjEgfAoJCQkJYXN5bmNMU1JPdmVycnVuRXJyb3IxIHwKCQkJCWFzeW5jTFNSUGFyaXR5RXJyb3IxICB8CgkJCQlhc3luY0xTUkJyZWFrSW50ZXJydXB0MSApKSAhPSAwKSB7CgkJCW91dGIoYXN5bmNMU1JGcmFtaW5nRXJyb3IxIHwKCQkJICAgICAgYXN5bmNMU1JPdmVycnVuRXJyb3IxIHwKCQkJICAgICAgYXN5bmNMU1JQYXJpdHlFcnJvcjEgIHwKCQkJICAgICAgYXN5bmNMU1JCcmVha0ludGVycnVwdDEsIFVBUlQwX0JBU0UgKyBVQVJUX0xTUik7CgkJfQoJfQoJcmV0dXJuICgweDAwMDAwMGZmICYgKGludCkgaW5iIChVQVJUMF9CQVNFKSk7Cn0KCgppbnQgc2VyaWFsX3RzdGModm9pZCkKewoJdW5zaWduZWQgY2hhciBzdGF0dXM7CgojaWZkZWYgQ09ORklHX1NFUklBTF9TT0ZUV0FSRV9GSUZPCglpZiAoc2VyaWFsX2J1ZmZlcl9hY3RpdmUpIHsKCQlyZXR1cm4gc2VyaWFsX2J1ZmZlcmVkX3RzdGMoKTsKCX0KI2VuZGlmCgoJc3RhdHVzID0gaW5iKFVBUlQwX0JBU0UgKyBVQVJUX0xTUik7CglpZiAoKHN0YXR1cyAmIGFzeW5jTFNSRGF0YVJlYWR5MSkgIT0gMHgwKSB7CgkJcmV0dXJuICgxKTsKCX0KCWlmICgoc3RhdHVzICYgKCBhc3luY0xTUkZyYW1pbmdFcnJvcjEgfAoJCQlhc3luY0xTUk92ZXJydW5FcnJvcjEgfAoJCQlhc3luY0xTUlBhcml0eUVycm9yMSAgfAoJCQlhc3luY0xTUkJyZWFrSW50ZXJydXB0MSApKSAhPSAwKSB7CgkJb3V0Yihhc3luY0xTUkZyYW1pbmdFcnJvcjEgfAoJCSAgICAgIGFzeW5jTFNST3ZlcnJ1bkVycm9yMSB8CgkJICAgICAgYXN5bmNMU1JQYXJpdHlFcnJvcjEgIHwKCQkgICAgICBhc3luY0xTUkJyZWFrSW50ZXJydXB0MSwgVUFSVDBfQkFTRSArIFVBUlRfTFNSKTsKCX0KCXJldHVybiAwOwp9CgoKI2lmZGVmIENPTkZJR19TRVJJQUxfU09GVFdBUkVfRklGTwoKdm9pZCBzZXJpYWxfaXNyKHZvaWQgKmFyZykKewoJaW50IHNwYWNlOwoJaW50IGM7CglpbnQgcnhfcHV0ID0gYnVmX2luZm8ucnhfcHV0OwoKCWlmIChidWZfaW5mby5yeF9nZXQgPD0gcnhfcHV0KSB7CgkJc3BhY2UgPSBDT05GSUdfU0VSSUFMX1NPRlRXQVJFX0ZJRk8gLSAocnhfcHV0IC0gYnVmX2luZm8ucnhfZ2V0KTsKCX0gZWxzZSB7CgkJc3BhY2UgPSBidWZfaW5mby5yeF9nZXQgLSByeF9wdXQ7Cgl9CgoJd2hpbGUgKGluYihVQVJUMF9CQVNFICsgVUFSVF9MU1IpICYgMSkgewoJCWMgPSBpbmIoVUFSVDBfQkFTRSk7CgkJaWYgKHNwYWNlKSB7CgkJCWJ1Zl9pbmZvLnJ4X2J1ZmZlcltyeF9wdXQrK10gPSBjOwoJCQlzcGFjZS0tOwoKCQkJaWYgKHJ4X3B1dCA9PSBidWZfaW5mby5yeF9nZXQpIHsKCQkJCWJ1Zl9pbmZvLnJ4X2dldCsrOwoJCQkJaWYgKHJ4X3B1dCA9PSBDT05GSUdfU0VSSUFMX1NPRlRXQVJFX0ZJRk8pIHsKCQkJCQlidWZfaW5mby5yeF9nZXQgPSAwOwoJCQkJfQoJCQl9CgoJCQlpZiAocnhfcHV0ID09IENPTkZJR19TRVJJQUxfU09GVFdBUkVfRklGTykgewoJCQkJcnhfcHV0ID0gMDsKCQkJCWlmICgwID09IGJ1Zl9pbmZvLnJ4X2dldCkgewoJCQkJCWJ1Zl9pbmZvLnJ4X2dldCA9IDE7CgkJCQl9CgoJCQl9CgoJCX0KCQlpZiAoc3BhY2UgPCBDT05GSUdfU0VSSUFMX1NPRlRXQVJFX0ZJRk8gLyA0KSB7CgkJCS8qIFN0b3AgZmxvdyBieSBzZXR0aW5nIFJUUyBpbmFjdGl2ZSAqLwoJCQlvdXRiKGluYihVQVJUMF9CQVNFICsgVUFSVF9NQ1IpICYgKDB4RkYgXiAweDAyKSwKCQkJICAgICAgVUFSVDBfQkFTRSArIFVBUlRfTUNSKTsKCQl9Cgl9CglidWZfaW5mby5yeF9wdXQgPSByeF9wdXQ7Cn0KCnZvaWQgc2VyaWFsX2J1ZmZlcmVkX2luaXQodm9pZCkKewoJc2VyaWFsX3B1dHMgKCJTd2l0Y2hpbmcgdG8gaW50ZXJydXB0IGRyaXZlbiBzZXJpYWwgaW5wdXQgbW9kZS5cbiIpOwoJYnVmX2luZm8ucnhfYnVmZmVyID0gbWFsbG9jIChDT05GSUdfU0VSSUFMX1NPRlRXQVJFX0ZJRk8pOwoJYnVmX2luZm8ucnhfcHV0ID0gMDsKCWJ1Zl9pbmZvLnJ4X2dldCA9IDA7CgoJaWYgKGluYiAoVUFSVDBfQkFTRSArIFVBUlRfTVNSKSAmIDB4MTApIHsKCQlzZXJpYWxfcHV0cyAoIkNoZWNrIENUUyBzaWduYWwgcHJlc2VudCBvbiBzZXJpYWwgcG9ydDogT0suXG4iKTsKCQlidWZfaW5mby5jdHMgPSAxOwoJfSBlbHNlIHsKCQlzZXJpYWxfcHV0cyAoIldBUk5JTkc6IENUUyBzaWduYWwgbm90IHByZXNlbnQgb24gc2VyaWFsIHBvcnQuXG4iKTsKCQlidWZfaW5mby5jdHMgPSAwOwoJfQoKCWlycV9pbnN0YWxsX2hhbmRsZXIgKCBWRUNOVU1fVTAgLypVQVJUMCAqLyAvKmludCB2ZWMgKi8gLAoJCQkgICAgICBzZXJpYWxfaXNyIC8qaW50ZXJydXB0X2hhbmRsZXJfdCAqaGFuZGxlciAqLyAsCgkJCSAgICAgICh2b2lkICopICZidWZfaW5mbyAvKnZvaWQgKmFyZyAqLyApOwoKCS8qIEVuYWJsZSAiUlggRGF0YSBBdmFpbGFibGUiIEludGVycnVwdCBvbiBVQVJUICovCgkvKiBvdXRiKGluYihVQVJUMF9CQVNFICsgVUFSVF9JRVIpIHwweDAxLCBVQVJUMF9CQVNFICsgVUFSVF9JRVIpOyAqLwoJb3V0YigweDAxLCBVQVJUMF9CQVNFICsgVUFSVF9JRVIpOwoKCS8qIFNldCBEVFIgYW5kIFJUUyBhY3RpdmUsIGVuYWJsZSBpbnRlcnJ1cHRzICAqLwoJb3V0YihpbmIgKFVBUlQwX0JBU0UgKyBVQVJUX01DUikgfCAweDBiLCBVQVJUMF9CQVNFICsgVUFSVF9NQ1IpOwoKCS8qIFNldHVwIFVBUlQgRklGTzogUlggdHJpZ2dlciBsZXZlbDogMSBieXRlLCBFbmFibGUgRklGTyAqLwoJb3V0YiggLyooMSA8PCA2KSB8Ki8gIDEsIFVBUlQwX0JBU0UgKyBVQVJUX0ZDUik7CgoJc2VyaWFsX2J1ZmZlcl9hY3RpdmUgPSAxOwp9Cgp2b2lkIHNlcmlhbF9idWZmZXJlZF9wdXRjIChjb25zdCBjaGFyIGMpCnsKCWludCBpOwoJLyogV2FpdCBmb3IgQ1RTICovCiNpZiBkZWZpbmVkKENPTkZJR19IV19XQVRDSERPRykKCXdoaWxlICghKGluYiAoVUFSVDBfQkFTRSArIFVBUlRfTVNSKSAmIDB4MTApKQoJCVdBVENIRE9HX1JFU0VUICgpOwojZWxzZQoJaWYgKGJ1Zl9pbmZvLmN0cykgIHsKCQlmb3IgKGk9MDtpPDEwMDA7aSsrKSB7CgkJCWlmICgoaW5iIChVQVJUMF9CQVNFICsgVUFSVF9NU1IpICYgMHgxMCkpIHsKCQkJCWJyZWFrOwoJCQl9CgkJfQoJCWlmIChpIT0xMDAwKSB7CgkJCWJ1Zl9pbmZvLmN0cyA9IDA7CgkJfQoJfSBlbHNlIHsKCQlpZiAoKGluYiAoVUFSVDBfQkFTRSArIFVBUlRfTVNSKSAmIDB4MTApKSB7CgkJCWJ1Zl9pbmZvLmN0cyA9IDE7CgkJfQoJfQoKI2VuZGlmCglzZXJpYWxfcHV0YyAoYyk7Cn0KCnZvaWQgc2VyaWFsX2J1ZmZlcmVkX3B1dHMoY29uc3QgY2hhciAqcykKewoJc2VyaWFsX3B1dHMgKHMpOwp9CgppbnQgc2VyaWFsX2J1ZmZlcmVkX2dldGModm9pZCkKewoJaW50IHNwYWNlOwoJaW50IGM7CglpbnQgcnhfZ2V0ID0gYnVmX2luZm8ucnhfZ2V0OwoJaW50IHJ4X3B1dDsKCiNpZiBkZWZpbmVkKENPTkZJR19IV19XQVRDSERPRykKCXdoaWxlIChyeF9nZXQgPT0gYnVmX2luZm8ucnhfcHV0KQoJCVdBVENIRE9HX1JFU0VUICgpOwojZWxzZQoJd2hpbGUgKHJ4X2dldCA9PSBidWZfaW5mby5yeF9wdXQpOwojZW5kaWYKCWMgPSBidWZfaW5mby5yeF9idWZmZXJbcnhfZ2V0KytdOwoJaWYgKHJ4X2dldCA9PSBDT05GSUdfU0VSSUFMX1NPRlRXQVJFX0ZJRk8pIHsKCQlyeF9nZXQgPSAwOwoJfQoJYnVmX2luZm8ucnhfZ2V0ID0gcnhfZ2V0OwoKCXJ4X3B1dCA9IGJ1Zl9pbmZvLnJ4X3B1dDsKCWlmIChyeF9nZXQgPD0gcnhfcHV0KSB7CgkJc3BhY2UgPSBDT05GSUdfU0VSSUFMX1NPRlRXQVJFX0ZJRk8gLSAocnhfcHV0IC0gcnhfZ2V0KTsKCX0gZWxzZSB7CgkJc3BhY2UgPSByeF9nZXQgLSByeF9wdXQ7Cgl9CglpZiAoc3BhY2UgPiBDT05GSUdfU0VSSUFMX1NPRlRXQVJFX0ZJRk8gLyAyKSB7CgkJLyogU3RhcnQgZmxvdyBieSBzZXR0aW5nIFJUUyBhY3RpdmUgKi8KCQlvdXRiKGluYiAoVUFSVDBfQkFTRSArIFVBUlRfTUNSKSB8IDB4MDIsIFVBUlQwX0JBU0UgKyBVQVJUX01DUik7Cgl9CgoJcmV0dXJuIGM7Cn0KCmludCBzZXJpYWxfYnVmZmVyZWRfdHN0Yyh2b2lkKQp7CglyZXR1cm4gKGJ1Zl9pbmZvLnJ4X2dldCAhPSBidWZfaW5mby5yeF9wdXQpID8gMSA6IDA7Cn0KCiNlbmRpZgkvKiBDT05GSUdfU0VSSUFMX1NPRlRXQVJFX0ZJRk8gKi8KCgojaWYgZGVmaW5lZChDT05GSUdfQ01EX0tHREIpCi8qCiAgQVMgSEFSTk9JUyA6IGFjY29yZGluZyB0byBDT05GSUdfS0dEQl9TRVJfSU5ERVgga2dkYiB1c2VzIHNlcmlhbCBwb3J0CiAgbnVtYmVyIDAgb3IgbnVtYmVyIDEKICAtIGlmIENPTkZJR19LR0RCX1NFUl9JTkRFWCA9IDEgPT4gc2VyaWFsIHBvcnQgbnVtYmVyIDAgOgogIGNvbmZpZ3VyYXRpb24gaGFzIGJlZW4gYWxyZWFkeSBkb25lCiAgLSBpZiBDT05GSUdfS0dEQl9TRVJfSU5ERVggPSAyID0+IHNlcmlhbCBwb3J0IG51bWJlciAxIDoKICBjb25maWd1cmUgcG9ydCAxIGZvciBzZXJpYWwgSS9PIHdpdGggcmF0ZSA9IENPTkZJR19LR0RCX0JBVURSQVRFCiovCiNpZiAoQ09ORklHX0tHREJfU0VSX0lOREVYICYgMikKdm9pZCBrZ2RiX3NlcmlhbF9pbml0KHZvaWQpCnsKCXZvbGF0aWxlIGNoYXIgdmFsOwoJYmRpdiA9IHNlcmlhbF9kaXYgKENPTkZJR19LR0RCX0JBVURSQVRFKTsKCgkvKgoJICogSW5pdCBvbmJvYXJkIDE2NTUwIFVBUlQKCSAqLwoJb3V0YigweDgwLCBVQVJUMV9CQVNFICsgVUFSVF9MQ1IpOwkvKiBzZXQgRExBQiBiaXQgKi8KCW91dGIoKGJkaXYgJiAweGZmKSwgVUFSVDFfQkFTRSArIFVBUlRfRExMKTsJLyogc2V0IGRpdmlzb3IgZm9yIDk2MDAgYmF1ZCAqLwoJb3V0YigoYmRpdiA+PiA4ICApLCBVQVJUMV9CQVNFICsgVUFSVF9ETE0pOwkvKiBzZXQgZGl2aXNvciBmb3IgOTYwMCBiYXVkICovCglvdXRiKDB4MDMsIFVBUlQxX0JBU0UgKyBVQVJUX0xDUik7CS8qIGxpbmUgY29udHJvbCA4IGJpdHMgbm8gcGFyaXR5ICovCglvdXRiKDB4MDAsIFVBUlQxX0JBU0UgKyBVQVJUX0ZDUik7CS8qIGRpc2FibGUgRklGTyAqLwoJb3V0YigweDAwLCBVQVJUMV9CQVNFICsgVUFSVF9NQ1IpOwkvKiBubyBtb2RlbSBjb250cm9sIERUUiBSVFMgKi8KCXZhbCA9IGluYihVQVJUMV9CQVNFICsgVUFSVF9MU1IpOwkvKiBjbGVhciBsaW5lIHN0YXR1cyAqLwoJdmFsID0gaW5iKFVBUlQxX0JBU0UgKyBVQVJUX1JCUik7CS8qIHJlYWQgcmVjZWl2ZSBidWZmZXIgKi8KCW91dGIoMHgwMCwgVUFSVDFfQkFTRSArIFVBUlRfU0NSKTsJLyogc2V0IHNjcmF0Y2hwYWQgKi8KCW91dGIoMHgwMCwgVUFSVDFfQkFTRSArIFVBUlRfSUVSKTsJLyogc2V0IGludGVycnVwdCBlbmFibGUgcmVnICovCn0KCgp2b2lkIHB1dERlYnVnQ2hhcihjb25zdCBjaGFyIGMpCnsKCWlmIChjID09ICdcbicpCgkJc2VyaWFsX3B1dGMgKCdccicpOwoKCW91dGIoYywgVUFSVDFfQkFTRSArIFVBUlRfVEhSKTsJLyogcHV0IGNoYXJhY3RlciBvdXQgKi8KCgkvKiBjaGVjayBUSFJFIGJpdCwgd2FpdCBmb3IgdHJhbnNmZXIgZG9uZSAqLwoJd2hpbGUgKChpbmIoVUFSVDFfQkFTRSArIFVBUlRfTFNSKSAmIDB4MjApICE9IDB4MjApOwp9CgoKdm9pZCBwdXREZWJ1Z1N0cihjb25zdCBjaGFyICpzKQp7Cgl3aGlsZSAoKnMpIHsKCQlzZXJpYWxfcHV0YygqcysrKTsKCX0KfQoKCmludCBnZXREZWJ1Z0NoYXIodm9pZCkKewoJdW5zaWduZWQgY2hhciBzdGF0dXMgPSAwOwoKCXdoaWxlICgxKSB7CgkJc3RhdHVzID0gaW5iKFVBUlQxX0JBU0UgKyBVQVJUX0xTUik7CgkJaWYgKChzdGF0dXMgJiBhc3luY0xTUkRhdGFSZWFkeTEpICE9IDB4MCkgewoJCQlicmVhazsKCQl9CgkJaWYgKChzdGF0dXMgJiAoIGFzeW5jTFNSRnJhbWluZ0Vycm9yMSB8CgkJCQlhc3luY0xTUk92ZXJydW5FcnJvcjEgfAoJCQkJYXN5bmNMU1JQYXJpdHlFcnJvcjEgIHwKCQkJCWFzeW5jTFNSQnJlYWtJbnRlcnJ1cHQxICkpICE9IDApIHsKCQkJb3V0Yihhc3luY0xTUkZyYW1pbmdFcnJvcjEgfAoJCQkgICAgIGFzeW5jTFNST3ZlcnJ1bkVycm9yMSB8CgkJCSAgICAgYXN5bmNMU1JQYXJpdHlFcnJvcjEgIHwKCQkJICAgICBhc3luY0xTUkJyZWFrSW50ZXJydXB0MSwgVUFSVDFfQkFTRSArIFVBUlRfTFNSKTsKCQl9Cgl9CglyZXR1cm4gKDB4MDAwMDAwZmYgJiAoaW50KSBpbmIoVUFSVDFfQkFTRSkpOwp9CgoKdm9pZCBrZ2RiX2ludGVycnVwdGlibGUoaW50IHllcykKewoJcmV0dXJuOwp9CgojZWxzZQkvKiAhIChDT05GSUdfS0dEQl9TRVJfSU5ERVggJiAyKSAqLwoKdm9pZCBrZ2RiX3NlcmlhbF9pbml0KHZvaWQpCnsKCXNlcmlhbF9wcmludGYgKCJbb24gc2VyaWFsXSAiKTsKfQoKdm9pZCBwdXREZWJ1Z0NoYXIoaW50IGMpCnsKCXNlcmlhbF9wdXRjIChjKTsKfQoKdm9pZCBwdXREZWJ1Z1N0cihjb25zdCBjaGFyICpzdHIpCnsKCXNlcmlhbF9wdXRzIChzdHIpOwp9CgppbnQgZ2V0RGVidWdDaGFyKHZvaWQpCnsKCXJldHVybiBzZXJpYWxfZ2V0YyAoKTsKfQoKdm9pZCBrZ2RiX2ludGVycnVwdGlibGUoaW50IHllcykKewoJcmV0dXJuOwp9CiNlbmRpZgkvKiAoQ09ORklHX0tHREJfU0VSX0lOREVYICYgMikgKi8KI2VuZGlmCg==