LyoKICogbGludXgvZHJpdmVycy9pZGUvaWRlLWNkLmMKICoKICogQ29weXJpZ2h0IChDKSAxOTk0LCAxOTk1LCAxOTk2ICBzY290dCBzbnlkZXIgIDxzbnlkZXJAZm5hbGQwLmZuYWwuZ292PgogKiBDb3B5cmlnaHQgKEMpIDE5OTYtMTk5OCAgRXJpayBBbmRlcnNlbiA8YW5kZXJzZWVAZGViaWFuLm9yZz4KICogQ29weXJpZ2h0IChDKSAxOTk4LTIwMDAgIEplbnMgQXhib2UgPGF4Ym9lQHN1c2UuZGU+CiAqCiAqIE1heSBiZSBjb3BpZWQgb3IgbW9kaWZpZWQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMKICogTGljZW5zZS4gIFNlZSBsaW51eC9DT1BZSU5HIGZvciBtb3JlIGluZm9ybWF0aW9uLgogKgogKiBBVEFQSSBDRC1ST00gZHJpdmVyLiAgVG8gYmUgdXNlZCB3aXRoIGlkZS5jLgogKiBTZWUgRG9jdW1lbnRhdGlvbi9jZHJvbS9pZGUtY2QgZm9yIHVzYWdlIGluZm9ybWF0aW9uLgogKgogKiBTdWdnZXN0aW9ucyBhcmUgd2VsY29tZS4gUGF0Y2hlcyB0aGF0IHdvcmsgYXJlIG1vcmUgd2VsY29tZSB0aG91Z2guIDstKQogKiBGb3IgdGhvc2Ugd2lzaGluZyB0byB3b3JrIG9uIHRoaXMgZHJpdmVyLCBwbGVhc2UgYmUgc3VyZSB5b3UgZG93bmxvYWQKICogYW5kIGNvbXBseSB3aXRoIHRoZSBsYXRlc3QgTXQuIEZ1amkgKFNGRjgwOTAgdmVyc2lvbiA0KSBhbmQgQVRBUEkgCiAqIChTRkYtODAyMGkgcmV2IDIuNikgc3RhbmRhcmRzLiBUaGVzZSBkb2N1bWVudHMgY2FuIGJlIG9idGFpbmVkIGJ5IAogKiBhbm9ueW1vdXMgZnRwIGZyb206CiAqIGZ0cDovL2Zpc3Npb24uZHQud2RjLmNvbS9wdWIvc3RhbmRhcmRzL1NGRl9hdGFwaS9zcGVjL1NGRjgwMjAtcjIuNi9QUy84MDIwcjI2LnBzCiAqIGZ0cDovL2Z0cC5hdmMtcGlvbmVlci5jb20vTXRmdWppNC9TcGVjL0Z1amk0cjEwLnBkZgogKgogKiBEcml2ZXMgdGhhdCBkZXZpYXRlIGZyb20gdGhlc2Ugc3RhbmRhcmRzIHdpbGwgYmUgYWNjb21tb2RhdGVkIGFzIG11Y2gKICogYXMgcG9zc2libGUgdmlhIGNvbXBpbGUgdGltZSBvciBjb21tYW5kLWxpbmUgb3B0aW9ucy4gIFNpbmNlIEkgb25seSBoYXZlCiAqIGEgZmV3IGRyaXZlcywgeW91IGdlbmVyYWxseSBuZWVkIHRvIHNlbmQgbWUgcGF0Y2hlcy4uLgogKgogKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAqIFRPIERPIExJU1Q6CiAqIC1NYWtlIGl0IHNvIHRoYXQgUGlvbmVlciBDRCBEUi1BMjRYIGFuZCBmcmllbmRzIGRvbid0IGdldCBzY3Jld2VkIHVwIG9uCiAqICAgYm9vdAogKgogKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAqIDEuMDAgIE9jdCAzMSwgMTk5NCAtLSBJbml0aWFsIHZlcnNpb24uCiAqIDEuMDEgIE5vdiAgMiwgMTk5NCAtLSBGaXhlZCBwcm9ibGVtIHdpdGggc3RhcnRpbmcgcmVxdWVzdCBpbgogKiAgICAgICAgICAgICAgICAgICAgICAgY2Ryb21fY2hlY2tfc3RhdHVzLgogKiAxLjAzICBOb3YgMjUsIDE5OTQgLS0gbGVhdmluZyB1bm1hc2tfaW50cltdIGFzIGEgdXNlci1zZXR0aW5nIChhcyBmb3IgZGlza3MpCiAqIChmcm9tIG1sb3JkKSAgICAgICAtLSBtaW5vciBjaGFuZ2VzIHRvIGNkcm9tX3NldHVwKCkKICogICAgICAgICAgICAgICAgICAgIC0tIHJlbmFtZWQgaWRlX2Rldl9zIHRvIGlkZV9kcml2ZV90LCBlbmFibGUgaXJxIG9uIGNvbW1hbmQKICogMi4wMCAgTm92IDI3LCAxOTk0IC0tIEdlbmVyYWxpemUgcGFja2V0IGNvbW1hbmQgaW50ZXJmYWNlOwogKiAgICAgICAgICAgICAgICAgICAgICAgYWRkIGF1ZGlvIGlvY3Rscy4KICogMi4wMSAgRGVjICAzLCAxOTk0IC0tIFJld29yayBwYWNrZXQgY29tbWFuZCBpbnRlcmZhY2UgdG8gaGFuZGxlIGRldmljZXMKICogICAgICAgICAgICAgICAgICAgICAgIHdoaWNoIHNlbmQgYW4gaW50ZXJydXB0IHdoZW4gcmVhZHkgZm9yIGEgY29tbWFuZC4KICogMi4wMiAgRGVjIDExLCAxOTk0IC0tIENhY2hlIHRoZSBUT0MgaW4gdGhlIGRyaXZlci4KICogICAgICAgICAgICAgICAgICAgICAgIERvbid0IHVzZSBTQ01EX1BMQVlBVURJT19USTsgaXQncyBub3QgaW5jbHVkZWQKICogICAgICAgICAgICAgICAgICAgICAgIGluIHRoZSBjdXJyZW50IHZlcnNpb24gb2YgQVRBUEkuCiAqICAgICAgICAgICAgICAgICAgICAgICBUcnkgdG8gdXNlIExCQSBpbnN0ZWFkIG9mIHRyYWNrIG9yIE1TRiBhZGRyZXNzaW5nCiAqICAgICAgICAgICAgICAgICAgICAgICB3aGVuIHBvc3NpYmxlLgogKiAgICAgICAgICAgICAgICAgICAgICAgRG9uJ3Qgd2FpdCBmb3IgUkVBRFlfU1RBVC4KICogMi4wMyAgSmFuIDEwLCAxOTk1IC0tIFJld3JpdGUgYmxvY2sgcmVhZCByb3V0aW5lcyB0byBoYW5kbGUgYmxvY2sgc2l6ZXMKICogICAgICAgICAgICAgICAgICAgICAgIG90aGVyIHRoYW4gMmsgYW5kIHRvIG1vdmUgbXVsdGlwbGUgc2VjdG9ycyBpbiBhCiAqICAgICAgICAgICAgICAgICAgICAgICBzaW5nbGUgdHJhbnNhY3Rpb24uCiAqIDIuMDQgIEFwciAyMSwgMTk5NSAtLSBBZGQgd29yay1hcm91bmQgZm9yIENyZWF0aXZlIExhYnMgQ0QyMjBFIGRyaXZlcy4KICogICAgICAgICAgICAgICAgICAgICAgIFRoYW5rcyB0byBOaWNrIFNhdyA8Y3dzYXdAcHRzNy5wdHMubW90LmNvbT4gZm9yCiAqICAgICAgICAgICAgICAgICAgICAgICBoZWxwIGluIGZpZ3VyaW5nIHRoaXMgb3V0LiAgRGl0dG8gZm9yIEFjZXIgYW5kCiAqICAgICAgICAgICAgICAgICAgICAgICBBenRlY2ggZHJpdmVzLCB3aGljaCBzZWVtIHRvIGhhdmUgdGhlIHNhbWUgcHJvYmxlbS4KICogMi4wNGIgTWF5IDMwLCAxOTk1IC0tIEZpeCB0byBtYXRjaCBjaGFuZ2VzIGluIGlkZS5jIHZlcnNpb24gMy4xNiAtbWwKICogMi4wNSAgSnVuICA4LCAxOTk1IC0tIERvbid0IGF0dGVtcHQgdG8gcmV0cnkgYWZ0ZXIgYW4gaWxsZWdhbCByZXF1ZXN0CiAqICAgICAgICAgICAgICAgICAgICAgICAgb3IgZGF0YSBwcm90ZWN0IGVycm9yLgogKiAgICAgICAgICAgICAgICAgICAgICAgVXNlIEhXSUYgYW5kIERFVl9IV0lGIG1hY3JvcyBhcyBpbiBpZGUuYy4KICogICAgICAgICAgICAgICAgICAgICAgIEFsd2F5cyB0cnkgdG8gZG8gYSByZXF1ZXN0X3NlbnNlIGFmdGVyCiAqICAgICAgICAgICAgICAgICAgICAgICAgYSBmYWlsZWQgY29tbWFuZC4KICogICAgICAgICAgICAgICAgICAgICAgIEluY2x1ZGUgYW4gb3B0aW9uIHRvIGdpdmUgdGV4dHVhbCBkZXNjcmlwdGlvbnMKICogICAgICAgICAgICAgICAgICAgICAgICBvZiBBVEFQSSBlcnJvcnMuCiAqICAgICAgICAgICAgICAgICAgICAgICBGaXggYSBidWcgaW4gaGFuZGxpbmcgdGhlIHNlY3RvciBjYWNoZSB3aGljaAogKiAgICAgICAgICAgICAgICAgICAgICAgIHNob3dlZCB1cCBpZiB0aGUgZHJpdmUgcmV0dXJuZWQgZGF0YSBpbiA1MTIgYnl0ZQogKiAgICAgICAgICAgICAgICAgICAgICAgIGJsb2NrcyAobGlrZSBQaW9uZWVyIGRyaXZlcykuICBUaGFua3MgdG8KICogICAgICAgICAgICAgICAgICAgICAgICBSaWNoYXJkIEhpcnN0IDxzcmhAZ3B0LmNvLnVrPiBmb3IgZGlhZ25vc2luZyB0aGlzLgogKiAgICAgICAgICAgICAgICAgICAgICAgUHJvcGVybHkgc3VwcGx5IHRoZSBwYWdlIG51bWJlciBmaWVsZCBpbiB0aGUKICogICAgICAgICAgICAgICAgICAgICAgICBNT0RFX1NFTEVDVCBjb21tYW5kLgogKiAgICAgICAgICAgICAgICAgICAgICAgUExBWUFVRElPMTIgaXMgYnJva2VuIG9uIHRoZSBBenRlY2g7IHdvcmsgYXJvdW5kIGl0LgogKiAyLjA1eCBBdWcgMTEsIDE5OTUgLS0gbG90cyBvZiBkYXRhIHN0cnVjdHVyZSByZW5hbWluZy9yZXN0cnVjdHVyaW5nIGluIGlkZS5jCiAqICAgICAgICAgICAgICAgICAgICAgICAobXkgYXBvbG9naWVzIHRvIFNjb3R0LCBidXQgbm93IGlkZS1jZC5jIGlzIGluZGVwZW5kZW50KQogKiAzLjAwICBBdWcgMjIsIDE5OTUgLS0gSW1wbGVtZW50IENEUk9NTVVMVElTRVNTSU9OIGlvY3RsLgogKiAgICAgICAgICAgICAgICAgICAgICAgSW1wbGVtZW50IENEUk9NUkVBREFVRElPIGlvY3RsIChVTlRFU1RFRCkuCiAqICAgICAgICAgICAgICAgICAgICAgICBVc2UgaW5wdXRfaWRlX2RhdGEoKSBhbmQgb3V0cHV0X2lkZV9kYXRhKCkuCiAqICAgICAgICAgICAgICAgICAgICAgICBBZGQgZG9vciBsb2NraW5nLgogKiAgICAgICAgICAgICAgICAgICAgICAgRml4IHVzYWdlIGNvdW50IGxlYWsgaW4gY2Ryb21fb3Blbiwgd2hpY2ggaGFwcGVuZWQKICogICAgICAgICAgICAgICAgICAgICAgICB3aGVuIGEgcmVhZC13cml0ZSBtb3VudCB3YXMgYXR0ZW1wdGVkLgogKiAgICAgICAgICAgICAgICAgICAgICAgVHJ5IHRvIGxvYWQgdGhlIGRpc2sgb24gb3Blbi4KICogICAgICAgICAgICAgICAgICAgICAgIEltcGxlbWVudCBDRFJPTUVKRUNUX1NXIGlvY3RsIChvZmYgYnkgZGVmYXVsdCkuCiAqICAgICAgICAgICAgICAgICAgICAgICBSZWFkIHRvdGFsIGNkcm9tIGNhcGFjaXR5IGR1cmluZyBvcGVuLgogKiAgICAgICAgICAgICAgICAgICAgICAgUmVhcnJhbmdlIGxvZ2ljIGluIGNkcm9tX2RlY29kZV9zdGF0dXMuICBJc3N1ZQogKiAgICAgICAgICAgICAgICAgICAgICAgIHJlcXVlc3Qgc2Vuc2UgY29tbWFuZHMgZm9yIGZhaWxlZCBwYWNrZXQgY29tbWFuZHMKICogICAgICAgICAgICAgICAgICAgICAgICBmcm9tIGhlcmUgaW5zdGVhZCBvZiBmcm9tIGNkcm9tX3F1ZXVlX3BhY2tldF9jb21tYW5kLgogKiAgICAgICAgICAgICAgICAgICAgICAgIEZpeCBhIHJhY2UgY29uZGl0aW9uIGluIHJldHJpZXZpbmcgZXJyb3IgaW5mb3JtYXRpb24uCiAqICAgICAgICAgICAgICAgICAgICAgICBTdXBwcmVzcyBwcmludGluZyBub3JtYWwgdW5pdCBhdHRlbnRpb24gZXJyb3JzIGFuZAogKiAgICAgICAgICAgICAgICAgICAgICAgIHNvbWUgZHJpdmUgbm90IHJlYWR5IGVycm9ycy4KICogICAgICAgICAgICAgICAgICAgICAgIEltcGxlbWVudCBDRFJPTVZPTFJFQUQgaW9jdGwuCiAqICAgICAgICAgICAgICAgICAgICAgICBJbXBsZW1lbnQgQ0RST01SRUFETU9ERTEvMiBpb2N0bHMuCiAqICAgICAgICAgICAgICAgICAgICAgICBGaXggcmFjZSBjb25kaXRpb24gaW4gc2V0dGluZyB1cCBpbnRlcnJ1cHQgaGFuZGxlcnMKICogICAgICAgICAgICAgICAgICAgICAgICB3aGVuIHRoZSBgc2VyaWFsaXplJyBvcHRpb24gaXMgdXNlZC4KICogMy4wMSAgU2VwICAyLCAxOTk1IC0tIEZpeCBvcmRlcmluZyBvZiByZWVuYWJsaW5nIGludGVycnVwdHMgaW4KICogICAgICAgICAgICAgICAgICAgICAgICBjZHJvbV9xdWV1ZV9yZXF1ZXN0LgogKiAgICAgICAgICAgICAgICAgICAgICAgQW5vdGhlciB0cnkgYXQgdXNpbmcgaWRlX1tpbnB1dCxvdXRwdXRdX2RhdGEuCiAqIDMuMDIgIFNlcCAxNiwgMTk5NSAtLSBTdGljayB0b3RhbCBkaXNrIGNhcGFjaXR5IGluIHBhcnRpdGlvbiB0YWJsZSBhcyB3ZWxsLgogKiAgICAgICAgICAgICAgICAgICAgICAgTWFrZSBWRVJCT1NFX0lERV9DRF9FUlJPUlMgZHVtcCBmYWlsZWQgY29tbWFuZCBhZ2Fpbi4KICogICAgICAgICAgICAgICAgICAgICAgIER1bXAgb3V0IG1vcmUgaW5mb3JtYXRpb24gZm9yIElMTEVHQUwgUkVRVUVTVCBlcnJzLgogKiAgICAgICAgICAgICAgICAgICAgICAgRml4IGhhbmRsaW5nIG9mIGVycm9ycyBvY2N1cnJpbmcgYmVmb3JlIHRoZQogKiAgICAgICAgICAgICAgICAgICAgICAgIHBhY2tldCBjb21tYW5kIGlzIHRyYW5zZmVycmVkLgogKiAgICAgICAgICAgICAgICAgICAgICAgRml4IHRyYW5zZmVycyB3aXRoIG9kZCBieXRlbGVuZ3Rocy4KICogMy4wMyAgT2N0IDI3LCAxOTk1IC0tIFNvbWUgQ3JlYXRpdmUgZHJpdmVzIGhhdmUgYW4gaWQgb2YganVzdCBgQ0QnLgogKiAgICAgICAgICAgICAgICAgICAgICAgYERDSS0yUzEwJyBkcml2ZXMgYXJlIGJyb2tlbiB0b28uCiAqIDMuMDQgIE5vdiAyMCwgMTk5NSAtLSBTbyBhcmUgVmVydG9zIGRyaXZlcy4KICogMy4wNSAgRGVjICAxLCAxOTk1IC0tIENoYW5nZXMgdG8gZ28gd2l0aCBvdmVyaGF1bCBvZiBpZGUuYyBhbmQgaWRlLXRhcGUuYwogKiAzLjA2ICBEZWMgMTYsIDE5OTUgLS0gQWRkIHN1cHBvcnQgbmVlZGVkIGZvciBwYXJ0aXRpb25zLgogKiAgICAgICAgICAgICAgICAgICAgICAgTW9yZSB3b3JrYXJvdW5kcyBmb3IgVmVydG9zIGJ1Z3MgKGJhc2VkIG9uIHBhdGNoZXMKICogICAgICAgICAgICAgICAgICAgICAgICBmcm9tIEhvbGdlciBEaWV0emUgPGRpZXR6ZUBhaXg1MjAuaW5mb3JtYXRpay51bmktbGVpcHppZy5kZT4pLgogKiAgICAgICAgICAgICAgICAgICAgICAgVHJ5IHRvIGVsaW1pbmF0ZSBieXRlb3JkZXIgYXNzdW1wdGlvbnMuCiAqICAgICAgICAgICAgICAgICAgICAgICBVc2UgYXRhcGlfY2Ryb21fc3ViY2hubCBzdHJ1Y3QgZGVmaW5pdGlvbi4KICogICAgICAgICAgICAgICAgICAgICAgIEFkZCBTVEFOREFSRF9BVEFQSSBjb21waWxhdGlvbiBvcHRpb24uCiAqIDMuMDcgIEphbiAyOSwgMTk5NiAtLSBNb3JlIHR3aWRkbGluZyBmb3IgYnJva2VuIGRyaXZlczogU29ueSA1NUQsCiAqICAgICAgICAgICAgICAgICAgICAgICAgVmVydG9zIDMwMC4KICogICAgICAgICAgICAgICAgICAgICAgIEFkZCBOT19ET09SX0xPQ0tJTkcgY29uZmlndXJhdGlvbiBvcHRpb24uCiAqICAgICAgICAgICAgICAgICAgICAgICBIYW5kbGUgZHJpdmVfY21kIHJlcXVlc3RzIHcvTlVMTCBhcmdzIChmb3IgaGRwYXJtIC10KS4KICogICAgICAgICAgICAgICAgICAgICAgIFdvcmsgYXJvdW5kIHNwb3JhZGljIFNvbnk1NWUgYXVkaW8gcGxheSBwcm9ibGVtLgogKiAzLjA3YSBGZWIgMTEsIDE5OTYgLS0gY2hlY2sgZHJpdmUtPmlkIGZvciBOVUxMIGJlZm9yZSBkZXJlZmVyZW5jaW5nLCB0byBmaXgKICogICAgICAgICAgICAgICAgICAgICAgICBwcm9ibGVtIHdpdGggImhkZT1jZHJvbSIgd2l0aCBubyBkcml2ZSBwcmVzZW50LiAgLW1sCiAqIDMuMDggIE1hciAgNiwgMTk5NiAtLSBNb3JlIFZlcnRvcyB3b3JrYXJvdW5kcy4KICogMy4wOSAgQXByICA1LCAxOTk2IC0tIEFkZCBDRFJPTUNMT1NFVFJBWSBpb2N0bC4KICogICAgICAgICAgICAgICAgICAgICAgIFN3aXRjaCB0byB1c2luZyBNU0YgYWRkcmVzc2luZyBmb3IgYXVkaW8gY29tbWFuZHMuCiAqICAgICAgICAgICAgICAgICAgICAgICBSZWZvcm1hdCB0byBtYXRjaCBrZXJuZWwgdGFiYmluZyBzdHlsZS4KICogICAgICAgICAgICAgICAgICAgICAgIEFkZCBDRFJPTV9HRVRfVVBDIGlvY3RsLgogKiAzLjEwICBBcHIgMTAsIDE5OTYgLS0gRml4IGNvbXBpbGF0aW9uIGVycm9yIHdpdGggU1RBTkRBUkRfQVRBUEkuCiAqIDMuMTEgIEFwciAyOSwgMTk5NiAtLSBQYXRjaCBmcm9tIEhlaWtvIEVpc3NmZWxkdCA8aGVpa29AY29sb3NzdXMuZXNjYXBlLmRlPgogKiAgICAgICAgICAgICAgICAgICAgICAgdG8gcmVtb3ZlIHJlZHVuZGFudCB2ZXJpZnlfYXJlYSBjYWxscy4KICogMy4xMiAgTWF5ICA3LCAxOTk2IC0tIFJ1ZGltZW50YXJ5IGNoYW5nZXIgc3VwcG9ydC4gIEJhc2VkIG9uIHBhdGNoZXMKICogICAgICAgICAgICAgICAgICAgICAgICBmcm9tIEdlcmhhcmQgWnViZXIgPHp1YmVyQGJlcmxpbi5zbmFmdS5kZT4uCiAqICAgICAgICAgICAgICAgICAgICAgICBMZXQgb3BlbiBzdWNjZWVkIGV2ZW4gaWYgdGhlcmUncyBubyBsb2FkZWQgZGlzYy4KICogMy4xMyAgTWF5IDE5LCAxOTk2IC0tIEZpeGVzIGZvciBjaGFuZ2VyIGNvZGUuCiAqIDMuMTQgIE1heSAyOSwgMTk5NiAtLSBBZGQgd29yay1hcm91bmQgZm9yIFZlcnRvcyA2MDAuCiAqICAgICAgICAgICAgICAgICAgICAgICAgKEZyb20gSGVubnVzIEJlcmdtYW4gPGhlbm51c0Bza3kub3cubmw+LikKICogMy4xNSAgSnVseSAyLCAxOTk2IC0tIEFkZGVkIHN1cHBvcnQgZm9yIFNhbnlvIDMgQ0QgY2hhbmdlcnMKICogICAgICAgICAgICAgICAgICAgICAgICBmcm9tIEJlbiBHYWxsaWFydCA8YmdhbGxpYUBsdWMuZWR1PiB3aXRoIAogKiAgICAgICAgICAgICAgICAgICAgICAgIHNwZWNpYWwgaGVscCBmcm9tIEplZmYgTGlnaHRmb290IAogKiAgICAgICAgICAgICAgICAgICAgICAgIDxqZWZmbWxAcG9ib3guY29tPgogKiAzLjE1YSBKdWx5IDksIDE5OTYgLS0gSW1wcm92ZWQgU2FueW8gMyBDRCBjaGFuZ2VyIGlkZW50aWZpY2F0aW9uCiAqIDMuMTYgIEp1bCAyOCwgMTk5NiAtLSBGaXggZnJvbSBHYWRpIHRvIHJlZHVjZSBrZXJuZWwgc3RhY2sgdXNhZ2UgZm9yIGlvY3RsLgogKiAzLjE3ICBTZXAgMTcsIDE5OTYgLS0gVHdlYWsgYXVkaW8gcmVhZHMgZm9yIHNvbWUgZHJpdmVzLgogKiAgICAgICAgICAgICAgICAgICAgICAgU3RhcnQgY2hhbmdpbmcgQ0RST01MT0FERlJPTVNMT1QgdG8gQ0RST01fU0VMRUNUX0RJU0MuCiAqIDMuMTggIE9jdCAzMSwgMTk5NiAtLSBBZGRlZCBtb2R1bGUgYW5kIERNQSBzdXBwb3J0LgogKiAgICAgICAgICAgICAgICAgICAgICAgCiAqICAgICAgICAgICAgICAgICAgICAgICAKICogNC4wMCAgTm92IDUsIDE5OTYgICAtLSBOZXcgaWRlLWNkIG1haW50YWluZXIsCiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRXJpayBCLiBBbmRlcnNlbiA8YW5kZXJzZWVAZGViaWFuLm9yZz4KICogICAgICAgICAgICAgICAgICAgICAtLSBOZXdlciBDcmVhdGl2ZSBkcml2ZXMgZG9uJ3QgYWx3YXlzIHNldCB0aGUgZXJyb3IKICogICAgICAgICAgICAgICAgICAgICAgICAgIHJlZ2lzdGVyIGNvcnJlY3RseS4gIE1ha2Ugc3VyZSB3ZSBzZWUgbWVkaWEgY2hhbmdlcwogKiAgICAgICAgICAgICAgICAgICAgICAgICAgcmVnYXJkbGVzcy4KICogICAgICAgICAgICAgICAgICAgICAtLSBJbnRlZ3JhdGUgd2l0aCBnZW5lcmljIGNkcm9tIGRyaXZlci4KICogICAgICAgICAgICAgICAgICAgICAtLSBDRFJPTUdFVFNQSU5ET1dOIGFuZCBDRFJPTVNFVFNQSU5ET1dOIGlvY3RscywgYmFzZWQgb24KICogICAgICAgICAgICAgICAgICAgICAgICAgIGEgcGF0Y2ggZnJvbSBDaXJvIENhdHR1dG8gPD4uCiAqICAgICAgICAgICAgICAgICAgICAgLS0gQ2FsbCBzZXRfZGV2aWNlX3JvLgogKiAgICAgICAgICAgICAgICAgICAgIC0tIEltcGxlbWVudCBDRFJPTU1FQ0hBTklTTVNUQVRVUyBhbmQgQ0RST01TTE9UVEFCTEUKICogICAgICAgICAgICAgICAgICAgICAgICAgIGlvY3RscywgYmFzZWQgb24gcGF0Y2ggYnkgRXJpayBBbmRlcnNlbgogKiAgICAgICAgICAgICAgICAgICAgIC0tIEFkZCBzb21lIHByb2JlcyBvZiBkcml2ZSBjYXBhYmlsaXR5IGR1cmluZyBzZXR1cC4KICoKICogNC4wMSAgTm92IDExLCAxOTk2ICAtLSBTcGxpdCBpbnRvIGlkZS1jZC5jIGFuZCBpZGUtY2QuaAogKiAgICAgICAgICAgICAgICAgICAgIC0tIFJlbW92ZWQgQ0RST01NRUNIQU5JU01TVEFUVVMgYW5kIENEUk9NU0xPVFRBQkxFIAogKiAgICAgICAgICAgICAgICAgICAgICAgICAgaW9jdGxzIGluIGZhdm9yIG9mIGEgZ2VuZXJhbGl6ZWQgYXBwcm9hY2ggCiAqICAgICAgICAgICAgICAgICAgICAgICAgICB1c2luZyB0aGUgZ2VuZXJpYyBjZHJvbSBkcml2ZXIuCiAqICAgICAgICAgICAgICAgICAgICAgLS0gRnVsbHkgaW50ZWdyYXRlZCB3aXRoIHRoZSAyLjEuWCBrZXJuZWwuCiAqICAgICAgICAgICAgICAgICAgICAgLS0gT3RoZXIgc3R1ZmYgdGhhdCBJIGZvcmdvdCAobG90cyBvZiBjaGFuZ2VzKQogKgogKiA0LjAyICBEZWMgMDEsIDE5OTYgIC0tIEFwcGxpZWQgcGF0Y2ggZnJvbSBHYWRpIE94bWFuIDxnYWRpb0BuZXR2aXNpb24ubmV0LmlsPgogKiAgICAgICAgICAgICAgICAgICAgICAgICAgdG8gZml4IHRoZSBkcml2ZSBkb29yIGxvY2tpbmcgcHJvYmxlbXMuCiAqCiAqIDQuMDMgIERlYyAwNCwgMTk5NiAgLS0gQWRkZWQgRFNDIG92ZXJsYXAgc3VwcG9ydC4KICogNC4wNCAgRGVjIDI5LCAxOTk2ICAtLSBBZGRlZCBDRFJPTVJFQURSQVcgaW9jbHQgYmFzZWQgb24gcGF0Y2ggCiAqICAgICAgICAgICAgICAgICAgICAgICAgICBieSBBbGVzIE1ha2Fyb3YgKHhtYWthcm92QHN1bi5mZWxrLmN2dXQuY3opCiAqCiAqIDQuMDUgIE5vdiAyMCwgMTk5NyAgLS0gTW9kaWZpZWQgdG8gcHJpbnQgbW9yZSBkcml2ZSBpbmZvIG9uIGluaXQKICogICAgICAgICAgICAgICAgICAgICAgICBNaW5vciBvdGhlciBjaGFuZ2VzCiAqICAgICAgICAgICAgICAgICAgICAgICAgRml4IGVycm9ycyBvbiBDRFJPTVNUT1AgKElmIHlvdSBoYXZlIGEgIkRvbHBoaW4iLAogKiAgICAgICAgICAgICAgICAgICAgICAgICAgeW91IG11c3QgZGVmaW5lIElIQVZFQURPTFBISU4pCiAqICAgICAgICAgICAgICAgICAgICAgICAgQWRkZWQgaWRlbnRpZmllciBzbyBuZXcgU2FueW8gQ0QtY2hhbmdlciB3b3JrcwogKiAgICAgICAgICAgICAgICAgICAgICAgIEJldHRlciBkZXRlY3Rpb24gaWYgZG9vciBsb2NraW5nIGlzbid0IHN1cHBvcnRlZAogKgogKiA0LjA2ICBEZWMgMTcsIDE5OTcgIC0tIGZpeGVkIGVuZGxlc3MgInRyYXkgb3BlbiIgbWVzc2FnZXMgIC1tbAogKiA0LjA3ICBEZWMgMTcsIDE5OTcgIC0tIGZhbGxiYWNrIHRvIHNldCBwYy0+c3RhdCBvbiAidHJheSBvcGVuIgogKiA0LjA4ICBEZWMgMTgsIDE5OTcgIC0tIHNwZXcgbGVzcyBub2lzZSB3aGVuIHRyYXkgaXMgZW1wdHkKICogICAgICAgICAgICAgICAgICAgICAtLSBmaXggc3BlZWQgZGlzcGxheSBmb3IgQUNFUiAyNFgsIDE4WAogKiA0LjA5ICBKYW4gMDQsIDE5OTggIC0tIGZpeCBoYW5kbGluZyBvZiB0aGUgbGFzdCBibG9jayBzbyB3ZSByZXR1cm4KICogICAgICAgICAgICAgICAgICAgICAgICAgYW4gZW5kIG9mIGZpbGUgaW5zdGVhZCBvZiBhbiBJL08gZXJyb3IgKEdhZGkpCiAqIDQuMTAgIEphbiAyNCwgMTk5OCAgLS0gZml4ZWQgYSBidWcgc28gbm93IGNoYW5nZXJzIGNhbiBjaGFuZ2UgdG8gYSBuZXcKICogICAgICAgICAgICAgICAgICAgICAgICAgc2xvdCB3aGVuIHRoZXJlIGlzIG5vIGRpc2MgaW4gdGhlIGN1cnJlbnQgc2xvdC4KICogICAgICAgICAgICAgICAgICAgICAtLSBGaXhlZCBhIG1lbW9yeSBsZWFrIHdoZXJlIGluZm8tPmNoYW5nZXJfaW5mbyB3YXMKICogICAgICAgICAgICAgICAgICAgICAgICAgbWFsbG9jJ2VkIGJ1dCBuZXZlciBmcmVlJ2Qgd2hlbiBjbG9zaW5nIHRoZSBkZXZpY2UuCiAqICAgICAgICAgICAgICAgICAgICAgLS0gQ2xlYW5lZCB1cCB0aGUgZ2xvYmFsIG5hbWVzcGFjZSBhIGJpdCBieSBtYWtpbmcgbW9yZQogKiAgICAgICAgICAgICAgICAgICAgICAgICBmdW5jdGlvbnMgc3RhdGljIHRoYXQgc2hvdWxkIGFscmVhZHkgaGF2ZSBiZWVuLgogKiA0LjExICBNYXIgMTIsIDE5OTggIC0tIEFkZGVkIHN1cHBvcnQgZm9yIHRoZSBDRFJPTV9TRUxFQ1RfU1BFRUQgaW9jdGwKICogICAgICAgICAgICAgICAgICAgICAgICAgYmFzZWQgb24gYSBwYXRjaCBmb3IgMi4wLjMzIGJ5IEplbGxlIEZva3MgCiAqICAgICAgICAgICAgICAgICAgICAgICAgIDxqZWxsZUBzY2ludGlsbGEudXR3ZW50ZS5ubD4sIGEgcGF0Y2ggZm9yIDIuMC4zMwogKiAgICAgICAgICAgICAgICAgICAgICAgICBieSBUb25pIEdpb3JnaW5vIDx0b25pQHBjYXBlMi5waS5pbmZuLml0PiwgdGhlIFNDU0kKICogICAgICAgICAgICAgICAgICAgICAgICAgdmVyc2lvbiwgYW5kIG15IG93biBlZmZvcnRzLiAgLWVyaWsKICogICAgICAgICAgICAgICAgICAgICAtLSBGaXhlZCBhIHN0dXBpZCBidWcgd2hpY2ggZWdjcyB3YXMga2luZCBlbm91Z2ggdG8KICogICAgICAgICAgICAgICAgICAgICAgICAgaW5mb3JtIG1lIG9mIHdoZXJlICJJbGxlZ2FsIG1vZGUgZm9yIHRoaXMgdHJhY2siCiAqICAgICAgICAgICAgICAgICAgICAgICAgIHdhcyBuZXZlciByZXR1cm5lZCBkdWUgdG8gYSBjb21wYXJpc29uIG9uIGRhdGEKICogICAgICAgICAgICAgICAgICAgICAgICAgdHlwZXMgb2YgbGltaXRlZCByYW5nZS4KICogNC4xMiAgTWFyIDI5LCAxOTk4ICAtLSBGaXhlZCBidWcgaW4gQ0RST01fU0VMRUNUX1NQRUVEIHNvIHdyaXRlIHNwZWVkIGlzIAogKiAgICAgICAgICAgICAgICAgICAgICAgICBub3cgc2V0IGlvbmx5IGZvciBDRC1SIGFuZCBDRC1SVyBkcml2ZXMuICBJIGhhZCAKICogICAgICAgICAgICAgICAgICAgICAgICAgcmVtb3ZlZCB0aGlzIHN1cHBvcnQgYmVjYXVzZSBpdCBwcm9kdWNlZCBlcnJvcnMuCiAqICAgICAgICAgICAgICAgICAgICAgICAgIEl0IHByb2R1Y2VkIGVycm9ycyBfb25seV8gZm9yIG5vbi13cml0ZXJzLiBkdWguCiAqIDQuMTMgIE1heSAwNSwgMTk5OCAgLS0gU3VwcHJlc3MgdXNlbGVzcyAiaW4gcHJvZ3Jlc3Mgb2YgYmVjb21pbmcgcmVhZHkiCiAqICAgICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2VzLCBzaW5jZSB0aGlzIGlzIG5vdCBhbiBlcnJvci4KICogICAgICAgICAgICAgICAgICAgICAtLSBDaGFuZ2UgZXJyb3IgbWVzc2FnZXMgdG8gYmUgY29uc3QKICogICAgICAgICAgICAgICAgICAgICAtLSBSZW1vdmUgYSAiXHQiIHdoaWNoIGxvb2tzIHVnbHkgaW4gdGhlIHN5c2xvZ3MKICogNC4xNCAgSnVseSAxNywgMTk5OCAtLSBDaGFuZ2UgdG8gcG9pbnRpbmcgdG8gLnBzIHZlcnNpb24gb2YgQVRBUEkgc3BlYwogKiAgICAgICAgICAgICAgICAgICAgICAgICBzaW5jZSB0aGUgLnBkZiB2ZXJzaW9uIGRvZXNuJ3Qgc2VlbSB0byB3b3JrLi4uCiAqICAgICAgICAgICAgICAgICAgICAgLS0gVXBkYXRlZCB0aGUgVE9ETyBsaXN0IHRvIHNvbWV0aGluZyBtb3JlIGN1cnJlbnQuCiAqCiAqIDQuMTUgIEF1ZyAyNSwgMTk5OCAgLS0gVXBkYXRlZCBpZGUtY2QuaCB0byByZXNwZWN0IG1lY2hpbmUgZW5kaWFuZXNzLCAKICogICAgICAgICAgICAgICAgICAgICAgICAgcGF0Y2ggdGhhbmtzIHRvICJFZGRpZSBDLiBEb3N0IiA8ZWNkQHNreW5ldC5iZT4KICoKICogNC41MCAgT2N0IDE5LCAxOTk4ICAtLSBOZXcgbWFpbnRhaW5lcnMhCiAqICAgICAgICAgICAgICAgICAgICAgICAgIEplbnMgQXhib2UgPGF4Ym9lQGltYWdlLmRrPgogKiAgICAgICAgICAgICAgICAgICAgICAgICBDaHJpcyBad2lsbGluZyA8Y2hyaXNAY2xvdWRuZXQuY29tPgogKgogKiA0LjUxICBEZWMgMjMsIDE5OTggIC0tIEplbnMgQXhib2UgPGF4Ym9lQGltYWdlLmRrPgogKiAgICAgICAgICAgICAgICAgICAgICAtIGlkZV9jZHJvbV9yZXNldCBlbmFibGVkIHNpbmNlIHRoZSBpZGUgc3Vic3lzdGVtCiAqICAgICAgICAgICAgICAgICAgICAgICAgIGhhbmRsZXMgcmVzZXRzIGZpbmUgbm93LiA8YXhib2VAaW1hZ2UuZGs+CiAqICAgICAgICAgICAgICAgICAgICAgIC0gVHJhbnNmZXIgc2l6ZSBmaXggZm9yIFNhbXN1bmcgQ0QtUk9NcywgdGhhbmtzIHRvCiAqICAgICAgICAgICAgICAgICAgICAgICAgIlZpbGxlIEhhbGxpayIgPHZpbGxlLmhhbGxpa0BtYWlsLmVlPi4KICogICAgICAgICAgICAgICAgICAgICAgLSBvdGhlciBtaW5vciBzdHVmZi4KICoKICogNC41MiAgSmFuIDE5LCAxOTk5ICAtLSBKZW5zIEF4Ym9lIDxheGJvZUBpbWFnZS5kaz4KICogICAgICAgICAgICAgICAgICAgICAgLSBEZXRlY3QgRFZELVJPTS9SQU0gZHJpdmVzCiAqCiAqIDQuNTMgIEZlYiAyMiwgMTk5OSAgIC0gSW5jbHVkZSBvdGhlciBtb2RlbCBTYW1zdW5nIGFuZCBvbmUgR29sZHN0YXIKICogICAgICAgICAgICAgICAgICAgICAgICAgZHJpdmUgaW4gdHJhbnNmZXIgc2l6ZSBsaW1pdC4KICogICAgICAgICAgICAgICAgICAgICAgLSBGaXggdGhlIEkvTyBlcnJvciB3aGVuIGRvaW5nIGVqZWN0IHdpdGhvdXQgYSBtZWRpdW0KICogICAgICAgICAgICAgICAgICAgICAgICAgbG9hZGVkIG9uIHNvbWUgZHJpdmVzLgogKiAgICAgICAgICAgICAgICAgICAgICAtIENEUk9NUkVBRE1PREUyIGlzIG5vdyBpbXBsZW1lbnRlZCB0aHJvdWdoCiAqICAgICAgICAgICAgICAgICAgICAgICAgIENEUk9NUkVBRFJBVywgc2luY2UgbWFueSBkcml2ZXMgZG9uJ3Qgc3VwcG9ydAogKiAgICAgICAgICAgICAgICAgICAgICAgICBNT0RFMiAoZXZlbiB0aG91Z2ggQVRBUEkgMi42IHNheXMgdGhleSBtdXN0KS4KICogICAgICAgICAgICAgICAgICAgICAgLSBBZGRlZCBpZ25vcmUgcGFyYW1ldGVyIHRvIGlkZS1jZCAoYXMgYSBtb2R1bGUpLCBlZwogKiAgICAgICAgICAgICAgICAgICAgICAgICAJaW5zbW9kIGlkZS1jZCBpZ25vcmU9J2hkYSBoZGInCiAqICAgICAgICAgICAgICAgICAgICAgICAgIFVzZWZ1bCB3aGVuIHVzaW5nIGlkZS1jZCBpbiBjb25qdW5jdGlvbiB3aXRoCiAqICAgICAgICAgICAgICAgICAgICAgICAgIGlkZS1zY3NpLiBUT0RPOiBub24tbW9kdWxhciB3YXkgb2YgZG9pbmcgdGhlCiAqICAgICAgICAgICAgICAgICAgICAgICAgIHNhbWUuCiAqCiAqIDQuNTQgIEF1ZyA1LCAxOTk5CS0gU3VwcG9ydCBmb3IgTU1DMiBjbGFzcyBjb21tYW5kcyB0aHJvdWdoIHRoZSBnZW5lcmljCiAqCQkJICBwYWNrZXQgaW50ZXJmYWNlIHRvIGNkcm9tLmMuCiAqCQkJLSBVbmlmaWVkIGF1ZGlvIGlvY3RsIHN1cHBvcnQsIG1vc3Qgb2YgaXQuCiAqCQkJLSBjbGVhbmVkIHVwIHZhcmlvdXMgZGVwcmVjYXRlZCB2ZXJpZnlfYXJlYSgpLgogKgkJCS0gQWRkZWQgaWRlX2Nkcm9tX3BhY2tldCgpIGFzIHRoZSBpbnRlcmZhY2UgZm9yCiAqCQkJICB0aGUgVW5pZm9ybSBnZW5lcmljX3BhY2tldCgpLgogKgkJCS0gYnVuY2ggb2Ygb3RoZXIgc3R1ZmYsIHdpbGwgZmlsbCBpbiBsb2dzIGxhdGVyLgogKgkJCS0gcmVwb3J0IDEgc2xvdCBmb3Igbm9uLWNoYW5nZXJzLCBsaWtlIHRoZSBvdGhlcgogKgkJCSAgY2Qtcm9tIGRyaXZlcnMuIGRvbid0IHJlcG9ydCBzZWxlY3QgZGlzYyBmb3IKICoJCQkgIG5vbi1jaGFuZ2VycyBhcyB3ZWxsLgogKgkJCS0gbWFzayBvdXQgYXVkaW8gcGxheWluZywgaWYgdGhlIGRldmljZSBjYW4ndCBkbyBpdC4KICoKICogNC41NSAgU2VwIDEsIDE5OTkJLSBFbGltaW5hdGVkIHRoZSByZXN0IG9mIHRoZSBhdWRpbyBpb2N0bHMsIGV4Y2VwdAogKgkJCSAgZm9yIENEUk9NUkVBRFRPQ1tFTlRSWXxIRUFERVJdLiBTb21lIG9mIHRoZSBkcml2ZXJzCiAqCQkJICB1c2UgdGhpcyBpbmRlcGVuZGVudGx5IG9mIHRoZSBhY3R1YWwgYXVkaW8gaGFuZGxpbmcuCiAqCQkJICBUaGV5IHdpbGwgZGlzYXBwZWFyIGxhdGVyIHdoZW4gSSBnZXQgdGhlIHRpbWUgdG8KICoJCQkgIGRvIGl0IGNsZWFubHkuCiAqCQkJLSBNaW5pbWl6ZSB0aGUgVE9DIHJlYWRpbmcgLSBvbmx5IGRvIGl0IHdoZW4gd2UKICoJCQkgIGtub3cgYSBtZWRpYSBjaGFuZ2UgaGFzIG9jY3VycmVkLgogKgkJCS0gTW92ZWQgYWxsIHRoZSBDRFJPTVJFQUR4IGlvY3RscyB0byB0aGUgVW5pZm9ybSBsYXllci4KICoJCQktIEhlaWtvIEVpc3NmZWxkdCA8aGVpa29AY29sb3NzdXMuZXNjYXBlLmRlPiBzdXBwbGllZAogKgkJCSAgc29tZSBmaXhlcyBmb3IgQ0RJLgogKgkJCS0gQ0QtUk9NIGxlYXZpbmcgZG9vciBsb2NrZWQgZml4IGZyb20gQW5kcmllcwogKgkJCSAgQnJvdXdlciA8QW5kcmllcy5Ccm91d2VyQGN3aS5ubD4KICoJCQktIEVyaWsgQW5kZXJzZW4gPGFuZGVyc2VuQHhtaXNzaW9uLmNvbT4gdW5pZmllZAogKgkJCSAgY29tbWFuZHMgYWNyb3NzIHRoZSB2YXJpb3VzIGRyaXZlcnMgYW5kIGhvdwogKgkJCSAgc2Vuc2UgZXJyb3JzIGFyZSBoYW5kbGVkLgogKgogKiA0LjU2ICBTZXAgMTIsIDE5OTkJLSBSZW1vdmVkIGNoYW5nZXIgc3VwcG9ydCAtIGl0IGlzIG5vdyBpbiB0aGUKICoJCQkgIFVuaWZvcm0gbGF5ZXIuCiAqCQkJLSBBZGRlZCBwYXJ0aXRpb24gYmFzZWQgbXVsdGlzZXNzaW9uIGhhbmRsaW5nLgogKgkJCS0gTW9kZSBzZW5zZSBhbmQgbW9kZSBzZWxlY3QgbW92ZWQgdG8gdGhlCiAqCQkJICBVbmlmb3JtIGxheWVyLgogKgkJCS0gRml4ZWQgYSBwcm9ibGVtIHdpdGggV1BJIENEUy0zMlggZHJpdmUgLSBpdAogKgkJCSAgZmFpbGVkIHRoZSBjYXBhYmlsaXRpZXMgCiAqCiAqIDQuNTcgIEFwciA3LCAyMDAwCS0gRml4ZWQgc2Vuc2UgcmVwb3J0aW5nLgogKgkJCS0gRml4ZWQgcG9zc2libGUgb29wcyBpbiBpZGVfY2Ryb21fZ2V0X2xhc3Rfc2Vzc2lvbigpCiAqCQkJLSBGaXggbG9ja2luZyBtYW5pYSBhbmQgbWFrZSBpZGVfY2Ryb21fcmVzZXQgcmVsb2NrCiAqCQkJLSBTdG9wIHNwZXdpbmcgZXJyb3JzIHRvIGxvZyB3aGVuIG1hZ2ljZGV2IHBvbGxzIHdpdGgKICoJCQkgIFRFU1RfVU5JVF9SRUFEWSBvbiBzb21lIGRyaXZlcy4KICoJCQktIFZhcmlvdXMgZml4ZXMgZnJvbSBUb2JpYXMgUmluZ3N0cm9tOgogKgkJCSAgdHJheSBpZiBpdCB3YXMgbG9ja2VkIHByaW9yIHRvIHRoZSByZXNldC4KICoJCQkgIC0gY2Ryb21fcmVhZF9jYXBhY2l0eSByZXR1cm5zIG9uZSBmcmFtZSB0b28gbGl0dGxlLgogKgkJCSAgLSBGaXggcmVhbCBjYXBhY2l0eSByZXBvcnRpbmcuCiAqCiAqIDQuNTggIE1heSAxLCAyMDAwCS0gQ2xlYW4gdXAgQUNFUjUwIHN0dWZmLgogKgkJCS0gRml4IHNtYWxsIHByb2JsZW0gd2l0aCBpZGVfY2Ryb21fY2FwYWNpdHkKICoKICogNC41OSAgQXVnIDExLCAyMDAwCS0gRml4IGNoYW5nZXIgcHJvYmxlbSBpbiBjZHJvbV9yZWFkX3RvYywgd2Ugd2VyZW4ndAogKgkJCSAgY29ycmVjdGx5IHNlbnNpbmcgYSBkaXNjIGNoYW5nZS4KICoJCQktIFJlYXJyYW5nZWQgc29tZSBjb2RlCiAqCQkJLSBVc2UgZXh0ZW5kZWQgc2Vuc2Ugb24gZHJpdmVzIHRoYXQgc3VwcG9ydCBpdCBmb3IKICoJCQkgIGNvcnJlY3RseSByZXBvcnRpbmcgdHJheSBzdGF0dXMgLS0gZnJvbQogKgkJCSAgTWljaGFlbCBEIEpvaG5zb24gPGpvaG5zb21Ab3JzdC5lZHU+CiAqIDQuNjAgIERlYyAxNywgMjAwMwktIEFkZCBtdCByYWluaWVyIHN1cHBvcnQKICoJCQktIEJ1bXAgdGltZW91dCBmb3IgcGFja2V0IGNvbW1hbmRzLCBtYXRjaGVzIHNyCiAqCQkJLSBPZGQgc3R1ZmYKICogNC42MSAgSmFuIDIyLCAyMDA0CS0gc3VwcG9ydCBoYXJkd2FyZSBzZWN0b3Igc2l6ZXMgb3RoZXIgdGhhbiAya0IsCiAqCQkJICBQYXNjYWwgU2NobWlkdCA8ZGVyLmVyZW1pdEBlbWFpbC5kZT4KICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCiAKI2RlZmluZSBJREVDRF9WRVJTSU9OICI0LjYxIgoKI2luY2x1ZGUgPGxpbnV4L21vZHVsZS5oPgojaW5jbHVkZSA8bGludXgvdHlwZXMuaD4KI2luY2x1ZGUgPGxpbnV4L2tlcm5lbC5oPgojaW5jbHVkZSA8bGludXgvZGVsYXkuaD4KI2luY2x1ZGUgPGxpbnV4L3RpbWVyLmg+CiNpbmNsdWRlIDxsaW51eC9zbGFiLmg+CiNpbmNsdWRlIDxsaW51eC9pbnRlcnJ1cHQuaD4KI2luY2x1ZGUgPGxpbnV4L2Vycm5vLmg+CiNpbmNsdWRlIDxsaW51eC9jZHJvbS5oPgojaW5jbHVkZSA8bGludXgvaWRlLmg+CiNpbmNsdWRlIDxsaW51eC9jb21wbGV0aW9uLmg+CiNpbmNsdWRlIDxsaW51eC9tdXRleC5oPgoKI2luY2x1ZGUgPHNjc2kvc2NzaS5oPgkvKiBGb3IgU0NTSSAtPiBBVEFQSSBjb21tYW5kIGNvbnZlcnNpb24gKi8KCiNpbmNsdWRlIDxhc20vaXJxLmg+CiNpbmNsdWRlIDxhc20vaW8uaD4KI2luY2x1ZGUgPGFzbS9ieXRlb3JkZXIuaD4KI2luY2x1ZGUgPGFzbS91YWNjZXNzLmg+CiNpbmNsdWRlIDxhc20vdW5hbGlnbmVkLmg+CgojaW5jbHVkZSAiaWRlLWNkLmgiCgpzdGF0aWMgREVGSU5FX01VVEVYKGlkZWNkX3JlZl9tdXRleCk7CgojZGVmaW5lIHRvX2lkZV9jZChvYmopIGNvbnRhaW5lcl9vZihvYmosIHN0cnVjdCBjZHJvbV9pbmZvLCBrcmVmKSAKCiNkZWZpbmUgaWRlX2NkX2coZGlzaykgXAoJY29udGFpbmVyX29mKChkaXNrKS0+cHJpdmF0ZV9kYXRhLCBzdHJ1Y3QgY2Ryb21faW5mbywgZHJpdmVyKQoKc3RhdGljIHN0cnVjdCBjZHJvbV9pbmZvICppZGVfY2RfZ2V0KHN0cnVjdCBnZW5kaXNrICpkaXNrKQp7CglzdHJ1Y3QgY2Ryb21faW5mbyAqY2QgPSBOVUxMOwoKCW11dGV4X2xvY2soJmlkZWNkX3JlZl9tdXRleCk7CgljZCA9IGlkZV9jZF9nKGRpc2spOwoJaWYgKGNkKQoJCWtyZWZfZ2V0KCZjZC0+a3JlZik7CgltdXRleF91bmxvY2soJmlkZWNkX3JlZl9tdXRleCk7CglyZXR1cm4gY2Q7Cn0KCnN0YXRpYyB2b2lkIGlkZV9jZF9yZWxlYXNlKHN0cnVjdCBrcmVmICopOwoKc3RhdGljIHZvaWQgaWRlX2NkX3B1dChzdHJ1Y3QgY2Ryb21faW5mbyAqY2QpCnsKCW11dGV4X2xvY2soJmlkZWNkX3JlZl9tdXRleCk7CglrcmVmX3B1dCgmY2QtPmtyZWYsIGlkZV9jZF9yZWxlYXNlKTsKCW11dGV4X3VubG9jaygmaWRlY2RfcmVmX211dGV4KTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogR2VuZXJpYyBwYWNrZXQgY29tbWFuZCBzdXBwb3J0IGFuZCBlcnJvciBoYW5kbGluZyByb3V0aW5lcy4KICovCgovKiBNYXJrIHRoYXQgd2UndmUgc2VlbiBhIG1lZGlhIGNoYW5nZSwgYW5kIGludmFsaWRhdGUgb3VyIGludGVybmFsCiAgIGJ1ZmZlcnMuICovCnN0YXRpYyB2b2lkIGNkcm9tX3Nhd19tZWRpYV9jaGFuZ2UgKGlkZV9kcml2ZV90ICpkcml2ZSkKewoJc3RydWN0IGNkcm9tX2luZm8gKmluZm8gPSBkcml2ZS0+ZHJpdmVyX2RhdGE7CgkKCUNEUk9NX1NUQVRFX0ZMQUdTIChkcml2ZSktPm1lZGlhX2NoYW5nZWQgPSAxOwoJQ0RST01fU1RBVEVfRkxBR1MgKGRyaXZlKS0+dG9jX3ZhbGlkID0gMDsKCWluZm8tPm5zZWN0b3JzX2J1ZmZlcmVkID0gMDsKfQoKc3RhdGljIGludCBjZHJvbV9sb2dfc2Vuc2UoaWRlX2RyaXZlX3QgKmRyaXZlLCBzdHJ1Y3QgcmVxdWVzdCAqcnEsCgkJCSAgIHN0cnVjdCByZXF1ZXN0X3NlbnNlICpzZW5zZSkKewoJaW50IGxvZyA9IDA7CgoJaWYgKCFzZW5zZSB8fCAhcnEgfHwgKHJxLT5jbWRfZmxhZ3MgJiBSRVFfUVVJRVQpKQoJCXJldHVybiAwOwoKCXN3aXRjaCAoc2Vuc2UtPnNlbnNlX2tleSkgewoJCWNhc2UgTk9fU0VOU0U6IGNhc2UgUkVDT1ZFUkVEX0VSUk9SOgoJCQlicmVhazsKCQljYXNlIE5PVF9SRUFEWToKCQkJLyoKCQkJICogZG9uJ3QgY2FyZSBhYm91dCB0cmF5IHN0YXRlIG1lc3NhZ2VzIGZvcgoJCQkgKiBlLmcuIGNhcGFjaXR5IGNvbW1hbmRzIG9yIGluLXByb2dyZXNzIG9yCgkJCSAqIGJlY29taW5nIHJlYWR5CgkJCSAqLwoJCQlpZiAoc2Vuc2UtPmFzYyA9PSAweDNhIHx8IHNlbnNlLT5hc2MgPT0gMHgwNCkKCQkJCWJyZWFrOwoJCQlsb2cgPSAxOwoJCQlicmVhazsKCQljYXNlIElMTEVHQUxfUkVRVUVTVDoKCQkJLyoKCQkJICogZG9uJ3QgbG9nIFNUQVJUX1NUT1AgdW5pdCB3aXRoIExvRWogc2V0LCBzaW5jZQoJCQkgKiB3ZSBjYW5ub3QgcmVsaWFibHkgY2hlY2sgaWYgZHJpdmUgY2FuIGF1dG8tY2xvc2UKCQkJICovCgkJCWlmIChycS0+Y21kWzBdID09IEdQQ01EX1NUQVJUX1NUT1BfVU5JVCAmJiBzZW5zZS0+YXNjID09IDB4MjQpCgkJCQlicmVhazsKCQkJbG9nID0gMTsKCQkJYnJlYWs7CgkJY2FzZSBVTklUX0FUVEVOVElPTjoKCQkJLyoKCQkJICogTWFrZSBnb29kIGFuZCBzdXJlIHdlJ3ZlIHNlZW4gdGhpcyBwb3RlbnRpYWwgbWVkaWEKCQkJICogY2hhbmdlLiBTb21lIGRyaXZlcyAoaS5lLiBDcmVhdGl2ZSkgZmFpbCB0byBwcmVzZW50CgkJCSAqIHRoZSBjb3JyZWN0IHNlbnNlIGtleSBpbiB0aGUgZXJyb3IgcmVnaXN0ZXIuCgkJCSAqLwoJCQljZHJvbV9zYXdfbWVkaWFfY2hhbmdlKGRyaXZlKTsKCQkJYnJlYWs7CgkJZGVmYXVsdDoKCQkJbG9nID0gMTsKCQkJYnJlYWs7Cgl9CglyZXR1cm4gbG9nOwp9CgpzdGF0aWMKdm9pZCBjZHJvbV9hbmFseXplX3NlbnNlX2RhdGEoaWRlX2RyaXZlX3QgKmRyaXZlLAoJCQkgICAgICBzdHJ1Y3QgcmVxdWVzdCAqZmFpbGVkX2NvbW1hbmQsCgkJCSAgICAgIHN0cnVjdCByZXF1ZXN0X3NlbnNlICpzZW5zZSkKewoJdW5zaWduZWQgbG9uZyBzZWN0b3I7Cgl1bnNpZ25lZCBsb25nIGJpb19zZWN0b3JzOwoJdW5zaWduZWQgbG9uZyB2YWxpZDsKCXN0cnVjdCBjZHJvbV9pbmZvICppbmZvID0gZHJpdmUtPmRyaXZlcl9kYXRhOwoKCWlmICghY2Ryb21fbG9nX3NlbnNlKGRyaXZlLCBmYWlsZWRfY29tbWFuZCwgc2Vuc2UpKQoJCXJldHVybjsKCgkvKgoJICogSWYgYSByZWFkIHRvYyBpcyBleGVjdXRlZCBmb3IgYSBDRC1SIG9yIENELVJXIG1lZGl1bSB3aGVyZQoJICogdGhlIGZpcnN0IHRvYyBoYXMgbm90IGJlZW4gcmVjb3JkZWQgeWV0LCBpdCB3aWxsIGZhaWwgd2l0aAoJICogMDUvMjQvMDAgKHdoaWNoIGlzIGEgY29uZnVzaW5nIGVycm9yKQoJICovCglpZiAoZmFpbGVkX2NvbW1hbmQgJiYgZmFpbGVkX2NvbW1hbmQtPmNtZFswXSA9PSBHUENNRF9SRUFEX1RPQ19QTUFfQVRJUCkKCQlpZiAoc2Vuc2UtPnNlbnNlX2tleSA9PSAweDA1ICYmIHNlbnNlLT5hc2MgPT0gMHgyNCkKCQkJcmV0dXJuOwoKIAlpZiAoc2Vuc2UtPmVycm9yX2NvZGUgPT0gMHg3MCkgewkvKiBDdXJyZW50IEVycm9yICovCiAJCXN3aXRjaChzZW5zZS0+c2Vuc2Vfa2V5KSB7CgkJY2FzZSBNRURJVU1fRVJST1I6CgkJY2FzZSBWT0xVTUVfT1ZFUkZMT1c6CgkJY2FzZSBJTExFR0FMX1JFUVVFU1Q6CgkJCWlmICghc2Vuc2UtPnZhbGlkKQoJCQkJYnJlYWs7CgkJCWlmIChmYWlsZWRfY29tbWFuZCA9PSBOVUxMIHx8CgkJCQkJIWJsa19mc19yZXF1ZXN0KGZhaWxlZF9jb21tYW5kKSkKCQkJCWJyZWFrOwoJCQlzZWN0b3IgPSAoc2Vuc2UtPmluZm9ybWF0aW9uWzBdIDw8IDI0KSB8CgkJCQkgKHNlbnNlLT5pbmZvcm1hdGlvblsxXSA8PCAxNikgfAoJCQkJIChzZW5zZS0+aW5mb3JtYXRpb25bMl0gPDwgIDgpIHwKCQkJCSAoc2Vuc2UtPmluZm9ybWF0aW9uWzNdKTsKCgkJCWJpb19zZWN0b3JzID0gYmlvX3NlY3RvcnMoZmFpbGVkX2NvbW1hbmQtPmJpbyk7CgkJCWlmIChiaW9fc2VjdG9ycyA8IDQpCgkJCQliaW9fc2VjdG9ycyA9IDQ7CgkJCWlmIChkcml2ZS0+cXVldWUtPmhhcmRzZWN0X3NpemUgPT0gMjA0OCkKCQkJCXNlY3RvciA8PD0gMjsJLyogRGV2aWNlIHNlY3RvciBzaXplIGlzIDJLICovCgkJCXNlY3RvciAmPSB+KGJpb19zZWN0b3JzIC0xKTsKCQkJdmFsaWQgPSAoc2VjdG9yIC0gZmFpbGVkX2NvbW1hbmQtPnNlY3RvcikgPDwgOTsKCgkJCWlmICh2YWxpZCA8IDApCgkJCQl2YWxpZCA9IDA7CgkJCWlmIChzZWN0b3IgPCBnZXRfY2FwYWNpdHkoaW5mby0+ZGlzaykgJiYKCQkJCWRyaXZlLT5wcm9iZWRfY2FwYWNpdHkgLSBzZWN0b3IgPCA0ICogNzUpIHsKCQkJCXNldF9jYXBhY2l0eShpbmZvLT5kaXNrLCBzZWN0b3IpOwoJCQl9CiAJCX0KIAl9CiNpZiBWRVJCT1NFX0lERV9DRF9FUlJPUlMKCXsKCQlpbnQgaTsKCQljb25zdCBjaGFyICpzID0gImJhZCBzZW5zZSBrZXkhIjsKCQljaGFyIGJ1Zls4MF07CgoJCXByaW50ayAoIkFUQVBJIGRldmljZSAlczpcbiIsIGRyaXZlLT5uYW1lKTsKCQlpZiAoc2Vuc2UtPmVycm9yX2NvZGU9PTB4NzApCgkJCXByaW50aygiICBFcnJvcjogIik7CgkJZWxzZSBpZiAoc2Vuc2UtPmVycm9yX2NvZGU9PTB4NzEpCgkJCXByaW50aygiICBEZWZlcnJlZCBFcnJvcjogIik7CgkJZWxzZSBpZiAoc2Vuc2UtPmVycm9yX2NvZGUgPT0gMHg3ZikKCQkJcHJpbnRrKCIgIFZlbmRvci1zcGVjaWZpYyBFcnJvcjogIik7CgkJZWxzZQoJCQlwcmludGsoIiAgVW5rbm93biBFcnJvciBUeXBlOiAiKTsKCgkJaWYgKHNlbnNlLT5zZW5zZV9rZXkgPCBBUllfTEVOKHNlbnNlX2tleV90ZXh0cykpCgkJCXMgPSBzZW5zZV9rZXlfdGV4dHNbc2Vuc2UtPnNlbnNlX2tleV07CgoJCXByaW50aygiJXMgLS0gKFNlbnNlIGtleT0weCUwMngpXG4iLCBzLCBzZW5zZS0+c2Vuc2Vfa2V5KTsKCgkJaWYgKHNlbnNlLT5hc2MgPT0gMHg0MCkgewoJCQlzcHJpbnRmKGJ1ZiwgIkRpYWdub3N0aWMgZmFpbHVyZSBvbiBjb21wb25lbnQgMHglMDJ4IiwKCQkJCSBzZW5zZS0+YXNjcSk7CgkJCXMgPSBidWY7CgkJfSBlbHNlIHsKCQkJaW50IGxvID0gMCwgbWlkLCBoaSA9IEFSWV9MRU4oc2Vuc2VfZGF0YV90ZXh0cyk7CgkJCXVuc2lnbmVkIGxvbmcga2V5ID0gKHNlbnNlLT5zZW5zZV9rZXkgPDwgMTYpOwoJCQlrZXkgfD0gKHNlbnNlLT5hc2MgPDwgOCk7CgkJCWlmICghKHNlbnNlLT5hc2NxID49IDB4ODAgJiYgc2Vuc2UtPmFzY3EgPD0gMHhkZCkpCgkJCQlrZXkgfD0gc2Vuc2UtPmFzY3E7CgkJCXMgPSBOVUxMOwoKCQkJd2hpbGUgKGhpID4gbG8pIHsKCQkJCW1pZCA9IChsbyArIGhpKSAvIDI7CgkJCQlpZiAoc2Vuc2VfZGF0YV90ZXh0c1ttaWRdLmFzY19hc2NxID09IGtleSB8fAoJCQkJICAgIHNlbnNlX2RhdGFfdGV4dHNbbWlkXS5hc2NfYXNjcSA9PSAoMHhmZjAwMDB8a2V5KSkgewoJCQkJCXMgPSBzZW5zZV9kYXRhX3RleHRzW21pZF0udGV4dDsKCQkJCQlicmVhazsKCQkJCX0KCQkJCWVsc2UgaWYgKHNlbnNlX2RhdGFfdGV4dHNbbWlkXS5hc2NfYXNjcSA+IGtleSkKCQkJCQloaSA9IG1pZDsKCQkJCWVsc2UKCQkJCQlsbyA9IG1pZCsxOwoJCQl9CgkJfQoKCQlpZiAocyA9PSBOVUxMKSB7CgkJCWlmIChzZW5zZS0+YXNjID4gMHg4MCkKCQkJCXMgPSAiKHZlbmRvci1zcGVjaWZpYyBlcnJvcikiOwoJCQllbHNlCgkJCQlzID0gIihyZXNlcnZlZCBlcnJvciBjb2RlKSI7CgkJfQoKCQlwcmludGsoS0VSTl9FUlIgIiAgJXMgLS0gKGFzYz0weCUwMngsIGFzY3E9MHglMDJ4KVxuIiwKCQkJcywgc2Vuc2UtPmFzYywgc2Vuc2UtPmFzY3EpOwoKCQlpZiAoZmFpbGVkX2NvbW1hbmQgIT0gTlVMTCkgewoKCQkJaW50IGxvPTAsIG1pZCwgaGk9IEFSWV9MRU4gKHBhY2tldF9jb21tYW5kX3RleHRzKTsKCQkJcyA9IE5VTEw7CgoJCQl3aGlsZSAoaGkgPiBsbykgewoJCQkJbWlkID0gKGxvICsgaGkpIC8gMjsKCQkJCWlmIChwYWNrZXRfY29tbWFuZF90ZXh0c1ttaWRdLnBhY2tldF9jb21tYW5kID09CgkJCQkgICAgZmFpbGVkX2NvbW1hbmQtPmNtZFswXSkgewoJCQkJCXMgPSBwYWNrZXRfY29tbWFuZF90ZXh0c1ttaWRdLnRleHQ7CgkJCQkJYnJlYWs7CgkJCQl9CgkJCQlpZiAocGFja2V0X2NvbW1hbmRfdGV4dHNbbWlkXS5wYWNrZXRfY29tbWFuZCA+CgkJCQkgICAgZmFpbGVkX2NvbW1hbmQtPmNtZFswXSkKCQkJCQloaSA9IG1pZDsKCQkJCWVsc2UKCQkJCQlsbyA9IG1pZCsxOwoJCQl9CgoJCQlwcmludGsgKEtFUk5fRVJSICIgIFRoZSBmYWlsZWQgXCIlc1wiIHBhY2tldCBjb21tYW5kIHdhczogXG4gIFwiIiwgcyk7CgkJCWZvciAoaT0wOyBpPHNpemVvZiAoZmFpbGVkX2NvbW1hbmQtPmNtZCk7IGkrKykKCQkJCXByaW50ayAoIiUwMnggIiwgZmFpbGVkX2NvbW1hbmQtPmNtZFtpXSk7CgkJCXByaW50ayAoIlwiXG4iKTsKCQl9CgoJCS8qIFRoZSBTS1NWIGJpdCBzcGVjaWZpZXMgdmFsaWRpdHkgb2YgdGhlIHNlbnNlX2tleV9zcGVjaWZpYwoJCSAqIGluIHRoZSBuZXh0IHR3byBjb21tYW5kcy4gSXQgaXMgYml0IDcgb2YgdGhlIGZpcnN0IGJ5dGUuCgkJICogSW4gdGhlIGNhc2Ugb2YgTk9UX1JFQURZLCBpZiBTS1NWIGlzIHNldCB0aGUgZHJpdmUgY2FuCgkJICogZ2l2ZSB1cyBuaWNlIEVUQSByZWFkaW5ncy4KCQkgKi8KCQlpZiAoc2Vuc2UtPnNlbnNlX2tleSA9PSBOT1RfUkVBRFkgJiYgKHNlbnNlLT5za3NbMF0gJiAweDgwKSkgewoJCQlpbnQgcHJvZ3Jlc3MgPSAoc2Vuc2UtPnNrc1sxXSA8PCA4IHwgc2Vuc2UtPnNrc1syXSkgKiAxMDA7CgkJCXByaW50ayhLRVJOX0VSUiAiICBDb21tYW5kIGlzICUwMmQlJSBjb21wbGV0ZVxuIiwgcHJvZ3Jlc3MgLyAweGZmZmYpOwoKCQl9CgoJCWlmIChzZW5zZS0+c2Vuc2Vfa2V5ID09IElMTEVHQUxfUkVRVUVTVCAmJgoJCSAgICAoc2Vuc2UtPnNrc1swXSAmIDB4ODApICE9IDApIHsKCQkJcHJpbnRrKEtFUk5fRVJSICIgIEVycm9yIGluICVzIGJ5dGUgJWQiLAoJCQkJKHNlbnNlLT5za3NbMF0gJiAweDQwKSAhPSAwID8KCQkJCSJjb21tYW5kIHBhY2tldCIgOiAiY29tbWFuZCBkYXRhIiwKCQkJCShzZW5zZS0+c2tzWzFdIDw8IDgpICsgc2Vuc2UtPnNrc1syXSk7CgoJCQlpZiAoKHNlbnNlLT5za3NbMF0gJiAweDQwKSAhPSAwKQoJCQkJcHJpbnRrICgiIGJpdCAlZCIsIHNlbnNlLT5za3NbMF0gJiAweDA3KTsKCgkJCXByaW50ayAoIlxuIik7CgkJfQoJfQoKI2Vsc2UgLyogbm90IFZFUkJPU0VfSURFX0NEX0VSUk9SUyAqLwoKCS8qIFN1cHByZXNzIHByaW50aW5nIHVuaXQgYXR0ZW50aW9uIGFuZCBgaW4gcHJvZ3Jlc3Mgb2YgYmVjb21pbmcgcmVhZHknCgkgICBlcnJvcnMgd2hlbiB3ZSdyZSBub3QgYmVpbmcgdmVyYm9zZS4gKi8KCglpZiAoc2Vuc2UtPnNlbnNlX2tleSA9PSBVTklUX0FUVEVOVElPTiB8fAoJICAgIChzZW5zZS0+c2Vuc2Vfa2V5ID09IE5PVF9SRUFEWSAmJiAoc2Vuc2UtPmFzYyA9PSA0IHx8CgkJCQkJCXNlbnNlLT5hc2MgPT0gMHgzYSkpKQoJCXJldHVybjsKCglwcmludGsoS0VSTl9FUlIgIiVzOiBlcnJvciBjb2RlOiAweCUwMnggIHNlbnNlX2tleTogMHglMDJ4ICBhc2M6IDB4JTAyeCAgYXNjcTogMHglMDJ4XG4iLAoJCWRyaXZlLT5uYW1lLAoJCXNlbnNlLT5lcnJvcl9jb2RlLCBzZW5zZS0+c2Vuc2Vfa2V5LAoJCXNlbnNlLT5hc2MsIHNlbnNlLT5hc2NxKTsKI2VuZGlmIC8qIG5vdCBWRVJCT1NFX0lERV9DRF9FUlJPUlMgKi8KfQoKLyoKICogSW5pdGlhbGl6ZSBhIGlkZS1jZCBwYWNrZXQgY29tbWFuZCByZXF1ZXN0CiAqLwpzdGF0aWMgdm9pZCBjZHJvbV9wcmVwYXJlX3JlcXVlc3QoaWRlX2RyaXZlX3QgKmRyaXZlLCBzdHJ1Y3QgcmVxdWVzdCAqcnEpCnsKCXN0cnVjdCBjZHJvbV9pbmZvICpjZCA9IGRyaXZlLT5kcml2ZXJfZGF0YTsKCglpZGVfaW5pdF9kcml2ZV9jbWQocnEpOwoJcnEtPmNtZF90eXBlID0gUkVRX1RZUEVfQVRBX1BDOwoJcnEtPnJxX2Rpc2sgPSBjZC0+ZGlzazsKfQoKc3RhdGljIHZvaWQgY2Ryb21fcXVldWVfcmVxdWVzdF9zZW5zZShpZGVfZHJpdmVfdCAqZHJpdmUsIHZvaWQgKnNlbnNlLAoJCQkJICAgICAgc3RydWN0IHJlcXVlc3QgKmZhaWxlZF9jb21tYW5kKQp7CglzdHJ1Y3QgY2Ryb21faW5mbyAqaW5mbwkJPSBkcml2ZS0+ZHJpdmVyX2RhdGE7CglzdHJ1Y3QgcmVxdWVzdCAqcnEJCT0gJmluZm8tPnJlcXVlc3Rfc2Vuc2VfcmVxdWVzdDsKCglpZiAoc2Vuc2UgPT0gTlVMTCkKCQlzZW5zZSA9ICZpbmZvLT5zZW5zZV9kYXRhOwoKCS8qIHN0dWZmIHRoZSBzZW5zZSByZXF1ZXN0IGluIGZyb250IG9mIG91ciBjdXJyZW50IHJlcXVlc3QgKi8KCWNkcm9tX3ByZXBhcmVfcmVxdWVzdChkcml2ZSwgcnEpOwoKCXJxLT5kYXRhID0gc2Vuc2U7CglycS0+Y21kWzBdID0gR1BDTURfUkVRVUVTVF9TRU5TRTsKCXJxLT5jbWRbNF0gPSBycS0+ZGF0YV9sZW4gPSAxODsKCglycS0+Y21kX3R5cGUgPSBSRVFfVFlQRV9TRU5TRTsKCgkvKiBOT1RFISBTYXZlIHRoZSBmYWlsZWQgY29tbWFuZCBpbiAicnEtPmJ1ZmZlciIgKi8KCXJxLT5idWZmZXIgPSAodm9pZCAqKSBmYWlsZWRfY29tbWFuZDsKCgkodm9pZCkgaWRlX2RvX2RyaXZlX2NtZChkcml2ZSwgcnEsIGlkZV9wcmVlbXB0KTsKfQoKc3RhdGljIHZvaWQgY2Ryb21fZW5kX3JlcXVlc3QgKGlkZV9kcml2ZV90ICpkcml2ZSwgaW50IHVwdG9kYXRlKQp7CglzdHJ1Y3QgcmVxdWVzdCAqcnEgPSBIV0dST1VQKGRyaXZlKS0+cnE7CglpbnQgbnNlY3RvcnMgPSBycS0+aGFyZF9jdXJfc2VjdG9yczsKCglpZiAoYmxrX3NlbnNlX3JlcXVlc3QocnEpICYmIHVwdG9kYXRlKSB7CgkJLyoKCQkgKiBGb3IgUkVRX1RZUEVfU0VOU0UsICJycS0+YnVmZmVyIiBwb2ludHMgdG8gdGhlIG9yaWdpbmFsCgkJICogZmFpbGVkIHJlcXVlc3QKCQkgKi8KCQlzdHJ1Y3QgcmVxdWVzdCAqZmFpbGVkID0gKHN0cnVjdCByZXF1ZXN0ICopIHJxLT5idWZmZXI7CgkJc3RydWN0IGNkcm9tX2luZm8gKmluZm8gPSBkcml2ZS0+ZHJpdmVyX2RhdGE7CgkJdm9pZCAqc2Vuc2UgPSAmaW5mby0+c2Vuc2VfZGF0YTsKCQl1bnNpZ25lZCBsb25nIGZsYWdzOwoKCQlpZiAoZmFpbGVkKSB7CgkJCWlmIChmYWlsZWQtPnNlbnNlKSB7CgkJCQlzZW5zZSA9IGZhaWxlZC0+c2Vuc2U7CgkJCQlmYWlsZWQtPnNlbnNlX2xlbiA9IHJxLT5zZW5zZV9sZW47CgkJCX0KCQkJY2Ryb21fYW5hbHl6ZV9zZW5zZV9kYXRhKGRyaXZlLCBmYWlsZWQsIHNlbnNlKTsKCQkJLyoKCQkJICogbm93IGVuZCBmYWlsZWQgcmVxdWVzdAoJCQkgKi8KCQkJaWYgKGJsa19mc19yZXF1ZXN0KGZhaWxlZCkpIHsKCQkJCWlmIChpZGVfZW5kX2RlcXVldWVkX3JlcXVlc3QoZHJpdmUsIGZhaWxlZCwgMCwKCQkJCQkJZmFpbGVkLT5oYXJkX25yX3NlY3RvcnMpKQoJCQkJCUJVRygpOwoJCQl9IGVsc2UgewoJCQkJc3Bpbl9sb2NrX2lycXNhdmUoJmlkZV9sb2NrLCBmbGFncyk7CgkJCQllbmRfdGhhdF9yZXF1ZXN0X2NodW5rKGZhaWxlZCwgMCwKCQkJCQkJCWZhaWxlZC0+ZGF0YV9sZW4pOwoJCQkJZW5kX3RoYXRfcmVxdWVzdF9sYXN0KGZhaWxlZCwgMCk7CgkJCQlzcGluX3VubG9ja19pcnFyZXN0b3JlKCZpZGVfbG9jaywgZmxhZ3MpOwoJCQl9CgkJfSBlbHNlCgkJCWNkcm9tX2FuYWx5emVfc2Vuc2VfZGF0YShkcml2ZSwgTlVMTCwgc2Vuc2UpOwoJfQoKCWlmICghcnEtPmN1cnJlbnRfbnJfc2VjdG9ycyAmJiBibGtfZnNfcmVxdWVzdChycSkpCgkJdXB0b2RhdGUgPSAxOwoJLyogbWFrZSBzdXJlIGl0J3MgZnVsbHkgZW5kZWQgKi8KCWlmIChibGtfcGNfcmVxdWVzdChycSkpCgkJbnNlY3RvcnMgPSAocnEtPmRhdGFfbGVuICsgNTExKSA+PiA5OwoJaWYgKCFuc2VjdG9ycykKCQluc2VjdG9ycyA9IDE7CgoJaWRlX2VuZF9yZXF1ZXN0KGRyaXZlLCB1cHRvZGF0ZSwgbnNlY3RvcnMpOwp9CgpzdGF0aWMgdm9pZCBpZGVfZHVtcF9zdGF0dXNfbm9fc2Vuc2UoaWRlX2RyaXZlX3QgKmRyaXZlLCBjb25zdCBjaGFyICptc2csIHU4IHN0YXQpCnsKCWlmIChzdGF0ICYgMHg4MCkKCQlyZXR1cm47CglpZGVfZHVtcF9zdGF0dXMoZHJpdmUsIG1zZywgc3RhdCk7Cn0KCi8qIFJldHVybnMgMCBpZiB0aGUgcmVxdWVzdCBzaG91bGQgYmUgY29udGludWVkLgogICBSZXR1cm5zIDEgaWYgdGhlIHJlcXVlc3Qgd2FzIGVuZGVkLiAqLwpzdGF0aWMgaW50IGNkcm9tX2RlY29kZV9zdGF0dXMoaWRlX2RyaXZlX3QgKmRyaXZlLCBpbnQgZ29vZF9zdGF0LCBpbnQgKnN0YXRfcmV0KQp7CglzdHJ1Y3QgcmVxdWVzdCAqcnEgPSBIV0dST1VQKGRyaXZlKS0+cnE7CglpbnQgc3RhdCwgZXJyLCBzZW5zZV9rZXk7CgkKCS8qIENoZWNrIGZvciBlcnJvcnMuICovCglzdGF0ID0gSFdJRihkcml2ZSktPklOQihJREVfU1RBVFVTX1JFRyk7CglpZiAoc3RhdF9yZXQpCgkJKnN0YXRfcmV0ID0gc3RhdDsKCglpZiAoT0tfU1RBVChzdGF0LCBnb29kX3N0YXQsIEJBRF9SX1NUQVQpKQoJCXJldHVybiAwOwoKCS8qIEdldCB0aGUgSURFIGVycm9yIHJlZ2lzdGVyLiAqLwoJZXJyID0gSFdJRihkcml2ZSktPklOQihJREVfRVJST1JfUkVHKTsKCXNlbnNlX2tleSA9IGVyciA+PiA0OwoKCWlmIChycSA9PSBOVUxMKSB7CgkJcHJpbnRrKCIlczogbWlzc2luZyBycSBpbiBjZHJvbV9kZWNvZGVfc3RhdHVzXG4iLCBkcml2ZS0+bmFtZSk7CgkJcmV0dXJuIDE7Cgl9CgoJaWYgKGJsa19zZW5zZV9yZXF1ZXN0KHJxKSkgewoJCS8qIFdlIGdvdCBhbiBlcnJvciB0cnlpbmcgdG8gZ2V0IHNlbnNlIGluZm8KCQkgICBmcm9tIHRoZSBkcml2ZSAocHJvYmFibHkgd2hpbGUgdHJ5aW5nCgkJICAgdG8gcmVjb3ZlciBmcm9tIGEgZm9ybWVyIGVycm9yKS4gIEp1c3QgZ2l2ZSB1cC4gKi8KCgkJcnEtPmNtZF9mbGFncyB8PSBSRVFfRkFJTEVEOwoJCWNkcm9tX2VuZF9yZXF1ZXN0KGRyaXZlLCAwKTsKCQlpZGVfZXJyb3IoZHJpdmUsICJyZXF1ZXN0IHNlbnNlIGZhaWx1cmUiLCBzdGF0KTsKCQlyZXR1cm4gMTsKCgl9IGVsc2UgaWYgKGJsa19wY19yZXF1ZXN0KHJxKSB8fCBycS0+Y21kX3R5cGUgPT0gUkVRX1RZUEVfQVRBX1BDKSB7CgkJLyogQWxsIG90aGVyIGZ1bmN0aW9ucywgZXhjZXB0IGZvciBSRUFELiAqLwoJCXVuc2lnbmVkIGxvbmcgZmxhZ3M7CgoJCS8qCgkJICogaWYgd2UgaGF2ZSBhbiBlcnJvciwgcGFzcyBiYWNrIENIRUNLX0NPTkRJVElPTiBhcyB0aGUKCQkgKiBzY3NpIHN0YXR1cyBieXRlCgkJICovCgkJaWYgKCFycS0+ZXJyb3JzKQoJCQlycS0+ZXJyb3JzID0gU0FNX1NUQVRfQ0hFQ0tfQ09ORElUSU9OOwoKCQkvKiBDaGVjayBmb3IgdHJheSBvcGVuLiAqLwoJCWlmIChzZW5zZV9rZXkgPT0gTk9UX1JFQURZKSB7CgkJCWNkcm9tX3Nhd19tZWRpYV9jaGFuZ2UgKGRyaXZlKTsKCQl9IGVsc2UgaWYgKHNlbnNlX2tleSA9PSBVTklUX0FUVEVOVElPTikgewoJCQkvKiBDaGVjayBmb3IgbWVkaWEgY2hhbmdlLiAqLwoJCQljZHJvbV9zYXdfbWVkaWFfY2hhbmdlIChkcml2ZSk7CgkJCS8qcHJpbnRrKCIlczogbWVkaWEgY2hhbmdlZFxuIixkcml2ZS0+bmFtZSk7Ki8KCQkJcmV0dXJuIDA7CgkJfSBlbHNlIGlmICghKHJxLT5jbWRfZmxhZ3MgJiBSRVFfUVVJRVQpKSB7CgkJCS8qIE90aGVyd2lzZSwgcHJpbnQgYW4gZXJyb3IuICovCgkJCWlkZV9kdW1wX3N0YXR1cyhkcml2ZSwgInBhY2tldCBjb21tYW5kIGVycm9yIiwgc3RhdCk7CgkJfQoJCQoJCXJxLT5jbWRfZmxhZ3MgfD0gUkVRX0ZBSUxFRDsKCgkJLyoKCQkgKiBpbnN0ZWFkIG9mIHBsYXlpbmcgZ2FtZXMgd2l0aCBtb3ZpbmcgY29tcGxldGlvbnMgYXJvdW5kLAoJCSAqIHJlbW92ZSBmYWlsZWQgcmVxdWVzdCBjb21wbGV0ZWx5IGFuZCBlbmQgaXQgd2hlbiB0aGUKCQkgKiByZXF1ZXN0IHNlbnNlIGhhcyBjb21wbGV0ZWQKCQkgKi8KCQlpZiAoc3RhdCAmIEVSUl9TVEFUKSB7CgkJCXNwaW5fbG9ja19pcnFzYXZlKCZpZGVfbG9jaywgZmxhZ3MpOwoJCQlibGtkZXZfZGVxdWV1ZV9yZXF1ZXN0KHJxKTsKCQkJSFdHUk9VUChkcml2ZSktPnJxID0gTlVMTDsKCQkJc3Bpbl91bmxvY2tfaXJxcmVzdG9yZSgmaWRlX2xvY2ssIGZsYWdzKTsKCgkJCWNkcm9tX3F1ZXVlX3JlcXVlc3Rfc2Vuc2UoZHJpdmUsIHJxLT5zZW5zZSwgcnEpOwoJCX0gZWxzZQoJCQljZHJvbV9lbmRfcmVxdWVzdChkcml2ZSwgMCk7CgoJfSBlbHNlIGlmIChibGtfZnNfcmVxdWVzdChycSkpIHsKCQlpbnQgZG9fZW5kX3JlcXVlc3QgPSAwOwoKCQkvKiBIYW5kbGUgZXJyb3JzIGZyb20gUkVBRCBhbmQgV1JJVEUgcmVxdWVzdHMuICovCgoJCWlmIChibGtfbm9yZXRyeV9yZXF1ZXN0KHJxKSkKCQkJZG9fZW5kX3JlcXVlc3QgPSAxOwoKCQlpZiAoc2Vuc2Vfa2V5ID09IE5PVF9SRUFEWSkgewoJCQkvKiBUcmF5IG9wZW4uICovCgkJCWlmIChycV9kYXRhX2RpcihycSkgPT0gUkVBRCkgewoJCQkJY2Ryb21fc2F3X21lZGlhX2NoYW5nZSAoZHJpdmUpOwoKCQkJCS8qIEZhaWwgdGhlIHJlcXVlc3QuICovCgkJCQlwcmludGsgKCIlczogdHJheSBvcGVuXG4iLCBkcml2ZS0+bmFtZSk7CgkJCQlkb19lbmRfcmVxdWVzdCA9IDE7CgkJCX0gZWxzZSB7CgkJCQlzdHJ1Y3QgY2Ryb21faW5mbyAqaW5mbyA9IGRyaXZlLT5kcml2ZXJfZGF0YTsKCgkJCQkvKiBhbGxvdyB0aGUgZHJpdmUgNSBzZWNvbmRzIHRvIHJlY292ZXIsIHNvbWUKCQkJCSAqIGRldmljZXMgd2lsbCByZXR1cm4gdGhpcyBlcnJvciB3aGlsZSBmbHVzaGluZwoJCQkJICogZGF0YSBmcm9tIGNhY2hlICovCgkJCQlpZiAoIXJxLT5lcnJvcnMpCgkJCQkJaW5mby0+d3JpdGVfdGltZW91dCA9IGppZmZpZXMgKyBBVEFQSV9XQUlUX1dSSVRFX0JVU1k7CgkJCQlycS0+ZXJyb3JzID0gMTsKCQkJCWlmICh0aW1lX2FmdGVyKGppZmZpZXMsIGluZm8tPndyaXRlX3RpbWVvdXQpKQoJCQkJCWRvX2VuZF9yZXF1ZXN0ID0gMTsKCQkJCWVsc2UgewoJCQkJCXVuc2lnbmVkIGxvbmcgZmxhZ3M7CgoJCQkJCS8qCgkJCQkJICogdGFrZSBhIGJyZWF0aGVyIHJlbHlpbmcgb24gdGhlCgkJCQkJICogdW5wbHVnIHRpbWVyIHRvIGtpY2sgdXMgYWdhaW4KCQkJCQkgKi8KCQkJCQlzcGluX2xvY2tfaXJxc2F2ZSgmaWRlX2xvY2ssIGZsYWdzKTsKCQkJCQlibGtfcGx1Z19kZXZpY2UoZHJpdmUtPnF1ZXVlKTsKCQkJCQlzcGluX3VubG9ja19pcnFyZXN0b3JlKCZpZGVfbG9jayxmbGFncyk7CgkJCQkJcmV0dXJuIDE7CgkJCQl9CgkJCX0KCQl9IGVsc2UgaWYgKHNlbnNlX2tleSA9PSBVTklUX0FUVEVOVElPTikgewoJCQkvKiBNZWRpYSBjaGFuZ2UuICovCgkJCWNkcm9tX3Nhd19tZWRpYV9jaGFuZ2UgKGRyaXZlKTsKCgkJCS8qIEFycmFuZ2UgdG8gcmV0cnkgdGhlIHJlcXVlc3QuCgkJCSAgIEJ1dCBiZSBzdXJlIHRvIGdpdmUgdXAgaWYgd2UndmUgcmV0cmllZAoJCQkgICB0b28gbWFueSB0aW1lcy4gKi8KCQkJaWYgKCsrcnEtPmVycm9ycyA+IEVSUk9SX01BWCkKCQkJCWRvX2VuZF9yZXF1ZXN0ID0gMTsKCQl9IGVsc2UgaWYgKHNlbnNlX2tleSA9PSBJTExFR0FMX1JFUVVFU1QgfHwKCQkJICAgc2Vuc2Vfa2V5ID09IERBVEFfUFJPVEVDVCkgewoJCQkvKiBObyBwb2ludCBpbiByZXRyeWluZyBhZnRlciBhbiBpbGxlZ2FsCgkJCSAgIHJlcXVlc3Qgb3IgZGF0YSBwcm90ZWN0IGVycm9yLiovCgkJCWlkZV9kdW1wX3N0YXR1c19ub19zZW5zZSAoZHJpdmUsICJjb21tYW5kIGVycm9yIiwgc3RhdCk7CgkJCWRvX2VuZF9yZXF1ZXN0ID0gMTsKCQl9IGVsc2UgaWYgKHNlbnNlX2tleSA9PSBNRURJVU1fRVJST1IpIHsKCQkJLyogTm8gcG9pbnQgaW4gcmUtdHJ5aW5nIGEgemlsbGlvbiB0aW1lcyBvbiBhIGJhZCAKCQkJICogc2VjdG9yLi4uICBJZiB3ZSBnb3QgaGVyZSB0aGUgZXJyb3IgaXMgbm90IGNvcnJlY3RhYmxlICovCgkJCWlkZV9kdW1wX3N0YXR1c19ub19zZW5zZSAoZHJpdmUsICJtZWRpYSBlcnJvciAoYmFkIHNlY3RvcikiLCBzdGF0KTsKCQkJZG9fZW5kX3JlcXVlc3QgPSAxOwoJCX0gZWxzZSBpZiAoc2Vuc2Vfa2V5ID09IEJMQU5LX0NIRUNLKSB7CgkJCS8qIERpc2sgYXBwZWFycyBibGFuayA/PyAqLwoJCQlpZGVfZHVtcF9zdGF0dXNfbm9fc2Vuc2UgKGRyaXZlLCAibWVkaWEgZXJyb3IgKGJsYW5rKSIsIHN0YXQpOwoJCQlkb19lbmRfcmVxdWVzdCA9IDE7CgkJfSBlbHNlIGlmICgoZXJyICYgfkFCUlRfRVJSKSAhPSAwKSB7CgkJCS8qIEdvIHRvIHRoZSBkZWZhdWx0IGhhbmRsZXIKCQkJICAgZm9yIG90aGVyIGVycm9ycy4gKi8KCQkJaWRlX2Vycm9yKGRyaXZlLCAiY2Ryb21fZGVjb2RlX3N0YXR1cyIsIHN0YXQpOwoJCQlyZXR1cm4gMTsKCQl9IGVsc2UgaWYgKCgrK3JxLT5lcnJvcnMgPiBFUlJPUl9NQVgpKSB7CgkJCS8qIFdlJ3ZlIHJhY2tlZCB1cCB0b28gbWFueSByZXRyaWVzLiAgQWJvcnQuICovCgkJCWRvX2VuZF9yZXF1ZXN0ID0gMTsKCQl9CgoJCS8qIEVuZCBhIHJlcXVlc3QgdGhyb3VnaCByZXF1ZXN0IHNlbnNlIGFuYWx5c2lzIHdoZW4gd2UgaGF2ZQoJCSAgIHNlbnNlIGRhdGEuIFdlIG5lZWQgdGhpcyBpbiBvcmRlciB0byBwZXJmb3JtIGVuZCBvZiBtZWRpYQoJCSAgIHByb2Nlc3NpbmcgKi8KCgkJaWYgKGRvX2VuZF9yZXF1ZXN0KSB7CgkJCWlmIChzdGF0ICYgRVJSX1NUQVQpIHsKCQkJCXVuc2lnbmVkIGxvbmcgZmxhZ3M7CgkJCQlzcGluX2xvY2tfaXJxc2F2ZSgmaWRlX2xvY2ssIGZsYWdzKTsKCQkJCWJsa2Rldl9kZXF1ZXVlX3JlcXVlc3QocnEpOwoJCQkJSFdHUk9VUChkcml2ZSktPnJxID0gTlVMTDsKCQkJCXNwaW5fdW5sb2NrX2lycXJlc3RvcmUoJmlkZV9sb2NrLCBmbGFncyk7CgoJCQkJY2Ryb21fcXVldWVfcmVxdWVzdF9zZW5zZShkcml2ZSwgcnEtPnNlbnNlLCBycSk7CgkJCX0gZWxzZQoJCQkJY2Ryb21fZW5kX3JlcXVlc3QoZHJpdmUsIDApOwoJCX0gZWxzZSB7CgkJCS8qIElmIHdlIGdvdCBhIENIRUNLX0NPTkRJVElPTiBzdGF0dXMsCgkJCSAgIHF1ZXVlIGEgcmVxdWVzdCBzZW5zZSBjb21tYW5kLiAqLwoJCQlpZiAoc3RhdCAmIEVSUl9TVEFUKQoJCQkJY2Ryb21fcXVldWVfcmVxdWVzdF9zZW5zZShkcml2ZSwgTlVMTCwgTlVMTCk7CgkJfQoJfSBlbHNlIHsKCQlibGtfZHVtcF9ycV9mbGFncyhycSwgImlkZS1jZDogYmFkIHJxIik7CgkJY2Ryb21fZW5kX3JlcXVlc3QoZHJpdmUsIDApOwoJfQoKCS8qIFJldHJ5LCBvciBoYW5kbGUgdGhlIG5leHQgcmVxdWVzdC4gKi8KCXJldHVybiAxOwp9CgpzdGF0aWMgaW50IGNkcm9tX3RpbWVyX2V4cGlyeShpZGVfZHJpdmVfdCAqZHJpdmUpCnsKCXN0cnVjdCByZXF1ZXN0ICpycSA9IEhXR1JPVVAoZHJpdmUpLT5ycTsKCXVuc2lnbmVkIGxvbmcgd2FpdCA9IDA7CgoJLyoKCSAqIFNvbWUgY29tbWFuZHMgYXJlICpzbG93KiBhbmQgbm9ybWFsbHkgdGFrZSBhIGxvbmcgdGltZSB0bwoJICogY29tcGxldGUuIFVzdWFsbHkgd2UgY2FuIHVzZSB0aGUgQVRBUEkgImRpc2Nvbm5lY3QiIHRvIGJ5cGFzcwoJICogdGhpcywgYnV0IG5vdCBhbGwgY29tbWFuZHMvZHJpdmVzIHN1cHBvcnQgdGhhdC4gTGV0CgkgKiBpZGVfdGltZXJfZXhwaXJ5IGtlZXAgcG9sbGluZyB1cyBmb3IgdGhlc2UuCgkgKi8KCXN3aXRjaCAocnEtPmNtZFswXSkgewoJCWNhc2UgR1BDTURfQkxBTks6CgkJY2FzZSBHUENNRF9GT1JNQVRfVU5JVDoKCQljYXNlIEdQQ01EX1JFU0VSVkVfUlpPTkVfVFJBQ0s6CgkJY2FzZSBHUENNRF9DTE9TRV9UUkFDSzoKCQljYXNlIEdQQ01EX0ZMVVNIX0NBQ0hFOgoJCQl3YWl0ID0gQVRBUElfV0FJVF9QQzsKCQkJYnJlYWs7CgkJZGVmYXVsdDoKCQkJaWYgKCEocnEtPmNtZF9mbGFncyAmIFJFUV9RVUlFVCkpCgkJCQlwcmludGsoS0VSTl9JTkZPICJpZGUtY2Q6IGNtZCAweCV4IHRpbWVkIG91dFxuIiwgcnEtPmNtZFswXSk7CgkJCXdhaXQgPSAwOwoJCQlicmVhazsKCX0KCXJldHVybiB3YWl0Owp9CgovKiBTZXQgdXAgdGhlIGRldmljZSByZWdpc3RlcnMgZm9yIHRyYW5zZmVycmluZyBhIHBhY2tldCBjb21tYW5kIG9uIERFViwKICAgZXhwZWN0aW5nIHRvIGxhdGVyIHRyYW5zZmVyIFhGRVJMRU4gYnl0ZXMuICBIQU5ETEVSIGlzIHRoZSByb3V0aW5lCiAgIHdoaWNoIGFjdHVhbGx5IHRyYW5zZmVycyB0aGUgY29tbWFuZCB0byB0aGUgZHJpdmUuICBJZiB0aGlzIGlzIGEKICAgZHJxX2ludGVycnVwdCBkZXZpY2UsIHRoaXMgcm91dGluZSB3aWxsIGFycmFuZ2UgZm9yIEhBTkRMRVIgdG8gYmUKICAgY2FsbGVkIHdoZW4gdGhlIGludGVycnVwdCBmcm9tIHRoZSBkcml2ZSBhcnJpdmVzLiAgT3RoZXJ3aXNlLCBIQU5ETEVSCiAgIHdpbGwgYmUgY2FsbGVkIGltbWVkaWF0ZWx5IGFmdGVyIHRoZSBkcml2ZSBpcyBwcmVwYXJlZCBmb3IgdGhlIHRyYW5zZmVyLiAqLwoKc3RhdGljIGlkZV9zdGFydHN0b3BfdCBjZHJvbV9zdGFydF9wYWNrZXRfY29tbWFuZChpZGVfZHJpdmVfdCAqZHJpdmUsCgkJCQkJCSAgaW50IHhmZXJsZW4sCgkJCQkJCSAgaWRlX2hhbmRsZXJfdCAqaGFuZGxlcikKewoJaWRlX3N0YXJ0c3RvcF90IHN0YXJ0c3RvcDsKCXN0cnVjdCBjZHJvbV9pbmZvICppbmZvID0gZHJpdmUtPmRyaXZlcl9kYXRhOwoJaWRlX2h3aWZfdCAqaHdpZiA9IGRyaXZlLT5od2lmOwoKCS8qIFdhaXQgZm9yIHRoZSBjb250cm9sbGVyIHRvIGJlIGlkbGUuICovCglpZiAoaWRlX3dhaXRfc3RhdCgmc3RhcnRzdG9wLCBkcml2ZSwgMCwgQlVTWV9TVEFULCBXQUlUX1JFQURZKSkKCQlyZXR1cm4gc3RhcnRzdG9wOwoKCWlmIChpbmZvLT5kbWEpCgkJaW5mby0+ZG1hID0gIWh3aWYtPmRtYV9zZXR1cChkcml2ZSk7CgoJLyogU2V0IHVwIHRoZSBjb250cm9sbGVyIHJlZ2lzdGVycy4gKi8KCS8qIEZJWE1FOiBmb3IgVmlydHVhbCBETUEgd2UgbXVzdCBjaGVjayBoYXJkZXIgKi8KCUhXSUYoZHJpdmUpLT5PVVRCKGluZm8tPmRtYSwgSURFX0ZFQVRVUkVfUkVHKTsKCUhXSUYoZHJpdmUpLT5PVVRCKDAsIElERV9JUkVBU09OX1JFRyk7CglIV0lGKGRyaXZlKS0+T1VUQigwLCBJREVfU0VDVE9SX1JFRyk7CgoJSFdJRihkcml2ZSktPk9VVEIoeGZlcmxlbiAmIDB4ZmYsIElERV9CQ09VTlRMX1JFRyk7CglIV0lGKGRyaXZlKS0+T1VUQih4ZmVybGVuID4+IDggICwgSURFX0JDT1VOVEhfUkVHKTsKCWlmIChJREVfQ09OVFJPTF9SRUcpCgkJSFdJRihkcml2ZSktPk9VVEIoZHJpdmUtPmN0bCwgSURFX0NPTlRST0xfUkVHKTsKIAoJaWYgKENEUk9NX0NPTkZJR19GTEFHUyAoZHJpdmUpLT5kcnFfaW50ZXJydXB0KSB7CgkJLyogcGFja2V0IGNvbW1hbmQgKi8KCQlpZGVfZXhlY3V0ZV9jb21tYW5kKGRyaXZlLCBXSU5fUEFDS0VUQ01ELCBoYW5kbGVyLCBBVEFQSV9XQUlUX1BDLCBjZHJvbV90aW1lcl9leHBpcnkpOwoJCXJldHVybiBpZGVfc3RhcnRlZDsKCX0gZWxzZSB7CgkJdW5zaWduZWQgbG9uZyBmbGFnczsKCgkJLyogcGFja2V0IGNvbW1hbmQgKi8KCQlzcGluX2xvY2tfaXJxc2F2ZSgmaWRlX2xvY2ssIGZsYWdzKTsKCQlod2lmLT5PVVRCU1lOQyhkcml2ZSwgV0lOX1BBQ0tFVENNRCwgSURFX0NPTU1BTkRfUkVHKTsKCQluZGVsYXkoNDAwKTsKCQlzcGluX3VubG9ja19pcnFyZXN0b3JlKCZpZGVfbG9jaywgZmxhZ3MpOwoKCQlyZXR1cm4gKCpoYW5kbGVyKSAoZHJpdmUpOwoJfQp9CgovKiBTZW5kIGEgcGFja2V0IGNvbW1hbmQgdG8gRFJJVkUgZGVzY3JpYmVkIGJ5IENNRF9CVUYgYW5kIENNRF9MRU4uCiAgIFRoZSBkZXZpY2UgcmVnaXN0ZXJzIG11c3QgaGF2ZSBhbHJlYWR5IGJlZW4gcHJlcGFyZWQKICAgYnkgY2Ryb21fc3RhcnRfcGFja2V0X2NvbW1hbmQuCiAgIEhBTkRMRVIgaXMgdGhlIGludGVycnVwdCBoYW5kbGVyIHRvIGNhbGwgd2hlbiB0aGUgY29tbWFuZCBjb21wbGV0ZXMKICAgb3IgdGhlcmUncyBkYXRhIHJlYWR5LiAqLwovKgogKiBjaGFuZ2VkIDUgcGFyYW1ldGVycyB0byAzIGZvciBkdmQtcmFtCiAqIHN0cnVjdCBwYWNrZXRfY29tbWFuZCAqcGM7IG5vdyBwYWNrZXRfY29tbWFuZF90ICpwYzsKICovCiNkZWZpbmUgQVRBUElfTUlOX0NEQl9CWVRFUyAxMgpzdGF0aWMgaWRlX3N0YXJ0c3RvcF90IGNkcm9tX3RyYW5zZmVyX3BhY2tldF9jb21tYW5kIChpZGVfZHJpdmVfdCAqZHJpdmUsCgkJCQkJICBzdHJ1Y3QgcmVxdWVzdCAqcnEsCgkJCQkJICBpZGVfaGFuZGxlcl90ICpoYW5kbGVyKQp7CglpZGVfaHdpZl90ICpod2lmID0gZHJpdmUtPmh3aWY7CglpbnQgY21kX2xlbjsKCXN0cnVjdCBjZHJvbV9pbmZvICppbmZvID0gZHJpdmUtPmRyaXZlcl9kYXRhOwoJaWRlX3N0YXJ0c3RvcF90IHN0YXJ0c3RvcDsKCglpZiAoQ0RST01fQ09ORklHX0ZMQUdTKGRyaXZlKS0+ZHJxX2ludGVycnVwdCkgewoJCS8qIEhlcmUgd2Ugc2hvdWxkIGhhdmUgYmVlbiBjYWxsZWQgYWZ0ZXIgcmVjZWl2aW5nIGFuIGludGVycnVwdAoJCSAgIGZyb20gdGhlIGRldmljZS4gIERSUSBzaG91bGQgaG93IGJlIHNldC4gKi8KCgkJLyogQ2hlY2sgZm9yIGVycm9ycy4gKi8KCQlpZiAoY2Ryb21fZGVjb2RlX3N0YXR1cyhkcml2ZSwgRFJRX1NUQVQsIE5VTEwpKQoJCQlyZXR1cm4gaWRlX3N0b3BwZWQ7Cgl9IGVsc2UgewoJCS8qIE90aGVyd2lzZSwgd2UgbXVzdCB3YWl0IGZvciBEUlEgdG8gZ2V0IHNldC4gKi8KCQlpZiAoaWRlX3dhaXRfc3RhdCgmc3RhcnRzdG9wLCBkcml2ZSwgRFJRX1NUQVQsCgkJCQlCVVNZX1NUQVQsIFdBSVRfUkVBRFkpKQoJCQlyZXR1cm4gc3RhcnRzdG9wOwoJfQoKCS8qIEFybSB0aGUgaW50ZXJydXB0IGhhbmRsZXIuICovCglpZGVfc2V0X2hhbmRsZXIoZHJpdmUsIGhhbmRsZXIsIHJxLT50aW1lb3V0LCBjZHJvbV90aW1lcl9leHBpcnkpOwoKCS8qIEFUQVBJIGNvbW1hbmRzIGdldCBwYWRkZWQgb3V0IHRvIDEyIGJ5dGVzIG1pbmltdW0gKi8KCWNtZF9sZW4gPSBDT01NQU5EX1NJWkUocnEtPmNtZFswXSk7CglpZiAoY21kX2xlbiA8IEFUQVBJX01JTl9DREJfQllURVMpCgkJY21kX2xlbiA9IEFUQVBJX01JTl9DREJfQllURVM7CgoJLyogU2VuZCB0aGUgY29tbWFuZCB0byB0aGUgZGV2aWNlLiAqLwoJSFdJRihkcml2ZSktPmF0YXBpX291dHB1dF9ieXRlcyhkcml2ZSwgcnEtPmNtZCwgY21kX2xlbik7CgoJLyogU3RhcnQgdGhlIERNQSBpZiBuZWVkIGJlICovCglpZiAoaW5mby0+ZG1hKQoJCWh3aWYtPmRtYV9zdGFydChkcml2ZSk7CgoJcmV0dXJuIGlkZV9zdGFydGVkOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBCbG9jayByZWFkIGZ1bmN0aW9ucy4KICovCgovKgogKiBCdWZmZXIgdXAgdG8gU0VDVE9SU19UT19UUkFOU0ZFUiBzZWN0b3JzIGZyb20gdGhlIGRyaXZlIGluIG91ciBzZWN0b3IKICogYnVmZmVyLiAgT25jZSB0aGUgZmlyc3Qgc2VjdG9yIGlzIGFkZGVkLCBhbnkgc3Vic2VxdWVudCBzZWN0b3JzIGFyZQogKiBhc3N1bWVkIHRvIGJlIGNvbnRpbnVvdXMgKHVudGlsIHRoZSBidWZmZXIgaXMgY2xlYXJlZCkuICBGb3IgdGhlIGZpcnN0CiAqIHNlY3RvciBhZGRlZCwgU0VDVE9SIGlzIGl0cyBzZWN0b3IgbnVtYmVyLiAgKFNFQ1RPUiBpcyB0aGVuIGlnbm9yZWQgdW50aWwKICogdGhlIGJ1ZmZlciBpcyBjbGVhcmVkLikKICovCnN0YXRpYyB2b2lkIGNkcm9tX2J1ZmZlcl9zZWN0b3JzIChpZGVfZHJpdmVfdCAqZHJpdmUsIHVuc2lnbmVkIGxvbmcgc2VjdG9yLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IHNlY3RvcnNfdG9fdHJhbnNmZXIpCnsKCXN0cnVjdCBjZHJvbV9pbmZvICppbmZvID0gZHJpdmUtPmRyaXZlcl9kYXRhOwoKCS8qIE51bWJlciBvZiBzZWN0b3JzIHRvIHJlYWQgaW50byB0aGUgYnVmZmVyLiAqLwoJaW50IHNlY3RvcnNfdG9fYnVmZmVyID0gbWluX3QoaW50LCBzZWN0b3JzX3RvX3RyYW5zZmVyLAoJCQkJICAgICAoU0VDVE9SX0JVRkZFUl9TSVpFID4+IFNFQ1RPUl9CSVRTKSAtCgkJCQkgICAgICAgaW5mby0+bnNlY3RvcnNfYnVmZmVyZWQpOwoKCWNoYXIgKmRlc3Q7CgoJLyogSWYgd2UgY291bGRuJ3QgZ2V0IGEgYnVmZmVyLCBkb24ndCB0cnkgdG8gYnVmZmVyIGFueXRoaW5nLi4uICovCglpZiAoaW5mby0+YnVmZmVyID09IE5VTEwpCgkJc2VjdG9yc190b19idWZmZXIgPSAwOwoKCS8qIElmIHRoaXMgaXMgdGhlIGZpcnN0IHNlY3RvciBpbiB0aGUgYnVmZmVyLCByZW1lbWJlciBpdHMgbnVtYmVyLiAqLwoJaWYgKGluZm8tPm5zZWN0b3JzX2J1ZmZlcmVkID09IDApCgkJaW5mby0+c2VjdG9yX2J1ZmZlcmVkID0gc2VjdG9yOwoKCS8qIFJlYWQgdGhlIGRhdGEgaW50byB0aGUgYnVmZmVyLiAqLwoJZGVzdCA9IGluZm8tPmJ1ZmZlciArIGluZm8tPm5zZWN0b3JzX2J1ZmZlcmVkICogU0VDVE9SX1NJWkU7Cgl3aGlsZSAoc2VjdG9yc190b19idWZmZXIgPiAwKSB7CgkJSFdJRihkcml2ZSktPmF0YXBpX2lucHV0X2J5dGVzKGRyaXZlLCBkZXN0LCBTRUNUT1JfU0laRSk7CgkJLS1zZWN0b3JzX3RvX2J1ZmZlcjsKCQktLXNlY3RvcnNfdG9fdHJhbnNmZXI7CgkJKytpbmZvLT5uc2VjdG9yc19idWZmZXJlZDsKCQlkZXN0ICs9IFNFQ1RPUl9TSVpFOwoJfQoKCS8qIFRocm93IGF3YXkgYW55IHJlbWFpbmluZyBkYXRhLiAqLwoJd2hpbGUgKHNlY3RvcnNfdG9fdHJhbnNmZXIgPiAwKSB7CgkJc3RhdGljIGNoYXIgZHVtW1NFQ1RPUl9TSVpFXTsKCQlIV0lGKGRyaXZlKS0+YXRhcGlfaW5wdXRfYnl0ZXMoZHJpdmUsIGR1bSwgc2l6ZW9mIChkdW0pKTsKCQktLXNlY3RvcnNfdG9fdHJhbnNmZXI7Cgl9Cn0KCi8qCiAqIENoZWNrIHRoZSBjb250ZW50cyBvZiB0aGUgaW50ZXJydXB0IHJlYXNvbiByZWdpc3RlciBmcm9tIHRoZSBjZHJvbQogKiBhbmQgYXR0ZW1wdCB0byByZWNvdmVyIGlmIHRoZXJlIGFyZSBwcm9ibGVtcy4gIFJldHVybnMgIDAgaWYgZXZlcnl0aGluZydzCiAqIG9rOyBub256ZXJvIGlmIHRoZSByZXF1ZXN0IGhhcyBiZWVuIHRlcm1pbmF0ZWQuCiAqLwpzdGF0aWMKaW50IGNkcm9tX3JlYWRfY2hlY2tfaXJlYXNvbiAoaWRlX2RyaXZlX3QgKmRyaXZlLCBpbnQgbGVuLCBpbnQgaXJlYXNvbikKewoJaWYgKGlyZWFzb24gPT0gMikKCQlyZXR1cm4gMDsKCWVsc2UgaWYgKGlyZWFzb24gPT0gMCkgewoJCS8qIFdob29wcy4uLiBUaGUgZHJpdmUgaXMgZXhwZWN0aW5nIHRvIHJlY2VpdmUgZGF0YSBmcm9tIHVzISAqLwoJCXByaW50ayhLRVJOX0VSUiAiJXM6IHJlYWRfaW50cjogRHJpdmUgd2FudHMgdG8gdHJhbnNmZXIgZGF0YSB0aGUgIgoJCQkJCQkid3Jvbmcgd2F5IVxuIiwgZHJpdmUtPm5hbWUpOwoKCQkvKiBUaHJvdyBzb21lIGRhdGEgYXQgdGhlIGRyaXZlIHNvIGl0IGRvZXNuJ3QgaGFuZwoJCSAgIGFuZCBxdWl0IHRoaXMgcmVxdWVzdC4gKi8KCQl3aGlsZSAobGVuID4gMCkgewoJCQlpbnQgZHVtID0gMDsKCQkJSFdJRihkcml2ZSktPmF0YXBpX291dHB1dF9ieXRlcyhkcml2ZSwgJmR1bSwgc2l6ZW9mIChkdW0pKTsKCQkJbGVuIC09IHNpemVvZiAoZHVtKTsKCQl9Cgl9IGVsc2UgIGlmIChpcmVhc29uID09IDEpIHsKCQkvKiBTb21lIGRyaXZlcyAoQVNVUykgc2VlbSB0byB0ZWxsIHVzIHRoYXQgc3RhdHVzCgkJICogaW5mbyBpcyBhdmFpbGFibGUuIGp1c3QgZ2V0IGl0IGFuZCBpZ25vcmUuCgkJICovCgkJKHZvaWQpIEhXSUYoZHJpdmUpLT5JTkIoSURFX1NUQVRVU19SRUcpOwoJCXJldHVybiAwOwoJfSBlbHNlIHsKCQkvKiBEcml2ZSB3YW50cyBhIGNvbW1hbmQgcGFja2V0LCBvciBpbnZhbGlkIGlyZWFzb24uLi4gKi8KCQlwcmludGsoS0VSTl9FUlIgIiVzOiByZWFkX2ludHI6IGJhZCBpbnRlcnJ1cHQgcmVhc29uICV4XG4iLCBkcml2ZS0+bmFtZSwKCQkJCQkJCQlpcmVhc29uKTsKCX0KCgljZHJvbV9lbmRfcmVxdWVzdChkcml2ZSwgMCk7CglyZXR1cm4gLTE7Cn0KCi8qCiAqIEludGVycnVwdCByb3V0aW5lLiAgQ2FsbGVkIHdoZW4gYSByZWFkIHJlcXVlc3QgaGFzIGNvbXBsZXRlZC4KICovCnN0YXRpYyBpZGVfc3RhcnRzdG9wX3QgY2Ryb21fcmVhZF9pbnRyIChpZGVfZHJpdmVfdCAqZHJpdmUpCnsKCWludCBzdGF0OwoJaW50IGlyZWFzb24sIGxlbiwgc2VjdG9yc190b190cmFuc2ZlciwgbnNraXA7CglzdHJ1Y3QgY2Ryb21faW5mbyAqaW5mbyA9IGRyaXZlLT5kcml2ZXJfZGF0YTsKCXU4IGxvd2N5bCA9IDAsIGhpZ2hjeWwgPSAwOwoJaW50IGRtYSA9IGluZm8tPmRtYSwgZG1hX2Vycm9yID0gMDsKCglzdHJ1Y3QgcmVxdWVzdCAqcnEgPSBIV0dST1VQKGRyaXZlKS0+cnE7CgoJLyoKCSAqIGhhbmRsZSBkbWEgY2FzZQoJICovCglpZiAoZG1hKSB7CgkJaW5mby0+ZG1hID0gMDsKCQlpZiAoKGRtYV9lcnJvciA9IEhXSUYoZHJpdmUpLT5pZGVfZG1hX2VuZChkcml2ZSkpKQoJCQlfX2lkZV9kbWFfb2ZmKGRyaXZlKTsKCX0KCglpZiAoY2Ryb21fZGVjb2RlX3N0YXR1cyhkcml2ZSwgMCwgJnN0YXQpKQoJCXJldHVybiBpZGVfc3RvcHBlZDsKCglpZiAoZG1hKSB7CgkJaWYgKCFkbWFfZXJyb3IpIHsKCQkJaWRlX2VuZF9yZXF1ZXN0KGRyaXZlLCAxLCBycS0+bnJfc2VjdG9ycyk7CgkJCXJldHVybiBpZGVfc3RvcHBlZDsKCQl9IGVsc2UKCQkJcmV0dXJuIGlkZV9lcnJvcihkcml2ZSwgImRtYSBlcnJvciIsIHN0YXQpOwoJfQoKCS8qIFJlYWQgdGhlIGludGVycnVwdCByZWFzb24gYW5kIHRoZSB0cmFuc2ZlciBsZW5ndGguICovCglpcmVhc29uID0gSFdJRihkcml2ZSktPklOQihJREVfSVJFQVNPTl9SRUcpICYgMHgzOwoJbG93Y3lsICA9IEhXSUYoZHJpdmUpLT5JTkIoSURFX0JDT1VOVExfUkVHKTsKCWhpZ2hjeWwgPSBIV0lGKGRyaXZlKS0+SU5CKElERV9CQ09VTlRIX1JFRyk7CgoJbGVuID0gbG93Y3lsICsgKDI1NiAqIGhpZ2hjeWwpOwoKCS8qIElmIERSUSBpcyBjbGVhciwgdGhlIGNvbW1hbmQgaGFzIGNvbXBsZXRlZC4gKi8KCWlmICgoc3RhdCAmIERSUV9TVEFUKSA9PSAwKSB7CgkJLyogSWYgd2UncmUgbm90IGRvbmUgZmlsbGluZyB0aGUgY3VycmVudCBidWZmZXIsIGNvbXBsYWluLgoJCSAgIE90aGVyd2lzZSwgY29tcGxldGUgdGhlIGNvbW1hbmQgbm9ybWFsbHkuICovCgkJaWYgKHJxLT5jdXJyZW50X25yX3NlY3RvcnMgPiAwKSB7CgkJCXByaW50ayAoS0VSTl9FUlIgIiVzOiBjZHJvbV9yZWFkX2ludHI6IGRhdGEgdW5kZXJydW4gKCVkIGJsb2NrcylcbiIsCgkJCQlkcml2ZS0+bmFtZSwgcnEtPmN1cnJlbnRfbnJfc2VjdG9ycyk7CgkJCXJxLT5jbWRfZmxhZ3MgfD0gUkVRX0ZBSUxFRDsKCQkJY2Ryb21fZW5kX3JlcXVlc3QoZHJpdmUsIDApOwoJCX0gZWxzZQoJCQljZHJvbV9lbmRfcmVxdWVzdChkcml2ZSwgMSk7CgkJcmV0dXJuIGlkZV9zdG9wcGVkOwoJfQoKCS8qIENoZWNrIHRoYXQgdGhlIGRyaXZlIGlzIGV4cGVjdGluZyB0byBkbyB0aGUgc2FtZSB0aGluZyB3ZSBhcmUuICovCglpZiAoY2Ryb21fcmVhZF9jaGVja19pcmVhc29uIChkcml2ZSwgbGVuLCBpcmVhc29uKSkKCQlyZXR1cm4gaWRlX3N0b3BwZWQ7CgoJLyogQXNzdW1lIHRoYXQgdGhlIGRyaXZlIHdpbGwgYWx3YXlzIHByb3ZpZGUgZGF0YSBpbiBtdWx0aXBsZXMKCSAgIG9mIGF0IGxlYXN0IFNFQ1RPUl9TSVpFLCBhcyBpdCBnZXRzIGhhaXJ5IHRvIGtlZXAgdHJhY2sKCSAgIG9mIHRoZSB0cmFuc2ZlcnMgb3RoZXJ3aXNlLiAqLwoJaWYgKChsZW4gJSBTRUNUT1JfU0laRSkgIT0gMCkgewoJCXByaW50ayAoS0VSTl9FUlIgIiVzOiBjZHJvbV9yZWFkX2ludHI6IEJhZCB0cmFuc2ZlciBzaXplICVkXG4iLAoJCQlkcml2ZS0+bmFtZSwgbGVuKTsKCQlpZiAoQ0RST01fQ09ORklHX0ZMQUdTKGRyaXZlKS0+bGltaXRfbmZyYW1lcykKCQkJcHJpbnRrIChLRVJOX0VSUiAiICBUaGlzIGRyaXZlIGlzIG5vdCBzdXBwb3J0ZWQgYnkgdGhpcyB2ZXJzaW9uIG9mIHRoZSBkcml2ZXJcbiIpOwoJCWVsc2UgewoJCQlwcmludGsgKEtFUk5fRVJSICIgIFRyeWluZyB0byBsaW1pdCB0cmFuc2ZlciBzaXplc1xuIik7CgkJCUNEUk9NX0NPTkZJR19GTEFHUyhkcml2ZSktPmxpbWl0X25mcmFtZXMgPSAxOwoJCX0KCQljZHJvbV9lbmRfcmVxdWVzdChkcml2ZSwgMCk7CgkJcmV0dXJuIGlkZV9zdG9wcGVkOwoJfQoKCS8qIFRoZSBudW1iZXIgb2Ygc2VjdG9ycyB3ZSBuZWVkIHRvIHJlYWQgZnJvbSB0aGUgZHJpdmUuICovCglzZWN0b3JzX3RvX3RyYW5zZmVyID0gbGVuIC8gU0VDVE9SX1NJWkU7CgoJLyogRmlyc3QsIGZpZ3VyZSBvdXQgaWYgd2UgbmVlZCB0byBiaXQtYnVja2V0CgkgICBhbnkgb2YgdGhlIGxlYWRpbmcgc2VjdG9ycy4gKi8KCW5za2lwID0gbWluX3QoaW50LCBycS0+Y3VycmVudF9ucl9zZWN0b3JzIC0gYmlvX2N1cl9zZWN0b3JzKHJxLT5iaW8pLCBzZWN0b3JzX3RvX3RyYW5zZmVyKTsKCgl3aGlsZSAobnNraXAgPiAwKSB7CgkJLyogV2UgbmVlZCB0byB0aHJvdyBhd2F5IGEgc2VjdG9yLiAqLwoJCXN0YXRpYyBjaGFyIGR1bVtTRUNUT1JfU0laRV07CgkJSFdJRihkcml2ZSktPmF0YXBpX2lucHV0X2J5dGVzKGRyaXZlLCBkdW0sIHNpemVvZiAoZHVtKSk7CgoJCS0tcnEtPmN1cnJlbnRfbnJfc2VjdG9yczsKCQktLW5za2lwOwoJCS0tc2VjdG9yc190b190cmFuc2ZlcjsKCX0KCgkvKiBOb3cgbG9vcCB3aGlsZSB3ZSBzdGlsbCBoYXZlIGRhdGEgdG8gcmVhZCBmcm9tIHRoZSBkcml2ZS4gKi8KCXdoaWxlIChzZWN0b3JzX3RvX3RyYW5zZmVyID4gMCkgewoJCWludCB0aGlzX3RyYW5zZmVyOwoKCQkvKiBJZiB3ZSd2ZSBmaWxsZWQgdGhlIHByZXNlbnQgYnVmZmVyIGJ1dCB0aGVyZSdzIGFub3RoZXIKCQkgICBjaGFpbmVkIGJ1ZmZlciBhZnRlciBpdCwgbW92ZSBvbi4gKi8KCQlpZiAocnEtPmN1cnJlbnRfbnJfc2VjdG9ycyA9PSAwICYmIHJxLT5ucl9zZWN0b3JzKQoJCQljZHJvbV9lbmRfcmVxdWVzdChkcml2ZSwgMSk7CgoJCS8qIElmIHRoZSBidWZmZXJzIGFyZSBmdWxsLCBjYWNoZSB0aGUgcmVzdCBvZiB0aGUgZGF0YSBpbiBvdXIKCQkgICBpbnRlcm5hbCBidWZmZXIuICovCgkJaWYgKHJxLT5jdXJyZW50X25yX3NlY3RvcnMgPT0gMCkgewoJCQljZHJvbV9idWZmZXJfc2VjdG9ycyhkcml2ZSwgcnEtPnNlY3Rvciwgc2VjdG9yc190b190cmFuc2Zlcik7CgkJCXNlY3RvcnNfdG9fdHJhbnNmZXIgPSAwOwoJCX0gZWxzZSB7CgkJCS8qIFRyYW5zZmVyIGRhdGEgdG8gdGhlIGJ1ZmZlcnMuCgkJCSAgIEZpZ3VyZSBvdXQgaG93IG1hbnkgc2VjdG9ycyB3ZSBjYW4gdHJhbnNmZXIKCQkJICAgdG8gdGhlIGN1cnJlbnQgYnVmZmVyLiAqLwoJCQl0aGlzX3RyYW5zZmVyID0gbWluX3QoaW50LCBzZWN0b3JzX3RvX3RyYW5zZmVyLAoJCQkJCSAgICAgcnEtPmN1cnJlbnRfbnJfc2VjdG9ycyk7CgoJCQkvKiBSZWFkIHRoaXNfdHJhbnNmZXIgc2VjdG9ycwoJCQkgICBpbnRvIHRoZSBjdXJyZW50IGJ1ZmZlci4gKi8KCQkJd2hpbGUgKHRoaXNfdHJhbnNmZXIgPiAwKSB7CgkJCQlIV0lGKGRyaXZlKS0+YXRhcGlfaW5wdXRfYnl0ZXMoZHJpdmUsIHJxLT5idWZmZXIsIFNFQ1RPUl9TSVpFKTsKCQkJCXJxLT5idWZmZXIgKz0gU0VDVE9SX1NJWkU7CgkJCQktLXJxLT5ucl9zZWN0b3JzOwoJCQkJLS1ycS0+Y3VycmVudF9ucl9zZWN0b3JzOwoJCQkJKytycS0+c2VjdG9yOwoJCQkJLS10aGlzX3RyYW5zZmVyOwoJCQkJLS1zZWN0b3JzX3RvX3RyYW5zZmVyOwoJCQl9CgkJfQoJfQoKCS8qIERvbmUgbW92aW5nIGRhdGEhICBXYWl0IGZvciBhbm90aGVyIGludGVycnVwdC4gKi8KCWlkZV9zZXRfaGFuZGxlcihkcml2ZSwgJmNkcm9tX3JlYWRfaW50ciwgQVRBUElfV0FJVF9QQywgTlVMTCk7CglyZXR1cm4gaWRlX3N0YXJ0ZWQ7Cn0KCi8qCiAqIFRyeSB0byBzYXRpc2Z5IHNvbWUgb2YgdGhlIGN1cnJlbnQgcmVhZCByZXF1ZXN0IGZyb20gb3VyIGNhY2hlZCBkYXRhLgogKiBSZXR1cm5zIG5vbnplcm8gaWYgdGhlIHJlcXVlc3QgaGFzIGJlZW4gY29tcGxldGVkLCB6ZXJvIG90aGVyd2lzZS4KICovCnN0YXRpYyBpbnQgY2Ryb21fcmVhZF9mcm9tX2J1ZmZlciAoaWRlX2RyaXZlX3QgKmRyaXZlKQp7CglzdHJ1Y3QgY2Ryb21faW5mbyAqaW5mbyA9IGRyaXZlLT5kcml2ZXJfZGF0YTsKCXN0cnVjdCByZXF1ZXN0ICpycSA9IEhXR1JPVVAoZHJpdmUpLT5ycTsKCXVuc2lnbmVkIHNob3J0IHNlY3RvcnNfcGVyX2ZyYW1lOwoKCXNlY3RvcnNfcGVyX2ZyYW1lID0gcXVldWVfaGFyZHNlY3Rfc2l6ZShkcml2ZS0+cXVldWUpID4+IFNFQ1RPUl9CSVRTOwoKCS8qIENhbid0IGRvIGFueXRoaW5nIGlmIHRoZXJlJ3Mgbm8gYnVmZmVyLiAqLwoJaWYgKGluZm8tPmJ1ZmZlciA9PSBOVUxMKSByZXR1cm4gMDsKCgkvKiBMb29wIHdoaWxlIHRoaXMgcmVxdWVzdCBuZWVkcyBkYXRhIGFuZCB0aGUgbmV4dCBibG9jayBpcyBwcmVzZW50CgkgICBpbiBvdXIgY2FjaGUuICovCgl3aGlsZSAocnEtPm5yX3NlY3RvcnMgPiAwICYmCgkgICAgICAgcnEtPnNlY3RvciA+PSBpbmZvLT5zZWN0b3JfYnVmZmVyZWQgJiYKCSAgICAgICBycS0+c2VjdG9yIDwgaW5mby0+c2VjdG9yX2J1ZmZlcmVkICsgaW5mby0+bnNlY3RvcnNfYnVmZmVyZWQpIHsKCQlpZiAocnEtPmN1cnJlbnRfbnJfc2VjdG9ycyA9PSAwKQoJCQljZHJvbV9lbmRfcmVxdWVzdChkcml2ZSwgMSk7CgoJCW1lbWNweSAocnEtPmJ1ZmZlciwKCQkJaW5mby0+YnVmZmVyICsKCQkJKHJxLT5zZWN0b3IgLSBpbmZvLT5zZWN0b3JfYnVmZmVyZWQpICogU0VDVE9SX1NJWkUsCgkJCVNFQ1RPUl9TSVpFKTsKCQlycS0+YnVmZmVyICs9IFNFQ1RPUl9TSVpFOwoJCS0tcnEtPmN1cnJlbnRfbnJfc2VjdG9yczsKCQktLXJxLT5ucl9zZWN0b3JzOwoJCSsrcnEtPnNlY3RvcjsKCX0KCgkvKiBJZiB3ZSd2ZSBzYXRpc2ZpZWQgdGhlIGN1cnJlbnQgcmVxdWVzdCwKCSAgIHRlcm1pbmF0ZSBpdCBzdWNjZXNzZnVsbHkuICovCglpZiAocnEtPm5yX3NlY3RvcnMgPT0gMCkgewoJCWNkcm9tX2VuZF9yZXF1ZXN0KGRyaXZlLCAxKTsKCQlyZXR1cm4gLTE7Cgl9CgoJLyogTW92ZSBvbiB0byB0aGUgbmV4dCBidWZmZXIgaWYgbmVlZGVkLiAqLwoJaWYgKHJxLT5jdXJyZW50X25yX3NlY3RvcnMgPT0gMCkKCQljZHJvbV9lbmRfcmVxdWVzdChkcml2ZSwgMSk7CgoJLyogSWYgdGhpcyBjb25kaXRpb24gZG9lcyBub3QgaG9sZCwgdGhlbiB0aGUga2x1Z2UgaSB1c2UgdG8KCSAgIHJlcHJlc2VudCB0aGUgbnVtYmVyIG9mIHNlY3RvcnMgdG8gc2tpcCBhdCB0aGUgc3RhcnQgb2YgYSB0cmFuc2ZlcgoJICAgd2lsbCBmYWlsLiAgSSB0aGluayB0aGF0IHRoaXMgd2lsbCBuZXZlciBoYXBwZW4sIGJ1dCBsZXQncyBiZQoJICAgcGFyYW5vaWQgYW5kIGNoZWNrLiAqLwoJaWYgKHJxLT5jdXJyZW50X25yX3NlY3RvcnMgPCBiaW9fY3VyX3NlY3RvcnMocnEtPmJpbykgJiYKCSAgICAocnEtPnNlY3RvciAmIChzZWN0b3JzX3Blcl9mcmFtZSAtIDEpKSkgewoJCXByaW50ayhLRVJOX0VSUiAiJXM6IGNkcm9tX3JlYWRfZnJvbV9idWZmZXI6IGJ1ZmZlciBib3RjaCAoJWxkKVxuIiwKCQkJZHJpdmUtPm5hbWUsIChsb25nKXJxLT5zZWN0b3IpOwoJCWNkcm9tX2VuZF9yZXF1ZXN0KGRyaXZlLCAwKTsKCQlyZXR1cm4gLTE7Cgl9CgoJcmV0dXJuIDA7Cn0KCi8qCiAqIFJvdXRpbmUgdG8gc2VuZCBhIHJlYWQgcGFja2V0IGNvbW1hbmQgdG8gdGhlIGRyaXZlLgogKiBUaGlzIGlzIHVzdWFsbHkgY2FsbGVkIGRpcmVjdGx5IGZyb20gY2Ryb21fc3RhcnRfcmVhZC4KICogSG93ZXZlciwgZm9yIGRycV9pbnRlcnJ1cHQgZGV2aWNlcywgaXQgaXMgY2FsbGVkIGZyb20gYW4gaW50ZXJydXB0CiAqIHdoZW4gdGhlIGRyaXZlIGlzIHJlYWR5IHRvIGFjY2VwdCB0aGUgY29tbWFuZC4KICovCnN0YXRpYyBpZGVfc3RhcnRzdG9wX3QgY2Ryb21fc3RhcnRfcmVhZF9jb250aW51YXRpb24gKGlkZV9kcml2ZV90ICpkcml2ZSkKewoJc3RydWN0IHJlcXVlc3QgKnJxID0gSFdHUk9VUChkcml2ZSktPnJxOwoJdW5zaWduZWQgc2hvcnQgc2VjdG9yc19wZXJfZnJhbWU7CglpbnQgbnNraXA7CgoJc2VjdG9yc19wZXJfZnJhbWUgPSBxdWV1ZV9oYXJkc2VjdF9zaXplKGRyaXZlLT5xdWV1ZSkgPj4gU0VDVE9SX0JJVFM7CgoJLyogSWYgdGhlIHJlcXVlc3RlZCBzZWN0b3IgZG9lc24ndCBzdGFydCBvbiBhIGNkcm9tIGJsb2NrIGJvdW5kYXJ5LAoJICAgd2UgbXVzdCBhZGp1c3QgdGhlIHN0YXJ0IG9mIHRoZSB0cmFuc2ZlciBzbyB0aGF0IGl0IGRvZXMsCgkgICBhbmQgcmVtZW1iZXIgdG8gc2tpcCB0aGUgZmlyc3QgZmV3IHNlY3RvcnMuCgkgICBJZiB0aGUgQ1VSUkVOVF9OUl9TRUNUT1JTIGZpZWxkIGlzIGxhcmdlciB0aGFuIHRoZSBzaXplCgkgICBvZiB0aGUgYnVmZmVyLCBpdCB3aWxsIG1lYW4gdGhhdCB3ZSdyZSB0byBza2lwIGEgbnVtYmVyCgkgICBvZiBzZWN0b3JzIGVxdWFsIHRvIHRoZSBhbW91bnQgYnkgd2hpY2ggQ1VSUkVOVF9OUl9TRUNUT1JTCgkgICBpcyBsYXJnZXIgdGhhbiB0aGUgYnVmZmVyIHNpemUuICovCgluc2tpcCA9IHJxLT5zZWN0b3IgJiAoc2VjdG9yc19wZXJfZnJhbWUgLSAxKTsKCWlmIChuc2tpcCA+IDApIHsKCQkvKiBTYW5pdHkgY2hlY2suLi4gKi8KCQlpZiAocnEtPmN1cnJlbnRfbnJfc2VjdG9ycyAhPSBiaW9fY3VyX3NlY3RvcnMocnEtPmJpbykgJiYKCQkJKHJxLT5zZWN0b3IgJiAoc2VjdG9yc19wZXJfZnJhbWUgLSAxKSkpIHsKCQkJcHJpbnRrKEtFUk5fRVJSICIlczogY2Ryb21fc3RhcnRfcmVhZF9jb250aW51YXRpb246IGJ1ZmZlciBib3RjaCAoJXUpXG4iLAoJCQkJZHJpdmUtPm5hbWUsIHJxLT5jdXJyZW50X25yX3NlY3RvcnMpOwoJCQljZHJvbV9lbmRfcmVxdWVzdChkcml2ZSwgMCk7CgkJCXJldHVybiBpZGVfc3RvcHBlZDsKCQl9CgkJcnEtPmN1cnJlbnRfbnJfc2VjdG9ycyArPSBuc2tpcDsKCX0KCgkvKiBTZXQgdXAgdGhlIGNvbW1hbmQgKi8KCXJxLT50aW1lb3V0ID0gQVRBUElfV0FJVF9QQzsKCgkvKiBTZW5kIHRoZSBjb21tYW5kIHRvIHRoZSBkcml2ZSBhbmQgcmV0dXJuLiAqLwoJcmV0dXJuIGNkcm9tX3RyYW5zZmVyX3BhY2tldF9jb21tYW5kKGRyaXZlLCBycSwgJmNkcm9tX3JlYWRfaW50cik7Cn0KCgojZGVmaW5lIElERUNEX1NFRUtfVEhSRVNIT0xECSgxMDAwKQkJCS8qIDEwMDAgYmxvY2tzICovCiNkZWZpbmUgSURFQ0RfU0VFS19USU1FUgkoNSAqIFdBSVRfTUlOX1NMRUVQKQkvKiAxMDAgbXMgKi8KI2RlZmluZSBJREVDRF9TRUVLX1RJTUVPVVQJKDIgKiBXQUlUX0NNRCkJCS8qIDIwIHNlYyAqLwoKc3RhdGljIGlkZV9zdGFydHN0b3BfdCBjZHJvbV9zZWVrX2ludHIgKGlkZV9kcml2ZV90ICpkcml2ZSkKewoJc3RydWN0IGNkcm9tX2luZm8gKmluZm8gPSBkcml2ZS0+ZHJpdmVyX2RhdGE7CglpbnQgc3RhdDsKCXN0YXRpYyBpbnQgcmV0cnkgPSAxMDsKCglpZiAoY2Ryb21fZGVjb2RlX3N0YXR1cyhkcml2ZSwgMCwgJnN0YXQpKQoJCXJldHVybiBpZGVfc3RvcHBlZDsKCUNEUk9NX0NPTkZJR19GTEFHUyhkcml2ZSktPnNlZWtpbmcgPSAxOwoKCWlmIChyZXRyeSAmJiB0aW1lX2FmdGVyKGppZmZpZXMsIGluZm8tPnN0YXJ0X3NlZWsgKyBJREVDRF9TRUVLX1RJTUVSKSkgewoJCWlmICgtLXJldHJ5ID09IDApIHsKCQkJLyoKCQkJICogdGhpcyBjb25kaXRpb24gaXMgZmFyIHRvbyBjb21tb24sIHRvIGJvdGhlcgoJCQkgKiB1c2VycyBhYm91dCBpdAoJCQkgKi8KCQkJLyogcHJpbnRrKCIlczogZGlzYWJsZWQgRFNDIHNlZWsgb3ZlcmxhcFxuIiwgZHJpdmUtPm5hbWUpOyovIAoJCQlkcml2ZS0+ZHNjX292ZXJsYXAgPSAwOwoJCX0KCX0KCXJldHVybiBpZGVfc3RvcHBlZDsKfQoKc3RhdGljIGlkZV9zdGFydHN0b3BfdCBjZHJvbV9zdGFydF9zZWVrX2NvbnRpbnVhdGlvbiAoaWRlX2RyaXZlX3QgKmRyaXZlKQp7CglzdHJ1Y3QgcmVxdWVzdCAqcnEgPSBIV0dST1VQKGRyaXZlKS0+cnE7CglzZWN0b3JfdCBmcmFtZSA9IHJxLT5zZWN0b3I7CgoJc2VjdG9yX2RpdihmcmFtZSwgcXVldWVfaGFyZHNlY3Rfc2l6ZShkcml2ZS0+cXVldWUpID4+IFNFQ1RPUl9CSVRTKTsKCgltZW1zZXQocnEtPmNtZCwgMCwgc2l6ZW9mKHJxLT5jbWQpKTsKCXJxLT5jbWRbMF0gPSBHUENNRF9TRUVLOwoJcHV0X3VuYWxpZ25lZChjcHVfdG9fYmUzMihmcmFtZSksICh1bnNpZ25lZCBpbnQgKikgJnJxLT5jbWRbMl0pOwoKCXJxLT50aW1lb3V0ID0gQVRBUElfV0FJVF9QQzsKCXJldHVybiBjZHJvbV90cmFuc2Zlcl9wYWNrZXRfY29tbWFuZChkcml2ZSwgcnEsICZjZHJvbV9zZWVrX2ludHIpOwp9CgpzdGF0aWMgaWRlX3N0YXJ0c3RvcF90IGNkcm9tX3N0YXJ0X3NlZWsgKGlkZV9kcml2ZV90ICpkcml2ZSwgdW5zaWduZWQgaW50IGJsb2NrKQp7CglzdHJ1Y3QgY2Ryb21faW5mbyAqaW5mbyA9IGRyaXZlLT5kcml2ZXJfZGF0YTsKCglpbmZvLT5kbWEgPSAwOwoJaW5mby0+c3RhcnRfc2VlayA9IGppZmZpZXM7CglyZXR1cm4gY2Ryb21fc3RhcnRfcGFja2V0X2NvbW1hbmQoZHJpdmUsIDAsIGNkcm9tX3N0YXJ0X3NlZWtfY29udGludWF0aW9uKTsKfQoKLyogRml4IHVwIGEgcG9zc2libHkgcGFydGlhbGx5LXByb2Nlc3NlZCByZXF1ZXN0IHNvIHRoYXQgd2UgY2FuCiAgIHN0YXJ0IGl0IG92ZXIgZW50aXJlbHksIG9yIGV2ZW4gcHV0IGl0IGJhY2sgb24gdGhlIHJlcXVlc3QgcXVldWUuICovCnN0YXRpYyB2b2lkIHJlc3RvcmVfcmVxdWVzdCAoc3RydWN0IHJlcXVlc3QgKnJxKQp7CglpZiAocnEtPmJ1ZmZlciAhPSBiaW9fZGF0YShycS0+YmlvKSkgewoJCXNlY3Rvcl90IG4gPSAocnEtPmJ1ZmZlciAtIChjaGFyICopIGJpb19kYXRhKHJxLT5iaW8pKSAvIFNFQ1RPUl9TSVpFOwoKCQlycS0+YnVmZmVyID0gYmlvX2RhdGEocnEtPmJpbyk7CgkJcnEtPm5yX3NlY3RvcnMgKz0gbjsKCQlycS0+c2VjdG9yIC09IG47Cgl9CglycS0+aGFyZF9jdXJfc2VjdG9ycyA9IHJxLT5jdXJyZW50X25yX3NlY3RvcnMgPSBiaW9fY3VyX3NlY3RvcnMocnEtPmJpbyk7CglycS0+aGFyZF9ucl9zZWN0b3JzID0gcnEtPm5yX3NlY3RvcnM7CglycS0+aGFyZF9zZWN0b3IgPSBycS0+c2VjdG9yOwoJcnEtPnEtPnByZXBfcnFfZm4ocnEtPnEsIHJxKTsKfQoKLyoKICogU3RhcnQgYSByZWFkIHJlcXVlc3QgZnJvbSB0aGUgQ0QtUk9NLgogKi8Kc3RhdGljIGlkZV9zdGFydHN0b3BfdCBjZHJvbV9zdGFydF9yZWFkIChpZGVfZHJpdmVfdCAqZHJpdmUsIHVuc2lnbmVkIGludCBibG9jaykKewoJc3RydWN0IGNkcm9tX2luZm8gKmluZm8gPSBkcml2ZS0+ZHJpdmVyX2RhdGE7CglzdHJ1Y3QgcmVxdWVzdCAqcnEgPSBIV0dST1VQKGRyaXZlKS0+cnE7Cgl1bnNpZ25lZCBzaG9ydCBzZWN0b3JzX3Blcl9mcmFtZTsKCglzZWN0b3JzX3Blcl9mcmFtZSA9IHF1ZXVlX2hhcmRzZWN0X3NpemUoZHJpdmUtPnF1ZXVlKSA+PiBTRUNUT1JfQklUUzsKCgkvKiBXZSBtYXkgYmUgcmV0cnlpbmcgdGhpcyByZXF1ZXN0IGFmdGVyIGFuIGVycm9yLiAgRml4IHVwCgkgICBhbnkgd2VpcmRuZXNzIHdoaWNoIG1pZ2h0IGJlIHByZXNlbnQgaW4gdGhlIHJlcXVlc3QgcGFja2V0LiAqLwoJcmVzdG9yZV9yZXF1ZXN0KHJxKTsKCgkvKiBTYXRpc2Z5IHdoYXRldmVyIHdlIGNhbiBvZiB0aGlzIHJlcXVlc3QgZnJvbSBvdXIgY2FjaGVkIHNlY3Rvci4gKi8KCWlmIChjZHJvbV9yZWFkX2Zyb21fYnVmZmVyKGRyaXZlKSkKCQlyZXR1cm4gaWRlX3N0b3BwZWQ7CgoJLyogQ2xlYXIgdGhlIGxvY2FsIHNlY3RvciBidWZmZXIuICovCglpbmZvLT5uc2VjdG9yc19idWZmZXJlZCA9IDA7CgoJLyogdXNlIGRtYSwgaWYgcG9zc2libGUuICovCglpbmZvLT5kbWEgPSBkcml2ZS0+dXNpbmdfZG1hOwoJaWYgKChycS0+c2VjdG9yICYgKHNlY3RvcnNfcGVyX2ZyYW1lIC0gMSkpIHx8CgkgICAgKHJxLT5ucl9zZWN0b3JzICYgKHNlY3RvcnNfcGVyX2ZyYW1lIC0gMSkpKQoJCWluZm8tPmRtYSA9IDA7CgoJLyogU3RhcnQgc2VuZGluZyB0aGUgcmVhZCByZXF1ZXN0IHRvIHRoZSBkcml2ZS4gKi8KCXJldHVybiBjZHJvbV9zdGFydF9wYWNrZXRfY29tbWFuZChkcml2ZSwgMzI3NjgsIGNkcm9tX3N0YXJ0X3JlYWRfY29udGludWF0aW9uKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogRXhlY3V0ZSBhbGwgb3RoZXIgcGFja2V0IGNvbW1hbmRzLgogKi8KCi8qIEludGVycnVwdCByb3V0aW5lIGZvciBwYWNrZXQgY29tbWFuZCBjb21wbGV0aW9uLiAqLwpzdGF0aWMgaWRlX3N0YXJ0c3RvcF90IGNkcm9tX3BjX2ludHIgKGlkZV9kcml2ZV90ICpkcml2ZSkKewoJaW50IGlyZWFzb24sIGxlbiwgdGhpc2xlbjsKCXN0cnVjdCByZXF1ZXN0ICpycSA9IEhXR1JPVVAoZHJpdmUpLT5ycTsKCXU4IGxvd2N5bCA9IDAsIGhpZ2hjeWwgPSAwOwoJaW50IHN0YXQ7CgoJLyogQ2hlY2sgZm9yIGVycm9ycy4gKi8KCWlmIChjZHJvbV9kZWNvZGVfc3RhdHVzKGRyaXZlLCAwLCAmc3RhdCkpCgkJcmV0dXJuIGlkZV9zdG9wcGVkOwoKCS8qIFJlYWQgdGhlIGludGVycnVwdCByZWFzb24gYW5kIHRoZSB0cmFuc2ZlciBsZW5ndGguICovCglpcmVhc29uID0gSFdJRihkcml2ZSktPklOQihJREVfSVJFQVNPTl9SRUcpOwoJbG93Y3lsICA9IEhXSUYoZHJpdmUpLT5JTkIoSURFX0JDT1VOVExfUkVHKTsKCWhpZ2hjeWwgPSBIV0lGKGRyaXZlKS0+SU5CKElERV9CQ09VTlRIX1JFRyk7CgoJbGVuID0gbG93Y3lsICsgKDI1NiAqIGhpZ2hjeWwpOwoKCS8qIElmIERSUSBpcyBjbGVhciwgdGhlIGNvbW1hbmQgaGFzIGNvbXBsZXRlZC4KCSAgIENvbXBsYWluIGlmIHdlIHN0aWxsIGhhdmUgZGF0YSBsZWZ0IHRvIHRyYW5zZmVyLiAqLwoJaWYgKChzdGF0ICYgRFJRX1NUQVQpID09IDApIHsKCQkvKiBTb21lIG9mIHRoZSB0cmFpbGluZyByZXF1ZXN0IHNlbnNlIGZpZWxkcyBhcmUgb3B0aW9uYWwsIGFuZAoJCSAgIHNvbWUgZHJpdmVzIGRvbid0IHNlbmQgdGhlbS4gIFNpZ2guICovCgkJaWYgKHJxLT5jbWRbMF0gPT0gR1BDTURfUkVRVUVTVF9TRU5TRSAmJgoJCSAgICBycS0+ZGF0YV9sZW4gPiAwICYmCgkJICAgIHJxLT5kYXRhX2xlbiA8PSA1KSB7CgkJCXdoaWxlIChycS0+ZGF0YV9sZW4gPiAwKSB7CgkJCQkqKHVuc2lnbmVkIGNoYXIgKilycS0+ZGF0YSsrID0gMDsKCQkJCS0tcnEtPmRhdGFfbGVuOwoJCQl9CgkJfQoKCQlpZiAocnEtPmRhdGFfbGVuID09IDApCgkJCWNkcm9tX2VuZF9yZXF1ZXN0KGRyaXZlLCAxKTsKCQllbHNlIHsKCQkJLyogQ29tbWVudCB0aGlzIG91dCwgYmVjYXVzZSB0aGlzIGFsd2F5cyBoYXBwZW5zIAoJCQkgICByaWdodCBhZnRlciBhIHJlc2V0IG9jY3VycywgYW5kIGl0IGlzIGFubm95aW5nIHRvIAoJCQkgICBhbHdheXMgcHJpbnQgZXhwZWN0ZWQgc3R1ZmYuICAqLwoJCQkvKgoJCQlwcmludGsgKCIlczogY2Ryb21fcGNfaW50cjogZGF0YSB1bmRlcnJ1biAlZFxuIiwKCQkJCWRyaXZlLT5uYW1lLCBwYy0+YnVmbGVuKTsKCQkJKi8KCQkJcnEtPmNtZF9mbGFncyB8PSBSRVFfRkFJTEVEOwoJCQljZHJvbV9lbmRfcmVxdWVzdChkcml2ZSwgMCk7CgkJfQoJCXJldHVybiBpZGVfc3RvcHBlZDsKCX0KCgkvKiBGaWd1cmUgb3V0IGhvdyBtdWNoIGRhdGEgdG8gdHJhbnNmZXIuICovCgl0aGlzbGVuID0gcnEtPmRhdGFfbGVuOwoJaWYgKHRoaXNsZW4gPiBsZW4pIHRoaXNsZW4gPSBsZW47CgoJLyogVGhlIGRyaXZlIHdhbnRzIHRvIGJlIHdyaXR0ZW4gdG8uICovCglpZiAoKGlyZWFzb24gJiAzKSA9PSAwKSB7CgkJaWYgKCFycS0+ZGF0YSkgewoJCQlibGtfZHVtcF9ycV9mbGFncyhycSwgImNkcm9tX3BjX2ludHIsIHdyaXRlIik7CgkJCWdvdG8gY29uZnVzZWQ7CgkJfQoJCS8qIFRyYW5zZmVyIHRoZSBkYXRhLiAqLwoJCUhXSUYoZHJpdmUpLT5hdGFwaV9vdXRwdXRfYnl0ZXMoZHJpdmUsIHJxLT5kYXRhLCB0aGlzbGVuKTsKCgkJLyogSWYgd2UgaGF2ZW4ndCBtb3ZlZCBlbm91Z2ggZGF0YSB0byBzYXRpc2Z5IHRoZSBkcml2ZSwKCQkgICBhZGQgc29tZSBwYWRkaW5nLiAqLwoJCXdoaWxlIChsZW4gPiB0aGlzbGVuKSB7CgkJCWludCBkdW0gPSAwOwoJCQlIV0lGKGRyaXZlKS0+YXRhcGlfb3V0cHV0X2J5dGVzKGRyaXZlLCAmZHVtLCBzaXplb2YoZHVtKSk7CgkJCWxlbiAtPSBzaXplb2YoZHVtKTsKCQl9CgoJCS8qIEtlZXAgY291bnQgb2YgaG93IG11Y2ggZGF0YSB3ZSd2ZSBtb3ZlZC4gKi8KCQlycS0+ZGF0YSArPSB0aGlzbGVuOwoJCXJxLT5kYXRhX2xlbiAtPSB0aGlzbGVuOwoJfQoKCS8qIFNhbWUgZHJpbGwgZm9yIHJlYWRpbmcuICovCgllbHNlIGlmICgoaXJlYXNvbiAmIDMpID09IDIpIHsKCQlpZiAoIXJxLT5kYXRhKSB7CgkJCWJsa19kdW1wX3JxX2ZsYWdzKHJxLCAiY2Ryb21fcGNfaW50ciwgd3JpdGUiKTsKCQkJZ290byBjb25mdXNlZDsKCQl9CgkJLyogVHJhbnNmZXIgdGhlIGRhdGEuICovCgkJSFdJRihkcml2ZSktPmF0YXBpX2lucHV0X2J5dGVzKGRyaXZlLCBycS0+ZGF0YSwgdGhpc2xlbik7CgoJCS8qIElmIHdlIGhhdmVuJ3QgbW92ZWQgZW5vdWdoIGRhdGEgdG8gc2F0aXNmeSB0aGUgZHJpdmUsCgkJICAgYWRkIHNvbWUgcGFkZGluZy4gKi8KCQl3aGlsZSAobGVuID4gdGhpc2xlbikgewoJCQlpbnQgZHVtID0gMDsKCQkJSFdJRihkcml2ZSktPmF0YXBpX2lucHV0X2J5dGVzKGRyaXZlLCAmZHVtLCBzaXplb2YoZHVtKSk7CgkJCWxlbiAtPSBzaXplb2YoZHVtKTsKCQl9CgoJCS8qIEtlZXAgY291bnQgb2YgaG93IG11Y2ggZGF0YSB3ZSd2ZSBtb3ZlZC4gKi8KCQlycS0+ZGF0YSArPSB0aGlzbGVuOwoJCXJxLT5kYXRhX2xlbiAtPSB0aGlzbGVuOwoKCQlpZiAoYmxrX3NlbnNlX3JlcXVlc3QocnEpKQoJCQlycS0+c2Vuc2VfbGVuICs9IHRoaXNsZW47Cgl9IGVsc2Ugewpjb25mdXNlZDoKCQlwcmludGsgKEtFUk5fRVJSICIlczogY2Ryb21fcGNfaW50cjogVGhlIGRyaXZlICIKCQkJImFwcGVhcnMgY29uZnVzZWQgKGlyZWFzb24gPSAweCUwMngpLiAiCgkJCSJUcnlpbmcgdG8gcmVjb3ZlciBieSBlbmRpbmcgcmVxdWVzdC5cbiIsCgkJCWRyaXZlLT5uYW1lLCBpcmVhc29uKTsKCQlycS0+Y21kX2ZsYWdzIHw9IFJFUV9GQUlMRUQ7CgkJY2Ryb21fZW5kX3JlcXVlc3QoZHJpdmUsIDApOwoJCXJldHVybiBpZGVfc3RvcHBlZDsKCX0KCgkvKiBOb3cgd2Ugd2FpdCBmb3IgYW5vdGhlciBpbnRlcnJ1cHQuICovCglpZGVfc2V0X2hhbmRsZXIoZHJpdmUsICZjZHJvbV9wY19pbnRyLCBBVEFQSV9XQUlUX1BDLCBjZHJvbV90aW1lcl9leHBpcnkpOwoJcmV0dXJuIGlkZV9zdGFydGVkOwp9CgpzdGF0aWMgaWRlX3N0YXJ0c3RvcF90IGNkcm9tX2RvX3BjX2NvbnRpbnVhdGlvbiAoaWRlX2RyaXZlX3QgKmRyaXZlKQp7CglzdHJ1Y3QgcmVxdWVzdCAqcnEgPSBIV0dST1VQKGRyaXZlKS0+cnE7CgoJaWYgKCFycS0+dGltZW91dCkKCQlycS0+dGltZW91dCA9IEFUQVBJX1dBSVRfUEM7CgoJLyogU2VuZCB0aGUgY29tbWFuZCB0byB0aGUgZHJpdmUgYW5kIHJldHVybi4gKi8KCXJldHVybiBjZHJvbV90cmFuc2Zlcl9wYWNrZXRfY29tbWFuZChkcml2ZSwgcnEsICZjZHJvbV9wY19pbnRyKTsKfQoKCnN0YXRpYyBpZGVfc3RhcnRzdG9wX3QgY2Ryb21fZG9fcGFja2V0X2NvbW1hbmQgKGlkZV9kcml2ZV90ICpkcml2ZSkKewoJaW50IGxlbjsKCXN0cnVjdCByZXF1ZXN0ICpycSA9IEhXR1JPVVAoZHJpdmUpLT5ycTsKCXN0cnVjdCBjZHJvbV9pbmZvICppbmZvID0gZHJpdmUtPmRyaXZlcl9kYXRhOwoKCWluZm8tPmRtYSA9IDA7CglycS0+Y21kX2ZsYWdzICY9IH5SRVFfRkFJTEVEOwoJbGVuID0gcnEtPmRhdGFfbGVuOwoKCS8qIFN0YXJ0IHNlbmRpbmcgdGhlIGNvbW1hbmQgdG8gdGhlIGRyaXZlLiAqLwoJcmV0dXJuIGNkcm9tX3N0YXJ0X3BhY2tldF9jb21tYW5kKGRyaXZlLCBsZW4sIGNkcm9tX2RvX3BjX2NvbnRpbnVhdGlvbik7Cn0KCgpzdGF0aWMgaW50IGNkcm9tX3F1ZXVlX3BhY2tldF9jb21tYW5kKGlkZV9kcml2ZV90ICpkcml2ZSwgc3RydWN0IHJlcXVlc3QgKnJxKQp7CglzdHJ1Y3QgcmVxdWVzdF9zZW5zZSBzZW5zZTsKCWludCByZXRyaWVzID0gMTA7Cgl1bnNpZ25lZCBpbnQgZmxhZ3MgPSBycS0+Y21kX2ZsYWdzOwoKCWlmIChycS0+c2Vuc2UgPT0gTlVMTCkKCQlycS0+c2Vuc2UgPSAmc2Vuc2U7CgoJLyogU3RhcnQgb2YgcmV0cnkgbG9vcC4gKi8KCWRvIHsKCQlpbnQgZXJyb3I7CgkJdW5zaWduZWQgbG9uZyB0aW1lID0gamlmZmllczsKCQlycS0+Y21kX2ZsYWdzID0gZmxhZ3M7CgoJCWVycm9yID0gaWRlX2RvX2RyaXZlX2NtZChkcml2ZSwgcnEsIGlkZV93YWl0KTsKCQl0aW1lID0gamlmZmllcyAtIHRpbWU7CgoJCS8qIEZJWE1FOiB3ZSBzaG91bGQgcHJvYmFibHkgYWJvcnQvcmV0cnkgb3Igc29tZXRoaW5nIAoJCSAqIGluIGNhc2Ugb2YgZmFpbHVyZSAqLwoJCWlmIChycS0+Y21kX2ZsYWdzICYgUkVRX0ZBSUxFRCkgewoJCQkvKiBUaGUgcmVxdWVzdCBmYWlsZWQuICBSZXRyeSBpZiBpdCB3YXMgZHVlIHRvIGEgdW5pdAoJCQkgICBhdHRlbnRpb24gc3RhdHVzCgkJCSAgICh1c3VhbGx5IG1lYW5zIG1lZGlhIHdhcyBjaGFuZ2VkKS4gKi8KCQkJc3RydWN0IHJlcXVlc3Rfc2Vuc2UgKnJlcWJ1ZiA9IHJxLT5zZW5zZTsKCgkJCWlmIChyZXFidWYtPnNlbnNlX2tleSA9PSBVTklUX0FUVEVOVElPTikKCQkJCWNkcm9tX3Nhd19tZWRpYV9jaGFuZ2UoZHJpdmUpOwoJCQllbHNlIGlmIChyZXFidWYtPnNlbnNlX2tleSA9PSBOT1RfUkVBRFkgJiYKCQkJCSByZXFidWYtPmFzYyA9PSA0ICYmIHJlcWJ1Zi0+YXNjcSAhPSA0KSB7CgkJCQkvKiBUaGUgZHJpdmUgaXMgaW4gdGhlIHByb2Nlc3Mgb2YgbG9hZGluZwoJCQkJICAgYSBkaXNrLiAgUmV0cnksIGJ1dCB3YWl0IGEgbGl0dGxlIHRvIGdpdmUKCQkJCSAgIHRoZSBkcml2ZSB0aW1lIHRvIGNvbXBsZXRlIHRoZSBsb2FkLiAqLwoJCQkJc3NsZWVwKDIpOwoJCQl9IGVsc2UgewoJCQkJLyogT3RoZXJ3aXNlLCBkb24ndCByZXRyeS4gKi8KCQkJCXJldHJpZXMgPSAwOwoJCQl9CgkJCS0tcmV0cmllczsKCQl9CgoJCS8qIEVuZCBvZiByZXRyeSBsb29wLiAqLwoJfSB3aGlsZSAoKHJxLT5jbWRfZmxhZ3MgJiBSRVFfRkFJTEVEKSAmJiByZXRyaWVzID49IDApOwoKCS8qIFJldHVybiBhbiBlcnJvciBpZiB0aGUgY29tbWFuZCBmYWlsZWQuICovCglyZXR1cm4gKHJxLT5jbWRfZmxhZ3MgJiBSRVFfRkFJTEVEKSA/IC1FSU8gOiAwOwp9CgovKgogKiBXcml0ZSBoYW5kbGluZwogKi8Kc3RhdGljIGludCBjZHJvbV93cml0ZV9jaGVja19pcmVhc29uKGlkZV9kcml2ZV90ICpkcml2ZSwgaW50IGxlbiwgaW50IGlyZWFzb24pCnsKCS8qIFR3byBub3RlcyBhYm91dCBJREUgaW50ZXJydXB0IHJlYXNvbiBoZXJlIC0gMCBtZWFucyB0aGF0CgkgKiB0aGUgZHJpdmUgd2FudHMgdG8gcmVjZWl2ZSBkYXRhIGZyb20gdXMsIDIgbWVhbnMgdGhhdAoJICogdGhlIGRyaXZlIGlzIGV4cGVjdGluZyB0byB0cmFuc2ZlciBkYXRhIHRvIHVzLgoJICovCglpZiAoaXJlYXNvbiA9PSAwKQoJCXJldHVybiAwOwoJZWxzZSBpZiAoaXJlYXNvbiA9PSAyKSB7CgkJLyogV2hvb3BzLi4uIFRoZSBkcml2ZSB3YW50cyB0byBzZW5kIGRhdGEuICovCgkJcHJpbnRrKEtFUk5fRVJSICIlczogd3JpdGVfaW50cjogd3JvbmcgdHJhbnNmZXIgZGlyZWN0aW9uIVxuIiwKCQkJCQkJCWRyaXZlLT5uYW1lKTsKCgkJd2hpbGUgKGxlbiA+IDApIHsKCQkJaW50IGR1bSA9IDA7CgkJCUhXSUYoZHJpdmUpLT5hdGFwaV9pbnB1dF9ieXRlcyhkcml2ZSwgJmR1bSwgc2l6ZW9mKGR1bSkpOwoJCQlsZW4gLT0gc2l6ZW9mKGR1bSk7CgkJfQoJfSBlbHNlIHsKCQkvKiBEcml2ZSB3YW50cyBhIGNvbW1hbmQgcGFja2V0LCBvciBpbnZhbGlkIGlyZWFzb24uLi4gKi8KCQlwcmludGsoS0VSTl9FUlIgIiVzOiB3cml0ZV9pbnRyOiBiYWQgaW50ZXJydXB0IHJlYXNvbiAleFxuIiwKCQkJCQkJCWRyaXZlLT5uYW1lLCBpcmVhc29uKTsKCX0KCgljZHJvbV9lbmRfcmVxdWVzdChkcml2ZSwgMCk7CglyZXR1cm4gMTsKfQoKc3RhdGljIHZvaWQgcG9zdF90cmFuc2Zvcm1fY29tbWFuZChzdHJ1Y3QgcmVxdWVzdCAqcmVxKQp7Cgl1OCAqYyA9IHJlcS0+Y21kOwoJY2hhciAqaWJ1ZjsKCglpZiAoIWJsa19wY19yZXF1ZXN0KHJlcSkpCgkJcmV0dXJuOwoKCWlmIChyZXEtPmJpbykKCQlpYnVmID0gYmlvX2RhdGEocmVxLT5iaW8pOwoJZWxzZQoJCWlidWYgPSByZXEtPmRhdGE7CgoJaWYgKCFpYnVmKQoJCXJldHVybjsKCgkvKgoJICogc2V0IGFuc2ktcmV2aXNpb24gYW5kIHJlc3BvbnNlIGRhdGEgYXMgYXRhcGkKCSAqLwoJaWYgKGNbMF0gPT0gR1BDTURfSU5RVUlSWSkgewoJCWlidWZbMl0gfD0gMjsKCQlpYnVmWzNdID0gKGlidWZbM10gJiAweGYwKSB8IDI7Cgl9Cn0KCnR5cGVkZWYgdm9pZCAoeGZlcl9mdW5jX3QpKGlkZV9kcml2ZV90ICosIHZvaWQgKiwgdTMyKTsKCi8qCiAqIGJlc3Qgd2F5IHRvIGRlYWwgd2l0aCBkbWEgdGhhdCBpcyBub3Qgc2VjdG9yIGFsaWduZWQgcmlnaHQgbm93Li4uIG5vdGUKICogdGhhdCBpbiB0aGlzIHBhdGggd2UgYXJlIG5vdCB1c2luZyAtPmRhdGEgb3IgLT5idWZmZXIgYXQgYWxsLiB0aGlzIGlycwogKiBjYW4gcmVwbGFjZSBjZHJvbV9wY19pbnRyLCBjZHJvbV9yZWFkX2ludHIsIGFuZCBjZHJvbV93cml0ZV9pbnRyIGluIHRoZQogKiBmdXR1cmUuCiAqLwpzdGF0aWMgaWRlX3N0YXJ0c3RvcF90IGNkcm9tX25ld3BjX2ludHIoaWRlX2RyaXZlX3QgKmRyaXZlKQp7CglzdHJ1Y3QgY2Ryb21faW5mbyAqaW5mbyA9IGRyaXZlLT5kcml2ZXJfZGF0YTsKCXN0cnVjdCByZXF1ZXN0ICpycSA9IEhXR1JPVVAoZHJpdmUpLT5ycTsKCWludCBkbWFfZXJyb3IsIGRtYSwgc3RhdCwgaXJlYXNvbiwgbGVuLCB0aGlzbGVuOwoJdTggbG93Y3lsLCBoaWdoY3lsOwoJeGZlcl9mdW5jX3QgKnhmZXJmdW5jOwoJdW5zaWduZWQgbG9uZyBmbGFnczsKCgkvKiBDaGVjayBmb3IgZXJyb3JzLiAqLwoJZG1hX2Vycm9yID0gMDsKCWRtYSA9IGluZm8tPmRtYTsKCWlmIChkbWEpIHsKCQlpbmZvLT5kbWEgPSAwOwoJCWRtYV9lcnJvciA9IEhXSUYoZHJpdmUpLT5pZGVfZG1hX2VuZChkcml2ZSk7Cgl9CgoJaWYgKGNkcm9tX2RlY29kZV9zdGF0dXMoZHJpdmUsIDAsICZzdGF0KSkKCQlyZXR1cm4gaWRlX3N0b3BwZWQ7CgoJLyoKCSAqIHVzaW5nIGRtYSwgdHJhbnNmZXIgaXMgY29tcGxldGUgbm93CgkgKi8KCWlmIChkbWEpIHsKCQlpZiAoZG1hX2Vycm9yKSB7CgkJCXByaW50ayhLRVJOX0VSUiAiaWRlLWNkOiBkbWEgZXJyb3JcbiIpOwoJCQlfX2lkZV9kbWFfb2ZmKGRyaXZlKTsKCQkJcmV0dXJuIGlkZV9lcnJvcihkcml2ZSwgImRtYSBlcnJvciIsIHN0YXQpOwoJCX0KCgkJZW5kX3RoYXRfcmVxdWVzdF9jaHVuayhycSwgMSwgcnEtPmRhdGFfbGVuKTsKCQlycS0+ZGF0YV9sZW4gPSAwOwoJCWdvdG8gZW5kX3JlcXVlc3Q7Cgl9CgoJLyoKCSAqIG9rIHdlIGZhbGwgdG8gcGlvIDovCgkgKi8KCWlyZWFzb24gPSBIV0lGKGRyaXZlKS0+SU5CKElERV9JUkVBU09OX1JFRykgJiAweDM7Cglsb3djeWwgID0gSFdJRihkcml2ZSktPklOQihJREVfQkNPVU5UTF9SRUcpOwoJaGlnaGN5bCA9IEhXSUYoZHJpdmUpLT5JTkIoSURFX0JDT1VOVEhfUkVHKTsKCglsZW4gPSBsb3djeWwgKyAoMjU2ICogaGlnaGN5bCk7Cgl0aGlzbGVuID0gcnEtPmRhdGFfbGVuOwoJaWYgKHRoaXNsZW4gPiBsZW4pCgkJdGhpc2xlbiA9IGxlbjsKCgkvKgoJICogSWYgRFJRIGlzIGNsZWFyLCB0aGUgY29tbWFuZCBoYXMgY29tcGxldGVkLgoJICovCglpZiAoKHN0YXQgJiBEUlFfU1RBVCkgPT0gMCkKCQlnb3RvIGVuZF9yZXF1ZXN0OwoKCS8qCgkgKiBjaGVjayB3aGljaCB3YXkgdG8gdHJhbnNmZXIgZGF0YQoJICovCglpZiAocnFfZGF0YV9kaXIocnEpID09IFdSSVRFKSB7CgkJLyoKCQkgKiB3cml0ZSB0byBkcml2ZQoJCSAqLwoJCWlmIChjZHJvbV93cml0ZV9jaGVja19pcmVhc29uKGRyaXZlLCBsZW4sIGlyZWFzb24pKQoJCQlyZXR1cm4gaWRlX3N0b3BwZWQ7CgoJCXhmZXJmdW5jID0gSFdJRihkcml2ZSktPmF0YXBpX291dHB1dF9ieXRlczsKCX0gZWxzZSAgewoJCS8qCgkJICogcmVhZCBmcm9tIGRyaXZlCgkJICovCgkJaWYgKGNkcm9tX3JlYWRfY2hlY2tfaXJlYXNvbihkcml2ZSwgbGVuLCBpcmVhc29uKSkKCQkJcmV0dXJuIGlkZV9zdG9wcGVkOwoKCQl4ZmVyZnVuYyA9IEhXSUYoZHJpdmUpLT5hdGFwaV9pbnB1dF9ieXRlczsKCX0KCgkvKgoJICogdHJhbnNmZXIgZGF0YQoJICovCgl3aGlsZSAodGhpc2xlbiA+IDApIHsKCQlpbnQgYmxlbiA9IGJsZW4gPSBycS0+ZGF0YV9sZW47CgkJY2hhciAqcHRyID0gcnEtPmRhdGE7CgoJCS8qCgkJICogYmlvIGJhY2tlZD8KCQkgKi8KCQlpZiAocnEtPmJpbykgewoJCQlwdHIgPSBiaW9fZGF0YShycS0+YmlvKTsKCQkJYmxlbiA9IGJpb19pb3ZlYyhycS0+YmlvKS0+YnZfbGVuOwoJCX0KCgkJaWYgKCFwdHIpIHsKCQkJcHJpbnRrKEtFUk5fRVJSICIlczogY29uZnVzZWQsIG1pc3NpbmcgZGF0YVxuIiwgZHJpdmUtPm5hbWUpOwoJCQlicmVhazsKCQl9CgoJCWlmIChibGVuID4gdGhpc2xlbikKCQkJYmxlbiA9IHRoaXNsZW47CgoJCXhmZXJmdW5jKGRyaXZlLCBwdHIsIGJsZW4pOwoKCQl0aGlzbGVuIC09IGJsZW47CgkJbGVuIC09IGJsZW47CgkJcnEtPmRhdGFfbGVuIC09IGJsZW47CgoJCWlmIChycS0+YmlvKQoJCQllbmRfdGhhdF9yZXF1ZXN0X2NodW5rKHJxLCAxLCBibGVuKTsKCQllbHNlCgkJCXJxLT5kYXRhICs9IGJsZW47Cgl9CgoJLyoKCSAqIHBhZCwgaWYgbmVjZXNzYXJ5CgkgKi8KCWlmIChsZW4gPiAwKSB7CgkJd2hpbGUgKGxlbiA+IDApIHsKCQkJaW50IHBhZCA9IDA7CgoJCQl4ZmVyZnVuYyhkcml2ZSwgJnBhZCwgc2l6ZW9mKHBhZCkpOwoJCQlsZW4gLT0gc2l6ZW9mKHBhZCk7CgkJfQoJfQoKCUJVR19PTihIV0dST1VQKGRyaXZlKS0+aGFuZGxlciAhPSBOVUxMKTsKCglpZGVfc2V0X2hhbmRsZXIoZHJpdmUsIGNkcm9tX25ld3BjX2ludHIsIHJxLT50aW1lb3V0LCBOVUxMKTsKCXJldHVybiBpZGVfc3RhcnRlZDsKCmVuZF9yZXF1ZXN0OgoJaWYgKCFycS0+ZGF0YV9sZW4pCgkJcG9zdF90cmFuc2Zvcm1fY29tbWFuZChycSk7CgoJc3Bpbl9sb2NrX2lycXNhdmUoJmlkZV9sb2NrLCBmbGFncyk7CglibGtkZXZfZGVxdWV1ZV9yZXF1ZXN0KHJxKTsKCWVuZF90aGF0X3JlcXVlc3RfbGFzdChycSwgMSk7CglIV0dST1VQKGRyaXZlKS0+cnEgPSBOVUxMOwoJc3Bpbl91bmxvY2tfaXJxcmVzdG9yZSgmaWRlX2xvY2ssIGZsYWdzKTsKCXJldHVybiBpZGVfc3RvcHBlZDsKfQoKc3RhdGljIGlkZV9zdGFydHN0b3BfdCBjZHJvbV93cml0ZV9pbnRyKGlkZV9kcml2ZV90ICpkcml2ZSkKewoJaW50IHN0YXQsIGlyZWFzb24sIGxlbiwgc2VjdG9yc190b190cmFuc2ZlciwgdXB0b2RhdGU7CglzdHJ1Y3QgY2Ryb21faW5mbyAqaW5mbyA9IGRyaXZlLT5kcml2ZXJfZGF0YTsKCWludCBkbWFfZXJyb3IgPSAwLCBkbWEgPSBpbmZvLT5kbWE7Cgl1OCBsb3djeWwgPSAwLCBoaWdoY3lsID0gMDsKCglzdHJ1Y3QgcmVxdWVzdCAqcnEgPSBIV0dST1VQKGRyaXZlKS0+cnE7CgoJLyogQ2hlY2sgZm9yIGVycm9ycy4gKi8KCWlmIChkbWEpIHsKCQlpbmZvLT5kbWEgPSAwOwoJCWlmICgoZG1hX2Vycm9yID0gSFdJRihkcml2ZSktPmlkZV9kbWFfZW5kKGRyaXZlKSkpIHsKCQkJcHJpbnRrKEtFUk5fRVJSICJpZGUtY2Q6IHdyaXRlIGRtYSBlcnJvclxuIik7CgkJCV9faWRlX2RtYV9vZmYoZHJpdmUpOwoJCX0KCX0KCglpZiAoY2Ryb21fZGVjb2RlX3N0YXR1cyhkcml2ZSwgMCwgJnN0YXQpKQoJCXJldHVybiBpZGVfc3RvcHBlZDsKCgkvKgoJICogdXNpbmcgZG1hLCB0cmFuc2ZlciBpcyBjb21wbGV0ZSBub3cKCSAqLwoJaWYgKGRtYSkgewoJCWlmIChkbWFfZXJyb3IpCgkJCXJldHVybiBpZGVfZXJyb3IoZHJpdmUsICJkbWEgZXJyb3IiLCBzdGF0KTsKCgkJaWRlX2VuZF9yZXF1ZXN0KGRyaXZlLCAxLCBycS0+bnJfc2VjdG9ycyk7CgkJcmV0dXJuIGlkZV9zdG9wcGVkOwoJfQoKCS8qIFJlYWQgdGhlIGludGVycnVwdCByZWFzb24gYW5kIHRoZSB0cmFuc2ZlciBsZW5ndGguICovCglpcmVhc29uID0gSFdJRihkcml2ZSktPklOQihJREVfSVJFQVNPTl9SRUcpOwoJbG93Y3lsICA9IEhXSUYoZHJpdmUpLT5JTkIoSURFX0JDT1VOVExfUkVHKTsKCWhpZ2hjeWwgPSBIV0lGKGRyaXZlKS0+SU5CKElERV9CQ09VTlRIX1JFRyk7CgoJbGVuID0gbG93Y3lsICsgKDI1NiAqIGhpZ2hjeWwpOwoKCS8qIElmIERSUSBpcyBjbGVhciwgdGhlIGNvbW1hbmQgaGFzIGNvbXBsZXRlZC4gKi8KCWlmICgoc3RhdCAmIERSUV9TVEFUKSA9PSAwKSB7CgkJLyogSWYgd2UncmUgbm90IGRvbmUgd3JpdGluZywgY29tcGxhaW4uCgkJICogT3RoZXJ3aXNlLCBjb21wbGV0ZSB0aGUgY29tbWFuZCBub3JtYWxseS4KCQkgKi8KCQl1cHRvZGF0ZSA9IDE7CgkJaWYgKHJxLT5jdXJyZW50X25yX3NlY3RvcnMgPiAwKSB7CgkJCXByaW50ayhLRVJOX0VSUiAiJXM6IHdyaXRlX2ludHI6IGRhdGEgdW5kZXJydW4gKCVkIGJsb2NrcylcbiIsCgkJCWRyaXZlLT5uYW1lLCBycS0+Y3VycmVudF9ucl9zZWN0b3JzKTsKCQkJdXB0b2RhdGUgPSAwOwoJCX0KCQljZHJvbV9lbmRfcmVxdWVzdChkcml2ZSwgdXB0b2RhdGUpOwoJCXJldHVybiBpZGVfc3RvcHBlZDsKCX0KCgkvKiBDaGVjayB0aGF0IHRoZSBkcml2ZSBpcyBleHBlY3RpbmcgdG8gZG8gdGhlIHNhbWUgdGhpbmcgd2UgYXJlLiAqLwoJaWYgKGNkcm9tX3dyaXRlX2NoZWNrX2lyZWFzb24oZHJpdmUsIGxlbiwgaXJlYXNvbikpCgkJcmV0dXJuIGlkZV9zdG9wcGVkOwoKCXNlY3RvcnNfdG9fdHJhbnNmZXIgPSBsZW4gLyBTRUNUT1JfU0laRTsKCgkvKgoJICogbm93IGxvb3AgYW5kIHdyaXRlIG91dCB0aGUgZGF0YQoJICovCgl3aGlsZSAoc2VjdG9yc190b190cmFuc2ZlciA+IDApIHsKCQlpbnQgdGhpc190cmFuc2ZlcjsKCgkJaWYgKCFycS0+Y3VycmVudF9ucl9zZWN0b3JzKSB7CgkJCXByaW50ayhLRVJOX0VSUiAiaWRlLWNkOiB3cml0ZV9pbnRyOiBvb3BzXG4iKTsKCQkJYnJlYWs7CgkJfQoKCQkvKgoJCSAqIEZpZ3VyZSBvdXQgaG93IG1hbnkgc2VjdG9ycyB3ZSBjYW4gdHJhbnNmZXIKCQkgKi8KCQl0aGlzX3RyYW5zZmVyID0gbWluX3QoaW50LCBzZWN0b3JzX3RvX3RyYW5zZmVyLCBycS0+Y3VycmVudF9ucl9zZWN0b3JzKTsKCgkJd2hpbGUgKHRoaXNfdHJhbnNmZXIgPiAwKSB7CgkJCUhXSUYoZHJpdmUpLT5hdGFwaV9vdXRwdXRfYnl0ZXMoZHJpdmUsIHJxLT5idWZmZXIsIFNFQ1RPUl9TSVpFKTsKCQkJcnEtPmJ1ZmZlciArPSBTRUNUT1JfU0laRTsKCQkJLS1ycS0+bnJfc2VjdG9yczsKCQkJLS1ycS0+Y3VycmVudF9ucl9zZWN0b3JzOwoJCQkrK3JxLT5zZWN0b3I7CgkJCS0tdGhpc190cmFuc2ZlcjsKCQkJLS1zZWN0b3JzX3RvX3RyYW5zZmVyOwoJCX0KCgkJLyoKCQkgKiBjdXJyZW50IGJ1ZmZlciBjb21wbGV0ZSwgbW92ZSBvbgoJCSAqLwoJCWlmIChycS0+Y3VycmVudF9ucl9zZWN0b3JzID09IDAgJiYgcnEtPm5yX3NlY3RvcnMpCgkJCWNkcm9tX2VuZF9yZXF1ZXN0KGRyaXZlLCAxKTsKCX0KCgkvKiByZS1hcm0gaGFuZGxlciAqLwoJaWRlX3NldF9oYW5kbGVyKGRyaXZlLCAmY2Ryb21fd3JpdGVfaW50ciwgQVRBUElfV0FJVF9QQywgTlVMTCk7CglyZXR1cm4gaWRlX3N0YXJ0ZWQ7Cn0KCnN0YXRpYyBpZGVfc3RhcnRzdG9wX3QgY2Ryb21fc3RhcnRfd3JpdGVfY29udChpZGVfZHJpdmVfdCAqZHJpdmUpCnsKCXN0cnVjdCByZXF1ZXN0ICpycSA9IEhXR1JPVVAoZHJpdmUpLT5ycTsKCiNpZiAwCS8qIHRoZSBpbW1lZGlhdGUgYml0ICovCglycS0+Y21kWzFdID0gMSA8PCAzOwojZW5kaWYKCXJxLT50aW1lb3V0ID0gQVRBUElfV0FJVF9QQzsKCglyZXR1cm4gY2Ryb21fdHJhbnNmZXJfcGFja2V0X2NvbW1hbmQoZHJpdmUsIHJxLCBjZHJvbV93cml0ZV9pbnRyKTsKfQoKc3RhdGljIGlkZV9zdGFydHN0b3BfdCBjZHJvbV9zdGFydF93cml0ZShpZGVfZHJpdmVfdCAqZHJpdmUsIHN0cnVjdCByZXF1ZXN0ICpycSkKewoJc3RydWN0IGNkcm9tX2luZm8gKmluZm8gPSBkcml2ZS0+ZHJpdmVyX2RhdGE7CglzdHJ1Y3QgZ2VuZGlzayAqZyA9IGluZm8tPmRpc2s7Cgl1bnNpZ25lZCBzaG9ydCBzZWN0b3JzX3Blcl9mcmFtZSA9IHF1ZXVlX2hhcmRzZWN0X3NpemUoZHJpdmUtPnF1ZXVlKSA+PiBTRUNUT1JfQklUUzsKCgkvKgoJICogd3JpdGVzICptdXN0KiBiZSBoYXJkd2FyZSBmcmFtZSBhbGlnbmVkCgkgKi8KCWlmICgocnEtPm5yX3NlY3RvcnMgJiAoc2VjdG9yc19wZXJfZnJhbWUgLSAxKSkgfHwKCSAgICAocnEtPnNlY3RvciAmIChzZWN0b3JzX3Blcl9mcmFtZSAtIDEpKSkgewoJCWNkcm9tX2VuZF9yZXF1ZXN0KGRyaXZlLCAwKTsKCQlyZXR1cm4gaWRlX3N0b3BwZWQ7Cgl9CgoJLyoKCSAqIGRpc2sgaGFzIGJlY29tZSB3cml0ZSBwcm90ZWN0ZWQKCSAqLwoJaWYgKGctPnBvbGljeSkgewoJCWNkcm9tX2VuZF9yZXF1ZXN0KGRyaXZlLCAwKTsKCQlyZXR1cm4gaWRlX3N0b3BwZWQ7Cgl9CgoJaW5mby0+bnNlY3RvcnNfYnVmZmVyZWQgPSAwOwoKCS8qIHVzZSBkbWEsIGlmIHBvc3NpYmxlLiB3ZSBkb24ndCBuZWVkIHRvIGNoZWNrIG1vcmUsIHNpbmNlIHdlCgkgKiBrbm93IHRoYXQgdGhlIHRyYW5zZmVyIGlzIGFsd2F5cyAoYXQgbGVhc3QhKSBmcmFtZSBhbGlnbmVkICovCglpbmZvLT5kbWEgPSBkcml2ZS0+dXNpbmdfZG1hID8gMSA6IDA7CgoJaW5mby0+ZGV2aW5mby5tZWRpYV93cml0dGVuID0gMTsKCgkvKiBTdGFydCBzZW5kaW5nIHRoZSB3cml0ZSByZXF1ZXN0IHRvIHRoZSBkcml2ZS4gKi8KCXJldHVybiBjZHJvbV9zdGFydF9wYWNrZXRfY29tbWFuZChkcml2ZSwgMzI3NjgsIGNkcm9tX3N0YXJ0X3dyaXRlX2NvbnQpOwp9CgpzdGF0aWMgaWRlX3N0YXJ0c3RvcF90IGNkcm9tX2RvX25ld3BjX2NvbnQoaWRlX2RyaXZlX3QgKmRyaXZlKQp7CglzdHJ1Y3QgcmVxdWVzdCAqcnEgPSBIV0dST1VQKGRyaXZlKS0+cnE7CgoJaWYgKCFycS0+dGltZW91dCkKCQlycS0+dGltZW91dCA9IEFUQVBJX1dBSVRfUEM7CgoJcmV0dXJuIGNkcm9tX3RyYW5zZmVyX3BhY2tldF9jb21tYW5kKGRyaXZlLCBycSwgY2Ryb21fbmV3cGNfaW50cik7Cn0KCnN0YXRpYyBpZGVfc3RhcnRzdG9wX3QgY2Ryb21fZG9fYmxvY2tfcGMoaWRlX2RyaXZlX3QgKmRyaXZlLCBzdHJ1Y3QgcmVxdWVzdCAqcnEpCnsKCXN0cnVjdCBjZHJvbV9pbmZvICppbmZvID0gZHJpdmUtPmRyaXZlcl9kYXRhOwoKCXJxLT5jbWRfZmxhZ3MgfD0gUkVRX1FVSUVUOwoKCWluZm8tPmRtYSA9IDA7CgoJLyoKCSAqIHNnIHJlcXVlc3QKCSAqLwoJaWYgKHJxLT5iaW8pIHsKCQlpbnQgbWFzayA9IGRyaXZlLT5xdWV1ZS0+ZG1hX2FsaWdubWVudDsKCQl1bnNpZ25lZCBsb25nIGFkZHIgPSAodW5zaWduZWQgbG9uZykgcGFnZV9hZGRyZXNzKGJpb19wYWdlKHJxLT5iaW8pKTsKCgkJaW5mby0+ZG1hID0gZHJpdmUtPnVzaW5nX2RtYTsKCgkJLyoKCQkgKiBjaGVjayBpZiBkbWEgaXMgc2FmZQoJCSAqCgkJICogTk9URSEgVGhlICJsZW4iIGFuZCAiYWRkciIgY2hlY2tzIHNob3VsZCBwb3NzaWJseSBoYXZlCgkJICogc2VwYXJhdGUgbWFza3MuCgkJICovCgkJaWYgKChycS0+ZGF0YV9sZW4gJiAxNSkgfHwgKGFkZHIgJiBtYXNrKSkKCQkJaW5mby0+ZG1hID0gMDsKCX0KCgkvKiBTdGFydCBzZW5kaW5nIHRoZSBjb21tYW5kIHRvIHRoZSBkcml2ZS4gKi8KCXJldHVybiBjZHJvbV9zdGFydF9wYWNrZXRfY29tbWFuZChkcml2ZSwgcnEtPmRhdGFfbGVuLCBjZHJvbV9kb19uZXdwY19jb250KTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogY2Ryb20gZHJpdmVyIHJlcXVlc3Qgcm91dGluZS4KICovCnN0YXRpYyBpZGVfc3RhcnRzdG9wX3QKaWRlX2RvX3J3X2Nkcm9tIChpZGVfZHJpdmVfdCAqZHJpdmUsIHN0cnVjdCByZXF1ZXN0ICpycSwgc2VjdG9yX3QgYmxvY2spCnsKCWlkZV9zdGFydHN0b3BfdCBhY3Rpb247CglzdHJ1Y3QgY2Ryb21faW5mbyAqaW5mbyA9IGRyaXZlLT5kcml2ZXJfZGF0YTsKCglpZiAoYmxrX2ZzX3JlcXVlc3QocnEpKSB7CgkJaWYgKENEUk9NX0NPTkZJR19GTEFHUyhkcml2ZSktPnNlZWtpbmcpIHsKCQkJdW5zaWduZWQgbG9uZyBlbGFwc2VkID0gamlmZmllcyAtIGluZm8tPnN0YXJ0X3NlZWs7CgkJCWludCBzdGF0ID0gSFdJRihkcml2ZSktPklOQihJREVfU1RBVFVTX1JFRyk7CgoJCQlpZiAoKHN0YXQgJiBTRUVLX1NUQVQpICE9IFNFRUtfU1RBVCkgewoJCQkJaWYgKGVsYXBzZWQgPCBJREVDRF9TRUVLX1RJTUVPVVQpIHsKCQkJCQlpZGVfc3RhbGxfcXVldWUoZHJpdmUsIElERUNEX1NFRUtfVElNRVIpOwoJCQkJCXJldHVybiBpZGVfc3RvcHBlZDsKCQkJCX0KCQkJCXByaW50ayAoS0VSTl9FUlIgIiVzOiBEU0MgdGltZW91dFxuIiwgZHJpdmUtPm5hbWUpOwoJCQl9CgkJCUNEUk9NX0NPTkZJR19GTEFHUyhkcml2ZSktPnNlZWtpbmcgPSAwOwoJCX0KCQlpZiAoKHJxX2RhdGFfZGlyKHJxKSA9PSBSRUFEKSAmJiBJREVfTEFSR0VfU0VFSyhpbmZvLT5sYXN0X2Jsb2NrLCBibG9jaywgSURFQ0RfU0VFS19USFJFU0hPTEQpICYmIGRyaXZlLT5kc2Nfb3ZlcmxhcCkgewoJCQlhY3Rpb24gPSBjZHJvbV9zdGFydF9zZWVrKGRyaXZlLCBibG9jayk7CgkJfSBlbHNlIHsKCQkJaWYgKHJxX2RhdGFfZGlyKHJxKSA9PSBSRUFEKQoJCQkJYWN0aW9uID0gY2Ryb21fc3RhcnRfcmVhZChkcml2ZSwgYmxvY2spOwoJCQllbHNlCgkJCQlhY3Rpb24gPSBjZHJvbV9zdGFydF93cml0ZShkcml2ZSwgcnEpOwoJCX0KCQlpbmZvLT5sYXN0X2Jsb2NrID0gYmxvY2s7CgkJcmV0dXJuIGFjdGlvbjsKCX0gZWxzZSBpZiAocnEtPmNtZF90eXBlID09IFJFUV9UWVBFX1NFTlNFIHx8CgkJICAgcnEtPmNtZF90eXBlID09IFJFUV9UWVBFX0FUQV9QQykgewoJCXJldHVybiBjZHJvbV9kb19wYWNrZXRfY29tbWFuZChkcml2ZSk7Cgl9IGVsc2UgaWYgKGJsa19wY19yZXF1ZXN0KHJxKSkgewoJCXJldHVybiBjZHJvbV9kb19ibG9ja19wYyhkcml2ZSwgcnEpOwoJfSBlbHNlIGlmIChibGtfc3BlY2lhbF9yZXF1ZXN0KHJxKSkgewoJCS8qCgkJICogcmlnaHQgbm93IHRoaXMgY2FuIG9ubHkgYmUgYSByZXNldC4uLgoJCSAqLwoJCWNkcm9tX2VuZF9yZXF1ZXN0KGRyaXZlLCAxKTsKCQlyZXR1cm4gaWRlX3N0b3BwZWQ7Cgl9CgoJYmxrX2R1bXBfcnFfZmxhZ3MocnEsICJpZGUtY2QgYmFkIGZsYWdzIik7CgljZHJvbV9lbmRfcmVxdWVzdChkcml2ZSwgMCk7CglyZXR1cm4gaWRlX3N0b3BwZWQ7Cn0KCgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSW9jdGwgaGFuZGxpbmcuCiAqCiAqIFJvdXRpbmVzIHdoaWNoIHF1ZXVlIHBhY2tldCBjb21tYW5kcyB0YWtlIGFzIGEgZmluYWwgYXJndW1lbnQgYSBwb2ludGVyCiAqIHRvIGEgcmVxdWVzdF9zZW5zZSBzdHJ1Y3QuICBJZiBleGVjdXRpb24gb2YgdGhlIGNvbW1hbmQgcmVzdWx0cwogKiBpbiBhbiBlcnJvciB3aXRoIGEgQ0hFQ0sgQ09ORElUSU9OIHN0YXR1cywgdGhpcyBzdHJ1Y3R1cmUgd2lsbCBiZSBmaWxsZWQKICogd2l0aCB0aGUgcmVzdWx0cyBvZiB0aGUgc3Vic2VxdWVudCByZXF1ZXN0IHNlbnNlIGNvbW1hbmQuICBUaGUgcG9pbnRlcgogKiBjYW4gYWxzbyBiZSBOVUxMLCBpbiB3aGljaCBjYXNlIG5vIHNlbnNlIGluZm9ybWF0aW9uIGlzIHJldHVybmVkLgogKi8KCiNpZiAhIFNUQU5EQVJEX0FUQVBJCnN0YXRpYyBpbmxpbmUKaW50IGJpbjJiY2QgKGludCB4KQp7CglyZXR1cm4gKHglMTApIHwgKCh4LzEwKSA8PCA0KTsKfQoKCnN0YXRpYyBpbmxpbmUKaW50IGJjZDJiaW4gKGludCB4KQp7CglyZXR1cm4gKHggPj4gNCkgKiAxMCArICh4ICYgMHgwZik7Cn0KCnN0YXRpYwp2b2lkIG1zZl9mcm9tX2JjZCAoc3RydWN0IGF0YXBpX21zZiAqbXNmKQp7Cgltc2YtPm1pbnV0ZSA9IGJjZDJiaW4gKG1zZi0+bWludXRlKTsKCW1zZi0+c2Vjb25kID0gYmNkMmJpbiAobXNmLT5zZWNvbmQpOwoJbXNmLT5mcmFtZSAgPSBiY2QyYmluIChtc2YtPmZyYW1lKTsKfQoKI2VuZGlmIC8qIG5vdCBTVEFOREFSRF9BVEFQSSAqLwoKCnN0YXRpYyBpbmxpbmUKdm9pZCBsYmFfdG9fbXNmIChpbnQgbGJhLCBieXRlICptLCBieXRlICpzLCBieXRlICpmKQp7CglsYmEgKz0gQ0RfTVNGX09GRlNFVDsKCWxiYSAmPSAweGZmZmZmZjsgIC8qIG5lZ2F0aXZlIGxiYXMgdXNlIG9ubHkgMjQgYml0cyAqLwoJKm0gPSBsYmEgLyAoQ0RfU0VDUyAqIENEX0ZSQU1FUyk7CglsYmEgJT0gKENEX1NFQ1MgKiBDRF9GUkFNRVMpOwoJKnMgPSBsYmEgLyBDRF9GUkFNRVM7CgkqZiA9IGxiYSAlIENEX0ZSQU1FUzsKfQoKCnN0YXRpYyBpbmxpbmUKaW50IG1zZl90b19sYmEgKGJ5dGUgbSwgYnl0ZSBzLCBieXRlIGYpCnsKCXJldHVybiAoKChtICogQ0RfU0VDUykgKyBzKSAqIENEX0ZSQU1FUyArIGYpIC0gQ0RfTVNGX09GRlNFVDsKfQoKc3RhdGljIGludCBjZHJvbV9jaGVja19zdGF0dXMoaWRlX2RyaXZlX3QgKmRyaXZlLCBzdHJ1Y3QgcmVxdWVzdF9zZW5zZSAqc2Vuc2UpCnsKCXN0cnVjdCByZXF1ZXN0IHJlcTsKCXN0cnVjdCBjZHJvbV9pbmZvICppbmZvID0gZHJpdmUtPmRyaXZlcl9kYXRhOwoJc3RydWN0IGNkcm9tX2RldmljZV9pbmZvICpjZGkgPSAmaW5mby0+ZGV2aW5mbzsKCgljZHJvbV9wcmVwYXJlX3JlcXVlc3QoZHJpdmUsICZyZXEpOwoKCXJlcS5zZW5zZSA9IHNlbnNlOwoJcmVxLmNtZFswXSA9IEdQQ01EX1RFU1RfVU5JVF9SRUFEWTsKCXJlcS5jbWRfZmxhZ3MgfD0gUkVRX1FVSUVUOwoKI2lmICEgU1RBTkRBUkRfQVRBUEkKICAgICAgICAvKiB0aGUgU2FueW8gMyBDRCBjaGFuZ2VyIHVzZXMgYnl0ZSA3IG9mIFRFU1RfVU5JVF9SRUFEWSB0byAKICAgICAgICAgICBzd2l0Y2ggQ0RzIGluc3RlYWQgb2Ygc3VwcG9ydGluZyB0aGUgTE9BRF9VTkxPQUQgb3Bjb2RlICAgKi8KCglyZXEuY21kWzddID0gY2RpLT5zYW55b19zbG90ICUgMzsKI2VuZGlmIC8qIG5vdCBTVEFOREFSRF9BVEFQSSAqLwoKCXJldHVybiBjZHJvbV9xdWV1ZV9wYWNrZXRfY29tbWFuZChkcml2ZSwgJnJlcSk7Cn0KCgovKiBMb2NrIHRoZSBkb29yIGlmIExPQ0tGTEFHIGlzIG5vbnplcm87IHVubG9jayBpdCBvdGhlcndpc2UuICovCnN0YXRpYyBpbnQKY2Ryb21fbG9ja2Rvb3IoaWRlX2RyaXZlX3QgKmRyaXZlLCBpbnQgbG9ja2ZsYWcsIHN0cnVjdCByZXF1ZXN0X3NlbnNlICpzZW5zZSkKewoJc3RydWN0IHJlcXVlc3Rfc2Vuc2UgbXlfc2Vuc2U7CglzdHJ1Y3QgcmVxdWVzdCByZXE7CglpbnQgc3RhdDsKCglpZiAoc2Vuc2UgPT0gTlVMTCkKCQlzZW5zZSA9ICZteV9zZW5zZTsKCgkvKiBJZiB0aGUgZHJpdmUgY2Fubm90IGxvY2sgdGhlIGRvb3IsIGp1c3QgcHJldGVuZC4gKi8KCWlmIChDRFJPTV9DT05GSUdfRkxBR1MoZHJpdmUpLT5ub19kb29ybG9jaykgewoJCXN0YXQgPSAwOwoJfSBlbHNlIHsKCQljZHJvbV9wcmVwYXJlX3JlcXVlc3QoZHJpdmUsICZyZXEpOwoJCXJlcS5zZW5zZSA9IHNlbnNlOwoJCXJlcS5jbWRbMF0gPSBHUENNRF9QUkVWRU5UX0FMTE9XX01FRElVTV9SRU1PVkFMOwoJCXJlcS5jbWRbNF0gPSBsb2NrZmxhZyA/IDEgOiAwOwoJCXN0YXQgPSBjZHJvbV9xdWV1ZV9wYWNrZXRfY29tbWFuZChkcml2ZSwgJnJlcSk7Cgl9CgoJLyogSWYgd2UgZ290IGFuIGlsbGVnYWwgZmllbGQgZXJyb3IsIHRoZSBkcml2ZQoJICAgcHJvYmFibHkgY2Fubm90IGxvY2sgdGhlIGRvb3IuICovCglpZiAoc3RhdCAhPSAwICYmCgkgICAgc2Vuc2UtPnNlbnNlX2tleSA9PSBJTExFR0FMX1JFUVVFU1QgJiYKCSAgICAoc2Vuc2UtPmFzYyA9PSAweDI0IHx8IHNlbnNlLT5hc2MgPT0gMHgyMCkpIHsKCQlwcmludGsgKEtFUk5fRVJSICIlczogZG9vciBsb2NraW5nIG5vdCBzdXBwb3J0ZWRcbiIsCgkJCWRyaXZlLT5uYW1lKTsKCQlDRFJPTV9DT05GSUdfRkxBR1MoZHJpdmUpLT5ub19kb29ybG9jayA9IDE7CgkJc3RhdCA9IDA7Cgl9CgkKCS8qIG5vIG1lZGl1bSwgdGhhdCdzIGFscmlnaHQuICovCglpZiAoc3RhdCAhPSAwICYmIHNlbnNlLT5zZW5zZV9rZXkgPT0gTk9UX1JFQURZICYmIHNlbnNlLT5hc2MgPT0gMHgzYSkKCQlzdGF0ID0gMDsKCglpZiAoc3RhdCA9PSAwKQoJCUNEUk9NX1NUQVRFX0ZMQUdTKGRyaXZlKS0+ZG9vcl9sb2NrZWQgPSBsb2NrZmxhZzsKCglyZXR1cm4gc3RhdDsKfQoKCi8qIEVqZWN0IHRoZSBkaXNrIGlmIEVKRUNURkxBRyBpcyAwLgogICBJZiBFSkVDVEZMQUcgaXMgMSwgdHJ5IHRvIHJlbG9hZCB0aGUgZGlzay4gKi8Kc3RhdGljIGludCBjZHJvbV9lamVjdChpZGVfZHJpdmVfdCAqZHJpdmUsIGludCBlamVjdGZsYWcsCgkJICAgICAgIHN0cnVjdCByZXF1ZXN0X3NlbnNlICpzZW5zZSkKewoJc3RydWN0IHJlcXVlc3QgcmVxOwoJY2hhciBsb2VqID0gMHgwMjsKCglpZiAoQ0RST01fQ09ORklHX0ZMQUdTKGRyaXZlKS0+bm9fZWplY3QgJiYgIWVqZWN0ZmxhZykKCQlyZXR1cm4gLUVEUklWRV9DQU5UX0RPX1RISVM7CgkKCS8qIHJlbG9hZCBmYWlscyBvbiBzb21lIGRyaXZlcywgaWYgdGhlIHRyYXkgaXMgbG9ja2VkICovCglpZiAoQ0RST01fU1RBVEVfRkxBR1MoZHJpdmUpLT5kb29yX2xvY2tlZCAmJiBlamVjdGZsYWcpCgkJcmV0dXJuIDA7CgoJY2Ryb21fcHJlcGFyZV9yZXF1ZXN0KGRyaXZlLCAmcmVxKTsKCgkvKiBvbmx5IHRlbGwgZHJpdmUgdG8gY2xvc2UgdHJheSBpZiBvcGVuLCBpZiBpdCBjYW4gZG8gdGhhdCAqLwoJaWYgKGVqZWN0ZmxhZyAmJiAhQ0RST01fQ09ORklHX0ZMQUdTKGRyaXZlKS0+Y2xvc2VfdHJheSkKCQlsb2VqID0gMDsKCglyZXEuc2Vuc2UgPSBzZW5zZTsKCXJlcS5jbWRbMF0gPSBHUENNRF9TVEFSVF9TVE9QX1VOSVQ7CglyZXEuY21kWzRdID0gbG9laiB8IChlamVjdGZsYWcgIT0gMCk7CglyZXR1cm4gY2Ryb21fcXVldWVfcGFja2V0X2NvbW1hbmQoZHJpdmUsICZyZXEpOwp9CgpzdGF0aWMgaW50IGNkcm9tX3JlYWRfY2FwYWNpdHkoaWRlX2RyaXZlX3QgKmRyaXZlLCB1bnNpZ25lZCBsb25nICpjYXBhY2l0eSwKCQkJICAgICAgIHVuc2lnbmVkIGxvbmcgKnNlY3RvcnNfcGVyX2ZyYW1lLAoJCQkgICAgICAgc3RydWN0IHJlcXVlc3Rfc2Vuc2UgKnNlbnNlKQp7CglzdHJ1Y3QgewoJCV9fdTMyIGxiYTsKCQlfX3UzMiBibG9ja2xlbjsKCX0gY2FwYnVmOwoKCWludCBzdGF0OwoJc3RydWN0IHJlcXVlc3QgcmVxOwoKCWNkcm9tX3ByZXBhcmVfcmVxdWVzdChkcml2ZSwgJnJlcSk7CgoJcmVxLnNlbnNlID0gc2Vuc2U7CglyZXEuY21kWzBdID0gR1BDTURfUkVBRF9DRFZEX0NBUEFDSVRZOwoJcmVxLmRhdGEgPSAoY2hhciAqKSZjYXBidWY7CglyZXEuZGF0YV9sZW4gPSBzaXplb2YoY2FwYnVmKTsKCXJlcS5jbWRfZmxhZ3MgfD0gUkVRX1FVSUVUOwoKCXN0YXQgPSBjZHJvbV9xdWV1ZV9wYWNrZXRfY29tbWFuZChkcml2ZSwgJnJlcSk7CglpZiAoc3RhdCA9PSAwKSB7CgkJKmNhcGFjaXR5ID0gMSArIGJlMzJfdG9fY3B1KGNhcGJ1Zi5sYmEpOwoJCSpzZWN0b3JzX3Blcl9mcmFtZSA9CgkJCWJlMzJfdG9fY3B1KGNhcGJ1Zi5ibG9ja2xlbikgPj4gU0VDVE9SX0JJVFM7Cgl9CgoJcmV0dXJuIHN0YXQ7Cn0KCnN0YXRpYyBpbnQgY2Ryb21fcmVhZF90b2NlbnRyeShpZGVfZHJpdmVfdCAqZHJpdmUsIGludCB0cmFja25vLCBpbnQgbXNmX2ZsYWcsCgkJCQlpbnQgZm9ybWF0LCBjaGFyICpidWYsIGludCBidWZsZW4sCgkJCQlzdHJ1Y3QgcmVxdWVzdF9zZW5zZSAqc2Vuc2UpCnsKCXN0cnVjdCByZXF1ZXN0IHJlcTsKCgljZHJvbV9wcmVwYXJlX3JlcXVlc3QoZHJpdmUsICZyZXEpOwoKCXJlcS5zZW5zZSA9IHNlbnNlOwoJcmVxLmRhdGEgPSAgYnVmOwoJcmVxLmRhdGFfbGVuID0gYnVmbGVuOwoJcmVxLmNtZF9mbGFncyB8PSBSRVFfUVVJRVQ7CglyZXEuY21kWzBdID0gR1BDTURfUkVBRF9UT0NfUE1BX0FUSVA7CglyZXEuY21kWzZdID0gdHJhY2tubzsKCXJlcS5jbWRbN10gPSAoYnVmbGVuID4+IDgpOwoJcmVxLmNtZFs4XSA9IChidWZsZW4gJiAweGZmKTsKCXJlcS5jbWRbOV0gPSAoZm9ybWF0IDw8IDYpOwoKCWlmIChtc2ZfZmxhZykKCQlyZXEuY21kWzFdID0gMjsKCglyZXR1cm4gY2Ryb21fcXVldWVfcGFja2V0X2NvbW1hbmQoZHJpdmUsICZyZXEpOwp9CgoKLyogVHJ5IHRvIHJlYWQgdGhlIGVudGlyZSBUT0MgZm9yIHRoZSBkaXNrIGludG8gb3VyIGludGVybmFsIGJ1ZmZlci4gKi8Kc3RhdGljIGludCBjZHJvbV9yZWFkX3RvYyhpZGVfZHJpdmVfdCAqZHJpdmUsIHN0cnVjdCByZXF1ZXN0X3NlbnNlICpzZW5zZSkKewoJaW50IHN0YXQsIG50cmFja3MsIGk7CglzdHJ1Y3QgY2Ryb21faW5mbyAqaW5mbyA9IGRyaXZlLT5kcml2ZXJfZGF0YTsKCXN0cnVjdCBjZHJvbV9kZXZpY2VfaW5mbyAqY2RpID0gJmluZm8tPmRldmluZm87CglzdHJ1Y3QgYXRhcGlfdG9jICp0b2MgPSBpbmZvLT50b2M7CglzdHJ1Y3QgewoJCXN0cnVjdCBhdGFwaV90b2NfaGVhZGVyIGhkcjsKCQlzdHJ1Y3QgYXRhcGlfdG9jX2VudHJ5ICBlbnQ7Cgl9IG1zX3RtcDsKCWxvbmcgbGFzdF93cml0dGVuOwoJdW5zaWduZWQgbG9uZyBzZWN0b3JzX3Blcl9mcmFtZSA9IFNFQ1RPUlNfUEVSX0ZSQU1FOwoKCWlmICh0b2MgPT0gTlVMTCkgewoJCS8qIFRyeSB0byBhbGxvY2F0ZSBzcGFjZS4gKi8KCQl0b2MgPSBrbWFsbG9jKHNpemVvZihzdHJ1Y3QgYXRhcGlfdG9jKSwgR0ZQX0tFUk5FTCk7CgkJaWYgKHRvYyA9PSBOVUxMKSB7CgkJCXByaW50ayAoS0VSTl9FUlIgIiVzOiBObyBjZHJvbSBUT0MgYnVmZmVyIVxuIiwgZHJpdmUtPm5hbWUpOwoJCQlyZXR1cm4gLUVOT01FTTsKCQl9CgkJaW5mby0+dG9jID0gdG9jOwoJfQoKCS8qIENoZWNrIHRvIHNlZSBpZiB0aGUgZXhpc3RpbmcgZGF0YSBpcyBzdGlsbCB2YWxpZC4KCSAgIElmIGl0IGlzLCBqdXN0IHJldHVybi4gKi8KCSh2b2lkKSBjZHJvbV9jaGVja19zdGF0dXMoZHJpdmUsIHNlbnNlKTsKCglpZiAoQ0RST01fU1RBVEVfRkxBR1MoZHJpdmUpLT50b2NfdmFsaWQpCgkJcmV0dXJuIDA7CgoJLyogVHJ5IHRvIGdldCB0aGUgdG90YWwgY2Ryb20gY2FwYWNpdHkgYW5kIHNlY3RvciBzaXplLiAqLwoJc3RhdCA9IGNkcm9tX3JlYWRfY2FwYWNpdHkoZHJpdmUsICZ0b2MtPmNhcGFjaXR5LCAmc2VjdG9yc19wZXJfZnJhbWUsCgkJCQkgICBzZW5zZSk7CglpZiAoc3RhdCkKCQl0b2MtPmNhcGFjaXR5ID0gMHgxZmZmZmY7CgoJc2V0X2NhcGFjaXR5KGluZm8tPmRpc2ssIHRvYy0+Y2FwYWNpdHkgKiBzZWN0b3JzX3Blcl9mcmFtZSk7CgkvKiBTYXZlIGEgcHJpdmF0ZSBjb3B5IG9mIHRlIFRPQyBjYXBhY2l0eSBmb3IgZXJyb3IgaGFuZGxpbmcgKi8KCWRyaXZlLT5wcm9iZWRfY2FwYWNpdHkgPSB0b2MtPmNhcGFjaXR5ICogc2VjdG9yc19wZXJfZnJhbWU7CgoJYmxrX3F1ZXVlX2hhcmRzZWN0X3NpemUoZHJpdmUtPnF1ZXVlLAoJCQkJc2VjdG9yc19wZXJfZnJhbWUgPDwgU0VDVE9SX0JJVFMpOwoKCS8qIEZpcnN0IHJlYWQganVzdCB0aGUgaGVhZGVyLCBzbyB3ZSBrbm93IGhvdyBsb25nIHRoZSBUT0MgaXMuICovCglzdGF0ID0gY2Ryb21fcmVhZF90b2NlbnRyeShkcml2ZSwgMCwgMSwgMCwgKGNoYXIgKikgJnRvYy0+aGRyLAoJCQkJICAgIHNpemVvZihzdHJ1Y3QgYXRhcGlfdG9jX2hlYWRlciksIHNlbnNlKTsKCWlmIChzdGF0KQoJCXJldHVybiBzdGF0OwoKI2lmICEgU1RBTkRBUkRfQVRBUEkKCWlmIChDRFJPTV9DT05GSUdfRkxBR1MoZHJpdmUpLT50b2N0cmFja3NfYXNfYmNkKSB7CgkJdG9jLT5oZHIuZmlyc3RfdHJhY2sgPSBiY2QyYmluKHRvYy0+aGRyLmZpcnN0X3RyYWNrKTsKCQl0b2MtPmhkci5sYXN0X3RyYWNrICA9IGJjZDJiaW4odG9jLT5oZHIubGFzdF90cmFjayk7Cgl9CiNlbmRpZiAgLyogbm90IFNUQU5EQVJEX0FUQVBJICovCgoJbnRyYWNrcyA9IHRvYy0+aGRyLmxhc3RfdHJhY2sgLSB0b2MtPmhkci5maXJzdF90cmFjayArIDE7CglpZiAobnRyYWNrcyA8PSAwKQoJCXJldHVybiAtRUlPOwoJaWYgKG50cmFja3MgPiBNQVhfVFJBQ0tTKQoJCW50cmFja3MgPSBNQVhfVFJBQ0tTOwoKCS8qIE5vdyByZWFkIHRoZSB3aG9sZSBzY2htZWVyLiAqLwoJc3RhdCA9IGNkcm9tX3JlYWRfdG9jZW50cnkoZHJpdmUsIHRvYy0+aGRyLmZpcnN0X3RyYWNrLCAxLCAwLAoJCQkJICAoY2hhciAqKSZ0b2MtPmhkciwKCQkJCSAgIHNpemVvZihzdHJ1Y3QgYXRhcGlfdG9jX2hlYWRlcikgKwoJCQkJICAgKG50cmFja3MgKyAxKSAqCgkJCQkgICBzaXplb2Yoc3RydWN0IGF0YXBpX3RvY19lbnRyeSksIHNlbnNlKTsKCglpZiAoc3RhdCAmJiB0b2MtPmhkci5maXJzdF90cmFjayA+IDEpIHsKCQkvKiBDZHMgd2l0aCBDREkgdHJhY2tzIG9ubHkgZG9uJ3QgaGF2ZSBhbnkgVE9DIGVudHJpZXMsCgkJICAgZGVzcGl0ZSBvZiB0aGlzIHRoZSByZXR1cm5lZCB2YWx1ZXMgYXJlCgkJICAgZmlyc3RfdHJhY2sgPT0gbGFzdF90cmFjayA9IG51bWJlciBvZiBDREkgdHJhY2tzICsgMSwKCQkgICBzbyB0aGF0IHRoaXMgY2FzZSBpcyBpbmRpc3Rpbmd1aXNoYWJsZSBmcm9tIHRoZSBzYW1lCgkJICAgbGF5b3V0IHBsdXMgYW4gYWRkaXRpb25hbCBhdWRpbyB0cmFjay4KCQkgICBJZiB3ZSBnZXQgYW4gZXJyb3IgZm9yIHRoZSByZWd1bGFyIGNhc2UsIHdlIGFzc3VtZQoJCSAgIGEgQ0RJIHdpdGhvdXQgYWRkaXRpb25hbCBhdWRpbyB0cmFja3MuIEluIHRoaXMgY2FzZQoJCSAgIHRoZSByZWFkYWJsZSBUT0MgaXMgZW1wdHkgKENESSB0cmFja3MgYXJlIG5vdCBpbmNsdWRlZCkKCQkgICBhbmQgb25seSBob2xkcyB0aGUgTGVhZG91dCBlbnRyeS4gSGVpa28gRWnfZmVsZHQgKi8KCQludHJhY2tzID0gMDsKCQlzdGF0ID0gY2Ryb21fcmVhZF90b2NlbnRyeShkcml2ZSwgQ0RST01fTEVBRE9VVCwgMSwgMCwKCQkJCQkgICAoY2hhciAqKSZ0b2MtPmhkciwKCQkJCQkgICBzaXplb2Yoc3RydWN0IGF0YXBpX3RvY19oZWFkZXIpICsKCQkJCQkgICAobnRyYWNrcyArIDEpICoKCQkJCQkgICBzaXplb2Yoc3RydWN0IGF0YXBpX3RvY19lbnRyeSksCgkJCQkJICAgc2Vuc2UpOwoJCWlmIChzdGF0KSB7CgkJCXJldHVybiBzdGF0OwoJCX0KI2lmICEgU1RBTkRBUkRfQVRBUEkKCQlpZiAoQ0RST01fQ09ORklHX0ZMQUdTKGRyaXZlKS0+dG9jdHJhY2tzX2FzX2JjZCkgewoJCQl0b2MtPmhkci5maXJzdF90cmFjayA9IGJpbjJiY2QoQ0RST01fTEVBRE9VVCk7CgkJCXRvYy0+aGRyLmxhc3RfdHJhY2sgPSBiaW4yYmNkKENEUk9NX0xFQURPVVQpOwoJCX0gZWxzZQojZW5kaWYgIC8qIG5vdCBTVEFOREFSRF9BVEFQSSAqLwoJCXsKCQkJdG9jLT5oZHIuZmlyc3RfdHJhY2sgPSBDRFJPTV9MRUFET1VUOwoJCQl0b2MtPmhkci5sYXN0X3RyYWNrID0gQ0RST01fTEVBRE9VVDsKCQl9Cgl9CgoJaWYgKHN0YXQpCgkJcmV0dXJuIHN0YXQ7CgoJdG9jLT5oZHIudG9jX2xlbmd0aCA9IG50b2hzICh0b2MtPmhkci50b2NfbGVuZ3RoKTsKCiNpZiAhIFNUQU5EQVJEX0FUQVBJCglpZiAoQ0RST01fQ09ORklHX0ZMQUdTKGRyaXZlKS0+dG9jdHJhY2tzX2FzX2JjZCkgewoJCXRvYy0+aGRyLmZpcnN0X3RyYWNrID0gYmNkMmJpbih0b2MtPmhkci5maXJzdF90cmFjayk7CgkJdG9jLT5oZHIubGFzdF90cmFjayAgPSBiY2QyYmluKHRvYy0+aGRyLmxhc3RfdHJhY2spOwoJfQojZW5kaWYgIC8qIG5vdCBTVEFOREFSRF9BVEFQSSAqLwoKCWZvciAoaT0wOyBpPD1udHJhY2tzOyBpKyspIHsKI2lmICEgU1RBTkRBUkRfQVRBUEkKCQlpZiAoQ0RST01fQ09ORklHX0ZMQUdTKGRyaXZlKS0+dG9jYWRkcl9hc19iY2QpIHsKCQkJaWYgKENEUk9NX0NPTkZJR19GTEFHUyhkcml2ZSktPnRvY3RyYWNrc19hc19iY2QpCgkJCQl0b2MtPmVudFtpXS50cmFjayA9IGJjZDJiaW4odG9jLT5lbnRbaV0udHJhY2spOwoJCQltc2ZfZnJvbV9iY2QoJnRvYy0+ZW50W2ldLmFkZHIubXNmKTsKCQl9CiNlbmRpZiAgLyogbm90IFNUQU5EQVJEX0FUQVBJICovCgkJdG9jLT5lbnRbaV0uYWRkci5sYmEgPSBtc2ZfdG9fbGJhICh0b2MtPmVudFtpXS5hZGRyLm1zZi5taW51dGUsCgkJCQkJCSAgIHRvYy0+ZW50W2ldLmFkZHIubXNmLnNlY29uZCwKCQkJCQkJICAgdG9jLT5lbnRbaV0uYWRkci5tc2YuZnJhbWUpOwoJfQoKCS8qIFJlYWQgdGhlIG11bHRpc2Vzc2lvbiBpbmZvcm1hdGlvbi4gKi8KCWlmICh0b2MtPmhkci5maXJzdF90cmFjayAhPSBDRFJPTV9MRUFET1VUKSB7CgkJLyogUmVhZCB0aGUgbXVsdGlzZXNzaW9uIGluZm9ybWF0aW9uLiAqLwoJCXN0YXQgPSBjZHJvbV9yZWFkX3RvY2VudHJ5KGRyaXZlLCAwLCAwLCAxLCAoY2hhciAqKSZtc190bXAsCgkJCQkJICAgc2l6ZW9mKG1zX3RtcCksIHNlbnNlKTsKCQlpZiAoc3RhdCkKCQkJcmV0dXJuIHN0YXQ7CgoJCXRvYy0+bGFzdF9zZXNzaW9uX2xiYSA9IGJlMzJfdG9fY3B1KG1zX3RtcC5lbnQuYWRkci5sYmEpOwoJfSBlbHNlIHsKCQltc190bXAuaGRyLmZpcnN0X3RyYWNrID0gbXNfdG1wLmhkci5sYXN0X3RyYWNrID0gQ0RST01fTEVBRE9VVDsKCQl0b2MtPmxhc3Rfc2Vzc2lvbl9sYmEgPSBtc2ZfdG9fbGJhKDAsIDIsIDApOyAvKiAwbSAycyAwZiAqLwoJfQoKI2lmICEgU1RBTkRBUkRfQVRBUEkKCWlmIChDRFJPTV9DT05GSUdfRkxBR1MoZHJpdmUpLT50b2NhZGRyX2FzX2JjZCkgewoJCS8qIFJlLXJlYWQgbXVsdGlzZXNzaW9uIGluZm9ybWF0aW9uIHVzaW5nIE1TRiBmb3JtYXQgKi8KCQlzdGF0ID0gY2Ryb21fcmVhZF90b2NlbnRyeShkcml2ZSwgMCwgMSwgMSwgKGNoYXIgKikmbXNfdG1wLAoJCQkJCSAgIHNpemVvZihtc190bXApLCBzZW5zZSk7CgkJaWYgKHN0YXQpCgkJCXJldHVybiBzdGF0OwoKCQltc2ZfZnJvbV9iY2QgKCZtc190bXAuZW50LmFkZHIubXNmKTsKCQl0b2MtPmxhc3Rfc2Vzc2lvbl9sYmEgPSBtc2ZfdG9fbGJhKG1zX3RtcC5lbnQuYWRkci5tc2YubWludXRlLAoJCQkJCSAgCSAgIG1zX3RtcC5lbnQuYWRkci5tc2Yuc2Vjb25kLAoJCQkJCQkgICBtc190bXAuZW50LmFkZHIubXNmLmZyYW1lKTsKCX0KI2VuZGlmICAvKiBub3QgU1RBTkRBUkRfQVRBUEkgKi8KCgl0b2MtPnhhX2ZsYWcgPSAobXNfdG1wLmhkci5maXJzdF90cmFjayAhPSBtc190bXAuaGRyLmxhc3RfdHJhY2spOwoKCS8qIE5vdyB0cnkgdG8gZ2V0IHRoZSB0b3RhbCBjZHJvbSBjYXBhY2l0eS4gKi8KCXN0YXQgPSBjZHJvbV9nZXRfbGFzdF93cml0dGVuKGNkaSwgJmxhc3Rfd3JpdHRlbik7CglpZiAoIXN0YXQgJiYgKGxhc3Rfd3JpdHRlbiA+IHRvYy0+Y2FwYWNpdHkpKSB7CgkJdG9jLT5jYXBhY2l0eSA9IGxhc3Rfd3JpdHRlbjsKCQlzZXRfY2FwYWNpdHkoaW5mby0+ZGlzaywgdG9jLT5jYXBhY2l0eSAqIHNlY3RvcnNfcGVyX2ZyYW1lKTsKCQlkcml2ZS0+cHJvYmVkX2NhcGFjaXR5ID0gdG9jLT5jYXBhY2l0eSAqIHNlY3RvcnNfcGVyX2ZyYW1lOwoJfQoKCS8qIFJlbWVtYmVyIHRoYXQgd2UndmUgcmVhZCB0aGlzIHN0dWZmLiAqLwoJQ0RST01fU1RBVEVfRkxBR1MoZHJpdmUpLT50b2NfdmFsaWQgPSAxOwoKCXJldHVybiAwOwp9CgoKc3RhdGljIGludCBjZHJvbV9yZWFkX3N1YmNoYW5uZWwoaWRlX2RyaXZlX3QgKmRyaXZlLCBpbnQgZm9ybWF0LCBjaGFyICpidWYsCgkJCQkgaW50IGJ1Zmxlbiwgc3RydWN0IHJlcXVlc3Rfc2Vuc2UgKnNlbnNlKQp7CglzdHJ1Y3QgcmVxdWVzdCByZXE7CgoJY2Ryb21fcHJlcGFyZV9yZXF1ZXN0KGRyaXZlLCAmcmVxKTsKCglyZXEuc2Vuc2UgPSBzZW5zZTsKCXJlcS5kYXRhID0gYnVmOwoJcmVxLmRhdGFfbGVuID0gYnVmbGVuOwoJcmVxLmNtZFswXSA9IEdQQ01EX1JFQURfU1VCQ0hBTk5FTDsKCXJlcS5jbWRbMV0gPSAyOyAgICAgLyogTVNGIGFkZHJlc3NpbmcgKi8KCXJlcS5jbWRbMl0gPSAweDQwOyAgLyogcmVxdWVzdCBzdWJRIGRhdGEgKi8KCXJlcS5jbWRbM10gPSBmb3JtYXQ7CglyZXEuY21kWzddID0gKGJ1ZmxlbiA+PiA4KTsKCXJlcS5jbWRbOF0gPSAoYnVmbGVuICYgMHhmZik7CglyZXR1cm4gY2Ryb21fcXVldWVfcGFja2V0X2NvbW1hbmQoZHJpdmUsICZyZXEpOwp9CgovKiBBVEFQSSBjZHJvbSBkcml2ZXMgYXJlIGZyZWUgdG8gc2VsZWN0IHRoZSBzcGVlZCB5b3UgcmVxdWVzdCBvciBhbnkgc2xvd2VyCiAgIHJhdGUgOi0oIFJlcXVlc3RpbmcgdG9vIGZhc3QgYSBzcGVlZCB3aWxsIF9ub3RfIHByb2R1Y2UgYW4gZXJyb3IuICovCnN0YXRpYyBpbnQgY2Ryb21fc2VsZWN0X3NwZWVkKGlkZV9kcml2ZV90ICpkcml2ZSwgaW50IHNwZWVkLAoJCQkgICAgICBzdHJ1Y3QgcmVxdWVzdF9zZW5zZSAqc2Vuc2UpCnsKCXN0cnVjdCByZXF1ZXN0IHJlcTsKCWNkcm9tX3ByZXBhcmVfcmVxdWVzdChkcml2ZSwgJnJlcSk7CgoJcmVxLnNlbnNlID0gc2Vuc2U7CglpZiAoc3BlZWQgPT0gMCkKCQlzcGVlZCA9IDB4ZmZmZjsgLyogc2V0IHRvIG1heCAqLwoJZWxzZQoJCXNwZWVkICo9IDE3NzsgICAvKiBOeCB0byBrYnl0ZXMvcyAqLwoKCXJlcS5jbWRbMF0gPSBHUENNRF9TRVRfU1BFRUQ7CgkvKiBSZWFkIERyaXZlIHNwZWVkIGluIGtieXRlcy9zZWNvbmQgTVNCICovCglyZXEuY21kWzJdID0gKHNwZWVkID4+IDgpICYgMHhmZjsJCgkvKiBSZWFkIERyaXZlIHNwZWVkIGluIGtieXRlcy9zZWNvbmQgTFNCICovCglyZXEuY21kWzNdID0gc3BlZWQgJiAweGZmOwoJaWYgKENEUk9NX0NPTkZJR19GTEFHUyhkcml2ZSktPmNkX3IgfHwKCSAgICBDRFJPTV9DT05GSUdfRkxBR1MoZHJpdmUpLT5jZF9ydyB8fAoJICAgIENEUk9NX0NPTkZJR19GTEFHUyhkcml2ZSktPmR2ZF9yKSB7CgkJLyogV3JpdGUgRHJpdmUgc3BlZWQgaW4ga2J5dGVzL3NlY29uZCBNU0IgKi8KCQlyZXEuY21kWzRdID0gKHNwZWVkID4+IDgpICYgMHhmZjsKCQkvKiBXcml0ZSBEcml2ZSBzcGVlZCBpbiBrYnl0ZXMvc2Vjb25kIExTQiAqLwoJCXJlcS5jbWRbNV0gPSBzcGVlZCAmIDB4ZmY7CiAgICAgICB9CgoJcmV0dXJuIGNkcm9tX3F1ZXVlX3BhY2tldF9jb21tYW5kKGRyaXZlLCAmcmVxKTsKfQoKc3RhdGljIGludCBjZHJvbV9wbGF5X2F1ZGlvKGlkZV9kcml2ZV90ICpkcml2ZSwgaW50IGxiYV9zdGFydCwgaW50IGxiYV9lbmQpCnsKCXN0cnVjdCByZXF1ZXN0X3NlbnNlIHNlbnNlOwoJc3RydWN0IHJlcXVlc3QgcmVxOwoKCWNkcm9tX3ByZXBhcmVfcmVxdWVzdChkcml2ZSwgJnJlcSk7CgoJcmVxLnNlbnNlID0gJnNlbnNlOwoJcmVxLmNtZFswXSA9IEdQQ01EX1BMQVlfQVVESU9fTVNGOwoJbGJhX3RvX21zZihsYmFfc3RhcnQsICZyZXEuY21kWzNdLCAmcmVxLmNtZFs0XSwgJnJlcS5jbWRbNV0pOwoJbGJhX3RvX21zZihsYmFfZW5kLTEsICZyZXEuY21kWzZdLCAmcmVxLmNtZFs3XSwgJnJlcS5jbWRbOF0pOwoKCXJldHVybiBjZHJvbV9xdWV1ZV9wYWNrZXRfY29tbWFuZChkcml2ZSwgJnJlcSk7Cn0KCnN0YXRpYyBpbnQgY2Ryb21fZ2V0X3RvY19lbnRyeShpZGVfZHJpdmVfdCAqZHJpdmUsIGludCB0cmFjaywKCQkJCXN0cnVjdCBhdGFwaV90b2NfZW50cnkgKiplbnQpCnsKCXN0cnVjdCBjZHJvbV9pbmZvICppbmZvID0gZHJpdmUtPmRyaXZlcl9kYXRhOwoJc3RydWN0IGF0YXBpX3RvYyAqdG9jID0gaW5mby0+dG9jOwoJaW50IG50cmFja3M7CgoJLyoKCSAqIGRvbid0IHNlcnZlIGNhY2hlZCBkYXRhLCBpZiB0aGUgdG9jIGlzbid0IHZhbGlkCgkgKi8KCWlmICghQ0RST01fU1RBVEVfRkxBR1MoZHJpdmUpLT50b2NfdmFsaWQpCgkJcmV0dXJuIC1FSU5WQUw7CgoJLyogQ2hlY2sgdmFsaWRpdHkgb2YgcmVxdWVzdGVkIHRyYWNrIG51bWJlci4gKi8KCW50cmFja3MgPSB0b2MtPmhkci5sYXN0X3RyYWNrIC0gdG9jLT5oZHIuZmlyc3RfdHJhY2sgKyAxOwoJaWYgKHRvYy0+aGRyLmZpcnN0X3RyYWNrID09IENEUk9NX0xFQURPVVQpIG50cmFja3MgPSAwOwoJaWYgKHRyYWNrID09IENEUk9NX0xFQURPVVQpCgkJKmVudCA9ICZ0b2MtPmVudFtudHJhY2tzXTsKCWVsc2UgaWYgKHRyYWNrIDwgdG9jLT5oZHIuZmlyc3RfdHJhY2sgfHwKCQkgdHJhY2sgPiB0b2MtPmhkci5sYXN0X3RyYWNrKQoJCXJldHVybiAtRUlOVkFMOwoJZWxzZQoJCSplbnQgPSAmdG9jLT5lbnRbdHJhY2sgLSB0b2MtPmhkci5maXJzdF90cmFja107CgoJcmV0dXJuIDA7Cn0KCi8qIHRoZSBnZW5lcmljIHBhY2tldCBpbnRlcmZhY2UgdG8gY2Ryb20uYyAqLwpzdGF0aWMgaW50IGlkZV9jZHJvbV9wYWNrZXQoc3RydWN0IGNkcm9tX2RldmljZV9pbmZvICpjZGksCgkJCSAgICBzdHJ1Y3QgcGFja2V0X2NvbW1hbmQgKmNnYykKewoJc3RydWN0IHJlcXVlc3QgcmVxOwoJaWRlX2RyaXZlX3QgKmRyaXZlID0gY2RpLT5oYW5kbGU7CgoJaWYgKGNnYy0+dGltZW91dCA8PSAwKQoJCWNnYy0+dGltZW91dCA9IEFUQVBJX1dBSVRfUEM7CgoJLyogaGVyZSB3ZSBxdWV1ZSB0aGUgY29tbWFuZHMgZnJvbSB0aGUgdW5pZm9ybSBDRC1ST00KCSAgIGxheWVyLiB0aGUgcGFja2V0IG11c3QgYmUgY29tcGxldGUsIGFzIHdlIGRvIG5vdAoJICAgdG91Y2ggaXQgYXQgYWxsLiAqLwoJY2Ryb21fcHJlcGFyZV9yZXF1ZXN0KGRyaXZlLCAmcmVxKTsKCW1lbWNweShyZXEuY21kLCBjZ2MtPmNtZCwgQ0RST01fUEFDS0VUX1NJWkUpOwoJaWYgKGNnYy0+c2Vuc2UpCgkJbWVtc2V0KGNnYy0+c2Vuc2UsIDAsIHNpemVvZihzdHJ1Y3QgcmVxdWVzdF9zZW5zZSkpOwoJcmVxLmRhdGEgPSBjZ2MtPmJ1ZmZlcjsKCXJlcS5kYXRhX2xlbiA9IGNnYy0+YnVmbGVuOwoJcmVxLnRpbWVvdXQgPSBjZ2MtPnRpbWVvdXQ7CgoJaWYgKGNnYy0+cXVpZXQpCgkJcmVxLmNtZF9mbGFncyB8PSBSRVFfUVVJRVQ7CgoJcmVxLnNlbnNlID0gY2djLT5zZW5zZTsKCWNnYy0+c3RhdCA9IGNkcm9tX3F1ZXVlX3BhY2tldF9jb21tYW5kKGRyaXZlLCAmcmVxKTsKCWlmICghY2djLT5zdGF0KQoJCWNnYy0+YnVmbGVuIC09IHJlcS5kYXRhX2xlbjsKCXJldHVybiBjZ2MtPnN0YXQ7Cn0KCnN0YXRpYwppbnQgaWRlX2Nkcm9tX2F1ZGlvX2lvY3RsIChzdHJ1Y3QgY2Ryb21fZGV2aWNlX2luZm8gKmNkaSwKCQkJICAgdW5zaWduZWQgaW50IGNtZCwgdm9pZCAqYXJnKQoJCQkgICAKewoJaWRlX2RyaXZlX3QgKmRyaXZlID0gY2RpLT5oYW5kbGU7CglzdHJ1Y3QgY2Ryb21faW5mbyAqaW5mbyA9IGRyaXZlLT5kcml2ZXJfZGF0YTsKCWludCBzdGF0OwoKCXN3aXRjaCAoY21kKSB7CgkvKgoJICogZW11bGF0ZSBQTEFZX0FVRElPX1RJIGNvbW1hbmQgd2l0aCBQTEFZX0FVRElPXzEwLCBzaW5jZQoJICogYXRhcGkgZG9lc24ndCBzdXBwb3J0IGl0CgkgKi8KCWNhc2UgQ0RST01QTEFZVFJLSU5EOiB7CgkJdW5zaWduZWQgbG9uZyBsYmFfc3RhcnQsIGxiYV9lbmQ7CgkJc3RydWN0IGNkcm9tX3RpICp0aSA9IGFyZzsKCQlzdHJ1Y3QgYXRhcGlfdG9jX2VudHJ5ICpmaXJzdF90b2MsICpsYXN0X3RvYzsKCgkJc3RhdCA9IGNkcm9tX2dldF90b2NfZW50cnkoZHJpdmUsIHRpLT5jZHRpX3RyazAsICZmaXJzdF90b2MpOwoJCWlmIChzdGF0KQoJCQlyZXR1cm4gc3RhdDsKCgkJc3RhdCA9IGNkcm9tX2dldF90b2NfZW50cnkoZHJpdmUsIHRpLT5jZHRpX3RyazEsICZsYXN0X3RvYyk7CgkJaWYgKHN0YXQpCgkJCXJldHVybiBzdGF0OwoKCQlpZiAodGktPmNkdGlfdHJrMSAhPSBDRFJPTV9MRUFET1VUKQoJCQkrK2xhc3RfdG9jOwoJCWxiYV9zdGFydCA9IGZpcnN0X3RvYy0+YWRkci5sYmE7CgkJbGJhX2VuZCAgID0gbGFzdF90b2MtPmFkZHIubGJhOwoKCQlpZiAobGJhX2VuZCA8PSBsYmFfc3RhcnQpCgkJCXJldHVybiAtRUlOVkFMOwoKCQlyZXR1cm4gY2Ryb21fcGxheV9hdWRpbyhkcml2ZSwgbGJhX3N0YXJ0LCBsYmFfZW5kKTsKCX0KCgljYXNlIENEUk9NUkVBRFRPQ0hEUjogewoJCXN0cnVjdCBjZHJvbV90b2NoZHIgKnRvY2hkciA9IGFyZzsKCQlzdHJ1Y3QgYXRhcGlfdG9jICp0b2M7CgoJCS8qIE1ha2Ugc3VyZSBvdXIgc2F2ZWQgVE9DIGlzIHZhbGlkLiAqLwoJCXN0YXQgPSBjZHJvbV9yZWFkX3RvYyhkcml2ZSwgTlVMTCk7CgkJaWYgKHN0YXQpCgkJCXJldHVybiBzdGF0OwoKCQl0b2MgPSBpbmZvLT50b2M7CgkJdG9jaGRyLT5jZHRoX3RyazAgPSB0b2MtPmhkci5maXJzdF90cmFjazsKCQl0b2NoZHItPmNkdGhfdHJrMSA9IHRvYy0+aGRyLmxhc3RfdHJhY2s7CgoJCXJldHVybiAwOwoJfQoKCWNhc2UgQ0RST01SRUFEVE9DRU5UUlk6IHsKCQlzdHJ1Y3QgY2Ryb21fdG9jZW50cnkgKnRvY2VudHJ5ID0gYXJnOwoJCXN0cnVjdCBhdGFwaV90b2NfZW50cnkgKnRvY2U7CgoJCXN0YXQgPSBjZHJvbV9nZXRfdG9jX2VudHJ5KGRyaXZlLCB0b2NlbnRyeS0+Y2R0ZV90cmFjaywgJnRvY2UpOwoJCWlmIChzdGF0KQoJCQlyZXR1cm4gc3RhdDsKCgkJdG9jZW50cnktPmNkdGVfY3RybCA9IHRvY2UtPmNvbnRyb2w7CgkJdG9jZW50cnktPmNkdGVfYWRyICA9IHRvY2UtPmFkcjsKCQlpZiAodG9jZW50cnktPmNkdGVfZm9ybWF0ID09IENEUk9NX01TRikgewoJCQlsYmFfdG9fbXNmICh0b2NlLT5hZGRyLmxiYSwKCQkJCSAgICZ0b2NlbnRyeS0+Y2R0ZV9hZGRyLm1zZi5taW51dGUsCgkJCQkgICAmdG9jZW50cnktPmNkdGVfYWRkci5tc2Yuc2Vjb25kLAoJCQkJICAgJnRvY2VudHJ5LT5jZHRlX2FkZHIubXNmLmZyYW1lKTsKCQl9IGVsc2UKCQkJdG9jZW50cnktPmNkdGVfYWRkci5sYmEgPSB0b2NlLT5hZGRyLmxiYTsKCgkJcmV0dXJuIDA7Cgl9CgoJZGVmYXVsdDoKCQlyZXR1cm4gLUVJTlZBTDsKCX0KfQoKc3RhdGljCmludCBpZGVfY2Ryb21fcmVzZXQgKHN0cnVjdCBjZHJvbV9kZXZpY2VfaW5mbyAqY2RpKQp7CglpZGVfZHJpdmVfdCAqZHJpdmUgPSBjZGktPmhhbmRsZTsKCXN0cnVjdCByZXF1ZXN0X3NlbnNlIHNlbnNlOwoJc3RydWN0IHJlcXVlc3QgcmVxOwoJaW50IHJldDsKCgljZHJvbV9wcmVwYXJlX3JlcXVlc3QoZHJpdmUsICZyZXEpOwoJcmVxLmNtZF90eXBlID0gUkVRX1RZUEVfU1BFQ0lBTDsKCXJlcS5jbWRfZmxhZ3MgPSBSRVFfUVVJRVQ7CglyZXQgPSBpZGVfZG9fZHJpdmVfY21kKGRyaXZlLCAmcmVxLCBpZGVfd2FpdCk7CgoJLyoKCSAqIEEgcmVzZXQgd2lsbCB1bmxvY2sgdGhlIGRvb3IuIElmIGl0IHdhcyBwcmV2aW91c2x5IGxvY2tlZCwKCSAqIGxvY2sgaXQgYWdhaW4uCgkgKi8KCWlmIChDRFJPTV9TVEFURV9GTEFHUyhkcml2ZSktPmRvb3JfbG9ja2VkKQoJCSh2b2lkKSBjZHJvbV9sb2NrZG9vcihkcml2ZSwgMSwgJnNlbnNlKTsKCglyZXR1cm4gcmV0Owp9CgoKc3RhdGljCmludCBpZGVfY2Ryb21fdHJheV9tb3ZlIChzdHJ1Y3QgY2Ryb21fZGV2aWNlX2luZm8gKmNkaSwgaW50IHBvc2l0aW9uKQp7CglpZGVfZHJpdmVfdCAqZHJpdmUgPSBjZGktPmhhbmRsZTsKCXN0cnVjdCByZXF1ZXN0X3NlbnNlIHNlbnNlOwoKCWlmIChwb3NpdGlvbikgewoJCWludCBzdGF0ID0gY2Ryb21fbG9ja2Rvb3IoZHJpdmUsIDAsICZzZW5zZSk7CgkJaWYgKHN0YXQpCgkJCXJldHVybiBzdGF0OwoJfQoKCXJldHVybiBjZHJvbV9lamVjdChkcml2ZSwgIXBvc2l0aW9uLCAmc2Vuc2UpOwp9CgpzdGF0aWMKaW50IGlkZV9jZHJvbV9sb2NrX2Rvb3IgKHN0cnVjdCBjZHJvbV9kZXZpY2VfaW5mbyAqY2RpLCBpbnQgbG9jaykKewoJaWRlX2RyaXZlX3QgKmRyaXZlID0gY2RpLT5oYW5kbGU7CglyZXR1cm4gY2Ryb21fbG9ja2Rvb3IoZHJpdmUsIGxvY2ssIE5VTEwpOwp9CgpzdGF0aWMKaW50IGlkZV9jZHJvbV9nZXRfY2FwYWJpbGl0aWVzKGlkZV9kcml2ZV90ICpkcml2ZSwgc3RydWN0IGF0YXBpX2NhcGFiaWxpdGllc19wYWdlICpjYXApCnsKCXN0cnVjdCBjZHJvbV9pbmZvICppbmZvID0gZHJpdmUtPmRyaXZlcl9kYXRhOwoJc3RydWN0IGNkcm9tX2RldmljZV9pbmZvICpjZGkgPSAmaW5mby0+ZGV2aW5mbzsKCXN0cnVjdCBwYWNrZXRfY29tbWFuZCBjZ2M7CglpbnQgc3RhdCwgYXR0ZW1wdHMgPSAzLCBzaXplID0gc2l6ZW9mKCpjYXApOwoKCS8qCgkgKiBBQ0VSNTAgKGFuZCBvdGhlcnM/KSByZXF1aXJlIHRoZSBmdWxsIHNwZWMgbGVuZ3RoIG1vZGUgc2Vuc2UKCSAqIHBhZ2UgY2FwYWJpbGl0aWVzIHNpemUsIGJ1dCBvbGRlciBkcml2ZXMgYnJlYWsuCgkgKi8KCWlmICghKCFzdHJjbXAoZHJpdmUtPmlkLT5tb2RlbCwgIkFUQVBJIENEIFJPTSBEUklWRSA1MFggTUFYIikgfHwKCSAgICAhc3RyY21wKGRyaXZlLT5pZC0+bW9kZWwsICJXUEkgQ0RTLTMyWCIpKSkKCQlzaXplIC09IHNpemVvZihjYXAtPnBhZCk7CgoJaW5pdF9jZHJvbV9jb21tYW5kKCZjZ2MsIGNhcCwgc2l6ZSwgQ0dDX0RBVEFfVU5LTk9XTik7CglkbyB7IC8qIHdlIHNlZW0gdG8gZ2V0IHN0YXQ9MHgwMSxlcnI9MHgwMCB0aGUgZmlyc3QgdGltZSAoPz8pICovCgkJc3RhdCA9IGNkcm9tX21vZGVfc2Vuc2UoY2RpLCAmY2djLCBHUE1PREVfQ0FQQUJJTElUSUVTX1BBR0UsIDApOwoJCWlmICghc3RhdCkKCQkJYnJlYWs7Cgl9IHdoaWxlICgtLWF0dGVtcHRzKTsKCXJldHVybiBzdGF0Owp9CgpzdGF0aWMKdm9pZCBpZGVfY2Ryb21fdXBkYXRlX3NwZWVkIChpZGVfZHJpdmVfdCAqZHJpdmUsIHN0cnVjdCBhdGFwaV9jYXBhYmlsaXRpZXNfcGFnZSAqY2FwKQp7CgkvKiBUaGUgQUNFUi9BT3BlbiAyNFggY2Ryb20gaGFzIHRoZSBzcGVlZCBmaWVsZHMgYnl0ZS1zd2FwcGVkICovCglpZiAoIWRyaXZlLT5pZC0+bW9kZWxbMF0gJiYKCSAgICAhc3RybmNtcChkcml2ZS0+aWQtPmZ3X3JldiwgIjI0MU4iLCA0KSkgewoJCUNEUk9NX1NUQVRFX0ZMQUdTKGRyaXZlKS0+Y3VycmVudF9zcGVlZCAgPQoJCQkoKCh1bnNpZ25lZCBpbnQpY2FwLT5jdXJzcGVlZCkgKyAoMTc2LzIpKSAvIDE3NjsKCQlDRFJPTV9DT05GSUdfRkxBR1MoZHJpdmUpLT5tYXhfc3BlZWQgPQoJCQkoKCh1bnNpZ25lZCBpbnQpY2FwLT5tYXhzcGVlZCkgKyAoMTc2LzIpKSAvIDE3NjsKCX0gZWxzZSB7CgkJQ0RST01fU1RBVEVfRkxBR1MoZHJpdmUpLT5jdXJyZW50X3NwZWVkICA9CgkJCShudG9ocyhjYXAtPmN1cnNwZWVkKSArICgxNzYvMikpIC8gMTc2OwoJCUNEUk9NX0NPTkZJR19GTEFHUyhkcml2ZSktPm1heF9zcGVlZCA9CgkJCShudG9ocyhjYXAtPm1heHNwZWVkKSArICgxNzYvMikpIC8gMTc2OwoJfQp9CgpzdGF0aWMKaW50IGlkZV9jZHJvbV9zZWxlY3Rfc3BlZWQgKHN0cnVjdCBjZHJvbV9kZXZpY2VfaW5mbyAqY2RpLCBpbnQgc3BlZWQpCnsKCWlkZV9kcml2ZV90ICpkcml2ZSA9IGNkaS0+aGFuZGxlOwoJc3RydWN0IHJlcXVlc3Rfc2Vuc2Ugc2Vuc2U7CglzdHJ1Y3QgYXRhcGlfY2FwYWJpbGl0aWVzX3BhZ2UgY2FwOwoJaW50IHN0YXQ7CgoJaWYgKChzdGF0ID0gY2Ryb21fc2VsZWN0X3NwZWVkKGRyaXZlLCBzcGVlZCwgJnNlbnNlKSkgPCAwKQoJCXJldHVybiBzdGF0OwoKCWlmICghaWRlX2Nkcm9tX2dldF9jYXBhYmlsaXRpZXMoZHJpdmUsICZjYXApKSB7CgkJaWRlX2Nkcm9tX3VwZGF0ZV9zcGVlZChkcml2ZSwgJmNhcCk7CgkJY2RpLT5zcGVlZCA9IENEUk9NX1NUQVRFX0ZMQUdTKGRyaXZlKS0+Y3VycmVudF9zcGVlZDsKCX0KICAgICAgICByZXR1cm4gMDsKfQoKLyoKICogYWRkIGxvZ2ljIHRvIHRyeSBHRVRfRVZFTlQgY29tbWFuZCBmaXJzdCB0byBjaGVjayBmb3IgbWVkaWEgYW5kIHRyYXkKICogc3RhdHVzLiB0aGlzIHNob3VsZCBiZSBzdXBwb3J0ZWQgYnkgbmV3ZXIgY2Qtci93IGFuZCBhbGwgRFZEIGV0YwogKiBkcml2ZXMKICovCnN0YXRpYwppbnQgaWRlX2Nkcm9tX2RyaXZlX3N0YXR1cyAoc3RydWN0IGNkcm9tX2RldmljZV9pbmZvICpjZGksIGludCBzbG90X25yKQp7CglpZGVfZHJpdmVfdCAqZHJpdmUgPSBjZGktPmhhbmRsZTsKCXN0cnVjdCBtZWRpYV9ldmVudF9kZXNjIG1lZDsKCXN0cnVjdCByZXF1ZXN0X3NlbnNlIHNlbnNlOwoJaW50IHN0YXQ7CgoJaWYgKHNsb3RfbnIgIT0gQ0RTTF9DVVJSRU5UKQoJCXJldHVybiAtRUlOVkFMOwoKCXN0YXQgPSBjZHJvbV9jaGVja19zdGF0dXMoZHJpdmUsICZzZW5zZSk7CglpZiAoIXN0YXQgfHwgc2Vuc2Uuc2Vuc2Vfa2V5ID09IFVOSVRfQVRURU5USU9OKQoJCXJldHVybiBDRFNfRElTQ19PSzsKCglpZiAoIWNkcm9tX2dldF9tZWRpYV9ldmVudChjZGksICZtZWQpKSB7CgkJaWYgKG1lZC5tZWRpYV9wcmVzZW50KQoJCQlyZXR1cm4gQ0RTX0RJU0NfT0s7CgkJZWxzZSBpZiAobWVkLmRvb3Jfb3BlbikKCQkJcmV0dXJuIENEU19UUkFZX09QRU47CgkJZWxzZQoJCQlyZXR1cm4gQ0RTX05PX0RJU0M7Cgl9CgoJaWYgKHNlbnNlLnNlbnNlX2tleSA9PSBOT1RfUkVBRFkgJiYgc2Vuc2UuYXNjID09IDB4MDQgJiYgc2Vuc2UuYXNjcSA9PSAweDA0KQoJCXJldHVybiBDRFNfRElTQ19PSzsKCgkvKgoJICogSWYgbm90IHVzaW5nIE10IEZ1amkgZXh0ZW5kZWQgbWVkaWEgdHJheSByZXBvcnRzLAoJICoganVzdCByZXR1cm4gVFJBWV9PUEVOIHNpbmNlIEFUQVBJIGRvZXNuJ3QgcHJvdmlkZQoJICogYW55IG90aGVyIHdheSB0byBkZXRlY3QgdGhpcy4uLgoJICovCglpZiAoc2Vuc2Uuc2Vuc2Vfa2V5ID09IE5PVF9SRUFEWSkgewoJCWlmIChzZW5zZS5hc2MgPT0gMHgzYSAmJiBzZW5zZS5hc2NxID09IDEpCgkJCXJldHVybiBDRFNfTk9fRElTQzsKCQllbHNlCgkJCXJldHVybiBDRFNfVFJBWV9PUEVOOwoJfQoJcmV0dXJuIENEU19EUklWRV9OT1RfUkVBRFk7Cn0KCnN0YXRpYwppbnQgaWRlX2Nkcm9tX2dldF9sYXN0X3Nlc3Npb24gKHN0cnVjdCBjZHJvbV9kZXZpY2VfaW5mbyAqY2RpLAoJCQkJc3RydWN0IGNkcm9tX211bHRpc2Vzc2lvbiAqbXNfaW5mbykKewoJc3RydWN0IGF0YXBpX3RvYyAqdG9jOwoJaWRlX2RyaXZlX3QgKmRyaXZlID0gY2RpLT5oYW5kbGU7CglzdHJ1Y3QgY2Ryb21faW5mbyAqaW5mbyA9IGRyaXZlLT5kcml2ZXJfZGF0YTsKCXN0cnVjdCByZXF1ZXN0X3NlbnNlIHNlbnNlOwoJaW50IHJldDsKCglpZiAoIUNEUk9NX1NUQVRFX0ZMQUdTKGRyaXZlKS0+dG9jX3ZhbGlkIHx8IGluZm8tPnRvYyA9PSBOVUxMKQoJCWlmICgocmV0ID0gY2Ryb21fcmVhZF90b2MoZHJpdmUsICZzZW5zZSkpKQoJCQlyZXR1cm4gcmV0OwoKCXRvYyA9IGluZm8tPnRvYzsKCW1zX2luZm8tPmFkZHIubGJhID0gdG9jLT5sYXN0X3Nlc3Npb25fbGJhOwoJbXNfaW5mby0+eGFfZmxhZyA9IHRvYy0+eGFfZmxhZzsKCglyZXR1cm4gMDsKfQoKc3RhdGljCmludCBpZGVfY2Ryb21fZ2V0X21jbiAoc3RydWN0IGNkcm9tX2RldmljZV9pbmZvICpjZGksCgkJICAgICAgIHN0cnVjdCBjZHJvbV9tY24gKm1jbl9pbmZvKQp7CglpbnQgc3RhdDsKCWNoYXIgbWNuYnVmWzI0XTsKCWlkZV9kcml2ZV90ICpkcml2ZSA9IGNkaS0+aGFuZGxlOwoKLyogZ2V0IE1DTiAqLwoJaWYgKChzdGF0ID0gY2Ryb21fcmVhZF9zdWJjaGFubmVsKGRyaXZlLCAyLCBtY25idWYsIHNpemVvZiAobWNuYnVmKSwgTlVMTCkpKQoJCXJldHVybiBzdGF0OwoKCW1lbWNweSAobWNuX2luZm8tPm1lZGl1bV9jYXRhbG9nX251bWJlciwgbWNuYnVmKzksCgkJc2l6ZW9mIChtY25faW5mby0+bWVkaXVtX2NhdGFsb2dfbnVtYmVyKS0xKTsKCW1jbl9pbmZvLT5tZWRpdW1fY2F0YWxvZ19udW1iZXJbc2l6ZW9mIChtY25faW5mby0+bWVkaXVtX2NhdGFsb2dfbnVtYmVyKS0xXQoJCT0gJ1wwJzsKCglyZXR1cm4gMDsKfQoKCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBPdGhlciBkcml2ZXIgcmVxdWVzdHMgKG9wZW4sIGNsb3NlLCBjaGVjayBtZWRpYSBjaGFuZ2UpLgogKi8KCnN0YXRpYwppbnQgaWRlX2Nkcm9tX2NoZWNrX21lZGlhX2NoYW5nZV9yZWFsIChzdHJ1Y3QgY2Ryb21fZGV2aWNlX2luZm8gKmNkaSwKCQkJCSAgICAgICBpbnQgc2xvdF9ucikKewoJaWRlX2RyaXZlX3QgKmRyaXZlID0gY2RpLT5oYW5kbGU7CglpbnQgcmV0dmFsOwoJCglpZiAoc2xvdF9uciA9PSBDRFNMX0NVUlJFTlQpIHsKCQkodm9pZCkgY2Ryb21fY2hlY2tfc3RhdHVzKGRyaXZlLCBOVUxMKTsKCQlyZXR2YWwgPSBDRFJPTV9TVEFURV9GTEFHUyhkcml2ZSktPm1lZGlhX2NoYW5nZWQ7CgkJQ0RST01fU1RBVEVfRkxBR1MoZHJpdmUpLT5tZWRpYV9jaGFuZ2VkID0gMDsKCQlyZXR1cm4gcmV0dmFsOwoJfSBlbHNlIHsKCQlyZXR1cm4gLUVJTlZBTDsKCX0KfQoKCnN0YXRpYwppbnQgaWRlX2Nkcm9tX29wZW5fcmVhbCAoc3RydWN0IGNkcm9tX2RldmljZV9pbmZvICpjZGksIGludCBwdXJwb3NlKQp7CglyZXR1cm4gMDsKfQoKLyoKICogQ2xvc2UgZG93biB0aGUgZGV2aWNlLiAgSW52YWxpZGF0ZSBhbGwgY2FjaGVkIGJsb2Nrcy4KICovCgpzdGF0aWMKdm9pZCBpZGVfY2Ryb21fcmVsZWFzZV9yZWFsIChzdHJ1Y3QgY2Ryb21fZGV2aWNlX2luZm8gKmNkaSkKewoJaWRlX2RyaXZlX3QgKmRyaXZlID0gY2RpLT5oYW5kbGU7CgoJaWYgKCFjZGktPnVzZV9jb3VudCkKCQlDRFJPTV9TVEFURV9GTEFHUyhkcml2ZSktPnRvY192YWxpZCA9IDA7Cn0KCgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogRGV2aWNlIGluaXRpYWxpemF0aW9uLgogKi8Kc3RhdGljIHN0cnVjdCBjZHJvbV9kZXZpY2Vfb3BzIGlkZV9jZHJvbV9kb3BzID0gewoJLm9wZW4JCQk9IGlkZV9jZHJvbV9vcGVuX3JlYWwsCgkucmVsZWFzZQkJPSBpZGVfY2Ryb21fcmVsZWFzZV9yZWFsLAoJLmRyaXZlX3N0YXR1cwkJPSBpZGVfY2Ryb21fZHJpdmVfc3RhdHVzLAoJLm1lZGlhX2NoYW5nZWQJCT0gaWRlX2Nkcm9tX2NoZWNrX21lZGlhX2NoYW5nZV9yZWFsLAoJLnRyYXlfbW92ZQkJPSBpZGVfY2Ryb21fdHJheV9tb3ZlLAoJLmxvY2tfZG9vcgkJPSBpZGVfY2Ryb21fbG9ja19kb29yLAoJLnNlbGVjdF9zcGVlZAkJPSBpZGVfY2Ryb21fc2VsZWN0X3NwZWVkLAoJLmdldF9sYXN0X3Nlc3Npb24JPSBpZGVfY2Ryb21fZ2V0X2xhc3Rfc2Vzc2lvbiwKCS5nZXRfbWNuCQk9IGlkZV9jZHJvbV9nZXRfbWNuLAoJLnJlc2V0CQkJPSBpZGVfY2Ryb21fcmVzZXQsCgkuYXVkaW9faW9jdGwJCT0gaWRlX2Nkcm9tX2F1ZGlvX2lvY3RsLAoJLmNhcGFiaWxpdHkJCT0gQ0RDX0NMT1NFX1RSQVkgfCBDRENfT1BFTl9UUkFZIHwgQ0RDX0xPQ0sgfAoJCQkJQ0RDX1NFTEVDVF9TUEVFRCB8IENEQ19TRUxFQ1RfRElTQyB8CgkJCQlDRENfTVVMVElfU0VTU0lPTiB8IENEQ19NQ04gfAoJCQkJQ0RDX01FRElBX0NIQU5HRUQgfCBDRENfUExBWV9BVURJTyB8IENEQ19SRVNFVCB8CgkJCQlDRENfRFJJVkVfU1RBVFVTIHwgQ0RDX0NEX1IgfAoJCQkJQ0RDX0NEX1JXIHwgQ0RDX0RWRCB8IENEQ19EVkRfUnwgQ0RDX0RWRF9SQU0gfAoJCQkJQ0RDX0dFTkVSSUNfUEFDS0VUIHwgQ0RDX01PX0RSSVZFIHwgQ0RDX01SVyB8CgkJCQlDRENfTVJXX1cgfCBDRENfUkFNLAoJLmdlbmVyaWNfcGFja2V0CQk9IGlkZV9jZHJvbV9wYWNrZXQsCn07CgpzdGF0aWMgaW50IGlkZV9jZHJvbV9yZWdpc3RlciAoaWRlX2RyaXZlX3QgKmRyaXZlLCBpbnQgbnNsb3RzKQp7CglzdHJ1Y3QgY2Ryb21faW5mbyAqaW5mbyA9IGRyaXZlLT5kcml2ZXJfZGF0YTsKCXN0cnVjdCBjZHJvbV9kZXZpY2VfaW5mbyAqZGV2aW5mbyA9ICZpbmZvLT5kZXZpbmZvOwoKCWRldmluZm8tPm9wcyA9ICZpZGVfY2Ryb21fZG9wczsKCWRldmluZm8tPm1hc2sgPSAwOwoJZGV2aW5mby0+c3BlZWQgPSBDRFJPTV9TVEFURV9GTEFHUyhkcml2ZSktPmN1cnJlbnRfc3BlZWQ7CglkZXZpbmZvLT5jYXBhY2l0eSA9IG5zbG90czsKCWRldmluZm8tPmhhbmRsZSA9IGRyaXZlOwoJc3RyY3B5KGRldmluZm8tPm5hbWUsIGRyaXZlLT5uYW1lKTsKCQoJLyogc2V0IGNhcGFiaWxpdHkgbWFzayB0byBtYXRjaCB0aGUgcHJvYmUuICovCglpZiAoIUNEUk9NX0NPTkZJR19GTEFHUyhkcml2ZSktPmNkX3IpCgkJZGV2aW5mby0+bWFzayB8PSBDRENfQ0RfUjsKCWlmICghQ0RST01fQ09ORklHX0ZMQUdTKGRyaXZlKS0+Y2RfcncpCgkJZGV2aW5mby0+bWFzayB8PSBDRENfQ0RfUlc7CglpZiAoIUNEUk9NX0NPTkZJR19GTEFHUyhkcml2ZSktPmR2ZCkKCQlkZXZpbmZvLT5tYXNrIHw9IENEQ19EVkQ7CglpZiAoIUNEUk9NX0NPTkZJR19GTEFHUyhkcml2ZSktPmR2ZF9yKQoJCWRldmluZm8tPm1hc2sgfD0gQ0RDX0RWRF9SOwoJaWYgKCFDRFJPTV9DT05GSUdfRkxBR1MoZHJpdmUpLT5kdmRfcmFtKQoJCWRldmluZm8tPm1hc2sgfD0gQ0RDX0RWRF9SQU07CglpZiAoIUNEUk9NX0NPTkZJR19GTEFHUyhkcml2ZSktPmlzX2NoYW5nZXIpCgkJZGV2aW5mby0+bWFzayB8PSBDRENfU0VMRUNUX0RJU0M7CglpZiAoIUNEUk9NX0NPTkZJR19GTEFHUyhkcml2ZSktPmF1ZGlvX3BsYXkpCgkJZGV2aW5mby0+bWFzayB8PSBDRENfUExBWV9BVURJTzsKCWlmICghQ0RST01fQ09ORklHX0ZMQUdTKGRyaXZlKS0+Y2xvc2VfdHJheSkKCQlkZXZpbmZvLT5tYXNrIHw9IENEQ19DTE9TRV9UUkFZOwoJaWYgKCFDRFJPTV9DT05GSUdfRkxBR1MoZHJpdmUpLT5tb19kcml2ZSkKCQlkZXZpbmZvLT5tYXNrIHw9IENEQ19NT19EUklWRTsKCWlmICghQ0RST01fQ09ORklHX0ZMQUdTKGRyaXZlKS0+cmFtKQoJCWRldmluZm8tPm1hc2sgfD0gQ0RDX1JBTTsKCglkZXZpbmZvLT5kaXNrID0gaW5mby0+ZGlzazsKCXJldHVybiByZWdpc3Rlcl9jZHJvbShkZXZpbmZvKTsKfQoKc3RhdGljCmludCBpZGVfY2Ryb21fcHJvYmVfY2FwYWJpbGl0aWVzIChpZGVfZHJpdmVfdCAqZHJpdmUpCnsKCXN0cnVjdCBjZHJvbV9pbmZvICppbmZvID0gZHJpdmUtPmRyaXZlcl9kYXRhOwoJc3RydWN0IGNkcm9tX2RldmljZV9pbmZvICpjZGkgPSAmaW5mby0+ZGV2aW5mbzsKCXN0cnVjdCBhdGFwaV9jYXBhYmlsaXRpZXNfcGFnZSBjYXA7CglpbnQgbnNsb3RzID0gMTsKCglpZiAoZHJpdmUtPm1lZGlhID09IGlkZV9vcHRpY2FsKSB7CgkJQ0RST01fQ09ORklHX0ZMQUdTKGRyaXZlKS0+bW9fZHJpdmUgPSAxOwoJCUNEUk9NX0NPTkZJR19GTEFHUyhkcml2ZSktPnJhbSA9IDE7CgkJcHJpbnRrKEtFUk5fRVJSICIlczogQVRBUEkgbWFnbmV0by1vcHRpY2FsIGRyaXZlXG4iLCBkcml2ZS0+bmFtZSk7CgkJcmV0dXJuIG5zbG90czsKCX0KCglpZiAoQ0RST01fQ09ORklHX0ZMQUdTKGRyaXZlKS0+bmVjMjYwIHx8CgkgICAgIXN0cmNtcChkcml2ZS0+aWQtPm1vZGVsLCJTVElOR1JBWSA4NDIyIElERSA4WCBDRC1ST00gNy0yNy05NSIpKSB7CgkJQ0RST01fQ09ORklHX0ZMQUdTKGRyaXZlKS0+bm9fZWplY3QgPSAwOwoJCUNEUk9NX0NPTkZJR19GTEFHUyhkcml2ZSktPmF1ZGlvX3BsYXkgPSAxOwoJCXJldHVybiBuc2xvdHM7Cgl9CgoJLyoKCSAqIHdlIGhhdmUgdG8gY2hlYXQgYSBsaXR0bGUgaGVyZS4gdGhlIHBhY2tldCB3aWxsIGV2ZW50dWFsbHkKCSAqIGJlIHF1ZXVlZCB3aXRoIGlkZV9jZHJvbV9wYWNrZXQoKSwgd2hpY2ggZXh0cmFjdHMgdGhlCgkgKiBkcml2ZSBmcm9tIGNkaS0+aGFuZGxlLiBTaW5jZSB0aGlzIGRldmljZSBoYXNuJ3QgYmVlbgoJICogcmVnaXN0ZXJlZCB3aXRoIHRoZSBVbmlmb3JtIGxheWVyIHlldCwgaXQgY2FuJ3QgZG8gdGhpcy4KCSAqIFNhbWUgZ29lcyBmb3IgY2RpLT5vcHMuCgkgKi8KCWNkaS0+aGFuZGxlID0gZHJpdmU7CgljZGktPm9wcyA9ICZpZGVfY2Ryb21fZG9wczsKCglpZiAoaWRlX2Nkcm9tX2dldF9jYXBhYmlsaXRpZXMoZHJpdmUsICZjYXApKQoJCXJldHVybiAwOwoKCWlmIChjYXAubG9jayA9PSAwKQoJCUNEUk9NX0NPTkZJR19GTEFHUyhkcml2ZSktPm5vX2Rvb3Jsb2NrID0gMTsKCWlmIChjYXAuZWplY3QpCgkJQ0RST01fQ09ORklHX0ZMQUdTKGRyaXZlKS0+bm9fZWplY3QgPSAwOwoJaWYgKGNhcC5jZF9yX3dyaXRlKQoJCUNEUk9NX0NPTkZJR19GTEFHUyhkcml2ZSktPmNkX3IgPSAxOwoJaWYgKGNhcC5jZF9yd193cml0ZSkgewoJCUNEUk9NX0NPTkZJR19GTEFHUyhkcml2ZSktPmNkX3J3ID0gMTsKCQlDRFJPTV9DT05GSUdfRkxBR1MoZHJpdmUpLT5yYW0gPSAxOwoJfQoJaWYgKGNhcC50ZXN0X3dyaXRlKQoJCUNEUk9NX0NPTkZJR19GTEFHUyhkcml2ZSktPnRlc3Rfd3JpdGUgPSAxOwoJaWYgKGNhcC5kdmRfcmFtX3JlYWQgfHwgY2FwLmR2ZF9yX3JlYWQgfHwgY2FwLmR2ZF9yb20pCgkJQ0RST01fQ09ORklHX0ZMQUdTKGRyaXZlKS0+ZHZkID0gMTsKCWlmIChjYXAuZHZkX3JhbV93cml0ZSkgewoJCUNEUk9NX0NPTkZJR19GTEFHUyhkcml2ZSktPmR2ZF9yYW0gPSAxOwoJCUNEUk9NX0NPTkZJR19GTEFHUyhkcml2ZSktPnJhbSA9IDE7Cgl9CglpZiAoY2FwLmR2ZF9yX3dyaXRlKQoJCUNEUk9NX0NPTkZJR19GTEFHUyhkcml2ZSktPmR2ZF9yID0gMTsKCWlmIChjYXAuYXVkaW9fcGxheSkKCQlDRFJPTV9DT05GSUdfRkxBR1MoZHJpdmUpLT5hdWRpb19wbGF5ID0gMTsKCWlmIChjYXAubWVjaHR5cGUgPT0gbWVjaHR5cGVfY2FkZHkgfHwgY2FwLm1lY2h0eXBlID09IG1lY2h0eXBlX3BvcHVwKQoJCUNEUk9NX0NPTkZJR19GTEFHUyhkcml2ZSktPmNsb3NlX3RyYXkgPSAwOwoKCS8qIFNvbWUgZHJpdmVzIHVzZWQgYnkgQXBwbGUgZG9uJ3QgYWR2ZXJ0aXNlIGF1ZGlvIHBsYXkKCSAqIGJ1dCB0aGV5IGRvIHN1cHBvcnQgcmVhZGluZyBUT0MgJiBhdWRpbyBkYXRhcwoJICovCglpZiAoc3RyY21wKGRyaXZlLT5pZC0+bW9kZWwsICJNQVRTSElUQURWRC1ST00gU1ItODE4NyIpID09IDAgfHwKCSAgICBzdHJjbXAoZHJpdmUtPmlkLT5tb2RlbCwgIk1BVFNISVRBRFZELVJPTSBTUi04MTg2IikgPT0gMCB8fAoJICAgIHN0cmNtcChkcml2ZS0+aWQtPm1vZGVsLCAiTUFUU0hJVEFEVkQtUk9NIFNSLTgxNzYiKSA9PSAwIHx8CgkgICAgc3RyY21wKGRyaXZlLT5pZC0+bW9kZWwsICJNQVRTSElUQURWRC1ST00gU1ItODE3NCIpID09IDApCgkJQ0RST01fQ09ORklHX0ZMQUdTKGRyaXZlKS0+YXVkaW9fcGxheSA9IDE7CgojaWYgISBTVEFOREFSRF9BVEFQSQoJaWYgKGNkaS0+c2FueW9fc2xvdCA+IDApIHsKCQlDRFJPTV9DT05GSUdfRkxBR1MoZHJpdmUpLT5pc19jaGFuZ2VyID0gMTsKCQluc2xvdHMgPSAzOwoJfQoKCWVsc2UKI2VuZGlmIC8qIG5vdCBTVEFOREFSRF9BVEFQSSAqLwoJaWYgKGNhcC5tZWNodHlwZSA9PSBtZWNodHlwZV9pbmRpdmlkdWFsX2NoYW5nZXIgfHwKCSAgICBjYXAubWVjaHR5cGUgPT0gbWVjaHR5cGVfY2FydHJpZGdlX2NoYW5nZXIpIHsKCQlpZiAoKG5zbG90cyA9IGNkcm9tX251bWJlcl9vZl9zbG90cyhjZGkpKSA+IDEpIHsKCQkJQ0RST01fQ09ORklHX0ZMQUdTKGRyaXZlKS0+aXNfY2hhbmdlciA9IDE7CgkJCUNEUk9NX0NPTkZJR19GTEFHUyhkcml2ZSktPnN1cHBfZGlzY19wcmVzZW50ID0gMTsKCQl9Cgl9CgoJaWRlX2Nkcm9tX3VwZGF0ZV9zcGVlZChkcml2ZSwgJmNhcCk7CgkvKiBkb24ndCBwcmludCBzcGVlZCBpZiB0aGUgZHJpdmUgcmVwb3J0ZWQgMC4KCSAqLwoJcHJpbnRrKEtFUk5fSU5GTyAiJXM6IEFUQVBJIiwgZHJpdmUtPm5hbWUpOwoJaWYgKENEUk9NX0NPTkZJR19GTEFHUyhkcml2ZSktPm1heF9zcGVlZCkKCQlwcmludGsoIiAlZFgiLCBDRFJPTV9DT05GSUdfRkxBR1MoZHJpdmUpLT5tYXhfc3BlZWQpOwoJcHJpbnRrKCIgJXMiLCBDRFJPTV9DT05GSUdfRkxBR1MoZHJpdmUpLT5kdmQgPyAiRFZELVJPTSIgOiAiQ0QtUk9NIik7CgoJaWYgKENEUk9NX0NPTkZJR19GTEFHUyhkcml2ZSktPmR2ZF9yfENEUk9NX0NPTkZJR19GTEFHUyhkcml2ZSktPmR2ZF9yYW0pCiAgICAgICAgCXByaW50aygiIERWRCVzJXMiLCAKICAgICAgICAJKENEUk9NX0NPTkZJR19GTEFHUyhkcml2ZSktPmR2ZF9yKT8gIi1SIiA6ICIiLCAKICAgICAgICAJKENEUk9NX0NPTkZJR19GTEFHUyhkcml2ZSktPmR2ZF9yYW0pPyAiLVJBTSIgOiAiIik7CgogICAgICAgIGlmIChDRFJPTV9DT05GSUdfRkxBR1MoZHJpdmUpLT5jZF9yfENEUk9NX0NPTkZJR19GTEFHUyhkcml2ZSktPmNkX3J3KSAKICAgICAgICAJcHJpbnRrKCIgQ0QlcyVzIiwgCiAgICAgICAgCShDRFJPTV9DT05GSUdfRkxBR1MoZHJpdmUpLT5jZF9yKT8gIi1SIiA6ICIiLCAKICAgICAgICAJKENEUk9NX0NPTkZJR19GTEFHUyhkcml2ZSktPmNkX3J3KT8gIi9SVyIgOiAiIik7CgogICAgICAgIGlmIChDRFJPTV9DT05GSUdfRkxBR1MoZHJpdmUpLT5pc19jaGFuZ2VyKSAKICAgICAgICAJcHJpbnRrKCIgY2hhbmdlciB3LyVkIHNsb3RzIiwgbnNsb3RzKTsKICAgICAgICBlbHNlIAkKICAgICAgICAJcHJpbnRrKCIgZHJpdmUiKTsKCglwcmludGsoIiwgJWRrQiBDYWNoZSIsIGJlMTZfdG9fY3B1KGNhcC5idWZmZXJfc2l6ZSkpOwoKCWlmIChkcml2ZS0+dXNpbmdfZG1hKQoJCWlkZV9kbWFfdmVyYm9zZShkcml2ZSk7CgoJcHJpbnRrKCJcbiIpOwoKCXJldHVybiBuc2xvdHM7Cn0KCnN0YXRpYyB2b2lkIGlkZV9jZHJvbV9hZGRfc2V0dGluZ3MoaWRlX2RyaXZlX3QgKmRyaXZlKQp7CglpZGVfYWRkX3NldHRpbmcoZHJpdmUsCSJkc2Nfb3ZlcmxhcCIsCQlTRVRUSU5HX1JXLCAtMSwgLTEsIFRZUEVfQllURSwgMCwgMSwgMSwJMSwgJmRyaXZlLT5kc2Nfb3ZlcmxhcCwgTlVMTCk7Cn0KCi8qCiAqIHN0YW5kYXJkIHByZXBfcnFfZm4gdGhhdCBidWlsZHMgMTAgYnl0ZSBjbWRzCiAqLwpzdGF0aWMgaW50IGlkZV9jZHJvbV9wcmVwX2ZzKHJlcXVlc3RfcXVldWVfdCAqcSwgc3RydWN0IHJlcXVlc3QgKnJxKQp7CglpbnQgaGFyZF9zZWN0ID0gcXVldWVfaGFyZHNlY3Rfc2l6ZShxKTsKCWxvbmcgYmxvY2sgPSAobG9uZylycS0+aGFyZF9zZWN0b3IgLyAoaGFyZF9zZWN0ID4+IDkpOwoJdW5zaWduZWQgbG9uZyBibG9ja3MgPSBycS0+aGFyZF9ucl9zZWN0b3JzIC8gKGhhcmRfc2VjdCA+PiA5KTsKCgltZW1zZXQocnEtPmNtZCwgMCwgc2l6ZW9mKHJxLT5jbWQpKTsKCglpZiAocnFfZGF0YV9kaXIocnEpID09IFJFQUQpCgkJcnEtPmNtZFswXSA9IEdQQ01EX1JFQURfMTA7CgllbHNlCgkJcnEtPmNtZFswXSA9IEdQQ01EX1dSSVRFXzEwOwoKCS8qCgkgKiBmaWxsIGluIGxiYQoJICovCglycS0+Y21kWzJdID0gKGJsb2NrID4+IDI0KSAmIDB4ZmY7CglycS0+Y21kWzNdID0gKGJsb2NrID4+IDE2KSAmIDB4ZmY7CglycS0+Y21kWzRdID0gKGJsb2NrID4+ICA4KSAmIDB4ZmY7CglycS0+Y21kWzVdID0gYmxvY2sgJiAweGZmOwoKCS8qCgkgKiBhbmQgdHJhbnNmZXIgbGVuZ3RoCgkgKi8KCXJxLT5jbWRbN10gPSAoYmxvY2tzID4+IDgpICYgMHhmZjsKCXJxLT5jbWRbOF0gPSBibG9ja3MgJiAweGZmOwoJcnEtPmNtZF9sZW4gPSAxMDsKCXJldHVybiBCTEtQUkVQX09LOwp9CgovKgogKiBNb3N0IG9mIHRoZSBTQ1NJIGNvbW1hbmRzIGFyZSBzdXBwb3J0ZWQgZGlyZWN0bHkgYnkgQVRBUEkgZGV2aWNlcy4KICogVGhpcyB0cmFuc2Zvcm0gaGFuZGxlcyB0aGUgZmV3IGV4Y2VwdGlvbnMuCiAqLwpzdGF0aWMgaW50IGlkZV9jZHJvbV9wcmVwX3BjKHN0cnVjdCByZXF1ZXN0ICpycSkKewoJdTggKmMgPSBycS0+Y21kOwoKCS8qCgkgKiBUcmFuc2Zvcm0gNi1ieXRlIHJlYWQvd3JpdGUgY29tbWFuZHMgdG8gdGhlIDEwLWJ5dGUgdmVyc2lvbgoJICovCglpZiAoY1swXSA9PSBSRUFEXzYgfHwgY1swXSA9PSBXUklURV82KSB7CgkJY1s4XSA9IGNbNF07CgkJY1s1XSA9IGNbM107CgkJY1s0XSA9IGNbMl07CgkJY1szXSA9IGNbMV0gJiAweDFmOwoJCWNbMl0gPSAwOwoJCWNbMV0gJj0gMHhlMDsKCQljWzBdICs9IChSRUFEXzEwIC0gUkVBRF82KTsKCQlycS0+Y21kX2xlbiA9IDEwOwoJCXJldHVybiBCTEtQUkVQX09LOwoJfQoKCS8qCgkgKiBpdCdzIHNpbGx5IHRvIHByZXRlbmQgd2UgdW5kZXJzdGFuZCA2LWJ5dGUgc2Vuc2UgY29tbWFuZHMsIGp1c3QKCSAqIHJlamVjdCB3aXRoIElMTEVHQUxfUkVRVUVTVCBhbmQgdGhlIGNhbGxlciBzaG91bGQgdGFrZSB0aGUKCSAqIGFwcHJvcHJpYXRlIGFjdGlvbgoJICovCglpZiAoY1swXSA9PSBNT0RFX1NFTlNFIHx8IGNbMF0gPT0gTU9ERV9TRUxFQ1QpIHsKCQlycS0+ZXJyb3JzID0gSUxMRUdBTF9SRVFVRVNUOwoJCXJldHVybiBCTEtQUkVQX0tJTEw7Cgl9CgkKCXJldHVybiBCTEtQUkVQX09LOwp9CgpzdGF0aWMgaW50IGlkZV9jZHJvbV9wcmVwX2ZuKHJlcXVlc3RfcXVldWVfdCAqcSwgc3RydWN0IHJlcXVlc3QgKnJxKQp7CglpZiAoYmxrX2ZzX3JlcXVlc3QocnEpKQoJCXJldHVybiBpZGVfY2Ryb21fcHJlcF9mcyhxLCBycSk7CgllbHNlIGlmIChibGtfcGNfcmVxdWVzdChycSkpCgkJcmV0dXJuIGlkZV9jZHJvbV9wcmVwX3BjKHJxKTsKCglyZXR1cm4gMDsKfQoKc3RhdGljCmludCBpZGVfY2Ryb21fc2V0dXAgKGlkZV9kcml2ZV90ICpkcml2ZSkKewoJc3RydWN0IGNkcm9tX2luZm8gKmluZm8gPSBkcml2ZS0+ZHJpdmVyX2RhdGE7CglzdHJ1Y3QgY2Ryb21fZGV2aWNlX2luZm8gKmNkaSA9ICZpbmZvLT5kZXZpbmZvOwoJaW50IG5zbG90czsKCglibGtfcXVldWVfcHJlcF9ycShkcml2ZS0+cXVldWUsIGlkZV9jZHJvbV9wcmVwX2ZuKTsKCWJsa19xdWV1ZV9kbWFfYWxpZ25tZW50KGRyaXZlLT5xdWV1ZSwgMzEpOwoJZHJpdmUtPnF1ZXVlLT51bnBsdWdfZGVsYXkgPSAoMSAqIEhaKSAvIDEwMDA7CglpZiAoIWRyaXZlLT5xdWV1ZS0+dW5wbHVnX2RlbGF5KQoJCWRyaXZlLT5xdWV1ZS0+dW5wbHVnX2RlbGF5ID0gMTsKCglkcml2ZS0+c3BlY2lhbC5hbGwJPSAwOwoKCUNEUk9NX1NUQVRFX0ZMQUdTKGRyaXZlKS0+bWVkaWFfY2hhbmdlZCA9IDE7CglDRFJPTV9TVEFURV9GTEFHUyhkcml2ZSktPnRvY192YWxpZCAgICAgPSAwOwoJQ0RST01fU1RBVEVfRkxBR1MoZHJpdmUpLT5kb29yX2xvY2tlZCAgID0gMDsKCiNpZiBOT19ET09SX0xPQ0tJTkcKCUNEUk9NX0NPTkZJR19GTEFHUyhkcml2ZSktPm5vX2Rvb3Jsb2NrID0gMTsKI2Vsc2UKCUNEUk9NX0NPTkZJR19GTEFHUyhkcml2ZSktPm5vX2Rvb3Jsb2NrID0gMDsKI2VuZGlmCgoJQ0RST01fQ09ORklHX0ZMQUdTKGRyaXZlKS0+ZHJxX2ludGVycnVwdCA9ICgoZHJpdmUtPmlkLT5jb25maWcgJiAweDAwNjApID09IDB4MjApOwoJQ0RST01fQ09ORklHX0ZMQUdTKGRyaXZlKS0+aXNfY2hhbmdlciA9IDA7CglDRFJPTV9DT05GSUdfRkxBR1MoZHJpdmUpLT5jZF9yID0gMDsKCUNEUk9NX0NPTkZJR19GTEFHUyhkcml2ZSktPmNkX3J3ID0gMDsKCUNEUk9NX0NPTkZJR19GTEFHUyhkcml2ZSktPnRlc3Rfd3JpdGUgPSAwOwoJQ0RST01fQ09ORklHX0ZMQUdTKGRyaXZlKS0+ZHZkID0gMDsKCUNEUk9NX0NPTkZJR19GTEFHUyhkcml2ZSktPmR2ZF9yID0gMDsKCUNEUk9NX0NPTkZJR19GTEFHUyhkcml2ZSktPmR2ZF9yYW0gPSAwOwoJQ0RST01fQ09ORklHX0ZMQUdTKGRyaXZlKS0+bm9fZWplY3QgPSAxOwoJQ0RST01fQ09ORklHX0ZMQUdTKGRyaXZlKS0+c3VwcF9kaXNjX3ByZXNlbnQgPSAwOwoJQ0RST01fQ09ORklHX0ZMQUdTKGRyaXZlKS0+YXVkaW9fcGxheSA9IDA7CglDRFJPTV9DT05GSUdfRkxBR1MoZHJpdmUpLT5jbG9zZV90cmF5ID0gMTsKCQoJLyogbGltaXQgdHJhbnNmZXIgc2l6ZSBwZXIgaW50ZXJydXB0LiAqLwoJQ0RST01fQ09ORklHX0ZMQUdTKGRyaXZlKS0+bGltaXRfbmZyYW1lcyA9IDA7CgkvKiBhIHRlc3RhbWVudCB0byB0aGUgbmljZSBxdWFsaXR5IG9mIFNhbXN1bmcgZHJpdmVzLi4uICovCglpZiAoIXN0cmNtcChkcml2ZS0+aWQtPm1vZGVsLCAiU0FNU1VORyBDRC1ST00gU0NSLTI0MzAiKSkKCQlDRFJPTV9DT05GSUdfRkxBR1MoZHJpdmUpLT5saW1pdF9uZnJhbWVzID0gMTsKCWVsc2UgaWYgKCFzdHJjbXAoZHJpdmUtPmlkLT5tb2RlbCwgIlNBTVNVTkcgQ0QtUk9NIFNDUi0yNDMyIikpCgkJQ0RST01fQ09ORklHX0ZMQUdTKGRyaXZlKS0+bGltaXRfbmZyYW1lcyA9IDE7CgkvKiB0aGUgMzIzMSBtb2RlbCBkb2VzIG5vdCBzdXBwb3J0IHRoZSBTRVRfQ0RfU1BFRUQgY29tbWFuZCAqLwoJZWxzZSBpZiAoIXN0cmNtcChkcml2ZS0+aWQtPm1vZGVsLCAiU0FNU1VORyBDRC1ST00gU0NSLTMyMzEiKSkKCQljZGktPm1hc2sgfD0gQ0RDX1NFTEVDVF9TUEVFRDsKCiNpZiAhIFNUQU5EQVJEX0FUQVBJCgkvKiBieSBkZWZhdWx0IFNhbnlvIDMgQ0QgY2hhbmdlciBzdXBwb3J0IGlzIHR1cm5lZCBvZmYgYW5kCiAgICAgICAgICAgQVRBUEkgUmV2IDIuMisgc3RhbmRhcmQgc3VwcG9ydCBmb3IgQ0QgY2hhbmdlcnMgaXMgdXNlZCAqLwoJY2RpLT5zYW55b19zbG90ID0gMDsKCglDRFJPTV9DT05GSUdfRkxBR1MoZHJpdmUpLT5uZWMyNjAgPSAwOwoJQ0RST01fQ09ORklHX0ZMQUdTKGRyaXZlKS0+dG9jdHJhY2tzX2FzX2JjZCA9IDA7CglDRFJPTV9DT05GSUdfRkxBR1MoZHJpdmUpLT50b2NhZGRyX2FzX2JjZCA9IDA7CglDRFJPTV9DT05GSUdfRkxBR1MoZHJpdmUpLT5wbGF5bXNmX2FzX2JjZCA9IDA7CglDRFJPTV9DT05GSUdfRkxBR1MoZHJpdmUpLT5zdWJjaGFuX2FzX2JjZCA9IDA7CgoJaWYgKHN0cmNtcCAoZHJpdmUtPmlkLT5tb2RlbCwgIlYwMDNTMERTIikgPT0gMCAmJgoJICAgIGRyaXZlLT5pZC0+ZndfcmV2WzRdID09ICcxJyAmJgoJICAgIGRyaXZlLT5pZC0+ZndfcmV2WzZdIDw9ICcyJykgewoJCS8qIFZlcnRvcyAzMDAuCgkJICAgU29tZSB2ZXJzaW9ucyBvZiB0aGlzIGRyaXZlIGxpa2UgdG8gdGFsayBCQ0QuICovCgkJQ0RST01fQ09ORklHX0ZMQUdTKGRyaXZlKS0+dG9jdHJhY2tzX2FzX2JjZCA9IDE7CgkJQ0RST01fQ09ORklHX0ZMQUdTKGRyaXZlKS0+dG9jYWRkcl9hc19iY2QgPSAxOwoJCUNEUk9NX0NPTkZJR19GTEFHUyhkcml2ZSktPnBsYXltc2ZfYXNfYmNkID0gMTsKCQlDRFJPTV9DT05GSUdfRkxBR1MoZHJpdmUpLT5zdWJjaGFuX2FzX2JjZCA9IDE7Cgl9CgoJZWxzZSBpZiAoc3RyY21wIChkcml2ZS0+aWQtPm1vZGVsLCAiVjAwNkUwRFMiKSA9PSAwICYmCgkgICAgZHJpdmUtPmlkLT5md19yZXZbNF0gPT0gJzEnICYmCgkgICAgZHJpdmUtPmlkLT5md19yZXZbNl0gPD0gJzInKSB7CgkJLyogVmVydG9zIDYwMCBFU0QuICovCgkJQ0RST01fQ09ORklHX0ZMQUdTKGRyaXZlKS0+dG9jdHJhY2tzX2FzX2JjZCA9IDE7Cgl9CgllbHNlIGlmIChzdHJjbXAoZHJpdmUtPmlkLT5tb2RlbCwgIk5FQyBDRC1ST00gRFJJVkU6MjYwIikgPT0gMCAmJgoJCSBzdHJuY21wKGRyaXZlLT5pZC0+ZndfcmV2LCAiMS4wMSIsIDQpID09IDApIHsgLyogRklYTUUgKi8KCQkvKiBPbGQgTkVDMjYwIChub3QgUikuCgkJICAgVGhpcyBkcml2ZSB3YXMgcmVsZWFzZWQgYmVmb3JlIHRoZSAxLjIgdmVyc2lvbgoJCSAgIG9mIHRoZSBzcGVjLiAqLwoJCUNEUk9NX0NPTkZJR19GTEFHUyhkcml2ZSktPnRvY2FkZHJfYXNfYmNkID0gMTsKCQlDRFJPTV9DT05GSUdfRkxBR1MoZHJpdmUpLT5wbGF5bXNmX2FzX2JjZCA9IDE7CgkJQ0RST01fQ09ORklHX0ZMQUdTKGRyaXZlKS0+c3ViY2hhbl9hc19iY2QgPSAxOwoJCUNEUk9NX0NPTkZJR19GTEFHUyhkcml2ZSktPm5lYzI2MCAgICAgICAgID0gMTsKCX0KCWVsc2UgaWYgKHN0cmNtcChkcml2ZS0+aWQtPm1vZGVsLCAiV0VBUk5FUyBDREQtMTIwIikgPT0gMCAmJgoJCSBzdHJuY21wKGRyaXZlLT5pZC0+ZndfcmV2LCAiQTEuMSIsIDQpID09IDApIHsgLyogRklYTUUgKi8KCQkvKiBXZWFybmVzICovCgkJQ0RST01fQ09ORklHX0ZMQUdTKGRyaXZlKS0+cGxheW1zZl9hc19iY2QgPSAxOwoJCUNEUk9NX0NPTkZJR19GTEFHUyhkcml2ZSktPnN1YmNoYW5fYXNfYmNkID0gMTsKCX0KICAgICAgICAvKiBTYW55byAzIENEIGNoYW5nZXIgdXNlcyBhIG5vbi1zdGFuZGFyZCBjb21tYW5kCiAgICAgICAgICAgZm9yIENEIGNoYW5naW5nICovCiAgICAgICAgZWxzZSBpZiAoKHN0cmNtcChkcml2ZS0+aWQtPm1vZGVsLCAiQ0QtUk9NIENEUi1DMyBHIikgPT0gMCkgfHwKICAgICAgICAgICAgICAgICAoc3RyY21wKGRyaXZlLT5pZC0+bW9kZWwsICJDRC1ST00gQ0RSLUMzRyIpID09IDApIHx8CiAgICAgICAgICAgICAgICAgKHN0cmNtcChkcml2ZS0+aWQtPm1vZGVsLCAiQ0QtUk9NIENEUl9DMzYiKSA9PSAwKSkgewogICAgICAgICAgICAgICAgIC8qIHVzZXMgQ0QgaW4gc2xvdCAwIHdoZW4gdmFsdWUgaXMgc2V0IHRvIDMgKi8KICAgICAgICAgICAgICAgICBjZGktPnNhbnlvX3Nsb3QgPSAzOwogICAgICAgIH0KI2VuZGlmIC8qIG5vdCBTVEFOREFSRF9BVEFQSSAqLwoKCWluZm8tPnRvYwkJPSBOVUxMOwoJaW5mby0+YnVmZmVyCQk9IE5VTEw7CglpbmZvLT5zZWN0b3JfYnVmZmVyZWQJPSAwOwoJaW5mby0+bnNlY3RvcnNfYnVmZmVyZWQJPSAwOwoJaW5mby0+Y2hhbmdlcl9pbmZvICAgICAgPSBOVUxMOwoJaW5mby0+bGFzdF9ibG9jawk9IDA7CglpbmZvLT5zdGFydF9zZWVrCT0gMDsKCgluc2xvdHMgPSBpZGVfY2Ryb21fcHJvYmVfY2FwYWJpbGl0aWVzIChkcml2ZSk7CgoJLyoKCSAqIHNldCBjb3JyZWN0IGJsb2NrIHNpemUKCSAqLwoJYmxrX3F1ZXVlX2hhcmRzZWN0X3NpemUoZHJpdmUtPnF1ZXVlLCBDRF9GUkFNRVNJWkUpOwoKCWlmIChkcml2ZS0+YXV0b3R1bmUgPT0gSURFX1RVTkVfREVGQVVMVCB8fAoJICAgIGRyaXZlLT5hdXRvdHVuZSA9PSBJREVfVFVORV9BVVRPKQoJCWRyaXZlLT5kc2Nfb3ZlcmxhcCA9IChkcml2ZS0+bmV4dCAhPSBkcml2ZSk7CiNpZiAwCglkcml2ZS0+ZHNjX292ZXJsYXAgPSAoSFdJRihkcml2ZSktPm5vX2RzYykgPyAwIDogMTsKCWlmIChIV0lGKGRyaXZlKS0+bm9fZHNjKSB7CgkJcHJpbnRrKEtFUk5fSU5GTyAiaWRlLWNkOiAlczogZGlzYWJsaW5nIERTQyBvdmVybGFwXG4iLAoJCQlkcml2ZS0+bmFtZSk7CgkJZHJpdmUtPmRzY19vdmVybGFwID0gMDsKCX0KI2VuZGlmCgoJaWYgKGlkZV9jZHJvbV9yZWdpc3Rlcihkcml2ZSwgbnNsb3RzKSkgewoJCXByaW50ayAoS0VSTl9FUlIgIiVzOiBpZGVfY2Ryb21fc2V0dXAgZmFpbGVkIHRvIHJlZ2lzdGVyIGRldmljZSB3aXRoIHRoZSBjZHJvbSBkcml2ZXIuXG4iLCBkcml2ZS0+bmFtZSk7CgkJaW5mby0+ZGV2aW5mby5oYW5kbGUgPSBOVUxMOwoJCXJldHVybiAxOwoJfQoJaWRlX2Nkcm9tX2FkZF9zZXR0aW5ncyhkcml2ZSk7CglyZXR1cm4gMDsKfQoKI2lmZGVmIENPTkZJR19QUk9DX0ZTCnN0YXRpYwpzZWN0b3JfdCBpZGVfY2Ryb21fY2FwYWNpdHkgKGlkZV9kcml2ZV90ICpkcml2ZSkKewoJdW5zaWduZWQgbG9uZyBjYXBhY2l0eSwgc2VjdG9yc19wZXJfZnJhbWU7CgoJaWYgKGNkcm9tX3JlYWRfY2FwYWNpdHkoZHJpdmUsICZjYXBhY2l0eSwgJnNlY3RvcnNfcGVyX2ZyYW1lLCBOVUxMKSkKCQlyZXR1cm4gMDsKCglyZXR1cm4gY2FwYWNpdHkgKiBzZWN0b3JzX3Blcl9mcmFtZTsKfQojZW5kaWYKCnN0YXRpYyB2b2lkIGlkZV9jZF9yZW1vdmUoaWRlX2RyaXZlX3QgKmRyaXZlKQp7CglzdHJ1Y3QgY2Ryb21faW5mbyAqaW5mbyA9IGRyaXZlLT5kcml2ZXJfZGF0YTsKCglpZGVfdW5yZWdpc3Rlcl9zdWJkcml2ZXIoZHJpdmUsIGluZm8tPmRyaXZlcik7CgoJZGVsX2dlbmRpc2soaW5mby0+ZGlzayk7CgoJaWRlX2NkX3B1dChpbmZvKTsKfQoKc3RhdGljIHZvaWQgaWRlX2NkX3JlbGVhc2Uoc3RydWN0IGtyZWYgKmtyZWYpCnsKCXN0cnVjdCBjZHJvbV9pbmZvICppbmZvID0gdG9faWRlX2NkKGtyZWYpOwoJc3RydWN0IGNkcm9tX2RldmljZV9pbmZvICpkZXZpbmZvID0gJmluZm8tPmRldmluZm87CglpZGVfZHJpdmVfdCAqZHJpdmUgPSBpbmZvLT5kcml2ZTsKCXN0cnVjdCBnZW5kaXNrICpnID0gaW5mby0+ZGlzazsKCglrZnJlZShpbmZvLT5idWZmZXIpOwoJa2ZyZWUoaW5mby0+dG9jKTsKCWtmcmVlKGluZm8tPmNoYW5nZXJfaW5mbyk7CglpZiAoZGV2aW5mby0+aGFuZGxlID09IGRyaXZlICYmIHVucmVnaXN0ZXJfY2Ryb20oZGV2aW5mbykpCgkJcHJpbnRrKEtFUk5fRVJSICIlczogJXMgZmFpbGVkIHRvIHVucmVnaXN0ZXIgZGV2aWNlIGZyb20gdGhlIGNkcm9tICIKCQkJCSJkcml2ZXIuXG4iLCBfX0ZVTkNUSU9OX18sIGRyaXZlLT5uYW1lKTsKCWRyaXZlLT5kc2Nfb3ZlcmxhcCA9IDA7Cglkcml2ZS0+ZHJpdmVyX2RhdGEgPSBOVUxMOwoJYmxrX3F1ZXVlX3ByZXBfcnEoZHJpdmUtPnF1ZXVlLCBOVUxMKTsKCWctPnByaXZhdGVfZGF0YSA9IE5VTEw7CglwdXRfZGlzayhnKTsKCWtmcmVlKGluZm8pOwp9CgpzdGF0aWMgaW50IGlkZV9jZF9wcm9iZShpZGVfZHJpdmVfdCAqKTsKCiNpZmRlZiBDT05GSUdfUFJPQ19GUwpzdGF0aWMgaW50IHByb2NfaWRlY2RfcmVhZF9jYXBhY2l0eQoJKGNoYXIgKnBhZ2UsIGNoYXIgKipzdGFydCwgb2ZmX3Qgb2ZmLCBpbnQgY291bnQsIGludCAqZW9mLCB2b2lkICpkYXRhKQp7CglpZGVfZHJpdmVfdCAqZHJpdmUgPSBkYXRhOwoJaW50IGxlbjsKCglsZW4gPSBzcHJpbnRmKHBhZ2UsIiVsbHVcbiIsIChsb25nIGxvbmcpaWRlX2Nkcm9tX2NhcGFjaXR5KGRyaXZlKSk7CglQUk9DX0lERV9SRUFEX1JFVFVSTihwYWdlLHN0YXJ0LG9mZixjb3VudCxlb2YsbGVuKTsKfQoKc3RhdGljIGlkZV9wcm9jX2VudHJ5X3QgaWRlY2RfcHJvY1tdID0gewoJeyAiY2FwYWNpdHkiLCBTX0lGUkVHfFNfSVJVR08sIHByb2NfaWRlY2RfcmVhZF9jYXBhY2l0eSwgTlVMTCB9LAoJeyBOVUxMLCAwLCBOVUxMLCBOVUxMIH0KfTsKI2Vsc2UKIyBkZWZpbmUgaWRlY2RfcHJvYwlOVUxMCiNlbmRpZgoKc3RhdGljIGlkZV9kcml2ZXJfdCBpZGVfY2Ryb21fZHJpdmVyID0gewoJLmdlbl9kcml2ZXIgPSB7CgkJLm93bmVyCQk9IFRISVNfTU9EVUxFLAoJCS5uYW1lCQk9ICJpZGUtY2Ryb20iLAoJCS5idXMJCT0gJmlkZV9idXNfdHlwZSwKCX0sCgkucHJvYmUJCQk9IGlkZV9jZF9wcm9iZSwKCS5yZW1vdmUJCQk9IGlkZV9jZF9yZW1vdmUsCgkudmVyc2lvbgkJPSBJREVDRF9WRVJTSU9OLAoJLm1lZGlhCQkJPSBpZGVfY2Ryb20sCgkuc3VwcG9ydHNfZHNjX292ZXJsYXAJPSAxLAoJLmRvX3JlcXVlc3QJCT0gaWRlX2RvX3J3X2Nkcm9tLAoJLmVuZF9yZXF1ZXN0CQk9IGlkZV9lbmRfcmVxdWVzdCwKCS5lcnJvcgkJCT0gX19pZGVfZXJyb3IsCgkuYWJvcnQJCQk9IF9faWRlX2Fib3J0LAoJLnByb2MJCQk9IGlkZWNkX3Byb2MsCn07CgpzdGF0aWMgaW50IGlkZWNkX29wZW4oc3RydWN0IGlub2RlICogaW5vZGUsIHN0cnVjdCBmaWxlICogZmlsZSkKewoJc3RydWN0IGdlbmRpc2sgKmRpc2sgPSBpbm9kZS0+aV9iZGV2LT5iZF9kaXNrOwoJc3RydWN0IGNkcm9tX2luZm8gKmluZm87CglpZGVfZHJpdmVfdCAqZHJpdmU7CglpbnQgcmMgPSAtRU5PTUVNOwoKCWlmICghKGluZm8gPSBpZGVfY2RfZ2V0KGRpc2spKSkKCQlyZXR1cm4gLUVOWElPOwoKCWRyaXZlID0gaW5mby0+ZHJpdmU7CgoJZHJpdmUtPnVzYWdlKys7CgoJaWYgKCFpbmZvLT5idWZmZXIpCgkJaW5mby0+YnVmZmVyID0ga21hbGxvYyhTRUNUT1JfQlVGRkVSX1NJWkUsCgkJCQkJR0ZQX0tFUk5FTHxfX0dGUF9SRVBFQVQpOwogICAgICAgIGlmICghaW5mby0+YnVmZmVyIHx8IChyYyA9IGNkcm9tX29wZW4oJmluZm8tPmRldmluZm8sIGlub2RlLCBmaWxlKSkpCgkJZHJpdmUtPnVzYWdlLS07CgoJaWYgKHJjIDwgMCkKCQlpZGVfY2RfcHV0KGluZm8pOwoKCXJldHVybiByYzsKfQoKc3RhdGljIGludCBpZGVjZF9yZWxlYXNlKHN0cnVjdCBpbm9kZSAqIGlub2RlLCBzdHJ1Y3QgZmlsZSAqIGZpbGUpCnsKCXN0cnVjdCBnZW5kaXNrICpkaXNrID0gaW5vZGUtPmlfYmRldi0+YmRfZGlzazsKCXN0cnVjdCBjZHJvbV9pbmZvICppbmZvID0gaWRlX2NkX2coZGlzayk7CglpZGVfZHJpdmVfdCAqZHJpdmUgPSBpbmZvLT5kcml2ZTsKCgljZHJvbV9yZWxlYXNlICgmaW5mby0+ZGV2aW5mbywgZmlsZSk7Cglkcml2ZS0+dXNhZ2UtLTsKCglpZGVfY2RfcHV0KGluZm8pOwoKCXJldHVybiAwOwp9CgpzdGF0aWMgaW50IGlkZWNkX3NldF9zcGluZG93bihzdHJ1Y3QgY2Ryb21fZGV2aWNlX2luZm8gKmNkaSwgdW5zaWduZWQgbG9uZyBhcmcpCnsKCXN0cnVjdCBwYWNrZXRfY29tbWFuZCBjZ2M7CgljaGFyIGJ1ZmZlclsxNl07CglpbnQgc3RhdDsKCWNoYXIgc3BpbmRvd247CgoJaWYgKGNvcHlfZnJvbV91c2VyKCZzcGluZG93biwgKHZvaWQgX191c2VyICopYXJnLCBzaXplb2YoY2hhcikpKQoJCXJldHVybiAtRUZBVUxUOwoKCWluaXRfY2Ryb21fY29tbWFuZCgmY2djLCBidWZmZXIsIHNpemVvZihidWZmZXIpLCBDR0NfREFUQV9VTktOT1dOKTsKCglzdGF0ID0gY2Ryb21fbW9kZV9zZW5zZShjZGksICZjZ2MsIEdQTU9ERV9DRFJPTV9QQUdFLCAwKTsKCWlmIChzdGF0KQoJCXJldHVybiBzdGF0OwoKCWJ1ZmZlclsxMV0gPSAoYnVmZmVyWzExXSAmIDB4ZjApIHwgKHNwaW5kb3duICYgMHgwZik7CglyZXR1cm4gY2Ryb21fbW9kZV9zZWxlY3QoY2RpLCAmY2djKTsKfQoKc3RhdGljIGludCBpZGVjZF9nZXRfc3BpbmRvd24oc3RydWN0IGNkcm9tX2RldmljZV9pbmZvICpjZGksIHVuc2lnbmVkIGxvbmcgYXJnKQp7CglzdHJ1Y3QgcGFja2V0X2NvbW1hbmQgY2djOwoJY2hhciBidWZmZXJbMTZdOwoJaW50IHN0YXQ7CiAJY2hhciBzcGluZG93bjsKCglpbml0X2Nkcm9tX2NvbW1hbmQoJmNnYywgYnVmZmVyLCBzaXplb2YoYnVmZmVyKSwgQ0dDX0RBVEFfVU5LTk9XTik7CgoJc3RhdCA9IGNkcm9tX21vZGVfc2Vuc2UoY2RpLCAmY2djLCBHUE1PREVfQ0RST01fUEFHRSwgMCk7CglpZiAoc3RhdCkKCQlyZXR1cm4gc3RhdDsKCglzcGluZG93biA9IGJ1ZmZlclsxMV0gJiAweDBmOwoJaWYgKGNvcHlfdG9fdXNlcigodm9pZCBfX3VzZXIgKilhcmcsICZzcGluZG93biwgc2l6ZW9mIChjaGFyKSkpCgkJcmV0dXJuIC1FRkFVTFQ7CglyZXR1cm4gMDsKfQoKc3RhdGljIGludCBpZGVjZF9pb2N0bCAoc3RydWN0IGlub2RlICppbm9kZSwgc3RydWN0IGZpbGUgKmZpbGUsCgkJCXVuc2lnbmVkIGludCBjbWQsIHVuc2lnbmVkIGxvbmcgYXJnKQp7CglzdHJ1Y3QgYmxvY2tfZGV2aWNlICpiZGV2ID0gaW5vZGUtPmlfYmRldjsKCXN0cnVjdCBjZHJvbV9pbmZvICppbmZvID0gaWRlX2NkX2coYmRldi0+YmRfZGlzayk7CglpbnQgZXJyOwoKCXN3aXRjaCAoY21kKSB7CiAJY2FzZSBDRFJPTVNFVFNQSU5ET1dOOgoJCXJldHVybiBpZGVjZF9zZXRfc3BpbmRvd24oJmluZm8tPmRldmluZm8sIGFyZyk7CiAJY2FzZSBDRFJPTUdFVFNQSU5ET1dOOgoJCXJldHVybiBpZGVjZF9nZXRfc3BpbmRvd24oJmluZm8tPmRldmluZm8sIGFyZyk7CglkZWZhdWx0OgoJCWJyZWFrOwogCX0KCgllcnIgPSBnZW5lcmljX2lkZV9pb2N0bChpbmZvLT5kcml2ZSwgZmlsZSwgYmRldiwgY21kLCBhcmcpOwoJaWYgKGVyciA9PSAtRUlOVkFMKQoJCWVyciA9IGNkcm9tX2lvY3RsKGZpbGUsICZpbmZvLT5kZXZpbmZvLCBpbm9kZSwgY21kLCBhcmcpOwoKCXJldHVybiBlcnI7Cn0KCnN0YXRpYyBpbnQgaWRlY2RfbWVkaWFfY2hhbmdlZChzdHJ1Y3QgZ2VuZGlzayAqZGlzaykKewoJc3RydWN0IGNkcm9tX2luZm8gKmluZm8gPSBpZGVfY2RfZyhkaXNrKTsKCXJldHVybiBjZHJvbV9tZWRpYV9jaGFuZ2VkKCZpbmZvLT5kZXZpbmZvKTsKfQoKc3RhdGljIGludCBpZGVjZF9yZXZhbGlkYXRlX2Rpc2soc3RydWN0IGdlbmRpc2sgKmRpc2spCnsKCXN0cnVjdCBjZHJvbV9pbmZvICppbmZvID0gaWRlX2NkX2coZGlzayk7CglzdHJ1Y3QgcmVxdWVzdF9zZW5zZSBzZW5zZTsKCWNkcm9tX3JlYWRfdG9jKGluZm8tPmRyaXZlLCAmc2Vuc2UpOwoJcmV0dXJuICAwOwp9CgpzdGF0aWMgc3RydWN0IGJsb2NrX2RldmljZV9vcGVyYXRpb25zIGlkZWNkX29wcyA9IHsKCS5vd25lcgkJPSBUSElTX01PRFVMRSwKCS5vcGVuCQk9IGlkZWNkX29wZW4sCgkucmVsZWFzZQk9IGlkZWNkX3JlbGVhc2UsCgkuaW9jdGwJCT0gaWRlY2RfaW9jdGwsCgkubWVkaWFfY2hhbmdlZAk9IGlkZWNkX21lZGlhX2NoYW5nZWQsCgkucmV2YWxpZGF0ZV9kaXNrPSBpZGVjZF9yZXZhbGlkYXRlX2Rpc2sKfTsKCi8qIG9wdGlvbnMgKi8Kc3RhdGljIGNoYXIgKmlnbm9yZSA9IE5VTEw7Cgptb2R1bGVfcGFyYW0oaWdub3JlLCBjaGFycCwgMDQwMCk7Ck1PRFVMRV9ERVNDUklQVElPTigiQVRBUEkgQ0QtUk9NIERyaXZlciIpOwoKc3RhdGljIGludCBpZGVfY2RfcHJvYmUoaWRlX2RyaXZlX3QgKmRyaXZlKQp7CglzdHJ1Y3QgY2Ryb21faW5mbyAqaW5mbzsKCXN0cnVjdCBnZW5kaXNrICpnOwoJc3RydWN0IHJlcXVlc3Rfc2Vuc2Ugc2Vuc2U7CgoJaWYgKCFzdHJzdHIoImlkZS1jZHJvbSIsIGRyaXZlLT5kcml2ZXJfcmVxKSkKCQlnb3RvIGZhaWxlZDsKCWlmICghZHJpdmUtPnByZXNlbnQpCgkJZ290byBmYWlsZWQ7CglpZiAoZHJpdmUtPm1lZGlhICE9IGlkZV9jZHJvbSAmJiBkcml2ZS0+bWVkaWEgIT0gaWRlX29wdGljYWwpCgkJZ290byBmYWlsZWQ7CgkvKiBza2lwIGRyaXZlcyB0aGF0IHdlIHdlcmUgdG9sZCB0byBpZ25vcmUgKi8KCWlmIChpZ25vcmUgIT0gTlVMTCkgewoJCWlmIChzdHJzdHIoaWdub3JlLCBkcml2ZS0+bmFtZSkpIHsKCQkJcHJpbnRrKEtFUk5fSU5GTyAiaWRlLWNkOiBpZ25vcmluZyBkcml2ZSAlc1xuIiwgZHJpdmUtPm5hbWUpOwoJCQlnb3RvIGZhaWxlZDsKCQl9Cgl9CglpZiAoZHJpdmUtPnNjc2kpIHsKCQlwcmludGsoS0VSTl9JTkZPICJpZGUtY2Q6IHBhc3NpbmcgZHJpdmUgJXMgdG8gaWRlLXNjc2kgZW11bGF0aW9uLlxuIiwgZHJpdmUtPm5hbWUpOwoJCWdvdG8gZmFpbGVkOwoJfQoJaW5mbyA9IGt6YWxsb2Moc2l6ZW9mKHN0cnVjdCBjZHJvbV9pbmZvKSwgR0ZQX0tFUk5FTCk7CglpZiAoaW5mbyA9PSBOVUxMKSB7CgkJcHJpbnRrKEtFUk5fRVJSICIlczogQ2FuJ3QgYWxsb2NhdGUgYSBjZHJvbSBzdHJ1Y3R1cmVcbiIsIGRyaXZlLT5uYW1lKTsKCQlnb3RvIGZhaWxlZDsKCX0KCglnID0gYWxsb2NfZGlzaygxIDw8IFBBUlROX0JJVFMpOwoJaWYgKCFnKQoJCWdvdG8gb3V0X2ZyZWVfY2Q7CgoJaWRlX2luaXRfZGlzayhnLCBkcml2ZSk7CgoJaWRlX3JlZ2lzdGVyX3N1YmRyaXZlcihkcml2ZSwgJmlkZV9jZHJvbV9kcml2ZXIpOwoKCWtyZWZfaW5pdCgmaW5mby0+a3JlZik7CgoJaW5mby0+ZHJpdmUgPSBkcml2ZTsKCWluZm8tPmRyaXZlciA9ICZpZGVfY2Ryb21fZHJpdmVyOwoJaW5mby0+ZGlzayA9IGc7CgoJZy0+cHJpdmF0ZV9kYXRhID0gJmluZm8tPmRyaXZlcjsKCglkcml2ZS0+ZHJpdmVyX2RhdGEgPSBpbmZvOwoKCWctPm1pbm9ycyA9IDE7CglnLT5kcml2ZXJmc19kZXYgPSAmZHJpdmUtPmdlbmRldjsKCWctPmZsYWdzID0gR0VOSERfRkxfQ0QgfCBHRU5IRF9GTF9SRU1PVkFCTEU7CglpZiAoaWRlX2Nkcm9tX3NldHVwKGRyaXZlKSkgewoJCXN0cnVjdCBjZHJvbV9kZXZpY2VfaW5mbyAqZGV2aW5mbyA9ICZpbmZvLT5kZXZpbmZvOwoJCWlkZV91bnJlZ2lzdGVyX3N1YmRyaXZlcihkcml2ZSwgJmlkZV9jZHJvbV9kcml2ZXIpOwoJCWtmcmVlKGluZm8tPmJ1ZmZlcik7CgkJa2ZyZWUoaW5mby0+dG9jKTsKCQlrZnJlZShpbmZvLT5jaGFuZ2VyX2luZm8pOwoJCWlmIChkZXZpbmZvLT5oYW5kbGUgPT0gZHJpdmUgJiYgdW5yZWdpc3Rlcl9jZHJvbShkZXZpbmZvKSkKCQkJcHJpbnRrIChLRVJOX0VSUiAiJXM6IGlkZV9jZHJvbV9jbGVhbnVwIGZhaWxlZCB0byB1bnJlZ2lzdGVyIGRldmljZSBmcm9tIHRoZSBjZHJvbSBkcml2ZXIuXG4iLCBkcml2ZS0+bmFtZSk7CgkJa2ZyZWUoaW5mbyk7CgkJZHJpdmUtPmRyaXZlcl9kYXRhID0gTlVMTDsKCQlnb3RvIGZhaWxlZDsKCX0KCgljZHJvbV9yZWFkX3RvYyhkcml2ZSwgJnNlbnNlKTsKCWctPmZvcHMgPSAmaWRlY2Rfb3BzOwoJZy0+ZmxhZ3MgfD0gR0VOSERfRkxfUkVNT1ZBQkxFOwoJYWRkX2Rpc2soZyk7CglyZXR1cm4gMDsKCm91dF9mcmVlX2NkOgoJa2ZyZWUoaW5mbyk7CmZhaWxlZDoKCXJldHVybiAtRU5PREVWOwp9CgpzdGF0aWMgdm9pZCBfX2V4aXQgaWRlX2Nkcm9tX2V4aXQodm9pZCkKewoJZHJpdmVyX3VucmVnaXN0ZXIoJmlkZV9jZHJvbV9kcml2ZXIuZ2VuX2RyaXZlcik7Cn0KCnN0YXRpYyBpbnQgX19pbml0IGlkZV9jZHJvbV9pbml0KHZvaWQpCnsKCXJldHVybiBkcml2ZXJfcmVnaXN0ZXIoJmlkZV9jZHJvbV9kcml2ZXIuZ2VuX2RyaXZlcik7Cn0KCk1PRFVMRV9BTElBUygiaWRlOiptLWNkcm9tKiIpOwptb2R1bGVfaW5pdChpZGVfY2Ryb21faW5pdCk7Cm1vZHVsZV9leGl0KGlkZV9jZHJvbV9leGl0KTsKTU9EVUxFX0xJQ0VOU0UoIkdQTCIpOwo=