LyoKICogKEMpIENvcHlyaWdodCAyMDAyCiAqIERhbmllbCBFbmdzdHL2bSwgT21pY3JvbiBDZXRpIEFCLCBkYW5pZWxAb21pY3Jvbi5zZQogKgogKiBTZWUgZmlsZSBDUkVESVRTIGZvciBsaXN0IG9mIHBlb3BsZSB3aG8gY29udHJpYnV0ZWQgdG8gdGhpcwogKiBwcm9qZWN0LgogKgogKiBUaGlzIHByb2dyYW0gaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yCiAqIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGFzCiAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXIgdmVyc2lvbiAyIG9mCiAqIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLgogKgogKiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwKICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YKICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZQogKiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQogKiBhbG9uZyB3aXRoIHRoaXMgcHJvZ3JhbTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZQogKiBGb3VuZGF0aW9uLCBJbmMuLCA1OSBUZW1wbGUgUGxhY2UsIFN1aXRlIDMzMCwgQm9zdG9uLAogKiBNQSAwMjExMS0xMzA3IFVTQQogKi8KCi8qCiAqIExpbnV4IGkzODYgekltYWdlIGFuZCBiekltYWdlIGxvYWRpbmcKICoKICogYmFzZWQgb24gdGhlIHByb2NkdXJlIGRlc2NyaWJlZCBpbgogKiBsaW51eC9Eb2N1bWVudGF0aW9uL2kzODYvYm9vdC50eHQKICovCgojaW5jbHVkZSA8Y29tbW9uLmg+CiNpbmNsdWRlIDxhc20vaW8uaD4KI2luY2x1ZGUgPGFzbS9wdHJhY2UuaD4KI2luY2x1ZGUgPGFzbS96aW1hZ2UuaD4KI2luY2x1ZGUgPGFzbS9yZWFsbW9kZS5oPgojaW5jbHVkZSA8YXNtL2J5dGVvcmRlci5oPgoKLyoKICogTWVtb3J5IGxheS1vdXQ6CiAqCiAqIHJlbGF0aXZlIHRvIHNldHVwX2Jhc2UgKHdoaWNoIGlzIDB4OTAwMDAgY3VycmVudGx5KQogKgogKgkweDAwMDAtMHg3RkZGCVJlYWwgbW9kZSBrZXJuZWwKICoJMHg4MDAwLTB4OEZGRglTdGFjayBhbmQgaGVhcAogKgkweDkwMDAtMHg5MEZGCUtlcm5lbCBjb21tYW5kIGxpbmUKICovCiNkZWZpbmUgREVGQVVMVF9TRVRVUF9CQVNFICAweDkwMDAwCiNkZWZpbmUgQ09NTUFORF9MSU5FX09GRlNFVCAweDkwMDAKI2RlZmluZSBIRUFQX0VORF9PRkZTRVQgICAgIDB4OGUwMAoKI2RlZmluZSBDT01NQU5EX0xJTkVfU0laRSAgIDIwNDgKCnN0YXRpYyB2b2lkIGJ1aWxkX2NvbW1hbmRfbGluZShjaGFyICpjb21tYW5kX2xpbmUsIGludCBhdXRvX2Jvb3QpCnsKCWNoYXIgKmVudl9jb21tYW5kX2xpbmU7CgoJY29tbWFuZF9saW5lWzBdID0gJ1wwJzsKCgllbnZfY29tbWFuZF9saW5lID0gIGdldGVudigiYm9vdGFyZ3MiKTsKCgkvKiBzZXQgY29uc29sZT0gYXJndW1lbnQgaWYgd2UgdXNlIGEgc2VyaWFsIGNvbnNvbGUgKi8KCWlmIChOVUxMID09IHN0cnN0cihlbnZfY29tbWFuZF9saW5lLCAiY29uc29sZT0iKSkgewoJCWlmICgwPT1zdHJjbXAoZ2V0ZW52KCJzdGRvdXQiKSwgInNlcmlhbCIpKSB7CgoJCQkvKiBXZSBzZWVtIHRvIHVzZSBzZXJpYWwgY29uc29sZSAqLwoJCQlzcHJpbnRmKGNvbW1hbmRfbGluZSwgImNvbnNvbGU9dHR5UzAsJXMgIiwKCQkJCSBnZXRlbnYoImJhdWRyYXRlIikpOwoJCX0KCX0KCglpZiAoYXV0b19ib290KSB7CgkJc3RyY2F0KGNvbW1hbmRfbGluZSwgImF1dG8gIik7Cgl9CgoJaWYgKE5VTEwgIT0gZW52X2NvbW1hbmRfbGluZSkgewoJCXN0cmNhdChjb21tYW5kX2xpbmUsIGVudl9jb21tYW5kX2xpbmUpOwoJfQoKCglwcmludGYoIktlcm5lbCBjb21tYW5kIGxpbmU6IFwiJXNcIlxuIiwgY29tbWFuZF9saW5lKTsKfQoKdm9pZCAqbG9hZF96aW1hZ2UoY2hhciAqaW1hZ2UsIHVuc2lnbmVkIGxvbmcga2VybmVsX3NpemUsCgkJICB1bnNpZ25lZCBsb25nIGluaXRyZF9hZGRyLCB1bnNpZ25lZCBsb25nIGluaXRyZF9zaXplLAoJCSAgaW50IGF1dG9fYm9vdCkKewoJdm9pZCAqc2V0dXBfYmFzZTsKCWludCBzZXR1cF9zaXplOwoJaW50IGJvb3Rwcm90bzsKCWludCBiaWdfaW1hZ2U7Cgl2b2lkICpsb2FkX2FkZHJlc3M7CgoKCXNldHVwX2Jhc2UgPSAodm9pZCopREVGQVVMVF9TRVRVUF9CQVNFOwkvKiBiYXNlIGFkZHJlc3MgZm9yIHJlYWwtbW9kZSBzZWdtZW50ICovCgoJaWYgKEtFUk5FTF9NQUdJQyAhPSAqKHUxNiopKGltYWdlICsgQk9PVF9GTEFHX09GRikpIHsKCQlwcmludGYoIkVycm9yOiBJbnZhbGlkIGtlcm5lbCBtYWdpYyAoZm91bmQgMHglMDR4LCBleHBlY3RlZCAweGFhNTUpXG4iLAoJCSAgICAgICAqKHUxNiopKGltYWdlICsgQk9PVF9GTEFHX09GRikpOwoJCXJldHVybiAwOwoJfQoKCgkvKiBkZXRlcm1pbmUgYm9vdCBwcm90b2NvbCB2ZXJzaW9uICovCglpZiAoS0VSTkVMX1YyX01BR0lDID09ICoodTMyKikoaW1hZ2UrSEVBREVSX09GRikpIHsKCQlib290cHJvdG8gPSAqKHUxNiopKGltYWdlK1ZFUlNJT05fT0ZGKTsKCX0gZWxzZSB7CgkJLyogVmVyeSBvbGQga2VybmVsICovCgkJYm9vdHByb3RvID0gMHgwMTAwOwoJfQoKCS8qIGRldGVybWluZSBzaXplIG9mIHNldHVwICovCglpZiAoMCA9PSAqKHU4KikoaW1hZ2UgKyBTRVRVUF9TRUNUU19PRkYpKSB7CgkJc2V0dXBfc2l6ZSA9IDUgKiA1MTI7Cgl9IGVsc2UgewoJCXNldHVwX3NpemUgPSAoKih1OCopKGltYWdlICsgU0VUVVBfU0VDVFNfT0ZGKSArIDEpICogNTEyOwoJfQoKCWlmIChzZXR1cF9zaXplID4gU0VUVVBfTUFYX1NJWkUpIHsKCQlwcmludGYoIkVycm9yOiBTZXR1cCBpcyB0b28gbGFyZ2UgKCVkIGJ5dGVzKVxuIiwgc2V0dXBfc2l6ZSk7Cgl9CgoJLyogRGV0ZXJtaW5lIGltYWdlIHR5cGUgKi8KCWJpZ19pbWFnZSA9IChib290cHJvdG8gPj0gMHgwMjAwKSAmJiAoKih1OCopKGltYWdlICsgTE9BREZMQUdTX09GRikgJiBCSUdfS0VSTkVMX0ZMQUcpOwoKCS8qIERlcmVybWluZSBsb2FkIGFkZHJlc3MgKi8KCWxvYWRfYWRkcmVzcyA9ICh2b2lkKikoYmlnX2ltYWdlID8gQlpJTUFHRV9MT0FEX0FERFI6WklNQUdFX0xPQURfQUREUik7CgoJLyogbG9hZCBzZXR1cCAqLwoJbWVtbW92ZShzZXR1cF9iYXNlLCBpbWFnZSwgc2V0dXBfc2l6ZSk7CgoJcHJpbnRmKCJVc2luZyBib290IHByb3RvY29sIHZlcnNpb24gJXguJTAyeFxuIiwKCSAgICAgICAoYm9vdHByb3RvICYgMHhmZjAwKSA+PiA4LCBib290cHJvdG8gJiAweGZmKTsKCgoJaWYgKGJvb3Rwcm90byA9PSAweDAxMDApIHsKCgkJKih1MTYqKShzZXR1cF9iYXNlICsgQ01EX0xJTkVfTUFHSUNfT0ZGKSA9IENPTU1BTkRfTElORV9NQUdJQzsKCQkqKHUxNiopKHNldHVwX2Jhc2UgKyBDTURfTElORV9PRkZTRVRfT0ZGKSA9IENPTU1BTkRfTElORV9PRkZTRVQ7CgoJCS8qIEEgdmVyeSBvbGQga2VybmVsIE1VU1QgaGF2ZSBpdHMgcmVhbC1tb2RlIGNvZGUKCQkgKiBsb2FkZWQgYXQgMHg5MDAwMCAqLwoKCQlpZiAoKHUzMilzZXR1cF9iYXNlICE9IDB4OTAwMDApIHsKCQkJLyogQ29weSB0aGUgcmVhbC1tb2RlIGtlcm5lbCAqLwoJCQltZW1tb3ZlKCh2b2lkKikweDkwMDAwLCBzZXR1cF9iYXNlLCBzZXR1cF9zaXplKTsKCQkJLyogQ29weSB0aGUgY29tbWFuZCBsaW5lICovCgkJCW1lbW1vdmUoKHZvaWQqKTB4OTkwMDAsIHNldHVwX2Jhc2UrQ09NTUFORF9MSU5FX09GRlNFVCwKCQkJICAgICAgIENPTU1BTkRfTElORV9TSVpFKTsKCgkJCXNldHVwX2Jhc2UgPSAodm9pZCopMHg5MDAwMDsJCSAvKiBSZWxvY2F0ZWQgKi8KCQl9CgoJCS8qIEl0IGlzIHJlY29tbWVuZGVkIHRvIGNsZWFyIG1lbW9yeSB1cCB0byB0aGUgMzJLIG1hcmsgKi8KCQltZW1zZXQoKHZvaWQqKTB4OTAwMDAgKyBzZXR1cF9zaXplLCAwLCBTRVRVUF9NQVhfU0laRS1zZXR1cF9zaXplKTsKCX0KCglpZiAoYm9vdHByb3RvID49IDB4MDIwMCkgewoJCSoodTgqKShzZXR1cF9iYXNlICsgVFlQRV9PRl9MT0FERVJfT0ZGKSA9IDB4ZmY7CgkJcHJpbnRmKCJMaW51eCBrZXJuZWwgdmVyc2lvbiAlc1xuIiwKCQkgICAgICAgKGNoYXIqKShzZXR1cF9iYXNlICsgU0VUVVBfU1RBUlRfT0ZGU0VUICsKCQkJICAgICAgICoodTE2Kikoc2V0dXBfYmFzZSArIFNUQVJUX1NZU19PRkYgKyAyKSkpOwoKCQlpZiAoaW5pdHJkX2FkZHIpIHsKCQkJcHJpbnRmKCJJbml0aWFsIFJBTSBkaXNrIGF0IGxpbmVhciBhZGRyZXNzIDB4JTA4bHgsIHNpemUgJWxkIGJ5dGVzXG4iLAoJCQkgICAgICAgaW5pdHJkX2FkZHIsIGluaXRyZF9zaXplKTsKCgkJCSoodTMyKikoc2V0dXBfYmFzZSArIFJBTURJU0tfSU1BR0VfT0ZGKSA9IGluaXRyZF9hZGRyOwoJCQkqKHUzMiopKHNldHVwX2Jhc2UgKyBSQU1ESVNLX1NJWkVfT0ZGKT1pbml0cmRfc2l6ZTsKCQl9Cgl9CgoJaWYgKGJvb3Rwcm90byA+PSAweDAyMDEpIHsKCQkqKHUxNiopKHNldHVwX2Jhc2UgKyBIRUFQX0VORF9QVFJfT0ZGKSA9IEhFQVBfRU5EX09GRlNFVDsKCgkJLyogQ0FOX1VTRV9IRUFQICovCgkJKih1OCopKHNldHVwX2Jhc2UgKyBMT0FERkxBR1NfT0ZGKSA9CgkJCSoodTgqKShzZXR1cF9iYXNlICsgTE9BREZMQUdTX09GRikgfCBIRUFQX0ZMQUc7Cgl9CgoJaWYgKGJvb3Rwcm90byA+PSAweDAyMDIpIHsKCQkqKHUzMiopKHNldHVwX2Jhc2UgKyBDTURfTElORV9QVFJfT0ZGKSA9ICh1MzIpc2V0dXBfYmFzZSArIENPTU1BTkRfTElORV9PRkZTRVQ7Cgl9IGVsc2UgaWYgKGJvb3Rwcm90byA+PSAweDAyMDApIHsKCQkqKHUxNiopKHNldHVwX2Jhc2UgKyBDTURfTElORV9NQUdJQ19PRkYpID0gQ09NTUFORF9MSU5FX01BR0lDOwoJCSoodTE2Kikoc2V0dXBfYmFzZSArIENNRF9MSU5FX09GRlNFVF9PRkYpID0gQ09NTUFORF9MSU5FX09GRlNFVDsKCQkqKHUxNiopKHNldHVwX2Jhc2UgKyBTRVRVUF9NT1ZFX1NJWkVfT0ZGKSA9IDB4OTEwMDsKCX0KCgoJaWYgKGJpZ19pbWFnZSkgewoJCWlmICgoa2VybmVsX3NpemUgLSBzZXR1cF9zaXplKSA+IEJaSU1BR0VfTUFYX1NJWkUpIHsKCQkJcHJpbnRmKCJFcnJvcjogYnpJbWFnZSBrZXJuZWwgdG9vIGJpZyEgKHNpemU6ICVsZCwgbWF4OiAlZClcbiIsCgkJCSAgICAgICBrZXJuZWxfc2l6ZSAtIHNldHVwX3NpemUsIEJaSU1BR0VfTUFYX1NJWkUpOwoJCQlyZXR1cm4gMDsKCQl9CgoJfSBlbHNlIGlmICgoa2VybmVsX3NpemUgLSBzZXR1cF9zaXplKSA+IFpJTUFHRV9NQVhfU0laRSkgewoJCXByaW50ZigiRXJyb3I6IHpJbWFnZSBrZXJuZWwgdG9vIGJpZyEgKHNpemU6ICVsZCwgbWF4OiAlZClcbiIsCgkJICAgICAgIGtlcm5lbF9zaXplIC0gc2V0dXBfc2l6ZSwgWklNQUdFX01BWF9TSVpFKTsKCQlyZXR1cm4gMDsKCX0KCgkvKiBidWlsZCBjb21tYW5kIGxpbmUgYXQgQ09NTUFORF9MSU5FX09GRlNFVCAqLwoJYnVpbGRfY29tbWFuZF9saW5lKHNldHVwX2Jhc2UgKyBDT01NQU5EX0xJTkVfT0ZGU0VULCBhdXRvX2Jvb3QpOwoKCXByaW50ZigiTG9hZGluZyAlY3pJbWFnZSBhdCBhZGRyZXNzIDB4JTA4eCAoJWxkIGJ5dGVzKVxuIiwgYmlnX2ltYWdlID8gJ2InIDogJyAnLAoJICAgICAgICh1MzIpbG9hZF9hZGRyZXNzLCBrZXJuZWxfc2l6ZSAtIHNldHVwX3NpemUpOwoKCgltZW1tb3ZlKGxvYWRfYWRkcmVzcywgaW1hZ2UgKyBzZXR1cF9zaXplLCBrZXJuZWxfc2l6ZSAtIHNldHVwX3NpemUpOwoKCS8qIHJlYWR5IGZvciBib290aW5nICovCglyZXR1cm4gc2V0dXBfYmFzZTsKfQoKCnZvaWQgYm9vdF96aW1hZ2Uodm9pZCAqc2V0dXBfYmFzZSkKewoJc3RydWN0IHB0X3JlZ3MgcmVnczsKCgltZW1zZXQoJnJlZ3MsIDAsIHNpemVvZihzdHJ1Y3QgcHRfcmVncykpOwoJcmVncy54ZHMgPSAodTMyKXNldHVwX2Jhc2UgPj4gNDsKCXJlZ3MueHNzID0gMHg5MDAwOwoJcmVncy5lc3AgPSAweDkwMDA7CglyZWdzLmVmbGFncyA9IDA7CgllbnRlcl9yZWFsbW9kZSgoKHUzMilzZXR1cF9iYXNlK1NFVFVQX1NUQVJUX09GRlNFVCk+PjQsIDAsICZyZWdzLCAmcmVncyk7Cn0KCgppbWFnZV9oZWFkZXJfdCAqZmFrZV96aW1hZ2VfaGVhZGVyKGltYWdlX2hlYWRlcl90ICpoZHIsIHZvaWQgKnB0ciwgaW50IHNpemUpCnsKCS8qIFRoZXJlIGlzIG5vIHdheSB0byBrbm93IHRoZSBzaXplIG9mIGEgekltYWdlIC4uLiAqCgkgKiBzbyB3ZSBhc3N1bWUgdGhhdCAyTUIgd2lsbCBiZSBlbm91Z2ggZm9yIG5vdyAqLwojZGVmaW5lIFpJTUFHRV9TSVpFIDB4MjAwMDAwCgoJLyogbG9hZCBhIDFNQiwgdGhlIGxvYWRlZCB3aWxsIGhhdmUgdG8gYmUgbW92ZWQgdG8gaXRzIGZpbmFsCgkgKiBwb3NpdGlvbiBhZ2FpbiBsYXRlci4uLiAqLwojZGVmaW5lIFpJTUFHRV9MT0FEIDB4MTAwMDAwCgoJdWxvbmcgY2hlY2tzdW07CgoJaWYgKEtFUk5FTF9NQUdJQyAhPSAqKHUxNiopKHB0ciArIEJPT1RfRkxBR19PRkYpKSB7CgkJLyogbm90IGEgekltYWdlIG9yIGJ6SW1hZ2UgKi8KCQlyZXR1cm4gTlVMTDsKCX0KCglpZiAoLTEgPT0gc2l6ZSkgewoJCXNpemUgPSBaSU1BR0VfU0laRTsKCX0KI2lmIDAKCWNoZWNrc3VtID0gY3JjMzIgKDAsIHB0ciwgc2l6ZSk7CiNlbHNlCgljaGVja3N1bSA9IDA7CiNlbmRpZgoJbWVtc2V0KGhkciwgMCwgc2l6ZW9mKGltYWdlX2hlYWRlcl90KSk7CgoJLyogQnVpbGQgbmV3IGhlYWRlciAqLwoJaGRyLT5paF9tYWdpYyA9IGh0b25sKElIX01BR0lDKTsKCWhkci0+aWhfdGltZSAgPSAwOwoJaGRyLT5paF9zaXplICA9IGh0b25sKHNpemUpOwoJaGRyLT5paF9sb2FkICA9IGh0b25sKFpJTUFHRV9MT0FEKTsKCWhkci0+aWhfZXAgICAgPSAwOwoJaGRyLT5paF9kY3JjICA9IGh0b25sKGNoZWNrc3VtKTsKCWhkci0+aWhfb3MgICAgPSBJSF9PU19MSU5VWDsKCWhkci0+aWhfYXJjaCAgPSBJSF9DUFVfSTM4NjsKCWhkci0+aWhfdHlwZSAgPSBJSF9UWVBFX0tFUk5FTDsKCWhkci0+aWhfY29tcCAgPSBJSF9DT01QX05PTkU7CgoJc3RybmNweSgoY2hhciAqKWhkci0+aWhfbmFtZSwgIihub25lKSIsIElIX05NTEVOKTsKCgljaGVja3N1bSA9IGNyYzMyKDAsKGNvbnN0IGNoYXIgKiloZHIsc2l6ZW9mKGltYWdlX2hlYWRlcl90KSk7CgoJaGRyLT5paF9oY3JjID0gaHRvbmwoY2hlY2tzdW0pOwoKCXJldHVybiBoZHI7Cn0K