LyoKICogKEMpCUNvcHlyaWdodCAyMDAxCiAqIFN05HVibGkgRmF2ZXJnZXMgLSA8d3d3LnN0YXVibGkuY29tPgogKiBQaWVycmUgQVVCRVJUICBwLmF1YmVydEBzdGF1YmxpLmNvbQogKiBVLUJvb3QgcG9ydCBvbiBSUFhDbGFzc2ljIExGIChDTExGX0JXMzEpIGJvYXJkCiAqCiAqIChDKSBDb3B5cmlnaHQgMjAwMAogKiBXb2xmZ2FuZyBEZW5rLCBERU5YIFNvZnR3YXJlIEVuZ2luZWVyaW5nLCB3ZEBkZW54LmRlLgogKgogKiBTZWUgZmlsZSBDUkVESVRTIGZvciBsaXN0IG9mIHBlb3BsZSB3aG8gY29udHJpYnV0ZWQgdG8gdGhpcwogKiBwcm9qZWN0LgogKgogKiBUaGlzIHByb2dyYW0gaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yCiAqIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGFzCiAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXIgdmVyc2lvbiAyIG9mCiAqIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLgogKgogKiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwKICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YKICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLgkgU2VlIHRoZQogKiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQogKiBhbG9uZyB3aXRoIHRoaXMgcHJvZ3JhbTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZQogKiBGb3VuZGF0aW9uLCBJbmMuLCA1OSBUZW1wbGUgUGxhY2UsIFN1aXRlIDMzMCwgQm9zdG9uLAogKiBNQSAwMjExMS0xMzA3IFVTQQogKi8KCiNpbmNsdWRlIDxjb21tb24uaD4KI2luY2x1ZGUgPGkyYy5oPgojaW5jbHVkZSA8Y29uZmlnLmg+CiNpbmNsdWRlIDxtcGM4eHguaD4KI2luY2x1ZGUgPG5ldC5oPgoKLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLwoKc3RhdGljIGxvbmcgaW50IGRyYW1fc2l6ZSAobG9uZyBpbnQsIGxvbmcgaW50ICosIGxvbmcgaW50KTsKc3RhdGljIHVuc2lnbmVkIGNoYXIgYXNjaGV4X3RvX2J5dGUgKHVuc2lnbmVkIGNoYXIgKmNwKTsKCi8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi8KCiNkZWZpbmUgX05PVF9VU0VEXwkweEZGRkZDQzI1Cgpjb25zdCB1aW50IHNkcmFtX3RhYmxlW10gPQp7CgkvKgoJICogU2luZ2xlIFJlYWQuIChPZmZzZXQgMDBoIGluIFVQTUEgUkFNKQoJICovCgkweENGRkZDQzI0LCAweDBGRkZDQzA0LCAwWDBDQUZDQzA0LCAwWDAzQUZDQzA4LAoJMHgzRkJGQ0MyNywgLyogbGFzdCAqLwoJX05PVF9VU0VEXywgX05PVF9VU0VEXywgX05PVF9VU0VEXywKCgkvKgoJICogQnVyc3QgUmVhZC4gKE9mZnNldCAwOGggaW4gVVBNQSBSQU0pCgkgKi8KCTB4Q0ZGRkNDMjQsIDB4MEZGRkNDMDQsIDB4MENBRkNDODQsIDB4MDNBRkNDODgsCgkweDNGQkZDQzI3LCAvKiBsYXN0ICovCglfTk9UX1VTRURfLCBfTk9UX1VTRURfLCBfTk9UX1VTRURfLCBfTk9UX1VTRURfLAoJX05PVF9VU0VEXywgX05PVF9VU0VEXywgX05PVF9VU0VEXywgX05PVF9VU0VEXywKCV9OT1RfVVNFRF8sIF9OT1RfVVNFRF8sIF9OT1RfVVNFRF8sCgoJLyoKCSAqIFNpbmdsZSBXcml0ZS4gKE9mZnNldCAxOGggaW4gVVBNQSBSQU0pCgkgKi8KCTB4Q0ZGRkNDMjQsIDB4MEZGRkNDMDQsIDB4MENGRkNDMDQsIDB4MDNGRkNDMDAsCgkweDNGRkZDQzI3LCAvKiBsYXN0ICovCglfTk9UX1VTRURfLCBfTk9UX1VTRURfLCBfTk9UX1VTRURfLAoKCS8qCgkgKiBCdXJzdCBXcml0ZS4gKE9mZnNldCAyMGggaW4gVVBNQSBSQU0pCgkgKi8KCTB4Q0ZGRkNDMjQsIDB4MEZGRkNDMDQsIDB4MENGRkNDODAsIDB4MDNGRkNDOEMsCgkweDBDRkZDQzAwLCAweDMzRkZDQzI3LCAvKiBsYXN0ICovCglfTk9UX1VTRURfLCBfTk9UX1VTRURfLCBfTk9UX1VTRURfLCBfTk9UX1VTRURfLAoJX05PVF9VU0VEXywgX05PVF9VU0VEXywgX05PVF9VU0VEXywgX05PVF9VU0VEXywKCV9OT1RfVVNFRF8sIF9OT1RfVVNFRF8sCgoJLyoKCSAqIFJlZnJlc2guIChPZmZzZXQgMzBoIGluIFVQTUEgUkFNKQoJICovCgkweEMwRkZDQzI0LCAweDAzRkZDQzI0LCAweDBGRkZDQzI0LCAweDBGRkZDQzI0LAoJMHgzRkZGQ0MyNywgLyogbGFzdCAqLwoJX05PVF9VU0VEXywgX05PVF9VU0VEXywgX05PVF9VU0VEXywgX05PVF9VU0VEXywKCV9OT1RfVVNFRF8sIF9OT1RfVVNFRF8sIF9OT1RfVVNFRF8sCgoJLyoKCSAqIEV4Y2VwdGlvbi4gKE9mZnNldCAzQ2ggaW4gVVBNQSBSQU0pCgkgKi8KCV9OT1RfVVNFRF8sIF9OT1RfVVNFRF8sIF9OT1RfVVNFRF8sIF9OT1RfVVNFRF8KfTsKCi8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi8KCgovKgogKiBDaGVjayBCb2FyZCBJZGVudGl0eToKICovCgppbnQgY2hlY2tib2FyZCAodm9pZCkKewoJcHV0cyAoIkJvYXJkOiBSUFhDbGFzc2ljXG4iKTsKCXJldHVybiAoMCk7Cn0KCi8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICogYm9hcmRfZ2V0X2VuZXRhZGRyIC0tIFJlYWQgdGhlIE1BQyBBZGRyZXNzIGluIHRoZSBJMkMgRUVQUk9NCiAqLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICovCnN0YXRpYyB2b2lkIGJvYXJkX2dldF9lbmV0YWRkcih1Y2hhciAqZW5ldCkKewoJaW50IGk7CgljaGFyIGJ1ZmZbMjU2XSwgKmNwOwoKCS8qIEluaXRpYWxpemUgSTJDCQkJCQkqLwoJaTJjX2luaXQgKENPTkZJR19TWVNfSTJDX1NQRUVELCBDT05GSUdfU1lTX0kyQ19TTEFWRSk7CgoJLyogUmVhZCAyNTYgYnl0ZXMgaW4gRUVQUk9NCQkJCSovCglpMmNfcmVhZCAoMHg1NCwgMCwgMSwgKHVjaGFyICopYnVmZiwgMTI4KTsKCWkyY19yZWFkICgweDU0LCAxMjgsIDEsICh1Y2hhciAqKWJ1ZmYgKyAxMjgsIDEyOCk7CgoJLyogUmV0cmlldmUgTUFDIGFkZHJlc3MgaW4gYnVmZmVyIChrZXkgRUEpCQkqLwoJZm9yIChjcCA9IGJ1ZmY7OykgewoJCWlmIChjcFswXSA9PSAnRScgJiYgY3BbMV0gPT0gJ0EnKSB7CgkJCWNwICs9IDM7CgkJCS8qIFJlYWQgTUFDIGFkZHJlc3MJCQkqLwoJCQlmb3IgKGkgPSAwOyBpIDwgNjsgaSsrLCBjcCArPSAyKSB7CgkJCQllbmV0W2ldID0gYXNjaGV4X3RvX2J5dGUgKCh1bnNpZ25lZCBjaGFyICopY3ApOwoJCQl9CgkJfQoJCS8qIFNjYW4gdG8gdGhlIGVuZCBvZiB0aGUgcmVjb3JkCQkqLwoJCXdoaWxlICgoKmNwICE9ICdcbicpICYmICgqY3AgIT0gKGNoYXIpMHhmZikpIHsKCQkJY3ArKzsKCQl9CgkJLyogSWYgdGhlIG5leHQgY2hhcmFjdGVyIGlzIGEgXG4sIDAgb3IgZmYsIHdlIGFyZSBkb25lLgkqLwoJCWNwKys7CgkJaWYgKCgqY3AgPT0gJ1xuJykgfHwgKCpjcCA9PSAwKSB8fCAoKmNwID09IChjaGFyKTB4ZmYpKQoJCQlicmVhazsKCX0KCiNpZmRlZiBDT05GSUdfRkVDX0VORVQKCS8qIFRoZSBNQUMgYWRkcmVzcyBpcyB0aGUgc2FtZSBhcyBub3JtYWwgZXRoZXJuZXQgZXhjZXB0IHRoZSAzcmQgYnl0ZQkgKi8KCS8qIChTZWUgdGhlIEUuUC4gUGxhbmV0IENvcmUgT3ZlcnZpZXcgbWFudWFsCQkqLwoJZW5ldFszXSB8PSAweDgwOwojZW5kaWYKCglwcmludGYoIk1BQyBhZGRyZXNzID0gJXBNXG4iLCBlbmV0KTsKfQoKaW50IG1pc2NfaW5pdF9yKHZvaWQpCnsKCXVjaGFyIGVuZXRhZGRyWzZdOwoKCWlmICghZXRoX2dldGVudl9lbmV0YWRkcigiZXRoYWRkciIsIGVuZXRhZGRyKSkgewoJCWJvYXJkX2dldF9lbmV0YWRkcihlbmV0YWRkcik7CgkJZXRoX3NldGVudl9lbmV0YWRkcigiZXRoYWRkciIsIGVuZXRhZGRyKTsKCX0KCglyZXR1cm4gMDsKfQoKdm9pZCBycHhjbGFzc2ljX2luaXQgKHZvaWQpCnsKCS8qIEVuYWJsZSBOVlJBTSAqLwoJKigodWNoYXIgKikgQkNTUjApIHw9IEJDU1IwX0VOTlZSQU07CgojaWZkZWYgQ09ORklHX0ZFQ19FTkVUCgoJLyogVmFsaWRhdGUgdGhlIGZhc3QgZXRoZXJuZXQgdHJhbmNlaXZlciAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKi8KCSooKHZvbGF0aWxlIHVjaGFyICopIEJDU1IyKSAmPSB+QkNTUjJfTUlJQ1RMOwoJKigodm9sYXRpbGUgdWNoYXIgKikgQkNTUjIpICY9IH5CQ1NSMl9NSUlQV1JEV047CgkqKCh2b2xhdGlsZSB1Y2hhciAqKSBCQ1NSMikgfD0gQkNTUjJfTUlJUlNUOwoJKigodm9sYXRpbGUgdWNoYXIgKikgQkNTUjIpIHw9IEJDU1IyX01JSVBXUkRXTjsKI2VuZGlmCgp9CgovKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovCgpwaHlzX3NpemVfdCBpbml0ZHJhbSAoaW50IGJvYXJkX3R5cGUpCnsKCXZvbGF0aWxlIGltbWFwX3QgKmltbWFwID0gKGltbWFwX3QgKikgQ09ORklHX1NZU19JTU1SOwoJdm9sYXRpbGUgbWVtY3RsOHh4X3QgKm1lbWN0bCA9ICZpbW1hcC0+aW1fbWVtY3RsOwoJbG9uZyBpbnQgc2l6ZTEwOwoKCXVwbWNvbmZpZyAoVVBNQSwgKHVpbnQgKikgc2RyYW1fdGFibGUsCgkJCSAgIHNpemVvZiAoc2RyYW1fdGFibGUpIC8gc2l6ZW9mICh1aW50KSk7CgoJLyogUmVmcmVzaCBjbG9jayBwcmVzY2FsYXIgKi8KCW1lbWN0bC0+bWVtY19tcHRwciA9IENPTkZJR19TWVNfTVBUUFI7CgoJbWVtY3RsLT5tZW1jX21hciA9IDB4MDAwMDAwMDA7CgoJLyogTWFwIGNvbnRyb2xsZXIgYmFua3MgMSB0byB0aGUgU0RSQU0gYmFuayAqLwoJbWVtY3RsLT5tZW1jX29yMSA9IENPTkZJR19TWVNfT1IxX1BSRUxJTTsKCW1lbWN0bC0+bWVtY19icjEgPSBDT05GSUdfU1lTX0JSMV9QUkVMSU07CgoJbWVtY3RsLT5tZW1jX21hbXIgPSBDT05GSUdfU1lTX01BTVJfMTBDT0wgJiAofihNQU1SX1BUQUUpKTsJLyogbm8gcmVmcmVzaCB5ZXQgKi8KCgl1ZGVsYXkgKDIwMCk7CgoJLyogcGVyZm9ybSBTRFJBTSBpbml0aWFsaXpzYXRpb24gc2VxdWVuY2UgKi8KCgltZW1jdGwtPm1lbWNfbWNyID0gMHg4MDAwMjIzMDsJLyogU0RSQU0gYmFuayAwIC0gcmVmcmVzaCB0d2ljZSAqLwoJdWRlbGF5ICgxKTsKCgltZW1jdGwtPm1lbWNfbWFtciB8PSBNQU1SX1BUQUU7IC8qIGVuYWJsZSByZWZyZXNoICovCgoJdWRlbGF5ICgxMDAwKTsKCgkvKiBDaGVjayBCYW5rIDAgTWVtb3J5IFNpemUKCSAqIHRyeSAxMCBjb2x1bW4gbW9kZQoJICovCgoJc2l6ZTEwID0gZHJhbV9zaXplIChDT05GSUdfU1lTX01BTVJfMTBDT0wsIFNEUkFNX0JBU0VfUFJFTElNLAoJCQkJCQlTRFJBTV9NQVhfU0laRSk7CgoJcmV0dXJuIChzaXplMTApOwp9CgovKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovCgovKgogKiBDaGVjayBtZW1vcnkgcmFuZ2UgZm9yIHZhbGlkIFJBTS4gQSBzaW1wbGUgbWVtb3J5IHRlc3QgZGV0ZXJtaW5lcwogKiB0aGUgYWN0dWFsbHkgYXZhaWxhYmxlIFJBTSBzaXplIGJldHdlZW4gYWRkcmVzc2VzIGBiYXNlJyBhbmQKICogYGJhc2UgKyBtYXhzaXplJy4gU29tZSAobm90IGFsbCkgaGFyZHdhcmUgZXJyb3JzIGFyZSBkZXRlY3RlZDoKICogLSBzaG9ydCBiZXR3ZWVuIGFkZHJlc3MgbGluZXMKICogLSBzaG9ydCBiZXR3ZWVuIGRhdGEgbGluZXMKICovCgpzdGF0aWMgbG9uZyBpbnQgZHJhbV9zaXplIChsb25nIGludCBtYW1yX3ZhbHVlLCBsb25nIGludCAqYmFzZSwgbG9uZyBpbnQgbWF4c2l6ZSkKewoJdm9sYXRpbGUgaW1tYXBfdCAqaW1tYXAgPSAoaW1tYXBfdCAqKSBDT05GSUdfU1lTX0lNTVI7Cgl2b2xhdGlsZSBtZW1jdGw4eHhfdCAqbWVtY3RsID0gJmltbWFwLT5pbV9tZW1jdGw7CgoJbWVtY3RsLT5tZW1jX21hbXIgPSBtYW1yX3ZhbHVlOwoKCXJldHVybiAoZ2V0X3JhbV9zaXplKGJhc2UsIG1heHNpemUpKTsKfQovKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAqIGFzY2hleF90b19ieXRlIC0tCiAqLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICovCnN0YXRpYyB1bnNpZ25lZCBjaGFyIGFzY2hleF90b19ieXRlICh1bnNpZ25lZCBjaGFyICpjcCkKewoJdV9jaGFyIGJ5dGUsIGM7CgoJYyA9ICpjcCsrOwoKCWlmICgoYyA+PSAnQScpICYmIChjIDw9ICdGJykpIHsKCQljIC09ICdBJzsKCQljICs9IDEwOwoJfSBlbHNlIGlmICgoYyA+PSAnYScpICYmIChjIDw9ICdmJykpIHsKCQljIC09ICdhJzsKCQljICs9IDEwOwoJfSBlbHNlIHsKCQljIC09ICcwJzsKCX0KCglieXRlID0gYyAqIDE2OwoKCWMgPSAqY3A7CgoJaWYgKChjID49ICdBJykgJiYgKGMgPD0gJ0YnKSkgewoJCWMgLT0gJ0EnOwoJCWMgKz0gMTA7Cgl9IGVsc2UgaWYgKChjID49ICdhJykgJiYgKGMgPD0gJ2YnKSkgewoJCWMgLT0gJ2EnOwoJCWMgKz0gMTA7Cgl9IGVsc2UgewoJCWMgLT0gJzAnOwoJfQoKCWJ5dGUgKz0gYzsKCglyZXR1cm4gKGJ5dGUpOwp9Cg==