LyoKICogQ29weXJpZ2h0IChjKSAyMDEyLTIwMTMgVGhlIExpbnV4IEZvdW5kYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqCiAqIFByZXZpb3VzbHkgbGljZW5zZWQgdW5kZXIgdGhlIElTQyBsaWNlbnNlIGJ5IFF1YWxjb21tIEF0aGVyb3MsIEluYy4KICoKICoKICogUGVybWlzc2lvbiB0byB1c2UsIGNvcHksIG1vZGlmeSwgYW5kL29yIGRpc3RyaWJ1dGUgdGhpcyBzb2Z0d2FyZSBmb3IKICogYW55IHB1cnBvc2Ugd2l0aCBvciB3aXRob3V0IGZlZSBpcyBoZXJlYnkgZ3JhbnRlZCwgcHJvdmlkZWQgdGhhdCB0aGUKICogYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBhcHBlYXIgaW4gYWxsCiAqIGNvcGllcy4KICoKICogVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEICJBUyBJUyIgQU5EIFRIRSBBVVRIT1IgRElTQ0xBSU1TIEFMTAogKiBXQVJSQU5USUVTIFdJVEggUkVHQVJEIFRPIFRISVMgU09GVFdBUkUgSU5DTFVESU5HIEFMTCBJTVBMSUVECiAqIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTLiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUKICogQVVUSE9SIEJFIExJQUJMRSBGT1IgQU5ZIFNQRUNJQUwsIERJUkVDVCwgSU5ESVJFQ1QsIE9SIENPTlNFUVVFTlRJQUwKICogREFNQUdFUyBPUiBBTlkgREFNQUdFUyBXSEFUU09FVkVSIFJFU1VMVElORyBGUk9NIExPU1MgT0YgVVNFLCBEQVRBIE9SCiAqIFBST0ZJVFMsIFdIRVRIRVIgSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNULCBORUdMSUdFTkNFIE9SIE9USEVSCiAqIFRPUlRJT1VTIEFDVElPTiwgQVJJU0lORyBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBVU0UgT1IKICogUEVSRk9STUFOQ0UgT0YgVEhJUyBTT0ZUV0FSRS4KICovCgovKgogKiBUaGlzIGZpbGUgd2FzIG9yaWdpbmFsbHkgZGlzdHJpYnV0ZWQgYnkgUXVhbGNvbW0gQXRoZXJvcywgSW5jLgogKiB1bmRlciBwcm9wcmlldGFyeSB0ZXJtcyBiZWZvcmUgQ29weXJpZ2h0IG93bmVyc2hpcCB3YXMgYXNzaWduZWQKICogdG8gdGhlIExpbnV4IEZvdW5kYXRpb24uCiAqLwoKLyoqPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogIAogIFxmaWxlICB3bGFuX3FjdF9wYWxfcGFja2V0LmMKICAKICBcYnJpZWYgSW1wbGVtZW50YXRpb24gZm9yIFBBTCBwYWNrZXQuIHdwdCA9IChXbGFuIFBhbCBUeXBlKSB3cGFsID0gKFdsYW4gUEFMKQogICAgICAgICAgICAgICAKICAgRGVmaW5pdGlvbnMgZm9yIHBsYXRmb3JtIHdpdGggVk9TUyBwYWNrZXQgc3VwcG9ydCBhbmQgTEEuCiAgCiAgCiAgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ki8KCiNpbmNsdWRlICJ3bGFuX3FjdF9wYWxfcGFja2V0LmgiCiNpbmNsdWRlICJ3bGFuX3FjdF9wYWxfYXBpLmgiCiNpbmNsdWRlICJ3bGFuX3FjdF9wYWxfdHJhY2UuaCIKI2luY2x1ZGUgIndsYW5fcWN0X29zX3N0YXR1cy5oIgojaW5jbHVkZSAidm9zX3BhY2tldC5oIgojaW5jbHVkZSAidm9zX3RyYWNlLmgiCiNpbmNsdWRlICJ2b3NfbGlzdC5oIgoKI2luY2x1ZGUgPGxpbnV4L3NrYnVmZi5oPgojaW5jbHVkZSAiZG1hLW1hcHBpbmcuaCIKI2luY2x1ZGUgPGxpbnV4L3djbnNzX3dsYW4uaD4KCi8qUGVyIHNwZWMgZGVmaW5pdGlvbiovCiNkZWZpbmUgV1BBTF9FVEhFUk5FVF9QQUtDRVRfSEVBREVSX1NJWkUgICAgIDE0CgovKlBlciBzcGVjIGRlZmluaXRpb24gLSBub3QgaW5jbHVkaW5nIFFPUyBmaWVsZCovCiNkZWZpbmUgV1BBTF84MDJfMTFfUEFDS0VUX0hFQURFUl9TSVpFICAgIDI0IAoKLypwIGlzIGEgcG9pbnRlciB0byB3cHRfcGFja2V0Ki8KI2RlZmluZSBXUEFMX1RPX1ZPU19QS1QocCkgKCh2b3NfcGt0X3QgKikocCkpCgoKdHlwZWRlZiBzdHJ1Y3QKewogIHZvaWQqICAgICAgcFBoeUFkZHI7CiAgd3B0X3VpbnQzMiB1TGVuOwp9d3B0X2l0ZXJhdG9yX2luZm87CgovKiBTdG9yYWdlIGZvciBEWEUgQ0IgZnVuY3Rpb24gcG9pbnRlciAqLwpzdGF0aWMgd3BhbFBhY2tldExvd1BhY2tldENCIHdwYWxQYWNrZXRBdmFpbGFibGVDQjsKCi8qIFRlbXAgc3RvcmFnZSBmb3IgdHJhbnNwb3J0IGNoYW5uZWwgRElBRy9MT0cgaW5mb3JtYXRpb24KICogRWFjaCBjaGFubmVsIHdpbGwgdXBkYXRlIGluZm9ybWF0aW9uIHdpdGggZGlmZmVyZW50IGNvbnRleHQKICogQmVmb3JlIHNlbmQgc3RvcmVkIGRhdGUgdG8gRElBRywKICogdGVtcG9yYXJ5IGl0IHNob3VsZCBiZSBzdG9yZWQgKi8Kc3RhdGljIHdwdF9sb2dfZGF0YV9zdGFsbF90eXBlIHdwYWxUcmFzcG9ydFN0YWxsSW5mbzsKCi8qCiAgIHdwYWxQYWNrZXRJbml0IGlzIG5vLW9wIGZvciBWT1NTLXN1cHBvcnQgd3B0X3BhY2tldAoqLwp3cHRfc3RhdHVzIHdwYWxQYWNrZXRJbml0KHZvaWQgKnBQYWxDb250ZXh0KQp7CiAgIHJldHVybiBlV0xBTl9QQUxfU1RBVFVTX1NVQ0NFU1M7Cn0KCgovKgogICB3cGFsUGFja2V0Q2xvc2UgaXMgbm8tb3AgZm9yIFZPU1Mtc3VwcG9ydCB3cHRfcGFja2V0CiovCndwdF9zdGF0dXMgd3BhbFBhY2tldENsb3NlKHZvaWQgKnBQYWxDb250ZXh0KQp7CiAgIHJldHVybiBlV0xBTl9QQUxfU1RBVFVTX1NVQ0NFU1M7Cn0KCi8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgICB3cGFsUGFja2V0UlhMb3dSZXNvdXJjZUNCIJYgUlggUkFXIHBhY2tlciBDQiBmdW5jdGlvbgogICAgUGFyYW06IAogICAgICAgIHBQYWNrZXQgliBBdmFpbGFibGUgUlggcGFja2V0CiAgICAgICAgdXNlckRhdGEgLSBQQUwgQ2xpZW50IENvbnRleHQsIERYRQogICAgUmV0dXJuOgogICAgICAgIFN0YXR1cwotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwpWT1NfU1RBVFVTIHdwYWxQYWNrZXRSWExvd1Jlc291cmNlQ0Iodm9zX3BrdF90ICpwUGFja2V0LCB2X1ZPSURfdCAqdXNlckRhdGEpCnsKICAgVk9TX1NUQVRVUyAgIHZvc1N0YXR1cyA9IFZPU19TVEFUVVNfRV9GQUlMVVJFOwogICB2b2lkKiAgICAgICAgcERhdGEgICAgID0gTlVMTDsKCiAgIGlmIChOVUxMID09IHBQYWNrZXQpCiAgIHsKICAgICAgV1BBTF9UUkFDRShlV0xBTl9NT0RVTEVfUEFMLCBlV0xBTl9QQUxfVFJBQ0VfTEVWRUxfRVJST1IsIAogICAgICAgICAgICAgICAgICAiR2V0IG5ldyBSWCBQQUwgcGFja2V0IGZhaWwiKTsKICAgICAgcmV0dXJuIFZPU19TVEFUVVNfRV9GQUlMVVJFOwogICB9CiAgIHZvc1N0YXR1cyA9IHZvc19wa3RfcmVzZXJ2ZV9oZWFkX2Zhc3QoIHBQYWNrZXQsICZwRGF0YSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVlBLVF9TSVpFX0JVRkZFUiApOwogICBpZihWT1NfU1RBVFVTX1NVQ0NFU1MgIT0gdm9zU3RhdHVzKQogICB7CiAgICAgIFdQQUxfVFJBQ0UoZVdMQU5fTU9EVUxFX1BBTCwgZVdMQU5fUEFMX1RSQUNFX0xFVkVMX0VSUk9SLCAKICAgICAgICAgICAgICAgICAgIlByZXBhcmUgUlggcGFja2V0IGZvciBEWEUgZmFpbCIpOwogICAgICByZXR1cm4gVk9TX1NUQVRVU19FX0ZBSUxVUkU7CiAgIH0KCiAgIGlmKChOVUxMID09IHdwYWxQYWNrZXRBdmFpbGFibGVDQikgfHwgKE5VTEwgPT0gdXNlckRhdGEpKQogICB7CiAgICAgIFdQQUxfVFJBQ0UoZVdMQU5fTU9EVUxFX1BBTCwgZVdMQU5fUEFMX1RSQUNFX0xFVkVMX0VSUk9SLCAKICAgICAgICAgICAgICAgICAgIkludmFsaWQgQVJHIGZvciBuZXcgUlggcGFja2V0Iik7CiAgICAgIHJldHVybiBWT1NfU1RBVFVTX0VfRkFJTFVSRTsKICAgfQoKICAgd3BhbFBhY2tldEF2YWlsYWJsZUNCKCAod3B0X3BhY2tldCAqKXBQYWNrZXQsIHVzZXJEYXRhICk7CgogICByZXR1cm4gVk9TX1NUQVRVU19TVUNDRVNTOwp9CgovKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogICAgd3BhbFBhY2tldEFsbG9jIJYgQWxsb2NhdGUgYSB3cHRfcGFja2V0IGZyb20gUEFMLgogICAgUGFyYW06IAogICAgICAgIHBrdFR5cGUgliBzcGVjaWZ5IHRoZSB0eXBlIG9mIHdwdF9wYWNrZXQgdG8gYWxsb2NhdGUKICAgICAgICBuUGt0U2l6ZSAtIHBhY2tldCBzaXplCiAgICBSZXR1cm46CiAgICAgICAgQSBwb2ludGVyIHRvIHRoZSB3cHRfcGFja2V0LiBOVUxMIG1lYW5zIGZhaWwuCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCndwdF9wYWNrZXQgKiB3cGFsUGFja2V0QWxsb2Mod3B0X3BhY2tldF90eXBlIHBrdFR5cGUsIHdwdF91aW50MzIgblBrdFNpemUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd3BhbFBhY2tldExvd1BhY2tldENCIHJ4TG93Q0IsIHZvaWQgKnVzckRhdGEpCnsKICAgVk9TX1NUQVRVUyAgIHZvc1N0YXR1cyA9IFZPU19TVEFUVVNfRV9GQUlMVVJFOwogICB3cHRfcGFja2V0KiAgcFBrdCAgICAgID0gTlVMTDsKICAgdm9zX3BrdF90KiAgIHBWb3NQa3QgICA9IE5VTEw7CiAgIHZvaWQqICAgICAgICBwRGF0YSAgICAgPSBOVUxMOwogICB2X1UxNl90ICAgICAgYWxsb2NMZW47CiAgIC8qLSAtIC0gLSAtIC0gLSAtIC0gLSAtIC0gLSAtIC0gLSAtIC0gLSAtIC0gLSAtIC0gLSAtIC0gLSAtIC0gLSAtIC0gLSAtICovCgogICBzd2l0Y2ggKHBrdFR5cGUpCiAgIHsKICAgY2FzZSBlV0xBTl9QQUxfUEtUX1RZUEVfVFhfODAyXzExX01HTVQ6CiAgICAgIHZvc1N0YXR1cyA9IHZvc19wa3RfZ2V0X3BhY2tldCgmcFZvc1BrdCwgVk9TX1BLVF9UWVBFX1RYXzgwMl8xMV9NR01ULAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuUGt0U2l6ZSwgMSwgVk9TX0ZBTFNFLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTlVMTCwgTlVMTCAvKm5vIGNhbGxiYWNrKi8pOwogICAgICBicmVhazsKCiAgIGNhc2UgZVdMQU5fUEFMX1BLVF9UWVBFX1JYX1JBVzoKICAgICAgLyogU2V0IHRoZSB3cGFsUGFja2V0QXZhaWxhYmxlQ0IgYmVmb3JlIHdlIHRyeSB0byBnZXQgYSBWT1MKICAgICAgICogcGFja2V0IGZyb20gdGhlICdmcmVlIGxpc3QnIGFuZCByZXNldCBpdCBpZiB2b3NfcGt0X2dldF9wYWNrZXQoKQogICAgICAgKiByZXR1cm5zIGEgdmFsaWQgcGFja2V0LiBUaGlzIG9yZGVyIGlzIHJlcXVpcmVkIHRvIGF2b2lkIHRoZQogICAgICAgKiByYWNlIGNvbmRpdGlvbjoKICAgICAgICogMS4gVGhlIGJlbG93IGNhbGwgdG8gdm9zX3BrdF9nZXRfcGFja2V0KCkgaW4gUlhfVGhyZWFkIGRldGVybWluZXMKICAgICAgICogICAgdGhhdCBubyBtb3JlIHBhY2tldHMgYXJlIGF2YWlsYWJsZSBpbiB0aGUgJ2ZyZWUgbGlzdCcgYW5kIHNldHMKICAgICAgICogICAgdGhlIGxvdyByZXNvdXJjZSBjYWxsYmFja3MuCiAgICAgICAqIDIuIGluIHBhcmFsbGVsIHZvc19wa3RfcmV0dXJuX3BhY2tldCgpIGlzIGNhbGxlZCBpbiBNQ19UaHJlYWQgZm9yIGEKICAgICAgICogICAgTWFuYWdlbWVudCBmcmFtZSBiZWZvcmUgd3BhbFBhY2tldEFsbG9jKCkgZ2V0cyBhIGNoYW5jZSB0byBzZXQKICAgICAgICogICAgd3BhbFBhY2tldEF2YWlsYWJsZUNCIGFuZCBzaW5jZSB0aGUgJ2xvdyByZXNvdXJjZSBjYWxsYmFja3MnCiAgICAgICAqICAgIGFyZSBzZXQgdGhlIGNhbGxiYWNrIGZ1bmN0aW9uIC0gd3BhbFBhY2tldFJYTG93UmVzb3VyY2VDQiBpcwogICAgICAgKiAgICBleGVjdXRlZCxidXQgc2luY2Ugd3BhbFBhY2tldEF2YWlsYWJsZUNCIGlzIHN0aWxsIE5VTEwgdGhlIGxvdwogICAgICAgKiAgICByZXNvdXJjZSByZWNvdmVyeSBmYWlscy4KICAgICAgICovCiAgICAgIHdwYWxQYWNrZXRBdmFpbGFibGVDQiA9IHJ4TG93Q0I7CgogICAgICB2b3NTdGF0dXMgPSB2b3NfcGt0X2dldF9wYWNrZXQoJnBWb3NQa3QsIFZPU19QS1RfVFlQRV9SWF9SQVcsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5Qa3RTaXplLCAxLCBWT1NfRkFMU0UsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3cGFsUGFja2V0UlhMb3dSZXNvdXJjZUNCLCB1c3JEYXRhKTsKCiNpZm5kZWYgRkVBVFVSRV9SMzNECiAgICAgIC8qIFJlc2VydmUgdGhlIGVudGlyZSByYXcgcnggYnVmZmVyIGZvciBEWEUgKi8KICAgICAgaWYoIHZvc1N0YXR1cyA9PSBWT1NfU1RBVFVTX1NVQ0NFU1MgKQogICAgICB7CiAgICAgICAgd3BhbFBhY2tldEF2YWlsYWJsZUNCID0gTlVMTDsKICAgICAgICB2b3NTdGF0dXMgPSAgdm9zX3BrdF9yZXNlcnZlX2hlYWRfZmFzdCggcFZvc1BrdCwgJnBEYXRhLCBuUGt0U2l6ZSApOyAKICAgICAgfQojZW5kaWYgLyogRkVBVFVSRV9SMzNEICovCiAgICAgIGlmKChOVUxMICE9IHBWb3NQa3QpICYmIChWT1NfU1RBVFVTX0VfUkVTT1VSQ0VTICE9IHZvc1N0YXR1cykpCiAgICAgIHsKICAgICAgICAgdm9zX3BrdF9nZXRfcGFja2V0X2xlbmd0aChwVm9zUGt0LCAmYWxsb2NMZW4pOwogICAgICAgICBpZiAoblBrdFNpemUgIT0gYWxsb2NMZW4pCiAgICAgICAgIHsKICAgICAgICAgICAgV1BBTF9UUkFDRShlV0xBTl9NT0RVTEVfUEFMLCBlV0xBTl9QQUxfVFJBQ0VfTEVWRUxfRVJST1IsCiAgICAgICAgICAgICAgICAgICAgICAgIlJYIHBhY2tldCBhbGxvYyBoYXMgcHJvYmxlbSwgZGlzY2FyZCB0aGlzIGZyYW1lLCBMZW4gJWQiLCBhbGxvY0xlbik7CiAgICAgICAgICAgIHZvc19wa3RfcmV0dXJuX3BhY2tldChwVm9zUGt0KTsKICAgICAgICAgICAgcmV0dXJuIE5VTEw7CiAgICAgICAgIH0KICAgICAgfQogICAgICBicmVhazsKCiAgIGRlZmF1bHQ6CiAgICAgIFdQQUxfVFJBQ0UoZVdMQU5fTU9EVUxFX1BBTCwgZVdMQU5fUEFMX1RSQUNFX0xFVkVMX0VSUk9SLCAKICAgICAgICAgICAgICAgICAgIiB0cnkgdG8gYWxsb2NhdGUgdW5zdXBwb3J0ZWQgcGFja2V0IHR5cGUgKCVkKSIsIHBrdFR5cGUpOwogICAgICBicmVhazsKICAgfQoKICAgaWYoVk9TX0lTX1NUQVRVU19TVUNDRVNTKHZvc1N0YXR1cykpCiAgIHsKICAgICAgcFBrdCA9ICh3cHRfcGFja2V0ICopcFZvc1BrdDsKICAgfQoKCiAgIHJldHVybiBwUGt0Owp9Lyp3cGFsUGFja2V0QWxsb2MqLwoKCgovKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogICAgd3BhbFBhY2tldEZyZWUgliBGcmVlIGEgd3B0X3BhY2tldCBjaGFpbiBmb3Igb25lIHBhcnRpY3VsYXIgdHlwZS4KICAgIEZvciBvdXIgbGVnYWN5IFVNQUMsIGl0IGlzIG5vdCBuZWVkZWQgYmVjYXVzZSB2b3NfcGFja2V0IGNvbnRhaW5zIHBhbF9wYWNrZXQuCiAgICBQYXJhbTogCiAgICAgICAgcFBrdCCWIHBvaW50ZXIgdG8gYSB3cHRfcGFja2V0CiAgICBSZXR1cm46CiAgICAgICAgZVdMQU5fUEFMX1NUQVRVU19TVUNDRVNTIC0gc3VjY2VzcwotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwp3cHRfc3RhdHVzIHdwYWxQYWNrZXRGcmVlKHdwdF9wYWNrZXQgKnBQa3QpCnsKICAgVk9TX1NUQVRVUyB2b3NTdGF0dXM7CgogICBpZihOVUxMICE9IHBQa3QtPnBJbnRlcm5hbERhdGEpCiAgIHsKICAgICAgd3BhbE1lbW9yeUZyZWUocFBrdC0+cEludGVybmFsRGF0YSk7CiAgIH0KICAgdm9zU3RhdHVzID0gdm9zX3BrdF9yZXR1cm5fcGFja2V0KFdQQUxfVE9fVk9TX1BLVChwUGt0KSk7CgogICAvL1dpdGggVk9TUyBzdXBwb3J0LCB3ZSBjYW4gY2FzdCBiZXR3ZWVuIHdwdF9zdGF0dXMgYW5kIFZPU19TVEFUVVMKICAgcmV0dXJuICh3cHRfc3RhdHVzKXZvc1N0YXR1czsKfS8qd3BhbFBhY2tldEZyZWUqLwoKCi8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgICB3cGFsUGFja2V0R2V0TGVuZ3RoIJYgR2V0IG51bWJlciBvZiBieXRlcyBpbiBhIHdwdF9wYWNrZXQuIEl0IGluY2x1ZGUgdGhlIAogICAgYnl0ZXMgaW4gYSBCRCBpZiBpdCBleGlzdC4KICAgIFBhcmFtOiAKICAgICAgICBwUGt0IC0gcG9pbnRlciB0byBhIHBhY2tldCB0byBiZSBmcmVlZC4KICAgIFJldHVybjoKICAgICAgICBMZW5ndGggb2YgdGhlIGRhdGEgaW5jbHVkZSBsYXllci0yIGhlYWRlcnMuIEZvciBleGFtcGxlLCBpZiB0aGUgZnJhbWUKICAgICAgICBpcyA4MDIuMywgdGhlIGxlbmd0aCBpbmNsdWRlcyB0aGUgZXRoZXJuZXQgaGVhZGVyLgotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwp3cHRfdWludDMyIHdwYWxQYWNrZXRHZXRMZW5ndGgod3B0X3BhY2tldCAqcFBrdCkKewogICB2X1UxNl90IGxlbiA9IDAsIHBrdExlbiA9IDA7CgogICAvLyBWYWxpZGF0ZSB0aGUgcGFyYW1ldGVyIHBvaW50ZXJzCiAgIGlmICh1bmxpa2VseShOVUxMID09IHBQa3QpKQogICB7CiAgICAgIFdQQUxfVFJBQ0UoZVdMQU5fTU9EVUxFX1BBTCwgZVdMQU5fUEFMX1RSQUNFX0xFVkVMX0VSUk9SLAogICAgICAgICAgICAgICAgIiVzIDogTlVMTCBwYWNrZXQgcG9pbnRlciIsIF9fZnVuY19fKTsKICAgICAgcmV0dXJuIGVXTEFOX1BBTF9TVEFUVVNfRV9JTlZBTDsKICAgfQoKCiAgIGlmKCBXUEFMX1BBQ0tFVF9HRVRfQkRfUE9JTlRFUihwUGt0KSApCiAgIHsKICAgICAgbGVuID0gV1BBTF9QQUNLRVRfR0VUX0JEX0xFTkdUSChwUGt0KTsKICAgfQogICBpZiggVk9TX0lTX1NUQVRVU19TVUNDRVNTKHZvc19wa3RfZ2V0X3BhY2tldF9sZW5ndGgoV1BBTF9UT19WT1NfUEtUKHBQa3QpLCAmcGt0TGVuKSkgKQogICB7CiAgICAgIGxlbiArPSBwa3RMZW47CiAgIH0KICAgZWxzZQogICB7CiAgICAgIFdQQUxfVFJBQ0UoZVdMQU5fTU9EVUxFX1BBTCwgZVdMQU5fUEFMX1RSQUNFX0xFVkVMX0VSUk9SLCAiJXMgIGZhaWxlZCIsCiAgICAgICAgIF9fZnVuY19fKTsKICAgfQoKICAgcmV0dXJuICgod3B0X3VpbnQzMilsZW4pOwp9Lyp3cGFsUGFja2V0R2V0TGVuZ3RoKi8KCgovKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogICAgd3BhbFBhY2tldFJhd1RyaW1IZWFkIJYgTW92ZSB0aGUgc3RhcnRpbmcgb2Zmc2V0IGFuZCByZXR1cm4gdGhlIGhlYWQgcG9pbnRlcgogICAgICAgICAgYmVmb3JlIHRoZSBtb3ZpbmcuIFRoZSBmdW5jdGlvbiBjYW4gb25seSBiZSB1c2VkIHdpdGggcmF3IHBhY2tldHMsCiAgICAgICAgICB3aG9zZSBidWZmZXIgaXMgb25lIHBpZWNlIGFuZCBhbGxvY2F0ZWQgYnkgV0xBTiBkcml2ZXIuIFRoaXMgYWxzbwogICAgICAgICAgcmVkdWNlIHRoZSBsZW5ndGggb2YgdGhlIHBhY2tldC4KICAgIFBhcmFtOiAKICAgICAgICBwUGt0IC0gcG9pbnRlciB0byBhIHdwdF9wYWNrZXQuCiAgICAgICAgc2l6ZSCWIG51bWJlciBvZiBieXRlcyB0byB0YWtlIG9mZiB0aGUgaGVhZC4KICAgIFJldHVybjoKICAgICAgICBBIHBvaW50ZXIgdG8gdGhlIG9yaWdpbmFsIGJ1ZmZlciBoZWFkIGJlZm9yZSB0aGUgdHJpbW1pbmcuCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCndwdF9zdGF0dXMgd3BhbFBhY2tldFJhd1RyaW1IZWFkKHdwdF9wYWNrZXQgKnBQa3QsIHdwdF91aW50MzIgc2l6ZSkKewogICB3cHRfc3RhdHVzIHN0YXR1cyA9IGVXTEFOX1BBTF9TVEFUVVNfU1VDQ0VTUzsKCiAgIC8vIFZhbGlkYXRlIHRoZSBwYXJhbWV0ZXIgcG9pbnRlcnMKICAgaWYgKHVubGlrZWx5KE5VTEwgPT0gcFBrdCkpCiAgIHsKICAgICAgV1BBTF9UUkFDRShlV0xBTl9NT0RVTEVfUEFMLCBlV0xBTl9QQUxfVFJBQ0VfTEVWRUxfRVJST1IsCiAgICAgICAgICAgICAgICAiJXMgOiBOVUxMIHBhY2tldCBwb2ludGVyIiwgX19mdW5jX18pOwogICAgICByZXR1cm4gZVdMQU5fUEFMX1NUQVRVU19FX0lOVkFMOwogICB9CgogICBpZiAoKGVXTEFOX1BBTF9QS1RfVFlQRV9UWF84MDJfMTFfTUdNVCA9PSBXUEFMX1BBQ0tFVF9HRVRfVFlQRShwUGt0KSkgfHwKICAgICAgICAgICAgICAgKGVXTEFOX1BBTF9QS1RfVFlQRV9SWF9SQVcgPT0gV1BBTF9QQUNLRVRfR0VUX1RZUEUocFBrdCkpKQogICB7CiAgICAgICAvLyBDb250aW51ZSB0byB0cmltIHRoZSBwYWNrZXQKICAgfQogICBlbHNlCiAgIHsKICAgICAgV1BBTF9UUkFDRShlV0xBTl9NT0RVTEVfUEFMLCBlV0xBTl9QQUxfVFJBQ0VfTEVWRUxfRVJST1IsCiAgICAgICAgICAgICAgICAiJXMgOiBuZWl0aGVyIDgwMjExIG1hbmFnbWVudCBwYWNrZXQgbm9yIFJBVyBwYWNrZXQiLCBfX2Z1bmNfXyk7CiAgICAgIFZPU19BU1NFUlQoMCk7CiAgICAgIHJldHVybiBlV0xBTl9QQUxfU1RBVFVTX0VfSU5WQUw7CiAgIH0KCiAgIGlmKCAhVk9TX0lTX1NUQVRVU19TVUNDRVNTKHZvc19wa3RfdHJpbV9oZWFkKFdQQUxfVE9fVk9TX1BLVChwUGt0KSwgKHZfU0laRV90KXNpemUpKSApCiAgIHsKICAgICAgV1BBTF9UUkFDRShlV0xBTl9NT0RVTEVfUEFMLCBlV0xBTl9QQUxfVFJBQ0VfTEVWRUxfRVJST1IsICIlcyAgSW52YWxpZCB0cmltKCVkKSIsCiAgICAgICAgIF9fZnVuY19fLCBzaXplKTsKICAgICAgc3RhdHVzID0gZVdMQU5fUEFMX1NUQVRVU19FX0lOVkFMOwogICB9CgogICByZXR1cm4gc3RhdHVzOwp9Lyp3cGFsUGFja2V0UmF3VHJpbUhlYWQqLwoKLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAgIHdwYWxQYWNrZXRSYXdUcmltVGFpbCCWIHJlZHVjZSB0aGUgbGVuZ3RoIG9mIHRoZSBwYWNrZXQuCiAgICBQYXJhbTogCiAgICAgICAgcFBrdCAtIHBvaW50ZXIgdG8gYSB3cHRfcGFja2V0LgogICAgICAgIHNpemUgliBudW1iZXIgb2YgYnl0ZXMgdG8gdGFrZSBvZiB0aGUgcGFja2V0IGxlbmd0aAogICAgUmV0dXJuOgogICAgICAgIGVXTEFOX1BBTF9TVEFUVVNfU1VDQ0VTUyCWIHN1Y2Nlc3MuIE90aGVyd2lzZSBmYWlsLgotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwp3cHRfc3RhdHVzIHdwYWxQYWNrZXRSYXdUcmltVGFpbCh3cHRfcGFja2V0ICpwUGt0LCB3cHRfdWludDMyIHNpemUpCnsKICAgd3B0X3N0YXR1cyBzdGF0dXMgPSBlV0xBTl9QQUxfU1RBVFVTX1NVQ0NFU1M7CgogICAvLyBWYWxpZGF0ZSB0aGUgcGFyYW1ldGVyIHBvaW50ZXJzCiAgIGlmICh1bmxpa2VseShOVUxMID09IHBQa3QpKQogICB7CiAgICAgIFdQQUxfVFJBQ0UoZVdMQU5fTU9EVUxFX1BBTCwgZVdMQU5fUEFMX1RSQUNFX0xFVkVMX0VSUk9SLAogICAgICAgICAgICAgICAgIiVzIDogTlVMTCBwYWNrZXQgcG9pbnRlciIsIF9fZnVuY19fKTsKICAgICAgcmV0dXJuIGVXTEFOX1BBTF9TVEFUVVNfRV9JTlZBTDsKICAgfQoKICAgaWYgKChlV0xBTl9QQUxfUEtUX1RZUEVfVFhfODAyXzExX01HTVQgPT0gV1BBTF9QQUNLRVRfR0VUX1RZUEUocFBrdCkpIHx8CiAgICAgICAgICAgICAgIChlV0xBTl9QQUxfUEtUX1RZUEVfUlhfUkFXID09IFdQQUxfUEFDS0VUX0dFVF9UWVBFKHBQa3QpKSkKICAgewogICAgICAgLy8gQ29udGludWUgdG8gdHJpbSB0aGUgcGFja2V0CiAgIH0KICAgZWxzZQogICB7CiAgICAgIFdQQUxfVFJBQ0UoZVdMQU5fTU9EVUxFX1BBTCwgZVdMQU5fUEFMX1RSQUNFX0xFVkVMX0VSUk9SLAogICAgICAgICAgICAgICAgIiVzIDogbmVpdGhlciA4MDIxMSBtYW5hZ21lbnQgcGFja2V0IG5vciBSQVcgcGFja2V0IiwgX19mdW5jX18pOwogICAgICBWT1NfQVNTRVJUKDApOwogICAgICByZXR1cm4gZVdMQU5fUEFMX1NUQVRVU19FX0lOVkFMOwogICB9CgogICBpZiggIVZPU19JU19TVEFUVVNfU1VDQ0VTUyh2b3NfcGt0X3RyaW1fdGFpbChXUEFMX1RPX1ZPU19QS1QocFBrdCksICh2X1NJWkVfdClzaXplKSkgKQogICB7CiAgICAgIFdQQUxfVFJBQ0UoZVdMQU5fTU9EVUxFX1BBTCwgZVdMQU5fUEFMX1RSQUNFX0xFVkVMX0VSUk9SLCAiJXMgIEludmFsaWQgdHJpbSglZCkiLAogICAgICAgICBfX2Z1bmNfXywgc2l6ZSk7CiAgICAgIHN0YXR1cyA9IGVXTEFOX1BBTF9TVEFUVVNfRV9JTlZBTDsKICAgfQoKICAgcmV0dXJuIHN0YXR1czsKfS8qd3BhbFBhY2tldFJhd1RyaW1UYWlsKi8KCgovKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogICAgd3BhbFBhY2tldEdldFJhd0J1ZiCWIFJldHVybiB0aGUgc3RhcnRpbmcgYnVmZmVyIHZpcnR1YWwgYWRkcmVzcyBmb3IgdGhlIFJBVyBmbGF0IGJ1ZmZlcgogICAgSXQgaXMgaW5saW5lIGluIGhvcGUgb2YgZmFzdGVyIGltcGxlbWVudGF0aW9uIGZvciBjZXJ0YWluIHBsYXRmb3JtLiBGb3IgV2lueHAsIGl0IAogICAgd2lsbCBiZSBzbG93LgogICAgUGFyYW06IAogICAgICAgIHBQa3QgLSBwb2ludGVyIHRvIGEgd3B0X3BhY2tldC4KICAgIFJldHVybjoKICAgICAgICBOVUxMIC0gZmFpbC4KICAgICAgICBPdGhlcndpc2UgdGhlIGFkZHJlc3Mgb2YgdGhlIHN0YXJ0aW5nIG9mIHRoZSBidWZmZXIKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8Kd3B0X3VpbnQ4ICp3cGFsUGFja2V0R2V0UmF3QnVmKHdwdF9wYWNrZXQgKnBQa3QpCnsKICAgd3B0X3VpbnQ4ICpwUmV0ID0gTlVMTDsKCiAgIC8vIFZhbGlkYXRlIHRoZSBwYXJhbWV0ZXIgcG9pbnRlcnMKICAgaWYgKHVubGlrZWx5KE5VTEwgPT0gcFBrdCkpCiAgIHsKICAgICAgV1BBTF9UUkFDRShlV0xBTl9NT0RVTEVfUEFMLCBlV0xBTl9QQUxfVFJBQ0VfTEVWRUxfRVJST1IsCiAgICAgICAgICAgICAgICAiJXMgOiBOVUxMIHBhY2tldCBwb2ludGVyIiwgX19mdW5jX18pOwogICAgICByZXR1cm4gTlVMTDsKICAgfQoKICAgLy9TaW5jZSBpdCBpcyBhIGZsYXQgYnVmZmVyLCBhbGwgd2UgbmVlZCBpcyB0byBnZXQgb25lIGJ5dGUgb2Ygb2Zmc2V0IDAKICAgaWYoIChlV0xBTl9QQUxfUEtUX1RZUEVfUlhfUkFXID09IFdQQUxfUEFDS0VUX0dFVF9UWVBFKHBQa3QpKSB8fAogICAgICAgKGVXTEFOX1BBTF9QS1RfVFlQRV9UWF84MDJfMTFfTUdNVCA9PSBXUEFMX1BBQ0tFVF9HRVRfVFlQRShwUGt0KSkgKQogICB7CiAgICAgIHZvc19wa3RfcGVla19kYXRhKFdQQUxfVE9fVk9TX1BLVChwUGt0KSwgMCwgKHZfVk9JRF90KiopJnBSZXQsIDEpOwogICAgICBXUEFMX0FTU0VSVChOVUxMICE9IHBSZXQpOwogICB9ICAgICAgICAgICAgCgogICByZXR1cm4gcFJldDsKfS8qd3BhbFBhY2tldEdldFJhd0J1ZiovCgoKLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAgIHdwYWxQYWNrZXRTZXRSeExlbmd0aCCWIFNldCB0aGUgdmFsaWQgZGF0YSBsZW5ndGggb24gYSBSWCBwYWNrZXQuIFRoaXMgZnVuY3Rpb24gbXVzdCAKICAgIGJlIGNhbGxlZCBvbmNlIHBlciBSWCBwYWNrZXQgcGVyIHJlY2VpdmluZy4gSXQgaW5kaWNhdGVzIHRoZSBhdmFpbGFibGUgZGF0YSBsZW5ndGggZnJvbQogICAgdGhlIHN0YXJ0IG9mIHRoZSBidWZmZXIuCiAgICBQYXJhbTogCiAgICAgICAgcFBrdCAtIHBvaW50ZXIgdG8gYSB3cHRfcGFja2V0LgogICAgUmV0dXJuOgogICAgICAgIE5VTEwgLSBmYWlsLgogICAgICAgIE90aGVyd2lzZSB0aGUgYWRkcmVzcyBvZiB0aGUgc3RhcnRpbmcgb2YgdGhlIGJ1ZmZlcgotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwp3cHRfc3RhdHVzIHdwYWxQYWNrZXRTZXRSeExlbmd0aCh3cHRfcGFja2V0ICpwUGt0LCB3cHRfdWludDMyIGxlbikKewogICAvLyBWYWxpZGF0ZSB0aGUgcGFyYW1ldGVyIHBvaW50ZXJzCiAgIGlmICh1bmxpa2VseShOVUxMID09IHBQa3QpKQogICB7CiAgICAgIFdQQUxfVFJBQ0UoZVdMQU5fTU9EVUxFX1BBTCwgZVdMQU5fUEFMX1RSQUNFX0xFVkVMX0VSUk9SLAogICAgICAgICAgICAgICAgIiVzIDogTlVMTCBwYWNrZXQgcG9pbnRlciIsIF9fZnVuY19fKTsKICAgICAgcmV0dXJuIGVXTEFOX1BBTF9TVEFUVVNfRV9JTlZBTDsKICAgfQoKICAgLypPbmx5IGFsbG93ZWQgZm9yIFJYIFJhdyBwYWNrZXRzICovCiAgIGlmKCAoZVdMQU5fUEFMX1BLVF9UWVBFX1JYX1JBVyAhPSBXUEFMX1BBQ0tFVF9HRVRfVFlQRShwUGt0KSkpCiAgIHsKICAgICBXUEFMX1RSQUNFKGVXTEFOX01PRFVMRV9QQUwsIGVXTEFOX1BBTF9UUkFDRV9MRVZFTF9FUlJPUiwgCiAgICAgICAgICAgICAgICAiJXMgIEludmFsaWQgcGFja2V0IHR5cGUoJWQpIiwgIF9fZnVuY19fLAogICAgICAgICAgICAgICAgV1BBTF9QQUNLRVRfR0VUX1RZUEUocFBrdCkpOwogICAgIHJldHVybiBlV0xBTl9QQUxfU1RBVFVTX0VfSU5WQUw7CiAgIH0KCiAgIGlmKFZPU19JU19TVEFUVVNfU1VDQ0VTUyh2b3NfcGt0X3NldF9yeF9sZW5ndGgoV1BBTF9UT19WT1NfUEtUKHBQa3QpLCBsZW4pKSkKICAgewogICAgICByZXR1cm4gZVdMQU5fUEFMX1NUQVRVU19TVUNDRVNTOwogICB9CiAgIGVsc2UKICAgewogICAgICByZXR1cm4gZVdMQU5fUEFMX1NUQVRVU19FX0lOVkFMOwogICB9Cn0vKndwYWxQYWNrZXRTZXRSeExlbmd0aCovCgovKgogIFNldCBvZiBoZWxwZXIgZnVuY3Rpb25zIHRoYXQgd2lsbCBwcmVwYXJlIHBhY2tldCBmb3IgRE1BIHRyYW5zZmVyLAogIGJhc2VkIG9uIHRoZSB0eXBlIG9mIHRyYW5zZmVyIDogLSB0byBhbmQgZnJvbSB0aGUgZGV2aWNlCiAgLSBmb2xsb3dpbmcgdGhlc2UgY2FsbHMgdGhlIHBhY2tldCB3aWxsIGJlIGxvY2tlZCBmb3IgRE1BIG9ubHksCiAgQ1BVIHdpbGwgbm90IGJlIGFibGUgdG8gbW9kaWZ5IGl0ID0+IHRoZSBwYWNrZXQgbXVzdCBiZSBleHBsaWNpdGx5IHJldHVybmVkIHRvCiAgdGhlIENQVSBvbmNlIHRoZSBETUEgdHJhbnNmZXIgaXMgY29tcGxldGUKKi8KV1BUX1NUQVRJQyBXUFRfSU5MSU5FIHZvaWQqIGl0R2V0T1NQa3RBZGRyRm9yRGV2aWNlKCB3cHRfcGFja2V0ICpwUGFja2V0ICkKewogICBzdHJ1Y3Qgc2tfYnVmZiAqc2tiOwogICBzdHJ1Y3QgZGV2aWNlICp3Y25zc19kZXZpY2UgPSAoc3RydWN0IGRldmljZSAqKWdDb250ZXh0LmRldkhhbmRsZTsKICAgLyotIC0gLSAtIC0gLSAtIC0gLSAtIC0gLSAtIC0gLSAtIC0gLSAtIC0gLSAtIC0gLSAtIC0gLSAtIC0gLSAtIC0gLSAqLwoKICAgaWYgKCBWT1NfU1RBVFVTX1NVQ0NFU1MgIT0gCiAgICAgICAgdm9zX3BrdF9nZXRfb3NfcGFja2V0KFdQQUxfVE9fVk9TX1BLVChwUGFja2V0KSwgKHZvaWQqKikmc2tiLCBWT1NfRkFMU0UgKSkKICAgewogICAgIHJldHVybiBOVUxMOwogICB9CiAgIGVsc2UKICAgewogICAgIC8qTWFwIHNrYiBkYXRhIGludG8gZG1hLWFibGUgbWVtb3J5IAogICAgICAgKGNoYW5nZXMgd2lsbCBiZSBjb21taXRlZCBmcm9tIGNhY2hlKSAqLwogICAgIHJldHVybiAodm9pZCopZG1hX21hcF9zaW5nbGUoIHdjbnNzX2RldmljZSwgc2tiLT5kYXRhLCBza2ItPmxlbiwgRE1BX1RPX0RFVklDRSApOwogICB9Cn0vKml0R2V0T1NQa3RBZGRyRm9yRGV2aWNlKi8KCldQVF9TVEFUSUMgV1BUX0lOTElORSB2b2lkKiBpdEdldE9TUGt0QWRkckZyb21EZXZpY2UoIHdwdF9wYWNrZXQgKnBQYWNrZXQgKQp7CiAgIHN0cnVjdCBza19idWZmICpza2I7CiAgIHN0cnVjdCBkZXZpY2UgKndjbnNzX2RldmljZSA9IChzdHJ1Y3QgZGV2aWNlICopZ0NvbnRleHQuZGV2SGFuZGxlOwogICAvKi0gLSAtIC0gLSAtIC0gLSAtIC0gLSAtIC0gLSAtIC0gLSAtIC0gLSAtIC0gLSAtIC0gLSAtIC0gLSAtIC0gLSAtICovCgogICBpZiAoIFZPU19TVEFUVVNfU1VDQ0VTUyAhPSAKICAgICAgICB2b3NfcGt0X2dldF9vc19wYWNrZXQoV1BBTF9UT19WT1NfUEtUKHBQYWNrZXQpLCAodm9pZCoqKSZza2IsIFZPU19GQUxTRSApKQogICB7CiAgICAgcmV0dXJuIE5VTEw7CiAgIH0KICAgZWxzZQogICB7CiAgICAgaWYoKHVpbnRwdHJfdClza2ItPmRhdGEgPT0gKHVpbnRwdHJfdClza2ItPnRhaWwpCiAgICAgewojaWZkZWYgV0xBTl9CVUdfT05fU0tCX0VSUk9SCiAgICAgICB3cGFsRGV2aWNlUGFuaWMoKTsKI2Vsc2UKICAgICAgIFdQQUxfVFJBQ0UoZVdMQU5fTU9EVUxFX1BBTCwgZVdMQU5fUEFMX1RSQUNFX0xFVkVMX0ZBVEFMLAogICAgICAgICAgICAgICAgIiVzOiBza2ItPmRhdGEgPT0gc2tiLT50YWlsLiBBdHRlbXB0aW5nIHJlY292ZXJ5ICIKICAgICAgICAgICAgICAgICJza2I6JXAsIGhlYWQ6JXAsIHRhaWw6JXAsIGRhdGE6JXAiLAogICAgICAgICAgICAgICAgICBfX2Z1bmNfXywgc2tiLCBza2ItPmhlYWQsIHNrYi0+dGFpbCwgc2tiLT5kYXRhKTsKCiAgICAgIHNrYi0+ZGF0YSA9IHNrYi0+aGVhZDsKI2VuZGlmCiAgICAgfQogICAgIC8qTWFwIHNrYiBkYXRhIGludG8gZG1hLWFibGUgbWVtb3J5IAogICAgICAgKGNoYW5nZXMgd2lsbCBiZSBjb21taXRlZCBmcm9tIGNhY2hlKSAqLwogICAgIHJldHVybiAodm9pZCopZG1hX21hcF9zaW5nbGUoIHdjbnNzX2RldmljZSwgc2tiLT5kYXRhLCBza2ItPmxlbiwgRE1BX0ZST01fREVWSUNFICk7CiAgIH0KfS8qaXRHZXRPU1BrdEFkZHJGcm9tRGV2aWNlKi8KCi8qCiAgU2V0IG9mIGhlbHBlciBmdW5jdGlvbnMgdGhhdCB3aWxsIHJldHVybiBhIERNQS1lZCBwYWNrZXQgdG8gdGhlIENQVSwKICBiYXNlZCBvbiB0aGUgdHlwZSBvZiB0cmFuc2ZlciA6IC0gdG8gYW5kIGZyb20gdGhlIGRldmljZQoqLwpXUFRfU1RBVElDIFdQVF9JTkxJTkUgdm9pZCBpdFJldHVybk9TUGt0QWRkckZvckRldmljZSggd3B0X3BhY2tldCAqcFBhY2tldCwgIHZvaWQqIGFkZHIsIHdwdF91aW50MzIgc2l6ZSApCnsKICAgc3RydWN0IGRldmljZSAqd2Nuc3NfZGV2aWNlID0gKHN0cnVjdCBkZXZpY2UgKilnQ29udGV4dC5kZXZIYW5kbGU7CgogICBkbWFfdW5tYXBfc2luZ2xlKCB3Y25zc19kZXZpY2UsIChkbWFfYWRkcl90KWFkZHIsIHNpemUsIERNQV9UT19ERVZJQ0UgKTsKfQoKV1BUX1NUQVRJQyBXUFRfSU5MSU5FIHZvaWQgaXRSZXR1cm5PU1BrdEFkZHJGcm9tRGV2aWNlKCB3cHRfcGFja2V0ICpwUGFja2V0LCB2b2lkKiBhZGRyLCB3cHRfdWludDMyIHNpemUgICkKewogICBzdHJ1Y3QgZGV2aWNlICp3Y25zc19kZXZpY2UgPSAoc3RydWN0IGRldmljZSAqKWdDb250ZXh0LmRldkhhbmRsZTsKCiAgIGRtYV91bm1hcF9zaW5nbGUoIHdjbnNzX2RldmljZSwgKGRtYV9hZGRyX3QpYWRkciwgc2l6ZSwgRE1BX0ZST01fREVWSUNFICk7Cn0KCgovKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogICAgd3BhbEl0ZXJhdG9ySW5pdCCWIEluaXRpYWxpemUgYW4gaW50ZXJhdG9yIGJ5IHVwZGF0aW5nIHBDdXIgdG8gZmlyc3QgaXRlbS4KICAgIFBhcmFtOiAKICAgICAgICBwSXRlciCWIHBvaW50ZXIgdG8gYSBjYWxsZXIgYWxsb2NhdGVkIHdwdF9pdGVyYXRvcgogICAgICAgIHBQYWNrZXQgliBwb2ludGVyIHRvIGEgd3B0X3BhY2tldAogICAgUmV0dXJuOgogICAgICAgIGVXTEFOX1BBTF9TVEFUVVNfU1VDQ0VTUyAtIHN1Y2Nlc3MKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8Kd3B0X3N0YXR1cyB3cGFsSXRlcmF0b3JJbml0KHdwdF9pdGVyYXRvciAqcEl0ZXIsIHdwdF9wYWNrZXQgKnBQYWNrZXQpCnsKICAgd3B0X3N0YXR1cyAgICAgICAgIHN0YXR1cyAgICAgPSBlV0xBTl9QQUxfU1RBVFVTX1NVQ0NFU1M7CiAgIHdwdF9pdGVyYXRvcl9pbmZvKiBwQ3VySW5mbyAgID0gTlVMTDsKICAgd3B0X2l0ZXJhdG9yX2luZm8qIHBOZXh0SW5mbyAgPSBOVUxMOwogICB3cHRfaXRlcmF0b3JfaW5mbyogcFBrdEluZm8gICA9IE5VTEw7CgogICAvLyBWYWxpZGF0ZSB0aGUgcGFyYW1ldGVyIHBvaW50ZXJzCiAgIGlmICh1bmxpa2VseSgoTlVMTCA9PSBwUGFja2V0KXx8KE5VTEw9PXBJdGVyKSkpCiAgIHsKICAgICAgV1BBTF9UUkFDRShlV0xBTl9NT0RVTEVfUEFMLCBlV0xBTl9QQUxfVFJBQ0VfTEVWRUxfRVJST1IsCiAgICAgICAgICAgICAgICAiJXMgOiBOVUxMIGlucHV0IHBvaW50ZXJzICVwICVwIiwgX19mdW5jX18sIHBQYWNrZXQsIHBJdGVyKTsKICAgICAgcmV0dXJuIGVXTEFOX1BBTF9TVEFUVVNfRV9JTlZBTDsKICAgfQoKICAgcFBrdEluZm8gPSAod3B0X2l0ZXJhdG9yX2luZm8qKXBQYWNrZXQtPnBJbnRlcm5hbERhdGE7CiAgIGlmICh1bmxpa2VseShOVUxMID09IHBQa3RJbmZvKSkKICAgewogICAgICBXUEFMX1RSQUNFKGVXTEFOX01PRFVMRV9QQUwsIGVXTEFOX1BBTF9UUkFDRV9MRVZFTF9FUlJPUiwKICAgICAgICAgICAgICAgICIlcyA6IEludmFsaWQgUGFja2V0IEluZm8iLCBfX2Z1bmNfXyk7CiAgICAgIHJldHVybiBlV0xBTl9QQUxfU1RBVFVTX0VfSU5WQUw7CiAgIH0KCiAgIC8vIGlmIHRoZXJlIGlzIE5PIEJEIG9uIHRoaXMgZnJhbWUsIHRoZW4gaW5pdGlhbGl6ZSB0aGUgbmV4dCBwb2ludGVyIHRvCiAgIC8vIHBvaW50IHRoZSBmaXJzdCBmcmFnbWVudC4KICAgaWYgKCBOVUxMID09IFdQQUxfUEFDS0VUX0dFVF9CRF9QSFlTKHBQYWNrZXQpICkKICAgewogICAgIHBDdXJJbmZvICAgPSBwUGt0SW5mbzsKICAgICBwTmV4dEluZm8gICAgICAgICAgID0gTlVMTDsKICAgfQogICBlbHNlCiAgIHsKICAgICAvKkFsbG9jYXRlIG1lbW9yeSBmb3IgdGhlIGN1cnJlbnQgaW5mbyovCiAgICAgcEN1ckluZm8gPSB3cGFsTWVtb3J5QWxsb2NhdGUoIHNpemVvZih3cHRfaXRlcmF0b3JfaW5mbykgKTsKCiAgICAgLy8gVmFsaWRhdGUgdGhlIG1lbW9yeSBhbGxvY2F0aW9uCiAgICAgaWYgKHVubGlrZWx5KE5VTEwgPT0gcEN1ckluZm8pKQogICAgIHsKICAgICAgICBXUEFMX1RSQUNFKGVXTEFOX01PRFVMRV9QQUwsIGVXTEFOX1BBTF9UUkFDRV9MRVZFTF9FUlJPUiwKICAgICAgICAgICAgICAgICAgIiVzIDogRmFpbGVkIHRvIGFsbG9jYXRlIG1lbW9yeSAiLCBfX2Z1bmNfXyk7CiAgICAgICAgcmV0dXJuIGVXTEFOX1BBTF9TVEFUVVNfRV9JTlZBTDsKICAgICB9CgogICAgIHBDdXJJbmZvLT5wUGh5QWRkciA9IFdQQUxfUEFDS0VUX0dFVF9CRF9QSFlTKHBQYWNrZXQpOwogICAgIHBDdXJJbmZvLT51TGVuICAgICA9IFdQQUxfUEFDS0VUX0dFVF9CRF9MRU5HVEgocFBhY2tldCk7CgogICAgIHBOZXh0SW5mbyAgICAgICAgICAgPSBwUGt0SW5mbzsKICAgfSAgICAgIAoKICAgcEl0ZXItPnBDdXIgICAgID0gKHZvaWQqKXBDdXJJbmZvOyAKICAgcEl0ZXItPnBOZXh0ICAgID0gKHZvaWQqKXBOZXh0SW5mbzsKICAgcEl0ZXItPnBDb250ZXh0ID0gTlVMTDsKCiAgIHJldHVybiBzdGF0dXM7Cn0vKndwYWxJdGVyYXRvckluaXQqLwoKLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAgIHdwYWxJdGVyYXRvck5leHQgliBHZXQgdGhlIGFkZHJlc3MgZm9yIHRoZSBuZXh0IGl0ZW0KICAgIFBhcmFtOiAKICAgICAgICBwSXRlciCWIHBvaW50ZXIgdG8gYSBjYWxsZXIgYWxsb2NhdGVkIHdwdF9pdGVyYXRvcgogICAgICAgIHBQYWNrZXQgliBwb2ludGVyIHRvIGEgd3B0X3BhY2tldAogICAgICAgIHBwQWRkciCWIENhbGxlciBhbGxvY2F0ZWQgcG9pbnRlciB0byByZXR1cm4gdGhlIGFkZHJlc3Mgb2YgdGhlIGl0ZW0uCiAgICAgICAgRm9yIERNQS1hYmxlIGRldmljZXMsIHRoaXMgaXMgdGhlIHBoeXNpY2FsIGFkZHJlc3Mgb2YgdGhlIGl0ZW0uCiAgICAgICAgcExlbiCWIFRvIHJldHVybiB0aGUgbnVtYmVyIG9mIGJ5dGVzIGluIHRoZSBpdGVtLgogICAgUmV0dXJuOgogICAgICAgIGVXTEFOX1BBTF9TVEFUVVNfU1VDQ0VTUyAtIHN1Y2Nlc3MKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8Kd3B0X3N0YXR1cyB3cGFsSXRlcmF0b3JOZXh0KHdwdF9pdGVyYXRvciAqcEl0ZXIsIHdwdF9wYWNrZXQgKnBQYWNrZXQsIHZvaWQgKipwcEFkZHIsIHdwdF91aW50MzIgKnBMZW4pCnsKICAgd3B0X2l0ZXJhdG9yX2luZm8qIHBDdXJJbmZvICA9IE5VTEw7CiAgIC8qLSAtIC0gLSAtIC0gLSAtIC0gLSAtIC0gLSAtIC0gLSAtIC0gLSAtIC0gLSAtIC0gLSAtIC0gLSAtIC0gLSAtIC0gLSAtIC0qLwogICAKICAgLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgICAgU2FuaXR5IGNoZWNrCiAgIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwogICBpZiAodW5saWtlbHkoKCBOVUxMID09IHBJdGVyICl8fCggTlVMTCA9PSBwUGFja2V0ICkgfHwgCiAgICAgICggTlVMTCA9PSBwcEFkZHIgKSB8fCAoIE5VTEwgPT0gcExlbiApKSkKICAgewogICAgIFdQQUxfVFJBQ0UoZVdMQU5fTU9EVUxFX1BBTCwgZVdMQU5fUEFMX1RSQUNFX0xFVkVMX0VSUk9SLCAKICAgICAgICAgICAgICAgICIlcyAgSW52YWxpZCBpbnB1dCBwYXJhbWV0ZXJzIiwgIF9fZnVuY19fICk7CiAgICAgcmV0dXJuIGVXTEFOX1BBTF9TVEFUVVNfRV9JTlZBTDsKICAgfQoKICAgcEN1ckluZm8gPSAod3B0X2l0ZXJhdG9yX2luZm8qKXBJdGVyLT5wQ3VyOyAKICAgLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgICAgSWYgY3VycmVudCBwb2ludGVyIGlzIE5VTEwgLSB0aGVyZSBpcyBubyBkYXRhIGluIHRoZSBwYWNrZXQgLSByZXR1cm4KICAgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCiAgIGlmKCBwSXRlci0+cEN1ciA9PSBOVUxMICkKICAgewogICAgICAqcHBBZGRyID0gTlVMTDsgCiAgICAgICpwTGVuICAgPSAwOwogICAgICByZXR1cm4gZVdMQU5fUEFMX1NUQVRVU19TVUNDRVNTOwogICB9CgogICAvKkFkZHJlc3MgYW5kIGxlbmd0aCBhcmUga2VwdCBpbiB0aGUgY3VycmVudCBmaWVsZCovCiAgICpwcEFkZHIgPSBwQ3VySW5mby0+cFBoeUFkZHI7IAogICAqcExlbiAgID0gcEN1ckluZm8tPnVMZW47CiAgICAKICAgaWYoIE5VTEwgPT0gcEl0ZXItPnBOZXh0ICkKICAgewogICAgIC8qU2F2ZSB0aGUgaXRlcmF0b3IgZm9yIGNsZWFudXAqLwogICAgIHBQYWNrZXQtPnBJbnRlcm5hbERhdGEgPSBwSXRlci0+cEN1cjsgCiAgICAgcEl0ZXItPnBDdXIgICAgICAgICAgICA9IE5VTEw7IAogICB9CiAgIGVsc2UKICAgewogICAgIC8qUmVsZWFzZSB0aGUgbWVtb3J5IHNhdmVkIGZvciBzdG9yaW5nIHRoZSBCRCBpbmZvcm1hdGlvbiovCiAgICAgd3BhbE1lbW9yeUZyZWUocEN1ckluZm8pOyAKICAKICAgICAvKkZvciBMQSAtIHRoZSBwYWNrZXQgaXMgcmVwcmVzZW50ZWQgYnkgbWF4aW11bSAyIGZpZWxkcyBvZiBkYXRhIAogICAgICAgLSBCRCBhbmQgYWN0dWFsIGRhdGEgZnJvbSBzayBidWZmICovCiAgICAgcEl0ZXItPnBDdXIgICAgID0gcEl0ZXItPnBOZXh0OwogICAgIHBJdGVyLT5wTmV4dCAgICA9IE5VTEw7CiAgIH0KICAgCiAgIHJldHVybiBlV0xBTl9QQUxfU1RBVFVTX1NVQ0NFU1M7Cn0KCi8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgICB3cGFsTG9ja1BhY2tldEZvclRyYW5zZmVyIJYgTWFwIHRoZSBkYXRhIGJ1ZmZlciBmcm9tIGRtYSBzbyB0aGF0IHRoZQogICAgICAgICAgICAgICAgICAgICAgICAgZGF0YSBpcyBjb21taXRlZCBmcm9tIGNhY2hlIGFuZCB0aGUgY3B1IHJlbGlucXVpc2hlcwogICAgICAgICAgICAgICAgICAgICAgICAgb3duZXJzaGlwIG9mIHRoZSBidWZmZXIKIAogICAgUGFyYW06IAogICAgICAgIHBQYWNrZXQgliBwb2ludGVyIHRvIGEgd3B0X3BhY2tldAogCiAgICBSZXR1cm46CiAgICAgICAgZVdMQU5fUEFMX1NUQVRVU19TVUNDRVNTIC0gc3VjY2VzcwotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwp3cHRfc3RhdHVzIHdwYWxMb2NrUGFja2V0Rm9yVHJhbnNmZXIoIHdwdF9wYWNrZXQgKnBQYWNrZXQpCnsKICAgdm9pZCogICAgICAgICAgICAgIHBQaHlEYXRhICAgPSBOVUxMOwogICB3cHRfaXRlcmF0b3JfaW5mbyogcEluZm8gICAgICA9IE5VTEw7CiAgIHZfVTE2X3QgICAgICAgICAgICB1TGVuRGF0YSAgID0gMDsKCiAgIC8vIFZhbGlkYXRlIHRoZSBwYXJhbWV0ZXIgcG9pbnRlcnMKICAgaWYgKHVubGlrZWx5KE5VTEwgPT0gcFBhY2tldCkpCiAgIHsKICAgICAgV1BBTF9UUkFDRShlV0xBTl9NT0RVTEVfUEFMLCBlV0xBTl9QQUxfVFJBQ0VfTEVWRUxfRVJST1IsCiAgICAgICAgICAgICAgICAiJXMgOiBOVUxMIGlucHV0IHBvaW50ZXIiLCBfX2Z1bmNfXyk7CiAgICAgIHJldHVybiBlV0xBTl9QQUxfU1RBVFVTX0VfSU5WQUw7CiAgIH0KCiAgIHN3aXRjaChXUEFMX1BBQ0tFVF9HRVRfVFlQRShwUGFja2V0KSkKICAgewogICAgICAvKiBGb3IgbWFuYWdlbWVudCBmcmFtZXMsIEJEIGlzIGFsbG9jYXRlZCBieSBXREksIGhlYWRlciBpcyBpbiByYXcgYnVmZmVyLAogICAgICAgICByZXN0IG9mIHRoZSBmcmFtZSBpcyBhbHNvIGluIHJhdyBidWZmZXIgKi8KICAgY2FzZSBlV0xBTl9QQUxfUEtUX1RZUEVfVFhfODAyXzExX01HTVQ6CiAgICAgIHsKICAgICAgICAgLypUWCBQYWNrZXRzIG5lZWQgdG8gYmUgRE1BLWVkIHRvIHRoZSBkZXZpY2UsIHBlcmZvcm0gRE1BIG1hcHBpbmcgCiAgICAgICAgICAgYWNjb3JkaW5nbHkgKi8KICAgICAgICAgcFBoeURhdGEgPSAodm9pZCopaXRHZXRPU1BrdEFkZHJGb3JEZXZpY2UoIHBQYWNrZXQgKTsgICAKICAgICAgfQogICAgICBicmVhazsKICAgICAgICAgLyogRGF0YSBwYWNrZXRzIC0gQkQgKGFsbG9jYXRlZCBieSBXREkpLCBoZWFkZXIgKGluIFZPU1MgaGVhZGVyKSwKICAgICAgICAgICAgcmVzdCBvZiB0aGUgcGFja2V0IChEU00gaXRlbXMpICovCiAgIGNhc2UgZVdMQU5fUEFMX1BLVF9UWVBFX1RYXzgwMl8xMV9EQVRBOgogICBjYXNlIGVXTEFOX1BBTF9QS1RfVFlQRV9UWF84MDJfM19EQVRBOgogICAgICB7CiAgICAgICAgIC8qVFggUGFja2V0cyBuZWVkIHRvIGJlIERNQS1lZCB0byB0aGUgZGV2aWNlLCBwZXJmb3JtIERNQSBtYXBwaW5nIAogICAgICAgICAgIGFjY29yZGluZ2x5ICovCiAgICAgICAgIHBQaHlEYXRhID0gKHZvaWQqKWl0R2V0T1NQa3RBZGRyRm9yRGV2aWNlKCBwUGFja2V0ICk7CiAgICAgIH0KICAgICAgYnJlYWs7CgogICAgICAvKiBGb3IgUmF3IFJYLCBCRCArIGhlYWRlciArIHJlc3Qgb2YgdGhlIHBhY2tldCBpcyBhbGwgY29udGFpbmVkIGluIHRoZSByYXcKICAgICAgICAgYnVmZmVyICovCiAgIGNhc2UgZVdMQU5fUEFMX1BLVF9UWVBFX1JYX1JBVzoKICAgICAgewogICAgICAgICAvKlJYIFBhY2tldHMgbmVlZCB0byBiZSBETUEtZWQgZnJvbSB0aGUgZGV2aWNlLCBwZXJmb3JtIERNQSBtYXBwaW5nIAogICAgICAgICAgIGFjY29yZGluZ2x5ICovCiAgICAgICAgIHBQaHlEYXRhID0gKHZvaWQqKWl0R2V0T1NQa3RBZGRyRnJvbURldmljZSggcFBhY2tldCApOwogICAgICB9CiAgICAgIGJyZWFrOwoKICAgZGVmYXVsdDoKICAgICAgewogICAgICAgICBXUEFMX1RSQUNFKGVXTEFOX01PRFVMRV9QQUwsIGVXTEFOX1BBTF9UUkFDRV9MRVZFTF9FUlJPUiwgCiAgICAgICAgICAgICAgICAgICAgIiBXTEFOX1BBTDogJXM6IEludmFsaWQgcGFja2V0IHR5cGUgJWQhIiwgIF9fZnVuY19fLCAKICAgICAgICAgICAgICAgICAgICBXUEFMX1BBQ0tFVF9HRVRfVFlQRShwUGFja2V0KSApOyAKICAgICAgICAgV1BBTF9BU1NFUlQoMCk7IAogICAgICAgICByZXR1cm4gZVdMQU5fUEFMX1NUQVRVU19FX0ZBSUxVUkU7CiAgICAgIH0KICAgfQoKICAgLypHZXQgcGFja2V0IGxlbmd0aCovCiAgIHZvc19wa3RfZ2V0X3BhY2tldF9sZW5ndGgoV1BBTF9UT19WT1NfUEtUKHBQYWNrZXQpLCZ1TGVuRGF0YSk7CgogICAgLypBbGxvY2F0ZSBtZW1vcnkgZm9yIHRoZSBjdXJyZW50IGluZm8qLwogICBwSW5mbyA9IHdwYWxNZW1vcnlBbGxvY2F0ZSggc2l6ZW9mKHdwdF9pdGVyYXRvcl9pbmZvKSApOwoKICAgLy8gVmFsaWRhdGUgdGhlIG1lbW9yeSBhbGxvY2F0aW9uCiAgIGlmICh1bmxpa2VseShOVUxMID09IHBJbmZvKSkKICAgewogICAgICBXUEFMX1RSQUNFKGVXTEFOX01PRFVMRV9QQUwsIGVXTEFOX1BBTF9UUkFDRV9MRVZFTF9FUlJPUiwKICAgICAgICAgICAgICAgICIlcyA6IEZhaWxlZCB0byBhbGxvY2F0ZSBtZW1vcnkgIiwgX19mdW5jX18pOwogICAgICByZXR1cm4gZVdMQU5fUEFMX1NUQVRVU19FX0lOVkFMOwogICB9CgogICBwSW5mby0+cFBoeUFkZHIgPSBwUGh5RGF0YTsKICAgcEluZm8tPnVMZW4gICAgID0gdUxlbkRhdGE7CgogICBwUGFja2V0LT5wSW50ZXJuYWxEYXRhID0gcEluZm87CiAgIHJldHVybiBlV0xBTl9QQUxfU1RBVFVTX1NVQ0NFU1M7Cn0vKndwYWxMb2NrUGFja2V0Rm9yVHJhbnNmZXIqLwoKLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAgIHdwYWxVbmxvY2tQYWNrZXQgliBVbm1hcCB0aGUgZGF0YSBidWZmZXIgZnJvbSBkbWEgc28gdGhhdCBjcHUgY2FuIHJlZ2FpbgogICAgICAgICAgICAgICAgICAgICAgICAgIG93bmVyc2hpcCBvbiBpdAogICAgUGFyYW06IAogICAgICAgIHBQYWNrZXQgliBwb2ludGVyIHRvIGEgd3B0X3BhY2tldAogCiAgICBSZXR1cm46CiAgICAgICAgZVdMQU5fUEFMX1NUQVRVU19TVUNDRVNTIC0gc3VjY2VzcwotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwp3cHRfc3RhdHVzIHdwYWxVbmxvY2tQYWNrZXQoIHdwdF9wYWNrZXQgKnBQYWNrZXQpCnsKCiAgIHdwdF9pdGVyYXRvcl9pbmZvKiBwSW5mbzsKCiAgIC8vIFZhbGlkYXRlIHRoZSBwYXJhbWV0ZXIgcG9pbnRlcnMKICAgaWYgKHVubGlrZWx5KE5VTEwgPT0gcFBhY2tldCkpCiAgIHsKICAgICAgV1BBTF9UUkFDRShlV0xBTl9NT0RVTEVfUEFMLCBlV0xBTl9QQUxfVFJBQ0VfTEVWRUxfRVJST1IsCiAgICAgICAgICAgICAgICAiJXMgOiBOVUxMIGlucHV0IHBvaW50ZXIgcFBhY2tldCIsIF9fZnVuY19fKTsKICAgICAgcmV0dXJuIGVXTEFOX1BBTF9TVEFUVVNfRV9JTlZBTDsKICAgfQoKICAgcEluZm8gID0gKHdwdF9pdGVyYXRvcl9pbmZvKilwUGFja2V0LT5wSW50ZXJuYWxEYXRhOwoKICAgLy8gVmFsaWRhdGUgcEluZm8KICAgaWYgKHVubGlrZWx5KE5VTEwgPT0gcEluZm8pKQogICB7CiAgICAgIFdQQUxfVFJBQ0UoZVdMQU5fTU9EVUxFX1BBTCwgZVdMQU5fUEFMX1RSQUNFX0xFVkVMX0ZBVEFMLAogICAgICAgICAgICAgICAgIiVzIDogTlVMTCBpbnB1dCBwb2ludGVyIHBJbmZvIiwgX19mdW5jX18pOwogICAgICByZXR1cm4gZVdMQU5fUEFMX1NUQVRVU19FX0lOVkFMOwogICB9CgogICBzd2l0Y2goV1BBTF9QQUNLRVRfR0VUX1RZUEUocFBhY2tldCkpCiAgIHsKICAgICAgLyogRm9yIG1hbmFnZW1lbnQgZnJhbWVzLCBCRCBpcyBhbGxvY2F0ZWQgYnkgV0RJLCBoZWFkZXIgaXMgaW4gcmF3IGJ1ZmZlciwKICAgICAgICAgcmVzdCBvZiB0aGUgZnJhbWUgaXMgYWxzbyBpbiByYXcgYnVmZmVyICovCiAgIGNhc2UgZVdMQU5fUEFMX1BLVF9UWVBFX1RYXzgwMl8xMV9NR01UOgogICAgICB7CiAgICAgICAgIC8qVFggUGFja2V0cyBuZWVkIHRvIGJlIERNQS1lZCB0byB0aGUgZGV2aWNlLCBwZXJmb3JtIERNQSBtYXBwaW5nIAogICAgICAgICAgIGFjY29yZGluZ2x5ICovCiAgICAgICAgaXRSZXR1cm5PU1BrdEFkZHJGb3JEZXZpY2UocFBhY2tldCwgcEluZm8tPnBQaHlBZGRyLCBwSW5mby0+dUxlbik7ICAgCiAgICAgIH0KICAgICAgYnJlYWs7CiAgICAgICAgIC8qIERhdGEgcGFja2V0cyAtIEJEIChhbGxvY2F0ZWQgYnkgV0RJKSwgaGVhZGVyIChpbiBWT1NTIGhlYWRlciksCiAgICAgICAgICAgIHJlc3Qgb2YgdGhlIHBhY2tldCAoRFNNIGl0ZW1zKSAqLwogICBjYXNlIGVXTEFOX1BBTF9QS1RfVFlQRV9UWF84MDJfMTFfREFUQToKICAgY2FzZSBlV0xBTl9QQUxfUEtUX1RZUEVfVFhfODAyXzNfREFUQToKICAgICAgewogICAgICAgICAvKlRYIFBhY2tldHMgbmVlZCB0byBiZSBETUEtZWQgdG8gdGhlIGRldmljZSwgcGVyZm9ybSBETUEgbWFwcGluZyAKICAgICAgICAgICBhY2NvcmRpbmdseSAqLwogICAgICAgICBpdFJldHVybk9TUGt0QWRkckZvckRldmljZShwUGFja2V0LCBwSW5mby0+cFBoeUFkZHIsIHBJbmZvLT51TGVuKTsgICAKICAgICAgfQogICAgICBicmVhazsKCiAgICAgIC8qIEZvciBSYXcgUlgsIEJEICsgaGVhZGVyICsgcmVzdCBvZiB0aGUgcGFja2V0IGlzIGFsbCBjb250YWluZWQgaW4gdGhlIHJhdwogICAgICAgICBidWZmZXIgKi8KICAgY2FzZSBlV0xBTl9QQUxfUEtUX1RZUEVfUlhfUkFXOgogICAgICB7CiAgICAgICAgIC8qUlggUGFja2V0cyBuZWVkIHRvIGJlIERNQS1lZCBmcm9tIHRoZSBkZXZpY2UsIHBlcmZvcm0gRE1BIG1hcHBpbmcgCiAgICAgICAgICAgYWNjb3JkaW5nbHkgKi8KICAgICAgICAgaWYoTlVMTCA9PSBwSW5mby0+cFBoeUFkZHIpCiAgICAgICAgIHsKICAgICAgICAgICAgV1BBTF9UUkFDRShlV0xBTl9NT0RVTEVfUEFMLCBlV0xBTl9QQUxfVFJBQ0VfTEVWRUxfRVJST1IsIAogICAgICAgICAgICAgICAgICAgICAgICIgV0xBTl9QQUw6ICVzOiBSWCBmcmFtZSB3YXMgbm90IGxvY2tlZCBwcm9wZXJseSIsICBfX2Z1bmNfXyk7IAogICAgICAgICB9CiAgICAgICAgIGVsc2UKICAgICAgICAgewogICAgICAgICAgICBpdFJldHVybk9TUGt0QWRkckZyb21EZXZpY2UocFBhY2tldCwgcEluZm8tPnBQaHlBZGRyLCBwSW5mby0+dUxlbik7ICAgCiAgICAgICAgIH0KICAgICAgfQogICAgICBicmVhazsKCiAgIGRlZmF1bHQ6CiAgICAgIHsKICAgICAgICAgV1BBTF9UUkFDRShlV0xBTl9NT0RVTEVfUEFMLCBlV0xBTl9QQUxfVFJBQ0VfTEVWRUxfRVJST1IsIAogICAgICAgICAgICAgICAgICAgICIgV0xBTl9QQUw6ICVzOiBJbnZhbGlkIHBhY2tldCB0eXBlICVkISIsICBfX2Z1bmNfXywgCiAgICAgICAgICAgICAgICAgICAgV1BBTF9QQUNLRVRfR0VUX1RZUEUocFBhY2tldCkgKTsgCiAgICAgICAgIFdQQUxfQVNTRVJUKDApOyAKICAgICAgICAgcmV0dXJuIGVXTEFOX1BBTF9TVEFUVVNfRV9GQUlMVVJFOwogICAgICB9CiAgIH0KCiAgd3BhbE1lbW9yeUZyZWUocEluZm8pOwogIHBQYWNrZXQtPnBJbnRlcm5hbERhdGEgPSBOVUxMOwogIHJldHVybiBlV0xBTl9QQUxfU1RBVFVTX1NVQ0NFU1M7Cn0vKndwYWxVbmxvY2tQYWNrZXQqLwoKLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAgIHdwYWxJc1BhY2tldExvY2tlZCCWICBDaGVjayB3aGV0aGVyIHRoZSBQYWNrZXQgaXMgbG9ja2VkIGZvciBETUEuCiAgICBQYXJhbTogCiAgICAgICAgcFBhY2tldCCWIHBvaW50ZXIgdG8gYSB3cHRfcGFja2V0CiAKICAgIFJldHVybjoKICAgICAgICBlV0xBTl9QQUxfU1RBVFVTX1NVQ0NFU1MKICAgICAgICBlV0xBTl9QQUxfU1RBVFVTX0VfRkFJTFVSRQogICAgICAgIGVXTEFOX1BBTF9TVEFUVVNfRV9JTlZBTAotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwp3cHRfc3RhdHVzIHdwYWxJc1BhY2tldExvY2tlZCggd3B0X3BhY2tldCAqcFBhY2tldCkKewoKICAgd3B0X2l0ZXJhdG9yX2luZm8qIHBJbmZvOwoKICAgLyogVmFsaWRhdGUgdGhlIHBhcmFtZXRlciBwb2ludGVycyAqLwogICBpZiAoTlVMTCA9PSBwUGFja2V0KQogICB7CiAgICAgIFdQQUxfVFJBQ0UoZVdMQU5fTU9EVUxFX1BBTCwgZVdMQU5fUEFMX1RSQUNFX0xFVkVMX1dBUk4sCiAgICAgICAgICAgICAgICAiJXMgOiBOVUxMIGlucHV0IHBvaW50ZXIiLCBfX2Z1bmNfXyk7CiAgICAgIHJldHVybiBlV0xBTl9QQUxfU1RBVFVTX0VfSU5WQUw7CiAgIH0KCiAgIC8qIFZhbGlkYXRlIHBJbnRlcm5hbERhdGEgKi8KICAgcEluZm8gID0gKHdwdF9pdGVyYXRvcl9pbmZvKilwUGFja2V0LT5wSW50ZXJuYWxEYXRhOwogICByZXR1cm4gKE5VTEwgPT0gcEluZm8pPyBlV0xBTl9QQUxfU1RBVFVTX0VfRkFJTFVSRSA6IAogICAgICAgICAgICAgICAgICAgIGVXTEFOX1BBTF9TVEFUVVNfU1VDQ0VTUzsKfS8qd3BhbElzUGFja2V0TG9ja2VkKi8KCi8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgIHdwYWxHZXROdW1SeFJhd1BhY2tldCAgIFF1ZXJ5IGF2YWlsYWJsZSBSWCBSQVcgdG90YWwgYnVmZmVyIGNvdW50CiAgIHBhcmFtOgogICAgICAgbnVtUnhSZXNvdXJjZSAgcG9pbnRlciBvZiBxdWVyaWVkIHZhbHVlCgogICByZXR1cm46CiAgICAgICBlV0xBTl9QQUxfU1RBVFVTX1NVQ0NFU1MKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8Kd3B0X3N0YXR1cyB3cGFsR2V0TnVtUnhSYXdQYWNrZXQod3B0X3VpbnQzMiAqbnVtUnhSZXNvdXJjZSkKewogICAqbnVtUnhSZXNvdXJjZSA9ICh3cHRfdWludDMyKXZvc19wa3RfZ2V0X251bV9vZl9yeF9yYXdfcGt0cygpOwoKICAgcmV0dXJuIGVXTEFOX1BBTF9TVEFUVVNfU1VDQ0VTUzsKfQoKLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAgd3BhbEdldE51bVJ4UGFja2V0QWxsb2NGYWlsdXJlcyAgIEdldCBudW1iZXIgb2YgdGltZXMgcGFja2V0IGFsbG9jIGZhaWxlZAogICAgICAgbnVtUnhSZXNvdXJjZSAgcG9pbnRlciBvZiBxdWVyaWVkIHZhbHVlCgogICByZXR1cm46CiAgICAgICBlV0xBTl9QQUxfU1RBVFVTX1NVQ0NFU1MKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8Kd3B0X3N0YXR1cyB3cGFsR2V0TnVtUnhQYWNrZXRBbGxvY0ZhaWx1cmVzKHdwdF91aW50MzIgKm51bVJ4UmVzb3VyY2UpCnsKICAgKm51bVJ4UmVzb3VyY2UgPSAod3B0X3VpbnQzMil2b3NfcGt0X2dldF9udW1fb2ZfcnhfcGt0X2FsbG9jX2ZhaWx1cmVzKCk7CgogICByZXR1cm4gZVdMQU5fUEFMX1NUQVRVU19TVUNDRVNTOwp9Ci8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgIHdwYWxHZXROdW1SeEZyZWVQYWNrZXQgICBRdWVyeSBhdmFpbGFibGUgUlggRnJlZSBidWZmZXIgY291bnQKICAgcGFyYW06CiAgICAgICBudW1SeFJlc291cmNlICBwb2ludGVyIG9mIHF1ZXJpZWQgdmFsdWUKCiAgIHJldHVybjoKICAgICAgIFdQVF9TVEFUVVMKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8Kd3B0X3N0YXR1cyB3cGFsR2V0TnVtUnhGcmVlUGFja2V0KHdwdF91aW50MzIgKm51bVJ4UmVzb3VyY2UpCnsKICAgVk9TX1NUQVRVUyBzdGF0dXM7CgogICBzdGF0dXMgPSB2b3NfcGt0X2dldF9hdmFpbGFibGVfYnVmZmVyX3Bvb2woVk9TX1BLVF9UWVBFX1JYX1JBVywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICh2X1NJWkVfdCAqKW51bVJ4UmVzb3VyY2UpOwoKICAgcmV0dXJuIFdQQUxfVk9TX1RPX1dQQUxfU1RBVFVTKHN0YXR1cyk7Cn0KCi8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgICB3cGFsUGFja2V0U3RhbGxVcGRhdGVJbmZvIJYgVXBkYXRlIGVhY2ggY2hhbm5lbCBpbmZvcm1hdGlvbiB3aGVuIHN0YWxsCiAgICAgICBkZXRlY3RlZCwgYWxzbyBwb3dlciBzdGF0ZSBhbmQgZnJlZSByZXNvdXJjZSBjb3VudAoKICAgIFBhcmFtOgogICAgICAgcG93ZXJTdGF0ZSAgPyBXTEFOIHN5c3RlbSBwb3dlciBzdGF0ZSB3aGVuIHN0YWxsIGRldGVjdGVkCiAgICAgICBudW1GcmVlQmQgICA/IE51bWJlciBvZiBmcmVlIHJlc291cmNlIGNvdW50IGluIEhXCiAgICAgICBjaGFubmVsSW5mbyA/IEVhY2ggY2hhbm5lbCBzcGVjaWZpYyBpbmZvcm1hdGlvbiB3aGVuIHN0YWxsIGhhcHBlbgogICAgICAgY2hhbm5lbE51bSAgPyBDaGFubmVsIG51bWJlciB1cGRhdGUgaW5mb3JtYXRpb24KCiAgICBSZXR1cm46CiAgICAgICBOT05FCgotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwp2b2lkIHdwYWxQYWNrZXRTdGFsbFVwZGF0ZUluZm8KKAogICB2X1UzMl90ICAgICAgICAgICAgICAgICAgICAgICAgICpwb3dlclN0YXRlLAogICB2X1UzMl90ICAgICAgICAgICAgICAgICAgICAgICAgICpudW1GcmVlQmQsCiAgIHdwdF9sb2dfZGF0YV9zdGFsbF9jaGFubmVsX3R5cGUgKmNoYW5uZWxJbmZvLAogICB2X1U4X3QgICAgICAgICAgICAgICAgICAgICAgICAgICBjaGFubmVsTnVtCikKewogICAvKiBVcGRhdGUgcG93ZXIgc3RhdGUgd2hlbiBzdGFsbCBkZXRlY3RlZCAqLwogICBpZihOVUxMICE9IHBvd2VyU3RhdGUpCiAgIHsKICAgICAgd3BhbFRyYXNwb3J0U3RhbGxJbmZvLlBvd2VyU3RhdGUgPSAqcG93ZXJTdGF0ZTsKICAgfQoKICAgLyogVXBkYXRlIEhXIGZyZWUgcmVzb3VyY2UgY291bnQgKi8KICAgaWYoTlVMTCAhPSBudW1GcmVlQmQpCiAgIHsKICAgICAgd3BhbFRyYXNwb3J0U3RhbGxJbmZvLm51bUZyZWVCZCAgPSAqbnVtRnJlZUJkOwogICB9CgogICAvKiBVcGRhdGUgY2hhbm5lbCBpbmZvcm1hdGlvbiAqLwogICBpZihOVUxMICE9IGNoYW5uZWxJbmZvKQogICB7CiAgICAgIHdwYWxNZW1vcnlDb3B5KCZ3cGFsVHJhc3BvcnRTdGFsbEluZm8uZHhlQ2hhbm5lbEluZm9bY2hhbm5lbE51bV0sCiAgICAgICAgICAgICAgICAgICAgIGNoYW5uZWxJbmZvLAogICAgICAgICAgICAgICAgICAgICBzaXplb2Yod3B0X2xvZ19kYXRhX3N0YWxsX2NoYW5uZWxfdHlwZSkpOwogICB9CgogICByZXR1cm47Cn0KCiNpZmRlZiBGRUFUVVJFX1dMQU5fRElBR19TVVBQT1JUCi8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgICB3cGFsUGFja2V0U3RhbGxEdW1wTG9nIJYgVHJpZ2dlciB0byBzZW5kIGxvZyBwYWNrZXQgdG8gRElBRwogICAgICAgVXBkYXRlZCB0cmFuc3BvcnQgc3lzdGVtIGluZm9ybWF0aW9uIHdpbGwgYmUgc2VudCB0byBESUFHCgogICAgUGFyYW06CiAgICAgICAgTk9ORQoKICAgIFJldHVybjoKICAgICAgICBOT05FCgotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwp2b2lkIHdwYWxQYWNrZXRTdGFsbER1bXBMb2cKKAogICB2b2lkCikKewogICB2b3NfbG9nX2RhdGFfc3RhbGxfdHlwZSAgKmxvZ19wdHIgPSBOVUxMOwoKICAgV0xBTl9WT1NfRElBR19MT0dfQUxMT0MobG9nX3B0ciwgdm9zX2xvZ19kYXRhX3N0YWxsX3R5cGUsIExPR19UUlNQX0RBVEFfU1RBTExfQyk7CiAgIGlmKGxvZ19wdHIpCiAgIHsKICAgICAgbG9nX3B0ci0+UG93ZXJTdGF0ZSA9IHdwYWxUcmFzcG9ydFN0YWxsSW5mby5Qb3dlclN0YXRlOwogICAgICBsb2dfcHRyLT5udW1GcmVlQmQgID0gd3BhbFRyYXNwb3J0U3RhbGxJbmZvLm51bUZyZWVCZDsKICAgICAgd3BhbE1lbW9yeUNvcHkoJmxvZ19wdHItPmR4ZUNoYW5uZWxJbmZvWzBdLAogICAgICAgICAgICAgICAgICAgICAmd3BhbFRyYXNwb3J0U3RhbGxJbmZvLmR4ZUNoYW5uZWxJbmZvWzBdLAogICAgICAgICAgICAgICAgICAgICBXUFRfTlVNX1RSUFRfQ0hBTk5FTCAqIHNpemVvZih2b3NfbG9nX2RhdGFfc3RhbGxfY2hhbm5lbF90eXBlKSk7CiAgICAgIHByX2luZm8oIlN0YWxsIGxvZyBkdW1wIik7CiAgICAgIFdMQU5fVk9TX0RJQUdfTE9HX1JFUE9SVChsb2dfcHRyKTsKICAgfQoKICAgcmV0dXJuOwp9CiNlbmRpZiAvKiBGRUFUVVJFX1dMQU5fRElBR19TVVBQT1JUICovCg==