LyoKICogU2NhdHRlcmxpc3QgQ3J5cHRvZ3JhcGhpYyBBUEkuCiAqCiAqIENvcHlyaWdodCAoYykgMjAwMiBKYW1lcyBNb3JyaXMgPGptb3JyaXNAaW50ZXJjb2RlLmNvbS5hdT4KICogQ29weXJpZ2h0IChjKSAyMDAyIERhdmlkIFMuIE1pbGxlciAoZGF2ZW1AcmVkaGF0LmNvbSkKICogQ29weXJpZ2h0IChjKSAyMDA1IEhlcmJlcnQgWHUgPGhlcmJlcnRAZ29uZG9yLmFwYW5hLm9yZy5hdT4KICoKICogUG9ydGlvbnMgZGVyaXZlZCBmcm9tIENyeXB0b2FwaSwgYnkgQWxleGFuZGVyIEtqZWxkYWFzIDxhc3RvckBmYXN0Lm5vPgogKiBhbmQgTmV0dGxlLCBieSBOaWVscyBN9mxsZXIuCiAqCiAqIFRoaXMgcHJvZ3JhbSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0CiAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlCiAqIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlciB2ZXJzaW9uIDIgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgCiAqIGFueSBsYXRlciB2ZXJzaW9uLgogKgogKi8KCiNpbmNsdWRlIDxsaW51eC9lcnIuaD4KI2luY2x1ZGUgPGxpbnV4L2Vycm5vLmg+CiNpbmNsdWRlIDxsaW51eC9rZXJuZWwuaD4KI2luY2x1ZGUgPGxpbnV4L2ttb2QuaD4KI2luY2x1ZGUgPGxpbnV4L21vZHVsZS5oPgojaW5jbHVkZSA8bGludXgvcGFyYW0uaD4KI2luY2x1ZGUgPGxpbnV4L3NjaGVkLmg+CiNpbmNsdWRlIDxsaW51eC9zbGFiLmg+CiNpbmNsdWRlIDxsaW51eC9zdHJpbmcuaD4KI2luY2x1ZGUgImludGVybmFsLmgiCgpMSVNUX0hFQUQoY3J5cHRvX2FsZ19saXN0KTsKRVhQT1JUX1NZTUJPTF9HUEwoY3J5cHRvX2FsZ19saXN0KTsKREVDTEFSRV9SV1NFTShjcnlwdG9fYWxnX3NlbSk7CkVYUE9SVF9TWU1CT0xfR1BMKGNyeXB0b19hbGdfc2VtKTsKCkJMT0NLSU5HX05PVElGSUVSX0hFQUQoY3J5cHRvX2NoYWluKTsKRVhQT1JUX1NZTUJPTF9HUEwoY3J5cHRvX2NoYWluKTsKCnN0YXRpYyBpbmxpbmUgc3RydWN0IGNyeXB0b19hbGcgKmNyeXB0b19hbGdfZ2V0KHN0cnVjdCBjcnlwdG9fYWxnICphbGcpCnsKCWF0b21pY19pbmMoJmFsZy0+Y3JhX3JlZmNudCk7CglyZXR1cm4gYWxnOwp9CgpzdHJ1Y3QgY3J5cHRvX2FsZyAqY3J5cHRvX21vZF9nZXQoc3RydWN0IGNyeXB0b19hbGcgKmFsZykKewoJcmV0dXJuIHRyeV9tb2R1bGVfZ2V0KGFsZy0+Y3JhX21vZHVsZSkgPyBjcnlwdG9fYWxnX2dldChhbGcpIDogTlVMTDsKfQpFWFBPUlRfU1lNQk9MX0dQTChjcnlwdG9fbW9kX2dldCk7Cgp2b2lkIGNyeXB0b19tb2RfcHV0KHN0cnVjdCBjcnlwdG9fYWxnICphbGcpCnsKCXN0cnVjdCBtb2R1bGUgKm1vZHVsZSA9IGFsZy0+Y3JhX21vZHVsZTsKCgljcnlwdG9fYWxnX3B1dChhbGcpOwoJbW9kdWxlX3B1dChtb2R1bGUpOwp9CkVYUE9SVF9TWU1CT0xfR1BMKGNyeXB0b19tb2RfcHV0KTsKCnN0cnVjdCBjcnlwdG9fYWxnICpfX2NyeXB0b19hbGdfbG9va3VwKGNvbnN0IGNoYXIgKm5hbWUsIHUzMiB0eXBlLCB1MzIgbWFzaykKewoJc3RydWN0IGNyeXB0b19hbGcgKnEsICphbGcgPSBOVUxMOwoJaW50IGJlc3QgPSAtMjsKCglsaXN0X2Zvcl9lYWNoX2VudHJ5KHEsICZjcnlwdG9fYWxnX2xpc3QsIGNyYV9saXN0KSB7CgkJaW50IGV4YWN0LCBmdXp6eTsKCgkJaWYgKGNyeXB0b19pc19tb3JpYnVuZChxKSkKCQkJY29udGludWU7CgoJCWlmICgocS0+Y3JhX2ZsYWdzIF4gdHlwZSkgJiBtYXNrKQoJCQljb250aW51ZTsKCgkJaWYgKGNyeXB0b19pc19sYXJ2YWwocSkgJiYKCQkgICAgKChzdHJ1Y3QgY3J5cHRvX2xhcnZhbCAqKXEpLT5tYXNrICE9IG1hc2spCgkJCWNvbnRpbnVlOwoKCQlleGFjdCA9ICFzdHJjbXAocS0+Y3JhX2RyaXZlcl9uYW1lLCBuYW1lKTsKCQlmdXp6eSA9ICFzdHJjbXAocS0+Y3JhX25hbWUsIG5hbWUpOwoJCWlmICghZXhhY3QgJiYgIShmdXp6eSAmJiBxLT5jcmFfcHJpb3JpdHkgPiBiZXN0KSkKCQkJY29udGludWU7CgoJCWlmICh1bmxpa2VseSghY3J5cHRvX21vZF9nZXQocSkpKQoJCQljb250aW51ZTsKCgkJYmVzdCA9IHEtPmNyYV9wcmlvcml0eTsKCQlpZiAoYWxnKQoJCQljcnlwdG9fbW9kX3B1dChhbGcpOwoJCWFsZyA9IHE7CgoJCWlmIChleGFjdCkKCQkJYnJlYWs7Cgl9CgoJcmV0dXJuIGFsZzsKfQpFWFBPUlRfU1lNQk9MX0dQTChfX2NyeXB0b19hbGdfbG9va3VwKTsKCnN0YXRpYyB2b2lkIGNyeXB0b19sYXJ2YWxfZGVzdHJveShzdHJ1Y3QgY3J5cHRvX2FsZyAqYWxnKQp7CglzdHJ1Y3QgY3J5cHRvX2xhcnZhbCAqbGFydmFsID0gKHZvaWQgKilhbGc7CgoJQlVHX09OKCFjcnlwdG9faXNfbGFydmFsKGFsZykpOwoJaWYgKGxhcnZhbC0+YWR1bHQpCgkJY3J5cHRvX21vZF9wdXQobGFydmFsLT5hZHVsdCk7CglrZnJlZShsYXJ2YWwpOwp9CgpzdGF0aWMgc3RydWN0IGNyeXB0b19hbGcgKmNyeXB0b19sYXJ2YWxfYWxsb2MoY29uc3QgY2hhciAqbmFtZSwgdTMyIHR5cGUsCgkJCQkJICAgICAgdTMyIG1hc2spCnsKCXN0cnVjdCBjcnlwdG9fYWxnICphbGc7CglzdHJ1Y3QgY3J5cHRvX2xhcnZhbCAqbGFydmFsOwoKCWxhcnZhbCA9IGt6YWxsb2Moc2l6ZW9mKCpsYXJ2YWwpLCBHRlBfS0VSTkVMKTsKCWlmICghbGFydmFsKQoJCXJldHVybiBFUlJfUFRSKC1FTk9NRU0pOwoKCWxhcnZhbC0+bWFzayA9IG1hc2s7CglsYXJ2YWwtPmFsZy5jcmFfZmxhZ3MgPSBDUllQVE9fQUxHX0xBUlZBTCB8IHR5cGU7CglsYXJ2YWwtPmFsZy5jcmFfcHJpb3JpdHkgPSAtMTsKCWxhcnZhbC0+YWxnLmNyYV9kZXN0cm95ID0gY3J5cHRvX2xhcnZhbF9kZXN0cm95OwoKCWF0b21pY19zZXQoJmxhcnZhbC0+YWxnLmNyYV9yZWZjbnQsIDIpOwoJc3RybGNweShsYXJ2YWwtPmFsZy5jcmFfbmFtZSwgbmFtZSwgQ1JZUFRPX01BWF9BTEdfTkFNRSk7Cglpbml0X2NvbXBsZXRpb24oJmxhcnZhbC0+Y29tcGxldGlvbik7CgoJZG93bl93cml0ZSgmY3J5cHRvX2FsZ19zZW0pOwoJYWxnID0gX19jcnlwdG9fYWxnX2xvb2t1cChuYW1lLCB0eXBlLCBtYXNrKTsKCWlmICghYWxnKSB7CgkJYWxnID0gJmxhcnZhbC0+YWxnOwoJCWxpc3RfYWRkKCZhbGctPmNyYV9saXN0LCAmY3J5cHRvX2FsZ19saXN0KTsKCX0KCXVwX3dyaXRlKCZjcnlwdG9fYWxnX3NlbSk7CgoJaWYgKGFsZyAhPSAmbGFydmFsLT5hbGcpCgkJa2ZyZWUobGFydmFsKTsKCglyZXR1cm4gYWxnOwp9CgpzdGF0aWMgdm9pZCBjcnlwdG9fbGFydmFsX2tpbGwoc3RydWN0IGNyeXB0b19hbGcgKmFsZykKewoJc3RydWN0IGNyeXB0b19sYXJ2YWwgKmxhcnZhbCA9ICh2b2lkICopYWxnOwoKCWRvd25fd3JpdGUoJmNyeXB0b19hbGdfc2VtKTsKCWxpc3RfZGVsKCZhbGctPmNyYV9saXN0KTsKCXVwX3dyaXRlKCZjcnlwdG9fYWxnX3NlbSk7Cgljb21wbGV0ZV9hbGwoJmxhcnZhbC0+Y29tcGxldGlvbik7CgljcnlwdG9fYWxnX3B1dChhbGcpOwp9CgpzdGF0aWMgc3RydWN0IGNyeXB0b19hbGcgKmNyeXB0b19sYXJ2YWxfd2FpdChzdHJ1Y3QgY3J5cHRvX2FsZyAqYWxnKQp7CglzdHJ1Y3QgY3J5cHRvX2xhcnZhbCAqbGFydmFsID0gKHZvaWQgKilhbGc7CgoJd2FpdF9mb3JfY29tcGxldGlvbl9pbnRlcnJ1cHRpYmxlX3RpbWVvdXQoJmxhcnZhbC0+Y29tcGxldGlvbiwgNjAgKiBIWik7CglhbGcgPSBsYXJ2YWwtPmFkdWx0OwoJaWYgKGFsZykgewoJCWlmICghY3J5cHRvX21vZF9nZXQoYWxnKSkKCQkJYWxnID0gRVJSX1BUUigtRUFHQUlOKTsKCX0gZWxzZQoJCWFsZyA9IEVSUl9QVFIoLUVOT0VOVCk7CgljcnlwdG9fbW9kX3B1dCgmbGFydmFsLT5hbGcpOwoKCXJldHVybiBhbGc7Cn0KCnN0YXRpYyBzdHJ1Y3QgY3J5cHRvX2FsZyAqY3J5cHRvX2FsZ19sb29rdXAoY29uc3QgY2hhciAqbmFtZSwgdTMyIHR5cGUsCgkJCQkJICAgIHUzMiBtYXNrKQp7CglzdHJ1Y3QgY3J5cHRvX2FsZyAqYWxnOwoKCWRvd25fcmVhZCgmY3J5cHRvX2FsZ19zZW0pOwoJYWxnID0gX19jcnlwdG9fYWxnX2xvb2t1cChuYW1lLCB0eXBlLCBtYXNrKTsKCXVwX3JlYWQoJmNyeXB0b19hbGdfc2VtKTsKCglyZXR1cm4gYWxnOwp9CgpzdHJ1Y3QgY3J5cHRvX2FsZyAqY3J5cHRvX2FsZ19tb2RfbG9va3VwKGNvbnN0IGNoYXIgKm5hbWUsIHUzMiB0eXBlLCB1MzIgbWFzaykKewoJc3RydWN0IGNyeXB0b19hbGcgKmFsZzsKCXN0cnVjdCBjcnlwdG9fYWxnICpsYXJ2YWw7CglpbnQgb2s7CgoJaWYgKCFuYW1lKQoJCXJldHVybiBFUlJfUFRSKC1FTk9FTlQpOwoKCW1hc2sgJj0gfihDUllQVE9fQUxHX0xBUlZBTCB8IENSWVBUT19BTEdfREVBRCk7Cgl0eXBlICY9IG1hc2s7CgoJYWxnID0gdHJ5X3RoZW5fcmVxdWVzdF9tb2R1bGUoY3J5cHRvX2FsZ19sb29rdXAobmFtZSwgdHlwZSwgbWFzayksCgkJCQkgICAgICBuYW1lKTsKCWlmIChhbGcpCgkJcmV0dXJuIGNyeXB0b19pc19sYXJ2YWwoYWxnKSA/IGNyeXB0b19sYXJ2YWxfd2FpdChhbGcpIDogYWxnOwoKCWxhcnZhbCA9IGNyeXB0b19sYXJ2YWxfYWxsb2MobmFtZSwgdHlwZSwgbWFzayk7CglpZiAoSVNfRVJSKGxhcnZhbCkgfHwgIWNyeXB0b19pc19sYXJ2YWwobGFydmFsKSkKCQlyZXR1cm4gbGFydmFsOwoKCW9rID0gY3J5cHRvX25vdGlmeShDUllQVE9fTVNHX0FMR19SRVFVRVNULCBsYXJ2YWwpOwoJaWYgKG9rID09IE5PVElGWV9ET05FKSB7CgkJcmVxdWVzdF9tb2R1bGUoImNyeXB0b21nciIpOwoJCW9rID0gY3J5cHRvX25vdGlmeShDUllQVE9fTVNHX0FMR19SRVFVRVNULCBsYXJ2YWwpOwoJfQoKCWlmIChvayA9PSBOT1RJRllfU1RPUCkKCQlhbGcgPSBjcnlwdG9fbGFydmFsX3dhaXQobGFydmFsKTsKCWVsc2UgewoJCWNyeXB0b19tb2RfcHV0KGxhcnZhbCk7CgkJYWxnID0gRVJSX1BUUigtRU5PRU5UKTsKCX0KCWNyeXB0b19sYXJ2YWxfa2lsbChsYXJ2YWwpOwoJcmV0dXJuIGFsZzsKfQpFWFBPUlRfU1lNQk9MX0dQTChjcnlwdG9fYWxnX21vZF9sb29rdXApOwoKc3RhdGljIGludCBjcnlwdG9faW5pdF9vcHMoc3RydWN0IGNyeXB0b190Zm0gKnRmbSwgdTMyIHR5cGUsIHUzMiBtYXNrKQp7Cgljb25zdCBzdHJ1Y3QgY3J5cHRvX3R5cGUgKnR5cGVfb2JqID0gdGZtLT5fX2NydF9hbGctPmNyYV90eXBlOwoKCWlmICh0eXBlX29iaikKCQlyZXR1cm4gdHlwZV9vYmotPmluaXQodGZtLCB0eXBlLCBtYXNrKTsKCglzd2l0Y2ggKGNyeXB0b190Zm1fYWxnX3R5cGUodGZtKSkgewoJY2FzZSBDUllQVE9fQUxHX1RZUEVfQ0lQSEVSOgoJCXJldHVybiBjcnlwdG9faW5pdF9jaXBoZXJfb3BzKHRmbSk7CgkJCgljYXNlIENSWVBUT19BTEdfVFlQRV9ESUdFU1Q6CgkJcmV0dXJuIGNyeXB0b19pbml0X2RpZ2VzdF9vcHModGZtKTsKCQkKCWNhc2UgQ1JZUFRPX0FMR19UWVBFX0NPTVBSRVNTOgoJCXJldHVybiBjcnlwdG9faW5pdF9jb21wcmVzc19vcHModGZtKTsKCQoJZGVmYXVsdDoKCQlicmVhazsKCX0KCQoJQlVHKCk7CglyZXR1cm4gLUVJTlZBTDsKfQoKc3RhdGljIHZvaWQgY3J5cHRvX2V4aXRfb3BzKHN0cnVjdCBjcnlwdG9fdGZtICp0Zm0pCnsKCWNvbnN0IHN0cnVjdCBjcnlwdG9fdHlwZSAqdHlwZSA9IHRmbS0+X19jcnRfYWxnLT5jcmFfdHlwZTsKCglpZiAodHlwZSkgewoJCWlmICh0eXBlLT5leGl0KQoJCQl0eXBlLT5leGl0KHRmbSk7CgkJcmV0dXJuOwoJfQoKCXN3aXRjaCAoY3J5cHRvX3RmbV9hbGdfdHlwZSh0Zm0pKSB7CgljYXNlIENSWVBUT19BTEdfVFlQRV9DSVBIRVI6CgkJY3J5cHRvX2V4aXRfY2lwaGVyX29wcyh0Zm0pOwoJCWJyZWFrOwoJCQoJY2FzZSBDUllQVE9fQUxHX1RZUEVfRElHRVNUOgoJCWNyeXB0b19leGl0X2RpZ2VzdF9vcHModGZtKTsKCQlicmVhazsKCQkKCWNhc2UgQ1JZUFRPX0FMR19UWVBFX0NPTVBSRVNTOgoJCWNyeXB0b19leGl0X2NvbXByZXNzX29wcyh0Zm0pOwoJCWJyZWFrOwoJCglkZWZhdWx0OgoJCUJVRygpOwoJCQoJfQp9CgpzdGF0aWMgdW5zaWduZWQgaW50IGNyeXB0b19jdHhzaXplKHN0cnVjdCBjcnlwdG9fYWxnICphbGcsIHUzMiB0eXBlLCB1MzIgbWFzaykKewoJY29uc3Qgc3RydWN0IGNyeXB0b190eXBlICp0eXBlX29iaiA9IGFsZy0+Y3JhX3R5cGU7Cgl1bnNpZ25lZCBpbnQgbGVuOwoKCWxlbiA9IGFsZy0+Y3JhX2FsaWdubWFzayAmIH4oY3J5cHRvX3RmbV9jdHhfYWxpZ25tZW50KCkgLSAxKTsKCWlmICh0eXBlX29iaikKCQlyZXR1cm4gbGVuICsgdHlwZV9vYmotPmN0eHNpemUoYWxnLCB0eXBlLCBtYXNrKTsKCglzd2l0Y2ggKGFsZy0+Y3JhX2ZsYWdzICYgQ1JZUFRPX0FMR19UWVBFX01BU0spIHsKCWRlZmF1bHQ6CgkJQlVHKCk7CgoJY2FzZSBDUllQVE9fQUxHX1RZUEVfQ0lQSEVSOgoJCWxlbiArPSBjcnlwdG9fY2lwaGVyX2N0eHNpemUoYWxnKTsKCQlicmVhazsKCQkKCWNhc2UgQ1JZUFRPX0FMR19UWVBFX0RJR0VTVDoKCQlsZW4gKz0gY3J5cHRvX2RpZ2VzdF9jdHhzaXplKGFsZyk7CgkJYnJlYWs7CgkJCgljYXNlIENSWVBUT19BTEdfVFlQRV9DT01QUkVTUzoKCQlsZW4gKz0gY3J5cHRvX2NvbXByZXNzX2N0eHNpemUoYWxnKTsKCQlicmVhazsKCX0KCglyZXR1cm4gbGVuOwp9Cgp2b2lkIGNyeXB0b19zaG9vdF9hbGcoc3RydWN0IGNyeXB0b19hbGcgKmFsZykKewoJZG93bl93cml0ZSgmY3J5cHRvX2FsZ19zZW0pOwoJYWxnLT5jcmFfZmxhZ3MgfD0gQ1JZUFRPX0FMR19EWUlORzsKCXVwX3dyaXRlKCZjcnlwdG9fYWxnX3NlbSk7Cn0KRVhQT1JUX1NZTUJPTF9HUEwoY3J5cHRvX3Nob290X2FsZyk7CgpzdHJ1Y3QgY3J5cHRvX3RmbSAqX19jcnlwdG9fYWxsb2NfdGZtKHN0cnVjdCBjcnlwdG9fYWxnICphbGcsIHUzMiB0eXBlLAoJCQkJICAgICAgdTMyIG1hc2spCnsKCXN0cnVjdCBjcnlwdG9fdGZtICp0Zm0gPSBOVUxMOwoJdW5zaWduZWQgaW50IHRmbV9zaXplOwoJaW50IGVyciA9IC1FTk9NRU07CgoJdGZtX3NpemUgPSBzaXplb2YoKnRmbSkgKyBjcnlwdG9fY3R4c2l6ZShhbGcsIHR5cGUsIG1hc2spOwoJdGZtID0ga3phbGxvYyh0Zm1fc2l6ZSwgR0ZQX0tFUk5FTCk7CglpZiAodGZtID09IE5VTEwpCgkJZ290byBvdXRfZXJyOwoKCXRmbS0+X19jcnRfYWxnID0gYWxnOwoKCWVyciA9IGNyeXB0b19pbml0X29wcyh0Zm0sIHR5cGUsIG1hc2spOwoJaWYgKGVycikKCQlnb3RvIG91dF9mcmVlX3RmbTsKCglpZiAoYWxnLT5jcmFfaW5pdCAmJiAoZXJyID0gYWxnLT5jcmFfaW5pdCh0Zm0pKSkgewoJCWlmIChlcnIgPT0gLUVBR0FJTikKCQkJY3J5cHRvX3Nob290X2FsZyhhbGcpOwoJCWdvdG8gY3JhX2luaXRfZmFpbGVkOwoJfQoKCWdvdG8gb3V0OwoKY3JhX2luaXRfZmFpbGVkOgoJY3J5cHRvX2V4aXRfb3BzKHRmbSk7Cm91dF9mcmVlX3RmbToKCWtmcmVlKHRmbSk7Cm91dF9lcnI6Cgl0Zm0gPSBFUlJfUFRSKGVycik7Cm91dDoKCXJldHVybiB0Zm07Cn0KRVhQT1JUX1NZTUJPTF9HUEwoX19jcnlwdG9fYWxsb2NfdGZtKTsKCi8qCiAqCWNyeXB0b19hbGxvY19iYXNlIC0gTG9jYXRlIGFsZ29yaXRobSBhbmQgYWxsb2NhdGUgdHJhbnNmb3JtCiAqCUBhbGdfbmFtZTogTmFtZSBvZiBhbGdvcml0aG0KICoJQHR5cGU6IFR5cGUgb2YgYWxnb3JpdGhtCiAqCUBtYXNrOiBNYXNrIGZvciB0eXBlIGNvbXBhcmlzb24KICoKICoJY3J5cHRvX2FsbG9jX2Jhc2UoKSB3aWxsIGZpcnN0IGF0dGVtcHQgdG8gbG9jYXRlIGFuIGFscmVhZHkgbG9hZGVkCiAqCWFsZ29yaXRobS4gIElmIHRoYXQgZmFpbHMgYW5kIHRoZSBrZXJuZWwgc3VwcG9ydHMgZHluYW1pY2FsbHkgbG9hZGFibGUKICoJbW9kdWxlcywgaXQgd2lsbCB0aGVuIGF0dGVtcHQgdG8gbG9hZCBhIG1vZHVsZSBvZiB0aGUgc2FtZSBuYW1lIG9yCiAqCWFsaWFzLiAgSWYgdGhhdCBmYWlscyBpdCB3aWxsIHNlbmQgYSBxdWVyeSB0byBhbnkgbG9hZGVkIGNyeXB0byBtYW5hZ2VyCiAqCXRvIGNvbnN0cnVjdCBhbiBhbGdvcml0aG0gb24gdGhlIGZseS4gIEEgcmVmY291bnQgaXMgZ3JhYmJlZCBvbiB0aGUKICoJYWxnb3JpdGhtIHdoaWNoIGlzIHRoZW4gYXNzb2NpYXRlZCB3aXRoIHRoZSBuZXcgdHJhbnNmb3JtLgogKgogKglUaGUgcmV0dXJuZWQgdHJhbnNmb3JtIGlzIG9mIGEgbm9uLWRldGVybWluYXRlIHR5cGUuICBNb3N0IHBlb3BsZQogKglzaG91bGQgdXNlIG9uZSBvZiB0aGUgbW9yZSBzcGVjaWZpYyBhbGxvY2F0aW9uIGZ1bmN0aW9ucyBzdWNoIGFzCiAqCWNyeXB0b19hbGxvY19ibGtjaXBoZXIuCiAqCiAqCUluIGNhc2Ugb2YgZXJyb3IgdGhlIHJldHVybiB2YWx1ZSBpcyBhbiBlcnJvciBwb2ludGVyLgogKi8Kc3RydWN0IGNyeXB0b190Zm0gKmNyeXB0b19hbGxvY19iYXNlKGNvbnN0IGNoYXIgKmFsZ19uYW1lLCB1MzIgdHlwZSwgdTMyIG1hc2spCnsKCXN0cnVjdCBjcnlwdG9fdGZtICp0Zm07CglpbnQgZXJyOwoKCWZvciAoOzspIHsKCQlzdHJ1Y3QgY3J5cHRvX2FsZyAqYWxnOwoKCQlhbGcgPSBjcnlwdG9fYWxnX21vZF9sb29rdXAoYWxnX25hbWUsIHR5cGUsIG1hc2spOwoJCWlmIChJU19FUlIoYWxnKSkgewoJCQllcnIgPSBQVFJfRVJSKGFsZyk7CgkJCWdvdG8gZXJyOwoJCX0KCgkJdGZtID0gX19jcnlwdG9fYWxsb2NfdGZtKGFsZywgdHlwZSwgbWFzayk7CgkJaWYgKCFJU19FUlIodGZtKSkKCQkJcmV0dXJuIHRmbTsKCgkJY3J5cHRvX21vZF9wdXQoYWxnKTsKCQllcnIgPSBQVFJfRVJSKHRmbSk7CgplcnI6CgkJaWYgKGVyciAhPSAtRUFHQUlOKQoJCQlicmVhazsKCQlpZiAoc2lnbmFsX3BlbmRpbmcoY3VycmVudCkpIHsKCQkJZXJyID0gLUVJTlRSOwoJCQlicmVhazsKCQl9Cgl9CgoJcmV0dXJuIEVSUl9QVFIoZXJyKTsKfQpFWFBPUlRfU1lNQk9MX0dQTChjcnlwdG9fYWxsb2NfYmFzZSk7CiAKLyoKICoJY3J5cHRvX2ZyZWVfdGZtIC0gRnJlZSBjcnlwdG8gdHJhbnNmb3JtCiAqCUB0Zm06IFRyYW5zZm9ybSB0byBmcmVlCiAqCiAqCWNyeXB0b19mcmVlX3RmbSgpIGZyZWVzIHVwIHRoZSB0cmFuc2Zvcm0gYW5kIGFueSBhc3NvY2lhdGVkIHJlc291cmNlcywKICoJdGhlbiBkcm9wcyB0aGUgcmVmY291bnQgb24gdGhlIGFzc29jaWF0ZWQgYWxnb3JpdGhtLgogKi8Kdm9pZCBjcnlwdG9fZnJlZV90Zm0oc3RydWN0IGNyeXB0b190Zm0gKnRmbSkKewoJc3RydWN0IGNyeXB0b19hbGcgKmFsZzsKCWludCBzaXplOwoKCWlmICh1bmxpa2VseSghdGZtKSkKCQlyZXR1cm47CgoJYWxnID0gdGZtLT5fX2NydF9hbGc7CglzaXplID0gc2l6ZW9mKCp0Zm0pICsgYWxnLT5jcmFfY3R4c2l6ZTsKCglpZiAoYWxnLT5jcmFfZXhpdCkKCQlhbGctPmNyYV9leGl0KHRmbSk7CgljcnlwdG9fZXhpdF9vcHModGZtKTsKCWNyeXB0b19tb2RfcHV0KGFsZyk7CgltZW1zZXQodGZtLCAwLCBzaXplKTsKCWtmcmVlKHRmbSk7Cn0KCkVYUE9SVF9TWU1CT0xfR1BMKGNyeXB0b19mcmVlX3RmbSk7CgppbnQgY3J5cHRvX2hhc19hbGcoY29uc3QgY2hhciAqbmFtZSwgdTMyIHR5cGUsIHUzMiBtYXNrKQp7CglpbnQgcmV0ID0gMDsKCXN0cnVjdCBjcnlwdG9fYWxnICphbGcgPSBjcnlwdG9fYWxnX21vZF9sb29rdXAobmFtZSwgdHlwZSwgbWFzayk7CgkKCWlmICghSVNfRVJSKGFsZykpIHsKCQljcnlwdG9fbW9kX3B1dChhbGcpOwoJCXJldCA9IDE7Cgl9CgkKCXJldHVybiByZXQ7Cn0KRVhQT1JUX1NZTUJPTF9HUEwoY3J5cHRvX2hhc19hbGcpOwo=