QmxvY2sgSW1wbGVtZW50YXRpb24gU3BlY2lmaWNhdGlvbgoKQ29weXJpZ2h0IDIwMDgtMjAwOSBBcHBsZSwgSW5jLgpQZXJtaXNzaW9uIGlzIGhlcmVieSBncmFudGVkLCBmcmVlIG9mIGNoYXJnZSwgdG8gYW55IHBlcnNvbiBvYnRhaW5pbmcgYSBjb3B5Cm9mIHRoaXMgc29mdHdhcmUgYW5kIGFzc29jaWF0ZWQgZG9jdW1lbnRhdGlvbiBmaWxlcyAodGhlICJTb2Z0d2FyZSIpLCB0byBkZWFsCmluIHRoZSBTb2Z0d2FyZSB3aXRob3V0IHJlc3RyaWN0aW9uLCBpbmNsdWRpbmcgd2l0aG91dCBsaW1pdGF0aW9uIHRoZSByaWdodHMKdG8gdXNlLCBjb3B5LCBtb2RpZnksIG1lcmdlLCBwdWJsaXNoLCBkaXN0cmlidXRlLCBzdWJsaWNlbnNlLCBhbmQvb3Igc2VsbApjb3BpZXMgb2YgdGhlIFNvZnR3YXJlLCBhbmQgdG8gcGVybWl0IHBlcnNvbnMgdG8gd2hvbSB0aGUgU29mdHdhcmUgaXMKZnVybmlzaGVkIHRvIGRvIHNvLCBzdWJqZWN0IHRvIHRoZSBmb2xsb3dpbmcgY29uZGl0aW9uczoKClRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsIGJlIGluY2x1ZGVkIGluCmFsbCBjb3BpZXMgb3Igc3Vic3RhbnRpYWwgcG9ydGlvbnMgb2YgdGhlIFNvZnR3YXJlLgoKVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEICJBUyBJUyIsIFdJVEhPVVQgV0FSUkFOVFkgT0YgQU5ZIEtJTkQsIEVYUFJFU1MgT1IKSU1QTElFRCwgSU5DTFVESU5HIEJVVCBOT1QgTElNSVRFRCBUTyBUSEUgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFksCkZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFORCBOT05JTkZSSU5HRU1FTlQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRQpBVVRIT1JTIE9SIENPUFlSSUdIVCBIT0xERVJTIEJFIExJQUJMRSBGT1IgQU5ZIENMQUlNLCBEQU1BR0VTIE9SIE9USEVSCkxJQUJJTElUWSwgV0hFVEhFUiBJTiBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsIFRPUlQgT1IgT1RIRVJXSVNFLCBBUklTSU5HIEZST00sCk9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFNPRlRXQVJFIE9SIFRIRSBVU0UgT1IgT1RIRVIgREVBTElOR1MgSU4KVEhFIFNPRlRXQVJFLgoKMC4gSGlzdG9yeQoKMjAwOC83LzE0ICAtIGNyZWF0ZWQKMjAwOC84LzIxICAtIHJldmlzZWQsIEMrKwoyMDA4LzkvMjQgIC0gYWRkIE5VTEwgaXNhIGZpZWxkIHRvIF9fYmxvY2sgc3RvcmFnZQoyMDA4LzEwLzEgIC0gcmV2aXNlIGJsb2NrIGxheW91dCB0byB1c2UgYSBzdGF0aWMgZGVzY3JpcHRvciBzdHJ1Y3R1cmUKMjAwOC8xMC82ICAtIHJldmlzZSBibG9jayBsYXlvdXQgdG8gdXNlIGFuIHVuc2lnbmVkIGxvbmcgaW50IGZsYWdzCjIwMDgvMTAvMjggLSBzcGVjaWZ5IHVzZSBvZiBfQmxvY2tfb2JqZWN0X2Fzc2lnbi9kaXNwb3NlIGZvciBhbGwgIk9iamVjdCIgdHlwZXMgaW4gaGVscGVyIGZ1bmN0aW9ucwoyMDA4LzEwLzMwIC0gcmV2aXNlIG5ldyBsYXlvdXQgdG8gaGF2ZSBpbnZva2UgZnVuY3Rpb24gaW4gc2FtZSBwbGFjZQoyMDA4LzEwLzMwIC0gYWRkIF9fd2VhayBzdXBwb3J0CgpUaGlzIGRvY3VtZW50IGRlc2NyaWJlcyB0aGUgQXBwbGUgQUJJIGltcGxlbWVudGF0aW9uIHNwZWNpZmljYXRpb24gb2YgQmxvY2tzLgoKMS4gSGlnaCBMZXZlbAoKQSBCbG9jayBjb25zaXN0cyBvZiBhIHN0cnVjdHVyZSBvZiB0aGUgZm9sbG93aW5nIGZvcm06CgpzdHJ1Y3QgQmxvY2tfbGl0ZXJhbF8xIHsKICAgIHZvaWQgKmlzYTsgLy8gaW5pdGlhbGl6ZWQgdG8gJl9OU0NvbmNyZXRlU3RhY2tCbG9jayBvciAmX05TQ29uY3JldGVHbG9iYWxCbG9jawogICAgaW50IGZsYWdzOwogICAgaW50IHJlc2VydmVkOyAKICAgIHZvaWQgKCppbnZva2UpKHZvaWQgKiwgLi4uKTsKICAgIHN0cnVjdCBCbG9ja19kZXNjcmlwdG9yXzEgewoJdW5zaWduZWQgbG9uZyBpbnQgcmVzZXJ2ZWQ7CS8vIE5VTEwKICAgIAl1bnNpZ25lZCBsb25nIGludCBzaXplOyAgLy8gc2l6ZW9mKHN0cnVjdCBCbG9ja19saXRlcmFsXzEpCgkvLyBvcHRpb25hbCBoZWxwZXIgZnVuY3Rpb25zCiAgICAJdm9pZCAoKmNvcHlfaGVscGVyKSh2b2lkICpkc3QsIHZvaWQgKnNyYyk7CiAgICAJdm9pZCAoKmRpc3Bvc2VfaGVscGVyKSh2b2lkICpzcmMpOyAKICAgIH0gKmRlc2NyaXB0b3I7CiAgICAvLyBpbXBvcnRlZCB2YXJpYWJsZXMKfTsKClRoZSBmb2xsb3dpbmcgZmxhZ3MgYml0cyBhcmUgdXNlZCBieSB0aGUgY29tcGlsZXI6CgplbnVtIHsKICAgIEJMT0NLX0hBU19DT1BZX0RJU1BPU0UgPSAgKDEgPDwgMjUpLAogICAgQkxPQ0tfSEFTX0NUT1IgPSAgICAgICAgICAoMSA8PCAyNiksIC8vIGhlbHBlcnMgaGF2ZSBDKysgY29kZQogICAgQkxPQ0tfSVNfR0xPQkFMID0gICAgICAgICAoMSA8PCAyOCksCiAgICBCTE9DS19IQVNfREVTQ1JJUFRPUiA9ICAgICgxIDw8IDI5KSwgLy8gaW50ZXJpbSB1bnRpbCBjb21wbGV0ZSB3b3JsZCBidWlsZCBpcyBhY2NvbXBsaXNoZWQKfTsKCkJsb2NrIGxpdGVyYWxzIG1heSBvY2N1ciB3aXRoaW4gZnVuY3Rpb25zIHdoZXJlIHRoZSBzdHJ1Y3R1cmUgaXMgY3JlYXRlZCBpbiBzdGFjayBsb2NhbCBtZW1vcnkuICBUaGV5IG1heSBhbHNvIGFwcGVhciBhcyBpbml0aWFsaXphdGlvbiBleHByZXNzaW9ucyBmb3IgQmxvY2sgdmFyaWFibGVzIG9mIGdsb2JhbCBvciBzdGF0aWMgbG9jYWwgdmFyaWFibGVzLgoKV2hlbiBhIEJsb2NrIGxpdGVyYWwgZXhwcmVzc2lvbiBpcyBldmFsdWF0ZWQgdGhlIHN0YWNrIGJhc2VkIHN0cnVjdHVyZSBpcyBpbml0aWFsaXplZCBhcyBmb2xsb3dzOgoKMSkgc3RhdGljIGRlc2NyaXB0b3Igc3RydWN0dXJlIGlzIGRlY2xhcmVkIGFuZCBpbml0aWFsaXplZCBhcyBmb2xsb3dzOgoxYSkgdGhlIGludm9rZSBmdW5jdGlvbiBwb2ludGVyIGlzIHNldCB0byBhIGZ1bmN0aW9uIHRoYXQgdGFrZXMgdGhlIEJsb2NrIHN0cnVjdHVyZSBhcyBpdHMgZmlyc3QgYXJndW1lbnQgYW5kIHRoZSByZXN0IG9mIHRoZSBhcmd1bWVudHMgKGlmIGFueSkgdG8gdGhlIEJsb2NrIGFuZCBleGVjdXRlcyB0aGUgQmxvY2sgY29tcG91bmQgc3RhdGVtZW50LgoxYikgdGhlIHNpemUgZmllbGQgaXMgc2V0IHRvIHRoZSBzaXplIG9mIHRoZSBmb2xsb3dpbmcgQmxvY2sgbGl0ZXJhbCBzdHJ1Y3R1cmUuCjFjKSB0aGUgY29weV9oZWxwZXIgYW5kIGRpc3Bvc2VfaGVscGVyIGZ1bmN0aW9uIHBvaW50ZXJzIGFyZSBzZXQgdG8gcmVzcGVjdGl2ZSBoZWxwZXIgZnVuY3Rpb25zIGlmIHRoZXkgYXJlIHJlcXVpcmVkIGJ5IHRoZSBCbG9jayBsaXRlcmFsCjIpIGEgc3RhY2sgKG9yIGdsb2JhbCkgQmxvY2sgbGl0ZXJhbCBkYXRhIHN0cnVjdHVyZSBpcyBjcmVhdGVkIGFuZCBpbml0aWFsaXplZCBhcyBmb2xsb3dzOgoyYSkgdGhlIGlzYSBmaWVsZCBpcyBzZXQgdG8gdGhlIGFkZHJlc3Mgb2YgdGhlIGV4dGVybmFsIF9OU0NvbmNyZXRlU3RhY2tCbG9jaywgd2hpY2ggaXMgYSBibG9jayBvZiB1bmluaXRpYWxpemVkIG1lbW9yeSBzdXBwbGllZCBpbiBsaWJTeXN0ZW0sIG9yIF9OU0NvbmNyZXRlR2xvYmFsQmxvY2sgaWYgdGhpcyBpcyBhIHN0YXRpYyBvciBmaWxlIGxldmVsIGJsb2NrIGxpdGVyYWwuCjIpIFRoZSBmbGFncyBmaWVsZCBpcyBzZXQgdG8gemVybyB1bmxlc3MgdGhlcmUgYXJlIHZhcmlhYmxlcyBpbXBvcnRlZCBpbnRvIHRoZSBibG9jayB0aGF0IG5lZWQgaGVscGVyIGZ1bmN0aW9ucyBmb3IgcHJvZ3JhbSBsZXZlbCBCbG9ja19jb3B5KCkgYW5kIEJsb2NrX3JlbGVhc2UoKSBvcGVyYXRpb25zLCBpbiB3aGljaCBjYXNlIHRoZSAoMTw8MjUpIGZsYWdzIGJpdCBpcyBzZXQuCgpBcyBhbiBleGFtcGxlLCB0aGUgQmxvY2sgbGl0ZXJhbCBleHByZXNzaW9uCiAgIF4geyBwcmludGYoImhlbGxvIHdvcmxkXG4iKTsgfQp3b3VsZCBjYXVzZSB0byBiZSBjcmVhdGVkIG9uIGEgMzItYml0IHN5c3RlbToKCnN0cnVjdCBfX2Jsb2NrX2xpdGVyYWxfMSB7CiAgICB2b2lkICppc2E7CiAgICBpbnQgZmxhZ3M7CiAgICBpbnQgcmVzZXJ2ZWQ7IAogICAgdm9pZCAoKmludm9rZSkoc3RydWN0IF9fYmxvY2tfbGl0ZXJhbF8xICopOwogICAgc3RydWN0IF9fYmxvY2tfZGVzY3JpcHRvcl8xICpkZXNjcmlwdG9yOwp9OwoKdm9pZCBfX2Jsb2NrX2ludm9rZV8xKHN0cnVjdCBfX2Jsb2NrX2xpdGVyYWxfMSAqX2Jsb2NrKSB7CiAgICBwcmludGYoImhlbGxvIHdvcmxkXG4iKTsKfQoKc3RhdGljIHN0cnVjdCBfX2Jsb2NrX2Rlc2NyaXB0b3JfMSB7CiAgICB1bnNpZ25lZCBsb25nIGludCByZXNlcnZlZDsKICAgIHVuc2lnbmVkIGxvbmcgaW50IEJsb2NrX3NpemU7Cn0gX19ibG9ja19kZXNjcmlwdG9yXzEgPSB7IDAsIHNpemVvZihzdHJ1Y3QgX19ibG9ja19saXRlcmFsXzEpLCBfX2Jsb2NrX2ludm9rZV8xIH07CgphbmQgd2hlcmUgdGhlIGJsb2NrIGxpdGVyYWwgYXBwZWFyZWQKCiAgc3RydWN0IF9fYmxvY2tfbGl0ZXJhbF8xIF9ibG9ja19saXRlcmFsID0gewoJJl9OU0NvbmNyZXRlU3RhY2tCbG9jaywKCSgxPDwyOSksIDx1bmluaXRpYWxpemVkPiwKCV9fYmxvY2tfaW52b2tlXzEsCgkmX19ibG9ja19kZXNjcmlwdG9yXzEKICAgfTsKCkJsb2NrcyBpbXBvcnQgb3RoZXIgQmxvY2sgcmVmZXJlbmNlcywgY29uc3QgY29waWVzIG9mIG90aGVyIHZhcmlhYmxlcywgYW5kIHZhcmlhYmxlcyBtYXJrZWQgX19ibG9jay4gIEluIE9iamVjdGl2ZS1DIHZhcmlhYmxlcyBtYXkgYWRkaXRpb25hbGx5IGJlIG9iamVjdHMuCgpXaGVuIGEgQmxvY2sgbGl0ZXJhbCBleHByZXNzaW9uIHVzZWQgYXMgdGhlIGluaXRpYWwgdmFsdWUgb2YgYSBnbG9iYWwgb3Igc3RhdGljIGxvY2FsIHZhcmlhYmxlIGl0IGlzIGluaXRpYWxpemVkIGFzIGZvbGxvd3M6CiAgc3RydWN0IF9fYmxvY2tfbGl0ZXJhbF8xIF9fYmxvY2tfbGl0ZXJhbF8xID0gewoJJl9OU0NvbmNyZXRlR2xvYmFsQmxvY2ssCgkoMTw8MjgpfCgxPDwyOSksIDx1bmluaXRpYWxpemVkPiwKCV9fYmxvY2tfaW52b2tlXzEsCgkmX19ibG9ja19kZXNjcmlwdG9yXzEKICAgfTsKdGhhdCBpcywgYSBkaWZmZXJlbnQgYWRkcmVzcyBpcyBwcm92aWRlZCBhcyB0aGUgZmlyc3QgdmFsdWUgYW5kIGEgcGFydGljdWxhciAoMTw8MjgpIGJpdCBpcyBzZXQgaW4gdGhlIGZsYWdzIGZpZWxkLCBhbmQgb3RoZXJ3aXNlIGl0IGlzIHRoZSBzYW1lIGFzIGZvciBzdGFjayBiYXNlZCBCbG9jayBsaXRlcmFscy4gIFRoaXMgaXMgYW4gb3B0aW1pemF0aW9uIHRoYXQgY2FuIGJlIHVzZWQgZm9yIGFueSBCbG9jayBsaXRlcmFsIHRoYXQgaW1wb3J0cyBubyBjb25zdCBvciBfX2Jsb2NrIHN0b3JhZ2UgdmFyaWFibGVzLgoKCjIuIEltcG9ydGVkIFZhcmlhYmxlcwoKVmFyaWFibGVzIG9mICJhdXRvIiBzdG9yYWdlIGNsYXNzIGFyZSBpbXBvcnRlZCBhcyBjb25zdCBjb3BpZXMuICBWYXJpYWJsZXMgb2YgIl9fYmxvY2siIHN0b3JhZ2UgY2xhc3MgYXJlIGltcG9ydGVkIGFzIGEgcG9pbnRlciB0byBhbiBlbmNsb3NpbmcgZGF0YSBzdHJ1Y3R1cmUuICBHbG9iYWwgdmFyaWFibGVzIGFyZSBzaW1wbHkgcmVmZXJlbmNlZCBhbmQgbm90IGNvbnNpZGVyZWQgYXMgaW1wb3J0ZWQuCgoyLjEgSW1wb3J0ZWQgY29uc3QgY29weSB2YXJpYWJsZXMKCkF1dG9tYXRpYyBzdG9yYWdlIHZhcmlhYmxlcyBub3QgbWFya2VkIHdpdGggX19ibG9jayBhcmUgaW1wb3J0ZWQgYXMgY29uc3QgY29waWVzLgoKVGhlIHNpbXBsZXN0IGV4YW1wbGUgaXMgdGhhdCBvZiBpbXBvcnRpbmcgYSB2YXJpYWJsZSBvZiB0eXBlIGludC4KCiAgIGludCB4ID0gMTA7CiAgIHZvaWQgKF52dikodm9pZCkgPSBeeyBwcmludGYoInggaXMgJWRcbiIsIHgpOyB9CiAgIHggPSAxMTsKICAgdnYoKTsKCndvdWxkIGJlIGNvbXBpbGVkCgpzdHJ1Y3QgX19ibG9ja19saXRlcmFsXzIgewogICAgdm9pZCAqaXNhOwogICAgaW50IGZsYWdzOwogICAgaW50IHJlc2VydmVkOyAKICAgIHZvaWQgKCppbnZva2UpKHN0cnVjdCBfX2Jsb2NrX2xpdGVyYWxfMiAqKTsKICAgIHN0cnVjdCBfX2Jsb2NrX2Rlc2NyaXB0b3JfMiAqZGVzY3JpcHRvcjsKICAgIGNvbnN0IGludCB4Owp9OwoKdm9pZCBfX2Jsb2NrX2ludm9rZV8yKHN0cnVjdCBfX2Jsb2NrX2xpdGVyYWxfMiAqX2Jsb2NrKSB7CiAgICBwcmludGYoInggaXMgJWRcbiIsIF9ibG9jay0+eCk7Cn0KCnN0YXRpYyBzdHJ1Y3QgX19ibG9ja19kZXNjcmlwdG9yXzIgewogICAgdW5zaWduZWQgbG9uZyBpbnQgcmVzZXJ2ZWQ7CiAgICB1bnNpZ25lZCBsb25nIGludCBCbG9ja19zaXplOwp9IF9fYmxvY2tfZGVzY3JpcHRvcl8yID0geyAwLCBzaXplb2Yoc3RydWN0IF9fYmxvY2tfbGl0ZXJhbF8yKSB9OwoKYW5kCgogIHN0cnVjdCBfX2Jsb2NrX2xpdGVyYWxfMiBfX2Jsb2NrX2xpdGVyYWxfMiA9IHsKCSZfTlNDb25jcmV0ZVN0YWNrQmxvY2ssCgkoMTw8MjkpLCA8dW5pbml0aWFsaXplZD4sCglfX2Jsb2NrX2ludm9rZV8yLAoJJl9fYmxvY2tfZGVzY3JpcHRvcl8yLAogICAgICAgIHgKICAgfTsKCkluIHN1bW1hcnksIHNjYWxhcnMsIHN0cnVjdHVyZXMsIHVuaW9ucywgYW5kIGZ1bmN0aW9uIHBvaW50ZXJzIGFyZSBnZW5lcmFsbHkgaW1wb3J0ZWQgYXMgY29uc3QgY29waWVzIHdpdGggbm8gbmVlZCBmb3IgaGVscGVyIGZ1bmN0aW9ucy4KCjIuMiBJbXBvcnRlZCBjb25zdCBjb3B5IG9mIEJsb2NrIHJlZmVyZW5jZQoKVGhlIGZpcnN0IGNhc2Ugd2hlcmUgY29weSBhbmQgZGlzcG9zZSBoZWxwZXIgZnVuY3Rpb25zIGFyZSByZXF1aXJlZCBpcyBmb3IgdGhlIGNhc2Ugb2Ygd2hlbiBhIGJsb2NrIGl0c2VsZiBpcyBpbXBvcnRlZC4gIEluIHRoaXMgY2FzZSBib3RoIGEgY29weV9oZWxwZXIgZnVuY3Rpb24gYW5kIGEgZGlzcG9zZV9oZWxwZXIgZnVuY3Rpb24gYXJlIG5lZWRlZC4gIFRoZSBjb3B5X2hlbHBlciBmdW5jdGlvbiBpcyBwYXNzZWQgYm90aCB0aGUgZXhpc3Rpbmcgc3RhY2sgYmFzZWQgcG9pbnRlciBhbmQgdGhlIHBvaW50ZXIgdG8gdGhlIG5ldyBoZWFwIHZlcnNpb24gYW5kIHNob3VsZCBjYWxsIGJhY2sgaW50byB0aGUgcnVudGltZSB0byBhY3R1YWxseSBkbyB0aGUgY29weSBvcGVyYXRpb24gb24gdGhlIGltcG9ydGVkIGZpZWxkcyB3aXRoaW4gdGhlIGJsb2NrLiAgVGhlIHJ1bnRpbWUgZnVuY3Rpb25zIGFyZSBhbGwgZGVzY3JpYmVkIGluIFNlY3Rpb24gNS4wIFJ1bnRpbWUgSGVscGVyIEZ1bmN0aW9ucy4KCkFuIGV4YW1wbGU6CgogICB2b2lkICheZXhpc3RpbmdCbG9jaykodm9pZCkgPSAuLi47CiAgIHZvaWQgKF52dikodm9pZCkgPSBeeyBleGlzdGluZ0Jsb2NrKCk7IH0KICAgdnYoKTsKCnN0cnVjdCBfX2Jsb2NrX2xpdGVyYWxfMyB7CiAgIC4uLjsgLy8gZXhpc3RpbmcgYmxvY2sKfTsKCnN0cnVjdCBfX2Jsb2NrX2xpdGVyYWxfNCB7CiAgICB2b2lkICppc2E7CiAgICBpbnQgZmxhZ3M7CiAgICBpbnQgcmVzZXJ2ZWQ7IAogICAgdm9pZCAoKmludm9rZSkoc3RydWN0IF9fYmxvY2tfbGl0ZXJhbF80ICopOwogICAgc3RydWN0IF9fYmxvY2tfbGl0ZXJhbF8zICpjb25zdCBleGlzdGluZ0Jsb2NrOwp9OwoKdm9pZCBfX2Jsb2NrX2ludm9rZV80KHN0cnVjdCBfX2Jsb2NrX2xpdGVyYWxfMiAqX2Jsb2NrKSB7CiAgIF9fYmxvY2stPmV4aXN0aW5nQmxvY2stPmludm9rZShfX2Jsb2NrLT5leGlzdGluZ0Jsb2NrKTsKfQoKdm9pZCBfX2Jsb2NrX2NvcHlfNChzdHJ1Y3QgX19ibG9ja19saXRlcmFsXzQgKmRzdCwgc3RydWN0IF9fYmxvY2tfbGl0ZXJhbF80ICpzcmMpIHsKICAgICAvL19CbG9ja19jb3B5X2Fzc2lnbigmZHN0LT5leGlzdGluZ0Jsb2NrLCBzcmMtPmV4aXN0aW5nQmxvY2ssIDApOwogICAgIF9CbG9ja19vYmplY3RfYXNzaWduKCZkc3QtPmV4aXN0aW5nQmxvY2ssIHNyYy0+ZXhpc3RpbmdCbG9jaywgQkxPQ0tfRklFTERfSVNfQkxPQ0spOwp9Cgp2b2lkIF9fYmxvY2tfZGlzcG9zZV80KHN0cnVjdCBfX2Jsb2NrX2xpdGVyYWxfNCAqc3JjKSB7CiAgICAgLy8gd2FzIF9CbG9ja19kZXN0cm95CiAgICAgX0Jsb2NrX29iamVjdF9kaXNwb3NlKHNyYy0+ZXhpc3RpbmdCbG9jaywgQkxPQ0tfRklFTERfSVNfQkxPQ0spOwp9CgpzdGF0aWMgc3RydWN0IF9fYmxvY2tfZGVzY3JpcHRvcl80IHsKICAgIHVuc2lnbmVkIGxvbmcgaW50IHJlc2VydmVkOwogICAgdW5zaWduZWQgbG9uZyBpbnQgQmxvY2tfc2l6ZTsKICAgIHZvaWQgKCpjb3B5X2hlbHBlcikoc3RydWN0IF9fYmxvY2tfbGl0ZXJhbF80ICpkc3QsIHN0cnVjdCBfX2Jsb2NrX2xpdGVyYWxfNCAqc3JjKTsKICAgIHZvaWQgKCpkaXNwb3NlX2hlbHBlcikoc3RydWN0IF9fYmxvY2tfbGl0ZXJhbF80ICopOwp9IF9fYmxvY2tfZGVzY3JpcHRvcl80ID0gewoJMCwKCXNpemVvZihzdHJ1Y3QgX19ibG9ja19saXRlcmFsXzQpLAoJX19ibG9ja19jb3B5XzQsCglfX2Jsb2NrX2Rpc3Bvc2VfNCwKfTsKCmFuZCB3aGVyZSBpdCBpcyB1c2VkCgogIHN0cnVjdCBfX2Jsb2NrX2xpdGVyYWxfNCBfYmxvY2tfbGl0ZXJhbCA9IHsKCSZfTlNDb25jcmV0ZVN0YWNrQmxvY2ssCgkoMTw8MjUpfCgxPDwyOSksIDx1bmluaXRpYWxpemVkPgoJX19ibG9ja19pbnZva2VfNCwKCSYgX19ibG9ja19kZXNjcmlwdG9yXzQKICAgICAgICBleGlzdGluZ0Jsb2NrLAogICB9OwoKMi4yLjEgSW1wb3J0aW5nIF9fYXR0cmlidXRlX18oKE5TT2JqZWN0KSkgdmFyaWFibGVzLgoKR0NDIGludHJvZHVjZXMgX19hdHRyaWJ1dGVfXygoTlNPYmplY3QpKSBvbiBzdHJ1Y3R1cmUgcG9pbnRlcnMgdG8gbWVhbiAidGhpcyBpcyBhbiBvYmplY3QiLiAgVGhpcyBpcyB1c2VmdWwgYmVjYXVzZSBtYW55IGxvdyBsZXZlbCBkYXRhIHN0cnVjdHVyZXMgYXJlIGRlY2xhcmVkIGFzIG9wYXF1ZSBzdHJ1Y3R1cmUgcG9pbnRlcnMsIGUuZy4gQ0ZTdHJpbmdSZWYsIENGQXJyYXlSZWYsIGV0Yy4gIFdoZW4gdXNlZCBmcm9tIEMsIGhvd2V2ZXIsIHRoZXNlIGFyZSBzdGlsbCByZWFsbHkgb2JqZWN0cyBhbmQgYXJlIHRoZSBzZWNvbmQgY2FzZSB3aGVyZSB0aGF0IHJlcXVpcmVzIGNvcHkgYW5kIGRpc3Bvc2UgaGVscGVyIGZ1bmN0aW9ucyB0byBiZSBnZW5lcmF0ZWQuICBUaGUgY29weSBoZWxwZXIgZnVuY3Rpb25zIGdlbmVyYXRlZCBieSB0aGUgY29tcGlsZXIgc2hvdWxkIHVzZSB0aGUgX0Jsb2NrX29iamVjdF9hc3NpZ24gcnVudGltZSBoZWxwZXIgZnVuY3Rpb24gYW5kIGluIHRoZSBkaXNwb3NlIGhlbHBlciB0aGUgX0Jsb2NrX29iamVjdF9kaXNwb3NlIHJ1bnRpbWUgaGVscGVyIGZ1bmN0aW9uIHNob3VsZCBiZSBjYWxsZWQuCgpGb3IgZXhhbXBsZSwgYmxvY2sgeHl6enkgaW4gdGhlIGZvbGxvd2luZwoKICAgIHN0cnVjdCBPcGFxdWUgKl9fYXR0cmlidXRlX18oKE5TT2JqZWN0KSkgb2JqZWN0UG9pbnRlciA9IC4uLjsKICAgIC4uLgogICAgdm9pZCAoXnh5enp5KSh2b2lkKSA9IF57ICBDRlByaW50KG9iamVjdFBvaW50ZXIpOyB9OwoKd291bGQgaGF2ZSBoZWxwZXIgZnVuY3Rpb25zCgp2b2lkIF9fYmxvY2tfY29weV94eXp6eShzdHJ1Y3QgX19ibG9ja19saXRlcmFsXzUgKmRzdCwgc3RydWN0IF9fYmxvY2tfbGl0ZXJhbF81ICpzcmMpIHsKICAgICBfQmxvY2tfb2JqZWN0X2Fzc2lnbigmZHN0LT5vYmplY3RQb2ludGVyLCBzcmMtPiBvYmplY3RQb2ludGVyLCBCTE9DS19GSUVMRF9JU19PQkpFQ1QpOwp9Cgp2b2lkIF9fYmxvY2tfZGlzcG9zZV94eXp6eShzdHJ1Y3QgX19ibG9ja19saXRlcmFsXzUgKnNyYykgewogICAgIF9CbG9ja19vYmplY3RfZGlzcG9zZShzcmMtPm9iamVjdFBvaW50ZXIsIEJMT0NLX0ZJRUxEX0lTX09CSkVDVCk7Cn0KCmdlbmVyYXRlZC4KCgoyLjMgSW1wb3J0ZWQgX19ibG9jayBtYXJrZWQgdmFyaWFibGVzLgoKMi4zLjEgTGF5b3V0IG9mIF9fYmxvY2sgbWFya2VkIHZhcmlhYmxlcwoKVGhlIGNvbXBpbGVyIG11c3QgZW1iZWQgdmFyaWFibGVzIHRoYXQgYXJlIG1hcmtlZCBfX2Jsb2NrIGluIGEgc3BlY2lhbGl6ZWQgc3RydWN0dXJlIG9mIHRoZSBmb3JtOgoKc3RydWN0IF9ibG9ja19ieXJlZl94eHh4IHsKICAgIHZvaWQgKmlzYTsKICAgIHN0cnVjdCBCbG9ja19ieXJlZiAqZm9yd2FyZGluZzsKICAgIGludCBmbGFnczsgICAvL3JlZmNvdW50OwogICAgaW50IHNpemU7CiAgICB0eXBlb2YobWFya2VkX3ZhcmlhYmxlKSBtYXJrZWRfdmFyaWFibGU7Cn07CgpWYXJpYWJsZXMgb2YgY2VydGFpbiB0eXBlcyByZXF1aXJlIGhlbHBlciBmdW5jdGlvbnMgZm9yIHdoZW4gQmxvY2tfY29weSgpIGFuZCBCbG9ja19yZWxlYXNlKCkgYXJlIHBlcmZvcm1lZCB1cG9uIGEgcmVmZXJlbmNpbmcgQmxvY2suICBBdCB0aGUgIkMiIGxldmVsIG9ubHkgdmFyaWFibGVzIHRoYXQgYXJlIG9mIHR5cGUgQmxvY2sgb3Igb25lcyB0aGF0IGhhdmUgX19hdHRyaWJ1dGVfXygoTlNPYmplY3QpKSBtYXJrZWQgcmVxdWlyZSBoZWxwZXIgZnVuY3Rpb25zLiAgSW4gT2JqZWN0aXZlLUMgb2JqZWN0cyByZXF1aXJlIGhlbHBlciBmdW5jdGlvbnMgYW5kIGluIEMrKyBzdGFjayBiYXNlZCBvYmplY3RzIHJlcXVpcmUgaGVscGVyIGZ1bmN0aW9ucy4gVmFyaWFibGVzIHRoYXQgcmVxdWlyZSBoZWxwZXIgZnVuY3Rpb25zIHVzZSB0aGUgZm9ybToKCnN0cnVjdCBfYmxvY2tfYnlyZWZfeHh4eCB7CiAgICB2b2lkICppc2E7CiAgICBzdHJ1Y3QgX2Jsb2NrX2J5cmVmX3h4eHggKmZvcndhcmRpbmc7CiAgICBpbnQgZmxhZ3M7ICAgLy9yZWZjb3VudDsKICAgIGludCBzaXplOwogICAgLy8gaGVscGVyIGZ1bmN0aW9ucyBjYWxsZWQgdmlhIEJsb2NrX2NvcHkoKSBhbmQgQmxvY2tfcmVsZWFzZSgpCiAgICB2b2lkICgqYnlyZWZfa2VlcCkodm9pZCAgKmRzdCwgdm9pZCAqc3JjKTsKICAgIHZvaWQgKCpieXJlZl9kaXNwb3NlKSh2b2lkICopOwogICAgdHlwZW9mKG1hcmtlZF92YXJpYWJsZSkgbWFya2VkX3ZhcmlhYmxlOwp9OwoKVGhlIHN0cnVjdHVyZSBpcyBpbml0aWFsaXplZCBzdWNoIHRoYXQKIGEpIHRoZSBmb3J3YXJkaW5nIHBvaW50ZXIgaXMgc2V0IHRvIHRoZSBiZWdpbm5pbmcgb2YgaXRzIGVuY2xvc2luZyBzdHJ1Y3R1cmUsCiBiKSB0aGUgc2l6ZSBmaWVsZCBpcyBpbml0aWFsaXplZCB0byB0aGUgdG90YWwgc2l6ZSBvZiB0aGUgZW5jbG9zaW5nIHN0cnVjdHVyZSwKIGMpIHRoZSBmbGFncyBmaWVsZCBpcyBzZXQgdG8gZWl0aGVyIDAgaWYgbm8gaGVscGVyIGZ1bmN0aW9ucyBhcmUgbmVlZGVkIG9yICgxPDwyNSkgaWYgdGhleSBhcmUsCiBkKSB0aGUgaGVscGVyIGZ1bmN0aW9ucyBhcmUgaW5pdGlhbGl6ZWQgKGlmIHByZXNlbnQpCiBlKSB0aGUgdmFyaWFibGUgaXRzZWxmIGlzIHNldCB0byBpdHMgaW5pdGlhbCB2YWx1ZS4KIGYpIHRoZSBpc2EgZmllbGQgaXMgc2V0IHRvIE5VTEwKCjIuMy4yIEFjY2VzcyB0byBfX2Jsb2NrIHZhcmlhYmxlcyBmcm9tIHdpdGhpbiBpdHMgbGV4aWNhbCBzY29wZS4KCkluIG9yZGVyIHRvICJtb3ZlIiB0aGUgdmFyaWFibGUgdG8gdGhlIGhlYXAgdXBvbiBhIGNvcHlfaGVscGVyIG9wZXJhdGlvbiB0aGUgY29tcGlsZXIgbXVzdCByZXdyaXRlIGFjY2VzcyB0byBzdWNoIGEgdmFyaWFibGUgdG8gYmUgaW5kaXJlY3QgdGhyb3VnaCB0aGUgc3RydWN0dXJlcyBmb3J3YXJkaW5nIHBvaW50ZXIuICBGb3IgZXhhbXBsZToKCiAgaW50IF9fYmxvY2sgaSA9IDEwOwogIGkgPSAxMTsKCndvdWxkIGJlIHJld3JpdHRlbiB0byBiZToKCiAgc3RydWN0IF9ibG9ja19ieXJlZl9pIHsKICAgIHZvaWQgKmlzYTsKICAgIHN0cnVjdCBfYmxvY2tfYnlyZWZfaSAqZm9yd2FyZGluZzsKICAgIGludCBmbGFnczsgICAvL3JlZmNvdW50OwogICAgaW50IHNpemU7CiAgICBpbnQgY2FwdHVyZWRfaTsKICB9IGkgPSB7IE5VTEwsICZpLCAwLCBzaXplb2Yoc3RydWN0IF9ibG9ja19ieXJlZl9pKSwgMTE7CgogIGkuZm9yd2FyZGluZy0+Y2FwdHVyZWRfaSA9IDExOwoKSW4gdGhlIGNhc2Ugb2YgYSBCbG9jayByZWZlcmVuY2UgdmFyaWFibGUgYmVpbmcgbWFya2VkIF9fYmxvY2sgdGhlIGhlbHBlciBjb2RlIGdlbmVyYXRlZCBtdXN0IHVzZSB0aGUgX0Jsb2NrX29iamVjdF9hc3NpZ24gYW5kIF9CbG9ja19vYmplY3RfZGlzcG9zZSByb3V0aW5lcyBzdXBwbGllZCBieSB0aGUgcnVudGltZSB0byBtYWtlIHRoZSBjb3BpZXMuICBGb3IgZXhhbXBsZToKCiAgIF9fYmxvY2sgdm9pZCAodm9pZEJsb2NrKSh2b2lkKSA9IGJsb2NrQTsKICAgdm9pZEJsb2NrID0gYmxvY2tCOwoKd291bGQgdHJhbnNsYXRlIGludG8KCnN0cnVjdCBfYmxvY2tfYnlyZWZfdm9pZEJsb2NrIHsKICAgIHZvaWQgKmlzYTsKICAgIHN0cnVjdCBfYmxvY2tfYnlyZWZfdm9pZEJsb2NrICpmb3J3YXJkaW5nOwogICAgaW50IGZsYWdzOyAgIC8vcmVmY291bnQ7CiAgICBpbnQgc2l6ZTsKICAgIHZvaWQgKCpieXJlZl9rZWVwKShzdHJ1Y3QgX2Jsb2NrX2J5cmVmX3ZvaWRCbG9jayAqZHN0LCBzdHJ1Y3QgX2Jsb2NrX2J5cmVmX3ZvaWRCbG9jayAqc3JjKTsKICAgIHZvaWQgKCpieXJlZl9kaXNwb3NlKShzdHJ1Y3QgX2Jsb2NrX2J5cmVmX3ZvaWRCbG9jayAqKTsKICAgIHZvaWQgKF5jYXB0dXJlZF92b2lkQmxvY2spKHZvaWQpOwp9OwoKdm9pZCBfYmxvY2tfYnlyZWZfa2VlcF9oZWxwZXIoc3RydWN0IF9ibG9ja19ieXJlZl92b2lkQmxvY2sgKmRzdCwgc3RydWN0IF9ibG9ja19ieXJlZl92b2lkQmxvY2sgKnNyYykgewogICAgLy9fQmxvY2tfY29weV9hc3NpZ24oJmRzdC0+Y2FwdHVyZWRfdm9pZEJsb2NrLCBzcmMtPmNhcHR1cmVkX3ZvaWRCbG9jaywgMCk7CiAgICBfQmxvY2tfb2JqZWN0X2Fzc2lnbigmZHN0LT5jYXB0dXJlZF92b2lkQmxvY2ssIHNyYy0+Y2FwdHVyZWRfdm9pZEJsb2NrLCBCTE9DS19GSUVMRF9JU19CTE9DSyB8IEJMT0NLX0JZUkVGX0NBTExFUik7Cn0KCnZvaWQgX2Jsb2NrX2J5cmVmX2Rpc3Bvc2VfaGVscGVyKHN0cnVjdCBfYmxvY2tfYnlyZWZfdm9pZEJsb2NrICpwYXJhbSkgewogICAgLy9fQmxvY2tfZGVzdHJveShwYXJhbS0+Y2FwdHVyZWRfdm9pZEJsb2NrLCAwKTsKICAgIF9CbG9ja19vYmplY3RfZGlzcG9zZShwYXJhbS0+Y2FwdHVyZWRfdm9pZEJsb2NrLCBCTE9DS19GSUVMRF9JU19CTE9DSyB8IEJMT0NLX0JZUkVGX0NBTExFUil9CgphbmQKICBzdHJ1Y3QgX2Jsb2NrX2J5cmVmX3ZvaWRCbG9jayB2b2lkQmxvY2sgPSB7KCAuZm9yd2FyZGluZz0mdm9pZEJsb2NrLCAuZmxhZ3M9KDE8PDI1KSwgLnNpemU9c2l6ZW9mKHN0cnVjdCBfYmxvY2tfYnlyZWZfdm9pZEJsb2NrICopLAogICAgICAuYnlyZWZfa2VlcD1fYmxvY2tfYnlyZWZfa2VlcF9oZWxwZXIsIC5ieXJlZl9kaXNwb3NlPV9ibG9ja19ieXJlZl9kaXNwb3NlX2hlbHBlciwKICAgICAgLmNhcHR1cmVkX3ZvaWRCbG9jaz1ibG9ja0EgfTsKCiAgdm9pZEJsb2NrLmZvcndhcmRpbmctPmNhcHR1cmVkX3ZvaWRCbG9jayA9IGJsb2NrQjsKICAKCjIuMy4zIEltcG9ydGluZyBfX2Jsb2NrIHZhcmlhYmxlcyBpbnRvIEJsb2NrcwoKQSBCbG9jayB0aGF0IHVzZXMgYSBfX2Jsb2NrIHZhcmlhYmxlIGluIGl0cyBjb21wb3VuZCBzdGF0ZW1lbnQgYm9keSBtdXN0IGltcG9ydCB0aGUgdmFyaWFibGUgYW5kIGVtaXQgY29weV9oZWxwZXIgYW5kIGRpc3Bvc2VfaGVscGVyIGhlbHBlciBmdW5jdGlvbnMgdGhhdCwgaW4gdHVybiwgY2FsbCBiYWNrIGludG8gdGhlIHJ1bnRpbWUgdG8gYWN0dWFsbHkgY29weSBvciByZWxlYXNlIHRoZSBieXJlZiBkYXRhIGJsb2NrIHVzaW5nIHRoZSBmdW5jdGlvbnMgX0Jsb2NrX29iamVjdF9hc3NpZ24gYW5kIF9CbG9ja19vYmplY3RfZGlzcG9zZS4KCkZvciBleGFtcGxlOgoKICAgaW50IF9fYmxvY2sgaSA9IDI7CiAgIGZ1bmN0aW9uY2FsbCheeyBpID0gMTA7IH0pOwoKd291bGQgdHJhbnNsYXRlIHRvCgpzdHJ1Y3QgX2Jsb2NrX2J5cmVmX2kgewogICAgdm9pZCAqaXNhOyAgLy8gc2V0IHRvIE5VTEwKICAgIHN0cnVjdCBfYmxvY2tfYnlyZWZfdm9pZEJsb2NrICpmb3J3YXJkaW5nOwogICAgaW50IGZsYWdzOyAgIC8vcmVmY291bnQ7CiAgICBpbnQgc2l6ZTsKICAgIHZvaWQgKCpieXJlZl9rZWVwKShzdHJ1Y3QgX2Jsb2NrX2J5cmVmX2kgKmRzdCwgc3RydWN0IF9ibG9ja19ieXJlZl9pICpzcmMpOwogICAgdm9pZCAoKmJ5cmVmX2Rpc3Bvc2UpKHN0cnVjdCBfYmxvY2tfYnlyZWZfaSAqKTsKICAgIGludCBjYXB0dXJlZF9pOwp9OwoKCnN0cnVjdCBfX2Jsb2NrX2xpdGVyYWxfNSB7CiAgICB2b2lkICppc2E7CiAgICBpbnQgZmxhZ3M7CiAgICBpbnQgcmVzZXJ2ZWQ7IAogICAgdm9pZCAoKmludm9rZSkoc3RydWN0IF9fYmxvY2tfbGl0ZXJhbF81ICopOwogICAgc3RydWN0IF9fYmxvY2tfZGVzY3JpcHRvcl81ICpkZXNjcmlwdG9yOwogICAgc3RydWN0IF9ibG9ja19ieXJlZl9pICppX2hvbGRlcjsKfTsKCnZvaWQgX19ibG9ja19pbnZva2VfNShzdHJ1Y3QgX19ibG9ja19saXRlcmFsXzUgKl9ibG9jaykgewogICBfYmxvY2stPmZvcndhcmRpbmctPmNhcHR1cmVkX2kgPSAxMDsKfQoKdm9pZCBfX2Jsb2NrX2NvcHlfNShzdHJ1Y3QgX19ibG9ja19saXRlcmFsXzUgKmRzdCwgc3RydWN0IF9fYmxvY2tfbGl0ZXJhbF81ICpzcmMpIHsKICAgICAvL19CbG9ja19ieXJlZl9hc3NpZ25fY29weSgmZHN0LT5jYXB0dXJlZF9pLCBzcmMtPmNhcHR1cmVkX2kpOwogICAgIF9CbG9ja19vYmplY3RfYXNzaWduKCZkc3QtPmNhcHR1cmVkX2ksIHNyYy0+Y2FwdHVyZWRfaSwgQkxPQ0tfRklFTERfSVNfQllSRUYgfCBCTE9DS19CWVJFRl9DQUxMRVIpOwp9Cgp2b2lkIF9fYmxvY2tfZGlzcG9zZV81KHN0cnVjdCBfX2Jsb2NrX2xpdGVyYWxfNSAqc3JjKSB7CiAgICAgLy9fQmxvY2tfYnlyZWZfcmVsZWFzZShzcmMtPmNhcHR1cmVkX2kpOwogICAgIF9CbG9ja19vYmplY3RfZGlzcG9zZShzcmMtPmNhcHR1cmVkX2ksIEJMT0NLX0ZJRUxEX0lTX0JZUkVGIHwgQkxPQ0tfQllSRUZfQ0FMTEVSKTsKfQoKc3RhdGljIHN0cnVjdCBfX2Jsb2NrX2Rlc2NyaXB0b3JfNSB7CiAgICB1bnNpZ25lZCBsb25nIGludCByZXNlcnZlZDsKICAgIHVuc2lnbmVkIGxvbmcgaW50IEJsb2NrX3NpemU7CiAgICB2b2lkICgqY29weV9oZWxwZXIpKHN0cnVjdCBfX2Jsb2NrX2xpdGVyYWxfNSAqZHN0LCBzdHJ1Y3QgX19ibG9ja19saXRlcmFsXzUgKnNyYyk7CiAgICB2b2lkICgqZGlzcG9zZV9oZWxwZXIpKHN0cnVjdCBfX2Jsb2NrX2xpdGVyYWxfNSAqKTsKfSBfX2Jsb2NrX2Rlc2NyaXB0b3JfNSA9IHsgMCwgc2l6ZW9mKHN0cnVjdCBfX2Jsb2NrX2xpdGVyYWxfNSkgX19ibG9ja19jb3B5XzUsIF9fYmxvY2tfZGlzcG9zZV81IH07CgphbmQKCiAgc3RydWN0IF9ibG9ja19ieXJlZl9pIGkgPSB7KCAuZm9yd2FyZGluZz0maSwgLmZsYWdzPTAsIC5zaXplPXNpemVvZihzdHJ1Y3QgX2Jsb2NrX2J5cmVmX2kpICl9OwogIHN0cnVjdCBfX2Jsb2NrX2xpdGVyYWxfNSBfYmxvY2tfbGl0ZXJhbCA9IHsKCSZfTlNDb25jcmV0ZVN0YWNrQmxvY2ssCgkoMTw8MjUpfCgxPDwyOSksIDx1bmluaXRpYWxpemVkPiwKCV9fYmxvY2tfaW52b2tlXzUsCgkmX19ibG9ja19kZXNjcmlwdG9yXzUsCiAgICAgICAgMiwKICAgfTsKCjIuMy40IEltcG9ydGluZyBfX2F0dHJpYnV0ZV9fKChOU09iamVjdCkpIF9fYmxvY2sgdmFyaWFibGVzCgpBIF9fYmxvY2sgdmFyaWFibGUgdGhhdCBpcyBhbHNvIG1hcmtlZCBfX2F0dHJpYnV0ZV9fKChOU09iamVjdCkpIHNob3VsZCBoYXZlIGJ5cmVmX2tlZXAgYW5kIGJ5cmVmX2Rpc3Bvc2UgaGVscGVyIGZ1bmN0aW9ucyB0aGF0IHVzZSBfQmxvY2tfb2JqZWN0X2Fzc2lnbiBhbmQgX0Jsb2NrX29iamVjdF9kaXNwb3NlLgoKMi4zLjUgX19ibG9jayBlc2NhcGVzCgpCZWNhdXNlIEJsb2NrcyByZWZlcmVuY2luZyBfX2Jsb2NrIHZhcmlhYmxlcyBtYXkgaGF2ZSBCbG9ja19jb3B5KCkgcGVyZm9ybWVkIHVwb24gdGhlbSB0aGUgdW5kZXJseWluZyBzdG9yYWdlIGZvciB0aGUgdmFyaWFibGVzIG1heSBtb3ZlIHRvIHRoZSBoZWFwLiAgSW4gT2JqZWN0aXZlLUMgR2FyYmFnZSBDb2xsZWN0aW9uIE9ubHkgY29tcGlsYXRpb24gZW52aXJvbm1lbnRzIHRoZSBoZWFwIHVzZWQgaXMgdGhlIGdhcmJhZ2UgY29sbGVjdGVkIG9uZSBhbmQgbm8gZnVydGhlciBhY3Rpb24gaXMgcmVxdWlyZWQuICBPdGhlcndpc2UgdGhlIGNvbXBpbGVyIG11c3QgaXNzdWUgYSBjYWxsIHRvIHBvdGVudGlhbGx5IHJlbGVhc2UgYW55IGhlYXAgc3RvcmFnZSBmb3IgX19ibG9jayB2YXJpYWJsZXMgYXQgYWxsIGVzY2FwZXMgb3IgdGVybWluYXRpb25zIG9mIHRoZWlyIHNjb3BlLgoKCjIuMy42IE5lc3RpbmcKCkJsb2NrcyBtYXkgY29udGFpbiBCbG9jayBsaXRlcmFsIGV4cHJlc3Npb25zLiAgQW55IHZhcmlhYmxlcyB1c2VkIHdpdGhpbiBpbm5lciBibG9ja3MgYXJlIGltcG9ydGVkIGludG8gYWxsIGVuY2xvc2luZyBCbG9jayBzY29wZXMgZXZlbiBpZiB0aGUgdmFyaWFibGVzIGFyZSBub3QgdXNlZC4gIFRoaXMgaW5jbHVkZXMgY29uc3QgaW1wb3J0cyBhcyB3ZWxsIGFzIF9fYmxvY2sgdmFyaWFibGVzLgoKMy4gT2JqZWN0aXZlIEMgRXh0ZW5zaW9ucyB0byBCbG9ja3MKCjMuMSBJbXBvcnRpbmcgT2JqZWN0cwoKT2JqZWN0cyBzaG91bGQgYmUgdHJlYXRlZCBhcyBfX2F0dHJpYnV0ZV9fKChOU09iamVjdCkpIHZhcmlhYmxlczsgYWxsIGNvcHlfaGVscGVyLCBkaXNwb3NlX2hlbHBlciwgYnlyZWZfa2VlcCwgYW5kIGJ5cmVmX2Rpc3Bvc2UgaGVscGVyIGZ1bmN0aW9ucyBzaG91bGQgdXNlIF9CbG9ja19vYmplY3RfYXNzaWduIGFuZCBfQmxvY2tfb2JqZWN0X2Rpc3Bvc2UuICBUaGVyZSBzaG91bGQgYmUgbm8gY29kZSBnZW5lcmF0ZWQgdGhhdCB1c2VzIC1yZXRhaW4gb3IgLXJlbGVhc2UgbWV0aG9kcy4KCgozLjIgQmxvY2tzIGFzIE9iamVjdHMKClRoZSBjb21waWxlciB3aWxsIHRyZWF0IEJsb2NrcyBhcyBvYmplY3RzIHdoZW4gc3ludGhlc2l6aW5nIHByb3BlcnR5IHNldHRlcnMgYW5kIGdldHRlcnMsIHdpbGwgY2hhcmFjdGVyaXplIHRoZW0gYXMgb2JqZWN0cyB3aGVuIGdlbmVyYXRpbmcgZ2FyYmFnZSBjb2xsZWN0aW9uIHN0cm9uZyBhbmQgd2VhayBsYXlvdXQgaW5mb3JtYXRpb24gaW4gdGhlIHNhbWUgbWFubmVyIGFzIG9iamVjdHMsIGFuZCB3aWxsIGlzc3VlIHN0cm9uZyBhbmQgd2VhayB3cml0ZS1iYXJyaWVyIGFzc2lnbm1lbnRzIGluIHRoZSBzYW1lIG1hbm5lciBhcyBvYmplY3RzLgoKMy4zIF9fd2VhayBfX2Jsb2NrIFN1cHBvcnQKCk9iamVjdGl2ZS1DIChhbmQgT2JqZWN0aXZlLUMrKykgc3VwcG9ydCB0aGUgX193ZWFrIGF0dHJpYnV0ZSBvbiBfX2Jsb2NrIHZhcmlhYmxlcy4gIFVuZGVyIG5vcm1hbCBjaXJjdW1zdGFuY2VzIHRoZSBjb21waWxlciB1c2VzIHRoZSBPYmplY3RpdmUtQyBydW50aW1lIGhlbHBlciBzdXBwb3J0IGZ1bmN0aW9ucyBvYmpjX2Fzc2lnbl93ZWFrIGFuZCBvYmpjX3JlYWRfd2Vhay4gIEJvdGggc2hvdWxkIGNvbnRpbnVlIHRvIGJlIHVzZWQgZm9yIGFsbCByZWFkcyBhbmQgd3JpdGVzIG9mIF9fd2VhayBfX2Jsb2NrIHZhcmlhYmxlczoKCW9iamNfcmVhZF93ZWFrKCZibG9jay0+YnlyZWZfaS0+Zm9yd2FyZGluZy0+aSkKClRoZSBfX3dlYWsgdmFyaWFibGUgaXMgc3RvcmVkIGluIGEgX2Jsb2NrX2J5cmVmX3h4eHggc3RydWN0dXJlIGFuZCB0aGUgQmxvY2sgaGFzIGNvcHkgYW5kIGRpc3Bvc2UgaGVscGVycyBmb3IgdGhpcyBzdHJ1Y3R1cmUgdGhhdCBjYWxsOgoJX0Jsb2NrX29iamVjdF9hc3NpZ24oJmRlc3QtPl9ibG9ja19ieXJlZl9pLCBzcmMtPiBfYmxvY2tfYnlyZWZfaSwgQkxPQ0tfRklFTERfSVNfV0VBSyB8IEJMT0NLX0ZJRUxEX0lTX0JZUkVGKTsKYW5kCglfQmxvY2tfb2JqZWN0X2Rpc3Bvc2Uoc3JjLT5fYmxvY2tfYnlyZWZfaSwgQkxPQ0tfRklFTERfSVNfV0VBSyB8IEJMT0NLX0ZJRUxEX0lTX0JZUkVGKTsKCgpJbiB0dXJuLCB0aGUgYmxvY2tfYnlyZWYgY29weSBzdXBwb3J0IGhlbHBlcnMgZGlzdGluZ3Vpc2ggYmV0d2VlbiB3aGV0aGVyIHRoZSBfX2Jsb2NrIHZhcmlhYmxlIGlzIGEgQmxvY2sgb3Igbm90IGFuZCBzaG91bGQgZWl0aGVyIGNhbGw6CglfQmxvY2tfb2JqZWN0X2Fzc2lnbigmZGVzdC0+X2Jsb2NrX2J5cmVmX2ksIHNyYy0+X2Jsb2NrX2J5cmVmX2ksIEJMT0NLX0ZJRUxEX0lTX1dFQUsgfCBCTE9DS19GSUVMRF9JU19PQkpFQ1QgfCBCTE9DS19CWVJFRl9DQUxMRVIpOwpmb3Igc29tZXRoaW5nIGRlY2xhcmVkIGFzIGFuIG9iamVjdCBvcgoJX0Jsb2NrX29iamVjdF9hc3NpZ24oJmRlc3QtPl9ibG9ja19ieXJlZl9pLCBzcmMtPl9ibG9ja19ieXJlZl9pLCBCTE9DS19GSUVMRF9JU19XRUFLIHwgQkxPQ0tfRklFTERfSVNfQkxPQ0sgfCBCTE9DS19CWVJFRl9DQUxMRVIpOwpmb3Igc29tZXRoaW5nIGRlY2xhcmVkIGFzIGEgQmxvY2suCgpBIGZ1bGwgZXhhbXBsZSBmb2xsb3dzOgoKCiAgIF9fYmxvY2sgX193ZWFrIGlkIG9iaiA9IDxpbml0aWFsaXphdGlvbiBleHByZXNzaW9uPjsKICAgZnVuY3Rpb25jYWxsKF57IFtvYmogc29tZW1lc3NhZ2VdOyB9KTsKCndvdWxkIHRyYW5zbGF0ZSB0bwoKc3RydWN0IF9ibG9ja19ieXJlZl9vYmogewogICAgdm9pZCAqaXNhOyAgLy8gdW5pbml0aWFsaXplZAogICAgc3RydWN0IF9ibG9ja19ieXJlZl9vYmogKmZvcndhcmRpbmc7CiAgICBpbnQgZmxhZ3M7ICAgLy9yZWZjb3VudDsKICAgIGludCBzaXplOwogICAgdm9pZCAoKmJ5cmVmX2tlZXApKHN0cnVjdCBfYmxvY2tfYnlyZWZfaSAqZHN0LCBzdHJ1Y3QgX2Jsb2NrX2J5cmVmX2kgKnNyYyk7CiAgICB2b2lkICgqYnlyZWZfZGlzcG9zZSkoc3RydWN0IF9ibG9ja19ieXJlZl9pICopOwogICAgaW50IGNhcHR1cmVkX29iajsKfTsKCnZvaWQgX2Jsb2NrX2J5cmVmX29ial9rZWVwKHN0cnVjdCBfYmxvY2tfYnlyZWZfdm9pZEJsb2NrICpkc3QsIHN0cnVjdCBfYmxvY2tfYnlyZWZfdm9pZEJsb2NrICpzcmMpIHsKICAgIC8vX0Jsb2NrX2NvcHlfYXNzaWduKCZkc3QtPmNhcHR1cmVkX29iaiwgc3JjLT5jYXB0dXJlZF9vYmosIDApOwogICAgX0Jsb2NrX29iamVjdF9hc3NpZ24oJmRzdC0+Y2FwdHVyZWRfb2JqLCBzcmMtPmNhcHR1cmVkX29iaiwgQkxPQ0tfRklFTERfSVNfT0JKRUNUIHwgQkxPQ0tfRklFTERfSVNfV0VBSyB8IEJMT0NLX0JZUkVGX0NBTExFUik7Cn0KCnZvaWQgX2Jsb2NrX2J5cmVmX29ial9kaXNwb3NlKHN0cnVjdCBfYmxvY2tfYnlyZWZfdm9pZEJsb2NrICpwYXJhbSkgewogICAgLy9fQmxvY2tfZGVzdHJveShwYXJhbS0+Y2FwdHVyZWRfb2JqLCAwKTsKICAgIF9CbG9ja19vYmplY3RfZGlzcG9zZShwYXJhbS0+Y2FwdHVyZWRfb2JqLCBCTE9DS19GSUVMRF9JU19PQkpFQ1QgfCBCTE9DS19GSUVMRF9JU19XRUFLIHwgQkxPQ0tfQllSRUZfQ0FMTEVSKTsKfTsKCmZvciB0aGUgYmxvY2sgYnlyZWYgcGFydCBhbmQKCnN0cnVjdCBfX2Jsb2NrX2xpdGVyYWxfNSB7CiAgICB2b2lkICppc2E7CiAgICBpbnQgZmxhZ3M7CiAgICBpbnQgcmVzZXJ2ZWQ7IAogICAgdm9pZCAoKmludm9rZSkoc3RydWN0IF9fYmxvY2tfbGl0ZXJhbF81ICopOwogICAgc3RydWN0IF9fYmxvY2tfZGVzY3JpcHRvcl81ICpkZXNjcmlwdG9yOwogICAgc3RydWN0IF9ibG9ja19ieXJlZl9vYmogKmJ5cmVmX29iajsKfTsKCnZvaWQgX19ibG9ja19pbnZva2VfNShzdHJ1Y3QgX19ibG9ja19saXRlcmFsXzUgKl9ibG9jaykgewogICBbb2JqY19yZWFkX3dlYWsoJl9ibG9jay0+YnlyZWZfb2JqLT5mb3J3YXJkaW5nLT5jYXB0dXJlZF9vYmopIHNvbWVtZXNzYWdlXTsKfQoKdm9pZCBfX2Jsb2NrX2NvcHlfNShzdHJ1Y3QgX19ibG9ja19saXRlcmFsXzUgKmRzdCwgc3RydWN0IF9fYmxvY2tfbGl0ZXJhbF81ICpzcmMpIHsKICAgICAvL19CbG9ja19ieXJlZl9hc3NpZ25fY29weSgmZHN0LT5ieXJlZl9vYmosIHNyYy0+YnlyZWZfb2JqKTsKICAgICBfQmxvY2tfb2JqZWN0X2Fzc2lnbigmZHN0LT5ieXJlZl9vYmosIHNyYy0+YnlyZWZfb2JqLCBCTE9DS19GSUVMRF9JU19CWVJFRiB8IEJMT0NLX0ZJRUxEX0lTX1dFQUspOwp9Cgp2b2lkIF9fYmxvY2tfZGlzcG9zZV81KHN0cnVjdCBfX2Jsb2NrX2xpdGVyYWxfNSAqc3JjKSB7CiAgICAgLy9fQmxvY2tfYnlyZWZfcmVsZWFzZShzcmMtPmJ5cmVmX29iaik7CiAgICAgX0Jsb2NrX29iamVjdF9kaXNwb3NlKHNyYy0+YnlyZWZfb2JqLCBCTE9DS19GSUVMRF9JU19CWVJFRiB8IEJMT0NLX0ZJRUxEX0lTX1dFQUspOwp9CgpzdGF0aWMgc3RydWN0IF9fYmxvY2tfZGVzY3JpcHRvcl81IHsKICAgIHVuc2lnbmVkIGxvbmcgaW50IHJlc2VydmVkOwogICAgdW5zaWduZWQgbG9uZyBpbnQgQmxvY2tfc2l6ZTsKICAgIHZvaWQgKCpjb3B5X2hlbHBlcikoc3RydWN0IF9fYmxvY2tfbGl0ZXJhbF81ICpkc3QsIHN0cnVjdCBfX2Jsb2NrX2xpdGVyYWxfNSAqc3JjKTsKICAgIHZvaWQgKCpkaXNwb3NlX2hlbHBlcikoc3RydWN0IF9fYmxvY2tfbGl0ZXJhbF81ICopOwp9IF9fYmxvY2tfZGVzY3JpcHRvcl81ID0geyAwLCBzaXplb2Yoc3RydWN0IF9fYmxvY2tfbGl0ZXJhbF81KSwgX19ibG9ja19jb3B5XzUsIF9fYmxvY2tfZGlzcG9zZV81IH07CgphbmQgd2l0aGluIHRoZSBjb21wb3VuZCBzdGF0ZW1lbnQ6CgogIHN0cnVjdCBfYmxvY2tfYnlyZWZfb2JqIG9iaiA9IHsoIC5mb3J3YXJkaW5nPSZvYmosIC5mbGFncz0oMTw8MjUpLCAuc2l6ZT1zaXplb2Yoc3RydWN0IF9ibG9ja19ieXJlZl9vYmopLAoJCQkJLmJ5cmVmX2tlZXA9X2Jsb2NrX2J5cmVmX29ial9rZWVwLCAuYnlyZWZfZGlzcG9zZT1fYmxvY2tfYnlyZWZfb2JqX2Rpc3Bvc2UsCgkJCQkuY2FwdHVyZWRfb2JqID0gPGluaXRpYWxpemF0aW9uIGV4cHJlc3Npb24+ICl9OwoKICBzdHJ1Y3QgX19ibG9ja19saXRlcmFsXzUgX2Jsb2NrX2xpdGVyYWwgPSB7CgkmX05TQ29uY3JldGVTdGFja0Jsb2NrLAoJKDE8PDI1KXwoMTw8MjkpLCA8dW5pbml0aWFsaXplZD4sCglfX2Jsb2NrX2ludm9rZV81LAoJJl9fYmxvY2tfZGVzY3JpcHRvcl81LAogICAgICAgICZvYmosCQkvLyBhIHJlZmVyZW5jZSB0byB0aGUgb24tc3RhY2sgc3RydWN0dXJlIGNvbnRhaW5pbmcgImNhcHR1cmVkX29iaiIKICAgfTsKCgogICBmdW5jdGlvbmNhbGwoX2Jsb2NrX2xpdGVyYWwtPmludm9rZSgmX2Jsb2NrX2xpdGVyYWwpKTsKCgo0LjAgQysrIFN1cHBvcnQKCldpdGhpbiBhIGJsb2NrIHN0YWNrIGJhc2VkIEMrKyBvYmplY3RzIGFyZSBjb3BpZWQgYXMgY29uc3QgY29waWVzIHVzaW5nIHRoZSBjb25zdCBjb3B5IGNvbnN0cnVjdG9yLiAgSXQgaXMgYW4gZXJyb3IgaWYgYSBzdGFjayBiYXNlZCBDKysgb2JqZWN0IGlzIHVzZWQgd2l0aGluIGEgYmxvY2sgaWYgaXQgZG9lcyBub3QgaGF2ZSBhIGNvbnN0IGNvcHkgY29uc3RydWN0b3IuICBJbiBhZGRpdGlvbiBib3RoIGNvcHkgYW5kIGRlc3Ryb3kgaGVscGVyIHJvdXRpbmVzIG11c3QgYmUgc3ludGhlc2l6ZWQgZm9yIHRoZSBibG9jayB0byBzdXBwb3J0IHRoZSBCbG9ja19jb3B5KCkgb3BlcmF0aW9uLCBhbmQgdGhlIGZsYWdzIHdvcmsgbWFya2VkIHdpdGggdGhlICgxPDwyNikgYml0IGluIGFkZGl0aW9uIHRvIHRoZSAoMTw8MjUpIGJpdC4gIFRoZSBjb3B5IGhlbHBlciBzaG91bGQgY2FsbCB0aGUgY29uc3RydWN0b3IgdXNpbmcgYXBwcm9wcmlhdGUgb2Zmc2V0cyBvZiB0aGUgdmFyaWFibGUgd2l0aGluIHRoZSBzdXBwbGllZCBzdGFjayBiYXNlZCBibG9jayBzb3VyY2UgYW5kIGhlYXAgYmFzZWQgZGVzdGluYXRpb24gZm9yIGFsbCBjb25zdCBjb25zdHJ1Y3RlZCBjb3BpZXMsIGFuZCBzaW1pbGFybHkgc2hvdWxkIGNhbGwgdGhlIGRlc3RydWN0b3IgaW4gdGhlIGRlc3Ryb3kgcm91dGluZS4KCkFzIGFuIGV4YW1wbGUsIHN1cHBvc2UgYSBDKysgY2xhc3MgRk9PIGV4aXN0ZWQgd2l0aCBhIGNvbnN0IGNvcHkgY29uc3RydWN0b3IuICBXaXRoaW4gYSBjb2RlIGJsb2NrIGEgc3RhY2sgdmVyc2lvbiBvZiBhIEZPTyBvYmplY3QgaXMgZGVjbGFyZWQgYW5kIHVzZWQgd2l0aGluIGEgQmxvY2sgbGl0ZXJhbCBleHByZXNzaW9uOgoKewogICAgRk9PIGZvbzsKICAgIHZvaWQgKF5ibG9jaykodm9pZCkgPSBeeyBwcmludGYoIiVkXG4iLCBmb28udmFsdWUoKSk7IH07Cn0KClRoZSBjb21waWxlciB3b3VsZCBzeW50aGVzaXplCgpzdHJ1Y3QgX19ibG9ja19saXRlcmFsXzEwIHsKICAgIHZvaWQgKmlzYTsKICAgIGludCBmbGFnczsKICAgIGludCByZXNlcnZlZDsgCiAgICB2b2lkICgqaW52b2tlKShzdHJ1Y3QgX19ibG9ja19saXRlcmFsXzEwICopOwogICAgc3RydWN0IF9fYmxvY2tfZGVzY3JpcHRvcl8xMCAqZGVzY3JpcHRvcjsKICAgIGNvbnN0IEZPTyBmb287Cn07Cgp2b2lkIF9fYmxvY2tfaW52b2tlXzEwKHN0cnVjdCBfX2Jsb2NrX2xpdGVyYWxfMTAgKl9ibG9jaykgewogICBwcmludGYoIiVkXG4iLCBfYmxvY2stPmZvby52YWx1ZSgpKTsKfQoKdm9pZCBfX2Jsb2NrX2xpdGVyYWxfMTAoc3RydWN0IF9fYmxvY2tfbGl0ZXJhbF8xMCAqZHN0LCBzdHJ1Y3QgX19ibG9ja19saXRlcmFsXzEwICpzcmMpIHsKICAgICBjb21wX2N0b3IoJmRzdC0+Zm9vLCAmc3JjLT5mb28pOwp9Cgp2b2lkIF9fYmxvY2tfZGlzcG9zZV8xMChzdHJ1Y3QgX19ibG9ja19saXRlcmFsXzEwICpzcmMpIHsKICAgICBjb21wX2R0b3IoJnNyYy0+Zm9vKTsKfQoKc3RhdGljIHN0cnVjdCBfX2Jsb2NrX2Rlc2NyaXB0b3JfMTAgewogICAgdW5zaWduZWQgbG9uZyBpbnQgcmVzZXJ2ZWQ7CiAgICB1bnNpZ25lZCBsb25nIGludCBCbG9ja19zaXplOwogICAgdm9pZCAoKmNvcHlfaGVscGVyKShzdHJ1Y3QgX19ibG9ja19saXRlcmFsXzEwICpkc3QsIHN0cnVjdCBfX2Jsb2NrX2xpdGVyYWxfMTAgKnNyYyk7CiAgICB2b2lkICgqZGlzcG9zZV9oZWxwZXIpKHN0cnVjdCBfX2Jsb2NrX2xpdGVyYWxfMTAgKik7Cn0gX19ibG9ja19kZXNjcmlwdG9yXzEwID0geyAwLCBzaXplb2Yoc3RydWN0IF9fYmxvY2tfbGl0ZXJhbF8xMCksIF9fYmxvY2tfY29weV8xMCwgX19ibG9ja19kaXNwb3NlXzEwIH07CgphbmQgdGhlIGNvZGUgd291bGQgYmU6CnsKICBGT08gZm9vOwogIGNvbXBfY3RvcigmZm9vKTsgLy8gZGVmYXVsdCBjb25zdHJ1Y3RvcgogIHN0cnVjdCBfX2Jsb2NrX2xpdGVyYWxfMTAgX2Jsb2NrX2xpdGVyYWwgPSB7CgkmX05TQ29uY3JldGVTdGFja0Jsb2NrLAoJKDE8PDI1KXwoMTw8MjYpfCgxPDwyOSksIDx1bmluaXRpYWxpemVkPiwKCV9fYmxvY2tfaW52b2tlXzEwLAoJJl9fYmxvY2tfZGVzY3JpcHRvcl8xMCwKICAgfTsKICAgY29tcF9jdG9yKCZfYmxvY2tfbGl0ZXJhbC0+Zm9vLCAmZm9vKTsgIC8vIGNvbnN0IGNvcHkgaW50byBzdGFjayB2ZXJzaW9uCiAgIHN0cnVjdCBfX2Jsb2NrX2xpdGVyYWxfMTAgJmJsb2NrID0gJl9ibG9ja19saXRlcmFsOyAgLy8gYXNzaWduIGxpdGVyYWwgdG8gYmxvY2sgdmFyaWFibGUKICAgYmxvY2stPmludm9rZShibG9jayk7CS8vIGludm9rZSBibG9jawogICBjb21wX2R0b3IoJl9ibG9ja19saXRlcmFsLT5mb28pOyAvLyBkZXN0cm95IHN0YWNrIHZlcnNpb24gb2YgY29uc3QgYmxvY2sgY29weQogICBjb21wX2R0b3IoJmZvbyk7IC8vIGRlc3Ryb3kgb3JpZ2luYWwgdmVyc2lvbgp9CgoKQysrIG9iamVjdHMgc3RvcmVkIGluIF9fYmxvY2sgc3RvcmFnZSBzdGFydCBvdXQgb24gdGhlIHN0YWNrIGluIGEgYmxvY2tfYnlyZWYgZGF0YSBzdHJ1Y3R1cmUgYXMgZG8gb3RoZXIgdmFyaWFibGVzLiAgU3VjaCBvYmplY3RzIChpZiBub3QgY29uc3Qgb2JqZWN0cykgbXVzdCBzdXBwb3J0IGEgcmVndWxhciBjb3B5IGNvbnN0cnVjdG9yLiAgVGhlIGJsb2NrX2J5cmVmIGRhdGEgc3RydWN0dXJlIHdpbGwgaGF2ZSBjb3B5IGFuZCBkZXN0cm95IGhlbHBlciByb3V0aW5lcyBzeW50aGVzaXplZCBieSB0aGUgY29tcGlsZXIuICBUaGUgY29weSBoZWxwZXIgd2lsbCBoYXZlIGNvZGUgY3JlYXRlZCB0byBwZXJmb3JtIHRoZSBjb3B5IGNvbnN0cnVjdG9yIGJhc2VkIG9uIHRoZSBpbml0aWFsIHN0YWNrIGJsb2NrX2J5cmVmIGRhdGEgc3RydWN0dXJlLCBhbmQgd2lsbCBhbHNvIHNldCB0aGUgKDE8PDI2KSBiaXQgaW4gYWRkaXRpb24gdG8gdGhlICgxPDwyNSkgYml0LiAgVGhlIGRlc3Ryb3kgaGVscGVyIHdpbGwgaGF2ZSBjb2RlIHRvIGRvIHRoZSBkZXN0cnVjdG9yIG9uIHRoZSBvYmplY3Qgc3RvcmVkIHdpdGhpbiB0aGUgc3VwcGxpZWQgYmxvY2tfYnlyZWYgaGVhcCBkYXRhIHN0cnVjdHVyZS4KClRvIHN1cHBvcnQgbWVtYmVyIHZhcmlhYmxlIGFuZCBmdW5jdGlvbiBhY2Nlc3MgdGhlIGNvbXBpbGVyIHdpbGwgc3ludGhlc2l6ZSBhIGNvbnN0IHBvaW50ZXIgdG8gYSBibG9jayB2ZXJzaW9uIG9mIHRoZSB0aGlzIHBvaW50ZXIuCgo1LjAgUnVudGltZSBIZWxwZXIgRnVuY3Rpb25zCgpUaGUgcnVudGltZSBoZWxwZXIgZnVuY3Rpb25zIGFyZSBkZXNjcmliZWQgaW4gL3Vzci9sb2NhbC9pbmNsdWRlL0Jsb2NrX3ByaXZhdGUuaC4gIFRvIHN1bW1hcml6ZSB0aGVpciB1c2UsIGEgYmxvY2sgcmVxdWlyZXMgY29weS9kaXNwb3NlIGhlbHBlcnMgaWYgaXQgaW1wb3J0cyBhbnkgYmxvY2sgdmFyaWFibGVzLCBfX2Jsb2NrIHN0b3JhZ2UgdmFyaWFibGVzLCBfX2F0dHJpYnV0ZV9fKChOU09iamVjdCkpIHZhcmlhYmxlcywgb3IgQysrIGNvbnN0IGNvcGllZCBvYmplY3RzIHdpdGggY29uc3RydWN0b3IvZGVzdHJ1Y3RvcnMuICBUaGUgKDE8PDI2KSBiaXQgaXMgc2V0IGFuZCBmdW5jdGlvbnMgYXJlIGdlbmVyYXRlZC4KClRoZSBibG9jayBjb3B5IGhlbHBlciBmdW5jdGlvbiBzaG91bGQsIGZvciBlYWNoIG9mIHRoZSB2YXJpYWJsZXMgb2YgdGhlIHR5cGUgbWVudGlvbmVkIGFib3ZlLCBjYWxsCiAgICAgX0Jsb2NrX29iamVjdF9hc3NpZ24oJmRzdC0+dGFyZ2V0LCBzcmMtPnRhcmdldCwgQkxPQ0tfRklFTERfPGFwcHJvcG8+KTsKaW4gdGhlIGNvcHkgaGVscGVyIGFuZAogICAgX0Jsb2NrX29iamVjdF9kaXNwb3NlKC0+dGFyZ2V0LCBCTE9DS19GSUVMRF88YXBwcm9wbz4pOwppbiB0aGUgZGlzcG9zZSBoZWxwZXIgd2hlcmUKICAgICAgPGFwcHJvcG8+IGlzCgplbnVtIHsKICAgIEJMT0NLX0ZJRUxEX0lTX09CSkVDVCAgID0gIDMsICAvLyBpZCwgTlNPYmplY3QsIF9fYXR0cmlidXRlX18oKE5TT2JqZWN0KSksIGJsb2NrLCAuLi4KICAgIEJMT0NLX0ZJRUxEX0lTX0JMT0NLICAgID0gIDcsICAvLyBhIGJsb2NrIHZhcmlhYmxlCiAgICBCTE9DS19GSUVMRF9JU19CWVJFRiAgICA9ICA4LCAgLy8gdGhlIG9uIHN0YWNrIHN0cnVjdHVyZSBob2xkaW5nIHRoZSBfX2Jsb2NrIHZhcmlhYmxlCgogICAgQkxPQ0tfRklFTERfSVNfV0VBSyAgICAgPSAxNiwgIC8vIGRlY2xhcmVkIF9fd2VhawoKICAgIEJMT0NLX0JZUkVGX0NBTExFUiAgICAgID0gMTI4LCAvLyBjYWxsZWQgZnJvbSBieXJlZiBjb3B5L2Rpc3Bvc2UgaGVscGVycwp9OwoKYW5kIG9mIGNvdXJzZSB0aGUgQ1RPUnMvRFRPUnMgZm9yIGNvbnN0IGNvcGllZCBDKysgb2JqZWN0cy4KClRoZSBibG9ja19ieXJlZiBkYXRhIHN0cnVjdHVyZSBzaW1pbGFybHkgcmVxdWlyZXMgY29weS9kaXNwb3NlIGhlbHBlcnMgZm9yIGJsb2NrIHZhcmlhYmxlcywgX19hdHRyaWJ1dGVfXygoTlNPYmplY3QpKSB2YXJpYWJsZXMsIG9yIEMrKyBjb25zdCBjb3BpZWQgb2JqZWN0cyB3aXRoIGNvbnN0cnVjdG9yL2Rlc3RydWN0b3JzLCBhbmQgYWdhaW4gdGhlICgxPDwyNikgYml0IGlzIHNldCBhbmQgZnVuY3Rpb25zIGFyZSBnZW5lcmF0ZWQgaW4gdGhlIHNhbWUgbWFubmVyLgoKVW5kZXIgT2JqQyB3ZSBhbGxvdyBfX3dlYWsgYXMgYW4gYXR0cmlidXRlIG9uIF9fYmxvY2sgdmFyaWFibGVzLCBhbmQgdGhpcyBjYXVzZXMgdGhlIGFkZGl0aW9uIG9mIEJMT0NLX0ZJRUxEX0lTX1dFQUsgb3JyZWQgb250byB0aGUgQkxPQ0tfRklFTERfSVNfQllSRUYgZmxhZyB3aGVuIGNvcHlpbmcgdGhlIGJsb2NrX2J5cmVmIHN0cnVjdHVyZSBpbiB0aGUgYmxvY2sgY29weSBoZWxwZXIsIGFuZCBvbnRvIHRoZSBCTE9DS19GSUVMRF88YXBwcm9wbz4gZmllbGQgd2l0aGluIHRoZSBibG9ja19ieXJlZiBjb3B5L2Rpc3Bvc2UgaGVscGVyIGNhbGxzLgoKVGhlIHByb3RvdHlwZXMsIGFuZCBzdW1tYXJ5LCBvZiB0aGUgaGVscGVyIGZ1bmN0aW9ucyBhcmUKCi8qIENlcnRhaW4gZmllbGQgdHlwZXMgcmVxdWlyZSBydW50aW1lIGFzc2lzdGFuY2Ugd2hlbiBiZWluZyBjb3BpZWQgdG8gdGhlIGhlYXAuICBUaGUgZm9sbG93aW5nIGZ1bmN0aW9uIGlzIHVzZWQKICAgdG8gY29weSBmaWVsZHMgb2YgdHlwZXM6IGJsb2NrcywgcG9pbnRlcnMgdG8gYnlyZWYgc3RydWN0dXJlcywgYW5kIG9iamVjdHMgKGluY2x1ZGluZyBfX2F0dHJpYnV0ZV9fKChOU09iamVjdCkpIHBvaW50ZXJzLgogICBCTE9DS19GSUVMRF9JU19XRUFLIGlzIG9ydGhvZ29uYWwgdG8gdGhlIG90aGVyIGNob2ljZXMgd2hpY2ggYXJlIG11dHVhbGx5IGV4Y2x1c2l2ZS4KICAgT25seSBpbiBhIEJsb2NrIGNvcHkgaGVscGVyIHdpbGwgb25lIHNlZSBCTE9DS19GSUVMRF9JU19CWVJFRi4KICovCnZvaWQgX0Jsb2NrX29iamVjdF9hc3NpZ24odm9pZCAqZGVzdEFkZHIsIGNvbnN0IHZvaWQgKm9iamVjdCwgY29uc3QgaW50IGZsYWdzKTsKCi8qIFNpbWlsYXJseSBhIGNvbXBpbGVyIGdlbmVyYXRlZCBkaXNwb3NlIGhlbHBlciBuZWVkcyB0byBjYWxsIGJhY2sgZm9yIGVhY2ggZmllbGQgb2YgdGhlIGJ5cmVmIGRhdGEgc3RydWN0dXJlLgogICAoQ3VycmVudGx5IHRoZSBpbXBsZW1lbnRhdGlvbiBvbmx5IHBhY2tzIG9uZSBmaWVsZCBpbnRvIHRoZSBieXJlZiBzdHJ1Y3R1cmUgYnV0IGluIHByaW5jaXBsZSB0aGVyZSBjb3VsZCBiZSBtb3JlKS4KICAgVGhlIHNhbWUgZmxhZ3MgdXNlZCBpbiB0aGUgY29weSBoZWxwZXIgc2hvdWxkIGJlIHVzZWQgZm9yIGVhY2ggY2FsbCBnZW5lcmF0ZWQgdG8gdGhpcyBmdW5jdGlvbjoKICovCnZvaWQgX0Jsb2NrX29iamVjdF9kaXNwb3NlKGNvbnN0IHZvaWQgKm9iamVjdCwgY29uc3QgaW50IGZsYWdzKTsKClRoZSBmb2xsb3dpbmcgZnVuY3Rpb25zIGhhdmUgYmVlbiB1c2VkIGFuZCB3aWxsIGNvbnRpbnVlIHRvIGJlIHN1cHBvcnRlZCB1bnRpbCBuZXcgY29tcGlsZXIgc3VwcG9ydCBpcyBjb21wbGV0ZS4KCi8vIE9ic29sZXRlIGZ1bmN0aW9ucy4KLy8gQ29weSBoZWxwZXIgY2FsbGJhY2sgZm9yIGNvcHlpbmcgYSBibG9jayBpbXBvcnRlZCBpbnRvIGEgQmxvY2sKLy8gQ2FsbGVkIGJ5IGNvcHlfaGVscGVyIGhlbHBlciBmdW5jdGlvbnMgc3ludGhlc2l6ZWQgYnkgdGhlIGNvbXBpbGVyLgovLyBUaGUgYWRkcmVzcyBpbiB0aGUgZGVzdGluYXRpb24gYmxvY2sgb2YgYW4gaW1wb3J0ZWQgQmxvY2sgaXMgcHJvdmlkZWQgYXMgdGhlIGZpcnN0IGFyZ3VtZW50Ci8vIGFuZCB0aGUgdmFsdWUgb2YgdGhlIGV4aXN0aW5nIGltcG9ydGVkIEJsb2NrIGlzIHRoZSBzZWNvbmQuCi8vIFVzZTogX0Jsb2NrX29iamVjdF9hc3NpZ24oZGVzdCwgc3JjLCBCTE9DS19GSUVMRF9JU19CTE9DSyB7fCBCTE9DS19GSUVMRF9JU19XRUFLfSk7CnZvaWQgX0Jsb2NrX2NvcHlfYXNzaWduKHN0cnVjdCBCbG9ja19iYXNpYyAqKmRlc3QsIGNvbnN0IHN0cnVjdCBCbG9ja19iYXNpYyAqc3JjLCBjb25zdCBpbnQgZmxhZ3MpOwoKLy8gRGVzdHJveSBoZWxwZXIgY2FsbGJhY2sgZm9yIHJlbGVhc2luZyBCbG9ja3MgaW1wb3J0ZWQgaW50byBhIEJsb2NrCi8vIENhbGxlZCBieSBkaXNwb3NlX2hlbHBlciBoZWxwZXIgZnVuY3Rpb25zIHN5bnRoZXNpemVkIGJ5IHRoZSBjb21waWxlci4KLy8gVGhlIHZhbHVlIG9mIHRoZSBpbXBvcnRlZCBCbG9jayB2YXJpYWJsZSBpcyBwYXNzZWQgYmFjay4KLy8gVXNlOiBfQmxvY2tfb2JqZWN0X2Rpc3Bvc2Uoc3JjLCBCTE9DS19GSUVMRF9JU19CTE9DSyB7fCBCTE9DS19GSUVMRF9JU19XRUFLfSk7CnZvaWQgX0Jsb2NrX2Rlc3Ryb3koY29uc3Qgc3RydWN0IEJsb2NrX2Jhc2ljICpzcmMsIGNvbnN0IGludCBmbGFncyk7CgovLyBCeXJlZiBkYXRhIGJsb2NrIGNvcHkgaGVscGVyIGNhbGxiYWNrCi8vIENhbGxlZCBieSBibG9jayBjb3B5IGhlbHBlcnMgd2hlbiBjb3B5aW5nIF9fYmxvY2sgc3RydWN0dXJlcwovLyBVc2U6IF9CbG9ja19vYmplY3RfYXNzaWduKGRlc3QsIHNyYywgQkxPQ0tfRklFTERfSVNfQllSRUYge3wgQkxPQ0tfRklFTERfSVNfV0VBS30pOwp2b2lkIF9CbG9ja19ieXJlZl9hc3NpZ25fY29weShzdHJ1Y3QgQmxvY2tfYnlyZWYgKipkZXN0cCwgc3RydWN0IEJsb2NrX2J5cmVmICpzcmMpOwoKLy8gQnlyZWYgZGF0YSBibG9jayByZWxlYXNlIGhlbHBlciBjYWxsYmFjawovLyBDYWxsZWQgYnkgYmxvY2sgcmVsZWFzZSBoZWxwZXJzIHdoZW4gcmVsZWFzaW5nIGEgQmxvY2sgCi8vIENhbGxlZCBhdCBlc2NhcGUgcG9pbnRzIGluIHNjb3BlIHdoZXJlIF9fYmxvY2sgdmFyaWFibGVzIGxpdmUgKHVuZGVyIG5vbi1HQy1vbmx5IGNvbmRpdGlvbnMpIAovLyBVc2U6IF9CbG9ja19vYmplY3RfZGlzcG9zZShzcmMsIEJMT0NLX0ZJRUxEX0lTX0JZUkVGIHt8IEJMT0NLX0ZJRUxEX0lTX1dFQUt9KTsKdm9pZCCnKHN0cnVjdCBCbG9ja19ieXJlZiAqc2hhcmVkX3N0cnVjdCk7CgoK