LyogJFhGcmVlODYkICovIC8qIC0qLSBtb2RlOiBjOyBjLWJhc2ljLW9mZnNldDogMyAtKi0gKi8KLyoKICogQ29weXJpZ2h0IDIwMDAgR2FyZXRoIEh1Z2hlcwogKiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKgogKiBQZXJtaXNzaW9uIGlzIGhlcmVieSBncmFudGVkLCBmcmVlIG9mIGNoYXJnZSwgdG8gYW55IHBlcnNvbiBvYnRhaW5pbmcgYQogKiBjb3B5IG9mIHRoaXMgc29mdHdhcmUgYW5kIGFzc29jaWF0ZWQgZG9jdW1lbnRhdGlvbiBmaWxlcyAodGhlICJTb2Z0d2FyZSIpLAogKiB0byBkZWFsIGluIHRoZSBTb2Z0d2FyZSB3aXRob3V0IHJlc3RyaWN0aW9uLCBpbmNsdWRpbmcgd2l0aG91dCBsaW1pdGF0aW9uCiAqIHRoZSByaWdodHMgdG8gdXNlLCBjb3B5LCBtb2RpZnksIG1lcmdlLCBwdWJsaXNoLCBkaXN0cmlidXRlLCBzdWJsaWNlbnNlLAogKiBhbmQvb3Igc2VsbCBjb3BpZXMgb2YgdGhlIFNvZnR3YXJlLCBhbmQgdG8gcGVybWl0IHBlcnNvbnMgdG8gd2hvbSB0aGUKICogU29mdHdhcmUgaXMgZnVybmlzaGVkIHRvIGRvIHNvLCBzdWJqZWN0IHRvIHRoZSBmb2xsb3dpbmcgY29uZGl0aW9uczoKICoKICogVGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgYW5kIHRoaXMgcGVybWlzc2lvbiBub3RpY2UgKGluY2x1ZGluZyB0aGUgbmV4dAogKiBwYXJhZ3JhcGgpIHNoYWxsIGJlIGluY2x1ZGVkIGluIGFsbCBjb3BpZXMgb3Igc3Vic3RhbnRpYWwgcG9ydGlvbnMgb2YgdGhlCiAqIFNvZnR3YXJlLgogKgogKiBUSEUgU09GVFdBUkUgSVMgUFJPVklERUQgIkFTIElTIiwgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCwgRVhQUkVTUyBPUgogKiBJTVBMSUVELCBJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPIFRIRSBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSwKICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQU5EIE5PTklORlJJTkdFTUVOVC4gIElOIE5PIEVWRU5UIFNIQUxMCiAqIEdBUkVUSCBIVUdIRVMgQkUgTElBQkxFIEZPUiBBTlkgQ0xBSU0sIERBTUFHRVMgT1IgT1RIRVIgTElBQklMSVRZLCBXSEVUSEVSCiAqIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgVE9SVCBPUiBPVEhFUldJU0UsIEFSSVNJTkcgRlJPTSwgT1VUIE9GIE9SIElOCiAqIENPTk5FQ1RJT04gV0lUSCBUSEUgU09GVFdBUkUgT1IgVEhFIFVTRSBPUiBPVEhFUiBERUFMSU5HUyBJTiBUSEUgU09GVFdBUkUuCiAqLwoKLyoKICogQXV0aG9yczoKICoJR2FyZXRoIEh1Z2hlcyA8Z2FyZXRoQHZhbGludXguY29tPgogKglMZWlmIERlbGdhc3MgPGxkZWxnYXNzQHJldGluYWxidXJuLm5ldD4KICoJSm9z6SBGb25zZWNhIDxqX3JfZm9uc2VjYUB5YWhvby5jby51az4KICovCgojaWZuZGVmIF9fTUFDSDY0X0lPQ1RMX0hfXwojZGVmaW5lIF9fTUFDSDY0X0lPQ1RMX0hfXwoKI2luY2x1ZGUgIm1hY2g2NF9kcmkuaCIKI2luY2x1ZGUgIm1hY2g2NF9yZWcuaCIKI2luY2x1ZGUgIm1hY2g2NF9sb2NrLmgiCgojZGVmaW5lIE1BQ0g2NF9CVUZGRVJfTUFYX0RXT1JEUwkoTUFDSDY0X0JVRkZFUl9TSVpFIC8gc2l6ZW9mKENBUkQzMikpCgoKZXh0ZXJuIGRybUJ1ZlB0ciBtYWNoNjRHZXRCdWZmZXJMb2NrZWQoIG1hY2g2NENvbnRleHRQdHIgbW1lc2EgKTsKZXh0ZXJuIHZvaWQgbWFjaDY0Rmx1c2hWZXJ0aWNlc0xvY2tlZCggbWFjaDY0Q29udGV4dFB0ciBtbWVzYSApOwpleHRlcm4gdm9pZCBtYWNoNjRGbHVzaERNQUxvY2tlZCggbWFjaDY0Q29udGV4dFB0ciBtbWVzYSApOwpleHRlcm4gdm9pZCBtYWNoNjRVcGxvYWRId1N0YXRlTG9ja2VkKCBtYWNoNjRDb250ZXh0UHRyIG1tZXNhICk7CgpzdGF0aWMgSU5MSU5FIHZvaWQgKm1hY2g2NEFsbG9jRG1hTG93KCBtYWNoNjRDb250ZXh0UHRyIG1tZXNhLCBpbnQgYnl0ZXMgKQp7CiAgIENBUkQzMiAqaGVhZDsKCiAgIGlmICggbW1lc2EtPnZlcnRfdXNlZCArIGJ5dGVzID4gbW1lc2EtPnZlcnRfdG90YWwgKSB7CiAgICAgIExPQ0tfSEFSRFdBUkUoIG1tZXNhICk7CiAgICAgIG1hY2g2NEZsdXNoVmVydGljZXNMb2NrZWQoIG1tZXNhICk7CiAgICAgIFVOTE9DS19IQVJEV0FSRSggbW1lc2EgKTsKICAgfQoKICAgaGVhZCA9IChDQVJEMzIgKikoKGNoYXIgKiltbWVzYS0+dmVydF9idWYgKyBtbWVzYS0+dmVydF91c2VkKTsKICAgbW1lc2EtPnZlcnRfdXNlZCArPSBieXRlczsKCiAgIHJldHVybiBoZWFkOwp9CgpzdGF0aWMgSU5MSU5FIHZvaWQgKm1hY2g2NEFsbG9jRG1hTG9ja2VkKCBtYWNoNjRDb250ZXh0UHRyIG1tZXNhLCBpbnQgYnl0ZXMgKQp7CiAgIENBUkQzMiAqaGVhZDsKCiAgIGlmICggbW1lc2EtPnZlcnRfdXNlZCArIGJ5dGVzID4gbW1lc2EtPnZlcnRfdG90YWwgKSB7CiAgICAgIG1hY2g2NEZsdXNoVmVydGljZXNMb2NrZWQoIG1tZXNhICk7CiAgIH0KCiAgIGhlYWQgPSAoQ0FSRDMyICopKChjaGFyICopbW1lc2EtPnZlcnRfYnVmICsgbW1lc2EtPnZlcnRfdXNlZCk7CiAgIG1tZXNhLT52ZXJ0X3VzZWQgKz0gYnl0ZXM7CgogICByZXR1cm4gaGVhZDsKfQoKZXh0ZXJuIHZvaWQgbWFjaDY0RmlyZUJsaXRMb2NrZWQoIG1hY2g2NENvbnRleHRQdHIgbW1lc2EsIHZvaWQgKmJ1ZmZlciwKCQkJCSAgR0xpbnQgb2Zmc2V0LCBHTGludCBwaXRjaCwgR0xpbnQgZm9ybWF0LAoJCQkJICBHTGludCB4LCBHTGludCB5LCBHTGludCB3aWR0aCwgR0xpbnQgaGVpZ2h0ICk7CgpleHRlcm4gdm9pZCBtYWNoNjRDb3B5QnVmZmVyKCBfX0RSSWRyYXdhYmxlUHJpdmF0ZSAqZFByaXYgKTsKI2lmIEVOQUJMRV9QRVJGX0JPWEVTCmV4dGVybiB2b2lkIG1hY2g2NFBlcmZvcm1hbmNlQ291bnRlcnMoIG1hY2g2NENvbnRleHRQdHIgbW1lc2EgKTsKZXh0ZXJuIHZvaWQgbWFjaDY0UGVyZm9ybWFuY2VCb3hlc0xvY2tlZCggbWFjaDY0Q29udGV4dFB0ciBtbWVzYSApOwojZW5kaWYKZXh0ZXJuIHZvaWQgbWFjaDY0V2FpdEZvcklkbGVMb2NrZWQoIG1hY2g2NENvbnRleHRQdHIgbW1lc2EgKTsKCmV4dGVybiB2b2lkIG1hY2g2NEluaXRJb2N0bEZ1bmNzKCBzdHJ1Y3QgZGRfZnVuY3Rpb25fdGFibGUgKmZ1bmN0aW9ucyApOwoKLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKiBIZWxwZXIgbWFjcm9zOgogKi8KCiNkZWZpbmUgRkxVU0hfQkFUQ0goIG1tZXNhICkJCQkJCQlcCmRvIHsJCQkJCQkJCQlcCiAgIGlmICggTUFDSDY0X0RFQlVHICYgREVCVUdfVkVSQk9TRV9JT0NUTCApCQkJCVwKICAgICAgZnByaW50Ziggc3RkZXJyLCAiRkxVU0hfQkFUQ0ggaW4gJXNcbiIsIF9fRlVOQ1RJT05fXyApOwkJXAogICBpZiAoIG1tZXNhLT52ZXJ0X3VzZWQgKSB7CQkJCQkJXAogICAgICBtYWNoNjRGbHVzaFZlcnRpY2VzKCBtbWVzYSApOwkJCQkJXAogICB9CQkJCQkJCQkJXAp9IHdoaWxlICgwKQoKLyogQWNjb3JkaW5nIHRvIGEgY29tbWVudCBpbiBBVElNYWNoNjRTeW5jIChhdGltYWNoNjQuYykgaW4gdGhlIEREWDoKICoKICogIkZvciBWVEIncyBhbmQgbGF0ZXIsIHRoZSBmaXJzdCBDUFUgcmVhZCBvZiB0aGUgZnJhbWVidWZmZXIgd2lsbCByZXR1cm4KICogemVyb2VzIFsuLi5dIFRoaXMgYXBwZWFycyB0byBiZSBkdWUgdG8gc29tZSBraW5kIG9mIGVuZ2luZQogKiBjYWNoaW5nIG9mIGZyYW1lYnVmZmVyIGRhdGEgSSBoYXZlbid0IGZvdW5kIGFueSB3YXkgb2YgZGlzYWJsaW5nLCBvcgogKiBvdGhlcndpc2UgY2lyY3VtdmVudGluZy4iCiAqLwojZGVmaW5lIEZJTklTSF9ETUFfTE9DS0VEKCBtbWVzYSApCQkJCQlcCmRvIHsJCQkJCQkJCQlcCiAgIENBUkQzMiBfdG1wOwkJCQkJCQkJXAogICBpZiAoIE1BQ0g2NF9ERUJVRyAmIERFQlVHX1ZFUkJPU0VfSU9DVEwgKQkJCQlcCiAgICAgIGZwcmludGYoIHN0ZGVyciwgIkZJTklTSF9ETUFfTE9DS0VEIGluICVzXG4iLCBfX0ZVTkNUSU9OX18gKTsJXAogICBpZiAoIG1tZXNhLT52ZXJ0X3VzZWQgKSB7CQkJCQkJXAogICAgICBtYWNoNjRGbHVzaFZlcnRpY2VzTG9ja2VkKCBtbWVzYSApOwkJCQlcCiAgIH0JCQkJCQkJCQlcCiAgIG1hY2g2NFdhaXRGb3JJZGxlTG9ja2VkKCBtbWVzYSApOwkJCQkJXAogICAvKiBwcmUtcmVhZCBmcmFtZWJ1ZmZlciB0byBjb3VudGVyIGNhY2hpbmcgcHJvYmxlbSAqLwkJXAogICBfdG1wID0gKih2b2xhdGlsZSBDQVJEMzIgKiltbWVzYS0+ZHJpU2NyZWVuLT5wRkI7CQkJXAp9IHdoaWxlICgwKQoKI2RlZmluZSBGTFVTSF9ETUFfTE9DS0VEKCBtbWVzYSApCQkJCQlcCmRvIHsJCQkJCQkJCQlcCiAgIGlmICggTUFDSDY0X0RFQlVHICYgREVCVUdfVkVSQk9TRV9JT0NUTCApCQkJCVwKICAgICAgZnByaW50Ziggc3RkZXJyLCAiRkxVU0hfRE1BX0xPQ0tFRCBpbiAlc1xuIiwgX19GVU5DVElPTl9fICk7CVwKICAgaWYgKCBtbWVzYS0+dmVydF91c2VkICkgewkJCQkJCVwKICAgICAgbWFjaDY0Rmx1c2hWZXJ0aWNlc0xvY2tlZCggbW1lc2EgKTsJCQkJXAogICB9CQkJCQkJCQkJXAogICBtYWNoNjRGbHVzaERNQUxvY2tlZCggbW1lc2EgKTsJCQkJCVwKfSB3aGlsZSAoMCkKCiNkZWZpbmUgbWFjaDY0Rmx1c2hWZXJ0aWNlcyggbW1lc2EgKQkJCQkJXApkbyB7CQkJCQkJCQkJXAogICBMT0NLX0hBUkRXQVJFKCBtbWVzYSApOwkJCQkJCVwKICAgbWFjaDY0Rmx1c2hWZXJ0aWNlc0xvY2tlZCggbW1lc2EgKTsJCQkJCVwKICAgVU5MT0NLX0hBUkRXQVJFKCBtbWVzYSApOwkJCQkJCVwKfSB3aGlsZSAoMCkKCiNkZWZpbmUgbWFjaDY0V2FpdEZvcklkbGUoIG1tZXNhICkJCVwKZG8gewkJCQkJCVwKICAgTE9DS19IQVJEV0FSRSggbW1lc2EgKTsJCQlcCiAgIG1hY2g2NFdhaXRGb3JJZGxlTG9ja2VkKCBtbWVzYSApOwkJXAogICBVTkxPQ0tfSEFSRFdBUkUoIG1tZXNhICk7CQkJXAp9IHdoaWxlICgwKQoKCiNlbmRpZiAvKiBfX01BQ0g2NF9JT0NUTF9IX18gKi8K