LyoKICogc25tcF9hbGFybS5jOgogKi8KLyogUG9ydGlvbnMgb2YgdGhpcyBmaWxlIGFyZSBzdWJqZWN0IHRvIHRoZSBmb2xsb3dpbmcgY29weXJpZ2h0KHMpLiAgU2VlCiAqIHRoZSBOZXQtU05NUCdzIENPUFlJTkcgZmlsZSBmb3IgbW9yZSBkZXRhaWxzIGFuZCBvdGhlciBjb3B5cmlnaHRzCiAqIHRoYXQgbWF5IGFwcGx5OgogKi8KLyoKICogUG9ydGlvbnMgb2YgdGhpcyBmaWxlIGFyZSBjb3B5cmlnaHRlZCBieToKICogQ29weXJpZ2h0IKkgMjAwMyBTdW4gTWljcm9zeXN0ZW1zLCBJbmMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqIFVzZSBpcyBzdWJqZWN0IHRvIGxpY2Vuc2UgdGVybXMgc3BlY2lmaWVkIGluIHRoZSBDT1BZSU5HIGZpbGUKICogZGlzdHJpYnV0ZWQgd2l0aCB0aGUgTmV0LVNOTVAgcGFja2FnZS4KICovCi8qKiBAZGVmZ3JvdXAgc25tcF9hbGFybSAgZ2VuZXJpYyBsaWJyYXJ5IGJhc2VkIGFsYXJtIHRpbWVycyBmb3IgdmFyaW91cyBwYXJ0cyBvZiBhbiBhcHBsaWNhdGlvbiAKICogIEBpbmdyb3VwIGxpYnJhcnkKICogCiAqICBAewogKi8KI2luY2x1ZGUgPG5ldC1zbm1wL25ldC1zbm1wLWNvbmZpZy5oPgoKI2lmIEhBVkVfVU5JU1REX0gKI2luY2x1ZGUgPHVuaXN0ZC5oPgojZW5kaWYKI2luY2x1ZGUgPHNpZ25hbC5oPgojaWYgSEFWRV9TVERMSUJfSAojaW5jbHVkZSA8c3RkbGliLmg+CiNlbmRpZgojaW5jbHVkZSA8c3lzL3R5cGVzLmg+CiNpZiBIQVZFX05FVElORVRfSU5fSAojaW5jbHVkZSA8bmV0aW5ldC9pbi5oPgojZW5kaWYKI2lmIEhBVkVfU1RSSU5HX0gKI2luY2x1ZGUgPHN0cmluZy5oPgojZW5kaWYKCiNpZiBUSU1FX1dJVEhfU1lTX1RJTUUKIyBpbmNsdWRlIDxzeXMvdGltZS5oPgojIGluY2x1ZGUgPHRpbWUuaD4KI2Vsc2UKIyBpZiBIQVZFX1NZU19USU1FX0gKIyAgaW5jbHVkZSA8c3lzL3RpbWUuaD4KIyBlbHNlCiMgIGluY2x1ZGUgPHRpbWUuaD4KIyBlbmRpZgojZW5kaWYKCiNpZiBIQVZFX0RNQUxMT0NfSAojaW5jbHVkZSA8ZG1hbGxvYy5oPgojZW5kaWYKCiNpbmNsdWRlIDxuZXQtc25tcC90eXBlcy5oPgojaW5jbHVkZSA8bmV0LXNubXAvb3V0cHV0X2FwaS5oPgojaW5jbHVkZSA8bmV0LXNubXAvY29uZmlnX2FwaS5oPgojaW5jbHVkZSA8bmV0LXNubXAvdXRpbGl0aWVzLmg+CgojaW5jbHVkZSA8bmV0LXNubXAvbGlicmFyeS9zbm1wX2FwaS5oPgojaW5jbHVkZSA8bmV0LXNubXAvbGlicmFyeS9jYWxsYmFjay5oPgojaW5jbHVkZSA8bmV0LXNubXAvbGlicmFyeS9zbm1wX2FsYXJtLmg+CgpzdGF0aWMgc3RydWN0IHNubXBfYWxhcm0gKnRoZWFsYXJtcyA9IE5VTEw7CnN0YXRpYyBpbnQgICAgICBzdGFydF9hbGFybXMgPSAwOwpzdGF0aWMgdW5zaWduZWQgaW50IHJlZ251bSA9IDE7CgppbnQKaW5pdF9hbGFybV9wb3N0X2NvbmZpZyhpbnQgbWFqb3JpZCwgaW50IG1pbm9yaWQsIHZvaWQgKnNlcnZlcmFyZywKICAgICAgICAgICAgICAgICAgICAgICB2b2lkICpjbGllbnRhcmcpCnsKICAgIHN0YXJ0X2FsYXJtcyA9IDE7CiAgICBzZXRfYW5fYWxhcm0oKTsKICAgIHJldHVybiBTTk1QRVJSX1NVQ0NFU1M7Cn0KCnZvaWQKaW5pdF9zbm1wX2FsYXJtKHZvaWQpCnsKICAgIHN0YXJ0X2FsYXJtcyA9IDA7CiAgICBzbm1wX3JlZ2lzdGVyX2NhbGxiYWNrKFNOTVBfQ0FMTEJBQ0tfTElCUkFSWSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgU05NUF9DQUxMQkFDS19QT1NUX1JFQURfQ09ORklHLAogICAgICAgICAgICAgICAgICAgICAgICAgICBpbml0X2FsYXJtX3Bvc3RfY29uZmlnLCBOVUxMKTsKfQoKdm9pZApzYV91cGRhdGVfZW50cnkoc3RydWN0IHNubXBfYWxhcm0gKmEpCnsKICAgIGlmICghdGltZXJpc3NldCgmYS0+dF9sYXN0KSkgewogICAgICAgIHN0cnVjdCB0aW1ldmFsICB0X25vdzsKICAgICAgICAvKgogICAgICAgICAqIE5ldmVyIGJlZW4gY2FsbGVkIHlldCwgY2FsbCB0aW1lIGB0JyBmcm9tIG5vdy4gIAogICAgICAgICAqLwogICAgICAgIGdldHRpbWVvZmRheSgmdF9ub3csIE5VTEwpOwoKICAgICAgICBhLT50X2xhc3QgPSB0X25vdzsKCiAgICAgICAgTkVUU05NUF9USU1FUkFERCgmdF9ub3csICZhLT50LCAmYS0+dF9uZXh0KTsKICAgIH0gZWxzZSBpZiAoIXRpbWVyaXNzZXQoJmEtPnRfbmV4dCkpIHsKICAgICAgICAvKgogICAgICAgICAqIFdlJ3ZlIGJlZW4gY2FsbGVkIGJ1dCBub3QgcmVzZXQgZm9yIHRoZSBuZXh0IGNhbGwuICAKICAgICAgICAgKi8KICAgICAgICBpZiAoYS0+ZmxhZ3MgJiBTQV9SRVBFQVQpIHsKICAgICAgICAgICAgaWYgKCF0aW1lcmlzc2V0KCZhLT50KSkgewogICAgICAgICAgICAgICAgREVCVUdNU0dUTCgoInNubXBfYWxhcm0iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgInVwZGF0ZV9lbnRyeTogaWxsZWdhbCBpbnRlcnZhbCBzcGVjaWZpZWRcbiIpKTsKICAgICAgICAgICAgICAgIHNubXBfYWxhcm1fdW5yZWdpc3RlcihhLT5jbGllbnRyZWcpOwogICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICB9CgogICAgICAgICAgICBORVRTTk1QX1RJTUVSQUREKCZhLT50X2xhc3QsICZhLT50LCAmYS0+dF9uZXh0KTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAvKgogICAgICAgICAgICAgKiBTaW5nbGUgdGltZSBjYWxsLCByZW1vdmUgaXQuICAKICAgICAgICAgICAgICovCiAgICAgICAgICAgIHNubXBfYWxhcm1fdW5yZWdpc3RlcihhLT5jbGllbnRyZWcpOwogICAgICAgIH0KICAgIH0KfQoKLyoqCiAqIFRoaXMgZnVuY3Rpb24gcmVtb3ZlcyB0aGUgY2FsbGJhY2sgZnVuY3Rpb24gZnJvbSBhIGxpc3Qgb2YgcmVnaXN0ZXJlZAogKiBhbGFybXMsIHVucmVnaXN0ZXJpbmcgdGhlIGFsYXJtLgogKgogKiBAcGFyYW0gY2xpZW50cmVnIGlzIGEgdW5pcXVlIHVuc2lnbmVkIGludGVnZXIgcmVwcmVzZW50aW5nIGEgcmVnaXN0ZXJlZAogKglhbGFybSB3aGljaCB0aGUgY2xpZW50IHdhbnRzIHRvIHVucmVnaXN0ZXIuCiAqCiAqIEByZXR1cm4gdm9pZAogKgogKiBAc2VlIHNubXBfYWxhcm1fcmVnaXN0ZXIKICogQHNlZSBzbm1wX2FsYXJtX3JlZ2lzdGVyX2hyCiAqIEBzZWUgc25tcF9hbGFybV91bnJlZ2lzdGVyX2FsbAogKi8Kdm9pZApzbm1wX2FsYXJtX3VucmVnaXN0ZXIodW5zaWduZWQgaW50IGNsaWVudHJlZykKewogICAgc3RydWN0IHNubXBfYWxhcm0gKnNhX3B0ciwgKipwcmV2TmV4dCA9ICZ0aGVhbGFybXM7CgogICAgZm9yIChzYV9wdHIgPSB0aGVhbGFybXM7CiAgICAgICAgIHNhX3B0ciAhPSBOVUxMICYmIHNhX3B0ci0+Y2xpZW50cmVnICE9IGNsaWVudHJlZzsKICAgICAgICAgc2FfcHRyID0gc2FfcHRyLT5uZXh0KSB7CiAgICAgICAgcHJldk5leHQgPSAmKHNhX3B0ci0+bmV4dCk7CiAgICB9CgogICAgaWYgKHNhX3B0ciAhPSBOVUxMKSB7CiAgICAgICAgKnByZXZOZXh0ID0gc2FfcHRyLT5uZXh0OwogICAgICAgIERFQlVHTVNHVEwoKCJzbm1wX2FsYXJtIiwgInVucmVnaXN0ZXJlZCBhbGFybSAlZFxuIiwgCgkJICAgIHNhX3B0ci0+Y2xpZW50cmVnKSk7CiAgICAgICAgLyoKICAgICAgICAgKiBOb3RlOiBkbyBub3QgZnJlZSB0aGUgY2xpZW50YXJnLCBpdCdzIHRoZSBjbGllbnQncyByZXNwb25zaWJpbGl0eSAKICAgICAgICAgKi8KICAgICAgICBmcmVlKHNhX3B0cik7CiAgICB9IGVsc2UgewogICAgICAgIERFQlVHTVNHVEwoKCJzbm1wX2FsYXJtIiwgIm5vIGFsYXJtICVkIHRvIHVucmVnaXN0ZXJcbiIsIGNsaWVudHJlZykpOwogICAgfQp9CgovKioKICogVGhpcyBmdW5jdGlvbiB1bnJlZ2lzdGVycyBhbGwgYWxhcm1zIGN1cnJlbnRseSBzdG9yZWQuCiAqCiAqIEByZXR1cm4gdm9pZAogKgogKiBAc2VlIHNubXBfYWxhcm1fcmVnaXN0ZXIKICogQHNlZSBzbm1wX2FsYXJtX3JlZ2lzdGVyX2hyCiAqIEBzZWUgc25tcF9hbGFybV91bnJlZ2lzdGVyCiAqLwp2b2lkCnNubXBfYWxhcm1fdW5yZWdpc3Rlcl9hbGwodm9pZCkKewogIHN0cnVjdCBzbm1wX2FsYXJtICpzYV9wdHIsICpzYV90bXA7CgogIGZvciAoc2FfcHRyID0gdGhlYWxhcm1zOyBzYV9wdHIgIT0gTlVMTDsgc2FfcHRyID0gc2FfdG1wKSB7CiAgICBzYV90bXAgPSBzYV9wdHItPm5leHQ7CiAgICBmcmVlKHNhX3B0cik7CiAgfQogIERFQlVHTVNHVEwoKCJzbm1wX2FsYXJtIiwgIkFMTCBhbGFybXMgdW5yZWdpc3RlcmVkXG4iKSk7CiAgdGhlYWxhcm1zID0gTlVMTDsKfSAgCgpzdHJ1Y3Qgc25tcF9hbGFybSAqCnNhX2ZpbmRfbmV4dCh2b2lkKQp7CiAgICBzdHJ1Y3Qgc25tcF9hbGFybSAqYSwgKmxvd2VzdCA9IE5VTEw7CiAgICBzdHJ1Y3QgdGltZXZhbCAgdF9ub3c7CgogICAgZ2V0dGltZW9mZGF5KCZ0X25vdywgTlVMTCk7CgogICAgZm9yIChhID0gdGhlYWxhcm1zOyBhICE9IE5VTEw7IGEgPSBhLT5uZXh0KSB7CiAgICAgICAgaWYgKCEoYS0+ZmxhZ3MgJiBTQV9GSVJFRCkpIHsKICAgICAgICAgICAgLyogY2hlY2sgZm9yIHRpbWUgZGVsdGEgc2tldyAqLwogICAgICAgICAgICBpZiAoKGEtPnRfbmV4dC50dl9zZWMgLSB0X25vdy50dl9zZWMpID4gYS0+dC50dl9zZWMpIHsKICAgICAgICAgICAgICAgIERFQlVHTVNHVEwoKCJ0aW1lX3NrZXciLCAiVGltZSBkZWx0YSB0b28gYmlnICglbGQgc2Vjb25kcyksIHNob3VsZCBiZSAlbGQgc2Vjb25kcyAtIGZpeGluZ1xuIiwKCQkgICAgKGxvbmcpKGEtPnRfbmV4dC50dl9zZWMgLSB0X25vdy50dl9zZWMpLCAobG9uZylhLT50LnR2X3NlYykpOwogICAgICAgICAgICAgICAgTkVUU05NUF9USU1FUkFERCgmdF9ub3csICZhLT50LCAmYS0+dF9uZXh0KTsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAobG93ZXN0ID09IE5VTEwgfHwgdGltZXJjbXAoJmEtPnRfbmV4dCwgJmxvd2VzdC0+dF9uZXh0LCA8KSkKICAgICAgICAgICAgICAgIGxvd2VzdCA9IGE7CiAgICAgICB9CiAgICB9CiAgICByZXR1cm4gbG93ZXN0Owp9CgpORVRTTk1QX0lNUE9SVCBzdHJ1Y3Qgc25tcF9hbGFybSAqc2FfZmluZF9zcGVjaWZpYyh1bnNpZ25lZCBpbnQgY2xpZW50cmVnKTsKc3RydWN0IHNubXBfYWxhcm0gKgpzYV9maW5kX3NwZWNpZmljKHVuc2lnbmVkIGludCBjbGllbnRyZWcpCnsKICAgIHN0cnVjdCBzbm1wX2FsYXJtICpzYV9wdHI7CiAgICBmb3IgKHNhX3B0ciA9IHRoZWFsYXJtczsgc2FfcHRyICE9IE5VTEw7IHNhX3B0ciA9IHNhX3B0ci0+bmV4dCkgewogICAgICAgIGlmIChzYV9wdHItPmNsaWVudHJlZyA9PSBjbGllbnRyZWcpIHsKICAgICAgICAgICAgcmV0dXJuIHNhX3B0cjsKICAgICAgICB9CiAgICB9CiAgICByZXR1cm4gTlVMTDsKfQoKdm9pZApydW5fYWxhcm1zKHZvaWQpCnsKICAgIGludCAgICAgICAgICAgICBkb25lID0gMDsKICAgIHN0cnVjdCBzbm1wX2FsYXJtICphID0gTlVMTDsKICAgIHVuc2lnbmVkIGludCAgICBjbGllbnRyZWc7CiAgICBzdHJ1Y3QgdGltZXZhbCAgdF9ub3c7CgogICAgLyoKICAgICAqIExvb3AgdGhyb3VnaCBldmVyeXRoaW5nIHdlIGhhdmUgcmVwZWF0ZWRseSBsb29raW5nIGZvciB0aGUgbmV4dCB0aGluZyB0bwogICAgICogY2FsbCB1bnRpbCBhbGwgZXZlbnRzIGFyZSBmaW5hbGx5IGluIHRoZSBmdXR1cmUgYWdhaW4uICAKICAgICAqLwoKICAgIHdoaWxlICghZG9uZSkgewogICAgICAgIGlmICgoYSA9IHNhX2ZpbmRfbmV4dCgpKSA9PSBOVUxMKSB7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CgogICAgICAgIGdldHRpbWVvZmRheSgmdF9ub3csIE5VTEwpOwoKICAgICAgICBpZiAodGltZXJjbXAoJmEtPnRfbmV4dCwgJnRfbm93LCA8KSkgewogICAgICAgICAgICBjbGllbnRyZWcgPSBhLT5jbGllbnRyZWc7CiAgICAgICAgICAgIGEtPmZsYWdzIHw9IFNBX0ZJUkVEOwogICAgICAgICAgICBERUJVR01TR1RMKCgic25tcF9hbGFybSIsICJydW4gYWxhcm0gJWRcbiIsIGNsaWVudHJlZykpOwogICAgICAgICAgICAoKihhLT50aGVjYWxsYmFjaykpIChjbGllbnRyZWcsIGEtPmNsaWVudGFyZyk7CiAgICAgICAgICAgIERFQlVHTVNHVEwoKCJzbm1wX2FsYXJtIiwgImFsYXJtICVkIGNvbXBsZXRlZFxuIiwgY2xpZW50cmVnKSk7CgogICAgICAgICAgICBpZiAoKGEgPSBzYV9maW5kX3NwZWNpZmljKGNsaWVudHJlZykpICE9IE5VTEwpIHsKICAgICAgICAgICAgICAgIGEtPnRfbGFzdCA9IHRfbm93OwogICAgICAgICAgICAgICAgdGltZXJjbGVhcigmYS0+dF9uZXh0KTsKICAgICAgICAgICAgICAgIGEtPmZsYWdzICY9IH5TQV9GSVJFRDsKICAgICAgICAgICAgICAgIHNhX3VwZGF0ZV9lbnRyeShhKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIERFQlVHTVNHVEwoKCJzbm1wX2FsYXJtIiwgImFsYXJtICVkIGRlbGV0ZWQgaXRzZWxmXG4iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xpZW50cmVnKSk7CiAgICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBkb25lID0gMTsKICAgICAgICB9CiAgICB9Cn0KCgoKUkVUU0lHVFlQRQphbGFybV9oYW5kbGVyKGludCBhKQp7CiAgICBydW5fYWxhcm1zKCk7CiAgICBzZXRfYW5fYWxhcm0oKTsKfQoKCgovKioKICogTG9vayB1cCB0aGUgdGltZSBhdCB3aGljaCB0aGUgbmV4dCBhbGFybSB3aWxsIGZpcmUuCiAqCiAqIEBwYXJhbVtvdXRdIGFsYXJtX3RtIFRpbWUgYXQgd2hpY2ggdGhlIG5leHQgYWxhcm0gd2lsbCBmaXJlLgogKiBAcGFyYW1baW5dIG5vdyBFYXJsaWVzdCB0aW1lIHRoYXQgc2hvdWxkIGJlIHdyaXR0ZW4gaW50byAqYWxhcm1fdG0uCiAqCiAqIEByZXR1cm4gWmVybyBpZiBubyBhbGFybXMgYXJlIHNjaGVkdWxlZDsgbm9uLXplcm8gJ2NsaWVudHJlZycgdmFsdWUKICogICBpZGVudGlmeWluZyB0aGUgZmlyc3QgYWxhcm0gdGhhdCB3aWxsIGZpcmUgaWYgb25lIG9yIG1vcmUgYWxhcm1zIGFyZQogKiAgIHNjaGVkdWxlZC4KICovCmludApuZXRzbm1wX2dldF9uZXh0X2FsYXJtX3RpbWUoc3RydWN0IHRpbWV2YWwgKmFsYXJtX3RtLCBjb25zdCBzdHJ1Y3QgdGltZXZhbCAqbm93KQp7CiAgICBzdHJ1Y3Qgc25tcF9hbGFybSAqc2FfcHRyOwoKICAgIHNhX3B0ciA9IHNhX2ZpbmRfbmV4dCgpOwoKICAgIGlmIChzYV9wdHIpIHsKICAgICAgICBuZXRzbm1wX2Fzc2VydChhbGFybV90bSk7CiAgICAgICAgbmV0c25tcF9hc3NlcnQodGltZXJpc3NldCgmc2FfcHRyLT50X25leHQpKTsKICAgICAgICBpZiAodGltZXJjbXAoJnNhX3B0ci0+dF9uZXh0LCBub3csID4pKQogICAgICAgICAgICAqYWxhcm1fdG0gPSBzYV9wdHItPnRfbmV4dDsKICAgICAgICBlbHNlCiAgICAgICAgICAgICphbGFybV90bSA9ICpub3c7CiAgICAgICAgcmV0dXJuIHNhX3B0ci0+Y2xpZW50cmVnOwogICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gMDsKICAgIH0KfQoKLyoqCiAqIEdldCB0aGUgdGltZSB1bnRpbCB0aGUgbmV4dCBhbGFybSB3aWxsIGZpcmUuCiAqCiAqIEBwYXJhbVtvdXRdIGRlbHRhIFRpbWUgdW50aWwgdGhlIG5leHQgYWxhcm0uCiAqCiAqIEByZXR1cm4gWmVybyBpZiBubyBhbGFybXMgYXJlIHNjaGVkdWxlZDsgbm9uLXplcm8gJ2NsaWVudHJlZycgdmFsdWUKICogICBpZGVudGlmeWluZyB0aGUgZmlyc3QgYWxhcm0gdGhhdCB3aWxsIGZpcmUgaWYgb25lIG9yIG1vcmUgYWxhcm1zIGFyZQogKiAgIHNjaGVkdWxlZC4KICovCmludApnZXRfbmV4dF9hbGFybV9kZWxheV90aW1lKHN0cnVjdCB0aW1ldmFsICpkZWx0YSkKewogICAgc3RydWN0IHRpbWV2YWwgdF9ub3csIGFsYXJtX3RtOwogICAgaW50IHJlczsKCiAgICBnZXR0aW1lb2ZkYXkoJnRfbm93LCBOVUxMKTsKICAgIHJlcyA9IG5ldHNubXBfZ2V0X25leHRfYWxhcm1fdGltZSgmYWxhcm1fdG0sICZ0X25vdyk7CiAgICBpZiAocmVzKQogICAgICAgIE5FVFNOTVBfVElNRVJTVUIoJmFsYXJtX3RtLCAmdF9ub3csIGRlbHRhKTsKICAgIHJldHVybiByZXM7Cn0KCgp2b2lkCnNldF9hbl9hbGFybSh2b2lkKQp7CiAgICBzdHJ1Y3QgdGltZXZhbCAgZGVsdGE7CiAgICBpbnQgICAgICAgICAgICAgbmV4dGFsYXJtID0gZ2V0X25leHRfYWxhcm1fZGVsYXlfdGltZSgmZGVsdGEpOwoKICAgIC8qCiAgICAgKiBXZSBkb24ndCB1c2Ugc2lnbmFscyBpZiB0aGV5IGFza2VkIHVzIG5pY2VseSBub3QgdG8uICBJdCdzIGV4cGVjdGVkCiAgICAgKiB0aGV5J2xsIGNoZWNrIHRoZSBuZXh0IGFsYXJtIHRpbWUgYW5kIGRvIHRoZWlyIG93biBjYWxsaW5nIG9mCiAgICAgKiBydW5fYWxhcm1zKCkuICAKICAgICAqLwoKICAgIGlmIChuZXh0YWxhcm0gJiYgIW5ldHNubXBfZHNfZ2V0X2Jvb2xlYW4oTkVUU05NUF9EU19MSUJSQVJZX0lELAoJCQkJCU5FVFNOTVBfRFNfTElCX0FMQVJNX0RPTlRfVVNFX1NJRykpIHsKI2lmbmRlZiBXSU4zMgojIGlmZGVmIEhBVkVfU0VUSVRJTUVSCiAgICAgICAgc3RydWN0IGl0aW1lcnZhbCBpdDsKCiAgICAgICAgaXQuaXRfdmFsdWUgPSBkZWx0YTsKICAgICAgICB0aW1lcmNsZWFyKCZpdC5pdF9pbnRlcnZhbCk7CgogICAgICAgIHNpZ25hbChTSUdBTFJNLCBhbGFybV9oYW5kbGVyKTsKICAgICAgICBzZXRpdGltZXIoSVRJTUVSX1JFQUwsICZpdCwgTlVMTCk7CiAgICAgICAgREVCVUdNU0dUTCgoInNubXBfYWxhcm0iLCAic2NoZWR1bGUgYWxhcm0gJWQgaW4gJWxkLiUwM2xkIHNlY29uZHNcbiIsCiAgICAgICAgICAgICAgICAgICAgbmV4dGFsYXJtLCBkZWx0YS50dl9zZWMsIChkZWx0YS50dl91c2VjIC8gMTAwMCkpKTsKIyBlbHNlICAvKiBIQVZFX1NFVElUSU1FUiAqLwojICBpZmRlZiBTSUdBTFJNCiAgICAgICAgc2lnbmFsKFNJR0FMUk0sIGFsYXJtX2hhbmRsZXIpOwogICAgICAgIGFsYXJtKGRlbHRhLnR2X3NlYyk7CiAgICAgICAgREVCVUdNU0dUTCgoInNubXBfYWxhcm0iLAogICAgICAgICAgICAgICAgICAgICJzY2hlZHVsZSBhbGFybSAlZCBpbiByb3VnaGx5ICVsZCBzZWNvbmRzXG4iLCBuZXh0YWxhcm0sCiAgICAgICAgICAgICAgICAgICAgZGVsdGEudHZfc2VjKSk7CiMgIGVuZGlmICAvKiBTSUdBTFJNICovCiMgZW5kaWYgIC8qIEhBVkVfU0VUSVRJTUVSICovCiNlbmRpZiAgLyogV0lOMzIgKi8KCiAgICB9IGVsc2UgewogICAgICAgIERFQlVHTVNHVEwoKCJzbm1wX2FsYXJtIiwgIm5vIGFsYXJtcyBmb3VuZCB0byBzY2hlZHVsZVxuIikpOwogICAgfQp9CgoKLyoqCiAqIFRoaXMgZnVuY3Rpb24gcmVnaXN0ZXJzIGZ1bmN0aW9uIGNhbGxiYWNrcyB0byBvY2N1ciBhdCBhIHNwZWNpZmljIHRpbWUKICogaW4gdGhlIGZ1dHVyZS4KICoKICogQHBhcmFtIHdoZW4gaXMgYW4gdW5zaWduZWQgaW50ZWdlciBzcGVjaWZ5aW5nIHdoZW4gdGhlIGNhbGxiYWNrIGZ1bmN0aW9uCiAqICAgICAgICAgICAgIHdpbGwgYmUgY2FsbGVkIGluIHNlY29uZHMuCiAqCiAqIEBwYXJhbSBmbGFncyBpcyBhbiB1bnNpZ25lZCBpbnRlZ2VyIHRoYXQgc3BlY2lmaWVzIGhvdyBmcmVxdWVudCB0aGUgY2FsbGJhY2sKICoJZnVuY3Rpb24gaXMgY2FsbGVkIGluIHNlY29uZHMuICBTaG91bGQgYmUgU0FfUkVQRUFUIG9yIDAuICBJZiAgCiAqCWZsYWdzICBpcyAgc2V0IHdpdGggU0FfUkVQRUFULCB0aGVuIHRoZSByZWdpc3RlcmVkIGNhbGxiYWNrIGZ1bmN0aW9uCiAqCXdpbGwgYmUgY2FsbGVkIGV2ZXJ5IFNBX1JFUEVBVCBzZWNvbmRzLiAgSWYgZmxhZ3MgaXMgMCB0aGVuIHRoZSAKICoJZnVuY3Rpb24gd2lsbCBvbmx5IGJlIGNhbGxlZCBvbmNlIGFuZCB0aGVuIHJlbW92ZWQgZnJvbSB0aGUgCiAqCXJlZ2lzdGVyZWQgYWxhcm0gbGlzdC4KICoKICogQHBhcmFtIHRoZWNhbGxiYWNrIGlzIGEgcG9pbnRlciBTTk1QQWxhcm1DYWxsYmFjayB3aGljaCBpcyB0aGUgY2FsbGJhY2sgCiAqCWZ1bmN0aW9uIGJlaW5nIHN0b3JlZCBhbmQgcmVnaXN0ZXJlZC4KICoKICogQHBhcmFtIGNsaWVudGFyZyBpcyBhIHZvaWQgcG9pbnRlciB1c2VkIGJ5IHRoZSBjYWxsYmFjayBmdW5jdGlvbi4gIFRoaXMgCiAqCXBvaW50ZXIgaXMgYXNzaWduZWQgdG8gc25tcF9hbGFybS0+Y2xpZW50YXJnIGFuZCBwYXNzZWQgaW50byB0aGUKICoJY2FsbGJhY2sgZnVuY3Rpb24gZm9yIHRoZSBjbGllbnQncyBzcGVjaWZpYyBuZWVkcy4KICoKICogQHJldHVybiBSZXR1cm5zIGEgdW5pcXVlIHVuc2lnbmVkIGludGVnZXIod2hpY2ggaXMgYWxzbyBwYXNzZWQgYXMgdGhlIGZpcnN0IAogKglhcmd1bWVudCBvZiBlYWNoIGNhbGxiYWNrKSwgd2hpY2ggY2FuIHRoZW4gYmUgdXNlZCB0byByZW1vdmUgdGhlCiAqCWNhbGxiYWNrIGZyb20gdGhlIGxpc3QgYXQgYSBsYXRlciBwb2ludCBpbiB0aGUgZnV0dXJlIHVzaW5nIHRoZQogKglzbm1wX2FsYXJtX3VucmVnaXN0ZXIoKSBmdW5jdGlvbi4gIElmIG1lbW9yeSBjb3VsZCBub3QgYmUgYWxsb2NhdGVkCiAqCWZvciB0aGUgc25tcF9hbGFybSBzdHJ1Y3QgMCBpcyByZXR1cm5lZC4KICoKICogQHNlZSBzbm1wX2FsYXJtX3VucmVnaXN0ZXIKICogQHNlZSBzbm1wX2FsYXJtX3JlZ2lzdGVyX2hyCiAqIEBzZWUgc25tcF9hbGFybV91bnJlZ2lzdGVyX2FsbAogKi8KdW5zaWduZWQgaW50CnNubXBfYWxhcm1fcmVnaXN0ZXIodW5zaWduZWQgaW50IHdoZW4sIHVuc2lnbmVkIGludCBmbGFncywKICAgICAgICAgICAgICAgICAgICBTTk1QQWxhcm1DYWxsYmFjayAqIHRoZWNhbGxiYWNrLCB2b2lkICpjbGllbnRhcmcpCnsKICAgIHN0cnVjdCB0aW1ldmFsICB0OwoKICAgIGlmICgwID09IHdoZW4pIHsKICAgICAgICB0LnR2X3NlYyA9IDA7CiAgICAgICAgdC50dl91c2VjID0gMTsKICAgIH0gZWxzZSB7CiAgICAgICAgdC50dl9zZWMgPSB3aGVuOwogICAgICAgIHQudHZfdXNlYyA9IDA7CiAgICB9CgogICAgcmV0dXJuIHNubXBfYWxhcm1fcmVnaXN0ZXJfaHIodCwgZmxhZ3MsIHRoZWNhbGxiYWNrLCBjbGllbnRhcmcpOwp9CgoKLyoqCiAqIFRoaXMgZnVuY3Rpb24gb2ZmZXJzIGZpbmVyIGdyYW51bGFyaXR5IGFzIHRvIHdoZW4gdGhlIGNhbGxiYWNrIAogKiBmdW5jdGlvbiBpcyBjYWxsZWQgYnkgbWFraW5nIHVzZSBvZiB0LT50dl91c2VjIHZhbHVlIGZvcm1pbmcgdGhlIAogKiAid2hlbiIgYXNwZWN0IG9mIHNubXBfYWxhcm1fcmVnaXN0ZXIoKS4KICoKICogQHBhcmFtIHQgaXMgYSB0aW1ldmFsIHN0cnVjdHVyZSB1c2VkIHRvIHNwZWNpZnkgd2hlbiB0aGUgY2FsbGJhY2sgCiAqCWZ1bmN0aW9uKGFsYXJtKSB3aWxsIGJlIGNhbGxlZC4gIEFkZHMgdGhlIGFiaWxpdHkgdG8gc3BlY2lmeQogKgltaWNyb3NlY29uZHMuICB0LnR2X3NlYyBhbmQgdC50dl91c2VjIGFyZSBhc3NpZ25lZAogKgl0byBzbm1wX2FsYXJtLT50dl9zZWMgYW5kIHNubXBfYWxhcm0tPnR2X3VzZWMgcmVzcGVjdGl2ZWx5IGludGVybmFsbHkuCiAqCVRoZSBzbm1wX2FsYXJtX3JlZ2lzdGVyIGZ1bmN0aW9uIG9ubHkgYXNzaWducyBzZWNvbmRzKGl0J3Mgd2hlbiAKICoJYXJndW1lbnQpLgogKgogKiBAcGFyYW0gZmxhZ3MgaXMgYW4gdW5zaWduZWQgaW50ZWdlciB0aGF0IHNwZWNpZmllcyBob3cgZnJlcXVlbnQgdGhlIGNhbGxiYWNrCiAqCWZ1bmN0aW9uIGlzIGNhbGxlZCBpbiBzZWNvbmRzLiAgU2hvdWxkIGJlIFNBX1JFUEVBVCBvciBOVUxMLiAgSWYgIAogKglmbGFncyAgaXMgIHNldCB3aXRoIFNBX1JFUEVBVCwgdGhlbiB0aGUgcmVnaXN0ZXJlZCBjYWxsYmFjayBmdW5jdGlvbgogKgl3aWxsIGJlIGNhbGxlZCBldmVyeSBTQV9SRVBFQVQgc2Vjb25kcy4gIElmIGZsYWdzIGlzIE5VTEwgdGhlbiB0aGUgCiAqCWZ1bmN0aW9uIHdpbGwgb25seSBiZSBjYWxsZWQgb25jZSBhbmQgdGhlbiByZW1vdmVkIGZyb20gdGhlIAogKglyZWdpc3RlcmVkIGFsYXJtIGxpc3QuCiAqCiAqIEBwYXJhbSBjYiBpcyBhIHBvaW50ZXIgU05NUEFsYXJtQ2FsbGJhY2sgd2hpY2ggaXMgdGhlIGNhbGxiYWNrIAogKglmdW5jdGlvbiBiZWluZyBzdG9yZWQgYW5kIHJlZ2lzdGVyZWQuCiAqCiAqIEBwYXJhbSBjZCBpcyBhIHZvaWQgcG9pbnRlciB1c2VkIGJ5IHRoZSBjYWxsYmFjayBmdW5jdGlvbi4gIFRoaXMgCiAqCXBvaW50ZXIgaXMgYXNzaWduZWQgdG8gc25tcF9hbGFybS0+Y2xpZW50YXJnIGFuZCBwYXNzZWQgaW50byB0aGUKICoJY2FsbGJhY2sgZnVuY3Rpb24gZm9yIHRoZSBjbGllbnQncyBzcGVjaWZpYyBuZWVkcy4KICoKICogQHJldHVybiBSZXR1cm5zIGEgdW5pcXVlIHVuc2lnbmVkIGludGVnZXIod2hpY2ggaXMgYWxzbyBwYXNzZWQgYXMgdGhlIGZpcnN0IAogKglhcmd1bWVudCBvZiBlYWNoIGNhbGxiYWNrKSwgd2hpY2ggY2FuIHRoZW4gYmUgdXNlZCB0byByZW1vdmUgdGhlCiAqCWNhbGxiYWNrIGZyb20gdGhlIGxpc3QgYXQgYSBsYXRlciBwb2ludCBpbiB0aGUgZnV0dXJlIHVzaW5nIHRoZQogKglzbm1wX2FsYXJtX3VucmVnaXN0ZXIoKSBmdW5jdGlvbi4gIElmIG1lbW9yeSBjb3VsZCBub3QgYmUgYWxsb2NhdGVkCiAqCWZvciB0aGUgc25tcF9hbGFybSBzdHJ1Y3QgMCBpcyByZXR1cm5lZC4KICoKICogQHNlZSBzbm1wX2FsYXJtX3JlZ2lzdGVyCiAqIEBzZWUgc25tcF9hbGFybV91bnJlZ2lzdGVyCiAqIEBzZWUgc25tcF9hbGFybV91bnJlZ2lzdGVyX2FsbAogKi8KdW5zaWduZWQgaW50CnNubXBfYWxhcm1fcmVnaXN0ZXJfaHIoc3RydWN0IHRpbWV2YWwgdCwgdW5zaWduZWQgaW50IGZsYWdzLAogICAgICAgICAgICAgICAgICAgICAgIFNOTVBBbGFybUNhbGxiYWNrICogY2IsIHZvaWQgKmNkKQp7CiAgICBzdHJ1Y3Qgc25tcF9hbGFybSAqKnMgPSBOVUxMOwoKICAgIGZvciAocyA9ICYodGhlYWxhcm1zKTsgKnMgIT0gTlVMTDsgcyA9ICYoKCpzKS0+bmV4dCkpOwoKICAgICpzID0gU05NUF9NQUxMT0NfU1RSVUNUKHNubXBfYWxhcm0pOwogICAgaWYgKCpzID09IE5VTEwpIHsKICAgICAgICByZXR1cm4gMDsKICAgIH0KCiAgICAoKnMpLT50ID0gdDsKICAgICgqcyktPmZsYWdzID0gZmxhZ3M7CiAgICAoKnMpLT5jbGllbnRhcmcgPSBjZDsKICAgICgqcyktPnRoZWNhbGxiYWNrID0gY2I7CiAgICAoKnMpLT5jbGllbnRyZWcgPSByZWdudW0rKzsKICAgICgqcyktPm5leHQgPSBOVUxMOwoKICAgIHNhX3VwZGF0ZV9lbnRyeSgqcyk7CgogICAgREVCVUdNU0dUTCgoInNubXBfYWxhcm0iLAogICAgICAgICAgICAgICAgInJlZ2lzdGVyZWQgYWxhcm0gJWQsIHQgPSAlbGQuJTAzbGQsIGZsYWdzPTB4JTAyeFxuIiwKICAgICAgICAgICAgICAgICgqcyktPmNsaWVudHJlZywgKCpzKS0+dC50dl9zZWMsICgoKnMpLT50LnR2X3VzZWMgLyAxMDAwKSwKICAgICAgICAgICAgICAgICgqcyktPmZsYWdzKSk7CgogICAgaWYgKHN0YXJ0X2FsYXJtcykgewogICAgICAgIHNldF9hbl9hbGFybSgpOwogICAgfQoKICAgIHJldHVybiAoKnMpLT5jbGllbnRyZWc7Cn0KCi8qKgogKiBUaGlzIGZ1bmN0aW9uIHJlc2V0cyBhbiBleGlzdGluZyBhbGFybS4KICoKICogQHBhcmFtIGNsaWVudHJlZyBpcyBhIHVuaXF1ZSB1bnNpZ25lZCBpbnRlZ2VyIHJlcHJlc2VudGluZyBhIHJlZ2lzdGVyZWQKICoJYWxhcm0gd2hpY2ggdGhlIGNsaWVudCB3YW50cyB0byB1bnJlZ2lzdGVyLgogKgogKiBAcmV0dXJuIDAgb24gc3VjY2VzcywgLTEgaWYgdGhlIGFsYXJtIHdhcyBub3QgZm91bmQKICoKICogQHNlZSBzbm1wX2FsYXJtX3JlZ2lzdGVyCiAqIEBzZWUgc25tcF9hbGFybV9yZWdpc3Rlcl9ocgogKiBAc2VlIHNubXBfYWxhcm1fdW5yZWdpc3RlcgogKi8KaW50CnNubXBfYWxhcm1fcmVzZXQodW5zaWduZWQgaW50IGNsaWVudHJlZykKewogICAgc3RydWN0IHNubXBfYWxhcm0gKmE7CiAgICBzdHJ1Y3QgdGltZXZhbCAgdF9ub3c7CiAgICBpZiAoKGEgPSBzYV9maW5kX3NwZWNpZmljKGNsaWVudHJlZykpICE9IE5VTEwpIHsKICAgICAgICBnZXR0aW1lb2ZkYXkoJnRfbm93LCBOVUxMKTsKICAgICAgICBhLT50X2xhc3QudHZfc2VjID0gdF9ub3cudHZfc2VjOwogICAgICAgIGEtPnRfbGFzdC50dl91c2VjID0gdF9ub3cudHZfdXNlYzsKICAgICAgICBhLT50X25leHQudHZfc2VjID0gMDsKICAgICAgICBhLT50X25leHQudHZfdXNlYyA9IDA7CiAgICAgICAgTkVUU05NUF9USU1FUkFERCgmdF9ub3csICZhLT50LCAmYS0+dF9uZXh0KTsKICAgICAgICByZXR1cm4gMDsKICAgIH0KICAgIERFQlVHTVNHVEwoKCJzbm1wX2FsYXJtX3Jlc2V0IiwgImFsYXJtICVkIG5vdCBmb3VuZFxuIiwKICAgICAgICAgICAgICAgIGNsaWVudHJlZykpOwogICAgcmV0dXJuIC0xOwp9Ci8qKiAgQH0gKi8K