LyoKICogVGhpcyBwcm9ncmFtIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkKICogaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkKICogdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyIHZlcnNpb24gMiBvZiB0aGUgTGljZW5zZSwgb3IKICogKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi4KICoKICogQ29weXJpZ2h0IChDKSBKb25hdGhhbiBOYXlsb3IgRzRLTFggKGc0a2x4QGc0a2x4LmRlbW9uLmNvLnVrKQogKiBDb3B5cmlnaHQgKEMpIEpvZXJnIFJldXRlciBETDFCS0UgKGpyZXV0ZXJAeWFpbmEuZGUpCiAqLwojaW5jbHVkZSA8bGludXgvZXJybm8uaD4KI2luY2x1ZGUgPGxpbnV4L3R5cGVzLmg+CiNpbmNsdWRlIDxsaW51eC9zb2NrZXQuaD4KI2luY2x1ZGUgPGxpbnV4L2luLmg+CiNpbmNsdWRlIDxsaW51eC9rZXJuZWwuaD4KI2luY2x1ZGUgPGxpbnV4L3NjaGVkLmg+CiNpbmNsdWRlIDxsaW51eC90aW1lci5oPgojaW5jbHVkZSA8bGludXgvc3RyaW5nLmg+CiNpbmNsdWRlIDxsaW51eC9zb2NraW9zLmg+CiNpbmNsdWRlIDxsaW51eC9zcGlubG9jay5oPgojaW5jbHVkZSA8bGludXgvbmV0Lmg+CiNpbmNsdWRlIDxuZXQvYXgyNS5oPgojaW5jbHVkZSA8bGludXgvaW5ldC5oPgojaW5jbHVkZSA8bGludXgvbmV0ZGV2aWNlLmg+CiNpbmNsdWRlIDxsaW51eC9za2J1ZmYuaD4KI2luY2x1ZGUgPG5ldC9zb2NrLmg+CiNpbmNsdWRlIDxhc20vdWFjY2Vzcy5oPgojaW5jbHVkZSA8YXNtL3N5c3RlbS5oPgojaW5jbHVkZSA8bGludXgvZmNudGwuaD4KI2luY2x1ZGUgPGxpbnV4L21tLmg+CiNpbmNsdWRlIDxsaW51eC9pbnRlcnJ1cHQuaD4KCnZvaWQgYXgyNV9kc19ucl9lcnJvcl9yZWNvdmVyeShheDI1X2NiICpheDI1KQp7CglheDI1X2RzX2VzdGFibGlzaF9kYXRhX2xpbmsoYXgyNSk7Cn0KCi8qCiAqCWRsMWJrZSA5NjAxMTQ6IHRyYW5zbWl0IEkgZnJhbWVzIG9uIERBTUEgcG9sbAogKi8Kdm9pZCBheDI1X2RzX2VucXVpcnlfcmVzcG9uc2UoYXgyNV9jYiAqYXgyNSkKewoJYXgyNV9jYiAqYXgyNW87CglzdHJ1Y3QgaGxpc3Rfbm9kZSAqbm9kZTsKCgkvKiBQbGVhc2Ugbm90ZSB0aGF0IG5laXRoZXIgREs0RUe0cyBub3IgREcyRkVGtHMKCSAqIERBTUEgc3BlYyBtZW50aW9uIHRoZSBmb2xsb3dpbmcgYmVoYXZpb3VyIGFzIHNlZW4KCSAqIHdpdGggVGhlRmlybXdhcmU6CgkgKgoJICogCURCMEFDSC0+REwxQktFIDxSUiBDIFAgUjA+IFtEQU1BXQoJICoJREwxQktFLT5EQjBBQ0ggPEkgTlI9MCBOUz0wPgoJICoJREwxQktFLTctPkRCMFBSQS02IERCMEFDSCA8SSBDIFMzIFI1PgoJICoJREwxQktFLT5EQjBBQ0ggPFJSIFIgRiBSMD4KCSAqCgkgKiBUaGUgRmxleG5ldCBEQU1BIE1hc3RlciBpbXBsZW1lbnRhdGlvbiBhcHBhcmVudGx5CgkgKiBpbnNpc3RzIG9uIHRoZSAicHJvcGVyIiBBWC4yNSBiZWhhdmlvdXI6CgkgKgoJICogCURCMEFDSC0+REwxQktFIDxSUiBDIFAgUjA+IFtEQU1BXQoJICoJREwxQktFLT5EQjBBQ0ggPFJSIFIgRiBSMD4KCSAqCURMMUJLRS0+REIwQUNIIDxJIE5SPTAgTlM9MD4KCSAqCURMMUJLRS03LT5EQjBQUkEtNiBEQjBBQ0ggPEkgQyBTMyBSNT4KCSAqCgkgKiBGbGV4bmV0IHJlZnVzZXMgdG8gc2VuZCB1cyAqYW55KiBJIGZyYW1lIGlmIHdlIHNlbmQKCSAqIGEgUkVKIGluIGNhc2UgQVgyNV9DT05EX1JFSkVDVCBpcyBzZXQuIEl0IGlzIHN1cGVyZmx1b3VzIGluCgkgKiB0aGlzIG1vZGUgYW55d2F5IChhIFJSIG9yIFJOUiBpbnZva2VzIHRoZSByZXRyYW5zbWlzc2lvbikuCgkgKiBJcyB0aGlzIGEgRmxleG5ldCBidWc/CgkgKi8KCglheDI1X3N0ZF9lbnF1aXJ5X3Jlc3BvbnNlKGF4MjUpOwoKCWlmICghKGF4MjUtPmNvbmRpdGlvbiAmIEFYMjVfQ09ORF9QRUVSX1JYX0JVU1kpKSB7CgkJYXgyNV9yZXF1ZXVlX2ZyYW1lcyhheDI1KTsKCQlheDI1X2tpY2soYXgyNSk7Cgl9CgoJaWYgKGF4MjUtPnN0YXRlID09IEFYMjVfU1RBVEVfMSB8fCBheDI1LT5zdGF0ZSA9PSBBWDI1X1NUQVRFXzIgfHwgc2tiX3BlZWsoJmF4MjUtPmFja19xdWV1ZSkgIT0gTlVMTCkKCQlheDI1X2RzX3QxX3RpbWVvdXQoYXgyNSk7CgllbHNlCgkJYXgyNS0+bjJjb3VudCA9IDA7CgoJYXgyNV9zdGFydF90M3RpbWVyKGF4MjUpOwoJYXgyNV9kc19zZXRfdGltZXIoYXgyNS0+YXgyNV9kZXYpOwoKCXNwaW5fbG9ja19iaCgmYXgyNV9saXN0X2xvY2spOwoJYXgyNV9mb3JfZWFjaChheDI1bywgbm9kZSwgJmF4MjVfbGlzdCkgewoJCWlmIChheDI1byA9PSBheDI1KQoJCQljb250aW51ZTsKCgkJaWYgKGF4MjVvLT5heDI1X2RldiAhPSBheDI1LT5heDI1X2RldikKCQkJY29udGludWU7CgoJCWlmIChheDI1by0+c3RhdGUgPT0gQVgyNV9TVEFURV8xIHx8IGF4MjVvLT5zdGF0ZSA9PSBBWDI1X1NUQVRFXzIpIHsKCQkJYXgyNV9kc190MV90aW1lb3V0KGF4MjVvKTsKCQkJY29udGludWU7CgkJfQoKCQlpZiAoIShheDI1by0+Y29uZGl0aW9uICYgQVgyNV9DT05EX1BFRVJfUlhfQlVTWSkgJiYgYXgyNW8tPnN0YXRlID09IEFYMjVfU1RBVEVfMykgewoJCQlheDI1X3JlcXVldWVfZnJhbWVzKGF4MjVvKTsKCQkJYXgyNV9raWNrKGF4MjVvKTsKCQl9CgoJCWlmIChheDI1by0+c3RhdGUgPT0gQVgyNV9TVEFURV8xIHx8IGF4MjVvLT5zdGF0ZSA9PSBBWDI1X1NUQVRFXzIgfHwgc2tiX3BlZWsoJmF4MjVvLT5hY2tfcXVldWUpICE9IE5VTEwpCgkJCWF4MjVfZHNfdDFfdGltZW91dChheDI1byk7CgoJCS8qIGRvIG5vdCBzdGFydCBUMyBmb3IgbGlzdGVuaW5nIHNvY2tldHMgKHRueCBERDhORSkgKi8KCgkJaWYgKGF4MjVvLT5zdGF0ZSAhPSBBWDI1X1NUQVRFXzApCgkJCWF4MjVfc3RhcnRfdDN0aW1lcihheDI1byk7Cgl9CglzcGluX3VubG9ja19iaCgmYXgyNV9saXN0X2xvY2spOwp9Cgp2b2lkIGF4MjVfZHNfZXN0YWJsaXNoX2RhdGFfbGluayhheDI1X2NiICpheDI1KQp7CglheDI1LT5jb25kaXRpb24gJj0gQVgyNV9DT05EX0RBTUFfTU9ERTsKCWF4MjUtPm4yY291bnQgICAgPSAwOwoJYXgyNV9jYWxjdWxhdGVfdDEoYXgyNSk7CglheDI1X3N0YXJ0X3QxdGltZXIoYXgyNSk7CglheDI1X3N0b3BfdDJ0aW1lcihheDI1KTsKCWF4MjVfc3RhcnRfdDN0aW1lcihheDI1KTsKfQoKLyoKICoJOjo6RklYTUU6OjoKICoJVGhpcyBpcyBhIGtsdWRnZS4gTm90IGFsbCBkcml2ZXJzIHJlY29nbml6ZSBraXNzIGNvbW1hbmRzLgogKglXZSBuZWVkIGEgZHJpdmVyIGxldmVsICByZXF1ZXN0IHRvIHN3aXRjaCBkdXBsZXggbW9kZSwgdGhhdCBkb2VzCiAqCWVpdGhlciBTQ0MgY2hhbmdpbmcsIFBJIGNvbmZpZyBvciBLSVNTIGFzIHJlcXVpcmVkLiBDdXJyZW50bHkKICoJdGhpcyByZXF1ZXN0IGlzbid0IHJlbGlhYmxlLgogKi8Kc3RhdGljIHZvaWQgYXgyNV9raXNzX2NtZChheDI1X2RldiAqYXgyNV9kZXYsIHVuc2lnbmVkIGNoYXIgY21kLCB1bnNpZ25lZCBjaGFyIHBhcmFtKQp7CglzdHJ1Y3Qgc2tfYnVmZiAqc2tiOwoJdW5zaWduZWQgY2hhciAqcDsKCglpZiAoYXgyNV9kZXYtPmRldiA9PSBOVUxMKQoJCXJldHVybjsKCglpZiAoKHNrYiA9IGFsbG9jX3NrYigyLCBHRlBfQVRPTUlDKSkgPT0gTlVMTCkKCQlyZXR1cm47CgoJc2tiLT5uaC5yYXcgPSBza2ItPmRhdGE7CglwID0gc2tiX3B1dChza2IsIDIpOwoKCSpwKysgPSBjbWQ7CgkqcCsrID0gcGFyYW07CgoJc2tiLT5kZXYgICAgICA9IGF4MjVfZGV2LT5kZXY7Cglza2ItPnByb3RvY29sID0gaHRvbnMoRVRIX1BfQVgyNSk7CgoJZGV2X3F1ZXVlX3htaXQoc2tiKTsKfQoKLyoKICoJQSBuYXN0eSBwcm9ibGVtIGFyaXNlcyBpZiB3ZSBjb3VudCB0aGUgbnVtYmVyIG9mIERBTUEgY29ubmVjdGlvbnMKICoJd3JvbmcsIGVzcGVjaWFsbHkgd2hlbiBjb25uZWN0aW9ucyBvbiB0aGUgZGV2aWNlIGFscmVhZHkgZXhpc3RlZAogKglhbmQgb3VyIG5ldHdvcmsgbm9kZSAob3IgdGhlIHN5c29wKSBkZWNpZGVzIHRvIHR1cm4gb24gREFNQSBNYXN0ZXIKICoJbW9kZS4gV2UgdGh1cyBmbGFnIHRoZSAncmVhbCcgc2xhdmUgY29ubmVjdGlvbnMgd2l0aAogKglheDI1LT5kYW1hX3NsYXZlPTEgYW5kIGxvb2sgb24gZXZlcnkgZGlzY29ubmVjdCBpZiBzdGlsbCBzbGF2ZQogKgljb25uZWN0aW9ucyBleGlzdC4KICovCnN0YXRpYyBpbnQgYXgyNV9jaGVja19kYW1hX3NsYXZlKGF4MjVfZGV2ICpheDI1X2RldikKewoJYXgyNV9jYiAqYXgyNTsKCWludCByZXMgPSAwOwoJc3RydWN0IGhsaXN0X25vZGUgKm5vZGU7CgoJc3Bpbl9sb2NrX2JoKCZheDI1X2xpc3RfbG9jayk7CglheDI1X2Zvcl9lYWNoKGF4MjUsIG5vZGUsICZheDI1X2xpc3QpCgkJaWYgKGF4MjUtPmF4MjVfZGV2ID09IGF4MjVfZGV2ICYmIChheDI1LT5jb25kaXRpb24gJiBBWDI1X0NPTkRfREFNQV9NT0RFKSAmJiBheDI1LT5zdGF0ZSA+IEFYMjVfU1RBVEVfMSkgewoJCQlyZXMgPSAxOwoJCQlicmVhazsKCQl9CglzcGluX3VubG9ja19iaCgmYXgyNV9saXN0X2xvY2spOwoKCXJldHVybiByZXM7Cn0KCnN0YXRpYyB2b2lkIGF4MjVfZGV2X2RhbWFfb24oYXgyNV9kZXYgKmF4MjVfZGV2KQp7CglpZiAoYXgyNV9kZXYgPT0gTlVMTCkKCQlyZXR1cm47CgoJaWYgKGF4MjVfZGV2LT5kYW1hLnNsYXZlID09IDApCgkJYXgyNV9raXNzX2NtZChheDI1X2RldiwgNSwgMSk7CgoJYXgyNV9kZXYtPmRhbWEuc2xhdmUgPSAxOwoJYXgyNV9kc19zZXRfdGltZXIoYXgyNV9kZXYpOwp9Cgp2b2lkIGF4MjVfZGV2X2RhbWFfb2ZmKGF4MjVfZGV2ICpheDI1X2RldikKewoJaWYgKGF4MjVfZGV2ID09IE5VTEwpCgkJcmV0dXJuOwoKCWlmIChheDI1X2Rldi0+ZGFtYS5zbGF2ZSAmJiAhYXgyNV9jaGVja19kYW1hX3NsYXZlKGF4MjVfZGV2KSkgewoJCWF4MjVfa2lzc19jbWQoYXgyNV9kZXYsIDUsIDApOwoJCWF4MjVfZGV2LT5kYW1hLnNsYXZlID0gMDsKCQlheDI1X2RzX2RlbF90aW1lcihheDI1X2Rldik7Cgl9Cn0KCnZvaWQgYXgyNV9kYW1hX29uKGF4MjVfY2IgKmF4MjUpCnsKCWF4MjVfZGV2X2RhbWFfb24oYXgyNS0+YXgyNV9kZXYpOwoJYXgyNS0+Y29uZGl0aW9uIHw9IEFYMjVfQ09ORF9EQU1BX01PREU7Cn0KCnZvaWQgYXgyNV9kYW1hX29mZihheDI1X2NiICpheDI1KQp7CglheDI1LT5jb25kaXRpb24gJj0gfkFYMjVfQ09ORF9EQU1BX01PREU7CglheDI1X2Rldl9kYW1hX29mZihheDI1LT5heDI1X2Rldik7Cn0KCg==