LyoKICogU2NhdHRlcmxpc3QgQ3J5cHRvZ3JhcGhpYyBBUEkuCiAqCiAqIENvcHlyaWdodCAoYykgMjAwMiBKYW1lcyBNb3JyaXMgPGptb3JyaXNAaW50ZXJjb2RlLmNvbS5hdT4KICogQ29weXJpZ2h0IChjKSAyMDAyIERhdmlkIFMuIE1pbGxlciAoZGF2ZW1AcmVkaGF0LmNvbSkKICoKICogUG9ydGlvbnMgZGVyaXZlZCBmcm9tIENyeXB0b2FwaSwgYnkgQWxleGFuZGVyIEtqZWxkYWFzIDxhc3RvckBmYXN0Lm5vPgogKiBhbmQgTmV0dGxlLCBieSBOaWVscyBN9mxsZXIuCiAqCiAqIFRoaXMgcHJvZ3JhbSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0CiAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlCiAqIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlciB2ZXJzaW9uIDIgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgCiAqIGFueSBsYXRlciB2ZXJzaW9uLgogKgogKi8KCiNpbmNsdWRlIDxsaW51eC9jb21waWxlci5oPgojaW5jbHVkZSA8bGludXgvaW5pdC5oPgojaW5jbHVkZSA8bGludXgvY3J5cHRvLmg+CiNpbmNsdWRlIDxsaW51eC9lcnJuby5oPgojaW5jbHVkZSA8bGludXgva21vZC5oPgojaW5jbHVkZSA8bGludXgvcndzZW0uaD4KI2luY2x1ZGUgPGxpbnV4L3NsYWIuaD4KI2luY2x1ZGUgImludGVybmFsLmgiCgpMSVNUX0hFQUQoY3J5cHRvX2FsZ19saXN0KTsKREVDTEFSRV9SV1NFTShjcnlwdG9fYWxnX3NlbSk7CgpzdGF0aWMgaW5saW5lIGludCBjcnlwdG9fYWxnX2dldChzdHJ1Y3QgY3J5cHRvX2FsZyAqYWxnKQp7CglyZXR1cm4gdHJ5X21vZHVsZV9nZXQoYWxnLT5jcmFfbW9kdWxlKTsKfQoKc3RhdGljIGlubGluZSB2b2lkIGNyeXB0b19hbGdfcHV0KHN0cnVjdCBjcnlwdG9fYWxnICphbGcpCnsKCW1vZHVsZV9wdXQoYWxnLT5jcmFfbW9kdWxlKTsKfQoKc3RhdGljIHN0cnVjdCBjcnlwdG9fYWxnICpjcnlwdG9fYWxnX2xvb2t1cChjb25zdCBjaGFyICpuYW1lKQp7CglzdHJ1Y3QgY3J5cHRvX2FsZyAqcSwgKmFsZyA9IE5VTEw7CgoJaWYgKCFuYW1lKQoJCXJldHVybiBOVUxMOwoJCglkb3duX3JlYWQoJmNyeXB0b19hbGdfc2VtKTsKCQoJbGlzdF9mb3JfZWFjaF9lbnRyeShxLCAmY3J5cHRvX2FsZ19saXN0LCBjcmFfbGlzdCkgewoJCWlmICghKHN0cmNtcChxLT5jcmFfbmFtZSwgbmFtZSkpKSB7CgkJCWlmIChjcnlwdG9fYWxnX2dldChxKSkKCQkJCWFsZyA9IHE7CgkJCWJyZWFrOwoJCX0KCX0KCQoJdXBfcmVhZCgmY3J5cHRvX2FsZ19zZW0pOwoJcmV0dXJuIGFsZzsKfQoKLyogQSBmYXIgbW9yZSBpbnRlbGxpZ2VudCB2ZXJzaW9uIG9mIHRoaXMgaXMgcGxhbm5lZC4gIEZvciBub3csIGp1c3QKICogdHJ5IGFuIGV4YWN0IG1hdGNoIG9uIHRoZSBuYW1lIG9mIHRoZSBhbGdvcml0aG0uICovCnN0YXRpYyBpbmxpbmUgc3RydWN0IGNyeXB0b19hbGcgKmNyeXB0b19hbGdfbW9kX2xvb2t1cChjb25zdCBjaGFyICpuYW1lKQp7CglyZXR1cm4gdHJ5X3RoZW5fcmVxdWVzdF9tb2R1bGUoY3J5cHRvX2FsZ19sb29rdXAobmFtZSksIG5hbWUpOwp9CgpzdGF0aWMgaW50IGNyeXB0b19pbml0X2ZsYWdzKHN0cnVjdCBjcnlwdG9fdGZtICp0Zm0sIHUzMiBmbGFncykKewoJdGZtLT5jcnRfZmxhZ3MgPSAwOwoJCglzd2l0Y2ggKGNyeXB0b190Zm1fYWxnX3R5cGUodGZtKSkgewoJY2FzZSBDUllQVE9fQUxHX1RZUEVfQ0lQSEVSOgoJCXJldHVybiBjcnlwdG9faW5pdF9jaXBoZXJfZmxhZ3ModGZtLCBmbGFncyk7CgkJCgljYXNlIENSWVBUT19BTEdfVFlQRV9ESUdFU1Q6CgkJcmV0dXJuIGNyeXB0b19pbml0X2RpZ2VzdF9mbGFncyh0Zm0sIGZsYWdzKTsKCQkKCWNhc2UgQ1JZUFRPX0FMR19UWVBFX0NPTVBSRVNTOgoJCXJldHVybiBjcnlwdG9faW5pdF9jb21wcmVzc19mbGFncyh0Zm0sIGZsYWdzKTsKCQoJZGVmYXVsdDoKCQlicmVhazsKCX0KCQoJQlVHKCk7CglyZXR1cm4gLUVJTlZBTDsKfQoKc3RhdGljIGludCBjcnlwdG9faW5pdF9vcHMoc3RydWN0IGNyeXB0b190Zm0gKnRmbSkKewoJc3dpdGNoIChjcnlwdG9fdGZtX2FsZ190eXBlKHRmbSkpIHsKCWNhc2UgQ1JZUFRPX0FMR19UWVBFX0NJUEhFUjoKCQlyZXR1cm4gY3J5cHRvX2luaXRfY2lwaGVyX29wcyh0Zm0pOwoJCQoJY2FzZSBDUllQVE9fQUxHX1RZUEVfRElHRVNUOgoJCXJldHVybiBjcnlwdG9faW5pdF9kaWdlc3Rfb3BzKHRmbSk7CgkJCgljYXNlIENSWVBUT19BTEdfVFlQRV9DT01QUkVTUzoKCQlyZXR1cm4gY3J5cHRvX2luaXRfY29tcHJlc3Nfb3BzKHRmbSk7CgkKCWRlZmF1bHQ6CgkJYnJlYWs7Cgl9CgkKCUJVRygpOwoJcmV0dXJuIC1FSU5WQUw7Cn0KCnN0YXRpYyB2b2lkIGNyeXB0b19leGl0X29wcyhzdHJ1Y3QgY3J5cHRvX3RmbSAqdGZtKQp7Cglzd2l0Y2ggKGNyeXB0b190Zm1fYWxnX3R5cGUodGZtKSkgewoJY2FzZSBDUllQVE9fQUxHX1RZUEVfQ0lQSEVSOgoJCWNyeXB0b19leGl0X2NpcGhlcl9vcHModGZtKTsKCQlicmVhazsKCQkKCWNhc2UgQ1JZUFRPX0FMR19UWVBFX0RJR0VTVDoKCQljcnlwdG9fZXhpdF9kaWdlc3Rfb3BzKHRmbSk7CgkJYnJlYWs7CgkJCgljYXNlIENSWVBUT19BTEdfVFlQRV9DT01QUkVTUzoKCQljcnlwdG9fZXhpdF9jb21wcmVzc19vcHModGZtKTsKCQlicmVhazsKCQoJZGVmYXVsdDoKCQlCVUcoKTsKCQkKCX0KfQoKc3RhdGljIHVuc2lnbmVkIGludCBjcnlwdG9fY3R4c2l6ZShzdHJ1Y3QgY3J5cHRvX2FsZyAqYWxnLCBpbnQgZmxhZ3MpCnsKCXVuc2lnbmVkIGludCBsZW47CgoJc3dpdGNoIChhbGctPmNyYV9mbGFncyAmIENSWVBUT19BTEdfVFlQRV9NQVNLKSB7CglkZWZhdWx0OgoJCUJVRygpOwoKCWNhc2UgQ1JZUFRPX0FMR19UWVBFX0NJUEhFUjoKCQlsZW4gPSBjcnlwdG9fY2lwaGVyX2N0eHNpemUoYWxnLCBmbGFncyk7CgkJYnJlYWs7CgkJCgljYXNlIENSWVBUT19BTEdfVFlQRV9ESUdFU1Q6CgkJbGVuID0gY3J5cHRvX2RpZ2VzdF9jdHhzaXplKGFsZywgZmxhZ3MpOwoJCWJyZWFrOwoJCQoJY2FzZSBDUllQVE9fQUxHX1RZUEVfQ09NUFJFU1M6CgkJbGVuID0gY3J5cHRvX2NvbXByZXNzX2N0eHNpemUoYWxnLCBmbGFncyk7CgkJYnJlYWs7Cgl9CgoJcmV0dXJuIGxlbiArIGFsZy0+Y3JhX2FsaWdubWFzazsKfQoKc3RydWN0IGNyeXB0b190Zm0gKmNyeXB0b19hbGxvY190Zm0oY29uc3QgY2hhciAqbmFtZSwgdTMyIGZsYWdzKQp7CglzdHJ1Y3QgY3J5cHRvX3RmbSAqdGZtID0gTlVMTDsKCXN0cnVjdCBjcnlwdG9fYWxnICphbGc7Cgl1bnNpZ25lZCBpbnQgdGZtX3NpemU7CgoJYWxnID0gY3J5cHRvX2FsZ19tb2RfbG9va3VwKG5hbWUpOwoJaWYgKGFsZyA9PSBOVUxMKQoJCWdvdG8gb3V0OwoKCXRmbV9zaXplID0gc2l6ZW9mKCp0Zm0pICsgY3J5cHRvX2N0eHNpemUoYWxnLCBmbGFncyk7Cgl0Zm0gPSBrbWFsbG9jKHRmbV9zaXplLCBHRlBfS0VSTkVMKTsKCWlmICh0Zm0gPT0gTlVMTCkKCQlnb3RvIG91dF9wdXQ7CgoJbWVtc2V0KHRmbSwgMCwgdGZtX3NpemUpOwoJCgl0Zm0tPl9fY3J0X2FsZyA9IGFsZzsKCQoJaWYgKGNyeXB0b19pbml0X2ZsYWdzKHRmbSwgZmxhZ3MpKQoJCWdvdG8gb3V0X2ZyZWVfdGZtOwoJCQoJaWYgKGNyeXB0b19pbml0X29wcyh0Zm0pKSB7CgkJY3J5cHRvX2V4aXRfb3BzKHRmbSk7CgkJZ290byBvdXRfZnJlZV90Zm07Cgl9CgoJZ290byBvdXQ7CgpvdXRfZnJlZV90Zm06CglrZnJlZSh0Zm0pOwoJdGZtID0gTlVMTDsKb3V0X3B1dDoKCWNyeXB0b19hbGdfcHV0KGFsZyk7Cm91dDoKCXJldHVybiB0Zm07Cn0KCnZvaWQgY3J5cHRvX2ZyZWVfdGZtKHN0cnVjdCBjcnlwdG9fdGZtICp0Zm0pCnsKCXN0cnVjdCBjcnlwdG9fYWxnICphbGc7CglpbnQgc2l6ZTsKCglpZiAodW5saWtlbHkoIXRmbSkpCgkJcmV0dXJuOwoKCWFsZyA9IHRmbS0+X19jcnRfYWxnOwoJc2l6ZSA9IHNpemVvZigqdGZtKSArIGFsZy0+Y3JhX2N0eHNpemU7CgoJY3J5cHRvX2V4aXRfb3BzKHRmbSk7CgljcnlwdG9fYWxnX3B1dChhbGcpOwoJbWVtc2V0KHRmbSwgMCwgc2l6ZSk7CglrZnJlZSh0Zm0pOwp9CgppbnQgY3J5cHRvX3JlZ2lzdGVyX2FsZyhzdHJ1Y3QgY3J5cHRvX2FsZyAqYWxnKQp7CglpbnQgcmV0ID0gMDsKCXN0cnVjdCBjcnlwdG9fYWxnICpxOwoKCWlmIChhbGctPmNyYV9hbGlnbm1hc2sgJiAoYWxnLT5jcmFfYWxpZ25tYXNrICsgMSkpCgkJcmV0dXJuIC1FSU5WQUw7CgoJaWYgKGFsZy0+Y3JhX2FsaWdubWFzayA+IFBBR0VfU0laRSkKCQlyZXR1cm4gLUVJTlZBTDsKCQoJZG93bl93cml0ZSgmY3J5cHRvX2FsZ19zZW0pOwoJCglsaXN0X2Zvcl9lYWNoX2VudHJ5KHEsICZjcnlwdG9fYWxnX2xpc3QsIGNyYV9saXN0KSB7CgkJaWYgKCEoc3RyY21wKHEtPmNyYV9uYW1lLCBhbGctPmNyYV9uYW1lKSkpIHsKCQkJcmV0ID0gLUVFWElTVDsKCQkJZ290byBvdXQ7CgkJfQoJfQoJCglsaXN0X2FkZF90YWlsKCZhbGctPmNyYV9saXN0LCAmY3J5cHRvX2FsZ19saXN0KTsKb3V0OgkKCXVwX3dyaXRlKCZjcnlwdG9fYWxnX3NlbSk7CglyZXR1cm4gcmV0Owp9CgppbnQgY3J5cHRvX3VucmVnaXN0ZXJfYWxnKHN0cnVjdCBjcnlwdG9fYWxnICphbGcpCnsKCWludCByZXQgPSAtRU5PRU5UOwoJc3RydWN0IGNyeXB0b19hbGcgKnE7CgkKCUJVR19PTighYWxnLT5jcmFfbW9kdWxlKTsKCQoJZG93bl93cml0ZSgmY3J5cHRvX2FsZ19zZW0pOwoJbGlzdF9mb3JfZWFjaF9lbnRyeShxLCAmY3J5cHRvX2FsZ19saXN0LCBjcmFfbGlzdCkgewoJCWlmIChhbGcgPT0gcSkgewoJCQlsaXN0X2RlbCgmYWxnLT5jcmFfbGlzdCk7CgkJCXJldCA9IDA7CgkJCWdvdG8gb3V0OwoJCX0KCX0Kb3V0OgkKCXVwX3dyaXRlKCZjcnlwdG9fYWxnX3NlbSk7CglyZXR1cm4gcmV0Owp9CgppbnQgY3J5cHRvX2FsZ19hdmFpbGFibGUoY29uc3QgY2hhciAqbmFtZSwgdTMyIGZsYWdzKQp7CglpbnQgcmV0ID0gMDsKCXN0cnVjdCBjcnlwdG9fYWxnICphbGcgPSBjcnlwdG9fYWxnX21vZF9sb29rdXAobmFtZSk7CgkKCWlmIChhbGcpIHsKCQljcnlwdG9fYWxnX3B1dChhbGcpOwoJCXJldCA9IDE7Cgl9CgkKCXJldHVybiByZXQ7Cn0KCnN0YXRpYyBpbnQgX19pbml0IGluaXRfY3J5cHRvKHZvaWQpCnsKCXByaW50ayhLRVJOX0lORk8gIkluaXRpYWxpemluZyBDcnlwdG9ncmFwaGljIEFQSVxuIik7CgljcnlwdG9faW5pdF9wcm9jKCk7CglyZXR1cm4gMDsKfQoKX19pbml0Y2FsbChpbml0X2NyeXB0byk7CgpFWFBPUlRfU1lNQk9MX0dQTChjcnlwdG9fcmVnaXN0ZXJfYWxnKTsKRVhQT1JUX1NZTUJPTF9HUEwoY3J5cHRvX3VucmVnaXN0ZXJfYWxnKTsKRVhQT1JUX1NZTUJPTF9HUEwoY3J5cHRvX2FsbG9jX3RmbSk7CkVYUE9SVF9TWU1CT0xfR1BMKGNyeXB0b19mcmVlX3RmbSk7CkVYUE9SVF9TWU1CT0xfR1BMKGNyeXB0b19hbGdfYXZhaWxhYmxlKTsK