LyoKICogR2x1ZSBjb2RlIGZvciB0aGUgU0hBMjU2IFNlY3VyZSBIYXNoIEFsZ29yaXRobSBhc3NlbWJseSBpbXBsZW1lbnRhdGlvbgogKiB1c2luZyBvcHRpbWl6ZWQgQVJNIGFzc2VtYmxlciBhbmQgTkVPTiBpbnN0cnVjdGlvbnMuCiAqCiAqIENvcHlyaWdodCCpIDIwMTUgR29vZ2xlIEluYy4KICoKICogVGhpcyBmaWxlIGlzIGJhc2VkIG9uIHNoYTI1Nl9zc3NlM19nbHVlLmM6CiAqICAgQ29weXJpZ2h0IChDKSAyMDEzIEludGVsIENvcnBvcmF0aW9uCiAqICAgQXV0aG9yOiBUaW0gQ2hlbiA8dGltLmMuY2hlbkBsaW51eC5pbnRlbC5jb20+CiAqCiAqIFRoaXMgcHJvZ3JhbSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0CiAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlCiAqIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlciB2ZXJzaW9uIDIgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikKICogYW55IGxhdGVyIHZlcnNpb24uCiAqCiAqLwoKI2luY2x1ZGUgPGNyeXB0by9pbnRlcm5hbC9oYXNoLmg+CiNpbmNsdWRlIDxsaW51eC9jcnlwdG8uaD4KI2luY2x1ZGUgPGxpbnV4L2luaXQuaD4KI2luY2x1ZGUgPGxpbnV4L21vZHVsZS5oPgojaW5jbHVkZSA8bGludXgvbW0uaD4KI2luY2x1ZGUgPGxpbnV4L2NyeXB0b2hhc2guaD4KI2luY2x1ZGUgPGxpbnV4L3R5cGVzLmg+CiNpbmNsdWRlIDxsaW51eC9zdHJpbmcuaD4KI2luY2x1ZGUgPGNyeXB0by9zaGEuaD4KI2luY2x1ZGUgPGNyeXB0by9zaGEyNTZfYmFzZS5oPgojaW5jbHVkZSA8YXNtL3NpbWQuaD4KI2luY2x1ZGUgPGFzbS9uZW9uLmg+CgojaW5jbHVkZSAic2hhMjU2X2dsdWUuaCIKCmFzbWxpbmthZ2Ugdm9pZCBzaGEyNTZfYmxvY2tfZGF0YV9vcmRlcih1MzIgKmRpZ2VzdCwgY29uc3Qgdm9pZCAqZGF0YSwKCQkJCQl1bnNpZ25lZCBpbnQgbnVtX2Jsa3MpOwoKaW50IGNyeXB0b19zaGEyNTZfYXJtX3VwZGF0ZShzdHJ1Y3Qgc2hhc2hfZGVzYyAqZGVzYywgY29uc3QgdTggKmRhdGEsCgkJCSAgICAgdW5zaWduZWQgaW50IGxlbikKewoJLyogbWFrZSBzdXJlIGNhc3RpbmcgdG8gc2hhMjU2X2Jsb2NrX2ZuKCkgaXMgc2FmZSAqLwoJQlVJTERfQlVHX09OKG9mZnNldG9mKHN0cnVjdCBzaGEyNTZfc3RhdGUsIHN0YXRlKSAhPSAwKTsKCglyZXR1cm4gc2hhMjU2X2Jhc2VfZG9fdXBkYXRlKGRlc2MsIGRhdGEsIGxlbiwKCQkJCShzaGEyNTZfYmxvY2tfZm4gKilzaGEyNTZfYmxvY2tfZGF0YV9vcmRlcik7Cn0KRVhQT1JUX1NZTUJPTChjcnlwdG9fc2hhMjU2X2FybV91cGRhdGUpOwoKc3RhdGljIGludCBzaGEyNTZfZmluYWwoc3RydWN0IHNoYXNoX2Rlc2MgKmRlc2MsIHU4ICpvdXQpCnsKCXNoYTI1Nl9iYXNlX2RvX2ZpbmFsaXplKGRlc2MsCgkJCQkoc2hhMjU2X2Jsb2NrX2ZuICopc2hhMjU2X2Jsb2NrX2RhdGFfb3JkZXIpOwoJcmV0dXJuIHNoYTI1Nl9iYXNlX2ZpbmlzaChkZXNjLCBvdXQpOwp9CgppbnQgY3J5cHRvX3NoYTI1Nl9hcm1fZmludXAoc3RydWN0IHNoYXNoX2Rlc2MgKmRlc2MsIGNvbnN0IHU4ICpkYXRhLAoJCQkgICAgdW5zaWduZWQgaW50IGxlbiwgdTggKm91dCkKewoJc2hhMjU2X2Jhc2VfZG9fdXBkYXRlKGRlc2MsIGRhdGEsIGxlbiwKCQkJICAgICAgKHNoYTI1Nl9ibG9ja19mbiAqKXNoYTI1Nl9ibG9ja19kYXRhX29yZGVyKTsKCXJldHVybiBzaGEyNTZfZmluYWwoZGVzYywgb3V0KTsKfQpFWFBPUlRfU1lNQk9MKGNyeXB0b19zaGEyNTZfYXJtX2ZpbnVwKTsKCnN0YXRpYyBzdHJ1Y3Qgc2hhc2hfYWxnIGFsZ3NbXSA9IHsgewoJLmRpZ2VzdHNpemUJPQlTSEEyNTZfRElHRVNUX1NJWkUsCgkuaW5pdAkJPQlzaGEyNTZfYmFzZV9pbml0LAoJLnVwZGF0ZQkJPQljcnlwdG9fc2hhMjU2X2FybV91cGRhdGUsCgkuZmluYWwJCT0Jc2hhMjU2X2ZpbmFsLAoJLmZpbnVwCQk9CWNyeXB0b19zaGEyNTZfYXJtX2ZpbnVwLAoJLmRlc2NzaXplCT0Jc2l6ZW9mKHN0cnVjdCBzaGEyNTZfc3RhdGUpLAoJLmJhc2UJCT0JewoJCS5jcmFfbmFtZQk9CSJzaGEyNTYiLAoJCS5jcmFfZHJpdmVyX25hbWUgPQkic2hhMjU2LWFzbSIsCgkJLmNyYV9wcmlvcml0eQk9CTE1MCwKCQkuY3JhX2ZsYWdzCT0JQ1JZUFRPX0FMR19UWVBFX1NIQVNILAoJCS5jcmFfYmxvY2tzaXplCT0JU0hBMjU2X0JMT0NLX1NJWkUsCgkJLmNyYV9tb2R1bGUJPQlUSElTX01PRFVMRSwKCX0KfSwgewoJLmRpZ2VzdHNpemUJPQlTSEEyMjRfRElHRVNUX1NJWkUsCgkuaW5pdAkJPQlzaGEyMjRfYmFzZV9pbml0LAoJLnVwZGF0ZQkJPQljcnlwdG9fc2hhMjU2X2FybV91cGRhdGUsCgkuZmluYWwJCT0Jc2hhMjU2X2ZpbmFsLAoJLmZpbnVwCQk9CWNyeXB0b19zaGEyNTZfYXJtX2ZpbnVwLAoJLmRlc2NzaXplCT0Jc2l6ZW9mKHN0cnVjdCBzaGEyNTZfc3RhdGUpLAoJLmJhc2UJCT0JewoJCS5jcmFfbmFtZQk9CSJzaGEyMjQiLAoJCS5jcmFfZHJpdmVyX25hbWUgPQkic2hhMjI0LWFzbSIsCgkJLmNyYV9wcmlvcml0eQk9CTE1MCwKCQkuY3JhX2ZsYWdzCT0JQ1JZUFRPX0FMR19UWVBFX1NIQVNILAoJCS5jcmFfYmxvY2tzaXplCT0JU0hBMjI0X0JMT0NLX1NJWkUsCgkJLmNyYV9tb2R1bGUJPQlUSElTX01PRFVMRSwKCX0KfSB9OwoKc3RhdGljIGludCBfX2luaXQgc2hhMjU2X21vZF9pbml0KHZvaWQpCnsKCWludCByZXMgPSBjcnlwdG9fcmVnaXN0ZXJfc2hhc2hlcyhhbGdzLCBBUlJBWV9TSVpFKGFsZ3MpKTsKCglpZiAocmVzIDwgMCkKCQlyZXR1cm4gcmVzOwoKCWlmIChJU19FTkFCTEVEKENPTkZJR19LRVJORUxfTU9ERV9ORU9OKSAmJiBjcHVfaGFzX25lb24oKSkgewoJCXJlcyA9IGNyeXB0b19yZWdpc3Rlcl9zaGFzaGVzKHNoYTI1Nl9uZW9uX2FsZ3MsCgkJCQkJICAgICAgQVJSQVlfU0laRShzaGEyNTZfbmVvbl9hbGdzKSk7CgoJCWlmIChyZXMgPCAwKQoJCQljcnlwdG9fdW5yZWdpc3Rlcl9zaGFzaGVzKGFsZ3MsIEFSUkFZX1NJWkUoYWxncykpOwoJfQoKCXJldHVybiByZXM7Cn0KCnN0YXRpYyB2b2lkIF9fZXhpdCBzaGEyNTZfbW9kX2Zpbmkodm9pZCkKewoJY3J5cHRvX3VucmVnaXN0ZXJfc2hhc2hlcyhhbGdzLCBBUlJBWV9TSVpFKGFsZ3MpKTsKCglpZiAoSVNfRU5BQkxFRChDT05GSUdfS0VSTkVMX01PREVfTkVPTikgJiYgY3B1X2hhc19uZW9uKCkpCgkJY3J5cHRvX3VucmVnaXN0ZXJfc2hhc2hlcyhzaGEyNTZfbmVvbl9hbGdzLAoJCQkJCSAgQVJSQVlfU0laRShzaGEyNTZfbmVvbl9hbGdzKSk7Cn0KCm1vZHVsZV9pbml0KHNoYTI1Nl9tb2RfaW5pdCk7Cm1vZHVsZV9leGl0KHNoYTI1Nl9tb2RfZmluaSk7CgpNT0RVTEVfTElDRU5TRSgiR1BMIik7Ck1PRFVMRV9ERVNDUklQVElPTigiU0hBMjU2IFNlY3VyZSBIYXNoIEFsZ29yaXRobSAoQVJNKSwgaW5jbHVkaW5nIE5FT04iKTsKCk1PRFVMRV9BTElBU19DUllQVE8oInNoYTI1NiIpOwo=