LyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLwovKiBpMmMtYWxnby1zaWJ5dGUuYyBpMmMgZHJpdmVyIGFsZ29yaXRobXMgZm9yIGJpdC1zaGlmdCBhZGFwdGVycwkJICAgICAqLwovKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovCi8qICAgQ29weXJpZ2h0IChDKSAyMDAxLDIwMDIsMjAwMyBCcm9hZGNvbSBDb3Jwb3JhdGlvbgogICAgIENvcHlyaWdodCAoQykgMTk5NS0yMDAwIFNpbW9uIEcuIFZvZ2wKCiAgICBUaGlzIHByb2dyYW0gaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeQogICAgaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkKICAgIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlciB2ZXJzaW9uIDIgb2YgdGhlIExpY2Vuc2UsIG9yCiAgICAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLgoKICAgIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLAogICAgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YKICAgIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUKICAgIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuCgogICAgWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKICAgIGFsb25nIHdpdGggdGhpcyBwcm9ncmFtOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlCiAgICBGb3VuZGF0aW9uLCBJbmMuLCA2NzUgTWFzcyBBdmUsIENhbWJyaWRnZSwgTUEgMDIxMzksIFVTQS4JCSAgICAgKi8KLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLwoKLyogV2l0aCBzb21lIGNoYW5nZXMgZnJvbSBLefZzdGkgTeRsa2tpIDxrbWFsa2tpQGNjLmh1dC5maT4gYW5kIGV2ZW4KICAgRnJvZG8gTG9vaWphYXJkIDxmcm9kb2xAZGRzLm5sPi4gICovCgovKiBQb3J0ZWQgZm9yIFNpQnl0ZSBTT0NzIGJ5IEJyb2FkY29tIENvcnBvcmF0aW9uLiAgKi8KCiNpbmNsdWRlIDxsaW51eC9rZXJuZWwuaD4KI2luY2x1ZGUgPGxpbnV4L21vZHVsZS5oPgojaW5jbHVkZSA8bGludXgvaW5pdC5oPgoKI2luY2x1ZGUgPGFzbS9pby5oPgojaW5jbHVkZSA8YXNtL3NpYnl0ZS9zYjEyNTBfcmVncy5oPgojaW5jbHVkZSA8YXNtL3NpYnl0ZS9zYjEyNTBfc21idXMuaD4KCiNpbmNsdWRlIDxsaW51eC9pMmMuaD4KI2luY2x1ZGUgPGxpbnV4L2kyYy1hbGdvLXNpYnl0ZS5oPgoKLyogLS0tLS0gZ2xvYmFsIGRlZmluZXMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi8KI2RlZmluZSBTTUJfQ1NSKGEscikgKChsb25nKShhLT5yZWdfYmFzZSArIHIpKQoKLyogLS0tLS0gZ2xvYmFsIHZhcmlhYmxlcyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0JKi8KCi8qIG1vZHVsZSBwYXJhbWV0ZXJzOgogKi8Kc3RhdGljIGludCBiaXRfc2Nhbj0wOwkvKiBoYXZlIGEgbG9vayBhdCB3aGF0J3MgaGFuZ2luZyAncm91bmQJCSovCgoKc3RhdGljIGludCBzbWJ1c194ZmVyKHN0cnVjdCBpMmNfYWRhcHRlciAqaTJjX2FkYXAsIHUxNiBhZGRyLCAKICAgICAgICAgICAgICAgICAgICAgIHVuc2lnbmVkIHNob3J0IGZsYWdzLCBjaGFyIHJlYWRfd3JpdGUsCiAgICAgICAgICAgICAgICAgICAgICB1OCBjb21tYW5kLCBpbnQgc2l6ZSwgdW5pb24gaTJjX3NtYnVzX2RhdGEgKiBkYXRhKQp7CglzdHJ1Y3QgaTJjX2FsZ29fc2lieXRlX2RhdGEgKmFkYXAgPSBpMmNfYWRhcC0+YWxnb19kYXRhOwogICAgICAgIGludCBkYXRhX2J5dGVzID0gMDsKICAgICAgICBpbnQgZXJyb3I7CgogICAgICAgIHdoaWxlIChjc3JfaW4zMihTTUJfQ1NSKGFkYXAsIFJfU01CX1NUQVRVUykpICYgTV9TTUJfQlVTWSkKICAgICAgICAgICAgICAgIDsKCiAgICAgICAgc3dpdGNoIChzaXplKSB7CiAgICAgICAgY2FzZSBJMkNfU01CVVNfUVVJQ0s6CiAgICAgICAgICAgICAgICBjc3Jfb3V0MzIoKFZfU01CX0FERFIoYWRkcikgfCAocmVhZF93cml0ZSA9PSBJMkNfU01CVVNfUkVBRCA/IE1fU01CX1FEQVRBIDogMCkgfAoJCQkgICBWX1NNQl9UVF9RVUlDS0NNRCksIFNNQl9DU1IoYWRhcCwgUl9TTUJfU1RBUlQpKTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgSTJDX1NNQlVTX0JZVEU6CiAgICAgICAgICAgICAgICBpZiAocmVhZF93cml0ZSA9PSBJMkNfU01CVVNfUkVBRCkgewogICAgICAgICAgICAgICAgICAgICAgICBjc3Jfb3V0MzIoKFZfU01CX0FERFIoYWRkcikgfCBWX1NNQl9UVF9SRDFCWVRFKSwKCQkJCSAgU01CX0NTUihhZGFwLCBSX1NNQl9TVEFSVCkpOwogICAgICAgICAgICAgICAgICAgICAgICBkYXRhX2J5dGVzID0gMTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGNzcl9vdXQzMihWX1NNQl9DTUQoY29tbWFuZCksIFNNQl9DU1IoYWRhcCwgUl9TTUJfQ01EKSk7CiAgICAgICAgICAgICAgICAgICAgICAgIGNzcl9vdXQzMigoVl9TTUJfQUREUihhZGRyKSB8IFZfU01CX1RUX1dSMUJZVEUpLAoJCQkJICBTTUJfQ1NSKGFkYXAsIFJfU01CX1NUQVJUKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIEkyQ19TTUJVU19CWVRFX0RBVEE6CiAgICAgICAgICAgICAgICBjc3Jfb3V0MzIoVl9TTUJfQ01EKGNvbW1hbmQpLCBTTUJfQ1NSKGFkYXAsIFJfU01CX0NNRCkpOwogICAgICAgICAgICAgICAgaWYgKHJlYWRfd3JpdGUgPT0gSTJDX1NNQlVTX1JFQUQpIHsKICAgICAgICAgICAgICAgICAgICAgICAgY3NyX291dDMyKChWX1NNQl9BRERSKGFkZHIpIHwgVl9TTUJfVFRfQ01EX1JEMUJZVEUpLAoJCQkJICBTTUJfQ1NSKGFkYXAsIFJfU01CX1NUQVJUKSk7CiAgICAgICAgICAgICAgICAgICAgICAgIGRhdGFfYnl0ZXMgPSAxOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgY3NyX291dDMyKFZfU01CX0xCKGRhdGEtPmJ5dGUpLCBTTUJfQ1NSKGFkYXAsIFJfU01CX0RBVEEpKTsKICAgICAgICAgICAgICAgICAgICAgICAgY3NyX291dDMyKChWX1NNQl9BRERSKGFkZHIpIHwgVl9TTUJfVFRfV1IyQllURSksCgkJCQkgIFNNQl9DU1IoYWRhcCwgUl9TTUJfU1RBUlQpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgSTJDX1NNQlVTX1dPUkRfREFUQToKICAgICAgICAgICAgICAgIGNzcl9vdXQzMihWX1NNQl9DTUQoY29tbWFuZCksIFNNQl9DU1IoYWRhcCwgUl9TTUJfQ01EKSk7CiAgICAgICAgICAgICAgICBpZiAocmVhZF93cml0ZSA9PSBJMkNfU01CVVNfUkVBRCkgewogICAgICAgICAgICAgICAgICAgICAgICBjc3Jfb3V0MzIoKFZfU01CX0FERFIoYWRkcikgfCBWX1NNQl9UVF9DTURfUkQyQllURSksCgkJCQkgIFNNQl9DU1IoYWRhcCwgUl9TTUJfU1RBUlQpKTsKICAgICAgICAgICAgICAgICAgICAgICAgZGF0YV9ieXRlcyA9IDI7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICBjc3Jfb3V0MzIoVl9TTUJfTEIoZGF0YS0+d29yZCAmIDB4ZmYpLCBTTUJfQ1NSKGFkYXAsIFJfU01CX0RBVEEpKTsKICAgICAgICAgICAgICAgICAgICAgICAgY3NyX291dDMyKFZfU01CX01CKGRhdGEtPndvcmQgPj4gOCksIFNNQl9DU1IoYWRhcCwgUl9TTUJfREFUQSkpOwogICAgICAgICAgICAgICAgICAgICAgICBjc3Jfb3V0MzIoKFZfU01CX0FERFIoYWRkcikgfCBWX1NNQl9UVF9XUjJCWVRFKSwKCQkJCSAgU01CX0NTUihhZGFwLCBSX1NNQl9TVEFSVCkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgIHJldHVybiAtMTsgICAgICAvKiBYWFhLVyBiZXR0ZXIgZXJyb3IgY29kZT8gKi8KICAgICAgICB9CgogICAgICAgIHdoaWxlIChjc3JfaW4zMihTTUJfQ1NSKGFkYXAsIFJfU01CX1NUQVRVUykpICYgTV9TTUJfQlVTWSkKICAgICAgICAgICAgICAgIDsKCiAgICAgICAgZXJyb3IgPSBjc3JfaW4zMihTTUJfQ1NSKGFkYXAsIFJfU01CX1NUQVRVUykpOwogICAgICAgIGlmIChlcnJvciAmIE1fU01CX0VSUk9SKSB7CiAgICAgICAgICAgICAgICAvKiBDbGVhciBlcnJvciBiaXQgYnkgd3JpdGluZyBhIDEgKi8KICAgICAgICAgICAgICAgIGNzcl9vdXQzMihNX1NNQl9FUlJPUiwgU01CX0NTUihhZGFwLCBSX1NNQl9TVEFUVVMpKTsKICAgICAgICAgICAgICAgIHJldHVybiAtMTsgICAgICAvKiBYWFhLVyBiZXR0ZXIgZXJyb3IgY29kZT8gKi8KICAgICAgICB9CgogICAgICAgIGlmIChkYXRhX2J5dGVzID09IDEpCiAgICAgICAgICAgICAgICBkYXRhLT5ieXRlID0gY3NyX2luMzIoU01CX0NTUihhZGFwLCBSX1NNQl9EQVRBKSkgJiAweGZmOwogICAgICAgIGlmIChkYXRhX2J5dGVzID09IDIpCiAgICAgICAgICAgICAgICBkYXRhLT53b3JkID0gY3NyX2luMzIoU01CX0NTUihhZGFwLCBSX1NNQl9EQVRBKSkgJiAweGZmZmY7CgogICAgICAgIHJldHVybiAwOwp9CgpzdGF0aWMgaW50IGFsZ29fY29udHJvbChzdHJ1Y3QgaTJjX2FkYXB0ZXIgKmFkYXB0ZXIsIAoJdW5zaWduZWQgaW50IGNtZCwgdW5zaWduZWQgbG9uZyBhcmcpCnsKCXJldHVybiAwOwp9CgpzdGF0aWMgdTMyIGJpdF9mdW5jKHN0cnVjdCBpMmNfYWRhcHRlciAqYWRhcCkKewoJcmV0dXJuIChJMkNfRlVOQ19TTUJVU19RVUlDSyB8IEkyQ19GVU5DX1NNQlVTX0JZVEUgfAogICAgICAgICAgICAgICAgSTJDX0ZVTkNfU01CVVNfQllURV9EQVRBIHwgSTJDX0ZVTkNfU01CVVNfV09SRF9EQVRBKTsKfQoKCi8qIC0tLS0tZXhwb3J0ZWQgYWxnb3JpdGhtIGRhdGE6IC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0JKi8KCnN0YXRpYyBzdHJ1Y3QgaTJjX2FsZ29yaXRobSBpMmNfc2lieXRlX2FsZ28gPSB7Cgkuc21idXNfeGZlcgk9IHNtYnVzX3hmZXIsCgkuYWxnb19jb250cm9sCT0gYWxnb19jb250cm9sLCAvKiBpb2N0bCAqLwoJLmZ1bmN0aW9uYWxpdHkJPSBiaXRfZnVuYywKfTsKCi8qIAogKiByZWdpc3RlcmluZyBmdW5jdGlvbnMgdG8gbG9hZCBhbGdvcml0aG1zIGF0IHJ1bnRpbWUgCiAqLwppbnQgaTJjX3NpYnl0ZV9hZGRfYnVzKHN0cnVjdCBpMmNfYWRhcHRlciAqaTJjX2FkYXAsIGludCBzcGVlZCkKewoJaW50IGk7CglzdHJ1Y3QgaTJjX2FsZ29fc2lieXRlX2RhdGEgKmFkYXAgPSBpMmNfYWRhcC0+YWxnb19kYXRhOwoKCS8qIHJlZ2lzdGVyIG5ldyBhZGFwdGVyIHRvIGkyYyBtb2R1bGUuLi4gKi8KCWkyY19hZGFwLT5hbGdvID0gJmkyY19zaWJ5dGVfYWxnbzsKICAgICAgICAKICAgICAgICAvKiBTZXQgdGhlIGZyZXF1ZW5jeSB0byAxMDAga0h6ICovCiAgICAgICAgY3NyX291dDMyKHNwZWVkLCBTTUJfQ1NSKGFkYXAsUl9TTUJfRlJFUSkpOwogICAgICAgIGNzcl9vdXQzMigwLCBTTUJfQ1NSKGFkYXAsUl9TTUJfQ09OVFJPTCkpOwoKCS8qIHNjYW4gYnVzICovCglpZiAoYml0X3NjYW4pIHsKICAgICAgICAgICAgICAgIHVuaW9uIGkyY19zbWJ1c19kYXRhIGRhdGE7CiAgICAgICAgICAgICAgICBpbnQgcmM7CgkJcHJpbnRrKEtFUk5fSU5GTyAiIGkyYy1hbGdvLXNpYnl0ZS5vOiBzY2FubmluZyBidXMgJXMuXG4iLAoJCSAgICAgICBpMmNfYWRhcC0+bmFtZSk7CgkJZm9yIChpID0gMHgwMDsgaSA8IDB4N2Y7IGkrKykgewogICAgICAgICAgICAgICAgICAgICAgICAvKiBYWFhLVyBpcyB0aGlzIGEgcmVhbGlzdGljIHByb2JlPyAqLwogICAgICAgICAgICAgICAgICAgICAgICByYyA9IHNtYnVzX3hmZXIoaTJjX2FkYXAsIGksIDAsIEkyQ19TTUJVU19SRUFELCAwLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSTJDX1NNQlVTX0JZVEVfREFUQSwgJmRhdGEpOwoJCQlpZiAoIXJjKSB7CgkJCQlwcmludGsoIiglMDJ4KSIsaSk7IAoJCQl9IGVsc2UgCgkJCQlwcmludGsoIi4iKTsgCgkJfQoJCXByaW50aygiXG4iKTsKCX0KCglpMmNfYWRkX2FkYXB0ZXIoaTJjX2FkYXApOwoKCXJldHVybiAwOwp9CgoKaW50IGkyY19zaWJ5dGVfZGVsX2J1cyhzdHJ1Y3QgaTJjX2FkYXB0ZXIgKmFkYXApCnsKCWludCByZXM7CgoJaWYgKChyZXMgPSBpMmNfZGVsX2FkYXB0ZXIoYWRhcCkpIDwgMCkKCQlyZXR1cm4gcmVzOwoKCXJldHVybiAwOwp9CgppbnQgX19pbml0IGkyY19hbGdvX3NpYnl0ZV9pbml0ICh2b2lkKQp7CglwcmludGsoImkyYy1hbGdvLXNpYnl0ZS5vOiBpMmMgU2lCeXRlIGFsZ29yaXRobSBtb2R1bGVcbiIpOwoJcmV0dXJuIDA7Cn0KCgpFWFBPUlRfU1lNQk9MKGkyY19zaWJ5dGVfYWRkX2J1cyk7CkVYUE9SVF9TWU1CT0woaTJjX3NpYnl0ZV9kZWxfYnVzKTsKCiNpZmRlZiBNT0RVTEUKTU9EVUxFX0FVVEhPUigiS2lwIFdhbGtlciwgQnJvYWRjb20gQ29ycC4iKTsKTU9EVUxFX0RFU0NSSVBUSU9OKCJTaUJ5dGUgSTJDLUJ1cyBhbGdvcml0aG0iKTsKTU9EVUxFX1BBUk0oYml0X3NjYW4sICJpIik7Ck1PRFVMRV9QQVJNX0RFU0MoYml0X3NjYW4sICJTY2FuIGZvciBhY3RpdmUgY2hpcHMgb24gdGhlIGJ1cyIpOwpNT0RVTEVfTElDRU5TRSgiR1BMIik7CgppbnQgaW5pdF9tb2R1bGUodm9pZCkgCnsKCXJldHVybiBpMmNfYWxnb19zaWJ5dGVfaW5pdCgpOwp9Cgp2b2lkIGNsZWFudXBfbW9kdWxlKHZvaWQpIAp7Cn0KI2VuZGlmCg==