LyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgogKiBGaWxlbmFtZTogICAgICBpcmlhcC5jCiAqIFZlcnNpb246ICAgICAgIDAuOAogKiBEZXNjcmlwdGlvbjogICBJbmZvcm1hdGlvbiBBY2Nlc3MgUHJvdG9jb2wgKElBUCkKICogU3RhdHVzOiAgICAgICAgRXhwZXJpbWVudGFsLgogKiBBdXRob3I6ICAgICAgICBEYWcgQnJhdHRsaSA8ZGFnYkBjcy51aXQubm8+CiAqIENyZWF0ZWQgYXQ6ICAgIFRodSBBdWcgMjEgMDA6MDI6MDcgMTk5NwogKiBNb2RpZmllZCBhdDogICBTYXQgRGVjIDI1IDE2OjQyOjQyIDE5OTkKICogTW9kaWZpZWQgYnk6ICAgRGFnIEJyYXR0bGkgPGRhZ2JAY3MudWl0Lm5vPgogKgogKiAgICAgQ29weXJpZ2h0IChjKSAxOTk4LTE5OTkgRGFnIEJyYXR0bGkgPGRhZ2JAY3MudWl0Lm5vPiwKICogICAgIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqICAgICBDb3B5cmlnaHQgKGMpIDIwMDAtMjAwMyBKZWFuIFRvdXJyaWxoZXMgPGp0QGhwbC5ocC5jb20+CiAqCiAqICAgICBUaGlzIHByb2dyYW0gaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yCiAqICAgICBtb2RpZnkgaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBhcwogKiAgICAgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlciB2ZXJzaW9uIDIgb2YKICogICAgIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLgogKgogKiAgICAgTmVpdGhlciBEYWcgQnJhdHRsaSBub3IgVW5pdmVyc2l0eSBvZiBUcm9tc/ggYWRtaXQgbGlhYmlsaXR5IG5vcgogKiAgICAgcHJvdmlkZSB3YXJyYW50eSBmb3IgYW55IG9mIHRoaXMgc29mdHdhcmUuIFRoaXMgbWF0ZXJpYWwgaXMKICogICAgIHByb3ZpZGVkICJBUy1JUyIgYW5kIGF0IG5vIGNoYXJnZS4KICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKI2luY2x1ZGUgPGxpbnV4L21vZHVsZS5oPgojaW5jbHVkZSA8bGludXgvdHlwZXMuaD4KI2luY2x1ZGUgPGxpbnV4L3NrYnVmZi5oPgojaW5jbHVkZSA8bGludXgvZnMuaD4KI2luY2x1ZGUgPGxpbnV4L3N0cmluZy5oPgojaW5jbHVkZSA8bGludXgvaW5pdC5oPgojaW5jbHVkZSA8bGludXgvc2VxX2ZpbGUuaD4KCiNpbmNsdWRlIDxhc20vYnl0ZW9yZGVyLmg+CiNpbmNsdWRlIDxhc20vdW5hbGlnbmVkLmg+CgojaW5jbHVkZSA8bmV0L2lyZGEvaXJkYS5oPgojaW5jbHVkZSA8bmV0L2lyZGEvaXJ0dHAuaD4KI2luY2x1ZGUgPG5ldC9pcmRhL2lybG1wLmg+CiNpbmNsdWRlIDxuZXQvaXJkYS9pcmlhc19vYmplY3QuaD4KI2luY2x1ZGUgPG5ldC9pcmRhL2lyaWFwX2V2ZW50Lmg+CiNpbmNsdWRlIDxuZXQvaXJkYS9pcmlhcC5oPgoKI2lmZGVmIENPTkZJR19JUkRBX0RFQlVHCi8qIEZJWE1FOiBUaGlzIG9uZSBzaG91bGQgZ28gaW4gaXJsbXAuYyAqLwpzdGF0aWMgY29uc3QgY2hhciAqaWFzX2NoYXJzZXRfdHlwZXNbXSA9IHsKCSJDU19BU0NJSSIsCgkiQ1NfSVNPXzg4NTlfMSIsCgkiQ1NfSVNPXzg4NTlfMiIsCgkiQ1NfSVNPXzg4NTlfMyIsCgkiQ1NfSVNPXzg4NTlfNCIsCgkiQ1NfSVNPXzg4NTlfNSIsCgkiQ1NfSVNPXzg4NTlfNiIsCgkiQ1NfSVNPXzg4NTlfNyIsCgkiQ1NfSVNPXzg4NTlfOCIsCgkiQ1NfSVNPXzg4NTlfOSIsCgkiQ1NfVU5JQ09ERSIKfTsKI2VuZGlmCS8qIENPTkZJR19JUkRBX0RFQlVHICovCgpzdGF0aWMgaGFzaGJpbl90ICppcmlhcCA9IE5VTEw7CnN0YXRpYyB2b2lkICpzZXJ2aWNlX2hhbmRsZTsKCnN0YXRpYyB2b2lkIF9faXJpYXBfY2xvc2Uoc3RydWN0IGlyaWFwX2NiICpzZWxmKTsKc3RhdGljIGludCBpcmlhcF9yZWdpc3Rlcl9sc2FwKHN0cnVjdCBpcmlhcF9jYiAqc2VsZiwgX191OCBzbHNhcF9zZWwsIGludCBtb2RlKTsKc3RhdGljIHZvaWQgaXJpYXBfZGlzY29ubmVjdF9pbmRpY2F0aW9uKHZvaWQgKmluc3RhbmNlLCB2b2lkICpzYXAsCgkJCQkJTE1fUkVBU09OIHJlYXNvbiwgc3RydWN0IHNrX2J1ZmYgKnNrYik7CnN0YXRpYyB2b2lkIGlyaWFwX2Nvbm5lY3RfaW5kaWNhdGlvbih2b2lkICppbnN0YW5jZSwgdm9pZCAqc2FwLAoJCQkJICAgICBzdHJ1Y3QgcW9zX2luZm8gKnFvcywgX191MzIgbWF4X3NkdV9zaXplLAoJCQkJICAgICBfX3U4IG1heF9oZWFkZXJfc2l6ZSwKCQkJCSAgICAgc3RydWN0IHNrX2J1ZmYgKnNrYik7CnN0YXRpYyB2b2lkIGlyaWFwX2Nvbm5lY3RfY29uZmlybSh2b2lkICppbnN0YW5jZSwgdm9pZCAqc2FwLAoJCQkJICBzdHJ1Y3QgcW9zX2luZm8gKnFvcywKCQkJCSAgX191MzIgbWF4X3NkdV9zaXplLCBfX3U4IG1heF9oZWFkZXJfc2l6ZSwKCQkJCSAgc3RydWN0IHNrX2J1ZmYgKnNrYik7CnN0YXRpYyBpbnQgaXJpYXBfZGF0YV9pbmRpY2F0aW9uKHZvaWQgKmluc3RhbmNlLCB2b2lkICpzYXAsCgkJCQkgc3RydWN0IHNrX2J1ZmYgKnNrYik7CgpzdGF0aWMgdm9pZCBpcmlhcF93YXRjaGRvZ190aW1lcl9leHBpcmVkKHZvaWQgKmRhdGEpOwoKc3RhdGljIGlubGluZSB2b2lkIGlyaWFwX3N0YXJ0X3dhdGNoZG9nX3RpbWVyKHN0cnVjdCBpcmlhcF9jYiAqc2VsZiwKCQkJCQkgICAgICBpbnQgdGltZW91dCkKewoJaXJkYV9zdGFydF90aW1lcigmc2VsZi0+d2F0Y2hkb2dfdGltZXIsIHRpbWVvdXQsIHNlbGYsCgkJCSBpcmlhcF93YXRjaGRvZ190aW1lcl9leHBpcmVkKTsKfQoKLyoKICogRnVuY3Rpb24gaXJpYXBfaW5pdCAodm9pZCkKICoKICogICAgSW5pdGlhbGl6ZXMgdGhlIElySUFQIGxheWVyLCBjYWxsZWQgYnkgdGhlIG1vZHVsZSBpbml0aWFsaXphdGlvbiBjb2RlCiAqICAgIGluIGlybW9kLmMKICovCmludCBfX2luaXQgaXJpYXBfaW5pdCh2b2lkKQp7CglzdHJ1Y3QgaWFzX29iamVjdCAqb2JqOwoJc3RydWN0IGlyaWFwX2NiICpzZXJ2ZXI7CglfX3U4IG9jdF9zZXFbNl07CglfX3UxNiBoaW50czsKCgkvKiBBbGxvY2F0ZSBtYXN0ZXIgYXJyYXkgKi8KCWlyaWFwID0gaGFzaGJpbl9uZXcoSEJfTE9DSyk7CglpZiAoIWlyaWFwKQoJCXJldHVybiAtRU5PTUVNOwoKCS8qIE9iamVjdCByZXBvc2l0b3J5IC0gZGVmaW5lZCBpbiBpcmlhc19vYmplY3QuYyAqLwoJaXJpYXNfb2JqZWN0cyA9IGhhc2hiaW5fbmV3KEhCX0xPQ0spOwoJaWYgKCFpcmlhc19vYmplY3RzKSB7CgkJSVJEQV9XQVJOSU5HKCIlczogQ2FuJ3QgYWxsb2NhdGUgaXJpYXNfb2JqZWN0cyBoYXNoYmluIVxuIiwKCQkJICAgICBfX0ZVTkNUSU9OX18pOwoJCWhhc2hiaW5fZGVsZXRlKGlyaWFwLCBOVUxMKTsKCQlyZXR1cm4gLUVOT01FTTsKCX0KCgkvKgoJICogIFJlZ2lzdGVyIHNvbWUgZGVmYXVsdCBzZXJ2aWNlcyBmb3IgSXJMTVAKCSAqLwoJaGludHMgID0gaXJsbXBfc2VydmljZV90b19oaW50KFNfQ09NUFVURVIpOwoJc2VydmljZV9oYW5kbGUgPSBpcmxtcF9yZWdpc3Rlcl9zZXJ2aWNlKGhpbnRzKTsKCgkvKiBSZWdpc3RlciB0aGUgRGV2aWNlIG9iamVjdCB3aXRoIExNLUlBUyAqLwoJb2JqID0gaXJpYXNfbmV3X29iamVjdCgiRGV2aWNlIiwgSUFTX0RFVklDRV9JRCk7Cglpcmlhc19hZGRfc3RyaW5nX2F0dHJpYihvYmosICJEZXZpY2VOYW1lIiwgIkxpbnV4IiwgSUFTX0tFUk5FTF9BVFRSKTsKCglvY3Rfc2VxWzBdID0gMHgwMTsgIC8qIFZlcnNpb24gMSAqLwoJb2N0X3NlcVsxXSA9IDB4MDA7ICAvKiBJQVMgc3VwcG9ydCBiaXRzICovCglvY3Rfc2VxWzJdID0gMHgwMDsgIC8qIExNLU1VWCBzdXBwb3J0IGJpdHMgKi8KI2lmZGVmIENPTkZJR19JUkRBX1VMVFJBCglvY3Rfc2VxWzJdIHw9IDB4MDQ7IC8qIENvbm5lY3Rpb25sZXNzIERhdGEgc3VwcG9ydCAqLwojZW5kaWYKCWlyaWFzX2FkZF9vY3RzZXFfYXR0cmliKG9iaiwgIklyTE1QU3VwcG9ydCIsIG9jdF9zZXEsIDMsCgkJCQlJQVNfS0VSTkVMX0FUVFIpOwoJaXJpYXNfaW5zZXJ0X29iamVjdChvYmopOwoKCS8qCgkgKiAgUmVnaXN0ZXIgc2VydmVyIHN1cHBvcnQgd2l0aCBJckxNUCBzbyB3ZSBjYW4gYWNjZXB0IGluY29taW5nCgkgKiAgY29ubmVjdGlvbnMKCSAqLwoJc2VydmVyID0gaXJpYXBfb3BlbihMU0FQX0lBUywgSUFTX1NFUlZFUiwgTlVMTCwgTlVMTCk7CglpZiAoIXNlcnZlcikgewoJCUlSREFfREVCVUcoMCwgIiVzKCksIHVuYWJsZSB0byBvcGVuIHNlcnZlclxuIiwgX19GVU5DVElPTl9fKTsKCQlyZXR1cm4gLTE7Cgl9CglpcmlhcF9yZWdpc3Rlcl9sc2FwKHNlcnZlciwgTFNBUF9JQVMsIElBU19TRVJWRVIpOwoKCXJldHVybiAwOwp9CgovKgogKiBGdW5jdGlvbiBpcmlhcF9jbGVhbnVwICh2b2lkKQogKgogKiAgICBJbml0aWFsaXplcyB0aGUgSXJJQVAgbGF5ZXIsIGNhbGxlZCBieSB0aGUgbW9kdWxlIGNsZWFudXAgY29kZSBpbgogKiAgICBpcm1vZC5jCiAqLwp2b2lkIF9fZXhpdCBpcmlhcF9jbGVhbnVwKHZvaWQpCnsKCWlybG1wX3VucmVnaXN0ZXJfc2VydmljZShzZXJ2aWNlX2hhbmRsZSk7CgoJaGFzaGJpbl9kZWxldGUoaXJpYXAsIChGUkVFX0ZVTkMpIF9faXJpYXBfY2xvc2UpOwoJaGFzaGJpbl9kZWxldGUoaXJpYXNfb2JqZWN0cywgKEZSRUVfRlVOQykgX19pcmlhc19kZWxldGVfb2JqZWN0KTsKfQoKLyoKICogRnVuY3Rpb24gaXJpYXBfb3BlbiAodm9pZCkKICoKICogICAgT3BlbnMgYW4gaW5zdGFuY2Ugb2YgdGhlIElySUFQIGxheWVyLCBhbmQgcmVnaXN0ZXJzIHdpdGggSXJMTVAKICovCnN0cnVjdCBpcmlhcF9jYiAqaXJpYXBfb3BlbihfX3U4IHNsc2FwX3NlbCwgaW50IG1vZGUsIHZvaWQgKnByaXYsCgkJCSAgICBDT05GSVJNX0NBTExCQUNLIGNhbGxiYWNrKQp7CglzdHJ1Y3QgaXJpYXBfY2IgKnNlbGY7CgoJSVJEQV9ERUJVRygyLCAiJXMoKVxuIiwgX19GVU5DVElPTl9fKTsKCglzZWxmID0ga3phbGxvYyhzaXplb2YoKnNlbGYpLCBHRlBfQVRPTUlDKTsKCWlmICghc2VsZikgewoJCUlSREFfV0FSTklORygiJXM6IFVuYWJsZSB0byBrbWFsbG9jIVxuIiwgX19GVU5DVElPTl9fKTsKCQlyZXR1cm4gTlVMTDsKCX0KCgkvKgoJICogIEluaXRpYWxpemUgaW5zdGFuY2UKCSAqLwoKCXNlbGYtPm1hZ2ljID0gSUFTX01BR0lDOwoJc2VsZi0+bW9kZSA9IG1vZGU7CglpZiAobW9kZSA9PSBJQVNfQ0xJRU5UKQoJCWlyaWFwX3JlZ2lzdGVyX2xzYXAoc2VsZiwgc2xzYXBfc2VsLCBtb2RlKTsKCglzZWxmLT5jb25maXJtID0gY2FsbGJhY2s7CglzZWxmLT5wcml2ID0gcHJpdjsKCgkvKiBpcmlhcF9nZXR2YWx1ZWJ5Y2xhc3NfcmVxdWVzdCgpIHdpbGwgY29uc3RydWN0IHBhY2tldHMgYmVmb3JlCgkgKiB3ZSBjb25uZWN0LCBzbyB0aGlzIG11c3QgaGF2ZSBhIHNhbmUgdmFsdWUuLi4gSmVhbiBJSSAqLwoJc2VsZi0+bWF4X2hlYWRlcl9zaXplID0gTE1QX01BWF9IRUFERVI7CgoJaW5pdF90aW1lcigmc2VsZi0+d2F0Y2hkb2dfdGltZXIpOwoKCWhhc2hiaW5faW5zZXJ0KGlyaWFwLCAoaXJkYV9xdWV1ZV90ICopIHNlbGYsIChsb25nKSBzZWxmLCBOVUxMKTsKCgkvKiBJbml0aWFsaXplIHN0YXRlIG1hY2hpbmVzICovCglpcmlhcF9uZXh0X2NsaWVudF9zdGF0ZShzZWxmLCBTX0RJU0NPTk5FQ1QpOwoJaXJpYXBfbmV4dF9jYWxsX3N0YXRlKHNlbGYsIFNfTUFLRV9DQUxMKTsKCWlyaWFwX25leHRfc2VydmVyX3N0YXRlKHNlbGYsIFJfRElTQ09OTkVDVCk7CglpcmlhcF9uZXh0X3JfY29ubmVjdF9zdGF0ZShzZWxmLCBSX1dBSVRJTkcpOwoKCXJldHVybiBzZWxmOwp9CkVYUE9SVF9TWU1CT0woaXJpYXBfb3Blbik7CgovKgogKiBGdW5jdGlvbiBfX2lyaWFwX2Nsb3NlIChzZWxmKQogKgogKiAgICBSZW1vdmVzIChkZWFsbG9jYXRlcykgdGhlIElySUFQIGluc3RhbmNlCiAqCiAqLwpzdGF0aWMgdm9pZCBfX2lyaWFwX2Nsb3NlKHN0cnVjdCBpcmlhcF9jYiAqc2VsZikKewoJSVJEQV9ERUJVRyg0LCAiJXMoKVxuIiwgX19GVU5DVElPTl9fKTsKCglJUkRBX0FTU0VSVChzZWxmICE9IE5VTEwsIHJldHVybjspOwoJSVJEQV9BU1NFUlQoc2VsZi0+bWFnaWMgPT0gSUFTX01BR0lDLCByZXR1cm47KTsKCglkZWxfdGltZXIoJnNlbGYtPndhdGNoZG9nX3RpbWVyKTsKCglpZiAoc2VsZi0+cmVxdWVzdF9za2IpCgkJZGV2X2tmcmVlX3NrYihzZWxmLT5yZXF1ZXN0X3NrYik7CgoJc2VsZi0+bWFnaWMgPSAwOwoKCWtmcmVlKHNlbGYpOwp9CgovKgogKiBGdW5jdGlvbiBpcmlhcF9jbG9zZSAodm9pZCkKICoKICogICAgQ2xvc2VzIElySUFQIGFuZCBkZXJlZ2lzdGVycyB3aXRoIElyTE1QCiAqLwp2b2lkIGlyaWFwX2Nsb3NlKHN0cnVjdCBpcmlhcF9jYiAqc2VsZikKewoJc3RydWN0IGlyaWFwX2NiICplbnRyeTsKCglJUkRBX0RFQlVHKDIsICIlcygpXG4iLCBfX0ZVTkNUSU9OX18pOwoKCUlSREFfQVNTRVJUKHNlbGYgIT0gTlVMTCwgcmV0dXJuOyk7CglJUkRBX0FTU0VSVChzZWxmLT5tYWdpYyA9PSBJQVNfTUFHSUMsIHJldHVybjspOwoKCWlmIChzZWxmLT5sc2FwKSB7CgkJaXJsbXBfY2xvc2VfbHNhcChzZWxmLT5sc2FwKTsKCQlzZWxmLT5sc2FwID0gTlVMTDsKCX0KCgllbnRyeSA9IChzdHJ1Y3QgaXJpYXBfY2IgKikgaGFzaGJpbl9yZW1vdmUoaXJpYXAsIChsb25nKSBzZWxmLCBOVUxMKTsKCUlSREFfQVNTRVJUKGVudHJ5ID09IHNlbGYsIHJldHVybjspOwoKCV9faXJpYXBfY2xvc2Uoc2VsZik7Cn0KRVhQT1JUX1NZTUJPTChpcmlhcF9jbG9zZSk7CgpzdGF0aWMgaW50IGlyaWFwX3JlZ2lzdGVyX2xzYXAoc3RydWN0IGlyaWFwX2NiICpzZWxmLCBfX3U4IHNsc2FwX3NlbCwgaW50IG1vZGUpCnsKCW5vdGlmeV90IG5vdGlmeTsKCglJUkRBX0RFQlVHKDIsICIlcygpXG4iLCBfX0ZVTkNUSU9OX18pOwoKCWlyZGFfbm90aWZ5X2luaXQoJm5vdGlmeSk7Cglub3RpZnkuY29ubmVjdF9jb25maXJtICAgICAgID0gaXJpYXBfY29ubmVjdF9jb25maXJtOwoJbm90aWZ5LmNvbm5lY3RfaW5kaWNhdGlvbiAgICA9IGlyaWFwX2Nvbm5lY3RfaW5kaWNhdGlvbjsKCW5vdGlmeS5kaXNjb25uZWN0X2luZGljYXRpb24gPSBpcmlhcF9kaXNjb25uZWN0X2luZGljYXRpb247Cglub3RpZnkuZGF0YV9pbmRpY2F0aW9uICAgICAgID0gaXJpYXBfZGF0YV9pbmRpY2F0aW9uOwoJbm90aWZ5Lmluc3RhbmNlID0gc2VsZjsKCWlmIChtb2RlID09IElBU19DTElFTlQpCgkJc3RyY3B5KG5vdGlmeS5uYW1lLCAiSXJJQVMgY2xpIik7CgllbHNlCgkJc3RyY3B5KG5vdGlmeS5uYW1lLCAiSXJJQVMgc3J2Iik7CgoJc2VsZi0+bHNhcCA9IGlybG1wX29wZW5fbHNhcChzbHNhcF9zZWwsICZub3RpZnksIDApOwoJaWYgKHNlbGYtPmxzYXAgPT0gTlVMTCkgewoJCUlSREFfRVJST1IoIiVzOiBVbmFibGUgdG8gYWxsb2NhdGVkIExTQVAhXG4iLCBfX0ZVTkNUSU9OX18pOwoJCXJldHVybiAtMTsKCX0KCXNlbGYtPnNsc2FwX3NlbCA9IHNlbGYtPmxzYXAtPnNsc2FwX3NlbDsKCglyZXR1cm4gMDsKfQoKLyoKICogRnVuY3Rpb24gaXJpYXBfZGlzY29ubmVjdF9pbmRpY2F0aW9uIChoYW5kbGUsIHJlYXNvbikKICoKICogICAgR290IGRpc2Nvbm5lY3QsIHNvIGNsZWFuIHVwIGV2ZXJ5dGhpbmcgYXNzb2NpYXRlZCB3aXRoIHRoaXMgY29ubmVjdGlvbgogKgogKi8Kc3RhdGljIHZvaWQgaXJpYXBfZGlzY29ubmVjdF9pbmRpY2F0aW9uKHZvaWQgKmluc3RhbmNlLCB2b2lkICpzYXAsCgkJCQkJTE1fUkVBU09OIHJlYXNvbiwKCQkJCQlzdHJ1Y3Qgc2tfYnVmZiAqc2tiKQp7CglzdHJ1Y3QgaXJpYXBfY2IgKnNlbGY7CgoJSVJEQV9ERUJVRyg0LCAiJXMoKSwgcmVhc29uPSVzXG4iLCBfX0ZVTkNUSU9OX18sIGlybG1wX3JlYXNvbnNbcmVhc29uXSk7CgoJc2VsZiA9IChzdHJ1Y3QgaXJpYXBfY2IgKikgaW5zdGFuY2U7CgoJSVJEQV9BU1NFUlQoc2VsZiAhPSBOVUxMLCByZXR1cm47KTsKCUlSREFfQVNTRVJUKHNlbGYtPm1hZ2ljID09IElBU19NQUdJQywgcmV0dXJuOyk7CgoJSVJEQV9BU1NFUlQoaXJpYXAgIT0gTlVMTCwgcmV0dXJuOyk7CgoJZGVsX3RpbWVyKCZzZWxmLT53YXRjaGRvZ190aW1lcik7CgoJLyogTm90IG5lZWRlZCAqLwoJaWYgKHNrYikKCQlkZXZfa2ZyZWVfc2tiKHNrYik7CgoJaWYgKHNlbGYtPm1vZGUgPT0gSUFTX0NMSUVOVCkgewoJCUlSREFfREVCVUcoNCwgIiVzKCksIGRpc2Nvbm5lY3QgYXMgY2xpZW50XG4iLCBfX0ZVTkNUSU9OX18pOwoKCgkJaXJpYXBfZG9fY2xpZW50X2V2ZW50KHNlbGYsIElBUF9MTV9ESVNDT05ORUNUX0lORElDQVRJT04sCgkJCQkgICAgICBOVUxMKTsKCQkvKgoJCSAqIEluZm9ybSBzZXJ2aWNlIHVzZXIgdGhhdCB0aGUgcmVxdWVzdCBmYWlsZWQgYnkgc2VuZGluZwoJCSAqIGl0IGEgTlVMTCB2YWx1ZS4gV2FybmluZywgdGhlIGNsaWVudCBtaWdodCBjbG9zZSB1cywgc28KCQkgKiByZW1lbWJlciBubyB0byB1c2Ugc2VsZiBhbnltb3JlIGFmdGVyIGNhbGxpbmcgY29uZmlybQoJCSAqLwoJCWlmIChzZWxmLT5jb25maXJtKQoJCQlzZWxmLT5jb25maXJtKElBU19ESVNDT05ORUNULCAwLCBOVUxMLCBzZWxmLT5wcml2KTsKCX0gZWxzZSB7CgkJSVJEQV9ERUJVRyg0LCAiJXMoKSwgZGlzY29ubmVjdCBhcyBzZXJ2ZXJcbiIsIF9fRlVOQ1RJT05fXyk7CgkJaXJpYXBfZG9fc2VydmVyX2V2ZW50KHNlbGYsIElBUF9MTV9ESVNDT05ORUNUX0lORElDQVRJT04sCgkJCQkgICAgICBOVUxMKTsKCQlpcmlhcF9jbG9zZShzZWxmKTsKCX0KfQoKLyoKICogRnVuY3Rpb24gaXJpYXBfZGlzY29ubmVjdF9yZXF1ZXN0IChoYW5kbGUpCiAqLwpzdGF0aWMgdm9pZCBpcmlhcF9kaXNjb25uZWN0X3JlcXVlc3Qoc3RydWN0IGlyaWFwX2NiICpzZWxmKQp7CglzdHJ1Y3Qgc2tfYnVmZiAqdHhfc2tiOwoKCUlSREFfREVCVUcoNCwgIiVzKClcbiIsIF9fRlVOQ1RJT05fXyk7CgoJSVJEQV9BU1NFUlQoc2VsZiAhPSBOVUxMLCByZXR1cm47KTsKCUlSREFfQVNTRVJUKHNlbGYtPm1hZ2ljID09IElBU19NQUdJQywgcmV0dXJuOyk7CgoJdHhfc2tiID0gYWxsb2Nfc2tiKExNUF9NQVhfSEVBREVSLCBHRlBfQVRPTUlDKTsKCWlmICh0eF9za2IgPT0gTlVMTCkgewoJCUlSREFfREVCVUcoMCwKCQkJICAgIiVzKCksIENvdWxkIG5vdCBhbGxvY2F0ZSBhbiBza19idWZmIG9mIGxlbmd0aCAlZFxuIiwKCQkJICAgX19GVU5DVElPTl9fLCBMTVBfTUFYX0hFQURFUik7CgkJcmV0dXJuOwoJfQoKCS8qCgkgKiAgUmVzZXJ2ZSBzcGFjZSBmb3IgTVVYIGNvbnRyb2wgYW5kIExBUCBoZWFkZXIKCSAqLwoJc2tiX3Jlc2VydmUodHhfc2tiLCBMTVBfTUFYX0hFQURFUik7CgoJaXJsbXBfZGlzY29ubmVjdF9yZXF1ZXN0KHNlbGYtPmxzYXAsIHR4X3NrYik7Cn0KCi8qCiAqIEZ1bmN0aW9uIGlyaWFwX2dldHZhbHVlYnljbGFzcyAoYWRkciwgbmFtZSwgYXR0cikKICoKICogICAgUmV0cmlldmUgYWxsIHZhbHVlcyBmcm9tIGF0dHJpYnV0ZSBpbiBhbGwgb2JqZWN0cyB3aXRoIGdpdmVuIGNsYXNzCiAqICAgIG5hbWUKICovCmludCBpcmlhcF9nZXR2YWx1ZWJ5Y2xhc3NfcmVxdWVzdChzdHJ1Y3QgaXJpYXBfY2IgKnNlbGYsCgkJCQkgIF9fdTMyIHNhZGRyLCBfX3UzMiBkYWRkciwKCQkJCSAgY2hhciAqbmFtZSwgY2hhciAqYXR0cikKewoJc3RydWN0IHNrX2J1ZmYgKnR4X3NrYjsKCWludCBuYW1lX2xlbiwgYXR0cl9sZW4sIHNrYl9sZW47CglfX3U4ICpmcmFtZTsKCglJUkRBX0FTU0VSVChzZWxmICE9IE5VTEwsIHJldHVybiAtMTspOwoJSVJEQV9BU1NFUlQoc2VsZi0+bWFnaWMgPT0gSUFTX01BR0lDLCByZXR1cm4gLTE7KTsKCgkvKiBDbGllbnQgbXVzdCBzdXBwbHkgdGhlIGRlc3RpbmF0aW9uIGRldmljZSBhZGRyZXNzICovCglpZiAoIWRhZGRyKQoJCXJldHVybiAtMTsKCglzZWxmLT5kYWRkciA9IGRhZGRyOwoJc2VsZi0+c2FkZHIgPSBzYWRkcjsKCgkvKgoJICogIFNhdmUgb3BlcmF0aW9uLCBzbyB3ZSBrbm93IHdoYXQgdGhlIGxhdGVyIGluZGljYXRpb24gaXMgYWJvdXQKCSAqLwoJc2VsZi0+b3BlcmF0aW9uID0gR0VUX1ZBTFVFX0JZX0NMQVNTOwoKCS8qIEdpdmUgb3Vyc2VsdmVzIDEwIHNlY3MgdG8gZmluaXNoIHRoaXMgb3BlcmF0aW9uICovCglpcmlhcF9zdGFydF93YXRjaGRvZ190aW1lcihzZWxmLCAxMCpIWik7CgoJbmFtZV9sZW4gPSBzdHJsZW4obmFtZSk7CS8qIFVwIHRvIElBU19NQVhfQ0xBU1NOQU1FID0gNjAgKi8KCWF0dHJfbGVuID0gc3RybGVuKGF0dHIpOwkvKiBVcCB0byBJQVNfTUFYX0FUVFJJQk5BTUUgPSA2MCAqLwoKCXNrYl9sZW4gPSBzZWxmLT5tYXhfaGVhZGVyX3NpemUrMituYW1lX2xlbisxK2F0dHJfbGVuKzQ7Cgl0eF9za2IgPSBhbGxvY19za2Ioc2tiX2xlbiwgR0ZQX0FUT01JQyk7CglpZiAoIXR4X3NrYikKCQlyZXR1cm4gLUVOT01FTTsKCgkvKiBSZXNlcnZlIHNwYWNlIGZvciBNVVggYW5kIExBUCBoZWFkZXIgKi8KCXNrYl9yZXNlcnZlKHR4X3NrYiwgc2VsZi0+bWF4X2hlYWRlcl9zaXplKTsKCXNrYl9wdXQodHhfc2tiLCAzK25hbWVfbGVuK2F0dHJfbGVuKTsKCWZyYW1lID0gdHhfc2tiLT5kYXRhOwoKCS8qIEJ1aWxkIGZyYW1lICovCglmcmFtZVswXSA9IElBUF9MU1QgfCBHRVRfVkFMVUVfQllfQ0xBU1M7CglmcmFtZVsxXSA9IG5hbWVfbGVuOyAgICAgICAgICAgICAgICAgICAgICAgLyogSW5zZXJ0IGxlbmd0aCBvZiBuYW1lICovCgltZW1jcHkoZnJhbWUrMiwgbmFtZSwgbmFtZV9sZW4pOyAgICAgICAgICAgLyogSW5zZXJ0IG5hbWUgKi8KCWZyYW1lWzIrbmFtZV9sZW5dID0gYXR0cl9sZW47ICAgICAgICAgICAgICAvKiBJbnNlcnQgbGVuZ3RoIG9mIGF0dHIgKi8KCW1lbWNweShmcmFtZSszK25hbWVfbGVuLCBhdHRyLCBhdHRyX2xlbik7ICAvKiBJbnNlcnQgYXR0ciAqLwoKCWlyaWFwX2RvX2NsaWVudF9ldmVudChzZWxmLCBJQVBfQ0FMTF9SRVFVRVNUX0dWQkMsIHR4X3NrYik7CgoJLyogRHJvcCByZWZlcmVuY2UgY291bnQgLSBzZWUgc3RhdGVfc19kaXNjb25uZWN0KCkuICovCglkZXZfa2ZyZWVfc2tiKHR4X3NrYik7CgoJcmV0dXJuIDA7Cn0KRVhQT1JUX1NZTUJPTChpcmlhcF9nZXR2YWx1ZWJ5Y2xhc3NfcmVxdWVzdCk7CgovKgogKiBGdW5jdGlvbiBpcmlhcF9nZXR2YWx1ZWJ5Y2xhc3NfY29uZmlybSAoc2VsZiwgc2tiKQogKgogKiAgICBHb3QgcmVzdWx0IGZyb20gR2V0VmFsdWVCeUNsYXNzIGNvbW1hbmQuIFBhcnNlIGl0IGFuZCByZXR1cm4gcmVzdWx0CiAqICAgIHRvIHNlcnZpY2UgdXNlci4KICoKICovCnN0YXRpYyB2b2lkIGlyaWFwX2dldHZhbHVlYnljbGFzc19jb25maXJtKHN0cnVjdCBpcmlhcF9jYiAqc2VsZiwKCQkJCQkgIHN0cnVjdCBza19idWZmICpza2IpCnsKCXN0cnVjdCBpYXNfdmFsdWUgKnZhbHVlOwoJaW50IGNoYXJzZXQ7CglfX3UzMiB2YWx1ZV9sZW47CglfX3UzMiB0bXBfY3B1MzI7CglfX3UxNiBvYmpfaWQ7CglfX3UxNiBsZW47CglfX3U4ICB0eXBlOwoJX191OCAqZnA7CglpbnQgbjsKCglJUkRBX0FTU0VSVChzZWxmICE9IE5VTEwsIHJldHVybjspOwoJSVJEQV9BU1NFUlQoc2VsZi0+bWFnaWMgPT0gSUFTX01BR0lDLCByZXR1cm47KTsKCUlSREFfQVNTRVJUKHNrYiAhPSBOVUxMLCByZXR1cm47KTsKCgkvKiBJbml0aWFsaXplIHZhcmlhYmxlcyAqLwoJZnAgPSBza2ItPmRhdGE7CgluID0gMjsKCgkvKiBHZXQgbGVuZ3RoLCBNU0IgZmlyc3QgKi8KCWxlbiA9IGJlMTZfdG9fY3B1KGdldF91bmFsaWduZWQoKF9fYmUxNiAqKShmcCtuKSkpOyBuICs9IDI7CgoJSVJEQV9ERUJVRyg0LCAiJXMoKSwgbGVuPSVkXG4iLCBfX0ZVTkNUSU9OX18sIGxlbik7CgoJLyogR2V0IG9iamVjdCBJRCwgTVNCIGZpcnN0ICovCglvYmpfaWQgPSBiZTE2X3RvX2NwdShnZXRfdW5hbGlnbmVkKChfX2JlMTYgKikoZnArbikpKTsgbiArPSAyOwoKCXR5cGUgPSBmcFtuKytdOwoJSVJEQV9ERUJVRyg0LCAiJXMoKSwgVmFsdWUgdHlwZSA9ICVkXG4iLCBfX0ZVTkNUSU9OX18sIHR5cGUpOwoKCXN3aXRjaCAodHlwZSkgewoJY2FzZSBJQVNfSU5URUdFUjoKCQltZW1jcHkoJnRtcF9jcHUzMiwgZnArbiwgNCk7IG4gKz0gNDsKCQliZTMyX3RvX2NwdXMoJnRtcF9jcHUzMik7CgkJdmFsdWUgPSBpcmlhc19uZXdfaW50ZWdlcl92YWx1ZSh0bXBfY3B1MzIpOwoKCQkvKiAgTGVnYWwgdmFsdWVzIHJlc3RyaWN0ZWQgdG8gMHgwMS0weDZmLCBwYWdlIDE1IGlydHRwICovCgkJSVJEQV9ERUJVRyg0LCAiJXMoKSwgbHNhcD0lZFxuIiwgX19GVU5DVElPTl9fLCB2YWx1ZS0+dC5pbnRlZ2VyKTsKCQlicmVhazsKCWNhc2UgSUFTX1NUUklORzoKCQljaGFyc2V0ID0gZnBbbisrXTsKCgkJc3dpdGNoIChjaGFyc2V0KSB7CgkJY2FzZSBDU19BU0NJSToKCQkJYnJlYWs7Ci8qCQljYXNlIENTX0lTT184ODU5XzE6ICovCi8qCQljYXNlIENTX0lTT184ODU5XzI6ICovCi8qCQljYXNlIENTX0lTT184ODU5XzM6ICovCi8qCQljYXNlIENTX0lTT184ODU5XzQ6ICovCi8qCQljYXNlIENTX0lTT184ODU5XzU6ICovCi8qCQljYXNlIENTX0lTT184ODU5XzY6ICovCi8qCQljYXNlIENTX0lTT184ODU5Xzc6ICovCi8qCQljYXNlIENTX0lTT184ODU5Xzg6ICovCi8qCQljYXNlIENTX0lTT184ODU5Xzk6ICovCi8qCQljYXNlIENTX1VOSUNPREU6ICovCgkJZGVmYXVsdDoKCQkJSVJEQV9ERUJVRygwLCAiJXMoKSwgY2hhcnNldCAlcywgbm90IHN1cHBvcnRlZFxuIiwKCQkJCSAgIF9fRlVOQ1RJT05fXywgaWFzX2NoYXJzZXRfdHlwZXNbY2hhcnNldF0pOwoKCQkJLyogQWJvcnRpbmcsIGNsb3NlIGNvbm5lY3Rpb24hICovCgkJCWlyaWFwX2Rpc2Nvbm5lY3RfcmVxdWVzdChzZWxmKTsKCQkJcmV0dXJuOwoJCQkvKiBicmVhazsgKi8KCQl9CgkJdmFsdWVfbGVuID0gZnBbbisrXTsKCQlJUkRBX0RFQlVHKDQsICIlcygpLCBzdHJsZW49JWRcbiIsIF9fRlVOQ1RJT05fXywgdmFsdWVfbGVuKTsKCgkJLyogTWFrZSBzdXJlIHRoZSBzdHJpbmcgaXMgbnVsbC10ZXJtaW5hdGVkICovCgkJZnBbbit2YWx1ZV9sZW5dID0gMHgwMDsKCQlJUkRBX0RFQlVHKDQsICJHb3Qgc3RyaW5nICVzXG4iLCBmcCtuKTsKCgkJLyogV2lsbCB0cnVuY2F0ZSB0byBJQVNfTUFYX1NUUklORyBieXRlcyAqLwoJCXZhbHVlID0gaXJpYXNfbmV3X3N0cmluZ192YWx1ZShmcCtuKTsKCQlicmVhazsKCWNhc2UgSUFTX09DVF9TRVE6CgkJdmFsdWVfbGVuID0gYmUxNl90b19jcHUoZ2V0X3VuYWxpZ25lZCgoX19iZTE2ICopKGZwK24pKSk7CgkJbiArPSAyOwoKCQkvKiBXaWxsIHRydW5jYXRlIHRvIElBU19NQVhfT0NURVRfU1RSSU5HIGJ5dGVzICovCgkJdmFsdWUgPSBpcmlhc19uZXdfb2N0c2VxX3ZhbHVlKGZwK24sIHZhbHVlX2xlbik7CgkJYnJlYWs7CglkZWZhdWx0OgoJCXZhbHVlID0gaXJpYXNfbmV3X21pc3NpbmdfdmFsdWUoKTsKCQlicmVhazsKCX0KCgkvKiBGaW5pc2hlZCwgY2xvc2UgY29ubmVjdGlvbiEgKi8KCWlyaWFwX2Rpc2Nvbm5lY3RfcmVxdWVzdChzZWxmKTsKCgkvKiBXYXJuaW5nLCB0aGUgY2xpZW50IG1pZ2h0IGNsb3NlIHVzLCBzbyByZW1lbWJlciBubyB0byB1c2Ugc2VsZgoJICogYW55bW9yZSBhZnRlciBjYWxsaW5nIGNvbmZpcm0KCSAqLwoJaWYgKHNlbGYtPmNvbmZpcm0pCgkJc2VsZi0+Y29uZmlybShJQVNfU1VDQ0VTUywgb2JqX2lkLCB2YWx1ZSwgc2VsZi0+cHJpdik7CgllbHNlIHsKCQlJUkRBX0RFQlVHKDAsICIlcygpLCBtaXNzaW5nIGhhbmRsZXIhXG4iLCBfX0ZVTkNUSU9OX18pOwoJCWlyaWFzX2RlbGV0ZV92YWx1ZSh2YWx1ZSk7Cgl9Cn0KCi8qCiAqIEZ1bmN0aW9uIGlyaWFwX2dldHZhbHVlYnljbGFzc19yZXNwb25zZSAoKQogKgogKiAgICBTZW5kIGFuc3dlciBiYWNrIHRvIHJlbW90ZSBMTS1JQVMKICoKICovCnN0YXRpYyB2b2lkIGlyaWFwX2dldHZhbHVlYnljbGFzc19yZXNwb25zZShzdHJ1Y3QgaXJpYXBfY2IgKnNlbGYsCgkJCQkJICAgX191MTYgb2JqX2lkLAoJCQkJCSAgIF9fdTggcmV0X2NvZGUsCgkJCQkJICAgc3RydWN0IGlhc192YWx1ZSAqdmFsdWUpCnsKCXN0cnVjdCBza19idWZmICp0eF9za2I7CglpbnQgbjsKCV9fYmUzMiB0bXBfYmUzMjsKCV9fYmUxNiB0bXBfYmUxNjsKCV9fdTggKmZwOwoKCUlSREFfREVCVUcoNCwgIiVzKClcbiIsIF9fRlVOQ1RJT05fXyk7CgoJSVJEQV9BU1NFUlQoc2VsZiAhPSBOVUxMLCByZXR1cm47KTsKCUlSREFfQVNTRVJUKHNlbGYtPm1hZ2ljID09IElBU19NQUdJQywgcmV0dXJuOyk7CglJUkRBX0FTU0VSVCh2YWx1ZSAhPSBOVUxMLCByZXR1cm47KTsKCUlSREFfQVNTRVJUKHZhbHVlLT5sZW4gPD0gMTAyNCwgcmV0dXJuOyk7CgoJLyogSW5pdGlhbGl6ZSB2YXJpYWJsZXMgKi8KCW4gPSAwOwoKCS8qCgkgKiAgV2UgbXVzdCBhZGp1c3QgdGhlIHNpemUgb2YgdGhlIHJlc3BvbnNlIGFmdGVyIHRoZSBsZW5ndGggb2YgdGhlCgkgKiAgdmFsdWUuIFdlIGFkZCAzMiBieXRlcyBiZWNhdXNlIG9mIHRoZSA2IGJ5dGVzIGZvciB0aGUgZnJhbWUgYW5kCgkgKiAgbWF4IDUgYnl0ZXMgZm9yIHRoZSB2YWx1ZSBjb2RpbmcuCgkgKi8KCXR4X3NrYiA9IGFsbG9jX3NrYih2YWx1ZS0+bGVuICsgc2VsZi0+bWF4X2hlYWRlcl9zaXplICsgMzIsCgkJCSAgIEdGUF9BVE9NSUMpOwoJaWYgKCF0eF9za2IpCgkJcmV0dXJuOwoKCS8qIFJlc2VydmUgc3BhY2UgZm9yIE1VWCBhbmQgTEFQIGhlYWRlciAqLwoJc2tiX3Jlc2VydmUodHhfc2tiLCBzZWxmLT5tYXhfaGVhZGVyX3NpemUpOwoJc2tiX3B1dCh0eF9za2IsIDYpOwoKCWZwID0gdHhfc2tiLT5kYXRhOwoKCS8qIEJ1aWxkIGZyYW1lICovCglmcFtuKytdID0gR0VUX1ZBTFVFX0JZX0NMQVNTIHwgSUFQX0xTVDsKCWZwW24rK10gPSByZXRfY29kZTsKCgkvKiBJbnNlcnQgbGlzdCBsZW5ndGggKE1TQiBmaXJzdCkgKi8KCXRtcF9iZTE2ID0gX19jb25zdGFudF9odG9ucygweDAwMDEpOwoJbWVtY3B5KGZwK24sICZ0bXBfYmUxNiwgMik7ICBuICs9IDI7CgoJLyogSW5zZXJ0IG9iamVjdCBpZGVudGlmaWVyICggTVNCIGZpcnN0KSAqLwoJdG1wX2JlMTYgPSBjcHVfdG9fYmUxNihvYmpfaWQpOwoJbWVtY3B5KGZwK24sICZ0bXBfYmUxNiwgMik7IG4gKz0gMjsKCglzd2l0Y2ggKHZhbHVlLT50eXBlKSB7CgljYXNlIElBU19TVFJJTkc6CgkJc2tiX3B1dCh0eF9za2IsIDMgKyB2YWx1ZS0+bGVuKTsKCQlmcFtuKytdID0gdmFsdWUtPnR5cGU7CgkJZnBbbisrXSA9IDA7IC8qIEFTQ0lJICovCgkJZnBbbisrXSA9IChfX3U4KSB2YWx1ZS0+bGVuOwoJCW1lbWNweShmcCtuLCB2YWx1ZS0+dC5zdHJpbmcsIHZhbHVlLT5sZW4pOyBuKz12YWx1ZS0+bGVuOwoJCWJyZWFrOwoJY2FzZSBJQVNfSU5URUdFUjoKCQlza2JfcHV0KHR4X3NrYiwgNSk7CgkJZnBbbisrXSA9IHZhbHVlLT50eXBlOwoKCQl0bXBfYmUzMiA9IGNwdV90b19iZTMyKHZhbHVlLT50LmludGVnZXIpOwoJCW1lbWNweShmcCtuLCAmdG1wX2JlMzIsIDQpOyBuICs9IDQ7CgkJYnJlYWs7CgljYXNlIElBU19PQ1RfU0VROgoJCXNrYl9wdXQodHhfc2tiLCAzICsgdmFsdWUtPmxlbik7CgkJZnBbbisrXSA9IHZhbHVlLT50eXBlOwoKCQl0bXBfYmUxNiA9IGNwdV90b19iZTE2KHZhbHVlLT5sZW4pOwoJCW1lbWNweShmcCtuLCAmdG1wX2JlMTYsIDIpOyBuICs9IDI7CgkJbWVtY3B5KGZwK24sIHZhbHVlLT50Lm9jdF9zZXEsIHZhbHVlLT5sZW4pOyBuKz12YWx1ZS0+bGVuOwoJCWJyZWFrOwoJY2FzZSBJQVNfTUlTU0lORzoKCQlJUkRBX0RFQlVHKCAzLCAiJXM6IHNlbmRpbmcgSUFTX01JU1NJTkdcbiIsIF9fRlVOQ1RJT05fXyk7CgkJc2tiX3B1dCh0eF9za2IsIDEpOwoJCWZwW24rK10gPSB2YWx1ZS0+dHlwZTsKCQlicmVhazsKCWRlZmF1bHQ6CgkJSVJEQV9ERUJVRygwLCAiJXMoKSwgdHlwZSBub3QgaW1wbGVtZW50ZWQhXG4iLCBfX0ZVTkNUSU9OX18pOwoJCWJyZWFrOwoJfQoJaXJpYXBfZG9fcl9jb25uZWN0X2V2ZW50KHNlbGYsIElBUF9DQUxMX1JFU1BPTlNFLCB0eF9za2IpOwoKCS8qIERyb3AgcmVmZXJlbmNlIGNvdW50IC0gc2VlIHN0YXRlX3JfZXhlY3V0ZSgpLiAqLwoJZGV2X2tmcmVlX3NrYih0eF9za2IpOwp9CgovKgogKiBGdW5jdGlvbiBpcmlhcF9nZXR2YWx1ZWJ5Y2xhc3NfaW5kaWNhdGlvbiAoc2VsZiwgc2tiKQogKgogKiAgICBnZXR2YWx1ZWJ5Y2xhc3MgaXMgcmVxdWVzdGVkIGZyb20gcGVlciBMTS1JQVMKICoKICovCnN0YXRpYyB2b2lkIGlyaWFwX2dldHZhbHVlYnljbGFzc19pbmRpY2F0aW9uKHN0cnVjdCBpcmlhcF9jYiAqc2VsZiwKCQkJCQkgICAgIHN0cnVjdCBza19idWZmICpza2IpCnsKCXN0cnVjdCBpYXNfb2JqZWN0ICpvYmo7CglzdHJ1Y3QgaWFzX2F0dHJpYiAqYXR0cmliOwoJaW50IG5hbWVfbGVuOwoJaW50IGF0dHJfbGVuOwoJY2hhciBuYW1lW0lBU19NQVhfQ0xBU1NOQU1FICsgMV07CS8qIDYwIGJ5dGVzICovCgljaGFyIGF0dHJbSUFTX01BWF9BVFRSSUJOQU1FICsgMV07CS8qIDYwIGJ5dGVzICovCglfX3U4ICpmcDsKCWludCBuOwoKCUlSREFfREVCVUcoNCwgIiVzKClcbiIsIF9fRlVOQ1RJT05fXyk7CgoJSVJEQV9BU1NFUlQoc2VsZiAhPSBOVUxMLCByZXR1cm47KTsKCUlSREFfQVNTRVJUKHNlbGYtPm1hZ2ljID09IElBU19NQUdJQywgcmV0dXJuOyk7CglJUkRBX0FTU0VSVChza2IgIT0gTlVMTCwgcmV0dXJuOyk7CgoJZnAgPSBza2ItPmRhdGE7CgluID0gMTsKCgluYW1lX2xlbiA9IGZwW24rK107CgltZW1jcHkobmFtZSwgZnArbiwgbmFtZV9sZW4pOyBuKz1uYW1lX2xlbjsKCW5hbWVbbmFtZV9sZW5dID0gJ1wwJzsKCglhdHRyX2xlbiA9IGZwW24rK107CgltZW1jcHkoYXR0ciwgZnArbiwgYXR0cl9sZW4pOyBuKz1hdHRyX2xlbjsKCWF0dHJbYXR0cl9sZW5dID0gJ1wwJzsKCglJUkRBX0RFQlVHKDQsICJMTS1JQVM6IExvb2tpbmcgdXAgJXM6ICVzXG4iLCBuYW1lLCBhdHRyKTsKCW9iaiA9IGlyaWFzX2ZpbmRfb2JqZWN0KG5hbWUpOwoKCWlmIChvYmogPT0gTlVMTCkgewoJCUlSREFfREVCVUcoMiwgIkxNLUlBUzogT2JqZWN0ICVzIG5vdCBmb3VuZFxuIiwgbmFtZSk7CgkJaXJpYXBfZ2V0dmFsdWVieWNsYXNzX3Jlc3BvbnNlKHNlbGYsIDB4MTIzNSwgSUFTX0NMQVNTX1VOS05PV04sCgkJCQkJICAgICAgICZpcmlhc19taXNzaW5nKTsKCQlyZXR1cm47Cgl9CglJUkRBX0RFQlVHKDQsICJMTS1JQVM6IGZvdW5kICVzLCBpZD0lZFxuIiwgb2JqLT5uYW1lLCBvYmotPmlkKTsKCglhdHRyaWIgPSBpcmlhc19maW5kX2F0dHJpYihvYmosIGF0dHIpOwoJaWYgKGF0dHJpYiA9PSBOVUxMKSB7CgkJSVJEQV9ERUJVRygyLCAiTE0tSUFTOiBBdHRyaWJ1dGUgJXMgbm90IGZvdW5kXG4iLCBhdHRyKTsKCQlpcmlhcF9nZXR2YWx1ZWJ5Y2xhc3NfcmVzcG9uc2Uoc2VsZiwgb2JqLT5pZCwKCQkJCQkgICAgICAgSUFTX0FUVFJJQl9VTktOT1dOLAoJCQkJCSAgICAgICAmaXJpYXNfbWlzc2luZyk7CgkJcmV0dXJuOwoJfQoKCS8qIFdlIGhhdmUgYSBtYXRjaDsgc2VuZCB0aGUgdmFsdWUuICAqLwoJaXJpYXBfZ2V0dmFsdWVieWNsYXNzX3Jlc3BvbnNlKHNlbGYsIG9iai0+aWQsIElBU19TVUNDRVNTLAoJCQkJICAgICAgIGF0dHJpYi0+dmFsdWUpOwoKCXJldHVybjsKfQoKLyoKICogRnVuY3Rpb24gaXJpYXBfc2VuZF9hY2sgKHZvaWQpCiAqCiAqICAgIEN1cnJlbnRseSBub3QgdXNlZAogKgogKi8Kdm9pZCBpcmlhcF9zZW5kX2FjayhzdHJ1Y3QgaXJpYXBfY2IgKnNlbGYpCnsKCXN0cnVjdCBza19idWZmICp0eF9za2I7CglfX3U4ICpmcmFtZTsKCglJUkRBX0RFQlVHKDIsICIlcygpXG4iLCBfX0ZVTkNUSU9OX18pOwoKCUlSREFfQVNTRVJUKHNlbGYgIT0gTlVMTCwgcmV0dXJuOyk7CglJUkRBX0FTU0VSVChzZWxmLT5tYWdpYyA9PSBJQVNfTUFHSUMsIHJldHVybjspOwoKCXR4X3NrYiA9IGFsbG9jX3NrYihMTVBfTUFYX0hFQURFUiArIDEsIEdGUF9BVE9NSUMpOwoJaWYgKCF0eF9za2IpCgkJcmV0dXJuOwoKCS8qIFJlc2VydmUgc3BhY2UgZm9yIE1VWCBhbmQgTEFQIGhlYWRlciAqLwoJc2tiX3Jlc2VydmUodHhfc2tiLCBzZWxmLT5tYXhfaGVhZGVyX3NpemUpOwoJc2tiX3B1dCh0eF9za2IsIDEpOwoJZnJhbWUgPSB0eF9za2ItPmRhdGE7CgoJLyogQnVpbGQgZnJhbWUgKi8KCWZyYW1lWzBdID0gSUFQX0xTVCB8IElBUF9BQ0sgfCBzZWxmLT5vcGVyYXRpb247CgoJaXJsbXBfZGF0YV9yZXF1ZXN0KHNlbGYtPmxzYXAsIHR4X3NrYik7Cn0KCnZvaWQgaXJpYXBfY29ubmVjdF9yZXF1ZXN0KHN0cnVjdCBpcmlhcF9jYiAqc2VsZikKewoJaW50IHJldDsKCglJUkRBX0FTU0VSVChzZWxmICE9IE5VTEwsIHJldHVybjspOwoJSVJEQV9BU1NFUlQoc2VsZi0+bWFnaWMgPT0gSUFTX01BR0lDLCByZXR1cm47KTsKCglyZXQgPSBpcmxtcF9jb25uZWN0X3JlcXVlc3Qoc2VsZi0+bHNhcCwgTFNBUF9JQVMsCgkJCQkgICAgc2VsZi0+c2FkZHIsIHNlbGYtPmRhZGRyLAoJCQkJICAgIE5VTEwsIE5VTEwpOwoJaWYgKHJldCA8IDApIHsKCQlJUkRBX0RFQlVHKDAsICIlcygpLCBjb25uZWN0IGZhaWxlZCFcbiIsIF9fRlVOQ1RJT05fXyk7CgkJc2VsZi0+Y29uZmlybShJQVNfRElTQ09OTkVDVCwgMCwgTlVMTCwgc2VsZi0+cHJpdik7Cgl9Cn0KCi8qCiAqIEZ1bmN0aW9uIGlyaWFwX2Nvbm5lY3RfY29uZmlybSAoaGFuZGxlLCBza2IpCiAqCiAqICAgIExTQVAgY29ubmVjdGlvbiBjb25maXJtZWQhCiAqCiAqLwpzdGF0aWMgdm9pZCBpcmlhcF9jb25uZWN0X2NvbmZpcm0odm9pZCAqaW5zdGFuY2UsIHZvaWQgKnNhcCwKCQkJCSAgc3RydWN0IHFvc19pbmZvICpxb3MsIF9fdTMyIG1heF9zZWdfc2l6ZSwKCQkJCSAgX191OCBtYXhfaGVhZGVyX3NpemUsCgkJCQkgIHN0cnVjdCBza19idWZmICpza2IpCnsKCXN0cnVjdCBpcmlhcF9jYiAqc2VsZjsKCglzZWxmID0gKHN0cnVjdCBpcmlhcF9jYiAqKSBpbnN0YW5jZTsKCglJUkRBX0FTU0VSVChzZWxmICE9IE5VTEwsIHJldHVybjspOwoJSVJEQV9BU1NFUlQoc2VsZi0+bWFnaWMgPT0gSUFTX01BR0lDLCByZXR1cm47KTsKCUlSREFfQVNTRVJUKHNrYiAhPSBOVUxMLCByZXR1cm47KTsKCglzZWxmLT5tYXhfZGF0YV9zaXplID0gbWF4X3NlZ19zaXplOwoJc2VsZi0+bWF4X2hlYWRlcl9zaXplID0gbWF4X2hlYWRlcl9zaXplOwoKCWRlbF90aW1lcigmc2VsZi0+d2F0Y2hkb2dfdGltZXIpOwoKCWlyaWFwX2RvX2NsaWVudF9ldmVudChzZWxmLCBJQVBfTE1fQ09OTkVDVF9DT05GSVJNLCBza2IpOwoKCS8qIERyb3AgcmVmZXJlbmNlIGNvdW50IC0gc2VlIHN0YXRlX3NfbWFrZV9jYWxsKCkuICovCglkZXZfa2ZyZWVfc2tiKHNrYik7Cn0KCi8qCiAqIEZ1bmN0aW9uIGlyaWFwX2Nvbm5lY3RfaW5kaWNhdGlvbiAoIGhhbmRsZSwgc2tiKQogKgogKiAgICBSZW1vdGUgTE0tSUFTIGlzIHJlcXVlc3RpbmcgY29ubmVjdGlvbgogKgogKi8Kc3RhdGljIHZvaWQgaXJpYXBfY29ubmVjdF9pbmRpY2F0aW9uKHZvaWQgKmluc3RhbmNlLCB2b2lkICpzYXAsCgkJCQkgICAgIHN0cnVjdCBxb3NfaW5mbyAqcW9zLCBfX3UzMiBtYXhfc2VnX3NpemUsCgkJCQkgICAgIF9fdTggbWF4X2hlYWRlcl9zaXplLAoJCQkJICAgICBzdHJ1Y3Qgc2tfYnVmZiAqc2tiKQp7CglzdHJ1Y3QgaXJpYXBfY2IgKnNlbGYsICpuZXc7CgoJSVJEQV9ERUJVRygxLCAiJXMoKVxuIiwgX19GVU5DVElPTl9fKTsKCglzZWxmID0gKHN0cnVjdCBpcmlhcF9jYiAqKSBpbnN0YW5jZTsKCglJUkRBX0FTU0VSVChza2IgIT0gTlVMTCwgcmV0dXJuOyk7CglJUkRBX0FTU0VSVChzZWxmICE9IE5VTEwsIGdvdG8gb3V0Oyk7CglJUkRBX0FTU0VSVChzZWxmLT5tYWdpYyA9PSBJQVNfTUFHSUMsIGdvdG8gb3V0Oyk7CgoJLyogU3RhcnQgbmV3IHNlcnZlciAqLwoJbmV3ID0gaXJpYXBfb3BlbihMU0FQX0lBUywgSUFTX1NFUlZFUiwgTlVMTCwgTlVMTCk7CglpZiAoIW5ldykgewoJCUlSREFfREVCVUcoMCwgIiVzKCksIG9wZW4gZmFpbGVkXG4iLCBfX0ZVTkNUSU9OX18pOwoJCWdvdG8gb3V0OwoJfQoKCS8qIE5vdyBhdHRhY2ggdXAgdGhlIG5ldyAic29ja2V0IiAqLwoJbmV3LT5sc2FwID0gaXJsbXBfZHVwKHNlbGYtPmxzYXAsIG5ldyk7CglpZiAoIW5ldy0+bHNhcCkgewoJCUlSREFfREVCVUcoMCwgIiVzKCksIGR1cCBmYWlsZWQhXG4iLCBfX0ZVTkNUSU9OX18pOwoJCWdvdG8gb3V0OwoJfQoKCW5ldy0+bWF4X2RhdGFfc2l6ZSA9IG1heF9zZWdfc2l6ZTsKCW5ldy0+bWF4X2hlYWRlcl9zaXplID0gbWF4X2hlYWRlcl9zaXplOwoKCS8qIENsZWFuIHVwIHRoZSBvcmlnaW5hbCBvbmUgdG8ga2VlcCBpdCBpbiBsaXN0ZW4gc3RhdGUgKi8KCWlybG1wX2xpc3RlbihzZWxmLT5sc2FwKTsKCglpcmlhcF9kb19zZXJ2ZXJfZXZlbnQobmV3LCBJQVBfTE1fQ09OTkVDVF9JTkRJQ0FUSU9OLCBza2IpOwoKb3V0OgoJLyogRHJvcCByZWZlcmVuY2UgY291bnQgLSBzZWUgc3RhdGVfcl9kaXNjb25uZWN0KCkuICovCglkZXZfa2ZyZWVfc2tiKHNrYik7Cn0KCi8qCiAqIEZ1bmN0aW9uIGlyaWFwX2RhdGFfaW5kaWNhdGlvbiAoaGFuZGxlLCBza2IpCiAqCiAqICAgIFJlY2VpdmVzIGRhdGEgZnJvbSBjb25uZWN0aW9uIGlkZW50aWZpZWQgYnkgaGFuZGxlIGZyb20gSXJMTVAKICoKICovCnN0YXRpYyBpbnQgaXJpYXBfZGF0YV9pbmRpY2F0aW9uKHZvaWQgKmluc3RhbmNlLCB2b2lkICpzYXAsCgkJCQkgc3RydWN0IHNrX2J1ZmYgKnNrYikKewoJc3RydWN0IGlyaWFwX2NiICpzZWxmOwoJX191OCAgKmZyYW1lOwoJX191OCAgb3Bjb2RlOwoKCUlSREFfREVCVUcoMywgIiVzKClcbiIsIF9fRlVOQ1RJT05fXyk7CgoJc2VsZiA9IChzdHJ1Y3QgaXJpYXBfY2IgKikgaW5zdGFuY2U7CgoJSVJEQV9BU1NFUlQoc2tiICE9IE5VTEwsIHJldHVybiAwOyk7CglJUkRBX0FTU0VSVChzZWxmICE9IE5VTEwsIGdvdG8gb3V0Oyk7CglJUkRBX0FTU0VSVChzZWxmLT5tYWdpYyA9PSBJQVNfTUFHSUMsIGdvdG8gb3V0Oyk7CgoJZnJhbWUgPSBza2ItPmRhdGE7CgoJaWYgKHNlbGYtPm1vZGUgPT0gSUFTX1NFUlZFUikgewoJCS8qIENhbGwgc2VydmVyICovCgkJSVJEQV9ERUJVRyg0LCAiJXMoKSwgQ2FsbGluZyBzZXJ2ZXIhXG4iLCBfX0ZVTkNUSU9OX18pOwoJCWlyaWFwX2RvX3JfY29ubmVjdF9ldmVudChzZWxmLCBJQVBfUkVDVl9GX0xTVCwgc2tiKTsKCQlnb3RvIG91dDsKCX0KCW9wY29kZSA9IGZyYW1lWzBdOwoJaWYgKH5vcGNvZGUgJiBJQVBfTFNUKSB7CgkJSVJEQV9XQVJOSU5HKCIlczosIElySUFTIG11bHRpZnJhbWUgY29tbWFuZHMgb3IgIgoJCQkgICAgICJyZXN1bHRzIGlzIG5vdCBpbXBsZW1lbnRlZCB5ZXQhXG4iLAoJCQkgICAgIF9fRlVOQ1RJT05fXyk7CgkJZ290byBvdXQ7Cgl9CgoJLyogQ2hlY2sgZm9yIGFjayBmcmFtZXMgc2luY2UgdGhleSBkb24ndCBjb250YWluIGFueSBkYXRhICovCglpZiAob3Bjb2RlICYgSUFQX0FDSykgewoJCUlSREFfREVCVUcoMCwgIiVzKCkgR290IGFjayBmcmFtZSFcbiIsIF9fRlVOQ1RJT05fXyk7CgkJZ290byBvdXQ7Cgl9CgoJb3Bjb2RlICY9IH5JQVBfTFNUOyAvKiBNYXNrIGF3YXkgTFNUIGJpdCAqLwoKCXN3aXRjaCAob3Bjb2RlKSB7CgljYXNlIEdFVF9JTkZPX0JBU0U6CgkJSVJEQV9ERUJVRygwLCAiSXJMTVAgR2V0SW5mb0Jhc2VEZXRhaWxzIG5vdCBpbXBsZW1lbnRlZCFcbiIpOwoJCWJyZWFrOwoJY2FzZSBHRVRfVkFMVUVfQllfQ0xBU1M6CgkJaXJpYXBfZG9fY2FsbF9ldmVudChzZWxmLCBJQVBfUkVDVl9GX0xTVCwgTlVMTCk7CgoJCXN3aXRjaCAoZnJhbWVbMV0pIHsKCQljYXNlIElBU19TVUNDRVNTOgoJCQlpcmlhcF9nZXR2YWx1ZWJ5Y2xhc3NfY29uZmlybShzZWxmLCBza2IpOwoJCQlicmVhazsKCQljYXNlIElBU19DTEFTU19VTktOT1dOOgoJCQlJUkRBX0RFQlVHKDEsICIlcygpLCBObyBzdWNoIGNsYXNzIVxuIiwgX19GVU5DVElPTl9fKTsKCQkJLyogRmluaXNoZWQsIGNsb3NlIGNvbm5lY3Rpb24hICovCgkJCWlyaWFwX2Rpc2Nvbm5lY3RfcmVxdWVzdChzZWxmKTsKCgkJCS8qCgkJCSAqIFdhcm5pbmcsIHRoZSBjbGllbnQgbWlnaHQgY2xvc2UgdXMsIHNvIHJlbWVtYmVyCgkJCSAqIG5vIHRvIHVzZSBzZWxmIGFueW1vcmUgYWZ0ZXIgY2FsbGluZyBjb25maXJtCgkJCSAqLwoJCQlpZiAoc2VsZi0+Y29uZmlybSkKCQkJCXNlbGYtPmNvbmZpcm0oSUFTX0NMQVNTX1VOS05PV04sIDAsIE5VTEwsCgkJCQkJICAgICAgc2VsZi0+cHJpdik7CgkJCWJyZWFrOwoJCWNhc2UgSUFTX0FUVFJJQl9VTktOT1dOOgoJCQlJUkRBX0RFQlVHKDEsICIlcygpLCBObyBzdWNoIGF0dHJpYnV0ZSFcbiIsIF9fRlVOQ1RJT05fXyk7CgkJCS8qIEZpbmlzaGVkLCBjbG9zZSBjb25uZWN0aW9uISAqLwoJCQlpcmlhcF9kaXNjb25uZWN0X3JlcXVlc3Qoc2VsZik7CgoJCQkvKgoJCQkgKiBXYXJuaW5nLCB0aGUgY2xpZW50IG1pZ2h0IGNsb3NlIHVzLCBzbyByZW1lbWJlcgoJCQkgKiBubyB0byB1c2Ugc2VsZiBhbnltb3JlIGFmdGVyIGNhbGxpbmcgY29uZmlybQoJCQkgKi8KCQkJaWYgKHNlbGYtPmNvbmZpcm0pCgkJCQlzZWxmLT5jb25maXJtKElBU19BVFRSSUJfVU5LTk9XTiwgMCwgTlVMTCwKCQkJCQkgICAgICBzZWxmLT5wcml2KTsKCQkJYnJlYWs7CgkJfQoJCWJyZWFrOwoJZGVmYXVsdDoKCQlJUkRBX0RFQlVHKDAsICIlcygpLCBVbmtub3duIG9wLWNvZGU6ICUwMnhcbiIsIF9fRlVOQ1RJT05fXywKCQkJICAgb3Bjb2RlKTsKCQlicmVhazsKCX0KCm91dDoKCS8qIENsZWFudXAgLSBzdWItY2FsbHMgd2lsbCBoYXZlIGRvbmUgc2tiX2dldCgpIGFzIG5lZWRlZC4gKi8KCWRldl9rZnJlZV9za2Ioc2tiKTsKCXJldHVybiAwOwp9CgovKgogKiBGdW5jdGlvbiBpcmlhcF9jYWxsX2luZGljYXRpb24gKHNlbGYsIHNrYikKICoKICogICAgUmVjZWl2ZWQgY2FsbCB0byBzZXJ2ZXIgZnJvbSBwZWVyIExNLUlBUwogKgogKi8Kdm9pZCBpcmlhcF9jYWxsX2luZGljYXRpb24oc3RydWN0IGlyaWFwX2NiICpzZWxmLCBzdHJ1Y3Qgc2tfYnVmZiAqc2tiKQp7CglfX3U4ICpmcDsKCV9fdTggb3Bjb2RlOwoKCUlSREFfREVCVUcoNCwgIiVzKClcbiIsIF9fRlVOQ1RJT05fXyk7CgoJSVJEQV9BU1NFUlQoc2VsZiAhPSBOVUxMLCByZXR1cm47KTsKCUlSREFfQVNTRVJUKHNlbGYtPm1hZ2ljID09IElBU19NQUdJQywgcmV0dXJuOyk7CglJUkRBX0FTU0VSVChza2IgIT0gTlVMTCwgcmV0dXJuOyk7CgoJZnAgPSBza2ItPmRhdGE7CgoJb3Bjb2RlID0gZnBbMF07CglpZiAofm9wY29kZSAmIDB4ODApIHsKCQlJUkRBX1dBUk5JTkcoIiVzOiBJcklBUyBtdWx0aWZyYW1lIGNvbW1hbmRzIG9yIHJlc3VsdHMiCgkJCSAgICAgImlzIG5vdCBpbXBsZW1lbnRlZCB5ZXQhXG4iLCBfX0ZVTkNUSU9OX18pOwoJCXJldHVybjsKCX0KCW9wY29kZSAmPSAweDdmOyAvKiBNYXNrIGF3YXkgTFNUIGJpdCAqLwoKCXN3aXRjaCAob3Bjb2RlKSB7CgljYXNlIEdFVF9JTkZPX0JBU0U6CgkJSVJEQV9XQVJOSU5HKCIlczogR2V0SW5mb0Jhc2VEZXRhaWxzIG5vdCBpbXBsZW1lbnRlZCB5ZXQhXG4iLAoJCQkgICAgIF9fRlVOQ1RJT05fXyk7CgkJYnJlYWs7CgljYXNlIEdFVF9WQUxVRV9CWV9DTEFTUzoKCQlpcmlhcF9nZXR2YWx1ZWJ5Y2xhc3NfaW5kaWNhdGlvbihzZWxmLCBza2IpOwoJCWJyZWFrOwoJfQoJLyogc2tiIHdpbGwgYmUgY2xlYW5lZCB1cCBpbiBpcmlhcF9kYXRhX2luZGljYXRpb24gKi8KfQoKLyoKICogRnVuY3Rpb24gaXJpYXBfd2F0Y2hkb2dfdGltZXJfZXhwaXJlZCAoZGF0YSkKICoKICogICAgUXVlcnkgaGFzIHRha2VuIHRvbyBsb25nIHRpbWUsIHNvIGFib3J0CiAqCiAqLwpzdGF0aWMgdm9pZCBpcmlhcF93YXRjaGRvZ190aW1lcl9leHBpcmVkKHZvaWQgKmRhdGEpCnsKCXN0cnVjdCBpcmlhcF9jYiAqc2VsZiA9IChzdHJ1Y3QgaXJpYXBfY2IgKikgZGF0YTsKCglJUkRBX0FTU0VSVChzZWxmICE9IE5VTEwsIHJldHVybjspOwoJSVJEQV9BU1NFUlQoc2VsZi0+bWFnaWMgPT0gSUFTX01BR0lDLCByZXR1cm47KTsKCgkvKiBpcmlhcF9jbG9zZShzZWxmKTsgKi8KfQoKI2lmZGVmIENPTkZJR19QUk9DX0ZTCgpzdGF0aWMgY29uc3QgY2hhciAqaWFzX3ZhbHVlX3R5cGVzW10gPSB7CgkiSUFTX01JU1NJTkciLAoJIklBU19JTlRFR0VSIiwKCSJJQVNfT0NUX1NFUSIsCgkiSUFTX1NUUklORyIKfTsKCnN0YXRpYyBpbmxpbmUgc3RydWN0IGlhc19vYmplY3QgKmlyaWFzX3NlcV9pZHgobG9mZl90IHBvcykKewoJc3RydWN0IGlhc19vYmplY3QgKm9iajsKCglmb3IgKG9iaiA9IChzdHJ1Y3QgaWFzX29iamVjdCAqKSBoYXNoYmluX2dldF9maXJzdChpcmlhc19vYmplY3RzKTsKCSAgICAgb2JqOyBvYmogPSAoc3RydWN0IGlhc19vYmplY3QgKikgaGFzaGJpbl9nZXRfbmV4dChpcmlhc19vYmplY3RzKSkgewoJCWlmIChwb3MtLSA9PSAwKQoJCQlicmVhazsKCX0KCglyZXR1cm4gb2JqOwp9CgpzdGF0aWMgdm9pZCAqaXJpYXNfc2VxX3N0YXJ0KHN0cnVjdCBzZXFfZmlsZSAqc2VxLCBsb2ZmX3QgKnBvcykKewoJc3Bpbl9sb2NrX2lycSgmaXJpYXNfb2JqZWN0cy0+aGJfc3BpbmxvY2spOwoKCXJldHVybiAqcG9zID8gaXJpYXNfc2VxX2lkeCgqcG9zIC0gMSkgOiBTRVFfU1RBUlRfVE9LRU47Cn0KCnN0YXRpYyB2b2lkICppcmlhc19zZXFfbmV4dChzdHJ1Y3Qgc2VxX2ZpbGUgKnNlcSwgdm9pZCAqdiwgbG9mZl90ICpwb3MpCnsKCSsrKnBvczsKCglyZXR1cm4gKHYgPT0gU0VRX1NUQVJUX1RPS0VOKQoJCT8gKHZvaWQgKikgaGFzaGJpbl9nZXRfZmlyc3QoaXJpYXNfb2JqZWN0cykKCQk6ICh2b2lkICopIGhhc2hiaW5fZ2V0X25leHQoaXJpYXNfb2JqZWN0cyk7Cn0KCnN0YXRpYyB2b2lkIGlyaWFzX3NlcV9zdG9wKHN0cnVjdCBzZXFfZmlsZSAqc2VxLCB2b2lkICp2KQp7CglzcGluX3VubG9ja19pcnEoJmlyaWFzX29iamVjdHMtPmhiX3NwaW5sb2NrKTsKfQoKc3RhdGljIGludCBpcmlhc19zZXFfc2hvdyhzdHJ1Y3Qgc2VxX2ZpbGUgKnNlcSwgdm9pZCAqdikKewoJaWYgKHYgPT0gU0VRX1NUQVJUX1RPS0VOKQoJCXNlcV9wdXRzKHNlcSwgIkxNLUlBUyBPYmplY3RzOlxuIik7CgllbHNlIHsKCQlzdHJ1Y3QgaWFzX29iamVjdCAqb2JqID0gdjsKCQlzdHJ1Y3QgaWFzX2F0dHJpYiAqYXR0cmliOwoKCQlJUkRBX0FTU0VSVChvYmotPm1hZ2ljID09IElBU19PQkpFQ1RfTUFHSUMsIHJldHVybiAtRUlOVkFMOyk7CgoJCXNlcV9wcmludGYoc2VxLCAibmFtZTogJXMsIGlkPSVkXG4iLAoJCQkgICBvYmotPm5hbWUsIG9iai0+aWQpOwoKCQkvKiBDYXJlZnVsIGZvciBwcmlvcml0eSBpbnZlcnNpb25zIGhlcmUgIQoJCSAqIEFsbCBvdGhlciB1c2VzIG9mIGF0dHJpYiBzcGlubG9jayBhcmUgaW5kZXBlbmRlbnQgb2YKCQkgKiB0aGUgb2JqZWN0IHNwaW5sb2NrLCBzbyB3ZSBhcmUgc2FmZS4gSmVhbiBJSSAqLwoJCXNwaW5fbG9jaygmb2JqLT5hdHRyaWJzLT5oYl9zcGlubG9jayk7CgoJCS8qIExpc3QgYWxsIGF0dHJpYnV0ZXMgZm9yIHRoaXMgb2JqZWN0ICovCgkJZm9yIChhdHRyaWIgPSAoc3RydWN0IGlhc19hdHRyaWIgKikgaGFzaGJpbl9nZXRfZmlyc3Qob2JqLT5hdHRyaWJzKTsKCQkgICAgIGF0dHJpYiAhPSBOVUxMOwoJCSAgICAgYXR0cmliID0gKHN0cnVjdCBpYXNfYXR0cmliICopIGhhc2hiaW5fZ2V0X25leHQob2JqLT5hdHRyaWJzKSkgewoKCQkJSVJEQV9BU1NFUlQoYXR0cmliLT5tYWdpYyA9PSBJQVNfQVRUUklCX01BR0lDLAoJCQkJICAgIGdvdG8gb3V0bG9vcDsgKTsKCgkJCXNlcV9wcmludGYoc2VxLCAiIC0gQXR0cmlidXRlIG5hbWU6IFwiJXNcIiwgIiwKCQkJCSAgIGF0dHJpYi0+bmFtZSk7CgkJCXNlcV9wcmludGYoc2VxLCAidmFsdWVbJXNdOiAiLAoJCQkJICAgaWFzX3ZhbHVlX3R5cGVzW2F0dHJpYi0+dmFsdWUtPnR5cGVdKTsKCgkJCXN3aXRjaCAoYXR0cmliLT52YWx1ZS0+dHlwZSkgewoJCQljYXNlIElBU19JTlRFR0VSOgoJCQkJc2VxX3ByaW50ZihzZXEsICIlZFxuIiwKCQkJCQkgICBhdHRyaWItPnZhbHVlLT50LmludGVnZXIpOwoJCQkJYnJlYWs7CgkJCWNhc2UgSUFTX1NUUklORzoKCQkJCXNlcV9wcmludGYoc2VxLCAiXCIlc1wiXG4iLAoJCQkJCSAgIGF0dHJpYi0+dmFsdWUtPnQuc3RyaW5nKTsKCQkJCWJyZWFrOwoJCQljYXNlIElBU19PQ1RfU0VROgoJCQkJc2VxX3ByaW50ZihzZXEsICJvY3RldCBzZXF1ZW5jZSAoJWQgYnl0ZXMpXG4iLAoJCQkJCSAgIGF0dHJpYi0+dmFsdWUtPmxlbik7CgkJCQlicmVhazsKCQkJY2FzZSBJQVNfTUlTU0lORzoKCQkJCXNlcV9wdXRzKHNlcSwgIm1pc3NpbmdcbiIpOwoJCQkJYnJlYWs7CgkJCWRlZmF1bHQ6CgkJCQlzZXFfcHJpbnRmKHNlcSwgInR5cGUgJWQ/XG4iLAoJCQkJCSAgIGF0dHJpYi0+dmFsdWUtPnR5cGUpOwoJCQl9CgkJCXNlcV9wdXRjKHNlcSwgJ1xuJyk7CgoJCX0KCUlSREFfQVNTRVJUX0xBQkVMKG91dGxvb3A6KQoJCXNwaW5fdW5sb2NrKCZvYmotPmF0dHJpYnMtPmhiX3NwaW5sb2NrKTsKCX0KCglyZXR1cm4gMDsKfQoKc3RhdGljIHN0cnVjdCBzZXFfb3BlcmF0aW9ucyBpcmlhc19zZXFfb3BzID0gewoJLnN0YXJ0ICA9IGlyaWFzX3NlcV9zdGFydCwKCS5uZXh0ICAgPSBpcmlhc19zZXFfbmV4dCwKCS5zdG9wICAgPSBpcmlhc19zZXFfc3RvcCwKCS5zaG93ICAgPSBpcmlhc19zZXFfc2hvdywKfTsKCnN0YXRpYyBpbnQgaXJpYXNfc2VxX29wZW4oc3RydWN0IGlub2RlICppbm9kZSwgc3RydWN0IGZpbGUgKmZpbGUpCnsKCUlSREFfQVNTRVJUKCBpcmlhc19vYmplY3RzICE9IE5VTEwsIHJldHVybiAtRUlOVkFMOyk7CgoJcmV0dXJuIHNlcV9vcGVuKGZpbGUsICZpcmlhc19zZXFfb3BzKTsKfQoKY29uc3Qgc3RydWN0IGZpbGVfb3BlcmF0aW9ucyBpcmlhc19zZXFfZm9wcyA9IHsKCS5vd25lcgkJPSBUSElTX01PRFVMRSwKCS5vcGVuICAgICAgICAgICA9IGlyaWFzX3NlcV9vcGVuLAoJLnJlYWQgICAgICAgICAgID0gc2VxX3JlYWQsCgkubGxzZWVrICAgICAgICAgPSBzZXFfbHNlZWssCgkucmVsZWFzZQk9IHNlcV9yZWxlYXNlLAp9OwoKI2VuZGlmIC8qIFBST0NfRlMgKi8K