LyoKICogQ29weXJpZ2h0IChDKSAyMDA4IE9sZSBBbmRy6SBWYWRsYSBSYXZu5XMgPG9sZS5hbmRyZS5yYXZuYXNAdGFuZGJlcmcuY29tPgogKgogKiBUaGlzIGxpYnJhcnkgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yCiAqIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMaWJyYXJ5IEdlbmVyYWwgUHVibGljCiAqIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlcgogKiB2ZXJzaW9uIDIgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLAogKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZgogKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVQogKiBMaWJyYXJ5IEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIExpYnJhcnkgR2VuZXJhbCBQdWJsaWMKICogTGljZW5zZSBhbG9uZyB3aXRoIHRoaXMgbGlicmFyeTsgaWYgbm90LCB3cml0ZSB0byB0aGUKICogRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsCiAqIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSwgVVNBLgogKi8KCiNpbmNsdWRlICJrc2hlbHBlcnMuaCIKCi8qIFRoaXMgcGx1Z2luIGlzIGZyb20gdGhlIGVyYSBvZiBXaW5kb3dzIFhQIGFuZCB1c2VzIEFQSXMgdGhhdCBoYXZlIGJlZW4KICogZGVwcmVjYXRlZCBzaW5jZSB0aGVuLiBMZXQncyBwcmV0ZW5kIHdlJ3JlIFdpbmRvd3MgWFAgdG9vIHNvIHRoYXQgV2luZG93cwogKiBsZXRzIHVzIHVzZSB0aGF0IGRlcHJlY2F0ZWQgQVBJLiAqLwojZGVmaW5lIE5URERJX1ZFUlNJT04gTlRERElfV0lOWFAKI2RlZmluZSBfV0lOMzJfV0lOTlQgX1dJTjMyX1dJTk5UX1dJTlhQCgojaW5jbHVkZSA8a3NtZWRpYS5oPgojaW5jbHVkZSA8c2V0dXBhcGkuaD4KI2luY2x1ZGUgPGdzdC9nc3QuaD4KCkdTVF9ERUJVR19DQVRFR09SWV9FWFRFUk4gKGdzdF9rc19kZWJ1Zyk7CiNkZWZpbmUgR1NUX0NBVF9ERUZBVUxUIGdzdF9rc19kZWJ1ZwoKI2lmbmRlZiBTVEFUSUNfS1NQUk9QU0VUSURfV2F2ZV9RdWV1ZWQKI2RlZmluZSBTVEFUSUNfS1NQUk9QU0VUSURfV2F2ZV9RdWV1ZWQgXAogICAgMHgxNmExNWIxMEwsIDB4MTZmMCwgMHgxMWQwLCB7IDB4YTEsIDB4OTUsIDB4MDAsIDB4MjAsIDB4YWYsIDB4ZDEsIDB4NTYsIDB4ZTQgfQpERUZJTkVfR1VJRFNUUlVDVCAoIjE2YTE1YjEwLTE2ZjAtMTFkMC1hMTk1LTAwMjBhZmQxNTZlNCIsCiAgICBLU1BST1BTRVRJRF9XYXZlX1F1ZXVlZCk7CiNlbmRpZgoKZ2Jvb2xlYW4Ka3NfaXNfdmFsaWRfaGFuZGxlIChIQU5ETEUgaCkKewogIHJldHVybiAoaCAhPSBJTlZBTElEX0hBTkRMRV9WQUxVRSAmJiBoICE9IE5VTEwpOwp9CgpHTGlzdCAqCmtzX2VudW1lcmF0ZV9kZXZpY2VzIChjb25zdCBHVUlEICogZGV2dHlwZSwgY29uc3QgR1VJRCAqIGRpcmVjdGlvbl9jYXRlZ29yeSkKewogIEdMaXN0ICpyZXN1bHQgPSBOVUxMOwogIEhERVZJTkZPIGRldmluZm87CiAgZ2ludCBpOwoKICBkZXZpbmZvID0gU2V0dXBEaUdldENsYXNzRGV2c1cgKGRldnR5cGUsIE5VTEwsIE5VTEwsCiAgICAgIERJR0NGX1BSRVNFTlQgfCBESUdDRl9ERVZJQ0VJTlRFUkZBQ0UpOwogIGlmICgha3NfaXNfdmFsaWRfaGFuZGxlIChkZXZpbmZvKSkKICAgIHJldHVybiBOVUxMOyAgICAgICAgICAgICAgICAvKiBubyBkZXZpY2VzICovCgogIGZvciAoaSA9IDA7OyBpKyspIHsKICAgIEJPT0wgc3VjY2VzczsKICAgIFNQX0RFVklDRV9JTlRFUkZBQ0VfREFUQSBpZl9kYXRhID0geyAwLCB9OwogICAgU1BfREVWSUNFX0lOVEVSRkFDRV9EQVRBIGlmX2FsaWFzX2RhdGEgPSB7IDAsIH07CiAgICBTUF9ERVZJQ0VfSU5URVJGQUNFX0RFVEFJTF9EQVRBX1cgKmlmX2RldGFpbF9kYXRhOwogICAgRFdPUkQgaWZfZGV0YWlsX2RhdGFfc2l6ZTsKICAgIFNQX0RFVklORk9fREFUQSBkZXZpbmZvX2RhdGEgPSB7IDAsIH07CiAgICBEV09SRCByZXFfc2l6ZTsKCiAgICBpZl9kYXRhLmNiU2l6ZSA9IHNpemVvZiAoU1BfREVWSUNFX0lOVEVSRkFDRV9EQVRBKTsKCiAgICBzdWNjZXNzID0gU2V0dXBEaUVudW1EZXZpY2VJbnRlcmZhY2VzIChkZXZpbmZvLCBOVUxMLCBkZXZ0eXBlLCBpLCAmaWZfZGF0YSk7CiAgICBpZiAoIXN1Y2Nlc3MpICAgICAgICAgICAgICAgLyogYWxsIGRldmljZXMgZW51bWVyYXRlZD8gKi8KICAgICAgYnJlYWs7CgogICAgaWZfYWxpYXNfZGF0YS5jYlNpemUgPSBzaXplb2YgKFNQX0RFVklDRV9JTlRFUkZBQ0VfREFUQSk7CiAgICBzdWNjZXNzID0KICAgICAgICBTZXR1cERpR2V0RGV2aWNlSW50ZXJmYWNlQWxpYXMgKGRldmluZm8sICZpZl9kYXRhLCBkaXJlY3Rpb25fY2F0ZWdvcnksCiAgICAgICAgJmlmX2FsaWFzX2RhdGEpOwogICAgaWYgKCFzdWNjZXNzKQogICAgICBjb250aW51ZTsKCiAgICBpZl9kZXRhaWxfZGF0YV9zaXplID0gKE1BWF9QQVRIIC0gMSkgKiBzaXplb2YgKGd1bmljaGFyMik7CiAgICBpZl9kZXRhaWxfZGF0YSA9IGdfbWFsbG9jMCAoaWZfZGV0YWlsX2RhdGFfc2l6ZSk7CiAgICBpZl9kZXRhaWxfZGF0YS0+Y2JTaXplID0gc2l6ZW9mIChTUF9ERVZJQ0VfSU5URVJGQUNFX0RFVEFJTF9EQVRBX1cpOwoKICAgIGRldmluZm9fZGF0YS5jYlNpemUgPSBzaXplb2YgKFNQX0RFVklORk9fREFUQSk7CgogICAgc3VjY2VzcyA9IFNldHVwRGlHZXREZXZpY2VJbnRlcmZhY2VEZXRhaWxXIChkZXZpbmZvLCAmaWZfZGF0YSwKICAgICAgICBpZl9kZXRhaWxfZGF0YSwgaWZfZGV0YWlsX2RhdGFfc2l6ZSwgJnJlcV9zaXplLCAmZGV2aW5mb19kYXRhKTsKICAgIGlmIChzdWNjZXNzKSB7CiAgICAgIEtzRGV2aWNlRW50cnkgKmVudHJ5OwogICAgICBXQ0hBUiBidWZbNTEyXTsKCiAgICAgIGVudHJ5ID0gZ19uZXcwIChLc0RldmljZUVudHJ5LCAxKTsKICAgICAgZW50cnktPmluZGV4ID0gaTsKICAgICAgZW50cnktPnBhdGggPQogICAgICAgICAgZ191dGYxNl90b191dGY4IChpZl9kZXRhaWxfZGF0YS0+RGV2aWNlUGF0aCwgLTEsIE5VTEwsIE5VTEwsIE5VTEwpOwoKICAgICAgaWYgKFNldHVwRGlHZXREZXZpY2VSZWdpc3RyeVByb3BlcnR5VyAoZGV2aW5mbywgJmRldmluZm9fZGF0YSwKICAgICAgICAgICAgICBTUERSUF9GUklFTkRMWU5BTUUsIE5VTEwsIChCWVRFICopIGJ1Ziwgc2l6ZW9mIChidWYpLCBOVUxMKSkgewogICAgICAgIGVudHJ5LT5uYW1lID0gZ191dGYxNl90b191dGY4IChidWYsIC0xLCBOVUxMLCBOVUxMLCBOVUxMKTsKICAgICAgfQoKICAgICAgaWYgKGVudHJ5LT5uYW1lID09IE5VTEwpIHsKICAgICAgICBpZiAoU2V0dXBEaUdldERldmljZVJlZ2lzdHJ5UHJvcGVydHlXIChkZXZpbmZvLCAmZGV2aW5mb19kYXRhLAogICAgICAgICAgICAgICAgU1BEUlBfREVWSUNFREVTQywgTlVMTCwgKEJZVEUgKikgYnVmLCBzaXplb2YgKGJ1ZiksIE5VTEwpKSB7CiAgICAgICAgICBlbnRyeS0+bmFtZSA9IGdfdXRmMTZfdG9fdXRmOCAoYnVmLCAtMSwgTlVMTCwgTlVMTCwgTlVMTCk7CiAgICAgICAgfQogICAgICB9CgogICAgICBpZiAoZW50cnktPm5hbWUgIT0gTlVMTCkKICAgICAgICByZXN1bHQgPSBnX2xpc3RfcHJlcGVuZCAocmVzdWx0LCBlbnRyeSk7CiAgICAgIGVsc2UKICAgICAgICBrc19kZXZpY2VfZW50cnlfZnJlZSAoZW50cnkpOwogICAgfQoKICAgIGdfZnJlZSAoaWZfZGV0YWlsX2RhdGEpOwogIH0KCiAgU2V0dXBEaURlc3Ryb3lEZXZpY2VJbmZvTGlzdCAoZGV2aW5mbyk7CgogIHJldHVybiBnX2xpc3RfcmV2ZXJzZSAocmVzdWx0KTsKfQoKdm9pZAprc19kZXZpY2VfZW50cnlfZnJlZSAoS3NEZXZpY2VFbnRyeSAqIGVudHJ5KQp7CiAgaWYgKGVudHJ5ID09IE5VTEwpCiAgICByZXR1cm47CgogIGdfZnJlZSAoZW50cnktPnBhdGgpOwogIGdfZnJlZSAoZW50cnktPm5hbWUpOwoKICBnX2ZyZWUgKGVudHJ5KTsKfQoKdm9pZAprc19kZXZpY2VfbGlzdF9mcmVlIChHTGlzdCAqIGRldmljZXMpCnsKICBHTGlzdCAqY3VyOwoKICBmb3IgKGN1ciA9IGRldmljZXM7IGN1ciAhPSBOVUxMOyBjdXIgPSBjdXItPm5leHQpCiAgICBrc19kZXZpY2VfZW50cnlfZnJlZSAoY3VyLT5kYXRhKTsKCiAgZ19saXN0X2ZyZWUgKGRldmljZXMpOwp9CgpzdGF0aWMgZ2Jvb2xlYW4Ka3Nfc3luY19kZXZpY2VfaW9fY29udHJvbCAoSEFORExFIGRldmljZSwgZ3Vsb25nIGlvX2NvbnRyb2xfY29kZSwKICAgIGdwb2ludGVyIGluX2J1ZmZlciwgZ3Vsb25nIGluX2J1ZmZlcl9zaXplLCBncG9pbnRlciBvdXRfYnVmZmVyLAogICAgZ3Vsb25nIG91dF9idWZmZXJfc2l6ZSwgZ3Vsb25nICogYnl0ZXNfcmV0dXJuZWQsIGd1bG9uZyAqIGVycm9yKQp7CiAgT1ZFUkxBUFBFRCBvdmVybGFwcGVkID0geyAwLCB9OwogIEJPT0wgc3VjY2VzczsKCiAgb3ZlcmxhcHBlZC5oRXZlbnQgPSBDcmVhdGVFdmVudCAoTlVMTCwgVFJVRSwgRkFMU0UsIE5VTEwpOwoKICBzdWNjZXNzID0gRGV2aWNlSW9Db250cm9sIChkZXZpY2UsIGlvX2NvbnRyb2xfY29kZSwgaW5fYnVmZmVyLAogICAgICBpbl9idWZmZXJfc2l6ZSwgb3V0X2J1ZmZlciwgb3V0X2J1ZmZlcl9zaXplLCBieXRlc19yZXR1cm5lZCwgJm92ZXJsYXBwZWQpOwogIGlmICghc3VjY2VzcykgewogICAgRFdPUkQgZXJyOwoKICAgIGlmICgoZXJyID0gR2V0TGFzdEVycm9yICgpKSA9PSBFUlJPUl9JT19QRU5ESU5HKSB7CiAgICAgIHN1Y2Nlc3MgPSBHZXRPdmVybGFwcGVkUmVzdWx0IChkZXZpY2UsICZvdmVybGFwcGVkLCBieXRlc19yZXR1cm5lZCwgVFJVRSk7CiAgICAgIGlmICghc3VjY2VzcykKICAgICAgICBlcnIgPSBHZXRMYXN0RXJyb3IgKCk7CiAgICB9CgogICAgaWYgKGVycm9yICE9IE5VTEwpCiAgICAgICplcnJvciA9IGVycjsKICB9CgogIENsb3NlSGFuZGxlIChvdmVybGFwcGVkLmhFdmVudCk7CgogIHJldHVybiBzdWNjZXNzID8gVFJVRSA6IEZBTFNFOwp9CgpnYm9vbGVhbgprc19maWx0ZXJfZ2V0X3Bpbl9wcm9wZXJ0eSAoSEFORExFIGZpbHRlcl9oYW5kbGUsIGd1bG9uZyBwaW5faWQsCiAgICBHVUlEIHByb3Bfc2V0LCBndWxvbmcgcHJvcF9pZCwgZ3BvaW50ZXIgdmFsdWUsIGd1bG9uZyB2YWx1ZV9zaXplLAogICAgZ3Vsb25nICogZXJyb3IpCnsKICBLU1BfUElOIHByb3A7CiAgRFdPUkQgYnl0ZXNfcmV0dXJuZWQgPSAwOwoKICBtZW1zZXQgKCZwcm9wLCAwLCBzaXplb2YgKEtTUF9QSU4pKTsKCiAgcHJvcC5QaW5JZCA9IHBpbl9pZDsKICBwcm9wLlByb3BlcnR5LlNldCA9IHByb3Bfc2V0OwogIHByb3AuUHJvcGVydHkuSWQgPSBwcm9wX2lkOwogIHByb3AuUHJvcGVydHkuRmxhZ3MgPSBLU1BST1BFUlRZX1RZUEVfR0VUOwoKICByZXR1cm4ga3Nfc3luY19kZXZpY2VfaW9fY29udHJvbCAoZmlsdGVyX2hhbmRsZSwgSU9DVExfS1NfUFJPUEVSVFksICZwcm9wLAogICAgICBzaXplb2YgKHByb3ApLCB2YWx1ZSwgdmFsdWVfc2l6ZSwgJmJ5dGVzX3JldHVybmVkLCBlcnJvcik7Cn0KCmdib29sZWFuCmtzX2ZpbHRlcl9nZXRfcGluX3Byb3BlcnR5X211bHRpIChIQU5ETEUgZmlsdGVyX2hhbmRsZSwgZ3Vsb25nIHBpbl9pZCwKICAgIEdVSUQgcHJvcF9zZXQsIGd1bG9uZyBwcm9wX2lkLCBLU01VTFRJUExFX0lURU0gKiogaXRlbXMsIGd1bG9uZyAqIGVycm9yKQp7CiAgS1NQX1BJTiBwcm9wOwogIERXT1JEIGl0ZW1zX3NpemUgPSAwLCBieXRlc193cml0dGVuID0gMDsKICBndWxvbmcgZXJyOwogIGdib29sZWFuIHJldDsKCiAgbWVtc2V0ICgmcHJvcCwgMCwgc2l6ZW9mIChLU1BfUElOKSk7CiAgKml0ZW1zID0gTlVMTDsKCiAgcHJvcC5QaW5JZCA9IHBpbl9pZDsKICBwcm9wLlByb3BlcnR5LlNldCA9IHByb3Bfc2V0OwogIHByb3AuUHJvcGVydHkuSWQgPSBwcm9wX2lkOwogIHByb3AuUHJvcGVydHkuRmxhZ3MgPSBLU1BST1BFUlRZX1RZUEVfR0VUOwoKICByZXQgPSBrc19zeW5jX2RldmljZV9pb19jb250cm9sIChmaWx0ZXJfaGFuZGxlLCBJT0NUTF9LU19QUk9QRVJUWSwKICAgICAgJnByb3AuUHJvcGVydHksIHNpemVvZiAocHJvcCksIE5VTEwsIDAsICZpdGVtc19zaXplLCAmZXJyKTsKICBpZiAoIXJldCAmJiBlcnIgIT0gRVJST1JfSU5TVUZGSUNJRU5UX0JVRkZFUiAmJiBlcnIgIT0gRVJST1JfTU9SRV9EQVRBKQogICAgZ290byBpb2N0bF9mYWlsZWQ7CgogICppdGVtcyA9IGdfbWFsbG9jMCAoaXRlbXNfc2l6ZSk7CgogIHJldCA9IGtzX3N5bmNfZGV2aWNlX2lvX2NvbnRyb2wgKGZpbHRlcl9oYW5kbGUsIElPQ1RMX0tTX1BST1BFUlRZLCAmcHJvcCwKICAgICAgc2l6ZW9mIChwcm9wKSwgKml0ZW1zLCBpdGVtc19zaXplLCAmYnl0ZXNfd3JpdHRlbiwgJmVycik7CiAgaWYgKCFyZXQpCiAgICBnb3RvIGlvY3RsX2ZhaWxlZDsKCiAgcmV0dXJuIHJldDsKCmlvY3RsX2ZhaWxlZDoKICBpZiAoZXJyb3IgIT0gTlVMTCkKICAgICplcnJvciA9IGVycjsKCiAgZ19mcmVlICgqaXRlbXMpOwogICppdGVtcyA9IE5VTEw7CgogIHJldHVybiBGQUxTRTsKfQoKZ2Jvb2xlYW4Ka3Nfb2JqZWN0X3F1ZXJ5X3Byb3BlcnR5IChIQU5ETEUgaGFuZGxlLCBHVUlEIHByb3Bfc2V0LCBndWxvbmcgcHJvcF9pZCwKICAgIGd1bG9uZyBwcm9wX2ZsYWdzLCBncG9pbnRlciAqIHZhbHVlLCBndWxvbmcgKiB2YWx1ZV9zaXplLCBndWxvbmcgKiBlcnJvcikKewogIEtTUFJPUEVSVFkgcHJvcDsKICBEV09SRCByZXFfdmFsdWVfc2l6ZSA9IDAsIGJ5dGVzX3dyaXR0ZW4gPSAwOwogIGd1bG9uZyBlcnI7CiAgZ2Jvb2xlYW4gcmV0OwoKICBtZW1zZXQgKCZwcm9wLCAwLCBzaXplb2YgKEtTUFJPUEVSVFkpKTsKICAqdmFsdWUgPSBOVUxMOwoKICBwcm9wLlNldCA9IHByb3Bfc2V0OwogIHByb3AuSWQgPSBwcm9wX2lkOwogIHByb3AuRmxhZ3MgPSBwcm9wX2ZsYWdzOwoKICBpZiAodmFsdWVfc2l6ZSA9PSBOVUxMIHx8ICp2YWx1ZV9zaXplID09IDApIHsKICAgIHJldCA9IGtzX3N5bmNfZGV2aWNlX2lvX2NvbnRyb2wgKGhhbmRsZSwgSU9DVExfS1NfUFJPUEVSVFksCiAgICAgICAgJnByb3AsIHNpemVvZiAocHJvcCksIE5VTEwsIDAsICZyZXFfdmFsdWVfc2l6ZSwgJmVycik7CiAgICBpZiAoIXJldCAmJiBlcnIgIT0gRVJST1JfSU5TVUZGSUNJRU5UX0JVRkZFUiAmJiBlcnIgIT0gRVJST1JfTU9SRV9EQVRBKQogICAgICBnb3RvIGlvY3RsX2ZhaWxlZDsKICB9IGVsc2UgewogICAgcmVxX3ZhbHVlX3NpemUgPSAqdmFsdWVfc2l6ZTsKICB9CgogICp2YWx1ZSA9IGdfbWFsbG9jMCAocmVxX3ZhbHVlX3NpemUpOwoKICByZXQgPSBrc19zeW5jX2RldmljZV9pb19jb250cm9sIChoYW5kbGUsIElPQ1RMX0tTX1BST1BFUlRZLCAmcHJvcCwKICAgICAgc2l6ZW9mIChwcm9wKSwgKnZhbHVlLCByZXFfdmFsdWVfc2l6ZSwgJmJ5dGVzX3dyaXR0ZW4sICZlcnIpOwogIGlmICghcmV0KQogICAgZ290byBpb2N0bF9mYWlsZWQ7CgogIGlmICh2YWx1ZV9zaXplICE9IE5VTEwpCiAgICAqdmFsdWVfc2l6ZSA9IGJ5dGVzX3dyaXR0ZW47CgogIHJldHVybiByZXQ7Cgppb2N0bF9mYWlsZWQ6CiAgaWYgKGVycm9yICE9IE5VTEwpCiAgICAqZXJyb3IgPSBlcnI7CgogIGdfZnJlZSAoKnZhbHVlKTsKICAqdmFsdWUgPSBOVUxMOwoKICBpZiAodmFsdWVfc2l6ZSAhPSBOVUxMKQogICAgKnZhbHVlX3NpemUgPSAwOwoKICByZXR1cm4gRkFMU0U7Cn0KCmdib29sZWFuCmtzX29iamVjdF9nZXRfcHJvcGVydHkgKEhBTkRMRSBoYW5kbGUsIEdVSUQgcHJvcF9zZXQsIGd1bG9uZyBwcm9wX2lkLAogICAgZ3BvaW50ZXIgKiB2YWx1ZSwgZ3Vsb25nICogdmFsdWVfc2l6ZSwgZ3Vsb25nICogZXJyb3IpCnsKICByZXR1cm4ga3Nfb2JqZWN0X3F1ZXJ5X3Byb3BlcnR5IChoYW5kbGUsIHByb3Bfc2V0LCBwcm9wX2lkLAogICAgICBLU1BST1BFUlRZX1RZUEVfR0VULCB2YWx1ZSwgdmFsdWVfc2l6ZSwgZXJyb3IpOwp9CgpnYm9vbGVhbgprc19vYmplY3Rfc2V0X3Byb3BlcnR5IChIQU5ETEUgaGFuZGxlLCBHVUlEIHByb3Bfc2V0LCBndWxvbmcgcHJvcF9pZCwKICAgIGdwb2ludGVyIHZhbHVlLCBndWxvbmcgdmFsdWVfc2l6ZSwgZ3Vsb25nICogZXJyb3IpCnsKICBLU1BST1BFUlRZIHByb3A7CiAgRFdPUkQgYnl0ZXNfcmV0dXJuZWQ7CgogIG1lbXNldCAoJnByb3AsIDAsIHNpemVvZiAoS1NQUk9QRVJUWSkpOwogIHByb3AuU2V0ID0gcHJvcF9zZXQ7CiAgcHJvcC5JZCA9IHByb3BfaWQ7CiAgcHJvcC5GbGFncyA9IEtTUFJPUEVSVFlfVFlQRV9TRVQ7CgogIHJldHVybiBrc19zeW5jX2RldmljZV9pb19jb250cm9sIChoYW5kbGUsIElPQ1RMX0tTX1BST1BFUlRZLCAmcHJvcCwKICAgICAgc2l6ZW9mIChwcm9wKSwgdmFsdWUsIHZhbHVlX3NpemUsICZieXRlc19yZXR1cm5lZCwgZXJyb3IpOwp9CgpnYm9vbGVhbgprc19vYmplY3RfZ2V0X3N1cHBvcnRlZF9wcm9wZXJ0eV9zZXRzIChIQU5ETEUgaGFuZGxlLCBHVUlEICoqIHByb3BzZXRzLAogICAgZ3Vsb25nICogbGVuKQp7CiAgZ3Vsb25nIHNpemUgPSAwOwogIGd1bG9uZyBlcnJvcjsKCiAgKnByb3BzZXRzID0gTlVMTDsKICAqbGVuID0gMDsKCiAgaWYgKGtzX29iamVjdF9xdWVyeV9wcm9wZXJ0eSAoaGFuZGxlLCBHVUlEX05VTEwsIDAsCiAgICAgICAgICBLU1BST1BFUlRZX1RZUEVfU0VUU1VQUE9SVCwgKHZvaWQgKikgcHJvcHNldHMsICZzaXplLCAmZXJyb3IpKSB7CiAgICBpZiAoc2l6ZSAlIHNpemVvZiAoR1VJRCkgPT0gMCkgewogICAgICAqbGVuID0gc2l6ZSAvIHNpemVvZiAoR1VJRCk7CiAgICAgIHJldHVybiBUUlVFOwogICAgfQogIH0KCiAgZ19mcmVlICgqcHJvcHNldHMpOwogICpwcm9wc2V0cyA9IE5VTEw7CiAgKmxlbiA9IDA7CiAgcmV0dXJuIEZBTFNFOwp9CgpnYm9vbGVhbgprc19vYmplY3Rfc2V0X2Nvbm5lY3Rpb25fc3RhdGUgKEhBTkRMRSBoYW5kbGUsIEtTU1RBVEUgc3RhdGUsIGd1bG9uZyAqIGVycm9yKQp7CiAgcmV0dXJuIGtzX29iamVjdF9zZXRfcHJvcGVydHkgKGhhbmRsZSwgS1NQUk9QU0VUSURfQ29ubmVjdGlvbiwKICAgICAgS1NQUk9QRVJUWV9DT05ORUNUSU9OX1NUQVRFLCAmc3RhdGUsIHNpemVvZiAoc3RhdGUpLCBlcnJvcik7Cn0KCmdjaGFyICoKa3NfZ3VpZF90b19zdHJpbmcgKGNvbnN0IEdVSUQgKiBndWlkKQp7CiAgcmV0dXJuIGdfc3RyZHVwX3ByaW50ZiAoInslMDhYLSUwNFgtJTA0WC0lMDJYJTAyWC0lMDJYJTAyWCUwMlglMDJYJTAyWCUwMlh9IiwKICAgICAgKGd1aW50KSBndWlkLT5EYXRhMSwgKGd1aW50KSBndWlkLT5EYXRhMiwgKGd1aW50KSBndWlkLT5EYXRhMywKICAgICAgKGd1aW50KSBndWlkLT5EYXRhNFswXSwgKGd1aW50KSBndWlkLT5EYXRhNFsxXSwgKGd1aW50KSBndWlkLT5EYXRhNFsyXSwKICAgICAgKGd1aW50KSBndWlkLT5EYXRhNFszXSwgKGd1aW50KSBndWlkLT5EYXRhNFs0XSwgKGd1aW50KSBndWlkLT5EYXRhNFs1XSwKICAgICAgKGd1aW50KSBndWlkLT5EYXRhNFs2XSwgKGd1aW50KSBndWlkLT5EYXRhNFs3XSk7Cn0KCmNvbnN0IGdjaGFyICoKa3Nfc3RhdGVfdG9fc3RyaW5nIChLU1NUQVRFIHN0YXRlKQp7CiAgc3dpdGNoIChzdGF0ZSkgewogICAgY2FzZSBLU1NUQVRFX1NUT1A6CiAgICAgIHJldHVybiAiS1NTVEFURV9TVE9QIjsKICAgIGNhc2UgS1NTVEFURV9BQ1FVSVJFOgogICAgICByZXR1cm4gIktTU1RBVEVfQUNRVUlSRSI7CiAgICBjYXNlIEtTU1RBVEVfUEFVU0U6CiAgICAgIHJldHVybiAiS1NTVEFURV9QQVVTRSI7CiAgICBjYXNlIEtTU1RBVEVfUlVOOgogICAgICByZXR1cm4gIktTU1RBVEVfUlVOIjsKICAgIGRlZmF1bHQ6CiAgICAgIGdfYXNzZXJ0X25vdF9yZWFjaGVkICgpOwogIH0KCiAgcmV0dXJuICJVTktOT1dOIjsKfQoKI2RlZmluZSBDSEVDS19PUFRJT05TX0ZMQUcoZmxhZykgXAogIGlmIChmbGFncyAmIEtTU1RSRUFNX0hFQURFUl9PUFRJT05TRl8jI2ZsYWcpXAogIHtcCiAgICBpZiAoc3RyLT5sZW4gPiAwKVwKICAgICAgZ19zdHJpbmdfYXBwZW5kIChzdHIsICJ8Iik7XAogICAgZ19zdHJpbmdfYXBwZW5kIChzdHIsIEdfU1RSSU5HSUZZIChmbGFnKSk7XAogICAgZmxhZ3MgJj0gfktTU1RSRUFNX0hFQURFUl9PUFRJT05TRl8jI2ZsYWc7XAogIH0KCmdjaGFyICoKa3Nfb3B0aW9uc19mbGFnc190b19zdHJpbmcgKGd1bG9uZyBmbGFncykKewogIGdjaGFyICpyZXQ7CiAgR1N0cmluZyAqc3RyOwoKICBzdHIgPSBnX3N0cmluZ19zaXplZF9uZXcgKDEyOCk7CgogIENIRUNLX09QVElPTlNfRkxBRyAoU1BMSUNFUE9JTlQpOwogIENIRUNLX09QVElPTlNfRkxBRyAoUFJFUk9MTCk7CiAgQ0hFQ0tfT1BUSU9OU19GTEFHIChEQVRBRElTQ09OVElOVUlUWSk7CiAgQ0hFQ0tfT1BUSU9OU19GTEFHIChUWVBFQ0hBTkdFRCk7CiAgQ0hFQ0tfT1BUSU9OU19GTEFHIChUSU1FVkFMSUQpOwogIENIRUNLX09QVElPTlNfRkxBRyAoVElNRURJU0NPTlRJTlVJVFkpOwogIENIRUNLX09QVElPTlNfRkxBRyAoRkxVU0hPTlBBVVNFKTsKICBDSEVDS19PUFRJT05TX0ZMQUcgKERVUkFUSU9OVkFMSUQpOwogIENIRUNLX09QVElPTlNfRkxBRyAoRU5ET0ZTVFJFQU0pOwogIENIRUNLX09QVElPTlNfRkxBRyAoQlVGRkVSRURUUkFOU0ZFUik7CiAgQ0hFQ0tfT1BUSU9OU19GTEFHIChWUkFNX0RBVEFfVFJBTlNGRVIpOwogIENIRUNLX09QVElPTlNfRkxBRyAoTE9PUEVEREFUQSk7CgogIGlmIChmbGFncyAhPSAwKQogICAgZ19zdHJpbmdfYXBwZW5kX3ByaW50ZiAoc3RyLCAifDB4JTA4eCIsIChndWludCkgZmxhZ3MpOwoKICByZXQgPSBzdHItPnN0cjsKICBnX3N0cmluZ19mcmVlIChzdHIsIEZBTFNFKTsKCiAgcmV0dXJuIHJldDsKfQoKdHlwZWRlZiBzdHJ1Y3QKewogIGNvbnN0IEdVSUQgZ3VpZDsKICBjb25zdCBnY2hhciAqbmFtZTsKfSBLc1Byb3BlcnR5U2V0TWFwcGluZzsKCiNpZm5kZWYgU1RBVElDX0tTUFJPUFNFVElEX0dNCiNkZWZpbmUgU1RBVElDX0tTUFJPUFNFVElEX0dNIFwKICAgIDB4QUY2Mjc1MzYsIDB4RTcxOSwgMHgxMUQyLCB7IDB4OEEsIDB4MUQsIDB4MDAsIDB4NjAsIDB4OTcsIDB4RDIsIDB4REYsIDB4NUQgfQojZW5kaWYKI2lmbmRlZiBTVEFUSUNfS1NQUk9QU0VUSURfSmFjawojZGVmaW5lIFNUQVRJQ19LU1BST1BTRVRJRF9KYWNrIFwKICAgIDB4NDUwOUY3NTcsIDB4MkQ0NiwgMHg0NjM3LCB7IDB4OEUsIDB4NjIsIDB4Q0UsIDB4N0QsIDB4QjksIDB4NDQsIDB4RjUsIDB4N0IgfQojZW5kaWYKCiNpZm5kZWYgU1RBVElDX1BST1BTRVRJRF9WSURDQVBfU0VMRUNUT1IKI2RlZmluZSBTVEFUSUNfUFJPUFNFVElEX1ZJRENBUF9TRUxFQ1RPUiBcCiAgICAweDFBQkRBRUNBLCAweDY4QjYsIDB4NEY4MywgeyAweDkzLCAweDcxLCAweEI0LCAweDEzLCAweDkwLCAweDdDLCAweDdCLCAweDlGIH0KI2VuZGlmCiNpZm5kZWYgU1RBVElDX1BST1BTRVRJRF9FWFRfREVWSUNFCiNkZWZpbmUgU1RBVElDX1BST1BTRVRJRF9FWFRfREVWSUNFIFwKICAgIDB4QjU3MzBBOTAsIDB4MUEyQywgMHgxMWNmLCB7IDB4OGMsIDB4MjMsIDB4MDAsIDB4QUEsIDB4MDAsIDB4NkIsIDB4NjgsIDB4MTQgfQojZW5kaWYKI2lmbmRlZiBTVEFUSUNfUFJPUFNFVElEX0VYVF9UUkFOU1BPUlQKI2RlZmluZSBTVEFUSUNfUFJPUFNFVElEX0VYVF9UUkFOU1BPUlQgXAogICAgMHhBMDNDRDVGMCwgMHgzMDQ1LCAweDExY2YsIHsgMHg4YywgMHg0NCwgMHgwMCwgMHhBQSwgMHgwMCwgMHg2QiwgMHg2OCwgMHgxNCB9CiNlbmRpZgojaWZuZGVmIFNUQVRJQ19QUk9QU0VUSURfVElNRUNPREVfUkVBREVSCiNkZWZpbmUgU1RBVElDX1BST1BTRVRJRF9USU1FQ09ERV9SRUFERVIgXAogICAgMHg5QjQ5NkNFMSwgMHg4MTFCLCAweDExY2YsIHsgMHg4QywgMHg3NywgMHgwMCwgMHhBQSwgMHgwMCwgMHg2QiwgMHg2OCwgMHgxNCB9CiNlbmRpZgoKc3RhdGljIGNvbnN0IEtzUHJvcGVydHlTZXRNYXBwaW5nIGtub3duX3Byb3BlcnR5X3NldHNbXSA9IHsKICB7e1NUQVRJQ19LU1BST1BTRVRJRF9HZW5lcmFsfSwgIkdlbmVyYWwifSwKICB7e1NUQVRJQ19LU1BST1BTRVRJRF9NZWRpYVNlZWtpbmd9LCAiTWVkaWFTZWVraW5nIn0sCiAge3tTVEFUSUNfS1NQUk9QU0VUSURfVG9wb2xvZ3l9LCAiVG9wb2xvZ3kifSwKICB7e1NUQVRJQ19LU1BST1BTRVRJRF9HTX0sICJHTSJ9LAogIHt7U1RBVElDX0tTUFJPUFNFVElEX1Bpbn0sICJQaW4ifSwKICB7e1NUQVRJQ19LU1BST1BTRVRJRF9RdWFsaXR5fSwgIlF1YWxpdHkifSwKICB7e1NUQVRJQ19LU1BST1BTRVRJRF9Db25uZWN0aW9ufSwgIkNvbm5lY3Rpb24ifSwKICB7e1NUQVRJQ19LU1BST1BTRVRJRF9NZW1vcnlUcmFuc3BvcnR9LCAiTWVtb3J5VHJhbnNwb3J0In0sCiAge3tTVEFUSUNfS1NQUk9QU0VUSURfU3RyZWFtQWxsb2NhdG9yfSwgIlN0cmVhbUFsbG9jYXRvciJ9LAogIHt7U1RBVElDX0tTUFJPUFNFVElEX1N0cmVhbUludGVyZmFjZX0sICJTdHJlYW1JbnRlcmZhY2UifSwKICB7e1NUQVRJQ19LU1BST1BTRVRJRF9TdHJlYW19LCAiU3RyZWFtIn0sCiAge3tTVEFUSUNfS1NQUk9QU0VUSURfQ2xvY2t9LCAiQ2xvY2sifSwKCiAge3tTVEFUSUNfS1NQUk9QU0VUSURfRGlyZWN0U291bmQzRExpc3RlbmVyfSwgIkRpcmVjdFNvdW5kM0RMaXN0ZW5lciJ9LAogIHt7U1RBVElDX0tTUFJPUFNFVElEX0RpcmVjdFNvdW5kM0RCdWZmZXJ9LCAiRGlyZWN0U291bmQzREJ1ZmZlciJ9LAogIHt7U1RBVElDX0tTUFJPUFNFVElEX0hydGYzZH0sICJIcnRmM2QifSwKICB7e1NUQVRJQ19LU1BST1BTRVRJRF9JdGQzZH0sICJJdGQzZCJ9LAogIHt7U1RBVElDX0tTUFJPUFNFVElEX0JpYmxpb2dyYXBoaWN9LCAiQmlibGlvZ3JhcGhpYyJ9LAogIHt7U1RBVElDX0tTUFJPUFNFVElEX1RvcG9sb2d5Tm9kZX0sICJUb3BvbG9neU5vZGUifSwKICB7e1NUQVRJQ19LU1BST1BTRVRJRF9SdEF1ZGlvfSwgIlJ0QXVkaW8ifSwKICB7e1NUQVRJQ19LU1BST1BTRVRJRF9Ecm1BdWRpb1N0cmVhbX0sICJEcm1BdWRpb1N0cmVhbSJ9LAogIHt7U1RBVElDX0tTUFJPUFNFVElEX0F1ZGlvfSwgIkF1ZGlvIn0sCiAge3tTVEFUSUNfS1NQUk9QU0VUSURfQWNvdXN0aWNfRWNob19DYW5jZWx9LCAiQWNvdXN0aWNfRWNob19DYW5jZWwifSwKICB7e1NUQVRJQ19LU1BST1BTRVRJRF9XYXZlX1F1ZXVlZH0sICJXYXZlX1F1ZXVlZCJ9LAogIHt7U1RBVElDX0tTUFJPUFNFVElEX1dhdmV9LCAiV2F2ZSJ9LAogIHt7U1RBVElDX0tTUFJPUFNFVElEX1dhdmVUYWJsZX0sICJXYXZlVGFibGUifSwKICB7e1NUQVRJQ19LU1BST1BTRVRJRF9DeWNsaWN9LCAiQ3ljbGljIn0sCiAge3tTVEFUSUNfS1NQUk9QU0VUSURfU3lzYXVkaW99LCAiU3lzYXVkaW8ifSwKICB7e1NUQVRJQ19LU1BST1BTRVRJRF9TeXNhdWRpb19QaW59LCAiU3lzYXVkaW9fUGluIn0sCiAge3tTVEFUSUNfS1NQUk9QU0VUSURfQXVkaW9HZnh9LCAiQXVkaW9HZngifSwKICB7e1NUQVRJQ19LU1BST1BTRVRJRF9MaW5lYXJ9LCAiTGluZWFyIn0sCiAge3tTVEFUSUNfS1NQUk9QU0VUSURfTXBlZzJWaWR9LCAiTXBlZzJWaWQifSwKICB7e1NUQVRJQ19LU1BST1BTRVRJRF9BQzN9LCAiQUMzIn0sCiAge3tTVEFUSUNfS1NQUk9QU0VUSURfQXVkaW9EZWNvZGVyT3V0fSwgIkF1ZGlvRGVjb2Rlck91dCJ9LAogIHt7U1RBVElDX0tTUFJPUFNFVElEX0R2ZFN1YlBpY30sICJEdmRTdWJQaWMifSwKICB7e1NUQVRJQ19LU1BST1BTRVRJRF9Db3B5UHJvdH0sICJDb3B5UHJvdCJ9LAogIHt7U1RBVElDX0tTUFJPUFNFVElEX1ZCSUNBUF9QUk9QRVJUSUVTfSwgIlZCSUNBUF9QUk9QRVJUSUVTIn0sCiAge3tTVEFUSUNfS1NQUk9QU0VUSURfVkJJQ29kZWNGaWx0ZXJpbmd9LCAiVkJJQ29kZWNGaWx0ZXJpbmcifSwKICB7e1NUQVRJQ19LU1BST1BTRVRJRF9WcmFtQ2FwdHVyZX0sICJWcmFtQ2FwdHVyZSJ9LAogIHt7U1RBVElDX0tTUFJPUFNFVElEX092ZXJsYXlVcGRhdGV9LCAiT3ZlcmxheVVwZGF0ZSJ9LAogIHt7U1RBVElDX0tTUFJPUFNFVElEX1ZQQ29uZmlnfSwgIlZQQ29uZmlnIn0sCiAge3tTVEFUSUNfS1NQUk9QU0VUSURfVlBWQklDb25maWd9LCAiVlBWQklDb25maWcifSwKICB7e1NUQVRJQ19LU1BST1BTRVRJRF9UU1JhdGVDaGFuZ2V9LCAiVFNSYXRlQ2hhbmdlIn0sCiAge3tTVEFUSUNfS1NQUk9QU0VUSURfSmFja30sICJKYWNrIn0sCgogIHt7U1RBVElDX1BST1BTRVRJRF9BTExPQ0FUT1JfQ09OVFJPTH0sICJBTExPQ0FUT1JfQ09OVFJPTCJ9LAogIHt7U1RBVElDX1BST1BTRVRJRF9WSURDQVBfVklERU9QUk9DQU1QfSwgIlZJRENBUF9WSURFT1BST0NBTVAifSwKICB7e1NUQVRJQ19QUk9QU0VUSURfVklEQ0FQX1NFTEVDVE9SfSwgIlZJRENBUF9TRUxFQ1RPUiJ9LAogIHt7U1RBVElDX1BST1BTRVRJRF9UVU5FUn0sICJUVU5FUiJ9LAogIHt7U1RBVElDX1BST1BTRVRJRF9WSURDQVBfVklERU9FTkNPREVSfSwgIlZJRENBUF9WSURFT0VOQ09ERVIifSwKICB7e1NUQVRJQ19QUk9QU0VUSURfVklEQ0FQX1ZJREVPREVDT0RFUn0sICJWSURDQVBfVklERU9ERUNPREVSIn0sCiAge3tTVEFUSUNfUFJPUFNFVElEX1ZJRENBUF9DQU1FUkFDT05UUk9MfSwgIlZJRENBUF9DQU1FUkFDT05UUk9MIn0sCiAge3tTVEFUSUNfUFJPUFNFVElEX0VYVF9ERVZJQ0V9LCAiRVhUX0RFVklDRSJ9LAogIHt7U1RBVElDX1BST1BTRVRJRF9FWFRfVFJBTlNQT1JUfSwgIkVYVF9UUkFOU1BPUlQifSwKICB7e1NUQVRJQ19QUk9QU0VUSURfVElNRUNPREVfUkVBREVSfSwgIlRJTUVDT0RFX1JFQURFUiJ9LAogIHt7U1RBVElDX1BST1BTRVRJRF9WSURDQVBfQ1JPU1NCQVJ9LCAiVklEQ0FQX0NST1NTQkFSIn0sCiAge3tTVEFUSUNfUFJPUFNFVElEX1ZJRENBUF9UVkFVRElPfSwgIlZJRENBUF9UVkFVRElPIn0sCiAge3tTVEFUSUNfUFJPUFNFVElEX1ZJRENBUF9WSURFT0NPTVBSRVNTSU9OfSwgIlZJRENBUF9WSURFT0NPTVBSRVNTSU9OIn0sCiAge3tTVEFUSUNfUFJPUFNFVElEX1ZJRENBUF9WSURFT0NPTlRST0x9LCAiVklEQ0FQX1ZJREVPQ09OVFJPTCJ9LAogIHt7U1RBVElDX1BST1BTRVRJRF9WSURDQVBfRFJPUFBFREZSQU1FU30sICJWSURDQVBfRFJPUFBFREZSQU1FUyJ9LAp9OwoKZ2NoYXIgKgprc19wcm9wZXJ0eV9zZXRfdG9fc3RyaW5nIChjb25zdCBHVUlEICogZ3VpZCkKewogIGd1aW50IGk7CgogIGZvciAoaSA9IDA7CiAgICAgIGkgPCBzaXplb2YgKGtub3duX3Byb3BlcnR5X3NldHMpIC8gc2l6ZW9mIChrbm93bl9wcm9wZXJ0eV9zZXRzWzBdKTsgaSsrKSB7CiAgICBpZiAoSXNFcXVhbEdVSUQgKGd1aWQsICZrbm93bl9wcm9wZXJ0eV9zZXRzW2ldLmd1aWQpKQogICAgICByZXR1cm4gZ19zdHJkdXBfcHJpbnRmICgiS1NQUk9QU0VUSURfJXMiLCBrbm93bl9wcm9wZXJ0eV9zZXRzW2ldLm5hbWUpOwogIH0KCiAgcmV0dXJuIGtzX2d1aWRfdG9fc3RyaW5nIChndWlkKTsKfQo=