LyoKICogU2VydmVyLXNpZGUgc29ja2V0IG1hbmFnZW1lbnQKICoKICogQ29weXJpZ2h0IChDKSAxOTk5IE1hcmN1cyBNZWlzc25lciwgT3ZlIEvldmVuCiAqCiAqIEZJWE1FOiB3ZSB1c2UgcmVhZHx3cml0ZSBhY2Nlc3MgaW4gYWxsIGNhc2VzLiBTaG91bGRuJ3Qgd2UgZGVwZW5kIHRoYXQKICogb24gdGhlIGFjY2VzcyBvZiB0aGUgY3VycmVudCBoYW5kbGU/CiAqLwoKI2luY2x1ZGUgImNvbmZpZy5oIgoKI2luY2x1ZGUgPGFzc2VydC5oPgojaW5jbHVkZSA8ZmNudGwuaD4KI2luY2x1ZGUgPHN0ZGlvLmg+CiNpbmNsdWRlIDxzdHJpbmcuaD4KI2luY2x1ZGUgPHN0ZGxpYi5oPgojaW5jbHVkZSA8ZXJybm8uaD4KI2lmZGVmIEhBVkVfU1lTX0VSUk5PX0gKIyBpbmNsdWRlIDxzeXMvZXJybm8uaD4KI2VuZGlmCiNpbmNsdWRlIDxzeXMvdGltZS5oPgojaW5jbHVkZSA8c3lzL3R5cGVzLmg+CiNpZmRlZiBIQVZFX1NZU19TT0NLRVRfSAojIGluY2x1ZGUgPHN5cy9zb2NrZXQuaD4KI2VuZGlmCiNpbmNsdWRlIDxzeXMvaW9jdGwuaD4KI2lmZGVmIEhBVkVfU1lTX0ZJTElPX0gKIyBpbmNsdWRlIDxzeXMvZmlsaW8uaD4KI2VuZGlmCiNpbmNsdWRlIDx0aW1lLmg+CiNpbmNsdWRlIDx1bmlzdGQuaD4KCiNpbmNsdWRlICJ3aW5lcnJvci5oIgojaW5jbHVkZSAid2luYmFzZS5oIgojaW5jbHVkZSAid2luc29jazIuaCIKI2luY2x1ZGUgInByb2Nlc3MuaCIKI2luY2x1ZGUgImhhbmRsZS5oIgojaW5jbHVkZSAidGhyZWFkLmgiCiNpbmNsdWRlICJyZXF1ZXN0LmgiCgpzdHJ1Y3Qgc29jawp7CiAgICBzdHJ1Y3Qgb2JqZWN0ICAgICAgIG9iajsgICAgICAgICAvKiBvYmplY3QgaGVhZGVyICovCiAgICB1bnNpZ25lZCBpbnQgICAgICAgIHN0YXRlOyAgICAgICAvKiBzdGF0dXMgYml0cyAqLwogICAgdW5zaWduZWQgaW50ICAgICAgICBtYXNrOyAgICAgICAgLyogZXZlbnQgbWFzayAqLwogICAgdW5zaWduZWQgaW50ICAgICAgICBobWFzazsgICAgICAgLyogaGVsZCAoYmxvY2tlZCkgZXZlbnRzICovCiAgICB1bnNpZ25lZCBpbnQgICAgICAgIHBtYXNrOyAgICAgICAvKiBwZW5kaW5nIGV2ZW50cyAqLwogICAgc3RydWN0IGV2ZW50ICAgICAgICpldmVudDsgICAgICAgLyogZXZlbnQgb2JqZWN0ICovCiAgICBpbnQgICAgICAgICAgICAgICAgIGVycm9yc1tGRF9NQVhfRVZFTlRTXTsgLyogZXZlbnQgZXJyb3JzICovCn07CgpzdGF0aWMgdm9pZCBzb2NrX2R1bXAoIHN0cnVjdCBvYmplY3QgKm9iaiwgaW50IHZlcmJvc2UgKTsKc3RhdGljIGludCBzb2NrX3NpZ25hbGVkKCBzdHJ1Y3Qgb2JqZWN0ICpvYmosIHN0cnVjdCB0aHJlYWQgKnRocmVhZCApOwpzdGF0aWMgaW50IHNvY2tfZ2V0X3BvbGxfZXZlbnRzKCBzdHJ1Y3Qgb2JqZWN0ICpvYmogKTsKc3RhdGljIHZvaWQgc29ja19wb2xsX2V2ZW50KCBzdHJ1Y3Qgb2JqZWN0ICpvYmosIGludCBldmVudCApOwpzdGF0aWMgaW50IHNvY2tfZ2V0X2ZkKCBzdHJ1Y3Qgb2JqZWN0ICpvYmogKTsKc3RhdGljIHZvaWQgc29ja19kZXN0cm95KCBzdHJ1Y3Qgb2JqZWN0ICpvYmogKTsKc3RhdGljIGludCBzb2NrX2dldF9lcnJvciggaW50IGVyciApOwpzdGF0aWMgdm9pZCBzb2NrX3NldF9lcnJvcih2b2lkKTsKCnN0YXRpYyBjb25zdCBzdHJ1Y3Qgb2JqZWN0X29wcyBzb2NrX29wcyA9CnsKICAgIHNpemVvZihzdHJ1Y3Qgc29jayksICAgICAgICAgIC8qIHNpemUgKi8KICAgIHNvY2tfZHVtcCwgICAgICAgICAgICAgICAgICAgIC8qIGR1bXAgKi8KICAgIGFkZF9xdWV1ZSwgICAgICAgICAgICAgICAgICAgIC8qIGFkZF9xdWV1ZSAqLwogICAgcmVtb3ZlX3F1ZXVlLCAgICAgICAgICAgICAgICAgLyogcmVtb3ZlX3F1ZXVlICovCiAgICBzb2NrX3NpZ25hbGVkLCAgICAgICAgICAgICAgICAvKiBzaWduYWxlZCAqLwogICAgbm9fc2F0aXNmaWVkLCAgICAgICAgICAgICAgICAgLyogc2F0aXNmaWVkICovCiAgICBzb2NrX2dldF9wb2xsX2V2ZW50cywgICAgICAgICAvKiBnZXRfcG9sbF9ldmVudHMgKi8KICAgIHNvY2tfcG9sbF9ldmVudCwgICAgICAgICAgICAgIC8qIHBvbGxfZXZlbnQgKi8KICAgIHNvY2tfZ2V0X2ZkLCAgICAgICAgICAgICAgICAgIC8qIGdldF9mZCAqLwogICAgbm9fZmx1c2gsICAgICAgICAgICAgICAgICAgICAgLyogZmx1c2ggKi8KICAgIG5vX2dldF9maWxlX2luZm8sICAgICAgICAgICAgIC8qIGdldF9maWxlX2luZm8gKi8KICAgIHNvY2tfZGVzdHJveSAgICAgICAgICAgICAgICAgIC8qIGRlc3Ryb3kgKi8KfTsKCnN0YXRpYyB2b2lkIHNvY2tfcmVzZWxlY3QoIHN0cnVjdCBzb2NrICpzb2NrICkKewogICAgaW50IGV2ID0gc29ja19nZXRfcG9sbF9ldmVudHMoICZzb2NrLT5vYmogKTsKICAgIHN0cnVjdCBwb2xsZmQgcGZkOwoKICAgIGlmIChkZWJ1Z19sZXZlbCkKICAgICAgICBmcHJpbnRmKHN0ZGVyciwic29ja19yZXNlbGVjdCglZCk6IG5ldyBtYXNrICV4XG4iLCBzb2NrLT5vYmouZmQsIGV2KTsKCiAgICBpZiAoc29jay0+b2JqLnNlbGVjdCA9PSAtMSkgewogICAgICAgIC8qIHByZXZpb3VzbHkgdW5jb25uZWN0ZWQgc29ja2V0LCBpcyB0aGlzIHJlc2VsZWN0IHN1cHBvc2VkIHRvIGNvbm5lY3QgaXQ/ICovCiAgICAgICAgaWYgKCEoc29jay0+c3RhdGUgJiB+RkRfV0lORV9OT05CTE9DS0lORykpIHJldHVybjsKICAgICAgICAvKiBvaywgaXQgaXMsIGF0dGFjaCBpdCB0byB0aGUgd2luZXNlcnZlcidzIG1haW4gcG9sbCBsb29wICovCiAgICAgICAgYWRkX3NlbGVjdF91c2VyKCAmc29jay0+b2JqICk7CiAgICB9CiAgICAvKiB1cGRhdGUgY29uZGl0aW9uIG1hc2sgKi8KICAgIHNldF9zZWxlY3RfZXZlbnRzKCAmc29jay0+b2JqLCBldiApOwoKICAgIC8qIGNoZWNrIHdoZXRoZXIgY29uZGl0aW9uIGlzIHNhdGlzZmllZCBhbHJlYWR5ICovCiAgICBwZmQuZmQgPSBzb2NrLT5vYmouZmQ7CiAgICBwZmQuZXZlbnRzID0gZXY7CiAgICBwZmQucmV2ZW50cyA9IDA7CiAgICBwb2xsKCAmcGZkLCAxLCAwICk7CiAgICBpZiAocGZkLnJldmVudHMpCiAgICAgICAgc29ja19wb2xsX2V2ZW50KCAmc29jay0+b2JqLCBwZmQucmV2ZW50cyk7Cn0KCmlubGluZSBzdGF0aWMgaW50IHNvY2tfZXJyb3IoaW50IHMpCnsKICAgIHVuc2lnbmVkIGludCBvcHR2YWwgPSAwLCBvcHRsZW47CiAgICAKICAgIG9wdGxlbiA9IHNpemVvZihvcHR2YWwpOwogICAgZ2V0c29ja29wdChzLCBTT0xfU09DS0VULCBTT19FUlJPUiwgKHZvaWQgKikgJm9wdHZhbCwgJm9wdGxlbik7CiAgICByZXR1cm4gb3B0dmFsID8gc29ja19nZXRfZXJyb3Iob3B0dmFsKSA6IDA7Cn0KCnN0YXRpYyB2b2lkIHNvY2tfcG9sbF9ldmVudCggc3RydWN0IG9iamVjdCAqb2JqLCBpbnQgZXZlbnQgKQp7CiAgICBzdHJ1Y3Qgc29jayAqc29jayA9IChzdHJ1Y3Qgc29jayAqKW9iajsKICAgIHVuc2lnbmVkIGludCBlbWFzazsKICAgIGFzc2VydCggc29jay0+b2JqLm9wcyA9PSAmc29ja19vcHMgKTsKICAgIGlmIChkZWJ1Z19sZXZlbCkKICAgICAgICBmcHJpbnRmKHN0ZGVyciwgInNvY2tldCAlZCBzZWxlY3QgZXZlbnQ6ICV4XG4iLCBzb2NrLT5vYmouZmQsIGV2ZW50KTsKICAgIGlmIChzb2NrLT5zdGF0ZSAmIEZEX0NPTk5FQ1QpCiAgICB7CiAgICAgICAgLyogY29ubmVjdGluZyAqLwogICAgICAgIGlmIChldmVudCAmIFBPTExPVVQpCiAgICAgICAgewogICAgICAgICAgICAvKiB3ZSBnb3QgY29ubmVjdGVkICovCiAgICAgICAgICAgIHNvY2stPnN0YXRlIHw9IEZEX1dJTkVfQ09OTkVDVEVEfEZEX1JFQUR8RkRfV1JJVEU7CiAgICAgICAgICAgIHNvY2stPnN0YXRlICY9IH5GRF9DT05ORUNUOwogICAgICAgICAgICBzb2NrLT5wbWFzayB8PSBGRF9DT05ORUNUOwogICAgICAgICAgICBzb2NrLT5lcnJvcnNbRkRfQ09OTkVDVF9CSVRdID0gMDsKICAgICAgICAgICAgaWYgKGRlYnVnX2xldmVsKQogICAgICAgICAgICAgICAgZnByaW50ZihzdGRlcnIsICJzb2NrZXQgJWQgY29ubmVjdGlvbiBzdWNjZXNzXG4iLCBzb2NrLT5vYmouZmQpOwogICAgICAgIH0KICAgICAgICBlbHNlIGlmIChldmVudCAmIChQT0xMRVJSfFBPTExIVVApKQogICAgICAgIHsKICAgICAgICAgICAgLyogd2UgZGlkbid0IGdldCBjb25uZWN0ZWQ/ICovCiAgICAgICAgICAgIHNvY2stPnN0YXRlICY9IH5GRF9DT05ORUNUOwogICAgICAgICAgICBzb2NrLT5wbWFzayB8PSBGRF9DT05ORUNUOwogICAgICAgICAgICBzb2NrLT5lcnJvcnNbRkRfQ09OTkVDVF9CSVRdID0gc29ja19lcnJvciggc29jay0+b2JqLmZkICk7CiAgICAgICAgICAgIGlmIChkZWJ1Z19sZXZlbCkKICAgICAgICAgICAgICAgIGZwcmludGYoc3RkZXJyLCAic29ja2V0ICVkIGNvbm5lY3Rpb24gZmFpbHVyZVxuIiwgc29jay0+b2JqLmZkKTsKICAgICAgICB9CiAgICB9IGVsc2UKICAgIGlmIChzb2NrLT5zdGF0ZSAmIEZEX1dJTkVfTElTVEVOSU5HKQogICAgewogICAgICAgIC8qIGxpc3RlbmluZyAqLwogICAgICAgIGlmIChldmVudCAmIFBPTExJTikKICAgICAgICB7CiAgICAgICAgICAgIC8qIGluY29taW5nIGNvbm5lY3Rpb24gKi8KICAgICAgICAgICAgc29jay0+cG1hc2sgfD0gRkRfQUNDRVBUOwogICAgICAgICAgICBzb2NrLT5lcnJvcnNbRkRfQUNDRVBUX0JJVF0gPSAwOwogICAgICAgICAgICBzb2NrLT5obWFzayB8PSBGRF9BQ0NFUFQ7CiAgICAgICAgfQogICAgICAgIGVsc2UgaWYgKGV2ZW50ICYgKFBPTExFUlJ8UE9MTEhVUCkpCiAgICAgICAgewogICAgICAgICAgICAvKiBmYWlsZWQgaW5jb21pbmcgY29ubmVjdGlvbj8gKi8KICAgICAgICAgICAgc29jay0+cG1hc2sgfD0gRkRfQUNDRVBUOwogICAgICAgICAgICBzb2NrLT5lcnJvcnNbRkRfQUNDRVBUX0JJVF0gPSBzb2NrX2Vycm9yKCBzb2NrLT5vYmouZmQgKTsKICAgICAgICAgICAgc29jay0+aG1hc2sgfD0gRkRfQUNDRVBUOwogICAgICAgIH0KICAgIH0gZWxzZQogICAgewogICAgICAgIC8qIG5vcm1hbCBkYXRhIGZsb3cgKi8KICAgICAgICBpZiAoZXZlbnQgJiBQT0xMSU4pCiAgICAgICAgewogICAgICAgICAgICBjaGFyIGR1bW15OwoKICAgICAgICAgICAgLyogTGludXggMi40IGRvZXNuJ3QgcmVwb3J0IFBPTExIVVAgaWYgb25seSBvbmUgc2lkZSBvZiB0aGUgc29ja2V0CiAgICAgICAgICAgICAqIGhhcyBiZWVuIGNsb3NlZCwgc28gd2UgbmVlZCB0byBjaGVjayBmb3IgaXQgZXhwbGljaXRseSBoZXJlICovCiAgICAgICAgICAgIGlmICghcmVjdiggc29jay0+b2JqLmZkLCAmZHVtbXksIDEsIE1TR19QRUVLICkpIGV2ZW50ID0gUE9MTEhVUDsKICAgICAgICAgICAgZWxzZQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAvKiBpbmNvbWluZyBkYXRhICovCiAgICAgICAgICAgICAgICBzb2NrLT5wbWFzayB8PSBGRF9SRUFEOwogICAgICAgICAgICAgICAgc29jay0+aG1hc2sgfD0gRkRfUkVBRDsKICAgICAgICAgICAgICAgIHNvY2stPmVycm9yc1tGRF9SRUFEX0JJVF0gPSAwOwogICAgICAgICAgICAgICAgaWYgKGRlYnVnX2xldmVsKQogICAgICAgICAgICAgICAgICAgIGZwcmludGYoc3RkZXJyLCAic29ja2V0ICVkIGlzIHJlYWRhYmxlXG4iLCBzb2NrLT5vYmouZmQgKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBpZiAoZXZlbnQgJiBQT0xMT1VUKQogICAgICAgIHsKICAgICAgICAgICAgc29jay0+cG1hc2sgfD0gRkRfV1JJVEU7CiAgICAgICAgICAgIHNvY2stPmhtYXNrIHw9IEZEX1dSSVRFOwogICAgICAgICAgICBzb2NrLT5lcnJvcnNbRkRfV1JJVEVfQklUXSA9IDA7CiAgICAgICAgICAgIGlmIChkZWJ1Z19sZXZlbCkKICAgICAgICAgICAgICAgIGZwcmludGYoc3RkZXJyLCAic29ja2V0ICVkIGlzIHdyaXRhYmxlXG4iLCBzb2NrLT5vYmouZmQpOwogICAgICAgIH0KICAgICAgICBpZiAoZXZlbnQgJiBQT0xMUFJJKQogICAgICAgIHsKICAgICAgICAgICAgc29jay0+cG1hc2sgfD0gRkRfT09COwogICAgICAgICAgICBzb2NrLT5obWFzayB8PSBGRF9PT0I7CiAgICAgICAgICAgIHNvY2stPmVycm9yc1tGRF9PT0JfQklUXSA9IDA7CiAgICAgICAgICAgIGlmIChkZWJ1Z19sZXZlbCkKICAgICAgICAgICAgICAgIGZwcmludGYoc3RkZXJyLCAic29ja2V0ICVkIGdvdCBPT0IgZGF0YVxuIiwgc29jay0+b2JqLmZkKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZXZlbnQgJiBQT0xMRVJSKSB8fCAoKGV2ZW50ICYgKFBPTExJTnxQT0xMSFVQKSkgPT0gUE9MTEhVUCkpCiAgICAgICAgICAgICYmIChzb2NrLT5zdGF0ZSAmIChGRF9SRUFEfEZEX1dSSVRFKSkpIHsKICAgICAgICAgICAgLyogc29ja2V0IGNsb3NpbmcgKi8KICAgICAgICAgICAgc29jay0+ZXJyb3JzW0ZEX0NMT1NFX0JJVF0gPSBzb2NrX2Vycm9yKCBzb2NrLT5vYmouZmQgKTsKICAgICAgICAgICAgc29jay0+c3RhdGUgJj0gfihGRF9XSU5FX0NPTk5FQ1RFRHxGRF9SRUFEfEZEX1dSSVRFKTsKICAgICAgICAgICAgc29jay0+cG1hc2sgfD0gRkRfQ0xPU0U7CiAgICAgICAgICAgIGlmIChkZWJ1Z19sZXZlbCkKICAgICAgICAgICAgICAgIGZwcmludGYoc3RkZXJyLCAic29ja2V0ICVkIGFib3J0ZWQgYnkgZXJyb3IgJWRcbiIsCiAgICAgICAgICAgICAgICAgICAgICAgIHNvY2stPm9iai5mZCwgc29jay0+ZXJyb3JzW0ZEX0NMT1NFX0JJVF0pOwogICAgICAgIH0KICAgIH0KCiAgICBpZiAoZXZlbnQgJiAoUE9MTEVSUnxQT0xMSFVQKSkKICAgICAgICBzZXRfc2VsZWN0X2V2ZW50cyggJnNvY2stPm9iaiwgLTEgKTsKICAgIGVsc2UKICAgICAgICBzb2NrX3Jlc2VsZWN0KCBzb2NrICk7CiAgICAvKiB3YWtlIHVwIGFueW9uZSB3YWl0aW5nIGZvciB3aGF0ZXZlciBqdXN0IGhhcHBlbmVkICovCiAgICBlbWFzayA9IHNvY2stPnBtYXNrICYgc29jay0+bWFzazsKICAgIGlmIChkZWJ1Z19sZXZlbCAmJiBlbWFzaykKICAgICAgICBmcHJpbnRmKHN0ZGVyciwgInNvY2tldCAlZCBwZW5kaW5nIGV2ZW50czogJXhcbiIsIHNvY2stPm9iai5mZCwgZW1hc2spOwogICAgaWYgKGVtYXNrICYmIHNvY2stPmV2ZW50KSB7CiAgICAgICAgaWYgKGRlYnVnX2xldmVsKSBmcHJpbnRmKHN0ZGVyciwgInNpZ25hbGxpbmcgZXZlbnQgcHRyICVwXG4iLCBzb2NrLT5ldmVudCk7CiAgICAgICAgc2V0X2V2ZW50KHNvY2stPmV2ZW50KTsKICAgIH0KCiAgICAvKiBpZiBhbnlvbmUgaXMgc3R1cGlkIGVub3VnaCB0byB3YWl0IG9uIHRoZSBzb2NrZXQgb2JqZWN0IGl0c2VsZiwKICAgICAqIG1heWJlIHdlIHNob3VsZCB3YWtlIHRoZW0gdXAgdG9vLCBqdXN0IGluIGNhc2U/ICovCiAgICB3YWtlX3VwKCAmc29jay0+b2JqLCAwICk7Cn0KCnN0YXRpYyB2b2lkIHNvY2tfZHVtcCggc3RydWN0IG9iamVjdCAqb2JqLCBpbnQgdmVyYm9zZSApCnsKICAgIHN0cnVjdCBzb2NrICpzb2NrID0gKHN0cnVjdCBzb2NrICopb2JqOwogICAgYXNzZXJ0KCBvYmotPm9wcyA9PSAmc29ja19vcHMgKTsKICAgIHByaW50ZiggIlNvY2tldCBmZD0lZCwgc3RhdGU9JXgsIG1hc2s9JXgsIHBlbmRpbmc9JXgsIGhlbGQ9JXhcbiIsCiAgICAgICAgICAgIHNvY2stPm9iai5mZCwgc29jay0+c3RhdGUsCiAgICAgICAgICAgIHNvY2stPm1hc2ssIHNvY2stPnBtYXNrLCBzb2NrLT5obWFzayApOwp9CgpzdGF0aWMgaW50IHNvY2tfc2lnbmFsZWQoIHN0cnVjdCBvYmplY3QgKm9iaiwgc3RydWN0IHRocmVhZCAqdGhyZWFkICkKewogICAgc3RydWN0IHNvY2sgKnNvY2sgPSAoc3RydWN0IHNvY2sgKilvYmo7CiAgICBhc3NlcnQoIG9iai0+b3BzID09ICZzb2NrX29wcyApOwoKICAgIHJldHVybiBjaGVja19zZWxlY3RfZXZlbnRzKCBzb2NrLT5vYmouZmQsIHNvY2tfZ2V0X3BvbGxfZXZlbnRzKCAmc29jay0+b2JqICkgKTsKfQoKc3RhdGljIGludCBzb2NrX2dldF9wb2xsX2V2ZW50cyggc3RydWN0IG9iamVjdCAqb2JqICkKewogICAgc3RydWN0IHNvY2sgKnNvY2sgPSAoc3RydWN0IHNvY2sgKilvYmo7CiAgICB1bnNpZ25lZCBpbnQgbWFzayA9IHNvY2stPm1hc2sgJiBzb2NrLT5zdGF0ZSAmIH5zb2NrLT5obWFzazsKICAgIGludCBldiA9IDA7CgogICAgYXNzZXJ0KCBvYmotPm9wcyA9PSAmc29ja19vcHMgKTsKCiAgICBpZiAoc29jay0+c3RhdGUgJiBGRF9DT05ORUNUKQogICAgICAgIC8qIGNvbm5lY3RpbmcsIHdhaXQgZm9yIHdyaXRhYmxlICovCiAgICAgICAgcmV0dXJuIFBPTExPVVQ7CiAgICBpZiAoc29jay0+c3RhdGUgJiBGRF9XSU5FX0xJU1RFTklORykKICAgICAgICAvKiBsaXN0ZW5pbmcsIHdhaXQgZm9yIHJlYWRhYmxlICovCiAgICAgICAgcmV0dXJuIChzb2NrLT5obWFzayAmIEZEX0FDQ0VQVCkgPyAwIDogUE9MTElOOwoKICAgIGlmIChtYXNrICYgRkRfUkVBRCkgIGV2IHw9IFBPTExJTiB8IFBPTExQUkk7CiAgICBpZiAobWFzayAmIEZEX1dSSVRFKSBldiB8PSBQT0xMT1VUOwogICAgcmV0dXJuIGV2Owp9CgpzdGF0aWMgaW50IHNvY2tfZ2V0X2ZkKCBzdHJ1Y3Qgb2JqZWN0ICpvYmogKQp7CiAgICBzdHJ1Y3Qgc29jayAqc29jayA9IChzdHJ1Y3Qgc29jayAqKW9iajsKICAgIGFzc2VydCggb2JqLT5vcHMgPT0gJnNvY2tfb3BzICk7CiAgICByZXR1cm4gc29jay0+b2JqLmZkOwp9CgpzdGF0aWMgdm9pZCBzb2NrX2Rlc3Ryb3koIHN0cnVjdCBvYmplY3QgKm9iaiApCnsKICAgIHN0cnVjdCBzb2NrICpzb2NrID0gKHN0cnVjdCBzb2NrICopb2JqOwogICAgYXNzZXJ0KCBvYmotPm9wcyA9PSAmc29ja19vcHMgKTsKCiAgICAvKiBGSVhNRTogc3BlY2lhbCBzb2NrZXQgc2h1dGRvd24gc3R1ZmY/ICovCiAgICBpZiAoc29jay0+ZXZlbnQpCiAgICB7CiAgICAgICAgLyogaWYgdGhlIHNlcnZpY2UgdGhyZWFkIHdhcyB3YWl0aW5nIGZvciB0aGUgZXZlbnQgb2JqZWN0LAogICAgICAgICAqIHdlIHNob3VsZCBub3cgc2lnbmFsIGl0LCB0byBsZXQgdGhlIHNlcnZpY2UgdGhyZWFkCiAgICAgICAgICogb2JqZWN0IGRldGVjdCB0aGF0IGl0IGlzIG5vdyBvcnBoYW5lZC4uLiAqLwogICAgICAgIGlmIChzb2NrLT5tYXNrICYgRkRfV0lORV9TRVJWRVZFTlQpCiAgICAgICAgICAgIHNldF9ldmVudCggc29jay0+ZXZlbnQgKTsKICAgICAgICAvKiB3ZSdyZSB0aHJvdWdoIHdpdGggaXQgKi8KICAgICAgICByZWxlYXNlX29iamVjdCggc29jay0+ZXZlbnQgKTsKICAgIH0KfQoKLyogY3JlYXRlIGEgbmV3IGFuZCB1bmNvbm5lY3RlZCBzb2NrZXQgKi8Kc3RhdGljIHN0cnVjdCBvYmplY3QgKmNyZWF0ZV9zb2NrZXQoIGludCBmYW1pbHksIGludCB0eXBlLCBpbnQgcHJvdG9jb2wgKQp7CiAgICBzdHJ1Y3Qgc29jayAqc29jazsKICAgIGludCBzb2NrZmQ7CgogICAgc29ja2ZkID0gc29ja2V0KCBmYW1pbHksIHR5cGUsIHByb3RvY29sICk7CiAgICBpZiAoZGVidWdfbGV2ZWwpCiAgICAgICAgZnByaW50ZihzdGRlcnIsInNvY2tldCglZCwlZCwlZCk9JWRcbiIsZmFtaWx5LHR5cGUscHJvdG9jb2wsc29ja2ZkKTsKICAgIGlmIChzb2NrZmQgPT0gLTEpIHsKICAgICAgICBzb2NrX3NldF9lcnJvcigpOwogICAgICAgIHJldHVybiBOVUxMOwogICAgfQogICAgZmNudGwoc29ja2ZkLCBGX1NFVEZMLCBPX05PTkJMT0NLKTsgLyogbWFrZSBzb2NrZXQgbm9uYmxvY2tpbmcgKi8KICAgIGlmICghKHNvY2sgPSBhbGxvY19vYmplY3QoICZzb2NrX29wcywgLTEgKSkpIHJldHVybiBOVUxMOwogICAgc29jay0+b2JqLmZkID0gc29ja2ZkOwogICAgc29jay0+c3RhdGUgPSAodHlwZSAhPSBTT0NLX1NUUkVBTSkgPyAoRkRfUkVBRHxGRF9XUklURSkgOiAwOwogICAgc29jay0+bWFzayAgPSAwOwogICAgc29jay0+aG1hc2sgPSAwOwogICAgc29jay0+cG1hc2sgPSAwOwogICAgc29jay0+ZXZlbnQgPSBOVUxMOwogICAgc29ja19yZXNlbGVjdCggc29jayApOwogICAgY2xlYXJfZXJyb3IoKTsKICAgIHJldHVybiAmc29jay0+b2JqOwp9CgovKiBhY2NlcHQgYSBzb2NrZXQgKGNyZWF0ZXMgYSBuZXcgZmQpICovCnN0YXRpYyBzdHJ1Y3Qgb2JqZWN0ICphY2NlcHRfc29ja2V0KCBoYW5kbGVfdCBoYW5kbGUgKQp7CiAgICBzdHJ1Y3Qgc29jayAqYWNjZXB0c29jazsKICAgIHN0cnVjdCBzb2NrICpzb2NrOwogICAgaW50CWFjY2VwdGZkOwogICAgc3RydWN0IHNvY2thZGRyCXNhZGRyOwogICAgaW50CQkJc2xlbjsKCiAgICBzb2NrPShzdHJ1Y3Qgc29jayopZ2V0X2hhbmRsZV9vYmooY3VycmVudC0+cHJvY2VzcyxoYW5kbGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgR0VORVJJQ19SRUFEfEdFTkVSSUNfV1JJVEV8U1lOQ0hST05JWkUsJnNvY2tfb3BzKTsKICAgIGlmICghc29jaykKICAgIAlyZXR1cm4gTlVMTDsKICAgIC8qIFRyeSB0byBhY2NlcHQoMikuIFdlIGNhbid0IGJlIHNhZmUgdGhhdCB0aGlzIGFuIGFscmVhZHkgY29ubmVjdGVkIHNvY2tldCAKICAgICAqIG9yIHRoYXQgYWNjZXB0KCkgaXMgYWxsb3dlZCBvbiBpdC4gSW4gdGhvc2UgY2FzZXMgd2Ugd2lsbCBnZXQgLTEvZXJybm8KICAgICAqIHJldHVybi4KICAgICAqLwogICAgc2xlbiA9IHNpemVvZihzYWRkcik7CiAgICBhY2NlcHRmZCA9IGFjY2VwdChzb2NrLT5vYmouZmQsJnNhZGRyLCZzbGVuKTsKICAgIGlmIChhY2NlcHRmZD09LTEpIHsKICAgIAlzb2NrX3NldF9lcnJvcigpOwogICAgICAgIHJlbGVhc2Vfb2JqZWN0KCBzb2NrICk7CglyZXR1cm4gTlVMTDsKICAgIH0KICAgIGlmICghKGFjY2VwdHNvY2sgPSBhbGxvY19vYmplY3QoICZzb2NrX29wcywgLTEgKSkpCiAgICB7CiAgICAgICAgcmVsZWFzZV9vYmplY3QoIHNvY2sgKTsKICAgICAgICByZXR1cm4gTlVMTDsKICAgIH0KCiAgICAvKiBuZXdseSBjcmVhdGVkIHNvY2tldCBnZXRzIHRoZSBzYW1lIHByb3BlcnRpZXMgb2YgdGhlIGxpc3RlbmluZyBzb2NrZXQgKi8KICAgIGZjbnRsKGFjY2VwdGZkLCBGX1NFVEZMLCBPX05PTkJMT0NLKTsgLyogbWFrZSBzb2NrZXQgbm9uYmxvY2tpbmcgKi8KICAgIGFjY2VwdHNvY2stPm9iai5mZCA9IGFjY2VwdGZkOwogICAgYWNjZXB0c29jay0+c3RhdGUgID0gRkRfV0lORV9DT05ORUNURUR8RkRfUkVBRHxGRF9XUklURTsKICAgIGlmIChzb2NrLT5zdGF0ZSAmIEZEX1dJTkVfTk9OQkxPQ0tJTkcpCiAgICAgICAgYWNjZXB0c29jay0+c3RhdGUgfD0gRkRfV0lORV9OT05CTE9DS0lORzsKICAgIGFjY2VwdHNvY2stPm1hc2sgICA9IHNvY2stPm1hc2s7CiAgICBhY2NlcHRzb2NrLT5obWFzayAgPSAwOwogICAgYWNjZXB0c29jay0+cG1hc2sgID0gMDsKICAgIGFjY2VwdHNvY2stPmV2ZW50ICA9IE5VTEw7CiAgICBpZiAoc29jay0+ZXZlbnQgJiYgIShzb2NrLT5tYXNrICYgRkRfV0lORV9TRVJWRVZFTlQpKQogICAgICAgIGFjY2VwdHNvY2stPmV2ZW50ID0gKHN0cnVjdCBldmVudCAqKWdyYWJfb2JqZWN0KCBzb2NrLT5ldmVudCApOwoKICAgIHNvY2tfcmVzZWxlY3QoIGFjY2VwdHNvY2sgKTsKICAgIGNsZWFyX2Vycm9yKCk7CiAgICBzb2NrLT5wbWFzayAmPSB+RkRfQUNDRVBUOwogICAgc29jay0+aG1hc2sgJj0gfkZEX0FDQ0VQVDsKICAgIHNvY2tfcmVzZWxlY3QoIHNvY2sgKTsKICAgIHJlbGVhc2Vfb2JqZWN0KCBzb2NrICk7CiAgICByZXR1cm4gJmFjY2VwdHNvY2stPm9iajsKfQoKLyogc2V0IHRoZSBsYXN0IGVycm9yIGRlcGVuZGluZyBvbiBlcnJubyAqLwpzdGF0aWMgaW50IHNvY2tfZ2V0X2Vycm9yKCBpbnQgZXJyICkKewogICAgc3dpdGNoIChlcnIpCiAgICB7CiAgICAgICAgY2FzZSBFSU5UUjogICAgICAgICAgICAgcmV0dXJuIFdTQUVJTlRSOyBicmVhazsKICAgICAgICBjYXNlIEVCQURGOiAgICAgICAgICAgICByZXR1cm4gV1NBRUJBREY7IGJyZWFrOwogICAgICAgIGNhc2UgRVBFUk06CiAgICAgICAgY2FzZSBFQUNDRVM6ICAgICAgICAgICAgcmV0dXJuIFdTQUVBQ0NFUzsgYnJlYWs7CiAgICAgICAgY2FzZSBFRkFVTFQ6ICAgICAgICAgICAgcmV0dXJuIFdTQUVGQVVMVDsgYnJlYWs7CiAgICAgICAgY2FzZSBFSU5WQUw6ICAgICAgICAgICAgcmV0dXJuIFdTQUVJTlZBTDsgYnJlYWs7CiAgICAgICAgY2FzZSBFTUZJTEU6ICAgICAgICAgICAgcmV0dXJuIFdTQUVNRklMRTsgYnJlYWs7CiAgICAgICAgY2FzZSBFV09VTERCTE9DSzogICAgICAgcmV0dXJuIFdTQUVXT1VMREJMT0NLOyBicmVhazsKICAgICAgICBjYXNlIEVJTlBST0dSRVNTOiAgICAgICByZXR1cm4gV1NBRUlOUFJPR1JFU1M7IGJyZWFrOwogICAgICAgIGNhc2UgRUFMUkVBRFk6ICAgICAgICAgIHJldHVybiBXU0FFQUxSRUFEWTsgYnJlYWs7CiAgICAgICAgY2FzZSBFTk9UU09DSzogICAgICAgICAgcmV0dXJuIFdTQUVOT1RTT0NLOyBicmVhazsKICAgICAgICBjYXNlIEVERVNUQUREUlJFUTogICAgICByZXR1cm4gV1NBRURFU1RBRERSUkVROyBicmVhazsKICAgICAgICBjYXNlIEVNU0dTSVpFOiAgICAgICAgICByZXR1cm4gV1NBRU1TR1NJWkU7IGJyZWFrOwogICAgICAgIGNhc2UgRVBST1RPVFlQRTogICAgICAgIHJldHVybiBXU0FFUFJPVE9UWVBFOyBicmVhazsKICAgICAgICBjYXNlIEVOT1BST1RPT1BUOiAgICAgICByZXR1cm4gV1NBRU5PUFJPVE9PUFQ7IGJyZWFrOwogICAgICAgIGNhc2UgRVBST1RPTk9TVVBQT1JUOiAgIHJldHVybiBXU0FFUFJPVE9OT1NVUFBPUlQ7IGJyZWFrOwogICAgICAgIGNhc2UgRVNPQ0tUTk9TVVBQT1JUOiAgIHJldHVybiBXU0FFU09DS1ROT1NVUFBPUlQ7IGJyZWFrOwogICAgICAgIGNhc2UgRU9QTk9UU1VQUDogICAgICAgIHJldHVybiBXU0FFT1BOT1RTVVBQOyBicmVhazsKICAgICAgICBjYXNlIEVQRk5PU1VQUE9SVDogICAgICByZXR1cm4gV1NBRVBGTk9TVVBQT1JUOyBicmVhazsKICAgICAgICBjYXNlIEVBRk5PU1VQUE9SVDogICAgICByZXR1cm4gV1NBRUFGTk9TVVBQT1JUOyBicmVhazsKICAgICAgICBjYXNlIEVBRERSSU5VU0U6ICAgICAgICByZXR1cm4gV1NBRUFERFJJTlVTRTsgYnJlYWs7CiAgICAgICAgY2FzZSBFQUREUk5PVEFWQUlMOiAgICAgcmV0dXJuIFdTQUVBRERSTk9UQVZBSUw7IGJyZWFrOwogICAgICAgIGNhc2UgRU5FVERPV046ICAgICAgICAgIHJldHVybiBXU0FFTkVURE9XTjsgYnJlYWs7CiAgICAgICAgY2FzZSBFTkVUVU5SRUFDSDogICAgICAgcmV0dXJuIFdTQUVORVRVTlJFQUNIOyBicmVhazsKICAgICAgICBjYXNlIEVORVRSRVNFVDogICAgICAgICByZXR1cm4gV1NBRU5FVFJFU0VUOyBicmVhazsKICAgICAgICBjYXNlIEVDT05OQUJPUlRFRDogICAgICByZXR1cm4gV1NBRUNPTk5BQk9SVEVEOyBicmVhazsKICAgICAgICBjYXNlIEVQSVBFOgogICAgICAgIGNhc2UgRUNPTk5SRVNFVDogICAgICAgIHJldHVybiBXU0FFQ09OTlJFU0VUOyBicmVhazsKICAgICAgICBjYXNlIEVOT0JVRlM6ICAgICAgICAgICByZXR1cm4gV1NBRU5PQlVGUzsgYnJlYWs7CiAgICAgICAgY2FzZSBFSVNDT05OOiAgICAgICAgICAgcmV0dXJuIFdTQUVJU0NPTk47IGJyZWFrOwogICAgICAgIGNhc2UgRU5PVENPTk46ICAgICAgICAgIHJldHVybiBXU0FFTk9UQ09OTjsgYnJlYWs7CiAgICAgICAgY2FzZSBFU0hVVERPV046ICAgICAgICAgcmV0dXJuIFdTQUVTSFVURE9XTjsgYnJlYWs7CiAgICAgICAgY2FzZSBFVE9PTUFOWVJFRlM6ICAgICAgcmV0dXJuIFdTQUVUT09NQU5ZUkVGUzsgYnJlYWs7CiAgICAgICAgY2FzZSBFVElNRURPVVQ6ICAgICAgICAgcmV0dXJuIFdTQUVUSU1FRE9VVDsgYnJlYWs7CiAgICAgICAgY2FzZSBFQ09OTlJFRlVTRUQ6ICAgICAgcmV0dXJuIFdTQUVDT05OUkVGVVNFRDsgYnJlYWs7CiAgICAgICAgY2FzZSBFTE9PUDogICAgICAgICAgICAgcmV0dXJuIFdTQUVMT09QOyBicmVhazsKICAgICAgICBjYXNlIEVOQU1FVE9PTE9ORzogICAgICByZXR1cm4gV1NBRU5BTUVUT09MT05HOyBicmVhazsKICAgICAgICBjYXNlIEVIT1NURE9XTjogICAgICAgICByZXR1cm4gV1NBRUhPU1RET1dOOyBicmVhazsKICAgICAgICBjYXNlIEVIT1NUVU5SRUFDSDogICAgICByZXR1cm4gV1NBRUhPU1RVTlJFQUNIOyBicmVhazsKICAgICAgICBjYXNlIEVOT1RFTVBUWTogICAgICAgICByZXR1cm4gV1NBRU5PVEVNUFRZOyBicmVhazsKI2lmZGVmIEVQUk9DTElNCiAgICAgICAgY2FzZSBFUFJPQ0xJTTogICAgICAgICAgcmV0dXJuIFdTQUVQUk9DTElNOyBicmVhazsKI2VuZGlmCiNpZmRlZiBFVVNFUlMKICAgICAgICBjYXNlIEVVU0VSUzogICAgICAgICAgICByZXR1cm4gV1NBRVVTRVJTOyBicmVhazsKI2VuZGlmCiNpZmRlZiBFRFFVT1QKICAgICAgICBjYXNlIEVEUVVPVDogICAgICAgICAgICByZXR1cm4gV1NBRURRVU9UOyBicmVhazsKI2VuZGlmCiNpZmRlZiBFU1RBTEUKICAgICAgICBjYXNlIEVTVEFMRTogICAgICAgICAgICByZXR1cm4gV1NBRVNUQUxFOyBicmVhazsKI2VuZGlmCiNpZmRlZiBFUkVNT1RFCiAgICAgICAgY2FzZSBFUkVNT1RFOiAgICAgICAgICAgcmV0dXJuIFdTQUVSRU1PVEU7IGJyZWFrOwojZW5kaWYKICAgIGRlZmF1bHQ6IGVycm5vPWVycjsgcGVycm9yKCJzb2NrX3NldF9lcnJvciIpOyByZXR1cm4gRVJST1JfVU5LTk9XTjsgYnJlYWs7CiAgICB9Cn0KCi8qIHNldCB0aGUgbGFzdCBlcnJvciBkZXBlbmRpbmcgb24gZXJybm8gKi8Kc3RhdGljIHZvaWQgc29ja19zZXRfZXJyb3Iodm9pZCkKewogICAgc2V0X2Vycm9yKCBzb2NrX2dldF9lcnJvciggZXJybm8gKSApOwp9CgovKiBjcmVhdGUgYSBzb2NrZXQgKi8KREVDTF9IQU5ETEVSKGNyZWF0ZV9zb2NrZXQpCnsKICAgIHN0cnVjdCBvYmplY3QgKm9iajsKCiAgICByZXEtPmhhbmRsZSA9IDA7CiAgICBpZiAoKG9iaiA9IGNyZWF0ZV9zb2NrZXQoIHJlcS0+ZmFtaWx5LCByZXEtPnR5cGUsIHJlcS0+cHJvdG9jb2wgKSkgIT0gTlVMTCkKICAgIHsKICAgICAgICByZXEtPmhhbmRsZSA9IGFsbG9jX2hhbmRsZSggY3VycmVudC0+cHJvY2Vzcywgb2JqLCByZXEtPmFjY2VzcywgcmVxLT5pbmhlcml0ICk7CiAgICAgICAgcmVsZWFzZV9vYmplY3QoIG9iaiApOwogICAgfQp9CgovKiBhY2NlcHQgYSBzb2NrZXQgKi8KREVDTF9IQU5ETEVSKGFjY2VwdF9zb2NrZXQpCnsKICAgIHN0cnVjdCBvYmplY3QgKm9iajsKCiAgICByZXEtPmhhbmRsZSA9IDA7CiAgICBpZiAoKG9iaiA9IGFjY2VwdF9zb2NrZXQoIHJlcS0+bGhhbmRsZSApKSAhPSBOVUxMKQogICAgewogICAgICAgIHJlcS0+aGFuZGxlID0gYWxsb2NfaGFuZGxlKCBjdXJyZW50LT5wcm9jZXNzLCBvYmosIHJlcS0+YWNjZXNzLCByZXEtPmluaGVyaXQgKTsKICAgICAgICByZWxlYXNlX29iamVjdCggb2JqICk7CiAgICB9Cn0KCi8qIHNldCBzb2NrZXQgZXZlbnQgcGFyYW1ldGVycyAqLwpERUNMX0hBTkRMRVIoc2V0X3NvY2tldF9ldmVudCkKewogICAgc3RydWN0IHNvY2sgKnNvY2s7CiAgICBzdHJ1Y3QgZXZlbnQgKm9ldmVudDsKICAgIHVuc2lnbmVkIGludCBvbWFzazsKCiAgICBzb2NrPShzdHJ1Y3Qgc29jayopZ2V0X2hhbmRsZV9vYmooY3VycmVudC0+cHJvY2VzcyxyZXEtPmhhbmRsZSxHRU5FUklDX1JFQUR8R0VORVJJQ19XUklURXxTWU5DSFJPTklaRSwmc29ja19vcHMpOwogICAgaWYgKCFzb2NrKQoJcmV0dXJuOwogICAgb2V2ZW50ID0gc29jay0+ZXZlbnQ7CiAgICBvbWFzayAgPSBzb2NrLT5tYXNrOwogICAgc29jay0+bWFzayAgICA9IHJlcS0+bWFzazsKICAgIHNvY2stPmV2ZW50ICAgPSBnZXRfZXZlbnRfb2JqKCBjdXJyZW50LT5wcm9jZXNzLCByZXEtPmV2ZW50LCBFVkVOVF9NT0RJRllfU1RBVEUgKTsKICAgIGlmIChkZWJ1Z19sZXZlbCAmJiBzb2NrLT5ldmVudCkgZnByaW50ZihzdGRlcnIsICJldmVudCBwdHI6ICVwXG4iLCBzb2NrLT5ldmVudCk7CiAgICBzb2NrX3Jlc2VsZWN0KCBzb2NrICk7CiAgICBpZiAoc29jay0+bWFzaykKICAgICAgICBzb2NrLT5zdGF0ZSB8PSBGRF9XSU5FX05PTkJMT0NLSU5HOwoKICAgIC8qIGlmIGEgbmV0d29yayBldmVudCBpcyBwZW5kaW5nLCBzaWduYWwgdGhlIGV2ZW50IG9iamVjdCAKICAgICAgIGl0IGlzIHBvc3NpYmxlIHRoYXQgRkRfQ09OTkVDVCBvciBGRF9BQ0NFUFQgbmV0d29yayBldmVudHMgaGFzIGhhcHBlbmVkCiAgICAgICBiZWZvcmUgYSBXU0FFdmVudFNlbGVjdCgpIHdhcyBkb25lIG9uIGl0LiAKICAgICAgICh3aGVuIGRlYWxpbmcgd2l0aCBBc3luY2hyb25vdXMgc29ja2V0KSAgKi8KICAgIGlmIChzb2NrLT5wbWFzayAmIHNvY2stPm1hc2spCiAgICAgICAgc2V0X2V2ZW50KHNvY2stPmV2ZW50KTsKICAgIAogICAgaWYgKG9ldmVudCkKICAgIHsKICAgICAgICBpZiAoKG9ldmVudCAhPSBzb2NrLT5ldmVudCkgJiYgKG9tYXNrICYgRkRfV0lORV9TRVJWRVZFTlQpKQogICAgICAgICAgICAvKiBpZiB0aGUgc2VydmljZSB0aHJlYWQgd2FzIHdhaXRpbmcgZm9yIHRoZSBvbGQgZXZlbnQgb2JqZWN0LAogICAgICAgICAgICAgKiB3ZSBzaG91bGQgbm93IHNpZ25hbCBpdCwgdG8gbGV0IHRoZSBzZXJ2aWNlIHRocmVhZAogICAgICAgICAgICAgKiBvYmplY3QgZGV0ZWN0IHRoYXQgaXQgaXMgbm93IG9ycGhhbmVkLi4uICovCiAgICAgICAgICAgIHNldF9ldmVudCggb2V2ZW50ICk7CiAgICAgICAgLyogd2UncmUgdGhyb3VnaCB3aXRoIGl0ICovCiAgICAgICAgcmVsZWFzZV9vYmplY3QoIG9ldmVudCApOwogICAgfQogICAgcmVsZWFzZV9vYmplY3QoICZzb2NrLT5vYmogKTsKfQoKLyogZ2V0IHNvY2tldCBldmVudCBwYXJhbWV0ZXJzICovCkRFQ0xfSEFORExFUihnZXRfc29ja2V0X2V2ZW50KQp7CiAgICBzdHJ1Y3Qgc29jayAqc29jazsKICAgIHNpemVfdCBzaXplOwoKICAgIHNvY2s9KHN0cnVjdCBzb2NrKilnZXRfaGFuZGxlX29iaihjdXJyZW50LT5wcm9jZXNzLHJlcS0+aGFuZGxlLEdFTkVSSUNfUkVBRHxHRU5FUklDX1dSSVRFfFNZTkNIUk9OSVpFLCZzb2NrX29wcyk7CiAgICBpZiAoIXNvY2spCiAgICB7CglyZXEtPm1hc2sgID0gMDsKCXJlcS0+cG1hc2sgPSAwOwoJcmVxLT5zdGF0ZSA9IDA7CglzZXRfZXJyb3IoV1NBRU5PVFNPQ0spOwoJcmV0dXJuOwogICAgfQogICAgcmVxLT5tYXNrICAgID0gc29jay0+bWFzazsKICAgIHJlcS0+cG1hc2sgICA9IHNvY2stPnBtYXNrOwogICAgcmVxLT5zdGF0ZSAgID0gc29jay0+c3RhdGU7CiAgICBzaXplID0gbWluKCBnZXRfcmVxX2RhdGFfc2l6ZShyZXEpLCBzaXplb2Yoc29jay0+ZXJyb3JzKSApOwogICAgbWVtY3B5KCBnZXRfcmVxX2RhdGEocmVxKSwgc29jay0+ZXJyb3JzLCBzaXplICk7CiAgICBzZXRfcmVxX2RhdGFfc2l6ZSggcmVxLCBzaXplICk7CgogICAgaWYgKHJlcS0+c2VydmljZSkKICAgIHsKICAgICAgICBpZiAocmVxLT5zX2V2ZW50KQogICAgICAgIHsKICAgICAgICAgICAgc3RydWN0IGV2ZW50ICpzZXZlbnQgPSBnZXRfZXZlbnRfb2JqKGN1cnJlbnQtPnByb2Nlc3MsIHJlcS0+c19ldmVudCwgMCk7CiAgICAgICAgICAgIGlmIChzZXZlbnQgPT0gc29jay0+ZXZlbnQpCiAgICAgICAgICAgICAgICByZXEtPnNfZXZlbnQgPSAwOwogICAgICAgICAgICByZWxlYXNlX29iamVjdCggc2V2ZW50ICk7CiAgICAgICAgfQogICAgICAgIGlmICghcmVxLT5zX2V2ZW50KQogICAgICAgIHsKICAgICAgICAgICAgaWYgKHJlcS0+Y19ldmVudCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgc3RydWN0IGV2ZW50ICpjZXZlbnQgPSBnZXRfZXZlbnRfb2JqKGN1cnJlbnQtPnByb2Nlc3MsIHJlcS0+Y19ldmVudCwgRVZFTlRfTU9ESUZZX1NUQVRFKTsKICAgICAgICAgICAgICAgIHJlc2V0X2V2ZW50KCBjZXZlbnQgKTsKICAgICAgICAgICAgICAgIHJlbGVhc2Vfb2JqZWN0KCBjZXZlbnQgKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBzb2NrLT5wbWFzayA9IDA7CiAgICAgICAgICAgIHNvY2tfcmVzZWxlY3QoIHNvY2sgKTsKICAgICAgICB9CiAgICAgICAgZWxzZSBzZXRfZXJyb3IoV1NBRUlOVkFMKTsKICAgIH0KICAgIHJlbGVhc2Vfb2JqZWN0KCAmc29jay0+b2JqICk7Cn0KCi8qIHJlLWVuYWJsZSBwZW5kaW5nIHNvY2tldCBldmVudHMgKi8KREVDTF9IQU5ETEVSKGVuYWJsZV9zb2NrZXRfZXZlbnQpCnsKICAgIHN0cnVjdCBzb2NrICpzb2NrOwoKICAgIHNvY2s9KHN0cnVjdCBzb2NrKilnZXRfaGFuZGxlX29iaihjdXJyZW50LT5wcm9jZXNzLHJlcS0+aGFuZGxlLEdFTkVSSUNfUkVBRHxHRU5FUklDX1dSSVRFfFNZTkNIUk9OSVpFLCZzb2NrX29wcyk7CiAgICBpZiAoIXNvY2spCiAgICAJcmV0dXJuOwogICAgc29jay0+cG1hc2sgJj0gfnJlcS0+bWFzazsgLyogaXMgdGhpcyBzYWZlPyAqLwogICAgc29jay0+aG1hc2sgJj0gfnJlcS0+bWFzazsKICAgIHNvY2stPnN0YXRlIHw9IHJlcS0+c3N0YXRlOwogICAgc29jay0+c3RhdGUgJj0gfnJlcS0+Y3N0YXRlOwogICAgc29ja19yZXNlbGVjdCggc29jayApOwoKICAgIC8qIHNlcnZpY2UgdHJpZ2dlciAqLwogICAgaWYgKHJlcS0+bWFzayAmIEZEX1dJTkVfU0VSVkVWRU5UKQogICAgewogICAgICAgIHNvY2stPnBtYXNrIHw9IEZEX1dJTkVfU0VSVkVWRU5UOwogICAgICAgIGlmIChzb2NrLT5ldmVudCkgewogICAgICAgICAgICBpZiAoZGVidWdfbGV2ZWwpIGZwcmludGYoc3RkZXJyLCAic2lnbmFsbGluZyBzZXJ2aWNlIGV2ZW50IHB0ciAlcFxuIiwgc29jay0+ZXZlbnQpOwogICAgICAgICAgICBzZXRfZXZlbnQoc29jay0+ZXZlbnQpOwogICAgICAgIH0KICAgIH0KCiAgICByZWxlYXNlX29iamVjdCggJnNvY2stPm9iaiApOwp9Cg==