LyogR1N0cmVhbWVyCiAqIENvcHlyaWdodCAoQykgMTk5OSBFcmlrIFdhbHRoaW5zZW4gPG9tZWdhQGNzZS5vZ2kuZWR1PgogKiBDb3B5cmlnaHQgKEMpIDIwMDQgV2ltIFRheW1hbnMgPHdpbS50YXltYW5zQGdtYWlsLmNvbT4KICogQ29weXJpZ2h0IChDKSAyMDA3IFBldGVyIEtqZWxsZXJzdGVkdCA8cGtqQGF4aXMuY29tPgogKiBDb3B5cmlnaHQgKEMpIDIwMDggT2xlIEFuZHLpIFZhZGxhIFJhdm7lcyA8b2xlLmFuZHJlLnJhdm5hc0B0YW5kYmVyZy5jb20+CiAqCiAqIGdzdHBvbGwuYzogRmlsZSBkZXNjcmlwdG9yIHNldAogKgogKiBUaGlzIGxpYnJhcnkgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yCiAqIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMaWJyYXJ5IEdlbmVyYWwgUHVibGljCiAqIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlcgogKiB2ZXJzaW9uIDIgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLAogKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZgogKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVQogKiBMaWJyYXJ5IEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIExpYnJhcnkgR2VuZXJhbCBQdWJsaWMKICogTGljZW5zZSBhbG9uZyB3aXRoIHRoaXMgbGlicmFyeTsgaWYgbm90LCB3cml0ZSB0byB0aGUKICogRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBJbmMuLCA1OSBUZW1wbGUgUGxhY2UgLSBTdWl0ZSAzMzAsCiAqIEJvc3RvbiwgTUEgMDIxMTEtMTMwNywgVVNBLgogKi8KLyoqCiAqIFNFQ1RJT046Z3N0cG9sbAogKiBAc2hvcnRfZGVzY3JpcHRpb246IEtlZXAgdHJhY2sgb2YgZmlsZSBkZXNjcmlwdG9ycyBhbmQgbWFrZSBpdCBwb3NzaWJsZQogKiAgICAgICAgICAgICAgICAgICAgIHRvIHdhaXQgb24gdGhlbSBpbiBhIGNhbmNlbGFibGUgd2F5CiAqCiAqIEEgI0dzdFBvbGwga2VlcHMgdHJhY2sgb2YgZmlsZSBkZXNjcmlwdG9ycyBtdWNoIGxpa2UgZmRfc2V0ICh1c2VkIHdpdGgKICogc2VsZWN0KCkpIG9yIGEgc3RydWN0IHBvbGxmZCBhcnJheSAodXNlZCB3aXRoIHBvbGwoKSkuIE9uY2UgY3JlYXRlZCB3aXRoCiAqIGdzdF9wb2xsX25ldygpLCB0aGUgc2V0IGNhbiBiZSB1c2VkIHRvIHdhaXQgZm9yIGZpbGUgZGVzY3JpcHRvcnMgdG8gYmUKICogcmVhZGFibGUgYW5kL29yIHdyaXRlYWJsZS4gSXQgaXMgcG9zc2libGUgdG8gbWFrZSB0aGlzIHdhaXQgYmUgY29udHJvbGxlZAogKiBieSBzcGVjaWZ5aW5nICVUUlVFIGZvciB0aGUgQGNvbnRyb2xsYWJsZSBmbGFnIHdoZW4gY3JlYXRpbmcgdGhlIHNldCAob3IKICogbGF0ZXIgY2FsbGluZyBnc3RfcG9sbF9zZXRfY29udHJvbGxhYmxlKCkpLgogKgogKiBOZXcgZmlsZSBkZXNjcmlwdG9ycyBhcmUgYWRkZWQgdG8gdGhlIHNldCB1c2luZyBnc3RfcG9sbF9hZGRfZmQoKSwgYW5kCiAqIHJlbW92ZWQgdXNpbmcgZ3N0X3BvbGxfcmVtb3ZlX2ZkKCkuIENvbnRyb2xsaW5nIHdoaWNoIGZpbGUgZGVzY3JpcHRvcnMKICogc2hvdWxkIGJlIHdhaXRlZCBmb3IgdG8gYmVjb21lIHJlYWRhYmxlIGFuZC9vciB3cml0ZWFibGUgYXJlIGRvbmUgdXNpbmcKICogZ3N0X3BvbGxfZmRfY3RsX3JlYWQoKSBhbmQgZ3N0X3BvbGxfZmRfY3RsX3dyaXRlKCkuCiAqCiAqIFVzZSBnc3RfcG9sbF93YWl0KCkgdG8gd2FpdCBmb3IgdGhlIGZpbGUgZGVzY3JpcHRvcnMgdG8gYWN0dWFsbHkgYmVjb21lCiAqIHJlYWRhYmxlIGFuZC9vciB3cml0ZWFibGUsIG9yIHRvIHRpbWVvdXQgaWYgbm8gZmlsZSBkZXNjcmlwdG9yIGlzIGF2YWlsYWJsZQogKiBpbiB0aW1lLiBUaGUgd2FpdCBjYW4gYmUgY29udHJvbGxlZCBieSBjYWxsaW5nIGdzdF9wb2xsX3Jlc3RhcnQoKSBhbmQKICogZ3N0X3BvbGxfc2V0X2ZsdXNoaW5nKCkuCiAqCiAqIE9uY2UgdGhlIGZpbGUgZGVzY3JpcHRvciBzZXQgaGFzIGJlZW4gd2FpdGVkIGZvciwgb25lIGNhbiB1c2UKICogZ3N0X3BvbGxfZmRfaGFzX2Nsb3NlZCgpIHRvIHNlZSBpZiB0aGUgZmlsZSBkZXNjcmlwdG9yIGhhcyBiZWVuIGNsb3NlZCwKICogZ3N0X3BvbGxfZmRfaGFzX2Vycm9yKCkgdG8gc2VlIGlmIGl0IGhhcyBnZW5lcmF0ZWQgYW4gZXJyb3IsCiAqIGdzdF9wb2xsX2ZkX2Nhbl9yZWFkKCkgdG8gc2VlIGlmIGl0IGlzIHBvc3NpYmxlIHRvIHJlYWQgZnJvbSB0aGUgZmlsZQogKiBkZXNjcmlwdG9yLCBhbmQgZ3N0X3BvbGxfZmRfY2FuX3dyaXRlKCkgdG8gc2VlIGlmIGl0IGlzIHBvc3NpYmxlIHRvCiAqIHdyaXRlIHRvIGl0LgogKgogKi8KCiNpZmRlZiBIQVZFX0NPTkZJR19ICiNpbmNsdWRlICJjb25maWcuaCIKI2VuZGlmCgojaW5jbHVkZSAiZ3N0X3ByaXZhdGUuaCIKI2luY2x1ZGUgImdsaWItY29tcGF0LXByaXZhdGUuaCIKCiNpbmNsdWRlIDxzeXMvdHlwZXMuaD4KCiNpZmRlZiBIQVZFX1VOSVNURF9ICiNpbmNsdWRlIDx1bmlzdGQuaD4KI2VuZGlmCgojaW5jbHVkZSA8ZXJybm8uaD4KI2luY2x1ZGUgPGZjbnRsLmg+CgojaW5jbHVkZSA8Z2xpYi5oPgoKI2lmZGVmIEdfT1NfV0lOMzIKI2luY2x1ZGUgPHdpbnNvY2syLmg+CiNkZWZpbmUgRUlOUFJPR1JFU1MgV1NBRUlOUFJPR1JFU1MKI2Vsc2UKI2RlZmluZSBfR05VX1NPVVJDRSAxCiNpbmNsdWRlIDxzeXMvcG9sbC5oPgojaW5jbHVkZSA8c3lzL3RpbWUuaD4KI2luY2x1ZGUgPHN5cy9zb2NrZXQuaD4KI2VuZGlmCgovKiBPUy9YIG5lZWRzIHRoaXMgYmVjYXVzZSBvZiBiYWQgaGVhZGVycyAqLwojaW5jbHVkZSA8c3RyaW5nLmg+CgovKiBUaGUgcG9sbCgpIGVtdWxhdGlvbiBvbiBPUy9YIGRvZXNuJ3QgaGFuZGxlIGZkcz1OVUxMLCBuZmRzPTAsCiAqIHNvIHdlIHByZWZlciBvdXIgb3duIHBvbGwgZW11bGF0aW9uLgogKi8KI2lmIGRlZmluZWQoQlJPS0VOX1BPTEwpCiN1bmRlZiBIQVZFX1BPTEwKI2VuZGlmCgojaW5jbHVkZSAiZ3N0cG9sbC5oIgoKI2RlZmluZSBHU1RfQ0FUX0RFRkFVTFQgR1NUX0NBVF9QT0xMCgojaWZkZWYgR19PU19XSU4zMgp0eXBlZGVmIHN0cnVjdCBfV2luc29ja0ZkIFdpbnNvY2tGZDsKCnN0cnVjdCBfV2luc29ja0ZkCnsKICBnaW50IGZkOwogIGdsb25nIGV2ZW50X21hc2s7CiAgV1NBTkVUV09SS0VWRU5UUyBldmVudHM7CiAgZ2xvbmcgaWdub3JlZF9ldmVudF9tYXNrOwp9OwojZW5kaWYKCnR5cGVkZWYgZW51bQp7CiAgR1NUX1BPTExfTU9ERV9BVVRPLAogIEdTVF9QT0xMX01PREVfU0VMRUNULAogIEdTVF9QT0xMX01PREVfUFNFTEVDVCwKICBHU1RfUE9MTF9NT0RFX1BPTEwsCiAgR1NUX1BPTExfTU9ERV9QUE9MTCwKICBHU1RfUE9MTF9NT0RFX1dJTkRPV1MKfSBHc3RQb2xsTW9kZTsKCnN0cnVjdCBfR3N0UG9sbAp7CiAgR3N0UG9sbE1vZGUgbW9kZTsKCiAgR011dGV4ICpsb2NrOwogIC8qIGFycmF5IG9mIGZkcywgYWx3YXlzIHdyaXR0ZW4gdG8gYW5kIHJlYWQgZnJvbSB3aXRoIGxvY2sgKi8KICBHQXJyYXkgKmZkczsKICAvKiBhcnJheSBvZiBhY3RpdmUgZmRzLCBvbmx5IHdyaXR0ZW4gdG8gZnJvbSB0aGUgd2FpdGluZyB0aHJlYWQgd2l0aCB0aGUKICAgKiBsb2NrIGFuZCByZWFkIGZyb20gd2l0aCB0aGUgbG9jayBvciB3aXRob3V0IHRoZSBsb2NrIGZyb20gdGhlIHdhaXRpbmcKICAgKiB0aHJlYWQgKi8KICBHQXJyYXkgKmFjdGl2ZV9mZHM7CgojaWZuZGVmIEdfT1NfV0lOMzIKICBnY2hhciBidWZbMV07CiAgR3N0UG9sbEZEIGNvbnRyb2xfcmVhZF9mZDsKICBHc3RQb2xsRkQgY29udHJvbF93cml0ZV9mZDsKI2Vsc2UKICBHQXJyYXkgKmFjdGl2ZV9mZHNfaWdub3JlZDsKICBHQXJyYXkgKmV2ZW50czsKICBHQXJyYXkgKmFjdGl2ZV9ldmVudHM7CgogIEhBTkRMRSB3YWtldXBfZXZlbnQ7CiNlbmRpZgoKICBnYm9vbGVhbiBjb250cm9sbGFibGU7CiAgdm9sYXRpbGUgZ2ludCB3YWl0aW5nOwogIHZvbGF0aWxlIGdpbnQgY29udHJvbF9wZW5kaW5nOwogIHZvbGF0aWxlIGdpbnQgZmx1c2hpbmc7CiAgZ2Jvb2xlYW4gdGltZXI7CiAgdm9sYXRpbGUgZ2ludCByZWJ1aWxkOwp9OwoKc3RhdGljIGdib29sZWFuIGdzdF9wb2xsX2ZkX2N0bF9yZWFkX3VubG9ja2VkIChHc3RQb2xsICogc2V0LCBHc3RQb2xsRkQgKiBmZCwKICAgIGdib29sZWFuIGFjdGl2ZSk7CnN0YXRpYyBnYm9vbGVhbiBnc3RfcG9sbF9hZGRfZmRfdW5sb2NrZWQgKEdzdFBvbGwgKiBzZXQsIEdzdFBvbGxGRCAqIGZkKTsKCiNkZWZpbmUgSVNfRkxVU0hJTkcocykgICAgICAoZ19hdG9taWNfaW50X2dldCgmKHMpLT5mbHVzaGluZykpCiNkZWZpbmUgU0VUX0ZMVVNISU5HKHMsdmFsKSAoZ19hdG9taWNfaW50X3NldCgmKHMpLT5mbHVzaGluZywgKHZhbCkpKQoKI2RlZmluZSBJTkNfV0FJVElORyhzKSAgICAgIChHX0FUT01JQ19JTlRfQUREKCYocyktPndhaXRpbmcsIDEpKQojZGVmaW5lIERFQ19XQUlUSU5HKHMpICAgICAgKEdfQVRPTUlDX0lOVF9BREQoJihzKS0+d2FpdGluZywgLTEpKQojZGVmaW5lIEdFVF9XQUlUSU5HKHMpICAgICAgKGdfYXRvbWljX2ludF9nZXQoJihzKS0+d2FpdGluZykpCgojZGVmaW5lIFRFU1RfUkVCVUlMRChzKSAgICAgKGdfYXRvbWljX2ludF9jb21wYXJlX2FuZF9leGNoYW5nZSgmKHMpLT5yZWJ1aWxkLCAxLCAwKSkKI2RlZmluZSBNQVJLX1JFQlVJTEQocykgICAgIChnX2F0b21pY19pbnRfc2V0KCYocyktPnJlYnVpbGQsIDEpKQoKI2lmbmRlZiBHX09TX1dJTjMyCiNkZWZpbmUgV0FLRV9FVkVOVChzKSAgICAgICAod3JpdGUgKChzKS0+Y29udHJvbF93cml0ZV9mZC5mZCwgIlciLCAxKSA9PSAxKQojZGVmaW5lIFJFTEVBU0VfRVZFTlQocykgICAgKHJlYWQgKChzKS0+Y29udHJvbF9yZWFkX2ZkLmZkLCAocyktPmJ1ZiwgMSkgPT0gMSkKI2Vsc2UKI2RlZmluZSBXQUtFX0VWRU5UKHMpICAgICAgIChTZXRFdmVudCAoKHMpLT53YWtldXBfZXZlbnQpLCBlcnJubyA9IEdldExhc3RFcnJvciAoKSA9PSBOT19FUlJPUiA/IDAgOiBFQUNDRVMsIGVycm5vID09IDAgPyAxIDogMCkKI2RlZmluZSBSRUxFQVNFX0VWRU5UKHMpICAgIChSZXNldEV2ZW50ICgocyktPndha2V1cF9ldmVudCkpCiNlbmRpZgoKLyogdGhlIHBvbGwvc2VsZWN0IGNhbGwgaXMgYWxzbyBwZXJmb3JtZWQgb24gYSBjb250cm9sIHNvY2tldCwgdGhhdCB3YXkKICogd2UgY2FuIHNlbmQgc3BlY2lhbCBjb21tYW5kcyB0byBjb250cm9sIGl0ICovCnN0YXRpYyBpbmxpbmUgZ2Jvb2xlYW4KcmFpc2Vfd2FrZXVwIChHc3RQb2xsICogc2V0KQp7CiAgZ2Jvb2xlYW4gcmVzdWx0ID0gVFJVRTsKCiAgaWYgKEdfQVRPTUlDX0lOVF9BREQgKCZzZXQtPmNvbnRyb2xfcGVuZGluZywgMSkgPT0gMCkgewogICAgLyogcmFpc2Ugd2hlbiBub3RoaW5nIHBlbmRpbmcgKi8KICAgIEdTVF9MT0cgKCIlcDogcmFpc2UiLCBzZXQpOwogICAgcmVzdWx0ID0gV0FLRV9FVkVOVCAoc2V0KTsKICB9CiAgcmV0dXJuIHJlc3VsdDsKfQoKLyogbm90ZSBob3cgYmFkIHRoaW5ncyBjYW4gaGFwcGVuIHdoZW4gdGhlIDIgdGhyZWFkcyBib3RoIHJhaXNlIGFuZCByZWxlYXNlIHRoZQogKiB3YWtldXAuIFRoaXMgaXMgaG93ZXZlciBub3QgYSBwcm9ibGVtIGJlY2F1c2UgeW91IG11c3QgYWx3YXlzIHBhaXIgYSByYWlzZQogKiB3aXRoIGEgcmVsZWFzZSAqLwpzdGF0aWMgaW5saW5lIGdib29sZWFuCnJlbGVhc2Vfd2FrZXVwIChHc3RQb2xsICogc2V0KQp7CiAgZ2Jvb2xlYW4gcmVzdWx0ID0gVFJVRTsKCiAgaWYgKGdfYXRvbWljX2ludF9kZWNfYW5kX3Rlc3QgKCZzZXQtPmNvbnRyb2xfcGVuZGluZykpIHsKICAgIEdTVF9MT0cgKCIlcDogcmVsZWFzZSIsIHNldCk7CiAgICByZXN1bHQgPSBSRUxFQVNFX0VWRU5UIChzZXQpOwogIH0KICByZXR1cm4gcmVzdWx0Owp9CgpzdGF0aWMgaW5saW5lIGdpbnQKcmVsZWFzZV9hbGxfd2FrZXVwIChHc3RQb2xsICogc2V0KQp7CiAgZ2ludCBvbGQ7CgogIHdoaWxlIChUUlVFKSB7CiAgICBpZiAoIShvbGQgPSBnX2F0b21pY19pbnRfZ2V0ICgmc2V0LT5jb250cm9sX3BlbmRpbmcpKSkKICAgICAgLyogbm90aGluZyBwZW5kaW5nLCBqdXN0IGV4aXQgKi8KICAgICAgYnJlYWs7CgogICAgLyogdHJ5IHRvIHJlbW92ZSBhbGwgcGVuZGluZyBjb250cm9sIG1lc3NhZ2VzICovCiAgICBpZiAoZ19hdG9taWNfaW50X2NvbXBhcmVfYW5kX2V4Y2hhbmdlICgmc2V0LT5jb250cm9sX3BlbmRpbmcsIG9sZCwgMCkpIHsKICAgICAgLyogd2UgbWFuYWdlZCB0byByZW1vdmUgYWxsIG1lc3NhZ2VzLCByZWFkIHRoZSBjb250cm9sIHNvY2tldCAqLwogICAgICBpZiAoUkVMRUFTRV9FVkVOVCAoc2V0KSkKICAgICAgICBicmVhazsKICAgICAgZWxzZQogICAgICAgIC8qIHJldHJ5IGFnYWluIHVudGlsIHdlIHJlYWQgaXQgc3VjY2Vzc2Z1bGx5ICovCiAgICAgICAgR19BVE9NSUNfSU5UX0FERCAoJnNldC0+Y29udHJvbF9wZW5kaW5nLCAxKTsKICAgIH0KICB9CiAgcmV0dXJuIG9sZDsKfQoKc3RhdGljIGdpbnQKZmluZF9pbmRleCAoR0FycmF5ICogYXJyYXksIEdzdFBvbGxGRCAqIGZkKQp7CiNpZm5kZWYgR19PU19XSU4zMgogIHN0cnVjdCBwb2xsZmQgKmlmZDsKI2Vsc2UKICBXaW5zb2NrRmQgKmlmZDsKI2VuZGlmCiAgZ3VpbnQgaTsKCiAgLyogc3RhcnQgYnkgYXNzdW1pbmcgdGhlIGluZGV4IGZvdW5kIGluIHRoZSBmZCBpcyBzdGlsbCB2YWxpZCAqLwogIGlmIChmZC0+aWR4ID49IDAgJiYgZmQtPmlkeCA8IGFycmF5LT5sZW4pIHsKI2lmbmRlZiBHX09TX1dJTjMyCiAgICBpZmQgPSAmZ19hcnJheV9pbmRleCAoYXJyYXksIHN0cnVjdCBwb2xsZmQsIGZkLT5pZHgpOwojZWxzZQogICAgaWZkID0gJmdfYXJyYXlfaW5kZXggKGFycmF5LCBXaW5zb2NrRmQsIGZkLT5pZHgpOwojZW5kaWYKCiAgICBpZiAoaWZkLT5mZCA9PSBmZC0+ZmQpIHsKICAgICAgcmV0dXJuIGZkLT5pZHg7CiAgICB9CiAgfQoKICAvKiB0aGUgcG9sbGZkIGFycmF5IGhhcyBjaGFuZ2VkIGFuZCB3ZSBuZWVkIHRvIGxvb2t1cCB0aGUgZmQgYWdhaW4gKi8KICBmb3IgKGkgPSAwOyBpIDwgYXJyYXktPmxlbjsgaSsrKSB7CiNpZm5kZWYgR19PU19XSU4zMgogICAgaWZkID0gJmdfYXJyYXlfaW5kZXggKGFycmF5LCBzdHJ1Y3QgcG9sbGZkLCBpKTsKI2Vsc2UKICAgIGlmZCA9ICZnX2FycmF5X2luZGV4IChhcnJheSwgV2luc29ja0ZkLCBpKTsKI2VuZGlmCgogICAgaWYgKGlmZC0+ZmQgPT0gZmQtPmZkKSB7CiAgICAgIGZkLT5pZHggPSAoZ2ludCkgaTsKICAgICAgcmV0dXJuIGZkLT5pZHg7CiAgICB9CiAgfQoKICBmZC0+aWR4ID0gLTE7CiAgcmV0dXJuIGZkLT5pZHg7Cn0KCiNpZiAhZGVmaW5lZChIQVZFX1BQT0xMKSAmJiBkZWZpbmVkKEhBVkVfUE9MTCkKLyogY2hlY2sgaWYgYWxsIGZpbGUgZGVzY3JpcHRvcnMgd2lsbCBmaXQgaW4gYW4gZmRfc2V0ICovCnN0YXRpYyBnYm9vbGVhbgpzZWxlY3RhYmxlX2ZkcyAoY29uc3QgR3N0UG9sbCAqIHNldCkKewogIGd1aW50IGk7CgogIGdfbXV0ZXhfbG9jayAoc2V0LT5sb2NrKTsKICBmb3IgKGkgPSAwOyBpIDwgc2V0LT5mZHMtPmxlbjsgaSsrKSB7CiAgICBzdHJ1Y3QgcG9sbGZkICpwZmQgPSAmZ19hcnJheV9pbmRleCAoc2V0LT5mZHMsIHN0cnVjdCBwb2xsZmQsIGkpOwoKICAgIGlmIChwZmQtPmZkID49IEZEX1NFVFNJWkUpCiAgICAgIGdvdG8gdG9vX21hbnk7CiAgfQogIGdfbXV0ZXhfdW5sb2NrIChzZXQtPmxvY2spOwoKICByZXR1cm4gVFJVRTsKCnRvb19tYW55OgogIHsKICAgIGdfbXV0ZXhfdW5sb2NrIChzZXQtPmxvY2spOwogICAgcmV0dXJuIEZBTFNFOwogIH0KfQoKLyogY2hlY2sgaWYgdGhlIHRpbWVvdXQgd2lsbCBjb252ZXJ0IHRvIGEgdGltZW91dCB2YWx1ZSB1c2VkIGZvciBwb2xsKCkKICogd2l0aG91dCBhIGxvc3Mgb2YgcHJlY2lzaW9uCiAqLwpzdGF0aWMgZ2Jvb2xlYW4KcG9sbGFibGVfdGltZW91dCAoR3N0Q2xvY2tUaW1lIHRpbWVvdXQpCnsKICBpZiAodGltZW91dCA9PSBHU1RfQ0xPQ0tfVElNRV9OT05FKQogICAgcmV0dXJuIFRSVUU7CgogIC8qIG5vdCBhIG5pY2UgbXVsdGlwbGUgb2YgbWlsbGlzZWNvbmRzICovCiAgaWYgKHRpbWVvdXQgJSAxMDAwMDAwKQogICAgcmV0dXJuIEZBTFNFOwoKICByZXR1cm4gVFJVRTsKfQojZW5kaWYKCnN0YXRpYyBHc3RQb2xsTW9kZQpjaG9vc2VfbW9kZSAoY29uc3QgR3N0UG9sbCAqIHNldCwgR3N0Q2xvY2tUaW1lIHRpbWVvdXQpCnsKICBHc3RQb2xsTW9kZSBtb2RlOwoKICBpZiAoc2V0LT5tb2RlID09IEdTVF9QT0xMX01PREVfQVVUTykgewojaWZkZWYgSEFWRV9QUE9MTAogICAgbW9kZSA9IEdTVF9QT0xMX01PREVfUFBPTEw7CiNlbGlmIGRlZmluZWQoSEFWRV9QT0xMKQogICAgaWYgKCFzZWxlY3RhYmxlX2ZkcyAoc2V0KSB8fCBwb2xsYWJsZV90aW1lb3V0ICh0aW1lb3V0KSkgewogICAgICBtb2RlID0gR1NUX1BPTExfTU9ERV9QT0xMOwogICAgfSBlbHNlIHsKI2lmZGVmIEhBVkVfUFNFTEVDVAogICAgICBtb2RlID0gR1NUX1BPTExfTU9ERV9QU0VMRUNUOwojZWxzZQogICAgICBtb2RlID0gR1NUX1BPTExfTU9ERV9TRUxFQ1Q7CiNlbmRpZgogICAgfQojZWxpZiBkZWZpbmVkKEhBVkVfUFNFTEVDVCkKICAgIG1vZGUgPSBHU1RfUE9MTF9NT0RFX1BTRUxFQ1Q7CiNlbHNlCiAgICBtb2RlID0gR1NUX1BPTExfTU9ERV9TRUxFQ1Q7CiNlbmRpZgogIH0gZWxzZSB7CiAgICBtb2RlID0gc2V0LT5tb2RlOwogIH0KICByZXR1cm4gbW9kZTsKfQoKI2lmbmRlZiBHX09TX1dJTjMyCnN0YXRpYyBnaW50CnBvbGxmZF90b19mZF9zZXQgKEdzdFBvbGwgKiBzZXQsIGZkX3NldCAqIHJlYWRmZHMsIGZkX3NldCAqIHdyaXRlZmRzLAogICAgZmRfc2V0ICogZXJyb3JmZHMpCnsKICBnaW50IG1heF9mZCA9IC0xOwogIGd1aW50IGk7CgogIEZEX1pFUk8gKHJlYWRmZHMpOwogIEZEX1pFUk8gKHdyaXRlZmRzKTsKICBGRF9aRVJPIChlcnJvcmZkcyk7CgogIGdfbXV0ZXhfbG9jayAoc2V0LT5sb2NrKTsKCiAgZm9yIChpID0gMDsgaSA8IHNldC0+YWN0aXZlX2Zkcy0+bGVuOyBpKyspIHsKICAgIHN0cnVjdCBwb2xsZmQgKnBmZCA9ICZnX2FycmF5X2luZGV4IChzZXQtPmZkcywgc3RydWN0IHBvbGxmZCwgaSk7CgogICAgaWYgKHBmZC0+ZmQgPCBGRF9TRVRTSVpFKSB7CiAgICAgIGlmIChwZmQtPmV2ZW50cyAmIFBPTExJTikKICAgICAgICBGRF9TRVQgKHBmZC0+ZmQsIHJlYWRmZHMpOwogICAgICBpZiAocGZkLT5ldmVudHMgJiBQT0xMT1VUKQogICAgICAgIEZEX1NFVCAocGZkLT5mZCwgd3JpdGVmZHMpOwogICAgICBpZiAocGZkLT5ldmVudHMpCiAgICAgICAgRkRfU0VUIChwZmQtPmZkLCBlcnJvcmZkcyk7CiAgICAgIGlmIChwZmQtPmZkID4gbWF4X2ZkICYmIChwZmQtPmV2ZW50cyAmIChQT0xMSU4gfCBQT0xMT1VUKSkpCiAgICAgICAgbWF4X2ZkID0gcGZkLT5mZDsKICAgIH0KICB9CgogIGdfbXV0ZXhfdW5sb2NrIChzZXQtPmxvY2spOwoKICByZXR1cm4gbWF4X2ZkOwp9CgpzdGF0aWMgdm9pZApmZF9zZXRfdG9fcG9sbGZkIChHc3RQb2xsICogc2V0LCBmZF9zZXQgKiByZWFkZmRzLCBmZF9zZXQgKiB3cml0ZWZkcywKICAgIGZkX3NldCAqIGVycm9yZmRzKQp7CiAgZ3VpbnQgaTsKCiAgZ19tdXRleF9sb2NrIChzZXQtPmxvY2spOwoKICBmb3IgKGkgPSAwOyBpIDwgc2V0LT5hY3RpdmVfZmRzLT5sZW47IGkrKykgewogICAgc3RydWN0IHBvbGxmZCAqcGZkID0gJmdfYXJyYXlfaW5kZXggKHNldC0+YWN0aXZlX2Zkcywgc3RydWN0IHBvbGxmZCwgaSk7CgogICAgaWYgKHBmZC0+ZmQgPCBGRF9TRVRTSVpFKSB7CiAgICAgIHBmZC0+cmV2ZW50cyA9IDA7CiAgICAgIGlmIChGRF9JU1NFVCAocGZkLT5mZCwgcmVhZGZkcykpCiAgICAgICAgcGZkLT5yZXZlbnRzIHw9IFBPTExJTjsKICAgICAgaWYgKEZEX0lTU0VUIChwZmQtPmZkLCB3cml0ZWZkcykpCiAgICAgICAgcGZkLT5yZXZlbnRzIHw9IFBPTExPVVQ7CiAgICAgIGlmIChGRF9JU1NFVCAocGZkLT5mZCwgZXJyb3JmZHMpKQogICAgICAgIHBmZC0+cmV2ZW50cyB8PSBQT0xMRVJSOwogICAgfQogIH0KCiAgZ19tdXRleF91bmxvY2sgKHNldC0+bG9jayk7Cn0KI2Vsc2UgLyogR19PU19XSU4zMiAqLwovKgogKiBUcmFuc2xhdGUgZXJyb3JzIHRocm93biBieSB0aGUgV2luc29jayBBUEkgdXNlZCBieSBHc3RQb2xsOgogKiAgIFdTQUV2ZW50U2VsZWN0LCBXU0FXYWl0Rm9yTXVsdGlwbGVFdmVudHMgYW5kIFdTQUVudW1OZXR3b3JrRXZlbnRzCiAqLwpzdGF0aWMgZ2ludApnc3RfcG9sbF93aW5zb2NrX2Vycm9yX3RvX2Vycm5vIChEV09SRCBsYXN0X2Vycm9yKQp7CiAgc3dpdGNoIChsYXN0X2Vycm9yKSB7CiAgICBjYXNlIFdTQV9JTlZBTElEX0hBTkRMRToKICAgIGNhc2UgV1NBRUlOVkFMOgogICAgY2FzZSBXU0FFTk9UU09DSzoKICAgICAgcmV0dXJuIEVCQURGOwoKICAgIGNhc2UgV1NBX05PVF9FTk9VR0hfTUVNT1JZOgogICAgICByZXR1cm4gRU5PTUVNOwoKICAgICAgLyoKICAgICAgICogQW55dGhpbmcgZWxzZSwgaW5jbHVkaW5nOgogICAgICAgKiAgIFdTQV9JTlZBTElEX1BBUkFNRVRFUiwgV1NBRUZBVUxULCBXU0FFSU5QUk9HUkVTUywgV1NBRU5FVERPV04sCiAgICAgICAqICAgV1NBTk9USU5JVElBTElTRUQKICAgICAgICovCiAgICBkZWZhdWx0OgogICAgICByZXR1cm4gRUlOVkFMOwogIH0KfQoKc3RhdGljIHZvaWQKZ3N0X3BvbGxfZnJlZV93aW5zb2NrX2V2ZW50IChHc3RQb2xsICogc2V0LCBnaW50IGlkeCkKewogIFdpbnNvY2tGZCAqd2ZkID0gJmdfYXJyYXlfaW5kZXggKHNldC0+ZmRzLCBXaW5zb2NrRmQsIGlkeCk7CiAgSEFORExFIGV2ZW50ID0gZ19hcnJheV9pbmRleCAoc2V0LT5ldmVudHMsIEhBTkRMRSwgaWR4KTsKCiAgV1NBRXZlbnRTZWxlY3QgKHdmZC0+ZmQsIGV2ZW50LCAwKTsKICBDbG9zZUhhbmRsZSAoZXZlbnQpOwp9CgpzdGF0aWMgdm9pZApnc3RfcG9sbF91cGRhdGVfd2luc29ja19ldmVudF9tYXNrIChHc3RQb2xsICogc2V0LCBnaW50IGlkeCwgZ2xvbmcgZmxhZ3MsCiAgICBnYm9vbGVhbiBhY3RpdmUpCnsKICBXaW5zb2NrRmQgKndmZDsKCiAgd2ZkID0gJmdfYXJyYXlfaW5kZXggKHNldC0+ZmRzLCBXaW5zb2NrRmQsIGlkeCk7CgogIGlmIChhY3RpdmUpCiAgICB3ZmQtPmV2ZW50X21hc2sgfD0gZmxhZ3M7CiAgZWxzZQogICAgd2ZkLT5ldmVudF9tYXNrICY9IH5mbGFnczsKCiAgLyogcmVzZXQgaWdub3JlZCBzdGF0ZSBpZiB0aGUgbmV3IG1hc2sgZG9lc24ndCBvdmVybGFwIGF0IGFsbCAqLwogIGlmICgod2ZkLT5pZ25vcmVkX2V2ZW50X21hc2sgJiB3ZmQtPmV2ZW50X21hc2spID09IDApCiAgICB3ZmQtPmlnbm9yZWRfZXZlbnRfbWFzayA9IDA7Cn0KCnN0YXRpYyBnYm9vbGVhbgpnc3RfcG9sbF9wcmVwYXJlX3dpbnNvY2tfYWN0aXZlX3NldHMgKEdzdFBvbGwgKiBzZXQpCnsKICBndWludCBpOwoKICBnX2FycmF5X3NldF9zaXplIChzZXQtPmFjdGl2ZV9mZHMsIDApOwogIGdfYXJyYXlfc2V0X3NpemUgKHNldC0+YWN0aXZlX2Zkc19pZ25vcmVkLCAwKTsKICBnX2FycmF5X3NldF9zaXplIChzZXQtPmFjdGl2ZV9ldmVudHMsIDApOwogIGdfYXJyYXlfYXBwZW5kX3ZhbCAoc2V0LT5hY3RpdmVfZXZlbnRzLCBzZXQtPndha2V1cF9ldmVudCk7CgogIGZvciAoaSA9IDA7IGkgPCBzZXQtPmZkcy0+bGVuOyBpKyspIHsKICAgIFdpbnNvY2tGZCAqd2ZkID0gJmdfYXJyYXlfaW5kZXggKHNldC0+ZmRzLCBXaW5zb2NrRmQsIGkpOwogICAgSEFORExFIGV2ZW50ID0gZ19hcnJheV9pbmRleCAoc2V0LT5ldmVudHMsIEhBTkRMRSwgaSk7CgogICAgaWYgKHdmZC0+aWdub3JlZF9ldmVudF9tYXNrID09IDApIHsKICAgICAgZ2ludCByZXQ7CgogICAgICBnX2FycmF5X2FwcGVuZF92YWwgKHNldC0+YWN0aXZlX2ZkcywgKndmZCk7CiAgICAgIGdfYXJyYXlfYXBwZW5kX3ZhbCAoc2V0LT5hY3RpdmVfZXZlbnRzLCBldmVudCk7CgogICAgICByZXQgPSBXU0FFdmVudFNlbGVjdCAod2ZkLT5mZCwgZXZlbnQsIHdmZC0+ZXZlbnRfbWFzayk7CiAgICAgIGlmIChHX1VOTElLRUxZIChyZXQgIT0gMCkpIHsKICAgICAgICBlcnJubyA9IGdzdF9wb2xsX3dpbnNvY2tfZXJyb3JfdG9fZXJybm8gKFdTQUdldExhc3RFcnJvciAoKSk7CiAgICAgICAgcmV0dXJuIEZBTFNFOwogICAgICB9CiAgICB9IGVsc2UgewogICAgICBnX2FycmF5X2FwcGVuZF92YWwgKHNldC0+YWN0aXZlX2Zkc19pZ25vcmVkLCB3ZmQpOwogICAgfQogIH0KCiAgcmV0dXJuIFRSVUU7Cn0KCnN0YXRpYyBnaW50CmdzdF9wb2xsX2NvbGxlY3Rfd2luc29ja19ldmVudHMgKEdzdFBvbGwgKiBzZXQpCnsKICBnaW50IHJlcywgaTsKCiAgLyoKICAgKiBXZSBuZWVkIHRvIGNoZWNrIHdoaWNoIGV2ZW50cyBhcmUgc2lnbmFsZWQsIGFuZCBjYWxsCiAgICogV1NBRW51bU5ldHdvcmtFdmVudHMgZm9yIHRob3NlIHRoYXQgYXJlLCB3aGljaCByZXNldHMKICAgKiB0aGUgZXZlbnQgYW5kIGNsZWFycyB0aGUgaW50ZXJuYWwgbmV0d29yayBldmVudCByZWNvcmRzLgogICAqLwogIHJlcyA9IDA7CiAgZm9yIChpID0gMDsgaSA8IHNldC0+YWN0aXZlX2Zkcy0+bGVuOyBpKyspIHsKICAgIFdpbnNvY2tGZCAqd2ZkID0gJmdfYXJyYXlfaW5kZXggKHNldC0+YWN0aXZlX2ZkcywgV2luc29ja0ZkLCBpKTsKICAgIEhBTkRMRSBldmVudCA9IGdfYXJyYXlfaW5kZXggKHNldC0+YWN0aXZlX2V2ZW50cywgSEFORExFLCBpICsgMSk7CiAgICBEV09SRCB3YWl0X3JldDsKCiAgICB3YWl0X3JldCA9IFdhaXRGb3JTaW5nbGVPYmplY3QgKGV2ZW50LCAwKTsKICAgIGlmICh3YWl0X3JldCA9PSBXQUlUX09CSkVDVF8wKSB7CiAgICAgIGdpbnQgZW51bV9yZXQgPSBXU0FFbnVtTmV0d29ya0V2ZW50cyAod2ZkLT5mZCwgZXZlbnQsICZ3ZmQtPmV2ZW50cyk7CgogICAgICBpZiAoR19VTkxJS0VMWSAoZW51bV9yZXQgIT0gMCkpIHsKICAgICAgICByZXMgPSAtMTsKICAgICAgICBlcnJubyA9IGdzdF9wb2xsX3dpbnNvY2tfZXJyb3JfdG9fZXJybm8gKFdTQUdldExhc3RFcnJvciAoKSk7CiAgICAgICAgYnJlYWs7CiAgICAgIH0KCiAgICAgIHJlcysrOwogICAgfSBlbHNlIHsKICAgICAgLyogY2xlYXIgYW55IHByZXZpb3VzbHkgc3RvcmVkIHJlc3VsdCAqLwogICAgICBtZW1zZXQgKCZ3ZmQtPmV2ZW50cywgMCwgc2l6ZW9mICh3ZmQtPmV2ZW50cykpOwogICAgfQogIH0KCiAgLyogSWYgYWxsIHdlbnQgd2VsbCB3ZSBhbHNvIG5lZWQgdG8gcmVzZXQgdGhlIGlnbm9yZWQgZmRzLiAqLwogIGlmIChyZXMgPj0gMCkgewogICAgcmVzICs9IHNldC0+YWN0aXZlX2Zkc19pZ25vcmVkLT5sZW47CgogICAgZm9yIChpID0gMDsgaSA8IHNldC0+YWN0aXZlX2Zkc19pZ25vcmVkLT5sZW47IGkrKykgewogICAgICBXaW5zb2NrRmQgKndmZCA9IGdfYXJyYXlfaW5kZXggKHNldC0+YWN0aXZlX2Zkc19pZ25vcmVkLCBXaW5zb2NrRmQgKiwgaSk7CgogICAgICB3ZmQtPmlnbm9yZWRfZXZlbnRfbWFzayA9IDA7CiAgICB9CgogICAgZ19hcnJheV9zZXRfc2l6ZSAoc2V0LT5hY3RpdmVfZmRzX2lnbm9yZWQsIDApOwogIH0KCiAgcmV0dXJuIHJlczsKfQojZW5kaWYKCi8qKgogKiBnc3RfcG9sbF9uZXc6CiAqIEBjb250cm9sbGFibGU6IHdoZXRoZXIgaXQgc2hvdWxkIGJlIHBvc3NpYmxlIHRvIGNvbnRyb2wgYSB3YWl0LgogKgogKiBDcmVhdGUgYSBuZXcgZmlsZSBkZXNjcmlwdG9yIHNldC4gSWYgQGNvbnRyb2xsYWJsZSwgaXQKICogaXMgcG9zc2libGUgdG8gcmVzdGFydCBvciBmbHVzaCBhIGNhbGwgdG8gZ3N0X3BvbGxfd2FpdCgpIHdpdGgKICogZ3N0X3BvbGxfcmVzdGFydCgpIGFuZCBnc3RfcG9sbF9zZXRfZmx1c2hpbmcoKSByZXNwZWN0aXZlbHkuCiAqCiAqIEZyZWUtZnVuY3Rpb246IGdzdF9wb2xsX2ZyZWUKICoKICogUmV0dXJuczogKHRyYW5zZmVyIGZ1bGwpOiBhIG5ldyAjR3N0UG9sbCwgb3IgJU5VTEwgaW4gY2FzZSBvZiBhbiBlcnJvci4KICogICAgIEZyZWUgd2l0aCBnc3RfcG9sbF9mcmVlKCkuCiAqCiAqIFNpbmNlOiAwLjEwLjE4CiAqLwpHc3RQb2xsICoKZ3N0X3BvbGxfbmV3IChnYm9vbGVhbiBjb250cm9sbGFibGUpCnsKICBHc3RQb2xsICpuc2V0OwoKICBHU1RfREVCVUcgKCJjb250cm9sbGFibGUgOiAlZCIsIGNvbnRyb2xsYWJsZSk7CgogIG5zZXQgPSBnX3NsaWNlX25ldzAgKEdzdFBvbGwpOwogIG5zZXQtPmxvY2sgPSBnX211dGV4X25ldyAoKTsKI2lmbmRlZiBHX09TX1dJTjMyCiAgbnNldC0+bW9kZSA9IEdTVF9QT0xMX01PREVfQVVUTzsKICBuc2V0LT5mZHMgPSBnX2FycmF5X25ldyAoRkFMU0UsIEZBTFNFLCBzaXplb2YgKHN0cnVjdCBwb2xsZmQpKTsKICBuc2V0LT5hY3RpdmVfZmRzID0gZ19hcnJheV9uZXcgKEZBTFNFLCBGQUxTRSwgc2l6ZW9mIChzdHJ1Y3QgcG9sbGZkKSk7CiAgbnNldC0+Y29udHJvbF9yZWFkX2ZkLmZkID0gLTE7CiAgbnNldC0+Y29udHJvbF93cml0ZV9mZC5mZCA9IC0xOwogIHsKICAgIGdpbnQgY29udHJvbF9zb2NrWzJdOwoKICAgIGlmIChzb2NrZXRwYWlyIChQRl9VTklYLCBTT0NLX1NUUkVBTSwgMCwgY29udHJvbF9zb2NrKSA8IDApCiAgICAgIGdvdG8gbm9fc29ja2V0X3BhaXI7CgogICAgZmNudGwgKGNvbnRyb2xfc29ja1swXSwgRl9TRVRGTCwgT19OT05CTE9DSyk7CiAgICBmY250bCAoY29udHJvbF9zb2NrWzFdLCBGX1NFVEZMLCBPX05PTkJMT0NLKTsKCiAgICBuc2V0LT5jb250cm9sX3JlYWRfZmQuZmQgPSBjb250cm9sX3NvY2tbMF07CiAgICBuc2V0LT5jb250cm9sX3dyaXRlX2ZkLmZkID0gY29udHJvbF9zb2NrWzFdOwoKICAgIGdzdF9wb2xsX2FkZF9mZF91bmxvY2tlZCAobnNldCwgJm5zZXQtPmNvbnRyb2xfcmVhZF9mZCk7CiAgICBnc3RfcG9sbF9mZF9jdGxfcmVhZF91bmxvY2tlZCAobnNldCwgJm5zZXQtPmNvbnRyb2xfcmVhZF9mZCwgVFJVRSk7CiAgfQojZWxzZQogIG5zZXQtPm1vZGUgPSBHU1RfUE9MTF9NT0RFX1dJTkRPV1M7CiAgbnNldC0+ZmRzID0gZ19hcnJheV9uZXcgKEZBTFNFLCBGQUxTRSwgc2l6ZW9mIChXaW5zb2NrRmQpKTsKICBuc2V0LT5hY3RpdmVfZmRzID0gZ19hcnJheV9uZXcgKEZBTFNFLCBGQUxTRSwgc2l6ZW9mIChXaW5zb2NrRmQpKTsKICBuc2V0LT5hY3RpdmVfZmRzX2lnbm9yZWQgPSBnX2FycmF5X25ldyAoRkFMU0UsIEZBTFNFLCBzaXplb2YgKFdpbnNvY2tGZCAqKSk7CiAgbnNldC0+ZXZlbnRzID0gZ19hcnJheV9uZXcgKEZBTFNFLCBGQUxTRSwgc2l6ZW9mIChIQU5ETEUpKTsKICBuc2V0LT5hY3RpdmVfZXZlbnRzID0gZ19hcnJheV9uZXcgKEZBTFNFLCBGQUxTRSwgc2l6ZW9mIChIQU5ETEUpKTsKCiAgbnNldC0+d2FrZXVwX2V2ZW50ID0gQ3JlYXRlRXZlbnQgKE5VTEwsIFRSVUUsIEZBTFNFLCBOVUxMKTsKI2VuZGlmCgogIC8qIGVuc3VyZSAocmUpYnVpbGQsIHRob3VnaCBhbHJlYWR5IHNuZWFraWx5IHNldCBpbiBub24td2luZG93cyBjYXNlICovCiAgTUFSS19SRUJVSUxEIChuc2V0KTsKCiAgbnNldC0+Y29udHJvbGxhYmxlID0gY29udHJvbGxhYmxlOwoKICByZXR1cm4gbnNldDsKCiAgLyogRVJST1JTICovCiNpZm5kZWYgR19PU19XSU4zMgpub19zb2NrZXRfcGFpcjoKICB7CiAgICBHU1RfV0FSTklORyAoIiVwOiBjYW4ndCBjcmVhdGUgc29ja2V0IHBhaXIgISIsIG5zZXQpOwogICAgZ3N0X3BvbGxfZnJlZSAobnNldCk7CiAgICByZXR1cm4gTlVMTDsKICB9CiNlbmRpZgp9CgovKioKICogZ3N0X3BvbGxfbmV3X3RpbWVyOgogKgogKiBDcmVhdGUgYSBuZXcgcG9sbCBvYmplY3QgdGhhdCBjYW4gYmUgdXNlZCBmb3Igc2NoZWR1bGluZyBjYW5jZWxsYWJsZQogKiB0aW1lb3V0cy4KICoKICogQSB0aW1lb3V0IGlzIHBlcmZvcm1lZCB3aXRoIGdzdF9wb2xsX3dhaXQoKS4gTXVsdGlwbGUgdGltZW91dHMgY2FuIGJlCiAqIHBlcmZvcm1lZCBmcm9tIGRpZmZlcmVudCB0aHJlYWRzLiAKICoKICogRnJlZS1mdW5jdGlvbjogZ3N0X3BvbGxfZnJlZQogKgogKiBSZXR1cm5zOiAodHJhbnNmZXIgZnVsbCk6IGEgbmV3ICNHc3RQb2xsLCBvciAlTlVMTCBpbiBjYXNlIG9mIGFuIGVycm9yLgogKiAgICAgRnJlZSB3aXRoIGdzdF9wb2xsX2ZyZWUoKS4KICoKICogU2luY2U6IDAuMTAuMjMKICovCkdzdFBvbGwgKgpnc3RfcG9sbF9uZXdfdGltZXIgKHZvaWQpCnsKICBHc3RQb2xsICpwb2xsOwoKICAvKiBtYWtlIGEgbmV3IGNvbnRyb2xsYWJsZSBwb2xsIHNldCAqLwogIGlmICghKHBvbGwgPSBnc3RfcG9sbF9uZXcgKFRSVUUpKSkKICAgIGdvdG8gZG9uZTsKCiAgLyogd2UgYXJlIGEgdGltZXIgKi8KICBwb2xsLT50aW1lciA9IFRSVUU7Cgpkb25lOgogIHJldHVybiBwb2xsOwp9CgovKioKICogZ3N0X3BvbGxfZnJlZToKICogQHNldDogKHRyYW5zZmVyIGZ1bGwpOiBhIGZpbGUgZGVzY3JpcHRvciBzZXQuCiAqCiAqIEZyZWUgYSBmaWxlIGRlc2NyaXB0b3Igc2V0LgogKgogKiBTaW5jZTogMC4xMC4xOAogKi8Kdm9pZApnc3RfcG9sbF9mcmVlIChHc3RQb2xsICogc2V0KQp7CiAgZ19yZXR1cm5faWZfZmFpbCAoc2V0ICE9IE5VTEwpOwoKICBHU1RfREVCVUcgKCIlcDogZnJlZWluZyIsIHNldCk7CgojaWZuZGVmIEdfT1NfV0lOMzIKICBpZiAoc2V0LT5jb250cm9sX3dyaXRlX2ZkLmZkID49IDApCiAgICBjbG9zZSAoc2V0LT5jb250cm9sX3dyaXRlX2ZkLmZkKTsKICBpZiAoc2V0LT5jb250cm9sX3JlYWRfZmQuZmQgPj0gMCkKICAgIGNsb3NlIChzZXQtPmNvbnRyb2xfcmVhZF9mZC5mZCk7CiNlbHNlCiAgQ2xvc2VIYW5kbGUgKHNldC0+d2FrZXVwX2V2ZW50KTsKCiAgewogICAgZ3VpbnQgaTsKCiAgICBmb3IgKGkgPSAwOyBpIDwgc2V0LT5ldmVudHMtPmxlbjsgaSsrKQogICAgICBnc3RfcG9sbF9mcmVlX3dpbnNvY2tfZXZlbnQgKHNldCwgaSk7CiAgfQoKICBnX2FycmF5X2ZyZWUgKHNldC0+YWN0aXZlX2V2ZW50cywgVFJVRSk7CiAgZ19hcnJheV9mcmVlIChzZXQtPmV2ZW50cywgVFJVRSk7CiAgZ19hcnJheV9mcmVlIChzZXQtPmFjdGl2ZV9mZHNfaWdub3JlZCwgVFJVRSk7CiNlbmRpZgoKICBnX2FycmF5X2ZyZWUgKHNldC0+YWN0aXZlX2ZkcywgVFJVRSk7CiAgZ19hcnJheV9mcmVlIChzZXQtPmZkcywgVFJVRSk7CiAgZ19tdXRleF9mcmVlIChzZXQtPmxvY2spOwogIGdfc2xpY2VfZnJlZSAoR3N0UG9sbCwgc2V0KTsKfQoKLyoqCiAqIGdzdF9wb2xsX2dldF9yZWFkX2dwb2xsZmQ6CiAqIEBzZXQ6IGEgI0dzdFBvbGwKICogQGZkOiBhICNHUG9sbEZECiAqCiAqIEdldCBhIEdQb2xsRkQgZm9yIHRoZSByZWFkaW5nIHBhcnQgb2YgdGhlIGNvbnRyb2wgc29ja2V0LiBUaGlzIGlzIHVzZWZ1bCB3aGVuCiAqIGludGVncmF0aW5nIHdpdGggYSBHU291cmNlIGFuZCBHTWFpbkxvb3AuCiAqCiAqIFNpbmNlOiAwLjEwLjMyCiAqLwp2b2lkCmdzdF9wb2xsX2dldF9yZWFkX2dwb2xsZmQgKEdzdFBvbGwgKiBzZXQsIEdQb2xsRkQgKiBmZCkKewogIGdfcmV0dXJuX2lmX2ZhaWwgKHNldCAhPSBOVUxMKTsKICBnX3JldHVybl9pZl9mYWlsIChmZCAhPSBOVUxMKTsKCiNpZm5kZWYgR19PU19XSU4zMgogIGZkLT5mZCA9IHNldC0+Y29udHJvbF9yZWFkX2ZkLmZkOwojZWxzZQojaWYgR0xJQl9TSVpFT0ZfVk9JRF9QID09IDgKICBmZC0+ZmQgPSAoZ2ludDY0KSBzZXQtPndha2V1cF9ldmVudDsKI2Vsc2UKICBmZC0+ZmQgPSAoZ2ludCkgc2V0LT53YWtldXBfZXZlbnQ7CiNlbmRpZgojZW5kaWYKICBmZC0+ZXZlbnRzID0gR19JT19JTiB8IEdfSU9fSFVQIHwgR19JT19FUlI7CiAgZmQtPnJldmVudHMgPSAwOwp9CgovKioKICogZ3N0X3BvbGxfZmRfaW5pdDoKICogQGZkOiBhICNHc3RQb2xsRkQKICoKICogSW5pdGlhbGl6ZXMgQGZkLiBBbHRlcm5hdGl2ZWx5IHlvdSBjYW4gaW5pdGlhbGl6ZSBpdCB3aXRoCiAqICNHU1RfUE9MTF9GRF9JTklULgogKgogKiBTaW5jZTogMC4xMC4xOAogKi8Kdm9pZApnc3RfcG9sbF9mZF9pbml0IChHc3RQb2xsRkQgKiBmZCkKewogIGdfcmV0dXJuX2lmX2ZhaWwgKGZkICE9IE5VTEwpOwoKICBmZC0+ZmQgPSAtMTsKICBmZC0+aWR4ID0gLTE7Cn0KCnN0YXRpYyBnYm9vbGVhbgpnc3RfcG9sbF9hZGRfZmRfdW5sb2NrZWQgKEdzdFBvbGwgKiBzZXQsIEdzdFBvbGxGRCAqIGZkKQp7CiAgZ2ludCBpZHg7CgogIEdTVF9ERUJVRyAoIiVwOiBmZCAoZmQ6JWQsIGlkeDolZCkiLCBzZXQsIGZkLT5mZCwgZmQtPmlkeCk7CgogIGlkeCA9IGZpbmRfaW5kZXggKHNldC0+ZmRzLCBmZCk7CiAgaWYgKGlkeCA8IDApIHsKI2lmbmRlZiBHX09TX1dJTjMyCiAgICBzdHJ1Y3QgcG9sbGZkIG5mZDsKCiAgICBuZmQuZmQgPSBmZC0+ZmQ7CiAgICBuZmQuZXZlbnRzID0gUE9MTEVSUiB8IFBPTExOVkFMIHwgUE9MTEhVUDsKICAgIG5mZC5yZXZlbnRzID0gMDsKCiAgICBnX2FycmF5X2FwcGVuZF92YWwgKHNldC0+ZmRzLCBuZmQpOwoKICAgIGZkLT5pZHggPSBzZXQtPmZkcy0+bGVuIC0gMTsKI2Vsc2UKICAgIFdpbnNvY2tGZCB3ZmQ7CiAgICBIQU5ETEUgZXZlbnQ7CgogICAgd2ZkLmZkID0gZmQtPmZkOwogICAgd2ZkLmV2ZW50X21hc2sgPSBGRF9DTE9TRTsKICAgIG1lbXNldCAoJndmZC5ldmVudHMsIDAsIHNpemVvZiAod2ZkLmV2ZW50cykpOwogICAgd2ZkLmlnbm9yZWRfZXZlbnRfbWFzayA9IDA7CiAgICBldmVudCA9IFdTQUNyZWF0ZUV2ZW50ICgpOwoKICAgIGdfYXJyYXlfYXBwZW5kX3ZhbCAoc2V0LT5mZHMsIHdmZCk7CiAgICBnX2FycmF5X2FwcGVuZF92YWwgKHNldC0+ZXZlbnRzLCBldmVudCk7CgogICAgZmQtPmlkeCA9IHNldC0+ZmRzLT5sZW4gLSAxOwojZW5kaWYKICAgIE1BUktfUkVCVUlMRCAoc2V0KTsKICB9IGVsc2UgewogICAgR1NUX1dBUk5JTkcgKCIlcDogY291bGRuJ3QgZmluZCBmZCAhIiwgc2V0KTsKICB9CgogIHJldHVybiBUUlVFOwp9CgovKioKICogZ3N0X3BvbGxfYWRkX2ZkOgogKiBAc2V0OiBhIGZpbGUgZGVzY3JpcHRvciBzZXQuCiAqIEBmZDogYSBmaWxlIGRlc2NyaXB0b3IuCiAqCiAqIEFkZCBhIGZpbGUgZGVzY3JpcHRvciB0byB0aGUgZmlsZSBkZXNjcmlwdG9yIHNldC4KICoKICogUmV0dXJuczogJVRSVUUgaWYgdGhlIGZpbGUgZGVzY3JpcHRvciB3YXMgc3VjY2Vzc2Z1bGx5IGFkZGVkIHRvIHRoZSBzZXQuCiAqCiAqIFNpbmNlOiAwLjEwLjE4CiAqLwpnYm9vbGVhbgpnc3RfcG9sbF9hZGRfZmQgKEdzdFBvbGwgKiBzZXQsIEdzdFBvbGxGRCAqIGZkKQp7CiAgZ2Jvb2xlYW4gcmV0OwoKICBnX3JldHVybl92YWxfaWZfZmFpbCAoc2V0ICE9IE5VTEwsIEZBTFNFKTsKICBnX3JldHVybl92YWxfaWZfZmFpbCAoZmQgIT0gTlVMTCwgRkFMU0UpOwogIGdfcmV0dXJuX3ZhbF9pZl9mYWlsIChmZC0+ZmQgPj0gMCwgRkFMU0UpOwoKICBnX211dGV4X2xvY2sgKHNldC0+bG9jayk7CgogIHJldCA9IGdzdF9wb2xsX2FkZF9mZF91bmxvY2tlZCAoc2V0LCBmZCk7CgogIGdfbXV0ZXhfdW5sb2NrIChzZXQtPmxvY2spOwoKICByZXR1cm4gcmV0Owp9CgovKioKICogZ3N0X3BvbGxfcmVtb3ZlX2ZkOgogKiBAc2V0OiBhIGZpbGUgZGVzY3JpcHRvciBzZXQuCiAqIEBmZDogYSBmaWxlIGRlc2NyaXB0b3IuCiAqCiAqIFJlbW92ZSBhIGZpbGUgZGVzY3JpcHRvciBmcm9tIHRoZSBmaWxlIGRlc2NyaXB0b3Igc2V0LgogKgogKiBSZXR1cm5zOiAlVFJVRSBpZiB0aGUgZmlsZSBkZXNjcmlwdG9yIHdhcyBzdWNjZXNzZnVsbHkgcmVtb3ZlZCBmcm9tIHRoZSBzZXQuCiAqCiAqIFNpbmNlOiAwLjEwLjE4CiAqLwpnYm9vbGVhbgpnc3RfcG9sbF9yZW1vdmVfZmQgKEdzdFBvbGwgKiBzZXQsIEdzdFBvbGxGRCAqIGZkKQp7CiAgZ2ludCBpZHg7CgogIGdfcmV0dXJuX3ZhbF9pZl9mYWlsIChzZXQgIT0gTlVMTCwgRkFMU0UpOwogIGdfcmV0dXJuX3ZhbF9pZl9mYWlsIChmZCAhPSBOVUxMLCBGQUxTRSk7CiAgZ19yZXR1cm5fdmFsX2lmX2ZhaWwgKGZkLT5mZCA+PSAwLCBGQUxTRSk7CgoKICBHU1RfREVCVUcgKCIlcDogZmQgKGZkOiVkLCBpZHg6JWQpIiwgc2V0LCBmZC0+ZmQsIGZkLT5pZHgpOwoKICBnX211dGV4X2xvY2sgKHNldC0+bG9jayk7CgogIC8qIGdldCB0aGUgaW5kZXgsIC0xIGlzIGFuIGZkIHRoYXQgaXMgbm90IGFkZGVkICovCiAgaWR4ID0gZmluZF9pbmRleCAoc2V0LT5mZHMsIGZkKTsKICBpZiAoaWR4ID49IDApIHsKI2lmZGVmIEdfT1NfV0lOMzIKICAgIGdzdF9wb2xsX2ZyZWVfd2luc29ja19ldmVudCAoc2V0LCBpZHgpOwogICAgZ19hcnJheV9yZW1vdmVfaW5kZXhfZmFzdCAoc2V0LT5ldmVudHMsIGlkeCk7CiNlbmRpZgoKICAgIC8qIHJlbW92ZSB0aGUgZmQgYXQgaW5kZXgsIHdlIHVzZSBfcmVtb3ZlX2luZGV4X2Zhc3QsIHdoaWNoIGNvcGllcyB0aGUgbGFzdAogICAgICogZWxlbWVudCBvZiB0aGUgYXJyYXkgdG8gdGhlIGZyZWVkIGluZGV4ICovCiAgICBnX2FycmF5X3JlbW92ZV9pbmRleF9mYXN0IChzZXQtPmZkcywgaWR4KTsKCiAgICAvKiBtYXJrIGZkIGFzIHJlbW92ZWQgYnkgc2V0dGluZyB0aGUgaW5kZXggdG8gLTEgKi8KICAgIGZkLT5pZHggPSAtMTsKICAgIE1BUktfUkVCVUlMRCAoc2V0KTsKICB9IGVsc2UgewogICAgR1NUX1dBUk5JTkcgKCIlcDogY291bGRuJ3QgZmluZCBmZCAhIiwgc2V0KTsKICB9CgogIGdfbXV0ZXhfdW5sb2NrIChzZXQtPmxvY2spOwoKICByZXR1cm4gaWR4ID49IDA7Cn0KCi8qKgogKiBnc3RfcG9sbF9mZF9jdGxfd3JpdGU6CiAqIEBzZXQ6IGEgZmlsZSBkZXNjcmlwdG9yIHNldC4KICogQGZkOiBhIGZpbGUgZGVzY3JpcHRvci4KICogQGFjdGl2ZTogYSBuZXcgc3RhdHVzLgogKgogKiBDb250cm9sIHdoZXRoZXIgdGhlIGRlc2NyaXB0b3IgQGZkIGluIEBzZXQgd2lsbCBiZSBtb25pdG9yZWQgZm9yCiAqIHdyaXRhYmlsaXR5LgogKgogKiBSZXR1cm5zOiAlVFJVRSBpZiB0aGUgZGVzY3JpcHRvciB3YXMgc3VjY2Vzc2Z1bGx5IHVwZGF0ZWQuCiAqCiAqIFNpbmNlOiAwLjEwLjE4CiAqLwpnYm9vbGVhbgpnc3RfcG9sbF9mZF9jdGxfd3JpdGUgKEdzdFBvbGwgKiBzZXQsIEdzdFBvbGxGRCAqIGZkLCBnYm9vbGVhbiBhY3RpdmUpCnsKICBnaW50IGlkeDsKCiAgZ19yZXR1cm5fdmFsX2lmX2ZhaWwgKHNldCAhPSBOVUxMLCBGQUxTRSk7CiAgZ19yZXR1cm5fdmFsX2lmX2ZhaWwgKGZkICE9IE5VTEwsIEZBTFNFKTsKICBnX3JldHVybl92YWxfaWZfZmFpbCAoZmQtPmZkID49IDAsIEZBTFNFKTsKCiAgR1NUX0RFQlVHICgiJXA6IGZkIChmZDolZCwgaWR4OiVkKSwgYWN0aXZlIDogJWQiLCBzZXQsCiAgICAgIGZkLT5mZCwgZmQtPmlkeCwgYWN0aXZlKTsKCiAgZ19tdXRleF9sb2NrIChzZXQtPmxvY2spOwoKICBpZHggPSBmaW5kX2luZGV4IChzZXQtPmZkcywgZmQpOwogIGlmIChpZHggPj0gMCkgewojaWZuZGVmIEdfT1NfV0lOMzIKICAgIHN0cnVjdCBwb2xsZmQgKnBmZCA9ICZnX2FycmF5X2luZGV4IChzZXQtPmZkcywgc3RydWN0IHBvbGxmZCwgaWR4KTsKCiAgICBpZiAoYWN0aXZlKQogICAgICBwZmQtPmV2ZW50cyB8PSBQT0xMT1VUOwogICAgZWxzZQogICAgICBwZmQtPmV2ZW50cyAmPSB+UE9MTE9VVDsKCiAgICBHU1RfTE9HICgicGZkLT5ldmVudHMgbm93ICVkIChQT0xMT1VUOiVkKSIsIHBmZC0+ZXZlbnRzLCBQT0xMT1VUKTsKI2Vsc2UKICAgIGdzdF9wb2xsX3VwZGF0ZV93aW5zb2NrX2V2ZW50X21hc2sgKHNldCwgaWR4LCBGRF9XUklURSB8IEZEX0NPTk5FQ1QsCiAgICAgICAgYWN0aXZlKTsKI2VuZGlmCiAgICBNQVJLX1JFQlVJTEQgKHNldCk7CiAgfSBlbHNlIHsKICAgIEdTVF9XQVJOSU5HICgiJXA6IGNvdWxkbid0IGZpbmQgZmQgISIsIHNldCk7CiAgfQoKICBnX211dGV4X3VubG9jayAoc2V0LT5sb2NrKTsKCiAgcmV0dXJuIGlkeCA+PSAwOwp9CgpzdGF0aWMgZ2Jvb2xlYW4KZ3N0X3BvbGxfZmRfY3RsX3JlYWRfdW5sb2NrZWQgKEdzdFBvbGwgKiBzZXQsIEdzdFBvbGxGRCAqIGZkLCBnYm9vbGVhbiBhY3RpdmUpCnsKICBnaW50IGlkeDsKCiAgR1NUX0RFQlVHICgiJXA6IGZkIChmZDolZCwgaWR4OiVkKSwgYWN0aXZlIDogJWQiLCBzZXQsCiAgICAgIGZkLT5mZCwgZmQtPmlkeCwgYWN0aXZlKTsKCiAgaWR4ID0gZmluZF9pbmRleCAoc2V0LT5mZHMsIGZkKTsKCiAgaWYgKGlkeCA+PSAwKSB7CiNpZm5kZWYgR19PU19XSU4zMgogICAgc3RydWN0IHBvbGxmZCAqcGZkID0gJmdfYXJyYXlfaW5kZXggKHNldC0+ZmRzLCBzdHJ1Y3QgcG9sbGZkLCBpZHgpOwoKICAgIGlmIChhY3RpdmUpCiAgICAgIHBmZC0+ZXZlbnRzIHw9IChQT0xMSU4gfCBQT0xMUFJJKTsKICAgIGVsc2UKICAgICAgcGZkLT5ldmVudHMgJj0gfihQT0xMSU4gfCBQT0xMUFJJKTsKI2Vsc2UKICAgIGdzdF9wb2xsX3VwZGF0ZV93aW5zb2NrX2V2ZW50X21hc2sgKHNldCwgaWR4LCBGRF9SRUFEIHwgRkRfQUNDRVBULCBhY3RpdmUpOwojZW5kaWYKICAgIE1BUktfUkVCVUlMRCAoc2V0KTsKICB9IGVsc2UgewogICAgR1NUX1dBUk5JTkcgKCIlcDogY291bGRuJ3QgZmluZCBmZCAhIiwgc2V0KTsKICB9CgogIHJldHVybiBpZHggPj0gMDsKfQoKLyoqCiAqIGdzdF9wb2xsX2ZkX2N0bF9yZWFkOgogKiBAc2V0OiBhIGZpbGUgZGVzY3JpcHRvciBzZXQuCiAqIEBmZDogYSBmaWxlIGRlc2NyaXB0b3IuCiAqIEBhY3RpdmU6IGEgbmV3IHN0YXR1cy4KICoKICogQ29udHJvbCB3aGV0aGVyIHRoZSBkZXNjcmlwdG9yIEBmZCBpbiBAc2V0IHdpbGwgYmUgbW9uaXRvcmVkIGZvcgogKiByZWFkYWJpbGl0eS4KICoKICogUmV0dXJuczogJVRSVUUgaWYgdGhlIGRlc2NyaXB0b3Igd2FzIHN1Y2Nlc3NmdWxseSB1cGRhdGVkLgogKgogKiBTaW5jZTogMC4xMC4xOAogKi8KZ2Jvb2xlYW4KZ3N0X3BvbGxfZmRfY3RsX3JlYWQgKEdzdFBvbGwgKiBzZXQsIEdzdFBvbGxGRCAqIGZkLCBnYm9vbGVhbiBhY3RpdmUpCnsKICBnYm9vbGVhbiByZXQ7CgogIGdfcmV0dXJuX3ZhbF9pZl9mYWlsIChzZXQgIT0gTlVMTCwgRkFMU0UpOwogIGdfcmV0dXJuX3ZhbF9pZl9mYWlsIChmZCAhPSBOVUxMLCBGQUxTRSk7CiAgZ19yZXR1cm5fdmFsX2lmX2ZhaWwgKGZkLT5mZCA+PSAwLCBGQUxTRSk7CgogIGdfbXV0ZXhfbG9jayAoc2V0LT5sb2NrKTsKCiAgcmV0ID0gZ3N0X3BvbGxfZmRfY3RsX3JlYWRfdW5sb2NrZWQgKHNldCwgZmQsIGFjdGl2ZSk7CgogIGdfbXV0ZXhfdW5sb2NrIChzZXQtPmxvY2spOwoKICByZXR1cm4gcmV0Owp9CgovKioKICogZ3N0X3BvbGxfZmRfaWdub3JlZDoKICogQHNldDogYSBmaWxlIGRlc2NyaXB0b3Igc2V0LgogKiBAZmQ6IGEgZmlsZSBkZXNjcmlwdG9yLgogKgogKiBNYXJrIEBmZCBhcyBpZ25vcmVkIHNvIHRoYXQgdGhlIG5leHQgY2FsbCB0byBnc3RfcG9sbF93YWl0KCkgd2lsbCB5aWVsZAogKiB0aGUgc2FtZSByZXN1bHQgZm9yIEBmZCBhcyBsYXN0IHRpbWUuIFRoaXMgZnVuY3Rpb24gbXVzdCBiZSBjYWxsZWQgaWYgbm8KICogb3BlcmF0aW9uIChyZWFkL3dyaXRlL3JlY3Yvc2VuZC9ldGMuKSB3aWxsIGJlIHBlcmZvcm1lZCBvbiBAZmQgYmVmb3JlCiAqIHRoZSBuZXh0IGNhbGwgdG8gZ3N0X3BvbGxfd2FpdCgpLgogKgogKiBUaGUgcmVhc29uIHdoeSB0aGlzIGlzIG5lZWRlZCBpcyBiZWNhdXNlIHRoZSB1bmRlcmx5aW5nIGltcGxlbWVudGF0aW9uCiAqIG1pZ2h0IG5vdCBhbGxvdyBxdWVyeWluZyB0aGUgZmQgbW9yZSB0aGFuIG9uY2UgYmV0d2VlbiBjYWxscyB0byBvbmUgb2YKICogdGhlIHJlLWVuYWJsaW5nIG9wZXJhdGlvbnMuCiAqCiAqIFNpbmNlOiAwLjEwLjE4CiAqLwp2b2lkCmdzdF9wb2xsX2ZkX2lnbm9yZWQgKEdzdFBvbGwgKiBzZXQsIEdzdFBvbGxGRCAqIGZkKQp7CiNpZmRlZiBHX09TX1dJTjMyCiAgZ2ludCBpZHg7CgogIGdfcmV0dXJuX2lmX2ZhaWwgKHNldCAhPSBOVUxMKTsKICBnX3JldHVybl9pZl9mYWlsIChmZCAhPSBOVUxMKTsKICBnX3JldHVybl9pZl9mYWlsIChmZC0+ZmQgPj0gMCk7CgogIGdfbXV0ZXhfbG9jayAoc2V0LT5sb2NrKTsKCiAgaWR4ID0gZmluZF9pbmRleCAoc2V0LT5mZHMsIGZkKTsKICBpZiAoaWR4ID49IDApIHsKICAgIFdpbnNvY2tGZCAqd2ZkID0gJmdfYXJyYXlfaW5kZXggKHNldC0+ZmRzLCBXaW5zb2NrRmQsIGlkeCk7CgogICAgd2ZkLT5pZ25vcmVkX2V2ZW50X21hc2sgPSB3ZmQtPmV2ZW50X21hc2sgJiAoRkRfUkVBRCB8IEZEX1dSSVRFKTsKICAgIE1BUktfUkVCVUlMRCAoc2V0KTsKICB9CgogIGdfbXV0ZXhfdW5sb2NrIChzZXQtPmxvY2spOwojZW5kaWYKfQoKLyoqCiAqIGdzdF9wb2xsX2ZkX2hhc19jbG9zZWQ6CiAqIEBzZXQ6IGEgZmlsZSBkZXNjcmlwdG9yIHNldC4KICogQGZkOiBhIGZpbGUgZGVzY3JpcHRvci4KICoKICogQ2hlY2sgaWYgQGZkIGluIEBzZXQgaGFzIGNsb3NlZCB0aGUgY29ubmVjdGlvbi4KICoKICogUmV0dXJuczogJVRSVUUgaWYgdGhlIGNvbm5lY3Rpb24gd2FzIGNsb3NlZC4KICoKICogU2luY2U6IDAuMTAuMTgKICovCmdib29sZWFuCmdzdF9wb2xsX2ZkX2hhc19jbG9zZWQgKGNvbnN0IEdzdFBvbGwgKiBzZXQsIEdzdFBvbGxGRCAqIGZkKQp7CiAgZ2Jvb2xlYW4gcmVzID0gRkFMU0U7CiAgZ2ludCBpZHg7CgogIGdfcmV0dXJuX3ZhbF9pZl9mYWlsIChzZXQgIT0gTlVMTCwgRkFMU0UpOwogIGdfcmV0dXJuX3ZhbF9pZl9mYWlsIChmZCAhPSBOVUxMLCBGQUxTRSk7CiAgZ19yZXR1cm5fdmFsX2lmX2ZhaWwgKGZkLT5mZCA+PSAwLCBGQUxTRSk7CgogIEdTVF9ERUJVRyAoIiVwOiBmZCAoZmQ6JWQsIGlkeDolZCkiLCBzZXQsIGZkLT5mZCwgZmQtPmlkeCk7CgogIGdfbXV0ZXhfbG9jayAoc2V0LT5sb2NrKTsKCiAgaWR4ID0gZmluZF9pbmRleCAoc2V0LT5hY3RpdmVfZmRzLCBmZCk7CiAgaWYgKGlkeCA+PSAwKSB7CiNpZm5kZWYgR19PU19XSU4zMgogICAgc3RydWN0IHBvbGxmZCAqcGZkID0gJmdfYXJyYXlfaW5kZXggKHNldC0+YWN0aXZlX2Zkcywgc3RydWN0IHBvbGxmZCwgaWR4KTsKCiAgICByZXMgPSAocGZkLT5yZXZlbnRzICYgUE9MTEhVUCkgIT0gMDsKI2Vsc2UKICAgIFdpbnNvY2tGZCAqd2ZkID0gJmdfYXJyYXlfaW5kZXggKHNldC0+YWN0aXZlX2ZkcywgV2luc29ja0ZkLCBpZHgpOwoKICAgIHJlcyA9ICh3ZmQtPmV2ZW50cy5sTmV0d29ya0V2ZW50cyAmIEZEX0NMT1NFKSAhPSAwOwojZW5kaWYKICB9IGVsc2UgewogICAgR1NUX1dBUk5JTkcgKCIlcDogY291bGRuJ3QgZmluZCBmZCAhIiwgc2V0KTsKICB9CgogIGdfbXV0ZXhfdW5sb2NrIChzZXQtPmxvY2spOwoKICByZXR1cm4gcmVzOwp9CgovKioKICogZ3N0X3BvbGxfZmRfaGFzX2Vycm9yOgogKiBAc2V0OiBhIGZpbGUgZGVzY3JpcHRvciBzZXQuCiAqIEBmZDogYSBmaWxlIGRlc2NyaXB0b3IuCiAqCiAqIENoZWNrIGlmIEBmZCBpbiBAc2V0IGhhcyBhbiBlcnJvci4KICoKICogUmV0dXJuczogJVRSVUUgaWYgdGhlIGRlc2NyaXB0b3IgaGFzIGFuIGVycm9yLgogKgogKiBTaW5jZTogMC4xMC4xOAogKi8KZ2Jvb2xlYW4KZ3N0X3BvbGxfZmRfaGFzX2Vycm9yIChjb25zdCBHc3RQb2xsICogc2V0LCBHc3RQb2xsRkQgKiBmZCkKewogIGdib29sZWFuIHJlcyA9IEZBTFNFOwogIGdpbnQgaWR4OwoKICBnX3JldHVybl92YWxfaWZfZmFpbCAoc2V0ICE9IE5VTEwsIEZBTFNFKTsKICBnX3JldHVybl92YWxfaWZfZmFpbCAoZmQgIT0gTlVMTCwgRkFMU0UpOwogIGdfcmV0dXJuX3ZhbF9pZl9mYWlsIChmZC0+ZmQgPj0gMCwgRkFMU0UpOwoKICBHU1RfREVCVUcgKCIlcDogZmQgKGZkOiVkLCBpZHg6JWQpIiwgc2V0LCBmZC0+ZmQsIGZkLT5pZHgpOwoKICBnX211dGV4X2xvY2sgKHNldC0+bG9jayk7CgogIGlkeCA9IGZpbmRfaW5kZXggKHNldC0+YWN0aXZlX2ZkcywgZmQpOwogIGlmIChpZHggPj0gMCkgewojaWZuZGVmIEdfT1NfV0lOMzIKICAgIHN0cnVjdCBwb2xsZmQgKnBmZCA9ICZnX2FycmF5X2luZGV4IChzZXQtPmFjdGl2ZV9mZHMsIHN0cnVjdCBwb2xsZmQsIGlkeCk7CgogICAgcmVzID0gKHBmZC0+cmV2ZW50cyAmIChQT0xMRVJSIHwgUE9MTE5WQUwpKSAhPSAwOwojZWxzZQogICAgV2luc29ja0ZkICp3ZmQgPSAmZ19hcnJheV9pbmRleCAoc2V0LT5hY3RpdmVfZmRzLCBXaW5zb2NrRmQsIGlkeCk7CgogICAgcmVzID0gKHdmZC0+ZXZlbnRzLmlFcnJvckNvZGVbRkRfQ0xPU0VfQklUXSAhPSAwKSB8fAogICAgICAgICh3ZmQtPmV2ZW50cy5pRXJyb3JDb2RlW0ZEX1JFQURfQklUXSAhPSAwKSB8fAogICAgICAgICh3ZmQtPmV2ZW50cy5pRXJyb3JDb2RlW0ZEX1dSSVRFX0JJVF0gIT0gMCkgfHwKICAgICAgICAod2ZkLT5ldmVudHMuaUVycm9yQ29kZVtGRF9BQ0NFUFRfQklUXSAhPSAwKSB8fAogICAgICAgICh3ZmQtPmV2ZW50cy5pRXJyb3JDb2RlW0ZEX0NPTk5FQ1RfQklUXSAhPSAwKTsKI2VuZGlmCiAgfSBlbHNlIHsKICAgIEdTVF9XQVJOSU5HICgiJXA6IGNvdWxkbid0IGZpbmQgZmQgISIsIHNldCk7CiAgfQoKICBnX211dGV4X3VubG9jayAoc2V0LT5sb2NrKTsKCiAgcmV0dXJuIHJlczsKfQoKc3RhdGljIGdib29sZWFuCmdzdF9wb2xsX2ZkX2Nhbl9yZWFkX3VubG9ja2VkIChjb25zdCBHc3RQb2xsICogc2V0LCBHc3RQb2xsRkQgKiBmZCkKewogIGdib29sZWFuIHJlcyA9IEZBTFNFOwogIGdpbnQgaWR4OwoKICBHU1RfREVCVUcgKCIlcDogZmQgKGZkOiVkLCBpZHg6JWQpIiwgc2V0LCBmZC0+ZmQsIGZkLT5pZHgpOwoKICBpZHggPSBmaW5kX2luZGV4IChzZXQtPmFjdGl2ZV9mZHMsIGZkKTsKICBpZiAoaWR4ID49IDApIHsKI2lmbmRlZiBHX09TX1dJTjMyCiAgICBzdHJ1Y3QgcG9sbGZkICpwZmQgPSAmZ19hcnJheV9pbmRleCAoc2V0LT5hY3RpdmVfZmRzLCBzdHJ1Y3QgcG9sbGZkLCBpZHgpOwoKICAgIHJlcyA9IChwZmQtPnJldmVudHMgJiAoUE9MTElOIHwgUE9MTFBSSSkpICE9IDA7CiNlbHNlCiAgICBXaW5zb2NrRmQgKndmZCA9ICZnX2FycmF5X2luZGV4IChzZXQtPmFjdGl2ZV9mZHMsIFdpbnNvY2tGZCwgaWR4KTsKCiAgICByZXMgPSAod2ZkLT5ldmVudHMubE5ldHdvcmtFdmVudHMgJiAoRkRfUkVBRCB8IEZEX0FDQ0VQVCkpICE9IDA7CiNlbmRpZgogIH0gZWxzZSB7CiAgICBHU1RfV0FSTklORyAoIiVwOiBjb3VsZG4ndCBmaW5kIGZkICEiLCBzZXQpOwogIH0KCiAgcmV0dXJuIHJlczsKfQoKLyoqCiAqIGdzdF9wb2xsX2ZkX2Nhbl9yZWFkOgogKiBAc2V0OiBhIGZpbGUgZGVzY3JpcHRvciBzZXQuCiAqIEBmZDogYSBmaWxlIGRlc2NyaXB0b3IuCiAqCiAqIENoZWNrIGlmIEBmZCBpbiBAc2V0IGhhcyBkYXRhIHRvIGJlIHJlYWQuCiAqCiAqIFJldHVybnM6ICVUUlVFIGlmIHRoZSBkZXNjcmlwdG9yIGhhcyBkYXRhIHRvIGJlIHJlYWQuCiAqCiAqIFNpbmNlOiAwLjEwLjE4CiAqLwpnYm9vbGVhbgpnc3RfcG9sbF9mZF9jYW5fcmVhZCAoY29uc3QgR3N0UG9sbCAqIHNldCwgR3N0UG9sbEZEICogZmQpCnsKICBnYm9vbGVhbiByZXMgPSBGQUxTRTsKCiAgZ19yZXR1cm5fdmFsX2lmX2ZhaWwgKHNldCAhPSBOVUxMLCBGQUxTRSk7CiAgZ19yZXR1cm5fdmFsX2lmX2ZhaWwgKGZkICE9IE5VTEwsIEZBTFNFKTsKICBnX3JldHVybl92YWxfaWZfZmFpbCAoZmQtPmZkID49IDAsIEZBTFNFKTsKCiAgZ19tdXRleF9sb2NrIChzZXQtPmxvY2spOwoKICByZXMgPSBnc3RfcG9sbF9mZF9jYW5fcmVhZF91bmxvY2tlZCAoc2V0LCBmZCk7CgogIGdfbXV0ZXhfdW5sb2NrIChzZXQtPmxvY2spOwoKICByZXR1cm4gcmVzOwp9CgovKioKICogZ3N0X3BvbGxfZmRfY2FuX3dyaXRlOgogKiBAc2V0OiBhIGZpbGUgZGVzY3JpcHRvciBzZXQuCiAqIEBmZDogYSBmaWxlIGRlc2NyaXB0b3IuCiAqCiAqIENoZWNrIGlmIEBmZCBpbiBAc2V0IGNhbiBiZSB1c2VkIGZvciB3cml0aW5nLgogKgogKiBSZXR1cm5zOiAlVFJVRSBpZiB0aGUgZGVzY3JpcHRvciBjYW4gYmUgdXNlZCBmb3Igd3JpdGluZy4KICoKICogU2luY2U6IDAuMTAuMTgKICovCmdib29sZWFuCmdzdF9wb2xsX2ZkX2Nhbl93cml0ZSAoY29uc3QgR3N0UG9sbCAqIHNldCwgR3N0UG9sbEZEICogZmQpCnsKICBnYm9vbGVhbiByZXMgPSBGQUxTRTsKICBnaW50IGlkeDsKCiAgZ19yZXR1cm5fdmFsX2lmX2ZhaWwgKHNldCAhPSBOVUxMLCBGQUxTRSk7CiAgZ19yZXR1cm5fdmFsX2lmX2ZhaWwgKGZkICE9IE5VTEwsIEZBTFNFKTsKICBnX3JldHVybl92YWxfaWZfZmFpbCAoZmQtPmZkID49IDAsIEZBTFNFKTsKCiAgR1NUX0RFQlVHICgiJXA6IGZkIChmZDolZCwgaWR4OiVkKSIsIHNldCwgZmQtPmZkLCBmZC0+aWR4KTsKCiAgZ19tdXRleF9sb2NrIChzZXQtPmxvY2spOwoKICBpZHggPSBmaW5kX2luZGV4IChzZXQtPmFjdGl2ZV9mZHMsIGZkKTsKICBpZiAoaWR4ID49IDApIHsKI2lmbmRlZiBHX09TX1dJTjMyCiAgICBzdHJ1Y3QgcG9sbGZkICpwZmQgPSAmZ19hcnJheV9pbmRleCAoc2V0LT5hY3RpdmVfZmRzLCBzdHJ1Y3QgcG9sbGZkLCBpZHgpOwoKICAgIHJlcyA9IChwZmQtPnJldmVudHMgJiBQT0xMT1VUKSAhPSAwOwojZWxzZQogICAgV2luc29ja0ZkICp3ZmQgPSAmZ19hcnJheV9pbmRleCAoc2V0LT5hY3RpdmVfZmRzLCBXaW5zb2NrRmQsIGlkeCk7CgogICAgcmVzID0gKHdmZC0+ZXZlbnRzLmxOZXR3b3JrRXZlbnRzICYgRkRfV1JJVEUpICE9IDA7CiNlbmRpZgogIH0gZWxzZSB7CiAgICBHU1RfV0FSTklORyAoIiVwOiBjb3VsZG4ndCBmaW5kIGZkICEiLCBzZXQpOwogIH0KCiAgZ19tdXRleF91bmxvY2sgKHNldC0+bG9jayk7CgogIHJldHVybiByZXM7Cn0KCi8qKgogKiBnc3RfcG9sbF93YWl0OgogKiBAc2V0OiBhICNHc3RQb2xsLgogKiBAdGltZW91dDogYSB0aW1lb3V0IGluIG5hbm9zZWNvbmRzLgogKgogKiBXYWl0IGZvciBhY3Rpdml0eSBvbiB0aGUgZmlsZSBkZXNjcmlwdG9ycyBpbiBAc2V0LiBUaGlzIGZ1bmN0aW9uIHdhaXRzIHVwIHRvCiAqIHRoZSBzcGVjaWZpZWQgQHRpbWVvdXQuICBBIHRpbWVvdXQgb2YgI0dTVF9DTE9DS19USU1FX05PTkUgd2FpdHMgZm9yZXZlci4KICoKICogRm9yICNHc3RQb2xsIG9iamVjdHMgY3JlYXRlZCB3aXRoIGdzdF9wb2xsX25ldygpLCB0aGlzIGZ1bmN0aW9uIGNhbiBvbmx5IGJlCiAqIGNhbGxlZCBmcm9tIGEgc2luZ2xlIHRocmVhZCBhdCBhIHRpbWUuICBJZiBjYWxsZWQgZnJvbSBtdWx0aXBsZSB0aHJlYWRzLAogKiAtMSB3aWxsIGJlIHJldHVybmVkIHdpdGggZXJybm8gc2V0IHRvIEVQRVJNLgogKgogKiBUaGlzIGlzIG5vdCB0cnVlIGZvciB0aW1lciAjR3N0UG9sbCBvYmplY3RzIGNyZWF0ZWQgd2l0aAogKiBnc3RfcG9sbF9uZXdfdGltZXIoKSwgd2hlcmUgaXQgaXMgYWxsb3dlZCB0byBoYXZlIG11bHRpcGxlIHRocmVhZHMgd2FpdGluZwogKiBzaW11bHRhbmVvdXNseS4KICoKICogUmV0dXJuczogVGhlIG51bWJlciBvZiAjR3N0UG9sbEZEIGluIEBzZXQgdGhhdCBoYXZlIGFjdGl2aXR5IG9yIDAgd2hlbiBubwogKiBhY3Rpdml0eSB3YXMgZGV0ZWN0ZWQgYWZ0ZXIgQHRpbWVvdXQuIElmIGFuIGVycm9yIG9jY3VycywgLTEgaXMgcmV0dXJuZWQKICogYW5kIGVycm5vIGlzIHNldC4KICoKICogU2luY2U6IDAuMTAuMTgKICovCmdpbnQKZ3N0X3BvbGxfd2FpdCAoR3N0UG9sbCAqIHNldCwgR3N0Q2xvY2tUaW1lIHRpbWVvdXQpCnsKICBnYm9vbGVhbiByZXN0YXJ0aW5nOwogIGdib29sZWFuIGlzX3RpbWVyOwogIGludCByZXM7CiAgZ2ludCBvbGRfd2FpdGluZzsKCiAgZ19yZXR1cm5fdmFsX2lmX2ZhaWwgKHNldCAhPSBOVUxMLCAtMSk7CgogIEdTVF9ERUJVRyAoInRpbWVvdXQgOiUiIEdTVF9USU1FX0ZPUk1BVCwgR1NUX1RJTUVfQVJHUyAodGltZW91dCkpOwoKICBpc190aW1lciA9IHNldC0+dGltZXI7CgogIC8qIGFkZCBvbmUgbW9yZSB3YWl0ZXIgKi8KICBvbGRfd2FpdGluZyA9IElOQ19XQUlUSU5HIChzZXQpOwoKICAvKiB3ZSBjYW5ub3Qgd2FpdCBmcm9tIG11bHRpcGxlIHRocmVhZHMgdW5sZXNzIHdlIGFyZSBhIHRpbWVyICovCiAgaWYgKEdfVU5MSUtFTFkgKG9sZF93YWl0aW5nID4gMCAmJiAhaXNfdGltZXIpKQogICAgZ290byBhbHJlYWR5X3dhaXRpbmc7CgogIC8qIGZsdXNoaW5nLCBleGl0IGltbWVkaWF0ZWx5ICovCiAgaWYgKEdfVU5MSUtFTFkgKElTX0ZMVVNISU5HIChzZXQpKSkKICAgIGdvdG8gZmx1c2hpbmc7CgogIGRvIHsKICAgIEdzdFBvbGxNb2RlIG1vZGU7CgogICAgcmVzID0gLTE7CiAgICByZXN0YXJ0aW5nID0gRkFMU0U7CgogICAgbW9kZSA9IGNob29zZV9tb2RlIChzZXQsIHRpbWVvdXQpOwoKICAgIGlmIChURVNUX1JFQlVJTEQgKHNldCkpIHsKICAgICAgZ19tdXRleF9sb2NrIChzZXQtPmxvY2spOwojaWZuZGVmIEdfT1NfV0lOMzIKICAgICAgZ19hcnJheV9zZXRfc2l6ZSAoc2V0LT5hY3RpdmVfZmRzLCBzZXQtPmZkcy0+bGVuKTsKICAgICAgbWVtY3B5IChzZXQtPmFjdGl2ZV9mZHMtPmRhdGEsIHNldC0+ZmRzLT5kYXRhLAogICAgICAgICAgc2V0LT5mZHMtPmxlbiAqIHNpemVvZiAoc3RydWN0IHBvbGxmZCkpOwojZWxzZQogICAgICBpZiAoIWdzdF9wb2xsX3ByZXBhcmVfd2luc29ja19hY3RpdmVfc2V0cyAoc2V0KSkKICAgICAgICBnb3RvIHdpbnNvY2tfZXJyb3I7CiNlbmRpZgogICAgICBnX211dGV4X3VubG9jayAoc2V0LT5sb2NrKTsKICAgIH0KCiAgICBzd2l0Y2ggKG1vZGUpIHsKICAgICAgY2FzZSBHU1RfUE9MTF9NT0RFX0FVVE86CiAgICAgICAgZ19hc3NlcnRfbm90X3JlYWNoZWQgKCk7CiAgICAgICAgYnJlYWs7CiAgICAgIGNhc2UgR1NUX1BPTExfTU9ERV9QUE9MTDoKICAgICAgewojaWZkZWYgSEFWRV9QUE9MTAogICAgICAgIHN0cnVjdCB0aW1lc3BlYyB0czsKICAgICAgICBzdHJ1Y3QgdGltZXNwZWMgKnRzcHRyOwoKICAgICAgICBpZiAodGltZW91dCAhPSBHU1RfQ0xPQ0tfVElNRV9OT05FKSB7CiAgICAgICAgICBHU1RfVElNRV9UT19USU1FU1BFQyAodGltZW91dCwgdHMpOwogICAgICAgICAgdHNwdHIgPSAmdHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHRzcHRyID0gTlVMTDsKICAgICAgICB9CgogICAgICAgIHJlcyA9CiAgICAgICAgICAgIHBwb2xsICgoc3RydWN0IHBvbGxmZCAqKSBzZXQtPmFjdGl2ZV9mZHMtPmRhdGEsCiAgICAgICAgICAgIHNldC0+YWN0aXZlX2Zkcy0+bGVuLCB0c3B0ciwgTlVMTCk7CiNlbHNlCiAgICAgICAgZ19hc3NlcnRfbm90X3JlYWNoZWQgKCk7CiAgICAgICAgZXJybm8gPSBFTk9TWVM7CiNlbmRpZgogICAgICAgIGJyZWFrOwogICAgICB9CiAgICAgIGNhc2UgR1NUX1BPTExfTU9ERV9QT0xMOgogICAgICB7CiNpZmRlZiBIQVZFX1BPTEwKICAgICAgICBnaW50IHQ7CgogICAgICAgIGlmICh0aW1lb3V0ICE9IEdTVF9DTE9DS19USU1FX05PTkUpIHsKICAgICAgICAgIHQgPSBHU1RfVElNRV9BU19NU0VDT05EUyAodGltZW91dCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHQgPSAtMTsKICAgICAgICB9CgogICAgICAgIHJlcyA9CiAgICAgICAgICAgIHBvbGwgKChzdHJ1Y3QgcG9sbGZkICopIHNldC0+YWN0aXZlX2Zkcy0+ZGF0YSwKICAgICAgICAgICAgc2V0LT5hY3RpdmVfZmRzLT5sZW4sIHQpOwojZWxzZQogICAgICAgIGdfYXNzZXJ0X25vdF9yZWFjaGVkICgpOwogICAgICAgIGVycm5vID0gRU5PU1lTOwojZW5kaWYKICAgICAgICBicmVhazsKICAgICAgfQogICAgICBjYXNlIEdTVF9QT0xMX01PREVfUFNFTEVDVDoKI2lmbmRlZiBIQVZFX1BTRUxFQ1QKICAgICAgewogICAgICAgIGdfYXNzZXJ0X25vdF9yZWFjaGVkICgpOwogICAgICAgIGVycm5vID0gRU5PU1lTOwogICAgICAgIGJyZWFrOwogICAgICB9CiNlbmRpZgogICAgICBjYXNlIEdTVF9QT0xMX01PREVfU0VMRUNUOgogICAgICB7CiNpZm5kZWYgR19PU19XSU4zMgogICAgICAgIGZkX3NldCByZWFkZmRzOwogICAgICAgIGZkX3NldCB3cml0ZWZkczsKICAgICAgICBmZF9zZXQgZXJyb3JmZHM7CiAgICAgICAgZ2ludCBtYXhfZmQ7CgogICAgICAgIG1heF9mZCA9IHBvbGxmZF90b19mZF9zZXQgKHNldCwgJnJlYWRmZHMsICZ3cml0ZWZkcywgJmVycm9yZmRzKTsKCiAgICAgICAgaWYgKG1vZGUgPT0gR1NUX1BPTExfTU9ERV9TRUxFQ1QpIHsKICAgICAgICAgIHN0cnVjdCB0aW1ldmFsIHR2OwogICAgICAgICAgc3RydWN0IHRpbWV2YWwgKnR2cHRyOwoKICAgICAgICAgIGlmICh0aW1lb3V0ICE9IEdTVF9DTE9DS19USU1FX05PTkUpIHsKICAgICAgICAgICAgR1NUX1RJTUVfVE9fVElNRVZBTCAodGltZW91dCwgdHYpOwogICAgICAgICAgICB0dnB0ciA9ICZ0djsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHR2cHRyID0gTlVMTDsKICAgICAgICAgIH0KCiAgICAgICAgICBHU1RfREVCVUcgKCJDYWxsaW5nIHNlbGVjdCIpOwogICAgICAgICAgcmVzID0gc2VsZWN0IChtYXhfZmQgKyAxLCAmcmVhZGZkcywgJndyaXRlZmRzLCAmZXJyb3JmZHMsIHR2cHRyKTsKICAgICAgICAgIEdTVF9ERUJVRyAoIkFmdGVyIHNlbGVjdCwgcmVzOiVkIiwgcmVzKTsKICAgICAgICB9IGVsc2UgewojaWZkZWYgSEFWRV9QU0VMRUNUCiAgICAgICAgICBzdHJ1Y3QgdGltZXNwZWMgdHM7CiAgICAgICAgICBzdHJ1Y3QgdGltZXNwZWMgKnRzcHRyOwoKICAgICAgICAgIGlmICh0aW1lb3V0ICE9IEdTVF9DTE9DS19USU1FX05PTkUpIHsKICAgICAgICAgICAgR1NUX1RJTUVfVE9fVElNRVNQRUMgKHRpbWVvdXQsIHRzKTsKICAgICAgICAgICAgdHNwdHIgPSAmdHM7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICB0c3B0ciA9IE5VTEw7CiAgICAgICAgICB9CgogICAgICAgICAgR1NUX0RFQlVHICgiQ2FsbGluZyBwc2VsZWN0Iik7CiAgICAgICAgICByZXMgPQogICAgICAgICAgICAgIHBzZWxlY3QgKG1heF9mZCArIDEsICZyZWFkZmRzLCAmd3JpdGVmZHMsICZlcnJvcmZkcywgdHNwdHIsIE5VTEwpOwogICAgICAgICAgR1NUX0RFQlVHICgiQWZ0ZXIgcHNlbGVjdCwgcmVzOiVkIiwgcmVzKTsKI2VuZGlmCiAgICAgICAgfQoKICAgICAgICBpZiAocmVzID49IDApIHsKICAgICAgICAgIGZkX3NldF90b19wb2xsZmQgKHNldCwgJnJlYWRmZHMsICZ3cml0ZWZkcywgJmVycm9yZmRzKTsKICAgICAgICB9CiNlbHNlIC8qIEdfT1NfV0lOMzIgKi8KICAgICAgICBnX2Fzc2VydF9ub3RfcmVhY2hlZCAoKTsKICAgICAgICBlcnJubyA9IEVOT1NZUzsKI2VuZGlmCiAgICAgICAgYnJlYWs7CiAgICAgIH0KICAgICAgY2FzZSBHU1RfUE9MTF9NT0RFX1dJTkRPV1M6CiAgICAgIHsKI2lmZGVmIEdfT1NfV0lOMzIKICAgICAgICBnaW50IGlnbm9yZV9jb3VudCA9IHNldC0+YWN0aXZlX2Zkc19pZ25vcmVkLT5sZW47CiAgICAgICAgRFdPUkQgdCwgd2FpdF9yZXQ7CgogICAgICAgIGlmIChHX0xJS0VMWSAoaWdub3JlX2NvdW50ID09IDApKSB7CiAgICAgICAgICBpZiAodGltZW91dCAhPSBHU1RfQ0xPQ0tfVElNRV9OT05FKQogICAgICAgICAgICB0ID0gR1NUX1RJTUVfQVNfTVNFQ09ORFMgKHRpbWVvdXQpOwogICAgICAgICAgZWxzZQogICAgICAgICAgICB0ID0gSU5GSU5JVEU7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIC8qIGFscmVhZHkgb25lIG9yIG1vcmUgaWdub3JlZCBmZHMsIHNvIHdlIHF1aWNrbHkgc3dlZXAgdGhlIG90aGVycyAqLwogICAgICAgICAgdCA9IDA7CiAgICAgICAgfQoKICAgICAgICBpZiAoc2V0LT5hY3RpdmVfZXZlbnRzLT5sZW4gIT0gMCkgewogICAgICAgICAgd2FpdF9yZXQgPSBXU0FXYWl0Rm9yTXVsdGlwbGVFdmVudHMgKHNldC0+YWN0aXZlX2V2ZW50cy0+bGVuLAogICAgICAgICAgICAgIChIQU5ETEUgKikgc2V0LT5hY3RpdmVfZXZlbnRzLT5kYXRhLCBGQUxTRSwgdCwgRkFMU0UpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICB3YWl0X3JldCA9IFdTQV9XQUlUX0ZBSUxFRDsKICAgICAgICAgIFdTQVNldExhc3RFcnJvciAoV1NBX0lOVkFMSURfUEFSQU1FVEVSKTsKICAgICAgICB9CgogICAgICAgIGlmIChpZ25vcmVfY291bnQgPT0gMCAmJiB3YWl0X3JldCA9PSBXU0FfV0FJVF9USU1FT1VUKSB7CiAgICAgICAgICByZXMgPSAwOwogICAgICAgIH0gZWxzZSBpZiAod2FpdF9yZXQgPT0gV1NBX1dBSVRfRkFJTEVEKSB7CiAgICAgICAgICByZXMgPSAtMTsKICAgICAgICAgIGVycm5vID0gZ3N0X3BvbGxfd2luc29ja19lcnJvcl90b19lcnJubyAoV1NBR2V0TGFzdEVycm9yICgpKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgLyogdGhlIGZpcnN0IGVudHJ5IGlzIHRoZSB3YWtldXAgZXZlbnQgKi8KICAgICAgICAgIGlmICh3YWl0X3JldCAtIFdTQV9XQUlUX0VWRU5UXzAgPj0gMSkgewogICAgICAgICAgICByZXMgPSBnc3RfcG9sbF9jb2xsZWN0X3dpbnNvY2tfZXZlbnRzIChzZXQpOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgcmVzID0gMTsgICAgICAgICAgICAvKiB3YWtldXAgZXZlbnQgKi8KICAgICAgICAgIH0KICAgICAgICB9CiNlbHNlCiAgICAgICAgZ19hc3NlcnRfbm90X3JlYWNoZWQgKCk7CiAgICAgICAgZXJybm8gPSBFTk9TWVM7CiNlbmRpZgogICAgICAgIGJyZWFrOwogICAgICB9CiAgICB9CgogICAgaWYgKCFpc190aW1lcikgewogICAgICAvKiBBcHBsaWNhdGlvbnMgbmVlZHMgdG8gY2xlYXIgdGhlIGNvbnRyb2wgc29ja2V0IHRoZW1zZWx2ZXMgZm9yIHRpbWVyCiAgICAgICAqIHBvbGxzLgogICAgICAgKiBGb3Igb3RoZXIgcG9sbHMsIHdlIG5lZWQgdG8gY2xlYXIgdGhlIGNvbnRyb2wgc29ja2V0LiBJZiB0aGVyZSB3YXMgb25seQogICAgICAgKiBvbmUgc29ja2V0IHdpdGggYWN0aXZpdHkgYW5kIGl0IHdhcyB0aGUgY29udHJvbCBzb2NrZXQsIHdlIG5lZWQgdG8KICAgICAgICogcmVzdGFydCAqLwogICAgICBpZiAocmVsZWFzZV9hbGxfd2FrZXVwIChzZXQpID4gMCAmJiByZXMgPT0gMSkKICAgICAgICByZXN0YXJ0aW5nID0gVFJVRTsKICAgIH0KCiAgICAvKiB3ZSBnb3Qgd29rZW4gdXAgYW5kIHdlIGFyZSBmbHVzaGluZywgd2UgbmVlZCB0byBzdG9wICovCiAgICBpZiAoR19VTkxJS0VMWSAoSVNfRkxVU0hJTkcgKHNldCkpKQogICAgICBnb3RvIGZsdXNoaW5nOwoKICB9IHdoaWxlIChHX1VOTElLRUxZIChyZXN0YXJ0aW5nKSk7CgogIERFQ19XQUlUSU5HIChzZXQpOwoKICByZXR1cm4gcmVzOwoKICAvKiBFUlJPUlMgKi8KYWxyZWFkeV93YWl0aW5nOgogIHsKICAgIEdTVF9MT0cgKCIlcDogd2UgYXJlIGFscmVhZHkgd2FpdGluZyIsIHNldCk7CiAgICBERUNfV0FJVElORyAoc2V0KTsKICAgIGVycm5vID0gRVBFUk07CiAgICByZXR1cm4gLTE7CiAgfQpmbHVzaGluZzoKICB7CiAgICBHU1RfTE9HICgiJXA6IHdlIGFyZSBmbHVzaGluZyIsIHNldCk7CiAgICBERUNfV0FJVElORyAoc2V0KTsKICAgIGVycm5vID0gRUJVU1k7CiAgICByZXR1cm4gLTE7CiAgfQojaWZkZWYgR19PU19XSU4zMgp3aW5zb2NrX2Vycm9yOgogIHsKICAgIEdTVF9MT0cgKCIlcDogd2luc29jayBlcnJvciIsIHNldCk7CiAgICBnX211dGV4X3VubG9jayAoc2V0LT5sb2NrKTsKICAgIERFQ19XQUlUSU5HIChzZXQpOwogICAgcmV0dXJuIC0xOwogIH0KI2VuZGlmCn0KCi8qKgogKiBnc3RfcG9sbF9zZXRfY29udHJvbGxhYmxlOgogKiBAc2V0OiBhICNHc3RQb2xsLgogKiBAY29udHJvbGxhYmxlOiBuZXcgY29udHJvbGxhYmxlIHN0YXRlLgogKgogKiBXaGVuIEBjb250cm9sbGFibGUgaXMgJVRSVUUsIHRoaXMgZnVuY3Rpb24gZW5zdXJlcyB0aGF0IGZ1dHVyZSBjYWxscyB0bwogKiBnc3RfcG9sbF93YWl0KCkgd2lsbCBiZSBhZmZlY3RlZCBieSBnc3RfcG9sbF9yZXN0YXJ0KCkgYW5kCiAqIGdzdF9wb2xsX3NldF9mbHVzaGluZygpLgogKgogKiBSZXR1cm5zOiAlVFJVRSBpZiB0aGUgY29udHJvbGxhYmlsaXR5IG9mIEBzZXQgY291bGQgYmUgdXBkYXRlZC4KICoKICogU2luY2U6IDAuMTAuMTgKICovCmdib29sZWFuCmdzdF9wb2xsX3NldF9jb250cm9sbGFibGUgKEdzdFBvbGwgKiBzZXQsIGdib29sZWFuIGNvbnRyb2xsYWJsZSkKewogIGdfcmV0dXJuX3ZhbF9pZl9mYWlsIChzZXQgIT0gTlVMTCwgRkFMU0UpOwoKICBHU1RfTE9HICgiJXA6IGNvbnRyb2xsYWJsZSA6ICVkIiwgc2V0LCBjb250cm9sbGFibGUpOwoKICBzZXQtPmNvbnRyb2xsYWJsZSA9IGNvbnRyb2xsYWJsZTsKCiAgcmV0dXJuIFRSVUU7Cn0KCi8qKgogKiBnc3RfcG9sbF9yZXN0YXJ0OgogKiBAc2V0OiBhICNHc3RQb2xsLgogKgogKiBSZXN0YXJ0IGFueSBnc3RfcG9sbF93YWl0KCkgdGhhdCBpcyBpbiBwcm9ncmVzcy4gVGhpcyBmdW5jdGlvbiBpcyB0eXBpY2FsbHkKICogdXNlZCBhZnRlciBhZGRpbmcgb3IgcmVtb3ZpbmcgZGVzY3JpcHRvcnMgdG8gQHNldC4KICoKICogSWYgQHNldCBpcyBub3QgY29udHJvbGxhYmxlLCB0aGVuIHRoaXMgY2FsbCB3aWxsIGhhdmUgbm8gZWZmZWN0LgogKgogKiBTaW5jZTogMC4xMC4xOAogKi8Kdm9pZApnc3RfcG9sbF9yZXN0YXJ0IChHc3RQb2xsICogc2V0KQp7CiAgZ19yZXR1cm5faWZfZmFpbCAoc2V0ICE9IE5VTEwpOwoKICBpZiAoc2V0LT5jb250cm9sbGFibGUgJiYgR0VUX1dBSVRJTkcgKHNldCkgPiAwKSB7CiAgICAvKiB3ZSBhcmUgY29udHJvbGxhYmxlIGFuZCB3YWl0aW5nLCB3YWtlIHVwIHRoZSB3YWl0ZXIuIFRoZSBzb2NrZXQgd2lsbCBiZQogICAgICogY2xlYXJlZCBieSB0aGUgX3dhaXQoKSB0aHJlYWQgYW5kIHRoZSBwb2xsIHdpbGwgYmUgcmVzdGFydGVkICovCiAgICByYWlzZV93YWtldXAgKHNldCk7CiAgfQp9CgovKioKICogZ3N0X3BvbGxfc2V0X2ZsdXNoaW5nOgogKiBAc2V0OiBhICNHc3RQb2xsLgogKiBAZmx1c2hpbmc6IG5ldyBmbHVzaGluZyBzdGF0ZS4KICoKICogV2hlbiBAZmx1c2hpbmcgaXMgJVRSVUUsIHRoaXMgZnVuY3Rpb24gZW5zdXJlcyB0aGF0IGN1cnJlbnQgYW5kIGZ1dHVyZSBjYWxscwogKiB0byBnc3RfcG9sbF93YWl0KCkgd2lsbCByZXR1cm4gLTEsIHdpdGggZXJybm8gc2V0IHRvIEVCVVNZLgogKgogKiBVbnNldHRpbmcgdGhlIGZsdXNoaW5nIHN0YXRlIHdpbGwgcmVzdG9yZSBub3JtYWwgb3BlcmF0aW9uIG9mIEBzZXQuCiAqCiAqIFNpbmNlOiAwLjEwLjE4CiAqLwp2b2lkCmdzdF9wb2xsX3NldF9mbHVzaGluZyAoR3N0UG9sbCAqIHNldCwgZ2Jvb2xlYW4gZmx1c2hpbmcpCnsKICBnX3JldHVybl9pZl9mYWlsIChzZXQgIT0gTlVMTCk7CgogIEdTVF9MT0cgKCIlcDogZmx1c2hpbmc6ICVkIiwgc2V0LCBmbHVzaGluZyk7CgogIC8qIHVwZGF0ZSB0aGUgbmV3IHN0YXRlIGZpcnN0ICovCiAgU0VUX0ZMVVNISU5HIChzZXQsIGZsdXNoaW5nKTsKCiAgaWYgKGZsdXNoaW5nICYmIHNldC0+Y29udHJvbGxhYmxlICYmIEdFVF9XQUlUSU5HIChzZXQpID4gMCkgewogICAgLyogd2UgYXJlIGZsdXNoaW5nLCBjb250cm9sbGFibGUgYW5kIHdhaXRpbmcsIHdha2UgdXAgdGhlIHdhaXRlci4gV2hlbiB3ZQogICAgICogc3RvcCB0aGUgZmx1c2hpbmcgb3BlcmF0aW9uIHdlIGRvbid0IGNsZWFyIHRoZSB3YWtldXAgZmQgaGVyZSwgdGhpcyB3aWxsCiAgICAgKiBoYXBwZW4gaW4gdGhlIF93YWl0KCkgdGhyZWFkLiAqLwogICAgcmFpc2Vfd2FrZXVwIChzZXQpOwogIH0KfQoKLyoqCiAqIGdzdF9wb2xsX3dyaXRlX2NvbnRyb2w6CiAqIEBzZXQ6IGEgI0dzdFBvbGwuCiAqCiAqIFdyaXRlIGEgYnl0ZSB0byB0aGUgY29udHJvbCBzb2NrZXQgb2YgdGhlIGNvbnRyb2xsYWJsZSBAc2V0LgogKiBUaGlzIGZ1bmN0aW9uIGlzIG1vc3RseSB1c2VmdWwgZm9yIHRpbWVyICNHc3RQb2xsIG9iamVjdHMgY3JlYXRlZCB3aXRoCiAqIGdzdF9wb2xsX25ld190aW1lcigpLiAKICoKICogSXQgd2lsbCBtYWtlIGFueSBjdXJyZW50IGFuZCBmdXR1cmUgZ3N0X3BvbGxfd2FpdCgpIGZ1bmN0aW9uIHJldHVybiB3aXRoCiAqIDEsIG1lYW5pbmcgdGhlIGNvbnRyb2wgc29ja2V0IGlzIHNldC4gQWZ0ZXIgYW4gZXF1YWwgYW1vdW50IG9mIGNhbGxzIHRvCiAqIGdzdF9wb2xsX3JlYWRfY29udHJvbCgpIGhhdmUgYmVlbiBwZXJmb3JtZWQsIGNhbGxzIHRvIGdzdF9wb2xsX3dhaXQoKSB3aWxsCiAqIGJsb2NrIGFnYWluIHVudGlsIHRoZWlyIHRpbWVvdXQgZXhwaXJlZC4KICoKICogUmV0dXJuczogJVRSVUUgb24gc3VjY2Vzcy4gJUZBTFNFIHdoZW4gQHNldCBpcyBub3QgY29udHJvbGxhYmxlIG9yIHdoZW4gdGhlCiAqIGJ5dGUgY291bGQgbm90IGJlIHdyaXR0ZW4uCiAqCiAqIFNpbmNlOiAwLjEwLjIzCiAqLwpnYm9vbGVhbgpnc3RfcG9sbF93cml0ZV9jb250cm9sIChHc3RQb2xsICogc2V0KQp7CiAgZ2Jvb2xlYW4gcmVzOwoKICBnX3JldHVybl92YWxfaWZfZmFpbCAoc2V0ICE9IE5VTEwsIEZBTFNFKTsKICBnX3JldHVybl92YWxfaWZfZmFpbCAoc2V0LT50aW1lciwgRkFMU0UpOwoKICByZXMgPSByYWlzZV93YWtldXAgKHNldCk7CgogIHJldHVybiByZXM7Cn0KCi8qKgogKiBnc3RfcG9sbF9yZWFkX2NvbnRyb2w6CiAqIEBzZXQ6IGEgI0dzdFBvbGwuCiAqCiAqIFJlYWQgYSBieXRlIGZyb20gdGhlIGNvbnRyb2wgc29ja2V0IG9mIHRoZSBjb250cm9sbGFibGUgQHNldC4KICogVGhpcyBmdW5jdGlvbiBpcyBtb3N0bHkgdXNlZnVsIGZvciB0aW1lciAjR3N0UG9sbCBvYmplY3RzIGNyZWF0ZWQgd2l0aAogKiBnc3RfcG9sbF9uZXdfdGltZXIoKS4gCiAqCiAqIFJldHVybnM6ICVUUlVFIG9uIHN1Y2Nlc3MuICVGQUxTRSB3aGVuIEBzZXQgaXMgbm90IGNvbnRyb2xsYWJsZSBvciB3aGVuIHRoZXJlCiAqIHdhcyBubyBieXRlIHRvIHJlYWQuCiAqCiAqIFNpbmNlOiAwLjEwLjIzCiAqLwpnYm9vbGVhbgpnc3RfcG9sbF9yZWFkX2NvbnRyb2wgKEdzdFBvbGwgKiBzZXQpCnsKICBnYm9vbGVhbiByZXM7CgogIGdfcmV0dXJuX3ZhbF9pZl9mYWlsIChzZXQgIT0gTlVMTCwgRkFMU0UpOwogIGdfcmV0dXJuX3ZhbF9pZl9mYWlsIChzZXQtPnRpbWVyLCBGQUxTRSk7CgogIHJlcyA9IHJlbGVhc2Vfd2FrZXVwIChzZXQpOwoKICByZXR1cm4gcmVzOwp9Cg==