LyogZmRmb3JtYXQuYyAgLSAgTG93LWxldmVsIGZvcm1hdHMgYSBmbG9wcHkgZGlzayAtIFdlcm5lciBBbG1lc2JlcmdlciAqLwoKLyogMTk5OS0wMi0yMiBBcmthZGl1c3ogTWm2a2lld2ljeiA8bWlzaWVrQHBsZC5PUkcuUEw+CiAqIC0gYWRkZWQgTmF0aXZlIExhbmd1YWdlIFN1cHBvcnQKICogMTk5OS0wMy0yMCBBcm5hbGRvIENhcnZhbGhvIGRlIE1lbG8gPGFjbWVAY29uZWN0aXZhLmNvbS5icj4KICogLSBtb3JlIGkxOG4vbmxzIHRyYW5zbGF0YWJsZSBzdHJpbmdzIG1hcmtlZAogKgogKiA1IEp1bHkgMjAwMyAtLSBtb2RpZmllZCBmb3IgQnVzeWJveCBieSBFcmlrIEFuZGVyc2VuCiAqLwoKI2luY2x1ZGUgPHN0ZGlvLmg+CiNpbmNsdWRlIDxzdHJpbmcuaD4KI2luY2x1ZGUgPGZjbnRsLmg+CiNpbmNsdWRlIDxlcnJuby5oPgojaW5jbHVkZSA8dW5pc3RkLmg+CiNpbmNsdWRlIDxzdGRsaWIuaD4KI2luY2x1ZGUgPHN5cy9zdGF0Lmg+CiNpbmNsdWRlIDxzeXMvaW9jdGwuaD4KI2luY2x1ZGUgImJ1c3lib3guaCIKCgovKiBTdHVmZiBleHRyYWN0ZWQgZnJvbSBsaW51eC9mZC5oICovCnN0cnVjdCBmbG9wcHlfc3RydWN0IHsKCXVuc2lnbmVkIGludAlzaXplLAkJLyogbnIgb2Ygc2VjdG9ycyB0b3RhbCAqLwoJCQlzZWN0LAkJLyogc2VjdG9ycyBwZXIgdHJhY2sgKi8KCQkJaGVhZCwJCS8qIG5yIG9mIGhlYWRzICovCgkJCXRyYWNrLAkJLyogbnIgb2YgdHJhY2tzICovCgkJCXN0cmV0Y2g7CS8qICE9MCBtZWFucyBkb3VibGUgdHJhY2sgc3RlcHMgKi8KI2RlZmluZSBGRF9TVFJFVENIIDEKI2RlZmluZSBGRF9TV0FQU0lERVMgMgoKCXVuc2lnbmVkIGNoYXIJZ2FwLAkJLyogZ2FwMSBzaXplICovCgoJCQlyYXRlLAkJLyogZGF0YSByYXRlLiB8PSAweDQwIGZvciBwZXJwZW5kaWN1bGFyICovCiNkZWZpbmUgRkRfMk0gMHg0CiNkZWZpbmUgRkRfU0laRUNPREVNQVNLIDB4MzgKI2RlZmluZSBGRF9TSVpFQ09ERShmbG9wcHkpICgoKCgoZmxvcHB5KS0+cmF0ZSZGRF9TSVpFQ09ERU1BU0spPj4gMykrIDIpICU4KQojZGVmaW5lIEZEX1NFQ1RTSVpFKGZsb3BweSkgKCAoZmxvcHB5KS0+cmF0ZSAmIEZEXzJNID8gXAoJCQkgICAgIDUxMiA6IDEyOCA8PCBGRF9TSVpFQ09ERShmbG9wcHkpICkKI2RlZmluZSBGRF9QRVJQIDB4NDAKCgkJCXNwZWMxLAkJLyogc3RlcHBpbmcgcmF0ZSwgaGVhZCB1bmxvYWQgdGltZSAqLwoJCQlmbXRfZ2FwOwkvKiBnYXAyIHNpemUgKi8KCWNvbnN0IGNoYXIJKiBuYW1lOyAvKiB1c2VkIG9ubHkgZm9yIHByZWRlZmluZWQgZm9ybWF0cyAqLwp9OwpzdHJ1Y3QgZm9ybWF0X2Rlc2NyIHsKCXVuc2lnbmVkIGludCBkZXZpY2UsaGVhZCx0cmFjazsKfTsKI2RlZmluZSBGREZNVEJFRyBfSU8oMiwweDQ3KQojZGVmaW5lCUZERk1UVFJLIF9JT1coMiwweDQ4LCBzdHJ1Y3QgZm9ybWF0X2Rlc2NyKQojZGVmaW5lIEZERk1URU5EIF9JTygyLDB4NDkpCiNkZWZpbmUgRkRHRVRQUk0gX0lPUigyLCAweDA0LCBzdHJ1Y3QgZmxvcHB5X3N0cnVjdCkKI2RlZmluZSBGRF9GSUxMX0JZVEUgMHhGNiAvKiBmb3JtYXQgZmlsbCBieXRlLiAqLwoKc3RhdGljIHZvaWQgcHJpbnRfYW5kX2ZsdXNoKGNvbnN0IGNoYXIgKiBfX3Jlc3RyaWN0IGZvcm1hdCwgLi4uKQp7Cgl2YV9saXN0IGFyZzsKCgl2YV9zdGFydChhcmcsIGZvcm1hdCk7CgliYl92ZnByaW50ZihzdGRvdXQsIGZvcm1hdCwgYXJnKTsKCXZhX2VuZChhcmcpOwoJYmJfeGZmbHVzaF9zdGRvdXQoKTsKfQoKc3RhdGljIHZvaWQgYmJfeGlvY3RsKGludCBmZCwgaW50IHJlcXVlc3QsIHZvaWQgKmFyZ3AsIGNvbnN0IGNoYXIgKnN0cmluZykKewoJaWYgKGlvY3RsIChmZCwgcmVxdWVzdCwgYXJncCkgPCAwKSB7CgkJYmJfcGVycm9yX21zZ19hbmRfZGllKHN0cmluZyk7Cgl9Cn0KCmludCBmZGZvcm1hdF9tYWluKGludCBhcmdjLGNoYXIgKiphcmd2KQp7CglpbnQgZmQsIG4sIGN5bCwgcmVhZF9ieXRlcywgdmVyaWZ5OwoJdW5zaWduZWQgY2hhciAqZGF0YTsKCXN0cnVjdCBzdGF0IHN0OwoJc3RydWN0IGZsb3BweV9zdHJ1Y3QgcGFyYW07CglzdHJ1Y3QgZm9ybWF0X2Rlc2NyIGRlc2NyOwoKCWlmIChhcmdjIDwgMikgewoJCWJiX3Nob3dfdXNhZ2UoKTsKCX0KCXZlcmlmeSA9ICFiYl9nZXRvcHRfdWxmbGFncyhhcmdjLCBhcmd2LCAibiIpOwoJYXJndiArPSBvcHRpbmQ7CgoJLyogUl9PSyBpcyBuZWVkZWQgZm9yIHZlcmlmeWluZyAqLwoJaWYgKHN0YXQoKmFyZ3YsJnN0KSA8IDAgfHwgYWNjZXNzKCphcmd2LFdfT0sgfCBSX09LICkgPCAwKSB7CgkJYmJfcGVycm9yX21zZ19hbmRfZGllKCIlcyIsKmFyZ3YpOwoJfQoJaWYgKCFTX0lTQkxLKHN0LnN0X21vZGUpKSB7CgkJYmJfZXJyb3JfbXNnX2FuZF9kaWUoIiVzOiBub3QgYSBibG9jayBkZXZpY2UiLCphcmd2KTsKCQkvKiBkbyBub3QgdGVzdCBtYWpvciAtIHBlcmhhcHMgdGhpcyB3YXMgYW4gVVNCIGZsb3BweSAqLwoJfQoKCgkvKiBPX1JEV1IgZm9yIGZvcm1hdHRpbmcgYW5kIHZlcmlmeWluZyAqLwoJZmQgPSBiYl94b3BlbigqYXJndixPX1JEV1IgKTsKCgliYl94aW9jdGwoZmQsIEZER0VUUFJNLCAmcGFyYW0sICJGREdFVFBSTSIpOy8qb3JpZ2luYWwgbWVzc2FnZSB3YXM6ICJDb3VsZCBub3QgZGV0ZXJtaW5lIGN1cnJlbnQgZm9ybWF0IHR5cGUiICovCgoJcHJpbnRfYW5kX2ZsdXNoKCIlcy1zaWRlZCwgJWQgdHJhY2tzLCAlZCBzZWMvdHJhY2suIFRvdGFsIGNhcGFjaXR5ICVkIGtCLlxuIiwKCQkocGFyYW0uaGVhZCA9PSAyKSA/ICJEb3VibGUiIDogIlNpbmdsZSIsCgkJcGFyYW0udHJhY2ssIHBhcmFtLnNlY3QsIHBhcmFtLnNpemUgPj4gMSk7CgoJLyogRk9STUFUICovCglwcmludF9hbmRfZmx1c2goIkZvcm1hdHRpbmcgLi4uICIsIE5VTEwpOwoJYmJfeGlvY3RsKGZkLCBGREZNVEJFRyxOVUxMLCJGREZNVEJFRyIpOwoKCS8qIG4gPT0gdHJhY2sgKi8KCWZvciAobiA9IDA7IG4gPCBwYXJhbS50cmFjazsgbisrKQoJewoJICAgIGRlc2NyLmhlYWQgPSAwOwoJICAgIGRlc2NyLnRyYWNrID0gbjsKCSAgICBiYl94aW9jdGwoZmQsIEZERk1UVFJLLCZkZXNjciwiRkRGTVRUUksiKTsKCSAgICBwcmludF9hbmRfZmx1c2goIiUzZFxiXGJcYiIsIG4pOwoJICAgIGlmIChwYXJhbS5oZWFkID09IDIpIHsKCQlkZXNjci5oZWFkID0gMTsKCQliYl94aW9jdGwoZmQsIEZERk1UVFJLLCZkZXNjciwiRkRGTVRUUksiKTsKCSAgICB9Cgl9CgoJYmJfeGlvY3RsKGZkLEZERk1URU5ELE5VTEwsIkZERk1URU5EIik7CglwcmludF9hbmRfZmx1c2goImRvbmVcbiIsIE5VTEwpOwoKCS8qIFZFUklGWSAqLwoJaWYodmVyaWZ5KSB7CgkJLyogbiA9PSBjeWxfc2l6ZSAqLwoJCW4gPSBwYXJhbS5zZWN0KnBhcmFtLmhlYWQqNTEyOwoKCQlkYXRhID0geG1hbGxvYyhuKTsKCQlwcmludF9hbmRfZmx1c2goIlZlcmlmeWluZyAuLi4gIiwgTlVMTCk7CgkJZm9yIChjeWwgPSAwOyBjeWwgPCBwYXJhbS50cmFjazsgY3lsKyspIHsKCQkJcHJpbnRfYW5kX2ZsdXNoKCIlM2RcYlxiXGIiLCBjeWwpOwoJCQlpZigocmVhZF9ieXRlcyA9IHNhZmVfcmVhZChmZCxkYXRhLG4pKSE9IG4gKSB7CgkJCQlpZihyZWFkX2J5dGVzIDwgMCkgewoJCQkJCWJiX3BlcnJvcl9tc2coIlJlYWQ6ICIpOwoJCQkJfQoJCQkJYmJfZXJyb3JfbXNnX2FuZF9kaWUoIlByb2JsZW0gcmVhZGluZyBjeWxpbmRlciAlZCwgZXhwZWN0ZWQgJWQsIHJlYWQgJWQiLCBjeWwsIG4sIHJlYWRfYnl0ZXMpOwoJCQl9CgkJCS8qIENoZWNrIGJhY2t3YXJkcyBzbyB3ZSBkb24ndCBuZWVkIGEgY291bnRlciAqLwoJCQl3aGlsZSgtLXJlYWRfYnl0ZXM+PTApIHsKCQkJCWlmKCBkYXRhW3JlYWRfYnl0ZXNdICE9IEZEX0ZJTExfQllURSkgewoJCQkJCSBwcmludF9hbmRfZmx1c2goImJhZCBkYXRhIGluIGN5bCAlZFxuQ29udGludWluZyAuLi4gIixjeWwpOwoJCQkJfQoJCQl9CgkJfQoJCS8qIFRoZXJlIGlzIG5vIHBvaW50IGluIGZyZWVpbmcgYmxvY2tzIGF0IHRoZSBlbmQgb2YgYSBwcm9ncmFtLCBiZWNhdXNlCgkJYWxsIG9mIHRoZSBwcm9ncmFtJ3Mgc3BhY2UgaXMgZ2l2ZW4gYmFjayB0byB0aGUgc3lzdGVtIHdoZW4gdGhlIHByb2Nlc3MKCQl0ZXJtaW5hdGVzLiovCgoJCWlmIChFTkFCTEVfRkVBVFVSRV9DTEVBTl9VUCkgZnJlZShkYXRhKTsKCgkJcHJpbnRfYW5kX2ZsdXNoKCJkb25lXG4iLCBOVUxMKTsKCX0KCglpZiAoRU5BQkxFX0ZFQVRVUkVfQ0xFQU5fVVApIGNsb3NlKGZkKTsKCgkvKiBEb24ndCBib3RoZXIgY2xvc2luZy4gIEV4aXQgZG9lcwoJICogdGhhdCwgc28gd2UgY2FuIHNhdmUgYSBmZXcgYnl0ZXMgKi8KCXJldHVybiBFWElUX1NVQ0NFU1M7Cn0K