LyoKICogRE9TIGRldmljZXMKICoKICogQ29weXJpZ2h0IDE5OTkgT3ZlIEvldmVuCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IKICogbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXIKICogdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLAogKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZgogKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVQogKiBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljCiAqIExpY2Vuc2UgYWxvbmcgd2l0aCB0aGlzIGxpYnJhcnk7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUKICogRm91bmRhdGlvbiwgSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEsIFVTQQogKi8KCiNpbmNsdWRlIDxzdGRsaWIuaD4KI2luY2x1ZGUgPHN0cmluZy5oPgojaW5jbHVkZSAid2luZS93aW5iYXNlMTYuaCIKI2luY2x1ZGUgImRvc2V4ZS5oIgojaW5jbHVkZSAid2luZS9kZWJ1Zy5oIgoKI2luY2x1ZGUgInBzaHBhY2sxLmgiCgovKiBXYXJuaW5nOiBuZWVkIHRvIHJldHVybiBMT0wgcHRyIHcvIG9mZnNldCAwICgmcHRyX2ZpcnN0X0RQQikgdG8gcHJvZ3JhbXMgISAqLwp0eXBlZGVmIHN0cnVjdCBfRE9TX0xJU1RPRkxJU1RTCnsKICAgIFdPUkQgIENYX0ludDIxXzVlMDE7ICAgICAgICAvKiAtMjRkIGNvbnRlbnRzIG9mIENYIGZyb20gSU5UIDIxL0FYPTVFMDFoICovCiAgICBXT1JEICBMUlVfY291bnRfRkNCX2NhY2hlOyAgLyogLTIyZCAqLwogICAgV09SRCAgTFJVX2NvdW50X0ZDQl9vcGVuOyAgIC8qIC0yMGQgKi8KICAgIERXT1JEIE9FTV9mdW5jX2hhbmRsZXI7ICAgICAvKiAtMThkIE9FTSBmdW5jdGlvbiBvZiBJTlQgMjEvQUg9RjhoICovCiAgICBXT1JEICBJTlQyMV9vZmZzZXQ7ICAgICAgICAgLyogLTE0ZCBvZmZzZXQgaW4gRE9TIENTIG9mIGNvZGUgdG8gcmV0dXJuIGZyb20gSU5UIDIxIGNhbGwgKi8KICAgIFdPUkQgIHNoYXJpbmdfcmV0cnlfY291bnQ7ICAvKiAtMTJkICovCiAgICBXT1JEICBzaGFyaW5nX3JldHJ5X2RlbGF5OyAgLyogLTEwZCAqLwogICAgRFdPUkQgcHRyX2Rpc2tfYnVmOyAgICAgICAgIC8qIC04ZCBwdHIgdG8gY3VycmVudCBkaXNrIGJ1ZiAqLwogICAgV09SRCAgb2Zmc191bnJlYWRfQ09OOyAgICAgIC8qIC00ZCBwb2ludGVyIGluIERPUyBkYXRhIHNlZ21lbnQgb2YgdW5yZWFkIENPTiBpbnB1dCAqLwogICAgV09SRCAgc2VnX2ZpcnN0X01DQjsgICAgICAgIC8qIC0yZCAqLwogICAgRFdPUkQgcHRyX2ZpcnN0X0RQQjsgICAgICAgIC8qIDAwICovCiAgICBEV09SRCBwdHJfZmlyc3RfU3lzRmlsZVRhYmxlOyAvKiAwNCAqLwogICAgRFdPUkQgcHRyX2Nsb2NrX2Rldl9oZHI7ICAgIC8qIDA4ICovCiAgICBEV09SRCBwdHJfQ09OX2Rldl9oZHI7ICAgICAgLyogMEMgKi8KICAgIFdPUkQgIG1heF9ieXRlX3Blcl9zZWM7ICAgICAvKiAxMCBtYXhpbXVtIGJ5dGVzIHBlciBzZWN0b3Igb2YgYW55IGJsb2NrIGRldmljZSAqLwogICAgRFdPUkQgcHRyX2Rpc2tfYnVmX2luZm87ICAgIC8qIDEyICovCiAgICBEV09SRCBwdHJfYXJyYXlfQ0RTOyAgICAgICAgLyogMTYgY3VycmVudCBkaXJlY3Rvcnkgc3RydWN0dXJlICovCiAgICBEV09SRCBwdHJfc3lzX0ZDQjsgICAgICAgICAgLyogMUEgKi8KICAgIFdPUkQgIG5yX3Byb3RlY3RfRkNCOyAgICAgICAvKiAxRSAqLwogICAgQllURSAgbnJfYmxvY2tfZGV2OyAgICAgICAgIC8qIDIwICovCiAgICBCWVRFICBucl9hdmFpbF9kcml2ZV9sZXR0ZXJzOyAvKiAyMSAqLwogICAgRE9TX0RFVklDRV9IRUFERVIgTlVMX2RldjsgIC8qIDIyICovCiAgICBCWVRFICBucl9kcml2ZXNfSk9JTmVkOyAgICAgLyogMzQgKi8KICAgIFdPUkQgIHB0cl9zcGVjX3ByZ19uYW1lczsgICAvKiAzNSAqLwogICAgRFdPUkQgcHRyX1NFVFZFUl9wcmdfbGlzdDsgIC8qIDM3ICovCiAgICBXT1JEIERPU19ISUdIX0EyMF9mdW5jX29mZnM7LyogM0IgKi8KICAgIFdPUkQgUFNQX2xhc3RfZXhlYzsgICAgICAgICAvKiAzRCBpZiBET1MgaW4gSE1BOiBQU1Agb2YgcHJvZ3JhbSBleGVjdXRlZCBsYXN0OyBpZiBET1MgbG93OiAwMDAwaCAqLwogICAgV09SRCBCVUZGRVJTX3ZhbDsgICAgICAgICAgIC8qIDNGICovCiAgICBXT1JEIEJVRkZFUlNfbnJfbG9va2FoZWFkOyAgLyogNDEgKi8KICAgIEJZVEUgYm9vdF9kcml2ZTsgICAgICAgICAgICAvKiA0MyAqLwogICAgQllURSBmbGFnX0RXT1JEX21vdmVzOyAgICAgIC8qIDQ0IDAxaCBmb3IgMzg2KywgMDBoIG90aGVyd2lzZSAqLwogICAgV09SRCBzaXplX2V4dGVuZGVkX21lbTsgICAgIC8qIDQ1IHNpemUgb2YgZXh0ZW5kZWQgbWVtIGluIEtCICovCiAgICBTRUdQVFIgd2luZV9ybV9sb2w7ICAgICAgICAgLyogLS0gd2luZTogUmVhbCBtb2RlIHBvaW50ZXIgdG8gTE9MICovCiAgICBTRUdQVFIgd2luZV9wbV9sb2w7ICAgICAgICAgLyogLS0gd2luZTogUHJvdGVjdGVkIG1vZGUgcG9pbnRlciB0byBMT0wgKi8KfSBET1NfTElTVE9GTElTVFM7CgojaW5jbHVkZSAicG9wcGFjay5oIgoKI2RlZmluZSBDT05fQlVGRkVSIDEyOAoKZW51bSBzdHJhdGVneSB7IFNZU1RFTV9TVFJBVEVHWV9OVUwsIFNZU1RFTV9TVFJBVEVHWV9DT04sIE5CX1NZU1RFTV9TVFJBVEVHSUVTIH07CgpzdGF0aWMgdm9pZCAqc3RyYXRlZ3lfZGF0YVtOQl9TWVNURU1fU1RSQVRFR0lFU107CgojZGVmaW5lIExKTVAgMHhlYQoKCi8qIHByb3RvdHlwZXMgKi8Kc3RhdGljIHZvaWQgV0lOQVBJIG51bF9zdHJhdGVneShDT05URVhUODYqY3R4KTsKc3RhdGljIHZvaWQgV0lOQVBJIG51bF9pbnRlcnJ1cHQoQ09OVEVYVDg2KmN0eCk7CnN0YXRpYyB2b2lkIFdJTkFQSSBjb25fc3RyYXRlZ3koQ09OVEVYVDg2KmN0eCk7CnN0YXRpYyB2b2lkIFdJTkFQSSBjb25faW50ZXJydXB0KENPTlRFWFQ4NipjdHgpOwoKLyogZGV2aWNlcyAqLwpzdGF0aWMgY29uc3QgV0lORURFViBkZXZzW10gPQp7CiAgeyAiTlVMICAgICAiLAogICAgQVRUUl9DSEFSfEFUVFJfTlVMfEFUVFJfREVWSUNFLAogICAgbnVsX3N0cmF0ZWd5LCBudWxfaW50ZXJydXB0IH0sCgogIHsgIkNPTiAgICAgIiwKICAgIEFUVFJfQ0hBUnxBVFRSX1NURElOfEFUVFJfU1RET1VUfEFUVFJfRkFTVENPTnxBVFRSX05PVEVPRnxBVFRSX0RFVklDRSwKICAgIGNvbl9zdHJhdGVneSwgY29uX2ludGVycnVwdCB9Cn07CgojZGVmaW5lIE5SX0RFVlMgKHNpemVvZihkZXZzKS9zaXplb2YoV0lORURFVikpCgovKiBET1MgZGF0YSBzZWdtZW50ICovCnR5cGVkZWYgc3RydWN0CnsKICAgIERPU19MSVNUT0ZMSVNUUyAgICBsb2w7CiAgICBET1NfREVWSUNFX0hFQURFUiAgZGV2W05SX0RFVlMtMV07CiAgICBET1NfREVWSUNFX0hFQURFUiAqbGFzdF9kZXY7IC8qIHB0ciB0byBsYXN0IHJlZ2lzdGVyZWQgZGV2aWNlIGRyaXZlciAqLwogICAgV0lORURFVl9USFVOSyAgICAgIHRodW5rW05SX0RFVlNdOwogICAgUkVRX0lPICAgICAgICAgICAgIHJlcTsKICAgIEJZVEUgICAgICAgICAgICAgICBidWZmZXJbQ09OX0JVRkZFUl07Cgp9IERPU19EQVRBU0VHOwoKI2RlZmluZSBET1NfREFUQVNFR19PRkYoeHh4KSBGSUVMRF9PRkZTRVQoRE9TX0RBVEFTRUcsIHh4eCkKCnN0YXRpYyBEV09SRCBET1NfTE9MU2VnOwoKc3RhdGljIHN0cnVjdCBfRE9TX0xJU1RPRkxJU1RTICogRE9TTUVNX0xPTCh2b2lkKQp7CiAgICByZXR1cm4gUFRSX1JFQUxfVE9fTElOKEhJV09SRChET1NfTE9MU2VnKSwwKTsKfQoKCi8qIHRoZSBkZXZpY2UgaW1wbGVtZW50YXRpb25zICovCnN0YXRpYyB2b2lkIGRvX2xyZXQoQ09OVEVYVDg2KmN0eCkKewogIFdPUkQgKnN0YWNrID0gQ1RYX1NFR19PRkZfVE9fTElOKGN0eCwgY3R4LT5TZWdTcywgY3R4LT5Fc3ApOwoKICBjdHgtPkVpcCAgID0gKihzdGFjaysrKTsKICBjdHgtPlNlZ0NzID0gKihzdGFjaysrKTsKICBjdHgtPkVzcCAgKz0gMipzaXplb2YoV09SRCk7Cn0KCnN0YXRpYyB2b2lkIGRvX3N0cmF0ZWd5KENPTlRFWFQ4NipjdHgsIGludCBpZCwgaW50IGV4dHJhKQp7CiAgUkVRVUVTVF9IRUFERVIgKmhkciA9IENUWF9TRUdfT0ZGX1RPX0xJTihjdHgsIGN0eC0+U2VnRXMsIGN0eC0+RWJ4KTsKICB2b2lkICoqaGRyX3B0ciA9IHN0cmF0ZWd5X2RhdGFbaWRdOwoKICBpZiAoIWhkcl9wdHIpIHsKICAgIGhkcl9wdHIgPSBjYWxsb2MoMSxzaXplb2Yodm9pZCAqKStleHRyYSk7CiAgICBzdHJhdGVneV9kYXRhW2lkXSA9IGhkcl9wdHI7CiAgfQogICpoZHJfcHRyID0gaGRyOwogIGRvX2xyZXQoY3R4KTsKfQoKc3RhdGljIFJFUVVFU1RfSEVBREVSICogZ2V0X2hkcihpbnQgaWQsIHZvaWQqKmV4dHJhKQp7CiAgdm9pZCAqKmhkcl9wdHIgPSBzdHJhdGVneV9kYXRhW2lkXTsKICBpZiAoZXh0cmEpCiAgICAqZXh0cmEgPSBoZHJfcHRyID8gKHZvaWQqKShoZHJfcHRyKzEpIDogKHZvaWQgKilOVUxMOwogIHJldHVybiBoZHJfcHRyID8gKmhkcl9wdHIgOiAodm9pZCAqKU5VTEw7Cn0KCnN0YXRpYyB2b2lkIFdJTkFQSSBudWxfc3RyYXRlZ3koQ09OVEVYVDg2KmN0eCkKewogIGRvX3N0cmF0ZWd5KGN0eCwgU1lTVEVNX1NUUkFURUdZX05VTCwgMCk7Cn0KCnN0YXRpYyB2b2lkIFdJTkFQSSBudWxfaW50ZXJydXB0KENPTlRFWFQ4NipjdHgpCnsKICBSRVFVRVNUX0hFQURFUiAqaGRyID0gZ2V0X2hkcihTWVNURU1fU1RSQVRFR1lfTlVMLCBOVUxMKTsKICAvKiBlYXQgZXZlcnl0aGluZyBhbmQgcmVjeWNsZSBub3RoaW5nICovCiAgc3dpdGNoIChoZHItPmNvbW1hbmQpIHsKICBjYXNlIENNRF9JTlBVVDoKICAgICgoUkVRX0lPKiloZHIpLT5jb3VudCA9IDA7CiAgICBoZHItPnN0YXR1cyA9IFNUQVRfRE9ORTsKICAgIGJyZWFrOwogIGNhc2UgQ01EX1NBRkVJTlBVVDoKICAgIGhkci0+c3RhdHVzID0gU1RBVF9ET05FfFNUQVRfQlVTWTsKICAgIGJyZWFrOwogIGRlZmF1bHQ6CiAgICBoZHItPnN0YXR1cyA9IFNUQVRfRE9ORTsKICB9CiAgZG9fbHJldChjdHgpOwp9CgpzdGF0aWMgdm9pZCBXSU5BUEkgY29uX3N0cmF0ZWd5KENPTlRFWFQ4NipjdHgpCnsKICBkb19zdHJhdGVneShjdHgsIFNZU1RFTV9TVFJBVEVHWV9DT04sIHNpemVvZihpbnQpKTsKfQoKc3RhdGljIHZvaWQgV0lOQVBJIGNvbl9pbnRlcnJ1cHQoQ09OVEVYVDg2KmN0eCkKewogIGludCAqc2NhbjsKICBSRVFVRVNUX0hFQURFUiAqaGRyID0gZ2V0X2hkcihTWVNURU1fU1RSQVRFR1lfQ09OLCh2b2lkICoqKSZzY2FuKTsKICBCSU9TREFUQSAqYmlvcyA9IERPU1ZNX0Jpb3NEYXRhKCk7CiAgV09SRCBDdXJPZnMgPSBiaW9zLT5OZXh0S2JkQ2hhclB0cjsKICBET1NfTElTVE9GTElTVFMgKmxvbCA9IERPU01FTV9MT0woKTsKICBET1NfREFUQVNFRyAqZGF0YXNlZyA9IChET1NfREFUQVNFRyAqKWxvbDsKICBCWVRFICpsaW5lYnVmZmVyID0gZGF0YXNlZy0+YnVmZmVyOwogIEJZVEUgKmN1cmJ1ZmZlciA9IChsb2wtPm9mZnNfdW5yZWFkX0NPTikgPwogICAgKCgoQllURSopZGF0YXNlZykgKyBsb2wtPm9mZnNfdW5yZWFkX0NPTikgOiAoQllURSopTlVMTDsKICBET1NfREVWSUNFX0hFQURFUiAqY29uID0gZGF0YXNlZy0+ZGV2OwogIERXT1JEIHc7CgogIHN3aXRjaCAoaGRyLT5jb21tYW5kKSB7CiAgY2FzZSBDTURfSU5QVVQ6CiAgICB7CiAgICAgIFJFUV9JTyAqaW8gPSAoUkVRX0lPICopaGRyOwogICAgICBXT1JEIGNvdW50ID0gaW8tPmNvdW50LCBsZW4gPSAwOwogICAgICBCWVRFICpidWZmZXIgPSBDVFhfU0VHX09GRl9UT19MSU4oY3R4LAoJCQkJCVNFTEVDVE9ST0YoaW8tPmJ1ZmZlciksCgkJCQkJKERXT1JEKU9GRlNFVE9GKGlvLT5idWZmZXIpKTsKCiAgICAgIGhkci0+c3RhdHVzID0gU1RBVF9CVVNZOwogICAgICAvKiBmaXJzdCwgY2hlY2sgd2hldGhlciB3ZSBhbHJlYWR5IGhhdmUgZGF0YSBpbiBsaW5lIGJ1ZmZlciAqLwogICAgICBpZiAoY3VyYnVmZmVyKSB7CgkvKiB5ZXAsIGNvcHkgYXMgbXVjaCBhcyB3ZSBjYW4gKi8KCUJZVEUgZGF0YSA9IDA7Cgl3aGlsZSAoKGxlbjxjb3VudCkgJiYgKGRhdGEgIT0gJ1xyJykpIHsKCSAgZGF0YSA9ICpjdXJidWZmZXIrKzsKCSAgYnVmZmVyW2xlbisrXSA9IGRhdGE7Cgl9CglpZiAoZGF0YSA9PSAnXHInKSB7CgkgIC8qIGxpbmUgYnVmZmVyIGVtcHRpZWQgKi8KCSAgbG9sLT5vZmZzX3VucmVhZF9DT04gPSAwOwoJICBjdXJidWZmZXIgPSBOVUxMOwoJICAvKiBpZiB3ZSdyZSBub3QgaW4gcmF3IG1vZGUsIGNhbGwgaXQgYSBkYXkgKi8KCSAgaWYgKCEoY29uLT5hdHRyICYgQVRUUl9SQVcpKSB7CgkgICAgaGRyLT5zdGF0dXMgPSBTVEFUX0RPTkU7CgkgICAgaW8tPmNvdW50ID0gbGVuOwoJICAgIGJyZWFrOwoJICB9Cgl9IGVsc2UgewoJICAvKiBzdGlsbCBzb21lIGRhdGEgbGVmdCAqLwoJICBsb2wtPm9mZnNfdW5yZWFkX0NPTiA9IGN1cmJ1ZmZlciAtIChCWVRFKilsb2w7CgkgIC8qIGJ1dCBidWZmZXIgd2FzIGZpbGxlZCwgd2UncmUgZG9uZSAqLwoJICBoZHItPnN0YXR1cyA9IFNUQVRfRE9ORTsKCSAgaW8tPmNvdW50ID0gbGVuOwoJICBicmVhazsKCX0KICAgICAgfQoKICAgICAgLyogaWYgd2UncmUgaW4gcmF3IG1vZGUsIHdlIGp1c3QgbmVlZCB0byBmaWxsIHRoZSBidWZmZXIgKi8KICAgICAgaWYgKGNvbi0+YXR0ciAmIEFUVFJfUkFXKSB7Cgl3aGlsZSAobGVuPGNvdW50KSB7CgkgIFdPUkQgZGF0YTsKCgkgIC8qIGRvIHdlIGhhdmUgYSB3YWl0aW5nIHNjYW5jb2RlPyAqLwoJICBpZiAoKnNjYW4pIHsKCSAgICAvKiB5ZXMsIHN0b3JlIHNjYW5jb2RlIGluIGJ1ZmZlciAqLwoJICAgIGJ1ZmZlcltsZW4rK10gPSAqc2NhbjsKCSAgICAqc2NhbiA9IDA7CgkgICAgaWYgKGxlbj09Y291bnQpIGJyZWFrOwoJICB9CgoJICAvKiBjaGVjayBmb3IgbmV3IGtleWJvYXJkIGlucHV0ICovCgkgIHdoaWxlIChDdXJPZnMgPT0gYmlvcy0+Rmlyc3RLYmRDaGFyUHRyKSB7CgkgICAgLyogbm8gaW5wdXQgYXZhaWxhYmxlIHlldCwgc28gd2FpdC4uLiAqLwoJICAgIERPU1ZNX1dhaXQoIGN0eCApOwoJICB9CgkgIC8qIHJlYWQgZnJvbSBrZXlib2FyZCBxdWV1ZSAoY2FsbCBpbnQxNj8pICovCgkgIGRhdGEgPSAoKFdPUkQqKWJpb3MpW0N1ck9mc107CgkgIEN1ck9mcyArPSAyOwoJICBpZiAoQ3VyT2ZzID49IGJpb3MtPktiZEJ1ZmZlckVuZCkgQ3VyT2ZzID0gYmlvcy0+S2JkQnVmZmVyU3RhcnQ7CgkgIGJpb3MtPk5leHRLYmRDaGFyUHRyID0gQ3VyT2ZzOwoJICAvKiBpZiBpdCdzIGFuIGV4dGVuZGVkIGtleSwgc2F2ZSBzY2FuY29kZSAqLwoJICBpZiAoTE9CWVRFKGRhdGEpID09IDApICpzY2FuID0gSElCWVRFKGRhdGEpOwoJICAvKiBzdG9yZSBBU0NJSSBjaGFyIGluIGJ1ZmZlciAqLwoJICBidWZmZXJbbGVuKytdID0gTE9CWVRFKGRhdGEpOwoJfQogICAgICB9IGVsc2UgewoJLyogd2UncmUgbm90IGluIHJhdyBtb2RlLCBzbyB3ZSBuZWVkIHRvIGRvIGxpbmUgaW5wdXQuLi4gKi8KCXdoaWxlIChUUlVFKSB7CgkgIFdPUkQgZGF0YTsKCSAgLyogY2hlY2sgZm9yIG5ldyBrZXlib2FyZCBpbnB1dCAqLwoJICB3aGlsZSAoQ3VyT2ZzID09IGJpb3MtPkZpcnN0S2JkQ2hhclB0cikgewoJICAgIC8qIG5vIGlucHV0IGF2YWlsYWJsZSB5ZXQsIHNvIHdhaXQuLi4gKi8KCSAgICBET1NWTV9XYWl0KCBjdHggKTsKCSAgfQoJICAvKiByZWFkIGZyb20ga2V5Ym9hcmQgcXVldWUgKGNhbGwgaW50MTY/KSAqLwoJICBkYXRhID0gKChXT1JEKiliaW9zKVtDdXJPZnNdOwoJICBDdXJPZnMgKz0gMjsKCSAgaWYgKEN1ck9mcyA+PSBiaW9zLT5LYmRCdWZmZXJFbmQpIEN1ck9mcyA9IGJpb3MtPktiZEJ1ZmZlclN0YXJ0OwoJICBiaW9zLT5OZXh0S2JkQ2hhclB0ciA9IEN1ck9mczsKCgkgIGlmIChMT0JZVEUoZGF0YSkgPT0gJ1xyJykgewoJICAgIC8qIGl0J3MgdGhlIHJldHVybiBrZXksIHdlJ3JlIGRvbmUgKi8KCSAgICBsaW5lYnVmZmVyW2xlbisrXSA9IExPQllURShkYXRhKTsKCSAgICBicmVhazsKCSAgfQoJICBlbHNlIGlmIChMT0JZVEUoZGF0YSkgPj0gJyAnKSB7CgkgICAgLyogYSBjaGFyYWN0ZXIgKi8KCSAgICBpZiAoKGxlbisxKTxDT05fQlVGRkVSKSB7CgkgICAgICBsaW5lYnVmZmVyW2xlbl0gPSBMT0JZVEUoZGF0YSk7CgkgICAgICBXcml0ZUZpbGUoR2V0U3RkSGFuZGxlKFNURF9PVVRQVVRfSEFORExFKSwgJmxpbmVidWZmZXJbbGVuKytdLCAxLCAmdywgTlVMTCk7CgkgICAgfQoJICAgIC8qIGVsc2UgYmVlcCwgYnV0IEkgZG9uJ3QgbGlrZSBub2lzZSAqLwoJICB9CgkgIGVsc2Ugc3dpdGNoIChMT0JZVEUoZGF0YSkpIHsKCSAgY2FzZSAnXGInOgoJICAgIGlmIChsZW4+MCkgewoJICAgICAgbGVuLS07CgkgICAgICBXcml0ZUZpbGUoR2V0U3RkSGFuZGxlKFNURF9PVVRQVVRfSEFORExFKSwgIlxiIFxiIiwgMywgJncsIE5VTEwpOwoJICAgIH0KCSAgICBicmVhazsKCSAgfQoJfQoJaWYgKGxlbiA+IGNvdW50KSB7CgkgIC8qIHNhdmUgcmVzdCBvZiBsaW5lIGZvciBsYXRlciAqLwoJICBsb2wtPm9mZnNfdW5yZWFkX0NPTiA9IGxpbmVidWZmZXIgLSAoQllURSopbG9sICsgY291bnQ7CgkgIGxlbiA9IGNvdW50OwoJfQoJbWVtY3B5KGJ1ZmZlciwgbGluZWJ1ZmZlciwgbGVuKTsKICAgICAgfQogICAgICBoZHItPnN0YXR1cyA9IFNUQVRfRE9ORTsKICAgICAgaW8tPmNvdW50ID0gbGVuOwogICAgfQogICAgYnJlYWs7CiAgY2FzZSBDTURfU0FGRUlOUFVUOgogICAgaWYgKGN1cmJ1ZmZlcikgewogICAgICAvKiBzb21lIGxpbmUgaW5wdXQgd2FpdGluZyAqLwogICAgICBoZHItPnN0YXR1cyA9IFNUQVRfRE9ORTsKICAgICAgKChSRVFfU0FGRUlOUFVUKiloZHIpLT5kYXRhID0gKmN1cmJ1ZmZlcjsKICAgIH0KICAgIGVsc2UgaWYgKGNvbi0+YXR0ciAmIEFUVFJfUkFXKSB7CiAgICAgIGlmIChDdXJPZnMgPT0gYmlvcy0+Rmlyc3RLYmRDaGFyUHRyKSB7CgkvKiBubyBpbnB1dCAqLwoJaGRyLT5zdGF0dXMgPSBTVEFUX0RPTkV8U1RBVF9CVVNZOwogICAgICB9IGVsc2UgewoJLyogc29tZSBrZXlib2FyZCBpbnB1dCB3YWl0aW5nICovCgloZHItPnN0YXR1cyA9IFNUQVRfRE9ORTsKCSgoUkVRX1NBRkVJTlBVVCopaGRyKS0+ZGF0YSA9ICgoQllURSopYmlvcylbQ3VyT2ZzXTsKICAgICAgfQogICAgfSBlbHNlIHsKICAgICAgLyogbm8gbGluZSBpbnB1dCAqLwogICAgICBoZHItPnN0YXR1cyA9IFNUQVRfRE9ORXxTVEFUX0JVU1k7CiAgICB9CiAgICBicmVhazsKICBjYXNlIENNRF9JTlNUQVRVUzoKICAgIGlmIChjdXJidWZmZXIpIHsKICAgICAgLyogd2UgaGF2ZSBkYXRhICovCiAgICAgIGhkci0+c3RhdHVzID0gU1RBVF9ET05FOwogICAgfQogICAgZWxzZSBpZiAoY29uLT5hdHRyICYgQVRUUl9SQVcpIHsKICAgICAgaWYgKEN1ck9mcyA9PSBiaW9zLT5GaXJzdEtiZENoYXJQdHIpIHsKCS8qIG5vIGlucHV0ICovCgloZHItPnN0YXR1cyA9IFNUQVRfRE9ORXxTVEFUX0JVU1k7CiAgICAgIH0gZWxzZSB7CgkvKiBzb21lIGtleWJvYXJkIGlucHV0IHdhaXRpbmcgKi8KCWhkci0+c3RhdHVzID0gU1RBVF9ET05FOwogICAgICB9CiAgICB9IGVsc2UgewogICAgICAvKiBubyBsaW5lIGlucHV0ICovCiAgICAgIGhkci0+c3RhdHVzID0gU1RBVF9ET05FfFNUQVRfQlVTWTsKICAgIH0KCiAgICBicmVhazsKICBjYXNlIENNRF9JTkZMVVNIOgogICAgLyogZmx1c2ggbGluZSBhbmQga2V5Ym9hcmQgcXVldWUgKi8KICAgIGxvbC0+b2Zmc191bnJlYWRfQ09OID0gMDsKICAgIGJpb3MtPk5leHRLYmRDaGFyUHRyID0gYmlvcy0+Rmlyc3RLYmRDaGFyUHRyOwogICAgYnJlYWs7CiAgY2FzZSBDTURfT1VUUFVUOgogIGNhc2UgQ01EX1NBRkVPVVRQVVQ6CiAgICB7CiAgICAgIFJFUV9JTyAqaW8gPSAoUkVRX0lPICopaGRyOwogICAgICBCWVRFICpidWZmZXIgPSBDVFhfU0VHX09GRl9UT19MSU4oY3R4LAoJCQkJCVNFTEVDVE9ST0YoaW8tPmJ1ZmZlciksCgkJCQkJKERXT1JEKU9GRlNFVE9GKGlvLT5idWZmZXIpKTsKICAgICAgRFdPUkQgcmVzdWx0ID0gMDsKICAgICAgV3JpdGVGaWxlKEdldFN0ZEhhbmRsZShTVERfT1VUUFVUX0hBTkRMRSksIGJ1ZmZlciwgaW8tPmNvdW50LCAmcmVzdWx0LCBOVUxMKTsKICAgICAgaW8tPmNvdW50ID0gcmVzdWx0OwogICAgICBoZHItPnN0YXR1cyA9IFNUQVRfRE9ORTsKICAgIH0KICAgIGJyZWFrOwogIGRlZmF1bHQ6CiAgICBoZHItPnN0YXR1cyA9IFNUQVRfRE9ORTsKICB9CiAgZG9fbHJldChjdHgpOwp9CgpzdGF0aWMgdm9pZCBJbml0TGlzdE9mTGlzdHMoRE9TX0xJU1RPRkxJU1RTICpET1NfTE9MKQp7Ci8qCk91dHB1dCBvZiBET1MgNi4yMjoKCjAxMzM6MDAyMCAgICAgICAgICAgICAgICAgICAgNkEgMTMtMzMgMDEgQ0MgMDAgMzMgMDEgNTkgMDAgICAgICAgICBqLjMuLi4zLlkuCjAxMzM6MDAzMCAgNzAgMDAgMDAgMDAgNzIgMDIgMDAgMDItNkQgMDAgMzMgMDEgMDAgMDAgMkUgMDUgICBwLi4uci4uLm0uMy4uLi4uCjAxMzM6MDA0MCAgMDAgMDAgRkMgMDQgMDAgMDAgMDMgMDgtOTIgMjEgMTEgRTAgMDQgODAgQzYgMEQgICAuLi4uLi4uLi4hLi4uLi4uCjAxMzM6MDA1MCAgQ0MgMEQgNEUgNTUgNEMgMjAgMjAgMjAtMjAgMjAgMDAgMDAgMDAgMDAgMDAgMDAgICAuLk5VTCAgICAgLi4uLi4uCjAxMzM6MDA2MCAgMDAgNEIgQkEgQzEgMDYgMTQgMDAgMDAtMDAgMDMgMDEgMDAgMDQgNzAgQ0UgRkYgICAuSy4uLi4uLi4uLi4ucC4uCjAxMzM6MDA3MCAgRkYgMDAgMDAgMDAgMDAgMDAgMDAgMDAtMDAgMDEgMDAgMDAgMEQgMDUgMDAgMDAgICAuLi4uLi4uLi4uLi4uLi4uCjAxMzM6MDA4MCAgMDAgRkYgRkYgMDAgMDAgMDAgMDAgRkUtMDAgMDAgRjggMDMgRkYgOUYgNzAgMDIgICAuLi4uLi4uLi4uLi4uLnAuCjAxMzM6MDA5MCAgRDAgNDQgQzggRkQgRDQgNDQgQzggRkQtRDQgNDQgQzggRkQgRDAgNDQgQzggRkQgICAuRC4uLkQuLi5ELi4uRC4uCjAxMzM6MDBBMCAgRDAgNDQgQzggRkQgRDAgNDQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAuRC4uLkQKKi8KICBET1NfTE9MLT5DWF9JbnQyMV81ZTAxCQk9IDB4MDsKICBET1NfTE9MLT5MUlVfY291bnRfRkNCX2NhY2hlCT0gMHgwOwogIERPU19MT0wtPkxSVV9jb3VudF9GQ0Jfb3BlbgkJPSAweDA7CiAgRE9TX0xPTC0+T0VNX2Z1bmNfaGFuZGxlcgkJPSAtMTsgLyogbm90IGF2YWlsYWJsZSAqLwogIERPU19MT0wtPklOVDIxX29mZnNldAkJPSAweDA7CiAgRE9TX0xPTC0+c2hhcmluZ19yZXRyeV9jb3VudAk9IDM7CiAgRE9TX0xPTC0+c2hhcmluZ19yZXRyeV9kZWxheQk9IDE7CiAgRE9TX0xPTC0+cHRyX2Rpc2tfYnVmCQk9IDB4MDsKICBET1NfTE9MLT5vZmZzX3VucmVhZF9DT04JCT0gMHgwOwogIERPU19MT0wtPnNlZ19maXJzdF9NQ0IJCT0gMHgwOwogIERPU19MT0wtPnB0cl9maXJzdF9EUEIJCT0gMHgwOwogIERPU19MT0wtPnB0cl9maXJzdF9TeXNGaWxlVGFibGUJPSAweDA7CiAgRE9TX0xPTC0+cHRyX2Nsb2NrX2Rldl9oZHIJCT0gMHgwOwogIERPU19MT0wtPnB0cl9DT05fZGV2X2hkcgkJPSAweDA7CiAgRE9TX0xPTC0+bWF4X2J5dGVfcGVyX3NlYwkJPSA1MTI7CiAgRE9TX0xPTC0+cHRyX2Rpc2tfYnVmX2luZm8JCT0gMHgwOwogIERPU19MT0wtPnB0cl9hcnJheV9DRFMJCT0gMHgwOwogIERPU19MT0wtPnB0cl9zeXNfRkNCCQk9IDB4MDsKICBET1NfTE9MLT5ucl9wcm90ZWN0X0ZDQgkJPSAweDA7CiAgRE9TX0xPTC0+bnJfYmxvY2tfZGV2CQk9IDB4MDsKICBET1NfTE9MLT5ucl9hdmFpbF9kcml2ZV9sZXR0ZXJzCT0gMjY7IC8qIEEgLSBaICovCiAgRE9TX0xPTC0+bnJfZHJpdmVzX0pPSU5lZAkJPSAweDA7CiAgRE9TX0xPTC0+cHRyX3NwZWNfcHJnX25hbWVzCQk9IDB4MDsKICBET1NfTE9MLT5wdHJfU0VUVkVSX3ByZ19saXN0CT0gMHgwOyAvKiBubyBTRVRWRVIgbGlzdCAqLwogIERPU19MT0wtPkRPU19ISUdIX0EyMF9mdW5jX29mZnMJPSAweDA7CiAgRE9TX0xPTC0+UFNQX2xhc3RfZXhlYwkJPSAweDA7CiAgRE9TX0xPTC0+QlVGRkVSU192YWwJCT0gOTk7IC8qIG1heGltdW06IDk5ICovCiAgRE9TX0xPTC0+QlVGRkVSU19ucl9sb29rYWhlYWQJPSA4OyAvKiBtYXhpbXVtOiA4ICovCiAgRE9TX0xPTC0+Ym9vdF9kcml2ZQkJCT0gMzsgLyogQzogKi8KICBET1NfTE9MLT5mbGFnX0RXT1JEX21vdmVzCQk9IDB4MDE7IC8qIGkzODYrICovCiAgRE9TX0xPTC0+c2l6ZV9leHRlbmRlZF9tZW0JCT0gMHhmMDAwOyAvKiB2ZXJ5IGhpZ2ggdmFsdWUgKi8KfQoKdm9pZCBET1NERVZfU2V0dXBEZXZpY2UoY29uc3QgV0lORURFViAqIGRldmluZm8sCgkJCVdPUkQgc2VnLCBXT1JEIG9mZl9kZXYsIFdPUkQgb2ZmX3RodW5rKQp7CiAgRE9TX0RFVklDRV9IRUFERVIgKmRldiA9IFBUUl9SRUFMX1RPX0xJTihzZWcsIG9mZl9kZXYpOwogIFdJTkVERVZfVEhVTksgKnRodW5rID0gUFRSX1JFQUxfVE9fTElOKHNlZywgb2ZmX3RodW5rKTsKICBET1NfREFUQVNFRyAqZGF0YXNlZyA9IChET1NfREFUQVNFRyopRE9TTUVNX0xPTCgpOwoKICBkZXYtPmF0dHIgPSBkZXZpbmZvLT5hdHRyOwogIGRldi0+c3RyYXRlZ3kgID0gb2ZmX3RodW5rICsgRklFTERfT0ZGU0VUKFdJTkVERVZfVEhVTkssIGxqbXAxKTsKICBkZXYtPmludGVycnVwdCA9IG9mZl90aHVuayArIEZJRUxEX09GRlNFVChXSU5FREVWX1RIVU5LLCBsam1wMik7CiAgbWVtY3B5KGRldi0+bmFtZSwgZGV2aW5mby0+bmFtZSwgOCk7CgogIHRodW5rLT5sam1wMSAgICAgPSBMSk1QOwogIHRodW5rLT5zdHJhdGVneSAgPSBEUE1JX0FsbG9jSW50ZXJuYWxSTUNCKGRldmluZm8tPnN0cmF0ZWd5KTsKICB0aHVuay0+bGptcDIgICAgID0gTEpNUDsKICB0aHVuay0+aW50ZXJydXB0ID0gRFBNSV9BbGxvY0ludGVybmFsUk1DQihkZXZpbmZvLT5pbnRlcnJ1cHQpOwoKICBkZXYtPm5leHRfZGV2ID0gTk9ORVhUOwogIGlmIChkYXRhc2VnLT5sYXN0X2RldikKICAgICAgZGF0YXNlZy0+bGFzdF9kZXYtPm5leHRfZGV2ID0gTUFLRVNFR1BUUihzZWcsIG9mZl9kZXYpOwogIGRhdGFzZWctPmxhc3RfZGV2ID0gZGV2Owp9Cgp2b2lkIERPU0RFVl9JbnN0YWxsRE9TRGV2aWNlcyh2b2lkKQp7CiAgRE9TX0RBVEFTRUcgKmRhdGFzZWc7CiAgV09SRCBzZWc7CiAgV09SRCBzZWxlY3RvcjsKICB1bnNpZ25lZCBpbnQgbjsKCiAgLyogYWxsb2NhdGUgRE9TIGRhdGEgc2VnbWVudCBvciBzb21ldGhpbmcgKi8KICBkYXRhc2VnID0gRE9TVk1fQWxsb2NEYXRhVU1CKCBzaXplb2YoRE9TX0RBVEFTRUcpLCAmc2VnLCAmc2VsZWN0b3IgKTsKCiAgRE9TX0xPTFNlZyA9IE1BS0VTRUdQVFIoIHNlZywgMCApOwogIERPU01FTV9MT0woKS0+d2luZV9ybV9sb2wgPSAKICAgICAgTUFLRVNFR1BUUiggc2VnLCBGSUVMRF9PRkZTRVQoRE9TX0xJU1RPRkxJU1RTLCBwdHJfZmlyc3RfRFBCKSApOwogIERPU01FTV9MT0woKS0+d2luZV9wbV9sb2wgPSAKICAgICAgTUFLRVNFR1BUUiggc2VsZWN0b3IsIEZJRUxEX09GRlNFVChET1NfTElTVE9GTElTVFMsIHB0cl9maXJzdF9EUEIpICk7CgogIC8qIGluaXRpYWxpemUgdGhlIG1hZ25pZmljZW50IExpc3QgT2YgTGlzdHMgKi8KICBJbml0TGlzdE9mTGlzdHMoJmRhdGFzZWctPmxvbCk7CgogIC8qIFNldCB1cCBmaXJzdCBkZXZpY2UgKE5VTCkgKi8KICBkYXRhc2VnLT5sYXN0X2RldiA9IE5VTEw7CiAgRE9TREVWX1NldHVwRGV2aWNlKCAmZGV2c1swXSwKCQkgICAgICBzZWcsCgkJICAgICAgRE9TX0RBVEFTRUdfT0ZGKGxvbC5OVUxfZGV2KSwKCQkgICAgICBET1NfREFUQVNFR19PRkYodGh1bmtbMF0pICk7CgogIC8qIFNldCB1cCB0aGUgcmVtYWluaW5nIGRldmljZXMgKi8KICBmb3IgKG4gPSAxOyBuIDwgTlJfREVWUzsgbisrKQogICAgRE9TREVWX1NldHVwRGV2aWNlKCAmZGV2c1tuXSwKCQkJc2VnLAoJCQlET1NfREFUQVNFR19PRkYoZGV2W24tMV0pLAoJCQlET1NfREFUQVNFR19PRkYodGh1bmtbbl0pICk7CgogIC8qIENPTiBpcyBkZXZpY2UgMSAqLwogIGRhdGFzZWctPmxvbC5wdHJfQ09OX2Rldl9oZHIgPSBNQUtFU0VHUFRSKHNlZywgRE9TX0RBVEFTRUdfT0ZGKGRldlswXSkpOwp9CgpEV09SRCBET1NERVZfQ29uc29sZSh2b2lkKQp7CiAgcmV0dXJuIERPU01FTV9MT0woKS0+cHRyX0NPTl9kZXZfaGRyOwp9CgpEV09SRCBET1NERVZfRmluZENoYXJEZXZpY2UoY2hhcipuYW1lKQp7CiAgU0VHUFRSIGN1cl9wdHIgPSBNQUtFU0VHUFRSKEhJV09SRChET1NfTE9MU2VnKSwgRklFTERfT0ZGU0VUKERPU19MSVNUT0ZMSVNUUyxOVUxfZGV2KSk7CiAgRE9TX0RFVklDRV9IRUFERVIgKmN1ciA9IFBUUl9SRUFMX1RPX0xJTihTRUxFQ1RPUk9GKGN1cl9wdHIpLE9GRlNFVE9GKGN1cl9wdHIpKTsKICBjaGFyIGRuYW1lWzhdOwogIGludCBjbnQ7CgogIC8qIGdldCBmaXJzdCA4IGNoYXJhY3RlcnMgKi8KICAvKiBpZiBsZXNzIHRoYW4gOCBjaGFyYWN0ZXJzLCBwYWQgd2l0aCBzcGFjZXMgKi8KICBmb3IgKGNudD0wOyBuYW1lW2NudF0gJiYgY250PDg7IGNudCsrKQogICAgZG5hbWVbY250XT1uYW1lW2NudF07CgogIHdoaWxlKGNudDw4KSBkbmFtZVtjbnQrK10gPSAnICc7CgogIC8qIHNlYXJjaCBmb3IgY2hhciBkZXZpY2VzIHdpdGggdGhlIHJpZ2h0IG5hbWUgKi8KICB3aGlsZSAoY3VyICYmCgkgKCghKGN1ci0+YXR0ciAmIEFUVFJfQ0hBUikpIHx8CgkgIG1lbWNtcChjdXItPm5hbWUsZG5hbWUsOCkpKSB7CiAgICBjdXJfcHRyID0gY3VyLT5uZXh0X2RldjsKICAgIGlmIChjdXJfcHRyID09IE5PTkVYVCkgY3VyPU5VTEw7CiAgICBlbHNlIGN1ciA9IFBUUl9SRUFMX1RPX0xJTihTRUxFQ1RPUk9GKGN1cl9wdHIpLE9GRlNFVE9GKGN1cl9wdHIpKTsKICB9CiAgcmV0dXJuIGN1cl9wdHI7Cn0KCnN0YXRpYyB2b2lkIERPU0RFVl9Eb1JlcSh2b2lkKnJlcSwgRFdPUkQgZGV2KQp7CiAgUkVRVUVTVF9IRUFERVIgKmhkciA9IChSRVFVRVNUX0hFQURFUiAqKXJlcTsKICBET1NfREVWSUNFX0hFQURFUiAqZGhkcjsKICBDT05URVhUODYgY3R4OwogIGNoYXIgKnBoZHI7CgogIGRoZHIgPSBQVFJfUkVBTF9UT19MSU4oU0VMRUNUT1JPRihkZXYpLE9GRlNFVE9GKGRldikpOwogIHBoZHIgPSAoKGNoYXIqKURPU01FTV9MT0woKSkgKyBET1NfREFUQVNFR19PRkYocmVxKTsKCiAgLyogY29weSByZXF1ZXN0IHRvIHJlcXVlc3Qgc2NyYXRjaCBhcmVhICovCiAgbWVtY3B5KHBoZHIsIHJlcSwgaGRyLT5zaXplKTsKCiAgLyogcHJlcGFyZSB0byBjYWxsIGRldmljZSBkcml2ZXIgKi8KICBtZW1zZXQoJmN0eCwgMCwgc2l6ZW9mKGN0eCkpOwogIGN0eC5FRmxhZ3MgfD0gVjg2X0ZMQUc7CgogIC8qIEVTOkJYIHBvaW50cyB0byByZXF1ZXN0IGZvciBzdHJhdGVneSByb3V0aW5lICovCiAgY3R4LlNlZ0VzID0gSElXT1JEKERPU19MT0xTZWcpOwogIGN0eC5FYnggICA9IERPU19EQVRBU0VHX09GRihyZXEpOwoKICAvKiBjYWxsIHN0cmF0ZWd5IHJvdXRpbmUgKi8KICBjdHguU2VnQ3MgPSBTRUxFQ1RPUk9GKGRldik7CiAgY3R4LkVpcCAgID0gZGhkci0+c3RyYXRlZ3k7CiAgRFBNSV9DYWxsUk1Qcm9jKCZjdHgsIDAsIDAsIDApOwoKICAvKiBjYWxsIGludGVycnVwdCByb3V0aW5lICovCiAgY3R4LlNlZ0NzID0gU0VMRUNUT1JPRihkZXYpOwogIGN0eC5FaXAgICA9IGRoZHItPmludGVycnVwdDsKICBEUE1JX0NhbGxSTVByb2MoJmN0eCwgMCwgMCwgMCk7CgogIC8qIGNvbXBsZXRlZCwgY29weSByZXF1ZXN0IGJhY2sgKi8KICBtZW1jcHkocmVxLCBwaGRyLCBoZHItPnNpemUpOwoKICBpZiAoaGRyLT5zdGF0dXMgJiBTVEFUX0VSUk9SKSB7CiAgICBzd2l0Y2ggKGhkci0+c3RhdHVzICYgU1RBVF9NQVNLKSB7CiAgICBjYXNlIDB4MEY6IC8qIGludmFsaWQgZGlzayBjaGFuZ2UgKi8KICAgICAgLyogdGhpcyBlcnJvciBzZWVtcyB0byBmaXQgdGhlIGJpbGwgKi8KICAgICAgU2V0TGFzdEVycm9yKEVSUk9SX05PVF9TQU1FX0RFVklDRSk7CiAgICAgIGJyZWFrOwogICAgZGVmYXVsdDoKICAgICAgU2V0TGFzdEVycm9yKChoZHItPnN0YXR1cyAmIFNUQVRfTUFTSykgKyAweDEzKTsKICAgICAgYnJlYWs7CiAgICB9CiAgfQp9CgpzdGF0aWMgaW50IERPU0RFVl9JTyh1bnNpZ25lZCBjbWQsIERXT1JEIGRldiwgRFdPUkQgYnVmLCBpbnQgYnVmbGVuKQp7CiAgUkVRX0lPIHJlcTsKCiAgcmVxLmhkci5zaXplPXNpemVvZihyZXEpOwogIHJlcS5oZHIudW5pdD0wOyAvKiBub3QgZGVhbGluZyB3aXRoIGJsb2NrIGRldmljZXMgeWV0ICovCiAgcmVxLmhkci5jb21tYW5kPWNtZDsKICByZXEuaGRyLnN0YXR1cz1TVEFUX0JVU1k7CiAgcmVxLm1lZGlhPTA7IC8qIG5vdCBkZWFsaW5nIHdpdGggYmxvY2sgZGV2aWNlcyB5ZXQgKi8KICByZXEuYnVmZmVyPWJ1ZjsKICByZXEuY291bnQ9YnVmbGVuOwogIHJlcS5zZWN0b3I9MDsgLyogYmxvY2sgZGV2aWNlcyAqLwogIHJlcS52b2x1bWU9MDsgLyogYmxvY2sgZGV2aWNlcyAqLwoKICBET1NERVZfRG9SZXEoJnJlcSwgZGV2KTsKCiAgcmV0dXJuIHJlcS5jb3VudDsKfQoKaW50IERPU0RFVl9QZWVrKERXT1JEIGRldiwgQllURSpkYXRhKQp7CiAgUkVRX1NBRkVJTlBVVCByZXE7CgogIHJlcS5oZHIuc2l6ZT1zaXplb2YocmVxKTsKICByZXEuaGRyLnVuaXQ9MDsgLyogbm90IGRlYWxpbmcgd2l0aCBibG9jayBkZXZpY2VzIHlldCAqLwogIHJlcS5oZHIuY29tbWFuZD1DTURfU0FGRUlOUFVUOwogIHJlcS5oZHIuc3RhdHVzPVNUQVRfQlVTWTsKICByZXEuZGF0YT0wOwoKICBET1NERVZfRG9SZXEoJnJlcSwgZGV2KTsKCiAgaWYgKHJlcS5oZHIuc3RhdHVzICYgU1RBVF9CVVNZKSByZXR1cm4gMDsKCiAgKmRhdGEgPSByZXEuZGF0YTsKICByZXR1cm4gMTsKfQoKaW50IERPU0RFVl9SZWFkKERXT1JEIGRldiwgRFdPUkQgYnVmLCBpbnQgYnVmbGVuKQp7CiAgcmV0dXJuIERPU0RFVl9JTyhDTURfSU5QVVQsIGRldiwgYnVmLCBidWZsZW4pOwp9CgppbnQgRE9TREVWX1dyaXRlKERXT1JEIGRldiwgRFdPUkQgYnVmLCBpbnQgYnVmbGVuLCBpbnQgdmVyaWZ5KQp7CiAgcmV0dXJuIERPU0RFVl9JTyh2ZXJpZnk/Q01EX1NBRkVPVVRQVVQ6Q01EX09VVFBVVCwgZGV2LCBidWYsIGJ1Zmxlbik7Cn0KCmludCBET1NERVZfSW9jdGxSZWFkKERXT1JEIGRldiwgRFdPUkQgYnVmLCBpbnQgYnVmbGVuKQp7CiAgcmV0dXJuIERPU0RFVl9JTyhDTURfSU5JT0NUTCwgZGV2LCBidWYsIGJ1Zmxlbik7Cn0KCmludCBET1NERVZfSW9jdGxXcml0ZShEV09SRCBkZXYsIERXT1JEIGJ1ZiwgaW50IGJ1ZmxlbikKewogIHJldHVybiBET1NERVZfSU8oQ01EX09VVElPQ1RMLCBkZXYsIGJ1ZiwgYnVmbGVuKTsKfQoKdm9pZCBET1NERVZfU2V0U2hhcmluZ1JldHJ5KFdPUkQgZGVsYXksIFdPUkQgY291bnQpCnsKICAgIERPU01FTV9MT0woKS0+c2hhcmluZ19yZXRyeV9kZWxheSA9IGRlbGF5OwogICAgaWYgKGNvdW50KSBET1NNRU1fTE9MKCktPnNoYXJpbmdfcmV0cnlfY291bnQgPSBjb3VudDsKfQoKU0VHUFRSIERPU0RFVl9HZXRMT0woQk9PTCB2ODYpCnsKICAgIGlmICh2ODYpIHJldHVybiBET1NNRU1fTE9MKCktPndpbmVfcm1fbG9sOwogICAgZWxzZSByZXR1cm4gRE9TTUVNX0xPTCgpLT53aW5lX3BtX2xvbDsKfQo=