LyoKICogc25tcF9hbGFybS5jOgogKi8KLyogUG9ydGlvbnMgb2YgdGhpcyBmaWxlIGFyZSBzdWJqZWN0IHRvIHRoZSBmb2xsb3dpbmcgY29weXJpZ2h0KHMpLiAgU2VlCiAqIHRoZSBOZXQtU05NUCdzIENPUFlJTkcgZmlsZSBmb3IgbW9yZSBkZXRhaWxzIGFuZCBvdGhlciBjb3B5cmlnaHRzCiAqIHRoYXQgbWF5IGFwcGx5OgogKi8KLyoKICogUG9ydGlvbnMgb2YgdGhpcyBmaWxlIGFyZSBjb3B5cmlnaHRlZCBieToKICogQ29weXJpZ2h0IKkgMjAwMyBTdW4gTWljcm9zeXN0ZW1zLCBJbmMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqIFVzZSBpcyBzdWJqZWN0IHRvIGxpY2Vuc2UgdGVybXMgc3BlY2lmaWVkIGluIHRoZSBDT1BZSU5HIGZpbGUKICogZGlzdHJpYnV0ZWQgd2l0aCB0aGUgTmV0LVNOTVAgcGFja2FnZS4KICovCi8qKiBAZGVmZ3JvdXAgc25tcF9hbGFybSAgZ2VuZXJpYyBsaWJyYXJ5IGJhc2VkIGFsYXJtIHRpbWVycyBmb3IgdmFyaW91cyBwYXJ0cyBvZiBhbiBhcHBsaWNhdGlvbiAKICogIEBpbmdyb3VwIGxpYnJhcnkKICogCiAqICBAewogKi8KI2luY2x1ZGUgPG5ldC1zbm1wL25ldC1zbm1wLWNvbmZpZy5oPgoKI2lmIEhBVkVfVU5JU1REX0gKI2luY2x1ZGUgPHVuaXN0ZC5oPgojZW5kaWYKI2luY2x1ZGUgPHNpZ25hbC5oPgojaWYgSEFWRV9TVERMSUJfSAojaW5jbHVkZSA8c3RkbGliLmg+CiNlbmRpZgojaW5jbHVkZSA8c3lzL3R5cGVzLmg+CiNpZiBIQVZFX05FVElORVRfSU5fSAojaW5jbHVkZSA8bmV0aW5ldC9pbi5oPgojZW5kaWYKI2lmIEhBVkVfU1RSSU5HX0gKI2luY2x1ZGUgPHN0cmluZy5oPgojZW5kaWYKCiNpZiBUSU1FX1dJVEhfU1lTX1RJTUUKIyBpZmRlZiBXSU4zMgojICBpbmNsdWRlIDxzeXMvdGltZWIuaD4KIyBlbHNlCiMgIGluY2x1ZGUgPHN5cy90aW1lLmg+CiMgZW5kaWYKIyBpbmNsdWRlIDx0aW1lLmg+CiNlbHNlCiMgaWYgSEFWRV9TWVNfVElNRV9ICiMgIGluY2x1ZGUgPHN5cy90aW1lLmg+CiMgZWxzZQojICBpbmNsdWRlIDx0aW1lLmg+CiMgZW5kaWYKI2VuZGlmCiNpZiBIQVZFX1dJTlNPQ0tfSAojaW5jbHVkZSA8d2luc29jay5oPgojZW5kaWYKCiNpZiBIQVZFX0RNQUxMT0NfSAojaW5jbHVkZSA8ZG1hbGxvYy5oPgojZW5kaWYKCiNpbmNsdWRlIDxuZXQtc25tcC90eXBlcy5oPgojaW5jbHVkZSA8bmV0LXNubXAvb3V0cHV0X2FwaS5oPgojaW5jbHVkZSA8bmV0LXNubXAvY29uZmlnX2FwaS5oPgojaW5jbHVkZSA8bmV0LXNubXAvdXRpbGl0aWVzLmg+CgojaW5jbHVkZSA8bmV0LXNubXAvbGlicmFyeS9zbm1wX2FwaS5oPgojaW5jbHVkZSA8bmV0LXNubXAvbGlicmFyeS9jYWxsYmFjay5oPgojaW5jbHVkZSA8bmV0LXNubXAvbGlicmFyeS9zbm1wX2FsYXJtLmg+CgpzdGF0aWMgc3RydWN0IHNubXBfYWxhcm0gKnRoZWFsYXJtcyA9IE5VTEw7CnN0YXRpYyBpbnQgICAgICBzdGFydF9hbGFybXMgPSAwOwpzdGF0aWMgdW5zaWduZWQgaW50IHJlZ251bSA9IDE7CgppbnQKaW5pdF9hbGFybV9wb3N0X2NvbmZpZyhpbnQgbWFqb3JpZCwgaW50IG1pbm9yaWQsIHZvaWQgKnNlcnZlcmFyZywKICAgICAgICAgICAgICAgICAgICAgICB2b2lkICpjbGllbnRhcmcpCnsKICAgIHN0YXJ0X2FsYXJtcyA9IDE7CiAgICBzZXRfYW5fYWxhcm0oKTsKICAgIHJldHVybiBTTk1QRVJSX1NVQ0NFU1M7Cn0KCnZvaWQKaW5pdF9zbm1wX2FsYXJtKHZvaWQpCnsKICAgIHN0YXJ0X2FsYXJtcyA9IDA7CiAgICBzbm1wX3JlZ2lzdGVyX2NhbGxiYWNrKFNOTVBfQ0FMTEJBQ0tfTElCUkFSWSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgU05NUF9DQUxMQkFDS19QT1NUX1JFQURfQ09ORklHLAogICAgICAgICAgICAgICAgICAgICAgICAgICBpbml0X2FsYXJtX3Bvc3RfY29uZmlnLCBOVUxMKTsKfQoKdm9pZApzYV91cGRhdGVfZW50cnkoc3RydWN0IHNubXBfYWxhcm0gKmEpCnsKICAgIGlmIChhLT50X2xhc3QudHZfc2VjID09IDAgJiYgYS0+dF9sYXN0LnR2X3VzZWMgPT0gMCkgewogICAgICAgIHN0cnVjdCB0aW1ldmFsICB0X25vdzsKICAgICAgICAvKgogICAgICAgICAqIE5ldmVyIGJlZW4gY2FsbGVkIHlldCwgY2FsbCB0aW1lIGB0JyBmcm9tIG5vdy4gIAogICAgICAgICAqLwogICAgICAgIGdldHRpbWVvZmRheSgmdF9ub3csIE5VTEwpOwoKICAgICAgICBhLT50X2xhc3QudHZfc2VjID0gdF9ub3cudHZfc2VjOwogICAgICAgIGEtPnRfbGFzdC50dl91c2VjID0gdF9ub3cudHZfdXNlYzsKCiAgICAgICAgTkVUU05NUF9USU1FUkFERCgmdF9ub3csICZhLT50LCAmYS0+dF9uZXh0KTsKICAgIH0gZWxzZSBpZiAoYS0+dF9uZXh0LnR2X3NlYyA9PSAwICYmIGEtPnRfbmV4dC50dl91c2VjID09IDApIHsKICAgICAgICAvKgogICAgICAgICAqIFdlJ3ZlIGJlZW4gY2FsbGVkIGJ1dCBub3QgcmVzZXQgZm9yIHRoZSBuZXh0IGNhbGwuICAKICAgICAgICAgKi8KICAgICAgICBpZiAoYS0+ZmxhZ3MgJiBTQV9SRVBFQVQpIHsKICAgICAgICAgICAgaWYgKGEtPnQudHZfc2VjID09IDAgJiYgYS0+dC50dl91c2VjID09IDApIHsKICAgICAgICAgICAgICAgIERFQlVHTVNHVEwoKCJzbm1wX2FsYXJtIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ1cGRhdGVfZW50cnk6IGlsbGVnYWwgaW50ZXJ2YWwgc3BlY2lmaWVkXG4iKSk7CiAgICAgICAgICAgICAgICBzbm1wX2FsYXJtX3VucmVnaXN0ZXIoYS0+Y2xpZW50cmVnKTsKICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgTkVUU05NUF9USU1FUkFERCgmYS0+dF9sYXN0LCAmYS0+dCwgJmEtPnRfbmV4dCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgLyoKICAgICAgICAgICAgICogU2luZ2xlIHRpbWUgY2FsbCwgcmVtb3ZlIGl0LiAgCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBzbm1wX2FsYXJtX3VucmVnaXN0ZXIoYS0+Y2xpZW50cmVnKTsKICAgICAgICB9CiAgICB9Cn0KCi8qKgogKiBUaGlzIGZ1bmN0aW9uIHJlbW92ZXMgdGhlIGNhbGxiYWNrIGZ1bmN0aW9uIGZyb20gYSBsaXN0IG9mIHJlZ2lzdGVyZWQKICogYWxhcm1zLCB1bnJlZ2lzdGVyaW5nIHRoZSBhbGFybS4KICoKICogQHBhcmFtIGNsaWVudHJlZyBpcyBhIHVuaXF1ZSB1bnNpZ25lZCBpbnRlZ2VyIHJlcHJlc2VudGluZyBhIHJlZ2lzdGVyZWQKICoJYWxhcm0gd2hpY2ggdGhlIGNsaWVudCB3YW50cyB0byB1bnJlZ2lzdGVyLgogKgogKiBAcmV0dXJuIHZvaWQKICoKICogQHNlZSBzbm1wX2FsYXJtX3JlZ2lzdGVyCiAqIEBzZWUgc25tcF9hbGFybV9yZWdpc3Rlcl9ocgogKiBAc2VlIHNubXBfYWxhcm1fdW5yZWdpc3Rlcl9hbGwKICovCnZvaWQKc25tcF9hbGFybV91bnJlZ2lzdGVyKHVuc2lnbmVkIGludCBjbGllbnRyZWcpCnsKICAgIHN0cnVjdCBzbm1wX2FsYXJtICpzYV9wdHIsICoqcHJldk5leHQgPSAmdGhlYWxhcm1zOwoKICAgIGZvciAoc2FfcHRyID0gdGhlYWxhcm1zOwogICAgICAgICBzYV9wdHIgIT0gTlVMTCAmJiBzYV9wdHItPmNsaWVudHJlZyAhPSBjbGllbnRyZWc7CiAgICAgICAgIHNhX3B0ciA9IHNhX3B0ci0+bmV4dCkgewogICAgICAgIHByZXZOZXh0ID0gJihzYV9wdHItPm5leHQpOwogICAgfQoKICAgIGlmIChzYV9wdHIgIT0gTlVMTCkgewogICAgICAgICpwcmV2TmV4dCA9IHNhX3B0ci0+bmV4dDsKICAgICAgICBERUJVR01TR1RMKCgic25tcF9hbGFybSIsICJ1bnJlZ2lzdGVyZWQgYWxhcm0gJWRcbiIsIAoJCSAgICBzYV9wdHItPmNsaWVudHJlZykpOwogICAgICAgIC8qCiAgICAgICAgICogTm90ZTogZG8gbm90IGZyZWUgdGhlIGNsaWVudGFyZywgaXQncyB0aGUgY2xpZW50J3MgcmVzcG9uc2liaWxpdHkgCiAgICAgICAgICovCiAgICAgICAgZnJlZShzYV9wdHIpOwogICAgfSBlbHNlIHsKICAgICAgICBERUJVR01TR1RMKCgic25tcF9hbGFybSIsICJubyBhbGFybSAlZCB0byB1bnJlZ2lzdGVyXG4iLCBjbGllbnRyZWcpKTsKICAgIH0KfQoKLyoqCiAqIFRoaXMgZnVuY3Rpb24gdW5yZWdpc3RlcnMgYWxsIGFsYXJtcyBjdXJyZW50bHkgc3RvcmVkLgogKgogKiBAcmV0dXJuIHZvaWQKICoKICogQHNlZSBzbm1wX2FsYXJtX3JlZ2lzdGVyCiAqIEBzZWUgc25tcF9hbGFybV9yZWdpc3Rlcl9ocgogKiBAc2VlIHNubXBfYWxhcm1fdW5yZWdpc3RlcgogKi8Kdm9pZApzbm1wX2FsYXJtX3VucmVnaXN0ZXJfYWxsKHZvaWQpCnsKICBzdHJ1Y3Qgc25tcF9hbGFybSAqc2FfcHRyLCAqc2FfdG1wOwoKICBmb3IgKHNhX3B0ciA9IHRoZWFsYXJtczsgc2FfcHRyICE9IE5VTEw7IHNhX3B0ciA9IHNhX3RtcCkgewogICAgc2FfdG1wID0gc2FfcHRyLT5uZXh0OwogICAgZnJlZShzYV9wdHIpOwogIH0KICBERUJVR01TR1RMKCgic25tcF9hbGFybSIsICJBTEwgYWxhcm1zIHVucmVnaXN0ZXJlZFxuIikpOwogIHRoZWFsYXJtcyA9IE5VTEw7Cn0gIAoKc3RydWN0IHNubXBfYWxhcm0gKgpzYV9maW5kX25leHQodm9pZCkKewogICAgc3RydWN0IHNubXBfYWxhcm0gKmEsICpsb3dlc3QgPSBOVUxMOwogICAgc3RydWN0IHRpbWV2YWwgIHRfbm93OwoKICAgIGdldHRpbWVvZmRheSgmdF9ub3csIE5VTEwpOwoKICAgIGZvciAoYSA9IHRoZWFsYXJtczsgYSAhPSBOVUxMOyBhID0gYS0+bmV4dCkgewogICAgICAgIC8qIGNoZWNrIGZvciB0aW1lIGRlbHRhIHNrZXcgKi8KICAgICAgICBpZiAoKGEtPnRfbmV4dC50dl9zZWMgLSB0X25vdy50dl9zZWMpID4gYS0+dC50dl9zZWMpCiAgICAgICAgewogICAgICAgICAgICBERUJVR01TR1RMKCgidGltZV9za2V3IiwgIlRpbWUgZGVsdGEgdG9vIGJpZyAoJWxkIHNlY29uZHMpLCBzaG91bGQgYmUgJWxkIHNlY29uZHMgLSBmaXhpbmdcbiIsCgkJKGxvbmcpKGEtPnRfbmV4dC50dl9zZWMgLSB0X25vdy50dl9zZWMpLCAobG9uZylhLT50LnR2X3NlYykpOwogICAgICAgICAgICBhLT50X25leHQudHZfc2VjID0gdF9ub3cudHZfc2VjICsgYS0+dC50dl9zZWM7CiAgICAgICAgICAgIGEtPnRfbmV4dC50dl91c2VjID0gdF9ub3cudHZfdXNlYyArIGEtPnQudHZfdXNlYzsKICAgICAgICB9CiAgICAgICAgaWYgKGxvd2VzdCA9PSBOVUxMKSB7CiAgICAgICAgICAgIGxvd2VzdCA9IGE7CiAgICAgICAgfSBlbHNlIGlmIChhLT50X25leHQudHZfc2VjID09IGxvd2VzdC0+dF9uZXh0LnR2X3NlYykgewogICAgICAgICAgICBpZiAoYS0+dF9uZXh0LnR2X3VzZWMgPCBsb3dlc3QtPnRfbmV4dC50dl91c2VjKSB7CiAgICAgICAgICAgICAgICBsb3dlc3QgPSBhOwogICAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIGlmIChhLT50X25leHQudHZfc2VjIDwgbG93ZXN0LT50X25leHQudHZfc2VjKSB7CiAgICAgICAgICAgIGxvd2VzdCA9IGE7CiAgICAgICAgfQogICAgfQogICAgcmV0dXJuIGxvd2VzdDsKfQoKc3RydWN0IHNubXBfYWxhcm0gKgpzYV9maW5kX3NwZWNpZmljKHVuc2lnbmVkIGludCBjbGllbnRyZWcpCnsKICAgIHN0cnVjdCBzbm1wX2FsYXJtICpzYV9wdHI7CiAgICBmb3IgKHNhX3B0ciA9IHRoZWFsYXJtczsgc2FfcHRyICE9IE5VTEw7IHNhX3B0ciA9IHNhX3B0ci0+bmV4dCkgewogICAgICAgIGlmIChzYV9wdHItPmNsaWVudHJlZyA9PSBjbGllbnRyZWcpIHsKICAgICAgICAgICAgcmV0dXJuIHNhX3B0cjsKICAgICAgICB9CiAgICB9CiAgICByZXR1cm4gTlVMTDsKfQoKdm9pZApydW5fYWxhcm1zKHZvaWQpCnsKICAgIGludCAgICAgICAgICAgICBkb25lID0gMDsKICAgIHN0cnVjdCBzbm1wX2FsYXJtICphID0gTlVMTDsKICAgIHVuc2lnbmVkIGludCAgICBjbGllbnRyZWc7CiAgICBzdHJ1Y3QgdGltZXZhbCAgdF9ub3c7CgogICAgLyoKICAgICAqIExvb3AgdGhyb3VnaCBldmVyeXRoaW5nIHdlIGhhdmUgcmVwZWF0ZWRseSBsb29raW5nIGZvciB0aGUgbmV4dCB0aGluZyB0bwogICAgICogY2FsbCB1bnRpbCBhbGwgZXZlbnRzIGFyZSBmaW5hbGx5IGluIHRoZSBmdXR1cmUgYWdhaW4uICAKICAgICAqLwoKICAgIHdoaWxlICghZG9uZSkgewogICAgICAgIGlmICgoYSA9IHNhX2ZpbmRfbmV4dCgpKSA9PSBOVUxMKSB7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CgogICAgICAgIGdldHRpbWVvZmRheSgmdF9ub3csIE5VTEwpOwoKICAgICAgICBpZiAodGltZXJjbXAoJmEtPnRfbmV4dCwgJnRfbm93LCA8KSkgewogICAgICAgICAgICBjbGllbnRyZWcgPSBhLT5jbGllbnRyZWc7CiAgICAgICAgICAgIERFQlVHTVNHVEwoKCJzbm1wX2FsYXJtIiwgInJ1biBhbGFybSAlZFxuIiwgY2xpZW50cmVnKSk7CiAgICAgICAgICAgICgqKGEtPnRoZWNhbGxiYWNrKSkgKGNsaWVudHJlZywgYS0+Y2xpZW50YXJnKTsKICAgICAgICAgICAgREVCVUdNU0dUTCgoInNubXBfYWxhcm0iLCAiYWxhcm0gJWQgY29tcGxldGVkXG4iLCBjbGllbnRyZWcpKTsKCiAgICAgICAgICAgIGlmICgoYSA9IHNhX2ZpbmRfc3BlY2lmaWMoY2xpZW50cmVnKSkgIT0gTlVMTCkgewogICAgICAgICAgICAgICAgYS0+dF9sYXN0LnR2X3NlYyA9IHRfbm93LnR2X3NlYzsKICAgICAgICAgICAgICAgIGEtPnRfbGFzdC50dl91c2VjID0gdF9ub3cudHZfdXNlYzsKICAgICAgICAgICAgICAgIGEtPnRfbmV4dC50dl9zZWMgPSAwOwogICAgICAgICAgICAgICAgYS0+dF9uZXh0LnR2X3VzZWMgPSAwOwogICAgICAgICAgICAgICAgc2FfdXBkYXRlX2VudHJ5KGEpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgREVCVUdNU0dUTCgoInNubXBfYWxhcm0iLCAiYWxhcm0gJWQgZGVsZXRlZCBpdHNlbGZcbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGllbnRyZWcpKTsKICAgICAgICAgICAgfQogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGRvbmUgPSAxOwogICAgICAgIH0KICAgIH0KfQoKCgpSRVRTSUdUWVBFCmFsYXJtX2hhbmRsZXIoaW50IGEpCnsKICAgIHJ1bl9hbGFybXMoKTsKICAgIHNldF9hbl9hbGFybSgpOwp9CgoKCmludApnZXRfbmV4dF9hbGFybV9kZWxheV90aW1lKHN0cnVjdCB0aW1ldmFsICpkZWx0YSkKewogICAgc3RydWN0IHNubXBfYWxhcm0gKnNhX3B0cjsKICAgIHN0cnVjdCB0aW1ldmFsICB0X25vdzsKCiAgICBzYV9wdHIgPSBzYV9maW5kX25leHQoKTsKCiAgICBpZiAoc2FfcHRyKSB7CiAgICAgICAgZ2V0dGltZW9mZGF5KCZ0X25vdywgTlVMTCk7CgogICAgICAgIGlmICh0aW1lcmNtcCgmdF9ub3csICZzYV9wdHItPnRfbmV4dCwgPikpIHsKICAgICAgICAgICAgLyoKICAgICAgICAgICAgICogVGltZSBoYXMgYWxyZWFkeSBwYXNzZWQuICBSZXR1cm4gdGhlIHNtYWxsZXN0IHBvc3NpYmxlIGFtb3VudCBvZgogICAgICAgICAgICAgKiB0aW1lLiAgCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBkZWx0YS0+dHZfc2VjID0gMDsKICAgICAgICAgICAgZGVsdGEtPnR2X3VzZWMgPSAxOwogICAgICAgICAgICByZXR1cm4gc2FfcHRyLT5jbGllbnRyZWc7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgLyoKICAgICAgICAgICAgICogVGltZSBpcyBzdGlsbCBpbiB0aGUgZnV0dXJlLiAgCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBORVRTTk1QX1RJTUVSU1VCKCZzYV9wdHItPnRfbmV4dCwgJnRfbm93LCBkZWx0YSk7CgogICAgICAgICAgICByZXR1cm4gc2FfcHRyLT5jbGllbnRyZWc7CiAgICAgICAgfQogICAgfQoKICAgIC8qCiAgICAgKiBOb3RoaW5nIExlZnQuICAKICAgICAqLwogICAgcmV0dXJuIDA7Cn0KCgp2b2lkCnNldF9hbl9hbGFybSh2b2lkKQp7CiAgICBzdHJ1Y3QgdGltZXZhbCAgZGVsdGE7CiAgICBpbnQgICAgICAgICAgICAgbmV4dGFsYXJtID0gZ2V0X25leHRfYWxhcm1fZGVsYXlfdGltZSgmZGVsdGEpOwoKICAgIC8qCiAgICAgKiBXZSBkb24ndCB1c2Ugc2lnbmFscyBpZiB0aGV5IGFza2VkIHVzIG5pY2VseSBub3QgdG8uICBJdCdzIGV4cGVjdGVkCiAgICAgKiB0aGV5J2xsIGNoZWNrIHRoZSBuZXh0IGFsYXJtIHRpbWUgYW5kIGRvIHRoZWlyIG93biBjYWxsaW5nIG9mCiAgICAgKiBydW5fYWxhcm1zKCkuICAKICAgICAqLwoKICAgIGlmIChuZXh0YWxhcm0gJiYgIW5ldHNubXBfZHNfZ2V0X2Jvb2xlYW4oTkVUU05NUF9EU19MSUJSQVJZX0lELAoJCQkJCU5FVFNOTVBfRFNfTElCX0FMQVJNX0RPTlRfVVNFX1NJRykpIHsKI2lmbmRlZiBXSU4zMgojIGlmZGVmIEhBVkVfU0VUSVRJTUVSCiAgICAgICAgc3RydWN0IGl0aW1lcnZhbCBpdDsKCiAgICAgICAgaXQuaXRfdmFsdWUudHZfc2VjID0gZGVsdGEudHZfc2VjOwogICAgICAgIGl0Lml0X3ZhbHVlLnR2X3VzZWMgPSBkZWx0YS50dl91c2VjOwogICAgICAgIGl0Lml0X2ludGVydmFsLnR2X3NlYyA9IDA7CiAgICAgICAgaXQuaXRfaW50ZXJ2YWwudHZfdXNlYyA9IDA7CgogICAgICAgIHNpZ25hbChTSUdBTFJNLCBhbGFybV9oYW5kbGVyKTsKICAgICAgICBzZXRpdGltZXIoSVRJTUVSX1JFQUwsICZpdCwgTlVMTCk7CiAgICAgICAgREVCVUdNU0dUTCgoInNubXBfYWxhcm0iLCAic2NoZWR1bGUgYWxhcm0gJWQgaW4gJWxkLiUwM2xkIHNlY29uZHNcbiIsCiAgICAgICAgICAgICAgICAgICAgbmV4dGFsYXJtLCBkZWx0YS50dl9zZWMsIChkZWx0YS50dl91c2VjIC8gMTAwMCkpKTsKIyBlbHNlICAvKiBIQVZFX1NFVElUSU1FUiAqLwojICBpZmRlZiBTSUdBTFJNCiAgICAgICAgc2lnbmFsKFNJR0FMUk0sIGFsYXJtX2hhbmRsZXIpOwogICAgICAgIGFsYXJtKGRlbHRhLnR2X3NlYyk7CiAgICAgICAgREVCVUdNU0dUTCgoInNubXBfYWxhcm0iLAogICAgICAgICAgICAgICAgICAgICJzY2hlZHVsZSBhbGFybSAlZCBpbiByb3VnaGx5ICVsZCBzZWNvbmRzXG4iLCBuZXh0YWxhcm0sCiAgICAgICAgICAgICAgICAgICAgZGVsdGEudHZfc2VjKSk7CiMgIGVuZGlmICAvKiBTSUdBTFJNICovCiMgZW5kaWYgIC8qIEhBVkVfU0VUSVRJTUVSICovCiNlbmRpZiAgLyogV0lOMzIgKi8KCiAgICB9IGVsc2UgewogICAgICAgIERFQlVHTVNHVEwoKCJzbm1wX2FsYXJtIiwgIm5vIGFsYXJtcyBmb3VuZCB0byBzY2hlZHVsZVxuIikpOwogICAgfQp9CgoKLyoqCiAqIFRoaXMgZnVuY3Rpb24gcmVnaXN0ZXJzIGZ1bmN0aW9uIGNhbGxiYWNrcyB0byBvY2N1ciBhdCBhIHNwZWNpZmljIHRpbWUKICogaW4gdGhlIGZ1dHVyZS4KICoKICogQHBhcmFtIHdoZW4gaXMgYW4gdW5zaWduZWQgaW50ZWdlciBzcGVjaWZ5aW5nIHdoZW4gdGhlIGNhbGxiYWNrIGZ1bmN0aW9uCiAqICAgICAgICAgICAgIHdpbGwgYmUgY2FsbGVkIGluIHNlY29uZHMuCiAqCiAqIEBwYXJhbSBmbGFncyBpcyBhbiB1bnNpZ25lZCBpbnRlZ2VyIHRoYXQgc3BlY2lmaWVzIGhvdyBmcmVxdWVudCB0aGUgY2FsbGJhY2sKICoJZnVuY3Rpb24gaXMgY2FsbGVkIGluIHNlY29uZHMuICBTaG91bGQgYmUgU0FfUkVQRUFUIG9yIDAuICBJZiAgCiAqCWZsYWdzICBpcyAgc2V0IHdpdGggU0FfUkVQRUFULCB0aGVuIHRoZSByZWdpc3RlcmVkIGNhbGxiYWNrIGZ1bmN0aW9uCiAqCXdpbGwgYmUgY2FsbGVkIGV2ZXJ5IFNBX1JFUEVBVCBzZWNvbmRzLiAgSWYgZmxhZ3MgaXMgMCB0aGVuIHRoZSAKICoJZnVuY3Rpb24gd2lsbCBvbmx5IGJlIGNhbGxlZCBvbmNlIGFuZCB0aGVuIHJlbW92ZWQgZnJvbSB0aGUgCiAqCXJlZ2lzdGVyZWQgYWxhcm0gbGlzdC4KICoKICogQHBhcmFtIHRoZWNhbGxiYWNrIGlzIGEgcG9pbnRlciBTTk1QQWxhcm1DYWxsYmFjayB3aGljaCBpcyB0aGUgY2FsbGJhY2sgCiAqCWZ1bmN0aW9uIGJlaW5nIHN0b3JlZCBhbmQgcmVnaXN0ZXJlZC4KICoKICogQHBhcmFtIGNsaWVudGFyZyBpcyBhIHZvaWQgcG9pbnRlciB1c2VkIGJ5IHRoZSBjYWxsYmFjayBmdW5jdGlvbi4gIFRoaXMgCiAqCXBvaW50ZXIgaXMgYXNzaWduZWQgdG8gc25tcF9hbGFybS0+Y2xpZW50YXJnIGFuZCBwYXNzZWQgaW50byB0aGUKICoJY2FsbGJhY2sgZnVuY3Rpb24gZm9yIHRoZSBjbGllbnQncyBzcGVjaWZjIG5lZWRzLgogKgogKiBAcmV0dXJuIFJldHVybnMgYSB1bmlxdWUgdW5zaWduZWQgaW50ZWdlcih3aGljaCBpcyBhbHNvIHBhc3NlZCBhcyB0aGUgZmlyc3QgCiAqCWFyZ3VtZW50IG9mIGVhY2ggY2FsbGJhY2spLCB3aGljaCBjYW4gdGhlbiBiZSB1c2VkIHRvIHJlbW92ZSB0aGUKICoJY2FsbGJhY2sgZnJvbSB0aGUgbGlzdCBhdCBhIGxhdGVyIHBvaW50IGluIHRoZSBmdXR1cmUgdXNpbmcgdGhlCiAqCXNubXBfYWxhcm1fdW5yZWdpc3RlcigpIGZ1bmN0aW9uLiAgSWYgbWVtb3J5IGNvdWxkIG5vdCBiZSBhbGxvY2F0ZWQKICoJZm9yIHRoZSBzbm1wX2FsYXJtIHN0cnVjdCAwIGlzIHJldHVybmVkLgogKgogKiBAc2VlIHNubXBfYWxhcm1fdW5yZWdpc3RlcgogKiBAc2VlIHNubXBfYWxhcm1fcmVnaXN0ZXJfaHIKICogQHNlZSBzbm1wX2FsYXJtX3VucmVnaXN0ZXJfYWxsCiAqLwp1bnNpZ25lZCBpbnQKc25tcF9hbGFybV9yZWdpc3Rlcih1bnNpZ25lZCBpbnQgd2hlbiwgdW5zaWduZWQgaW50IGZsYWdzLAogICAgICAgICAgICAgICAgICAgIFNOTVBBbGFybUNhbGxiYWNrICogdGhlY2FsbGJhY2ssIHZvaWQgKmNsaWVudGFyZykKewogICAgc3RydWN0IHNubXBfYWxhcm0gKipzYV9wcHRyOwogICAgaWYgKHRoZWFsYXJtcyAhPSBOVUxMKSB7CiAgICAgICAgZm9yIChzYV9wcHRyID0gJnRoZWFsYXJtczsgKCpzYV9wcHRyKSAhPSBOVUxMOwogICAgICAgICAgICAgc2FfcHB0ciA9ICYoKCpzYV9wcHRyKS0+bmV4dCkpOwogICAgfSBlbHNlIHsKICAgICAgICBzYV9wcHRyID0gJnRoZWFsYXJtczsKICAgIH0KCiAgICAqc2FfcHB0ciA9IFNOTVBfTUFMTE9DX1NUUlVDVChzbm1wX2FsYXJtKTsKICAgIGlmICgqc2FfcHB0ciA9PSBOVUxMKQogICAgICAgIHJldHVybiAwOwoKICAgIGlmICgwID09IHdoZW4pIHsKICAgICAgICAoKnNhX3BwdHIpLT50LnR2X3NlYyA9IDA7CiAgICAgICAgKCpzYV9wcHRyKS0+dC50dl91c2VjID0gMTsKICAgIH0gZWxzZSB7CiAgICAgICAgKCpzYV9wcHRyKS0+dC50dl9zZWMgPSB3aGVuOwogICAgICAgICgqc2FfcHB0ciktPnQudHZfdXNlYyA9IDA7CiAgICB9CiAgICAoKnNhX3BwdHIpLT5mbGFncyA9IGZsYWdzOwogICAgKCpzYV9wcHRyKS0+Y2xpZW50YXJnID0gY2xpZW50YXJnOwogICAgKCpzYV9wcHRyKS0+dGhlY2FsbGJhY2sgPSB0aGVjYWxsYmFjazsKICAgICgqc2FfcHB0ciktPmNsaWVudHJlZyA9IHJlZ251bSsrOwogICAgKCpzYV9wcHRyKS0+bmV4dCA9IE5VTEw7CiAgICBzYV91cGRhdGVfZW50cnkoKnNhX3BwdHIpOwoKICAgIERFQlVHTVNHVEwoKCJzbm1wX2FsYXJtIiwKCQkicmVnaXN0ZXJlZCBhbGFybSAlZCwgdCA9ICVsZC4lMDNsZCwgZmxhZ3M9MHglMDJ4XG4iLAogICAgICAgICAgICAgICAgKCpzYV9wcHRyKS0+Y2xpZW50cmVnLCAoKnNhX3BwdHIpLT50LnR2X3NlYywKICAgICAgICAgICAgICAgICgoKnNhX3BwdHIpLT50LnR2X3VzZWMgLyAxMDAwKSwgKCpzYV9wcHRyKS0+ZmxhZ3MpKTsKCiAgICBpZiAoc3RhcnRfYWxhcm1zKQogICAgICAgIHNldF9hbl9hbGFybSgpOwogICAgcmV0dXJuICgqc2FfcHB0ciktPmNsaWVudHJlZzsKfQoKCi8qKgogKiBUaGlzIGZ1bmN0aW9uIG9mZmVycyBmaW5lciBncmFudWxhcml0eSBhcyB0byB3aGVuIHRoZSBjYWxsYmFjayAKICogZnVuY3Rpb24gaXMgY2FsbGVkIGJ5IG1ha2luZyB1c2Ugb2YgdC0+dHZfdXNlYyB2YWx1ZSBmb3JtaW5nIHRoZSAKICogIndoZW4iIGFzcGVjdCBvZiBzbm1wX2FsYXJtX3JlZ2lzdGVyKCkuCiAqCiAqIEBwYXJhbSB0IGlzIGEgdGltZXZhbCBzdHJ1Y3R1cmUgdXNlZCB0byBzcGVjaWZ5IHdoZW4gdGhlIGNhbGxiYWNrIAogKglmdW5jdGlvbihhbGFybSkgd2lsbCBiZSBjYWxsZWQuICBBZGRzIHRoZSBhYmlsaXR5IHRvIHNwZWNpZnkKICoJbWljcm9zZWNvbmRzLiAgdC50dl9zZWMgYW5kIHQudHZfdXNlYyBhcmUgYXNzaWduZWQKICoJdG8gc25tcF9hbGFybS0+dHZfc2VjIGFuZCBzbm1wX2FsYXJtLT50dl91c2VjIHJlc3BlY3RpdmVseSBpbnRlcm5hbGx5LgogKglUaGUgc25tcF9hbGFybV9yZWdpc3RlciBmdW5jdGlvbiBvbmx5IGFzc2lnbnMgc2Vjb25kcyhpdCdzIHdoZW4gCiAqCWFyZ3VtZW50KS4KICoKICogQHBhcmFtIGZsYWdzIGlzIGFuIHVuc2lnbmVkIGludGVnZXIgdGhhdCBzcGVjaWZpZXMgaG93IGZyZXF1ZW50IHRoZSBjYWxsYmFjawogKglmdW5jdGlvbiBpcyBjYWxsZWQgaW4gc2Vjb25kcy4gIFNob3VsZCBiZSBTQV9SRVBFQVQgb3IgTlVMTC4gIElmICAKICoJZmxhZ3MgIGlzICBzZXQgd2l0aCBTQV9SRVBFQVQsIHRoZW4gdGhlIHJlZ2lzdGVyZWQgY2FsbGJhY2sgZnVuY3Rpb24KICoJd2lsbCBiZSBjYWxsZWQgZXZlcnkgU0FfUkVQRUFUIHNlY29uZHMuICBJZiBmbGFncyBpcyBOVUxMIHRoZW4gdGhlIAogKglmdW5jdGlvbiB3aWxsIG9ubHkgYmUgY2FsbGVkIG9uY2UgYW5kIHRoZW4gcmVtb3ZlZCBmcm9tIHRoZSAKICoJcmVnaXN0ZXJlZCBhbGFybSBsaXN0LgogKgogKiBAcGFyYW0gY2IgaXMgYSBwb2ludGVyIFNOTVBBbGFybUNhbGxiYWNrIHdoaWNoIGlzIHRoZSBjYWxsYmFjayAKICoJZnVuY3Rpb24gYmVpbmcgc3RvcmVkIGFuZCByZWdpc3RlcmVkLgogKgogKiBAcGFyYW0gY2QgaXMgYSB2b2lkIHBvaW50ZXIgdXNlZCBieSB0aGUgY2FsbGJhY2sgZnVuY3Rpb24uICBUaGlzIAogKglwb2ludGVyIGlzIGFzc2lnbmVkIHRvIHNubXBfYWxhcm0tPmNsaWVudGFyZyBhbmQgcGFzc2VkIGludG8gdGhlCiAqCWNhbGxiYWNrIGZ1bmN0aW9uIGZvciB0aGUgY2xpZW50J3Mgc3BlY2lmYyBuZWVkcy4KICoKICogQHJldHVybiBSZXR1cm5zIGEgdW5pcXVlIHVuc2lnbmVkIGludGVnZXIod2hpY2ggaXMgYWxzbyBwYXNzZWQgYXMgdGhlIGZpcnN0IAogKglhcmd1bWVudCBvZiBlYWNoIGNhbGxiYWNrKSwgd2hpY2ggY2FuIHRoZW4gYmUgdXNlZCB0byByZW1vdmUgdGhlCiAqCWNhbGxiYWNrIGZyb20gdGhlIGxpc3QgYXQgYSBsYXRlciBwb2ludCBpbiB0aGUgZnV0dXJlIHVzaW5nIHRoZQogKglzbm1wX2FsYXJtX3VucmVnaXN0ZXIoKSBmdW5jdGlvbi4gIElmIG1lbW9yeSBjb3VsZCBub3QgYmUgYWxsb2NhdGVkCiAqCWZvciB0aGUgc25tcF9hbGFybSBzdHJ1Y3QgMCBpcyByZXR1cm5lZC4KICoKICogQHNlZSBzbm1wX2FsYXJtX3JlZ2lzdGVyCiAqIEBzZWUgc25tcF9hbGFybV91bnJlZ2lzdGVyCiAqIEBzZWUgc25tcF9hbGFybV91bnJlZ2lzdGVyX2FsbAogKi8KdW5zaWduZWQgaW50CnNubXBfYWxhcm1fcmVnaXN0ZXJfaHIoc3RydWN0IHRpbWV2YWwgdCwgdW5zaWduZWQgaW50IGZsYWdzLAogICAgICAgICAgICAgICAgICAgICAgIFNOTVBBbGFybUNhbGxiYWNrICogY2IsIHZvaWQgKmNkKQp7CiAgICBzdHJ1Y3Qgc25tcF9hbGFybSAqKnMgPSBOVUxMOwoKICAgIGZvciAocyA9ICYodGhlYWxhcm1zKTsgKnMgIT0gTlVMTDsgcyA9ICYoKCpzKS0+bmV4dCkpOwoKICAgICpzID0gU05NUF9NQUxMT0NfU1RSVUNUKHNubXBfYWxhcm0pOwogICAgaWYgKCpzID09IE5VTEwpIHsKICAgICAgICByZXR1cm4gMDsKICAgIH0KCiAgICAoKnMpLT50LnR2X3NlYyA9IHQudHZfc2VjOwogICAgKCpzKS0+dC50dl91c2VjID0gdC50dl91c2VjOwogICAgKCpzKS0+ZmxhZ3MgPSBmbGFnczsKICAgICgqcyktPmNsaWVudGFyZyA9IGNkOwogICAgKCpzKS0+dGhlY2FsbGJhY2sgPSBjYjsKICAgICgqcyktPmNsaWVudHJlZyA9IHJlZ251bSsrOwogICAgKCpzKS0+bmV4dCA9IE5VTEw7CgogICAgc2FfdXBkYXRlX2VudHJ5KCpzKTsKCiAgICBERUJVR01TR1RMKCgic25tcF9hbGFybSIsCiAgICAgICAgICAgICAgICAicmVnaXN0ZXJlZCBhbGFybSAlZCwgdCA9ICVsZC4lMDNsZCwgZmxhZ3M9MHglMDJ4XG4iLAogICAgICAgICAgICAgICAgKCpzKS0+Y2xpZW50cmVnLCAoKnMpLT50LnR2X3NlYywgKCgqcyktPnQudHZfdXNlYyAvIDEwMDApLAogICAgICAgICAgICAgICAgKCpzKS0+ZmxhZ3MpKTsKCiAgICBpZiAoc3RhcnRfYWxhcm1zKSB7CiAgICAgICAgc2V0X2FuX2FsYXJtKCk7CiAgICB9CgogICAgcmV0dXJuICgqcyktPmNsaWVudHJlZzsKfQoKLyoqCiAqIFRoaXMgZnVuY3Rpb24gcmVzZXRzIGFuIGV4aXN0aW5nIGFsYXJtLgogKgogKiBAcGFyYW0gY2xpZW50cmVnIGlzIGEgdW5pcXVlIHVuc2lnbmVkIGludGVnZXIgcmVwcmVzZW50aW5nIGEgcmVnaXN0ZXJlZAogKglhbGFybSB3aGljaCB0aGUgY2xpZW50IHdhbnRzIHRvIHVucmVnaXN0ZXIuCiAqCiAqIEByZXR1cm4gMCBvbiBzdWNjZXNzLCAtMSBpZiB0aGUgYWxhcm0gd2FzIG5vdCBmb3VuZAogKgogKiBAc2VlIHNubXBfYWxhcm1fcmVnaXN0ZXIKICogQHNlZSBzbm1wX2FsYXJtX3JlZ2lzdGVyX2hyCiAqIEBzZWUgc25tcF9hbGFybV91bnJlZ2lzdGVyCiAqLwppbnQKc25tcF9hbGFybV9yZXNldCh1bnNpZ25lZCBpbnQgY2xpZW50cmVnKQp7CiAgICBzdHJ1Y3Qgc25tcF9hbGFybSAqYTsKICAgIHN0cnVjdCB0aW1ldmFsICB0X25vdzsKICAgIGlmICgoYSA9IHNhX2ZpbmRfc3BlY2lmaWMoY2xpZW50cmVnKSkgIT0gTlVMTCkgewogICAgICAgIGdldHRpbWVvZmRheSgmdF9ub3csIE5VTEwpOwogICAgICAgIGEtPnRfbGFzdC50dl9zZWMgPSB0X25vdy50dl9zZWM7CiAgICAgICAgYS0+dF9sYXN0LnR2X3VzZWMgPSB0X25vdy50dl91c2VjOwogICAgICAgIGEtPnRfbmV4dC50dl9zZWMgPSAwOwogICAgICAgIGEtPnRfbmV4dC50dl91c2VjID0gMDsKICAgICAgICBORVRTTk1QX1RJTUVSQUREKCZ0X25vdywgJmEtPnQsICZhLT50X25leHQpOwogICAgICAgIHJldHVybiAwOwogICAgfQogICAgREVCVUdNU0dUTCgoInNubXBfYWxhcm1fcmVzZXQiLCAiYWxhcm0gJWQgbm90IGZvdW5kXG4iLAogICAgICAgICAgICAgICAgY2xpZW50cmVnKSk7CiAgICByZXR1cm4gLTE7Cn0KLyoqICBAfSAqLwo=