LyoKICogQ29weXJpZ2h0IChDKSAyMDA4IE9sZSBBbmRy6SBWYWRsYSBSYXZu5XMgPG9sZS5hbmRyZS5yYXZuYXNAdGFuZGJlcmcuY29tPgogKgogKiBUaGlzIGxpYnJhcnkgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yCiAqIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMaWJyYXJ5IEdlbmVyYWwgUHVibGljCiAqIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlcgogKiB2ZXJzaW9uIDIgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLAogKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZgogKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVQogKiBMaWJyYXJ5IEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIExpYnJhcnkgR2VuZXJhbCBQdWJsaWMKICogTGljZW5zZSBhbG9uZyB3aXRoIHRoaXMgbGlicmFyeTsgaWYgbm90LCB3cml0ZSB0byB0aGUKICogRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsCiAqIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSwgVVNBLgogKi8KCiNpbmNsdWRlICJrc2hlbHBlcnMuaCIKCiNpbmNsdWRlIDxrc21lZGlhLmg+CiNpbmNsdWRlIDxzZXR1cGFwaS5oPgojaW5jbHVkZSA8Z3N0L2dzdC5oPgoKR1NUX0RFQlVHX0NBVEVHT1JZX0VYVEVSTiAoZ3N0X2tzX2RlYnVnKTsKI2RlZmluZSBHU1RfQ0FUX0RFRkFVTFQgZ3N0X2tzX2RlYnVnCgojaWZuZGVmIFNUQVRJQ19LU1BST1BTRVRJRF9XYXZlX1F1ZXVlZAojZGVmaW5lIFNUQVRJQ19LU1BST1BTRVRJRF9XYXZlX1F1ZXVlZCBcCiAgICAweDE2YTE1YjEwTCwgMHgxNmYwLCAweDExZDAsIHsgMHhhMSwgMHg5NSwgMHgwMCwgMHgyMCwgMHhhZiwgMHhkMSwgMHg1NiwgMHhlNCB9CkRFRklORV9HVUlEU1RSVUNUICgiMTZhMTViMTAtMTZmMC0xMWQwLWExOTUtMDAyMGFmZDE1NmU0IiwKICAgIEtTUFJPUFNFVElEX1dhdmVfUXVldWVkKTsKI2VuZGlmCgpnYm9vbGVhbgprc19pc192YWxpZF9oYW5kbGUgKEhBTkRMRSBoKQp7CiAgcmV0dXJuIChoICE9IElOVkFMSURfSEFORExFX1ZBTFVFICYmIGggIT0gTlVMTCk7Cn0KCkdMaXN0ICoKa3NfZW51bWVyYXRlX2RldmljZXMgKGNvbnN0IEdVSUQgKiBkZXZ0eXBlLCBjb25zdCBHVUlEICogZGlyZWN0aW9uX2NhdGVnb3J5KQp7CiAgR0xpc3QgKnJlc3VsdCA9IE5VTEw7CiAgSERFVklORk8gZGV2aW5mbzsKICBnaW50IGk7CgogIGRldmluZm8gPSBTZXR1cERpR2V0Q2xhc3NEZXZzVyAoZGV2dHlwZSwgTlVMTCwgTlVMTCwKICAgICAgRElHQ0ZfUFJFU0VOVCB8IERJR0NGX0RFVklDRUlOVEVSRkFDRSk7CiAgaWYgKCFrc19pc192YWxpZF9oYW5kbGUgKGRldmluZm8pKQogICAgcmV0dXJuIE5VTEw7ICAgICAgICAgICAgICAgIC8qIG5vIGRldmljZXMgKi8KCiAgZm9yIChpID0gMDs7IGkrKykgewogICAgQk9PTCBzdWNjZXNzOwogICAgU1BfREVWSUNFX0lOVEVSRkFDRV9EQVRBIGlmX2RhdGEgPSB7IDAsIH07CiAgICBTUF9ERVZJQ0VfSU5URVJGQUNFX0RBVEEgaWZfYWxpYXNfZGF0YSA9IHsgMCwgfTsKICAgIFNQX0RFVklDRV9JTlRFUkZBQ0VfREVUQUlMX0RBVEFfVyAqaWZfZGV0YWlsX2RhdGE7CiAgICBEV09SRCBpZl9kZXRhaWxfZGF0YV9zaXplOwogICAgU1BfREVWSU5GT19EQVRBIGRldmluZm9fZGF0YSA9IHsgMCwgfTsKICAgIERXT1JEIHJlcV9zaXplOwoKICAgIGlmX2RhdGEuY2JTaXplID0gc2l6ZW9mIChTUF9ERVZJQ0VfSU5URVJGQUNFX0RBVEEpOwoKICAgIHN1Y2Nlc3MgPSBTZXR1cERpRW51bURldmljZUludGVyZmFjZXMgKGRldmluZm8sIE5VTEwsIGRldnR5cGUsIGksICZpZl9kYXRhKTsKICAgIGlmICghc3VjY2VzcykgICAgICAgICAgICAgICAvKiBhbGwgZGV2aWNlcyBlbnVtZXJhdGVkPyAqLwogICAgICBicmVhazsKCiAgICBpZl9hbGlhc19kYXRhLmNiU2l6ZSA9IHNpemVvZiAoU1BfREVWSUNFX0lOVEVSRkFDRV9EQVRBKTsKICAgIHN1Y2Nlc3MgPQogICAgICAgIFNldHVwRGlHZXREZXZpY2VJbnRlcmZhY2VBbGlhcyAoZGV2aW5mbywgJmlmX2RhdGEsIGRpcmVjdGlvbl9jYXRlZ29yeSwKICAgICAgICAmaWZfYWxpYXNfZGF0YSk7CiAgICBpZiAoIXN1Y2Nlc3MpCiAgICAgIGNvbnRpbnVlOwoKICAgIGlmX2RldGFpbF9kYXRhX3NpemUgPSAoTUFYX1BBVEggLSAxKSAqIHNpemVvZiAoZ3VuaWNoYXIyKTsKICAgIGlmX2RldGFpbF9kYXRhID0gZ19tYWxsb2MwIChpZl9kZXRhaWxfZGF0YV9zaXplKTsKICAgIGlmX2RldGFpbF9kYXRhLT5jYlNpemUgPSBzaXplb2YgKFNQX0RFVklDRV9JTlRFUkZBQ0VfREVUQUlMX0RBVEFfVyk7CgogICAgZGV2aW5mb19kYXRhLmNiU2l6ZSA9IHNpemVvZiAoU1BfREVWSU5GT19EQVRBKTsKCiAgICBzdWNjZXNzID0gU2V0dXBEaUdldERldmljZUludGVyZmFjZURldGFpbFcgKGRldmluZm8sICZpZl9kYXRhLAogICAgICAgIGlmX2RldGFpbF9kYXRhLCBpZl9kZXRhaWxfZGF0YV9zaXplLCAmcmVxX3NpemUsICZkZXZpbmZvX2RhdGEpOwogICAgaWYgKHN1Y2Nlc3MpIHsKICAgICAgS3NEZXZpY2VFbnRyeSAqZW50cnk7CiAgICAgIFdDSEFSIGJ1Zls1MTJdOwoKICAgICAgZW50cnkgPSBnX25ldzAgKEtzRGV2aWNlRW50cnksIDEpOwogICAgICBlbnRyeS0+aW5kZXggPSBpOwogICAgICBlbnRyeS0+cGF0aCA9CiAgICAgICAgICBnX3V0ZjE2X3RvX3V0ZjggKGlmX2RldGFpbF9kYXRhLT5EZXZpY2VQYXRoLCAtMSwgTlVMTCwgTlVMTCwgTlVMTCk7CgogICAgICBpZiAoU2V0dXBEaUdldERldmljZVJlZ2lzdHJ5UHJvcGVydHlXIChkZXZpbmZvLCAmZGV2aW5mb19kYXRhLAogICAgICAgICAgICAgIFNQRFJQX0ZSSUVORExZTkFNRSwgTlVMTCwgKEJZVEUgKikgYnVmLCBzaXplb2YgKGJ1ZiksIE5VTEwpKSB7CiAgICAgICAgZW50cnktPm5hbWUgPSBnX3V0ZjE2X3RvX3V0ZjggKGJ1ZiwgLTEsIE5VTEwsIE5VTEwsIE5VTEwpOwogICAgICB9CgogICAgICBpZiAoZW50cnktPm5hbWUgPT0gTlVMTCkgewogICAgICAgIGlmIChTZXR1cERpR2V0RGV2aWNlUmVnaXN0cnlQcm9wZXJ0eVcgKGRldmluZm8sICZkZXZpbmZvX2RhdGEsCiAgICAgICAgICAgICAgICBTUERSUF9ERVZJQ0VERVNDLCBOVUxMLCAoQllURSAqKSBidWYsIHNpemVvZiAoYnVmKSwgTlVMTCkpIHsKICAgICAgICAgIGVudHJ5LT5uYW1lID0gZ191dGYxNl90b191dGY4IChidWYsIC0xLCBOVUxMLCBOVUxMLCBOVUxMKTsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIGlmIChlbnRyeS0+bmFtZSAhPSBOVUxMKQogICAgICAgIHJlc3VsdCA9IGdfbGlzdF9wcmVwZW5kIChyZXN1bHQsIGVudHJ5KTsKICAgICAgZWxzZQogICAgICAgIGtzX2RldmljZV9lbnRyeV9mcmVlIChlbnRyeSk7CiAgICB9CgogICAgZ19mcmVlIChpZl9kZXRhaWxfZGF0YSk7CiAgfQoKICBTZXR1cERpRGVzdHJveURldmljZUluZm9MaXN0IChkZXZpbmZvKTsKCiAgcmV0dXJuIGdfbGlzdF9yZXZlcnNlIChyZXN1bHQpOwp9Cgp2b2lkCmtzX2RldmljZV9lbnRyeV9mcmVlIChLc0RldmljZUVudHJ5ICogZW50cnkpCnsKICBpZiAoZW50cnkgPT0gTlVMTCkKICAgIHJldHVybjsKCiAgZ19mcmVlIChlbnRyeS0+cGF0aCk7CiAgZ19mcmVlIChlbnRyeS0+bmFtZSk7CgogIGdfZnJlZSAoZW50cnkpOwp9Cgp2b2lkCmtzX2RldmljZV9saXN0X2ZyZWUgKEdMaXN0ICogZGV2aWNlcykKewogIEdMaXN0ICpjdXI7CgogIGZvciAoY3VyID0gZGV2aWNlczsgY3VyICE9IE5VTEw7IGN1ciA9IGN1ci0+bmV4dCkKICAgIGtzX2RldmljZV9lbnRyeV9mcmVlIChjdXItPmRhdGEpOwoKICBnX2xpc3RfZnJlZSAoZGV2aWNlcyk7Cn0KCnN0YXRpYyBnYm9vbGVhbgprc19zeW5jX2RldmljZV9pb19jb250cm9sIChIQU5ETEUgZGV2aWNlLCBndWxvbmcgaW9fY29udHJvbF9jb2RlLAogICAgZ3BvaW50ZXIgaW5fYnVmZmVyLCBndWxvbmcgaW5fYnVmZmVyX3NpemUsIGdwb2ludGVyIG91dF9idWZmZXIsCiAgICBndWxvbmcgb3V0X2J1ZmZlcl9zaXplLCBndWxvbmcgKiBieXRlc19yZXR1cm5lZCwgZ3Vsb25nICogZXJyb3IpCnsKICBPVkVSTEFQUEVEIG92ZXJsYXBwZWQgPSB7IDAsIH07CiAgQk9PTCBzdWNjZXNzOwoKICBvdmVybGFwcGVkLmhFdmVudCA9IENyZWF0ZUV2ZW50IChOVUxMLCBUUlVFLCBGQUxTRSwgTlVMTCk7CgogIHN1Y2Nlc3MgPSBEZXZpY2VJb0NvbnRyb2wgKGRldmljZSwgaW9fY29udHJvbF9jb2RlLCBpbl9idWZmZXIsCiAgICAgIGluX2J1ZmZlcl9zaXplLCBvdXRfYnVmZmVyLCBvdXRfYnVmZmVyX3NpemUsIGJ5dGVzX3JldHVybmVkLCAmb3ZlcmxhcHBlZCk7CiAgaWYgKCFzdWNjZXNzKSB7CiAgICBEV09SRCBlcnI7CgogICAgaWYgKChlcnIgPSBHZXRMYXN0RXJyb3IgKCkpID09IEVSUk9SX0lPX1BFTkRJTkcpIHsKICAgICAgc3VjY2VzcyA9IEdldE92ZXJsYXBwZWRSZXN1bHQgKGRldmljZSwgJm92ZXJsYXBwZWQsIGJ5dGVzX3JldHVybmVkLCBUUlVFKTsKICAgICAgaWYgKCFzdWNjZXNzKQogICAgICAgIGVyciA9IEdldExhc3RFcnJvciAoKTsKICAgIH0KCiAgICBpZiAoZXJyb3IgIT0gTlVMTCkKICAgICAgKmVycm9yID0gZXJyOwogIH0KCiAgQ2xvc2VIYW5kbGUgKG92ZXJsYXBwZWQuaEV2ZW50KTsKCiAgcmV0dXJuIHN1Y2Nlc3MgPyBUUlVFIDogRkFMU0U7Cn0KCmdib29sZWFuCmtzX2ZpbHRlcl9nZXRfcGluX3Byb3BlcnR5IChIQU5ETEUgZmlsdGVyX2hhbmRsZSwgZ3Vsb25nIHBpbl9pZCwKICAgIEdVSUQgcHJvcF9zZXQsIGd1bG9uZyBwcm9wX2lkLCBncG9pbnRlciB2YWx1ZSwgZ3Vsb25nIHZhbHVlX3NpemUsCiAgICBndWxvbmcgKiBlcnJvcikKewogIEtTUF9QSU4gcHJvcDsKICBEV09SRCBieXRlc19yZXR1cm5lZCA9IDA7CgogIG1lbXNldCAoJnByb3AsIDAsIHNpemVvZiAoS1NQX1BJTikpOwoKICBwcm9wLlBpbklkID0gcGluX2lkOwogIHByb3AuUHJvcGVydHkuU2V0ID0gcHJvcF9zZXQ7CiAgcHJvcC5Qcm9wZXJ0eS5JZCA9IHByb3BfaWQ7CiAgcHJvcC5Qcm9wZXJ0eS5GbGFncyA9IEtTUFJPUEVSVFlfVFlQRV9HRVQ7CgogIHJldHVybiBrc19zeW5jX2RldmljZV9pb19jb250cm9sIChmaWx0ZXJfaGFuZGxlLCBJT0NUTF9LU19QUk9QRVJUWSwgJnByb3AsCiAgICAgIHNpemVvZiAocHJvcCksIHZhbHVlLCB2YWx1ZV9zaXplLCAmYnl0ZXNfcmV0dXJuZWQsIGVycm9yKTsKfQoKZ2Jvb2xlYW4Ka3NfZmlsdGVyX2dldF9waW5fcHJvcGVydHlfbXVsdGkgKEhBTkRMRSBmaWx0ZXJfaGFuZGxlLCBndWxvbmcgcGluX2lkLAogICAgR1VJRCBwcm9wX3NldCwgZ3Vsb25nIHByb3BfaWQsIEtTTVVMVElQTEVfSVRFTSAqKiBpdGVtcywgZ3Vsb25nICogZXJyb3IpCnsKICBLU1BfUElOIHByb3A7CiAgRFdPUkQgaXRlbXNfc2l6ZSA9IDAsIGJ5dGVzX3dyaXR0ZW4gPSAwOwogIGd1bG9uZyBlcnI7CiAgZ2Jvb2xlYW4gcmV0OwoKICBtZW1zZXQgKCZwcm9wLCAwLCBzaXplb2YgKEtTUF9QSU4pKTsKICAqaXRlbXMgPSBOVUxMOwoKICBwcm9wLlBpbklkID0gcGluX2lkOwogIHByb3AuUHJvcGVydHkuU2V0ID0gcHJvcF9zZXQ7CiAgcHJvcC5Qcm9wZXJ0eS5JZCA9IHByb3BfaWQ7CiAgcHJvcC5Qcm9wZXJ0eS5GbGFncyA9IEtTUFJPUEVSVFlfVFlQRV9HRVQ7CgogIHJldCA9IGtzX3N5bmNfZGV2aWNlX2lvX2NvbnRyb2wgKGZpbHRlcl9oYW5kbGUsIElPQ1RMX0tTX1BST1BFUlRZLAogICAgICAmcHJvcC5Qcm9wZXJ0eSwgc2l6ZW9mIChwcm9wKSwgTlVMTCwgMCwgJml0ZW1zX3NpemUsICZlcnIpOwogIGlmICghcmV0ICYmIGVyciAhPSBFUlJPUl9JTlNVRkZJQ0lFTlRfQlVGRkVSICYmIGVyciAhPSBFUlJPUl9NT1JFX0RBVEEpCiAgICBnb3RvIGlvY3RsX2ZhaWxlZDsKCiAgKml0ZW1zID0gZ19tYWxsb2MwIChpdGVtc19zaXplKTsKCiAgcmV0ID0ga3Nfc3luY19kZXZpY2VfaW9fY29udHJvbCAoZmlsdGVyX2hhbmRsZSwgSU9DVExfS1NfUFJPUEVSVFksICZwcm9wLAogICAgICBzaXplb2YgKHByb3ApLCAqaXRlbXMsIGl0ZW1zX3NpemUsICZieXRlc193cml0dGVuLCAmZXJyKTsKICBpZiAoIXJldCkKICAgIGdvdG8gaW9jdGxfZmFpbGVkOwoKICByZXR1cm4gcmV0OwoKaW9jdGxfZmFpbGVkOgogIGlmIChlcnJvciAhPSBOVUxMKQogICAgKmVycm9yID0gZXJyOwoKICBnX2ZyZWUgKCppdGVtcyk7CiAgKml0ZW1zID0gTlVMTDsKCiAgcmV0dXJuIEZBTFNFOwp9CgpnYm9vbGVhbgprc19vYmplY3RfcXVlcnlfcHJvcGVydHkgKEhBTkRMRSBoYW5kbGUsIEdVSUQgcHJvcF9zZXQsIGd1bG9uZyBwcm9wX2lkLAogICAgZ3Vsb25nIHByb3BfZmxhZ3MsIGdwb2ludGVyICogdmFsdWUsIGd1bG9uZyAqIHZhbHVlX3NpemUsIGd1bG9uZyAqIGVycm9yKQp7CiAgS1NQUk9QRVJUWSBwcm9wOwogIERXT1JEIHJlcV92YWx1ZV9zaXplID0gMCwgYnl0ZXNfd3JpdHRlbiA9IDA7CiAgZ3Vsb25nIGVycjsKICBnYm9vbGVhbiByZXQ7CgogIG1lbXNldCAoJnByb3AsIDAsIHNpemVvZiAoS1NQUk9QRVJUWSkpOwogICp2YWx1ZSA9IE5VTEw7CgogIHByb3AuU2V0ID0gcHJvcF9zZXQ7CiAgcHJvcC5JZCA9IHByb3BfaWQ7CiAgcHJvcC5GbGFncyA9IHByb3BfZmxhZ3M7CgogIGlmICh2YWx1ZV9zaXplID09IE5VTEwgfHwgKnZhbHVlX3NpemUgPT0gMCkgewogICAgcmV0ID0ga3Nfc3luY19kZXZpY2VfaW9fY29udHJvbCAoaGFuZGxlLCBJT0NUTF9LU19QUk9QRVJUWSwKICAgICAgICAmcHJvcCwgc2l6ZW9mIChwcm9wKSwgTlVMTCwgMCwgJnJlcV92YWx1ZV9zaXplLCAmZXJyKTsKICAgIGlmICghcmV0ICYmIGVyciAhPSBFUlJPUl9JTlNVRkZJQ0lFTlRfQlVGRkVSICYmIGVyciAhPSBFUlJPUl9NT1JFX0RBVEEpCiAgICAgIGdvdG8gaW9jdGxfZmFpbGVkOwogIH0gZWxzZSB7CiAgICByZXFfdmFsdWVfc2l6ZSA9ICp2YWx1ZV9zaXplOwogIH0KCiAgKnZhbHVlID0gZ19tYWxsb2MwIChyZXFfdmFsdWVfc2l6ZSk7CgogIHJldCA9IGtzX3N5bmNfZGV2aWNlX2lvX2NvbnRyb2wgKGhhbmRsZSwgSU9DVExfS1NfUFJPUEVSVFksICZwcm9wLAogICAgICBzaXplb2YgKHByb3ApLCAqdmFsdWUsIHJlcV92YWx1ZV9zaXplLCAmYnl0ZXNfd3JpdHRlbiwgJmVycik7CiAgaWYgKCFyZXQpCiAgICBnb3RvIGlvY3RsX2ZhaWxlZDsKCiAgaWYgKHZhbHVlX3NpemUgIT0gTlVMTCkKICAgICp2YWx1ZV9zaXplID0gYnl0ZXNfd3JpdHRlbjsKCiAgcmV0dXJuIHJldDsKCmlvY3RsX2ZhaWxlZDoKICBpZiAoZXJyb3IgIT0gTlVMTCkKICAgICplcnJvciA9IGVycjsKCiAgZ19mcmVlICgqdmFsdWUpOwogICp2YWx1ZSA9IE5VTEw7CgogIGlmICh2YWx1ZV9zaXplICE9IE5VTEwpCiAgICAqdmFsdWVfc2l6ZSA9IDA7CgogIHJldHVybiBGQUxTRTsKfQoKZ2Jvb2xlYW4Ka3Nfb2JqZWN0X2dldF9wcm9wZXJ0eSAoSEFORExFIGhhbmRsZSwgR1VJRCBwcm9wX3NldCwgZ3Vsb25nIHByb3BfaWQsCiAgICBncG9pbnRlciAqIHZhbHVlLCBndWxvbmcgKiB2YWx1ZV9zaXplLCBndWxvbmcgKiBlcnJvcikKewogIHJldHVybiBrc19vYmplY3RfcXVlcnlfcHJvcGVydHkgKGhhbmRsZSwgcHJvcF9zZXQsIHByb3BfaWQsCiAgICAgIEtTUFJPUEVSVFlfVFlQRV9HRVQsIHZhbHVlLCB2YWx1ZV9zaXplLCBlcnJvcik7Cn0KCmdib29sZWFuCmtzX29iamVjdF9zZXRfcHJvcGVydHkgKEhBTkRMRSBoYW5kbGUsIEdVSUQgcHJvcF9zZXQsIGd1bG9uZyBwcm9wX2lkLAogICAgZ3BvaW50ZXIgdmFsdWUsIGd1bG9uZyB2YWx1ZV9zaXplLCBndWxvbmcgKiBlcnJvcikKewogIEtTUFJPUEVSVFkgcHJvcDsKICBEV09SRCBieXRlc19yZXR1cm5lZDsKCiAgbWVtc2V0ICgmcHJvcCwgMCwgc2l6ZW9mIChLU1BST1BFUlRZKSk7CiAgcHJvcC5TZXQgPSBwcm9wX3NldDsKICBwcm9wLklkID0gcHJvcF9pZDsKICBwcm9wLkZsYWdzID0gS1NQUk9QRVJUWV9UWVBFX1NFVDsKCiAgcmV0dXJuIGtzX3N5bmNfZGV2aWNlX2lvX2NvbnRyb2wgKGhhbmRsZSwgSU9DVExfS1NfUFJPUEVSVFksICZwcm9wLAogICAgICBzaXplb2YgKHByb3ApLCB2YWx1ZSwgdmFsdWVfc2l6ZSwgJmJ5dGVzX3JldHVybmVkLCBlcnJvcik7Cn0KCmdib29sZWFuCmtzX29iamVjdF9nZXRfc3VwcG9ydGVkX3Byb3BlcnR5X3NldHMgKEhBTkRMRSBoYW5kbGUsIEdVSUQgKiogcHJvcHNldHMsCiAgICBndWxvbmcgKiBsZW4pCnsKICBndWxvbmcgc2l6ZSA9IDA7CiAgZ3Vsb25nIGVycm9yOwoKICAqcHJvcHNldHMgPSBOVUxMOwogICpsZW4gPSAwOwoKICBpZiAoa3Nfb2JqZWN0X3F1ZXJ5X3Byb3BlcnR5IChoYW5kbGUsIEdVSURfTlVMTCwgMCwKICAgICAgICAgIEtTUFJPUEVSVFlfVFlQRV9TRVRTVVBQT1JULCAodm9pZCAqKSBwcm9wc2V0cywgJnNpemUsICZlcnJvcikpIHsKICAgIGlmIChzaXplICUgc2l6ZW9mIChHVUlEKSA9PSAwKSB7CiAgICAgICpsZW4gPSBzaXplIC8gc2l6ZW9mIChHVUlEKTsKICAgICAgcmV0dXJuIFRSVUU7CiAgICB9CiAgfQoKICBnX2ZyZWUgKCpwcm9wc2V0cyk7CiAgKnByb3BzZXRzID0gTlVMTDsKICAqbGVuID0gMDsKICByZXR1cm4gRkFMU0U7Cn0KCmdib29sZWFuCmtzX29iamVjdF9zZXRfY29ubmVjdGlvbl9zdGF0ZSAoSEFORExFIGhhbmRsZSwgS1NTVEFURSBzdGF0ZSwgZ3Vsb25nICogZXJyb3IpCnsKICByZXR1cm4ga3Nfb2JqZWN0X3NldF9wcm9wZXJ0eSAoaGFuZGxlLCBLU1BST1BTRVRJRF9Db25uZWN0aW9uLAogICAgICBLU1BST1BFUlRZX0NPTk5FQ1RJT05fU1RBVEUsICZzdGF0ZSwgc2l6ZW9mIChzdGF0ZSksIGVycm9yKTsKfQoKZ2NoYXIgKgprc19ndWlkX3RvX3N0cmluZyAoY29uc3QgR1VJRCAqIGd1aWQpCnsKICByZXR1cm4gZ19zdHJkdXBfcHJpbnRmICgieyUwOFgtJTA0WC0lMDRYLSUwMlglMDJYLSUwMlglMDJYJTAyWCUwMlglMDJYJTAyWH0iLAogICAgICAoZ3VpbnQpIGd1aWQtPkRhdGExLCAoZ3VpbnQpIGd1aWQtPkRhdGEyLCAoZ3VpbnQpIGd1aWQtPkRhdGEzLAogICAgICAoZ3VpbnQpIGd1aWQtPkRhdGE0WzBdLCAoZ3VpbnQpIGd1aWQtPkRhdGE0WzFdLCAoZ3VpbnQpIGd1aWQtPkRhdGE0WzJdLAogICAgICAoZ3VpbnQpIGd1aWQtPkRhdGE0WzNdLCAoZ3VpbnQpIGd1aWQtPkRhdGE0WzRdLCAoZ3VpbnQpIGd1aWQtPkRhdGE0WzVdLAogICAgICAoZ3VpbnQpIGd1aWQtPkRhdGE0WzZdLCAoZ3VpbnQpIGd1aWQtPkRhdGE0WzddKTsKfQoKY29uc3QgZ2NoYXIgKgprc19zdGF0ZV90b19zdHJpbmcgKEtTU1RBVEUgc3RhdGUpCnsKICBzd2l0Y2ggKHN0YXRlKSB7CiAgICBjYXNlIEtTU1RBVEVfU1RPUDoKICAgICAgcmV0dXJuICJLU1NUQVRFX1NUT1AiOwogICAgY2FzZSBLU1NUQVRFX0FDUVVJUkU6CiAgICAgIHJldHVybiAiS1NTVEFURV9BQ1FVSVJFIjsKICAgIGNhc2UgS1NTVEFURV9QQVVTRToKICAgICAgcmV0dXJuICJLU1NUQVRFX1BBVVNFIjsKICAgIGNhc2UgS1NTVEFURV9SVU46CiAgICAgIHJldHVybiAiS1NTVEFURV9SVU4iOwogICAgZGVmYXVsdDoKICAgICAgZ19hc3NlcnRfbm90X3JlYWNoZWQgKCk7CiAgfQoKICByZXR1cm4gIlVOS05PV04iOwp9CgojZGVmaW5lIENIRUNLX09QVElPTlNfRkxBRyhmbGFnKSBcCiAgaWYgKGZsYWdzICYgS1NTVFJFQU1fSEVBREVSX09QVElPTlNGXyMjZmxhZylcCiAge1wKICAgIGlmIChzdHItPmxlbiA+IDApXAogICAgICBnX3N0cmluZ19hcHBlbmQgKHN0ciwgInwiKTtcCiAgICBnX3N0cmluZ19hcHBlbmQgKHN0ciwgR19TVFJJTkdJRlkgKGZsYWcpKTtcCiAgICBmbGFncyAmPSB+S1NTVFJFQU1fSEVBREVSX09QVElPTlNGXyMjZmxhZztcCiAgfQoKZ2NoYXIgKgprc19vcHRpb25zX2ZsYWdzX3RvX3N0cmluZyAoZ3Vsb25nIGZsYWdzKQp7CiAgZ2NoYXIgKnJldDsKICBHU3RyaW5nICpzdHI7CgogIHN0ciA9IGdfc3RyaW5nX3NpemVkX25ldyAoMTI4KTsKCiAgQ0hFQ0tfT1BUSU9OU19GTEFHIChTUExJQ0VQT0lOVCk7CiAgQ0hFQ0tfT1BUSU9OU19GTEFHIChQUkVST0xMKTsKICBDSEVDS19PUFRJT05TX0ZMQUcgKERBVEFESVNDT05USU5VSVRZKTsKICBDSEVDS19PUFRJT05TX0ZMQUcgKFRZUEVDSEFOR0VEKTsKICBDSEVDS19PUFRJT05TX0ZMQUcgKFRJTUVWQUxJRCk7CiAgQ0hFQ0tfT1BUSU9OU19GTEFHIChUSU1FRElTQ09OVElOVUlUWSk7CiAgQ0hFQ0tfT1BUSU9OU19GTEFHIChGTFVTSE9OUEFVU0UpOwogIENIRUNLX09QVElPTlNfRkxBRyAoRFVSQVRJT05WQUxJRCk7CiAgQ0hFQ0tfT1BUSU9OU19GTEFHIChFTkRPRlNUUkVBTSk7CiAgQ0hFQ0tfT1BUSU9OU19GTEFHIChCVUZGRVJFRFRSQU5TRkVSKTsKICBDSEVDS19PUFRJT05TX0ZMQUcgKFZSQU1fREFUQV9UUkFOU0ZFUik7CiAgQ0hFQ0tfT1BUSU9OU19GTEFHIChMT09QRUREQVRBKTsKCiAgaWYgKGZsYWdzICE9IDApCiAgICBnX3N0cmluZ19hcHBlbmRfcHJpbnRmIChzdHIsICJ8MHglMDh4IiwgKGd1aW50KSBmbGFncyk7CgogIHJldCA9IHN0ci0+c3RyOwogIGdfc3RyaW5nX2ZyZWUgKHN0ciwgRkFMU0UpOwoKICByZXR1cm4gcmV0Owp9Cgp0eXBlZGVmIHN0cnVjdAp7CiAgY29uc3QgR1VJRCBndWlkOwogIGNvbnN0IGdjaGFyICpuYW1lOwp9IEtzUHJvcGVydHlTZXRNYXBwaW5nOwoKI2lmbmRlZiBTVEFUSUNfS1NQUk9QU0VUSURfR00KI2RlZmluZSBTVEFUSUNfS1NQUk9QU0VUSURfR00gXAogICAgMHhBRjYyNzUzNiwgMHhFNzE5LCAweDExRDIsIHsgMHg4QSwgMHgxRCwgMHgwMCwgMHg2MCwgMHg5NywgMHhEMiwgMHhERiwgMHg1RCB9CiNlbmRpZgojaWZuZGVmIFNUQVRJQ19LU1BST1BTRVRJRF9KYWNrCiNkZWZpbmUgU1RBVElDX0tTUFJPUFNFVElEX0phY2sgXAogICAgMHg0NTA5Rjc1NywgMHgyRDQ2LCAweDQ2MzcsIHsgMHg4RSwgMHg2MiwgMHhDRSwgMHg3RCwgMHhCOSwgMHg0NCwgMHhGNSwgMHg3QiB9CiNlbmRpZgoKI2lmbmRlZiBTVEFUSUNfUFJPUFNFVElEX1ZJRENBUF9TRUxFQ1RPUgojZGVmaW5lIFNUQVRJQ19QUk9QU0VUSURfVklEQ0FQX1NFTEVDVE9SIFwKICAgIDB4MUFCREFFQ0EsIDB4NjhCNiwgMHg0RjgzLCB7IDB4OTMsIDB4NzEsIDB4QjQsIDB4MTMsIDB4OTAsIDB4N0MsIDB4N0IsIDB4OUYgfQojZW5kaWYKI2lmbmRlZiBTVEFUSUNfUFJPUFNFVElEX0VYVF9ERVZJQ0UKI2RlZmluZSBTVEFUSUNfUFJPUFNFVElEX0VYVF9ERVZJQ0UgXAogICAgMHhCNTczMEE5MCwgMHgxQTJDLCAweDExY2YsIHsgMHg4YywgMHgyMywgMHgwMCwgMHhBQSwgMHgwMCwgMHg2QiwgMHg2OCwgMHgxNCB9CiNlbmRpZgojaWZuZGVmIFNUQVRJQ19QUk9QU0VUSURfRVhUX1RSQU5TUE9SVAojZGVmaW5lIFNUQVRJQ19QUk9QU0VUSURfRVhUX1RSQU5TUE9SVCBcCiAgICAweEEwM0NENUYwLCAweDMwNDUsIDB4MTFjZiwgeyAweDhjLCAweDQ0LCAweDAwLCAweEFBLCAweDAwLCAweDZCLCAweDY4LCAweDE0IH0KI2VuZGlmCiNpZm5kZWYgU1RBVElDX1BST1BTRVRJRF9USU1FQ09ERV9SRUFERVIKI2RlZmluZSBTVEFUSUNfUFJPUFNFVElEX1RJTUVDT0RFX1JFQURFUiBcCiAgICAweDlCNDk2Q0UxLCAweDgxMUIsIDB4MTFjZiwgeyAweDhDLCAweDc3LCAweDAwLCAweEFBLCAweDAwLCAweDZCLCAweDY4LCAweDE0IH0KI2VuZGlmCgpzdGF0aWMgY29uc3QgS3NQcm9wZXJ0eVNldE1hcHBpbmcga25vd25fcHJvcGVydHlfc2V0c1tdID0gewogIHt7U1RBVElDX0tTUFJPUFNFVElEX0dlbmVyYWx9LCAiR2VuZXJhbCJ9LAogIHt7U1RBVElDX0tTUFJPUFNFVElEX01lZGlhU2Vla2luZ30sICJNZWRpYVNlZWtpbmcifSwKICB7e1NUQVRJQ19LU1BST1BTRVRJRF9Ub3BvbG9neX0sICJUb3BvbG9neSJ9LAogIHt7U1RBVElDX0tTUFJPUFNFVElEX0dNfSwgIkdNIn0sCiAge3tTVEFUSUNfS1NQUk9QU0VUSURfUGlufSwgIlBpbiJ9LAogIHt7U1RBVElDX0tTUFJPUFNFVElEX1F1YWxpdHl9LCAiUXVhbGl0eSJ9LAogIHt7U1RBVElDX0tTUFJPUFNFVElEX0Nvbm5lY3Rpb259LCAiQ29ubmVjdGlvbiJ9LAogIHt7U1RBVElDX0tTUFJPUFNFVElEX01lbW9yeVRyYW5zcG9ydH0sICJNZW1vcnlUcmFuc3BvcnQifSwKICB7e1NUQVRJQ19LU1BST1BTRVRJRF9TdHJlYW1BbGxvY2F0b3J9LCAiU3RyZWFtQWxsb2NhdG9yIn0sCiAge3tTVEFUSUNfS1NQUk9QU0VUSURfU3RyZWFtSW50ZXJmYWNlfSwgIlN0cmVhbUludGVyZmFjZSJ9LAogIHt7U1RBVElDX0tTUFJPUFNFVElEX1N0cmVhbX0sICJTdHJlYW0ifSwKICB7e1NUQVRJQ19LU1BST1BTRVRJRF9DbG9ja30sICJDbG9jayJ9LAoKICB7e1NUQVRJQ19LU1BST1BTRVRJRF9EaXJlY3RTb3VuZDNETGlzdGVuZXJ9LCAiRGlyZWN0U291bmQzRExpc3RlbmVyIn0sCiAge3tTVEFUSUNfS1NQUk9QU0VUSURfRGlyZWN0U291bmQzREJ1ZmZlcn0sICJEaXJlY3RTb3VuZDNEQnVmZmVyIn0sCiAge3tTVEFUSUNfS1NQUk9QU0VUSURfSHJ0ZjNkfSwgIkhydGYzZCJ9LAogIHt7U1RBVElDX0tTUFJPUFNFVElEX0l0ZDNkfSwgIkl0ZDNkIn0sCiAge3tTVEFUSUNfS1NQUk9QU0VUSURfQmlibGlvZ3JhcGhpY30sICJCaWJsaW9ncmFwaGljIn0sCiAge3tTVEFUSUNfS1NQUk9QU0VUSURfVG9wb2xvZ3lOb2RlfSwgIlRvcG9sb2d5Tm9kZSJ9LAogIHt7U1RBVElDX0tTUFJPUFNFVElEX1J0QXVkaW99LCAiUnRBdWRpbyJ9LAogIHt7U1RBVElDX0tTUFJPUFNFVElEX0RybUF1ZGlvU3RyZWFtfSwgIkRybUF1ZGlvU3RyZWFtIn0sCiAge3tTVEFUSUNfS1NQUk9QU0VUSURfQXVkaW99LCAiQXVkaW8ifSwKICB7e1NUQVRJQ19LU1BST1BTRVRJRF9BY291c3RpY19FY2hvX0NhbmNlbH0sICJBY291c3RpY19FY2hvX0NhbmNlbCJ9LAogIHt7U1RBVElDX0tTUFJPUFNFVElEX1dhdmVfUXVldWVkfSwgIldhdmVfUXVldWVkIn0sCiAge3tTVEFUSUNfS1NQUk9QU0VUSURfV2F2ZX0sICJXYXZlIn0sCiAge3tTVEFUSUNfS1NQUk9QU0VUSURfV2F2ZVRhYmxlfSwgIldhdmVUYWJsZSJ9LAogIHt7U1RBVElDX0tTUFJPUFNFVElEX0N5Y2xpY30sICJDeWNsaWMifSwKICB7e1NUQVRJQ19LU1BST1BTRVRJRF9TeXNhdWRpb30sICJTeXNhdWRpbyJ9LAogIHt7U1RBVElDX0tTUFJPUFNFVElEX1N5c2F1ZGlvX1Bpbn0sICJTeXNhdWRpb19QaW4ifSwKICB7e1NUQVRJQ19LU1BST1BTRVRJRF9BdWRpb0dmeH0sICJBdWRpb0dmeCJ9LAogIHt7U1RBVElDX0tTUFJPUFNFVElEX0xpbmVhcn0sICJMaW5lYXIifSwKICB7e1NUQVRJQ19LU1BST1BTRVRJRF9NcGVnMlZpZH0sICJNcGVnMlZpZCJ9LAogIHt7U1RBVElDX0tTUFJPUFNFVElEX0FDM30sICJBQzMifSwKICB7e1NUQVRJQ19LU1BST1BTRVRJRF9BdWRpb0RlY29kZXJPdXR9LCAiQXVkaW9EZWNvZGVyT3V0In0sCiAge3tTVEFUSUNfS1NQUk9QU0VUSURfRHZkU3ViUGljfSwgIkR2ZFN1YlBpYyJ9LAogIHt7U1RBVElDX0tTUFJPUFNFVElEX0NvcHlQcm90fSwgIkNvcHlQcm90In0sCiAge3tTVEFUSUNfS1NQUk9QU0VUSURfVkJJQ0FQX1BST1BFUlRJRVN9LCAiVkJJQ0FQX1BST1BFUlRJRVMifSwKICB7e1NUQVRJQ19LU1BST1BTRVRJRF9WQklDb2RlY0ZpbHRlcmluZ30sICJWQklDb2RlY0ZpbHRlcmluZyJ9LAogIHt7U1RBVElDX0tTUFJPUFNFVElEX1ZyYW1DYXB0dXJlfSwgIlZyYW1DYXB0dXJlIn0sCiAge3tTVEFUSUNfS1NQUk9QU0VUSURfT3ZlcmxheVVwZGF0ZX0sICJPdmVybGF5VXBkYXRlIn0sCiAge3tTVEFUSUNfS1NQUk9QU0VUSURfVlBDb25maWd9LCAiVlBDb25maWcifSwKICB7e1NUQVRJQ19LU1BST1BTRVRJRF9WUFZCSUNvbmZpZ30sICJWUFZCSUNvbmZpZyJ9LAogIHt7U1RBVElDX0tTUFJPUFNFVElEX1RTUmF0ZUNoYW5nZX0sICJUU1JhdGVDaGFuZ2UifSwKICB7e1NUQVRJQ19LU1BST1BTRVRJRF9KYWNrfSwgIkphY2sifSwKCiAge3tTVEFUSUNfUFJPUFNFVElEX0FMTE9DQVRPUl9DT05UUk9MfSwgIkFMTE9DQVRPUl9DT05UUk9MIn0sCiAge3tTVEFUSUNfUFJPUFNFVElEX1ZJRENBUF9WSURFT1BST0NBTVB9LCAiVklEQ0FQX1ZJREVPUFJPQ0FNUCJ9LAogIHt7U1RBVElDX1BST1BTRVRJRF9WSURDQVBfU0VMRUNUT1J9LCAiVklEQ0FQX1NFTEVDVE9SIn0sCiAge3tTVEFUSUNfUFJPUFNFVElEX1RVTkVSfSwgIlRVTkVSIn0sCiAge3tTVEFUSUNfUFJPUFNFVElEX1ZJRENBUF9WSURFT0VOQ09ERVJ9LCAiVklEQ0FQX1ZJREVPRU5DT0RFUiJ9LAogIHt7U1RBVElDX1BST1BTRVRJRF9WSURDQVBfVklERU9ERUNPREVSfSwgIlZJRENBUF9WSURFT0RFQ09ERVIifSwKICB7e1NUQVRJQ19QUk9QU0VUSURfVklEQ0FQX0NBTUVSQUNPTlRST0x9LCAiVklEQ0FQX0NBTUVSQUNPTlRST0wifSwKICB7e1NUQVRJQ19QUk9QU0VUSURfRVhUX0RFVklDRX0sICJFWFRfREVWSUNFIn0sCiAge3tTVEFUSUNfUFJPUFNFVElEX0VYVF9UUkFOU1BPUlR9LCAiRVhUX1RSQU5TUE9SVCJ9LAogIHt7U1RBVElDX1BST1BTRVRJRF9USU1FQ09ERV9SRUFERVJ9LCAiVElNRUNPREVfUkVBREVSIn0sCiAge3tTVEFUSUNfUFJPUFNFVElEX1ZJRENBUF9DUk9TU0JBUn0sICJWSURDQVBfQ1JPU1NCQVIifSwKICB7e1NUQVRJQ19QUk9QU0VUSURfVklEQ0FQX1RWQVVESU99LCAiVklEQ0FQX1RWQVVESU8ifSwKICB7e1NUQVRJQ19QUk9QU0VUSURfVklEQ0FQX1ZJREVPQ09NUFJFU1NJT059LCAiVklEQ0FQX1ZJREVPQ09NUFJFU1NJT04ifSwKICB7e1NUQVRJQ19QUk9QU0VUSURfVklEQ0FQX1ZJREVPQ09OVFJPTH0sICJWSURDQVBfVklERU9DT05UUk9MIn0sCiAge3tTVEFUSUNfUFJPUFNFVElEX1ZJRENBUF9EUk9QUEVERlJBTUVTfSwgIlZJRENBUF9EUk9QUEVERlJBTUVTIn0sCn07CgpnY2hhciAqCmtzX3Byb3BlcnR5X3NldF90b19zdHJpbmcgKGNvbnN0IEdVSUQgKiBndWlkKQp7CiAgZ3VpbnQgaTsKCiAgZm9yIChpID0gMDsKICAgICAgaSA8IHNpemVvZiAoa25vd25fcHJvcGVydHlfc2V0cykgLyBzaXplb2YgKGtub3duX3Byb3BlcnR5X3NldHNbMF0pOyBpKyspIHsKICAgIGlmIChJc0VxdWFsR1VJRCAoZ3VpZCwgJmtub3duX3Byb3BlcnR5X3NldHNbaV0uZ3VpZCkpCiAgICAgIHJldHVybiBnX3N0cmR1cF9wcmludGYgKCJLU1BST1BTRVRJRF8lcyIsIGtub3duX3Byb3BlcnR5X3NldHNbaV0ubmFtZSk7CiAgfQoKICByZXR1cm4ga3NfZ3VpZF90b19zdHJpbmcgKGd1aWQpOwp9Cg==