LyoKICogRE9TIGRldmljZXMKICoKICogQ29weXJpZ2h0IDE5OTkgT3ZlIEvldmVuCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IKICogbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXIKICogdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLAogKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZgogKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVQogKiBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljCiAqIExpY2Vuc2UgYWxvbmcgd2l0aCB0aGlzIGxpYnJhcnk7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUKICogRm91bmRhdGlvbiwgSW5jLiwgNTkgVGVtcGxlIFBsYWNlLCBTdWl0ZSAzMzAsIEJvc3RvbiwgTUEgIDAyMTExLTEzMDcgIFVTQQogKi8KCiNpbmNsdWRlIDxzdGRsaWIuaD4KI2luY2x1ZGUgPHN0cmluZy5oPgojaW5jbHVkZSAid2luZS93aW5iYXNlMTYuaCIKI2luY2x1ZGUgIm1zZG9zLmgiCiNpbmNsdWRlICJtaXNjZW11LmgiCiNpbmNsdWRlICJkb3NleGUuaCIKI2luY2x1ZGUgIndpbmUvZGVidWcuaCIKCiNpbmNsdWRlICJwc2hwYWNrMS5oIgoKdHlwZWRlZiBzdHJ1Y3QgewogIEJZVEUgbGptcDE7CiAgUk1DQlBST0Mgc3RyYXRlZ3k7CiAgQllURSBsam1wMjsKICBSTUNCUFJPQyBpbnRlcnJ1cHQ7Cn0gV0lORURFVl9USFVOSzsKCnR5cGVkZWYgc3RydWN0IHsKICBCWVRFIHNpemU7IC8qIGxlbmd0aCBvZiBoZWFkZXIgKyBkYXRhICovCiAgQllURSB1bml0OyAvKiB1bml0IChibG9jayBkZXZpY2VzIG9ubHkpICovCiAgQllURSBjb21tYW5kOwogIFdPUkQgc3RhdHVzOwogIEJZVEUgcmVzZXJ2ZWRbOF07Cn0gUkVRVUVTVF9IRUFERVI7Cgp0eXBlZGVmIHN0cnVjdCB7CiAgUkVRVUVTVF9IRUFERVIgaGRyOwogIEJZVEUgbWVkaWE7IC8qIG1lZGlhIGRlc2NyaXB0b3IgZnJvbSBCUEIgKi8KICBTRUdQVFIgYnVmZmVyOwogIFdPUkQgY291bnQ7IC8qIGJ5dGUvc2VjdG9yIGNvdW50ICovCiAgV09SRCBzZWN0b3I7IC8qIHN0YXJ0aW5nIHNlY3RvciAoYmxvY2sgZGV2aWNlcykgKi8KICBEV09SRCB2b2x1bWU7IC8qIHZvbHVtZSBJRCAoYmxvY2sgZGV2aWNlcykgKi8KfSBSRVFfSU87Cgp0eXBlZGVmIHN0cnVjdCB7CiAgUkVRVUVTVF9IRUFERVIgaGRyOwogIEJZVEUgZGF0YTsKfSBSRVFfU0FGRUlOUFVUOwoKI2luY2x1ZGUgInBvcHBhY2suaCIKCiNkZWZpbmUgQ09OX0JVRkZFUiAxMjgKCmVudW0gc3RyYXRlZ3kgeyBTWVNURU1fU1RSQVRFR1lfTlVMLCBTWVNURU1fU1RSQVRFR1lfQ09OLCBOQl9TWVNURU1fU1RSQVRFR0lFUyB9OwoKc3RhdGljIHZvaWQgKnN0cmF0ZWd5X2RhdGFbTkJfU1lTVEVNX1NUUkFURUdJRVNdOwoKI2RlZmluZSBOT05FWFQgKChEV09SRCktMSkKCiNkZWZpbmUgQVRUUl9TVERJTiAgICAgMHgwMDAxCiNkZWZpbmUgQVRUUl9TVERPVVQgICAgMHgwMDAyCiNkZWZpbmUgQVRUUl9OVUwgICAgICAgMHgwMDA0CiNkZWZpbmUgQVRUUl9DTE9DSyAgICAgMHgwMDA4CiNkZWZpbmUgQVRUUl9GQVNUQ09OICAgMHgwMDEwCiNkZWZpbmUgQVRUUl9SQVcgICAgICAgMHgwMDIwCiNkZWZpbmUgQVRUUl9OT1RFT0YgICAgMHgwMDQwCiNkZWZpbmUgQVRUUl9ERVZJQ0UgICAgMHgwMDgwCiNkZWZpbmUgQVRUUl9SRU1PVkFCTEUgMHgwODAwCiNkZWZpbmUgQVRUUl9OT05JQk0gICAgMHgyMDAwIC8qIGJsb2NrIGRldmljZXMgKi8KI2RlZmluZSBBVFRSX1VOVElMQlVTWSAweDIwMDAgLyogY2hhciBkZXZpY2VzICovCiNkZWZpbmUgQVRUUl9JT0NUTCAgICAgMHg0MDAwCiNkZWZpbmUgQVRUUl9DSEFSICAgICAgMHg4MDAwCgojZGVmaW5lIENNRF9JTklUICAgICAgIDAKI2RlZmluZSBDTURfTUVESUFDSEVDSyAxIC8qIGJsb2NrIGRldmljZXMgKi8KI2RlZmluZSBDTURfQlVJTERCUEIgICAyIC8qIGJsb2NrIGRldmljZXMgKi8KI2RlZmluZSBDTURfSU5JT0NUTCAgICAzCiNkZWZpbmUgQ01EX0lOUFVUICAgICAgNCAvKiByZWFkIGRhdGEgKi8KI2RlZmluZSBDTURfU0FGRUlOUFVUICA1IC8qICJub24tZGVzdHJ1Y3RpdmUgaW5wdXQgbm8gd2FpdCIsIGNoYXIgZGV2aWNlcyAqLwojZGVmaW5lIENNRF9JTlNUQVRVUyAgIDYgLyogY2hhciBkZXZpY2VzICovCiNkZWZpbmUgQ01EX0lORkxVU0ggICAgNyAvKiBjaGFyIGRldmljZXMgKi8KI2RlZmluZSBDTURfT1VUUFVUICAgICA4IC8qIHdyaXRlIGRhdGEgKi8KI2RlZmluZSBDTURfU0FGRU9VVFBVVCA5IC8qIHdyaXRlIGRhdGEgd2l0aCB2ZXJpZnkgKi8KI2RlZmluZSBDTURfT1VUU1RBVFVTIDEwIC8qIGNoYXIgZGV2aWNlcyAqLwojZGVmaW5lIENNRF9PVVRGTFVTSCAgMTEgLyogY2hhciBkZXZpY2VzICovCiNkZWZpbmUgQ01EX09VVElPQ1RMICAxMgojZGVmaW5lIENNRF9ERVZPUEVOICAgMTMKI2RlZmluZSBDTURfREVWQ0xPU0UgIDE0CiNkZWZpbmUgQ01EX1JFTU9WQUJMRSAxNSAvKiBibG9jayBkZXZpY2VzICovCiNkZWZpbmUgQ01EX1VOVElMQlVTWSAxNiAvKiBvdXRwdXQgdW50aWwgYnVzeSAqLwoKI2RlZmluZSBTVEFUX01BU0sgIDB4MDBGRgojZGVmaW5lIFNUQVRfRE9ORSAgMHgwMTAwCiNkZWZpbmUgU1RBVF9CVVNZICAweDAyMDAKI2RlZmluZSBTVEFUX0VSUk9SIDB4ODAwMAoKI2RlZmluZSBMSk1QIDB4ZWEKCgovKiBwcm90b3R5cGVzICovCnN0YXRpYyB2b2lkIFdJTkFQSSBudWxfc3RyYXRlZ3koQ09OVEVYVDg2KmN0eCk7CnN0YXRpYyB2b2lkIFdJTkFQSSBudWxfaW50ZXJydXB0KENPTlRFWFQ4NipjdHgpOwpzdGF0aWMgdm9pZCBXSU5BUEkgY29uX3N0cmF0ZWd5KENPTlRFWFQ4NipjdHgpOwpzdGF0aWMgdm9pZCBXSU5BUEkgY29uX2ludGVycnVwdChDT05URVhUODYqY3R4KTsKCi8qIGRldmljZXMgKi8KdHlwZWRlZiBzdHJ1Y3QgCnsKICAgIGNoYXIgbmFtZVs4XTsKICAgIFdPUkQgYXR0cjsKICAgIFJNQ0JQUk9DIHN0cmF0ZWd5OwogICAgUk1DQlBST0MgaW50ZXJydXB0Owp9IFdJTkVERVY7CgpzdGF0aWMgV0lORURFViBkZXZzW10gPSAKewogIHsgIk5VTCAgICAgIiwKICAgIEFUVFJfQ0hBUnxBVFRSX05VTHxBVFRSX0RFVklDRSwKICAgIG51bF9zdHJhdGVneSwgbnVsX2ludGVycnVwdCB9LAoKICB7ICJDT04gICAgICIsCiAgICBBVFRSX0NIQVJ8QVRUUl9TVERJTnxBVFRSX1NURE9VVHxBVFRSX0ZBU1RDT058QVRUUl9OT1RFT0Z8QVRUUl9ERVZJQ0UsCiAgICBjb25fc3RyYXRlZ3ksIGNvbl9pbnRlcnJ1cHQgfQp9OwoKI2RlZmluZSBOUl9ERVZTIChzaXplb2YoZGV2cykvc2l6ZW9mKFdJTkVERVYpKQoKLyogRE9TIGRhdGEgc2VnbWVudCAqLwp0eXBlZGVmIHN0cnVjdAp7CiAgICBET1NfTElTVE9GTElTVFMgICAgbG9sOwogICAgRE9TX0RFVklDRV9IRUFERVIgIGRldltOUl9ERVZTLTFdOwogICAgV0lORURFVl9USFVOSyAgICAgIHRodW5rW05SX0RFVlNdOwogICAgUkVRX0lPICAgICAgICAgICAgIHJlcTsKICAgIEJZVEUgICAgICAgICAgICAgICBidWZmZXJbQ09OX0JVRkZFUl07Cgp9IERPU19EQVRBU0VHOwoKI2RlZmluZSBET1NfREFUQVNFR19PRkYoeHh4KSBGSUVMRF9PRkZTRVQoRE9TX0RBVEFTRUcsIHh4eCkKCnN0cnVjdCBfRE9TX0xJU1RPRkxJU1RTICogRE9TTUVNX0xPTCgpCnsKICAgIHJldHVybiAoc3RydWN0IF9ET1NfTElTVE9GTElTVFMgKilET1NNRU1fTWFwUmVhbFRvTGluZWFyCiAgICAgIChNQUtFU0VHUFRSKEhJV09SRChET1NfTE9MU2VnKSwwKSk7Cn0KCgovKiB0aGUgZGV2aWNlIGltcGxlbWVudGF0aW9ucyAqLwpzdGF0aWMgdm9pZCBkb19scmV0KENPTlRFWFQ4NipjdHgpCnsKICBXT1JEICpzdGFjayA9IENUWF9TRUdfT0ZGX1RPX0xJTihjdHgsIGN0eC0+U2VnU3MsIGN0eC0+RXNwKTsKCiAgY3R4LT5FaXAgICA9ICooc3RhY2srKyk7CiAgY3R4LT5TZWdDcyA9ICooc3RhY2srKyk7CiAgY3R4LT5Fc3AgICs9IDIqc2l6ZW9mKFdPUkQpOwp9CgpzdGF0aWMgdm9pZCBkb19zdHJhdGVneShDT05URVhUODYqY3R4LCBpbnQgaWQsIGludCBleHRyYSkKewogIFJFUVVFU1RfSEVBREVSICpoZHIgPSBDVFhfU0VHX09GRl9UT19MSU4oY3R4LCBjdHgtPlNlZ0VzLCBjdHgtPkVieCk7CiAgdm9pZCAqKmhkcl9wdHIgPSBzdHJhdGVneV9kYXRhW2lkXTsKCiAgaWYgKCFoZHJfcHRyKSB7CiAgICBoZHJfcHRyID0gY2FsbG9jKDEsc2l6ZW9mKHZvaWQgKikrZXh0cmEpOwogICAgc3RyYXRlZ3lfZGF0YVtpZF0gPSBoZHJfcHRyOwogIH0KICAqaGRyX3B0ciA9IGhkcjsKICBkb19scmV0KGN0eCk7Cn0KCnN0YXRpYyBSRVFVRVNUX0hFQURFUiAqIGdldF9oZHIoaW50IGlkLCB2b2lkKipleHRyYSkKewogIHZvaWQgKipoZHJfcHRyID0gc3RyYXRlZ3lfZGF0YVtpZF07CiAgaWYgKGV4dHJhKQogICAgKmV4dHJhID0gaGRyX3B0ciA/ICh2b2lkKikoaGRyX3B0cisxKSA6ICh2b2lkICopTlVMTDsKICByZXR1cm4gaGRyX3B0ciA/ICpoZHJfcHRyIDogKHZvaWQgKilOVUxMOwp9CgpzdGF0aWMgdm9pZCBXSU5BUEkgbnVsX3N0cmF0ZWd5KENPTlRFWFQ4NipjdHgpCnsKICBkb19zdHJhdGVneShjdHgsIFNZU1RFTV9TVFJBVEVHWV9OVUwsIDApOwp9CgpzdGF0aWMgdm9pZCBXSU5BUEkgbnVsX2ludGVycnVwdChDT05URVhUODYqY3R4KQp7CiAgUkVRVUVTVF9IRUFERVIgKmhkciA9IGdldF9oZHIoU1lTVEVNX1NUUkFURUdZX05VTCwgTlVMTCk7CiAgLyogZWF0IGV2ZXJ5dGhpbmcgYW5kIHJlY3ljbGUgbm90aGluZyAqLwogIHN3aXRjaCAoaGRyLT5jb21tYW5kKSB7CiAgY2FzZSBDTURfSU5QVVQ6CiAgICAoKFJFUV9JTyopaGRyKS0+Y291bnQgPSAwOwogICAgaGRyLT5zdGF0dXMgPSBTVEFUX0RPTkU7CiAgICBicmVhazsKICBjYXNlIENNRF9TQUZFSU5QVVQ6CiAgICBoZHItPnN0YXR1cyA9IFNUQVRfRE9ORXxTVEFUX0JVU1k7CiAgICBicmVhazsKICBkZWZhdWx0OgogICAgaGRyLT5zdGF0dXMgPSBTVEFUX0RPTkU7CiAgfQogIGRvX2xyZXQoY3R4KTsKfQoKc3RhdGljIHZvaWQgV0lOQVBJIGNvbl9zdHJhdGVneShDT05URVhUODYqY3R4KQp7CiAgZG9fc3RyYXRlZ3koY3R4LCBTWVNURU1fU1RSQVRFR1lfQ09OLCBzaXplb2YoaW50KSk7Cn0KCnN0YXRpYyB2b2lkIFdJTkFQSSBjb25faW50ZXJydXB0KENPTlRFWFQ4NipjdHgpCnsKICBpbnQgKnNjYW47CiAgUkVRVUVTVF9IRUFERVIgKmhkciA9IGdldF9oZHIoU1lTVEVNX1NUUkFURUdZX0NPTiwodm9pZCAqKikmc2Nhbik7CiAgQklPU0RBVEEgKmJpb3MgPSBET1NNRU1fQmlvc0RhdGEoKTsKICBXT1JEIEN1ck9mcyA9IGJpb3MtPk5leHRLYmRDaGFyUHRyOwogIERPU19MSVNUT0ZMSVNUUyAqbG9sID0gRE9TTUVNX0xPTCgpOwogIERPU19EQVRBU0VHICpkYXRhc2VnID0gKERPU19EQVRBU0VHICopbG9sOwogIEJZVEUgKmxpbmVidWZmZXIgPSBkYXRhc2VnLT5idWZmZXI7CiAgQllURSAqY3VyYnVmZmVyID0gKGxvbC0+b2Zmc191bnJlYWRfQ09OKSA/CiAgICAoKChCWVRFKilkYXRhc2VnKSArIGxvbC0+b2Zmc191bnJlYWRfQ09OKSA6IChCWVRFKilOVUxMOwogIERPU19ERVZJQ0VfSEVBREVSICpjb24gPSBkYXRhc2VnLT5kZXY7CgogIHN3aXRjaCAoaGRyLT5jb21tYW5kKSB7CiAgY2FzZSBDTURfSU5QVVQ6CiAgICB7CiAgICAgIFJFUV9JTyAqaW8gPSAoUkVRX0lPICopaGRyOwogICAgICBXT1JEIGNvdW50ID0gaW8tPmNvdW50LCBsZW4gPSAwOwogICAgICBCWVRFICpidWZmZXIgPSBDVFhfU0VHX09GRl9UT19MSU4oY3R4LAoJCQkJCVNFTEVDVE9ST0YoaW8tPmJ1ZmZlciksCgkJCQkJKERXT1JEKU9GRlNFVE9GKGlvLT5idWZmZXIpKTsKCiAgICAgIGhkci0+c3RhdHVzID0gU1RBVF9CVVNZOwogICAgICAvKiBmaXJzdCwgY2hlY2sgd2hldGhlciB3ZSBhbHJlYWR5IGhhdmUgZGF0YSBpbiBsaW5lIGJ1ZmZlciAqLwogICAgICBpZiAoY3VyYnVmZmVyKSB7CgkvKiB5ZXAsIGNvcHkgYXMgbXVjaCBhcyB3ZSBjYW4gKi8KCUJZVEUgZGF0YSA9IDA7Cgl3aGlsZSAoKGxlbjxjb3VudCkgJiYgKGRhdGEgIT0gJ1xyJykpIHsKCSAgZGF0YSA9ICpjdXJidWZmZXIrKzsKCSAgYnVmZmVyW2xlbisrXSA9IGRhdGE7Cgl9CglpZiAoZGF0YSA9PSAnXHInKSB7CgkgIC8qIGxpbmUgYnVmZmVyIGVtcHRpZWQgKi8KCSAgbG9sLT5vZmZzX3VucmVhZF9DT04gPSAwOwoJICBjdXJidWZmZXIgPSBOVUxMOwoJICAvKiBpZiB3ZSdyZSBub3QgaW4gcmF3IG1vZGUsIGNhbGwgaXQgYSBkYXkgKi8KCSAgaWYgKCEoY29uLT5hdHRyICYgQVRUUl9SQVcpKSB7CgkgICAgaGRyLT5zdGF0dXMgPSBTVEFUX0RPTkU7CgkgICAgaW8tPmNvdW50ID0gbGVuOwoJICAgIGJyZWFrOwoJICB9Cgl9IGVsc2UgewoJICAvKiBzdGlsbCBzb21lIGRhdGEgbGVmdCAqLwoJICBsb2wtPm9mZnNfdW5yZWFkX0NPTiA9IGN1cmJ1ZmZlciAtIChCWVRFKilsb2w7CgkgIC8qIGJ1dCBidWZmZXIgd2FzIGZpbGxlZCwgd2UncmUgZG9uZSAqLwoJICBoZHItPnN0YXR1cyA9IFNUQVRfRE9ORTsKCSAgaW8tPmNvdW50ID0gbGVuOwoJICBicmVhazsKCX0KICAgICAgfQoKICAgICAgLyogaWYgd2UncmUgaW4gcmF3IG1vZGUsIHdlIGp1c3QgbmVlZCB0byBmaWxsIHRoZSBidWZmZXIgKi8KICAgICAgaWYgKGNvbi0+YXR0ciAmIEFUVFJfUkFXKSB7Cgl3aGlsZSAobGVuPGNvdW50KSB7CgkgIFdPUkQgZGF0YTsKCgkgIC8qIGRvIHdlIGhhdmUgYSB3YWl0aW5nIHNjYW5jb2RlPyAqLwoJICBpZiAoKnNjYW4pIHsKCSAgICAvKiB5ZXMsIHN0b3JlIHNjYW5jb2RlIGluIGJ1ZmZlciAqLwoJICAgIGJ1ZmZlcltsZW4rK10gPSAqc2NhbjsKCSAgICAqc2NhbiA9IDA7CgkgICAgaWYgKGxlbj09Y291bnQpIGJyZWFrOwoJICB9CgoJICAvKiBjaGVjayBmb3IgbmV3IGtleWJvYXJkIGlucHV0ICovCgkgIHdoaWxlIChDdXJPZnMgPT0gYmlvcy0+Rmlyc3RLYmRDaGFyUHRyKSB7CgkgICAgLyogbm8gaW5wdXQgYXZhaWxhYmxlIHlldCwgc28gd2FpdC4uLiAqLwoJICAgIERPU1ZNX1dhaXQoIC0xLCAwICk7CgkgIH0KCSAgLyogcmVhZCBmcm9tIGtleWJvYXJkIHF1ZXVlIChjYWxsIGludDE2PykgKi8KCSAgZGF0YSA9ICgoV09SRCopYmlvcylbQ3VyT2ZzXTsKCSAgQ3VyT2ZzICs9IDI7CgkgIGlmIChDdXJPZnMgPj0gYmlvcy0+S2JkQnVmZmVyRW5kKSBDdXJPZnMgPSBiaW9zLT5LYmRCdWZmZXJTdGFydDsKCSAgYmlvcy0+TmV4dEtiZENoYXJQdHIgPSBDdXJPZnM7CgkgIC8qIGlmIGl0J3MgYW4gZXh0ZW5kZWQga2V5LCBzYXZlIHNjYW5jb2RlICovCgkgIGlmIChMT0JZVEUoZGF0YSkgPT0gMCkgKnNjYW4gPSBISUJZVEUoZGF0YSk7CgkgIC8qIHN0b3JlIEFTQ0lJIGNoYXIgaW4gYnVmZmVyICovCgkgIGJ1ZmZlcltsZW4rK10gPSBMT0JZVEUoZGF0YSk7Cgl9CiAgICAgIH0gZWxzZSB7CgkvKiB3ZSdyZSBub3QgaW4gcmF3IG1vZGUsIHNvIHdlIG5lZWQgdG8gZG8gbGluZSBpbnB1dC4uLiAqLwoJd2hpbGUgKFRSVUUpIHsKCSAgV09SRCBkYXRhOwoJICAvKiBjaGVjayBmb3IgbmV3IGtleWJvYXJkIGlucHV0ICovCgkgIHdoaWxlIChDdXJPZnMgPT0gYmlvcy0+Rmlyc3RLYmRDaGFyUHRyKSB7CgkgICAgLyogbm8gaW5wdXQgYXZhaWxhYmxlIHlldCwgc28gd2FpdC4uLiAqLwoJICAgIERPU1ZNX1dhaXQoIC0xLCAwICk7CgkgIH0KCSAgLyogcmVhZCBmcm9tIGtleWJvYXJkIHF1ZXVlIChjYWxsIGludDE2PykgKi8KCSAgZGF0YSA9ICgoV09SRCopYmlvcylbQ3VyT2ZzXTsKCSAgQ3VyT2ZzICs9IDI7CgkgIGlmIChDdXJPZnMgPj0gYmlvcy0+S2JkQnVmZmVyRW5kKSBDdXJPZnMgPSBiaW9zLT5LYmRCdWZmZXJTdGFydDsKCSAgYmlvcy0+TmV4dEtiZENoYXJQdHIgPSBDdXJPZnM7CgoJICBpZiAoTE9CWVRFKGRhdGEpID09ICdccicpIHsKCSAgICAvKiBpdCdzIHRoZSByZXR1cm4ga2V5LCB3ZSdyZSBkb25lICovCgkgICAgbGluZWJ1ZmZlcltsZW4rK10gPSBMT0JZVEUoZGF0YSk7CgkgICAgYnJlYWs7CgkgIH0KCSAgZWxzZSBpZiAoTE9CWVRFKGRhdGEpID49ICcgJykgewoJICAgIC8qIGEgY2hhcmFjdGVyICovCgkgICAgaWYgKChsZW4rMSk8Q09OX0JVRkZFUikgewoJICAgICAgbGluZWJ1ZmZlcltsZW5dID0gTE9CWVRFKGRhdGEpOwoJICAgICAgV3JpdGVGaWxlKEdldFN0ZEhhbmRsZShTVERfT1VUUFVUX0hBTkRMRSksICZsaW5lYnVmZmVyW2xlbisrXSwgMSwgTlVMTCwgTlVMTCk7CgkgICAgfQoJICAgIC8qIGVsc2UgYmVlcCwgYnV0IEkgZG9uJ3QgbGlrZSBub2lzZSAqLwoJICB9CgkgIGVsc2Ugc3dpdGNoIChMT0JZVEUoZGF0YSkpIHsKCSAgY2FzZSAnXGInOgoJICAgIGlmIChsZW4+MCkgewoJICAgICAgbGVuLS07CgkgICAgICBXcml0ZUZpbGUoR2V0U3RkSGFuZGxlKFNURF9PVVRQVVRfSEFORExFKSwgIlxiIFxiIiwgMywgTlVMTCwgTlVMTCk7CgkgICAgfQoJICAgIGJyZWFrOwoJICB9Cgl9CglpZiAobGVuID4gY291bnQpIHsKCSAgLyogc2F2ZSByZXN0IG9mIGxpbmUgZm9yIGxhdGVyICovCgkgIGxvbC0+b2Zmc191bnJlYWRfQ09OID0gbGluZWJ1ZmZlciAtIChCWVRFKilsb2wgKyBjb3VudDsKCSAgbGVuID0gY291bnQ7Cgl9CgltZW1jcHkoYnVmZmVyLCBsaW5lYnVmZmVyLCBsZW4pOwogICAgICB9CiAgICAgIGhkci0+c3RhdHVzID0gU1RBVF9ET05FOwogICAgICBpby0+Y291bnQgPSBsZW47CiAgICB9CiAgICBicmVhazsKICBjYXNlIENNRF9TQUZFSU5QVVQ6CiAgICBpZiAoY3VyYnVmZmVyKSB7CiAgICAgIC8qIHNvbWUgbGluZSBpbnB1dCB3YWl0aW5nICovCiAgICAgIGhkci0+c3RhdHVzID0gU1RBVF9ET05FOwogICAgICAoKFJFUV9TQUZFSU5QVVQqKWhkciktPmRhdGEgPSAqY3VyYnVmZmVyOwogICAgfQogICAgZWxzZSBpZiAoY29uLT5hdHRyICYgQVRUUl9SQVcpIHsKICAgICAgaWYgKEN1ck9mcyA9PSBiaW9zLT5GaXJzdEtiZENoYXJQdHIpIHsKCS8qIG5vIGlucHV0ICovCgloZHItPnN0YXR1cyA9IFNUQVRfRE9ORXxTVEFUX0JVU1k7CiAgICAgIH0gZWxzZSB7CgkvKiBzb21lIGtleWJvYXJkIGlucHV0IHdhaXRpbmcgKi8KCWhkci0+c3RhdHVzID0gU1RBVF9ET05FOwoJKChSRVFfU0FGRUlOUFVUKiloZHIpLT5kYXRhID0gKChCWVRFKiliaW9zKVtDdXJPZnNdOwogICAgICB9CiAgICB9IGVsc2UgewogICAgICAvKiBubyBsaW5lIGlucHV0ICovCiAgICAgIGhkci0+c3RhdHVzID0gU1RBVF9ET05FfFNUQVRfQlVTWTsKICAgIH0KICAgIGJyZWFrOwogIGNhc2UgQ01EX0lOU1RBVFVTOgogICAgaWYgKGN1cmJ1ZmZlcikgewogICAgICAvKiB3ZSBoYXZlIGRhdGEgKi8KICAgICAgaGRyLT5zdGF0dXMgPSBTVEFUX0RPTkU7CiAgICB9CiAgICBlbHNlIGlmIChjb24tPmF0dHIgJiBBVFRSX1JBVykgewogICAgICBpZiAoQ3VyT2ZzID09IGJpb3MtPkZpcnN0S2JkQ2hhclB0cikgewoJLyogbm8gaW5wdXQgKi8KCWhkci0+c3RhdHVzID0gU1RBVF9ET05FfFNUQVRfQlVTWTsKICAgICAgfSBlbHNlIHsKCS8qIHNvbWUga2V5Ym9hcmQgaW5wdXQgd2FpdGluZyAqLwoJaGRyLT5zdGF0dXMgPSBTVEFUX0RPTkU7CiAgICAgIH0KICAgIH0gZWxzZSB7CiAgICAgIC8qIG5vIGxpbmUgaW5wdXQgKi8KICAgICAgaGRyLT5zdGF0dXMgPSBTVEFUX0RPTkV8U1RBVF9CVVNZOwogICAgfQoKICAgIGJyZWFrOwogIGNhc2UgQ01EX0lORkxVU0g6CiAgICAvKiBmbHVzaCBsaW5lIGFuZCBrZXlib2FyZCBxdWV1ZSAqLwogICAgbG9sLT5vZmZzX3VucmVhZF9DT04gPSAwOwogICAgYmlvcy0+TmV4dEtiZENoYXJQdHIgPSBiaW9zLT5GaXJzdEtiZENoYXJQdHI7CiAgICBicmVhazsKICBjYXNlIENNRF9PVVRQVVQ6CiAgY2FzZSBDTURfU0FGRU9VVFBVVDoKICAgIHsKICAgICAgUkVRX0lPICppbyA9IChSRVFfSU8gKiloZHI7CiAgICAgIEJZVEUgKmJ1ZmZlciA9IENUWF9TRUdfT0ZGX1RPX0xJTihjdHgsCgkJCQkJU0VMRUNUT1JPRihpby0+YnVmZmVyKSwKCQkJCQkoRFdPUkQpT0ZGU0VUT0YoaW8tPmJ1ZmZlcikpOwogICAgICBEV09SRCByZXN1bHQgPSAwOwogICAgICBXcml0ZUZpbGUoR2V0U3RkSGFuZGxlKFNURF9PVVRQVVRfSEFORExFKSwgYnVmZmVyLCBpby0+Y291bnQsICZyZXN1bHQsIE5VTEwpOwogICAgICBpby0+Y291bnQgPSByZXN1bHQ7CiAgICAgIGhkci0+c3RhdHVzID0gU1RBVF9ET05FOwogICAgfQogICAgYnJlYWs7CiAgZGVmYXVsdDoKICAgIGhkci0+c3RhdHVzID0gU1RBVF9ET05FOwogIH0KICBkb19scmV0KGN0eCk7Cn0KCnN0YXRpYyB2b2lkIEluaXRMaXN0T2ZMaXN0cyhET1NfTElTVE9GTElTVFMgKkRPU19MT0wpCnsKLyoKT3V0cHV0IG9mIERPUyA2LjIyOgoKMDEzMzowMDIwICAgICAgICAgICAgICAgICAgICA2QSAxMy0zMyAwMSBDQyAwMCAzMyAwMSA1OSAwMCAgICAgICAgIGouMy4uLjMuWS4KMDEzMzowMDMwICA3MCAwMCAwMCAwMCA3MiAwMiAwMCAwMi02RCAwMCAzMyAwMSAwMCAwMCAyRSAwNSAgIHAuLi5yLi4ubS4zLi4uLi4KMDEzMzowMDQwICAwMCAwMCBGQyAwNCAwMCAwMCAwMyAwOC05MiAyMSAxMSBFMCAwNCA4MCBDNiAwRCAgIC4uLi4uLi4uLiEuLi4uLi4KMDEzMzowMDUwICBDQyAwRCA0RSA1NSA0QyAyMCAyMCAyMC0yMCAyMCAwMCAwMCAwMCAwMCAwMCAwMCAgIC4uTlVMICAgICAuLi4uLi4KMDEzMzowMDYwICAwMCA0QiBCQSBDMSAwNiAxNCAwMCAwMC0wMCAwMyAwMSAwMCAwNCA3MCBDRSBGRiAgIC5LLi4uLi4uLi4uLi5wLi4KMDEzMzowMDcwICBGRiAwMCAwMCAwMCAwMCAwMCAwMCAwMC0wMCAwMSAwMCAwMCAwRCAwNSAwMCAwMCAgIC4uLi4uLi4uLi4uLi4uLi4KMDEzMzowMDgwICAwMCBGRiBGRiAwMCAwMCAwMCAwMCBGRS0wMCAwMCBGOCAwMyBGRiA5RiA3MCAwMiAgIC4uLi4uLi4uLi4uLi4ucC4KMDEzMzowMDkwICBEMCA0NCBDOCBGRCBENCA0NCBDOCBGRC1ENCA0NCBDOCBGRCBEMCA0NCBDOCBGRCAgIC5ELi4uRC4uLkQuLi5ELi4KMDEzMzowMEEwICBEMCA0NCBDOCBGRCBEMCA0NCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5ELi4uRAoqLwogIERPU19MT0wtPkNYX0ludDIxXzVlMDEJCT0gMHgwOwogIERPU19MT0wtPkxSVV9jb3VudF9GQ0JfY2FjaGUJPSAweDA7CiAgRE9TX0xPTC0+TFJVX2NvdW50X0ZDQl9vcGVuCQk9IDB4MDsKICBET1NfTE9MLT5PRU1fZnVuY19oYW5kbGVyCQk9IC0xOyAvKiBub3QgYXZhaWxhYmxlICovCiAgRE9TX0xPTC0+SU5UMjFfb2Zmc2V0CQk9IDB4MDsKICBET1NfTE9MLT5zaGFyaW5nX3JldHJ5X2NvdW50CT0gMzsKICBET1NfTE9MLT5zaGFyaW5nX3JldHJ5X2RlbGF5CT0gMTsKICBET1NfTE9MLT5wdHJfZGlza19idWYJCT0gMHgwOwogIERPU19MT0wtPm9mZnNfdW5yZWFkX0NPTgkJPSAweDA7CiAgRE9TX0xPTC0+c2VnX2ZpcnN0X01DQgkJPSAweDA7CiAgRE9TX0xPTC0+cHRyX2ZpcnN0X0RQQgkJPSAweDA7CiAgRE9TX0xPTC0+cHRyX2ZpcnN0X1N5c0ZpbGVUYWJsZQk9IDB4MDsKICBET1NfTE9MLT5wdHJfY2xvY2tfZGV2X2hkcgkJPSAweDA7CiAgRE9TX0xPTC0+cHRyX0NPTl9kZXZfaGRyCQk9IDB4MDsKICBET1NfTE9MLT5tYXhfYnl0ZV9wZXJfc2VjCQk9IDUxMjsKICBET1NfTE9MLT5wdHJfZGlza19idWZfaW5mbwkJPSAweDA7CiAgRE9TX0xPTC0+cHRyX2FycmF5X0NEUwkJPSAweDA7CiAgRE9TX0xPTC0+cHRyX3N5c19GQ0IJCT0gMHgwOwogIERPU19MT0wtPm5yX3Byb3RlY3RfRkNCCQk9IDB4MDsKICBET1NfTE9MLT5ucl9ibG9ja19kZXYJCT0gMHgwOwogIERPU19MT0wtPm5yX2F2YWlsX2RyaXZlX2xldHRlcnMJPSAyNjsgLyogQSAtIFogKi8KICBET1NfTE9MLT5ucl9kcml2ZXNfSk9JTmVkCQk9IDB4MDsKICBET1NfTE9MLT5wdHJfc3BlY19wcmdfbmFtZXMJCT0gMHgwOwogIERPU19MT0wtPnB0cl9TRVRWRVJfcHJnX2xpc3QJPSAweDA7IC8qIG5vIFNFVFZFUiBsaXN0ICovCiAgRE9TX0xPTC0+RE9TX0hJR0hfQTIwX2Z1bmNfb2Zmcwk9IDB4MDsKICBET1NfTE9MLT5QU1BfbGFzdF9leGVjCQk9IDB4MDsKICBET1NfTE9MLT5CVUZGRVJTX3ZhbAkJPSA5OTsgLyogbWF4aW11bTogOTkgKi8KICBET1NfTE9MLT5CVUZGRVJTX25yX2xvb2thaGVhZAk9IDg7IC8qIG1heGltdW06IDggKi8KICBET1NfTE9MLT5ib290X2RyaXZlCQkJPSAzOyAvKiBDOiAqLwogIERPU19MT0wtPmZsYWdfRFdPUkRfbW92ZXMJCT0gMHgwMTsgLyogaTM4NisgKi8KICBET1NfTE9MLT5zaXplX2V4dGVuZGVkX21lbQkJPSAweGYwMDA7IC8qIHZlcnkgaGlnaCB2YWx1ZSAqLwp9Cgp2b2lkIERPU0RFVl9JbnN0YWxsRE9TRGV2aWNlcyh2b2lkKQp7CiAgRE9TX0RBVEFTRUcgKmRhdGFzZWc7CiAgVUlOVDE2IHNlZzsKICB1bnNpZ25lZCBpbnQgbjsKCiAgLyogYWxsb2NhdGUgRE9TIGRhdGEgc2VnbWVudCBvciBzb21ldGhpbmcgKi8KICBET1NfTE9MU2VnID0gR2xvYmFsRE9TQWxsb2MxNihzaXplb2YoRE9TX0RBVEFTRUcpKTsKICBzZWcgPSBISVdPUkQoRE9TX0xPTFNlZyk7CiAgZGF0YXNlZyA9IE1hcFNMKCBNQUtFU0VHUFRSKExPV09SRChET1NfTE9MU2VnKSwgMCkgKTsKCiAgLyogaW5pdGlhbGl6ZSB0aGUgbWFnbmlmaWNlbnQgTGlzdCBPZiBMaXN0cyAqLwogIEluaXRMaXN0T2ZMaXN0cygmZGF0YXNlZy0+bG9sKTsKCiAgLyogU2V0IHVwIGZpcnN0IGRldmljZSAoTlVMKSAqLwogIGRhdGFzZWctPmxvbC5OVUxfZGV2Lm5leHRfZGV2ICA9IE1BS0VTRUdQVFIoc2VnLCBET1NfREFUQVNFR19PRkYoZGV2WzBdKSk7CiAgZGF0YXNlZy0+bG9sLk5VTF9kZXYuYXR0ciAgICAgID0gZGV2c1swXS5hdHRyOwogIGRhdGFzZWctPmxvbC5OVUxfZGV2LnN0cmF0ZWd5ICA9IERPU19EQVRBU0VHX09GRih0aHVua1swXS5sam1wMSk7CiAgZGF0YXNlZy0+bG9sLk5VTF9kZXYuaW50ZXJydXB0ID0gRE9TX0RBVEFTRUdfT0ZGKHRodW5rWzBdLmxqbXAyKTsKICBtZW1jcHkoZGF0YXNlZy0+bG9sLk5VTF9kZXYubmFtZSwgZGV2c1swXS5uYW1lLCA4KTsKCiAgLyogU2V0IHVwIHRoZSByZW1haW5pbmcgZGV2aWNlcyAqLwogIGZvciAobiA9IDE7IG4gPCBOUl9ERVZTOyBuKyspCiAgewogICAgZGF0YXNlZy0+ZGV2W24tMV0ubmV4dF9kZXYgID0gKG4rMSkgPT0gTlJfREVWUyA/IE5PTkVYVCA6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNQUtFU0VHUFRSKHNlZywgRE9TX0RBVEFTRUdfT0ZGKGRldltuXSkpOwogICAgZGF0YXNlZy0+ZGV2W24tMV0uYXR0ciAgICAgID0gZGV2c1tuXS5hdHRyOwogICAgZGF0YXNlZy0+ZGV2W24tMV0uc3RyYXRlZ3kgID0gRE9TX0RBVEFTRUdfT0ZGKHRodW5rW25dLmxqbXAxKTsKICAgIGRhdGFzZWctPmRldltuLTFdLmludGVycnVwdCA9IERPU19EQVRBU0VHX09GRih0aHVua1tuXS5sam1wMik7CiAgICBtZW1jcHkoZGF0YXNlZy0+ZGV2W24tMV0ubmFtZSwgZGV2c1tuXS5uYW1lLCA4KTsKICB9CgogIC8qIFNldCB1cCB0aHVua3MgKi8KICBmb3IgKG4gPSAwOyBuIDwgTlJfREVWUzsgbisrKQogIHsKICAgIGRhdGFzZWctPnRodW5rW25dLmxqbXAxICAgICA9IExKTVA7CiAgICBkYXRhc2VnLT50aHVua1tuXS5zdHJhdGVneSAgPSAoUk1DQlBST0MpRFBNSV9BbGxvY0ludGVybmFsUk1DQihkZXZzW25dLnN0cmF0ZWd5KTsKICAgIGRhdGFzZWctPnRodW5rW25dLmxqbXAyICAgICA9IExKTVA7CiAgICBkYXRhc2VnLT50aHVua1tuXS5pbnRlcnJ1cHQgPSAoUk1DQlBST0MpRFBNSV9BbGxvY0ludGVybmFsUk1DQihkZXZzW25dLmludGVycnVwdCk7CiAgfQoKICAvKiBDT04gaXMgZGV2aWNlIDEgKi8KICBkYXRhc2VnLT5sb2wucHRyX0NPTl9kZXZfaGRyID0gTUFLRVNFR1BUUihzZWcsIERPU19EQVRBU0VHX09GRihkZXZbMF0pKTsKfQoKRFdPUkQgRE9TREVWX0NvbnNvbGUodm9pZCkKewogIHJldHVybiBET1NNRU1fTE9MKCktPnB0cl9DT05fZGV2X2hkcjsKfQoKRFdPUkQgRE9TREVWX0ZpbmRDaGFyRGV2aWNlKGNoYXIqbmFtZSkKewogIFNFR1BUUiBjdXJfcHRyID0gTUFLRVNFR1BUUihISVdPUkQoRE9TX0xPTFNlZyksIEZJRUxEX09GRlNFVChET1NfTElTVE9GTElTVFMsTlVMX2RldikpOwogIERPU19ERVZJQ0VfSEVBREVSICpjdXIgPSBET1NNRU1fTWFwUmVhbFRvTGluZWFyKGN1cl9wdHIpOwogIGNoYXIgZG5hbWVbOF07CiAgaW50IGNudDsKCiAgLyogZ2V0IGZpcnN0IDggY2hhcmFjdGVycyAqLwogIHN0cm5jcHkoZG5hbWUsbmFtZSw4KTsKICAvKiBpZiBsZXNzIHRoYW4gOCBjaGFyYWN0ZXJzLCBwYWQgd2l0aCBzcGFjZXMgKi8KICBmb3IgKGNudD0wOyBjbnQ8ODsgY250KyspCiAgICBpZiAoIWRuYW1lW2NudF0pIGRuYW1lW2NudF09JyAnOwoKICAvKiBzZWFyY2ggZm9yIGNoYXIgZGV2aWNlcyB3aXRoIHRoZSByaWdodCBuYW1lICovCiAgd2hpbGUgKGN1ciAmJgoJICgoIShjdXItPmF0dHIgJiBBVFRSX0NIQVIpKSB8fAoJICBtZW1jbXAoY3VyLT5uYW1lLGRuYW1lLDgpKSkgewogICAgY3VyX3B0ciA9IGN1ci0+bmV4dF9kZXY7CiAgICBpZiAoY3VyX3B0ciA9PSBOT05FWFQpIGN1cj1OVUxMOwogICAgZWxzZSBjdXIgPSBET1NNRU1fTWFwUmVhbFRvTGluZWFyKGN1cl9wdHIpOwogIH0KICByZXR1cm4gY3VyX3B0cjsKfQoKc3RhdGljIHZvaWQgRE9TREVWX0RvUmVxKHZvaWQqcmVxLCBEV09SRCBkZXYpCnsKICBSRVFVRVNUX0hFQURFUiAqaGRyID0gKFJFUVVFU1RfSEVBREVSICopcmVxOwogIERPU19ERVZJQ0VfSEVBREVSICpkaGRyOwogIENPTlRFWFQ4NiBjdHg7CiAgY2hhciAqcGhkcjsKCiAgZGhkciA9IERPU01FTV9NYXBSZWFsVG9MaW5lYXIoZGV2KTsKICBwaGRyID0gKChjaGFyKilET1NNRU1fTE9MKCkpICsgRE9TX0RBVEFTRUdfT0ZGKHJlcSk7CgogIC8qIGNvcHkgcmVxdWVzdCB0byByZXF1ZXN0IHNjcmF0Y2ggYXJlYSAqLwogIG1lbWNweShwaGRyLCByZXEsIGhkci0+c2l6ZSk7CgogIC8qIHByZXBhcmUgdG8gY2FsbCBkZXZpY2UgZHJpdmVyICovCiAgbWVtc2V0KCZjdHgsIDAsIHNpemVvZihjdHgpKTsKCiAgLyogRVM6QlggcG9pbnRzIHRvIHJlcXVlc3QgZm9yIHN0cmF0ZWd5IHJvdXRpbmUgKi8KICBjdHguU2VnRXMgPSBISVdPUkQoRE9TX0xPTFNlZyk7CiAgY3R4LkVieCAgID0gRE9TX0RBVEFTRUdfT0ZGKHJlcSk7CgogIC8qIGNhbGwgc3RyYXRlZ3kgcm91dGluZSAqLwogIGN0eC5TZWdDcyA9IFNFTEVDVE9ST0YoZGV2KTsKICBjdHguRWlwICAgPSBkaGRyLT5zdHJhdGVneTsKICBEUE1JX0NhbGxSTVByb2MoJmN0eCwgMCwgMCwgMCk7CgogIC8qIGNhbGwgaW50ZXJydXB0IHJvdXRpbmUgKi8KICBjdHguU2VnQ3MgPSBTRUxFQ1RPUk9GKGRldik7CiAgY3R4LkVpcCAgID0gZGhkci0+aW50ZXJydXB0OwogIERQTUlfQ2FsbFJNUHJvYygmY3R4LCAwLCAwLCAwKTsKCiAgLyogY29tcGxldGVkLCBjb3B5IHJlcXVlc3QgYmFjayAqLwogIG1lbWNweShyZXEsIHBoZHIsIGhkci0+c2l6ZSk7CgogIGlmIChoZHItPnN0YXR1cyAmIFNUQVRfRVJST1IpIHsKICAgIHN3aXRjaCAoaGRyLT5zdGF0dXMgJiBTVEFUX01BU0spIHsKICAgIGNhc2UgMHgwRjogLyogaW52YWxpZCBkaXNrIGNoYW5nZSAqLwogICAgICAvKiB0aGlzIGVycm9yIHNlZW1zIHRvIGZpdCB0aGUgYmlsbCAqLwogICAgICBTZXRMYXN0RXJyb3IoRVJfTm90U2FtZURldmljZSk7CiAgICAgIGJyZWFrOwogICAgZGVmYXVsdDoKICAgICAgU2V0TGFzdEVycm9yKChoZHItPnN0YXR1cyAmIFNUQVRfTUFTSykgKyAweDEzKTsKICAgICAgYnJlYWs7CiAgICB9CiAgfQp9CgpzdGF0aWMgaW50IERPU0RFVl9JTyh1bnNpZ25lZCBjbWQsIERXT1JEIGRldiwgRFdPUkQgYnVmLCBpbnQgYnVmbGVuKQp7CiAgUkVRX0lPIHJlcTsKCiAgcmVxLmhkci5zaXplPXNpemVvZihyZXEpOwogIHJlcS5oZHIudW5pdD0wOyAvKiBub3QgZGVhbGluZyB3aXRoIGJsb2NrIGRldmljZXMgeWV0ICovCiAgcmVxLmhkci5jb21tYW5kPWNtZDsKICByZXEuaGRyLnN0YXR1cz1TVEFUX0JVU1k7CiAgcmVxLm1lZGlhPTA7IC8qIG5vdCBkZWFsaW5nIHdpdGggYmxvY2sgZGV2aWNlcyB5ZXQgKi8KICByZXEuYnVmZmVyPWJ1ZjsKICByZXEuY291bnQ9YnVmbGVuOwogIHJlcS5zZWN0b3I9MDsgLyogYmxvY2sgZGV2aWNlcyAqLwogIHJlcS52b2x1bWU9MDsgLyogYmxvY2sgZGV2aWNlcyAqLwoKICBET1NERVZfRG9SZXEoJnJlcSwgZGV2KTsKCiAgcmV0dXJuIHJlcS5jb3VudDsKfQoKaW50IERPU0RFVl9QZWVrKERXT1JEIGRldiwgQllURSpkYXRhKQp7CiAgUkVRX1NBRkVJTlBVVCByZXE7CgogIHJlcS5oZHIuc2l6ZT1zaXplb2YocmVxKTsKICByZXEuaGRyLnVuaXQ9MDsgLyogbm90IGRlYWxpbmcgd2l0aCBibG9jayBkZXZpY2VzIHlldCAqLwogIHJlcS5oZHIuY29tbWFuZD1DTURfU0FGRUlOUFVUOwogIHJlcS5oZHIuc3RhdHVzPVNUQVRfQlVTWTsKICByZXEuZGF0YT0wOwoKICBET1NERVZfRG9SZXEoJnJlcSwgZGV2KTsKCiAgaWYgKHJlcS5oZHIuc3RhdHVzICYgU1RBVF9CVVNZKSByZXR1cm4gMDsKCiAgKmRhdGEgPSByZXEuZGF0YTsKICByZXR1cm4gMTsKfQoKaW50IERPU0RFVl9SZWFkKERXT1JEIGRldiwgRFdPUkQgYnVmLCBpbnQgYnVmbGVuKQp7CiAgcmV0dXJuIERPU0RFVl9JTyhDTURfSU5QVVQsIGRldiwgYnVmLCBidWZsZW4pOwp9CgppbnQgRE9TREVWX1dyaXRlKERXT1JEIGRldiwgRFdPUkQgYnVmLCBpbnQgYnVmbGVuLCBpbnQgdmVyaWZ5KQp7CiAgcmV0dXJuIERPU0RFVl9JTyh2ZXJpZnk/Q01EX1NBRkVPVVRQVVQ6Q01EX09VVFBVVCwgZGV2LCBidWYsIGJ1Zmxlbik7Cn0KCmludCBET1NERVZfSW9jdGxSZWFkKERXT1JEIGRldiwgRFdPUkQgYnVmLCBpbnQgYnVmbGVuKQp7CiAgcmV0dXJuIERPU0RFVl9JTyhDTURfSU5JT0NUTCwgZGV2LCBidWYsIGJ1Zmxlbik7Cn0KCmludCBET1NERVZfSW9jdGxXcml0ZShEV09SRCBkZXYsIERXT1JEIGJ1ZiwgaW50IGJ1ZmxlbikKewogIHJldHVybiBET1NERVZfSU8oQ01EX09VVElPQ1RMLCBkZXYsIGJ1ZiwgYnVmbGVuKTsKfQo=