LyoKICogU2NhdHRlcmxpc3QgQ3J5cHRvZ3JhcGhpYyBBUEkuCiAqCiAqIENvcHlyaWdodCAoYykgMjAwMiBKYW1lcyBNb3JyaXMgPGptb3JyaXNAaW50ZXJjb2RlLmNvbS5hdT4KICogQ29weXJpZ2h0IChjKSAyMDAyIERhdmlkIFMuIE1pbGxlciAoZGF2ZW1AcmVkaGF0LmNvbSkKICoKICogUG9ydGlvbnMgZGVyaXZlZCBmcm9tIENyeXB0b2FwaSwgYnkgQWxleGFuZGVyIEtqZWxkYWFzIDxhc3RvckBmYXN0Lm5vPgogKiBhbmQgTmV0dGxlLCBieSBOaWVscyBN9mxsZXIuCiAqCiAqIFRoaXMgcHJvZ3JhbSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0CiAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlCiAqIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlciB2ZXJzaW9uIDIgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgCiAqIGFueSBsYXRlciB2ZXJzaW9uLgogKgogKi8KI2luY2x1ZGUgPGxpbnV4L2luaXQuaD4KI2luY2x1ZGUgPGxpbnV4L2NyeXB0by5oPgojaW5jbHVkZSA8bGludXgvZXJybm8uaD4KI2luY2x1ZGUgPGxpbnV4L2ttb2QuaD4KI2luY2x1ZGUgPGxpbnV4L3J3c2VtLmg+CiNpbmNsdWRlIDxsaW51eC9zbGFiLmg+CiNpbmNsdWRlICJpbnRlcm5hbC5oIgoKTElTVF9IRUFEKGNyeXB0b19hbGdfbGlzdCk7CkRFQ0xBUkVfUldTRU0oY3J5cHRvX2FsZ19zZW0pOwoKc3RhdGljIGlubGluZSBpbnQgY3J5cHRvX2FsZ19nZXQoc3RydWN0IGNyeXB0b19hbGcgKmFsZykKewoJcmV0dXJuIHRyeV9tb2R1bGVfZ2V0KGFsZy0+Y3JhX21vZHVsZSk7Cn0KCnN0YXRpYyBpbmxpbmUgdm9pZCBjcnlwdG9fYWxnX3B1dChzdHJ1Y3QgY3J5cHRvX2FsZyAqYWxnKQp7Cgltb2R1bGVfcHV0KGFsZy0+Y3JhX21vZHVsZSk7Cn0KCnN0YXRpYyBzdHJ1Y3QgY3J5cHRvX2FsZyAqY3J5cHRvX2FsZ19sb29rdXAoY29uc3QgY2hhciAqbmFtZSkKewoJc3RydWN0IGNyeXB0b19hbGcgKnEsICphbGcgPSBOVUxMOwoKCWlmICghbmFtZSkKCQlyZXR1cm4gTlVMTDsKCQoJZG93bl9yZWFkKCZjcnlwdG9fYWxnX3NlbSk7CgkKCWxpc3RfZm9yX2VhY2hfZW50cnkocSwgJmNyeXB0b19hbGdfbGlzdCwgY3JhX2xpc3QpIHsKCQlpZiAoIShzdHJjbXAocS0+Y3JhX25hbWUsIG5hbWUpKSkgewoJCQlpZiAoY3J5cHRvX2FsZ19nZXQocSkpCgkJCQlhbGcgPSBxOwoJCQlicmVhazsKCQl9Cgl9CgkKCXVwX3JlYWQoJmNyeXB0b19hbGdfc2VtKTsKCXJldHVybiBhbGc7Cn0KCi8qIEEgZmFyIG1vcmUgaW50ZWxsaWdlbnQgdmVyc2lvbiBvZiB0aGlzIGlzIHBsYW5uZWQuICBGb3Igbm93LCBqdXN0CiAqIHRyeSBhbiBleGFjdCBtYXRjaCBvbiB0aGUgbmFtZSBvZiB0aGUgYWxnb3JpdGhtLiAqLwpzdGF0aWMgaW5saW5lIHN0cnVjdCBjcnlwdG9fYWxnICpjcnlwdG9fYWxnX21vZF9sb29rdXAoY29uc3QgY2hhciAqbmFtZSkKewoJcmV0dXJuIHRyeV90aGVuX3JlcXVlc3RfbW9kdWxlKGNyeXB0b19hbGdfbG9va3VwKG5hbWUpLCBuYW1lKTsKfQoKc3RhdGljIGludCBjcnlwdG9faW5pdF9mbGFncyhzdHJ1Y3QgY3J5cHRvX3RmbSAqdGZtLCB1MzIgZmxhZ3MpCnsKCXRmbS0+Y3J0X2ZsYWdzID0gMDsKCQoJc3dpdGNoIChjcnlwdG9fdGZtX2FsZ190eXBlKHRmbSkpIHsKCWNhc2UgQ1JZUFRPX0FMR19UWVBFX0NJUEhFUjoKCQlyZXR1cm4gY3J5cHRvX2luaXRfY2lwaGVyX2ZsYWdzKHRmbSwgZmxhZ3MpOwoJCQoJY2FzZSBDUllQVE9fQUxHX1RZUEVfRElHRVNUOgoJCXJldHVybiBjcnlwdG9faW5pdF9kaWdlc3RfZmxhZ3ModGZtLCBmbGFncyk7CgkJCgljYXNlIENSWVBUT19BTEdfVFlQRV9DT01QUkVTUzoKCQlyZXR1cm4gY3J5cHRvX2luaXRfY29tcHJlc3NfZmxhZ3ModGZtLCBmbGFncyk7CgkKCWRlZmF1bHQ6CgkJYnJlYWs7Cgl9CgkKCUJVRygpOwoJcmV0dXJuIC1FSU5WQUw7Cn0KCnN0YXRpYyBpbnQgY3J5cHRvX2luaXRfb3BzKHN0cnVjdCBjcnlwdG9fdGZtICp0Zm0pCnsKCXN3aXRjaCAoY3J5cHRvX3RmbV9hbGdfdHlwZSh0Zm0pKSB7CgljYXNlIENSWVBUT19BTEdfVFlQRV9DSVBIRVI6CgkJcmV0dXJuIGNyeXB0b19pbml0X2NpcGhlcl9vcHModGZtKTsKCQkKCWNhc2UgQ1JZUFRPX0FMR19UWVBFX0RJR0VTVDoKCQlyZXR1cm4gY3J5cHRvX2luaXRfZGlnZXN0X29wcyh0Zm0pOwoJCQoJY2FzZSBDUllQVE9fQUxHX1RZUEVfQ09NUFJFU1M6CgkJcmV0dXJuIGNyeXB0b19pbml0X2NvbXByZXNzX29wcyh0Zm0pOwoJCglkZWZhdWx0OgoJCWJyZWFrOwoJfQoJCglCVUcoKTsKCXJldHVybiAtRUlOVkFMOwp9CgpzdGF0aWMgdm9pZCBjcnlwdG9fZXhpdF9vcHMoc3RydWN0IGNyeXB0b190Zm0gKnRmbSkKewoJc3dpdGNoIChjcnlwdG9fdGZtX2FsZ190eXBlKHRmbSkpIHsKCWNhc2UgQ1JZUFRPX0FMR19UWVBFX0NJUEhFUjoKCQljcnlwdG9fZXhpdF9jaXBoZXJfb3BzKHRmbSk7CgkJYnJlYWs7CgkJCgljYXNlIENSWVBUT19BTEdfVFlQRV9ESUdFU1Q6CgkJY3J5cHRvX2V4aXRfZGlnZXN0X29wcyh0Zm0pOwoJCWJyZWFrOwoJCQoJY2FzZSBDUllQVE9fQUxHX1RZUEVfQ09NUFJFU1M6CgkJY3J5cHRvX2V4aXRfY29tcHJlc3Nfb3BzKHRmbSk7CgkJYnJlYWs7CgkKCWRlZmF1bHQ6CgkJQlVHKCk7CgkJCgl9Cn0KCnN0YXRpYyB1bnNpZ25lZCBpbnQgY3J5cHRvX2N0eHNpemUoc3RydWN0IGNyeXB0b19hbGcgKmFsZywgaW50IGZsYWdzKQp7Cgl1bnNpZ25lZCBpbnQgbGVuOwoKCXN3aXRjaCAoYWxnLT5jcmFfZmxhZ3MgJiBDUllQVE9fQUxHX1RZUEVfTUFTSykgewoJZGVmYXVsdDoKCQlCVUcoKTsKCgljYXNlIENSWVBUT19BTEdfVFlQRV9DSVBIRVI6CgkJbGVuID0gY3J5cHRvX2NpcGhlcl9jdHhzaXplKGFsZywgZmxhZ3MpOwoJCWJyZWFrOwoJCQoJY2FzZSBDUllQVE9fQUxHX1RZUEVfRElHRVNUOgoJCWxlbiA9IGNyeXB0b19kaWdlc3RfY3R4c2l6ZShhbGcsIGZsYWdzKTsKCQlicmVhazsKCQkKCWNhc2UgQ1JZUFRPX0FMR19UWVBFX0NPTVBSRVNTOgoJCWxlbiA9IGNyeXB0b19jb21wcmVzc19jdHhzaXplKGFsZywgZmxhZ3MpOwoJCWJyZWFrOwoJfQoKCXJldHVybiBsZW4gKyBhbGctPmNyYV9hbGlnbm1hc2s7Cn0KCnN0cnVjdCBjcnlwdG9fdGZtICpjcnlwdG9fYWxsb2NfdGZtKGNvbnN0IGNoYXIgKm5hbWUsIHUzMiBmbGFncykKewoJc3RydWN0IGNyeXB0b190Zm0gKnRmbSA9IE5VTEw7CglzdHJ1Y3QgY3J5cHRvX2FsZyAqYWxnOwoJdW5zaWduZWQgaW50IHRmbV9zaXplOwoKCWFsZyA9IGNyeXB0b19hbGdfbW9kX2xvb2t1cChuYW1lKTsKCWlmIChhbGcgPT0gTlVMTCkKCQlnb3RvIG91dDsKCgl0Zm1fc2l6ZSA9IHNpemVvZigqdGZtKSArIGNyeXB0b19jdHhzaXplKGFsZywgZmxhZ3MpOwoJdGZtID0ga21hbGxvYyh0Zm1fc2l6ZSwgR0ZQX0tFUk5FTCk7CglpZiAodGZtID09IE5VTEwpCgkJZ290byBvdXRfcHV0OwoKCW1lbXNldCh0Zm0sIDAsIHRmbV9zaXplKTsKCQoJdGZtLT5fX2NydF9hbGcgPSBhbGc7CgkKCWlmIChjcnlwdG9faW5pdF9mbGFncyh0Zm0sIGZsYWdzKSkKCQlnb3RvIG91dF9mcmVlX3RmbTsKCQkKCWlmIChjcnlwdG9faW5pdF9vcHModGZtKSkgewoJCWNyeXB0b19leGl0X29wcyh0Zm0pOwoJCWdvdG8gb3V0X2ZyZWVfdGZtOwoJfQoKCWdvdG8gb3V0OwoKb3V0X2ZyZWVfdGZtOgoJa2ZyZWUodGZtKTsKCXRmbSA9IE5VTEw7Cm91dF9wdXQ6CgljcnlwdG9fYWxnX3B1dChhbGcpOwpvdXQ6CglyZXR1cm4gdGZtOwp9Cgp2b2lkIGNyeXB0b19mcmVlX3RmbShzdHJ1Y3QgY3J5cHRvX3RmbSAqdGZtKQp7CglzdHJ1Y3QgY3J5cHRvX2FsZyAqYWxnID0gdGZtLT5fX2NydF9hbGc7CglpbnQgc2l6ZSA9IHNpemVvZigqdGZtKSArIGFsZy0+Y3JhX2N0eHNpemU7CgoJY3J5cHRvX2V4aXRfb3BzKHRmbSk7CgljcnlwdG9fYWxnX3B1dChhbGcpOwoJbWVtc2V0KHRmbSwgMCwgc2l6ZSk7CglrZnJlZSh0Zm0pOwp9CgppbnQgY3J5cHRvX3JlZ2lzdGVyX2FsZyhzdHJ1Y3QgY3J5cHRvX2FsZyAqYWxnKQp7CglpbnQgcmV0ID0gMDsKCXN0cnVjdCBjcnlwdG9fYWxnICpxOwoKCWlmIChhbGctPmNyYV9hbGlnbm1hc2sgJiAoYWxnLT5jcmFfYWxpZ25tYXNrICsgMSkpCgkJcmV0dXJuIC1FSU5WQUw7CgoJaWYgKGFsZy0+Y3JhX2FsaWdubWFzayA+IFBBR0VfU0laRSkKCQlyZXR1cm4gLUVJTlZBTDsKCQoJZG93bl93cml0ZSgmY3J5cHRvX2FsZ19zZW0pOwoJCglsaXN0X2Zvcl9lYWNoX2VudHJ5KHEsICZjcnlwdG9fYWxnX2xpc3QsIGNyYV9saXN0KSB7CgkJaWYgKCEoc3RyY21wKHEtPmNyYV9uYW1lLCBhbGctPmNyYV9uYW1lKSkpIHsKCQkJcmV0ID0gLUVFWElTVDsKCQkJZ290byBvdXQ7CgkJfQoJfQoJCglsaXN0X2FkZF90YWlsKCZhbGctPmNyYV9saXN0LCAmY3J5cHRvX2FsZ19saXN0KTsKb3V0OgkKCXVwX3dyaXRlKCZjcnlwdG9fYWxnX3NlbSk7CglyZXR1cm4gcmV0Owp9CgppbnQgY3J5cHRvX3VucmVnaXN0ZXJfYWxnKHN0cnVjdCBjcnlwdG9fYWxnICphbGcpCnsKCWludCByZXQgPSAtRU5PRU5UOwoJc3RydWN0IGNyeXB0b19hbGcgKnE7CgkKCUJVR19PTighYWxnLT5jcmFfbW9kdWxlKTsKCQoJZG93bl93cml0ZSgmY3J5cHRvX2FsZ19zZW0pOwoJbGlzdF9mb3JfZWFjaF9lbnRyeShxLCAmY3J5cHRvX2FsZ19saXN0LCBjcmFfbGlzdCkgewoJCWlmIChhbGcgPT0gcSkgewoJCQlsaXN0X2RlbCgmYWxnLT5jcmFfbGlzdCk7CgkJCXJldCA9IDA7CgkJCWdvdG8gb3V0OwoJCX0KCX0Kb3V0OgkKCXVwX3dyaXRlKCZjcnlwdG9fYWxnX3NlbSk7CglyZXR1cm4gcmV0Owp9CgppbnQgY3J5cHRvX2FsZ19hdmFpbGFibGUoY29uc3QgY2hhciAqbmFtZSwgdTMyIGZsYWdzKQp7CglpbnQgcmV0ID0gMDsKCXN0cnVjdCBjcnlwdG9fYWxnICphbGcgPSBjcnlwdG9fYWxnX21vZF9sb29rdXAobmFtZSk7CgkKCWlmIChhbGcpIHsKCQljcnlwdG9fYWxnX3B1dChhbGcpOwoJCXJldCA9IDE7Cgl9CgkKCXJldHVybiByZXQ7Cn0KCnN0YXRpYyBpbnQgX19pbml0IGluaXRfY3J5cHRvKHZvaWQpCnsKCXByaW50ayhLRVJOX0lORk8gIkluaXRpYWxpemluZyBDcnlwdG9ncmFwaGljIEFQSVxuIik7CgljcnlwdG9faW5pdF9wcm9jKCk7CglyZXR1cm4gMDsKfQoKX19pbml0Y2FsbChpbml0X2NyeXB0byk7CgpFWFBPUlRfU1lNQk9MX0dQTChjcnlwdG9fcmVnaXN0ZXJfYWxnKTsKRVhQT1JUX1NZTUJPTF9HUEwoY3J5cHRvX3VucmVnaXN0ZXJfYWxnKTsKRVhQT1JUX1NZTUJPTF9HUEwoY3J5cHRvX2FsbG9jX3RmbSk7CkVYUE9SVF9TWU1CT0xfR1BMKGNyeXB0b19mcmVlX3RmbSk7CkVYUE9SVF9TWU1CT0xfR1BMKGNyeXB0b19hbGdfYXZhaWxhYmxlKTsK