LyogUG9ydGlvbnMgb2YgdGhpcyBmaWxlIGFyZSBzdWJqZWN0IHRvIHRoZSBmb2xsb3dpbmcgY29weXJpZ2h0KHMpLiAgU2VlCiAqIHRoZSBOZXQtU05NUCdzIENPUFlJTkcgZmlsZSBmb3IgbW9yZSBkZXRhaWxzIGFuZCBvdGhlciBjb3B5cmlnaHRzCiAqIHRoYXQgbWF5IGFwcGx5OgogKi8KLyoKICogUG9ydGlvbnMgb2YgdGhpcyBmaWxlIGFyZSBjb3B5cmlnaHRlZCBieToKICogQ29weXJpZ2h0IKkgMjAwMyBTdW4gTWljcm9zeXN0ZW1zLCBJbmMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqIFVzZSBpcyBzdWJqZWN0IHRvIGxpY2Vuc2UgdGVybXMgc3BlY2lmaWVkIGluIHRoZSBDT1BZSU5HIGZpbGUKICogZGlzdHJpYnV0ZWQgd2l0aCB0aGUgTmV0LVNOTVAgcGFja2FnZS4KICovCiNpbmNsdWRlIDxuZXQtc25tcC9uZXQtc25tcC1jb25maWcuaD4KCiNpbmNsdWRlIDxuZXQtc25tcC9uZXQtc25tcC1pbmNsdWRlcy5oPgojaW5jbHVkZSA8bmV0LXNubXAvYWdlbnQvbmV0LXNubXAtYWdlbnQtaW5jbHVkZXMuaD4KCiNpbmNsdWRlIDxuZXQtc25tcC9hZ2VudC9zY2FsYXIuaD4KCiNpbmNsdWRlIDxzdGRsaWIuaD4KI2lmIEhBVkVfU1RSSU5HX0gKI2luY2x1ZGUgPHN0cmluZy5oPgojZWxzZQojaW5jbHVkZSA8c3RyaW5ncy5oPgojZW5kaWYKCiNpbmNsdWRlIDxuZXQtc25tcC9hZ2VudC9pbnN0YW5jZS5oPgojaW5jbHVkZSA8bmV0LXNubXAvYWdlbnQvc2VyaWFsaXplLmg+CiNpbmNsdWRlIDxuZXQtc25tcC9hZ2VudC9yZWFkX29ubHkuaD4KCi8qKiBAZGVmZ3JvdXAgc2NhbGFyIHNjYWxhcgogKiAgUHJvY2VzcyBzY2FsYXJzIGVhc2lseS4KICogIEBpbmdyb3VwIGxlYWYKICogIEB7CiAqLwoKLyoqCiAqIENyZWF0ZXMgYSBzY2FsYXIgaGFuZGxlciBjYWxsaW5nIG5ldHNubXBfY3JlYXRlX2hhbmRsZXIgd2l0aCBhCiAqIGhhbmRsZXIgbmFtZSBkZWZhdWx0ZWQgdG8gInNjYWxhciIgYW5kIGFjY2VzcyBtZXRob2QsIAogKiBuZXRzbm1wX3NjYWxhcl9oZWxwZXJfaGFuZGxlci4KICoKICogQHJldHVybiBSZXR1cm5zIGEgcG9pbnRlciB0byBhIG5ldHNubXBfbWliX2hhbmRsZXIgc3RydWN0IHdoaWNoIGNvbnRhaW5zCiAqCXRoZSBoYW5kbGVyJ3MgbmFtZSBhbmQgdGhlIGFjY2VzcyBtZXRob2QKICoKICogQHNlZSBuZXRzbm1wX2dldF9zY2FsYXJfaGFuZGxlcgogKiBAc2VlIG5ldHNubXBfcmVnaXN0ZXJfc2NhbGFyCiAqLwpuZXRzbm1wX21pYl9oYW5kbGVyICoKbmV0c25tcF9nZXRfc2NhbGFyX2hhbmRsZXIodm9pZCkKewogICAgcmV0dXJuIG5ldHNubXBfY3JlYXRlX2hhbmRsZXIoInNjYWxhciIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXRzbm1wX3NjYWxhcl9oZWxwZXJfaGFuZGxlcik7Cn0KCi8qKgogKiBUaGlzIGZ1bmN0aW9uIHJlZ2lzdGVycyBhIHNjYWxhciBoZWxwZXIgaGFuZGxlci4gIFRoZSByZWdpc3RlcmVkIE9JRCwgCiAqIHJlZ2luZm8tPnJvb3RvaWQsIHNwYWNlIGlzIGV4dGVuZGVkIGZvciB0aGUgaW5zdGFuY2Ugc3ViaWQgdXNpbmcgCiAqIHJlYWxsb2MoKSBidXQgdGhlIHJlZ2luZm8tPnJvb3RvaWRfbGVuIGxlbmd0aCBpcyBub3QgZXh0ZW5kZWQganVzdCB5ZXQuCiAqIC5UaGlzIGZ1bmN0aW9uIHN1YnNlcXVlbnRseSBpbmplY3RzIHRoZSBpbnN0YW5jZSwgc2NhbGFyLCBhbmQgc2VyaWFsaXplCiAqIGhlbHBlciBoYW5kbGVycyBiZWZvcmUgYWN0dWFsbHkgcmVnaXN0ZXJpbmcgcmVnaW5mby4KICoKICogRWFjaCBoYW5kbGVyIGlzIGluamVjdGVkL3B1c2hlZCB0byB0aGUgdG9wIG9mIHRoZSBoYW5kbGVyIGNoYWluIGxpc3QgCiAqIGFuZCB3aWxsIGJlIHByb2Nlc3NlZCBsYXN0IGluIGZpcnN0IG91dCwgTElGTy4KICoKICogQHBhcmFtIHJlZ2luZm8gYSBoYW5kbGVyIHJlZ2lzdHJhdGlvbiBzdHJ1Y3R1cmUgd2hpY2ggY291bGQgZ2V0IGNyZWF0ZWQKICogICAgICAgICAgICAgICAgdXNpbmcgbmV0c25tcF9jcmVhdGVfaGFuZGxlcl9yZWdpc3RyYXRpb24uICBVc2VkIHRvIHJlZ2lzdGVyCiAqICAgICAgICAgICAgICAgIGEgc2NhbGFyIGhlbHBlciBoYW5kbGVyLgogKgogKiBAcmV0dXJuIE1JQl9SRUdJU1RFUkVEX09LIGlzIHJldHVybmVkIGlmIHRoZSByZWdpc3RyYXRpb24gd2FzIGEgc3VjY2Vzcy4KICoJRmFpbHVyZXMgYXJlIE1JQl9SRUdJU1RSQVRJT05fRkFJTFVSRSBhbmQgTUlCX0RVUExJQ0FURV9SRUdJU1RSQVRJT04uCiAqCiAqIEBzZWUgbmV0c25tcF9yZWdpc3Rlcl9yZWFkX29ubHlfc2NhbGFyCiAqIEBzZWUgbmV0c25tcF9nZXRfc2NhbGFyX2hhbmRsZXIKICovCgppbnQKbmV0c25tcF9yZWdpc3Rlcl9zY2FsYXIobmV0c25tcF9oYW5kbGVyX3JlZ2lzdHJhdGlvbiAqcmVnaW5mbykKewogICAgLyoKICAgICAqIEV4dGVuZCB0aGUgcmVnaXN0ZXJlZCBPSUQgd2l0aCBzcGFjZSBmb3IgdGhlIGluc3RhbmNlIHN1YmlkCiAgICAgKiAoYnV0IGRvbid0IGV4dGVuZCB0aGUgbGVuZ3RoIGp1c3QgeWV0ISkKICAgICAqLwogICAgcmVnaW5mby0+cm9vdG9pZCA9IChvaWQqKXJlYWxsb2MocmVnaW5mby0+cm9vdG9pZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKHJlZ2luZm8tPnJvb3RvaWRfbGVuKzEpICogc2l6ZW9mKG9pZCkgKTsKICAgIHJlZ2luZm8tPnJvb3RvaWRbIHJlZ2luZm8tPnJvb3RvaWRfbGVuIF0gPSAwOwoKICAgIG5ldHNubXBfaW5qZWN0X2hhbmRsZXIocmVnaW5mbywgbmV0c25tcF9nZXRfaW5zdGFuY2VfaGFuZGxlcigpKTsKICAgIG5ldHNubXBfaW5qZWN0X2hhbmRsZXIocmVnaW5mbywgbmV0c25tcF9nZXRfc2NhbGFyX2hhbmRsZXIoKSk7CiAgICByZXR1cm4gbmV0c25tcF9yZWdpc3Rlcl9zZXJpYWxpemUocmVnaW5mbyk7Cn0KCgovKioKICogVGhpcyBmdW5jdGlvbiByZWdpc3RlcnMgYSByZWFkIG9ubHkgc2NhbGFyIGhlbHBlciBoYW5kbGVyLiBUaGlzIAogKiBmdW5jdGlvbiBpcyB2ZXJ5IHNpbWlsYXIgdG8gbmV0c25tcF9yZWdpc3Rlcl9zY2FsYXIgdGhlIG9ubHkgYWRkaXRpb24KICogaXMgdGhhdCB0aGUgInJlYWRfb25seSIgaGFuZGxlciBpcyBpbmplY3RlZCBpbnRvIHRoZSBoYW5kbGVyIGNoYWluCiAqIHByaW9yIHRvIGluamVjdGluZyB0aGUgc2VyaWFsaXplIGhhbmRsZXIgYW5kIHJlZ2lzdGVyaW5nIHJlZ2luZm8uCiAqCiAqIEBwYXJhbSByZWdpbmZvIGEgaGFuZGxlciByZWdpc3RyYXRpb24gc3RydWN0dXJlIHdoaWNoIGNvdWxkIGdldCBjcmVhdGVkCiAqICAgICAgICAgICAgICAgIHVzaW5nIG5ldHNubXBfY3JlYXRlX2hhbmRsZXJfcmVnaXN0cmF0aW9uLiAgVXNlZCB0byByZWdpc3RlcgogKiAgICAgICAgICAgICAgICBhIHJlYWQgb25seSBzY2FsYXIgaGVscGVyIGhhbmRsZXIuCiAqCiAqIEByZXR1cm4gIE1JQl9SRUdJU1RFUkVEX09LIGlzIHJldHVybmVkIGlmIHRoZSByZWdpc3RyYXRpb24gd2FzIGEgc3VjY2Vzcy4KICogIAlGYWlsdXJlcyBhcmUgTUlCX1JFR0lTVFJBVElPTl9GQUlMVVJFIGFuZCBNSUJfRFVQTElDQVRFX1JFR0lTVFJBVElPTi4KICoKICogQHNlZSBuZXRzbm1wX3JlZ2lzdGVyX3NjYWxhcgogKiBAc2VlIG5ldHNubXBfZ2V0X3NjYWxhcl9oYW5kbGVyCiAqCiAqLwogCmludApuZXRzbm1wX3JlZ2lzdGVyX3JlYWRfb25seV9zY2FsYXIobmV0c25tcF9oYW5kbGVyX3JlZ2lzdHJhdGlvbiAqcmVnaW5mbykKewogICAgLyoKICAgICAqIEV4dGVuZCB0aGUgcmVnaXN0ZXJlZCBPSUQgd2l0aCBzcGFjZSBmb3IgdGhlIGluc3RhbmNlIHN1YmlkCiAgICAgKiAoYnV0IGRvbid0IGV4dGVuZCB0aGUgbGVuZ3RoIGp1c3QgeWV0ISkKICAgICAqLwogICAgcmVnaW5mby0+cm9vdG9pZCA9IChvaWQqKXJlYWxsb2MocmVnaW5mby0+cm9vdG9pZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKHJlZ2luZm8tPnJvb3RvaWRfbGVuKzEpICogc2l6ZW9mKG9pZCkgKTsKICAgIHJlZ2luZm8tPnJvb3RvaWRbIHJlZ2luZm8tPnJvb3RvaWRfbGVuIF0gPSAwOwoKICAgIG5ldHNubXBfaW5qZWN0X2hhbmRsZXIocmVnaW5mbywgbmV0c25tcF9nZXRfaW5zdGFuY2VfaGFuZGxlcigpKTsKICAgIG5ldHNubXBfaW5qZWN0X2hhbmRsZXIocmVnaW5mbywgbmV0c25tcF9nZXRfc2NhbGFyX2hhbmRsZXIoKSk7CiAgICBuZXRzbm1wX2luamVjdF9oYW5kbGVyKHJlZ2luZm8sIG5ldHNubXBfZ2V0X3JlYWRfb25seV9oYW5kbGVyKCkpOwogICAgcmV0dXJuIG5ldHNubXBfcmVnaXN0ZXJfc2VyaWFsaXplKHJlZ2luZm8pOwp9CgoKCmludApuZXRzbm1wX3NjYWxhcl9oZWxwZXJfaGFuZGxlcihuZXRzbm1wX21pYl9oYW5kbGVyICpoYW5kbGVyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldHNubXBfaGFuZGxlcl9yZWdpc3RyYXRpb24gKnJlZ2luZm8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV0c25tcF9hZ2VudF9yZXF1ZXN0X2luZm8gKnJlcWluZm8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV0c25tcF9yZXF1ZXN0X2luZm8gKnJlcXVlc3RzKQp7CgogICAgbmV0c25tcF92YXJpYWJsZV9saXN0ICp2YXIgPSByZXF1ZXN0cy0+cmVxdWVzdHZiOwoKICAgIGludCAgICAgICAgICAgICByZXQsIGNtcDsKICAgIGludCAgICAgICAgICAgICBuYW1lbGVuOwoKICAgIERFQlVHTVNHVEwoKCJoZWxwZXI6c2NhbGFyIiwgIkdvdCByZXF1ZXN0OlxuIikpOwogICAgbmFtZWxlbiA9IFNOTVBfTUlOKHJlcXVlc3RzLT5yZXF1ZXN0dmItPm5hbWVfbGVuZ3RoLAogICAgICAgICAgICAgICAgICAgICAgIHJlZ2luZm8tPnJvb3RvaWRfbGVuKTsKICAgIGNtcCA9IHNubXBfb2lkX2NvbXBhcmUocmVxdWVzdHMtPnJlcXVlc3R2Yi0+bmFtZSwgbmFtZWxlbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVnaW5mby0+cm9vdG9pZCwgcmVnaW5mby0+cm9vdG9pZF9sZW4pOwoKICAgIERFQlVHTVNHVEwoKCJoZWxwZXI6c2NhbGFyIiwgIiAgb2lkOiIpKTsKICAgIERFQlVHTVNHT0lEKCgiaGVscGVyOnNjYWxhciIsIHZhci0+bmFtZSwgdmFyLT5uYW1lX2xlbmd0aCkpOwogICAgREVCVUdNU0coKCJoZWxwZXI6c2NhbGFyIiwgIlxuIikpOwoKICAgIHN3aXRjaCAocmVxaW5mby0+bW9kZSkgewogICAgY2FzZSBNT0RFX0dFVDoKICAgICAgICBpZiAoY21wICE9IDApIHsKICAgICAgICAgICAgbmV0c25tcF9zZXRfcmVxdWVzdF9lcnJvcihyZXFpbmZvLCByZXF1ZXN0cywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTTk1QX05PU1VDSE9CSkVDVCk7CiAgICAgICAgICAgIHJldHVybiBTTk1QX0VSUl9OT0VSUk9SOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHJlZ2luZm8tPnJvb3RvaWRbcmVnaW5mby0+cm9vdG9pZF9sZW4rK10gPSAwOwogICAgICAgICAgICByZXQgPSBuZXRzbm1wX2NhbGxfbmV4dF9oYW5kbGVyKGhhbmRsZXIsIHJlZ2luZm8sIHJlcWluZm8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlcXVlc3RzKTsKICAgICAgICAgICAgcmVnaW5mby0+cm9vdG9pZF9sZW4tLTsKICAgICAgICAgICAgcmV0dXJuIHJldDsKICAgICAgICB9CiAgICAgICAgYnJlYWs7CgojaWZuZGVmIE5FVFNOTVBfTk9fV1JJVEVfU1VQUE9SVAogICAgY2FzZSBNT0RFX1NFVF9SRVNFUlZFMToKICAgIGNhc2UgTU9ERV9TRVRfUkVTRVJWRTI6CiAgICBjYXNlIE1PREVfU0VUX0FDVElPTjoKICAgIGNhc2UgTU9ERV9TRVRfQ09NTUlUOgogICAgY2FzZSBNT0RFX1NFVF9VTkRPOgogICAgY2FzZSBNT0RFX1NFVF9GUkVFOgogICAgICAgIGlmIChjbXAgIT0gMCkgewogICAgICAgICAgICBuZXRzbm1wX3NldF9yZXF1ZXN0X2Vycm9yKHJlcWluZm8sIHJlcXVlc3RzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNOTVBfRVJSX05PQ1JFQVRJT04pOwogICAgICAgICAgICByZXR1cm4gU05NUF9FUlJfTk9FUlJPUjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICByZWdpbmZvLT5yb290b2lkW3JlZ2luZm8tPnJvb3RvaWRfbGVuKytdID0gMDsKICAgICAgICAgICAgcmV0ID0gbmV0c25tcF9jYWxsX25leHRfaGFuZGxlcihoYW5kbGVyLCByZWdpbmZvLCByZXFpbmZvLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXF1ZXN0cyk7CiAgICAgICAgICAgIHJlZ2luZm8tPnJvb3RvaWRfbGVuLS07CiAgICAgICAgICAgIHJldHVybiByZXQ7CiAgICAgICAgfQogICAgICAgIGJyZWFrOwojZW5kaWYgLyogTkVUU05NUF9OT19XUklURV9TVVBQT1JUICovCgogICAgY2FzZSBNT0RFX0dFVE5FWFQ6CiAgICAgICAgcmVnaW5mby0+cm9vdG9pZFtyZWdpbmZvLT5yb290b2lkX2xlbisrXSA9IDA7CiAgICAgICAgcmV0ID0gbmV0c25tcF9jYWxsX25leHRfaGFuZGxlcihoYW5kbGVyLCByZWdpbmZvLCByZXFpbmZvLCByZXF1ZXN0cyk7CiAgICAgICAgcmVnaW5mby0+cm9vdG9pZF9sZW4tLTsKICAgICAgICByZXR1cm4gcmV0OwogICAgfQogICAgLyoKICAgICAqIGdvdCBoZXJlIG9ubHkgaWYgaWxsZWdhbCBtb2RlIGZvdW5kIAogICAgICovCiAgICByZXR1cm4gU05NUF9FUlJfR0VORVJSOwp9CgovKiogQH0gCiAqLwo=