LyoKICogIFRoaXMgZmlsZSB3YXMgYmFzZWQgdXBvbiBjb2RlIGluIFBvd2VydHdlYWsgTGludXggKGh0dHA6Ly9wb3dlcnR3ZWFrLnNmLm5ldCkKICogIChDKSAyMDAwLTIwMDMgIERhdmUgSm9uZXMsIEFyamFuIHZhbiBkZSBWZW4sIEphbm5lIFDkbmvkbOQsIERvbWluaWsgQnJvZG93c2tpLgogKgogKiAgTGljZW5zZWQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR1BMIExpY2Vuc2UgdmVyc2lvbiAyLgogKgogKiAgQklHIEZBVCBESVNDTEFJTUVSOiBXb3JrIGluIHByb2dyZXNzIGNvZGUuIFBvc3NpYmx5ICpkYW5nZXJvdXMqCiAqLwoKI2luY2x1ZGUgPGxpbnV4L2tlcm5lbC5oPgojaW5jbHVkZSA8bGludXgvbW9kdWxlLmg+CiNpbmNsdWRlIDxsaW51eC9pbml0Lmg+CiNpbmNsdWRlIDxsaW51eC9jcHVmcmVxLmg+CiNpbmNsdWRlIDxsaW51eC9pb3BvcnQuaD4KI2luY2x1ZGUgPGxpbnV4L3NsYWIuaD4KCiNpbmNsdWRlIDxhc20vbXNyLmg+CiNpbmNsdWRlIDxhc20vdGltZXguaD4KI2luY2x1ZGUgPGFzbS9pby5oPgoKCiNkZWZpbmUgUE9XRVJOT1dfSU9QT1JUIDB4ZmZmMCAgICAgICAgIC8qIGl0IGRvZXNuJ3QgbWF0dGVyIHdoZXJlLCBhcyBsb25nCgkJCQkJICBhcyBpdCBpcyB1bnVzZWQgKi8KCnN0YXRpYyB1bnNpZ25lZCBpbnQgICAgICAgICAgICAgICAgICAgICBidXNmcmVxOyAgIC8qIEZTQiwgaW4gMTAga0h6ICovCnN0YXRpYyB1bnNpZ25lZCBpbnQgICAgICAgICAgICAgICAgICAgICBtYXhfbXVsdGlwbGllcjsKCgovKiBDbG9jayByYXRpbyBtdWx0aXBsaWVkIGJ5IDEwIC0gc2VlIHRhYmxlIDI3IGluIEFNRCMyMzQ0NiAqLwpzdGF0aWMgc3RydWN0IGNwdWZyZXFfZnJlcXVlbmN5X3RhYmxlIGNsb2NrX3JhdGlvW10gPSB7Cgl7NDUsICAvKiAwMDAgLT4gNC41eCAqLyAwfSwKCXs1MCwgIC8qIDAwMSAtPiA1LjB4ICovIDB9LAoJezQwLCAgLyogMDEwIC0+IDQuMHggKi8gMH0sCgl7NTUsICAvKiAwMTEgLT4gNS41eCAqLyAwfSwKCXsyMCwgIC8qIDEwMCAtPiAyLjB4ICovIDB9LAoJezMwLCAgLyogMTAxIC0+IDMuMHggKi8gMH0sCgl7NjAsICAvKiAxMTAgLT4gNi4weCAqLyAwfSwKCXszNSwgIC8qIDExMSAtPiAzLjV4ICovIDB9LAoJezAsIENQVUZSRVFfVEFCTEVfRU5EfQp9OwoKCi8qKgogKiBwb3dlcm5vd19rNl9nZXRfY3B1X211bHRpcGxpZXIgLSByZXR1cm5zIHRoZSBjdXJyZW50IEZTQiBtdWx0aXBsaWVyCiAqCiAqICAgUmV0dXJucyB0aGUgY3VycmVudCBzZXR0aW5nIG9mIHRoZSBmcmVxdWVuY3kgbXVsdGlwbGllci4gQ29yZSBjbG9jawogKiBzcGVlZCBpcyBmcmVxdWVuY3kgb2YgdGhlIEZyb250LVNpZGUgQnVzIG11bHRpcGxpZWQgd2l0aCB0aGlzIHZhbHVlLgogKi8Kc3RhdGljIGludCBwb3dlcm5vd19rNl9nZXRfY3B1X211bHRpcGxpZXIodm9pZCkKewoJdTY0ICAgICAgICAgICAgIGludmFsdWUgPSAwOwoJdTMyICAgICAgICAgICAgIG1zcnZhbDsKCgltc3J2YWwgPSBQT1dFUk5PV19JT1BPUlQgKyAweDE7Cgl3cm1zcihNU1JfSzZfRVBNUiwgbXNydmFsLCAwKTsgLyogZW5hYmxlIHRoZSBQb3dlck5vdyBwb3J0ICovCglpbnZhbHVlPWlubChQT1dFUk5PV19JT1BPUlQgKyAweDgpOwoJbXNydmFsID0gUE9XRVJOT1dfSU9QT1JUICsgMHgwOwoJd3Jtc3IoTVNSX0s2X0VQTVIsIG1zcnZhbCwgMCk7IC8qIGRpc2FibGUgaXQgYWdhaW4gKi8KCglyZXR1cm4gY2xvY2tfcmF0aW9bKGludmFsdWUgPj4gNSkmN10uaW5kZXg7Cn0KCgovKioKICogcG93ZXJub3dfazZfc2V0X3N0YXRlIC0gc2V0IHRoZSBQb3dlck5vdyEgbXVsdGlwbGllcgogKiBAYmVzdF9pOiBjbG9ja19yYXRpb1tiZXN0X2ldIGlzIHRoZSB0YXJnZXQgbXVsdGlwbGllcgogKgogKiAgIFRyaWVzIHRvIGNoYW5nZSB0aGUgUG93ZXJOb3chIG11bHRpcGxpZXIKICovCnN0YXRpYyB2b2lkIHBvd2Vybm93X2s2X3NldF9zdGF0ZSAodW5zaWduZWQgaW50IGJlc3RfaSkKewoJdW5zaWduZWQgbG9uZyAgICAgICAgICAgb3V0dmFsdWU9MCwgaW52YWx1ZT0wOwoJdW5zaWduZWQgbG9uZyAgICAgICAgICAgbXNydmFsOwoJc3RydWN0IGNwdWZyZXFfZnJlcXMgICAgZnJlcXM7CgoJaWYgKGNsb2NrX3JhdGlvW2Jlc3RfaV0uaW5kZXggPiBtYXhfbXVsdGlwbGllcikgewoJCXByaW50ayhLRVJOX0VSUiAiY3B1ZnJlcTogaW52YWxpZCB0YXJnZXQgZnJlcXVlbmN5XG4iKTsKCQlyZXR1cm47Cgl9CgoJZnJlcXMub2xkID0gYnVzZnJlcSAqIHBvd2Vybm93X2s2X2dldF9jcHVfbXVsdGlwbGllcigpOwoJZnJlcXMubmV3ID0gYnVzZnJlcSAqIGNsb2NrX3JhdGlvW2Jlc3RfaV0uaW5kZXg7CglmcmVxcy5jcHUgPSAwOyAvKiBwb3dlcm5vdy1rNi5jIGlzIFVQIG9ubHkgZHJpdmVyICovCgoJY3B1ZnJlcV9ub3RpZnlfdHJhbnNpdGlvbigmZnJlcXMsIENQVUZSRVFfUFJFQ0hBTkdFKTsKCgkvKiB3ZSBub3cgbmVlZCB0byB0cmFuc2Zvcm0gYmVzdF9pIHRvIHRoZSBCVkMgZm9ybWF0LCBzZWUgQU1EIzIzNDQ2ICovCgoJb3V0dmFsdWUgPSAoMTw8MTIpIHwgKDE8PDEwKSB8ICgxPDw5KSB8IChiZXN0X2k8PDUpOwoKCW1zcnZhbCA9IFBPV0VSTk9XX0lPUE9SVCArIDB4MTsKCXdybXNyKE1TUl9LNl9FUE1SLCBtc3J2YWwsIDApOyAvKiBlbmFibGUgdGhlIFBvd2VyTm93IHBvcnQgKi8KCWludmFsdWU9aW5sKFBPV0VSTk9XX0lPUE9SVCArIDB4OCk7CglpbnZhbHVlID0gaW52YWx1ZSAmIDB4ZjsKCW91dHZhbHVlID0gb3V0dmFsdWUgfCBpbnZhbHVlOwoJb3V0bChvdXR2YWx1ZSAsKFBPV0VSTk9XX0lPUE9SVCArIDB4OCkpOwoJbXNydmFsID0gUE9XRVJOT1dfSU9QT1JUICsgMHgwOwoJd3Jtc3IoTVNSX0s2X0VQTVIsIG1zcnZhbCwgMCk7IC8qIGRpc2FibGUgaXQgYWdhaW4gKi8KCgljcHVmcmVxX25vdGlmeV90cmFuc2l0aW9uKCZmcmVxcywgQ1BVRlJFUV9QT1NUQ0hBTkdFKTsKCglyZXR1cm47Cn0KCgovKioKICogcG93ZXJub3dfazZfdmVyaWZ5IC0gdmVyaWZpZXMgYSBuZXcgQ1BVZnJlcSBwb2xpY3kKICogQHBvbGljeTogbmV3IHBvbGljeQogKgogKiBQb2xpY3kgbXVzdCBiZSB3aXRoaW4gbG93ZXN0IGFuZCBoaWdoZXN0IHBvc3NpYmxlIENQVSBGcmVxdWVuY3ksCiAqIGFuZCBhdCBsZWFzdCBvbmUgcG9zc2libGUgc3RhdGUgbXVzdCBiZSB3aXRoaW4gbWluIGFuZCBtYXguCiAqLwpzdGF0aWMgaW50IHBvd2Vybm93X2s2X3ZlcmlmeShzdHJ1Y3QgY3B1ZnJlcV9wb2xpY3kgKnBvbGljeSkKewoJcmV0dXJuIGNwdWZyZXFfZnJlcXVlbmN5X3RhYmxlX3ZlcmlmeShwb2xpY3ksICZjbG9ja19yYXRpb1swXSk7Cn0KCgovKioKICogcG93ZXJub3dfazZfc2V0cG9saWN5IC0gc2V0cyBhIG5ldyBDUFVGcmVxIHBvbGljeQogKiBAcG9saWN5OiBuZXcgcG9saWN5CiAqIEB0YXJnZXRfZnJlcTogdGhlIHRhcmdldCBmcmVxdWVuY3kKICogQHJlbGF0aW9uOiBob3cgdGhhdCBmcmVxdWVuY3kgcmVsYXRlcyB0byBhY2hpZXZlZCBmcmVxdWVuY3kgKENQVUZSRVFfUkVMQVRJT05fTCBvciBDUFVGUkVRX1JFTEFUSU9OX0gpCiAqCiAqIHNldHMgYSBuZXcgQ1BVRnJlcSBwb2xpY3kKICovCnN0YXRpYyBpbnQgcG93ZXJub3dfazZfdGFyZ2V0IChzdHJ1Y3QgY3B1ZnJlcV9wb2xpY3kgKnBvbGljeSwKCQkJICAgICAgIHVuc2lnbmVkIGludCB0YXJnZXRfZnJlcSwKCQkJICAgICAgIHVuc2lnbmVkIGludCByZWxhdGlvbikKewoJdW5zaWduZWQgaW50ICAgIG5ld3N0YXRlID0gMDsKCglpZiAoY3B1ZnJlcV9mcmVxdWVuY3lfdGFibGVfdGFyZ2V0KHBvbGljeSwgJmNsb2NrX3JhdGlvWzBdLCB0YXJnZXRfZnJlcSwgcmVsYXRpb24sICZuZXdzdGF0ZSkpCgkJcmV0dXJuIC1FSU5WQUw7CgoJcG93ZXJub3dfazZfc2V0X3N0YXRlKG5ld3N0YXRlKTsKCglyZXR1cm4gMDsKfQoKCnN0YXRpYyBpbnQgcG93ZXJub3dfazZfY3B1X2luaXQoc3RydWN0IGNwdWZyZXFfcG9saWN5ICpwb2xpY3kpCnsKCXVuc2lnbmVkIGludCBpOwoJaW50IHJlc3VsdDsKCglpZiAocG9saWN5LT5jcHUgIT0gMCkKCQlyZXR1cm4gLUVOT0RFVjsKCgkvKiBnZXQgZnJlcXVlbmNpZXMgKi8KCW1heF9tdWx0aXBsaWVyID0gcG93ZXJub3dfazZfZ2V0X2NwdV9tdWx0aXBsaWVyKCk7CglidXNmcmVxID0gY3B1X2toeiAvIG1heF9tdWx0aXBsaWVyOwoKCS8qIHRhYmxlIGluaXQgKi8KCWZvciAoaT0wOyAoY2xvY2tfcmF0aW9baV0uZnJlcXVlbmN5ICE9IENQVUZSRVFfVEFCTEVfRU5EKTsgaSsrKSB7CgkJaWYgKGNsb2NrX3JhdGlvW2ldLmluZGV4ID4gbWF4X211bHRpcGxpZXIpCgkJCWNsb2NrX3JhdGlvW2ldLmZyZXF1ZW5jeSA9IENQVUZSRVFfRU5UUllfSU5WQUxJRDsKCQllbHNlCgkJCWNsb2NrX3JhdGlvW2ldLmZyZXF1ZW5jeSA9IGJ1c2ZyZXEgKiBjbG9ja19yYXRpb1tpXS5pbmRleDsKCX0KCgkvKiBjcHVpbmZvIGFuZCBkZWZhdWx0IHBvbGljeSB2YWx1ZXMgKi8KCXBvbGljeS0+Z292ZXJub3IgPSBDUFVGUkVRX0RFRkFVTFRfR09WRVJOT1I7Cglwb2xpY3ktPmNwdWluZm8udHJhbnNpdGlvbl9sYXRlbmN5ID0gQ1BVRlJFUV9FVEVSTkFMOwoJcG9saWN5LT5jdXIgPSBidXNmcmVxICogbWF4X211bHRpcGxpZXI7CgoJcmVzdWx0ID0gY3B1ZnJlcV9mcmVxdWVuY3lfdGFibGVfY3B1aW5mbyhwb2xpY3ksIGNsb2NrX3JhdGlvKTsKCWlmIChyZXN1bHQpCgkJcmV0dXJuIChyZXN1bHQpOwoKCWNwdWZyZXFfZnJlcXVlbmN5X3RhYmxlX2dldF9hdHRyKGNsb2NrX3JhdGlvLCBwb2xpY3ktPmNwdSk7CgoJcmV0dXJuIDA7Cn0KCgpzdGF0aWMgaW50IHBvd2Vybm93X2s2X2NwdV9leGl0KHN0cnVjdCBjcHVmcmVxX3BvbGljeSAqcG9saWN5KQp7Cgl1bnNpZ25lZCBpbnQgaTsKCWZvciAoaT0wOyBpPDg7IGkrKykgewoJCWlmIChpPT1tYXhfbXVsdGlwbGllcikKCQkJcG93ZXJub3dfazZfc2V0X3N0YXRlKGkpOwoJfQoJY3B1ZnJlcV9mcmVxdWVuY3lfdGFibGVfcHV0X2F0dHIocG9saWN5LT5jcHUpOwoJcmV0dXJuIDA7Cn0KCnN0YXRpYyB1bnNpZ25lZCBpbnQgcG93ZXJub3dfazZfZ2V0KHVuc2lnbmVkIGludCBjcHUpCnsKCXJldHVybiBidXNmcmVxICogcG93ZXJub3dfazZfZ2V0X2NwdV9tdWx0aXBsaWVyKCk7Cn0KCnN0YXRpYyBzdHJ1Y3QgZnJlcV9hdHRyKiBwb3dlcm5vd19rNl9hdHRyW10gPSB7CgkmY3B1ZnJlcV9mcmVxX2F0dHJfc2NhbGluZ19hdmFpbGFibGVfZnJlcXMsCglOVUxMLAp9OwoKc3RhdGljIHN0cnVjdCBjcHVmcmVxX2RyaXZlciBwb3dlcm5vd19rNl9kcml2ZXIgPSB7CgkudmVyaWZ5CQk9IHBvd2Vybm93X2s2X3ZlcmlmeSwKCS50YXJnZXQJCT0gcG93ZXJub3dfazZfdGFyZ2V0LAoJLmluaXQJCT0gcG93ZXJub3dfazZfY3B1X2luaXQsCgkuZXhpdAkJPSBwb3dlcm5vd19rNl9jcHVfZXhpdCwKCS5nZXQJCT0gcG93ZXJub3dfazZfZ2V0LAoJLm5hbWUJCT0gInBvd2Vybm93LWs2IiwKCS5vd25lcgkJPSBUSElTX01PRFVMRSwKCS5hdHRyCQk9IHBvd2Vybm93X2s2X2F0dHIsCn07CgoKLyoqCiAqIHBvd2Vybm93X2s2X2luaXQgLSBpbml0aWFsaXplcyB0aGUgazYgUG93ZXJOb3chIENQVUZyZXEgZHJpdmVyCiAqCiAqICAgSW5pdGlhbGl6ZXMgdGhlIEs2IFBvd2VyTm93ISBzdXBwb3J0LiBSZXR1cm5zIC1FTk9ERVYgb24gdW5zdXBwb3J0ZWQKICogZGV2aWNlcywgLUVJTlZBTCBvciAtRU5PTUVNIG9uIHByb2JsZW1zIGR1cmluZyBpbml0aWF0aXphdGlvbiwgYW5kIHplcm8KICogb24gc3VjY2Vzcy4KICovCnN0YXRpYyBpbnQgX19pbml0IHBvd2Vybm93X2s2X2luaXQodm9pZCkKewoJc3RydWN0IGNwdWluZm9feDg2ICAgICAgKmMgPSBjcHVfZGF0YTsKCglpZiAoKGMtPng4Nl92ZW5kb3IgIT0gWDg2X1ZFTkRPUl9BTUQpIHx8IChjLT54ODYgIT0gNSkgfHwKCQkoKGMtPng4Nl9tb2RlbCAhPSAxMikgJiYgKGMtPng4Nl9tb2RlbCAhPSAxMykpKQoJCXJldHVybiAtRU5PREVWOwoKCWlmICghcmVxdWVzdF9yZWdpb24oUE9XRVJOT1dfSU9QT1JULCAxNiwgIlBvd2VyTm93ISIpKSB7CgkJcHJpbnRrKCJjcHVmcmVxOiBQb3dlck5vdyBJT1BPUlQgcmVnaW9uIGFscmVhZHkgdXNlZC5cbiIpOwoJCXJldHVybiAtRUlPOwoJfQoKCWlmIChjcHVmcmVxX3JlZ2lzdGVyX2RyaXZlcigmcG93ZXJub3dfazZfZHJpdmVyKSkgewoJCXJlbGVhc2VfcmVnaW9uIChQT1dFUk5PV19JT1BPUlQsIDE2KTsKCQlyZXR1cm4gLUVJTlZBTDsKCX0KCglyZXR1cm4gMDsKfQoKCi8qKgogKiBwb3dlcm5vd19rNl9leGl0IC0gdW5yZWdpc3RlcnMgQU1EIEs2LTIrLzMrIFBvd2VyTm93ISBzdXBwb3J0CiAqCiAqICAgVW5yZWdpc3RlcnMgQU1EIEs2LTIrIC8gSzYtMysgUG93ZXJOb3chIHN1cHBvcnQuCiAqLwpzdGF0aWMgdm9pZCBfX2V4aXQgcG93ZXJub3dfazZfZXhpdCh2b2lkKQp7CgljcHVmcmVxX3VucmVnaXN0ZXJfZHJpdmVyKCZwb3dlcm5vd19rNl9kcml2ZXIpOwoJcmVsZWFzZV9yZWdpb24gKFBPV0VSTk9XX0lPUE9SVCwgMTYpOwp9CgoKTU9EVUxFX0FVVEhPUiAoIkFyamFuIHZhbiBkZSBWZW4gPGFyamFudkByZWRoYXQuY29tPiwgRGF2ZSBKb25lcyA8ZGF2ZWpAY29kZW1vbmtleS5vcmcudWs+LCBEb21pbmlrIEJyb2Rvd3NraSA8bGludXhAYnJvZG8uZGU+Iik7Ck1PRFVMRV9ERVNDUklQVElPTiAoIlBvd2VyTm93ISBkcml2ZXIgZm9yIEFNRCBLNi0yKyAvIEs2LTMrIHByb2Nlc3NvcnMuIik7Ck1PRFVMRV9MSUNFTlNFICgiR1BMIik7Cgptb2R1bGVfaW5pdChwb3dlcm5vd19rNl9pbml0KTsKbW9kdWxlX2V4aXQocG93ZXJub3dfazZfZXhpdCk7Cg==