LyoKICogU2NhdHRlcmxpc3QgQ3J5cHRvZ3JhcGhpYyBBUEkuCiAqCiAqIENvcHlyaWdodCAoYykgMjAwMiBKYW1lcyBNb3JyaXMgPGptb3JyaXNAaW50ZXJjb2RlLmNvbS5hdT4KICogQ29weXJpZ2h0IChjKSAyMDAyIERhdmlkIFMuIE1pbGxlciAoZGF2ZW1AcmVkaGF0LmNvbSkKICoKICogUG9ydGlvbnMgZGVyaXZlZCBmcm9tIENyeXB0b2FwaSwgYnkgQWxleGFuZGVyIEtqZWxkYWFzIDxhc3RvckBmYXN0Lm5vPgogKiBhbmQgTmV0dGxlLCBieSBOaWVscyBN9mxsZXIuCiAqCiAqIFRoaXMgcHJvZ3JhbSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0CiAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlCiAqIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlciB2ZXJzaW9uIDIgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgCiAqIGFueSBsYXRlciB2ZXJzaW9uLgogKgogKi8KI2luY2x1ZGUgPGxpbnV4L2luaXQuaD4KI2luY2x1ZGUgPGxpbnV4L2NyeXB0by5oPgojaW5jbHVkZSA8bGludXgvZXJybm8uaD4KI2luY2x1ZGUgPGxpbnV4L3J3c2VtLmg+CiNpbmNsdWRlIDxsaW51eC9zbGFiLmg+CiNpbmNsdWRlICJpbnRlcm5hbC5oIgoKTElTVF9IRUFEKGNyeXB0b19hbGdfbGlzdCk7CkRFQ0xBUkVfUldTRU0oY3J5cHRvX2FsZ19zZW0pOwoKc3RhdGljIGlubGluZSBpbnQgY3J5cHRvX2FsZ19nZXQoc3RydWN0IGNyeXB0b19hbGcgKmFsZykKewoJcmV0dXJuIHRyeV9pbmNfbW9kX2NvdW50KGFsZy0+Y3JhX21vZHVsZSk7Cn0KCnN0YXRpYyBpbmxpbmUgdm9pZCBjcnlwdG9fYWxnX3B1dChzdHJ1Y3QgY3J5cHRvX2FsZyAqYWxnKQp7CglpZiAoYWxnLT5jcmFfbW9kdWxlKQoJCV9fTU9EX0RFQ19VU0VfQ09VTlQoYWxnLT5jcmFfbW9kdWxlKTsKfQoKc3RydWN0IGNyeXB0b19hbGcgKmNyeXB0b19hbGdfbG9va3VwKGNvbnN0IGNoYXIgKm5hbWUpCnsKCXN0cnVjdCBjcnlwdG9fYWxnICpxLCAqYWxnID0gTlVMTDsKCglpZiAoIW5hbWUpCgkJcmV0dXJuIE5VTEw7CgkKCWRvd25fcmVhZCgmY3J5cHRvX2FsZ19zZW0pOwoJCglsaXN0X2Zvcl9lYWNoX2VudHJ5KHEsICZjcnlwdG9fYWxnX2xpc3QsIGNyYV9saXN0KSB7CgkJaWYgKCEoc3RyY21wKHEtPmNyYV9uYW1lLCBuYW1lKSkpIHsKCQkJaWYgKGNyeXB0b19hbGdfZ2V0KHEpKQoJCQkJYWxnID0gcTsKCQkJYnJlYWs7CgkJfQoJfQoJCgl1cF9yZWFkKCZjcnlwdG9fYWxnX3NlbSk7CglyZXR1cm4gYWxnOwp9CgpzdGF0aWMgaW50IGNyeXB0b19pbml0X2ZsYWdzKHN0cnVjdCBjcnlwdG9fdGZtICp0Zm0sIHUzMiBmbGFncykKewoJdGZtLT5jcnRfZmxhZ3MgPSAwOwoJCglzd2l0Y2ggKGNyeXB0b190Zm1fYWxnX3R5cGUodGZtKSkgewoJY2FzZSBDUllQVE9fQUxHX1RZUEVfQ0lQSEVSOgoJCXJldHVybiBjcnlwdG9faW5pdF9jaXBoZXJfZmxhZ3ModGZtLCBmbGFncyk7CgkJCgljYXNlIENSWVBUT19BTEdfVFlQRV9ESUdFU1Q6CgkJcmV0dXJuIGNyeXB0b19pbml0X2RpZ2VzdF9mbGFncyh0Zm0sIGZsYWdzKTsKCQkKCWNhc2UgQ1JZUFRPX0FMR19UWVBFX0NPTVBSRVNTOgoJCXJldHVybiBjcnlwdG9faW5pdF9jb21wcmVzc19mbGFncyh0Zm0sIGZsYWdzKTsKCQoJZGVmYXVsdDoKCQlicmVhazsKCX0KCQoJQlVHKCk7CglyZXR1cm4gLUVJTlZBTDsKfQoKc3RhdGljIGludCBjcnlwdG9faW5pdF9vcHMoc3RydWN0IGNyeXB0b190Zm0gKnRmbSkKewoJc3dpdGNoIChjcnlwdG9fdGZtX2FsZ190eXBlKHRmbSkpIHsKCWNhc2UgQ1JZUFRPX0FMR19UWVBFX0NJUEhFUjoKCQlyZXR1cm4gY3J5cHRvX2luaXRfY2lwaGVyX29wcyh0Zm0pOwoJCQoJY2FzZSBDUllQVE9fQUxHX1RZUEVfRElHRVNUOgoJCXJldHVybiBjcnlwdG9faW5pdF9kaWdlc3Rfb3BzKHRmbSk7CgkJCgljYXNlIENSWVBUT19BTEdfVFlQRV9DT01QUkVTUzoKCQlyZXR1cm4gY3J5cHRvX2luaXRfY29tcHJlc3Nfb3BzKHRmbSk7CgkKCWRlZmF1bHQ6CgkJYnJlYWs7Cgl9CgkKCUJVRygpOwoJcmV0dXJuIC1FSU5WQUw7Cn0KCnN0YXRpYyB2b2lkIGNyeXB0b19leGl0X29wcyhzdHJ1Y3QgY3J5cHRvX3RmbSAqdGZtKQp7Cglzd2l0Y2ggKGNyeXB0b190Zm1fYWxnX3R5cGUodGZtKSkgewoJY2FzZSBDUllQVE9fQUxHX1RZUEVfQ0lQSEVSOgoJCWNyeXB0b19leGl0X2NpcGhlcl9vcHModGZtKTsKCQlicmVhazsKCQkKCWNhc2UgQ1JZUFRPX0FMR19UWVBFX0RJR0VTVDoKCQljcnlwdG9fZXhpdF9kaWdlc3Rfb3BzKHRmbSk7CgkJYnJlYWs7CgkJCgljYXNlIENSWVBUT19BTEdfVFlQRV9DT01QUkVTUzoKCQljcnlwdG9fZXhpdF9jb21wcmVzc19vcHModGZtKTsKCQlicmVhazsKCQoJZGVmYXVsdDoKCQlCVUcoKTsKCQkKCX0KfQoKc3RydWN0IGNyeXB0b190Zm0gKmNyeXB0b19hbGxvY190Zm0oY29uc3QgY2hhciAqbmFtZSwgdTMyIGZsYWdzKQp7CglzdHJ1Y3QgY3J5cHRvX3RmbSAqdGZtID0gTlVMTDsKCXN0cnVjdCBjcnlwdG9fYWxnICphbGc7CgoJYWxnID0gY3J5cHRvX2FsZ19tb2RfbG9va3VwKG5hbWUpOwoJaWYgKGFsZyA9PSBOVUxMKQoJCWdvdG8gb3V0OwoJCgl0Zm0gPSBrbWFsbG9jKHNpemVvZigqdGZtKSArIGFsZy0+Y3JhX2N0eHNpemUsIEdGUF9LRVJORUwpOwoJaWYgKHRmbSA9PSBOVUxMKQoJCWdvdG8gb3V0X3B1dDsKCgltZW1zZXQodGZtLCAwLCBzaXplb2YoKnRmbSkgKyBhbGctPmNyYV9jdHhzaXplKTsKCQoJdGZtLT5fX2NydF9hbGcgPSBhbGc7CgkKCWlmIChjcnlwdG9faW5pdF9mbGFncyh0Zm0sIGZsYWdzKSkKCQlnb3RvIG91dF9mcmVlX3RmbTsKCQkKCWlmIChjcnlwdG9faW5pdF9vcHModGZtKSkgewoJCWNyeXB0b19leGl0X29wcyh0Zm0pOwoJCWdvdG8gb3V0X2ZyZWVfdGZtOwoJfQoKCWdvdG8gb3V0OwoKb3V0X2ZyZWVfdGZtOgoJa2ZyZWUodGZtKTsKCXRmbSA9IE5VTEw7Cm91dF9wdXQ6CgljcnlwdG9fYWxnX3B1dChhbGcpOwpvdXQ6CglyZXR1cm4gdGZtOwp9Cgp2b2lkIGNyeXB0b19mcmVlX3RmbShzdHJ1Y3QgY3J5cHRvX3RmbSAqdGZtKQp7CglzdHJ1Y3QgY3J5cHRvX2FsZyAqYWxnID0gdGZtLT5fX2NydF9hbGc7CglpbnQgc2l6ZSA9IHNpemVvZigqdGZtKSArIGFsZy0+Y3JhX2N0eHNpemU7CgoJY3J5cHRvX2V4aXRfb3BzKHRmbSk7CgljcnlwdG9fYWxnX3B1dChhbGcpOwoJbWVtc2V0KHRmbSwgMCwgc2l6ZSk7CglrZnJlZSh0Zm0pOwp9CgppbnQgY3J5cHRvX3JlZ2lzdGVyX2FsZyhzdHJ1Y3QgY3J5cHRvX2FsZyAqYWxnKQp7CglpbnQgcmV0ID0gMDsKCXN0cnVjdCBjcnlwdG9fYWxnICpxOwoJCglkb3duX3dyaXRlKCZjcnlwdG9fYWxnX3NlbSk7CgkKCWxpc3RfZm9yX2VhY2hfZW50cnkocSwgJmNyeXB0b19hbGdfbGlzdCwgY3JhX2xpc3QpIHsKCQlpZiAoIShzdHJjbXAocS0+Y3JhX25hbWUsIGFsZy0+Y3JhX25hbWUpKSkgewoJCQlyZXQgPSAtRUVYSVNUOwoJCQlnb3RvIG91dDsKCQl9Cgl9CgkKCWxpc3RfYWRkX3RhaWwoJmFsZy0+Y3JhX2xpc3QsICZjcnlwdG9fYWxnX2xpc3QpOwpvdXQ6CQoJdXBfd3JpdGUoJmNyeXB0b19hbGdfc2VtKTsKCXJldHVybiByZXQ7Cn0KCmludCBjcnlwdG9fdW5yZWdpc3Rlcl9hbGcoc3RydWN0IGNyeXB0b19hbGcgKmFsZykKewoJaW50IHJldCA9IC1FTk9FTlQ7CglzdHJ1Y3QgY3J5cHRvX2FsZyAqcTsKCQoJQlVHX09OKCFhbGctPmNyYV9tb2R1bGUpOwoJCglkb3duX3dyaXRlKCZjcnlwdG9fYWxnX3NlbSk7CglsaXN0X2Zvcl9lYWNoX2VudHJ5KHEsICZjcnlwdG9fYWxnX2xpc3QsIGNyYV9saXN0KSB7CgkJaWYgKGFsZyA9PSBxKSB7CgkJCWxpc3RfZGVsKCZhbGctPmNyYV9saXN0KTsKCQkJcmV0ID0gMDsKCQkJZ290byBvdXQ7CgkJfQoJfQpvdXQ6CQoJdXBfd3JpdGUoJmNyeXB0b19hbGdfc2VtKTsKCXJldHVybiByZXQ7Cn0KCmludCBjcnlwdG9fYWxnX2F2YWlsYWJsZShjb25zdCBjaGFyICpuYW1lLCB1MzIgZmxhZ3MpCnsKCWludCByZXQgPSAwOwoJc3RydWN0IGNyeXB0b19hbGcgKmFsZyA9IGNyeXB0b19hbGdfbW9kX2xvb2t1cChuYW1lKTsKCQoJaWYgKGFsZykgewoJCWNyeXB0b19hbGdfcHV0KGFsZyk7CgkJcmV0ID0gMTsKCX0KCQoJcmV0dXJuIHJldDsKfQoKc3RhdGljIGludCBfX2luaXQgaW5pdF9jcnlwdG8odm9pZCkKewoJcHJpbnRrKEtFUk5fSU5GTyAiSW5pdGlhbGl6aW5nIENyeXB0b2dyYXBoaWMgQVBJXG4iKTsKCWNyeXB0b19pbml0X3Byb2MoKTsKCXJldHVybiAwOwp9CgpfX2luaXRjYWxsKGluaXRfY3J5cHRvKTsKCkVYUE9SVF9TWU1CT0xfR1BMKGNyeXB0b19yZWdpc3Rlcl9hbGcpOwpFWFBPUlRfU1lNQk9MX0dQTChjcnlwdG9fdW5yZWdpc3Rlcl9hbGcpOwpFWFBPUlRfU1lNQk9MX0dQTChjcnlwdG9fYWxsb2NfdGZtKTsKRVhQT1JUX1NZTUJPTF9HUEwoY3J5cHRvX2ZyZWVfdGZtKTsKRVhQT1JUX1NZTUJPTF9HUEwoY3J5cHRvX2FsZ19hdmFpbGFibGUpOwo=