LyoKICogSUJNIEFTTSBTZXJ2aWNlIFByb2Nlc3NvciBEZXZpY2UgRHJpdmVyCiAqCiAqIFRoaXMgcHJvZ3JhbSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5CiAqIGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5CiAqIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlciB2ZXJzaW9uIDIgb2YgdGhlIExpY2Vuc2UsIG9yCiAqIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uCiAqCiAqIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLAogKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZgogKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlCiAqIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIGFsb25nIHdpdGggdGhpcyBwcm9ncmFtOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlCiAqIEZvdW5kYXRpb24sIEluYy4sIDU5IFRlbXBsZSBQbGFjZSAtIFN1aXRlIDMzMCwgQm9zdG9uLCBNQSAwMjExMS0xMzA3LCBVU0EuCiAqCiAqIENvcHlyaWdodCAoQykgSUJNIENvcnBvcmF0aW9uLCAyMDA0CiAqCiAqIEF1dGhvcjogTWF4IEFzYvZjayA8YW1heEB1cy5pYm0uY29tPiAKICoKICovCgovKiBDb25kb3Igc2VydmljZSBwcm9jZXNzb3Igc3BlY2lmaWMgaGFyZHdhcmUgZGVmaW5pdGlvbnMgKi8KCiNpZm5kZWYgX19JQk1BU01fQ09ORE9SX0hfXwojZGVmaW5lIF9fSUJNQVNNX0NPTkRPUl9IX18KCiNpbmNsdWRlIDxhc20vaW8uaD4KCiNkZWZpbmUgVkVORE9SSURfSUJNCTB4MTAxNAojZGVmaW5lIERFVklDRUlEX1JTQQkweDAxMEYKCiNkZWZpbmUgR0VUX01GQV9BRERSKHgpICAoeCAmIDB4RkZGRkZGMDApCgojZGVmaW5lIE1BSUxCT1hfRlVMTCh4KSAgKHggJiAweDAwMDAwMDAxKQoKI2RlZmluZSBOT19NRkFTX0FWQUlMQUJMRSAgICAgMHhGRkZGRkZGRgoKCiNkZWZpbmUgSU5CT1VORF9RVUVVRV9QT1JUICAgMHg0MCAgLyogY29udGFpbnMgYWRkcmVzcyBvZiBuZXh0IGZyZWUgTUZBICovCiNkZWZpbmUgT1VUQk9VTkRfUVVFVUVfUE9SVCAgMHg0NCAgLyogY29udGFpbnMgYWRkcmVzcyBvZiBwb3N0ZWQgTUZBICAgICovCgojZGVmaW5lIFNQX0lOVFJfTUFTSwkweDAwMDAwMDA4CiNkZWZpbmUgVUFSVF9JTlRSX01BU0sJMHgwMDAwMDAxMAoKI2RlZmluZSBJTlRSX1NUQVRVU19SRUdJU1RFUiAgIDB4MTNBMAojZGVmaW5lIElOVFJfQ09OVFJPTF9SRUdJU1RFUiAgMHgxM0E0CgojZGVmaW5lIFNDT1VUX0NPTV9BX0JBU0UgICAgICAgICAweDAwMDAKI2RlZmluZSBTQ09VVF9DT01fQl9CQVNFICAgICAgICAgMHgwMTAwICAgCiNkZWZpbmUgU0NPVVRfQ09NX0NfQkFTRSAgICAgICAgIDB4MDIwMCAgIAojZGVmaW5lIFNDT1VUX0NPTV9EX0JBU0UgICAgICAgICAweDAzMDAgICAKCnN0YXRpYyBpbmxpbmUgaW50IHNwX2ludGVycnVwdF9wZW5kaW5nKHZvaWQgX19pb21lbSAqYmFzZV9hZGRyZXNzKQp7CglyZXR1cm4gU1BfSU5UUl9NQVNLICYgcmVhZGwoYmFzZV9hZGRyZXNzICsgSU5UUl9TVEFUVVNfUkVHSVNURVIpOwp9CgpzdGF0aWMgaW5saW5lIGludCB1YXJ0X2ludGVycnVwdF9wZW5kaW5nKHZvaWQgX19pb21lbSAqYmFzZV9hZGRyZXNzKQp7CglyZXR1cm4gVUFSVF9JTlRSX01BU0sgJiByZWFkbChiYXNlX2FkZHJlc3MgKyBJTlRSX1NUQVRVU19SRUdJU1RFUik7Cn0KCnN0YXRpYyBpbmxpbmUgdm9pZCBpYm1hc21fZW5hYmxlX2ludGVycnVwdHModm9pZCBfX2lvbWVtICpiYXNlX2FkZHJlc3MsIGludCBtYXNrKQp7Cgl2b2lkIF9faW9tZW0gKmN0cmxfcmVnID0gYmFzZV9hZGRyZXNzICsgSU5UUl9DT05UUk9MX1JFR0lTVEVSOwoJd3JpdGVsKCByZWFkbChjdHJsX3JlZykgJiB+bWFzaywgY3RybF9yZWcpOwp9CgpzdGF0aWMgaW5saW5lIHZvaWQgaWJtYXNtX2Rpc2FibGVfaW50ZXJydXB0cyh2b2lkIF9faW9tZW0gKmJhc2VfYWRkcmVzcywgaW50IG1hc2spCnsKCXZvaWQgX19pb21lbSAqY3RybF9yZWcgPSBiYXNlX2FkZHJlc3MgKyBJTlRSX0NPTlRST0xfUkVHSVNURVI7Cgl3cml0ZWwoIHJlYWRsKGN0cmxfcmVnKSB8IG1hc2ssIGN0cmxfcmVnKTsKfQoKc3RhdGljIGlubGluZSB2b2lkIGVuYWJsZV9zcF9pbnRlcnJ1cHRzKHZvaWQgX19pb21lbSAqYmFzZV9hZGRyZXNzKQp7CglpYm1hc21fZW5hYmxlX2ludGVycnVwdHMoYmFzZV9hZGRyZXNzLCBTUF9JTlRSX01BU0spOwp9CgpzdGF0aWMgaW5saW5lIHZvaWQgZGlzYWJsZV9zcF9pbnRlcnJ1cHRzKHZvaWQgX19pb21lbSAqYmFzZV9hZGRyZXNzKQp7CglpYm1hc21fZGlzYWJsZV9pbnRlcnJ1cHRzKGJhc2VfYWRkcmVzcywgU1BfSU5UUl9NQVNLKTsKfQoKc3RhdGljIGlubGluZSB2b2lkIGVuYWJsZV91YXJ0X2ludGVycnVwdHModm9pZCBfX2lvbWVtICpiYXNlX2FkZHJlc3MpCnsKCWlibWFzbV9lbmFibGVfaW50ZXJydXB0cyhiYXNlX2FkZHJlc3MsIFVBUlRfSU5UUl9NQVNLKTsgCn0KCnN0YXRpYyBpbmxpbmUgdm9pZCBkaXNhYmxlX3VhcnRfaW50ZXJydXB0cyh2b2lkIF9faW9tZW0gKmJhc2VfYWRkcmVzcykKewoJaWJtYXNtX2Rpc2FibGVfaW50ZXJydXB0cyhiYXNlX2FkZHJlc3MsIFVBUlRfSU5UUl9NQVNLKTsgCn0KCiNkZWZpbmUgdmFsaWRfbWZhKG1mYSkJKCAobWZhKSAhPSBOT19NRkFTX0FWQUlMQUJMRSApCgpzdGF0aWMgaW5saW5lIHUzMiBnZXRfbWZhX291dGJvdW5kKHZvaWQgX19pb21lbSAqYmFzZV9hZGRyZXNzKQp7CglpbnQgcmV0cnk7Cgl1MzIgbWZhOwoKCWZvciAocmV0cnk9MDsgcmV0cnk8PTEwOyByZXRyeSsrKSB7CgkJbWZhID0gcmVhZGwoYmFzZV9hZGRyZXNzICsgT1VUQk9VTkRfUVVFVUVfUE9SVCk7CgkJaWYgKHZhbGlkX21mYShtZmEpKQoJCQlicmVhazsKCX0KCXJldHVybiBtZmE7Cn0KCnN0YXRpYyBpbmxpbmUgdm9pZCBzZXRfbWZhX291dGJvdW5kKHZvaWQgX19pb21lbSAqYmFzZV9hZGRyZXNzLCB1MzIgbWZhKQp7CiAgIAl3cml0ZWwobWZhLCBiYXNlX2FkZHJlc3MgKyBPVVRCT1VORF9RVUVVRV9QT1JUKTsKfQoKc3RhdGljIGlubGluZSB1MzIgZ2V0X21mYV9pbmJvdW5kKHZvaWQgX19pb21lbSAqYmFzZV9hZGRyZXNzKQp7Cgl1MzIgbWZhID0gcmVhZGwoYmFzZV9hZGRyZXNzICsgSU5CT1VORF9RVUVVRV9QT1JUKTsKCglpZiAoTUFJTEJPWF9GVUxMKG1mYSkpCgkJcmV0dXJuIDA7CgoJcmV0dXJuIG1mYTsKfQoKc3RhdGljIGlubGluZSB2b2lkIHNldF9tZmFfaW5ib3VuZCh2b2lkIF9faW9tZW0gKmJhc2VfYWRkcmVzcywgdTMyIG1mYSkKewogICAJd3JpdGVsKG1mYSwgYmFzZV9hZGRyZXNzICsgSU5CT1VORF9RVUVVRV9QT1JUKTsKfQoKc3RhdGljIGlubGluZSBzdHJ1Y3QgaTJvX21lc3NhZ2UgKmdldF9pMm9fbWVzc2FnZSh2b2lkIF9faW9tZW0gKmJhc2VfYWRkcmVzcywgdTMyIG1mYSkKewoJcmV0dXJuIChzdHJ1Y3QgaTJvX21lc3NhZ2UgKikoR0VUX01GQV9BRERSKG1mYSkgKyBiYXNlX2FkZHJlc3MpOwp9CgojZW5kaWYgLyogX19JQk1BU01fQ09ORE9SX0hfXyAqLwo=