LyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgogKiBGaWxlbmFtZTogICAgICBpcmxtcC5jCiAqIFZlcnNpb246ICAgICAgIDEuMAogKiBEZXNjcmlwdGlvbjogICBJckRBIExpbmsgTWFuYWdlbWVudCBQcm90b2NvbCAoTE1QKSBsYXllcgogKiBTdGF0dXM6ICAgICAgICBTdGFibGUuCiAqIEF1dGhvcjogICAgICAgIERhZyBCcmF0dGxpIDxkYWdiQGNzLnVpdC5ubz4KICogQ3JlYXRlZCBhdDogICAgU3VuIEF1ZyAxNyAyMDo1NDozMiAxOTk3CiAqIE1vZGlmaWVkIGF0OiAgIFdlZCBKYW4gIDUgMTE6MjY6MDMgMjAwMAogKiBNb2RpZmllZCBieTogICBEYWcgQnJhdHRsaSA8ZGFnYkBjcy51aXQubm8+CiAqCiAqICAgICBDb3B5cmlnaHQgKGMpIDE5OTgtMjAwMCBEYWcgQnJhdHRsaSA8ZGFnYkBjcy51aXQubm8+LAogKiAgICAgQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogICAgIENvcHlyaWdodCAoYykgMjAwMC0yMDAzIEplYW4gVG91cnJpbGhlcyA8anRAaHBsLmhwLmNvbT4KICoKICogICAgIFRoaXMgcHJvZ3JhbSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IKICogICAgIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGFzCiAqICAgICBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyIHZlcnNpb24gMiBvZgogKiAgICAgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uCiAqCiAqICAgICBOZWl0aGVyIERhZyBCcmF0dGxpIG5vciBVbml2ZXJzaXR5IG9mIFRyb21z+CBhZG1pdCBsaWFiaWxpdHkgbm9yCiAqICAgICBwcm92aWRlIHdhcnJhbnR5IGZvciBhbnkgb2YgdGhpcyBzb2Z0d2FyZS4gVGhpcyBtYXRlcmlhbCBpcwogKiAgICAgcHJvdmlkZWQgIkFTLUlTIiBhbmQgYXQgbm8gY2hhcmdlLgogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgojaW5jbHVkZSA8bGludXgvY29uZmlnLmg+CiNpbmNsdWRlIDxsaW51eC9tb2R1bGUuaD4KI2luY2x1ZGUgPGxpbnV4L3NsYWIuaD4KI2luY2x1ZGUgPGxpbnV4L3N0cmluZy5oPgojaW5jbHVkZSA8bGludXgvc2tidWZmLmg+CiNpbmNsdWRlIDxsaW51eC90eXBlcy5oPgojaW5jbHVkZSA8bGludXgvcHJvY19mcy5oPgojaW5jbHVkZSA8bGludXgvaW5pdC5oPgojaW5jbHVkZSA8bGludXgva21vZC5oPgojaW5jbHVkZSA8bGludXgvcmFuZG9tLmg+CiNpbmNsdWRlIDxsaW51eC9zZXFfZmlsZS5oPgoKI2luY2x1ZGUgPG5ldC9pcmRhL2lyZGEuaD4KI2luY2x1ZGUgPG5ldC9pcmRhL3RpbWVyLmg+CiNpbmNsdWRlIDxuZXQvaXJkYS9xb3MuaD4KI2luY2x1ZGUgPG5ldC9pcmRhL2lybGFwLmg+CiNpbmNsdWRlIDxuZXQvaXJkYS9pcmlhcC5oPgojaW5jbHVkZSA8bmV0L2lyZGEvaXJsbXAuaD4KI2luY2x1ZGUgPG5ldC9pcmRhL2lybG1wX2ZyYW1lLmg+CgpzdGF0aWMgX191OCBpcmxtcF9maW5kX2ZyZWVfc2xzYXAodm9pZCk7CnN0YXRpYyBpbnQgaXJsbXBfc2xzYXBfaW51c2UoX191OCBzbHNhcF9zZWwpOwoKLyogTWFzdGVyIHN0cnVjdHVyZSAqLwpzdHJ1Y3QgaXJsbXBfY2IgKmlybG1wID0gTlVMTDsKCi8qIFRoZXNlIGNhbiBiZSBhbHRlcmVkIGJ5IHRoZSBzeXNjdGwgaW50ZXJmYWNlICovCmludCAgc3lzY3RsX2Rpc2NvdmVyeSAgICAgICAgID0gMDsKaW50ICBzeXNjdGxfZGlzY292ZXJ5X3RpbWVvdXQgPSAzOyAvKiAzIHNlY29uZHMgYnkgZGVmYXVsdCAqLwppbnQgIHN5c2N0bF9kaXNjb3Zlcnlfc2xvdHMgICA9IDY7IC8qIDYgc2xvdHMgYnkgZGVmYXVsdCAqLwppbnQgIHN5c2N0bF9sYXBfa2VlcGFsaXZlX3RpbWUgPSBMTV9JRExFX1RJTUVPVVQgKiAxMDAwIC8gSFo7CmNoYXIgc3lzY3RsX2Rldm5hbWVbNjVdOwoKY29uc3QgY2hhciAqaXJsbXBfcmVhc29uc1tdID0gewoJIkVSUk9SLCBOT1QgVVNFRCIsCgkiTE1fVVNFUl9SRVFVRVNUIiwKCSJMTV9MQVBfRElTQ09OTkVDVCIsCgkiTE1fQ09OTkVDVF9GQUlMVVJFIiwKCSJMTV9MQVBfUkVTRVQiLAoJIkxNX0lOSVRfRElTQ09OTkVDVCIsCgkiRVJST1IsIE5PVCBVU0VEIiwKfTsKCi8qCiAqIEZ1bmN0aW9uIGlybG1wX2luaXQgKHZvaWQpCiAqCiAqICAgIENyZWF0ZSAoYWxsb2NhdGUpIHRoZSBtYWluIElyTE1QIHN0cnVjdHVyZQogKgogKi8KaW50IF9faW5pdCBpcmxtcF9pbml0KHZvaWQpCnsKCUlSREFfREVCVUcoMSwgIiVzKClcbiIsIF9fRlVOQ1RJT05fXyk7CgkvKiBJbml0aWFsaXplIHRoZSBpcmxtcCBzdHJ1Y3R1cmUuICovCglpcmxtcCA9IGttYWxsb2MoIHNpemVvZihzdHJ1Y3QgaXJsbXBfY2IpLCBHRlBfS0VSTkVMKTsKCWlmIChpcmxtcCA9PSBOVUxMKQoJCXJldHVybiAtRU5PTUVNOwoJbWVtc2V0KGlybG1wLCAwLCBzaXplb2Yoc3RydWN0IGlybG1wX2NiKSk7CgoJaXJsbXAtPm1hZ2ljID0gTE1QX01BR0lDOwoKCWlybG1wLT5jbGllbnRzID0gaGFzaGJpbl9uZXcoSEJfTE9DSyk7CglpcmxtcC0+c2VydmljZXMgPSBoYXNoYmluX25ldyhIQl9MT0NLKTsKCWlybG1wLT5saW5rcyA9IGhhc2hiaW5fbmV3KEhCX0xPQ0spOwoJaXJsbXAtPnVuY29ubmVjdGVkX2xzYXBzID0gaGFzaGJpbl9uZXcoSEJfTE9DSyk7CglpcmxtcC0+Y2FjaGVsb2cgPSBoYXNoYmluX25ldyhIQl9OT0xPQ0spOwoKCWlmICgoaXJsbXAtPmNsaWVudHMgPT0gTlVMTCkgfHwKCSAgICAoaXJsbXAtPnNlcnZpY2VzID09IE5VTEwpIHx8CgkgICAgKGlybG1wLT5saW5rcyA9PSBOVUxMKSB8fAoJICAgIChpcmxtcC0+dW5jb25uZWN0ZWRfbHNhcHMgPT0gTlVMTCkgfHwKCSAgICAoaXJsbXAtPmNhY2hlbG9nID09IE5VTEwpKSB7CgkJcmV0dXJuIC1FTk9NRU07Cgl9CgoJc3Bpbl9sb2NrX2luaXQoJmlybG1wLT5jYWNoZWxvZy0+aGJfc3BpbmxvY2spOwoKCWlybG1wLT5sYXN0X2xzYXBfc2VsID0gMHgwZjsgLyogUmVzZXJ2ZWQgMHgwMC0weDBmICovCglzdHJjcHkoc3lzY3RsX2Rldm5hbWUsICJMaW51eCIpOwoKCS8qIERvIGRpc2NvdmVyeSBldmVyeSAzIHNlY29uZHMgKi8KCWluaXRfdGltZXIoJmlybG1wLT5kaXNjb3ZlcnlfdGltZXIpOwoJaXJsbXBfc3RhcnRfZGlzY292ZXJ5X3RpbWVyKGlybG1wLCBzeXNjdGxfZGlzY292ZXJ5X3RpbWVvdXQqSFopOwoKCXJldHVybiAwOwp9CgovKgogKiBGdW5jdGlvbiBpcmxtcF9jbGVhbnVwICh2b2lkKQogKgogKiAgICBSZW1vdmUgSXJMTVAgbGF5ZXIKICoKICovCnZvaWQgX19leGl0IGlybG1wX2NsZWFudXAodm9pZCkgCnsKCS8qIENoZWNrIGZvciBtYWluIHN0cnVjdHVyZSAqLwoJSVJEQV9BU1NFUlQoaXJsbXAgIT0gTlVMTCwgcmV0dXJuOyk7CglJUkRBX0FTU0VSVChpcmxtcC0+bWFnaWMgPT0gTE1QX01BR0lDLCByZXR1cm47KTsKCglkZWxfdGltZXIoJmlybG1wLT5kaXNjb3ZlcnlfdGltZXIpOwoKCWhhc2hiaW5fZGVsZXRlKGlybG1wLT5saW5rcywgKEZSRUVfRlVOQykga2ZyZWUpOwoJaGFzaGJpbl9kZWxldGUoaXJsbXAtPnVuY29ubmVjdGVkX2xzYXBzLCAoRlJFRV9GVU5DKSBrZnJlZSk7CgloYXNoYmluX2RlbGV0ZShpcmxtcC0+Y2xpZW50cywgKEZSRUVfRlVOQykga2ZyZWUpOwoJaGFzaGJpbl9kZWxldGUoaXJsbXAtPnNlcnZpY2VzLCAoRlJFRV9GVU5DKSBrZnJlZSk7CgloYXNoYmluX2RlbGV0ZShpcmxtcC0+Y2FjaGVsb2csIChGUkVFX0ZVTkMpIGtmcmVlKTsKCgkvKiBEZS1hbGxvY2F0ZSBtYWluIHN0cnVjdHVyZSAqLwoJa2ZyZWUoaXJsbXApOwoJaXJsbXAgPSBOVUxMOwp9CgovKgogKiBGdW5jdGlvbiBpcmxtcF9vcGVuX2xzYXAgKHNsc2FwLCBub3RpZnkpCiAqCiAqICAgUmVnaXN0ZXIgd2l0aCBJckxNUCBhbmQgY3JlYXRlIGEgbG9jYWwgTFNBUCwKICogICByZXR1cm5zIGhhbmRsZSB0byBMU0FQLgogKi8Kc3RydWN0IGxzYXBfY2IgKmlybG1wX29wZW5fbHNhcChfX3U4IHNsc2FwX3NlbCwgbm90aWZ5X3QgKm5vdGlmeSwgX191OCBwaWQpCnsKCXN0cnVjdCBsc2FwX2NiICpzZWxmOwoKCUlSREFfQVNTRVJUKG5vdGlmeSAhPSBOVUxMLCByZXR1cm4gTlVMTDspOwoJSVJEQV9BU1NFUlQoaXJsbXAgIT0gTlVMTCwgcmV0dXJuIE5VTEw7KTsKCUlSREFfQVNTRVJUKGlybG1wLT5tYWdpYyA9PSBMTVBfTUFHSUMsIHJldHVybiBOVUxMOyk7CglJUkRBX0FTU0VSVChub3RpZnktPmluc3RhbmNlICE9IE5VTEwsIHJldHVybiBOVUxMOyk7CgoJLyogIERvZXMgdGhlIGNsaWVudCBjYXJlIHdoaWNoIFNvdXJjZSBMU0FQIHNlbGVjdG9yIGl0IGdldHM/ICAqLwoJaWYgKHNsc2FwX3NlbCA9PSBMU0FQX0FOWSkgewoJCXNsc2FwX3NlbCA9IGlybG1wX2ZpbmRfZnJlZV9zbHNhcCgpOwoJCWlmICghc2xzYXBfc2VsKQoJCQlyZXR1cm4gTlVMTDsKCX0gZWxzZSBpZiAoaXJsbXBfc2xzYXBfaW51c2Uoc2xzYXBfc2VsKSkKCQlyZXR1cm4gTlVMTDsKCgkvKiBBbGxvY2F0ZSBuZXcgaW5zdGFuY2Ugb2YgYSBMU0FQIGNvbm5lY3Rpb24gKi8KCXNlbGYgPSBrbWFsbG9jKHNpemVvZihzdHJ1Y3QgbHNhcF9jYiksIEdGUF9BVE9NSUMpOwoJaWYgKHNlbGYgPT0gTlVMTCkgewoJCUlSREFfRVJST1IoIiVzOiBjYW4ndCBhbGxvY2F0ZSBtZW1vcnlcbiIsIF9fRlVOQ1RJT05fXyk7CgkJcmV0dXJuIE5VTEw7Cgl9CgltZW1zZXQoc2VsZiwgMCwgc2l6ZW9mKHN0cnVjdCBsc2FwX2NiKSk7CgoJc2VsZi0+bWFnaWMgPSBMTVBfTFNBUF9NQUdJQzsKCXNlbGYtPnNsc2FwX3NlbCA9IHNsc2FwX3NlbDsKCgkvKiBGaXggY29ubmVjdGlvbmxlc3MgTFNBUCdzICovCglpZiAoc2xzYXBfc2VsID09IExTQVBfQ09OTkxFU1MpIHsKI2lmZGVmIENPTkZJR19JUkRBX1VMVFJBCgkJc2VsZi0+ZGxzYXBfc2VsID0gTFNBUF9DT05OTEVTUzsKCQlzZWxmLT5waWQgPSBwaWQ7CiNlbmRpZiAvKiBDT05GSUdfSVJEQV9VTFRSQSAqLwoJfSBlbHNlCgkJc2VsZi0+ZGxzYXBfc2VsID0gTFNBUF9BTlk7CgkvKiBzZWxmLT5jb25uZWN0ZWQgPSBGQUxTRTsgLT4gYWxyZWFkeSBOVUxMIHZpYSBtZW1zZXQoKSAqLwoKCWluaXRfdGltZXIoJnNlbGYtPndhdGNoZG9nX3RpbWVyKTsKCglzZWxmLT5ub3RpZnkgPSAqbm90aWZ5OwoKCXNlbGYtPmxzYXBfc3RhdGUgPSBMU0FQX0RJU0NPTk5FQ1RFRDsKCgkvKiBJbnNlcnQgaW50byBxdWV1ZSBvZiB1bmNvbm5lY3RlZCBMU0FQcyAqLwoJaGFzaGJpbl9pbnNlcnQoaXJsbXAtPnVuY29ubmVjdGVkX2xzYXBzLCAoaXJkYV9xdWV1ZV90ICopIHNlbGYsCgkJICAgICAgIChsb25nKSBzZWxmLCBOVUxMKTsKCglyZXR1cm4gc2VsZjsKfQpFWFBPUlRfU1lNQk9MKGlybG1wX29wZW5fbHNhcCk7CgovKgogKiBGdW5jdGlvbiBfX2lybG1wX2Nsb3NlX2xzYXAgKHNlbGYpCiAqCiAqICAgIFJlbW92ZSBhbiBpbnN0YW5jZSBvZiBMU0FQCiAqLwpzdGF0aWMgdm9pZCBfX2lybG1wX2Nsb3NlX2xzYXAoc3RydWN0IGxzYXBfY2IgKnNlbGYpCnsKCUlSREFfREVCVUcoNCwgIiVzKClcbiIsIF9fRlVOQ1RJT05fXyk7CgoJSVJEQV9BU1NFUlQoc2VsZiAhPSBOVUxMLCByZXR1cm47KTsKCUlSREFfQVNTRVJUKHNlbGYtPm1hZ2ljID09IExNUF9MU0FQX01BR0lDLCByZXR1cm47KTsKCgkvKgoJICogIFNldCBzb21lIG9mIHRoZSB2YXJpYWJsZXMgdG8gcHJlc2V0IHZhbHVlcwoJICovCglzZWxmLT5tYWdpYyA9IDA7CglkZWxfdGltZXIoJnNlbGYtPndhdGNoZG9nX3RpbWVyKTsgLyogSW1wb3J0YW50ISAqLwoKCWlmIChzZWxmLT5jb25uX3NrYikKCQlkZXZfa2ZyZWVfc2tiKHNlbGYtPmNvbm5fc2tiKTsKCglrZnJlZShzZWxmKTsKfQoKLyoKICogRnVuY3Rpb24gaXJsbXBfY2xvc2VfbHNhcCAoc2VsZikKICoKICogICAgQ2xvc2UgYW5kIHJlbW92ZSBMU0FQCiAqCiAqLwp2b2lkIGlybG1wX2Nsb3NlX2xzYXAoc3RydWN0IGxzYXBfY2IgKnNlbGYpCnsKCXN0cnVjdCBsYXBfY2IgKmxhcDsKCXN0cnVjdCBsc2FwX2NiICpsc2FwID0gTlVMTDsKCglJUkRBX0FTU0VSVChzZWxmICE9IE5VTEwsIHJldHVybjspOwoJSVJEQV9BU1NFUlQoc2VsZi0+bWFnaWMgPT0gTE1QX0xTQVBfTUFHSUMsIHJldHVybjspOwoKCS8qCgkgKiAgRmluZCBvdXQgaWYgd2Ugc2hvdWxkIHJlbW92ZSB0aGlzIExTQVAgZnJvbSBhIGxpbmsgb3IgZnJvbSB0aGUKCSAqICBsaXN0IG9mIHVuY29ubmVjdGVkIGxzYXBzIChub3QgYXNzb2NpYXRlZCB3aXRoIGEgbGluaykKCSAqLwoJbGFwID0gc2VsZi0+bGFwOwoJaWYgKGxhcCkgewoJCUlSREFfQVNTRVJUKGxhcC0+bWFnaWMgPT0gTE1QX0xBUF9NQUdJQywgcmV0dXJuOyk7CgkJLyogV2UgbWlnaHQgY2xvc2UgYSBMU0FQIGJlZm9yZSBpdCBoYXMgY29tcGxldGVkIHRoZQoJCSAqIGNvbm5lY3Rpb24gc2V0dXAuIEluIHRob3NlIGNhc2UsIGhpZ2hlciBsYXllcnMgd29uJ3QKCQkgKiBzZW5kIGEgcHJvcGVyIGRpc2Nvbm5lY3QgcmVxdWVzdC4gSGFybWxlc3MsIGV4Y2VwdAoJCSAqIHRoYXQgd2Ugd2lsbCBmb3JnZXQgdG8gY2xvc2UgTEFQLi4uIC0gSmVhbiBJSSAqLwoJCWlmKHNlbGYtPmxzYXBfc3RhdGUgIT0gTFNBUF9ESVNDT05ORUNURUQpIHsKCQkJc2VsZi0+bHNhcF9zdGF0ZSA9IExTQVBfRElTQ09OTkVDVEVEOwoJCQlpcmxtcF9kb19sYXBfZXZlbnQoc2VsZi0+bGFwLAoJCQkJCSAgIExNX0xBUF9ESVNDT05ORUNUX1JFUVVFU1QsIE5VTEwpOwoJCX0KCQkvKiBOb3csIHJlbW92ZSBmcm9tIHRoZSBsaW5rICovCgkJbHNhcCA9IGhhc2hiaW5fcmVtb3ZlKGxhcC0+bHNhcHMsIChsb25nKSBzZWxmLCBOVUxMKTsKI2lmZGVmIENPTkZJR19JUkRBX0NBQ0hFX0xBU1RfTFNBUAoJCWxhcC0+Y2FjaGUudmFsaWQgPSBGQUxTRTsKI2VuZGlmCgl9CglzZWxmLT5sYXAgPSBOVUxMOwoJLyogQ2hlY2sgaWYgd2UgZm91bmQgdGhlIExTQVAhIElmIG5vdCB0aGVuIHRyeSB0aGUgdW5jb25uZWN0ZWQgbHNhcHMgKi8KCWlmICghbHNhcCkgewoJCWxzYXAgPSBoYXNoYmluX3JlbW92ZShpcmxtcC0+dW5jb25uZWN0ZWRfbHNhcHMsIChsb25nKSBzZWxmLAoJCQkJICAgICAgTlVMTCk7Cgl9CglpZiAoIWxzYXApIHsKCQlJUkRBX0RFQlVHKDAsCgkJICAgICAiJXMoKSwgTG9va3MgbGlrZSBzb21lYm9keSBoYXMgcmVtb3ZlZCBtZSBhbHJlYWR5IVxuIiwKCQkJICAgX19GVU5DVElPTl9fKTsKCQlyZXR1cm47Cgl9CglfX2lybG1wX2Nsb3NlX2xzYXAoc2VsZik7Cn0KRVhQT1JUX1NZTUJPTChpcmxtcF9jbG9zZV9sc2FwKTsKCi8qCiAqIEZ1bmN0aW9uIGlybG1wX3JlZ2lzdGVyX2lybGFwIChzYWRkciwgbm90aWZ5KQogKgogKiAgICBSZWdpc3RlciBJckxBUCBsYXllciB3aXRoIElyTE1QLiBUaGVyZSBpcyBwb3NzaWJsZSB0byBoYXZlIG11bHRpcGxlCiAqICAgIGluc3RhbmNlcyBvZiB0aGUgSXJMQVAgbGF5ZXIsIGVhY2ggY29ubmVjdGVkIHRvIGRpZmZlcmVudCBJckRBIHBvcnRzCiAqCiAqLwp2b2lkIGlybG1wX3JlZ2lzdGVyX2xpbmsoc3RydWN0IGlybGFwX2NiICppcmxhcCwgX191MzIgc2FkZHIsIG5vdGlmeV90ICpub3RpZnkpCnsKCXN0cnVjdCBsYXBfY2IgKmxhcDsKCglJUkRBX0FTU0VSVChpcmxtcCAhPSBOVUxMLCByZXR1cm47KTsKCUlSREFfQVNTRVJUKGlybG1wLT5tYWdpYyA9PSBMTVBfTUFHSUMsIHJldHVybjspOwoJSVJEQV9BU1NFUlQobm90aWZ5ICE9IE5VTEwsIHJldHVybjspOwoKCS8qCgkgKiAgQWxsb2NhdGUgbmV3IGluc3RhbmNlIG9mIGEgTFNBUCBjb25uZWN0aW9uCgkgKi8KCWxhcCA9IGttYWxsb2Moc2l6ZW9mKHN0cnVjdCBsYXBfY2IpLCBHRlBfS0VSTkVMKTsKCWlmIChsYXAgPT0gTlVMTCkgewoJCUlSREFfRVJST1IoIiVzOiB1bmFibGUgdG8ga21hbGxvY1xuIiwgX19GVU5DVElPTl9fKTsKCQlyZXR1cm47Cgl9CgltZW1zZXQobGFwLCAwLCBzaXplb2Yoc3RydWN0IGxhcF9jYikpOwoKCWxhcC0+aXJsYXAgPSBpcmxhcDsKCWxhcC0+bWFnaWMgPSBMTVBfTEFQX01BR0lDOwoJbGFwLT5zYWRkciA9IHNhZGRyOwoJbGFwLT5kYWRkciA9IERFVl9BRERSX0FOWTsKI2lmZGVmIENPTkZJR19JUkRBX0NBQ0hFX0xBU1RfTFNBUAoJbGFwLT5jYWNoZS52YWxpZCA9IEZBTFNFOwojZW5kaWYKCWxhcC0+bHNhcHMgPSBoYXNoYmluX25ldyhIQl9MT0NLKTsKCWlmIChsYXAtPmxzYXBzID09IE5VTEwpIHsKCQlJUkRBX1dBUk5JTkcoIiVzKCksIHVuYWJsZSB0byBrbWFsbG9jIGxzYXBzXG4iLCBfX0ZVTkNUSU9OX18pOwoJCWtmcmVlKGxhcCk7CgkJcmV0dXJuOwoJfQoKCWxhcC0+bGFwX3N0YXRlID0gTEFQX1NUQU5EQlk7CgoJaW5pdF90aW1lcigmbGFwLT5pZGxlX3RpbWVyKTsKCgkvKgoJICogIEluc2VydCBpbnRvIHF1ZXVlIG9mIExNUCBsaW5rcwoJICovCgloYXNoYmluX2luc2VydChpcmxtcC0+bGlua3MsIChpcmRhX3F1ZXVlX3QgKikgbGFwLCBsYXAtPnNhZGRyLCBOVUxMKTsKCgkvKgoJICogIFdlIHNldCBvbmx5IHRoaXMgdmFyaWFibGUgc28gSXJMQVAgY2FuIHRlbGwgdXMgb24gd2hpY2ggbGluayB0aGUKCSAqICBkaWZmZXJlbnQgZXZlbnRzIGhhcHBlbmVkIG9uCgkgKi8KCWlyZGFfbm90aWZ5X2luaXQobm90aWZ5KTsKCW5vdGlmeS0+aW5zdGFuY2UgPSBsYXA7Cn0KCi8qCiAqIEZ1bmN0aW9uIGlybG1wX3VucmVnaXN0ZXJfaXJsYXAgKHNhZGRyKQogKgogKiAgICBJckxBUCBsYXllciBoYXMgYmVlbiByZW1vdmVkIQogKgogKi8Kdm9pZCBpcmxtcF91bnJlZ2lzdGVyX2xpbmsoX191MzIgc2FkZHIpCnsKCXN0cnVjdCBsYXBfY2IgKmxpbms7CgoJSVJEQV9ERUJVRyg0LCAiJXMoKVxuIiwgX19GVU5DVElPTl9fKTsKCgkvKiBXZSBtdXN0IHJlbW92ZSBvdXJzZWx2ZXMgZnJvbSB0aGUgaGFzaGJpbiAqZmlyc3QqLiBUaGlzIGVuc3VyZQoJICogdGhhdCBubyBtb3JlIExTQVBzIHdpbGwgYmUgb3BlbiBvbiB0aGlzIGxpbmsgYW5kIG5vIGRpc2NvdmVyeQoJICogd2lsbCBiZSB0cmlnZ2VyZWQgYW55bW9yZS4gSmVhbiBJSSAqLwoJbGluayA9IGhhc2hiaW5fcmVtb3ZlKGlybG1wLT5saW5rcywgc2FkZHIsIE5VTEwpOwoJaWYgKGxpbmspIHsKCQlJUkRBX0FTU0VSVChsaW5rLT5tYWdpYyA9PSBMTVBfTEFQX01BR0lDLCByZXR1cm47KTsKCgkJLyogS2lsbCBhbGwgdGhlIExTQVBzIG9uIHRoaXMgbGluay4gSmVhbiBJSSAqLwoJCWxpbmstPnJlYXNvbiA9IExBUF9ESVNDX0lORElDQVRJT047CgkJbGluay0+ZGFkZHIgPSBERVZfQUREUl9BTlk7CgkJaXJsbXBfZG9fbGFwX2V2ZW50KGxpbmssIExNX0xBUF9ESVNDT05ORUNUX0lORElDQVRJT04sIE5VTEwpOwoKCQkvKiBSZW1vdmUgYWxsIGRpc2NvdmVyaWVzIGRpc2NvdmVyZWQgYXQgdGhpcyBsaW5rICovCgkJaXJsbXBfZXhwaXJlX2Rpc2NvdmVyaWVzKGlybG1wLT5jYWNoZWxvZywgbGluay0+c2FkZHIsIFRSVUUpOwoKCQkvKiBGaW5hbCBjbGVhbnVwICovCgkJZGVsX3RpbWVyKCZsaW5rLT5pZGxlX3RpbWVyKTsKCQlsaW5rLT5tYWdpYyA9IDA7CgkJa2ZyZWUobGluayk7Cgl9Cn0KCi8qCiAqIEZ1bmN0aW9uIGlybG1wX2Nvbm5lY3RfcmVxdWVzdCAoaGFuZGxlLCBkbHNhcCwgdXNlcmRhdGEpCiAqCiAqICAgIENvbm5lY3Qgd2l0aCBhIHBlZXIgTFNBUAogKgogKi8KaW50IGlybG1wX2Nvbm5lY3RfcmVxdWVzdChzdHJ1Y3QgbHNhcF9jYiAqc2VsZiwgX191OCBkbHNhcF9zZWwsCgkJCSAgX191MzIgc2FkZHIsIF9fdTMyIGRhZGRyLAoJCQkgIHN0cnVjdCBxb3NfaW5mbyAqcW9zLCBzdHJ1Y3Qgc2tfYnVmZiAqdXNlcmRhdGEpCnsKCXN0cnVjdCBza19idWZmICp0eF9za2IgPSB1c2VyZGF0YTsKCXN0cnVjdCBsYXBfY2IgKmxhcDsKCXN0cnVjdCBsc2FwX2NiICpsc2FwOwoJaW50IHJldDsKCglJUkRBX0FTU0VSVChzZWxmICE9IE5VTEwsIHJldHVybiAtRUJBRFI7KTsKCUlSREFfQVNTRVJUKHNlbGYtPm1hZ2ljID09IExNUF9MU0FQX01BR0lDLCByZXR1cm4gLUVCQURSOyk7CgoJSVJEQV9ERUJVRygyLAoJICAgICAgIiVzKCksIHNsc2FwX3NlbD0lMDJ4LCBkbHNhcF9zZWw9JTAyeCwgc2FkZHI9JTA4eCwgZGFkZHI9JTA4eFxuIiwKCSAgICAgIF9fRlVOQ1RJT05fXywgc2VsZi0+c2xzYXBfc2VsLCBkbHNhcF9zZWwsIHNhZGRyLCBkYWRkcik7CgoJaWYgKHRlc3RfYml0KDAsICZzZWxmLT5jb25uZWN0ZWQpKSB7CgkJcmV0ID0gLUVJU0NPTk47CgkJZ290byBlcnI7Cgl9CgoJLyogQ2xpZW50IG11c3Qgc3VwcGx5IGRlc3RpbmF0aW9uIGRldmljZSBhZGRyZXNzICovCglpZiAoIWRhZGRyKSB7CgkJcmV0ID0gLUVJTlZBTDsKCQlnb3RvIGVycjsKCX0KCgkvKiBBbnkgdXNlcmRhdGE/ICovCglpZiAodHhfc2tiID09IE5VTEwpIHsKCQl0eF9za2IgPSBkZXZfYWxsb2Nfc2tiKDY0KTsKCQlpZiAoIXR4X3NrYikKCQkJcmV0dXJuIC1FTk9NRU07CgoJCXNrYl9yZXNlcnZlKHR4X3NrYiwgTE1QX01BWF9IRUFERVIpOwoJfQoKCS8qIE1ha2Ugcm9vbSBmb3IgTVVYIGNvbnRyb2wgaGVhZGVyICgzIGJ5dGVzKSAqLwoJSVJEQV9BU1NFUlQoc2tiX2hlYWRyb29tKHR4X3NrYikgPj0gTE1QX0NPTlRST0xfSEVBREVSLCByZXR1cm4gLTE7KTsKCXNrYl9wdXNoKHR4X3NrYiwgTE1QX0NPTlRST0xfSEVBREVSKTsKCglzZWxmLT5kbHNhcF9zZWwgPSBkbHNhcF9zZWw7CgoJLyoKCSAqIEZpbmQgdGhlIGxpbmsgdG8gd2hlcmUgd2Ugc2hvdWxkIHRyeSB0byBjb25uZWN0IHNpbmNlIHRoZXJlIG1heQoJICogYmUgbW9yZSB0aGFuIG9uZSBJckRBIHBvcnQgb24gdGhpcyBtYWNoaW5lLiBJZiB0aGUgY2xpZW50IGhhcwoJICogcGFzc2VkIHVzIHRoZSBzYWRkciAoYW5kIGFscmVhZHkga25vd3Mgd2hpY2ggbGluayB0byB1c2UpLCB0aGVuCgkgKiB3ZSB1c2UgdGhhdCB0byBmaW5kIHRoZSBsaW5rLCBpZiBub3QgdGhlbiB3ZSBoYXZlIHRvIGxvb2sgaW4gdGhlCgkgKiBkaXNjb3ZlcnkgbG9nIGFuZCBjaGVjayBpZiBhbnkgb2YgdGhlIGxpbmtzIGhhcyBkaXNjb3ZlcmVkIGEKCSAqIGRldmljZSB3aXRoIHRoZSBnaXZlbiBkYWRkcgoJICovCglpZiAoKCFzYWRkcikgfHwgKHNhZGRyID09IERFVl9BRERSX0FOWSkpIHsKCQlkaXNjb3ZlcnlfdCAqZGlzY292ZXJ5OwoJCXVuc2lnbmVkIGxvbmcgZmxhZ3M7CgoJCXNwaW5fbG9ja19pcnFzYXZlKCZpcmxtcC0+Y2FjaGVsb2ctPmhiX3NwaW5sb2NrLCBmbGFncyk7CgkJaWYgKGRhZGRyICE9IERFVl9BRERSX0FOWSkKCQkJZGlzY292ZXJ5ID0gaGFzaGJpbl9maW5kKGlybG1wLT5jYWNoZWxvZywgZGFkZHIsIE5VTEwpOwoJCWVsc2UgewoJCQlJUkRBX0RFQlVHKDIsICIlcygpLCBubyBkYWRkclxuIiwgX19GVU5DVElPTl9fKTsKCQkJZGlzY292ZXJ5ID0gKGRpc2NvdmVyeV90ICopCgkJCQloYXNoYmluX2dldF9maXJzdChpcmxtcC0+Y2FjaGVsb2cpOwoJCX0KCgkJaWYgKGRpc2NvdmVyeSkgewoJCQlzYWRkciA9IGRpc2NvdmVyeS0+ZGF0YS5zYWRkcjsKCQkJZGFkZHIgPSBkaXNjb3ZlcnktPmRhdGEuZGFkZHI7CgkJfQoJCXNwaW5fdW5sb2NrX2lycXJlc3RvcmUoJmlybG1wLT5jYWNoZWxvZy0+aGJfc3BpbmxvY2ssIGZsYWdzKTsKCX0KCWxhcCA9IGhhc2hiaW5fbG9ja19maW5kKGlybG1wLT5saW5rcywgc2FkZHIsIE5VTEwpOwoJaWYgKGxhcCA9PSBOVUxMKSB7CgkJSVJEQV9ERUJVRygxLCAiJXMoKSwgVW5hYmxlIHRvIGZpbmQgYSB1c2FibGUgbGluayFcbiIsIF9fRlVOQ1RJT05fXyk7CgkJcmV0ID0gLUVIT1NUVU5SRUFDSDsKCQlnb3RvIGVycjsKCX0KCgkvKiBDaGVjayBpZiBMQVAgaXMgZGlzY29ubmVjdGVkIG9yIGFscmVhZHkgY29ubmVjdGVkICovCglpZiAobGFwLT5kYWRkciA9PSBERVZfQUREUl9BTlkpCgkJbGFwLT5kYWRkciA9IGRhZGRyOwoJZWxzZSBpZiAobGFwLT5kYWRkciAhPSBkYWRkcikgewoJCS8qIENoZWNrIGlmIHNvbWUgTFNBUHMgYXJlIGFjdGl2ZSBvbiB0aGlzIExBUCAqLwoJCWlmIChIQVNIQklOX0dFVF9TSVpFKGxhcC0+bHNhcHMpID09IDApIHsKCQkJLyogTm8gYWN0aXZlIGNvbm5lY3Rpb24sIGJ1dCBMQVAgaGFzbid0IGJlZW4KCQkJICogZGlzY29ubmVjdGVkIHlldCAod2FpdGluZyBmb3IgdGltZW91dCBpbiBMQVApLgoJCQkgKiBNYXliZSB3ZSBjb3VsZCBnaXZlIExBUCBhIGJpdCBvZiBoZWxwIGluIHRoaXMgY2FzZS4KCQkJICovCgkJCUlSREFfREVCVUcoMCwgIiVzKCksIHNvcnJ5LCBidXQgSSdtIHdhaXRpbmcgZm9yIExBUCB0byB0aW1lb3V0IVxuIiwgX19GVU5DVElPTl9fKTsKCQkJcmV0ID0gLUVBR0FJTjsKCQkJZ290byBlcnI7CgkJfQoKCQkvKiBMQVAgaXMgYWxyZWFkeSBjb25uZWN0ZWQgdG8gYSBkaWZmZXJlbnQgbm9kZSwgYW5kIExBUAoJCSAqIGNhbiBvbmx5IHRhbGsgdG8gb25lIG5vZGUgYXQgYSB0aW1lICovCgkJSVJEQV9ERUJVRygwLCAiJXMoKSwgc29ycnksIGJ1dCBsaW5rIGlzIGJ1c3khXG4iLCBfX0ZVTkNUSU9OX18pOwoJCXJldCA9IC1FQlVTWTsKCQlnb3RvIGVycjsKCX0KCglzZWxmLT5sYXAgPSBsYXA7CgoJLyoKCSAqICBSZW1vdmUgTFNBUCBmcm9tIGxpc3Qgb2YgdW5jb25uZWN0ZWQgTFNBUHMgYW5kIGluc2VydCBpdCBpbnRvIHRoZQoJICogIGxpc3Qgb2YgY29ubmVjdGVkIExTQVBzIGZvciB0aGUgcGFydGljdWxhciBsaW5rCgkgKi8KCWxzYXAgPSBoYXNoYmluX3JlbW92ZShpcmxtcC0+dW5jb25uZWN0ZWRfbHNhcHMsIChsb25nKSBzZWxmLCBOVUxMKTsKCglJUkRBX0FTU0VSVChsc2FwICE9IE5VTEwsIHJldHVybiAtMTspOwoJSVJEQV9BU1NFUlQobHNhcC0+bWFnaWMgPT0gTE1QX0xTQVBfTUFHSUMsIHJldHVybiAtMTspOwoJSVJEQV9BU1NFUlQobHNhcC0+bGFwICE9IE5VTEwsIHJldHVybiAtMTspOwoJSVJEQV9BU1NFUlQobHNhcC0+bGFwLT5tYWdpYyA9PSBMTVBfTEFQX01BR0lDLCByZXR1cm4gLTE7KTsKCgloYXNoYmluX2luc2VydChzZWxmLT5sYXAtPmxzYXBzLCAoaXJkYV9xdWV1ZV90ICopIHNlbGYsIChsb25nKSBzZWxmLAoJCSAgICAgICBOVUxMKTsKCglzZXRfYml0KDAsICZzZWxmLT5jb25uZWN0ZWQpOwkvKiBUUlVFICovCgoJLyoKCSAqICBVc2VyIHN1cHBsaWVkIHFvcyBzcGVjaWZpY2F0aW9ucz8KCSAqLwoJaWYgKHFvcykKCQlzZWxmLT5xb3MgPSAqcW9zOwoKCWlybG1wX2RvX2xzYXBfZXZlbnQoc2VsZiwgTE1fQ09OTkVDVF9SRVFVRVNULCB0eF9za2IpOwoKCS8qIERyb3AgcmVmZXJlbmNlIGNvdW50IC0gc2VlIGlybGFwX2RhdGFfcmVxdWVzdCgpLiAqLwoJZGV2X2tmcmVlX3NrYih0eF9za2IpOwoKCXJldHVybiAwOwoKZXJyOgoJLyogQ2xlYW51cCAqLwoJaWYodHhfc2tiKQoJCWRldl9rZnJlZV9za2IodHhfc2tiKTsKCXJldHVybiByZXQ7Cn0KRVhQT1JUX1NZTUJPTChpcmxtcF9jb25uZWN0X3JlcXVlc3QpOwoKLyoKICogRnVuY3Rpb24gaXJsbXBfY29ubmVjdF9pbmRpY2F0aW9uIChzZWxmKQogKgogKiAgICBJbmNvbWluZyBjb25uZWN0aW9uCiAqCiAqLwp2b2lkIGlybG1wX2Nvbm5lY3RfaW5kaWNhdGlvbihzdHJ1Y3QgbHNhcF9jYiAqc2VsZiwgc3RydWN0IHNrX2J1ZmYgKnNrYikKewoJaW50IG1heF9zZWdfc2l6ZTsKCWludCBsYXBfaGVhZGVyX3NpemU7CglpbnQgbWF4X2hlYWRlcl9zaXplOwoKCUlSREFfQVNTRVJUKHNlbGYgIT0gTlVMTCwgcmV0dXJuOyk7CglJUkRBX0FTU0VSVChzZWxmLT5tYWdpYyA9PSBMTVBfTFNBUF9NQUdJQywgcmV0dXJuOyk7CglJUkRBX0FTU0VSVChza2IgIT0gTlVMTCwgcmV0dXJuOyk7CglJUkRBX0FTU0VSVChzZWxmLT5sYXAgIT0gTlVMTCwgcmV0dXJuOyk7CgoJSVJEQV9ERUJVRygyLCAiJXMoKSwgc2xzYXBfc2VsPSUwMngsIGRsc2FwX3NlbD0lMDJ4XG4iLAoJCSAgIF9fRlVOQ1RJT05fXywgc2VsZi0+c2xzYXBfc2VsLCBzZWxmLT5kbHNhcF9zZWwpOwoKCS8qIE5vdGUgOiBzZWxmLT5sYXAgaXMgc2V0IGluIGlybG1wX2xpbmtfZGF0YV9pbmRpY2F0aW9uKCksCgkgKiAoY2FzZSBDT05ORUNUX0NNRDopIGJlY2F1c2Ugd2UgaGF2ZSBubyB3YXkgdG8gc2V0IGl0IGhlcmUuCgkgKiBTaW1pbGFybHksIHNlbGYtPmRsc2FwX3NlbCBpcyB1c3VhbGx5IHNldCBpbiBpcmxtcF9maW5kX2xzYXAoKS4KCSAqIEplYW4gSUkgKi8KCglzZWxmLT5xb3MgPSAqc2VsZi0+bGFwLT5xb3M7CgoJbWF4X3NlZ19zaXplID0gc2VsZi0+bGFwLT5xb3MtPmRhdGFfc2l6ZS52YWx1ZS1MTVBfSEVBREVSOwoJbGFwX2hlYWRlcl9zaXplID0gSVJMQVBfR0VUX0hFQURFUl9TSVpFKHNlbGYtPmxhcC0+aXJsYXApOwoJbWF4X2hlYWRlcl9zaXplID0gTE1QX0hFQURFUiArIGxhcF9oZWFkZXJfc2l6ZTsKCgkvKiBIaWRlIExNUF9DT05UUk9MX0hFQURFUiBoZWFkZXIgZnJvbSBsYXllciBhYm92ZSAqLwoJc2tiX3B1bGwoc2tiLCBMTVBfQ09OVFJPTF9IRUFERVIpOwoKCWlmIChzZWxmLT5ub3RpZnkuY29ubmVjdF9pbmRpY2F0aW9uKSB7CgkJLyogRG9uJ3QgZm9yZ2V0IHRvIHJlZmNvdW50IGl0IC0gc2VlIGlybGFwX2RyaXZlcl9yY3YoKS4gKi8KCQlza2JfZ2V0KHNrYik7CgkJc2VsZi0+bm90aWZ5LmNvbm5lY3RfaW5kaWNhdGlvbihzZWxmLT5ub3RpZnkuaW5zdGFuY2UsIHNlbGYsCgkJCQkJCSZzZWxmLT5xb3MsIG1heF9zZWdfc2l6ZSwKCQkJCQkJbWF4X2hlYWRlcl9zaXplLCBza2IpOwoJfQp9CgovKgogKiBGdW5jdGlvbiBpcmxtcF9jb25uZWN0X3Jlc3BvbnNlIChoYW5kbGUsIHVzZXJkYXRhKQogKgogKiAgICBTZXJ2aWNlIHVzZXIgaXMgYWNjZXB0aW5nIGNvbm5lY3Rpb24KICoKICovCmludCBpcmxtcF9jb25uZWN0X3Jlc3BvbnNlKHN0cnVjdCBsc2FwX2NiICpzZWxmLCBzdHJ1Y3Qgc2tfYnVmZiAqdXNlcmRhdGEpCnsKCUlSREFfQVNTRVJUKHNlbGYgIT0gTlVMTCwgcmV0dXJuIC0xOyk7CglJUkRBX0FTU0VSVChzZWxmLT5tYWdpYyA9PSBMTVBfTFNBUF9NQUdJQywgcmV0dXJuIC0xOyk7CglJUkRBX0FTU0VSVCh1c2VyZGF0YSAhPSBOVUxMLCByZXR1cm4gLTE7KTsKCgkvKiBXZSBzZXQgdGhlIGNvbm5lY3RlZCBiaXQgYW5kIG1vdmUgdGhlIGxzYXAgdG8gdGhlIGNvbm5lY3RlZCBsaXN0CgkgKiBpbiB0aGUgc3RhdGUgbWFjaGluZSBpdHNlbGYuIEplYW4gSUkgKi8KCglJUkRBX0RFQlVHKDIsICIlcygpLCBzbHNhcF9zZWw9JTAyeCwgZGxzYXBfc2VsPSUwMnhcbiIsCgkJICAgX19GVU5DVElPTl9fLCBzZWxmLT5zbHNhcF9zZWwsIHNlbGYtPmRsc2FwX3NlbCk7CgoJLyogTWFrZSByb29tIGZvciBNVVggY29udHJvbCBoZWFkZXIgKDMgYnl0ZXMpICovCglJUkRBX0FTU0VSVChza2JfaGVhZHJvb20odXNlcmRhdGEpID49IExNUF9DT05UUk9MX0hFQURFUiwgcmV0dXJuIC0xOyk7Cglza2JfcHVzaCh1c2VyZGF0YSwgTE1QX0NPTlRST0xfSEVBREVSKTsKCglpcmxtcF9kb19sc2FwX2V2ZW50KHNlbGYsIExNX0NPTk5FQ1RfUkVTUE9OU0UsIHVzZXJkYXRhKTsKCgkvKiBEcm9wIHJlZmVyZW5jZSBjb3VudCAtIHNlZSBpcmxhcF9kYXRhX3JlcXVlc3QoKS4gKi8KCWRldl9rZnJlZV9za2IodXNlcmRhdGEpOwoKCXJldHVybiAwOwp9CkVYUE9SVF9TWU1CT0woaXJsbXBfY29ubmVjdF9yZXNwb25zZSk7CgovKgogKiBGdW5jdGlvbiBpcmxtcF9jb25uZWN0X2NvbmZpcm0gKGhhbmRsZSwgc2tiKQogKgogKiAgICBMU0FQIGNvbm5lY3Rpb24gY29uZmlybWVkIHBlZXIgZGV2aWNlIQogKi8Kdm9pZCBpcmxtcF9jb25uZWN0X2NvbmZpcm0oc3RydWN0IGxzYXBfY2IgKnNlbGYsIHN0cnVjdCBza19idWZmICpza2IpCnsKCWludCBtYXhfaGVhZGVyX3NpemU7CglpbnQgbGFwX2hlYWRlcl9zaXplOwoJaW50IG1heF9zZWdfc2l6ZTsKCglJUkRBX0RFQlVHKDMsICIlcygpXG4iLCBfX0ZVTkNUSU9OX18pOwoKCUlSREFfQVNTRVJUKHNrYiAhPSBOVUxMLCByZXR1cm47KTsKCUlSREFfQVNTRVJUKHNlbGYgIT0gTlVMTCwgcmV0dXJuOyk7CglJUkRBX0FTU0VSVChzZWxmLT5tYWdpYyA9PSBMTVBfTFNBUF9NQUdJQywgcmV0dXJuOyk7CglJUkRBX0FTU0VSVChzZWxmLT5sYXAgIT0gTlVMTCwgcmV0dXJuOyk7CgoJc2VsZi0+cW9zID0gKnNlbGYtPmxhcC0+cW9zOwoKCW1heF9zZWdfc2l6ZSAgICA9IHNlbGYtPmxhcC0+cW9zLT5kYXRhX3NpemUudmFsdWUtTE1QX0hFQURFUjsKCWxhcF9oZWFkZXJfc2l6ZSA9IElSTEFQX0dFVF9IRUFERVJfU0laRShzZWxmLT5sYXAtPmlybGFwKTsKCW1heF9oZWFkZXJfc2l6ZSA9IExNUF9IRUFERVIgKyBsYXBfaGVhZGVyX3NpemU7CgoJSVJEQV9ERUJVRygyLCAiJXMoKSwgbWF4X2hlYWRlcl9zaXplPSVkXG4iLAoJCSAgIF9fRlVOQ1RJT05fXywgbWF4X2hlYWRlcl9zaXplKTsKCgkvKiBIaWRlIExNUF9DT05UUk9MX0hFQURFUiBoZWFkZXIgZnJvbSBsYXllciBhYm92ZSAqLwoJc2tiX3B1bGwoc2tiLCBMTVBfQ09OVFJPTF9IRUFERVIpOwoKCWlmIChzZWxmLT5ub3RpZnkuY29ubmVjdF9jb25maXJtKSB7CgkJLyogRG9uJ3QgZm9yZ2V0IHRvIHJlZmNvdW50IGl0IC0gc2VlIGlybGFwX2RyaXZlcl9yY3YoKSAqLwoJCXNrYl9nZXQoc2tiKTsKCQlzZWxmLT5ub3RpZnkuY29ubmVjdF9jb25maXJtKHNlbGYtPm5vdGlmeS5pbnN0YW5jZSwgc2VsZiwKCQkJCQkgICAgICZzZWxmLT5xb3MsIG1heF9zZWdfc2l6ZSwKCQkJCQkgICAgIG1heF9oZWFkZXJfc2l6ZSwgc2tiKTsKCX0KfQoKLyoKICogRnVuY3Rpb24gaXJsbXBfZHVwIChvcmlnLCBpbnN0YW5jZSkKICoKICogICAgRHVwbGljYXRlIExTQVAsIGNhbiBiZSB1c2VkIGJ5IHNlcnZlcnMgdG8gY29uZmlybSBhIGNvbm5lY3Rpb24gb24gYQogKiAgICBuZXcgTFNBUCBzbyBpdCBjYW4ga2VlcCBsaXN0ZW5pbmcgb24gdGhlIG9sZCBvbmUuCiAqCiAqLwpzdHJ1Y3QgbHNhcF9jYiAqaXJsbXBfZHVwKHN0cnVjdCBsc2FwX2NiICpvcmlnLCB2b2lkICppbnN0YW5jZSkKewoJc3RydWN0IGxzYXBfY2IgKm5ldzsKCXVuc2lnbmVkIGxvbmcgZmxhZ3M7CgoJSVJEQV9ERUJVRygxLCAiJXMoKVxuIiwgX19GVU5DVElPTl9fKTsKCglzcGluX2xvY2tfaXJxc2F2ZSgmaXJsbXAtPnVuY29ubmVjdGVkX2xzYXBzLT5oYl9zcGlubG9jaywgZmxhZ3MpOwoKCS8qIE9ubHkgYWxsb3dlZCB0byBkdXBsaWNhdGUgdW5jb25uZWN0ZWQgTFNBUCdzLCBhbmQgb25seSBMU0FQcwoJICogdGhhdCBoYXZlIHJlY2VpdmVkIGEgY29ubmVjdCBpbmRpY2F0aW9uLiBKZWFuIElJICovCglpZiAoKCFoYXNoYmluX2ZpbmQoaXJsbXAtPnVuY29ubmVjdGVkX2xzYXBzLCAobG9uZykgb3JpZywgTlVMTCkpIHx8CgkgICAgKG9yaWctPmxhcCA9PSBOVUxMKSkgewoJCUlSREFfREVCVUcoMCwgIiVzKCksIGludmFsaWQgTFNBUCAod3Jvbmcgc3RhdGUpXG4iLAoJCQkgICBfX0ZVTkNUSU9OX18pOwoJCXNwaW5fdW5sb2NrX2lycXJlc3RvcmUoJmlybG1wLT51bmNvbm5lY3RlZF9sc2Fwcy0+aGJfc3BpbmxvY2ssCgkJCQkgICAgICAgZmxhZ3MpOwoJCXJldHVybiBOVUxMOwoJfQoKCS8qIEFsbG9jYXRlIGEgbmV3IGluc3RhbmNlICovCgluZXcgPSBrbWFsbG9jKHNpemVvZihzdHJ1Y3QgbHNhcF9jYiksIEdGUF9BVE9NSUMpOwoJaWYgKCFuZXcpICB7CgkJSVJEQV9ERUJVRygwLCAiJXMoKSwgdW5hYmxlIHRvIGttYWxsb2NcbiIsIF9fRlVOQ1RJT05fXyk7CgkJc3Bpbl91bmxvY2tfaXJxcmVzdG9yZSgmaXJsbXAtPnVuY29ubmVjdGVkX2xzYXBzLT5oYl9zcGlubG9jaywKCQkJCSAgICAgICBmbGFncyk7CgkJcmV0dXJuIE5VTEw7Cgl9CgkvKiBEdXAgKi8KCW1lbWNweShuZXcsIG9yaWcsIHNpemVvZihzdHJ1Y3QgbHNhcF9jYikpOwoJLyogbmV3LT5sYXAgPSBvcmlnLT5sYXA7ID0+IGRvbmUgaW4gdGhlIG1lbWNweSgpICovCgkvKiBuZXctPnNsc2FwX3NlbCA9IG9yaWctPnNsc2FwX3NlbDsgPT4gZG9uZSBpbiB0aGUgbWVtY3B5KCkgKi8KCW5ldy0+Y29ubl9za2IgPSBOVUxMOwoKCXNwaW5fdW5sb2NrX2lycXJlc3RvcmUoJmlybG1wLT51bmNvbm5lY3RlZF9sc2Fwcy0+aGJfc3BpbmxvY2ssIGZsYWdzKTsKCgkvKiBOb3QgZXZlcnl0aGluZyBpcyB0aGUgc2FtZSAqLwoJbmV3LT5ub3RpZnkuaW5zdGFuY2UgPSBpbnN0YW5jZTsKCglpbml0X3RpbWVyKCZuZXctPndhdGNoZG9nX3RpbWVyKTsKCgloYXNoYmluX2luc2VydChpcmxtcC0+dW5jb25uZWN0ZWRfbHNhcHMsIChpcmRhX3F1ZXVlX3QgKikgbmV3LAoJCSAgICAgICAobG9uZykgbmV3LCBOVUxMKTsKCiNpZmRlZiBDT05GSUdfSVJEQV9DQUNIRV9MQVNUX0xTQVAKCS8qIE1ha2Ugc3VyZSB0aGF0IHdlIGludmFsaWRhdGUgdGhlIExTQVAgY2FjaGUgKi8KCW5ldy0+bGFwLT5jYWNoZS52YWxpZCA9IEZBTFNFOwojZW5kaWYgLyogQ09ORklHX0lSREFfQ0FDSEVfTEFTVF9MU0FQICovCgoJcmV0dXJuIG5ldzsKfQoKLyoKICogRnVuY3Rpb24gaXJsbXBfZGlzY29ubmVjdF9yZXF1ZXN0IChoYW5kbGUsIHVzZXJkYXRhKQogKgogKiAgICBUaGUgc2VydmljZSB1c2VyIGlzIHJlcXVlc3RpbmcgZGlzY29ubmVjdGlvbiwgdGhpcyB3aWxsIG5vdCByZW1vdmUgdGhlCiAqICAgIExTQVAsIGJ1dCBvbmx5IG1hcmsgaXQgYXMgZGlzY29ubmVjdGVkCiAqLwppbnQgaXJsbXBfZGlzY29ubmVjdF9yZXF1ZXN0KHN0cnVjdCBsc2FwX2NiICpzZWxmLCBzdHJ1Y3Qgc2tfYnVmZiAqdXNlcmRhdGEpCnsKCXN0cnVjdCBsc2FwX2NiICpsc2FwOwoKCUlSREFfQVNTRVJUKHNlbGYgIT0gTlVMTCwgcmV0dXJuIC0xOyk7CglJUkRBX0FTU0VSVChzZWxmLT5tYWdpYyA9PSBMTVBfTFNBUF9NQUdJQywgcmV0dXJuIC0xOyk7CglJUkRBX0FTU0VSVCh1c2VyZGF0YSAhPSBOVUxMLCByZXR1cm4gLTE7KTsKCgkvKiBBbHJlYWR5IGRpc2Nvbm5lY3RlZCA/CgkgKiBUaGVyZSBpcyBhIHJhY2UgY29uZGl0aW9uIGJldHdlZW4gaXJsbXBfZGlzY29ubmVjdF9pbmRpY2F0aW9uKCkKCSAqIGFuZCB1cyB0aGF0IG1pZ2h0IG1lc3MgdXAgdGhlIGhhc2hiaW5zIGJlbG93LiBUaGlzIGZpeGVzIGl0LgoJICogSmVhbiBJSSAqLwoJaWYgKCEgdGVzdF9hbmRfY2xlYXJfYml0KDAsICZzZWxmLT5jb25uZWN0ZWQpKSB7CgkJSVJEQV9ERUJVRygwLCAiJXMoKSwgYWxyZWFkeSBkaXNjb25uZWN0ZWQhXG4iLCBfX0ZVTkNUSU9OX18pOwoJCWRldl9rZnJlZV9za2IodXNlcmRhdGEpOwoJCXJldHVybiAtMTsKCX0KCglza2JfcHVzaCh1c2VyZGF0YSwgTE1QX0NPTlRST0xfSEVBREVSKTsKCgkvKgoJICogIERvIHRoZSBldmVudCBiZWZvcmUgdGhlIG90aGVyIHN0dWZmIHNpbmNlIHdlIG11c3Qga25vdwoJICogIHdoaWNoIGxhcCBsYXllciB0aGF0IHRoZSBmcmFtZSBzaG91bGQgYmUgdHJhbnNtaXR0ZWQgb24KCSAqLwoJaXJsbXBfZG9fbHNhcF9ldmVudChzZWxmLCBMTV9ESVNDT05ORUNUX1JFUVVFU1QsIHVzZXJkYXRhKTsKCgkvKiBEcm9wIHJlZmVyZW5jZSBjb3VudCAtIHNlZSBpcmxhcF9kYXRhX3JlcXVlc3QoKS4gKi8KCWRldl9rZnJlZV9za2IodXNlcmRhdGEpOwoKCS8qCgkgKiAgUmVtb3ZlIExTQVAgZnJvbSBsaXN0IG9mIGNvbm5lY3RlZCBMU0FQcyBmb3IgdGhlIHBhcnRpY3VsYXIgbGluawoJICogIGFuZCBpbnNlcnQgaXQgaW50byB0aGUgbGlzdCBvZiB1bmNvbm5lY3RlZCBMU0FQcwoJICovCglJUkRBX0FTU0VSVChzZWxmLT5sYXAgIT0gTlVMTCwgcmV0dXJuIC0xOyk7CglJUkRBX0FTU0VSVChzZWxmLT5sYXAtPm1hZ2ljID09IExNUF9MQVBfTUFHSUMsIHJldHVybiAtMTspOwoJSVJEQV9BU1NFUlQoc2VsZi0+bGFwLT5sc2FwcyAhPSBOVUxMLCByZXR1cm4gLTE7KTsKCglsc2FwID0gaGFzaGJpbl9yZW1vdmUoc2VsZi0+bGFwLT5sc2FwcywgKGxvbmcpIHNlbGYsIE5VTEwpOwojaWZkZWYgQ09ORklHX0lSREFfQ0FDSEVfTEFTVF9MU0FQCglzZWxmLT5sYXAtPmNhY2hlLnZhbGlkID0gRkFMU0U7CiNlbmRpZgoKCUlSREFfQVNTRVJUKGxzYXAgIT0gTlVMTCwgcmV0dXJuIC0xOyk7CglJUkRBX0FTU0VSVChsc2FwLT5tYWdpYyA9PSBMTVBfTFNBUF9NQUdJQywgcmV0dXJuIC0xOyk7CglJUkRBX0FTU0VSVChsc2FwID09IHNlbGYsIHJldHVybiAtMTspOwoKCWhhc2hiaW5faW5zZXJ0KGlybG1wLT51bmNvbm5lY3RlZF9sc2FwcywgKGlyZGFfcXVldWVfdCAqKSBzZWxmLAoJCSAgICAgICAobG9uZykgc2VsZiwgTlVMTCk7CgoJLyogUmVzZXQgc29tZSB2YWx1ZXMgKi8KCXNlbGYtPmRsc2FwX3NlbCA9IExTQVBfQU5ZOwoJc2VsZi0+bGFwID0gTlVMTDsKCglyZXR1cm4gMDsKfQpFWFBPUlRfU1lNQk9MKGlybG1wX2Rpc2Nvbm5lY3RfcmVxdWVzdCk7CgovKgogKiBGdW5jdGlvbiBpcmxtcF9kaXNjb25uZWN0X2luZGljYXRpb24gKHJlYXNvbiwgdXNlcmRhdGEpCiAqCiAqICAgIExTQVAgaXMgYmVpbmcgY2xvc2VkIQogKi8Kdm9pZCBpcmxtcF9kaXNjb25uZWN0X2luZGljYXRpb24oc3RydWN0IGxzYXBfY2IgKnNlbGYsIExNX1JFQVNPTiByZWFzb24sCgkJCQkgc3RydWN0IHNrX2J1ZmYgKnNrYikKewoJc3RydWN0IGxzYXBfY2IgKmxzYXA7CgoJSVJEQV9ERUJVRygxLCAiJXMoKSwgcmVhc29uPSVzXG4iLCBfX0ZVTkNUSU9OX18sIGlybG1wX3JlYXNvbnNbcmVhc29uXSk7CglJUkRBX0FTU0VSVChzZWxmICE9IE5VTEwsIHJldHVybjspOwoJSVJEQV9BU1NFUlQoc2VsZi0+bWFnaWMgPT0gTE1QX0xTQVBfTUFHSUMsIHJldHVybjspOwoKCUlSREFfREVCVUcoMywgIiVzKCksIHNsc2FwX3NlbD0lMDJ4LCBkbHNhcF9zZWw9JTAyeFxuIiwKCQkgICBfX0ZVTkNUSU9OX18sIHNlbGYtPnNsc2FwX3NlbCwgc2VsZi0+ZGxzYXBfc2VsKTsKCgkvKiBBbHJlYWR5IGRpc2Nvbm5lY3RlZCA/CgkgKiBUaGVyZSBpcyBhIHJhY2UgY29uZGl0aW9uIGJldHdlZW4gaXJsbXBfZGlzY29ubmVjdF9yZXF1ZXN0KCkKCSAqIGFuZCB1cyB0aGF0IG1pZ2h0IG1lc3MgdXAgdGhlIGhhc2hiaW5zIGJlbG93LiBUaGlzIGZpeGVzIGl0LgoJICogSmVhbiBJSSAqLwoJaWYgKCEgdGVzdF9hbmRfY2xlYXJfYml0KDAsICZzZWxmLT5jb25uZWN0ZWQpKSB7CgkJSVJEQV9ERUJVRygwLCAiJXMoKSwgYWxyZWFkeSBkaXNjb25uZWN0ZWQhXG4iLCBfX0ZVTkNUSU9OX18pOwoJCXJldHVybjsKCX0KCgkvKgoJICogIFJlbW92ZSBhc3NvY2lhdGlvbiBiZXR3ZWVuIHRoaXMgTFNBUCBhbmQgdGhlIGxpbmsgaXQgdXNlZAoJICovCglJUkRBX0FTU0VSVChzZWxmLT5sYXAgIT0gTlVMTCwgcmV0dXJuOyk7CglJUkRBX0FTU0VSVChzZWxmLT5sYXAtPmxzYXBzICE9IE5VTEwsIHJldHVybjspOwoKCWxzYXAgPSBoYXNoYmluX3JlbW92ZShzZWxmLT5sYXAtPmxzYXBzLCAobG9uZykgc2VsZiwgTlVMTCk7CiNpZmRlZiBDT05GSUdfSVJEQV9DQUNIRV9MQVNUX0xTQVAKCXNlbGYtPmxhcC0+Y2FjaGUudmFsaWQgPSBGQUxTRTsKI2VuZGlmCgoJSVJEQV9BU1NFUlQobHNhcCAhPSBOVUxMLCByZXR1cm47KTsKCUlSREFfQVNTRVJUKGxzYXAgPT0gc2VsZiwgcmV0dXJuOyk7CgloYXNoYmluX2luc2VydChpcmxtcC0+dW5jb25uZWN0ZWRfbHNhcHMsIChpcmRhX3F1ZXVlX3QgKikgbHNhcCwKCQkgICAgICAgKGxvbmcpIGxzYXAsIE5VTEwpOwoKCXNlbGYtPmRsc2FwX3NlbCA9IExTQVBfQU5ZOwoJc2VsZi0+bGFwID0gTlVMTDsKCgkvKgoJICogIEluZm9ybSBzZXJ2aWNlIHVzZXIKCSAqLwoJaWYgKHNlbGYtPm5vdGlmeS5kaXNjb25uZWN0X2luZGljYXRpb24pIHsKCQkvKiBEb24ndCBmb3JnZXQgdG8gcmVmY291bnQgaXQgLSBzZWUgaXJsYXBfZHJpdmVyX3JjdigpLiAqLwoJCWlmKHNrYikKCQkJc2tiX2dldChza2IpOwoJCXNlbGYtPm5vdGlmeS5kaXNjb25uZWN0X2luZGljYXRpb24oc2VsZi0+bm90aWZ5Lmluc3RhbmNlLAoJCQkJCQkgICBzZWxmLCByZWFzb24sIHNrYik7Cgl9IGVsc2UgewoJCUlSREFfREVCVUcoMCwgIiVzKCksIG5vIGhhbmRsZXJcbiIsIF9fRlVOQ1RJT05fXyk7Cgl9Cn0KCi8qCiAqIEZ1bmN0aW9uIGlybG1wX2RvX2V4cGlyeSAodm9pZCkKICoKICogICAgRG8gYSBjbGVhbnVwIG9mIHRoZSBkaXNjb3ZlcnkgbG9nIChyZW1vdmUgb2xkIGVudHJpZXMpCiAqCiAqIE5vdGUgOiBzZXBhcmF0ZSBmcm9tIGlybG1wX2RvX2Rpc2NvdmVyeSgpIHNvIHRoYXQgd2UgY2FuIGhhbmRsZQogKiBwYXNzaXZlIGRpc2NvdmVyeSBwcm9wZXJseS4KICovCnZvaWQgaXJsbXBfZG9fZXhwaXJ5KHZvaWQpCnsKCXN0cnVjdCBsYXBfY2IgKmxhcDsKCgkvKgoJICogRXhwaXJlIGRpc2NvdmVyeSBvbiBhbGwgbGlua3Mgd2hpY2ggYXJlICpub3QqIGNvbm5lY3RlZC4KCSAqIE9uIGxpbmtzIHdoaWNoIGFyZSBjb25uZWN0ZWQsIHdlIGNhbid0IGRvIGRpc2NvdmVyeQoJICogYW55bW9yZSBhbmQgY2FuJ3QgcmVmcmVzaCB0aGUgbG9nLCBzbyB3ZSBmcmVlemUgdGhlCgkgKiBkaXNjb3ZlcnkgbG9nIHRvIGtlZXAgaW5mbyBhYm91dCB0aGUgZGV2aWNlIHdlIGFyZQoJICogY29ubmVjdGVkIHRvLgoJICogVGhpcyBpbmZvIGlzIG1hbmRhdG9yeSBpZiB3ZSB3YW50IGlybG1wX2Nvbm5lY3RfcmVxdWVzdCgpCgkgKiB0byB3b3JrIHByb3Blcmx5LiAtIEplYW4gSUkKCSAqLwoJbGFwID0gKHN0cnVjdCBsYXBfY2IgKikgaGFzaGJpbl9nZXRfZmlyc3QoaXJsbXAtPmxpbmtzKTsKCXdoaWxlIChsYXAgIT0gTlVMTCkgewoJCUlSREFfQVNTRVJUKGxhcC0+bWFnaWMgPT0gTE1QX0xBUF9NQUdJQywgcmV0dXJuOyk7CgoJCWlmIChsYXAtPmxhcF9zdGF0ZSA9PSBMQVBfU1RBTkRCWSkgewoJCQkvKiBFeHBpcmUgZGlzY292ZXJpZXMgZGlzY292ZXJlZCBvbiB0aGlzIGxpbmsgKi8KCQkJaXJsbXBfZXhwaXJlX2Rpc2NvdmVyaWVzKGlybG1wLT5jYWNoZWxvZywgbGFwLT5zYWRkciwKCQkJCQkJIEZBTFNFKTsKCQl9CgkJbGFwID0gKHN0cnVjdCBsYXBfY2IgKikgaGFzaGJpbl9nZXRfbmV4dChpcmxtcC0+bGlua3MpOwoJfQp9CgovKgogKiBGdW5jdGlvbiBpcmxtcF9kb19kaXNjb3ZlcnkgKG5zbG90cykKICoKICogICAgRG8gc29tZSBkaXNjb3Zlcnkgb24gYWxsIGxpbmtzCiAqCiAqIE5vdGUgOiBsb2cgZXhwaXJ5IGlzIGRvbmUgYWJvdmUuCiAqLwp2b2lkIGlybG1wX2RvX2Rpc2NvdmVyeShpbnQgbnNsb3RzKQp7CglzdHJ1Y3QgbGFwX2NiICpsYXA7CgoJLyogTWFrZSBzdXJlIHRoZSB2YWx1ZSBpcyBzYW5lICovCglpZiAoKG5zbG90cyAhPSAxKSAmJiAobnNsb3RzICE9IDYpICYmIChuc2xvdHMgIT0gOCkgJiYgKG5zbG90cyAhPSAxNikpewoJCUlSREFfV0FSTklORygiJXM6IGludmFsaWQgdmFsdWUgZm9yIG51bWJlciBvZiBzbG90cyFcbiIsCgkJCSAgICAgX19GVU5DVElPTl9fKTsKCQluc2xvdHMgPSBzeXNjdGxfZGlzY292ZXJ5X3Nsb3RzID0gODsKCX0KCgkvKiBDb25zdHJ1Y3QgbmV3IGRpc2NvdmVyeSBpbmZvIHRvIGJlIHVzZWQgYnkgSXJMQVAsICovCgl1MTZobyhpcmxtcC0+ZGlzY292ZXJ5X2NtZC5kYXRhLmhpbnRzKSA9IGlybG1wLT5oaW50cy53b3JkOwoKCS8qCgkgKiAgU2V0IGNoYXJhY3RlciBzZXQgZm9yIGRldmljZSBuYW1lICh3ZSB1c2UgQVNDSUkpLCBhbmQKCSAqICBjb3B5IGRldmljZSBuYW1lLiBSZW1lbWJlciB0byBtYWtlIHJvb20gZm9yIGEgXDAgYXQgdGhlCgkgKiAgZW5kCgkgKi8KCWlybG1wLT5kaXNjb3ZlcnlfY21kLmRhdGEuY2hhcnNldCA9IENTX0FTQ0lJOwoJc3RybmNweShpcmxtcC0+ZGlzY292ZXJ5X2NtZC5kYXRhLmluZm8sIHN5c2N0bF9kZXZuYW1lLAoJCU5JQ0tOQU1FX01BWF9MRU4pOwoJaXJsbXAtPmRpc2NvdmVyeV9jbWQubmFtZV9sZW4gPSBzdHJsZW4oaXJsbXAtPmRpc2NvdmVyeV9jbWQuZGF0YS5pbmZvKTsKCWlybG1wLT5kaXNjb3ZlcnlfY21kLm5zbG90cyA9IG5zbG90czsKCgkvKgoJICogVHJ5IHRvIHNlbmQgZGlzY292ZXJ5IHBhY2tldHMgb24gYWxsIGxpbmtzCgkgKi8KCWxhcCA9IChzdHJ1Y3QgbGFwX2NiICopIGhhc2hiaW5fZ2V0X2ZpcnN0KGlybG1wLT5saW5rcyk7Cgl3aGlsZSAobGFwICE9IE5VTEwpIHsKCQlJUkRBX0FTU0VSVChsYXAtPm1hZ2ljID09IExNUF9MQVBfTUFHSUMsIHJldHVybjspOwoKCQlpZiAobGFwLT5sYXBfc3RhdGUgPT0gTEFQX1NUQU5EQlkpIHsKCQkJLyogVHJ5IHRvIGRpc2NvdmVyICovCgkJCWlybG1wX2RvX2xhcF9ldmVudChsYXAsIExNX0xBUF9ESVNDT1ZFUllfUkVRVUVTVCwKCQkJCQkgICBOVUxMKTsKCQl9CgkJbGFwID0gKHN0cnVjdCBsYXBfY2IgKikgaGFzaGJpbl9nZXRfbmV4dChpcmxtcC0+bGlua3MpOwoJfQp9CgovKgogKiBGdW5jdGlvbiBpcmxtcF9kaXNjb3ZlcnlfcmVxdWVzdCAobnNsb3RzKQogKgogKiAgICBEbyBhIGRpc2NvdmVyeSBvZiBkZXZpY2VzIGluIGZyb250IG9mIHRoZSBjb21wdXRlcgogKgogKiBJZiB0aGUgY2FsbGVyIGhhcyByZWdpc3RlcmVkIGEgY2xpZW50IGRpc2NvdmVyeSBjYWxsYmFjaywgdGhpcwogKiBhbGxvdyBoaW0gdG8gcmVjZWl2ZSB0aGUgZnVsbCBjb250ZW50IG9mIHRoZSBkaXNjb3ZlcnkgbG9nIHRocm91Z2gKICogdGhpcyBjYWxsYmFjayAoYXMgbm9ybWFsbHkgaGUgd2lsbCByZWNlaXZlIG9ubHkgbmV3IGRpc2NvdmVyaWVzKS4KICovCnZvaWQgaXJsbXBfZGlzY292ZXJ5X3JlcXVlc3QoaW50IG5zbG90cykKewoJLyogUmV0dXJuIGN1cnJlbnQgY2FjaGVkIGRpc2NvdmVyeSBsb2cgKGluIGZ1bGwpICovCglpcmxtcF9kaXNjb3ZlcnlfY29uZmlybShpcmxtcC0+Y2FjaGVsb2csIERJU0NPVkVSWV9MT0cpOwoKCS8qCgkgKiBTdGFydCBhIHNpbmdsZSBkaXNjb3Zlcnkgb3BlcmF0aW9uIGlmIGRpc2NvdmVyeSBpcyBub3QgYWxyZWFkeQogICAgICAgICAqIHJ1bm5pbmcKCSAqLwoJaWYgKCFzeXNjdGxfZGlzY292ZXJ5KSB7CgkJLyogQ2hlY2sgaWYgdXNlciB3YW50cyB0byBvdmVycmlkZSB0aGUgZGVmYXVsdCAqLwoJCWlmIChuc2xvdHMgPT0gRElTQ09WRVJZX0RFRkFVTFRfU0xPVFMpCgkJCW5zbG90cyA9IHN5c2N0bF9kaXNjb3Zlcnlfc2xvdHM7CgoJCWlybG1wX2RvX2Rpc2NvdmVyeShuc2xvdHMpOwoJCS8qIE5vdGUgOiB3ZSBuZXZlciBkbyBleHBpcnkgaGVyZS4gRXhwaXJ5IHdpbGwgcnVuIG9uIHRoZQoJCSAqIGRpc2NvdmVyeSB0aW1lciByZWdhcmRsZXNzIG9mIHRoZSBzdGF0ZSBvZiBzeXNjdGxfZGlzY292ZXJ5CgkJICogSmVhbiBJSSAqLwoJfQp9CkVYUE9SVF9TWU1CT0woaXJsbXBfZGlzY292ZXJ5X3JlcXVlc3QpOwoKLyoKICogRnVuY3Rpb24gaXJsbXBfZ2V0X2Rpc2NvdmVyaWVzIChwbiwgbWFzaywgc2xvdHMpCiAqCiAqICAgIFJldHVybiB0aGUgY3VycmVudCBkaXNjb3ZlcnkgbG9nCiAqCiAqIElmIGRpc2NvdmVyeSBpcyBub3QgZW5hYmxlZCwgeW91IHNob3VsZCBjYWxsIHRoaXMgZnVuY3Rpb24gYWdhaW4KICogYWZ0ZXIgMSBvciAyIHNlY29uZHMgKGkuZS4gYWZ0ZXIgZGlzY292ZXJ5IGhhcyBiZWVuIGRvbmUpLgogKi8Kc3RydWN0IGlyZGFfZGV2aWNlX2luZm8gKmlybG1wX2dldF9kaXNjb3ZlcmllcyhpbnQgKnBuLCBfX3UxNiBtYXNrLCBpbnQgbnNsb3RzKQp7CgkvKiBJZiBkaXNjb3ZlcnkgaXMgbm90IGVuYWJsZWQsIGl0J3MgbGlrZWx5IHRoYXQgdGhlIGRpc2NvdmVyeSBsb2cKCSAqIHdpbGwgYmUgZW1wdHkuIFNvLCB3ZSB0cmlnZ2VyIGEgc2luZ2xlIGRpc2NvdmVyeSwgc28gdGhhdCBuZXh0CgkgKiB0aW1lIHRoZSB1c2VyIGNhbGwgdXMgdGhlcmUgbWlnaHQgYmUgc29tZSByZXN1bHRzIGluIHRoZSBsb2cuCgkgKiBKZWFuIElJCgkgKi8KCWlmICghc3lzY3RsX2Rpc2NvdmVyeSkgewoJCS8qIENoZWNrIGlmIHVzZXIgd2FudHMgdG8gb3ZlcnJpZGUgdGhlIGRlZmF1bHQgKi8KCQlpZiAobnNsb3RzID09IERJU0NPVkVSWV9ERUZBVUxUX1NMT1RTKQoJCQluc2xvdHMgPSBzeXNjdGxfZGlzY292ZXJ5X3Nsb3RzOwoKCQkvKiBTdGFydCBkaXNjb3ZlcnkgLSB3aWxsIGNvbXBsZXRlIHNvbWV0aW1lIGxhdGVyICovCgkJaXJsbXBfZG9fZGlzY292ZXJ5KG5zbG90cyk7CgkJLyogTm90ZSA6IHdlIG5ldmVyIGRvIGV4cGlyeSBoZXJlLiBFeHBpcnkgd2lsbCBydW4gb24gdGhlCgkJICogZGlzY292ZXJ5IHRpbWVyIHJlZ2FyZGxlc3Mgb2YgdGhlIHN0YXRlIG9mIHN5c2N0bF9kaXNjb3ZlcnkKCQkgKiBKZWFuIElJICovCgl9CgoJLyogUmV0dXJuIGN1cnJlbnQgY2FjaGVkIGRpc2NvdmVyeSBsb2cgKi8KCXJldHVybihpcmxtcF9jb3B5X2Rpc2NvdmVyaWVzKGlybG1wLT5jYWNoZWxvZywgcG4sIG1hc2ssIFRSVUUpKTsKfQpFWFBPUlRfU1lNQk9MKGlybG1wX2dldF9kaXNjb3Zlcmllcyk7CgovKgogKiBGdW5jdGlvbiBpcmxtcF9ub3RpZnlfY2xpZW50IChsb2cpCiAqCiAqICAgIE5vdGlmeSBhbGwgYWJvdXQgZGlzY292ZXJlZCBkZXZpY2VzCiAqCiAqIENsaWVudHMgcmVnaXN0ZXJlZCB3aXRoIElyTE1QIGFyZSA6CiAqCW8gSXJDb21tCiAqCW8gSXJMQU4KICoJbyBBbnkgc29ja2V0IChpbiBhbnkgc3RhdGUgLSBvdWNoLCB0aGF0IG1heSBiZSBhIGxvdCAhKQogKiBUaGUgY2xpZW50IG1heSBoYXZlIGRlZmluZWQgYSBjYWxsYmFjayB0byBiZSBub3RpZmllZCBpbiBjYXNlIG9mCiAqIHBhcnRpYWwvc2VsZWN0aXZlIGRpc2NvdmVyeSBiYXNlZCBvbiB0aGUgaGludHMgdGhhdCBpdCBwYXNzZWQgdG8gSXJMTVAuCiAqLwpzdGF0aWMgaW5saW5lIHZvaWQKaXJsbXBfbm90aWZ5X2NsaWVudChpcmxtcF9jbGllbnRfdCAqY2xpZW50LAoJCSAgICBoYXNoYmluX3QgKmxvZywgRElTQ09WRVJZX01PREUgbW9kZSkKewoJZGlzY2luZm9fdCAqZGlzY292ZXJpZXM7CS8qIENvcHkgb2YgdGhlIGRpc2NvdmVyeSBsb2cgKi8KCWludAludW1iZXI7CQkJLyogTnVtYmVyIG9mIG5vZGVzIGluIHRoZSBsb2cgKi8KCWludAlpOwoKCUlSREFfREVCVUcoMywgIiVzKClcbiIsIF9fRlVOQ1RJT05fXyk7CgoJLyogQ2hlY2sgaWYgY2xpZW50IHdhbnRzIG9yIG5vdCBwYXJ0aWFsL3NlbGVjdGl2ZSBsb2cgKG9wdGltaXNhdGlvbikgKi8KCWlmICghY2xpZW50LT5kaXNjb19jYWxsYmFjaykKCQlyZXR1cm47CgoJLyoKCSAqIExvY2tpbmcgbm90ZXMgOgoJICogdGhlIG9sZCBjb2RlIHdhcyBtYW5pcHVsYXRpbmcgdGhlIGxvZyBkaXJlY3RseSwgd2hpY2ggd2FzCgkgKiB2ZXJ5IHJhY3kuIE5vdywgd2UgdXNlIGNvcHlfZGlzY292ZXJpZXMsIHRoYXQgcHJvdGVjdHMKCSAqIGl0c2VsZiB3aGlsZSBkdW1waW5nIHRoZSBsb2cgZm9yIHVzLgoJICogVGhlIG92ZXJoZWFkIG9mIHRoZSBjb3B5IGlzIGNvbXBlbnNhdGVkIGJ5IHRoZSBmYWN0IHRoYXQKCSAqIHdlIG9ubHkgcGFzcyBuZXcgZGlzY292ZXJpZXMgaW4gbm9ybWFsIG1vZGUgYW5kIGRvbid0CgkgKiBwYXNzIHRoZSBzYW1lIG9sZCBlbnRyeSBldmVyeSAzcyB0byB0aGUgY2FsbGVyIGFzIHdlIHVzZWQKCSAqIHRvIGRvICh2aXJ0dWFsIGZ1bmN0aW9uIGNhbGxpbmcgaXMgZXhwZW5zaXZlKS4KCSAqIEplYW4gSUkKCSAqLwoKCS8qCgkgKiBOb3csIGNoZWNrIGFsbCBkaXNjb3ZlcmVkIGRldmljZXMgKGlmIGFueSksIGFuZCBub3RpZnkgY2xpZW50CgkgKiBvbmx5IGFib3V0IHRoZSBzZXJ2aWNlcyB0aGF0IHRoZSBjbGllbnQgaXMgaW50ZXJlc3RlZCBpbgoJICogV2UgYWxzbyBub3RpZnkgb25seSBhYm91dCB0aGUgbmV3IGRldmljZXMgdW5sZXNzIHRoZSBjYWxsZXIKCSAqIGV4cGxpY2l0bHkgcmVxdWVzdCBhIGR1bXAgb2YgdGhlIGxvZy4gSmVhbiBJSQoJICovCglkaXNjb3ZlcmllcyA9IGlybG1wX2NvcHlfZGlzY292ZXJpZXMobG9nLCAmbnVtYmVyLAoJCQkJCSAgICAgY2xpZW50LT5oaW50X21hc2sud29yZCwKCQkJCQkgICAgIChtb2RlID09IERJU0NPVkVSWV9MT0cpKTsKCS8qIENoZWNrIGlmIHRoZSB3ZSBnb3Qgc29tZSByZXN1bHRzICovCglpZiAoZGlzY292ZXJpZXMgPT0gTlVMTCkKCQlyZXR1cm47CS8qIE5vIG5vZGVzIGRpc2NvdmVyZWQgKi8KCgkvKiBQYXNzIGFsbCBlbnRyaWVzIHRvIHRoZSBsaXN0ZW5lciAqLwoJZm9yKGkgPSAwOyBpIDwgbnVtYmVyOyBpKyspCgkJY2xpZW50LT5kaXNjb19jYWxsYmFjaygmKGRpc2NvdmVyaWVzW2ldKSwgbW9kZSwgY2xpZW50LT5wcml2KTsKCgkvKiBGcmVlIHVwIG91ciBidWZmZXIgKi8KCWtmcmVlKGRpc2NvdmVyaWVzKTsKfQoKLyoKICogRnVuY3Rpb24gaXJsbXBfZGlzY292ZXJ5X2NvbmZpcm0gKCBzZWxmLCBsb2cpCiAqCiAqICAgIFNvbWUgZGV2aWNlKHMpIGFuc3dlcmVkIHRvIG91ciBkaXNjb3ZlcnkgcmVxdWVzdCEgQ2hlY2sgdG8gc2VlIHdoaWNoCiAqICAgIGRldmljZSBpdCBpcywgYW5kIGdpdmUgaW5kaWNhdGlvbiB0byB0aGUgY2xpZW50KHMpCiAqCiAqLwp2b2lkIGlybG1wX2Rpc2NvdmVyeV9jb25maXJtKGhhc2hiaW5fdCAqbG9nLCBESVNDT1ZFUllfTU9ERSBtb2RlKQp7CglpcmxtcF9jbGllbnRfdCAqY2xpZW50OwoJaXJsbXBfY2xpZW50X3QgKmNsaWVudF9uZXh0OwoKCUlSREFfREVCVUcoMywgIiVzKClcbiIsIF9fRlVOQ1RJT05fXyk7CgoJSVJEQV9BU1NFUlQobG9nICE9IE5VTEwsIHJldHVybjspOwoKCWlmICghKEhBU0hCSU5fR0VUX1NJWkUobG9nKSkpCgkJcmV0dXJuOwoKCS8qIEZvciBlYWNoIGNsaWVudCAtIG5vdGlmeSBjYWxsYmFjayBtYXkgdG91Y2ggY2xpZW50IGxpc3QgKi8KCWNsaWVudCA9IChpcmxtcF9jbGllbnRfdCAqKSBoYXNoYmluX2dldF9maXJzdChpcmxtcC0+Y2xpZW50cyk7Cgl3aGlsZSAoTlVMTCAhPSBoYXNoYmluX2ZpbmRfbmV4dChpcmxtcC0+Y2xpZW50cywgKGxvbmcpIGNsaWVudCwgTlVMTCwKCQkJCQkgKHZvaWQgKikgJmNsaWVudF9uZXh0KSApIHsKCQkvKiBDaGVjayBpZiB3ZSBzaG91bGQgbm90aWZ5IGNsaWVudCAqLwoJCWlybG1wX25vdGlmeV9jbGllbnQoY2xpZW50LCBsb2csIG1vZGUpOwoKCQljbGllbnQgPSBjbGllbnRfbmV4dDsKCX0KfQoKLyoKICogRnVuY3Rpb24gaXJsbXBfZGlzY292ZXJ5X2V4cGlyeSAoZXhwaXJ5KQogKgogKglUaGlzIGRldmljZSBpcyBubyBsb25nZXIgYmVlbiBkaXNjb3ZlcmVkLCBhbmQgdGhlcmVmb3JlIGl0IGlzIGJlaW5nCiAqCXB1cmdlZCBmcm9tIHRoZSBkaXNjb3ZlcnkgbG9nLiBJbmZvcm0gYWxsIGNsaWVudHMgd2hvIGhhdmUKICoJcmVnaXN0ZXJlZCBmb3IgdGhpcyBldmVudC4uLgogKgogKglOb3RlIDogY2FsbGVkIGV4Y2x1c2l2ZWx5IGZyb20gZGlzY292ZXJ5LmMKICoJTm90ZSA6IHRoaXMgaXMgbm8gbG9uZ2VyIGNhbGxlZCB1bmRlciBkaXNjb3Zlcnkgc3BpbmxvY2ssIHNvIHRoZQogKgkJY2xpZW50IGNhbiBkbyB3aGF0ZXZlciBoZSB3YW50cyBpbiB0aGUgY2FsbGJhY2suCiAqLwp2b2lkIGlybG1wX2Rpc2NvdmVyeV9leHBpcnkoZGlzY2luZm9fdCAqZXhwaXJpZXMsIGludCBudW1iZXIpCnsKCWlybG1wX2NsaWVudF90ICpjbGllbnQ7CglpcmxtcF9jbGllbnRfdCAqY2xpZW50X25leHQ7CglpbnQJCWk7CgoJSVJEQV9ERUJVRygzLCAiJXMoKVxuIiwgX19GVU5DVElPTl9fKTsKCglJUkRBX0FTU0VSVChleHBpcmllcyAhPSBOVUxMLCByZXR1cm47KTsKCgkvKiBGb3IgZWFjaCBjbGllbnQgLSBub3RpZnkgY2FsbGJhY2sgbWF5IHRvdWNoIGNsaWVudCBsaXN0ICovCgljbGllbnQgPSAoaXJsbXBfY2xpZW50X3QgKikgaGFzaGJpbl9nZXRfZmlyc3QoaXJsbXAtPmNsaWVudHMpOwoJd2hpbGUgKE5VTEwgIT0gaGFzaGJpbl9maW5kX25leHQoaXJsbXAtPmNsaWVudHMsIChsb25nKSBjbGllbnQsIE5VTEwsCgkJCQkJICh2b2lkICopICZjbGllbnRfbmV4dCkgKSB7CgoJCS8qIFBhc3MgYWxsIGVudHJpZXMgdG8gdGhlIGxpc3RlbmVyICovCgkJZm9yKGkgPSAwOyBpIDwgbnVtYmVyOyBpKyspIHsKCQkJLyogQ2hlY2sgaWYgd2Ugc2hvdWxkIG5vdGlmeSBjbGllbnQgKi8KCQkJaWYgKChjbGllbnQtPmV4cGlyX2NhbGxiYWNrKSAmJgoJCQkgICAgKGNsaWVudC0+aGludF9tYXNrLndvcmQgJiB1MTZobyhleHBpcmllc1tpXS5oaW50cykKCQkJICAgICAmIDB4N2Y3ZikgKQoJCQkJY2xpZW50LT5leHBpcl9jYWxsYmFjaygmKGV4cGlyaWVzW2ldKSwKCQkJCQkJICAgICAgIEVYUElSWV9USU1FT1VULAoJCQkJCQkgICAgICAgY2xpZW50LT5wcml2KTsKCQl9CgoJCS8qIE5leHQgY2xpZW50ICovCgkJY2xpZW50ID0gY2xpZW50X25leHQ7Cgl9Cn0KCi8qCiAqIEZ1bmN0aW9uIGlybG1wX2dldF9kaXNjb3ZlcnlfcmVzcG9uc2UgKCkKICoKICogICAgVXNlZCBieSBJckxBUCB0byBnZXQgdGhlIGRpc2NvdmVyeSBpbmZvIGl0IG5lZWRzIHdoZW4gYW5zd2VyaW5nCiAqICAgIGRpc2NvdmVyeSByZXF1ZXN0cyBieSBvdGhlciBkZXZpY2VzLgogKi8KZGlzY292ZXJ5X3QgKmlybG1wX2dldF9kaXNjb3ZlcnlfcmVzcG9uc2Uodm9pZCkKewoJSVJEQV9ERUJVRyg0LCAiJXMoKVxuIiwgX19GVU5DVElPTl9fKTsKCglJUkRBX0FTU0VSVChpcmxtcCAhPSBOVUxMLCByZXR1cm4gTlVMTDspOwoKCXUxNmhvKGlybG1wLT5kaXNjb3ZlcnlfcnNwLmRhdGEuaGludHMpID0gaXJsbXAtPmhpbnRzLndvcmQ7CgoJLyoKCSAqICBTZXQgY2hhcmFjdGVyIHNldCBmb3IgZGV2aWNlIG5hbWUgKHdlIHVzZSBBU0NJSSksIGFuZAoJICogIGNvcHkgZGV2aWNlIG5hbWUuIFJlbWVtYmVyIHRvIG1ha2Ugcm9vbSBmb3IgYSBcMCBhdCB0aGUKCSAqICBlbmQKCSAqLwoJaXJsbXAtPmRpc2NvdmVyeV9yc3AuZGF0YS5jaGFyc2V0ID0gQ1NfQVNDSUk7CgoJc3RybmNweShpcmxtcC0+ZGlzY292ZXJ5X3JzcC5kYXRhLmluZm8sIHN5c2N0bF9kZXZuYW1lLAoJCU5JQ0tOQU1FX01BWF9MRU4pOwoJaXJsbXAtPmRpc2NvdmVyeV9yc3AubmFtZV9sZW4gPSBzdHJsZW4oaXJsbXAtPmRpc2NvdmVyeV9yc3AuZGF0YS5pbmZvKTsKCglyZXR1cm4gJmlybG1wLT5kaXNjb3ZlcnlfcnNwOwp9CgovKgogKiBGdW5jdGlvbiBpcmxtcF9kYXRhX3JlcXVlc3QgKHNlbGYsIHNrYikKICoKICogICAgU2VuZCBzb21lIGRhdGEgdG8gcGVlciBkZXZpY2UKICoKICogTm90ZSBvbiBza2IgbWFuYWdlbWVudCA6CiAqIEFmdGVyIGNhbGxpbmcgdGhlIGxvd2VyIGxheWVycyBvZiB0aGUgSXJEQSBzdGFjaywgd2UgYWx3YXlzCiAqIGtmcmVlKCkgdGhlIHNrYiwgd2hpY2ggZHJvcCB0aGUgcmVmZXJlbmNlIGNvdW50IChhbmQgcG90ZW50aWFsbHkKICogZGVzdHJveSBpdCkuCiAqIElyTE1QIGFuZCBJckxBUCBtYXkgcXVldWUgdGhlIHBhY2tldCwgYW5kIGluIHRob3NlIGNhc2VzIHdpbGwgbmVlZAogKiB0byB1c2Ugc2tiX2dldCgpIHRvIGtlZXAgaXQgYXJvdW5kLgogKiBKZWFuIElJCiAqLwppbnQgaXJsbXBfZGF0YV9yZXF1ZXN0KHN0cnVjdCBsc2FwX2NiICpzZWxmLCBzdHJ1Y3Qgc2tfYnVmZiAqdXNlcmRhdGEpCnsKCWludAlyZXQ7CgoJSVJEQV9BU1NFUlQoc2VsZiAhPSBOVUxMLCByZXR1cm4gLTE7KTsKCUlSREFfQVNTRVJUKHNlbGYtPm1hZ2ljID09IExNUF9MU0FQX01BR0lDLCByZXR1cm4gLTE7KTsKCgkvKiBNYWtlIHJvb20gZm9yIE1VWCBoZWFkZXIgKi8KCUlSREFfQVNTRVJUKHNrYl9oZWFkcm9vbSh1c2VyZGF0YSkgPj0gTE1QX0hFQURFUiwgcmV0dXJuIC0xOyk7Cglza2JfcHVzaCh1c2VyZGF0YSwgTE1QX0hFQURFUik7CgoJcmV0ID0gaXJsbXBfZG9fbHNhcF9ldmVudChzZWxmLCBMTV9EQVRBX1JFUVVFU1QsIHVzZXJkYXRhKTsKCgkvKiBEcm9wIHJlZmVyZW5jZSBjb3VudCAtIHNlZSBpcmxhcF9kYXRhX3JlcXVlc3QoKS4gKi8KCWRldl9rZnJlZV9za2IodXNlcmRhdGEpOwoKCXJldHVybiByZXQ7Cn0KRVhQT1JUX1NZTUJPTChpcmxtcF9kYXRhX3JlcXVlc3QpOwoKLyoKICogRnVuY3Rpb24gaXJsbXBfZGF0YV9pbmRpY2F0aW9uIChoYW5kbGUsIHNrYikKICoKICogICAgR290IGRhdGEgZnJvbSBMQVAgbGF5ZXIgc28gcGFzcyBpdCB1cCB0byB1cHBlciBsYXllcgogKgogKi8Kdm9pZCBpcmxtcF9kYXRhX2luZGljYXRpb24oc3RydWN0IGxzYXBfY2IgKnNlbGYsIHN0cnVjdCBza19idWZmICpza2IpCnsKCS8qIEhpZGUgTE1QIGhlYWRlciBmcm9tIGxheWVyIGFib3ZlICovCglza2JfcHVsbChza2IsIExNUF9IRUFERVIpOwoKCWlmIChzZWxmLT5ub3RpZnkuZGF0YV9pbmRpY2F0aW9uKSB7CgkJLyogRG9uJ3QgZm9yZ2V0IHRvIHJlZmNvdW50IGl0IC0gc2VlIGlybGFwX2RyaXZlcl9yY3YoKS4gKi8KCQlza2JfZ2V0KHNrYik7CgkJc2VsZi0+bm90aWZ5LmRhdGFfaW5kaWNhdGlvbihzZWxmLT5ub3RpZnkuaW5zdGFuY2UsIHNlbGYsIHNrYik7Cgl9Cn0KCi8qCiAqIEZ1bmN0aW9uIGlybG1wX3VkYXRhX3JlcXVlc3QgKHNlbGYsIHNrYikKICovCmludCBpcmxtcF91ZGF0YV9yZXF1ZXN0KHN0cnVjdCBsc2FwX2NiICpzZWxmLCBzdHJ1Y3Qgc2tfYnVmZiAqdXNlcmRhdGEpCnsKCWludAlyZXQ7CgoJSVJEQV9ERUJVRyg0LCAiJXMoKVxuIiwgX19GVU5DVElPTl9fKTsKCglJUkRBX0FTU0VSVCh1c2VyZGF0YSAhPSBOVUxMLCByZXR1cm4gLTE7KTsKCgkvKiBNYWtlIHJvb20gZm9yIE1VWCBoZWFkZXIgKi8KCUlSREFfQVNTRVJUKHNrYl9oZWFkcm9vbSh1c2VyZGF0YSkgPj0gTE1QX0hFQURFUiwgcmV0dXJuIC0xOyk7Cglza2JfcHVzaCh1c2VyZGF0YSwgTE1QX0hFQURFUik7CgoJcmV0ID0gaXJsbXBfZG9fbHNhcF9ldmVudChzZWxmLCBMTV9VREFUQV9SRVFVRVNULCB1c2VyZGF0YSk7CgoJLyogRHJvcCByZWZlcmVuY2UgY291bnQgLSBzZWUgaXJsYXBfZGF0YV9yZXF1ZXN0KCkuICovCglkZXZfa2ZyZWVfc2tiKHVzZXJkYXRhKTsKCglyZXR1cm4gcmV0Owp9CgovKgogKiBGdW5jdGlvbiBpcmxtcF91ZGF0YV9pbmRpY2F0aW9uIChzZWxmLCBza2IpCiAqCiAqICAgIFNlbmQgdW5yZWxpYWJsZSBkYXRhIChidXQgc3RpbGwgd2l0aGluIHRoZSBjb25uZWN0aW9uKQogKgogKi8Kdm9pZCBpcmxtcF91ZGF0YV9pbmRpY2F0aW9uKHN0cnVjdCBsc2FwX2NiICpzZWxmLCBzdHJ1Y3Qgc2tfYnVmZiAqc2tiKQp7CglJUkRBX0RFQlVHKDQsICIlcygpXG4iLCBfX0ZVTkNUSU9OX18pOwoKCUlSREFfQVNTRVJUKHNlbGYgIT0gTlVMTCwgcmV0dXJuOyk7CglJUkRBX0FTU0VSVChzZWxmLT5tYWdpYyA9PSBMTVBfTFNBUF9NQUdJQywgcmV0dXJuOyk7CglJUkRBX0FTU0VSVChza2IgIT0gTlVMTCwgcmV0dXJuOyk7CgoJLyogSGlkZSBMTVAgaGVhZGVyIGZyb20gbGF5ZXIgYWJvdmUgKi8KCXNrYl9wdWxsKHNrYiwgTE1QX0hFQURFUik7CgoJaWYgKHNlbGYtPm5vdGlmeS51ZGF0YV9pbmRpY2F0aW9uKSB7CgkJLyogRG9uJ3QgZm9yZ2V0IHRvIHJlZmNvdW50IGl0IC0gc2VlIGlybGFwX2RyaXZlcl9yY3YoKS4gKi8KCQlza2JfZ2V0KHNrYik7CgkJc2VsZi0+bm90aWZ5LnVkYXRhX2luZGljYXRpb24oc2VsZi0+bm90aWZ5Lmluc3RhbmNlLCBzZWxmLAoJCQkJCSAgICAgIHNrYik7Cgl9Cn0KCi8qCiAqIEZ1bmN0aW9uIGlybG1wX2Nvbm5sZXNzX2RhdGFfcmVxdWVzdCAoc2VsZiwgc2tiKQogKi8KI2lmZGVmIENPTkZJR19JUkRBX1VMVFJBCmludCBpcmxtcF9jb25ubGVzc19kYXRhX3JlcXVlc3Qoc3RydWN0IGxzYXBfY2IgKnNlbGYsIHN0cnVjdCBza19idWZmICp1c2VyZGF0YSwKCQkJCV9fdTggcGlkKQp7CglzdHJ1Y3Qgc2tfYnVmZiAqY2xvbmVfc2tiOwoJc3RydWN0IGxhcF9jYiAqbGFwOwoKCUlSREFfREVCVUcoNCwgIiVzKClcbiIsIF9fRlVOQ1RJT05fXyk7CgoJSVJEQV9BU1NFUlQodXNlcmRhdGEgIT0gTlVMTCwgcmV0dXJuIC0xOyk7CgoJLyogTWFrZSByb29tIGZvciBNVVggYW5kIFBJRCBoZWFkZXIgKi8KCUlSREFfQVNTRVJUKHNrYl9oZWFkcm9vbSh1c2VyZGF0YSkgPj0gTE1QX0hFQURFUitMTVBfUElEX0hFQURFUiwKCQkgICAgcmV0dXJuIC0xOyk7CgoJLyogSW5zZXJ0IHByb3RvY29sIGlkZW50aWZpZXIgKi8KCXNrYl9wdXNoKHVzZXJkYXRhLCBMTVBfUElEX0hFQURFUik7CglpZihzZWxmICE9IE5VTEwpCgkgIHVzZXJkYXRhLT5kYXRhWzBdID0gc2VsZi0+cGlkOwoJZWxzZQoJICB1c2VyZGF0YS0+ZGF0YVswXSA9IHBpZDsKCgkvKiBDb25uZWN0aW9ubGVzcyBzb2NrZXRzIG11c3QgdXNlIDB4NzAgKi8KCXNrYl9wdXNoKHVzZXJkYXRhLCBMTVBfSEVBREVSKTsKCXVzZXJkYXRhLT5kYXRhWzBdID0gdXNlcmRhdGEtPmRhdGFbMV0gPSBMU0FQX0NPTk5MRVNTOwoKCS8qIFRyeSB0byBzZW5kIENvbm5lY3Rpb25sZXNzICBwYWNrZXRzIG91dCBvbiBhbGwgbGlua3MgKi8KCWxhcCA9IChzdHJ1Y3QgbGFwX2NiICopIGhhc2hiaW5fZ2V0X2ZpcnN0KGlybG1wLT5saW5rcyk7Cgl3aGlsZSAobGFwICE9IE5VTEwpIHsKCQlJUkRBX0FTU0VSVChsYXAtPm1hZ2ljID09IExNUF9MQVBfTUFHSUMsIHJldHVybiAtMTspOwoKCQljbG9uZV9za2IgPSBza2JfY2xvbmUodXNlcmRhdGEsIEdGUF9BVE9NSUMpOwoJCWlmICghY2xvbmVfc2tiKSB7CgkJCWRldl9rZnJlZV9za2IodXNlcmRhdGEpOwoJCQlyZXR1cm4gLUVOT01FTTsKCQl9CgoJCWlybGFwX3VuaXRkYXRhX3JlcXVlc3QobGFwLT5pcmxhcCwgY2xvbmVfc2tiKTsKCQkvKiBpcmxhcF91bml0ZGF0YV9yZXF1ZXN0KCkgZG9uJ3QgaW5jcmVhc2UgcmVmY291bnQsCgkJICogc28gbm8gZGV2X2tmcmVlX3NrYigpIC0gSmVhbiBJSSAqLwoKCQlsYXAgPSAoc3RydWN0IGxhcF9jYiAqKSBoYXNoYmluX2dldF9uZXh0KGlybG1wLT5saW5rcyk7Cgl9CglkZXZfa2ZyZWVfc2tiKHVzZXJkYXRhKTsKCglyZXR1cm4gMDsKfQojZW5kaWYgLyogQ09ORklHX0lSREFfVUxUUkEgKi8KCi8qCiAqIEZ1bmN0aW9uIGlybG1wX2Nvbm5sZXNzX2RhdGFfaW5kaWNhdGlvbiAoc2VsZiwgc2tiKQogKgogKiAgICBSZWNlaXZlIHVucmVsaWFibGUgZGF0YSBvdXRzaWRlIGFueSBjb25uZWN0aW9uLiBNb3N0bHkgdXNlZCBieSBVbHRyYQogKgogKi8KI2lmZGVmIENPTkZJR19JUkRBX1VMVFJBCnZvaWQgaXJsbXBfY29ubmxlc3NfZGF0YV9pbmRpY2F0aW9uKHN0cnVjdCBsc2FwX2NiICpzZWxmLCBzdHJ1Y3Qgc2tfYnVmZiAqc2tiKQp7CglJUkRBX0RFQlVHKDQsICIlcygpXG4iLCBfX0ZVTkNUSU9OX18pOwoKCUlSREFfQVNTRVJUKHNlbGYgIT0gTlVMTCwgcmV0dXJuOyk7CglJUkRBX0FTU0VSVChzZWxmLT5tYWdpYyA9PSBMTVBfTFNBUF9NQUdJQywgcmV0dXJuOyk7CglJUkRBX0FTU0VSVChza2IgIT0gTlVMTCwgcmV0dXJuOyk7CgoJLyogSGlkZSBMTVAgYW5kIFBJRCBoZWFkZXIgZnJvbSBsYXllciBhYm92ZSAqLwoJc2tiX3B1bGwoc2tiLCBMTVBfSEVBREVSK0xNUF9QSURfSEVBREVSKTsKCglpZiAoc2VsZi0+bm90aWZ5LnVkYXRhX2luZGljYXRpb24pIHsKCQkvKiBEb24ndCBmb3JnZXQgdG8gcmVmY291bnQgaXQgLSBzZWUgaXJsYXBfZHJpdmVyX3JjdigpLiAqLwoJCXNrYl9nZXQoc2tiKTsKCQlzZWxmLT5ub3RpZnkudWRhdGFfaW5kaWNhdGlvbihzZWxmLT5ub3RpZnkuaW5zdGFuY2UsIHNlbGYsCgkJCQkJICAgICAgc2tiKTsKCX0KfQojZW5kaWYgLyogQ09ORklHX0lSREFfVUxUUkEgKi8KCi8qCiAqIFByb3BhZ2F0ZSBzdGF0dXMgaW5kaWNhdGlvbiBmcm9tIExBUCB0byBMU0FQcyAodmlhIExNUCkKICogVGhpcyBkb24ndCB0cmlnZ2VyIGFueSBjaGFuZ2Ugb2Ygc3RhdGUgaW4gbGFwX2NiLCBsbXBfY2Igb3IgbHNhcF9jYiwKICogYW5kIHRoZSBldmVudCBpcyBzdGF0ZWxlc3MsIHRoZXJlZm9yZSB3ZSBjYW4gYnlwYXNzIGJvdGggc3RhdGUgbWFjaGluZXMKICogYW5kIHNlbmQgdGhlIGV2ZW50IGRpcmVjdCB0byB0aGUgTFNBUCB1c2VyLgogKiBKZWFuIElJCiAqLwp2b2lkIGlybG1wX3N0YXR1c19pbmRpY2F0aW9uKHN0cnVjdCBsYXBfY2IgKnNlbGYsCgkJCSAgICAgTElOS19TVEFUVVMgbGluaywgTE9DS19TVEFUVVMgbG9jaykKewoJc3RydWN0IGxzYXBfY2IgKm5leHQ7CglzdHJ1Y3QgbHNhcF9jYiAqY3VycjsKCgkvKiBTZW5kIHN0YXR1c19pbmRpY2F0aW9uIHRvIGFsbCBMU0FQcyB1c2luZyB0aGlzIGxpbmsgKi8KCWN1cnIgPSAoc3RydWN0IGxzYXBfY2IgKikgaGFzaGJpbl9nZXRfZmlyc3QoIHNlbGYtPmxzYXBzKTsKCXdoaWxlIChOVUxMICE9IGhhc2hiaW5fZmluZF9uZXh0KHNlbGYtPmxzYXBzLCAobG9uZykgY3VyciwgTlVMTCwKCQkJCQkgKHZvaWQgKikgJm5leHQpICkgewoJCUlSREFfQVNTRVJUKGN1cnItPm1hZ2ljID09IExNUF9MU0FQX01BR0lDLCByZXR1cm47KTsKCQkvKgoJCSAqICBJbmZvcm0gc2VydmljZSB1c2VyIGlmIGhlIGhhcyByZXF1ZXN0ZWQgaXQKCQkgKi8KCQlpZiAoY3Vyci0+bm90aWZ5LnN0YXR1c19pbmRpY2F0aW9uICE9IE5VTEwpCgkJCWN1cnItPm5vdGlmeS5zdGF0dXNfaW5kaWNhdGlvbihjdXJyLT5ub3RpZnkuaW5zdGFuY2UsCgkJCQkJCSAgICAgICBsaW5rLCBsb2NrKTsKCQllbHNlCgkJCUlSREFfREVCVUcoMiwgIiVzKCksIG5vIGhhbmRsZXJcbiIsIF9fRlVOQ1RJT05fXyk7CgoJCWN1cnIgPSBuZXh0OwoJfQp9CgovKgogKiBSZWNlaXZlIGZsb3cgY29udHJvbCBpbmRpY2F0aW9uIGZyb20gTEFQLgogKiBMQVAgd2FudCB1cyB0byBzZW5kIGl0IG9uZSBtb3JlIGZyYW1lLiBXZSBpbXBsZW1lbnQgYSBzaW1wbGUgcm91bmQKICogcm9iaW4gc2NoZWR1bGVyIGJldHdlZW4gdGhlIGFjdGl2ZSBzb2NrZXRzIHNvIHRoYXQgd2UgZ2V0IGEgYml0IG9mCiAqIGZhaXJuZXNzLiBOb3RlIHRoYXQgdGhlIHJvdW5kIHJvYmluIGlzIGZhciBmcm9tIHBlcmZlY3QsIGJ1dCBpdCdzCiAqIGJldHRlciB0aGFuIG5vdGhpbmcuCiAqIFdlIHRoZW4gcG9sbCB0aGUgc2VsZWN0ZWQgc29ja2V0IHNvIHRoYXQgd2UgY2FuIGRvIHN5bmNocm9ub3VzCiAqIHJlZmlsbGluZyBvZiBJckxBUCAod2hpY2ggYWxsb3cgdG8gbWluaW1pc2UgdGhlIG51bWJlciBvZiBidWZmZXJzKS4KICogSmVhbiBJSQogKi8Kdm9pZCBpcmxtcF9mbG93X2luZGljYXRpb24oc3RydWN0IGxhcF9jYiAqc2VsZiwgTE9DQUxfRkxPVyBmbG93KQp7CglzdHJ1Y3QgbHNhcF9jYiAqbmV4dDsKCXN0cnVjdCBsc2FwX2NiICpjdXJyOwoJaW50CWxzYXBfdG9kbzsKCglJUkRBX0FTU0VSVChzZWxmLT5tYWdpYyA9PSBMTVBfTEFQX01BR0lDLCByZXR1cm47KTsKCUlSREFfQVNTRVJUKGZsb3cgPT0gRkxPV19TVEFSVCwgcmV0dXJuOyk7CgoJLyogR2V0IHRoZSBudW1iZXIgb2YgbHNhcC4gVGhhdCdzIHRoZSBvbmx5IHNhZmUgd2F5IHRvIGtub3cKCSAqIHRoYXQgd2UgaGF2ZSBsb29wZWQgYXJvdW5kLi4uIC0gSmVhbiBJSSAqLwoJbHNhcF90b2RvID0gSEFTSEJJTl9HRVRfU0laRShzZWxmLT5sc2Fwcyk7CglJUkRBX0RFQlVHKDQsICIlcygpIDogJWQgbHNhcHMgdG8gc2NhblxuIiwgX19GVU5DVElPTl9fLCBsc2FwX3RvZG8pOwoKCS8qIFBvbGwgbHNhcCBpbiBvcmRlciB1bnRpbCB0aGUgcXVldWUgaXMgZnVsbCBvciB1bnRpbCB3ZQoJICogdHJpZWQgdGhlbSBhbGwuCgkgKiBNb3N0IG9mdGVuLCB0aGUgY3VycmVudCBMU0FQIHdpbGwgaGF2ZSBzb21ldGhpbmcgdG8gc2VuZCwKCSAqIHNvIHdlIHdpbGwgZ28gdGhyb3VnaCB0aGlzIGxvb3Agb25seSBvbmNlLiAtIEplYW4gSUkgKi8KCXdoaWxlKChsc2FwX3RvZG8tLSkgJiYKCSAgICAgIChJUkxBUF9HRVRfVFhfUVVFVUVfTEVOKHNlbGYtPmlybGFwKSA8IExBUF9ISUdIX1RIUkVTSE9MRCkpIHsKCQkvKiBUcnkgdG8gZmluZCB0aGUgbmV4dCBsc2FwIHdlIHNob3VsZCBwb2xsLiAqLwoJCW5leHQgPSBzZWxmLT5mbG93X25leHQ7CgkJLyogSWYgd2UgaGF2ZSBubyBsc2FwLCByZXN0YXJ0IGZyb20gZmlyc3Qgb25lICovCgkJaWYobmV4dCA9PSBOVUxMKQoJCQluZXh0ID0gKHN0cnVjdCBsc2FwX2NiICopIGhhc2hiaW5fZ2V0X2ZpcnN0KHNlbGYtPmxzYXBzKTsKCQkvKiBWZXJpZnkgY3VycmVudCBvbmUgYW5kIGZpbmQgdGhlIG5leHQgb25lICovCgkJY3VyciA9IGhhc2hiaW5fZmluZF9uZXh0KHNlbGYtPmxzYXBzLCAobG9uZykgbmV4dCwgTlVMTCwKCQkJCQkgKHZvaWQgKikgJnNlbGYtPmZsb3dfbmV4dCk7CgkJLyogVWgtb2guLi4gUGFyYW5vaWEgKi8KCQlpZihjdXJyID09IE5VTEwpCgkJCWJyZWFrOwoJCUlSREFfREVCVUcoNCwgIiVzKCkgOiBjdXJyIGlzICVwLCBuZXh0IHdhcyAlcCBhbmQgaXMgbm93ICVwLCBzdGlsbCAlZCB0byBnbyAtIHF1ZXVlIGxlbiA9ICVkXG4iLCBfX0ZVTkNUSU9OX18sIGN1cnIsIG5leHQsIHNlbGYtPmZsb3dfbmV4dCwgbHNhcF90b2RvLCBJUkxBUF9HRVRfVFhfUVVFVUVfTEVOKHNlbGYtPmlybGFwKSk7CgoJCS8qIEluZm9ybSBsc2FwIHVzZXIgdGhhdCBpdCBjYW4gc2VuZCBvbmUgbW9yZSBwYWNrZXQuICovCgkJaWYgKGN1cnItPm5vdGlmeS5mbG93X2luZGljYXRpb24gIT0gTlVMTCkKCQkJY3Vyci0+bm90aWZ5LmZsb3dfaW5kaWNhdGlvbihjdXJyLT5ub3RpZnkuaW5zdGFuY2UsCgkJCQkJCSAgICAgY3VyciwgZmxvdyk7CgkJZWxzZQoJCQlJUkRBX0RFQlVHKDEsICIlcygpLCBubyBoYW5kbGVyXG4iLCBfX0ZVTkNUSU9OX18pOwoJfQp9CgojaWYgMAovKgogKiBGdW5jdGlvbiBpcmxtcF9oaW50X3RvX3NlcnZpY2UgKGhpbnQpCiAqCiAqICAgIFJldHVybnMgYSBsaXN0IG9mIGFsbCBzZXJ2aWNzIGNvbnRhaW5lZCBpbiB0aGUgZ2l2ZW4gaGludCBiaXRzLiBUaGlzCiAqICAgIGZ1bmN0aW9uIGFzc3VtZXMgdGhhdCB0aGUgaGludCBiaXRzIGhhdmUgdGhlIHNpemUgb2YgdHdvIGJ5dGVzIG9ubHkKICovCl9fdTggKmlybG1wX2hpbnRfdG9fc2VydmljZShfX3U4ICpoaW50KQp7CglfX3U4ICpzZXJ2aWNlOwoJaW50IGkgPSAwOwoKCS8qCgkgKiBBbGxvY2F0ZSBhcnJheSB0byBzdG9yZSBzZXJ2aWNlcyBpbi4gMTYgZW50cmllcyBzaG91bGQgYmUgc2FmZQoJICogc2luY2Ugd2UgY3VycmVudGx5IG9ubHkgc3VwcG9ydCAyIGhpbnQgYnl0ZXMKCSAqLwoJc2VydmljZSA9IGttYWxsb2MoMTYsIEdGUF9BVE9NSUMpOwoJaWYgKCFzZXJ2aWNlKSB7CgkJSVJEQV9ERUJVRygxLCAiJXMoKSwgVW5hYmxlIHRvIGttYWxsb2MhXG4iLCBfX0ZVTkNUSU9OX18pOwoJCXJldHVybiBOVUxMOwoJfQoKCWlmICghaGludFswXSkgewoJCUlSREFfREVCVUcoMSwgIjxOb25lPlxuIik7CgkJa2ZyZWUoc2VydmljZSk7CgkJcmV0dXJuIE5VTEw7Cgl9CglpZiAoaGludFswXSAmIEhJTlRfUE5QKQoJCUlSREFfREVCVUcoMSwgIlBuUCBDb21wYXRpYmxlICIpOwoJaWYgKGhpbnRbMF0gJiBISU5UX1BEQSkKCQlJUkRBX0RFQlVHKDEsICJQREEvUGFsbXRvcCAiKTsKCWlmIChoaW50WzBdICYgSElOVF9DT01QVVRFUikKCQlJUkRBX0RFQlVHKDEsICJDb21wdXRlciAiKTsKCWlmIChoaW50WzBdICYgSElOVF9QUklOVEVSKSB7CgkJSVJEQV9ERUJVRygxLCAiUHJpbnRlciAiKTsKCQlzZXJ2aWNlW2krK10gPSBTX1BSSU5URVI7Cgl9CglpZiAoaGludFswXSAmIEhJTlRfTU9ERU0pCgkJSVJEQV9ERUJVRygxLCAiTW9kZW0gIik7CglpZiAoaGludFswXSAmIEhJTlRfRkFYKQoJCUlSREFfREVCVUcoMSwgIkZheCAiKTsKCWlmIChoaW50WzBdICYgSElOVF9MQU4pIHsKCQlJUkRBX0RFQlVHKDEsICJMQU4gQWNjZXNzICIpOwoJCXNlcnZpY2VbaSsrXSA9IFNfTEFOOwoJfQoJLyoKCSAqICBUZXN0IGlmIGV4dGVuc2lvbiBieXRlIGV4aXN0cy4gVGhpcyBieXRlIHdpbGwgdXN1YWxseSBiZQoJICogIHRoZXJlLCBidXQgdGhpcyBpcyBub3QgcmVhbGx5IHJlcXVpcmVkIGJ5IHRoZSBzdGFuZGFyZC4KCSAqICAoSXJMTVAgcC4gMjkpCgkgKi8KCWlmIChoaW50WzBdICYgSElOVF9FWFRFTlNJT04pIHsKCQlpZiAoaGludFsxXSAmIEhJTlRfVEVMRVBIT05ZKSB7CgkJCUlSREFfREVCVUcoMSwgIlRlbGVwaG9ueSAiKTsKCQkJc2VydmljZVtpKytdID0gU19URUxFUEhPTlk7CgkJfSBpZiAoaGludFsxXSAmIEhJTlRfRklMRV9TRVJWRVIpCgkJCUlSREFfREVCVUcoMSwgIkZpbGUgU2VydmVyICIpOwoKCQlpZiAoaGludFsxXSAmIEhJTlRfQ09NTSkgewoJCQlJUkRBX0RFQlVHKDEsICJJckNPTU0gIik7CgkJCXNlcnZpY2VbaSsrXSA9IFNfQ09NTTsKCQl9CgkJaWYgKGhpbnRbMV0gJiBISU5UX09CRVgpIHsKCQkJSVJEQV9ERUJVRygxLCAiSXJPQkVYICIpOwoJCQlzZXJ2aWNlW2krK10gPSBTX09CRVg7CgkJfQoJfQoJSVJEQV9ERUJVRygxLCAiXG4iKTsKCgkvKiBTbyB0aGF0IGNsaWVudCBjYW4gYmUgbm90aWZpZWQgYWJvdXQgYW55IGRpc2NvdmVyeSAqLwoJc2VydmljZVtpKytdID0gU19BTlk7CgoJc2VydmljZVtpXSA9IFNfRU5EOwoKCXJldHVybiBzZXJ2aWNlOwp9CiNlbmRpZgoKc3RhdGljIGNvbnN0IF9fdTE2IHNlcnZpY2VfaGludF9tYXBwaW5nW1NfRU5EXVsyXSA9IHsKCXsgSElOVF9QTlAsCQkwIH0sCQkJLyogU19QTlAgKi8KCXsgSElOVF9QREEsCQkwIH0sCQkJLyogU19QREEgKi8KCXsgSElOVF9DT01QVVRFUiwJMCB9LAkJCS8qIFNfQ09NUFVURVIgKi8KCXsgSElOVF9QUklOVEVSLAkJMCB9LAkJCS8qIFNfUFJJTlRFUiAqLwoJeyBISU5UX01PREVNLAkJMCB9LAkJCS8qIFNfTU9ERU0gKi8KCXsgSElOVF9GQVgsCQkwIH0sCQkJLyogU19GQVggKi8KCXsgSElOVF9MQU4sCQkwIH0sCQkJLyogU19MQU4gKi8KCXsgSElOVF9FWFRFTlNJT04sCUhJTlRfVEVMRVBIT05ZIH0sCS8qIFNfVEVMRVBIT05ZICovCgl7IEhJTlRfRVhURU5TSU9OLAlISU5UX0NPTU0gfSwJCS8qIFNfQ09NTSAqLwoJeyBISU5UX0VYVEVOU0lPTiwJSElOVF9PQkVYIH0sCQkvKiBTX09CRVggKi8KCXsgMHhGRiwJCQkweEZGIH0sCQkJLyogU19BTlkgKi8KfTsKCi8qCiAqIEZ1bmN0aW9uIGlybG1wX3NlcnZpY2VfdG9faGludCAoc2VydmljZSkKICoKICogICAgQ29udmVydHMgYSBzZXJ2aWNlIHR5cGUsIHRvIGEgaGludCBiaXQKICoKICogICAgUmV0dXJuczogYSAxNiBiaXQgaGludCB2YWx1ZSwgd2l0aCB0aGUgc2VydmljZSBiaXQgc2V0CiAqLwpfX3UxNiBpcmxtcF9zZXJ2aWNlX3RvX2hpbnQoaW50IHNlcnZpY2UpCnsKCV9fdTE2X2hvc3Rfb3JkZXIgaGludDsKCgloaW50LmJ5dGVbMF0gPSBzZXJ2aWNlX2hpbnRfbWFwcGluZ1tzZXJ2aWNlXVswXTsKCWhpbnQuYnl0ZVsxXSA9IHNlcnZpY2VfaGludF9tYXBwaW5nW3NlcnZpY2VdWzFdOwoKCXJldHVybiBoaW50LndvcmQ7Cn0KRVhQT1JUX1NZTUJPTChpcmxtcF9zZXJ2aWNlX3RvX2hpbnQpOwoKLyoKICogRnVuY3Rpb24gaXJsbXBfcmVnaXN0ZXJfc2VydmljZSAoc2VydmljZSkKICoKICogICAgUmVnaXN0ZXIgbG9jYWwgc2VydmljZSB3aXRoIElyTE1QCiAqCiAqLwp2b2lkICppcmxtcF9yZWdpc3Rlcl9zZXJ2aWNlKF9fdTE2IGhpbnRzKQp7CglpcmxtcF9zZXJ2aWNlX3QgKnNlcnZpY2U7CgoJSVJEQV9ERUJVRyg0LCAiJXMoKSwgaGludHMgPSAlMDR4XG4iLCBfX0ZVTkNUSU9OX18sIGhpbnRzKTsKCgkvKiBNYWtlIGEgbmV3IHJlZ2lzdHJhdGlvbiAqLwoJc2VydmljZSA9IGttYWxsb2Moc2l6ZW9mKGlybG1wX3NlcnZpY2VfdCksIEdGUF9BVE9NSUMpOwoJaWYgKCFzZXJ2aWNlKSB7CgkJSVJEQV9ERUJVRygxLCAiJXMoKSwgVW5hYmxlIHRvIGttYWxsb2MhXG4iLCBfX0ZVTkNUSU9OX18pOwoJCXJldHVybiBOVUxMOwoJfQoJc2VydmljZS0+aGludHMud29yZCA9IGhpbnRzOwoJaGFzaGJpbl9pbnNlcnQoaXJsbXAtPnNlcnZpY2VzLCAoaXJkYV9xdWV1ZV90ICopIHNlcnZpY2UsCgkJICAgICAgIChsb25nKSBzZXJ2aWNlLCBOVUxMKTsKCglpcmxtcC0+aGludHMud29yZCB8PSBoaW50czsKCglyZXR1cm4gKHZvaWQgKilzZXJ2aWNlOwp9CkVYUE9SVF9TWU1CT0woaXJsbXBfcmVnaXN0ZXJfc2VydmljZSk7CgovKgogKiBGdW5jdGlvbiBpcmxtcF91bnJlZ2lzdGVyX3NlcnZpY2UgKGhhbmRsZSkKICoKICogICAgVW5yZWdpc3RlciBzZXJ2aWNlIHdpdGggSXJMTVAuCiAqCiAqICAgIFJldHVybnM6IDAgb24gc3VjY2VzcywgLTEgb24gZXJyb3IKICovCmludCBpcmxtcF91bnJlZ2lzdGVyX3NlcnZpY2Uodm9pZCAqaGFuZGxlKQp7CglpcmxtcF9zZXJ2aWNlX3QgKnNlcnZpY2U7Cgl1bnNpZ25lZCBsb25nIGZsYWdzOwoKCUlSREFfREVCVUcoNCwgIiVzKClcbiIsIF9fRlVOQ1RJT05fXyk7CgoJaWYgKCFoYW5kbGUpCgkJcmV0dXJuIC0xOwoKCS8qIENhbGxlciBtYXkgY2FsbCB3aXRoIGludmFsaWQgaGFuZGxlIChpdCdzIGxlZ2FsKSAtIEplYW4gSUkgKi8KCXNlcnZpY2UgPSBoYXNoYmluX2xvY2tfZmluZChpcmxtcC0+c2VydmljZXMsIChsb25nKSBoYW5kbGUsIE5VTEwpOwoJaWYgKCFzZXJ2aWNlKSB7CgkJSVJEQV9ERUJVRygxLCAiJXMoKSwgVW5rbm93biBzZXJ2aWNlIVxuIiwgX19GVU5DVElPTl9fKTsKCQlyZXR1cm4gLTE7Cgl9CgoJaGFzaGJpbl9yZW1vdmVfdGhpcyhpcmxtcC0+c2VydmljZXMsIChpcmRhX3F1ZXVlX3QgKikgc2VydmljZSk7CglrZnJlZShzZXJ2aWNlKTsKCgkvKiBSZW1vdmUgb2xkIGhpbnQgYml0cyAqLwoJaXJsbXAtPmhpbnRzLndvcmQgPSAwOwoKCS8qIFJlZnJlc2ggY3VycmVudCBoaW50IGJpdHMgKi8KCXNwaW5fbG9ja19pcnFzYXZlKCZpcmxtcC0+c2VydmljZXMtPmhiX3NwaW5sb2NrLCBmbGFncyk7CiAgICAgICAgc2VydmljZSA9IChpcmxtcF9zZXJ2aWNlX3QgKikgaGFzaGJpbl9nZXRfZmlyc3QoaXJsbXAtPnNlcnZpY2VzKTsKICAgICAgICB3aGlsZSAoc2VydmljZSkgewoJCWlybG1wLT5oaW50cy53b3JkIHw9IHNlcnZpY2UtPmhpbnRzLndvcmQ7CgogICAgICAgICAgICAgICAgc2VydmljZSA9IChpcmxtcF9zZXJ2aWNlX3QgKiloYXNoYmluX2dldF9uZXh0KGlybG1wLT5zZXJ2aWNlcyk7CiAgICAgICAgfQoJc3Bpbl91bmxvY2tfaXJxcmVzdG9yZSgmaXJsbXAtPnNlcnZpY2VzLT5oYl9zcGlubG9jaywgZmxhZ3MpOwoJcmV0dXJuIDA7Cn0KRVhQT1JUX1NZTUJPTChpcmxtcF91bnJlZ2lzdGVyX3NlcnZpY2UpOwoKLyoKICogRnVuY3Rpb24gaXJsbXBfcmVnaXN0ZXJfY2xpZW50IChoaW50X21hc2ssIGNhbGxiYWNrMSwgY2FsbGJhY2syKQogKgogKiAgICBSZWdpc3RlciBhIGxvY2FsIGNsaWVudCB3aXRoIElyTE1QCiAqCUZpcnN0IGNhbGxiYWNrIGlzIHNlbGVjdGl2ZSBkaXNjb3ZlcnkgKGJhc2VkIG9uIGhpbnRzKQogKglTZWNvbmQgY2FsbGJhY2sgaXMgZm9yIHNlbGVjdGl2ZSBkaXNjb3ZlcnkgZXhwaXJpZXMKICoKICogICAgUmV0dXJuczogaGFuZGxlID4gMCBvbiBzdWNjZXNzLCAwIG9uIGVycm9yCiAqLwp2b2lkICppcmxtcF9yZWdpc3Rlcl9jbGllbnQoX191MTYgaGludF9tYXNrLCBESVNDT1ZFUllfQ0FMTEJBQ0sxIGRpc2NvX2NsYiwKCQkJICAgIERJU0NPVkVSWV9DQUxMQkFDSzIgZXhwaXJfY2xiLCB2b2lkICpwcml2KQp7CglpcmxtcF9jbGllbnRfdCAqY2xpZW50OwoKCUlSREFfREVCVUcoMSwgIiVzKClcbiIsIF9fRlVOQ1RJT05fXyk7CglJUkRBX0FTU0VSVChpcmxtcCAhPSBOVUxMLCByZXR1cm4gTlVMTDspOwoKCS8qIE1ha2UgYSBuZXcgcmVnaXN0cmF0aW9uICovCgljbGllbnQgPSBrbWFsbG9jKHNpemVvZihpcmxtcF9jbGllbnRfdCksIEdGUF9BVE9NSUMpOwoJaWYgKCFjbGllbnQpIHsKCQlJUkRBX0RFQlVHKCAxLCAiJXMoKSwgVW5hYmxlIHRvIGttYWxsb2MhXG4iLCBfX0ZVTkNUSU9OX18pOwoJCXJldHVybiBOVUxMOwoJfQoKCS8qIFJlZ2lzdGVyIHRoZSBkZXRhaWxzICovCgljbGllbnQtPmhpbnRfbWFzay53b3JkID0gaGludF9tYXNrOwoJY2xpZW50LT5kaXNjb19jYWxsYmFjayA9IGRpc2NvX2NsYjsKCWNsaWVudC0+ZXhwaXJfY2FsbGJhY2sgPSBleHBpcl9jbGI7CgljbGllbnQtPnByaXYgPSBwcml2OwoKCWhhc2hiaW5faW5zZXJ0KGlybG1wLT5jbGllbnRzLCAoaXJkYV9xdWV1ZV90ICopIGNsaWVudCwKCQkgICAgICAgKGxvbmcpIGNsaWVudCwgTlVMTCk7CgoJcmV0dXJuICh2b2lkICopIGNsaWVudDsKfQpFWFBPUlRfU1lNQk9MKGlybG1wX3JlZ2lzdGVyX2NsaWVudCk7CgovKgogKiBGdW5jdGlvbiBpcmxtcF91cGRhdGVfY2xpZW50IChoYW5kbGUsIGhpbnRfbWFzaywgY2FsbGJhY2sxLCBjYWxsYmFjazIpCiAqCiAqICAgIFVwZGF0ZXMgc3BlY2lmaWVkIGNsaWVudCAoaGFuZGxlKSB3aXRoIHBvc3NpYmx5IG5ldyBoaW50X21hc2sgYW5kCiAqICAgIGNhbGxiYWNrCiAqCiAqICAgIFJldHVybnM6IDAgb24gc3VjY2VzcywgLTEgb24gZXJyb3IKICovCmludCBpcmxtcF91cGRhdGVfY2xpZW50KHZvaWQgKmhhbmRsZSwgX191MTYgaGludF9tYXNrLAoJCQlESVNDT1ZFUllfQ0FMTEJBQ0sxIGRpc2NvX2NsYiwKCQkJRElTQ09WRVJZX0NBTExCQUNLMiBleHBpcl9jbGIsIHZvaWQgKnByaXYpCnsKCWlybG1wX2NsaWVudF90ICpjbGllbnQ7CgoJaWYgKCFoYW5kbGUpCgkJcmV0dXJuIC0xOwoKCWNsaWVudCA9IGhhc2hiaW5fbG9ja19maW5kKGlybG1wLT5jbGllbnRzLCAobG9uZykgaGFuZGxlLCBOVUxMKTsKCWlmICghY2xpZW50KSB7CgkJSVJEQV9ERUJVRygxLCAiJXMoKSwgVW5rbm93biBjbGllbnQhXG4iLCBfX0ZVTkNUSU9OX18pOwoJCXJldHVybiAtMTsKCX0KCgljbGllbnQtPmhpbnRfbWFzay53b3JkID0gaGludF9tYXNrOwoJY2xpZW50LT5kaXNjb19jYWxsYmFjayA9IGRpc2NvX2NsYjsKCWNsaWVudC0+ZXhwaXJfY2FsbGJhY2sgPSBleHBpcl9jbGI7CgljbGllbnQtPnByaXYgPSBwcml2OwoKCXJldHVybiAwOwp9CkVYUE9SVF9TWU1CT0woaXJsbXBfdXBkYXRlX2NsaWVudCk7CgovKgogKiBGdW5jdGlvbiBpcmxtcF91bnJlZ2lzdGVyX2NsaWVudCAoaGFuZGxlKQogKgogKiAgICBSZXR1cm5zOiAwIG9uIHN1Y2Nlc3MsIC0xIG9uIGVycm9yCiAqCiAqLwppbnQgaXJsbXBfdW5yZWdpc3Rlcl9jbGllbnQodm9pZCAqaGFuZGxlKQp7CglzdHJ1Y3QgaXJsbXBfY2xpZW50ICpjbGllbnQ7CgoJSVJEQV9ERUJVRyg0LCAiJXMoKVxuIiwgX19GVU5DVElPTl9fKTsKCglpZiAoIWhhbmRsZSkKCQlyZXR1cm4gLTE7CgoJLyogQ2FsbGVyIG1heSBjYWxsIHdpdGggaW52YWxpZCBoYW5kbGUgKGl0J3MgbGVnYWwpIC0gSmVhbiBJSSAqLwoJY2xpZW50ID0gaGFzaGJpbl9sb2NrX2ZpbmQoaXJsbXAtPmNsaWVudHMsIChsb25nKSBoYW5kbGUsIE5VTEwpOwoJaWYgKCFjbGllbnQpIHsKCQlJUkRBX0RFQlVHKDEsICIlcygpLCBVbmtub3duIGNsaWVudCFcbiIsIF9fRlVOQ1RJT05fXyk7CgkJcmV0dXJuIC0xOwoJfQoKCUlSREFfREVCVUcoNCwgIiVzKCksIHJlbW92aW5nIGNsaWVudCFcbiIsIF9fRlVOQ1RJT05fXyk7CgloYXNoYmluX3JlbW92ZV90aGlzKGlybG1wLT5jbGllbnRzLCAoaXJkYV9xdWV1ZV90ICopIGNsaWVudCk7CglrZnJlZShjbGllbnQpOwoKCXJldHVybiAwOwp9CkVYUE9SVF9TWU1CT0woaXJsbXBfdW5yZWdpc3Rlcl9jbGllbnQpOwoKLyoKICogRnVuY3Rpb24gaXJsbXBfc2xzYXBfaW51c2UgKHNsc2FwKQogKgogKiAgICBDaGVjayBpZiB0aGUgZ2l2ZW4gc291cmNlIExTQVAgc2VsZWN0b3IgaXMgaW4gdXNlCiAqCiAqIFRoaXMgZnVuY3Rpb24gaXMgY2xlYXJseSBub3QgdmVyeSBlZmZpY2llbnQuIE9uIHRoZSBtaXRpZ2F0aW5nIHNpZGUsIHRoZQogKiBzdGFjayBtYWtlIHN1cmUgdGhhdCBpbiA5OSUgb2YgdGhlIGNhc2VzLCB3ZSBhcmUgY2FsbGVkIG9ubHkgb25jZQogKiBmb3IgZWFjaCBzb2NrZXQgYWxsb2NhdGlvbi4gV2UgY291bGQgcHJvYmFibHkga2VlcCBhIGJpdG1hcAogKiBvZiB0aGUgYWxsb2NhdGVkIExTQVAsIGJ1dCBJJ20gbm90IHN1cmUgdGhlIGNvbXBsZXhpdHkgaXMgd29ydGggaXQuCiAqIEplYW4gSUkKICovCnN0YXRpYyBpbnQgaXJsbXBfc2xzYXBfaW51c2UoX191OCBzbHNhcF9zZWwpCnsKCXN0cnVjdCBsc2FwX2NiICpzZWxmOwoJc3RydWN0IGxhcF9jYiAqbGFwOwoJdW5zaWduZWQgbG9uZyBmbGFnczsKCglJUkRBX0FTU0VSVChpcmxtcCAhPSBOVUxMLCByZXR1cm4gVFJVRTspOwoJSVJEQV9BU1NFUlQoaXJsbXAtPm1hZ2ljID09IExNUF9NQUdJQywgcmV0dXJuIFRSVUU7KTsKCUlSREFfQVNTRVJUKHNsc2FwX3NlbCAhPSBMU0FQX0FOWSwgcmV0dXJuIFRSVUU7KTsKCglJUkRBX0RFQlVHKDQsICIlcygpXG4iLCBfX0ZVTkNUSU9OX18pOwoKI2lmZGVmIENPTkZJR19JUkRBX1VMVFJBCgkvKiBBY2NlcHQgYWxsIGJpbmRpbmdzIHRvIHRoZSBjb25uZWN0aW9ubGVzcyBMU0FQICovCglpZiAoc2xzYXBfc2VsID09IExTQVBfQ09OTkxFU1MpCgkJcmV0dXJuIEZBTFNFOwojZW5kaWYgLyogQ09ORklHX0lSREFfVUxUUkEgKi8KCgkvKiBWYWxpZCB2YWx1ZXMgYXJlIGJldHdlZW4gMCBhbmQgMTI3ICgweDAtMHg2RikgKi8KCWlmIChzbHNhcF9zZWwgPiBMU0FQX01BWCkKCQlyZXR1cm4gVFJVRTsKCgkvKgoJICogIENoZWNrIGlmIHNsc2FwIGlzIGFscmVhZHkgaW4gdXNlLiBUbyBkbyB0aGlzIHdlIGhhdmUgdG8gbG9vcCBvdmVyCgkgKiAgZXZlcnkgSXJMQVAgY29ubmVjdGlvbiBhbmQgY2hlY2sgZXZlcnkgTFNBUCBhc3NvY2lhdGVkIHdpdGggZWFjaAoJICogIHRoZSBjb25uZWN0aW9uLgoJICovCglzcGluX2xvY2tfaXJxc2F2ZSgmaXJsbXAtPmxpbmtzLT5oYl9zcGlubG9jaywgZmxhZ3MpOwoJbGFwID0gKHN0cnVjdCBsYXBfY2IgKikgaGFzaGJpbl9nZXRfZmlyc3QoaXJsbXAtPmxpbmtzKTsKCXdoaWxlIChsYXAgIT0gTlVMTCkgewoJCUlSREFfQVNTRVJUKGxhcC0+bWFnaWMgPT0gTE1QX0xBUF9NQUdJQywgZ290byBlcnJsYXA7KTsKCgkJLyogQ2FyZWZ1bCBmb3IgcHJpb3JpdHkgaW52ZXJzaW9ucyBoZXJlICEKCQkgKiBpcmxtcC0+bGlua3MgaXMgbmV2ZXIgdGFrZW4gd2hpbGUgYW5vdGhlciBJckRBCgkJICogc3BpbmxvY2sgaXMgaGVsZCwgc28gd2UgYXJlIHNhZmUuIEplYW4gSUkgKi8KCQlzcGluX2xvY2soJmxhcC0+bHNhcHMtPmhiX3NwaW5sb2NrKTsKCgkJLyogRm9yIHRoaXMgSXJMQVAsIGNoZWNrIGFsbCB0aGUgTFNBUHMgKi8KCQlzZWxmID0gKHN0cnVjdCBsc2FwX2NiICopIGhhc2hiaW5fZ2V0X2ZpcnN0KGxhcC0+bHNhcHMpOwoJCXdoaWxlIChzZWxmICE9IE5VTEwpIHsKCQkJSVJEQV9BU1NFUlQoc2VsZi0+bWFnaWMgPT0gTE1QX0xTQVBfTUFHSUMsCgkJCQkgICAgZ290byBlcnJsc2FwOyk7CgoJCQlpZiAoKHNlbGYtPnNsc2FwX3NlbCA9PSBzbHNhcF9zZWwpKSB7CgkJCQlJUkRBX0RFQlVHKDQsICJTb3VyY2UgTFNBUCBzZWxlY3Rvcj0lMDJ4IGluIHVzZVxuIiwKCQkJCQkgICBzZWxmLT5zbHNhcF9zZWwpOwoJCQkJZ290byBlcnJsc2FwOwoJCQl9CgkJCXNlbGYgPSAoc3RydWN0IGxzYXBfY2IqKSBoYXNoYmluX2dldF9uZXh0KGxhcC0+bHNhcHMpOwoJCX0KCQlzcGluX3VubG9jaygmbGFwLT5sc2Fwcy0+aGJfc3BpbmxvY2spOwoKCQkvKiBOZXh0IExBUCAqLwoJCWxhcCA9IChzdHJ1Y3QgbGFwX2NiICopIGhhc2hiaW5fZ2V0X25leHQoaXJsbXAtPmxpbmtzKTsKCX0KCXNwaW5fdW5sb2NrX2lycXJlc3RvcmUoJmlybG1wLT5saW5rcy0+aGJfc3BpbmxvY2ssIGZsYWdzKTsKCgkvKgoJICogU2VydmVyIHNvY2tldHMgYXJlIHR5cGljYWxseSB3YWl0aW5nIGZvciBjb25uZWN0aW9ucyBhbmQKCSAqIHRoZXJlZm9yZSByZXNpZGUgaW4gdGhlIHVuY29ubmVjdGVkIGxpc3QuIFdlIGRvbid0IHdhbnQKCSAqIHRvIGdpdmUgb3V0IHRoZWlyIExTQVBzIGZvciBvYnZpb3VzIHJlYXNvbnMuLi4KCSAqIEplYW4gSUkKCSAqLwoJc3Bpbl9sb2NrX2lycXNhdmUoJmlybG1wLT51bmNvbm5lY3RlZF9sc2Fwcy0+aGJfc3BpbmxvY2ssIGZsYWdzKTsKCglzZWxmID0gKHN0cnVjdCBsc2FwX2NiICopIGhhc2hiaW5fZ2V0X2ZpcnN0KGlybG1wLT51bmNvbm5lY3RlZF9sc2Fwcyk7Cgl3aGlsZSAoc2VsZiAhPSBOVUxMKSB7CgkJSVJEQV9BU1NFUlQoc2VsZi0+bWFnaWMgPT0gTE1QX0xTQVBfTUFHSUMsIGdvdG8gZXJydW5jb247KTsKCQlpZiAoKHNlbGYtPnNsc2FwX3NlbCA9PSBzbHNhcF9zZWwpKSB7CgkJCUlSREFfREVCVUcoNCwgIlNvdXJjZSBMU0FQIHNlbGVjdG9yPSUwMnggaW4gdXNlICh1bmNvbm5lY3RlZClcbiIsCgkJCQkgICBzZWxmLT5zbHNhcF9zZWwpOwoJCQlnb3RvIGVycnVuY29uOwoJCX0KCQlzZWxmID0gKHN0cnVjdCBsc2FwX2NiKikgaGFzaGJpbl9nZXRfbmV4dChpcmxtcC0+dW5jb25uZWN0ZWRfbHNhcHMpOwoJfQoJc3Bpbl91bmxvY2tfaXJxcmVzdG9yZSgmaXJsbXAtPnVuY29ubmVjdGVkX2xzYXBzLT5oYl9zcGlubG9jaywgZmxhZ3MpOwoKCXJldHVybiBGQUxTRTsKCgkvKiBFcnJvciBleGl0IGZyb20gd2l0aGluIG9uZSBvZiB0aGUgdHdvIG5lc3RlZCBsb29wcy4KCSAqIE1ha2Ugc3VyZSB3ZSByZWxlYXNlIHRoZSByaWdodCBzcGlubG9jayBpbiB0aGUgcmlnaCBvcmRlci4KCSAqIEplYW4gSUkgKi8KZXJybHNhcDoKCXNwaW5fdW5sb2NrKCZsYXAtPmxzYXBzLT5oYl9zcGlubG9jayk7CklSREFfQVNTRVJUX0xBQkVMKGVycmxhcDopCglzcGluX3VubG9ja19pcnFyZXN0b3JlKCZpcmxtcC0+bGlua3MtPmhiX3NwaW5sb2NrLCBmbGFncyk7CglyZXR1cm4gVFJVRTsKCgkvKiBFcnJvciBleGl0IGZyb20gd2l0aGluIHRoZSB1bmNvbm5lY3RlZCBsb29wLgoJICogSnVzdCBvbmUgc3BpbmxvY2sgdG8gcmVsZWFzZS4uLiBKZWFuIElJICovCmVycnVuY29uOgoJc3Bpbl91bmxvY2tfaXJxcmVzdG9yZSgmaXJsbXAtPnVuY29ubmVjdGVkX2xzYXBzLT5oYl9zcGlubG9jaywgZmxhZ3MpOwoJcmV0dXJuIFRSVUU7Cn0KCi8qCiAqIEZ1bmN0aW9uIGlybG1wX2ZpbmRfZnJlZV9zbHNhcCAoKQogKgogKiAgICBGaW5kIGEgZnJlZSBzb3VyY2UgTFNBUCB0byB1c2UuIFRoaXMgZnVuY3Rpb24gaXMgY2FsbGVkIGlmIHRoZSBzZXJ2aWNlCiAqICAgIHVzZXIgaGFzIHJlcXVlc3RlZCBhIHNvdXJjZSBMU0FQIGVxdWFsIHRvIExNX0FOWQogKi8Kc3RhdGljIF9fdTggaXJsbXBfZmluZF9mcmVlX3Nsc2FwKHZvaWQpCnsKCV9fdTggbHNhcF9zZWw7CglpbnQgd3JhcHBlZCA9IDA7CgoJSVJEQV9BU1NFUlQoaXJsbXAgIT0gTlVMTCwgcmV0dXJuIC0xOyk7CglJUkRBX0FTU0VSVChpcmxtcC0+bWFnaWMgPT0gTE1QX01BR0lDLCByZXR1cm4gLTE7KTsKCgkvKiBNb3N0IHVzZXJzIGRvbid0IHJlYWxseSBjYXJlIHdoaWNoIExTQVBzIHRoZXkgYXJlIGdpdmVuLAoJICogYW5kIHRoZXJlZm9yZSB3ZSBhdXRvbWF0aWNhbGx5IGdpdmUgdGhlbSBhIGZyZWUgTFNBUC4KCSAqIFRoaXMgZnVuY3Rpb24gdHJ5IHRvIGZpbmQgYSBzdWl0YWJsZSBMU0FQLCBpLmUuIHdoaWNoIGlzCgkgKiBub3QgaW4gdXNlIGFuZCBpcyB3aXRoaW4gdGhlIGFjY2VwdGFibGUgcmFuZ2UuIEplYW4gSUkgKi8KCglkbyB7CgkJLyogQWx3YXlzIGluY3JlbWVudCB0byBMU0FQIG51bWJlciBiZWZvcmUgdXNpbmcgaXQuCgkJICogSW4gdGhlb3J5LCB3ZSBjb3VsZCByZXVzZSB0aGUgbGFzdCBMU0FQIG51bWJlciwgYXMgbG9uZwoJCSAqIGFzIGl0IGlzIG5vIGxvbmdlciBpbiB1c2UuIFNvbWUgSXJEQSBzdGFjayBkbyB0aGF0LgoJCSAqIEhvd2V2ZXIsIHRoZSBwcmV2aW91cyBzb2NrZXQgbWF5IGJlIGhhbGYgY2xvc2VkLCBpLmUuCgkJICogd2UgY2xvc2VkIGl0LCB3ZSB0aGluayBpdCdzIG5vIGxvbmdlciBpbiB1c2UsIGJ1dCB0aGUKCQkgKiBvdGhlciBzaWRlIGRpZCBub3QgcmVjZWl2ZSBvdXIgY2xvc2UgYW5kIHRoaW5rIGl0J3MKCQkgKiBhY3RpdmUgYW5kIHN0aWxsIHNlbmQgZGF0YSBvbiBpdC4KCQkgKiBUaGlzIGlzIHNpbWlsYXIgdG8gd2hhdCBpcyBkb25lIHdpdGggUElEcyBhbmQgVENQIHBvcnRzLgoJCSAqIEFsc28sIHRoaXMgcmVkdWNlIHRoZSBudW1iZXIgb2YgY2FsbHMgdG8gaXJsbXBfc2xzYXBfaW51c2UoKQoJCSAqIHdoaWNoIGlzIGFuIGV4cGVuc2l2ZSBmdW5jdGlvbiB0byBjYWxsLgoJCSAqIEplYW4gSUkgKi8KCQlpcmxtcC0+bGFzdF9sc2FwX3NlbCsrOwoKCQkvKiBDaGVjayBpZiB3ZSBuZWVkIHRvIHdyYXBhcm91bmQgKDB4NzAtMHg3ZiBhcmUgcmVzZXJ2ZWQpICovCgkJaWYgKGlybG1wLT5sYXN0X2xzYXBfc2VsID4gTFNBUF9NQVgpIHsKCQkJLyogMHgwMC0weDEwIGFyZSBhbHNvIHJlc2VydmVkIGZvciB3ZWxsIGtub3cgcG9ydHMgKi8KCQkJaXJsbXAtPmxhc3RfbHNhcF9zZWwgPSAweDEwOwoKCQkJLyogTWFrZSBzdXJlIHdlIHRlcm1pbmF0ZSB0aGUgbG9vcCAqLwoJCQlpZiAod3JhcHBlZCsrKSB7CgkJCQlJUkRBX0VSUk9SKCIlczogbm8gbW9yZSBmcmVlIExTQVBzICFcbiIsCgkJCQkJICAgX19GVU5DVElPTl9fKTsKCQkJCXJldHVybiAwOwoJCQl9CgkJfQoKCQkvKiBJZiB0aGUgTFNBUCBpcyBpbiB1c2UsIHRyeSB0aGUgbmV4dCBvbmUuCgkJICogRGVzcGl0ZSB0aGUgYXV0b2luY3JlbWVudCwgd2UgbmVlZCB0byBjaGVjayBpZiB0aGUgbHNhcAoJCSAqIGlzIHJlYWxseSBpbiB1c2Ugb3Igbm90LCBmaXJzdCBiZWNhdXNlIExTQVAgbWF5IGJlCgkJICogZGlyZWN0bHkgYWxsb2NhdGVkIGluIGlybG1wX29wZW5fbHNhcCgpLCBhbmQgYWxzbyBiZWNhdXNlCgkJICogd2UgbWF5IHdyYXBhcm91bmQgb24gb2xkIHNvY2tldHMuIEplYW4gSUkgKi8KCX0gd2hpbGUgKGlybG1wX3Nsc2FwX2ludXNlKGlybG1wLT5sYXN0X2xzYXBfc2VsKSk7CgoJLyogR290IGl0ICEgKi8KCWxzYXBfc2VsID0gaXJsbXAtPmxhc3RfbHNhcF9zZWw7CglJUkRBX0RFQlVHKDQsICIlcygpLCBmb3VuZCBmcmVlIGxzYXBfc2VsPSUwMnhcbiIsCgkJICAgX19GVU5DVElPTl9fLCBsc2FwX3NlbCk7CgoJcmV0dXJuIGxzYXBfc2VsOwp9CgovKgogKiBGdW5jdGlvbiBpcmxtcF9jb252ZXJ0X2xhcF9yZWFzb24gKGxhcF9yZWFzb24pCiAqCiAqICAgIENvbnZlcnRzIElyTEFQIGRpc2Nvbm5lY3QgcmVhc29uIGNvZGVzIHRvIElyTE1QIGRpc2Nvbm5lY3QgcmVhc29uCiAqICAgIGNvZGVzCiAqCiAqLwpMTV9SRUFTT04gaXJsbXBfY29udmVydF9sYXBfcmVhc29uKCBMQVBfUkVBU09OIGxhcF9yZWFzb24pCnsKCWludCByZWFzb24gPSBMTV9MQVBfRElTQ09OTkVDVDsKCglzd2l0Y2ggKGxhcF9yZWFzb24pIHsKCWNhc2UgTEFQX0RJU0NfSU5ESUNBVElPTjogLyogUmVjZWl2ZWQgYSBkaXNjb25uZWN0IHJlcXVlc3QgZnJvbSBwZWVyICovCgkJSVJEQV9ERUJVRyggMSwgIiVzKCksIExBUF9ESVNDX0lORElDQVRJT05cbiIsIF9fRlVOQ1RJT05fXyk7CgkJcmVhc29uID0gTE1fVVNFUl9SRVFVRVNUOwoJCWJyZWFrOwoJY2FzZSBMQVBfTk9fUkVTUE9OU0U6ICAgIC8qIFRvIG1hbnkgcmV0cmFuc21pdHMgd2l0aG91dCByZXNwb25zZSAqLwoJCUlSREFfREVCVUcoIDEsICIlcygpLCBMQVBfTk9fUkVTUE9OU0VcbiIsIF9fRlVOQ1RJT05fXyk7CgkJcmVhc29uID0gTE1fTEFQX0RJU0NPTk5FQ1Q7CgkJYnJlYWs7CgljYXNlIExBUF9SRVNFVF9JTkRJQ0FUSU9OOgoJCUlSREFfREVCVUcoIDEsICIlcygpLCBMQVBfUkVTRVRfSU5ESUNBVElPTlxuIiwgX19GVU5DVElPTl9fKTsKCQlyZWFzb24gPSBMTV9MQVBfUkVTRVQ7CgkJYnJlYWs7CgljYXNlIExBUF9GT1VORF9OT05FOgoJY2FzZSBMQVBfTUVESUFfQlVTWToKCWNhc2UgTEFQX1BSSU1BUllfQ09ORkxJQ1Q6CgkJSVJEQV9ERUJVRygxLCAiJXMoKSwgTEFQX0ZPVU5EX05PTkUsIExBUF9NRURJQV9CVVNZIG9yIExBUF9QUklNQVJZX0NPTkZMSUNUXG4iLCBfX0ZVTkNUSU9OX18pOwoJCXJlYXNvbiA9IExNX0NPTk5FQ1RfRkFJTFVSRTsKCQlicmVhazsKCWRlZmF1bHQ6CgkJSVJEQV9ERUJVRygxLCAiJXMoKSwgVW5rbm93IElyTEFQIGRpc2Nvbm5lY3QgcmVhc29uICVkIVxuIiwKCQkJICAgX19GVU5DVElPTl9fLCBsYXBfcmVhc29uKTsKCQlyZWFzb24gPSBMTV9MQVBfRElTQ09OTkVDVDsKCQlicmVhazsKCX0KCglyZXR1cm4gcmVhc29uOwp9CgojaWZkZWYgQ09ORklHX1BST0NfRlMKCnN0cnVjdCBpcmxtcF9pdGVyX3N0YXRlIHsKCWhhc2hiaW5fdCAqaGFzaGJpbjsKfTsKCiNkZWZpbmUgTFNBUF9TVEFSVF9UT0tFTgkoKHZvaWQgKikxKQojZGVmaW5lIExJTktfU1RBUlRfVE9LRU4JKCh2b2lkICopMikKCnN0YXRpYyB2b2lkICppcmxtcF9zZXFfaGJfaWR4KHN0cnVjdCBpcmxtcF9pdGVyX3N0YXRlICppdGVyLCBsb2ZmX3QgKm9mZikKewoJdm9pZCAqZWxlbWVudDsKCglzcGluX2xvY2tfaXJxKCZpdGVyLT5oYXNoYmluLT5oYl9zcGlubG9jayk7Cglmb3IgKGVsZW1lbnQgPSBoYXNoYmluX2dldF9maXJzdChpdGVyLT5oYXNoYmluKTsKCSAgICAgZWxlbWVudCAhPSBOVUxMOyAKCSAgICAgZWxlbWVudCA9IGhhc2hiaW5fZ2V0X25leHQoaXRlci0+aGFzaGJpbikpIHsKCQlpZiAoIW9mZiB8fCAqb2ZmLS0gPT0gMCkgewoJCQkvKiBOQjogaGFzaGJpbiBsZWZ0IGxvY2tlZCAqLwoJCQlyZXR1cm4gZWxlbWVudDsKCQl9Cgl9CglzcGluX3VubG9ja19pcnEoJml0ZXItPmhhc2hiaW4tPmhiX3NwaW5sb2NrKTsKCWl0ZXItPmhhc2hiaW4gPSBOVUxMOwoJcmV0dXJuIE5VTEw7Cn0KCgpzdGF0aWMgdm9pZCAqaXJsbXBfc2VxX3N0YXJ0KHN0cnVjdCBzZXFfZmlsZSAqc2VxLCBsb2ZmX3QgKnBvcykKewoJc3RydWN0IGlybG1wX2l0ZXJfc3RhdGUgKml0ZXIgPSBzZXEtPnByaXZhdGU7Cgl2b2lkICp2OwoJbG9mZl90IG9mZiA9ICpwb3M7CgoJaXRlci0+aGFzaGJpbiA9IE5VTEw7CglpZiAob2ZmLS0gPT0gMCkKCQlyZXR1cm4gTFNBUF9TVEFSVF9UT0tFTjsKCglpdGVyLT5oYXNoYmluID0gaXJsbXAtPnVuY29ubmVjdGVkX2xzYXBzOwoJdiA9IGlybG1wX3NlcV9oYl9pZHgoaXRlciwgJm9mZik7CglpZiAodikKCQlyZXR1cm4gdjsKCglpZiAob2ZmLS0gPT0gMCkKCQlyZXR1cm4gTElOS19TVEFSVF9UT0tFTjsKCglpdGVyLT5oYXNoYmluID0gaXJsbXAtPmxpbmtzOwoJcmV0dXJuIGlybG1wX3NlcV9oYl9pZHgoaXRlciwgJm9mZik7Cn0KCnN0YXRpYyB2b2lkICppcmxtcF9zZXFfbmV4dChzdHJ1Y3Qgc2VxX2ZpbGUgKnNlcSwgdm9pZCAqdiwgbG9mZl90ICpwb3MpCnsKCXN0cnVjdCBpcmxtcF9pdGVyX3N0YXRlICppdGVyID0gc2VxLT5wcml2YXRlOwoKCSsrKnBvczsKCglpZiAodiA9PSBMU0FQX1NUQVJUX1RPS0VOKSB7CQkvKiBzdGFydCBvZiBsaXN0IG9mIGxzYXBzICovCgkJaXRlci0+aGFzaGJpbiA9IGlybG1wLT51bmNvbm5lY3RlZF9sc2FwczsKCQl2ID0gaXJsbXBfc2VxX2hiX2lkeChpdGVyLCBOVUxMKTsKCQlyZXR1cm4gdiA/IHYgOiBMSU5LX1NUQVJUX1RPS0VOOwoJfQoKCWlmICh2ID09IExJTktfU1RBUlRfVE9LRU4pIHsJCS8qIHN0YXJ0IG9mIGxpc3Qgb2YgbGlua3MgKi8KCQlpdGVyLT5oYXNoYmluID0gaXJsbXAtPmxpbmtzOwoJCXJldHVybiBpcmxtcF9zZXFfaGJfaWR4KGl0ZXIsIE5VTEwpOwoJfQoKCXYgPSBoYXNoYmluX2dldF9uZXh0KGl0ZXItPmhhc2hiaW4pOwoKCWlmICh2ID09IE5VTEwpIHsJCQkvKiBubyBtb3JlIGluIHRoaXMgaGFzaCBiaW4gKi8KCQlzcGluX3VubG9ja19pcnEoJml0ZXItPmhhc2hiaW4tPmhiX3NwaW5sb2NrKTsKCgkJaWYgKGl0ZXItPmhhc2hiaW4gPT0gaXJsbXAtPnVuY29ubmVjdGVkX2xzYXBzKSAKCQkJdiA9ICBMSU5LX1NUQVJUX1RPS0VOOwoKCQlpdGVyLT5oYXNoYmluID0gTlVMTDsKCX0KCXJldHVybiB2Owp9CgpzdGF0aWMgdm9pZCBpcmxtcF9zZXFfc3RvcChzdHJ1Y3Qgc2VxX2ZpbGUgKnNlcSwgdm9pZCAqdikKewoJc3RydWN0IGlybG1wX2l0ZXJfc3RhdGUgKml0ZXIgPSBzZXEtPnByaXZhdGU7CgoJaWYgKGl0ZXItPmhhc2hiaW4pCgkJc3Bpbl91bmxvY2tfaXJxKCZpdGVyLT5oYXNoYmluLT5oYl9zcGlubG9jayk7Cn0KCnN0YXRpYyBpbnQgaXJsbXBfc2VxX3Nob3coc3RydWN0IHNlcV9maWxlICpzZXEsIHZvaWQgKnYpCnsKCWNvbnN0IHN0cnVjdCBpcmxtcF9pdGVyX3N0YXRlICppdGVyID0gc2VxLT5wcml2YXRlOwoJc3RydWN0IGxzYXBfY2IgKnNlbGYgPSB2OwoKCWlmICh2ID09IExTQVBfU1RBUlRfVE9LRU4pCgkJc2VxX3B1dHMoc2VxLCAiVW5jb25uZWN0ZWQgTFNBUHM6XG4iKTsKCWVsc2UgaWYgKHYgPT0gTElOS19TVEFSVF9UT0tFTikKCQlzZXFfcHV0cyhzZXEsICJcblJlZ2lzdGVyZWQgTGluayBMYXllcnM6XG4iKTsKCWVsc2UgaWYgKGl0ZXItPmhhc2hiaW4gPT0gaXJsbXAtPnVuY29ubmVjdGVkX2xzYXBzKSB7CgkJc2VsZiA9IHY7CgkJSVJEQV9BU1NFUlQoc2VsZi0+bWFnaWMgPT0gTE1QX0xTQVBfTUFHSUMsIHJldHVybiAtRUlOVkFMOyApOwoJCXNlcV9wcmludGYoc2VxLCAibHNhcCBzdGF0ZTogJXMsICIsCgkJCSAgIGlybHNhcF9zdGF0ZVsgc2VsZi0+bHNhcF9zdGF0ZV0pOwoJCXNlcV9wcmludGYoc2VxLAoJCQkgICAic2xzYXBfc2VsOiAlIzAyeCwgZGxzYXBfc2VsOiAlIzAyeCwgIiwKCQkJICAgc2VsZi0+c2xzYXBfc2VsLCBzZWxmLT5kbHNhcF9zZWwpOwoJCXNlcV9wcmludGYoc2VxLCAiKCVzKSIsIHNlbGYtPm5vdGlmeS5uYW1lKTsKCQlzZXFfcHJpbnRmKHNlcSwgIlxuIik7Cgl9IGVsc2UgaWYgKGl0ZXItPmhhc2hiaW4gPT0gaXJsbXAtPmxpbmtzKSB7CgkJc3RydWN0IGxhcF9jYiAqbGFwID0gdjsKCgkJc2VxX3ByaW50ZihzZXEsICJsYXAgc3RhdGU6ICVzLCAiLAoJCQkgICBpcmxtcF9zdGF0ZVtsYXAtPmxhcF9zdGF0ZV0pOwoKCQlzZXFfcHJpbnRmKHNlcSwgInNhZGRyOiAlIzA4eCwgZGFkZHI6ICUjMDh4LCAiLAoJCQkgICBsYXAtPnNhZGRyLCBsYXAtPmRhZGRyKTsKCQlzZXFfcHJpbnRmKHNlcSwgIm51bSBsc2FwczogJWQiLAoJCQkgICBIQVNIQklOX0dFVF9TSVpFKGxhcC0+bHNhcHMpKTsKCQlzZXFfcHJpbnRmKHNlcSwgIlxuIik7CgoJCS8qIENhcmVmdWwgZm9yIHByaW9yaXR5IGludmVyc2lvbnMgaGVyZSAhCgkJICogQWxsIG90aGVyIHVzZXMgb2YgYXR0cmliIHNwaW5sb2NrIGFyZSBpbmRlcGVuZGVudCBvZgoJCSAqIHRoZSBvYmplY3Qgc3BpbmxvY2ssIHNvIHdlIGFyZSBzYWZlLiBKZWFuIElJICovCgkJc3Bpbl9sb2NrKCZsYXAtPmxzYXBzLT5oYl9zcGlubG9jayk7CgoJCXNlcV9wcmludGYoc2VxLCAiXG4gIENvbm5lY3RlZCBMU0FQczpcbiIpOwoJCWZvciAoc2VsZiA9IChzdHJ1Y3QgbHNhcF9jYiAqKSBoYXNoYmluX2dldF9maXJzdChsYXAtPmxzYXBzKTsKCQkgICAgIHNlbGYgIT0gTlVMTDsKCQkgICAgIHNlbGYgPSAoc3RydWN0IGxzYXBfY2IgKiloYXNoYmluX2dldF9uZXh0KGxhcC0+bHNhcHMpKSB7CgkJCUlSREFfQVNTRVJUKHNlbGYtPm1hZ2ljID09IExNUF9MU0FQX01BR0lDLAoJCQkJICAgIGdvdG8gb3V0bG9vcDspOwoJCQlzZXFfcHJpbnRmKHNlcSwgIiAgbHNhcCBzdGF0ZTogJXMsICIsCgkJCQkgICBpcmxzYXBfc3RhdGVbIHNlbGYtPmxzYXBfc3RhdGVdKTsKCQkJc2VxX3ByaW50ZihzZXEsCgkJCQkgICAic2xzYXBfc2VsOiAlIzAyeCwgZGxzYXBfc2VsOiAlIzAyeCwgIiwKCQkJCSAgIHNlbGYtPnNsc2FwX3NlbCwgc2VsZi0+ZGxzYXBfc2VsKTsKCQkJc2VxX3ByaW50ZihzZXEsICIoJXMpIiwgc2VsZi0+bm90aWZ5Lm5hbWUpOwoJCQlzZXFfcHV0YyhzZXEsICdcbicpOwoKCQl9CglJUkRBX0FTU0VSVF9MQUJFTChvdXRsb29wOikKCQlzcGluX3VubG9jaygmbGFwLT5sc2Fwcy0+aGJfc3BpbmxvY2spOwoJCXNlcV9wdXRjKHNlcSwgJ1xuJyk7Cgl9IGVsc2UKCQlyZXR1cm4gLUVJTlZBTDsKCglyZXR1cm4gMDsKfQoKc3RhdGljIHN0cnVjdCBzZXFfb3BlcmF0aW9ucyBpcmxtcF9zZXFfb3BzID0gewoJLnN0YXJ0ICA9IGlybG1wX3NlcV9zdGFydCwKCS5uZXh0ICAgPSBpcmxtcF9zZXFfbmV4dCwKCS5zdG9wICAgPSBpcmxtcF9zZXFfc3RvcCwKCS5zaG93ICAgPSBpcmxtcF9zZXFfc2hvdywKfTsKCnN0YXRpYyBpbnQgaXJsbXBfc2VxX29wZW4oc3RydWN0IGlub2RlICppbm9kZSwgc3RydWN0IGZpbGUgKmZpbGUpCnsKCXN0cnVjdCBzZXFfZmlsZSAqc2VxOwoJaW50IHJjID0gLUVOT01FTTsKCXN0cnVjdCBpcmxtcF9pdGVyX3N0YXRlICpzOwoKCUlSREFfQVNTRVJUKGlybG1wICE9IE5VTEwsIHJldHVybiAtRUlOVkFMOyk7CgoJcyA9IGttYWxsb2Moc2l6ZW9mKCpzKSwgR0ZQX0tFUk5FTCk7CglpZiAoIXMpCgkJZ290byBvdXQ7CgoJcmMgPSBzZXFfb3BlbihmaWxlLCAmaXJsbXBfc2VxX29wcyk7CglpZiAocmMpCgkJZ290byBvdXRfa2ZyZWU7CgoJc2VxCSAgICAgPSBmaWxlLT5wcml2YXRlX2RhdGE7CglzZXEtPnByaXZhdGUgPSBzOwpvdXQ6CglyZXR1cm4gcmM7Cm91dF9rZnJlZToKCWtmcmVlKHMpOwoJZ290byBvdXQ7Cn0KCnN0cnVjdCBmaWxlX29wZXJhdGlvbnMgaXJsbXBfc2VxX2ZvcHMgPSB7Cgkub3duZXIJCT0gVEhJU19NT0RVTEUsCgkub3BlbiAgICAgICAgICAgPSBpcmxtcF9zZXFfb3BlbiwKCS5yZWFkICAgICAgICAgICA9IHNlcV9yZWFkLAoJLmxsc2VlayAgICAgICAgID0gc2VxX2xzZWVrLAoJLnJlbGVhc2UJPSBzZXFfcmVsZWFzZV9wcml2YXRlLAp9OwoKI2VuZGlmIC8qIFBST0NfRlMgKi8K