LyoKICogU2NhdHRlcmxpc3QgQ3J5cHRvZ3JhcGhpYyBBUEkuCiAqCiAqIENvcHlyaWdodCAoYykgMjAwMiBKYW1lcyBNb3JyaXMgPGptb3JyaXNAaW50ZXJjb2RlLmNvbS5hdT4KICogQ29weXJpZ2h0IChjKSAyMDAyIERhdmlkIFMuIE1pbGxlciAoZGF2ZW1AcmVkaGF0LmNvbSkKICoKICogUG9ydGlvbnMgZGVyaXZlZCBmcm9tIENyeXB0b2FwaSwgYnkgQWxleGFuZGVyIEtqZWxkYWFzIDxhc3RvckBmYXN0Lm5vPgogKiBhbmQgTmV0dGxlLCBieSBOaWVscyBN9mxsZXIuCiAqCiAqIFRoaXMgcHJvZ3JhbSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0CiAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlCiAqIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlciB2ZXJzaW9uIDIgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgCiAqIGFueSBsYXRlciB2ZXJzaW9uLgogKgogKi8KCiNpbmNsdWRlIDxsaW51eC9jb21waWxlci5oPgojaW5jbHVkZSA8bGludXgvaW5pdC5oPgojaW5jbHVkZSA8bGludXgvY3J5cHRvLmg+CiNpbmNsdWRlIDxsaW51eC9lcnJuby5oPgojaW5jbHVkZSA8bGludXgva21vZC5oPgojaW5jbHVkZSA8bGludXgvcndzZW0uaD4KI2luY2x1ZGUgPGxpbnV4L3NsYWIuaD4KI2luY2x1ZGUgImludGVybmFsLmgiCgpMSVNUX0hFQUQoY3J5cHRvX2FsZ19saXN0KTsKREVDTEFSRV9SV1NFTShjcnlwdG9fYWxnX3NlbSk7CgpzdGF0aWMgaW5saW5lIGludCBjcnlwdG9fYWxnX2dldChzdHJ1Y3QgY3J5cHRvX2FsZyAqYWxnKQp7CglyZXR1cm4gdHJ5X21vZHVsZV9nZXQoYWxnLT5jcmFfbW9kdWxlKTsKfQoKc3RhdGljIGlubGluZSB2b2lkIGNyeXB0b19hbGdfcHV0KHN0cnVjdCBjcnlwdG9fYWxnICphbGcpCnsKCW1vZHVsZV9wdXQoYWxnLT5jcmFfbW9kdWxlKTsKfQoKc3RhdGljIHN0cnVjdCBjcnlwdG9fYWxnICpjcnlwdG9fYWxnX2xvb2t1cChjb25zdCBjaGFyICpuYW1lKQp7CglzdHJ1Y3QgY3J5cHRvX2FsZyAqcSwgKmFsZyA9IE5VTEw7CgoJaWYgKCFuYW1lKQoJCXJldHVybiBOVUxMOwoJCglkb3duX3JlYWQoJmNyeXB0b19hbGdfc2VtKTsKCQoJbGlzdF9mb3JfZWFjaF9lbnRyeShxLCAmY3J5cHRvX2FsZ19saXN0LCBjcmFfbGlzdCkgewoJCWlmICghKHN0cmNtcChxLT5jcmFfbmFtZSwgbmFtZSkpKSB7CgkJCWlmIChjcnlwdG9fYWxnX2dldChxKSkKCQkJCWFsZyA9IHE7CgkJCWJyZWFrOwoJCX0KCX0KCQoJdXBfcmVhZCgmY3J5cHRvX2FsZ19zZW0pOwoJcmV0dXJuIGFsZzsKfQoKLyogQSBmYXIgbW9yZSBpbnRlbGxpZ2VudCB2ZXJzaW9uIG9mIHRoaXMgaXMgcGxhbm5lZC4gIEZvciBub3csIGp1c3QKICogdHJ5IGFuIGV4YWN0IG1hdGNoIG9uIHRoZSBuYW1lIG9mIHRoZSBhbGdvcml0aG0uICovCnN0YXRpYyBpbmxpbmUgc3RydWN0IGNyeXB0b19hbGcgKmNyeXB0b19hbGdfbW9kX2xvb2t1cChjb25zdCBjaGFyICpuYW1lKQp7CglyZXR1cm4gdHJ5X3RoZW5fcmVxdWVzdF9tb2R1bGUoY3J5cHRvX2FsZ19sb29rdXAobmFtZSksIG5hbWUpOwp9CgpzdGF0aWMgaW50IGNyeXB0b19pbml0X2ZsYWdzKHN0cnVjdCBjcnlwdG9fdGZtICp0Zm0sIHUzMiBmbGFncykKewoJdGZtLT5jcnRfZmxhZ3MgPSBmbGFncyAmIENSWVBUT19URk1fUkVRX01BU0s7CglmbGFncyAmPSB+Q1JZUFRPX1RGTV9SRVFfTUFTSzsKCQoJc3dpdGNoIChjcnlwdG9fdGZtX2FsZ190eXBlKHRmbSkpIHsKCWNhc2UgQ1JZUFRPX0FMR19UWVBFX0NJUEhFUjoKCQlyZXR1cm4gY3J5cHRvX2luaXRfY2lwaGVyX2ZsYWdzKHRmbSwgZmxhZ3MpOwoJCQoJY2FzZSBDUllQVE9fQUxHX1RZUEVfRElHRVNUOgoJCXJldHVybiBjcnlwdG9faW5pdF9kaWdlc3RfZmxhZ3ModGZtLCBmbGFncyk7CgkJCgljYXNlIENSWVBUT19BTEdfVFlQRV9DT01QUkVTUzoKCQlyZXR1cm4gY3J5cHRvX2luaXRfY29tcHJlc3NfZmxhZ3ModGZtLCBmbGFncyk7CgkKCWRlZmF1bHQ6CgkJYnJlYWs7Cgl9CgkKCUJVRygpOwoJcmV0dXJuIC1FSU5WQUw7Cn0KCnN0YXRpYyBpbnQgY3J5cHRvX2luaXRfb3BzKHN0cnVjdCBjcnlwdG9fdGZtICp0Zm0pCnsKCXN3aXRjaCAoY3J5cHRvX3RmbV9hbGdfdHlwZSh0Zm0pKSB7CgljYXNlIENSWVBUT19BTEdfVFlQRV9DSVBIRVI6CgkJcmV0dXJuIGNyeXB0b19pbml0X2NpcGhlcl9vcHModGZtKTsKCQkKCWNhc2UgQ1JZUFRPX0FMR19UWVBFX0RJR0VTVDoKCQlyZXR1cm4gY3J5cHRvX2luaXRfZGlnZXN0X29wcyh0Zm0pOwoJCQoJY2FzZSBDUllQVE9fQUxHX1RZUEVfQ09NUFJFU1M6CgkJcmV0dXJuIGNyeXB0b19pbml0X2NvbXByZXNzX29wcyh0Zm0pOwoJCglkZWZhdWx0OgoJCWJyZWFrOwoJfQoJCglCVUcoKTsKCXJldHVybiAtRUlOVkFMOwp9CgpzdGF0aWMgdm9pZCBjcnlwdG9fZXhpdF9vcHMoc3RydWN0IGNyeXB0b190Zm0gKnRmbSkKewoJc3dpdGNoIChjcnlwdG9fdGZtX2FsZ190eXBlKHRmbSkpIHsKCWNhc2UgQ1JZUFRPX0FMR19UWVBFX0NJUEhFUjoKCQljcnlwdG9fZXhpdF9jaXBoZXJfb3BzKHRmbSk7CgkJYnJlYWs7CgkJCgljYXNlIENSWVBUT19BTEdfVFlQRV9ESUdFU1Q6CgkJY3J5cHRvX2V4aXRfZGlnZXN0X29wcyh0Zm0pOwoJCWJyZWFrOwoJCQoJY2FzZSBDUllQVE9fQUxHX1RZUEVfQ09NUFJFU1M6CgkJY3J5cHRvX2V4aXRfY29tcHJlc3Nfb3BzKHRmbSk7CgkJYnJlYWs7CgkKCWRlZmF1bHQ6CgkJQlVHKCk7CgkJCgl9Cn0KCnN0YXRpYyB1bnNpZ25lZCBpbnQgY3J5cHRvX2N0eHNpemUoc3RydWN0IGNyeXB0b19hbGcgKmFsZywgaW50IGZsYWdzKQp7Cgl1bnNpZ25lZCBpbnQgbGVuOwoKCXN3aXRjaCAoYWxnLT5jcmFfZmxhZ3MgJiBDUllQVE9fQUxHX1RZUEVfTUFTSykgewoJZGVmYXVsdDoKCQlCVUcoKTsKCgljYXNlIENSWVBUT19BTEdfVFlQRV9DSVBIRVI6CgkJbGVuID0gY3J5cHRvX2NpcGhlcl9jdHhzaXplKGFsZywgZmxhZ3MpOwoJCWJyZWFrOwoJCQoJY2FzZSBDUllQVE9fQUxHX1RZUEVfRElHRVNUOgoJCWxlbiA9IGNyeXB0b19kaWdlc3RfY3R4c2l6ZShhbGcsIGZsYWdzKTsKCQlicmVhazsKCQkKCWNhc2UgQ1JZUFRPX0FMR19UWVBFX0NPTVBSRVNTOgoJCWxlbiA9IGNyeXB0b19jb21wcmVzc19jdHhzaXplKGFsZywgZmxhZ3MpOwoJCWJyZWFrOwoJfQoKCXJldHVybiBsZW4gKyBhbGctPmNyYV9hbGlnbm1hc2s7Cn0KCnN0cnVjdCBjcnlwdG9fdGZtICpjcnlwdG9fYWxsb2NfdGZtKGNvbnN0IGNoYXIgKm5hbWUsIHUzMiBmbGFncykKewoJc3RydWN0IGNyeXB0b190Zm0gKnRmbSA9IE5VTEw7CglzdHJ1Y3QgY3J5cHRvX2FsZyAqYWxnOwoJdW5zaWduZWQgaW50IHRmbV9zaXplOwoKCWFsZyA9IGNyeXB0b19hbGdfbW9kX2xvb2t1cChuYW1lKTsKCWlmIChhbGcgPT0gTlVMTCkKCQlnb3RvIG91dDsKCgl0Zm1fc2l6ZSA9IHNpemVvZigqdGZtKSArIGNyeXB0b19jdHhzaXplKGFsZywgZmxhZ3MpOwoJdGZtID0ga21hbGxvYyh0Zm1fc2l6ZSwgR0ZQX0tFUk5FTCk7CglpZiAodGZtID09IE5VTEwpCgkJZ290byBvdXRfcHV0OwoKCW1lbXNldCh0Zm0sIDAsIHRmbV9zaXplKTsKCQoJdGZtLT5fX2NydF9hbGcgPSBhbGc7CgkKCWlmIChjcnlwdG9faW5pdF9mbGFncyh0Zm0sIGZsYWdzKSkKCQlnb3RvIG91dF9mcmVlX3RmbTsKCQkKCWlmIChjcnlwdG9faW5pdF9vcHModGZtKSkgewoJCWNyeXB0b19leGl0X29wcyh0Zm0pOwoJCWdvdG8gb3V0X2ZyZWVfdGZtOwoJfQoKCWdvdG8gb3V0OwoKb3V0X2ZyZWVfdGZtOgoJa2ZyZWUodGZtKTsKCXRmbSA9IE5VTEw7Cm91dF9wdXQ6CgljcnlwdG9fYWxnX3B1dChhbGcpOwpvdXQ6CglyZXR1cm4gdGZtOwp9Cgp2b2lkIGNyeXB0b19mcmVlX3RmbShzdHJ1Y3QgY3J5cHRvX3RmbSAqdGZtKQp7CglzdHJ1Y3QgY3J5cHRvX2FsZyAqYWxnOwoJaW50IHNpemU7CgoJaWYgKHVubGlrZWx5KCF0Zm0pKQoJCXJldHVybjsKCglhbGcgPSB0Zm0tPl9fY3J0X2FsZzsKCXNpemUgPSBzaXplb2YoKnRmbSkgKyBhbGctPmNyYV9jdHhzaXplOwoKCWNyeXB0b19leGl0X29wcyh0Zm0pOwoJY3J5cHRvX2FsZ19wdXQoYWxnKTsKCW1lbXNldCh0Zm0sIDAsIHNpemUpOwoJa2ZyZWUodGZtKTsKfQoKaW50IGNyeXB0b19yZWdpc3Rlcl9hbGcoc3RydWN0IGNyeXB0b19hbGcgKmFsZykKewoJaW50IHJldCA9IDA7CglzdHJ1Y3QgY3J5cHRvX2FsZyAqcTsKCglpZiAoYWxnLT5jcmFfYWxpZ25tYXNrICYgKGFsZy0+Y3JhX2FsaWdubWFzayArIDEpKQoJCXJldHVybiAtRUlOVkFMOwoKCWlmIChhbGctPmNyYV9hbGlnbm1hc2sgJiBhbGctPmNyYV9ibG9ja3NpemUpCgkJcmV0dXJuIC1FSU5WQUw7CgoJaWYgKGFsZy0+Y3JhX2Jsb2Nrc2l6ZSA+IFBBR0VfU0laRSkKCQlyZXR1cm4gLUVJTlZBTDsKCQoJZG93bl93cml0ZSgmY3J5cHRvX2FsZ19zZW0pOwoJCglsaXN0X2Zvcl9lYWNoX2VudHJ5KHEsICZjcnlwdG9fYWxnX2xpc3QsIGNyYV9saXN0KSB7CgkJaWYgKCEoc3RyY21wKHEtPmNyYV9uYW1lLCBhbGctPmNyYV9uYW1lKSkpIHsKCQkJcmV0ID0gLUVFWElTVDsKCQkJZ290byBvdXQ7CgkJfQoJfQoJCglsaXN0X2FkZF90YWlsKCZhbGctPmNyYV9saXN0LCAmY3J5cHRvX2FsZ19saXN0KTsKb3V0OgkKCXVwX3dyaXRlKCZjcnlwdG9fYWxnX3NlbSk7CglyZXR1cm4gcmV0Owp9CgppbnQgY3J5cHRvX3VucmVnaXN0ZXJfYWxnKHN0cnVjdCBjcnlwdG9fYWxnICphbGcpCnsKCWludCByZXQgPSAtRU5PRU5UOwoJc3RydWN0IGNyeXB0b19hbGcgKnE7CgkKCUJVR19PTighYWxnLT5jcmFfbW9kdWxlKTsKCQoJZG93bl93cml0ZSgmY3J5cHRvX2FsZ19zZW0pOwoJbGlzdF9mb3JfZWFjaF9lbnRyeShxLCAmY3J5cHRvX2FsZ19saXN0LCBjcmFfbGlzdCkgewoJCWlmIChhbGcgPT0gcSkgewoJCQlsaXN0X2RlbCgmYWxnLT5jcmFfbGlzdCk7CgkJCXJldCA9IDA7CgkJCWdvdG8gb3V0OwoJCX0KCX0Kb3V0OgkKCXVwX3dyaXRlKCZjcnlwdG9fYWxnX3NlbSk7CglyZXR1cm4gcmV0Owp9CgppbnQgY3J5cHRvX2FsZ19hdmFpbGFibGUoY29uc3QgY2hhciAqbmFtZSwgdTMyIGZsYWdzKQp7CglpbnQgcmV0ID0gMDsKCXN0cnVjdCBjcnlwdG9fYWxnICphbGcgPSBjcnlwdG9fYWxnX21vZF9sb29rdXAobmFtZSk7CgkKCWlmIChhbGcpIHsKCQljcnlwdG9fYWxnX3B1dChhbGcpOwoJCXJldCA9IDE7Cgl9CgkKCXJldHVybiByZXQ7Cn0KCnN0YXRpYyBpbnQgX19pbml0IGluaXRfY3J5cHRvKHZvaWQpCnsKCXByaW50ayhLRVJOX0lORk8gIkluaXRpYWxpemluZyBDcnlwdG9ncmFwaGljIEFQSVxuIik7CgljcnlwdG9faW5pdF9wcm9jKCk7CglyZXR1cm4gMDsKfQoKX19pbml0Y2FsbChpbml0X2NyeXB0byk7CgpFWFBPUlRfU1lNQk9MX0dQTChjcnlwdG9fcmVnaXN0ZXJfYWxnKTsKRVhQT1JUX1NZTUJPTF9HUEwoY3J5cHRvX3VucmVnaXN0ZXJfYWxnKTsKRVhQT1JUX1NZTUJPTF9HUEwoY3J5cHRvX2FsbG9jX3RmbSk7CkVYUE9SVF9TWU1CT0xfR1BMKGNyeXB0b19mcmVlX3RmbSk7CkVYUE9SVF9TWU1CT0xfR1BMKGNyeXB0b19hbGdfYXZhaWxhYmxlKTsK