I2lmbmRlZiBmb29kb21haW5oZm9vCiNkZWZpbmUgZm9vZG9tYWluaGZvbwoKLyoqKgogIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIGF2YWhpLgoKICBhdmFoaSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0CiAgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgYXMKICBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyIHZlcnNpb24gMi4xIG9mIHRoZQogIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uCgogIGF2YWhpIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCiAgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZCiAgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuIFNlZSB0aGUgR05VIExlc3NlciBHZW5lcmFsCiAgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy4KCiAgWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogIExpY2Vuc2UgYWxvbmcgd2l0aCBhdmFoaTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZQogIEZvdW5kYXRpb24sIEluYy4sIDU5IFRlbXBsZSBQbGFjZSwgU3VpdGUgMzMwLCBCb3N0b24sIE1BIDAyMTExLTEzMDcKICBVU0EuCioqKi8KCi8qKiBcZmlsZSBkb21haW4uaCBEb21haW4gbmFtZSBoYW5kbGluZyBmdW5jdGlvbnMgKi8KCiNpbmNsdWRlIDxpbnR0eXBlcy5oPgojaW5jbHVkZSA8c3lzL3R5cGVzLmg+CgojaW5jbHVkZSA8YXZhaGktY29tbW9uL2NkZWNsLmg+CgpBVkFISV9DX0RFQ0xfQkVHSU4KCi8qKiBUaGUgbWF4aW11bSBsZW5ndGggb2YgYSBhIGZ1bGx5IGVzY2FwZWQgZG9tYWluIG5hbWUgQyBzdHJpbmcuIFRoaXMKICogaXMgY2FsY3VsYXRlZCBsaWtlIHRoaXM6IFJGQzEwMzQgbWFuZGF0ZXMgbWF4aW11bSBsZW5ndGggb2YgRlFETnMKICogaXMgMjU1LiBUaGUgbWF4aW11bSBsYWJlbCBsZW5ndGggaXMgNjMuIFRvIG1pbmltaXplIHRoZSBudW1iZXIgb2YKICogKG5vbi1lc2NhcGVkKSBkb3RzLCB3ZSBjb21wcmlzZSBvdXIgbWF4aW11bS1sZW5ndGggZG9tYWluIG5hbWUgb2YKICogZm91ciBsYWJlbHMg4SA2MyBjaGFyYWN0ZXJzIHBsdXMgdGhyZWUgaW5uZXIgZG90cy4gRXNjYXBpbmcgdGhlCiAqIGZvdXIgbGFiZWxzIHF1YWRydXBsZXMgdGhlaXIgbGVuZ3RoIGF0IG1heGltdW0uIEFuIGVzY2FwZWQgZG9tYWluCiAqIG5hbWUgaGFzIHRoZSB0aGVyZWZvcmUgdGhlIG1heGltdW0gbGVuZ3RoIG9mIDYzKjQqNCszPTEwMTEuIEEKICogdHJhaWxpbmcgTlVMIGFuZCBwZXJoYXBzIHR3byB1bm5lY2Vzc2FyeSBkb3RzIGxlYWRpbmcgYW5kIHRyYWlsaW5nCiAqIHRoZSBzdHJpbmcgYnJpbmdzIHVzIHRvIDEwMTQuICovCiNkZWZpbmUgQVZBSElfRE9NQUlOX05BTUVfTUFYIDEwMTQKCi8qKiBNYXhpbXVtIHNpemUgb2YgYW4gdW5lc2NhcGVkIGxhYmVsICovCiNkZWZpbmUgQVZBSElfTEFCRUxfTUFYIDY0CgovKiogQHsgXG5hbWUgTm9ybWFsaXphdGlvbiAqLwoKLyoqIE5vcm1hbGl6ZSBhIGRvbWFpbiBuYW1lIGludG8gY2Fub25pY2FsIGZvcm0uIFRoaXMgZHJvcHMgdHJhaWxpbmcKICogZG90cyBhbmQgcmVtb3ZlcyB1c2VsZXNzIGJhY2tzbGFzaCBlc2NhcGVzLiAqLwpjaGFyICphdmFoaV9ub3JtYWxpemVfbmFtZShjb25zdCBjaGFyICpzLCBjaGFyICpyZXRfcywgc2l6ZV90IHNpemUpOwoKLyoqIE5vcm1hbGl6ZSBhIGRvbWFpbiBuYW1lIGludG8gY2Fub25pY2FsIGZvcm0uIFRoaXMgZHJvcHMgdHJhaWxpbmcKICogZG90cyBhbmQgcmVtb3ZlcyB1c2VsZXNzIGJhY2tzbGFzaCBlc2NhcGVzLiBhdmFoaV9mcmVlKCkgdGhlCiAqIHJlc3VsdCEgKi8KY2hhciAqYXZhaGlfbm9ybWFsaXplX25hbWVfc3RyZHVwKGNvbnN0IGNoYXIgKnMpOwoKLyoqIEB9ICovCgovKiogQHsgXG5hbWUgQ29tcGFyaXNvbiAqLwoKLyoqIFJldHVybiAxIHdoZW4gdGhlIHNwZWNpZmllZCBkb21haW4gbmFtZXMgYXJlIGVxdWFsLCAwIG90aGVyd2lzZSAqLwppbnQgYXZhaGlfZG9tYWluX2VxdWFsKGNvbnN0IGNoYXIgKmEsIGNvbnN0IGNoYXIgKmIpOwoKLyoqIFJldHVybiBzb21lIGtpbmQgb2YgaGFzaCB2YWx1ZSBmb3IgdGhlIGRvbWFpbiwgdXNlZnVsIGZvciB1c2luZyBkb21haW5zIGFzIGhhc2ggdGFibGUga2V5cy4gKi8KdW5zaWduZWQgYXZhaGlfZG9tYWluX2hhc2goY29uc3QgY2hhciAqbmFtZSk7CgovKiogQH0gKi8KCi8qKiBAeyBcbmFtZSBFc2NhcGluZyAqLwoKLyoqIFJlYWQgdGhlIGZpcnN0IGxhYmVsIGZyb20gdGhlIHRleHR1YWwgZG9tYWluIG5hbWUgKm5hbWUsIHVuZXNjYXBlCiAqIGl0IGFuZCB3cml0ZSBpdCB0byBkZXN0LCAqbmFtZSBpcyBjaGFuZ2VkIHRvIHBvaW50IHRvIHRoZSBuZXh0IGxhYmVsKi8KY2hhciAqYXZhaGlfdW5lc2NhcGVfbGFiZWwoY29uc3QgY2hhciAqKm5hbWUsIGNoYXIgKmRlc3QsIHNpemVfdCBzaXplKTsKCi8qKiBFc2NhcGUgdGhlIGRvbWFpbiBuYW1lIGluICpzcmMgYW5kIHdyaXRlIGl0IHRvICpyZXRfbmFtZSAqLwpjaGFyICphdmFoaV9lc2NhcGVfbGFiZWwoY29uc3QgY2hhciogc3JjLCBzaXplX3Qgc3JjX2xlbmd0aCwgY2hhciAqKnJldF9uYW1lLCBzaXplX3QgKnJldF9zaXplKTsKCi8qKiBAfSAqLwoKLyoqIEB7IFxuYW1lIFZhbGlkaXR5IENoZWNrcyAqLwoKLyoqIFJldHVybiAxIHdoZW4gdGhlIHNwZWNpZmllZCBzdHJpbmcgY29udGFpbnMgYSB2YWxpZCBnZW5lcmljIEROUy1TRAogKiBzZXJ2aWNlIHR5cGUgKGkuZS4gYSBzZXJpZXMgb2Ygd29yZHMgc3RhcnRpbmcgd2l0aCAiXyIpLCAwCiAqIG90aGVyd2lzZSAqLwppbnQgYXZhaGlfaXNfdmFsaWRfc2VydmljZV90eXBlX2dlbmVyaWMoY29uc3QgY2hhciAqdCk7CgovKiogUmV0dXJuIDEgd2hlbiB0aGUgc3BlY2lmaWVkIHN0cmluZyBjb250YWlucyBhIHZhbGlkIHN0cmljdCBETlMtU0QKICogc2VydmljZSB0eXBlIChpLmUuIGNvbnNpc3Rpbmcgb2Ygb25seSB0d28gd29yZHMsIHRoZSBsYXR0ZXIgYmVpbmcKICogZWl0aGVyIF91ZHAgb3IgX3RjcCksIDAgb3RoZXJ3aXNlICovCmludCBhdmFoaV9pc192YWxpZF9zZXJ2aWNlX3R5cGVfc3RyaWN0KGNvbnN0IGNoYXIgKnQpOwoKLyoqIFJldHVybiAxIHdoZW4gdGhlIHNwZWNpZmllZCBzdHJpbmcgY29udGFpbnMgYSB2YWxpZCBETlMtU0Qgc2VydmljZQogKiBzdWJ0eXBlLCAwIG90aGVyd2lzZSAqLwppbnQgYXZhaGlfaXNfdmFsaWRfc2VydmljZV9zdWJ0eXBlKGNvbnN0IGNoYXIgKnQpOwoKLyoqIFJldHVybiAxIHdoZW4gdGhlIHNwZWNpZmllZCBzdHJpbmcgY29udGFpbnMgYSB2YWxpZCBkb21haW4gbmFtZSwgMCBvdGhlcndpc2UgKi8KaW50IGF2YWhpX2lzX3ZhbGlkX2RvbWFpbl9uYW1lKGNvbnN0IGNoYXIgKnQpOwoKLyoqIFJldHVybiAxIHdoZW4gdGhlIHNwZWNpZmllZCBzdHJpbmcgY29udGFpbnMgYSB2YWxpZCBETlMtU0Qgc2VydmljZSBuYW1lLCAwIG90aGVyd2lzZSAqLwppbnQgYXZhaGlfaXNfdmFsaWRfc2VydmljZV9uYW1lKGNvbnN0IGNoYXIgKnQpOwoKLyoqIFJldHVybiAxIHdoZW4gdGhlIHNwZWNpZmllZCBzdHJpbmcgY29udGFpbnMgYSB2YWxpZCBub24tRlFETiBob3N0IG5hbWUgKGkuZS4gd2l0aG91dCBkb3RzKSwgMCBvdGhlcndpc2UgKi8KaW50IGF2YWhpX2lzX3ZhbGlkX2hvc3RfbmFtZShjb25zdCBjaGFyICp0KTsKCi8qKiBSZXR1cm4gMSB3aGVuIHRoZSBzcGVjaWZpZWQgc3RyaW5nIGNvbnRhaW5zIGEgdmFsaWQgRlFETiBob3N0IG5hbWUgKGkuZS4gd2l0aCBtb3JlIHRoYW4gb25lIGxhYmVsIGFuZCBub24tbnVtZXJpY2FsKSwgMCBvdGhlcndpc2UuIFxzaW5jZSAwLjYuOSAqLwppbnQgYXZhaGlfaXNfdmFsaWRfZnFkbihjb25zdCBjaGFyICp0KTsKCi8qKiBAfSAqLwoKLyoqIEB7IFxuYW1lIEROUy1TRCBzZXJ2aWNlIG5hbWUgaGFuZGxpbmcgKi8KCi8qKiBDb25zdHJ1Y3QgYSB2YWxpZCBjb21wbGV0ZSBETlMtU0Qgc2VydmljZSBuYW1lIGZyb20gYSBuYW1lLCBhIHR5cGUgYW5kIGEgZG9tYWluICovCmludCBhdmFoaV9zZXJ2aWNlX25hbWVfam9pbihjaGFyICpwLCBzaXplX3Qgc2l6ZSwgY29uc3QgY2hhciAqbmFtZSwgY29uc3QgY2hhciAqdHlwZSwgY29uc3QgY2hhciAqZG9tYWluKTsKCi8qKiBTcGxpdCBhIGZ1bGwgc2VydmljZSBuYW1lIGludG8gbmFtZSwgdHlwZSBhbmQgZG9tYWluICovCmludCBhdmFoaV9zZXJ2aWNlX25hbWVfc3BsaXQoY29uc3QgY2hhciAqcCwgY2hhciAqbmFtZSwgc2l6ZV90IG5hbWVfc2l6ZSwgY2hhciAqdHlwZSwgc2l6ZV90IHR5cGVfc2l6ZSwgY2hhciAqZG9tYWluLCBzaXplX3QgZG9tYWluX3NpemUpOwoKLyoqIEB9ICovCgovKiogQHsgXG5hbWUgRE5TLVNEIFN1YnR5cGUgaGFuZGxpbmcgKi8KCi8qKiBSZXR1cm4gYSBwb2ludGVyIHRvIHRoZSB0eXBlIHNlY3Rpb24gb2YgYSBzdWJ0eXBlIGkuZS4gX2Zvby5fc3ViLl9iYXIuX3RjcCA9PiBfYmFyLl90Y3AgKi8KY29uc3QgY2hhciAqYXZhaGlfZ2V0X3R5cGVfZnJvbV9zdWJ0eXBlKGNvbnN0IGNoYXIgKnQpOwoKLyoqIEB9ICovCgpBVkFISV9DX0RFQ0xfRU5ECgojZW5kaWYK