LyogS2VybmVsIG1vZHVsZSB0byBjb250cm9sIHRoZSByYXRlCiAqCiAqIDIgU2VwdGVtYmVyIDE5OTk6IENoYW5nZWQgZnJvbSB0aGUgdGFyZ2V0IFJBVEUgdG8gdGhlIG1hdGNoCiAqICAgICAgICAgICAgICAgICAgIGBsaW1pdCcsIHJlbW92ZWQgbG9nZ2luZy4gIERpZCBJIG1lbnRpb24gdGhhdAogKiAgICAgICAgICAgICAgICAgICBBbGV4ZXkgaXMgYSBmdWNraW5nIGdlbml1cz8KICogICAgICAgICAgICAgICAgICAgUnVzdHkgUnVzc2VsbCAocnVzdHlAcnVzdGNvcnAuY29tLmF1KS4gICovCgovKiAoQykgMTk5OSBK6XL0bWUgZGUgVml2aWUgPGRldml2aWVAaW5mby5lbnNlcmIudS1ib3JkZWF1eC5mcj4KICogKEMpIDE5OTkgSGVydukgRXljaGVubmUgPGV5Y2hlbm5lQGluZm8uZW5zZXJiLnUtYm9yZGVhdXguZnI+CiAqCiAqIFRoaXMgcHJvZ3JhbSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5CiAqIGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIGFzCiAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgogKi8KCiNpbmNsdWRlIDxsaW51eC9tb2R1bGUuaD4KI2luY2x1ZGUgPGxpbnV4L3NrYnVmZi5oPgojaW5jbHVkZSA8bGludXgvc3BpbmxvY2suaD4KI2luY2x1ZGUgPGxpbnV4L2ludGVycnVwdC5oPgoKI2luY2x1ZGUgPGxpbnV4L25ldGZpbHRlci94X3RhYmxlcy5oPgojaW5jbHVkZSA8bGludXgvbmV0ZmlsdGVyL3h0X2xpbWl0Lmg+CgpNT0RVTEVfTElDRU5TRSgiR1BMIik7Ck1PRFVMRV9BVVRIT1IoIkhlcnZlIEV5Y2hlbm5lIDxydkB3YWxsZmlyZS5vcmc+Iik7Ck1PRFVMRV9ERVNDUklQVElPTigiaXB0YWJsZXMgcmF0ZSBsaW1pdCBtYXRjaCIpOwpNT0RVTEVfQUxJQVMoImlwdF9saW1pdCIpOwpNT0RVTEVfQUxJQVMoImlwNnRfbGltaXQiKTsKCi8qIFRoZSBhbGdvcml0aG0gdXNlZCBpcyB0aGUgU2ltcGxlIFRva2VuIEJ1Y2tldCBGaWx0ZXIgKFRCRikKICogc2VlIG5ldC9zY2hlZC9zY2hfdGJmLmMgaW4gdGhlIGxpbnV4IHNvdXJjZSB0cmVlCiAqLwoKc3RhdGljIERFRklORV9TUElOTE9DSyhsaW1pdF9sb2NrKTsKCi8qIFJ1c3R5OiBUaGlzIGlzIG15IChub24tbWF0aGVtYXRpY2FsbHktaW5jbGluZWQpIHVuZGVyc3RhbmRpbmcgb2YKICAgdGhpcyBhbGdvcml0aG0uICBUaGUgYGF2ZXJhZ2UgcmF0ZScgaW4gamlmZmllcyBiZWNvbWVzIHlvdXIgaW5pdGlhbAogICBhbW91bnQgb2YgY3JlZGl0IGBjcmVkaXQnIGFuZCB0aGUgbW9zdCBjcmVkaXQgeW91IGNhbiBldmVyIGhhdmUKICAgYGNyZWRpdF9jYXAnLiAgVGhlIGBwZWFrIHJhdGUnIGJlY29tZXMgdGhlIGNvc3Qgb2YgcGFzc2luZyB0aGUKICAgdGVzdCwgYGNvc3QnLgoKICAgYHByZXYnIHRyYWNrcyB0aGUgbGFzdCBwYWNrZXQgaGl0OiB5b3UgZ2FpbiBvbmUgY3JlZGl0IHBlciBqaWZmeS4KICAgSWYgeW91IGdldCBjcmVkaXQgYmFsYW5jZSBtb3JlIHRoYW4gdGhpcywgdGhlIGV4dHJhIGNyZWRpdCBpcwogICBkaXNjYXJkZWQuICBFdmVyeSB0aW1lIHRoZSBtYXRjaCBwYXNzZXMsIHlvdSBsb3NlIGBjb3N0JyBjcmVkaXRzOwogICBpZiB5b3UgZG9uJ3QgaGF2ZSB0aGF0IG1hbnksIHRoZSB0ZXN0IGZhaWxzLgoKICAgU2VlIEFsZXhleSdzIGZvcm1hbCBleHBsYW5hdGlvbiBpbiBuZXQvc2NoZWQvc2NoX3RiZi5jLgoKICAgVG8gZ2V0IHRoZSBtYXhtdW0gcmFuZ2UsIHdlIG11bHRpcGx5IGJ5IHRoaXMgZmFjdG9yIChpZS4geW91IGdldCBOCiAgIGNyZWRpdHMgcGVyIGppZmZ5KS4gIFdlIHdhbnQgdG8gYWxsb3cgYSByYXRlIGFzIGxvdyBhcyAxIHBlciBkYXkKICAgKHNsb3dlc3QgdXNlcnNwYWNlIHRvb2wgYWxsb3dzKSwgd2hpY2ggbWVhbnMKICAgQ1JFRElUU19QRVJfSklGRlkqSFoqNjAqNjAqMjQgPCAyXjMyLiBpZS4gKi8KI2RlZmluZSBNQVhfQ1BKICgweEZGRkZGRkZGIC8gKEhaKjYwKjYwKjI0KSkKCi8qIFJlcGVhdGVkIHNoaWZ0IGFuZCBvciBnaXZlcyB1cyBhbGwgMXMsIGZpbmFsIHNoaWZ0IGFuZCBhZGQgMSBnaXZlcwogKiB1cyB0aGUgcG93ZXIgb2YgMiBiZWxvdyB0aGUgdGhlb3JldGljYWwgbWF4LCBzbyBHQ0Mgc2ltcGx5IGRvZXMgYQogKiBzaGlmdC4gKi8KI2RlZmluZSBfUE9XMl9CRUxPVzIoeCkgKCh4KXwoKHgpPj4xKSkKI2RlZmluZSBfUE9XMl9CRUxPVzQoeCkgKF9QT1cyX0JFTE9XMih4KXxfUE9XMl9CRUxPVzIoKHgpPj4yKSkKI2RlZmluZSBfUE9XMl9CRUxPVzgoeCkgKF9QT1cyX0JFTE9XNCh4KXxfUE9XMl9CRUxPVzQoKHgpPj40KSkKI2RlZmluZSBfUE9XMl9CRUxPVzE2KHgpIChfUE9XMl9CRUxPVzgoeCl8X1BPVzJfQkVMT1c4KCh4KT4+OCkpCiNkZWZpbmUgX1BPVzJfQkVMT1czMih4KSAoX1BPVzJfQkVMT1cxNih4KXxfUE9XMl9CRUxPVzE2KCh4KT4+MTYpKQojZGVmaW5lIFBPVzJfQkVMT1czMih4KSAoKF9QT1cyX0JFTE9XMzIoeCk+PjEpICsgMSkKCiNkZWZpbmUgQ1JFRElUU19QRVJfSklGRlkgUE9XMl9CRUxPVzMyKE1BWF9DUEopCgpzdGF0aWMgaW50CmlwdF9saW1pdF9tYXRjaChjb25zdCBzdHJ1Y3Qgc2tfYnVmZiAqc2tiLAoJCWNvbnN0IHN0cnVjdCBuZXRfZGV2aWNlICppbiwKCQljb25zdCBzdHJ1Y3QgbmV0X2RldmljZSAqb3V0LAoJCWNvbnN0IHN0cnVjdCB4dF9tYXRjaCAqbWF0Y2gsCgkJY29uc3Qgdm9pZCAqbWF0Y2hpbmZvLAoJCWludCBvZmZzZXQsCgkJdW5zaWduZWQgaW50IHByb3RvZmYsCgkJaW50ICpob3Rkcm9wKQp7CglzdHJ1Y3QgeHRfcmF0ZWluZm8gKnIgPSAoKHN0cnVjdCB4dF9yYXRlaW5mbyAqKW1hdGNoaW5mbyktPm1hc3RlcjsKCXVuc2lnbmVkIGxvbmcgbm93ID0gamlmZmllczsKCglzcGluX2xvY2tfYmgoJmxpbWl0X2xvY2spOwoJci0+Y3JlZGl0ICs9IChub3cgLSB4Y2hnKCZyLT5wcmV2LCBub3cpKSAqIENSRURJVFNfUEVSX0pJRkZZOwoJaWYgKHItPmNyZWRpdCA+IHItPmNyZWRpdF9jYXApCgkJci0+Y3JlZGl0ID0gci0+Y3JlZGl0X2NhcDsKCglpZiAoci0+Y3JlZGl0ID49IHItPmNvc3QpIHsKCQkvKiBXZSdyZSBub3QgbGltaXRlZC4gKi8KCQlyLT5jcmVkaXQgLT0gci0+Y29zdDsKCQlzcGluX3VubG9ja19iaCgmbGltaXRfbG9jayk7CgkJcmV0dXJuIDE7Cgl9CgoJc3Bpbl91bmxvY2tfYmgoJmxpbWl0X2xvY2spOwoJcmV0dXJuIDA7Cn0KCi8qIFByZWNpc2lvbiBzYXZlci4gKi8Kc3RhdGljIHVfaW50MzJfdAp1c2VyMmNyZWRpdHModV9pbnQzMl90IHVzZXIpCnsKCS8qIElmIG11bHRpcGx5aW5nIHdvdWxkIG92ZXJmbG93Li4uICovCglpZiAodXNlciA+IDB4RkZGRkZGRkYgLyAoSFoqQ1JFRElUU19QRVJfSklGRlkpKQoJCS8qIERpdmlkZSBmaXJzdC4gKi8KCQlyZXR1cm4gKHVzZXIgLyBYVF9MSU1JVF9TQ0FMRSkgKiBIWiAqIENSRURJVFNfUEVSX0pJRkZZOwoKCXJldHVybiAodXNlciAqIEhaICogQ1JFRElUU19QRVJfSklGRlkpIC8gWFRfTElNSVRfU0NBTEU7Cn0KCnN0YXRpYyBpbnQKaXB0X2xpbWl0X2NoZWNrZW50cnkoY29uc3QgY2hhciAqdGFibGVuYW1lLAoJCSAgICAgY29uc3Qgdm9pZCAqaW5mLAoJCSAgICAgY29uc3Qgc3RydWN0IHh0X21hdGNoICptYXRjaCwKCQkgICAgIHZvaWQgKm1hdGNoaW5mbywKCQkgICAgIHVuc2lnbmVkIGludCBob29rX21hc2spCnsKCXN0cnVjdCB4dF9yYXRlaW5mbyAqciA9IG1hdGNoaW5mbzsKCgkvKiBDaGVjayBmb3Igb3ZlcmZsb3cuICovCglpZiAoci0+YnVyc3QgPT0gMAoJICAgIHx8IHVzZXIyY3JlZGl0cyhyLT5hdmcgKiByLT5idXJzdCkgPCB1c2VyMmNyZWRpdHMoci0+YXZnKSkgewoJCXByaW50aygiT3ZlcmZsb3cgaW4geHRfbGltaXQsIHRyeSBsb3dlcjogJXUvJXVcbiIsCgkJICAgICAgIHItPmF2Zywgci0+YnVyc3QpOwoJCXJldHVybiAwOwoJfQoKCS8qIEZvciBTTVAsIHdlIG9ubHkgd2FudCB0byB1c2Ugb25lIHNldCBvZiBjb3VudGVycy4gKi8KCXItPm1hc3RlciA9IHI7CglpZiAoci0+Y29zdCA9PSAwKSB7CgkJLyogVXNlciBhdmcgaW4gc2Vjb25kcyAqIFhUX0xJTUlUX1NDQUxFOiBjb252ZXJ0IHRvIGppZmZpZXMgKgoJCSAgIDEyOC4gKi8KCQlyLT5wcmV2ID0gamlmZmllczsKCQlyLT5jcmVkaXQgPSB1c2VyMmNyZWRpdHMoci0+YXZnICogci0+YnVyc3QpOwkgLyogQ3JlZGl0cyBmdWxsLiAqLwoJCXItPmNyZWRpdF9jYXAgPSB1c2VyMmNyZWRpdHMoci0+YXZnICogci0+YnVyc3QpOyAvKiBDcmVkaXRzIGZ1bGwuICovCgkJci0+Y29zdCA9IHVzZXIyY3JlZGl0cyhyLT5hdmcpOwoJfQoJcmV0dXJuIDE7Cn0KCiNpZmRlZiBDT05GSUdfQ09NUEFUCnN0cnVjdCBjb21wYXRfeHRfcmF0ZWluZm8gewoJdV9pbnQzMl90IGF2ZzsKCXVfaW50MzJfdCBidXJzdDsKCgljb21wYXRfdWxvbmdfdCBwcmV2OwoJdV9pbnQzMl90IGNyZWRpdDsKCXVfaW50MzJfdCBjcmVkaXRfY2FwLCBjb3N0OwoKCXVfaW50MzJfdCBtYXN0ZXI7Cn07CgovKiBUbyBrZWVwIHRoZSBmdWxsICJwcmV2IiB0aW1lc3RhbXAsIHRoZSB1cHBlciAzMiBiaXRzIGFyZSBzdG9yZWQgaW4gdGhlCiAqIG1hc3RlciBwb2ludGVyLCB3aGljaCBkb2VzIG5vdCBuZWVkIHRvIGJlIHByZXNlcnZlZC4gKi8Kc3RhdGljIHZvaWQgY29tcGF0X2Zyb21fdXNlcih2b2lkICpkc3QsIHZvaWQgKnNyYykKewoJc3RydWN0IGNvbXBhdF94dF9yYXRlaW5mbyAqY20gPSBzcmM7CglzdHJ1Y3QgeHRfcmF0ZWluZm8gbSA9IHsKCQkuYXZnCQk9IGNtLT5hdmcsCgkJLmJ1cnN0CQk9IGNtLT5idXJzdCwKCQkucHJldgkJPSBjbS0+cHJldiB8ICh1bnNpZ25lZCBsb25nKWNtLT5tYXN0ZXIgPDwgMzIsCgkJLmNyZWRpdAkJPSBjbS0+Y3JlZGl0LAoJCS5jcmVkaXRfY2FwCT0gY20tPmNyZWRpdF9jYXAsCgkJLmNvc3QJCT0gY20tPmNvc3QsCgl9OwoJbWVtY3B5KGRzdCwgJm0sIHNpemVvZihtKSk7Cn0KCnN0YXRpYyBpbnQgY29tcGF0X3RvX3VzZXIodm9pZCBfX3VzZXIgKmRzdCwgdm9pZCAqc3JjKQp7CglzdHJ1Y3QgeHRfcmF0ZWluZm8gKm0gPSBzcmM7CglzdHJ1Y3QgY29tcGF0X3h0X3JhdGVpbmZvIGNtID0gewoJCS5hdmcJCT0gbS0+YXZnLAoJCS5idXJzdAkJPSBtLT5idXJzdCwKCQkucHJldgkJPSBtLT5wcmV2LAoJCS5jcmVkaXQJCT0gbS0+Y3JlZGl0LAoJCS5jcmVkaXRfY2FwCT0gbS0+Y3JlZGl0X2NhcCwKCQkuY29zdAkJPSBtLT5jb3N0LAoJCS5tYXN0ZXIJCT0gbS0+cHJldiA+PiAzMiwKCX07CglyZXR1cm4gY29weV90b191c2VyKGRzdCwgJmNtLCBzaXplb2YoY20pKSA/IC1FRkFVTFQgOiAwOwp9CiNlbmRpZiAvKiBDT05GSUdfQ09NUEFUICovCgpzdGF0aWMgc3RydWN0IHh0X21hdGNoIHh0X2xpbWl0X21hdGNoW10gPSB7Cgl7CgkJLm5hbWUJCT0gImxpbWl0IiwKCQkuZmFtaWx5CQk9IEFGX0lORVQsCgkJLmNoZWNrZW50cnkJPSBpcHRfbGltaXRfY2hlY2tlbnRyeSwKCQkubWF0Y2gJCT0gaXB0X2xpbWl0X21hdGNoLAoJCS5tYXRjaHNpemUJPSBzaXplb2Yoc3RydWN0IHh0X3JhdGVpbmZvKSwKI2lmZGVmIENPTkZJR19DT01QQVQKCQkuY29tcGF0c2l6ZQk9IHNpemVvZihzdHJ1Y3QgY29tcGF0X3h0X3JhdGVpbmZvKSwKCQkuY29tcGF0X2Zyb21fdXNlciA9IGNvbXBhdF9mcm9tX3VzZXIsCgkJLmNvbXBhdF90b191c2VyCT0gY29tcGF0X3RvX3VzZXIsCiNlbmRpZgoJCS5tZQkJPSBUSElTX01PRFVMRSwKCX0sCgl7CgkJLm5hbWUJCT0gImxpbWl0IiwKCQkuZmFtaWx5CQk9IEFGX0lORVQ2LAoJCS5jaGVja2VudHJ5CT0gaXB0X2xpbWl0X2NoZWNrZW50cnksCgkJLm1hdGNoCQk9IGlwdF9saW1pdF9tYXRjaCwKCQkubWF0Y2hzaXplCT0gc2l6ZW9mKHN0cnVjdCB4dF9yYXRlaW5mbyksCgkJLm1lCQk9IFRISVNfTU9EVUxFLAoJfSwKfTsKCnN0YXRpYyBpbnQgX19pbml0IHh0X2xpbWl0X2luaXQodm9pZCkKewoJcmV0dXJuIHh0X3JlZ2lzdGVyX21hdGNoZXMoeHRfbGltaXRfbWF0Y2gsIEFSUkFZX1NJWkUoeHRfbGltaXRfbWF0Y2gpKTsKfQoKc3RhdGljIHZvaWQgX19leGl0IHh0X2xpbWl0X2Zpbmkodm9pZCkKewoJeHRfdW5yZWdpc3Rlcl9tYXRjaGVzKHh0X2xpbWl0X21hdGNoLCBBUlJBWV9TSVpFKHh0X2xpbWl0X21hdGNoKSk7Cn0KCm1vZHVsZV9pbml0KHh0X2xpbWl0X2luaXQpOwptb2R1bGVfZXhpdCh4dF9saW1pdF9maW5pKTsK