LyoKICogUGVyZm9ybWFuY2UgZXZlbnRzIGNhbGxjaGFpbiBjb2RlLCBleHRyYWN0ZWQgZnJvbSBjb3JlLmM6CiAqCiAqICBDb3B5cmlnaHQgKEMpIDIwMDggVGhvbWFzIEdsZWl4bmVyIDx0Z2x4QGxpbnV0cm9uaXguZGU+CiAqICBDb3B5cmlnaHQgKEMpIDIwMDgtMjAxMSBSZWQgSGF0LCBJbmMuLCBJbmdvIE1vbG5hcgogKiAgQ29weXJpZ2h0IChDKSAyMDA4LTIwMTEgUmVkIEhhdCwgSW5jLiwgUGV0ZXIgWmlqbHN0cmEKICogIENvcHlyaWdodCAgqSAgMjAwOSBQYXVsIE1hY2tlcnJhcywgSUJNIENvcnAuIDxwYXVsdXNAYXUxLmlibS5jb20+CiAqCiAqIEZvciBsaWNlbnNpbmcgZGV0YWlscyBzZWUga2VybmVsLWJhc2UvQ09QWUlORwogKi8KCiNpbmNsdWRlIDxsaW51eC9wZXJmX2V2ZW50Lmg+CiNpbmNsdWRlIDxsaW51eC9zbGFiLmg+CiNpbmNsdWRlIDxsaW51eC9zY2hlZC90YXNrX3N0YWNrLmg+CgojaW5jbHVkZSAiaW50ZXJuYWwuaCIKCnN0cnVjdCBjYWxsY2hhaW5fY3B1c19lbnRyaWVzIHsKCXN0cnVjdCByY3VfaGVhZAkJCXJjdV9oZWFkOwoJc3RydWN0IHBlcmZfY2FsbGNoYWluX2VudHJ5CSpjcHVfZW50cmllc1swXTsKfTsKCmludCBzeXNjdGxfcGVyZl9ldmVudF9tYXhfc3RhY2sgX19yZWFkX21vc3RseSA9IFBFUkZfTUFYX1NUQUNLX0RFUFRIOwppbnQgc3lzY3RsX3BlcmZfZXZlbnRfbWF4X2NvbnRleHRzX3Blcl9zdGFjayBfX3JlYWRfbW9zdGx5ID0gUEVSRl9NQVhfQ09OVEVYVFNfUEVSX1NUQUNLOwoKc3RhdGljIGlubGluZSBzaXplX3QgcGVyZl9jYWxsY2hhaW5fZW50cnlfX3NpemVvZih2b2lkKQp7CglyZXR1cm4gKHNpemVvZihzdHJ1Y3QgcGVyZl9jYWxsY2hhaW5fZW50cnkpICsKCQlzaXplb2YoX191NjQpICogKHN5c2N0bF9wZXJmX2V2ZW50X21heF9zdGFjayArCgkJCQkgc3lzY3RsX3BlcmZfZXZlbnRfbWF4X2NvbnRleHRzX3Blcl9zdGFjaykpOwp9CgpzdGF0aWMgREVGSU5FX1BFUl9DUFUoaW50LCBjYWxsY2hhaW5fcmVjdXJzaW9uW1BFUkZfTlJfQ09OVEVYVFNdKTsKc3RhdGljIGF0b21pY190IG5yX2NhbGxjaGFpbl9ldmVudHM7CnN0YXRpYyBERUZJTkVfTVVURVgoY2FsbGNoYWluX211dGV4KTsKc3RhdGljIHN0cnVjdCBjYWxsY2hhaW5fY3B1c19lbnRyaWVzICpjYWxsY2hhaW5fY3B1c19lbnRyaWVzOwoKCl9fd2VhayB2b2lkIHBlcmZfY2FsbGNoYWluX2tlcm5lbChzdHJ1Y3QgcGVyZl9jYWxsY2hhaW5fZW50cnlfY3R4ICplbnRyeSwKCQkJCSAgc3RydWN0IHB0X3JlZ3MgKnJlZ3MpCnsKfQoKX193ZWFrIHZvaWQgcGVyZl9jYWxsY2hhaW5fdXNlcihzdHJ1Y3QgcGVyZl9jYWxsY2hhaW5fZW50cnlfY3R4ICplbnRyeSwKCQkJCXN0cnVjdCBwdF9yZWdzICpyZWdzKQp7Cn0KCnN0YXRpYyB2b2lkIHJlbGVhc2VfY2FsbGNoYWluX2J1ZmZlcnNfcmN1KHN0cnVjdCByY3VfaGVhZCAqaGVhZCkKewoJc3RydWN0IGNhbGxjaGFpbl9jcHVzX2VudHJpZXMgKmVudHJpZXM7CglpbnQgY3B1OwoKCWVudHJpZXMgPSBjb250YWluZXJfb2YoaGVhZCwgc3RydWN0IGNhbGxjaGFpbl9jcHVzX2VudHJpZXMsIHJjdV9oZWFkKTsKCglmb3JfZWFjaF9wb3NzaWJsZV9jcHUoY3B1KQoJCWtmcmVlKGVudHJpZXMtPmNwdV9lbnRyaWVzW2NwdV0pOwoKCWtmcmVlKGVudHJpZXMpOwp9CgpzdGF0aWMgdm9pZCByZWxlYXNlX2NhbGxjaGFpbl9idWZmZXJzKHZvaWQpCnsKCXN0cnVjdCBjYWxsY2hhaW5fY3B1c19lbnRyaWVzICplbnRyaWVzOwoKCWVudHJpZXMgPSBjYWxsY2hhaW5fY3B1c19lbnRyaWVzOwoJUkNVX0lOSVRfUE9JTlRFUihjYWxsY2hhaW5fY3B1c19lbnRyaWVzLCBOVUxMKTsKCWNhbGxfcmN1KCZlbnRyaWVzLT5yY3VfaGVhZCwgcmVsZWFzZV9jYWxsY2hhaW5fYnVmZmVyc19yY3UpOwp9CgpzdGF0aWMgaW50IGFsbG9jX2NhbGxjaGFpbl9idWZmZXJzKHZvaWQpCnsKCWludCBjcHU7CglpbnQgc2l6ZTsKCXN0cnVjdCBjYWxsY2hhaW5fY3B1c19lbnRyaWVzICplbnRyaWVzOwoKCS8qCgkgKiBXZSBjYW4ndCB1c2UgdGhlIHBlcmNwdSBhbGxvY2F0aW9uIEFQSSBmb3IgZGF0YSB0aGF0IGNhbiBiZQoJICogYWNjZXNzZWQgZnJvbSBOTUkuIFVzZSBhIHRlbXBvcmFyeSBtYW51YWwgcGVyIGNwdSBhbGxvY2F0aW9uCgkgKiB1bnRpbCB0aGF0IGdldHMgc29ydGVkIG91dC4KCSAqLwoJc2l6ZSA9IG9mZnNldG9mKHN0cnVjdCBjYWxsY2hhaW5fY3B1c19lbnRyaWVzLCBjcHVfZW50cmllc1tucl9jcHVfaWRzXSk7CgoJZW50cmllcyA9IGt6YWxsb2Moc2l6ZSwgR0ZQX0tFUk5FTCk7CglpZiAoIWVudHJpZXMpCgkJcmV0dXJuIC1FTk9NRU07CgoJc2l6ZSA9IHBlcmZfY2FsbGNoYWluX2VudHJ5X19zaXplb2YoKSAqIFBFUkZfTlJfQ09OVEVYVFM7CgoJZm9yX2VhY2hfcG9zc2libGVfY3B1KGNwdSkgewoJCWVudHJpZXMtPmNwdV9lbnRyaWVzW2NwdV0gPSBrbWFsbG9jX25vZGUoc2l6ZSwgR0ZQX0tFUk5FTCwKCQkJCQkJCSBjcHVfdG9fbm9kZShjcHUpKTsKCQlpZiAoIWVudHJpZXMtPmNwdV9lbnRyaWVzW2NwdV0pCgkJCWdvdG8gZmFpbDsKCX0KCglyY3VfYXNzaWduX3BvaW50ZXIoY2FsbGNoYWluX2NwdXNfZW50cmllcywgZW50cmllcyk7CgoJcmV0dXJuIDA7CgpmYWlsOgoJZm9yX2VhY2hfcG9zc2libGVfY3B1KGNwdSkKCQlrZnJlZShlbnRyaWVzLT5jcHVfZW50cmllc1tjcHVdKTsKCWtmcmVlKGVudHJpZXMpOwoKCXJldHVybiAtRU5PTUVNOwp9CgppbnQgZ2V0X2NhbGxjaGFpbl9idWZmZXJzKGludCBldmVudF9tYXhfc3RhY2spCnsKCWludCBlcnIgPSAwOwoJaW50IGNvdW50OwoKCW11dGV4X2xvY2soJmNhbGxjaGFpbl9tdXRleCk7CgoJY291bnQgPSBhdG9taWNfaW5jX3JldHVybigmbnJfY2FsbGNoYWluX2V2ZW50cyk7CglpZiAoV0FSTl9PTl9PTkNFKGNvdW50IDwgMSkpIHsKCQllcnIgPSAtRUlOVkFMOwoJCWdvdG8gZXhpdDsKCX0KCglpZiAoY291bnQgPiAxKSB7CgkJLyogSWYgdGhlIGFsbG9jYXRpb24gZmFpbGVkLCBnaXZlIHVwICovCgkJaWYgKCFjYWxsY2hhaW5fY3B1c19lbnRyaWVzKQoJCQllcnIgPSAtRU5PTUVNOwoJCS8qCgkJICogSWYgcmVxdWVzdGluZyBwZXIgZXZlbnQgbW9yZSB0aGFuIHRoZSBnbG9iYWwgY2FwLAoJCSAqIHJldHVybiBhIGRpZmZlcmVudCBlcnJvciB0byBoZWxwIHVzZXJzcGFjZSBmaWd1cmUKCQkgKiB0aGlzIG91dC4KCQkgKgoJCSAqIEFuZCBhbHNvIGRvIGl0IGhlcmUgc28gdGhhdCB3ZSBoYXZlICZjYWxsY2hhaW5fbXV0ZXggaGVsZC4KCQkgKi8KCQlpZiAoZXZlbnRfbWF4X3N0YWNrID4gc3lzY3RsX3BlcmZfZXZlbnRfbWF4X3N0YWNrKQoJCQllcnIgPSAtRU9WRVJGTE9XOwoJCWdvdG8gZXhpdDsKCX0KCgllcnIgPSBhbGxvY19jYWxsY2hhaW5fYnVmZmVycygpOwpleGl0OgoJaWYgKGVycikKCQlhdG9taWNfZGVjKCZucl9jYWxsY2hhaW5fZXZlbnRzKTsKCgltdXRleF91bmxvY2soJmNhbGxjaGFpbl9tdXRleCk7CgoJcmV0dXJuIGVycjsKfQoKdm9pZCBwdXRfY2FsbGNoYWluX2J1ZmZlcnModm9pZCkKewoJaWYgKGF0b21pY19kZWNfYW5kX211dGV4X2xvY2soJm5yX2NhbGxjaGFpbl9ldmVudHMsICZjYWxsY2hhaW5fbXV0ZXgpKSB7CgkJcmVsZWFzZV9jYWxsY2hhaW5fYnVmZmVycygpOwoJCW11dGV4X3VubG9jaygmY2FsbGNoYWluX211dGV4KTsKCX0KfQoKc3RhdGljIHN0cnVjdCBwZXJmX2NhbGxjaGFpbl9lbnRyeSAqZ2V0X2NhbGxjaGFpbl9lbnRyeShpbnQgKnJjdHgpCnsKCWludCBjcHU7CglzdHJ1Y3QgY2FsbGNoYWluX2NwdXNfZW50cmllcyAqZW50cmllczsKCgkqcmN0eCA9IGdldF9yZWN1cnNpb25fY29udGV4dCh0aGlzX2NwdV9wdHIoY2FsbGNoYWluX3JlY3Vyc2lvbikpOwoJaWYgKCpyY3R4ID09IC0xKQoJCXJldHVybiBOVUxMOwoKCWVudHJpZXMgPSByY3VfZGVyZWZlcmVuY2UoY2FsbGNoYWluX2NwdXNfZW50cmllcyk7CglpZiAoIWVudHJpZXMpCgkJcmV0dXJuIE5VTEw7CgoJY3B1ID0gc21wX3Byb2Nlc3Nvcl9pZCgpOwoKCXJldHVybiAoKCh2b2lkICopZW50cmllcy0+Y3B1X2VudHJpZXNbY3B1XSkgKwoJCSgqcmN0eCAqIHBlcmZfY2FsbGNoYWluX2VudHJ5X19zaXplb2YoKSkpOwp9CgpzdGF0aWMgdm9pZApwdXRfY2FsbGNoYWluX2VudHJ5KGludCByY3R4KQp7CglwdXRfcmVjdXJzaW9uX2NvbnRleHQodGhpc19jcHVfcHRyKGNhbGxjaGFpbl9yZWN1cnNpb24pLCByY3R4KTsKfQoKc3RydWN0IHBlcmZfY2FsbGNoYWluX2VudHJ5ICoKZ2V0X3BlcmZfY2FsbGNoYWluKHN0cnVjdCBwdF9yZWdzICpyZWdzLCB1MzIgaW5pdF9uciwgYm9vbCBrZXJuZWwsIGJvb2wgdXNlciwKCQkgICB1MzIgbWF4X3N0YWNrLCBib29sIGNyb3NzdGFzaywgYm9vbCBhZGRfbWFyaykKewoJc3RydWN0IHBlcmZfY2FsbGNoYWluX2VudHJ5ICplbnRyeTsKCXN0cnVjdCBwZXJmX2NhbGxjaGFpbl9lbnRyeV9jdHggY3R4OwoJaW50IHJjdHg7CgoJZW50cnkgPSBnZXRfY2FsbGNoYWluX2VudHJ5KCZyY3R4KTsKCWlmIChyY3R4ID09IC0xKQoJCXJldHVybiBOVUxMOwoKCWlmICghZW50cnkpCgkJZ290byBleGl0X3B1dDsKCgljdHguZW50cnkgICAgID0gZW50cnk7CgljdHgubWF4X3N0YWNrID0gbWF4X3N0YWNrOwoJY3R4Lm5yCSAgICAgID0gZW50cnktPm5yID0gaW5pdF9ucjsKCWN0eC5jb250ZXh0cyAgICAgICA9IDA7CgljdHguY29udGV4dHNfbWF4ZWQgPSBmYWxzZTsKCglpZiAoa2VybmVsICYmICF1c2VyX21vZGUocmVncykpIHsKCQlpZiAoYWRkX21hcmspCgkJCXBlcmZfY2FsbGNoYWluX3N0b3JlX2NvbnRleHQoJmN0eCwgUEVSRl9DT05URVhUX0tFUk5FTCk7CgkJcGVyZl9jYWxsY2hhaW5fa2VybmVsKCZjdHgsIHJlZ3MpOwoJfQoKCWlmICh1c2VyKSB7CgkJaWYgKCF1c2VyX21vZGUocmVncykpIHsKCQkJaWYgIChjdXJyZW50LT5tbSkKCQkJCXJlZ3MgPSB0YXNrX3B0X3JlZ3MoY3VycmVudCk7CgkJCWVsc2UKCQkJCXJlZ3MgPSBOVUxMOwoJCX0KCgkJaWYgKHJlZ3MpIHsKCQkJbW1fc2VnbWVudF90IGZzOwoKCQkJaWYgKGNyb3NzdGFzaykKCQkJCWdvdG8gZXhpdF9wdXQ7CgoJCQlpZiAoYWRkX21hcmspCgkJCQlwZXJmX2NhbGxjaGFpbl9zdG9yZV9jb250ZXh0KCZjdHgsIFBFUkZfQ09OVEVYVF9VU0VSKTsKCgkJCWZzID0gZ2V0X2ZzKCk7CgkJCXNldF9mcyhVU0VSX0RTKTsKCQkJcGVyZl9jYWxsY2hhaW5fdXNlcigmY3R4LCByZWdzKTsKCQkJc2V0X2ZzKGZzKTsKCQl9Cgl9CgpleGl0X3B1dDoKCXB1dF9jYWxsY2hhaW5fZW50cnkocmN0eCk7CgoJcmV0dXJuIGVudHJ5Owp9CgovKgogKiBVc2VkIGZvciBzeXNjdGxfcGVyZl9ldmVudF9tYXhfc3RhY2sgYW5kCiAqIHN5c2N0bF9wZXJmX2V2ZW50X21heF9jb250ZXh0c19wZXJfc3RhY2suCiAqLwppbnQgcGVyZl9ldmVudF9tYXhfc3RhY2tfaGFuZGxlcihzdHJ1Y3QgY3RsX3RhYmxlICp0YWJsZSwgaW50IHdyaXRlLAoJCQkJIHZvaWQgX191c2VyICpidWZmZXIsIHNpemVfdCAqbGVucCwgbG9mZl90ICpwcG9zKQp7CglpbnQgKnZhbHVlID0gdGFibGUtPmRhdGE7CglpbnQgbmV3X3ZhbHVlID0gKnZhbHVlLCByZXQ7CglzdHJ1Y3QgY3RsX3RhYmxlIG5ld190YWJsZSA9ICp0YWJsZTsKCgluZXdfdGFibGUuZGF0YSA9ICZuZXdfdmFsdWU7CglyZXQgPSBwcm9jX2RvaW50dmVjX21pbm1heCgmbmV3X3RhYmxlLCB3cml0ZSwgYnVmZmVyLCBsZW5wLCBwcG9zKTsKCWlmIChyZXQgfHwgIXdyaXRlKQoJCXJldHVybiByZXQ7CgoJbXV0ZXhfbG9jaygmY2FsbGNoYWluX211dGV4KTsKCWlmIChhdG9taWNfcmVhZCgmbnJfY2FsbGNoYWluX2V2ZW50cykpCgkJcmV0ID0gLUVCVVNZOwoJZWxzZQoJCSp2YWx1ZSA9IG5ld192YWx1ZTsKCgltdXRleF91bmxvY2soJmNhbGxjaGFpbl9tdXRleCk7CgoJcmV0dXJuIHJldDsKfQo=