LyoKICogKEMpIENvcHlyaWdodCAyMDAyCiAqIERhbmllbCBFbmdzdHL2bSwgT21pY3JvbiBDZXRpIEFCLCBkYW5pZWxAb21pY3Jvbi5zZQogKiAKICogKEMpIENvcHlyaWdodCAyMDAwCiAqIFdvbGZnYW5nIERlbmssIERFTlggU29mdHdhcmUgRW5naW5lZXJpbmcsIHdkQGRlbnguZGUuCiAqCiAqIFNlZSBmaWxlIENSRURJVFMgZm9yIGxpc3Qgb2YgcGVvcGxlIHdobyBjb250cmlidXRlZCB0byB0aGlzCiAqIHByb2plY3QuCiAqCiAqIFRoaXMgcHJvZ3JhbSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IKICogbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgYXMKICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlciB2ZXJzaW9uIDIgb2YKICogdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uCiAqCiAqIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLAogKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZgogKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlCiAqIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIGFsb25nIHdpdGggdGhpcyBwcm9ncmFtOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlCiAqIEZvdW5kYXRpb24sIEluYy4sIDU5IFRlbXBsZSBQbGFjZSwgU3VpdGUgMzMwLCBCb3N0b24sCiAqIE1BIDAyMTExLTEzMDcgVVNBCiAqLwovKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSsgKi8KLyoKICogVGhpcyBzb3VyY2UgY29kZSBoYXMgYmVlbiBtYWRlIGF2YWlsYWJsZSB0byB5b3UgYnkgSUJNIG9uIGFuIEFTLUlTCiAqIGJhc2lzLiAgQW55b25lIHJlY2VpdmluZyB0aGlzIHNvdXJjZSBpcyBsaWNlbnNlZCB1bmRlciBJQk0KICogY29weXJpZ2h0cyB0byB1c2UgaXQgaW4gYW55IHdheSBoZSBvciBzaGUgZGVlbXMgZml0LCBpbmNsdWRpbmcKICogY29weWluZyBpdCwgbW9kaWZ5aW5nIGl0LCBjb21waWxpbmcgaXQsIGFuZCByZWRpc3RyaWJ1dGluZyBpdCBlaXRoZXIKICogd2l0aCBvciB3aXRob3V0IG1vZGlmaWNhdGlvbnMuICBObyBsaWNlbnNlIHVuZGVyIElCTSBwYXRlbnRzIG9yCiAqIHBhdGVudCBhcHBsaWNhdGlvbnMgaXMgdG8gYmUgaW1wbGllZCBieSB0aGUgY29weXJpZ2h0IGxpY2Vuc2UuCiAqCiAqIEFueSB1c2VyIG9mIHRoaXMgc29mdHdhcmUgc2hvdWxkIHVuZGVyc3RhbmQgdGhhdCBJQk0gY2Fubm90IHByb3ZpZGUKICogdGVjaG5pY2FsIHN1cHBvcnQgZm9yIHRoaXMgc29mdHdhcmUgYW5kIHdpbGwgbm90IGJlIHJlc3BvbnNpYmxlIGZvcgogKiBhbnkgY29uc2VxdWVuY2VzIHJlc3VsdGluZyBmcm9tIHRoZSB1c2Ugb2YgdGhpcyBzb2Z0d2FyZS4KICoKICogQW55IHBlcnNvbiB3aG8gdHJhbnNmZXJzIHRoaXMgc291cmNlIGNvZGUgb3IgYW55IGRlcml2YXRpdmUgd29yawogKiBtdXN0IGluY2x1ZGUgdGhlIElCTSBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIHBhcmFncmFwaCwgYW5kIHRoZQogKiBwcmVjZWRpbmcgdHdvIHBhcmFncmFwaHMgaW4gdGhlIHRyYW5zZmVycmVkIHNvZnR3YXJlLgogKgogKiBDT1BZUklHSFQgICBJIEIgTSAgIENPUlBPUkFUSU9OIDE5OTUKICogTElDRU5TRUQgTUFURVJJQUwgIC0gIFBST0dSQU0gUFJPUEVSVFkgT0YgSSBCIE0KICovCi8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLwoKI2luY2x1ZGUgPGNvbW1vbi5oPgojaW5jbHVkZSA8d2F0Y2hkb2cuaD4KI2luY2x1ZGUgPGFzbS9pby5oPgojaW5jbHVkZSA8YXNtL2libXBjLmg+CgojaWYgQ09ORklHX1NFUklBTF9TT0ZUV0FSRV9GSUZPCiNpbmNsdWRlIDxtYWxsb2MuaD4KI2VuZGlmCgojZGVmaW5lIFVBUlRfUkJSICAgIDB4MDAKI2RlZmluZSBVQVJUX1RIUiAgICAweDAwCiNkZWZpbmUgVUFSVF9JRVIgICAgMHgwMQojZGVmaW5lIFVBUlRfSUlSICAgIDB4MDIKI2RlZmluZSBVQVJUX0ZDUiAgICAweDAyCiNkZWZpbmUgVUFSVF9MQ1IgICAgMHgwMwojZGVmaW5lIFVBUlRfTUNSICAgIDB4MDQKI2RlZmluZSBVQVJUX0xTUiAgICAweDA1CiNkZWZpbmUgVUFSVF9NU1IgICAgMHgwNgojZGVmaW5lIFVBUlRfU0NSICAgIDB4MDcKI2RlZmluZSBVQVJUX0RMTCAgICAweDAwCiNkZWZpbmUgVUFSVF9ETE0gICAgMHgwMQoKLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSsKICB8IExpbmUgU3RhdHVzIFJlZ2lzdGVyLgogICstLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCiNkZWZpbmUgYXN5bmNMU1JEYXRhUmVhZHkxICAgICAgICAgICAgMHgwMQojZGVmaW5lIGFzeW5jTFNST3ZlcnJ1bkVycm9yMSAgICAgICAgIDB4MDIKI2RlZmluZSBhc3luY0xTUlBhcml0eUVycm9yMSAgICAgICAgICAweDA0CiNkZWZpbmUgYXN5bmNMU1JGcmFtaW5nRXJyb3IxICAgICAgICAgMHgwOAojZGVmaW5lIGFzeW5jTFNSQnJlYWtJbnRlcnJ1cHQxICAgICAgIDB4MTAKI2RlZmluZSBhc3luY0xTUlR4SG9sZEVtcHR5MSAgICAgICAgICAweDIwCiNkZWZpbmUgYXN5bmNMU1JUeFNoaWZ0RW1wdHkxICAgICAgICAgMHg0MAojZGVmaW5lIGFzeW5jTFNSUnhGaWZvRXJyb3IxICAgICAgICAgIDB4ODAKCgoKI2lmIENPTkZJR19TRVJJQUxfU09GVFdBUkVfRklGTwovKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKwogIHwgRmlmbwogICstLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCnR5cGVkZWYgc3RydWN0IHsKCWNoYXIgKnJ4X2J1ZmZlcjsKCXVsb25nIHJ4X3B1dDsKCXVsb25nIHJ4X2dldDsKfSBzZXJpYWxfYnVmZmVyX3Q7Cgp2b2xhdGlsZSBzdGF0aWMgc2VyaWFsX2J1ZmZlcl90IGJ1Zl9pbmZvOwojZW5kaWYKCgpzdGF0aWMgaW50IHNlcmlhbF9kaXYgKGludCBiYXVkcmF0ZSApCnsKCQoJc3dpdGNoIChiYXVkcmF0ZSkgewoJY2FzZSAxMjAwOgoJCXJldHVybiA5NjsKCWNhc2UgOTYwMDoKCQlyZXR1cm4gMTI7CgljYXNlIDE5MjAwOgoJCXJldHVybiA2OwoJY2FzZSAzODQwMDoKCQlyZXR1cm4gMzsKCWNhc2UgNTc2MDA6CgkJcmV0dXJuIDI7CgljYXNlIDExNTIwMDoKCQlyZXR1cm4gMTsJCQoJfQoJaGFuZyAoKTsKfQoKCi8qCiAqIE1pbmltYWwgc2VyaWFsIGZ1bmN0aW9ucyBuZWVkZWQgdG8gdXNlIG9uZSBvZiB0aGUgU01DIHBvcnRzCiAqIGFzIHNlcmlhbCBjb25zb2xlIGludGVyZmFjZS4KICovCgppbnQgc2VyaWFsX2luaXQgKHZvaWQpCnsKCURFQ0xBUkVfR0xPQkFMX0RBVEFfUFRSOwoKCXZvbGF0aWxlIGNoYXIgdmFsOwoKCWludCBiZGl2ID0gc2VyaWFsX2RpdihnZC0+YmF1ZHJhdGUpOwogICAgCgoJb3V0YigweDgwLCBVQVJUMF9CQVNFICsgVUFSVF9MQ1IpOwkvKiBzZXQgRExBQiBiaXQgKi8KCW91dGIoYmRpdiwgVUFSVDBfQkFTRSArIFVBUlRfRExMKTsJLyogc2V0IGJhdWRyYXRlIGRpdmlzb3IgKi8KCW91dGIoYmRpdiA+PiA4LCBVQVJUMF9CQVNFICsgVUFSVF9ETE0pOy8qIHNldCBiYXVkcmF0ZSBkaXZpc29yICovCglvdXRiKDB4MDMsIFVBUlQwX0JBU0UgKyBVQVJUX0xDUik7CS8qIGNsZWFyIERMQUI7IHNldCA4IGJpdHMsIG5vIHBhcml0eSAqLwoJb3V0YigweDAwLCBVQVJUMF9CQVNFICsgVUFSVF9GQ1IpOwkvKiBkaXNhYmxlIEZJRk8gKi8KCW91dGIoMHgwMCwgVUFSVDBfQkFTRSArIFVBUlRfTUNSKTsJLyogbm8gbW9kZW0gY29udHJvbCBEVFIgUlRTICovCgl2YWwgPSBpbmIoVUFSVDBfQkFTRSArIFVBUlRfTFNSKTsJLyogY2xlYXIgbGluZSBzdGF0dXMgKi8KCXZhbCA9IGluYihVQVJUMF9CQVNFICsgVUFSVF9SQlIpOwkvKiByZWFkIHJlY2VpdmUgYnVmZmVyICovCglvdXRiKDB4MDAsIFVBUlQwX0JBU0UgKyBVQVJUX1NDUik7CS8qIHNldCBzY3JhdGNocGFkICovCglvdXRiKDB4MDAsIFVBUlQwX0JBU0UgKyBVQVJUX0lFUik7CS8qIHNldCBpbnRlcnJ1cHQgZW5hYmxlIHJlZyAqLwoKCXJldHVybiAoMCk7Cn0KCgp2b2lkIHNlcmlhbF9zZXRicmcgKHZvaWQpCnsKCURFQ0xBUkVfR0xPQkFMX0RBVEFfUFRSOwoKCXVuc2lnbmVkIHNob3J0IGJkaXY7CgkKCWJkaXYgPSBzZXJpYWxfZGl2IChnZC0+YmF1ZHJhdGUpOwoKCW91dGIoMHg4MCwgVUFSVDBfQkFTRSArIFVBUlRfTENSKTsJLyogc2V0IERMQUIgYml0ICovCglvdXRiKGJkaXYmMHhmZiwgVUFSVDBfQkFTRSArIFVBUlRfRExMKTsJLyogc2V0IGJhdWRyYXRlIGRpdmlzb3IgKi8KCW91dGIoYmRpdiA+PiA4LCBVQVJUMF9CQVNFICsgVUFSVF9ETE0pOy8qIHNldCBiYXVkcmF0ZSBkaXZpc29yICovCglvdXRiKDB4MDMsIFVBUlQwX0JBU0UgKyBVQVJUX0xDUik7CS8qIGNsZWFyIERMQUI7IHNldCA4IGJpdHMsIG5vIHBhcml0eSAqLwp9CgoKdm9pZCBzZXJpYWxfcHV0YyAoY29uc3QgY2hhciBjKQp7CglpbnQgaTsKCglpZiAoYyA9PSAnXG4nKQoJCXNlcmlhbF9wdXRjICgnXHInKTsKCgkvKiBjaGVjayBUSFJFIGJpdCwgd2FpdCBmb3IgdHJhbnNtaXRlciBhdmFpbGFibGUgKi8KCWZvciAoaSA9IDE7IGkgPCAzNTAwOyBpKyspIHsKCQlpZiAoKGluYiAoVUFSVDBfQkFTRSArIFVBUlRfTFNSKSAmIDB4MjApID09IDB4MjApCgkJCWJyZWFrOwoJCXVkZWxheSAoMTAwKTsKCX0KCW91dGIoYywgVUFSVDBfQkFTRSArIFVBUlRfVEhSKTsJLyogcHV0IGNoYXJhY3RlciBvdXQgKi8KfQoKCnZvaWQgc2VyaWFsX3B1dHMgKGNvbnN0IGNoYXIgKnMpCnsKCXdoaWxlICgqcykgewoJCXNlcmlhbF9wdXRjICgqcysrKTsKCX0KfQoKCmludCBzZXJpYWxfZ2V0YyAoKQp7Cgl1bnNpZ25lZCBjaGFyIHN0YXR1cyA9IDA7CgoJd2hpbGUgKDEpIHsKI2lmIGRlZmluZWQoQ09ORklHX0hXX1dBVENIRE9HKQoJCVdBVENIRE9HX1JFU0VUICgpOwkvKiBSZXNldCBIVyBXYXRjaGRvZywgaWYgbmVlZGVkICovCiNlbmRpZgkvKiBDT05GSUdfSFdfV0FUQ0hET0cgKi8KCQlzdGF0dXMgPSBpbmIgKFVBUlQwX0JBU0UgKyBVQVJUX0xTUik7CgkJaWYgKChzdGF0dXMgJiBhc3luY0xTUkRhdGFSZWFkeTEpICE9IDB4MCkgewoJCQlicmVhazsKCQl9CgkJaWYgKChzdGF0dXMgJiAoIGFzeW5jTFNSRnJhbWluZ0Vycm9yMSB8CgkJCQlhc3luY0xTUk92ZXJydW5FcnJvcjEgfAoJCQkJYXN5bmNMU1JQYXJpdHlFcnJvcjEgIHwKCQkJCWFzeW5jTFNSQnJlYWtJbnRlcnJ1cHQxICkpICE9IDApIHsKCQkJb3V0Yihhc3luY0xTUkZyYW1pbmdFcnJvcjEgfAoJCQkgICAgICBhc3luY0xTUk92ZXJydW5FcnJvcjEgfAoJCQkgICAgICBhc3luY0xTUlBhcml0eUVycm9yMSAgfAoJCQkgICAgICBhc3luY0xTUkJyZWFrSW50ZXJydXB0MSwgVUFSVDBfQkFTRSArIFVBUlRfTFNSKTsKCQl9Cgl9CglyZXR1cm4gKDB4MDAwMDAwZmYgJiAoaW50KSBpbmIgKFVBUlQwX0JBU0UpKTsKfQoKCmludCBzZXJpYWxfdHN0YyAoKQp7Cgl1bnNpZ25lZCBjaGFyIHN0YXR1czsKCglzdGF0dXMgPSBpbmIgKFVBUlQwX0JBU0UgKyBVQVJUX0xTUik7CglpZiAoKHN0YXR1cyAmIGFzeW5jTFNSRGF0YVJlYWR5MSkgIT0gMHgwKSB7CgkJcmV0dXJuICgxKTsKCX0KCWlmICgoc3RhdHVzICYgKCBhc3luY0xTUkZyYW1pbmdFcnJvcjEgfAoJCQlhc3luY0xTUk92ZXJydW5FcnJvcjEgfAoJCQlhc3luY0xTUlBhcml0eUVycm9yMSAgfAoJCQlhc3luY0xTUkJyZWFrSW50ZXJydXB0MSApKSAhPSAwKSB7CgkJb3V0Yihhc3luY0xTUkZyYW1pbmdFcnJvcjEgfAoJCSAgICAgIGFzeW5jTFNST3ZlcnJ1bkVycm9yMSB8CgkJICAgICAgYXN5bmNMU1JQYXJpdHlFcnJvcjEgIHwKCQkgICAgICBhc3luY0xTUkJyZWFrSW50ZXJydXB0MSwgVUFSVDBfQkFTRSArIFVBUlRfTFNSKTsKCX0KCXJldHVybiAwOwp9CgoKI2lmIENPTkZJR19TRVJJQUxfU09GVFdBUkVfRklGTwoKdm9pZCBzZXJpYWxfaXNyICh2b2lkICphcmcpCnsKCWludCBzcGFjZTsKCWludCBjOwoJY29uc3QgaW50IHJ4X2dldCA9IGJ1Zl9pbmZvLnJ4X2dldDsKCWludCByeF9wdXQgPSBidWZfaW5mby5yeF9wdXQ7CgoJaWYgKHJ4X2dldCA8PSByeF9wdXQpIHsKCQlzcGFjZSA9IENPTkZJR19TRVJJQUxfU09GVFdBUkVfRklGTyAtIChyeF9wdXQgLSByeF9nZXQpOwoJfSBlbHNlIHsKCQlzcGFjZSA9IHJ4X2dldCAtIHJ4X3B1dDsKCX0KCXdoaWxlIChzZXJpYWxfdHN0YyAoKSkgewoJCWMgPSBzZXJpYWxfZ2V0YyAoKTsKCQlpZiAoc3BhY2UpIHsKCQkJYnVmX2luZm8ucnhfYnVmZmVyW3J4X3B1dCsrXSA9IGM7CgkJCXNwYWNlLS07CgkJfQoJCWlmIChyeF9wdXQgPT0gQ09ORklHX1NFUklBTF9TT0ZUV0FSRV9GSUZPKQoJCQlyeF9wdXQgPSAwOwoJCWlmIChzcGFjZSA8IENPTkZJR19TRVJJQUxfU09GVFdBUkVfRklGTyAvIDQpIHsKCQkJLyogU3RvcCBmbG93IGJ5IHNldHRpbmcgUlRTIGluYWN0aXZlICovCgkJCW91dGIoaW5iIChVQVJUMF9CQVNFICsgVUFSVF9NQ1IpICYgKDB4RkYgXiAweDAyKSwKCQkJICAgICAgVUFSVDBfQkFTRSArIFVBUlRfTUNSKTsKCQl9Cgl9CglidWZfaW5mby5yeF9wdXQgPSByeF9wdXQ7Cn0KCnZvaWQgc2VyaWFsX2J1ZmZlcmVkX2luaXQgKHZvaWQpCnsKCXNlcmlhbF9wdXRzICgiU3dpdGNoaW5nIHRvIGludGVycnVwdCBkcml2ZW4gc2VyaWFsIGlucHV0IG1vZGUuXG4iKTsKCWJ1Zl9pbmZvLnJ4X2J1ZmZlciA9IG1hbGxvYyAoQ09ORklHX1NFUklBTF9TT0ZUV0FSRV9GSUZPKTsKCWJ1Zl9pbmZvLnJ4X3B1dCA9IDA7CglidWZfaW5mby5yeF9nZXQgPSAwOwoKCWlmIChpbmIgKFVBUlQwX0JBU0UgKyBVQVJUX01TUikgJiAweDEwKSB7CgkJc2VyaWFsX3B1dHMgKCJDaGVjayBDVFMgc2lnbmFsIHByZXNlbnQgb24gc2VyaWFsIHBvcnQ6IE9LLlxuIik7Cgl9IGVsc2UgewoJCXNlcmlhbF9wdXRzICgiV0FSTklORzogQ1RTIHNpZ25hbCBub3QgcHJlc2VudCBvbiBzZXJpYWwgcG9ydC5cbiIpOwoJfQoKCWlycV9pbnN0YWxsX2hhbmRsZXIgKCBWRUNOVU1fVTAgLypVQVJUMCAqLy8qaW50IHZlYyAqLyAsCgkJCSAgICAgIHNlcmlhbF9pc3IgLyppbnRlcnJ1cHRfaGFuZGxlcl90ICpoYW5kbGVyICovICwKCQkJICAgICAgKHZvaWQgKikgJmJ1Zl9pbmZvIC8qdm9pZCAqYXJnICovICk7CgoJLyogRW5hYmxlICJSWCBEYXRhIEF2YWlsYWJsZSIgSW50ZXJydXB0IG9uIFVBUlQgKi8KCS8qIG91dGIoaW5iKFVBUlQwX0JBU0UgKyBVQVJUX0lFUikgfDB4MDEsIFVBUlQwX0JBU0UgKyBVQVJUX0lFUik7ICovCglvdXRiKDB4MDEsIFVBUlQwX0JBU0UgKyBVQVJUX0lFUik7CgkvKiBTZXQgRFRSIGFjdGl2ZSAqLwoJb3V0YihpbmIgKFVBUlQwX0JBU0UgKyBVQVJUX01DUikgfCAweDAxLCBVQVJUMF9CQVNFICsgVUFSVF9NQ1IpOwoJLyogU3RhcnQgZmxvdyBieSBzZXR0aW5nIFJUUyBhY3RpdmUgKi8KCW91dGIoaW5iIChVQVJUMF9CQVNFICsgVUFSVF9NQ1IpIHwgMHgwMiwgVUFSVDBfQkFTRSArIFVBUlRfTUNSKTsKCS8qIFNldHVwIFVBUlQgRklGTzogUlggdHJpZ2dlciBsZXZlbDogNCBieXRlLCBFbmFibGUgRklGTyAqLwoJb3V0YigoMSA8PCA2KSB8IDEsIFVBUlQwX0JBU0UgKyBVQVJUX0ZDUik7Cn0KCnZvaWQgc2VyaWFsX2J1ZmZlcmVkX3B1dGMgKGNvbnN0IGNoYXIgYykKewoJLyogV2FpdCBmb3IgQ1RTICovCiNpZiBkZWZpbmVkKENPTkZJR19IV19XQVRDSERPRykKCXdoaWxlICghKGluYiAoVUFSVDBfQkFTRSArIFVBUlRfTVNSKSAmIDB4MTApKQoJCVdBVENIRE9HX1JFU0VUICgpOwojZWxzZQoJd2hpbGUgKCEoaW5iIChVQVJUMF9CQVNFICsgVUFSVF9NU1IpICYgMHgxMCkpOwojZW5kaWYKCXNlcmlhbF9wdXRjIChjKTsKfQoKdm9pZCBzZXJpYWxfYnVmZmVyZWRfcHV0cyAoY29uc3QgY2hhciAqcykKewoJc2VyaWFsX3B1dHMgKHMpOwp9CgppbnQgc2VyaWFsX2J1ZmZlcmVkX2dldGMgKHZvaWQpCnsKCWludCBzcGFjZTsKCWludCBjOwoJaW50IHJ4X2dldCA9IGJ1Zl9pbmZvLnJ4X2dldDsKCWludCByeF9wdXQ7CgojaWYgZGVmaW5lZChDT05GSUdfSFdfV0FUQ0hET0cpCgl3aGlsZSAocnhfZ2V0ID09IGJ1Zl9pbmZvLnJ4X3B1dCkKCQlXQVRDSERPR19SRVNFVCAoKTsKI2Vsc2UKCXdoaWxlIChyeF9nZXQgPT0gYnVmX2luZm8ucnhfcHV0KTsKI2VuZGlmCgljID0gYnVmX2luZm8ucnhfYnVmZmVyW3J4X2dldCsrXTsKCWlmIChyeF9nZXQgPT0gQ09ORklHX1NFUklBTF9TT0ZUV0FSRV9GSUZPKQoJCXJ4X2dldCA9IDA7CglidWZfaW5mby5yeF9nZXQgPSByeF9nZXQ7CgoJcnhfcHV0ID0gYnVmX2luZm8ucnhfcHV0OwoJaWYgKHJ4X2dldCA8PSByeF9wdXQpIHsKCQlzcGFjZSA9IENPTkZJR19TRVJJQUxfU09GVFdBUkVfRklGTyAtIChyeF9wdXQgLSByeF9nZXQpOwoJfSBlbHNlIHsKCQlzcGFjZSA9IHJ4X2dldCAtIHJ4X3B1dDsKCX0KCWlmIChzcGFjZSA+IENPTkZJR19TRVJJQUxfU09GVFdBUkVfRklGTyAvIDIpIHsKCQkvKiBTdGFydCBmbG93IGJ5IHNldHRpbmcgUlRTIGFjdGl2ZSAqLwoJCW91dGIoaW5iIChVQVJUMF9CQVNFICsgVUFSVF9NQ1IpIHwgMHgwMiwgVUFSVDBfQkFTRSArIFVBUlRfTUNSKTsKCX0KCglyZXR1cm4gYzsKfQoKaW50IHNlcmlhbF9idWZmZXJlZF90c3RjICh2b2lkKQp7CglyZXR1cm4gKGJ1Zl9pbmZvLnJ4X2dldCAhPSBidWZfaW5mby5yeF9wdXQpID8gMSA6IDA7Cn0KCiNlbmRpZgkvKiBDT05GSUdfU0VSSUFMX1NPRlRXQVJFX0ZJRk8gKi8KCgojaWYgKENPTkZJR19DT01NQU5EUyAmIENGR19DTURfS0dEQikKLyoKICBBUyBIQVJOT0lTIDogYWNjb3JkaW5nIHRvIENPTkZJR19LR0RCX1NFUl9JTkRFWCBrZ2RiIHVzZXMgc2VyaWFsIHBvcnQKICBudW1iZXIgMCBvciBudW1iZXIgMQogIC0gaWYgQ09ORklHX0tHREJfU0VSX0lOREVYID0gMSA9PiBzZXJpYWwgcG9ydCBudW1iZXIgMCA6CiAgY29uZmlndXJhdGlvbiBoYXMgYmVlbiBhbHJlYWR5IGRvbmUKICAtIGlmIENPTkZJR19LR0RCX1NFUl9JTkRFWCA9IDIgPT4gc2VyaWFsIHBvcnQgbnVtYmVyIDEgOgogIGNvbmZpZ3VyZSBwb3J0IDEgZm9yIHNlcmlhbCBJL08gd2l0aCByYXRlID0gQ09ORklHX0tHREJfQkFVRFJBVEUKKi8KI2lmIChDT05GSUdfS0dEQl9TRVJfSU5ERVggJiAyKQp2b2lkIGtnZGJfc2VyaWFsX2luaXQgKHZvaWQpCnsKCURFQ0xBUkVfR0xPQkFMX0RBVEFfUFRSOwoKCXZvbGF0aWxlIGNoYXIgdmFsOwoJYmRpdiA9IHNlcmlhbF9kaXYgKENPTkZJR19LR0RCX0JBVURSQVRFKTsKCgkvKgoJICogSW5pdCBvbmJvYXJkIDE2NTUwIFVBUlQKCSAqLwoJb3V0YigweDgwLCBVQVJUMV9CQVNFICsgVUFSVF9MQ1IpOwkvKiBzZXQgRExBQiBiaXQgKi8KCW91dGIoYmRpdiAmIDB4ZmYpLCBVQVJUMV9CQVNFICsgVUFSVF9ETEwpOwkvKiBzZXQgZGl2aXNvciBmb3IgOTYwMCBiYXVkICovCglvdXRiKGJkaXYgPj4gOCksIFVBUlQxX0JBU0UgKyBVQVJUX0RMTSk7CS8qIHNldCBkaXZpc29yIGZvciA5NjAwIGJhdWQgKi8KCW91dGIoMHgwMywgVUFSVDFfQkFTRSArIFVBUlRfTENSKTsJLyogbGluZSBjb250cm9sIDggYml0cyBubyBwYXJpdHkgKi8KCW91dGIoMHgwMCwgVUFSVDFfQkFTRSArIFVBUlRfRkNSKTsJLyogZGlzYWJsZSBGSUZPICovCglvdXRiKDB4MDAsIFVBUlQxX0JBU0UgKyBVQVJUX01DUik7CS8qIG5vIG1vZGVtIGNvbnRyb2wgRFRSIFJUUyAqLwoJdmFsID0gaW5iKFVBUlQxX0JBU0UgKyBVQVJUX0xTUik7CS8qIGNsZWFyIGxpbmUgc3RhdHVzICovCgl2YWwgPSBpbmIoVUFSVDFfQkFTRSArIFVBUlRfUkJSKTsJLyogcmVhZCByZWNlaXZlIGJ1ZmZlciAqLwoJb3V0YigweDAwLCBVQVJUMV9CQVNFICsgVUFSVF9TQ1IpOwkvKiBzZXQgc2NyYXRjaHBhZCAqLwoJb3V0YigweDAwLCBVQVJUMV9CQVNFICsgVUFSVF9JRVIpOwkvKiBzZXQgaW50ZXJydXB0IGVuYWJsZSByZWcgKi8KfQoKCnZvaWQgcHV0RGVidWdDaGFyIChjb25zdCBjaGFyIGMpCnsKCWlmIChjID09ICdcbicpCgkJc2VyaWFsX3B1dGMgKCdccicpOwoKCW91dGIoYywgVUFSVDFfQkFTRSArIFVBUlRfVEhSKTsJLyogcHV0IGNoYXJhY3RlciBvdXQgKi8KCgkvKiBjaGVjayBUSFJFIGJpdCwgd2FpdCBmb3IgdHJhbnNmZXIgZG9uZSAqLwoJd2hpbGUgKChpbmIoVUFSVDFfQkFTRSArIFVBUlRfTFNSKSAmIDB4MjApICE9IDB4MjApOwp9CgoKdm9pZCBwdXREZWJ1Z1N0ciAoY29uc3QgY2hhciAqcykKewoJd2hpbGUgKCpzKSB7CgkJc2VyaWFsX3B1dGMoKnMrKyk7Cgl9Cn0KCgppbnQgZ2V0RGVidWdDaGFyICh2b2lkKQp7Cgl1bnNpZ25lZCBjaGFyIHN0YXR1cyA9IDA7CgoJd2hpbGUgKDEpIHsKCQlzdGF0dXMgPSBpbmIoVUFSVDFfQkFTRSArIFVBUlRfTFNSKTsKCQlpZiAoKHN0YXR1cyAmIGFzeW5jTFNSRGF0YVJlYWR5MSkgIT0gMHgwKSB7CgkJCWJyZWFrOwoJCX0KCQlpZiAoKHN0YXR1cyAmICggYXN5bmNMU1JGcmFtaW5nRXJyb3IxIHwKCQkJCWFzeW5jTFNST3ZlcnJ1bkVycm9yMSB8CgkJCQlhc3luY0xTUlBhcml0eUVycm9yMSAgfAoJCQkJYXN5bmNMU1JCcmVha0ludGVycnVwdDEgKSkgIT0gMCkgewoJCQlvdXRiKGFzeW5jTFNSRnJhbWluZ0Vycm9yMSB8CgkJCSAgICAgYXN5bmNMU1JPdmVycnVuRXJyb3IxIHwKCQkJICAgICBhc3luY0xTUlBhcml0eUVycm9yMSAgfAoJCQkgICAgIGFzeW5jTFNSQnJlYWtJbnRlcnJ1cHQxLCBVQVJUMV9CQVNFICsgVUFSVF9MU1IpOwoJCX0KCX0KCXJldHVybiAoMHgwMDAwMDBmZiAmIChpbnQpIGluYihVQVJUMV9CQVNFKSk7Cn0KCgp2b2lkIGtnZGJfaW50ZXJydXB0aWJsZSAoaW50IHllcykKewoJcmV0dXJuOwp9CgojZWxzZQkvKiAhIChDT05GSUdfS0dEQl9TRVJfSU5ERVggJiAyKSAqLwoKdm9pZCBrZ2RiX3NlcmlhbF9pbml0ICh2b2lkKQp7CglzZXJpYWxfcHJpbnRmICgiW29uIHNlcmlhbF0gIik7Cn0KCnZvaWQgcHV0RGVidWdDaGFyIChpbnQgYykKewoJc2VyaWFsX3B1dGMgKGMpOwp9Cgp2b2lkIHB1dERlYnVnU3RyIChjb25zdCBjaGFyICpzdHIpCnsKCXNlcmlhbF9wdXRzIChzdHIpOwp9CgppbnQgZ2V0RGVidWdDaGFyICh2b2lkKQp7CglyZXR1cm4gc2VyaWFsX2dldGMgKCk7Cn0KCnZvaWQga2dkYl9pbnRlcnJ1cHRpYmxlIChpbnQgeWVzKQp7CglyZXR1cm47Cn0KI2VuZGlmCS8qIChDT05GSUdfS0dEQl9TRVJfSU5ERVggJiAyKSAqLwojZW5kaWYJLyogQ0ZHX0NNRF9LR0RCICovCgo=