LyogS2VybmVsIG1vZHVsZSB0byBjb250cm9sIHRoZSByYXRlCiAqCiAqIDIgU2VwdGVtYmVyIDE5OTk6IENoYW5nZWQgZnJvbSB0aGUgdGFyZ2V0IFJBVEUgdG8gdGhlIG1hdGNoCiAqICAgICAgICAgICAgICAgICAgIGBsaW1pdCcsIHJlbW92ZWQgbG9nZ2luZy4gIERpZCBJIG1lbnRpb24gdGhhdAogKiAgICAgICAgICAgICAgICAgICBBbGV4ZXkgaXMgYSBmdWNraW5nIGdlbml1cz8KICogICAgICAgICAgICAgICAgICAgUnVzdHkgUnVzc2VsbCAocnVzdHlAcnVzdGNvcnAuY29tLmF1KS4gICovCgovKiAoQykgMTk5OSBK6XL0bWUgZGUgVml2aWUgPGRldml2aWVAaW5mby5lbnNlcmIudS1ib3JkZWF1eC5mcj4KICogKEMpIDE5OTkgSGVydukgRXljaGVubmUgPGV5Y2hlbm5lQGluZm8uZW5zZXJiLnUtYm9yZGVhdXguZnI+CiAqCiAqIFRoaXMgcHJvZ3JhbSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5CiAqIGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIGFzCiAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgogKi8KCiNpbmNsdWRlIDxsaW51eC9tb2R1bGUuaD4KI2luY2x1ZGUgPGxpbnV4L3NrYnVmZi5oPgojaW5jbHVkZSA8bGludXgvc3BpbmxvY2suaD4KI2luY2x1ZGUgPGxpbnV4L2ludGVycnVwdC5oPgoKI2luY2x1ZGUgPGxpbnV4L25ldGZpbHRlcl9pcHY2L2lwNl90YWJsZXMuaD4KI2luY2x1ZGUgPGxpbnV4L25ldGZpbHRlcl9pcHY2L2lwNnRfbGltaXQuaD4KCk1PRFVMRV9MSUNFTlNFKCJHUEwiKTsKTU9EVUxFX0FVVEhPUigiSGVydmUgRXljaGVubmUgPHJ2QHdhbGxmaXJlLm9yZz4iKTsKTU9EVUxFX0RFU0NSSVBUSU9OKCJyYXRlIGxpbWl0aW5nIHdpdGhpbiBpcDZ0YWJsZXMiKTsKCi8qIFRoZSBhbGdvcml0aG0gdXNlZCBpcyB0aGUgU2ltcGxlIFRva2VuIEJ1Y2tldCBGaWx0ZXIgKFRCRikKICogc2VlIG5ldC9zY2hlZC9zY2hfdGJmLmMgaW4gdGhlIGxpbnV4IHNvdXJjZSB0cmVlCiAqLwoKc3RhdGljIERFRklORV9TUElOTE9DSyhsaW1pdF9sb2NrKTsKCi8qIFJ1c3R5OiBUaGlzIGlzIG15IChub24tbWF0aGVtYXRpY2FsbHktaW5jbGluZWQpIHVuZGVyc3RhbmRpbmcgb2YKICAgdGhpcyBhbGdvcml0aG0uICBUaGUgYGF2ZXJhZ2UgcmF0ZScgaW4gamlmZmllcyBiZWNvbWVzIHlvdXIgaW5pdGlhbAogICBhbW91bnQgb2YgY3JlZGl0IGBjcmVkaXQnIGFuZCB0aGUgbW9zdCBjcmVkaXQgeW91IGNhbiBldmVyIGhhdmUKICAgYGNyZWRpdF9jYXAnLiAgVGhlIGBwZWFrIHJhdGUnIGJlY29tZXMgdGhlIGNvc3Qgb2YgcGFzc2luZyB0aGUKICAgdGVzdCwgYGNvc3QnLgoKICAgYHByZXYnIHRyYWNrcyB0aGUgbGFzdCBwYWNrZXQgaGl0OiB5b3UgZ2FpbiBvbmUgY3JlZGl0IHBlciBqaWZmeS4KICAgSWYgeW91IGdldCBjcmVkaXQgYmFsYW5jZSBtb3JlIHRoYW4gdGhpcywgdGhlIGV4dHJhIGNyZWRpdCBpcwogICBkaXNjYXJkZWQuICBFdmVyeSB0aW1lIHRoZSBtYXRjaCBwYXNzZXMsIHlvdSBsb3NlIGBjb3N0JyBjcmVkaXRzOwogICBpZiB5b3UgZG9uJ3QgaGF2ZSB0aGF0IG1hbnksIHRoZSB0ZXN0IGZhaWxzLgoKICAgU2VlIEFsZXhleSdzIGZvcm1hbCBleHBsYW5hdGlvbiBpbiBuZXQvc2NoZWQvc2NoX3RiZi5jLgoKICAgVG8gYXZvaWQgdW5kZXJmbG93LCB3ZSBtdWx0aXBseSBieSAxMjggKGllLiB5b3UgZ2V0IDEyOCBjcmVkaXRzIHBlcgogICBqaWZmeSkuICBIZW5jZSBhIGNvc3Qgb2YgMl4zMi0xLCBtZWFucyBvbmUgcGFzcyBwZXIgMzI3Njggc2Vjb25kcwogICBhdCAxMDI0SFogKG9yIG9uZSBldmVyeSA5IGhvdXJzKS4gIEEgY29zdCBvZiAxIG1lYW5zIDEyODAwIHBhc3NlcwogICBwZXIgc2Vjb25kIGF0IDEwMEhaLiAgKi8KCiNkZWZpbmUgQ1JFRElUU19QRVJfSklGRlkgMTI4CgpzdGF0aWMgaW50CmlwNnRfbGltaXRfbWF0Y2goY29uc3Qgc3RydWN0IHNrX2J1ZmYgKnNrYiwKCQljb25zdCBzdHJ1Y3QgbmV0X2RldmljZSAqaW4sCgkJY29uc3Qgc3RydWN0IG5ldF9kZXZpY2UgKm91dCwKCQljb25zdCB2b2lkICptYXRjaGluZm8sCgkJaW50IG9mZnNldCwKCQl1bnNpZ25lZCBpbnQgcHJvdG9mZiwKCQlpbnQgKmhvdGRyb3ApCnsKCXN0cnVjdCBpcDZ0X3JhdGVpbmZvICpyID0gKChzdHJ1Y3QgaXA2dF9yYXRlaW5mbyAqKW1hdGNoaW5mbyktPm1hc3RlcjsKCXVuc2lnbmVkIGxvbmcgbm93ID0gamlmZmllczsKCglzcGluX2xvY2tfYmgoJmxpbWl0X2xvY2spOwoJci0+Y3JlZGl0ICs9IChub3cgLSB4Y2hnKCZyLT5wcmV2LCBub3cpKSAqIENSRURJVFNfUEVSX0pJRkZZOwoJaWYgKHItPmNyZWRpdCA+IHItPmNyZWRpdF9jYXApCgkJci0+Y3JlZGl0ID0gci0+Y3JlZGl0X2NhcDsKCglpZiAoci0+Y3JlZGl0ID49IHItPmNvc3QpIHsKCQkvKiBXZSdyZSBub3QgbGltaXRlZC4gKi8KCQlyLT5jcmVkaXQgLT0gci0+Y29zdDsKCQlzcGluX3VubG9ja19iaCgmbGltaXRfbG9jayk7CgkJcmV0dXJuIDE7Cgl9CgogICAgICAgCXNwaW5fdW5sb2NrX2JoKCZsaW1pdF9sb2NrKTsKCXJldHVybiAwOwp9CgovKiBQcmVjaXNpb24gc2F2ZXIuICovCnN0YXRpYyB1X2ludDMyX3QKdXNlcjJjcmVkaXRzKHVfaW50MzJfdCB1c2VyKQp7CgkvKiBJZiBtdWx0aXBseWluZyB3b3VsZCBvdmVyZmxvdy4uLiAqLwoJaWYgKHVzZXIgPiAweEZGRkZGRkZGIC8gKEhaKkNSRURJVFNfUEVSX0pJRkZZKSkKCQkvKiBEaXZpZGUgZmlyc3QuICovCgkJcmV0dXJuICh1c2VyIC8gSVA2VF9MSU1JVF9TQ0FMRSkgKiBIWiAqIENSRURJVFNfUEVSX0pJRkZZOwoKCXJldHVybiAodXNlciAqIEhaICogQ1JFRElUU19QRVJfSklGRlkpIC8gSVA2VF9MSU1JVF9TQ0FMRTsKfQoKc3RhdGljIGludAppcDZ0X2xpbWl0X2NoZWNrZW50cnkoY29uc3QgY2hhciAqdGFibGVuYW1lLAoJCSAgICAgY29uc3Qgc3RydWN0IGlwNnRfaXA2ICppcCwKCQkgICAgIHZvaWQgKm1hdGNoaW5mbywKCQkgICAgIHVuc2lnbmVkIGludCBtYXRjaHNpemUsCgkJICAgICB1bnNpZ25lZCBpbnQgaG9va19tYXNrKQp7CglzdHJ1Y3QgaXA2dF9yYXRlaW5mbyAqciA9IG1hdGNoaW5mbzsKCglpZiAobWF0Y2hzaXplICE9IElQNlRfQUxJR04oc2l6ZW9mKHN0cnVjdCBpcDZ0X3JhdGVpbmZvKSkpCgkJcmV0dXJuIDA7CgoJLyogQ2hlY2sgZm9yIG92ZXJmbG93LiAqLwoJaWYgKHItPmJ1cnN0ID09IDAKCSAgICB8fCB1c2VyMmNyZWRpdHMoci0+YXZnICogci0+YnVyc3QpIDwgdXNlcjJjcmVkaXRzKHItPmF2ZykpIHsKCQlwcmludGsoIkNhbGwgcnVzdHk6IG92ZXJmbG93IGluIGlwNnRfbGltaXQ6ICV1LyV1XG4iLAoJCSAgICAgICByLT5hdmcsIHItPmJ1cnN0KTsKCQlyZXR1cm4gMDsKCX0KCgkvKiBVc2VyIGF2ZyBpbiBzZWNvbmRzICogSVA2VF9MSU1JVF9TQ0FMRTogY29udmVydCB0byBqaWZmaWVzICoKCSAgIDEyOC4gKi8KCXItPnByZXYgPSBqaWZmaWVzOwoJci0+Y3JlZGl0ID0gdXNlcjJjcmVkaXRzKHItPmF2ZyAqIHItPmJ1cnN0KTsJIC8qIENyZWRpdHMgZnVsbC4gKi8KCXItPmNyZWRpdF9jYXAgPSB1c2VyMmNyZWRpdHMoci0+YXZnICogci0+YnVyc3QpOyAvKiBDcmVkaXRzIGZ1bGwuICovCglyLT5jb3N0ID0gdXNlcjJjcmVkaXRzKHItPmF2Zyk7CgoJLyogRm9yIFNNUCwgd2Ugb25seSB3YW50IHRvIHVzZSBvbmUgc2V0IG9mIGNvdW50ZXJzLiAqLwoJci0+bWFzdGVyID0gcjsKCglyZXR1cm4gMTsKfQoKc3RhdGljIHN0cnVjdCBpcDZ0X21hdGNoIGlwNnRfbGltaXRfcmVnID0gewoJLm5hbWUJCT0gImxpbWl0IiwKCS5tYXRjaAkJPSBpcDZ0X2xpbWl0X21hdGNoLAoJLmNoZWNrZW50cnkJPSBpcDZ0X2xpbWl0X2NoZWNrZW50cnksCgkubWUJCT0gVEhJU19NT0RVTEUsCn07CgpzdGF0aWMgaW50IF9faW5pdCBpbml0KHZvaWQpCnsKCWlmIChpcDZ0X3JlZ2lzdGVyX21hdGNoKCZpcDZ0X2xpbWl0X3JlZykpCgkJcmV0dXJuIC1FSU5WQUw7CglyZXR1cm4gMDsKfQoKc3RhdGljIHZvaWQgX19leGl0IGZpbmkodm9pZCkKewoJaXA2dF91bnJlZ2lzdGVyX21hdGNoKCZpcDZ0X2xpbWl0X3JlZyk7Cn0KCm1vZHVsZV9pbml0KGluaXQpOwptb2R1bGVfZXhpdChmaW5pKTsK