LyoKICogR2x1ZSBjb2RlIGZvciB0aGUgU0hBMjU2IFNlY3VyZSBIYXNoIEFsZ29yaXRobSBhc3NlbWJseSBpbXBsZW1lbnRhdGlvbgogKiB1c2luZyBORU9OIGluc3RydWN0aW9ucy4KICoKICogQ29weXJpZ2h0IKkgMjAxNSBHb29nbGUgSW5jLgogKgogKiBUaGlzIGZpbGUgaXMgYmFzZWQgb24gc2hhNTEyX25lb25fZ2x1ZS5jOgogKiAgIENvcHlyaWdodCCpIDIwMTQgSnVzc2kgS2l2aWxpbm5hIDxqdXNzaS5raXZpbGlubmFAaWtpLmZpPgogKgogKiBUaGlzIHByb2dyYW0gaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdAogKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZQogKiBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXIgdmVyc2lvbiAyIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pCiAqIGFueSBsYXRlciB2ZXJzaW9uLgogKgogKi8KCiNpbmNsdWRlIDxjcnlwdG8vaW50ZXJuYWwvaGFzaC5oPgojaW5jbHVkZSA8bGludXgvY3J5cHRvaGFzaC5oPgojaW5jbHVkZSA8bGludXgvZXhwb3J0Lmg+CiNpbmNsdWRlIDxsaW51eC90eXBlcy5oPgojaW5jbHVkZSA8bGludXgvc3RyaW5nLmg+CiNpbmNsdWRlIDxjcnlwdG8vc2hhLmg+CiNpbmNsdWRlIDxhc20vYnl0ZW9yZGVyLmg+CiNpbmNsdWRlIDxhc20vc2ltZC5oPgojaW5jbHVkZSA8YXNtL25lb24uaD4KI2luY2x1ZGUgInNoYTI1Nl9nbHVlLmgiCgphc21saW5rYWdlIHZvaWQgc2hhMjU2X2Jsb2NrX2RhdGFfb3JkZXJfbmVvbih1MzIgKmRpZ2VzdCwgY29uc3Qgdm9pZCAqZGF0YSwKCQkJCSAgICAgIHVuc2lnbmVkIGludCBudW1fYmxrcyk7CgoKc3RhdGljIGludCBfX3NoYTI1Nl9uZW9uX3VwZGF0ZShzdHJ1Y3Qgc2hhc2hfZGVzYyAqZGVzYywgY29uc3QgdTggKmRhdGEsCgkJCQl1bnNpZ25lZCBpbnQgbGVuLCB1bnNpZ25lZCBpbnQgcGFydGlhbCkKewoJc3RydWN0IHNoYTI1Nl9zdGF0ZSAqc2N0eCA9IHNoYXNoX2Rlc2NfY3R4KGRlc2MpOwoJdW5zaWduZWQgaW50IGRvbmUgPSAwOwoKCXNjdHgtPmNvdW50ICs9IGxlbjsKCglpZiAocGFydGlhbCkgewoJCWRvbmUgPSBTSEEyNTZfQkxPQ0tfU0laRSAtIHBhcnRpYWw7CgkJbWVtY3B5KHNjdHgtPmJ1ZiArIHBhcnRpYWwsIGRhdGEsIGRvbmUpOwoJCXNoYTI1Nl9ibG9ja19kYXRhX29yZGVyX25lb24oc2N0eC0+c3RhdGUsIHNjdHgtPmJ1ZiwgMSk7Cgl9CgoJaWYgKGxlbiAtIGRvbmUgPj0gU0hBMjU2X0JMT0NLX1NJWkUpIHsKCQljb25zdCB1bnNpZ25lZCBpbnQgcm91bmRzID0gKGxlbiAtIGRvbmUpIC8gU0hBMjU2X0JMT0NLX1NJWkU7CgoJCXNoYTI1Nl9ibG9ja19kYXRhX29yZGVyX25lb24oc2N0eC0+c3RhdGUsIGRhdGEgKyBkb25lLCByb3VuZHMpOwoJCWRvbmUgKz0gcm91bmRzICogU0hBMjU2X0JMT0NLX1NJWkU7Cgl9CgoJbWVtY3B5KHNjdHgtPmJ1ZiwgZGF0YSArIGRvbmUsIGxlbiAtIGRvbmUpOwoKCXJldHVybiAwOwp9CgpzdGF0aWMgaW50IHNoYTI1Nl9uZW9uX3VwZGF0ZShzdHJ1Y3Qgc2hhc2hfZGVzYyAqZGVzYywgY29uc3QgdTggKmRhdGEsCgkJCSAgICAgIHVuc2lnbmVkIGludCBsZW4pCnsKCXN0cnVjdCBzaGEyNTZfc3RhdGUgKnNjdHggPSBzaGFzaF9kZXNjX2N0eChkZXNjKTsKCXVuc2lnbmVkIGludCBwYXJ0aWFsID0gc2N0eC0+Y291bnQgJSBTSEEyNTZfQkxPQ0tfU0laRTsKCWludCByZXM7CgoJLyogSGFuZGxlIHRoZSBmYXN0IGNhc2UgcmlnaHQgaGVyZSAqLwoJaWYgKHBhcnRpYWwgKyBsZW4gPCBTSEEyNTZfQkxPQ0tfU0laRSkgewoJCXNjdHgtPmNvdW50ICs9IGxlbjsKCQltZW1jcHkoc2N0eC0+YnVmICsgcGFydGlhbCwgZGF0YSwgbGVuKTsKCgkJcmV0dXJuIDA7Cgl9CgoJaWYgKCFtYXlfdXNlX3NpbWQoKSkgewoJCXJlcyA9IF9fc2hhMjU2X3VwZGF0ZShkZXNjLCBkYXRhLCBsZW4sIHBhcnRpYWwpOwoJfSBlbHNlIHsKCQlrZXJuZWxfbmVvbl9iZWdpbigpOwoJCXJlcyA9IF9fc2hhMjU2X25lb25fdXBkYXRlKGRlc2MsIGRhdGEsIGxlbiwgcGFydGlhbCk7CgkJa2VybmVsX25lb25fZW5kKCk7Cgl9CgoJcmV0dXJuIHJlczsKfQoKLyogQWRkIHBhZGRpbmcgYW5kIHJldHVybiB0aGUgbWVzc2FnZSBkaWdlc3QuICovCnN0YXRpYyBpbnQgc2hhMjU2X25lb25fZmluYWwoc3RydWN0IHNoYXNoX2Rlc2MgKmRlc2MsIHU4ICpvdXQpCnsKCXN0cnVjdCBzaGEyNTZfc3RhdGUgKnNjdHggPSBzaGFzaF9kZXNjX2N0eChkZXNjKTsKCXVuc2lnbmVkIGludCBpLCBpbmRleCwgcGFkbGVuOwoJX19iZTMyICpkc3QgPSAoX19iZTMyICopb3V0OwoJX19iZTY0IGJpdHM7CglzdGF0aWMgY29uc3QgdTggcGFkZGluZ1tTSEEyNTZfQkxPQ0tfU0laRV0gPSB7IDB4ODAsIH07CgoJLyogc2F2ZSBudW1iZXIgb2YgYml0cyAqLwoJYml0cyA9IGNwdV90b19iZTY0KHNjdHgtPmNvdW50IDw8IDMpOwoKCS8qIFBhZCBvdXQgdG8gNTYgbW9kIDY0IGFuZCBhcHBlbmQgbGVuZ3RoICovCglpbmRleCA9IHNjdHgtPmNvdW50ICUgU0hBMjU2X0JMT0NLX1NJWkU7CglwYWRsZW4gPSAoaW5kZXggPCA1NikgPyAoNTYgLSBpbmRleCkgOiAoKFNIQTI1Nl9CTE9DS19TSVpFKzU2KS1pbmRleCk7CgoJaWYgKCFtYXlfdXNlX3NpbWQoKSkgewoJCXNoYTI1Nl91cGRhdGUoZGVzYywgcGFkZGluZywgcGFkbGVuKTsKCQlzaGEyNTZfdXBkYXRlKGRlc2MsIChjb25zdCB1OCAqKSZiaXRzLCBzaXplb2YoYml0cykpOwoJfSBlbHNlIHsKCQlrZXJuZWxfbmVvbl9iZWdpbigpOwoJCS8qIFdlIG5lZWQgdG8gZmlsbCBhIHdob2xlIGJsb2NrIGZvciBfX3NoYTI1Nl9uZW9uX3VwZGF0ZSgpICovCgkJaWYgKHBhZGxlbiA8PSA1NikgewoJCQlzY3R4LT5jb3VudCArPSBwYWRsZW47CgkJCW1lbWNweShzY3R4LT5idWYgKyBpbmRleCwgcGFkZGluZywgcGFkbGVuKTsKCQl9IGVsc2UgewoJCQlfX3NoYTI1Nl9uZW9uX3VwZGF0ZShkZXNjLCBwYWRkaW5nLCBwYWRsZW4sIGluZGV4KTsKCQl9CgkJX19zaGEyNTZfbmVvbl91cGRhdGUoZGVzYywgKGNvbnN0IHU4ICopJmJpdHMsCgkJCQkJc2l6ZW9mKGJpdHMpLCA1Nik7CgkJa2VybmVsX25lb25fZW5kKCk7Cgl9CgoJLyogU3RvcmUgc3RhdGUgaW4gZGlnZXN0ICovCglmb3IgKGkgPSAwOyBpIDwgODsgaSsrKQoJCWRzdFtpXSA9IGNwdV90b19iZTMyKHNjdHgtPnN0YXRlW2ldKTsKCgkvKiBXaXBlIGNvbnRleHQgKi8KCW1lbXplcm9fZXhwbGljaXQoc2N0eCwgc2l6ZW9mKCpzY3R4KSk7CgoJcmV0dXJuIDA7Cn0KCnN0YXRpYyBpbnQgc2hhMjI0X25lb25fZmluYWwoc3RydWN0IHNoYXNoX2Rlc2MgKmRlc2MsIHU4ICpvdXQpCnsKCXU4IERbU0hBMjU2X0RJR0VTVF9TSVpFXTsKCglzaGEyNTZfbmVvbl9maW5hbChkZXNjLCBEKTsKCgltZW1jcHkob3V0LCBELCBTSEEyMjRfRElHRVNUX1NJWkUpOwoJbWVtemVyb19leHBsaWNpdChELCBTSEEyNTZfRElHRVNUX1NJWkUpOwoKCXJldHVybiAwOwp9CgpzdHJ1Y3Qgc2hhc2hfYWxnIHNoYTI1Nl9uZW9uX2FsZ3NbXSA9IHsgewoJLmRpZ2VzdHNpemUJPQlTSEEyNTZfRElHRVNUX1NJWkUsCgkuaW5pdAkJPQlzaGEyNTZfaW5pdCwKCS51cGRhdGUJCT0Jc2hhMjU2X25lb25fdXBkYXRlLAoJLmZpbmFsCQk9CXNoYTI1Nl9uZW9uX2ZpbmFsLAoJLmV4cG9ydAkJPQlzaGEyNTZfZXhwb3J0LAoJLmltcG9ydAkJPQlzaGEyNTZfaW1wb3J0LAoJLmRlc2NzaXplCT0Jc2l6ZW9mKHN0cnVjdCBzaGEyNTZfc3RhdGUpLAoJLnN0YXRlc2l6ZQk9CXNpemVvZihzdHJ1Y3Qgc2hhMjU2X3N0YXRlKSwKCS5iYXNlCQk9CXsKCQkuY3JhX25hbWUJPQkic2hhMjU2IiwKCQkuY3JhX2RyaXZlcl9uYW1lID0JInNoYTI1Ni1uZW9uIiwKCQkuY3JhX3ByaW9yaXR5CT0JMjUwLAoJCS5jcmFfZmxhZ3MJPQlDUllQVE9fQUxHX1RZUEVfU0hBU0gsCgkJLmNyYV9ibG9ja3NpemUJPQlTSEEyNTZfQkxPQ0tfU0laRSwKCQkuY3JhX21vZHVsZQk9CVRISVNfTU9EVUxFLAoJfQp9LCB7CgkuZGlnZXN0c2l6ZQk9CVNIQTIyNF9ESUdFU1RfU0laRSwKCS5pbml0CQk9CXNoYTIyNF9pbml0LAoJLnVwZGF0ZQkJPQlzaGEyNTZfbmVvbl91cGRhdGUsCgkuZmluYWwJCT0Jc2hhMjI0X25lb25fZmluYWwsCgkuZXhwb3J0CQk9CXNoYTI1Nl9leHBvcnQsCgkuaW1wb3J0CQk9CXNoYTI1Nl9pbXBvcnQsCgkuZGVzY3NpemUJPQlzaXplb2Yoc3RydWN0IHNoYTI1Nl9zdGF0ZSksCgkuc3RhdGVzaXplCT0Jc2l6ZW9mKHN0cnVjdCBzaGEyNTZfc3RhdGUpLAoJLmJhc2UJCT0JewoJCS5jcmFfbmFtZQk9CSJzaGEyMjQiLAoJCS5jcmFfZHJpdmVyX25hbWUgPQkic2hhMjI0LW5lb24iLAoJCS5jcmFfcHJpb3JpdHkJPQkyNTAsCgkJLmNyYV9mbGFncwk9CUNSWVBUT19BTEdfVFlQRV9TSEFTSCwKCQkuY3JhX2Jsb2Nrc2l6ZQk9CVNIQTIyNF9CTE9DS19TSVpFLAoJCS5jcmFfbW9kdWxlCT0JVEhJU19NT0RVTEUsCgl9Cn0gfTsK