LyoKICogU2VydmVyLXNpZGUgc29ja2V0IG1hbmFnZW1lbnQKICoKICogQ29weXJpZ2h0IChDKSAxOTk5IE1hcmN1cyBNZWlzc25lciwgT3ZlIEvldmVuCiAqCiAqIEZJWE1FOiB3ZSB1c2UgcmVhZHx3cml0ZSBhY2Nlc3MgaW4gYWxsIGNhc2VzLiBTaG91bGRuJ3Qgd2UgZGVwZW5kIHRoYXQKICogb24gdGhlIGFjY2VzcyBvZiB0aGUgY3VycmVudCBoYW5kbGU/CiAqLwoKI2luY2x1ZGUgImNvbmZpZy5oIgoKI2luY2x1ZGUgPGFzc2VydC5oPgojaW5jbHVkZSA8ZmNudGwuaD4KI2luY2x1ZGUgPHN0ZGlvLmg+CiNpbmNsdWRlIDxzdHJpbmcuaD4KI2luY2x1ZGUgPHN0ZGxpYi5oPgojaW5jbHVkZSA8ZXJybm8uaD4KI2lmZGVmIEhBVkVfU1lTX0VSUk5PX0gKIyBpbmNsdWRlIDxzeXMvZXJybm8uaD4KI2VuZGlmCiNpbmNsdWRlIDxzeXMvc3RhdC5oPgojaW5jbHVkZSA8c3lzL3RpbWUuaD4KI2luY2x1ZGUgPHN5cy90eXBlcy5oPgojaWZkZWYgSEFWRV9TWVNfU09DS0VUX0gKIyBpbmNsdWRlIDxzeXMvc29ja2V0Lmg+CiNlbmRpZgojaW5jbHVkZSA8c3lzL2lvY3RsLmg+CiNpZmRlZiBIQVZFX1NZU19GSUxJT19ICiMgaW5jbHVkZSA8c3lzL2ZpbGlvLmg+CiNlbmRpZgojaW5jbHVkZSA8dGltZS5oPgojaW5jbHVkZSA8dW5pc3RkLmg+CgojaW5jbHVkZSAid2luZXJyb3IuaCIKI2luY2x1ZGUgIndpbmJhc2UuaCIKI2luY2x1ZGUgIndpbnNvY2syLmgiCiNpbmNsdWRlICJwcm9jZXNzLmgiCiNpbmNsdWRlICJoYW5kbGUuaCIKI2luY2x1ZGUgInRocmVhZC5oIgojaW5jbHVkZSAicmVxdWVzdC5oIgoKc3RydWN0IHNvY2sKewogICAgc3RydWN0IG9iamVjdCAgICAgICBvYmo7ICAgICAgICAgLyogb2JqZWN0IGhlYWRlciAqLwogICAgdW5zaWduZWQgaW50ICAgICAgICBzdGF0ZTsgICAgICAgLyogc3RhdHVzIGJpdHMgKi8KICAgIHVuc2lnbmVkIGludCAgICAgICAgbWFzazsgICAgICAgIC8qIGV2ZW50IG1hc2sgKi8KICAgIHVuc2lnbmVkIGludCAgICAgICAgaG1hc2s7ICAgICAgIC8qIGhlbGQgKGJsb2NrZWQpIGV2ZW50cyAqLwogICAgdW5zaWduZWQgaW50ICAgICAgICBwbWFzazsgICAgICAgLyogcGVuZGluZyBldmVudHMgKi8KICAgIHN0cnVjdCBldmVudCAgICAgICAqZXZlbnQ7ICAgICAgIC8qIGV2ZW50IG9iamVjdCAqLwogICAgaW50ICAgICAgICAgICAgICAgICBlcnJvcnNbRkRfTUFYX0VWRU5UU107IC8qIGV2ZW50IGVycm9ycyAqLwp9OwoKc3RhdGljIHZvaWQgc29ja19kdW1wKCBzdHJ1Y3Qgb2JqZWN0ICpvYmosIGludCB2ZXJib3NlICk7CnN0YXRpYyBpbnQgc29ja19zaWduYWxlZCggc3RydWN0IG9iamVjdCAqb2JqLCBzdHJ1Y3QgdGhyZWFkICp0aHJlYWQgKTsKc3RhdGljIGludCBzb2NrX2dldF9wb2xsX2V2ZW50cyggc3RydWN0IG9iamVjdCAqb2JqICk7CnN0YXRpYyB2b2lkIHNvY2tfcG9sbF9ldmVudCggc3RydWN0IG9iamVjdCAqb2JqLCBpbnQgZXZlbnQgKTsKc3RhdGljIGludCBzb2NrX2dldF9mZCggc3RydWN0IG9iamVjdCAqb2JqICk7CnN0YXRpYyB2b2lkIHNvY2tfZGVzdHJveSggc3RydWN0IG9iamVjdCAqb2JqICk7CnN0YXRpYyB2b2lkIHNvY2tfc2V0X2Vycm9yKHZvaWQpOwoKc3RhdGljIGNvbnN0IHN0cnVjdCBvYmplY3Rfb3BzIHNvY2tfb3BzID0KewogICAgc2l6ZW9mKHN0cnVjdCBzb2NrKSwgICAgICAgICAgLyogc2l6ZSAqLwogICAgc29ja19kdW1wLCAgICAgICAgICAgICAgICAgICAgLyogZHVtcCAqLwogICAgYWRkX3F1ZXVlLCAgICAgICAgICAgICAgICAgICAgLyogYWRkX3F1ZXVlICovCiAgICByZW1vdmVfcXVldWUsICAgICAgICAgICAgICAgICAvKiByZW1vdmVfcXVldWUgKi8KICAgIHNvY2tfc2lnbmFsZWQsICAgICAgICAgICAgICAgIC8qIHNpZ25hbGVkICovCiAgICBub19zYXRpc2ZpZWQsICAgICAgICAgICAgICAgICAvKiBzYXRpc2ZpZWQgKi8KICAgIHNvY2tfZ2V0X3BvbGxfZXZlbnRzLCAgICAgICAgIC8qIGdldF9wb2xsX2V2ZW50cyAqLwogICAgc29ja19wb2xsX2V2ZW50LCAgICAgICAgICAgICAgLyogcG9sbF9ldmVudCAqLwogICAgc29ja19nZXRfZmQsICAgICAgICAgICAgICAgICAgLyogZ2V0X3JlYWRfZmQgKi8KICAgIHNvY2tfZ2V0X2ZkLCAgICAgICAgICAgICAgICAgIC8qIGdldF93cml0ZV9mZCAqLwogICAgbm9fZmx1c2gsICAgICAgICAgICAgICAgICAgICAgLyogZmx1c2ggKi8KICAgIG5vX2dldF9maWxlX2luZm8sICAgICAgICAgICAgIC8qIGdldF9maWxlX2luZm8gKi8KICAgIHNvY2tfZGVzdHJveSAgICAgICAgICAgICAgICAgIC8qIGRlc3Ryb3kgKi8KfTsKCnN0YXRpYyB2b2lkIHNvY2tfcmVzZWxlY3QoIHN0cnVjdCBzb2NrICpzb2NrICkKewogICAgaW50IGV2ID0gc29ja19nZXRfcG9sbF9ldmVudHMoICZzb2NrLT5vYmogKTsKICAgIGlmIChkZWJ1Z19sZXZlbCkKICAgICAgICBmcHJpbnRmKHN0ZGVyciwic29ja19yZXNlbGVjdCglZCk6IG5ldyBtYXNrICV4XG4iLCBzb2NrLT5vYmouZmQsIGV2KTsKICAgIHNldF9zZWxlY3RfZXZlbnRzKCAmc29jay0+b2JqLCBldiApOwp9CgppbmxpbmUgc3RhdGljIGludCBzb2NrX2Vycm9yKGludCBzKQp7CiAgICB1bnNpZ25lZCBpbnQgb3B0dmFsLCBvcHRsZW47CiAgICAKICAgIG9wdGxlbiA9IHNpemVvZihvcHR2YWwpOwogICAgZ2V0c29ja29wdChzLCBTT0xfU09DS0VULCBTT19FUlJPUiwgKHZvaWQgKikgJm9wdHZhbCwgJm9wdGxlbik7CiAgICByZXR1cm4gb3B0dmFsOwp9CgpzdGF0aWMgdm9pZCBzb2NrX3BvbGxfZXZlbnQoIHN0cnVjdCBvYmplY3QgKm9iaiwgaW50IGV2ZW50ICkKewogICAgc3RydWN0IHNvY2sgKnNvY2sgPSAoc3RydWN0IHNvY2sgKilvYmo7CiAgICB1bnNpZ25lZCBpbnQgZW1hc2s7CiAgICBhc3NlcnQoIHNvY2stPm9iai5vcHMgPT0gJnNvY2tfb3BzICk7CiAgICBpZiAoZGVidWdfbGV2ZWwpCiAgICAgICAgZnByaW50ZihzdGRlcnIsICJzb2NrZXQgJWQgc2VsZWN0IGV2ZW50OiAleFxuIiwgc29jay0+b2JqLmZkLCBldmVudCk7CiAgICBpZiAoc29jay0+c3RhdGUgJiBXU19GRF9DT05ORUNUKQogICAgewogICAgICAgIC8qIGNvbm5lY3RpbmcgKi8KICAgICAgICBpZiAoZXZlbnQgJiBQT0xMT1VUKQogICAgICAgIHsKICAgICAgICAgICAgLyogd2UgZ290IGNvbm5lY3RlZCAqLwogICAgICAgICAgICBzb2NrLT5zdGF0ZSB8PSBXU19GRF9DT05ORUNURUR8V1NfRkRfUkVBRHxXU19GRF9XUklURTsKICAgICAgICAgICAgc29jay0+c3RhdGUgJj0gfldTX0ZEX0NPTk5FQ1Q7CiAgICAgICAgICAgIHNvY2stPnBtYXNrIHw9IEZEX0NPTk5FQ1Q7CiAgICAgICAgICAgIHNvY2stPmVycm9yc1tGRF9DT05ORUNUX0JJVF0gPSAwOwogICAgICAgICAgICBpZiAoZGVidWdfbGV2ZWwpCiAgICAgICAgICAgICAgICBmcHJpbnRmKHN0ZGVyciwgInNvY2tldCAlZCBjb25uZWN0aW9uIHN1Y2Nlc3NcbiIsIHNvY2stPm9iai5mZCk7CiAgICAgICAgfQogICAgICAgIGVsc2UgaWYgKGV2ZW50ICYgKFBPTExFUlJ8UE9MTEhVUCkpCiAgICAgICAgewogICAgICAgICAgICAvKiB3ZSBkaWRuJ3QgZ2V0IGNvbm5lY3RlZD8gKi8KICAgICAgICAgICAgc29jay0+c3RhdGUgJj0gfldTX0ZEX0NPTk5FQ1Q7CiAgICAgICAgICAgIHNvY2stPnBtYXNrIHw9IEZEX0NPTk5FQ1Q7CiAgICAgICAgICAgIHNvY2stPmVycm9yc1tGRF9DT05ORUNUX0JJVF0gPSBzb2NrX2Vycm9yKCBzb2NrLT5vYmouZmQgKTsKICAgICAgICAgICAgaWYgKGRlYnVnX2xldmVsKQogICAgICAgICAgICAgICAgZnByaW50ZihzdGRlcnIsICJzb2NrZXQgJWQgY29ubmVjdGlvbiBmYWlsdXJlXG4iLCBzb2NrLT5vYmouZmQpOwogICAgICAgIH0KICAgIH0gZWxzZQogICAgaWYgKHNvY2stPnN0YXRlICYgV1NfRkRfTElTVEVOSU5HKQogICAgewogICAgICAgIC8qIGxpc3RlbmluZyAqLwogICAgICAgIGlmIChldmVudCAmIFBPTExJTikKICAgICAgICB7CiAgICAgICAgICAgIC8qIGluY29taW5nIGNvbm5lY3Rpb24gKi8KICAgICAgICAgICAgc29jay0+cG1hc2sgfD0gRkRfQUNDRVBUOwogICAgICAgICAgICBzb2NrLT5lcnJvcnNbRkRfQUNDRVBUX0JJVF0gPSAwOwogICAgICAgICAgICBzb2NrLT5obWFzayB8PSBGRF9BQ0NFUFQ7CiAgICAgICAgfQogICAgICAgIGVsc2UgaWYgKGV2ZW50ICYgKFBPTExFUlJ8UE9MTEhVUCkpCiAgICAgICAgewogICAgICAgICAgICAvKiBmYWlsZWQgaW5jb21pbmcgY29ubmVjdGlvbj8gKi8KICAgICAgICAgICAgc29jay0+cG1hc2sgfD0gRkRfQUNDRVBUOwogICAgICAgICAgICBzb2NrLT5lcnJvcnNbRkRfQUNDRVBUX0JJVF0gPSBzb2NrX2Vycm9yKCBzb2NrLT5vYmouZmQgKTsKICAgICAgICAgICAgc29jay0+aG1hc2sgfD0gRkRfQUNDRVBUOwogICAgICAgIH0KICAgIH0gZWxzZQogICAgewogICAgICAgIC8qIG5vcm1hbCBkYXRhIGZsb3cgKi8KICAgICAgICBpZiAoZXZlbnQgJiBQT0xMSU4pCiAgICAgICAgewogICAgICAgICAgICAvKiBpbmNvbWluZyBkYXRhICovCiAgICAgICAgICAgIHNvY2stPnBtYXNrIHw9IEZEX1JFQUQ7CiAgICAgICAgICAgIHNvY2stPmhtYXNrIHw9IEZEX1JFQUQ7CiAgICAgICAgICAgIHNvY2stPmVycm9yc1tGRF9SRUFEX0JJVF0gPSAwOwogICAgICAgICAgICBpZiAoZGVidWdfbGV2ZWwpCiAgICAgICAgICAgICAgICBmcHJpbnRmKHN0ZGVyciwgInNvY2tldCAlZCBpcyByZWFkYWJsZVxuIiwgc29jay0+b2JqLmZkICk7CiAgICAgICAgfQogICAgICAgIGlmIChldmVudCAmIFBPTExPVVQpCiAgICAgICAgewogICAgICAgICAgICBzb2NrLT5wbWFzayB8PSBGRF9XUklURTsKICAgICAgICAgICAgc29jay0+aG1hc2sgfD0gRkRfV1JJVEU7CiAgICAgICAgICAgIHNvY2stPmVycm9yc1tGRF9XUklURV9CSVRdID0gMDsKICAgICAgICAgICAgaWYgKGRlYnVnX2xldmVsKQogICAgICAgICAgICAgICAgZnByaW50ZihzdGRlcnIsICJzb2NrZXQgJWQgaXMgd3JpdGFibGVcbiIsIHNvY2stPm9iai5mZCk7CiAgICAgICAgfQogICAgICAgIGlmIChldmVudCAmIFBPTExQUkkpCiAgICAgICAgewogICAgICAgICAgICBzb2NrLT5wbWFzayB8PSBGRF9PT0I7CiAgICAgICAgICAgIHNvY2stPmhtYXNrIHw9IEZEX09PQjsKICAgICAgICAgICAgaWYgKGRlYnVnX2xldmVsKQogICAgICAgICAgICAgICAgZnByaW50ZihzdGRlcnIsICJzb2NrZXQgJWQgZ290IE9PQiBkYXRhXG4iLCBzb2NrLT5vYmouZmQpOwogICAgICAgIH0KICAgICAgICBpZiAoZXZlbnQgJiAoUE9MTEVSUnxQT0xMSFVQKSkKICAgICAgICB7CiAgICAgICAgICAgIHNvY2stPmVycm9yc1tGRF9DTE9TRV9CSVRdID0gc29ja19lcnJvciggc29jay0+b2JqLmZkICk7CiAgICAgICAgICAgIC8qIHdlIGdvdCBhbiBlcnJvciwgc29ja2V0IGNsb3Npbmc/ICovCiAgICAgICAgICAgIHNvY2stPnN0YXRlICY9IH4oV1NfRkRfQ09OTkVDVEVEfFdTX0ZEX1JFQUR8V1NfRkRfV1JJVEUpOwogICAgICAgICAgICBzb2NrLT5wbWFzayB8PSBGRF9DTE9TRTsKICAgICAgICAgICAgaWYgKGRlYnVnX2xldmVsKQogICAgICAgICAgICAgICAgZnByaW50ZihzdGRlcnIsICJzb2NrZXQgJWQgYWJvcnRlZCBieSBlcnJvciAlZFxuIiwKICAgICAgICAgICAgICAgICAgICAgICAgc29jay0+b2JqLmZkLCBzb2NrLT5lcnJvcnNbRkRfQ0xPU0VfQklUXSk7CiAgICAgICAgfQogICAgfQoKICAgIHNvY2tfcmVzZWxlY3QoIHNvY2sgKTsKICAgIC8qIHdha2UgdXAgYW55b25lIHdhaXRpbmcgZm9yIHdoYXRldmVyIGp1c3QgaGFwcGVuZWQgKi8KICAgIGVtYXNrID0gc29jay0+cG1hc2sgJiBzb2NrLT5tYXNrOwogICAgaWYgKGRlYnVnX2xldmVsICYmIGVtYXNrKQogICAgICAgIGZwcmludGYoc3RkZXJyLCAic29ja2V0ICVkIHBlbmRpbmcgZXZlbnRzOiAleFxuIiwgc29jay0+b2JqLmZkLCBlbWFzayk7CiAgICBpZiAoZW1hc2sgJiYgc29jay0+ZXZlbnQpIHsKICAgICAgICBpZiAoZGVidWdfbGV2ZWwpIGZwcmludGYoc3RkZXJyLCAic2lnbmFsbGluZyBldmVudCBwdHIgJXBcbiIsIHNvY2stPmV2ZW50KTsKICAgICAgICBzZXRfZXZlbnQoc29jay0+ZXZlbnQpOwogICAgfQoKICAgIC8qIGlmIGFueW9uZSBpcyBzdHVwaWQgZW5vdWdoIHRvIHdhaXQgb24gdGhlIHNvY2tldCBvYmplY3QgaXRzZWxmLAogICAgICogbWF5YmUgd2Ugc2hvdWxkIHdha2UgdGhlbSB1cCB0b28sIGp1c3QgaW4gY2FzZT8gKi8KICAgIHdha2VfdXAoICZzb2NrLT5vYmosIDAgKTsKfQoKc3RhdGljIHZvaWQgc29ja19kdW1wKCBzdHJ1Y3Qgb2JqZWN0ICpvYmosIGludCB2ZXJib3NlICkKewogICAgc3RydWN0IHNvY2sgKnNvY2sgPSAoc3RydWN0IHNvY2sgKilvYmo7CiAgICBhc3NlcnQoIG9iai0+b3BzID09ICZzb2NrX29wcyApOwogICAgcHJpbnRmKCAiU29ja2V0IGZkPSVkLCBzdGF0ZT0leCwgbWFzaz0leCwgcGVuZGluZz0leCwgaGVsZD0leFxuIiwKICAgICAgICAgICAgc29jay0+b2JqLmZkLCBzb2NrLT5zdGF0ZSwKICAgICAgICAgICAgc29jay0+bWFzaywgc29jay0+cG1hc2ssIHNvY2stPmhtYXNrICk7Cn0KCnN0YXRpYyBpbnQgc29ja19zaWduYWxlZCggc3RydWN0IG9iamVjdCAqb2JqLCBzdHJ1Y3QgdGhyZWFkICp0aHJlYWQgKQp7CiAgICBzdHJ1Y3Qgc29jayAqc29jayA9IChzdHJ1Y3Qgc29jayAqKW9iajsKICAgIGFzc2VydCggb2JqLT5vcHMgPT0gJnNvY2tfb3BzICk7CgogICAgcmV0dXJuIGNoZWNrX3NlbGVjdF9ldmVudHMoIHNvY2stPm9iai5mZCwgc29ja19nZXRfcG9sbF9ldmVudHMoICZzb2NrLT5vYmogKSApOwp9CgpzdGF0aWMgaW50IHNvY2tfZ2V0X3BvbGxfZXZlbnRzKCBzdHJ1Y3Qgb2JqZWN0ICpvYmogKQp7CiAgICBzdHJ1Y3Qgc29jayAqc29jayA9IChzdHJ1Y3Qgc29jayAqKW9iajsKICAgIHVuc2lnbmVkIGludCBtYXNrID0gc29jay0+bWFzayAmIHNvY2stPnN0YXRlICYgfnNvY2stPmhtYXNrOwogICAgaW50IGV2ID0gMDsKCiAgICBhc3NlcnQoIG9iai0+b3BzID09ICZzb2NrX29wcyApOwoKICAgIGlmIChzb2NrLT5zdGF0ZSAmIFdTX0ZEX0NPTk5FQ1QpCiAgICAgICAgLyogY29ubmVjdGluZywgd2FpdCBmb3Igd3JpdGFibGUgKi8KICAgICAgICByZXR1cm4gUE9MTE9VVDsKICAgIGlmIChzb2NrLT5zdGF0ZSAmIFdTX0ZEX0xJU1RFTklORykKICAgICAgICAvKiBsaXN0ZW5pbmcsIHdhaXQgZm9yIHJlYWRhYmxlICovCiAgICAgICAgcmV0dXJuIChzb2NrLT5obWFzayAmIEZEX0FDQ0VQVCkgPyAwIDogUE9MTElOOwoKICAgIGlmIChtYXNrICYgRkRfUkVBRCkgIGV2IHw9IFBPTExJTiB8IFBPTExQUkk7CiAgICBpZiAobWFzayAmIEZEX1dSSVRFKSBldiB8PSBQT0xMT1VUOwogICAgcmV0dXJuIGV2Owp9CgpzdGF0aWMgaW50IHNvY2tfZ2V0X2ZkKCBzdHJ1Y3Qgb2JqZWN0ICpvYmogKQp7CiAgICBzdHJ1Y3Qgc29jayAqc29jayA9IChzdHJ1Y3Qgc29jayAqKW9iajsKICAgIGludCBmZDsKICAgIGFzc2VydCggb2JqLT5vcHMgPT0gJnNvY2tfb3BzICk7CiAgICBmZCA9IGR1cCggc29jay0+b2JqLmZkICk7CiAgICBpZiAoZmQ9PS0xKQogICAgCXNvY2tfc2V0X2Vycm9yKCk7CiAgICByZXR1cm4gZmQ7Cn0KCnN0YXRpYyB2b2lkIHNvY2tfZGVzdHJveSggc3RydWN0IG9iamVjdCAqb2JqICkKewogICAgc3RydWN0IHNvY2sgKnNvY2sgPSAoc3RydWN0IHNvY2sgKilvYmo7CiAgICBhc3NlcnQoIG9iai0+b3BzID09ICZzb2NrX29wcyApOwoKICAgIC8qIEZJWE1FOiBzcGVjaWFsIHNvY2tldCBzaHV0ZG93biBzdHVmZj8gKi8KICAgIGlmIChzb2NrLT5ldmVudCkKICAgIHsKICAgICAgICAvKiBpZiB0aGUgc2VydmljZSB0aHJlYWQgd2FzIHdhaXRpbmcgZm9yIHRoZSBldmVudCBvYmplY3QsCiAgICAgICAgICogd2Ugc2hvdWxkIG5vdyBzaWduYWwgaXQsIHRvIGxldCB0aGUgc2VydmljZSB0aHJlYWQKICAgICAgICAgKiBvYmplY3QgZGV0ZWN0IHRoYXQgaXQgaXMgbm93IG9ycGhhbmVkLi4uICovCiAgICAgICAgaWYgKHNvY2stPm1hc2sgJiBXU19GRF9TRVJWRVZFTlQpCiAgICAgICAgICAgIHNldF9ldmVudCggc29jay0+ZXZlbnQgKTsKICAgICAgICAvKiB3ZSdyZSB0aHJvdWdoIHdpdGggaXQgKi8KICAgICAgICByZWxlYXNlX29iamVjdCggc29jay0+ZXZlbnQgKTsKICAgIH0KfQoKLyogY3JlYXRlIGEgbmV3IGFuZCB1bmNvbm5lY3RlZCBzb2NrZXQgKi8Kc3RhdGljIHN0cnVjdCBvYmplY3QgKmNyZWF0ZV9zb2NrZXQoIGludCBmYW1pbHksIGludCB0eXBlLCBpbnQgcHJvdG9jb2wgKQp7CiAgICBzdHJ1Y3Qgc29jayAqc29jazsKICAgIGludCBzb2NrZmQ7CgogICAgc29ja2ZkID0gc29ja2V0KCBmYW1pbHksIHR5cGUsIHByb3RvY29sICk7CiAgICBpZiAoZGVidWdfbGV2ZWwpCiAgICAgICAgZnByaW50ZihzdGRlcnIsInNvY2tldCglZCwlZCwlZCk9JWRcbiIsZmFtaWx5LHR5cGUscHJvdG9jb2wsc29ja2ZkKTsKICAgIGlmIChzb2NrZmQgPT0gLTEpIHsKICAgICAgICBzb2NrX3NldF9lcnJvcigpOwogICAgICAgIHJldHVybiBOVUxMOwogICAgfQogICAgZmNudGwoc29ja2ZkLCBGX1NFVEZMLCBPX05PTkJMT0NLKTsgLyogbWFrZSBzb2NrZXQgbm9uYmxvY2tpbmcgKi8KICAgIGlmICghKHNvY2sgPSBhbGxvY19vYmplY3QoICZzb2NrX29wcywgc29ja2ZkICkpKSByZXR1cm4gTlVMTDsKICAgIHNvY2stPnN0YXRlID0gKHR5cGUhPVNPQ0tfU1RSRUFNKSA/IFdTX0ZEX1JFQUR8V1NfRkRfV1JJVEUgOiAwOwogICAgc29jay0+bWFzayAgPSAwOwogICAgc29jay0+aG1hc2sgPSAwOwogICAgc29jay0+cG1hc2sgPSAwOwogICAgc29jay0+ZXZlbnQgPSBOVUxMOwogICAgc29ja19yZXNlbGVjdCggc29jayApOwogICAgY2xlYXJfZXJyb3IoKTsKICAgIHJldHVybiAmc29jay0+b2JqOwp9CgovKiBhY2NlcHQgYSBzb2NrZXQgKGNyZWF0ZXMgYSBuZXcgZmQpICovCnN0YXRpYyBzdHJ1Y3Qgb2JqZWN0ICphY2NlcHRfc29ja2V0KCBpbnQgaGFuZGxlICkKewogICAgc3RydWN0IHNvY2sgKmFjY2VwdHNvY2s7CiAgICBzdHJ1Y3Qgc29jayAqc29jazsKICAgIGludAlhY2NlcHRmZDsKICAgIHN0cnVjdCBzb2NrYWRkcglzYWRkcjsKICAgIGludAkJCXNsZW47CgogICAgc29jaz0oc3RydWN0IHNvY2sqKWdldF9oYW5kbGVfb2JqKGN1cnJlbnQtPnByb2Nlc3MsaGFuZGxlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEdFTkVSSUNfUkVBRHxHRU5FUklDX1dSSVRFfFNZTkNIUk9OSVpFLCZzb2NrX29wcyk7CiAgICBpZiAoIXNvY2spCiAgICAJcmV0dXJuIE5VTEw7CiAgICAvKiBUcnkgdG8gYWNjZXB0KDIpLiBXZSBjYW4ndCBiZSBzYWZlIHRoYXQgdGhpcyBhbiBhbHJlYWR5IGNvbm5lY3RlZCBzb2NrZXQgCiAgICAgKiBvciB0aGF0IGFjY2VwdCgpIGlzIGFsbG93ZWQgb24gaXQuIEluIHRob3NlIGNhc2VzIHdlIHdpbGwgZ2V0IC0xL2Vycm5vCiAgICAgKiByZXR1cm4uCiAgICAgKi8KICAgIHNsZW4gPSBzaXplb2Yoc2FkZHIpOwogICAgYWNjZXB0ZmQgPSBhY2NlcHQoc29jay0+b2JqLmZkLCZzYWRkciwmc2xlbik7CiAgICBpZiAoYWNjZXB0ZmQ9PS0xKSB7CiAgICAJc29ja19zZXRfZXJyb3IoKTsKICAgICAgICByZWxlYXNlX29iamVjdCggc29jayApOwoJcmV0dXJuIE5VTEw7CiAgICB9CiAgICBpZiAoIShhY2NlcHRzb2NrID0gYWxsb2Nfb2JqZWN0KCAmc29ja19vcHMsIGFjY2VwdGZkICkpKQogICAgewogICAgICAgIHJlbGVhc2Vfb2JqZWN0KCBzb2NrICk7CiAgICAgICAgcmV0dXJuIE5VTEw7CiAgICB9CgogICAgYWNjZXB0c29jay0+c3RhdGUgID0gV1NfRkRfQ09OTkVDVEVEfFdTX0ZEX1JFQUR8V1NfRkRfV1JJVEU7CiAgICBhY2NlcHRzb2NrLT5tYXNrICAgPSBzb2NrLT5tYXNrOwogICAgYWNjZXB0c29jay0+aG1hc2sgID0gMDsKICAgIGFjY2VwdHNvY2stPnBtYXNrICA9IDA7CiAgICBhY2NlcHRzb2NrLT5ldmVudCAgPSBOVUxMOwogICAgaWYgKHNvY2stPmV2ZW50KSBhY2NlcHRzb2NrLT5ldmVudCA9IChzdHJ1Y3QgZXZlbnQgKilncmFiX29iamVjdCggc29jay0+ZXZlbnQgKTsKCiAgICBzb2NrX3Jlc2VsZWN0KCBhY2NlcHRzb2NrICk7CiAgICBjbGVhcl9lcnJvcigpOwogICAgc29jay0+cG1hc2sgJj0gfkZEX0FDQ0VQVDsKICAgIHNvY2stPmhtYXNrICY9IH5GRF9BQ0NFUFQ7CiAgICByZWxlYXNlX29iamVjdCggc29jayApOwogICAgcmV0dXJuICZhY2NlcHRzb2NrLT5vYmo7Cn0KCi8qIHNldCB0aGUgbGFzdCBlcnJvciBkZXBlbmRpbmcgb24gZXJybm8gKi8Kc3RhdGljIHZvaWQgc29ja19zZXRfZXJyb3Iodm9pZCkKewogICAgc3dpdGNoIChlcnJubykKICAgIHsKICAgICAgICBjYXNlIEVJTlRSOiAgICAgICAgICAgICBzZXRfZXJyb3IoV1NBRUlOVFIpO2JyZWFrOwogICAgICAgIGNhc2UgRUJBREY6ICAgICAgICAgICAgIHNldF9lcnJvcihXU0FFQkFERik7YnJlYWs7CiAgICAgICAgY2FzZSBFUEVSTToKICAgICAgICBjYXNlIEVBQ0NFUzogICAgICAgICAgICBzZXRfZXJyb3IoV1NBRUFDQ0VTKTticmVhazsKICAgICAgICBjYXNlIEVGQVVMVDogICAgICAgICAgICBzZXRfZXJyb3IoV1NBRUZBVUxUKTticmVhazsKICAgICAgICBjYXNlIEVJTlZBTDogICAgICAgICAgICBzZXRfZXJyb3IoV1NBRUlOVkFMKTticmVhazsKICAgICAgICBjYXNlIEVNRklMRTogICAgICAgICAgICBzZXRfZXJyb3IoV1NBRU1GSUxFKTticmVhazsKICAgICAgICBjYXNlIEVXT1VMREJMT0NLOiAgICAgICBzZXRfZXJyb3IoV1NBRVdPVUxEQkxPQ0spO2JyZWFrOwogICAgICAgIGNhc2UgRUlOUFJPR1JFU1M6ICAgICAgIHNldF9lcnJvcihXU0FFSU5QUk9HUkVTUyk7YnJlYWs7CiAgICAgICAgY2FzZSBFQUxSRUFEWTogICAgICAgICAgc2V0X2Vycm9yKFdTQUVBTFJFQURZKTticmVhazsKICAgICAgICBjYXNlIEVOT1RTT0NLOiAgICAgICAgICBzZXRfZXJyb3IoV1NBRU5PVFNPQ0spO2JyZWFrOwogICAgICAgIGNhc2UgRURFU1RBRERSUkVROiAgICAgIHNldF9lcnJvcihXU0FFREVTVEFERFJSRVEpO2JyZWFrOwogICAgICAgIGNhc2UgRU1TR1NJWkU6ICAgICAgICAgIHNldF9lcnJvcihXU0FFTVNHU0laRSk7YnJlYWs7CiAgICAgICAgY2FzZSBFUFJPVE9UWVBFOiAgICAgICAgc2V0X2Vycm9yKFdTQUVQUk9UT1RZUEUpO2JyZWFrOwogICAgICAgIGNhc2UgRU5PUFJPVE9PUFQ6ICAgICAgIHNldF9lcnJvcihXU0FFTk9QUk9UT09QVCk7YnJlYWs7CiAgICAgICAgY2FzZSBFUFJPVE9OT1NVUFBPUlQ6ICAgc2V0X2Vycm9yKFdTQUVQUk9UT05PU1VQUE9SVCk7YnJlYWs7CiAgICAgICAgY2FzZSBFU09DS1ROT1NVUFBPUlQ6ICAgc2V0X2Vycm9yKFdTQUVTT0NLVE5PU1VQUE9SVCk7YnJlYWs7CiAgICAgICAgY2FzZSBFT1BOT1RTVVBQOiAgICAgICAgc2V0X2Vycm9yKFdTQUVPUE5PVFNVUFApO2JyZWFrOwogICAgICAgIGNhc2UgRVBGTk9TVVBQT1JUOiAgICAgIHNldF9lcnJvcihXU0FFUEZOT1NVUFBPUlQpO2JyZWFrOwogICAgICAgIGNhc2UgRUFGTk9TVVBQT1JUOiAgICAgIHNldF9lcnJvcihXU0FFQUZOT1NVUFBPUlQpO2JyZWFrOwogICAgICAgIGNhc2UgRUFERFJJTlVTRTogICAgICAgIHNldF9lcnJvcihXU0FFQUREUklOVVNFKTticmVhazsKICAgICAgICBjYXNlIEVBRERSTk9UQVZBSUw6ICAgICBzZXRfZXJyb3IoV1NBRUFERFJOT1RBVkFJTCk7YnJlYWs7CiAgICAgICAgY2FzZSBFTkVURE9XTjogICAgICAgICAgc2V0X2Vycm9yKFdTQUVORVRET1dOKTticmVhazsKICAgICAgICBjYXNlIEVORVRVTlJFQUNIOiAgICAgICBzZXRfZXJyb3IoV1NBRU5FVFVOUkVBQ0gpO2JyZWFrOwogICAgICAgIGNhc2UgRU5FVFJFU0VUOiAgICAgICAgIHNldF9lcnJvcihXU0FFTkVUUkVTRVQpO2JyZWFrOwogICAgICAgIGNhc2UgRUNPTk5BQk9SVEVEOiAgICAgIHNldF9lcnJvcihXU0FFQ09OTkFCT1JURUQpO2JyZWFrOwogICAgICAgIGNhc2UgRVBJUEU6CiAgICAgICAgY2FzZSBFQ09OTlJFU0VUOiAgICAgICAgc2V0X2Vycm9yKFdTQUVDT05OUkVTRVQpO2JyZWFrOwogICAgICAgIGNhc2UgRU5PQlVGUzogICAgICAgICAgIHNldF9lcnJvcihXU0FFTk9CVUZTKTticmVhazsKICAgICAgICBjYXNlIEVJU0NPTk46ICAgICAgICAgICBzZXRfZXJyb3IoV1NBRUlTQ09OTik7YnJlYWs7CiAgICAgICAgY2FzZSBFTk9UQ09OTjogICAgICAgICAgc2V0X2Vycm9yKFdTQUVOT1RDT05OKTticmVhazsKICAgICAgICBjYXNlIEVTSFVURE9XTjogICAgICAgICBzZXRfZXJyb3IoV1NBRVNIVVRET1dOKTticmVhazsKICAgICAgICBjYXNlIEVUT09NQU5ZUkVGUzogICAgICBzZXRfZXJyb3IoV1NBRVRPT01BTllSRUZTKTticmVhazsKICAgICAgICBjYXNlIEVUSU1FRE9VVDogICAgICAgICBzZXRfZXJyb3IoV1NBRVRJTUVET1VUKTticmVhazsKICAgICAgICBjYXNlIEVDT05OUkVGVVNFRDogICAgICBzZXRfZXJyb3IoV1NBRUNPTk5SRUZVU0VEKTticmVhazsKICAgICAgICBjYXNlIEVMT09QOiAgICAgICAgICAgICBzZXRfZXJyb3IoV1NBRUxPT1ApO2JyZWFrOwogICAgICAgIGNhc2UgRU5BTUVUT09MT05HOiAgICAgIHNldF9lcnJvcihXU0FFTkFNRVRPT0xPTkcpO2JyZWFrOwogICAgICAgIGNhc2UgRUhPU1RET1dOOiAgICAgICAgIHNldF9lcnJvcihXU0FFSE9TVERPV04pO2JyZWFrOwogICAgICAgIGNhc2UgRUhPU1RVTlJFQUNIOiAgICAgIHNldF9lcnJvcihXU0FFSE9TVFVOUkVBQ0gpO2JyZWFrOwogICAgICAgIGNhc2UgRU5PVEVNUFRZOiAgICAgICAgIHNldF9lcnJvcihXU0FFTk9URU1QVFkpO2JyZWFrOwojaWZkZWYgRVBST0NMSU0KICAgICAgICBjYXNlIEVQUk9DTElNOiAgICAgICAgICBzZXRfZXJyb3IoV1NBRVBST0NMSU0pO2JyZWFrOwojZW5kaWYKI2lmZGVmIEVVU0VSUwogICAgICAgIGNhc2UgRVVTRVJTOiAgICAgICAgICAgIHNldF9lcnJvcihXU0FFVVNFUlMpO2JyZWFrOwojZW5kaWYKI2lmZGVmIEVEUVVPVAogICAgICAgIGNhc2UgRURRVU9UOiAgICAgICAgICAgIHNldF9lcnJvcihXU0FFRFFVT1QpO2JyZWFrOwojZW5kaWYKI2lmZGVmIEVTVEFMRQogICAgICAgIGNhc2UgRVNUQUxFOiAgICAgICAgICAgIHNldF9lcnJvcihXU0FFU1RBTEUpO2JyZWFrOwojZW5kaWYKI2lmZGVmIEVSRU1PVEUKICAgICAgICBjYXNlIEVSRU1PVEU6ICAgICAgICAgICBzZXRfZXJyb3IoV1NBRVJFTU9URSk7YnJlYWs7CiNlbmRpZgogICAgZGVmYXVsdDogICAgICAgIHBlcnJvcigic29ja19zZXRfZXJyb3IiKTsgc2V0X2Vycm9yKCBFUlJPUl9VTktOT1dOICk7IGJyZWFrOwogICAgfQp9CgovKiBjcmVhdGUgYSBzb2NrZXQgKi8KREVDTF9IQU5ETEVSKGNyZWF0ZV9zb2NrZXQpCnsKICAgIHN0cnVjdCBvYmplY3QgKm9iajsKICAgIGludCBzID0gLTE7CgogICAgaWYgKChvYmogPSBjcmVhdGVfc29ja2V0KCByZXEtPmZhbWlseSwgcmVxLT50eXBlLCByZXEtPnByb3RvY29sICkpICE9IE5VTEwpCiAgICB7CiAgICAgICAgcyA9IGFsbG9jX2hhbmRsZSggY3VycmVudC0+cHJvY2Vzcywgb2JqLCByZXEtPmFjY2VzcywgcmVxLT5pbmhlcml0ICk7CiAgICAgICAgcmVsZWFzZV9vYmplY3QoIG9iaiApOwogICAgfQogICAgcmVxLT5oYW5kbGUgPSBzOwp9CgovKiBhY2NlcHQgYSBzb2NrZXQgKi8KREVDTF9IQU5ETEVSKGFjY2VwdF9zb2NrZXQpCnsKICAgIHN0cnVjdCBvYmplY3QgKm9iajsKICAgIGludCBzID0gLTE7CgogICAgaWYgKChvYmogPSBhY2NlcHRfc29ja2V0KCByZXEtPmxoYW5kbGUgKSkgIT0gTlVMTCkKICAgIHsKICAgICAgICBzID0gYWxsb2NfaGFuZGxlKCBjdXJyZW50LT5wcm9jZXNzLCBvYmosIHJlcS0+YWNjZXNzLCByZXEtPmluaGVyaXQgKTsKICAgICAgICByZWxlYXNlX29iamVjdCggb2JqICk7CiAgICB9CiAgICByZXEtPmhhbmRsZSA9IHM7Cn0KCi8qIHNldCBzb2NrZXQgZXZlbnQgcGFyYW1ldGVycyAqLwpERUNMX0hBTkRMRVIoc2V0X3NvY2tldF9ldmVudCkKewogICAgc3RydWN0IHNvY2sgKnNvY2s7CiAgICBzdHJ1Y3QgZXZlbnQgKm9ldmVudDsKICAgIHVuc2lnbmVkIGludCBvbWFzazsKCiAgICBzb2NrPShzdHJ1Y3Qgc29jayopZ2V0X2hhbmRsZV9vYmooY3VycmVudC0+cHJvY2VzcyxyZXEtPmhhbmRsZSxHRU5FUklDX1JFQUR8R0VORVJJQ19XUklURXxTWU5DSFJPTklaRSwmc29ja19vcHMpOwogICAgaWYgKCFzb2NrKQoJcmV0dXJuOwogICAgb2V2ZW50ID0gc29jay0+ZXZlbnQ7CiAgICBvbWFzayAgPSBzb2NrLT5tYXNrOwogICAgc29jay0+bWFzayAgICA9IHJlcS0+bWFzazsKICAgIHNvY2stPmV2ZW50ICAgPSBnZXRfZXZlbnRfb2JqKCBjdXJyZW50LT5wcm9jZXNzLCByZXEtPmV2ZW50LCBFVkVOVF9NT0RJRllfU1RBVEUgKTsKICAgIGlmIChkZWJ1Z19sZXZlbCAmJiBzb2NrLT5ldmVudCkgZnByaW50ZihzdGRlcnIsICJldmVudCBwdHI6ICVwXG4iLCBzb2NrLT5ldmVudCk7CiAgICBzb2NrX3Jlc2VsZWN0KCBzb2NrICk7CiAgICBpZiAoc29jay0+bWFzaykKICAgICAgICBzb2NrLT5zdGF0ZSB8PSBXU19GRF9OT05CTE9DS0lORzsKICAgIGlmIChvZXZlbnQpCiAgICB7CiAgICAJaWYgKChvZXZlbnQgIT0gc29jay0+ZXZlbnQpICYmIChvbWFzayAmIFdTX0ZEX1NFUlZFVkVOVCkpCiAgICAgICAgICAgIC8qIGlmIHRoZSBzZXJ2aWNlIHRocmVhZCB3YXMgd2FpdGluZyBmb3IgdGhlIG9sZCBldmVudCBvYmplY3QsCiAgICAgICAgICAgICAqIHdlIHNob3VsZCBub3cgc2lnbmFsIGl0LCB0byBsZXQgdGhlIHNlcnZpY2UgdGhyZWFkCiAgICAgICAgICAgICAqIG9iamVjdCBkZXRlY3QgdGhhdCBpdCBpcyBub3cgb3JwaGFuZWQuLi4gKi8KICAgICAgICAgICAgc2V0X2V2ZW50KCBvZXZlbnQgKTsKICAgICAgICAvKiB3ZSdyZSB0aHJvdWdoIHdpdGggaXQgKi8KICAgICAgICByZWxlYXNlX29iamVjdCggb2V2ZW50ICk7CiAgICB9CiAgICByZWxlYXNlX29iamVjdCggJnNvY2stPm9iaiApOwp9CgovKiBnZXQgc29ja2V0IGV2ZW50IHBhcmFtZXRlcnMgKi8KREVDTF9IQU5ETEVSKGdldF9zb2NrZXRfZXZlbnQpCnsKICAgIHN0cnVjdCBzb2NrICpzb2NrOwoKICAgIHNvY2s9KHN0cnVjdCBzb2NrKilnZXRfaGFuZGxlX29iaihjdXJyZW50LT5wcm9jZXNzLHJlcS0+aGFuZGxlLEdFTkVSSUNfUkVBRHxHRU5FUklDX1dSSVRFfFNZTkNIUk9OSVpFLCZzb2NrX29wcyk7CiAgICBpZiAoIXNvY2spCiAgICB7CglyZXEtPm1hc2sgID0gMDsKCXJlcS0+cG1hc2sgPSAwOwoJcmVxLT5zdGF0ZSA9IDA7CglzZXRfZXJyb3IoV1NBRU5PVFNPQ0spOwoJcmV0dXJuOwogICAgfQogICAgcmVxLT5tYXNrICAgID0gc29jay0+bWFzazsKICAgIHJlcS0+cG1hc2sgICA9IHNvY2stPnBtYXNrOwogICAgcmVxLT5zdGF0ZSAgID0gc29jay0+c3RhdGU7CiAgICBtZW1jcHkocmVxLT5lcnJvcnMsIHNvY2stPmVycm9ycywgc2l6ZW9mKHNvY2stPmVycm9ycykpOwogICAgY2xlYXJfZXJyb3IoKTsKICAgIGlmIChyZXEtPnNlcnZpY2UpCiAgICB7CiAgICAgICAgaWYgKHJlcS0+c19ldmVudCkKICAgICAgICB7CiAgICAgICAgICAgIHN0cnVjdCBldmVudCAqc2V2ZW50ID0gZ2V0X2V2ZW50X29iaihjdXJyZW50LT5wcm9jZXNzLCByZXEtPnNfZXZlbnQsIDApOwogICAgICAgICAgICBpZiAoc2V2ZW50ID09IHNvY2stPmV2ZW50KQogICAgICAgICAgICAgICAgcmVxLT5zX2V2ZW50ID0gMDsKICAgICAgICAgICAgcmVsZWFzZV9vYmplY3QoIHNldmVudCApOwogICAgICAgIH0KICAgICAgICBpZiAoIXJlcS0+c19ldmVudCkKICAgICAgICB7CiAgICAgICAgICAgIHNvY2stPnBtYXNrID0gMDsKICAgICAgICAgICAgc29ja19yZXNlbGVjdCggc29jayApOwogICAgICAgIH0KICAgICAgICBlbHNlIHNldF9lcnJvcihXU0FFSU5WQUwpOwogICAgfQogICAgcmVsZWFzZV9vYmplY3QoICZzb2NrLT5vYmogKTsKfQoKLyogcmUtZW5hYmxlIHBlbmRpbmcgc29ja2V0IGV2ZW50cyAqLwpERUNMX0hBTkRMRVIoZW5hYmxlX3NvY2tldF9ldmVudCkKewogICAgc3RydWN0IHNvY2sgKnNvY2s7CgogICAgc29jaz0oc3RydWN0IHNvY2sqKWdldF9oYW5kbGVfb2JqKGN1cnJlbnQtPnByb2Nlc3MscmVxLT5oYW5kbGUsR0VORVJJQ19SRUFEfEdFTkVSSUNfV1JJVEV8U1lOQ0hST05JWkUsJnNvY2tfb3BzKTsKICAgIGlmICghc29jaykKICAgIAlyZXR1cm47CiAgICBzb2NrLT5wbWFzayAmPSB+cmVxLT5tYXNrOyAvKiBpcyB0aGlzIHNhZmU/ICovCiAgICBzb2NrLT5obWFzayAmPSB+cmVxLT5tYXNrOwogICAgc29jay0+c3RhdGUgfD0gcmVxLT5zc3RhdGU7CiAgICBzb2NrLT5zdGF0ZSAmPSB+cmVxLT5jc3RhdGU7CiAgICBzb2NrX3Jlc2VsZWN0KCBzb2NrICk7CiAgICByZWxlYXNlX29iamVjdCggJnNvY2stPm9iaiApOwp9Cg==