LyoKICogQ0FQSSBlbmNvZGVyL2RlY29kZXIgZm9yCiAqIFBvcnR1Z2FsIFRlbGVjb20gQ0FQSSAyLjAKICoKICogQ29weXJpZ2h0IChDKSAxOTk2IFVuaXZlcnNpZGFkZSBkZSBMaXNib2EKICogCiAqIFdyaXR0ZW4gYnkgUGVkcm8gUm9xdWUgTWFycXVlcyAocm9xdWVAZGkuZmMudWwucHQpCiAqCiAqIFRoaXMgc29mdHdhcmUgbWF5IGJlIHVzZWQgYW5kIGRpc3RyaWJ1dGVkIGFjY29yZGluZyB0byB0aGUgdGVybXMgb2YgCiAqIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSwgaW5jb3Jwb3JhdGVkIGhlcmVpbiBieSByZWZlcmVuY2UuCiAqCiAqIE5vdCBjb21wYXRpYmxlIHdpdGggdGhlIEFWTSBHbWJoLiBDQVBJIDIuMAogKgogKi8KCi8qCiAqICAgICAgICBEb2N1bWVudGF0aW9uOgogKiAgICAgICAgLSAiQ29tbW9uIElTRE4gQVBJIC0gUGVyZmlsIFBvcnR1Z3XqcyAtIFZlcnPjbyAyLjEiLAogKiAgICAgICAgICAgVGVsZWNvbSBQb3J0dWdhbCwgRmV2IDE5OTIuCiAqICAgICAgICAtICJDb21tb24gSVNETiBBUEkgLSBFc3BlY2lmaWNh5+NvIGRlIHByb3RvY29sb3MgcGFyYSAKICogICAgICAgICAgIGFjZXNzbyBhb3MgY2FuYWlzIEIiLCBJbmVzYywgSmFuIDE5OTQuCiAqLwoKLyoKICogICAgICAgIFRPRE86IGJldHRlciBkZWNvZGluZyBvZiBJbmZvcm1hdGlvbiBFbGVtZW50cwogKiAgICAgICAgICAgICAgZm9yIGRlYnVnIHB1cnBvc2VzIG1haW5seQogKiAgICAgICAgICAgICAgZW5jb2RlIG91ciBudW1iZXIgaW4gQ2FsbGVyUE4gYW5kIENvbm5lY3RlZFBOCiAqLwoKI2luY2x1ZGUgPGxpbnV4L3NjaGVkLmg+CiNpbmNsdWRlIDxsaW51eC9zdHJpbmcuaD4KI2luY2x1ZGUgPGxpbnV4L2tlcm5lbC5oPgoKI2luY2x1ZGUgPGxpbnV4L3R5cGVzLmg+CiNpbmNsdWRlIDxsaW51eC9zbGFiLmg+CiNpbmNsdWRlIDxsaW51eC9tbS5oPgoKI2luY2x1ZGUgPGxpbnV4L3NrYnVmZi5oPgoKI2luY2x1ZGUgPGFzbS9pby5oPgojaW5jbHVkZSA8YXNtL3N0cmluZy5oPgoKI2luY2x1ZGUgPGxpbnV4L2lzZG5pZi5oPgoKI2luY2x1ZGUgInBjYml0LmgiCiNpbmNsdWRlICJlZHNzMS5oIgojaW5jbHVkZSAiY2FwaS5oIgoKCi8qCiAqICBFbmNvZGluZyBvZiBDQVBJIG1lc3NhZ2VzCiAqCiAqLwoKaW50IGNhcGlfY29ubl9yZXEoY29uc3QgY2hhciAqIGNhbGxlZFBOLCBzdHJ1Y3Qgc2tfYnVmZiAqKnNrYiwgaW50IHByb3RvKQp7CiAgICAgICAgdXNob3J0IGxlbjsKCiAgICAgICAgLyoKICAgICAgICAgKiBsZW5ndGgKICAgICAgICAgKiAgIEFwcEluZm9NYXNrIC0gMgogICAgICAgICAqICAgQkMwICAgICAgICAgLSAzCiAgICAgICAgICogICBCQzEgICAgICAgICAtIDEKICAgICAgICAgKiAgIENoYW4gICAgICAgIC0gMgogICAgICAgICAqICAgS2V5cGFkICAgICAgLSAxCiAgICAgICAgICogICBDUE4gICAgICAgICAtIDEKICAgICAgICAgKiAgIENQU0EgICAgICAgIC0gMQogICAgICAgICAqICAgQ2FsbGVkUE4gICAgLSAyICsgc3RybGVuCiAgICAgICAgICogICBDYWxsZWRQU0EgICAtIDEKICAgICAgICAgKiAgIHJlc3QuLi4gICAgIC0gNAogICAgICAgICAqICAgLS0tLS0tLS0tLS0tLS0tLQogICAgICAgICAqICAgVG90YWwgICAgICAgIDE4ICsgc3RybGVuCiAgICAgICAgICovCgogICAgICAgIGxlbiA9IDE4ICsgc3RybGVuKGNhbGxlZFBOKTsKCglpZiAocHJvdG8gPT0gSVNETl9QUk9UT19MMl9UUkFOUykKCQlsZW4rKzsKCglpZiAoKCpza2IgPSBkZXZfYWxsb2Nfc2tiKGxlbikpID09IE5VTEwpIHsKICAgIAoJICAgICAgICBwcmludGsoS0VSTl9XQVJOSU5HICJjYXBpX2Nvbm5fcmVxOiBhbGxvY19za2IgZmFpbGVkXG4iKTsKCQlyZXR1cm4gLTE7Cgl9CgogICAgICAgIC8qIEluZm9FbG1NYXNrICovCiAgICAgICAgKigodXNob3J0Kikgc2tiX3B1dCgqc2tiLCAyKSkgPSBBcHBJbmZvTWFzazsgCgoJaWYgKHByb3RvID09IElTRE5fUFJPVE9fTDJfVFJBTlMpCgl7CgkJLyogQmVhcmVyIENhcGFiaWxpdHkgLSBNYW5kYXRvcnkqLwoJCSooc2tiX3B1dCgqc2tiLCAxKSkgPSAzOyAgICAgICAgLyogQkMwLkxlbmd0aAkJKi8KCQkqKHNrYl9wdXQoKnNrYiwgMSkpID0gMHg4MDsgICAgIC8qIFNwZWVjaAkJKi8KCQkqKHNrYl9wdXQoKnNrYiwgMSkpID0gMHgxMDsgICAgIC8qIENpcmN1aXQgTW9kZQkJKi8KCQkqKHNrYl9wdXQoKnNrYiwgMSkpID0gMHgyMzsgICAgIC8qIEEtbGF3CQkqLwoJfQoJZWxzZQoJewoJCS8qIEJlYXJlciBDYXBhYmlsaXR5IC0gTWFuZGF0b3J5Ki8KCQkqKHNrYl9wdXQoKnNrYiwgMSkpID0gMjsgICAgICAgIC8qIEJDMC5MZW5ndGgJCSovCgkJKihza2JfcHV0KCpza2IsIDEpKSA9IDB4ODg7ICAgICAvKiBEaWdpdGFsIEluZm9ybWF0aW9uCSovCgkJKihza2JfcHV0KCpza2IsIDEpKSA9IDB4OTA7ICAgICAvKiBCQzAuT2N0ZWN0NAkJKi8KCX0KCiAgICAgICAgLyogQmVhcmVyIENhcGFiaWxpdHkgLSBPcHRpb25hbCovCiAgICAgICAgKihza2JfcHV0KCpza2IsIDEpKSA9IDA7ICAgICAgICAvKiBCQzEuTGVuZ3RoID0gMCAgICAgICAgICAgICAgICAgICAgKi8KCiAgICAgICAgKihza2JfcHV0KCpza2IsIDEpKSA9IDE7ICAgICAgICAvKiBDaGFubmVsSUQuTGVuZ3RoID0gMSAgICAgICAgICAgICAgKi8KICAgICAgICAqKHNrYl9wdXQoKnNrYiwgMSkpID0gMHg4MzsgICAgIC8qIEJhc2ljIEludGVyZmFjZSAtIEFueSBDaGFubmVsICAgICAqLwoKICAgICAgICAqKHNrYl9wdXQoKnNrYiwgMSkpID0gMDsgICAgICAgIC8qIEtleXBhZC5MZW5ndGggPSAwICAgICAgICAgICAgICAgICAqLwogICAgICAgICAgICAgICAgICAKCiAgICAgICAgKihza2JfcHV0KCpza2IsIDEpKSA9IDA7ICAgICAgICAvKiBDYWxsaW5nUE4uTGVuZ3RoID0gMCAgICAgICAgICAgICAgKi8KICAgICAgICAqKHNrYl9wdXQoKnNrYiwgMSkpID0gMDsgICAgICAgIC8qIENhbGxpbmdQU0EuTGVuZ3RoID0gMCAgICAgICAgICAgICAqLwoKICAgICAgICAvKiBDYWxsZWQgUGFydHkgTnVtYmVyICovCiAgICAgICAgKihza2JfcHV0KCpza2IsIDEpKSA9IHN0cmxlbihjYWxsZWRQTikgKyAxOwogICAgICAgICooc2tiX3B1dCgqc2tiLCAxKSkgPSAweDgxOwogICAgICAgIG1lbWNweShza2JfcHV0KCpza2IsIHN0cmxlbihjYWxsZWRQTikpLCBjYWxsZWRQTiwgc3RybGVuKGNhbGxlZFBOKSk7CgogICAgICAgIC8qICcjJyAqLwoKICAgICAgICAqKHNrYl9wdXQoKnNrYiwgMSkpID0gMDsgICAgICAgLyogQ2FsbGVkUFNBLkxlbmd0aCA9IDAgICAgICovCgogICAgICAgIC8qIExMQy5MZW5ndGggID0gMDsgKi8KICAgICAgICAvKiBITEMwLkxlbmd0aCA9IDA7ICovCiAgICAgICAgLyogSExDMS5MZW5ndGggPSAwOyAqLyAKICAgICAgICAvKiBVVFVTLkxlbmd0aCA9IDA7ICovCiAgICAgICAgbWVtc2V0KHNrYl9wdXQoKnNrYiwgNCksIDAsIDQpOwoKICAgICAgICByZXR1cm4gbGVuOwp9CgppbnQgY2FwaV9jb25uX3Jlc3Aoc3RydWN0IHBjYml0X2NoYW4qIGNoYW4sIHN0cnVjdCBza19idWZmICoqc2tiKQp7CiAgICAgICAgCglpZiAoKCpza2IgPSBkZXZfYWxsb2Nfc2tiKDUpKSA9PSBOVUxMKSB7CiAgICAKCQlwcmludGsoS0VSTl9XQVJOSU5HICJjYXBpX2Nvbm5fcmVzcDogYWxsb2Nfc2tiIGZhaWxlZFxuIik7CgkJcmV0dXJuIC0xOwoJfQoKICAgICAgICAqKCh1c2hvcnQqKSBza2JfcHV0KCpza2IsIDIpICkgPSBjaGFuLT5jYWxscmVmOyAgCiAgICAgICAgKihza2JfcHV0KCpza2IsIDEpKSA9IDB4MDE7ICAvKiBBQ0NFUFRfQ0FMTCAqLwogICAgICAgICooc2tiX3B1dCgqc2tiLCAxKSkgPSAwOwogICAgICAgICooc2tiX3B1dCgqc2tiLCAxKSkgPSAwOwoKICAgICAgICByZXR1cm4gNTsKfQoKaW50IGNhcGlfY29ubl9hY3RpdmVfcmVxKHN0cnVjdCBwY2JpdF9jaGFuKiBjaGFuLCBzdHJ1Y3Qgc2tfYnVmZiAqKnNrYikKewogICAgICAgIC8qCiAgICAgICAgICogOCBieXRlcwogICAgICAgICAqLwogICAgICAgIAoJaWYgKCgqc2tiID0gZGV2X2FsbG9jX3NrYig4KSkgPT0gTlVMTCkgewogICAgCgkJcHJpbnRrKEtFUk5fV0FSTklORyAiY2FwaV9jb25uX2FjdGl2ZV9yZXE6IGFsbG9jX3NrYiBmYWlsZWRcbiIpOwoJCXJldHVybiAtMTsKCX0KCiAgICAgICAgKigodXNob3J0Kikgc2tiX3B1dCgqc2tiLCAyKSApID0gY2hhbi0+Y2FsbHJlZjsgIAoKI2lmZGVmIERFQlVHCglwcmludGsoS0VSTl9ERUJVRyAiQ2FsbCBSZWZlcmVuY2U6ICUwNHhcbiIsIGNoYW4tPmNhbGxyZWYpOyAKI2VuZGlmCgogICAgICAgICooc2tiX3B1dCgqc2tiLCAxKSkgPSAwOyAgICAgICAvKiAgQkMuTGVuZ3RoID0gMDsgICAgICAgICAgKi8KICAgICAgICAqKHNrYl9wdXQoKnNrYiwgMSkpID0gMDsgICAgICAgLyogIENvbm5lY3RlZFBOLkxlbmd0aCA9IDAgICovCiAgICAgICAgKihza2JfcHV0KCpza2IsIDEpKSA9IDA7ICAgICAgIC8qICBQU0EuTGVuZ3RoICAgICAgICAgICAgICAqLwogICAgICAgICooc2tiX3B1dCgqc2tiLCAxKSkgPSAwOyAgICAgICAvKiAgTExDLkxlbmd0aCA9IDA7ICAgICAgICAgKi8KICAgICAgICAqKHNrYl9wdXQoKnNrYiwgMSkpID0gMDsgICAgICAgLyogIEhMQy5MZW5ndGggPSAwOyAgICAgICAgICovCiAgICAgICAgKihza2JfcHV0KCpza2IsIDEpKSA9IDA7ICAgICAgIC8qICBVVFVTLkxlbmd0aCA9IDA7ICAgICAgICAqLwoKCXJldHVybiA4Owp9CgppbnQgY2FwaV9jb25uX2FjdGl2ZV9yZXNwKHN0cnVjdCBwY2JpdF9jaGFuKiBjaGFuLCBzdHJ1Y3Qgc2tfYnVmZiAqKnNrYikKewogICAgICAgIC8qCiAgICAgICAgICogMiBieXRlcwogICAgICAgICAqLwogIAoJaWYgKCgqc2tiID0gZGV2X2FsbG9jX3NrYigyKSkgPT0gTlVMTCkgewogICAgCgkJcHJpbnRrKEtFUk5fV0FSTklORyAiY2FwaV9jb25uX2FjdGl2ZV9yZXNwOiBhbGxvY19za2IgZmFpbGVkXG4iKTsKCQlyZXR1cm4gLTE7Cgl9CgogICAgICAgICooKHVzaG9ydCopIHNrYl9wdXQoKnNrYiwgMikgKSA9IGNoYW4tPmNhbGxyZWY7ICAKCiAgICAgICAgcmV0dXJuIDI7Cn0KCgppbnQgY2FwaV9zZWxlY3RfcHJvdG9fcmVxKHN0cnVjdCBwY2JpdF9jaGFuICpjaGFuLCBzdHJ1Y3Qgc2tfYnVmZiAqKnNrYiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IG91dGdvaW5nKQp7CgogICAgICAgIC8qCiAgICAgICAgICogMTggYnl0ZXMKICAgICAgICAgKi8KCglpZiAoKCpza2IgPSBkZXZfYWxsb2Nfc2tiKDE4KSkgPT0gTlVMTCkgewogICAgCgkJcHJpbnRrKEtFUk5fV0FSTklORyAiY2FwaV9zZWxlY3RfcHJvdG9fcmVxOiBhbGxvY19za2IgZmFpbGVkXG4iKTsKCQlyZXR1cm4gLTE7Cgl9CgogICAgICAgICooKHVzaG9ydCopIHNrYl9wdXQoKnNrYiwgMikgKSA9IGNoYW4tPmNhbGxyZWY7ICAKCiAgICAgICAgLyogTGF5ZXIyIHByb3RvY29sICovCgogICAgICAgIHN3aXRjaCAoY2hhbi0+cHJvdG8pIHsKICAgICAgICBjYXNlIElTRE5fUFJPVE9fTDJfWDc1STogCiAgICAgICAgICAgICAgICAqKHNrYl9wdXQoKnNrYiwgMSkpID0gMHgwNTsgICAgICAgICAgICAvKiBMQVBCICovCiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIElTRE5fUFJPVE9fTDJfSERMQzoKICAgICAgICAgICAgICAgICooc2tiX3B1dCgqc2tiLCAxKSkgPSAweDAyOwogICAgICAgICAgICAgICAgYnJlYWs7CgljYXNlIElTRE5fUFJPVE9fTDJfVFJBTlM6CgkJLyogCgkJICoJVm9pY2UgKGEtbGF3KQoJCSAqLwoJCSooc2tiX3B1dCgqc2tiLCAxKSkgPSAweDA2OwoJCWJyZWFrOwogICAgICAgIGRlZmF1bHQ6CiNpZmRlZiBERUJVRyAKICAgICAgICAgICAgICAgIHByaW50ayhLRVJOX0RFQlVHICJUcmFuc3BhcmVudFxuIik7CiNlbmRpZgogICAgICAgICAgICAgICAgKihza2JfcHV0KCpza2IsIDEpKSA9IDB4MDM7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICB9CgogICAgICAgICooc2tiX3B1dCgqc2tiLCAxKSkgPSAob3V0Z29pbmcgPyAweDAyIDogMHg0Mik7ICAgIC8qIERvbid0IGFzayAqLwogICAgICAgICooc2tiX3B1dCgqc2tiLCAxKSkgPSAweDAwOwogIAogICAgICAgICooKHVzaG9ydCAqKSBza2JfcHV0KCpza2IsIDIpKSA9IE1SVTsKCiAKICAgICAgICAqKHNrYl9wdXQoKnNrYiwgMSkpID0gMHgwODsgICAgICAgICAgIC8qIE1vZHVsbyAqLwogICAgICAgICooc2tiX3B1dCgqc2tiLCAxKSkgPSAweDA3OyAgICAgICAgICAgLyogTWF4IFdpbmRvdyAqLwogIAogICAgICAgICooc2tiX3B1dCgqc2tiLCAxKSkgPSAweDAxOyAgICAgICAgICAgLyogTm8gTGF5ZXIzIFByb3RvY29sICovCgogICAgICAgIC8qCiAgICAgICAgICogMiAtIGxheWVyMyBNVFUgICAgICAgWzEwXQogICAgICAgICAqICAgLSBNb2R1bG8gICAgICAgICAgIFsxMl0KICAgICAgICAgKiAgIC0gV2luZG93ICAgICAgICAgICAKICAgICAgICAgKiAgIC0gbGF5ZXIxIHByb3RvICAgICBbMTRdCiAgICAgICAgICogICAtIGJpdHJhdGUKICAgICAgICAgKiAgIC0gc3ViLWNoYW5uZWwgICAgICBbMTZdCiAgICAgICAgICogICAtIGxheWVyMWRhdGFmb3JtYXQgWzE3XQogICAgICAgICAqLwoKICAgICAgICBtZW1zZXQoc2tiX3B1dCgqc2tiLCA4KSwgMCwgOCk7CgogICAgICAgIHJldHVybiAxODsKfQoKCmludCBjYXBpX2FjdGl2YXRlX3RyYW5zcF9yZXEoc3RydWN0IHBjYml0X2NoYW4gKmNoYW4sIHN0cnVjdCBza19idWZmICoqc2tiKQp7CgoJaWYgKCgqc2tiID0gZGV2X2FsbG9jX3NrYig3KSkgPT0gTlVMTCkgewogICAgCgkJcHJpbnRrKEtFUk5fV0FSTklORyAiY2FwaV9hY3RpdmF0ZV90cmFuc3BfcmVxOiBhbGxvY19za2IgZmFpbGVkXG4iKTsKCQlyZXR1cm4gLTE7Cgl9CgogICAgICAgICooKHVzaG9ydCopIHNrYl9wdXQoKnNrYiwgMikgKSA9IGNoYW4tPmNhbGxyZWY7ICAKCiAgICAgICAgCiAgICAgICAgKihza2JfcHV0KCpza2IsIDEpKSA9IGNoYW4tPmxheWVyMmxpbms7IC8qIExheWVyMiBpZCAqLwogICAgICAgICooc2tiX3B1dCgqc2tiLCAxKSkgPSAweDAwOyAgICAgICAgICAgICAvKiBUcmFuc21pdCBieSBkZWZhdWx0ICovCgogICAgICAgICooKHVzaG9ydCAqKSBza2JfcHV0KCpza2IsIDIpKSA9IE1SVTsKCiAgICAgICAgKihza2JfcHV0KCpza2IsIDEpKSA9IDB4MDE7ICAgICAgICAgICAgIC8qIEVuYWJsZXMgcmVjZXB0aW9uKi8KCiAgICAgICAgcmV0dXJuIDc7Cn0KCmludCBjYXBpX3RkYXRhX3JlcShzdHJ1Y3QgcGNiaXRfY2hhbiogY2hhbiwgc3RydWN0IHNrX2J1ZmYgKnNrYikKewoJdXNob3J0IGRhdGFfbGVuOwoJCgoJLyogIAoJICogY2FsbHJlZiAgICAgIC0gMiAgCgkgKiBsYXllcjJsaW5rICAgLSAxCgkgKiB3QmxvY2tMZW5ndGggLSAyIAoJICogZGF0YSAgICAgICAgIC0gNAoJICogc2VybnVtICAgICAgIC0gMQoJICovCgkKCWRhdGFfbGVuID0gc2tiLT5sZW47CgoJaWYoc2tiX2hlYWRyb29tKHNrYikgPCAxMCkKCXsKCQlwcmludGsoS0VSTl9DUklUICJObyBoZWFkc3BhY2UgKCV1KSBvbiBoZWFkcm9vbSAlcCBmb3IgY2FwaSBoZWFkZXJcbiIsIHNrYl9oZWFkcm9vbShza2IpLCBza2IpOwoJfQoJZWxzZQoJewkKCQlza2JfcHVzaChza2IsIDEwKTsKCX0KCgkqKCh1MTYgKikgKHNrYi0+ZGF0YSkpID0gY2hhbi0+Y2FsbHJlZjsKCXNrYi0+ZGF0YVsyXSA9IGNoYW4tPmxheWVyMmxpbms7CgkqKCh1MTYgKikgKHNrYi0+ZGF0YSArIDMpKSA9IGRhdGFfbGVuOwoKCWNoYW4tPnNfcmVmbnVtID0gKGNoYW4tPnNfcmVmbnVtICsgMSkgJSA4OwoJKigodTMyICopIChza2ItPmRhdGEgKyA1KSkgPSBjaGFuLT5zX3JlZm51bTsKCglza2ItPmRhdGFbOV0gPSAwOyAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIEhETEMgZnJhbWUgbnVtYmVyICovCgoJcmV0dXJuIDEwOwp9CgppbnQgY2FwaV90ZGF0YV9yZXNwKHN0cnVjdCBwY2JpdF9jaGFuICpjaGFuLCBzdHJ1Y3Qgc2tfYnVmZiAqKiBza2IpCgkJICAgIAp7CglpZiAoKCpza2IgPSBkZXZfYWxsb2Nfc2tiKDQpKSA9PSBOVUxMKSB7CiAgICAKCQlwcmludGsoS0VSTl9XQVJOSU5HICJjYXBpX3RkYXRhX3Jlc3A6IGFsbG9jX3NrYiBmYWlsZWRcbiIpOwoJCXJldHVybiAtMTsKCX0KCiAgICAgICAgKigodXNob3J0Kikgc2tiX3B1dCgqc2tiLCAyKSApID0gY2hhbi0+Y2FsbHJlZjsgIAoKICAgICAgICAqKHNrYl9wdXQoKnNrYiwgMSkpID0gY2hhbi0+bGF5ZXIybGluazsKICAgICAgICAqKHNrYl9wdXQoKnNrYiwgMSkpID0gY2hhbi0+cl9yZWZudW07CgogICAgICAgIHJldHVybiAoKnNrYiktPmxlbjsKfQoKaW50IGNhcGlfZGlzY19yZXEodXNob3J0IGNhbGxyZWYsIHN0cnVjdCBza19idWZmICoqc2tiLCB1X2NoYXIgY2F1c2UpCnsKCglpZiAoKCpza2IgPSBkZXZfYWxsb2Nfc2tiKDYpKSA9PSBOVUxMKSB7CiAgICAKCQlwcmludGsoS0VSTl9XQVJOSU5HICJjYXBpX2Rpc2NfcmVxOiBhbGxvY19za2IgZmFpbGVkXG4iKTsKCQlyZXR1cm4gLTE7Cgl9CgogICAgICAgICooKHVzaG9ydCopIHNrYl9wdXQoKnNrYiwgMikgKSA9IGNhbGxyZWY7ICAKCiAgICAgICAgKihza2JfcHV0KCpza2IsIDEpKSA9IDI7ICAgICAgICAgICAgICAgICAgLyogQ2F1c2UuTGVuZ3RoID0gMjsgKi8KICAgICAgICAqKHNrYl9wdXQoKnNrYiwgMSkpID0gMHg4MDsKICAgICAgICAqKHNrYl9wdXQoKnNrYiwgMSkpID0gMHg4MCB8IGNhdXNlOyAgICAgICAgICAgCgogICAgICAgIC8qIAogICAgICAgICAqIENoYW5nZSBpdDogd2Ugc2hvdWxkIHNlbmQgJ1NpYyB0cmFuc2l0IGdsb3JpYSBNdW5kaScgaGVyZSA7LSkgCiAgICAgICAgICovCgogICAgICAgICooc2tiX3B1dCgqc2tiLCAxKSkgPSAwOyAgICAgICAgICAgICAgICAgICAvKiBVVFVTLkxlbmd0aCA9IDA7ICAqLwoKICAgICAgICByZXR1cm4gNjsKfQoKaW50IGNhcGlfZGlzY19yZXNwKHN0cnVjdCBwY2JpdF9jaGFuICpjaGFuLCBzdHJ1Y3Qgc2tfYnVmZiAqKnNrYikKewoJaWYgKCgqc2tiID0gZGV2X2FsbG9jX3NrYigyKSkgPT0gTlVMTCkgewogICAgCgkJcHJpbnRrKEtFUk5fV0FSTklORyAiY2FwaV9kaXNjX3Jlc3A6IGFsbG9jX3NrYiBmYWlsZWRcbiIpOwoJCXJldHVybiAtMTsKCX0KCiAgICAgICAgKigodXNob3J0Kikgc2tiX3B1dCgqc2tiLCAyKSkgPSBjaGFuLT5jYWxscmVmOyAgCgogICAgICAgIHJldHVybiAyOwp9CgoKLyoKICogIERlY29kaW5nIG9mIENBUEkgbWVzc2FnZXMKICoKICovCgppbnQgY2FwaV9kZWNvZGVfY29ubl9pbmQoc3RydWN0IHBjYml0X2NoYW4gKiBjaGFuLCAKICAgICAgICAgICAgICAgICAgICAgICAgIHN0cnVjdCBza19idWZmICpza2IsCiAgICAgICAgICAgICAgICAgICAgICAgICBzdHJ1Y3QgY2FsbGJfZGF0YSAqaW5mbykgCnsKICAgICAgICBpbnQgQ0lsZW4sIGxlbjsKCiAgICAgICAgLyogQ2FsbCBSZWZlcmVuY2UgW0NBUEldICovCiAgICAgICAgY2hhbi0+Y2FsbHJlZiA9ICooKHVzaG9ydCopIHNrYi0+ZGF0YSk7CiAgICAgICAgc2tiX3B1bGwoc2tiLCAyKTsKCiNpZmRlZiBERUJVRwoJcHJpbnRrKEtFUk5fREVCVUcgIkNhbGwgUmVmZXJlbmNlOiAlMDR4XG4iLCBjaGFuLT5jYWxscmVmKTsgCiNlbmRpZgoKICAgICAgICAvKiBDaGFubmVsIElkZW50aWZpY2F0aW9uICovCgogICAgICAgIC8qIEV4cGVjdCAgCiAgICAgICAgICAgTGVuID0gMSAKICAgICAgICAgICBPY3RlY3QgMyA9IDAxMDAgMTBDQyAtIFsgNyBCYXNpYywgNCAsIDItMSBjaGFuIF0KICAgICAgICAgICAqLwoKICAgICAgICBDSWxlbiA9IHNrYi0+ZGF0YVswXTsKI2lmZGVmIERFQlVHCiAgICAgICAgaWYgKENJbGVuID09IDEpIHsKCiAgICAgICAgICAgICAgICBpZiAoICgoc2tiLT5kYXRhWzFdKSAmIDB4RkMpID09IDB4NDggKQogICAgICAgICAgICAgICAgICAgICAgICBwcmludGsoS0VSTl9ERUJVRyAiZGVjb2RlX2Nvbm5faW5kOiBjaGFuIG9rXG4iKTsKICAgICAgICAgICAgICAgIHByaW50ayhLRVJOX0RFQlVHICJwaHlDaGFuID0gJWRcbiIsIHNrYi0+ZGF0YVsxXSAmIDB4MDMpOyAKICAgICAgICB9CgllbHNlCgkJcHJpbnRrKEtFUk5fREVCVUcgImNvbm5faW5kOiBDSWxlbiA9ICVkXG4iLCBDSWxlbik7CiNlbmRpZgogICAgICAgIHNrYl9wdWxsKHNrYiwgQ0lsZW4gKyAxKTsKCiAgICAgICAgLyogQ2FsbGluZyBQYXJ0eSBOdW1iZXIgKi8KICAgICAgICAvKiBBbiAiYWRkaXRpb25hbCBzZXJ2aWNlIiBhcyBmYXIgYXMgUG9ydHVnYWwgVGVsZWNvbSBpcyBjb25jZXJuZWQgKi8KCiAgICAgICAgbGVuID0gc2tiLT5kYXRhWzBdOwoKCWlmIChsZW4gPiAwKSB7CgkJaW50IGNvdW50ID0gMTsKCQkKI2lmZGVmIERFQlVHCgkJcHJpbnRrKEtFUk5fREVCVUcgIkNQTjogT2N0ZWN0IDMgJTAyeFxuIiwgc2tiLT5kYXRhWzFdKTsKI2VuZGlmCgkJaWYgKChza2ItPmRhdGFbMV0gJiAweDgwKSA9PSAwKQoJCQljb3VudCA9IDI7CgkJCgkJaWYgKCEoaW5mby0+ZGF0YS5zZXR1cC5DYWxsaW5nUE4gPSBrbWFsbG9jKGxlbiAtIGNvdW50ICsgMSwgR0ZQX0FUT01JQykpKQoJCQlyZXR1cm4gLTE7CiAgICAgICAKCQltZW1jcHkoaW5mby0+ZGF0YS5zZXR1cC5DYWxsaW5nUE4sIHNrYi0+ZGF0YSArIGNvdW50ICsgMSwgCgkJICAgICAgIGxlbiAtIGNvdW50KTsKCQlpbmZvLT5kYXRhLnNldHVwLkNhbGxpbmdQTltsZW4gLSBjb3VudF0gPSAwOwoKCX0KCWVsc2UgewoJCWluZm8tPmRhdGEuc2V0dXAuQ2FsbGluZ1BOID0gTlVMTDsKCQlwcmludGsoS0VSTl9ERUJVRyAiTlVMTCBDYWxsaW5nUE5cbiIpOwoJfQoKCXNrYl9wdWxsKHNrYiwgbGVuICsgMSk7CgogICAgICAgIC8qIENhbGxpbmcgUGFydHkgU3ViYWRkcmVzcyAqLwogICAgICAgIHNrYl9wdWxsKHNrYiwgc2tiLT5kYXRhWzBdICsgMSk7CgogICAgICAgIC8qIENhbGxlZCBQYXJ0eSBOdW1iZXIgKi8KCiAgICAgICAgbGVuID0gc2tiLT5kYXRhWzBdOwoKCWlmIChsZW4gPiAwKSB7CgkJaW50IGNvdW50ID0gMTsKCQkKCQlpZiAoKHNrYi0+ZGF0YVsxXSAmIDB4ODApID09IDApCgkJCWNvdW50ID0gMjsKICAgICAgICAKCQlpZiAoIShpbmZvLT5kYXRhLnNldHVwLkNhbGxlZFBOID0ga21hbGxvYyhsZW4gLSBjb3VudCArIDEsIEdGUF9BVE9NSUMpKSkKCQkJcmV0dXJuIC0xOwogICAgICAgIAoJCW1lbWNweShpbmZvLT5kYXRhLnNldHVwLkNhbGxlZFBOLCBza2ItPmRhdGEgKyBjb3VudCArIDEsIAoJCSAgICAgICBsZW4gLSBjb3VudCk7IAoJCWluZm8tPmRhdGEuc2V0dXAuQ2FsbGVkUE5bbGVuIC0gY291bnRdID0gMDsKCgl9CgllbHNlIHsKCQlpbmZvLT5kYXRhLnNldHVwLkNhbGxlZFBOID0gTlVMTDsKCQlwcmludGsoS0VSTl9ERUJVRyAiTlVMTCBDYWxsZWRQTlxuIik7Cgl9CgoJc2tiX3B1bGwoc2tiLCBsZW4gKyAxKTsKCiAgICAgICAgLyogQ2FsbGVkIFBhcnR5IFN1YmFkZHJlc3MgKi8KICAgICAgICBza2JfcHVsbChza2IsIHNrYi0+ZGF0YVswXSArIDEpOwoKICAgICAgICAvKiBMTEMgKi8KICAgICAgICBza2JfcHVsbChza2IsIHNrYi0+ZGF0YVswXSArIDEpOwoKICAgICAgICAvKiBITEMgKi8KICAgICAgICBza2JfcHVsbChza2IsIHNrYi0+ZGF0YVswXSArIDEpOwoKICAgICAgICAvKiBVMlUgKi8KICAgICAgICBza2JfcHVsbChza2IsIHNrYi0+ZGF0YVswXSArIDEpOwoKICAgICAgICByZXR1cm4gMDsKfQoKLyoKICogIHJldHVybnMgZXJyY29kZQogKi8KCmludCBjYXBpX2RlY29kZV9jb25uX2NvbmYoc3RydWN0IHBjYml0X2NoYW4gKiBjaGFuLCBzdHJ1Y3Qgc2tfYnVmZiAqc2tiLAoJCQkgIGludCAqY29tcGxldGUpIAp7CiAgICAgICAgaW50IGVycmNvZGU7CiAgCiAgICAgICAgY2hhbi0+Y2FsbHJlZiA9ICooKHVzaG9ydCAqKSBza2ItPmRhdGEpOyAgICAgLyogVXBkYXRlIENhbGxSZWZlcmVuY2UgKi8KICAgICAgICBza2JfcHVsbChza2IsIDIpOwoKICAgICAgICBlcnJjb2RlID0gKigodXNob3J0ICopIHNrYi0+ZGF0YSk7ICAgLyogcmVhZCBlcnJjb2RlICovCiAgICAgICAgc2tiX3B1bGwoc2tiLCAyKTsKCiAgICAgICAgKmNvbXBsZXRlID0gKihza2ItPmRhdGEpOwogICAgICAgIHNrYl9wdWxsKHNrYiwgMSk7CgogICAgICAgIC8qIEZJWCBNRSAqLwogICAgICAgIC8qIFRoaXMgaXMgYWN0dWFsbHkgYSBmaXJtd2FyZSBidWcgKi8KICAgICAgICBpZiAoISpjb21wbGV0ZSkKICAgICAgICB7CiAgICAgICAgICAgICAgICBwcmludGsoS0VSTl9ERUJVRyAiY29tcGxldGU9JTAyeFxuIiwgKmNvbXBsZXRlKTsKICAgICAgICAgICAgICAgICpjb21wbGV0ZSA9IDE7CiAgICAgICAgfQoKCiAgICAgICAgLyogT3B0aW9uYWwgQmVhcmVyIENhcGFiaWxpdHkgKi8KICAgICAgICBza2JfcHVsbChza2IsICooc2tiLT5kYXRhKSArIDEpOwogICAgICAgIAogICAgICAgIC8qIENoYW5uZWwgSWRlbnRpZmljYXRpb24gKi8KICAgICAgICBza2JfcHVsbChza2IsICooc2tiLT5kYXRhKSArIDEpOwoKICAgICAgICAvKiBIaWdoIExheWVyIENvbXBhdGliaWxpdHkgZm9sbG93cyAqLwogICAgICAgIHNrYl9wdWxsKHNrYiwgKihza2ItPmRhdGEpICsgMSk7CgogICAgICAgIHJldHVybiBlcnJjb2RlOwp9CgppbnQgY2FwaV9kZWNvZGVfY29ubl9hY3R2X2luZChzdHJ1Y3QgcGNiaXRfY2hhbiAqIGNoYW4sIHN0cnVjdCBza19idWZmICpza2IpCnsKICAgICAgICB1c2hvcnQgbGVuOwojaWZkZWYgREVCVUcKICAgICAgICBjaGFyIHN0clszMl07CiNlbmRpZgoKICAgICAgICAvKiBZZXQgQW5vdGhlciBCZWFyZXIgQ2FwYWJpbGl0eSAqLwogICAgICAgIHNrYl9wdWxsKHNrYiwgKihza2ItPmRhdGEpICsgMSk7CiAgCgogICAgICAgIC8qIENvbm5lY3RlZCBQYXJ0eSBOdW1iZXIgKi8KICAgICAgICBsZW49Kihza2ItPmRhdGEpOwoKI2lmZGVmIERFQlVHCglpZiAobGVuID4gMSAmJiBsZW4gPCAzMSkgewoJCW1lbWNweShzdHIsIHNrYi0+ZGF0YSArIDIsIGxlbiAtIDEpOwoJCXN0cltsZW5dID0gMDsKCQlwcmludGsoS0VSTl9ERUJVRyAiQ29ubmVjdGVkIFBhcnR5IE51bWJlcjogJXNcbiIsIHN0cik7Cgl9CgllbHNlCgkJcHJpbnRrKEtFUk5fREVCVUcgImFjdHZfaW5kIENQTiBsZW4gPSAlZFxuIiwgbGVuKTsKI2VuZGlmCgogICAgICAgIHNrYl9wdWxsKHNrYiwgbGVuICsgMSk7CgogICAgICAgIC8qIENvbm5lY3RlZCBTdWJhZGRyZXNzICovCiAgICAgICAgc2tiX3B1bGwoc2tiLCAqKHNrYi0+ZGF0YSkgKyAxKTsKCiAgICAgICAgLyogTG93IExheWVyIENhcGFiaWxpdHkgKi8KICAgICAgICBza2JfcHVsbChza2IsICooc2tiLT5kYXRhKSArIDEpOwoKICAgICAgICAvKiBIaWdoIExheWVyIENhcGFiaWxpdHkgKi8KICAgICAgICBza2JfcHVsbChza2IsICooc2tiLT5kYXRhKSArIDEpOwoKICAgICAgICByZXR1cm4gMDsKfQoKaW50IGNhcGlfZGVjb2RlX2Nvbm5fYWN0dl9jb25mKHN0cnVjdCBwY2JpdF9jaGFuICogY2hhbiwgc3RydWN0IHNrX2J1ZmYgKnNrYikKewogICAgICAgIHVzaG9ydCBlcnJjb2RlOwoKICAgICAgICBlcnJjb2RlID0gKigodXNob3J0Kikgc2tiLT5kYXRhKTsKICAgICAgICBza2JfcHVsbChza2IsIDIpOwogICAgICAgIAogICAgICAgIC8qIENoYW5uZWwgSWRlbnRpZmljYXRpb24gCiAgICAgICAgc2tiX3B1bGwoc2tiLCBza2ItPmRhdGFbMF0gKyAxKTsKICAgICAgICAqLwogICAgICAgIHJldHVybiBlcnJjb2RlOwp9CgoKaW50IGNhcGlfZGVjb2RlX3NlbF9wcm90b19jb25mKHN0cnVjdCBwY2JpdF9jaGFuICpjaGFuLCBzdHJ1Y3Qgc2tfYnVmZiAqc2tiKQp7CiAgICAgICAgdXNob3J0IGVycmNvZGU7CiAgICAgICAgCiAgICAgICAgY2hhbi0+bGF5ZXIybGluayA9ICooc2tiLT5kYXRhKTsKICAgICAgICBza2JfcHVsbChza2IsIDEpOwoKICAgICAgICBlcnJjb2RlID0gKigodXNob3J0Kikgc2tiLT5kYXRhKTsKICAgICAgICBza2JfcHVsbChza2IsIDIpOwoKICAgICAgICByZXR1cm4gZXJyY29kZTsKfQoKaW50IGNhcGlfZGVjb2RlX2FjdHZfdHJhbnNfY29uZihzdHJ1Y3QgcGNiaXRfY2hhbiAqY2hhbiwgc3RydWN0IHNrX2J1ZmYgKnNrYikKewogICAgICAgIHVzaG9ydCBlcnJjb2RlOwoKICAgICAgICBpZiAoY2hhbi0+bGF5ZXIybGluayAhPSAqKHNrYi0+ZGF0YSkgKQogICAgICAgICAgICAgICAgcHJpbnRrKCJjYXBpX2RlY29kZV9hY3R2X3RyYW5zX2NvbmY6IGxheWVyMmxpbmsgZG9lc24ndCBtYXRjaFxuIik7CgogICAgICAgIHNrYl9wdWxsKHNrYiwgMSk7CgogICAgICAgIGVycmNvZGUgPSAqKCh1c2hvcnQqKSBza2ItPmRhdGEpOwogICAgICAgIHNrYl9wdWxsKHNrYiwgMik7CgogICAgICAgIHJldHVybiBlcnJjb2RlOyAgICAgICAgCn0KCmludCBjYXBpX2RlY29kZV9kaXNjX2luZChzdHJ1Y3QgcGNiaXRfY2hhbiAqY2hhbiwgc3RydWN0IHNrX2J1ZmYgKnNrYikKewogICAgICAgIHVzaG9ydCBsZW47CiNpZmRlZiBERUJVRwogICAgICAgIGludCBpOwojZW5kaWYKICAgICAgICAvKiBDYXVzZSAqLwogICAgICAgIAogICAgICAgIGxlbiA9ICooc2tiLT5kYXRhKTsKICAgICAgICBza2JfcHVsbChza2IsIDEpOwoKI2lmZGVmIERFQlVHCgogICAgICAgIGZvciAoaT0wOyBpPGxlbjsgaSsrKQogICAgICAgICAgICAgICAgcHJpbnRrKEtFUk5fREVCVUcgIkNhdXNlIE9jdGVjdCAlZDogJTAyeFxuIiwgaSszLCAKICAgICAgICAgICAgICAgICAgICAgICAqKHNrYi0+ZGF0YSArIGkpKTsKI2VuZGlmCgogICAgICAgIHNrYl9wdWxsKHNrYiwgbGVuKTsKCiAgICAgICAgcmV0dXJuIDA7Cn0KCmludCBjYXBpX2RlY29kZV9kaXNjX2NvbmYoc3RydWN0IHBjYml0X2NoYW4gKmNoYW4sIHN0cnVjdCBza19idWZmICpza2IpCnsKICAgICAgICB1c2hvcnQgZXJyY29kZTsKCiAgICAgICAgZXJyY29kZSA9ICooKHVzaG9ydCopIHNrYi0+ZGF0YSk7CiAgICAgICAgc2tiX3B1bGwoc2tiLCAyKTsKCiAgICAgICAgcmV0dXJuIGVycmNvZGU7ICAgICAgICAgICAgICAgIAp9CgojaWZkZWYgREVCVUcKaW50IGNhcGlfZGVjb2RlX2RlYnVnXzE4OCh1X2NoYXIgKmhkciwgdXNob3J0IGhkcmxlbikKewogICAgICAgIGNoYXIgc3RyWzY0XTsKICAgICAgICBpbnQgbGVuOwogICAgICAgIAogICAgICAgIGxlbiA9IGhkclswXTsKCiAgICAgICAgaWYgKGxlbiA8IDY0ICYmIGxlbiA9PSBoZHJsZW4gLSAxKSB7ICAgICAgICAKICAgICAgICAgICAgICAgIG1lbWNweShzdHIsIGhkciArIDEsIGhkcmxlbiAtIDEpOwogICAgICAgICAgICAgICAgc3RyW2hkcmxlbiAtIDFdID0gMDsKICAgICAgICAgICAgICAgIHByaW50aygiJXNcbiIsIHN0cik7CiAgICAgICAgfQogICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIHByaW50aygiZGVidWcgbWVzc2FnZSBpbmNvcnJlY3RcbiIpOwoKICAgICAgICByZXR1cm4gMDsKfQojZW5kaWYKCgoKCgo=