LyoKICogU2VydmVyLXNpZGUgc29ja2V0IG1hbmFnZW1lbnQKICoKICogQ29weXJpZ2h0IChDKSAxOTk5IE1hcmN1cyBNZWlzc25lciwgT3ZlIEvldmVuCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IKICogbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXIKICogdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLAogKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZgogKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVQogKiBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljCiAqIExpY2Vuc2UgYWxvbmcgd2l0aCB0aGlzIGxpYnJhcnk7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUKICogRm91bmRhdGlvbiwgSW5jLiwgNTkgVGVtcGxlIFBsYWNlLCBTdWl0ZSAzMzAsIEJvc3RvbiwgTUEgIDAyMTExLTEzMDcgIFVTQQogKgogKiBGSVhNRTogd2UgdXNlIHJlYWR8d3JpdGUgYWNjZXNzIGluIGFsbCBjYXNlcy4gU2hvdWxkbid0IHdlIGRlcGVuZCB0aGF0CiAqIG9uIHRoZSBhY2Nlc3Mgb2YgdGhlIGN1cnJlbnQgaGFuZGxlPwogKi8KCiNpbmNsdWRlICJjb25maWcuaCIKCiNpbmNsdWRlIDxhc3NlcnQuaD4KI2luY2x1ZGUgPGZjbnRsLmg+CiNpbmNsdWRlIDxzdGRpby5oPgojaW5jbHVkZSA8c3RyaW5nLmg+CiNpbmNsdWRlIDxzdGRsaWIuaD4KI2luY2x1ZGUgPGVycm5vLmg+CiNpZmRlZiBIQVZFX1NZU19FUlJOT19ICiMgaW5jbHVkZSA8c3lzL2Vycm5vLmg+CiNlbmRpZgojaW5jbHVkZSA8c3lzL3RpbWUuaD4KI2luY2x1ZGUgPHN5cy90eXBlcy5oPgojaWZkZWYgSEFWRV9TWVNfU09DS0VUX0gKIyBpbmNsdWRlIDxzeXMvc29ja2V0Lmg+CiNlbmRpZgojaW5jbHVkZSA8c3lzL2lvY3RsLmg+CiNpZmRlZiBIQVZFX1NZU19GSUxJT19ICiMgaW5jbHVkZSA8c3lzL2ZpbGlvLmg+CiNlbmRpZgojaW5jbHVkZSA8dGltZS5oPgojaW5jbHVkZSA8dW5pc3RkLmg+CgojaW5jbHVkZSAid2luZXJyb3IuaCIKI2luY2x1ZGUgIndpbmJhc2UuaCIKI2luY2x1ZGUgInByb2Nlc3MuaCIKI2luY2x1ZGUgImhhbmRsZS5oIgojaW5jbHVkZSAidGhyZWFkLmgiCiNpbmNsdWRlICJyZXF1ZXN0LmgiCiNpbmNsdWRlICJ1c2VyLmgiCiNpbmNsdWRlICJhc3luYy5oIgoKLyogVG8gYXZvaWQgY29uZmxpY3RzIHdpdGggdGhlIFVuaXggc29ja2V0IGhlYWRlcnMuIFBsdXMgd2Ugb25seSBuZWVkIGEgZmV3CiAqIG1hY3JvcyBhbnl3YXkuCiAqLwojZGVmaW5lIFVTRV9XU19QUkVGSVgKI2luY2x1ZGUgIndpbnNvY2syLmgiCgpzdHJ1Y3Qgc29jawp7CiAgICBzdHJ1Y3Qgb2JqZWN0ICAgICAgIG9iajsgICAgICAgICAvKiBvYmplY3QgaGVhZGVyICovCiAgICB1bnNpZ25lZCBpbnQgICAgICAgIHN0YXRlOyAgICAgICAvKiBzdGF0dXMgYml0cyAqLwogICAgdW5zaWduZWQgaW50ICAgICAgICBtYXNrOyAgICAgICAgLyogZXZlbnQgbWFzayAqLwogICAgdW5zaWduZWQgaW50ICAgICAgICBobWFzazsgICAgICAgLyogaGVsZCAoYmxvY2tlZCkgZXZlbnRzICovCiAgICB1bnNpZ25lZCBpbnQgICAgICAgIHBtYXNrOyAgICAgICAvKiBwZW5kaW5nIGV2ZW50cyAqLwogICAgdW5zaWduZWQgaW50ICAgICAgICBmbGFnczsgICAgICAgLyogc29ja2V0IGZsYWdzICovCiAgICBzdHJ1Y3QgZXZlbnQgICAgICAgKmV2ZW50OyAgICAgICAvKiBldmVudCBvYmplY3QgKi8KICAgIHVzZXJfaGFuZGxlX3QgICAgICAgd2luZG93OyAgICAgIC8qIHdpbmRvdyB0byBzZW5kIHRoZSBtZXNzYWdlIHRvICovCiAgICB1bnNpZ25lZCBpbnQgICAgICAgIG1lc3NhZ2U7ICAgICAvKiBtZXNzYWdlIHRvIHNlbmQgKi8KICAgIHVuc2lnbmVkIGludCAgICAgICAgd3BhcmFtOyAgICAgIC8qIG1lc3NhZ2Ugd3BhcmFtIChzb2NrZXQgaGFuZGxlKSAqLwogICAgaW50ICAgICAgICAgICAgICAgICBlcnJvcnNbRkRfTUFYX0VWRU5UU107IC8qIGV2ZW50IGVycm9ycyAqLwogICAgc3RydWN0IGFzeW5jX3F1ZXVlICByZWFkX3E7ICAgICAgLyogUXVldWUgZm9yIGFzeW5jaHJvbm91cyByZWFkcyAqLwogICAgc3RydWN0IGFzeW5jX3F1ZXVlICB3cml0ZV9xOyAgICAgLyogUXVldWUgZm9yIGFzeW5jaHJvbm91cyB3cml0ZXMgKi8KfTsKCnN0YXRpYyB2b2lkIHNvY2tfZHVtcCggc3RydWN0IG9iamVjdCAqb2JqLCBpbnQgdmVyYm9zZSApOwpzdGF0aWMgaW50IHNvY2tfc2lnbmFsZWQoIHN0cnVjdCBvYmplY3QgKm9iaiwgc3RydWN0IHRocmVhZCAqdGhyZWFkICk7CnN0YXRpYyBpbnQgc29ja19nZXRfcG9sbF9ldmVudHMoIHN0cnVjdCBvYmplY3QgKm9iaiApOwpzdGF0aWMgdm9pZCBzb2NrX3BvbGxfZXZlbnQoIHN0cnVjdCBvYmplY3QgKm9iaiwgaW50IGV2ZW50ICk7CnN0YXRpYyBpbnQgc29ja19nZXRfZmQoIHN0cnVjdCBvYmplY3QgKm9iaiApOwpzdGF0aWMgaW50IHNvY2tfZ2V0X2luZm8oIHN0cnVjdCBvYmplY3QgKm9iaiwgc3RydWN0IGdldF9maWxlX2luZm9fcmVwbHkgKnJlcGx5LCBpbnQgKmZsYWdzICk7CnN0YXRpYyB2b2lkIHNvY2tfZGVzdHJveSggc3RydWN0IG9iamVjdCAqb2JqICk7CnN0YXRpYyBpbnQgc29ja19nZXRfZXJyb3IoIGludCBlcnIgKTsKc3RhdGljIHZvaWQgc29ja19zZXRfZXJyb3Iodm9pZCk7CgpzdGF0aWMgY29uc3Qgc3RydWN0IG9iamVjdF9vcHMgc29ja19vcHMgPQp7CiAgICBzaXplb2Yoc3RydWN0IHNvY2spLCAgICAgICAgICAvKiBzaXplICovCiAgICBzb2NrX2R1bXAsICAgICAgICAgICAgICAgICAgICAvKiBkdW1wICovCiAgICBhZGRfcXVldWUsICAgICAgICAgICAgICAgICAgICAvKiBhZGRfcXVldWUgKi8KICAgIHJlbW92ZV9xdWV1ZSwgICAgICAgICAgICAgICAgIC8qIHJlbW92ZV9xdWV1ZSAqLwogICAgc29ja19zaWduYWxlZCwgICAgICAgICAgICAgICAgLyogc2lnbmFsZWQgKi8KICAgIG5vX3NhdGlzZmllZCwgICAgICAgICAgICAgICAgIC8qIHNhdGlzZmllZCAqLwogICAgc29ja19nZXRfcG9sbF9ldmVudHMsICAgICAgICAgLyogZ2V0X3BvbGxfZXZlbnRzICovCiAgICBzb2NrX3BvbGxfZXZlbnQsICAgICAgICAgICAgICAvKiBwb2xsX2V2ZW50ICovCiAgICBzb2NrX2dldF9mZCwgICAgICAgICAgICAgICAgICAvKiBnZXRfZmQgKi8KICAgIG5vX2ZsdXNoLCAgICAgICAgICAgICAgICAgICAgIC8qIGZsdXNoICovCiAgICBzb2NrX2dldF9pbmZvLCAgICAgICAgICAgICAgICAvKiBnZXRfZmlsZV9pbmZvICovCiAgICBOVUxMLCAgICAgICAgICAgICAgICAgICAgICAgICAvKiBxdWV1ZV9hc3luYyAqLwogICAgc29ja19kZXN0cm95ICAgICAgICAgICAgICAgICAgLyogZGVzdHJveSAqLwp9OwoKCi8qIFBlcm11dGF0aW9uIG9mIDAuLkZEX01BWF9FVkVOVFMgLSAxIHJlcHJlc2VudGluZyB0aGUgb3JkZXIgaW4gd2hpY2gKICogd2UgcG9zdCBtZXNzYWdlcyBpZiB0aGVyZSBhcmUgbXVsdGlwbGUgZXZlbnRzLiAgVXNlZCB0byBzZW5kCiAqIG1lc3NhZ2VzLiAgVGhlIHByb2JsZW0gaXMgaWYgdGhlcmUgaXMgYm90aCBhIEZEX0NPTk5FQ1QgZXZlbnQgYW5kLAogKiBzYXksIGFuIEZEX1JFQUQgZXZlbnQgYXZhaWxhYmxlIG9uIHRoZSBzYW1lIHNvY2tldCwgd2Ugd2FudCB0bwogKiBub3RpZnkgdGhlIGFwcCBvZiB0aGUgY29ubmVjdCBldmVudCBmaXJzdC4gIE90aGVyd2lzZSBpdCBtYXkKICogZGlzY2FyZCB0aGUgcmVhZCBldmVudCBiZWNhdXNlIGl0IHRoaW5rcyBpdCBoYXNuJ3QgY29ubmVjdGVkIHlldC4KICovCnN0YXRpYyBjb25zdCBpbnQgZXZlbnRfYml0b3JkZXJbRkRfTUFYX0VWRU5UU10gPQp7CiAgICBGRF9DT05ORUNUX0JJVCwKICAgIEZEX0FDQ0VQVF9CSVQsCiAgICBGRF9PT0JfQklULAogICAgRkRfV1JJVEVfQklULAogICAgRkRfUkVBRF9CSVQsCiAgICBGRF9DTE9TRV9CSVQsCiAgICA2LCA3LCA4LCA5ICAvKiBsZWZ0b3ZlcnMgKi8KfTsKCgpzdGF0aWMgdm9pZCBzb2NrX3Jlc2VsZWN0KCBzdHJ1Y3Qgc29jayAqc29jayApCnsKICAgIGludCBldiA9IHNvY2tfZ2V0X3BvbGxfZXZlbnRzKCAmc29jay0+b2JqICk7CgogICAgaWYgKGRlYnVnX2xldmVsKQogICAgICAgIGZwcmludGYoc3RkZXJyLCJzb2NrX3Jlc2VsZWN0KCVkKTogbmV3IG1hc2sgJXhcbiIsIHNvY2stPm9iai5mZCwgZXYpOwoKICAgIGlmIChzb2NrLT5vYmouc2VsZWN0ID09IC0xKSB7CiAgICAgICAgLyogcHJldmlvdXNseSB1bmNvbm5lY3RlZCBzb2NrZXQsIGlzIHRoaXMgcmVzZWxlY3Qgc3VwcG9zZWQgdG8gY29ubmVjdCBpdD8gKi8KICAgICAgICBpZiAoIShzb2NrLT5zdGF0ZSAmIH5GRF9XSU5FX05PTkJMT0NLSU5HKSkgcmV0dXJuOwogICAgICAgIC8qIG9rLCBpdCBpcywgYXR0YWNoIGl0IHRvIHRoZSB3aW5lc2VydmVyJ3MgbWFpbiBwb2xsIGxvb3AgKi8KICAgICAgICBhZGRfc2VsZWN0X3VzZXIoICZzb2NrLT5vYmogKTsKICAgIH0KICAgIC8qIHVwZGF0ZSBjb25kaXRpb24gbWFzayAqLwogICAgc2V0X3NlbGVjdF9ldmVudHMoICZzb2NrLT5vYmosIGV2ICk7Cn0KCi8qIHdha2UgYW55Ym9keSB3YWl0aW5nIG9uIHRoZSBzb2NrZXQgZXZlbnQgb3Igc2VuZCB0aGUgYXNzb2NpYXRlZCBtZXNzYWdlICovCnN0YXRpYyB2b2lkIHNvY2tfd2FrZV91cCggc3RydWN0IHNvY2sgKnNvY2sgKQp7CiAgICB1bnNpZ25lZCBpbnQgZXZlbnRzID0gc29jay0+cG1hc2sgJiBzb2NrLT5tYXNrOwogICAgaW50IGk7CgogICAgaWYgKCFldmVudHMpIHJldHVybjsKCiAgICBpZiAoc29jay0+ZXZlbnQpCiAgICB7CiAgICAgICAgaWYgKGRlYnVnX2xldmVsKSBmcHJpbnRmKHN0ZGVyciwgInNpZ25hbGxpbmcgZXZlbnRzICV4IHB0ciAlcFxuIiwgZXZlbnRzLCBzb2NrLT5ldmVudCApOwogICAgICAgIHNldF9ldmVudCggc29jay0+ZXZlbnQgKTsKICAgIH0KICAgIGlmIChzb2NrLT53aW5kb3cpCiAgICB7CiAgICAgICAgaWYgKGRlYnVnX2xldmVsKSBmcHJpbnRmKHN0ZGVyciwgInNpZ25hbGxpbmcgZXZlbnRzICV4IHdpbiAleFxuIiwgZXZlbnRzLCBzb2NrLT53aW5kb3cgKTsKICAgICAgICBmb3IgKGkgPSAwOyBpIDwgRkRfTUFYX0VWRU5UUzsgaSsrKQogICAgICAgIHsKICAgICAgICAgICAgaW50IGV2ZW50ID0gZXZlbnRfYml0b3JkZXJbaV07CiAgICAgICAgICAgIGlmIChzb2NrLT5wbWFzayAmICgxIDw8IGV2ZW50KSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgdW5zaWduZWQgaW50IGxwYXJhbSA9ICgxIDw8IGV2ZW50KSB8IChzb2NrLT5lcnJvcnNbZXZlbnRdIDw8IDE2KTsKICAgICAgICAgICAgICAgIHBvc3RfbWVzc2FnZSggc29jay0+d2luZG93LCBzb2NrLT5tZXNzYWdlLCBzb2NrLT53cGFyYW0sIGxwYXJhbSApOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHNvY2stPnBtYXNrID0gMDsKICAgICAgICBzb2NrX3Jlc2VsZWN0KCBzb2NrICk7CiAgICB9Cn0KCmlubGluZSBzdGF0aWMgaW50IHNvY2tfZXJyb3IoaW50IHMpCnsKICAgIHVuc2lnbmVkIGludCBvcHR2YWwgPSAwLCBvcHRsZW47CiAgICAKICAgIG9wdGxlbiA9IHNpemVvZihvcHR2YWwpOwogICAgZ2V0c29ja29wdChzLCBTT0xfU09DS0VULCBTT19FUlJPUiwgKHZvaWQgKikgJm9wdHZhbCwgJm9wdGxlbik7CiAgICByZXR1cm4gb3B0dmFsID8gc29ja19nZXRfZXJyb3Iob3B0dmFsKSA6IDA7Cn0KCnN0YXRpYyB2b2lkIHNvY2tfcG9sbF9ldmVudCggc3RydWN0IG9iamVjdCAqb2JqLCBpbnQgZXZlbnQgKQp7CiAgICBzdHJ1Y3Qgc29jayAqc29jayA9IChzdHJ1Y3Qgc29jayAqKW9iajsKCiAgICBhc3NlcnQoIHNvY2stPm9iai5vcHMgPT0gJnNvY2tfb3BzICk7CiAgICBpZiAoZGVidWdfbGV2ZWwpCiAgICAgICAgZnByaW50ZihzdGRlcnIsICJzb2NrZXQgJWQgc2VsZWN0IGV2ZW50OiAleFxuIiwgc29jay0+b2JqLmZkLCBldmVudCk7CiAgICBpZiAoc29jay0+c3RhdGUgJiBGRF9DT05ORUNUKQogICAgewogICAgICAgIC8qIGNvbm5lY3RpbmcgKi8KICAgICAgICBpZiAoZXZlbnQgJiBQT0xMT1VUKQogICAgICAgIHsKICAgICAgICAgICAgLyogd2UgZ290IGNvbm5lY3RlZCAqLwogICAgICAgICAgICBzb2NrLT5zdGF0ZSB8PSBGRF9XSU5FX0NPTk5FQ1RFRHxGRF9SRUFEfEZEX1dSSVRFOwogICAgICAgICAgICBzb2NrLT5zdGF0ZSAmPSB+RkRfQ09OTkVDVDsKICAgICAgICAgICAgc29jay0+cG1hc2sgfD0gRkRfQ09OTkVDVDsKICAgICAgICAgICAgc29jay0+ZXJyb3JzW0ZEX0NPTk5FQ1RfQklUXSA9IDA7CiAgICAgICAgICAgIGlmIChkZWJ1Z19sZXZlbCkKICAgICAgICAgICAgICAgIGZwcmludGYoc3RkZXJyLCAic29ja2V0ICVkIGNvbm5lY3Rpb24gc3VjY2Vzc1xuIiwgc29jay0+b2JqLmZkKTsKICAgICAgICB9CiAgICAgICAgZWxzZSBpZiAoZXZlbnQgJiAoUE9MTEVSUnxQT0xMSFVQKSkKICAgICAgICB7CiAgICAgICAgICAgIC8qIHdlIGRpZG4ndCBnZXQgY29ubmVjdGVkPyAqLwogICAgICAgICAgICBzb2NrLT5zdGF0ZSAmPSB+RkRfQ09OTkVDVDsKICAgICAgICAgICAgc29jay0+cG1hc2sgfD0gRkRfQ09OTkVDVDsKICAgICAgICAgICAgc29jay0+ZXJyb3JzW0ZEX0NPTk5FQ1RfQklUXSA9IHNvY2tfZXJyb3IoIHNvY2stPm9iai5mZCApOwogICAgICAgICAgICBpZiAoZGVidWdfbGV2ZWwpCiAgICAgICAgICAgICAgICBmcHJpbnRmKHN0ZGVyciwgInNvY2tldCAlZCBjb25uZWN0aW9uIGZhaWx1cmVcbiIsIHNvY2stPm9iai5mZCk7CiAgICAgICAgfQogICAgfSBlbHNlCiAgICBpZiAoc29jay0+c3RhdGUgJiBGRF9XSU5FX0xJU1RFTklORykKICAgIHsKICAgICAgICAvKiBsaXN0ZW5pbmcgKi8KICAgICAgICBpZiAoZXZlbnQgJiBQT0xMSU4pCiAgICAgICAgewogICAgICAgICAgICAvKiBpbmNvbWluZyBjb25uZWN0aW9uICovCiAgICAgICAgICAgIHNvY2stPnBtYXNrIHw9IEZEX0FDQ0VQVDsKICAgICAgICAgICAgc29jay0+ZXJyb3JzW0ZEX0FDQ0VQVF9CSVRdID0gMDsKICAgICAgICAgICAgc29jay0+aG1hc2sgfD0gRkRfQUNDRVBUOwogICAgICAgIH0KICAgICAgICBlbHNlIGlmIChldmVudCAmIChQT0xMRVJSfFBPTExIVVApKQogICAgICAgIHsKICAgICAgICAgICAgLyogZmFpbGVkIGluY29taW5nIGNvbm5lY3Rpb24/ICovCiAgICAgICAgICAgIHNvY2stPnBtYXNrIHw9IEZEX0FDQ0VQVDsKICAgICAgICAgICAgc29jay0+ZXJyb3JzW0ZEX0FDQ0VQVF9CSVRdID0gc29ja19lcnJvciggc29jay0+b2JqLmZkICk7CiAgICAgICAgICAgIHNvY2stPmhtYXNrIHw9IEZEX0FDQ0VQVDsKICAgICAgICB9CiAgICB9IGVsc2UKICAgIHsKICAgICAgICAvKiBub3JtYWwgZGF0YSBmbG93ICovCiAgICAgICAgaWYgKGV2ZW50ICYgUE9MTElOKQogICAgICAgIHsKICAgICAgICAgICAgY2hhciBkdW1teTsKCiAgICAgICAgICAgIC8qIExpbnV4IDIuNCBkb2Vzbid0IHJlcG9ydCBQT0xMSFVQIGlmIG9ubHkgb25lIHNpZGUgb2YgdGhlIHNvY2tldAogICAgICAgICAgICAgKiBoYXMgYmVlbiBjbG9zZWQsIHNvIHdlIG5lZWQgdG8gY2hlY2sgZm9yIGl0IGV4cGxpY2l0bHkgaGVyZSAqLwogICAgICAgICAgICBpZiAoIXJlY3YoIHNvY2stPm9iai5mZCwgJmR1bW15LCAxLCBNU0dfUEVFSyApKSBldmVudCA9IFBPTExIVVA7CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgLyogaW5jb21pbmcgZGF0YSAqLwogICAgICAgICAgICAgICAgc29jay0+cG1hc2sgfD0gRkRfUkVBRDsKICAgICAgICAgICAgICAgIHNvY2stPmhtYXNrIHw9IEZEX1JFQUQ7CiAgICAgICAgICAgICAgICBzb2NrLT5lcnJvcnNbRkRfUkVBRF9CSVRdID0gMDsKICAgICAgICAgICAgICAgIGlmIChkZWJ1Z19sZXZlbCkKICAgICAgICAgICAgICAgICAgICBmcHJpbnRmKHN0ZGVyciwgInNvY2tldCAlZCBpcyByZWFkYWJsZVxuIiwgc29jay0+b2JqLmZkICk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgaWYgKGV2ZW50ICYgUE9MTE9VVCkKICAgICAgICB7CiAgICAgICAgICAgIHNvY2stPnBtYXNrIHw9IEZEX1dSSVRFOwogICAgICAgICAgICBzb2NrLT5obWFzayB8PSBGRF9XUklURTsKICAgICAgICAgICAgc29jay0+ZXJyb3JzW0ZEX1dSSVRFX0JJVF0gPSAwOwogICAgICAgICAgICBpZiAoZGVidWdfbGV2ZWwpCiAgICAgICAgICAgICAgICBmcHJpbnRmKHN0ZGVyciwgInNvY2tldCAlZCBpcyB3cml0YWJsZVxuIiwgc29jay0+b2JqLmZkKTsKICAgICAgICB9CiAgICAgICAgaWYgKGV2ZW50ICYgUE9MTFBSSSkKICAgICAgICB7CiAgICAgICAgICAgIHNvY2stPnBtYXNrIHw9IEZEX09PQjsKICAgICAgICAgICAgc29jay0+aG1hc2sgfD0gRkRfT09COwogICAgICAgICAgICBzb2NrLT5lcnJvcnNbRkRfT09CX0JJVF0gPSAwOwogICAgICAgICAgICBpZiAoZGVidWdfbGV2ZWwpCiAgICAgICAgICAgICAgICBmcHJpbnRmKHN0ZGVyciwgInNvY2tldCAlZCBnb3QgT09CIGRhdGFcbiIsIHNvY2stPm9iai5mZCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGV2ZW50ICYgUE9MTEVSUikgfHwgKChldmVudCAmIChQT0xMSU58UE9MTEhVUCkpID09IFBPTExIVVApKQogICAgICAgICAgICAmJiAoc29jay0+c3RhdGUgJiAoRkRfUkVBRHxGRF9XUklURSkpKSB7CiAgICAgICAgICAgIC8qIHNvY2tldCBjbG9zaW5nICovCiAgICAgICAgICAgIHNvY2stPmVycm9yc1tGRF9DTE9TRV9CSVRdID0gc29ja19lcnJvciggc29jay0+b2JqLmZkICk7CiAgICAgICAgICAgIHNvY2stPnN0YXRlICY9IH4oRkRfV0lORV9DT05ORUNURUR8RkRfUkVBRHxGRF9XUklURSk7CiAgICAgICAgICAgIHNvY2stPnBtYXNrIHw9IEZEX0NMT1NFOwogICAgICAgICAgICBpZiAoZGVidWdfbGV2ZWwpCiAgICAgICAgICAgICAgICBmcHJpbnRmKHN0ZGVyciwgInNvY2tldCAlZCBhYm9ydGVkIGJ5IGVycm9yICVkXG4iLAogICAgICAgICAgICAgICAgICAgICAgICBzb2NrLT5vYmouZmQsIHNvY2stPmVycm9yc1tGRF9DTE9TRV9CSVRdKTsKICAgICAgICB9CiAgICB9CgogICAgaWYgKGV2ZW50ICYgKFBPTExFUlJ8UE9MTEhVUCkpCiAgICAgICAgc2V0X3NlbGVjdF9ldmVudHMoICZzb2NrLT5vYmosIC0xICk7CiAgICBlbHNlCiAgICAgICAgc29ja19yZXNlbGVjdCggc29jayApOwoKICAgIC8qIHdha2UgdXAgYW55b25lIHdhaXRpbmcgZm9yIHdoYXRldmVyIGp1c3QgaGFwcGVuZWQgKi8KICAgIGlmIChzb2NrLT5wbWFzayAmIHNvY2stPm1hc2spIHNvY2tfd2FrZV91cCggc29jayApOwoKICAgIC8qIGlmIGFueW9uZSBpcyBzdHVwaWQgZW5vdWdoIHRvIHdhaXQgb24gdGhlIHNvY2tldCBvYmplY3QgaXRzZWxmLAogICAgICogbWF5YmUgd2Ugc2hvdWxkIHdha2UgdGhlbSB1cCB0b28sIGp1c3QgaW4gY2FzZT8gKi8KICAgIHdha2VfdXAoICZzb2NrLT5vYmosIDAgKTsKfQoKc3RhdGljIHZvaWQgc29ja19kdW1wKCBzdHJ1Y3Qgb2JqZWN0ICpvYmosIGludCB2ZXJib3NlICkKewogICAgc3RydWN0IHNvY2sgKnNvY2sgPSAoc3RydWN0IHNvY2sgKilvYmo7CiAgICBhc3NlcnQoIG9iai0+b3BzID09ICZzb2NrX29wcyApOwogICAgcHJpbnRmKCAiU29ja2V0IGZkPSVkLCBzdGF0ZT0leCwgbWFzaz0leCwgcGVuZGluZz0leCwgaGVsZD0leFxuIiwKICAgICAgICAgICAgc29jay0+b2JqLmZkLCBzb2NrLT5zdGF0ZSwKICAgICAgICAgICAgc29jay0+bWFzaywgc29jay0+cG1hc2ssIHNvY2stPmhtYXNrICk7Cn0KCnN0YXRpYyBpbnQgc29ja19zaWduYWxlZCggc3RydWN0IG9iamVjdCAqb2JqLCBzdHJ1Y3QgdGhyZWFkICp0aHJlYWQgKQp7CiAgICBzdHJ1Y3Qgc29jayAqc29jayA9IChzdHJ1Y3Qgc29jayAqKW9iajsKICAgIGFzc2VydCggb2JqLT5vcHMgPT0gJnNvY2tfb3BzICk7CgogICAgcmV0dXJuIGNoZWNrX3NlbGVjdF9ldmVudHMoIHNvY2stPm9iai5mZCwgc29ja19nZXRfcG9sbF9ldmVudHMoICZzb2NrLT5vYmogKSApOwp9CgpzdGF0aWMgaW50IHNvY2tfZ2V0X3BvbGxfZXZlbnRzKCBzdHJ1Y3Qgb2JqZWN0ICpvYmogKQp7CiAgICBzdHJ1Y3Qgc29jayAqc29jayA9IChzdHJ1Y3Qgc29jayAqKW9iajsKICAgIHVuc2lnbmVkIGludCBtYXNrID0gc29jay0+bWFzayAmIHNvY2stPnN0YXRlICYgfnNvY2stPmhtYXNrOwogICAgaW50IGV2ID0gMDsKCiAgICBhc3NlcnQoIG9iai0+b3BzID09ICZzb2NrX29wcyApOwoKICAgIGlmIChzb2NrLT5zdGF0ZSAmIEZEX0NPTk5FQ1QpCiAgICAgICAgLyogY29ubmVjdGluZywgd2FpdCBmb3Igd3JpdGFibGUgKi8KICAgICAgICByZXR1cm4gUE9MTE9VVDsKICAgIGlmIChzb2NrLT5zdGF0ZSAmIEZEX1dJTkVfTElTVEVOSU5HKQogICAgICAgIC8qIGxpc3RlbmluZywgd2FpdCBmb3IgcmVhZGFibGUgKi8KICAgICAgICByZXR1cm4gKHNvY2stPmhtYXNrICYgRkRfQUNDRVBUKSA/IDAgOiBQT0xMSU47CgogICAgaWYgKG1hc2sgJiBGRF9SRUFEKSAgZXYgfD0gUE9MTElOIHwgUE9MTFBSSTsKICAgIGlmIChtYXNrICYgRkRfV1JJVEUpIGV2IHw9IFBPTExPVVQ7CiAgICByZXR1cm4gZXY7Cn0KCnN0YXRpYyBpbnQgc29ja19nZXRfZmQoIHN0cnVjdCBvYmplY3QgKm9iaiApCnsKICAgIHN0cnVjdCBzb2NrICpzb2NrID0gKHN0cnVjdCBzb2NrICopb2JqOwogICAgYXNzZXJ0KCBvYmotPm9wcyA9PSAmc29ja19vcHMgKTsKICAgIHJldHVybiBzb2NrLT5vYmouZmQ7Cn0KCnN0YXRpYyBpbnQgc29ja19nZXRfaW5mbyggc3RydWN0IG9iamVjdCAqb2JqLCBzdHJ1Y3QgZ2V0X2ZpbGVfaW5mb19yZXBseSAqcmVwbHksIGludCAqZmxhZ3MgKQp7CiAgICBzdHJ1Y3Qgc29jayAqc29jayA9IChzdHJ1Y3Qgc29jayopIG9iajsKICAgIGFzc2VydCAoIG9iai0+b3BzID09ICZzb2NrX29wcyApOwoKICAgIGlmIChyZXBseSkKICAgIHsKICAgICAgICByZXBseS0+dHlwZSAgICAgICAgPSBGSUxFX1RZUEVfUElQRTsKICAgICAgICByZXBseS0+YXR0ciAgICAgICAgPSAwOwogICAgICAgIHJlcGx5LT5hY2Nlc3NfdGltZSA9IDA7CiAgICAgICAgcmVwbHktPndyaXRlX3RpbWUgID0gMDsKICAgICAgICByZXBseS0+c2l6ZV9oaWdoICAgPSAwOwogICAgICAgIHJlcGx5LT5zaXplX2xvdyAgICA9IDA7CiAgICAgICAgcmVwbHktPmxpbmtzICAgICAgID0gMDsKICAgICAgICByZXBseS0+aW5kZXhfaGlnaCAgPSAwOwogICAgICAgIHJlcGx5LT5pbmRleF9sb3cgICA9IDA7CiAgICAgICAgcmVwbHktPnNlcmlhbCAgICAgID0gMDsKICAgIH0KICAgICpmbGFncyA9IDA7CiAgICBpZiAoc29jay0+ZmxhZ3MgJiBXU0FfRkxBR19PVkVSTEFQUEVEKSAqZmxhZ3MgfD0gRkRfRkxBR19PVkVSTEFQUEVEOwogICAgcmV0dXJuIEZEX1RZUEVfREVGQVVMVDsKfQoKc3RhdGljIHZvaWQgc29ja19kZXN0cm95KCBzdHJ1Y3Qgb2JqZWN0ICpvYmogKQp7CiAgICBzdHJ1Y3Qgc29jayAqc29jayA9IChzdHJ1Y3Qgc29jayAqKW9iajsKICAgIGFzc2VydCggb2JqLT5vcHMgPT0gJnNvY2tfb3BzICk7CgogICAgLyogRklYTUU6IHNwZWNpYWwgc29ja2V0IHNodXRkb3duIHN0dWZmPyAqLwoKICAgIGlmICggc29jay0+ZmxhZ3MgJiBXU0FfRkxBR19PVkVSTEFQUEVEICkKICAgIHsKICAgICAgICBkZXN0cm95X2FzeW5jX3F1ZXVlICggJnNvY2stPnJlYWRfcSApOwogICAgICAgIGRlc3Ryb3lfYXN5bmNfcXVldWUgKCAmc29jay0+d3JpdGVfcSApOwogICAgfQogICAgaWYgKHNvY2stPmV2ZW50KSByZWxlYXNlX29iamVjdCggc29jay0+ZXZlbnQgKTsKfQoKLyogY3JlYXRlIGEgbmV3IGFuZCB1bmNvbm5lY3RlZCBzb2NrZXQgKi8Kc3RhdGljIHN0cnVjdCBvYmplY3QgKmNyZWF0ZV9zb2NrZXQoIGludCBmYW1pbHksIGludCB0eXBlLCBpbnQgcHJvdG9jb2wsIHVuc2lnbmVkIGludCBmbGFncyApCnsKICAgIHN0cnVjdCBzb2NrICpzb2NrOwogICAgaW50IHNvY2tmZDsKCiAgICBzb2NrZmQgPSBzb2NrZXQoIGZhbWlseSwgdHlwZSwgcHJvdG9jb2wgKTsKICAgIGlmIChkZWJ1Z19sZXZlbCkKICAgICAgICBmcHJpbnRmKHN0ZGVyciwic29ja2V0KCVkLCVkLCVkKT0lZFxuIixmYW1pbHksdHlwZSxwcm90b2NvbCxzb2NrZmQpOwogICAgaWYgKHNvY2tmZCA9PSAtMSkgewogICAgICAgIHNvY2tfc2V0X2Vycm9yKCk7CiAgICAgICAgcmV0dXJuIE5VTEw7CiAgICB9CiAgICBmY250bChzb2NrZmQsIEZfU0VURkwsIE9fTk9OQkxPQ0spOyAvKiBtYWtlIHNvY2tldCBub25ibG9ja2luZyAqLwogICAgaWYgKCEoc29jayA9IGFsbG9jX29iamVjdCggJnNvY2tfb3BzLCAtMSApKSkgcmV0dXJuIE5VTEw7CiAgICBzb2NrLT5vYmouZmQgPSBzb2NrZmQ7CiAgICBzb2NrLT5zdGF0ZSA9ICh0eXBlICE9IFNPQ0tfU1RSRUFNKSA/IChGRF9SRUFEfEZEX1dSSVRFKSA6IDA7CiAgICBzb2NrLT5tYXNrICAgID0gMDsKICAgIHNvY2stPmhtYXNrICAgPSAwOwogICAgc29jay0+cG1hc2sgICA9IDA7CiAgICBzb2NrLT5mbGFncyAgID0gZmxhZ3M7CiAgICBzb2NrLT5ldmVudCAgID0gTlVMTDsKICAgIHNvY2stPndpbmRvdyAgPSAwOwogICAgc29jay0+bWVzc2FnZSA9IDA7CiAgICBzb2NrLT53cGFyYW0gID0gMDsKICAgIHNvY2tfcmVzZWxlY3QoIHNvY2sgKTsKICAgIGNsZWFyX2Vycm9yKCk7CiAgICBpZiAoc29jay0+ZmxhZ3MgJiBXU0FfRkxBR19PVkVSTEFQUEVEKQogICAgewogICAgICAgIGluaXRfYXN5bmNfcXVldWUgKCZzb2NrLT5yZWFkX3EpOwogICAgICAgIGluaXRfYXN5bmNfcXVldWUgKCZzb2NrLT53cml0ZV9xKTsKICAgIH0KICAgIHJldHVybiAmc29jay0+b2JqOwp9CgovKiBhY2NlcHQgYSBzb2NrZXQgKGNyZWF0ZXMgYSBuZXcgZmQpICovCnN0YXRpYyBzdHJ1Y3Qgc29jayAqYWNjZXB0X3NvY2tldCggaGFuZGxlX3QgaGFuZGxlICkKewogICAgc3RydWN0IHNvY2sgKmFjY2VwdHNvY2s7CiAgICBzdHJ1Y3Qgc29jayAqc29jazsKICAgIGludAlhY2NlcHRmZDsKICAgIHN0cnVjdCBzb2NrYWRkcglzYWRkcjsKICAgIGludAkJCXNsZW47CgogICAgc29jaz0oc3RydWN0IHNvY2sqKWdldF9oYW5kbGVfb2JqKGN1cnJlbnQtPnByb2Nlc3MsaGFuZGxlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEdFTkVSSUNfUkVBRHxHRU5FUklDX1dSSVRFfFNZTkNIUk9OSVpFLCZzb2NrX29wcyk7CiAgICBpZiAoIXNvY2spCiAgICAJcmV0dXJuIE5VTEw7CiAgICAvKiBUcnkgdG8gYWNjZXB0KDIpLiBXZSBjYW4ndCBiZSBzYWZlIHRoYXQgdGhpcyBhbiBhbHJlYWR5IGNvbm5lY3RlZCBzb2NrZXQgCiAgICAgKiBvciB0aGF0IGFjY2VwdCgpIGlzIGFsbG93ZWQgb24gaXQuIEluIHRob3NlIGNhc2VzIHdlIHdpbGwgZ2V0IC0xL2Vycm5vCiAgICAgKiByZXR1cm4uCiAgICAgKi8KICAgIHNsZW4gPSBzaXplb2Yoc2FkZHIpOwogICAgYWNjZXB0ZmQgPSBhY2NlcHQoc29jay0+b2JqLmZkLCZzYWRkciwmc2xlbik7CiAgICBpZiAoYWNjZXB0ZmQ9PS0xKSB7CiAgICAJc29ja19zZXRfZXJyb3IoKTsKICAgICAgICByZWxlYXNlX29iamVjdCggc29jayApOwoJcmV0dXJuIE5VTEw7CiAgICB9CiAgICBpZiAoIShhY2NlcHRzb2NrID0gYWxsb2Nfb2JqZWN0KCAmc29ja19vcHMsIC0xICkpKQogICAgewogICAgICAgIHJlbGVhc2Vfb2JqZWN0KCBzb2NrICk7CiAgICAgICAgcmV0dXJuIE5VTEw7CiAgICB9CgogICAgLyogbmV3bHkgY3JlYXRlZCBzb2NrZXQgZ2V0cyB0aGUgc2FtZSBwcm9wZXJ0aWVzIG9mIHRoZSBsaXN0ZW5pbmcgc29ja2V0ICovCiAgICBmY250bChhY2NlcHRmZCwgRl9TRVRGTCwgT19OT05CTE9DSyk7IC8qIG1ha2Ugc29ja2V0IG5vbmJsb2NraW5nICovCiAgICBhY2NlcHRzb2NrLT5vYmouZmQgPSBhY2NlcHRmZDsKICAgIGFjY2VwdHNvY2stPnN0YXRlICA9IEZEX1dJTkVfQ09OTkVDVEVEfEZEX1JFQUR8RkRfV1JJVEU7CiAgICBpZiAoc29jay0+c3RhdGUgJiBGRF9XSU5FX05PTkJMT0NLSU5HKQogICAgICAgIGFjY2VwdHNvY2stPnN0YXRlIHw9IEZEX1dJTkVfTk9OQkxPQ0tJTkc7CiAgICBhY2NlcHRzb2NrLT5tYXNrICAgID0gc29jay0+bWFzazsKICAgIGFjY2VwdHNvY2stPmhtYXNrICAgPSAwOwogICAgYWNjZXB0c29jay0+cG1hc2sgICA9IDA7CiAgICBhY2NlcHRzb2NrLT5ldmVudCAgID0gTlVMTDsKICAgIGFjY2VwdHNvY2stPndpbmRvdyAgPSBzb2NrLT53aW5kb3c7CiAgICBhY2NlcHRzb2NrLT5tZXNzYWdlID0gc29jay0+bWVzc2FnZTsKICAgIGFjY2VwdHNvY2stPndwYXJhbSAgPSAwOwogICAgaWYgKHNvY2stPmV2ZW50KSBhY2NlcHRzb2NrLT5ldmVudCA9IChzdHJ1Y3QgZXZlbnQgKilncmFiX29iamVjdCggc29jay0+ZXZlbnQgKTsKICAgIGFjY2VwdHNvY2stPmZsYWdzID0gc29jay0+ZmxhZ3M7CiAgICBpZiAoIGFjY2VwdHNvY2stPmZsYWdzICYgV1NBX0ZMQUdfT1ZFUkxBUFBFRCApCiAgICB7Cglpbml0X2FzeW5jX3F1ZXVlICggJmFjY2VwdHNvY2stPnJlYWRfcSApOwoJaW5pdF9hc3luY19xdWV1ZSAoICZhY2NlcHRzb2NrLT53cml0ZV9xICk7CiAgICB9CgogICAgY2xlYXJfZXJyb3IoKTsKICAgIHNvY2stPnBtYXNrICY9IH5GRF9BQ0NFUFQ7CiAgICBzb2NrLT5obWFzayAmPSB+RkRfQUNDRVBUOwogICAgc29ja19yZXNlbGVjdCggc29jayApOwogICAgcmVsZWFzZV9vYmplY3QoIHNvY2sgKTsKICAgIHJldHVybiBhY2NlcHRzb2NrOwp9CgovKiBzZXQgdGhlIGxhc3QgZXJyb3IgZGVwZW5kaW5nIG9uIGVycm5vICovCnN0YXRpYyBpbnQgc29ja19nZXRfZXJyb3IoIGludCBlcnIgKQp7CiAgICBzd2l0Y2ggKGVycikKICAgIHsKICAgICAgICBjYXNlIEVJTlRSOiAgICAgICAgICAgICByZXR1cm4gV1NBRUlOVFI7IGJyZWFrOwogICAgICAgIGNhc2UgRUJBREY6ICAgICAgICAgICAgIHJldHVybiBXU0FFQkFERjsgYnJlYWs7CiAgICAgICAgY2FzZSBFUEVSTToKICAgICAgICBjYXNlIEVBQ0NFUzogICAgICAgICAgICByZXR1cm4gV1NBRUFDQ0VTOyBicmVhazsKICAgICAgICBjYXNlIEVGQVVMVDogICAgICAgICAgICByZXR1cm4gV1NBRUZBVUxUOyBicmVhazsKICAgICAgICBjYXNlIEVJTlZBTDogICAgICAgICAgICByZXR1cm4gV1NBRUlOVkFMOyBicmVhazsKICAgICAgICBjYXNlIEVNRklMRTogICAgICAgICAgICByZXR1cm4gV1NBRU1GSUxFOyBicmVhazsKICAgICAgICBjYXNlIEVXT1VMREJMT0NLOiAgICAgICByZXR1cm4gV1NBRVdPVUxEQkxPQ0s7IGJyZWFrOwogICAgICAgIGNhc2UgRUlOUFJPR1JFU1M6ICAgICAgIHJldHVybiBXU0FFSU5QUk9HUkVTUzsgYnJlYWs7CiAgICAgICAgY2FzZSBFQUxSRUFEWTogICAgICAgICAgcmV0dXJuIFdTQUVBTFJFQURZOyBicmVhazsKICAgICAgICBjYXNlIEVOT1RTT0NLOiAgICAgICAgICByZXR1cm4gV1NBRU5PVFNPQ0s7IGJyZWFrOwogICAgICAgIGNhc2UgRURFU1RBRERSUkVROiAgICAgIHJldHVybiBXU0FFREVTVEFERFJSRVE7IGJyZWFrOwogICAgICAgIGNhc2UgRU1TR1NJWkU6ICAgICAgICAgIHJldHVybiBXU0FFTVNHU0laRTsgYnJlYWs7CiAgICAgICAgY2FzZSBFUFJPVE9UWVBFOiAgICAgICAgcmV0dXJuIFdTQUVQUk9UT1RZUEU7IGJyZWFrOwogICAgICAgIGNhc2UgRU5PUFJPVE9PUFQ6ICAgICAgIHJldHVybiBXU0FFTk9QUk9UT09QVDsgYnJlYWs7CiAgICAgICAgY2FzZSBFUFJPVE9OT1NVUFBPUlQ6ICAgcmV0dXJuIFdTQUVQUk9UT05PU1VQUE9SVDsgYnJlYWs7CiAgICAgICAgY2FzZSBFU09DS1ROT1NVUFBPUlQ6ICAgcmV0dXJuIFdTQUVTT0NLVE5PU1VQUE9SVDsgYnJlYWs7CiAgICAgICAgY2FzZSBFT1BOT1RTVVBQOiAgICAgICAgcmV0dXJuIFdTQUVPUE5PVFNVUFA7IGJyZWFrOwogICAgICAgIGNhc2UgRVBGTk9TVVBQT1JUOiAgICAgIHJldHVybiBXU0FFUEZOT1NVUFBPUlQ7IGJyZWFrOwogICAgICAgIGNhc2UgRUFGTk9TVVBQT1JUOiAgICAgIHJldHVybiBXU0FFQUZOT1NVUFBPUlQ7IGJyZWFrOwogICAgICAgIGNhc2UgRUFERFJJTlVTRTogICAgICAgIHJldHVybiBXU0FFQUREUklOVVNFOyBicmVhazsKICAgICAgICBjYXNlIEVBRERSTk9UQVZBSUw6ICAgICByZXR1cm4gV1NBRUFERFJOT1RBVkFJTDsgYnJlYWs7CiAgICAgICAgY2FzZSBFTkVURE9XTjogICAgICAgICAgcmV0dXJuIFdTQUVORVRET1dOOyBicmVhazsKICAgICAgICBjYXNlIEVORVRVTlJFQUNIOiAgICAgICByZXR1cm4gV1NBRU5FVFVOUkVBQ0g7IGJyZWFrOwogICAgICAgIGNhc2UgRU5FVFJFU0VUOiAgICAgICAgIHJldHVybiBXU0FFTkVUUkVTRVQ7IGJyZWFrOwogICAgICAgIGNhc2UgRUNPTk5BQk9SVEVEOiAgICAgIHJldHVybiBXU0FFQ09OTkFCT1JURUQ7IGJyZWFrOwogICAgICAgIGNhc2UgRVBJUEU6CiAgICAgICAgY2FzZSBFQ09OTlJFU0VUOiAgICAgICAgcmV0dXJuIFdTQUVDT05OUkVTRVQ7IGJyZWFrOwogICAgICAgIGNhc2UgRU5PQlVGUzogICAgICAgICAgIHJldHVybiBXU0FFTk9CVUZTOyBicmVhazsKICAgICAgICBjYXNlIEVJU0NPTk46ICAgICAgICAgICByZXR1cm4gV1NBRUlTQ09OTjsgYnJlYWs7CiAgICAgICAgY2FzZSBFTk9UQ09OTjogICAgICAgICAgcmV0dXJuIFdTQUVOT1RDT05OOyBicmVhazsKICAgICAgICBjYXNlIEVTSFVURE9XTjogICAgICAgICByZXR1cm4gV1NBRVNIVVRET1dOOyBicmVhazsKICAgICAgICBjYXNlIEVUT09NQU5ZUkVGUzogICAgICByZXR1cm4gV1NBRVRPT01BTllSRUZTOyBicmVhazsKICAgICAgICBjYXNlIEVUSU1FRE9VVDogICAgICAgICByZXR1cm4gV1NBRVRJTUVET1VUOyBicmVhazsKICAgICAgICBjYXNlIEVDT05OUkVGVVNFRDogICAgICByZXR1cm4gV1NBRUNPTk5SRUZVU0VEOyBicmVhazsKICAgICAgICBjYXNlIEVMT09QOiAgICAgICAgICAgICByZXR1cm4gV1NBRUxPT1A7IGJyZWFrOwogICAgICAgIGNhc2UgRU5BTUVUT09MT05HOiAgICAgIHJldHVybiBXU0FFTkFNRVRPT0xPTkc7IGJyZWFrOwogICAgICAgIGNhc2UgRUhPU1RET1dOOiAgICAgICAgIHJldHVybiBXU0FFSE9TVERPV047IGJyZWFrOwogICAgICAgIGNhc2UgRUhPU1RVTlJFQUNIOiAgICAgIHJldHVybiBXU0FFSE9TVFVOUkVBQ0g7IGJyZWFrOwogICAgICAgIGNhc2UgRU5PVEVNUFRZOiAgICAgICAgIHJldHVybiBXU0FFTk9URU1QVFk7IGJyZWFrOwojaWZkZWYgRVBST0NMSU0KICAgICAgICBjYXNlIEVQUk9DTElNOiAgICAgICAgICByZXR1cm4gV1NBRVBST0NMSU07IGJyZWFrOwojZW5kaWYKI2lmZGVmIEVVU0VSUwogICAgICAgIGNhc2UgRVVTRVJTOiAgICAgICAgICAgIHJldHVybiBXU0FFVVNFUlM7IGJyZWFrOwojZW5kaWYKI2lmZGVmIEVEUVVPVAogICAgICAgIGNhc2UgRURRVU9UOiAgICAgICAgICAgIHJldHVybiBXU0FFRFFVT1Q7IGJyZWFrOwojZW5kaWYKI2lmZGVmIEVTVEFMRQogICAgICAgIGNhc2UgRVNUQUxFOiAgICAgICAgICAgIHJldHVybiBXU0FFU1RBTEU7IGJyZWFrOwojZW5kaWYKI2lmZGVmIEVSRU1PVEUKICAgICAgICBjYXNlIEVSRU1PVEU6ICAgICAgICAgICByZXR1cm4gV1NBRVJFTU9URTsgYnJlYWs7CiNlbmRpZgogICAgZGVmYXVsdDogZXJybm89ZXJyOyBwZXJyb3IoInNvY2tfc2V0X2Vycm9yIik7IHJldHVybiBFUlJPUl9VTktOT1dOOyBicmVhazsKICAgIH0KfQoKLyogc2V0IHRoZSBsYXN0IGVycm9yIGRlcGVuZGluZyBvbiBlcnJubyAqLwpzdGF0aWMgdm9pZCBzb2NrX3NldF9lcnJvcih2b2lkKQp7CiAgICBzZXRfZXJyb3IoIHNvY2tfZ2V0X2Vycm9yKCBlcnJubyApICk7Cn0KCi8qIGNyZWF0ZSBhIHNvY2tldCAqLwpERUNMX0hBTkRMRVIoY3JlYXRlX3NvY2tldCkKewogICAgc3RydWN0IG9iamVjdCAqb2JqOwoKICAgIHJlcGx5LT5oYW5kbGUgPSAwOwogICAgaWYgKChvYmogPSBjcmVhdGVfc29ja2V0KCByZXEtPmZhbWlseSwgcmVxLT50eXBlLCByZXEtPnByb3RvY29sLCByZXEtPmZsYWdzICkpICE9IE5VTEwpCiAgICB7CiAgICAgICAgcmVwbHktPmhhbmRsZSA9IGFsbG9jX2hhbmRsZSggY3VycmVudC0+cHJvY2Vzcywgb2JqLCByZXEtPmFjY2VzcywgcmVxLT5pbmhlcml0ICk7CiAgICAgICAgcmVsZWFzZV9vYmplY3QoIG9iaiApOwogICAgfQp9CgovKiBhY2NlcHQgYSBzb2NrZXQgKi8KREVDTF9IQU5ETEVSKGFjY2VwdF9zb2NrZXQpCnsKICAgIHN0cnVjdCBzb2NrICpzb2NrOwoKICAgIHJlcGx5LT5oYW5kbGUgPSAwOwogICAgaWYgKChzb2NrID0gYWNjZXB0X3NvY2tldCggcmVxLT5saGFuZGxlICkpICE9IE5VTEwpCiAgICB7CiAgICAgICAgcmVwbHktPmhhbmRsZSA9IGFsbG9jX2hhbmRsZSggY3VycmVudC0+cHJvY2VzcywgJnNvY2stPm9iaiwgcmVxLT5hY2Nlc3MsIHJlcS0+aW5oZXJpdCApOwogICAgICAgIHNvY2stPndwYXJhbSA9IHJlcGx5LT5oYW5kbGU7ICAvKiB3cGFyYW0gZm9yIG1lc3NhZ2UgaXMgdGhlIHNvY2tldCBoYW5kbGUgKi8KICAgICAgICBzb2NrX3Jlc2VsZWN0KCBzb2NrICk7CiAgICAgICAgcmVsZWFzZV9vYmplY3QoICZzb2NrLT5vYmogKTsKICAgIH0KfQoKLyogc2V0IHNvY2tldCBldmVudCBwYXJhbWV0ZXJzICovCkRFQ0xfSEFORExFUihzZXRfc29ja2V0X2V2ZW50KQp7CiAgICBzdHJ1Y3Qgc29jayAqc29jazsKICAgIHN0cnVjdCBldmVudCAqb2xkX2V2ZW50OwoKICAgIGlmICghKHNvY2sgPSAoc3RydWN0IHNvY2sqKWdldF9oYW5kbGVfb2JqKCBjdXJyZW50LT5wcm9jZXNzLCByZXEtPmhhbmRsZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBHRU5FUklDX1JFQUR8R0VORVJJQ19XUklURXxTWU5DSFJPTklaRSwgJnNvY2tfb3BzKSkpCiAgICAgICAgcmV0dXJuOwogICAgb2xkX2V2ZW50ID0gc29jay0+ZXZlbnQ7CiAgICBzb2NrLT5tYXNrICAgID0gcmVxLT5tYXNrOwogICAgc29jay0+ZXZlbnQgICA9IE5VTEw7CiAgICBzb2NrLT53aW5kb3cgID0gcmVxLT53aW5kb3c7CiAgICBzb2NrLT5tZXNzYWdlID0gcmVxLT5tc2c7CiAgICBzb2NrLT53cGFyYW0gID0gcmVxLT5oYW5kbGU7ICAvKiB3cGFyYW0gaXMgdGhlIHNvY2tldCBoYW5kbGUgKi8KICAgIGlmIChyZXEtPmV2ZW50KSBzb2NrLT5ldmVudCA9IGdldF9ldmVudF9vYmooIGN1cnJlbnQtPnByb2Nlc3MsIHJlcS0+ZXZlbnQsIEVWRU5UX01PRElGWV9TVEFURSApOwoKICAgIGlmIChkZWJ1Z19sZXZlbCAmJiBzb2NrLT5ldmVudCkgZnByaW50ZihzdGRlcnIsICJldmVudCBwdHI6ICVwXG4iLCBzb2NrLT5ldmVudCk7CiAgICBzb2NrX3Jlc2VsZWN0KCBzb2NrICk7CiAgICBpZiAoc29jay0+bWFzaykKICAgICAgICBzb2NrLT5zdGF0ZSB8PSBGRF9XSU5FX05PTkJMT0NLSU5HOwoKICAgIC8qIGlmIGEgbmV0d29yayBldmVudCBpcyBwZW5kaW5nLCBzaWduYWwgdGhlIGV2ZW50IG9iamVjdCAKICAgICAgIGl0IGlzIHBvc3NpYmxlIHRoYXQgRkRfQ09OTkVDVCBvciBGRF9BQ0NFUFQgbmV0d29yayBldmVudHMgaGFzIGhhcHBlbmVkCiAgICAgICBiZWZvcmUgYSBXU0FFdmVudFNlbGVjdCgpIHdhcyBkb25lIG9uIGl0LiAKICAgICAgICh3aGVuIGRlYWxpbmcgd2l0aCBBc3luY2hyb25vdXMgc29ja2V0KSAgKi8KICAgIGlmIChzb2NrLT5wbWFzayAmIHNvY2stPm1hc2spIHNvY2tfd2FrZV91cCggc29jayApOwoKICAgIGlmIChvbGRfZXZlbnQpIHJlbGVhc2Vfb2JqZWN0KCBvbGRfZXZlbnQgKTsgLyogd2UncmUgdGhyb3VnaCB3aXRoIGl0ICovCiAgICByZWxlYXNlX29iamVjdCggJnNvY2stPm9iaiApOwp9CgovKiBnZXQgc29ja2V0IGV2ZW50IHBhcmFtZXRlcnMgKi8KREVDTF9IQU5ETEVSKGdldF9zb2NrZXRfZXZlbnQpCnsKICAgIHN0cnVjdCBzb2NrICpzb2NrOwoKICAgIHNvY2s9KHN0cnVjdCBzb2NrKilnZXRfaGFuZGxlX29iaihjdXJyZW50LT5wcm9jZXNzLHJlcS0+aGFuZGxlLEdFTkVSSUNfUkVBRHxHRU5FUklDX1dSSVRFfFNZTkNIUk9OSVpFLCZzb2NrX29wcyk7CiAgICBpZiAoIXNvY2spCiAgICB7CiAgICAgICAgcmVwbHktPm1hc2sgID0gMDsKICAgICAgICByZXBseS0+cG1hc2sgPSAwOwogICAgICAgIHJlcGx5LT5zdGF0ZSA9IDA7CiAgICAgICAgc2V0X2Vycm9yKCBXU0FFTk9UU09DSyApOwogICAgICAgIHJldHVybjsKICAgIH0KICAgIHJlcGx5LT5tYXNrICA9IHNvY2stPm1hc2s7CiAgICByZXBseS0+cG1hc2sgPSBzb2NrLT5wbWFzazsKICAgIHJlcGx5LT5zdGF0ZSA9IHNvY2stPnN0YXRlOwogICAgc2V0X3JlcGx5X2RhdGEoIHNvY2stPmVycm9ycywgbWluKCBnZXRfcmVwbHlfbWF4X3NpemUoKSwgc2l6ZW9mKHNvY2stPmVycm9ycykgKSk7CgogICAgaWYgKHJlcS0+c2VydmljZSkKICAgIHsKICAgICAgICBpZiAocmVxLT5jX2V2ZW50KQogICAgICAgIHsKICAgICAgICAgICAgc3RydWN0IGV2ZW50ICpjZXZlbnQgPSBnZXRfZXZlbnRfb2JqKCBjdXJyZW50LT5wcm9jZXNzLCByZXEtPmNfZXZlbnQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRVZFTlRfTU9ESUZZX1NUQVRFICk7CiAgICAgICAgICAgIGlmIChjZXZlbnQpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHJlc2V0X2V2ZW50KCBjZXZlbnQgKTsKICAgICAgICAgICAgICAgIHJlbGVhc2Vfb2JqZWN0KCBjZXZlbnQgKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBzb2NrLT5wbWFzayA9IDA7CiAgICAgICAgc29ja19yZXNlbGVjdCggc29jayApOwogICAgfQogICAgcmVsZWFzZV9vYmplY3QoICZzb2NrLT5vYmogKTsKfQoKLyogcmUtZW5hYmxlIHBlbmRpbmcgc29ja2V0IGV2ZW50cyAqLwpERUNMX0hBTkRMRVIoZW5hYmxlX3NvY2tldF9ldmVudCkKewogICAgc3RydWN0IHNvY2sgKnNvY2s7CgogICAgaWYgKCEoc29jayA9IChzdHJ1Y3Qgc29jayopZ2V0X2hhbmRsZV9vYmooIGN1cnJlbnQtPnByb2Nlc3MsIHJlcS0+aGFuZGxlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEdFTkVSSUNfUkVBRHxHRU5FUklDX1dSSVRFfFNZTkNIUk9OSVpFLCAmc29ja19vcHMpKSkKICAgICAgICByZXR1cm47CgogICAgc29jay0+cG1hc2sgJj0gfnJlcS0+bWFzazsgLyogaXMgdGhpcyBzYWZlPyAqLwogICAgc29jay0+aG1hc2sgJj0gfnJlcS0+bWFzazsKICAgIHNvY2stPnN0YXRlIHw9IHJlcS0+c3N0YXRlOwogICAgc29jay0+c3RhdGUgJj0gfnJlcS0+Y3N0YXRlOwogICAgc29ja19yZXNlbGVjdCggc29jayApOwogICAgcmVsZWFzZV9vYmplY3QoICZzb2NrLT5vYmogKTsKfQo=