LyogR1N0cmVhbWVyCiAqIENvcHlyaWdodCAoQykgMTk5OSBFcmlrIFdhbHRoaW5zZW4gPG9tZWdhQGNzZS5vZ2kuZWR1PgogKiBDb3B5cmlnaHQgKEMpIDIwMDQgV2ltIFRheW1hbnMgPHdpbS50YXltYW5zQGdtYWlsLmNvbT4KICogQ29weXJpZ2h0IChDKSAyMDA3IFBldGVyIEtqZWxsZXJzdGVkdCA8cGtqQGF4aXMuY29tPgogKiBDb3B5cmlnaHQgKEMpIDIwMDggT2xlIEFuZHLpIFZhZGxhIFJhdm7lcyA8b2xlLmFuZHJlLnJhdm5hc0B0YW5kYmVyZy5jb20+CiAqCiAqIGdzdHBvbGwuYzogRmlsZSBkZXNjcmlwdG9yIHNldAogKgogKiBUaGlzIGxpYnJhcnkgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yCiAqIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMaWJyYXJ5IEdlbmVyYWwgUHVibGljCiAqIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlcgogKiB2ZXJzaW9uIDIgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLAogKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZgogKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVQogKiBMaWJyYXJ5IEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIExpYnJhcnkgR2VuZXJhbCBQdWJsaWMKICogTGljZW5zZSBhbG9uZyB3aXRoIHRoaXMgbGlicmFyeTsgaWYgbm90LCB3cml0ZSB0byB0aGUKICogRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBJbmMuLCA1OSBUZW1wbGUgUGxhY2UgLSBTdWl0ZSAzMzAsCiAqIEJvc3RvbiwgTUEgMDIxMTEtMTMwNywgVVNBLgogKi8KLyoqCiAqIFNFQ1RJT046Z3N0cG9sbAogKiBAc2hvcnRfZGVzY3JpcHRpb246IEtlZXAgdHJhY2sgb2YgZmlsZSBkZXNjcmlwdG9ycyBhbmQgbWFrZSBpdCBwb3NzaWJsZQogKiAgICAgICAgICAgICAgICAgICAgIHRvIHdhaXQgb24gdGhlbSBpbiBhIGNhbmNlbGFibGUgd2F5CiAqCiAqIEEgI0dzdFBvbGwga2VlcHMgdHJhY2sgb2YgZmlsZSBkZXNjcmlwdG9ycyBtdWNoIGxpa2UgZmRfc2V0ICh1c2VkIHdpdGgKICogc2VsZWN0KCkpIG9yIGEgc3RydWN0IHBvbGxmZCBhcnJheSAodXNlZCB3aXRoIHBvbGwoKSkuIE9uY2UgY3JlYXRlZCB3aXRoCiAqIGdzdF9wb2xsX25ldygpLCB0aGUgc2V0IGNhbiBiZSB1c2VkIHRvIHdhaXQgZm9yIGZpbGUgZGVzY3JpcHRvcnMgdG8gYmUKICogcmVhZGFibGUgYW5kL29yIHdyaXRhYmxlLiBJdCBpcyBwb3NzaWJsZSB0byBtYWtlIHRoaXMgd2FpdCBiZSBjb250cm9sbGVkCiAqIGJ5IHNwZWNpZnlpbmcgJVRSVUUgZm9yIHRoZSBAY29udHJvbGxhYmxlIGZsYWcgd2hlbiBjcmVhdGluZyB0aGUgc2V0IChvcgogKiBsYXRlciBjYWxsaW5nIGdzdF9wb2xsX3NldF9jb250cm9sbGFibGUoKSkuCiAqCiAqIE5ldyBmaWxlIGRlc2NyaXB0b3JzIGFyZSBhZGRlZCB0byB0aGUgc2V0IHVzaW5nIGdzdF9wb2xsX2FkZF9mZCgpLCBhbmQKICogcmVtb3ZlZCB1c2luZyBnc3RfcG9sbF9yZW1vdmVfZmQoKS4gQ29udHJvbGxpbmcgd2hpY2ggZmlsZSBkZXNjcmlwdG9ycwogKiBzaG91bGQgYmUgd2FpdGVkIGZvciB0byBiZWNvbWUgcmVhZGFibGUgYW5kL29yIHdyaXRhYmxlIGFyZSBkb25lIHVzaW5nCiAqIGdzdF9wb2xsX2ZkX2N0bF9yZWFkKCkgYW5kIGdzdF9wb2xsX2ZkX2N0bF93cml0ZSgpLgogKgogKiBVc2UgZ3N0X3BvbGxfd2FpdCgpIHRvIHdhaXQgZm9yIHRoZSBmaWxlIGRlc2NyaXB0b3JzIHRvIGFjdHVhbGx5IGJlY29tZQogKiByZWFkYWJsZSBhbmQvb3Igd3JpdGFibGUsIG9yIHRvIHRpbWVvdXQgaWYgbm8gZmlsZSBkZXNjcmlwdG9yIGlzIGF2YWlsYWJsZQogKiBpbiB0aW1lLiBUaGUgd2FpdCBjYW4gYmUgY29udHJvbGxlZCBieSBjYWxsaW5nIGdzdF9wb2xsX3Jlc3RhcnQoKSBhbmQKICogZ3N0X3BvbGxfc2V0X2ZsdXNoaW5nKCkuCiAqCiAqIE9uY2UgdGhlIGZpbGUgZGVzY3JpcHRvciBzZXQgaGFzIGJlZW4gd2FpdGVkIGZvciwgb25lIGNhbiB1c2UKICogZ3N0X3BvbGxfZmRfaGFzX2Nsb3NlZCgpIHRvIHNlZSBpZiB0aGUgZmlsZSBkZXNjcmlwdG9yIGhhcyBiZWVuIGNsb3NlZCwKICogZ3N0X3BvbGxfZmRfaGFzX2Vycm9yKCkgdG8gc2VlIGlmIGl0IGhhcyBnZW5lcmF0ZWQgYW4gZXJyb3IsCiAqIGdzdF9wb2xsX2ZkX2Nhbl9yZWFkKCkgdG8gc2VlIGlmIGl0IGlzIHBvc3NpYmxlIHRvIHJlYWQgZnJvbSB0aGUgZmlsZQogKiBkZXNjcmlwdG9yLCBhbmQgZ3N0X3BvbGxfZmRfY2FuX3dyaXRlKCkgdG8gc2VlIGlmIGl0IGlzIHBvc3NpYmxlIHRvCiAqIHdyaXRlIHRvIGl0LgogKgogKi8KCiNpZmRlZiBIQVZFX0NPTkZJR19ICiNpbmNsdWRlICJjb25maWcuaCIKI2VuZGlmCgojaW5jbHVkZSAiZ3N0X3ByaXZhdGUuaCIKI2luY2x1ZGUgImdsaWItY29tcGF0LXByaXZhdGUuaCIKCiNpbmNsdWRlIDxzeXMvdHlwZXMuaD4KCiNpZmRlZiBIQVZFX1VOSVNURF9ICiNpbmNsdWRlIDx1bmlzdGQuaD4KI2VuZGlmCgojaW5jbHVkZSA8ZXJybm8uaD4KI2luY2x1ZGUgPGZjbnRsLmg+CgojaW5jbHVkZSA8Z2xpYi5oPgoKI2lmZGVmIEdfT1NfV0lOMzIKI2luY2x1ZGUgPHdpbnNvY2syLmg+CiNkZWZpbmUgRUlOUFJPR1JFU1MgV1NBRUlOUFJPR1JFU1MKI2Vsc2UKI2RlZmluZSBfR05VX1NPVVJDRSAxCiNpZmRlZiBIQVZFX1NZU19QT0xMX0gKI2luY2x1ZGUgPHN5cy9wb2xsLmg+CiNlbmRpZgojaWZkZWYgSEFWRV9QT0xMX0gKI2luY2x1ZGUgPHBvbGwuaD4KI2VuZGlmCiNpbmNsdWRlIDxzeXMvdGltZS5oPgojaW5jbHVkZSA8c3lzL3NvY2tldC5oPgojZW5kaWYKCi8qIE9TL1ggbmVlZHMgdGhpcyBiZWNhdXNlIG9mIGJhZCBoZWFkZXJzICovCiNpbmNsdWRlIDxzdHJpbmcuaD4KCi8qIFRoZSBwb2xsKCkgZW11bGF0aW9uIG9uIE9TL1ggZG9lc24ndCBoYW5kbGUgZmRzPU5VTEwsIG5mZHM9MCwKICogc28gd2UgcHJlZmVyIG91ciBvd24gcG9sbCBlbXVsYXRpb24uCiAqLwojaWYgZGVmaW5lZChCUk9LRU5fUE9MTCkKI3VuZGVmIEhBVkVfUE9MTAojZW5kaWYKCiNpbmNsdWRlICJnc3Rwb2xsLmgiCgojZGVmaW5lIEdTVF9DQVRfREVGQVVMVCBHU1RfQ0FUX1BPTEwKCiNpZmRlZiBHX09TX1dJTjMyCnR5cGVkZWYgc3RydWN0IF9XaW5zb2NrRmQgV2luc29ja0ZkOwoKc3RydWN0IF9XaW5zb2NrRmQKewogIGdpbnQgZmQ7CiAgZ2xvbmcgZXZlbnRfbWFzazsKICBXU0FORVRXT1JLRVZFTlRTIGV2ZW50czsKICBnbG9uZyBpZ25vcmVkX2V2ZW50X21hc2s7Cn07CiNlbmRpZgoKdHlwZWRlZiBlbnVtCnsKICBHU1RfUE9MTF9NT0RFX0FVVE8sCiAgR1NUX1BPTExfTU9ERV9TRUxFQ1QsCiAgR1NUX1BPTExfTU9ERV9QU0VMRUNULAogIEdTVF9QT0xMX01PREVfUE9MTCwKICBHU1RfUE9MTF9NT0RFX1BQT0xMLAogIEdTVF9QT0xMX01PREVfV0lORE9XUwp9IEdzdFBvbGxNb2RlOwoKc3RydWN0IF9Hc3RQb2xsCnsKICBHc3RQb2xsTW9kZSBtb2RlOwoKICBHTXV0ZXggbG9jazsKICAvKiBhcnJheSBvZiBmZHMsIGFsd2F5cyB3cml0dGVuIHRvIGFuZCByZWFkIGZyb20gd2l0aCBsb2NrICovCiAgR0FycmF5ICpmZHM7CiAgLyogYXJyYXkgb2YgYWN0aXZlIGZkcywgb25seSB3cml0dGVuIHRvIGZyb20gdGhlIHdhaXRpbmcgdGhyZWFkIHdpdGggdGhlCiAgICogbG9jayBhbmQgcmVhZCBmcm9tIHdpdGggdGhlIGxvY2sgb3Igd2l0aG91dCB0aGUgbG9jayBmcm9tIHRoZSB3YWl0aW5nCiAgICogdGhyZWFkICovCiAgR0FycmF5ICphY3RpdmVfZmRzOwoKI2lmbmRlZiBHX09TX1dJTjMyCiAgZ2NoYXIgYnVmWzFdOwogIEdzdFBvbGxGRCBjb250cm9sX3JlYWRfZmQ7CiAgR3N0UG9sbEZEIGNvbnRyb2xfd3JpdGVfZmQ7CiNlbHNlCiAgR0FycmF5ICphY3RpdmVfZmRzX2lnbm9yZWQ7CiAgR0FycmF5ICpldmVudHM7CiAgR0FycmF5ICphY3RpdmVfZXZlbnRzOwoKICBIQU5ETEUgd2FrZXVwX2V2ZW50OwojZW5kaWYKCiAgZ2Jvb2xlYW4gY29udHJvbGxhYmxlOwogIHZvbGF0aWxlIGdpbnQgd2FpdGluZzsKICB2b2xhdGlsZSBnaW50IGNvbnRyb2xfcGVuZGluZzsKICB2b2xhdGlsZSBnaW50IGZsdXNoaW5nOwogIGdib29sZWFuIHRpbWVyOwogIHZvbGF0aWxlIGdpbnQgcmVidWlsZDsKfTsKCnN0YXRpYyBnYm9vbGVhbiBnc3RfcG9sbF9mZF9jdGxfcmVhZF91bmxvY2tlZCAoR3N0UG9sbCAqIHNldCwgR3N0UG9sbEZEICogZmQsCiAgICBnYm9vbGVhbiBhY3RpdmUpOwpzdGF0aWMgZ2Jvb2xlYW4gZ3N0X3BvbGxfYWRkX2ZkX3VubG9ja2VkIChHc3RQb2xsICogc2V0LCBHc3RQb2xsRkQgKiBmZCk7CgojZGVmaW5lIElTX0ZMVVNISU5HKHMpICAgICAgKGdfYXRvbWljX2ludF9nZXQoJihzKS0+Zmx1c2hpbmcpKQojZGVmaW5lIFNFVF9GTFVTSElORyhzLHZhbCkgKGdfYXRvbWljX2ludF9zZXQoJihzKS0+Zmx1c2hpbmcsICh2YWwpKSkKCiNkZWZpbmUgSU5DX1dBSVRJTkcocykgICAgICAoZ19hdG9taWNfaW50X2FkZCgmKHMpLT53YWl0aW5nLCAxKSkKI2RlZmluZSBERUNfV0FJVElORyhzKSAgICAgIChnX2F0b21pY19pbnRfYWRkKCYocyktPndhaXRpbmcsIC0xKSkKI2RlZmluZSBHRVRfV0FJVElORyhzKSAgICAgIChnX2F0b21pY19pbnRfZ2V0KCYocyktPndhaXRpbmcpKQoKI2RlZmluZSBURVNUX1JFQlVJTEQocykgICAgIChnX2F0b21pY19pbnRfY29tcGFyZV9hbmRfZXhjaGFuZ2UoJihzKS0+cmVidWlsZCwgMSwgMCkpCiNkZWZpbmUgTUFSS19SRUJVSUxEKHMpICAgICAoZ19hdG9taWNfaW50X3NldCgmKHMpLT5yZWJ1aWxkLCAxKSkKCiNpZm5kZWYgR19PU19XSU4zMgojZGVmaW5lIFdBS0VfRVZFTlQocykgICAgICAgKHdyaXRlICgocyktPmNvbnRyb2xfd3JpdGVfZmQuZmQsICJXIiwgMSkgPT0gMSkKI2RlZmluZSBSRUxFQVNFX0VWRU5UKHMpICAgIChyZWFkICgocyktPmNvbnRyb2xfcmVhZF9mZC5mZCwgKHMpLT5idWYsIDEpID09IDEpCiNlbHNlCiNkZWZpbmUgV0FLRV9FVkVOVChzKSAgICAgICAoU2V0RXZlbnQgKChzKS0+d2FrZXVwX2V2ZW50KSwgZXJybm8gPSBHZXRMYXN0RXJyb3IgKCkgPT0gTk9fRVJST1IgPyAwIDogRUFDQ0VTLCBlcnJubyA9PSAwID8gMSA6IDApCiNkZWZpbmUgUkVMRUFTRV9FVkVOVChzKSAgICAoUmVzZXRFdmVudCAoKHMpLT53YWtldXBfZXZlbnQpKQojZW5kaWYKCi8qIHRoZSBwb2xsL3NlbGVjdCBjYWxsIGlzIGFsc28gcGVyZm9ybWVkIG9uIGEgY29udHJvbCBzb2NrZXQsIHRoYXQgd2F5CiAqIHdlIGNhbiBzZW5kIHNwZWNpYWwgY29tbWFuZHMgdG8gY29udHJvbCBpdCAqLwpzdGF0aWMgaW5saW5lIGdib29sZWFuCnJhaXNlX3dha2V1cCAoR3N0UG9sbCAqIHNldCkKewogIGdib29sZWFuIHJlc3VsdCA9IFRSVUU7CgogIGlmIChnX2F0b21pY19pbnRfYWRkICgmc2V0LT5jb250cm9sX3BlbmRpbmcsIDEpID09IDApIHsKICAgIC8qIHJhaXNlIHdoZW4gbm90aGluZyBwZW5kaW5nICovCiAgICBHU1RfTE9HICgiJXA6IHJhaXNlIiwgc2V0KTsKICAgIHJlc3VsdCA9IFdBS0VfRVZFTlQgKHNldCk7CiAgfQogIHJldHVybiByZXN1bHQ7Cn0KCi8qIG5vdGUgaG93IGJhZCB0aGluZ3MgY2FuIGhhcHBlbiB3aGVuIHRoZSAyIHRocmVhZHMgYm90aCByYWlzZSBhbmQgcmVsZWFzZSB0aGUKICogd2FrZXVwLiBUaGlzIGlzIGhvd2V2ZXIgbm90IGEgcHJvYmxlbSBiZWNhdXNlIHlvdSBtdXN0IGFsd2F5cyBwYWlyIGEgcmFpc2UKICogd2l0aCBhIHJlbGVhc2UgKi8Kc3RhdGljIGlubGluZSBnYm9vbGVhbgpyZWxlYXNlX3dha2V1cCAoR3N0UG9sbCAqIHNldCkKewogIGdib29sZWFuIHJlc3VsdCA9IFRSVUU7CgogIGlmIChnX2F0b21pY19pbnRfZGVjX2FuZF90ZXN0ICgmc2V0LT5jb250cm9sX3BlbmRpbmcpKSB7CiAgICBHU1RfTE9HICgiJXA6IHJlbGVhc2UiLCBzZXQpOwogICAgcmVzdWx0ID0gUkVMRUFTRV9FVkVOVCAoc2V0KTsKICB9CiAgcmV0dXJuIHJlc3VsdDsKfQoKc3RhdGljIGlubGluZSBnaW50CnJlbGVhc2VfYWxsX3dha2V1cCAoR3N0UG9sbCAqIHNldCkKewogIGdpbnQgb2xkOwoKICB3aGlsZSAoVFJVRSkgewogICAgaWYgKCEob2xkID0gZ19hdG9taWNfaW50X2dldCAoJnNldC0+Y29udHJvbF9wZW5kaW5nKSkpCiAgICAgIC8qIG5vdGhpbmcgcGVuZGluZywganVzdCBleGl0ICovCiAgICAgIGJyZWFrOwoKICAgIC8qIHRyeSB0byByZW1vdmUgYWxsIHBlbmRpbmcgY29udHJvbCBtZXNzYWdlcyAqLwogICAgaWYgKGdfYXRvbWljX2ludF9jb21wYXJlX2FuZF9leGNoYW5nZSAoJnNldC0+Y29udHJvbF9wZW5kaW5nLCBvbGQsIDApKSB7CiAgICAgIC8qIHdlIG1hbmFnZWQgdG8gcmVtb3ZlIGFsbCBtZXNzYWdlcywgcmVhZCB0aGUgY29udHJvbCBzb2NrZXQgKi8KICAgICAgaWYgKFJFTEVBU0VfRVZFTlQgKHNldCkpCiAgICAgICAgYnJlYWs7CiAgICAgIGVsc2UKICAgICAgICAvKiByZXRyeSBhZ2FpbiB1bnRpbCB3ZSByZWFkIGl0IHN1Y2Nlc3NmdWxseSAqLwogICAgICAgIGdfYXRvbWljX2ludF9hZGQgKCZzZXQtPmNvbnRyb2xfcGVuZGluZywgMSk7CiAgICB9CiAgfQogIHJldHVybiBvbGQ7Cn0KCnN0YXRpYyBnaW50CmZpbmRfaW5kZXggKEdBcnJheSAqIGFycmF5LCBHc3RQb2xsRkQgKiBmZCkKewojaWZuZGVmIEdfT1NfV0lOMzIKICBzdHJ1Y3QgcG9sbGZkICppZmQ7CiNlbHNlCiAgV2luc29ja0ZkICppZmQ7CiNlbmRpZgogIGd1aW50IGk7CgogIC8qIHN0YXJ0IGJ5IGFzc3VtaW5nIHRoZSBpbmRleCBmb3VuZCBpbiB0aGUgZmQgaXMgc3RpbGwgdmFsaWQgKi8KICBpZiAoZmQtPmlkeCA+PSAwICYmIGZkLT5pZHggPCBhcnJheS0+bGVuKSB7CiNpZm5kZWYgR19PU19XSU4zMgogICAgaWZkID0gJmdfYXJyYXlfaW5kZXggKGFycmF5LCBzdHJ1Y3QgcG9sbGZkLCBmZC0+aWR4KTsKI2Vsc2UKICAgIGlmZCA9ICZnX2FycmF5X2luZGV4IChhcnJheSwgV2luc29ja0ZkLCBmZC0+aWR4KTsKI2VuZGlmCgogICAgaWYgKGlmZC0+ZmQgPT0gZmQtPmZkKSB7CiAgICAgIHJldHVybiBmZC0+aWR4OwogICAgfQogIH0KCiAgLyogdGhlIHBvbGxmZCBhcnJheSBoYXMgY2hhbmdlZCBhbmQgd2UgbmVlZCB0byBsb29rdXAgdGhlIGZkIGFnYWluICovCiAgZm9yIChpID0gMDsgaSA8IGFycmF5LT5sZW47IGkrKykgewojaWZuZGVmIEdfT1NfV0lOMzIKICAgIGlmZCA9ICZnX2FycmF5X2luZGV4IChhcnJheSwgc3RydWN0IHBvbGxmZCwgaSk7CiNlbHNlCiAgICBpZmQgPSAmZ19hcnJheV9pbmRleCAoYXJyYXksIFdpbnNvY2tGZCwgaSk7CiNlbmRpZgoKICAgIGlmIChpZmQtPmZkID09IGZkLT5mZCkgewogICAgICBmZC0+aWR4ID0gKGdpbnQpIGk7CiAgICAgIHJldHVybiBmZC0+aWR4OwogICAgfQogIH0KCiAgZmQtPmlkeCA9IC0xOwogIHJldHVybiBmZC0+aWR4Owp9CgojaWYgIWRlZmluZWQoSEFWRV9QUE9MTCkgJiYgZGVmaW5lZChIQVZFX1BPTEwpCi8qIGNoZWNrIGlmIGFsbCBmaWxlIGRlc2NyaXB0b3JzIHdpbGwgZml0IGluIGFuIGZkX3NldCAqLwpzdGF0aWMgZ2Jvb2xlYW4Kc2VsZWN0YWJsZV9mZHMgKGNvbnN0IEdzdFBvbGwgKiBzZXQpCnsKICBndWludCBpOwoKICBnX211dGV4X2xvY2sgKCZzZXQtPmxvY2spOwogIGZvciAoaSA9IDA7IGkgPCBzZXQtPmZkcy0+bGVuOyBpKyspIHsKICAgIHN0cnVjdCBwb2xsZmQgKnBmZCA9ICZnX2FycmF5X2luZGV4IChzZXQtPmZkcywgc3RydWN0IHBvbGxmZCwgaSk7CgogICAgaWYgKHBmZC0+ZmQgPj0gRkRfU0VUU0laRSkKICAgICAgZ290byB0b29fbWFueTsKICB9CiAgZ19tdXRleF91bmxvY2sgKCZzZXQtPmxvY2spOwoKICByZXR1cm4gVFJVRTsKCnRvb19tYW55OgogIHsKICAgIGdfbXV0ZXhfdW5sb2NrICgmc2V0LT5sb2NrKTsKICAgIHJldHVybiBGQUxTRTsKICB9Cn0KCi8qIGNoZWNrIGlmIHRoZSB0aW1lb3V0IHdpbGwgY29udmVydCB0byBhIHRpbWVvdXQgdmFsdWUgdXNlZCBmb3IgcG9sbCgpCiAqIHdpdGhvdXQgYSBsb3NzIG9mIHByZWNpc2lvbgogKi8Kc3RhdGljIGdib29sZWFuCnBvbGxhYmxlX3RpbWVvdXQgKEdzdENsb2NrVGltZSB0aW1lb3V0KQp7CiAgaWYgKHRpbWVvdXQgPT0gR1NUX0NMT0NLX1RJTUVfTk9ORSkKICAgIHJldHVybiBUUlVFOwoKICAvKiBub3QgYSBuaWNlIG11bHRpcGxlIG9mIG1pbGxpc2Vjb25kcyAqLwogIGlmICh0aW1lb3V0ICUgMTAwMDAwMCkKICAgIHJldHVybiBGQUxTRTsKCiAgcmV0dXJuIFRSVUU7Cn0KI2VuZGlmCgpzdGF0aWMgR3N0UG9sbE1vZGUKY2hvb3NlX21vZGUgKGNvbnN0IEdzdFBvbGwgKiBzZXQsIEdzdENsb2NrVGltZSB0aW1lb3V0KQp7CiAgR3N0UG9sbE1vZGUgbW9kZTsKCiAgaWYgKHNldC0+bW9kZSA9PSBHU1RfUE9MTF9NT0RFX0FVVE8pIHsKI2lmZGVmIEhBVkVfUFBPTEwKICAgIG1vZGUgPSBHU1RfUE9MTF9NT0RFX1BQT0xMOwojZWxpZiBkZWZpbmVkKEhBVkVfUE9MTCkKICAgIGlmICghc2VsZWN0YWJsZV9mZHMgKHNldCkgfHwgcG9sbGFibGVfdGltZW91dCAodGltZW91dCkpIHsKICAgICAgbW9kZSA9IEdTVF9QT0xMX01PREVfUE9MTDsKICAgIH0gZWxzZSB7CiNpZmRlZiBIQVZFX1BTRUxFQ1QKICAgICAgbW9kZSA9IEdTVF9QT0xMX01PREVfUFNFTEVDVDsKI2Vsc2UKICAgICAgbW9kZSA9IEdTVF9QT0xMX01PREVfU0VMRUNUOwojZW5kaWYKICAgIH0KI2VsaWYgZGVmaW5lZChIQVZFX1BTRUxFQ1QpCiAgICBtb2RlID0gR1NUX1BPTExfTU9ERV9QU0VMRUNUOwojZWxzZQogICAgbW9kZSA9IEdTVF9QT0xMX01PREVfU0VMRUNUOwojZW5kaWYKICB9IGVsc2UgewogICAgbW9kZSA9IHNldC0+bW9kZTsKICB9CiAgcmV0dXJuIG1vZGU7Cn0KCiNpZm5kZWYgR19PU19XSU4zMgpzdGF0aWMgZ2ludApwb2xsZmRfdG9fZmRfc2V0IChHc3RQb2xsICogc2V0LCBmZF9zZXQgKiByZWFkZmRzLCBmZF9zZXQgKiB3cml0ZWZkcywKICAgIGZkX3NldCAqIGVycm9yZmRzKQp7CiAgZ2ludCBtYXhfZmQgPSAtMTsKICBndWludCBpOwoKICBGRF9aRVJPIChyZWFkZmRzKTsKICBGRF9aRVJPICh3cml0ZWZkcyk7CiAgRkRfWkVSTyAoZXJyb3JmZHMpOwoKICBnX211dGV4X2xvY2sgKCZzZXQtPmxvY2spOwoKICBmb3IgKGkgPSAwOyBpIDwgc2V0LT5hY3RpdmVfZmRzLT5sZW47IGkrKykgewogICAgc3RydWN0IHBvbGxmZCAqcGZkID0gJmdfYXJyYXlfaW5kZXggKHNldC0+ZmRzLCBzdHJ1Y3QgcG9sbGZkLCBpKTsKCiAgICBpZiAocGZkLT5mZCA8IEZEX1NFVFNJWkUpIHsKICAgICAgaWYgKHBmZC0+ZXZlbnRzICYgUE9MTElOKQogICAgICAgIEZEX1NFVCAocGZkLT5mZCwgcmVhZGZkcyk7CiAgICAgIGlmIChwZmQtPmV2ZW50cyAmIFBPTExPVVQpCiAgICAgICAgRkRfU0VUIChwZmQtPmZkLCB3cml0ZWZkcyk7CiAgICAgIGlmIChwZmQtPmV2ZW50cykKICAgICAgICBGRF9TRVQgKHBmZC0+ZmQsIGVycm9yZmRzKTsKICAgICAgaWYgKHBmZC0+ZmQgPiBtYXhfZmQgJiYgKHBmZC0+ZXZlbnRzICYgKFBPTExJTiB8IFBPTExPVVQpKSkKICAgICAgICBtYXhfZmQgPSBwZmQtPmZkOwogICAgfQogIH0KCiAgZ19tdXRleF91bmxvY2sgKCZzZXQtPmxvY2spOwoKICByZXR1cm4gbWF4X2ZkOwp9CgpzdGF0aWMgdm9pZApmZF9zZXRfdG9fcG9sbGZkIChHc3RQb2xsICogc2V0LCBmZF9zZXQgKiByZWFkZmRzLCBmZF9zZXQgKiB3cml0ZWZkcywKICAgIGZkX3NldCAqIGVycm9yZmRzKQp7CiAgZ3VpbnQgaTsKCiAgZ19tdXRleF9sb2NrICgmc2V0LT5sb2NrKTsKCiAgZm9yIChpID0gMDsgaSA8IHNldC0+YWN0aXZlX2Zkcy0+bGVuOyBpKyspIHsKICAgIHN0cnVjdCBwb2xsZmQgKnBmZCA9ICZnX2FycmF5X2luZGV4IChzZXQtPmFjdGl2ZV9mZHMsIHN0cnVjdCBwb2xsZmQsIGkpOwoKICAgIGlmIChwZmQtPmZkIDwgRkRfU0VUU0laRSkgewogICAgICBwZmQtPnJldmVudHMgPSAwOwogICAgICBpZiAoRkRfSVNTRVQgKHBmZC0+ZmQsIHJlYWRmZHMpKQogICAgICAgIHBmZC0+cmV2ZW50cyB8PSBQT0xMSU47CiAgICAgIGlmIChGRF9JU1NFVCAocGZkLT5mZCwgd3JpdGVmZHMpKQogICAgICAgIHBmZC0+cmV2ZW50cyB8PSBQT0xMT1VUOwogICAgICBpZiAoRkRfSVNTRVQgKHBmZC0+ZmQsIGVycm9yZmRzKSkKICAgICAgICBwZmQtPnJldmVudHMgfD0gUE9MTEVSUjsKICAgIH0KICB9CgogIGdfbXV0ZXhfdW5sb2NrICgmc2V0LT5sb2NrKTsKfQojZWxzZSAvKiBHX09TX1dJTjMyICovCi8qCiAqIFRyYW5zbGF0ZSBlcnJvcnMgdGhyb3duIGJ5IHRoZSBXaW5zb2NrIEFQSSB1c2VkIGJ5IEdzdFBvbGw6CiAqICAgV1NBRXZlbnRTZWxlY3QsIFdTQVdhaXRGb3JNdWx0aXBsZUV2ZW50cyBhbmQgV1NBRW51bU5ldHdvcmtFdmVudHMKICovCnN0YXRpYyBnaW50CmdzdF9wb2xsX3dpbnNvY2tfZXJyb3JfdG9fZXJybm8gKERXT1JEIGxhc3RfZXJyb3IpCnsKICBzd2l0Y2ggKGxhc3RfZXJyb3IpIHsKICAgIGNhc2UgV1NBX0lOVkFMSURfSEFORExFOgogICAgY2FzZSBXU0FFSU5WQUw6CiAgICBjYXNlIFdTQUVOT1RTT0NLOgogICAgICByZXR1cm4gRUJBREY7CgogICAgY2FzZSBXU0FfTk9UX0VOT1VHSF9NRU1PUlk6CiAgICAgIHJldHVybiBFTk9NRU07CgogICAgICAvKgogICAgICAgKiBBbnl0aGluZyBlbHNlLCBpbmNsdWRpbmc6CiAgICAgICAqICAgV1NBX0lOVkFMSURfUEFSQU1FVEVSLCBXU0FFRkFVTFQsIFdTQUVJTlBST0dSRVNTLCBXU0FFTkVURE9XTiwKICAgICAgICogICBXU0FOT1RJTklUSUFMSVNFRAogICAgICAgKi8KICAgIGRlZmF1bHQ6CiAgICAgIHJldHVybiBFSU5WQUw7CiAgfQp9CgpzdGF0aWMgdm9pZApnc3RfcG9sbF9mcmVlX3dpbnNvY2tfZXZlbnQgKEdzdFBvbGwgKiBzZXQsIGdpbnQgaWR4KQp7CiAgV2luc29ja0ZkICp3ZmQgPSAmZ19hcnJheV9pbmRleCAoc2V0LT5mZHMsIFdpbnNvY2tGZCwgaWR4KTsKICBIQU5ETEUgZXZlbnQgPSBnX2FycmF5X2luZGV4IChzZXQtPmV2ZW50cywgSEFORExFLCBpZHgpOwoKICBXU0FFdmVudFNlbGVjdCAod2ZkLT5mZCwgZXZlbnQsIDApOwogIENsb3NlSGFuZGxlIChldmVudCk7Cn0KCnN0YXRpYyB2b2lkCmdzdF9wb2xsX3VwZGF0ZV93aW5zb2NrX2V2ZW50X21hc2sgKEdzdFBvbGwgKiBzZXQsIGdpbnQgaWR4LCBnbG9uZyBmbGFncywKICAgIGdib29sZWFuIGFjdGl2ZSkKewogIFdpbnNvY2tGZCAqd2ZkOwoKICB3ZmQgPSAmZ19hcnJheV9pbmRleCAoc2V0LT5mZHMsIFdpbnNvY2tGZCwgaWR4KTsKCiAgaWYgKGFjdGl2ZSkKICAgIHdmZC0+ZXZlbnRfbWFzayB8PSBmbGFnczsKICBlbHNlCiAgICB3ZmQtPmV2ZW50X21hc2sgJj0gfmZsYWdzOwoKICAvKiByZXNldCBpZ25vcmVkIHN0YXRlIGlmIHRoZSBuZXcgbWFzayBkb2Vzbid0IG92ZXJsYXAgYXQgYWxsICovCiAgaWYgKCh3ZmQtPmlnbm9yZWRfZXZlbnRfbWFzayAmIHdmZC0+ZXZlbnRfbWFzaykgPT0gMCkKICAgIHdmZC0+aWdub3JlZF9ldmVudF9tYXNrID0gMDsKfQoKc3RhdGljIGdib29sZWFuCmdzdF9wb2xsX3ByZXBhcmVfd2luc29ja19hY3RpdmVfc2V0cyAoR3N0UG9sbCAqIHNldCkKewogIGd1aW50IGk7CgogIGdfYXJyYXlfc2V0X3NpemUgKHNldC0+YWN0aXZlX2ZkcywgMCk7CiAgZ19hcnJheV9zZXRfc2l6ZSAoc2V0LT5hY3RpdmVfZmRzX2lnbm9yZWQsIDApOwogIGdfYXJyYXlfc2V0X3NpemUgKHNldC0+YWN0aXZlX2V2ZW50cywgMCk7CiAgZ19hcnJheV9hcHBlbmRfdmFsIChzZXQtPmFjdGl2ZV9ldmVudHMsIHNldC0+d2FrZXVwX2V2ZW50KTsKCiAgZm9yIChpID0gMDsgaSA8IHNldC0+ZmRzLT5sZW47IGkrKykgewogICAgV2luc29ja0ZkICp3ZmQgPSAmZ19hcnJheV9pbmRleCAoc2V0LT5mZHMsIFdpbnNvY2tGZCwgaSk7CiAgICBIQU5ETEUgZXZlbnQgPSBnX2FycmF5X2luZGV4IChzZXQtPmV2ZW50cywgSEFORExFLCBpKTsKCiAgICBpZiAod2ZkLT5pZ25vcmVkX2V2ZW50X21hc2sgPT0gMCkgewogICAgICBnaW50IHJldDsKCiAgICAgIGdfYXJyYXlfYXBwZW5kX3ZhbCAoc2V0LT5hY3RpdmVfZmRzLCAqd2ZkKTsKICAgICAgZ19hcnJheV9hcHBlbmRfdmFsIChzZXQtPmFjdGl2ZV9ldmVudHMsIGV2ZW50KTsKCiAgICAgIHJldCA9IFdTQUV2ZW50U2VsZWN0ICh3ZmQtPmZkLCBldmVudCwgd2ZkLT5ldmVudF9tYXNrKTsKICAgICAgaWYgKEdfVU5MSUtFTFkgKHJldCAhPSAwKSkgewogICAgICAgIGVycm5vID0gZ3N0X3BvbGxfd2luc29ja19lcnJvcl90b19lcnJubyAoV1NBR2V0TGFzdEVycm9yICgpKTsKICAgICAgICByZXR1cm4gRkFMU0U7CiAgICAgIH0KICAgIH0gZWxzZSB7CiAgICAgIGdfYXJyYXlfYXBwZW5kX3ZhbCAoc2V0LT5hY3RpdmVfZmRzX2lnbm9yZWQsIHdmZCk7CiAgICB9CiAgfQoKICByZXR1cm4gVFJVRTsKfQoKc3RhdGljIGdpbnQKZ3N0X3BvbGxfY29sbGVjdF93aW5zb2NrX2V2ZW50cyAoR3N0UG9sbCAqIHNldCkKewogIGdpbnQgcmVzLCBpOwoKICAvKgogICAqIFdlIG5lZWQgdG8gY2hlY2sgd2hpY2ggZXZlbnRzIGFyZSBzaWduYWxlZCwgYW5kIGNhbGwKICAgKiBXU0FFbnVtTmV0d29ya0V2ZW50cyBmb3IgdGhvc2UgdGhhdCBhcmUsIHdoaWNoIHJlc2V0cwogICAqIHRoZSBldmVudCBhbmQgY2xlYXJzIHRoZSBpbnRlcm5hbCBuZXR3b3JrIGV2ZW50IHJlY29yZHMuCiAgICovCiAgcmVzID0gMDsKICBmb3IgKGkgPSAwOyBpIDwgc2V0LT5hY3RpdmVfZmRzLT5sZW47IGkrKykgewogICAgV2luc29ja0ZkICp3ZmQgPSAmZ19hcnJheV9pbmRleCAoc2V0LT5hY3RpdmVfZmRzLCBXaW5zb2NrRmQsIGkpOwogICAgSEFORExFIGV2ZW50ID0gZ19hcnJheV9pbmRleCAoc2V0LT5hY3RpdmVfZXZlbnRzLCBIQU5ETEUsIGkgKyAxKTsKICAgIERXT1JEIHdhaXRfcmV0OwoKICAgIHdhaXRfcmV0ID0gV2FpdEZvclNpbmdsZU9iamVjdCAoZXZlbnQsIDApOwogICAgaWYgKHdhaXRfcmV0ID09IFdBSVRfT0JKRUNUXzApIHsKICAgICAgZ2ludCBlbnVtX3JldCA9IFdTQUVudW1OZXR3b3JrRXZlbnRzICh3ZmQtPmZkLCBldmVudCwgJndmZC0+ZXZlbnRzKTsKCiAgICAgIGlmIChHX1VOTElLRUxZIChlbnVtX3JldCAhPSAwKSkgewogICAgICAgIHJlcyA9IC0xOwogICAgICAgIGVycm5vID0gZ3N0X3BvbGxfd2luc29ja19lcnJvcl90b19lcnJubyAoV1NBR2V0TGFzdEVycm9yICgpKTsKICAgICAgICBicmVhazsKICAgICAgfQoKICAgICAgcmVzKys7CiAgICB9IGVsc2UgewogICAgICAvKiBjbGVhciBhbnkgcHJldmlvdXNseSBzdG9yZWQgcmVzdWx0ICovCiAgICAgIG1lbXNldCAoJndmZC0+ZXZlbnRzLCAwLCBzaXplb2YgKHdmZC0+ZXZlbnRzKSk7CiAgICB9CiAgfQoKICAvKiBJZiBhbGwgd2VudCB3ZWxsIHdlIGFsc28gbmVlZCB0byByZXNldCB0aGUgaWdub3JlZCBmZHMuICovCiAgaWYgKHJlcyA+PSAwKSB7CiAgICByZXMgKz0gc2V0LT5hY3RpdmVfZmRzX2lnbm9yZWQtPmxlbjsKCiAgICBmb3IgKGkgPSAwOyBpIDwgc2V0LT5hY3RpdmVfZmRzX2lnbm9yZWQtPmxlbjsgaSsrKSB7CiAgICAgIFdpbnNvY2tGZCAqd2ZkID0gZ19hcnJheV9pbmRleCAoc2V0LT5hY3RpdmVfZmRzX2lnbm9yZWQsIFdpbnNvY2tGZCAqLCBpKTsKCiAgICAgIHdmZC0+aWdub3JlZF9ldmVudF9tYXNrID0gMDsKICAgIH0KCiAgICBnX2FycmF5X3NldF9zaXplIChzZXQtPmFjdGl2ZV9mZHNfaWdub3JlZCwgMCk7CiAgfQoKICByZXR1cm4gcmVzOwp9CiNlbmRpZgoKLyoqCiAqIGdzdF9wb2xsX25ldzogKHNraXApCiAqIEBjb250cm9sbGFibGU6IHdoZXRoZXIgaXQgc2hvdWxkIGJlIHBvc3NpYmxlIHRvIGNvbnRyb2wgYSB3YWl0LgogKgogKiBDcmVhdGUgYSBuZXcgZmlsZSBkZXNjcmlwdG9yIHNldC4gSWYgQGNvbnRyb2xsYWJsZSwgaXQKICogaXMgcG9zc2libGUgdG8gcmVzdGFydCBvciBmbHVzaCBhIGNhbGwgdG8gZ3N0X3BvbGxfd2FpdCgpIHdpdGgKICogZ3N0X3BvbGxfcmVzdGFydCgpIGFuZCBnc3RfcG9sbF9zZXRfZmx1c2hpbmcoKSByZXNwZWN0aXZlbHkuCiAqCiAqIEZyZWUtZnVuY3Rpb246IGdzdF9wb2xsX2ZyZWUKICoKICogUmV0dXJuczogKHRyYW5zZmVyIGZ1bGwpOiBhIG5ldyAjR3N0UG9sbCwgb3IgJU5VTEwgaW4gY2FzZSBvZiBhbiBlcnJvci4KICogICAgIEZyZWUgd2l0aCBnc3RfcG9sbF9mcmVlKCkuCiAqCiAqIFNpbmNlOiAwLjEwLjE4CiAqLwpHc3RQb2xsICoKZ3N0X3BvbGxfbmV3IChnYm9vbGVhbiBjb250cm9sbGFibGUpCnsKICBHc3RQb2xsICpuc2V0OwoKICBHU1RfREVCVUcgKCJjb250cm9sbGFibGUgOiAlZCIsIGNvbnRyb2xsYWJsZSk7CgogIG5zZXQgPSBnX3NsaWNlX25ldzAgKEdzdFBvbGwpOwogIGdfbXV0ZXhfaW5pdCAoJm5zZXQtPmxvY2spOwojaWZuZGVmIEdfT1NfV0lOMzIKICBuc2V0LT5tb2RlID0gR1NUX1BPTExfTU9ERV9BVVRPOwogIG5zZXQtPmZkcyA9IGdfYXJyYXlfbmV3IChGQUxTRSwgRkFMU0UsIHNpemVvZiAoc3RydWN0IHBvbGxmZCkpOwogIG5zZXQtPmFjdGl2ZV9mZHMgPSBnX2FycmF5X25ldyAoRkFMU0UsIEZBTFNFLCBzaXplb2YgKHN0cnVjdCBwb2xsZmQpKTsKICBuc2V0LT5jb250cm9sX3JlYWRfZmQuZmQgPSAtMTsKICBuc2V0LT5jb250cm9sX3dyaXRlX2ZkLmZkID0gLTE7CiAgewogICAgZ2ludCBjb250cm9sX3NvY2tbMl07CgogICAgaWYgKHNvY2tldHBhaXIgKFBGX1VOSVgsIFNPQ0tfU1RSRUFNLCAwLCBjb250cm9sX3NvY2spIDwgMCkKICAgICAgZ290byBub19zb2NrZXRfcGFpcjsKCiAgICBmY250bCAoY29udHJvbF9zb2NrWzBdLCBGX1NFVEZMLCBPX05PTkJMT0NLKTsKICAgIGZjbnRsIChjb250cm9sX3NvY2tbMV0sIEZfU0VURkwsIE9fTk9OQkxPQ0spOwoKICAgIG5zZXQtPmNvbnRyb2xfcmVhZF9mZC5mZCA9IGNvbnRyb2xfc29ja1swXTsKICAgIG5zZXQtPmNvbnRyb2xfd3JpdGVfZmQuZmQgPSBjb250cm9sX3NvY2tbMV07CgogICAgZ3N0X3BvbGxfYWRkX2ZkX3VubG9ja2VkIChuc2V0LCAmbnNldC0+Y29udHJvbF9yZWFkX2ZkKTsKICAgIGdzdF9wb2xsX2ZkX2N0bF9yZWFkX3VubG9ja2VkIChuc2V0LCAmbnNldC0+Y29udHJvbF9yZWFkX2ZkLCBUUlVFKTsKICB9CiNlbHNlCiAgbnNldC0+bW9kZSA9IEdTVF9QT0xMX01PREVfV0lORE9XUzsKICBuc2V0LT5mZHMgPSBnX2FycmF5X25ldyAoRkFMU0UsIEZBTFNFLCBzaXplb2YgKFdpbnNvY2tGZCkpOwogIG5zZXQtPmFjdGl2ZV9mZHMgPSBnX2FycmF5X25ldyAoRkFMU0UsIEZBTFNFLCBzaXplb2YgKFdpbnNvY2tGZCkpOwogIG5zZXQtPmFjdGl2ZV9mZHNfaWdub3JlZCA9IGdfYXJyYXlfbmV3IChGQUxTRSwgRkFMU0UsIHNpemVvZiAoV2luc29ja0ZkICopKTsKICBuc2V0LT5ldmVudHMgPSBnX2FycmF5X25ldyAoRkFMU0UsIEZBTFNFLCBzaXplb2YgKEhBTkRMRSkpOwogIG5zZXQtPmFjdGl2ZV9ldmVudHMgPSBnX2FycmF5X25ldyAoRkFMU0UsIEZBTFNFLCBzaXplb2YgKEhBTkRMRSkpOwoKICBuc2V0LT53YWtldXBfZXZlbnQgPSBDcmVhdGVFdmVudCAoTlVMTCwgVFJVRSwgRkFMU0UsIE5VTEwpOwojZW5kaWYKCiAgLyogZW5zdXJlIChyZSlidWlsZCwgdGhvdWdoIGFscmVhZHkgc25lYWtpbHkgc2V0IGluIG5vbi13aW5kb3dzIGNhc2UgKi8KICBNQVJLX1JFQlVJTEQgKG5zZXQpOwoKICBuc2V0LT5jb250cm9sbGFibGUgPSBjb250cm9sbGFibGU7CgogIHJldHVybiBuc2V0OwoKICAvKiBFUlJPUlMgKi8KI2lmbmRlZiBHX09TX1dJTjMyCm5vX3NvY2tldF9wYWlyOgogIHsKICAgIEdTVF9XQVJOSU5HICgiJXA6IGNhbid0IGNyZWF0ZSBzb2NrZXQgcGFpciAhIiwgbnNldCk7CiAgICBnc3RfcG9sbF9mcmVlIChuc2V0KTsKICAgIHJldHVybiBOVUxMOwogIH0KI2VuZGlmCn0KCi8qKgogKiBnc3RfcG9sbF9uZXdfdGltZXI6IChza2lwKQogKgogKiBDcmVhdGUgYSBuZXcgcG9sbCBvYmplY3QgdGhhdCBjYW4gYmUgdXNlZCBmb3Igc2NoZWR1bGluZyBjYW5jZWxsYWJsZQogKiB0aW1lb3V0cy4KICoKICogQSB0aW1lb3V0IGlzIHBlcmZvcm1lZCB3aXRoIGdzdF9wb2xsX3dhaXQoKS4gTXVsdGlwbGUgdGltZW91dHMgY2FuIGJlCiAqIHBlcmZvcm1lZCBmcm9tIGRpZmZlcmVudCB0aHJlYWRzLiAKICoKICogRnJlZS1mdW5jdGlvbjogZ3N0X3BvbGxfZnJlZQogKgogKiBSZXR1cm5zOiAodHJhbnNmZXIgZnVsbCk6IGEgbmV3ICNHc3RQb2xsLCBvciAlTlVMTCBpbiBjYXNlIG9mIGFuIGVycm9yLgogKiAgICAgRnJlZSB3aXRoIGdzdF9wb2xsX2ZyZWUoKS4KICoKICogU2luY2U6IDAuMTAuMjMKICovCkdzdFBvbGwgKgpnc3RfcG9sbF9uZXdfdGltZXIgKHZvaWQpCnsKICBHc3RQb2xsICpwb2xsOwoKICAvKiBtYWtlIGEgbmV3IGNvbnRyb2xsYWJsZSBwb2xsIHNldCAqLwogIGlmICghKHBvbGwgPSBnc3RfcG9sbF9uZXcgKFRSVUUpKSkKICAgIGdvdG8gZG9uZTsKCiAgLyogd2UgYXJlIGEgdGltZXIgKi8KICBwb2xsLT50aW1lciA9IFRSVUU7Cgpkb25lOgogIHJldHVybiBwb2xsOwp9CgovKioKICogZ3N0X3BvbGxfZnJlZToKICogQHNldDogKHRyYW5zZmVyIGZ1bGwpOiBhIGZpbGUgZGVzY3JpcHRvciBzZXQuCiAqCiAqIEZyZWUgYSBmaWxlIGRlc2NyaXB0b3Igc2V0LgogKgogKiBTaW5jZTogMC4xMC4xOAogKi8Kdm9pZApnc3RfcG9sbF9mcmVlIChHc3RQb2xsICogc2V0KQp7CiAgZ19yZXR1cm5faWZfZmFpbCAoc2V0ICE9IE5VTEwpOwoKICBHU1RfREVCVUcgKCIlcDogZnJlZWluZyIsIHNldCk7CgojaWZuZGVmIEdfT1NfV0lOMzIKICBpZiAoc2V0LT5jb250cm9sX3dyaXRlX2ZkLmZkID49IDApCiAgICBjbG9zZSAoc2V0LT5jb250cm9sX3dyaXRlX2ZkLmZkKTsKICBpZiAoc2V0LT5jb250cm9sX3JlYWRfZmQuZmQgPj0gMCkKICAgIGNsb3NlIChzZXQtPmNvbnRyb2xfcmVhZF9mZC5mZCk7CiNlbHNlCiAgQ2xvc2VIYW5kbGUgKHNldC0+d2FrZXVwX2V2ZW50KTsKCiAgewogICAgZ3VpbnQgaTsKCiAgICBmb3IgKGkgPSAwOyBpIDwgc2V0LT5ldmVudHMtPmxlbjsgaSsrKQogICAgICBnc3RfcG9sbF9mcmVlX3dpbnNvY2tfZXZlbnQgKHNldCwgaSk7CiAgfQoKICBnX2FycmF5X2ZyZWUgKHNldC0+YWN0aXZlX2V2ZW50cywgVFJVRSk7CiAgZ19hcnJheV9mcmVlIChzZXQtPmV2ZW50cywgVFJVRSk7CiAgZ19hcnJheV9mcmVlIChzZXQtPmFjdGl2ZV9mZHNfaWdub3JlZCwgVFJVRSk7CiNlbmRpZgoKICBnX2FycmF5X2ZyZWUgKHNldC0+YWN0aXZlX2ZkcywgVFJVRSk7CiAgZ19hcnJheV9mcmVlIChzZXQtPmZkcywgVFJVRSk7CiAgZ19tdXRleF9jbGVhciAoJnNldC0+bG9jayk7CiAgZ19zbGljZV9mcmVlIChHc3RQb2xsLCBzZXQpOwp9CgovKioKICogZ3N0X3BvbGxfZ2V0X3JlYWRfZ3BvbGxmZDoKICogQHNldDogYSAjR3N0UG9sbAogKiBAZmQ6IGEgI0dQb2xsRkQKICoKICogR2V0IGEgR1BvbGxGRCBmb3IgdGhlIHJlYWRpbmcgcGFydCBvZiB0aGUgY29udHJvbCBzb2NrZXQuIFRoaXMgaXMgdXNlZnVsIHdoZW4KICogaW50ZWdyYXRpbmcgd2l0aCBhIEdTb3VyY2UgYW5kIEdNYWluTG9vcC4KICoKICogU2luY2U6IDAuMTAuMzIKICovCnZvaWQKZ3N0X3BvbGxfZ2V0X3JlYWRfZ3BvbGxmZCAoR3N0UG9sbCAqIHNldCwgR1BvbGxGRCAqIGZkKQp7CiAgZ19yZXR1cm5faWZfZmFpbCAoc2V0ICE9IE5VTEwpOwogIGdfcmV0dXJuX2lmX2ZhaWwgKGZkICE9IE5VTEwpOwoKI2lmbmRlZiBHX09TX1dJTjMyCiAgZmQtPmZkID0gc2V0LT5jb250cm9sX3JlYWRfZmQuZmQ7CiNlbHNlCiNpZiBHTElCX1NJWkVPRl9WT0lEX1AgPT0gOAogIGZkLT5mZCA9IChnaW50NjQpIHNldC0+d2FrZXVwX2V2ZW50OwojZWxzZQogIGZkLT5mZCA9IChnaW50KSBzZXQtPndha2V1cF9ldmVudDsKI2VuZGlmCiNlbmRpZgogIGZkLT5ldmVudHMgPSBHX0lPX0lOIHwgR19JT19IVVAgfCBHX0lPX0VSUjsKICBmZC0+cmV2ZW50cyA9IDA7Cn0KCi8qKgogKiBnc3RfcG9sbF9mZF9pbml0OgogKiBAZmQ6IGEgI0dzdFBvbGxGRAogKgogKiBJbml0aWFsaXplcyBAZmQuIEFsdGVybmF0aXZlbHkgeW91IGNhbiBpbml0aWFsaXplIGl0IHdpdGgKICogI0dTVF9QT0xMX0ZEX0lOSVQuCiAqCiAqIFNpbmNlOiAwLjEwLjE4CiAqLwp2b2lkCmdzdF9wb2xsX2ZkX2luaXQgKEdzdFBvbGxGRCAqIGZkKQp7CiAgZ19yZXR1cm5faWZfZmFpbCAoZmQgIT0gTlVMTCk7CgogIGZkLT5mZCA9IC0xOwogIGZkLT5pZHggPSAtMTsKfQoKc3RhdGljIGdib29sZWFuCmdzdF9wb2xsX2FkZF9mZF91bmxvY2tlZCAoR3N0UG9sbCAqIHNldCwgR3N0UG9sbEZEICogZmQpCnsKICBnaW50IGlkeDsKCiAgR1NUX0RFQlVHICgiJXA6IGZkIChmZDolZCwgaWR4OiVkKSIsIHNldCwgZmQtPmZkLCBmZC0+aWR4KTsKCiAgaWR4ID0gZmluZF9pbmRleCAoc2V0LT5mZHMsIGZkKTsKICBpZiAoaWR4IDwgMCkgewojaWZuZGVmIEdfT1NfV0lOMzIKICAgIHN0cnVjdCBwb2xsZmQgbmZkOwoKICAgIG5mZC5mZCA9IGZkLT5mZDsKICAgIG5mZC5ldmVudHMgPSBQT0xMRVJSIHwgUE9MTE5WQUwgfCBQT0xMSFVQOwogICAgbmZkLnJldmVudHMgPSAwOwoKICAgIGdfYXJyYXlfYXBwZW5kX3ZhbCAoc2V0LT5mZHMsIG5mZCk7CgogICAgZmQtPmlkeCA9IHNldC0+ZmRzLT5sZW4gLSAxOwojZWxzZQogICAgV2luc29ja0ZkIHdmZDsKICAgIEhBTkRMRSBldmVudDsKCiAgICB3ZmQuZmQgPSBmZC0+ZmQ7CiAgICB3ZmQuZXZlbnRfbWFzayA9IEZEX0NMT1NFOwogICAgbWVtc2V0ICgmd2ZkLmV2ZW50cywgMCwgc2l6ZW9mICh3ZmQuZXZlbnRzKSk7CiAgICB3ZmQuaWdub3JlZF9ldmVudF9tYXNrID0gMDsKICAgIGV2ZW50ID0gV1NBQ3JlYXRlRXZlbnQgKCk7CgogICAgZ19hcnJheV9hcHBlbmRfdmFsIChzZXQtPmZkcywgd2ZkKTsKICAgIGdfYXJyYXlfYXBwZW5kX3ZhbCAoc2V0LT5ldmVudHMsIGV2ZW50KTsKCiAgICBmZC0+aWR4ID0gc2V0LT5mZHMtPmxlbiAtIDE7CiNlbmRpZgogICAgTUFSS19SRUJVSUxEIChzZXQpOwogIH0gZWxzZSB7CiAgICBHU1RfV0FSTklORyAoIiVwOiBjb3VsZG4ndCBmaW5kIGZkICEiLCBzZXQpOwogIH0KCiAgcmV0dXJuIFRSVUU7Cn0KCi8qKgogKiBnc3RfcG9sbF9hZGRfZmQ6CiAqIEBzZXQ6IGEgZmlsZSBkZXNjcmlwdG9yIHNldC4KICogQGZkOiBhIGZpbGUgZGVzY3JpcHRvci4KICoKICogQWRkIGEgZmlsZSBkZXNjcmlwdG9yIHRvIHRoZSBmaWxlIGRlc2NyaXB0b3Igc2V0LgogKgogKiBSZXR1cm5zOiAlVFJVRSBpZiB0aGUgZmlsZSBkZXNjcmlwdG9yIHdhcyBzdWNjZXNzZnVsbHkgYWRkZWQgdG8gdGhlIHNldC4KICoKICogU2luY2U6IDAuMTAuMTgKICovCmdib29sZWFuCmdzdF9wb2xsX2FkZF9mZCAoR3N0UG9sbCAqIHNldCwgR3N0UG9sbEZEICogZmQpCnsKICBnYm9vbGVhbiByZXQ7CgogIGdfcmV0dXJuX3ZhbF9pZl9mYWlsIChzZXQgIT0gTlVMTCwgRkFMU0UpOwogIGdfcmV0dXJuX3ZhbF9pZl9mYWlsIChmZCAhPSBOVUxMLCBGQUxTRSk7CiAgZ19yZXR1cm5fdmFsX2lmX2ZhaWwgKGZkLT5mZCA+PSAwLCBGQUxTRSk7CgogIGdfbXV0ZXhfbG9jayAoJnNldC0+bG9jayk7CgogIHJldCA9IGdzdF9wb2xsX2FkZF9mZF91bmxvY2tlZCAoc2V0LCBmZCk7CgogIGdfbXV0ZXhfdW5sb2NrICgmc2V0LT5sb2NrKTsKCiAgcmV0dXJuIHJldDsKfQoKLyoqCiAqIGdzdF9wb2xsX3JlbW92ZV9mZDoKICogQHNldDogYSBmaWxlIGRlc2NyaXB0b3Igc2V0LgogKiBAZmQ6IGEgZmlsZSBkZXNjcmlwdG9yLgogKgogKiBSZW1vdmUgYSBmaWxlIGRlc2NyaXB0b3IgZnJvbSB0aGUgZmlsZSBkZXNjcmlwdG9yIHNldC4KICoKICogUmV0dXJuczogJVRSVUUgaWYgdGhlIGZpbGUgZGVzY3JpcHRvciB3YXMgc3VjY2Vzc2Z1bGx5IHJlbW92ZWQgZnJvbSB0aGUgc2V0LgogKgogKiBTaW5jZTogMC4xMC4xOAogKi8KZ2Jvb2xlYW4KZ3N0X3BvbGxfcmVtb3ZlX2ZkIChHc3RQb2xsICogc2V0LCBHc3RQb2xsRkQgKiBmZCkKewogIGdpbnQgaWR4OwoKICBnX3JldHVybl92YWxfaWZfZmFpbCAoc2V0ICE9IE5VTEwsIEZBTFNFKTsKICBnX3JldHVybl92YWxfaWZfZmFpbCAoZmQgIT0gTlVMTCwgRkFMU0UpOwogIGdfcmV0dXJuX3ZhbF9pZl9mYWlsIChmZC0+ZmQgPj0gMCwgRkFMU0UpOwoKCiAgR1NUX0RFQlVHICgiJXA6IGZkIChmZDolZCwgaWR4OiVkKSIsIHNldCwgZmQtPmZkLCBmZC0+aWR4KTsKCiAgZ19tdXRleF9sb2NrICgmc2V0LT5sb2NrKTsKCiAgLyogZ2V0IHRoZSBpbmRleCwgLTEgaXMgYW4gZmQgdGhhdCBpcyBub3QgYWRkZWQgKi8KICBpZHggPSBmaW5kX2luZGV4IChzZXQtPmZkcywgZmQpOwogIGlmIChpZHggPj0gMCkgewojaWZkZWYgR19PU19XSU4zMgogICAgZ3N0X3BvbGxfZnJlZV93aW5zb2NrX2V2ZW50IChzZXQsIGlkeCk7CiAgICBnX2FycmF5X3JlbW92ZV9pbmRleF9mYXN0IChzZXQtPmV2ZW50cywgaWR4KTsKI2VuZGlmCgogICAgLyogcmVtb3ZlIHRoZSBmZCBhdCBpbmRleCwgd2UgdXNlIF9yZW1vdmVfaW5kZXhfZmFzdCwgd2hpY2ggY29waWVzIHRoZSBsYXN0CiAgICAgKiBlbGVtZW50IG9mIHRoZSBhcnJheSB0byB0aGUgZnJlZWQgaW5kZXggKi8KICAgIGdfYXJyYXlfcmVtb3ZlX2luZGV4X2Zhc3QgKHNldC0+ZmRzLCBpZHgpOwoKICAgIC8qIG1hcmsgZmQgYXMgcmVtb3ZlZCBieSBzZXR0aW5nIHRoZSBpbmRleCB0byAtMSAqLwogICAgZmQtPmlkeCA9IC0xOwogICAgTUFSS19SRUJVSUxEIChzZXQpOwogIH0gZWxzZSB7CiAgICBHU1RfV0FSTklORyAoIiVwOiBjb3VsZG4ndCBmaW5kIGZkICEiLCBzZXQpOwogIH0KCiAgZ19tdXRleF91bmxvY2sgKCZzZXQtPmxvY2spOwoKICByZXR1cm4gaWR4ID49IDA7Cn0KCi8qKgogKiBnc3RfcG9sbF9mZF9jdGxfd3JpdGU6CiAqIEBzZXQ6IGEgZmlsZSBkZXNjcmlwdG9yIHNldC4KICogQGZkOiBhIGZpbGUgZGVzY3JpcHRvci4KICogQGFjdGl2ZTogYSBuZXcgc3RhdHVzLgogKgogKiBDb250cm9sIHdoZXRoZXIgdGhlIGRlc2NyaXB0b3IgQGZkIGluIEBzZXQgd2lsbCBiZSBtb25pdG9yZWQgZm9yCiAqIHdyaXRhYmlsaXR5LgogKgogKiBSZXR1cm5zOiAlVFJVRSBpZiB0aGUgZGVzY3JpcHRvciB3YXMgc3VjY2Vzc2Z1bGx5IHVwZGF0ZWQuCiAqCiAqIFNpbmNlOiAwLjEwLjE4CiAqLwpnYm9vbGVhbgpnc3RfcG9sbF9mZF9jdGxfd3JpdGUgKEdzdFBvbGwgKiBzZXQsIEdzdFBvbGxGRCAqIGZkLCBnYm9vbGVhbiBhY3RpdmUpCnsKICBnaW50IGlkeDsKCiAgZ19yZXR1cm5fdmFsX2lmX2ZhaWwgKHNldCAhPSBOVUxMLCBGQUxTRSk7CiAgZ19yZXR1cm5fdmFsX2lmX2ZhaWwgKGZkICE9IE5VTEwsIEZBTFNFKTsKICBnX3JldHVybl92YWxfaWZfZmFpbCAoZmQtPmZkID49IDAsIEZBTFNFKTsKCiAgR1NUX0RFQlVHICgiJXA6IGZkIChmZDolZCwgaWR4OiVkKSwgYWN0aXZlIDogJWQiLCBzZXQsCiAgICAgIGZkLT5mZCwgZmQtPmlkeCwgYWN0aXZlKTsKCiAgZ19tdXRleF9sb2NrICgmc2V0LT5sb2NrKTsKCiAgaWR4ID0gZmluZF9pbmRleCAoc2V0LT5mZHMsIGZkKTsKICBpZiAoaWR4ID49IDApIHsKI2lmbmRlZiBHX09TX1dJTjMyCiAgICBzdHJ1Y3QgcG9sbGZkICpwZmQgPSAmZ19hcnJheV9pbmRleCAoc2V0LT5mZHMsIHN0cnVjdCBwb2xsZmQsIGlkeCk7CgogICAgaWYgKGFjdGl2ZSkKICAgICAgcGZkLT5ldmVudHMgfD0gUE9MTE9VVDsKICAgIGVsc2UKICAgICAgcGZkLT5ldmVudHMgJj0gflBPTExPVVQ7CgogICAgR1NUX0xPRyAoInBmZC0+ZXZlbnRzIG5vdyAlZCAoUE9MTE9VVDolZCkiLCBwZmQtPmV2ZW50cywgUE9MTE9VVCk7CiNlbHNlCiAgICBnc3RfcG9sbF91cGRhdGVfd2luc29ja19ldmVudF9tYXNrIChzZXQsIGlkeCwgRkRfV1JJVEUgfCBGRF9DT05ORUNULAogICAgICAgIGFjdGl2ZSk7CiNlbmRpZgogICAgTUFSS19SRUJVSUxEIChzZXQpOwogIH0gZWxzZSB7CiAgICBHU1RfV0FSTklORyAoIiVwOiBjb3VsZG4ndCBmaW5kIGZkICEiLCBzZXQpOwogIH0KCiAgZ19tdXRleF91bmxvY2sgKCZzZXQtPmxvY2spOwoKICByZXR1cm4gaWR4ID49IDA7Cn0KCnN0YXRpYyBnYm9vbGVhbgpnc3RfcG9sbF9mZF9jdGxfcmVhZF91bmxvY2tlZCAoR3N0UG9sbCAqIHNldCwgR3N0UG9sbEZEICogZmQsIGdib29sZWFuIGFjdGl2ZSkKewogIGdpbnQgaWR4OwoKICBHU1RfREVCVUcgKCIlcDogZmQgKGZkOiVkLCBpZHg6JWQpLCBhY3RpdmUgOiAlZCIsIHNldCwKICAgICAgZmQtPmZkLCBmZC0+aWR4LCBhY3RpdmUpOwoKICBpZHggPSBmaW5kX2luZGV4IChzZXQtPmZkcywgZmQpOwoKICBpZiAoaWR4ID49IDApIHsKI2lmbmRlZiBHX09TX1dJTjMyCiAgICBzdHJ1Y3QgcG9sbGZkICpwZmQgPSAmZ19hcnJheV9pbmRleCAoc2V0LT5mZHMsIHN0cnVjdCBwb2xsZmQsIGlkeCk7CgogICAgaWYgKGFjdGl2ZSkKICAgICAgcGZkLT5ldmVudHMgfD0gKFBPTExJTiB8IFBPTExQUkkpOwogICAgZWxzZQogICAgICBwZmQtPmV2ZW50cyAmPSB+KFBPTExJTiB8IFBPTExQUkkpOwojZWxzZQogICAgZ3N0X3BvbGxfdXBkYXRlX3dpbnNvY2tfZXZlbnRfbWFzayAoc2V0LCBpZHgsIEZEX1JFQUQgfCBGRF9BQ0NFUFQsIGFjdGl2ZSk7CiNlbmRpZgogICAgTUFSS19SRUJVSUxEIChzZXQpOwogIH0gZWxzZSB7CiAgICBHU1RfV0FSTklORyAoIiVwOiBjb3VsZG4ndCBmaW5kIGZkICEiLCBzZXQpOwogIH0KCiAgcmV0dXJuIGlkeCA+PSAwOwp9CgovKioKICogZ3N0X3BvbGxfZmRfY3RsX3JlYWQ6CiAqIEBzZXQ6IGEgZmlsZSBkZXNjcmlwdG9yIHNldC4KICogQGZkOiBhIGZpbGUgZGVzY3JpcHRvci4KICogQGFjdGl2ZTogYSBuZXcgc3RhdHVzLgogKgogKiBDb250cm9sIHdoZXRoZXIgdGhlIGRlc2NyaXB0b3IgQGZkIGluIEBzZXQgd2lsbCBiZSBtb25pdG9yZWQgZm9yCiAqIHJlYWRhYmlsaXR5LgogKgogKiBSZXR1cm5zOiAlVFJVRSBpZiB0aGUgZGVzY3JpcHRvciB3YXMgc3VjY2Vzc2Z1bGx5IHVwZGF0ZWQuCiAqCiAqIFNpbmNlOiAwLjEwLjE4CiAqLwpnYm9vbGVhbgpnc3RfcG9sbF9mZF9jdGxfcmVhZCAoR3N0UG9sbCAqIHNldCwgR3N0UG9sbEZEICogZmQsIGdib29sZWFuIGFjdGl2ZSkKewogIGdib29sZWFuIHJldDsKCiAgZ19yZXR1cm5fdmFsX2lmX2ZhaWwgKHNldCAhPSBOVUxMLCBGQUxTRSk7CiAgZ19yZXR1cm5fdmFsX2lmX2ZhaWwgKGZkICE9IE5VTEwsIEZBTFNFKTsKICBnX3JldHVybl92YWxfaWZfZmFpbCAoZmQtPmZkID49IDAsIEZBTFNFKTsKCiAgZ19tdXRleF9sb2NrICgmc2V0LT5sb2NrKTsKCiAgcmV0ID0gZ3N0X3BvbGxfZmRfY3RsX3JlYWRfdW5sb2NrZWQgKHNldCwgZmQsIGFjdGl2ZSk7CgogIGdfbXV0ZXhfdW5sb2NrICgmc2V0LT5sb2NrKTsKCiAgcmV0dXJuIHJldDsKfQoKLyoqCiAqIGdzdF9wb2xsX2ZkX2lnbm9yZWQ6CiAqIEBzZXQ6IGEgZmlsZSBkZXNjcmlwdG9yIHNldC4KICogQGZkOiBhIGZpbGUgZGVzY3JpcHRvci4KICoKICogTWFyayBAZmQgYXMgaWdub3JlZCBzbyB0aGF0IHRoZSBuZXh0IGNhbGwgdG8gZ3N0X3BvbGxfd2FpdCgpIHdpbGwgeWllbGQKICogdGhlIHNhbWUgcmVzdWx0IGZvciBAZmQgYXMgbGFzdCB0aW1lLiBUaGlzIGZ1bmN0aW9uIG11c3QgYmUgY2FsbGVkIGlmIG5vCiAqIG9wZXJhdGlvbiAocmVhZC93cml0ZS9yZWN2L3NlbmQvZXRjLikgd2lsbCBiZSBwZXJmb3JtZWQgb24gQGZkIGJlZm9yZQogKiB0aGUgbmV4dCBjYWxsIHRvIGdzdF9wb2xsX3dhaXQoKS4KICoKICogVGhlIHJlYXNvbiB3aHkgdGhpcyBpcyBuZWVkZWQgaXMgYmVjYXVzZSB0aGUgdW5kZXJseWluZyBpbXBsZW1lbnRhdGlvbgogKiBtaWdodCBub3QgYWxsb3cgcXVlcnlpbmcgdGhlIGZkIG1vcmUgdGhhbiBvbmNlIGJldHdlZW4gY2FsbHMgdG8gb25lIG9mCiAqIHRoZSByZS1lbmFibGluZyBvcGVyYXRpb25zLgogKgogKiBTaW5jZTogMC4xMC4xOAogKi8Kdm9pZApnc3RfcG9sbF9mZF9pZ25vcmVkIChHc3RQb2xsICogc2V0LCBHc3RQb2xsRkQgKiBmZCkKewojaWZkZWYgR19PU19XSU4zMgogIGdpbnQgaWR4OwoKICBnX3JldHVybl9pZl9mYWlsIChzZXQgIT0gTlVMTCk7CiAgZ19yZXR1cm5faWZfZmFpbCAoZmQgIT0gTlVMTCk7CiAgZ19yZXR1cm5faWZfZmFpbCAoZmQtPmZkID49IDApOwoKICBnX211dGV4X2xvY2sgKCZzZXQtPmxvY2spOwoKICBpZHggPSBmaW5kX2luZGV4IChzZXQtPmZkcywgZmQpOwogIGlmIChpZHggPj0gMCkgewogICAgV2luc29ja0ZkICp3ZmQgPSAmZ19hcnJheV9pbmRleCAoc2V0LT5mZHMsIFdpbnNvY2tGZCwgaWR4KTsKCiAgICB3ZmQtPmlnbm9yZWRfZXZlbnRfbWFzayA9IHdmZC0+ZXZlbnRfbWFzayAmIChGRF9SRUFEIHwgRkRfV1JJVEUpOwogICAgTUFSS19SRUJVSUxEIChzZXQpOwogIH0KCiAgZ19tdXRleF91bmxvY2sgKCZzZXQtPmxvY2spOwojZW5kaWYKfQoKLyoqCiAqIGdzdF9wb2xsX2ZkX2hhc19jbG9zZWQ6CiAqIEBzZXQ6IGEgZmlsZSBkZXNjcmlwdG9yIHNldC4KICogQGZkOiBhIGZpbGUgZGVzY3JpcHRvci4KICoKICogQ2hlY2sgaWYgQGZkIGluIEBzZXQgaGFzIGNsb3NlZCB0aGUgY29ubmVjdGlvbi4KICoKICogUmV0dXJuczogJVRSVUUgaWYgdGhlIGNvbm5lY3Rpb24gd2FzIGNsb3NlZC4KICoKICogU2luY2U6IDAuMTAuMTgKICovCmdib29sZWFuCmdzdF9wb2xsX2ZkX2hhc19jbG9zZWQgKGNvbnN0IEdzdFBvbGwgKiBzZXQsIEdzdFBvbGxGRCAqIGZkKQp7CiAgZ2Jvb2xlYW4gcmVzID0gRkFMU0U7CiAgZ2ludCBpZHg7CgogIGdfcmV0dXJuX3ZhbF9pZl9mYWlsIChzZXQgIT0gTlVMTCwgRkFMU0UpOwogIGdfcmV0dXJuX3ZhbF9pZl9mYWlsIChmZCAhPSBOVUxMLCBGQUxTRSk7CiAgZ19yZXR1cm5fdmFsX2lmX2ZhaWwgKGZkLT5mZCA+PSAwLCBGQUxTRSk7CgogIEdTVF9ERUJVRyAoIiVwOiBmZCAoZmQ6JWQsIGlkeDolZCkiLCBzZXQsIGZkLT5mZCwgZmQtPmlkeCk7CgogIGdfbXV0ZXhfbG9jayAoJigoR3N0UG9sbCAqKSBzZXQpLT5sb2NrKTsKCiAgaWR4ID0gZmluZF9pbmRleCAoc2V0LT5hY3RpdmVfZmRzLCBmZCk7CiAgaWYgKGlkeCA+PSAwKSB7CiNpZm5kZWYgR19PU19XSU4zMgogICAgc3RydWN0IHBvbGxmZCAqcGZkID0gJmdfYXJyYXlfaW5kZXggKHNldC0+YWN0aXZlX2Zkcywgc3RydWN0IHBvbGxmZCwgaWR4KTsKCiAgICByZXMgPSAocGZkLT5yZXZlbnRzICYgUE9MTEhVUCkgIT0gMDsKI2Vsc2UKICAgIFdpbnNvY2tGZCAqd2ZkID0gJmdfYXJyYXlfaW5kZXggKHNldC0+YWN0aXZlX2ZkcywgV2luc29ja0ZkLCBpZHgpOwoKICAgIHJlcyA9ICh3ZmQtPmV2ZW50cy5sTmV0d29ya0V2ZW50cyAmIEZEX0NMT1NFKSAhPSAwOwojZW5kaWYKICB9IGVsc2UgewogICAgR1NUX1dBUk5JTkcgKCIlcDogY291bGRuJ3QgZmluZCBmZCAhIiwgc2V0KTsKICB9CgogIGdfbXV0ZXhfdW5sb2NrICgmKChHc3RQb2xsICopIHNldCktPmxvY2spOwoKICByZXR1cm4gcmVzOwp9CgovKioKICogZ3N0X3BvbGxfZmRfaGFzX2Vycm9yOgogKiBAc2V0OiBhIGZpbGUgZGVzY3JpcHRvciBzZXQuCiAqIEBmZDogYSBmaWxlIGRlc2NyaXB0b3IuCiAqCiAqIENoZWNrIGlmIEBmZCBpbiBAc2V0IGhhcyBhbiBlcnJvci4KICoKICogUmV0dXJuczogJVRSVUUgaWYgdGhlIGRlc2NyaXB0b3IgaGFzIGFuIGVycm9yLgogKgogKiBTaW5jZTogMC4xMC4xOAogKi8KZ2Jvb2xlYW4KZ3N0X3BvbGxfZmRfaGFzX2Vycm9yIChjb25zdCBHc3RQb2xsICogc2V0LCBHc3RQb2xsRkQgKiBmZCkKewogIGdib29sZWFuIHJlcyA9IEZBTFNFOwogIGdpbnQgaWR4OwoKICBnX3JldHVybl92YWxfaWZfZmFpbCAoc2V0ICE9IE5VTEwsIEZBTFNFKTsKICBnX3JldHVybl92YWxfaWZfZmFpbCAoZmQgIT0gTlVMTCwgRkFMU0UpOwogIGdfcmV0dXJuX3ZhbF9pZl9mYWlsIChmZC0+ZmQgPj0gMCwgRkFMU0UpOwoKICBHU1RfREVCVUcgKCIlcDogZmQgKGZkOiVkLCBpZHg6JWQpIiwgc2V0LCBmZC0+ZmQsIGZkLT5pZHgpOwoKICBnX211dGV4X2xvY2sgKCYoKEdzdFBvbGwgKikgc2V0KS0+bG9jayk7CgogIGlkeCA9IGZpbmRfaW5kZXggKHNldC0+YWN0aXZlX2ZkcywgZmQpOwogIGlmIChpZHggPj0gMCkgewojaWZuZGVmIEdfT1NfV0lOMzIKICAgIHN0cnVjdCBwb2xsZmQgKnBmZCA9ICZnX2FycmF5X2luZGV4IChzZXQtPmFjdGl2ZV9mZHMsIHN0cnVjdCBwb2xsZmQsIGlkeCk7CgogICAgcmVzID0gKHBmZC0+cmV2ZW50cyAmIChQT0xMRVJSIHwgUE9MTE5WQUwpKSAhPSAwOwojZWxzZQogICAgV2luc29ja0ZkICp3ZmQgPSAmZ19hcnJheV9pbmRleCAoc2V0LT5hY3RpdmVfZmRzLCBXaW5zb2NrRmQsIGlkeCk7CgogICAgcmVzID0gKHdmZC0+ZXZlbnRzLmlFcnJvckNvZGVbRkRfQ0xPU0VfQklUXSAhPSAwKSB8fAogICAgICAgICh3ZmQtPmV2ZW50cy5pRXJyb3JDb2RlW0ZEX1JFQURfQklUXSAhPSAwKSB8fAogICAgICAgICh3ZmQtPmV2ZW50cy5pRXJyb3JDb2RlW0ZEX1dSSVRFX0JJVF0gIT0gMCkgfHwKICAgICAgICAod2ZkLT5ldmVudHMuaUVycm9yQ29kZVtGRF9BQ0NFUFRfQklUXSAhPSAwKSB8fAogICAgICAgICh3ZmQtPmV2ZW50cy5pRXJyb3JDb2RlW0ZEX0NPTk5FQ1RfQklUXSAhPSAwKTsKI2VuZGlmCiAgfSBlbHNlIHsKICAgIEdTVF9XQVJOSU5HICgiJXA6IGNvdWxkbid0IGZpbmQgZmQgISIsIHNldCk7CiAgfQoKICBnX211dGV4X3VubG9jayAoJigoR3N0UG9sbCAqKSBzZXQpLT5sb2NrKTsKCiAgcmV0dXJuIHJlczsKfQoKc3RhdGljIGdib29sZWFuCmdzdF9wb2xsX2ZkX2Nhbl9yZWFkX3VubG9ja2VkIChjb25zdCBHc3RQb2xsICogc2V0LCBHc3RQb2xsRkQgKiBmZCkKewogIGdib29sZWFuIHJlcyA9IEZBTFNFOwogIGdpbnQgaWR4OwoKICBHU1RfREVCVUcgKCIlcDogZmQgKGZkOiVkLCBpZHg6JWQpIiwgc2V0LCBmZC0+ZmQsIGZkLT5pZHgpOwoKICBpZHggPSBmaW5kX2luZGV4IChzZXQtPmFjdGl2ZV9mZHMsIGZkKTsKICBpZiAoaWR4ID49IDApIHsKI2lmbmRlZiBHX09TX1dJTjMyCiAgICBzdHJ1Y3QgcG9sbGZkICpwZmQgPSAmZ19hcnJheV9pbmRleCAoc2V0LT5hY3RpdmVfZmRzLCBzdHJ1Y3QgcG9sbGZkLCBpZHgpOwoKICAgIHJlcyA9IChwZmQtPnJldmVudHMgJiAoUE9MTElOIHwgUE9MTFBSSSkpICE9IDA7CiNlbHNlCiAgICBXaW5zb2NrRmQgKndmZCA9ICZnX2FycmF5X2luZGV4IChzZXQtPmFjdGl2ZV9mZHMsIFdpbnNvY2tGZCwgaWR4KTsKCiAgICByZXMgPSAod2ZkLT5ldmVudHMubE5ldHdvcmtFdmVudHMgJiAoRkRfUkVBRCB8IEZEX0FDQ0VQVCkpICE9IDA7CiNlbmRpZgogIH0gZWxzZSB7CiAgICBHU1RfV0FSTklORyAoIiVwOiBjb3VsZG4ndCBmaW5kIGZkICEiLCBzZXQpOwogIH0KCiAgcmV0dXJuIHJlczsKfQoKLyoqCiAqIGdzdF9wb2xsX2ZkX2Nhbl9yZWFkOgogKiBAc2V0OiBhIGZpbGUgZGVzY3JpcHRvciBzZXQuCiAqIEBmZDogYSBmaWxlIGRlc2NyaXB0b3IuCiAqCiAqIENoZWNrIGlmIEBmZCBpbiBAc2V0IGhhcyBkYXRhIHRvIGJlIHJlYWQuCiAqCiAqIFJldHVybnM6ICVUUlVFIGlmIHRoZSBkZXNjcmlwdG9yIGhhcyBkYXRhIHRvIGJlIHJlYWQuCiAqCiAqIFNpbmNlOiAwLjEwLjE4CiAqLwpnYm9vbGVhbgpnc3RfcG9sbF9mZF9jYW5fcmVhZCAoY29uc3QgR3N0UG9sbCAqIHNldCwgR3N0UG9sbEZEICogZmQpCnsKICBnYm9vbGVhbiByZXMgPSBGQUxTRTsKCiAgZ19yZXR1cm5fdmFsX2lmX2ZhaWwgKHNldCAhPSBOVUxMLCBGQUxTRSk7CiAgZ19yZXR1cm5fdmFsX2lmX2ZhaWwgKGZkICE9IE5VTEwsIEZBTFNFKTsKICBnX3JldHVybl92YWxfaWZfZmFpbCAoZmQtPmZkID49IDAsIEZBTFNFKTsKCiAgZ19tdXRleF9sb2NrICgmKChHc3RQb2xsICopIHNldCktPmxvY2spOwoKICByZXMgPSBnc3RfcG9sbF9mZF9jYW5fcmVhZF91bmxvY2tlZCAoc2V0LCBmZCk7CgogIGdfbXV0ZXhfdW5sb2NrICgmKChHc3RQb2xsICopIHNldCktPmxvY2spOwoKICByZXR1cm4gcmVzOwp9CgovKioKICogZ3N0X3BvbGxfZmRfY2FuX3dyaXRlOgogKiBAc2V0OiBhIGZpbGUgZGVzY3JpcHRvciBzZXQuCiAqIEBmZDogYSBmaWxlIGRlc2NyaXB0b3IuCiAqCiAqIENoZWNrIGlmIEBmZCBpbiBAc2V0IGNhbiBiZSB1c2VkIGZvciB3cml0aW5nLgogKgogKiBSZXR1cm5zOiAlVFJVRSBpZiB0aGUgZGVzY3JpcHRvciBjYW4gYmUgdXNlZCBmb3Igd3JpdGluZy4KICoKICogU2luY2U6IDAuMTAuMTgKICovCmdib29sZWFuCmdzdF9wb2xsX2ZkX2Nhbl93cml0ZSAoY29uc3QgR3N0UG9sbCAqIHNldCwgR3N0UG9sbEZEICogZmQpCnsKICBnYm9vbGVhbiByZXMgPSBGQUxTRTsKICBnaW50IGlkeDsKCiAgZ19yZXR1cm5fdmFsX2lmX2ZhaWwgKHNldCAhPSBOVUxMLCBGQUxTRSk7CiAgZ19yZXR1cm5fdmFsX2lmX2ZhaWwgKGZkICE9IE5VTEwsIEZBTFNFKTsKICBnX3JldHVybl92YWxfaWZfZmFpbCAoZmQtPmZkID49IDAsIEZBTFNFKTsKCiAgR1NUX0RFQlVHICgiJXA6IGZkIChmZDolZCwgaWR4OiVkKSIsIHNldCwgZmQtPmZkLCBmZC0+aWR4KTsKCiAgZ19tdXRleF9sb2NrICgmKChHc3RQb2xsICopIHNldCktPmxvY2spOwoKICBpZHggPSBmaW5kX2luZGV4IChzZXQtPmFjdGl2ZV9mZHMsIGZkKTsKICBpZiAoaWR4ID49IDApIHsKI2lmbmRlZiBHX09TX1dJTjMyCiAgICBzdHJ1Y3QgcG9sbGZkICpwZmQgPSAmZ19hcnJheV9pbmRleCAoc2V0LT5hY3RpdmVfZmRzLCBzdHJ1Y3QgcG9sbGZkLCBpZHgpOwoKICAgIHJlcyA9IChwZmQtPnJldmVudHMgJiBQT0xMT1VUKSAhPSAwOwojZWxzZQogICAgV2luc29ja0ZkICp3ZmQgPSAmZ19hcnJheV9pbmRleCAoc2V0LT5hY3RpdmVfZmRzLCBXaW5zb2NrRmQsIGlkeCk7CgogICAgcmVzID0gKHdmZC0+ZXZlbnRzLmxOZXR3b3JrRXZlbnRzICYgRkRfV1JJVEUpICE9IDA7CiNlbmRpZgogIH0gZWxzZSB7CiAgICBHU1RfV0FSTklORyAoIiVwOiBjb3VsZG4ndCBmaW5kIGZkICEiLCBzZXQpOwogIH0KCiAgZ19tdXRleF91bmxvY2sgKCYoKEdzdFBvbGwgKikgc2V0KS0+bG9jayk7CgogIHJldHVybiByZXM7Cn0KCi8qKgogKiBnc3RfcG9sbF93YWl0OgogKiBAc2V0OiBhICNHc3RQb2xsLgogKiBAdGltZW91dDogYSB0aW1lb3V0IGluIG5hbm9zZWNvbmRzLgogKgogKiBXYWl0IGZvciBhY3Rpdml0eSBvbiB0aGUgZmlsZSBkZXNjcmlwdG9ycyBpbiBAc2V0LiBUaGlzIGZ1bmN0aW9uIHdhaXRzIHVwIHRvCiAqIHRoZSBzcGVjaWZpZWQgQHRpbWVvdXQuICBBIHRpbWVvdXQgb2YgI0dTVF9DTE9DS19USU1FX05PTkUgd2FpdHMgZm9yZXZlci4KICoKICogRm9yICNHc3RQb2xsIG9iamVjdHMgY3JlYXRlZCB3aXRoIGdzdF9wb2xsX25ldygpLCB0aGlzIGZ1bmN0aW9uIGNhbiBvbmx5IGJlCiAqIGNhbGxlZCBmcm9tIGEgc2luZ2xlIHRocmVhZCBhdCBhIHRpbWUuICBJZiBjYWxsZWQgZnJvbSBtdWx0aXBsZSB0aHJlYWRzLAogKiAtMSB3aWxsIGJlIHJldHVybmVkIHdpdGggZXJybm8gc2V0IHRvIEVQRVJNLgogKgogKiBUaGlzIGlzIG5vdCB0cnVlIGZvciB0aW1lciAjR3N0UG9sbCBvYmplY3RzIGNyZWF0ZWQgd2l0aAogKiBnc3RfcG9sbF9uZXdfdGltZXIoKSwgd2hlcmUgaXQgaXMgYWxsb3dlZCB0byBoYXZlIG11bHRpcGxlIHRocmVhZHMgd2FpdGluZwogKiBzaW11bHRhbmVvdXNseS4KICoKICogUmV0dXJuczogVGhlIG51bWJlciBvZiAjR3N0UG9sbEZEIGluIEBzZXQgdGhhdCBoYXZlIGFjdGl2aXR5IG9yIDAgd2hlbiBubwogKiBhY3Rpdml0eSB3YXMgZGV0ZWN0ZWQgYWZ0ZXIgQHRpbWVvdXQuIElmIGFuIGVycm9yIG9jY3VycywgLTEgaXMgcmV0dXJuZWQKICogYW5kIGVycm5vIGlzIHNldC4KICoKICogU2luY2U6IDAuMTAuMTgKICovCmdpbnQKZ3N0X3BvbGxfd2FpdCAoR3N0UG9sbCAqIHNldCwgR3N0Q2xvY2tUaW1lIHRpbWVvdXQpCnsKICBnYm9vbGVhbiByZXN0YXJ0aW5nOwogIGdib29sZWFuIGlzX3RpbWVyOwogIGludCByZXM7CiAgZ2ludCBvbGRfd2FpdGluZzsKCiAgZ19yZXR1cm5fdmFsX2lmX2ZhaWwgKHNldCAhPSBOVUxMLCAtMSk7CgogIEdTVF9ERUJVRyAoInRpbWVvdXQgOiUiIEdTVF9USU1FX0ZPUk1BVCwgR1NUX1RJTUVfQVJHUyAodGltZW91dCkpOwoKICBpc190aW1lciA9IHNldC0+dGltZXI7CgogIC8qIGFkZCBvbmUgbW9yZSB3YWl0ZXIgKi8KICBvbGRfd2FpdGluZyA9IElOQ19XQUlUSU5HIChzZXQpOwoKICAvKiB3ZSBjYW5ub3Qgd2FpdCBmcm9tIG11bHRpcGxlIHRocmVhZHMgdW5sZXNzIHdlIGFyZSBhIHRpbWVyICovCiAgaWYgKEdfVU5MSUtFTFkgKG9sZF93YWl0aW5nID4gMCAmJiAhaXNfdGltZXIpKQogICAgZ290byBhbHJlYWR5X3dhaXRpbmc7CgogIC8qIGZsdXNoaW5nLCBleGl0IGltbWVkaWF0ZWx5ICovCiAgaWYgKEdfVU5MSUtFTFkgKElTX0ZMVVNISU5HIChzZXQpKSkKICAgIGdvdG8gZmx1c2hpbmc7CgogIGRvIHsKICAgIEdzdFBvbGxNb2RlIG1vZGU7CgogICAgcmVzID0gLTE7CiAgICByZXN0YXJ0aW5nID0gRkFMU0U7CgogICAgbW9kZSA9IGNob29zZV9tb2RlIChzZXQsIHRpbWVvdXQpOwoKICAgIGlmIChURVNUX1JFQlVJTEQgKHNldCkpIHsKICAgICAgZ19tdXRleF9sb2NrICgmc2V0LT5sb2NrKTsKI2lmbmRlZiBHX09TX1dJTjMyCiAgICAgIGdfYXJyYXlfc2V0X3NpemUgKHNldC0+YWN0aXZlX2Zkcywgc2V0LT5mZHMtPmxlbik7CiAgICAgIG1lbWNweSAoc2V0LT5hY3RpdmVfZmRzLT5kYXRhLCBzZXQtPmZkcy0+ZGF0YSwKICAgICAgICAgIHNldC0+ZmRzLT5sZW4gKiBzaXplb2YgKHN0cnVjdCBwb2xsZmQpKTsKI2Vsc2UKICAgICAgaWYgKCFnc3RfcG9sbF9wcmVwYXJlX3dpbnNvY2tfYWN0aXZlX3NldHMgKHNldCkpCiAgICAgICAgZ290byB3aW5zb2NrX2Vycm9yOwojZW5kaWYKICAgICAgZ19tdXRleF91bmxvY2sgKCZzZXQtPmxvY2spOwogICAgfQoKICAgIHN3aXRjaCAobW9kZSkgewogICAgICBjYXNlIEdTVF9QT0xMX01PREVfQVVUTzoKICAgICAgICBnX2Fzc2VydF9ub3RfcmVhY2hlZCAoKTsKICAgICAgICBicmVhazsKICAgICAgY2FzZSBHU1RfUE9MTF9NT0RFX1BQT0xMOgogICAgICB7CiNpZmRlZiBIQVZFX1BQT0xMCiAgICAgICAgc3RydWN0IHRpbWVzcGVjIHRzOwogICAgICAgIHN0cnVjdCB0aW1lc3BlYyAqdHNwdHI7CgogICAgICAgIGlmICh0aW1lb3V0ICE9IEdTVF9DTE9DS19USU1FX05PTkUpIHsKICAgICAgICAgIEdTVF9USU1FX1RPX1RJTUVTUEVDICh0aW1lb3V0LCB0cyk7CiAgICAgICAgICB0c3B0ciA9ICZ0czsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgdHNwdHIgPSBOVUxMOwogICAgICAgIH0KCiAgICAgICAgcmVzID0KICAgICAgICAgICAgcHBvbGwgKChzdHJ1Y3QgcG9sbGZkICopIHNldC0+YWN0aXZlX2Zkcy0+ZGF0YSwKICAgICAgICAgICAgc2V0LT5hY3RpdmVfZmRzLT5sZW4sIHRzcHRyLCBOVUxMKTsKI2Vsc2UKICAgICAgICBnX2Fzc2VydF9ub3RfcmVhY2hlZCAoKTsKICAgICAgICBlcnJubyA9IEVOT1NZUzsKI2VuZGlmCiAgICAgICAgYnJlYWs7CiAgICAgIH0KICAgICAgY2FzZSBHU1RfUE9MTF9NT0RFX1BPTEw6CiAgICAgIHsKI2lmZGVmIEhBVkVfUE9MTAogICAgICAgIGdpbnQgdDsKCiAgICAgICAgaWYgKHRpbWVvdXQgIT0gR1NUX0NMT0NLX1RJTUVfTk9ORSkgewogICAgICAgICAgdCA9IEdTVF9USU1FX0FTX01TRUNPTkRTICh0aW1lb3V0KTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgdCA9IC0xOwogICAgICAgIH0KCiAgICAgICAgcmVzID0KICAgICAgICAgICAgcG9sbCAoKHN0cnVjdCBwb2xsZmQgKikgc2V0LT5hY3RpdmVfZmRzLT5kYXRhLAogICAgICAgICAgICBzZXQtPmFjdGl2ZV9mZHMtPmxlbiwgdCk7CiNlbHNlCiAgICAgICAgZ19hc3NlcnRfbm90X3JlYWNoZWQgKCk7CiAgICAgICAgZXJybm8gPSBFTk9TWVM7CiNlbmRpZgogICAgICAgIGJyZWFrOwogICAgICB9CiAgICAgIGNhc2UgR1NUX1BPTExfTU9ERV9QU0VMRUNUOgojaWZuZGVmIEhBVkVfUFNFTEVDVAogICAgICB7CiAgICAgICAgZ19hc3NlcnRfbm90X3JlYWNoZWQgKCk7CiAgICAgICAgZXJybm8gPSBFTk9TWVM7CiAgICAgICAgYnJlYWs7CiAgICAgIH0KI2VuZGlmCiAgICAgIGNhc2UgR1NUX1BPTExfTU9ERV9TRUxFQ1Q6CiAgICAgIHsKI2lmbmRlZiBHX09TX1dJTjMyCiAgICAgICAgZmRfc2V0IHJlYWRmZHM7CiAgICAgICAgZmRfc2V0IHdyaXRlZmRzOwogICAgICAgIGZkX3NldCBlcnJvcmZkczsKICAgICAgICBnaW50IG1heF9mZDsKCiAgICAgICAgbWF4X2ZkID0gcG9sbGZkX3RvX2ZkX3NldCAoc2V0LCAmcmVhZGZkcywgJndyaXRlZmRzLCAmZXJyb3JmZHMpOwoKICAgICAgICBpZiAobW9kZSA9PSBHU1RfUE9MTF9NT0RFX1NFTEVDVCkgewogICAgICAgICAgc3RydWN0IHRpbWV2YWwgdHY7CiAgICAgICAgICBzdHJ1Y3QgdGltZXZhbCAqdHZwdHI7CgogICAgICAgICAgaWYgKHRpbWVvdXQgIT0gR1NUX0NMT0NLX1RJTUVfTk9ORSkgewogICAgICAgICAgICBHU1RfVElNRV9UT19USU1FVkFMICh0aW1lb3V0LCB0dik7CiAgICAgICAgICAgIHR2cHRyID0gJnR2OwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgdHZwdHIgPSBOVUxMOwogICAgICAgICAgfQoKICAgICAgICAgIEdTVF9ERUJVRyAoIkNhbGxpbmcgc2VsZWN0Iik7CiAgICAgICAgICByZXMgPSBzZWxlY3QgKG1heF9mZCArIDEsICZyZWFkZmRzLCAmd3JpdGVmZHMsICZlcnJvcmZkcywgdHZwdHIpOwogICAgICAgICAgR1NUX0RFQlVHICgiQWZ0ZXIgc2VsZWN0LCByZXM6JWQiLCByZXMpOwogICAgICAgIH0gZWxzZSB7CiNpZmRlZiBIQVZFX1BTRUxFQ1QKICAgICAgICAgIHN0cnVjdCB0aW1lc3BlYyB0czsKICAgICAgICAgIHN0cnVjdCB0aW1lc3BlYyAqdHNwdHI7CgogICAgICAgICAgaWYgKHRpbWVvdXQgIT0gR1NUX0NMT0NLX1RJTUVfTk9ORSkgewogICAgICAgICAgICBHU1RfVElNRV9UT19USU1FU1BFQyAodGltZW91dCwgdHMpOwogICAgICAgICAgICB0c3B0ciA9ICZ0czsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHRzcHRyID0gTlVMTDsKICAgICAgICAgIH0KCiAgICAgICAgICBHU1RfREVCVUcgKCJDYWxsaW5nIHBzZWxlY3QiKTsKICAgICAgICAgIHJlcyA9CiAgICAgICAgICAgICAgcHNlbGVjdCAobWF4X2ZkICsgMSwgJnJlYWRmZHMsICZ3cml0ZWZkcywgJmVycm9yZmRzLCB0c3B0ciwgTlVMTCk7CiAgICAgICAgICBHU1RfREVCVUcgKCJBZnRlciBwc2VsZWN0LCByZXM6JWQiLCByZXMpOwojZW5kaWYKICAgICAgICB9CgogICAgICAgIGlmIChyZXMgPj0gMCkgewogICAgICAgICAgZmRfc2V0X3RvX3BvbGxmZCAoc2V0LCAmcmVhZGZkcywgJndyaXRlZmRzLCAmZXJyb3JmZHMpOwogICAgICAgIH0KI2Vsc2UgLyogR19PU19XSU4zMiAqLwogICAgICAgIGdfYXNzZXJ0X25vdF9yZWFjaGVkICgpOwogICAgICAgIGVycm5vID0gRU5PU1lTOwojZW5kaWYKICAgICAgICBicmVhazsKICAgICAgfQogICAgICBjYXNlIEdTVF9QT0xMX01PREVfV0lORE9XUzoKICAgICAgewojaWZkZWYgR19PU19XSU4zMgogICAgICAgIGdpbnQgaWdub3JlX2NvdW50ID0gc2V0LT5hY3RpdmVfZmRzX2lnbm9yZWQtPmxlbjsKICAgICAgICBEV09SRCB0LCB3YWl0X3JldDsKCiAgICAgICAgaWYgKEdfTElLRUxZIChpZ25vcmVfY291bnQgPT0gMCkpIHsKICAgICAgICAgIGlmICh0aW1lb3V0ICE9IEdTVF9DTE9DS19USU1FX05PTkUpCiAgICAgICAgICAgIHQgPSBHU1RfVElNRV9BU19NU0VDT05EUyAodGltZW91dCk7CiAgICAgICAgICBlbHNlCiAgICAgICAgICAgIHQgPSBJTkZJTklURTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgLyogYWxyZWFkeSBvbmUgb3IgbW9yZSBpZ25vcmVkIGZkcywgc28gd2UgcXVpY2tseSBzd2VlcCB0aGUgb3RoZXJzICovCiAgICAgICAgICB0ID0gMDsKICAgICAgICB9CgogICAgICAgIGlmIChzZXQtPmFjdGl2ZV9ldmVudHMtPmxlbiAhPSAwKSB7CiAgICAgICAgICB3YWl0X3JldCA9IFdTQVdhaXRGb3JNdWx0aXBsZUV2ZW50cyAoc2V0LT5hY3RpdmVfZXZlbnRzLT5sZW4sCiAgICAgICAgICAgICAgKEhBTkRMRSAqKSBzZXQtPmFjdGl2ZV9ldmVudHMtPmRhdGEsIEZBTFNFLCB0LCBGQUxTRSk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHdhaXRfcmV0ID0gV1NBX1dBSVRfRkFJTEVEOwogICAgICAgICAgV1NBU2V0TGFzdEVycm9yIChXU0FfSU5WQUxJRF9QQVJBTUVURVIpOwogICAgICAgIH0KCiAgICAgICAgaWYgKGlnbm9yZV9jb3VudCA9PSAwICYmIHdhaXRfcmV0ID09IFdTQV9XQUlUX1RJTUVPVVQpIHsKICAgICAgICAgIHJlcyA9IDA7CiAgICAgICAgfSBlbHNlIGlmICh3YWl0X3JldCA9PSBXU0FfV0FJVF9GQUlMRUQpIHsKICAgICAgICAgIHJlcyA9IC0xOwogICAgICAgICAgZXJybm8gPSBnc3RfcG9sbF93aW5zb2NrX2Vycm9yX3RvX2Vycm5vIChXU0FHZXRMYXN0RXJyb3IgKCkpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAvKiB0aGUgZmlyc3QgZW50cnkgaXMgdGhlIHdha2V1cCBldmVudCAqLwogICAgICAgICAgaWYgKHdhaXRfcmV0IC0gV1NBX1dBSVRfRVZFTlRfMCA+PSAxKSB7CiAgICAgICAgICAgIHJlcyA9IGdzdF9wb2xsX2NvbGxlY3Rfd2luc29ja19ldmVudHMgKHNldCk7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICByZXMgPSAxOyAgICAgICAgICAgIC8qIHdha2V1cCBldmVudCAqLwogICAgICAgICAgfQogICAgICAgIH0KI2Vsc2UKICAgICAgICBnX2Fzc2VydF9ub3RfcmVhY2hlZCAoKTsKICAgICAgICBlcnJubyA9IEVOT1NZUzsKI2VuZGlmCiAgICAgICAgYnJlYWs7CiAgICAgIH0KICAgIH0KCiAgICBpZiAoIWlzX3RpbWVyKSB7CiAgICAgIC8qIEFwcGxpY2F0aW9ucyBuZWVkcyB0byBjbGVhciB0aGUgY29udHJvbCBzb2NrZXQgdGhlbXNlbHZlcyBmb3IgdGltZXIKICAgICAgICogcG9sbHMuCiAgICAgICAqIEZvciBvdGhlciBwb2xscywgd2UgbmVlZCB0byBjbGVhciB0aGUgY29udHJvbCBzb2NrZXQuIElmIHRoZXJlIHdhcyBvbmx5CiAgICAgICAqIG9uZSBzb2NrZXQgd2l0aCBhY3Rpdml0eSBhbmQgaXQgd2FzIHRoZSBjb250cm9sIHNvY2tldCwgd2UgbmVlZCB0bwogICAgICAgKiByZXN0YXJ0ICovCiAgICAgIGlmIChyZWxlYXNlX2FsbF93YWtldXAgKHNldCkgPiAwICYmIHJlcyA9PSAxKQogICAgICAgIHJlc3RhcnRpbmcgPSBUUlVFOwogICAgfQoKICAgIC8qIHdlIGdvdCB3b2tlbiB1cCBhbmQgd2UgYXJlIGZsdXNoaW5nLCB3ZSBuZWVkIHRvIHN0b3AgKi8KICAgIGlmIChHX1VOTElLRUxZIChJU19GTFVTSElORyAoc2V0KSkpCiAgICAgIGdvdG8gZmx1c2hpbmc7CgogIH0gd2hpbGUgKEdfVU5MSUtFTFkgKHJlc3RhcnRpbmcpKTsKCiAgREVDX1dBSVRJTkcgKHNldCk7CgogIHJldHVybiByZXM7CgogIC8qIEVSUk9SUyAqLwphbHJlYWR5X3dhaXRpbmc6CiAgewogICAgR1NUX0xPRyAoIiVwOiB3ZSBhcmUgYWxyZWFkeSB3YWl0aW5nIiwgc2V0KTsKICAgIERFQ19XQUlUSU5HIChzZXQpOwogICAgZXJybm8gPSBFUEVSTTsKICAgIHJldHVybiAtMTsKICB9CmZsdXNoaW5nOgogIHsKICAgIEdTVF9MT0cgKCIlcDogd2UgYXJlIGZsdXNoaW5nIiwgc2V0KTsKICAgIERFQ19XQUlUSU5HIChzZXQpOwogICAgZXJybm8gPSBFQlVTWTsKICAgIHJldHVybiAtMTsKICB9CiNpZmRlZiBHX09TX1dJTjMyCndpbnNvY2tfZXJyb3I6CiAgewogICAgR1NUX0xPRyAoIiVwOiB3aW5zb2NrIGVycm9yIiwgc2V0KTsKICAgIGdfbXV0ZXhfdW5sb2NrICgmc2V0LT5sb2NrKTsKICAgIERFQ19XQUlUSU5HIChzZXQpOwogICAgcmV0dXJuIC0xOwogIH0KI2VuZGlmCn0KCi8qKgogKiBnc3RfcG9sbF9zZXRfY29udHJvbGxhYmxlOgogKiBAc2V0OiBhICNHc3RQb2xsLgogKiBAY29udHJvbGxhYmxlOiBuZXcgY29udHJvbGxhYmxlIHN0YXRlLgogKgogKiBXaGVuIEBjb250cm9sbGFibGUgaXMgJVRSVUUsIHRoaXMgZnVuY3Rpb24gZW5zdXJlcyB0aGF0IGZ1dHVyZSBjYWxscyB0bwogKiBnc3RfcG9sbF93YWl0KCkgd2lsbCBiZSBhZmZlY3RlZCBieSBnc3RfcG9sbF9yZXN0YXJ0KCkgYW5kCiAqIGdzdF9wb2xsX3NldF9mbHVzaGluZygpLgogKgogKiBSZXR1cm5zOiAlVFJVRSBpZiB0aGUgY29udHJvbGxhYmlsaXR5IG9mIEBzZXQgY291bGQgYmUgdXBkYXRlZC4KICoKICogU2luY2U6IDAuMTAuMTgKICovCmdib29sZWFuCmdzdF9wb2xsX3NldF9jb250cm9sbGFibGUgKEdzdFBvbGwgKiBzZXQsIGdib29sZWFuIGNvbnRyb2xsYWJsZSkKewogIGdfcmV0dXJuX3ZhbF9pZl9mYWlsIChzZXQgIT0gTlVMTCwgRkFMU0UpOwoKICBHU1RfTE9HICgiJXA6IGNvbnRyb2xsYWJsZSA6ICVkIiwgc2V0LCBjb250cm9sbGFibGUpOwoKICBzZXQtPmNvbnRyb2xsYWJsZSA9IGNvbnRyb2xsYWJsZTsKCiAgcmV0dXJuIFRSVUU7Cn0KCi8qKgogKiBnc3RfcG9sbF9yZXN0YXJ0OgogKiBAc2V0OiBhICNHc3RQb2xsLgogKgogKiBSZXN0YXJ0IGFueSBnc3RfcG9sbF93YWl0KCkgdGhhdCBpcyBpbiBwcm9ncmVzcy4gVGhpcyBmdW5jdGlvbiBpcyB0eXBpY2FsbHkKICogdXNlZCBhZnRlciBhZGRpbmcgb3IgcmVtb3ZpbmcgZGVzY3JpcHRvcnMgdG8gQHNldC4KICoKICogSWYgQHNldCBpcyBub3QgY29udHJvbGxhYmxlLCB0aGVuIHRoaXMgY2FsbCB3aWxsIGhhdmUgbm8gZWZmZWN0LgogKgogKiBTaW5jZTogMC4xMC4xOAogKi8Kdm9pZApnc3RfcG9sbF9yZXN0YXJ0IChHc3RQb2xsICogc2V0KQp7CiAgZ19yZXR1cm5faWZfZmFpbCAoc2V0ICE9IE5VTEwpOwoKICBpZiAoc2V0LT5jb250cm9sbGFibGUgJiYgR0VUX1dBSVRJTkcgKHNldCkgPiAwKSB7CiAgICAvKiB3ZSBhcmUgY29udHJvbGxhYmxlIGFuZCB3YWl0aW5nLCB3YWtlIHVwIHRoZSB3YWl0ZXIuIFRoZSBzb2NrZXQgd2lsbCBiZQogICAgICogY2xlYXJlZCBieSB0aGUgX3dhaXQoKSB0aHJlYWQgYW5kIHRoZSBwb2xsIHdpbGwgYmUgcmVzdGFydGVkICovCiAgICByYWlzZV93YWtldXAgKHNldCk7CiAgfQp9CgovKioKICogZ3N0X3BvbGxfc2V0X2ZsdXNoaW5nOgogKiBAc2V0OiBhICNHc3RQb2xsLgogKiBAZmx1c2hpbmc6IG5ldyBmbHVzaGluZyBzdGF0ZS4KICoKICogV2hlbiBAZmx1c2hpbmcgaXMgJVRSVUUsIHRoaXMgZnVuY3Rpb24gZW5zdXJlcyB0aGF0IGN1cnJlbnQgYW5kIGZ1dHVyZSBjYWxscwogKiB0byBnc3RfcG9sbF93YWl0KCkgd2lsbCByZXR1cm4gLTEsIHdpdGggZXJybm8gc2V0IHRvIEVCVVNZLgogKgogKiBVbnNldHRpbmcgdGhlIGZsdXNoaW5nIHN0YXRlIHdpbGwgcmVzdG9yZSBub3JtYWwgb3BlcmF0aW9uIG9mIEBzZXQuCiAqCiAqIFNpbmNlOiAwLjEwLjE4CiAqLwp2b2lkCmdzdF9wb2xsX3NldF9mbHVzaGluZyAoR3N0UG9sbCAqIHNldCwgZ2Jvb2xlYW4gZmx1c2hpbmcpCnsKICBnX3JldHVybl9pZl9mYWlsIChzZXQgIT0gTlVMTCk7CgogIEdTVF9MT0cgKCIlcDogZmx1c2hpbmc6ICVkIiwgc2V0LCBmbHVzaGluZyk7CgogIC8qIHVwZGF0ZSB0aGUgbmV3IHN0YXRlIGZpcnN0ICovCiAgU0VUX0ZMVVNISU5HIChzZXQsIGZsdXNoaW5nKTsKCiAgaWYgKGZsdXNoaW5nICYmIHNldC0+Y29udHJvbGxhYmxlICYmIEdFVF9XQUlUSU5HIChzZXQpID4gMCkgewogICAgLyogd2UgYXJlIGZsdXNoaW5nLCBjb250cm9sbGFibGUgYW5kIHdhaXRpbmcsIHdha2UgdXAgdGhlIHdhaXRlci4gV2hlbiB3ZQogICAgICogc3RvcCB0aGUgZmx1c2hpbmcgb3BlcmF0aW9uIHdlIGRvbid0IGNsZWFyIHRoZSB3YWtldXAgZmQgaGVyZSwgdGhpcyB3aWxsCiAgICAgKiBoYXBwZW4gaW4gdGhlIF93YWl0KCkgdGhyZWFkLiAqLwogICAgcmFpc2Vfd2FrZXVwIChzZXQpOwogIH0KfQoKLyoqCiAqIGdzdF9wb2xsX3dyaXRlX2NvbnRyb2w6CiAqIEBzZXQ6IGEgI0dzdFBvbGwuCiAqCiAqIFdyaXRlIGEgYnl0ZSB0byB0aGUgY29udHJvbCBzb2NrZXQgb2YgdGhlIGNvbnRyb2xsYWJsZSBAc2V0LgogKiBUaGlzIGZ1bmN0aW9uIGlzIG1vc3RseSB1c2VmdWwgZm9yIHRpbWVyICNHc3RQb2xsIG9iamVjdHMgY3JlYXRlZCB3aXRoCiAqIGdzdF9wb2xsX25ld190aW1lcigpLiAKICoKICogSXQgd2lsbCBtYWtlIGFueSBjdXJyZW50IGFuZCBmdXR1cmUgZ3N0X3BvbGxfd2FpdCgpIGZ1bmN0aW9uIHJldHVybiB3aXRoCiAqIDEsIG1lYW5pbmcgdGhlIGNvbnRyb2wgc29ja2V0IGlzIHNldC4gQWZ0ZXIgYW4gZXF1YWwgYW1vdW50IG9mIGNhbGxzIHRvCiAqIGdzdF9wb2xsX3JlYWRfY29udHJvbCgpIGhhdmUgYmVlbiBwZXJmb3JtZWQsIGNhbGxzIHRvIGdzdF9wb2xsX3dhaXQoKSB3aWxsCiAqIGJsb2NrIGFnYWluIHVudGlsIHRoZWlyIHRpbWVvdXQgZXhwaXJlZC4KICoKICogUmV0dXJuczogJVRSVUUgb24gc3VjY2Vzcy4gJUZBTFNFIHdoZW4gQHNldCBpcyBub3QgY29udHJvbGxhYmxlIG9yIHdoZW4gdGhlCiAqIGJ5dGUgY291bGQgbm90IGJlIHdyaXR0ZW4uCiAqCiAqIFNpbmNlOiAwLjEwLjIzCiAqLwpnYm9vbGVhbgpnc3RfcG9sbF93cml0ZV9jb250cm9sIChHc3RQb2xsICogc2V0KQp7CiAgZ2Jvb2xlYW4gcmVzOwoKICBnX3JldHVybl92YWxfaWZfZmFpbCAoc2V0ICE9IE5VTEwsIEZBTFNFKTsKICBnX3JldHVybl92YWxfaWZfZmFpbCAoc2V0LT50aW1lciwgRkFMU0UpOwoKICByZXMgPSByYWlzZV93YWtldXAgKHNldCk7CgogIHJldHVybiByZXM7Cn0KCi8qKgogKiBnc3RfcG9sbF9yZWFkX2NvbnRyb2w6CiAqIEBzZXQ6IGEgI0dzdFBvbGwuCiAqCiAqIFJlYWQgYSBieXRlIGZyb20gdGhlIGNvbnRyb2wgc29ja2V0IG9mIHRoZSBjb250cm9sbGFibGUgQHNldC4KICogVGhpcyBmdW5jdGlvbiBpcyBtb3N0bHkgdXNlZnVsIGZvciB0aW1lciAjR3N0UG9sbCBvYmplY3RzIGNyZWF0ZWQgd2l0aAogKiBnc3RfcG9sbF9uZXdfdGltZXIoKS4gCiAqCiAqIFJldHVybnM6ICVUUlVFIG9uIHN1Y2Nlc3MuICVGQUxTRSB3aGVuIEBzZXQgaXMgbm90IGNvbnRyb2xsYWJsZSBvciB3aGVuIHRoZXJlCiAqIHdhcyBubyBieXRlIHRvIHJlYWQuCiAqCiAqIFNpbmNlOiAwLjEwLjIzCiAqLwpnYm9vbGVhbgpnc3RfcG9sbF9yZWFkX2NvbnRyb2wgKEdzdFBvbGwgKiBzZXQpCnsKICBnYm9vbGVhbiByZXM7CgogIGdfcmV0dXJuX3ZhbF9pZl9mYWlsIChzZXQgIT0gTlVMTCwgRkFMU0UpOwogIGdfcmV0dXJuX3ZhbF9pZl9mYWlsIChzZXQtPnRpbWVyLCBGQUxTRSk7CgogIHJlcyA9IHJlbGVhc2Vfd2FrZXVwIChzZXQpOwoKICByZXR1cm4gcmVzOwp9Cg==