LyoKICogKEMpIENvcHlyaWdodCAyMDAyCiAqIFN05HVibGkgRmF2ZXJnZXMgLSA8d3d3LnN0YXVibGkuY29tPgogKiBQaWVycmUgQVVCRVJUICBwLmF1YmVydEBzdGF1YmxpLmNvbQogKgogKiBTZWUgZmlsZSBDUkVESVRTIGZvciBsaXN0IG9mIHBlb3BsZSB3aG8gY29udHJpYnV0ZWQgdG8gdGhpcwogKiBwcm9qZWN0LgogKgogKiBUaGlzIHByb2dyYW0gaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yCiAqIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGFzCiAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXIgdmVyc2lvbiAyIG9mCiAqIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLgogKgogKiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwKICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YKICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZQogKiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQogKiBhbG9uZyB3aXRoIHRoaXMgcHJvZ3JhbTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZQogKiBGb3VuZGF0aW9uLCBJbmMuLCA1OSBUZW1wbGUgUGxhY2UsIFN1aXRlIDMzMCwgQm9zdG9uLAogKiBNQSAwMjExMS0xMzA3IFVTQQogKi8KCiNpbmNsdWRlIDxjb21tb24uaD4KI2luY2x1ZGUgPGNvbmZpZy5oPgojaW5jbHVkZSA8bWFsbG9jLmg+CgojaW5jbHVkZSAiZG9zLmgiCiNpbmNsdWRlICJmZG9zLmgiCgoKLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogKiBmaWxsX2ZzIC0tIFJlYWQgaW5mbyBvbiBmaWxlIHN5c3RlbQogKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAqLwpzdGF0aWMgaW50IGZpbGxfZnMgKEJvb3RTZWN0b3JfdCAqYm9vdCwgRnNfdCAqZnMpCnsKCiAgICBmcyAtPiBmYXRfc3RhcnQgPSBfX2xlMTZfdG9fY3B1IChib290IC0+IG5yc3ZzZWN0KTsKICAgIGZzIC0+IGZhdF9sZW4gPSBfX2xlMTZfdG9fY3B1IChib290IC0+IGZhdGxlbik7CiAgICBmcyAtPiBuYl9mYXQgPSBib290IC0+IG5mYXQ7CgogICAgZnMgLT4gZGlyX3N0YXJ0ID0gZnMgLT4gZmF0X3N0YXJ0ICsgZnMgLT4gbmJfZmF0ICogZnMgLT4gZmF0X2xlbjsKICAgIGZzIC0+IGRpcl9sZW4gPSBfX2xlMTZfdG9fY3B1IChib290IC0+IGRpcmVudHMpICogTURJUl9TSVpFIC8gU1pfU1REX1NFQ1RPUjsKICAgIGZzIC0+IGNsdXN0ZXJfc2l6ZSA9IGJvb3QgLT4gY2xzaXo7CiAgICBmcyAtPiBudW1fY2x1cyA9IChmcyAtPiB0b3Rfc2VjdG9ycyAtIGZzIC0+IGRpcl9zdGFydCAtIGZzIC0+IGRpcl9sZW4pIC8gZnMgLT4gY2x1c3Rlcl9zaXplOwoKICAgIHJldHVybiAoMCk7Cn0KCi8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICogZnNfaW5pdCAtLQogKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAqLwppbnQgZnNfaW5pdCAoRnNfdCAqZnMpCnsKICAgIEJvb3RTZWN0b3JfdCAqYm9vdDsKCiAgICAvKiBJbml0aWFsaXplIHBoeXNpY2FsIGRldmljZSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKi8KICAgIGlmIChkZXZfb3BlbiAoKSA8IDApIHsKCVBSSU5URiAoIlVuYWJsZSB0byBpbml0aWFsaXplIHRoZSBmZGNcbiIpOwoJcmV0dXJuICgtMSk7CiAgICB9CiAgICBpbml0X3N1YmRpciAoKTsKCiAgICAvKiBBbGxvY2F0ZSBzcGFjZSBmb3IgcmVhZCB0aGUgYm9vdCBzZWN0b3IgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKi8KICAgIGlmICgoYm9vdCA9IChCb290U2VjdG9yX3QgKiltYWxsb2MgKHNpemVvZiAoQm9vdFNlY3Rvcl90KSkpID09IE5VTEwpIHsKCVBSSU5URiAoIlVuYWJsZSB0byBhbGxvY2F0ZSBzcGFjZSBmb3IgYm9vdCBzZWN0b3JcbiIpOwoJcmV0dXJuICgtMSk7CiAgICB9CgogICAgLyogcmVhZCBib290IHNlY3RvciAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCiAgICBpZiAoZGV2X3JlYWQgKGJvb3QsIDAsIDEpKXsKCVBSSU5URiAoIkVycm9yIGR1cmluZyBib290IHNlY3RvciByZWFkXG4iKTsKCWZyZWUgKGJvb3QpOwoJcmV0dXJuICgtMSk7CiAgICB9CgogICAgLyogd2UgdmVyaWZ5IGl0J2EgYSBET1MgZGlza2V0dGUgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCiAgICBpZiAoYm9vdCAtPiBqdW1wIFswXSAhPSAgSlVNUF8wXzEgJiYgYm9vdCAtPiBqdW1wIFswXSAhPSAgSlVNUF8wXzIpIHsKCVBSSU5URiAoIk5vdCBhIERPUyBkaXNrZXR0ZVxuIik7CglmcmVlIChib290KTsKCXJldHVybiAoLTEpOwogICAgfQoKICAgIGlmIChib290IC0+IGRlc2NyIDwgTUVESUFfU1REKSB7CgkvKiBXZSBoYW5kbGUgb25seSByZWNlbnQgbWVkaWFzICh0eXBlIEYwKSAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLwoJUFJJTlRGICgidW5yZWNvZ25pemVkIGRpc2tldHRlIHR5cGVcbiIpOwoJZnJlZSAoYm9vdCk7CglyZXR1cm4gKC0xKTsKICAgIH0KCiAgICBpZiAoY2hlY2tfZGV2IChib290LCBmcykgPCAwKSB7CglQUklOVEYgKCJCYWQgZGlza2V0dGVcbiIpOwoJZnJlZSAoYm9vdCk7CglyZXR1cm4gKC0xKTsKICAgIH0KCiAgICBpZiAoZmlsbF9mcyAoYm9vdCwgZnMpIDwgMCkgewoJZnJlZSAoYm9vdCk7CgoJcmV0dXJuICgtMSk7CiAgICB9CgogICAgLyogUmVhZCBGQVQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCiAgICBpZiAocmVhZF9mYXQgKGJvb3QsIGZzKSA8IDApIHsKCWZyZWUgKGJvb3QpOwoJcmV0dXJuICgtMSk7CiAgICB9CgogICAgZnJlZSAoYm9vdCk7CiAgICByZXR1cm4gKDApOwp9Cg==