LyoKICogQ29weXJpZ2h0IChDKSAyMDA4IE9sZSBBbmRy6SBWYWRsYSBSYXZu5XMgPG9sZS5hbmRyZS5yYXZuYXNAdGFuZGJlcmcuY29tPgogKgogKiBUaGlzIGxpYnJhcnkgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yCiAqIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMaWJyYXJ5IEdlbmVyYWwgUHVibGljCiAqIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlcgogKiB2ZXJzaW9uIDIgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLAogKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZgogKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVQogKiBMaWJyYXJ5IEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIExpYnJhcnkgR2VuZXJhbCBQdWJsaWMKICogTGljZW5zZSBhbG9uZyB3aXRoIHRoaXMgbGlicmFyeTsgaWYgbm90LCB3cml0ZSB0byB0aGUKICogRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsCiAqIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSwgVVNBLgogKi8KCiNpbmNsdWRlICJrc2hlbHBlcnMuaCIKCiNpbmNsdWRlIDxrc21lZGlhLmg+CiNpbmNsdWRlIDxzZXR1cGFwaS5oPgojaW5jbHVkZSA8Z3N0L2dzdC5oPgoKR1NUX0RFQlVHX0NBVEVHT1JZX0VYVEVSTiAoZ3N0X2tzX2RlYnVnKTsKI2RlZmluZSBHU1RfQ0FUX0RFRkFVTFQgZ3N0X2tzX2RlYnVnCgojaWZuZGVmIFNUQVRJQ19LU1BST1BTRVRJRF9XYXZlX1F1ZXVlZAojZGVmaW5lIFNUQVRJQ19LU1BST1BTRVRJRF9XYXZlX1F1ZXVlZCBcCiAgICAweDE2YTE1YjEwTCwweDE2ZjAsMHgxMWQwLDB4YTEsMHg5NSwweDAwLDB4MjAsMHhhZiwweGQxLDB4NTYsMHhlNApERUZJTkVfR1VJRFNUUlVDVCAoIjE2YTE1YjEwLTE2ZjAtMTFkMC1hMTk1LTAwMjBhZmQxNTZlNCIsCiAgICBLU1BST1BTRVRJRF9XYXZlX1F1ZXVlZCk7CiNlbmRpZgoKZ2Jvb2xlYW4Ka3NfaXNfdmFsaWRfaGFuZGxlIChIQU5ETEUgaCkKewogIHJldHVybiAoaCAhPSBJTlZBTElEX0hBTkRMRV9WQUxVRSAmJiBoICE9IE5VTEwpOwp9CgpHTGlzdCAqCmtzX2VudW1lcmF0ZV9kZXZpY2VzIChjb25zdCBHVUlEICogY2F0ZWdvcnkpCnsKICBHTGlzdCAqcmVzdWx0ID0gTlVMTDsKICBIREVWSU5GTyBkZXZpbmZvOwogIGdpbnQgaTsKCiAgZGV2aW5mbyA9IFNldHVwRGlHZXRDbGFzc0RldnNXIChjYXRlZ29yeSwgTlVMTCwgTlVMTCwKICAgICAgRElHQ0ZfUFJFU0VOVCB8IERJR0NGX0RFVklDRUlOVEVSRkFDRSk7CiAgaWYgKCFrc19pc192YWxpZF9oYW5kbGUgKGRldmluZm8pKQogICAgcmV0dXJuIE5VTEw7ICAgICAgICAgICAgICAgIC8qIG5vIGRldmljZXMgKi8KCiAgZm9yIChpID0gMDs7IGkrKykgewogICAgQk9PTCBzdWNjZXNzOwogICAgU1BfREVWSUNFX0lOVEVSRkFDRV9EQVRBIGlmX2RhdGEgPSB7IDAsIH07CiAgICBTUF9ERVZJQ0VfSU5URVJGQUNFX0RFVEFJTF9EQVRBX1cgKmlmX2RldGFpbF9kYXRhOwogICAgRFdPUkQgaWZfZGV0YWlsX2RhdGFfc2l6ZTsKICAgIFNQX0RFVklORk9fREFUQSBkZXZpbmZvX2RhdGEgPSB7IDAsIH07CiAgICBEV09SRCByZXFfc2l6ZTsKCiAgICBpZl9kYXRhLmNiU2l6ZSA9IHNpemVvZiAoU1BfREVWSUNFX0lOVEVSRkFDRV9EQVRBKTsKCiAgICBzdWNjZXNzID0gU2V0dXBEaUVudW1EZXZpY2VJbnRlcmZhY2VzIChkZXZpbmZvLCBOVUxMLCBjYXRlZ29yeSwgaSwKICAgICAgICAmaWZfZGF0YSk7CiAgICBpZiAoIXN1Y2Nlc3MpICAgICAgICAgICAgICAgLyogYWxsIGRldmljZXMgZW51bWVyYXRlZD8gKi8KICAgICAgYnJlYWs7CgogICAgaWZfZGV0YWlsX2RhdGFfc2l6ZSA9IChNQVhfUEFUSCAtIDEpICogc2l6ZW9mIChndW5pY2hhcjIpOwogICAgaWZfZGV0YWlsX2RhdGEgPSBnX21hbGxvYzAgKGlmX2RldGFpbF9kYXRhX3NpemUpOwogICAgaWZfZGV0YWlsX2RhdGEtPmNiU2l6ZSA9IHNpemVvZiAoU1BfREVWSUNFX0lOVEVSRkFDRV9ERVRBSUxfREFUQV9XKTsKCiAgICBkZXZpbmZvX2RhdGEuY2JTaXplID0gc2l6ZW9mIChTUF9ERVZJTkZPX0RBVEEpOwoKICAgIHN1Y2Nlc3MgPSBTZXR1cERpR2V0RGV2aWNlSW50ZXJmYWNlRGV0YWlsVyAoZGV2aW5mbywgJmlmX2RhdGEsCiAgICAgICAgaWZfZGV0YWlsX2RhdGEsIGlmX2RldGFpbF9kYXRhX3NpemUsICZyZXFfc2l6ZSwgJmRldmluZm9fZGF0YSk7CiAgICBpZiAoc3VjY2VzcykgewogICAgICBLc0RldmljZUVudHJ5ICplbnRyeTsKICAgICAgV0NIQVIgYnVmWzUxMl07CgogICAgICBlbnRyeSA9IGdfbmV3MCAoS3NEZXZpY2VFbnRyeSwgMSk7CiAgICAgIGVudHJ5LT5pbmRleCA9IGk7CiAgICAgIGVudHJ5LT5wYXRoID0KICAgICAgICAgIGdfdXRmMTZfdG9fdXRmOCAoaWZfZGV0YWlsX2RhdGEtPkRldmljZVBhdGgsIC0xLCBOVUxMLCBOVUxMLCBOVUxMKTsKCiAgICAgIGlmIChTZXR1cERpR2V0RGV2aWNlUmVnaXN0cnlQcm9wZXJ0eVcgKGRldmluZm8sICZkZXZpbmZvX2RhdGEsCiAgICAgICAgICAgICAgU1BEUlBfRlJJRU5ETFlOQU1FLCBOVUxMLCAoQllURSAqKSBidWYsIHNpemVvZiAoYnVmKSwgTlVMTCkpIHsKICAgICAgICBlbnRyeS0+bmFtZSA9IGdfdXRmMTZfdG9fdXRmOCAoYnVmLCAtMSwgTlVMTCwgTlVMTCwgTlVMTCk7CiAgICAgIH0KCiAgICAgIGlmIChlbnRyeS0+bmFtZSA9PSBOVUxMKSB7CiAgICAgICAgaWYgKFNldHVwRGlHZXREZXZpY2VSZWdpc3RyeVByb3BlcnR5VyAoZGV2aW5mbywgJmRldmluZm9fZGF0YSwKICAgICAgICAgICAgICAgIFNQRFJQX0RFVklDRURFU0MsIE5VTEwsIChCWVRFICopIGJ1Ziwgc2l6ZW9mIChidWYpLCBOVUxMKSkgewogICAgICAgICAgZW50cnktPm5hbWUgPSBnX3V0ZjE2X3RvX3V0ZjggKGJ1ZiwgLTEsIE5VTEwsIE5VTEwsIE5VTEwpOwogICAgICAgIH0KICAgICAgfQoKICAgICAgaWYgKGVudHJ5LT5uYW1lICE9IE5VTEwpCiAgICAgICAgcmVzdWx0ID0gZ19saXN0X3ByZXBlbmQgKHJlc3VsdCwgZW50cnkpOwogICAgICBlbHNlCiAgICAgICAga3NfZGV2aWNlX2VudHJ5X2ZyZWUgKGVudHJ5KTsKICAgIH0KCiAgICBnX2ZyZWUgKGlmX2RldGFpbF9kYXRhKTsKICB9CgogIFNldHVwRGlEZXN0cm95RGV2aWNlSW5mb0xpc3QgKGRldmluZm8pOwoKICByZXR1cm4gZ19saXN0X3JldmVyc2UgKHJlc3VsdCk7Cn0KCnZvaWQKa3NfZGV2aWNlX2VudHJ5X2ZyZWUgKEtzRGV2aWNlRW50cnkgKiBlbnRyeSkKewogIGlmIChlbnRyeSA9PSBOVUxMKQogICAgcmV0dXJuOwoKICBnX2ZyZWUgKGVudHJ5LT5wYXRoKTsKICBnX2ZyZWUgKGVudHJ5LT5uYW1lKTsKCiAgZ19mcmVlIChlbnRyeSk7Cn0KCnZvaWQKa3NfZGV2aWNlX2xpc3RfZnJlZSAoR0xpc3QgKiBkZXZpY2VzKQp7CiAgR0xpc3QgKmN1cjsKCiAgZm9yIChjdXIgPSBkZXZpY2VzOyBjdXIgIT0gTlVMTDsgY3VyID0gY3VyLT5uZXh0KQogICAga3NfZGV2aWNlX2VudHJ5X2ZyZWUgKGN1ci0+ZGF0YSk7CgogIGdfbGlzdF9mcmVlIChkZXZpY2VzKTsKfQoKc3RhdGljIGdib29sZWFuCmtzX3N5bmNfZGV2aWNlX2lvX2NvbnRyb2wgKEhBTkRMRSBkZXZpY2UsIGd1bG9uZyBpb19jb250cm9sX2NvZGUsCiAgICBncG9pbnRlciBpbl9idWZmZXIsIGd1bG9uZyBpbl9idWZmZXJfc2l6ZSwgZ3BvaW50ZXIgb3V0X2J1ZmZlciwKICAgIGd1bG9uZyBvdXRfYnVmZmVyX3NpemUsIGd1bG9uZyAqIGJ5dGVzX3JldHVybmVkLCBndWxvbmcgKiBlcnJvcikKewogIE9WRVJMQVBQRUQgb3ZlcmxhcHBlZCA9IHsgMCwgfTsKICBCT09MIHN1Y2Nlc3M7CgogIG92ZXJsYXBwZWQuaEV2ZW50ID0gQ3JlYXRlRXZlbnQgKE5VTEwsIFRSVUUsIEZBTFNFLCBOVUxMKTsKCiAgc3VjY2VzcyA9IERldmljZUlvQ29udHJvbCAoZGV2aWNlLCBpb19jb250cm9sX2NvZGUsIGluX2J1ZmZlciwKICAgICAgaW5fYnVmZmVyX3NpemUsIG91dF9idWZmZXIsIG91dF9idWZmZXJfc2l6ZSwgYnl0ZXNfcmV0dXJuZWQsICZvdmVybGFwcGVkKTsKICBpZiAoIXN1Y2Nlc3MpIHsKICAgIERXT1JEIGVycjsKCiAgICBpZiAoKGVyciA9IEdldExhc3RFcnJvciAoKSkgPT0gRVJST1JfSU9fUEVORElORykgewogICAgICBzdWNjZXNzID0gR2V0T3ZlcmxhcHBlZFJlc3VsdCAoZGV2aWNlLCAmb3ZlcmxhcHBlZCwgYnl0ZXNfcmV0dXJuZWQsIFRSVUUpOwogICAgICBpZiAoIXN1Y2Nlc3MpCiAgICAgICAgZXJyID0gR2V0TGFzdEVycm9yICgpOwogICAgfQoKICAgIGlmIChlcnJvciAhPSBOVUxMKQogICAgICAqZXJyb3IgPSBlcnI7CiAgfQoKICBDbG9zZUhhbmRsZSAob3ZlcmxhcHBlZC5oRXZlbnQpOwoKICByZXR1cm4gc3VjY2VzcyA/IFRSVUUgOiBGQUxTRTsKfQoKZ2Jvb2xlYW4Ka3NfZmlsdGVyX2dldF9waW5fcHJvcGVydHkgKEhBTkRMRSBmaWx0ZXJfaGFuZGxlLCBndWxvbmcgcGluX2lkLAogICAgR1VJRCBwcm9wX3NldCwgZ3Vsb25nIHByb3BfaWQsIGdwb2ludGVyIHZhbHVlLCBndWxvbmcgdmFsdWVfc2l6ZSwKICAgIGd1bG9uZyAqIGVycm9yKQp7CiAgS1NQX1BJTiBwcm9wOwogIERXT1JEIGJ5dGVzX3JldHVybmVkID0gMDsKCiAgbWVtc2V0ICgmcHJvcCwgMCwgc2l6ZW9mIChLU1BfUElOKSk7CgogIHByb3AuUGluSWQgPSBwaW5faWQ7CiAgcHJvcC5Qcm9wZXJ0eS5TZXQgPSBwcm9wX3NldDsKICBwcm9wLlByb3BlcnR5LklkID0gcHJvcF9pZDsKICBwcm9wLlByb3BlcnR5LkZsYWdzID0gS1NQUk9QRVJUWV9UWVBFX0dFVDsKCiAgcmV0dXJuIGtzX3N5bmNfZGV2aWNlX2lvX2NvbnRyb2wgKGZpbHRlcl9oYW5kbGUsIElPQ1RMX0tTX1BST1BFUlRZLCAmcHJvcCwKICAgICAgc2l6ZW9mIChwcm9wKSwgdmFsdWUsIHZhbHVlX3NpemUsICZieXRlc19yZXR1cm5lZCwgZXJyb3IpOwp9CgpnYm9vbGVhbgprc19maWx0ZXJfZ2V0X3Bpbl9wcm9wZXJ0eV9tdWx0aSAoSEFORExFIGZpbHRlcl9oYW5kbGUsIGd1bG9uZyBwaW5faWQsCiAgICBHVUlEIHByb3Bfc2V0LCBndWxvbmcgcHJvcF9pZCwgS1NNVUxUSVBMRV9JVEVNICoqIGl0ZW1zLCBndWxvbmcgKiBlcnJvcikKewogIEtTUF9QSU4gcHJvcDsKICBEV09SRCBpdGVtc19zaXplID0gMCwgYnl0ZXNfd3JpdHRlbiA9IDA7CiAgZ3Vsb25nIGVycjsKICBnYm9vbGVhbiByZXQ7CgogIG1lbXNldCAoJnByb3AsIDAsIHNpemVvZiAoS1NQX1BJTikpOwogICppdGVtcyA9IE5VTEw7CgogIHByb3AuUGluSWQgPSBwaW5faWQ7CiAgcHJvcC5Qcm9wZXJ0eS5TZXQgPSBwcm9wX3NldDsKICBwcm9wLlByb3BlcnR5LklkID0gcHJvcF9pZDsKICBwcm9wLlByb3BlcnR5LkZsYWdzID0gS1NQUk9QRVJUWV9UWVBFX0dFVDsKCiAgcmV0ID0ga3Nfc3luY19kZXZpY2VfaW9fY29udHJvbCAoZmlsdGVyX2hhbmRsZSwgSU9DVExfS1NfUFJPUEVSVFksCiAgICAgICZwcm9wLlByb3BlcnR5LCBzaXplb2YgKHByb3ApLCBOVUxMLCAwLCAmaXRlbXNfc2l6ZSwgJmVycik7CiAgaWYgKCFyZXQgJiYgZXJyICE9IEVSUk9SX0lOU1VGRklDSUVOVF9CVUZGRVIgJiYgZXJyICE9IEVSUk9SX01PUkVfREFUQSkKICAgIGdvdG8gaW9jdGxfZmFpbGVkOwoKICAqaXRlbXMgPSBnX21hbGxvYzAgKGl0ZW1zX3NpemUpOwoKICByZXQgPSBrc19zeW5jX2RldmljZV9pb19jb250cm9sIChmaWx0ZXJfaGFuZGxlLCBJT0NUTF9LU19QUk9QRVJUWSwgJnByb3AsCiAgICAgIHNpemVvZiAocHJvcCksICppdGVtcywgaXRlbXNfc2l6ZSwgJmJ5dGVzX3dyaXR0ZW4sICZlcnIpOwogIGlmICghcmV0KQogICAgZ290byBpb2N0bF9mYWlsZWQ7CgogIHJldHVybiByZXQ7Cgppb2N0bF9mYWlsZWQ6CiAgaWYgKGVycm9yICE9IE5VTEwpCiAgICAqZXJyb3IgPSBlcnI7CgogIGdfZnJlZSAoKml0ZW1zKTsKICAqaXRlbXMgPSBOVUxMOwoKICByZXR1cm4gRkFMU0U7Cn0KCmdib29sZWFuCmtzX29iamVjdF9xdWVyeV9wcm9wZXJ0eSAoSEFORExFIGhhbmRsZSwgR1VJRCBwcm9wX3NldCwgZ3Vsb25nIHByb3BfaWQsCiAgICBndWxvbmcgcHJvcF9mbGFncywgZ3BvaW50ZXIgKiB2YWx1ZSwgZ3Vsb25nICogdmFsdWVfc2l6ZSwgZ3Vsb25nICogZXJyb3IpCnsKICBLU1BST1BFUlRZIHByb3A7CiAgRFdPUkQgcmVxX3ZhbHVlX3NpemUgPSAwLCBieXRlc193cml0dGVuID0gMDsKICBndWxvbmcgZXJyOwogIGdib29sZWFuIHJldDsKCiAgbWVtc2V0ICgmcHJvcCwgMCwgc2l6ZW9mIChLU1BST1BFUlRZKSk7CiAgKnZhbHVlID0gTlVMTDsKCiAgcHJvcC5TZXQgPSBwcm9wX3NldDsKICBwcm9wLklkID0gcHJvcF9pZDsKICBwcm9wLkZsYWdzID0gcHJvcF9mbGFnczsKCiAgaWYgKHZhbHVlX3NpemUgPT0gTlVMTCB8fCAqdmFsdWVfc2l6ZSA9PSAwKSB7CiAgICByZXQgPSBrc19zeW5jX2RldmljZV9pb19jb250cm9sIChoYW5kbGUsIElPQ1RMX0tTX1BST1BFUlRZLAogICAgICAgICZwcm9wLCBzaXplb2YgKHByb3ApLCBOVUxMLCAwLCAmcmVxX3ZhbHVlX3NpemUsICZlcnIpOwogICAgaWYgKCFyZXQgJiYgZXJyICE9IEVSUk9SX0lOU1VGRklDSUVOVF9CVUZGRVIgJiYgZXJyICE9IEVSUk9SX01PUkVfREFUQSkKICAgICAgZ290byBpb2N0bF9mYWlsZWQ7CiAgfSBlbHNlIHsKICAgIHJlcV92YWx1ZV9zaXplID0gKnZhbHVlX3NpemU7CiAgfQoKICAqdmFsdWUgPSBnX21hbGxvYzAgKHJlcV92YWx1ZV9zaXplKTsKCiAgcmV0ID0ga3Nfc3luY19kZXZpY2VfaW9fY29udHJvbCAoaGFuZGxlLCBJT0NUTF9LU19QUk9QRVJUWSwgJnByb3AsCiAgICAgIHNpemVvZiAocHJvcCksICp2YWx1ZSwgcmVxX3ZhbHVlX3NpemUsICZieXRlc193cml0dGVuLCAmZXJyKTsKICBpZiAoIXJldCkKICAgIGdvdG8gaW9jdGxfZmFpbGVkOwoKICBpZiAodmFsdWVfc2l6ZSAhPSBOVUxMKQogICAgKnZhbHVlX3NpemUgPSBieXRlc193cml0dGVuOwoKICByZXR1cm4gcmV0OwoKaW9jdGxfZmFpbGVkOgogIGlmIChlcnJvciAhPSBOVUxMKQogICAgKmVycm9yID0gZXJyOwoKICBnX2ZyZWUgKCp2YWx1ZSk7CiAgKnZhbHVlID0gTlVMTDsKCiAgaWYgKHZhbHVlX3NpemUgIT0gTlVMTCkKICAgICp2YWx1ZV9zaXplID0gMDsKCiAgcmV0dXJuIEZBTFNFOwp9CgpnYm9vbGVhbgprc19vYmplY3RfZ2V0X3Byb3BlcnR5IChIQU5ETEUgaGFuZGxlLCBHVUlEIHByb3Bfc2V0LCBndWxvbmcgcHJvcF9pZCwKICAgIGdwb2ludGVyICogdmFsdWUsIGd1bG9uZyAqIHZhbHVlX3NpemUsIGd1bG9uZyAqIGVycm9yKQp7CiAgcmV0dXJuIGtzX29iamVjdF9xdWVyeV9wcm9wZXJ0eSAoaGFuZGxlLCBwcm9wX3NldCwgcHJvcF9pZCwKICAgICAgS1NQUk9QRVJUWV9UWVBFX0dFVCwgdmFsdWUsIHZhbHVlX3NpemUsIGVycm9yKTsKfQoKZ2Jvb2xlYW4Ka3Nfb2JqZWN0X3NldF9wcm9wZXJ0eSAoSEFORExFIGhhbmRsZSwgR1VJRCBwcm9wX3NldCwgZ3Vsb25nIHByb3BfaWQsCiAgICBncG9pbnRlciB2YWx1ZSwgZ3Vsb25nIHZhbHVlX3NpemUsIGd1bG9uZyAqIGVycm9yKQp7CiAgS1NQUk9QRVJUWSBwcm9wOwogIERXT1JEIGJ5dGVzX3JldHVybmVkOwoKICBtZW1zZXQgKCZwcm9wLCAwLCBzaXplb2YgKEtTUFJPUEVSVFkpKTsKICBwcm9wLlNldCA9IHByb3Bfc2V0OwogIHByb3AuSWQgPSBwcm9wX2lkOwogIHByb3AuRmxhZ3MgPSBLU1BST1BFUlRZX1RZUEVfU0VUOwoKICByZXR1cm4ga3Nfc3luY19kZXZpY2VfaW9fY29udHJvbCAoaGFuZGxlLCBJT0NUTF9LU19QUk9QRVJUWSwgJnByb3AsCiAgICAgIHNpemVvZiAocHJvcCksIHZhbHVlLCB2YWx1ZV9zaXplLCAmYnl0ZXNfcmV0dXJuZWQsIGVycm9yKTsKfQoKZ2Jvb2xlYW4Ka3Nfb2JqZWN0X2dldF9zdXBwb3J0ZWRfcHJvcGVydHlfc2V0cyAoSEFORExFIGhhbmRsZSwgR1VJRCAqKiBwcm9wc2V0cywKICAgIGd1bG9uZyAqIGxlbikKewogIGd1bG9uZyBzaXplID0gMDsKICBndWxvbmcgZXJyb3I7CgogICpwcm9wc2V0cyA9IE5VTEw7CiAgKmxlbiA9IDA7CgogIGlmIChrc19vYmplY3RfcXVlcnlfcHJvcGVydHkgKGhhbmRsZSwgR1VJRF9OVUxMLCAwLAogICAgICAgICAgS1NQUk9QRVJUWV9UWVBFX1NFVFNVUFBPUlQsICh2b2lkICopIHByb3BzZXRzLCAmc2l6ZSwgJmVycm9yKSkgewogICAgaWYgKHNpemUgJSBzaXplb2YgKEdVSUQpID09IDApIHsKICAgICAgKmxlbiA9IHNpemUgLyBzaXplb2YgKEdVSUQpOwogICAgICByZXR1cm4gVFJVRTsKICAgIH0KICB9CgogIGdfZnJlZSAoKnByb3BzZXRzKTsKICAqcHJvcHNldHMgPSBOVUxMOwogICpsZW4gPSAwOwogIHJldHVybiBGQUxTRTsKfQoKZ2Jvb2xlYW4Ka3Nfb2JqZWN0X3NldF9jb25uZWN0aW9uX3N0YXRlIChIQU5ETEUgaGFuZGxlLCBLU1NUQVRFIHN0YXRlLCBndWxvbmcgKiBlcnJvcikKewogIHJldHVybiBrc19vYmplY3Rfc2V0X3Byb3BlcnR5IChoYW5kbGUsIEtTUFJPUFNFVElEX0Nvbm5lY3Rpb24sCiAgICAgIEtTUFJPUEVSVFlfQ09OTkVDVElPTl9TVEFURSwgJnN0YXRlLCBzaXplb2YgKHN0YXRlKSwgZXJyb3IpOwp9CgpnY2hhciAqCmtzX2d1aWRfdG9fc3RyaW5nIChjb25zdCBHVUlEICogZ3VpZCkKewogIHJldHVybiBnX3N0cmR1cF9wcmludGYgKCJ7JTA4WC0lMDRYLSUwNFgtJTAyWCUwMlgtJTAyWCUwMlglMDJYJTAyWCUwMlglMDJYfSIsCiAgICAgIChndWludCkgZ3VpZC0+RGF0YTEsIChndWludCkgZ3VpZC0+RGF0YTIsIChndWludCkgZ3VpZC0+RGF0YTMsCiAgICAgIChndWludCkgZ3VpZC0+RGF0YTRbMF0sIChndWludCkgZ3VpZC0+RGF0YTRbMV0sIChndWludCkgZ3VpZC0+RGF0YTRbMl0sCiAgICAgIChndWludCkgZ3VpZC0+RGF0YTRbM10sIChndWludCkgZ3VpZC0+RGF0YTRbNF0sIChndWludCkgZ3VpZC0+RGF0YTRbNV0sCiAgICAgIChndWludCkgZ3VpZC0+RGF0YTRbNl0sIChndWludCkgZ3VpZC0+RGF0YTRbN10pOwp9Cgpjb25zdCBnY2hhciAqCmtzX3N0YXRlX3RvX3N0cmluZyAoS1NTVEFURSBzdGF0ZSkKewogIHN3aXRjaCAoc3RhdGUpIHsKICAgIGNhc2UgS1NTVEFURV9TVE9QOgogICAgICByZXR1cm4gIktTU1RBVEVfU1RPUCI7CiAgICBjYXNlIEtTU1RBVEVfQUNRVUlSRToKICAgICAgcmV0dXJuICJLU1NUQVRFX0FDUVVJUkUiOwogICAgY2FzZSBLU1NUQVRFX1BBVVNFOgogICAgICByZXR1cm4gIktTU1RBVEVfUEFVU0UiOwogICAgY2FzZSBLU1NUQVRFX1JVTjoKICAgICAgcmV0dXJuICJLU1NUQVRFX1JVTiI7CiAgICBkZWZhdWx0OgogICAgICBnX2Fzc2VydF9ub3RfcmVhY2hlZCAoKTsKICB9CgogIHJldHVybiAiVU5LTk9XTiI7Cn0KCiNkZWZpbmUgQ0hFQ0tfT1BUSU9OU19GTEFHKGZsYWcpIFwKICBpZiAoZmxhZ3MgJiBLU1NUUkVBTV9IRUFERVJfT1BUSU9OU0ZfIyNmbGFnKVwKICB7XAogICAgaWYgKHN0ci0+bGVuID4gMClcCiAgICAgIGdfc3RyaW5nX2FwcGVuZCAoc3RyLCAifCIpO1wKICAgIGdfc3RyaW5nX2FwcGVuZCAoc3RyLCBHX1NUUklOR0lGWSAoZmxhZykpO1wKICAgIGZsYWdzICY9IH5LU1NUUkVBTV9IRUFERVJfT1BUSU9OU0ZfIyNmbGFnO1wKICB9CgpnY2hhciAqCmtzX29wdGlvbnNfZmxhZ3NfdG9fc3RyaW5nIChndWxvbmcgZmxhZ3MpCnsKICBnY2hhciAqcmV0OwogIEdTdHJpbmcgKnN0cjsKCiAgc3RyID0gZ19zdHJpbmdfc2l6ZWRfbmV3ICgxMjgpOwoKICBDSEVDS19PUFRJT05TX0ZMQUcgKFNQTElDRVBPSU5UKTsKICBDSEVDS19PUFRJT05TX0ZMQUcgKFBSRVJPTEwpOwogIENIRUNLX09QVElPTlNfRkxBRyAoREFUQURJU0NPTlRJTlVJVFkpOwogIENIRUNLX09QVElPTlNfRkxBRyAoVFlQRUNIQU5HRUQpOwogIENIRUNLX09QVElPTlNfRkxBRyAoVElNRVZBTElEKTsKICBDSEVDS19PUFRJT05TX0ZMQUcgKFRJTUVESVNDT05USU5VSVRZKTsKICBDSEVDS19PUFRJT05TX0ZMQUcgKEZMVVNIT05QQVVTRSk7CiAgQ0hFQ0tfT1BUSU9OU19GTEFHIChEVVJBVElPTlZBTElEKTsKICBDSEVDS19PUFRJT05TX0ZMQUcgKEVORE9GU1RSRUFNKTsKICBDSEVDS19PUFRJT05TX0ZMQUcgKEJVRkZFUkVEVFJBTlNGRVIpOwogIENIRUNLX09QVElPTlNfRkxBRyAoVlJBTV9EQVRBX1RSQU5TRkVSKTsKICBDSEVDS19PUFRJT05TX0ZMQUcgKExPT1BFRERBVEEpOwoKICBpZiAoZmxhZ3MgIT0gMCkKICAgIGdfc3RyaW5nX2FwcGVuZF9wcmludGYgKHN0ciwgInwweCUwOHgiLCAoZ3VpbnQpIGZsYWdzKTsKCiAgcmV0ID0gc3RyLT5zdHI7CiAgZ19zdHJpbmdfZnJlZSAoc3RyLCBGQUxTRSk7CgogIHJldHVybiByZXQ7Cn0KCnR5cGVkZWYgc3RydWN0CnsKICBjb25zdCBHVUlEIGd1aWQ7CiAgY29uc3QgZ2NoYXIgKm5hbWU7Cn0gS3NQcm9wZXJ0eVNldE1hcHBpbmc7CgojaWZuZGVmIFNUQVRJQ19LU1BST1BTRVRJRF9HTQojZGVmaW5lIFNUQVRJQ19LU1BST1BTRVRJRF9HTSBcCiAgICAweEFGNjI3NTM2LCAweEU3MTksIDB4MTFEMiwgMHg4QSwgMHgxRCwgMHgwMCwgMHg2MCwgMHg5NywgMHhEMiwgMHhERiwgMHg1RAojZW5kaWYKI2lmbmRlZiBTVEFUSUNfS1NQUk9QU0VUSURfSmFjawojZGVmaW5lIFNUQVRJQ19LU1BST1BTRVRJRF9KYWNrIFwKICAgIDB4NDUwOUY3NTcsIDB4MkQ0NiwgMHg0NjM3LCAweDhFLCAweDYyLCAweENFLCAweDdELCAweEI5LCAweDQ0LCAweEY1LCAweDdCCiNlbmRpZgoKI2lmbmRlZiBTVEFUSUNfUFJPUFNFVElEX1ZJRENBUF9TRUxFQ1RPUgojZGVmaW5lIFNUQVRJQ19QUk9QU0VUSURfVklEQ0FQX1NFTEVDVE9SIFwKICAgIDB4MUFCREFFQ0EsIDB4NjhCNiwgMHg0RjgzLCAweDkzLCAweDcxLCAweEI0LCAweDEzLCAweDkwLCAweDdDLCAweDdCLCAweDlGCiNlbmRpZgojaWZuZGVmIFNUQVRJQ19QUk9QU0VUSURfRVhUX0RFVklDRQojZGVmaW5lIFNUQVRJQ19QUk9QU0VUSURfRVhUX0RFVklDRSBcCiAgICAweEI1NzMwQTkwLCAweDFBMkMsIDB4MTFjZiwgMHg4YywgMHgyMywgMHgwMCwgMHhBQSwgMHgwMCwgMHg2QiwgMHg2OCwgMHgxNAojZW5kaWYKI2lmbmRlZiBTVEFUSUNfUFJPUFNFVElEX0VYVF9UUkFOU1BPUlQKI2RlZmluZSBTVEFUSUNfUFJPUFNFVElEX0VYVF9UUkFOU1BPUlQgXAogICAgMHhBMDNDRDVGMCwgMHgzMDQ1LCAweDExY2YsIDB4OGMsIDB4NDQsIDB4MDAsIDB4QUEsIDB4MDAsIDB4NkIsIDB4NjgsIDB4MTQKI2VuZGlmCiNpZm5kZWYgU1RBVElDX1BST1BTRVRJRF9USU1FQ09ERV9SRUFERVIKI2RlZmluZSBTVEFUSUNfUFJPUFNFVElEX1RJTUVDT0RFX1JFQURFUiBcCiAgICAweDlCNDk2Q0UxLCAweDgxMUIsIDB4MTFjZiwgMHg4QywgMHg3NywgMHgwMCwgMHhBQSwgMHgwMCwgMHg2QiwgMHg2OCwgMHgxNAojZW5kaWYKCnN0YXRpYyBjb25zdCBLc1Byb3BlcnR5U2V0TWFwcGluZyBrbm93bl9wcm9wZXJ0eV9zZXRzW10gPSB7CiAge3tTVEFUSUNfS1NQUk9QU0VUSURfR2VuZXJhbH0sICJHZW5lcmFsIn0sCiAge3tTVEFUSUNfS1NQUk9QU0VUSURfTWVkaWFTZWVraW5nfSwgIk1lZGlhU2Vla2luZyJ9LAogIHt7U1RBVElDX0tTUFJPUFNFVElEX1RvcG9sb2d5fSwgIlRvcG9sb2d5In0sCiAge3tTVEFUSUNfS1NQUk9QU0VUSURfR019LCAiR00ifSwKICB7e1NUQVRJQ19LU1BST1BTRVRJRF9QaW59LCAiUGluIn0sCiAge3tTVEFUSUNfS1NQUk9QU0VUSURfUXVhbGl0eX0sICJRdWFsaXR5In0sCiAge3tTVEFUSUNfS1NQUk9QU0VUSURfQ29ubmVjdGlvbn0sICJDb25uZWN0aW9uIn0sCiAge3tTVEFUSUNfS1NQUk9QU0VUSURfTWVtb3J5VHJhbnNwb3J0fSwgIk1lbW9yeVRyYW5zcG9ydCJ9LAogIHt7U1RBVElDX0tTUFJPUFNFVElEX1N0cmVhbUFsbG9jYXRvcn0sICJTdHJlYW1BbGxvY2F0b3IifSwKICB7e1NUQVRJQ19LU1BST1BTRVRJRF9TdHJlYW1JbnRlcmZhY2V9LCAiU3RyZWFtSW50ZXJmYWNlIn0sCiAge3tTVEFUSUNfS1NQUk9QU0VUSURfU3RyZWFtfSwgIlN0cmVhbSJ9LAogIHt7U1RBVElDX0tTUFJPUFNFVElEX0Nsb2NrfSwgIkNsb2NrIn0sCgogIHt7U1RBVElDX0tTUFJPUFNFVElEX0RpcmVjdFNvdW5kM0RMaXN0ZW5lcn0sICJEaXJlY3RTb3VuZDNETGlzdGVuZXIifSwKICB7e1NUQVRJQ19LU1BST1BTRVRJRF9EaXJlY3RTb3VuZDNEQnVmZmVyfSwgIkRpcmVjdFNvdW5kM0RCdWZmZXIifSwKICB7e1NUQVRJQ19LU1BST1BTRVRJRF9IcnRmM2R9LCAiSHJ0ZjNkIn0sCiAge3tTVEFUSUNfS1NQUk9QU0VUSURfSXRkM2R9LCAiSXRkM2QifSwKICB7e1NUQVRJQ19LU1BST1BTRVRJRF9CaWJsaW9ncmFwaGljfSwgIkJpYmxpb2dyYXBoaWMifSwKICB7e1NUQVRJQ19LU1BST1BTRVRJRF9Ub3BvbG9neU5vZGV9LCAiVG9wb2xvZ3lOb2RlIn0sCiAge3tTVEFUSUNfS1NQUk9QU0VUSURfUnRBdWRpb30sICJSdEF1ZGlvIn0sCiAge3tTVEFUSUNfS1NQUk9QU0VUSURfRHJtQXVkaW9TdHJlYW19LCAiRHJtQXVkaW9TdHJlYW0ifSwKICB7e1NUQVRJQ19LU1BST1BTRVRJRF9BdWRpb30sICJBdWRpbyJ9LAogIHt7U1RBVElDX0tTUFJPUFNFVElEX0Fjb3VzdGljX0VjaG9fQ2FuY2VsfSwgIkFjb3VzdGljX0VjaG9fQ2FuY2VsIn0sCiAge3tTVEFUSUNfS1NQUk9QU0VUSURfV2F2ZV9RdWV1ZWR9LCAiV2F2ZV9RdWV1ZWQifSwKICB7e1NUQVRJQ19LU1BST1BTRVRJRF9XYXZlfSwgIldhdmUifSwKICB7e1NUQVRJQ19LU1BST1BTRVRJRF9XYXZlVGFibGV9LCAiV2F2ZVRhYmxlIn0sCiAge3tTVEFUSUNfS1NQUk9QU0VUSURfQ3ljbGljfSwgIkN5Y2xpYyJ9LAogIHt7U1RBVElDX0tTUFJPUFNFVElEX1N5c2F1ZGlvfSwgIlN5c2F1ZGlvIn0sCiAge3tTVEFUSUNfS1NQUk9QU0VUSURfU3lzYXVkaW9fUGlufSwgIlN5c2F1ZGlvX1BpbiJ9LAogIHt7U1RBVElDX0tTUFJPUFNFVElEX0F1ZGlvR2Z4fSwgIkF1ZGlvR2Z4In0sCiAge3tTVEFUSUNfS1NQUk9QU0VUSURfTGluZWFyfSwgIkxpbmVhciJ9LAogIHt7U1RBVElDX0tTUFJPUFNFVElEX01wZWcyVmlkfSwgIk1wZWcyVmlkIn0sCiAge3tTVEFUSUNfS1NQUk9QU0VUSURfQUMzfSwgIkFDMyJ9LAogIHt7U1RBVElDX0tTUFJPUFNFVElEX0F1ZGlvRGVjb2Rlck91dH0sICJBdWRpb0RlY29kZXJPdXQifSwKICB7e1NUQVRJQ19LU1BST1BTRVRJRF9EdmRTdWJQaWN9LCAiRHZkU3ViUGljIn0sCiAge3tTVEFUSUNfS1NQUk9QU0VUSURfQ29weVByb3R9LCAiQ29weVByb3QifSwKICB7e1NUQVRJQ19LU1BST1BTRVRJRF9WQklDQVBfUFJPUEVSVElFU30sICJWQklDQVBfUFJPUEVSVElFUyJ9LAogIHt7U1RBVElDX0tTUFJPUFNFVElEX1ZCSUNvZGVjRmlsdGVyaW5nfSwgIlZCSUNvZGVjRmlsdGVyaW5nIn0sCiAge3tTVEFUSUNfS1NQUk9QU0VUSURfVnJhbUNhcHR1cmV9LCAiVnJhbUNhcHR1cmUifSwKICB7e1NUQVRJQ19LU1BST1BTRVRJRF9PdmVybGF5VXBkYXRlfSwgIk92ZXJsYXlVcGRhdGUifSwKICB7e1NUQVRJQ19LU1BST1BTRVRJRF9WUENvbmZpZ30sICJWUENvbmZpZyJ9LAogIHt7U1RBVElDX0tTUFJPUFNFVElEX1ZQVkJJQ29uZmlnfSwgIlZQVkJJQ29uZmlnIn0sCiAge3tTVEFUSUNfS1NQUk9QU0VUSURfVFNSYXRlQ2hhbmdlfSwgIlRTUmF0ZUNoYW5nZSJ9LAogIHt7U1RBVElDX0tTUFJPUFNFVElEX0phY2t9LCAiSmFjayJ9LAoKICB7e1NUQVRJQ19QUk9QU0VUSURfQUxMT0NBVE9SX0NPTlRST0x9LCAiQUxMT0NBVE9SX0NPTlRST0wifSwKICB7e1NUQVRJQ19QUk9QU0VUSURfVklEQ0FQX1ZJREVPUFJPQ0FNUH0sICJWSURDQVBfVklERU9QUk9DQU1QIn0sCiAge3tTVEFUSUNfUFJPUFNFVElEX1ZJRENBUF9TRUxFQ1RPUn0sICJWSURDQVBfU0VMRUNUT1IifSwKICB7e1NUQVRJQ19QUk9QU0VUSURfVFVORVJ9LCAiVFVORVIifSwKICB7e1NUQVRJQ19QUk9QU0VUSURfVklEQ0FQX1ZJREVPRU5DT0RFUn0sICJWSURDQVBfVklERU9FTkNPREVSIn0sCiAge3tTVEFUSUNfUFJPUFNFVElEX1ZJRENBUF9WSURFT0RFQ09ERVJ9LCAiVklEQ0FQX1ZJREVPREVDT0RFUiJ9LAogIHt7U1RBVElDX1BST1BTRVRJRF9WSURDQVBfQ0FNRVJBQ09OVFJPTH0sICJWSURDQVBfQ0FNRVJBQ09OVFJPTCJ9LAogIHt7U1RBVElDX1BST1BTRVRJRF9FWFRfREVWSUNFfSwgIkVYVF9ERVZJQ0UifSwKICB7e1NUQVRJQ19QUk9QU0VUSURfRVhUX1RSQU5TUE9SVH0sICJFWFRfVFJBTlNQT1JUIn0sCiAge3tTVEFUSUNfUFJPUFNFVElEX1RJTUVDT0RFX1JFQURFUn0sICJUSU1FQ09ERV9SRUFERVIifSwKICB7e1NUQVRJQ19QUk9QU0VUSURfVklEQ0FQX0NST1NTQkFSfSwgIlZJRENBUF9DUk9TU0JBUiJ9LAogIHt7U1RBVElDX1BST1BTRVRJRF9WSURDQVBfVFZBVURJT30sICJWSURDQVBfVFZBVURJTyJ9LAogIHt7U1RBVElDX1BST1BTRVRJRF9WSURDQVBfVklERU9DT01QUkVTU0lPTn0sICJWSURDQVBfVklERU9DT01QUkVTU0lPTiJ9LAogIHt7U1RBVElDX1BST1BTRVRJRF9WSURDQVBfVklERU9DT05UUk9MfSwgIlZJRENBUF9WSURFT0NPTlRST0wifSwKICB7e1NUQVRJQ19QUk9QU0VUSURfVklEQ0FQX0RST1BQRURGUkFNRVN9LCAiVklEQ0FQX0RST1BQRURGUkFNRVMifSwKfTsKCmdjaGFyICoKa3NfcHJvcGVydHlfc2V0X3RvX3N0cmluZyAoY29uc3QgR1VJRCAqIGd1aWQpCnsKICBndWludCBpOwoKICBmb3IgKGkgPSAwOwogICAgICBpIDwgc2l6ZW9mIChrbm93bl9wcm9wZXJ0eV9zZXRzKSAvIHNpemVvZiAoa25vd25fcHJvcGVydHlfc2V0c1swXSk7IGkrKykgewogICAgaWYgKElzRXF1YWxHVUlEIChndWlkLCAma25vd25fcHJvcGVydHlfc2V0c1tpXS5ndWlkKSkKICAgICAgcmV0dXJuIGdfc3RyZHVwX3ByaW50ZiAoIktTUFJPUFNFVElEXyVzIiwga25vd25fcHJvcGVydHlfc2V0c1tpXS5uYW1lKTsKICB9CgogIHJldHVybiBrc19ndWlkX3RvX3N0cmluZyAoZ3VpZCk7Cn0K