LyoNCiAqIEZyZWVSVE9TK0ZBVCBidWlsZCAxOTExMjggLSBOb3RlOiAgRnJlZVJUT1MrRkFUIGlzIHN0aWxsIGluIHRoZSBsYWIhDQogKiBDb3B5cmlnaHQgKEMpIDIwMTggQW1hem9uLmNvbSwgSW5jLiBvciBpdHMgYWZmaWxpYXRlcy4gIEFsbCBSaWdodHMgUmVzZXJ2ZWQuDQogKiBBdXRob3JzIGluY2x1ZGUgSmFtZXMgV2FsbXNsZXksIEhlaW4gVGlib3NjaCBhbmQgUmljaGFyZCBCYXJyeQ0KICoNCiAqIFBlcm1pc3Npb24gaXMgaGVyZWJ5IGdyYW50ZWQsIGZyZWUgb2YgY2hhcmdlLCB0byBhbnkgcGVyc29uIG9idGFpbmluZyBhIGNvcHkgb2YNCiAqIHRoaXMgc29mdHdhcmUgYW5kIGFzc29jaWF0ZWQgZG9jdW1lbnRhdGlvbiBmaWxlcyAodGhlICJTb2Z0d2FyZSIpLCB0byBkZWFsIGluDQogKiB0aGUgU29mdHdhcmUgd2l0aG91dCByZXN0cmljdGlvbiwgaW5jbHVkaW5nIHdpdGhvdXQgbGltaXRhdGlvbiB0aGUgcmlnaHRzIHRvDQogKiB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsIGRpc3RyaWJ1dGUsIHN1YmxpY2Vuc2UsIGFuZC9vciBzZWxsIGNvcGllcyBvZg0KICogdGhlIFNvZnR3YXJlLCBhbmQgdG8gcGVybWl0IHBlcnNvbnMgdG8gd2hvbSB0aGUgU29mdHdhcmUgaXMgZnVybmlzaGVkIHRvIGRvIHNvLA0KICogc3ViamVjdCB0byB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnM6DQogKg0KICogVGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgYW5kIHRoaXMgcGVybWlzc2lvbiBub3RpY2Ugc2hhbGwgYmUgaW5jbHVkZWQgaW4gYWxsDQogKiBjb3BpZXMgb3Igc3Vic3RhbnRpYWwgcG9ydGlvbnMgb2YgdGhlIFNvZnR3YXJlLg0KICoNCiAqIFRIRSBTT0ZUV0FSRSBJUyBQUk9WSURFRCAiQVMgSVMiLCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSBLSU5ELCBFWFBSRVNTIE9SDQogKiBJTVBMSUVELCBJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPIFRIRSBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSwgRklUTkVTUw0KICogRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFORCBOT05JTkZSSU5HRU1FTlQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBVVRIT1JTIE9SDQogKiBDT1BZUklHSFQgSE9MREVSUyBCRSBMSUFCTEUgRk9SIEFOWSBDTEFJTSwgREFNQUdFUyBPUiBPVEhFUiBMSUFCSUxJVFksIFdIRVRIRVINCiAqIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgVE9SVCBPUiBPVEhFUldJU0UsIEFSSVNJTkcgRlJPTSwgT1VUIE9GIE9SIElODQogKiBDT05ORUNUSU9OIFdJVEggVEhFIFNPRlRXQVJFIE9SIFRIRSBVU0UgT1IgT1RIRVIgREVBTElOR1MgSU4gVEhFIFNPRlRXQVJFLg0KICoNCiAqIGh0dHBzOi8vd3d3LkZyZWVSVE9TLm9yZw0KICoNCiAqLw0KDQovKioNCiAqCUBmaWxlCQlmZl9pb21hbi5jDQogKglAaW5ncm91cAlJT01BTg0KICoNCiAqCUBkZWZncm91cAlJT01BTglJL08gTWFuYWdlcg0KICoJQGJyaWVmCQlIYW5kbGVzIElPIGJ1ZmZlcnMgZm9yIEZyZWVSVE9TK0ZBVCBzYWZlbHkuDQogKg0KICoJUHJvdmlkZXMgYSBzaW1wbGUgc3RhdGljIGludGVyZmFjZSB0byB0aGUgcmVzdCBvZiBGcmVlUlRPUytGQVQgdG8gbWFuYWdlDQogKglidWZmZXJzLiBJdCBhbHNvIGRlZmluZXMgdGhlIHB1YmxpYyBpbnRlcmZhY2VzIGZvciBDcmVhdGluZyBhbmQNCiAqCURlc3Ryb3lpbmcgYSBGcmVlUlRPUytGQVQgSU8gb2JqZWN0Lg0KICoqLw0KDQojaW5jbHVkZSA8dGltZS5oPg0KI2luY2x1ZGUgPHN0cmluZy5oPg0KDQojaW5jbHVkZSAiZmZfaGVhZGVycy5oIg0KDQojZGVmaW5lIEZBVDE2X1NFQ1RPUl9DT1VOVF80MDg1CQk0MDg1DQojZGVmaW5lIEZBVDMyX1NFQ1RPUl9DT1VOVF82NTUyNQk2NTUyNSAvKiA2NTUzNiBjbHVzdGVycyAqLw0KDQovKiBTb21lIHZhbHVlcyBhbmQgb2Zmc2V0cyBkZXNjcmliaW5nIHRoZSBzcGVjaWFsIHNlY3RvciBGUyBJTkZPOiAqLw0KI2RlZmluZSAgRlNfSU5GT19TSUdOQVRVUkUxXzB4NDE2MTUyNTIJCQkweDQxNjE1MjUyVUwNCiNkZWZpbmUgIEZTX0lORk9fU0lHTkFUVVJFMl8weDYxNDE3MjcyCQkJMHg2MTQxNzI3MlVMDQojZGVmaW5lICBGU19JTkZPX09GRlNFVF9TSUdOQVRVUkUxXzAwMAkJCTANCiNkZWZpbmUgIEZTX0lORk9fT0ZGU0VUX1NJR05BVFVSRTJfNDg0CQkJNDg0DQojZGVmaW5lICBGU19JTkZPX09GRlNFVF9GUkVFX0NPVU5UXzQ4OAkJCTQ4OA0KI2RlZmluZSAgRlNfSU5GT19PRkZTRVRfRlJFRV9DTFVTVEVSXzQ5MgkJNDkyDQoNCi8qIEluc3BlY3QgdGhlIFBCUiAoUGFydGl0aW9uIEJvb3QgUmVjb3JkKSB0byBkZXRlcm1pbmUgdGhlIHR5cGUgb2YgRkFUICovDQpzdGF0aWMgRkZfRXJyb3JfdCBwcnZEZXRlcm1pbmVGYXRUeXBlKCBGRl9JT01hbmFnZXJfdCAqcHhJT01hbmFnZXIgKTsNCg0KLyogQ2hlY2sgaWYgYSBnaXZlbiBJRCBpbnRyb2R1Y2VzIGFuIGV4dGVuZGVkIHBhcnRpdGlvbi4gKi8NCnN0YXRpYyBCYXNlVHlwZV90IHBydklzRXh0ZW5kZWRQYXJ0aXRpb24oIHVpbnQ4X3QgdWNQYXJ0aXRpb25JRCApOw0KDQovKiBSZXR1cm4gcGRUUlVFIGlmIHRoZSBtZWRpYSBieXRlIGluIGFuIE1CUiBpcyB2YWxpZC4gKi8NCnN0YXRpYyBCYXNlVHlwZV90IHBydklzVmFsaWRNZWRpYSggdWludDhfdCBtZWRpYSApOw0KDQovKiBSZWFkIHRoZSBNQlIgdG8gc2VlIHdoYXQgZXh0ZW5kZWQgcGFydGl0aW9ucyBoYXZlIGJlZW4gZGVmaW5lZC4NCkRlZmluaXRpb25zIG9mIGV4dGVuZGVkIHBhcnRpdGlvbnMgbWF5IGJlIGNoYWluZWQuDQpXYWxrIGRvd24gdGhlIGNoYWluIHRvIGZpbmQgYWxsIGV4dGVuZGVkIHBhcnRpdGlvbnMuICovDQpzdGF0aWMgRkZfRXJyb3JfdCBGRl9QYXJzZUV4dGVuZGVkKCBGRl9JT01hbmFnZXJfdCAqcHhJT01hbmFnZXIsIHVpbnQzMl90IHVsRmlyc3RTZWN0b3IsIHVpbnQzMl90IHVsRmlyc3RTaXplLA0KCUZGX1NQYXJ0Rm91bmRfdCAqcFBhcnRzRm91bmQgKTsNCg0Kc3RhdGljIEZGX0Vycm9yX3QgRkZfR2V0RWZpUGFydGl0aW9uRW50cnkoIEZGX0lPTWFuYWdlcl90ICpweElPTWFuYWdlciwgdWludDMyX3QgdWxQYXJ0aXRpb25OdW1iZXIgKTsNCg0Kc3RhdGljIEJhc2VUeXBlX3QgcHJ2SGFzQWN0aXZlSGFuZGxlcyggRkZfSU9NYW5hZ2VyX3QgKnB4SU9NYW5hZ2VyICk7DQoNCg0KLyoqDQogKglAcHVibGljDQogKglAYnJpZWYJQ3JlYXRlcyBhbiBGRl9JT01hbmFnZXJfdCBvYmplY3QsIHRvIGluaXRpYWxpc2UgRnJlZVJUT1MrRkFUDQogKg0KICoJQHBhcmFtCXB1Y0NhY2hlTWVtCQkJUG9pbnRlciB0byBhIGJ1ZmZlciBmb3IgdGhlIGNhY2hlLiAoTlVMTCBpZiBvayB0byBNYWxsb2MpLg0KICoJQHBhcmFtCXVsQ2FjaGVTaXplCQkJVGhlIHNpemUgb2YgdGhlIHByb3ZpZGVkIGJ1ZmZlciwgb3Igc2l6ZSBvZiB0aGUgY2FjaGUgdG8gYmUgY3JlYXRlZC4NCiAqCQkJCQkJCQkoTXVzdCBiZSBhdCBsZWFzdCAyICogdWxTZWN0b3JTaXplKS4gQWx3YXlzIGEgbXVsdGlwbGUgb2YgdWxTZWN0b3JTaXplLg0KICoJQHBhcmFtCXVzU2VjdG9yU2l6ZQkJVGhlIGJsb2NrIHNpemUgb2YgZGV2aWNlcyB0byBiZSBhdHRhY2hlZC4gSWYgaW4gZG91YnQgdXNlIDUxMi4NCiAqCUBwYXJhbQlwRXJyb3IJCQkJUG9pbnRlciB0byBhIHNpZ25lZCBieXRlIGZvciBlcnJvciBjaGVja2luZy4gQ2FuIGJlIE5VTEwgaWYgbm90IHJlcXVpcmVkLg0KICoJCQkJCQkJCVRvIGJlIGNoZWNrZWQgd2hlbiBhIE5VTEwgcG9pbnRlciBpcyByZXR1cm5lZC4NCiAqDQogKglAUmV0dXJuCVJldHVybnMgYSBwb2ludGVyIHRvIGFuIEZGX0lPTWFuYWdlcl90IHR5cGUgb2JqZWN0LiBOVUxMIG9uIHhFcnJvciwgY2hlY2sgdGhlIGNvbnRlbnRzIG9mDQogKglAUmV0dXJuIHBFcnJvcg0KICoqLw0KRkZfSU9NYW5hZ2VyX3QgKkZGX0NyZWF0ZUlPTWFuZ2VyKCBGRl9DcmVhdGlvblBhcmFtZXRlcnNfdCAqcHhQYXJhbWV0ZXJzLCBGRl9FcnJvcl90ICpwRXJyb3IgKQ0Kew0KRkZfSU9NYW5hZ2VyX3QgKnB4SU9NYW5hZ2VyID0gTlVMTDsNCkZGX0Vycm9yX3QgeEVycm9yOw0KdWludDMyX3QgdWxDYWNoZVNpemUgPSBweFBhcmFtZXRlcnMtPnVsTWVtb3J5U2l6ZTsNCnVpbnQzMl90IHVzU2VjdG9yU2l6ZSA9IHB4UGFyYW1ldGVycy0+dWxTZWN0b3JTaXplOw0KDQoJLyogTm9ybWFsbHk6DQoJdWxTZWN0b3JTaXplID0gNTEyDQoJdWxDYWNoZVNpemUgPSBOIHggdWxTZWN0b3JTaXplLiAqLw0KCWlmKCAoICggdXNTZWN0b3JTaXplICUgNTEyICkgIT0gMCApIHx8ICggdXNTZWN0b3JTaXplID09IDAgKSApDQoJew0KCQkvKiB1bFNlY3RvclNpemUgU2l6ZSBub3QgYSBtdWx0aXBsZSBvZiA1MTIgb3IgaXQgaXMgemVybyovDQoJCXhFcnJvciA9IEZGX0VSUl9JT01BTl9CQURfQkxLU0laRSB8IEZGX0NSRUFURUlPTUFOOw0KCX0NCgllbHNlIGlmKCAoICggdWxDYWNoZVNpemUgJSAoIHVpbnQzMl90ICkgdXNTZWN0b3JTaXplICkgIT0gMCApIHx8ICggdWxDYWNoZVNpemUgPT0gMCApIHx8DQoJCQkgKCB1bENhY2hlU2l6ZSA9PSAoIHVpbnQzMl90ICkgdXNTZWN0b3JTaXplICkgKQ0KCXsNCgkJLyogVGhlIHNpemUgb2YgdGhlIGNhY2hpbmcgbWVtb3J5ICh1bENhY2hlU2l6ZSkgbXVzdCBub3cgYmUgYXRsZWFzdCAyICogdWxTZWN0b3JTaXplIChvciBhIGRlYWRsb2NrIHdpbGwgb2NjdXIpLiAqLw0KCQl4RXJyb3IgPSBGRl9FUlJfSU9NQU5fQkFEX01FTVNJWkUgfCBGRl9DUkVBVEVJT01BTjsNCgl9DQoJZWxzZQ0KCXsNCgkJcHhJT01hbmFnZXIgPSAoIEZGX0lPTWFuYWdlcl90ICogKSBmZmNvbmZpZ01BTExPQyggc2l6ZW9mKCBGRl9JT01hbmFnZXJfdCApICk7DQoNCgkJLyogRW5zdXJlIG1hbGxvYygpIHN1Y2NlZWRlZC4gKi8NCgkJaWYoIHB4SU9NYW5hZ2VyICE9IE5VTEwgKQ0KCQl7DQoJCQkvKiBVc2UgbWVtc2V0KCkgdG8gY2xlYXIgZXZlcnkgc2luZ2xlIGJpdC4gKi8NCgkJCW1lbXNldCggcHhJT01hbmFnZXIsICdcMCcsIHNpemVvZiggRkZfSU9NYW5hZ2VyX3QgKSApOw0KCQkJaWYoIEZGX0NyZWF0ZUV2ZW50cyggcHhJT01hbmFnZXIgKSAhPSBwZEZBTFNFICkNCgkJCXsNCgkJCQl4RXJyb3IgPSBGRl9FUlJfTk9ORTsNCgkJCX0NCgkJCWVsc2UNCgkJCXsNCgkJCQkvKiB4RXZlbnRHcm91cENyZWF0ZSgpIHByb2JhYmx5IGZhaWxlZC4gKi8NCgkJCQl4RXJyb3IgPSBGRl9FUlJfTk9UX0VOT1VHSF9NRU1PUlkgfCBGRl9DUkVBVEVJT01BTjsNCgkJCX0NCgkJfQ0KCQllbHNlDQoJCXsNCgkJCS8qIGZmY29uZmlnTUFMTE9DKCkgZmFpbGVkLiAqLw0KCQkJeEVycm9yID0gRkZfRVJSX05PVF9FTk9VR0hfTUVNT1JZIHwgRkZfQ1JFQVRFSU9NQU47DQoJCX0NCgl9DQoNCglpZiggRkZfaXNFUlIoIHhFcnJvciApID09IHBkRkFMU0UgKQ0KCXsNCgkJLyogcHhJT01hbmFnZXIgaXMgY3JlYXRlZCwgRkZfQ3JlYXRlRXZlbnRzKCkgc3VjY2VlZGVkLiAqLw0KCQlpZiggcHhQYXJhbWV0ZXJzLT5wdWNDYWNoZU1lbW9yeSAhPSBOVUxMICkNCgkJew0KCQkJLyogVGhlIGNhbGxlciBoYXMgcHJvdmlkZWQgYSBwaWVjZSBvZiBtZW1vcnksIHVzZSBpdC4gKi8NCgkJCXB4SU9NYW5hZ2VyLT5wdWNDYWNoZU1lbSA9IHB4UGFyYW1ldGVycy0+cHVjQ2FjaGVNZW1vcnk7DQoJCX0NCgkJZWxzZQ0KCQl7DQoJCQkvKiBObyBjYWNoZSBidWZmZXIgcHJvdmlkZWQsIGNhbGwgbWFsbG9jKCkuICovDQoJCQlweElPTWFuYWdlci0+cHVjQ2FjaGVNZW0gPSAoIHVpbnQ4X3QgKiApIGZmY29uZmlnTUFMTE9DKCB1bENhY2hlU2l6ZSApOw0KCQkJaWYoIHB4SU9NYW5hZ2VyLT5wdWNDYWNoZU1lbSAhPSBOVUxMICkNCgkJCXsNCgkJCQkvKiBJbmRpY2F0ZSB0aGF0IG1hbGxvYygpIHdhcyB1c2VkIGZvciBwdWNDYWNoZU1lbS4gKi8NCgkJCQlweElPTWFuYWdlci0+dWNGbGFncyB8PSBGRl9JT01BTl9BTExPQ19CVUZGRVJTOw0KCQkJfQ0KCQkJZWxzZQ0KCQkJew0KCQkJCXhFcnJvciA9IEZGX0VSUl9OT1RfRU5PVUdIX01FTU9SWSB8IEZGX0NSRUFURUlPTUFOOw0KCQkJfQ0KCQl9DQoNCgkJaWYoIHB4SU9NYW5hZ2VyLT5wdWNDYWNoZU1lbSAhPSBOVUxMICkNCgkJew0KCQkJbWVtc2V0KCBweElPTWFuYWdlci0+cHVjQ2FjaGVNZW0sICdcMCcsIHVsQ2FjaGVTaXplICk7DQoJCX0NCgl9DQoNCglpZiggRkZfaXNFUlIoIHhFcnJvciApID09IHBkRkFMU0UgKQ0KCXsNCgkJcHhJT01hbmFnZXItPnVzU2VjdG9yU2l6ZSA9IHVzU2VjdG9yU2l6ZTsNCgkJcHhJT01hbmFnZXItPnVzQ2FjaGVTaXplID0gKCB1aW50MTZfdCApICggdWxDYWNoZVNpemUgLyAoIHVpbnQzMl90ICkgdXNTZWN0b3JTaXplICk7DQoNCgkJLyogTWFsbG9jKCkgbWVtb3J5IGZvciBidWZmZXIgb2JqZWN0cy4gRnJlZVJUT1MrRkFUIG5ldmVyIHJlZmVycyB0byBhDQoJCWJ1ZmZlciBkaXJlY3RseSBidXQgdXNlcyBidWZmZXIgb2JqZWN0cyBpbnN0ZWFkLiBBbGxvd3MgZm9yIHRocmVhZA0KCQlzYWZldHkuICovDQoJCXB4SU9NYW5hZ2VyLT5weEJ1ZmZlcnMgPSAoIEZGX0J1ZmZlcl90ICogKSBmZmNvbmZpZ01BTExPQyggc2l6ZW9mKCBGRl9CdWZmZXJfdCApICogcHhJT01hbmFnZXItPnVzQ2FjaGVTaXplICk7DQoNCgkJaWYoIHB4SU9NYW5hZ2VyLT5weEJ1ZmZlcnMgIT0gTlVMTCApDQoJCXsNCgkJCS8qIEZyb20gbm93IG9uIGEgY2FsbCB0byBGRl9JT01BTl9Jbml0QnVmZmVyRGVzY3JpcHRvcnMgd2lsbCBjbGVhcg0KCQkJcHhCdWZmZXJzLiAqLw0KCQkJcHhJT01hbmFnZXItPnVjRmxhZ3MgfD0gRkZfSU9NQU5fQUxMT0NfQlVGREVTQ1I7DQoNCgkJCUZGX0lPTUFOX0luaXRCdWZmZXJEZXNjcmlwdG9ycyggcHhJT01hbmFnZXIgKTsNCg0KCQkJLyogRmluYWxseSBzdG9yZSB0aGUgc2VtYXBob3JlIGZvciBCdWZmZXIgRGVzY3JpcHRpb24gbW9kaWZpY2F0aW9ucy4gKi8NCgkJCXB4SU9NYW5hZ2VyLT5wdlNlbWFwaG9yZSA9IHB4UGFyYW1ldGVycy0+cHZTZW1hcGhvcmU7DQoNCgkJCWlmKCBweFBhcmFtZXRlcnMtPnhCbG9ja0RldmljZUlzUmVlbnRyYW50ICE9IHBkRkFMU0UgKQ0KCQkJew0KCQkJCXB4SU9NYW5hZ2VyLT51Y0ZsYWdzIHw9IEZGX0lPTUFOX0JMT0NLX0RFVklDRV9JU19SRUVOVFJBTlQ7DQoJCQl9DQoNCgkJCXB4SU9NYW5hZ2VyLT54QmxrRGV2aWNlLmZucFJlYWRCbG9ja3MJPSBweFBhcmFtZXRlcnMtPmZuUmVhZEJsb2NrczsNCgkJCXB4SU9NYW5hZ2VyLT54QmxrRGV2aWNlLmZucFdyaXRlQmxvY2tzCT0gcHhQYXJhbWV0ZXJzLT5mbldyaXRlQmxvY2tzOw0KCQkJcHhJT01hbmFnZXItPnhCbGtEZXZpY2UucHhEaXNrCQkJPSBweFBhcmFtZXRlcnMtPnB4RGlzazsNCgkJfQ0KCQllbHNlDQoJCXsNCgkJCXhFcnJvciA9IEZGX0VSUl9OT1RfRU5PVUdIX01FTU9SWSB8IEZGX0NSRUFURUlPTUFOOw0KCQl9DQoJfQ0KDQoJaWYoIEZGX2lzRVJSKCB4RXJyb3IgKSApDQoJew0KCQlpZiggcHhJT01hbmFnZXIgIT0gTlVMTCApDQoJCXsNCgkJCUZGX0RlbGV0ZUlPTWFuYWdlciggcHhJT01hbmFnZXIgKTsNCgkJCXB4SU9NYW5hZ2VyID0gTlVMTDsNCgkJfQ0KCX0NCg0KCWlmKCBwRXJyb3IgIT0gTlVMTCApDQoJew0KCQkqcEVycm9yID0geEVycm9yOw0KCX0NCg0KCXJldHVybiBweElPTWFuYWdlcjsNCn0JLyogRkZfQ3JlYXRlSU9NYW5nZXIoKSAqLw0KLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovDQoNCi8qKg0KICoJQHB1YmxpYw0KICoJQGJyaWVmCURlc3Ryb3lzIGFuIEZGX0lPTWFuYWdlcl90IG9iamVjdCwgYW5kIGZyZWVzIGFsbCBhc3NpZ25lZCBtZW1vcnkuDQogKg0KICoJQHBhcmFtCXB4SU9NYW5hZ2VyCVBvaW50ZXIgdG8gYW4gRkZfSU9NYW5hZ2VyX3Qgb2JqZWN0LCBhcyByZXR1cm5lZCBmcm9tIEZGX0NyZWF0ZUlPTWFuZ2VyLg0KICoNCiAqCUBSZXR1cm4JRkZfRVJSX05PTkUgb24gc3VjZXNzLCBvciBhIGRvY3VtZW50ZWQgZXJyb3IgY29kZSBvbiBmYWlsdXJlLiAoRkZfRVJSX05VTExfUE9JTlRFUikNCiAqDQogKiovDQpGRl9FcnJvcl90IEZGX0RlbGV0ZUlPTWFuYWdlciggRkZfSU9NYW5hZ2VyX3QgKnB4SU9NYW5hZ2VyICkNCnsNCkZGX0Vycm9yX3QgeEVycm9yOw0KDQoJLyogRW5zdXJlIG5vIE5VTEwgcG9pbnRlciB3YXMgcHJvdmlkZWQuICovDQoJaWYoIHB4SU9NYW5hZ2VyID09IE5VTEwgKQ0KCXsNCgkJeEVycm9yID0gRkZfRVJSX05VTExfUE9JTlRFUiB8IEZGX0RFU1RST1lJT01BTjsNCgl9DQoJZWxzZQ0KCXsNCgkJeEVycm9yID0gRkZfRVJSX05PTkU7DQoNCgkJLyogRW5zdXJlIHB4QnVmZmVycyBwb2ludGVyIHdhcyBhbGxvY2F0ZWQuICovDQoJCWlmKCAoIHB4SU9NYW5hZ2VyLT51Y0ZsYWdzICYgRkZfSU9NQU5fQUxMT0NfQlVGREVTQ1IgKSAhPSAwICkNCgkJew0KCQkJZmZjb25maWdGUkVFKCBweElPTWFuYWdlci0+cHhCdWZmZXJzICk7DQoJCX0NCg0KCQkvKiBFbnN1cmUgcHVjQ2FjaGVNZW0gcG9pbnRlciB3YXMgYWxsb2NhdGVkLiAqLw0KCQlpZiggKCBweElPTWFuYWdlci0+dWNGbGFncyAmIEZGX0lPTUFOX0FMTE9DX0JVRkZFUlMgKSAhPSAwICkNCgkJew0KCQkJZmZjb25maWdGUkVFKCBweElPTWFuYWdlci0+cHVjQ2FjaGVNZW0gKTsNCgkJfQ0KDQoJCS8qIERlbGV0ZSB0aGUgZXZlbnQgZ3JvdXAgb2JqZWN0IHdpdGhpbiB0aGUgSU8gbWFuYWdlciBiZWZvcmUgZGVsZXRpbmcNCgkJdGhlIG1hbmFnZXIuICovDQoJCUZGX0RlbGV0ZUV2ZW50cyggcHhJT01hbmFnZXIgKTsNCg0KCQkvKiBGaW5hbGx5IGZyZWUgdGhlIEZGX0lPTWFuYWdlcl90IG9iamVjdC4gKi8NCgkJZmZjb25maWdGUkVFKCBweElPTWFuYWdlciApOw0KCX0NCg0KCXJldHVybiB4RXJyb3I7DQp9CS8qIEZGX0RlbGV0ZUlPTWFuYWdlcigpICovDQovKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8NCg0KLyoqDQogKglAcHJpdmF0ZQ0KICoJQGJyaWVmCUluaXRpYWxpc2VzIEJ1ZmZlciBEZXNjcmlwdGlvbnMgYXMgcGFydCBvZiB0aGUgRkZfSU9NYW5hZ2VyX3Qgb2JqZWN0IGluaXRpYWxpc2F0aW9uLg0KICoNCiAqCUBwYXJhbQlweElPTWFuYWdlcgkJSU9NQU4gT2JqZWN0Lg0KICoNCiAqKi8NCnZvaWQgRkZfSU9NQU5fSW5pdEJ1ZmZlckRlc2NyaXB0b3JzKCBGRl9JT01hbmFnZXJfdCAqcHhJT01hbmFnZXIgKQ0Kew0KdWludDhfdCAqcHVjQnVmZmVyID0gcHhJT01hbmFnZXItPnB1Y0NhY2hlTWVtOw0KRkZfQnVmZmVyX3QgKnB4QnVmZmVyID0gcHhJT01hbmFnZXItPnB4QnVmZmVyczsNCkZGX0J1ZmZlcl90ICpweExhc3RCdWZmZXIgPSBweEJ1ZmZlciArIHB4SU9NYW5hZ2VyLT51c0NhY2hlU2l6ZTsNCg0KCS8qIENsZWFyIHRoZSBjb250ZW50cyBvZiB0aGUgYnVmZmVyIGRlc2NyaXB0b3JzLiAqLw0KCW1lbXNldCggKCB2b2lkICogKSBweEJ1ZmZlciwgJ1wwJywgc2l6ZW9mKCBGRl9CdWZmZXJfdCApICogcHhJT01hbmFnZXItPnVzQ2FjaGVTaXplICk7DQoNCgl3aGlsZSggcHhCdWZmZXIgPCBweExhc3RCdWZmZXIgKQ0KCXsNCgkJcHhCdWZmZXItPnB1Y0J1ZmZlciA9IHB1Y0J1ZmZlcjsNCgkJcHhCdWZmZXIrKzsNCgkJcHVjQnVmZmVyICs9IHB4SU9NYW5hZ2VyLT51c1NlY3RvclNpemU7DQoJfQ0KfQkvKiBGRl9JT01BTl9Jbml0QnVmZmVyRGVzY3JpcHRvcnMoKSAqLw0KLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovDQoNCi8qKg0KICoJQHByaXZhdGUNCiAqCUBicmllZgkJRmx1c2hlcyBhbGwgV3JpdGUgY2FjaGUgYnVmZmVycyB3aXRoIG5vIGFjdGl2ZSBIYW5kbGVzLg0KICoNCiAqCUBwYXJhbQkJcHhJT01hbmFnZXIJSU9NQU4gT2JqZWN0Lg0KICoNCiAqCUBSZXR1cm4JCUZGX0VSUl9OT05FIG9uIFN1Y2Nlc3MuDQogKiovDQpGRl9FcnJvcl90IEZGX0ZsdXNoQ2FjaGUoIEZGX0lPTWFuYWdlcl90ICpweElPTWFuYWdlciApDQp7DQpCYXNlVHlwZV90IHhJbmRleCwgeEluZGV4MjsNCkZGX0Vycm9yX3QgeEVycm9yOw0KDQoJaWYoIHB4SU9NYW5hZ2VyID09IE5VTEwgKQ0KCXsNCgkJeEVycm9yID0gRkZfRVJSX05VTExfUE9JTlRFUiB8IEZGX0ZMVVNIQ0FDSEU7DQoJfQ0KCWVsc2UNCgl7DQoJCXhFcnJvciA9IEZGX0VSUl9OT05FOw0KDQoJCUZGX1BlbmRTZW1hcGhvcmUoIHB4SU9NYW5hZ2VyLT5wdlNlbWFwaG9yZSApOw0KCQl7DQoJCQlmb3IoIHhJbmRleCA9IDA7IHhJbmRleCA8IHB4SU9NYW5hZ2VyLT51c0NhY2hlU2l6ZTsgeEluZGV4KysgKQ0KCQkJew0KCQkJCS8qIElmIGEgYnVmZmVycyBoYXMgbm8gdXNlcnMgYW5kIGlmIGl0IGhhcyBiZWVuIG1vZGlmaWVkLi4uICovDQoJCQkJaWYoICggcHhJT01hbmFnZXItPnB4QnVmZmVyc1sgeEluZGV4IF0udXNOdW1IYW5kbGVzID09IDAgKSAmJiAoIHB4SU9NYW5hZ2VyLT5weEJ1ZmZlcnNbIHhJbmRleCBdLmJNb2RpZmllZCA9PSBwZFRSVUUgKSApDQoJCQkJew0KCQkJCQkvKiBUaGUgYnVmZmVyIG1heSBiZSBmbHVzaGVkIHRvIGRpc2suICovDQoJCQkJCUZGX0Jsb2NrV3JpdGUoIHB4SU9NYW5hZ2VyLCBweElPTWFuYWdlci0+cHhCdWZmZXJzWyB4SW5kZXggXS51bFNlY3RvciwgMSwgcHhJT01hbmFnZXItPnB4QnVmZmVyc1sgeEluZGV4IF0ucHVjQnVmZmVyLCBwZFRSVUUgKTsNCg0KCQkJCQkvKiBCdWZmZXIgaGFzIG5vdyBiZWVuIGZsdXNoZWQsIG1hcmsgaXQgYXMgYSByZWFkIGJ1ZmZlciBhbmQgdW5tb2RpZmllZC4gKi8NCgkJCQkJcHhJT01hbmFnZXItPnB4QnVmZmVyc1sgeEluZGV4IF0udWNNb2RlID0gRkZfTU9ERV9SRUFEOw0KCQkJCQlweElPTWFuYWdlci0+cHhCdWZmZXJzWyB4SW5kZXggXS5iTW9kaWZpZWQgPSBwZEZBTFNFOw0KDQoJCQkJCS8qIFNlYXJjaCBmb3Igb3RoZXIgYnVmZmVycyB0aGF0IHVzZWQgdGhpcyBzZWN0b3IsIGFuZCBtYXJrIHRoZW0gYXMgbW9kaWZpZWQNCgkJCQkJU28gdGhhdCBmdXJ0aGVyIHJlcXVlc3RzIHdpbGwgcmVzdWx0IGluIHRoZSBuZXcgc2VjdG9yIGJlaW5nIGZldGNoZWQuICovDQoJCQkJCWZvciggeEluZGV4MiA9IDA7IHhJbmRleDIgPCBweElPTWFuYWdlci0+dXNDYWNoZVNpemU7IHhJbmRleDIrKyApDQoJCQkJCXsNCgkJCQkJCWlmKCAoIHhJbmRleCAhPSB4SW5kZXgyICkgJiYNCgkJCQkJCQkoIHB4SU9NYW5hZ2VyLT5weEJ1ZmZlcnNbIHhJbmRleDIgXS51bFNlY3RvciA9PSBweElPTWFuYWdlci0+cHhCdWZmZXJzWyB4SW5kZXggXS51bFNlY3RvciApICYmDQoJCQkJCQkJKCBweElPTWFuYWdlci0+cHhCdWZmZXJzWyB4SW5kZXgyIF0udWNNb2RlID09IEZGX01PREVfUkVBRCApICkNCgkJCQkJCXsNCgkJCQkJCQlweElPTWFuYWdlci0+cHhCdWZmZXJzWyB4SW5kZXgyIF0uYk1vZGlmaWVkID0gcGRUUlVFOw0KCQkJCQkJfQ0KCQkJCQl9DQoJCQkJfQ0KCQkJfQ0KCQl9DQoJCWlmKCAoIHB4SU9NYW5hZ2VyLT54QmxrRGV2aWNlLnB4RGlzayAhPSBOVUxMICkgJiYNCgkJCSggcHhJT01hbmFnZXItPnhCbGtEZXZpY2UucHhEaXNrLT5mbkZsdXNoQXBwbGljYXRpb25Ib29rICE9IE5VTEwgKSApDQoJCXsNCgkJCS8qIExldCB0aGUgbG93LWxldmVsIGRyaXZlciBhbHNvIGZsdXNoIGRhdGEuDQoJCQlTZWUgY29tbWVudHMgaW4gZmZfaW9tYW4uaC4gKi8NCgkJCXB4SU9NYW5hZ2VyLT54QmxrRGV2aWNlLnB4RGlzay0+Zm5GbHVzaEFwcGxpY2F0aW9uSG9vayggcHhJT01hbmFnZXItPnhCbGtEZXZpY2UucHhEaXNrICk7DQoJCX0NCg0KCQlGRl9SZWxlYXNlU2VtYXBob3JlKCBweElPTWFuYWdlci0+cHZTZW1hcGhvcmUgKTsNCgl9DQoNCglyZXR1cm4geEVycm9yOw0KfQkvKiBGRl9GbHVzaENhY2hlKCkgKi8NCi8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLw0KDQovKg0KCUEgbmV3IHZlcnNpb24gb2YgRkZfR2V0QnVmZmVyKCkgd2l0aCBhIHNpbXBsZSBtZWNoYW5pc20gZm9yIHRpbWVvdXQNCiovDQojZGVmaW5lIEZGX0dFVEJVRkZFUl9TTEVFUF9USU1FX01TCTEwDQojZGVmaW5lIEZGX0dFVEJVRkZFUl9XQUlUX1RJTUVfTVMJKCAyMDAwMCAvIEZGX0dFVEJVRkZFUl9TTEVFUF9USU1FX01TICkNCg0KRkZfQnVmZmVyX3QgKkZGX0dldEJ1ZmZlciggRkZfSU9NYW5hZ2VyX3QgKnB4SU9NYW5hZ2VyLCB1aW50MzJfdCB1bFNlY3RvciwgdWludDhfdCB1Y01vZGUgKQ0Kew0KRkZfQnVmZmVyX3QgKnB4QnVmZmVyOw0KLyogTGVhc3QgUmVjZW50bHkgVXNlZCBCdWZmZXIgKi8NCkZGX0J1ZmZlcl90ICpweFJMVUJ1ZmZlcjsNCkZGX0J1ZmZlcl90ICpweE1hdGNoaW5nQnVmZmVyID0gTlVMTDsNCmludDMyX3QgbFJldFZhbDsNCkJhc2VUeXBlX3QgeExvb3BDb3VudCA9IEZGX0dFVEJVRkZFUl9XQUlUX1RJTUVfTVM7DQpjb25zdCBGRl9CdWZmZXJfdCAqcHhMYXN0QnVmZmVyID0gJiggcHhJT01hbmFnZXItPnB4QnVmZmVyc1sgcHhJT01hbmFnZXItPnVzQ2FjaGVTaXplIF0gKTsNCg0KCS8qICdweElPTWFuYWdlci0+dXNDYWNoZVNpemUnIGlzIGJpZ2dlciB0aGFuIHplcm8gYW5kIGl0IGlzIGEgbXVsdGlwbGUgb2YgdWxTZWN0b3JTaXplLiAqLw0KDQoJd2hpbGUoIHB4TWF0Y2hpbmdCdWZmZXIgPT0gTlVMTCApDQoJew0KCQl4TG9vcENvdW50LS07DQoJCWlmKCB4TG9vcENvdW50ID09IDAgKQ0KCQl7DQoJCQlicmVhazsNCgkJfQ0KDQoJCUZGX1BlbmRTZW1hcGhvcmUoIHB4SU9NYW5hZ2VyLT5wdlNlbWFwaG9yZSApOw0KDQoJCWZvciggcHhCdWZmZXIgPSBweElPTWFuYWdlci0+cHhCdWZmZXJzOyBweEJ1ZmZlciA8IHB4TGFzdEJ1ZmZlcjsgcHhCdWZmZXIrKyApDQoJCXsNCgkJCWlmKCAoIHB4QnVmZmVyLT51bFNlY3RvciA9PSB1bFNlY3RvciApICYmICggcHhCdWZmZXItPmJWYWxpZCApICkNCgkJCXsNCgkJCQlweE1hdGNoaW5nQnVmZmVyID0gcHhCdWZmZXI7DQoJCQkJLyogRG9uJ3QgbG9vayBmdXJ0aGVyIGlmIHlvdSBmb3VuZCBhIHBlcmZlY3QgbWF0Y2guICovDQoJCQkJYnJlYWs7DQoJCQl9DQoJCX0NCg0KCQlpZiggcHhNYXRjaGluZ0J1ZmZlciAhPSBOVUxMICkNCgkJew0KCQkJLyogQSBNYXRjaCB3YXMgZm91bmQgcHJvY2VzcyEgKi8NCgkJCWlmKCAoIHVjTW9kZSA9PSBGRl9NT0RFX1JFQUQgKSAmJiAoIHB4TWF0Y2hpbmdCdWZmZXItPnVjTW9kZSA9PSBGRl9NT0RFX1JFQUQgKSApDQoJCQl7DQoJCQkJcHhNYXRjaGluZ0J1ZmZlci0+dXNOdW1IYW5kbGVzICs9IDE7DQoJCQkJcHhNYXRjaGluZ0J1ZmZlci0+dXNQZXJzaXN0YW5jZSArPSAxOw0KCQkJCWJyZWFrOw0KCQkJfQ0KDQoJCQlpZiggcHhNYXRjaGluZ0J1ZmZlci0+dXNOdW1IYW5kbGVzID09IDAgKQ0KCQkJew0KCQkJCXB4TWF0Y2hpbmdCdWZmZXItPnVjTW9kZSA9ICggdWNNb2RlICYgRkZfTU9ERV9SRF9XUiApOw0KCQkJCWlmKCAoIHVjTW9kZSAmIEZGX01PREVfV1JJVEUgKSAhPSAwICkNCgkJCQl7DQoJCQkJCS8qIFRoaXMgYnVmZmVyIGhhcyBubyBhdHRhY2hlZCBoYW5kbGVzLiAqLw0KCQkJCQlweE1hdGNoaW5nQnVmZmVyLT5iTW9kaWZpZWQgPSBwZFRSVUU7DQoJCQkJfQ0KDQoJCQkJcHhNYXRjaGluZ0J1ZmZlci0+dXNOdW1IYW5kbGVzID0gMTsNCgkJCQlweE1hdGNoaW5nQnVmZmVyLT51c1BlcnNpc3RhbmNlICs9IDE7DQoJCQkJYnJlYWs7DQoJCQl9DQoNCgkJCXB4TWF0Y2hpbmdCdWZmZXIgPSBOVUxMOwkvKiBTZWN0b3IgaXMgYWxyZWFkeSBpbiB1c2UsIGtlZXAgeWllbGRpbmcgdW50aWwgaXRzIGF2YWlsYWJsZSEgKi8NCgkJfQ0KCQllbHNlDQoJCXsNCgkJCS8qIFRoZXJlIGlzIG5vIHZhbGlkIGJ1ZmZlciBub3cgZm9yIHRoZSBkZXNpcmVkIHNlY3Rvci4NCgkJCUZpbmQgYSBmcmVlIGJ1ZmZlciBhbmQgdXNlIGl0IGZvciB0aGF0IHNlY3Rvci4gKi8NCgkJCXB4UkxVQnVmZmVyID0gTlVMTDsNCg0KCQkJZm9yKCBweEJ1ZmZlciA9IHB4SU9NYW5hZ2VyLT5weEJ1ZmZlcnM7IHB4QnVmZmVyIDwgcHhMYXN0QnVmZmVyOyBweEJ1ZmZlcisrICkNCgkJCXsNCgkJCQlpZiggcHhCdWZmZXItPnVzTnVtSGFuZGxlcyAhPSAwICkNCgkJCQl7DQoJCQkJCWNvbnRpbnVlOwkvKiBPY2N1cGllZCAqLw0KCQkJCX0NCg0KCQkJCXB4QnVmZmVyLT51bExSVSArPSAxOw0KDQoJCQkJaWYoICggcHhSTFVCdWZmZXIgPT0gTlVMTCApIHx8DQoJCQkJCSggcHhCdWZmZXItPnVsTFJVID4gcHhSTFVCdWZmZXItPnVsTFJVICkgfHwNCgkJCQkJKCAoIHB4QnVmZmVyLT51bExSVSA9PSBweFJMVUJ1ZmZlci0+dWxMUlUgKSAmJiAoIHB4QnVmZmVyLT51c1BlcnNpc3RhbmNlID4gcHhSTFVCdWZmZXItPnVzUGVyc2lzdGFuY2UgKSApICkNCgkJCQl7DQoJCQkJCXB4UkxVQnVmZmVyID0gcHhCdWZmZXI7DQoJCQkJfQ0KCQkJfQ0KDQoJCQkvKiBBIGZyZWUgYnVmZmVyIHdpdGggdGhlIGhpZ2hlc3QgdmFsdWUgb2YgJ3VsTFJVJyB3YXMgZm91bmQ6ICovDQoJCQlpZiggcHhSTFVCdWZmZXIgIT0gTlVMTCApDQoJCQl7DQoJCQkJLyogUHJvY2VzcyB0aGUgc3VpdGFibGUgY2FuZGlkYXRlLiAqLw0KCQkJCWlmKCBweFJMVUJ1ZmZlci0+Yk1vZGlmaWVkID09IHBkVFJVRSApDQoJCQkJew0KCQkJCQkvKiBBbG9uZyB3aXRoIHRoZSBwZFRSVUUgcGFyYW1ldGVyIHRvIGluZGljYXRlIHNlbWFwaG9yZSBoYXMgYmVlbiBjbGFpbWVkIGFscmVhZHkuICovDQoJCQkJCWxSZXRWYWwgPSBGRl9CbG9ja1dyaXRlKCBweElPTWFuYWdlciwgcHhSTFVCdWZmZXItPnVsU2VjdG9yLCAxLCBweFJMVUJ1ZmZlci0+cHVjQnVmZmVyLCBwZFRSVUUgKTsNCgkJCQkJaWYoIGxSZXRWYWwgPCAwICkNCgkJCQkJew0KCQkJCQkJLyogTlVMTCB3aWxsIGJlIHJldHVybmVkIGJlY2F1c2UgJ3B4TWF0Y2hpbmdCdWZmZXInIGlzIHN0aWxsIE5VTEwuICovDQoJCQkJCQlicmVhazsNCgkJCQkJfQ0KCQkJCX0NCg0KCQkJCWlmKCB1Y01vZGUgPT0gRkZfTU9ERV9XUl9PTkxZICkNCgkJCQl7DQoJCQkJCW1lbXNldCggcHhSTFVCdWZmZXItPnB1Y0J1ZmZlciwgJ1wwJywgcHhJT01hbmFnZXItPnVzU2VjdG9yU2l6ZSApOw0KCQkJCX0NCgkJCQllbHNlDQoJCQkJew0KCQkJCQlsUmV0VmFsID0gRkZfQmxvY2tSZWFkKCBweElPTWFuYWdlciwgdWxTZWN0b3IsIDEsIHB4UkxVQnVmZmVyLT5wdWNCdWZmZXIsIHBkVFJVRSApOw0KCQkJCQlpZiggbFJldFZhbCA8IDAgKQ0KCQkJCQl7DQoJCQkJCQkvKiAncHhNYXRjaGluZ0J1ZmZlcicgaXMgTlVMTC4gKi8NCgkJCQkJCWJyZWFrOw0KCQkJCQl9DQoJCQkJfQ0KDQoJCQkJcHhSTFVCdWZmZXItPnVjTW9kZSA9ICggdWNNb2RlICYgRkZfTU9ERV9SRF9XUiApOw0KCQkJCXB4UkxVQnVmZmVyLT51c1BlcnNpc3RhbmNlID0gMTsNCgkJCQlweFJMVUJ1ZmZlci0+dWxMUlUgPSAwOw0KCQkJCXB4UkxVQnVmZmVyLT51c051bUhhbmRsZXMgPSAxOw0KCQkJCXB4UkxVQnVmZmVyLT51bFNlY3RvciA9IHVsU2VjdG9yOw0KDQoJCQkJcHhSTFVCdWZmZXItPmJNb2RpZmllZCA9ICggdWNNb2RlICYgRkZfTU9ERV9XUklURSApICE9IDA7DQoNCgkJCQlweFJMVUJ1ZmZlci0+YlZhbGlkID0gcGRUUlVFOw0KCQkJCXB4TWF0Y2hpbmdCdWZmZXIgPSBweFJMVUJ1ZmZlcjsNCgkJCQlicmVhazsNCgkJCX0gLyogaWYoIHB4UkxVQnVmZmVyICE9IE5VTEwgKSAqLw0KCQl9IC8qIGVsc2UgKCBweE1hdGNoaW5nQnVmZmVyID09IE5VTEwgKSAqLw0KDQoJCUZGX1JlbGVhc2VTZW1hcGhvcmUoIHB4SU9NYW5hZ2VyLT5wdlNlbWFwaG9yZSApOw0KDQoJCS8qIEJldHRlciB0byBnbyBhc2xlZXAgdG8gZ2l2ZSBsb3ctcHJpb3JpdHkgdGFzayBhIGNoYW5jZSB0byByZWxlYXNlIGJ1ZmZlcihzKS4gKi8NCgkJRkZfQnVmZmVyV2FpdCggcHhJT01hbmFnZXIsIEZGX0dFVEJVRkZFUl9TTEVFUF9USU1FX01TICk7DQoJfSAvKiB3aGlsZSggcHhNYXRjaGluZ0J1ZmZlciA9PSBOVUxMICkgKi8NCg0KCWlmKCB4TG9vcENvdW50ID4gMCApDQoJew0KCQkvKiBJZiB4TG9vcENvdW50IGlzIDAgaGVyZSwgdGhlIHNlbWFwaG9yZSB3YXMgbm90IHRha2VuLiAqLw0KCQlGRl9SZWxlYXNlU2VtYXBob3JlKCBweElPTWFuYWdlci0+cHZTZW1hcGhvcmUgKTsNCgl9DQoJaWYoIHB4TWF0Y2hpbmdCdWZmZXIgPT0gTlVMTCApDQoJew0KCQlGRl9QUklOVEYoICJGRl9HZXRCdWZmZXJbMHglWF06IGZhaWxlZCBtb2RlIDB4JVhcbiIsICggdW5zaWduZWQgKXVsU2VjdG9yLCAoIHVuc2lnbmVkICl1Y01vZGUgKTsNCgl9DQoJcmV0dXJuIHB4TWF0Y2hpbmdCdWZmZXI7CS8qIFJldHVybiB0aGUgTWF0Y2hlZCBCdWZmZXIhICovDQp9CS8qIEZGX0dldEJ1ZmZlcigpICovDQovKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8NCg0KLyoqDQogKglAcHJpdmF0ZQ0KICoJQGJyaWVmCVJlbGVhc2VzIGEgYnVmZmVyIHJlc291cmNlLg0KICoNCiAqCUBwYXJhbQlweElPTWFuYWdlcglQb2ludGVyIHRvIGFuIEZGX0lPTWFuYWdlcl90IG9iamVjdC4NCiAqCUBwYXJhbQlweEJ1ZmZlcglQb2ludGVyIHRvIGFuIEZGX0J1ZmZlcl90IG9iamVjdC4NCiAqDQogKiovDQpGRl9FcnJvcl90IEZGX1JlbGVhc2VCdWZmZXIoIEZGX0lPTWFuYWdlcl90ICpweElPTWFuYWdlciwgRkZfQnVmZmVyX3QgKnB4QnVmZmVyICkNCnsNCglGRl9FcnJvcl90IHhFcnJvciA9IEZGX0VSUl9OT05FOw0KDQoJLyogUHJvdGVjdCBkZXNjcmlwdGlvbiBjaGFuZ2VzIHdpdGggYSBzZW1hcGhvcmUuICovDQoJRkZfUGVuZFNlbWFwaG9yZSggcHhJT01hbmFnZXItPnB2U2VtYXBob3JlICk7DQoJew0KI2lmKCBmZmNvbmZpZ0NBQ0hFX1dSSVRFX1RIUk9VR0ggIT0gMCApDQoJCWlmKCBweEJ1ZmZlci0+Yk1vZGlmaWVkID09IHBkVFJVRSApDQoJCXsNCgkJCXhFcnJvciA9IEZGX0Jsb2NrV3JpdGUoIHB4SU9NYW5hZ2VyLCBweEJ1ZmZlci0+dWxTZWN0b3IsIDEsIHB4QnVmZmVyLT5wdWNCdWZmZXIsIHBkVFJVRSApOw0KCQkJaWYoIEZGX2lzRVJSKCB4RXJyb3IgKSA9PSBwZEZBTFNFICkNCgkJCXsNCgkJCQkvKiBFbnN1cmUgaWYgYW4gZXJyb3Igb2NjdXJzIGl0cyBzdGlsbCBwb3NzaWJsZSB0byB3cml0ZSB0aGUgYmxvY2sgYWdhaW4uICovDQoJCQkJcHhCdWZmZXItPmJNb2RpZmllZCA9IHBkRkFMU0U7DQoJCQl9DQoJCX0NCiNlbmRpZg0KCQljb25maWdBU1NFUlQoIHB4QnVmZmVyLT51c051bUhhbmRsZXMgIT0gMCApOw0KDQoJCWlmKCBweEJ1ZmZlci0+dXNOdW1IYW5kbGVzICE9IDAgKQ0KCQl7DQoJCQlweEJ1ZmZlci0+dXNOdW1IYW5kbGVzLS07DQoJCX0NCgkJZWxzZQ0KCQl7DQoJCQkvKnByaW50ZiAoIkZGX1JlbGVhc2VCdWZmZXI6IGJ1ZmZlciBub3QgY2xhaW1lZFxuIik7ICovDQoJCX0NCgl9DQoNCglGRl9SZWxlYXNlU2VtYXBob3JlKCBweElPTWFuYWdlci0+cHZTZW1hcGhvcmUgKTsNCg0KCS8qIE5vdGlmeSB0YXNrcyB3aGljaCBtYXkgYmUgd2FpdGluZyBpbiBGRl9HZXRCdWZmZXIoKSAqLw0KCUZGX0J1ZmZlclByb2NlZWQoIHB4SU9NYW5hZ2VyICk7DQoNCglyZXR1cm4geEVycm9yOw0KfQkvKiBGRl9SZWxlYXNlQnVmZmVyKCkgKi8NCi8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLw0KDQovKiBOZXcgSW50ZXJmYWNlIGZvciBGcmVlUlRPUytGQVQgdG8gcmVhZCBibG9ja3MuICovDQppbnQzMl90IEZGX0Jsb2NrUmVhZCggRkZfSU9NYW5hZ2VyX3QgKnB4SU9NYW5hZ2VyLCB1aW50MzJfdCB1bFNlY3RvckxCQSwgdWludDMyX3QgdWxOdW1TZWN0b3JzLCB2b2lkICpweEJ1ZmZlciwNCglCYXNlVHlwZV90IHhTZW1Mb2NrZWQgKQ0Kew0KaW50MzJfdCBzbFJldFZhbCA9IDA7DQoNCglpZiggcHhJT01hbmFnZXItPnhQYXJ0aXRpb24udWxUb3RhbFNlY3RvcnMgIT0gMHVsICkNCgl7DQoJCS8qIEF0IHNvbWUgcG9pbnQgd2hpbGUgZm9ybWF0dGluZyBhIHBhcnRpdGlvbiwgdWxUb3RhbFNlY3RvcnMgbWlnaHQgYmUgdW5rbm93bi4NCgkJSW4gdGhhdCBjYXNlIHRoaXMgdGVzdCB3aWxsIGJlIHNraXBwZWQuICovDQoJCWlmKCAoIHVsU2VjdG9yTEJBICsgdWxOdW1TZWN0b3JzICkgPiAoIHB4SU9NYW5hZ2VyLT54UGFydGl0aW9uLnVsVG90YWxTZWN0b3JzICsgcHhJT01hbmFnZXItPnhQYXJ0aXRpb24udWxCZWdpbkxCQSApICkNCgkJew0KCQkJc2xSZXRWYWwgPSBGRl9FUlJfSU9NQU5fT1VUX09GX0JPVU5EU19SRUFEIHwgRkZfQkxPQ0tSRUFEOw0KCQl9DQoJfQ0KDQoJaWYoICggc2xSZXRWYWwgPT0gMHVsICkgJiYgKCBweElPTWFuYWdlci0+eEJsa0RldmljZS5mbnBSZWFkQmxvY2tzICE9IE5VTEwgKSApDQoJew0KCQlkbw0KCQl7DQoJCQkvKiBNYWtlIHN1cmUgd2UgZG9uJ3QgZXhlY3V0ZSBhIE5VTEwuICovDQoJCQlpZiggKCB4U2VtTG9ja2VkID09IHBkRkFMU0UgKSAmJg0KCQkJCSggKCBweElPTWFuYWdlci0+dWNGbGFncyAmIEZGX0lPTUFOX0JMT0NLX0RFVklDRV9JU19SRUVOVFJBTlQgKSA9PSBwZEZBTFNFICkgKQ0KCQkJew0KCQkJCUZGX1BlbmRTZW1hcGhvcmUoIHB4SU9NYW5hZ2VyLT5wdlNlbWFwaG9yZSApOw0KCQkJfQ0KDQoJCQlzbFJldFZhbCA9IHB4SU9NYW5hZ2VyLT54QmxrRGV2aWNlLmZucFJlYWRCbG9ja3MoIHB4QnVmZmVyLCB1bFNlY3RvckxCQSwgdWxOdW1TZWN0b3JzLCBweElPTWFuYWdlci0+eEJsa0RldmljZS5weERpc2sgKTsNCg0KCQkJaWYoICggeFNlbUxvY2tlZCA9PSBwZEZBTFNFICkgJiYNCgkJCQkoICggcHhJT01hbmFnZXItPnVjRmxhZ3MgJiBGRl9JT01BTl9CTE9DS19ERVZJQ0VfSVNfUkVFTlRSQU5UICkgPT0gcGRGQUxTRSApICkNCgkJCXsNCgkJCQlGRl9SZWxlYXNlU2VtYXBob3JlKCBweElPTWFuYWdlci0+cHZTZW1hcGhvcmUgKTsNCgkJCX0NCg0KCQkJaWYoIEZGX0dFVEVSUk9SKCBzbFJldFZhbCApICE9IEZGX0VSUl9EUklWRVJfQlVTWSApDQoJCQl7DQoJCQkJYnJlYWs7DQoJCQl9DQoNCgkJCUZGX1NsZWVwKCBmZmNvbmZpZ0RSSVZFUl9CVVNZX1NMRUVQX01TICk7DQoJCX0gd2hpbGUoIHBkVFJVRSApOw0KCX0NCg0KCXJldHVybiBzbFJldFZhbDsNCn0JLyogRkZfQmxvY2tSZWFkKCkgKi8NCi8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLw0KDQppbnQzMl90IEZGX0Jsb2NrV3JpdGUoIEZGX0lPTWFuYWdlcl90ICpweElPTWFuYWdlciwgdWludDMyX3QgdWxTZWN0b3JMQkEsIHVpbnQzMl90IHVsTnVtU2VjdG9ycywgdm9pZCAqcHhCdWZmZXIsDQoJQmFzZVR5cGVfdCB4U2VtTG9ja2VkICkNCnsNCmludDMyX3Qgc2xSZXRWYWwgPSAwOw0KDQoJaWYoIHB4SU9NYW5hZ2VyLT54UGFydGl0aW9uLnVsVG90YWxTZWN0b3JzICE9IDAgKQ0KCXsNCgkJLyogQXQgc29tZSBwb2ludCB3aGlsZSBmb3JtYXR0aW5nIGEgcGFydGl0aW9uLCB1bFRvdGFsU2VjdG9ycyBtaWdodCBiZSB1bmtub3duLg0KCQlJbiB0aGF0IGNhc2UgdGhpcyB0ZXN0IHdpbGwgYmUgc2tpcHBlZC4gKi8NCgkJaWYoICggdWxTZWN0b3JMQkEgKyB1bE51bVNlY3RvcnMgKSA+ICggcHhJT01hbmFnZXItPnhQYXJ0aXRpb24udWxUb3RhbFNlY3RvcnMgKyBweElPTWFuYWdlci0+eFBhcnRpdGlvbi51bEJlZ2luTEJBICkgKQ0KCQl7DQoJCQlzbFJldFZhbCA9IEZGX0VSUl9JT01BTl9PVVRfT0ZfQk9VTkRTX1dSSVRFIHwgRkZfQkxPQ0tXUklURTsNCgkJfQ0KCX0NCg0KCWlmKCAoIHNsUmV0VmFsID09IDB1bCApICYmICggcHhJT01hbmFnZXItPnhCbGtEZXZpY2UuZm5wV3JpdGVCbG9ja3MgIT0gTlVMTCApICkNCgl7DQoJCWRvDQoJCXsJLyogTWFrZSBzdXJlIHdlIGRvbid0IGV4ZWN1dGUgYSBOVUxMLiAqLw0KDQoJCQlpZiggKCB4U2VtTG9ja2VkID09IHBkRkFMU0UgKSAmJg0KCQkJCSggKCBweElPTWFuYWdlci0+dWNGbGFncyAmIEZGX0lPTUFOX0JMT0NLX0RFVklDRV9JU19SRUVOVFJBTlQgKSA9PSBwZEZBTFNFICkgKQ0KCQkJew0KCQkJCUZGX1BlbmRTZW1hcGhvcmUoIHB4SU9NYW5hZ2VyLT5wdlNlbWFwaG9yZSApOw0KCQkJfQ0KDQoJCQlzbFJldFZhbCA9IHB4SU9NYW5hZ2VyLT54QmxrRGV2aWNlLmZucFdyaXRlQmxvY2tzKCBweEJ1ZmZlciwgdWxTZWN0b3JMQkEsIHVsTnVtU2VjdG9ycywgcHhJT01hbmFnZXItPnhCbGtEZXZpY2UucHhEaXNrICk7DQoNCgkJCWlmKCAoIHhTZW1Mb2NrZWQgPT0gcGRGQUxTRSApICYmDQoJCQkJKCAoIHB4SU9NYW5hZ2VyLT51Y0ZsYWdzICYgRkZfSU9NQU5fQkxPQ0tfREVWSUNFX0lTX1JFRU5UUkFOVCApID09IHBkRkFMU0UgKSApDQoJCQl7DQoJCQkJRkZfUmVsZWFzZVNlbWFwaG9yZSggcHhJT01hbmFnZXItPnB2U2VtYXBob3JlICk7DQoJCQl9DQoNCgkJCWlmKCBGRl9HRVRFUlJPUiggc2xSZXRWYWwgKSAhPSBGRl9FUlJfRFJJVkVSX0JVU1kgKQ0KCQkJew0KCQkJCWJyZWFrOw0KCQkJfQ0KDQoJCQlGRl9TbGVlcCggZmZjb25maWdEUklWRVJfQlVTWV9TTEVFUF9NUyApOw0KCQl9IHdoaWxlKCBwZFRSVUUgKTsNCgl9DQoNCglyZXR1cm4gc2xSZXRWYWw7DQp9CS8qIEZGX0Jsb2NrV3JpdGUoKSAqLw0KLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovDQoNCi8qDQogKiBUaGlzIGdsb2JhbCB2YXJpYWJsZSBpcyBhIGtpbmQgb2YgZXhwZXJ0IG9wdGlvbjoNCiAqIEl0IG1heSBiZSBzZXQgdG8gb25lIG9mIHRoZXNlIHZhbHVlczogRkZfVF9GQVRbMTIsMTYsMzJdDQogKiBqdXN0IHRvIGZvcmNlIHRoZSBkcml2ZXIgdG8gYXNzdW1lIGEgY2VydGFpbiBGQVQgdHlwZS4NCiAqLw0KdWludDhfdCB1Y0Fzc3VtZUZBVFR5cGU7DQoNCi8qIFRoZSBoaXN0b3J5IG9mIEZBVCB0eXBlczoNCiAqIFRoZSBNaWNyb3NvZnQgZG9jdW1lbnRzIHNheXMgdGhhdCB0aGUgYWN0dWFsIHR5cGU6IEZBVC0xMiwgRkFULTE2IGFuZCBGQVQtMzINCiAqIG9mIGEgcGFydGl0aW9uIGNhbiBiZSBmb3VuZCBieSBsb29raW5nIGF0IHRoZSB0b3RhbCBudW1iZXIgb2YgZGF0YSBjbHVzdGVyczoNCiAqDQogKiBpZiggY2x1c3RlcnMgPCA0MDg1ICkNCiAqICAgICBBc3N1bWUgRkFULTEyDQogKiBlbHNlIGlmKCBjbHVzdGVycyA8IDY1NTI1ICkNCiAqICAgICBBc3N1bWUgRkFULTE2DQogKiBlbHNlDQogKiAgICAgQXNzdW1lIEZBVC0zMg0KICoNCiAqIEluIHByYWN0aWNlIGhvd2V2ZXIsIHRoaXMgZG9lcyBub3QgYWx3YXlzIHNlZW0gdG8gYmUgYSBjb3JyZWN0IGFzc3VtcHRpb24uDQogKg0KICogVGhlIGZpcnN0IDEyIG9yIDE2IGJpdHMgaW4gdGhlIEZBVCB0YWJsZSBtYXkgYWxzbyBoZWxwIHRvIGRldGVybWluZSB0aGUNCiAqIGNvcnJlY3QgRkFULXR5cGU6DQogKg0KICogICAgRkFULTEyOiAoIGZpcnN0V29yZCAmIDB4M0ZGICkgPT0gMHgzRjggKQ0KICogICAgRkFULTE2OiAoIGZpcnN0V29yZCA9PSAweEZGRjggKQ0KICovDQoNCnN0YXRpYyBGRl9FcnJvcl90IHBydkRldGVybWluZUZhdFR5cGUoIEZGX0lPTWFuYWdlcl90ICpweElPTWFuYWdlciApDQp7DQpGRl9QYXJ0aXRpb25fdCAqcHhQYXJ0aXRpb247DQpGRl9CdWZmZXJfdCAqcHhCdWZmZXI7DQp1aW50MzJfdCB1bEZpcnN0V29yZCA9IDB1bDsNCkZGX0Vycm9yX3QgeEVycm9yID0gRkZfRVJSX05PTkU7DQoNCglweFBhcnRpdGlvbiA9ICYoIHB4SU9NYW5hZ2VyLT54UGFydGl0aW9uICk7DQoJaWYoIHVjQXNzdW1lRkFUVHlwZSAhPSAwICkNCgl7DQoJCXN3aXRjaCggdWNBc3N1bWVGQVRUeXBlICkNCgkJew0KCQljYXNlIEZGX1RfRkFUMTI6DQoJCWNhc2UgRkZfVF9GQVQxNjoNCgkJY2FzZSBGRl9UX0ZBVDMyOg0KCQkJcHhQYXJ0aXRpb24tPnVjVHlwZSA9IHVjQXNzdW1lRkFUVHlwZTsNCgkJCWJyZWFrOw0KCQlkZWZhdWx0Og0KCQkJLyogQW4gaW52YWxpZCB2YWx1ZSB3aWxsIGJlIGlnbm9yZWQsIGFuZCB0aGUgRkFUIHR5cGUgaXMgZGV0ZXJtaW5lZCBkeW5hbWljYWxseS4gKi8NCgkJCXVjQXNzdW1lRkFUVHlwZSA9IDA7DQoJCQlicmVhazsNCgkJfQ0KCQl4RXJyb3IgPSBGRl9FUlJfTk9ORTsNCgl9DQoNCgkvKiBUZXN0IGFnYWluLCB0aGUgdmFsdWUgbWF5IGhhdmUgYmVjb21lIHplcm8gbm93OiAqLw0KCWlmKCB1Y0Fzc3VtZUZBVFR5cGUgPT0gMCApDQoJew0KCQlweEJ1ZmZlciA9IEZGX0dldEJ1ZmZlciggcHhJT01hbmFnZXIsIHB4SU9NYW5hZ2VyLT54UGFydGl0aW9uLnVsRkFUQmVnaW5MQkEsIEZGX01PREVfUkVBRCApOw0KCQlpZiggcHhCdWZmZXIgPT0gTlVMTCApDQoJCXsNCgkJCXhFcnJvciA9IEZGX0VSUl9ERVZJQ0VfRFJJVkVSX0ZBSUxFRCB8IEZGX0RFVEVSTUlORUZBVFRZUEU7DQoJCX0NCgkJZWxzZQ0KCQl7DQoJCQl1bEZpcnN0V29yZCA9ICggdWludDMyX3QgKSBGRl9nZXRTaG9ydCggcHhCdWZmZXItPnB1Y0J1ZmZlciwgMHgwMDAwICk7DQoJCQl4RXJyb3IgPSBGRl9SZWxlYXNlQnVmZmVyKCBweElPTWFuYWdlciwgcHhCdWZmZXIgKTsNCgkJfQ0KCX0NCg0KCWlmKCAoIHVjQXNzdW1lRkFUVHlwZSA9PSAwICkgJiYgKCBGRl9pc0VSUiggeEVycm9yICkgPT0gcGRGQUxTRSApICkNCgl7DQoJI2lmKCBmZmNvbmZpZ0ZBVDEyX1NVUFBPUlQgIT0gMCApDQoJCWlmKCBweFBhcnRpdGlvbi0+dWxOdW1DbHVzdGVycyA8IEZBVDE2X1NFQ1RPUl9DT1VOVF80MDg1ICkNCgkJew0KCQkJLyogRkFUMTIgKi8NCgkJCXB4UGFydGl0aW9uLT51Y1R5cGUgPSBGRl9UX0ZBVDEyOw0KCQkJI2lmKCBmZmNvbmZpZ0ZBVF9DSEVDSyAhPSAwICkNCgkJCWlmKCAoIHVsRmlyc3RXb3JkICYgMHgzRkYgKSAhPSAweDNGOCApDQoJCQl7DQoJCQkJeEVycm9yID0gRkZfRVJSX0lPTUFOX05PVF9GQVRfRk9STUFUVEVEIHwgRkZfREVURVJNSU5FRkFUVFlQRTsNCgkJCX0NCgkJCWVsc2UNCgkJCSNlbmRpZiAvKiBmZmNvbmZpZ0ZBVF9DSEVDSyAqLw0KCQkJew0KCQkJCXhFcnJvciA9IEZGX0VSUl9OT05FOw0KCQkJfQ0KCQl9DQoJCWVsc2UNCgkjZW5kaWYgLyogZmZjb25maWdGQVQxMl9TVVBQT1JUICovDQoNCgkJaWYoIHB4UGFydGl0aW9uLT51bE51bUNsdXN0ZXJzIDwgRkFUMzJfU0VDVE9SX0NPVU5UXzY1NTI1ICkNCgkJew0KCQkJLyogRkFUIDE2ICovDQoJCQlweFBhcnRpdGlvbi0+dWNUeXBlID0gRkZfVF9GQVQxNjsNCgkJCSNpZiggZmZjb25maWdGQVRfQ0hFQ0sgIT0gMCApDQoJCQl7DQoJCQkJaWYoIHVsRmlyc3RXb3JkID09IDB4RkZGOCApDQoJCQkJew0KCQkJCQl4RXJyb3IgPSBGRl9FUlJfTk9ORTsNCgkJCQl9DQoJCQkJZWxzZSB7DQoJCQkJCWlmKCAoIHVsRmlyc3RXb3JkICYgMHgzRkYgKSAhPSAweDNGOCApDQoJCQkJCXsNCgkJCQkJCUZGX1BSSU5URiggIlBhcnQgYXQgJWx1IGlzIHByb2JhYmx5IGEgRkFUMTJcbiIsIHB4SU9NYW5hZ2VyLT54UGFydGl0aW9uLnVsRkFUQmVnaW5MQkEgKTsNCgkJCQkJfQ0KCQkJCQllbHNlDQoJCQkJCXsNCgkJCQkJCUZGX1BSSU5URiggIlBhcnRpdGlvbiBhdCAlbHUgaGFzIHN0cmFuZ2UgRkFUIGRhdGEgJTA4bFhcbiIsDQoJCQkJCQkJcHhJT01hbmFnZXItPnhQYXJ0aXRpb24udWxGQVRCZWdpbkxCQSwgdWxGaXJzdFdvcmQgKTsNCgkJCQkJfQ0KCQkJCQl4RXJyb3IgPSBGRl9FUlJfSU9NQU5fSU5WQUxJRF9GT1JNQVQgfCBGRl9ERVRFUk1JTkVGQVRUWVBFOw0KCQkJCX0NCgkJCX0NCgkJCSNlbmRpZiAvKiBmZmNvbmZpZ0ZBVF9DSEVDSyAqLw0KCQl9DQoJCWVsc2UNCgkJew0KCQkJLyogRkFUIDMyISAqLw0KCQkJcHhQYXJ0aXRpb24tPnVjVHlwZSA9IEZGX1RfRkFUMzI7DQoJI2lmKCBmZmNvbmZpZ0ZBVF9DSEVDSyAhPSAwICkNCgkJCWlmKCAoICggdWxGaXJzdFdvcmQgJiAweDBGRkZGRkY4ICkgIT0gMHgwRkZGRkZGOCApICYmDQoJCQkJKCAoIHVsRmlyc3RXb3JkICYgMHgwRkZGRkZGOCApICE9IDB4MEZGRkZGRjAgKSApDQoJCQl7DQoJCQkJLyogX0hUXw0KCQkJCUkgaGFkIGFuIFNELWNhcmQgd2hpY2ggd29ya2VkIHdlbGwgaW4gTGludXgvVzMyDQoJCQkJYnV0IEZyZWVSVE9TK0ZBVCByZXR1cm5lZCBtZSB0aGlzIGVycm9yDQoJCQkJU28gZm9yIG1lIEkgbGVmdCBvdXQgdGhpcyBjaGVjayAoanVzdCBpc3N1ZSBhIHdhcm5pbmcgZm9yIG5vdykNCgkJCQkqLw0KCQkJCUZGX1BSSU5URiggInBydkRldGVybWluZUZhdFR5cGU6IGZpcnN0V29yZCAlMDhsWFxuIiwgdWxGaXJzdFdvcmQgKTsNCgkJCQl4RXJyb3IgPSBGRl9FUlJfTk9ORTsgLyogRkZfRVJSX0lPTUFOX05PVF9GQVRfRk9STUFUVEVEOyAqLw0KCQkJfQ0KDQoJI2VuZGlmCS8qIGZmY29uZmlnRkFUX0NIRUNLICovDQoJCQl4RXJyb3IgPSBGRl9FUlJfTk9ORTsNCgkJfQ0KCX0NCg0KCXJldHVybiB4RXJyb3I7DQp9CS8qIHBydkRldGVybWluZUZhdFR5cGUoKSAqLw0KLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovDQoNCi8qIENoZWNrIGlmIHVjUGFydGl0aW9uSUQgaW50cm9kdWNlcyBhbiBleHRlbmRlZCBwYXJ0aXRpb24uICovDQpzdGF0aWMgQmFzZVR5cGVfdCBwcnZJc0V4dGVuZGVkUGFydGl0aW9uKCB1aW50OF90IHVjUGFydGl0aW9uSUQgKQ0Kew0KQmFzZVR5cGVfdCB4UmVzdWx0Ow0KDQoJaWYoICggdWNQYXJ0aXRpb25JRCA9PSBGRl9ET1NfRVhUX1BBUlQgKSB8fA0KCQkoIHVjUGFydGl0aW9uSUQgPT0gRkZfV0lOOThfRVhUX1BBUlQgKSB8fA0KCQkoIHVjUGFydGl0aW9uSUQgPT0gRkZfTElOVVhfRVhUX1BBUlQgKSApDQoJew0KCQl4UmVzdWx0ID0gcGRUUlVFOw0KCX0NCgllbHNlDQoJew0KCQl4UmVzdWx0ID0gcGRGQUxTRTsNCgl9DQoNCglyZXR1cm4geFJlc3VsdDsNCn0JLyogcHJ2SXNFeHRlbmRlZFBhcnRpdGlvbigpICovDQovKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8NCg0KLyogQ2hlY2sgaWYgdGhlIG1lZGlhIGJ5dGUgaW4gYW4gTUJSIGlzIHZhbGlkICovDQpzdGF0aWMgQmFzZVR5cGVfdCBwcnZJc1ZhbGlkTWVkaWEoIHVpbnQ4X3QgbWVkaWEgKQ0Kew0KQmFzZVR5cGVfdCB4UmVzdWx0Ow0KCS8qDQoJICogMHhGOCBpcyB0aGUgc3RhbmRhcmQgdmFsdWUgZm9yIJNmaXhlZJQgKG5vbi1yZW1vdmFibGUpIG1lZGlhLiBGb3INCgkgKiByZW1vdmFibGUgbWVkaWEsIDB4RjAgaXMgZnJlcXVlbnRseSB1c2VkLiBUaGUgbGVnYWwgdmFsdWVzIGZvciB0aGlzDQoJICogZmllbGQgYXJlIDB4RjAsIDB4RjgsIDB4RjksIDB4RkEsIDB4RkIsIDB4RkMsIDB4RkQsIDB4RkUsIGFuZA0KCSAqIDB4RkYuIFRoZSBvbmx5IG90aGVyIGltcG9ydGFudCBwb2ludCBpcyB0aGF0IHdoYXRldmVyIHZhbHVlIGlzIHB1dA0KCSAqIGluIGhlcmUgbXVzdCBhbHNvIGJlIHB1dCBpbiB0aGUgbG93IGJ5dGUgb2YgdGhlIEZBVFswXSBlbnRyeS4gVGhpcw0KCSAqIGRhdGVzIGJhY2sgdG8gdGhlIG9sZCBNUy1ET1MgMS54IG1lZGlhIGRldGVybWluYXRpb24gbm90ZWQNCgkgKiBlYXJsaWVyIGFuZCBpcyBubyBsb25nZXIgdXN1YWxseSB1c2VkIGZvciBhbnl0aGluZy4NCgkgKi8NCglpZiggKCAweGY4IDw9IG1lZGlhICkgfHwgKCBtZWRpYSA9PSAweGYwICkgKQ0KCXsNCgkJeFJlc3VsdCA9IHBkVFJVRTsNCgl9DQoJZWxzZQ0KCXsNCgkJeFJlc3VsdCA9IHBkRkFMU0U7DQoJfQ0KDQoJcmV0dXJuIHhSZXN1bHQ7DQp9CS8qIHBydklzVmFsaWRNZWRpYSgpICovDQovKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8NCg0Kdm9pZCBGRl9SZWFkUGFydHMoIHVpbnQ4X3QgKnB1Y0J1ZmZlciwgRkZfUGFydF90ICpweFBhcnRzICkNCnsNCkJhc2VUeXBlX3QgeFBhcnROcjsNClVCYXNlVHlwZV90IHV4T2Zmc2V0ID0gRkZfRkFUX1BUQkw7DQoNCgkvKiBweFBhcnRzIGlzIGV4cGVjdGVkIHRvIGJlIGRlY2xhcmVkIGFzIGFuIGFycmF5IG9mIDQgZWxlbWVudHM6DQoJCUZGX1BhcnRfdCBweFBhcnRzWzRdOw0KCQlGRl9SZWFkUGFydHMoIHB4QnVmZmVyLT5wdWNCdWZmZXIsIHB4UGFydHMgKTsNCgkqLw0KCWZvciggeFBhcnROciA9IDA7IHhQYXJ0TnIgPCA0OyB4UGFydE5yKyssIHV4T2Zmc2V0ICs9IDE2LCBweFBhcnRzKysgKQ0KCXsNCgkJcHhQYXJ0cy0+dWNBY3RpdmUgPSBGRl9nZXRDaGFyKCBwdWNCdWZmZXIsIHV4T2Zmc2V0ICsgRkZfRkFUX1BUQkxfQUNUSVZFICk7DQoJCXB4UGFydHMtPnVjUGFydGl0aW9uSUQgPSBGRl9nZXRDaGFyKCBwdWNCdWZmZXIsIHV4T2Zmc2V0ICsgRkZfRkFUX1BUQkxfSUQgKTsNCgkJcHhQYXJ0cy0+dWxTZWN0b3JDb3VudCA9IEZGX2dldExvbmcoIHB1Y0J1ZmZlciwgdXhPZmZzZXQgKyBGRl9GQVRfUFRCTF9TRUNUX0NPVU5UICk7DQoJCXB4UGFydHMtPnVsU3RhcnRMQkEgPSBGRl9nZXRMb25nKCBwdWNCdWZmZXIsIHV4T2Zmc2V0ICsgRkZfRkFUX1BUQkxfTEJBICk7DQoJfQ0KfQ0KLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovDQoNCi8qICBUaGlzIGZ1bmN0aW9uIHdpbGwgdHJhdmVyc2UgdGhyb3VnaCBhIGNoYWluIG9mIGV4dGVuZGVkIHBhcnRpdGlvbnMuICovDQoNCi8qIEl0IGlzIHByb3RlY3RlZCBhZ2FpbnN0IHJ1YmJpc2ggZGF0YSBieSBhIGNvdW50ZXIuICovDQpzdGF0aWMgRkZfRXJyb3JfdCBGRl9QYXJzZUV4dGVuZGVkKCBGRl9JT01hbmFnZXJfdCAqcHhJT01hbmFnZXIsIHVpbnQzMl90IHVsRmlyc3RTZWN0b3IsIHVpbnQzMl90IHVsRmlyc3RTaXplLA0KCUZGX1NQYXJ0Rm91bmRfdCAqcFBhcnRzRm91bmQgKQ0Kew0KdWludDMyX3QgdWxUaGlzU2VjdG9yLCB1bFRoaXNTaXplOw0KdWludDMyX3QgdWxTZWN0b3JTaXplID0gcHhJT01hbmFnZXItPnVzU2VjdG9yU2l6ZSAvIDUxMjsNCnVpbnQzMl90IHByZXZUb3RhbFNlY3RvcnMgPSBweElPTWFuYWdlci0+eFBhcnRpdGlvbi51bFRvdGFsU2VjdG9yczsNCkZGX0J1ZmZlcl90ICpweEJ1ZmZlciA9IE5VTEw7DQpCYXNlVHlwZV90IHhUcnlDb3VudCA9IDEwMDsNCkJhc2VUeXBlX3QgeFBhcnROcjsNCkJhc2VUeXBlX3QgeEV4dGVuZGVkUGFydE5yOw0KRkZfRXJyb3JfdCB4RXJyb3IgPSBGRl9FUlJfTk9ORTsNCkZGX1BhcnRfdCBweFBhcnRpdGlvbnNbIDQgXTsNCg0KCXVsVGhpc1NlY3RvciA9IHVsRmlyc3RTZWN0b3I7DQoJdWxUaGlzU2l6ZSA9IHVsRmlyc3RTaXplOw0KDQoJLyogRGlzYWJsZSBzZWN0b3IgY2hlY2tpbmcgaW4gRkZfQmxvY2tSZWFkLCBiZWNhdXNlIHRoZQ0KCWV4YWN0IGRpc2sgKHBhcnRpdGlvbikgcGFyYW1ldGVycyBhcmUgbm90IHlldCBrbm93bi4NCglMZXQgdXNlciBkcml2ZXIgcmV0dXJuIGFuIGVycm9yIGlzIGFwcHJvcHJpYXRlLiAqLw0KCXB4SU9NYW5hZ2VyLT54UGFydGl0aW9uLnVsVG90YWxTZWN0b3JzID0gMDsNCg0KCXdoaWxlKCB4VHJ5Q291bnQtLSApDQoJew0KCQlpZiggKCBweEJ1ZmZlciA9PSBOVUxMICkgfHwgKCBweEJ1ZmZlci0+dWxTZWN0b3IgIT0gdWxUaGlzU2VjdG9yICkgKQ0KCQl7DQoJCQkvKiBNb3ZpbmcgdG8gYSBkaWZmZXJlbnQgc2VjdG9yLiBSZWxlYXNlIHRoZQ0KCQkJcHJldmlvdXMgb25lIGFuZCBhbGxvY2F0ZSBhIG5ldyBidWZmZXIuICovDQoJCQlpZiggcHhCdWZmZXIgIT0gTlVMTCApDQoJCQl7DQoJCQkJeEVycm9yID0gRkZfUmVsZWFzZUJ1ZmZlciggcHhJT01hbmFnZXIsIHB4QnVmZmVyICk7DQoJCQkJcHhCdWZmZXIgPSBOVUxMOw0KCQkJCWlmKCBGRl9pc0VSUiggeEVycm9yICkgKQ0KCQkJCXsNCgkJCQkJYnJlYWs7DQoJCQkJfQ0KCQkJfQ0KCQkJRkZfUFJJTlRGKCAiRkZfUGFyc2VFeHRlbmRlZDogUmVhZCBzZWN0b3IgJXVcbiIsICggdW5zaWduZWQpIHVsVGhpc1NlY3RvciApOw0KCQkJcHhCdWZmZXIgPSBGRl9HZXRCdWZmZXIoIHB4SU9NYW5hZ2VyLCB1bFRoaXNTZWN0b3IsIEZGX01PREVfUkVBRCApOw0KCQkJaWYoIHB4QnVmZmVyID09IE5VTEwgKQ0KCQkJew0KCQkJCXhFcnJvciA9IEZGX1BBUlNFRVhURU5ERUQgfCBGRl9FUlJfREVWSUNFX0RSSVZFUl9GQUlMRUQ7IC8qIHwgRlVOQ1RJT04uLi47ICovDQoJCQkJYnJlYWs7DQoJCQl9DQoJCX0NCg0KCQl7DQoJCXVpbnQ4X3QgYSA9IEZGX2dldENoYXIoIHB4QnVmZmVyLT5wdWNCdWZmZXIsIEZGX0ZBVF9NQlJfU0lHTkFUVVJFICsgMCApOw0KCQl1aW50OF90IGIgPSBGRl9nZXRDaGFyKCBweEJ1ZmZlci0+cHVjQnVmZmVyLCBGRl9GQVRfTUJSX1NJR05BVFVSRSArIDEgKTsNCg0KCQkJaWYoICggYSAhPSAweDU1ICkgfHwgKCBiICE9IDB4QUEgKSApDQoJCQl7DQoJCQkJRkZfUFJJTlRGKCAiRkZfUGFyc2VFeHRlbmRlZDogTm8gc2lnbmF0dXJlICUwMlgsJTAyWFxuIiwgYSwgYiApOw0KCQkJCWJyZWFrOw0KCQkJfQ0KCQl9DQoNCgkJLyogQ2hlY2sgZm9yIGRhdGEgcGFydGl0aW9uKHMpLA0KCQlhbmQgcmVtZW1iZXIgaWYgdGhlcmUgaXMgYW4gZXh0ZW5kZWQgcGFydGl0aW9uICovDQoNCgkJRkZfUmVhZFBhcnRzKCBweEJ1ZmZlci0+cHVjQnVmZmVyLCBweFBhcnRpdGlvbnMgKTsNCg0KCQkvKiBBc3N1bWUgdGhlcmUgaXMgbm8gbmV4dCBleHQgcGFydGl0aW9uLiAqLw0KCQl4RXh0ZW5kZWRQYXJ0TnIgPSAtMTsNCg0KCQlmb3IoIHhQYXJ0TnIgPSAwOyB4UGFydE5yIDwgNDsgeFBhcnROcisrICkNCgkJew0KCQl1aW50MzJfdCB1bE9mZnNldCwgdWxTaXplLCB1bE5leHQ7DQoJCQlpZiggcHhQYXJ0aXRpb25zWyB4UGFydE5yIF0udWxTZWN0b3JDb3VudCA9PSAwICkNCgkJCXsNCgkJCQkvKiBQYXJ0aXRpb24gaXMgZW1wdHkgKi8NCgkJCQljb250aW51ZTsNCgkJCX0NCg0KCQkJaWYoIHBydklzRXh0ZW5kZWRQYXJ0aXRpb24oIHB4UGFydGl0aW9uc1sgeFBhcnROciBdLnVjUGFydGl0aW9uSUQgKSApDQoJCQl7DQoJCQkJaWYoIHhFeHRlbmRlZFBhcnROciA8IDAgKQ0KCQkJCXsNCgkJCQkJeEV4dGVuZGVkUGFydE5yID0geFBhcnROcjsNCgkJCQl9DQoNCgkJCQljb250aW51ZTsJLyogV2UnbGwgZXhhbWluZSB0aGlzIGV4dCBwYXJ0aXRpb24gbGF0ZXIgKi8NCgkJCX0NCg0KCQkJLyogU29tZSBzYW5pdHkgY2hlY2tzICovDQoJCQl1bE9mZnNldCA9IHB4UGFydGl0aW9uc1sgeFBhcnROciBdLnVsU3RhcnRMQkEgKiB1bFNlY3RvclNpemU7DQoJCQl1bFNpemUgPSBweFBhcnRpdGlvbnNbIHhQYXJ0TnIgXS51bFNlY3RvckNvdW50ICogdWxTZWN0b3JTaXplOw0KCQkJdWxOZXh0ID0gdWxUaGlzU2VjdG9yICsgdWxPZmZzZXQ7DQoJCQlpZigNCgkJCQkvKiBJcyBpdCBvdmVyc2l6ZWQ/ICovDQoJCQkJKCB1bE9mZnNldCArIHVsU2l6ZSA+IHVsVGhpc1NpemUgKSB8fA0KCQkJCS8qIG9yIGdvaW5nIGJhY2t3YXJkPyAqLw0KCQkJCSggdWxOZXh0IDwgdWxGaXJzdFNlY3RvciApIHx8DQoJCQkJLyogT3Igb3V0c2l6ZSB0aGUgbG9naWNhbCBwYXJ0aXRpb24/ICovDQoJCQkJKCB1bE5leHQgPiB1bEZpcnN0U2VjdG9yICsgdWxGaXJzdFNpemUgKQ0KCQkJCSkNCgkJCXsNCgkJCQlGRl9QUklOVEYoICJQYXJ0ICVkIGxvb2tzIGluc2FuZTogdWxUaGlzU2VjdG9yICV1IHVsT2Zmc2V0ICV1IHVsTmV4dCAldVxuIiwNCgkJCQkJKCBpbnQgKSB4UGFydE5yLCAoIHVuc2lnbmVkICl1bFRoaXNTZWN0b3IsICggdW5zaWduZWQgKXVsT2Zmc2V0LCAoIHVuc2lnbmVkICl1bE5leHQgKTsNCgkJCQljb250aW51ZTsNCgkJCX0NCg0KCQkJew0KCQkJCS8qIFN0b3JlIHRoaXMgcGFydGl0aW9uIGZvciB0aGUgY2FsbGVyICovDQoJCQkJRkZfUGFydF90ICpwID0gJnBQYXJ0c0ZvdW5kLT5weFBhcnRpdGlvbnNbIHBQYXJ0c0ZvdW5kLT5pQ291bnQrKyBdOw0KDQoJCQkJLyogQ29weSB0aGUgd2hvbGUgc3RydWN0dXJlICovDQoJCQkJbWVtY3B5KCBwLCBweFBhcnRpdGlvbnMgKyB4UGFydE5yLCBzaXplb2YoICpwICkgKTsNCg0KCQkJCS8qIGFuZCBtYWtlIExCQSBhYnNvbHV0ZSB0byBzZWN0b3ItMC4gKi8NCgkJCQlwLT51bFN0YXJ0TEJBICs9IHVsVGhpc1NlY3RvcjsNCgkJCQlwLT5iSXNFeHRlbmRlZCA9IHBkVFJVRTsNCgkJCX0NCg0KCQkJaWYoIHBQYXJ0c0ZvdW5kLT5pQ291bnQgPj0gZmZjb25maWdNQVhfUEFSVElUSU9OUyApDQoJCQl7DQoJCQkJYnJlYWs7DQoJCQl9DQoNCgkJCXhUcnlDb3VudCA9IDEwMDsNCgkJfQkvKiBmb3IoIHhQYXJ0TnIgPSAwOyB4UGFydE5yIDwgNDsgeFBhcnROcisrICkgKi8NCg0KCQlpZiggeEV4dGVuZGVkUGFydE5yIDwgMCApDQoJCXsNCgkJCUZGX1BSSU5URiggIk5vIG1vcmUgZXh0ZW5kZWQgcGFydGl0aW9uc1xuIiApOw0KCQkJYnJlYWs7CQkvKiBub3RoaW5nIGxlZnQgdG8gZG8gKi8NCgkJfQ0KDQoJCS8qIEV4YW1pbmUgdGhlIHVsTmV4dCBleHRlbmRlZCBwYXJ0aXRpb24gKi8NCgkJdWxUaGlzU2VjdG9yID0gdWxGaXJzdFNlY3RvciArIHB4UGFydGl0aW9uc1sgeEV4dGVuZGVkUGFydE5yIF0udWxTdGFydExCQSAqIHVsU2VjdG9yU2l6ZTsNCgkJdWxUaGlzU2l6ZSA9IHB4UGFydGl0aW9uc1sgeEV4dGVuZGVkUGFydE5yIF0udWxTZWN0b3JDb3VudCAqIHVsU2VjdG9yU2l6ZTsNCgl9DQoNCglpZiggcHhCdWZmZXIgIT0gTlVMTCApDQoJew0KCQlGRl9FcnJvcl90IHhUZW1wRXJyb3IgPSBGRl9SZWxlYXNlQnVmZmVyKCBweElPTWFuYWdlciwgcHhCdWZmZXIgKTsNCgkJaWYoIEZGX2lzRVJSKCB4RXJyb3IgKSA9PSBwZEZBTFNFICkNCgkJew0KCQkJeEVycm9yID0geFRlbXBFcnJvcjsNCgkJfQ0KCX0NCg0KCXB4SU9NYW5hZ2VyLT54UGFydGl0aW9uLnVsVG90YWxTZWN0b3JzID0gcHJldlRvdGFsU2VjdG9yczsNCg0KCXJldHVybiB4RXJyb3I7DQp9CS8qIEZGX1BhcnNlRXh0ZW5kZWQoKSAqLw0KLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovDQoNCi8qKg0KICoJQHB1YmxpYw0KICoJQGJyaWVmCVNlYXJjaGVzIGEgZGlzayBmb3IgYWxsIHByaW1hcnkgYW5kIGV4dGVuZGVkL2xvZ2ljYWwgcGFydGl0aW9ucw0KICoJQGJyaWVmCVByZXZpb3VzbHkgY2FsbGVkIEZGX1BhcnRpdGlvbkNvdW50DQogKg0KICoJQHBhcmFtCXB4SU9NYW5hZ2VyCQlGRl9JT01hbmFnZXJfdCBvYmplY3QuDQogKglAcGFyYW0JcFBhcnRzRm91bmQJCUNvbnRhaW5zIGFuIGFycmF5IG9mIGZmY29uZmlnTUFYX1BBUlRJVElPTlMgcGFydGl0aW9ucw0KICoNCiAqCUBSZXR1cm4JPj0wIE51bWJlciBvZiBwYXJ0aXRpb25zIGZvdW5kDQogKglAUmV0dXJuCTwwIGVycm9yDQogKiovDQpGRl9FcnJvcl90IEZGX1BhcnRpdGlvblNlYXJjaCggRkZfSU9NYW5hZ2VyX3QgKnB4SU9NYW5hZ2VyLCBGRl9TUGFydEZvdW5kX3QgKnBQYXJ0c0ZvdW5kICkNCnsNCkJhc2VUeXBlX3QgeFBhcnROcjsNCkZGX0J1ZmZlcl90ICpweEJ1ZmZlcjsNCnVpbnQ4X3QgKnVjRGF0YUJ1ZmZlcjsNCkJhc2VUeXBlX3QgaXNQQlIgPSBwZEZBTFNFOw0KRkZfRXJyb3JfdCB4RXJyb3IgPSBGRl9FUlJfTk9ORTsNCnVpbnQzMl90IHByZXZUb3RhbFNlY3RvcnMgPSBweElPTWFuYWdlci0+eFBhcnRpdGlvbi51bFRvdGFsU2VjdG9yczsNCkZGX1BhcnRfdCBweFBhcnRpdGlvbnNbIDQgXTsNCg0KCW1lbXNldCggcFBhcnRzRm91bmQsICdcMCcsIHNpemVvZiggKnBQYXJ0c0ZvdW5kICkgKTsNCg0KCWRvDQoJew0KCQlweEJ1ZmZlciA9IEZGX0dldEJ1ZmZlciggcHhJT01hbmFnZXIsIDAsIEZGX01PREVfUkVBRCApOw0KCQlpZiggcHhCdWZmZXIgPT0gTlVMTCApDQoJCXsNCgkJCXhFcnJvciA9IEZGX0VSUl9ERVZJQ0VfRFJJVkVSX0ZBSUxFRCB8IEZGX1BBUlRJVElPTlNFQVJDSDsNCgkJCWJyZWFrOw0KCQl9DQoNCgkJLyogRGlzYWJsZSBzZWN0b3IgY2hlY2tpbmcgaW4gRkZfQmxvY2tSZWFkDQoJCUxldCB1c2VyIGRyaXZlciByZXR1cm4gYW4gZXJyb3IgaXMgYXBwcm9wcmlhdGUuICovDQoJCXB4SU9NYW5hZ2VyLT54UGFydGl0aW9uLnVsVG90YWxTZWN0b3JzID0gMDsNCgkJdWNEYXRhQnVmZmVyID0gcHhCdWZmZXItPnB1Y0J1ZmZlcjsNCg0KCQkvKiBDaGVjayBNQlIgKE1hc3RlciBCb290IFJlY29yZCkgb3INCgkJUEJSIChQYXJ0aXRpb24gQm9vdCBSZWNvcmQpIHNpZ25hdHVyZS4gKi8NCgkJaWYoICggRkZfZ2V0Q2hhciggdWNEYXRhQnVmZmVyLCBGRl9GQVRfTUJSX1NJR05BVFVSRSApICE9IDB4NTUgKSAmJg0KCQkJKCBGRl9nZXRDaGFyKCB1Y0RhdGFCdWZmZXIsIEZGX0ZBVF9NQlJfU0lHTkFUVVJFICkgIT0gMHhBQSApICkNCgkJew0KCQkJLyogTm8gTUJSLCBidXQgaXMgaXQgYSBQQlIgPw0KCQkJUGFydGl0aW9uIEJvb3QgUmVjb3JkICovDQoJCQlpZiggKCBGRl9nZXRDaGFyKCB1Y0RhdGFCdWZmZXIsIDAgKSA9PSAweEVCICkgJiYgLyogUEJSIEJ5dGUgMCAqLw0KCQkJCSggRkZfZ2V0Q2hhciggdWNEYXRhQnVmZmVyLCAyICkgPT0gMHg5MCApICkNCgkJCXsNCgkJCQkvKiBQQlIgQnl0ZSAyDQoJCQkJTm8gTUJSIGJ1dCBQQlIgZXhpc3QgdGhlbiB0aGVyZSBpcyBvbmx5IG9uZSBwYXJ0aXRpb24NCgkJCQlIYW5kbGUgdGhpcyBsYXRlci4gKi8NCgkJCQlpc1BCUiA9IHBkVFJVRTsNCgkJCX0NCgkJCWVsc2UNCgkJCXsNCgkJCQlGRl9QUklOVEYoICJGRl9QYXJ0aXRpb25TZWFyY2g6IFslMDJYLCUwMlhdIE5vIHNpZ25hdHVyZSAoJTAyWCAlMDJYKSwgbm8gUEJSIG5laXRoZXJcbiIsDQoJCQkJCUZGX2dldENoYXIoIHVjRGF0YUJ1ZmZlciwgMCApLA0KCQkJCQlGRl9nZXRDaGFyKCB1Y0RhdGFCdWZmZXIsIDIgKSwNCgkJCQkJRkZfZ2V0Q2hhciggdWNEYXRhQnVmZmVyLCBGRl9GQVRfTUJSX1NJR05BVFVSRSApLA0KCQkJCQlGRl9nZXRDaGFyKCB1Y0RhdGFCdWZmZXIsIEZGX0ZBVF9NQlJfU0lHTkFUVVJFICsgMSApICk7DQoNCgkJCQkvKiBObyBNQlIgYW5kIG5vIFBCUiB0aGVuIG5vIHBhcnRpdGlvbiBmb3VuZC4gKi8NCgkJCQl4RXJyb3IgPSBGRl9FUlJfSU9NQU5fSU5WQUxJRF9GT1JNQVQgfCBGRl9QQVJUSVRJT05TRUFSQ0g7DQoJCQkJYnJlYWs7DQoJCQl9DQoJCX0NCgkJLyogQ29weSB0aGUgNCBwYXJ0aXRpb24gcmVjb3JkcyBpbnRvICdweFBhcnRpdGlvbnMnOiAqLw0KCQlGRl9SZWFkUGFydHMoIHVjRGF0YUJ1ZmZlciwgcHhQYXJ0aXRpb25zICk7DQoNCgkJZm9yKCB4UGFydE5yID0gMDsgKCB4UGFydE5yIDwgNCApICYmICggaXNQQlIgPT0gcGRGQUxTRSApOyB4UGFydE5yKysgKQ0KCQl7DQoJCQkvKgkJRkZfUFJJTlRGICgiRkZfUGFydFslZF06IGlkICUwMlggYWN0ICUwMlggU3RhcnQgJTZsdSBMZW4gJTZsdSAoc2VjdG9ycylcbiIsICovDQoJCQkvKgkJCXhQYXJ0TnIsIHB4UGFydGl0aW9uc1sgeFBhcnROciBdLnVjUGFydGl0aW9uSUQsICovDQoJCQkvKgkJCXB4UGFydGl0aW9uc1sgeFBhcnROciBdLnVjQWN0aXZlLCAqLw0KCQkJLyoJCQlweFBhcnRpdGlvbnNbIHhQYXJ0TnIgXS51bFN0YXJ0TEJBLCAqLw0KCQkJLyoJCQlweFBhcnRpdGlvbnNbIHhQYXJ0TnIgXS51bFNlY3RvckNvdW50KTsgKi8NCgkJCWlmKCBwcnZJc0V4dGVuZGVkUGFydGl0aW9uKCBweFBhcnRpdGlvbnNbIHhQYXJ0TnIgXS51Y1BhcnRpdGlvbklEICkgIT0gcGRGQUxTRSApDQoJCQl7DQoJCQkJY29udGludWU7CQkvKiBEbyB0aGlzIGxhdGVyICovDQoJCQl9DQoNCgkJCS8qIFRoZSBmaXJzdCBzZWN0b3IgbXVzdCBiZSBhIE1CUiwgdGhlbiBjaGVjayB0aGUgcGFydGl0aW9uIGVudHJ5IGluIHRoZSBNQlIgKi8NCgkJCWlmKCAoIHB4UGFydGl0aW9uc1sgeFBhcnROciBdLnVjQWN0aXZlICE9IDB4ODAgKSAmJg0KCQkJCSggcHhQYXJ0aXRpb25zWyB4UGFydE5yIF0udWNBY3RpdmUgIT0gMHgwMCApICkNCgkJCXsNCgkJCQlpZiggKCB4UGFydE5yID09IDAgKSAmJg0KCQkJCQkoIEZGX2dldFNob3J0KCB1Y0RhdGFCdWZmZXIsIEZGX0ZBVF9SRVNFUlZFRF9TRUNUT1JTICkgIT0gMCApICYmDQoJCQkJCSggRkZfZ2V0Q2hhciggdWNEYXRhQnVmZmVyLCBGRl9GQVRfTlVNQkVSX09GX0ZBVFMgKSAhPSAwICkgKQ0KCQkJCXsNCgkJCQkJaXNQQlIgPSBwZFRSVUU7DQoJCQkJfQ0KCQkJCWVsc2UNCgkJCQl7DQoJCQkJCXhFcnJvciA9IEZGX0VSUl9JT01BTl9JTlZBTElEX0ZPUk1BVCB8IEZGX1BBUlRJVElPTlNFQVJDSDsNCgkJCQkJYnJlYWs7DQoJCQkJfQ0KCQkJfQ0KCQkJZWxzZSBpZiggcHhQYXJ0aXRpb25zWyB4UGFydE5yIF0udWxTZWN0b3JDb3VudCApDQoJCQl7DQoJCQkJRkZfUGFydF90CSpwID0gJnBQYXJ0c0ZvdW5kLT5weFBhcnRpdGlvbnNbIHBQYXJ0c0ZvdW5kLT5pQ291bnQrKyBdOw0KCQkJCSpwID0gcHhQYXJ0aXRpb25zWyB4UGFydE5yIF07DQoJCQkJcC0+YklzRXh0ZW5kZWQgPSAwOw0KCQkJCWlmKCBwUGFydHNGb3VuZC0+aUNvdW50ID49IGZmY29uZmlnTUFYX1BBUlRJVElPTlMgKQ0KCQkJCXsNCgkJCQkJYnJlYWs7DQoJCQkJfQ0KCQkJfQ0KCQl9DQoJCWlmKCBGRl9pc0VSUiggeEVycm9yICkgfHwgKCBwUGFydHNGb3VuZC0+aUNvdW50ID49IGZmY29uZmlnTUFYX1BBUlRJVElPTlMgKSApDQoJCXsNCgkJCWJyZWFrOw0KCQl9DQoJCWZvciggeFBhcnROciA9IDA7IHhQYXJ0TnIgPCA0OyB4UGFydE5yKysgKQ0KCQl7DQoJCQlpZiggcHJ2SXNFeHRlbmRlZFBhcnRpdGlvbiggcHhQYXJ0aXRpb25zWyB4UGFydE5yIF0udWNQYXJ0aXRpb25JRCApICkNCgkJCXsNCgkJCQl4RXJyb3IgPSBGRl9QYXJzZUV4dGVuZGVkKCBweElPTWFuYWdlciwgcHhQYXJ0aXRpb25zWyB4UGFydE5yIF0udWxTdGFydExCQSwNCgkJCQkJcHhQYXJ0aXRpb25zWyB4UGFydE5yIF0udWxTZWN0b3JDb3VudCwgcFBhcnRzRm91bmQgKTsNCg0KCQkJCWlmKCAoIEZGX2lzRVJSKCB4RXJyb3IgKSAhPSBwZEZBTFNFICkgfHwgKCBwUGFydHNGb3VuZC0+aUNvdW50ID49IGZmY29uZmlnTUFYX1BBUlRJVElPTlMgKSApDQoJCQkJew0KCQkJCQlnb3RvIGRvbmU7DQoJCQkJfQ0KCQkJfQ0KCQl9DQoNCgkJaWYoIHBQYXJ0c0ZvdW5kLT5pQ291bnQgPT0gMCApDQoJCXsNCgkJCUZGX1BSSU5URiggIkZGX1BhcnQ6IG5vIHBhcnRpdGlvbnMsIHRyeSBhcyBQQlJcbiIgKTsNCgkJCWlzUEJSID0gcGRUUlVFOw0KCQl9DQoNCgkJaWYoIGlzUEJSICkNCgkJew0KCQkJdWludDhfdCBtZWRpYSA9IEZGX2dldENoYXIoIHVjRGF0YUJ1ZmZlciwgRkZfRkFUX01FRElBX1RZUEUgKTsNCgkJCUZGX1BhcnRfdAkqcDsNCgkJCWlmKCAhcHJ2SXNWYWxpZE1lZGlhKCBtZWRpYSApICkNCgkJCXsNCgkJCQlGRl9QUklOVEYoICJGRl9QYXJ0OiBMb29rcyBsaWtlIFBCUiBidXQgbWVkaWEgJTAyWFxuIiwgbWVkaWEgKTsNCgkJCQl4RXJyb3IgPSBGRl9FUlJfSU9NQU5fTk9fTU9VTlRBQkxFX1BBUlRJVElPTiB8IEZGX1BBUlRJVElPTlNFQVJDSDsNCgkJCQlnb3RvIGRvbmU7DQoJCQl9DQoNCgkJCS8qIFRoaXMgbG9va3MgbGlrZSBhIFBCUiBiZWNhdXNlIGl0IGhhcyBhIHZhbGlkIG1lZGlhIHR5cGUgKi8NCgkJCXAgPSBwUGFydHNGb3VuZC0+cHhQYXJ0aXRpb25zOw0KCQkJcC0+dWxTdGFydExCQSA9IDA7CS8qIEZGX0ZBVF9QVEJMX0xCQSAqLw0KCQkJcC0+dWxTZWN0b3JDb3VudCA9ICggdWludDMyX3QgKSBGRl9nZXRTaG9ydCggcHhCdWZmZXItPnB1Y0J1ZmZlciwgRkZfRkFUXzE2X1RPVEFMX1NFQ1RPUlMgKTsNCgkJCWlmKCBwLT51bFNlY3RvckNvdW50ID09IDB1bCApDQoJCQl7DQoJCQkJcC0+dWxTZWN0b3JDb3VudCA9IEZGX2dldExvbmcoIHB4QnVmZmVyLT5wdWNCdWZmZXIsIEZGX0ZBVF8zMl9UT1RBTF9TRUNUT1JTICk7DQoJCQl9DQoNCgkJCXAtPnVjQWN0aXZlID0gMHg4MDsJLyogRkZfRkFUX1BUQkxfQUNUSVZFICovDQoJCQlwLT51Y1BhcnRpdGlvbklEID0gMHgwQjsJLyogRkZfRkFUX1BUQkxfSUQgTVNET1MgZGF0YSBwYXJ0aXRpb24gKi8NCgkJCXAtPmJJc0V4dGVuZGVkID0gMDsNCgkJCXBQYXJ0c0ZvdW5kLT5pQ291bnQgPSAxOw0KCQl9DQoJfSB3aGlsZSggcGRGQUxTRSApOw0KZG9uZToNCglpZiggcHhCdWZmZXIgKQ0KCXsNCgkJRkZfRXJyb3JfdCB4VGVtcEVycm9yID0gRkZfUmVsZWFzZUJ1ZmZlciggcHhJT01hbmFnZXIsIHB4QnVmZmVyICk7DQoJCWlmKCBGRl9pc0VSUiggeEVycm9yICkgPT0gcGRGQUxTRSApDQoJCXsNCgkJCXhFcnJvciA9IHhUZW1wRXJyb3I7DQoJCX0NCgl9DQoNCglweElPTWFuYWdlci0+eFBhcnRpdGlvbi51bFRvdGFsU2VjdG9ycyA9IHByZXZUb3RhbFNlY3RvcnM7DQoNCglyZXR1cm4gRkZfaXNFUlIoIHhFcnJvciApID8geEVycm9yIDogcFBhcnRzRm91bmQtPmlDb3VudDsNCn0JLyogRkZfUGFydGl0aW9uU2VhcmNoKCkgKi8NCi8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLw0KDQovKg0KCU1vdW50IEdQVCBQYXJ0aXRpb24gVGFibGVzDQoqLw0KI2RlZmluZSBGRl9HUFRfSEVBRF9FTlRSWV9TSVpFCQkJMHg1NA0KI2RlZmluZSBGRl9HUFRfSEVBRF9UT1RBTF9FTlRSSUVTCQkweDUwDQojZGVmaW5lIEZGX0dQVF9IRUFEX1BBUlRfRU5UUllfTEJBCQkweDQ4DQojZGVmaW5lIEZGX0dQVF9FTlRSWV9GSVJTVF9TRUNUT1JfTEJBCTB4MjANCiNkZWZpbmUgRkZfR1BUX0hFQURfQ1JDCQkJCQkweDEwDQojZGVmaW5lIEZGX0dQVF9IRUFEX0xFTkdUSAkJCQkweDBDDQoNCnN0YXRpYyBGRl9FcnJvcl90IEZGX0dldEVmaVBhcnRpdGlvbkVudHJ5KCBGRl9JT01hbmFnZXJfdCAqcHhJT01hbmFnZXIsIHVpbnQzMl90IHVsUGFydGl0aW9uTnVtYmVyICkNCnsNCi8qIENvbnRpbnVpbmcgb24gZnJvbSBGRl9Nb3VudCgpIHBQYXJ0aXRpb24tPnVsQmVnaW5MQkEgc2hvdWxkIGJlIHRoZSBzZWN0b3Igb2YgdGhlIEdQVCBIZWFkZXIgKi8NCkZGX0J1ZmZlcl90ICpweEJ1ZmZlcjsNCkZGX1BhcnRpdGlvbl90ICpweFBhcnRpdGlvbiA9ICYoIHB4SU9NYW5hZ2VyLT54UGFydGl0aW9uICk7DQoNCnVpbnQzMl90IHVsQmVnaW5HUFQ7DQp1aW50MzJfdCB1bEVudHJ5U2VjdG9yOw0KdWludDMyX3QgdWxTZWN0b3JPZmZzZXQ7DQp1aW50MzJfdCB1bFBhcnRpdGlvbkVudHJ5U2l6ZTsNCnVpbnQzMl90IHVsR1BUSGVhZENSQywgdWxHUFRDcmNDaGVjaywgdWxHUFRIZWFkTGVuZ3RoOw0KDQpGRl9FcnJvcl90IHhFcnJvcjsNCg0KCWRvDQoJew0KCQlpZiggdWxQYXJ0aXRpb25OdW1iZXIgPj0gMTI4ICkNCgkJew0KCQkJeEVycm9yID0gRkZfRVJSX0lPTUFOX0lOVkFMSURfUEFSVElUSU9OX05VTSB8IEZGX0dFVEVGSVBBUlRJVElPTkVOVFJZOw0KCQkJYnJlYWs7DQoJCX0NCgkJcHhCdWZmZXIgPSBGRl9HZXRCdWZmZXIoIHB4SU9NYW5hZ2VyLCBweFBhcnRpdGlvbi0+dWxCZWdpbkxCQSwgRkZfTU9ERV9SRUFEICk7DQoJCWlmKCBweEJ1ZmZlciA9PSBOVUxMICkNCgkJew0KCQkJeEVycm9yID0gRkZfRVJSX0RFVklDRV9EUklWRVJfRkFJTEVEIHwgRkZfR0VURUZJUEFSVElUSU9ORU5UUlk7DQoJCQlicmVhazsNCgkJfQ0KDQoJCS8qIFZlcmlmeSB0aGlzIGlzIGFuIEVGSSBoZWFkZXIgd2l0aCB0aGUgdGV4dCAiRUZJIFBBUlQiOiAqLw0KCQlpZiggbWVtY21wKCBweEJ1ZmZlci0+cHVjQnVmZmVyLCAiRUZJIFBBUlQiLCA4ICkgIT0gMCApDQoJCXsNCgkJCS8qIEFscmVhZHkgcmV0dXJuaW5nIGFuIGVycm9yLCBidXQgdGhpcyBlcnJvciB3b3VsZCBvdmVycmlkZSB0aGUgY3VycmVudCBvbmUuICovDQoJCQl4RXJyb3IgPSBGRl9SZWxlYXNlQnVmZmVyKCBweElPTWFuYWdlciwgcHhCdWZmZXIgKTsNCgkJCWlmKCBGRl9pc0VSUiggeEVycm9yICkgPT0gcGRGQUxTRSApDQoJCQl7DQoJCQkJeEVycm9yID0gRkZfRVJSX0lPTUFOX0lOVkFMSURfRk9STUFUIHwgRkZfR0VURUZJUEFSVElUSU9ORU5UUlk7DQoJCQl9DQoJCQlicmVhazsNCgkJfQ0KDQoJCXVsQmVnaW5HUFQJCQkJCT0gRkZfZ2V0TG9uZyggcHhCdWZmZXItPnB1Y0J1ZmZlciwgRkZfR1BUX0hFQURfUEFSVF9FTlRSWV9MQkEgKTsNCgkJdWxQYXJ0aXRpb25FbnRyeVNpemUJCT0gRkZfZ2V0TG9uZyggcHhCdWZmZXItPnB1Y0J1ZmZlciwgRkZfR1BUX0hFQURfRU5UUllfU0laRSApOw0KCQl1bEdQVEhlYWRDUkMJCQkJPSBGRl9nZXRMb25nKCBweEJ1ZmZlci0+cHVjQnVmZmVyLCBGRl9HUFRfSEVBRF9DUkMgKTsNCgkJdWxHUFRIZWFkTGVuZ3RoCQkJCT0gRkZfZ2V0TG9uZyggcHhCdWZmZXItPnB1Y0J1ZmZlciwgRkZfR1BUX0hFQURfTEVOR1RIICk7DQoNCgkJLyogQ2FsY3VsYXRlIEhlYWQgQ1JDICovDQoJCS8qIEJsYW5rIENSQyBmaWVsZCAqLw0KCQlGRl9wdXRMb25nKCBweEJ1ZmZlci0+cHVjQnVmZmVyLCBGRl9HUFRfSEVBRF9DUkMsIDB4MDAwMDAwMDAgKTsNCg0KCQkvKiBDYWxjdWxhdGUgQ1JDICovDQoJCXVsR1BUQ3JjQ2hlY2sgPSBGRl9HZXRDUkMzMiggcHhCdWZmZXItPnB1Y0J1ZmZlciwgdWxHUFRIZWFkTGVuZ3RoICk7DQoNCgkJLyogUmVzdG9yZSBUaGUgQ1JDIGZpZWxkICovDQoJCUZGX3B1dExvbmcoIHB4QnVmZmVyLT5wdWNCdWZmZXIsIEZGX0dQVF9IRUFEX0NSQywgdWxHUFRIZWFkQ1JDICk7DQoNCgkJeEVycm9yID0gRkZfUmVsZWFzZUJ1ZmZlciggcHhJT01hbmFnZXIsIHB4QnVmZmVyICk7DQoJCWlmKCBGRl9pc0VSUiggeEVycm9yICkgKQ0KCQl7DQoJCQlicmVhazsNCgkJfQ0KDQoJCS8qIENoZWNrIENSQyAqLw0KCQlpZiggdWxHUFRIZWFkQ1JDICE9IHVsR1BUQ3JjQ2hlY2sgKQ0KCQl7DQoJCQl4RXJyb3IgPSBGRl9FUlJfSU9NQU5fR1BUX0hFQURFUl9DT1JSVVBUIHwgRkZfR0VURUZJUEFSVElUSU9ORU5UUlk7DQoJCQlicmVhazsNCgkJfQ0KDQoJCS8qIENhbGN1bGF0ZSBTZWN0b3IgQ29udGFpbmluZyB0aGUgUGFydGl0aW9uIEVudHJ5IHdlIHdhbnQgdG8gdXNlLiAqLw0KCQl1bEVudHJ5U2VjdG9yID0gKCAoIHVsUGFydGl0aW9uTnVtYmVyICogdWxQYXJ0aXRpb25FbnRyeVNpemUgKSAvIHB4SU9NYW5hZ2VyLT51c1NlY3RvclNpemUgKSArIHVsQmVnaW5HUFQ7DQoJCXVsU2VjdG9yT2Zmc2V0ID0gKCB1bFBhcnRpdGlvbk51bWJlciAlICggcHhJT01hbmFnZXItPnVzU2VjdG9yU2l6ZSAvIHVsUGFydGl0aW9uRW50cnlTaXplICkgKSAqIHVsUGFydGl0aW9uRW50cnlTaXplOw0KDQoJCXB4QnVmZmVyID0gRkZfR2V0QnVmZmVyKCBweElPTWFuYWdlciwgdWxFbnRyeVNlY3RvciwgRkZfTU9ERV9SRUFEICk7DQoJCXsNCgkJCWlmKCBweEJ1ZmZlciA9PSBOVUxMICkNCgkJCXsNCgkJCQl4RXJyb3IgPSBGRl9FUlJfREVWSUNFX0RSSVZFUl9GQUlMRUQgfCBGRl9HRVRFRklQQVJUSVRJT05FTlRSWTsNCgkJCQlicmVhazsNCgkJCX0NCg0KCQkJcHhQYXJ0aXRpb24tPnVsQmVnaW5MQkEgPSBGRl9nZXRMb25nKCBweEJ1ZmZlci0+cHVjQnVmZmVyLCB1bFNlY3Rvck9mZnNldCArIEZGX0dQVF9FTlRSWV9GSVJTVF9TRUNUT1JfTEJBICk7DQoJCX0NCg0KCQl4RXJyb3IgPSBGRl9SZWxlYXNlQnVmZmVyKCBweElPTWFuYWdlciwgcHhCdWZmZXIgKTsNCgkJaWYoIEZGX2lzRVJSKCB4RXJyb3IgKSA9PSBwZEZBTFNFICkNCgkJew0KCQkJaWYoIHB4UGFydGl0aW9uLT51bEJlZ2luTEJBID09IDB1bCApDQoJCQl7DQoJCQkJeEVycm9yID0gRkZfRVJSX0lPTUFOX0lOVkFMSURfUEFSVElUSU9OX05VTSB8IEZGX0dFVEVGSVBBUlRJVElPTkVOVFJZOw0KCQkJfQ0KCQl9DQoJfQ0KCXdoaWxlKCBwZEZBTFNFICk7DQoNCglyZXR1cm4geEVycm9yOw0KfQkvKiBGRl9HZXRFZmlQYXJ0aXRpb25FbnRyeSgpICovDQovKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8NCg0KLyoqDQogKglAcHVibGljDQogKglAYnJpZWYJTW91bnRzIHRoZSBTcGVjaWZpZWQgcGFydGl0aW9uLCB0aGUgdm9sdW1lIHNwZWNpZmllZCBieSB0aGUgRkZfSU9NYW5hZ2VyX3Qgb2JqZWN0IHByb3ZpZGVkLg0KICoNCiAqCVRoZSBkZXZpY2UgZHJpdmVycyBtdXN0IGFkaGVyZSB0byB0aGUgc3BlY2lmaWNhdGlvbiBwcm92aWRlZCBieQ0KICoJRkZfV3JpdGVCbG9ja3NfdCBhbmQgRkZfUmVhZEJsb2Nrc190Lg0KICoNCiAqCUBwYXJhbQlweElPTWFuYWdlcgkJCUZGX0lPTWFuYWdlcl90IG9iamVjdC4NCiAqCUBwYXJhbQlQYXJ0aXRpb25OdW1iZXIJVGhlIHByaW1hcnkgb3IgbG9naWNhbCBwYXJ0aXRpb24gbnVtYmVyIHRvIGJlIG1vdW50ZWQsDQogKiAgICAgICAgICAgICAgICAgICAgICAgICAgcmFuZ2luZyBiZXR3ZWVuIDAgYW5kIGZmY29uZmlnTUFYX1BBUlRJVElPTlMtMSAobm9ybWFsbHkgMCkNCiAqICAgICAgICAgICAgICAgICAgICAgICAgICBOb3RlIHRoYXQgRkZfUGFydGl0aW9uU2VhcmNoIGNhbiBiZSBjYWxsZWQgaW4gYWR2YW5jZSB0bw0KICogICAgICAgICAgICAgICAgICAgICAgICAgIGVudW1lcmF0ZSBhbGwgYXZhaWxhYmxlIHBhcnRpdGlvbnMNCiAqDQogKglAUmV0dXJuCTAgb24gc3VjY2Vzcy4NCiAqCUBSZXR1cm4gRkZfRVJSX05VTExfUE9JTlRFUiBpZiBhIHB4SU9NYW5hZ2VyIG9iamVjdCB3YXNuJ3QgcHJvdmlkZWQuDQogKglAUmV0dXJuIEZGX0VSUl9JT01BTl9JTlZBTElEX1BBUlRJVElPTl9OVU0gaWYgdGhlIHBhcnRpdGlvbiBudW1iZXIgaXMgb3V0IG9mIHJhbmdlLg0KICoJQFJldHVybiBGRl9FUlJfSU9NQU5fTk9fTU9VTlRBQkxFX1BBUlRJVElPTiBpZiBubyBwYXJ0aXRpb24gd2FzIGZvdW5kLg0KICoJQFJldHVybiBGRl9FUlJfSU9NQU5fSU5WQUxJRF9GT1JNQVQgaWYgdGhlIG1hc3RlciBib290IHJlY29yZCBvciBwYXJ0aXRpb24gYm9vdCBibG9jayBkaWRuJ3QgcHJvdmlkZSBzZW5zaWJsZSBkYXRhLg0KICoJQFJldHVybiBGRl9FUlJfSU9NQU5fTk9UX0ZBVF9GT1JNQVRURUQgaWYgdGhlIHZvbHVtZSBvciBwYXJ0aXRpb24gY291bGRuJ3QgYmUgZGV0ZXJtaW5lZCB0byBiZSBGQVQuIChAc2VlIEZyZWVSVE9TRkFUQ29uZmlnLmgpDQogKg0KICoqLw0KRkZfRXJyb3JfdCBGRl9Nb3VudCggRkZfRGlza190ICpweERpc2ssIEJhc2VUeXBlX3QgeFBhcnRpdGlvbk51bWJlciApDQp7DQpGRl9QYXJ0aXRpb25fdCAqcHhQYXJ0aXRpb247DQpGRl9CdWZmZXJfdCAqcHhCdWZmZXIgPSAwOw0KRkZfRXJyb3JfdCB4RXJyb3IgPSBGRl9FUlJfTk9ORTsNCmludDE2X3Qgcm9vdEVudHJ5Q291bnQ7DQpGRl9JT01hbmFnZXJfdCAqcHhJT01hbmFnZXIgPSBweERpc2stPnB4SU9NYW5hZ2VyOw0KDQovKiBIVCBUT0RPOiBmaW5kIGEgbWV0aG9kIHRvIHNhZmVseSBkZXRlcm1pbmUgdGhlIEZBVCB0eXBlOiAzMi8xNi8xMiAqLw0KLyogb3RoZXIgdGhhbiBvbmx5IGNvdW50aW5nIENsdXN0ZXJzICovDQovKglVQmFzZVR5cGVfdAkJZmF0MzJJbmRpY2F0b3IgPSAwOyAqLw0KRkZfUGFydF90ICpweE15UGFydGl0aW9uOw0KI2lmKCBmZmNvbmZpZ0hBU0hfQ0FDSEUgIT0gMCApDQoJQmFzZVR5cGVfdCBpOw0KI2VuZGlmDQpGRl9FcnJvcl90IHhQYXJ0aXRpb25Db3VudCA9IDA7DQpGRl9TUGFydEZvdW5kX3QgcGFydHNGb3VuZDsNCnBhcnRzRm91bmQuaUNvdW50ID0gMDsNCg0KCWRvDQoJew0KCQlpZiggcHhJT01hbmFnZXIgPT0gTlVMTCApDQoJCXsNCgkJCXhFcnJvciA9IEZGX0VSUl9OVUxMX1BPSU5URVIgfCBGRl9NT1VOVDsNCgkJCWJyZWFrOw0KCQl9DQoNCgkJcHhQYXJ0aXRpb24gPSAmKCBweElPTWFuYWdlci0+eFBhcnRpdGlvbiApOw0KDQoJCSNpZiggZmZjb25maWdSRU1PVkFCTEVfTUVESUEgIT0gMCApDQoJCXsNCgkJCXB4SU9NYW5hZ2VyLT51Y0ZsYWdzICY9ICggdWludDhfdCApICggfiAoIEZGX0lPTUFOX0RFVklDRV9JU19FWFRSQUNURUQgKSApOw0KCQl9DQoJCSNlbmRpZiAvKiBmZmNvbmZpZ1JFTU9WQUJMRV9NRURJQSAqLw0KDQoJCS8qIEZGX0lPTUFOX0luaXRCdWZmZXJEZXNjcmlwdG9ycyB3aWxsIGNsZWFyICdweEJ1ZmZlcnMnICovDQoJCW1lbXNldCggcHhJT01hbmFnZXItPnB1Y0NhY2hlTWVtLCAnXDAnLCAoIHNpemVfdCApIHB4SU9NYW5hZ2VyLT51c1NlY3RvclNpemUgKiBweElPTWFuYWdlci0+dXNDYWNoZVNpemUgKTsNCg0KCQkjaWYoIGZmY29uZmlnSEFTSF9DQUNIRSAhPSAwICkNCgkJew0KCQkJbWVtc2V0KCBweElPTWFuYWdlci0+eEhhc2hDYWNoZSwgJ1wwJywgc2l6ZW9mKCBweElPTWFuYWdlci0+eEhhc2hDYWNoZSApICk7DQoJCQlmb3IoIGkgPSAwOyBpIDwgZmZjb25maWdIQVNIX0NBQ0hFX0RFUFRIOyBpKysgKQ0KCQkJew0KCQkJCS8qIF9IVF8gQ2hlY2sgd2h5IGRpZCBKVyBwdXQgaXQgdG8gMTAwPyAqLw0KCQkJCXB4SU9NYW5hZ2VyLT54SGFzaENhY2hlWyBpIF0udWxNaXNzZXMgPSAxMDA7DQoJCQl9DQoJCX0NCgkJI2VuZGlmDQoJCSNpZiggZmZjb25maWdQQVRIX0NBQ0hFICE9IDAgKQ0KCQl7DQoJCQltZW1zZXQoIHB4UGFydGl0aW9uLT5weFBhdGhDYWNoZSwgJ1wwJywgc2l6ZW9mKCBweFBhcnRpdGlvbi0+cHhQYXRoQ2FjaGUgKSApOw0KCQl9DQoJCSNlbmRpZg0KCQlGRl9JT01BTl9Jbml0QnVmZmVyRGVzY3JpcHRvcnMoIHB4SU9NYW5hZ2VyICk7DQoJCXB4SU9NYW5hZ2VyLT5GaXJzdEZpbGUgPSAwOw0KDQoJCXhQYXJ0aXRpb25Db3VudCA9IEZGX1BhcnRpdGlvblNlYXJjaCggcHhJT01hbmFnZXIsICZwYXJ0c0ZvdW5kICk7DQoJCWlmKCBGRl9pc0VSUiggeFBhcnRpdGlvbkNvdW50ICkgKQ0KCQl7DQoJCQl4RXJyb3IgPSB4UGFydGl0aW9uQ291bnQ7DQoJCQlicmVhazsNCgkJfQ0KDQoJCWlmKCB4UGFydGl0aW9uQ291bnQgPT0gMCApDQoJCXsNCgkJCXhFcnJvciA9IEZGX0VSUl9JT01BTl9OT19NT1VOVEFCTEVfUEFSVElUSU9OIHwgRkZfTU9VTlQ7DQoJCQlicmVhazsNCgkJfQ0KDQoJCWlmKCB4UGFydGl0aW9uTnVtYmVyID49IHhQYXJ0aXRpb25Db3VudCApDQoJCXsNCgkJCXhFcnJvciA9IEZGX0VSUl9JT01BTl9JTlZBTElEX1BBUlRJVElPTl9OVU0gfCBGRl9NT1VOVDsNCgkJCWJyZWFrOw0KCQl9DQoNCgkJcHhNeVBhcnRpdGlvbiA9ICYoIHBhcnRzRm91bmQucHhQYXJ0aXRpb25zWyB4UGFydGl0aW9uTnVtYmVyIF0gKTsNCg0KCQlweFBhcnRpdGlvbi0+dWxCZWdpbkxCQSA9IHB4TXlQYXJ0aXRpb24tPnVsU3RhcnRMQkE7DQoNCgkJaWYoIHB4TXlQYXJ0aXRpb24tPnVjUGFydGl0aW9uSUQgPT0gMHhFRSApDQoJCXsNCgkJCXhFcnJvciA9IEZGX0dldEVmaVBhcnRpdGlvbkVudHJ5KCBweElPTWFuYWdlciwgeFBhcnRpdGlvbk51bWJlciApOw0KDQoJCQlpZiggRkZfaXNFUlIoIHhFcnJvciApICkNCgkJCXsNCgkJCQlicmVhazsNCgkJCX0NCgkJfQ0KDQoJCS8qIE5vdyB3ZSBnZXQgdGhlIFBhcnRpdGlvbiBzZWN0b3IuICovDQoJCXB4QnVmZmVyID0gRkZfR2V0QnVmZmVyKCBweElPTWFuYWdlciwgcHhQYXJ0aXRpb24tPnVsQmVnaW5MQkEsIEZGX01PREVfUkVBRCApOw0KCQlpZiggcHhCdWZmZXIgPT0gTlVMTCApDQoJCXsNCgkJCXhFcnJvciA9IEZGX0VSUl9ERVZJQ0VfRFJJVkVSX0ZBSUxFRCB8IEZGX01PVU5UOw0KCQkJYnJlYWs7DQoJCX0NCg0KCQlweFBhcnRpdGlvbi0+dXNCbGtTaXplID0gRkZfZ2V0U2hvcnQoIHB4QnVmZmVyLT5wdWNCdWZmZXIsIEZGX0ZBVF9CWVRFU19QRVJfU0VDVE9SICk7DQoJCWlmKCAoICggcHhQYXJ0aXRpb24tPnVzQmxrU2l6ZSAlIDUxMiApICE9IDAgKSB8fCAoIHB4UGFydGl0aW9uLT51c0Jsa1NpemUgPT0gMCApICkNCgkJew0KCQkJLyogQW4gZXJyb3IgaGVyZSBzaG91bGQgb3ZlcnJpZGUgdGhlIGN1cnJlbnQgZXJyb3IsIGFzIGl0cyBsaWtlbHkgZmF0YWwuICovDQoJCQl4RXJyb3IgPSBGRl9SZWxlYXNlQnVmZmVyKCBweElPTWFuYWdlciwgcHhCdWZmZXIgKTsNCgkJCWlmKCBGRl9pc0VSUiggeEVycm9yICkgPT0gcGRGQUxTRSApDQoJCQl7DQoJCQkJeEVycm9yID0gRkZfRVJSX0lPTUFOX0lOVkFMSURfRk9STUFUIHwgRkZfTU9VTlQ7DQoJCQl9DQoJCQlicmVhazsNCgkJfQ0KDQoJCS8qIEFzc3VtZSBGQVQxNiwgdGhlbiB3ZSdsbCBhZGp1c3QgaWYgaXRzIEZBVDMyICovDQoJCXB4UGFydGl0aW9uLT51c1Jlc2VydmVkU2VjdG9ycyA9IEZGX2dldFNob3J0KCBweEJ1ZmZlci0+cHVjQnVmZmVyLCBGRl9GQVRfUkVTRVJWRURfU0VDVE9SUyApOw0KCQlweFBhcnRpdGlvbi0+dWxGQVRCZWdpbkxCQSA9IHB4UGFydGl0aW9uLT51bEJlZ2luTEJBICsgcHhQYXJ0aXRpb24tPnVzUmVzZXJ2ZWRTZWN0b3JzOw0KDQoJCXB4UGFydGl0aW9uLT51Y051bUZBVFMgPSAoIHVpbnQ4X3QgKSBGRl9nZXRTaG9ydCggcHhCdWZmZXItPnB1Y0J1ZmZlciwgRkZfRkFUX05VTUJFUl9PRl9GQVRTICk7DQoJCXB4UGFydGl0aW9uLT51bFNlY3RvcnNQZXJGQVQgPSAoIHVpbnQzMl90ICkgRkZfZ2V0U2hvcnQoIHB4QnVmZmVyLT5wdWNCdWZmZXIsIEZGX0ZBVF8xNl9TRUNUT1JTX1BFUl9GQVQgKTsNCg0KCQlweFBhcnRpdGlvbi0+dWxTZWN0b3JzUGVyQ2x1c3RlciA9IEZGX2dldENoYXIoIHB4QnVmZmVyLT5wdWNCdWZmZXIsIEZGX0ZBVF9TRUNUT1JTX1BFUl9DTFVTICk7DQoNCgkJLyogU2V0IHRoZSBCbG9ja0ZhY3RvciAoSG93IG1hbnkgcmVhbC1ibG9ja3MgaW4gYSBmYWtlIGJsb2NrISkuICovDQoJCXB4UGFydGl0aW9uLT51Y0Jsa0ZhY3RvciA9ICggdWludDhfdCApICggcHhQYXJ0aXRpb24tPnVzQmxrU2l6ZSAvIHB4SU9NYW5hZ2VyLT51c1NlY3RvclNpemUgKTsNCgkJcHhQYXJ0aXRpb24tPnVsVG90YWxTZWN0b3JzID0gKCB1aW50MzJfdCApIEZGX2dldFNob3J0KCBweEJ1ZmZlci0+cHVjQnVmZmVyLCBGRl9GQVRfMTZfVE9UQUxfU0VDVE9SUyApOw0KCQlpZiggcHhQYXJ0aXRpb24tPnVsVG90YWxTZWN0b3JzID09IDAgKQ0KCQl7DQoJCQlweFBhcnRpdGlvbi0+dWxUb3RhbFNlY3RvcnMgPSBGRl9nZXRMb25nKCBweEJ1ZmZlci0+cHVjQnVmZmVyLCBGRl9GQVRfMzJfVE9UQUxfU0VDVE9SUyApOw0KCQl9DQoNCgkJaWYoIHB4UGFydGl0aW9uLT51bFNlY3RvcnNQZXJGQVQgPT0gMCApDQoJCXsJLyogRkFUMzIgKi8NCgkJCXB4UGFydGl0aW9uLT51bFNlY3RvcnNQZXJGQVQgPSBGRl9nZXRMb25nKCBweEJ1ZmZlci0+cHVjQnVmZmVyLCBGRl9GQVRfMzJfU0VDVE9SU19QRVJfRkFUICk7DQoJCQlweFBhcnRpdGlvbi0+dWxSb290RGlyQ2x1c3RlciA9IEZGX2dldExvbmcoIHB4QnVmZmVyLT5wdWNCdWZmZXIsIEZGX0ZBVF9ST09UX0RJUl9DTFVTVEVSICk7DQoJCQltZW1jcHkoIHB4UGFydGl0aW9uLT5wY1ZvbHVtZUxhYmVsLCBweEJ1ZmZlci0+cHVjQnVmZmVyICsgRkZfRkFUXzMyX1ZPTF9MQUJFTCwgc2l6ZW9mKCBweFBhcnRpdGlvbi0+cGNWb2x1bWVMYWJlbCApIC0gMSApOw0KCQl9DQoJCWVsc2UNCgkJewkvKiBGQVQxNiAqLw0KCQkJcHhQYXJ0aXRpb24tPnVsUm9vdERpckNsdXN0ZXIgPSAxOwkJCS8qIDFzdCBDbHVzdGVyIGlzIFJvb3REaXIhICovDQoJCQltZW1jcHkoIHB4UGFydGl0aW9uLT5wY1ZvbHVtZUxhYmVsLCBweEJ1ZmZlci0+cHVjQnVmZmVyICsgRkZfRkFUXzE2X1ZPTF9MQUJFTCwgc2l6ZW9mKCBweFBhcnRpdGlvbi0+cGNWb2x1bWVMYWJlbCApIC0gMSk7DQoJCX0NCg0KCQlweFBhcnRpdGlvbi0+dWxDbHVzdGVyQmVnaW5MQkEgPSBweFBhcnRpdGlvbi0+dWxGQVRCZWdpbkxCQSArICggcHhQYXJ0aXRpb24tPnVjTnVtRkFUUyAqIHB4UGFydGl0aW9uLT51bFNlY3RvcnNQZXJGQVQgKTsNCgkJI2lmKCBmZmNvbmZpZ1dSSVRFX0ZSRUVfQ09VTlQgIT0gMCApDQoJCXsNCgkJCXB4UGFydGl0aW9uLT51bEZTSW5mb0xCQSA9IHB4UGFydGl0aW9uLT51bEJlZ2luTEJBICsgRkZfZ2V0U2hvcnQoIHB4QnVmZmVyLT5wdWNCdWZmZXIsIDQ4ICk7DQoJCX0NCgkJI2VuZGlmDQoJCUZGX1JlbGVhc2VCdWZmZXIoIHB4SU9NYW5hZ2VyLCBweEJ1ZmZlciApOwkvKiBSZWxlYXNlIHRoZSBidWZmZXIgZmluYWxseSEgKi8NCgkJaWYoIHB4UGFydGl0aW9uLT51c0Jsa1NpemUgPT0gMCApDQoJCXsNCgkJCXhFcnJvciA9IEZGX0VSUl9JT01BTl9JTlZBTElEX0ZPUk1BVCB8IEZGX01PVU5UOw0KCQkJYnJlYWs7DQoJCX0NCg0KCQlyb290RW50cnlDb3VudCA9IEZGX2dldFNob3J0KCBweEJ1ZmZlci0+cHVjQnVmZmVyLCBGRl9GQVRfUk9PVF9FTlRSWV9DT1VOVCApOw0KCQlweFBhcnRpdGlvbi0+dWxSb290RGlyU2VjdG9ycyA9ICggKCByb290RW50cnlDb3VudCAqIDMyICkgKyBweFBhcnRpdGlvbi0+dXNCbGtTaXplIC0gMSApIC8gcHhQYXJ0aXRpb24tPnVzQmxrU2l6ZTsNCgkJcHhQYXJ0aXRpb24tPnVsRmlyc3REYXRhU2VjdG9yID0gcHhQYXJ0aXRpb24tPnVsQ2x1c3RlckJlZ2luTEJBICsgcHhQYXJ0aXRpb24tPnVsUm9vdERpclNlY3RvcnM7DQoJCXB4UGFydGl0aW9uLT51bERhdGFTZWN0b3JzID0gcHhQYXJ0aXRpb24tPnVsVG90YWxTZWN0b3JzIC0gKCBweFBhcnRpdGlvbi0+dXNSZXNlcnZlZFNlY3RvcnMgKyAoIHB4UGFydGl0aW9uLT51Y051bUZBVFMgKiBweFBhcnRpdGlvbi0+dWxTZWN0b3JzUGVyRkFUICkgKyBweFBhcnRpdGlvbi0+dWxSb290RGlyU2VjdG9ycyApOw0KDQoJCS8qDQoJCSAqIEhUOiBmYXQzMkluZGljYXRvciBub3QgeWV0IHVzZWQNCgkJICogQXMgdGhlcmUgaXMgc28gbXVjaCBjb25mdXNpb24gYWJvdXQgdGhlIEZBVCB0eXBlcw0KCQkgKiBJIHdhcyB0aGlua2luZyBvZiBjb2xsZWN0aW5nIGluZGljYXRpb25zIGZvciBlaXRoZXIgRkFUMTIsIDE2IG9yIDMyDQoJCSAqLw0KDQoJCS8qDQoJCWlmKCBGRl9nZXRTaG9ydCggcHhCdWZmZXItPnB1Y0J1ZmZlciwgRkZfRkFUX0VYVF9CT09UX1NJR05BVFVSRSApID09IDB4MjkgKQ0KCQkJZmF0MzJJbmRpY2F0b3IrKzsNCgkJaWYoIHJvb3RFbnRyeUNvdW50ID09IDAgKQ0KCQkJZmF0MzJJbmRpY2F0b3IrKzsNCgkJKi8NCgkJaWYoIHB4UGFydGl0aW9uLT51bFNlY3RvcnNQZXJDbHVzdGVyID09IDAgKQ0KCQl7DQoJCQl4RXJyb3IgPSBGRl9FUlJfSU9NQU5fSU5WQUxJRF9GT1JNQVQgfCBGRl9NT1VOVDsNCgkJCWJyZWFrOw0KCQl9DQoNCgkJcHhQYXJ0aXRpb24tPnVsTnVtQ2x1c3RlcnMgPSBweFBhcnRpdGlvbi0+dWxEYXRhU2VjdG9ycyAvIHB4UGFydGl0aW9uLT51bFNlY3RvcnNQZXJDbHVzdGVyOw0KDQoJCXhFcnJvciA9IHBydkRldGVybWluZUZhdFR5cGUoIHB4SU9NYW5hZ2VyICk7DQoJCWlmKCBGRl9pc0VSUiggeEVycm9yICkgKQ0KCQl7DQoJCQlicmVhazsNCgkJfQ0KDQoJCWlmKCAhcm9vdEVudHJ5Q291bnQgJiYgcHhQYXJ0aXRpb24tPnVjVHlwZSAhPSBGRl9UX0ZBVDMyICkNCgkJew0KCQkJRkZfUFJJTlRGKCAiTm8gcm9vdCBkaXIsIG11c3QgYmUgYSBGQVQzMlxuIiApOw0KCQkJcHhQYXJ0aXRpb24tPnVjVHlwZSA9IEZGX1RfRkFUMzI7DQoJCX0NCg0KCQlweFBhcnRpdGlvbi0+dWNQYXJ0aXRpb25Nb3VudGVkID0gcGRUUlVFOw0KCQlweFBhcnRpdGlvbi0+dWxMYXN0RnJlZUNsdXN0ZXIgPSAwOw0KCQkjaWYoIGZmY29uZmlnTU9VTlRfRklORF9GUkVFICE9IDAgKQ0KCQl7DQoJCQlGRl9Mb2NrRkFUKCBweElPTWFuYWdlciApOw0KCQkJew0KCQkJCS8qIFRoZSBwYXJhbWV0ZXIgJ3BkRkFMU0UnIG1lYW5zOiBkbyBub3QgY2xhaW0gdGhlIGZyZWUgY2x1c3RlciBmb3VuZC4gKi8NCgkJCQlweFBhcnRpdGlvbi0+dWxMYXN0RnJlZUNsdXN0ZXIgPSBGRl9GaW5kRnJlZUNsdXN0ZXIoIHB4SU9NYW5hZ2VyLCAmeEVycm9yLCBwZEZBTFNFICk7DQoJCQl9DQoJCQlGRl9VbmxvY2tGQVQoIHB4SU9NYW5hZ2VyICk7DQoNCgkJCWlmKCBGRl9pc0VSUiggeEVycm9yICkgKQ0KCQkJew0KCQkJCWlmKCBGRl9HRVRFUlJPUiggeEVycm9yICkgPT0gRkZfRVJSX0lPTUFOX05PVF9FTk9VR0hfRlJFRV9TUEFDRSApDQoJCQkJew0KCQkJCQlweFBhcnRpdGlvbi0+dWxMYXN0RnJlZUNsdXN0ZXIgPSAwOw0KCQkJCX0NCgkJCQllbHNlDQoJCQkJew0KCQkJCQlicmVhazsNCgkJCQl9DQoJCQl9DQoNCgkJCXB4UGFydGl0aW9uLT51bEZyZWVDbHVzdGVyQ291bnQgPSBGRl9Db3VudEZyZWVDbHVzdGVycyggcHhJT01hbmFnZXIsICZ4RXJyb3IgKTsNCgkJCWlmKCBGRl9pc0VSUiggeEVycm9yICkgKQ0KCQkJew0KCQkJCWJyZWFrOw0KCQkJfQ0KCQl9DQoJCSNlbHNlDQoJCXsNCgkJCXB4UGFydGl0aW9uLT51bEZyZWVDbHVzdGVyQ291bnQgPSAwOw0KCQl9DQoJCSNlbmRpZgkvKiBmZmNvbmZpZ01PVU5UX0ZJTkRfRlJFRSAqLw0KCX0NCgl3aGlsZSggcGRGQUxTRSApOw0KDQoJaWYoIEZGX2lzRVJSKCB4RXJyb3IgKSA9PSBwZEZBTFNFICkNCgl7DQoJCXhFcnJvciA9IDA7DQoJfQ0KDQoJcmV0dXJuIHhFcnJvcjsNCn0JLyogRkZfTW91bnQoKSAqLw0KLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovDQoNCi8qKg0KICoJQHByaXZhdGUNCiAqCUBicmllZgkJQ2hlY2tzIHRoZSBjYWNoZSBmb3IgQWN0aXZlIEhhbmRsZXMNCiAqDQogKglAcGFyYW0JCXB4SU9NYW5hZ2VyIEZGX0lPTWFuYWdlcl90IE9iamVjdC4NCiAqDQogKglAUmV0dXJuCQlwZFRSVUUgaWYgYW4gYWN0aXZlIGhhbmRsZSBpcyBmb3VuZCwgZWxzZSBwZEZBTFNFLg0KICoNCiAqCUBwcmUJCVRoaXMgZnVuY3Rpb24gbXVzdCBiZSB3cmFwcGVkIHdpdGggdGhlIGNhY2hlIGhhbmRsaW5nIHNlbWFwaG9yZS4NCiAqKi8NCnN0YXRpYyBCYXNlVHlwZV90IHBydkhhc0FjdGl2ZUhhbmRsZXMoIEZGX0lPTWFuYWdlcl90ICpweElPTWFuYWdlciApDQp7DQpCYXNlVHlwZV90IHhSZXN1bHQ7DQpGRl9CdWZmZXJfdCAqcHhCdWZmZXIgPSBweElPTWFuYWdlci0+cHhCdWZmZXJzOw0KRkZfQnVmZmVyX3QgKnB4TGFzdEJ1ZmZlciA9IHB4QnVmZmVyICsgcHhJT01hbmFnZXItPnVzQ2FjaGVTaXplOw0KDQoJZm9yKCA7IDsgKQ0KCXsNCgkJaWYoIHB4QnVmZmVyLT51c051bUhhbmRsZXMgKQ0KCQl7DQoJCQl4UmVzdWx0ID0gcGRUUlVFOw0KCQkJYnJlYWs7DQoJCX0NCgkJcHhCdWZmZXIrKzsNCgkJaWYoIHB4QnVmZmVyID09IHB4TGFzdEJ1ZmZlciApDQoJCXsNCgkJCXhSZXN1bHQgPSBwZEZBTFNFOw0KCQkJYnJlYWs7DQoJCX0NCgl9DQoNCglyZXR1cm4geFJlc3VsdDsNCn0JLyogcHJ2SGFzQWN0aXZlSGFuZGxlcygpICovDQovKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8NCg0KLyoqDQogKglAcHVibGljDQogKglAYnJpZWYJVW5tb3VudHMgdGhlIGFjdGl2ZSBwYXJ0aXRpb24uDQogKg0KICoJQHBhcmFtCXB4SU9NYW5hZ2VyCUZGX0lPTWFuYWdlcl90IE9iamVjdC4NCiAqDQogKglAUmV0dXJuIEZGX0VSUl9OT05FIG9uIHN1Y2Nlc3MuDQogKiovDQpGRl9FcnJvcl90IEZGX1VubW91bnQoIEZGX0Rpc2tfdCAqcHhEaXNrICkNCnsNCkZGX0Vycm9yX3QgeEVycm9yID0gRkZfRVJSX05PTkU7DQpGRl9JT01hbmFnZXJfdCAqcHhJT01hbmFnZXI7DQoNCiNpZiggZmZjb25maWdNSVJST1JfRkFUU19VTU9VTlQgIT0gMCApDQoJVUJhc2VUeXBlX3QgdXhJbmRleCwgeTsNCglGRl9CdWZmZXJfdAkqcHhCdWZmZXI7DQojZW5kaWYNCg0KCWlmKCBweERpc2stPnB4SU9NYW5hZ2VyID09IE5VTEwgKQ0KCXsNCgkJeEVycm9yID0gRkZfRVJSX05VTExfUE9JTlRFUiB8IEZGX1VOTU9VTlQ7DQoJfQ0KCWVsc2UgaWYoIHB4RGlzay0+cHhJT01hbmFnZXItPnhQYXJ0aXRpb24udWNQYXJ0aXRpb25Nb3VudGVkID09IDAgKQ0KCXsNCgkJeEVycm9yID0gRkZfRVJSX05PTkU7DQoJfQ0KCWVsc2UNCgl7DQoJCXB4SU9NYW5hZ2VyID0gcHhEaXNrLT5weElPTWFuYWdlcjsNCgkJRkZfUGVuZFNlbWFwaG9yZSggcHhJT01hbmFnZXItPnB2U2VtYXBob3JlICk7CQkvKiBFbnN1cmUgdGhhdCB0aGVyZSBhcmUgbm8gRmlsZSBIYW5kbGVzICovDQoJCXsNCgkJCWlmKCBwcnZIYXNBY3RpdmVIYW5kbGVzKCBweElPTWFuYWdlciApICE9IDAgKQ0KCQkJew0KCQkJCS8qIEFjdGl2ZSBoYW5kbGVzIGZvdW5kIG9uIHRoZSBjYWNoZS4gKi8NCgkJCQl4RXJyb3IgPSBGRl9FUlJfSU9NQU5fQUNUSVZFX0hBTkRMRVMgfCBGRl9VTk1PVU5UOw0KCQkJfQ0KCQkJZWxzZSBpZiggcHhJT01hbmFnZXItPkZpcnN0RmlsZSAhPSBOVUxMICkNCgkJCXsNCgkJCQkvKiBPcGVuIGZpbGVzIGluIHRoaXMgcGFydGl0aW9uLiAqLw0KCQkJCXhFcnJvciA9IEZGX0VSUl9JT01BTl9BQ1RJVkVfSEFORExFUyB8IEZGX1VOTU9VTlQ7DQoJCQl9DQoJCQllbHNlDQoJCQl7DQoJCQkJLyogUmVsZWFzZSBTZW1hcGhvcmUgdG8gY2FsbCB0aGlzIGZ1bmN0aW9uISAqLw0KCQkJCUZGX1JlbGVhc2VTZW1hcGhvcmUoIHB4SU9NYW5hZ2VyLT5wdlNlbWFwaG9yZSApOw0KCQkJCS8qIEZsdXNoIGFueSB1bndyaXR0ZW4gc2VjdG9ycyB0byBkaXNrLiAqLw0KCQkJCXhFcnJvciA9IEZGX0ZsdXNoQ2FjaGUoIHB4SU9NYW5hZ2VyICk7DQoJCQkJLyogUmVjbGFpbSBTZW1hcGhvcmUgKi8NCgkJCQlGRl9QZW5kU2VtYXBob3JlKCBweElPTWFuYWdlci0+cHZTZW1hcGhvcmUgKTsNCg0KCQkJCWlmKCBGRl9pc0VSUiggeEVycm9yICkgPT0gcGRGQUxTRSApDQoJCQkJew0KCQkJCQlweElPTWFuYWdlci0+eFBhcnRpdGlvbi51Y1BhcnRpdGlvbk1vdW50ZWQgPSBwZEZBTFNFOw0KDQoJCQkJCSNpZiggZmZjb25maWdNSVJST1JfRkFUU19VTU9VTlQgIT0gMCApDQoJCQkJCXsNCgkJCQkJCUZGX1JlbGVhc2VTZW1hcGhvcmUoIHB4SU9NYW5hZ2VyLT5wdlNlbWFwaG9yZSApOw0KCQkJCQkJZm9yKCB1eEluZGV4ID0gMDsgdXhJbmRleCA8IHB4SU9NYW5hZ2VyLT54UGFydGl0aW9uLnVsU2VjdG9yc1BlckZBVDsgdXhJbmRleCsrICkNCgkJCQkJCXsNCgkJCQkJCQlweEJ1ZmZlciA9IEZGX0dldEJ1ZmZlciggcHhJT01hbmFnZXIsIHB4SU9NYW5hZ2VyLT54UGFydGl0aW9uLnVsRkFUQmVnaW5MQkEgKyB1eEluZGV4LCBGRl9NT0RFX1JFQUQgKTsNCgkJCQkJCQlpZiggIXB4QnVmZmVyICkNCgkJCQkJCQl7DQoJCQkJCQkJCXhFcnJvciA9IEZGX0VSUl9ERVZJQ0VfRFJJVkVSX0ZBSUxFRCB8IEZGX1VOTU9VTlQ7DQoJCQkJCQkJCWJyZWFrOw0KCQkJCQkJCX0NCgkJCQkJCQlmb3IoIHkgPSAwOyB5IDwgcHhJT01hbmFnZXItPnhQYXJ0aXRpb24udWNOdW1GQVRTOyB5KysgKQ0KCQkJCQkJCXsNCgkJCQkJCQkJRkZfQmxvY2tXcml0ZSggcHhJT01hbmFnZXIsDQoJCQkJCQkJCQlweElPTWFuYWdlci0+eFBhcnRpdGlvbi51bEZBVEJlZ2luTEJBICsgKCB5ICogcHhJT01hbmFnZXItPnhQYXJ0aXRpb24udWxTZWN0b3JzUGVyRkFUICkgKyB1eEluZGV4LCAxLA0KCQkJCQkJCQkJcHhCdWZmZXItPnB1Y0J1ZmZlciwgcGRGQUxTRSApOw0KCQkJCQkJCX0NCgkJCQkJCX0NCgkJCQkJCUZGX1BlbmRTZW1hcGhvcmUoIHB4SU9NYW5hZ2VyLT5wdlNlbWFwaG9yZSApOw0KCQkJCQl9DQoJCQkJCSNlbmRpZg0KCQkJCX0NCgkJCX0NCgkJfQ0KCQlGRl9SZWxlYXNlU2VtYXBob3JlKCBweElPTWFuYWdlci0+cHZTZW1hcGhvcmUgKTsNCgl9DQoNCglyZXR1cm4geEVycm9yOw0KfQkvKiBGRl9Vbm1vdW50KCkgKi8NCi8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLw0KDQpGRl9FcnJvcl90IEZGX0luY3JlYXNlRnJlZUNsdXN0ZXJzKCBGRl9JT01hbmFnZXJfdCAqcHhJT01hbmFnZXIsIHVpbnQzMl90IENvdW50ICkNCnsNCkZGX0Vycm9yX3QgeEVycm9yOw0KDQojaWYoIGZmY29uZmlnV1JJVEVfRlJFRV9DT1VOVCAhPSAwICkNCglGRl9CdWZmZXJfdAkqcHhCdWZmZXI7DQojZW5kaWYNCg0KCWRvDQoJew0KCQkvKiBPcGVuIGEgZG8ge30gd2hpbGUoIHBkRkFMU0UgKSBsb29wIHRvIGFsbG93IHRoZSB1c2Ugb2YgYnJlYWsgc3RhdGVtZW50cy4gKi8NCgkJaWYoIHB4SU9NYW5hZ2VyLT54UGFydGl0aW9uLnVsRnJlZUNsdXN0ZXJDb3VudCA9PSAwdWwgKQ0KCQl7DQoJCQkvKiBBcHBhcmVudGx5IHRoZSBudW1iZXIgb2YgZnJlZSBjbHVzdGVycyBoYXMgbm90IGJlZW4gY2FsY3VsYXRlZCB5ZXQsDQoJCQlvciBubyBmcmVlIGNsdXN0ZXIgd2FzIGF2YWlsYWJsZS4gTm93IGNoZWNrIGl0LiAqLw0KCQkJcHhJT01hbmFnZXItPnhQYXJ0aXRpb24udWxGcmVlQ2x1c3RlckNvdW50ID0gRkZfQ291bnRGcmVlQ2x1c3RlcnMoIHB4SU9NYW5hZ2VyLCAmeEVycm9yICk7DQoJCQlpZiggRkZfaXNFUlIoIHhFcnJvciApICkNCgkJCXsNCgkJCQlicmVhazsNCgkJCX0NCgkJfQ0KCQllbHNlDQoJCXsNCgkJCXhFcnJvciA9IEZGX0VSUl9OT05FOw0KCQkJdGFza0VOVEVSX0NSSVRJQ0FMKCk7DQoJCQl7DQoJCQkJcHhJT01hbmFnZXItPnhQYXJ0aXRpb24udWxGcmVlQ2x1c3RlckNvdW50ICs9IENvdW50Ow0KCQkJfQ0KCQkJdGFza0VYSVRfQ1JJVElDQUwoKTsNCgkJfQ0KDQoJCWlmKCBweElPTWFuYWdlci0+eFBhcnRpdGlvbi51bExhc3RGcmVlQ2x1c3RlciA9PSAwICkNCgkJew0KCQlCYXNlVHlwZV90IHhUYWtlTG9jayA9IEZGX0hhc19Mb2NrKCBweElPTWFuYWdlciwgRkZfRkFUX0xPQ0sgKSA9PSBwZEZBTFNFOw0KDQoJCQlpZiggeFRha2VMb2NrICkNCgkJCXsNCgkJCQlGRl9Mb2NrRkFUKCBweElPTWFuYWdlciApOw0KCQkJfQ0KCQkJLyogRmluZCB0aGUgYW4gYXZhaWxhYmxlIGNsdXN0ZXIuICovDQoJCQlweElPTWFuYWdlci0+eFBhcnRpdGlvbi51bExhc3RGcmVlQ2x1c3RlciA9IEZGX0ZpbmRGcmVlQ2x1c3RlciggcHhJT01hbmFnZXIsICZ4RXJyb3IsIHBkRkFMU0UgKTsNCgkJCWlmKCB4VGFrZUxvY2sgKQ0KCQkJew0KCQkJCUZGX1VubG9ja0ZBVCggcHhJT01hbmFnZXIgKTsNCgkJCX0NCgkJCWlmKCBGRl9pc0VSUiggeEVycm9yICkgKQ0KCQkJew0KCQkJCWJyZWFrOw0KCQkJfQ0KCQl9DQoNCgkJI2lmKCBmZmNvbmZpZ1dSSVRFX0ZSRUVfQ09VTlQgIT0gMCApDQoJCXsNCgkJCS8qIEZBVDMyIHVwZGF0ZXMgdGhlIEZTSU5GTyBzZWN0b3IuICovDQoJCQlpZiggcHhJT01hbmFnZXItPnhQYXJ0aXRpb24udWNUeXBlID09IEZGX1RfRkFUMzIgKQ0KCQkJew0KCQkJCS8qIEZpbmQgdGhlIEZTSU5GTyBzZWN0b3IuICovDQoJCQkJcHhCdWZmZXIgPSBGRl9HZXRCdWZmZXIoIHB4SU9NYW5hZ2VyLCBweElPTWFuYWdlci0+eFBhcnRpdGlvbi51bEZTSW5mb0xCQSwgRkZfTU9ERV9XUklURSApOw0KCQkJCWlmKCBweEJ1ZmZlciA9PSBOVUxMICkNCgkJCQl7DQoJCQkJCXhFcnJvciA9IEZGX0VSUl9ERVZJQ0VfRFJJVkVSX0ZBSUxFRCB8IEZGX0lOQ1JFQVNFRlJFRUNMVVNURVJTOw0KCQkJCX0NCgkJCQllbHNlDQoJCQkJew0KCQkJCXVpbnQzMl90IHVsU2lnbmF0dXJlMTsNCgkJCQl1aW50MzJfdCB1bFNpZ25hdHVyZTI7DQoNCgkJCQkJdWxTaWduYXR1cmUxID0gRkZfZ2V0TG9uZyggcHhCdWZmZXItPnB1Y0J1ZmZlciwgRlNfSU5GT19PRkZTRVRfU0lHTkFUVVJFMV8wMDAgKTsNCgkJCQkJdWxTaWduYXR1cmUyID0gRkZfZ2V0TG9uZyggcHhCdWZmZXItPnB1Y0J1ZmZlciwgRlNfSU5GT19PRkZTRVRfU0lHTkFUVVJFMl80ODQgKTsNCg0KCQkJCQlpZiggKCB1bFNpZ25hdHVyZTEgPT0gRlNfSU5GT19TSUdOQVRVUkUxXzB4NDE2MTUyNTIgKSAmJg0KCQkJCQkJKCB1bFNpZ25hdHVyZTIgPT0gRlNfSU5GT19TSUdOQVRVUkUyXzB4NjE0MTcyNzIgKSApDQoJCQkJCXsNCgkJCQkJCS8qIEZTSU5GTyBzZWN0b3IgbWFnaWMgbnVtYmVycyB3ZSdyZSB2ZXJpZmllZC4gU2FmZSB0byB3cml0ZS4gKi8NCgkJCQkJCUZGX3B1dExvbmcoIHB4QnVmZmVyLT5wdWNCdWZmZXIsIEZTX0lORk9fT0ZGU0VUX0ZSRUVfQ09VTlRfNDg4LCBweElPTWFuYWdlci0+eFBhcnRpdGlvbi51bEZyZWVDbHVzdGVyQ291bnQgKTsNCgkJCQkJCUZGX3B1dExvbmcoIHB4QnVmZmVyLT5wdWNCdWZmZXIsIEZTX0lORk9fT0ZGU0VUX0ZSRUVfQ0xVU1RFUl80OTIsIHB4SU9NYW5hZ2VyLT54UGFydGl0aW9uLnVsTGFzdEZyZWVDbHVzdGVyICk7DQoJCQkJCX0NCgkJCQkJeEVycm9yID0gRkZfUmVsZWFzZUJ1ZmZlciggcHhJT01hbmFnZXIsIHB4QnVmZmVyICk7DQoJCQkJfQ0KCQkJfQ0KCQl9DQoJCSNlbmRpZg0KCX0NCgl3aGlsZSggcGRGQUxTRSApOw0KDQoJcmV0dXJuIHhFcnJvcjsNCn0JLyogRkZfSW5jcmVhc2VGcmVlQ2x1c3RlcnMoKSAqLw0KLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovDQoNCkZGX0Vycm9yX3QgRkZfRGVjcmVhc2VGcmVlQ2x1c3RlcnMoIEZGX0lPTWFuYWdlcl90ICpweElPTWFuYWdlciwgdWludDMyX3QgQ291bnQgKQ0Kew0KRkZfRXJyb3JfdAl4RXJyb3IgPSBGRl9FUlJfTk9ORTsNCiNpZiggZmZjb25maWdXUklURV9GUkVFX0NPVU5UICE9IDAgKQ0KCUZGX0J1ZmZlcl90CSpweEJ1ZmZlcjsNCiNlbmRpZg0KDQoJaWYoIHB4SU9NYW5hZ2VyLT54UGFydGl0aW9uLnVsRnJlZUNsdXN0ZXJDb3VudCA9PSAwdWwgKQ0KCXsNCgkJcHhJT01hbmFnZXItPnhQYXJ0aXRpb24udWxGcmVlQ2x1c3RlckNvdW50ID0gRkZfQ291bnRGcmVlQ2x1c3RlcnMoIHB4SU9NYW5hZ2VyLCAmeEVycm9yICk7DQoJfQ0KCWVsc2UNCgl7DQoJCXRhc2tFTlRFUl9DUklUSUNBTCgpOw0KCQlweElPTWFuYWdlci0+eFBhcnRpdGlvbi51bEZyZWVDbHVzdGVyQ291bnQgLT0gQ291bnQ7DQoJCXRhc2tFWElUX0NSSVRJQ0FMKCk7DQoJfQ0KDQoJaWYoIEZGX2lzRVJSKCB4RXJyb3IgKSA9PSBwZEZBTFNFICkNCgl7DQoJCWlmKCBweElPTWFuYWdlci0+eFBhcnRpdGlvbi51bExhc3RGcmVlQ2x1c3RlciA9PSAwICkNCgkJew0KCQkJRkZfTG9ja0ZBVCggcHhJT01hbmFnZXIgKTsNCgkJCXsNCgkJCQlweElPTWFuYWdlci0+eFBhcnRpdGlvbi51bExhc3RGcmVlQ2x1c3RlciA9IEZGX0ZpbmRGcmVlQ2x1c3RlciggcHhJT01hbmFnZXIsICZ4RXJyb3IsIHBkRkFMU0UgKTsNCgkJCX0NCgkJCUZGX1VubG9ja0ZBVCggcHhJT01hbmFnZXIgKTsNCgkJfQ0KCX0NCglpZiggRkZfaXNFUlIoIHhFcnJvciApID09IHBkRkFMU0UgKQ0KCXsNCgkJI2lmKCBmZmNvbmZpZ1dSSVRFX0ZSRUVfQ09VTlQgIT0gMCApDQoJCXsNCgkJCS8qIEZBVDMyIHVwZGF0ZSB0aGUgRlNJTkZPIHNlY3Rvci4gKi8NCgkJCWlmKCBweElPTWFuYWdlci0+eFBhcnRpdGlvbi51Y1R5cGUgPT0gRkZfVF9GQVQzMiApDQoJCQl7DQoJCQkJLyogRmluZCB0aGUgRlNJTkZPIHNlY3Rvci4gKi8NCgkJCQlweEJ1ZmZlciA9IEZGX0dldEJ1ZmZlciggcHhJT01hbmFnZXIsIHB4SU9NYW5hZ2VyLT54UGFydGl0aW9uLnVsRlNJbmZvTEJBLCBGRl9NT0RFX1dSSVRFICk7DQoJCQkJaWYoIHB4QnVmZmVyID09IE5VTEwgKQ0KCQkJCXsNCgkJCQkJeEVycm9yID0gRkZfRVJSX0RFVklDRV9EUklWRVJfRkFJTEVEIHwgRkZfREVDUkVBU0VGUkVFQ0xVU1RFUlM7DQoJCQkJfQ0KCQkJCWVsc2UNCgkJCQl7DQoJCQkJCWlmKCAoIEZGX2dldExvbmcoIHB4QnVmZmVyLT5wdWNCdWZmZXIsIEZTX0lORk9fT0ZGU0VUX1NJR05BVFVSRTFfMDAwICkgPT0gRlNfSU5GT19TSUdOQVRVUkUxXzB4NDE2MTUyNTIgKSAmJg0KCQkJCQkJKCBGRl9nZXRMb25nKCBweEJ1ZmZlci0+cHVjQnVmZmVyLCBGU19JTkZPX09GRlNFVF9TSUdOQVRVUkUyXzQ4NCApID09IEZTX0lORk9fU0lHTkFUVVJFMl8weDYxNDE3MjcyICkgKQ0KCQkJCQl7DQoJCQkJCQkvKiBGU0lORk8gc2VjdG9yIG1hZ2ljIG51bXMgd2UncmUgdmVyaWZpZWQuIFNhZmUgdG8gd3JpdGUuICovDQoJCQkJCQlGRl9wdXRMb25nKCBweEJ1ZmZlci0+cHVjQnVmZmVyLCBGU19JTkZPX09GRlNFVF9GUkVFX0NPVU5UXzQ4OCwgcHhJT01hbmFnZXItPnhQYXJ0aXRpb24udWxGcmVlQ2x1c3RlckNvdW50ICk7DQoJCQkJCQlGRl9wdXRMb25nKCBweEJ1ZmZlci0+cHVjQnVmZmVyLCBGU19JTkZPX09GRlNFVF9GUkVFX0NMVVNURVJfNDkyLCBweElPTWFuYWdlci0+eFBhcnRpdGlvbi51bExhc3RGcmVlQ2x1c3RlciApOw0KCQkJCQl9DQoJCQkJCXhFcnJvciA9IEZGX1JlbGVhc2VCdWZmZXIoIHB4SU9NYW5hZ2VyLCBweEJ1ZmZlciApOw0KCQkJCX0NCgkJCX0NCgkJfQ0KCQkjZW5kaWYNCgl9DQoNCglyZXR1cm4geEVycm9yOw0KfQkvKiBGRl9EZWNyZWFzZUZyZWVDbHVzdGVycygpICovDQovKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8NCg0KLyoqDQogKglAYnJpZWYJUmV0dXJucyB0aGUgQmxvY2stc2l6ZSBvZiBhIG1vdW50ZWQgUGFydGl0aW9uDQogKg0KICoJVGhlIHB1cnBvc2Ugb2YgdGhpcyBmdW5jdGlvbiBpcyB0byBwcm92aWRlIEFQSSBhY2Nlc3MgdG8gaW5mb3JtYXRpb24NCiAqCXRoYXQgbWlnaHQgYmUgdXNlZnVsIGluIHNwZWNpYWwgY2FzZXMuIExpa2UgVVNCIHN0aWNrcyB0aGF0IHJlcXVpcmUgYSBzZWN0b3INCiAqCWtub2NraW5nIHNlcXVlbmNlIGZvciBzZWN1cml0eS4gQWZ0ZXIgdGhlIHNlY3RvciBrbm9jaywgc29tZSBzZWN1cmUgVVNCDQogKglzdGlja3MgdGhlbiBwcmVzZW50IGEgZGlmZmVyZW50IEJsb2NrU2l6ZS4NCiAqDQogKglAcGFyYW0JcHhJT01hbmFnZXIJCUZGX0lPTWFuYWdlcl90IE9iamVjdCByZXR1cm5lZCBmcm9tIEZGX0NyZWF0ZUlPTWFuZ2VyKCkNCiAqDQogKglAUmV0dXJuCVRoZSBibG9ja3NpemUgb2YgdGhlIHBhcnRpdGlvbi4gQSB2YWx1ZSBsZXNzIHRoYW4gMCB3aGVuIGFuIGVycm9yIG9jY3Vycy4NCiAqCUBSZXR1cm4JQW55IG5lZ2F0aXZlIHZhbHVlIGNhbiBiZSBjYXN0IHRvIHRoZSBGRl9FcnJvcl90IHR5cGUuDQogKiovDQppbnQzMl90IEZGX0dldFBhcnRpdGlvbkJsb2NrU2l6ZSggRkZfSU9NYW5hZ2VyX3QgKnB4SU9NYW5hZ2VyICkNCnsNCmludDMyX3QgbFJldHVybjsNCglpZiggcHhJT01hbmFnZXIgKQ0KCXsNCgkJbFJldHVybiA9ICggaW50MzJfdCApIHB4SU9NYW5hZ2VyLT54UGFydGl0aW9uLnVzQmxrU2l6ZTsNCgl9DQoJZWxzZQ0KCXsNCgkJbFJldHVybiA9IEZGX0VSUl9OVUxMX1BPSU5URVIgfCBGRl9HRVRQQVJUSVRJT05CTE9DS1NJWkU7DQoJfQ0KDQoJcmV0dXJuIGxSZXR1cm47DQp9CS8qIEZGX0dldFBhcnRpdGlvbkJsb2NrU2l6ZSgpICovDQovKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8NCg0KI2lmKCBmZmNvbmZpZzY0X05VTV9TVVBQT1JUICE9IDAgKQ0KDQoJLyoqDQoJICoJQGJyaWVmCVJldHVybnMgdGhlIG51bWJlciBvZiBieXRlcyBjb250YWluZWQgd2l0aGluIHRoZSBtb3VudGVkIHBhcnRpdGlvbiBvciB2b2x1bWUuDQoJICoNCgkgKglAcGFyYW0JcHhJT01hbmFnZXIJCUZGX0lPTWFuYWdlcl90IE9iamVjdCByZXR1cm5lZCBmcm9tIEZGX0NyZWF0ZUlPTWFuZ2VyKCkNCgkgKg0KCSAqCUBSZXR1cm4gVGhlIHRvdGFsIG51bWJlciBvZiBieXRlcyB0aGF0IHRoZSBtb3VudGVkIHBhcnRpdGlvbiBvciB2b2x1bWUgY29udGFpbnMuDQoJICoNCgkgKiovDQoJdWludDY0X3QgRkZfR2V0Vm9sdW1lU2l6ZSggRkZfSU9NYW5hZ2VyX3QgKnB4SU9NYW5hZ2VyICkNCgl7DQoJdWludDY0X3QgdWxsUmVzdWx0Ow0KDQoJCWlmKCBweElPTWFuYWdlciApDQoJCXsNCgkJCXVpbnQzMl90IFRvdGFsQ2x1c3RlcnMgPSAoIHB4SU9NYW5hZ2VyLT54UGFydGl0aW9uLnVsRGF0YVNlY3RvcnMgLyBweElPTWFuYWdlci0+eFBhcnRpdGlvbi51bFNlY3RvcnNQZXJDbHVzdGVyICk7DQoJCQl1bGxSZXN1bHQgPSAoIHVpbnQ2NF90ICkNCgkJCQkoDQoJCQkJCSggdWludDY0X3QgKSBUb3RhbENsdXN0ZXJzICogKCB1aW50NjRfdCApDQoJCQkJCQkoICggdWludDY0X3QgKSBweElPTWFuYWdlci0+eFBhcnRpdGlvbi51bFNlY3RvcnNQZXJDbHVzdGVyICogKCB1aW50NjRfdCApIHB4SU9NYW5hZ2VyLT54UGFydGl0aW9uLnVzQmxrU2l6ZSApDQoJCQkJKTsNCgkJfQ0KCQllbHNlDQoJCXsNCgkJCXVsbFJlc3VsdCA9IDBVTEw7DQoJCX0NCg0KCQlyZXR1cm4gdWxsUmVzdWx0Ow0KCX0JLyogRkZfR2V0Vm9sdW1lU2l6ZSgpICovDQojZWxzZQ0KCXVpbnQzMl90IEZGX0dldFZvbHVtZVNpemUoIEZGX0lPTWFuYWdlcl90ICpweElPTWFuYWdlciApDQoJew0KCXVpbnQzMl90IHVsUmVzdWx0Ow0KCQlpZiggcHhJT01hbmFnZXIgKQ0KCQl7DQoJCQl1aW50MzJfdAlUb3RhbENsdXN0ZXJzID0gcHhJT01hbmFnZXItPnhQYXJ0aXRpb24udWxEYXRhU2VjdG9ycyAvIHB4SU9NYW5hZ2VyLT54UGFydGl0aW9uLnVsU2VjdG9yc1BlckNsdXN0ZXI7DQoJCQl1bFJlc3VsdCA9ICggdWludDMyX3QgKSAoIFRvdGFsQ2x1c3RlcnMgKiAoIHB4SU9NYW5hZ2VyLT54UGFydGl0aW9uLnVsU2VjdG9yc1BlckNsdXN0ZXIgKiBweElPTWFuYWdlci0+eFBhcnRpdGlvbi51c0Jsa1NpemUgKSApOw0KCQl9DQoJCWVsc2UNCgkJew0KCQkJdWxSZXN1bHQgPSAwVUw7DQoJCX0NCg0KCQlyZXR1cm4gdWxSZXN1bHQ7DQoJfQkvKiBGRl9HZXRWb2x1bWVTaXplKCkgKi8NCiNlbmRpZg0KLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovDQo=