LyogbG9nZ2luZy5jIC0gZ2VuZXJpYyBsb2dnaW5nIGZvciBzbm1wLWFnZW50CiAqIENvbnRyaWJ1dGVkIGJ5IFJhZ25hciBLavhyc3RhZCwgdWNkQHJhZ25hcmsudmVzdGRhdGEubm8gMTk5OS0wNi0yNiAqLwoKI2luY2x1ZGUgImNvbmZpZy5oIgojaW5jbHVkZSA8c3RkaW8uaD4KI2lmIEhBVkVfTUFMTE9DX0gKI2luY2x1ZGUgPG1hbGxvYy5oPgojZW5kaWYKI2lmIEhBVkVfU1RSSU5HX0gKI2luY2x1ZGUgPHN0cmluZy5oPgojZWxzZQojaW5jbHVkZSA8c3RyaW5ncy5oPgojZW5kaWYKI2lmIEhBVkVfU1RETElCX0gKI2luY2x1ZGUgPHN0ZGxpYi5oPgojZW5kaWYKI2luY2x1ZGUgPHN5cy90eXBlcy5oPgojaW5jbHVkZSA8c3lzL3N0YXQuaD4KI2luY2x1ZGUgPGZjbnRsLmg+CiNpbmNsdWRlIDxlcnJuby5oPgojaWYgSEFWRV9TWVNMT0dfSAojaW5jbHVkZSA8c3lzbG9nLmg+CiNpZm5kZWYgTE9HX0NPTlMJLyogSW50ZXJlc3RpbmcgVWx0cml4IGZlYXR1cmUgKi8KI2luY2x1ZGUgPHN5cy9zeXNsb2cuaD4KI2VuZGlmCiNlbmRpZgojaWYgVElNRV9XSVRIX1NZU19USU1FCiMgaWZkZWYgV0lOMzIKIyAgaW5jbHVkZSA8c3lzL3RpbWViLmg+CiMgZWxzZQojICBpbmNsdWRlIDxzeXMvdGltZS5oPgojIGVuZGlmCiMgaW5jbHVkZSA8dGltZS5oPgojZWxzZQojIGlmIEhBVkVfU1lTX1RJTUVfSAojICBpbmNsdWRlIDxzeXMvdGltZS5oPgojIGVsc2UKIyAgaW5jbHVkZSA8dGltZS5oPgojIGVuZGlmCiNlbmRpZgojaWYgSEFWRV9ORVRJTkVUX0lOX0gKI2luY2x1ZGUgPG5ldGluZXQvaW4uaD4KI2VuZGlmCgojaWYgSEFWRV9TVERBUkdfSAojaW5jbHVkZSA8c3RkYXJnLmg+CiNlbHNlCiNpbmNsdWRlIDx2YXJhcmdzLmg+CiNlbmRpZgoKI2lmIEhBVkVfRE1BTExPQ19ICiNpbmNsdWRlIDxkbWFsbG9jLmg+CiNlbmRpZgoKI2lmIEhBVkVfV0lOU09DS19ICiNpbmNsdWRlIDx3aW5zb2NrLmg+CiNlbmRpZgoKI2lmIEhBVkVfV0lORE9XU19ICiNpbmNsdWRlIDx3aW5kb3dzLmg+CiNlbmRpZgoKI2luY2x1ZGUgImFzbjEuaCIKI2luY2x1ZGUgImRlZmF1bHRfc3RvcmUuaCIKI2luY2x1ZGUgInNubXBfbG9nZ2luZy5oIgojaW5jbHVkZSAiY2FsbGJhY2suaCIKI2luY2x1ZGUgInN5c3RlbS5oIgojZGVmaW5lIExPR0xFTkdUSCAxMDI0CgpzdGF0aWMgaW50IGRvX3N5c2xvZ2dpbmc9MDsKc3RhdGljIGludCBkb19maWxlbG9nZ2luZz0wOwpzdGF0aWMgaW50IGRvX3N0ZGVycmxvZ2dpbmc9MTsKc3RhdGljIGludCBkb19sb2dfY2FsbGJhY2s9MDsKc3RhdGljIGludCBuZXdsaW5lID0gMTsKc3RhdGljIEZJTEUgKmxvZ2ZpbGU7CiNpZmRlZiBXSU4zMgpzdGF0aWMgSEFORExFIGV2ZW50bG9nX2g7CiNlbmRpZgoKI2lmbmRlZiBIQVZFX1ZTTlBSSU5URgoJCS8qIE5lZWQgdG8gdXNlIHRoZSBVQ0QtcHJvdmlkZWQgb25lICovCmludCB2c25wcmludGYgKGNoYXIgKnN0ciwgc2l6ZV90IGNvdW50LCBjb25zdCBjaGFyICpmbXQsIHZhX2xpc3QgYXJnKTsKI2VuZGlmCgp2b2lkCmluaXRfc25tcF9sb2dnaW5nKHZvaWQpIHsKICBkc19yZWdpc3Rlcl9wcmVtaWIoQVNOX0JPT0xFQU4sICJzbm1wIiwgImxvZ1RpbWVzdGFtcCIsIERTX0xJQlJBUllfSUQsCiAgICAgICAgICAgICAgICAgICAgIERTX0xJQl9MT0dfVElNRVNUQU1QKTsKfQoKaW50CnNubXBfZ2V0X2RvX2xvZ2dpbmcodm9pZCkgewogIHJldHVybiAoZG9fc3lzbG9nZ2luZyB8fCBkb19maWxlbG9nZ2luZyB8fCBkb19zdGRlcnJsb2dnaW5nIHx8CiAgICAgICAgICBkb19sb2dfY2FsbGJhY2spOwp9CgoKc3RhdGljIGNoYXIgKgpzcHJpbnRmX3N0YW1wICh0aW1lX3QgKm5vdywgY2hhciAqc2J1ZikKewogICAgdGltZV90IE5vdzsKICAgIHN0cnVjdCB0bSAqdG07CgogICAgaWYgKG5vdyA9PSBOVUxMKSB7Cglub3cgPSAmTm93OwoJdGltZSAobm93KTsKICAgIH0KICAgIHRtID0gbG9jYWx0aW1lIChub3cpOwogICAgc3ByaW50ZihzYnVmLCAiJS40ZC0lLjJkLSUuMmQgJS4yZDolLjJkOiUuMmQgIiwKCSAgICB0bS0+dG1feWVhcisxOTAwLCB0bS0+dG1fbW9uKzEsIHRtLT50bV9tZGF5LAoJICAgIHRtLT50bV9ob3VyLCB0bS0+dG1fbWluLCB0bS0+dG1fc2VjKTsKICAgIHJldHVybiBzYnVmOwp9Cgp2b2lkCnNubXBfZGlzYWJsZV9zeXNsb2codm9pZCkgewojaWYgSEFWRV9TWVNMT0dfSAogIGlmIChkb19zeXNsb2dnaW5nKQogICAgY2xvc2Vsb2coKTsKI2VuZGlmCiNpZmRlZiBXSU4zMgogIGlmIChldmVudGxvZ19oICE9IE5VTEwpCiAgewoJICBpZiAoISBDbG9zZUV2ZW50TG9nKGV2ZW50bG9nX2gpKQoJICB7CgkJICBmcHJpbnRmKHN0ZGVyciwgIkNvdWxkIG5vdCBjbG9zZSBldmVudCBsb2cuICIKCQkJICAiTGFzdCBlcnJvcjogMHgleFxuIiwgR2V0TGFzdEVycm9yKCkpOwoJICB9CgkgIGVsc2UKCSAgewoJCSAgZXZlbnRsb2dfaCA9IE5VTEw7CgkgIH0KICB9CiNlbmRpZiAvKiBXSU4zMiAqLyAgCiAgZG9fc3lzbG9nZ2luZz0wOwp9CgoKdm9pZApzbm1wX2Rpc2FibGVfZmlsZWxvZyh2b2lkKSB7CiAgaWYgKGRvX2ZpbGVsb2dnaW5nKQogIHsKICAgIGZwdXRzKCJcbiIsbG9nZmlsZSk7CiAgICBmY2xvc2UobG9nZmlsZSk7CiAgfQogIGRvX2ZpbGVsb2dnaW5nPTA7Cn0KCgp2b2lkCnNubXBfZGlzYWJsZV9zdGRlcnJsb2codm9pZCkgewogIGRvX3N0ZGVycmxvZ2dpbmc9MDsKfQoKCnZvaWQKc25tcF9kaXNhYmxlX2xvZyh2b2lkKSB7CiAgc25tcF9kaXNhYmxlX3N5c2xvZygpOwogIHNubXBfZGlzYWJsZV9maWxlbG9nKCk7CiAgc25tcF9kaXNhYmxlX3N0ZGVycmxvZygpOwogIHNubXBfZGlzYWJsZV9jYWxsbG9nKCk7Cn0KCnZvaWQKc25tcF9lbmFibGVfc3lzbG9nKHZvaWQpCnsKCS8qIFRoaXMgZGVmYXVsdCBzaG91bGQgcHJvYmFibHkgYmUgbmV0LXNubXAgYXQgc29tZSBwb2ludCAqLwoJc25tcF9lbmFibGVfc3lzbG9nX2lkZW50KERFRkFVTFRfTE9HX0lEKTsKfQoKdm9pZApzbm1wX2VuYWJsZV9zeXNsb2dfaWRlbnQoY29uc3QgY2hhciAqaWRlbnQpCnsKCXNubXBfZGlzYWJsZV9zeXNsb2coKTsKCWlmIChpZGVudCA9PSBOVUxMKQoJCS8qIFRoaXMgZGVmYXVsdCBzaG91bGQgcHJvYmFibHkgYmUgbmV0LXNubXAgYXQgc29tZSBwb2ludCAqLwoJCWlkZW50ID0gREVGQVVMVF9MT0dfSUQ7CiNpZiBIQVZFX1NZU0xPR19ICglvcGVubG9nKGlkZW50LCBMT0dfQ09OU3xMT0dfUElELCBMT0dfREFFTU9OKTsKCWRvX3N5c2xvZ2dpbmc9MTsKI2VuZGlmCiNpZmRlZiBXSU4zMgoJZXZlbnRsb2dfaCA9IE9wZW5FdmVudExvZyhOVUxMLCBpZGVudCk7CglpZiAoZXZlbnRsb2dfaCA9PSBOVUxMKQoJewoJCWZwcmludGYoc3RkZXJyLCAiQ291bGQgbm90IG9wZW4gZXZlbnQgbG9nIGZvciAlcy4gIgoJCQkiTGFzdCBlcnJvcjogMHgleFxuIiwgaWRlbnQsIEdldExhc3RFcnJvcigpKTsKCQlkb19zeXNsb2dnaW5nPTA7Cgl9CgllbHNlCgkJZG9fc3lzbG9nZ2luZz0xOwojZW5kaWYgLyogV0lOMzIgKi8KfQoKdm9pZApzbm1wX2VuYWJsZV9maWxlbG9nKGNvbnN0IGNoYXIgKmxvZ2ZpbGVuYW1lLCBpbnQgZG9udF96ZXJvX2xvZykKewogIHNubXBfZGlzYWJsZV9maWxlbG9nKCk7CiAgbG9nZmlsZT1mb3Blbihsb2dmaWxlbmFtZSwgZG9udF96ZXJvX2xvZyA/ICJhIiA6ICJ3Iik7CiAgaWYgKGxvZ2ZpbGUpIHsKICAgIGRvX2ZpbGVsb2dnaW5nPTE7CiAgICBzZXR2YnVmKGxvZ2ZpbGUsIE5VTEwsIF9JT0xCRiwgQlVGU0laKTsKICB9CiAgZWxzZQogICAgZG9fZmlsZWxvZ2dpbmc9MDsKfQoKCnZvaWQKc25tcF9lbmFibGVfc3RkZXJybG9nKHZvaWQpIHsKICBkb19zdGRlcnJsb2dnaW5nPTE7Cn0KCgp2b2lkCnNubXBfZW5hYmxlX2NhbGxsb2codm9pZCkgewogIGRvX2xvZ19jYWxsYmFjayA9IDE7Cn0KCgp2b2lkCnNubXBfZGlzYWJsZV9jYWxsbG9nKHZvaWQpIHsKICBkb19sb2dfY2FsbGJhY2sgPSAwOwp9CgoKdm9pZApzbm1wX2xvZ19zdHJpbmcgKGludCBwcmlvcml0eSwgY29uc3QgY2hhciAqc3RyaW5nKQp7CiAgICBjaGFyIHNidWZbNDBdOwogICAgc3RydWN0IHNubXBfbG9nX21lc3NhZ2Ugc2xtOwojaWZkZWYgV0lOMzIKICAgIFdPUkQgZXR5cGU7CiAgICBMUENUU1RSIGV2ZW50X21zZ1syXTsKI2VuZGlmIC8qIFdJTjMyICovCiAgICAKI2lmIEhBVkVfU1lTTE9HX0gKICBpZiAoZG9fc3lzbG9nZ2luZykgewogICAgc3lzbG9nKHByaW9yaXR5LCAiJXMiLCBzdHJpbmcpOwogIH0KI2VuZGlmCgojaWZkZWYgV0lOMzIKICAgIGlmIChkb19zeXNsb2dnaW5nKQogICAgewoJICAgIC8qCgkgICAgICoqICBFVkVOVCBUWVBFUzoKCSAgICAgKioKCSAgICAgKiogIEluZm9ybWF0aW9uIChFVkVOVExPR19JTkZPUk1BVElPTl9UWVBFKQoJICAgICAqKiAgICAgIEluZm9ybWF0aW9uIGV2ZW50cyBpbmRpY2F0ZSBpbmZyZXF1ZW50IGJ1dCBzaWduaWZpY2FudAoJICAgICAqKiAgICAgIHN1Y2Nlc3NmdWwgb3BlcmF0aW9ucy4KCSAgICAgKiogIFdhcm5pbmcgKEVWRU5UTE9HX1dBUk5JTkdfVFlQRSkKCSAgICAgKiogICAgICBXYXJuaW5nIGV2ZW50cyBpbmRpY2F0ZSBwcm9ibGVtcyB0aGF0IGFyZSBub3QgaW1tZWRpYXRlbHkKCSAgICAgKiogICAgICBzaWduaWZpY2FudCwgYnV0IHRoYXQgbWF5IGluZGljYXRlIGNvbmRpdGlvbnMgdGhhdCBjb3VsZAoJICAgICAqKiAgICAgIGNhdXNlIGZ1dHVyZSBwcm9ibGVtcy4gUmVzb3VyY2UgY29uc3VtcHRpb24gaXMgYSBnb29kCgkgICAgICoqICAgICAgY2FuZGlkYXRlIGZvciBhIHdhcm5pbmcgZXZlbnQuCgkgICAgICoqICBFcnJvciAoRVZFTlRMT0dfRVJST1JfVFlQRSkKCSAgICAgKiogICAgICBFcnJvciBldmVudHMgaW5kaWNhdGUgc2lnbmlmaWNhbnQgcHJvYmxlbXMgdGhhdCB0aGUgdXNlcgoJICAgICAqKiAgICAgIHNob3VsZCBrbm93IGFib3V0LiBFcnJvciBldmVudHMgdXN1YWxseSBpbmRpY2F0ZSBhIGxvc3Mgb2YKCSAgICAgKiogICAgICBmdW5jdGlvbmFsaXR5IG9yIGRhdGEuCgkgICAgICovCgkgICAgc3dpdGNoKHByaW9yaXR5KQoJICAgIHsKCSAgICBjYXNlIExPR19FTUVSRzoKCSAgICBjYXNlIExPR19BTEVSVDoKCSAgICBjYXNlIExPR19DUklUOgoJICAgIGNhc2UgTE9HX0VSUjoKCQkgICAgZXR5cGUgPSBFVkVOVExPR19FUlJPUl9UWVBFOwoJCSAgICBicmVhazsKCSAgICBjYXNlIExPR19XQVJOSU5HOgoJCSAgICBldHlwZSA9IEVWRU5UTE9HX1dBUk5JTkdfVFlQRTsKCQkgICAgYnJlYWs7CgkgICAgY2FzZSBMT0dfTk9USUNFOgoJICAgIGNhc2UgTE9HX0lORk86CgkgICAgY2FzZSBMT0dfREVCVUc6CgkJICAgIGV0eXBlID0gRVZFTlRMT0dfSU5GT1JNQVRJT05fVFlQRTsKCQkgICAgYnJlYWs7CgkgICAgZGVmYXVsdDoKCQkgICAgZXR5cGUgPSBFVkVOVExPR19JTkZPUk1BVElPTl9UWVBFOwoJCSAgICBicmVhazsKCSAgICB9CgkgICAgZXZlbnRfbXNnWzBdID0gc3RyaW5nOwoJICAgIGV2ZW50X21zZ1sxXSA9IE5VTEw7CgkgICAgaWYgKCEgUmVwb3J0RXZlbnQoZXZlbnRsb2dfaCwgZXR5cGUsIDAsIDAsIE5VTEwsIDEsIDAsCgkJCSAgICAgIGV2ZW50X21zZywgTlVMTCkpCgkJICAgIGZwcmludGYoc3RkZXJyLCAiQ291bGQgbm90IHJlcG9ydCBldmVudC4gIExhc3QgZXJyb3I6ICIKCQkJICAgICIweCV4XG4iLCBHZXRMYXN0RXJyb3IoKSk7CiAgICB9CiNlbmRpZiAvKiBXSU4zMiAqLwogICAgCiAgaWYgKGRvX2xvZ19jYWxsYmFjaykgewogICAgICBzbG0ucHJpb3JpdHkgPSBwcmlvcml0eTsKICAgICAgc2xtLm1zZyA9IHN0cmluZzsKICAgICAgc25tcF9jYWxsX2NhbGxiYWNrcyhTTk1QX0NBTExCQUNLX0xJQlJBUlksIFNOTVBfQ0FMTEJBQ0tfTE9HR0lORywgJnNsbSk7CiAgfQoKICBpZiAoZG9fZmlsZWxvZ2dpbmcgfHwgZG9fc3RkZXJybG9nZ2luZykgewoKICAgIGlmIChkc19nZXRfYm9vbGVhbihEU19MSUJSQVJZX0lELCBEU19MSUJfTE9HX1RJTUVTVEFNUCkgJiYgbmV3bGluZSkgewogICAgICBzcHJpbnRmX3N0YW1wKE5VTEwsIHNidWYpOwogICAgfSBlbHNlIHsKICAgICAgc3RyY3B5KHNidWYsICIiKTsKICAgIH0KICAgIG5ld2xpbmUgPSBzdHJpbmdbc3RybGVuKHN0cmluZyktMV0gPT0gJ1xuJzsKCiAgICBpZiAoZG9fZmlsZWxvZ2dpbmcpCiAgICAgIGZwcmludGYobG9nZmlsZSwgIiVzJXMiLCBzYnVmLCBzdHJpbmcpOwoKICAgIGlmIChkb19zdGRlcnJsb2dnaW5nKQogICAgICBmcHJpbnRmKHN0ZGVyciwgIiVzJXMiLCBzYnVmLCBzdHJpbmcpOwogIH0KfQoKaW50CnNubXBfdmxvZyAoaW50IHByaW9yaXR5LCBjb25zdCBjaGFyICpmb3JtYXQsIHZhX2xpc3QgYXApCnsKICBjaGFyIGJ1ZmZlcltMT0dMRU5HVEhdOwogIGludCBsZW5ndGg7CiAgY2hhciAqZHluYW1pYzsKCiAgbGVuZ3RoPXZzbnByaW50ZihidWZmZXIsIExPR0xFTkdUSCwgZm9ybWF0LCBhcCk7CgogIGlmIChsZW5ndGggPT0gMCkgCiAgICByZXR1cm4oMCk7CQkvKiBFbXB0eSBzdHJpbmcgKi8KCiAgaWYgKGxlbmd0aCA9PSAtMSkgewogICAgc25tcF9sb2dfc3RyaW5nKExPR19FUlIsICJDb3VsZCBub3QgZm9ybWF0IGxvZy1zdHJpbmdcbiIpOwogICAgcmV0dXJuKC0xKTsKICB9CgogIGlmIChsZW5ndGggPCBMT0dMRU5HVEgpIHsKICAgIHNubXBfbG9nX3N0cmluZyhwcmlvcml0eSwgYnVmZmVyKTsKICAgIHJldHVybigwKTsKICB9CgogIGR5bmFtaWMgPSAoY2hhciAqKW1hbGxvYyhsZW5ndGgrMSk7CiAgaWYgKGR5bmFtaWM9PU5VTEwpIHsKICAgIHNubXBfbG9nX3N0cmluZyhMT0dfRVJSLCAiQ291bGQgbm90IGFsbG9jYXRlIG1lbW9yeSBmb3IgbG9nLW1lc3NhZ2VcbiIpOwogICAgc25tcF9sb2dfc3RyaW5nKHByaW9yaXR5LCBidWZmZXIpOwogICAgcmV0dXJuKC0yKTsKICB9CgogIHZzbnByaW50ZihkeW5hbWljLCBsZW5ndGgrMSwgZm9ybWF0LCBhcCk7CiAgc25tcF9sb2dfc3RyaW5nKHByaW9yaXR5LCBkeW5hbWljKTsKICBmcmVlKGR5bmFtaWMpOwogIHJldHVybiAwOwp9CgoKaW50CiNpZiBIQVZFX1NUREFSR19ICnNubXBfbG9nIChpbnQgcHJpb3JpdHksIGNvbnN0IGNoYXIgKmZvcm1hdCwgLi4uKQojZWxzZQpzbm1wX2xvZyAodmFfYWxpc3QpCiAgdmFfZGNsCiNlbmRpZgp7CiAgdmFfbGlzdCBhcDsKICBpbnQgcmV0OwojaWYgSEFWRV9TVERBUkdfSAogIHZhX3N0YXJ0KGFwLCBmb3JtYXQpOwojZWxzZQogIGludCBwcmlvcml0eTsKICBjb25zdCBjaGFyICpmb3JtYXQ7CiAgdmFfc3RhcnQoYXApOwoKICBwcmlvcml0eSA9IHZhX2FyZyhhcCwgaW50KTsKICBmb3JtYXQgPSB2YV9hcmcoYXAsIGNvbnN0IGNoYXIgKik7CiNlbmRpZgogIHJldD1zbm1wX3Zsb2cocHJpb3JpdHksIGZvcm1hdCwgYXApOwogIHZhX2VuZChhcCk7CiAgcmV0dXJuKHJldCk7Cn0KCi8qCiAqIGxvZyBhIGNyaXRpY2FsIGVycm9yLgogKi8Kdm9pZApzbm1wX2xvZ19wZXJyb3IoY29uc3QgY2hhciAqcykKewogIGNoYXIgKmVycm9yICA9IHN0cmVycm9yKGVycm5vKTsKICBpZiAocykgewogICAgaWYgKGVycm9yKQogICAgICBzbm1wX2xvZyhMT0dfRVJSLCAiJXM6ICVzXG4iLCBzLCBlcnJvcik7CiAgICBlbHNlCiAgICAgIHNubXBfbG9nKExPR19FUlIsICIlczogRXJyb3IgJWQgb3V0LW9mLXJhbmdlXG4iLCBzLCBlcnJubyk7CiAgfSBlbHNlIHsKICAgIGlmIChlcnJvcikKICAgICAgc25tcF9sb2coTE9HX0VSUiwgIiVzXG4iLCBlcnJvcik7CiAgICBlbHNlCiAgICAgIHNubXBfbG9nKExPR19FUlIsICJFcnJvciAlZCBvdXQtb2YtcmFuZ2VcbiIsIGVycm5vKTsKICB9Cn0KCg==