LyoKICogU2NhdHRlcmxpc3QgQ3J5cHRvZ3JhcGhpYyBBUEkuCiAqCiAqIENvcHlyaWdodCAoYykgMjAwMiBKYW1lcyBNb3JyaXMgPGptb3JyaXNAaW50ZXJjb2RlLmNvbS5hdT4KICogQ29weXJpZ2h0IChjKSAyMDAyIERhdmlkIFMuIE1pbGxlciAoZGF2ZW1AcmVkaGF0LmNvbSkKICogQ29weXJpZ2h0IChjKSAyMDA1IEhlcmJlcnQgWHUgPGhlcmJlcnRAZ29uZG9yLmFwYW5hLm9yZy5hdT4KICoKICogUG9ydGlvbnMgZGVyaXZlZCBmcm9tIENyeXB0b2FwaSwgYnkgQWxleGFuZGVyIEtqZWxkYWFzIDxhc3RvckBmYXN0Lm5vPgogKiBhbmQgTmV0dGxlLCBieSBOaWVscyBN9mxsZXIuCiAqCiAqIFRoaXMgcHJvZ3JhbSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0CiAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlCiAqIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlciB2ZXJzaW9uIDIgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgCiAqIGFueSBsYXRlciB2ZXJzaW9uLgogKgogKi8KCiNpbmNsdWRlIDxsaW51eC9lcnIuaD4KI2luY2x1ZGUgPGxpbnV4L2Vycm5vLmg+CiNpbmNsdWRlIDxsaW51eC9rZXJuZWwuaD4KI2luY2x1ZGUgPGxpbnV4L2ttb2QuaD4KI2luY2x1ZGUgPGxpbnV4L21vZHVsZS5oPgojaW5jbHVkZSA8bGludXgvcGFyYW0uaD4KI2luY2x1ZGUgPGxpbnV4L3NjaGVkLmg+CiNpbmNsdWRlIDxsaW51eC9zbGFiLmg+CiNpbmNsdWRlIDxsaW51eC9zdHJpbmcuaD4KI2luY2x1ZGUgImludGVybmFsLmgiCgpMSVNUX0hFQUQoY3J5cHRvX2FsZ19saXN0KTsKRVhQT1JUX1NZTUJPTF9HUEwoY3J5cHRvX2FsZ19saXN0KTsKREVDTEFSRV9SV1NFTShjcnlwdG9fYWxnX3NlbSk7CkVYUE9SVF9TWU1CT0xfR1BMKGNyeXB0b19hbGdfc2VtKTsKCkJMT0NLSU5HX05PVElGSUVSX0hFQUQoY3J5cHRvX2NoYWluKTsKRVhQT1JUX1NZTUJPTF9HUEwoY3J5cHRvX2NoYWluKTsKCnN0YXRpYyBpbmxpbmUgc3RydWN0IGNyeXB0b19hbGcgKmNyeXB0b19hbGdfZ2V0KHN0cnVjdCBjcnlwdG9fYWxnICphbGcpCnsKCWF0b21pY19pbmMoJmFsZy0+Y3JhX3JlZmNudCk7CglyZXR1cm4gYWxnOwp9CgpzdHJ1Y3QgY3J5cHRvX2FsZyAqY3J5cHRvX21vZF9nZXQoc3RydWN0IGNyeXB0b19hbGcgKmFsZykKewoJcmV0dXJuIHRyeV9tb2R1bGVfZ2V0KGFsZy0+Y3JhX21vZHVsZSkgPyBjcnlwdG9fYWxnX2dldChhbGcpIDogTlVMTDsKfQpFWFBPUlRfU1lNQk9MX0dQTChjcnlwdG9fbW9kX2dldCk7Cgp2b2lkIGNyeXB0b19tb2RfcHV0KHN0cnVjdCBjcnlwdG9fYWxnICphbGcpCnsKCWNyeXB0b19hbGdfcHV0KGFsZyk7Cgltb2R1bGVfcHV0KGFsZy0+Y3JhX21vZHVsZSk7Cn0KRVhQT1JUX1NZTUJPTF9HUEwoY3J5cHRvX21vZF9wdXQpOwoKc3RydWN0IGNyeXB0b19hbGcgKl9fY3J5cHRvX2FsZ19sb29rdXAoY29uc3QgY2hhciAqbmFtZSwgdTMyIHR5cGUsIHUzMiBtYXNrKQp7CglzdHJ1Y3QgY3J5cHRvX2FsZyAqcSwgKmFsZyA9IE5VTEw7CglpbnQgYmVzdCA9IC0yOwoKCWxpc3RfZm9yX2VhY2hfZW50cnkocSwgJmNyeXB0b19hbGdfbGlzdCwgY3JhX2xpc3QpIHsKCQlpbnQgZXhhY3QsIGZ1enp5OwoKCQlpZiAoY3J5cHRvX2lzX21vcmlidW5kKHEpKQoJCQljb250aW51ZTsKCgkJaWYgKChxLT5jcmFfZmxhZ3MgXiB0eXBlKSAmIG1hc2spCgkJCWNvbnRpbnVlOwoKCQlpZiAoY3J5cHRvX2lzX2xhcnZhbChxKSAmJgoJCSAgICAoKHN0cnVjdCBjcnlwdG9fbGFydmFsICopcSktPm1hc2sgIT0gbWFzaykKCQkJY29udGludWU7CgoJCWV4YWN0ID0gIXN0cmNtcChxLT5jcmFfZHJpdmVyX25hbWUsIG5hbWUpOwoJCWZ1enp5ID0gIXN0cmNtcChxLT5jcmFfbmFtZSwgbmFtZSk7CgkJaWYgKCFleGFjdCAmJiAhKGZ1enp5ICYmIHEtPmNyYV9wcmlvcml0eSA+IGJlc3QpKQoJCQljb250aW51ZTsKCgkJaWYgKHVubGlrZWx5KCFjcnlwdG9fbW9kX2dldChxKSkpCgkJCWNvbnRpbnVlOwoKCQliZXN0ID0gcS0+Y3JhX3ByaW9yaXR5OwoJCWlmIChhbGcpCgkJCWNyeXB0b19tb2RfcHV0KGFsZyk7CgkJYWxnID0gcTsKCgkJaWYgKGV4YWN0KQoJCQlicmVhazsKCX0KCglyZXR1cm4gYWxnOwp9CkVYUE9SVF9TWU1CT0xfR1BMKF9fY3J5cHRvX2FsZ19sb29rdXApOwoKc3RhdGljIHZvaWQgY3J5cHRvX2xhcnZhbF9kZXN0cm95KHN0cnVjdCBjcnlwdG9fYWxnICphbGcpCnsKCXN0cnVjdCBjcnlwdG9fbGFydmFsICpsYXJ2YWwgPSAodm9pZCAqKWFsZzsKCglCVUdfT04oIWNyeXB0b19pc19sYXJ2YWwoYWxnKSk7CglpZiAobGFydmFsLT5hZHVsdCkKCQljcnlwdG9fbW9kX3B1dChsYXJ2YWwtPmFkdWx0KTsKCWtmcmVlKGxhcnZhbCk7Cn0KCnN0YXRpYyBzdHJ1Y3QgY3J5cHRvX2FsZyAqY3J5cHRvX2xhcnZhbF9hbGxvYyhjb25zdCBjaGFyICpuYW1lLCB1MzIgdHlwZSwKCQkJCQkgICAgICB1MzIgbWFzaykKewoJc3RydWN0IGNyeXB0b19hbGcgKmFsZzsKCXN0cnVjdCBjcnlwdG9fbGFydmFsICpsYXJ2YWw7CgoJbGFydmFsID0ga3phbGxvYyhzaXplb2YoKmxhcnZhbCksIEdGUF9LRVJORUwpOwoJaWYgKCFsYXJ2YWwpCgkJcmV0dXJuIEVSUl9QVFIoLUVOT01FTSk7CgoJbGFydmFsLT5tYXNrID0gbWFzazsKCWxhcnZhbC0+YWxnLmNyYV9mbGFncyA9IENSWVBUT19BTEdfTEFSVkFMIHwgdHlwZTsKCWxhcnZhbC0+YWxnLmNyYV9wcmlvcml0eSA9IC0xOwoJbGFydmFsLT5hbGcuY3JhX2Rlc3Ryb3kgPSBjcnlwdG9fbGFydmFsX2Rlc3Ryb3k7CgoJYXRvbWljX3NldCgmbGFydmFsLT5hbGcuY3JhX3JlZmNudCwgMik7CglzdHJsY3B5KGxhcnZhbC0+YWxnLmNyYV9uYW1lLCBuYW1lLCBDUllQVE9fTUFYX0FMR19OQU1FKTsKCWluaXRfY29tcGxldGlvbigmbGFydmFsLT5jb21wbGV0aW9uKTsKCglkb3duX3dyaXRlKCZjcnlwdG9fYWxnX3NlbSk7CglhbGcgPSBfX2NyeXB0b19hbGdfbG9va3VwKG5hbWUsIHR5cGUsIG1hc2spOwoJaWYgKCFhbGcpIHsKCQlhbGcgPSAmbGFydmFsLT5hbGc7CgkJbGlzdF9hZGQoJmFsZy0+Y3JhX2xpc3QsICZjcnlwdG9fYWxnX2xpc3QpOwoJfQoJdXBfd3JpdGUoJmNyeXB0b19hbGdfc2VtKTsKCglpZiAoYWxnICE9ICZsYXJ2YWwtPmFsZykKCQlrZnJlZShsYXJ2YWwpOwoKCXJldHVybiBhbGc7Cn0KCnN0YXRpYyB2b2lkIGNyeXB0b19sYXJ2YWxfa2lsbChzdHJ1Y3QgY3J5cHRvX2FsZyAqYWxnKQp7CglzdHJ1Y3QgY3J5cHRvX2xhcnZhbCAqbGFydmFsID0gKHZvaWQgKilhbGc7CgoJZG93bl93cml0ZSgmY3J5cHRvX2FsZ19zZW0pOwoJbGlzdF9kZWwoJmFsZy0+Y3JhX2xpc3QpOwoJdXBfd3JpdGUoJmNyeXB0b19hbGdfc2VtKTsKCWNvbXBsZXRlKCZsYXJ2YWwtPmNvbXBsZXRpb24pOwoJY3J5cHRvX2FsZ19wdXQoYWxnKTsKfQoKc3RhdGljIHN0cnVjdCBjcnlwdG9fYWxnICpjcnlwdG9fbGFydmFsX3dhaXQoc3RydWN0IGNyeXB0b19hbGcgKmFsZykKewoJc3RydWN0IGNyeXB0b19sYXJ2YWwgKmxhcnZhbCA9ICh2b2lkICopYWxnOwoKCXdhaXRfZm9yX2NvbXBsZXRpb25faW50ZXJydXB0aWJsZV90aW1lb3V0KCZsYXJ2YWwtPmNvbXBsZXRpb24sIDYwICogSFopOwoJYWxnID0gbGFydmFsLT5hZHVsdDsKCWlmIChhbGcpIHsKCQlpZiAoIWNyeXB0b19tb2RfZ2V0KGFsZykpCgkJCWFsZyA9IEVSUl9QVFIoLUVBR0FJTik7Cgl9IGVsc2UKCQlhbGcgPSBFUlJfUFRSKC1FTk9FTlQpOwoJY3J5cHRvX21vZF9wdXQoJmxhcnZhbC0+YWxnKTsKCglyZXR1cm4gYWxnOwp9CgpzdGF0aWMgc3RydWN0IGNyeXB0b19hbGcgKmNyeXB0b19hbGdfbG9va3VwKGNvbnN0IGNoYXIgKm5hbWUsIHUzMiB0eXBlLAoJCQkJCSAgICB1MzIgbWFzaykKewoJc3RydWN0IGNyeXB0b19hbGcgKmFsZzsKCglkb3duX3JlYWQoJmNyeXB0b19hbGdfc2VtKTsKCWFsZyA9IF9fY3J5cHRvX2FsZ19sb29rdXAobmFtZSwgdHlwZSwgbWFzayk7Cgl1cF9yZWFkKCZjcnlwdG9fYWxnX3NlbSk7CgoJcmV0dXJuIGFsZzsKfQoKc3RydWN0IGNyeXB0b19hbGcgKmNyeXB0b19hbGdfbW9kX2xvb2t1cChjb25zdCBjaGFyICpuYW1lLCB1MzIgdHlwZSwgdTMyIG1hc2spCnsKCXN0cnVjdCBjcnlwdG9fYWxnICphbGc7CglzdHJ1Y3QgY3J5cHRvX2FsZyAqbGFydmFsOwoJaW50IG9rOwoKCWlmICghbmFtZSkKCQlyZXR1cm4gRVJSX1BUUigtRU5PRU5UKTsKCgltYXNrICY9IH4oQ1JZUFRPX0FMR19MQVJWQUwgfCBDUllQVE9fQUxHX0RFQUQpOwoJdHlwZSAmPSBtYXNrOwoKCWFsZyA9IHRyeV90aGVuX3JlcXVlc3RfbW9kdWxlKGNyeXB0b19hbGdfbG9va3VwKG5hbWUsIHR5cGUsIG1hc2spLAoJCQkJICAgICAgbmFtZSk7CglpZiAoYWxnKQoJCXJldHVybiBjcnlwdG9faXNfbGFydmFsKGFsZykgPyBjcnlwdG9fbGFydmFsX3dhaXQoYWxnKSA6IGFsZzsKCglsYXJ2YWwgPSBjcnlwdG9fbGFydmFsX2FsbG9jKG5hbWUsIHR5cGUsIG1hc2spOwoJaWYgKElTX0VSUihsYXJ2YWwpIHx8ICFjcnlwdG9faXNfbGFydmFsKGxhcnZhbCkpCgkJcmV0dXJuIGxhcnZhbDsKCglvayA9IGNyeXB0b19ub3RpZnkoQ1JZUFRPX01TR19BTEdfUkVRVUVTVCwgbGFydmFsKTsKCWlmIChvayA9PSBOT1RJRllfRE9ORSkgewoJCXJlcXVlc3RfbW9kdWxlKCJjcnlwdG9tZ3IiKTsKCQlvayA9IGNyeXB0b19ub3RpZnkoQ1JZUFRPX01TR19BTEdfUkVRVUVTVCwgbGFydmFsKTsKCX0KCglpZiAob2sgPT0gTk9USUZZX1NUT1ApCgkJYWxnID0gY3J5cHRvX2xhcnZhbF93YWl0KGxhcnZhbCk7CgllbHNlIHsKCQljcnlwdG9fbW9kX3B1dChsYXJ2YWwpOwoJCWFsZyA9IEVSUl9QVFIoLUVOT0VOVCk7Cgl9CgljcnlwdG9fbGFydmFsX2tpbGwobGFydmFsKTsKCXJldHVybiBhbGc7Cn0KRVhQT1JUX1NZTUJPTF9HUEwoY3J5cHRvX2FsZ19tb2RfbG9va3VwKTsKCnN0YXRpYyBpbnQgY3J5cHRvX2luaXRfZmxhZ3Moc3RydWN0IGNyeXB0b190Zm0gKnRmbSwgdTMyIGZsYWdzKQp7Cgl0Zm0tPmNydF9mbGFncyA9IGZsYWdzICYgQ1JZUFRPX1RGTV9SRVFfTUFTSzsKCWZsYWdzICY9IH5DUllQVE9fVEZNX1JFUV9NQVNLOwoJCglzd2l0Y2ggKGNyeXB0b190Zm1fYWxnX3R5cGUodGZtKSkgewoJY2FzZSBDUllQVE9fQUxHX1RZUEVfQ0lQSEVSOgoJCXJldHVybiBjcnlwdG9faW5pdF9jaXBoZXJfZmxhZ3ModGZtLCBmbGFncyk7CgkJCgljYXNlIENSWVBUT19BTEdfVFlQRV9ESUdFU1Q6CgkJcmV0dXJuIGNyeXB0b19pbml0X2RpZ2VzdF9mbGFncyh0Zm0sIGZsYWdzKTsKCQkKCWNhc2UgQ1JZUFRPX0FMR19UWVBFX0NPTVBSRVNTOgoJCXJldHVybiBjcnlwdG9faW5pdF9jb21wcmVzc19mbGFncyh0Zm0sIGZsYWdzKTsKCQoJZGVmYXVsdDoKCQlicmVhazsKCX0KCQoJQlVHKCk7CglyZXR1cm4gLUVJTlZBTDsKfQoKc3RhdGljIGludCBjcnlwdG9faW5pdF9vcHMoc3RydWN0IGNyeXB0b190Zm0gKnRmbSkKewoJc3dpdGNoIChjcnlwdG9fdGZtX2FsZ190eXBlKHRmbSkpIHsKCWNhc2UgQ1JZUFRPX0FMR19UWVBFX0NJUEhFUjoKCQlyZXR1cm4gY3J5cHRvX2luaXRfY2lwaGVyX29wcyh0Zm0pOwoJCQoJY2FzZSBDUllQVE9fQUxHX1RZUEVfRElHRVNUOgoJCXJldHVybiBjcnlwdG9faW5pdF9kaWdlc3Rfb3BzKHRmbSk7CgkJCgljYXNlIENSWVBUT19BTEdfVFlQRV9DT01QUkVTUzoKCQlyZXR1cm4gY3J5cHRvX2luaXRfY29tcHJlc3Nfb3BzKHRmbSk7CgkKCWRlZmF1bHQ6CgkJYnJlYWs7Cgl9CgkKCUJVRygpOwoJcmV0dXJuIC1FSU5WQUw7Cn0KCnN0YXRpYyB2b2lkIGNyeXB0b19leGl0X29wcyhzdHJ1Y3QgY3J5cHRvX3RmbSAqdGZtKQp7Cglzd2l0Y2ggKGNyeXB0b190Zm1fYWxnX3R5cGUodGZtKSkgewoJY2FzZSBDUllQVE9fQUxHX1RZUEVfQ0lQSEVSOgoJCWNyeXB0b19leGl0X2NpcGhlcl9vcHModGZtKTsKCQlicmVhazsKCQkKCWNhc2UgQ1JZUFRPX0FMR19UWVBFX0RJR0VTVDoKCQljcnlwdG9fZXhpdF9kaWdlc3Rfb3BzKHRmbSk7CgkJYnJlYWs7CgkJCgljYXNlIENSWVBUT19BTEdfVFlQRV9DT01QUkVTUzoKCQljcnlwdG9fZXhpdF9jb21wcmVzc19vcHModGZtKTsKCQlicmVhazsKCQoJZGVmYXVsdDoKCQlCVUcoKTsKCQkKCX0KfQoKc3RhdGljIHVuc2lnbmVkIGludCBjcnlwdG9fY3R4c2l6ZShzdHJ1Y3QgY3J5cHRvX2FsZyAqYWxnLCBpbnQgZmxhZ3MpCnsKCXVuc2lnbmVkIGludCBsZW47CgoJc3dpdGNoIChhbGctPmNyYV9mbGFncyAmIENSWVBUT19BTEdfVFlQRV9NQVNLKSB7CglkZWZhdWx0OgoJCUJVRygpOwoKCWNhc2UgQ1JZUFRPX0FMR19UWVBFX0NJUEhFUjoKCQlsZW4gPSBjcnlwdG9fY2lwaGVyX2N0eHNpemUoYWxnLCBmbGFncyk7CgkJYnJlYWs7CgkJCgljYXNlIENSWVBUT19BTEdfVFlQRV9ESUdFU1Q6CgkJbGVuID0gY3J5cHRvX2RpZ2VzdF9jdHhzaXplKGFsZywgZmxhZ3MpOwoJCWJyZWFrOwoJCQoJY2FzZSBDUllQVE9fQUxHX1RZUEVfQ09NUFJFU1M6CgkJbGVuID0gY3J5cHRvX2NvbXByZXNzX2N0eHNpemUoYWxnLCBmbGFncyk7CgkJYnJlYWs7Cgl9CgoJcmV0dXJuIGxlbiArIChhbGctPmNyYV9hbGlnbm1hc2sgJiB+KGNyeXB0b190Zm1fY3R4X2FsaWdubWVudCgpIC0gMSkpOwp9Cgp2b2lkIGNyeXB0b19zaG9vdF9hbGcoc3RydWN0IGNyeXB0b19hbGcgKmFsZykKewoJZG93bl93cml0ZSgmY3J5cHRvX2FsZ19zZW0pOwoJYWxnLT5jcmFfZmxhZ3MgfD0gQ1JZUFRPX0FMR19EWUlORzsKCXVwX3dyaXRlKCZjcnlwdG9fYWxnX3NlbSk7Cn0KRVhQT1JUX1NZTUJPTF9HUEwoY3J5cHRvX3Nob290X2FsZyk7CgpzdHJ1Y3QgY3J5cHRvX3RmbSAqX19jcnlwdG9fYWxsb2NfdGZtKHN0cnVjdCBjcnlwdG9fYWxnICphbGcsIHUzMiBmbGFncykKewoJc3RydWN0IGNyeXB0b190Zm0gKnRmbSA9IE5VTEw7Cgl1bnNpZ25lZCBpbnQgdGZtX3NpemU7CglpbnQgZXJyID0gLUVOT01FTTsKCgl0Zm1fc2l6ZSA9IHNpemVvZigqdGZtKSArIGNyeXB0b19jdHhzaXplKGFsZywgZmxhZ3MpOwoJdGZtID0ga3phbGxvYyh0Zm1fc2l6ZSwgR0ZQX0tFUk5FTCk7CglpZiAodGZtID09IE5VTEwpCgkJZ290byBvdXQ7CgoJdGZtLT5fX2NydF9hbGcgPSBhbGc7CgoJZXJyID0gY3J5cHRvX2luaXRfZmxhZ3ModGZtLCBmbGFncyk7CglpZiAoZXJyKQoJCWdvdG8gb3V0X2ZyZWVfdGZtOwoJCQoJZXJyID0gY3J5cHRvX2luaXRfb3BzKHRmbSk7CglpZiAoZXJyKQoJCWdvdG8gb3V0X2ZyZWVfdGZtOwoKCWlmIChhbGctPmNyYV9pbml0ICYmIChlcnIgPSBhbGctPmNyYV9pbml0KHRmbSkpKSB7CgkJaWYgKGVyciA9PSAtRUFHQUlOKQoJCQljcnlwdG9fc2hvb3RfYWxnKGFsZyk7CgkJZ290byBjcmFfaW5pdF9mYWlsZWQ7Cgl9CgoJZ290byBvdXQ7CgpjcmFfaW5pdF9mYWlsZWQ6CgljcnlwdG9fZXhpdF9vcHModGZtKTsKb3V0X2ZyZWVfdGZtOgoJa2ZyZWUodGZtKTsKCXRmbSA9IEVSUl9QVFIoZXJyKTsKb3V0OgoJcmV0dXJuIHRmbTsKfQpFWFBPUlRfU1lNQk9MX0dQTChfX2NyeXB0b19hbGxvY190Zm0pOwoKc3RydWN0IGNyeXB0b190Zm0gKmNyeXB0b19hbGxvY190Zm0oY29uc3QgY2hhciAqbmFtZSwgdTMyIGZsYWdzKQp7CglzdHJ1Y3QgY3J5cHRvX3RmbSAqdGZtID0gTlVMTDsKCWludCBlcnI7CgoJZG8gewoJCXN0cnVjdCBjcnlwdG9fYWxnICphbGc7CgoJCWFsZyA9IGNyeXB0b19hbGdfbW9kX2xvb2t1cChuYW1lLCAwLCAwKTsKCQllcnIgPSBQVFJfRVJSKGFsZyk7CgkJaWYgKElTX0VSUihhbGcpKQoJCQljb250aW51ZTsKCgkJdGZtID0gX19jcnlwdG9fYWxsb2NfdGZtKGFsZywgZmxhZ3MpOwoJCWVyciA9IDA7CgkJaWYgKElTX0VSUih0Zm0pKSB7CgkJCWNyeXB0b19tb2RfcHV0KGFsZyk7CgkJCWVyciA9IFBUUl9FUlIodGZtKTsKCQkJdGZtID0gTlVMTDsKCQl9Cgl9IHdoaWxlIChlcnIgPT0gLUVBR0FJTiAmJiAhc2lnbmFsX3BlbmRpbmcoY3VycmVudCkpOwoKCXJldHVybiB0Zm07Cn0KCnZvaWQgY3J5cHRvX2ZyZWVfdGZtKHN0cnVjdCBjcnlwdG9fdGZtICp0Zm0pCnsKCXN0cnVjdCBjcnlwdG9fYWxnICphbGc7CglpbnQgc2l6ZTsKCglpZiAodW5saWtlbHkoIXRmbSkpCgkJcmV0dXJuOwoKCWFsZyA9IHRmbS0+X19jcnRfYWxnOwoJc2l6ZSA9IHNpemVvZigqdGZtKSArIGFsZy0+Y3JhX2N0eHNpemU7CgoJaWYgKGFsZy0+Y3JhX2V4aXQpCgkJYWxnLT5jcmFfZXhpdCh0Zm0pOwoJY3J5cHRvX2V4aXRfb3BzKHRmbSk7CgljcnlwdG9fbW9kX3B1dChhbGcpOwoJbWVtc2V0KHRmbSwgMCwgc2l6ZSk7CglrZnJlZSh0Zm0pOwp9CgppbnQgY3J5cHRvX2FsZ19hdmFpbGFibGUoY29uc3QgY2hhciAqbmFtZSwgdTMyIGZsYWdzKQp7CglpbnQgcmV0ID0gMDsKCXN0cnVjdCBjcnlwdG9fYWxnICphbGcgPSBjcnlwdG9fYWxnX21vZF9sb29rdXAobmFtZSwgMCwgMCk7CgkKCWlmICghSVNfRVJSKGFsZykpIHsKCQljcnlwdG9fbW9kX3B1dChhbGcpOwoJCXJldCA9IDE7Cgl9CgkKCXJldHVybiByZXQ7Cn0KCkVYUE9SVF9TWU1CT0xfR1BMKGNyeXB0b19hbGxvY190Zm0pOwpFWFBPUlRfU1lNQk9MX0dQTChjcnlwdG9fZnJlZV90Zm0pOwpFWFBPUlRfU1lNQk9MX0dQTChjcnlwdG9fYWxnX2F2YWlsYWJsZSk7Cg==