LyoKICogbGludXgvZHJpdmVycy9pZGUvaWRlLWNkLmMKICoKICogQ29weXJpZ2h0IChDKSAxOTk0LCAxOTk1LCAxOTk2ICBzY290dCBzbnlkZXIgIDxzbnlkZXJAZm5hbGQwLmZuYWwuZ292PgogKiBDb3B5cmlnaHQgKEMpIDE5OTYtMTk5OCAgRXJpayBBbmRlcnNlbiA8YW5kZXJzZWVAZGViaWFuLm9yZz4KICogQ29weXJpZ2h0IChDKSAxOTk4LTIwMDAgIEplbnMgQXhib2UgPGF4Ym9lQHN1c2UuZGU+CiAqCiAqIE1heSBiZSBjb3BpZWQgb3IgbW9kaWZpZWQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMKICogTGljZW5zZS4gIFNlZSBsaW51eC9DT1BZSU5HIGZvciBtb3JlIGluZm9ybWF0aW9uLgogKgogKiBBVEFQSSBDRC1ST00gZHJpdmVyLiAgVG8gYmUgdXNlZCB3aXRoIGlkZS5jLgogKiBTZWUgRG9jdW1lbnRhdGlvbi9jZHJvbS9pZGUtY2QgZm9yIHVzYWdlIGluZm9ybWF0aW9uLgogKgogKiBTdWdnZXN0aW9ucyBhcmUgd2VsY29tZS4gUGF0Y2hlcyB0aGF0IHdvcmsgYXJlIG1vcmUgd2VsY29tZSB0aG91Z2guIDstKQogKiBGb3IgdGhvc2Ugd2lzaGluZyB0byB3b3JrIG9uIHRoaXMgZHJpdmVyLCBwbGVhc2UgYmUgc3VyZSB5b3UgZG93bmxvYWQKICogYW5kIGNvbXBseSB3aXRoIHRoZSBsYXRlc3QgTXQuIEZ1amkgKFNGRjgwOTAgdmVyc2lvbiA0KSBhbmQgQVRBUEkgCiAqIChTRkYtODAyMGkgcmV2IDIuNikgc3RhbmRhcmRzLiBUaGVzZSBkb2N1bWVudHMgY2FuIGJlIG9idGFpbmVkIGJ5IAogKiBhbm9ueW1vdXMgZnRwIGZyb206CiAqIGZ0cDovL2Zpc3Npb24uZHQud2RjLmNvbS9wdWIvc3RhbmRhcmRzL1NGRl9hdGFwaS9zcGVjL1NGRjgwMjAtcjIuNi9QUy84MDIwcjI2LnBzCiAqIGZ0cDovL2Z0cC5hdmMtcGlvbmVlci5jb20vTXRmdWppNC9TcGVjL0Z1amk0cjEwLnBkZgogKgogKiBEcml2ZXMgdGhhdCBkZXZpYXRlIGZyb20gdGhlc2Ugc3RhbmRhcmRzIHdpbGwgYmUgYWNjb21tb2RhdGVkIGFzIG11Y2gKICogYXMgcG9zc2libGUgdmlhIGNvbXBpbGUgdGltZSBvciBjb21tYW5kLWxpbmUgb3B0aW9ucy4gIFNpbmNlIEkgb25seSBoYXZlCiAqIGEgZmV3IGRyaXZlcywgeW91IGdlbmVyYWxseSBuZWVkIHRvIHNlbmQgbWUgcGF0Y2hlcy4uLgogKgogKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAqIFRPIERPIExJU1Q6CiAqIC1NYWtlIGl0IHNvIHRoYXQgUGlvbmVlciBDRCBEUi1BMjRYIGFuZCBmcmllbmRzIGRvbid0IGdldCBzY3Jld2VkIHVwIG9uCiAqICAgYm9vdAogKgogKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAqIDEuMDAgIE9jdCAzMSwgMTk5NCAtLSBJbml0aWFsIHZlcnNpb24uCiAqIDEuMDEgIE5vdiAgMiwgMTk5NCAtLSBGaXhlZCBwcm9ibGVtIHdpdGggc3RhcnRpbmcgcmVxdWVzdCBpbgogKiAgICAgICAgICAgICAgICAgICAgICAgY2Ryb21fY2hlY2tfc3RhdHVzLgogKiAxLjAzICBOb3YgMjUsIDE5OTQgLS0gbGVhdmluZyB1bm1hc2tfaW50cltdIGFzIGEgdXNlci1zZXR0aW5nIChhcyBmb3IgZGlza3MpCiAqIChmcm9tIG1sb3JkKSAgICAgICAtLSBtaW5vciBjaGFuZ2VzIHRvIGNkcm9tX3NldHVwKCkKICogICAgICAgICAgICAgICAgICAgIC0tIHJlbmFtZWQgaWRlX2Rldl9zIHRvIGlkZV9kcml2ZV90LCBlbmFibGUgaXJxIG9uIGNvbW1hbmQKICogMi4wMCAgTm92IDI3LCAxOTk0IC0tIEdlbmVyYWxpemUgcGFja2V0IGNvbW1hbmQgaW50ZXJmYWNlOwogKiAgICAgICAgICAgICAgICAgICAgICAgYWRkIGF1ZGlvIGlvY3Rscy4KICogMi4wMSAgRGVjICAzLCAxOTk0IC0tIFJld29yayBwYWNrZXQgY29tbWFuZCBpbnRlcmZhY2UgdG8gaGFuZGxlIGRldmljZXMKICogICAgICAgICAgICAgICAgICAgICAgIHdoaWNoIHNlbmQgYW4gaW50ZXJydXB0IHdoZW4gcmVhZHkgZm9yIGEgY29tbWFuZC4KICogMi4wMiAgRGVjIDExLCAxOTk0IC0tIENhY2hlIHRoZSBUT0MgaW4gdGhlIGRyaXZlci4KICogICAgICAgICAgICAgICAgICAgICAgIERvbid0IHVzZSBTQ01EX1BMQVlBVURJT19USTsgaXQncyBub3QgaW5jbHVkZWQKICogICAgICAgICAgICAgICAgICAgICAgIGluIHRoZSBjdXJyZW50IHZlcnNpb24gb2YgQVRBUEkuCiAqICAgICAgICAgICAgICAgICAgICAgICBUcnkgdG8gdXNlIExCQSBpbnN0ZWFkIG9mIHRyYWNrIG9yIE1TRiBhZGRyZXNzaW5nCiAqICAgICAgICAgICAgICAgICAgICAgICB3aGVuIHBvc3NpYmxlLgogKiAgICAgICAgICAgICAgICAgICAgICAgRG9uJ3Qgd2FpdCBmb3IgUkVBRFlfU1RBVC4KICogMi4wMyAgSmFuIDEwLCAxOTk1IC0tIFJld3JpdGUgYmxvY2sgcmVhZCByb3V0aW5lcyB0byBoYW5kbGUgYmxvY2sgc2l6ZXMKICogICAgICAgICAgICAgICAgICAgICAgIG90aGVyIHRoYW4gMmsgYW5kIHRvIG1vdmUgbXVsdGlwbGUgc2VjdG9ycyBpbiBhCiAqICAgICAgICAgICAgICAgICAgICAgICBzaW5nbGUgdHJhbnNhY3Rpb24uCiAqIDIuMDQgIEFwciAyMSwgMTk5NSAtLSBBZGQgd29yay1hcm91bmQgZm9yIENyZWF0aXZlIExhYnMgQ0QyMjBFIGRyaXZlcy4KICogICAgICAgICAgICAgICAgICAgICAgIFRoYW5rcyB0byBOaWNrIFNhdyA8Y3dzYXdAcHRzNy5wdHMubW90LmNvbT4gZm9yCiAqICAgICAgICAgICAgICAgICAgICAgICBoZWxwIGluIGZpZ3VyaW5nIHRoaXMgb3V0LiAgRGl0dG8gZm9yIEFjZXIgYW5kCiAqICAgICAgICAgICAgICAgICAgICAgICBBenRlY2ggZHJpdmVzLCB3aGljaCBzZWVtIHRvIGhhdmUgdGhlIHNhbWUgcHJvYmxlbS4KICogMi4wNGIgTWF5IDMwLCAxOTk1IC0tIEZpeCB0byBtYXRjaCBjaGFuZ2VzIGluIGlkZS5jIHZlcnNpb24gMy4xNiAtbWwKICogMi4wNSAgSnVuICA4LCAxOTk1IC0tIERvbid0IGF0dGVtcHQgdG8gcmV0cnkgYWZ0ZXIgYW4gaWxsZWdhbCByZXF1ZXN0CiAqICAgICAgICAgICAgICAgICAgICAgICAgb3IgZGF0YSBwcm90ZWN0IGVycm9yLgogKiAgICAgICAgICAgICAgICAgICAgICAgVXNlIEhXSUYgYW5kIERFVl9IV0lGIG1hY3JvcyBhcyBpbiBpZGUuYy4KICogICAgICAgICAgICAgICAgICAgICAgIEFsd2F5cyB0cnkgdG8gZG8gYSByZXF1ZXN0X3NlbnNlIGFmdGVyCiAqICAgICAgICAgICAgICAgICAgICAgICAgYSBmYWlsZWQgY29tbWFuZC4KICogICAgICAgICAgICAgICAgICAgICAgIEluY2x1ZGUgYW4gb3B0aW9uIHRvIGdpdmUgdGV4dHVhbCBkZXNjcmlwdGlvbnMKICogICAgICAgICAgICAgICAgICAgICAgICBvZiBBVEFQSSBlcnJvcnMuCiAqICAgICAgICAgICAgICAgICAgICAgICBGaXggYSBidWcgaW4gaGFuZGxpbmcgdGhlIHNlY3RvciBjYWNoZSB3aGljaAogKiAgICAgICAgICAgICAgICAgICAgICAgIHNob3dlZCB1cCBpZiB0aGUgZHJpdmUgcmV0dXJuZWQgZGF0YSBpbiA1MTIgYnl0ZQogKiAgICAgICAgICAgICAgICAgICAgICAgIGJsb2NrcyAobGlrZSBQaW9uZWVyIGRyaXZlcykuICBUaGFua3MgdG8KICogICAgICAgICAgICAgICAgICAgICAgICBSaWNoYXJkIEhpcnN0IDxzcmhAZ3B0LmNvLnVrPiBmb3IgZGlhZ25vc2luZyB0aGlzLgogKiAgICAgICAgICAgICAgICAgICAgICAgUHJvcGVybHkgc3VwcGx5IHRoZSBwYWdlIG51bWJlciBmaWVsZCBpbiB0aGUKICogICAgICAgICAgICAgICAgICAgICAgICBNT0RFX1NFTEVDVCBjb21tYW5kLgogKiAgICAgICAgICAgICAgICAgICAgICAgUExBWUFVRElPMTIgaXMgYnJva2VuIG9uIHRoZSBBenRlY2g7IHdvcmsgYXJvdW5kIGl0LgogKiAyLjA1eCBBdWcgMTEsIDE5OTUgLS0gbG90cyBvZiBkYXRhIHN0cnVjdHVyZSByZW5hbWluZy9yZXN0cnVjdHVyaW5nIGluIGlkZS5jCiAqICAgICAgICAgICAgICAgICAgICAgICAobXkgYXBvbG9naWVzIHRvIFNjb3R0LCBidXQgbm93IGlkZS1jZC5jIGlzIGluZGVwZW5kZW50KQogKiAzLjAwICBBdWcgMjIsIDE5OTUgLS0gSW1wbGVtZW50IENEUk9NTVVMVElTRVNTSU9OIGlvY3RsLgogKiAgICAgICAgICAgICAgICAgICAgICAgSW1wbGVtZW50IENEUk9NUkVBREFVRElPIGlvY3RsIChVTlRFU1RFRCkuCiAqICAgICAgICAgICAgICAgICAgICAgICBVc2UgaW5wdXRfaWRlX2RhdGEoKSBhbmQgb3V0cHV0X2lkZV9kYXRhKCkuCiAqICAgICAgICAgICAgICAgICAgICAgICBBZGQgZG9vciBsb2NraW5nLgogKiAgICAgICAgICAgICAgICAgICAgICAgRml4IHVzYWdlIGNvdW50IGxlYWsgaW4gY2Ryb21fb3Blbiwgd2hpY2ggaGFwcGVuZWQKICogICAgICAgICAgICAgICAgICAgICAgICB3aGVuIGEgcmVhZC13cml0ZSBtb3VudCB3YXMgYXR0ZW1wdGVkLgogKiAgICAgICAgICAgICAgICAgICAgICAgVHJ5IHRvIGxvYWQgdGhlIGRpc2sgb24gb3Blbi4KICogICAgICAgICAgICAgICAgICAgICAgIEltcGxlbWVudCBDRFJPTUVKRUNUX1NXIGlvY3RsIChvZmYgYnkgZGVmYXVsdCkuCiAqICAgICAgICAgICAgICAgICAgICAgICBSZWFkIHRvdGFsIGNkcm9tIGNhcGFjaXR5IGR1cmluZyBvcGVuLgogKiAgICAgICAgICAgICAgICAgICAgICAgUmVhcnJhbmdlIGxvZ2ljIGluIGNkcm9tX2RlY29kZV9zdGF0dXMuICBJc3N1ZQogKiAgICAgICAgICAgICAgICAgICAgICAgIHJlcXVlc3Qgc2Vuc2UgY29tbWFuZHMgZm9yIGZhaWxlZCBwYWNrZXQgY29tbWFuZHMKICogICAgICAgICAgICAgICAgICAgICAgICBmcm9tIGhlcmUgaW5zdGVhZCBvZiBmcm9tIGNkcm9tX3F1ZXVlX3BhY2tldF9jb21tYW5kLgogKiAgICAgICAgICAgICAgICAgICAgICAgIEZpeCBhIHJhY2UgY29uZGl0aW9uIGluIHJldHJpZXZpbmcgZXJyb3IgaW5mb3JtYXRpb24uCiAqICAgICAgICAgICAgICAgICAgICAgICBTdXBwcmVzcyBwcmludGluZyBub3JtYWwgdW5pdCBhdHRlbnRpb24gZXJyb3JzIGFuZAogKiAgICAgICAgICAgICAgICAgICAgICAgIHNvbWUgZHJpdmUgbm90IHJlYWR5IGVycm9ycy4KICogICAgICAgICAgICAgICAgICAgICAgIEltcGxlbWVudCBDRFJPTVZPTFJFQUQgaW9jdGwuCiAqICAgICAgICAgICAgICAgICAgICAgICBJbXBsZW1lbnQgQ0RST01SRUFETU9ERTEvMiBpb2N0bHMuCiAqICAgICAgICAgICAgICAgICAgICAgICBGaXggcmFjZSBjb25kaXRpb24gaW4gc2V0dGluZyB1cCBpbnRlcnJ1cHQgaGFuZGxlcnMKICogICAgICAgICAgICAgICAgICAgICAgICB3aGVuIHRoZSBgc2VyaWFsaXplJyBvcHRpb24gaXMgdXNlZC4KICogMy4wMSAgU2VwICAyLCAxOTk1IC0tIEZpeCBvcmRlcmluZyBvZiByZWVuYWJsaW5nIGludGVycnVwdHMgaW4KICogICAgICAgICAgICAgICAgICAgICAgICBjZHJvbV9xdWV1ZV9yZXF1ZXN0LgogKiAgICAgICAgICAgICAgICAgICAgICAgQW5vdGhlciB0cnkgYXQgdXNpbmcgaWRlX1tpbnB1dCxvdXRwdXRdX2RhdGEuCiAqIDMuMDIgIFNlcCAxNiwgMTk5NSAtLSBTdGljayB0b3RhbCBkaXNrIGNhcGFjaXR5IGluIHBhcnRpdGlvbiB0YWJsZSBhcyB3ZWxsLgogKiAgICAgICAgICAgICAgICAgICAgICAgTWFrZSBWRVJCT1NFX0lERV9DRF9FUlJPUlMgZHVtcCBmYWlsZWQgY29tbWFuZCBhZ2Fpbi4KICogICAgICAgICAgICAgICAgICAgICAgIER1bXAgb3V0IG1vcmUgaW5mb3JtYXRpb24gZm9yIElMTEVHQUwgUkVRVUVTVCBlcnJzLgogKiAgICAgICAgICAgICAgICAgICAgICAgRml4IGhhbmRsaW5nIG9mIGVycm9ycyBvY2N1cnJpbmcgYmVmb3JlIHRoZQogKiAgICAgICAgICAgICAgICAgICAgICAgIHBhY2tldCBjb21tYW5kIGlzIHRyYW5zZmVycmVkLgogKiAgICAgICAgICAgICAgICAgICAgICAgRml4IHRyYW5zZmVycyB3aXRoIG9kZCBieXRlbGVuZ3Rocy4KICogMy4wMyAgT2N0IDI3LCAxOTk1IC0tIFNvbWUgQ3JlYXRpdmUgZHJpdmVzIGhhdmUgYW4gaWQgb2YganVzdCBgQ0QnLgogKiAgICAgICAgICAgICAgICAgICAgICAgYERDSS0yUzEwJyBkcml2ZXMgYXJlIGJyb2tlbiB0b28uCiAqIDMuMDQgIE5vdiAyMCwgMTk5NSAtLSBTbyBhcmUgVmVydG9zIGRyaXZlcy4KICogMy4wNSAgRGVjICAxLCAxOTk1IC0tIENoYW5nZXMgdG8gZ28gd2l0aCBvdmVyaGF1bCBvZiBpZGUuYyBhbmQgaWRlLXRhcGUuYwogKiAzLjA2ICBEZWMgMTYsIDE5OTUgLS0gQWRkIHN1cHBvcnQgbmVlZGVkIGZvciBwYXJ0aXRpb25zLgogKiAgICAgICAgICAgICAgICAgICAgICAgTW9yZSB3b3JrYXJvdW5kcyBmb3IgVmVydG9zIGJ1Z3MgKGJhc2VkIG9uIHBhdGNoZXMKICogICAgICAgICAgICAgICAgICAgICAgICBmcm9tIEhvbGdlciBEaWV0emUgPGRpZXR6ZUBhaXg1MjAuaW5mb3JtYXRpay51bmktbGVpcHppZy5kZT4pLgogKiAgICAgICAgICAgICAgICAgICAgICAgVHJ5IHRvIGVsaW1pbmF0ZSBieXRlb3JkZXIgYXNzdW1wdGlvbnMuCiAqICAgICAgICAgICAgICAgICAgICAgICBVc2UgYXRhcGlfY2Ryb21fc3ViY2hubCBzdHJ1Y3QgZGVmaW5pdGlvbi4KICogICAgICAgICAgICAgICAgICAgICAgIEFkZCBTVEFOREFSRF9BVEFQSSBjb21waWxhdGlvbiBvcHRpb24uCiAqIDMuMDcgIEphbiAyOSwgMTk5NiAtLSBNb3JlIHR3aWRkbGluZyBmb3IgYnJva2VuIGRyaXZlczogU29ueSA1NUQsCiAqICAgICAgICAgICAgICAgICAgICAgICAgVmVydG9zIDMwMC4KICogICAgICAgICAgICAgICAgICAgICAgIEFkZCBOT19ET09SX0xPQ0tJTkcgY29uZmlndXJhdGlvbiBvcHRpb24uCiAqICAgICAgICAgICAgICAgICAgICAgICBIYW5kbGUgZHJpdmVfY21kIHJlcXVlc3RzIHcvTlVMTCBhcmdzIChmb3IgaGRwYXJtIC10KS4KICogICAgICAgICAgICAgICAgICAgICAgIFdvcmsgYXJvdW5kIHNwb3JhZGljIFNvbnk1NWUgYXVkaW8gcGxheSBwcm9ibGVtLgogKiAzLjA3YSBGZWIgMTEsIDE5OTYgLS0gY2hlY2sgZHJpdmUtPmlkIGZvciBOVUxMIGJlZm9yZSBkZXJlZmVyZW5jaW5nLCB0byBmaXgKICogICAgICAgICAgICAgICAgICAgICAgICBwcm9ibGVtIHdpdGggImhkZT1jZHJvbSIgd2l0aCBubyBkcml2ZSBwcmVzZW50LiAgLW1sCiAqIDMuMDggIE1hciAgNiwgMTk5NiAtLSBNb3JlIFZlcnRvcyB3b3JrYXJvdW5kcy4KICogMy4wOSAgQXByICA1LCAxOTk2IC0tIEFkZCBDRFJPTUNMT1NFVFJBWSBpb2N0bC4KICogICAgICAgICAgICAgICAgICAgICAgIFN3aXRjaCB0byB1c2luZyBNU0YgYWRkcmVzc2luZyBmb3IgYXVkaW8gY29tbWFuZHMuCiAqICAgICAgICAgICAgICAgICAgICAgICBSZWZvcm1hdCB0byBtYXRjaCBrZXJuZWwgdGFiYmluZyBzdHlsZS4KICogICAgICAgICAgICAgICAgICAgICAgIEFkZCBDRFJPTV9HRVRfVVBDIGlvY3RsLgogKiAzLjEwICBBcHIgMTAsIDE5OTYgLS0gRml4IGNvbXBpbGF0aW9uIGVycm9yIHdpdGggU1RBTkRBUkRfQVRBUEkuCiAqIDMuMTEgIEFwciAyOSwgMTk5NiAtLSBQYXRjaCBmcm9tIEhlaWtvIEVpc3NmZWxkdCA8aGVpa29AY29sb3NzdXMuZXNjYXBlLmRlPgogKiAgICAgICAgICAgICAgICAgICAgICAgdG8gcmVtb3ZlIHJlZHVuZGFudCB2ZXJpZnlfYXJlYSBjYWxscy4KICogMy4xMiAgTWF5ICA3LCAxOTk2IC0tIFJ1ZGltZW50YXJ5IGNoYW5nZXIgc3VwcG9ydC4gIEJhc2VkIG9uIHBhdGNoZXMKICogICAgICAgICAgICAgICAgICAgICAgICBmcm9tIEdlcmhhcmQgWnViZXIgPHp1YmVyQGJlcmxpbi5zbmFmdS5kZT4uCiAqICAgICAgICAgICAgICAgICAgICAgICBMZXQgb3BlbiBzdWNjZWVkIGV2ZW4gaWYgdGhlcmUncyBubyBsb2FkZWQgZGlzYy4KICogMy4xMyAgTWF5IDE5LCAxOTk2IC0tIEZpeGVzIGZvciBjaGFuZ2VyIGNvZGUuCiAqIDMuMTQgIE1heSAyOSwgMTk5NiAtLSBBZGQgd29yay1hcm91bmQgZm9yIFZlcnRvcyA2MDAuCiAqICAgICAgICAgICAgICAgICAgICAgICAgKEZyb20gSGVubnVzIEJlcmdtYW4gPGhlbm51c0Bza3kub3cubmw+LikKICogMy4xNSAgSnVseSAyLCAxOTk2IC0tIEFkZGVkIHN1cHBvcnQgZm9yIFNhbnlvIDMgQ0QgY2hhbmdlcnMKICogICAgICAgICAgICAgICAgICAgICAgICBmcm9tIEJlbiBHYWxsaWFydCA8YmdhbGxpYUBsdWMuZWR1PiB3aXRoIAogKiAgICAgICAgICAgICAgICAgICAgICAgIHNwZWNpYWwgaGVscCBmcm9tIEplZmYgTGlnaHRmb290IAogKiAgICAgICAgICAgICAgICAgICAgICAgIDxqZWZmbWxAcG9ib3guY29tPgogKiAzLjE1YSBKdWx5IDksIDE5OTYgLS0gSW1wcm92ZWQgU2FueW8gMyBDRCBjaGFuZ2VyIGlkZW50aWZpY2F0aW9uCiAqIDMuMTYgIEp1bCAyOCwgMTk5NiAtLSBGaXggZnJvbSBHYWRpIHRvIHJlZHVjZSBrZXJuZWwgc3RhY2sgdXNhZ2UgZm9yIGlvY3RsLgogKiAzLjE3ICBTZXAgMTcsIDE5OTYgLS0gVHdlYWsgYXVkaW8gcmVhZHMgZm9yIHNvbWUgZHJpdmVzLgogKiAgICAgICAgICAgICAgICAgICAgICAgU3RhcnQgY2hhbmdpbmcgQ0RST01MT0FERlJPTVNMT1QgdG8gQ0RST01fU0VMRUNUX0RJU0MuCiAqIDMuMTggIE9jdCAzMSwgMTk5NiAtLSBBZGRlZCBtb2R1bGUgYW5kIERNQSBzdXBwb3J0LgogKiAgICAgICAgICAgICAgICAgICAgICAgCiAqICAgICAgICAgICAgICAgICAgICAgICAKICogNC4wMCAgTm92IDUsIDE5OTYgICAtLSBOZXcgaWRlLWNkIG1haW50YWluZXIsCiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRXJpayBCLiBBbmRlcnNlbiA8YW5kZXJzZWVAZGViaWFuLm9yZz4KICogICAgICAgICAgICAgICAgICAgICAtLSBOZXdlciBDcmVhdGl2ZSBkcml2ZXMgZG9uJ3QgYWx3YXlzIHNldCB0aGUgZXJyb3IKICogICAgICAgICAgICAgICAgICAgICAgICAgIHJlZ2lzdGVyIGNvcnJlY3RseS4gIE1ha2Ugc3VyZSB3ZSBzZWUgbWVkaWEgY2hhbmdlcwogKiAgICAgICAgICAgICAgICAgICAgICAgICAgcmVnYXJkbGVzcy4KICogICAgICAgICAgICAgICAgICAgICAtLSBJbnRlZ3JhdGUgd2l0aCBnZW5lcmljIGNkcm9tIGRyaXZlci4KICogICAgICAgICAgICAgICAgICAgICAtLSBDRFJPTUdFVFNQSU5ET1dOIGFuZCBDRFJPTVNFVFNQSU5ET1dOIGlvY3RscywgYmFzZWQgb24KICogICAgICAgICAgICAgICAgICAgICAgICAgIGEgcGF0Y2ggZnJvbSBDaXJvIENhdHR1dG8gPD4uCiAqICAgICAgICAgICAgICAgICAgICAgLS0gQ2FsbCBzZXRfZGV2aWNlX3JvLgogKiAgICAgICAgICAgICAgICAgICAgIC0tIEltcGxlbWVudCBDRFJPTU1FQ0hBTklTTVNUQVRVUyBhbmQgQ0RST01TTE9UVEFCTEUKICogICAgICAgICAgICAgICAgICAgICAgICAgIGlvY3RscywgYmFzZWQgb24gcGF0Y2ggYnkgRXJpayBBbmRlcnNlbgogKiAgICAgICAgICAgICAgICAgICAgIC0tIEFkZCBzb21lIHByb2JlcyBvZiBkcml2ZSBjYXBhYmlsaXR5IGR1cmluZyBzZXR1cC4KICoKICogNC4wMSAgTm92IDExLCAxOTk2ICAtLSBTcGxpdCBpbnRvIGlkZS1jZC5jIGFuZCBpZGUtY2QuaAogKiAgICAgICAgICAgICAgICAgICAgIC0tIFJlbW92ZWQgQ0RST01NRUNIQU5JU01TVEFUVVMgYW5kIENEUk9NU0xPVFRBQkxFIAogKiAgICAgICAgICAgICAgICAgICAgICAgICAgaW9jdGxzIGluIGZhdm9yIG9mIGEgZ2VuZXJhbGl6ZWQgYXBwcm9hY2ggCiAqICAgICAgICAgICAgICAgICAgICAgICAgICB1c2luZyB0aGUgZ2VuZXJpYyBjZHJvbSBkcml2ZXIuCiAqICAgICAgICAgICAgICAgICAgICAgLS0gRnVsbHkgaW50ZWdyYXRlZCB3aXRoIHRoZSAyLjEuWCBrZXJuZWwuCiAqICAgICAgICAgICAgICAgICAgICAgLS0gT3RoZXIgc3R1ZmYgdGhhdCBJIGZvcmdvdCAobG90cyBvZiBjaGFuZ2VzKQogKgogKiA0LjAyICBEZWMgMDEsIDE5OTYgIC0tIEFwcGxpZWQgcGF0Y2ggZnJvbSBHYWRpIE94bWFuIDxnYWRpb0BuZXR2aXNpb24ubmV0LmlsPgogKiAgICAgICAgICAgICAgICAgICAgICAgICAgdG8gZml4IHRoZSBkcml2ZSBkb29yIGxvY2tpbmcgcHJvYmxlbXMuCiAqCiAqIDQuMDMgIERlYyAwNCwgMTk5NiAgLS0gQWRkZWQgRFNDIG92ZXJsYXAgc3VwcG9ydC4KICogNC4wNCAgRGVjIDI5LCAxOTk2ICAtLSBBZGRlZCBDRFJPTVJFQURSQVcgaW9jbHQgYmFzZWQgb24gcGF0Y2ggCiAqICAgICAgICAgICAgICAgICAgICAgICAgICBieSBBbGVzIE1ha2Fyb3YgKHhtYWthcm92QHN1bi5mZWxrLmN2dXQuY3opCiAqCiAqIDQuMDUgIE5vdiAyMCwgMTk5NyAgLS0gTW9kaWZpZWQgdG8gcHJpbnQgbW9yZSBkcml2ZSBpbmZvIG9uIGluaXQKICogICAgICAgICAgICAgICAgICAgICAgICBNaW5vciBvdGhlciBjaGFuZ2VzCiAqICAgICAgICAgICAgICAgICAgICAgICAgRml4IGVycm9ycyBvbiBDRFJPTVNUT1AgKElmIHlvdSBoYXZlIGEgIkRvbHBoaW4iLAogKiAgICAgICAgICAgICAgICAgICAgICAgICAgeW91IG11c3QgZGVmaW5lIElIQVZFQURPTFBISU4pCiAqICAgICAgICAgICAgICAgICAgICAgICAgQWRkZWQgaWRlbnRpZmllciBzbyBuZXcgU2FueW8gQ0QtY2hhbmdlciB3b3JrcwogKiAgICAgICAgICAgICAgICAgICAgICAgIEJldHRlciBkZXRlY3Rpb24gaWYgZG9vciBsb2NraW5nIGlzbid0IHN1cHBvcnRlZAogKgogKiA0LjA2ICBEZWMgMTcsIDE5OTcgIC0tIGZpeGVkIGVuZGxlc3MgInRyYXkgb3BlbiIgbWVzc2FnZXMgIC1tbAogKiA0LjA3ICBEZWMgMTcsIDE5OTcgIC0tIGZhbGxiYWNrIHRvIHNldCBwYy0+c3RhdCBvbiAidHJheSBvcGVuIgogKiA0LjA4ICBEZWMgMTgsIDE5OTcgIC0tIHNwZXcgbGVzcyBub2lzZSB3aGVuIHRyYXkgaXMgZW1wdHkKICogICAgICAgICAgICAgICAgICAgICAtLSBmaXggc3BlZWQgZGlzcGxheSBmb3IgQUNFUiAyNFgsIDE4WAogKiA0LjA5ICBKYW4gMDQsIDE5OTggIC0tIGZpeCBoYW5kbGluZyBvZiB0aGUgbGFzdCBibG9jayBzbyB3ZSByZXR1cm4KICogICAgICAgICAgICAgICAgICAgICAgICAgYW4gZW5kIG9mIGZpbGUgaW5zdGVhZCBvZiBhbiBJL08gZXJyb3IgKEdhZGkpCiAqIDQuMTAgIEphbiAyNCwgMTk5OCAgLS0gZml4ZWQgYSBidWcgc28gbm93IGNoYW5nZXJzIGNhbiBjaGFuZ2UgdG8gYSBuZXcKICogICAgICAgICAgICAgICAgICAgICAgICAgc2xvdCB3aGVuIHRoZXJlIGlzIG5vIGRpc2MgaW4gdGhlIGN1cnJlbnQgc2xvdC4KICogICAgICAgICAgICAgICAgICAgICAtLSBGaXhlZCBhIG1lbW9yeSBsZWFrIHdoZXJlIGluZm8tPmNoYW5nZXJfaW5mbyB3YXMKICogICAgICAgICAgICAgICAgICAgICAgICAgbWFsbG9jJ2VkIGJ1dCBuZXZlciBmcmVlJ2Qgd2hlbiBjbG9zaW5nIHRoZSBkZXZpY2UuCiAqICAgICAgICAgICAgICAgICAgICAgLS0gQ2xlYW5lZCB1cCB0aGUgZ2xvYmFsIG5hbWVzcGFjZSBhIGJpdCBieSBtYWtpbmcgbW9yZQogKiAgICAgICAgICAgICAgICAgICAgICAgICBmdW5jdGlvbnMgc3RhdGljIHRoYXQgc2hvdWxkIGFscmVhZHkgaGF2ZSBiZWVuLgogKiA0LjExICBNYXIgMTIsIDE5OTggIC0tIEFkZGVkIHN1cHBvcnQgZm9yIHRoZSBDRFJPTV9TRUxFQ1RfU1BFRUQgaW9jdGwKICogICAgICAgICAgICAgICAgICAgICAgICAgYmFzZWQgb24gYSBwYXRjaCBmb3IgMi4wLjMzIGJ5IEplbGxlIEZva3MgCiAqICAgICAgICAgICAgICAgICAgICAgICAgIDxqZWxsZUBzY2ludGlsbGEudXR3ZW50ZS5ubD4sIGEgcGF0Y2ggZm9yIDIuMC4zMwogKiAgICAgICAgICAgICAgICAgICAgICAgICBieSBUb25pIEdpb3JnaW5vIDx0b25pQHBjYXBlMi5waS5pbmZuLml0PiwgdGhlIFNDU0kKICogICAgICAgICAgICAgICAgICAgICAgICAgdmVyc2lvbiwgYW5kIG15IG93biBlZmZvcnRzLiAgLWVyaWsKICogICAgICAgICAgICAgICAgICAgICAtLSBGaXhlZCBhIHN0dXBpZCBidWcgd2hpY2ggZWdjcyB3YXMga2luZCBlbm91Z2ggdG8KICogICAgICAgICAgICAgICAgICAgICAgICAgaW5mb3JtIG1lIG9mIHdoZXJlICJJbGxlZ2FsIG1vZGUgZm9yIHRoaXMgdHJhY2siCiAqICAgICAgICAgICAgICAgICAgICAgICAgIHdhcyBuZXZlciByZXR1cm5lZCBkdWUgdG8gYSBjb21wYXJpc29uIG9uIGRhdGEKICogICAgICAgICAgICAgICAgICAgICAgICAgdHlwZXMgb2YgbGltaXRlZCByYW5nZS4KICogNC4xMiAgTWFyIDI5LCAxOTk4ICAtLSBGaXhlZCBidWcgaW4gQ0RST01fU0VMRUNUX1NQRUVEIHNvIHdyaXRlIHNwZWVkIGlzIAogKiAgICAgICAgICAgICAgICAgICAgICAgICBub3cgc2V0IGlvbmx5IGZvciBDRC1SIGFuZCBDRC1SVyBkcml2ZXMuICBJIGhhZCAKICogICAgICAgICAgICAgICAgICAgICAgICAgcmVtb3ZlZCB0aGlzIHN1cHBvcnQgYmVjYXVzZSBpdCBwcm9kdWNlZCBlcnJvcnMuCiAqICAgICAgICAgICAgICAgICAgICAgICAgIEl0IHByb2R1Y2VkIGVycm9ycyBfb25seV8gZm9yIG5vbi13cml0ZXJzLiBkdWguCiAqIDQuMTMgIE1heSAwNSwgMTk5OCAgLS0gU3VwcHJlc3MgdXNlbGVzcyAiaW4gcHJvZ3Jlc3Mgb2YgYmVjb21pbmcgcmVhZHkiCiAqICAgICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2VzLCBzaW5jZSB0aGlzIGlzIG5vdCBhbiBlcnJvci4KICogICAgICAgICAgICAgICAgICAgICAtLSBDaGFuZ2UgZXJyb3IgbWVzc2FnZXMgdG8gYmUgY29uc3QKICogICAgICAgICAgICAgICAgICAgICAtLSBSZW1vdmUgYSAiXHQiIHdoaWNoIGxvb2tzIHVnbHkgaW4gdGhlIHN5c2xvZ3MKICogNC4xNCAgSnVseSAxNywgMTk5OCAtLSBDaGFuZ2UgdG8gcG9pbnRpbmcgdG8gLnBzIHZlcnNpb24gb2YgQVRBUEkgc3BlYwogKiAgICAgICAgICAgICAgICAgICAgICAgICBzaW5jZSB0aGUgLnBkZiB2ZXJzaW9uIGRvZXNuJ3Qgc2VlbSB0byB3b3JrLi4uCiAqICAgICAgICAgICAgICAgICAgICAgLS0gVXBkYXRlZCB0aGUgVE9ETyBsaXN0IHRvIHNvbWV0aGluZyBtb3JlIGN1cnJlbnQuCiAqCiAqIDQuMTUgIEF1ZyAyNSwgMTk5OCAgLS0gVXBkYXRlZCBpZGUtY2QuaCB0byByZXNwZWN0IG1lY2hpbmUgZW5kaWFuZXNzLCAKICogICAgICAgICAgICAgICAgICAgICAgICAgcGF0Y2ggdGhhbmtzIHRvICJFZGRpZSBDLiBEb3N0IiA8ZWNkQHNreW5ldC5iZT4KICoKICogNC41MCAgT2N0IDE5LCAxOTk4ICAtLSBOZXcgbWFpbnRhaW5lcnMhCiAqICAgICAgICAgICAgICAgICAgICAgICAgIEplbnMgQXhib2UgPGF4Ym9lQGltYWdlLmRrPgogKiAgICAgICAgICAgICAgICAgICAgICAgICBDaHJpcyBad2lsbGluZyA8Y2hyaXNAY2xvdWRuZXQuY29tPgogKgogKiA0LjUxICBEZWMgMjMsIDE5OTggIC0tIEplbnMgQXhib2UgPGF4Ym9lQGltYWdlLmRrPgogKiAgICAgICAgICAgICAgICAgICAgICAtIGlkZV9jZHJvbV9yZXNldCBlbmFibGVkIHNpbmNlIHRoZSBpZGUgc3Vic3lzdGVtCiAqICAgICAgICAgICAgICAgICAgICAgICAgIGhhbmRsZXMgcmVzZXRzIGZpbmUgbm93LiA8YXhib2VAaW1hZ2UuZGs+CiAqICAgICAgICAgICAgICAgICAgICAgIC0gVHJhbnNmZXIgc2l6ZSBmaXggZm9yIFNhbXN1bmcgQ0QtUk9NcywgdGhhbmtzIHRvCiAqICAgICAgICAgICAgICAgICAgICAgICAgIlZpbGxlIEhhbGxpayIgPHZpbGxlLmhhbGxpa0BtYWlsLmVlPi4KICogICAgICAgICAgICAgICAgICAgICAgLSBvdGhlciBtaW5vciBzdHVmZi4KICoKICogNC41MiAgSmFuIDE5LCAxOTk5ICAtLSBKZW5zIEF4Ym9lIDxheGJvZUBpbWFnZS5kaz4KICogICAgICAgICAgICAgICAgICAgICAgLSBEZXRlY3QgRFZELVJPTS9SQU0gZHJpdmVzCiAqCiAqIDQuNTMgIEZlYiAyMiwgMTk5OSAgIC0gSW5jbHVkZSBvdGhlciBtb2RlbCBTYW1zdW5nIGFuZCBvbmUgR29sZHN0YXIKICogICAgICAgICAgICAgICAgICAgICAgICAgZHJpdmUgaW4gdHJhbnNmZXIgc2l6ZSBsaW1pdC4KICogICAgICAgICAgICAgICAgICAgICAgLSBGaXggdGhlIEkvTyBlcnJvciB3aGVuIGRvaW5nIGVqZWN0IHdpdGhvdXQgYSBtZWRpdW0KICogICAgICAgICAgICAgICAgICAgICAgICAgbG9hZGVkIG9uIHNvbWUgZHJpdmVzLgogKiAgICAgICAgICAgICAgICAgICAgICAtIENEUk9NUkVBRE1PREUyIGlzIG5vdyBpbXBsZW1lbnRlZCB0aHJvdWdoCiAqICAgICAgICAgICAgICAgICAgICAgICAgIENEUk9NUkVBRFJBVywgc2luY2UgbWFueSBkcml2ZXMgZG9uJ3Qgc3VwcG9ydAogKiAgICAgICAgICAgICAgICAgICAgICAgICBNT0RFMiAoZXZlbiB0aG91Z2ggQVRBUEkgMi42IHNheXMgdGhleSBtdXN0KS4KICogICAgICAgICAgICAgICAgICAgICAgLSBBZGRlZCBpZ25vcmUgcGFyYW1ldGVyIHRvIGlkZS1jZCAoYXMgYSBtb2R1bGUpLCBlZwogKiAgICAgICAgICAgICAgICAgICAgICAgICAJaW5zbW9kIGlkZS1jZCBpZ25vcmU9J2hkYSBoZGInCiAqICAgICAgICAgICAgICAgICAgICAgICAgIFVzZWZ1bCB3aGVuIHVzaW5nIGlkZS1jZCBpbiBjb25qdW5jdGlvbiB3aXRoCiAqICAgICAgICAgICAgICAgICAgICAgICAgIGlkZS1zY3NpLiBUT0RPOiBub24tbW9kdWxhciB3YXkgb2YgZG9pbmcgdGhlCiAqICAgICAgICAgICAgICAgICAgICAgICAgIHNhbWUuCiAqCiAqIDQuNTQgIEF1ZyA1LCAxOTk5CS0gU3VwcG9ydCBmb3IgTU1DMiBjbGFzcyBjb21tYW5kcyB0aHJvdWdoIHRoZSBnZW5lcmljCiAqCQkJICBwYWNrZXQgaW50ZXJmYWNlIHRvIGNkcm9tLmMuCiAqCQkJLSBVbmlmaWVkIGF1ZGlvIGlvY3RsIHN1cHBvcnQsIG1vc3Qgb2YgaXQuCiAqCQkJLSBjbGVhbmVkIHVwIHZhcmlvdXMgZGVwcmVjYXRlZCB2ZXJpZnlfYXJlYSgpLgogKgkJCS0gQWRkZWQgaWRlX2Nkcm9tX3BhY2tldCgpIGFzIHRoZSBpbnRlcmZhY2UgZm9yCiAqCQkJICB0aGUgVW5pZm9ybSBnZW5lcmljX3BhY2tldCgpLgogKgkJCS0gYnVuY2ggb2Ygb3RoZXIgc3R1ZmYsIHdpbGwgZmlsbCBpbiBsb2dzIGxhdGVyLgogKgkJCS0gcmVwb3J0IDEgc2xvdCBmb3Igbm9uLWNoYW5nZXJzLCBsaWtlIHRoZSBvdGhlcgogKgkJCSAgY2Qtcm9tIGRyaXZlcnMuIGRvbid0IHJlcG9ydCBzZWxlY3QgZGlzYyBmb3IKICoJCQkgIG5vbi1jaGFuZ2VycyBhcyB3ZWxsLgogKgkJCS0gbWFzayBvdXQgYXVkaW8gcGxheWluZywgaWYgdGhlIGRldmljZSBjYW4ndCBkbyBpdC4KICoKICogNC41NSAgU2VwIDEsIDE5OTkJLSBFbGltaW5hdGVkIHRoZSByZXN0IG9mIHRoZSBhdWRpbyBpb2N0bHMsIGV4Y2VwdAogKgkJCSAgZm9yIENEUk9NUkVBRFRPQ1tFTlRSWXxIRUFERVJdLiBTb21lIG9mIHRoZSBkcml2ZXJzCiAqCQkJICB1c2UgdGhpcyBpbmRlcGVuZGVudGx5IG9mIHRoZSBhY3R1YWwgYXVkaW8gaGFuZGxpbmcuCiAqCQkJICBUaGV5IHdpbGwgZGlzYXBwZWFyIGxhdGVyIHdoZW4gSSBnZXQgdGhlIHRpbWUgdG8KICoJCQkgIGRvIGl0IGNsZWFubHkuCiAqCQkJLSBNaW5pbWl6ZSB0aGUgVE9DIHJlYWRpbmcgLSBvbmx5IGRvIGl0IHdoZW4gd2UKICoJCQkgIGtub3cgYSBtZWRpYSBjaGFuZ2UgaGFzIG9jY3VycmVkLgogKgkJCS0gTW92ZWQgYWxsIHRoZSBDRFJPTVJFQUR4IGlvY3RscyB0byB0aGUgVW5pZm9ybSBsYXllci4KICoJCQktIEhlaWtvIEVpc3NmZWxkdCA8aGVpa29AY29sb3NzdXMuZXNjYXBlLmRlPiBzdXBwbGllZAogKgkJCSAgc29tZSBmaXhlcyBmb3IgQ0RJLgogKgkJCS0gQ0QtUk9NIGxlYXZpbmcgZG9vciBsb2NrZWQgZml4IGZyb20gQW5kcmllcwogKgkJCSAgQnJvdXdlciA8QW5kcmllcy5Ccm91d2VyQGN3aS5ubD4KICoJCQktIEVyaWsgQW5kZXJzZW4gPGFuZGVyc2VuQHhtaXNzaW9uLmNvbT4gdW5pZmllZAogKgkJCSAgY29tbWFuZHMgYWNyb3NzIHRoZSB2YXJpb3VzIGRyaXZlcnMgYW5kIGhvdwogKgkJCSAgc2Vuc2UgZXJyb3JzIGFyZSBoYW5kbGVkLgogKgogKiA0LjU2ICBTZXAgMTIsIDE5OTkJLSBSZW1vdmVkIGNoYW5nZXIgc3VwcG9ydCAtIGl0IGlzIG5vdyBpbiB0aGUKICoJCQkgIFVuaWZvcm0gbGF5ZXIuCiAqCQkJLSBBZGRlZCBwYXJ0aXRpb24gYmFzZWQgbXVsdGlzZXNzaW9uIGhhbmRsaW5nLgogKgkJCS0gTW9kZSBzZW5zZSBhbmQgbW9kZSBzZWxlY3QgbW92ZWQgdG8gdGhlCiAqCQkJICBVbmlmb3JtIGxheWVyLgogKgkJCS0gRml4ZWQgYSBwcm9ibGVtIHdpdGggV1BJIENEUy0zMlggZHJpdmUgLSBpdAogKgkJCSAgZmFpbGVkIHRoZSBjYXBhYmlsaXRpZXMgCiAqCiAqIDQuNTcgIEFwciA3LCAyMDAwCS0gRml4ZWQgc2Vuc2UgcmVwb3J0aW5nLgogKgkJCS0gRml4ZWQgcG9zc2libGUgb29wcyBpbiBpZGVfY2Ryb21fZ2V0X2xhc3Rfc2Vzc2lvbigpCiAqCQkJLSBGaXggbG9ja2luZyBtYW5pYSBhbmQgbWFrZSBpZGVfY2Ryb21fcmVzZXQgcmVsb2NrCiAqCQkJLSBTdG9wIHNwZXdpbmcgZXJyb3JzIHRvIGxvZyB3aGVuIG1hZ2ljZGV2IHBvbGxzIHdpdGgKICoJCQkgIFRFU1RfVU5JVF9SRUFEWSBvbiBzb21lIGRyaXZlcy4KICoJCQktIFZhcmlvdXMgZml4ZXMgZnJvbSBUb2JpYXMgUmluZ3N0cm9tOgogKgkJCSAgdHJheSBpZiBpdCB3YXMgbG9ja2VkIHByaW9yIHRvIHRoZSByZXNldC4KICoJCQkgIC0gY2Ryb21fcmVhZF9jYXBhY2l0eSByZXR1cm5zIG9uZSBmcmFtZSB0b28gbGl0dGxlLgogKgkJCSAgLSBGaXggcmVhbCBjYXBhY2l0eSByZXBvcnRpbmcuCiAqCiAqIDQuNTggIE1heSAxLCAyMDAwCS0gQ2xlYW4gdXAgQUNFUjUwIHN0dWZmLgogKgkJCS0gRml4IHNtYWxsIHByb2JsZW0gd2l0aCBpZGVfY2Ryb21fY2FwYWNpdHkKICoKICogNC41OSAgQXVnIDExLCAyMDAwCS0gRml4IGNoYW5nZXIgcHJvYmxlbSBpbiBjZHJvbV9yZWFkX3RvYywgd2Ugd2VyZW4ndAogKgkJCSAgY29ycmVjdGx5IHNlbnNpbmcgYSBkaXNjIGNoYW5nZS4KICoJCQktIFJlYXJyYW5nZWQgc29tZSBjb2RlCiAqCQkJLSBVc2UgZXh0ZW5kZWQgc2Vuc2Ugb24gZHJpdmVzIHRoYXQgc3VwcG9ydCBpdCBmb3IKICoJCQkgIGNvcnJlY3RseSByZXBvcnRpbmcgdHJheSBzdGF0dXMgLS0gZnJvbQogKgkJCSAgTWljaGFlbCBEIEpvaG5zb24gPGpvaG5zb21Ab3JzdC5lZHU+CiAqIDQuNjAgIERlYyAxNywgMjAwMwktIEFkZCBtdCByYWluaWVyIHN1cHBvcnQKICoJCQktIEJ1bXAgdGltZW91dCBmb3IgcGFja2V0IGNvbW1hbmRzLCBtYXRjaGVzIHNyCiAqCQkJLSBPZGQgc3R1ZmYKICogNC42MSAgSmFuIDIyLCAyMDA0CS0gc3VwcG9ydCBoYXJkd2FyZSBzZWN0b3Igc2l6ZXMgb3RoZXIgdGhhbiAya0IsCiAqCQkJICBQYXNjYWwgU2NobWlkdCA8ZGVyLmVyZW1pdEBlbWFpbC5kZT4KICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCiAKI2RlZmluZSBJREVDRF9WRVJTSU9OICI0LjYxIgoKI2luY2x1ZGUgPGxpbnV4L2NvbmZpZy5oPgojaW5jbHVkZSA8bGludXgvbW9kdWxlLmg+CiNpbmNsdWRlIDxsaW51eC90eXBlcy5oPgojaW5jbHVkZSA8bGludXgva2VybmVsLmg+CiNpbmNsdWRlIDxsaW51eC9kZWxheS5oPgojaW5jbHVkZSA8bGludXgvdGltZXIuaD4KI2luY2x1ZGUgPGxpbnV4L3NsYWIuaD4KI2luY2x1ZGUgPGxpbnV4L2ludGVycnVwdC5oPgojaW5jbHVkZSA8bGludXgvZXJybm8uaD4KI2luY2x1ZGUgPGxpbnV4L2Nkcm9tLmg+CiNpbmNsdWRlIDxsaW51eC9pZGUuaD4KI2luY2x1ZGUgPGxpbnV4L2NvbXBsZXRpb24uaD4KI2luY2x1ZGUgPGxpbnV4L211dGV4Lmg+CgojaW5jbHVkZSA8c2NzaS9zY3NpLmg+CS8qIEZvciBTQ1NJIC0+IEFUQVBJIGNvbW1hbmQgY29udmVyc2lvbiAqLwoKI2luY2x1ZGUgPGFzbS9pcnEuaD4KI2luY2x1ZGUgPGFzbS9pby5oPgojaW5jbHVkZSA8YXNtL2J5dGVvcmRlci5oPgojaW5jbHVkZSA8YXNtL3VhY2Nlc3MuaD4KI2luY2x1ZGUgPGFzbS91bmFsaWduZWQuaD4KCiNpbmNsdWRlICJpZGUtY2QuaCIKCnN0YXRpYyBERUZJTkVfTVVURVgoaWRlY2RfcmVmX211dGV4KTsKCiNkZWZpbmUgdG9faWRlX2NkKG9iaikgY29udGFpbmVyX29mKG9iaiwgc3RydWN0IGNkcm9tX2luZm8sIGtyZWYpIAoKI2RlZmluZSBpZGVfY2RfZyhkaXNrKSBcCgljb250YWluZXJfb2YoKGRpc2spLT5wcml2YXRlX2RhdGEsIHN0cnVjdCBjZHJvbV9pbmZvLCBkcml2ZXIpCgpzdGF0aWMgc3RydWN0IGNkcm9tX2luZm8gKmlkZV9jZF9nZXQoc3RydWN0IGdlbmRpc2sgKmRpc2spCnsKCXN0cnVjdCBjZHJvbV9pbmZvICpjZCA9IE5VTEw7CgoJbXV0ZXhfbG9jaygmaWRlY2RfcmVmX211dGV4KTsKCWNkID0gaWRlX2NkX2coZGlzayk7CglpZiAoY2QpCgkJa3JlZl9nZXQoJmNkLT5rcmVmKTsKCW11dGV4X3VubG9jaygmaWRlY2RfcmVmX211dGV4KTsKCXJldHVybiBjZDsKfQoKc3RhdGljIHZvaWQgaWRlX2NkX3JlbGVhc2Uoc3RydWN0IGtyZWYgKik7CgpzdGF0aWMgdm9pZCBpZGVfY2RfcHV0KHN0cnVjdCBjZHJvbV9pbmZvICpjZCkKewoJbXV0ZXhfbG9jaygmaWRlY2RfcmVmX211dGV4KTsKCWtyZWZfcHV0KCZjZC0+a3JlZiwgaWRlX2NkX3JlbGVhc2UpOwoJbXV0ZXhfdW5sb2NrKCZpZGVjZF9yZWZfbXV0ZXgpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBHZW5lcmljIHBhY2tldCBjb21tYW5kIHN1cHBvcnQgYW5kIGVycm9yIGhhbmRsaW5nIHJvdXRpbmVzLgogKi8KCi8qIE1hcmsgdGhhdCB3ZSd2ZSBzZWVuIGEgbWVkaWEgY2hhbmdlLCBhbmQgaW52YWxpZGF0ZSBvdXIgaW50ZXJuYWwKICAgYnVmZmVycy4gKi8Kc3RhdGljIHZvaWQgY2Ryb21fc2F3X21lZGlhX2NoYW5nZSAoaWRlX2RyaXZlX3QgKmRyaXZlKQp7CglzdHJ1Y3QgY2Ryb21faW5mbyAqaW5mbyA9IGRyaXZlLT5kcml2ZXJfZGF0YTsKCQoJQ0RST01fU1RBVEVfRkxBR1MgKGRyaXZlKS0+bWVkaWFfY2hhbmdlZCA9IDE7CglDRFJPTV9TVEFURV9GTEFHUyAoZHJpdmUpLT50b2NfdmFsaWQgPSAwOwoJaW5mby0+bnNlY3RvcnNfYnVmZmVyZWQgPSAwOwp9CgpzdGF0aWMgaW50IGNkcm9tX2xvZ19zZW5zZShpZGVfZHJpdmVfdCAqZHJpdmUsIHN0cnVjdCByZXF1ZXN0ICpycSwKCQkJICAgc3RydWN0IHJlcXVlc3Rfc2Vuc2UgKnNlbnNlKQp7CglpbnQgbG9nID0gMDsKCglpZiAoIXNlbnNlIHx8ICFycSB8fCAocnEtPmZsYWdzICYgUkVRX1FVSUVUKSkKCQlyZXR1cm4gMDsKCglzd2l0Y2ggKHNlbnNlLT5zZW5zZV9rZXkpIHsKCQljYXNlIE5PX1NFTlNFOiBjYXNlIFJFQ09WRVJFRF9FUlJPUjoKCQkJYnJlYWs7CgkJY2FzZSBOT1RfUkVBRFk6CgkJCS8qCgkJCSAqIGRvbid0IGNhcmUgYWJvdXQgdHJheSBzdGF0ZSBtZXNzYWdlcyBmb3IKCQkJICogZS5nLiBjYXBhY2l0eSBjb21tYW5kcyBvciBpbi1wcm9ncmVzcyBvcgoJCQkgKiBiZWNvbWluZyByZWFkeQoJCQkgKi8KCQkJaWYgKHNlbnNlLT5hc2MgPT0gMHgzYSB8fCBzZW5zZS0+YXNjID09IDB4MDQpCgkJCQlicmVhazsKCQkJbG9nID0gMTsKCQkJYnJlYWs7CgkJY2FzZSBJTExFR0FMX1JFUVVFU1Q6CgkJCS8qCgkJCSAqIGRvbid0IGxvZyBTVEFSVF9TVE9QIHVuaXQgd2l0aCBMb0VqIHNldCwgc2luY2UKCQkJICogd2UgY2Fubm90IHJlbGlhYmx5IGNoZWNrIGlmIGRyaXZlIGNhbiBhdXRvLWNsb3NlCgkJCSAqLwoJCQlpZiAocnEtPmNtZFswXSA9PSBHUENNRF9TVEFSVF9TVE9QX1VOSVQgJiYgc2Vuc2UtPmFzYyA9PSAweDI0KQoJCQkJbG9nID0gMDsKCQkJYnJlYWs7CgkJY2FzZSBVTklUX0FUVEVOVElPTjoKCQkJLyoKCQkJICogTWFrZSBnb29kIGFuZCBzdXJlIHdlJ3ZlIHNlZW4gdGhpcyBwb3RlbnRpYWwgbWVkaWEKCQkJICogY2hhbmdlLiBTb21lIGRyaXZlcyAoaS5lLiBDcmVhdGl2ZSkgZmFpbCB0byBwcmVzZW50CgkJCSAqIHRoZSBjb3JyZWN0IHNlbnNlIGtleSBpbiB0aGUgZXJyb3IgcmVnaXN0ZXIuCgkJCSAqLwoJCQljZHJvbV9zYXdfbWVkaWFfY2hhbmdlKGRyaXZlKTsKCQkJYnJlYWs7CgkJZGVmYXVsdDoKCQkJbG9nID0gMTsKCQkJYnJlYWs7Cgl9CglyZXR1cm4gbG9nOwp9CgpzdGF0aWMKdm9pZCBjZHJvbV9hbmFseXplX3NlbnNlX2RhdGEoaWRlX2RyaXZlX3QgKmRyaXZlLAoJCQkgICAgICBzdHJ1Y3QgcmVxdWVzdCAqZmFpbGVkX2NvbW1hbmQsCgkJCSAgICAgIHN0cnVjdCByZXF1ZXN0X3NlbnNlICpzZW5zZSkKewoJaWYgKCFjZHJvbV9sb2dfc2Vuc2UoZHJpdmUsIGZhaWxlZF9jb21tYW5kLCBzZW5zZSkpCgkJcmV0dXJuOwoKCS8qCgkgKiBJZiBhIHJlYWQgdG9jIGlzIGV4ZWN1dGVkIGZvciBhIENELVIgb3IgQ0QtUlcgbWVkaXVtIHdoZXJlCgkgKiB0aGUgZmlyc3QgdG9jIGhhcyBub3QgYmVlbiByZWNvcmRlZCB5ZXQsIGl0IHdpbGwgZmFpbCB3aXRoCgkgKiAwNS8yNC8wMCAod2hpY2ggaXMgYSBjb25mdXNpbmcgZXJyb3IpCgkgKi8KCWlmIChmYWlsZWRfY29tbWFuZCAmJiBmYWlsZWRfY29tbWFuZC0+Y21kWzBdID09IEdQQ01EX1JFQURfVE9DX1BNQV9BVElQKQoJCWlmIChzZW5zZS0+c2Vuc2Vfa2V5ID09IDB4MDUgJiYgc2Vuc2UtPmFzYyA9PSAweDI0KQoJCQlyZXR1cm47CgojaWYgVkVSQk9TRV9JREVfQ0RfRVJST1JTCgl7CgkJaW50IGk7CgkJY29uc3QgY2hhciAqcyA9ICJiYWQgc2Vuc2Uga2V5ISI7CgkJY2hhciBidWZbODBdOwoKCQlwcmludGsgKCJBVEFQSSBkZXZpY2UgJXM6XG4iLCBkcml2ZS0+bmFtZSk7CgkJaWYgKHNlbnNlLT5lcnJvcl9jb2RlPT0weDcwKQoJCQlwcmludGsoIiAgRXJyb3I6ICIpOwoJCWVsc2UgaWYgKHNlbnNlLT5lcnJvcl9jb2RlPT0weDcxKQoJCQlwcmludGsoIiAgRGVmZXJyZWQgRXJyb3I6ICIpOwoJCWVsc2UgaWYgKHNlbnNlLT5lcnJvcl9jb2RlID09IDB4N2YpCgkJCXByaW50aygiICBWZW5kb3Itc3BlY2lmaWMgRXJyb3I6ICIpOwoJCWVsc2UKCQkJcHJpbnRrKCIgIFVua25vd24gRXJyb3IgVHlwZTogIik7CgoJCWlmIChzZW5zZS0+c2Vuc2Vfa2V5IDwgQVJZX0xFTihzZW5zZV9rZXlfdGV4dHMpKQoJCQlzID0gc2Vuc2Vfa2V5X3RleHRzW3NlbnNlLT5zZW5zZV9rZXldOwoKCQlwcmludGsoIiVzIC0tIChTZW5zZSBrZXk9MHglMDJ4KVxuIiwgcywgc2Vuc2UtPnNlbnNlX2tleSk7CgoJCWlmIChzZW5zZS0+YXNjID09IDB4NDApIHsKCQkJc3ByaW50ZihidWYsICJEaWFnbm9zdGljIGZhaWx1cmUgb24gY29tcG9uZW50IDB4JTAyeCIsCgkJCQkgc2Vuc2UtPmFzY3EpOwoJCQlzID0gYnVmOwoJCX0gZWxzZSB7CgkJCWludCBsbyA9IDAsIG1pZCwgaGkgPSBBUllfTEVOKHNlbnNlX2RhdGFfdGV4dHMpOwoJCQl1bnNpZ25lZCBsb25nIGtleSA9IChzZW5zZS0+c2Vuc2Vfa2V5IDw8IDE2KTsKCQkJa2V5IHw9IChzZW5zZS0+YXNjIDw8IDgpOwoJCQlpZiAoIShzZW5zZS0+YXNjcSA+PSAweDgwICYmIHNlbnNlLT5hc2NxIDw9IDB4ZGQpKQoJCQkJa2V5IHw9IHNlbnNlLT5hc2NxOwoJCQlzID0gTlVMTDsKCgkJCXdoaWxlIChoaSA+IGxvKSB7CgkJCQltaWQgPSAobG8gKyBoaSkgLyAyOwoJCQkJaWYgKHNlbnNlX2RhdGFfdGV4dHNbbWlkXS5hc2NfYXNjcSA9PSBrZXkgfHwKCQkJCSAgICBzZW5zZV9kYXRhX3RleHRzW21pZF0uYXNjX2FzY3EgPT0gKDB4ZmYwMDAwfGtleSkpIHsKCQkJCQlzID0gc2Vuc2VfZGF0YV90ZXh0c1ttaWRdLnRleHQ7CgkJCQkJYnJlYWs7CgkJCQl9CgkJCQllbHNlIGlmIChzZW5zZV9kYXRhX3RleHRzW21pZF0uYXNjX2FzY3EgPiBrZXkpCgkJCQkJaGkgPSBtaWQ7CgkJCQllbHNlCgkJCQkJbG8gPSBtaWQrMTsKCQkJfQoJCX0KCgkJaWYgKHMgPT0gTlVMTCkgewoJCQlpZiAoc2Vuc2UtPmFzYyA+IDB4ODApCgkJCQlzID0gIih2ZW5kb3Itc3BlY2lmaWMgZXJyb3IpIjsKCQkJZWxzZQoJCQkJcyA9ICIocmVzZXJ2ZWQgZXJyb3IgY29kZSkiOwoJCX0KCgkJcHJpbnRrKEtFUk5fRVJSICIgICVzIC0tIChhc2M9MHglMDJ4LCBhc2NxPTB4JTAyeClcbiIsCgkJCXMsIHNlbnNlLT5hc2MsIHNlbnNlLT5hc2NxKTsKCgkJaWYgKGZhaWxlZF9jb21tYW5kICE9IE5VTEwpIHsKCgkJCWludCBsbz0wLCBtaWQsIGhpPSBBUllfTEVOIChwYWNrZXRfY29tbWFuZF90ZXh0cyk7CgkJCXMgPSBOVUxMOwoKCQkJd2hpbGUgKGhpID4gbG8pIHsKCQkJCW1pZCA9IChsbyArIGhpKSAvIDI7CgkJCQlpZiAocGFja2V0X2NvbW1hbmRfdGV4dHNbbWlkXS5wYWNrZXRfY29tbWFuZCA9PQoJCQkJICAgIGZhaWxlZF9jb21tYW5kLT5jbWRbMF0pIHsKCQkJCQlzID0gcGFja2V0X2NvbW1hbmRfdGV4dHNbbWlkXS50ZXh0OwoJCQkJCWJyZWFrOwoJCQkJfQoJCQkJaWYgKHBhY2tldF9jb21tYW5kX3RleHRzW21pZF0ucGFja2V0X2NvbW1hbmQgPgoJCQkJICAgIGZhaWxlZF9jb21tYW5kLT5jbWRbMF0pCgkJCQkJaGkgPSBtaWQ7CgkJCQllbHNlCgkJCQkJbG8gPSBtaWQrMTsKCQkJfQoKCQkJcHJpbnRrIChLRVJOX0VSUiAiICBUaGUgZmFpbGVkIFwiJXNcIiBwYWNrZXQgY29tbWFuZCB3YXM6IFxuICBcIiIsIHMpOwoJCQlmb3IgKGk9MDsgaTxzaXplb2YgKGZhaWxlZF9jb21tYW5kLT5jbWQpOyBpKyspCgkJCQlwcmludGsgKCIlMDJ4ICIsIGZhaWxlZF9jb21tYW5kLT5jbWRbaV0pOwoJCQlwcmludGsgKCJcIlxuIik7CgkJfQoKCQkvKiBUaGUgU0tTViBiaXQgc3BlY2lmaWVzIHZhbGlkaXR5IG9mIHRoZSBzZW5zZV9rZXlfc3BlY2lmaWMKCQkgKiBpbiB0aGUgbmV4dCB0d28gY29tbWFuZHMuIEl0IGlzIGJpdCA3IG9mIHRoZSBmaXJzdCBieXRlLgoJCSAqIEluIHRoZSBjYXNlIG9mIE5PVF9SRUFEWSwgaWYgU0tTViBpcyBzZXQgdGhlIGRyaXZlIGNhbgoJCSAqIGdpdmUgdXMgbmljZSBFVEEgcmVhZGluZ3MuCgkJICovCgkJaWYgKHNlbnNlLT5zZW5zZV9rZXkgPT0gTk9UX1JFQURZICYmIChzZW5zZS0+c2tzWzBdICYgMHg4MCkpIHsKCQkJaW50IHByb2dyZXNzID0gKHNlbnNlLT5za3NbMV0gPDwgOCB8IHNlbnNlLT5za3NbMl0pICogMTAwOwoJCQlwcmludGsoS0VSTl9FUlIgIiAgQ29tbWFuZCBpcyAlMDJkJSUgY29tcGxldGVcbiIsIHByb2dyZXNzIC8gMHhmZmZmKTsKCgkJfQoKCQlpZiAoc2Vuc2UtPnNlbnNlX2tleSA9PSBJTExFR0FMX1JFUVVFU1QgJiYKCQkgICAgKHNlbnNlLT5za3NbMF0gJiAweDgwKSAhPSAwKSB7CgkJCXByaW50ayhLRVJOX0VSUiAiICBFcnJvciBpbiAlcyBieXRlICVkIiwKCQkJCShzZW5zZS0+c2tzWzBdICYgMHg0MCkgIT0gMCA/CgkJCQkiY29tbWFuZCBwYWNrZXQiIDogImNvbW1hbmQgZGF0YSIsCgkJCQkoc2Vuc2UtPnNrc1sxXSA8PCA4KSArIHNlbnNlLT5za3NbMl0pOwoKCQkJaWYgKChzZW5zZS0+c2tzWzBdICYgMHg0MCkgIT0gMCkKCQkJCXByaW50ayAoIiBiaXQgJWQiLCBzZW5zZS0+c2tzWzBdICYgMHgwNyk7CgoJCQlwcmludGsgKCJcbiIpOwoJCX0KCX0KCiNlbHNlIC8qIG5vdCBWRVJCT1NFX0lERV9DRF9FUlJPUlMgKi8KCgkvKiBTdXBwcmVzcyBwcmludGluZyB1bml0IGF0dGVudGlvbiBhbmQgYGluIHByb2dyZXNzIG9mIGJlY29taW5nIHJlYWR5JwoJICAgZXJyb3JzIHdoZW4gd2UncmUgbm90IGJlaW5nIHZlcmJvc2UuICovCgoJaWYgKHNlbnNlLT5zZW5zZV9rZXkgPT0gVU5JVF9BVFRFTlRJT04gfHwKCSAgICAoc2Vuc2UtPnNlbnNlX2tleSA9PSBOT1RfUkVBRFkgJiYgKHNlbnNlLT5hc2MgPT0gNCB8fAoJCQkJCQlzZW5zZS0+YXNjID09IDB4M2EpKSkKCQlyZXR1cm47CgoJcHJpbnRrKEtFUk5fRVJSICIlczogZXJyb3IgY29kZTogMHglMDJ4ICBzZW5zZV9rZXk6IDB4JTAyeCAgYXNjOiAweCUwMnggIGFzY3E6IDB4JTAyeFxuIiwKCQlkcml2ZS0+bmFtZSwKCQlzZW5zZS0+ZXJyb3JfY29kZSwgc2Vuc2UtPnNlbnNlX2tleSwKCQlzZW5zZS0+YXNjLCBzZW5zZS0+YXNjcSk7CiNlbmRpZiAvKiBub3QgVkVSQk9TRV9JREVfQ0RfRVJST1JTICovCn0KCi8qCiAqIEluaXRpYWxpemUgYSBpZGUtY2QgcGFja2V0IGNvbW1hbmQgcmVxdWVzdAogKi8Kc3RhdGljIHZvaWQgY2Ryb21fcHJlcGFyZV9yZXF1ZXN0KGlkZV9kcml2ZV90ICpkcml2ZSwgc3RydWN0IHJlcXVlc3QgKnJxKQp7CglzdHJ1Y3QgY2Ryb21faW5mbyAqY2QgPSBkcml2ZS0+ZHJpdmVyX2RhdGE7CgoJaWRlX2luaXRfZHJpdmVfY21kKHJxKTsKCXJxLT5mbGFncyA9IFJFUV9QQzsKCXJxLT5ycV9kaXNrID0gY2QtPmRpc2s7Cn0KCnN0YXRpYyB2b2lkIGNkcm9tX3F1ZXVlX3JlcXVlc3Rfc2Vuc2UoaWRlX2RyaXZlX3QgKmRyaXZlLCB2b2lkICpzZW5zZSwKCQkJCSAgICAgIHN0cnVjdCByZXF1ZXN0ICpmYWlsZWRfY29tbWFuZCkKewoJc3RydWN0IGNkcm9tX2luZm8gKmluZm8JCT0gZHJpdmUtPmRyaXZlcl9kYXRhOwoJc3RydWN0IHJlcXVlc3QgKnJxCQk9ICZpbmZvLT5yZXF1ZXN0X3NlbnNlX3JlcXVlc3Q7CgoJaWYgKHNlbnNlID09IE5VTEwpCgkJc2Vuc2UgPSAmaW5mby0+c2Vuc2VfZGF0YTsKCgkvKiBzdHVmZiB0aGUgc2Vuc2UgcmVxdWVzdCBpbiBmcm9udCBvZiBvdXIgY3VycmVudCByZXF1ZXN0ICovCgljZHJvbV9wcmVwYXJlX3JlcXVlc3QoZHJpdmUsIHJxKTsKCglycS0+ZGF0YSA9IHNlbnNlOwoJcnEtPmNtZFswXSA9IEdQQ01EX1JFUVVFU1RfU0VOU0U7CglycS0+Y21kWzRdID0gcnEtPmRhdGFfbGVuID0gMTg7CgoJcnEtPmZsYWdzID0gUkVRX1NFTlNFOwoKCS8qIE5PVEUhIFNhdmUgdGhlIGZhaWxlZCBjb21tYW5kIGluICJycS0+YnVmZmVyIiAqLwoJcnEtPmJ1ZmZlciA9ICh2b2lkICopIGZhaWxlZF9jb21tYW5kOwoKCSh2b2lkKSBpZGVfZG9fZHJpdmVfY21kKGRyaXZlLCBycSwgaWRlX3ByZWVtcHQpOwp9CgpzdGF0aWMgdm9pZCBjZHJvbV9lbmRfcmVxdWVzdCAoaWRlX2RyaXZlX3QgKmRyaXZlLCBpbnQgdXB0b2RhdGUpCnsKCXN0cnVjdCByZXF1ZXN0ICpycSA9IEhXR1JPVVAoZHJpdmUpLT5ycTsKCWludCBuc2VjdG9ycyA9IHJxLT5oYXJkX2N1cl9zZWN0b3JzOwoKCWlmICgocnEtPmZsYWdzICYgUkVRX1NFTlNFKSAmJiB1cHRvZGF0ZSkgewoJCS8qCgkJICogRm9yIFJFUV9TRU5TRSwgInJxLT5idWZmZXIiIHBvaW50cyB0byB0aGUgb3JpZ2luYWwgZmFpbGVkCgkJICogcmVxdWVzdAoJCSAqLwoJCXN0cnVjdCByZXF1ZXN0ICpmYWlsZWQgPSAoc3RydWN0IHJlcXVlc3QgKikgcnEtPmJ1ZmZlcjsKCQlzdHJ1Y3QgY2Ryb21faW5mbyAqaW5mbyA9IGRyaXZlLT5kcml2ZXJfZGF0YTsKCQl2b2lkICpzZW5zZSA9ICZpbmZvLT5zZW5zZV9kYXRhOwoJCXVuc2lnbmVkIGxvbmcgZmxhZ3M7CgoJCWlmIChmYWlsZWQpIHsKCQkJaWYgKGZhaWxlZC0+c2Vuc2UpIHsKCQkJCXNlbnNlID0gZmFpbGVkLT5zZW5zZTsKCQkJCWZhaWxlZC0+c2Vuc2VfbGVuID0gcnEtPnNlbnNlX2xlbjsKCQkJfQoKCQkJLyoKCQkJICogbm93IGVuZCBmYWlsZWQgcmVxdWVzdAoJCQkgKi8KCQkJc3Bpbl9sb2NrX2lycXNhdmUoJmlkZV9sb2NrLCBmbGFncyk7CgkJCWVuZF90aGF0X3JlcXVlc3RfY2h1bmsoZmFpbGVkLCAwLCBmYWlsZWQtPmRhdGFfbGVuKTsKCQkJZW5kX3RoYXRfcmVxdWVzdF9sYXN0KGZhaWxlZCwgMCk7CgkJCXNwaW5fdW5sb2NrX2lycXJlc3RvcmUoJmlkZV9sb2NrLCBmbGFncyk7CgkJfQoKCQljZHJvbV9hbmFseXplX3NlbnNlX2RhdGEoZHJpdmUsIGZhaWxlZCwgc2Vuc2UpOwoJfQoKCWlmICghcnEtPmN1cnJlbnRfbnJfc2VjdG9ycyAmJiBibGtfZnNfcmVxdWVzdChycSkpCgkJdXB0b2RhdGUgPSAxOwoJLyogbWFrZSBzdXJlIGl0J3MgZnVsbHkgZW5kZWQgKi8KCWlmIChibGtfcGNfcmVxdWVzdChycSkpCgkJbnNlY3RvcnMgPSAocnEtPmRhdGFfbGVuICsgNTExKSA+PiA5OwoJaWYgKCFuc2VjdG9ycykKCQluc2VjdG9ycyA9IDE7CgoJaWRlX2VuZF9yZXF1ZXN0KGRyaXZlLCB1cHRvZGF0ZSwgbnNlY3RvcnMpOwp9CgovKiBSZXR1cm5zIDAgaWYgdGhlIHJlcXVlc3Qgc2hvdWxkIGJlIGNvbnRpbnVlZC4KICAgUmV0dXJucyAxIGlmIHRoZSByZXF1ZXN0IHdhcyBlbmRlZC4gKi8Kc3RhdGljIGludCBjZHJvbV9kZWNvZGVfc3RhdHVzKGlkZV9kcml2ZV90ICpkcml2ZSwgaW50IGdvb2Rfc3RhdCwgaW50ICpzdGF0X3JldCkKewoJc3RydWN0IHJlcXVlc3QgKnJxID0gSFdHUk9VUChkcml2ZSktPnJxOwoJaW50IHN0YXQsIGVyciwgc2Vuc2Vfa2V5OwoJCgkvKiBDaGVjayBmb3IgZXJyb3JzLiAqLwoJc3RhdCA9IEhXSUYoZHJpdmUpLT5JTkIoSURFX1NUQVRVU19SRUcpOwoJaWYgKHN0YXRfcmV0KQoJCSpzdGF0X3JldCA9IHN0YXQ7CgoJaWYgKE9LX1NUQVQoc3RhdCwgZ29vZF9zdGF0LCBCQURfUl9TVEFUKSkKCQlyZXR1cm4gMDsKCgkvKiBHZXQgdGhlIElERSBlcnJvciByZWdpc3Rlci4gKi8KCWVyciA9IEhXSUYoZHJpdmUpLT5JTkIoSURFX0VSUk9SX1JFRyk7CglzZW5zZV9rZXkgPSBlcnIgPj4gNDsKCglpZiAocnEgPT0gTlVMTCkgewoJCXByaW50aygiJXM6IG1pc3NpbmcgcnEgaW4gY2Ryb21fZGVjb2RlX3N0YXR1c1xuIiwgZHJpdmUtPm5hbWUpOwoJCXJldHVybiAxOwoJfQoKCWlmIChycS0+ZmxhZ3MgJiBSRVFfU0VOU0UpIHsKCQkvKiBXZSBnb3QgYW4gZXJyb3IgdHJ5aW5nIHRvIGdldCBzZW5zZSBpbmZvCgkJICAgZnJvbSB0aGUgZHJpdmUgKHByb2JhYmx5IHdoaWxlIHRyeWluZwoJCSAgIHRvIHJlY292ZXIgZnJvbSBhIGZvcm1lciBlcnJvcikuICBKdXN0IGdpdmUgdXAuICovCgoJCXJxLT5mbGFncyB8PSBSRVFfRkFJTEVEOwoJCWNkcm9tX2VuZF9yZXF1ZXN0KGRyaXZlLCAwKTsKCQlpZGVfZXJyb3IoZHJpdmUsICJyZXF1ZXN0IHNlbnNlIGZhaWx1cmUiLCBzdGF0KTsKCQlyZXR1cm4gMTsKCgl9IGVsc2UgaWYgKHJxLT5mbGFncyAmIChSRVFfUEMgfCBSRVFfQkxPQ0tfUEMpKSB7CgkJLyogQWxsIG90aGVyIGZ1bmN0aW9ucywgZXhjZXB0IGZvciBSRUFELiAqLwoJCXVuc2lnbmVkIGxvbmcgZmxhZ3M7CgoJCS8qCgkJICogaWYgd2UgaGF2ZSBhbiBlcnJvciwgcGFzcyBiYWNrIENIRUNLX0NPTkRJVElPTiBhcyB0aGUKCQkgKiBzY3NpIHN0YXR1cyBieXRlCgkJICovCgkJaWYgKChycS0+ZmxhZ3MgJiBSRVFfQkxPQ0tfUEMpICYmICFycS0+ZXJyb3JzKQoJCQlycS0+ZXJyb3JzID0gU0FNX1NUQVRfQ0hFQ0tfQ09ORElUSU9OOwoKCQkvKiBDaGVjayBmb3IgdHJheSBvcGVuLiAqLwoJCWlmIChzZW5zZV9rZXkgPT0gTk9UX1JFQURZKSB7CgkJCWNkcm9tX3Nhd19tZWRpYV9jaGFuZ2UgKGRyaXZlKTsKCQl9IGVsc2UgaWYgKHNlbnNlX2tleSA9PSBVTklUX0FUVEVOVElPTikgewoJCQkvKiBDaGVjayBmb3IgbWVkaWEgY2hhbmdlLiAqLwoJCQljZHJvbV9zYXdfbWVkaWFfY2hhbmdlIChkcml2ZSk7CgkJCS8qcHJpbnRrKCIlczogbWVkaWEgY2hhbmdlZFxuIixkcml2ZS0+bmFtZSk7Ki8KCQkJcmV0dXJuIDA7CgkJfSBlbHNlIGlmICghKHJxLT5mbGFncyAmIFJFUV9RVUlFVCkpIHsKCQkJLyogT3RoZXJ3aXNlLCBwcmludCBhbiBlcnJvci4gKi8KCQkJaWRlX2R1bXBfc3RhdHVzKGRyaXZlLCAicGFja2V0IGNvbW1hbmQgZXJyb3IiLCBzdGF0KTsKCQl9CgkJCgkJcnEtPmZsYWdzIHw9IFJFUV9GQUlMRUQ7CgoJCS8qCgkJICogaW5zdGVhZCBvZiBwbGF5aW5nIGdhbWVzIHdpdGggbW92aW5nIGNvbXBsZXRpb25zIGFyb3VuZCwKCQkgKiByZW1vdmUgZmFpbGVkIHJlcXVlc3QgY29tcGxldGVseSBhbmQgZW5kIGl0IHdoZW4gdGhlCgkJICogcmVxdWVzdCBzZW5zZSBoYXMgY29tcGxldGVkCgkJICovCgkJaWYgKHN0YXQgJiBFUlJfU1RBVCkgewoJCQlzcGluX2xvY2tfaXJxc2F2ZSgmaWRlX2xvY2ssIGZsYWdzKTsKCQkJYmxrZGV2X2RlcXVldWVfcmVxdWVzdChycSk7CgkJCUhXR1JPVVAoZHJpdmUpLT5ycSA9IE5VTEw7CgkJCXNwaW5fdW5sb2NrX2lycXJlc3RvcmUoJmlkZV9sb2NrLCBmbGFncyk7CgoJCQljZHJvbV9xdWV1ZV9yZXF1ZXN0X3NlbnNlKGRyaXZlLCBycS0+c2Vuc2UsIHJxKTsKCQl9IGVsc2UKCQkJY2Ryb21fZW5kX3JlcXVlc3QoZHJpdmUsIDApOwoKCX0gZWxzZSBpZiAoYmxrX2ZzX3JlcXVlc3QocnEpKSB7CgkJaW50IGRvX2VuZF9yZXF1ZXN0ID0gMDsKCgkJLyogSGFuZGxlIGVycm9ycyBmcm9tIFJFQUQgYW5kIFdSSVRFIHJlcXVlc3RzLiAqLwoKCQlpZiAoYmxrX25vcmV0cnlfcmVxdWVzdChycSkpCgkJCWRvX2VuZF9yZXF1ZXN0ID0gMTsKCgkJaWYgKHNlbnNlX2tleSA9PSBOT1RfUkVBRFkpIHsKCQkJLyogVHJheSBvcGVuLiAqLwoJCQlpZiAocnFfZGF0YV9kaXIocnEpID09IFJFQUQpIHsKCQkJCWNkcm9tX3Nhd19tZWRpYV9jaGFuZ2UgKGRyaXZlKTsKCgkJCQkvKiBGYWlsIHRoZSByZXF1ZXN0LiAqLwoJCQkJcHJpbnRrICgiJXM6IHRyYXkgb3BlblxuIiwgZHJpdmUtPm5hbWUpOwoJCQkJZG9fZW5kX3JlcXVlc3QgPSAxOwoJCQl9IGVsc2UgewoJCQkJc3RydWN0IGNkcm9tX2luZm8gKmluZm8gPSBkcml2ZS0+ZHJpdmVyX2RhdGE7CgoJCQkJLyogYWxsb3cgdGhlIGRyaXZlIDUgc2Vjb25kcyB0byByZWNvdmVyLCBzb21lCgkJCQkgKiBkZXZpY2VzIHdpbGwgcmV0dXJuIHRoaXMgZXJyb3Igd2hpbGUgZmx1c2hpbmcKCQkJCSAqIGRhdGEgZnJvbSBjYWNoZSAqLwoJCQkJaWYgKCFycS0+ZXJyb3JzKQoJCQkJCWluZm8tPndyaXRlX3RpbWVvdXQgPSBqaWZmaWVzICsgQVRBUElfV0FJVF9XUklURV9CVVNZOwoJCQkJcnEtPmVycm9ycyA9IDE7CgkJCQlpZiAodGltZV9hZnRlcihqaWZmaWVzLCBpbmZvLT53cml0ZV90aW1lb3V0KSkKCQkJCQlkb19lbmRfcmVxdWVzdCA9IDE7CgkJCQllbHNlIHsKCQkJCQl1bnNpZ25lZCBsb25nIGZsYWdzOwoKCQkJCQkvKgoJCQkJCSAqIHRha2UgYSBicmVhdGhlciByZWx5aW5nIG9uIHRoZQoJCQkJCSAqIHVucGx1ZyB0aW1lciB0byBraWNrIHVzIGFnYWluCgkJCQkJICovCgkJCQkJc3Bpbl9sb2NrX2lycXNhdmUoJmlkZV9sb2NrLCBmbGFncyk7CgkJCQkJYmxrX3BsdWdfZGV2aWNlKGRyaXZlLT5xdWV1ZSk7CgkJCQkJc3Bpbl91bmxvY2tfaXJxcmVzdG9yZSgmaWRlX2xvY2ssZmxhZ3MpOwoJCQkJCXJldHVybiAxOwoJCQkJfQoJCQl9CgkJfSBlbHNlIGlmIChzZW5zZV9rZXkgPT0gVU5JVF9BVFRFTlRJT04pIHsKCQkJLyogTWVkaWEgY2hhbmdlLiAqLwoJCQljZHJvbV9zYXdfbWVkaWFfY2hhbmdlIChkcml2ZSk7CgoJCQkvKiBBcnJhbmdlIHRvIHJldHJ5IHRoZSByZXF1ZXN0LgoJCQkgICBCdXQgYmUgc3VyZSB0byBnaXZlIHVwIGlmIHdlJ3ZlIHJldHJpZWQKCQkJICAgdG9vIG1hbnkgdGltZXMuICovCgkJCWlmICgrK3JxLT5lcnJvcnMgPiBFUlJPUl9NQVgpCgkJCQlkb19lbmRfcmVxdWVzdCA9IDE7CgkJfSBlbHNlIGlmIChzZW5zZV9rZXkgPT0gSUxMRUdBTF9SRVFVRVNUIHx8CgkJCSAgIHNlbnNlX2tleSA9PSBEQVRBX1BST1RFQ1QpIHsKCQkJLyogTm8gcG9pbnQgaW4gcmV0cnlpbmcgYWZ0ZXIgYW4gaWxsZWdhbAoJCQkgICByZXF1ZXN0IG9yIGRhdGEgcHJvdGVjdCBlcnJvci4qLwoJCQlpZGVfZHVtcF9zdGF0dXMgKGRyaXZlLCAiY29tbWFuZCBlcnJvciIsIHN0YXQpOwoJCQlkb19lbmRfcmVxdWVzdCA9IDE7CgkJfSBlbHNlIGlmIChzZW5zZV9rZXkgPT0gTUVESVVNX0VSUk9SKSB7CgkJCS8qIE5vIHBvaW50IGluIHJlLXRyeWluZyBhIHppbGxpb24gdGltZXMgb24gYSBiYWQgCgkJCSAqIHNlY3Rvci4uLiAgSWYgd2UgZ290IGhlcmUgdGhlIGVycm9yIGlzIG5vdCBjb3JyZWN0YWJsZSAqLwoJCQlpZGVfZHVtcF9zdGF0dXMgKGRyaXZlLCAibWVkaWEgZXJyb3IgKGJhZCBzZWN0b3IpIiwgc3RhdCk7CgkJCWRvX2VuZF9yZXF1ZXN0ID0gMTsKCQl9IGVsc2UgaWYgKHNlbnNlX2tleSA9PSBCTEFOS19DSEVDSykgewoJCQkvKiBEaXNrIGFwcGVhcnMgYmxhbmsgPz8gKi8KCQkJaWRlX2R1bXBfc3RhdHVzIChkcml2ZSwgIm1lZGlhIGVycm9yIChibGFuaykiLCBzdGF0KTsKCQkJZG9fZW5kX3JlcXVlc3QgPSAxOwoJCX0gZWxzZSBpZiAoKGVyciAmIH5BQlJUX0VSUikgIT0gMCkgewoJCQkvKiBHbyB0byB0aGUgZGVmYXVsdCBoYW5kbGVyCgkJCSAgIGZvciBvdGhlciBlcnJvcnMuICovCgkJCWlkZV9lcnJvcihkcml2ZSwgImNkcm9tX2RlY29kZV9zdGF0dXMiLCBzdGF0KTsKCQkJcmV0dXJuIDE7CgkJfSBlbHNlIGlmICgoKytycS0+ZXJyb3JzID4gRVJST1JfTUFYKSkgewoJCQkvKiBXZSd2ZSByYWNrZWQgdXAgdG9vIG1hbnkgcmV0cmllcy4gIEFib3J0LiAqLwoJCQlkb19lbmRfcmVxdWVzdCA9IDE7CgkJfQoKCQlpZiAoZG9fZW5kX3JlcXVlc3QpCgkJCWNkcm9tX2VuZF9yZXF1ZXN0KGRyaXZlLCAwKTsKCgkJLyogSWYgd2UgZ290IGEgQ0hFQ0tfQ09ORElUSU9OIHN0YXR1cywKCQkgICBxdWV1ZSBhIHJlcXVlc3Qgc2Vuc2UgY29tbWFuZC4gKi8KCQlpZiAoKHN0YXQgJiBFUlJfU1RBVCkgIT0gMCkKCQkJY2Ryb21fcXVldWVfcmVxdWVzdF9zZW5zZShkcml2ZSwgTlVMTCwgTlVMTCk7Cgl9IGVsc2UgewoJCWJsa19kdW1wX3JxX2ZsYWdzKHJxLCAiaWRlLWNkOiBiYWQgcnEiKTsKCQljZHJvbV9lbmRfcmVxdWVzdChkcml2ZSwgMCk7Cgl9CgoJLyogUmV0cnksIG9yIGhhbmRsZSB0aGUgbmV4dCByZXF1ZXN0LiAqLwoJcmV0dXJuIDE7Cn0KCnN0YXRpYyBpbnQgY2Ryb21fdGltZXJfZXhwaXJ5KGlkZV9kcml2ZV90ICpkcml2ZSkKewoJc3RydWN0IHJlcXVlc3QgKnJxID0gSFdHUk9VUChkcml2ZSktPnJxOwoJdW5zaWduZWQgbG9uZyB3YWl0ID0gMDsKCgkvKgoJICogU29tZSBjb21tYW5kcyBhcmUgKnNsb3cqIGFuZCBub3JtYWxseSB0YWtlIGEgbG9uZyB0aW1lIHRvCgkgKiBjb21wbGV0ZS4gVXN1YWxseSB3ZSBjYW4gdXNlIHRoZSBBVEFQSSAiZGlzY29ubmVjdCIgdG8gYnlwYXNzCgkgKiB0aGlzLCBidXQgbm90IGFsbCBjb21tYW5kcy9kcml2ZXMgc3VwcG9ydCB0aGF0LiBMZXQKCSAqIGlkZV90aW1lcl9leHBpcnkga2VlcCBwb2xsaW5nIHVzIGZvciB0aGVzZS4KCSAqLwoJc3dpdGNoIChycS0+Y21kWzBdKSB7CgkJY2FzZSBHUENNRF9CTEFOSzoKCQljYXNlIEdQQ01EX0ZPUk1BVF9VTklUOgoJCWNhc2UgR1BDTURfUkVTRVJWRV9SWk9ORV9UUkFDSzoKCQljYXNlIEdQQ01EX0NMT1NFX1RSQUNLOgoJCWNhc2UgR1BDTURfRkxVU0hfQ0FDSEU6CgkJCXdhaXQgPSBBVEFQSV9XQUlUX1BDOwoJCQlicmVhazsKCQlkZWZhdWx0OgoJCQlpZiAoIShycS0+ZmxhZ3MgJiBSRVFfUVVJRVQpKQoJCQkJcHJpbnRrKEtFUk5fSU5GTyAiaWRlLWNkOiBjbWQgMHgleCB0aW1lZCBvdXRcbiIsIHJxLT5jbWRbMF0pOwoJCQl3YWl0ID0gMDsKCQkJYnJlYWs7Cgl9CglyZXR1cm4gd2FpdDsKfQoKLyogU2V0IHVwIHRoZSBkZXZpY2UgcmVnaXN0ZXJzIGZvciB0cmFuc2ZlcnJpbmcgYSBwYWNrZXQgY29tbWFuZCBvbiBERVYsCiAgIGV4cGVjdGluZyB0byBsYXRlciB0cmFuc2ZlciBYRkVSTEVOIGJ5dGVzLiAgSEFORExFUiBpcyB0aGUgcm91dGluZQogICB3aGljaCBhY3R1YWxseSB0cmFuc2ZlcnMgdGhlIGNvbW1hbmQgdG8gdGhlIGRyaXZlLiAgSWYgdGhpcyBpcyBhCiAgIGRycV9pbnRlcnJ1cHQgZGV2aWNlLCB0aGlzIHJvdXRpbmUgd2lsbCBhcnJhbmdlIGZvciBIQU5ETEVSIHRvIGJlCiAgIGNhbGxlZCB3aGVuIHRoZSBpbnRlcnJ1cHQgZnJvbSB0aGUgZHJpdmUgYXJyaXZlcy4gIE90aGVyd2lzZSwgSEFORExFUgogICB3aWxsIGJlIGNhbGxlZCBpbW1lZGlhdGVseSBhZnRlciB0aGUgZHJpdmUgaXMgcHJlcGFyZWQgZm9yIHRoZSB0cmFuc2Zlci4gKi8KCnN0YXRpYyBpZGVfc3RhcnRzdG9wX3QgY2Ryb21fc3RhcnRfcGFja2V0X2NvbW1hbmQoaWRlX2RyaXZlX3QgKmRyaXZlLAoJCQkJCQkgIGludCB4ZmVybGVuLAoJCQkJCQkgIGlkZV9oYW5kbGVyX3QgKmhhbmRsZXIpCnsKCWlkZV9zdGFydHN0b3BfdCBzdGFydHN0b3A7CglzdHJ1Y3QgY2Ryb21faW5mbyAqaW5mbyA9IGRyaXZlLT5kcml2ZXJfZGF0YTsKCWlkZV9od2lmX3QgKmh3aWYgPSBkcml2ZS0+aHdpZjsKCgkvKiBXYWl0IGZvciB0aGUgY29udHJvbGxlciB0byBiZSBpZGxlLiAqLwoJaWYgKGlkZV93YWl0X3N0YXQoJnN0YXJ0c3RvcCwgZHJpdmUsIDAsIEJVU1lfU1RBVCwgV0FJVF9SRUFEWSkpCgkJcmV0dXJuIHN0YXJ0c3RvcDsKCglpZiAoaW5mby0+ZG1hKQoJCWluZm8tPmRtYSA9ICFod2lmLT5kbWFfc2V0dXAoZHJpdmUpOwoKCS8qIFNldCB1cCB0aGUgY29udHJvbGxlciByZWdpc3RlcnMuICovCgkvKiBGSVhNRTogZm9yIFZpcnR1YWwgRE1BIHdlIG11c3QgY2hlY2sgaGFyZGVyICovCglIV0lGKGRyaXZlKS0+T1VUQihpbmZvLT5kbWEsIElERV9GRUFUVVJFX1JFRyk7CglIV0lGKGRyaXZlKS0+T1VUQigwLCBJREVfSVJFQVNPTl9SRUcpOwoJSFdJRihkcml2ZSktPk9VVEIoMCwgSURFX1NFQ1RPUl9SRUcpOwoKCUhXSUYoZHJpdmUpLT5PVVRCKHhmZXJsZW4gJiAweGZmLCBJREVfQkNPVU5UTF9SRUcpOwoJSFdJRihkcml2ZSktPk9VVEIoeGZlcmxlbiA+PiA4ICAsIElERV9CQ09VTlRIX1JFRyk7CglpZiAoSURFX0NPTlRST0xfUkVHKQoJCUhXSUYoZHJpdmUpLT5PVVRCKGRyaXZlLT5jdGwsIElERV9DT05UUk9MX1JFRyk7CiAKCWlmIChDRFJPTV9DT05GSUdfRkxBR1MgKGRyaXZlKS0+ZHJxX2ludGVycnVwdCkgewoJCS8qIHBhY2tldCBjb21tYW5kICovCgkJaWRlX2V4ZWN1dGVfY29tbWFuZChkcml2ZSwgV0lOX1BBQ0tFVENNRCwgaGFuZGxlciwgQVRBUElfV0FJVF9QQywgY2Ryb21fdGltZXJfZXhwaXJ5KTsKCQlyZXR1cm4gaWRlX3N0YXJ0ZWQ7Cgl9IGVsc2UgewoJCXVuc2lnbmVkIGxvbmcgZmxhZ3M7CgoJCS8qIHBhY2tldCBjb21tYW5kICovCgkJc3Bpbl9sb2NrX2lycXNhdmUoJmlkZV9sb2NrLCBmbGFncyk7CgkJaHdpZi0+T1VUQlNZTkMoZHJpdmUsIFdJTl9QQUNLRVRDTUQsIElERV9DT01NQU5EX1JFRyk7CgkJbmRlbGF5KDQwMCk7CgkJc3Bpbl91bmxvY2tfaXJxcmVzdG9yZSgmaWRlX2xvY2ssIGZsYWdzKTsKCgkJcmV0dXJuICgqaGFuZGxlcikgKGRyaXZlKTsKCX0KfQoKLyogU2VuZCBhIHBhY2tldCBjb21tYW5kIHRvIERSSVZFIGRlc2NyaWJlZCBieSBDTURfQlVGIGFuZCBDTURfTEVOLgogICBUaGUgZGV2aWNlIHJlZ2lzdGVycyBtdXN0IGhhdmUgYWxyZWFkeSBiZWVuIHByZXBhcmVkCiAgIGJ5IGNkcm9tX3N0YXJ0X3BhY2tldF9jb21tYW5kLgogICBIQU5ETEVSIGlzIHRoZSBpbnRlcnJ1cHQgaGFuZGxlciB0byBjYWxsIHdoZW4gdGhlIGNvbW1hbmQgY29tcGxldGVzCiAgIG9yIHRoZXJlJ3MgZGF0YSByZWFkeS4gKi8KLyoKICogY2hhbmdlZCA1IHBhcmFtZXRlcnMgdG8gMyBmb3IgZHZkLXJhbQogKiBzdHJ1Y3QgcGFja2V0X2NvbW1hbmQgKnBjOyBub3cgcGFja2V0X2NvbW1hbmRfdCAqcGM7CiAqLwojZGVmaW5lIEFUQVBJX01JTl9DREJfQllURVMgMTIKc3RhdGljIGlkZV9zdGFydHN0b3BfdCBjZHJvbV90cmFuc2Zlcl9wYWNrZXRfY29tbWFuZCAoaWRlX2RyaXZlX3QgKmRyaXZlLAoJCQkJCSAgc3RydWN0IHJlcXVlc3QgKnJxLAoJCQkJCSAgaWRlX2hhbmRsZXJfdCAqaGFuZGxlcikKewoJaWRlX2h3aWZfdCAqaHdpZiA9IGRyaXZlLT5od2lmOwoJaW50IGNtZF9sZW47CglzdHJ1Y3QgY2Ryb21faW5mbyAqaW5mbyA9IGRyaXZlLT5kcml2ZXJfZGF0YTsKCWlkZV9zdGFydHN0b3BfdCBzdGFydHN0b3A7CgoJaWYgKENEUk9NX0NPTkZJR19GTEFHUyhkcml2ZSktPmRycV9pbnRlcnJ1cHQpIHsKCQkvKiBIZXJlIHdlIHNob3VsZCBoYXZlIGJlZW4gY2FsbGVkIGFmdGVyIHJlY2VpdmluZyBhbiBpbnRlcnJ1cHQKCQkgICBmcm9tIHRoZSBkZXZpY2UuICBEUlEgc2hvdWxkIGhvdyBiZSBzZXQuICovCgoJCS8qIENoZWNrIGZvciBlcnJvcnMuICovCgkJaWYgKGNkcm9tX2RlY29kZV9zdGF0dXMoZHJpdmUsIERSUV9TVEFULCBOVUxMKSkKCQkJcmV0dXJuIGlkZV9zdG9wcGVkOwoJfSBlbHNlIHsKCQkvKiBPdGhlcndpc2UsIHdlIG11c3Qgd2FpdCBmb3IgRFJRIHRvIGdldCBzZXQuICovCgkJaWYgKGlkZV93YWl0X3N0YXQoJnN0YXJ0c3RvcCwgZHJpdmUsIERSUV9TVEFULAoJCQkJQlVTWV9TVEFULCBXQUlUX1JFQURZKSkKCQkJcmV0dXJuIHN0YXJ0c3RvcDsKCX0KCgkvKiBBcm0gdGhlIGludGVycnVwdCBoYW5kbGVyLiAqLwoJaWRlX3NldF9oYW5kbGVyKGRyaXZlLCBoYW5kbGVyLCBycS0+dGltZW91dCwgY2Ryb21fdGltZXJfZXhwaXJ5KTsKCgkvKiBBVEFQSSBjb21tYW5kcyBnZXQgcGFkZGVkIG91dCB0byAxMiBieXRlcyBtaW5pbXVtICovCgljbWRfbGVuID0gQ09NTUFORF9TSVpFKHJxLT5jbWRbMF0pOwoJaWYgKGNtZF9sZW4gPCBBVEFQSV9NSU5fQ0RCX0JZVEVTKQoJCWNtZF9sZW4gPSBBVEFQSV9NSU5fQ0RCX0JZVEVTOwoKCS8qIFNlbmQgdGhlIGNvbW1hbmQgdG8gdGhlIGRldmljZS4gKi8KCUhXSUYoZHJpdmUpLT5hdGFwaV9vdXRwdXRfYnl0ZXMoZHJpdmUsIHJxLT5jbWQsIGNtZF9sZW4pOwoKCS8qIFN0YXJ0IHRoZSBETUEgaWYgbmVlZCBiZSAqLwoJaWYgKGluZm8tPmRtYSkKCQlod2lmLT5kbWFfc3RhcnQoZHJpdmUpOwoKCXJldHVybiBpZGVfc3RhcnRlZDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogQmxvY2sgcmVhZCBmdW5jdGlvbnMuCiAqLwoKLyoKICogQnVmZmVyIHVwIHRvIFNFQ1RPUlNfVE9fVFJBTlNGRVIgc2VjdG9ycyBmcm9tIHRoZSBkcml2ZSBpbiBvdXIgc2VjdG9yCiAqIGJ1ZmZlci4gIE9uY2UgdGhlIGZpcnN0IHNlY3RvciBpcyBhZGRlZCwgYW55IHN1YnNlcXVlbnQgc2VjdG9ycyBhcmUKICogYXNzdW1lZCB0byBiZSBjb250aW51b3VzICh1bnRpbCB0aGUgYnVmZmVyIGlzIGNsZWFyZWQpLiAgRm9yIHRoZSBmaXJzdAogKiBzZWN0b3IgYWRkZWQsIFNFQ1RPUiBpcyBpdHMgc2VjdG9yIG51bWJlci4gIChTRUNUT1IgaXMgdGhlbiBpZ25vcmVkIHVudGlsCiAqIHRoZSBidWZmZXIgaXMgY2xlYXJlZC4pCiAqLwpzdGF0aWMgdm9pZCBjZHJvbV9idWZmZXJfc2VjdG9ycyAoaWRlX2RyaXZlX3QgKmRyaXZlLCB1bnNpZ25lZCBsb25nIHNlY3RvciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBzZWN0b3JzX3RvX3RyYW5zZmVyKQp7CglzdHJ1Y3QgY2Ryb21faW5mbyAqaW5mbyA9IGRyaXZlLT5kcml2ZXJfZGF0YTsKCgkvKiBOdW1iZXIgb2Ygc2VjdG9ycyB0byByZWFkIGludG8gdGhlIGJ1ZmZlci4gKi8KCWludCBzZWN0b3JzX3RvX2J1ZmZlciA9IG1pbl90KGludCwgc2VjdG9yc190b190cmFuc2ZlciwKCQkJCSAgICAgKFNFQ1RPUl9CVUZGRVJfU0laRSA+PiBTRUNUT1JfQklUUykgLQoJCQkJICAgICAgIGluZm8tPm5zZWN0b3JzX2J1ZmZlcmVkKTsKCgljaGFyICpkZXN0OwoKCS8qIElmIHdlIGNvdWxkbid0IGdldCBhIGJ1ZmZlciwgZG9uJ3QgdHJ5IHRvIGJ1ZmZlciBhbnl0aGluZy4uLiAqLwoJaWYgKGluZm8tPmJ1ZmZlciA9PSBOVUxMKQoJCXNlY3RvcnNfdG9fYnVmZmVyID0gMDsKCgkvKiBJZiB0aGlzIGlzIHRoZSBmaXJzdCBzZWN0b3IgaW4gdGhlIGJ1ZmZlciwgcmVtZW1iZXIgaXRzIG51bWJlci4gKi8KCWlmIChpbmZvLT5uc2VjdG9yc19idWZmZXJlZCA9PSAwKQoJCWluZm8tPnNlY3Rvcl9idWZmZXJlZCA9IHNlY3RvcjsKCgkvKiBSZWFkIHRoZSBkYXRhIGludG8gdGhlIGJ1ZmZlci4gKi8KCWRlc3QgPSBpbmZvLT5idWZmZXIgKyBpbmZvLT5uc2VjdG9yc19idWZmZXJlZCAqIFNFQ1RPUl9TSVpFOwoJd2hpbGUgKHNlY3RvcnNfdG9fYnVmZmVyID4gMCkgewoJCUhXSUYoZHJpdmUpLT5hdGFwaV9pbnB1dF9ieXRlcyhkcml2ZSwgZGVzdCwgU0VDVE9SX1NJWkUpOwoJCS0tc2VjdG9yc190b19idWZmZXI7CgkJLS1zZWN0b3JzX3RvX3RyYW5zZmVyOwoJCSsraW5mby0+bnNlY3RvcnNfYnVmZmVyZWQ7CgkJZGVzdCArPSBTRUNUT1JfU0laRTsKCX0KCgkvKiBUaHJvdyBhd2F5IGFueSByZW1haW5pbmcgZGF0YS4gKi8KCXdoaWxlIChzZWN0b3JzX3RvX3RyYW5zZmVyID4gMCkgewoJCXN0YXRpYyBjaGFyIGR1bVtTRUNUT1JfU0laRV07CgkJSFdJRihkcml2ZSktPmF0YXBpX2lucHV0X2J5dGVzKGRyaXZlLCBkdW0sIHNpemVvZiAoZHVtKSk7CgkJLS1zZWN0b3JzX3RvX3RyYW5zZmVyOwoJfQp9CgovKgogKiBDaGVjayB0aGUgY29udGVudHMgb2YgdGhlIGludGVycnVwdCByZWFzb24gcmVnaXN0ZXIgZnJvbSB0aGUgY2Ryb20KICogYW5kIGF0dGVtcHQgdG8gcmVjb3ZlciBpZiB0aGVyZSBhcmUgcHJvYmxlbXMuICBSZXR1cm5zICAwIGlmIGV2ZXJ5dGhpbmcncwogKiBvazsgbm9uemVybyBpZiB0aGUgcmVxdWVzdCBoYXMgYmVlbiB0ZXJtaW5hdGVkLgogKi8Kc3RhdGljCmludCBjZHJvbV9yZWFkX2NoZWNrX2lyZWFzb24gKGlkZV9kcml2ZV90ICpkcml2ZSwgaW50IGxlbiwgaW50IGlyZWFzb24pCnsKCWlmIChpcmVhc29uID09IDIpCgkJcmV0dXJuIDA7CgllbHNlIGlmIChpcmVhc29uID09IDApIHsKCQkvKiBXaG9vcHMuLi4gVGhlIGRyaXZlIGlzIGV4cGVjdGluZyB0byByZWNlaXZlIGRhdGEgZnJvbSB1cyEgKi8KCQlwcmludGsoS0VSTl9FUlIgIiVzOiByZWFkX2ludHI6IERyaXZlIHdhbnRzIHRvIHRyYW5zZmVyIGRhdGEgdGhlICIKCQkJCQkJIndyb25nIHdheSFcbiIsIGRyaXZlLT5uYW1lKTsKCgkJLyogVGhyb3cgc29tZSBkYXRhIGF0IHRoZSBkcml2ZSBzbyBpdCBkb2Vzbid0IGhhbmcKCQkgICBhbmQgcXVpdCB0aGlzIHJlcXVlc3QuICovCgkJd2hpbGUgKGxlbiA+IDApIHsKCQkJaW50IGR1bSA9IDA7CgkJCUhXSUYoZHJpdmUpLT5hdGFwaV9vdXRwdXRfYnl0ZXMoZHJpdmUsICZkdW0sIHNpemVvZiAoZHVtKSk7CgkJCWxlbiAtPSBzaXplb2YgKGR1bSk7CgkJfQoJfSBlbHNlICBpZiAoaXJlYXNvbiA9PSAxKSB7CgkJLyogU29tZSBkcml2ZXMgKEFTVVMpIHNlZW0gdG8gdGVsbCB1cyB0aGF0IHN0YXR1cwoJCSAqIGluZm8gaXMgYXZhaWxhYmxlLiBqdXN0IGdldCBpdCBhbmQgaWdub3JlLgoJCSAqLwoJCSh2b2lkKSBIV0lGKGRyaXZlKS0+SU5CKElERV9TVEFUVVNfUkVHKTsKCQlyZXR1cm4gMDsKCX0gZWxzZSB7CgkJLyogRHJpdmUgd2FudHMgYSBjb21tYW5kIHBhY2tldCwgb3IgaW52YWxpZCBpcmVhc29uLi4uICovCgkJcHJpbnRrKEtFUk5fRVJSICIlczogcmVhZF9pbnRyOiBiYWQgaW50ZXJydXB0IHJlYXNvbiAleFxuIiwgZHJpdmUtPm5hbWUsCgkJCQkJCQkJaXJlYXNvbik7Cgl9CgoJY2Ryb21fZW5kX3JlcXVlc3QoZHJpdmUsIDApOwoJcmV0dXJuIC0xOwp9CgovKgogKiBJbnRlcnJ1cHQgcm91dGluZS4gIENhbGxlZCB3aGVuIGEgcmVhZCByZXF1ZXN0IGhhcyBjb21wbGV0ZWQuCiAqLwpzdGF0aWMgaWRlX3N0YXJ0c3RvcF90IGNkcm9tX3JlYWRfaW50ciAoaWRlX2RyaXZlX3QgKmRyaXZlKQp7CglpbnQgc3RhdDsKCWludCBpcmVhc29uLCBsZW4sIHNlY3RvcnNfdG9fdHJhbnNmZXIsIG5za2lwOwoJc3RydWN0IGNkcm9tX2luZm8gKmluZm8gPSBkcml2ZS0+ZHJpdmVyX2RhdGE7Cgl1OCBsb3djeWwgPSAwLCBoaWdoY3lsID0gMDsKCWludCBkbWEgPSBpbmZvLT5kbWEsIGRtYV9lcnJvciA9IDA7CgoJc3RydWN0IHJlcXVlc3QgKnJxID0gSFdHUk9VUChkcml2ZSktPnJxOwoKCS8qCgkgKiBoYW5kbGUgZG1hIGNhc2UKCSAqLwoJaWYgKGRtYSkgewoJCWluZm8tPmRtYSA9IDA7CgkJaWYgKChkbWFfZXJyb3IgPSBIV0lGKGRyaXZlKS0+aWRlX2RtYV9lbmQoZHJpdmUpKSkKCQkJX19pZGVfZG1hX29mZihkcml2ZSk7Cgl9CgoJaWYgKGNkcm9tX2RlY29kZV9zdGF0dXMoZHJpdmUsIDAsICZzdGF0KSkKCQlyZXR1cm4gaWRlX3N0b3BwZWQ7CgoJaWYgKGRtYSkgewoJCWlmICghZG1hX2Vycm9yKSB7CgkJCWlkZV9lbmRfcmVxdWVzdChkcml2ZSwgMSwgcnEtPm5yX3NlY3RvcnMpOwoJCQlyZXR1cm4gaWRlX3N0b3BwZWQ7CgkJfSBlbHNlCgkJCXJldHVybiBpZGVfZXJyb3IoZHJpdmUsICJkbWEgZXJyb3IiLCBzdGF0KTsKCX0KCgkvKiBSZWFkIHRoZSBpbnRlcnJ1cHQgcmVhc29uIGFuZCB0aGUgdHJhbnNmZXIgbGVuZ3RoLiAqLwoJaXJlYXNvbiA9IEhXSUYoZHJpdmUpLT5JTkIoSURFX0lSRUFTT05fUkVHKSAmIDB4MzsKCWxvd2N5bCAgPSBIV0lGKGRyaXZlKS0+SU5CKElERV9CQ09VTlRMX1JFRyk7CgloaWdoY3lsID0gSFdJRihkcml2ZSktPklOQihJREVfQkNPVU5USF9SRUcpOwoKCWxlbiA9IGxvd2N5bCArICgyNTYgKiBoaWdoY3lsKTsKCgkvKiBJZiBEUlEgaXMgY2xlYXIsIHRoZSBjb21tYW5kIGhhcyBjb21wbGV0ZWQuICovCglpZiAoKHN0YXQgJiBEUlFfU1RBVCkgPT0gMCkgewoJCS8qIElmIHdlJ3JlIG5vdCBkb25lIGZpbGxpbmcgdGhlIGN1cnJlbnQgYnVmZmVyLCBjb21wbGFpbi4KCQkgICBPdGhlcndpc2UsIGNvbXBsZXRlIHRoZSBjb21tYW5kIG5vcm1hbGx5LiAqLwoJCWlmIChycS0+Y3VycmVudF9ucl9zZWN0b3JzID4gMCkgewoJCQlwcmludGsgKEtFUk5fRVJSICIlczogY2Ryb21fcmVhZF9pbnRyOiBkYXRhIHVuZGVycnVuICglZCBibG9ja3MpXG4iLAoJCQkJZHJpdmUtPm5hbWUsIHJxLT5jdXJyZW50X25yX3NlY3RvcnMpOwoJCQlycS0+ZmxhZ3MgfD0gUkVRX0ZBSUxFRDsKCQkJY2Ryb21fZW5kX3JlcXVlc3QoZHJpdmUsIDApOwoJCX0gZWxzZQoJCQljZHJvbV9lbmRfcmVxdWVzdChkcml2ZSwgMSk7CgkJcmV0dXJuIGlkZV9zdG9wcGVkOwoJfQoKCS8qIENoZWNrIHRoYXQgdGhlIGRyaXZlIGlzIGV4cGVjdGluZyB0byBkbyB0aGUgc2FtZSB0aGluZyB3ZSBhcmUuICovCglpZiAoY2Ryb21fcmVhZF9jaGVja19pcmVhc29uIChkcml2ZSwgbGVuLCBpcmVhc29uKSkKCQlyZXR1cm4gaWRlX3N0b3BwZWQ7CgoJLyogQXNzdW1lIHRoYXQgdGhlIGRyaXZlIHdpbGwgYWx3YXlzIHByb3ZpZGUgZGF0YSBpbiBtdWx0aXBsZXMKCSAgIG9mIGF0IGxlYXN0IFNFQ1RPUl9TSVpFLCBhcyBpdCBnZXRzIGhhaXJ5IHRvIGtlZXAgdHJhY2sKCSAgIG9mIHRoZSB0cmFuc2ZlcnMgb3RoZXJ3aXNlLiAqLwoJaWYgKChsZW4gJSBTRUNUT1JfU0laRSkgIT0gMCkgewoJCXByaW50ayAoS0VSTl9FUlIgIiVzOiBjZHJvbV9yZWFkX2ludHI6IEJhZCB0cmFuc2ZlciBzaXplICVkXG4iLAoJCQlkcml2ZS0+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+YnVmbGVuKTsKCQkJKi8KCQkJcnEtPmZsYWdzIHw9IFJFUV9GQUlMRUQ7CgkJCWNkcm9tX2VuZF9yZXF1ZXN0KGRyaXZlLCAwKTsKCQl9CgkJcmV0dXJuIGlkZV9zdG9wcGVkOwoJfQoKCS8qIEZpZ3VyZSBvdXQgaG93IG11Y2ggZGF0YSB0byB0cmFuc2Zlci4gKi8KCXRoaXNsZW4gPSBycS0+ZGF0YV9sZW47CglpZiAodGhpc2xlbiA+IGxlbikgdGhpc2xlbiA9IGxlbjsKCgkvKiBUaGUgZHJpdmUgd2FudHMgdG8gYmUgd3JpdHRlbiB0by4gKi8KCWlmICgoaXJlYXNvbiAmIDMpID09IDApIHsKCQlpZiAoIXJxLT5kYXRhKSB7CgkJCWJsa19kdW1wX3JxX2ZsYWdzKHJxLCAiY2Ryb21fcGNfaW50ciwgd3JpdGUiKTsKCQkJZ290byBjb25mdXNlZDsKCQl9CgkJLyogVHJhbnNmZXIgdGhlIGRhdGEuICovCgkJSFdJRihkcml2ZSktPmF0YXBpX291dHB1dF9ieXRlcyhkcml2ZSwgcnEtPmRhdGEsIHRoaXNsZW4pOwoKCQkvKiBJZiB3ZSBoYXZlbid0IG1vdmVkIGVub3VnaCBkYXRhIHRvIHNhdGlzZnkgdGhlIGRyaXZlLAoJCSAgIGFkZCBzb21lIHBhZGRpbmcuICovCgkJd2hpbGUgKGxlbiA+IHRoaXNsZW4pIHsKCQkJaW50IGR1bSA9IDA7CgkJCUhXSUYoZHJpdmUpLT5hdGFwaV9vdXRwdXRfYnl0ZXMoZHJpdmUsICZkdW0sIHNpemVvZihkdW0pKTsKCQkJbGVuIC09IHNpemVvZihkdW0pOwoJCX0KCgkJLyogS2VlcCBjb3VudCBvZiBob3cgbXVjaCBkYXRhIHdlJ3ZlIG1vdmVkLiAqLwoJCXJxLT5kYXRhICs9IHRoaXNsZW47CgkJcnEtPmRhdGFfbGVuIC09IHRoaXNsZW47Cgl9CgoJLyogU2FtZSBkcmlsbCBmb3IgcmVhZGluZy4gKi8KCWVsc2UgaWYgKChpcmVhc29uICYgMykgPT0gMikgewoJCWlmICghcnEtPmRhdGEpIHsKCQkJYmxrX2R1bXBfcnFfZmxhZ3MocnEsICJjZHJvbV9wY19pbnRyLCB3cml0ZSIpOwoJCQlnb3RvIGNvbmZ1c2VkOwoJCX0KCQkvKiBUcmFuc2ZlciB0aGUgZGF0YS4gKi8KCQlIV0lGKGRyaXZlKS0+YXRhcGlfaW5wdXRfYnl0ZXMoZHJpdmUsIHJxLT5kYXRhLCB0aGlzbGVuKTsKCgkJLyogSWYgd2UgaGF2ZW4ndCBtb3ZlZCBlbm91Z2ggZGF0YSB0byBzYXRpc2Z5IHRoZSBkcml2ZSwKCQkgICBhZGQgc29tZSBwYWRkaW5nLiAqLwoJCXdoaWxlIChsZW4gPiB0aGlzbGVuKSB7CgkJCWludCBkdW0gPSAwOwoJCQlIV0lGKGRyaXZlKS0+YXRhcGlfaW5wdXRfYnl0ZXMoZHJpdmUsICZkdW0sIHNpemVvZihkdW0pKTsKCQkJbGVuIC09IHNpemVvZihkdW0pOwoJCX0KCgkJLyogS2VlcCBjb3VudCBvZiBob3cgbXVjaCBkYXRhIHdlJ3ZlIG1vdmVkLiAqLwoJCXJxLT5kYXRhICs9IHRoaXNsZW47CgkJcnEtPmRhdGFfbGVuIC09IHRoaXNsZW47CgoJCWlmIChycS0+ZmxhZ3MgJiBSRVFfU0VOU0UpCgkJCXJxLT5zZW5zZV9sZW4gKz0gdGhpc2xlbjsKCX0gZWxzZSB7CmNvbmZ1c2VkOgoJCXByaW50ayAoS0VSTl9FUlIgIiVzOiBjZHJvbV9wY19pbnRyOiBUaGUgZHJpdmUgIgoJCQkiYXBwZWFycyBjb25mdXNlZCAoaXJlYXNvbiA9IDB4JTAyeClcbiIsCgkJCWRyaXZlLT5uYW1lLCBpcmVhc29uKTsKCQlycS0+ZmxhZ3MgfD0gUkVRX0ZBSUxFRDsKCX0KCgkvKiBOb3cgd2Ugd2FpdCBmb3IgYW5vdGhlciBpbnRlcnJ1cHQuICovCglpZGVfc2V0X2hhbmRsZXIoZHJpdmUsICZjZHJvbV9wY19pbnRyLCBBVEFQSV9XQUlUX1BDLCBjZHJvbV90aW1lcl9leHBpcnkpOwoJcmV0dXJuIGlkZV9zdGFydGVkOwp9CgpzdGF0aWMgaWRlX3N0YXJ0c3RvcF90IGNkcm9tX2RvX3BjX2NvbnRpbnVhdGlvbiAoaWRlX2RyaXZlX3QgKmRyaXZlKQp7CglzdHJ1Y3QgcmVxdWVzdCAqcnEgPSBIV0dST1VQKGRyaXZlKS0+cnE7CgoJaWYgKCFycS0+dGltZW91dCkKCQlycS0+dGltZW91dCA9IEFUQVBJX1dBSVRfUEM7CgoJLyogU2VuZCB0aGUgY29tbWFuZCB0byB0aGUgZHJpdmUgYW5kIHJldHVybi4gKi8KCXJldHVybiBjZHJvbV90cmFuc2Zlcl9wYWNrZXRfY29tbWFuZChkcml2ZSwgcnEsICZjZHJvbV9wY19pbnRyKTsKfQoKCnN0YXRpYyBpZGVfc3RhcnRzdG9wX3QgY2Ryb21fZG9fcGFja2V0X2NvbW1hbmQgKGlkZV9kcml2ZV90ICpkcml2ZSkKewoJaW50IGxlbjsKCXN0cnVjdCByZXF1ZXN0ICpycSA9IEhXR1JPVVAoZHJpdmUpLT5ycTsKCXN0cnVjdCBjZHJvbV9pbmZvICppbmZvID0gZHJpdmUtPmRyaXZlcl9kYXRhOwoKCWluZm8tPmRtYSA9IDA7CglycS0+ZmxhZ3MgJj0gflJFUV9GQUlMRUQ7CglsZW4gPSBycS0+ZGF0YV9sZW47CgoJLyogU3RhcnQgc2VuZGluZyB0aGUgY29tbWFuZCB0byB0aGUgZHJpdmUuICovCglyZXR1cm4gY2Ryb21fc3RhcnRfcGFja2V0X2NvbW1hbmQoZHJpdmUsIGxlbiwgY2Ryb21fZG9fcGNfY29udGludWF0aW9uKTsKfQoKCnN0YXRpYwppbnQgY2Ryb21fcXVldWVfcGFja2V0X2NvbW1hbmQoaWRlX2RyaXZlX3QgKmRyaXZlLCBzdHJ1Y3QgcmVxdWVzdCAqcnEpCnsKCXN0cnVjdCByZXF1ZXN0X3NlbnNlIHNlbnNlOwoJaW50IHJldHJpZXMgPSAxMDsKCXVuc2lnbmVkIGludCBmbGFncyA9IHJxLT5mbGFnczsKCglpZiAocnEtPnNlbnNlID09IE5VTEwpCgkJcnEtPnNlbnNlID0gJnNlbnNlOwoKCS8qIFN0YXJ0IG9mIHJldHJ5IGxvb3AuICovCglkbyB7CgkJaW50IGVycm9yOwoJCXVuc2lnbmVkIGxvbmcgdGltZSA9IGppZmZpZXM7CgkJcnEtPmZsYWdzID0gZmxhZ3M7CgoJCWVycm9yID0gaWRlX2RvX2RyaXZlX2NtZChkcml2ZSwgcnEsIGlkZV93YWl0KTsKCQl0aW1lID0gamlmZmllcyAtIHRpbWU7CgoJCS8qIEZJWE1FOiB3ZSBzaG91bGQgcHJvYmFibHkgYWJvcnQvcmV0cnkgb3Igc29tZXRoaW5nIAoJCSAqIGluIGNhc2Ugb2YgZmFpbHVyZSAqLwoJCWlmIChycS0+ZmxhZ3MgJiBSRVFfRkFJTEVEKSB7CgkJCS8qIFRoZSByZXF1ZXN0IGZhaWxlZC4gIFJldHJ5IGlmIGl0IHdhcyBkdWUgdG8gYSB1bml0CgkJCSAgIGF0dGVudGlvbiBzdGF0dXMKCQkJICAgKHVzdWFsbHkgbWVhbnMgbWVkaWEgd2FzIGNoYW5nZWQpLiAqLwoJCQlzdHJ1Y3QgcmVxdWVzdF9zZW5zZSAqcmVxYnVmID0gcnEtPnNlbnNlOwoKCQkJaWYgKHJlcWJ1Zi0+c2Vuc2Vfa2V5ID09IFVOSVRfQVRURU5USU9OKQoJCQkJY2Ryb21fc2F3X21lZGlhX2NoYW5nZShkcml2ZSk7CgkJCWVsc2UgaWYgKHJlcWJ1Zi0+c2Vuc2Vfa2V5ID09IE5PVF9SRUFEWSAmJgoJCQkJIHJlcWJ1Zi0+YXNjID09IDQgJiYgcmVxYnVmLT5hc2NxICE9IDQpIHsKCQkJCS8qIFRoZSBkcml2ZSBpcyBpbiB0aGUgcHJvY2VzcyBvZiBsb2FkaW5nCgkJCQkgICBhIGRpc2suICBSZXRyeSwgYnV0IHdhaXQgYSBsaXR0bGUgdG8gZ2l2ZQoJCQkJICAgdGhlIGRyaXZlIHRpbWUgdG8gY29tcGxldGUgdGhlIGxvYWQuICovCgkJCQlzc2xlZXAoMik7CgkJCX0gZWxzZSB7CgkJCQkvKiBPdGhlcndpc2UsIGRvbid0IHJldHJ5LiAqLwoJCQkJcmV0cmllcyA9IDA7CgkJCX0KCQkJLS1yZXRyaWVzOwoJCX0KCgkJLyogRW5kIG9mIHJldHJ5IGxvb3AuICovCgl9IHdoaWxlICgocnEtPmZsYWdzICYgUkVRX0ZBSUxFRCkgJiYgcmV0cmllcyA+PSAwKTsKCgkvKiBSZXR1cm4gYW4gZXJyb3IgaWYgdGhlIGNvbW1hbmQgZmFpbGVkLiAqLwoJcmV0dXJuIChycS0+ZmxhZ3MgJiBSRVFfRkFJTEVEKSA/IC1FSU8gOiAwOwp9CgovKgogKiBXcml0ZSBoYW5kbGluZwogKi8Kc3RhdGljIGludCBjZHJvbV93cml0ZV9jaGVja19pcmVhc29uKGlkZV9kcml2ZV90ICpkcml2ZSwgaW50IGxlbiwgaW50IGlyZWFzb24pCnsKCS8qIFR3byBub3RlcyBhYm91dCBJREUgaW50ZXJydXB0IHJlYXNvbiBoZXJlIC0gMCBtZWFucyB0aGF0CgkgKiB0aGUgZHJpdmUgd2FudHMgdG8gcmVjZWl2ZSBkYXRhIGZyb20gdXMsIDIgbWVhbnMgdGhhdAoJICogdGhlIGRyaXZlIGlzIGV4cGVjdGluZyB0byB0cmFuc2ZlciBkYXRhIHRvIHVzLgoJICovCglpZiAoaXJlYXNvbiA9PSAwKQoJCXJldHVybiAwOwoJZWxzZSBpZiAoaXJlYXNvbiA9PSAyKSB7CgkJLyogV2hvb3BzLi4uIFRoZSBkcml2ZSB3YW50cyB0byBzZW5kIGRhdGEuICovCgkJcHJpbnRrKEtFUk5fRVJSICIlczogd3JpdGVfaW50cjogd3JvbmcgdHJhbnNmZXIgZGlyZWN0aW9uIVxuIiwKCQkJCQkJCWRyaXZlLT5uYW1lKTsKCgkJd2hpbGUgKGxlbiA+IDApIHsKCQkJaW50IGR1bSA9IDA7CgkJCUhXSUYoZHJpdmUpLT5hdGFwaV9pbnB1dF9ieXRlcyhkcml2ZSwgJmR1bSwgc2l6ZW9mKGR1bSkpOwoJCQlsZW4gLT0gc2l6ZW9mKGR1bSk7CgkJfQoJfSBlbHNlIHsKCQkvKiBEcml2ZSB3YW50cyBhIGNvbW1hbmQgcGFja2V0LCBvciBpbnZhbGlkIGlyZWFzb24uLi4gKi8KCQlwcmludGsoS0VSTl9FUlIgIiVzOiB3cml0ZV9pbnRyOiBiYWQgaW50ZXJydXB0IHJlYXNvbiAleFxuIiwKCQkJCQkJCWRyaXZlLT5uYW1lLCBpcmVhc29uKTsKCX0KCgljZHJvbV9lbmRfcmVxdWVzdChkcml2ZSwgMCk7CglyZXR1cm4gMTsKfQoKc3RhdGljIHZvaWQgcG9zdF90cmFuc2Zvcm1fY29tbWFuZChzdHJ1Y3QgcmVxdWVzdCAqcmVxKQp7Cgl1OCAqYyA9IHJlcS0+Y21kOwoJY2hhciAqaWJ1ZjsKCglpZiAoIWJsa19wY19yZXF1ZXN0KHJlcSkpCgkJcmV0dXJuOwoKCWlmIChyZXEtPmJpbykKCQlpYnVmID0gYmlvX2RhdGEocmVxLT5iaW8pOwoJZWxzZQoJCWlidWYgPSByZXEtPmRhdGE7CgoJaWYgKCFpYnVmKQoJCXJldHVybjsKCgkvKgoJICogc2V0IGFuc2ktcmV2aXNpb24gYW5kIHJlc3BvbnNlIGRhdGEgYXMgYXRhcGkKCSAqLwoJaWYgKGNbMF0gPT0gR1BDTURfSU5RVUlSWSkgewoJCWlidWZbMl0gfD0gMjsKCQlpYnVmWzNdID0gKGlidWZbM10gJiAweGYwKSB8IDI7Cgl9Cn0KCnR5cGVkZWYgdm9pZCAoeGZlcl9mdW5jX3QpKGlkZV9kcml2ZV90ICosIHZvaWQgKiwgdTMyKTsKCi8qCiAqIGJlc3Qgd2F5IHRvIGRlYWwgd2l0aCBkbWEgdGhhdCBpcyBub3Qgc2VjdG9yIGFsaWduZWQgcmlnaHQgbm93Li4uIG5vdGUKICogdGhhdCBpbiB0aGlzIHBhdGggd2UgYXJlIG5vdCB1c2luZyAtPmRhdGEgb3IgLT5idWZmZXIgYXQgYWxsLiB0aGlzIGlycwogKiBjYW4gcmVwbGFjZSBjZHJvbV9wY19pbnRyLCBjZHJvbV9yZWFkX2ludHIsIGFuZCBjZHJvbV93cml0ZV9pbnRyIGluIHRoZQogKiBmdXR1cmUuCiAqLwpzdGF0aWMgaWRlX3N0YXJ0c3RvcF90IGNkcm9tX25ld3BjX2ludHIoaWRlX2RyaXZlX3QgKmRyaXZlKQp7CglzdHJ1Y3QgY2Ryb21faW5mbyAqaW5mbyA9IGRyaXZlLT5kcml2ZXJfZGF0YTsKCXN0cnVjdCByZXF1ZXN0ICpycSA9IEhXR1JPVVAoZHJpdmUpLT5ycTsKCWludCBkbWFfZXJyb3IsIGRtYSwgc3RhdCwgaXJlYXNvbiwgbGVuLCB0aGlzbGVuOwoJdTggbG93Y3lsLCBoaWdoY3lsOwoJeGZlcl9mdW5jX3QgKnhmZXJmdW5jOwoJdW5zaWduZWQgbG9uZyBmbGFnczsKCgkvKiBDaGVjayBmb3IgZXJyb3JzLiAqLwoJZG1hX2Vycm9yID0gMDsKCWRtYSA9IGluZm8tPmRtYTsKCWlmIChkbWEpIHsKCQlpbmZvLT5kbWEgPSAwOwoJCWRtYV9lcnJvciA9IEhXSUYoZHJpdmUpLT5pZGVfZG1hX2VuZChkcml2ZSk7Cgl9CgoJaWYgKGNkcm9tX2RlY29kZV9zdGF0dXMoZHJpdmUsIDAsICZzdGF0KSkKCQlyZXR1cm4gaWRlX3N0b3BwZWQ7CgoJLyoKCSAqIHVzaW5nIGRtYSwgdHJhbnNmZXIgaXMgY29tcGxldGUgbm93CgkgKi8KCWlmIChkbWEpIHsKCQlpZiAoZG1hX2Vycm9yKSB7CgkJCXByaW50ayhLRVJOX0VSUiAiaWRlLWNkOiBkbWEgZXJyb3JcbiIpOwoJCQlfX2lkZV9kbWFfb2ZmKGRyaXZlKTsKCQkJcmV0dXJuIGlkZV9lcnJvcihkcml2ZSwgImRtYSBlcnJvciIsIHN0YXQpOwoJCX0KCgkJZW5kX3RoYXRfcmVxdWVzdF9jaHVuayhycSwgMSwgcnEtPmRhdGFfbGVuKTsKCQlycS0+ZGF0YV9sZW4gPSAwOwoJCWdvdG8gZW5kX3JlcXVlc3Q7Cgl9CgoJLyoKCSAqIG9rIHdlIGZhbGwgdG8gcGlvIDovCgkgKi8KCWlyZWFzb24gPSBIV0lGKGRyaXZlKS0+SU5CKElERV9JUkVBU09OX1JFRykgJiAweDM7Cglsb3djeWwgID0gSFdJRihkcml2ZSktPklOQihJREVfQkNPVU5UTF9SRUcpOwoJaGlnaGN5bCA9IEhXSUYoZHJpdmUpLT5JTkIoSURFX0JDT1VOVEhfUkVHKTsKCglsZW4gPSBsb3djeWwgKyAoMjU2ICogaGlnaGN5bCk7Cgl0aGlzbGVuID0gcnEtPmRhdGFfbGVuOwoJaWYgKHRoaXNsZW4gPiBsZW4pCgkJdGhpc2xlbiA9IGxlbjsKCgkvKgoJICogSWYgRFJRIGlzIGNsZWFyLCB0aGUgY29tbWFuZCBoYXMgY29tcGxldGVkLgoJICovCglpZiAoKHN0YXQgJiBEUlFfU1RBVCkgPT0gMCkKCQlnb3RvIGVuZF9yZXF1ZXN0OwoKCS8qCgkgKiBjaGVjayB3aGljaCB3YXkgdG8gdHJhbnNmZXIgZGF0YQoJICovCglpZiAocnFfZGF0YV9kaXIocnEpID09IFdSSVRFKSB7CgkJLyoKCQkgKiB3cml0ZSB0byBkcml2ZQoJCSAqLwoJCWlmIChjZHJvbV93cml0ZV9jaGVja19pcmVhc29uKGRyaXZlLCBsZW4sIGlyZWFzb24pKQoJCQlyZXR1cm4gaWRlX3N0b3BwZWQ7CgoJCXhmZXJmdW5jID0gSFdJRihkcml2ZSktPmF0YXBpX291dHB1dF9ieXRlczsKCX0gZWxzZSAgewoJCS8qCgkJICogcmVhZCBmcm9tIGRyaXZlCgkJICovCgkJaWYgKGNkcm9tX3JlYWRfY2hlY2tfaXJlYXNvbihkcml2ZSwgbGVuLCBpcmVhc29uKSkKCQkJcmV0dXJuIGlkZV9zdG9wcGVkOwoKCQl4ZmVyZnVuYyA9IEhXSUYoZHJpdmUpLT5hdGFwaV9pbnB1dF9ieXRlczsKCX0KCgkvKgoJICogdHJhbnNmZXIgZGF0YQoJICovCgl3aGlsZSAodGhpc2xlbiA+IDApIHsKCQlpbnQgYmxlbiA9IGJsZW4gPSBycS0+ZGF0YV9sZW47CgkJY2hhciAqcHRyID0gcnEtPmRhdGE7CgoJCS8qCgkJICogYmlvIGJhY2tlZD8KCQkgKi8KCQlpZiAocnEtPmJpbykgewoJCQlwdHIgPSBiaW9fZGF0YShycS0+YmlvKTsKCQkJYmxlbiA9IGJpb19pb3ZlYyhycS0+YmlvKS0+YnZfbGVuOwoJCX0KCgkJaWYgKCFwdHIpIHsKCQkJcHJpbnRrKEtFUk5fRVJSICIlczogY29uZnVzZWQsIG1pc3NpbmcgZGF0YVxuIiwgZHJpdmUtPm5hbWUpOwoJCQlicmVhazsKCQl9CgoJCWlmIChibGVuID4gdGhpc2xlbikKCQkJYmxlbiA9IHRoaXNsZW47CgoJCXhmZXJmdW5jKGRyaXZlLCBwdHIsIGJsZW4pOwoKCQl0aGlzbGVuIC09IGJsZW47CgkJbGVuIC09IGJsZW47CgkJcnEtPmRhdGFfbGVuIC09IGJsZW47CgoJCWlmIChycS0+YmlvKQoJCQllbmRfdGhhdF9yZXF1ZXN0X2NodW5rKHJxLCAxLCBibGVuKTsKCQllbHNlCgkJCXJxLT5kYXRhICs9IGJsZW47Cgl9CgoJLyoKCSAqIHBhZCwgaWYgbmVjZXNzYXJ5CgkgKi8KCWlmIChsZW4gPiAwKSB7CgkJd2hpbGUgKGxlbiA+IDApIHsKCQkJaW50IHBhZCA9IDA7CgoJCQl4ZmVyZnVuYyhkcml2ZSwgJnBhZCwgc2l6ZW9mKHBhZCkpOwoJCQlsZW4gLT0gc2l6ZW9mKHBhZCk7CgkJfQoJfQoKCWlmIChIV0dST1VQKGRyaXZlKS0+aGFuZGxlciAhPSBOVUxMKQoJCUJVRygpOwoKCWlkZV9zZXRfaGFuZGxlcihkcml2ZSwgY2Ryb21fbmV3cGNfaW50ciwgcnEtPnRpbWVvdXQsIE5VTEwpOwoJcmV0dXJuIGlkZV9zdGFydGVkOwoKZW5kX3JlcXVlc3Q6CglpZiAoIXJxLT5kYXRhX2xlbikKCQlwb3N0X3RyYW5zZm9ybV9jb21tYW5kKHJxKTsKCglzcGluX2xvY2tfaXJxc2F2ZSgmaWRlX2xvY2ssIGZsYWdzKTsKCWJsa2Rldl9kZXF1ZXVlX3JlcXVlc3QocnEpOwoJZW5kX3RoYXRfcmVxdWVzdF9sYXN0KHJxLCAxKTsKCUhXR1JPVVAoZHJpdmUpLT5ycSA9IE5VTEw7CglzcGluX3VubG9ja19pcnFyZXN0b3JlKCZpZGVfbG9jaywgZmxhZ3MpOwoJcmV0dXJuIGlkZV9zdG9wcGVkOwp9CgpzdGF0aWMgaWRlX3N0YXJ0c3RvcF90IGNkcm9tX3dyaXRlX2ludHIoaWRlX2RyaXZlX3QgKmRyaXZlKQp7CglpbnQgc3RhdCwgaXJlYXNvbiwgbGVuLCBzZWN0b3JzX3RvX3RyYW5zZmVyLCB1cHRvZGF0ZTsKCXN0cnVjdCBjZHJvbV9pbmZvICppbmZvID0gZHJpdmUtPmRyaXZlcl9kYXRhOwoJaW50IGRtYV9lcnJvciA9IDAsIGRtYSA9IGluZm8tPmRtYTsKCXU4IGxvd2N5bCA9IDAsIGhpZ2hjeWwgPSAwOwoKCXN0cnVjdCByZXF1ZXN0ICpycSA9IEhXR1JPVVAoZHJpdmUpLT5ycTsKCgkvKiBDaGVjayBmb3IgZXJyb3JzLiAqLwoJaWYgKGRtYSkgewoJCWluZm8tPmRtYSA9IDA7CgkJaWYgKChkbWFfZXJyb3IgPSBIV0lGKGRyaXZlKS0+aWRlX2RtYV9lbmQoZHJpdmUpKSkgewoJCQlwcmludGsoS0VSTl9FUlIgImlkZS1jZDogd3JpdGUgZG1hIGVycm9yXG4iKTsKCQkJX19pZGVfZG1hX29mZihkcml2ZSk7CgkJfQoJfQoKCWlmIChjZHJvbV9kZWNvZGVfc3RhdHVzKGRyaXZlLCAwLCAmc3RhdCkpCgkJcmV0dXJuIGlkZV9zdG9wcGVkOwoKCS8qCgkgKiB1c2luZyBkbWEsIHRyYW5zZmVyIGlzIGNvbXBsZXRlIG5vdwoJICovCglpZiAoZG1hKSB7CgkJaWYgKGRtYV9lcnJvcikKCQkJcmV0dXJuIGlkZV9lcnJvcihkcml2ZSwgImRtYSBlcnJvciIsIHN0YXQpOwoKCQlpZGVfZW5kX3JlcXVlc3QoZHJpdmUsIDEsIHJxLT5ucl9zZWN0b3JzKTsKCQlyZXR1cm4gaWRlX3N0b3BwZWQ7Cgl9CgoJLyogUmVhZCB0aGUgaW50ZXJydXB0IHJlYXNvbiBhbmQgdGhlIHRyYW5zZmVyIGxlbmd0aC4gKi8KCWlyZWFzb24gPSBIV0lGKGRyaXZlKS0+SU5CKElERV9JUkVBU09OX1JFRyk7Cglsb3djeWwgID0gSFdJRihkcml2ZSktPklOQihJREVfQkNPVU5UTF9SRUcpOwoJaGlnaGN5bCA9IEhXSUYoZHJpdmUpLT5JTkIoSURFX0JDT1VOVEhfUkVHKTsKCglsZW4gPSBsb3djeWwgKyAoMjU2ICogaGlnaGN5bCk7CgoJLyogSWYgRFJRIGlzIGNsZWFyLCB0aGUgY29tbWFuZCBoYXMgY29tcGxldGVkLiAqLwoJaWYgKChzdGF0ICYgRFJRX1NUQVQpID09IDApIHsKCQkvKiBJZiB3ZSdyZSBub3QgZG9uZSB3cml0aW5nLCBjb21wbGFpbi4KCQkgKiBPdGhlcndpc2UsIGNvbXBsZXRlIHRoZSBjb21tYW5kIG5vcm1hbGx5LgoJCSAqLwoJCXVwdG9kYXRlID0gMTsKCQlpZiAocnEtPmN1cnJlbnRfbnJfc2VjdG9ycyA+IDApIHsKCQkJcHJpbnRrKEtFUk5fRVJSICIlczogd3JpdGVfaW50cjogZGF0YSB1bmRlcnJ1biAoJWQgYmxvY2tzKVxuIiwKCQkJZHJpdmUtPm5hbWUsIHJxLT5jdXJyZW50X25yX3NlY3RvcnMpOwoJCQl1cHRvZGF0ZSA9IDA7CgkJfQoJCWNkcm9tX2VuZF9yZXF1ZXN0KGRyaXZlLCB1cHRvZGF0ZSk7CgkJcmV0dXJuIGlkZV9zdG9wcGVkOwoJfQoKCS8qIENoZWNrIHRoYXQgdGhlIGRyaXZlIGlzIGV4cGVjdGluZyB0byBkbyB0aGUgc2FtZSB0aGluZyB3ZSBhcmUuICovCglpZiAoY2Ryb21fd3JpdGVfY2hlY2tfaXJlYXNvbihkcml2ZSwgbGVuLCBpcmVhc29uKSkKCQlyZXR1cm4gaWRlX3N0b3BwZWQ7CgoJc2VjdG9yc190b190cmFuc2ZlciA9IGxlbiAvIFNFQ1RPUl9TSVpFOwoKCS8qCgkgKiBub3cgbG9vcCBhbmQgd3JpdGUgb3V0IHRoZSBkYXRhCgkgKi8KCXdoaWxlIChzZWN0b3JzX3RvX3RyYW5zZmVyID4gMCkgewoJCWludCB0aGlzX3RyYW5zZmVyOwoKCQlpZiAoIXJxLT5jdXJyZW50X25yX3NlY3RvcnMpIHsKCQkJcHJpbnRrKEtFUk5fRVJSICJpZGUtY2Q6IHdyaXRlX2ludHI6IG9vcHNcbiIpOwoJCQlicmVhazsKCQl9CgoJCS8qCgkJICogRmlndXJlIG91dCBob3cgbWFueSBzZWN0b3JzIHdlIGNhbiB0cmFuc2ZlcgoJCSAqLwoJCXRoaXNfdHJhbnNmZXIgPSBtaW5fdChpbnQsIHNlY3RvcnNfdG9fdHJhbnNmZXIsIHJxLT5jdXJyZW50X25yX3NlY3RvcnMpOwoKCQl3aGlsZSAodGhpc190cmFuc2ZlciA+IDApIHsKCQkJSFdJRihkcml2ZSktPmF0YXBpX291dHB1dF9ieXRlcyhkcml2ZSwgcnEtPmJ1ZmZlciwgU0VDVE9SX1NJWkUpOwoJCQlycS0+YnVmZmVyICs9IFNFQ1RPUl9TSVpFOwoJCQktLXJxLT5ucl9zZWN0b3JzOwoJCQktLXJxLT5jdXJyZW50X25yX3NlY3RvcnM7CgkJCSsrcnEtPnNlY3RvcjsKCQkJLS10aGlzX3RyYW5zZmVyOwoJCQktLXNlY3RvcnNfdG9fdHJhbnNmZXI7CgkJfQoKCQkvKgoJCSAqIGN1cnJlbnQgYnVmZmVyIGNvbXBsZXRlLCBtb3ZlIG9uCgkJICovCgkJaWYgKHJxLT5jdXJyZW50X25yX3NlY3RvcnMgPT0gMCAmJiBycS0+bnJfc2VjdG9ycykKCQkJY2Ryb21fZW5kX3JlcXVlc3QoZHJpdmUsIDEpOwoJfQoKCS8qIHJlLWFybSBoYW5kbGVyICovCglpZGVfc2V0X2hhbmRsZXIoZHJpdmUsICZjZHJvbV93cml0ZV9pbnRyLCBBVEFQSV9XQUlUX1BDLCBOVUxMKTsKCXJldHVybiBpZGVfc3RhcnRlZDsKfQoKc3RhdGljIGlkZV9zdGFydHN0b3BfdCBjZHJvbV9zdGFydF93cml0ZV9jb250KGlkZV9kcml2ZV90ICpkcml2ZSkKewoJc3RydWN0IHJlcXVlc3QgKnJxID0gSFdHUk9VUChkcml2ZSktPnJxOwoKI2lmIDAJLyogdGhlIGltbWVkaWF0ZSBiaXQgKi8KCXJxLT5jbWRbMV0gPSAxIDw8IDM7CiNlbmRpZgoJcnEtPnRpbWVvdXQgPSBBVEFQSV9XQUlUX1BDOwoKCXJldHVybiBjZHJvbV90cmFuc2Zlcl9wYWNrZXRfY29tbWFuZChkcml2ZSwgcnEsIGNkcm9tX3dyaXRlX2ludHIpOwp9CgpzdGF0aWMgaWRlX3N0YXJ0c3RvcF90IGNkcm9tX3N0YXJ0X3dyaXRlKGlkZV9kcml2ZV90ICpkcml2ZSwgc3RydWN0IHJlcXVlc3QgKnJxKQp7CglzdHJ1Y3QgY2Ryb21faW5mbyAqaW5mbyA9IGRyaXZlLT5kcml2ZXJfZGF0YTsKCXN0cnVjdCBnZW5kaXNrICpnID0gaW5mby0+ZGlzazsKCXVuc2lnbmVkIHNob3J0IHNlY3RvcnNfcGVyX2ZyYW1lID0gcXVldWVfaGFyZHNlY3Rfc2l6ZShkcml2ZS0+cXVldWUpID4+IFNFQ1RPUl9CSVRTOwoKCS8qCgkgKiB3cml0ZXMgKm11c3QqIGJlIGhhcmR3YXJlIGZyYW1lIGFsaWduZWQKCSAqLwoJaWYgKChycS0+bnJfc2VjdG9ycyAmIChzZWN0b3JzX3Blcl9mcmFtZSAtIDEpKSB8fAoJICAgIChycS0+c2VjdG9yICYgKHNlY3RvcnNfcGVyX2ZyYW1lIC0gMSkpKSB7CgkJY2Ryb21fZW5kX3JlcXVlc3QoZHJpdmUsIDApOwoJCXJldHVybiBpZGVfc3RvcHBlZDsKCX0KCgkvKgoJICogZGlzayBoYXMgYmVjb21lIHdyaXRlIHByb3RlY3RlZAoJICovCglpZiAoZy0+cG9saWN5KSB7CgkJY2Ryb21fZW5kX3JlcXVlc3QoZHJpdmUsIDApOwoJCXJldHVybiBpZGVfc3RvcHBlZDsKCX0KCglpbmZvLT5uc2VjdG9yc19idWZmZXJlZCA9IDA7CgoJLyogdXNlIGRtYSwgaWYgcG9zc2libGUuIHdlIGRvbid0IG5lZWQgdG8gY2hlY2sgbW9yZSwgc2luY2Ugd2UKCSAqIGtub3cgdGhhdCB0aGUgdHJhbnNmZXIgaXMgYWx3YXlzIChhdCBsZWFzdCEpIGZyYW1lIGFsaWduZWQgKi8KCWluZm8tPmRtYSA9IGRyaXZlLT51c2luZ19kbWEgPyAxIDogMDsKCglpbmZvLT5kZXZpbmZvLm1lZGlhX3dyaXR0ZW4gPSAxOwoKCS8qIFN0YXJ0IHNlbmRpbmcgdGhlIHdyaXRlIHJlcXVlc3QgdG8gdGhlIGRyaXZlLiAqLwoJcmV0dXJuIGNkcm9tX3N0YXJ0X3BhY2tldF9jb21tYW5kKGRyaXZlLCAzMjc2OCwgY2Ryb21fc3RhcnRfd3JpdGVfY29udCk7Cn0KCnN0YXRpYyBpZGVfc3RhcnRzdG9wX3QgY2Ryb21fZG9fbmV3cGNfY29udChpZGVfZHJpdmVfdCAqZHJpdmUpCnsKCXN0cnVjdCByZXF1ZXN0ICpycSA9IEhXR1JPVVAoZHJpdmUpLT5ycTsKCglpZiAoIXJxLT50aW1lb3V0KQoJCXJxLT50aW1lb3V0ID0gQVRBUElfV0FJVF9QQzsKCglyZXR1cm4gY2Ryb21fdHJhbnNmZXJfcGFja2V0X2NvbW1hbmQoZHJpdmUsIHJxLCBjZHJvbV9uZXdwY19pbnRyKTsKfQoKc3RhdGljIGlkZV9zdGFydHN0b3BfdCBjZHJvbV9kb19ibG9ja19wYyhpZGVfZHJpdmVfdCAqZHJpdmUsIHN0cnVjdCByZXF1ZXN0ICpycSkKewoJc3RydWN0IGNkcm9tX2luZm8gKmluZm8gPSBkcml2ZS0+ZHJpdmVyX2RhdGE7CgoJcnEtPmZsYWdzIHw9IFJFUV9RVUlFVDsKCglpbmZvLT5kbWEgPSAwOwoKCS8qCgkgKiBzZyByZXF1ZXN0CgkgKi8KCWlmIChycS0+YmlvKSB7CgkJaW50IG1hc2sgPSBkcml2ZS0+cXVldWUtPmRtYV9hbGlnbm1lbnQ7CgkJdW5zaWduZWQgbG9uZyBhZGRyID0gKHVuc2lnbmVkIGxvbmcpIHBhZ2VfYWRkcmVzcyhiaW9fcGFnZShycS0+YmlvKSk7CgoJCWluZm8tPmRtYSA9IGRyaXZlLT51c2luZ19kbWE7CgoJCS8qCgkJICogY2hlY2sgaWYgZG1hIGlzIHNhZmUKCQkgKgoJCSAqIE5PVEUhIFRoZSAibGVuIiBhbmQgImFkZHIiIGNoZWNrcyBzaG91bGQgcG9zc2libHkgaGF2ZQoJCSAqIHNlcGFyYXRlIG1hc2tzLgoJCSAqLwoJCWlmICgocnEtPmRhdGFfbGVuICYgMTUpIHx8IChhZGRyICYgbWFzaykpCgkJCWluZm8tPmRtYSA9IDA7Cgl9CgoJLyogU3RhcnQgc2VuZGluZyB0aGUgY29tbWFuZCB0byB0aGUgZHJpdmUuICovCglyZXR1cm4gY2Ryb21fc3RhcnRfcGFja2V0X2NvbW1hbmQoZHJpdmUsIHJxLT5kYXRhX2xlbiwgY2Ryb21fZG9fbmV3cGNfY29udCk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIGNkcm9tIGRyaXZlciByZXF1ZXN0IHJvdXRpbmUuCiAqLwpzdGF0aWMgaWRlX3N0YXJ0c3RvcF90CmlkZV9kb19yd19jZHJvbSAoaWRlX2RyaXZlX3QgKmRyaXZlLCBzdHJ1Y3QgcmVxdWVzdCAqcnEsIHNlY3Rvcl90IGJsb2NrKQp7CglpZGVfc3RhcnRzdG9wX3QgYWN0aW9uOwoJc3RydWN0IGNkcm9tX2luZm8gKmluZm8gPSBkcml2ZS0+ZHJpdmVyX2RhdGE7CgoJaWYgKGJsa19mc19yZXF1ZXN0KHJxKSkgewoJCWlmIChDRFJPTV9DT05GSUdfRkxBR1MoZHJpdmUpLT5zZWVraW5nKSB7CgkJCXVuc2lnbmVkIGxvbmcgZWxhcHNlZCA9IGppZmZpZXMgLSBpbmZvLT5zdGFydF9zZWVrOwoJCQlpbnQgc3RhdCA9IEhXSUYoZHJpdmUpLT5JTkIoSURFX1NUQVRVU19SRUcpOwoKCQkJaWYgKChzdGF0ICYgU0VFS19TVEFUKSAhPSBTRUVLX1NUQVQpIHsKCQkJCWlmIChlbGFwc2VkIDwgSURFQ0RfU0VFS19USU1FT1VUKSB7CgkJCQkJaWRlX3N0YWxsX3F1ZXVlKGRyaXZlLCBJREVDRF9TRUVLX1RJTUVSKTsKCQkJCQlyZXR1cm4gaWRlX3N0b3BwZWQ7CgkJCQl9CgkJCQlwcmludGsgKEtFUk5fRVJSICIlczogRFNDIHRpbWVvdXRcbiIsIGRyaXZlLT5uYW1lKTsKCQkJfQoJCQlDRFJPTV9DT05GSUdfRkxBR1MoZHJpdmUpLT5zZWVraW5nID0gMDsKCQl9CgkJaWYgKChycV9kYXRhX2RpcihycSkgPT0gUkVBRCkgJiYgSURFX0xBUkdFX1NFRUsoaW5mby0+bGFzdF9ibG9jaywgYmxvY2ssIElERUNEX1NFRUtfVEhSRVNIT0xEKSAmJiBkcml2ZS0+ZHNjX292ZXJsYXApIHsKCQkJYWN0aW9uID0gY2Ryb21fc3RhcnRfc2Vlayhkcml2ZSwgYmxvY2spOwoJCX0gZWxzZSB7CgkJCWlmIChycV9kYXRhX2RpcihycSkgPT0gUkVBRCkKCQkJCWFjdGlvbiA9IGNkcm9tX3N0YXJ0X3JlYWQoZHJpdmUsIGJsb2NrKTsKCQkJZWxzZQoJCQkJYWN0aW9uID0gY2Ryb21fc3RhcnRfd3JpdGUoZHJpdmUsIHJxKTsKCQl9CgkJaW5mby0+bGFzdF9ibG9jayA9IGJsb2NrOwoJCXJldHVybiBhY3Rpb247Cgl9IGVsc2UgaWYgKHJxLT5mbGFncyAmIChSRVFfUEMgfCBSRVFfU0VOU0UpKSB7CgkJcmV0dXJuIGNkcm9tX2RvX3BhY2tldF9jb21tYW5kKGRyaXZlKTsKCX0gZWxzZSBpZiAocnEtPmZsYWdzICYgUkVRX0JMT0NLX1BDKSB7CgkJcmV0dXJuIGNkcm9tX2RvX2Jsb2NrX3BjKGRyaXZlLCBycSk7Cgl9IGVsc2UgaWYgKHJxLT5mbGFncyAmIFJFUV9TUEVDSUFMKSB7CgkJLyoKCQkgKiByaWdodCBub3cgdGhpcyBjYW4gb25seSBiZSBhIHJlc2V0Li4uCgkJICovCgkJY2Ryb21fZW5kX3JlcXVlc3QoZHJpdmUsIDEpOwoJCXJldHVybiBpZGVfc3RvcHBlZDsKCX0KCglibGtfZHVtcF9ycV9mbGFncyhycSwgImlkZS1jZCBiYWQgZmxhZ3MiKTsKCWNkcm9tX2VuZF9yZXF1ZXN0KGRyaXZlLCAwKTsKCXJldHVybiBpZGVfc3RvcHBlZDsKfQoKCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJb2N0bCBoYW5kbGluZy4KICoKICogUm91dGluZXMgd2hpY2ggcXVldWUgcGFja2V0IGNvbW1hbmRzIHRha2UgYXMgYSBmaW5hbCBhcmd1bWVudCBhIHBvaW50ZXIKICogdG8gYSByZXF1ZXN0X3NlbnNlIHN0cnVjdC4gIElmIGV4ZWN1dGlvbiBvZiB0aGUgY29tbWFuZCByZXN1bHRzCiAqIGluIGFuIGVycm9yIHdpdGggYSBDSEVDSyBDT05ESVRJT04gc3RhdHVzLCB0aGlzIHN0cnVjdHVyZSB3aWxsIGJlIGZpbGxlZAogKiB3aXRoIHRoZSByZXN1bHRzIG9mIHRoZSBzdWJzZXF1ZW50IHJlcXVlc3Qgc2Vuc2UgY29tbWFuZC4gIFRoZSBwb2ludGVyCiAqIGNhbiBhbHNvIGJlIE5VTEwsIGluIHdoaWNoIGNhc2Ugbm8gc2Vuc2UgaW5mb3JtYXRpb24gaXMgcmV0dXJuZWQuCiAqLwoKI2lmICEgU1RBTkRBUkRfQVRBUEkKc3RhdGljIGlubGluZQppbnQgYmluMmJjZCAoaW50IHgpCnsKCXJldHVybiAoeCUxMCkgfCAoKHgvMTApIDw8IDQpOwp9CgoKc3RhdGljIGlubGluZQppbnQgYmNkMmJpbiAoaW50IHgpCnsKCXJldHVybiAoeCA+PiA0KSAqIDEwICsgKHggJiAweDBmKTsKfQoKc3RhdGljCnZvaWQgbXNmX2Zyb21fYmNkIChzdHJ1Y3QgYXRhcGlfbXNmICptc2YpCnsKCW1zZi0+bWludXRlID0gYmNkMmJpbiAobXNmLT5taW51dGUpOwoJbXNmLT5zZWNvbmQgPSBiY2QyYmluIChtc2YtPnNlY29uZCk7Cgltc2YtPmZyYW1lICA9IGJjZDJiaW4gKG1zZi0+ZnJhbWUpOwp9CgojZW5kaWYgLyogbm90IFNUQU5EQVJEX0FUQVBJICovCgoKc3RhdGljIGlubGluZQp2b2lkIGxiYV90b19tc2YgKGludCBsYmEsIGJ5dGUgKm0sIGJ5dGUgKnMsIGJ5dGUgKmYpCnsKCWxiYSArPSBDRF9NU0ZfT0ZGU0VUOwoJbGJhICY9IDB4ZmZmZmZmOyAgLyogbmVnYXRpdmUgbGJhcyB1c2Ugb25seSAyNCBiaXRzICovCgkqbSA9IGxiYSAvIChDRF9TRUNTICogQ0RfRlJBTUVTKTsKCWxiYSAlPSAoQ0RfU0VDUyAqIENEX0ZSQU1FUyk7CgkqcyA9IGxiYSAvIENEX0ZSQU1FUzsKCSpmID0gbGJhICUgQ0RfRlJBTUVTOwp9CgoKc3RhdGljIGlubGluZQppbnQgbXNmX3RvX2xiYSAoYnl0ZSBtLCBieXRlIHMsIGJ5dGUgZikKewoJcmV0dXJuICgoKG0gKiBDRF9TRUNTKSArIHMpICogQ0RfRlJBTUVTICsgZikgLSBDRF9NU0ZfT0ZGU0VUOwp9CgpzdGF0aWMgaW50IGNkcm9tX2NoZWNrX3N0YXR1cyhpZGVfZHJpdmVfdCAqZHJpdmUsIHN0cnVjdCByZXF1ZXN0X3NlbnNlICpzZW5zZSkKewoJc3RydWN0IHJlcXVlc3QgcmVxOwoJc3RydWN0IGNkcm9tX2luZm8gKmluZm8gPSBkcml2ZS0+ZHJpdmVyX2RhdGE7CglzdHJ1Y3QgY2Ryb21fZGV2aWNlX2luZm8gKmNkaSA9ICZpbmZvLT5kZXZpbmZvOwoKCWNkcm9tX3ByZXBhcmVfcmVxdWVzdChkcml2ZSwgJnJlcSk7CgoJcmVxLnNlbnNlID0gc2Vuc2U7CglyZXEuY21kWzBdID0gR1BDTURfVEVTVF9VTklUX1JFQURZOwoJcmVxLmZsYWdzIHw9IFJFUV9RVUlFVDsKCiNpZiAhIFNUQU5EQVJEX0FUQVBJCiAgICAgICAgLyogdGhlIFNhbnlvIDMgQ0QgY2hhbmdlciB1c2VzIGJ5dGUgNyBvZiBURVNUX1VOSVRfUkVBRFkgdG8gCiAgICAgICAgICAgc3dpdGNoIENEcyBpbnN0ZWFkIG9mIHN1cHBvcnRpbmcgdGhlIExPQURfVU5MT0FEIG9wY29kZSAgICovCgoJcmVxLmNtZFs3XSA9IGNkaS0+c2FueW9fc2xvdCAlIDM7CiNlbmRpZiAvKiBub3QgU1RBTkRBUkRfQVRBUEkgKi8KCglyZXR1cm4gY2Ryb21fcXVldWVfcGFja2V0X2NvbW1hbmQoZHJpdmUsICZyZXEpOwp9CgoKLyogTG9jayB0aGUgZG9vciBpZiBMT0NLRkxBRyBpcyBub256ZXJvOyB1bmxvY2sgaXQgb3RoZXJ3aXNlLiAqLwpzdGF0aWMgaW50CmNkcm9tX2xvY2tkb29yKGlkZV9kcml2ZV90ICpkcml2ZSwgaW50IGxvY2tmbGFnLCBzdHJ1Y3QgcmVxdWVzdF9zZW5zZSAqc2Vuc2UpCnsKCXN0cnVjdCByZXF1ZXN0X3NlbnNlIG15X3NlbnNlOwoJc3RydWN0IHJlcXVlc3QgcmVxOwoJaW50IHN0YXQ7CgoJaWYgKHNlbnNlID09IE5VTEwpCgkJc2Vuc2UgPSAmbXlfc2Vuc2U7CgoJLyogSWYgdGhlIGRyaXZlIGNhbm5vdCBsb2NrIHRoZSBkb29yLCBqdXN0IHByZXRlbmQuICovCglpZiAoQ0RST01fQ09ORklHX0ZMQUdTKGRyaXZlKS0+bm9fZG9vcmxvY2spIHsKCQlzdGF0ID0gMDsKCX0gZWxzZSB7CgkJY2Ryb21fcHJlcGFyZV9yZXF1ZXN0KGRyaXZlLCAmcmVxKTsKCQlyZXEuc2Vuc2UgPSBzZW5zZTsKCQlyZXEuY21kWzBdID0gR1BDTURfUFJFVkVOVF9BTExPV19NRURJVU1fUkVNT1ZBTDsKCQlyZXEuY21kWzRdID0gbG9ja2ZsYWcgPyAxIDogMDsKCQlzdGF0ID0gY2Ryb21fcXVldWVfcGFja2V0X2NvbW1hbmQoZHJpdmUsICZyZXEpOwoJfQoKCS8qIElmIHdlIGdvdCBhbiBpbGxlZ2FsIGZpZWxkIGVycm9yLCB0aGUgZHJpdmUKCSAgIHByb2JhYmx5IGNhbm5vdCBsb2NrIHRoZSBkb29yLiAqLwoJaWYgKHN0YXQgIT0gMCAmJgoJICAgIHNlbnNlLT5zZW5zZV9rZXkgPT0gSUxMRUdBTF9SRVFVRVNUICYmCgkgICAgKHNlbnNlLT5hc2MgPT0gMHgyNCB8fCBzZW5zZS0+YXNjID09IDB4MjApKSB7CgkJcHJpbnRrIChLRVJOX0VSUiAiJXM6IGRvb3IgbG9ja2luZyBub3Qgc3VwcG9ydGVkXG4iLAoJCQlkcml2ZS0+bmFtZSk7CgkJQ0RST01fQ09ORklHX0ZMQUdTKGRyaXZlKS0+bm9fZG9vcmxvY2sgPSAxOwoJCXN0YXQgPSAwOwoJfQoJCgkvKiBubyBtZWRpdW0sIHRoYXQncyBhbHJpZ2h0LiAqLwoJaWYgKHN0YXQgIT0gMCAmJiBzZW5zZS0+c2Vuc2Vfa2V5ID09IE5PVF9SRUFEWSAmJiBzZW5zZS0+YXNjID09IDB4M2EpCgkJc3RhdCA9IDA7CgoJaWYgKHN0YXQgPT0gMCkKCQlDRFJPTV9TVEFURV9GTEFHUyhkcml2ZSktPmRvb3JfbG9ja2VkID0gbG9ja2ZsYWc7CgoJcmV0dXJuIHN0YXQ7Cn0KCgovKiBFamVjdCB0aGUgZGlzayBpZiBFSkVDVEZMQUcgaXMgMC4KICAgSWYgRUpFQ1RGTEFHIGlzIDEsIHRyeSB0byByZWxvYWQgdGhlIGRpc2suICovCnN0YXRpYyBpbnQgY2Ryb21fZWplY3QoaWRlX2RyaXZlX3QgKmRyaXZlLCBpbnQgZWplY3RmbGFnLAoJCSAgICAgICBzdHJ1Y3QgcmVxdWVzdF9zZW5zZSAqc2Vuc2UpCnsKCXN0cnVjdCByZXF1ZXN0IHJlcTsKCWNoYXIgbG9laiA9IDB4MDI7CgoJaWYgKENEUk9NX0NPTkZJR19GTEFHUyhkcml2ZSktPm5vX2VqZWN0ICYmICFlamVjdGZsYWcpCgkJcmV0dXJuIC1FRFJJVkVfQ0FOVF9ET19USElTOwoJCgkvKiByZWxvYWQgZmFpbHMgb24gc29tZSBkcml2ZXMsIGlmIHRoZSB0cmF5IGlzIGxvY2tlZCAqLwoJaWYgKENEUk9NX1NUQVRFX0ZMQUdTKGRyaXZlKS0+ZG9vcl9sb2NrZWQgJiYgZWplY3RmbGFnKQoJCXJldHVybiAwOwoKCWNkcm9tX3ByZXBhcmVfcmVxdWVzdChkcml2ZSwgJnJlcSk7CgoJLyogb25seSB0ZWxsIGRyaXZlIHRvIGNsb3NlIHRyYXkgaWYgb3BlbiwgaWYgaXQgY2FuIGRvIHRoYXQgKi8KCWlmIChlamVjdGZsYWcgJiYgIUNEUk9NX0NPTkZJR19GTEFHUyhkcml2ZSktPmNsb3NlX3RyYXkpCgkJbG9laiA9IDA7CgoJcmVxLnNlbnNlID0gc2Vuc2U7CglyZXEuY21kWzBdID0gR1BDTURfU1RBUlRfU1RPUF9VTklUOwoJcmVxLmNtZFs0XSA9IGxvZWogfCAoZWplY3RmbGFnICE9IDApOwoJcmV0dXJuIGNkcm9tX3F1ZXVlX3BhY2tldF9jb21tYW5kKGRyaXZlLCAmcmVxKTsKfQoKc3RhdGljIGludCBjZHJvbV9yZWFkX2NhcGFjaXR5KGlkZV9kcml2ZV90ICpkcml2ZSwgdW5zaWduZWQgbG9uZyAqY2FwYWNpdHksCgkJCSAgICAgICB1bnNpZ25lZCBsb25nICpzZWN0b3JzX3Blcl9mcmFtZSwKCQkJICAgICAgIHN0cnVjdCByZXF1ZXN0X3NlbnNlICpzZW5zZSkKewoJc3RydWN0IHsKCQlfX3UzMiBsYmE7CgkJX191MzIgYmxvY2tsZW47Cgl9IGNhcGJ1ZjsKCglpbnQgc3RhdDsKCXN0cnVjdCByZXF1ZXN0IHJlcTsKCgljZHJvbV9wcmVwYXJlX3JlcXVlc3QoZHJpdmUsICZyZXEpOwoKCXJlcS5zZW5zZSA9IHNlbnNlOwoJcmVxLmNtZFswXSA9IEdQQ01EX1JFQURfQ0RWRF9DQVBBQ0lUWTsKCXJlcS5kYXRhID0gKGNoYXIgKikmY2FwYnVmOwoJcmVxLmRhdGFfbGVuID0gc2l6ZW9mKGNhcGJ1Zik7CglyZXEuZmxhZ3MgfD0gUkVRX1FVSUVUOwoKCXN0YXQgPSBjZHJvbV9xdWV1ZV9wYWNrZXRfY29tbWFuZChkcml2ZSwgJnJlcSk7CglpZiAoc3RhdCA9PSAwKSB7CgkJKmNhcGFjaXR5ID0gMSArIGJlMzJfdG9fY3B1KGNhcGJ1Zi5sYmEpOwoJCSpzZWN0b3JzX3Blcl9mcmFtZSA9CgkJCWJlMzJfdG9fY3B1KGNhcGJ1Zi5ibG9ja2xlbikgPj4gU0VDVE9SX0JJVFM7Cgl9CgoJcmV0dXJuIHN0YXQ7Cn0KCnN0YXRpYyBpbnQgY2Ryb21fcmVhZF90b2NlbnRyeShpZGVfZHJpdmVfdCAqZHJpdmUsIGludCB0cmFja25vLCBpbnQgbXNmX2ZsYWcsCgkJCQlpbnQgZm9ybWF0LCBjaGFyICpidWYsIGludCBidWZsZW4sCgkJCQlzdHJ1Y3QgcmVxdWVzdF9zZW5zZSAqc2Vuc2UpCnsKCXN0cnVjdCByZXF1ZXN0IHJlcTsKCgljZHJvbV9wcmVwYXJlX3JlcXVlc3QoZHJpdmUsICZyZXEpOwoKCXJlcS5zZW5zZSA9IHNlbnNlOwoJcmVxLmRhdGEgPSAgYnVmOwoJcmVxLmRhdGFfbGVuID0gYnVmbGVuOwoJcmVxLmZsYWdzIHw9IFJFUV9RVUlFVDsKCXJlcS5jbWRbMF0gPSBHUENNRF9SRUFEX1RPQ19QTUFfQVRJUDsKCXJlcS5jbWRbNl0gPSB0cmFja25vOwoJcmVxLmNtZFs3XSA9IChidWZsZW4gPj4gOCk7CglyZXEuY21kWzhdID0gKGJ1ZmxlbiAmIDB4ZmYpOwoJcmVxLmNtZFs5XSA9IChmb3JtYXQgPDwgNik7CgoJaWYgKG1zZl9mbGFnKQoJCXJlcS5jbWRbMV0gPSAyOwoKCXJldHVybiBjZHJvbV9xdWV1ZV9wYWNrZXRfY29tbWFuZChkcml2ZSwgJnJlcSk7Cn0KCgovKiBUcnkgdG8gcmVhZCB0aGUgZW50aXJlIFRPQyBmb3IgdGhlIGRpc2sgaW50byBvdXIgaW50ZXJuYWwgYnVmZmVyLiAqLwpzdGF0aWMgaW50IGNkcm9tX3JlYWRfdG9jKGlkZV9kcml2ZV90ICpkcml2ZSwgc3RydWN0IHJlcXVlc3Rfc2Vuc2UgKnNlbnNlKQp7CglpbnQgc3RhdCwgbnRyYWNrcywgaTsKCXN0cnVjdCBjZHJvbV9pbmZvICppbmZvID0gZHJpdmUtPmRyaXZlcl9kYXRhOwoJc3RydWN0IGNkcm9tX2RldmljZV9pbmZvICpjZGkgPSAmaW5mby0+ZGV2aW5mbzsKCXN0cnVjdCBhdGFwaV90b2MgKnRvYyA9IGluZm8tPnRvYzsKCXN0cnVjdCB7CgkJc3RydWN0IGF0YXBpX3RvY19oZWFkZXIgaGRyOwoJCXN0cnVjdCBhdGFwaV90b2NfZW50cnkgIGVudDsKCX0gbXNfdG1wOwoJbG9uZyBsYXN0X3dyaXR0ZW47Cgl1bnNpZ25lZCBsb25nIHNlY3RvcnNfcGVyX2ZyYW1lID0gU0VDVE9SU19QRVJfRlJBTUU7CgoJaWYgKHRvYyA9PSBOVUxMKSB7CgkJLyogVHJ5IHRvIGFsbG9jYXRlIHNwYWNlLiAqLwoJCXRvYyA9IGttYWxsb2Moc2l6ZW9mKHN0cnVjdCBhdGFwaV90b2MpLCBHRlBfS0VSTkVMKTsKCQlpZiAodG9jID09IE5VTEwpIHsKCQkJcHJpbnRrIChLRVJOX0VSUiAiJXM6IE5vIGNkcm9tIFRPQyBidWZmZXIhXG4iLCBkcml2ZS0+bmFtZSk7CgkJCXJldHVybiAtRU5PTUVNOwoJCX0KCQlpbmZvLT50b2MgPSB0b2M7Cgl9CgoJLyogQ2hlY2sgdG8gc2VlIGlmIHRoZSBleGlzdGluZyBkYXRhIGlzIHN0aWxsIHZhbGlkLgoJICAgSWYgaXQgaXMsIGp1c3QgcmV0dXJuLiAqLwoJKHZvaWQpIGNkcm9tX2NoZWNrX3N0YXR1cyhkcml2ZSwgc2Vuc2UpOwoKCWlmIChDRFJPTV9TVEFURV9GTEFHUyhkcml2ZSktPnRvY192YWxpZCkKCQlyZXR1cm4gMDsKCgkvKiBUcnkgdG8gZ2V0IHRoZSB0b3RhbCBjZHJvbSBjYXBhY2l0eSBhbmQgc2VjdG9yIHNpemUuICovCglzdGF0ID0gY2Ryb21fcmVhZF9jYXBhY2l0eShkcml2ZSwgJnRvYy0+Y2FwYWNpdHksICZzZWN0b3JzX3Blcl9mcmFtZSwKCQkJCSAgIHNlbnNlKTsKCWlmIChzdGF0KQoJCXRvYy0+Y2FwYWNpdHkgPSAweDFmZmZmZjsKCglzZXRfY2FwYWNpdHkoaW5mby0+ZGlzaywgdG9jLT5jYXBhY2l0eSAqIHNlY3RvcnNfcGVyX2ZyYW1lKTsKCWJsa19xdWV1ZV9oYXJkc2VjdF9zaXplKGRyaXZlLT5xdWV1ZSwKCQkJCXNlY3RvcnNfcGVyX2ZyYW1lIDw8IFNFQ1RPUl9CSVRTKTsKCgkvKiBGaXJzdCByZWFkIGp1c3QgdGhlIGhlYWRlciwgc28gd2Uga25vdyBob3cgbG9uZyB0aGUgVE9DIGlzLiAqLwoJc3RhdCA9IGNkcm9tX3JlYWRfdG9jZW50cnkoZHJpdmUsIDAsIDEsIDAsIChjaGFyICopICZ0b2MtPmhkciwKCQkJCSAgICBzaXplb2Yoc3RydWN0IGF0YXBpX3RvY19oZWFkZXIpLCBzZW5zZSk7CglpZiAoc3RhdCkKCQlyZXR1cm4gc3RhdDsKCiNpZiAhIFNUQU5EQVJEX0FUQVBJCglpZiAoQ0RST01fQ09ORklHX0ZMQUdTKGRyaXZlKS0+dG9jdHJhY2tzX2FzX2JjZCkgewoJCXRvYy0+aGRyLmZpcnN0X3RyYWNrID0gYmNkMmJpbih0b2MtPmhkci5maXJzdF90cmFjayk7CgkJdG9jLT5oZHIubGFzdF90cmFjayAgPSBiY2QyYmluKHRvYy0+aGRyLmxhc3RfdHJhY2spOwoJfQojZW5kaWYgIC8qIG5vdCBTVEFOREFSRF9BVEFQSSAqLwoKCW50cmFja3MgPSB0b2MtPmhkci5sYXN0X3RyYWNrIC0gdG9jLT5oZHIuZmlyc3RfdHJhY2sgKyAxOwoJaWYgKG50cmFja3MgPD0gMCkKCQlyZXR1cm4gLUVJTzsKCWlmIChudHJhY2tzID4gTUFYX1RSQUNLUykKCQludHJhY2tzID0gTUFYX1RSQUNLUzsKCgkvKiBOb3cgcmVhZCB0aGUgd2hvbGUgc2NobWVlci4gKi8KCXN0YXQgPSBjZHJvbV9yZWFkX3RvY2VudHJ5KGRyaXZlLCB0b2MtPmhkci5maXJzdF90cmFjaywgMSwgMCwKCQkJCSAgKGNoYXIgKikmdG9jLT5oZHIsCgkJCQkgICBzaXplb2Yoc3RydWN0IGF0YXBpX3RvY19oZWFkZXIpICsKCQkJCSAgIChudHJhY2tzICsgMSkgKgoJCQkJICAgc2l6ZW9mKHN0cnVjdCBhdGFwaV90b2NfZW50cnkpLCBzZW5zZSk7CgoJaWYgKHN0YXQgJiYgdG9jLT5oZHIuZmlyc3RfdHJhY2sgPiAxKSB7CgkJLyogQ2RzIHdpdGggQ0RJIHRyYWNrcyBvbmx5IGRvbid0IGhhdmUgYW55IFRPQyBlbnRyaWVzLAoJCSAgIGRlc3BpdGUgb2YgdGhpcyB0aGUgcmV0dXJuZWQgdmFsdWVzIGFyZQoJCSAgIGZpcnN0X3RyYWNrID09IGxhc3RfdHJhY2sgPSBudW1iZXIgb2YgQ0RJIHRyYWNrcyArIDEsCgkJICAgc28gdGhhdCB0aGlzIGNhc2UgaXMgaW5kaXN0aW5ndWlzaGFibGUgZnJvbSB0aGUgc2FtZQoJCSAgIGxheW91dCBwbHVzIGFuIGFkZGl0aW9uYWwgYXVkaW8gdHJhY2suCgkJICAgSWYgd2UgZ2V0IGFuIGVycm9yIGZvciB0aGUgcmVndWxhciBjYXNlLCB3ZSBhc3N1bWUKCQkgICBhIENESSB3aXRob3V0IGFkZGl0aW9uYWwgYXVkaW8gdHJhY2tzLiBJbiB0aGlzIGNhc2UKCQkgICB0aGUgcmVhZGFibGUgVE9DIGlzIGVtcHR5IChDREkgdHJhY2tzIGFyZSBub3QgaW5jbHVkZWQpCgkJICAgYW5kIG9ubHkgaG9sZHMgdGhlIExlYWRvdXQgZW50cnkuIEhlaWtvIEVp32ZlbGR0ICovCgkJbnRyYWNrcyA9IDA7CgkJc3RhdCA9IGNkcm9tX3JlYWRfdG9jZW50cnkoZHJpdmUsIENEUk9NX0xFQURPVVQsIDEsIDAsCgkJCQkJICAgKGNoYXIgKikmdG9jLT5oZHIsCgkJCQkJICAgc2l6ZW9mKHN0cnVjdCBhdGFwaV90b2NfaGVhZGVyKSArCgkJCQkJICAgKG50cmFja3MgKyAxKSAqCgkJCQkJICAgc2l6ZW9mKHN0cnVjdCBhdGFwaV90b2NfZW50cnkpLAoJCQkJCSAgIHNlbnNlKTsKCQlpZiAoc3RhdCkgewoJCQlyZXR1cm4gc3RhdDsKCQl9CiNpZiAhIFNUQU5EQVJEX0FUQVBJCgkJaWYgKENEUk9NX0NPTkZJR19GTEFHUyhkcml2ZSktPnRvY3RyYWNrc19hc19iY2QpIHsKCQkJdG9jLT5oZHIuZmlyc3RfdHJhY2sgPSBiaW4yYmNkKENEUk9NX0xFQURPVVQpOwoJCQl0b2MtPmhkci5sYXN0X3RyYWNrID0gYmluMmJjZChDRFJPTV9MRUFET1VUKTsKCQl9IGVsc2UKI2VuZGlmICAvKiBub3QgU1RBTkRBUkRfQVRBUEkgKi8KCQl7CgkJCXRvYy0+aGRyLmZpcnN0X3RyYWNrID0gQ0RST01fTEVBRE9VVDsKCQkJdG9jLT5oZHIubGFzdF90cmFjayA9IENEUk9NX0xFQURPVVQ7CgkJfQoJfQoKCWlmIChzdGF0KQoJCXJldHVybiBzdGF0OwoKCXRvYy0+aGRyLnRvY19sZW5ndGggPSBudG9ocyAodG9jLT5oZHIudG9jX2xlbmd0aCk7CgojaWYgISBTVEFOREFSRF9BVEFQSQoJaWYgKENEUk9NX0NPTkZJR19GTEFHUyhkcml2ZSktPnRvY3RyYWNrc19hc19iY2QpIHsKCQl0b2MtPmhkci5maXJzdF90cmFjayA9IGJjZDJiaW4odG9jLT5oZHIuZmlyc3RfdHJhY2spOwoJCXRvYy0+aGRyLmxhc3RfdHJhY2sgID0gYmNkMmJpbih0b2MtPmhkci5sYXN0X3RyYWNrKTsKCX0KI2VuZGlmICAvKiBub3QgU1RBTkRBUkRfQVRBUEkgKi8KCglmb3IgKGk9MDsgaTw9bnRyYWNrczsgaSsrKSB7CiNpZiAhIFNUQU5EQVJEX0FUQVBJCgkJaWYgKENEUk9NX0NPTkZJR19GTEFHUyhkcml2ZSktPnRvY2FkZHJfYXNfYmNkKSB7CgkJCWlmIChDRFJPTV9DT05GSUdfRkxBR1MoZHJpdmUpLT50b2N0cmFja3NfYXNfYmNkKQoJCQkJdG9jLT5lbnRbaV0udHJhY2sgPSBiY2QyYmluKHRvYy0+ZW50W2ldLnRyYWNrKTsKCQkJbXNmX2Zyb21fYmNkKCZ0b2MtPmVudFtpXS5hZGRyLm1zZik7CgkJfQojZW5kaWYgIC8qIG5vdCBTVEFOREFSRF9BVEFQSSAqLwoJCXRvYy0+ZW50W2ldLmFkZHIubGJhID0gbXNmX3RvX2xiYSAodG9jLT5lbnRbaV0uYWRkci5tc2YubWludXRlLAoJCQkJCQkgICB0b2MtPmVudFtpXS5hZGRyLm1zZi5zZWNvbmQsCgkJCQkJCSAgIHRvYy0+ZW50W2ldLmFkZHIubXNmLmZyYW1lKTsKCX0KCgkvKiBSZWFkIHRoZSBtdWx0aXNlc3Npb24gaW5mb3JtYXRpb24uICovCglpZiAodG9jLT5oZHIuZmlyc3RfdHJhY2sgIT0gQ0RST01fTEVBRE9VVCkgewoJCS8qIFJlYWQgdGhlIG11bHRpc2Vzc2lvbiBpbmZvcm1hdGlvbi4gKi8KCQlzdGF0ID0gY2Ryb21fcmVhZF90b2NlbnRyeShkcml2ZSwgMCwgMCwgMSwgKGNoYXIgKikmbXNfdG1wLAoJCQkJCSAgIHNpemVvZihtc190bXApLCBzZW5zZSk7CgkJaWYgKHN0YXQpCgkJCXJldHVybiBzdGF0OwoKCQl0b2MtPmxhc3Rfc2Vzc2lvbl9sYmEgPSBiZTMyX3RvX2NwdShtc190bXAuZW50LmFkZHIubGJhKTsKCX0gZWxzZSB7CgkJbXNfdG1wLmhkci5maXJzdF90cmFjayA9IG1zX3RtcC5oZHIubGFzdF90cmFjayA9IENEUk9NX0xFQURPVVQ7CgkJdG9jLT5sYXN0X3Nlc3Npb25fbGJhID0gbXNmX3RvX2xiYSgwLCAyLCAwKTsgLyogMG0gMnMgMGYgKi8KCX0KCiNpZiAhIFNUQU5EQVJEX0FUQVBJCglpZiAoQ0RST01fQ09ORklHX0ZMQUdTKGRyaXZlKS0+dG9jYWRkcl9hc19iY2QpIHsKCQkvKiBSZS1yZWFkIG11bHRpc2Vzc2lvbiBpbmZvcm1hdGlvbiB1c2luZyBNU0YgZm9ybWF0ICovCgkJc3RhdCA9IGNkcm9tX3JlYWRfdG9jZW50cnkoZHJpdmUsIDAsIDEsIDEsIChjaGFyICopJm1zX3RtcCwKCQkJCQkgICBzaXplb2YobXNfdG1wKSwgc2Vuc2UpOwoJCWlmIChzdGF0KQoJCQlyZXR1cm4gc3RhdDsKCgkJbXNmX2Zyb21fYmNkICgmbXNfdG1wLmVudC5hZGRyLm1zZik7CgkJdG9jLT5sYXN0X3Nlc3Npb25fbGJhID0gbXNmX3RvX2xiYShtc190bXAuZW50LmFkZHIubXNmLm1pbnV0ZSwKCQkJCQkgIAkgICBtc190bXAuZW50LmFkZHIubXNmLnNlY29uZCwKCQkJCQkJICAgbXNfdG1wLmVudC5hZGRyLm1zZi5mcmFtZSk7Cgl9CiNlbmRpZiAgLyogbm90IFNUQU5EQVJEX0FUQVBJICovCgoJdG9jLT54YV9mbGFnID0gKG1zX3RtcC5oZHIuZmlyc3RfdHJhY2sgIT0gbXNfdG1wLmhkci5sYXN0X3RyYWNrKTsKCgkvKiBOb3cgdHJ5IHRvIGdldCB0aGUgdG90YWwgY2Ryb20gY2FwYWNpdHkuICovCglzdGF0ID0gY2Ryb21fZ2V0X2xhc3Rfd3JpdHRlbihjZGksICZsYXN0X3dyaXR0ZW4pOwoJaWYgKCFzdGF0ICYmIChsYXN0X3dyaXR0ZW4gPiB0b2MtPmNhcGFjaXR5KSkgewoJCXRvYy0+Y2FwYWNpdHkgPSBsYXN0X3dyaXR0ZW47CgkJc2V0X2NhcGFjaXR5KGluZm8tPmRpc2ssIHRvYy0+Y2FwYWNpdHkgKiBzZWN0b3JzX3Blcl9mcmFtZSk7Cgl9CgoJLyogUmVtZW1iZXIgdGhhdCB3ZSd2ZSByZWFkIHRoaXMgc3R1ZmYuICovCglDRFJPTV9TVEFURV9GTEFHUyhkcml2ZSktPnRvY192YWxpZCA9IDE7CgoJcmV0dXJuIDA7Cn0KCgpzdGF0aWMgaW50IGNkcm9tX3JlYWRfc3ViY2hhbm5lbChpZGVfZHJpdmVfdCAqZHJpdmUsIGludCBmb3JtYXQsIGNoYXIgKmJ1ZiwKCQkJCSBpbnQgYnVmbGVuLCBzdHJ1Y3QgcmVxdWVzdF9zZW5zZSAqc2Vuc2UpCnsKCXN0cnVjdCByZXF1ZXN0IHJlcTsKCgljZHJvbV9wcmVwYXJlX3JlcXVlc3QoZHJpdmUsICZyZXEpOwoKCXJlcS5zZW5zZSA9IHNlbnNlOwoJcmVxLmRhdGEgPSBidWY7CglyZXEuZGF0YV9sZW4gPSBidWZsZW47CglyZXEuY21kWzBdID0gR1BDTURfUkVBRF9TVUJDSEFOTkVMOwoJcmVxLmNtZFsxXSA9IDI7ICAgICAvKiBNU0YgYWRkcmVzc2luZyAqLwoJcmVxLmNtZFsyXSA9IDB4NDA7ICAvKiByZXF1ZXN0IHN1YlEgZGF0YSAqLwoJcmVxLmNtZFszXSA9IGZvcm1hdDsKCXJlcS5jbWRbN10gPSAoYnVmbGVuID4+IDgpOwoJcmVxLmNtZFs4XSA9IChidWZsZW4gJiAweGZmKTsKCXJldHVybiBjZHJvbV9xdWV1ZV9wYWNrZXRfY29tbWFuZChkcml2ZSwgJnJlcSk7Cn0KCi8qIEFUQVBJIGNkcm9tIGRyaXZlcyBhcmUgZnJlZSB0byBzZWxlY3QgdGhlIHNwZWVkIHlvdSByZXF1ZXN0IG9yIGFueSBzbG93ZXIKICAgcmF0ZSA6LSggUmVxdWVzdGluZyB0b28gZmFzdCBhIHNwZWVkIHdpbGwgX25vdF8gcHJvZHVjZSBhbiBlcnJvci4gKi8Kc3RhdGljIGludCBjZHJvbV9zZWxlY3Rfc3BlZWQoaWRlX2RyaXZlX3QgKmRyaXZlLCBpbnQgc3BlZWQsCgkJCSAgICAgIHN0cnVjdCByZXF1ZXN0X3NlbnNlICpzZW5zZSkKewoJc3RydWN0IHJlcXVlc3QgcmVxOwoJY2Ryb21fcHJlcGFyZV9yZXF1ZXN0KGRyaXZlLCAmcmVxKTsKCglyZXEuc2Vuc2UgPSBzZW5zZTsKCWlmIChzcGVlZCA9PSAwKQoJCXNwZWVkID0gMHhmZmZmOyAvKiBzZXQgdG8gbWF4ICovCgllbHNlCgkJc3BlZWQgKj0gMTc3OyAgIC8qIE54IHRvIGtieXRlcy9zICovCgoJcmVxLmNtZFswXSA9IEdQQ01EX1NFVF9TUEVFRDsKCS8qIFJlYWQgRHJpdmUgc3BlZWQgaW4ga2J5dGVzL3NlY29uZCBNU0IgKi8KCXJlcS5jbWRbMl0gPSAoc3BlZWQgPj4gOCkgJiAweGZmOwkKCS8qIFJlYWQgRHJpdmUgc3BlZWQgaW4ga2J5dGVzL3NlY29uZCBMU0IgKi8KCXJlcS5jbWRbM10gPSBzcGVlZCAmIDB4ZmY7CglpZiAoQ0RST01fQ09ORklHX0ZMQUdTKGRyaXZlKS0+Y2RfciB8fAoJICAgIENEUk9NX0NPTkZJR19GTEFHUyhkcml2ZSktPmNkX3J3IHx8CgkgICAgQ0RST01fQ09ORklHX0ZMQUdTKGRyaXZlKS0+ZHZkX3IpIHsKCQkvKiBXcml0ZSBEcml2ZSBzcGVlZCBpbiBrYnl0ZXMvc2Vjb25kIE1TQiAqLwoJCXJlcS5jbWRbNF0gPSAoc3BlZWQgPj4gOCkgJiAweGZmOwoJCS8qIFdyaXRlIERyaXZlIHNwZWVkIGluIGtieXRlcy9zZWNvbmQgTFNCICovCgkJcmVxLmNtZFs1XSA9IHNwZWVkICYgMHhmZjsKICAgICAgIH0KCglyZXR1cm4gY2Ryb21fcXVldWVfcGFja2V0X2NvbW1hbmQoZHJpdmUsICZyZXEpOwp9CgpzdGF0aWMgaW50IGNkcm9tX3BsYXlfYXVkaW8oaWRlX2RyaXZlX3QgKmRyaXZlLCBpbnQgbGJhX3N0YXJ0LCBpbnQgbGJhX2VuZCkKewoJc3RydWN0IHJlcXVlc3Rfc2Vuc2Ugc2Vuc2U7CglzdHJ1Y3QgcmVxdWVzdCByZXE7CgoJY2Ryb21fcHJlcGFyZV9yZXF1ZXN0KGRyaXZlLCAmcmVxKTsKCglyZXEuc2Vuc2UgPSAmc2Vuc2U7CglyZXEuY21kWzBdID0gR1BDTURfUExBWV9BVURJT19NU0Y7CglsYmFfdG9fbXNmKGxiYV9zdGFydCwgJnJlcS5jbWRbM10sICZyZXEuY21kWzRdLCAmcmVxLmNtZFs1XSk7CglsYmFfdG9fbXNmKGxiYV9lbmQtMSwgJnJlcS5jbWRbNl0sICZyZXEuY21kWzddLCAmcmVxLmNtZFs4XSk7CgoJcmV0dXJuIGNkcm9tX3F1ZXVlX3BhY2tldF9jb21tYW5kKGRyaXZlLCAmcmVxKTsKfQoKc3RhdGljIGludCBjZHJvbV9nZXRfdG9jX2VudHJ5KGlkZV9kcml2ZV90ICpkcml2ZSwgaW50IHRyYWNrLAoJCQkJc3RydWN0IGF0YXBpX3RvY19lbnRyeSAqKmVudCkKewoJc3RydWN0IGNkcm9tX2luZm8gKmluZm8gPSBkcml2ZS0+ZHJpdmVyX2RhdGE7CglzdHJ1Y3QgYXRhcGlfdG9jICp0b2MgPSBpbmZvLT50b2M7CglpbnQgbnRyYWNrczsKCgkvKgoJICogZG9uJ3Qgc2VydmUgY2FjaGVkIGRhdGEsIGlmIHRoZSB0b2MgaXNuJ3QgdmFsaWQKCSAqLwoJaWYgKCFDRFJPTV9TVEFURV9GTEFHUyhkcml2ZSktPnRvY192YWxpZCkKCQlyZXR1cm4gLUVJTlZBTDsKCgkvKiBDaGVjayB2YWxpZGl0eSBvZiByZXF1ZXN0ZWQgdHJhY2sgbnVtYmVyLiAqLwoJbnRyYWNrcyA9IHRvYy0+aGRyLmxhc3RfdHJhY2sgLSB0b2MtPmhkci5maXJzdF90cmFjayArIDE7CglpZiAodG9jLT5oZHIuZmlyc3RfdHJhY2sgPT0gQ0RST01fTEVBRE9VVCkgbnRyYWNrcyA9IDA7CglpZiAodHJhY2sgPT0gQ0RST01fTEVBRE9VVCkKCQkqZW50ID0gJnRvYy0+ZW50W250cmFja3NdOwoJZWxzZSBpZiAodHJhY2sgPCB0b2MtPmhkci5maXJzdF90cmFjayB8fAoJCSB0cmFjayA+IHRvYy0+aGRyLmxhc3RfdHJhY2spCgkJcmV0dXJuIC1FSU5WQUw7CgllbHNlCgkJKmVudCA9ICZ0b2MtPmVudFt0cmFjayAtIHRvYy0+aGRyLmZpcnN0X3RyYWNrXTsKCglyZXR1cm4gMDsKfQoKLyogdGhlIGdlbmVyaWMgcGFja2V0IGludGVyZmFjZSB0byBjZHJvbS5jICovCnN0YXRpYyBpbnQgaWRlX2Nkcm9tX3BhY2tldChzdHJ1Y3QgY2Ryb21fZGV2aWNlX2luZm8gKmNkaSwKCQkJICAgIHN0cnVjdCBwYWNrZXRfY29tbWFuZCAqY2djKQp7CglzdHJ1Y3QgcmVxdWVzdCByZXE7CglpZGVfZHJpdmVfdCAqZHJpdmUgPSBjZGktPmhhbmRsZTsKCglpZiAoY2djLT50aW1lb3V0IDw9IDApCgkJY2djLT50aW1lb3V0ID0gQVRBUElfV0FJVF9QQzsKCgkvKiBoZXJlIHdlIHF1ZXVlIHRoZSBjb21tYW5kcyBmcm9tIHRoZSB1bmlmb3JtIENELVJPTQoJICAgbGF5ZXIuIHRoZSBwYWNrZXQgbXVzdCBiZSBjb21wbGV0ZSwgYXMgd2UgZG8gbm90CgkgICB0b3VjaCBpdCBhdCBhbGwuICovCgljZHJvbV9wcmVwYXJlX3JlcXVlc3QoZHJpdmUsICZyZXEpOwoJbWVtY3B5KHJlcS5jbWQsIGNnYy0+Y21kLCBDRFJPTV9QQUNLRVRfU0laRSk7CglpZiAoY2djLT5zZW5zZSkKCQltZW1zZXQoY2djLT5zZW5zZSwgMCwgc2l6ZW9mKHN0cnVjdCByZXF1ZXN0X3NlbnNlKSk7CglyZXEuZGF0YSA9IGNnYy0+YnVmZmVyOwoJcmVxLmRhdGFfbGVuID0gY2djLT5idWZsZW47CglyZXEudGltZW91dCA9IGNnYy0+dGltZW91dDsKCglpZiAoY2djLT5xdWlldCkKCQlyZXEuZmxhZ3MgfD0gUkVRX1FVSUVUOwoKCXJlcS5zZW5zZSA9IGNnYy0+c2Vuc2U7CgljZ2MtPnN0YXQgPSBjZHJvbV9xdWV1ZV9wYWNrZXRfY29tbWFuZChkcml2ZSwgJnJlcSk7CglpZiAoIWNnYy0+c3RhdCkKCQljZ2MtPmJ1ZmxlbiAtPSByZXEuZGF0YV9sZW47CglyZXR1cm4gY2djLT5zdGF0Owp9CgpzdGF0aWMKaW50IGlkZV9jZHJvbV9hdWRpb19pb2N0bCAoc3RydWN0IGNkcm9tX2RldmljZV9pbmZvICpjZGksCgkJCSAgIHVuc2lnbmVkIGludCBjbWQsIHZvaWQgKmFyZykKCQkJICAgCnsKCWlkZV9kcml2ZV90ICpkcml2ZSA9IGNkaS0+aGFuZGxlOwoJc3RydWN0IGNkcm9tX2luZm8gKmluZm8gPSBkcml2ZS0+ZHJpdmVyX2RhdGE7CglpbnQgc3RhdDsKCglzd2l0Y2ggKGNtZCkgewoJLyoKCSAqIGVtdWxhdGUgUExBWV9BVURJT19USSBjb21tYW5kIHdpdGggUExBWV9BVURJT18xMCwgc2luY2UKCSAqIGF0YXBpIGRvZXNuJ3Qgc3VwcG9ydCBpdAoJICovCgljYXNlIENEUk9NUExBWVRSS0lORDogewoJCXVuc2lnbmVkIGxvbmcgbGJhX3N0YXJ0LCBsYmFfZW5kOwoJCXN0cnVjdCBjZHJvbV90aSAqdGkgPSBhcmc7CgkJc3RydWN0IGF0YXBpX3RvY19lbnRyeSAqZmlyc3RfdG9jLCAqbGFzdF90b2M7CgoJCXN0YXQgPSBjZHJvbV9nZXRfdG9jX2VudHJ5KGRyaXZlLCB0aS0+Y2R0aV90cmswLCAmZmlyc3RfdG9jKTsKCQlpZiAoc3RhdCkKCQkJcmV0dXJuIHN0YXQ7CgoJCXN0YXQgPSBjZHJvbV9nZXRfdG9jX2VudHJ5KGRyaXZlLCB0aS0+Y2R0aV90cmsxLCAmbGFzdF90b2MpOwoJCWlmIChzdGF0KQoJCQlyZXR1cm4gc3RhdDsKCgkJaWYgKHRpLT5jZHRpX3RyazEgIT0gQ0RST01fTEVBRE9VVCkKCQkJKytsYXN0X3RvYzsKCQlsYmFfc3RhcnQgPSBmaXJzdF90b2MtPmFkZHIubGJhOwoJCWxiYV9lbmQgICA9IGxhc3RfdG9jLT5hZGRyLmxiYTsKCgkJaWYgKGxiYV9lbmQgPD0gbGJhX3N0YXJ0KQoJCQlyZXR1cm4gLUVJTlZBTDsKCgkJcmV0dXJuIGNkcm9tX3BsYXlfYXVkaW8oZHJpdmUsIGxiYV9zdGFydCwgbGJhX2VuZCk7Cgl9CgoJY2FzZSBDRFJPTVJFQURUT0NIRFI6IHsKCQlzdHJ1Y3QgY2Ryb21fdG9jaGRyICp0b2NoZHIgPSBhcmc7CgkJc3RydWN0IGF0YXBpX3RvYyAqdG9jOwoKCQkvKiBNYWtlIHN1cmUgb3VyIHNhdmVkIFRPQyBpcyB2YWxpZC4gKi8KCQlzdGF0ID0gY2Ryb21fcmVhZF90b2MoZHJpdmUsIE5VTEwpOwoJCWlmIChzdGF0KQoJCQlyZXR1cm4gc3RhdDsKCgkJdG9jID0gaW5mby0+dG9jOwoJCXRvY2hkci0+Y2R0aF90cmswID0gdG9jLT5oZHIuZmlyc3RfdHJhY2s7CgkJdG9jaGRyLT5jZHRoX3RyazEgPSB0b2MtPmhkci5sYXN0X3RyYWNrOwoKCQlyZXR1cm4gMDsKCX0KCgljYXNlIENEUk9NUkVBRFRPQ0VOVFJZOiB7CgkJc3RydWN0IGNkcm9tX3RvY2VudHJ5ICp0b2NlbnRyeSA9IGFyZzsKCQlzdHJ1Y3QgYXRhcGlfdG9jX2VudHJ5ICp0b2NlOwoKCQlzdGF0ID0gY2Ryb21fZ2V0X3RvY19lbnRyeShkcml2ZSwgdG9jZW50cnktPmNkdGVfdHJhY2ssICZ0b2NlKTsKCQlpZiAoc3RhdCkKCQkJcmV0dXJuIHN0YXQ7CgoJCXRvY2VudHJ5LT5jZHRlX2N0cmwgPSB0b2NlLT5jb250cm9sOwoJCXRvY2VudHJ5LT5jZHRlX2FkciAgPSB0b2NlLT5hZHI7CgkJaWYgKHRvY2VudHJ5LT5jZHRlX2Zvcm1hdCA9PSBDRFJPTV9NU0YpIHsKCQkJbGJhX3RvX21zZiAodG9jZS0+YWRkci5sYmEsCgkJCQkgICAmdG9jZW50cnktPmNkdGVfYWRkci5tc2YubWludXRlLAoJCQkJICAgJnRvY2VudHJ5LT5jZHRlX2FkZHIubXNmLnNlY29uZCwKCQkJCSAgICZ0b2NlbnRyeS0+Y2R0ZV9hZGRyLm1zZi5mcmFtZSk7CgkJfSBlbHNlCgkJCXRvY2VudHJ5LT5jZHRlX2FkZHIubGJhID0gdG9jZS0+YWRkci5sYmE7CgoJCXJldHVybiAwOwoJfQoKCWRlZmF1bHQ6CgkJcmV0dXJuIC1FSU5WQUw7Cgl9Cn0KCnN0YXRpYwppbnQgaWRlX2Nkcm9tX3Jlc2V0IChzdHJ1Y3QgY2Ryb21fZGV2aWNlX2luZm8gKmNkaSkKewoJaWRlX2RyaXZlX3QgKmRyaXZlID0gY2RpLT5oYW5kbGU7CglzdHJ1Y3QgcmVxdWVzdF9zZW5zZSBzZW5zZTsKCXN0cnVjdCByZXF1ZXN0IHJlcTsKCWludCByZXQ7CgoJY2Ryb21fcHJlcGFyZV9yZXF1ZXN0KGRyaXZlLCAmcmVxKTsKCXJlcS5mbGFncyA9IFJFUV9TUEVDSUFMIHwgUkVRX1FVSUVUOwoJcmV0ID0gaWRlX2RvX2RyaXZlX2NtZChkcml2ZSwgJnJlcSwgaWRlX3dhaXQpOwoKCS8qCgkgKiBBIHJlc2V0IHdpbGwgdW5sb2NrIHRoZSBkb29yLiBJZiBpdCB3YXMgcHJldmlvdXNseSBsb2NrZWQsCgkgKiBsb2NrIGl0IGFnYWluLgoJICovCglpZiAoQ0RST01fU1RBVEVfRkxBR1MoZHJpdmUpLT5kb29yX2xvY2tlZCkKCQkodm9pZCkgY2Ryb21fbG9ja2Rvb3IoZHJpdmUsIDEsICZzZW5zZSk7CgoJcmV0dXJuIHJldDsKfQoKCnN0YXRpYwppbnQgaWRlX2Nkcm9tX3RyYXlfbW92ZSAoc3RydWN0IGNkcm9tX2RldmljZV9pbmZvICpjZGksIGludCBwb3NpdGlvbikKewoJaWRlX2RyaXZlX3QgKmRyaXZlID0gY2RpLT5oYW5kbGU7CglzdHJ1Y3QgcmVxdWVzdF9zZW5zZSBzZW5zZTsKCglpZiAocG9zaXRpb24pIHsKCQlpbnQgc3RhdCA9IGNkcm9tX2xvY2tkb29yKGRyaXZlLCAwLCAmc2Vuc2UpOwoJCWlmIChzdGF0KQoJCQlyZXR1cm4gc3RhdDsKCX0KCglyZXR1cm4gY2Ryb21fZWplY3QoZHJpdmUsICFwb3NpdGlvbiwgJnNlbnNlKTsKfQoKc3RhdGljCmludCBpZGVfY2Ryb21fbG9ja19kb29yIChzdHJ1Y3QgY2Ryb21fZGV2aWNlX2luZm8gKmNkaSwgaW50IGxvY2spCnsKCWlkZV9kcml2ZV90ICpkcml2ZSA9IGNkaS0+aGFuZGxlOwoJcmV0dXJuIGNkcm9tX2xvY2tkb29yKGRyaXZlLCBsb2NrLCBOVUxMKTsKfQoKc3RhdGljCmludCBpZGVfY2Ryb21fZ2V0X2NhcGFiaWxpdGllcyhpZGVfZHJpdmVfdCAqZHJpdmUsIHN0cnVjdCBhdGFwaV9jYXBhYmlsaXRpZXNfcGFnZSAqY2FwKQp7CglzdHJ1Y3QgY2Ryb21faW5mbyAqaW5mbyA9IGRyaXZlLT5kcml2ZXJfZGF0YTsKCXN0cnVjdCBjZHJvbV9kZXZpY2VfaW5mbyAqY2RpID0gJmluZm8tPmRldmluZm87CglzdHJ1Y3QgcGFja2V0X2NvbW1hbmQgY2djOwoJaW50IHN0YXQsIGF0dGVtcHRzID0gMywgc2l6ZSA9IHNpemVvZigqY2FwKTsKCgkvKgoJICogQUNFUjUwIChhbmQgb3RoZXJzPykgcmVxdWlyZSB0aGUgZnVsbCBzcGVjIGxlbmd0aCBtb2RlIHNlbnNlCgkgKiBwYWdlIGNhcGFiaWxpdGllcyBzaXplLCBidXQgb2xkZXIgZHJpdmVzIGJyZWFrLgoJICovCglpZiAoISghc3RyY21wKGRyaXZlLT5pZC0+bW9kZWwsICJBVEFQSSBDRCBST00gRFJJVkUgNTBYIE1BWCIpIHx8CgkgICAgIXN0cmNtcChkcml2ZS0+aWQtPm1vZGVsLCAiV1BJIENEUy0zMlgiKSkpCgkJc2l6ZSAtPSBzaXplb2YoY2FwLT5wYWQpOwoKCWluaXRfY2Ryb21fY29tbWFuZCgmY2djLCBjYXAsIHNpemUsIENHQ19EQVRBX1VOS05PV04pOwoJZG8geyAvKiB3ZSBzZWVtIHRvIGdldCBzdGF0PTB4MDEsZXJyPTB4MDAgdGhlIGZpcnN0IHRpbWUgKD8/KSAqLwoJCXN0YXQgPSBjZHJvbV9tb2RlX3NlbnNlKGNkaSwgJmNnYywgR1BNT0RFX0NBUEFCSUxJVElFU19QQUdFLCAwKTsKCQlpZiAoIXN0YXQpCgkJCWJyZWFrOwoJfSB3aGlsZSAoLS1hdHRlbXB0cyk7CglyZXR1cm4gc3RhdDsKfQoKc3RhdGljCnZvaWQgaWRlX2Nkcm9tX3VwZGF0ZV9zcGVlZCAoaWRlX2RyaXZlX3QgKmRyaXZlLCBzdHJ1Y3QgYXRhcGlfY2FwYWJpbGl0aWVzX3BhZ2UgKmNhcCkKewoJLyogVGhlIEFDRVIvQU9wZW4gMjRYIGNkcm9tIGhhcyB0aGUgc3BlZWQgZmllbGRzIGJ5dGUtc3dhcHBlZCAqLwoJaWYgKCFkcml2ZS0+aWQtPm1vZGVsWzBdICYmCgkgICAgIXN0cm5jbXAoZHJpdmUtPmlkLT5md19yZXYsICIyNDFOIiwgNCkpIHsKCQlDRFJPTV9TVEFURV9GTEFHUyhkcml2ZSktPmN1cnJlbnRfc3BlZWQgID0KCQkJKCgodW5zaWduZWQgaW50KWNhcC0+Y3Vyc3BlZWQpICsgKDE3Ni8yKSkgLyAxNzY7CgkJQ0RST01fQ09ORklHX0ZMQUdTKGRyaXZlKS0+bWF4X3NwZWVkID0KCQkJKCgodW5zaWduZWQgaW50KWNhcC0+bWF4c3BlZWQpICsgKDE3Ni8yKSkgLyAxNzY7Cgl9IGVsc2UgewoJCUNEUk9NX1NUQVRFX0ZMQUdTKGRyaXZlKS0+Y3VycmVudF9zcGVlZCAgPQoJCQkobnRvaHMoY2FwLT5jdXJzcGVlZCkgKyAoMTc2LzIpKSAvIDE3NjsKCQlDRFJPTV9DT05GSUdfRkxBR1MoZHJpdmUpLT5tYXhfc3BlZWQgPQoJCQkobnRvaHMoY2FwLT5tYXhzcGVlZCkgKyAoMTc2LzIpKSAvIDE3NjsKCX0KfQoKc3RhdGljCmludCBpZGVfY2Ryb21fc2VsZWN0X3NwZWVkIChzdHJ1Y3QgY2Ryb21fZGV2aWNlX2luZm8gKmNkaSwgaW50IHNwZWVkKQp7CglpZGVfZHJpdmVfdCAqZHJpdmUgPSBjZGktPmhhbmRsZTsKCXN0cnVjdCByZXF1ZXN0X3NlbnNlIHNlbnNlOwoJc3RydWN0IGF0YXBpX2NhcGFiaWxpdGllc19wYWdlIGNhcDsKCWludCBzdGF0OwoKCWlmICgoc3RhdCA9IGNkcm9tX3NlbGVjdF9zcGVlZChkcml2ZSwgc3BlZWQsICZzZW5zZSkpIDwgMCkKCQlyZXR1cm4gc3RhdDsKCglpZiAoIWlkZV9jZHJvbV9nZXRfY2FwYWJpbGl0aWVzKGRyaXZlLCAmY2FwKSkgewoJCWlkZV9jZHJvbV91cGRhdGVfc3BlZWQoZHJpdmUsICZjYXApOwoJCWNkaS0+c3BlZWQgPSBDRFJPTV9TVEFURV9GTEFHUyhkcml2ZSktPmN1cnJlbnRfc3BlZWQ7Cgl9CiAgICAgICAgcmV0dXJuIDA7Cn0KCi8qCiAqIGFkZCBsb2dpYyB0byB0cnkgR0VUX0VWRU5UIGNvbW1hbmQgZmlyc3QgdG8gY2hlY2sgZm9yIG1lZGlhIGFuZCB0cmF5CiAqIHN0YXR1cy4gdGhpcyBzaG91bGQgYmUgc3VwcG9ydGVkIGJ5IG5ld2VyIGNkLXIvdyBhbmQgYWxsIERWRCBldGMKICogZHJpdmVzCiAqLwpzdGF0aWMKaW50IGlkZV9jZHJvbV9kcml2ZV9zdGF0dXMgKHN0cnVjdCBjZHJvbV9kZXZpY2VfaW5mbyAqY2RpLCBpbnQgc2xvdF9ucikKewoJaWRlX2RyaXZlX3QgKmRyaXZlID0gY2RpLT5oYW5kbGU7CglzdHJ1Y3QgbWVkaWFfZXZlbnRfZGVzYyBtZWQ7CglzdHJ1Y3QgcmVxdWVzdF9zZW5zZSBzZW5zZTsKCWludCBzdGF0OwoKCWlmIChzbG90X25yICE9IENEU0xfQ1VSUkVOVCkKCQlyZXR1cm4gLUVJTlZBTDsKCglzdGF0ID0gY2Ryb21fY2hlY2tfc3RhdHVzKGRyaXZlLCAmc2Vuc2UpOwoJaWYgKCFzdGF0IHx8IHNlbnNlLnNlbnNlX2tleSA9PSBVTklUX0FUVEVOVElPTikKCQlyZXR1cm4gQ0RTX0RJU0NfT0s7CgoJaWYgKCFjZHJvbV9nZXRfbWVkaWFfZXZlbnQoY2RpLCAmbWVkKSkgewoJCWlmIChtZWQubWVkaWFfcHJlc2VudCkKCQkJcmV0dXJuIENEU19ESVNDX09LOwoJCWVsc2UgaWYgKG1lZC5kb29yX29wZW4pCgkJCXJldHVybiBDRFNfVFJBWV9PUEVOOwoJCWVsc2UKCQkJcmV0dXJuIENEU19OT19ESVNDOwoJfQoKCWlmIChzZW5zZS5zZW5zZV9rZXkgPT0gTk9UX1JFQURZICYmIHNlbnNlLmFzYyA9PSAweDA0ICYmIHNlbnNlLmFzY3EgPT0gMHgwNCkKCQlyZXR1cm4gQ0RTX0RJU0NfT0s7CgoJLyoKCSAqIElmIG5vdCB1c2luZyBNdCBGdWppIGV4dGVuZGVkIG1lZGlhIHRyYXkgcmVwb3J0cywKCSAqIGp1c3QgcmV0dXJuIFRSQVlfT1BFTiBzaW5jZSBBVEFQSSBkb2Vzbid0IHByb3ZpZGUKCSAqIGFueSBvdGhlciB3YXkgdG8gZGV0ZWN0IHRoaXMuLi4KCSAqLwoJaWYgKHNlbnNlLnNlbnNlX2tleSA9PSBOT1RfUkVBRFkpIHsKCQlpZiAoc2Vuc2UuYXNjID09IDB4M2EpIHsKCQkJaWYgKHNlbnNlLmFzY3EgPT0gMSkKCQkJCXJldHVybiBDRFNfTk9fRElTQzsKCQkJZWxzZSBpZiAoc2Vuc2UuYXNjcSA9PSAwIHx8IHNlbnNlLmFzY3EgPT0gMikKCQkJCXJldHVybiBDRFNfVFJBWV9PUEVOOwoJCX0KCX0KCglyZXR1cm4gQ0RTX0RSSVZFX05PVF9SRUFEWTsKfQoKc3RhdGljCmludCBpZGVfY2Ryb21fZ2V0X2xhc3Rfc2Vzc2lvbiAoc3RydWN0IGNkcm9tX2RldmljZV9pbmZvICpjZGksCgkJCQlzdHJ1Y3QgY2Ryb21fbXVsdGlzZXNzaW9uICptc19pbmZvKQp7CglzdHJ1Y3QgYXRhcGlfdG9jICp0b2M7CglpZGVfZHJpdmVfdCAqZHJpdmUgPSBjZGktPmhhbmRsZTsKCXN0cnVjdCBjZHJvbV9pbmZvICppbmZvID0gZHJpdmUtPmRyaXZlcl9kYXRhOwoJc3RydWN0IHJlcXVlc3Rfc2Vuc2Ugc2Vuc2U7CglpbnQgcmV0OwoKCWlmICghQ0RST01fU1RBVEVfRkxBR1MoZHJpdmUpLT50b2NfdmFsaWQgfHwgaW5mby0+dG9jID09IE5VTEwpCgkJaWYgKChyZXQgPSBjZHJvbV9yZWFkX3RvYyhkcml2ZSwgJnNlbnNlKSkpCgkJCXJldHVybiByZXQ7CgoJdG9jID0gaW5mby0+dG9jOwoJbXNfaW5mby0+YWRkci5sYmEgPSB0b2MtPmxhc3Rfc2Vzc2lvbl9sYmE7Cgltc19pbmZvLT54YV9mbGFnID0gdG9jLT54YV9mbGFnOwoKCXJldHVybiAwOwp9CgpzdGF0aWMKaW50IGlkZV9jZHJvbV9nZXRfbWNuIChzdHJ1Y3QgY2Ryb21fZGV2aWNlX2luZm8gKmNkaSwKCQkgICAgICAgc3RydWN0IGNkcm9tX21jbiAqbWNuX2luZm8pCnsKCWludCBzdGF0OwoJY2hhciBtY25idWZbMjRdOwoJaWRlX2RyaXZlX3QgKmRyaXZlID0gY2RpLT5oYW5kbGU7CgovKiBnZXQgTUNOICovCglpZiAoKHN0YXQgPSBjZHJvbV9yZWFkX3N1YmNoYW5uZWwoZHJpdmUsIDIsIG1jbmJ1Ziwgc2l6ZW9mIChtY25idWYpLCBOVUxMKSkpCgkJcmV0dXJuIHN0YXQ7CgoJbWVtY3B5IChtY25faW5mby0+bWVkaXVtX2NhdGFsb2dfbnVtYmVyLCBtY25idWYrOSwKCQlzaXplb2YgKG1jbl9pbmZvLT5tZWRpdW1fY2F0YWxvZ19udW1iZXIpLTEpOwoJbWNuX2luZm8tPm1lZGl1bV9jYXRhbG9nX251bWJlcltzaXplb2YgKG1jbl9pbmZvLT5tZWRpdW1fY2F0YWxvZ19udW1iZXIpLTFdCgkJPSAnXDAnOwoKCXJldHVybiAwOwp9CgoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIE90aGVyIGRyaXZlciByZXF1ZXN0cyAob3BlbiwgY2xvc2UsIGNoZWNrIG1lZGlhIGNoYW5nZSkuCiAqLwoKc3RhdGljCmludCBpZGVfY2Ryb21fY2hlY2tfbWVkaWFfY2hhbmdlX3JlYWwgKHN0cnVjdCBjZHJvbV9kZXZpY2VfaW5mbyAqY2RpLAoJCQkJICAgICAgIGludCBzbG90X25yKQp7CglpZGVfZHJpdmVfdCAqZHJpdmUgPSBjZGktPmhhbmRsZTsKCWludCByZXR2YWw7CgkKCWlmIChzbG90X25yID09IENEU0xfQ1VSUkVOVCkgewoJCSh2b2lkKSBjZHJvbV9jaGVja19zdGF0dXMoZHJpdmUsIE5VTEwpOwoJCXJldHZhbCA9IENEUk9NX1NUQVRFX0ZMQUdTKGRyaXZlKS0+bWVkaWFfY2hhbmdlZDsKCQlDRFJPTV9TVEFURV9GTEFHUyhkcml2ZSktPm1lZGlhX2NoYW5nZWQgPSAwOwoJCXJldHVybiByZXR2YWw7Cgl9IGVsc2UgewoJCXJldHVybiAtRUlOVkFMOwoJfQp9CgoKc3RhdGljCmludCBpZGVfY2Ryb21fb3Blbl9yZWFsIChzdHJ1Y3QgY2Ryb21fZGV2aWNlX2luZm8gKmNkaSwgaW50IHB1cnBvc2UpCnsKCXJldHVybiAwOwp9CgovKgogKiBDbG9zZSBkb3duIHRoZSBkZXZpY2UuICBJbnZhbGlkYXRlIGFsbCBjYWNoZWQgYmxvY2tzLgogKi8KCnN0YXRpYwp2b2lkIGlkZV9jZHJvbV9yZWxlYXNlX3JlYWwgKHN0cnVjdCBjZHJvbV9kZXZpY2VfaW5mbyAqY2RpKQp7CglpZGVfZHJpdmVfdCAqZHJpdmUgPSBjZGktPmhhbmRsZTsKCglpZiAoIWNkaS0+dXNlX2NvdW50KQoJCUNEUk9NX1NUQVRFX0ZMQUdTKGRyaXZlKS0+dG9jX3ZhbGlkID0gMDsKfQoKCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBEZXZpY2UgaW5pdGlhbGl6YXRpb24uCiAqLwpzdGF0aWMgc3RydWN0IGNkcm9tX2RldmljZV9vcHMgaWRlX2Nkcm9tX2RvcHMgPSB7Cgkub3BlbgkJCT0gaWRlX2Nkcm9tX29wZW5fcmVhbCwKCS5yZWxlYXNlCQk9IGlkZV9jZHJvbV9yZWxlYXNlX3JlYWwsCgkuZHJpdmVfc3RhdHVzCQk9IGlkZV9jZHJvbV9kcml2ZV9zdGF0dXMsCgkubWVkaWFfY2hhbmdlZAkJPSBpZGVfY2Ryb21fY2hlY2tfbWVkaWFfY2hhbmdlX3JlYWwsCgkudHJheV9tb3ZlCQk9IGlkZV9jZHJvbV90cmF5X21vdmUsCgkubG9ja19kb29yCQk9IGlkZV9jZHJvbV9sb2NrX2Rvb3IsCgkuc2VsZWN0X3NwZWVkCQk9IGlkZV9jZHJvbV9zZWxlY3Rfc3BlZWQsCgkuZ2V0X2xhc3Rfc2Vzc2lvbgk9IGlkZV9jZHJvbV9nZXRfbGFzdF9zZXNzaW9uLAoJLmdldF9tY24JCT0gaWRlX2Nkcm9tX2dldF9tY24sCgkucmVzZXQJCQk9IGlkZV9jZHJvbV9yZXNldCwKCS5hdWRpb19pb2N0bAkJPSBpZGVfY2Ryb21fYXVkaW9faW9jdGwsCgkuY2FwYWJpbGl0eQkJPSBDRENfQ0xPU0VfVFJBWSB8IENEQ19PUEVOX1RSQVkgfCBDRENfTE9DSyB8CgkJCQlDRENfU0VMRUNUX1NQRUVEIHwgQ0RDX1NFTEVDVF9ESVNDIHwKCQkJCUNEQ19NVUxUSV9TRVNTSU9OIHwgQ0RDX01DTiB8CgkJCQlDRENfTUVESUFfQ0hBTkdFRCB8IENEQ19QTEFZX0FVRElPIHwgQ0RDX1JFU0VUIHwKCQkJCUNEQ19EUklWRV9TVEFUVVMgfCBDRENfQ0RfUiB8CgkJCQlDRENfQ0RfUlcgfCBDRENfRFZEIHwgQ0RDX0RWRF9SfCBDRENfRFZEX1JBTSB8CgkJCQlDRENfR0VORVJJQ19QQUNLRVQgfCBDRENfTU9fRFJJVkUgfCBDRENfTVJXIHwKCQkJCUNEQ19NUldfVyB8IENEQ19SQU0sCgkuZ2VuZXJpY19wYWNrZXQJCT0gaWRlX2Nkcm9tX3BhY2tldCwKfTsKCnN0YXRpYyBpbnQgaWRlX2Nkcm9tX3JlZ2lzdGVyIChpZGVfZHJpdmVfdCAqZHJpdmUsIGludCBuc2xvdHMpCnsKCXN0cnVjdCBjZHJvbV9pbmZvICppbmZvID0gZHJpdmUtPmRyaXZlcl9kYXRhOwoJc3RydWN0IGNkcm9tX2RldmljZV9pbmZvICpkZXZpbmZvID0gJmluZm8tPmRldmluZm87CgoJZGV2aW5mby0+b3BzID0gJmlkZV9jZHJvbV9kb3BzOwoJZGV2aW5mby0+bWFzayA9IDA7CglkZXZpbmZvLT5zcGVlZCA9IENEUk9NX1NUQVRFX0ZMQUdTKGRyaXZlKS0+Y3VycmVudF9zcGVlZDsKCWRldmluZm8tPmNhcGFjaXR5ID0gbnNsb3RzOwoJZGV2aW5mby0+aGFuZGxlID0gZHJpdmU7CglzdHJjcHkoZGV2aW5mby0+bmFtZSwgZHJpdmUtPm5hbWUpOwoJCgkvKiBzZXQgY2FwYWJpbGl0eSBtYXNrIHRvIG1hdGNoIHRoZSBwcm9iZS4gKi8KCWlmICghQ0RST01fQ09ORklHX0ZMQUdTKGRyaXZlKS0+Y2RfcikKCQlkZXZpbmZvLT5tYXNrIHw9IENEQ19DRF9SOwoJaWYgKCFDRFJPTV9DT05GSUdfRkxBR1MoZHJpdmUpLT5jZF9ydykKCQlkZXZpbmZvLT5tYXNrIHw9IENEQ19DRF9SVzsKCWlmICghQ0RST01fQ09ORklHX0ZMQUdTKGRyaXZlKS0+ZHZkKQoJCWRldmluZm8tPm1hc2sgfD0gQ0RDX0RWRDsKCWlmICghQ0RST01fQ09ORklHX0ZMQUdTKGRyaXZlKS0+ZHZkX3IpCgkJZGV2aW5mby0+bWFzayB8PSBDRENfRFZEX1I7CglpZiAoIUNEUk9NX0NPTkZJR19GTEFHUyhkcml2ZSktPmR2ZF9yYW0pCgkJZGV2aW5mby0+bWFzayB8PSBDRENfRFZEX1JBTTsKCWlmICghQ0RST01fQ09ORklHX0ZMQUdTKGRyaXZlKS0+aXNfY2hhbmdlcikKCQlkZXZpbmZvLT5tYXNrIHw9IENEQ19TRUxFQ1RfRElTQzsKCWlmICghQ0RST01fQ09ORklHX0ZMQUdTKGRyaXZlKS0+YXVkaW9fcGxheSkKCQlkZXZpbmZvLT5tYXNrIHw9IENEQ19QTEFZX0FVRElPOwoJaWYgKCFDRFJPTV9DT05GSUdfRkxBR1MoZHJpdmUpLT5jbG9zZV90cmF5KQoJCWRldmluZm8tPm1hc2sgfD0gQ0RDX0NMT1NFX1RSQVk7CglpZiAoIUNEUk9NX0NPTkZJR19GTEFHUyhkcml2ZSktPm1vX2RyaXZlKQoJCWRldmluZm8tPm1hc2sgfD0gQ0RDX01PX0RSSVZFOwoJaWYgKCFDRFJPTV9DT05GSUdfRkxBR1MoZHJpdmUpLT5yYW0pCgkJZGV2aW5mby0+bWFzayB8PSBDRENfUkFNOwoKCWRldmluZm8tPmRpc2sgPSBpbmZvLT5kaXNrOwoJcmV0dXJuIHJlZ2lzdGVyX2Nkcm9tKGRldmluZm8pOwp9CgpzdGF0aWMKaW50IGlkZV9jZHJvbV9wcm9iZV9jYXBhYmlsaXRpZXMgKGlkZV9kcml2ZV90ICpkcml2ZSkKewoJc3RydWN0IGNkcm9tX2luZm8gKmluZm8gPSBkcml2ZS0+ZHJpdmVyX2RhdGE7CglzdHJ1Y3QgY2Ryb21fZGV2aWNlX2luZm8gKmNkaSA9ICZpbmZvLT5kZXZpbmZvOwoJc3RydWN0IGF0YXBpX2NhcGFiaWxpdGllc19wYWdlIGNhcDsKCWludCBuc2xvdHMgPSAxOwoKCWlmIChkcml2ZS0+bWVkaWEgPT0gaWRlX29wdGljYWwpIHsKCQlDRFJPTV9DT05GSUdfRkxBR1MoZHJpdmUpLT5tb19kcml2ZSA9IDE7CgkJQ0RST01fQ09ORklHX0ZMQUdTKGRyaXZlKS0+cmFtID0gMTsKCQlwcmludGsoS0VSTl9FUlIgIiVzOiBBVEFQSSBtYWduZXRvLW9wdGljYWwgZHJpdmVcbiIsIGRyaXZlLT5uYW1lKTsKCQlyZXR1cm4gbnNsb3RzOwoJfQoKCWlmIChDRFJPTV9DT05GSUdfRkxBR1MoZHJpdmUpLT5uZWMyNjAgfHwKCSAgICAhc3RyY21wKGRyaXZlLT5pZC0+bW9kZWwsIlNUSU5HUkFZIDg0MjIgSURFIDhYIENELVJPTSA3LTI3LTk1IikpIHsKCQlDRFJPTV9DT05GSUdfRkxBR1MoZHJpdmUpLT5ub19lamVjdCA9IDA7CgkJQ0RST01fQ09ORklHX0ZMQUdTKGRyaXZlKS0+YXVkaW9fcGxheSA9IDE7CgkJcmV0dXJuIG5zbG90czsKCX0KCgkvKgoJICogd2UgaGF2ZSB0byBjaGVhdCBhIGxpdHRsZSBoZXJlLiB0aGUgcGFja2V0IHdpbGwgZXZlbnR1YWxseQoJICogYmUgcXVldWVkIHdpdGggaWRlX2Nkcm9tX3BhY2tldCgpLCB3aGljaCBleHRyYWN0cyB0aGUKCSAqIGRyaXZlIGZyb20gY2RpLT5oYW5kbGUuIFNpbmNlIHRoaXMgZGV2aWNlIGhhc24ndCBiZWVuCgkgKiByZWdpc3RlcmVkIHdpdGggdGhlIFVuaWZvcm0gbGF5ZXIgeWV0LCBpdCBjYW4ndCBkbyB0aGlzLgoJICogU2FtZSBnb2VzIGZvciBjZGktPm9wcy4KCSAqLwoJY2RpLT5oYW5kbGUgPSBkcml2ZTsKCWNkaS0+b3BzID0gJmlkZV9jZHJvbV9kb3BzOwoKCWlmIChpZGVfY2Ryb21fZ2V0X2NhcGFiaWxpdGllcyhkcml2ZSwgJmNhcCkpCgkJcmV0dXJuIDA7CgoJaWYgKGNhcC5sb2NrID09IDApCgkJQ0RST01fQ09ORklHX0ZMQUdTKGRyaXZlKS0+bm9fZG9vcmxvY2sgPSAxOwoJaWYgKGNhcC5lamVjdCkKCQlDRFJPTV9DT05GSUdfRkxBR1MoZHJpdmUpLT5ub19lamVjdCA9IDA7CglpZiAoY2FwLmNkX3Jfd3JpdGUpCgkJQ0RST01fQ09ORklHX0ZMQUdTKGRyaXZlKS0+Y2RfciA9IDE7CglpZiAoY2FwLmNkX3J3X3dyaXRlKSB7CgkJQ0RST01fQ09ORklHX0ZMQUdTKGRyaXZlKS0+Y2RfcncgPSAxOwoJCUNEUk9NX0NPTkZJR19GTEFHUyhkcml2ZSktPnJhbSA9IDE7Cgl9CglpZiAoY2FwLnRlc3Rfd3JpdGUpCgkJQ0RST01fQ09ORklHX0ZMQUdTKGRyaXZlKS0+dGVzdF93cml0ZSA9IDE7CglpZiAoY2FwLmR2ZF9yYW1fcmVhZCB8fCBjYXAuZHZkX3JfcmVhZCB8fCBjYXAuZHZkX3JvbSkKCQlDRFJPTV9DT05GSUdfRkxBR1MoZHJpdmUpLT5kdmQgPSAxOwoJaWYgKGNhcC5kdmRfcmFtX3dyaXRlKSB7CgkJQ0RST01fQ09ORklHX0ZMQUdTKGRyaXZlKS0+ZHZkX3JhbSA9IDE7CgkJQ0RST01fQ09ORklHX0ZMQUdTKGRyaXZlKS0+cmFtID0gMTsKCX0KCWlmIChjYXAuZHZkX3Jfd3JpdGUpCgkJQ0RST01fQ09ORklHX0ZMQUdTKGRyaXZlKS0+ZHZkX3IgPSAxOwoJaWYgKGNhcC5hdWRpb19wbGF5KQoJCUNEUk9NX0NPTkZJR19GTEFHUyhkcml2ZSktPmF1ZGlvX3BsYXkgPSAxOwoJaWYgKGNhcC5tZWNodHlwZSA9PSBtZWNodHlwZV9jYWRkeSB8fCBjYXAubWVjaHR5cGUgPT0gbWVjaHR5cGVfcG9wdXApCgkJQ0RST01fQ09ORklHX0ZMQUdTKGRyaXZlKS0+Y2xvc2VfdHJheSA9IDA7CgoJLyogU29tZSBkcml2ZXMgdXNlZCBieSBBcHBsZSBkb24ndCBhZHZlcnRpc2UgYXVkaW8gcGxheQoJICogYnV0IHRoZXkgZG8gc3VwcG9ydCByZWFkaW5nIFRPQyAmIGF1ZGlvIGRhdGFzCgkgKi8KCWlmIChzdHJjbXAoZHJpdmUtPmlkLT5tb2RlbCwgIk1BVFNISVRBRFZELVJPTSBTUi04MTg3IikgPT0gMCB8fAoJICAgIHN0cmNtcChkcml2ZS0+aWQtPm1vZGVsLCAiTUFUU0hJVEFEVkQtUk9NIFNSLTgxODYiKSA9PSAwIHx8CgkgICAgc3RyY21wKGRyaXZlLT5pZC0+bW9kZWwsICJNQVRTSElUQURWRC1ST00gU1ItODE3NiIpID09IDAgfHwKCSAgICBzdHJjbXAoZHJpdmUtPmlkLT5tb2RlbCwgIk1BVFNISVRBRFZELVJPTSBTUi04MTc0IikgPT0gMCkKCQlDRFJPTV9DT05GSUdfRkxBR1MoZHJpdmUpLT5hdWRpb19wbGF5ID0gMTsKCiNpZiAhIFNUQU5EQVJEX0FUQVBJCglpZiAoY2RpLT5zYW55b19zbG90ID4gMCkgewoJCUNEUk9NX0NPTkZJR19GTEFHUyhkcml2ZSktPmlzX2NoYW5nZXIgPSAxOwoJCW5zbG90cyA9IDM7Cgl9CgoJZWxzZQojZW5kaWYgLyogbm90IFNUQU5EQVJEX0FUQVBJICovCglpZiAoY2FwLm1lY2h0eXBlID09IG1lY2h0eXBlX2luZGl2aWR1YWxfY2hhbmdlciB8fAoJICAgIGNhcC5tZWNodHlwZSA9PSBtZWNodHlwZV9jYXJ0cmlkZ2VfY2hhbmdlcikgewoJCWlmICgobnNsb3RzID0gY2Ryb21fbnVtYmVyX29mX3Nsb3RzKGNkaSkpID4gMSkgewoJCQlDRFJPTV9DT05GSUdfRkxBR1MoZHJpdmUpLT5pc19jaGFuZ2VyID0gMTsKCQkJQ0RST01fQ09ORklHX0ZMQUdTKGRyaXZlKS0+c3VwcF9kaXNjX3ByZXNlbnQgPSAxOwoJCX0KCX0KCglpZGVfY2Ryb21fdXBkYXRlX3NwZWVkKGRyaXZlLCAmY2FwKTsKCS8qIGRvbid0IHByaW50IHNwZWVkIGlmIHRoZSBkcml2ZSByZXBvcnRlZCAwLgoJICovCglwcmludGsoS0VSTl9JTkZPICIlczogQVRBUEkiLCBkcml2ZS0+bmFtZSk7CglpZiAoQ0RST01fQ09ORklHX0ZMQUdTKGRyaXZlKS0+bWF4X3NwZWVkKQoJCXByaW50aygiICVkWCIsIENEUk9NX0NPTkZJR19GTEFHUyhkcml2ZSktPm1heF9zcGVlZCk7CglwcmludGsoIiAlcyIsIENEUk9NX0NPTkZJR19GTEFHUyhkcml2ZSktPmR2ZCA/ICJEVkQtUk9NIiA6ICJDRC1ST00iKTsKCglpZiAoQ0RST01fQ09ORklHX0ZMQUdTKGRyaXZlKS0+ZHZkX3J8Q0RST01fQ09ORklHX0ZMQUdTKGRyaXZlKS0+ZHZkX3JhbSkKICAgICAgICAJcHJpbnRrKCIgRFZEJXMlcyIsIAogICAgICAgIAkoQ0RST01fQ09ORklHX0ZMQUdTKGRyaXZlKS0+ZHZkX3IpPyAiLVIiIDogIiIsIAogICAgICAgIAkoQ0RST01fQ09ORklHX0ZMQUdTKGRyaXZlKS0+ZHZkX3JhbSk/ICItUkFNIiA6ICIiKTsKCiAgICAgICAgaWYgKENEUk9NX0NPTkZJR19GTEFHUyhkcml2ZSktPmNkX3J8Q0RST01fQ09ORklHX0ZMQUdTKGRyaXZlKS0+Y2RfcncpIAogICAgICAgIAlwcmludGsoIiBDRCVzJXMiLCAKICAgICAgICAJKENEUk9NX0NPTkZJR19GTEFHUyhkcml2ZSktPmNkX3IpPyAiLVIiIDogIiIsIAogICAgICAgIAkoQ0RST01fQ09ORklHX0ZMQUdTKGRyaXZlKS0+Y2RfcncpPyAiL1JXIiA6ICIiKTsKCiAgICAgICAgaWYgKENEUk9NX0NPTkZJR19GTEFHUyhkcml2ZSktPmlzX2NoYW5nZXIpIAogICAgICAgIAlwcmludGsoIiBjaGFuZ2VyIHcvJWQgc2xvdHMiLCBuc2xvdHMpOwogICAgICAgIGVsc2UgCQogICAgICAgIAlwcmludGsoIiBkcml2ZSIpOwoKCXByaW50aygiLCAlZGtCIENhY2hlIiwgYmUxNl90b19jcHUoY2FwLmJ1ZmZlcl9zaXplKSk7CgoJaWYgKGRyaXZlLT51c2luZ19kbWEpCgkJaWRlX2RtYV92ZXJib3NlKGRyaXZlKTsKCglwcmludGsoIlxuIik7CgoJcmV0dXJuIG5zbG90czsKfQoKc3RhdGljIHZvaWQgaWRlX2Nkcm9tX2FkZF9zZXR0aW5ncyhpZGVfZHJpdmVfdCAqZHJpdmUpCnsKCWlkZV9hZGRfc2V0dGluZyhkcml2ZSwJImRzY19vdmVybGFwIiwJCVNFVFRJTkdfUlcsIC0xLCAtMSwgVFlQRV9CWVRFLCAwLCAxLCAxLAkxLCAmZHJpdmUtPmRzY19vdmVybGFwLCBOVUxMKTsKfQoKLyoKICogc3RhbmRhcmQgcHJlcF9ycV9mbiB0aGF0IGJ1aWxkcyAxMCBieXRlIGNtZHMKICovCnN0YXRpYyBpbnQgaWRlX2Nkcm9tX3ByZXBfZnMocmVxdWVzdF9xdWV1ZV90ICpxLCBzdHJ1Y3QgcmVxdWVzdCAqcnEpCnsKCWludCBoYXJkX3NlY3QgPSBxdWV1ZV9oYXJkc2VjdF9zaXplKHEpOwoJbG9uZyBibG9jayA9IChsb25nKXJxLT5oYXJkX3NlY3RvciAvIChoYXJkX3NlY3QgPj4gOSk7Cgl1bnNpZ25lZCBsb25nIGJsb2NrcyA9IHJxLT5oYXJkX25yX3NlY3RvcnMgLyAoaGFyZF9zZWN0ID4+IDkpOwoKCW1lbXNldChycS0+Y21kLCAwLCBzaXplb2YocnEtPmNtZCkpOwoKCWlmIChycV9kYXRhX2RpcihycSkgPT0gUkVBRCkKCQlycS0+Y21kWzBdID0gR1BDTURfUkVBRF8xMDsKCWVsc2UKCQlycS0+Y21kWzBdID0gR1BDTURfV1JJVEVfMTA7CgoJLyoKCSAqIGZpbGwgaW4gbGJhCgkgKi8KCXJxLT5jbWRbMl0gPSAoYmxvY2sgPj4gMjQpICYgMHhmZjsKCXJxLT5jbWRbM10gPSAoYmxvY2sgPj4gMTYpICYgMHhmZjsKCXJxLT5jbWRbNF0gPSAoYmxvY2sgPj4gIDgpICYgMHhmZjsKCXJxLT5jbWRbNV0gPSBibG9jayAmIDB4ZmY7CgoJLyoKCSAqIGFuZCB0cmFuc2ZlciBsZW5ndGgKCSAqLwoJcnEtPmNtZFs3XSA9IChibG9ja3MgPj4gOCkgJiAweGZmOwoJcnEtPmNtZFs4XSA9IGJsb2NrcyAmIDB4ZmY7CglycS0+Y21kX2xlbiA9IDEwOwoJcmV0dXJuIEJMS1BSRVBfT0s7Cn0KCi8qCiAqIE1vc3Qgb2YgdGhlIFNDU0kgY29tbWFuZHMgYXJlIHN1cHBvcnRlZCBkaXJlY3RseSBieSBBVEFQSSBkZXZpY2VzLgogKiBUaGlzIHRyYW5zZm9ybSBoYW5kbGVzIHRoZSBmZXcgZXhjZXB0aW9ucy4KICovCnN0YXRpYyBpbnQgaWRlX2Nkcm9tX3ByZXBfcGMoc3RydWN0IHJlcXVlc3QgKnJxKQp7Cgl1OCAqYyA9IHJxLT5jbWQ7CgoJLyoKCSAqIFRyYW5zZm9ybSA2LWJ5dGUgcmVhZC93cml0ZSBjb21tYW5kcyB0byB0aGUgMTAtYnl0ZSB2ZXJzaW9uCgkgKi8KCWlmIChjWzBdID09IFJFQURfNiB8fCBjWzBdID09IFdSSVRFXzYpIHsKCQljWzhdID0gY1s0XTsKCQljWzVdID0gY1szXTsKCQljWzRdID0gY1syXTsKCQljWzNdID0gY1sxXSAmIDB4MWY7CgkJY1syXSA9IDA7CgkJY1sxXSAmPSAweGUwOwoJCWNbMF0gKz0gKFJFQURfMTAgLSBSRUFEXzYpOwoJCXJxLT5jbWRfbGVuID0gMTA7CgkJcmV0dXJuIEJMS1BSRVBfT0s7Cgl9CgoJLyoKCSAqIGl0J3Mgc2lsbHkgdG8gcHJldGVuZCB3ZSB1bmRlcnN0YW5kIDYtYnl0ZSBzZW5zZSBjb21tYW5kcywganVzdAoJICogcmVqZWN0IHdpdGggSUxMRUdBTF9SRVFVRVNUIGFuZCB0aGUgY2FsbGVyIHNob3VsZCB0YWtlIHRoZQoJICogYXBwcm9wcmlhdGUgYWN0aW9uCgkgKi8KCWlmIChjWzBdID09IE1PREVfU0VOU0UgfHwgY1swXSA9PSBNT0RFX1NFTEVDVCkgewoJCXJxLT5lcnJvcnMgPSBJTExFR0FMX1JFUVVFU1Q7CgkJcmV0dXJuIEJMS1BSRVBfS0lMTDsKCX0KCQoJcmV0dXJuIEJMS1BSRVBfT0s7Cn0KCnN0YXRpYyBpbnQgaWRlX2Nkcm9tX3ByZXBfZm4ocmVxdWVzdF9xdWV1ZV90ICpxLCBzdHJ1Y3QgcmVxdWVzdCAqcnEpCnsKCWlmIChycS0+ZmxhZ3MgJiBSRVFfQ01EKQoJCXJldHVybiBpZGVfY2Ryb21fcHJlcF9mcyhxLCBycSk7CgllbHNlIGlmIChycS0+ZmxhZ3MgJiBSRVFfQkxPQ0tfUEMpCgkJcmV0dXJuIGlkZV9jZHJvbV9wcmVwX3BjKHJxKTsKCglyZXR1cm4gMDsKfQoKc3RhdGljCmludCBpZGVfY2Ryb21fc2V0dXAgKGlkZV9kcml2ZV90ICpkcml2ZSkKewoJc3RydWN0IGNkcm9tX2luZm8gKmluZm8gPSBkcml2ZS0+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+ZHJpdmVyX2RhdGEgPSBpbmZvOwoKCWctPm1pbm9ycyA9IDE7CglzbnByaW50ZihnLT5kZXZmc19uYW1lLCBzaXplb2YoZy0+ZGV2ZnNfbmFtZSksCgkJCSIlcy9jZCIsIGRyaXZlLT5kZXZmc19uYW1lKTsKCWctPmRyaXZlcmZzX2RldiA9ICZkcml2ZS0+Z2VuZGV2OwoJZy0+ZmxhZ3MgPSBHRU5IRF9GTF9DRCB8IEdFTkhEX0ZMX1JFTU9WQUJMRTsKCWlmIChpZGVfY2Ryb21fc2V0dXAoZHJpdmUpKSB7CgkJc3RydWN0IGNkcm9tX2RldmljZV9pbmZvICpkZXZpbmZvID0gJmluZm8tPmRldmluZm87CgkJaWRlX3VucmVnaXN0ZXJfc3ViZHJpdmVyKGRyaXZlLCAmaWRlX2Nkcm9tX2RyaXZlcik7CgkJa2ZyZWUoaW5mby0+YnVmZmVyKTsKCQlrZnJlZShpbmZvLT50b2MpOwoJCWtmcmVlKGluZm8tPmNoYW5nZXJfaW5mbyk7CgkJaWYgKGRldmluZm8tPmhhbmRsZSA9PSBkcml2ZSAmJiB1bnJlZ2lzdGVyX2Nkcm9tKGRldmluZm8pKQoJCQlwcmludGsgKEtFUk5fRVJSICIlczogaWRlX2Nkcm9tX2NsZWFudXAgZmFpbGVkIHRvIHVucmVnaXN0ZXIgZGV2aWNlIGZyb20gdGhlIGNkcm9tIGRyaXZlci5cbiIsIGRyaXZlLT5uYW1lKTsKCQlrZnJlZShpbmZvKTsKCQlkcml2ZS0+ZHJpdmVyX2RhdGEgPSBOVUxMOwoJCWdvdG8gZmFpbGVkOwoJfQoKCWNkcm9tX3JlYWRfdG9jKGRyaXZlLCAmc2Vuc2UpOwoJZy0+Zm9wcyA9ICZpZGVjZF9vcHM7CglnLT5mbGFncyB8PSBHRU5IRF9GTF9SRU1PVkFCTEU7CglhZGRfZGlzayhnKTsKCXJldHVybiAwOwoKb3V0X2ZyZWVfY2Q6CglrZnJlZShpbmZvKTsKZmFpbGVkOgoJcmV0dXJuIC1FTk9ERVY7Cn0KCnN0YXRpYyB2b2lkIF9fZXhpdCBpZGVfY2Ryb21fZXhpdCh2b2lkKQp7Cglkcml2ZXJfdW5yZWdpc3RlcigmaWRlX2Nkcm9tX2RyaXZlci5nZW5fZHJpdmVyKTsKfQoKc3RhdGljIGludCBfX2luaXQgaWRlX2Nkcm9tX2luaXQodm9pZCkKewoJcmV0dXJuIGRyaXZlcl9yZWdpc3RlcigmaWRlX2Nkcm9tX2RyaXZlci5nZW5fZHJpdmVyKTsKfQoKTU9EVUxFX0FMSUFTKCJpZGU6Km0tY2Ryb20qIik7Cm1vZHVsZV9pbml0KGlkZV9jZHJvbV9pbml0KTsKbW9kdWxlX2V4aXQoaWRlX2Nkcm9tX2V4aXQpOwpNT0RVTEVfTElDRU5TRSgiR1BMIik7Cg==