LyoKICogR2x1ZSBjb2RlIGZvciB0aGUgU0hBMjU2IFNlY3VyZSBIYXNoIEFsZ29yaXRobSBhc3NlbWJseSBpbXBsZW1lbnRhdGlvbgogKiB1c2luZyBvcHRpbWl6ZWQgQVJNIGFzc2VtYmxlciBhbmQgTkVPTiBpbnN0cnVjdGlvbnMuCiAqCiAqIENvcHlyaWdodCCpIDIwMTUgR29vZ2xlIEluYy4KICoKICogVGhpcyBmaWxlIGlzIGJhc2VkIG9uIHNoYTI1Nl9zc3NlM19nbHVlLmM6CiAqICAgQ29weXJpZ2h0IChDKSAyMDEzIEludGVsIENvcnBvcmF0aW9uCiAqICAgQXV0aG9yOiBUaW0gQ2hlbiA8dGltLmMuY2hlbkBsaW51eC5pbnRlbC5jb20+CiAqCiAqIFRoaXMgcHJvZ3JhbSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0CiAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlCiAqIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlciB2ZXJzaW9uIDIgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikKICogYW55IGxhdGVyIHZlcnNpb24uCiAqCiAqLwoKI2luY2x1ZGUgPGNyeXB0by9pbnRlcm5hbC9oYXNoLmg+CiNpbmNsdWRlIDxsaW51eC9jcnlwdG8uaD4KI2luY2x1ZGUgPGxpbnV4L2V4cG9ydC5oPgojaW5jbHVkZSA8bGludXgvaW5pdC5oPgojaW5jbHVkZSA8bGludXgvbW9kdWxlLmg+CiNpbmNsdWRlIDxsaW51eC9tbS5oPgojaW5jbHVkZSA8bGludXgvY3J5cHRvaGFzaC5oPgojaW5jbHVkZSA8bGludXgvdHlwZXMuaD4KI2luY2x1ZGUgPGxpbnV4L3N0cmluZy5oPgojaW5jbHVkZSA8Y3J5cHRvL3NoYS5oPgojaW5jbHVkZSA8YXNtL2J5dGVvcmRlci5oPgojaW5jbHVkZSA8YXNtL3NpbWQuaD4KI2luY2x1ZGUgPGFzbS9uZW9uLmg+CiNpbmNsdWRlICJzaGEyNTZfZ2x1ZS5oIgoKYXNtbGlua2FnZSB2b2lkIHNoYTI1Nl9ibG9ja19kYXRhX29yZGVyKHUzMiAqZGlnZXN0LCBjb25zdCB2b2lkICpkYXRhLAoJCQkJICAgICAgdW5zaWduZWQgaW50IG51bV9ibGtzKTsKCgppbnQgc2hhMjU2X2luaXQoc3RydWN0IHNoYXNoX2Rlc2MgKmRlc2MpCnsKCXN0cnVjdCBzaGEyNTZfc3RhdGUgKnNjdHggPSBzaGFzaF9kZXNjX2N0eChkZXNjKTsKCglzY3R4LT5zdGF0ZVswXSA9IFNIQTI1Nl9IMDsKCXNjdHgtPnN0YXRlWzFdID0gU0hBMjU2X0gxOwoJc2N0eC0+c3RhdGVbMl0gPSBTSEEyNTZfSDI7CglzY3R4LT5zdGF0ZVszXSA9IFNIQTI1Nl9IMzsKCXNjdHgtPnN0YXRlWzRdID0gU0hBMjU2X0g0OwoJc2N0eC0+c3RhdGVbNV0gPSBTSEEyNTZfSDU7CglzY3R4LT5zdGF0ZVs2XSA9IFNIQTI1Nl9INjsKCXNjdHgtPnN0YXRlWzddID0gU0hBMjU2X0g3OwoJc2N0eC0+Y291bnQgPSAwOwoKCXJldHVybiAwOwp9CgppbnQgc2hhMjI0X2luaXQoc3RydWN0IHNoYXNoX2Rlc2MgKmRlc2MpCnsKCXN0cnVjdCBzaGEyNTZfc3RhdGUgKnNjdHggPSBzaGFzaF9kZXNjX2N0eChkZXNjKTsKCglzY3R4LT5zdGF0ZVswXSA9IFNIQTIyNF9IMDsKCXNjdHgtPnN0YXRlWzFdID0gU0hBMjI0X0gxOwoJc2N0eC0+c3RhdGVbMl0gPSBTSEEyMjRfSDI7CglzY3R4LT5zdGF0ZVszXSA9IFNIQTIyNF9IMzsKCXNjdHgtPnN0YXRlWzRdID0gU0hBMjI0X0g0OwoJc2N0eC0+c3RhdGVbNV0gPSBTSEEyMjRfSDU7CglzY3R4LT5zdGF0ZVs2XSA9IFNIQTIyNF9INjsKCXNjdHgtPnN0YXRlWzddID0gU0hBMjI0X0g3OwoJc2N0eC0+Y291bnQgPSAwOwoKCXJldHVybiAwOwp9CgppbnQgX19zaGEyNTZfdXBkYXRlKHN0cnVjdCBzaGFzaF9kZXNjICpkZXNjLCBjb25zdCB1OCAqZGF0YSwgdW5zaWduZWQgaW50IGxlbiwKCQkgICAgdW5zaWduZWQgaW50IHBhcnRpYWwpCnsKCXN0cnVjdCBzaGEyNTZfc3RhdGUgKnNjdHggPSBzaGFzaF9kZXNjX2N0eChkZXNjKTsKCXVuc2lnbmVkIGludCBkb25lID0gMDsKCglzY3R4LT5jb3VudCArPSBsZW47CgoJaWYgKHBhcnRpYWwpIHsKCQlkb25lID0gU0hBMjU2X0JMT0NLX1NJWkUgLSBwYXJ0aWFsOwoJCW1lbWNweShzY3R4LT5idWYgKyBwYXJ0aWFsLCBkYXRhLCBkb25lKTsKCQlzaGEyNTZfYmxvY2tfZGF0YV9vcmRlcihzY3R4LT5zdGF0ZSwgc2N0eC0+YnVmLCAxKTsKCX0KCglpZiAobGVuIC0gZG9uZSA+PSBTSEEyNTZfQkxPQ0tfU0laRSkgewoJCWNvbnN0IHVuc2lnbmVkIGludCByb3VuZHMgPSAobGVuIC0gZG9uZSkgLyBTSEEyNTZfQkxPQ0tfU0laRTsKCgkJc2hhMjU2X2Jsb2NrX2RhdGFfb3JkZXIoc2N0eC0+c3RhdGUsIGRhdGEgKyBkb25lLCByb3VuZHMpOwoJCWRvbmUgKz0gcm91bmRzICogU0hBMjU2X0JMT0NLX1NJWkU7Cgl9CgoJbWVtY3B5KHNjdHgtPmJ1ZiwgZGF0YSArIGRvbmUsIGxlbiAtIGRvbmUpOwoKCXJldHVybiAwOwp9CgppbnQgc2hhMjU2X3VwZGF0ZShzdHJ1Y3Qgc2hhc2hfZGVzYyAqZGVzYywgY29uc3QgdTggKmRhdGEsIHVuc2lnbmVkIGludCBsZW4pCnsKCXN0cnVjdCBzaGEyNTZfc3RhdGUgKnNjdHggPSBzaGFzaF9kZXNjX2N0eChkZXNjKTsKCXVuc2lnbmVkIGludCBwYXJ0aWFsID0gc2N0eC0+Y291bnQgJSBTSEEyNTZfQkxPQ0tfU0laRTsKCgkvKiBIYW5kbGUgdGhlIGZhc3QgY2FzZSByaWdodCBoZXJlICovCglpZiAocGFydGlhbCArIGxlbiA8IFNIQTI1Nl9CTE9DS19TSVpFKSB7CgkJc2N0eC0+Y291bnQgKz0gbGVuOwoJCW1lbWNweShzY3R4LT5idWYgKyBwYXJ0aWFsLCBkYXRhLCBsZW4pOwoKCQlyZXR1cm4gMDsKCX0KCglyZXR1cm4gX19zaGEyNTZfdXBkYXRlKGRlc2MsIGRhdGEsIGxlbiwgcGFydGlhbCk7Cn0KCi8qIEFkZCBwYWRkaW5nIGFuZCByZXR1cm4gdGhlIG1lc3NhZ2UgZGlnZXN0LiAqLwpzdGF0aWMgaW50IHNoYTI1Nl9maW5hbChzdHJ1Y3Qgc2hhc2hfZGVzYyAqZGVzYywgdTggKm91dCkKewoJc3RydWN0IHNoYTI1Nl9zdGF0ZSAqc2N0eCA9IHNoYXNoX2Rlc2NfY3R4KGRlc2MpOwoJdW5zaWduZWQgaW50IGksIGluZGV4LCBwYWRsZW47CglfX2JlMzIgKmRzdCA9IChfX2JlMzIgKilvdXQ7CglfX2JlNjQgYml0czsKCXN0YXRpYyBjb25zdCB1OCBwYWRkaW5nW1NIQTI1Nl9CTE9DS19TSVpFXSA9IHsgMHg4MCwgfTsKCgkvKiBzYXZlIG51bWJlciBvZiBiaXRzICovCgliaXRzID0gY3B1X3RvX2JlNjQoc2N0eC0+Y291bnQgPDwgMyk7CgoJLyogUGFkIG91dCB0byA1NiBtb2QgNjQgYW5kIGFwcGVuZCBsZW5ndGggKi8KCWluZGV4ID0gc2N0eC0+Y291bnQgJSBTSEEyNTZfQkxPQ0tfU0laRTsKCXBhZGxlbiA9IChpbmRleCA8IDU2KSA/ICg1NiAtIGluZGV4KSA6ICgoU0hBMjU2X0JMT0NLX1NJWkUrNTYpLWluZGV4KTsKCgkvKiBXZSBuZWVkIHRvIGZpbGwgYSB3aG9sZSBibG9jayBmb3IgX19zaGEyNTZfdXBkYXRlICovCglpZiAocGFkbGVuIDw9IDU2KSB7CgkJc2N0eC0+Y291bnQgKz0gcGFkbGVuOwoJCW1lbWNweShzY3R4LT5idWYgKyBpbmRleCwgcGFkZGluZywgcGFkbGVuKTsKCX0gZWxzZSB7CgkJX19zaGEyNTZfdXBkYXRlKGRlc2MsIHBhZGRpbmcsIHBhZGxlbiwgaW5kZXgpOwoJfQoJX19zaGEyNTZfdXBkYXRlKGRlc2MsIChjb25zdCB1OCAqKSZiaXRzLCBzaXplb2YoYml0cyksIDU2KTsKCgkvKiBTdG9yZSBzdGF0ZSBpbiBkaWdlc3QgKi8KCWZvciAoaSA9IDA7IGkgPCA4OyBpKyspCgkJZHN0W2ldID0gY3B1X3RvX2JlMzIoc2N0eC0+c3RhdGVbaV0pOwoKCS8qIFdpcGUgY29udGV4dCAqLwoJbWVtc2V0KHNjdHgsIDAsIHNpemVvZigqc2N0eCkpOwoKCXJldHVybiAwOwp9CgpzdGF0aWMgaW50IHNoYTIyNF9maW5hbChzdHJ1Y3Qgc2hhc2hfZGVzYyAqZGVzYywgdTggKm91dCkKewoJdTggRFtTSEEyNTZfRElHRVNUX1NJWkVdOwoKCXNoYTI1Nl9maW5hbChkZXNjLCBEKTsKCgltZW1jcHkob3V0LCBELCBTSEEyMjRfRElHRVNUX1NJWkUpOwoJbWVtemVyb19leHBsaWNpdChELCBTSEEyNTZfRElHRVNUX1NJWkUpOwoKCXJldHVybiAwOwp9CgppbnQgc2hhMjU2X2V4cG9ydChzdHJ1Y3Qgc2hhc2hfZGVzYyAqZGVzYywgdm9pZCAqb3V0KQp7CglzdHJ1Y3Qgc2hhMjU2X3N0YXRlICpzY3R4ID0gc2hhc2hfZGVzY19jdHgoZGVzYyk7CgoJbWVtY3B5KG91dCwgc2N0eCwgc2l6ZW9mKCpzY3R4KSk7CgoJcmV0dXJuIDA7Cn0KCmludCBzaGEyNTZfaW1wb3J0KHN0cnVjdCBzaGFzaF9kZXNjICpkZXNjLCBjb25zdCB2b2lkICppbikKewoJc3RydWN0IHNoYTI1Nl9zdGF0ZSAqc2N0eCA9IHNoYXNoX2Rlc2NfY3R4KGRlc2MpOwoKCW1lbWNweShzY3R4LCBpbiwgc2l6ZW9mKCpzY3R4KSk7CgoJcmV0dXJuIDA7Cn0KCnN0YXRpYyBzdHJ1Y3Qgc2hhc2hfYWxnIGFsZ3NbXSA9IHsgewoJLmRpZ2VzdHNpemUJPQlTSEEyNTZfRElHRVNUX1NJWkUsCgkuaW5pdAkJPQlzaGEyNTZfaW5pdCwKCS51cGRhdGUJCT0Jc2hhMjU2X3VwZGF0ZSwKCS5maW5hbAkJPQlzaGEyNTZfZmluYWwsCgkuZXhwb3J0CQk9CXNoYTI1Nl9leHBvcnQsCgkuaW1wb3J0CQk9CXNoYTI1Nl9pbXBvcnQsCgkuZGVzY3NpemUJPQlzaXplb2Yoc3RydWN0IHNoYTI1Nl9zdGF0ZSksCgkuc3RhdGVzaXplCT0Jc2l6ZW9mKHN0cnVjdCBzaGEyNTZfc3RhdGUpLAoJLmJhc2UJCT0JewoJCS5jcmFfbmFtZQk9CSJzaGEyNTYiLAoJCS5jcmFfZHJpdmVyX25hbWUgPQkic2hhMjU2LWFzbSIsCgkJLmNyYV9wcmlvcml0eQk9CTE1MCwKCQkuY3JhX2ZsYWdzCT0JQ1JZUFRPX0FMR19UWVBFX1NIQVNILAoJCS5jcmFfYmxvY2tzaXplCT0JU0hBMjU2X0JMT0NLX1NJWkUsCgkJLmNyYV9tb2R1bGUJPQlUSElTX01PRFVMRSwKCX0KfSwgewoJLmRpZ2VzdHNpemUJPQlTSEEyMjRfRElHRVNUX1NJWkUsCgkuaW5pdAkJPQlzaGEyMjRfaW5pdCwKCS51cGRhdGUJCT0Jc2hhMjU2X3VwZGF0ZSwKCS5maW5hbAkJPQlzaGEyMjRfZmluYWwsCgkuZXhwb3J0CQk9CXNoYTI1Nl9leHBvcnQsCgkuaW1wb3J0CQk9CXNoYTI1Nl9pbXBvcnQsCgkuZGVzY3NpemUJPQlzaXplb2Yoc3RydWN0IHNoYTI1Nl9zdGF0ZSksCgkuc3RhdGVzaXplCT0Jc2l6ZW9mKHN0cnVjdCBzaGEyNTZfc3RhdGUpLAoJLmJhc2UJCT0JewoJCS5jcmFfbmFtZQk9CSJzaGEyMjQiLAoJCS5jcmFfZHJpdmVyX25hbWUgPQkic2hhMjI0LWFzbSIsCgkJLmNyYV9wcmlvcml0eQk9CTE1MCwKCQkuY3JhX2ZsYWdzCT0JQ1JZUFRPX0FMR19UWVBFX1NIQVNILAoJCS5jcmFfYmxvY2tzaXplCT0JU0hBMjI0X0JMT0NLX1NJWkUsCgkJLmNyYV9tb2R1bGUJPQlUSElTX01PRFVMRSwKCX0KfSB9OwoKc3RhdGljIGludCBfX2luaXQgc2hhMjU2X21vZF9pbml0KHZvaWQpCnsKCWludCByZXMgPSBjcnlwdG9fcmVnaXN0ZXJfc2hhc2hlcyhhbGdzLCBBUlJBWV9TSVpFKGFsZ3MpKTsKCglpZiAocmVzIDwgMCkKCQlyZXR1cm4gcmVzOwoKCWlmIChJU19FTkFCTEVEKENPTkZJR19LRVJORUxfTU9ERV9ORU9OKSAmJiBjcHVfaGFzX25lb24oKSkgewoJCXJlcyA9IGNyeXB0b19yZWdpc3Rlcl9zaGFzaGVzKHNoYTI1Nl9uZW9uX2FsZ3MsCgkJCQkJICAgICAgQVJSQVlfU0laRShzaGEyNTZfbmVvbl9hbGdzKSk7CgoJCWlmIChyZXMgPCAwKQoJCQljcnlwdG9fdW5yZWdpc3Rlcl9zaGFzaGVzKGFsZ3MsIEFSUkFZX1NJWkUoYWxncykpOwoJfQoKCXJldHVybiByZXM7Cn0KCnN0YXRpYyB2b2lkIF9fZXhpdCBzaGEyNTZfbW9kX2Zpbmkodm9pZCkKewoJY3J5cHRvX3VucmVnaXN0ZXJfc2hhc2hlcyhhbGdzLCBBUlJBWV9TSVpFKGFsZ3MpKTsKCglpZiAoSVNfRU5BQkxFRChDT05GSUdfS0VSTkVMX01PREVfTkVPTikgJiYgY3B1X2hhc19uZW9uKCkpCgkJY3J5cHRvX3VucmVnaXN0ZXJfc2hhc2hlcyhzaGEyNTZfbmVvbl9hbGdzLAoJCQkJCSAgQVJSQVlfU0laRShzaGEyNTZfbmVvbl9hbGdzKSk7Cn0KCm1vZHVsZV9pbml0KHNoYTI1Nl9tb2RfaW5pdCk7Cm1vZHVsZV9leGl0KHNoYTI1Nl9tb2RfZmluaSk7CgpNT0RVTEVfTElDRU5TRSgiR1BMIik7Ck1PRFVMRV9ERVNDUklQVElPTigiU0hBMjU2IFNlY3VyZSBIYXNoIEFsZ29yaXRobSAoQVJNKSwgaW5jbHVkaW5nIE5FT04iKTsKCk1PRFVMRV9BTElBUygic2hhMjU2Iik7Cg==