LyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgogKiBGaWxlbmFtZTogICAgICBnaXJiaWwuYwogKiBWZXJzaW9uOiAgICAgICAxLjIKICogRGVzY3JpcHRpb246ICAgSW1wbGVtZW50YXRpb24gZm9yIHRoZSBHcmVlbndpY2ggR0lyQklMIGRvbmdsZQogKiBTdGF0dXM6ICAgICAgICBFeHBlcmltZW50YWwuCiAqIEF1dGhvcjogICAgICAgIERhZyBCcmF0dGxpIDxkYWdiQGNzLnVpdC5ubz4KICogQ3JlYXRlZCBhdDogICAgU2F0IEZlYiAgNiAyMTowMjozMyAxOTk5CiAqIE1vZGlmaWVkIGF0OiAgIEZyaSBEZWMgMTcgMDk6MTM6MjAgMTk5OQogKiBNb2RpZmllZCBieTogICBEYWcgQnJhdHRsaSA8ZGFnYkBjcy51aXQubm8+CiAqCiAqICAgICBDb3B5cmlnaHQgKGMpIDE5OTkgRGFnIEJyYXR0bGksIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqICAgICAKICogICAgIFRoaXMgcHJvZ3JhbSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IKICogICAgIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGFzCiAqICAgICBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyIHZlcnNpb24gMiBvZgogKiAgICAgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uCiAqIAogKiAgICAgTmVpdGhlciBEYWcgQnJhdHRsaSBub3IgVW5pdmVyc2l0eSBvZiBUcm9tc/ggYWRtaXQgbGlhYmlsaXR5IG5vcgogKiAgICAgcHJvdmlkZSB3YXJyYW50eSBmb3IgYW55IG9mIHRoaXMgc29mdHdhcmUuIFRoaXMgbWF0ZXJpYWwgaXMKICogICAgIHByb3ZpZGVkICJBUy1JUyIgYW5kIGF0IG5vIGNoYXJnZS4KICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKI2luY2x1ZGUgPGxpbnV4L21vZHVsZS5oPgojaW5jbHVkZSA8bGludXgvZGVsYXkuaD4KI2luY2x1ZGUgPGxpbnV4L2luaXQuaD4KCiNpbmNsdWRlIDxuZXQvaXJkYS9pcmRhLmg+CgojaW5jbHVkZSAic2lyLWRldi5oIgoKc3RhdGljIGludCBnaXJiaWxfcmVzZXQoc3RydWN0IHNpcl9kZXYgKmRldik7CnN0YXRpYyBpbnQgZ2lyYmlsX29wZW4oc3RydWN0IHNpcl9kZXYgKmRldik7CnN0YXRpYyBpbnQgZ2lyYmlsX2Nsb3NlKHN0cnVjdCBzaXJfZGV2ICpkZXYpOwpzdGF0aWMgaW50IGdpcmJpbF9jaGFuZ2Vfc3BlZWQoc3RydWN0IHNpcl9kZXYgKmRldiwgdW5zaWduZWQgc3BlZWQpOwoKLyogQ29udHJvbCByZWdpc3RlciAxICovCiNkZWZpbmUgR0lSQklMX1RYRU4gICAgMHgwMSAvKiBFbmFibGUgdHJhbnNtaXR0ZXIgKi8KI2RlZmluZSBHSVJCSUxfUlhFTiAgICAweDAyIC8qIEVuYWJsZSByZWNlaXZlciAqLwojZGVmaW5lIEdJUkJJTF9FQ0FOICAgIDB4MDQgLyogQ2FuY2VsIHNlbGYgZW1taXRlZCBkYXRhICovCiNkZWZpbmUgR0lSQklMX0VDSE8gICAgMHgwOCAvKiBFY2hvIGNvbnRyb2wgY2hhcmFjdGVycyAqLwoKLyogTEVEIEN1cnJlbnQgUmVnaXN0ZXIgKDB4MikgKi8KI2RlZmluZSBHSVJCSUxfSElHSCAgICAweDIwCiNkZWZpbmUgR0lSQklMX01FRElVTSAgMHgyMQojZGVmaW5lIEdJUkJJTF9MT1cgICAgIDB4MjIKCi8qIEJhdWQgcmVnaXN0ZXIgKDB4MykgKi8KI2RlZmluZSBHSVJCSUxfMjQwMCAgICAweDMwCiNkZWZpbmUgR0lSQklMXzQ4MDAgICAgMHgzMQojZGVmaW5lIEdJUkJJTF85NjAwICAgIDB4MzIKI2RlZmluZSBHSVJCSUxfMTkyMDAgICAweDMzCiNkZWZpbmUgR0lSQklMXzM4NDAwICAgMHgzNAojZGVmaW5lIEdJUkJJTF81NzYwMCAgIDB4MzUKI2RlZmluZSBHSVJCSUxfMTE1MjAwICAweDM2CgovKiBNb2RlIHJlZ2lzdGVyICgweDQpICovCiNkZWZpbmUgR0lSQklMX0lSREEgICAgMHg0MAojZGVmaW5lIEdJUkJJTF9BU0sgICAgIDB4NDEKCi8qIENvbnRyb2wgcmVnaXN0ZXIgMiAoMHg1KSAqLwojZGVmaW5lIEdJUkJJTF9MT0FEICAgIDB4NTEgLyogTG9hZCB0aGUgbmV3IGJhdWQgcmF0ZSB2YWx1ZSAqLwoKc3RhdGljIHN0cnVjdCBkb25nbGVfZHJpdmVyIGdpcmJpbCA9IHsKCS5vd25lcgkJPSBUSElTX01PRFVMRSwKCS5kcml2ZXJfbmFtZQk9ICJHcmVlbndpY2ggR0lyQklMIiwKCS50eXBlCQk9IElSREFfR0lSQklMX0RPTkdMRSwKCS5vcGVuCQk9IGdpcmJpbF9vcGVuLAoJLmNsb3NlCQk9IGdpcmJpbF9jbG9zZSwKCS5yZXNldAkJPSBnaXJiaWxfcmVzZXQsCgkuc2V0X3NwZWVkCT0gZ2lyYmlsX2NoYW5nZV9zcGVlZCwKfTsKCnN0YXRpYyBpbnQgX19pbml0IGdpcmJpbF9zaXJfaW5pdCh2b2lkKQp7CglyZXR1cm4gaXJkYV9yZWdpc3Rlcl9kb25nbGUoJmdpcmJpbCk7Cn0KCnN0YXRpYyB2b2lkIF9fZXhpdCBnaXJiaWxfc2lyX2NsZWFudXAodm9pZCkKewoJaXJkYV91bnJlZ2lzdGVyX2RvbmdsZSgmZ2lyYmlsKTsKfQoKc3RhdGljIGludCBnaXJiaWxfb3BlbihzdHJ1Y3Qgc2lyX2RldiAqZGV2KQp7CglzdHJ1Y3QgcW9zX2luZm8gKnFvcyA9ICZkZXYtPnFvczsKCglJUkRBX0RFQlVHKDIsICIlcygpXG4iLCBfX0ZVTkNUSU9OX18pOwoKCS8qIFBvd2VyIG9uIGRvbmdsZSAqLwoJc2lyZGV2X3NldF9kdHJfcnRzKGRldiwgVFJVRSwgVFJVRSk7CgoJcW9zLT5iYXVkX3JhdGUuYml0cyAmPSBJUl85NjAwfElSXzE5MjAwfElSXzM4NDAwfElSXzU3NjAwfElSXzExNTIwMDsKCXFvcy0+bWluX3R1cm5fdGltZS5iaXRzID0gMHgwMzsKCWlyZGFfcW9zX2JpdHNfdG9fdmFsdWUocW9zKTsKCgkvKiBpcmRhIHRocmVhZCB3YWl0cyA1MCBtc2VjIGZvciBwb3dlciBzZXR0bGluZyAqLwoKCXJldHVybiAwOwp9CgpzdGF0aWMgaW50IGdpcmJpbF9jbG9zZShzdHJ1Y3Qgc2lyX2RldiAqZGV2KQp7CglJUkRBX0RFQlVHKDIsICIlcygpXG4iLCBfX0ZVTkNUSU9OX18pOwoKCS8qIFBvd2VyIG9mZiBkb25nbGUgKi8KCXNpcmRldl9zZXRfZHRyX3J0cyhkZXYsIEZBTFNFLCBGQUxTRSk7CgoJcmV0dXJuIDA7Cn0KCi8qCiAqIEZ1bmN0aW9uIGdpcmJpbF9jaGFuZ2Vfc3BlZWQgKGRldiwgc3BlZWQpCiAqCiAqICAgIFNldCB0aGUgc3BlZWQgZm9yIHRoZSBHaXJiaWwgdHlwZSBkb25nbGUuCiAqCiAqLwoKI2RlZmluZSBHSVJCSUxfU1RBVEVfV0FJVF9TUEVFRAkoU0lSREVWX1NUQVRFX0RPTkdMRV9TUEVFRCArIDEpCgpzdGF0aWMgaW50IGdpcmJpbF9jaGFuZ2Vfc3BlZWQoc3RydWN0IHNpcl9kZXYgKmRldiwgdW5zaWduZWQgc3BlZWQpCnsKCXVuc2lnbmVkIHN0YXRlID0gZGV2LT5mc20uc3Vic3RhdGU7Cgl1bnNpZ25lZCBkZWxheSA9IDA7Cgl1OCBjb250cm9sWzJdOwoJc3RhdGljIGludCByZXQgPSAwOwoKCUlSREFfREVCVUcoMiwgIiVzKClcbiIsIF9fRlVOQ1RJT05fXyk7CgoJLyogZG9uZ2xlIGFscmVhZCByZXNldCAtIHBvcnQgYW5kIGRvbmdsZSBhdCBkZWZhdWx0IHNwZWVkICovCgoJc3dpdGNoKHN0YXRlKSB7CgoJY2FzZSBTSVJERVZfU1RBVEVfRE9OR0xFX1NQRUVEOgoKCQkvKiBTZXQgRFRSIGFuZCBDbGVhciBSVFMgdG8gZW50ZXIgY29tbWFuZCBtb2RlICovCgkJc2lyZGV2X3NldF9kdHJfcnRzKGRldiwgRkFMU0UsIFRSVUUpOwoKCQl1ZGVsYXkoMjUpOwkJLyogYmV0dGVyIHdhaXQgYSBsaXR0bGUgd2hpbGUgKi8KCgkJcmV0ID0gMDsKCQlzd2l0Y2ggKHNwZWVkKSB7CgkJZGVmYXVsdDoKCQkJcmV0ID0gLUVJTlZBTDsKCQkJLyogZmFsbCB0aHJvdWdoICovCgkJY2FzZSA5NjAwOgoJCQljb250cm9sWzBdID0gR0lSQklMXzk2MDA7CgkJCWJyZWFrOwoJCWNhc2UgMTkyMDA6CgkJCWNvbnRyb2xbMF0gPSBHSVJCSUxfMTkyMDA7CgkJCWJyZWFrOwoJCWNhc2UgMzQ4MDA6CgkJCWNvbnRyb2xbMF0gPSBHSVJCSUxfMzg0MDA7CgkJCWJyZWFrOwoJCWNhc2UgNTc2MDA6CgkJCWNvbnRyb2xbMF0gPSBHSVJCSUxfNTc2MDA7CgkJCWJyZWFrOwoJCWNhc2UgMTE1MjAwOgoJCQljb250cm9sWzBdID0gR0lSQklMXzExNTIwMDsKCQkJYnJlYWs7CgkJfQoJCWNvbnRyb2xbMV0gPSBHSVJCSUxfTE9BRDsKCQoJCS8qIFdyaXRlIGNvbnRyb2wgYnl0ZXMgKi8KCQlzaXJkZXZfcmF3X3dyaXRlKGRldiwgY29udHJvbCwgMik7CgoJCWRldi0+c3BlZWQgPSBzcGVlZDsKCgkJc3RhdGUgPSBHSVJCSUxfU1RBVEVfV0FJVF9TUEVFRDsKCQlkZWxheSA9IDEwMDsKCQlicmVhazsKCgljYXNlIEdJUkJJTF9TVEFURV9XQUlUX1NQRUVEOgoJCS8qIEdvIGJhY2sgdG8gbm9ybWFsIG1vZGUgKi8KCQlzaXJkZXZfc2V0X2R0cl9ydHMoZGV2LCBUUlVFLCBUUlVFKTsKCgkJdWRlbGF5KDI1KTsJCS8qIGJldHRlciB3YWl0IGEgbGl0dGxlIHdoaWxlICovCgkJYnJlYWs7CgoJZGVmYXVsdDoKCQlJUkRBX0VSUk9SKCIlcyAtIHVuZGVmaW5lZCBzdGF0ZSAlZFxuIiwgX19GVU5DVElPTl9fLCBzdGF0ZSk7CgkJcmV0ID0gLUVJTlZBTDsKCQlicmVhazsKCX0KCWRldi0+ZnNtLnN1YnN0YXRlID0gc3RhdGU7CglyZXR1cm4gKGRlbGF5ID4gMCkgPyBkZWxheSA6IHJldDsKfQoKLyoKICogRnVuY3Rpb24gZ2lyYmlsX3Jlc2V0IChkcml2ZXIpCiAqCiAqICAgICAgVGhpcyBmdW5jdGlvbiByZXNldHMgdGhlIGdpcmJpbCBkb25nbGUuCiAqCiAqICAgICAgQWxnb3JpdGhtOgogKiAgICAJICAwLiBzZXQgUlRTLCBhbmQgd2FpdCBhdCBsZWFzdCA1IG1zCiAqICAgICAgICAxLiBjbGVhciBSVFMKICovCgoKI2RlZmluZSBHSVJCSUxfU1RBVEVfV0FJVDFfUkVTRVQJKFNJUkRFVl9TVEFURV9ET05HTEVfUkVTRVQgKyAxKQojZGVmaW5lIEdJUkJJTF9TVEFURV9XQUlUMl9SRVNFVAkoU0lSREVWX1NUQVRFX0RPTkdMRV9SRVNFVCArIDIpCiNkZWZpbmUgR0lSQklMX1NUQVRFX1dBSVQzX1JFU0VUCShTSVJERVZfU1RBVEVfRE9OR0xFX1JFU0VUICsgMykKCnN0YXRpYyBpbnQgZ2lyYmlsX3Jlc2V0KHN0cnVjdCBzaXJfZGV2ICpkZXYpCnsKCXVuc2lnbmVkIHN0YXRlID0gZGV2LT5mc20uc3Vic3RhdGU7Cgl1bnNpZ25lZCBkZWxheSA9IDA7Cgl1OCBjb250cm9sID0gR0lSQklMX1RYRU4gfCBHSVJCSUxfUlhFTjsKCWludCByZXQgPSAwOwoKCUlSREFfREVCVUcoMiwgIiVzKClcbiIsIF9fRlVOQ1RJT05fXyk7CgoJc3dpdGNoIChzdGF0ZSkgewoJY2FzZSBTSVJERVZfU1RBVEVfRE9OR0xFX1JFU0VUOgoJCS8qIFJlc2V0IGRvbmdsZSAqLwoJCXNpcmRldl9zZXRfZHRyX3J0cyhkZXYsIFRSVUUsIEZBTFNFKTsKCQkvKiBTbGVlcCBhdCBsZWFzdCA1IG1zICovCgkJZGVsYXkgPSAyMDsKCQlzdGF0ZSA9IEdJUkJJTF9TVEFURV9XQUlUMV9SRVNFVDsKCQlicmVhazsKCgljYXNlIEdJUkJJTF9TVEFURV9XQUlUMV9SRVNFVDoKCQkvKiBTZXQgRFRSIGFuZCBjbGVhciBSVFMgdG8gZW50ZXIgY29tbWFuZCBtb2RlICovCgkJc2lyZGV2X3NldF9kdHJfcnRzKGRldiwgRkFMU0UsIFRSVUUpOwoJCWRlbGF5ID0gMjA7CgkJc3RhdGUgPSBHSVJCSUxfU1RBVEVfV0FJVDJfUkVTRVQ7CgkJYnJlYWs7CgoJY2FzZSBHSVJCSUxfU1RBVEVfV0FJVDJfUkVTRVQ6CgkJLyogV3JpdGUgY29udHJvbCBieXRlICovCgkJc2lyZGV2X3Jhd193cml0ZShkZXYsICZjb250cm9sLCAxKTsKCQlkZWxheSA9IDIwOwoJCXN0YXRlID0gR0lSQklMX1NUQVRFX1dBSVQzX1JFU0VUOwoJCWJyZWFrOwoKCWNhc2UgR0lSQklMX1NUQVRFX1dBSVQzX1JFU0VUOgoJCS8qIEdvIGJhY2sgdG8gbm9ybWFsIG1vZGUgKi8KCQlzaXJkZXZfc2V0X2R0cl9ydHMoZGV2LCBUUlVFLCBUUlVFKTsKCQlkZXYtPnNwZWVkID0gOTYwMDsKCQlicmVhazsKCglkZWZhdWx0OgoJCUlSREFfRVJST1IoIiVzKCksIHVuZGVmaW5lZCBzdGF0ZSAlZFxuIiwgX19GVU5DVElPTl9fLCBzdGF0ZSk7CgkJcmV0ID0gLTE7CgkJYnJlYWs7Cgl9CglkZXYtPmZzbS5zdWJzdGF0ZSA9IHN0YXRlOwoJcmV0dXJuIChkZWxheSA+IDApID8gZGVsYXkgOiByZXQ7Cn0KCk1PRFVMRV9BVVRIT1IoIkRhZyBCcmF0dGxpIDxkYWdiQGNzLnVpdC5ubz4iKTsKTU9EVUxFX0RFU0NSSVBUSU9OKCJHcmVlbndpY2ggR0lyQklMIGRvbmdsZSBkcml2ZXIiKTsKTU9EVUxFX0xJQ0VOU0UoIkdQTCIpOwpNT0RVTEVfQUxJQVMoImlyZGEtZG9uZ2xlLTQiKTsgLyogSVJEQV9HSVJCSUxfRE9OR0xFICovCgptb2R1bGVfaW5pdChnaXJiaWxfc2lyX2luaXQpOwptb2R1bGVfZXhpdChnaXJiaWxfc2lyX2NsZWFudXApOwo=