LyoKICogKEMpIENvcHlyaWdodCAyMDAwLTIwMDIKICogV29sZmdhbmcgRGVuaywgREVOWCBTb2Z0d2FyZSBFbmdpbmVlcmluZywgd2RAZGVueC5kZS4KICoKICogU2VlIGZpbGUgQ1JFRElUUyBmb3IgbGlzdCBvZiBwZW9wbGUgd2hvIGNvbnRyaWJ1dGVkIHRvIHRoaXMKICogcHJvamVjdC4KICoKICogVGhpcyBwcm9ncmFtIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vcgogKiBtb2RpZnkgaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBhcwogKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyIHZlcnNpb24gMiBvZgogKiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi4KICoKICogVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsCiAqIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mCiAqIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUKICogR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKICogYWxvbmcgd2l0aCB0aGlzIHByb2dyYW07IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUKICogRm91bmRhdGlvbiwgSW5jLiwgNTkgVGVtcGxlIFBsYWNlLCBTdWl0ZSAzMzAsIEJvc3RvbiwKICogTUEgMDIxMTEtMTMwNyBVU0EKICovCgojaW5jbHVkZSA8Y29tbW9uLmg+CiNpbmNsdWRlIDxtcGM4MjYwLmg+CiNpbmNsdWRlIDxhc20vY3BtXzgyNjAuaD4KI2luY2x1ZGUgPGlvcG9ydHMuaD4KCkRFQ0xBUkVfR0xPQkFMX0RBVEFfUFRSOwoKI2lmIGRlZmluZWQoQ09ORklHX0JPQVJEX0dFVF9DUFVfQ0xLX0YpCmV4dGVybiB1bnNpZ25lZCBsb25nIGJvYXJkX2dldF9jcHVfY2xrX2YgKHZvaWQpOwojZW5kaWYKCnN0YXRpYyB2b2lkIGNvbmZpZ184MjYwX2lvcG9ydHMgKHZvbGF0aWxlIGltbWFwX3QgKiBpbW1yKQp7CglpbnQgcG9ydG51bTsKCglmb3IgKHBvcnRudW0gPSAwOyBwb3J0bnVtIDwgNDsgcG9ydG51bSsrKSB7CgkJdWludCBwbXNrID0gMCwKCQkgICAgIHBwYXIgPSAwLAoJCSAgICAgcHNvciA9IDAsCgkJICAgICBwZGlyID0gMCwKCQkgICAgIHBvZHIgPSAwLAoJCSAgICAgcGRhdCA9IDA7CgkJaW9wX2NvbmZfdCAqaW9wYyA9IChpb3BfY29uZl90ICopICYgaW9wX2NvbmZfdGFiW3BvcnRudW1dWzBdOwoJCWlvcF9jb25mX3QgKmVpb3BjID0gaW9wYyArIDMyOwoJCXVpbnQgbXNrID0gMTsKCgkJLyoKCQkgKiBOT1RFOgoJCSAqIGluZGV4IDAgcmVmZXJzIHRvIHBpbiAzMSwKCQkgKiBpbmRleCAzMSByZWZlcnMgdG8gcGluIDAKCQkgKi8KCQl3aGlsZSAoaW9wYyA8IGVpb3BjKSB7CgkJCWlmIChpb3BjLT5jb25mKSB7CgkJCQlwbXNrIHw9IG1zazsKCQkJCWlmIChpb3BjLT5wcGFyKQoJCQkJCXBwYXIgfD0gbXNrOwoJCQkJaWYgKGlvcGMtPnBzb3IpCgkJCQkJcHNvciB8PSBtc2s7CgkJCQlpZiAoaW9wYy0+cGRpcikKCQkJCQlwZGlyIHw9IG1zazsKCQkJCWlmIChpb3BjLT5wb2RyKQoJCQkJCXBvZHIgfD0gbXNrOwoJCQkJaWYgKGlvcGMtPnBkYXQpCgkJCQkJcGRhdCB8PSBtc2s7CgkJCX0KCgkJCW1zayA8PD0gMTsKCQkJaW9wYysrOwoJCX0KCgkJaWYgKHBtc2sgIT0gMCkgewoJCQl2b2xhdGlsZSBpb3BvcnRfdCAqaW9wID0gaW9wb3J0X2FkZHIgKGltbXIsIHBvcnRudW0pOwoJCQl1aW50IHRwbXNrID0gfnBtc2s7CgoJCQkvKgoJCQkgKiB0aGUgKHNvbWV3aGF0IGNvbmZ1c2VkKSBwYXJhZ3JhcGggYXQgdGhlCgkJCSAqIGJvdHRvbSBvZiBwYWdlIDM1LTUgd2FybnMgdGhhdCB0aGVyZSBtaWdodAoJCQkgKiBiZSAidW5rbm93biBiZWhhdmlvdXIiIHdoZW4gcHJvZ3JhbW1pbmcKCQkJICogUFNPUnggYW5kIFBESVJ4LCBpZiBQUEFSeCA9IDEsIHNvIEkKCQkJICogZGVjaWRlZCB0aGlzIG1lYW50IEkgaGFkIHRvIGRpc2FibGUgdGhlCgkJCSAqIGRlZGljYXRlZCBmdW5jdGlvbiBmaXJzdCwgYW5kIGVuYWJsZSBpdAoJCQkgKiBsYXN0LgoJCQkgKi8KCQkJaW9wLT5wcGFyICY9IHRwbXNrOwoJCQlpb3AtPnBzb3IgPSAoaW9wLT5wc29yICYgdHBtc2spIHwgcHNvcjsKCQkJaW9wLT5wb2RyID0gKGlvcC0+cG9kciAmIHRwbXNrKSB8IHBvZHI7CgkJCWlvcC0+cGRhdCA9IChpb3AtPnBkYXQgJiB0cG1zaykgfCBwZGF0OwoJCQlpb3AtPnBkaXIgPSAoaW9wLT5wZGlyICYgdHBtc2spIHwgcGRpcjsKCQkJaW9wLT5wcGFyIHw9IHBwYXI7CgkJfQoJfQp9CgojZGVmaW5lIFNFVF9WQUxfTUFTSyhhLCBiLCBtYXNrKSAoKGEgJiBtYXNrKSB8IChiICYgfm1hc2spKQovKgogKiBCcmVhdGggc29tZSBsaWZlIGludG8gdGhlIENQVS4uLgogKgogKiBTZXQgdXAgdGhlIG1lbW9yeSBtYXAsCiAqIGluaXRpYWxpemUgYSBidW5jaCBvZiByZWdpc3RlcnMsCiAqIGluaXRpYWxpemUgdGhlIFVQTSdzCiAqLwp2b2lkIGNwdV9pbml0X2YgKHZvbGF0aWxlIGltbWFwX3QgKiBpbW1yKQp7CiNpZiAhZGVmaW5lZChDT05GSUdfQ09HRU5UKQkJLyogZG9uZSBpbiBzdGFydC5TIGZvciB0aGUgY29nZW50ICovCgl1aW50IHNjY3I7CiNlbmRpZgojaWYgZGVmaW5lZChDT05GSUdfQk9BUkRfR0VUX0NQVV9DTEtfRikKCXVuc2lnbmVkIGxvbmcgY3B1X2NsazsKI2VuZGlmCgl2b2xhdGlsZSBtZW1jdGw4MjYwX3QgKm1lbWN0bCA9ICZpbW1yLT5pbV9tZW1jdGw7CglleHRlcm4gdm9pZCBtODI2MF9jcG1fcmVzZXQgKHZvaWQpOwoKCS8qIFBvaW50ZXIgaXMgd3JpdGFibGUgc2luY2Ugd2UgYWxsb2NhdGVkIGEgcmVnaXN0ZXIgZm9yIGl0ICovCglnZCA9IChnZF90ICopIChDRkdfSU5JVF9SQU1fQUREUiArIENGR19HQkxfREFUQV9PRkZTRVQpOwoKCS8qIENsZWFyIGluaXRpYWwgZ2xvYmFsIGRhdGEgKi8KCW1lbXNldCAoKHZvaWQgKikgZ2QsIDAsIHNpemVvZiAoZ2RfdCkpOwoKCS8qIFJTUiAtIFJlc2V0IFN0YXR1cyBSZWdpc3RlciAtIGNsZWFyIGFsbCBzdGF0dXMgKDUtNCkgKi8KCWdkLT5yZXNldF9zdGF0dXMgPSBpbW1yLT5pbV9jbGtyc3QuY2FyX3JzcjsKCWltbXItPmltX2Nsa3JzdC5jYXJfcnNyID0gUlNSX0FMTEJJVFM7CgoJLyogUk1SIC0gUmVzZXQgTW9kZSBSZWdpc3RlciAtIGNvbnRhaW5zIGNoZWNrc3RvcCByZXNldCBlbmFibGUgKDUtNSkgKi8KCWltbXItPmltX2Nsa3JzdC5jYXJfcm1yID0gQ0ZHX1JNUjsKCgkvKiBCQ1IgLSBCdXMgQ29uZmlndXJhdGlvbiBSZWdpc3RlciAoNC0yNSkgKi8KI2lmIGRlZmluZWQoQ0ZHX0JDUl82MHgpICYmIChDRkdfQkNSX1NJTkdMRSkKCWlmIChpbW1yLT5pbV9zaXVfY29uZi5zY19iY3IgJiBCQ1JfRUJNKSB7CgkJaW1tci0+aW1fc2l1X2NvbmYuc2NfYmNyID0gU0VUX1ZBTF9NQVNLKGltbXItPmltX3NpdV9jb25mLnNjX2JjciwgQ0ZHX0JDUl82MHgsIDB4ODAwMDAwMTApOwoJfSBlbHNlIHsKCQlpbW1yLT5pbV9zaXVfY29uZi5zY19iY3IgPSBTRVRfVkFMX01BU0soaW1tci0+aW1fc2l1X2NvbmYuc2NfYmNyLCBDRkdfQkNSX1NJTkdMRSwgMHg4MDAwMDAxMCk7Cgl9CiNlbHNlCglpbW1yLT5pbV9zaXVfY29uZi5zY19iY3IgPSBDRkdfQkNSOwojZW5kaWYKCgkvKiBTSVVNQ1IgLSBjb250YWlucyBkZWJ1ZyBwaW4gY29uZmlndXJhdGlvbiAoNC0zMSkgKi8KI2lmIGRlZmluZWQoQ0ZHX1NJVU1DUl9MT1cpICYmIChDRkdfU0lVTUNSX0hJR0gpCgljcHVfY2xrID0gYm9hcmRfZ2V0X2NwdV9jbGtfZiAoKTsKCWlmIChjcHVfY2xrID49IDEwMDAwMDAwMCkgewoJCWltbXItPmltX3NpdV9jb25mLnNjX3NpdW1jciA9IFNFVF9WQUxfTUFTSyhpbW1yLT5pbV9zaXVfY29uZi5zY19zaXVtY3IsIENGR19TSVVNQ1JfSElHSCwgMHg5ZjNjYzAwMCk7Cgl9IGVsc2UgewoJCWltbXItPmltX3NpdV9jb25mLnNjX3NpdW1jciA9IFNFVF9WQUxfTUFTSyhpbW1yLT5pbV9zaXVfY29uZi5zY19zaXVtY3IsIENGR19TSVVNQ1JfTE9XLCAweDlmM2NjMDAwKTsKCX0KI2Vsc2UKCWltbXItPmltX3NpdV9jb25mLnNjX3NpdW1jciA9IENGR19TSVVNQ1I7CiNlbmRpZgoKCWNvbmZpZ184MjYwX2lvcG9ydHMgKGltbXIpOwoKCS8qIGluaXRpYWxpemUgdGltZSBjb3VudGVyIHN0YXR1cyBhbmQgY29udHJvbCByZWdpc3RlciAoNC00MCkgKi8KCWltbXItPmltX3NpdC5zaXRfdG1jbnRzYyA9IENGR19UTUNOVFNDOwoKCS8qIGluaXRpYWxpemUgdGhlIFBJVCAoNC00MikgKi8KCWltbXItPmltX3NpdC5zaXRfcGlzY3IgPSBDRkdfUElTQ1I7CgojaWYgIWRlZmluZWQoQ09ORklHX0NPR0VOVCkJCS8qIGRvbmUgaW4gc3RhcnQuUyBmb3IgdGhlIGNvZ2VudCAqLwoJLyogU3lzdGVtIGNsb2NrIGNvbnRyb2wgcmVnaXN0ZXIgKDktOCkgKi8KCXNjY3IgPSBpbW1yLT5pbV9jbGtyc3QuY2FyX3NjY3IgJgoJCShTQ0NSX1BDSV9NT0RFIHwgU0NDUl9QQ0lfTU9EQ0sgfCBTQ0NSX1BDSURGX01TSyk7CglpbW1yLT5pbV9jbGtyc3QuY2FyX3NjY3IgPSBzY2NyIHwKCQkoQ0ZHX1NDQ1IgJiB+KFNDQ1JfUENJX01PREUgfCBTQ0NSX1BDSV9NT0RDSyB8IFNDQ1JfUENJREZfTVNLKSApOwojZW5kaWYgLyogIUNPTkZJR19DT0dFTlQgKi8KCgkvKgoJICogTWVtb3J5IENvbnRyb2xsZXI6CgkgKi8KCgkvKiBNYXAgYmFua3MgMCBhbmQgMSB0byB0aGUgRkxBU0ggYmFua3MgMCBhbmQgMSBhdCBwcmVsaW1pbmFyeQoJICogYWRkcmVzc2VzIC0gdGhlc2UgaGF2ZSB0byBiZSBtb2RpZmllZCBsYXRlciB3aGVuIEZMQVNIIHNpemUKCSAqIGhhcyBiZWVuIGRldGVybWluZWQKCSAqLwoKI2lmIGRlZmluZWQoQ0ZHX09SMF9SRU1BUCkKCW1lbWN0bC0+bWVtY19vcjAgPSBDRkdfT1IwX1JFTUFQOwojZW5kaWYKI2lmIGRlZmluZWQoQ0ZHX09SMV9SRU1BUCkKCW1lbWN0bC0+bWVtY19vcjEgPSBDRkdfT1IxX1JFTUFQOwojZW5kaWYKCgkvKiBub3cgcmVzdHJpY3QgdG8gcHJlbGltaW5hcnkgcmFuZ2UgKi8KCS8qIHRoZSBQUyBjYW1lIGZyb20gdGhlIEhSQ1csIGRvbrR0IGNoYW5nZSBpdCAqLwoJbWVtY3RsLT5tZW1jX2JyMCA9IFNFVF9WQUxfTUFTSyhtZW1jdGwtPm1lbWNfYnIwICwgQ0ZHX0JSMF9QUkVMSU0sIEJSeF9QU19NU0spOwoJbWVtY3RsLT5tZW1jX29yMCA9IENGR19PUjBfUFJFTElNOwoKI2lmIGRlZmluZWQoQ0ZHX0JSMV9QUkVMSU0pICYmIGRlZmluZWQoQ0ZHX09SMV9QUkVMSU0pCgltZW1jdGwtPm1lbWNfb3IxID0gQ0ZHX09SMV9QUkVMSU07CgltZW1jdGwtPm1lbWNfYnIxID0gQ0ZHX0JSMV9QUkVMSU07CiNlbmRpZgoKI2lmIGRlZmluZWQoQ0ZHX0JSMl9QUkVMSU0pICYmIGRlZmluZWQoQ0ZHX09SMl9QUkVMSU0pCgltZW1jdGwtPm1lbWNfb3IyID0gQ0ZHX09SMl9QUkVMSU07CgltZW1jdGwtPm1lbWNfYnIyID0gQ0ZHX0JSMl9QUkVMSU07CiNlbmRpZgoKI2lmIGRlZmluZWQoQ0ZHX0JSM19QUkVMSU0pICYmIGRlZmluZWQoQ0ZHX09SM19QUkVMSU0pCgltZW1jdGwtPm1lbWNfb3IzID0gQ0ZHX09SM19QUkVMSU07CgltZW1jdGwtPm1lbWNfYnIzID0gQ0ZHX0JSM19QUkVMSU07CiNlbmRpZgoKI2lmIGRlZmluZWQoQ0ZHX0JSNF9QUkVMSU0pICYmIGRlZmluZWQoQ0ZHX09SNF9QUkVMSU0pCgltZW1jdGwtPm1lbWNfb3I0ID0gQ0ZHX09SNF9QUkVMSU07CgltZW1jdGwtPm1lbWNfYnI0ID0gQ0ZHX0JSNF9QUkVMSU07CiNlbmRpZgoKI2lmIGRlZmluZWQoQ0ZHX0JSNV9QUkVMSU0pICYmIGRlZmluZWQoQ0ZHX09SNV9QUkVMSU0pCgltZW1jdGwtPm1lbWNfb3I1ID0gQ0ZHX09SNV9QUkVMSU07CgltZW1jdGwtPm1lbWNfYnI1ID0gQ0ZHX0JSNV9QUkVMSU07CiNlbmRpZgoKI2lmIGRlZmluZWQoQ0ZHX0JSNl9QUkVMSU0pICYmIGRlZmluZWQoQ0ZHX09SNl9QUkVMSU0pCgltZW1jdGwtPm1lbWNfb3I2ID0gQ0ZHX09SNl9QUkVMSU07CgltZW1jdGwtPm1lbWNfYnI2ID0gQ0ZHX0JSNl9QUkVMSU07CiNlbmRpZgoKI2lmIGRlZmluZWQoQ0ZHX0JSN19QUkVMSU0pICYmIGRlZmluZWQoQ0ZHX09SN19QUkVMSU0pCgltZW1jdGwtPm1lbWNfb3I3ID0gQ0ZHX09SN19QUkVMSU07CgltZW1jdGwtPm1lbWNfYnI3ID0gQ0ZHX0JSN19QUkVMSU07CiNlbmRpZgoKI2lmIGRlZmluZWQoQ0ZHX0JSOF9QUkVMSU0pICYmIGRlZmluZWQoQ0ZHX09SOF9QUkVMSU0pCgltZW1jdGwtPm1lbWNfb3I4ID0gQ0ZHX09SOF9QUkVMSU07CgltZW1jdGwtPm1lbWNfYnI4ID0gQ0ZHX0JSOF9QUkVMSU07CiNlbmRpZgoKI2lmIGRlZmluZWQoQ0ZHX0JSOV9QUkVMSU0pICYmIGRlZmluZWQoQ0ZHX09SOV9QUkVMSU0pCgltZW1jdGwtPm1lbWNfb3I5ID0gQ0ZHX09SOV9QUkVMSU07CgltZW1jdGwtPm1lbWNfYnI5ID0gQ0ZHX0JSOV9QUkVMSU07CiNlbmRpZgoKI2lmIGRlZmluZWQoQ0ZHX0JSMTBfUFJFTElNKSAmJiBkZWZpbmVkKENGR19PUjEwX1BSRUxJTSkKCW1lbWN0bC0+bWVtY19vcjEwID0gQ0ZHX09SMTBfUFJFTElNOwoJbWVtY3RsLT5tZW1jX2JyMTAgPSBDRkdfQlIxMF9QUkVMSU07CiNlbmRpZgoKI2lmIGRlZmluZWQoQ0ZHX0JSMTFfUFJFTElNKSAmJiBkZWZpbmVkKENGR19PUjExX1BSRUxJTSkKCW1lbWN0bC0+bWVtY19vcjExID0gQ0ZHX09SMTFfUFJFTElNOwoJbWVtY3RsLT5tZW1jX2JyMTEgPSBDRkdfQlIxMV9QUkVMSU07CiNlbmRpZgoKCW04MjYwX2NwbV9yZXNldCAoKTsKfQoKLyoKICogaW5pdGlhbGl6ZSBoaWdoZXIgbGV2ZWwgcGFydHMgb2YgQ1BVIGxpa2UgdGltZSBiYXNlIGFuZCB0aW1lcnMKICovCmludCBjcHVfaW5pdF9yICh2b2lkKQp7Cgl2b2xhdGlsZSBpbW1hcF90ICppbW1yID0gKGltbWFwX3QgKikgZ2QtPmJkLT5iaV9pbW1yX2Jhc2U7CgoJaW1tci0+aW1fY3BtLmNwX3JjY3IgPSBDRkdfUkNDUjsKCglyZXR1cm4gKDApOwp9CgovKgogKiBwcmludCBvdXQgdGhlIHJlYXNvbiBmb3IgdGhlIHJlc2V0CiAqLwppbnQgcHJ0XzgyNjBfcnNyICh2b2lkKQp7CglzdGF0aWMgc3RydWN0IHsKCQl1bG9uZyBtYXNrOwoJCWNoYXIgKmRlc2M7Cgl9IGJpdHNbXSA9IHsKCQl7CgkJUlNSX0pUUlMsICJKVEFHIn0sIHsKCQlSU1JfQ1NSUywgIkNoZWNrIFN0b3AifSwgewoJCVJTUl9TV1JTLCAiU29mdHdhcmUgV2F0Y2hkb2cifSwgewoJCVJTUl9CTVJTLCAiQnVzIE1vbml0b3IifSwgewoJCVJTUl9FU1JTLCAiRXh0ZXJuYWwgU29mdCJ9LCB7CgkJUlNSX0VIUlMsICJFeHRlcm5hbCBIYXJkIn0KCX07CglzdGF0aWMgaW50IG4gPSBzaXplb2YgYml0cyAvIHNpemVvZiBiaXRzWzBdOwoJdWxvbmcgcnNyID0gZ2QtPnJlc2V0X3N0YXR1czsKCWludCBpOwoJY2hhciAqc2VwOwoKCXB1dHMgKENQVV9JRF9TVFIgIiBSZXNldCBTdGF0dXM6Iik7CgoJc2VwID0gIiAiOwoJZm9yIChpID0gMDsgaSA8IG47IGkrKykKCQlpZiAocnNyICYgYml0c1tpXS5tYXNrKSB7CgkJCXByaW50ZiAoIiVzJXMiLCBzZXAsIGJpdHNbaV0uZGVzYyk7CgkJCXNlcCA9ICIsICI7CgkJfQoKCXB1dHMgKCJcblxuIik7CglyZXR1cm4gKDApOwp9Cg==