LyoKICogKEMpIENvcHlyaWdodCAyMDAyCiAqIERhbmllbCBFbmdzdHL2bSwgT21pY3JvbiBDZXRpIEFCLCBkYW5pZWxAb21pY3Jvbi5zZQogKgogKiAoQykgQ29weXJpZ2h0IDIwMDAKICogV29sZmdhbmcgRGVuaywgREVOWCBTb2Z0d2FyZSBFbmdpbmVlcmluZywgd2RAZGVueC5kZS4KICoKICogU2VlIGZpbGUgQ1JFRElUUyBmb3IgbGlzdCBvZiBwZW9wbGUgd2hvIGNvbnRyaWJ1dGVkIHRvIHRoaXMKICogcHJvamVjdC4KICoKICogVGhpcyBwcm9ncmFtIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vcgogKiBtb2RpZnkgaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBhcwogKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyIHZlcnNpb24gMiBvZgogKiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi4KICoKICogVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsCiAqIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mCiAqIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUKICogR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKICogYWxvbmcgd2l0aCB0aGlzIHByb2dyYW07IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUKICogRm91bmRhdGlvbiwgSW5jLiwgNTkgVGVtcGxlIFBsYWNlLCBTdWl0ZSAzMzAsIEJvc3RvbiwKICogTUEgMDIxMTEtMTMwNyBVU0EKICovCi8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKyAqLwoKLyoKICogVGhpcyBzb3VyY2UgY29kZSBpcyBkdWFsLWxpY2Vuc2VkLiAgWW91IG1heSB1c2UgaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZQogKiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIsIG9yIHVuZGVyIHRoZSBsaWNlbnNlIGJlbG93LgogKgogKiBUaGlzIHNvdXJjZSBjb2RlIGhhcyBiZWVuIG1hZGUgYXZhaWxhYmxlIHRvIHlvdSBieSBJQk0gb24gYW4gQVMtSVMKICogYmFzaXMuICBBbnlvbmUgcmVjZWl2aW5nIHRoaXMgc291cmNlIGlzIGxpY2Vuc2VkIHVuZGVyIElCTQogKiBjb3B5cmlnaHRzIHRvIHVzZSBpdCBpbiBhbnkgd2F5IGhlIG9yIHNoZSBkZWVtcyBmaXQsIGluY2x1ZGluZwogKiBjb3B5aW5nIGl0LCBtb2RpZnlpbmcgaXQsIGNvbXBpbGluZyBpdCwgYW5kIHJlZGlzdHJpYnV0aW5nIGl0IGVpdGhlcgogKiB3aXRoIG9yIHdpdGhvdXQgbW9kaWZpY2F0aW9ucy4gIE5vIGxpY2Vuc2UgdW5kZXIgSUJNIHBhdGVudHMgb3IKICogcGF0ZW50IGFwcGxpY2F0aW9ucyBpcyB0byBiZSBpbXBsaWVkIGJ5IHRoZSBjb3B5cmlnaHQgbGljZW5zZS4KICoKICogQW55IHVzZXIgb2YgdGhpcyBzb2Z0d2FyZSBzaG91bGQgdW5kZXJzdGFuZCB0aGF0IElCTSBjYW5ub3QgcHJvdmlkZQogKiB0ZWNobmljYWwgc3VwcG9ydCBmb3IgdGhpcyBzb2Z0d2FyZSBhbmQgd2lsbCBub3QgYmUgcmVzcG9uc2libGUgZm9yCiAqIGFueSBjb25zZXF1ZW5jZXMgcmVzdWx0aW5nIGZyb20gdGhlIHVzZSBvZiB0aGlzIHNvZnR3YXJlLgogKgogKiBBbnkgcGVyc29uIHdobyB0cmFuc2ZlcnMgdGhpcyBzb3VyY2UgY29kZSBvciBhbnkgZGVyaXZhdGl2ZSB3b3JrCiAqIG11c3QgaW5jbHVkZSB0aGUgSUJNIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgcGFyYWdyYXBoLCBhbmQgdGhlCiAqIHByZWNlZGluZyB0d28gcGFyYWdyYXBocyBpbiB0aGUgdHJhbnNmZXJyZWQgc29mdHdhcmUuCiAqCiAqIENPUFlSSUdIVCAgIEkgQiBNICAgQ09SUE9SQVRJT04gMTk5NQogKiBMSUNFTlNFRCBNQVRFUklBTCAgLSAgUFJPR1JBTSBQUk9QRVJUWSBPRiBJIEIgTQogKi8KLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovCgojaW5jbHVkZSA8Y29tbW9uLmg+CiNpbmNsdWRlIDx3YXRjaGRvZy5oPgojaW5jbHVkZSA8YXNtL2lvLmg+CiNpbmNsdWRlIDxhc20vaWJtcGMuaD4KCiNpZmRlZiBDT05GSUdfU0VSSUFMX1NPRlRXQVJFX0ZJRk8KI2luY2x1ZGUgPG1hbGxvYy5oPgojZW5kaWYKCkRFQ0xBUkVfR0xPQkFMX0RBVEFfUFRSOwoKI2RlZmluZSBVQVJUX1JCUiAgICAweDAwCiNkZWZpbmUgVUFSVF9USFIgICAgMHgwMAojZGVmaW5lIFVBUlRfSUVSICAgIDB4MDEKI2RlZmluZSBVQVJUX0lJUiAgICAweDAyCiNkZWZpbmUgVUFSVF9GQ1IgICAgMHgwMgojZGVmaW5lIFVBUlRfTENSICAgIDB4MDMKI2RlZmluZSBVQVJUX01DUiAgICAweDA0CiNkZWZpbmUgVUFSVF9MU1IgICAgMHgwNQojZGVmaW5lIFVBUlRfTVNSICAgIDB4MDYKI2RlZmluZSBVQVJUX1NDUiAgICAweDA3CiNkZWZpbmUgVUFSVF9ETEwgICAgMHgwMAojZGVmaW5lIFVBUlRfRExNICAgIDB4MDEKCi8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0rCiAgfCBMaW5lIFN0YXR1cyBSZWdpc3Rlci4KICArLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwojZGVmaW5lIGFzeW5jTFNSRGF0YVJlYWR5MSAgICAgICAgICAgIDB4MDEKI2RlZmluZSBhc3luY0xTUk92ZXJydW5FcnJvcjEgICAgICAgICAweDAyCiNkZWZpbmUgYXN5bmNMU1JQYXJpdHlFcnJvcjEgICAgICAgICAgMHgwNAojZGVmaW5lIGFzeW5jTFNSRnJhbWluZ0Vycm9yMSAgICAgICAgIDB4MDgKI2RlZmluZSBhc3luY0xTUkJyZWFrSW50ZXJydXB0MSAgICAgICAweDEwCiNkZWZpbmUgYXN5bmNMU1JUeEhvbGRFbXB0eTEgICAgICAgICAgMHgyMAojZGVmaW5lIGFzeW5jTFNSVHhTaGlmdEVtcHR5MSAgICAgICAgIDB4NDAKI2RlZmluZSBhc3luY0xTUlJ4Rmlmb0Vycm9yMSAgICAgICAgICAweDgwCgoKI2lmZGVmIENPTkZJR19TRVJJQUxfU09GVFdBUkVfRklGTwovKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKwogIHwgRmlmbwogICstLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCnR5cGVkZWYgc3RydWN0IHsKCWNoYXIgKnJ4X2J1ZmZlcjsKCXVsb25nIHJ4X3B1dDsKCXVsb25nIHJ4X2dldDsKCWludCBjdHM7Cn0gc2VyaWFsX2J1ZmZlcl90OwoKdm9sYXRpbGUgc2VyaWFsX2J1ZmZlcl90IGJ1Zl9pbmZvOwpzdGF0aWMgaW50IHNlcmlhbF9idWZmZXJfYWN0aXZlPTA7CiNlbmRpZgoKCnN0YXRpYyBpbnQgc2VyaWFsX2RpdihpbnQgYmF1ZHJhdGUpCnsKCglzd2l0Y2ggKGJhdWRyYXRlKSB7CgljYXNlIDEyMDA6CgkJcmV0dXJuIDk2OwoJY2FzZSA5NjAwOgoJCXJldHVybiAxMjsKCWNhc2UgMTkyMDA6CgkJcmV0dXJuIDY7CgljYXNlIDM4NDAwOgoJCXJldHVybiAzOwoJY2FzZSA1NzYwMDoKCQlyZXR1cm4gMjsKCWNhc2UgMTE1MjAwOgoJCXJldHVybiAxOwoJfQoKCXJldHVybiAxMjsKfQoKCi8qCiAqIE1pbmltYWwgc2VyaWFsIGZ1bmN0aW9ucyBuZWVkZWQgdG8gdXNlIG9uZSBvZiB0aGUgU01DIHBvcnRzCiAqIGFzIHNlcmlhbCBjb25zb2xlIGludGVyZmFjZS4KICovCgppbnQgc2VyaWFsX2luaXQodm9pZCkKewoJdm9sYXRpbGUgY2hhciB2YWw7CglpbnQgYmRpdiA9IHNlcmlhbF9kaXYoZ2QtPmJhdWRyYXRlKTsKCglvdXRiKDB4ODAsIFVBUlQwX0JBU0UgKyBVQVJUX0xDUik7CS8qIHNldCBETEFCIGJpdCAqLwoJb3V0YihiZGl2LCBVQVJUMF9CQVNFICsgVUFSVF9ETEwpOwkvKiBzZXQgYmF1ZHJhdGUgZGl2aXNvciAqLwoJb3V0YihiZGl2ID4+IDgsIFVBUlQwX0JBU0UgKyBVQVJUX0RMTSk7Lyogc2V0IGJhdWRyYXRlIGRpdmlzb3IgKi8KCW91dGIoMHgwMywgVUFSVDBfQkFTRSArIFVBUlRfTENSKTsJLyogY2xlYXIgRExBQjsgc2V0IDggYml0cywgbm8gcGFyaXR5ICovCglvdXRiKDB4MDEsIFVBUlQwX0JBU0UgKyBVQVJUX0ZDUik7CS8qIGVuYWJsZSBGSUZPICovCglvdXRiKDB4MGIsIFVBUlQwX0JBU0UgKyBVQVJUX01DUik7CS8qIFNldCBEVFIgYW5kIFJUUyBhY3RpdmUgKi8KCXZhbCA9IGluYihVQVJUMF9CQVNFICsgVUFSVF9MU1IpOwkvKiBjbGVhciBsaW5lIHN0YXR1cyAqLwoJdmFsID0gaW5iKFVBUlQwX0JBU0UgKyBVQVJUX1JCUik7CS8qIHJlYWQgcmVjZWl2ZSBidWZmZXIgKi8KCW91dGIoMHgwMCwgVUFSVDBfQkFTRSArIFVBUlRfU0NSKTsJLyogc2V0IHNjcmF0Y2hwYWQgKi8KCW91dGIoMHgwMCwgVUFSVDBfQkFTRSArIFVBUlRfSUVSKTsJLyogc2V0IGludGVycnVwdCBlbmFibGUgcmVnICovCgoJcmV0dXJuIDA7Cn0KCgp2b2lkIHNlcmlhbF9zZXRicmcodm9pZCkKewoJdW5zaWduZWQgc2hvcnQgYmRpdjsKCgliZGl2ID0gc2VyaWFsX2RpdihnZC0+YmF1ZHJhdGUpOwoKCW91dGIoMHg4MCwgVUFSVDBfQkFTRSArIFVBUlRfTENSKTsJLyogc2V0IERMQUIgYml0ICovCglvdXRiKGJkaXYmMHhmZiwgVUFSVDBfQkFTRSArIFVBUlRfRExMKTsJLyogc2V0IGJhdWRyYXRlIGRpdmlzb3IgKi8KCW91dGIoYmRpdiA+PiA4LCBVQVJUMF9CQVNFICsgVUFSVF9ETE0pOy8qIHNldCBiYXVkcmF0ZSBkaXZpc29yICovCglvdXRiKDB4MDMsIFVBUlQwX0JBU0UgKyBVQVJUX0xDUik7CS8qIGNsZWFyIERMQUI7IHNldCA4IGJpdHMsIG5vIHBhcml0eSAqLwp9CgoKdm9pZCBzZXJpYWxfcHV0Yyhjb25zdCBjaGFyIGMpCnsKCWludCBpOwoKCWlmIChjID09ICdcbicpCgkJc2VyaWFsX3B1dGMgKCdccicpOwoKCS8qIGNoZWNrIFRIUkUgYml0LCB3YWl0IGZvciB0cmFuc21pdGVyIGF2YWlsYWJsZSAqLwoJZm9yIChpID0gMTsgaSA8IDM1MDA7IGkrKykgewoJCWlmICgoaW5iIChVQVJUMF9CQVNFICsgVUFSVF9MU1IpICYgMHgyMCkgPT0gMHgyMCkgewoJCQlicmVhazsKCQl9CgkJdWRlbGF5KDEwMCk7Cgl9CglvdXRiKGMsIFVBUlQwX0JBU0UgKyBVQVJUX1RIUik7CS8qIHB1dCBjaGFyYWN0ZXIgb3V0ICovCn0KCgp2b2lkIHNlcmlhbF9wdXRzKGNvbnN0IGNoYXIgKnMpCnsKCXdoaWxlICgqcykgewoJCXNlcmlhbF9wdXRjKCpzKyspOwoJfQp9CgoKaW50IHNlcmlhbF9nZXRjKHZvaWQpCnsKCXVuc2lnbmVkIGNoYXIgc3RhdHVzID0gMDsKCiNpZmRlZiBDT05GSUdfU0VSSUFMX1NPRlRXQVJFX0ZJRk8KCWlmIChzZXJpYWxfYnVmZmVyX2FjdGl2ZSkgewoJCXJldHVybiBzZXJpYWxfYnVmZmVyZWRfZ2V0YygpOwoJfQojZW5kaWYKCgl3aGlsZSAoMSkgewojaWYgZGVmaW5lZChDT05GSUdfSFdfV0FUQ0hET0cpCgkJV0FUQ0hET0dfUkVTRVQoKTsJLyogUmVzZXQgSFcgV2F0Y2hkb2csIGlmIG5lZWRlZCAqLwojZW5kaWYJLyogQ09ORklHX0hXX1dBVENIRE9HICovCgkJc3RhdHVzID0gaW5iKFVBUlQwX0JBU0UgKyBVQVJUX0xTUik7CgkJaWYgKChzdGF0dXMgJiBhc3luY0xTUkRhdGFSZWFkeTEpICE9IDB4MCkgewoJCQlicmVhazsKCQl9CgkJaWYgKChzdGF0dXMgJiAoIGFzeW5jTFNSRnJhbWluZ0Vycm9yMSB8CgkJCQlhc3luY0xTUk92ZXJydW5FcnJvcjEgfAoJCQkJYXN5bmNMU1JQYXJpdHlFcnJvcjEgIHwKCQkJCWFzeW5jTFNSQnJlYWtJbnRlcnJ1cHQxICkpICE9IDApIHsKCQkJb3V0Yihhc3luY0xTUkZyYW1pbmdFcnJvcjEgfAoJCQkgICAgICBhc3luY0xTUk92ZXJydW5FcnJvcjEgfAoJCQkgICAgICBhc3luY0xTUlBhcml0eUVycm9yMSAgfAoJCQkgICAgICBhc3luY0xTUkJyZWFrSW50ZXJydXB0MSwgVUFSVDBfQkFTRSArIFVBUlRfTFNSKTsKCQl9Cgl9CglyZXR1cm4gKDB4MDAwMDAwZmYgJiAoaW50KSBpbmIgKFVBUlQwX0JBU0UpKTsKfQoKCmludCBzZXJpYWxfdHN0Yyh2b2lkKQp7Cgl1bnNpZ25lZCBjaGFyIHN0YXR1czsKCiNpZmRlZiBDT05GSUdfU0VSSUFMX1NPRlRXQVJFX0ZJRk8KCWlmIChzZXJpYWxfYnVmZmVyX2FjdGl2ZSkgewoJCXJldHVybiBzZXJpYWxfYnVmZmVyZWRfdHN0YygpOwoJfQojZW5kaWYKCglzdGF0dXMgPSBpbmIoVUFSVDBfQkFTRSArIFVBUlRfTFNSKTsKCWlmICgoc3RhdHVzICYgYXN5bmNMU1JEYXRhUmVhZHkxKSAhPSAweDApIHsKCQlyZXR1cm4gKDEpOwoJfQoJaWYgKChzdGF0dXMgJiAoIGFzeW5jTFNSRnJhbWluZ0Vycm9yMSB8CgkJCWFzeW5jTFNST3ZlcnJ1bkVycm9yMSB8CgkJCWFzeW5jTFNSUGFyaXR5RXJyb3IxICB8CgkJCWFzeW5jTFNSQnJlYWtJbnRlcnJ1cHQxICkpICE9IDApIHsKCQlvdXRiKGFzeW5jTFNSRnJhbWluZ0Vycm9yMSB8CgkJICAgICAgYXN5bmNMU1JPdmVycnVuRXJyb3IxIHwKCQkgICAgICBhc3luY0xTUlBhcml0eUVycm9yMSAgfAoJCSAgICAgIGFzeW5jTFNSQnJlYWtJbnRlcnJ1cHQxLCBVQVJUMF9CQVNFICsgVUFSVF9MU1IpOwoJfQoJcmV0dXJuIDA7Cn0KCgojaWZkZWYgQ09ORklHX1NFUklBTF9TT0ZUV0FSRV9GSUZPCgp2b2lkIHNlcmlhbF9pc3Iodm9pZCAqYXJnKQp7CglpbnQgc3BhY2U7CglpbnQgYzsKCWludCByeF9wdXQgPSBidWZfaW5mby5yeF9wdXQ7CgoJaWYgKGJ1Zl9pbmZvLnJ4X2dldCA8PSByeF9wdXQpIHsKCQlzcGFjZSA9IENPTkZJR19TRVJJQUxfU09GVFdBUkVfRklGTyAtIChyeF9wdXQgLSBidWZfaW5mby5yeF9nZXQpOwoJfSBlbHNlIHsKCQlzcGFjZSA9IGJ1Zl9pbmZvLnJ4X2dldCAtIHJ4X3B1dDsKCX0KCgl3aGlsZSAoaW5iKFVBUlQwX0JBU0UgKyBVQVJUX0xTUikgJiAxKSB7CgkJYyA9IGluYihVQVJUMF9CQVNFKTsKCQlpZiAoc3BhY2UpIHsKCQkJYnVmX2luZm8ucnhfYnVmZmVyW3J4X3B1dCsrXSA9IGM7CgkJCXNwYWNlLS07CgoJCQlpZiAocnhfcHV0ID09IGJ1Zl9pbmZvLnJ4X2dldCkgewoJCQkJYnVmX2luZm8ucnhfZ2V0Kys7CgkJCQlpZiAocnhfcHV0ID09IENPTkZJR19TRVJJQUxfU09GVFdBUkVfRklGTykgewoJCQkJCWJ1Zl9pbmZvLnJ4X2dldCA9IDA7CgkJCQl9CgkJCX0KCgkJCWlmIChyeF9wdXQgPT0gQ09ORklHX1NFUklBTF9TT0ZUV0FSRV9GSUZPKSB7CgkJCQlyeF9wdXQgPSAwOwoJCQkJaWYgKDAgPT0gYnVmX2luZm8ucnhfZ2V0KSB7CgkJCQkJYnVmX2luZm8ucnhfZ2V0ID0gMTsKCQkJCX0KCgkJCX0KCgkJfQoJCWlmIChzcGFjZSA8IENPTkZJR19TRVJJQUxfU09GVFdBUkVfRklGTyAvIDQpIHsKCQkJLyogU3RvcCBmbG93IGJ5IHNldHRpbmcgUlRTIGluYWN0aXZlICovCgkJCW91dGIoaW5iKFVBUlQwX0JBU0UgKyBVQVJUX01DUikgJiAoMHhGRiBeIDB4MDIpLAoJCQkgICAgICBVQVJUMF9CQVNFICsgVUFSVF9NQ1IpOwoJCX0KCX0KCWJ1Zl9pbmZvLnJ4X3B1dCA9IHJ4X3B1dDsKfQoKdm9pZCBzZXJpYWxfYnVmZmVyZWRfaW5pdCh2b2lkKQp7CglzZXJpYWxfcHV0cyAoIlN3aXRjaGluZyB0byBpbnRlcnJ1cHQgZHJpdmVuIHNlcmlhbCBpbnB1dCBtb2RlLlxuIik7CglidWZfaW5mby5yeF9idWZmZXIgPSBtYWxsb2MgKENPTkZJR19TRVJJQUxfU09GVFdBUkVfRklGTyk7CglidWZfaW5mby5yeF9wdXQgPSAwOwoJYnVmX2luZm8ucnhfZ2V0ID0gMDsKCglpZiAoaW5iIChVQVJUMF9CQVNFICsgVUFSVF9NU1IpICYgMHgxMCkgewoJCXNlcmlhbF9wdXRzICgiQ2hlY2sgQ1RTIHNpZ25hbCBwcmVzZW50IG9uIHNlcmlhbCBwb3J0OiBPSy5cbiIpOwoJCWJ1Zl9pbmZvLmN0cyA9IDE7Cgl9IGVsc2UgewoJCXNlcmlhbF9wdXRzICgiV0FSTklORzogQ1RTIHNpZ25hbCBub3QgcHJlc2VudCBvbiBzZXJpYWwgcG9ydC5cbiIpOwoJCWJ1Zl9pbmZvLmN0cyA9IDA7Cgl9CgoJaXJxX2luc3RhbGxfaGFuZGxlciAoIFZFQ05VTV9VMCAvKlVBUlQwICovIC8qaW50IHZlYyAqLyAsCgkJCSAgICAgIHNlcmlhbF9pc3IgLyppbnRlcnJ1cHRfaGFuZGxlcl90ICpoYW5kbGVyICovICwKCQkJICAgICAgKHZvaWQgKikgJmJ1Zl9pbmZvIC8qdm9pZCAqYXJnICovICk7CgoJLyogRW5hYmxlICJSWCBEYXRhIEF2YWlsYWJsZSIgSW50ZXJydXB0IG9uIFVBUlQgKi8KCS8qIG91dGIoaW5iKFVBUlQwX0JBU0UgKyBVQVJUX0lFUikgfDB4MDEsIFVBUlQwX0JBU0UgKyBVQVJUX0lFUik7ICovCglvdXRiKDB4MDEsIFVBUlQwX0JBU0UgKyBVQVJUX0lFUik7CgoJLyogU2V0IERUUiBhbmQgUlRTIGFjdGl2ZSwgZW5hYmxlIGludGVycnVwdHMgICovCglvdXRiKGluYiAoVUFSVDBfQkFTRSArIFVBUlRfTUNSKSB8IDB4MGIsIFVBUlQwX0JBU0UgKyBVQVJUX01DUik7CgoJLyogU2V0dXAgVUFSVCBGSUZPOiBSWCB0cmlnZ2VyIGxldmVsOiAxIGJ5dGUsIEVuYWJsZSBGSUZPICovCglvdXRiKCAvKigxIDw8IDYpIHwqLyAgMSwgVUFSVDBfQkFTRSArIFVBUlRfRkNSKTsKCglzZXJpYWxfYnVmZmVyX2FjdGl2ZSA9IDE7Cn0KCnZvaWQgc2VyaWFsX2J1ZmZlcmVkX3B1dGMgKGNvbnN0IGNoYXIgYykKewoJaW50IGk7CgkvKiBXYWl0IGZvciBDVFMgKi8KI2lmIGRlZmluZWQoQ09ORklHX0hXX1dBVENIRE9HKQoJd2hpbGUgKCEoaW5iIChVQVJUMF9CQVNFICsgVUFSVF9NU1IpICYgMHgxMCkpCgkJV0FUQ0hET0dfUkVTRVQgKCk7CiNlbHNlCglpZiAoYnVmX2luZm8uY3RzKSAgewoJCWZvciAoaT0wO2k8MTAwMDtpKyspIHsKCQkJaWYgKChpbmIgKFVBUlQwX0JBU0UgKyBVQVJUX01TUikgJiAweDEwKSkgewoJCQkJYnJlYWs7CgkJCX0KCQl9CgkJaWYgKGkhPTEwMDApIHsKCQkJYnVmX2luZm8uY3RzID0gMDsKCQl9Cgl9IGVsc2UgewoJCWlmICgoaW5iIChVQVJUMF9CQVNFICsgVUFSVF9NU1IpICYgMHgxMCkpIHsKCQkJYnVmX2luZm8uY3RzID0gMTsKCQl9Cgl9CgojZW5kaWYKCXNlcmlhbF9wdXRjIChjKTsKfQoKdm9pZCBzZXJpYWxfYnVmZmVyZWRfcHV0cyhjb25zdCBjaGFyICpzKQp7CglzZXJpYWxfcHV0cyAocyk7Cn0KCmludCBzZXJpYWxfYnVmZmVyZWRfZ2V0Yyh2b2lkKQp7CglpbnQgc3BhY2U7CglpbnQgYzsKCWludCByeF9nZXQgPSBidWZfaW5mby5yeF9nZXQ7CglpbnQgcnhfcHV0OwoKI2lmIGRlZmluZWQoQ09ORklHX0hXX1dBVENIRE9HKQoJd2hpbGUgKHJ4X2dldCA9PSBidWZfaW5mby5yeF9wdXQpCgkJV0FUQ0hET0dfUkVTRVQgKCk7CiNlbHNlCgl3aGlsZSAocnhfZ2V0ID09IGJ1Zl9pbmZvLnJ4X3B1dCk7CiNlbmRpZgoJYyA9IGJ1Zl9pbmZvLnJ4X2J1ZmZlcltyeF9nZXQrK107CglpZiAocnhfZ2V0ID09IENPTkZJR19TRVJJQUxfU09GVFdBUkVfRklGTykgewoJCXJ4X2dldCA9IDA7Cgl9CglidWZfaW5mby5yeF9nZXQgPSByeF9nZXQ7CgoJcnhfcHV0ID0gYnVmX2luZm8ucnhfcHV0OwoJaWYgKHJ4X2dldCA8PSByeF9wdXQpIHsKCQlzcGFjZSA9IENPTkZJR19TRVJJQUxfU09GVFdBUkVfRklGTyAtIChyeF9wdXQgLSByeF9nZXQpOwoJfSBlbHNlIHsKCQlzcGFjZSA9IHJ4X2dldCAtIHJ4X3B1dDsKCX0KCWlmIChzcGFjZSA+IENPTkZJR19TRVJJQUxfU09GVFdBUkVfRklGTyAvIDIpIHsKCQkvKiBTdGFydCBmbG93IGJ5IHNldHRpbmcgUlRTIGFjdGl2ZSAqLwoJCW91dGIoaW5iIChVQVJUMF9CQVNFICsgVUFSVF9NQ1IpIHwgMHgwMiwgVUFSVDBfQkFTRSArIFVBUlRfTUNSKTsKCX0KCglyZXR1cm4gYzsKfQoKaW50IHNlcmlhbF9idWZmZXJlZF90c3RjKHZvaWQpCnsKCXJldHVybiAoYnVmX2luZm8ucnhfZ2V0ICE9IGJ1Zl9pbmZvLnJ4X3B1dCkgPyAxIDogMDsKfQoKI2VuZGlmCS8qIENPTkZJR19TRVJJQUxfU09GVFdBUkVfRklGTyAqLwoKCiNpZiBkZWZpbmVkKENPTkZJR19DTURfS0dEQikKLyoKICBBUyBIQVJOT0lTIDogYWNjb3JkaW5nIHRvIENPTkZJR19LR0RCX1NFUl9JTkRFWCBrZ2RiIHVzZXMgc2VyaWFsIHBvcnQKICBudW1iZXIgMCBvciBudW1iZXIgMQogIC0gaWYgQ09ORklHX0tHREJfU0VSX0lOREVYID0gMSA9PiBzZXJpYWwgcG9ydCBudW1iZXIgMCA6CiAgY29uZmlndXJhdGlvbiBoYXMgYmVlbiBhbHJlYWR5IGRvbmUKICAtIGlmIENPTkZJR19LR0RCX1NFUl9JTkRFWCA9IDIgPT4gc2VyaWFsIHBvcnQgbnVtYmVyIDEgOgogIGNvbmZpZ3VyZSBwb3J0IDEgZm9yIHNlcmlhbCBJL08gd2l0aCByYXRlID0gQ09ORklHX0tHREJfQkFVRFJBVEUKKi8KI2lmIChDT05GSUdfS0dEQl9TRVJfSU5ERVggJiAyKQp2b2lkIGtnZGJfc2VyaWFsX2luaXQodm9pZCkKewoJdm9sYXRpbGUgY2hhciB2YWw7CgliZGl2ID0gc2VyaWFsX2RpdiAoQ09ORklHX0tHREJfQkFVRFJBVEUpOwoKCS8qCgkgKiBJbml0IG9uYm9hcmQgMTY1NTAgVUFSVAoJICovCglvdXRiKDB4ODAsIFVBUlQxX0JBU0UgKyBVQVJUX0xDUik7CS8qIHNldCBETEFCIGJpdCAqLwoJb3V0YigoYmRpdiAmIDB4ZmYpLCBVQVJUMV9CQVNFICsgVUFSVF9ETEwpOwkvKiBzZXQgZGl2aXNvciBmb3IgOTYwMCBiYXVkICovCglvdXRiKChiZGl2ID4+IDggICksIFVBUlQxX0JBU0UgKyBVQVJUX0RMTSk7CS8qIHNldCBkaXZpc29yIGZvciA5NjAwIGJhdWQgKi8KCW91dGIoMHgwMywgVUFSVDFfQkFTRSArIFVBUlRfTENSKTsJLyogbGluZSBjb250cm9sIDggYml0cyBubyBwYXJpdHkgKi8KCW91dGIoMHgwMCwgVUFSVDFfQkFTRSArIFVBUlRfRkNSKTsJLyogZGlzYWJsZSBGSUZPICovCglvdXRiKDB4MDAsIFVBUlQxX0JBU0UgKyBVQVJUX01DUik7CS8qIG5vIG1vZGVtIGNvbnRyb2wgRFRSIFJUUyAqLwoJdmFsID0gaW5iKFVBUlQxX0JBU0UgKyBVQVJUX0xTUik7CS8qIGNsZWFyIGxpbmUgc3RhdHVzICovCgl2YWwgPSBpbmIoVUFSVDFfQkFTRSArIFVBUlRfUkJSKTsJLyogcmVhZCByZWNlaXZlIGJ1ZmZlciAqLwoJb3V0YigweDAwLCBVQVJUMV9CQVNFICsgVUFSVF9TQ1IpOwkvKiBzZXQgc2NyYXRjaHBhZCAqLwoJb3V0YigweDAwLCBVQVJUMV9CQVNFICsgVUFSVF9JRVIpOwkvKiBzZXQgaW50ZXJydXB0IGVuYWJsZSByZWcgKi8KfQoKCnZvaWQgcHV0RGVidWdDaGFyKGNvbnN0IGNoYXIgYykKewoJaWYgKGMgPT0gJ1xuJykKCQlzZXJpYWxfcHV0YyAoJ1xyJyk7CgoJb3V0YihjLCBVQVJUMV9CQVNFICsgVUFSVF9USFIpOwkvKiBwdXQgY2hhcmFjdGVyIG91dCAqLwoKCS8qIGNoZWNrIFRIUkUgYml0LCB3YWl0IGZvciB0cmFuc2ZlciBkb25lICovCgl3aGlsZSAoKGluYihVQVJUMV9CQVNFICsgVUFSVF9MU1IpICYgMHgyMCkgIT0gMHgyMCk7Cn0KCgp2b2lkIHB1dERlYnVnU3RyKGNvbnN0IGNoYXIgKnMpCnsKCXdoaWxlICgqcykgewoJCXNlcmlhbF9wdXRjKCpzKyspOwoJfQp9CgoKaW50IGdldERlYnVnQ2hhcih2b2lkKQp7Cgl1bnNpZ25lZCBjaGFyIHN0YXR1cyA9IDA7CgoJd2hpbGUgKDEpIHsKCQlzdGF0dXMgPSBpbmIoVUFSVDFfQkFTRSArIFVBUlRfTFNSKTsKCQlpZiAoKHN0YXR1cyAmIGFzeW5jTFNSRGF0YVJlYWR5MSkgIT0gMHgwKSB7CgkJCWJyZWFrOwoJCX0KCQlpZiAoKHN0YXR1cyAmICggYXN5bmNMU1JGcmFtaW5nRXJyb3IxIHwKCQkJCWFzeW5jTFNST3ZlcnJ1bkVycm9yMSB8CgkJCQlhc3luY0xTUlBhcml0eUVycm9yMSAgfAoJCQkJYXN5bmNMU1JCcmVha0ludGVycnVwdDEgKSkgIT0gMCkgewoJCQlvdXRiKGFzeW5jTFNSRnJhbWluZ0Vycm9yMSB8CgkJCSAgICAgYXN5bmNMU1JPdmVycnVuRXJyb3IxIHwKCQkJICAgICBhc3luY0xTUlBhcml0eUVycm9yMSAgfAoJCQkgICAgIGFzeW5jTFNSQnJlYWtJbnRlcnJ1cHQxLCBVQVJUMV9CQVNFICsgVUFSVF9MU1IpOwoJCX0KCX0KCXJldHVybiAoMHgwMDAwMDBmZiAmIChpbnQpIGluYihVQVJUMV9CQVNFKSk7Cn0KCgp2b2lkIGtnZGJfaW50ZXJydXB0aWJsZShpbnQgeWVzKQp7CglyZXR1cm47Cn0KCiNlbHNlCS8qICEgKENPTkZJR19LR0RCX1NFUl9JTkRFWCAmIDIpICovCgp2b2lkIGtnZGJfc2VyaWFsX2luaXQodm9pZCkKewoJc2VyaWFsX3ByaW50ZiAoIltvbiBzZXJpYWxdICIpOwp9Cgp2b2lkIHB1dERlYnVnQ2hhcihpbnQgYykKewoJc2VyaWFsX3B1dGMgKGMpOwp9Cgp2b2lkIHB1dERlYnVnU3RyKGNvbnN0IGNoYXIgKnN0cikKewoJc2VyaWFsX3B1dHMgKHN0cik7Cn0KCmludCBnZXREZWJ1Z0NoYXIodm9pZCkKewoJcmV0dXJuIHNlcmlhbF9nZXRjICgpOwp9Cgp2b2lkIGtnZGJfaW50ZXJydXB0aWJsZShpbnQgeWVzKQp7CglyZXR1cm47Cn0KI2VuZGlmCS8qIChDT05GSUdfS0dEQl9TRVJfSU5ERVggJiAyKSAqLwojZW5kaWYK