LyogUHJvY2VzcyBkZWNsYXJhdGlvbnMgYW5kIHZhcmlhYmxlcyBmb3IgQysrIGNvbXBpbGVyLgogICBDb3B5cmlnaHQgKEMpIDE5ODgsIDE5OTIsIDE5OTMsIDE5OTQsIDE5OTUsIDE5OTYsIDE5OTcsIDE5OTgsIDE5OTksIDIwMDAsCiAgIDIwMDEsIDIwMDIsIDIwMDMsIDIwMDQsIDIwMDUgIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwgSW5jLgogICBDb250cmlidXRlZCBieSBNaWNoYWVsIFRpZW1hbm4gKHRpZW1hbm5AY3lnbnVzLmNvbSkKClRoaXMgZmlsZSBpcyBwYXJ0IG9mIEdDQy4KCkdDQyBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5Cml0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5CnRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlciB2ZXJzaW9uIDIsIG9yIChhdCB5b3VyIG9wdGlvbikKYW55IGxhdGVyIHZlcnNpb24uCgpHQ0MgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwKYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YKTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZQpHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLgoKWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKYWxvbmcgd2l0aCBHQ0M7IHNlZSB0aGUgZmlsZSBDT1BZSU5HLiAgSWYgbm90LCB3cml0ZSB0bwp0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCA1OSBUZW1wbGUgUGxhY2UgLSBTdWl0ZSAzMzAsCkJvc3RvbiwgTUEgMDIxMTEtMTMwNywgVVNBLiAgKi8KCgovKiBQcm9jZXNzIGRlY2xhcmF0aW9ucyBhbmQgc3ltYm9sIGxvb2t1cCBmb3IgQysrIGZyb250IGVuZC4KICAgQWxzbyBjb25zdHJ1Y3RzIHR5cGVzOyB0aGUgc3RhbmRhcmQgc2NhbGFyIHR5cGVzIGF0IGluaXRpYWxpemF0aW9uLAogICBhbmQgc3RydWN0dXJlLCB1bmlvbiwgYXJyYXkgYW5kIGVudW0gdHlwZXMgd2hlbiB0aGV5IGFyZSBkZWNsYXJlZC4gICovCgovKiA/Pz8gbm90IGFsbCBkZWNsIG5vZGVzIGFyZSBnaXZlbiB0aGUgbW9zdCB1c2VmdWwgcG9zc2libGUKICAgbGluZSBudW1iZXJzLiAgRm9yIGV4YW1wbGUsIHRoZSBDT05TVF9ERUNMcyBmb3IgZW51bSB2YWx1ZXMuICAqLwoKI2luY2x1ZGUgImNvbmZpZy5oIgojaW5jbHVkZSAic3lzdGVtLmgiCiNpbmNsdWRlICJjb3JldHlwZXMuaCIKI2luY2x1ZGUgInRtLmgiCiNpbmNsdWRlICJ0cmVlLmgiCiNpbmNsdWRlICJydGwuaCIKI2luY2x1ZGUgImV4cHIuaCIKI2luY2x1ZGUgImZsYWdzLmgiCiNpbmNsdWRlICJjcC10cmVlLmgiCiNpbmNsdWRlICJ0cmVlLWlubGluZS5oIgojaW5jbHVkZSAiZGVjbC5oIgojaW5jbHVkZSAib3V0cHV0LmgiCiNpbmNsdWRlICJleGNlcHQuaCIKI2luY2x1ZGUgInRvcGxldi5oIgojaW5jbHVkZSAiaGFzaHRhYi5oIgojaW5jbHVkZSAidG1fcC5oIgojaW5jbHVkZSAidGFyZ2V0LmgiCiNpbmNsdWRlICJjLWNvbW1vbi5oIgojaW5jbHVkZSAiYy1wcmFnbWEuaCIKI2luY2x1ZGUgImRpYWdub3N0aWMuaCIKI2luY2x1ZGUgImRlYnVnLmgiCiNpbmNsdWRlICJ0aW1ldmFyLmgiCiNpbmNsdWRlICJ0cmVlLWZsb3cuaCIKLyogQVBQTEUgTE9DQUwgb3B0aW1pemF0aW9uIHByYWdtYXMgMzEyNDIzNS8zNDIwMjQyICovCiNpbmNsdWRlICJvcHRzLmgiCgpzdGF0aWMgdHJlZSBncm9rcGFybXMgKGNwX3BhcmFtZXRlcl9kZWNsYXJhdG9yICosIHRyZWUgKik7CnN0YXRpYyBjb25zdCBjaGFyICpyZWRlY2xhcmF0aW9uX2Vycm9yX21lc3NhZ2UgKHRyZWUsIHRyZWUpOwoKc3RhdGljIGludCBkZWNsX2p1bXBfdW5zYWZlICh0cmVlKTsKc3RhdGljIHZvaWQgcmVxdWlyZV9jb21wbGV0ZV90eXBlc19mb3JfcGFybXMgKHRyZWUpOwpzdGF0aWMgaW50IGFtYmlfb3BfcCAoZW51bSB0cmVlX2NvZGUpOwpzdGF0aWMgaW50IHVuYXJ5X29wX3AgKGVudW0gdHJlZV9jb2RlKTsKc3RhdGljIHZvaWQgcHVzaF9sb2NhbF9uYW1lICh0cmVlKTsKc3RhdGljIHRyZWUgZ3Jva19yZWZlcmVuY2VfaW5pdCAodHJlZSwgdHJlZSwgdHJlZSwgdHJlZSAqKTsKc3RhdGljIHRyZWUgZ3Jva3ZhcmRlY2wgKHRyZWUsIHRyZWUsIGNvbnN0IGNwX2RlY2xfc3BlY2lmaWVyX3NlcSAqLAoJCQkgaW50LCBpbnQsIHRyZWUpOwpzdGF0aWMgdm9pZCByZWNvcmRfdW5rbm93bl90eXBlICh0cmVlLCBjb25zdCBjaGFyICopOwpzdGF0aWMgdHJlZSBidWlsdGluX2Z1bmN0aW9uXzEgKGNvbnN0IGNoYXIgKiwgdHJlZSwgdHJlZSwKCQkJCWVudW0gYnVpbHRfaW5fZnVuY3Rpb24gY29kZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbnVtIGJ1aWx0X2luX2NsYXNzIGNsLCBjb25zdCBjaGFyICosCgkJCQl0cmVlKTsKc3RhdGljIHRyZWUgYnVpbGRfbGlicmFyeV9mbl8xICh0cmVlLCBlbnVtIHRyZWVfY29kZSwgdHJlZSk7CnN0YXRpYyBpbnQgbWVtYmVyX2Z1bmN0aW9uX29yX2Vsc2UgKHRyZWUsIHRyZWUsIGVudW0gb3ZlcmxvYWRfZmxhZ3MpOwpzdGF0aWMgdm9pZCBiYWRfc3BlY2lmaWVycyAodHJlZSwgY29uc3QgY2hhciAqLCBpbnQsIGludCwgaW50LCBpbnQsCgkJCSAgICBpbnQpOwpzdGF0aWMgdm9pZCBjaGVja19mb3JfdW5pbml0aWFsaXplZF9jb25zdF92YXIgKHRyZWUpOwpzdGF0aWMgaGFzaHZhbF90IHR5cGVuYW1lX2hhc2ggKGNvbnN0IHZvaWQgKik7CnN0YXRpYyBpbnQgdHlwZW5hbWVfY29tcGFyZSAoY29uc3Qgdm9pZCAqLCBjb25zdCB2b2lkICopOwpzdGF0aWMgdHJlZSBsb2NhbF92YXJpYWJsZV9wX3dhbGtmbiAodHJlZSAqLCBpbnQgKiwgdm9pZCAqKTsKc3RhdGljIHRyZWUgcmVjb3JkX2J1aWx0aW5famF2YV90eXBlIChjb25zdCBjaGFyICosIGludCk7CnN0YXRpYyBjb25zdCBjaGFyICp0YWdfbmFtZSAoZW51bSB0YWdfdHlwZXMpOwpzdGF0aWMgdHJlZSBsb29rdXBfYW5kX2NoZWNrX3RhZyAoZW51bSB0YWdfdHlwZXMsIHRyZWUsIHRhZ19zY29wZSwgYm9vbCk7CnN0YXRpYyBpbnQgd2Fsa19uYW1lc3BhY2VzX3IgKHRyZWUsIHdhbGtfbmFtZXNwYWNlc19mbiwgdm9pZCAqKTsKc3RhdGljIHRyZWUgbWFrZV9sYWJlbF9kZWNsICh0cmVlLCBpbnQpOwpzdGF0aWMgdm9pZCB1c2VfbGFiZWwgKHRyZWUpOwpzdGF0aWMgdm9pZCBjaGVja19wcmV2aW91c19nb3RvXzEgKHRyZWUsIHN0cnVjdCBjcF9iaW5kaW5nX2xldmVsICosIHRyZWUsCgkJCQkgICBjb25zdCBsb2NhdGlvbl90ICopOwpzdGF0aWMgdm9pZCBjaGVja19wcmV2aW91c19nb3RvIChzdHJ1Y3QgbmFtZWRfbGFiZWxfdXNlX2xpc3QgKik7CnN0YXRpYyB2b2lkIGNoZWNrX3N3aXRjaF9nb3RvIChzdHJ1Y3QgY3BfYmluZGluZ19sZXZlbCAqKTsKc3RhdGljIHZvaWQgY2hlY2tfcHJldmlvdXNfZ290b3MgKHRyZWUpOwpzdGF0aWMgdm9pZCBwb3BfbGFiZWwgKHRyZWUsIHRyZWUpOwpzdGF0aWMgdm9pZCBwb3BfbGFiZWxzICh0cmVlKTsKc3RhdGljIHZvaWQgbWF5YmVfZGVkdWNlX3NpemVfZnJvbV9hcnJheV9pbml0ICh0cmVlLCB0cmVlKTsKc3RhdGljIHZvaWQgbGF5b3V0X3Zhcl9kZWNsICh0cmVlKTsKc3RhdGljIHZvaWQgbWF5YmVfY29tbW9uaXplX3ZhciAodHJlZSk7CnN0YXRpYyB0cmVlIGNoZWNrX2luaXRpYWxpemVyICh0cmVlLCB0cmVlLCBpbnQsIHRyZWUgKik7CnN0YXRpYyB2b2lkIG1ha2VfcnRsX2Zvcl9ub25sb2NhbF9kZWNsICh0cmVlLCB0cmVlLCBjb25zdCBjaGFyICopOwpzdGF0aWMgdm9pZCBzYXZlX2Z1bmN0aW9uX2RhdGEgKHRyZWUpOwpzdGF0aWMgdm9pZCBjaGVja19mdW5jdGlvbl90eXBlICh0cmVlLCB0cmVlKTsKc3RhdGljIHZvaWQgZmluaXNoX2NvbnN0cnVjdG9yX2JvZHkgKHZvaWQpOwpzdGF0aWMgdm9pZCBiZWdpbl9kZXN0cnVjdG9yX2JvZHkgKHZvaWQpOwpzdGF0aWMgdm9pZCBmaW5pc2hfZGVzdHJ1Y3Rvcl9ib2R5ICh2b2lkKTsKc3RhdGljIHRyZWUgY3JlYXRlX2FycmF5X3R5cGVfZm9yX2RlY2wgKHRyZWUsIHRyZWUsIHRyZWUpOwpzdGF0aWMgdHJlZSBnZXRfYXRleGl0X25vZGUgKHZvaWQpOwpzdGF0aWMgdHJlZSBnZXRfZHNvX2hhbmRsZV9ub2RlICh2b2lkKTsKc3RhdGljIHRyZWUgc3RhcnRfY2xlYW51cF9mbiAodm9pZCk7CnN0YXRpYyB2b2lkIGVuZF9jbGVhbnVwX2ZuICh2b2lkKTsKc3RhdGljIHRyZWUgY3BfbWFrZV9mbmFtZV9kZWNsICh0cmVlLCBpbnQpOwpzdGF0aWMgdm9pZCBpbml0aWFsaXplX3ByZWRlZmluZWRfaWRlbnRpZmllcnMgKHZvaWQpOwpzdGF0aWMgdHJlZSBjaGVja19zcGVjaWFsX2Z1bmN0aW9uX3JldHVybl90eXBlCgkoc3BlY2lhbF9mdW5jdGlvbl9raW5kLCB0cmVlLCB0cmVlKTsKc3RhdGljIHRyZWUgcHVzaF9jcF9saWJyYXJ5X2ZuIChlbnVtIHRyZWVfY29kZSwgdHJlZSk7CnN0YXRpYyB0cmVlIGJ1aWxkX2NwX2xpYnJhcnlfZm4gKHRyZWUsIGVudW0gdHJlZV9jb2RlLCB0cmVlKTsKc3RhdGljIHZvaWQgc3RvcmVfcGFybV9kZWNscyAodHJlZSk7CnN0YXRpYyB2b2lkIGluaXRpYWxpemVfbG9jYWxfdmFyICh0cmVlLCB0cmVlKTsKc3RhdGljIHZvaWQgZXhwYW5kX3N0YXRpY19pbml0ICh0cmVlLCB0cmVlKTsKc3RhdGljIHRyZWUgbmV4dF9pbml0aWFsaXphYmxlX2ZpZWxkICh0cmVlKTsKc3RhdGljIHRyZWUgcmVzaGFwZV9pbml0ICh0cmVlLCB0cmVlICopOwoKLyogRXJyb25lb3VzIGFyZ3VtZW50IGxpc3RzIGNhbiB1c2UgdGhpcyAqSUZGKiB0aGV5IGRvIG5vdCBtb2RpZnkgaXQuICAqLwp0cmVlIGVycm9yX21hcmtfbGlzdDsKCi8qIFRoZSBmb2xsb3dpbmcgc3ltYm9scyBhcmUgc3Vic3VtZWQgaW4gdGhlIGNwX2dsb2JhbF90cmVlcyBhcnJheSwgYW5kCiAgIGxpc3RlZCBoZXJlIGluZGl2aWR1YWxseSBmb3IgZG9jdW1lbnRhdGlvbiBwdXJwb3Nlcy4KCiAgIEMrKyBleHRlbnNpb25zCgl0cmVlIHdjaGFyX2RlY2xfbm9kZTsKCgl0cmVlIHZ0YWJsZV9lbnRyeV90eXBlOwoJdHJlZSBkZWx0YV90eXBlX25vZGU7Cgl0cmVlIF9fdF9kZXNjX3R5cGVfbm9kZTsKICAgICAgICB0cmVlIHRpX2Rlc2NfdHlwZV9ub2RlOwoJdHJlZSBibHRuX2Rlc2NfdHlwZV9ub2RlLCBwdHJfZGVzY190eXBlX25vZGU7Cgl0cmVlIGFyeV9kZXNjX3R5cGVfbm9kZSwgZnVuY19kZXNjX3R5cGVfbm9kZSwgZW51bV9kZXNjX3R5cGVfbm9kZTsKCXRyZWUgY2xhc3NfZGVzY190eXBlX25vZGUsIHNpX2NsYXNzX2Rlc2NfdHlwZV9ub2RlLCB2bWlfY2xhc3NfZGVzY190eXBlX25vZGU7Cgl0cmVlIHB0bV9kZXNjX3R5cGVfbm9kZTsKCXRyZWUgYmFzZV9kZXNjX3R5cGVfbm9kZTsKCgl0cmVlIGNsYXNzX3R5cGVfbm9kZTsKCXRyZWUgdW5rbm93bl90eXBlX25vZGU7CgogICBBcnJheSB0eXBlIGB2dGFibGVfZW50cnlfdHlwZVtdJwoKCXRyZWUgdnRibF90eXBlX25vZGU7Cgl0cmVlIHZ0YmxfcHRyX3R5cGVfbm9kZTsKCiAgIE5hbWVzcGFjZXMsCgoJdHJlZSBzdGRfbm9kZTsKCXRyZWUgYWJpX25vZGU7CgogICBBIEZVTkNUSU9OX0RFQ0wgd2hpY2ggY2FuIGNhbGwgYGFib3J0Jy4gIE5vdCBuZWNlc3NhcmlseSB0aGUKICAgb25lIHRoYXQgdGhlIHVzZXIgd2lsbCBkZWNsYXJlLCBidXQgc3VmZmljaWVudCB0byBiZSBjYWxsZWQKICAgYnkgcm91dGluZXMgdGhhdCB3YW50IHRvIGFib3J0IHRoZSBwcm9ncmFtLgoKCXRyZWUgYWJvcnRfZm5kZWNsOwoKICAgVGhlIEZVTkNUSU9OX0RFQ0wgZm9yIHRoZSBkZWZhdWx0IGA6Om9wZXJhdG9yIGRlbGV0ZScuCgoJdHJlZSBnbG9iYWxfZGVsZXRlX2ZuZGVjbDsKCiAgIFVzZWQgYnkgUlRUSQoJdHJlZSB0eXBlX2luZm9fdHlwZV9ub2RlLCB0aW5mb19kZWNsX2lkLCB0aW5mb19kZWNsX3R5cGU7Cgl0cmVlIHRpbmZvX3Zhcl9pZDsKCiovCgp0cmVlIGNwX2dsb2JhbF90cmVlc1tDUFRJX01BWF07CgovKiBJbmRpY2F0ZXMgdGhhdCB0aGVyZSBpcyBhIHR5cGUgdmFsdWUgaW4gc29tZSBuYW1lc3BhY2UsIGFsdGhvdWdoCiAgIHRoYXQgaXMgbm90IG5lY2Vzc2FyaWx5IGluIHNjb3BlIGF0IHRoZSBtb21lbnQuICAqLwoKdHJlZSBnbG9iYWxfdHlwZV9ub2RlOwoKLyogVGhlIG5vZGUgdGhhdCBob2xkcyB0aGUgIm5hbWUiIG9mIHRoZSBnbG9iYWwgc2NvcGUuICAqLwp0cmVlIGdsb2JhbF9zY29wZV9uYW1lOwoKLyogVXNlZCBvbmx5IGZvciBqdW1wcyB0byBhcy15ZXQgdW5kZWZpbmVkIGxhYmVscywgc2luY2UganVtcHMgdG8KICAgZGVmaW5lZCBsYWJlbHMgY2FuIGhhdmUgdGhlaXIgdmFsaWRpdHkgY2hlY2tlZCBpbW1lZGlhdGVseS4gICovCgpzdHJ1Y3QgbmFtZWRfbGFiZWxfdXNlX2xpc3QgR1RZKCgpKQp7CiAgc3RydWN0IGNwX2JpbmRpbmdfbGV2ZWwgKmJpbmRpbmdfbGV2ZWw7CiAgdHJlZSBuYW1lc19pbl9zY29wZTsKICB0cmVlIGxhYmVsX2RlY2w7CiAgbG9jYXRpb25fdCBvX2dvdG9fbG9jdXM7CiAgc3RydWN0IG5hbWVkX2xhYmVsX3VzZV9saXN0ICpuZXh0Owp9OwoKI2RlZmluZSBuYW1lZF9sYWJlbF91c2VzIGNwX2Z1bmN0aW9uX2NoYWluLT54X25hbWVkX2xhYmVsX3VzZXMKCiNkZWZpbmUgbG9jYWxfbmFtZXMgY3BfZnVuY3Rpb25fY2hhaW4tPnhfbG9jYWxfbmFtZXMKCi8qIEEgbGlzdCBvZiBvYmplY3RzIHdoaWNoIGhhdmUgY29uc3RydWN0b3JzIG9yIGRlc3RydWN0b3JzCiAgIHdoaWNoIHJlc2lkZSBpbiB0aGUgZ2xvYmFsIHNjb3BlLiAgVGhlIGRlY2wgaXMgc3RvcmVkIGluCiAgIHRoZSBUUkVFX1ZBTFVFIHNsb3QgYW5kIHRoZSBpbml0aWFsaXplciBpcyBzdG9yZWQKICAgaW4gdGhlIFRSRUVfUFVSUE9TRSBzbG90LiAgKi8KdHJlZSBzdGF0aWNfYWdncmVnYXRlczsKCi8qIC0tIGVuZCBvZiBDKysgKi8KCi8qIEEgbm9kZSBmb3IgdGhlIGludGVnZXIgY29uc3RhbnRzIDIsIGFuZCAzLiAgKi8KCnRyZWUgaW50ZWdlcl90d29fbm9kZSwgaW50ZWdlcl90aHJlZV9ub2RlOwoKLyogQSBsaXN0IG9mIGFsbCBMQUJFTF9ERUNMcyBpbiB0aGUgZnVuY3Rpb24gdGhhdCBoYXZlIG5hbWVzLiAgSGVyZSBzbwogICB3ZSBjYW4gY2xlYXIgb3V0IHRoZWlyIG5hbWVzJyBkZWZpbml0aW9ucyBhdCB0aGUgZW5kIG9mIHRoZQogICBmdW5jdGlvbiwgYW5kIHNvIHdlIGNhbiBjaGVjayB0aGUgdmFsaWRpdHkgb2YganVtcHMgdG8gdGhlc2UgbGFiZWxzLiAgKi8KCnN0cnVjdCBuYW1lZF9sYWJlbF9saXN0IEdUWSgoKSkKewogIHN0cnVjdCBjcF9iaW5kaW5nX2xldmVsICpiaW5kaW5nX2xldmVsOwogIHRyZWUgbmFtZXNfaW5fc2NvcGU7CiAgdHJlZSBvbGRfdmFsdWU7CiAgdHJlZSBsYWJlbF9kZWNsOwogIHRyZWUgYmFkX2RlY2xzOwogIHN0cnVjdCBuYW1lZF9sYWJlbF9saXN0ICpuZXh0OwogIHVuc2lnbmVkIGludCBpbl90cnlfc2NvcGUgOiAxOwogIHVuc2lnbmVkIGludCBpbl9jYXRjaF9zY29wZSA6IDE7Cn07CgojZGVmaW5lIG5hbWVkX2xhYmVscyBjcF9mdW5jdGlvbl9jaGFpbi0+eF9uYW1lZF9sYWJlbHMKDAovKiBUaGUgbnVtYmVyIG9mIGZ1bmN0aW9uIGJvZGllcyB3aGljaCB3ZSBhcmUgY3VycmVudGx5IHByb2Nlc3NpbmcuCiAgIChaZXJvIGlmIHdlIGFyZSBhdCBuYW1lc3BhY2Ugc2NvcGUsIG9uZSBpbnNpZGUgdGhlIGJvZHkgb2YgYQogICBmdW5jdGlvbiwgdHdvIGluc2lkZSB0aGUgYm9keSBvZiBhIGZ1bmN0aW9uIGluIGEgbG9jYWwgY2xhc3MsIGV0Yy4pICAqLwppbnQgZnVuY3Rpb25fZGVwdGg7CgovKiBTdGF0ZXMgaW5kaWNhdGluZyBob3cgZ3Jva2RlY2xhcmF0b3IoKSBzaG91bGQgaGFuZGxlIGRlY2xzcGVjcyBtYXJrZWQKICAgd2l0aCBfX2F0dHJpYnV0ZV9fKChkZXByZWNhdGVkKSkuICBBbiBvYmplY3QgZGVjbGFyZWQgYXMKICAgX19hdHRyaWJ1dGVfXygoZGVwcmVjYXRlZCkpIHN1cHByZXNzZXMgd2FybmluZ3Mgb2YgdXNlcyBvZiBvdGhlcgogICBkZXByZWNhdGVkIGl0ZW1zLiAgKi8KLyogQVBQTEUgTE9DQUwgYmVnaW4gInVuYXZhaWxhYmxlIiBhdHRyaWJ1dGUgKHJhZGFyIDI4MDk2OTcpICovCi8qIEFuIG9iamVjdCBkZWNsYXJlZCBhcyBfX2F0dHJpYnV0ZV9fKCh1bmF2YWlsYWJsZSkpIHN1cHByZXNzZXMKICAgYW55IHJlcG9ydHMgb2YgYmVpbmcgZGVjbGFyZWQgd2l0aCB1bmF2YWlsYWJsZSBvciBkZXByZWNhdGVkCiAgIGl0ZW1zLiAgKi8KLyogQVBQTEUgTE9DQUwgZW5kICJ1bmF2YWlsYWJsZSIgYXR0cmlidXRlIChyYWRhciAyODA5Njk3KSAqLwoKZW51bSBkZXByZWNhdGVkX3N0YXRlcyB7CiAgREVQUkVDQVRFRF9OT1JNQUwsCiAgREVQUkVDQVRFRF9TVVBQUkVTUwogIC8qIEFQUExFIExPQ0FMICJ1bmF2YWlsYWJsZSIgYXR0cmlidXRlIChyYWRhciAyODA5Njk3KSAqLwogICwgREVQUkVDQVRFRF9VTkFWQUlMQUJMRV9TVVBQUkVTUwp9OwoKc3RhdGljIGVudW0gZGVwcmVjYXRlZF9zdGF0ZXMgZGVwcmVjYXRlZF9zdGF0ZSA9IERFUFJFQ0FURURfTk9STUFMOwoKLyogVHJ1ZSBpZiBhIGRlY2xhcmF0aW9uIHdpdGggYW4gYGV4dGVybicgbGlua2FnZSBzcGVjaWZpZXIgaXMgYmVpbmcKICAgcHJvY2Vzc2VkLiAgKi8KYm9vbCBoYXZlX2V4dGVybl9zcGVjOwoKDAovKiBBIFRSRUVfTElTVCBvZiBWQVJfREVDTHMuICBUaGUgVFJFRV9QVVJQT1NFIGlzIGEgUkVDT1JEX1RZUEUgb3IKICAgVU5JT05fVFlQRTsgdGhlIFRSRUVfVkFMVUUgaXMgYSBWQVJfREVDTCB3aXRoIHRoYXQgdHlwZS4gIEF0IHRoZQogICB0aW1lIHRoZSBWQVJfREVDTCB3YXMgZGVjbGFyZWQsIHRoZSB0eXBlIHdhcyBpbmNvbXBsZXRlLiAgKi8KCnN0YXRpYyBHVFkoKCkpIHRyZWUgaW5jb21wbGV0ZV92YXJzOwoMCi8qIFJldHVybnMgdGhlIGtpbmQgb2YgdGVtcGxhdGUgc3BlY2lhbGl6YXRpb24gd2UgYXJlIGN1cnJlbnRseQogICBwcm9jZXNzaW5nLCBnaXZlbiB0aGF0IGl0J3MgZGVjbGFyYXRpb24gY29udGFpbmVkIE5fQ0xBU1NfU0NPUEVTCiAgIGV4cGxpY2l0IHNjb3BlIHF1YWxpZmljYXRpb25zLiAgKi8KCnRtcGxfc3BlY19raW5kCmN1cnJlbnRfdG1wbF9zcGVjX2tpbmQgKGludCBuX2NsYXNzX3Njb3BlcykKewogIGludCBuX3RlbXBsYXRlX3Bhcm1fc2NvcGVzID0gMDsKICBpbnQgc2Vlbl9zcGVjaWFsaXphdGlvbl9wID0gMDsKICBpbnQgaW5uZXJtb3N0X3NwZWNpYWxpemF0aW9uX3AgPSAwOwogIHN0cnVjdCBjcF9iaW5kaW5nX2xldmVsICpiOwoKICAvKiBTY2FuIHRocm91Z2ggdGhlIHRlbXBsYXRlIHBhcmFtZXRlciBzY29wZXMuICAqLwogIGZvciAoYiA9IGN1cnJlbnRfYmluZGluZ19sZXZlbDsKICAgICAgIGItPmtpbmQgPT0gc2tfdGVtcGxhdGVfcGFybXM7CiAgICAgICBiID0gYi0+bGV2ZWxfY2hhaW4pCiAgICB7CiAgICAgIC8qIElmIHdlIHNlZSBhIHNwZWNpYWxpemF0aW9uIHNjb3BlIGluc2lkZSBhIHBhcmFtZXRlciBzY29wZSwKCSB0aGVuIHNvbWV0aGluZyBpcyB3cm9uZy4gIFRoYXQgY29ycmVzcG9uZHMgdG8gYSBkZWNsYXJhdGlvbgoJIGxpa2U6CgoJICAgIHRlbXBsYXRlIDxjbGFzcyBUPiB0ZW1wbGF0ZSA8PiAuLi4KCgkgd2hpY2ggaXMgYWx3YXlzIGludmFsaWQgc2luY2UgW3RlbXAuZXhwbC5zcGVjXSBmb3JiaWRzIHRoZQoJIHNwZWNpYWxpemF0aW9uIG9mIGEgY2xhc3MgbWVtYmVyIHRlbXBsYXRlIGlmIHRoZSBlbmNsb3NpbmcKCSBjbGFzcyB0ZW1wbGF0ZXMgYXJlIG5vdCBleHBsaWNpdGx5IHNwZWNpYWxpemVkIGFzIHdlbGwuICAqLwogICAgICBpZiAoYi0+ZXhwbGljaXRfc3BlY19wKQoJewoJICBpZiAobl90ZW1wbGF0ZV9wYXJtX3Njb3BlcyA9PSAwKQoJICAgIGlubmVybW9zdF9zcGVjaWFsaXphdGlvbl9wID0gMTsKCSAgZWxzZQoJICAgIHNlZW5fc3BlY2lhbGl6YXRpb25fcCA9IDE7Cgl9CiAgICAgIGVsc2UgaWYgKHNlZW5fc3BlY2lhbGl6YXRpb25fcCA9PSAxKQoJcmV0dXJuIHRza19pbnZhbGlkX21lbWJlcl9zcGVjOwoKICAgICAgKytuX3RlbXBsYXRlX3Bhcm1fc2NvcGVzOwogICAgfQoKICAvKiBIYW5kbGUgZXhwbGljaXQgaW5zdGFudGlhdGlvbnMuICAqLwogIGlmIChwcm9jZXNzaW5nX2V4cGxpY2l0X2luc3RhbnRpYXRpb24pCiAgICB7CiAgICAgIGlmIChuX3RlbXBsYXRlX3Bhcm1fc2NvcGVzICE9IDApCgkvKiBXZSd2ZSBzZWVuIGEgdGVtcGxhdGUgcGFyYW1ldGVyIGxpc3QgZHVyaW5nIGFuIGV4cGxpY2l0CgkgICBpbnN0YW50aWF0aW9uLiAgRm9yIGV4YW1wbGU6CgoJICAgICB0ZW1wbGF0ZSA8Y2xhc3MgVD4gdGVtcGxhdGUgdm9pZCBmKGludCk7CgoJICAgVGhpcyBpcyBlcnJvbmVvdXMuICAqLwoJcmV0dXJuIHRza19pbnZhbGlkX2V4cGxfaW5zdDsKICAgICAgZWxzZQoJcmV0dXJuIHRza19leHBsX2luc3Q7CiAgICB9CgogIGlmIChuX3RlbXBsYXRlX3Bhcm1fc2NvcGVzIDwgbl9jbGFzc19zY29wZXMpCiAgICAvKiBXZSd2ZSBub3Qgc2VlbiBlbm91Z2ggdGVtcGxhdGUgaGVhZGVycyB0byBtYXRjaCBhbGwgdGhlCiAgICAgICBzcGVjaWFsaXplZCBjbGFzc2VzIHByZXNlbnQuICBGb3IgZXhhbXBsZToKCiAgICAgICAgIHRlbXBsYXRlIDxjbGFzcyBUPiB2b2lkIFI8VD46OlM8VD46OmYoaW50KTsKCiAgICAgICBUaGlzIGlzIGludmFsaWQ7IHRoZXJlIG5lZWRzIHRvIGJlIG9uZSBzZXQgb2YgdGVtcGxhdGUKICAgICAgIHBhcmFtZXRlcnMgZm9yIGVhY2ggY2xhc3MuICAqLwogICAgcmV0dXJuIHRza19pbnN1ZmZpY2llbnRfcGFybXM7CiAgZWxzZSBpZiAobl90ZW1wbGF0ZV9wYXJtX3Njb3BlcyA9PSBuX2NsYXNzX3Njb3BlcykKICAgIC8qIFdlJ3JlIHByb2Nlc3NpbmcgYSBub24tdGVtcGxhdGUgZGVjbGFyYXRpb24gKGV2ZW4gdGhvdWdoIGl0IG1heQogICAgICAgYmUgYSBtZW1iZXIgb2YgYSB0ZW1wbGF0ZSBjbGFzcy4pICBGb3IgZXhhbXBsZToKCiAgICAgICAgIHRlbXBsYXRlIDxjbGFzcyBUPiB2b2lkIFM8VD46OmYoaW50KTsKCiAgICAgICBUaGUgYGNsYXNzIFQnIG1hY2hlcyB0aGUgYFM8VD4nLCBsZWF2aW5nIG5vIHRlbXBsYXRlIGhlYWRlcnMKICAgICAgIGNvcnJlc3BvbmRpbmcgdG8gdGhlIGBmJy4gICovCiAgICByZXR1cm4gdHNrX25vbmU7CiAgZWxzZSBpZiAobl90ZW1wbGF0ZV9wYXJtX3Njb3BlcyA+IG5fY2xhc3Nfc2NvcGVzICsgMSkKICAgIC8qIFdlJ3ZlIGdvdCB0b28gbWFueSB0ZW1wbGF0ZSBoZWFkZXJzLiAgRm9yIGV4YW1wbGU6CgogICAgICAgICB0ZW1wbGF0ZSA8PiB0ZW1wbGF0ZSA8Y2xhc3MgVD4gdm9pZCBmIChUKTsKCiAgICAgICBUaGVyZSBuZWVkIHRvIGJlIG1vcmUgZW5jbG9zaW5nIGNsYXNzZXMuICAqLwogICAgcmV0dXJuIHRza19leGNlc3NpdmVfcGFybXM7CiAgZWxzZQogICAgLyogVGhpcyBtdXN0IGJlIGEgdGVtcGxhdGUuICBJdCdzIG9mIHRoZSBmb3JtOgoKICAgICAgICAgdGVtcGxhdGUgPGNsYXNzIFQ+IHRlbXBsYXRlIDxjbGFzcyBVPiB2b2lkIFM8VD46OmYoVSk7CgogICAgICAgVGhpcyBpcyBhIHNwZWNpYWxpemF0aW9uIGlmIHRoZSBpbm5lcm1vc3QgbGV2ZWwgd2FzIGEKICAgICAgIHNwZWNpYWxpemF0aW9uOyBvdGhlcndpc2UgaXQncyBqdXN0IGEgZGVmaW5pdGlvbiBvZiB0aGUKICAgICAgIHRlbXBsYXRlLiAgKi8KICAgIHJldHVybiBpbm5lcm1vc3Rfc3BlY2lhbGl6YXRpb25fcCA/IHRza19leHBsX3NwZWMgOiB0c2tfdGVtcGxhdGU7Cn0KCi8qIEV4aXQgdGhlIGN1cnJlbnQgc2NvcGUuICAqLwoKdm9pZApmaW5pc2hfc2NvcGUgKHZvaWQpCnsKICBwb3BsZXZlbCAoMCwgMCwgMCk7Cn0KCi8qIFdoZW4gYSBsYWJlbCBnb2VzIG91dCBvZiBzY29wZSwgY2hlY2sgdG8gc2VlIGlmIHRoYXQgbGFiZWwgd2FzIHVzZWQKICAgaW4gYSB2YWxpZCBtYW5uZXIsIGFuZCBpc3N1ZSBhbnkgYXBwcm9wcmlhdGUgd2FybmluZ3Mgb3IgZXJyb3JzLiAgKi8KCnN0YXRpYyB2b2lkCnBvcF9sYWJlbCAodHJlZSBsYWJlbCwgdHJlZSBvbGRfdmFsdWUpCnsKICBpZiAoIXByb2Nlc3NpbmdfdGVtcGxhdGVfZGVjbCkKICAgIHsKICAgICAgaWYgKERFQ0xfSU5JVElBTCAobGFiZWwpID09IE5VTExfVFJFRSkKCXsKCSAgbG9jYXRpb25fdCBsb2NhdGlvbjsKCgkgIGNwX2Vycm9yX2F0ICgibGFiZWwgJXFEIHVzZWQgYnV0IG5vdCBkZWZpbmVkIiwgbGFiZWwpOwojaWZkZWYgVVNFX01BUFBFRF9MT0NBVElPTgoJICBsb2NhdGlvbiA9IGlucHV0X2xvY2F0aW9uOyAvKiBGSVhNRSB3YW50IChpbnB1dF9maWxlbmFtZSwgKGxpbmUpMCkgKi8KI2Vsc2UKIAkgIGxvY2F0aW9uLmZpbGUgPSBpbnB1dF9maWxlbmFtZTsKCSAgbG9jYXRpb24ubGluZSA9IDA7CiNlbmRpZgoJICAvKiBBdm9pZCBjcmFzaGluZyBsYXRlci4gICovCgkgIGRlZmluZV9sYWJlbCAobG9jYXRpb24sIERFQ0xfTkFNRSAobGFiZWwpKTsKCX0KICAgICAgZWxzZSBpZiAod2Fybl91bnVzZWRfbGFiZWwgJiYgIVRSRUVfVVNFRCAobGFiZWwpKQoJY3Bfd2FybmluZ19hdCAoImxhYmVsICVxRCBkZWZpbmVkIGJ1dCBub3QgdXNlZCIsIGxhYmVsKTsKICAgIH0KCiAgU0VUX0lERU5USUZJRVJfTEFCRUxfVkFMVUUgKERFQ0xfTkFNRSAobGFiZWwpLCBvbGRfdmFsdWUpOwp9CgovKiBBdCB0aGUgZW5kIG9mIGEgZnVuY3Rpb24sIGFsbCBsYWJlbHMgZGVjbGFyZWQgd2l0aGluIHRoZSBmdW5jdGlvbgogICBnbyBvdXQgb2Ygc2NvcGUuICBCTE9DSyBpcyB0aGUgdG9wLWxldmVsIGJsb2NrIGZvciB0aGUKICAgZnVuY3Rpb24uICAqLwoKc3RhdGljIHZvaWQKcG9wX2xhYmVscyAodHJlZSBibG9jaykKewogIHN0cnVjdCBuYW1lZF9sYWJlbF9saXN0ICpsaW5rOwoKICAvKiBDbGVhciBvdXQgdGhlIGRlZmluaXRpb25zIG9mIGFsbCBsYWJlbCBuYW1lcywgc2luY2UgdGhlaXIgc2NvcGVzCiAgICAgZW5kIGhlcmUuICAqLwogIGZvciAobGluayA9IG5hbWVkX2xhYmVsczsgbGluazsgbGluayA9IGxpbmstPm5leHQpCiAgICB7CiAgICAgIHBvcF9sYWJlbCAobGluay0+bGFiZWxfZGVjbCwgbGluay0+b2xkX3ZhbHVlKTsKICAgICAgLyogUHV0IHRoZSBsYWJlbHMgaW50byB0aGUgInZhcmlhYmxlcyIgb2YgdGhlIHRvcC1sZXZlbCBibG9jaywKCSBzbyBkZWJ1Z2dlciBjYW4gc2VlIHRoZW0uICAqLwogICAgICBUUkVFX0NIQUlOIChsaW5rLT5sYWJlbF9kZWNsKSA9IEJMT0NLX1ZBUlMgKGJsb2NrKTsKICAgICAgQkxPQ0tfVkFSUyAoYmxvY2spID0gbGluay0+bGFiZWxfZGVjbDsKICAgIH0KCiAgbmFtZWRfbGFiZWxzID0gTlVMTDsKfQoKLyogVGhlIGZvbGxvd2luZyB0d28gcm91dGluZXMgYXJlIHVzZWQgdG8gaW50ZXJmYWNlIHRvIE9iamVjdGl2ZS1DKysuCiAgIFRoZSBiaW5kaW5nIGxldmVsIGlzIHB1cnBvc2VseSB0cmVhdGVkIGFzIGFuIG9wYXF1ZSB0eXBlLiAgKi8KCnZvaWQgKgpvYmpjX2dldF9jdXJyZW50X3Njb3BlICh2b2lkKQp7CiAgcmV0dXJuIGN1cnJlbnRfYmluZGluZ19sZXZlbDsKfQoKLyogVGhlIGZvbGxvd2luZyByb3V0aW5lIGlzIHVzZWQgYnkgdGhlIE5lWFQtc3R5bGUgU0pMSiBleGNlcHRpb25zOwogICB2YXJpYWJsZXMgZ2V0IG1hcmtlZCAndm9sYXRpbGUnIHNvIGFzIHRvIG5vdCBiZSBjbG9iYmVyZWQgYnkKICAgX3NldGptcCgpL19sb25nam1wKCkgY2FsbHMuICBBbGwgdmFyaWFibGVzIGluIHRoZSBjdXJyZW50IHNjb3BlLAogICBhcyB3ZWxsIGFzIHBhcmVudCBzY29wZXMgdXAgdG8gKGJ1dCBub3QgaW5jbHVkaW5nKSBFTkNMT1NJTkdfQkxLCiAgIHNoYWxsIGJlIHRodXNseSBtYXJrZWQuICAqLwoKdm9pZApvYmpjX21hcmtfbG9jYWxzX3ZvbGF0aWxlICh2b2lkICplbmNsb3NpbmdfYmxrKQp7CiAgc3RydWN0IGNwX2JpbmRpbmdfbGV2ZWwgKnNjb3BlOwoKICBmb3IgKHNjb3BlID0gY3VycmVudF9iaW5kaW5nX2xldmVsOwogICAgICAgLyogQVBQTEUgTE9DQUwgbWFpbmxpbmUgKi8KICAgICAgIHNjb3BlICYmIHNjb3BlICE9IGVuY2xvc2luZ19ibGs7CiAgICAgICBzY29wZSA9IHNjb3BlLT5sZXZlbF9jaGFpbikKICAgIHsKICAgICAgdHJlZSBkZWNsOwoKICAgICAgLyogQVBQTEUgTE9DQUwgYmVnaW4gbWFpbmxpbmUgKi8KICAgICAgZm9yIChkZWNsID0gc2NvcGUtPm5hbWVzOyBkZWNsOyBkZWNsID0gVFJFRV9DSEFJTiAoZGVjbCkpCglvYmpjX3ZvbGF0aWxpemVfZGVjbCAoZGVjbCk7CgogICAgICAvKiBEbyBub3QgY2xpbWIgdXAgcGFzdCB0aGUgY3VycmVudCBmdW5jdGlvbi4gICovCiAgICAgIGlmIChzY29wZS0+a2luZCA9PSBza19mdW5jdGlvbl9wYXJtcykKCWJyZWFrOwogICAgICAvKiBBUFBMRSBMT0NBTCBlbmQgbWFpbmxpbmUgKi8KICAgIH0KfQoKLyogRXhpdCBhIGJpbmRpbmcgbGV2ZWwuCiAgIFBvcCB0aGUgbGV2ZWwgb2ZmLCBhbmQgcmVzdG9yZSB0aGUgc3RhdGUgb2YgdGhlIGlkZW50aWZpZXItZGVjbCBtYXBwaW5ncwogICB0aGF0IHdlcmUgaW4gZWZmZWN0IHdoZW4gdGhpcyBsZXZlbCB3YXMgZW50ZXJlZC4KCiAgIElmIEtFRVAgPT0gMSwgdGhpcyBsZXZlbCBoYWQgZXhwbGljaXQgZGVjbGFyYXRpb25zLCBzbwogICBhbmQgY3JlYXRlIGEgImJsb2NrIiAoYSBCTE9DSyBub2RlKSBmb3IgdGhlIGxldmVsCiAgIHRvIHJlY29yZCBpdHMgZGVjbGFyYXRpb25zIGFuZCBzdWJibG9ja3MgZm9yIHN5bWJvbCB0YWJsZSBvdXRwdXQuCgogICBJZiBGVU5DVElPTkJPRFkgaXMgbm9uemVybywgdGhpcyBsZXZlbCBpcyB0aGUgYm9keSBvZiBhIGZ1bmN0aW9uLAogICBzbyBjcmVhdGUgYSBibG9jayBhcyBpZiBLRUVQIHdlcmUgc2V0IGFuZCBhbHNvIGNsZWFyIG91dCBhbGwKICAgbGFiZWwgbmFtZXMuCgogICBJZiBSRVZFUlNFIGlzIG5vbnplcm8sIHJldmVyc2UgdGhlIG9yZGVyIG9mIGRlY2xzIGJlZm9yZSBwdXR0aW5nCiAgIHRoZW0gaW50byB0aGUgQkxPQ0suICAqLwoKdHJlZQpwb3BsZXZlbCAoaW50IGtlZXAsIGludCByZXZlcnNlLCBpbnQgZnVuY3Rpb25ib2R5KQp7CiAgdHJlZSBsaW5rOwogIC8qIFRoZSBjaGFpbiBvZiBkZWNscyB3YXMgYWNjdW11bGF0ZWQgaW4gcmV2ZXJzZSBvcmRlci4KICAgICBQdXQgaXQgaW50byBmb3J3YXJkIG9yZGVyLCBqdXN0IGZvciBjbGVhbmxpbmVzcy4gICovCiAgdHJlZSBkZWNsczsKICBpbnQgdG1wID0gZnVuY3Rpb25ib2R5OwogIGludCByZWFsX2Z1bmN0aW9uYm9keTsKICB0cmVlIHN1YmJsb2NrczsKICB0cmVlIGJsb2NrOwogIHRyZWUgZGVjbDsKICBpbnQgbGVhdmluZ19mb3Jfc2NvcGU7CiAgc2NvcGVfa2luZCBraW5kOwoKICB0aW1ldmFyX3B1c2ggKFRWX05BTUVfTE9PS1VQKTsKIHJlc3RhcnQ6CgogIGJsb2NrID0gTlVMTF9UUkVFOwoKICBnY2NfYXNzZXJ0IChjdXJyZW50X2JpbmRpbmdfbGV2ZWwtPmtpbmQgIT0gc2tfY2xhc3MpOwoKICByZWFsX2Z1bmN0aW9uYm9keSA9IChjdXJyZW50X2JpbmRpbmdfbGV2ZWwtPmtpbmQgPT0gc2tfY2xlYW51cAoJCSAgICAgICA/ICgoZnVuY3Rpb25ib2R5ID0gMCksIHRtcCkgOiBmdW5jdGlvbmJvZHkpOwogIHN1YmJsb2NrcyA9IGZ1bmN0aW9uYm9keSA+PSAwID8gY3VycmVudF9iaW5kaW5nX2xldmVsLT5ibG9ja3MgOiAwOwoKICBnY2NfYXNzZXJ0ICghVkVDX2xlbmd0aChjcF9jbGFzc19iaW5kaW5nLAoJCQkgIGN1cnJlbnRfYmluZGluZ19sZXZlbC0+Y2xhc3Nfc2hhZG93ZWQpKTsKCiAgLyogV2UgdXNlZCB0byB1c2UgS0VFUCA9PSAyIHRvIGluZGljYXRlIHRoYXQgdGhlIG5ldyBibG9jayBzaG91bGQgZ28KICAgICBhdCB0aGUgYmVnaW5uaW5nIG9mIHRoZSBsaXN0IG9mIGJsb2NrcyBhdCB0aGlzIGJpbmRpbmcgbGV2ZWwsCiAgICAgcmF0aGVyIHRoYW4gdGhlIGVuZC4gIFRoaXMgaGFjayBpcyBubyBsb25nZXIgdXNlZC4gICovCiAgZ2NjX2Fzc2VydCAoa2VlcCA9PSAwIHx8IGtlZXAgPT0gMSk7CgogIGlmIChjdXJyZW50X2JpbmRpbmdfbGV2ZWwtPmtlZXApCiAgICBrZWVwID0gMTsKCiAgLyogQW55IHVzZXMgb2YgdW5kZWZpbmVkIGxhYmVscywgYW5kIGFueSBkZWZpbmVkIGxhYmVscywgbm93IG9wZXJhdGUKICAgICB1bmRlciBjb25zdHJhaW50cyBvZiBuZXh0IGJpbmRpbmcgY29udG91ci4gICovCiAgaWYgKGNmdW4gJiYgIWZ1bmN0aW9uYm9keSkKICAgIHsKICAgICAgc3RydWN0IGNwX2JpbmRpbmdfbGV2ZWwgKmxldmVsX2NoYWluOwogICAgICBsZXZlbF9jaGFpbiA9IGN1cnJlbnRfYmluZGluZ19sZXZlbC0+bGV2ZWxfY2hhaW47CiAgICAgIGlmIChsZXZlbF9jaGFpbikKCXsKCSAgc3RydWN0IG5hbWVkX2xhYmVsX3VzZV9saXN0ICp1c2VzOwoJICBzdHJ1Y3QgbmFtZWRfbGFiZWxfbGlzdCAqbGFiZWxzOwoJICBmb3IgKGxhYmVscyA9IG5hbWVkX2xhYmVsczsgbGFiZWxzOyBsYWJlbHMgPSBsYWJlbHMtPm5leHQpCgkgICAgaWYgKGxhYmVscy0+YmluZGluZ19sZXZlbCA9PSBjdXJyZW50X2JpbmRpbmdfbGV2ZWwpCgkgICAgICB7CgkJdHJlZSBkZWNsOwoJCWlmIChjdXJyZW50X2JpbmRpbmdfbGV2ZWwtPmtpbmQgPT0gc2tfdHJ5KQoJCSAgbGFiZWxzLT5pbl90cnlfc2NvcGUgPSAxOwoJCWlmIChjdXJyZW50X2JpbmRpbmdfbGV2ZWwtPmtpbmQgPT0gc2tfY2F0Y2gpCgkJICBsYWJlbHMtPmluX2NhdGNoX3Njb3BlID0gMTsKCQlmb3IgKGRlY2wgPSBsYWJlbHMtPm5hbWVzX2luX3Njb3BlOyBkZWNsOwoJCSAgICAgZGVjbCA9IFRSRUVfQ0hBSU4gKGRlY2wpKQoJCSAgaWYgKGRlY2xfanVtcF91bnNhZmUgKGRlY2wpKQoJCSAgICBsYWJlbHMtPmJhZF9kZWNscyA9IHRyZWVfY29ucyAoTlVMTF9UUkVFLCBkZWNsLAoJCQkJCQkgICBsYWJlbHMtPmJhZF9kZWNscyk7CgkJbGFiZWxzLT5iaW5kaW5nX2xldmVsID0gbGV2ZWxfY2hhaW47CgkJbGFiZWxzLT5uYW1lc19pbl9zY29wZSA9IGxldmVsX2NoYWluLT5uYW1lczsKCSAgICAgIH0KCgkgIGZvciAodXNlcyA9IG5hbWVkX2xhYmVsX3VzZXM7IHVzZXM7IHVzZXMgPSB1c2VzLT5uZXh0KQoJICAgIGlmICh1c2VzLT5iaW5kaW5nX2xldmVsID09IGN1cnJlbnRfYmluZGluZ19sZXZlbCkKCSAgICAgIHsKCQl1c2VzLT5iaW5kaW5nX2xldmVsID0gbGV2ZWxfY2hhaW47CgkJdXNlcy0+bmFtZXNfaW5fc2NvcGUgPSBsZXZlbF9jaGFpbi0+bmFtZXM7CgkgICAgICB9Cgl9CiAgICB9CgogIC8qIEdldCB0aGUgZGVjbHMgaW4gdGhlIG9yZGVyIHRoZXkgd2VyZSB3cml0dGVuLgogICAgIFVzdWFsbHkgY3VycmVudF9iaW5kaW5nX2xldmVsLT5uYW1lcyBpcyBpbiByZXZlcnNlIG9yZGVyLgogICAgIEJ1dCBwYXJhbWV0ZXIgZGVjbHMgd2VyZSBwcmV2aW91c2x5IHB1dCBpbiBmb3J3YXJkIG9yZGVyLiAgKi8KCiAgaWYgKHJldmVyc2UpCiAgICBjdXJyZW50X2JpbmRpbmdfbGV2ZWwtPm5hbWVzCiAgICAgID0gZGVjbHMgPSBucmV2ZXJzZSAoY3VycmVudF9iaW5kaW5nX2xldmVsLT5uYW1lcyk7CiAgZWxzZQogICAgZGVjbHMgPSBjdXJyZW50X2JpbmRpbmdfbGV2ZWwtPm5hbWVzOwoKICAvKiBJZiB0aGVyZSB3ZXJlIGFueSBkZWNsYXJhdGlvbnMgb3Igc3RydWN0dXJlIHRhZ3MgaW4gdGhhdCBsZXZlbCwKICAgICBvciBpZiB0aGlzIGxldmVsIGlzIGEgZnVuY3Rpb24gYm9keSwKICAgICBjcmVhdGUgYSBCTE9DSyB0byByZWNvcmQgdGhlbSBmb3IgdGhlIGxpZmUgb2YgdGhpcyBmdW5jdGlvbi4gICovCiAgYmxvY2sgPSBOVUxMX1RSRUU7CiAgaWYgKGtlZXAgPT0gMSB8fCBmdW5jdGlvbmJvZHkpCiAgICBibG9jayA9IG1ha2Vfbm9kZSAoQkxPQ0spOwogIGlmIChibG9jayAhPSBOVUxMX1RSRUUpCiAgICB7CiAgICAgIEJMT0NLX1ZBUlMgKGJsb2NrKSA9IGRlY2xzOwogICAgICBCTE9DS19TVUJCTE9DS1MgKGJsb2NrKSA9IHN1YmJsb2NrczsKICAgIH0KCiAgLyogSW4gZWFjaCBzdWJibG9jaywgcmVjb3JkIHRoYXQgdGhpcyBpcyBpdHMgc3VwZXJpb3IuICAqLwogIGlmIChrZWVwID49IDApCiAgICBmb3IgKGxpbmsgPSBzdWJibG9ja3M7IGxpbms7IGxpbmsgPSBUUkVFX0NIQUlOIChsaW5rKSkKICAgICAgQkxPQ0tfU1VQRVJDT05URVhUIChsaW5rKSA9IGJsb2NrOwoKICAvKiBXZSBzdGlsbCBzdXBwb3J0IHRoZSBvbGQgZm9yLXNjb3BlIHJ1bGVzLCB3aGVyZWJ5IHRoZSB2YXJpYWJsZXMKICAgICBpbiBhIGZvci1pbml0IHN0YXRlbWVudCB3ZXJlIGluIHNjb3BlIGFmdGVyIHRoZSBmb3Itc3RhdGVtZW50CiAgICAgZW5kZWQuICBXZSBvbmx5IHVzZSB0aGUgbmV3IHJ1bGVzIGlmIGZsYWdfbmV3X2Zvcl9zY29wZSBpcwogICAgIG5vbnplcm8uICAqLwogIGxlYXZpbmdfZm9yX3Njb3BlCiAgICA9IGN1cnJlbnRfYmluZGluZ19sZXZlbC0+a2luZCA9PSBza19mb3IgJiYgZmxhZ19uZXdfZm9yX3Njb3BlID09IDE7CgogIC8qIEJlZm9yZSB3ZSByZW1vdmUgdGhlIGRlY2xhcmF0aW9ucyBmaXJzdCBjaGVjayBmb3IgdW51c2VkIHZhcmlhYmxlcy4gICovCiAgaWYgKHdhcm5fdW51c2VkX3ZhcmlhYmxlCiAgICAgICYmICFwcm9jZXNzaW5nX3RlbXBsYXRlX2RlY2wpCiAgICBmb3IgKGRlY2wgPSBnZXRkZWNscyAoKTsgZGVjbDsgZGVjbCA9IFRSRUVfQ0hBSU4gKGRlY2wpKQogICAgICBpZiAoVFJFRV9DT0RFIChkZWNsKSA9PSBWQVJfREVDTAoJICAmJiAhIFRSRUVfVVNFRCAoZGVjbCkKCSAgJiYgISBERUNMX0lOX1NZU1RFTV9IRUFERVIgKGRlY2wpCgkgICYmIERFQ0xfTkFNRSAoZGVjbCkgJiYgISBERUNMX0FSVElGSUNJQUwgKGRlY2wpKQoJd2FybmluZyAoIiVKdW51c2VkIHZhcmlhYmxlICVxRCIsIGRlY2wsIGRlY2wpOwoKICAvKiBSZW1vdmUgZGVjbGFyYXRpb25zIGZvciBhbGwgdGhlIERFQ0xzIGluIHRoaXMgbGV2ZWwuICAqLwogIGZvciAobGluayA9IGRlY2xzOyBsaW5rOyBsaW5rID0gVFJFRV9DSEFJTiAobGluaykpCiAgICB7CiAgICAgIGlmIChsZWF2aW5nX2Zvcl9zY29wZSAmJiBUUkVFX0NPREUgKGxpbmspID09IFZBUl9ERUNMCiAgICAgICAgICAmJiBERUNMX05BTUUgKGxpbmspKQoJewoJICB0cmVlIG5hbWUgPSBERUNMX05BTUUgKGxpbmspOwoJICBjeHhfYmluZGluZyAqb2I7CgkgIHRyZWUgbnNfYmluZGluZzsKCgkgIG9iID0gb3V0ZXJfYmluZGluZyAobmFtZSwKCQkJICAgICAgSURFTlRJRklFUl9CSU5ESU5HIChuYW1lKSwKCQkJICAgICAgLypjbGFzc19wPSovdHJ1ZSk7CgkgIGlmICghb2IpCgkgICAgbnNfYmluZGluZyA9IElERU5USUZJRVJfTkFNRVNQQUNFX1ZBTFVFIChuYW1lKTsKCSAgZWxzZQoJICAgIG5zX2JpbmRpbmcgPSBOVUxMX1RSRUU7CgoJICBpZiAob2IgJiYgb2ItPnNjb3BlID09IGN1cnJlbnRfYmluZGluZ19sZXZlbC0+bGV2ZWxfY2hhaW4pCgkgICAgLyogV2UgaGF2ZSBzb21ldGhpbmcgbGlrZToKCgkgICAgICAgICBpbnQgaTsKCSAgICAgICAgIGZvciAoaW50IGk7IDspOwoKCSAgICAgICBhbmQgd2UgYXJlIGxlYXZpbmcgdGhlIGBmb3InIHNjb3BlLiAgVGhlcmUncyBubyByZWFzb24gdG8KCSAgICAgICBrZWVwIHRoZSBiaW5kaW5nIG9mIHRoZSBpbm5lciBgaScgaW4gdGhpcyBjYXNlLiAgKi8KCSAgICBwb3BfYmluZGluZyAobmFtZSwgbGluayk7CgkgIGVsc2UgaWYgKChvYiAmJiAoVFJFRV9DT0RFIChvYi0+dmFsdWUpID09IFRZUEVfREVDTCkpCgkJICAgfHwgKG5zX2JpbmRpbmcgJiYgVFJFRV9DT0RFIChuc19iaW5kaW5nKSA9PSBUWVBFX0RFQ0wpKQoJICAgIC8qIEhlcmUsIHdlIGhhdmUgc29tZXRoaW5nIGxpa2U6CgoJCSB0eXBlZGVmIGludCBJOwoKCQkgdm9pZCBmICgpIHsKCQkgICBmb3IgKGludCBJOyA7KTsKCQkgfQoKCSAgICAgICBXZSBtdXN0IHBvcCB0aGUgZm9yLXNjb3BlIGJpbmRpbmcgc28gd2Uga25vdyB3aGF0J3MgYQoJICAgICAgIHR5cGUgYW5kIHdoYXQgaXNuJ3QuICAqLwoJICAgIHBvcF9iaW5kaW5nIChuYW1lLCBsaW5rKTsKCSAgZWxzZQoJICAgIHsKCSAgICAgIC8qIE1hcmsgdGhpcyBWQVJfREVDTCBhcyBkZWFkIHNvIHRoYXQgd2UgY2FuIHRlbGwgd2UgbGVmdCBpdAoJCSB0aGVyZSBvbmx5IGZvciBiYWNrd2FyZCBjb21wYXRpYmlsaXR5LiAgKi8KCSAgICAgIERFQ0xfREVBRF9GT1JfTE9DQUwgKGxpbmspID0gMTsKCgkgICAgICAvKiBLZWVwIHRyYWNrIG9mIHdoYXQgc2hvdWxkIGhhdmUgaGFwcGVuZWQgd2hlbiB3ZQoJCSBwb3BwZWQgdGhlIGJpbmRpbmcuICAqLwoJICAgICAgaWYgKG9iICYmIG9iLT52YWx1ZSkKCQlERUNMX1NIQURPV0VEX0ZPUl9WQVIgKGxpbmspID0gb2ItPnZhbHVlOwoKCSAgICAgIC8qIEFkZCBpdCB0byB0aGUgbGlzdCBvZiBkZWFkIHZhcmlhYmxlcyBpbiB0aGUgbmV4dAoJCSBvdXRlcm1vc3QgYmluZGluZyB0byB0aGF0IHdlIGNhbiByZW1vdmUgdGhlc2Ugd2hlbiB3ZQoJCSBsZWF2ZSB0aGF0IGJpbmRpbmcuICAqLwoJICAgICAgY3VycmVudF9iaW5kaW5nX2xldmVsLT5sZXZlbF9jaGFpbi0+ZGVhZF92YXJzX2Zyb21fZm9yCgkJPSB0cmVlX2NvbnMgKE5VTExfVFJFRSwgbGluaywKCQkJICAgICBjdXJyZW50X2JpbmRpbmdfbGV2ZWwtPmxldmVsX2NoYWluLT4KCQkJICAgICBkZWFkX3ZhcnNfZnJvbV9mb3IpOwoKCSAgICAgIC8qIEFsdGhvdWdoIHdlIGRvbid0IHBvcCB0aGUgY3h4X2JpbmRpbmcsIHdlIGRvIGNsZWFyCgkJIGl0cyBTQ09QRSBzaW5jZSB0aGUgc2NvcGUgaXMgZ29pbmcgYXdheSBub3cuICAqLwoJICAgICAgSURFTlRJRklFUl9CSU5ESU5HIChuYW1lKS0+c2NvcGUKCQk9IGN1cnJlbnRfYmluZGluZ19sZXZlbC0+bGV2ZWxfY2hhaW47CgkgICAgfQoJfQogICAgICBlbHNlCgl7CgkgIHRyZWUgbmFtZTsKCSAgCgkgIC8qIFJlbW92ZSB0aGUgYmluZGluZy4gICovCgkgIGRlY2wgPSBsaW5rOwoKCSAgaWYgKFRSRUVfQ09ERSAoZGVjbCkgPT0gVFJFRV9MSVNUKQoJICAgIGRlY2wgPSBUUkVFX1ZBTFVFIChkZWNsKTsKCSAgbmFtZSA9IGRlY2w7CgkgIAoJICBpZiAoVFJFRV9DT0RFIChuYW1lKSA9PSBPVkVSTE9BRCkKCSAgICBuYW1lID0gT1ZMX0ZVTkNUSU9OIChuYW1lKTsKCgkgIGdjY19hc3NlcnQgKERFQ0xfUCAobmFtZSkpOwoJICBwb3BfYmluZGluZyAoREVDTF9OQU1FIChuYW1lKSwgZGVjbCk7Cgl9CiAgICB9CgogIC8qIFJlbW92ZSBkZWNsYXJhdGlvbnMgZm9yIGFueSBgZm9yJyB2YXJpYWJsZXMgZnJvbSBpbm5lciBzY29wZXMKICAgICB0aGF0IHdlIGtlcHQgYXJvdW5kLiAgKi8KICBmb3IgKGxpbmsgPSBjdXJyZW50X2JpbmRpbmdfbGV2ZWwtPmRlYWRfdmFyc19mcm9tX2ZvcjsKICAgICAgIGxpbms7IGxpbmsgPSBUUkVFX0NIQUlOIChsaW5rKSkKICAgIHBvcF9iaW5kaW5nIChERUNMX05BTUUgKFRSRUVfVkFMVUUgKGxpbmspKSwgVFJFRV9WQUxVRSAobGluaykpOwoKICAvKiBSZXN0b3JlIHRoZSBJREVOVElGSUVSX1RZUEVfVkFMVUVzLiAgKi8KICBmb3IgKGxpbmsgPSBjdXJyZW50X2JpbmRpbmdfbGV2ZWwtPnR5cGVfc2hhZG93ZWQ7CiAgICAgICBsaW5rOyBsaW5rID0gVFJFRV9DSEFJTiAobGluaykpCiAgICBTRVRfSURFTlRJRklFUl9UWVBFX1ZBTFVFIChUUkVFX1BVUlBPU0UgKGxpbmspLCBUUkVFX1ZBTFVFIChsaW5rKSk7CgogIC8qIFJlc3RvcmUgdGhlIElERU5USUZJRVJfTEFCRUxfVkFMVUVzIGZvciBsb2NhbCBsYWJlbHMuICAqLwogIGZvciAobGluayA9IGN1cnJlbnRfYmluZGluZ19sZXZlbC0+c2hhZG93ZWRfbGFiZWxzOwogICAgICAgbGluazsKICAgICAgIGxpbmsgPSBUUkVFX0NIQUlOIChsaW5rKSkKICAgIHBvcF9sYWJlbCAoVFJFRV9WQUxVRSAobGluayksIFRSRUVfUFVSUE9TRSAobGluaykpOwoKICAvKiBUaGVyZSBtYXkgYmUgT1ZFUkxPQURzICh3cmFwcGVkIGluIFRSRUVfTElTVHMpIG9uIHRoZSBCTE9DS19WQVJzCiAgICAgbGlzdCBpZiBhIGB1c2luZycgZGVjbGFyYXRpb24gcHV0IHRoZW0gdGhlcmUuICBUaGUgZGVidWdnaW5nCiAgICAgYmFjay1lbmRzIHdvbid0IHVuZGVyc3RhbmQgT1ZFUkxPQUQsIHNvIHdlIHJlbW92ZSB0aGVtIGhlcmUuCiAgICAgQmVjYXVzZSB0aGUgQkxPQ0tfVkFSUyBhcmUgKHRlbXBvcmFyaWx5KSBzaGFyZWQgd2l0aAogICAgIENVUlJFTlRfQklORElOR19MRVZFTC0+TkFNRVMgd2UgbXVzdCBkbyB0aGlzIGZpeHVwIGFmdGVyIHdlIGhhdmUKICAgICBwb3BwZWQgYWxsIHRoZSBiaW5kaW5ncy4gICovCiAgaWYgKGJsb2NrKQogICAgewogICAgICB0cmVlKiBkOwoKICAgICAgZm9yIChkID0gJkJMT0NLX1ZBUlMgKGJsb2NrKTsgKmQ7ICkKCXsKCSAgaWYgKFRSRUVfQ09ERSAoKmQpID09IFRSRUVfTElTVCkKCSAgICAqZCA9IFRSRUVfQ0hBSU4gKCpkKTsKCSAgZWxzZQoJICAgIGQgPSAmVFJFRV9DSEFJTiAoKmQpOwoJfQogICAgfQoKICAvKiBJZiB0aGUgbGV2ZWwgYmVpbmcgZXhpdGVkIGlzIHRoZSB0b3AgbGV2ZWwgb2YgYSBmdW5jdGlvbiwKICAgICBjaGVjayBvdmVyIGFsbCB0aGUgbGFiZWxzLiAgKi8KICBpZiAoZnVuY3Rpb25ib2R5KQogICAgewogICAgICAvKiBTaW5jZSB0aGlzIGlzIHRoZSB0b3AgbGV2ZWwgYmxvY2sgb2YgYSBmdW5jdGlvbiwgdGhlIHZhcnMgYXJlCgkgdGhlIGZ1bmN0aW9uJ3MgcGFyYW1ldGVycy4gIERvbid0IGxlYXZlIHRoZW0gaW4gdGhlIEJMT0NLCgkgYmVjYXVzZSB0aGV5IGFyZSBmb3VuZCBpbiB0aGUgRlVOQ1RJT05fREVDTCBpbnN0ZWFkLiAgKi8KICAgICAgQkxPQ0tfVkFSUyAoYmxvY2spID0gMDsKICAgICAgcG9wX2xhYmVscyAoYmxvY2spOwogICAgfQoKICBraW5kID0gY3VycmVudF9iaW5kaW5nX2xldmVsLT5raW5kOwogIGlmIChraW5kID09IHNrX2NsZWFudXApCiAgICB7CiAgICAgIHRyZWUgc3RtdDsKCiAgICAgIC8qIElmIHRoaXMgaXMgYSB0ZW1wb3JhcnkgYmluZGluZyBjcmVhdGVkIGZvciBhIGNsZWFudXAsIHRoZW4gd2UnbGwKCSBoYXZlIHB1c2hlZCBhIHN0YXRlbWVudCBsaXN0IGxldmVsLiAgUG9wIHRoYXQsIGNyZWF0ZSBhIG5ldwoJIEJJTkRfRVhQUiBmb3IgdGhlIGJsb2NrLCBhbmQgaW5zZXJ0IGl0IGludG8gdGhlIHN0cmVhbS4gICovCiAgICAgIHN0bXQgPSBwb3Bfc3RtdF9saXN0IChjdXJyZW50X2JpbmRpbmdfbGV2ZWwtPnN0YXRlbWVudF9saXN0KTsKICAgICAgc3RtdCA9IGNfYnVpbGRfYmluZF9leHByIChibG9jaywgc3RtdCk7CiAgICAgIGFkZF9zdG10IChzdG10KTsKICAgIH0KCiAgbGVhdmVfc2NvcGUgKCk7CiAgaWYgKGZ1bmN0aW9uYm9keSkKICAgIERFQ0xfSU5JVElBTCAoY3VycmVudF9mdW5jdGlvbl9kZWNsKSA9IGJsb2NrOwogIGVsc2UgaWYgKGJsb2NrKQogICAgY3VycmVudF9iaW5kaW5nX2xldmVsLT5ibG9ja3MKICAgICAgPSBjaGFpbm9uIChjdXJyZW50X2JpbmRpbmdfbGV2ZWwtPmJsb2NrcywgYmxvY2spOwoKICAvKiBJZiB3ZSBkaWQgbm90IG1ha2UgYSBibG9jayBmb3IgdGhlIGxldmVsIGp1c3QgZXhpdGVkLAogICAgIGFueSBibG9ja3MgbWFkZSBmb3IgaW5uZXIgbGV2ZWxzCiAgICAgKHNpbmNlIHRoZXkgY2Fubm90IGJlIHJlY29yZGVkIGFzIHN1YmJsb2NrcyBpbiB0aGF0IGxldmVsKQogICAgIG11c3QgYmUgY2FycmllZCBmb3J3YXJkIHNvIHRoZXkgd2lsbCBsYXRlciBiZWNvbWUgc3ViYmxvY2tzCiAgICAgb2Ygc29tZXRoaW5nIGVsc2UuICAqLwogIGVsc2UgaWYgKHN1YmJsb2NrcykKICAgIGN1cnJlbnRfYmluZGluZ19sZXZlbC0+YmxvY2tzCiAgICAgID0gY2hhaW5vbiAoY3VycmVudF9iaW5kaW5nX2xldmVsLT5ibG9ja3MsIHN1YmJsb2Nrcyk7CgogIC8qIEVhY2ggYW5kIGV2ZXJ5IEJMT0NLIG5vZGUgY3JlYXRlZCBoZXJlIGluIGBwb3BsZXZlbCcgaXMgaW1wb3J0YW50CiAgICAgKGUuZy4gZm9yIHByb3BlciBkZWJ1Z2dpbmcgaW5mb3JtYXRpb24pIHNvIGlmIHdlIGNyZWF0ZWQgb25lCiAgICAgZWFybGllciwgbWFyayBpdCBhcyAidXNlZCIuICAqLwogIGlmIChibG9jaykKICAgIFRSRUVfVVNFRCAoYmxvY2spID0gMTsKCiAgLyogQWxsIHRlbXBvcmFyeSBiaW5kaW5ncyBjcmVhdGVkIGZvciBjbGVhbnVwcyBhcmUgcG9wcGVkIHNpbGVudGx5LiAgKi8KICBpZiAoa2luZCA9PSBza19jbGVhbnVwKQogICAgZ290byByZXN0YXJ0OwoKICBQT1BfVElNRVZBUl9BTkRfUkVUVVJOIChUVl9OQU1FX0xPT0tVUCwgYmxvY2spOwp9CgovKiBJbnNlcnQgQkxPQ0sgYXQgdGhlIGVuZCBvZiB0aGUgbGlzdCBvZiBzdWJibG9ja3Mgb2YgdGhlCiAgIGN1cnJlbnQgYmluZGluZyBsZXZlbC4gIFRoaXMgaXMgdXNlZCB3aGVuIGEgQklORF9FWFBSIGlzIGV4cGFuZGVkLAogICB0byBoYW5kbGUgdGhlIEJMT0NLIG5vZGUgaW5zaWRlIHRoZSBCSU5EX0VYUFIuICAqLwoKdm9pZAppbnNlcnRfYmxvY2sgKHRyZWUgYmxvY2spCnsKICBUUkVFX1VTRUQgKGJsb2NrKSA9IDE7CiAgY3VycmVudF9iaW5kaW5nX2xldmVsLT5ibG9ja3MKICAgID0gY2hhaW5vbiAoY3VycmVudF9iaW5kaW5nX2xldmVsLT5ibG9ja3MsIGJsb2NrKTsKfQoKLyogV2FsayBhbGwgdGhlIG5hbWVzcGFjZXMgY29udGFpbmVkIE5BTUVTUEFDRSwgaW5jbHVkaW5nIE5BTUVTUEFDRQogICBpdHNlbGYsIGNhbGxpbmcgRiBmb3IgZWFjaC4gIFRoZSBEQVRBIGlzIHBhc3NlZCB0byBGIGFzIHdlbGwuICAqLwoKc3RhdGljIGludAp3YWxrX25hbWVzcGFjZXNfciAodHJlZSBuYW1lc3BhY2UsIHdhbGtfbmFtZXNwYWNlc19mbiBmLCB2b2lkKiBkYXRhKQp7CiAgaW50IHJlc3VsdCA9IDA7CiAgdHJlZSBjdXJyZW50ID0gTkFNRVNQQUNFX0xFVkVMIChuYW1lc3BhY2UpLT5uYW1lc3BhY2VzOwoKICByZXN1bHQgfD0gKCpmKSAobmFtZXNwYWNlLCBkYXRhKTsKCiAgZm9yICg7IGN1cnJlbnQ7IGN1cnJlbnQgPSBUUkVFX0NIQUlOIChjdXJyZW50KSkKICAgIHJlc3VsdCB8PSB3YWxrX25hbWVzcGFjZXNfciAoY3VycmVudCwgZiwgZGF0YSk7CgogIHJldHVybiByZXN1bHQ7Cn0KCi8qIFdhbGsgYWxsIHRoZSBuYW1lc3BhY2VzLCBjYWxsaW5nIEYgZm9yIGVhY2guICBUaGUgREFUQSBpcyBwYXNzZWQgdG8KICAgRiBhcyB3ZWxsLiAgKi8KCmludAp3YWxrX25hbWVzcGFjZXMgKHdhbGtfbmFtZXNwYWNlc19mbiBmLCB2b2lkKiBkYXRhKQp7CiAgcmV0dXJuIHdhbGtfbmFtZXNwYWNlc19yIChnbG9iYWxfbmFtZXNwYWNlLCBmLCBkYXRhKTsKfQoKLyogQ2FsbCB3cmFwdXBfZ2xvYmFsc19kZWNsYXJhdGlvbnMgZm9yIHRoZSBnbG9iYWxzIGluIE5BTUVTUEFDRS4gIElmCiAgIERBVEEgaXMgbm9uLU5VTEwsIHRoaXMgaXMgdGhlIGxhc3QgdGltZSB3ZSB3aWxsIGNhbGwKICAgd3JhcHVwX2dsb2JhbF9kZWNsYXJhdGlvbnMgZm9yIHRoaXMgTkFNRVNQQUNFLiAgKi8KCmludAp3cmFwdXBfZ2xvYmFsc19mb3JfbmFtZXNwYWNlICh0cmVlIG5hbWVzcGFjZSwgdm9pZCogZGF0YSkKewogIHN0cnVjdCBjcF9iaW5kaW5nX2xldmVsICpsZXZlbCA9IE5BTUVTUEFDRV9MRVZFTCAobmFtZXNwYWNlKTsKICB2YXJyYXlfdHlwZSBzdGF0aWNzID0gbGV2ZWwtPnN0YXRpY19kZWNsczsKICB0cmVlICp2ZWMgPSAmVkFSUkFZX1RSRUUgKHN0YXRpY3MsIDApOwogIGludCBsZW4gPSBWQVJSQVlfQUNUSVZFX1NJWkUgKHN0YXRpY3MpOwogIGludCBsYXN0X3RpbWUgPSAoZGF0YSAhPSAwKTsKCiAgaWYgKGxhc3RfdGltZSkKICAgIHsKICAgICAgY2hlY2tfZ2xvYmFsX2RlY2xhcmF0aW9ucyAodmVjLCBsZW4pOwogICAgICByZXR1cm4gMDsKICAgIH0KCiAgLyogV3JpdGUgb3V0IGFueSBnbG9iYWxzIHRoYXQgbmVlZCB0byBiZSBvdXRwdXQuICAqLwogIHJldHVybiB3cmFwdXBfZ2xvYmFsX2RlY2xhcmF0aW9ucyAodmVjLCBsZW4pOwp9CgoMCi8qIEluIEMrKywgeW91IGRvbid0IGhhdmUgdG8gd3JpdGUgYHN0cnVjdCBTJyB0byByZWZlciB0byBgUyc7IHlvdQogICBjYW4ganVzdCB1c2UgYFMnLiAgV2UgYWNjb21wbGlzaCB0aGlzIGJ5IGNyZWF0aW5nIGEgVFlQRV9ERUNMIGFzCiAgIGlmIHRoZSB1c2VyIGhhZCB3cml0dGVuIGB0eXBlZGVmIHN0cnVjdCBTIFMnLiAgQ3JlYXRlIGFuZCByZXR1cm4KICAgdGhlIFRZUEVfREVDTCBmb3IgVFlQRS4gICovCgp0cmVlCmNyZWF0ZV9pbXBsaWNpdF90eXBlZGVmICh0cmVlIG5hbWUsIHRyZWUgdHlwZSkKewogIHRyZWUgZGVjbDsKCiAgZGVjbCA9IGJ1aWxkX2RlY2wgKFRZUEVfREVDTCwgbmFtZSwgdHlwZSk7CiAgREVDTF9BUlRJRklDSUFMIChkZWNsKSA9IDE7CiAgLyogVGhlcmUgYXJlIG90aGVyIGltcGxpY2l0IHR5cGUgZGVjbGFyYXRpb25zLCBsaWtlIHRoZSBvbmUgKndpdGhpbioKICAgICBhIGNsYXNzIHRoYXQgYWxsb3dzIHlvdSB0byB3cml0ZSBgUzo6UycuICBXZSBtdXN0IGRpc3Rpbmd1aXNoCiAgICAgYW1vbmdzdCB0aGVzZS4gICovCiAgU0VUX0RFQ0xfSU1QTElDSVRfVFlQRURFRl9QIChkZWNsKTsKICBUWVBFX05BTUUgKHR5cGUpID0gZGVjbDsKCiAgcmV0dXJuIGRlY2w7Cn0KCi8qIFJlbWVtYmVyIGEgbG9jYWwgbmFtZSBmb3IgbmFtZS1tYW5nbGluZyBwdXJwb3Nlcy4gICovCgpzdGF0aWMgdm9pZApwdXNoX2xvY2FsX25hbWUgKHRyZWUgZGVjbCkKewogIHNpemVfdCBpLCBuZWx0czsKICB0cmVlIHQsIG5hbWU7CgogIHRpbWV2YXJfcHVzaCAoVFZfTkFNRV9MT09LVVApOwogIGlmICghbG9jYWxfbmFtZXMpCiAgICBWQVJSQVlfVFJFRV9JTklUIChsb2NhbF9uYW1lcywgOCwgImxvY2FsX25hbWVzIik7CgogIG5hbWUgPSBERUNMX05BTUUgKGRlY2wpOwoKICBuZWx0cyA9IFZBUlJBWV9BQ1RJVkVfU0laRSAobG9jYWxfbmFtZXMpOwogIGZvciAoaSA9IDA7IGkgPCBuZWx0czsgaSsrKQogICAgewogICAgICB0ID0gVkFSUkFZX1RSRUUgKGxvY2FsX25hbWVzLCBpKTsKICAgICAgaWYgKERFQ0xfTkFNRSAodCkgPT0gbmFtZSkKCXsKCSAgaWYgKCFERUNMX0xBTkdfU1BFQ0lGSUMgKGRlY2wpKQoJICAgIHJldHJvZml0X2xhbmdfZGVjbCAoZGVjbCk7CgkgIERFQ0xfTEFOR19TUEVDSUZJQyAoZGVjbCktPmRlY2xfZmxhZ3MudTJzZWwgPSAxOwoJICBpZiAoREVDTF9MQU5HX1NQRUNJRklDICh0KSkKCSAgICBERUNMX0RJU0NSSU1JTkFUT1IgKGRlY2wpID0gREVDTF9ESVNDUklNSU5BVE9SICh0KSArIDE7CgkgIGVsc2UKCSAgICBERUNMX0RJU0NSSU1JTkFUT1IgKGRlY2wpID0gMTsKCgkgIFZBUlJBWV9UUkVFIChsb2NhbF9uYW1lcywgaSkgPSBkZWNsOwoJICB0aW1ldmFyX3BvcCAoVFZfTkFNRV9MT09LVVApOwoJICByZXR1cm47Cgl9CiAgICB9CgogIFZBUlJBWV9QVVNIX1RSRUUgKGxvY2FsX25hbWVzLCBkZWNsKTsKICB0aW1ldmFyX3BvcCAoVFZfTkFNRV9MT09LVVApOwp9CgwKLyogU3Vicm91dGluZSBvZiBkdXBsaWNhdGVfZGVjbHM6IHJldHVybiB0cnV0aHZhbHVlIG9mIHdoZXRoZXIKICAgb3Igbm90IHR5cGVzIG9mIHRoZXNlIGRlY2xzIG1hdGNoLgoKICAgRm9yIEMrKywgd2UgbXVzdCBjb21wYXJlIHRoZSBwYXJhbWV0ZXIgbGlzdCBzbyB0aGF0IGBpbnQnIGNhbiBtYXRjaAogICBgaW50JicgaW4gYSBwYXJhbWV0ZXIgcG9zaXRpb24sIGJ1dCBgaW50JicgaXMgbm90IGNvbmZ1c2VkIHdpdGgKICAgYGNvbnN0IGludCYnLiAgKi8KCmludApkZWNsc19tYXRjaCAodHJlZSBuZXdkZWNsLCB0cmVlIG9sZGRlY2wpCnsKICBpbnQgdHlwZXNfbWF0Y2g7CgogIGlmIChuZXdkZWNsID09IG9sZGRlY2wpCiAgICByZXR1cm4gMTsKCiAgaWYgKFRSRUVfQ09ERSAobmV3ZGVjbCkgIT0gVFJFRV9DT0RFIChvbGRkZWNsKSkKICAgIC8qIElmIHRoZSB0d28gREVDTHMgYXJlIG5vdCBldmVuIHRoZSBzYW1lIGtpbmQgb2YgdGhpbmcsIHdlJ3JlIG5vdAogICAgICAgaW50ZXJlc3RlZCBpbiB0aGVpciB0eXBlcy4gICovCiAgICByZXR1cm4gMDsKCiAgaWYgKFRSRUVfQ09ERSAobmV3ZGVjbCkgPT0gRlVOQ1RJT05fREVDTCkKICAgIHsKICAgICAgdHJlZSBmMSA9IFRSRUVfVFlQRSAobmV3ZGVjbCk7CiAgICAgIHRyZWUgZjIgPSBUUkVFX1RZUEUgKG9sZGRlY2wpOwogICAgICB0cmVlIHAxID0gVFlQRV9BUkdfVFlQRVMgKGYxKTsKICAgICAgdHJlZSBwMiA9IFRZUEVfQVJHX1RZUEVTIChmMik7CgogICAgICBpZiAoQ1BfREVDTF9DT05URVhUIChuZXdkZWNsKSAhPSBDUF9ERUNMX0NPTlRFWFQgKG9sZGRlY2wpCgkgICYmICEgKERFQ0xfRVhURVJOX0NfUCAobmV3ZGVjbCkKCQkmJiBERUNMX0VYVEVSTl9DX1AgKG9sZGRlY2wpKSkKCXJldHVybiAwOwoKICAgICAgaWYgKFRSRUVfQ09ERSAoZjEpICE9IFRSRUVfQ09ERSAoZjIpKQogICAgICAgIHJldHVybiAwOwoKICAgICAgaWYgKHNhbWVfdHlwZV9wIChUUkVFX1RZUEUgKGYxKSwgVFJFRV9UWVBFIChmMikpKQoJewoJICBpZiAocDIgPT0gTlVMTF9UUkVFICYmIERFQ0xfRVhURVJOX0NfUCAob2xkZGVjbCkKCSAgICAgICYmIChERUNMX0JVSUxUX0lOIChvbGRkZWNsKQojaWZuZGVmIE5PX0lNUExJQ0lUX0VYVEVSTl9DCgkgICAgICAgICAgfHwgKERFQ0xfSU5fU1lTVEVNX0hFQURFUiAobmV3ZGVjbCkgJiYgIURFQ0xfQ0xBU1NfU0NPUEVfUCAobmV3ZGVjbCkpCgkgICAgICAgICAgfHwgKERFQ0xfSU5fU1lTVEVNX0hFQURFUiAob2xkZGVjbCkgJiYgIURFQ0xfQ0xBU1NfU0NPUEVfUCAob2xkZGVjbCkpCiNlbmRpZgoJICAgICAgKSkKCSAgICB7CgkgICAgICB0eXBlc19tYXRjaCA9IHNlbGZfcHJvbW90aW5nX2FyZ3NfcCAocDEpOwoJICAgICAgaWYgKHAxID09IHZvaWRfbGlzdF9ub2RlKQoJCVRSRUVfVFlQRSAobmV3ZGVjbCkgPSBUUkVFX1RZUEUgKG9sZGRlY2wpOwoJICAgIH0KI2lmbmRlZiBOT19JTVBMSUNJVF9FWFRFUk5fQwoJICBlbHNlIGlmIChwMSA9PSBOVUxMX1RSRUUKCQkgICAmJiAoREVDTF9FWFRFUk5fQ19QIChvbGRkZWNsKQoJICAgICAgICAgICAgICAgJiYgREVDTF9JTl9TWVNURU1fSEVBREVSIChvbGRkZWNsKQoJICAgICAgICAgICAgICAgJiYgIURFQ0xfQ0xBU1NfU0NPUEVfUCAob2xkZGVjbCkpCgkJICAgJiYgKERFQ0xfRVhURVJOX0NfUCAobmV3ZGVjbCkKCSAgICAgICAgICAgICAgICYmIERFQ0xfSU5fU1lTVEVNX0hFQURFUiAobmV3ZGVjbCkKCSAgICAgICAgICAgICAgICYmICFERUNMX0NMQVNTX1NDT1BFX1AgKG5ld2RlY2wpKSkKCSAgICB7CgkgICAgICB0eXBlc19tYXRjaCA9IHNlbGZfcHJvbW90aW5nX2FyZ3NfcCAocDIpOwoJICAgICAgVFJFRV9UWVBFIChuZXdkZWNsKSA9IFRSRUVfVFlQRSAob2xkZGVjbCk7CgkgICAgfQojZW5kaWYKCSAgZWxzZQoJICAgIHR5cGVzX21hdGNoID0gY29tcHBhcm1zIChwMSwgcDIpOwoJfQogICAgICBlbHNlCgl0eXBlc19tYXRjaCA9IDA7CiAgICB9CiAgZWxzZSBpZiAoVFJFRV9DT0RFIChuZXdkZWNsKSA9PSBURU1QTEFURV9ERUNMKQogICAgewogICAgICBpZiAoVFJFRV9DT0RFIChERUNMX1RFTVBMQVRFX1JFU1VMVCAobmV3ZGVjbCkpCgkgICE9IFRSRUVfQ09ERSAoREVDTF9URU1QTEFURV9SRVNVTFQgKG9sZGRlY2wpKSkKCXJldHVybiAwOwoKICAgICAgaWYgKCFjb21wX3RlbXBsYXRlX3Bhcm1zIChERUNMX1RFTVBMQVRFX1BBUk1TIChuZXdkZWNsKSwKCQkJCURFQ0xfVEVNUExBVEVfUEFSTVMgKG9sZGRlY2wpKSkKCXJldHVybiAwOwoKICAgICAgaWYgKFRSRUVfQ09ERSAoREVDTF9URU1QTEFURV9SRVNVTFQgKG5ld2RlY2wpKSA9PSBUWVBFX0RFQ0wpCgl0eXBlc19tYXRjaCA9IHNhbWVfdHlwZV9wIChUUkVFX1RZUEUgKERFQ0xfVEVNUExBVEVfUkVTVUxUIChvbGRkZWNsKSksCgkJCQkgICBUUkVFX1RZUEUgKERFQ0xfVEVNUExBVEVfUkVTVUxUIChuZXdkZWNsKSkpOwogICAgICBlbHNlCgl0eXBlc19tYXRjaCA9IGRlY2xzX21hdGNoIChERUNMX1RFTVBMQVRFX1JFU1VMVCAob2xkZGVjbCksCgkJCQkgICBERUNMX1RFTVBMQVRFX1JFU1VMVCAobmV3ZGVjbCkpOwogICAgfQogIGVsc2UKICAgIHsKICAgICAgLyogTmVlZCB0byBjaGVjayBzY29wZSBmb3IgdmFyaWFibGUgZGVjbGFyYXRpb24gKFZBUl9ERUNMKS4KCSBGb3IgdHlwZWRlZiAoVFlQRV9ERUNMKSwgc2NvcGUgaXMgaWdub3JlZC4gICovCiAgICAgIGlmIChUUkVFX0NPREUgKG5ld2RlY2wpID09IFZBUl9ERUNMCgkgICYmIENQX0RFQ0xfQ09OVEVYVCAobmV3ZGVjbCkgIT0gQ1BfREVDTF9DT05URVhUIChvbGRkZWNsKSkKCXJldHVybiAwOwoKICAgICAgaWYgKFRSRUVfVFlQRSAobmV3ZGVjbCkgPT0gZXJyb3JfbWFya19ub2RlKQoJdHlwZXNfbWF0Y2ggPSBUUkVFX1RZUEUgKG9sZGRlY2wpID09IGVycm9yX21hcmtfbm9kZTsKICAgICAgZWxzZSBpZiAoVFJFRV9UWVBFIChvbGRkZWNsKSA9PSBOVUxMX1RSRUUpCgl0eXBlc19tYXRjaCA9IFRSRUVfVFlQRSAobmV3ZGVjbCkgPT0gTlVMTF9UUkVFOwogICAgICBlbHNlIGlmIChUUkVFX1RZUEUgKG5ld2RlY2wpID09IE5VTExfVFJFRSkKCXR5cGVzX21hdGNoID0gMDsKICAgICAgZWxzZQoJdHlwZXNfbWF0Y2ggPSBjb21wdHlwZXMgKFRSRUVfVFlQRSAobmV3ZGVjbCksCgkJCQkgVFJFRV9UWVBFIChvbGRkZWNsKSwKCQkJCSBDT01QQVJFX1JFREVDTEFSQVRJT04pOwogICAgfQoKICByZXR1cm4gdHlwZXNfbWF0Y2g7Cn0KCi8qIElmIE5FV0RFQ0wgaXMgYHN0YXRpYycgYW5kIGFuIGBleHRlcm4nIHdhcyBzZWVuIHByZXZpb3VzbHksCiAgIHdhcm4gYWJvdXQgaXQuICBPTERERUNMIGlzIHRoZSBwcmV2aW91cyBkZWNsYXJhdGlvbi4KCiAgIE5vdGUgdGhhdCB0aGlzIGRvZXMgbm90IGFwcGx5IHRvIHRoZSBDKysgY2FzZSBvZiBkZWNsYXJpbmcKICAgYSB2YXJpYWJsZSBgZXh0ZXJuIGNvbnN0JyBhbmQgdGhlbiBsYXRlciBgY29uc3QnLgoKICAgRG9uJ3QgY29tcGxhaW4gYWJvdXQgYnVpbHQtaW4gZnVuY3Rpb25zLCBzaW5jZSB0aGV5IGFyZSBiZXlvbmQKICAgdGhlIHVzZXIncyBjb250cm9sLiAgKi8KCnZvaWQKd2Fybl9leHRlcm5fcmVkZWNsYXJlZF9zdGF0aWMgKHRyZWUgbmV3ZGVjbCwgdHJlZSBvbGRkZWNsKQp7CiAgdHJlZSBuYW1lOwoKICBpZiAoVFJFRV9DT0RFIChuZXdkZWNsKSA9PSBUWVBFX0RFQ0wKICAgICAgfHwgVFJFRV9DT0RFIChuZXdkZWNsKSA9PSBURU1QTEFURV9ERUNMCiAgICAgIHx8IFRSRUVfQ09ERSAobmV3ZGVjbCkgPT0gQ09OU1RfREVDTAogICAgICB8fCBUUkVFX0NPREUgKG5ld2RlY2wpID09IE5BTUVTUEFDRV9ERUNMKQogICAgcmV0dXJuOwoKICAvKiBEb24ndCBnZXQgY29uZnVzZWQgYnkgc3RhdGljIG1lbWJlciBmdW5jdGlvbnM7IHRoYXQncyBhIGRpZmZlcmVudAogICAgIHVzZSBvZiBgc3RhdGljJy4gICovCiAgaWYgKFRSRUVfQ09ERSAobmV3ZGVjbCkgPT0gRlVOQ1RJT05fREVDTAogICAgICAmJiBERUNMX1NUQVRJQ19GVU5DVElPTl9QIChuZXdkZWNsKSkKICAgIHJldHVybjsKCiAgLyogSWYgdGhlIG9sZCBkZWNsYXJhdGlvbiB3YXMgYHN0YXRpYycsIG9yIHRoZSBuZXcgb25lIGlzbid0LCB0aGVuCiAgICAgdGhlbiBldmVyeXRoaW5nIGlzIE9LLiAgKi8KICBpZiAoREVDTF9USElTX1NUQVRJQyAob2xkZGVjbCkgfHwgIURFQ0xfVEhJU19TVEFUSUMgKG5ld2RlY2wpKQogICAgcmV0dXJuOwoKICAvKiBJdCdzIE9LIHRvIGRlY2xhcmUgYSBidWlsdGluIGZ1bmN0aW9uIGFzIGBzdGF0aWMnLiAgKi8KICBpZiAoVFJFRV9DT0RFIChvbGRkZWNsKSA9PSBGVU5DVElPTl9ERUNMCiAgICAgICYmIERFQ0xfQVJUSUZJQ0lBTCAob2xkZGVjbCkpCiAgICByZXR1cm47CgogIG5hbWUgPSBERUNMX0FTU0VNQkxFUl9OQU1FIChuZXdkZWNsKTsKICBwZWR3YXJuICgiJXFEIHdhcyBkZWNsYXJlZCAlPGV4dGVybiU+IGFuZCBsYXRlciAlPHN0YXRpYyU+IiwgbmV3ZGVjbCk7CiAgY3BfcGVkd2Fybl9hdCAoInByZXZpb3VzIGRlY2xhcmF0aW9uIG9mICVxRCIsIG9sZGRlY2wpOwp9CgovKiBJZiBORVdERUNMIGlzIGEgcmVkZWNsYXJhdGlvbiBvZiBPTERERUNMLCBtZXJnZSB0aGUgZGVjbGFyYXRpb25zLgogICBJZiB0aGUgcmVkZWNsYXJhdGlvbiBpcyBpbnZhbGlkLCBhIGRpYWdub3N0aWMgaXMgaXNzdWVkLCBhbmQgdGhlCiAgIGVycm9yX21hcmtfbm9kZSBpcyByZXR1cm5lZC4gIE90aGVyd2lzZSwgT0xEREVDTCBpcyByZXR1cm5lZC4KCiAgIElmIE5FV0RFQ0wgaXMgbm90IGEgcmVkZWNsYXJhdGlvbiBvZiBPTERERUNMLCBOVUxMX1RSRUUgaXMKICAgcmV0dXJuZWQuICAqLwoKdHJlZQpkdXBsaWNhdGVfZGVjbHMgKHRyZWUgbmV3ZGVjbCwgdHJlZSBvbGRkZWNsKQp7CiAgdW5zaWduZWQgb2xkZGVjbF91aWQgPSBERUNMX1VJRCAob2xkZGVjbCk7CiAgaW50IG9sZGRlY2xfZnJpZW5kID0gMCwgdHlwZXNfbWF0Y2ggPSAwOwogIGludCBuZXdfZGVmaW5lc19mdW5jdGlvbiA9IDA7CiAgLyogQVBQTEUgTE9DQUwgbWFpbmxpbmUgMjAwNS0xMi0wMiBSYWRhciA0NDU4Mjc2ICAqLwogIHRyZWUgbmV3X3RlbXBsYXRlOwoKICBpZiAobmV3ZGVjbCA9PSBvbGRkZWNsKQogICAgcmV0dXJuIG9sZGRlY2w7CgogIHR5cGVzX21hdGNoID0gZGVjbHNfbWF0Y2ggKG5ld2RlY2wsIG9sZGRlY2wpOwoKICAvKiBJZiBlaXRoZXIgdGhlIHR5cGUgb2YgdGhlIG5ldyBkZWNsIG9yIHRoZSB0eXBlIG9mIHRoZSBvbGQgZGVjbCBpcyBhbgogICAgIGVycm9yX21hcmtfbm9kZSwgdGhlbiB0aGF0IGltcGxpZXMgdGhhdCB3ZSBoYXZlIGFscmVhZHkgaXNzdWVkIGFuCiAgICAgZXJyb3IgKGVhcmxpZXIpIGZvciBzb21lIGJvZ3VzIHR5cGUgc3BlY2lmaWNhdGlvbiwgYW5kIGluIHRoYXQgY2FzZSwKICAgICBpdCBpcyByYXRoZXIgcG9pbnRsZXNzIHRvIGhhcmFzcyB0aGUgdXNlciB3aXRoIHlldCBtb3JlIGVycm9yIG1lc3NhZ2UKICAgICBhYm91dCB0aGUgc2FtZSBkZWNsYXJhdGlvbiwgc28ganVzdCBwcmV0ZW5kIHRoZSB0eXBlcyBtYXRjaCBoZXJlLiAgKi8KICBpZiAoVFJFRV9UWVBFIChuZXdkZWNsKSA9PSBlcnJvcl9tYXJrX25vZGUKICAgICAgfHwgVFJFRV9UWVBFIChvbGRkZWNsKSA9PSBlcnJvcl9tYXJrX25vZGUpCiAgICB0eXBlc19tYXRjaCA9IDE7CgogIGlmIChERUNMX1AgKG9sZGRlY2wpCiAgICAgICYmIFRSRUVfQ09ERSAobmV3ZGVjbCkgPT0gRlVOQ1RJT05fREVDTAogICAgICAmJiBUUkVFX0NPREUgKG9sZGRlY2wpID09IEZVTkNUSU9OX0RFQ0wKICAgICAgJiYgKERFQ0xfVU5JTkxJTkFCTEUgKG5ld2RlY2wpIHx8IERFQ0xfVU5JTkxJTkFCTEUgKG9sZGRlY2wpKSkKICAgIHsKICAgICAgaWYgKERFQ0xfREVDTEFSRURfSU5MSU5FX1AgKG5ld2RlY2wpCgkgICYmIERFQ0xfVU5JTkxJTkFCTEUgKG5ld2RlY2wpCgkgICYmIGxvb2t1cF9hdHRyaWJ1dGUgKCJub2lubGluZSIsIERFQ0xfQVRUUklCVVRFUyAobmV3ZGVjbCkpKQoJLyogQWxyZWFkeSB3YXJuZWQgZWxzZXdoZXJlLiAgKi87CiAgICAgIGVsc2UgaWYgKERFQ0xfREVDTEFSRURfSU5MSU5FX1AgKG9sZGRlY2wpCgkgICAgICAgJiYgREVDTF9VTklOTElOQUJMRSAob2xkZGVjbCkKCSAgICAgICAmJiBsb29rdXBfYXR0cmlidXRlICgibm9pbmxpbmUiLCBERUNMX0FUVFJJQlVURVMgKG9sZGRlY2wpKSkKCS8qIEFscmVhZHkgd2FybmVkLiAgKi87CiAgICAgIGVsc2UgaWYgKERFQ0xfREVDTEFSRURfSU5MSU5FX1AgKG5ld2RlY2wpCgkgICAgICAgJiYgREVDTF9VTklOTElOQUJMRSAob2xkZGVjbCkKCSAgICAgICAmJiBsb29rdXBfYXR0cmlidXRlICgibm9pbmxpbmUiLCBERUNMX0FUVFJJQlVURVMgKG9sZGRlY2wpKSkKCXsKCSAgd2FybmluZyAoIiVKZnVuY3Rpb24gJXFEIHJlZGVjbGFyZWQgYXMgaW5saW5lIiwgbmV3ZGVjbCwgbmV3ZGVjbCk7CgkgIHdhcm5pbmcgKCIlSnByZXZpb3VzIGRlY2xhcmF0aW9uIG9mICVxRCB3aXRoIGF0dHJpYnV0ZSBub2lubGluZSIsCiAgICAgICAgICAgICAgICAgICBvbGRkZWNsLCBvbGRkZWNsKTsKCX0KICAgICAgZWxzZSBpZiAoREVDTF9ERUNMQVJFRF9JTkxJTkVfUCAob2xkZGVjbCkKCSAgICAgICAmJiBERUNMX1VOSU5MSU5BQkxFIChuZXdkZWNsKQoJICAgICAgICYmIGxvb2t1cF9hdHRyaWJ1dGUgKCJub2lubGluZSIsIERFQ0xfQVRUUklCVVRFUyAobmV3ZGVjbCkpKQoJewoJICB3YXJuaW5nICgiJUpmdW5jdGlvbiAlcUQgcmVkZWNsYXJlZCB3aXRoIGF0dHJpYnV0ZSBub2lubGluZSIsCgkJICAgbmV3ZGVjbCwgbmV3ZGVjbCk7CgkgIHdhcm5pbmcgKCIlSnByZXZpb3VzIGRlY2xhcmF0aW9uIG9mICVxRCB3YXMgaW5saW5lIiwKCQkgICBvbGRkZWNsLCBvbGRkZWNsKTsKCX0KICAgIH0KCiAgLyogQ2hlY2sgZm9yIHJlZGVjbGFyYXRpb24gYW5kIG90aGVyIGRpc2NyZXBhbmNpZXMuICAqLwogIGlmIChUUkVFX0NPREUgKG9sZGRlY2wpID09IEZVTkNUSU9OX0RFQ0wKICAgICAgJiYgREVDTF9BUlRJRklDSUFMIChvbGRkZWNsKSkKICAgIHsKICAgICAgaWYgKFRSRUVfQ09ERSAobmV3ZGVjbCkgIT0gRlVOQ1RJT05fREVDTCkKCXsKICAgICAgICAgIC8qIEF2b2lkIHdhcm5pbmdzIHJlZGVjbGFyaW5nIGFudGljaXBhdGVkIGJ1aWx0LWlucy4gICovCiAgICAgICAgICBpZiAoREVDTF9BTlRJQ0lQQVRFRCAob2xkZGVjbCkpCiAgICAgICAgICAgIHJldHVybiBOVUxMX1RSRUU7CgoJICAvKiBJZiB5b3UgZGVjbGFyZSBhIGJ1aWx0LWluIG9yIHByZWRlZmluZWQgZnVuY3Rpb24gbmFtZSBhcyBzdGF0aWMsCgkgICAgIHRoZSBvbGQgZGVmaW5pdGlvbiBpcyBvdmVycmlkZGVuLCBidXQgb3B0aW9uYWxseSB3YXJuIHRoaXMgd2FzIGEKCSAgICAgYmFkIGNob2ljZSBvZiBuYW1lLiAgKi8KCSAgaWYgKCEgVFJFRV9QVUJMSUMgKG5ld2RlY2wpKQoJICAgIHsKCSAgICAgIGlmICh3YXJuX3NoYWRvdykKICAgICAgICAgICAgICAgIHdhcm5pbmcgKCJzaGFkb3dpbmcgJXMgZnVuY3Rpb24gJXEjRCIsCiAgICAgICAgICAgICAgICAgICAgICAgICBERUNMX0JVSUxUX0lOIChvbGRkZWNsKSA/ICJidWlsdC1pbiIgOiAibGlicmFyeSIsCiAgICAgICAgICAgICAgICAgICAgICAgICBvbGRkZWNsKTsKCSAgICAgIC8qIERpc2NhcmQgdGhlIG9sZCBidWlsdC1pbiBmdW5jdGlvbi4gICovCgkgICAgICByZXR1cm4gTlVMTF9UUkVFOwoJICAgIH0KCSAgLyogSWYgdGhlIGJ1aWx0LWluIGlzIG5vdCBhbnNpLCB0aGVuIHByb2dyYW1zIGNhbiBvdmVycmlkZQoJICAgICBpdCBldmVuIGdsb2JhbGx5IHdpdGhvdXQgYW4gZXJyb3IuICAqLwoJICBlbHNlIGlmICghIERFQ0xfQlVJTFRfSU4gKG9sZGRlY2wpKQoJICAgIHdhcm5pbmcgKCJsaWJyYXJ5IGZ1bmN0aW9uICVxI0QgcmVkZWNsYXJlZCBhcyBub24tZnVuY3Rpb24gJXEjRCIsCiAgICAgICAgICAgICAgICAgICAgIG9sZGRlY2wsIG5ld2RlY2wpOwoJICBlbHNlCgkgICAgewoJICAgICAgZXJyb3IgKCJkZWNsYXJhdGlvbiBvZiAlcSNEIiwgbmV3ZGVjbCk7CgkgICAgICBlcnJvciAoImNvbmZsaWN0cyB3aXRoIGJ1aWx0LWluIGRlY2xhcmF0aW9uICVxI0QiLAogICAgICAgICAgICAgICAgICAgICBvbGRkZWNsKTsKCSAgICB9CgkgIHJldHVybiBOVUxMX1RSRUU7Cgl9CiAgICAgIGVsc2UgaWYgKCF0eXBlc19tYXRjaCkKCXsKICAgICAgICAgIC8qIEF2b2lkIHdhcm5pbmdzIHJlZGVjbGFyaW5nIGFudGljaXBhdGVkIGJ1aWx0LWlucy4gICovCiAgICAgICAgICBpZiAoREVDTF9BTlRJQ0lQQVRFRCAob2xkZGVjbCkpCgkgICAgewoJICAgICAgLyogRGVhbCB3aXRoIGZpbGVwdHJfdHlwZV9ub2RlLiAgRklMRSB0eXBlIGlzIG5vdCBrbm93bgoJCSBhdCB0aGUgdGltZSB3ZSBjcmVhdGUgdGhlIGJ1aWx0aW5zLiAgKi8KCSAgICAgIHRyZWUgdDEsIHQyOwoKCSAgICAgIGZvciAodDEgPSBUWVBFX0FSR19UWVBFUyAoVFJFRV9UWVBFIChuZXdkZWNsKSksCgkJICAgdDIgPSBUWVBFX0FSR19UWVBFUyAoVFJFRV9UWVBFIChvbGRkZWNsKSk7CgkJICAgdDEgfHwgdDI7CgkJICAgdDEgPSBUUkVFX0NIQUlOICh0MSksIHQyID0gVFJFRV9DSEFJTiAodDIpKQoJCWlmICghdDEgfHwgIXQyKQoJCSAgYnJlYWs7CgkJZWxzZSBpZiAoVFJFRV9WQUxVRSAodDIpID09IGZpbGVwdHJfdHlwZV9ub2RlKQoJCSAgewoJCSAgICB0cmVlIHQgPSBUUkVFX1ZBTFVFICh0MSk7CgoJCSAgICBpZiAoVFJFRV9DT0RFICh0KSA9PSBQT0lOVEVSX1RZUEUKCQkJJiYgVFlQRV9OQU1FIChUUkVFX1RZUEUgKHQpKQoJCQkmJiBERUNMX05BTUUgKFRZUEVfTkFNRSAoVFJFRV9UWVBFICh0KSkpCgkJCSAgID09IGdldF9pZGVudGlmaWVyICgiRklMRSIpCgkJCSYmIGNvbXBwYXJtcyAoVFJFRV9DSEFJTiAodDEpLCBUUkVFX0NIQUlOICh0MikpKQoJCSAgICAgIHsKCQkJdHJlZSBvbGRhcmdzID0gVFlQRV9BUkdfVFlQRVMgKFRSRUVfVFlQRSAob2xkZGVjbCkpOwoKCQkJVFlQRV9BUkdfVFlQRVMgKFRSRUVfVFlQRSAob2xkZGVjbCkpCgkJCSAgPSBUWVBFX0FSR19UWVBFUyAoVFJFRV9UWVBFIChuZXdkZWNsKSk7CgkJCXR5cGVzX21hdGNoID0gZGVjbHNfbWF0Y2ggKG5ld2RlY2wsIG9sZGRlY2wpOwoJCQlpZiAodHlwZXNfbWF0Y2gpCgkJCSAgcmV0dXJuIGR1cGxpY2F0ZV9kZWNscyAobmV3ZGVjbCwgb2xkZGVjbCk7CgkJCVRZUEVfQVJHX1RZUEVTIChUUkVFX1RZUEUgKG9sZGRlY2wpKSA9IG9sZGFyZ3M7CgkJICAgICAgfQoJCSAgfQoJCWVsc2UgaWYgKCEgc2FtZV90eXBlX3AgKFRSRUVfVkFMVUUgKHQxKSwgVFJFRV9WQUxVRSAodDIpKSkKCQkgIGJyZWFrOwoJICAgIH0KCSAgZWxzZSBpZiAoKERFQ0xfRVhURVJOX0NfUCAobmV3ZGVjbCkKCQkgICAgJiYgREVDTF9FWFRFUk5fQ19QIChvbGRkZWNsKSkKCQkgICB8fCBjb21wcGFybXMgKFRZUEVfQVJHX1RZUEVTIChUUkVFX1RZUEUgKG5ld2RlY2wpKSwKCQkJCSBUWVBFX0FSR19UWVBFUyAoVFJFRV9UWVBFIChvbGRkZWNsKSkpKQoJICAgIHsKCSAgICAgIC8qIEEgbmVhciBtYXRjaDsgb3ZlcnJpZGUgdGhlIGJ1aWx0aW4uICAqLwoKCSAgICAgIGlmIChUUkVFX1BVQkxJQyAobmV3ZGVjbCkpCgkJewoJCSAgd2FybmluZyAoIm5ldyBkZWNsYXJhdGlvbiAlcSNEIiwgbmV3ZGVjbCk7CgkJICB3YXJuaW5nICgiYW1iaWd1YXRlcyBidWlsdC1pbiBkZWNsYXJhdGlvbiAlcSNEIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgb2xkZGVjbCk7CgkJfQoJICAgICAgZWxzZSBpZiAod2Fybl9zaGFkb3cpCgkJd2FybmluZyAoInNoYWRvd2luZyAlcyBmdW5jdGlvbiAlcSNEIiwKICAgICAgICAgICAgICAgICAgICAgICAgIERFQ0xfQlVJTFRfSU4gKG9sZGRlY2wpID8gImJ1aWx0LWluIiA6ICJsaWJyYXJ5IiwKICAgICAgICAgICAgICAgICAgICAgICAgIG9sZGRlY2wpOwoJICAgIH0KCSAgZWxzZQoJICAgIC8qIERpc2NhcmQgdGhlIG9sZCBidWlsdC1pbiBmdW5jdGlvbi4gICovCgkgICAgcmV0dXJuIE5VTExfVFJFRTsKCgkgIC8qIFJlcGxhY2UgdGhlIG9sZCBSVEwgdG8gYXZvaWQgcHJvYmxlbXMgd2l0aCBpbmxpbmluZy4gICovCgkgIENPUFlfREVDTF9SVEwgKG5ld2RlY2wsIG9sZGRlY2wpOwoJfQogICAgICAvKiBFdmVuIGlmIHRoZSB0eXBlcyBtYXRjaCwgcHJlZmVyIHRoZSBuZXcgZGVjbGFyYXRpb25zIHR5cGUKCSBmb3IgYW50aWNpcGF0ZWQgYnVpbHQtaW5zLCBmb3IgZXhjZXB0aW9uIGxpc3RzLCBldGMuLi4gICovCiAgICAgIGVsc2UgaWYgKERFQ0xfQU5USUNJUEFURUQgKG9sZGRlY2wpKQoJewoJICB0cmVlIHR5cGUgPSBUUkVFX1RZUEUgKG5ld2RlY2wpOwoJICB0cmVlIGF0dHJpYnMgPSAoKnRhcmdldG0ubWVyZ2VfdHlwZV9hdHRyaWJ1dGVzKQoJICAgIChUUkVFX1RZUEUgKG9sZGRlY2wpLCB0eXBlKTsKCgkgIHR5cGUgPSBjcF9idWlsZF90eXBlX2F0dHJpYnV0ZV92YXJpYW50ICh0eXBlLCBhdHRyaWJzKTsKCSAgVFJFRV9UWVBFIChuZXdkZWNsKSA9IFRSRUVfVFlQRSAob2xkZGVjbCkgPSB0eXBlOwoJfQoKICAgICAgLyogV2hldGhlciBvciBub3QgdGhlIGJ1aWx0aW4gY2FuIHRocm93IGV4Y2VwdGlvbnMgaGFzIG5vCgkgYmVhcmluZyBvbiB0aGlzIGRlY2xhcmF0b3IuICAqLwogICAgICBUUkVFX05PVEhST1cgKG9sZGRlY2wpID0gMDsKCiAgICAgIGlmIChERUNMX1RISVNfU1RBVElDIChuZXdkZWNsKSAmJiAhREVDTF9USElTX1NUQVRJQyAob2xkZGVjbCkpCgl7CgkgIC8qIElmIGEgYnVpbHRpbiBmdW5jdGlvbiBpcyByZWRlY2xhcmVkIGFzIGBzdGF0aWMnLCBtZXJnZQoJICAgICB0aGUgZGVjbGFyYXRpb25zLCBidXQgbWFrZSB0aGUgb3JpZ2luYWwgb25lIHN0YXRpYy4gICovCgkgIERFQ0xfVEhJU19TVEFUSUMgKG9sZGRlY2wpID0gMTsKCSAgVFJFRV9QVUJMSUMgKG9sZGRlY2wpID0gMDsKCgkgIC8qIE1ha2UgdGhlIG9sZCBkZWNsYXJhdGlvbiBjb25zaXN0ZW50IHdpdGggdGhlIG5ldyBvbmUgc28KCSAgICAgdGhhdCBhbGwgcmVtbmFudHMgb2YgdGhlIGJ1aWx0aW4tbmVzcyBvZiB0aGlzIGZ1bmN0aW9uCgkgICAgIHdpbGwgYmUgYmFuaXNoZWQuICAqLwoJICBTRVRfREVDTF9MQU5HVUFHRSAob2xkZGVjbCwgREVDTF9MQU5HVUFHRSAobmV3ZGVjbCkpOwoJICBDT1BZX0RFQ0xfUlRMIChuZXdkZWNsLCBvbGRkZWNsKTsKCX0KICAgIH0KICBlbHNlIGlmIChUUkVFX0NPREUgKG9sZGRlY2wpICE9IFRSRUVfQ09ERSAobmV3ZGVjbCkpCiAgICB7CiAgICAgIC8qIEFQUExFIExPQ0FMIGJlZ2luIHJhZGFyIDQ4Mjk4NTEgKi8KICAgICAgaWYgKGNfZGlhbGVjdF9vYmpjICgpICYmIERFQ0xfUCAobmV3ZGVjbCkpCiAgICAgICAgb2JqY19jaGVja19nbG9iYWxfZGVjbCAobmV3ZGVjbCk7CiAgICAgIC8qIEFQUExFIExPQ0FMIGVuZCByYWRhciA0ODI5ODUxICovCiAgICAgIGlmICgoVFJFRV9DT0RFIChvbGRkZWNsKSA9PSBUWVBFX0RFQ0wgJiYgREVDTF9BUlRJRklDSUFMIChvbGRkZWNsKQoJICAgJiYgVFJFRV9DT0RFIChuZXdkZWNsKSAhPSBUWVBFX0RFQ0wKCSAgICYmICEgKFRSRUVfQ09ERSAobmV3ZGVjbCkgPT0gVEVNUExBVEVfREVDTAoJCSAmJiBUUkVFX0NPREUgKERFQ0xfVEVNUExBVEVfUkVTVUxUIChuZXdkZWNsKSkgPT0gVFlQRV9ERUNMKSkKCSAgfHwgKFRSRUVfQ09ERSAobmV3ZGVjbCkgPT0gVFlQRV9ERUNMICYmIERFQ0xfQVJUSUZJQ0lBTCAobmV3ZGVjbCkKCSAgICAgICYmIFRSRUVfQ09ERSAob2xkZGVjbCkgIT0gVFlQRV9ERUNMCgkgICAgICAmJiAhIChUUkVFX0NPREUgKG9sZGRlY2wpID09IFRFTVBMQVRFX0RFQ0wKCQkgICAgJiYgKFRSRUVfQ09ERSAoREVDTF9URU1QTEFURV9SRVNVTFQgKG9sZGRlY2wpKQoJCQk9PSBUWVBFX0RFQ0wpKSkpCgl7CgkgIC8qIFdlIGRvIG5vdGhpbmcgc3BlY2lhbCBoZXJlLCBiZWNhdXNlIEMrKyBkb2VzIHN1Y2ggbmFzdHkKCSAgICAgdGhpbmdzIHdpdGggVFlQRV9ERUNMcy4gIEluc3RlYWQsIGp1c3QgbGV0IHRoZSBUWVBFX0RFQ0wKCSAgICAgZ2V0IHNoYWRvd2VkLCBhbmQga25vdyB0aGF0IGlmIHdlIG5lZWQgdG8gZmluZCBhIFRZUEVfREVDTAoJICAgICBmb3IgYSBnaXZlbiBuYW1lLCB3ZSBjYW4gbG9vayBpbiB0aGUgSURFTlRJRklFUl9UWVBFX1ZBTFVFCgkgICAgIHNsb3Qgb2YgdGhlIGlkZW50aWZpZXIuICAqLwoJICByZXR1cm4gTlVMTF9UUkVFOwoJfQoKICAgICAgaWYgKChUUkVFX0NPREUgKG5ld2RlY2wpID09IEZVTkNUSU9OX0RFQ0wKCSAgICYmIERFQ0xfRlVOQ1RJT05fVEVNUExBVEVfUCAob2xkZGVjbCkpCgkgIHx8IChUUkVFX0NPREUgKG9sZGRlY2wpID09IEZVTkNUSU9OX0RFQ0wKCSAgICAgICYmIERFQ0xfRlVOQ1RJT05fVEVNUExBVEVfUCAobmV3ZGVjbCkpKQoJcmV0dXJuIE5VTExfVFJFRTsKCiAgICAgIGVycm9yICgiJXEjRCByZWRlY2xhcmVkIGFzIGRpZmZlcmVudCBraW5kIG9mIHN5bWJvbCIsIG5ld2RlY2wpOwogICAgICBpZiAoVFJFRV9DT0RFIChvbGRkZWNsKSA9PSBUUkVFX0xJU1QpCglvbGRkZWNsID0gVFJFRV9WQUxVRSAob2xkZGVjbCk7CiAgICAgIGNwX2Vycm9yX2F0ICgicHJldmlvdXMgZGVjbGFyYXRpb24gb2YgJXEjRCIsIG9sZGRlY2wpOwoKICAgICAgcmV0dXJuIGVycm9yX21hcmtfbm9kZTsKICAgIH0KICBlbHNlIGlmICghdHlwZXNfbWF0Y2gpCiAgICB7CiAgICAgIGlmIChDUF9ERUNMX0NPTlRFWFQgKG5ld2RlY2wpICE9IENQX0RFQ0xfQ09OVEVYVCAob2xkZGVjbCkpCgkvKiBUaGVzZSBhcmUgY2VydGFpbmx5IG5vdCBkdXBsaWNhdGUgZGVjbGFyYXRpb25zOyB0aGV5J3JlCgkgICBmcm9tIGRpZmZlcmVudCBzY29wZXMuICAqLwoJcmV0dXJuIE5VTExfVFJFRTsKCiAgICAgIGlmIChUUkVFX0NPREUgKG5ld2RlY2wpID09IFRFTVBMQVRFX0RFQ0wpCgl7CgkgIC8qIFRoZSBuYW1lIG9mIGEgY2xhc3MgdGVtcGxhdGUgbWF5IG5vdCBiZSBkZWNsYXJlZCB0byByZWZlciB0bwoJICAgICBhbnkgb3RoZXIgdGVtcGxhdGUsIGNsYXNzLCBmdW5jdGlvbiwgb2JqZWN0LCBuYW1lc3BhY2UsIHZhbHVlLAoJICAgICBvciB0eXBlIGluIHRoZSBzYW1lIHNjb3BlLiAgKi8KCSAgaWYgKFRSRUVfQ09ERSAoREVDTF9URU1QTEFURV9SRVNVTFQgKG9sZGRlY2wpKSA9PSBUWVBFX0RFQ0wKCSAgICAgIHx8IFRSRUVfQ09ERSAoREVDTF9URU1QTEFURV9SRVNVTFQgKG5ld2RlY2wpKSA9PSBUWVBFX0RFQ0wpCgkgICAgewoJICAgICAgZXJyb3IgKCJkZWNsYXJhdGlvbiBvZiB0ZW1wbGF0ZSAlcSNEIiwgbmV3ZGVjbCk7CgkgICAgICBjcF9lcnJvcl9hdCAoImNvbmZsaWN0cyB3aXRoIHByZXZpb3VzIGRlY2xhcmF0aW9uICVxI0QiLAoJCQkgICBvbGRkZWNsKTsKCSAgICB9CgkgIGVsc2UgaWYgKFRSRUVfQ09ERSAoREVDTF9URU1QTEFURV9SRVNVTFQgKG9sZGRlY2wpKSA9PSBGVU5DVElPTl9ERUNMCgkJICAgJiYgVFJFRV9DT0RFIChERUNMX1RFTVBMQVRFX1JFU1VMVCAobmV3ZGVjbCkpID09IEZVTkNUSU9OX0RFQ0wKCQkgICAmJiBjb21wcGFybXMgKFRZUEVfQVJHX1RZUEVTIChUUkVFX1RZUEUgKERFQ0xfVEVNUExBVEVfUkVTVUxUIChvbGRkZWNsKSkpLAoJCQkJIFRZUEVfQVJHX1RZUEVTIChUUkVFX1RZUEUgKERFQ0xfVEVNUExBVEVfUkVTVUxUIChuZXdkZWNsKSkpKQoJCSAgICYmIGNvbXBfdGVtcGxhdGVfcGFybXMgKERFQ0xfVEVNUExBVEVfUEFSTVMgKG5ld2RlY2wpLAoJCQkJCSAgIERFQ0xfVEVNUExBVEVfUEFSTVMgKG9sZGRlY2wpKQoJCSAgIC8qIFRlbXBsYXRlIGZ1bmN0aW9ucyBjYW4gYmUgZGlzYW1iaWd1YXRlZCBieQoJCSAgICAgIHJldHVybiB0eXBlLiAgKi8KCQkgICAmJiBzYW1lX3R5cGVfcCAoVFJFRV9UWVBFIChUUkVFX1RZUEUgKG5ld2RlY2wpKSwKCQkJCSAgIFRSRUVfVFlQRSAoVFJFRV9UWVBFIChvbGRkZWNsKSkpKQoJICAgIHsKCSAgICAgIGVycm9yICgibmV3IGRlY2xhcmF0aW9uICVxI0QiLCBuZXdkZWNsKTsKCSAgICAgIGNwX2Vycm9yX2F0ICgiYW1iaWd1YXRlcyBvbGQgZGVjbGFyYXRpb24gJXEjRCIsIG9sZGRlY2wpOwoJICAgIH0KCSAgcmV0dXJuIE5VTExfVFJFRTsKCX0KICAgICAgaWYgKFRSRUVfQ09ERSAobmV3ZGVjbCkgPT0gRlVOQ1RJT05fREVDTCkKCXsKCSAgaWYgKERFQ0xfRVhURVJOX0NfUCAobmV3ZGVjbCkgJiYgREVDTF9FWFRFUk5fQ19QIChvbGRkZWNsKSkKCSAgICB7CgkgICAgICBlcnJvciAoImRlY2xhcmF0aW9uIG9mIEMgZnVuY3Rpb24gJXEjRCBjb25mbGljdHMgd2l0aCIsCiAgICAgICAgICAgICAgICAgICAgIG5ld2RlY2wpOwoJICAgICAgY3BfZXJyb3JfYXQgKCJwcmV2aW91cyBkZWNsYXJhdGlvbiAlcSNEIGhlcmUiLCBvbGRkZWNsKTsKCSAgICB9CgkgIGVsc2UgaWYgKGNvbXBwYXJtcyAoVFlQRV9BUkdfVFlQRVMgKFRSRUVfVFlQRSAobmV3ZGVjbCkpLAoJCQkgICAgICBUWVBFX0FSR19UWVBFUyAoVFJFRV9UWVBFIChvbGRkZWNsKSkpKQoJICAgIHsKCSAgICAgIGVycm9yICgibmV3IGRlY2xhcmF0aW9uICVxI0QiLCBuZXdkZWNsKTsKCSAgICAgIGNwX2Vycm9yX2F0ICgiYW1iaWd1YXRlcyBvbGQgZGVjbGFyYXRpb24gJXEjRCIsIG9sZGRlY2wpOwoJICAgIH0KCSAgZWxzZQoJICAgIHJldHVybiBOVUxMX1RSRUU7Cgl9CiAgICAgIGVsc2UKCXsKCSAgZXJyb3IgKCJjb25mbGljdGluZyBkZWNsYXJhdGlvbiAlcSNEIiwgbmV3ZGVjbCk7CgkgIGNwX2Vycm9yX2F0ICgiJXFEIGhhcyBhIHByZXZpb3VzIGRlY2xhcmF0aW9uIGFzICVxI0QiLAogICAgICAgICAgICAgICAgICAgICAgIG9sZGRlY2wsIG9sZGRlY2wpOwogICAgICAgICAgcmV0dXJuIGVycm9yX21hcmtfbm9kZTsKCX0KICAgIH0KICBlbHNlIGlmIChUUkVFX0NPREUgKG5ld2RlY2wpID09IEZVTkNUSU9OX0RFQ0wKCSAgICAmJiAoKERFQ0xfVEVNUExBVEVfU1BFQ0lBTElaQVRJT04gKG9sZGRlY2wpCgkJICYmICghREVDTF9URU1QTEFURV9JTkZPIChuZXdkZWNsKQoJCSAgICAgfHwgKERFQ0xfVElfVEVNUExBVEUgKG5ld2RlY2wpCgkJCSAhPSBERUNMX1RJX1RFTVBMQVRFIChvbGRkZWNsKSkpKQoJCXx8IChERUNMX1RFTVBMQVRFX1NQRUNJQUxJWkFUSU9OIChuZXdkZWNsKQoJCSAgICAmJiAoIURFQ0xfVEVNUExBVEVfSU5GTyAob2xkZGVjbCkKCQkJfHwgKERFQ0xfVElfVEVNUExBVEUgKG9sZGRlY2wpCgkJCSAgICAhPSBERUNMX1RJX1RFTVBMQVRFIChuZXdkZWNsKSkpKSkpCiAgICAvKiBJdCdzIE9LIHRvIGhhdmUgYSB0ZW1wbGF0ZSBzcGVjaWFsaXphdGlvbiBhbmQgYSBub24tdGVtcGxhdGUKICAgICAgIHdpdGggdGhlIHNhbWUgdHlwZSwgb3IgdG8gaGF2ZSBzcGVjaWFsaXphdGlvbnMgb2YgdHdvCiAgICAgICBkaWZmZXJlbnQgdGVtcGxhdGVzIHdpdGggdGhlIHNhbWUgdHlwZS4gIE5vdGUgdGhhdCBpZiBvbmUgaXMgYQogICAgICAgc3BlY2lhbGl6YXRpb24sIGFuZCB0aGUgb3RoZXIgaXMgYW4gaW5zdGFudGlhdGlvbiBvZiB0aGUgc2FtZQogICAgICAgdGVtcGxhdGUsIHRoYXQgd2UgZG8gbm90IGV4aXQgYXQgdGhpcyBwb2ludC4gIFRoYXQgc2l0dWF0aW9uCiAgICAgICBjYW4gb2NjdXIgaWYgd2UgaW5zdGFudGlhdGUgYSB0ZW1wbGF0ZSBjbGFzcywgYW5kIHRoZW4KICAgICAgIHNwZWNpYWxpemUgb25lIG9mIGl0cyBtZXRob2RzLiAgVGhpcyBzaXR1YXRpb24gaXMgdmFsaWQsIGJ1dAogICAgICAgdGhlIGRlY2xhcmF0aW9ucyBtdXN0IGJlIG1lcmdlZCBpbiB0aGUgdXN1YWwgd2F5LiAgKi8KICAgIHJldHVybiBOVUxMX1RSRUU7CiAgZWxzZSBpZiAoVFJFRV9DT0RFIChuZXdkZWNsKSA9PSBGVU5DVElPTl9ERUNMCgkgICAmJiAoKERFQ0xfVEVNUExBVEVfSU5TVEFOVElBVElPTiAob2xkZGVjbCkKCQkmJiAhREVDTF9VU0VfVEVNUExBVEUgKG5ld2RlY2wpKQoJICAgICAgIHx8IChERUNMX1RFTVBMQVRFX0lOU1RBTlRJQVRJT04gKG5ld2RlY2wpCgkJICAgJiYgIURFQ0xfVVNFX1RFTVBMQVRFIChvbGRkZWNsKSkpKQogICAgLyogT25lIG9mIHRoZSBkZWNsYXJhdGlvbnMgaXMgYSB0ZW1wbGF0ZSBpbnN0YW50aWF0aW9uLCBhbmQgdGhlCiAgICAgICBvdGhlciBpcyBub3QgYSB0ZW1wbGF0ZSBhdCBhbGwuICBUaGF0J3MgT0suICAqLwogICAgcmV0dXJuIE5VTExfVFJFRTsKICBlbHNlIGlmIChUUkVFX0NPREUgKG5ld2RlY2wpID09IE5BTUVTUEFDRV9ERUNMKQogICAgewogICAgICAvKiBJbiBbbmFtZXNwYWNlLmFsaWFzXSB3ZSBoYXZlOgoJIAogICAgICAgICAgIEluIGEgZGVjbGFyYXRpdmUgcmVnaW9uLCBhIG5hbWVzcGFjZS1hbGlhcy1kZWZpbml0aW9uIGNhbiBiZQoJICAgdXNlZCB0byByZWRlZmluZSBhIG5hbWVzcGFjZS1hbGlhcyBkZWNsYXJlZCBpbiB0aGF0IGRlY2xhcmF0aXZlCgkgICByZWdpb24gdG8gcmVmZXIgb25seSB0byB0aGUgbmFtZXNwYWNlIHRvIHdoaWNoIGl0IGFscmVhZHkKCSAgIHJlZmVycy4KCSAgIAoJIFRoZXJlZm9yZSwgaWYgd2UgZW5jb3VudGVyIGEgc2Vjb25kIGFsaWFzIGRpcmVjdGl2ZSBmb3IgdGhlIHNhbWUKCSBhbGlhcywgd2UgY2FuIGp1c3QgaWdub3JlIHRoZSBzZWNvbmQgZGlyZWN0aXZlLiAgKi8KICAgICAgaWYgKERFQ0xfTkFNRVNQQUNFX0FMSUFTIChuZXdkZWNsKQoJICAmJiAoREVDTF9OQU1FU1BBQ0VfQUxJQVMgKG5ld2RlY2wpIAoJICAgICAgPT0gREVDTF9OQU1FU1BBQ0VfQUxJQVMgKG9sZGRlY2wpKSkKCXJldHVybiBvbGRkZWNsOwogICAgICAvKiBbbmFtZXNwYWNlLmFsaWFzXQoKICAgICAgICAgQSBuYW1lc3BhY2UtbmFtZSBvciBuYW1lc3BhY2UtYWxpYXMgc2hhbGwgbm90IGJlIGRlY2xhcmVkIGFzCgkgdGhlIG5hbWUgb2YgYW55IG90aGVyIGVudGl0eSBpbiB0aGUgc2FtZSBkZWNsYXJhdGl2ZSByZWdpb24uCgkgQSBuYW1lc3BhY2UtbmFtZSBkZWZpbmVkIGF0IGdsb2JhbCBzY29wZSBzaGFsbCBub3QgYmUKCSBkZWNsYXJlZCBhcyB0aGUgbmFtZSBvZiBhbnkgb3RoZXIgZW50aXR5IGluIGFueSBnbG9iYWwgc2NvcGUKCSBvZiB0aGUgcHJvZ3JhbS4gICovCiAgICAgIGVycm9yICgiZGVjbGFyYXRpb24gb2YgbmFtZXNwYWNlICVxRCBjb25mbGljdHMgd2l0aCIsIG5ld2RlY2wpOwogICAgICBjcF9lcnJvcl9hdCAoInByZXZpb3VzIGRlY2xhcmF0aW9uIG9mIG5hbWVzcGFjZSAlcUQgaGVyZSIsIG9sZGRlY2wpOwogICAgICByZXR1cm4gZXJyb3JfbWFya19ub2RlOwogICAgfQogIGVsc2UKICAgIHsKICAgICAgY29uc3QgY2hhciAqZXJybXNnID0gcmVkZWNsYXJhdGlvbl9lcnJvcl9tZXNzYWdlIChuZXdkZWNsLCBvbGRkZWNsKTsKICAgICAgaWYgKGVycm1zZykKCXsKCSAgZXJyb3IgKGVycm1zZywgbmV3ZGVjbCk7CgkgIGlmIChERUNMX05BTUUgKG9sZGRlY2wpICE9IE5VTExfVFJFRSkKCSAgICBjcF9lcnJvcl9hdCAoKERFQ0xfSU5JVElBTCAob2xkZGVjbCkKCQkJICAmJiBuYW1lc3BhY2VfYmluZGluZ3NfcCAoKSkKCQkJID8gIiVxI0QgcHJldmlvdXNseSBkZWZpbmVkIGhlcmUiCgkJCSA6ICIlcSNEIHByZXZpb3VzbHkgZGVjbGFyZWQgaGVyZSIsIG9sZGRlY2wpOwoJICByZXR1cm4gZXJyb3JfbWFya19ub2RlOwoJfQogICAgICBlbHNlIGlmIChUUkVFX0NPREUgKG9sZGRlY2wpID09IEZVTkNUSU9OX0RFQ0wKCSAgICAgICAmJiBERUNMX0lOSVRJQUwgKG9sZGRlY2wpICE9IE5VTExfVFJFRQoJICAgICAgICYmIFRZUEVfQVJHX1RZUEVTIChUUkVFX1RZUEUgKG9sZGRlY2wpKSA9PSBOVUxMX1RSRUUKCSAgICAgICAmJiBUWVBFX0FSR19UWVBFUyAoVFJFRV9UWVBFIChuZXdkZWNsKSkgIT0gTlVMTF9UUkVFKQoJewoJICAvKiBQcm90b3R5cGUgZGVjbCBmb2xsb3dzIGRlZm4gdy9vIHByb3RvdHlwZS4gICovCgkgIGNwX3dhcm5pbmdfYXQgKCJwcm90b3R5cGUgZm9yICVxI0QiLCBuZXdkZWNsKTsKCSAgd2FybmluZyAoIiVKZm9sbG93cyBub24tcHJvdG90eXBlIGRlZmluaXRpb24gaGVyZSIsIG9sZGRlY2wpOwoJfQogICAgICBlbHNlIGlmIChUUkVFX0NPREUgKG9sZGRlY2wpID09IEZVTkNUSU9OX0RFQ0wKCSAgICAgICAmJiBERUNMX0xBTkdVQUdFIChuZXdkZWNsKSAhPSBERUNMX0xBTkdVQUdFIChvbGRkZWNsKSkKCXsKCSAgLyogZXh0ZXJuICJDIiBpbnQgZm9vICgpOwoJICAgICBpbnQgZm9vICgpIHsgYmFyICgpOyB9CgkgICAgIGlzIE9LLiAgKi8KCSAgaWYgKGN1cnJlbnRfbGFuZ19kZXB0aCAoKSA9PSAwKQoJICAgIFNFVF9ERUNMX0xBTkdVQUdFIChuZXdkZWNsLCBERUNMX0xBTkdVQUdFIChvbGRkZWNsKSk7CgkgIGVsc2UKCSAgICB7CgkgICAgICBjcF9lcnJvcl9hdCAoInByZXZpb3VzIGRlY2xhcmF0aW9uIG9mICVxI0Qgd2l0aCAlcUwgbGlua2FnZSIsCgkJCSAgIG9sZGRlY2wsIERFQ0xfTEFOR1VBR0UgKG9sZGRlY2wpKTsKCSAgICAgIGVycm9yICgiY29uZmxpY3RzIHdpdGggbmV3IGRlY2xhcmF0aW9uIHdpdGggJXFMIGxpbmthZ2UiLAogICAgICAgICAgICAgICAgICAgICBERUNMX0xBTkdVQUdFIChuZXdkZWNsKSk7CgkgICAgfQoJfQoKICAgICAgaWYgKERFQ0xfTEFOR19TUEVDSUZJQyAob2xkZGVjbCkgJiYgREVDTF9VU0VfVEVNUExBVEUgKG9sZGRlY2wpKQoJOwogICAgICBlbHNlIGlmIChUUkVFX0NPREUgKG9sZGRlY2wpID09IEZVTkNUSU9OX0RFQ0wpCgl7CgkgIHRyZWUgdDEgPSBUWVBFX0FSR19UWVBFUyAoVFJFRV9UWVBFIChvbGRkZWNsKSk7CgkgIHRyZWUgdDIgPSBUWVBFX0FSR19UWVBFUyAoVFJFRV9UWVBFIChuZXdkZWNsKSk7CgkgIGludCBpID0gMTsKCgkgIGlmIChUUkVFX0NPREUgKFRSRUVfVFlQRSAobmV3ZGVjbCkpID09IE1FVEhPRF9UWVBFKQoJICAgIHQxID0gVFJFRV9DSEFJTiAodDEpLCB0MiA9IFRSRUVfQ0hBSU4gKHQyKTsKCgkgIGZvciAoOyB0MSAmJiB0MSAhPSB2b2lkX2xpc3Rfbm9kZTsKCSAgICAgICB0MSA9IFRSRUVfQ0hBSU4gKHQxKSwgdDIgPSBUUkVFX0NIQUlOICh0MiksIGkrKykKCSAgICBpZiAoVFJFRV9QVVJQT1NFICh0MSkgJiYgVFJFRV9QVVJQT1NFICh0MikpCgkgICAgICB7CgkJaWYgKDEgPT0gc2ltcGxlX2NzdF9lcXVhbCAoVFJFRV9QVVJQT1NFICh0MSksCgkJCQkJICAgVFJFRV9QVVJQT1NFICh0MikpKQoJCSAgewoJCSAgICBwZWR3YXJuICgiZGVmYXVsdCBhcmd1bWVudCBnaXZlbiBmb3IgcGFyYW1ldGVyICVkIG9mICVxI0QiLAoJCQkgICAgIGksIG5ld2RlY2wpOwoJCSAgICBjcF9wZWR3YXJuX2F0ICgiYWZ0ZXIgcHJldmlvdXMgc3BlY2lmaWNhdGlvbiBpbiAlcSNEIiwKCQkJICAgICAgICAgICBvbGRkZWNsKTsKCQkgIH0KCQllbHNlCgkJICB7CgkJICAgIGVycm9yICgiZGVmYXVsdCBhcmd1bWVudCBnaXZlbiBmb3IgcGFyYW1ldGVyICVkIG9mICVxI0QiLAogICAgICAgICAgICAgICAgICAgICAgICAgICBpLCBuZXdkZWNsKTsKCQkgICAgY3BfZXJyb3JfYXQgKCJhZnRlciBwcmV2aW91cyBzcGVjaWZpY2F0aW9uIGluICVxI0QiLAoJCQkJIG9sZGRlY2wpOwoJCSAgfQoJICAgICAgfQoKCSAgaWYgKERFQ0xfREVDTEFSRURfSU5MSU5FX1AgKG5ld2RlY2wpCgkgICAgICAmJiAhIERFQ0xfREVDTEFSRURfSU5MSU5FX1AgKG9sZGRlY2wpCgkgICAgICAmJiBUUkVFX0FERFJFU1NBQkxFIChvbGRkZWNsKSAmJiB3YXJuX2lubGluZSkKCSAgICB7CgkgICAgICB3YXJuaW5nICgiJXEjRCB3YXMgdXNlZCBiZWZvcmUgaXQgd2FzIGRlY2xhcmVkIGlubGluZSIsIG5ld2RlY2wpOwoJICAgICAgd2FybmluZyAoIiVKcHJldmlvdXMgbm9uLWlubGluZSBkZWNsYXJhdGlvbiBoZXJlIiwgb2xkZGVjbCk7CgkgICAgfQoJfQogICAgfQoKICAvKiBEbyBub3QgbWVyZ2UgYW4gaW1wbGljaXQgdHlwZWRlZiB3aXRoIGFuIGV4cGxpY2l0IG9uZS4gIEluOgoKICAgICAgIGNsYXNzIEE7CiAgICAgICAuLi4KICAgICAgIHR5cGVkZWYgY2xhc3MgQSBBIF9fYXR0cmlidXRlX18gKChmb28pKTsKCiAgICAgdGhlIGF0dHJpYnV0ZSBzaG91bGQgYXBwbHkgb25seSB0byB0aGUgdHlwZWRlZi4gICovCiAgaWYgKFRSRUVfQ09ERSAob2xkZGVjbCkgPT0gVFlQRV9ERUNMCiAgICAgICYmIChERUNMX0lNUExJQ0lUX1RZUEVERUZfUCAob2xkZGVjbCkKCSAgfHwgREVDTF9JTVBMSUNJVF9UWVBFREVGX1AgKG5ld2RlY2wpKSkKICAgIHJldHVybiBOVUxMX1RSRUU7CgogIC8qIElmIG5ldyBkZWNsIGlzIGBzdGF0aWMnIGFuZCBhbiBgZXh0ZXJuJyB3YXMgc2VlbiBwcmV2aW91c2x5LAogICAgIHdhcm4gYWJvdXQgaXQuICAqLwogIHdhcm5fZXh0ZXJuX3JlZGVjbGFyZWRfc3RhdGljIChuZXdkZWNsLCBvbGRkZWNsKTsKCiAgLyogV2UgaGF2ZSBjb21taXR0ZWQgdG8gcmV0dXJuaW5nIDEgYXQgdGhpcyBwb2ludC4gICovCiAgaWYgKFRSRUVfQ09ERSAobmV3ZGVjbCkgPT0gRlVOQ1RJT05fREVDTCkKICAgIHsKICAgICAgLyogTm93IHRoYXQgZnVuY3Rpb25zIG11c3QgaG9sZCBpbmZvcm1hdGlvbiBub3JtYWxseSBoZWxkCgkgYnkgZmllbGQgZGVjbHMsIHRoZXJlIGlzIGV4dHJhIHdvcmsgdG8gZG8gc28gdGhhdAoJIGRlY2xhcmF0aW9uIGluZm9ybWF0aW9uIGRvZXMgbm90IGdldCBkZXN0cm95ZWQgZHVyaW5nCgkgZGVmaW5pdGlvbi4gICovCiAgICAgIGlmIChERUNMX1ZJTkRFWCAob2xkZGVjbCkpCglERUNMX1ZJTkRFWCAobmV3ZGVjbCkgPSBERUNMX1ZJTkRFWCAob2xkZGVjbCk7CiAgICAgIGlmIChERUNMX0NPTlRFWFQgKG9sZGRlY2wpKQoJREVDTF9DT05URVhUIChuZXdkZWNsKSA9IERFQ0xfQ09OVEVYVCAob2xkZGVjbCk7CiAgICAgIERFQ0xfU1RBVElDX0NPTlNUUlVDVE9SIChuZXdkZWNsKSB8PSBERUNMX1NUQVRJQ19DT05TVFJVQ1RPUiAob2xkZGVjbCk7CiAgICAgIERFQ0xfU1RBVElDX0RFU1RSVUNUT1IgKG5ld2RlY2wpIHw9IERFQ0xfU1RBVElDX0RFU1RSVUNUT1IgKG9sZGRlY2wpOwogICAgICBERUNMX1BVUkVfVklSVFVBTF9QIChuZXdkZWNsKSB8PSBERUNMX1BVUkVfVklSVFVBTF9QIChvbGRkZWNsKTsKICAgICAgREVDTF9WSVJUVUFMX1AgKG5ld2RlY2wpIHw9IERFQ0xfVklSVFVBTF9QIChvbGRkZWNsKTsKICAgICAgREVDTF9USElTX1NUQVRJQyAobmV3ZGVjbCkgfD0gREVDTF9USElTX1NUQVRJQyAob2xkZGVjbCk7CiAgICAgIGlmIChERUNMX09WRVJMT0FERURfT1BFUkFUT1JfUCAob2xkZGVjbCkgIT0gRVJST1JfTUFSSykKCVNFVF9PVkVSTE9BREVEX09QRVJBVE9SX0NPREUKCSAgKG5ld2RlY2wsIERFQ0xfT1ZFUkxPQURFRF9PUEVSQVRPUl9QIChvbGRkZWNsKSk7CiAgICAgIG5ld19kZWZpbmVzX2Z1bmN0aW9uID0gREVDTF9JTklUSUFMIChuZXdkZWNsKSAhPSBOVUxMX1RSRUU7CgogICAgICAvKiBPcHRpb25hbGx5IHdhcm4gYWJvdXQgbW9yZSB0aGFuIG9uZSBkZWNsYXJhdGlvbiBmb3IgdGhlIHNhbWUKICAgICAgICAgbmFtZSwgYnV0IGRvbid0IHdhcm4gYWJvdXQgYSBmdW5jdGlvbiBkZWNsYXJhdGlvbiBmb2xsb3dlZCBieSBhCiAgICAgICAgIGRlZmluaXRpb24uICAqLwogICAgICBpZiAod2Fybl9yZWR1bmRhbnRfZGVjbHMgJiYgISBERUNMX0FSVElGSUNJQUwgKG9sZGRlY2wpCgkgICYmICEobmV3X2RlZmluZXNfZnVuY3Rpb24gJiYgREVDTF9JTklUSUFMIChvbGRkZWNsKSA9PSBOVUxMX1RSRUUpCgkgIC8qIERvbid0IHdhcm4gYWJvdXQgZXh0ZXJuIGRlY2wgZm9sbG93ZWQgYnkgZGVmaW5pdGlvbi4gICovCgkgICYmICEoREVDTF9FWFRFUk5BTCAob2xkZGVjbCkgJiYgISBERUNMX0VYVEVSTkFMIChuZXdkZWNsKSkKCSAgLyogRG9uJ3Qgd2FybiBhYm91dCBmcmllbmRzLCBsZXQgYWRkX2ZyaWVuZCB0YWtlIGNhcmUgb2YgaXQuICAqLwoJICAmJiAhIChERUNMX0ZSSUVORF9QIChuZXdkZWNsKSB8fCBERUNMX0ZSSUVORF9QIChvbGRkZWNsKSkpCgl7CgkgIHdhcm5pbmcgKCJyZWR1bmRhbnQgcmVkZWNsYXJhdGlvbiBvZiAlcUQgaW4gc2FtZSBzY29wZSIsIG5ld2RlY2wpOwoJICBjcF93YXJuaW5nX2F0ICgicHJldmlvdXMgZGVjbGFyYXRpb24gb2YgJXFEIiwgb2xkZGVjbCk7Cgl9CiAgICB9CgogIC8qIERlYWwgd2l0aCBDKys6IG11c3QgcHJlc2VydmUgdmlydHVhbCBmdW5jdGlvbiB0YWJsZSBzaXplLiAgKi8KICBpZiAoVFJFRV9DT0RFIChvbGRkZWNsKSA9PSBUWVBFX0RFQ0wpCiAgICB7CiAgICAgIHRyZWUgbmV3dHlwZSA9IFRSRUVfVFlQRSAobmV3ZGVjbCk7CiAgICAgIHRyZWUgb2xkdHlwZSA9IFRSRUVfVFlQRSAob2xkZGVjbCk7CgogICAgICBpZiAobmV3dHlwZSAhPSBlcnJvcl9tYXJrX25vZGUgJiYgb2xkdHlwZSAhPSBlcnJvcl9tYXJrX25vZGUKCSAgJiYgVFlQRV9MQU5HX1NQRUNJRklDIChuZXd0eXBlKSAmJiBUWVBFX0xBTkdfU1BFQ0lGSUMgKG9sZHR5cGUpKQoJQ0xBU1NUWVBFX0ZSSUVORF9DTEFTU0VTIChuZXd0eXBlKQoJICA9IENMQVNTVFlQRV9GUklFTkRfQ0xBU1NFUyAob2xkdHlwZSk7CgogICAgICBERUNMX09SSUdJTkFMX1RZUEUgKG5ld2RlY2wpID0gREVDTF9PUklHSU5BTF9UWVBFIChvbGRkZWNsKTsKICAgIH0KCiAgLyogQ29weSBhbGwgdGhlIERFQ0xfLi4uIHNsb3RzIHNwZWNpZmllZCBpbiB0aGUgbmV3IGRlY2wKICAgICBleGNlcHQgZm9yIGFueSB0aGF0IHdlIGNvcHkgaGVyZSBmcm9tIHRoZSBvbGQgdHlwZS4gICovCiAgREVDTF9BVFRSSUJVVEVTIChuZXdkZWNsKQogICAgPSAoKnRhcmdldG0ubWVyZ2VfZGVjbF9hdHRyaWJ1dGVzKSAob2xkZGVjbCwgbmV3ZGVjbCk7CgogIGlmIChUUkVFX0NPREUgKG5ld2RlY2wpID09IFRFTVBMQVRFX0RFQ0wpCiAgICB7CiAgICAgIFRSRUVfVFlQRSAob2xkZGVjbCkgPSBUUkVFX1RZUEUgKERFQ0xfVEVNUExBVEVfUkVTVUxUIChvbGRkZWNsKSk7CiAgICAgIERFQ0xfVEVNUExBVEVfU1BFQ0lBTElaQVRJT05TIChvbGRkZWNsKQoJPSBjaGFpbm9uIChERUNMX1RFTVBMQVRFX1NQRUNJQUxJWkFUSU9OUyAob2xkZGVjbCksCgkJICAgREVDTF9URU1QTEFURV9TUEVDSUFMSVpBVElPTlMgKG5ld2RlY2wpKTsKCiAgICAgIC8qIElmIHRoZSBuZXcgZGVjbGFyYXRpb24gaXMgYSBkZWZpbml0aW9uLCB1cGRhdGUgdGhlIGZpbGUgYW5kCgkgbGluZSBpbmZvcm1hdGlvbiBvbiB0aGUgZGVjbGFyYXRpb24uICAqLwogICAgICBpZiAoREVDTF9JTklUSUFMIChERUNMX1RFTVBMQVRFX1JFU1VMVCAob2xkZGVjbCkpID09IE5VTExfVFJFRQoJICAmJiBERUNMX0lOSVRJQUwgKERFQ0xfVEVNUExBVEVfUkVTVUxUIChuZXdkZWNsKSkgIT0gTlVMTF9UUkVFKQoJewoJICBERUNMX1NPVVJDRV9MT0NBVElPTiAob2xkZGVjbCkKCSAgICA9IERFQ0xfU09VUkNFX0xPQ0FUSU9OIChERUNMX1RFTVBMQVRFX1JFU1VMVCAob2xkZGVjbCkpCgkgICAgPSBERUNMX1NPVVJDRV9MT0NBVElPTiAobmV3ZGVjbCk7CgkgIGlmIChERUNMX0ZVTkNUSU9OX1RFTVBMQVRFX1AgKG5ld2RlY2wpKQoJICAgIERFQ0xfQVJHVU1FTlRTIChERUNMX1RFTVBMQVRFX1JFU1VMVCAob2xkZGVjbCkpCgkgICAgICA9IERFQ0xfQVJHVU1FTlRTIChERUNMX1RFTVBMQVRFX1JFU1VMVCAobmV3ZGVjbCkpOwoJfQoKICAgICAgaWYgKERFQ0xfRlVOQ1RJT05fVEVNUExBVEVfUCAobmV3ZGVjbCkpCgl7CgkgIERFQ0xfSU5MSU5FIChERUNMX1RFTVBMQVRFX1JFU1VMVCAob2xkZGVjbCkpCgkgICAgfD0gREVDTF9JTkxJTkUgKERFQ0xfVEVNUExBVEVfUkVTVUxUIChuZXdkZWNsKSk7CgkgIERFQ0xfREVDTEFSRURfSU5MSU5FX1AgKERFQ0xfVEVNUExBVEVfUkVTVUxUIChvbGRkZWNsKSkKCSAgICB8PSBERUNMX0RFQ0xBUkVEX0lOTElORV9QIChERUNMX1RFTVBMQVRFX1JFU1VMVCAobmV3ZGVjbCkpOwoJfQoKICAgICAgcmV0dXJuIG9sZGRlY2w7CiAgICB9CgogIGlmICh0eXBlc19tYXRjaCkKICAgIHsKICAgICAgLyogQXV0b21hdGljYWxseSBoYW5kbGVzIGRlZmF1bHQgcGFyYW1ldGVycy4gICovCiAgICAgIHRyZWUgb2xkdHlwZSA9IFRSRUVfVFlQRSAob2xkZGVjbCk7CiAgICAgIHRyZWUgbmV3dHlwZTsKCiAgICAgIC8qIE1lcmdlIHRoZSBkYXRhIHR5cGVzIHNwZWNpZmllZCBpbiB0aGUgdHdvIGRlY2xzLiAgKi8KICAgICAgbmV3dHlwZSA9IG1lcmdlX3R5cGVzIChUUkVFX1RZUEUgKG5ld2RlY2wpLCBUUkVFX1RZUEUgKG9sZGRlY2wpKTsKCiAgICAgIC8qIElmIG1lcmdlX3R5cGVzIHByb2R1Y2VzIGEgbm9uLXR5cGVkZWYgdHlwZSwganVzdCB1c2UgdGhlIG9sZCB0eXBlLiAgKi8KICAgICAgaWYgKFRSRUVfQ09ERSAobmV3ZGVjbCkgPT0gVFlQRV9ERUNMCgkgICYmIG5ld3R5cGUgPT0gREVDTF9PUklHSU5BTF9UWVBFIChuZXdkZWNsKSkKCW5ld3R5cGUgPSBvbGR0eXBlOwoKICAgICAgaWYgKFRSRUVfQ09ERSAobmV3ZGVjbCkgPT0gVkFSX0RFQ0wpCgl7CgkgIERFQ0xfVEhJU19FWFRFUk4gKG5ld2RlY2wpIHw9IERFQ0xfVEhJU19FWFRFUk4gKG9sZGRlY2wpOwoJICBERUNMX0lOSVRJQUxJWkVEX1AgKG5ld2RlY2wpIHw9IERFQ0xfSU5JVElBTElaRURfUCAob2xkZGVjbCk7CgkgIERFQ0xfSU5JVElBTElaRURfQllfQ09OU1RBTlRfRVhQUkVTU0lPTl9QIChuZXdkZWNsKQoJICAgIHw9IERFQ0xfSU5JVElBTElaRURfQllfQ09OU1RBTlRfRVhQUkVTU0lPTl9QIChvbGRkZWNsKTsKCX0KCiAgICAgIC8qIERvIHRoaXMgYWZ0ZXIgY2FsbGluZyBgbWVyZ2VfdHlwZXMnIHNvIHRoYXQgZGVmYXVsdAoJIHBhcmFtZXRlcnMgZG9uJ3QgY29uZnVzZSB1cy4gICovCiAgICAgIGVsc2UgaWYgKFRSRUVfQ09ERSAobmV3ZGVjbCkgPT0gRlVOQ1RJT05fREVDTAoJICAmJiAoVFlQRV9SQUlTRVNfRVhDRVBUSU9OUyAoVFJFRV9UWVBFIChuZXdkZWNsKSkKCSAgICAgICE9IFRZUEVfUkFJU0VTX0VYQ0VQVElPTlMgKFRSRUVfVFlQRSAob2xkZGVjbCkpKSkKCXsKCSAgVFJFRV9UWVBFIChuZXdkZWNsKSA9IGJ1aWxkX2V4Y2VwdGlvbl92YXJpYW50IChuZXd0eXBlLAoJCQkJCQkJIFRZUEVfUkFJU0VTX0VYQ0VQVElPTlMgKFRSRUVfVFlQRSAobmV3ZGVjbCkpKTsKCSAgVFJFRV9UWVBFIChvbGRkZWNsKSA9IGJ1aWxkX2V4Y2VwdGlvbl92YXJpYW50IChuZXd0eXBlLAoJCQkJCQkJIFRZUEVfUkFJU0VTX0VYQ0VQVElPTlMgKG9sZHR5cGUpKTsKCgkgIGlmICgocGVkYW50aWMgfHwgISBERUNMX0lOX1NZU1RFTV9IRUFERVIgKG9sZGRlY2wpKQoJICAgICAgJiYgISBERUNMX0lTX0JVSUxUSU4gKG9sZGRlY2wpCgkgICAgICAmJiBmbGFnX2V4Y2VwdGlvbnMKCSAgICAgICYmICFjb21wX2V4Y2VwdF9zcGVjcyAoVFlQRV9SQUlTRVNfRVhDRVBUSU9OUyAoVFJFRV9UWVBFIChuZXdkZWNsKSksCgkgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRZUEVfUkFJU0VTX0VYQ0VQVElPTlMgKFRSRUVfVFlQRSAob2xkZGVjbCkpLCAxKSkKCSAgICB7CgkgICAgICBlcnJvciAoImRlY2xhcmF0aW9uIG9mICVxRiB0aHJvd3MgZGlmZmVyZW50IGV4Y2VwdGlvbnMiLAogICAgICAgICAgICAgICAgICAgICBuZXdkZWNsKTsKCSAgICAgIGNwX2Vycm9yX2F0ICgidGhhbiBwcmV2aW91cyBkZWNsYXJhdGlvbiAlcUYiLCBvbGRkZWNsKTsKCSAgICB9Cgl9CiAgICAgIFRSRUVfVFlQRSAobmV3ZGVjbCkgPSBUUkVFX1RZUEUgKG9sZGRlY2wpID0gbmV3dHlwZTsKCiAgICAgIC8qIExheSB0aGUgdHlwZSBvdXQsIHVubGVzcyBhbHJlYWR5IGRvbmUuICAqLwogICAgICBpZiAoISBzYW1lX3R5cGVfcCAobmV3dHlwZSwgb2xkdHlwZSkKCSAgJiYgVFJFRV9UWVBFIChuZXdkZWNsKSAhPSBlcnJvcl9tYXJrX25vZGUKCSAgJiYgIShwcm9jZXNzaW5nX3RlbXBsYXRlX2RlY2wgJiYgdXNlc190ZW1wbGF0ZV9wYXJtcyAobmV3ZGVjbCkpKQoJbGF5b3V0X3R5cGUgKFRSRUVfVFlQRSAobmV3ZGVjbCkpOwoKICAgICAgaWYgKChUUkVFX0NPREUgKG5ld2RlY2wpID09IFZBUl9ERUNMCgkgICB8fCBUUkVFX0NPREUgKG5ld2RlY2wpID09IFBBUk1fREVDTAoJICAgfHwgVFJFRV9DT0RFIChuZXdkZWNsKSA9PSBSRVNVTFRfREVDTAoJICAgfHwgVFJFRV9DT0RFIChuZXdkZWNsKSA9PSBGSUVMRF9ERUNMCgkgICB8fCBUUkVFX0NPREUgKG5ld2RlY2wpID09IFRZUEVfREVDTCkKCSAgJiYgIShwcm9jZXNzaW5nX3RlbXBsYXRlX2RlY2wgJiYgdXNlc190ZW1wbGF0ZV9wYXJtcyAobmV3ZGVjbCkpKQoJbGF5b3V0X2RlY2wgKG5ld2RlY2wsIDApOwoKICAgICAgLyogTWVyZ2UgdGhlIHR5cGUgcXVhbGlmaWVycy4gICovCiAgICAgIGlmIChUUkVFX1JFQURPTkxZIChuZXdkZWNsKSkKCVRSRUVfUkVBRE9OTFkgKG9sZGRlY2wpID0gMTsKICAgICAgaWYgKFRSRUVfVEhJU19WT0xBVElMRSAobmV3ZGVjbCkpCglUUkVFX1RISVNfVk9MQVRJTEUgKG9sZGRlY2wpID0gMTsKICAgICAgaWYgKFRSRUVfTk9USFJPVyAobmV3ZGVjbCkpCglUUkVFX05PVEhST1cgKG9sZGRlY2wpID0gMTsKCiAgICAgIC8qIE1lcmdlIGRlcHJlY2F0ZWRuZXNzLiAgKi8KICAgICAgaWYgKFRSRUVfREVQUkVDQVRFRCAobmV3ZGVjbCkpCglUUkVFX0RFUFJFQ0FURUQgKG9sZGRlY2wpID0gMTsKCiAgICAgIC8qIE1lcmdlIHRoZSBpbml0aWFsaXphdGlvbiBpbmZvcm1hdGlvbi4gICovCiAgICAgIGlmIChERUNMX0lOSVRJQUwgKG5ld2RlY2wpID09IE5VTExfVFJFRQoJICAmJiBERUNMX0lOSVRJQUwgKG9sZGRlY2wpICE9IE5VTExfVFJFRSkKCXsKCSAgREVDTF9JTklUSUFMIChuZXdkZWNsKSA9IERFQ0xfSU5JVElBTCAob2xkZGVjbCk7CgkgIERFQ0xfU09VUkNFX0xPQ0FUSU9OIChuZXdkZWNsKSA9IERFQ0xfU09VUkNFX0xPQ0FUSU9OIChvbGRkZWNsKTsKCSAgaWYgKENBTl9IQVZFX0ZVTExfTEFOR19ERUNMX1AgKG5ld2RlY2wpCgkgICAgICAmJiBERUNMX0xBTkdfU1BFQ0lGSUMgKG5ld2RlY2wpCgkgICAgICAmJiBERUNMX0xBTkdfU1BFQ0lGSUMgKG9sZGRlY2wpKQoJICAgIHsKCSAgICAgIERFQ0xfU0FWRURfVFJFRSAobmV3ZGVjbCkgPSBERUNMX1NBVkVEX1RSRUUgKG9sZGRlY2wpOwoJICAgICAgREVDTF9TVFJVQ1RfRlVOQ1RJT04gKG5ld2RlY2wpID0gREVDTF9TVFJVQ1RfRlVOQ1RJT04gKG9sZGRlY2wpOwoJICAgIH0KCX0KCiAgICAgIC8qIE1lcmdlIHRoZSBzZWN0aW9uIGF0dHJpYnV0ZS4KICAgICAgICAgV2Ugd2FudCB0byBpc3N1ZSBhbiBlcnJvciBpZiB0aGUgc2VjdGlvbnMgY29uZmxpY3QgYnV0IHRoYXQgbXVzdCBiZQoJIGRvbmUgbGF0ZXIgaW4gZGVjbF9hdHRyaWJ1dGVzIHNpbmNlIHdlIGFyZSBjYWxsZWQgYmVmb3JlIGF0dHJpYnV0ZXMKCSBhcmUgYXNzaWduZWQuICAqLwogICAgICBpZiAoREVDTF9TRUNUSU9OX05BTUUgKG5ld2RlY2wpID09IE5VTExfVFJFRSkKCURFQ0xfU0VDVElPTl9OQU1FIChuZXdkZWNsKSA9IERFQ0xfU0VDVElPTl9OQU1FIChvbGRkZWNsKTsKCiAgICAgIGlmIChUUkVFX0NPREUgKG5ld2RlY2wpID09IEZVTkNUSU9OX0RFQ0wpCgl7CgkgIERFQ0xfTk9fSU5TVFJVTUVOVF9GVU5DVElPTl9FTlRSWV9FWElUIChuZXdkZWNsKQoJICAgIHw9IERFQ0xfTk9fSU5TVFJVTUVOVF9GVU5DVElPTl9FTlRSWV9FWElUIChvbGRkZWNsKTsKCSAgREVDTF9OT19MSU1JVF9TVEFDSyAobmV3ZGVjbCkgfD0gREVDTF9OT19MSU1JVF9TVEFDSyAob2xkZGVjbCk7CgkgIFRSRUVfVEhJU19WT0xBVElMRSAobmV3ZGVjbCkgfD0gVFJFRV9USElTX1ZPTEFUSUxFIChvbGRkZWNsKTsKCSAgVFJFRV9SRUFET05MWSAobmV3ZGVjbCkgfD0gVFJFRV9SRUFET05MWSAob2xkZGVjbCk7CgkgIFRSRUVfTk9USFJPVyAobmV3ZGVjbCkgfD0gVFJFRV9OT1RIUk9XIChvbGRkZWNsKTsKCSAgREVDTF9JU19NQUxMT0MgKG5ld2RlY2wpIHw9IERFQ0xfSVNfTUFMTE9DIChvbGRkZWNsKTsKCSAgREVDTF9JU19QVVJFIChuZXdkZWNsKSB8PSBERUNMX0lTX1BVUkUgKG9sZGRlY2wpOwoJICAvKiBLZWVwIHRoZSBvbGQgUlRMLiAgKi8KCSAgQ09QWV9ERUNMX1JUTCAob2xkZGVjbCwgbmV3ZGVjbCk7Cgl9CiAgICAgIGVsc2UgaWYgKFRSRUVfQ09ERSAobmV3ZGVjbCkgPT0gVkFSX0RFQ0wKCSAgICAgICAmJiAoREVDTF9TSVpFIChvbGRkZWNsKSB8fCAhREVDTF9TSVpFIChuZXdkZWNsKSkpCgl7CgkgIC8qIEtlZXAgdGhlIG9sZCBSVEwuICBXZSBjYW5ub3Qga2VlcCB0aGUgb2xkIFJUTCBpZiB0aGUgb2xkCgkgICAgIGRlY2xhcmF0aW9uIHdhcyBmb3IgYW4gaW5jb21wbGV0ZSBvYmplY3QgYW5kIHRoZSBuZXcKCSAgICAgZGVjbGFyYXRpb24gaXMgbm90IHNpbmNlIG1hbnkgYXR0cmlidXRlcyBvZiB0aGUgUlRMIHdpbGwKCSAgICAgY2hhbmdlLiAgKi8KCSAgQ09QWV9ERUNMX1JUTCAob2xkZGVjbCwgbmV3ZGVjbCk7Cgl9CiAgICB9CiAgLyogSWYgY2Fubm90IG1lcmdlLCB0aGVuIHVzZSB0aGUgbmV3IHR5cGUgYW5kIHF1YWxpZmllcnMsCiAgICAgYW5kIGRvbid0IHByZXNlcnZlIHRoZSBvbGQgcnRsLiAgKi8KICBlbHNlCiAgICB7CiAgICAgIC8qIENsZWFuIG91dCBhbnkgbWVtb3J5IHdlIGhhZCBvZiB0aGUgb2xkIGRlY2xhcmF0aW9uLiAgKi8KICAgICAgdHJlZSBvbGRzdGF0aWMgPSB2YWx1ZV9tZW1iZXIgKG9sZGRlY2wsIHN0YXRpY19hZ2dyZWdhdGVzKTsKICAgICAgaWYgKG9sZHN0YXRpYykKCVRSRUVfVkFMVUUgKG9sZHN0YXRpYykgPSBlcnJvcl9tYXJrX25vZGU7CgogICAgICBUUkVFX1RZUEUgKG9sZGRlY2wpID0gVFJFRV9UWVBFIChuZXdkZWNsKTsKICAgICAgVFJFRV9SRUFET05MWSAob2xkZGVjbCkgPSBUUkVFX1JFQURPTkxZIChuZXdkZWNsKTsKICAgICAgVFJFRV9USElTX1ZPTEFUSUxFIChvbGRkZWNsKSA9IFRSRUVfVEhJU19WT0xBVElMRSAobmV3ZGVjbCk7CiAgICAgIFRSRUVfU0lERV9FRkZFQ1RTIChvbGRkZWNsKSA9IFRSRUVfU0lERV9FRkZFQ1RTIChuZXdkZWNsKTsKICAgIH0KCiAgLyogTWVyZ2UgdGhlIHN0b3JhZ2UgY2xhc3MgaW5mb3JtYXRpb24uICAqLwogIG1lcmdlX3dlYWsgKG5ld2RlY2wsIG9sZGRlY2wpOwoKICBERUNMX09ORV9PTkxZIChuZXdkZWNsKSB8PSBERUNMX09ORV9PTkxZIChvbGRkZWNsKTsKICBERUNMX0RFRkVSX09VVFBVVCAobmV3ZGVjbCkgfD0gREVDTF9ERUZFUl9PVVRQVVQgKG9sZGRlY2wpOwogIFRSRUVfUFVCTElDIChuZXdkZWNsKSA9IFRSRUVfUFVCTElDIChvbGRkZWNsKTsKICBUUkVFX1NUQVRJQyAob2xkZGVjbCkgPSBUUkVFX1NUQVRJQyAobmV3ZGVjbCkgfD0gVFJFRV9TVEFUSUMgKG9sZGRlY2wpOwogIGlmICghIERFQ0xfRVhURVJOQUwgKG9sZGRlY2wpKQogICAgREVDTF9FWFRFUk5BTCAobmV3ZGVjbCkgPSAwOwoKICAvKiBBUFBMRSBMT0NBTCBtYWlubGluZSAyMDA1LTEyLTAyIFJhZGFyIDQ0NTgyNzYgICovCiAgbmV3X3RlbXBsYXRlID0gTlVMTF9UUkVFOwogIGlmIChERUNMX0xBTkdfU1BFQ0lGSUMgKG5ld2RlY2wpICYmIERFQ0xfTEFOR19TUEVDSUZJQyAob2xkZGVjbCkpCiAgICB7CiAgICAgIERFQ0xfSU5URVJGQUNFX0tOT1dOIChuZXdkZWNsKSB8PSBERUNMX0lOVEVSRkFDRV9LTk9XTiAob2xkZGVjbCk7CiAgICAgIERFQ0xfTk9UX1JFQUxMWV9FWFRFUk4gKG5ld2RlY2wpIHw9IERFQ0xfTk9UX1JFQUxMWV9FWFRFUk4gKG9sZGRlY2wpOwogICAgICBERUNMX0NPTURBVCAobmV3ZGVjbCkgfD0gREVDTF9DT01EQVQgKG9sZGRlY2wpOwogICAgICBERUNMX1RFTVBMQVRFX0lOU1RBTlRJQVRFRCAobmV3ZGVjbCkKCXw9IERFQ0xfVEVNUExBVEVfSU5TVEFOVElBVEVEIChvbGRkZWNsKTsKICAgICAgCiAgICAgIC8qIElmIHRoZSBPTERERUNMIGlzIGFuIGluc3RhbnRpYXRpb24gYW5kL29yIHNwZWNpYWxpemF0aW9uLAoJIHRoZW4gdGhlIE5FV0RFQ0wgbXVzdCBiZSB0b28uICBCdXQsIGl0IG1heSBub3QgeWV0IGJlIG1hcmtlZAoJIGFzIHN1Y2ggaWYgdGhlIGNhbGxlciBoYXMgY3JlYXRlZCBORVdERUNMLCBidXQgaGFzIG5vdCB5ZXQKCSBmaWd1cmVkIG91dCB0aGF0IGl0IGlzIGEgcmVkZWNsYXJhdGlvbi4gICovCiAgICAgIGlmICghREVDTF9VU0VfVEVNUExBVEUgKG5ld2RlY2wpKQoJREVDTF9VU0VfVEVNUExBVEUgKG5ld2RlY2wpID0gREVDTF9VU0VfVEVNUExBVEUgKG9sZGRlY2wpOwogICAgICAKICAgICAgLyogRG9uJ3QgcmVhbGx5IGtub3cgaG93IG11Y2ggb2YgdGhlIGxhbmd1YWdlLXNwZWNpZmljCgkgdmFsdWVzIHdlIHNob3VsZCBjb3B5IGZyb20gb2xkIHRvIG5ldy4gICovCiAgICAgIERFQ0xfSU5fQUdHUl9QIChuZXdkZWNsKSA9IERFQ0xfSU5fQUdHUl9QIChvbGRkZWNsKTsKICAgICAgREVDTF9MQU5HX1NQRUNJRklDIChuZXdkZWNsKS0+ZGVjbF9mbGFncy51MiA9CglERUNMX0xBTkdfU1BFQ0lGSUMgKG9sZGRlY2wpLT5kZWNsX2ZsYWdzLnUyOwogICAgICBERUNMX05PTkNPTlZFUlRJTkdfUCAobmV3ZGVjbCkgPSBERUNMX05PTkNPTlZFUlRJTkdfUCAob2xkZGVjbCk7CiAgICAgIERFQ0xfUkVQT19BVkFJTEFCTEVfUCAobmV3ZGVjbCkgPSBERUNMX1JFUE9fQVZBSUxBQkxFX1AgKG9sZGRlY2wpOwogICAgICAvKiBBUFBMRSBMT0NBTCBiZWdpbiBtYWlubGluZSAyMDA1LTEyLTAyIFJhZGFyIDQ0NTgyNzYgICovCiAgICAgIGlmIChERUNMX1RFTVBMQVRFX0lORk8gKG5ld2RlY2wpKQoJbmV3X3RlbXBsYXRlID0gREVDTF9USV9URU1QTEFURSAobmV3ZGVjbCk7CiAgICAgIC8qIEFQUExFIExPQ0FMIGVuZCAgbWFpbmxpbmUgMjAwNS0xMi0wMiBSYWRhciA0NDU4Mjc2ICAqLwogICAgICBERUNMX1RFTVBMQVRFX0lORk8gKG5ld2RlY2wpID0gREVDTF9URU1QTEFURV9JTkZPIChvbGRkZWNsKTsKICAgICAgREVDTF9JTklUSUFMSVpFRF9JTl9DTEFTU19QIChuZXdkZWNsKQogICAgICAgIHw9IERFQ0xfSU5JVElBTElaRURfSU5fQ0xBU1NfUCAob2xkZGVjbCk7CiAgICAgIG9sZGRlY2xfZnJpZW5kID0gREVDTF9GUklFTkRfUCAob2xkZGVjbCk7CgogICAgICAvKiBPbmx5IGZ1bmN0aW9ucyBoYXZlIERFQ0xfQkVGUklFTkRJTkdfQ0xBU1NFUy4gICovCiAgICAgIGlmIChUUkVFX0NPREUgKG5ld2RlY2wpID09IEZVTkNUSU9OX0RFQ0wKCSAgfHwgREVDTF9GVU5DVElPTl9URU1QTEFURV9QIChuZXdkZWNsKSkKCXsKCSAgREVDTF9CRUZSSUVORElOR19DTEFTU0VTIChuZXdkZWNsKQoJICAgID0gY2hhaW5vbiAoREVDTF9CRUZSSUVORElOR19DTEFTU0VTIChuZXdkZWNsKSwKCQkgICAgICAgREVDTF9CRUZSSUVORElOR19DTEFTU0VTIChvbGRkZWNsKSk7CgkgIC8qIERFQ0xfVEhVTktTIGlzIG9ubHkgdmFsaWQgZm9yIHZpcnR1YWwgZnVuY3Rpb25zLAoJICAgICBvdGhlcndpc2UgaXQgaXMgYSBERUNMX0ZSSUVORF9DT05URVhULiAgKi8KCSAgaWYgKERFQ0xfVklSVFVBTF9QIChuZXdkZWNsKSkKCSAgICBERUNMX1RIVU5LUyAobmV3ZGVjbCkgPSBERUNMX1RIVU5LUyAob2xkZGVjbCk7Cgl9CiAgICB9CgogIGlmIChUUkVFX0NPREUgKG5ld2RlY2wpID09IEZVTkNUSU9OX0RFQ0wpCiAgICB7CiAgICAgIGlmIChERUNMX1RFTVBMQVRFX0lOU1RBTlRJQVRJT04gKG9sZGRlY2wpCgkgICYmICFERUNMX1RFTVBMQVRFX0lOU1RBTlRJQVRJT04gKG5ld2RlY2wpKQoJewoJICAvKiBJZiBuZXdkZWNsIGlzIG5vdCBhIHNwZWNpYWxpemF0aW9uLCB0aGVuIGl0IGlzIG5vdCBhCgkgICAgIHRlbXBsYXRlLXJlbGF0ZWQgZnVuY3Rpb24gYXQgYWxsLiAgQW5kIHRoYXQgbWVhbnMgdGhhdCB3ZQoJICAgICBzaG91bGQgaGF2ZSBleGl0ZWQgYWJvdmUsIHJldHVybmluZyAwLiAgKi8KCSAgZ2NjX2Fzc2VydCAoREVDTF9URU1QTEFURV9TUEVDSUFMSVpBVElPTiAobmV3ZGVjbCkpOwoKCSAgaWYgKFRSRUVfVVNFRCAob2xkZGVjbCkpCgkgICAgLyogRnJvbSBbdGVtcC5leHBsLnNwZWNdOgoKCSAgICAgICBJZiBhIHRlbXBsYXRlLCBhIG1lbWJlciB0ZW1wbGF0ZSBvciB0aGUgbWVtYmVyIG9mIGEgY2xhc3MKCSAgICAgICB0ZW1wbGF0ZSBpcyBleHBsaWNpdGx5IHNwZWNpYWxpemVkIHRoZW4gdGhhdAoJICAgICAgIHNwZWNpYWxpemF0aW9uIHNoYWxsIGJlIGRlY2xhcmVkIGJlZm9yZSB0aGUgZmlyc3QgdXNlIG9mCgkgICAgICAgdGhhdCBzcGVjaWFsaXphdGlvbiB0aGF0IHdvdWxkIGNhdXNlIGFuIGltcGxpY2l0CgkgICAgICAgaW5zdGFudGlhdGlvbiB0byB0YWtlIHBsYWNlLCBpbiBldmVyeSB0cmFuc2xhdGlvbiB1bml0IGluCgkgICAgICAgd2hpY2ggc3VjaCBhIHVzZSBvY2N1cnMuICAqLwoJICAgIGVycm9yICgiZXhwbGljaXQgc3BlY2lhbGl6YXRpb24gb2YgJXFEIGFmdGVyIGZpcnN0IHVzZSIsCgkJICAgICAgb2xkZGVjbCk7CgoJICBTRVRfREVDTF9URU1QTEFURV9TUEVDSUFMSVpBVElPTiAob2xkZGVjbCk7CgoJICAvKiBbdGVtcC5leHBsLnNwZWMvMTRdIFdlIGRvbid0IGlubGluZSBleHBsaWNpdCBzcGVjaWFsaXphdGlvbgoJICAgICBqdXN0IGJlY2F1c2UgdGhlIHByaW1hcnkgdGVtcGxhdGUgc2F5cyBzby4gICovCgl9CiAgICAgIGVsc2UKCXsKCSAgaWYgKERFQ0xfUEVORElOR19JTkxJTkVfSU5GTyAobmV3ZGVjbCkgPT0gMCkKCSAgICBERUNMX1BFTkRJTkdfSU5MSU5FX0lORk8gKG5ld2RlY2wpID0gREVDTF9QRU5ESU5HX0lOTElORV9JTkZPIChvbGRkZWNsKTsKCgkgIERFQ0xfREVDTEFSRURfSU5MSU5FX1AgKG5ld2RlY2wpIHw9IERFQ0xfREVDTEFSRURfSU5MSU5FX1AgKG9sZGRlY2wpOwoKCSAgLyogSWYgZWl0aGVyIGRlY2wgc2F5cyBgaW5saW5lJywgdGhpcyBmbiBpcyBpbmxpbmUsIHVubGVzcwoJICAgICBpdHMgZGVmaW5pdGlvbiB3YXMgcGFzc2VkIGFscmVhZHkuICAqLwoJICBpZiAoREVDTF9JTkxJTkUgKG5ld2RlY2wpICYmIERFQ0xfSU5JVElBTCAob2xkZGVjbCkgPT0gTlVMTF9UUkVFKQoJICAgIERFQ0xfSU5MSU5FIChvbGRkZWNsKSA9IDE7CgkgIERFQ0xfSU5MSU5FIChuZXdkZWNsKSA9IERFQ0xfSU5MSU5FIChvbGRkZWNsKTsKCgkgIERFQ0xfVU5JTkxJTkFCTEUgKG5ld2RlY2wpID0gREVDTF9VTklOTElOQUJMRSAob2xkZGVjbCkKCSAgICA9IChERUNMX1VOSU5MSU5BQkxFIChuZXdkZWNsKSB8fCBERUNMX1VOSU5MSU5BQkxFIChvbGRkZWNsKSk7Cgl9CgogICAgICAvKiBQcmVzZXJ2ZSBhYnN0cmFjdG5lc3Mgb24gY2xvbmVkIFtjZF10b3JzLiAgKi8KICAgICAgREVDTF9BQlNUUkFDVCAobmV3ZGVjbCkgPSBERUNMX0FCU1RSQUNUIChvbGRkZWNsKTsKCiAgICAgIGlmICghIHR5cGVzX21hdGNoKQoJewoJICBTRVRfREVDTF9MQU5HVUFHRSAob2xkZGVjbCwgREVDTF9MQU5HVUFHRSAobmV3ZGVjbCkpOwoJICBDT1BZX0RFQ0xfQVNTRU1CTEVSX05BTUUgKG5ld2RlY2wsIG9sZGRlY2wpOwoJICBDT1BZX0RFQ0xfUlRMIChuZXdkZWNsLCBvbGRkZWNsKTsKCX0KICAgICAgaWYgKCEgdHlwZXNfbWF0Y2ggfHwgbmV3X2RlZmluZXNfZnVuY3Rpb24pCgl7CgkgIC8qIFRoZXNlIG5lZWQgdG8gYmUgY29waWVkIHNvIHRoYXQgdGhlIG5hbWVzIGFyZSBhdmFpbGFibGUuCgkgICAgIE5vdGUgdGhhdCBpZiB0aGUgdHlwZXMgZG8gbWF0Y2gsIHdlJ2xsIHByZXNlcnZlIGlubGluZQoJICAgICBpbmZvIGFuZCBvdGhlciBiaXRzLCBidXQgaWYgbm90LCB3ZSB3b24ndC4gICovCgkgIERFQ0xfQVJHVU1FTlRTIChvbGRkZWNsKSA9IERFQ0xfQVJHVU1FTlRTIChuZXdkZWNsKTsKCSAgREVDTF9SRVNVTFQgKG9sZGRlY2wpID0gREVDTF9SRVNVTFQgKG5ld2RlY2wpOwoJfQogICAgICBpZiAobmV3X2RlZmluZXNfZnVuY3Rpb24pCgkvKiBJZiBkZWZpbmluZyBhIGZ1bmN0aW9uIGRlY2xhcmVkIHdpdGggb3RoZXIgbGFuZ3VhZ2UKCSAgIGxpbmthZ2UsIHVzZSB0aGUgcHJldmlvdXNseSBkZWNsYXJlZCBsYW5ndWFnZSBsaW5rYWdlLiAgKi8KCVNFVF9ERUNMX0xBTkdVQUdFIChuZXdkZWNsLCBERUNMX0xBTkdVQUdFIChvbGRkZWNsKSk7CiAgICAgIGVsc2UgaWYgKHR5cGVzX21hdGNoKQoJewoJICAvKiBJZiByZWRlY2xhcmluZyBhIGJ1aWx0aW4gZnVuY3Rpb24sIGFuZCBub3QgYSBkZWZpbml0aW9uLAoJICAgICBpdCBzdGF5cyBidWlsdCBpbi4gICovCgkgIGlmIChERUNMX0JVSUxUX0lOIChvbGRkZWNsKSkKCSAgICB7CgkgICAgICBERUNMX0JVSUxUX0lOX0NMQVNTIChuZXdkZWNsKSA9IERFQ0xfQlVJTFRfSU5fQ0xBU1MgKG9sZGRlY2wpOwoJICAgICAgREVDTF9GVU5DVElPTl9DT0RFIChuZXdkZWNsKSA9IERFQ0xfRlVOQ1RJT05fQ09ERSAob2xkZGVjbCk7CgkgICAgICAvKiBJZiB3ZSdyZSBrZWVwaW5nIHRoZSBidWlsdC1pbiBkZWZpbml0aW9uLCBrZWVwIHRoZSBydGwsCgkJIHJlZ2FyZGxlc3Mgb2YgZGVjbGFyYXRpb24gbWF0Y2hlcy4gICovCgkgICAgICBDT1BZX0RFQ0xfUlRMIChvbGRkZWNsLCBuZXdkZWNsKTsKCSAgICB9CgoJICBERUNMX1JFU1VMVCAobmV3ZGVjbCkgPSBERUNMX1JFU1VMVCAob2xkZGVjbCk7CgkgIC8qIERvbid0IGNsZWFyIG91dCB0aGUgYXJndW1lbnRzIGlmIHdlJ3JlIHJlZGVmaW5pbmcgYSBmdW5jdGlvbi4gICovCgkgIGlmIChERUNMX0FSR1VNRU5UUyAob2xkZGVjbCkpCgkgICAgREVDTF9BUkdVTUVOVFMgKG5ld2RlY2wpID0gREVDTF9BUkdVTUVOVFMgKG9sZGRlY2wpOwoJfQogICAgfQogIGVsc2UgaWYgKFRSRUVfQ09ERSAobmV3ZGVjbCkgPT0gTkFNRVNQQUNFX0RFQ0wpCiAgICBOQU1FU1BBQ0VfTEVWRUwgKG5ld2RlY2wpID0gTkFNRVNQQUNFX0xFVkVMIChvbGRkZWNsKTsKCiAgLyogTm93IHByZXNlcnZlIHZhcmlvdXMgb3RoZXIgaW5mbyBmcm9tIHRoZSBkZWZpbml0aW9uLiAgKi8KICBUUkVFX0FERFJFU1NBQkxFIChuZXdkZWNsKSA9IFRSRUVfQUREUkVTU0FCTEUgKG9sZGRlY2wpOwogIFRSRUVfQVNNX1dSSVRURU4gKG5ld2RlY2wpID0gVFJFRV9BU01fV1JJVFRFTiAob2xkZGVjbCk7CiAgREVDTF9DT01NT04gKG5ld2RlY2wpID0gREVDTF9DT01NT04gKG9sZGRlY2wpOwogIENPUFlfREVDTF9BU1NFTUJMRVJfTkFNRSAob2xkZGVjbCwgbmV3ZGVjbCk7CgogIC8qIFdhcm4gYWJvdXQgY29uZmxpY3RpbmcgdmlzaWJpbGl0eSBzcGVjaWZpY2F0aW9ucy4gICovCiAgaWYgKERFQ0xfVklTSUJJTElUWV9TUEVDSUZJRUQgKG9sZGRlY2wpIAogICAgICAmJiBERUNMX1ZJU0lCSUxJVFlfU1BFQ0lGSUVEIChuZXdkZWNsKQogICAgICAmJiBERUNMX1ZJU0lCSUxJVFkgKG5ld2RlY2wpICE9IERFQ0xfVklTSUJJTElUWSAob2xkZGVjbCkpCiAgICB7CiAgICAgIHdhcm5pbmcgKCIlSiVxRDogdmlzaWJpbGl0eSBhdHRyaWJ1dGUgaWdub3JlZCBiZWNhdXNlIGl0IiwKCSAgICAgICBuZXdkZWNsLCBuZXdkZWNsKTsKICAgICAgd2FybmluZyAoIiVKY29uZmxpY3RzIHdpdGggcHJldmlvdXMgZGVjbGFyYXRpb24gaGVyZSIsIG9sZGRlY2wpOwogICAgfQogIC8qIENob29zZSB0aGUgZGVjbGFyYXRpb24gd2hpY2ggc3BlY2lmaWVkIHZpc2liaWxpdHkuICAqLwogIGlmIChERUNMX1ZJU0lCSUxJVFlfU1BFQ0lGSUVEIChvbGRkZWNsKSkKICAgIHsKICAgICAgREVDTF9WSVNJQklMSVRZIChuZXdkZWNsKSA9IERFQ0xfVklTSUJJTElUWSAob2xkZGVjbCk7CiAgICAgIERFQ0xfVklTSUJJTElUWV9TUEVDSUZJRUQgKG5ld2RlY2wpID0gMTsKICAgIH0KCiAgLyogVGhlIERFQ0xfTEFOR19TUEVDSUZJQyBpbmZvcm1hdGlvbiBpbiBPTERERUNMIHdpbGwgYmUgcmVwbGFjZWQKICAgICB3aXRoIHRoYXQgZnJvbSBORVdERUNMIGJlbG93LiAgKi8KICBpZiAoREVDTF9MQU5HX1NQRUNJRklDIChvbGRkZWNsKSkKICAgIHsKICAgICAgZ2NjX2Fzc2VydCAoREVDTF9MQU5HX1NQRUNJRklDIChvbGRkZWNsKSAKCQkgICE9IERFQ0xfTEFOR19TUEVDSUZJQyAobmV3ZGVjbCkpOwogICAgICBnZ2NfZnJlZSAoREVDTF9MQU5HX1NQRUNJRklDIChvbGRkZWNsKSk7CiAgICB9CgogIGlmIChUUkVFX0NPREUgKG5ld2RlY2wpID09IEZVTkNUSU9OX0RFQ0wpCiAgICB7CiAgICAgIGludCBmdW5jdGlvbl9zaXplOwoKICAgICAgZnVuY3Rpb25fc2l6ZSA9IHNpemVvZiAoc3RydWN0IHRyZWVfZGVjbCk7CgogICAgICBtZW1jcHkgKChjaGFyICopIG9sZGRlY2wgKyBzaXplb2YgKHN0cnVjdCB0cmVlX2NvbW1vbiksCgkgICAgICAoY2hhciAqKSBuZXdkZWNsICsgc2l6ZW9mIChzdHJ1Y3QgdHJlZV9jb21tb24pLAoJICAgICAgZnVuY3Rpb25fc2l6ZSAtIHNpemVvZiAoc3RydWN0IHRyZWVfY29tbW9uKSk7CgogICAgICAvKiBBUFBMRSBMT0NBTCBtYWlubGluZSAyMDA1LTEyLTAyIFJhZGFyIDQ0NTgyNzYgICovCiAgICAgIGlmIChuZXdfdGVtcGxhdGUpCgkvKiBJZiBuZXdkZWNsIGlzIGEgdGVtcGxhdGUgaW5zdGFudGlhdGlvbiwgaXQgaXMgcG9zc2libGUgdGhhdAoJICAgdGhlIGZvbGxvd2luZyBzZXF1ZW5jZSBvZiBldmVudHMgaGFzIG9jY3VycmVkOgoKCSAgIG8gQSBmcmllbmQgZnVuY3Rpb24gd2FzIGRlY2xhcmVkIGluIGEgY2xhc3MgdGVtcGxhdGUuICBUaGUKCSAgIGNsYXNzIHRlbXBsYXRlIHdhcyBpbnN0YW50aWF0ZWQuCgoJICAgbyBUaGUgaW5zdGFudGlhdGlvbiBvZiB0aGUgZnJpZW5kIGRlY2xhcmF0aW9uIHdhcwoJICAgcmVjb3JkZWQgb24gdGhlIGluc3RhbnRpYXRpb24gbGlzdCwgYW5kIGlzIG5ld2RlY2wuCgoJICAgbyBMYXRlciwgaG93ZXZlciwgaW5zdGFudGlhdGVfY2xhc3NfdGVtcGxhdGUgY2FsbGVkIHB1c2hkZWNsCgkgICBvbiB0aGUgbmV3ZGVjbCB0byBwZXJmb3JtIG5hbWUgaW5qZWN0aW9uLiAgQnV0LCBwdXNoZGVjbCBpbgoJICAgdHVybiBjYWxsZWQgZHVwbGljYXRlX2RlY2xzIHdoZW4gaXQgZGlzY292ZXJlZCB0aGF0IGFub3RoZXIKCSAgIGRlY2xhcmF0aW9uIG9mIGEgZ2xvYmFsIGZ1bmN0aW9uIHdpdGggdGhlIHNhbWUgbmFtZSBhbHJlYWR5CgkgICBleGlzdGVkLgoKCSAgIG8gSGVyZSwgaW4gZHVwbGljYXRlX2RlY2xzLCB3ZSBkZWNpZGVkIHRvIGNsb2JiZXIgbmV3ZGVjbC4KCgkgICBJZiB3ZSdyZSBnb2luZyB0byBkbyB0aGF0LCB3ZSdkIGJldHRlciBtYWtlIHN1cmUgdGhhdAoJICAgb2xkZGVjbCwgYW5kIG5vdCBuZXdkZWNsLCBpcyBvbiB0aGUgbGlzdCBvZgoJICAgaW5zdGFudGlhdGlvbnMgc28gdGhhdCBpZiB3ZSB0cnkgdG8gZG8gdGhlIGluc3RhbnRpYXRpb24KCSAgIGFnYWluIHdlIHdvbid0IGdldCB0aGUgY2xvYmJlcmVkIGRlY2xhcmF0aW9uLiAgKi8KCXJlcmVnaXN0ZXJfc3BlY2lhbGl6YXRpb24gKG5ld2RlY2wsCgkJCQkgICAvKiBBUFBMRSBMT0NBTCBtYWlubGluZSAyMDA1LTEyLTAyIFJhZGFyIDQ0NTgyNzYgICovCgkJCQkgICBuZXdfdGVtcGxhdGUsCgkJCQkgICBvbGRkZWNsKTsKICAgIH0KICBlbHNlCiAgICB7CiAgICAgIG1lbWNweSAoKGNoYXIgKikgb2xkZGVjbCArIHNpemVvZiAoc3RydWN0IHRyZWVfY29tbW9uKSwKCSAgICAgIChjaGFyICopIG5ld2RlY2wgKyBzaXplb2YgKHN0cnVjdCB0cmVlX2NvbW1vbiksCgkgICAgICBzaXplb2YgKHN0cnVjdCB0cmVlX2RlY2wpIC0gc2l6ZW9mIChzdHJ1Y3QgdHJlZV9jb21tb24pCgkgICAgICArIFRSRUVfQ09ERV9MRU5HVEggKFRSRUVfQ09ERSAobmV3ZGVjbCkpICogc2l6ZW9mIChjaGFyICopKTsKICAgIH0KCiAgREVDTF9VSUQgKG9sZGRlY2wpID0gb2xkZGVjbF91aWQ7CiAgaWYgKG9sZGRlY2xfZnJpZW5kKQogICAgREVDTF9GUklFTkRfUCAob2xkZGVjbCkgPSAxOwoKICAvKiBORVdERUNMIGNvbnRhaW5zIHRoZSBtZXJnZWQgYXR0cmlidXRlIGxpc3RzLgogICAgIFVwZGF0ZSBPTERERUNMIHRvIGJlIHRoZSBzYW1lLiAgKi8KICBERUNMX0FUVFJJQlVURVMgKG9sZGRlY2wpID0gREVDTF9BVFRSSUJVVEVTIChuZXdkZWNsKTsKCiAgLyogSWYgT0xEREVDTCBoYWQgaXRzIERFQ0xfUlRMIGluc3RhbnRpYXRlZCwgcmUtaW52b2tlIG1ha2VfZGVjbF9ydGwKICAgIHNvIHRoYXQgZW5jb2RlX3NlY3Rpb25faW5mbyBoYXMgYSBjaGFuY2UgdG8gbG9vayBhdCB0aGUgbmV3IGRlY2wKICAgIGZsYWdzIGFuZCBhdHRyaWJ1dGVzLiAgKi8KICAvKiBBUFBMRSBMT0NBTCBiZWdpbiBMTFZNICovCiNpZm5kZWYgRU5BQkxFX0xMVk0KICBpZiAoREVDTF9SVExfU0VUX1AgKG9sZGRlY2wpCiAgICAgICYmIChUUkVFX0NPREUgKG9sZGRlY2wpID09IEZVTkNUSU9OX0RFQ0wKCSAgfHwgKFRSRUVfQ09ERSAob2xkZGVjbCkgPT0gVkFSX0RFQ0wKCSAgICAgICYmIFRSRUVfU1RBVElDIChvbGRkZWNsKSkpKQogICAgbWFrZV9kZWNsX3J0bCAob2xkZGVjbCk7CiNlbHNlCiAgaWYgKERFQ0xfTExWTV9TRVRfUCAob2xkZGVjbCkKICAgICAgJiYgKFRSRUVfQ09ERSAob2xkZGVjbCkgPT0gRlVOQ1RJT05fREVDTAoJICB8fCAoVFJFRV9DT0RFIChvbGRkZWNsKSA9PSBWQVJfREVDTAoJICAgICAgJiYgVFJFRV9TVEFUSUMgKG9sZGRlY2wpKSkpCiAgICBtYWtlX2RlY2xfbGx2bSAob2xkZGVjbCk7CiNlbmRpZgoKICAvKiBUaGUgTkVXREVDTCB3aWxsIG5vIGxvbmdlciBiZSBuZWVkZWQuICBCZWNhdXNlIGV2ZXJ5IG91dC1vZi1jbGFzcwogICAgIGRlY2xhcmF0aW9uIG9mIGEgbWVtYmVyIHJlc3VsdHMgaW4gYSBjYWxsIHRvIGR1cGxpY2F0ZV9kZWNscywKICAgICBmcmVlaW5nIHRoZXNlIG5vZGVzIHJlcHJlc2VudHMgaW4gYSBzaWduaWZpY2FudCBzYXZpbmdzLiAgKi8KICBnZ2NfZnJlZSAobmV3ZGVjbCk7CgogIHJldHVybiBvbGRkZWNsOwp9CgwKLyogUmV0dXJuIHplcm8gaWYgdGhlIGRlY2xhcmF0aW9uIE5FV0RFQ0wgaXMgdmFsaWQKICAgd2hlbiB0aGUgZGVjbGFyYXRpb24gT0xEREVDTCAoYXNzdW1lZCB0byBiZSBmb3IgdGhlIHNhbWUgbmFtZSkKICAgaGFzIGFscmVhZHkgYmVlbiBzZWVuLgogICBPdGhlcndpc2UgcmV0dXJuIGFuIGVycm9yIG1lc3NhZ2UgZm9ybWF0IHN0cmluZyB3aXRoIGEgJXMKICAgd2hlcmUgdGhlIGlkZW50aWZpZXIgc2hvdWxkIGdvLiAgKi8KCnN0YXRpYyBjb25zdCBjaGFyICoKcmVkZWNsYXJhdGlvbl9lcnJvcl9tZXNzYWdlICh0cmVlIG5ld2RlY2wsIHRyZWUgb2xkZGVjbCkKewogIGlmIChUUkVFX0NPREUgKG5ld2RlY2wpID09IFRZUEVfREVDTCkKICAgIHsKICAgICAgLyogQmVjYXVzZSBDKysgY2FuIHB1dCB0aGluZ3MgaW50byBuYW1lIHNwYWNlIGZvciBmcmVlLAoJIGNvbnN0cnVjdHMgbGlrZSAidHlwZWRlZiBzdHJ1Y3QgZm9vIHsgLi4uIH0gZm9vIgoJIHdvdWxkIGxvb2sgbGlrZSBhbiBlcnJvbmVvdXMgcmVkZWNsYXJhdGlvbi4gICovCiAgICAgIGlmIChzYW1lX3R5cGVfcCAoVFJFRV9UWVBFIChuZXdkZWNsKSwgVFJFRV9UWVBFIChvbGRkZWNsKSkpCglyZXR1cm4gMDsKICAgICAgZWxzZQoJcmV0dXJuICJyZWRlZmluaXRpb24gb2YgJXEjRCI7CiAgICB9CiAgZWxzZSBpZiAoVFJFRV9DT0RFIChuZXdkZWNsKSA9PSBGVU5DVElPTl9ERUNMKQogICAgewogICAgICAvKiBJZiB0aGlzIGlzIGEgcHVyZSBmdW5jdGlvbiwgaXRzIG9sZGRlY2wgd2lsbCBhY3R1YWxseSBiZQoJIHRoZSBvcmlnaW5hbCBpbml0aWFsaXphdGlvbiB0byBgMCcgKHdoaWNoIHdlIGZvcmNlIHRvIGNhbGwKCSBhYm9ydCgpKS4gIERvbid0IGNvbXBsYWluIGFib3V0IHJlZGVmaW5pdGlvbiBpbiB0aGlzIGNhc2UuICAqLwogICAgICBpZiAoREVDTF9MQU5HX1NQRUNJRklDIChvbGRkZWNsKSAmJiBERUNMX1BVUkVfVklSVFVBTF9QIChvbGRkZWNsKQoJICAmJiBERUNMX0lOSVRJQUwgKG9sZGRlY2wpID09IE5VTExfVFJFRSkKCXJldHVybiAwOwoKICAgICAgLyogSWYgYm90aCBmdW5jdGlvbnMgY29tZSBmcm9tIGRpZmZlcmVudCBuYW1lc3BhY2VzLCB0aGlzIGlzIG5vdAoJIGEgcmVkZWNsYXJhdGlvbiAtIHRoaXMgaXMgYSBjb25mbGljdCB3aXRoIGEgdXNlZCBmdW5jdGlvbi4gICovCiAgICAgIGlmIChERUNMX05BTUVTUEFDRV9TQ09QRV9QIChvbGRkZWNsKQoJICAmJiBERUNMX0NPTlRFWFQgKG9sZGRlY2wpICE9IERFQ0xfQ09OVEVYVCAobmV3ZGVjbCkKCSAgJiYgISBkZWNsc19tYXRjaCAob2xkZGVjbCwgbmV3ZGVjbCkpCglyZXR1cm4gIiVxRCBjb25mbGljdHMgd2l0aCB1c2VkIGZ1bmN0aW9uIjsKCiAgICAgIC8qIFdlJ2xsIGNvbXBsYWluIGFib3V0IGxpbmthZ2UgbWlzbWF0Y2hlcyBpbgogICAgICAgICB3YXJuX2V4dGVybl9yZWRlY2xhcmVkX3N0YXRpYy4gICovCgogICAgICAvKiBEZWZpbmluZyB0aGUgc2FtZSBuYW1lIHR3aWNlIGlzIG5vIGdvb2QuICAqLwogICAgICBpZiAoREVDTF9JTklUSUFMIChvbGRkZWNsKSAhPSBOVUxMX1RSRUUKCSAgJiYgREVDTF9JTklUSUFMIChuZXdkZWNsKSAhPSBOVUxMX1RSRUUpCgl7CgkgIGlmIChERUNMX05BTUUgKG9sZGRlY2wpID09IE5VTExfVFJFRSkKCSAgICByZXR1cm4gIiVxI0Qgbm90IGRlY2xhcmVkIGluIGNsYXNzIjsKCSAgZWxzZQoJICAgIHJldHVybiAicmVkZWZpbml0aW9uIG9mICVxI0QiOwoJfQogICAgICByZXR1cm4gMDsKICAgIH0KICBlbHNlIGlmIChUUkVFX0NPREUgKG5ld2RlY2wpID09IFRFTVBMQVRFX0RFQ0wpCiAgICB7CiAgICAgIHRyZWUgbnQsIG90OwoKICAgICAgaWYgKFRSRUVfQ09ERSAoREVDTF9URU1QTEFURV9SRVNVTFQgKG5ld2RlY2wpKSA9PSBUWVBFX0RFQ0wpCgl7CgkgIGlmIChDT01QTEVURV9UWVBFX1AgKFRSRUVfVFlQRSAobmV3ZGVjbCkpCgkgICAgICAmJiBDT01QTEVURV9UWVBFX1AgKFRSRUVfVFlQRSAob2xkZGVjbCkpKQoJICAgIHJldHVybiAicmVkZWZpbml0aW9uIG9mICVxI0QiOwoJICByZXR1cm4gTlVMTDsKCX0KCiAgICAgIGlmIChUUkVFX0NPREUgKERFQ0xfVEVNUExBVEVfUkVTVUxUIChuZXdkZWNsKSkgIT0gRlVOQ1RJT05fREVDTAoJICB8fCAoREVDTF9URU1QTEFURV9SRVNVTFQgKG5ld2RlY2wpCgkgICAgICA9PSBERUNMX1RFTVBMQVRFX1JFU1VMVCAob2xkZGVjbCkpKQoJcmV0dXJuIE5VTEw7CgogICAgICBudCA9IERFQ0xfVEVNUExBVEVfUkVTVUxUIChuZXdkZWNsKTsKICAgICAgaWYgKERFQ0xfVEVNUExBVEVfSU5GTyAobnQpKQoJbnQgPSBERUNMX1RFTVBMQVRFX1JFU1VMVCAodGVtcGxhdGVfZm9yX3N1YnN0aXR1dGlvbiAobnQpKTsKICAgICAgb3QgPSBERUNMX1RFTVBMQVRFX1JFU1VMVCAob2xkZGVjbCk7CiAgICAgIGlmIChERUNMX1RFTVBMQVRFX0lORk8gKG90KSkKCW90ID0gREVDTF9URU1QTEFURV9SRVNVTFQgKHRlbXBsYXRlX2Zvcl9zdWJzdGl0dXRpb24gKG90KSk7CiAgICAgIGlmIChERUNMX0lOSVRJQUwgKG50KSAmJiBERUNMX0lOSVRJQUwgKG90KSkKCXJldHVybiAicmVkZWZpbml0aW9uIG9mICVxI0QiOwoKICAgICAgcmV0dXJuIE5VTEw7CiAgICB9CiAgZWxzZSBpZiAodG9wbGV2ZWxfYmluZGluZ3NfcCAoKSB8fCBERUNMX05BTUVTUEFDRV9TQ09QRV9QIChuZXdkZWNsKSkKICAgIHsKICAgICAgLyogT2JqZWN0cyBkZWNsYXJlZCBhdCB0b3AgbGV2ZWw6ICAqLwogICAgICAvKiBJZiBhdCBsZWFzdCBvbmUgaXMgYSByZWZlcmVuY2UsIGl0J3Mgb2suICAqLwogICAgICBpZiAoREVDTF9FWFRFUk5BTCAobmV3ZGVjbCkgfHwgREVDTF9FWFRFUk5BTCAob2xkZGVjbCkpCglyZXR1cm4gMDsKICAgICAgLyogUmVqZWN0IHR3byBkZWZpbml0aW9ucy4gICovCiAgICAgIHJldHVybiAicmVkZWZpbml0aW9uIG9mICVxI0QiOwogICAgfQogIGVsc2UKICAgIHsKICAgICAgLyogT2JqZWN0cyBkZWNsYXJlZCB3aXRoIGJsb2NrIHNjb3BlOiAgKi8KICAgICAgLyogUmVqZWN0IHR3byBkZWZpbml0aW9ucywgYW5kIHJlamVjdCBhIGRlZmluaXRpb24KCSB0b2dldGhlciB3aXRoIGFuIGV4dGVybmFsIHJlZmVyZW5jZS4gICovCiAgICAgIGlmICghKERFQ0xfRVhURVJOQUwgKG5ld2RlY2wpICYmIERFQ0xfRVhURVJOQUwgKG9sZGRlY2wpKSkKCXJldHVybiAicmVkZWNsYXJhdGlvbiBvZiAlcSNEIjsKICAgICAgcmV0dXJuIDA7CiAgICB9Cn0KDAovKiBDcmVhdGUgYSBuZXcgbGFiZWwsIG5hbWVkIElELiAgKi8KCnN0YXRpYyB0cmVlCm1ha2VfbGFiZWxfZGVjbCAodHJlZSBpZCwgaW50IGxvY2FsX3ApCnsKICB0cmVlIGRlY2w7CgogIGRlY2wgPSBidWlsZF9kZWNsIChMQUJFTF9ERUNMLCBpZCwgdm9pZF90eXBlX25vZGUpOwoKICBERUNMX0NPTlRFWFQgKGRlY2wpID0gY3VycmVudF9mdW5jdGlvbl9kZWNsOwogIERFQ0xfTU9ERSAoZGVjbCkgPSBWT0lEbW9kZTsKICBDX0RFQ0xBUkVEX0xBQkVMX0ZMQUcgKGRlY2wpID0gbG9jYWxfcDsKCiAgLyogU2F5IHdoZXJlIG9uZSByZWZlcmVuY2UgaXMgdG8gdGhlIGxhYmVsLCBmb3IgdGhlIHNha2Ugb2YgdGhlCiAgICAgZXJyb3IgaWYgaXQgaXMgbm90IGRlZmluZWQuICAqLwogIERFQ0xfU09VUkNFX0xPQ0FUSU9OIChkZWNsKSA9IGlucHV0X2xvY2F0aW9uOwoKICAvKiBSZWNvcmQgdGhlIGZhY3QgdGhhdCB0aGlzIGlkZW50aWZpZXIgaXMgYm91bmQgdG8gdGhpcyBsYWJlbC4gICovCiAgU0VUX0lERU5USUZJRVJfTEFCRUxfVkFMVUUgKGlkLCBkZWNsKTsKCiAgcmV0dXJuIGRlY2w7Cn0KCi8qIFJlY29yZCB0aGlzIGxhYmVsIG9uIHRoZSBsaXN0IG9mIHVzZWQgbGFiZWxzIHNvIHRoYXQgd2UgY2FuIGNoZWNrCiAgIGF0IHRoZSBlbmQgb2YgdGhlIGZ1bmN0aW9uIHRvIHNlZSB3aGV0aGVyIG9yIG5vdCB0aGUgbGFiZWwgd2FzCiAgIGFjdHVhbGx5IGRlZmluZWQsIGFuZCBzbyB3ZSBjYW4gY2hlY2sgd2hlbiB0aGUgbGFiZWwgaXMgZGVmaW5lZCB3aGV0aGVyCiAgIHRoaXMgdXNlIGlzIHZhbGlkLiAgKi8KCnN0YXRpYyB2b2lkCnVzZV9sYWJlbCAodHJlZSBkZWNsKQp7CiAgaWYgKG5hbWVkX2xhYmVsX3VzZXMgPT0gTlVMTAogICAgICB8fCBuYW1lZF9sYWJlbF91c2VzLT5uYW1lc19pbl9zY29wZSAhPSBjdXJyZW50X2JpbmRpbmdfbGV2ZWwtPm5hbWVzCiAgICAgIHx8IG5hbWVkX2xhYmVsX3VzZXMtPmxhYmVsX2RlY2wgIT0gZGVjbCkKICAgIHsKICAgICAgc3RydWN0IG5hbWVkX2xhYmVsX3VzZV9saXN0ICpuZXdfZW50OwogICAgICBuZXdfZW50ID0gR0dDX05FVyAoc3RydWN0IG5hbWVkX2xhYmVsX3VzZV9saXN0KTsKICAgICAgbmV3X2VudC0+bGFiZWxfZGVjbCA9IGRlY2w7CiAgICAgIG5ld19lbnQtPm5hbWVzX2luX3Njb3BlID0gY3VycmVudF9iaW5kaW5nX2xldmVsLT5uYW1lczsKICAgICAgbmV3X2VudC0+YmluZGluZ19sZXZlbCA9IGN1cnJlbnRfYmluZGluZ19sZXZlbDsKICAgICAgbmV3X2VudC0+b19nb3RvX2xvY3VzID0gaW5wdXRfbG9jYXRpb247CiAgICAgIG5ld19lbnQtPm5leHQgPSBuYW1lZF9sYWJlbF91c2VzOwogICAgICBuYW1lZF9sYWJlbF91c2VzID0gbmV3X2VudDsKICAgIH0KfQoKLyogTG9vayBmb3IgYSBsYWJlbCBuYW1lZCBJRCBpbiB0aGUgY3VycmVudCBmdW5jdGlvbi4gIElmIG9uZSBjYW5ub3QKICAgYmUgZm91bmQsIGNyZWF0ZSBvbmUuICAoV2Uga2VlcCB0cmFjayBvZiB1c2VkLCBidXQgdW5kZWZpbmVkLAogICBsYWJlbHMsIGFuZCBjb21wbGFpbiBhYm91dCB0aGVtIGF0IHRoZSBlbmQgb2YgYSBmdW5jdGlvbi4pICAqLwoKdHJlZQpsb29rdXBfbGFiZWwgKHRyZWUgaWQpCnsKICB0cmVlIGRlY2w7CiAgc3RydWN0IG5hbWVkX2xhYmVsX2xpc3QgKmVudDsKCiAgdGltZXZhcl9wdXNoIChUVl9OQU1FX0xPT0tVUCk7CiAgLyogWW91IGNhbid0IHVzZSBsYWJlbHMgYXQgZ2xvYmFsIHNjb3BlLiAgKi8KICBpZiAoY3VycmVudF9mdW5jdGlvbl9kZWNsID09IE5VTExfVFJFRSkKICAgIHsKICAgICAgZXJyb3IgKCJsYWJlbCAlcUUgcmVmZXJlbmNlZCBvdXRzaWRlIG9mIGFueSBmdW5jdGlvbiIsIGlkKTsKICAgICAgUE9QX1RJTUVWQVJfQU5EX1JFVFVSTiAoVFZfTkFNRV9MT09LVVAsIE5VTExfVFJFRSk7CiAgICB9CgogIC8qIFNlZSBpZiB3ZSd2ZSBhbHJlYWR5IGdvdCB0aGlzIGxhYmVsLiAgKi8KICBkZWNsID0gSURFTlRJRklFUl9MQUJFTF9WQUxVRSAoaWQpOwogIGlmIChkZWNsICE9IE5VTExfVFJFRSAmJiBERUNMX0NPTlRFWFQgKGRlY2wpID09IGN1cnJlbnRfZnVuY3Rpb25fZGVjbCkKICAgIFBPUF9USU1FVkFSX0FORF9SRVRVUk4gKFRWX05BTUVfTE9PS1VQLCBkZWNsKTsKCiAgLyogUmVjb3JkIHRoaXMgbGFiZWwgb24gdGhlIGxpc3Qgb2YgbGFiZWxzIHVzZWQgaW4gdGhpcyBmdW5jdGlvbi4KICAgICBXZSBkbyB0aGlzIGJlZm9yZSBjYWxsaW5nIG1ha2VfbGFiZWxfZGVjbCBzbyB0aGF0IHdlIGdldCB0aGUKICAgICBJREVOVElGSUVSX0xBQkVMX1ZBTFVFIGJlZm9yZSB0aGUgbmV3IGxhYmVsIGlzIGRlY2xhcmVkLiAgKi8KICBlbnQgPSBHR0NfQ05FVyAoc3RydWN0IG5hbWVkX2xhYmVsX2xpc3QpOwogIGVudC0+b2xkX3ZhbHVlID0gSURFTlRJRklFUl9MQUJFTF9WQUxVRSAoaWQpOwogIGVudC0+bmV4dCA9IG5hbWVkX2xhYmVsczsKICBuYW1lZF9sYWJlbHMgPSBlbnQ7CgogIC8qIFdlIG5lZWQgYSBuZXcgbGFiZWwuICAqLwogIGRlY2wgPSBtYWtlX2xhYmVsX2RlY2wgKGlkLCAvKmxvY2FsX3A9Ki8wKTsKCiAgLyogTm93IGZpbGwgaW4gdGhlIGluZm9ybWF0aW9uIHdlIGRpZG4ndCBoYXZlIGJlZm9yZS4gICovCiAgZW50LT5sYWJlbF9kZWNsID0gZGVjbDsKCiAgUE9QX1RJTUVWQVJfQU5EX1JFVFVSTiAoVFZfTkFNRV9MT09LVVAsIGRlY2wpOwp9CgovKiBEZWNsYXJlIGEgbG9jYWwgbGFiZWwgbmFtZWQgSUQuICAqLwoKdHJlZQpkZWNsYXJlX2xvY2FsX2xhYmVsICh0cmVlIGlkKQp7CiAgdHJlZSBkZWNsOwoKICAvKiBBZGQgYSBuZXcgZW50cnkgdG8gdGhlIFNIQURPV0VEX0xBQkVMUyBsaXN0IHNvIHRoYXQgd2hlbiB3ZSBsZWF2ZQogICAgIHRoaXMgc2NvcGUgd2UgY2FuIHJlc3RvcmUgdGhlIG9sZCB2YWx1ZSBvZgogICAgIElERU5USUZJRVJfVFlQRV9WQUxVRS4gICovCiAgY3VycmVudF9iaW5kaW5nX2xldmVsLT5zaGFkb3dlZF9sYWJlbHMKICAgID0gdHJlZV9jb25zIChJREVOVElGSUVSX0xBQkVMX1ZBTFVFIChpZCksIE5VTExfVFJFRSwKCQkgY3VycmVudF9iaW5kaW5nX2xldmVsLT5zaGFkb3dlZF9sYWJlbHMpOwogIC8qIExvb2sgZm9yIHRoZSBsYWJlbC4gICovCiAgZGVjbCA9IG1ha2VfbGFiZWxfZGVjbCAoaWQsIC8qbG9jYWxfcD0qLzEpOwogIC8qIE5vdyBmaWxsIGluIHRoZSBpbmZvcm1hdGlvbiB3ZSBkaWRuJ3QgaGF2ZSBiZWZvcmUuICAqLwogIFRSRUVfVkFMVUUgKGN1cnJlbnRfYmluZGluZ19sZXZlbC0+c2hhZG93ZWRfbGFiZWxzKSA9IGRlY2w7CgogIHJldHVybiBkZWNsOwp9CgovKiBSZXR1cm5zIG5vbnplcm8gaWYgaXQgaXMgaWxsLWZvcm1lZCB0byBqdW1wIHBhc3QgdGhlIGRlY2xhcmF0aW9uIG9mCiAgIERFQ0wuICBSZXR1cm5zIDIgaWYgaXQncyBhbHNvIGEgcmVhbCBwcm9ibGVtLiAgKi8KCnN0YXRpYyBpbnQKZGVjbF9qdW1wX3Vuc2FmZSAodHJlZSBkZWNsKQp7CiAgaWYgKFRSRUVfQ09ERSAoZGVjbCkgIT0gVkFSX0RFQ0wgfHwgVFJFRV9TVEFUSUMgKGRlY2wpKQogICAgcmV0dXJuIDA7CgogIGlmIChERUNMX0lOSVRJQUwgKGRlY2wpID09IE5VTExfVFJFRQogICAgICAmJiBwb2RfdHlwZV9wIChUUkVFX1RZUEUgKGRlY2wpKSkKICAgIHJldHVybiAwOwoKICAvKiBUaGlzIGlzIHJlYWxseSBvbmx5IGltcG9ydGFudCBpZiB3ZSdyZSBjcm9zc2luZyBhbiBpbml0aWFsaXphdGlvbi4KICAgICBUaGUgUE9EIHN0dWZmIGlzIGp1c3QgcGVkYW50cnk7IHdoeSBzaG91bGQgaXQgbWF0dGVyIGlmIHRoZSBjbGFzcwogICAgIGNvbnRhaW5zIGEgZmllbGQgb2YgcG9pbnRlciB0byBtZW1iZXIgdHlwZT8gICovCiAgaWYgKERFQ0xfSU5JVElBTCAoZGVjbCkKICAgICAgfHwgKFRZUEVfTkVFRFNfQ09OU1RSVUNUSU5HIChUUkVFX1RZUEUgKGRlY2wpKSkpCiAgICByZXR1cm4gMjsKICByZXR1cm4gMTsKfQoKLyogQ2hlY2sgdGhhdCBhIHNpbmdsZSBwcmV2aW91c2x5IHNlZW4ganVtcCB0byBhIG5ld2x5IGRlZmluZWQgbGFiZWwKICAgaXMgT0suICBERUNMIGlzIHRoZSBMQUJFTF9ERUNMIG9yIDA7IExFVkVMIGlzIHRoZSBiaW5kaW5nX2xldmVsIGZvcgogICB0aGUganVtcCBjb250ZXh0OyBOQU1FUyBhcmUgdGhlIG5hbWVzIGluIHNjb3BlIGluIExFVkVMIGF0IHRoZSBqdW1wCiAgIGNvbnRleHQ7IEZJTEUgYW5kIExJTkUgYXJlIHRoZSBzb3VyY2UgcG9zaXRpb24gb2YgdGhlIGp1bXAgb3IgMC4gICovCgpzdGF0aWMgdm9pZApjaGVja19wcmV2aW91c19nb3RvXzEgKHRyZWUgZGVjbCwKICAgICAgICAgICAgICAgICAgICAgICBzdHJ1Y3QgY3BfYmluZGluZ19sZXZlbCogbGV2ZWwsCiAgICAgICAgICAgICAgICAgICAgICAgdHJlZSBuYW1lcywgY29uc3QgbG9jYXRpb25fdCAqbG9jdXMpCnsKICBpbnQgaWRlbnRpZmllZCA9IDA7CiAgaW50IHNhd19laCA9IDA7CiAgc3RydWN0IGNwX2JpbmRpbmdfbGV2ZWwgKmIgPSBjdXJyZW50X2JpbmRpbmdfbGV2ZWw7CiAgZm9yICg7IGI7IGIgPSBiLT5sZXZlbF9jaGFpbikKICAgIHsKICAgICAgdHJlZSBuZXdfZGVjbHMgPSBiLT5uYW1lczsKICAgICAgdHJlZSBvbGRfZGVjbHMgPSAoYiA9PSBsZXZlbCA/IG5hbWVzIDogTlVMTF9UUkVFKTsKICAgICAgZm9yICg7IG5ld19kZWNscyAhPSBvbGRfZGVjbHM7CgkgICBuZXdfZGVjbHMgPSBUUkVFX0NIQUlOIChuZXdfZGVjbHMpKQoJewoJICBpbnQgcHJvYmxlbSA9IGRlY2xfanVtcF91bnNhZmUgKG5ld19kZWNscyk7CgkgIGlmICghIHByb2JsZW0pCgkgICAgY29udGludWU7CgoJICBpZiAoISBpZGVudGlmaWVkKQoJICAgIHsKCSAgICAgIGlmIChkZWNsKQoJCXBlZHdhcm4gKCJqdW1wIHRvIGxhYmVsICVxRCIsIGRlY2wpOwoJICAgICAgZWxzZQoJCXBlZHdhcm4gKCJqdW1wIHRvIGNhc2UgbGFiZWwiKTsKCgkgICAgICBpZiAobG9jdXMpCgkJcGVkd2FybiAoIiVIICBmcm9tIGhlcmUiLCBsb2N1cyk7CgkgICAgICBpZGVudGlmaWVkID0gMTsKCSAgICB9CgoJICBpZiAocHJvYmxlbSA+IDEpCgkgICAgY3BfZXJyb3JfYXQgKCIgIGNyb3NzZXMgaW5pdGlhbGl6YXRpb24gb2YgJXEjRCIsCgkJCSBuZXdfZGVjbHMpOwoJICBlbHNlCgkgICAgY3BfcGVkd2Fybl9hdCAoIiAgZW50ZXJzIHNjb3BlIG9mIG5vbi1QT0QgJXEjRCIsCgkJCSAgIG5ld19kZWNscyk7Cgl9CgogICAgICBpZiAoYiA9PSBsZXZlbCkKCWJyZWFrOwogICAgICBpZiAoKGItPmtpbmQgPT0gc2tfdHJ5IHx8IGItPmtpbmQgPT0gc2tfY2F0Y2gpICYmICEgc2F3X2VoKQoJewoJICBpZiAoISBpZGVudGlmaWVkKQoJICAgIHsKCSAgICAgIGlmIChkZWNsKQoJCXBlZHdhcm4gKCJqdW1wIHRvIGxhYmVsICVxRCIsIGRlY2wpOwoJICAgICAgZWxzZQoJCXBlZHdhcm4gKCJqdW1wIHRvIGNhc2UgbGFiZWwiKTsKCgkgICAgICBpZiAobG9jdXMpCgkJcGVkd2FybiAoIiVIICBmcm9tIGhlcmUiLCBsb2N1cyk7CgkgICAgICBpZGVudGlmaWVkID0gMTsKCSAgICB9CgkgIGlmIChiLT5raW5kID09IHNrX3RyeSkKCSAgICBlcnJvciAoIiAgZW50ZXJzIHRyeSBibG9jayIpOwoJICBlbHNlCgkgICAgZXJyb3IgKCIgIGVudGVycyBjYXRjaCBibG9jayIpOwoJICBzYXdfZWggPSAxOwoJfQogICAgfQp9CgpzdGF0aWMgdm9pZApjaGVja19wcmV2aW91c19nb3RvIChzdHJ1Y3QgbmFtZWRfbGFiZWxfdXNlX2xpc3QqIHVzZSkKewogIGNoZWNrX3ByZXZpb3VzX2dvdG9fMSAodXNlLT5sYWJlbF9kZWNsLCB1c2UtPmJpbmRpbmdfbGV2ZWwsCgkJCSB1c2UtPm5hbWVzX2luX3Njb3BlLCAmdXNlLT5vX2dvdG9fbG9jdXMpOwp9CgpzdGF0aWMgdm9pZApjaGVja19zd2l0Y2hfZ290byAoc3RydWN0IGNwX2JpbmRpbmdfbGV2ZWwqIGxldmVsKQp7CiAgY2hlY2tfcHJldmlvdXNfZ290b18xIChOVUxMX1RSRUUsIGxldmVsLCBsZXZlbC0+bmFtZXMsIE5VTEwpOwp9CgovKiBDaGVjayB0aGF0IGFueSBwcmV2aW91c2x5IHNlZW4ganVtcHMgdG8gYSBuZXdseSBkZWZpbmVkIGxhYmVsIERFQ0wKICAgYXJlIE9LLiAgQ2FsbGVkIGJ5IGRlZmluZV9sYWJlbC4gICovCgpzdGF0aWMgdm9pZApjaGVja19wcmV2aW91c19nb3RvcyAodHJlZSBkZWNsKQp7CiAgc3RydWN0IG5hbWVkX2xhYmVsX3VzZV9saXN0ICoqdXNlcDsKCiAgaWYgKCEgVFJFRV9VU0VEIChkZWNsKSkKICAgIHJldHVybjsKCiAgZm9yICh1c2VwID0gJm5hbWVkX2xhYmVsX3VzZXM7ICp1c2VwOyApCiAgICB7CiAgICAgIHN0cnVjdCBuYW1lZF9sYWJlbF91c2VfbGlzdCAqdXNlID0gKnVzZXA7CiAgICAgIGlmICh1c2UtPmxhYmVsX2RlY2wgPT0gZGVjbCkKCXsKCSAgY2hlY2tfcHJldmlvdXNfZ290byAodXNlKTsKCSAgKnVzZXAgPSB1c2UtPm5leHQ7Cgl9CiAgICAgIGVsc2UKCXVzZXAgPSAmKHVzZS0+bmV4dCk7CiAgICB9Cn0KCi8qIENoZWNrIHRoYXQgYSBuZXcganVtcCB0byBhIGxhYmVsIERFQ0wgaXMgT0suICBDYWxsZWQgYnkKICAgZmluaXNoX2dvdG9fc3RtdC4gICovCgp2b2lkCmNoZWNrX2dvdG8gKHRyZWUgZGVjbCkKewogIGludCBpZGVudGlmaWVkID0gMDsKICB0cmVlIGJhZDsKICBzdHJ1Y3QgbmFtZWRfbGFiZWxfbGlzdCAqbGFiOwoKICAvKiBXZSBjYW4ndCBrbm93IHdoZXJlIGEgY29tcHV0ZWQgZ290byBpcyBqdW1waW5nLiAgU28gd2UgYXNzdW1lCiAgICAgdGhhdCBpdCdzIE9LLiAgKi8KICBpZiAoISBERUNMX1AgKGRlY2wpKQogICAgcmV0dXJuOwoKICAvKiBJZiB0aGUgbGFiZWwgaGFzbid0IGJlZW4gZGVmaW5lZCB5ZXQsIGRlZmVyIGNoZWNraW5nLiAgKi8KICBpZiAoISBERUNMX0lOSVRJQUwgKGRlY2wpKQogICAgewogICAgICB1c2VfbGFiZWwgKGRlY2wpOwogICAgICByZXR1cm47CiAgICB9CgogIGZvciAobGFiID0gbmFtZWRfbGFiZWxzOyBsYWI7IGxhYiA9IGxhYi0+bmV4dCkKICAgIGlmIChkZWNsID09IGxhYi0+bGFiZWxfZGVjbCkKICAgICAgYnJlYWs7CgogIC8qIElmIHRoZSBsYWJlbCBpcyBub3Qgb24gbmFtZWRfbGFiZWxzIGl0J3MgYSBnY2MgbG9jYWwgbGFiZWwsIHNvCiAgICAgaXQgbXVzdCBiZSBpbiBhbiBvdXRlciBzY29wZSwgc28ganVtcGluZyB0byBpdCBpcyBhbHdheXMgT0suICAqLwogIGlmIChsYWIgPT0gMCkKICAgIHJldHVybjsKCiAgaWYgKChsYWItPmluX3RyeV9zY29wZSB8fCBsYWItPmluX2NhdGNoX3Njb3BlIHx8IGxhYi0+YmFkX2RlY2xzKQogICAgICAmJiAhaWRlbnRpZmllZCkKICAgIHsKICAgICAgY3BfcGVkd2Fybl9hdCAoImp1bXAgdG8gbGFiZWwgJXFEIiwgZGVjbCk7CiAgICAgIHBlZHdhcm4gKCIgIGZyb20gaGVyZSIpOwogICAgICBpZGVudGlmaWVkID0gMTsKICAgIH0KCiAgZm9yIChiYWQgPSBsYWItPmJhZF9kZWNsczsgYmFkOyBiYWQgPSBUUkVFX0NIQUlOIChiYWQpKQogICAgewogICAgICB0cmVlIGIgPSBUUkVFX1ZBTFVFIChiYWQpOwogICAgICBpbnQgdSA9IGRlY2xfanVtcF91bnNhZmUgKGIpOwoKICAgICAgaWYgKHUgPiAxICYmIERFQ0xfQVJUSUZJQ0lBTCAoYikpCgkvKiBDYW4ndCBza2lwIGluaXQgb2YgX19leGNlcHRpb25faW5mby4gICovCgllcnJvciAoIiVKICBlbnRlcnMgY2F0Y2ggYmxvY2siLCBiKTsKICAgICAgZWxzZSBpZiAodSA+IDEpCgljcF9lcnJvcl9hdCAoIiAgc2tpcHMgaW5pdGlhbGl6YXRpb24gb2YgJXEjRCIsIGIpOwogICAgICBlbHNlCgljcF9wZWR3YXJuX2F0ICgiICBlbnRlcnMgc2NvcGUgb2Ygbm9uLVBPRCAlcSNEIiwgYik7CiAgICB9CgogIGlmIChsYWItPmluX3RyeV9zY29wZSkKICAgIGVycm9yICgiICBlbnRlcnMgdHJ5IGJsb2NrIik7CiAgZWxzZSBpZiAobGFiLT5pbl9jYXRjaF9zY29wZSkKICAgIGVycm9yICgiICBlbnRlcnMgY2F0Y2ggYmxvY2siKTsKfQoKLyogRGVmaW5lIGEgbGFiZWwsIHNwZWNpZnlpbmcgdGhlIGxvY2F0aW9uIGluIHRoZSBzb3VyY2UgZmlsZS4KICAgUmV0dXJuIHRoZSBMQUJFTF9ERUNMIG5vZGUgZm9yIHRoZSBsYWJlbC4gICovCgp0cmVlCmRlZmluZV9sYWJlbCAobG9jYXRpb25fdCBsb2NhdGlvbiwgdHJlZSBuYW1lKQp7CiAgdHJlZSBkZWNsID0gbG9va3VwX2xhYmVsIChuYW1lKTsKICBzdHJ1Y3QgbmFtZWRfbGFiZWxfbGlzdCAqZW50OwogIHN0cnVjdCBjcF9iaW5kaW5nX2xldmVsICpwOwoKICB0aW1ldmFyX3B1c2ggKFRWX05BTUVfTE9PS1VQKTsKICBmb3IgKGVudCA9IG5hbWVkX2xhYmVsczsgZW50OyBlbnQgPSBlbnQtPm5leHQpCiAgICBpZiAoZW50LT5sYWJlbF9kZWNsID09IGRlY2wpCiAgICAgIGJyZWFrOwoKICAvKiBBZnRlciBsYWJlbHMsIG1ha2UgYW55IG5ldyBjbGVhbnVwcyBpbiB0aGUgZnVuY3Rpb24gZ28gaW50byB0aGVpcgogICAgIG93biBuZXcgKHRlbXBvcmFyeSkgYmluZGluZyBjb250b3VyLiAgKi8KICBmb3IgKHAgPSBjdXJyZW50X2JpbmRpbmdfbGV2ZWw7CiAgICAgICBwLT5raW5kICE9IHNrX2Z1bmN0aW9uX3Bhcm1zOwogICAgICAgcCA9IHAtPmxldmVsX2NoYWluKQogICAgcC0+bW9yZV9jbGVhbnVwc19vayA9IDA7CgogIGlmIChuYW1lID09IGdldF9pZGVudGlmaWVyICgid2NoYXJfdCIpKQogICAgcGVkd2FybiAoImxhYmVsIG5hbWVkIHdjaGFyX3QiKTsKCiAgaWYgKERFQ0xfSU5JVElBTCAoZGVjbCkgIT0gTlVMTF9UUkVFKQogICAgZXJyb3IgKCJkdXBsaWNhdGUgbGFiZWwgJXFEIiwgZGVjbCk7CiAgZWxzZQogICAgewogICAgICAvKiBNYXJrIGxhYmVsIGFzIGhhdmluZyBiZWVuIGRlZmluZWQuICAqLwogICAgICBERUNMX0lOSVRJQUwgKGRlY2wpID0gZXJyb3JfbWFya19ub2RlOwogICAgICAvKiBTYXkgd2hlcmUgaW4gdGhlIHNvdXJjZS4gICovCiAgICAgIERFQ0xfU09VUkNFX0xPQ0FUSU9OIChkZWNsKSA9IGxvY2F0aW9uOwogICAgICBpZiAoZW50KQoJewoJICBlbnQtPm5hbWVzX2luX3Njb3BlID0gY3VycmVudF9iaW5kaW5nX2xldmVsLT5uYW1lczsKCSAgZW50LT5iaW5kaW5nX2xldmVsID0gY3VycmVudF9iaW5kaW5nX2xldmVsOwoJfQogICAgICBjaGVja19wcmV2aW91c19nb3RvcyAoZGVjbCk7CiAgICB9CgogIFBPUF9USU1FVkFSX0FORF9SRVRVUk4gKFRWX05BTUVfTE9PS1VQLCBkZWNsKTsKfQoKc3RydWN0IGNwX3N3aXRjaAp7CiAgc3RydWN0IGNwX2JpbmRpbmdfbGV2ZWwgKmxldmVsOwogIHN0cnVjdCBjcF9zd2l0Y2ggKm5leHQ7CiAgLyogVGhlIFNXSVRDSF9TVE1UIGJlaW5nIGJ1aWx0LiAgKi8KICB0cmVlIHN3aXRjaF9zdG10OwogIC8qIEEgc3BsYXktdHJlZSBtYXBwaW5nIHRoZSBsb3cgZWxlbWVudCBvZiBhIGNhc2UgcmFuZ2UgdG8gdGhlIGhpZ2gKICAgICBlbGVtZW50LCBvciBOVUxMX1RSRUUgaWYgdGhlcmUgaXMgbm8gaGlnaCBlbGVtZW50LiAgVXNlZCB0bwogICAgIGRldGVybWluZSB3aGV0aGVyIG9yIG5vdCBhIG5ldyBjYXNlIGxhYmVsIGR1cGxpY2F0ZXMgYW4gb2xkIGNhc2UKICAgICBsYWJlbC4gIFdlIG5lZWQgYSB0cmVlLCByYXRoZXIgdGhhbiBzaW1wbHkgYSBoYXNoIHRhYmxlLCBiZWNhdXNlCiAgICAgb2YgdGhlIEdOVSBjYXNlIHJhbmdlIGV4dGVuc2lvbi4gICovCiAgc3BsYXlfdHJlZSBjYXNlczsKfTsKCi8qIEEgc3RhY2sgb2YgdGhlIGN1cnJlbnRseSBhY3RpdmUgc3dpdGNoIHN0YXRlbWVudHMuICBUaGUgaW5uZXJtb3N0CiAgIHN3aXRjaCBzdGF0ZW1lbnQgaXMgb24gdGhlIHRvcCBvZiB0aGUgc3RhY2suICBUaGVyZSBpcyBubyBuZWVkIHRvCiAgIG1hcmsgdGhlIHN0YWNrIGZvciBnYXJiYWdlIGNvbGxlY3Rpb24gYmVjYXVzZSBpdCBpcyBvbmx5IGFjdGl2ZQogICBkdXJpbmcgdGhlIHByb2Nlc3Npbmcgb2YgdGhlIGJvZHkgb2YgYSBmdW5jdGlvbiwgYW5kIHdlIG5ldmVyCiAgIGNvbGxlY3QgYXQgdGhhdCBwb2ludC4gICovCgpzdGF0aWMgc3RydWN0IGNwX3N3aXRjaCAqc3dpdGNoX3N0YWNrOwoKLyogQ2FsbGVkIHJpZ2h0IGFmdGVyIGEgc3dpdGNoLXN0YXRlbWVudCBjb25kaXRpb24gaXMgcGFyc2VkLgogICBTV0lUQ0hfU1RNVCBpcyB0aGUgc3dpdGNoIHN0YXRlbWVudCBiZWluZyBwYXJzZWQuICAqLwoKdm9pZApwdXNoX3N3aXRjaCAodHJlZSBzd2l0Y2hfc3RtdCkKewogIHN0cnVjdCBjcF9zd2l0Y2ggKnAgPSB4bWFsbG9jIChzaXplb2YgKHN0cnVjdCBjcF9zd2l0Y2gpKTsKICBwLT5sZXZlbCA9IGN1cnJlbnRfYmluZGluZ19sZXZlbDsKICBwLT5uZXh0ID0gc3dpdGNoX3N0YWNrOwogIHAtPnN3aXRjaF9zdG10ID0gc3dpdGNoX3N0bXQ7CiAgcC0+Y2FzZXMgPSBzcGxheV90cmVlX25ldyAoY2FzZV9jb21wYXJlLCBOVUxMLCBOVUxMKTsKICBzd2l0Y2hfc3RhY2sgPSBwOwp9Cgp2b2lkCnBvcF9zd2l0Y2ggKHZvaWQpCnsKICBzdHJ1Y3QgY3Bfc3dpdGNoICpjcyA9IHN3aXRjaF9zdGFjazsKCiAgLyogRW1pdCB3YXJuaW5ncyBhcyBuZWVkZWQuICAqLwogIGNfZG9fc3dpdGNoX3dhcm5pbmdzIChjcy0+Y2FzZXMsIGNzLT5zd2l0Y2hfc3RtdCk7CgogIHNwbGF5X3RyZWVfZGVsZXRlIChjcy0+Y2FzZXMpOwogIHN3aXRjaF9zdGFjayA9IHN3aXRjaF9zdGFjay0+bmV4dDsKICBmcmVlIChjcyk7Cn0KCi8qIE5vdGUgdGhhdCB3ZSd2ZSBzZWVuIGEgZGVmaW5pdGlvbiBvZiBhIGNhc2UgbGFiZWwsIGFuZCBjb21wbGFpbiBpZiB0aGlzCiAgIGlzIGEgYmFkIHBsYWNlIGZvciBvbmUuICAqLwoKdHJlZQpmaW5pc2hfY2FzZV9sYWJlbCAodHJlZSBsb3dfdmFsdWUsIHRyZWUgaGlnaF92YWx1ZSkKewogIHRyZWUgY29uZCwgcjsKICBzdHJ1Y3QgY3BfYmluZGluZ19sZXZlbCAqcDsKCiAgaWYgKHByb2Nlc3NpbmdfdGVtcGxhdGVfZGVjbCkKICAgIHsKICAgICAgdHJlZSBsYWJlbDsKCiAgICAgIC8qIEZvciB0ZW1wbGF0ZXMsIGp1c3QgYWRkIHRoZSBjYXNlIGxhYmVsOyB3ZSdsbCBkbyBzZW1hbnRpYwoJIGFuYWx5c2lzIGF0IGluc3RhbnRpYXRpb24tdGltZS4gICovCiAgICAgIGxhYmVsID0gYnVpbGRfZGVjbCAoTEFCRUxfREVDTCwgTlVMTF9UUkVFLCBOVUxMX1RSRUUpOwogICAgICByZXR1cm4gYWRkX3N0bXQgKGJ1aWxkX2Nhc2VfbGFiZWwgKGxvd192YWx1ZSwgaGlnaF92YWx1ZSwgbGFiZWwpKTsKICAgIH0KCiAgLyogRmluZCB0aGUgY29uZGl0aW9uIG9uIHdoaWNoIHRoaXMgc3dpdGNoIHN0YXRlbWVudCBkZXBlbmRzLiAgKi8KICBjb25kID0gU1dJVENIX1NUTVRfQ09ORCAoc3dpdGNoX3N0YWNrLT5zd2l0Y2hfc3RtdCk7CiAgaWYgKGNvbmQgJiYgVFJFRV9DT0RFIChjb25kKSA9PSBUUkVFX0xJU1QpCiAgICBjb25kID0gVFJFRV9WQUxVRSAoY29uZCk7CgogIHIgPSBjX2FkZF9jYXNlX2xhYmVsIChzd2l0Y2hfc3RhY2stPmNhc2VzLCBjb25kLCBUUkVFX1RZUEUgKGNvbmQpLAoJCQlsb3dfdmFsdWUsIGhpZ2hfdmFsdWUpOwoKICBjaGVja19zd2l0Y2hfZ290byAoc3dpdGNoX3N0YWNrLT5sZXZlbCk7CgogIC8qIEFmdGVyIGxhYmVscywgbWFrZSBhbnkgbmV3IGNsZWFudXBzIGluIHRoZSBmdW5jdGlvbiBnbyBpbnRvIHRoZWlyCiAgICAgb3duIG5ldyAodGVtcG9yYXJ5KSBiaW5kaW5nIGNvbnRvdXIuICAqLwogIGZvciAocCA9IGN1cnJlbnRfYmluZGluZ19sZXZlbDsKICAgICAgIHAtPmtpbmQgIT0gc2tfZnVuY3Rpb25fcGFybXM7CiAgICAgICBwID0gcC0+bGV2ZWxfY2hhaW4pCiAgICBwLT5tb3JlX2NsZWFudXBzX29rID0gMDsKCiAgcmV0dXJuIHI7Cn0KDAovKiBIYXNoIGEgVFlQRU5BTUVfVFlQRS4gIEsgaXMgcmVhbGx5IG9mIHR5cGUgYHRyZWUnLiAgKi8KCnN0YXRpYyBoYXNodmFsX3QKdHlwZW5hbWVfaGFzaCAoY29uc3Qgdm9pZCogaykKewogIGhhc2h2YWxfdCBoYXNoOwogIHRyZWUgdCA9ICh0cmVlKSBrOwoKICBoYXNoID0gKGh0YWJfaGFzaF9wb2ludGVyIChUWVBFX0NPTlRFWFQgKHQpKQoJICBeIGh0YWJfaGFzaF9wb2ludGVyIChERUNMX05BTUUgKFRZUEVfTkFNRSAodCkpKSk7CgogIHJldHVybiBoYXNoOwp9Cgp0eXBlZGVmIHN0cnVjdCB0eXBlbmFtZV9pbmZvIHsKICB0cmVlIHNjb3BlOwogIHRyZWUgbmFtZTsKICB0cmVlIHRlbXBsYXRlX2lkOwogIGJvb2wgZW51bV9wOwogIGJvb2wgY2xhc3NfcDsKfSB0eXBlbmFtZV9pbmZvOwoKLyogQ29tcGFyZSB0d28gVFlQRU5BTUVfVFlQRXMuICBLMSBhbmQgSzIgYXJlIHJlYWxseSBvZiB0eXBlIGB0cmVlJy4gICovCgpzdGF0aWMgaW50CnR5cGVuYW1lX2NvbXBhcmUgKGNvbnN0IHZvaWQgKiBrMSwgY29uc3Qgdm9pZCAqIGsyKQp7CiAgdHJlZSB0MTsKICBjb25zdCB0eXBlbmFtZV9pbmZvICp0MjsKCiAgdDEgPSAodHJlZSkgazE7CiAgdDIgPSAoY29uc3QgdHlwZW5hbWVfaW5mbyAqKSBrMjsKCiAgcmV0dXJuIChERUNMX05BTUUgKFRZUEVfTkFNRSAodDEpKSA9PSB0Mi0+bmFtZQoJICAmJiBUWVBFX0NPTlRFWFQgKHQxKSA9PSB0Mi0+c2NvcGUKCSAgJiYgVFlQRU5BTUVfVFlQRV9GVUxMTkFNRSAodDEpID09IHQyLT50ZW1wbGF0ZV9pZAoJICAmJiBUWVBFTkFNRV9JU19FTlVNX1AgKHQxKSA9PSB0Mi0+ZW51bV9wCgkgICYmIFRZUEVOQU1FX0lTX0NMQVNTX1AgKHQxKSA9PSB0Mi0+Y2xhc3NfcCk7Cn0KCi8qIEJ1aWxkIGEgVFlQRU5BTUVfVFlQRS4gIElmIHRoZSB0eXBlIGlzIGB0eXBlbmFtZSBUOjp0JywgQ09OVEVYVCBpcwogICB0aGUgdHlwZSBvZiBgVCcsIE5BTUUgaXMgdGhlIElERU5USUZJRVJfTk9ERSBmb3IgYHQnLgogCiAgIFJldHVybnMgdGhlIG5ldyBUWVBFTkFNRV9UWVBFLiAgKi8KCnN0YXRpYyBHVFkgKChwYXJhbV9pcyAodW5pb24gdHJlZV9ub2RlKSkpIGh0YWJfdCB0eXBlbmFtZV9odGFiOwoKc3RhdGljIHRyZWUKYnVpbGRfdHlwZW5hbWVfdHlwZSAodHJlZSBjb250ZXh0LCB0cmVlIG5hbWUsIHRyZWUgZnVsbG5hbWUsCgkJICAgICBlbnVtIHRhZ190eXBlcyB0YWdfdHlwZSkKewogIHRyZWUgdDsKICB0cmVlIGQ7CiAgdHlwZW5hbWVfaW5mbyB0aTsKICB2b2lkICoqZTsKICBoYXNodmFsX3QgaGFzaDsKCiAgaWYgKHR5cGVuYW1lX2h0YWIgPT0gTlVMTCkKICAgIHR5cGVuYW1lX2h0YWIgPSBodGFiX2NyZWF0ZV9nZ2MgKDYxLCAmdHlwZW5hbWVfaGFzaCwKCQkJCSAgICAgJnR5cGVuYW1lX2NvbXBhcmUsIE5VTEwpOwoKICB0aS5zY29wZSA9IEZST0JfQ09OVEVYVCAoY29udGV4dCk7IAogIHRpLm5hbWUgPSBuYW1lOwogIHRpLnRlbXBsYXRlX2lkID0gZnVsbG5hbWU7CiAgdGkuZW51bV9wID0gdGFnX3R5cGUgPT0gZW51bV90eXBlOwogIHRpLmNsYXNzX3AgPSAodGFnX3R5cGUgPT0gY2xhc3NfdHlwZQoJCXx8IHRhZ190eXBlID09IHJlY29yZF90eXBlCgkJfHwgdGFnX3R5cGUgPT0gdW5pb25fdHlwZSk7CiAgaGFzaCA9ICAoaHRhYl9oYXNoX3BvaW50ZXIgKHRpLnNjb3BlKQoJICAgXiBodGFiX2hhc2hfcG9pbnRlciAodGkubmFtZSkpOwoKICAvKiBTZWUgaWYgd2UgYWxyZWFkeSBoYXZlIHRoaXMgdHlwZS4gICovCiAgZSA9IGh0YWJfZmluZF9zbG90X3dpdGhfaGFzaCAodHlwZW5hbWVfaHRhYiwgJnRpLCBoYXNoLCBJTlNFUlQpOwogIGlmICgqZSkKICAgIHQgPSAodHJlZSkgKmU7CiAgZWxzZQogICAgewogICAgICAvKiBCdWlsZCB0aGUgVFlQRU5BTUVfVFlQRS4gICovCiAgICAgIHQgPSBtYWtlX2FnZ3JfdHlwZSAoVFlQRU5BTUVfVFlQRSk7CiAgICAgIFRZUEVfQ09OVEVYVCAodCkgPSB0aS5zY29wZTsKICAgICAgVFlQRU5BTUVfVFlQRV9GVUxMTkFNRSAodCkgPSB0aS50ZW1wbGF0ZV9pZDsKICAgICAgVFlQRU5BTUVfSVNfRU5VTV9QICh0KSA9IHRpLmVudW1fcDsKICAgICAgVFlQRU5BTUVfSVNfQ0xBU1NfUCAodCkgPSB0aS5jbGFzc19wOwogICAgICAKICAgICAgLyogQnVpbGQgdGhlIGNvcnJlc3BvbmRpbmcgVFlQRV9ERUNMLiAgKi8KICAgICAgZCA9IGJ1aWxkX2RlY2wgKFRZUEVfREVDTCwgbmFtZSwgdCk7CiAgICAgIFRZUEVfTkFNRSAoVFJFRV9UWVBFIChkKSkgPSBkOwogICAgICBUWVBFX1NUVUJfREVDTCAoVFJFRV9UWVBFIChkKSkgPSBkOwogICAgICBERUNMX0NPTlRFWFQgKGQpID0gRlJPQl9DT05URVhUIChjb250ZXh0KTsKICAgICAgREVDTF9BUlRJRklDSUFMIChkKSA9IDE7CgogICAgICAvKiBTdG9yZSBpdCBpbiB0aGUgaGFzaCB0YWJsZS4gICovCiAgICAgICplID0gdDsKICAgIH0KICAgICAgCiAgcmV0dXJuIHQ7Cn0KCi8qIFJlc29sdmUgYHR5cGVuYW1lIENPTlRFWFQ6Ok5BTUUnLiAgVEFHX1RZUEUgaW5kaWNhdGVzIHRoZSB0YWcKICAgcHJvdmlkZWQgdG8gbmFtZSB0aGUgdHlwZS4gIFJldHVybnMgYW4gYXBwcm9wcmlhdGUgdHlwZSwgdW5sZXNzIGFuCiAgIGVycm9yIG9jY3VycywgaW4gd2hpY2ggY2FzZSBlcnJvcl9tYXJrX25vZGUgaXMgcmV0dXJuZWQuICBJZiB3ZQogICBsb2NhdGUgYSBub24tYXJ0aWZpY2lhbCBUWVBFX0RFQ0wgYW5kIFRGX0tFRVBfVFlQRV9ERUNMIGlzIHNldCwgd2UKICAgcmV0dXJuIHRoYXQsIHJhdGhlciB0aGFuIHRoZSBfVFlQRSBpdCBjb3JyZXNwb25kcyB0bywgaW4gb3RoZXIKICAgY2FzZXMgd2UgbG9vayB0aHJvdWdoIHRoZSB0eXBlIGRlY2wuICBJZiBURl9FUlJPUiBpcyBzZXQsIGNvbXBsYWluCiAgIGFib3V0IGVycm9ycywgb3RoZXJ3aXNlIGJlIHF1aWV0LiAgKi8KCnRyZWUKbWFrZV90eXBlbmFtZV90eXBlICh0cmVlIGNvbnRleHQsIHRyZWUgbmFtZSwgZW51bSB0YWdfdHlwZXMgdGFnX3R5cGUsCgkJICAgIHRzdWJzdF9mbGFnc190IGNvbXBsYWluKQp7CiAgdHJlZSBmdWxsbmFtZTsKCiAgaWYgKG5hbWUgPT0gZXJyb3JfbWFya19ub2RlCiAgICAgIHx8IGNvbnRleHQgPT0gTlVMTF9UUkVFCiAgICAgIHx8IGNvbnRleHQgPT0gZXJyb3JfbWFya19ub2RlKQogICAgcmV0dXJuIGVycm9yX21hcmtfbm9kZTsKCiAgaWYgKFRZUEVfUCAobmFtZSkpCiAgICB7CiAgICAgIGlmICghKFRZUEVfTEFOR19TUEVDSUZJQyAobmFtZSkKCSAgICAmJiAoQ0xBU1NUWVBFX0lTX1RFTVBMQVRFIChuYW1lKQoJCXx8IENMQVNTVFlQRV9VU0VfVEVNUExBVEUgKG5hbWUpKSkpCgluYW1lID0gVFlQRV9JREVOVElGSUVSIChuYW1lKTsKICAgICAgZWxzZQoJLyogQ3JlYXRlIGEgVEVNUExBVEVfSURfRVhQUiBmb3IgdGhlIHR5cGUuICAqLwoJbmFtZSA9IGJ1aWxkX250IChURU1QTEFURV9JRF9FWFBSLAoJCQkgQ0xBU1NUWVBFX1RJX1RFTVBMQVRFIChuYW1lKSwKCQkJIENMQVNTVFlQRV9USV9BUkdTIChuYW1lKSk7CiAgICB9CiAgZWxzZSBpZiAoVFJFRV9DT0RFIChuYW1lKSA9PSBUWVBFX0RFQ0wpCiAgICBuYW1lID0gREVDTF9OQU1FIChuYW1lKTsKCiAgZnVsbG5hbWUgPSBuYW1lOwoKICBpZiAoVFJFRV9DT0RFIChuYW1lKSA9PSBURU1QTEFURV9JRF9FWFBSKQogICAgewogICAgICBuYW1lID0gVFJFRV9PUEVSQU5EIChuYW1lLCAwKTsKICAgICAgaWYgKFRSRUVfQ09ERSAobmFtZSkgPT0gVEVNUExBVEVfREVDTCkKCW5hbWUgPSBUUkVFX09QRVJBTkQgKGZ1bGxuYW1lLCAwKSA9IERFQ0xfTkFNRSAobmFtZSk7CiAgICB9CiAgaWYgKFRSRUVfQ09ERSAobmFtZSkgPT0gVEVNUExBVEVfREVDTCkKICAgIHsKICAgICAgZXJyb3IgKCIlcUQgdXNlZCB3aXRob3V0IHRlbXBsYXRlIHBhcmFtZXRlcnMiLCBuYW1lKTsKICAgICAgcmV0dXJuIGVycm9yX21hcmtfbm9kZTsKICAgIH0KICBnY2NfYXNzZXJ0IChUUkVFX0NPREUgKG5hbWUpID09IElERU5USUZJRVJfTk9ERSk7CiAgZ2NjX2Fzc2VydCAoVFlQRV9QIChjb250ZXh0KSk7CgogIGlmICghZGVwZW5kZW50X3R5cGVfcCAoY29udGV4dCkKICAgICAgfHwgY3VycmVudGx5X29wZW5fY2xhc3MgKGNvbnRleHQpKQogICAgewogICAgICBpZiAoVFJFRV9DT0RFIChmdWxsbmFtZSkgPT0gVEVNUExBVEVfSURfRVhQUikKCXsKCSAgdHJlZSB0bXBsID0gTlVMTF9UUkVFOwoJICBpZiAoSVNfQUdHUl9UWVBFIChjb250ZXh0KSkKCSAgICB0bXBsID0gbG9va3VwX2ZpZWxkIChjb250ZXh0LCBuYW1lLCAwLCBmYWxzZSk7CgkgIGlmICghdG1wbCB8fCAhREVDTF9DTEFTU19URU1QTEFURV9QICh0bXBsKSkKCSAgICB7CgkgICAgICBpZiAoY29tcGxhaW4gJiB0Zl9lcnJvcikKCQllcnJvciAoIm5vIGNsYXNzIHRlbXBsYXRlIG5hbWVkICVxI1QgaW4gJXEjVCIsCiAgICAgICAgICAgICAgICAgICAgICAgbmFtZSwgY29udGV4dCk7CgkgICAgICByZXR1cm4gZXJyb3JfbWFya19ub2RlOwoJICAgIH0KCgkgIGlmIChjb21wbGFpbiAmIHRmX2Vycm9yKQoJICAgIHBlcmZvcm1fb3JfZGVmZXJfYWNjZXNzX2NoZWNrIChUWVBFX0JJTkZPIChjb250ZXh0KSwgdG1wbCk7CgoJICByZXR1cm4gbG9va3VwX3RlbXBsYXRlX2NsYXNzICh0bXBsLAoJCQkJCVRSRUVfT1BFUkFORCAoZnVsbG5hbWUsIDEpLAoJCQkJCU5VTExfVFJFRSwgY29udGV4dCwKCQkJCQkvKmVudGVyaW5nX3Njb3BlPSovMCwKCSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGZfZXJyb3IgfCB0Zl93YXJuaW5nIHwgdGZfdXNlcik7Cgl9CiAgICAgIGVsc2UKCXsKICAgICAgICAgIHRyZWUgdDsKCgkgIGlmICghSVNfQUdHUl9UWVBFIChjb250ZXh0KSkKCSAgICB7CgkgICAgICBpZiAoY29tcGxhaW4gJiB0Zl9lcnJvcikKCQllcnJvciAoIm5vIHR5cGUgbmFtZWQgJXEjVCBpbiAlcSNUIiwgbmFtZSwgY29udGV4dCk7CgkgICAgICByZXR1cm4gZXJyb3JfbWFya19ub2RlOwoJICAgIH0KCgkgIHQgPSBsb29rdXBfZmllbGQgKGNvbnRleHQsIG5hbWUsIDAsIHRydWUpOwoJICBpZiAodCkKCSAgICB7CgkgICAgICBpZiAoVFJFRV9DT0RFICh0KSAhPSBUWVBFX0RFQ0wpCgkJewoJCSAgaWYgKGNvbXBsYWluICYgdGZfZXJyb3IpCgkJICAgIGVycm9yICgibm8gdHlwZSBuYW1lZCAlcSNUIGluICVxI1QiLCBuYW1lLCBjb250ZXh0KTsKCQkgIHJldHVybiBlcnJvcl9tYXJrX25vZGU7CgkJfQoKCSAgICAgIGlmIChjb21wbGFpbiAmIHRmX2Vycm9yKQoJCXBlcmZvcm1fb3JfZGVmZXJfYWNjZXNzX2NoZWNrIChUWVBFX0JJTkZPIChjb250ZXh0KSwgdCk7CgoJICAgICAgaWYgKERFQ0xfQVJUSUZJQ0lBTCAodCkgfHwgIShjb21wbGFpbiAmIHRmX2tlZXBfdHlwZV9kZWNsKSkKCQl0ID0gVFJFRV9UWVBFICh0KTsKCgkgICAgICByZXR1cm4gdDsKCSAgICB9Cgl9CiAgICB9CgogIC8qIElmIHRoZSBDT05URVhUIGlzIG5vdCBhIHRlbXBsYXRlIHR5cGUsIHRoZW4gZWl0aGVyIHRoZSBmaWVsZCBpcwogICAgIHRoZXJlIG5vdyBvciBpdHMgbmV2ZXIgZ29pbmcgdG8gYmUuICAqLwogIGlmICghZGVwZW5kZW50X3R5cGVfcCAoY29udGV4dCkpCiAgICB7CiAgICAgIGlmIChjb21wbGFpbiAmIHRmX2Vycm9yKQoJZXJyb3IgKCJubyB0eXBlIG5hbWVkICVxI1QgaW4gJXEjVCIsIG5hbWUsIGNvbnRleHQpOwogICAgICByZXR1cm4gZXJyb3JfbWFya19ub2RlOwogICAgfQoKICByZXR1cm4gYnVpbGRfdHlwZW5hbWVfdHlwZSAoY29udGV4dCwgbmFtZSwgZnVsbG5hbWUsIHRhZ190eXBlKTsKfQoKLyogUmVzb2x2ZSBgQ09OVEVYVDo6dGVtcGxhdGUgTkFNRScuICBSZXR1cm5zIGEgVEVNUExBVEVfREVDTCBpZiB0aGUgbmFtZQogICBjYW4gYmUgcmVzb2x2ZWQgb3IgYW4gVU5CT1VORF9DTEFTU19URU1QTEFURSwgdW5sZXNzIGFuIGVycm9yIG9jY3VycywgCiAgIGluIHdoaWNoIGNhc2UgZXJyb3JfbWFya19ub2RlIGlzIHJldHVybmVkLgoKICAgSWYgUEFSTV9MSVNUIGlzIG5vbi1OVUxMLCBhbHNvIG1ha2Ugc3VyZSB0aGF0IHRoZSB0ZW1wbGF0ZSBwYXJhbWV0ZXIKICAgbGlzdCBvZiBURU1QTEFURV9ERUNMIG1hdGNoZXMuCgogICBJZiBDT01QTEFJTiB6ZXJvLCBkb24ndCBjb21wbGFpbiBhYm91dCBhbnkgZXJyb3JzIHRoYXQgb2NjdXIuICAqLwoKdHJlZQptYWtlX3VuYm91bmRfY2xhc3NfdGVtcGxhdGUgKHRyZWUgY29udGV4dCwgdHJlZSBuYW1lLCB0cmVlIHBhcm1fbGlzdCwKCQkJICAgICB0c3Vic3RfZmxhZ3NfdCBjb21wbGFpbikKewogIHRyZWUgdDsKICB0cmVlIGQ7CgogIGlmIChUWVBFX1AgKG5hbWUpKQogICAgbmFtZSA9IFRZUEVfSURFTlRJRklFUiAobmFtZSk7CiAgZWxzZSBpZiAoREVDTF9QIChuYW1lKSkKICAgIG5hbWUgPSBERUNMX05BTUUgKG5hbWUpOwogIGdjY19hc3NlcnQgKFRSRUVfQ09ERSAobmFtZSkgPT0gSURFTlRJRklFUl9OT0RFKTsKCiAgaWYgKCFkZXBlbmRlbnRfdHlwZV9wIChjb250ZXh0KQogICAgICB8fCBjdXJyZW50bHlfb3Blbl9jbGFzcyAoY29udGV4dCkpCiAgICB7CiAgICAgIHRyZWUgdG1wbCA9IE5VTExfVFJFRTsKCiAgICAgIGlmIChJU19BR0dSX1RZUEUgKGNvbnRleHQpKQoJdG1wbCA9IGxvb2t1cF9maWVsZCAoY29udGV4dCwgbmFtZSwgMCwgZmFsc2UpOwoKICAgICAgaWYgKCF0bXBsIHx8ICFERUNMX0NMQVNTX1RFTVBMQVRFX1AgKHRtcGwpKQoJewoJICBpZiAoY29tcGxhaW4gJiB0Zl9lcnJvcikKCSAgICBlcnJvciAoIm5vIGNsYXNzIHRlbXBsYXRlIG5hbWVkICVxI1QgaW4gJXEjVCIsIG5hbWUsIGNvbnRleHQpOwoJICByZXR1cm4gZXJyb3JfbWFya19ub2RlOwoJfQoKICAgICAgaWYgKHBhcm1fbGlzdAoJICAmJiAhY29tcF90ZW1wbGF0ZV9wYXJtcyAoREVDTF9URU1QTEFURV9QQVJNUyAodG1wbCksIHBhcm1fbGlzdCkpCgl7CgkgIGlmIChjb21wbGFpbiAmIHRmX2Vycm9yKQoJICAgIHsKCSAgICAgIGVycm9yICgidGVtcGxhdGUgcGFyYW1ldGVycyBkbyBub3QgbWF0Y2ggdGVtcGxhdGUiKTsKCSAgICAgIGNwX2Vycm9yX2F0ICgiJXFEIGRlY2xhcmVkIGhlcmUiLCB0bXBsKTsKCSAgICB9CgkgIHJldHVybiBlcnJvcl9tYXJrX25vZGU7Cgl9CgogICAgICBpZiAoY29tcGxhaW4gJiB0Zl9lcnJvcikKCXBlcmZvcm1fb3JfZGVmZXJfYWNjZXNzX2NoZWNrIChUWVBFX0JJTkZPIChjb250ZXh0KSwgdG1wbCk7CgogICAgICByZXR1cm4gdG1wbDsKICAgIH0KCiAgLyogQnVpbGQgdGhlIFVOQk9VTkRfQ0xBU1NfVEVNUExBVEUuICAqLwogIHQgPSBtYWtlX2FnZ3JfdHlwZSAoVU5CT1VORF9DTEFTU19URU1QTEFURSk7CiAgVFlQRV9DT05URVhUICh0KSA9IEZST0JfQ09OVEVYVCAoY29udGV4dCk7CiAgVFJFRV9UWVBFICh0KSA9IE5VTExfVFJFRTsKCiAgLyogQnVpbGQgdGhlIGNvcnJlc3BvbmRpbmcgVEVNUExBVEVfREVDTC4gICovCiAgZCA9IGJ1aWxkX2RlY2wgKFRFTVBMQVRFX0RFQ0wsIG5hbWUsIHQpOwogIFRZUEVfTkFNRSAoVFJFRV9UWVBFIChkKSkgPSBkOwogIFRZUEVfU1RVQl9ERUNMIChUUkVFX1RZUEUgKGQpKSA9IGQ7CiAgREVDTF9DT05URVhUIChkKSA9IEZST0JfQ09OVEVYVCAoY29udGV4dCk7CiAgREVDTF9BUlRJRklDSUFMIChkKSA9IDE7CiAgREVDTF9URU1QTEFURV9QQVJNUyAoZCkgPSBwYXJtX2xpc3Q7CgogIHJldHVybiB0Owp9CgoMCgovKiBQdXNoIHRoZSBkZWNsYXJhdGlvbnMgb2YgYnVpbHRpbiB0eXBlcyBpbnRvIHRoZSBuYW1lc3BhY2UuCiAgIFJJRF9JTkRFWCBpcyB0aGUgaW5kZXggb2YgdGhlIGJ1aWx0aW4gdHlwZSBpbiB0aGUgYXJyYXkKICAgUklEX1BPSU5URVJTLiAgTkFNRSBpcyB0aGUgbmFtZSB1c2VkIHdoZW4gbG9va2luZyB1cCB0aGUgYnVpbHRpbgogICB0eXBlLiAgVFlQRSBpcyB0aGUgX1RZUEUgbm9kZSBmb3IgdGhlIGJ1aWx0aW4gdHlwZS4gICovCgp2b2lkCnJlY29yZF9idWlsdGluX3R5cGUgKGVudW0gcmlkIHJpZF9pbmRleCwKICAgICAgICAgICAgICAgICAgICAgY29uc3QgY2hhciogbmFtZSwKICAgICAgICAgICAgICAgICAgICAgdHJlZSB0eXBlKQp7CiAgdHJlZSBybmFtZSA9IE5VTExfVFJFRSwgdG5hbWUgPSBOVUxMX1RSRUU7CiAgdHJlZSB0ZGVjbCA9IE5VTExfVFJFRTsKCiAgaWYgKChpbnQpIHJpZF9pbmRleCA8IChpbnQpIFJJRF9NQVgpCiAgICBybmFtZSA9IHJpZHBvaW50ZXJzWyhpbnQpIHJpZF9pbmRleF07CiAgaWYgKG5hbWUpCiAgICB0bmFtZSA9IGdldF9pZGVudGlmaWVyIChuYW1lKTsKCiAgLyogVGhlIGNhbGxzIHRvIFNFVF9JREVOVElGSUVSX0dMT0JBTF9WQUxVRSBiZWxvdyBzaG91bGQgYmUKICAgICBlbGltaW5hdGVkLiAgQnVpbHQtaW4gdHlwZXMgc2hvdWxkIG5vdCBiZSBsb29rZWQgdXAgbmFtZTsgdGhlaXIKICAgICBuYW1lcyBhcmUga2V5d29yZHMgdGhhdCB0aGUgcGFyc2VyIGNhbiByZWNvZ25pemUuICBIb3dldmVyLCB0aGVyZQogICAgIGlzIGNvZGUgaW4gYy1jb21tb24uYyB0aGF0IHVzZXMgaWRlbnRpZmllcl9nbG9iYWxfdmFsdWUgdG8gbG9vawogICAgIHVwIGJ1aWx0LWluIHR5cGVzIGJ5IG5hbWUuICAqLwogIGlmICh0bmFtZSkKICAgIHsKICAgICAgdGRlY2wgPSBidWlsZF9kZWNsIChUWVBFX0RFQ0wsIHRuYW1lLCB0eXBlKTsKICAgICAgREVDTF9BUlRJRklDSUFMICh0ZGVjbCkgPSAxOwogICAgICBTRVRfSURFTlRJRklFUl9HTE9CQUxfVkFMVUUgKHRuYW1lLCB0ZGVjbCk7CiAgICB9CiAgaWYgKHJuYW1lKQogICAgewogICAgICBpZiAoIXRkZWNsKQoJewoJICB0ZGVjbCA9IGJ1aWxkX2RlY2wgKFRZUEVfREVDTCwgcm5hbWUsIHR5cGUpOwoJICBERUNMX0FSVElGSUNJQUwgKHRkZWNsKSA9IDE7Cgl9CiAgICAgIFNFVF9JREVOVElGSUVSX0dMT0JBTF9WQUxVRSAocm5hbWUsIHRkZWNsKTsKICAgIH0KCiAgaWYgKCFUWVBFX05BTUUgKHR5cGUpKQogICAgVFlQRV9OQU1FICh0eXBlKSA9IHRkZWNsOwoKICBpZiAodGRlY2wpCiAgICBkZWJ1Z19ob29rcy0+dHlwZV9kZWNsICh0ZGVjbCwgMCk7Cn0KCi8qIFJlY29yZCBvbmUgb2YgdGhlIHN0YW5kYXJkIEphdmEgdHlwZXMuCiAqIERlY2xhcmUgaXQgYXMgaGF2aW5nIHRoZSBnaXZlbiBOQU1FLgogKiBJZiBTSVpFID4gMCwgaXQgaXMgdGhlIHNpemUgb2Ygb25lIG9mIHRoZSBpbnRlZ3JhbCB0eXBlczsKICogb3RoZXJ3aXNlIGl0IGlzIHRoZSBuZWdhdGl2ZSBvZiB0aGUgc2l6ZSBvZiBvbmUgb2YgdGhlIG90aGVyIHR5cGVzLiAgKi8KCnN0YXRpYyB0cmVlCnJlY29yZF9idWlsdGluX2phdmFfdHlwZSAoY29uc3QgY2hhciogbmFtZSwgaW50IHNpemUpCnsKICB0cmVlIHR5cGUsIGRlY2w7CiAgaWYgKHNpemUgPiAwKQogICAgdHlwZSA9IG1ha2Vfc2lnbmVkX3R5cGUgKHNpemUpOwogIGVsc2UgaWYgKHNpemUgPiAtMzIpCiAgICB7IC8qICJfX2phdmFfY2hhciIgb3IgIiJfX2phdmFfYm9vbGVhbiIuICAqLwogICAgICB0eXBlID0gbWFrZV91bnNpZ25lZF90eXBlICgtc2l6ZSk7CiAgICAgIC8qaWYgKHNpemUgPT0gLTEpCVRSRUVfU0VUX0NPREUgKHR5cGUsIEJPT0xFQU5fVFlQRSk7Ki8KICAgIH0KICBlbHNlCiAgICB7IC8qICJfX2phdmFfZmxvYXQiIG9yICIiX19qYXZhX2RvdWJsZSIuICAqLwogICAgICB0eXBlID0gbWFrZV9ub2RlIChSRUFMX1RZUEUpOwogICAgICBUWVBFX1BSRUNJU0lPTiAodHlwZSkgPSAtIHNpemU7CiAgICAgIGxheW91dF90eXBlICh0eXBlKTsKICAgIH0KICByZWNvcmRfYnVpbHRpbl90eXBlIChSSURfTUFYLCBuYW1lLCB0eXBlKTsKICBkZWNsID0gVFlQRV9OQU1FICh0eXBlKTsKCiAgLyogU3VwcHJlc3MgZ2VuZXJhdGUgZGVidWcgc3ltYm9sIGVudHJpZXMgZm9yIHRoZXNlIHR5cGVzLAogICAgIHNpbmNlIGZvciBub3JtYWwgQysrIHRoZXkgYXJlIGp1c3QgY2x1dHRlci4KICAgICBIb3dldmVyLCBwdXNoX2xhbmdfY29udGV4dCB1bmRvZXMgdGhpcyBpZiBleHRlcm4gIkphdmEiIGlzIHNlZW4uICAqLwogIERFQ0xfSUdOT1JFRF9QIChkZWNsKSA9IDE7CgogIFRZUEVfRk9SX0pBVkEgKHR5cGUpID0gMTsKICByZXR1cm4gdHlwZTsKfQoKLyogUHVzaCBhIHR5cGUgaW50byB0aGUgbmFtZXNwYWNlIHNvIHRoYXQgdGhlIGJhY2stZW5kcyBpZ25vcmUgaXQuICAqLwoKc3RhdGljIHZvaWQKcmVjb3JkX3Vua25vd25fdHlwZSAodHJlZSB0eXBlLCBjb25zdCBjaGFyKiBuYW1lKQp7CiAgdHJlZSBkZWNsID0gcHVzaGRlY2wgKGJ1aWxkX2RlY2wgKFRZUEVfREVDTCwgZ2V0X2lkZW50aWZpZXIgKG5hbWUpLCB0eXBlKSk7CiAgLyogTWFrZSBzdXJlIHRoZSAidW5rbm93biB0eXBlIiB0eXBlZGVjbCBnZXRzIGlnbm9yZWQgZm9yIGRlYnVnIGluZm8uICAqLwogIERFQ0xfSUdOT1JFRF9QIChkZWNsKSA9IDE7CiAgVFlQRV9ERUNMX1NVUFBSRVNTX0RFQlVHIChkZWNsKSA9IDE7CiAgVFlQRV9TSVpFICh0eXBlKSA9IFRZUEVfU0laRSAodm9pZF90eXBlX25vZGUpOwogIFRZUEVfQUxJR04gKHR5cGUpID0gMTsKICBUWVBFX1VTRVJfQUxJR04gKHR5cGUpID0gMDsKICBUWVBFX01PREUgKHR5cGUpID0gVFlQRV9NT0RFICh2b2lkX3R5cGVfbm9kZSk7Cn0KCi8qIEFuIHN0cmluZyBmb3Igd2hpY2ggd2Ugc2hvdWxkIGNyZWF0ZSBhbiBJREVOVElGSUVSX05PREUgYXQKICAgc3RhcnR1cC4gICovCgp0eXBlZGVmIHN0cnVjdCBwcmVkZWZpbmVkX2lkZW50aWZpZXIKewogIC8qIFRoZSBuYW1lIG9mIHRoZSBpZGVudGlmaWVyLiAgKi8KICBjb25zdCBjaGFyICpjb25zdCBuYW1lOwogIC8qIFRoZSBwbGFjZSB3aGVyZSB0aGUgSURFTlRJRklFUl9OT0RFIHNob3VsZCBiZSBzdG9yZWQuICAqLwogIHRyZWUgKmNvbnN0IG5vZGU7CiAgLyogTm9uemVybyBpZiB0aGlzIGlzIHRoZSBuYW1lIG9mIGEgY29uc3RydWN0b3Igb3IgZGVzdHJ1Y3Rvci4gICovCiAgY29uc3QgaW50IGN0b3Jfb3JfZHRvcl9wOwp9IHByZWRlZmluZWRfaWRlbnRpZmllcjsKCi8qIENyZWF0ZSBhbGwgdGhlIHByZWRlZmluZWQgaWRlbnRpZmllcnMuICAqLwoKc3RhdGljIHZvaWQKaW5pdGlhbGl6ZV9wcmVkZWZpbmVkX2lkZW50aWZpZXJzICh2b2lkKQp7CiAgY29uc3QgcHJlZGVmaW5lZF9pZGVudGlmaWVyICpwaWQ7CgogIC8qIEEgdGFibGUgb2YgaWRlbnRpZmllcnMgdG8gY3JlYXRlIGF0IHN0YXJ0dXAuICAqLwogIHN0YXRpYyBjb25zdCBwcmVkZWZpbmVkX2lkZW50aWZpZXIgcHJlZGVmaW5lZF9pZGVudGlmaWVyc1tdID0gewogICAgeyAiQysrIiwgJmxhbmdfbmFtZV9jcGx1c3BsdXMsIDAgfSwKICAgIHsgIkMiLCAmbGFuZ19uYW1lX2MsIDAgfSwKICAgIHsgIkphdmEiLCAmbGFuZ19uYW1lX2phdmEsIDAgfSwKICAgIC8qIFNvbWUgb2YgdGhlc2UgbmFtZXMgaGF2ZSBhIHRyYWlsaW5nIHNwYWNlIHNvIHRoYXQgaXQgaXMKICAgICAgIGltcG9zc2libGUgZm9yIHRoZW0gdG8gY29uZmxpY3Qgd2l0aCBuYW1lcyB3cml0dGVuIGJ5IHVzZXJzLiAgKi8KICAgIHsgIl9fY3QgIiwgJmN0b3JfaWRlbnRpZmllciwgMSB9LAogICAgeyAiX19iYXNlX2N0b3IgIiwgJmJhc2VfY3Rvcl9pZGVudGlmaWVyLCAxIH0sCiAgICB7ICJfX2NvbXBfY3RvciAiLCAmY29tcGxldGVfY3Rvcl9pZGVudGlmaWVyLCAxIH0sCiAgICB7ICJfX2R0ICIsICZkdG9yX2lkZW50aWZpZXIsIDEgfSwKICAgIHsgIl9fY29tcF9kdG9yICIsICZjb21wbGV0ZV9kdG9yX2lkZW50aWZpZXIsIDEgfSwKICAgIHsgIl9fYmFzZV9kdG9yICIsICZiYXNlX2R0b3JfaWRlbnRpZmllciwgMSB9LAogICAgeyAiX19kZWxldGluZ19kdG9yICIsICZkZWxldGluZ19kdG9yX2lkZW50aWZpZXIsIDEgfSwKICAgIHsgSU5fQ0hBUkdFX05BTUUsICZpbl9jaGFyZ2VfaWRlbnRpZmllciwgMCB9LAogICAgeyAibmVsdHMiLCAmbmVsdHNfaWRlbnRpZmllciwgMCB9LAogICAgeyBUSElTX05BTUUsICZ0aGlzX2lkZW50aWZpZXIsIDAgfSwKICAgIHsgVlRBQkxFX0RFTFRBX05BTUUsICZkZWx0YV9pZGVudGlmaWVyLCAwIH0sCiAgICB7IFZUQUJMRV9QRk5fTkFNRSwgJnBmbl9pZGVudGlmaWVyLCAwIH0sCiAgICB7ICJfdnB0ciIsICZ2cHRyX2lkZW50aWZpZXIsIDAgfSwKICAgIHsgIl9fdnR0X3Bhcm0iLCAmdnR0X3Bhcm1faWRlbnRpZmllciwgMCB9LAogICAgeyAiOjoiLCAmZ2xvYmFsX3Njb3BlX25hbWUsIDAgfSwKICAgIHsgInN0ZCIsICZzdGRfaWRlbnRpZmllciwgMCB9LAogICAgeyBOVUxMLCBOVUxMLCAwIH0KICB9OwoKICBmb3IgKHBpZCA9IHByZWRlZmluZWRfaWRlbnRpZmllcnM7IHBpZC0+bmFtZTsgKytwaWQpCiAgICB7CiAgICAgICpwaWQtPm5vZGUgPSBnZXRfaWRlbnRpZmllciAocGlkLT5uYW1lKTsKICAgICAgaWYgKHBpZC0+Y3Rvcl9vcl9kdG9yX3ApCglJREVOVElGSUVSX0NUT1JfT1JfRFRPUl9QICgqcGlkLT5ub2RlKSA9IDE7CiAgICB9CiAgLyogQVBQTEUgTE9DQUwgYmVnaW4gS0VYVCAyLjk1LXB0bWYtY29tcGF0aWJpbGl0eSAtLXR1cmx5ICovCiAgaWYgKFRBUkdFVF9LRVhUQUJJKQogICAgewogICAgICAvKiBUaGlzIGlzIHNuYXJmZWQgZnJvbSB0aGUgMi45NSBjcC10cmVlLmguICBUaGUgbWVjaGFuaXNtIGlzCgkgY29tcGxldGVseSBkaWZmZXJlbnQgZnJvbSBnY2MzIChzZWUgY3AtdHJlZS5oLCBhbmQgcmVhZCB0aGUKCSBjb21tZW50IGp1c3QgYWJvdmUgJ2VudW0gcHRybWVtZnVuY192Yml0X3doZXJlX3QnLiAgU2lnaC4KCgkgQSAyLjk1IHBvaW50ZXItdG8tZnVuY3Rpb24gbWVtYmVyIHR5cGUgbG9va3MgbGlrZToKCgkgc3RydWN0IHsKCSAgIHNob3J0IF9fZGVsdGE7CgkgICBzaG9ydCBfX2luZGV4OwoJICAgdW5pb24gewoJICAgICBQIF9fcGZuOwoJICAgICBzaG9ydCBfX2RlbHRhMjsKCSAgIH0gX19wZm5fb3JfZGVsdGEyOwoJIH07CgoJIHdoZXJlIFAgaXMgYSBQT0lOVEVSX1RZUEUgdG8gYSBNRVRIT0RfVFlQRSBhcHByb3ByaWF0ZSBmb3IgdGhlCgkgcG9pbnRlciB0byBtZW1iZXIuICBUaGUgZmllbGRzIGFyZSB1c2VkIGFzIGZvbGxvd3M6CiAgICAgIAoJIElmIF9fSU5ERVggaXMgLTEsIHRoZW4gdGhlIGZ1bmN0aW9uIHRvIGNhbGwgaXMgbm9uLXZpcnR1YWwsIGFuZAoJIGlzIGxvY2F0ZWQgYXQgdGhlIGFkZHJlc3MgZ2l2ZW4gYnkgX19QRk4uICAKICAgICAgCgkgSWYgX19JTkRFWCBpcyB6ZXJvLCB0aGVuIHRoaXMgYSBOVUxMIHBvaW50ZXItdG8tbWVtYmVyLgoKCSBPdGhlcndpc2UsIHRoZSBmdW5jdGlvbiB0byBjYWxsIGlzIHZpcnR1YWwuICBUaGVuLCBfX0RFTFRBMiBnaXZlcwoJIHRoZSBvZmZzZXQgZnJvbSBhbiBpbnN0YW5jZSBvZiB0aGUgb2JqZWN0IHRvIHRoZSB2aXJ0dWFsIGZ1bmN0aW9uCgkgdGFibGUsIGFuZCBfX0lOREVYIC0gMSBpcyB0aGUgaW5kZXggaW50byB0aGUgdnRhYmxlIHRvIHVzZSB0bwoJIGZpbmQgdGhlIGZ1bmN0aW9uLgogICAgICAKCSBUaGUgdmFsdWUgdG8gdXNlIGZvciB0aGUgVEhJUyBwYXJhbWV0ZXIgaXMgdGhlIGFkZHJlc3Mgb2YgdGhlCgkgb2JqZWN0IHBsdXMgX19ERUxUQS4gICovCgogICAgICBkZWx0YTJfaWRlbnRpZmllciA9IGdldF9pZGVudGlmaWVyICgiX19kZWx0YTIiKTsKICAgICAgaW5kZXhfaWRlbnRpZmllciA9IGdldF9pZGVudGlmaWVyICgiX19pbmRleCIpOwogICAgICBwZm5fb3JfZGVsdGEyX2lkZW50aWZpZXIgPSBnZXRfaWRlbnRpZmllciAoIl9fcGZuX29yX2RlbHRhMiIpOwogICAgfQogIC8qIEFQUExFIExPQ0FMIGVuZCBLRVhUIDIuOTUtcHRtZi1jb21wYXRpYmlsaXR5IC0tdHVybHkgKi8KfQoKLyogQ3JlYXRlIHRoZSBwcmVkZWZpbmVkIHNjYWxhciB0eXBlcyBvZiBDLAogICBhbmQgc29tZSBub2RlcyByZXByZXNlbnRpbmcgc3RhbmRhcmQgY29uc3RhbnRzICgwLCAxLCAodm9pZCAqKTApLgogICBJbml0aWFsaXplIHRoZSBnbG9iYWwgYmluZGluZyBsZXZlbC4KICAgTWFrZSBkZWZpbml0aW9ucyBmb3IgYnVpbHQtaW4gcHJpbWl0aXZlIGZ1bmN0aW9ucy4gICovCgp2b2lkCmN4eF9pbml0X2RlY2xfcHJvY2Vzc2luZyAodm9pZCkKewogIHRyZWUgdm9pZF9mdHlwZTsKICB0cmVlIHZvaWRfZnR5cGVfcHRyOwoKICBidWlsZF9jb21tb25fdHJlZV9ub2RlcyAoZmxhZ19zaWduZWRfY2hhciwgZmFsc2UpOwoKICAvKiBDcmVhdGUgYWxsIHRoZSBpZGVudGlmaWVycyB3ZSBuZWVkLiAgKi8KICBpbml0aWFsaXplX3ByZWRlZmluZWRfaWRlbnRpZmllcnMgKCk7CgogIC8qIENyZWF0ZSB0aGUgZ2xvYmFsIHZhcmlhYmxlcy4gICovCiAgcHVzaF90b190b3BfbGV2ZWwgKCk7CgogIGN1cnJlbnRfZnVuY3Rpb25fZGVjbCA9IE5VTExfVFJFRTsKICBjdXJyZW50X2JpbmRpbmdfbGV2ZWwgPSBOVUxMOwogIC8qIEVudGVyIHRoZSBnbG9iYWwgbmFtZXNwYWNlLiAgKi8KICBnY2NfYXNzZXJ0IChnbG9iYWxfbmFtZXNwYWNlID09IE5VTExfVFJFRSk7CiAgZ2xvYmFsX25hbWVzcGFjZSA9IGJ1aWxkX2xhbmdfZGVjbCAoTkFNRVNQQUNFX0RFQ0wsIGdsb2JhbF9zY29wZV9uYW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZvaWRfdHlwZV9ub2RlKTsKICBiZWdpbl9zY29wZSAoc2tfbmFtZXNwYWNlLCBnbG9iYWxfbmFtZXNwYWNlKTsKCiAgY3VycmVudF9sYW5nX25hbWUgPSBOVUxMX1RSRUU7CgogIC8qIEFkanVzdCB2YXJpb3VzIGZsYWdzIGJhc2VkIG9uIGNvbW1hbmQtbGluZSBzZXR0aW5ncy4gICovCiAgaWYgKCFmbGFnX3Blcm1pc3NpdmUpCiAgICBmbGFnX3BlZGFudGljX2Vycm9ycyA9IDE7CiAgaWYgKCFmbGFnX25vX2lubGluZSkKICAgIHsKICAgICAgZmxhZ19pbmxpbmVfdHJlZXMgPSAxOwogICAgICBmbGFnX25vX2lubGluZSA9IDE7CiAgICB9CiAgaWYgKGZsYWdfaW5saW5lX2Z1bmN0aW9ucykKICAgIGZsYWdfaW5saW5lX3RyZWVzID0gMjsKICAvKiBBUFBMRSBMT0NBTCBiZWdpbiBtcyB0aW5mbyBjb21wYXQgNDIzMDA5OSAqLwogIGlmIChmbGFnX3Zpc2liaWxpdHlfbXNfY29tcGF0KQogICAgZGVmYXVsdF92aXNpYmlsaXR5ID0gVklTSUJJTElUWV9ISURERU47CiAgLyogQVBQTEUgTE9DQUwgZW5kIG1zIHRpbmZvIGNvbXBhdCA0MjMwMDk5ICovCgogIC8qIEZvcmNlIG1pbmltdW0gZnVuY3Rpb24gYWxpZ25tZW50IGlmIHVzaW5nIHRoZSBsZWFzdCBzaWduaWZpY2FudAogICAgIGJpdCBvZiBmdW5jdGlvbiBwb2ludGVycyB0byBzdG9yZSB0aGUgdmlydHVhbCBiaXQuICAqLwogIGlmIChUQVJHRVRfUFRSTUVNRlVOQ19WQklUX0xPQ0FUSU9OID09IHB0cm1lbWZ1bmNfdmJpdF9pbl9wZm4KICAgICAgJiYgZm9yY2VfYWxpZ25fZnVuY3Rpb25zX2xvZyA8IDEpCiAgICBmb3JjZV9hbGlnbl9mdW5jdGlvbnNfbG9nID0gMTsKCiAgLyogSW5pdGlhbGx5LCBDLiAgKi8KICBjdXJyZW50X2xhbmdfbmFtZSA9IGxhbmdfbmFtZV9jOwoKICBlcnJvcl9tYXJrX2xpc3QgPSBidWlsZF90cmVlX2xpc3QgKGVycm9yX21hcmtfbm9kZSwgZXJyb3JfbWFya19ub2RlKTsKICBUUkVFX1RZUEUgKGVycm9yX21hcmtfbGlzdCkgPSBlcnJvcl9tYXJrX25vZGU7CgogIC8qIENyZWF0ZSB0aGUgYHN0ZCcgbmFtZXNwYWNlLiAgKi8KICBwdXNoX25hbWVzcGFjZSAoc3RkX2lkZW50aWZpZXIpOwogIHN0ZF9ub2RlID0gY3VycmVudF9uYW1lc3BhY2U7CiAgcG9wX25hbWVzcGFjZSAoKTsKCiAgY19jb21tb25fbm9kZXNfYW5kX2J1aWx0aW5zICgpOwoKICBqYXZhX2J5dGVfdHlwZV9ub2RlID0gcmVjb3JkX2J1aWx0aW5famF2YV90eXBlICgiX19qYXZhX2J5dGUiLCA4KTsKICBqYXZhX3Nob3J0X3R5cGVfbm9kZSA9IHJlY29yZF9idWlsdGluX2phdmFfdHlwZSAoIl9famF2YV9zaG9ydCIsIDE2KTsKICBqYXZhX2ludF90eXBlX25vZGUgPSByZWNvcmRfYnVpbHRpbl9qYXZhX3R5cGUgKCJfX2phdmFfaW50IiwgMzIpOwogIGphdmFfbG9uZ190eXBlX25vZGUgPSByZWNvcmRfYnVpbHRpbl9qYXZhX3R5cGUgKCJfX2phdmFfbG9uZyIsIDY0KTsKICBqYXZhX2Zsb2F0X3R5cGVfbm9kZSA9IHJlY29yZF9idWlsdGluX2phdmFfdHlwZSAoIl9famF2YV9mbG9hdCIsIC0zMik7CiAgamF2YV9kb3VibGVfdHlwZV9ub2RlID0gcmVjb3JkX2J1aWx0aW5famF2YV90eXBlICgiX19qYXZhX2RvdWJsZSIsIC02NCk7CiAgamF2YV9jaGFyX3R5cGVfbm9kZSA9IHJlY29yZF9idWlsdGluX2phdmFfdHlwZSAoIl9famF2YV9jaGFyIiwgLTE2KTsKICBqYXZhX2Jvb2xlYW5fdHlwZV9ub2RlID0gcmVjb3JkX2J1aWx0aW5famF2YV90eXBlICgiX19qYXZhX2Jvb2xlYW4iLCAtMSk7CgogIGludGVnZXJfdHdvX25vZGUgPSBidWlsZF9pbnRfY3N0IChOVUxMX1RSRUUsIDIpOwogIGludGVnZXJfdGhyZWVfbm9kZSA9IGJ1aWxkX2ludF9jc3QgKE5VTExfVFJFRSwgMyk7CgogIHJlY29yZF9idWlsdGluX3R5cGUgKFJJRF9CT09MLCAiYm9vbCIsIGJvb2xlYW5fdHlwZV9ub2RlKTsKICB0cnV0aHZhbHVlX3R5cGVfbm9kZSA9IGJvb2xlYW5fdHlwZV9ub2RlOwogIHRydXRodmFsdWVfZmFsc2Vfbm9kZSA9IGJvb2xlYW5fZmFsc2Vfbm9kZTsKICB0cnV0aHZhbHVlX3RydWVfbm9kZSA9IGJvb2xlYW5fdHJ1ZV9ub2RlOwoKICBlbXB0eV9leGNlcHRfc3BlYyA9IGJ1aWxkX3RyZWVfbGlzdCAoTlVMTF9UUkVFLCBOVUxMX1RSRUUpOwoKI2lmIDAKICByZWNvcmRfYnVpbHRpbl90eXBlIChSSURfTUFYLCBOVUxMLCBzdHJpbmdfdHlwZV9ub2RlKTsKI2VuZGlmCgogIC8qIEFQUExFIExPQ0FMIGJlZ2luIEtFWFQgMi45NS1wdG1mLWNvbXBhdGliaWxpdHkgLS10dXJseSAqLwogIGlmIChUQVJHRVRfS0VYVEFCSSkKICAgIGRlbHRhX3R5cGVfbm9kZSA9IHNob3J0X2ludGVnZXJfdHlwZV9ub2RlOwogIGVsc2UKICAvKiBBUFBMRSBMT0NBTCBlbmQgS0VYVCAyLjk1LXB0bWYtY29tcGF0aWJpbGl0eSAtLXR1cmx5ICovCiAgZGVsdGFfdHlwZV9ub2RlID0gcHRyZGlmZl90eXBlX25vZGU7CiAgdnRhYmxlX2luZGV4X3R5cGUgPSBwdHJkaWZmX3R5cGVfbm9kZTsKCiAgdnR0X3Bhcm1fdHlwZSA9IGJ1aWxkX3BvaW50ZXJfdHlwZSAoY29uc3RfcHRyX3R5cGVfbm9kZSk7CiAgdm9pZF9mdHlwZSA9IGJ1aWxkX2Z1bmN0aW9uX3R5cGUgKHZvaWRfdHlwZV9ub2RlLCB2b2lkX2xpc3Rfbm9kZSk7CiAgdm9pZF9mdHlwZV9wdHIgPSBidWlsZF9mdW5jdGlvbl90eXBlICh2b2lkX3R5cGVfbm9kZSwKCQkJCQl0cmVlX2NvbnMgKE5VTExfVFJFRSwKCQkJCQkJICAgcHRyX3R5cGVfbm9kZSwKCQkJCQkJICAgdm9pZF9saXN0X25vZGUpKTsKICB2b2lkX2Z0eXBlX3B0cgogICAgPSBidWlsZF9leGNlcHRpb25fdmFyaWFudCAodm9pZF9mdHlwZV9wdHIsIGVtcHR5X2V4Y2VwdF9zcGVjKTsKCiAgLyogQysrIGV4dGVuc2lvbnMgKi8KCiAgdW5rbm93bl90eXBlX25vZGUgPSBtYWtlX25vZGUgKFVOS05PV05fVFlQRSk7CiAgcmVjb3JkX3Vua25vd25fdHlwZSAodW5rbm93bl90eXBlX25vZGUsICJ1bmtub3duIHR5cGUiKTsKCiAgLyogSW5kaXJlY3RpbmcgYW4gVU5LTk9XTl9UWVBFIG5vZGUgeWllbGRzIGFuIFVOS05PV05fVFlQRSBub2RlLiAgKi8KICBUUkVFX1RZUEUgKHVua25vd25fdHlwZV9ub2RlKSA9IHVua25vd25fdHlwZV9ub2RlOwoKICAvKiBMb29raW5nIHVwIFRZUEVfUE9JTlRFUl9UTyBhbmQgVFlQRV9SRUZFUkVOQ0VfVE8geWllbGQgdGhlIHNhbWUKICAgICByZXN1bHQuICAqLwogIFRZUEVfUE9JTlRFUl9UTyAodW5rbm93bl90eXBlX25vZGUpID0gdW5rbm93bl90eXBlX25vZGU7CiAgVFlQRV9SRUZFUkVOQ0VfVE8gKHVua25vd25fdHlwZV9ub2RlKSA9IHVua25vd25fdHlwZV9ub2RlOwoKICB7CiAgICAvKiBNYWtlIHN1cmUgd2UgZ2V0IGEgdW5pcXVlIGZ1bmN0aW9uIHR5cGUsIHNvIHdlIGNhbiBnaXZlCiAgICAgICBpdHMgcG9pbnRlciB0eXBlIGEgbmFtZS4gIChUaGlzIHdpbnMgZm9yIGdkYi4pICovCiAgICB0cmVlIHZmdW5jX3R5cGUgPSBtYWtlX25vZGUgKEZVTkNUSU9OX1RZUEUpOwogICAgVFJFRV9UWVBFICh2ZnVuY190eXBlKSA9IGludGVnZXJfdHlwZV9ub2RlOwogICAgVFlQRV9BUkdfVFlQRVMgKHZmdW5jX3R5cGUpID0gTlVMTF9UUkVFOwogICAgbGF5b3V0X3R5cGUgKHZmdW5jX3R5cGUpOwoKICAgIHZ0YWJsZV9lbnRyeV90eXBlID0gYnVpbGRfcG9pbnRlcl90eXBlICh2ZnVuY190eXBlKTsKICB9CiAgcmVjb3JkX2J1aWx0aW5fdHlwZSAoUklEX01BWCwgVlRCTF9QVFJfVFlQRSwgdnRhYmxlX2VudHJ5X3R5cGUpOwoKICB2dGJsX3R5cGVfbm9kZQogICAgPSBidWlsZF9jcGx1c19hcnJheV90eXBlICh2dGFibGVfZW50cnlfdHlwZSwgTlVMTF9UUkVFKTsKICBsYXlvdXRfdHlwZSAodnRibF90eXBlX25vZGUpOwogIHZ0YmxfdHlwZV9ub2RlID0gYnVpbGRfcXVhbGlmaWVkX3R5cGUgKHZ0YmxfdHlwZV9ub2RlLCBUWVBFX1FVQUxfQ09OU1QpOwogIHJlY29yZF9idWlsdGluX3R5cGUgKFJJRF9NQVgsIE5VTEwsIHZ0YmxfdHlwZV9ub2RlKTsKICB2dGJsX3B0cl90eXBlX25vZGUgPSBidWlsZF9wb2ludGVyX3R5cGUgKHZ0YWJsZV9lbnRyeV90eXBlKTsKICBsYXlvdXRfdHlwZSAodnRibF9wdHJfdHlwZV9ub2RlKTsKICByZWNvcmRfYnVpbHRpbl90eXBlIChSSURfTUFYLCBOVUxMLCB2dGJsX3B0cl90eXBlX25vZGUpOwoKICBwdXNoX25hbWVzcGFjZSAoZ2V0X2lkZW50aWZpZXIgKCJfX2N4eGFiaXYxIikpOwogIGFiaV9ub2RlID0gY3VycmVudF9uYW1lc3BhY2U7CiAgcG9wX25hbWVzcGFjZSAoKTsKCiAgZ2xvYmFsX3R5cGVfbm9kZSA9IG1ha2Vfbm9kZSAoTEFOR19UWVBFKTsKICByZWNvcmRfdW5rbm93bl90eXBlIChnbG9iYWxfdHlwZV9ub2RlLCAiZ2xvYmFsIHR5cGUiKTsKCiAgLyogTm93LCBDKysuICAqLwogIGN1cnJlbnRfbGFuZ19uYW1lID0gbGFuZ19uYW1lX2NwbHVzcGx1czsKCiAgewogICAgdHJlZSBiYWRfYWxsb2NfaWQ7CiAgICB0cmVlIGJhZF9hbGxvY190eXBlX25vZGU7CiAgICB0cmVlIGJhZF9hbGxvY19kZWNsOwogICAgdHJlZSBuZXd0eXBlLCBkZWx0eXBlOwogICAgdHJlZSBwdHJfZnR5cGVfc2l6ZXR5cGU7CgogICAgcHVzaF9uYW1lc3BhY2UgKHN0ZF9pZGVudGlmaWVyKTsKICAgIGJhZF9hbGxvY19pZCA9IGdldF9pZGVudGlmaWVyICgiYmFkX2FsbG9jIik7CiAgICBiYWRfYWxsb2NfdHlwZV9ub2RlID0gbWFrZV9hZ2dyX3R5cGUgKFJFQ09SRF9UWVBFKTsKICAgIFRZUEVfQ09OVEVYVCAoYmFkX2FsbG9jX3R5cGVfbm9kZSkgPSBjdXJyZW50X25hbWVzcGFjZTsKICAgIGJhZF9hbGxvY19kZWNsCiAgICAgID0gY3JlYXRlX2ltcGxpY2l0X3R5cGVkZWYgKGJhZF9hbGxvY19pZCwgYmFkX2FsbG9jX3R5cGVfbm9kZSk7CiAgICBERUNMX0NPTlRFWFQgKGJhZF9hbGxvY19kZWNsKSA9IGN1cnJlbnRfbmFtZXNwYWNlOwogICAgVFlQRV9TVFVCX0RFQ0wgKGJhZF9hbGxvY190eXBlX25vZGUpID0gYmFkX2FsbG9jX2RlY2w7CiAgICBwb3BfbmFtZXNwYWNlICgpOwoKICAgIHB0cl9mdHlwZV9zaXpldHlwZQogICAgICA9IGJ1aWxkX2Z1bmN0aW9uX3R5cGUgKHB0cl90eXBlX25vZGUsCgkJCSAgICAgdHJlZV9jb25zIChOVUxMX1RSRUUsCgkJCQkJc2l6ZV90eXBlX25vZGUsCgkJCQkJdm9pZF9saXN0X25vZGUpKTsKICAgIG5ld3R5cGUgPSBidWlsZF9leGNlcHRpb25fdmFyaWFudAogICAgICAocHRyX2Z0eXBlX3NpemV0eXBlLCBhZGRfZXhjZXB0aW9uX3NwZWNpZmllcgogICAgICAgKE5VTExfVFJFRSwgYmFkX2FsbG9jX3R5cGVfbm9kZSwgLTEpKTsKICAgIGRlbHR5cGUgPSBidWlsZF9leGNlcHRpb25fdmFyaWFudCAodm9pZF9mdHlwZV9wdHIsIGVtcHR5X2V4Y2VwdF9zcGVjKTsKICAgIHB1c2hfY3BfbGlicmFyeV9mbiAoTkVXX0VYUFIsIG5ld3R5cGUpOwogICAgcHVzaF9jcF9saWJyYXJ5X2ZuIChWRUNfTkVXX0VYUFIsIG5ld3R5cGUpOwogICAgZ2xvYmFsX2RlbGV0ZV9mbmRlY2wgPSBwdXNoX2NwX2xpYnJhcnlfZm4gKERFTEVURV9FWFBSLCBkZWx0eXBlKTsKICAgIHB1c2hfY3BfbGlicmFyeV9mbiAoVkVDX0RFTEVURV9FWFBSLCBkZWx0eXBlKTsKICB9CgogIGFib3J0X2ZuZGVjbAogICAgPSBidWlsZF9saWJyYXJ5X2ZuX3B0ciAoIl9fY3hhX3B1cmVfdmlydHVhbCIsIHZvaWRfZnR5cGUpOwoKICAvKiBQZXJmb3JtIG90aGVyIGxhbmd1YWdlIGRlcGVuZGVudCBpbml0aWFsaXphdGlvbnMuICAqLwogIGluaXRfY2xhc3NfcHJvY2Vzc2luZyAoKTsKICBpbml0X3J0dGlfcHJvY2Vzc2luZyAoKTsKCiAgaWYgKGZsYWdfZXhjZXB0aW9ucykKICAgIGluaXRfZXhjZXB0aW9uX3Byb2Nlc3NpbmcgKCk7CgogIGlmICghIHN1cHBvcnRzX29uZV9vbmx5ICgpKQogICAgZmxhZ193ZWFrID0gMDsKCiAgbWFrZV9mbmFtZV9kZWNsID0gY3BfbWFrZV9mbmFtZV9kZWNsOwogIHN0YXJ0X2ZuYW1lX2RlY2xzICgpOwoKICAvKiBTaG93IHdlIHVzZSBFSCBmb3IgY2xlYW51cHMuICAqLwogIGlmIChmbGFnX2V4Y2VwdGlvbnMpCiAgICB1c2luZ19laF9mb3JfY2xlYW51cHMgKCk7CgogIC8qIEFQUExFIExPQ0FMIGJlZ2luIGZ3cml0YWJsZSBzdHJpbmdzLiAgKi8KICAvKiBNYWludGFpbiBjb25zaXN0ZW5jeS4gIFBlcmhhcHMgd2Ugc2hvdWxkIGp1c3QgY29tcGxhaW4gaWYgdGhleQogICAgIHNheSAtZndyaXRhYmxlLXN0cmluZ3M/ICAqLwogICBpZiAoZmxhZ193cml0YWJsZV9zdHJpbmdzKQogICAgIGZsYWdfY29uc3Rfc3RyaW5ncyA9IDA7CiAgLyogQVBQTEUgTE9DQUwgZW5kIGZ3cml0YWJsZSBzdHJpbmdzLiAgKi8KfQoKLyogR2VuZXJhdGUgYW4gaW5pdGlhbGl6ZXIgZm9yIGEgZnVuY3Rpb24gbmFtaW5nIHZhcmlhYmxlIGZyb20KICAgTkFNRS4gTkFNRSBtYXkgYmUgTlVMTCwgdG8gaW5kaWNhdGUgYSBkZXBlbmRlbnQgbmFtZS4gIFRZUEVfUCBpcwogICBmaWxsZWQgaW4gd2l0aCB0aGUgdHlwZSBvZiB0aGUgaW5pdC4gICovCgp0cmVlCmNwX2ZuYW1lX2luaXQgKGNvbnN0IGNoYXIqIG5hbWUsIHRyZWUgKnR5cGVfcCkKewogIHRyZWUgZG9tYWluID0gTlVMTF9UUkVFOwogIHRyZWUgdHlwZTsKICB0cmVlIGluaXQgPSBOVUxMX1RSRUU7CiAgc2l6ZV90IGxlbmd0aCA9IDA7CgogIGlmIChuYW1lKQogICAgewogICAgICBsZW5ndGggPSBzdHJsZW4gKG5hbWUpOwogICAgICBkb21haW4gPSBidWlsZF9pbmRleF90eXBlIChzaXplX2ludCAobGVuZ3RoKSk7CiAgICAgIGluaXQgPSBidWlsZF9zdHJpbmcgKGxlbmd0aCArIDEsIG5hbWUpOwogICAgfQoKICB0eXBlID0gYnVpbGRfcXVhbGlmaWVkX3R5cGUgKGNoYXJfdHlwZV9ub2RlLCBUWVBFX1FVQUxfQ09OU1QpOwogIHR5cGUgPSBidWlsZF9jcGx1c19hcnJheV90eXBlICh0eXBlLCBkb21haW4pOwoKICAqdHlwZV9wID0gdHlwZTsKCiAgaWYgKGluaXQpCiAgICBUUkVFX1RZUEUgKGluaXQpID0gdHlwZTsKICBlbHNlCiAgICBpbml0ID0gZXJyb3JfbWFya19ub2RlOwoKICByZXR1cm4gaW5pdDsKfQoKLyogQ3JlYXRlIHRoZSBWQVJfREVDTCBmb3IgX19GVU5DVElPTl9fIGV0Yy4gSUQgaXMgdGhlIG5hbWUgdG8gZ2l2ZSB0aGUKICAgZGVjbCwgTkFNRSBpcyB0aGUgaW5pdGlhbGl6YXRpb24gc3RyaW5nIGFuZCBUWVBFX0RFUCBpbmRpY2F0ZXMgd2hldGhlcgogICBOQU1FIGRlcGVuZGVkIG9uIHRoZSB0eXBlIG9mIHRoZSBmdW5jdGlvbi4gV2UgbWFrZSB1c2Ugb2YgdGhhdCB0byBkZXRlY3QKICAgX19QUkVUVFlfRlVOQ1RJT05fXyBpbnNpZGUgYSB0ZW1wbGF0ZSBmbi4gVGhpcyBpcyBiZWluZyBkb25lCiAgIGxhemlseSBhdCB0aGUgcG9pbnQgb2YgZmlyc3QgdXNlLCBzbyB3ZSBtdXN0bid0IHB1c2ggdGhlIGRlY2wgbm93LiAgKi8KCnN0YXRpYyB0cmVlCmNwX21ha2VfZm5hbWVfZGVjbCAodHJlZSBpZCwgaW50IHR5cGVfZGVwKQp7CiAgY29uc3QgY2hhciAqY29uc3QgbmFtZSA9ICh0eXBlX2RlcCAmJiBwcm9jZXNzaW5nX3RlbXBsYXRlX2RlY2wKCQkJICAgID8gTlVMTCA6IGZuYW1lX2FzX3N0cmluZyAodHlwZV9kZXApKTsKICB0cmVlIHR5cGU7CiAgdHJlZSBpbml0ID0gY3BfZm5hbWVfaW5pdCAobmFtZSwgJnR5cGUpOwogIHRyZWUgZGVjbCA9IGJ1aWxkX2RlY2wgKFZBUl9ERUNMLCBpZCwgdHlwZSk7CgogIGlmIChuYW1lKQogICAgZnJlZSAoKGNoYXIgKikgbmFtZSk7CgogIC8qIEFzIHdlJ3JlIHVzaW5nIHB1c2hkZWNsX3dpdGhfc2NvcGUsIHdlIG11c3Qgc2V0IHRoZSBjb250ZXh0LiAgKi8KICBERUNMX0NPTlRFWFQgKGRlY2wpID0gY3VycmVudF9mdW5jdGlvbl9kZWNsOwogIERFQ0xfUFJFVFRZX0ZVTkNUSU9OX1AgKGRlY2wpID0gdHlwZV9kZXA7CgogIFRSRUVfU1RBVElDIChkZWNsKSA9IDE7CiAgVFJFRV9SRUFET05MWSAoZGVjbCkgPSAxOwogIERFQ0xfQVJUSUZJQ0lBTCAoZGVjbCkgPSAxOwogIERFQ0xfSU5JVElBTCAoZGVjbCkgPSBpbml0OwoKICBUUkVFX1VTRUQgKGRlY2wpID0gMTsKCiAgaWYgKGN1cnJlbnRfZnVuY3Rpb25fZGVjbCkKICAgIHsKICAgICAgc3RydWN0IGNwX2JpbmRpbmdfbGV2ZWwgKmIgPSBjdXJyZW50X2JpbmRpbmdfbGV2ZWw7CiAgICAgIHdoaWxlIChiLT5sZXZlbF9jaGFpbi0+a2luZCAhPSBza19mdW5jdGlvbl9wYXJtcykKCWIgPSBiLT5sZXZlbF9jaGFpbjsKICAgICAgcHVzaGRlY2xfd2l0aF9zY29wZSAoZGVjbCwgYik7CiAgICAgIGNwX2ZpbmlzaF9kZWNsIChkZWNsLCBpbml0LCBOVUxMX1RSRUUsIExPT0tVUF9PTkxZQ09OVkVSVElORyk7CiAgICB9CiAgZWxzZQogICAgcHVzaGRlY2xfdG9wX2xldmVsX2FuZF9maW5pc2ggKGRlY2wsIGluaXQpOwoKICByZXR1cm4gZGVjbDsKfQoKLyogTWFrZSBhIGRlZmluaXRpb24gZm9yIGEgYnVpbHRpbiBmdW5jdGlvbiBuYW1lZCBOQU1FIGluIHRoZSBjdXJyZW50CiAgIG5hbWVzcGFjZSwgd2hvc2UgZGF0YSB0eXBlIGlzIFRZUEUgYW5kIHdob3NlIGNvbnRleHQgaXMgQ09OVEVYVC4KICAgVFlQRSBzaG91bGQgYmUgYSBmdW5jdGlvbiB0eXBlIHdpdGggYXJndW1lbnQgdHlwZXMuCgogICBDTEFTUyBhbmQgQ09ERSB0ZWxsIGxhdGVyIHBhc3NlcyBob3cgdG8gY29tcGlsZSBjYWxscyB0byB0aGlzIGZ1bmN0aW9uLgogICBTZWUgdHJlZS5oIGZvciBwb3NzaWJsZSB2YWx1ZXMuCgogICBJZiBMSUJOQU1FIGlzIG5vbnplcm8sIHVzZSB0aGF0IGZvciBERUNMX0FTU0VNQkxFUl9OQU1FLAogICB0aGUgbmFtZSB0byBiZSBjYWxsZWQgaWYgd2UgY2FuJ3Qgb3BlbmNvZGUgdGhlIGZ1bmN0aW9uLgogICBJZiBBVFRSUyBpcyBub256ZXJvLCB1c2UgdGhhdCBmb3IgdGhlIGZ1bmN0aW9uJ3MgYXR0cmlidXRlCiAgIGxpc3QuICAqLwoKc3RhdGljIHRyZWUKYnVpbHRpbl9mdW5jdGlvbl8xIChjb25zdCBjaGFyKiBuYW1lLAogICAgICAgICAgICAgICAgICAgIHRyZWUgdHlwZSwKICAgICAgICAgICAgICAgICAgICB0cmVlIGNvbnRleHQsCgkJICAgIGVudW0gYnVpbHRfaW5fZnVuY3Rpb24gY29kZSwKICAgICAgICAgICAgICAgICAgICBlbnVtIGJ1aWx0X2luX2NsYXNzIGNsYXNzLAogICAgICAgICAgICAgICAgICAgIGNvbnN0IGNoYXIqIGxpYm5hbWUsCiAgICAgICAgICAgICAgICAgICAgdHJlZSBhdHRycykKewogIHRyZWUgZGVjbCA9IGJ1aWxkX2xpYnJhcnlfZm5fMSAoZ2V0X2lkZW50aWZpZXIgKG5hbWUpLCBFUlJPUl9NQVJLLCB0eXBlKTsKICBERUNMX0JVSUxUX0lOX0NMQVNTIChkZWNsKSA9IGNsYXNzOwogIERFQ0xfRlVOQ1RJT05fQ09ERSAoZGVjbCkgPSBjb2RlOwogIERFQ0xfQ09OVEVYVCAoZGVjbCkgPSBjb250ZXh0OwoKICBwdXNoZGVjbCAoZGVjbCk7CgogIC8qIFNpbmNlIGBwdXNoZGVjbCcgcmVsaWVzIG9uIERFQ0xfQVNTRU1CTEVSX05BTUUgaW5zdGVhZCBvZiBERUNMX05BTUUsCiAgICAgd2UgY2Fubm90IGNoYW5nZSBERUNMX0FTU0VNQkxFUl9OQU1FIHVudGlsIHdlIGhhdmUgaW5zdGFsbGVkIHRoaXMKICAgICBmdW5jdGlvbiBpbiB0aGUgbmFtZXNwYWNlLiAgKi8KICBpZiAobGlibmFtZSkKICAgIFNFVF9ERUNMX0FTU0VNQkxFUl9OQU1FIChkZWNsLCBnZXRfaWRlbnRpZmllciAobGlibmFtZSkpOwoKICAvKiBXYXJuIGlmIGEgZnVuY3Rpb24gaW4gdGhlIG5hbWVzcGFjZSBmb3IgdXNlcnMKICAgICBpcyB1c2VkIHdpdGhvdXQgYW4gb2NjYXNpb24gdG8gY29uc2lkZXIgaXQgZGVjbGFyZWQuICAqLwogIC8qIEFQUExFIExPQ0FMIGJlZ2luIEFsdGlWZWMgKi8KICBpZiAoKG5hbWVbMF0gIT0gJ18nIHx8IG5hbWVbMV0gIT0gJ18nKQojaWZkZWYgVEFSR0VUX1BPV0VSUEMKICAgICAgLyogQWx0aVZlYyBQSU0gYnVpbHRpbnMsIGV2ZW4gdGhvdWdoIHRoZXkgZG8gbm90IGJlZ2luIHdpdGgKCSB1bmRlcnNjb3JlcywgbmVlZCBub3QgYmUgZGVjbGFyZWQgZWl0aGVyLiAgKi8KICAgICAgJiYgIShjbGFzcyA9PSBCVUlMVF9JTl9NRAoJICAgJiYgY29kZSA+PSBBTFRJVkVDX1BJTV9fRklSU1QKCSAgICYmIGNvZGUgPD0gQUxUSVZFQ19QSU1fX0xBU1QpCiNlbmRpZiAvKiBUQVJHRVRfUE9XRVJQQyAqLwogICAgICApCiAgICBERUNMX0FOVElDSVBBVEVEIChkZWNsKSA9IDE7CiAgLyogQVBQTEUgTE9DQUwgZW5kIEFsdGlWZWMgKi8KCiAgLyogUG9zc2libHkgYXBwbHkgc29tZSBkZWZhdWx0IGF0dHJpYnV0ZXMgdG8gdGhpcyBidWlsdC1pbiBmdW5jdGlvbi4gICovCiAgaWYgKGF0dHJzKQogICAgZGVjbF9hdHRyaWJ1dGVzICgmZGVjbCwgYXR0cnMsIEFUVFJfRkxBR19CVUlMVF9JTik7CiAgZWxzZQogICAgZGVjbF9hdHRyaWJ1dGVzICgmZGVjbCwgTlVMTF9UUkVFLCAwKTsKCiAgcmV0dXJuIGRlY2w7Cn0KCi8qIEVudHJ5IHBvaW50IGZvciB0aGUgYmVuZWZpdCBvZiBjX2NvbW1vbl9ub2Rlc19hbmRfYnVpbHRpbnMuCgogICBNYWtlIGEgZGVmaW5pdGlvbiBmb3IgYSBidWlsdGluIGZ1bmN0aW9uIG5hbWVkIE5BTUUgYW5kIHdob3NlIGRhdGEgdHlwZQogICBpcyBUWVBFLiAgVFlQRSBzaG91bGQgYmUgYSBmdW5jdGlvbiB0eXBlIHdpdGggYXJndW1lbnQgdHlwZXMuICBUaGlzCiAgIGZ1bmN0aW9uIHBsYWNlcyB0aGUgYW50aWNpcGF0ZWQgZGVjbGFyYXRpb24gaW4gdGhlIGdsb2JhbCBuYW1lc3BhY2UKICAgYW5kIGFkZGl0aW9uYWxseSBpbiB0aGUgc3RkIG5hbWVzcGFjZSBpZiBhcHByb3ByaWF0ZS4KCiAgIENMQVNTIGFuZCBDT0RFIHRlbGwgbGF0ZXIgcGFzc2VzIGhvdyB0byBjb21waWxlIGNhbGxzIHRvIHRoaXMgZnVuY3Rpb24uCiAgIFNlZSB0cmVlLmggZm9yIHBvc3NpYmxlIHZhbHVlcy4KCiAgIElmIExJQk5BTUUgaXMgbm9uemVybywgdXNlIHRoYXQgZm9yIERFQ0xfQVNTRU1CTEVSX05BTUUsCiAgIHRoZSBuYW1lIHRvIGJlIGNhbGxlZCBpZiB3ZSBjYW4ndCBvcGVuY29kZSB0aGUgZnVuY3Rpb24uCgogICBJZiBBVFRSUyBpcyBub256ZXJvLCB1c2UgdGhhdCBmb3IgdGhlIGZ1bmN0aW9uJ3MgYXR0cmlidXRlCiAgIGxpc3QuICAqLwoKdHJlZQpidWlsdGluX2Z1bmN0aW9uIChjb25zdCBjaGFyKiBuYW1lLAogICAgICAgICAgICAgICAgICB0cmVlIHR5cGUsCiAgICAgICAgICAgICAgICAgIGludCBjb2RlLAogICAgICAgICAgICAgICAgICBlbnVtIGJ1aWx0X2luX2NsYXNzIGNsLAogICAgICAgICAgICAgICAgICBjb25zdCBjaGFyKiBsaWJuYW1lLAogICAgICAgICAgICAgICAgICB0cmVlIGF0dHJzKQp7CiAgLyogQWxsIGJ1aWx0aW5zIHRoYXQgZG9uJ3QgYmVnaW4gd2l0aCBhbiAnXycgc2hvdWxkIGFkZGl0aW9uYWxseQogICAgIGdvIGluIHRoZSAnc3RkJyBuYW1lc3BhY2UuICAqLwogIC8qIEFQUExFIExPQ0FMIGJlZ2luIGFsbG9jYSBub3QgaW4gc3RkICovCiAgLyogRG9uJ3QgdXNlIGBzdGQnIG5hbWVzcGFjZSBmb3IgYWxsb2NhLiAgKi8KICBpZiAobmFtZVswXSAhPSAnXycgJiYgc3RyY21wIChuYW1lLCAiYWxsb2NhIikpCiAgICAvKiBBUFBMRSBMT0NBTCBlbmQgYWxsb2NhIG5vdCBpbiBzdGQgKi8KICAgIHsKICAgICAgcHVzaF9uYW1lc3BhY2UgKHN0ZF9pZGVudGlmaWVyKTsKICAgICAgYnVpbHRpbl9mdW5jdGlvbl8xIChuYW1lLCB0eXBlLCBzdGRfbm9kZSwgY29kZSwgY2wsIGxpYm5hbWUsIGF0dHJzKTsKICAgICAgcG9wX25hbWVzcGFjZSAoKTsKICAgIH0KCiAgcmV0dXJuIGJ1aWx0aW5fZnVuY3Rpb25fMSAobmFtZSwgdHlwZSwgTlVMTF9UUkVFLCBjb2RlLAoJCQkgICAgIGNsLCBsaWJuYW1lLCBhdHRycyk7Cn0KCi8qIEdlbmVyYXRlIGEgRlVOQ1RJT05fREVDTCB3aXRoIHRoZSB0eXBpY2FsIGZsYWdzIGZvciBhIHJ1bnRpbWUgbGlicmFyeQogICBmdW5jdGlvbi4gIE5vdCBjYWxsZWQgZGlyZWN0bHkuICAqLwoKc3RhdGljIHRyZWUKYnVpbGRfbGlicmFyeV9mbl8xICh0cmVlIG5hbWUsIGVudW0gdHJlZV9jb2RlIG9wZXJhdG9yX2NvZGUsIHRyZWUgdHlwZSkKewogIHRyZWUgZm4gPSBidWlsZF9sYW5nX2RlY2wgKEZVTkNUSU9OX0RFQ0wsIG5hbWUsIHR5cGUpOwogIERFQ0xfRVhURVJOQUwgKGZuKSA9IDE7CiAgVFJFRV9QVUJMSUMgKGZuKSA9IDE7CiAgREVDTF9BUlRJRklDSUFMIChmbikgPSAxOwogIFRSRUVfTk9USFJPVyAoZm4pID0gMTsKICBTRVRfT1ZFUkxPQURFRF9PUEVSQVRPUl9DT0RFIChmbiwgb3BlcmF0b3JfY29kZSk7CiAgU0VUX0RFQ0xfTEFOR1VBR0UgKGZuLCBsYW5nX2MpOwogIC8qIFJ1bnRpbWUgbGlicmFyeSByb3V0aW5lcyBhcmUsIGJ5IGRlZmluaXRpb24sIGF2YWlsYWJsZSBpbiBhbgogICAgIGV4dGVybmFsIHNoYXJlZCBvYmplY3QuICAqLwogIERFQ0xfVklTSUJJTElUWSAoZm4pID0gVklTSUJJTElUWV9ERUZBVUxUOwogIERFQ0xfVklTSUJJTElUWV9TUEVDSUZJRUQgKGZuKSA9IDE7CiAgLyogQVBQTEUgTE9DQUwgYmVnaW4gb3B0aW1pemF0aW9uIHByYWdtYXMgMzEyNDIzNS8zNDIwMjQyICovCiAgLyogQnVpbGQgYSBtYXBwaW5nIGJldHdlZW4gdGhpcyBkZWNsIGFuZCB0aGUgcGVyLWZ1bmN0aW9uIG9wdGlvbnMgaW4KICAgICBlZmZlY3QgYXQgdGhpcyBwb2ludC4gICovCiAgcmVjb3JkX2Z1bmNfY2xfcGZfb3B0c19tYXBwaW5nIChmbik7CiAgLyogQVBQTEUgTE9DQUwgZW5kIG9wdGltaXphdGlvbiBwcmFnbWFzIDMxMjQyMzUvMzQyMDI0MiAqLwogIHJldHVybiBmbjsKfQoKLyogUmV0dXJucyB0aGUgX0RFQ0wgZm9yIGEgbGlicmFyeSBmdW5jdGlvbiB3aXRoIEMgbGlua2FnZS4KICAgV2UgYXNzdW1lIHRoYXQgc3VjaCBmdW5jdGlvbnMgbmV2ZXIgdGhyb3c7IGlmIHRoaXMgaXMgaW5jb3JyZWN0LAogICBjYWxsZXJzIHNob3VsZCB1bnNldCBUUkVFX05PVEhST1cuICAqLwoKdHJlZQpidWlsZF9saWJyYXJ5X2ZuICh0cmVlIG5hbWUsIHRyZWUgdHlwZSkKewogIHJldHVybiBidWlsZF9saWJyYXJ5X2ZuXzEgKG5hbWUsIEVSUk9SX01BUkssIHR5cGUpOwp9CgovKiBSZXR1cm5zIHRoZSBfREVDTCBmb3IgYSBsaWJyYXJ5IGZ1bmN0aW9uIHdpdGggQysrIGxpbmthZ2UuICAqLwoKc3RhdGljIHRyZWUKYnVpbGRfY3BfbGlicmFyeV9mbiAodHJlZSBuYW1lLCBlbnVtIHRyZWVfY29kZSBvcGVyYXRvcl9jb2RlLCB0cmVlIHR5cGUpCnsKICB0cmVlIGZuID0gYnVpbGRfbGlicmFyeV9mbl8xIChuYW1lLCBvcGVyYXRvcl9jb2RlLCB0eXBlKTsKICBUUkVFX05PVEhST1cgKGZuKSA9IFRZUEVfTk9USFJPV19QICh0eXBlKTsKICBERUNMX0NPTlRFWFQgKGZuKSA9IEZST0JfQ09OVEVYVCAoY3VycmVudF9uYW1lc3BhY2UpOwogIFNFVF9ERUNMX0xBTkdVQUdFIChmbiwgbGFuZ19jcGx1c3BsdXMpOwogIHJldHVybiBmbjsKfQoKLyogTGlrZSBidWlsZF9saWJyYXJ5X2ZuLCBidXQgdGFrZXMgYSBDIHN0cmluZyBpbnN0ZWFkIG9mIGFuCiAgIElERU5USUZJRVJfTk9ERS4gICovCgp0cmVlCmJ1aWxkX2xpYnJhcnlfZm5fcHRyIChjb25zdCBjaGFyKiBuYW1lLCB0cmVlIHR5cGUpCnsKICByZXR1cm4gYnVpbGRfbGlicmFyeV9mbiAoZ2V0X2lkZW50aWZpZXIgKG5hbWUpLCB0eXBlKTsKfQoKLyogTGlrZSBidWlsZF9jcF9saWJyYXJ5X2ZuLCBidXQgdGFrZXMgYSBDIHN0cmluZyBpbnN0ZWFkIG9mIGFuCiAgIElERU5USUZJRVJfTk9ERS4gICovCgp0cmVlCmJ1aWxkX2NwX2xpYnJhcnlfZm5fcHRyIChjb25zdCBjaGFyKiBuYW1lLCB0cmVlIHR5cGUpCnsKICByZXR1cm4gYnVpbGRfY3BfbGlicmFyeV9mbiAoZ2V0X2lkZW50aWZpZXIgKG5hbWUpLCBFUlJPUl9NQVJLLCB0eXBlKTsKfQoKLyogTGlrZSBidWlsZF9saWJyYXJ5X2ZuLCBidXQgYWxzbyBwdXNoZXMgdGhlIGZ1bmN0aW9uIHNvIHRoYXQgd2Ugd2lsbAogICBiZSBhYmxlIHRvIGZpbmQgaXQgdmlhIElERU5USUZJRVJfR0xPQkFMX1ZBTFVFLiAgKi8KCnRyZWUKcHVzaF9saWJyYXJ5X2ZuICh0cmVlIG5hbWUsIHRyZWUgdHlwZSkKewogIHRyZWUgZm4gPSBidWlsZF9saWJyYXJ5X2ZuIChuYW1lLCB0eXBlKTsKICBwdXNoZGVjbF90b3BfbGV2ZWwgKGZuKTsKICByZXR1cm4gZm47Cn0KCi8qIExpa2UgYnVpbGRfY3BfbGlicmFyeV9mbiwgYnV0IGFsc28gcHVzaGVzIHRoZSBmdW5jdGlvbiBzbyB0aGF0IGl0CiAgIHdpbGwgYmUgZm91bmQgYnkgbm9ybWFsIGxvb2t1cC4gICovCgpzdGF0aWMgdHJlZQpwdXNoX2NwX2xpYnJhcnlfZm4gKGVudW0gdHJlZV9jb2RlIG9wZXJhdG9yX2NvZGUsIHRyZWUgdHlwZSkKewogIHRyZWUgZm4gPSBidWlsZF9jcF9saWJyYXJ5X2ZuIChhbnNpX29wbmFtZSAob3BlcmF0b3JfY29kZSksCgkJCQkgb3BlcmF0b3JfY29kZSwKCQkJCSB0eXBlKTsKICBwdXNoZGVjbCAoZm4pOwogIHJldHVybiBmbjsKfQoKLyogTGlrZSBwdXNoX2xpYnJhcnlfZm4sIGJ1dCB0YWtlcyBhIFRSRUVfTElTVCBvZiBwYXJtIHR5cGVzIHJhdGhlciB0aGFuCiAgIGEgRlVOQ1RJT05fVFlQRS4gICovCgp0cmVlCnB1c2hfdm9pZF9saWJyYXJ5X2ZuICh0cmVlIG5hbWUsIHRyZWUgcGFybXR5cGVzKQp7CiAgdHJlZSB0eXBlID0gYnVpbGRfZnVuY3Rpb25fdHlwZSAodm9pZF90eXBlX25vZGUsIHBhcm10eXBlcyk7CiAgcmV0dXJuIHB1c2hfbGlicmFyeV9mbiAobmFtZSwgdHlwZSk7Cn0KCi8qIExpa2UgcHVzaF9saWJyYXJ5X2ZuLCBidXQgYWxzbyBub3RlIHRoYXQgdGhpcyBmdW5jdGlvbiB0aHJvd3MKICAgYW5kIGRvZXMgbm90IHJldHVybi4gIFVzZWQgZm9yIF9fdGhyb3dfZm9vIGFuZCB0aGUgbGlrZS4gICovCgp0cmVlCnB1c2hfdGhyb3dfbGlicmFyeV9mbiAodHJlZSBuYW1lLCB0cmVlIHR5cGUpCnsKICB0cmVlIGZuID0gcHVzaF9saWJyYXJ5X2ZuIChuYW1lLCB0eXBlKTsKICBUUkVFX1RISVNfVk9MQVRJTEUgKGZuKSA9IDE7CiAgVFJFRV9OT1RIUk9XIChmbikgPSAwOwogIHJldHVybiBmbjsKfQoMCi8qIFdoZW4gd2UgY2FsbCBmaW5pc2hfc3RydWN0IGZvciBhbiBhbm9ueW1vdXMgdW5pb24sIHdlIGNyZWF0ZQogICBkZWZhdWx0IGNvcHkgY29uc3RydWN0b3JzIGFuZCBzdWNoLiAgQnV0LCBhbiBhbm9ueW1vdXMgdW5pb24KICAgc2hvdWxkbid0IGhhdmUgc3VjaCB0aGluZ3M7IHRoaXMgZnVuY3Rpb24gdW5kb2VzIHRoZSBkYW1hZ2UgdG8gdGhlCiAgIGFub255bW91cyB1bmlvbiB0eXBlIFQuCgogICAoVGhlIHJlYXNvbiB0aGF0IHdlIGNyZWF0ZSB0aGUgc3ludGhlc2l6ZWQgbWV0aG9kcyBpcyB0aGF0IHdlIGRvbid0CiAgIGRpc3Rpbmd1aXNoIGB1bmlvbiB7IGludCBpOyB9JyBmcm9tIGB0eXBlZGVmIHVuaW9uIHsgaW50IGk7IH0gVScuCiAgIFRoZSBmaXJzdCBpcyBhbiBhbm9ueW1vdXMgdW5pb247IHRoZSBzZWNvbmQgaXMganVzdCBhbiBvcmRpbmFyeQogICB1bmlvbiB0eXBlLikgICovCgp2b2lkCmZpeHVwX2Fub255bW91c19hZ2dyICh0cmVlIHQpCnsKICB0cmVlICpxOwoKICAvKiBXaXBlIG91dCBtZW1vcnkgb2Ygc3ludGhlc2l6ZWQgbWV0aG9kcy4gICovCiAgVFlQRV9IQVNfQ09OU1RSVUNUT1IgKHQpID0gMDsKICBUWVBFX0hBU19ERUZBVUxUX0NPTlNUUlVDVE9SICh0KSA9IDA7CiAgVFlQRV9IQVNfSU5JVF9SRUYgKHQpID0gMDsKICBUWVBFX0hBU19DT05TVF9JTklUX1JFRiAodCkgPSAwOwogIFRZUEVfSEFTX0FTU0lHTl9SRUYgKHQpID0gMDsKICBUWVBFX0hBU19DT05TVF9BU1NJR05fUkVGICh0KSA9IDA7CgogIC8qIFNwbGljZSB0aGUgaW1wbGljaXRseSBnZW5lcmF0ZWQgZnVuY3Rpb25zIG91dCBvZiB0aGUgVFlQRV9NRVRIT0RTCiAgICAgbGlzdC4gICovCiAgcSA9ICZUWVBFX01FVEhPRFMgKHQpOwogIHdoaWxlICgqcSkKICAgIHsKICAgICAgaWYgKERFQ0xfQVJUSUZJQ0lBTCAoKnEpKQoJKnEgPSBUUkVFX0NIQUlOICgqcSk7CiAgICAgIGVsc2UKCXEgPSAmVFJFRV9DSEFJTiAoKnEpOwogICAgfQoKICAvKiBJU08gQysrIDkuNS4zLiAgQW5vbnltb3VzIHVuaW9ucyBtYXkgbm90IGhhdmUgZnVuY3Rpb24gbWVtYmVycy4gICovCiAgaWYgKFRZUEVfTUVUSE9EUyAodCkpCiAgICBlcnJvciAoIiVKYW4gYW5vbnltb3VzIHVuaW9uIGNhbm5vdCBoYXZlIGZ1bmN0aW9uIG1lbWJlcnMiLAoJICAgVFlQRV9NQUlOX0RFQ0wgKHQpKTsKCiAgLyogQW5vbnltb3VzIGFnZ3JlZ2F0ZXMgY2Fubm90IGhhdmUgZmllbGRzIHdpdGggY3RvcnMsIGR0b3JzIG9yIGNvbXBsZXgKICAgICBhc3NpZ25tZW50IG9wZXJhdG9ycyAoYmVjYXVzZSB0aGV5IGNhbm5vdCBoYXZlIHRoZXNlIG1ldGhvZHMgdGhlbXNlbHZlcykuCiAgICAgRm9yIGFub255bW91cyB1bmlvbnMgdGhpcyBpcyBhbHJlYWR5IGNoZWNrZWQgYmVjYXVzZSB0aGV5IGFyZSBub3QgYWxsb3dlZAogICAgIGluIGFueSB1bmlvbiwgb3RoZXJ3aXNlIHdlIGhhdmUgdG8gY2hlY2sgaXQuICAqLwogIGlmIChUUkVFX0NPREUgKHQpICE9IFVOSU9OX1RZUEUpCiAgICB7CiAgICAgIHRyZWUgZmllbGQsIHR5cGU7CgogICAgICBmb3IgKGZpZWxkID0gVFlQRV9GSUVMRFMgKHQpOyBmaWVsZDsgZmllbGQgPSBUUkVFX0NIQUlOIChmaWVsZCkpCglpZiAoVFJFRV9DT0RFIChmaWVsZCkgPT0gRklFTERfREVDTCkKCSAgewoJICAgIHR5cGUgPSBUUkVFX1RZUEUgKGZpZWxkKTsKCSAgICBpZiAoQ0xBU1NfVFlQRV9QICh0eXBlKSkKCSAgICAgIHsKCSAgICAgICAgaWYgKFRZUEVfTkVFRFNfQ09OU1RSVUNUSU5HICh0eXBlKSkKCQkgIGNwX2Vycm9yX2F0ICgibWVtYmVyICVxI0Qgd2l0aCBjb25zdHJ1Y3RvciBub3QgYWxsb3dlZCAiCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiaW4gYW5vbnltb3VzIGFnZ3JlZ2F0ZSIsCgkJCSAgICAgICBmaWVsZCk7CgkJaWYgKFRZUEVfSEFTX05PTlRSSVZJQUxfREVTVFJVQ1RPUiAodHlwZSkpCgkJICBjcF9lcnJvcl9hdCAoIm1lbWJlciAlcSNEIHdpdGggZGVzdHJ1Y3RvciBub3QgYWxsb3dlZCAiCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiaW4gYW5vbnltb3VzIGFnZ3JlZ2F0ZSIsCgkJCSAgICAgICBmaWVsZCk7CgkJaWYgKFRZUEVfSEFTX0NPTVBMRVhfQVNTSUdOX1JFRiAodHlwZSkpCgkJICBjcF9lcnJvcl9hdCAoIm1lbWJlciAlcSNEIHdpdGggY29weSBhc3NpZ25tZW50IG9wZXJhdG9yICIKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJub3QgYWxsb3dlZCBpbiBhbm9ueW1vdXMgYWdncmVnYXRlIiwKCQkJICAgICAgIGZpZWxkKTsKCSAgICAgIH0KCSAgfQogICAgfQp9CgovKiBNYWtlIHN1cmUgdGhhdCBhIGRlY2xhcmF0aW9uIHdpdGggbm8gZGVjbGFyYXRvciBpcyB3ZWxsLWZvcm1lZCwgaS5lLgogICBqdXN0IGRlY2xhcmVzIGEgdGFnZ2VkIHR5cGUgb3IgYW5vbnltb3VzIHVuaW9uLgoKICAgUmV0dXJucyB0aGUgdHlwZSBkZWNsYXJlZDsgb3IgTlVMTF9UUkVFIGlmIG5vbmUuICAqLwoKdHJlZQpjaGVja190YWdfZGVjbCAoY3BfZGVjbF9zcGVjaWZpZXJfc2VxICpkZWNsc3BlY3MpCnsKICBpbnQgc2F3X2ZyaWVuZCA9IGRlY2xzcGVjcy0+c3BlY3NbKGludClkc19mcmllbmRdICE9IDA7CiAgaW50IHNhd190eXBlZGVmID0gZGVjbHNwZWNzLT5zcGVjc1soaW50KWRzX3R5cGVkZWZdICE9IDA7CiAgLyogSWYgYSBjbGFzcywgc3RydWN0LCBvciBlbnVtIHR5cGUgaXMgZGVjbGFyZWQgYnkgdGhlIERFQ0xTUEVDUwogICAgIChpLmUsIGlmIGEgY2xhc3Mtc3BlY2lmaWVyLCBlbnVtLXNwZWNpZmllciwgb3Igbm9uLXR5cGVuYW1lCiAgICAgZWxhYm9yYXRlZC10eXBlLXNwZWNpZmllciBhcHBlYXJzIGluIHRoZSBERUNMU1BFQ1MpLAogICAgIERFQ0xBUkVEX1RZUEUgaXMgc2V0IHRvIHRoZSBjb3JyZXNwb25kaW5nIHR5cGUuICAqLwogIHRyZWUgZGVjbGFyZWRfdHlwZSA9IE5VTExfVFJFRTsKICBib29sIGVycm9yX3AgPSBmYWxzZTsKCiAgaWYgKGRlY2xzcGVjcy0+bXVsdGlwbGVfdHlwZXNfcCkKICAgIGVycm9yICgibXVsdGlwbGUgdHlwZXMgaW4gb25lIGRlY2xhcmF0aW9uIik7CiAgZWxzZSBpZiAoZGVjbHNwZWNzLT5yZWRlZmluZWRfYnVpbHRpbl90eXBlKQogICAgewogICAgICBpZiAoIWluX3N5c3RlbV9oZWFkZXIpCglwZWR3YXJuICgicmVkZWNsYXJhdGlvbiBvZiBDKysgYnVpbHQtaW4gdHlwZSAlcVQiLAoJCSBkZWNsc3BlY3MtPnJlZGVmaW5lZF9idWlsdGluX3R5cGUpOwogICAgICByZXR1cm4gTlVMTF9UUkVFOwogICAgfQoKICBpZiAoZGVjbHNwZWNzLT50eXBlCiAgICAgICYmIFRZUEVfUCAoZGVjbHNwZWNzLT50eXBlKQogICAgICAmJiAoKFRSRUVfQ09ERSAoZGVjbHNwZWNzLT50eXBlKSAhPSBUWVBFTkFNRV9UWVBFCgkgICAmJiBJU19BR0dSX1RZUEUgKGRlY2xzcGVjcy0+dHlwZSkpCgkgIHx8IFRSRUVfQ09ERSAoZGVjbHNwZWNzLT50eXBlKSA9PSBFTlVNRVJBTF9UWVBFKSkKICAgIGRlY2xhcmVkX3R5cGUgPSBkZWNsc3BlY3MtPnR5cGU7CiAgZWxzZSBpZiAoZGVjbHNwZWNzLT50eXBlID09IGVycm9yX21hcmtfbm9kZSkKICAgIGVycm9yX3AgPSB0cnVlOwogIGlmIChkZWNsYXJlZF90eXBlID09IE5VTExfVFJFRSAmJiAhIHNhd19mcmllbmQgJiYgIWVycm9yX3ApCiAgICAvKiBBUFBMRSBMT0NBTCBiZWdpbiA0MTY4MzkyICovCiAgICB7CiAgICAgIC8qIElmICctZm1zLWV4dGVuc2lvbnMnIGlzIG9uIGFuZCB0aGUgY29tcGlsZXIgZW5jb3VudGVycyBhbiBhbm9ueW1vdXMKCSBmaWVsZCBkZWNsYXJhdGlvbiBsaWtlCgoJICAgVDsKCgkgd2hlcmUgVCBkZW5vdGVzIGEgc3RydWN0LCBjbGFzcyBvciB1bmlvbiB0eXBlLCB3ZSB0cmFuc2Zvcm0gaXQgdG8KCSBhbiBhbm9ueW1vdXMgc3RydWN0L3VuaW9uIGxpa2UKCgkgICBzdHJ1Y3QvdW5pb24gewoJICAgICA8ZmllbGRzIGZyb20gVD4KCSAgIH07CgoJIHRoYXQgdGhlIHJlc3Qgb2YgQysrIGFscmVhZHkga25vd3MgaG93IHRvIGhhbmRsZS4gKi8KICAgICAgaWYgKGZsYWdfbXNfZXh0ZW5zaW9ucyAmJiBjdXJyZW50X2NsYXNzX3R5cGUgJiYgREVDTF9QIChkZWNsc3BlY3MtPnR5cGUpCgkgICYmIElTX0FHR1JfVFlQRV9DT0RFIChUUkVFX0NPREUgKFRSRUVfVFlQRSAoZGVjbHNwZWNzLT50eXBlKSkpKQoJewoJICB0cmVlIGZpZWxkcywgZmllbGQ7CgoJICBkZWNsYXJlZF90eXBlCgkgICAgPSBtYWtlX2FnZ3JfdHlwZSAoVFJFRV9DT0RFIChUUkVFX1RZUEUgKGRlY2xzcGVjcy0+dHlwZSkpKTsKCSAgU0VUX0lTX0FHR1JfVFlQRSAoZGVjbGFyZWRfdHlwZSwgMSk7CgkgIFRZUEVfQ09OVEVYVCAoZGVjbGFyZWRfdHlwZSkgPSBjdXJyZW50X2NsYXNzX3R5cGU7CgkgIHhyZWZfYmFzZXR5cGVzIChkZWNsYXJlZF90eXBlLCBOVUxMX1RSRUUpOwoJICBmaWVsZHMKCSAgICA9IG5yZXZlcnNlIChjb3B5X2xpc3QgKFRZUEVfRklFTERTIChUUkVFX1RZUEUgKGRlY2xzcGVjcy0+dHlwZSkpKSk7CgoJICBmb3IgKGZpZWxkID0gZmllbGRzOyBmaWVsZDsgZmllbGQgPSBUUkVFX0NIQUlOIChmaWVsZCkpCgkgICAgewoJICAgICAgaWYgKFRSRUVfQ09ERSAoZmllbGQpID09IFRZUEVfREVDTCkKCQlmaWVsZHMgPSBUUkVFX0NIQUlOIChmaWVsZCk7CgkgICAgICBlbHNlCgkJREVDTF9DT05URVhUIChmaWVsZCkgPSBOVUxMX1RSRUU7CgkgICAgfQoKCSAgZmluaXNoX2J1aWx0aW5fc3RydWN0IChkZWNsYXJlZF90eXBlLAoJCQkJIElERU5USUZJRVJfUE9JTlRFUiAobWFrZV9hbm9uX25hbWUgKCkpLAoJCQkJIGZpZWxkcywgVFJFRV9UWVBFIChkZWNsc3BlY3MtPnR5cGUpKTsKCgkgIGdvdG8gZmluaXNoX2Fub25fYWdncjsKCX0KCiAgICAgIHBlZHdhcm4gKCJkZWNsYXJhdGlvbiBkb2VzIG5vdCBkZWNsYXJlIGFueXRoaW5nIik7CiAgICB9CiAgICAvKiBBUFBMRSBMT0NBTCBlbmQgNDE2ODM5MiAqLwogIC8qIENoZWNrIGZvciBhbiBhbm9ueW1vdXMgdW5pb24uICAqLwogIGVsc2UgaWYgKGRlY2xhcmVkX3R5cGUgJiYgSVNfQUdHUl9UWVBFX0NPREUgKFRSRUVfQ09ERSAoZGVjbGFyZWRfdHlwZSkpCgkgICAmJiBUWVBFX0FOT05ZTU9VU19QIChkZWNsYXJlZF90eXBlKSkKICAgIHsKICAgICAgLyogNy8zIEluIGEgc2ltcGxlLWRlY2xhcmF0aW9uLCB0aGUgb3B0aW9uYWwgaW5pdC1kZWNsYXJhdG9yLWxpc3QKICAgICAgICAgY2FuIGJlIG9taXR0ZWQgb25seSB3aGVuIGRlY2xhcmluZyBhIGNsYXNzIChjbGF1c2UgOSkgb3IKICAgICAgICAgZW51bWVyYXRpb24gKDcuMiksIHRoYXQgaXMsIHdoZW4gdGhlIGRlY2wtc3BlY2lmaWVyLXNlcSBjb250YWlucwogICAgICAgICBlaXRoZXIgYSBjbGFzcy1zcGVjaWZpZXIsIGFuIGVsYWJvcmF0ZWQtdHlwZS1zcGVjaWZpZXIgd2l0aAogICAgICAgICBhIGNsYXNzLWtleSAoOS4xKSwgb3IgYW4gZW51bS1zcGVjaWZpZXIuICBJbiB0aGVzZSBjYXNlcyBhbmQKICAgICAgICAgd2hlbmV2ZXIgYSBjbGFzcy1zcGVjaWZpZXIgb3IgZW51bS1zcGVjaWZpZXIgaXMgcHJlc2VudCBpbiB0aGUKICAgICAgICAgZGVjbC1zcGVjaWZpZXItc2VxLCB0aGUgaWRlbnRpZmllcnMgaW4gdGhlc2Ugc3BlY2lmaWVycyBhcmUgYW1vbmcKICAgICAgICAgdGhlIG5hbWVzIGJlaW5nIGRlY2xhcmVkIGJ5IHRoZSBkZWNsYXJhdGlvbiAoYXMgY2xhc3MtbmFtZSwKICAgICAgICAgZW51bS1uYW1lcywgb3IgZW51bWVyYXRvcnMsIGRlcGVuZGluZyBvbiB0aGUgc3ludGF4KS4gIEluIHN1Y2gKICAgICAgICAgY2FzZXMsIGFuZCBleGNlcHQgZm9yIHRoZSBkZWNsYXJhdGlvbiBvZiBhbiB1bm5hbWVkIGJpdC1maWVsZCAoOS42KSwKICAgICAgICAgdGhlIGRlY2wtc3BlY2lmaWVyLXNlcSBzaGFsbCBpbnRyb2R1Y2Ugb25lIG9yIG1vcmUgbmFtZXMgaW50byB0aGUKICAgICAgICAgcHJvZ3JhbSwgb3Igc2hhbGwgcmVkZWNsYXJlIGEgbmFtZSBpbnRyb2R1Y2VkIGJ5IGEgcHJldmlvdXMKICAgICAgICAgZGVjbGFyYXRpb24uICBbRXhhbXBsZToKICAgICAgICAgICAgIGVudW0geyB9OyAgICAgICAgICAgIC8vIGlsbC1mb3JtZWQKICAgICAgICAgICAgIHR5cGVkZWYgY2xhc3MgeyB9OyAgIC8vIGlsbC1mb3JtZWQKICAgICAgICAgLS1lbmQgZXhhbXBsZV0gICovCiAgICAgIGlmIChzYXdfdHlwZWRlZikKICAgICAgICB7CiAgICAgICAgICBlcnJvciAoIm1pc3NpbmcgdHlwZS1uYW1lIGluIHR5cGVkZWYtZGVjbGFyYXRpb24iKTsKICAgICAgICAgIHJldHVybiBOVUxMX1RSRUU7CiAgICAgICAgfQogICAgICAvKiBBUFBMRSBMT0NBTCBiZWdpbiA0MTY4MzkyICovCgogICAgIGZpbmlzaF9hbm9uX2FnZ3I6CiAgICAgIC8qIEFQUExFIExPQ0FMIGVuZCA0MTY4MzkyICovCiAgICAgIC8qIEFub255bW91cyB1bmlvbnMgYXJlIG9iamVjdHMsIHNvIHRoZXkgY2FuIGhhdmUgc3BlY2lmaWVycy4gICovOwogICAgICBTRVRfQU5PTl9BR0dSX1RZUEVfUCAoZGVjbGFyZWRfdHlwZSk7CgogICAgICBpZiAoVFJFRV9DT0RFIChkZWNsYXJlZF90eXBlKSAhPSBVTklPTl9UWVBFICYmIHBlZGFudGljCgkgICYmICFpbl9zeXN0ZW1faGVhZGVyKQoJLyogQVBQTEUgTE9DQUwgYmVnaW4gNDE2ODM5MiAqLwoJewoJICBpZiAoZmxhZ19tc19leHRlbnNpb25zKQoJICAgIHdhcm5pbmcgKCJJU08gQysrIHByb2hpYml0cyBhbm9ueW1vdXMgc3RydWN0cyIpOwoJICBlbHNlCgkgICAgcGVkd2FybiAoIklTTyBDKysgcHJvaGliaXRzIGFub255bW91cyBzdHJ1Y3RzIik7Cgl9CgkvKiBBUFBMRSBMT0NBTCBlbmQgNDE2ODM5MiAqLwogICAgfQoKICBlbHNlCiAgICB7CiAgICAgIGlmIChkZWNsc3BlY3MtPnNwZWNzWyhpbnQpZHNfaW5saW5lXQoJICB8fCBkZWNsc3BlY3MtPnNwZWNzWyhpbnQpZHNfdmlydHVhbF0pCgllcnJvciAoIiVxcyBjYW4gb25seSBiZSBzcGVjaWZpZWQgZm9yIGZ1bmN0aW9ucyIsCgkgICAgICAgZGVjbHNwZWNzLT5zcGVjc1soaW50KWRzX2lubGluZV0KCSAgICAgICA/ICJpbmxpbmUiIDogInZpcnR1YWwiKTsKICAgICAgZWxzZSBpZiAoc2F3X2ZyaWVuZAoJICAgICAgICYmICghY3VycmVudF9jbGFzc190eXBlCgkJICAgfHwgY3VycmVudF9zY29wZSAoKSAhPSBjdXJyZW50X2NsYXNzX3R5cGUpKQoJZXJyb3IgKCIlPGZyaWVuZCU+IGNhbiBvbmx5IGJlIHNwZWNpZmllZCBpbnNpZGUgYSBjbGFzcyIpOwogICAgICBlbHNlIGlmIChkZWNsc3BlY3MtPnNwZWNzWyhpbnQpZHNfZXhwbGljaXRdKQoJZXJyb3IgKCIlPGV4cGxpY2l0JT4gY2FuIG9ubHkgYmUgc3BlY2lmaWVkIGZvciBjb25zdHJ1Y3RvcnMiKTsKICAgICAgZWxzZSBpZiAoZGVjbHNwZWNzLT5zdG9yYWdlX2NsYXNzKQoJZXJyb3IgKCJhIHN0b3JhZ2UgY2xhc3MgY2FuIG9ubHkgYmUgc3BlY2lmaWVkIGZvciBvYmplY3RzICIKCSAgICAgICAiYW5kIGZ1bmN0aW9ucyIpOwogICAgICBlbHNlIGlmIChkZWNsc3BlY3MtPnNwZWNzWyhpbnQpZHNfY29uc3RdCgkgICAgICAgfHwgZGVjbHNwZWNzLT5zcGVjc1soaW50KWRzX3ZvbGF0aWxlXQoJICAgICAgIHx8IGRlY2xzcGVjcy0+c3BlY3NbKGludClkc19yZXN0cmljdF0KCSAgICAgICB8fCBkZWNsc3BlY3MtPnNwZWNzWyhpbnQpZHNfdGhyZWFkXSkKCWVycm9yICgicXVhbGlmaWVycyBjYW4gb25seSBiZSBzcGVjaWZpZWQgZm9yIG9iamVjdHMgIgoJICAgICAgICJhbmQgZnVuY3Rpb25zIik7CiAgICB9CgogIHJldHVybiBkZWNsYXJlZF90eXBlOwp9CgovKiBDYWxsZWQgd2hlbiBhIGRlY2xhcmF0aW9uIGlzIHNlZW4gdGhhdCBjb250YWlucyBubyBuYW1lcyB0byBkZWNsYXJlLgogICBJZiBpdHMgdHlwZSBpcyBhIHJlZmVyZW5jZSB0byBhIHN0cnVjdHVyZSwgdW5pb24gb3IgZW51bSBpbmhlcml0ZWQKICAgZnJvbSBhIGNvbnRhaW5pbmcgc2NvcGUsIHNoYWRvdyB0aGF0IHRhZyBuYW1lIGZvciB0aGUgY3VycmVudCBzY29wZQogICB3aXRoIGEgZm9yd2FyZCByZWZlcmVuY2UuCiAgIElmIGl0cyB0eXBlIGRlZmluZXMgYSBuZXcgbmFtZWQgc3RydWN0dXJlIG9yIHVuaW9uCiAgIG9yIGRlZmluZXMgYW4gZW51bSwgaXQgaXMgdmFsaWQgYnV0IHdlIG5lZWQgbm90IGRvIGFueXRoaW5nIGhlcmUuCiAgIE90aGVyd2lzZSwgaXQgaXMgYW4gZXJyb3IuCgogICBDKys6IG1heSBoYXZlIHRvIGdyb2sgdGhlIGRlY2xzcGVjcyB0byBsZWFybiBhYm91dCBzdGF0aWMsCiAgIGNvbXBsYWluIGZvciBhbm9ueW1vdXMgdW5pb25zLgoKICAgUmV0dXJucyB0aGUgVFlQRSBkZWNsYXJlZCAtLSBvciBOVUxMX1RSRUUgaWYgbm9uZS4gICovCgp0cmVlCnNoYWRvd190YWcgKGNwX2RlY2xfc3BlY2lmaWVyX3NlcSAqZGVjbHNwZWNzKQp7CiAgdHJlZSB0ID0gY2hlY2tfdGFnX2RlY2wgKGRlY2xzcGVjcyk7CgogIGlmICghdCkKICAgIHJldHVybiBOVUxMX1RSRUU7CgogIGlmIChkZWNsc3BlY3MtPmF0dHJpYnV0ZXMpCiAgICB7CiAgICAgIGNwX3dhcm5pbmdfYXQgKCJhdHRyaWJ1dGUgaWdub3JlZCBpbiBkZWNsYXJhdGlvbiBvZiAlcSNUIiwgdCk7CiAgICAgIGNwX3dhcm5pbmdfYXQgKCJhdHRyaWJ1dGUgZm9yICVxI1QgbXVzdCBmb2xsb3cgdGhlICVxcyBrZXl3b3JkIiwKCQkgICAgIHQsCgkJICAgICBjbGFzc19rZXlfb3JfZW51bV9hc19zdHJpbmcgKHQpKTsKCiAgICB9CgogIG1heWJlX3Byb2Nlc3NfcGFydGlhbF9zcGVjaWFsaXphdGlvbiAodCk7CgogIC8qIFRoaXMgaXMgd2hlcmUgdGhlIHZhcmlhYmxlcyBpbiBhbiBhbm9ueW1vdXMgdW5pb24gYXJlCiAgICAgZGVjbGFyZWQuICBBbiBhbm9ueW1vdXMgdW5pb24gZGVjbGFyYXRpb24gbG9va3MgbGlrZToKICAgICB1bmlvbiB7IC4uLiB9IDsKICAgICBiZWNhdXNlIHRoZXJlIGlzIG5vIGRlY2xhcmF0b3IgYWZ0ZXIgdGhlIHVuaW9uLCB0aGUgcGFyc2VyCiAgICAgc2VuZHMgdGhhdCBkZWNsYXJhdGlvbiBoZXJlLiAgKi8KICBpZiAoQU5PTl9BR0dSX1RZUEVfUCAodCkpCiAgICB7CiAgICAgIGZpeHVwX2Fub255bW91c19hZ2dyICh0KTsKCiAgICAgIGlmIChUWVBFX0ZJRUxEUyAodCkpCgl7CgkgIHRyZWUgZGVjbCA9IGdyb2tkZWNsYXJhdG9yICgvKmRlY2xhcmF0b3I9Ki9OVUxMLAoJCQkJICAgICAgZGVjbHNwZWNzLCBOT1JNQUwsIDAsIE5VTEwpOwoJICBmaW5pc2hfYW5vbl91bmlvbiAoZGVjbCk7Cgl9CiAgICB9CgogIHJldHVybiB0Owp9CgwKLyogRGVjb2RlIGEgInR5cGVuYW1lIiwgc3VjaCBhcyAiaW50ICoqIiwgcmV0dXJuaW5nIGEgLi4uX1RZUEUgbm9kZS4gICovCgp0cmVlCmdyb2t0eXBlbmFtZSAoY3BfZGVjbF9zcGVjaWZpZXJfc2VxICp0eXBlX3NwZWNpZmllcnMsCgkgICAgICBjb25zdCBjcF9kZWNsYXJhdG9yICpkZWNsYXJhdG9yKQp7CiAgdHJlZSBhdHRyczsKICB0cmVlIHR5cGU7CiAgYXR0cnMgPSB0eXBlX3NwZWNpZmllcnMtPmF0dHJpYnV0ZXM7CiAgdHlwZV9zcGVjaWZpZXJzLT5hdHRyaWJ1dGVzID0gTlVMTF9UUkVFOwogIHR5cGUgPSBncm9rZGVjbGFyYXRvciAoZGVjbGFyYXRvciwgdHlwZV9zcGVjaWZpZXJzLCBUWVBFTkFNRSwgMCwgJmF0dHJzKTsKICBpZiAoYXR0cnMpCiAgICBjcGx1c19kZWNsX2F0dHJpYnV0ZXMgKCZ0eXBlLCBhdHRycywgMCk7CiAgcmV0dXJuIHR5cGU7Cn0KCi8qIERlY29kZSBhIGRlY2xhcmF0b3IgaW4gYW4gb3JkaW5hcnkgZGVjbGFyYXRpb24gb3IgZGF0YSBkZWZpbml0aW9uLgogICBUaGlzIGlzIGNhbGxlZCBhcyBzb29uIGFzIHRoZSB0eXBlIGluZm9ybWF0aW9uIGFuZCB2YXJpYWJsZSBuYW1lCiAgIGhhdmUgYmVlbiBwYXJzZWQsIGJlZm9yZSBwYXJzaW5nIHRoZSBpbml0aWFsaXplciBpZiBhbnkuCiAgIEhlcmUgd2UgY3JlYXRlIHRoZSAuLi5fREVDTCBub2RlLCBmaWxsIGluIGl0cyB0eXBlLAogICBhbmQgcHV0IGl0IG9uIHRoZSBsaXN0IG9mIGRlY2xzIGZvciB0aGUgY3VycmVudCBjb250ZXh0LgogICBUaGUgLi4uX0RFQ0wgbm9kZSBpcyByZXR1cm5lZCBhcyB0aGUgdmFsdWUuCgogICBFeGNlcHRpb246IGZvciBhcnJheXMgd2hlcmUgdGhlIGxlbmd0aCBpcyBub3Qgc3BlY2lmaWVkLAogICB0aGUgdHlwZSBpcyBsZWZ0IG51bGwsIHRvIGJlIGZpbGxlZCBpbiBieSBgY3BfZmluaXNoX2RlY2wnLgoKICAgRnVuY3Rpb24gZGVmaW5pdGlvbnMgZG8gbm90IGNvbWUgaGVyZTsgdGhleSBnbyB0byBzdGFydF9mdW5jdGlvbgogICBpbnN0ZWFkLiAgSG93ZXZlciwgZXh0ZXJuYWwgYW5kIGZvcndhcmQgZGVjbGFyYXRpb25zIG9mIGZ1bmN0aW9ucwogICBkbyBnbyB0aHJvdWdoIGhlcmUuICBTdHJ1Y3R1cmUgZmllbGQgZGVjbGFyYXRpb25zIGFyZSBkb25lIGJ5CiAgIGdyb2tmaWVsZCBhbmQgbm90IHRocm91Z2ggaGVyZS4gICovCgp0cmVlCnN0YXJ0X2RlY2wgKGNvbnN0IGNwX2RlY2xhcmF0b3IgKmRlY2xhcmF0b3IsCgkgICAgY3BfZGVjbF9zcGVjaWZpZXJfc2VxICpkZWNsc3BlY3MsCiAgICAgICAgICAgIGludCBpbml0aWFsaXplZCwKICAgICAgICAgICAgdHJlZSBhdHRyaWJ1dGVzLAogICAgICAgICAgICB0cmVlIHByZWZpeF9hdHRyaWJ1dGVzLCAKCSAgICB0cmVlICpwdXNoZWRfc2NvcGVfcCkKewogIHRyZWUgZGVjbDsKICB0cmVlIHR5cGUsIHRlbTsKICB0cmVlIGNvbnRleHQ7CiAgLyogQVBQTEUgTE9DQUwgInVuYXZhaWxhYmxlIiBhdHRyaWJ1dGUgKHJhZGFyIDI4MDk2OTcpICovCiAgdHJlZSBhOwoKICAqcHVzaGVkX3Njb3BlX3AgPSBOVUxMX1RSRUU7CiAKICAvKiBUaGlzIHNob3VsZCBvbmx5IGJlIGRvbmUgb25jZSBvbiB0aGUgdG9wIG1vc3QgZGVjbC4gICovCiAgaWYgKGhhdmVfZXh0ZXJuX3NwZWMpCiAgICB7CiAgICAgIGRlY2xzcGVjcy0+c3RvcmFnZV9jbGFzcyA9IHNjX2V4dGVybjsKICAgICAgaGF2ZV9leHRlcm5fc3BlYyA9IGZhbHNlOwogICAgfQoKICAvKiBBUFBMRSBMT0NBTCBiZWdpbiAidW5hdmFpbGFibGUiIGF0dHJpYnV0ZSAocmFkYXIgMjgwOTY5NykgKi8KICAvKiBBbiBvYmplY3QgZGVjbGFyZWQgYXMgX19hdHRyaWJ1dGVfXygodW5hdmFpbGFibGUpKSBzdXBwcmVzc2VzCiAgICAgYW55IHJlcG9ydHMgb2YgYmVpbmcgZGVjbGFyZWQgd2l0aCB1bmF2YWlsYWJsZSBvciBkZXByZWNhdGVkCiAgICAgaXRlbXMuICBBbiBvYmplY3QgZGVjbGFyZWQgYXMgX19hdHRyaWJ1dGVfXygoZGVwcmVjYXRlZCkpCiAgICAgc3VwcHJlc3NlcyB3YXJuaW5ncyBvZiB1c2VzIG9mIG90aGVyIGRlcHJlY2F0ZWQgaXRlbXMuICAqLwojaWZkZWYgQV9MRVNTX0lORUZGSUNFTlRfV0FZIC8qIHdoaWNoIEkgcmVhbGx5IGRvbid0IHdhbnQgdG8gZG8hICAqLwogIGlmIChsb29rdXBfYXR0cmlidXRlICgiZGVwcmVjYXRlZCIsIGF0dHJpYnV0ZXMpKQogICAgZGVwcmVjYXRlZF9zdGF0ZSA9IERFUFJFQ0FURURfU1VQUFJFU1M7CiAgZWxzZSBpZiAobG9va3VwX2F0dHJpYnV0ZSAoInVuYXZhaWxhYmxlIiwgYXR0cmlidXRlcykpCiAgICBkZXByZWNhdGVkX3N0YXRlID0gREVQUkVDQVRFRF9VTkFWQUlMQUJMRV9TVVBQUkVTUzsKI2Vsc2UgLyogYSBtb3JlIGVmZmljaWVudCB3YXkgZG9pbmcgd2hhdCBsb29rdXBfYXR0cmlidXRlIHdvdWxkIGRvICovCiAgZm9yIChhID0gYXR0cmlidXRlczsgYTsgYSA9IFRSRUVfQ0hBSU4gKGEpKQogICAgewogICAgICB0cmVlIG5hbWUgPSBUUkVFX1BVUlBPU0UgKGEpOwogICAgICBpZiAoVFJFRV9DT0RFIChuYW1lKSA9PSBJREVOVElGSUVSX05PREUpCiAgICAgICAgaWYgKGlzX2F0dHJpYnV0ZV9wICgiZGVwcmVjYXRlZCIsIG5hbWUpKQoJICB7CgkgICAgZGVwcmVjYXRlZF9zdGF0ZSA9IERFUFJFQ0FURURfU1VQUFJFU1M7CgkgICAgYnJlYWs7CgkgIH0KICAgICAgICBpZiAoaXNfYXR0cmlidXRlX3AgKCJ1bmF2YWlsYWJsZSIsIG5hbWUpKQoJICB7CgkgICAgZGVwcmVjYXRlZF9zdGF0ZSA9IERFUFJFQ0FURURfVU5BVkFJTEFCTEVfU1VQUFJFU1M7CgkgICAgYnJlYWs7CgkgIH0KICAgIH0KI2VuZGlmCiAgLyogQVBQTEUgTE9DQUwgZW5kICJ1bmF2YWlsYWJsZSIgYXR0cmlidXRlIChyYWRhciAyODA5Njk3KSAqLwoKICBhdHRyaWJ1dGVzID0gY2hhaW5vbiAoYXR0cmlidXRlcywgcHJlZml4X2F0dHJpYnV0ZXMpOwoKICBkZWNsID0gZ3Jva2RlY2xhcmF0b3IgKGRlY2xhcmF0b3IsIGRlY2xzcGVjcywgTk9STUFMLCBpbml0aWFsaXplZCwKCQkJICZhdHRyaWJ1dGVzKTsKCiAgZGVwcmVjYXRlZF9zdGF0ZSA9IERFUFJFQ0FURURfTk9STUFMOwoKICBpZiAoZGVjbCA9PSBOVUxMX1RSRUUgfHwgVFJFRV9DT0RFIChkZWNsKSA9PSBWT0lEX1RZUEUpCiAgICByZXR1cm4gZXJyb3JfbWFya19ub2RlOwoKICB0eXBlID0gVFJFRV9UWVBFIChkZWNsKTsKCiAgaWYgKHR5cGUgPT0gZXJyb3JfbWFya19ub2RlKQogICAgcmV0dXJuIGVycm9yX21hcmtfbm9kZTsKCiAgY29udGV4dCA9IERFQ0xfQ09OVEVYVCAoZGVjbCk7CgogIGlmIChjb250ZXh0KQogICAgewogICAgICAqcHVzaGVkX3Njb3BlX3AgPSBwdXNoX3Njb3BlIChjb250ZXh0KTsKICAKICAgICAgLyogV2UgYXJlIG9ubHkgaW50ZXJlc3RlZCBpbiBjbGFzcyBjb250ZXh0cywgbGF0ZXIuICAqLwogICAgICBpZiAoVFJFRV9DT0RFIChjb250ZXh0KSA9PSBOQU1FU1BBQ0VfREVDTCkKCWNvbnRleHQgPSBOVUxMX1RSRUU7CiAgICB9CgogIGlmIChpbml0aWFsaXplZCkKICAgIC8qIElzIGl0IHZhbGlkIGZvciB0aGlzIGRlY2wgdG8gaGF2ZSBhbiBpbml0aWFsaXplciBhdCBhbGw/CiAgICAgICBJZiBub3QsIHNldCBJTklUSUFMSVpFRCB0byB6ZXJvLCB3aGljaCB3aWxsIGluZGlyZWN0bHkKICAgICAgIHRlbGwgYGNwX2ZpbmlzaF9kZWNsJyB0byBpZ25vcmUgdGhlIGluaXRpYWxpemVyIG9uY2UgaXQgaXMgcGFyc2VkLiAgKi8KICAgIHN3aXRjaCAoVFJFRV9DT0RFIChkZWNsKSkKICAgICAgewogICAgICBjYXNlIFRZUEVfREVDTDoKCWVycm9yICgidHlwZWRlZiAlcUQgaXMgaW5pdGlhbGl6ZWQgKHVzZSBfX3R5cGVvZl9fIGluc3RlYWQpIiwgZGVjbCk7Cglpbml0aWFsaXplZCA9IDA7CglicmVhazsKCiAgICAgIGNhc2UgRlVOQ1RJT05fREVDTDoKCWVycm9yICgiZnVuY3Rpb24gJXEjRCBpcyBpbml0aWFsaXplZCBsaWtlIGEgdmFyaWFibGUiLCBkZWNsKTsKCWluaXRpYWxpemVkID0gMDsKCWJyZWFrOwoKICAgICAgZGVmYXVsdDoKCWJyZWFrOwogICAgICB9CgogIGlmIChpbml0aWFsaXplZCkKICAgIHsKICAgICAgaWYgKCEgdG9wbGV2ZWxfYmluZGluZ3NfcCAoKQoJICAmJiBERUNMX0VYVEVSTkFMIChkZWNsKSkKCXdhcm5pbmcgKCJkZWNsYXJhdGlvbiBvZiAlcSNEIGhhcyAlPGV4dGVybiU+IGFuZCBpcyBpbml0aWFsaXplZCIsCiAgICAgICAgICAgICAgICAgZGVjbCk7CiAgICAgIERFQ0xfRVhURVJOQUwgKGRlY2wpID0gMDsKICAgICAgaWYgKHRvcGxldmVsX2JpbmRpbmdzX3AgKCkpCglUUkVFX1NUQVRJQyAoZGVjbCkgPSAxOwoKICAgICAgLyogVGVsbCBgcHVzaGRlY2wnIHRoaXMgaXMgYW4gaW5pdGlhbGl6ZWQgZGVjbAoJIGV2ZW4gdGhvdWdoIHdlIGRvbid0IHlldCBoYXZlIHRoZSBpbml0aWFsaXplciBleHByZXNzaW9uLgoJIEFsc28gdGVsbCBgY3BfZmluaXNoX2RlY2wnIGl0IG1heSBzdG9yZSB0aGUgcmVhbCBpbml0aWFsaXplci4gICovCiAgICAgIERFQ0xfSU5JVElBTCAoZGVjbCkgPSBlcnJvcl9tYXJrX25vZGU7CiAgICB9CgogIC8qIFNldCBhdHRyaWJ1dGVzIGhlcmUgc28gaWYgZHVwbGljYXRlIGRlY2wsIHdpbGwgaGF2ZSBwcm9wZXIgYXR0cmlidXRlcy4gICovCiAgY3BsdXNfZGVjbF9hdHRyaWJ1dGVzICgmZGVjbCwgYXR0cmlidXRlcywgMCk7CiAgLyogQVBQTEUgTE9DQUwgYmVnaW4gcmFkYXIgNDU5MjUwMyAqLwogIGlmIChjX2RpYWxlY3Rfb2JqYyAoKSkKICAgIG9iamNfY2hlY2tvbl93ZWFrX2F0dHJpYnV0ZSAoZGVjbCk7CiAgLyogQVBQTEUgTE9DQUwgZW5kIHJhZGFyIDQ1OTI1MDMgKi8KCiAvKiBBUFBMRSBMT0NBTCBiZWdpbiBtYWlubGluZSAyMDA1LTEwLTEyICovCiAgLyogRGxsaW1wb3J0ZWQgc3ltYm9scyBjYW5ub3QgYmUgZGVmaW5lZC4gIFN0YXRpYyBkYXRhIG1lbWJlcnMgKHdoaWNoCiAgICAgY2FuIGJlIGluaXRpYWxpemVkIGluLWNsYXNzIGFuZCBkbGxpbXBvcnRlZCkgZ28gdGhyb3VnaCBncm9rZmllbGQsCiAgICAgbm90IGhlcmUsIHNvIHdlIGRvbid0IG5lZWQgdG8gZXhjbHVkZSB0aG9zZSBkZWNscyB3aGVuIGNoZWNraW5nIGZvcgogICAgIGEgZGVmaW5pdGlvbi4gICovCiAgaWYgKGluaXRpYWxpemVkICYmIERFQ0xfRExMSU1QT1JUX1AgKGRlY2wpKQogICAgewogICAgICBlcnJvciAoImRlZmluaXRpb24gb2YgJXEjRCBpcyBtYXJrZWQgJTxkbGxpbXBvcnQlPiIsIGRlY2wpOwogICAgICBERUNMX0RMTElNUE9SVF9QIChkZWNsKSA9IDA7CiAgICB9CiAvKiBBUFBMRSBMT0NBTCBlbmQgbWFpbmxpbmUgMjAwNS0xMC0xMiAqLwoKICAvKiBJZiAjcHJhZ21hIHdlYWsgd2FzIHVzZWQsIG1hcmsgdGhlIGRlY2wgd2VhayBub3cuICAqLwogIG1heWJlX2FwcGx5X3ByYWdtYV93ZWFrIChkZWNsKTsKCiAgaWYgKFRSRUVfQ09ERSAoZGVjbCkgPT0gRlVOQ1RJT05fREVDTAogICAgICAmJiBERUNMX0RFQ0xBUkVEX0lOTElORV9QIChkZWNsKQogICAgICAmJiBERUNMX1VOSU5MSU5BQkxFIChkZWNsKQogICAgICAmJiBsb29rdXBfYXR0cmlidXRlICgibm9pbmxpbmUiLCBERUNMX0FUVFJJQlVURVMgKGRlY2wpKSkKICAgIHdhcm5pbmcgKCIlSmlubGluZSBmdW5jdGlvbiAlcUQgZ2l2ZW4gYXR0cmlidXRlIG5vaW5saW5lIiwgZGVjbCwgZGVjbCk7CgogIGlmIChjb250ZXh0ICYmIENPTVBMRVRFX1RZUEVfUCAoY29tcGxldGVfdHlwZSAoY29udGV4dCkpKQogICAgewogICAgICBpZiAoVFJFRV9DT0RFIChkZWNsKSA9PSBWQVJfREVDTCkKCXsKCSAgdHJlZSBmaWVsZCA9IGxvb2t1cF9maWVsZCAoY29udGV4dCwgREVDTF9OQU1FIChkZWNsKSwgMCwgZmFsc2UpOwoJICBpZiAoZmllbGQgPT0gTlVMTF9UUkVFIHx8IFRSRUVfQ09ERSAoZmllbGQpICE9IFZBUl9ERUNMKQoJICAgIGVycm9yICgiJXEjRCBpcyBub3QgYSBzdGF0aWMgbWVtYmVyIG9mICVxI1QiLCBkZWNsLCBjb250ZXh0KTsKCSAgZWxzZQoJICAgIHsKCSAgICAgIGlmIChERUNMX0NPTlRFWFQgKGZpZWxkKSAhPSBjb250ZXh0KQoJCXsKCQkgIGlmICghc2FtZV90eXBlX3AgKERFQ0xfQ09OVEVYVCAoZmllbGQpLCBjb250ZXh0KSkKCQkgICAgcGVkd2FybiAoIklTTyBDKysgZG9lcyBub3QgcGVybWl0ICU8JVQ6OiVEJT4gIgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ0byBiZSBkZWZpbmVkIGFzICU8JVQ6OiVEJT4iLAoJCQkgICAgIERFQ0xfQ09OVEVYVCAoZmllbGQpLCBERUNMX05BTUUgKGRlY2wpLAoJCQkgICAgIGNvbnRleHQsIERFQ0xfTkFNRSAoZGVjbCkpOwoJCSAgREVDTF9DT05URVhUIChkZWNsKSA9IERFQ0xfQ09OVEVYVCAoZmllbGQpOwoJCX0KCSAgICAgIGlmIChwcm9jZXNzaW5nX3NwZWNpYWxpemF0aW9uCgkJICAmJiB0ZW1wbGF0ZV9jbGFzc19kZXB0aCAoY29udGV4dCkgPT0gMAoJCSAgJiYgQ0xBU1NUWVBFX1RFTVBMQVRFX1NQRUNJQUxJWkFUSU9OIChjb250ZXh0KSkKCQllcnJvciAoInRlbXBsYXRlIGhlYWRlciBub3QgYWxsb3dlZCBpbiBtZW1iZXIgZGVmaW5pdGlvbiAiCgkJICAgICAgICJvZiBleHBsaWNpdGx5IHNwZWNpYWxpemVkIGNsYXNzIik7CgkgICAgICAvKiBTdGF0aWMgZGF0YSBtZW1iZXIgYXJlIHRyaWNreTsgYW4gaW4tY2xhc3MgaW5pdGlhbGl6YXRpb24KCQkgc3RpbGwgZG9lc24ndCBwcm92aWRlIGEgZGVmaW5pdGlvbiwgc28gdGhlIGluLWNsYXNzCgkJIGRlY2xhcmF0aW9uIHdpbGwgaGF2ZSBERUNMX0VYVEVSTkFMIHNldCwgYnV0IHdpbGwgaGF2ZSBhbgoJCSBpbml0aWFsaXphdGlvbi4gIFRodXMsIGR1cGxpY2F0ZV9kZWNscyB3b24ndCB3YXJuCgkJIGFib3V0IHRoaXMgc2l0dWF0aW9uLCBhbmQgc28gd2UgY2hlY2sgaGVyZS4gICovCgkgICAgICBpZiAoREVDTF9JTklUSUFMIChkZWNsKSAmJiBERUNMX0lOSVRJQUwgKGZpZWxkKSkKCQllcnJvciAoImR1cGxpY2F0ZSBpbml0aWFsaXphdGlvbiBvZiAlcUQiLCBkZWNsKTsKCSAgICAgIGlmIChkdXBsaWNhdGVfZGVjbHMgKGRlY2wsIGZpZWxkKSkKCQlkZWNsID0gZmllbGQ7CgkgICAgfQoJfQogICAgICBlbHNlCgl7CgkgIHRyZWUgZmllbGQgPSBjaGVja19jbGFzc2ZuIChjb250ZXh0LCBkZWNsLAoJCQkJICAgICAgKHByb2Nlc3NpbmdfdGVtcGxhdGVfZGVjbAoJCQkJICAgICAgID4gdGVtcGxhdGVfY2xhc3NfZGVwdGggKGNvbnRleHQpKQoJCQkJICAgICAgPyBjdXJyZW50X3RlbXBsYXRlX3Bhcm1zCgkJCQkgICAgICA6IE5VTExfVFJFRSk7CgkgIGlmIChmaWVsZCAmJiBkdXBsaWNhdGVfZGVjbHMgKGRlY2wsIGZpZWxkKSkKCSAgICBkZWNsID0gZmllbGQ7Cgl9CgogICAgICAvKiBjcF9maW5pc2hfZGVjbCBzZXRzIERFQ0xfRVhURVJOQUwgaWYgREVDTF9JTl9BR0dSX1AgaXMgc2V0LiAgKi8KICAgICAgREVDTF9JTl9BR0dSX1AgKGRlY2wpID0gMDsKICAgICAgaWYgKChERUNMX0xBTkdfU1BFQ0lGSUMgKGRlY2wpICYmIERFQ0xfVVNFX1RFTVBMQVRFIChkZWNsKSkKCSAgfHwgQ0xBU1NUWVBFX1RFTVBMQVRFX0lOU1RBTlRJQVRJT04gKGNvbnRleHQpKQoJewoJICAvKiBEbyBub3QgbWFyayBERUNMIGFzIGFuIGV4cGxpY2l0IHNwZWNpYWxpemF0aW9uIGlmIGl0IHdhcwoJICAgICBub3QgYWxyZWFkeSBtYXJrZWQgYXMgYW4gaW5zdGFudGlhdGlvbjsgYSBkZWNsYXJhdGlvbgoJICAgICBzaG91bGQgbmV2ZXIgYmUgbWFya2VkIGFzIGEgc3BlY2lhbGl6YXRpb24gdW5sZXNzIHdlIGtub3cKCSAgICAgd2hhdCB0ZW1wbGF0ZSBpcyBiZWluZyBzcGVjaWFsaXplZC4gICovIAoJICBpZiAoREVDTF9MQU5HX1NQRUNJRklDIChkZWNsKSAmJiBERUNMX1VTRV9URU1QTEFURSAoZGVjbCkpCgkgICAgU0VUX0RFQ0xfVEVNUExBVEVfU1BFQ0lBTElaQVRJT04gKGRlY2wpOwoJICAvKiBbdGVtcC5leHBsLnNwZWNdIEFuIGV4cGxpY2l0IHNwZWNpYWxpemF0aW9uIG9mIGEgc3RhdGljIGRhdGEKCSAgICAgbWVtYmVyIG9mIGEgdGVtcGxhdGUgaXMgYSBkZWZpbml0aW9uIGlmIHRoZSBkZWNsYXJhdGlvbgoJICAgICBpbmNsdWRlcyBhbiBpbml0aWFsaXplcjsgb3RoZXJ3aXNlLCBpdCBpcyBhIGRlY2xhcmF0aW9uLgoKCSAgICAgV2UgY2hlY2sgZm9yIHByb2Nlc3Npbmdfc3BlY2lhbGl6YXRpb24gc28gdGhpcyBvbmx5IGFwcGxpZXMKCSAgICAgdG8gdGhlIG5ldyBzcGVjaWFsaXphdGlvbiBzeW50YXguICAqLwoJICBpZiAoREVDTF9JTklUSUFMIChkZWNsKSA9PSBOVUxMX1RSRUUgJiYgcHJvY2Vzc2luZ19zcGVjaWFsaXphdGlvbikKCSAgICBERUNMX0VYVEVSTkFMIChkZWNsKSA9IDE7Cgl9CgogICAgICBpZiAoREVDTF9FWFRFUk5BTCAoZGVjbCkgJiYgISBERUNMX1RFTVBMQVRFX1NQRUNJQUxJWkFUSU9OIChkZWNsKSkKCXBlZHdhcm4gKCJkZWNsYXJhdGlvbiBvZiAlcSNEIG91dHNpZGUgb2YgY2xhc3MgaXMgbm90IGRlZmluaXRpb24iLAogICAgICAgICAgICAgICAgIGRlY2wpOwogICAgfQoKICAvKiBFbnRlciB0aGlzIGRlY2xhcmF0aW9uIGludG8gdGhlIHN5bWJvbCB0YWJsZS4gICovCiAgdGVtID0gbWF5YmVfcHVzaF9kZWNsIChkZWNsKTsKCiAgaWYgKHByb2Nlc3NpbmdfdGVtcGxhdGVfZGVjbCkKICAgIHRlbSA9IHB1c2hfdGVtcGxhdGVfZGVjbCAodGVtKTsKICBpZiAodGVtID09IGVycm9yX21hcmtfbm9kZSkKICAgIHJldHVybiBlcnJvcl9tYXJrX25vZGU7CgojaWYgISBkZWZpbmVkIChBU01fT1VUUFVUX0JTUykgJiYgISBkZWZpbmVkIChBU01fT1VUUFVUX0FMSUdORURfQlNTKQogIC8qIFRlbGwgdGhlIGJhY2stZW5kIHRvIHVzZSBvciBub3QgdXNlIC5jb21tb24gYXMgYXBwcm9wcmlhdGUuICBJZiB3ZSBzYXkKICAgICAtZmNvbnNlcnZlLXNwYWNlLCB3ZSB3YW50IHRoaXMgdG8gc2F2ZSAuZGF0YSBzcGFjZSwgYXQgdGhlIGV4cGVuc2Ugb2YKICAgICB3cm9uZyBzZW1hbnRpY3MuICBJZiB3ZSBzYXkgLWZuby1jb25zZXJ2ZS1zcGFjZSwgd2Ugd2FudCB0aGlzIHRvCiAgICAgcHJvZHVjZSBlcnJvcnMgYWJvdXQgcmVkZWZzOyB0byBkbyB0aGlzIHdlIGZvcmNlIHZhcmlhYmxlcyBpbnRvIHRoZQogICAgIGRhdGEgc2VnbWVudC4gICovCiAgREVDTF9DT01NT04gKHRlbSkgPSAoKFRSRUVfQ09ERSAodGVtKSAhPSBWQVJfREVDTAoJCQl8fCAhREVDTF9USFJFQURfTE9DQUwgKHRlbSkpCgkJICAgICAgICYmIChmbGFnX2NvbnNlcnZlX3NwYWNlIHx8ICEgVFJFRV9QVUJMSUMgKHRlbSkpKTsKI2VuZGlmCgogIGlmICghIHByb2Nlc3NpbmdfdGVtcGxhdGVfZGVjbCkKICAgIHN0YXJ0X2RlY2xfMSAodGVtKTsKCiAgcmV0dXJuIHRlbTsKfQoKdm9pZApzdGFydF9kZWNsXzEgKHRyZWUgZGVjbCkKewogIHRyZWUgdHlwZSA9IFRSRUVfVFlQRSAoZGVjbCk7CiAgaW50IGluaXRpYWxpemVkID0gKERFQ0xfSU5JVElBTCAoZGVjbCkgIT0gTlVMTF9UUkVFKTsKCiAgaWYgKHR5cGUgPT0gZXJyb3JfbWFya19ub2RlKQogICAgcmV0dXJuOwoKICBpZiAoaW5pdGlhbGl6ZWQpCiAgICAvKiBJcyBpdCB2YWxpZCBmb3IgdGhpcyBkZWNsIHRvIGhhdmUgYW4gaW5pdGlhbGl6ZXIgYXQgYWxsPwogICAgICAgSWYgbm90LCBzZXQgSU5JVElBTElaRUQgdG8gemVybywgd2hpY2ggd2lsbCBpbmRpcmVjdGx5CiAgICAgICB0ZWxsIGBjcF9maW5pc2hfZGVjbCcgdG8gaWdub3JlIHRoZSBpbml0aWFsaXplciBvbmNlIGl0IGlzIHBhcnNlZC4gICovCiAgICB7CiAgICAgIC8qIERvbid0IGFsbG93IGluaXRpYWxpemF0aW9ucyBmb3IgaW5jb21wbGV0ZSB0eXBlcyBleGNlcHQgZm9yCgkgYXJyYXlzIHdoaWNoIG1pZ2h0IGJlIGNvbXBsZXRlZCBieSB0aGUgaW5pdGlhbGl6YXRpb24uICAqLwogICAgICBpZiAoQ09NUExFVEVfVFlQRV9QIChjb21wbGV0ZV90eXBlICh0eXBlKSkpCgk7CQkJLyogQSBjb21wbGV0ZSB0eXBlIGlzIG9rLiAgKi8KICAgICAgZWxzZSBpZiAoVFJFRV9DT0RFICh0eXBlKSAhPSBBUlJBWV9UWVBFKQoJewoJICBlcnJvciAoInZhcmlhYmxlICVxI0QgaGFzIGluaXRpYWxpemVyIGJ1dCBpbmNvbXBsZXRlIHR5cGUiLCBkZWNsKTsKCSAgaW5pdGlhbGl6ZWQgPSAwOwoJICB0eXBlID0gVFJFRV9UWVBFIChkZWNsKSA9IGVycm9yX21hcmtfbm9kZTsKCX0KICAgICAgZWxzZSBpZiAoIUNPTVBMRVRFX1RZUEVfUCAoY29tcGxldGVfdHlwZSAoVFJFRV9UWVBFICh0eXBlKSkpKQoJewoJICBpZiAoREVDTF9MQU5HX1NQRUNJRklDIChkZWNsKSAmJiBERUNMX1RFTVBMQVRFX0lORk8gKGRlY2wpKQoJICAgIGVycm9yICgiZWxlbWVudHMgb2YgYXJyYXkgJXEjRCBoYXZlIGluY29tcGxldGUgdHlwZSIsIGRlY2wpOwoJICAvKiBlbHNlIHdlIGFscmVhZHkgZ2F2ZSBhbiBlcnJvciBpbiBzdGFydF9kZWNsLiAgKi8KCSAgaW5pdGlhbGl6ZWQgPSAwOwoJfQogICAgfQoKICBpZiAoIWluaXRpYWxpemVkCiAgICAgICYmIFRSRUVfQ09ERSAoZGVjbCkgIT0gVFlQRV9ERUNMCiAgICAgICYmIFRSRUVfQ09ERSAoZGVjbCkgIT0gVEVNUExBVEVfREVDTAogICAgICAmJiB0eXBlICE9IGVycm9yX21hcmtfbm9kZQogICAgICAmJiBJU19BR0dSX1RZUEUgKHR5cGUpCiAgICAgICYmICEgREVDTF9FWFRFUk5BTCAoZGVjbCkpCiAgICB7CiAgICAgIGlmICgoISBwcm9jZXNzaW5nX3RlbXBsYXRlX2RlY2wgfHwgISB1c2VzX3RlbXBsYXRlX3Bhcm1zICh0eXBlKSkKCSAgJiYgIUNPTVBMRVRFX1RZUEVfUCAoY29tcGxldGVfdHlwZSAodHlwZSkpKQoJewoJICBlcnJvciAoImFnZ3JlZ2F0ZSAlcSNEIGhhcyBpbmNvbXBsZXRlIHR5cGUgYW5kIGNhbm5vdCBiZSBkZWZpbmVkIiwKCQkgZGVjbCk7CgkgIC8qIENoYW5nZSB0aGUgdHlwZSBzbyB0aGF0IGFzc2VtYmxlX3ZhcmlhYmxlIHdpbGwgZ2l2ZQoJICAgICBERUNMIGFuIHJ0bCB3ZSBjYW4gbGl2ZSB3aXRoOiAobWVtIChjb25zdF9pbnQgMCkpLiAgKi8KCSAgdHlwZSA9IFRSRUVfVFlQRSAoZGVjbCkgPSBlcnJvcl9tYXJrX25vZGU7Cgl9CiAgICAgIGVsc2UKCXsKCSAgLyogSWYgYW55IGJhc2UgdHlwZSBpbiB0aGUgaGllcmFyY2h5IG9mIFRZUEUgbmVlZHMgYSBjb25zdHJ1Y3RvciwKCSAgICAgdGhlbiB3ZSBzZXQgaW5pdGlhbGl6ZWQgdG8gMS4gIFRoaXMgd2F5IGFueSBub2RlcyB3aGljaCBhcmUKCSAgICAgY3JlYXRlZCBmb3IgdGhlIHB1cnBvc2VzIG9mIGluaXRpYWxpemluZyB0aGlzIGFnZ3JlZ2F0ZQoJICAgICB3aWxsIGxpdmUgYXMgbG9uZyBhcyBpdCBkb2VzLiAgVGhpcyBpcyBuZWNlc3NhcnkgZm9yIGdsb2JhbAoJICAgICBhZ2dyZWdhdGVzIHdoaWNoIGRvIG5vdCBoYXZlIHRoZWlyIGluaXRpYWxpemVycyBwcm9jZXNzZWQgdW50aWwKCSAgICAgdGhlIGVuZCBvZiB0aGUgZmlsZS4gICovCgkgIGluaXRpYWxpemVkID0gVFlQRV9ORUVEU19DT05TVFJVQ1RJTkcgKHR5cGUpOwoJfQogICAgfQoKICBpZiAoISBpbml0aWFsaXplZCkKICAgIERFQ0xfSU5JVElBTCAoZGVjbCkgPSBOVUxMX1RSRUU7CgogIC8qIENyZWF0ZSBhIG5ldyBzY29wZSB0byBob2xkIHRoaXMgZGVjbGFyYXRpb24gaWYgbmVjZXNzYXJ5LgogICAgIFdoZXRoZXIgb3Igbm90IGEgbmV3IHNjb3BlIGlzIG5lY2Vzc2FyeSBjYW5ub3QgYmUgZGV0ZXJtaW5lZAogICAgIHVudGlsIGFmdGVyIHRoZSB0eXBlIGhhcyBiZWVuIGNvbXBsZXRlZDsgaWYgdGhlIHR5cGUgaXMgYQogICAgIHNwZWNpYWxpemF0aW9uIG9mIGEgY2xhc3MgdGVtcGxhdGUgaXQgaXMgbm90IHVudGlsIGFmdGVyCiAgICAgaW5zdGFudGlhdGlvbiBoYXMgb2NjdXJyZWQgdGhhdCBUWVBFX0hBU19OT05UUklWSUFMX0RFU1RSVUNUT1IKICAgICB3aWxsIGJlIHNldCBjb3JyZWN0bHkuICAqLwogIG1heWJlX3B1c2hfY2xlYW51cF9sZXZlbCAodHlwZSk7Cn0KCi8qIEhhbmRsZSBpbml0aWFsaXphdGlvbiBvZiByZWZlcmVuY2VzLiAgREVDTCwgVFlQRSwgYW5kIElOSVQgaGF2ZSB0aGUKICAgc2FtZSBtZWFuaW5nIGFzIGluIGNwX2ZpbmlzaF9kZWNsLiAgKkNMRUFOVVAgbXVzdCBiZSBOVUxMIG9uIGVudHJ5LAogICBidXQgd2lsbCBiZSBzZXQgdG8gYSBuZXcgQ0xFQU5VUF9TVE1UIGlmIGEgdGVtcG9yYXJ5IGlzIGNyZWF0ZWQKICAgdGhhdCBtdXN0IGJlIGRlc3Ryb3llZCBzdWJzZXF1ZW50bHkuCgogICBSZXR1cm5zIGFuIGluaXRpYWxpemVyIGV4cHJlc3Npb24gdG8gdXNlIHRvIGluaXRpYWxpemUgREVDTCwgb3IKICAgTlVMTCBpZiB0aGUgaW5pdGlhbGl6YXRpb24gY2FuIGJlIHBlcmZvcm1lZCBzdGF0aWNhbGx5LgoKICAgUXVvdGVzIG9uIHNlbWFudGljcyBjYW4gYmUgZm91bmQgaW4gQVJNIDguNC4zLiAgKi8KCnN0YXRpYyB0cmVlCmdyb2tfcmVmZXJlbmNlX2luaXQgKHRyZWUgZGVjbCwgdHJlZSB0eXBlLCB0cmVlIGluaXQsIHRyZWUgKmNsZWFudXApCnsKICB0cmVlIHRtcDsKCiAgaWYgKGluaXQgPT0gTlVMTF9UUkVFKQogICAgewogICAgICBpZiAoKERFQ0xfTEFOR19TUEVDSUZJQyAoZGVjbCkgPT0gMAoJICAgfHwgREVDTF9JTl9BR0dSX1AgKGRlY2wpID09IDApCgkgICYmICEgREVDTF9USElTX0VYVEVSTiAoZGVjbCkpCgllcnJvciAoIiVxRCBkZWNsYXJlZCBhcyByZWZlcmVuY2UgYnV0IG5vdCBpbml0aWFsaXplZCIsIGRlY2wpOwogICAgICByZXR1cm4gTlVMTF9UUkVFOwogICAgfQoKICBpZiAoVFJFRV9DT0RFIChpbml0KSA9PSBDT05TVFJVQ1RPUikKICAgIHsKICAgICAgZXJyb3IgKCJJU08gQysrIGZvcmJpZHMgdXNlIG9mIGluaXRpYWxpemVyIGxpc3QgdG8gIgogICAgICAgICAgICAgImluaXRpYWxpemUgcmVmZXJlbmNlICVxRCIsIGRlY2wpOwogICAgICByZXR1cm4gTlVMTF9UUkVFOwogICAgfQoKICBpZiAoVFJFRV9DT0RFIChpbml0KSA9PSBUUkVFX0xJU1QpCiAgICBpbml0ID0gYnVpbGRfeF9jb21wb3VuZF9leHByX2Zyb21fbGlzdCAoaW5pdCwgImluaXRpYWxpemVyIik7CgogIGlmIChUUkVFX0NPREUgKFRSRUVfVFlQRSAodHlwZSkpICE9IEFSUkFZX1RZUEUKICAgICAgJiYgVFJFRV9DT0RFIChUUkVFX1RZUEUgKGluaXQpKSA9PSBBUlJBWV9UWVBFKQogICAgLyogTm90ZTogZGVmYXVsdCBjb252ZXJzaW9uIGlzIG9ubHkgY2FsbGVkIGluIHZlcnkgc3BlY2lhbCBjYXNlcy4gICovCiAgICBpbml0ID0gZGVjYXlfY29udmVyc2lvbiAoaW5pdCk7CgogIC8qIENvbnZlcnQgSU5JVCB0byB0aGUgcmVmZXJlbmNlIHR5cGUgVFlQRS4gIFRoaXMgbWF5IGludm9sdmUgdGhlCiAgICAgY3JlYXRpb24gb2YgYSB0ZW1wb3JhcnksIHdob3NlIGxpZmV0aW1lIG11c3QgYmUgdGhlIHNhbWUgYXMgdGhhdAogICAgIG9mIHRoZSByZWZlcmVuY2UuICBJZiBzbywgYSBERUNMX0VYUFIgZm9yIHRoZSB0ZW1wb3Jhcnkgd2lsbCBiZQogICAgIGFkZGVkIGp1c3QgYWZ0ZXIgdGhlIERFQ0xfRVhQUiBmb3IgREVDTC4gIFRoYXQncyB3aHkgd2UgZG9uJ3Qgc2V0CiAgICAgREVDTF9JTklUSUFMIGZvciBsb2NhbCByZWZlcmVuY2VzIChpbnN0ZWFkIGFzc2lnbmluZyB0byB0aGVtCiAgICAgZXhwbGljaXRseSk7IHdlIG5lZWQgdG8gYWxsb3cgdGhlIHRlbXBvcmFyeSB0byBiZSBpbml0aWFsaXplZAogICAgIGZpcnN0LiAgKi8KICB0bXAgPSBpbml0aWFsaXplX3JlZmVyZW5jZSAodHlwZSwgaW5pdCwgZGVjbCwgY2xlYW51cCk7CgogIGlmICh0bXAgPT0gZXJyb3JfbWFya19ub2RlKQogICAgcmV0dXJuIE5VTExfVFJFRTsKICBlbHNlIGlmICh0bXAgPT0gTlVMTF9UUkVFKQogICAgewogICAgICBlcnJvciAoImNhbm5vdCBpbml0aWFsaXplICVxVCBmcm9tICVxVCIsIHR5cGUsIFRSRUVfVFlQRSAoaW5pdCkpOwogICAgICByZXR1cm4gTlVMTF9UUkVFOwogICAgfQoKICBpZiAoVFJFRV9TVEFUSUMgKGRlY2wpICYmICFUUkVFX0NPTlNUQU5UICh0bXApKQogICAgcmV0dXJuIHRtcDsKCiAgREVDTF9JTklUSUFMIChkZWNsKSA9IHRtcDsKCiAgcmV0dXJuIE5VTExfVFJFRTsKfQoKLyogV2hlbiBwYXJzaW5nIGBpbnQgYVtdID0gezEsIDJ9Oycgd2UgZG9uJ3Qga25vdyB0aGUgc2l6ZSBvZiB0aGUKICAgYXJyYXkgdW50aWwgd2UgZmluaXNoIHBhcnNpbmcgdGhlIGluaXRpYWxpemVyLiAgSWYgdGhhdCdzIHRoZQogICBzaXR1YXRpb24gd2UncmUgaW4sIHVwZGF0ZSBERUNMIGFjY29yZGluZ2x5LiAgKi8KCnN0YXRpYyB2b2lkCm1heWJlX2RlZHVjZV9zaXplX2Zyb21fYXJyYXlfaW5pdCAodHJlZSBkZWNsLCB0cmVlIGluaXQpCnsKICB0cmVlIHR5cGUgPSBUUkVFX1RZUEUgKGRlY2wpOwoKICBpZiAoVFJFRV9DT0RFICh0eXBlKSA9PSBBUlJBWV9UWVBFCiAgICAgICYmIFRZUEVfRE9NQUlOICh0eXBlKSA9PSBOVUxMX1RSRUUKICAgICAgJiYgVFJFRV9DT0RFIChkZWNsKSAhPSBUWVBFX0RFQ0wpCiAgICB7CiAgICAgIC8qIGRvX2RlZmF1bHQgaXMgcmVhbGx5IGEgQy1pc20gdG8gZGVhbCB3aXRoIHRlbnRhdGl2ZSBkZWZpbml0aW9ucy4KCSBCdXQgbGV0J3MgbGVhdmUgaXQgaGVyZSB0byBlYXNlIHRoZSBldmVudHVhbCBtZXJnZS4gICovCiAgICAgIGludCBkb19kZWZhdWx0ID0gIURFQ0xfRVhURVJOQUwgKGRlY2wpOwogICAgICB0cmVlIGluaXRpYWxpemVyID0gaW5pdCA/IGluaXQgOiBERUNMX0lOSVRJQUwgKGRlY2wpOwogICAgICBpbnQgZmFpbHVyZSA9IGNwX2NvbXBsZXRlX2FycmF5X3R5cGUgKCZUUkVFX1RZUEUgKGRlY2wpLCBpbml0aWFsaXplciwKCQkJCQkgICAgZG9fZGVmYXVsdCk7CgogICAgICBpZiAoZmFpbHVyZSA9PSAxKQoJZXJyb3IgKCJpbml0aWFsaXplciBmYWlscyB0byBkZXRlcm1pbmUgc2l6ZSBvZiAlcUQiLCBkZWNsKTsKCiAgICAgIGlmIChmYWlsdXJlID09IDIpCgl7CgkgIGlmIChkb19kZWZhdWx0KQoJICAgIGVycm9yICgiYXJyYXkgc2l6ZSBtaXNzaW5nIGluICVxRCIsIGRlY2wpOwoJICAvKiBJZiBhIGBzdGF0aWMnIHZhcidzIHNpemUgaXNuJ3Qga25vd24sIG1ha2UgaXQgZXh0ZXJuIGFzCgkgICAgIHdlbGwgYXMgc3RhdGljLCBzbyBpdCBkb2VzIG5vdCBnZXQgYWxsb2NhdGVkLiAgSWYgaXQncyBub3QKCSAgICAgYHN0YXRpYycsIHRoZW4gZG9uJ3QgbWFyayBpdCBleHRlcm47IGZpbmlzaF9pbmNvbXBsZXRlX2RlY2wKCSAgICAgd2lsbCBnaXZlIGl0IGEgZGVmYXVsdCBzaXplIGFuZCBpdCB3aWxsIGdldCBhbGxvY2F0ZWQuICAqLwoJICBlbHNlIGlmICghcGVkYW50aWMgJiYgVFJFRV9TVEFUSUMgKGRlY2wpICYmICFUUkVFX1BVQkxJQyAoZGVjbCkpCgkgICAgREVDTF9FWFRFUk5BTCAoZGVjbCkgPSAxOwoJfQoKICAgICAgaWYgKGZhaWx1cmUgPT0gMykKCWVycm9yICgiemVyby1zaXplIGFycmF5ICVxRCIsIGRlY2wpOwoKICAgICAgY3BfYXBwbHlfdHlwZV9xdWFsc190b19kZWNsIChjcF90eXBlX3F1YWxzIChUUkVFX1RZUEUgKGRlY2wpKSwgZGVjbCk7CgogICAgICBsYXlvdXRfZGVjbCAoZGVjbCwgMCk7CiAgICB9Cn0KCi8qIFNldCBERUNMX1NJWkUsIERFQ0xfQUxJR04sIGV0Yy4gZm9yIERFQ0wgKGEgVkFSX0RFQ0wpLCBhbmQgaXNzdWUKICAgYW55IGFwcHJvcHJpYXRlIGVycm9yIG1lc3NhZ2VzIHJlZ2FyZGluZyB0aGUgbGF5b3V0LiAgKi8KCnN0YXRpYyB2b2lkCmxheW91dF92YXJfZGVjbCAodHJlZSBkZWNsKQp7CiAgdHJlZSB0eXBlID0gVFJFRV9UWVBFIChkZWNsKTsKI2lmIDAKICB0cmVlIHR0eXBlID0gdGFyZ2V0X3R5cGUgKHR5cGUpOwojZW5kaWYKCiAgLyogSWYgd2UgaGF2ZW4ndCBhbHJlYWR5IGxheWVkIG91dCB0aGlzIGRlY2xhcmF0aW9uLCBkbyBzbyBub3cuCiAgICAgTm90ZSB0aGF0IHdlIG11c3Qgbm90IGNhbGwgY29tcGxldGUgdHlwZSBmb3IgYW4gZXh0ZXJuYWwgb2JqZWN0CiAgICAgYmVjYXVzZSBpdCdzIHR5cGUgbWlnaHQgaW52b2x2ZSB0ZW1wbGF0ZXMgdGhhdCB3ZSBhcmUgbm90CiAgICAgc3VwcG9zZWQgdG8gaW5zdGFudGlhdGUgeWV0LiAgKEFuZCBpdCdzIHBlcmZlY3RseSB2YWxpZCB0byBzYXkKICAgICBgZXh0ZXJuIFggeCcgZm9yIHNvbWUgaW5jb21wbGV0ZSB0eXBlIGBYJy4pICAqLwogIGlmICghREVDTF9FWFRFUk5BTCAoZGVjbCkpCiAgICBjb21wbGV0ZV90eXBlICh0eXBlKTsKICBpZiAoIURFQ0xfU0laRSAoZGVjbCkKICAgICAgJiYgVFJFRV9UWVBFIChkZWNsKSAhPSBlcnJvcl9tYXJrX25vZGUKICAgICAgJiYgKENPTVBMRVRFX1RZUEVfUCAodHlwZSkKCSAgfHwgKFRSRUVfQ09ERSAodHlwZSkgPT0gQVJSQVlfVFlQRQoJICAgICAgJiYgIVRZUEVfRE9NQUlOICh0eXBlKQoJICAgICAgJiYgQ09NUExFVEVfVFlQRV9QIChUUkVFX1RZUEUgKHR5cGUpKSkpKQogICAgbGF5b3V0X2RlY2wgKGRlY2wsIDApOwoKICBpZiAoIURFQ0xfRVhURVJOQUwgKGRlY2wpICYmIERFQ0xfU0laRSAoZGVjbCkgPT0gTlVMTF9UUkVFKQogICAgewogICAgICAvKiBBbiBhdXRvbWF0aWMgdmFyaWFibGUgd2l0aCBhbiBpbmNvbXBsZXRlIHR5cGU6IHRoYXQgaXMgYW4gZXJyb3IuCgkgRG9uJ3QgdGFsayBhYm91dCBhcnJheSB0eXBlcyBoZXJlLCBzaW5jZSB3ZSB0b29rIGNhcmUgb2YgdGhhdAoJIG1lc3NhZ2UgaW4gZ3Jva2RlY2xhcmF0b3IuICAqLwogICAgICBlcnJvciAoInN0b3JhZ2Ugc2l6ZSBvZiAlcUQgaXNuJ3Qga25vd24iLCBkZWNsKTsKICAgICAgVFJFRV9UWVBFIChkZWNsKSA9IGVycm9yX21hcmtfbm9kZTsKICAgIH0KI2lmIDAKICAvKiBLZWVwIHRoaXMgY29kZSBhcm91bmQgaW4gY2FzZSB3ZSBsYXRlciB3YW50IHRvIGNvbnRyb2wgZGVidWcgaW5mbwogICAgIGJhc2VkIG9uIHdoZXRoZXIgYSB0eXBlIGlzICJ1c2VkIi4gIChqYXNvbiAxOTk5LTExLTExKSAqLwoKICBlbHNlIGlmICghREVDTF9FWFRFUk5BTCAoZGVjbCkgJiYgSVNfQUdHUl9UWVBFICh0dHlwZSkpCiAgICAvKiBMZXQgZGVidWdnZXIga25vdyBpdCBzaG91bGQgb3V0cHV0IGluZm8gZm9yIHRoaXMgdHlwZS4gICovCiAgICBub3RlX2RlYnVnX2luZm9fbmVlZGVkICh0dHlwZSk7CgogIGlmIChUUkVFX1NUQVRJQyAoZGVjbCkgJiYgREVDTF9DTEFTU19TQ09QRV9QIChkZWNsKSkKICAgIG5vdGVfZGVidWdfaW5mb19uZWVkZWQgKERFQ0xfQ09OVEVYVCAoZGVjbCkpOwojZW5kaWYKCiAgaWYgKChERUNMX0VYVEVSTkFMIChkZWNsKSB8fCBUUkVFX1NUQVRJQyAoZGVjbCkpCiAgICAgICYmIERFQ0xfU0laRSAoZGVjbCkgIT0gTlVMTF9UUkVFCiAgICAgICYmICEgVFJFRV9DT05TVEFOVCAoREVDTF9TSVpFIChkZWNsKSkpCiAgICB7CiAgICAgIGlmIChUUkVFX0NPREUgKERFQ0xfU0laRSAoZGVjbCkpID09IElOVEVHRVJfQ1NUKQoJY29uc3RhbnRfZXhwcmVzc2lvbl93YXJuaW5nIChERUNMX1NJWkUgKGRlY2wpKTsKICAgICAgZWxzZQoJZXJyb3IgKCJzdG9yYWdlIHNpemUgb2YgJXFEIGlzbid0IGNvbnN0YW50IiwgZGVjbCk7CiAgICB9CgogIGlmIChUUkVFX1NUQVRJQyAoZGVjbCkKICAgICAgJiYgIURFQ0xfQVJUSUZJQ0lBTCAoZGVjbCkKICAgICAgJiYgY3VycmVudF9mdW5jdGlvbl9kZWNsCiAgICAgICYmIERFQ0xfQ09OVEVYVCAoZGVjbCkgPT0gY3VycmVudF9mdW5jdGlvbl9kZWNsKQogICAgcHVzaF9sb2NhbF9uYW1lIChkZWNsKTsKfQoKLyogSWYgYSBsb2NhbCBzdGF0aWMgdmFyaWFibGUgaXMgZGVjbGFyZWQgaW4gYW4gaW5saW5lIGZ1bmN0aW9uLCBvciBpZgogICB3ZSBoYXZlIGEgd2VhayBkZWZpbml0aW9uLCB3ZSBtdXN0IGVuZGVhdm9yIHRvIGNyZWF0ZSBvbmx5IG9uZQogICBpbnN0YW5jZSBvZiB0aGUgdmFyaWFibGUgYXQgbGluay10aW1lLiAgKi8KCnN0YXRpYyB2b2lkCm1heWJlX2NvbW1vbml6ZV92YXIgKHRyZWUgZGVjbCkKewogIC8qIFN0YXRpYyBkYXRhIGluIGEgZnVuY3Rpb24gd2l0aCBjb21kYXQgbGlua2FnZSBhbHNvIGhhcyBjb21kYXQKICAgICBsaW5rYWdlLiAgKi8KICBpZiAoVFJFRV9TVEFUSUMgKGRlY2wpCiAgICAgIC8qIERvbid0IG1lc3Mgd2l0aCBfX0ZVTkNUSU9OX18uICAqLwogICAgICAmJiAhIERFQ0xfQVJUSUZJQ0lBTCAoZGVjbCkKICAgICAgJiYgREVDTF9GVU5DVElPTl9TQ09QRV9QIChkZWNsKQogICAgICAvKiBVbmZvcnR1bmF0ZWx5LCBpbXBvcnRfZXhwb3J0X2RlY2wgaGFzIG5vdCBhbHdheXMgYmVlbiBjYWxsZWQKCSBiZWZvcmUgdGhlIGZ1bmN0aW9uIGlzIHByb2Nlc3NlZCwgc28gd2UgY2Fubm90IHNpbXBseSBjaGVjawoJIERFQ0xfQ09NREFULiAgKi8KICAgICAgJiYgKERFQ0xfQ09NREFUIChERUNMX0NPTlRFWFQgKGRlY2wpKQoJICB8fCAoKERFQ0xfREVDTEFSRURfSU5MSU5FX1AgKERFQ0xfQ09OVEVYVCAoZGVjbCkpCgkgICAgICAgfHwgREVDTF9URU1QTEFURV9JTlNUQU5USUFUSU9OIChERUNMX0NPTlRFWFQgKGRlY2wpKSkKCSAgICAgICYmIFRSRUVfUFVCTElDIChERUNMX0NPTlRFWFQgKGRlY2wpKSkpKQogICAgewogICAgICBpZiAoZmxhZ193ZWFrKQoJewoJICAvKiBXaXRoIHdlYWsgc3ltYm9scywgd2Ugc2ltcGx5IG1ha2UgdGhlIHZhcmlhYmxlIENPTURBVDsKCSAgICAgdGhhdCB3aWxsIGNhdXNlIGNvcGllcyBpbiBtdWx0aXBsZSB0cmFuc2xhdGlvbnMgdW5pdHMgdG8KCSAgICAgYmUgbWVyZ2VkLiAgKi8KCSAgY29tZGF0X2xpbmthZ2UgKGRlY2wpOwoJfQogICAgICBlbHNlCgl7CgkgIGlmIChERUNMX0lOSVRJQUwgKGRlY2wpID09IE5VTExfVFJFRQoJICAgICAgfHwgREVDTF9JTklUSUFMIChkZWNsKSA9PSBlcnJvcl9tYXJrX25vZGUpCgkgICAgewoJICAgICAgLyogV2l0aG91dCB3ZWFrIHN5bWJvbHMsIHdlIGNhbiB1c2UgQ09NTU9OIHRvIG1lcmdlCgkJIHVuaW5pdGlhbGl6ZWQgdmFyaWFibGVzLiAgKi8KCSAgICAgIFRSRUVfUFVCTElDIChkZWNsKSA9IDE7CgkgICAgICBERUNMX0NPTU1PTiAoZGVjbCkgPSAxOwoJICAgIH0KCSAgZWxzZQoJICAgIHsKCSAgICAgIC8qIFdoaWxlIGZvciBpbml0aWFsaXplZCB2YXJpYWJsZXMsIHdlIG11c3QgdXNlIGludGVybmFsCgkJIGxpbmthZ2UgLS0gd2hpY2ggbWVhbnMgdGhhdCBtdWx0aXBsZSBjb3BpZXMgd2lsbCBub3QKCQkgYmUgbWVyZ2VkLiAgKi8KCSAgICAgIFRSRUVfUFVCTElDIChkZWNsKSA9IDA7CgkgICAgICBERUNMX0NPTU1PTiAoZGVjbCkgPSAwOwoJICAgICAgY3Bfd2FybmluZ19hdCAoInNvcnJ5OiBzZW1hbnRpY3Mgb2YgaW5saW5lIGZ1bmN0aW9uIHN0YXRpYyAiCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImRhdGEgJXEjRCBhcmUgd3JvbmcgKHlvdSdsbCB3aW5kIHVwICIKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAid2l0aCBtdWx0aXBsZSBjb3BpZXMpIiwgZGVjbCk7CgkgICAgICB3YXJuaW5nICgiJUogIHlvdSBjYW4gd29yayBhcm91bmQgdGhpcyBieSByZW1vdmluZyAiCiAgICAgICAgICAgICAgICAgICAgICAgInRoZSBpbml0aWFsaXplciIsCgkJICAgICAgIGRlY2wpOwoJICAgIH0KCX0KICAgIH0KICBlbHNlIGlmIChERUNMX0xBTkdfU1BFQ0lGSUMgKGRlY2wpICYmIERFQ0xfQ09NREFUIChkZWNsKSkKICAgIC8qIFNldCBpdCB1cCBhZ2Fpbjsgd2UgbWlnaHQgaGF2ZSBzZXQgREVDTF9JTklUSUFMIHNpbmNlIHRoZSBsYXN0CiAgICAgICB0aW1lLiAgKi8KICAgIGNvbWRhdF9saW5rYWdlIChkZWNsKTsKfQoKLyogSXNzdWUgYW4gZXJyb3IgbWVzc2FnZSBpZiBERUNMIGlzIGFuIHVuaW5pdGlhbGl6ZWQgY29uc3QgdmFyaWFibGUuICAqLwoKc3RhdGljIHZvaWQKY2hlY2tfZm9yX3VuaW5pdGlhbGl6ZWRfY29uc3RfdmFyICh0cmVlIGRlY2wpCnsKICB0cmVlIHR5cGUgPSBUUkVFX1RZUEUgKGRlY2wpOwoKICAvKiBgYFVubGVzcyBleHBsaWNpdGx5IGRlY2xhcmVkIGV4dGVybiwgYSBjb25zdCBvYmplY3QgZG9lcyBub3QgaGF2ZQogICAgIGV4dGVybmFsIGxpbmthZ2UgYW5kIG11c3QgYmUgaW5pdGlhbGl6ZWQuICgkOC40OyAkMTIuMSknJyBBUk0KICAgICA3LjEuNiAqLwogIGlmIChUUkVFX0NPREUgKGRlY2wpID09IFZBUl9ERUNMCiAgICAgICYmIFRSRUVfQ09ERSAodHlwZSkgIT0gUkVGRVJFTkNFX1RZUEUKICAgICAgJiYgQ1BfVFlQRV9DT05TVF9QICh0eXBlKQogICAgICAmJiAhVFlQRV9ORUVEU19DT05TVFJVQ1RJTkcgKHR5cGUpCiAgICAgICYmICFERUNMX0lOSVRJQUwgKGRlY2wpKQogICAgZXJyb3IgKCJ1bmluaXRpYWxpemVkIGNvbnN0ICVxRCIsIGRlY2wpOwp9CgovKiBGSUVMRCBpcyBhIEZJRUxEX0RFQ0wgb3IgTlVMTC4gIEluIHRoZSBmb3JtZXIgY2FzZSwgdGhlIHZhbHVlCiAgIHJldHVybmVkIGlzIHRoZSBuZXh0IEZJRUxEX0RFQ0wgKHBvc3NpYmx5IEZJRUxEIGl0c2VsZikgdGhhdCBjYW4gYmUKICAgaW5pdGlhbGl6ZWQuICBJZiB0aGVyZSBhcmUgbm8gbW9yZSBzdWNoIGZpZWxkcywgdGhlIHJldHVybiB2YWx1ZQogICB3aWxsIGJlIE5VTEwuICAqLwoKc3RhdGljIHRyZWUKbmV4dF9pbml0aWFsaXphYmxlX2ZpZWxkICh0cmVlIGZpZWxkKQp7CiAgd2hpbGUgKGZpZWxkCgkgJiYgKFRSRUVfQ09ERSAoZmllbGQpICE9IEZJRUxEX0RFQ0wKCSAgICAgfHwgKERFQ0xfQ19CSVRfRklFTEQgKGZpZWxkKSAmJiAhREVDTF9OQU1FIChmaWVsZCkpCgkgICAgIHx8IERFQ0xfQVJUSUZJQ0lBTCAoZmllbGQpKSkKICAgIGZpZWxkID0gVFJFRV9DSEFJTiAoZmllbGQpOwoKICByZXR1cm4gZmllbGQ7Cn0KCi8qIFN1YnJvdXRpbmUgb2YgcmVzaGFwZV9pbml0LiBSZXNoYXBlIHRoZSBjb25zdHJ1Y3RvciBmb3IgYW4gYXJyYXkuIElOSVRQCiAgIGlzIHRoZSBwb2ludGVyIHRvIHRoZSBvbGQgY29uc3RydWN0b3IgbGlzdCAodG8gdGhlIENPTlNUUlVDVE9SX0VMVFMgb2YKICAgdGhlIENPTlNUUlVDVE9SIHdlIGFyZSBwcm9jZXNzaW5nKSwgd2hpbGUgTkVXX0lOSVQgaXMgdGhlIENPTlNUUlVDVE9SIHdlCiAgIGFyZSBidWlsZGluZy4KICAgRUxUX1RZUEUgaXMgdGhlIGVsZW1lbnQgdHlwZSBvZiB0aGUgYXJyYXkuIE1BWF9JTkRFWCBpcyBhbiBJTlRFR0VSX0NTVAogICByZXByZXNlbnRpbmcgdGhlIHNpemUgb2YgdGhlIGFycmF5IG1pbnVzIG9uZSAodGhlIG1heGltdW0gaW5kZXgpLCBvcgogICBOVUxMX1RSRUUgaWYgdGhlIGFycmF5IHdhcyBkZWNsYXJlZCB3aXRob3V0IHNwZWNpZnlpbmcgdGhlIHNpemUuICAqLwoKc3RhdGljIGJvb2wKcmVzaGFwZV9pbml0X2FycmF5ICh0cmVlIGVsdF90eXBlLCB0cmVlIG1heF9pbmRleCwKCQkgICAgdHJlZSAqaW5pdHAsIHRyZWUgbmV3X2luaXQpCnsKICBib29sIHNpemVkX2FycmF5X3AgPSAobWF4X2luZGV4ICE9IE5VTExfVFJFRSk7CiAgdW5zaWduZWQgSE9TVF9XSURFX0lOVCBtYXhfaW5kZXhfY3N0ID0gMDsKICB1bnNpZ25lZCBIT1NUX1dJREVfSU5UIGluZGV4OwoKICBpZiAoc2l6ZWRfYXJyYXlfcCkKICAgIHsKICAgICAgaWYgKGhvc3RfaW50ZWdlcnAgKG1heF9pbmRleCwgMSkpCgltYXhfaW5kZXhfY3N0ID0gdHJlZV9sb3dfY3N0IChtYXhfaW5kZXgsIDEpOwogICAgICAvKiBzaXpldHlwZSBpcyBzaWduIGV4dGVuZGVkLCBub3QgemVybyBleHRlbmRlZC4gICovCiAgICAgIGVsc2UKCW1heF9pbmRleF9jc3QgPSB0cmVlX2xvd19jc3QgKGZvbGRfY29udmVydCAoc2l6ZV90eXBlX25vZGUsIG1heF9pbmRleCksCgkJCQkgICAgICAxKTsKICAgIH0KCiAgLyogTG9vcCB1bnRpbCB0aGVyZSBhcmUgbm8gbW9yZSBpbml0aWFsaXplcnMuICAqLwogIGZvciAoaW5kZXggPSAwOwogICAgICAgKmluaXRwICYmICghc2l6ZWRfYXJyYXlfcCB8fCBpbmRleCA8PSBtYXhfaW5kZXhfY3N0KTsKICAgICAgICsraW5kZXgpCiAgICB7CiAgICAgIHRyZWUgZWxlbWVudF9pbml0OwogICAgICB0cmVlIGRlc2lnbmF0ZWRfaW5kZXg7CgogICAgICBlbGVtZW50X2luaXQgPSByZXNoYXBlX2luaXQgKGVsdF90eXBlLCBpbml0cCk7CiAgICAgIGlmIChlbGVtZW50X2luaXQgPT0gZXJyb3JfbWFya19ub2RlKQoJcmV0dXJuIGZhbHNlOwogICAgICBUUkVFX0NIQUlOIChlbGVtZW50X2luaXQpID0gQ09OU1RSVUNUT1JfRUxUUyAobmV3X2luaXQpOwogICAgICBDT05TVFJVQ1RPUl9FTFRTIChuZXdfaW5pdCkgPSBlbGVtZW50X2luaXQ7CiAgICAgIGRlc2lnbmF0ZWRfaW5kZXggPSBUUkVFX1BVUlBPU0UgKGVsZW1lbnRfaW5pdCk7CiAgICAgIGlmIChkZXNpZ25hdGVkX2luZGV4KQoJewoJICAvKiBIYW5kbGUgYXJyYXkgZGVzaWduYXRlZCBpbml0aWFsaXplcnMgKEdOVSBleHRlbnNpb24pLiAgKi8KCSAgaWYgKFRSRUVfQ09ERSAoZGVzaWduYXRlZF9pbmRleCkgPT0gSURFTlRJRklFUl9OT0RFKQoJICAgIHsKCSAgICAgIGVycm9yICgibmFtZSAlcUQgdXNlZCBpbiBhIEdOVS1zdHlsZSBkZXNpZ25hdGVkICIKCQkgICAgICJpbml0aWFsaXplciBmb3IgYW4gYXJyYXkiLCBkZXNpZ25hdGVkX2luZGV4KTsKCSAgICAgIFRSRUVfUFVSUE9TRSAoZWxlbWVudF9pbml0KSA9IE5VTExfVFJFRTsKCSAgICB9CgkgIGVsc2UKCSAgICBnY2NfdW5yZWFjaGFibGUgKCk7Cgl9CiAgICB9CgogIHJldHVybiB0cnVlOwp9CgovKiBVbmRvIHRoZSBicmFjZS1lbGlzaW9uIGFsbG93ZWQgYnkgW2RjbC5pbml0LmFnZ3JdIGluIGEKICAgYnJhY2UtZW5jbG9zZWQgYWdncmVnYXRlIGluaXRpYWxpemVyLgoKICAgKklOSVRQIGlzIG9uZSBvZiBhIGxpc3Qgb2YgaW5pdGlhbGl6ZXJzIGRlc2NyaWJpbmcgYSBicmFjZS1lbmNsb3NlZAogICBpbml0aWFsaXplciBmb3IgYW4gZW50aXR5IG9mIHRoZSBpbmRpY2F0ZWQgYWdncmVnYXRlIFRZUEUuICBJdCBtYXkKICAgbm90IHByZXNlbnRseSBtYXRjaCB0aGUgc2hhcGUgb2YgdGhlIFRZUEU7IGZvciBleGFtcGxlOgoKICAgICBzdHJ1Y3QgUyB7IGludCBhOyBpbnQgYjsgfTsKICAgICBzdHJ1Y3QgUyBhW10gPSB7IDEsIDIsIDMsIDQgfTsKCiAgIEhlcmUgKklOSVRQIHdpbGwgcG9pbnQgdG8gVFJFRV9MSVNUIG9mIGZvdXIgZWxlbWVudHMsIHJhdGhlciB0aGFuIGEKICAgbGlzdCBvZiB0d28gZWxlbWVudHMsIGVhY2ggaXRzZWxmIGEgbGlzdCBvZiB0d28gZWxlbWVudHMuICBUaGlzCiAgIHJvdXRpbmUgdHJhbnNmb3JtcyBJTklUIGZyb20gdGhlIGZvcm1lciBmb3JtIGludG8gdGhlIGxhdHRlci4gIFRoZQogICByZXZpc2VkIGluaXRpYWxpemVyIGlzIHJldHVybmVkLiAgKi8KCnN0YXRpYyB0cmVlCnJlc2hhcGVfaW5pdCAodHJlZSB0eXBlLCB0cmVlICppbml0cCkKewogIHRyZWUgaW5pdHM7CiAgdHJlZSBvbGRfaW5pdDsKICB0cmVlIG9sZF9pbml0X3ZhbHVlOwogIHRyZWUgbmV3X2luaXQ7CiAgYm9vbCBicmFjZV9lbmNsb3NlZF9wOwogIGJvb2wgc3RyaW5nX2luaXRfcDsKCiAgb2xkX2luaXQgPSAqaW5pdHA7CiAgb2xkX2luaXRfdmFsdWUgPSAoVFJFRV9DT0RFICgqaW5pdHApID09IFRSRUVfTElTVAoJCSAgICA/IFRSRUVfVkFMVUUgKCppbml0cCkgOiBvbGRfaW5pdCk7CgogIGdjY19hc3NlcnQgKG9sZF9pbml0X3ZhbHVlKTsKCiAgLyogSWYgdGhlIGluaXRpYWxpemVyIGlzIGJyYWNlLWVuY2xvc2VkLCBwdWxsIGluaXRpYWxpemVycyBmcm9tIHRoZQogICAgIGVuY2xvc2VkIGVsZW1lbnRzLiAgQWR2YW5jZSBwYXN0IHRoZSBicmFjZS1lbmNsb3NlZCBpbml0aWFsaXplcgogICAgIG5vdy4gICovCiAgaWYgKFRSRUVfQ09ERSAob2xkX2luaXRfdmFsdWUpID09IENPTlNUUlVDVE9SCiAgICAgICYmIEJSQUNFX0VOQ0xPU0VEX0lOSVRJQUxJWkVSX1AgKG9sZF9pbml0X3ZhbHVlKSkKICAgIHsKICAgICAgKmluaXRwID0gVFJFRV9DSEFJTiAob2xkX2luaXQpOwogICAgICBUUkVFX0NIQUlOIChvbGRfaW5pdCkgPSBOVUxMX1RSRUU7CiAgICAgIGluaXRzID0gQ09OU1RSVUNUT1JfRUxUUyAob2xkX2luaXRfdmFsdWUpOwogICAgICBpbml0cCA9ICZpbml0czsKICAgICAgYnJhY2VfZW5jbG9zZWRfcCA9IHRydWU7CiAgICB9CiAgZWxzZQogICAgewogICAgICBpbml0cyA9IE5VTExfVFJFRTsKICAgICAgYnJhY2VfZW5jbG9zZWRfcCA9IGZhbHNlOwogICAgfQoKICAvKiBBIG5vbi1hZ2dyZWdhdGUgdHlwZSBpcyBhbHdheXMgaW5pdGlhbGl6ZWQgd2l0aCBhIHNpbmdsZQogICAgIGluaXRpYWxpemVyLiAgKi8KICBpZiAoIUNQX0FHR1JFR0FURV9UWVBFX1AgKHR5cGUpKQogICAgICB7CgkqaW5pdHAgPSBUUkVFX0NIQUlOIChvbGRfaW5pdCk7CglUUkVFX0NIQUlOIChvbGRfaW5pdCkgPSBOVUxMX1RSRUU7CgkvKiBJdCBpcyBpbnZhbGlkIHRvIGluaXRpYWxpemUgYSBub24tYWdncmVnYXRlIHR5cGUgd2l0aCBhCgkgICBicmFjZS1lbmNsb3NlZCBpbml0aWFsaXplci4gICovCglpZiAoYnJhY2VfZW5jbG9zZWRfcCkKCSAgewoJICAgIGVycm9yICgiYnJhY2UtZW5jbG9zZWQgaW5pdGlhbGl6ZXIgdXNlZCB0byBpbml0aWFsaXplICVxVCIsCgkJICAgdHlwZSk7CgkgICAgaWYgKFRSRUVfQ09ERSAob2xkX2luaXQpID09IFRSRUVfTElTVCkKCSAgICAgIFRSRUVfVkFMVUUgKG9sZF9pbml0KSA9IGVycm9yX21hcmtfbm9kZTsKCSAgICBlbHNlCgkgICAgICBvbGRfaW5pdCA9IGVycm9yX21hcmtfbm9kZTsKCSAgfQoKCXJldHVybiBvbGRfaW5pdDsKICAgICAgfQoKICAvKiBbZGNsLmluaXQuYWdncl0KCiAgICAgQWxsIGltcGxpY2l0IHR5cGUgY29udmVyc2lvbnMgKGNsYXVzZSBfY29udl8pIGFyZSBjb25zaWRlcmVkIHdoZW4KICAgICBpbml0aWFsaXppbmcgdGhlIGFnZ3JlZ2F0ZSBtZW1iZXIgd2l0aCBhbiBpbml0aWFsaXplciBmcm9tIGFuCiAgICAgaW5pdGlhbGl6ZXItbGlzdC4gIElmIHRoZSBpbml0aWFsaXplciBjYW4gaW5pdGlhbGl6ZSBhIG1lbWJlciwKICAgICB0aGUgbWVtYmVyIGlzIGluaXRpYWxpemVkLiAgT3RoZXJ3aXNlLCBpZiB0aGUgbWVtYmVyIGlzIGl0c2VsZiBhCiAgICAgbm9uLWVtcHR5IHN1YmFnZ3JlZ2F0ZSwgYnJhY2UgZWxpc2lvbiBpcyBhc3N1bWVkIGFuZCB0aGUKICAgICBpbml0aWFsaXplciBpcyBjb25zaWRlcmVkIGZvciB0aGUgaW5pdGlhbGl6YXRpb24gb2YgdGhlIGZpcnN0CiAgICAgbWVtYmVyIG9mIHRoZSBzdWJhZ2dyZWdhdGUuICAqLwogIGlmICghYnJhY2VfZW5jbG9zZWRfcAogICAgICAvKiBBUFBMRSBMT0NBTCByYWRhciA0MTg3OTE2ICovCiAgICAgICYmIGNhbl9jb252ZXJ0X2FyZyAodHlwZSwgVFJFRV9UWVBFIChvbGRfaW5pdF92YWx1ZSksIG9sZF9pbml0X3ZhbHVlLCBMT09LVVBfTk9STUFMKSkKICAgIHsKICAgICAgKmluaXRwID0gVFJFRV9DSEFJTiAob2xkX2luaXQpOwogICAgICBUUkVFX0NIQUlOIChvbGRfaW5pdCkgPSBOVUxMX1RSRUU7CiAgICAgIHJldHVybiBvbGRfaW5pdDsKICAgIH0KCiAgc3RyaW5nX2luaXRfcCA9IGZhbHNlOwogIGlmIChUUkVFX0NPREUgKG9sZF9pbml0X3ZhbHVlKSA9PSBTVFJJTkdfQ1NUCiAgICAgICYmIFRSRUVfQ09ERSAodHlwZSkgPT0gQVJSQVlfVFlQRQogICAgICAmJiBjaGFyX3R5cGVfcCAoVFlQRV9NQUlOX1ZBUklBTlQgKFRSRUVfVFlQRSAodHlwZSkpKSkKICAgIHsKICAgICAgLyogW2RjbC5pbml0LnN0cmluZ10KCgkgQSBjaGFyIGFycmF5ICh3aGV0aGVyIHBsYWluIGNoYXIsIHNpZ25lZCBjaGFyLCBvciB1bnNpZ25lZCBjaGFyKQoJIGNhbiBiZSBpbml0aWFsaXplZCBieSBhIHN0cmluZy1saXRlcmFsIChvcHRpb25hbGx5IGVuY2xvc2VkIGluCgkgYnJhY2VzKTsgYSB3Y2hhcl90IGFycmF5IGNhbiBiZSBpbml0aWFsaXplZCBieSBhIHdpZGUKCSBzdHJpbmctbGl0ZXJhbCAob3B0aW9uYWxseSBlbmNsb3NlZCBpbiBicmFjZXMpLiAgKi8KICAgICAgbmV3X2luaXQgPSBvbGRfaW5pdDsKICAgICAgLyogTW92ZSBwYXN0IHRoZSBpbml0aWFsaXplci4gICovCiAgICAgICppbml0cCA9IFRSRUVfQ0hBSU4gKG9sZF9pbml0KTsKICAgICAgVFJFRV9DSEFJTiAob2xkX2luaXQpID0gTlVMTF9UUkVFOwogICAgICBzdHJpbmdfaW5pdF9wID0gdHJ1ZTsKICAgIH0KICBlbHNlCiAgICB7CiAgICAgIC8qIEJ1aWxkIGEgQ09OU1RSVUNUT1IgdG8gaG9sZCB0aGUgY29udGVudHMgb2YgdGhlIGFnZ3JlZ2F0ZS4gICovCiAgICAgIG5ld19pbml0ID0gYnVpbGRfY29uc3RydWN0b3IgKE5VTExfVFJFRSwgTlVMTF9UUkVFKTsKCiAgICAgIGlmIChDTEFTU19UWVBFX1AgKHR5cGUpKQoJewoJICB0cmVlIGZpZWxkOwoKCSAgZmllbGQgPSBuZXh0X2luaXRpYWxpemFibGVfZmllbGQgKFRZUEVfRklFTERTICh0eXBlKSk7CgoJICBpZiAoIWZpZWxkKQoJICAgIHsKCSAgICAgIC8qIFtkY2wuaW5pdC5hZ2dyXQoKCQkgQW4gaW5pdGlhbGl6ZXIgZm9yIGFuIGFnZ3JlZ2F0ZSBtZW1iZXIgdGhhdCBpcyBhbgoJCSBlbXB0eSBjbGFzcyBzaGFsbCBoYXZlIHRoZSBmb3JtIG9mIGFuIGVtcHR5CgkJIGluaXRpYWxpemVyLWxpc3Qge30uICAqLwoJICAgICAgaWYgKCFicmFjZV9lbmNsb3NlZF9wKQoJCXsKCQkgIGVycm9yICgiaW5pdGlhbGl6ZXIgZm9yICVxVCBtdXN0IGJlIGJyYWNlLWVuY2xvc2VkIiwgdHlwZSk7CgkJICByZXR1cm4gZXJyb3JfbWFya19ub2RlOwoJCX0KCSAgICB9CgkgIGVsc2UKCSAgICB7CgkgICAgICAvKiBMb29wIHRocm91Z2ggdGhlIGluaXRpYWxpemFibGUgZmllbGRzLCBnYXRoZXJpbmcKCQkgaW5pdGlhbGl6ZXJzLiAgKi8KCSAgICAgIHdoaWxlICgqaW5pdHApCgkJewoJCSAgdHJlZSBmaWVsZF9pbml0OwoKCQkgIC8qIEhhbmRsZSBkZXNpZ25hdGVkIGluaXRpYWxpemVycywgYXMgYW4gZXh0ZW5zaW9uLiAgKi8KCQkgIGlmIChUUkVFX1BVUlBPU0UgKCppbml0cCkpCgkJICAgIHsKCQkgICAgICBpZiAocGVkYW50aWMpCgkJCXBlZHdhcm4gKCJJU08gQysrIGRvZXMgbm90IGFsbG93IGRlc2lnbmF0ZWQgaW5pdGlhbGl6ZXJzIik7CgkJICAgICAgZmllbGQgPSBsb29rdXBfZmllbGRfMSAodHlwZSwgVFJFRV9QVVJQT1NFICgqaW5pdHApLAoJCQkJCSAgICAgIC8qd2FudF90eXBlPSovZmFsc2UpOwoJCSAgICAgIGlmICghZmllbGQgfHwgVFJFRV9DT0RFIChmaWVsZCkgIT0gRklFTERfREVDTCkKCQkJZXJyb3IgKCIlcVQgaGFzIG5vIG5vbi1zdGF0aWMgZGF0YSBtZW1iZXIgbmFtZWQgJXFEIiwKCQkJICAgICAgIHR5cGUsIFRSRUVfUFVSUE9TRSAoKmluaXRwKSk7CgkJICAgIH0KCQkgIGlmICghZmllbGQpCgkJICAgIGJyZWFrOwoKCQkgIGZpZWxkX2luaXQgPSByZXNoYXBlX2luaXQgKFRSRUVfVFlQRSAoZmllbGQpLCBpbml0cCk7CgkJICBpZiAoZmllbGRfaW5pdCA9PSBlcnJvcl9tYXJrX25vZGUpCgkJICAgIHJldHVybiBlcnJvcl9tYXJrX25vZGU7CgkJICBUUkVFX0NIQUlOIChmaWVsZF9pbml0KSA9IENPTlNUUlVDVE9SX0VMVFMgKG5ld19pbml0KTsKCQkgIENPTlNUUlVDVE9SX0VMVFMgKG5ld19pbml0KSA9IGZpZWxkX2luaXQ7CgkJICAvKiBbZGNsLmluaXQuYWdncl0KCgkJICAgICBXaGVuIGEgdW5pb24gIGlzICBpbml0aWFsaXplZCB3aXRoIGEgYnJhY2UtZW5jbG9zZWQKCQkgICAgIGluaXRpYWxpemVyLCB0aGUgYnJhY2VzIHNoYWxsIG9ubHkgY29udGFpbiBhbgoJCSAgICAgaW5pdGlhbGl6ZXIgZm9yIHRoZSBmaXJzdCBtZW1iZXIgb2YgdGhlIHVuaW9uLiAgKi8KCQkgIGlmIChUUkVFX0NPREUgKHR5cGUpID09IFVOSU9OX1RZUEUpCgkJICAgIGJyZWFrOwoJCSAgZmllbGQgPSBuZXh0X2luaXRpYWxpemFibGVfZmllbGQgKFRSRUVfQ0hBSU4gKGZpZWxkKSk7CgkJfQoJICAgIH0KCX0KICAgICAgZWxzZSBpZiAoVFJFRV9DT0RFICh0eXBlKSA9PSBBUlJBWV9UWVBFCgkgICAgICAgfHwgVFJFRV9DT0RFICh0eXBlKSA9PSBWRUNUT1JfVFlQRSkKCXsKCSAgICAvKiBJZiB0aGUgYm91bmQgb2YgdGhlIGFycmF5IGlzIGtub3duLCB0YWtlIG5vIG1vcmUgaW5pdGlhbGl6ZXJzCgkgICAgICB0aGFuIGFyZSBhbGxvd2VkLiAgKi8KCSAgICB0cmVlIG1heF9pbmRleCA9IE5VTExfVFJFRTsKCSAgICBpZiAoVFJFRV9DT0RFICh0eXBlKSA9PSBBUlJBWV9UWVBFKQoJICAgICAgewoJCWlmIChUWVBFX0RPTUFJTiAodHlwZSkpCgkJICBtYXhfaW5kZXggPSBhcnJheV90eXBlX25lbHRzICh0eXBlKTsKCSAgICAgIH0KCSAgICBlbHNlCgkgICAgICB7CgkJLyogRm9yIGEgdmVjdG9yLCB0aGUgcmVwcmVzZW50YXRpb24gdHlwZSBpcyBhIHN0cnVjdAoJCSAgY29udGFpbmluZyBhIHNpbmdsZSBtZW1iZXIgd2hpY2ggaXMgYW4gYXJyYXkgb2YgdGhlCgkJICBhcHByb3ByaWF0ZSBzaXplLiAgKi8KCQl0cmVlIHJ0eXBlID0gVFlQRV9ERUJVR19SRVBSRVNFTlRBVElPTl9UWVBFICh0eXBlKTsKCQlpZiAocnR5cGUgJiYgVFlQRV9ET01BSU4gKFRSRUVfVFlQRSAoVFlQRV9GSUVMRFMgKHJ0eXBlKSkpKQoJCSAgbWF4X2luZGV4ID0gYXJyYXlfdHlwZV9uZWx0cyAoVFJFRV9UWVBFIChUWVBFX0ZJRUxEUwoJCQkJCQkJICAgKHJ0eXBlKSkpOwoJICAgICAgfQoKCSAgaWYgKCFyZXNoYXBlX2luaXRfYXJyYXkgKFRSRUVfVFlQRSAodHlwZSksIG1heF9pbmRleCwKCQkJCSAgIGluaXRwLCBuZXdfaW5pdCkpCgkgICAgcmV0dXJuIGVycm9yX21hcmtfbm9kZTsKCX0KICAgICAgZWxzZQoJZ2NjX3VucmVhY2hhYmxlICgpOwoKICAgICAgLyogVGhlIGluaXRpYWxpemVycyB3ZXJlIHBsYWNlZCBpbiByZXZlcnNlIG9yZGVyIGluIHRoZQoJIENPTlNUUlVDVE9SLiAgKi8KICAgICAgQ09OU1RSVUNUT1JfRUxUUyAobmV3X2luaXQpID0gbnJldmVyc2UgKENPTlNUUlVDVE9SX0VMVFMgKG5ld19pbml0KSk7CgogICAgICBpZiAoVFJFRV9DT0RFIChvbGRfaW5pdCkgPT0gVFJFRV9MSVNUKQoJbmV3X2luaXQgPSBidWlsZF90cmVlX2xpc3QgKFRSRUVfUFVSUE9TRSAob2xkX2luaXQpLCBuZXdfaW5pdCk7CiAgICB9CgogIC8qIElmIHRoZXJlIGFyZSBtb3JlIGluaXRpYWxpemVycyB0aGFuIG5lY2Vzc2FyeSwgaXNzdWUgYQogICAgIGRpYWdub3N0aWMuICAqLyAgCiAgaWYgKCppbml0cCkKICAgIHsKICAgICAgaWYgKGJyYWNlX2VuY2xvc2VkX3ApCgllcnJvciAoInRvbyBtYW55IGluaXRpYWxpemVycyBmb3IgJXFUIiwgdHlwZSk7CiAgICAgIGVsc2UgaWYgKHdhcm5fbWlzc2luZ19icmFjZXMgJiYgIXN0cmluZ19pbml0X3ApCgl3YXJuaW5nICgibWlzc2luZyBicmFjZXMgYXJvdW5kIGluaXRpYWxpemVyIik7CiAgICB9CgogIHJldHVybiBuZXdfaW5pdDsKfQoKLyogVmVyaWZ5IElOSVQgKHRoZSBpbml0aWFsaXplciBmb3IgREVDTCksIGFuZCByZWNvcmQgdGhlCiAgIGluaXRpYWxpemF0aW9uIGluIERFQ0xfSU5JVElBTCwgaWYgYXBwcm9wcmlhdGUuICBDTEVBTlVQIGlzIGFzIGZvcgogICBncm9rX3JlZmVyZW5jZV9pbml0LgoKICAgSWYgdGhlIHJldHVybiB2YWx1ZSBpcyBub24tTlVMTCwgaXQgaXMgYW4gZXhwcmVzc2lvbiB0aGF0IG11c3QgYmUKICAgZXZhbHVhdGVkIGR5bmFtaWNhbGx5IHRvIGluaXRpYWxpemUgREVDTC4gICovCgpzdGF0aWMgdHJlZQpjaGVja19pbml0aWFsaXplciAodHJlZSBkZWNsLCB0cmVlIGluaXQsIGludCBmbGFncywgdHJlZSAqY2xlYW51cCkKewogIHRyZWUgdHlwZSA9IFRSRUVfVFlQRSAoZGVjbCk7CiAgdHJlZSBpbml0X2NvZGUgPSBOVUxMOwoKICAvKiBJZiBgc3RhcnRfZGVjbCcgZGlkbid0IGxpa2UgaGF2aW5nIGFuIGluaXRpYWxpemF0aW9uLCBpZ25vcmUgaXQgbm93LiAgKi8KICBpZiAoaW5pdCAhPSBOVUxMX1RSRUUgJiYgREVDTF9JTklUSUFMIChkZWNsKSA9PSBOVUxMX1RSRUUpCiAgICBpbml0ID0gTlVMTF9UUkVFOwoKICAvKiBJZiBhbiBpbml0aWFsaXplciBpcyBwcmVzZW50LCBERUNMX0lOSVRJQUwgaGFzIGJlZW4KICAgICBlcnJvcl9tYXJrX25vZGUsIHRvIGluZGljYXRlIHRoYXQgYW4gYXMtb2YteWV0IHVuZXZhbHVhdGVkCiAgICAgaW5pdGlhbGl6YXRpb24gd2lsbCBvY2N1ci4gIEZyb20gbm93IG9uLCBERUNMX0lOSVRJQUwgcmVmbGVjdHMKICAgICB0aGUgc3RhdGljIGluaXRpYWxpemF0aW9uIC0tIGlmIGFueSAtLSBvZiBERUNMLiAgKi8KICBERUNMX0lOSVRJQUwgKGRlY2wpID0gTlVMTF9UUkVFOwoKICAvKiBUaGluZ3MgdGhhdCBhcmUgZ29pbmcgdG8gYmUgaW5pdGlhbGl6ZWQgbmVlZCB0byBoYXZlIGNvbXBsZXRlCiAgICAgdHlwZS4gICovCiAgVFJFRV9UWVBFIChkZWNsKSA9IHR5cGUgPSBjb21wbGV0ZV90eXBlIChUUkVFX1RZUEUgKGRlY2wpKTsKCiAgaWYgKHR5cGUgPT0gZXJyb3JfbWFya19ub2RlKQogICAgLyogV2Ugd2lsbCBoYXZlIGFscmVhZHkgY29tcGxhaW5lZC4gICovCiAgICBpbml0ID0gTlVMTF9UUkVFOwogIGVsc2UgaWYgKGluaXQgJiYgQ09NUExFVEVfVFlQRV9QICh0eXBlKQoJICAgJiYgIVRSRUVfQ09OU1RBTlQgKFRZUEVfU0laRSAodHlwZSkpKQogICAgewogICAgICBlcnJvciAoInZhcmlhYmxlLXNpemVkIG9iamVjdCAlcUQgbWF5IG5vdCBiZSBpbml0aWFsaXplZCIsIGRlY2wpOwogICAgICBpbml0ID0gTlVMTF9UUkVFOwogICAgfQogIGVsc2UgaWYgKFRSRUVfQ09ERSAodHlwZSkgPT0gQVJSQVlfVFlQRQoJICAgJiYgIUNPTVBMRVRFX1RZUEVfUCAoY29tcGxldGVfdHlwZSAoVFJFRV9UWVBFICh0eXBlKSkpKQogICAgewogICAgICBlcnJvciAoImVsZW1lbnRzIG9mIGFycmF5ICVxI0QgaGF2ZSBpbmNvbXBsZXRlIHR5cGUiLCBkZWNsKTsKICAgICAgaW5pdCA9IE5VTExfVFJFRTsKICAgIH0KICBlbHNlIGlmIChUUkVFX0NPREUgKHR5cGUpICE9IEFSUkFZX1RZUEUgJiYgIUNPTVBMRVRFX1RZUEVfUCAodHlwZSkpCiAgICB7CiAgICAgIGVycm9yICgiJXFEIGhhcyBpbmNvbXBsZXRlIHR5cGUiLCBkZWNsKTsKICAgICAgVFJFRV9UWVBFIChkZWNsKSA9IGVycm9yX21hcmtfbm9kZTsKICAgICAgaW5pdCA9IE5VTExfVFJFRTsKICAgIH0KCiAgaWYgKFRSRUVfQ09ERSAoZGVjbCkgPT0gQ09OU1RfREVDTCkKICAgIHsKICAgICAgZ2NjX2Fzc2VydCAoVFJFRV9DT0RFIChkZWNsKSAhPSBSRUZFUkVOQ0VfVFlQRSk7CgogICAgICBERUNMX0lOSVRJQUwgKGRlY2wpID0gaW5pdDsKCiAgICAgIGdjY19hc3NlcnQgKGluaXQgIT0gTlVMTF9UUkVFKTsKICAgICAgaW5pdCA9IE5VTExfVFJFRTsKICAgIH0KICBlbHNlIGlmICghREVDTF9FWFRFUk5BTCAoZGVjbCkgJiYgVFJFRV9DT0RFICh0eXBlKSA9PSBSRUZFUkVOQ0VfVFlQRSkKICAgIGluaXQgPSBncm9rX3JlZmVyZW5jZV9pbml0IChkZWNsLCB0eXBlLCBpbml0LCBjbGVhbnVwKTsKICBlbHNlIGlmIChpbml0KQogICAgewogICAgICBpZiAoVFJFRV9DT0RFIChpbml0KSA9PSBDT05TVFJVQ1RPUgoJICAmJiBCUkFDRV9FTkNMT1NFRF9JTklUSUFMSVpFUl9QIChpbml0KSkKCXsKCSAgLyogW2RjbC5pbml0XSBwYXJhZ3JhcGggMTMsCgkgICAgIElmIFQgaXMgYSBzY2FsYXIgdHlwZSwgdGhlbiBhIGRlY2xhcmF0aW9uIG9mIHRoZSBmb3JtCgkgICAgIFQgeCA9IHsgYSB9OwoJICAgICBpcyBlcXVpdmFsZW50IHRvCgkgICAgIFQgeCA9IGE7CgoJICAgICByZXNoYXBlX2luaXQgd2lsbCBjb21wbGFpbiBhYm91dCB0aGUgZXh0cmEgYnJhY2VzLAoJICAgICBhbmQgZG9lc24ndCBkbyBhbnl0aGluZyB1c2VmdWwgaW4gdGhlIGNhc2Ugd2hlcmUgVFlQRSBpcwoJICAgICBzY2FsYXIsIHNvIGp1c3QgZG9uJ3QgY2FsbCBpdC4gICovCgkgIGlmIChDUF9BR0dSRUdBVEVfVFlQRV9QICh0eXBlKSkKCSAgICBpbml0ID0gcmVzaGFwZV9pbml0ICh0eXBlLCAmaW5pdCk7CgoJICBpZiAoKCp0YXJnZXRtLnZlY3Rvcl9vcGFxdWVfcCkgKHR5cGUpKQoJICAgIHsKCSAgICAgIGVycm9yICgib3BhcXVlIHZlY3RvciB0eXBlcyBjYW5ub3QgYmUgaW5pdGlhbGl6ZWQiKTsKCSAgICAgIGluaXQgPSBlcnJvcl9tYXJrX25vZGU7CgkgICAgfQoJfQoKICAgICAgLyogSWYgREVDTCBoYXMgYW4gYXJyYXkgdHlwZSB3aXRob3V0IGEgc3BlY2lmaWMgYm91bmQsIGRlZHVjZSB0aGUKCSBhcnJheSBzaXplIGZyb20gdGhlIGluaXRpYWxpemVyLiAgKi8KICAgICAgbWF5YmVfZGVkdWNlX3NpemVfZnJvbV9hcnJheV9pbml0IChkZWNsLCBpbml0KTsKICAgICAgdHlwZSA9IFRSRUVfVFlQRSAoZGVjbCk7CgogICAgICBpZiAoVFlQRV9IQVNfQ09OU1RSVUNUT1IgKHR5cGUpIHx8IFRZUEVfTkVFRFNfQ09OU1RSVUNUSU5HICh0eXBlKSkKCXsKCSAgaWYgKFRSRUVfQ09ERSAodHlwZSkgPT0gQVJSQVlfVFlQRSkKCSAgICBnb3RvIGluaXRpYWxpemVfYWdncjsKCSAgZWxzZSBpZiAoVFJFRV9DT0RFIChpbml0KSA9PSBDT05TVFJVQ1RPUgoJCSAgICYmIEJSQUNFX0VOQ0xPU0VEX0lOSVRJQUxJWkVSX1AgKGluaXQpKQoJICAgIHsKCSAgICAgIGlmIChUWVBFX05PTl9BR0dSRUdBVEVfQ0xBU1MgKHR5cGUpKQoJCXsKCQkgIGVycm9yICgiJXFEIG11c3QgYmUgaW5pdGlhbGl6ZWQgYnkgY29uc3RydWN0b3IsICIKICAgICAgICAgICAgICAgICAgICAgICAgICJub3QgYnkgJTx7Li4ufSU+IiwKCQkJIGRlY2wpOwoJCSAgaW5pdCA9IGVycm9yX21hcmtfbm9kZTsKCQl9CgkgICAgICBlbHNlCgkJZ290byBkb250X3VzZV9jb25zdHJ1Y3RvcjsKCSAgICB9CgkgIGVsc2UKCSAgICB7CgkgICAgICBpbnQgc2F2ZWRfc3RtdHNfYXJlX2Z1bGxfZXhwcnNfcDsKCgkgICAgaW5pdGlhbGl6ZV9hZ2dyOgoJICAgICAgc2F2ZWRfc3RtdHNfYXJlX2Z1bGxfZXhwcnNfcCA9IDA7CgkgICAgICBpZiAoYnVpbGRpbmdfc3RtdF90cmVlICgpKQoJCXsKCQkgIHNhdmVkX3N0bXRzX2FyZV9mdWxsX2V4cHJzX3AgPSBzdG10c19hcmVfZnVsbF9leHByc19wICgpOwoJCSAgY3VycmVudF9zdG10X3RyZWUgKCktPnN0bXRzX2FyZV9mdWxsX2V4cHJzX3AgPSAxOwoJCX0KCSAgICAgIGluaXQgPSBidWlsZF9hZ2dyX2luaXQgKGRlY2wsIGluaXQsIGZsYWdzKTsKCSAgICAgIGlmIChidWlsZGluZ19zdG10X3RyZWUgKCkpCgkJY3VycmVudF9zdG10X3RyZWUgKCktPnN0bXRzX2FyZV9mdWxsX2V4cHJzX3AgPQoJCSAgc2F2ZWRfc3RtdHNfYXJlX2Z1bGxfZXhwcnNfcDsKCSAgICAgIHJldHVybiBpbml0OwoJICAgIH0KCX0KICAgICAgZWxzZQoJewoJZG9udF91c2VfY29uc3RydWN0b3I6CgkgIGlmIChUUkVFX0NPREUgKGluaXQpICE9IFRSRUVfVkVDKQoJICAgIHsKCSAgICAgIGluaXRfY29kZSA9IHN0b3JlX2luaXRfdmFsdWUgKGRlY2wsIGluaXQpOwoJICAgICAgaWYgKHBlZGFudGljICYmIFRSRUVfQ09ERSAodHlwZSkgPT0gQVJSQVlfVFlQRQoJCSAgJiYgREVDTF9JTklUSUFMIChkZWNsKQoJCSAgJiYgVFJFRV9DT0RFIChERUNMX0lOSVRJQUwgKGRlY2wpKSA9PSBTVFJJTkdfQ1NUCgkJICAmJiBQQVJFTl9TVFJJTkdfTElURVJBTF9QIChERUNMX0lOSVRJQUwgKGRlY2wpKSkKCQl3YXJuaW5nICgiYXJyYXkgJXFEIGluaXRpYWxpemVkIGJ5IHBhcmVudGhlc2l6ZWQgc3RyaW5nIGxpdGVyYWwgJXFFIiwKCQkJIGRlY2wsIERFQ0xfSU5JVElBTCAoZGVjbCkpOwoJICAgICAgaW5pdCA9IE5VTEw7CgkgICAgfQoJfQogICAgfQogIGVsc2UgaWYgKERFQ0xfRVhURVJOQUwgKGRlY2wpKQogICAgOwogIGVsc2UgaWYgKFRZUEVfUCAodHlwZSkgJiYgVFlQRV9ORUVEU19DT05TVFJVQ1RJTkcgKHR5cGUpKQogICAgZ290byBpbml0aWFsaXplX2FnZ3I7CiAgZWxzZSBpZiAoSVNfQUdHUl9UWVBFICh0eXBlKSkKICAgIHsKICAgICAgdHJlZSBjb3JlX3R5cGUgPSBzdHJpcF9hcnJheV90eXBlcyAodHlwZSk7CgogICAgICBpZiAoQ0xBU1NUWVBFX1JFQURPTkxZX0ZJRUxEU19ORUVEX0lOSVQgKGNvcmVfdHlwZSkpCgllcnJvciAoInN0cnVjdHVyZSAlcUQgd2l0aCB1bmluaXRpYWxpemVkIGNvbnN0IG1lbWJlcnMiLCBkZWNsKTsKICAgICAgaWYgKENMQVNTVFlQRV9SRUZfRklFTERTX05FRURfSU5JVCAoY29yZV90eXBlKSkKCWVycm9yICgic3RydWN0dXJlICVxRCB3aXRoIHVuaW5pdGlhbGl6ZWQgcmVmZXJlbmNlIG1lbWJlcnMiLCBkZWNsKTsKCiAgICAgIGNoZWNrX2Zvcl91bmluaXRpYWxpemVkX2NvbnN0X3ZhciAoZGVjbCk7CiAgICB9CiAgZWxzZQogICAgY2hlY2tfZm9yX3VuaW5pdGlhbGl6ZWRfY29uc3RfdmFyIChkZWNsKTsKCiAgaWYgKGluaXQgJiYgaW5pdCAhPSBlcnJvcl9tYXJrX25vZGUpCiAgICBpbml0X2NvZGUgPSBidWlsZDIgKElOSVRfRVhQUiwgdHlwZSwgZGVjbCwgaW5pdCk7CgogIHJldHVybiBpbml0X2NvZGU7Cn0KCi8qIElmIERFQ0wgaXMgbm90IGEgbG9jYWwgdmFyaWFibGUsIGdpdmUgaXQgUlRMLiAgKi8KCnN0YXRpYyB2b2lkCm1ha2VfcnRsX2Zvcl9ub25sb2NhbF9kZWNsICh0cmVlIGRlY2wsIHRyZWUgaW5pdCwgY29uc3QgY2hhciogYXNtc3BlYykKewogIGludCB0b3BsZXYgPSB0b3BsZXZlbF9iaW5kaW5nc19wICgpOwogIGludCBkZWZlcl9wOwoKICAvKiBTZXQgdGhlIERFQ0xfQVNTRU1CTEVSX05BTUUgZm9yIHRoZSBvYmplY3QuICAqLwogIGlmIChhc21zcGVjKQogICAgewogICAgICAvKiBUaGUgYHJlZ2lzdGVyJyBrZXl3b3JkLCB3aGVuIHVzZWQgdG9nZXRoZXIgd2l0aCBhbgoJIGFzbS1zcGVjaWZpY2F0aW9uLCBpbmRpY2F0ZXMgdGhhdCB0aGUgdmFyaWFibGUgc2hvdWxkIGJlCgkgcGxhY2VkIGluIGEgcGFydGljdWxhciByZWdpc3Rlci4gICovCiAgICAgIGlmIChUUkVFX0NPREUgKGRlY2wpID09IFZBUl9ERUNMICYmIERFQ0xfUkVHSVNURVIgKGRlY2wpKQoJewoJICBjaGFuZ2VfZGVjbF9hc3NlbWJsZXJfbmFtZSAoZGVjbCwgZ2V0X2lkZW50aWZpZXIgKGFzbXNwZWMpKTsKCSAgREVDTF9IQVJEX1JFR0lTVEVSIChkZWNsKSA9IDE7Cgl9CiAgICAgIGVsc2UKCXsKCSAgaWYgKFRSRUVfQ09ERSAoZGVjbCkgPT0gRlVOQ1RJT05fREVDTAoJICAgICAgJiYgREVDTF9CVUlMVF9JTl9DTEFTUyAoZGVjbCkgPT0gQlVJTFRfSU5fTk9STUFMKQoJICAgIHNldF9idWlsdGluX3VzZXJfYXNzZW1ibGVyX25hbWUgKGRlY2wsIGFzbXNwZWMpOwoJICBzZXRfdXNlcl9hc3NlbWJsZXJfbmFtZSAoZGVjbCwgYXNtc3BlYyk7Cgl9CiAgICB9CgogIC8qIEhhbmRsZSBub24tdmFyaWFibGVzIHVwIGZyb250LiAgKi8KICBpZiAoVFJFRV9DT0RFIChkZWNsKSAhPSBWQVJfREVDTCkKICAgIHsKICAgICAgcmVzdF9vZl9kZWNsX2NvbXBpbGF0aW9uIChkZWNsLCB0b3BsZXYsIGF0X2VvZik7CiAgICAgIHJldHVybjsKICAgIH0KCiAgLyogSWYgd2Ugc2VlIGEgY2xhc3MgbWVtYmVyIGhlcmUsIGl0IHNob3VsZCBiZSBhIHN0YXRpYyBkYXRhCiAgICAgbWVtYmVyLiAgKi8KICBpZiAoREVDTF9MQU5HX1NQRUNJRklDIChkZWNsKSAmJiBERUNMX0lOX0FHR1JfUCAoZGVjbCkpCiAgICB7CiAgICAgIGdjY19hc3NlcnQgKFRSRUVfU1RBVElDIChkZWNsKSk7CiAgICAgIC8qIEFuIGluLWNsYXNzIGRlY2xhcmF0aW9uIG9mIGEgc3RhdGljIGRhdGEgbWVtYmVyIHNob3VsZCBiZQoJIGV4dGVybmFsOyBpdCBpcyBvbmx5IGEgZGVjbGFyYXRpb24sIGFuZCBub3QgYSBkZWZpbml0aW9uLiAgKi8KICAgICAgaWYgKGluaXQgPT0gTlVMTF9UUkVFKQoJZ2NjX2Fzc2VydCAoREVDTF9FWFRFUk5BTCAoZGVjbCkpOwogICAgfQoKICAvKiBXZSBkb24ndCBjcmVhdGUgYW55IFJUTCBmb3IgbG9jYWwgdmFyaWFibGVzLiAgKi8KICBpZiAoREVDTF9GVU5DVElPTl9TQ09QRV9QIChkZWNsKSAmJiAhVFJFRV9TVEFUSUMgKGRlY2wpKQogICAgcmV0dXJuOwoKICAvKiBXZSBkZWZlciBlbWlzc2lvbiBvZiBsb2NhbCBzdGF0aWNzIHVudGlsIHRoZSBjb3JyZXNwb25kaW5nCiAgICAgREVDTF9FWFBSIGlzIGV4cGFuZGVkLiAgKi8KICBkZWZlcl9wID0gREVDTF9GVU5DVElPTl9TQ09QRV9QIChkZWNsKSB8fCBERUNMX1ZJUlRVQUxfUCAoZGVjbCk7CgogIC8qIFdlIHRyeSB0byBkZWZlciBuYW1lc3BhY2Utc2NvcGUgc3RhdGljIGNvbnN0YW50cyBzbyB0aGF0IHRoZXkgYXJlCiAgICAgbm90IGVtaXR0ZWQgaW50byB0aGUgb2JqZWN0IGZpbGUgdW5uZWNlc3NhcmlseS4gICovCiAgaWYgKCFERUNMX1ZJUlRVQUxfUCAoZGVjbCkKICAgICAgJiYgVFJFRV9SRUFET05MWSAoZGVjbCkKICAgICAgJiYgREVDTF9JTklUSUFMIChkZWNsKSAhPSBOVUxMX1RSRUUKICAgICAgJiYgREVDTF9JTklUSUFMIChkZWNsKSAhPSBlcnJvcl9tYXJrX25vZGUKICAgICAgJiYgISBFTVBUWV9DT05TVFJVQ1RPUl9QIChERUNMX0lOSVRJQUwgKGRlY2wpKQogICAgICAmJiB0b3BsZXYKICAgICAgJiYgIVRSRUVfUFVCTElDIChkZWNsKSkKICAgIHsKICAgICAgLyogRm9vbCB3aXRoIHRoZSBsaW5rYWdlIG9mIHN0YXRpYyBjb25zdHMgYWNjb3JkaW5nIHRvICNwcmFnbWEKCSBpbnRlcmZhY2UuICAqLwogICAgICBzdHJ1Y3QgY19maWxlaW5mbyAqZmluZm8gPSBnZXRfZmlsZWluZm8gKGxiYXNlbmFtZSAoaW5wdXRfZmlsZW5hbWUpKTsKICAgICAgaWYgKCFmaW5mby0+aW50ZXJmYWNlX3Vua25vd24gJiYgIVRSRUVfUFVCTElDIChkZWNsKSkKCXsKCSAgVFJFRV9QVUJMSUMgKGRlY2wpID0gMTsKCSAgREVDTF9FWFRFUk5BTCAoZGVjbCkgPSBmaW5mby0+aW50ZXJmYWNlX29ubHk7Cgl9CgogICAgICBkZWZlcl9wID0gMTsKICAgIH0KICAvKiBMaWtld2lzZSBmb3IgdGVtcGxhdGUgaW5zdGFudGlhdGlvbnMuICAqLwogIGVsc2UgaWYgKERFQ0xfTEFOR19TUEVDSUZJQyAoZGVjbCkKCSAgICYmIERFQ0xfSU1QTElDSVRfSU5TVEFOVElBVElPTiAoZGVjbCkpCiAgICBkZWZlcl9wID0gMTsKCgogIC8qIEFQUExFIExPQ0FMIGJlZ2luIHN0YXRpYyBjb25zdCBtZW1iZXJzICAyMDAyMDExMCAtLXR1cmx5ICAqLwogIC8qIFN0YXRpYyBjb25zdCBtZW1iZXJzIHdoaWNoIHJlcXVpcmUgcnVudGltZSBpbml0aWFsaXNhdGlvbiBzaG91bGQKICAgICBub3QgYmUgcGxhY2VkIGluIHJlYWRvbmx5IG1lbW9yeS4gIEF2b2lkIHRoaXMgYnkgdGVtcG9yYXJpbHkKICAgICB3aGFja2luZyB0aGUgVFJFRV9SRUFET05MWSBiaXQuICAqLwogIGlmICghZGVmZXJfcCAmJiBpbml0ICE9IE5VTExfVFJFRSAmJiBUUkVFX1JFQURPTkxZIChkZWNsKSAmJiB0b3BsZXYpCiAgICB7CiAgICAgIFRSRUVfUkVBRE9OTFkgKGRlY2wpID0gMDsKICAgICAgcmVzdF9vZl9kZWNsX2NvbXBpbGF0aW9uIChkZWNsLCB0b3BsZXYsIGF0X2VvZik7CiAgICAgIFRSRUVfUkVBRE9OTFkgKGRlY2wpID0gMTsKICAgIH0KICBlbHNlCiAgLyogQVBQTEUgTE9DQUwgZW5kIHN0YXRpYyBjb25zdCBtZW1iZXJzICAyMDAyMDExMCAtLXR1cmx5ICAqLwogIGlmICghZGVmZXJfcCkKICAgIHJlc3Rfb2ZfZGVjbF9jb21waWxhdGlvbiAoZGVjbCwgdG9wbGV2LCBhdF9lb2YpOwp9CgovKiBHZW5lcmF0ZSBjb2RlIHRvIGluaXRpYWxpemUgREVDTCAoYSBsb2NhbCB2YXJpYWJsZSkuICAqLwoKc3RhdGljIHZvaWQKaW5pdGlhbGl6ZV9sb2NhbF92YXIgKHRyZWUgZGVjbCwgdHJlZSBpbml0KQp7CiAgdHJlZSB0eXBlID0gVFJFRV9UWVBFIChkZWNsKTsKICB0cmVlIGNsZWFudXA7CgogIGdjY19hc3NlcnQgKFRSRUVfQ09ERSAoZGVjbCkgPT0gVkFSX0RFQ0wKCSAgICAgIHx8IFRSRUVfQ09ERSAoZGVjbCkgPT0gUkVTVUxUX0RFQ0wpOwogIGdjY19hc3NlcnQgKCFUUkVFX1NUQVRJQyAoZGVjbCkpOwoKICBpZiAoREVDTF9TSVpFIChkZWNsKSA9PSBOVUxMX1RSRUUpCiAgICB7CiAgICAgIC8qIElmIHdlIHVzZWQgaXQgYWxyZWFkeSBhcyBtZW1vcnksIGl0IG11c3Qgc3RheSBpbiBtZW1vcnkuICAqLwogICAgICBERUNMX0lOSVRJQUwgKGRlY2wpID0gTlVMTF9UUkVFOwogICAgICBUUkVFX0FERFJFU1NBQkxFIChkZWNsKSA9IFRSRUVfVVNFRCAoZGVjbCk7CiAgICB9CgogIGlmIChERUNMX1NJWkUgKGRlY2wpICYmIHR5cGUgIT0gZXJyb3JfbWFya19ub2RlKQogICAgewogICAgICBpbnQgYWxyZWFkeV91c2VkOwoKICAgICAgLyogQ29tcHV0ZSBhbmQgc3RvcmUgdGhlIGluaXRpYWwgdmFsdWUuICAqLwogICAgICBhbHJlYWR5X3VzZWQgPSBUUkVFX1VTRUQgKGRlY2wpIHx8IFRSRUVfVVNFRCAodHlwZSk7CgogICAgICAvKiBQZXJmb3JtIHRoZSBpbml0aWFsaXphdGlvbi4gICovCiAgICAgIGlmIChpbml0KQoJewoJICBpbnQgc2F2ZWRfc3RtdHNfYXJlX2Z1bGxfZXhwcnNfcDsKCgkgIGdjY19hc3NlcnQgKGJ1aWxkaW5nX3N0bXRfdHJlZSAoKSk7CgkgIHNhdmVkX3N0bXRzX2FyZV9mdWxsX2V4cHJzX3AgPSBzdG10c19hcmVfZnVsbF9leHByc19wICgpOwoJICBjdXJyZW50X3N0bXRfdHJlZSAoKS0+c3RtdHNfYXJlX2Z1bGxfZXhwcnNfcCA9IDE7CgkgIGZpbmlzaF9leHByX3N0bXQgKGluaXQpOwoJICBjdXJyZW50X3N0bXRfdHJlZSAoKS0+c3RtdHNfYXJlX2Z1bGxfZXhwcnNfcCA9CgkgICAgc2F2ZWRfc3RtdHNfYXJlX2Z1bGxfZXhwcnNfcDsKCX0KCiAgICAgIC8qIFNldCB0aGlzIHRvIDAgc28gd2UgY2FuIHRlbGwgd2hldGhlciBhbiBhZ2dyZWdhdGUgd2hpY2ggd2FzCgkgaW5pdGlhbGl6ZWQgd2FzIGV2ZXIgdXNlZC4gIERvbid0IGRvIHRoaXMgaWYgaXQgaGFzIGEKCSBkZXN0cnVjdG9yLCBzbyB3ZSBkb24ndCBjb21wbGFpbiBhYm91dCB0aGUgJ3Jlc291cmNlCgkgYWxsb2NhdGlvbiBpcyBpbml0aWFsaXphdGlvbicgaWRpb20uICBOb3cgc2V0CgkgYXR0cmlidXRlKCh1bnVzZWQpKSBvbiB0eXBlcyBzbyBkZWNscyBvZiB0aGF0IHR5cGUgd2lsbCBiZQoJIG1hcmtlZCB1c2VkLiAoc2VlIFRSRUVfVVNFRCwgYWJvdmUuKSAgKi8KICAgICAgaWYgKFRZUEVfTkVFRFNfQ09OU1RSVUNUSU5HICh0eXBlKQoJICAmJiAhIGFscmVhZHlfdXNlZAoJICAmJiBUWVBFX0hBU19UUklWSUFMX0RFU1RSVUNUT1IgKHR5cGUpCgkgICYmIERFQ0xfTkFNRSAoZGVjbCkpCglUUkVFX1VTRUQgKGRlY2wpID0gMDsKICAgICAgZWxzZSBpZiAoYWxyZWFkeV91c2VkKQoJVFJFRV9VU0VEIChkZWNsKSA9IDE7CiAgICB9CgogIC8qIEdlbmVyYXRlIGEgY2xlYW51cCwgaWYgbmVjZXNzYXJ5LiAgKi8KICBjbGVhbnVwID0gY3h4X21heWJlX2J1aWxkX2NsZWFudXAgKGRlY2wpOwogIGlmIChERUNMX1NJWkUgKGRlY2wpICYmIGNsZWFudXApCiAgICBmaW5pc2hfZGVjbF9jbGVhbnVwIChkZWNsLCBjbGVhbnVwKTsKfQoKLyogREVDTCBpcyBhIFZBUl9ERUNMIGZvciBhIGNvbXBpbGVyLWdlbmVyYXRlZCB2YXJpYWJsZSB3aXRoIHN0YXRpYwogICBzdG9yYWdlIGR1cmF0aW9uIChsaWtlIGEgdmlydHVhbCB0YWJsZSkgd2hvc2UgaW5pdGlhbGl6ZXIgaXMgYQogICBjb21waWxlLXRpbWUgY29uc3RhbnQuICBJbml0aWFsaXplIHRoZSB2YXJpYWJsZSBhbmQgcHJvdmlkZSBpdCB0bwogICB0aGUgYmFjayBlbmQuICAqLwoKdm9pZAppbml0aWFsaXplX2FydGlmaWNpYWxfdmFyICh0cmVlIGRlY2wsIHRyZWUgaW5pdCkKewogIERFQ0xfSU5JVElBTCAoZGVjbCkgPSBidWlsZF9jb25zdHJ1Y3RvciAoTlVMTF9UUkVFLCBpbml0KTsKICBERUNMX0lOSVRJQUxJWkVEX1AgKGRlY2wpID0gMTsKICBkZXRlcm1pbmVfdmlzaWJpbGl0eSAoZGVjbCk7CiAgbGF5b3V0X3Zhcl9kZWNsIChkZWNsKTsKICBtYXliZV9jb21tb25pemVfdmFyIChkZWNsKTsKICBtYWtlX3J0bF9mb3Jfbm9ubG9jYWxfZGVjbCAoZGVjbCwgaW5pdCwgLyphc21zcGVjPSovTlVMTCk7Cn0KCi8qIEZpbmlzaCBwcm9jZXNzaW5nIG9mIGEgZGVjbGFyYXRpb247CiAgIGluc3RhbGwgaXRzIGxpbmUgbnVtYmVyIGFuZCBpbml0aWFsIHZhbHVlLgogICBJZiB0aGUgbGVuZ3RoIG9mIGFuIGFycmF5IHR5cGUgaXMgbm90IGtub3duIGJlZm9yZSwKICAgaXQgbXVzdCBiZSBkZXRlcm1pbmVkIG5vdywgZnJvbSB0aGUgaW5pdGlhbCB2YWx1ZSwgb3IgaXQgaXMgYW4gZXJyb3IuCgogICBJTklUIGhvbGRzIHRoZSB2YWx1ZSBvZiBhbiBpbml0aWFsaXplciB0aGF0IHNob3VsZCBiZSBhbGxvd2VkIHRvIGVzY2FwZQogICB0aGUgbm9ybWFsIHJ1bGVzLgoKICAgRkxBR1MgaXMgTE9PS1VQX09OTFlDT05WRVJUSU5HIGlmIHRoZSA9IGluaXQgc3ludGF4IHdhcyB1c2VkLCBlbHNlIDAKICAgaWYgdGhlIChpbml0KSBzeW50YXggd2FzIHVzZWQuICAqLwoKdm9pZApjcF9maW5pc2hfZGVjbCAodHJlZSBkZWNsLCB0cmVlIGluaXQsIHRyZWUgYXNtc3BlY190cmVlLCBpbnQgZmxhZ3MpCnsKICB0cmVlIHR5cGU7CiAgdHJlZSB0dHlwZSA9IE5VTExfVFJFRTsKICB0cmVlIGNsZWFudXA7CiAgY29uc3QgY2hhciAqYXNtc3BlYyA9IE5VTEw7CiAgaW50IHdhc19yZWFkb25seSA9IDA7CiAgYm9vbCB2YXJfZGVmaW5pdGlvbl9wID0gZmFsc2U7CgogIGlmIChkZWNsID09IGVycm9yX21hcmtfbm9kZSkKICAgIHJldHVybjsKICBlbHNlIGlmICghIGRlY2wpCiAgICB7CiAgICAgIGlmIChpbml0KQoJZXJyb3IgKCJhc3NpZ25tZW50IChub3QgaW5pdGlhbGl6YXRpb24pIGluIGRlY2xhcmF0aW9uIik7CiAgICAgIHJldHVybjsKICAgIH0KCiAgZ2NjX2Fzc2VydCAoVFJFRV9DT0RFIChkZWNsKSAhPSBSRVNVTFRfREVDTCk7CgogIC8qIEFzc3VtZSBubyBjbGVhbnVwIGlzIHJlcXVpcmVkLiAgKi8KICBjbGVhbnVwID0gTlVMTF9UUkVFOwoKICAvKiBJZiBhIG5hbWUgd2FzIHNwZWNpZmllZCwgZ2V0IHRoZSBzdHJpbmcuICAqLwogIGlmIChnbG9iYWxfc2NvcGVfcCAoY3VycmVudF9iaW5kaW5nX2xldmVsKSkKICAgIGFzbXNwZWNfdHJlZSA9IG1heWJlX2FwcGx5X3JlbmFtaW5nX3ByYWdtYSAoZGVjbCwgYXNtc3BlY190cmVlKTsKICBpZiAoYXNtc3BlY190cmVlKQogICAgYXNtc3BlYyA9IFRSRUVfU1RSSU5HX1BPSU5URVIgKGFzbXNwZWNfdHJlZSk7CgogIGlmIChpbml0ICYmIFRSRUVfQ09ERSAoaW5pdCkgPT0gTkFNRVNQQUNFX0RFQ0wpCiAgICB7CiAgICAgIGVycm9yICgiY2Fubm90IGluaXRpYWxpemUgJXFEIHRvIG5hbWVzcGFjZSAlcUQiLCBkZWNsLCBpbml0KTsKICAgICAgaW5pdCA9IE5VTExfVFJFRTsKICAgIH0KCiAgaWYgKGN1cnJlbnRfY2xhc3NfdHlwZQogICAgICAmJiBDUF9ERUNMX0NPTlRFWFQgKGRlY2wpID09IGN1cnJlbnRfY2xhc3NfdHlwZQogICAgICAmJiBUWVBFX0JFSU5HX0RFRklORUQgKGN1cnJlbnRfY2xhc3NfdHlwZSkKICAgICAgJiYgKERFQ0xfSU5JVElBTCAoZGVjbCkgfHwgaW5pdCkpCiAgICBERUNMX0lOSVRJQUxJWkVEX0lOX0NMQVNTX1AgKGRlY2wpID0gMTsKCiAgdHlwZSA9IFRSRUVfVFlQRSAoZGVjbCk7CgogIGlmICh0eXBlID09IGVycm9yX21hcmtfbm9kZSkKICAgIGdvdG8gZmluaXNoX2VuZDsKCiAgaWYgKHByb2Nlc3NpbmdfdGVtcGxhdGVfZGVjbCkKICAgIHsKICAgICAgLyogQWRkIHRoaXMgZGVjbGFyYXRpb24gdG8gdGhlIHN0YXRlbWVudC10cmVlLiAgKi8KICAgICAgaWYgKGF0X2Z1bmN0aW9uX3Njb3BlX3AgKCkpCglhZGRfZGVjbF9leHByIChkZWNsKTsKCiAgICAgIGlmIChpbml0ICYmIERFQ0xfSU5JVElBTCAoZGVjbCkpCglERUNMX0lOSVRJQUwgKGRlY2wpID0gaW5pdDsKICAgICAgaWYgKFRSRUVfQ09ERSAoZGVjbCkgPT0gVkFSX0RFQ0wKCSAgJiYgIURFQ0xfUFJFVFRZX0ZVTkNUSU9OX1AgKGRlY2wpCgkgICYmICFkZXBlbmRlbnRfdHlwZV9wIChUUkVFX1RZUEUgKGRlY2wpKSkKCW1heWJlX2RlZHVjZV9zaXplX2Zyb21fYXJyYXlfaW5pdCAoZGVjbCwgaW5pdCk7CiAgICAgIAogICAgICBnb3RvIGZpbmlzaF9lbmQ7CiAgICB9CgogIC8qIFBhcmFtZXRlcnMgYXJlIGhhbmRsZWQgYnkgc3RvcmVfcGFybV9kZWNscywgbm90IGNwX2ZpbmlzaF9kZWNsLiAgKi8KICBnY2NfYXNzZXJ0IChUUkVFX0NPREUgKGRlY2wpICE9IFBBUk1fREVDTCk7CgogIC8qIFRha2UgY2FyZSBvZiBUWVBFX0RFQ0xzIHVwIGZyb250LiAgKi8KICBpZiAoVFJFRV9DT0RFIChkZWNsKSA9PSBUWVBFX0RFQ0wpCiAgICB7CiAgICAgIGlmICh0eXBlICE9IGVycm9yX21hcmtfbm9kZQoJICAmJiBJU19BR0dSX1RZUEUgKHR5cGUpICYmIERFQ0xfTkFNRSAoZGVjbCkpCgl7CgkgIGlmIChUUkVFX1RZUEUgKERFQ0xfTkFNRSAoZGVjbCkpICYmIFRSRUVfVFlQRSAoZGVjbCkgIT0gdHlwZSkKCSAgICB3YXJuaW5nICgic2hhZG93aW5nIHByZXZpb3VzIHR5cGUgZGVjbGFyYXRpb24gb2YgJXEjRCIsIGRlY2wpOwoJICBzZXRfaWRlbnRpZmllcl90eXBlX3ZhbHVlIChERUNMX05BTUUgKGRlY2wpLCBkZWNsKTsKCX0KCiAgICAgIC8qIElmIHdlIGhhdmUgaW5zdGFsbGVkIHRoaXMgYXMgdGhlIGNhbm9uaWNhbCB0eXBlZGVmIGZvciB0aGlzCgkgdHlwZSwgYW5kIHRoYXQgdHlwZSBoYXMgbm90IGJlZW4gZGVmaW5lZCB5ZXQsIGRlbGF5IGVtaXR0aW5nCgkgdGhlIGRlYnVnIGluZm9ybWF0aW9uIGZvciBpdCwgYXMgd2Ugd2lsbCBlbWl0IGl0IGxhdGVyLiAgKi8KICAgICAgaWYgKFRZUEVfTUFJTl9ERUNMIChUUkVFX1RZUEUgKGRlY2wpKSA9PSBkZWNsCgkgICYmICFDT01QTEVURV9UWVBFX1AgKFRSRUVfVFlQRSAoZGVjbCkpKQoJVFlQRV9ERUNMX1NVUFBSRVNTX0RFQlVHIChkZWNsKSA9IDE7CgogICAgICByZXN0X29mX2RlY2xfY29tcGlsYXRpb24gKGRlY2wsIERFQ0xfQ09OVEVYVCAoZGVjbCkgPT0gTlVMTF9UUkVFLAoJCQkJYXRfZW9mKTsKICAgICAgZ290byBmaW5pc2hfZW5kOwogICAgfQoKICBpZiAoVFJFRV9DT0RFIChkZWNsKSAhPSBGVU5DVElPTl9ERUNMKQogICAgdHR5cGUgPSB0YXJnZXRfdHlwZSAodHlwZSk7CgoKICAvKiBBIHJlZmVyZW5jZSB3aWxsIGJlIG1vZGlmaWVkIGhlcmUsIGFzIGl0IGlzIGluaXRpYWxpemVkLiAgKi8KICBpZiAoISBERUNMX0VYVEVSTkFMIChkZWNsKSAKICAgICAgJiYgVFJFRV9SRUFET05MWSAoZGVjbCkKICAgICAgJiYgVFJFRV9DT0RFICh0eXBlKSA9PSBSRUZFUkVOQ0VfVFlQRSkKICAgIHsKICAgICAgd2FzX3JlYWRvbmx5ID0gMTsKICAgICAgVFJFRV9SRUFET05MWSAoZGVjbCkgPSAwOwogICAgfQoKICBpZiAoVFJFRV9DT0RFIChkZWNsKSA9PSBWQVJfREVDTCkKICAgIHsKICAgICAgLyogT25seSBQT0RzIGNhbiBoYXZlIHRocmVhZC1sb2NhbCBzdG9yYWdlLiAgT3RoZXIgdHlwZXMgbWF5IHJlcXVpcmUKCSB2YXJpb3VzIGtpbmRzIG9mIG5vbi10cml2aWFsIGluaXRpYWxpemF0aW9uLiAgKi8KICAgICAgaWYgKERFQ0xfVEhSRUFEX0xPQ0FMIChkZWNsKSAmJiAhcG9kX3R5cGVfcCAoVFJFRV9UWVBFIChkZWNsKSkpCgllcnJvciAoIiVxRCBjYW5ub3QgYmUgdGhyZWFkLWxvY2FsIGJlY2F1c2UgaXQgaGFzIG5vbi1QT0QgdHlwZSAlcVQiLAoJICAgICAgIGRlY2wsIFRSRUVfVFlQRSAoZGVjbCkpOwogICAgICAvKiBDb252ZXJ0IHRoZSBpbml0aWFsaXplciB0byB0aGUgdHlwZSBvZiBERUNMLCBpZiB3ZSBoYXZlIG5vdAoJIGFscmVhZHkgaW5pdGlhbGl6ZWQgREVDTC4gICovCiAgICAgIGlmICghREVDTF9JTklUSUFMSVpFRF9QIChkZWNsKQoJICAvKiBJZiAhREVDTF9FWFRFUk5BTCB0aGVuIERFQ0wgaXMgYmVpbmcgZGVmaW5lZC4gIEluIHRoZQoJICAgICBjYXNlIG9mIGEgc3RhdGljIGRhdGEgbWVtYmVyIGluaXRpYWxpemVkIGluc2lkZSB0aGUKCSAgICAgY2xhc3Mtc3BlY2lmaWVyLCB0aGVyZSBjYW4gYmUgYW4gaW5pdGlhbGl6ZXIgZXZlbiBpZiBERUNMCgkgICAgIGlzICpub3QqIGRlZmluZWQuICAqLwoJICAmJiAoIURFQ0xfRVhURVJOQUwgKGRlY2wpIHx8IGluaXQpKQoJewoJICBpbml0ID0gY2hlY2tfaW5pdGlhbGl6ZXIgKGRlY2wsIGluaXQsIGZsYWdzLCAmY2xlYW51cCk7CgkgIC8qIFRocmVhZC1sb2NhbCBzdG9yYWdlIGNhbm5vdCBiZSBkeW5hbWljYWxseSBpbml0aWFsaXplZC4gICovCgkgIGlmIChERUNMX1RIUkVBRF9MT0NBTCAoZGVjbCkgJiYgaW5pdCkKCSAgICB7CgkgICAgICBlcnJvciAoIiVxRCBpcyB0aHJlYWQtbG9jYWwgYW5kIHNvIGNhbm5vdCBiZSBkeW5hbWljYWxseSAiCgkJICAgICAiaW5pdGlhbGl6ZWQiLCBkZWNsKTsKCSAgICAgIGluaXQgPSBOVUxMX1RSRUU7CgkgICAgfQoJICAvKiBIYW5kbGU6CgoJICAgICBbZGNsLmluaXRdCgoJICAgICBUaGUgbWVtb3J5IG9jY3VwaWVkIGJ5IGFueSBvYmplY3Qgb2Ygc3RhdGljIHN0b3JhZ2UKCSAgICAgZHVyYXRpb24gaXMgemVyby1pbml0aWFsaXplZCBhdCBwcm9ncmFtIHN0YXJ0dXAgYmVmb3JlCgkgICAgIGFueSBvdGhlciBpbml0aWFsaXphdGlvbiB0YWtlcyBwbGFjZS4KCgkgICAgIFdlIGNhbm5vdCBjcmVhdGUgYW4gYXBwcm9wcmlhdGUgaW5pdGlhbGl6ZXIgdW50aWwgYWZ0ZXIKCSAgICAgdGhlIHR5cGUgb2YgREVDTCBpcyBmaW5hbGl6ZWQuICBJZiBERUNMX0lOSVRJQUwgaXMgc2V0LAoJICAgICB0aGVuIHRoZSBERUNMIGlzIHN0YXRpY2FsbHkgaW5pdGlhbGl6ZWQsIGFuZCBhbnkKCSAgICAgbmVjZXNzYXJ5IHplcm8taW5pdGlhbGl6YXRpb24gaGFzIGFscmVhZHkgYmVlbiBwZXJmb3JtZWQuICAqLwoJICBpZiAoVFJFRV9TVEFUSUMgKGRlY2wpICYmICFERUNMX0lOSVRJQUwgKGRlY2wpKQoJICAgIERFQ0xfSU5JVElBTCAoZGVjbCkgPSBidWlsZF96ZXJvX2luaXQgKFRSRUVfVFlQRSAoZGVjbCksCgkJCQkJCSAgIC8qbmVsdHM9Ki9OVUxMX1RSRUUsCgkJCQkJCSAgIC8qc3RhdGljX3N0b3JhZ2VfcD0qL3RydWUpOwoJICAvKiBSZW1lbWJlciB0aGF0IHRoZSBpbml0aWFsaXphdGlvbiBmb3IgdGhpcyB2YXJpYWJsZSBoYXMKCSAgICAgdGFrZW4gcGxhY2UuICAqLwoJICBERUNMX0lOSVRJQUxJWkVEX1AgKGRlY2wpID0gMTsKCSAgLyogVGhpcyBkZWNsYXJhdGlvbiBpcyB0aGUgZGVmaW5pdGlvbiBvZiB0aGlzIHZhcmlhYmxlLAoJICAgICB1bmxlc3Mgd2UgYXJlIGluaXRpYWxpemluZyBhIHN0YXRpYyBkYXRhIG1lbWJlciB3aXRoaW4KCSAgICAgdGhlIGNsYXNzIHNwZWNpZmllci4gICovCgkgIGlmICghREVDTF9FWFRFUk5BTCAoZGVjbCkpCgkgICAgdmFyX2RlZmluaXRpb25fcCA9IHRydWU7CgkgIC8qIFRoZSB2YXJpYWJsZSBpcyBiZWluZyBkZWZpbmVkLCBzbyBkZXRlcm1pbmUgaXRzCgkgICAgIHZpc2liaWxpdHkuICAqLwoJICBkZXRlcm1pbmVfdmlzaWJpbGl0eSAoZGVjbCk7Cgl9CiAgICAgIC8qIElmIHRoZSB2YXJpYWJsZSBoYXMgYW4gYXJyYXkgdHlwZSwgbGF5IG91dCB0aGUgdHlwZSwgZXZlbiBpZgoJIHRoZXJlIGlzIG5vIGluaXRpYWxpemVyLiAgSXQgaXMgdmFsaWQgdG8gaW5kZXggdGhyb3VnaCB0aGUKCSBhcnJheSwgYW5kIHdlIG11c3QgZ2V0IFRZUEVfQUxJR04gc2V0IGNvcnJlY3RseSBvbiB0aGUgYXJyYXkKCSB0eXBlLiAgKi8KICAgICAgZWxzZSBpZiAoVFJFRV9DT0RFICh0eXBlKSA9PSBBUlJBWV9UWVBFKQoJbGF5b3V0X3R5cGUgKHR5cGUpOwogICAgfQoKICAvKiBBZGQgdGhpcyBkZWNsYXJhdGlvbiB0byB0aGUgc3RhdGVtZW50LXRyZWUuICBUaGlzIG5lZWRzIHRvIGhhcHBlbgogICAgIGFmdGVyIHRoZSBjYWxsIHRvIGNoZWNrX2luaXRpYWxpemVyIHNvIHRoYXQgdGhlIERFQ0xfRVhQUiBmb3IgYQogICAgIHJlZmVyZW5jZSB0ZW1wIGlzIGFkZGVkIGJlZm9yZSB0aGUgREVDTF9FWFBSIGZvciB0aGUgcmVmZXJlbmNlIGl0c2VsZi4gICovCiAgaWYgKGF0X2Z1bmN0aW9uX3Njb3BlX3AgKCkpCiAgICBhZGRfZGVjbF9leHByIChkZWNsKTsKCiAgaWYgKFRSRUVfQ09ERSAoZGVjbCkgPT0gVkFSX0RFQ0wpCiAgICBsYXlvdXRfdmFyX2RlY2wgKGRlY2wpOwoKICAvKiBPdXRwdXQgdGhlIGFzc2VtYmxlciBjb2RlIGFuZC9vciBSVEwgY29kZSBmb3IgdmFyaWFibGVzIGFuZCBmdW5jdGlvbnMsCiAgICAgdW5sZXNzIHRoZSB0eXBlIGlzIGFuIHVuZGVmaW5lZCBzdHJ1Y3R1cmUgb3IgdW5pb24uCiAgICAgSWYgbm90LCBpdCB3aWxsIGdldCBkb25lIHdoZW4gdGhlIHR5cGUgaXMgY29tcGxldGVkLiAgKi8KICBpZiAoVFJFRV9DT0RFIChkZWNsKSA9PSBWQVJfREVDTCB8fCBUUkVFX0NPREUgKGRlY2wpID09IEZVTkNUSU9OX0RFQ0wpCiAgICB7CiAgICAgIGlmIChUUkVFX0NPREUgKGRlY2wpID09IFZBUl9ERUNMKQoJbWF5YmVfY29tbW9uaXplX3ZhciAoZGVjbCk7CgogICAgICBtYWtlX3J0bF9mb3Jfbm9ubG9jYWxfZGVjbCAoZGVjbCwgaW5pdCwgYXNtc3BlYyk7CgogICAgICAvKiBDaGVjayBmb3IgYWJzdHJhY3RuZXNzIG9mIHRoZSB0eXBlLiBOb3RpY2UgdGhhdCB0aGVyZSBpcyBubwoJIG5lZWQgdG8gc3RyaXAgYXJyYXkgdHlwZXMgaGVyZSBzaW5jZSB0aGUgY2hlY2sgZm9yIHRob3NlIHR5cGVzCgkgaXMgYWxyZWFkeSBkb25lIHdpdGhpbiBjcmVhdGVfYXJyYXlfdHlwZV9mb3JfZGVjbC4gICovCiAgICAgIGlmIChUUkVFX0NPREUgKHR5cGUpID09IEZVTkNUSU9OX1RZUEUKCSAgfHwgVFJFRV9DT0RFICh0eXBlKSA9PSBNRVRIT0RfVFlQRSkKCWFic3RyYWN0X3ZpcnR1YWxzX2Vycm9yIChkZWNsLCBUUkVFX1RZUEUgKHR5cGUpKTsKICAgICAgZWxzZQoJYWJzdHJhY3RfdmlydHVhbHNfZXJyb3IgKGRlY2wsIHR5cGUpOwoKICAgICAgaWYgKFRSRUVfQ09ERSAoZGVjbCkgPT0gRlVOQ1RJT05fREVDTAoJICB8fCBUUkVFX1RZUEUgKGRlY2wpID09IGVycm9yX21hcmtfbm9kZSkKCS8qIE5vIGluaXRpYWxpemF0aW9uIHJlcXVpcmVkLiAgKi8KCTsKICAgICAgZWxzZSBpZiAoREVDTF9FWFRFUk5BTCAoZGVjbCkKCSAgICAgICAmJiAhIChERUNMX0xBTkdfU1BFQ0lGSUMgKGRlY2wpCgkJICAgICAmJiBERUNMX05PVF9SRUFMTFlfRVhURVJOIChkZWNsKSkpCgl7CgkgIGlmIChpbml0KQoJICAgIERFQ0xfSU5JVElBTCAoZGVjbCkgPSBpbml0OwoJfQogICAgICBlbHNlCgl7CgkgIC8qIEEgdmFyaWFibGUgZGVmaW5pdGlvbi4gICovCgkgIGlmIChERUNMX0ZVTkNUSU9OX1NDT1BFX1AgKGRlY2wpKQoJICAgIHsKCSAgICAgIC8qIEluaXRpYWxpemUgdGhlIGxvY2FsIHZhcmlhYmxlLiAgKi8KCSAgICAgIGlmIChwcm9jZXNzaW5nX3RlbXBsYXRlX2RlY2wpCgkJewoJCSAgaWYgKGluaXQgfHwgREVDTF9JTklUSUFMIChkZWNsKSA9PSBlcnJvcl9tYXJrX25vZGUpCgkJICAgIERFQ0xfSU5JVElBTCAoZGVjbCkgPSBpbml0OwoJCX0KCSAgICAgIGVsc2UgaWYgKCFUUkVFX1NUQVRJQyAoZGVjbCkpCgkJaW5pdGlhbGl6ZV9sb2NhbF92YXIgKGRlY2wsIGluaXQpOwoJICAgIH0KCSAgCgkgIC8qIElmIGEgdmFyaWFibGUgaXMgZGVmaW5lZCwgYW5kIHRoZW4gYSBzdWJzZXF1ZW50CgkgICAgIGRlZmluaXRpb24gd2l0aCBleHRlcm5hbCBsaW5rYWdlIGlzIGVuY291bnRlcmVkLCB3ZSB3aWxsCgkgICAgIGdldCBoZXJlIHR3aWNlIGZvciB0aGUgc2FtZSB2YXJpYWJsZS4gIFdlIHdhbnQgdG8gYXZvaWQKCSAgICAgY2FsbGluZyBleHBhbmRfc3RhdGljX2luaXQgbW9yZSB0aGFuIG9uY2UuICBGb3IgdmFyaWFibGVzCgkgICAgIHRoYXQgYXJlIG5vdCBzdGF0aWMgZGF0YSBtZW1iZXJzLCB3ZSBjYW4gY2FsbAoJICAgICBleHBhbmRfc3RhdGljX2luaXQgb25seSB3aGVuIHdlIGFjdHVhbGx5IHByb2Nlc3MgdGhlCgkgICAgIGluaXRpYWxpemVyLiAgSXQgaXMgbm90IGxlZ2FsIHRvIHJlZGVjbGFyZSBhIHN0YXRpYyBkYXRhCgkgICAgIG1lbWJlciwgc28gdGhpcyBpc3N1ZSBkb2VzIG5vdCBhcmlzZSBpbiB0aGF0IGNhc2UuICAqLwoJICBpZiAodmFyX2RlZmluaXRpb25fcCAmJiBUUkVFX1NUQVRJQyAoZGVjbCkpCgkgICAgZXhwYW5kX3N0YXRpY19pbml0IChkZWNsLCBpbml0KTsgCgl9IAogICAgfQoKICAvKiBJZiBhIENMRUFOVVBfU1RNVCB3YXMgY3JlYXRlZCB0byBkZXN0cm95IGEgdGVtcG9yYXJ5IGJvdW5kIHRvIGEKICAgICByZWZlcmVuY2UsIGluc2VydCBpdCBpbiB0aGUgc3RhdGVtZW50LXRyZWUgbm93LiAgKi8KICBpZiAoY2xlYW51cCkKICAgIHB1c2hfY2xlYW51cCAoZGVjbCwgY2xlYW51cCwgZmFsc2UpOwoKIGZpbmlzaF9lbmQ6CgogIGlmICh3YXNfcmVhZG9ubHkpCiAgICBUUkVFX1JFQURPTkxZIChkZWNsKSA9IDE7CgogIC8qIElmIHRoaXMgd2FzIG1hcmtlZCAndXNlZCcsIGJlIHN1cmUgaXQgd2lsbCBiZSBvdXRwdXQuICAqLwogIGlmIChsb29rdXBfYXR0cmlidXRlICgidXNlZCIsIERFQ0xfQVRUUklCVVRFUyAoZGVjbCkpKQogICAgbWFya19kZWNsX3JlZmVyZW5jZWQgKGRlY2wpOwp9CgovKiBUaGlzIGlzIGhlcmUgZm9yIGEgbWlkZW5kIGNhbGxiYWNrIGZyb20gYy1jb21tb24uYy4gICovCgp2b2lkCmZpbmlzaF9kZWNsICh0cmVlIGRlY2wsIHRyZWUgaW5pdCwgdHJlZSBhc21zcGVjX3RyZWUpCnsKICBjcF9maW5pc2hfZGVjbCAoZGVjbCwgaW5pdCwgYXNtc3BlY190cmVlLCAwKTsKfQoKLyogUmV0dXJucyBhIGRlY2xhcmF0aW9uIGZvciBhIFZBUl9ERUNMIGFzIGlmOgoKICAgICBleHRlcm4gIkMiIFRZUEUgTkFNRTsKCiAgIGhhZCBiZWVuIHNlZW4uICBVc2VkIHRvIGNyZWF0ZSBjb21waWxlci1nZW5lcmF0ZWQgZ2xvYmFsCiAgIHZhcmlhYmxlcy4gICovCgp0cmVlCmRlY2xhcmVfZ2xvYmFsX3ZhciAodHJlZSBuYW1lLCB0cmVlIHR5cGUpCnsKICB0cmVlIGRlY2w7CgogIHB1c2hfdG9fdG9wX2xldmVsICgpOwogIGRlY2wgPSBidWlsZF9kZWNsIChWQVJfREVDTCwgbmFtZSwgdHlwZSk7CiAgVFJFRV9QVUJMSUMgKGRlY2wpID0gMTsKICBERUNMX0VYVEVSTkFMIChkZWNsKSA9IDE7CiAgREVDTF9BUlRJRklDSUFMIChkZWNsKSA9IDE7CiAgLyogSWYgdGhlIHVzZXIgaGFzIGV4cGxpY2l0bHkgZGVjbGFyZWQgdGhpcyB2YXJpYWJsZSAocGVyaGFwcwogICAgIGJlY2F1c2UgdGhlIGNvZGUgd2UgYXJlIGNvbXBpbGluZyBpcyBwYXJ0IG9mIGEgbG93LWxldmVsIHJ1bnRpbWUKICAgICBsaWJyYXJ5KSwgdGhlbiBpdCBpcyBwb3NzaWJsZSB0aGF0IG91ciBkZWNsYXJhdGlvbiB3aWxsIGJlIG1lcmdlZAogICAgIHdpdGggdGhlaXJzIGJ5IHB1c2hkZWNsLiAgKi8KICBkZWNsID0gcHVzaGRlY2wgKGRlY2wpOwogIGNwX2ZpbmlzaF9kZWNsIChkZWNsLCBOVUxMX1RSRUUsIE5VTExfVFJFRSwgMCk7CiAgcG9wX2Zyb21fdG9wX2xldmVsICgpOwoKICByZXR1cm4gZGVjbDsKfQoKLyogUmV0dXJucyBhIHBvaW50ZXIgdG8gdGhlIGBhdGV4aXQnIGZ1bmN0aW9uLiAgTm90ZSB0aGF0IGlmCiAgIEZMQUdfVVNFX0NYQV9BVEVYSVQgaXMgbm9uemVybywgdGhlbiB0aGlzIHdpbGwgYWN0dWFsbHkgYmUgdGhlIG5ldwogICBgX19jeGFfYXRleGl0JyBmdW5jdGlvbiBzcGVjaWZpZWQgaW4gdGhlIElBNjQgQysrIEFCSS4gICovCgpzdGF0aWMgdHJlZQpnZXRfYXRleGl0X25vZGUgKHZvaWQpCnsKICB0cmVlIGF0ZXhpdF9mbmRlY2w7CiAgdHJlZSBhcmdfdHlwZXM7CiAgdHJlZSBmbl90eXBlOwogIHRyZWUgZm5fcHRyX3R5cGU7CiAgY29uc3QgY2hhciAqbmFtZTsKICAvKiBBUFBMRSBMT0NBTCBiZWdpbiBMTFZNICovCiAgYm9vbCB1c2VfYWVhYmlfYXRleGl0OwogIC8qIEFQUExFIExPQ0FMIGVuZCBMTFZNICovCgogIGlmIChhdGV4aXRfbm9kZSkKICAgIHJldHVybiBhdGV4aXRfbm9kZTsKCiAgaWYgKGZsYWdfdXNlX2N4YV9hdGV4aXQpCiAgICB7CiAgICAgIC8qIFRoZSBkZWNsYXJhdGlvbiBmb3IgYF9fY3hhX2F0ZXhpdCcgaXM6CgoJICAgaW50IF9fY3hhX2F0ZXhpdCAodm9pZCAoKikodm9pZCAqKSwgdm9pZCAqLCB2b2lkICopCgoJIFdlIGJ1aWxkIHVwIHRoZSBhcmd1bWVudCB0eXBlcyBhbmQgdGhlbiB0aGVuIGZ1bmN0aW9uIHR5cGUKCSBpdHNlbGYuICAqLwoKICAgICAgLyogQVBQTEUgTE9DQUwgYmVnaW4gTExWTSAqLwogICAgICB1c2VfYWVhYmlfYXRleGl0ID0gdGFyZ2V0bS5jeHgudXNlX2FlYWJpX2F0ZXhpdCAoKTsKICAgICAgLyogQVBQTEUgTE9DQUwgZW5kIExMVk0gKi8KICAgICAgLyogRmlyc3QsIGJ1aWxkIHRoZSBwb2ludGVyLXRvLWZ1bmN0aW9uIHR5cGUgZm9yIHRoZSBmaXJzdAoJIGFyZ3VtZW50LiAgKi8KICAgICAgYXJnX3R5cGVzID0gdHJlZV9jb25zIChOVUxMX1RSRUUsIHB0cl90eXBlX25vZGUsIHZvaWRfbGlzdF9ub2RlKTsKICAgICAgZm5fdHlwZSA9IGJ1aWxkX2Z1bmN0aW9uX3R5cGUgKHZvaWRfdHlwZV9ub2RlLCBhcmdfdHlwZXMpOwogICAgICBmbl9wdHJfdHlwZSA9IGJ1aWxkX3BvaW50ZXJfdHlwZSAoZm5fdHlwZSk7CiAgICAgIC8qIFRoZW4sIGJ1aWxkIHRoZSByZXN0IG9mIHRoZSBhcmd1bWVudCB0eXBlcy4gICovCiAgICAgIGFyZ190eXBlcyA9IHRyZWVfY29ucyAoTlVMTF9UUkVFLCBwdHJfdHlwZV9ub2RlLCB2b2lkX2xpc3Rfbm9kZSk7CiAgICAgIC8qIEFQUExFIExPQ0FMIGJlZ2luIExMVk0gKi8KICAgICAgaWYgKHVzZV9hZWFiaV9hdGV4aXQpCgl7CgkgIGFyZ190eXBlcyA9IHRyZWVfY29ucyAoTlVMTF9UUkVFLCBmbl9wdHJfdHlwZSwgYXJnX3R5cGVzKTsKCSAgYXJnX3R5cGVzID0gdHJlZV9jb25zIChOVUxMX1RSRUUsIHB0cl90eXBlX25vZGUsIGFyZ190eXBlcyk7Cgl9CiAgICAgIGVsc2UKCXsKCSAgYXJnX3R5cGVzID0gdHJlZV9jb25zIChOVUxMX1RSRUUsIHB0cl90eXBlX25vZGUsIGFyZ190eXBlcyk7CgkgIGFyZ190eXBlcyA9IHRyZWVfY29ucyAoTlVMTF9UUkVFLCBmbl9wdHJfdHlwZSwgYXJnX3R5cGVzKTsKCX0KICAgICAgLyogQVBQTEUgTE9DQUwgZW5kIExMVk0gKi8KICAgICAgLyogQW5kIHRoZSBmaW5hbCBfX2N4YV9hdGV4aXQgdHlwZS4gICovCiAgICAgIGZuX3R5cGUgPSBidWlsZF9mdW5jdGlvbl90eXBlIChpbnRlZ2VyX3R5cGVfbm9kZSwgYXJnX3R5cGVzKTsKICAgICAgZm5fcHRyX3R5cGUgPSBidWlsZF9wb2ludGVyX3R5cGUgKGZuX3R5cGUpOwogICAgICAvKiBBUFBMRSBMT0NBTCBiZWdpbiBMTFZNICovCiAgICAgIGlmICh1c2VfYWVhYmlfYXRleGl0KQoJbmFtZSA9ICJfX2FlYWJpX2F0ZXhpdCI7CiAgICAgIGVsc2UKCW5hbWUgPSAiX19jeGFfYXRleGl0IjsKICAgICAgLyogQVBQTEUgTE9DQUwgZW5kIExMVk0gKi8KICAgIH0KICBlbHNlCiAgICB7CiAgICAgIC8qIFRoZSBkZWNsYXJhdGlvbiBmb3IgYGF0ZXhpdCcgaXM6CgogICAgICAgICAgIGludCBhdGV4aXQgKHZvaWQgKCopKCkpOwoKCSBXZSBidWlsZCB1cCB0aGUgYXJndW1lbnQgdHlwZXMgYW5kIHRoZW4gdGhlbiBmdW5jdGlvbiB0eXBlCgkgaXRzZWxmLiAgKi8KICAgICAgZm5fdHlwZSA9IGJ1aWxkX2Z1bmN0aW9uX3R5cGUgKHZvaWRfdHlwZV9ub2RlLCB2b2lkX2xpc3Rfbm9kZSk7CiAgICAgIGZuX3B0cl90eXBlID0gYnVpbGRfcG9pbnRlcl90eXBlIChmbl90eXBlKTsKICAgICAgYXJnX3R5cGVzID0gdHJlZV9jb25zIChOVUxMX1RSRUUsIGZuX3B0cl90eXBlLCB2b2lkX2xpc3Rfbm9kZSk7CiAgICAgIC8qIEJ1aWxkIHRoZSBmaW5hbCBhdGV4aXQgdHlwZS4gICovCiAgICAgIGZuX3R5cGUgPSBidWlsZF9mdW5jdGlvbl90eXBlIChpbnRlZ2VyX3R5cGVfbm9kZSwgYXJnX3R5cGVzKTsKICAgICAgbmFtZSA9ICJhdGV4aXQiOwogICAgfQoKICAvKiBOb3csIGJ1aWxkIHRoZSBmdW5jdGlvbiBkZWNsYXJhdGlvbi4gICovCiAgcHVzaF9sYW5nX2NvbnRleHQgKGxhbmdfbmFtZV9jKTsKICBhdGV4aXRfZm5kZWNsID0gYnVpbGRfbGlicmFyeV9mbl9wdHIgKG5hbWUsIGZuX3R5cGUpOwogIG1hcmtfdXNlZCAoYXRleGl0X2ZuZGVjbCk7CiAgcG9wX2xhbmdfY29udGV4dCAoKTsKICBhdGV4aXRfbm9kZSA9IGRlY2F5X2NvbnZlcnNpb24gKGF0ZXhpdF9mbmRlY2wpOwoKICByZXR1cm4gYXRleGl0X25vZGU7Cn0KCi8qIFJldHVybnMgdGhlIF9fZHNvX2hhbmRsZSBWQVJfREVDTC4gICovCgpzdGF0aWMgdHJlZQpnZXRfZHNvX2hhbmRsZV9ub2RlICh2b2lkKQp7CiAgaWYgKGRzb19oYW5kbGVfbm9kZSkKICAgIHJldHVybiBkc29faGFuZGxlX25vZGU7CgogIC8qIERlY2xhcmUgdGhlIHZhcmlhYmxlLiAgKi8KICBkc29faGFuZGxlX25vZGUgPSBkZWNsYXJlX2dsb2JhbF92YXIgKGdldF9pZGVudGlmaWVyICgiX19kc29faGFuZGxlIiksCgkJCQkJcHRyX3R5cGVfbm9kZSk7CgogIHJldHVybiBkc29faGFuZGxlX25vZGU7Cn0KCi8qIEJlZ2luIGEgbmV3IGZ1bmN0aW9uIHdpdGggaW50ZXJuYWwgbGlua2FnZSB3aG9zZSBqb2Igd2lsbCBiZSBzaW1wbHkKICAgdG8gZGVzdHJveSBzb21lIHBhcnRpY3VsYXIgdmFyaWFibGUuICAqLwoKc3RhdGljIEdUWSgoKSkgaW50IHN0YXJ0X2NsZWFudXBfY250OwoKc3RhdGljIHRyZWUKc3RhcnRfY2xlYW51cF9mbiAodm9pZCkKewogIGNoYXIgbmFtZVszMl07CiAgdHJlZSBwYXJtdHlwZXM7CiAgdHJlZSBmbnR5cGU7CiAgdHJlZSBmbmRlY2w7CgogIHB1c2hfdG9fdG9wX2xldmVsICgpOwoKICAvKiBObyBuZWVkIHRvIG1hbmdsZSB0aGlzLiAgKi8KICBwdXNoX2xhbmdfY29udGV4dCAobGFuZ19uYW1lX2MpOwoKICAvKiBCdWlsZCB0aGUgcGFyYW1ldGVyLXR5cGVzLiAgKi8KICBwYXJtdHlwZXMgPSB2b2lkX2xpc3Rfbm9kZTsKICAvKiBGdW5jdGlvbnMgcGFzc2VkIHRvIF9fY3hhX2F0ZXhpdCB0YWtlIGFuIGFkZGl0aW9uYWwgcGFyYW1ldGVyLgogICAgIFdlJ2xsIGp1c3QgaWdub3JlIGl0LiAgQWZ0ZXIgd2UgaW1wbGVtZW50IHRoZSBuZXcgY2FsbGluZwogICAgIGNvbnZlbnRpb24gZm9yIGRlc3RydWN0b3JzLCB3ZSBjYW4gZWxpbWluYXRlIHRoZSB1c2Ugb2YKICAgICBhZGRpdGlvbmFsIGNsZWFudXAgZnVuY3Rpb25zIGVudGlyZWx5IGluIHRoZSAtZm5ldy1hYmkgY2FzZS4gICovCiAgaWYgKGZsYWdfdXNlX2N4YV9hdGV4aXQpCiAgICBwYXJtdHlwZXMgPSB0cmVlX2NvbnMgKE5VTExfVFJFRSwgcHRyX3R5cGVfbm9kZSwgcGFybXR5cGVzKTsKICAvKiBCdWlsZCB0aGUgZnVuY3Rpb24gdHlwZSBpdHNlbGYuICAqLwogIGZudHlwZSA9IGJ1aWxkX2Z1bmN0aW9uX3R5cGUgKHZvaWRfdHlwZV9ub2RlLCBwYXJtdHlwZXMpOwogIC8qIEJ1aWxkIHRoZSBuYW1lIG9mIHRoZSBmdW5jdGlvbi4gICovCiAgc3ByaW50ZiAobmFtZSwgIl9fdGNmXyVkIiwgc3RhcnRfY2xlYW51cF9jbnQrKyk7CiAgLyogQnVpbGQgdGhlIGZ1bmN0aW9uIGRlY2xhcmF0aW9uLiAgKi8KICBmbmRlY2wgPSBidWlsZF9sYW5nX2RlY2wgKEZVTkNUSU9OX0RFQ0wsIGdldF9pZGVudGlmaWVyIChuYW1lKSwgZm50eXBlKTsKICAvKiBJdCdzIGEgZnVuY3Rpb24gd2l0aCBpbnRlcm5hbCBsaW5rYWdlLCBnZW5lcmF0ZWQgYnkgdGhlCiAgICAgY29tcGlsZXIuICAqLwogIFRSRUVfUFVCTElDIChmbmRlY2wpID0gMDsKICBERUNMX0FSVElGSUNJQUwgKGZuZGVjbCkgPSAxOwogIC8qIE1ha2UgdGhlIGZ1bmN0aW9uIGBpbmxpbmUnIHNvIHRoYXQgaXQgaXMgb25seSBlbWl0dGVkIGlmIGl0IGlzCiAgICAgYWN0dWFsbHkgbmVlZGVkLiAgSXQgaXMgdW5saWtlbHkgdGhhdCBpdCB3aWxsIGJlIGlubGluZWQsIHNpbmNlCiAgICAgaXQgaXMgb25seSBjYWxsZWQgdmlhIGEgZnVuY3Rpb24gcG9pbnRlciwgYnV0IHdlIGF2b2lkIHVubmVjZXNzYXJ5CiAgICAgZW1pc3Npb25zIHRoaXMgd2F5LiAgKi8KICBERUNMX0lOTElORSAoZm5kZWNsKSA9IDE7CiAgREVDTF9ERUNMQVJFRF9JTkxJTkVfUCAoZm5kZWNsKSA9IDE7CiAgREVDTF9JTlRFUkZBQ0VfS05PV04gKGZuZGVjbCkgPSAxOwogIC8qIEJ1aWxkIHRoZSBwYXJhbWV0ZXIuICAqLwogIGlmIChmbGFnX3VzZV9jeGFfYXRleGl0KQogICAgewogICAgICB0cmVlIHBhcm1kZWNsOwoKICAgICAgcGFybWRlY2wgPSBjcF9idWlsZF9wYXJtX2RlY2wgKE5VTExfVFJFRSwgcHRyX3R5cGVfbm9kZSk7CiAgICAgIERFQ0xfQ09OVEVYVCAocGFybWRlY2wpID0gZm5kZWNsOwogICAgICBUUkVFX1VTRUQgKHBhcm1kZWNsKSA9IDE7CiAgICAgIERFQ0xfQVJHVU1FTlRTIChmbmRlY2wpID0gcGFybWRlY2w7CiAgICB9CgogIHB1c2hkZWNsIChmbmRlY2wpOwogIHN0YXJ0X3ByZXBhcnNlZF9mdW5jdGlvbiAoZm5kZWNsLCBOVUxMX1RSRUUsIFNGX1BSRV9QQVJTRUQpOwoKICBwb3BfbGFuZ19jb250ZXh0ICgpOwoKICByZXR1cm4gY3VycmVudF9mdW5jdGlvbl9kZWNsOwp9CgovKiBGaW5pc2ggdGhlIGNsZWFudXAgZnVuY3Rpb24gYmVndW4gYnkgc3RhcnRfY2xlYW51cF9mbi4gICovCgpzdGF0aWMgdm9pZAplbmRfY2xlYW51cF9mbiAodm9pZCkKewogIGV4cGFuZF9vcl9kZWZlcl9mbiAoZmluaXNoX2Z1bmN0aW9uICgwKSk7CgogIHBvcF9mcm9tX3RvcF9sZXZlbCAoKTsKfQoKLyogR2VuZXJhdGUgY29kZSB0byBoYW5kbGUgdGhlIGRlc3RydWN0aW9uIG9mIERFQ0wsIGFuIG9iamVjdCB3aXRoCiAgIHN0YXRpYyBzdG9yYWdlIGR1cmF0aW9uLiAgKi8KCnRyZWUKcmVnaXN0ZXJfZHRvcl9mbiAodHJlZSBkZWNsKQp7CiAgdHJlZSBjbGVhbnVwOwogIHRyZWUgY29tcG91bmRfc3RtdDsKICB0cmVlIGFyZ3M7CiAgdHJlZSBmY2FsbDsKCiAgaWYgKFRZUEVfSEFTX1RSSVZJQUxfREVTVFJVQ1RPUiAoVFJFRV9UWVBFIChkZWNsKSkpCiAgICByZXR1cm4gdm9pZF96ZXJvX25vZGU7CgogIC8qIENhbGwgYnVpbGRfY2xlYW51cCBiZWZvcmUgd2UgZW50ZXIgdGhlIGFub255bW91cyBmdW5jdGlvbiBzbyB0aGF0CiAgICAgYW55IGFjY2VzcyBjaGVja3Mgd2lsbCBiZSBkb25lIHJlbGF0aXZlIHRvIHRoZSBjdXJyZW50IHNjb3BlLAogICAgIHJhdGhlciB0aGFuIHRoZSBzY29wZSBvZiB0aGUgYW5vbnltb3VzIGZ1bmN0aW9uLiAgKi8KICBidWlsZF9jbGVhbnVwIChkZWNsKTsKCiAgLyogTm93IHN0YXJ0IHRoZSBmdW5jdGlvbi4gICovCiAgY2xlYW51cCA9IHN0YXJ0X2NsZWFudXBfZm4gKCk7CgogIC8qIE5vdywgcmVjb21wdXRlIHRoZSBjbGVhbnVwLiAgSXQgbWF5IGNvbnRhaW4gU0FWRV9FWFBScyB0aGF0IHJlZmVyCiAgICAgdG8gdGhlIG9yaWdpbmFsIGZ1bmN0aW9uLCByYXRoZXIgdGhhbiB0aGUgYW5vbnltb3VzIG9uZS4gIFRoYXQKICAgICB3aWxsIG1ha2UgdGhlIGJhY2stZW5kIHRoaW5rIHRoYXQgbmVzdGVkIGZ1bmN0aW9ucyBhcmUgaW4gdXNlLAogICAgIHdoaWNoIGNhdXNlcyBjb25mdXNpb24uICAqLwoKICBwdXNoX2RlZmVycmluZ19hY2Nlc3NfY2hlY2tzIChka19ub19jaGVjayk7CiAgZmNhbGwgPSBidWlsZF9jbGVhbnVwIChkZWNsKTsKICBwb3BfZGVmZXJyaW5nX2FjY2Vzc19jaGVja3MgKCk7CgogIC8qIENyZWF0ZSB0aGUgYm9keSBvZiB0aGUgYW5vbnltb3VzIGZ1bmN0aW9uLiAgKi8KICBjb21wb3VuZF9zdG10ID0gYmVnaW5fY29tcG91bmRfc3RtdCAoQkNTX0ZOX0JPRFkpOwogIGZpbmlzaF9leHByX3N0bXQgKGZjYWxsKTsKICBmaW5pc2hfY29tcG91bmRfc3RtdCAoY29tcG91bmRfc3RtdCk7CiAgZW5kX2NsZWFudXBfZm4gKCk7CgogIC8qIENhbGwgYXRleGl0IHdpdGggdGhlIGNsZWFudXAgZnVuY3Rpb24uICAqLwogIGN4eF9tYXJrX2FkZHJlc3NhYmxlIChjbGVhbnVwKTsKICBtYXJrX3VzZWQgKGNsZWFudXApOwogIGNsZWFudXAgPSBidWlsZF91bmFyeV9vcCAoQUREUl9FWFBSLCBjbGVhbnVwLCAwKTsKICBpZiAoZmxhZ191c2VfY3hhX2F0ZXhpdCkKICAgIHsKICAgICAgYXJncyA9IHRyZWVfY29ucyAoTlVMTF9UUkVFLAoJCQlidWlsZF91bmFyeV9vcCAoQUREUl9FWFBSLCBnZXRfZHNvX2hhbmRsZV9ub2RlICgpLCAwKSwKCQkJTlVMTF9UUkVFKTsKICAgICAgLyogQVBQTEUgTE9DQUwgYmVnaW4gTExWTSAqLwogICAgICBpZiAodGFyZ2V0bS5jeHgudXNlX2FlYWJpX2F0ZXhpdCAoKSkKCXsKCSAgYXJncyA9IHRyZWVfY29ucyAoTlVMTF9UUkVFLCBjbGVhbnVwLCBhcmdzKTsKCSAgYXJncyA9IHRyZWVfY29ucyAoTlVMTF9UUkVFLCBudWxsX3BvaW50ZXJfbm9kZSwgYXJncyk7Cgl9CiAgICAgIGVsc2UKCXsKCSAgYXJncyA9IHRyZWVfY29ucyAoTlVMTF9UUkVFLCBudWxsX3BvaW50ZXJfbm9kZSwgYXJncyk7CgkgIGFyZ3MgPSB0cmVlX2NvbnMgKE5VTExfVFJFRSwgY2xlYW51cCwgYXJncyk7Cgl9CiAgICAgIC8qIEFQUExFIExPQ0FMIGVuZCBMTFZNICovCiAgICB9CiAgZWxzZQogICAgYXJncyA9IHRyZWVfY29ucyAoTlVMTF9UUkVFLCBjbGVhbnVwLCBOVUxMX1RSRUUpOwogIHJldHVybiBidWlsZF9mdW5jdGlvbl9jYWxsIChnZXRfYXRleGl0X25vZGUgKCksIGFyZ3MpOwp9CgovKiBERUNMIGlzIGEgVkFSX0RFQ0wgd2l0aCBzdGF0aWMgc3RvcmFnZSBkdXJhdGlvbi4gIElOSVQsIGlmIHByZXNlbnQsCiAgIGlzIGl0cyBpbml0aWFsaXplci4gIEdlbmVyYXRlIGNvZGUgdG8gaGFuZGxlIHRoZSBjb25zdHJ1Y3Rpb24KICAgYW5kIGRlc3RydWN0aW9uIG9mIERFQ0wuICAqLwoKc3RhdGljIHZvaWQKZXhwYW5kX3N0YXRpY19pbml0ICh0cmVlIGRlY2wsIHRyZWUgaW5pdCkKewogIGdjY19hc3NlcnQgKFRSRUVfQ09ERSAoZGVjbCkgPT0gVkFSX0RFQ0wpOwogIGdjY19hc3NlcnQgKFRSRUVfU1RBVElDIChkZWNsKSk7CgogIC8qIFNvbWUgdmFyaWFibGVzIHJlcXVpcmUgbm8gaW5pdGlhbGl6YXRpb24uICAqLwogIGlmICghaW5pdAogICAgICAmJiAhVFlQRV9ORUVEU19DT05TVFJVQ1RJTkcgKFRSRUVfVFlQRSAoZGVjbCkpCiAgICAgICYmIFRZUEVfSEFTX1RSSVZJQUxfREVTVFJVQ1RPUiAoVFJFRV9UWVBFIChkZWNsKSkpCiAgICByZXR1cm47CgogIGlmIChERUNMX0ZVTkNUSU9OX1NDT1BFX1AgKGRlY2wpKQogICAgewogICAgICAvKiBFbWl0IGNvZGUgdG8gcGVyZm9ybSB0aGlzIGluaXRpYWxpemF0aW9uIGJ1dCBvbmNlLiAgKi8KICAgICAgdHJlZSBpZl9zdG10ID0gTlVMTF9UUkVFLCBpbm5lcl9pZl9zdG10ID0gTlVMTF9UUkVFOwogICAgICB0cmVlIHRoZW5fY2xhdXNlID0gTlVMTF9UUkVFLCBpbm5lcl90aGVuX2NsYXVzZSA9IE5VTExfVFJFRTsKICAgICAgdHJlZSBndWFyZCwgZ3VhcmRfYWRkciwgZ3VhcmRfYWRkcl9saXN0OwogICAgICB0cmVlIGFjcXVpcmVfZm4sIHJlbGVhc2VfZm4sIGFib3J0X2ZuOwogICAgICB0cmVlIGZsYWcsIGJlZ2luOwoKICAgICAgLyogRW1pdCBjb2RlIHRvIHBlcmZvcm0gdGhpcyBpbml0aWFsaXphdGlvbiBidXQgb25jZS4gIFRoaXMgY29kZQoJIGxvb2tzIGxpa2U6CgogICAgICAgICAgIHN0YXRpYyA8dHlwZT4gZ3VhcmQ7CiAgICAgICAgICAgaWYgKCFndWFyZC5maXJzdF9ieXRlKSB7CgkgICAgIGlmIChfX2N4YV9ndWFyZF9hY3F1aXJlICgmZ3VhcmQpKSB7CgkgICAgICAgYm9vbCBmbGFnID0gZmFsc2U7CgkgICAgICAgdHJ5IHsKCSAgICAgICAgIC8vIERvIGluaXRpYWxpemF0aW9uLgoJICAgICAgICAgZmxhZyA9IHRydWU7IF9fY3hhX2d1YXJkX3JlbGVhc2UgKCZndWFyZCk7CgkgICAgICAgICAvLyBSZWdpc3RlciB2YXJpYWJsZSBmb3IgZGVzdHJ1Y3Rpb24gYXQgZW5kIG9mIHByb2dyYW0uCgkgICAgICAgfSBjYXRjaCB7CgkgICAgICAgICBpZiAoIWZsYWcpIF9fY3hhX2d1YXJkX2Fib3J0ICgmZ3VhcmQpOwoJICAgICAgIH0KCSAgIH0KCgkgTm90ZSB0aGF0IHRoZSBgZmxhZycgdmFyaWFibGUgaXMgb25seSBzZXQgdG8gMSAqYWZ0ZXIqIHRoZQoJIGluaXRpYWxpemF0aW9uIGlzIGNvbXBsZXRlLiAgVGhpcyBlbnN1cmVzIHRoYXQgYW4gZXhjZXB0aW9uLAoJIHRocm93biBkdXJpbmcgdGhlIGNvbnN0cnVjdGlvbiwgd2lsbCBjYXVzZSB0aGUgdmFyaWFibGUgdG8KCSByZWluaXRpYWxpemVkIHdoZW4gd2UgcGFzcyB0aHJvdWdoIHRoaXMgY29kZSBhZ2FpbiwgYXMgcGVyOgoKCSAgIFtzdG10LmRjbF0KCgkgICBJZiB0aGUgaW5pdGlhbGl6YXRpb24gZXhpdHMgYnkgdGhyb3dpbmcgYW4gZXhjZXB0aW9uLCB0aGUgIAoJICAgaW5pdGlhbGl6YXRpb24gaXMgbm90IGNvbXBsZXRlLCBzbyBpdCB3aWxsIGJlIHRyaWVkIGFnYWluCgkgICB0aGUgbmV4dCB0aW1lIGNvbnRyb2wgZW50ZXJzIHRoZSBkZWNsYXJhdGlvbi4KCiAgICAgICAgIFRoaXMgcHJvY2VzcyBzaG91bGQgYmUgdGhyZWFkLXNhZmUsIHRvbzsgbXVsdGlwbGUgdGhyZWFkcwoJIHNob3VsZCBub3QgYmUgYWJsZSB0byBpbml0aWFsaXplIHRoZSB2YXJpYWJsZSBtb3JlIHRoYW4KCSBvbmNlLiAgKi8KCiAgICAgIC8qIENyZWF0ZSB0aGUgZ3VhcmQgdmFyaWFibGUuICAqLwogICAgICBndWFyZCA9IGdldF9ndWFyZCAoZGVjbCk7CgogICAgICAvKiBUaGlzIG9wdGltaXphdGlvbiBpc24ndCBzYWZlIG9uIHRhcmdldHMgd2l0aCByZWxheGVkIG1lbW9yeQoJIGNvbnNpc3RlbmN5LiAgT24gc3VjaCB0YXJnZXRzIHdlIGZvcmNlIHN5bmNocm9uaXphdGlvbiBpbgoJIF9fY3hhX2d1YXJkX2FjcXVpcmUuICAqLwogICAgICBpZiAoIXRhcmdldG0ucmVsYXhlZF9vcmRlcmluZyB8fCAhZmxhZ190aHJlYWRzYWZlX3N0YXRpY3MpCgl7CgkgIC8qIEJlZ2luIHRoZSBjb25kaXRpb25hbCBpbml0aWFsaXphdGlvbi4gICovCgkgIGlmX3N0bXQgPSBiZWdpbl9pZl9zdG10ICgpOwoJICBmaW5pc2hfaWZfc3RtdF9jb25kIChnZXRfZ3VhcmRfY29uZCAoZ3VhcmQpLCBpZl9zdG10KTsKCSAgdGhlbl9jbGF1c2UgPSBiZWdpbl9jb21wb3VuZF9zdG10IChCQ1NfTk9fU0NPUEUpOwoJfQoKICAgICAgaWYgKGZsYWdfdGhyZWFkc2FmZV9zdGF0aWNzKQoJewoJICBndWFyZF9hZGRyID0gYnVpbGRfYWRkcmVzcyAoZ3VhcmQpOwoJICBndWFyZF9hZGRyX2xpc3QgPSBidWlsZF90cmVlX2xpc3QgKE5VTExfVFJFRSwgZ3VhcmRfYWRkcik7CgoJICBhY3F1aXJlX2ZuID0gZ2V0X2lkZW50aWZpZXIgKCJfX2N4YV9ndWFyZF9hY3F1aXJlIik7CgkgIHJlbGVhc2VfZm4gPSBnZXRfaWRlbnRpZmllciAoIl9fY3hhX2d1YXJkX3JlbGVhc2UiKTsKCSAgYWJvcnRfZm4gPSBnZXRfaWRlbnRpZmllciAoIl9fY3hhX2d1YXJkX2Fib3J0Iik7CgkgIGlmICghZ2V0X2dsb2JhbF92YWx1ZV9pZl9wcmVzZW50IChhY3F1aXJlX2ZuLCAmYWNxdWlyZV9mbikpCgkgICAgewoJICAgICAgdHJlZSBhcmd0eXBlcyA9IHRyZWVfY29ucyAoTlVMTF9UUkVFLCBUUkVFX1RZUEUgKGd1YXJkX2FkZHIpLAoJCQkJCSB2b2lkX2xpc3Rfbm9kZSk7CgkgICAgICB0cmVlIHZmbnR5cGUgPSBidWlsZF9mdW5jdGlvbl90eXBlICh2b2lkX3R5cGVfbm9kZSwgYXJndHlwZXMpOwoJICAgICAgYWNxdWlyZV9mbiA9IHB1c2hfbGlicmFyeV9mbgoJCShhY3F1aXJlX2ZuLCBidWlsZF9mdW5jdGlvbl90eXBlIChpbnRlZ2VyX3R5cGVfbm9kZSwgYXJndHlwZXMpKTsKCSAgICAgIHJlbGVhc2VfZm4gPSBwdXNoX2xpYnJhcnlfZm4gKHJlbGVhc2VfZm4sIHZmbnR5cGUpOwoJICAgICAgYWJvcnRfZm4gPSBwdXNoX2xpYnJhcnlfZm4gKGFib3J0X2ZuLCB2Zm50eXBlKTsKCSAgICB9CgkgIGVsc2UKCSAgICB7CgkgICAgICByZWxlYXNlX2ZuID0gaWRlbnRpZmllcl9nbG9iYWxfdmFsdWUgKHJlbGVhc2VfZm4pOwoJICAgICAgYWJvcnRfZm4gPSBpZGVudGlmaWVyX2dsb2JhbF92YWx1ZSAoYWJvcnRfZm4pOwoJICAgIH0KCgkgIGlubmVyX2lmX3N0bXQgPSBiZWdpbl9pZl9zdG10ICgpOwoJICBmaW5pc2hfaWZfc3RtdF9jb25kIChidWlsZF9jYWxsIChhY3F1aXJlX2ZuLCBndWFyZF9hZGRyX2xpc3QpLAoJCQkgICAgICAgaW5uZXJfaWZfc3RtdCk7CgoJICBpbm5lcl90aGVuX2NsYXVzZSA9IGJlZ2luX2NvbXBvdW5kX3N0bXQgKEJDU19OT19TQ09QRSk7CgkgIGJlZ2luID0gZ2V0X3RhcmdldF9leHByIChib29sZWFuX2ZhbHNlX25vZGUpOwoJICBmbGFnID0gVEFSR0VUX0VYUFJfU0xPVCAoYmVnaW4pOwoKCSAgVEFSR0VUX0VYUFJfQ0xFQU5VUCAoYmVnaW4pCgkgICAgPSBidWlsZCAoQ09ORF9FWFBSLCB2b2lkX3R5cGVfbm9kZSwgZmxhZywKCQkgICAgIHZvaWRfemVyb19ub2RlLAoJCSAgICAgYnVpbGRfY2FsbCAoYWJvcnRfZm4sIGd1YXJkX2FkZHJfbGlzdCkpOwoJICBDTEVBTlVQX0VIX09OTFkgKGJlZ2luKSA9IDE7CgoJICAvKiBEbyB0aGUgaW5pdGlhbGl6YXRpb24gaXRzZWxmLiAgKi8KCSAgaW5pdCA9IGFkZF9zdG10X3RvX2NvbXBvdW5kIChiZWdpbiwgaW5pdCk7CgkgIGluaXQgPSBhZGRfc3RtdF90b19jb21wb3VuZAoJICAgIChpbml0LCBidWlsZCAoTU9ESUZZX0VYUFIsIHZvaWRfdHlwZV9ub2RlLCBmbGFnLCBib29sZWFuX3RydWVfbm9kZSkpOwoJICBpbml0ID0gYWRkX3N0bXRfdG9fY29tcG91bmQKCSAgICAoaW5pdCwgYnVpbGRfY2FsbCAocmVsZWFzZV9mbiwgZ3VhcmRfYWRkcl9saXN0KSk7Cgl9CiAgICAgIGVsc2UKCWluaXQgPSBhZGRfc3RtdF90b19jb21wb3VuZCAoaW5pdCwgc2V0X2d1YXJkIChndWFyZCkpOwoKICAgICAgLyogVXNlIGF0ZXhpdCB0byByZWdpc3RlciBhIGZ1bmN0aW9uIGZvciBkZXN0cm95aW5nIHRoaXMgc3RhdGljCgkgdmFyaWFibGUuICAqLwogICAgICBpbml0ID0gYWRkX3N0bXRfdG9fY29tcG91bmQgKGluaXQsIHJlZ2lzdGVyX2R0b3JfZm4gKGRlY2wpKTsKCiAgICAgIGZpbmlzaF9leHByX3N0bXQgKGluaXQpOwoKICAgICAgaWYgKGZsYWdfdGhyZWFkc2FmZV9zdGF0aWNzKQoJewoJICBmaW5pc2hfY29tcG91bmRfc3RtdCAoaW5uZXJfdGhlbl9jbGF1c2UpOwoJICBmaW5pc2hfdGhlbl9jbGF1c2UgKGlubmVyX2lmX3N0bXQpOwoJICBmaW5pc2hfaWZfc3RtdCAoaW5uZXJfaWZfc3RtdCk7Cgl9CgogICAgICBpZiAoIXRhcmdldG0ucmVsYXhlZF9vcmRlcmluZyB8fCAhZmxhZ190aHJlYWRzYWZlX3N0YXRpY3MpCgl7CgkgIGZpbmlzaF9jb21wb3VuZF9zdG10ICh0aGVuX2NsYXVzZSk7CgkgIGZpbmlzaF90aGVuX2NsYXVzZSAoaWZfc3RtdCk7CgkgIGZpbmlzaF9pZl9zdG10IChpZl9zdG10KTsKCX0KICAgIH0KICBlbHNlCiAgICBzdGF0aWNfYWdncmVnYXRlcyA9IHRyZWVfY29ucyAoaW5pdCwgZGVjbCwgc3RhdGljX2FnZ3JlZ2F0ZXMpOwp9CgoMCi8qIE1ha2UgVFlQRSBhIGNvbXBsZXRlIHR5cGUgYmFzZWQgb24gSU5JVElBTF9WQUxVRS4KICAgUmV0dXJuIDAgaWYgc3VjY2Vzc2Z1bCwgMSBpZiBJTklUSUFMX1ZBTFVFIGNhbid0IGJlIGRlY2lwaGVyZWQsCiAgIDIgaWYgdGhlcmUgd2FzIG5vIGluZm9ybWF0aW9uIChpbiB3aGljaCBjYXNlIGFzc3VtZSAwIGlmIERPX0RFRkFVTFQpLiAgKi8KCmludApjcF9jb21wbGV0ZV9hcnJheV90eXBlICh0cmVlICpwdHlwZSwgdHJlZSBpbml0aWFsX3ZhbHVlLCBib29sIGRvX2RlZmF1bHQpCnsKICBpbnQgZmFpbHVyZTsKICB0cmVlIHR5cGUsIGVsdF90eXBlOwoKICBpZiAoaW5pdGlhbF92YWx1ZSkKICAgIHsKICAgICAgLyogQW4gYXJyYXkgb2YgY2hhcmFjdGVyIHR5cGUgY2FuIGJlIGluaXRpYWxpemVkIGZyb20gYQoJIGJyYWNlLWVuY2xvc2VkIHN0cmluZyBjb25zdGFudC4gICovCiAgICAgIGlmIChjaGFyX3R5cGVfcCAoVFlQRV9NQUlOX1ZBUklBTlQgKFRSRUVfVFlQRSAoKnB0eXBlKSkpCgkgICYmIFRSRUVfQ09ERSAoaW5pdGlhbF92YWx1ZSkgPT0gQ09OU1RSVUNUT1IKCSAgJiYgQ09OU1RSVUNUT1JfRUxUUyAoaW5pdGlhbF92YWx1ZSkKCSAgJiYgKFRSRUVfQ09ERSAoVFJFRV9WQUxVRSAoQ09OU1RSVUNUT1JfRUxUUyAoaW5pdGlhbF92YWx1ZSkpKQoJICAgICAgPT0gU1RSSU5HX0NTVCkKCSAgJiYgVFJFRV9DSEFJTiAoQ09OU1RSVUNUT1JfRUxUUyAoaW5pdGlhbF92YWx1ZSkpID09IE5VTExfVFJFRSkKCWluaXRpYWxfdmFsdWUgPSBUUkVFX1ZBTFVFIChDT05TVFJVQ1RPUl9FTFRTIChpbml0aWFsX3ZhbHVlKSk7CiAgICB9CiAgCiAgZmFpbHVyZSA9IGNvbXBsZXRlX2FycmF5X3R5cGUgKHB0eXBlLCBpbml0aWFsX3ZhbHVlLCBkb19kZWZhdWx0KTsKICAKICAvKiBXZSBjYW4gY3JlYXRlIHRoZSBhcnJheSBiZWZvcmUgdGhlIGVsZW1lbnQgdHlwZSBpcyBjb21wbGV0ZSwgd2hpY2gKICAgICBtZWFucyB0aGF0IHdlIGRpZG4ndCBoYXZlIHRoZXNlIHR3byBiaXRzIHNldCBpbiB0aGUgb3JpZ2luYWwgdHlwZQogICAgIGVpdGhlci4gIEluIGNvbXBsZXRpbmcgdGhlIHR5cGUsIHdlIGFyZSBleHBlY3RlZCB0byBwcm9wYWdhdGUgdGhlc2UKICAgICBiaXRzLiAgU2VlIGFsc28gY29tcGxldGVfdHlwZSB3aGljaCBkb2VzIHRoZSBzYW1lIHRoaW5nIGZvciBhcnJheXMKICAgICBvZiBmaXhlZCBzaXplLiAgKi8KICB0eXBlID0gKnB0eXBlOwogIGlmIChUWVBFX0RPTUFJTiAodHlwZSkpCiAgICB7CiAgICAgIGVsdF90eXBlID0gVFJFRV9UWVBFICh0eXBlKTsKICAgICAgVFlQRV9ORUVEU19DT05TVFJVQ1RJTkcgKHR5cGUpID0gVFlQRV9ORUVEU19DT05TVFJVQ1RJTkcgKGVsdF90eXBlKTsKICAgICAgVFlQRV9IQVNfTk9OVFJJVklBTF9ERVNUUlVDVE9SICh0eXBlKQoJPSBUWVBFX0hBU19OT05UUklWSUFMX0RFU1RSVUNUT1IgKGVsdF90eXBlKTsKICAgIH0KCiAgcmV0dXJuIGZhaWx1cmU7Cn0KDAovKiBSZXR1cm4gemVybyBpZiBzb21ldGhpbmcgaXMgZGVjbGFyZWQgdG8gYmUgYSBtZW1iZXIgb2YgdHlwZQogICBDVFlQRSB3aGVuIGluIHRoZSBjb250ZXh0IG9mIENVUl9UWVBFLiAgU1RSSU5HIGlzIHRoZSBlcnJvcgogICBtZXNzYWdlIHRvIHByaW50IGluIHRoYXQgY2FzZS4gIE90aGVyd2lzZSwgcXVpZXRseSByZXR1cm4gMS4gICovCgpzdGF0aWMgaW50Cm1lbWJlcl9mdW5jdGlvbl9vcl9lbHNlICh0cmVlIGN0eXBlLCB0cmVlIGN1cl90eXBlLCBlbnVtIG92ZXJsb2FkX2ZsYWdzIGZsYWdzKQp7CiAgaWYgKGN0eXBlICYmIGN0eXBlICE9IGN1cl90eXBlKQogICAgewogICAgICBpZiAoZmxhZ3MgPT0gRFRPUl9GTEFHKQoJZXJyb3IgKCJkZXN0cnVjdG9yIGZvciBhbGllbiBjbGFzcyAlcVQgY2Fubm90IGJlIGEgbWVtYmVyIiwgY3R5cGUpOwogICAgICBlbHNlCgllcnJvciAoImNvbnN0cnVjdG9yIGZvciBhbGllbiBjbGFzcyAlcVQgY2Fubm90IGJlIGEgbWVtYmVyIiwgY3R5cGUpOwogICAgICByZXR1cm4gMDsKICAgIH0KICByZXR1cm4gMTsKfQoMCi8qIFN1YnJvdXRpbmUgb2YgYGdyb2tkZWNsYXJhdG9yJy4gICovCgovKiBHZW5lcmF0ZSBlcnJvcnMgcG9zc2libHkgYXBwbGljYWJsZSBmb3IgYSBnaXZlbiBzZXQgb2Ygc3BlY2lmaWVycy4KICAgVGhpcyBpcyBmb3IgQVJNICQ3LjEuMi4gICovCgpzdGF0aWMgdm9pZApiYWRfc3BlY2lmaWVycyAodHJlZSBvYmplY3QsCiAgICAgICAgICAgICAgICBjb25zdCBjaGFyKiB0eXBlLAogICAgICAgICAgICAgICAgaW50IHZpcnR1YWxwLAogICAgICAgICAgICAgICAgaW50IHF1YWxzLAogICAgICAgICAgICAgICAgaW50IGlubGluZXAsCiAgICAgICAgICAgICAgICBpbnQgZnJpZW5kcCwKICAgICAgICAgICAgICAgIGludCByYWlzZXMpCnsKICBpZiAodmlydHVhbHApCiAgICBlcnJvciAoIiVxRCBkZWNsYXJlZCBhcyBhICU8dmlydHVhbCU+ICVzIiwgb2JqZWN0LCB0eXBlKTsKICBpZiAoaW5saW5lcCkKICAgIGVycm9yICgiJXFEIGRlY2xhcmVkIGFzIGFuICU8aW5saW5lJT4gJXMiLCBvYmplY3QsIHR5cGUpOwogIGlmIChxdWFscykKICAgIGVycm9yICgiJTxjb25zdCU+IGFuZCAlPHZvbGF0aWxlJT4gZnVuY3Rpb24gc3BlY2lmaWVycyBvbiAiCiAgICAgICAgICAgIiVxRCBpbnZhbGlkIGluICVzIGRlY2xhcmF0aW9uIiwKICAgICAgICAgICBvYmplY3QsIHR5cGUpOwogIGlmIChmcmllbmRwKQogICAgY3BfZXJyb3JfYXQgKCIlcUQgZGVjbGFyZWQgYXMgYSBmcmllbmQiLCBvYmplY3QpOwogIGlmIChyYWlzZXMKICAgICAgJiYgKFRSRUVfQ09ERSAob2JqZWN0KSA9PSBUWVBFX0RFQ0wKCSAgfHwgKCFUWVBFX1BUUkZOX1AgKFRSRUVfVFlQRSAob2JqZWN0KSkKCSAgICAgICYmICFUWVBFX1JFRkZOX1AgKFRSRUVfVFlQRSAob2JqZWN0KSkKCSAgICAgICYmICFUWVBFX1BUUk1FTUZVTkNfUCAoVFJFRV9UWVBFIChvYmplY3QpKSkpKQogICAgY3BfZXJyb3JfYXQgKCIlcUQgZGVjbGFyZWQgd2l0aCBhbiBleGNlcHRpb24gc3BlY2lmaWNhdGlvbiIsIG9iamVjdCk7Cn0KCi8qIENUWVBFIGlzIGNsYXNzIHR5cGUsIG9yIG51bGwgaWYgbm9uLWNsYXNzLgogICBUWVBFIGlzIHR5cGUgdGhpcyBGVU5DVElPTl9ERUNMIHNob3VsZCBoYXZlLCBlaXRoZXIgRlVOQ1RJT05fVFlQRQogICBvciBNRVRIT0RfVFlQRS4KICAgREVDTEFSQVRPUiBpcyB0aGUgZnVuY3Rpb24ncyBuYW1lLgogICBQQVJNUyBpcyBhIGNoYWluIG9mIFBBUk1fREVDTHMgZm9yIHRoZSBmdW5jdGlvbi4KICAgVklSVFVBTFAgaXMgdHJ1dGh2YWx1ZSBvZiB3aGV0aGVyIHRoZSBmdW5jdGlvbiBpcyB2aXJ0dWFsIG9yIG5vdC4KICAgRkxBR1MgYXJlIHRvIGJlIHBhc3NlZCB0aHJvdWdoIHRvIGBncm9rY2xhc3NmbicuCiAgIFFVQUxTIGFyZSBxdWFsaWZpZXJzIGluZGljYXRpbmcgd2hldGhlciB0aGUgZnVuY3Rpb24gaXMgYGNvbnN0JwogICBvciBgdm9sYXRpbGUnLgogICBSQUlTRVMgaXMgYSBsaXN0IG9mIGV4Y2VwdGlvbnMgdGhhdCB0aGlzIGZ1bmN0aW9uIGNhbiByYWlzZS4KICAgQ0hFQ0sgaXMgMSBpZiB3ZSBtdXN0IGZpbmQgdGhpcyBtZXRob2QgaW4gQ1RZUEUsIDAgaWYgd2Ugc2hvdWxkCiAgIG5vdCBsb29rLCBhbmQgLTEgaWYgd2Ugc2hvdWxkIG5vdCBjYWxsIGBncm9rY2xhc3NmbicgYXQgYWxsLgoKICAgU0ZLIGlzIHRoZSBraW5kIG9mIHNwZWNpYWwgZnVuY3Rpb24gKGlmIGFueSkgZm9yIHRoZSBuZXcgZnVuY3Rpb24uCgogICBSZXR1cm5zIGBOVUxMX1RSRUUnIGlmIHNvbWV0aGluZyBnb2VzIHdyb25nLCBhZnRlciBpc3N1aW5nCiAgIGFwcGxpY2FibGUgZXJyb3IgbWVzc2FnZXMuICAqLwoKc3RhdGljIHRyZWUKZ3Jva2ZuZGVjbCAodHJlZSBjdHlwZSwKICAgICAgICAgICAgdHJlZSB0eXBlLAogICAgICAgICAgICB0cmVlIGRlY2xhcmF0b3IsCgkgICAgdHJlZSBwYXJtcywKICAgICAgICAgICAgdHJlZSBvcmlnX2RlY2xhcmF0b3IsCiAgICAgICAgICAgIGludCB2aXJ0dWFscCwKICAgICAgICAgICAgZW51bSBvdmVybG9hZF9mbGFncyBmbGFncywKCSAgICBjcF9jdl9xdWFscyBxdWFscywKICAgICAgICAgICAgdHJlZSByYWlzZXMsCiAgICAgICAgICAgIGludCBjaGVjaywKICAgICAgICAgICAgaW50IGZyaWVuZHAsCiAgICAgICAgICAgIGludCBwdWJsaWNwLAogICAgICAgICAgICBpbnQgaW5saW5lcCwKCSAgICBzcGVjaWFsX2Z1bmN0aW9uX2tpbmQgc2ZrLAogICAgICAgICAgICBpbnQgZnVuY2RlZl9mbGFnLAogICAgICAgICAgICBpbnQgdGVtcGxhdGVfY291bnQsCiAgICAgICAgICAgIHRyZWUgaW5fbmFtZXNwYWNlLAoJICAgIHRyZWUqIGF0dHJsaXN0KQp7CiAgdHJlZSBkZWNsOwogIGludCBzdGF0aWNwID0gY3R5cGUgJiYgVFJFRV9DT0RFICh0eXBlKSA9PSBGVU5DVElPTl9UWVBFOwogIGludCBoYXNfZGVmYXVsdF9hcmcgPSAwOwogIHRyZWUgdDsKCiAgaWYgKHJhaXNlcykKICAgIHR5cGUgPSBidWlsZF9leGNlcHRpb25fdmFyaWFudCAodHlwZSwgcmFpc2VzKTsKCiAgZGVjbCA9IGJ1aWxkX2xhbmdfZGVjbCAoRlVOQ1RJT05fREVDTCwgZGVjbGFyYXRvciwgdHlwZSk7CiAgREVDTF9BUkdVTUVOVFMgKGRlY2wpID0gcGFybXM7CiAgLyogUHJvcGFnYXRlIHZvbGF0aWxlIG91dCBmcm9tIHR5cGUgdG8gZGVjbC4gICovCiAgaWYgKFRZUEVfVk9MQVRJTEUgKHR5cGUpKQogICAgVFJFRV9USElTX1ZPTEFUSUxFIChkZWNsKSA9IDE7CgogIC8qIElmIHRoaXMgZGVjbCBoYXMgbmFtZXNwYWNlIHNjb3BlLCBzZXQgdGhhdCB1cC4gICovCiAgaWYgKGluX25hbWVzcGFjZSkKICAgIHNldF9kZWNsX25hbWVzcGFjZSAoZGVjbCwgaW5fbmFtZXNwYWNlLCBmcmllbmRwKTsKICBlbHNlIGlmICghY3R5cGUpCiAgICBERUNMX0NPTlRFWFQgKGRlY2wpID0gRlJPQl9DT05URVhUIChjdXJyZW50X25hbWVzcGFjZSk7CgogIC8qIGBtYWluJyBhbmQgYnVpbHRpbnMgaGF2ZSBpbXBsaWNpdCAnQycgbGlua2FnZS4gICovCiAgaWYgKChNQUlOX05BTUVfUCAoZGVjbGFyYXRvcikKICAgICAgIHx8IChJREVOVElGSUVSX0xFTkdUSCAoZGVjbGFyYXRvcikgPiAxMAoJICAgJiYgSURFTlRJRklFUl9QT0lOVEVSIChkZWNsYXJhdG9yKVswXSA9PSAnXycKCSAgICYmIElERU5USUZJRVJfUE9JTlRFUiAoZGVjbGFyYXRvcilbMV0gPT0gJ18nCgkgICAmJiBzdHJuY21wIChJREVOVElGSUVSX1BPSU5URVIgKGRlY2xhcmF0b3IpKzIsICJidWlsdGluXyIsIDgpID09IDApKQogICAgICAmJiBjdXJyZW50X2xhbmdfbmFtZSA9PSBsYW5nX25hbWVfY3BsdXNwbHVzCiAgICAgICYmIGN0eXBlID09IE5VTExfVFJFRQogICAgICAvKiBOVUxMX1RSRUUgbWVhbnMgZ2xvYmFsIG5hbWVzcGFjZS4gICovCiAgICAgICYmIERFQ0xfQ09OVEVYVCAoZGVjbCkgPT0gTlVMTF9UUkVFKQogICAgU0VUX0RFQ0xfTEFOR1VBR0UgKGRlY2wsIGxhbmdfYyk7CgogIC8qIFNob3VsZCBwcm9iYWJseSBwcm9wYWdhdGUgY29uc3Qgb3V0IGZyb20gdHlwZSB0byBkZWNsIEkgYmV0IChtcnMpLiAgKi8KICBpZiAoc3RhdGljcCkKICAgIHsKICAgICAgREVDTF9TVEFUSUNfRlVOQ1RJT05fUCAoZGVjbCkgPSAxOwogICAgICBERUNMX0NPTlRFWFQgKGRlY2wpID0gY3R5cGU7CiAgICB9CgogIGlmIChjdHlwZSkKICAgIERFQ0xfQ09OVEVYVCAoZGVjbCkgPSBjdHlwZTsKCiAgaWYgKGN0eXBlID09IE5VTExfVFJFRSAmJiBERUNMX01BSU5fUCAoZGVjbCkpCiAgICB7CiAgICAgIGlmIChwcm9jZXNzaW5nX3RlbXBsYXRlX2RlY2wpCgllcnJvciAoImNhbm5vdCBkZWNsYXJlICU8OjptYWluJT4gdG8gYmUgYSB0ZW1wbGF0ZSIpOwogICAgICBpZiAoaW5saW5lcCkKCWVycm9yICgiY2Fubm90IGRlY2xhcmUgJTw6Om1haW4lPiB0byBiZSBpbmxpbmUiKTsKICAgICAgaWYgKCFwdWJsaWNwKQoJZXJyb3IgKCJjYW5ub3QgZGVjbGFyZSAlPDo6bWFpbiU+IHRvIGJlIHN0YXRpYyIpOwogICAgICBpZiAoIXNhbWVfdHlwZV9wIChUUkVFX1RZUEUgKFRSRUVfVFlQRSAoZGVjbCkpLAoJCQlpbnRlZ2VyX3R5cGVfbm9kZSkpCgl7CgkgIC8qIEFQUExFIExPQ0FMIGJlZ2luIG1haW5saW5lIHJkYXIgNDQ1ODI5NCovCgkgIHRyZWUgb2xkdHlwZWFyZ3MgPSBUWVBFX0FSR19UWVBFUyAoVFJFRV9UWVBFIChkZWNsKSk7CgkgIHRyZWUgbmV3dHlwZTsKCSAgZXJyb3IgKCIlPDo6bWFpbiU+IG11c3QgcmV0dXJuICU8aW50JT4iKTsKCSAgbmV3dHlwZSA9IGJ1aWxkX2Z1bmN0aW9uX3R5cGUgKGludGVnZXJfdHlwZV9ub2RlLAoJICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb2xkdHlwZWFyZ3MpOwoJICBUUkVFX1RZUEUgKGRlY2wpID0gbmV3dHlwZTsKCSAgLyogQVBQTEUgTE9DQUwgZW5kIG1haW5saW5lIHJkYXIgNDQ1ODI5NCovCgkgIFRSRUVfVFlQRSAoVFJFRV9UWVBFIChkZWNsKSkgPSBpbnRlZ2VyX3R5cGVfbm9kZTsKCX0KICAgICAgaW5saW5lcCA9IDA7CiAgICAgIHB1YmxpY3AgPSAxOwogICAgfQoKICAvKiBNZW1iZXJzIG9mIGFub255bW91cyB0eXBlcyBhbmQgbG9jYWwgY2xhc3NlcyBoYXZlIG5vIGxpbmthZ2U7IG1ha2UKICAgICB0aGVtIGludGVybmFsLiAgSWYgYSB0eXBlZGVmIGlzIG1hZGUgbGF0ZXIsIHRoaXMgd2lsbCBiZSBjaGFuZ2VkLiAgKi8KICBpZiAoY3R5cGUgJiYgKFRZUEVfQU5PTllNT1VTX1AgKGN0eXBlKQoJCXx8IGRlY2xfZnVuY3Rpb25fY29udGV4dCAoVFlQRV9NQUlOX0RFQ0wgKGN0eXBlKSkpKQogICAgcHVibGljcCA9IDA7CgogIGlmIChwdWJsaWNwKQogICAgewogICAgICAvKiBbYmFzaWMubGlua106IEEgbmFtZSB3aXRoIG5vIGxpbmthZ2UgKG5vdGFibHksIHRoZSBuYW1lIG9mIGEgY2xhc3MKCSBvciBlbnVtZXJhdGlvbiBkZWNsYXJlZCBpbiBhIGxvY2FsIHNjb3BlKSBzaGFsbCBub3QgYmUgdXNlZCB0bwoJIGRlY2xhcmUgYW4gZW50aXR5IHdpdGggbGlua2FnZS4KCgkgT25seSBjaGVjayB0aGlzIGZvciBwdWJsaWMgZGVjbHMgZm9yIG5vdy4gIFNlZSBjb3JlIDMxOSwgMzg5LiAgKi8KICAgICAgdCA9IG5vX2xpbmthZ2VfY2hlY2sgKFRSRUVfVFlQRSAoZGVjbCksCgkJCSAgICAvKnJlbGF4ZWRfcD0qL2ZhbHNlKTsKICAgICAgaWYgKHQpCgl7CgkgIGlmIChUWVBFX0FOT05ZTU9VU19QICh0KSkKCSAgICB7CgkgICAgICBpZiAoREVDTF9FWFRFUk5fQ19QIChkZWNsKSkKCQkvKiBBbGxvdyB0aGlzOyBpdCdzIHByZXR0eSBjb21tb24gaW4gQy4gICovOwoJICAgICAgZWxzZQoJCXsKCQkgIHBlZHdhcm4gKCJub24tbG9jYWwgZnVuY3Rpb24gJXEjRCB1c2VzIGFub255bW91cyB0eXBlIiwKCQkJICAgICAgZGVjbCk7CgkJICBpZiAoREVDTF9PUklHSU5BTF9UWVBFIChUWVBFX05BTUUgKHQpKSkKCQkgICAgY3BfcGVkd2Fybl9hdCAoIiVxI0QgZG9lcyBub3QgcmVmZXIgdG8gdGhlIHVucXVhbGlmaWVkICIKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAidHlwZSwgc28gaXQgaXMgbm90IHVzZWQgZm9yIGxpbmthZ2UiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRZUEVfTkFNRSAodCkpOwoJCX0KCSAgICB9CgkgIGVsc2UKCSAgICBwZWR3YXJuICgibm9uLWxvY2FsIGZ1bmN0aW9uICVxI0QgdXNlcyBsb2NhbCB0eXBlICVxVCIsIGRlY2wsIHQpOwoJfQogICAgfQoKICBUUkVFX1BVQkxJQyAoZGVjbCkgPSBwdWJsaWNwOwogIGlmICghIHB1YmxpY3ApCiAgICB7CiAgICAgIERFQ0xfSU5URVJGQUNFX0tOT1dOIChkZWNsKSA9IDE7CiAgICAgIERFQ0xfTk9UX1JFQUxMWV9FWFRFUk4gKGRlY2wpID0gMTsKICAgIH0KCiAgLyogSWYgdGhlIGRlY2xhcmF0aW9uIHdhcyBkZWNsYXJlZCBpbmxpbmUsIG1hcmsgaXQgYXMgc3VjaC4gICovCiAgaWYgKGlubGluZXApCiAgICBERUNMX0RFQ0xBUkVEX0lOTElORV9QIChkZWNsKSA9IDE7CiAgLyogV2UgaW5saW5lIGZ1bmN0aW9ucyB0aGF0IGFyZSBleHBsaWNpdGx5IGRlY2xhcmVkIGlubGluZSwgb3IsIHdoZW4KICAgICB0aGUgdXNlciBleHBsaWNpdGx5IGFza3MgdXMgdG8sIGFsbCBmdW5jdGlvbnMuICAqLwogIGlmIChERUNMX0RFQ0xBUkVEX0lOTElORV9QIChkZWNsKQogICAgICB8fCAoZmxhZ19pbmxpbmVfdHJlZXMgPT0gMiAmJiAhREVDTF9JTkxJTkUgKGRlY2wpICYmIGZ1bmNkZWZfZmxhZykpCiAgICBERUNMX0lOTElORSAoZGVjbCkgPSAxOwoKICBERUNMX0VYVEVSTkFMIChkZWNsKSA9IDE7CiAgaWYgKHF1YWxzICYmIFRSRUVfQ09ERSAodHlwZSkgPT0gRlVOQ1RJT05fVFlQRSkKICAgIHsKICAgICAgZXJyb3IgKCIlc21lbWJlciBmdW5jdGlvbiAlcUQgY2Fubm90IGhhdmUgY3YtcXVhbGlmaWVyIiwKCSAgICAgKGN0eXBlID8gInN0YXRpYyAiIDogIm5vbi0iKSwgZGVjbCk7CiAgICAgIHF1YWxzID0gVFlQRV9VTlFVQUxJRklFRDsKICAgIH0KCiAgaWYgKElERU5USUZJRVJfT1BOQU1FX1AgKERFQ0xfTkFNRSAoZGVjbCkpKQogICAgZ3Jva19vcF9wcm9wZXJ0aWVzIChkZWNsLCAvKmNvbXBsYWluPSovdHJ1ZSk7CgogIGlmIChjdHlwZSAmJiBkZWNsX2Z1bmN0aW9uX2NvbnRleHQgKGRlY2wpKQogICAgREVDTF9OT19TVEFUSUNfQ0hBSU4gKGRlY2wpID0gMTsKCiAgZm9yICh0ID0gVFlQRV9BUkdfVFlQRVMgKFRSRUVfVFlQRSAoZGVjbCkpOyB0OyB0ID0gVFJFRV9DSEFJTiAodCkpCiAgICBpZiAoVFJFRV9QVVJQT1NFICh0KQoJJiYgVFJFRV9DT0RFIChUUkVFX1BVUlBPU0UgKHQpKSA9PSBERUZBVUxUX0FSRykKICAgICAgewoJaGFzX2RlZmF1bHRfYXJnID0gMTsKCWJyZWFrOwogICAgICB9CgogIGlmIChmcmllbmRwCiAgICAgICYmIFRSRUVfQ09ERSAob3JpZ19kZWNsYXJhdG9yKSA9PSBURU1QTEFURV9JRF9FWFBSKQogICAgewogICAgICBpZiAoZnVuY2RlZl9mbGFnKQoJZXJyb3IKCSAgKCJkZWZpbmluZyBleHBsaWNpdCBzcGVjaWFsaXphdGlvbiAlcUQgaW4gZnJpZW5kIGRlY2xhcmF0aW9uIiwKCSAgIG9yaWdfZGVjbGFyYXRvcik7CiAgICAgIGVsc2UKCXsKCSAgdHJlZSBmbnMgPSBUUkVFX09QRVJBTkQgKG9yaWdfZGVjbGFyYXRvciwgMCk7CgkgIHRyZWUgYXJncyA9IFRSRUVfT1BFUkFORCAob3JpZ19kZWNsYXJhdG9yLCAxKTsKCgkgIGlmIChQUk9DRVNTSU5HX1JFQUxfVEVNUExBVEVfREVDTF9QICgpKQoJICAgIHsKCSAgICAgIC8qIFNvbWV0aGluZyBsaWtlIGB0ZW1wbGF0ZSA8Y2xhc3MgVD4gZnJpZW5kIHZvaWQgZjxUPigpJy4gICovCgkgICAgICBlcnJvciAoImludmFsaWQgdXNlIG9mIHRlbXBsYXRlLWlkICVxRCBpbiBkZWNsYXJhdGlvbiAiCiAgICAgICAgICAgICAgICAgICAgICJvZiBwcmltYXJ5IHRlbXBsYXRlIiwKICAgICAgICAgICAgICAgICAgICAgb3JpZ19kZWNsYXJhdG9yKTsKCSAgICAgIHJldHVybiBOVUxMX1RSRUU7CgkgICAgfQoKCgkgIC8qIEEgZnJpZW5kIGRlY2xhcmF0aW9uIG9mIHRoZSBmb3JtIGZyaWVuZCB2b2lkIGY8PigpLiAgUmVjb3JkCgkgICAgIHRoZSBpbmZvcm1hdGlvbiBpbiB0aGUgVEVNUExBVEVfSURfRVhQUi4gICovCgkgIFNFVF9ERUNMX0lNUExJQ0lUX0lOU1RBTlRJQVRJT04gKGRlY2wpOwoKICAgICAgICAgIGlmIChUUkVFX0NPREUgKGZucykgPT0gQ09NUE9ORU5UX1JFRikKICAgICAgICAgICAgewogICAgICAgICAgICAgIC8qIER1ZSB0byBiaXNvbiBwYXJzZXIgaWNraW5lc3MsIHdlIHdpbGwgaGF2ZSBhbHJlYWR5IGxvb2tlZAogICAgICAgICAgICAgICAgIHVwIGFuIG9wZXJhdG9yX25hbWUgb3IgUEZVTkNOQU1FIHdpdGhpbiB0aGUgY3VycmVudCBjbGFzcwogICAgICAgICAgICAgICAgIChzZWUgdGVtcGxhdGVfaWQgaW4gcGFyc2UueSkuIElmIHRoZSBjdXJyZW50IGNsYXNzIGNvbnRhaW5zCiAgICAgICAgICAgICAgICAgc3VjaCBhIG5hbWUsIHdlJ2xsIGdldCBhIENPTVBPTkVOVF9SRUYgaGVyZS4gVW5kbyB0aGF0LiAgKi8KCiAgICAgICAgICAgICAgZ2NjX2Fzc2VydCAoVFJFRV9UWVBFIChUUkVFX09QRVJBTkQgKGZucywgMCkpCgkJCSAgPT0gY3VycmVudF9jbGFzc190eXBlKTsKICAgICAgICAgICAgICBmbnMgPSBUUkVFX09QRVJBTkQgKGZucywgMSk7CiAgICAgICAgICAgIH0KCSAgZ2NjX2Fzc2VydCAoVFJFRV9DT0RFIChmbnMpID09IElERU5USUZJRVJfTk9ERQoJCSAgICAgIHx8IFRSRUVfQ09ERSAoZm5zKSA9PSBPVkVSTE9BRCk7CgkgIERFQ0xfVEVNUExBVEVfSU5GTyAoZGVjbCkgPSB0cmVlX2NvbnMgKGZucywgYXJncywgTlVMTF9UUkVFKTsKCgkgIGlmIChoYXNfZGVmYXVsdF9hcmcpCgkgICAgewoJICAgICAgZXJyb3IgKCJkZWZhdWx0IGFyZ3VtZW50cyBhcmUgbm90IGFsbG93ZWQgaW4gZGVjbGFyYXRpb24gIgogICAgICAgICAgICAgICAgICAgICAib2YgZnJpZW5kIHRlbXBsYXRlIHNwZWNpYWxpemF0aW9uICVxRCIsCiAgICAgICAgICAgICAgICAgICAgIGRlY2wpOwoJICAgICAgcmV0dXJuIE5VTExfVFJFRTsKCSAgICB9CgoJICBpZiAoaW5saW5lcCkKCSAgICB7CgkgICAgICBlcnJvciAoIiU8aW5saW5lJT4gaXMgbm90IGFsbG93ZWQgaW4gZGVjbGFyYXRpb24gb2YgZnJpZW5kICIKICAgICAgICAgICAgICAgICAgICAgInRlbXBsYXRlIHNwZWNpYWxpemF0aW9uICVxRCIsCiAgICAgICAgICAgICAgICAgICAgIGRlY2wpOwoJICAgICAgcmV0dXJuIE5VTExfVFJFRTsKCSAgICB9Cgl9CiAgICB9CgogIGlmIChmdW5jZGVmX2ZsYWcpCiAgICAvKiBNYWtlIHRoZSBpbml0X3ZhbHVlIG5vbnplcm8gc28gcHVzaGRlY2wga25vd3MgdGhpcyBpcyBub3QKICAgICAgIHRlbnRhdGl2ZS4gIGVycm9yX21hcmtfbm9kZSBpcyByZXBsYWNlZCBsYXRlciB3aXRoIHRoZSBCTE9DSy4gICovCiAgICBERUNMX0lOSVRJQUwgKGRlY2wpID0gZXJyb3JfbWFya19ub2RlOwoKICBpZiAoVFlQRV9OT1RIUk9XX1AgKHR5cGUpIHx8IG5vdGhyb3dfbGliZm5fcCAoZGVjbCkpCiAgICBUUkVFX05PVEhST1cgKGRlY2wpID0gMTsKCiAgLyogQ2FsbGVyIHdpbGwgZG8gdGhlIHJlc3Qgb2YgdGhpcy4gICovCiAgaWYgKGNoZWNrIDwgMCkKICAgIHJldHVybiBkZWNsOwoKICBpZiAoY3R5cGUgIT0gTlVMTF9UUkVFKQogICAgewogICAgICBpZiAoc2ZrID09IHNma19jb25zdHJ1Y3RvcikKCURFQ0xfQ09OU1RSVUNUT1JfUCAoZGVjbCkgPSAxOwoKICAgICAgZ3Jva2NsYXNzZm4gKGN0eXBlLCBkZWNsLCBmbGFncywgcXVhbHMpOwogICAgfQoKICBkZWNsID0gY2hlY2tfZXhwbGljaXRfc3BlY2lhbGl6YXRpb24gKG9yaWdfZGVjbGFyYXRvciwgZGVjbCwKCQkJCQl0ZW1wbGF0ZV9jb3VudCwKCQkJCQkyICogKGZ1bmNkZWZfZmxhZyAhPSAwKSArCgkJCQkJNCAqIChmcmllbmRwICE9IDApKTsKICBpZiAoZGVjbCA9PSBlcnJvcl9tYXJrX25vZGUpCiAgICByZXR1cm4gTlVMTF9UUkVFOwoKICBpZiAoYXR0cmxpc3QpCiAgICB7CiAgICAgIGNwbHVzX2RlY2xfYXR0cmlidXRlcyAoJmRlY2wsICphdHRybGlzdCwgMCk7CiAgICAgICphdHRybGlzdCA9IE5VTExfVFJFRTsKICAgIH0KCiAgaWYgKGN0eXBlICE9IE5VTExfVFJFRQogICAgICAmJiAoISBUWVBFX0ZPUl9KQVZBIChjdHlwZSkgfHwgY2hlY2tfamF2YV9tZXRob2QgKGRlY2wpKQogICAgICAmJiBjaGVjaykKICAgIHsKICAgICAgdHJlZSBvbGRfZGVjbDsKCiAgICAgIG9sZF9kZWNsID0gY2hlY2tfY2xhc3NmbiAoY3R5cGUsIGRlY2wsCgkJCQkocHJvY2Vzc2luZ190ZW1wbGF0ZV9kZWNsCgkJCQkgPiB0ZW1wbGF0ZV9jbGFzc19kZXB0aCAoY3R5cGUpKQoJCQkJPyBjdXJyZW50X3RlbXBsYXRlX3Bhcm1zCgkJCQk6IE5VTExfVFJFRSk7IAoKICAgICAgaWYgKG9sZF9kZWNsICYmIFRSRUVfQ09ERSAob2xkX2RlY2wpID09IFRFTVBMQVRFX0RFQ0wpCgkvKiBCZWNhdXNlIGdyb2tmbmRlY2wgaXMgYWx3YXlzIHN1cHBvc2VkIHRvIHJldHVybiBhCgkgICBGVU5DVElPTl9ERUNMLCB3ZSBwdWxsIG91dCB0aGUgREVDTF9URU1QTEFURV9SRVNVTFQKCSAgIGhlcmUuICBXZSBkZXBlbmQgb24gb3VyIGNhbGxlcnMgdG8gZmlndXJlIG91dCB0aGF0IGl0cwoJICAgcmVhbGx5IGEgdGVtcGxhdGUgdGhhdCdzIGJlaW5nIHJldHVybmVkLiAgKi8KCW9sZF9kZWNsID0gREVDTF9URU1QTEFURV9SRVNVTFQgKG9sZF9kZWNsKTsKCiAgICAgIGlmIChvbGRfZGVjbCAmJiBERUNMX1NUQVRJQ19GVU5DVElPTl9QIChvbGRfZGVjbCkKCSAgJiYgVFJFRV9DT0RFIChUUkVFX1RZUEUgKGRlY2wpKSA9PSBNRVRIT0RfVFlQRSkKCS8qIFJlbW92ZSB0aGUgYHRoaXMnIHBhcm0gYWRkZWQgYnkgZ3Jva2NsYXNzZm4uCgkgICBYWFggSXNuJ3QgdGhpcyBkb25lIGluIHN0YXJ0X2Z1bmN0aW9uLCB0b28/ICAqLwoJcmV2ZXJ0X3N0YXRpY19tZW1iZXJfZm4gKGRlY2wpOwogICAgICBpZiAob2xkX2RlY2wgJiYgREVDTF9BUlRJRklDSUFMIChvbGRfZGVjbCkpCgllcnJvciAoImRlZmluaXRpb24gb2YgaW1wbGljaXRseS1kZWNsYXJlZCAlcUQiLCBvbGRfZGVjbCk7CgogICAgICBpZiAob2xkX2RlY2wpCgl7CgkgIHRyZWUgb2s7CgkgIHRyZWUgcHVzaGVkX3Njb3BlOwoKCSAgLyogU2luY2Ugd2UndmUgc21hc2hlZCBPTERfREVDTCB0byBpdHMKCSAgICAgREVDTF9URU1QTEFURV9SRVNVTFQsIHdlIG11c3QgZG8gdGhlIHNhbWUgdG8gREVDTC4gICovCgkgIGlmIChUUkVFX0NPREUgKGRlY2wpID09IFRFTVBMQVRFX0RFQ0wpCgkgICAgZGVjbCA9IERFQ0xfVEVNUExBVEVfUkVTVUxUIChkZWNsKTsKCgkgIC8qIEF0dGVtcHQgdG8gbWVyZ2UgdGhlIGRlY2xhcmF0aW9ucy4gIFRoaXMgY2FuIGZhaWwsIGluCgkgICAgIHRoZSBjYXNlIG9mIHNvbWUgaW52YWxpZCBzcGVjaWFsaXphdGlvbiBkZWNsYXJhdGlvbnMuICAqLwoJICBwdXNoZWRfc2NvcGUgPSBwdXNoX3Njb3BlIChjdHlwZSk7CgkgIG9rID0gZHVwbGljYXRlX2RlY2xzIChkZWNsLCBvbGRfZGVjbCk7CgkgIGlmIChwdXNoZWRfc2NvcGUpCgkgICAgcG9wX3Njb3BlIChwdXNoZWRfc2NvcGUpOwoJICBpZiAoIW9rKQoJICAgIHsKCSAgICAgIGVycm9yICgibm8gJXEjRCBtZW1iZXIgZnVuY3Rpb24gZGVjbGFyZWQgaW4gY2xhc3MgJXFUIiwKCQkgICAgIGRlY2wsIGN0eXBlKTsKCSAgICAgIHJldHVybiBOVUxMX1RSRUU7CgkgICAgfQoJICByZXR1cm4gb2xkX2RlY2w7Cgl9CiAgICB9CgogIGlmIChERUNMX0NPTlNUUlVDVE9SX1AgKGRlY2wpICYmICFncm9rX2N0b3JfcHJvcGVydGllcyAoY3R5cGUsIGRlY2wpKQogICAgcmV0dXJuIE5VTExfVFJFRTsKCiAgaWYgKGN0eXBlID09IE5VTExfVFJFRSB8fCBjaGVjaykKICAgIHJldHVybiBkZWNsOwoKICBpZiAodmlydHVhbHApCiAgICBERUNMX1ZJUlRVQUxfUCAoZGVjbCkgPSAxOwoKICByZXR1cm4gZGVjbDsKfQoKLyogREVDTCBpcyBhIFZBUl9ERUNMIGZvciBhIHN0YXRpYyBkYXRhIG1lbWJlci4gIFNldCBmbGFncyB0byByZWZsZWN0CiAgIHRoZSBsaW5rYWdlIHRoYXQgREVDTCB3aWxsIHJlY2VpdmUgaW4gdGhlIG9iamVjdCBmaWxlLiAgKi8KCnN0YXRpYyB2b2lkCnNldF9saW5rYWdlX2Zvcl9zdGF0aWNfZGF0YV9tZW1iZXIgKHRyZWUgZGVjbCkKewogIC8qIEEgc3RhdGljIGRhdGEgbWVtYmVyIGFsd2F5cyBoYXMgc3RhdGljIHN0b3JhZ2UgZHVyYXRpb24gYW5kCiAgICAgZXh0ZXJuYWwgbGlua2FnZS4gIE5vdGUgdGhhdCBzdGF0aWMgZGF0YSBtZW1iZXJzIGFyZSBmb3JiaWRkZW4gaW4KICAgICBsb2NhbCBjbGFzc2VzIC0tIHRoZSBvbmx5IHNpdHVhdGlvbiBpbiB3aGljaCBhIGNsYXNzIGhhcwogICAgIG5vbi1leHRlcm5hbCBsaW5rYWdlLiAgKi8KICBUUkVFX1BVQkxJQyAoZGVjbCkgPSAxOwogIFRSRUVfU1RBVElDIChkZWNsKSA9IDE7CiAgLyogRm9yIG5vbi10ZW1wbGF0ZSBjbGFzc2VzLCBzdGF0aWMgZGF0YSBtZW1iZXJzIGFyZSBhbHdheXMgcHV0CiAgICAgb3V0IGluIGV4YWN0bHkgdGhvc2UgZmlsZXMgd2hlcmUgdGhleSBhcmUgZGVmaW5lZCwganVzdCBhcwogICAgIHdpdGggb3JkaW5hcnkgbmFtZXNwYWNlLXNjb3BlIHZhcmlhYmxlcy4gICovCiAgaWYgKCFwcm9jZXNzaW5nX3RlbXBsYXRlX2RlY2wpCiAgICBERUNMX0lOVEVSRkFDRV9LTk9XTiAoZGVjbCkgPSAxOwp9CgovKiBDcmVhdGUgYSBWQVJfREVDTCBuYW1lZCBOQU1FIHdpdGggdGhlIGluZGljYXRlZCBUWVBFLgoKICAgSWYgU0NPUEUgaXMgbm9uLU5VTEwsIGl0IGlzIHRoZSBjbGFzcyB0eXBlIG9yIG5hbWVzcGFjZSBjb250YWluaW5nCiAgIHRoZSB2YXJpYWJsZS4gIElmIFNDT1BFIGlzIE5VTEwsIHRoZSB2YXJpYWJsZSBzaG91bGQgaXMgY3JlYXRlZCBpbgogICB0aGUgaW5uZXJtb3N0IGVuY2xvc2luZ3Mgc2NvcGUuICAqLwoKc3RhdGljIHRyZWUKZ3Jva3ZhcmRlY2wgKHRyZWUgdHlwZSwKICAgICAgICAgICAgIHRyZWUgbmFtZSwKCSAgICAgY29uc3QgY3BfZGVjbF9zcGVjaWZpZXJfc2VxICpkZWNsc3BlY3MsCiAgICAgICAgICAgICBpbnQgaW5pdGlhbGl6ZWQsCiAgICAgICAgICAgICBpbnQgY29uc3RwLAogICAgICAgICAgICAgdHJlZSBzY29wZSkKewogIHRyZWUgZGVjbDsKICB0cmVlIGV4cGxpY2l0X3Njb3BlOwoKICBnY2NfYXNzZXJ0ICghbmFtZSB8fCBUUkVFX0NPREUgKG5hbWUpID09IElERU5USUZJRVJfTk9ERSk7CgogIC8qIENvbXB1dGUgdGhlIHNjb3BlIGluIHdoaWNoIHRvIHBsYWNlIHRoZSB2YXJpYWJsZSwgYnV0IHJlbWVtYmVyCiAgICAgd2hldGhlciBvciBub3QgdGhhdCBzY29wZSB3YXMgZXhwbGljaXRseSBzcGVjaWZpZWQgYnkgdGhlIHVzZXIuICAgKi8KICBleHBsaWNpdF9zY29wZSA9IHNjb3BlOwogIGlmICghc2NvcGUpCiAgICB7CiAgICAgIC8qIEFuIGV4cGxpY2l0ICJleHRlcm4iIHNwZWNpZmllciBpbmRpY2F0ZXMgYSBuYW1lc3BhY2Utc2NvcGUKCSB2YXJpYWJsZS4gICovCiAgICAgIGlmIChkZWNsc3BlY3MtPnN0b3JhZ2VfY2xhc3MgPT0gc2NfZXh0ZXJuKQoJc2NvcGUgPSBjdXJyZW50X25hbWVzcGFjZTsKICAgICAgZWxzZSBpZiAoIWF0X2Z1bmN0aW9uX3Njb3BlX3AgKCkpCglzY29wZSA9IGN1cnJlbnRfc2NvcGUgKCk7CiAgICB9CgogIGlmIChzY29wZQogICAgICAmJiAoLyogSWYgdGhlIHZhcmlhYmxlIGlzIGEgbmFtZXNwYWNlLXNjb3BlIHZhcmlhYmxlIGRlY2xhcmVkIGluIGEKCSAgICAgdGVtcGxhdGUsIHdlIG5lZWQgREVDTF9MQU5HX1NQRUNJRklDLiAgKi8KCSAgKFRSRUVfQ09ERSAoc2NvcGUpID09IE5BTUVTUEFDRV9ERUNMICYmIHByb2Nlc3NpbmdfdGVtcGxhdGVfZGVjbCkKCSAgLyogU2ltaWxhcmx5IGZvciBuYW1lc3BhY2Utc2NvcGUgdmFyaWFibGVzIHdpdGggbGFuZ3VhZ2UgbGlua2FnZQoJICAgICBvdGhlciB0aGFuIEMrKy4gICovCgkgIHx8IChUUkVFX0NPREUgKHNjb3BlKSA9PSBOQU1FU1BBQ0VfREVDTAoJICAgICAgJiYgY3VycmVudF9sYW5nX25hbWUgIT0gbGFuZ19uYW1lX2NwbHVzcGx1cykKCSAgLyogU2ltaWxhcmx5IGZvciBzdGF0aWMgZGF0YSBtZW1iZXJzLiAgKi8KCSAgfHwgVFlQRV9QIChzY29wZSkpKQogICAgZGVjbCA9IGJ1aWxkX2xhbmdfZGVjbCAoVkFSX0RFQ0wsIG5hbWUsIHR5cGUpOwogIGVsc2UKICAgIGRlY2wgPSBidWlsZF9kZWNsIChWQVJfREVDTCwgbmFtZSwgdHlwZSk7CgogIGlmIChleHBsaWNpdF9zY29wZSAmJiBUUkVFX0NPREUgKGV4cGxpY2l0X3Njb3BlKSA9PSBOQU1FU1BBQ0VfREVDTCkKICAgIHNldF9kZWNsX25hbWVzcGFjZSAoZGVjbCwgZXhwbGljaXRfc2NvcGUsIDApOwogIGVsc2UKICAgIERFQ0xfQ09OVEVYVCAoZGVjbCkgPSBzY29wZTsKCiAgaWYgKGRlY2xzcGVjcy0+c3RvcmFnZV9jbGFzcyA9PSBzY19leHRlcm4pCiAgICB7CiAgICAgIERFQ0xfVEhJU19FWFRFUk4gKGRlY2wpID0gMTsKICAgICAgREVDTF9FWFRFUk5BTCAoZGVjbCkgPSAhaW5pdGlhbGl6ZWQ7CiAgICB9CgogIGlmIChERUNMX0NMQVNTX1NDT1BFX1AgKGRlY2wpKQogICAgewogICAgICBzZXRfbGlua2FnZV9mb3Jfc3RhdGljX2RhdGFfbWVtYmVyIChkZWNsKTsKICAgICAgLyogVGhpcyBmdW5jdGlvbiBpcyBvbmx5IGNhbGxlZCB3aXRoIG91dC1vZi1jbGFzcyBkZWZpbml0aW9ucy4gICovCiAgICAgIERFQ0xfRVhURVJOQUwgKGRlY2wpID0gMDsKICAgIH0KICAvKiBBdCB0b3AgbGV2ZWwsIGVpdGhlciBgc3RhdGljJyBvciBubyBzLmMuIG1ha2VzIGEgZGVmaW5pdGlvbgogICAgIChwZXJoYXBzIHRlbnRhdGl2ZSksIGFuZCBhYnNlbmNlIG9mIGBzdGF0aWMnIG1ha2VzIGl0IHB1YmxpYy4gICovCiAgZWxzZSBpZiAodG9wbGV2ZWxfYmluZGluZ3NfcCAoKSkKICAgIHsKICAgICAgVFJFRV9QVUJMSUMgKGRlY2wpID0gKGRlY2xzcGVjcy0+c3RvcmFnZV9jbGFzcyAhPSBzY19zdGF0aWMKCQkJICAgICYmIChERUNMX1RISVNfRVhURVJOIChkZWNsKSB8fCAhIGNvbnN0cCkpOwogICAgICBUUkVFX1NUQVRJQyAoZGVjbCkgPSAhIERFQ0xfRVhURVJOQUwgKGRlY2wpOwogICAgfQogIC8qIE5vdCBhdCB0b3AgbGV2ZWwsIG9ubHkgYHN0YXRpYycgbWFrZXMgYSBzdGF0aWMgZGVmaW5pdGlvbi4gICovCiAgZWxzZQogICAgewogICAgICBUUkVFX1NUQVRJQyAoZGVjbCkgPSBkZWNsc3BlY3MtPnN0b3JhZ2VfY2xhc3MgPT0gc2Nfc3RhdGljOwogICAgICBUUkVFX1BVQkxJQyAoZGVjbCkgPSBERUNMX0VYVEVSTkFMIChkZWNsKTsKICAgIH0KCiAgaWYgKGRlY2xzcGVjcy0+c3BlY3NbKGludClkc190aHJlYWRdKQogICAgewogICAgICBpZiAodGFyZ2V0bS5oYXZlX3RscykKCURFQ0xfVEhSRUFEX0xPQ0FMIChkZWNsKSA9IDE7CiAgICAgIGVsc2UKCS8qIEEgbWVyZSB3YXJuaW5nIGlzIHN1cmUgdG8gcmVzdWx0IGluIGltcHJvcGVyIHNlbWFudGljcwoJICAgYXQgcnVudGltZS4gIERvbid0IGJvdGhlciB0byBhbGxvdyB0aGlzIHRvIGNvbXBpbGUuICAqLwoJZXJyb3IgKCJ0aHJlYWQtbG9jYWwgc3RvcmFnZSBub3Qgc3VwcG9ydGVkIGZvciB0aGlzIHRhcmdldCIpOwogICAgfQoKICBpZiAoVFJFRV9QVUJMSUMgKGRlY2wpKQogICAgewogICAgICAvKiBbYmFzaWMubGlua106IEEgbmFtZSB3aXRoIG5vIGxpbmthZ2UgKG5vdGFibHksIHRoZSBuYW1lIG9mIGEgY2xhc3MKCSBvciBlbnVtZXJhdGlvbiBkZWNsYXJlZCBpbiBhIGxvY2FsIHNjb3BlKSBzaGFsbCBub3QgYmUgdXNlZCB0bwoJIGRlY2xhcmUgYW4gZW50aXR5IHdpdGggbGlua2FnZS4KCgkgT25seSBjaGVjayB0aGlzIGZvciBwdWJsaWMgZGVjbHMgZm9yIG5vdy4gICovCiAgICAgIHRyZWUgdCA9IG5vX2xpbmthZ2VfY2hlY2sgKFRSRUVfVFlQRSAoZGVjbCksIC8qcmVsYXhlZF9wPSovZmFsc2UpOwogICAgICBpZiAodCkKCXsKCSAgaWYgKFRZUEVfQU5PTllNT1VTX1AgKHQpKQoJICAgIHsKCSAgICAgIGlmIChERUNMX0VYVEVSTl9DX1AgKGRlY2wpKQoJCS8qIEFsbG93IHRoaXM7IGl0J3MgcHJldHR5IGNvbW1vbiBpbiBDLiAgKi8KCQkgIDsKCSAgICAgIGVsc2UKCQl7CgkJICAvKiBEUnMgMTMyLCAzMTkgYW5kIDM4OSBzZWVtIHRvIGluZGljYXRlIHR5cGVzIHdpdGgKCQkgICAgIG5vIGxpbmthZ2UgY2FuIG9ubHkgYmUgdXNlZCB0byBkZWNsYXJlIGV4dGVybiAiQyIKCQkgICAgIGVudGl0aWVzLiAgU2luY2UgaXQncyBub3QgYWx3YXlzIGFuIGVycm9yIGluIHRoZQoJCSAgICAgSVNPIEMrKyA5MCBTdGFuZGFyZCwgd2Ugb25seSBpc3N1ZSBhIHdhcm5pbmcuICAqLwoJCSAgd2FybmluZyAoIm5vbi1sb2NhbCB2YXJpYWJsZSAlcSNEIHVzZXMgYW5vbnltb3VzIHR5cGUiLAoJCQkgICBkZWNsKTsKCQkgIGlmIChERUNMX09SSUdJTkFMX1RZUEUgKFRZUEVfTkFNRSAodCkpKQoJCSAgICBjcF93YXJuaW5nX2F0ICgiJXEjRCBkb2VzIG5vdCByZWZlciB0byB0aGUgdW5xdWFsaWZpZWQgIgoJCQkJICAgInR5cGUsIHNvIGl0IGlzIG5vdCB1c2VkIGZvciBsaW5rYWdlIiwKCQkJCSAgIFRZUEVfTkFNRSAodCkpOwoJCX0KCSAgICB9CgkgIGVsc2UKCSAgICB3YXJuaW5nICgibm9uLWxvY2FsIHZhcmlhYmxlICVxI0QgdXNlcyBsb2NhbCB0eXBlICVxVCIsIGRlY2wsIHQpOwoJfQogICAgfQogIGVsc2UKICAgIERFQ0xfSU5URVJGQUNFX0tOT1dOIChkZWNsKSA9IDE7CgogIHJldHVybiBkZWNsOwp9CgovKiBDcmVhdGUgYW5kIHJldHVybiBhIGNhbm9uaWNhbCBwb2ludGVyIHRvIG1lbWJlciBmdW5jdGlvbiB0eXBlLCBmb3IKICAgVFlQRSwgd2hpY2ggaXMgYSBQT0lOVEVSX1RZUEUgdG8gYSBNRVRIT0RfVFlQRS4gICovCgp0cmVlCmJ1aWxkX3B0cm1lbWZ1bmNfdHlwZSAodHJlZSB0eXBlKQp7CiAgdHJlZSBmaWVsZCwgZmllbGRzOwogIHRyZWUgdDsKICB0cmVlIHVucXVhbGlmaWVkX3ZhcmlhbnQgPSBOVUxMX1RSRUU7CgogIGlmICh0eXBlID09IGVycm9yX21hcmtfbm9kZSkKICAgIHJldHVybiB0eXBlOwoKICAvKiBJZiBhIGNhbm9uaWNhbCB0eXBlIGFscmVhZHkgZXhpc3RzIGZvciB0aGlzIHR5cGUsIHVzZSBpdC4gIFdlIHVzZQogICAgIHRoaXMgbWV0aG9kIGluc3RlYWQgb2YgdHlwZV9oYXNoX2Nhbm9uLCBiZWNhdXNlIGl0IG9ubHkgZG9lcyBhCiAgICAgc2ltcGxlIGVxdWFsaXR5IGNoZWNrIG9uIHRoZSBsaXN0IG9mIGZpZWxkIG1lbWJlcnMuICAqLwoKICBpZiAoKHQgPSBUWVBFX0dFVF9QVFJNRU1GVU5DX1RZUEUgKHR5cGUpKSkKICAgIHJldHVybiB0OwoKICAvKiBNYWtlIHN1cmUgdGhhdCB3ZSBhbHdheXMgaGF2ZSB0aGUgdW5xdWFsaWZpZWQgcG9pbnRlci10by1tZW1iZXIKICAgICB0eXBlIGZpcnN0LiAgKi8KICBpZiAoY3BfdHlwZV9xdWFscyAodHlwZSkgIT0gVFlQRV9VTlFVQUxJRklFRCkKICAgIHVucXVhbGlmaWVkX3ZhcmlhbnQKICAgICAgPSBidWlsZF9wdHJtZW1mdW5jX3R5cGUgKFRZUEVfTUFJTl9WQVJJQU5UICh0eXBlKSk7CgogIC8qIEFQUExFIExPQ0FMIGJlZ2luIEtFWFQgMi45NS1wdG1mLWNvbXBhdGliaWxpdHkgLS10dXJseSAqLwogIGlmIChUQVJHRVRfS0VYVEFCSSkKICAgIHsKICAgICAgdHJlZSB1ID0gbWFrZV9hZ2dyX3R5cGUgKFVOSU9OX1RZUEUpOwogICAgICBTRVRfSVNfQUdHUl9UWVBFICh1LCAwKTsKICAgICAgeHJlZl9iYXNldHlwZXMgKHUsIE5VTExfVFJFRSk7CiAgICAgIGZpZWxkcyA9IGJ1aWxkX2RlY2wgKEZJRUxEX0RFQ0wsIGRlbHRhMl9pZGVudGlmaWVyLCBkZWx0YV90eXBlX25vZGUpOwogICAgICBUUkVFX0NIQUlOIChmaWVsZHMpIAoJPSBidWlsZF9kZWNsIChGSUVMRF9ERUNMLCBwZm5faWRlbnRpZmllciwgdHlwZSk7CiAgICAgIGZpbmlzaF9idWlsdGluX3N0cnVjdCAodSwgIl9fcHRybWVtZnVuY190eXBlIiwgZmllbGRzLCBwdHJfdHlwZV9ub2RlKTsKICAgICAgVFlQRV9OQU1FICh1KSA9IE5VTExfVFJFRTsKICAKICAgICAgdCA9IG1ha2VfYWdncl90eXBlIChSRUNPUkRfVFlQRSk7CiAgICAgIHhyZWZfYmFzZXR5cGVzICh0LCBOVUxMX1RSRUUpOwogIAogICAgICAvKiBMZXQgdGhlIGZyb250LWVuZCBrbm93IHRoaXMgaXMgYSBwb2ludGVyIHRvIG1lbWJlciBmdW5jdGlvbi4uLiAgKi8KICAgICAgVFlQRV9QVFJNRU1GVU5DX0ZMQUcgKHQpID0gMTsKICAgICAgLyogLi4uIGFuZCBub3QgcmVhbGx5IGFuIGFnZ3JlZ2F0ZS4gICovCiAgICAgIFNFVF9JU19BR0dSX1RZUEUgKHQsIDApOwogIAogICAgICBmaWVsZHMgPSBidWlsZF9kZWNsIChGSUVMRF9ERUNMLCBwZm5fb3JfZGVsdGEyX2lkZW50aWZpZXIsIHUpOwogICAgICBUUkVFX0NIQUlOIChmaWVsZHMpID0KCWJ1aWxkX2RlY2wgKEZJRUxEX0RFQ0wsIGluZGV4X2lkZW50aWZpZXIsIGRlbHRhX3R5cGVfbm9kZSk7CiAgICAgIFRSRUVfQ0hBSU4gKFRSRUVfQ0hBSU4gKGZpZWxkcykpID0gCglidWlsZF9kZWNsIChGSUVMRF9ERUNMLCBkZWx0YV9pZGVudGlmaWVyLCBkZWx0YV90eXBlX25vZGUpOwogICAgICBmaW5pc2hfYnVpbHRpbl9zdHJ1Y3QgKHQsICJfX3B0cm1lbWZ1bmNfdHlwZSIsIGZpZWxkcywgcHRyX3R5cGVfbm9kZSk7CiAgICB9CiAgZWxzZQogICAgewogIC8qIEFQUExFIExPQ0FMIGVuZCBLRVhUIDIuOTUtcHRtZi1jb21wYXRpYmlsaXR5IC0tdHVybHkgKi8KCiAgdCA9IG1ha2VfYWdncl90eXBlIChSRUNPUkRfVFlQRSk7CiAgeHJlZl9iYXNldHlwZXMgKHQsIE5VTExfVFJFRSk7CgogIC8qIExldCB0aGUgZnJvbnQtZW5kIGtub3cgdGhpcyBpcyBhIHBvaW50ZXIgdG8gbWVtYmVyIGZ1bmN0aW9uLi4uICAqLwogIFRZUEVfUFRSTUVNRlVOQ19GTEFHICh0KSA9IDE7CiAgLyogLi4uIGFuZCBub3QgcmVhbGx5IGFuIGFnZ3JlZ2F0ZS4gICovCiAgU0VUX0lTX0FHR1JfVFlQRSAodCwgMCk7CgogIGZpZWxkID0gYnVpbGRfZGVjbCAoRklFTERfREVDTCwgcGZuX2lkZW50aWZpZXIsIHR5cGUpOwogIGZpZWxkcyA9IGZpZWxkOwoKICBmaWVsZCA9IGJ1aWxkX2RlY2wgKEZJRUxEX0RFQ0wsIGRlbHRhX2lkZW50aWZpZXIsIGRlbHRhX3R5cGVfbm9kZSk7CiAgVFJFRV9DSEFJTiAoZmllbGQpID0gZmllbGRzOwogIGZpZWxkcyA9IGZpZWxkOwoKICBmaW5pc2hfYnVpbHRpbl9zdHJ1Y3QgKHQsICJfX3B0cm1lbWZ1bmNfdHlwZSIsIGZpZWxkcywgcHRyX3R5cGVfbm9kZSk7CiAgLyogQVBQTEUgTE9DQUwgS0VYVCAyLjk1LXB0bWYtY29tcGF0aWJpbGl0eSAtLXR1cmx5ICovCiAgICB9CgogIC8qIFphcCBvdXQgdGhlIG5hbWUgc28gdGhhdCB0aGUgYmFjay1lbmQgd2lsbCBnaXZlIHVzIHRoZSBkZWJ1Z2dpbmcKICAgICBpbmZvcm1hdGlvbiBmb3IgdGhpcyBhbm9ueW1vdXMgUkVDT1JEX1RZUEUuICAqLwogIFRZUEVfTkFNRSAodCkgPSBOVUxMX1RSRUU7CgogIC8qIElmIHRoaXMgaXMgbm90IHRoZSB1bnF1YWxpZmllZCBmb3JtIG9mIHRoaXMgcG9pbnRlci10by1tZW1iZXIKICAgICB0eXBlLCBzZXQgdGhlIFRZUEVfTUFJTl9WQVJJQU5UIGZvciB0aGlzIHR5cGUgdG8gYmUgdGhlCiAgICAgdW5xdWFsaWZpZWQgdHlwZS4gIFNpbmNlIHRoZXkgYXJlIGFjdHVhbGx5IFJFQ09SRF9UWVBFcyB0aGF0IGFyZQogICAgIG5vdCB2YXJpYW50cyBvZiBlYWNoIG90aGVyLCB3ZSBtdXN0IGRvIHRoaXMgbWFudWFsbHkuICAqLwogIGlmIChjcF90eXBlX3F1YWxzICh0eXBlKSAhPSBUWVBFX1VOUVVBTElGSUVEKQogICAgewogICAgICB0ID0gYnVpbGRfcXVhbGlmaWVkX3R5cGUgKHQsIGNwX3R5cGVfcXVhbHMgKHR5cGUpKTsKICAgICAgVFlQRV9NQUlOX1ZBUklBTlQgKHQpID0gdW5xdWFsaWZpZWRfdmFyaWFudDsKICAgICAgVFlQRV9ORVhUX1ZBUklBTlQgKHQpID0gVFlQRV9ORVhUX1ZBUklBTlQgKHVucXVhbGlmaWVkX3ZhcmlhbnQpOwogICAgICBUWVBFX05FWFRfVkFSSUFOVCAodW5xdWFsaWZpZWRfdmFyaWFudCkgPSB0OwogICAgfQoKICAvKiBDYWNoZSB0aGlzIHBvaW50ZXItdG8tbWVtYmVyIHR5cGUgc28gdGhhdCB3ZSBjYW4gZmluZCBpdCBhZ2FpbgogICAgIGxhdGVyLiAgKi8KICBUWVBFX1NFVF9QVFJNRU1GVU5DX1RZUEUgKHR5cGUsIHQpOwoKICByZXR1cm4gdDsKfQoKLyogQ3JlYXRlIGFuZCByZXR1cm4gYSBwb2ludGVyIHRvIGRhdGEgbWVtYmVyIHR5cGUuICAqLwoKdHJlZQpidWlsZF9wdHJtZW1fdHlwZSAodHJlZSBjbGFzc190eXBlLCB0cmVlIG1lbWJlcl90eXBlKQp7CiAgaWYgKFRSRUVfQ09ERSAobWVtYmVyX3R5cGUpID09IE1FVEhPRF9UWVBFKQogICAgewogICAgICB0cmVlIGFyZ190eXBlczsKCiAgICAgIGFyZ190eXBlcyA9IFRZUEVfQVJHX1RZUEVTIChtZW1iZXJfdHlwZSk7CiAgICAgIGNsYXNzX3R5cGUgPSAoY3BfYnVpbGRfcXVhbGlmaWVkX3R5cGUKCQkgICAgKGNsYXNzX3R5cGUsCgkJICAgICBjcF90eXBlX3F1YWxzIChUUkVFX1RZUEUgKFRSRUVfVkFMVUUgKGFyZ190eXBlcykpKSkpOwogICAgICBtZW1iZXJfdHlwZQoJPSBidWlsZF9tZXRob2RfdHlwZV9kaXJlY3RseSAoY2xhc3NfdHlwZSwKCQkJCSAgICAgIFRSRUVfVFlQRSAobWVtYmVyX3R5cGUpLAoJCQkJICAgICAgVFJFRV9DSEFJTiAoYXJnX3R5cGVzKSk7CiAgICAgIHJldHVybiBidWlsZF9wdHJtZW1mdW5jX3R5cGUgKGJ1aWxkX3BvaW50ZXJfdHlwZSAobWVtYmVyX3R5cGUpKTsKICAgIH0KICBlbHNlCiAgICB7CiAgICAgIGdjY19hc3NlcnQgKFRSRUVfQ09ERSAobWVtYmVyX3R5cGUpICE9IEZVTkNUSU9OX1RZUEUpOwogICAgICByZXR1cm4gYnVpbGRfb2Zmc2V0X3R5cGUgKGNsYXNzX3R5cGUsIG1lbWJlcl90eXBlKTsKICAgIH0KfQoKLyogREVDTCBpcyBhIFZBUl9ERUNMIGRlZmluZWQgaW4tY2xhc3MsIHdob3NlIFRZUEUgaXMgYWxzbyBnaXZlbi4KICAgQ2hlY2sgdG8gc2VlIHRoYXQgdGhlIGRlZmluaXRpb24gaXMgdmFsaWQuICBJc3N1ZSBhcHByb3ByaWF0ZSBlcnJvcgogICBtZXNzYWdlcy4gIFJldHVybiAxIGlmIHRoZSBkZWZpbml0aW9uIGlzIHBhcnRpY3VsYXJseSBiYWQsIG9yIDAKICAgb3RoZXJ3aXNlLiAgKi8KCmludApjaGVja19zdGF0aWNfdmFyaWFibGVfZGVmaW5pdGlvbiAodHJlZSBkZWNsLCB0cmVlIHR5cGUpCnsKICAvKiBNb3Rpb24gMTAgYXQgU2FuIERpZWdvOiBJZiBhIHN0YXRpYyBjb25zdCBpbnRlZ3JhbCBkYXRhIG1lbWJlciBpcwogICAgIGluaXRpYWxpemVkIHdpdGggYW4gaW50ZWdyYWwgY29uc3RhbnQgZXhwcmVzc2lvbiwgdGhlIGluaXRpYWxpemVyCiAgICAgbWF5IGFwcGVhciBlaXRoZXIgaW4gdGhlIGRlY2xhcmF0aW9uICh3aXRoaW4gdGhlIGNsYXNzKSwgb3IgaW4KICAgICB0aGUgZGVmaW5pdGlvbiwgYnV0IG5vdCBib3RoLiAgSWYgaXQgYXBwZWFycyBpbiB0aGUgY2xhc3MsIHRoZQogICAgIG1lbWJlciBpcyBhIG1lbWJlciBjb25zdGFudC4gIFRoZSBmaWxlLXNjb3BlIGRlZmluaXRpb24gaXMgYWx3YXlzCiAgICAgcmVxdWlyZWQuICAqLwogIGlmICghQVJJVEhNRVRJQ19UWVBFX1AgKHR5cGUpICYmIFRSRUVfQ09ERSAodHlwZSkgIT0gRU5VTUVSQUxfVFlQRSkKICAgIHsKICAgICAgZXJyb3IgKCJpbnZhbGlkIGluLWNsYXNzIGluaXRpYWxpemF0aW9uIG9mIHN0YXRpYyBkYXRhIG1lbWJlciAiCiAgICAgICAgICAgICAib2Ygbm9uLWludGVncmFsIHR5cGUgJXFUIiwKCSAgICAgdHlwZSk7CiAgICAgIC8qIElmIHdlIGp1c3QgcmV0dXJuIHRoZSBkZWNsYXJhdGlvbiwgY3Jhc2hlcyB3aWxsIHNvbWV0aW1lcwoJIG9jY3VyLiAgV2UgdGhlcmVmb3JlIHJldHVybiB2b2lkX3R5cGVfbm9kZSwgYXMgaWYgdGhpcyB3ZXJlIGEKCSBmcmllbmQgZGVjbGFyYXRpb24sIHRvIGNhdXNlIGNhbGxlcnMgdG8gY29tcGxldGVseSBpZ25vcmUKCSB0aGlzIGRlY2xhcmF0aW9uLiAgKi8KICAgICAgcmV0dXJuIDE7CiAgICB9CiAgZWxzZSBpZiAoIUNQX1RZUEVfQ09OU1RfUCAodHlwZSkpCiAgICBlcnJvciAoIklTTyBDKysgZm9yYmlkcyBpbi1jbGFzcyBpbml0aWFsaXphdGlvbiBvZiBub24tY29uc3QgIgogICAgICAgICAgICJzdGF0aWMgbWVtYmVyICVxRCIsCiAgICAgICAgICAgZGVjbCk7CiAgZWxzZSBpZiAocGVkYW50aWMgJiYgIUlOVEVHUkFMX1RZUEVfUCAodHlwZSkpCiAgICBwZWR3YXJuICgiSVNPIEMrKyBmb3JiaWRzIGluaXRpYWxpemF0aW9uIG9mIG1lbWJlciBjb25zdGFudCAiCiAgICAgICAgICAgICAiJXFEIG9mIG5vbi1pbnRlZ3JhbCB0eXBlICVxVCIsIGRlY2wsIHR5cGUpOwoKICByZXR1cm4gMDsKfQoKLyogR2l2ZW4gdGhlIFNJWkUgKGkuZS4sIG51bWJlciBvZiBlbGVtZW50cykgaW4gYW4gYXJyYXksIGNvbXB1dGUgYW4KICAgYXBwcm9wcmlhdGUgaW5kZXggdHlwZSBmb3IgdGhlIGFycmF5LiAgSWYgbm9uLU5VTEwsIE5BTUUgaXMgdGhlCiAgIG5hbWUgb2YgdGhlIHRoaW5nIGJlaW5nIGRlY2xhcmVkLiAgKi8KCnRyZWUKY29tcHV0ZV9hcnJheV9pbmRleF90eXBlICh0cmVlIG5hbWUsIHRyZWUgc2l6ZSkKewogIHRyZWUgdHlwZSA9IFRSRUVfVFlQRSAoc2l6ZSk7CiAgdHJlZSBpdHlwZTsKCiAgLyogVGhlIGFycmF5IGJvdW5kIG11c3QgYmUgYW4gaW50ZWdlciB0eXBlLiAgKi8KICBpZiAoIWRlcGVuZGVudF90eXBlX3AgKHR5cGUpICYmICFJTlRFR1JBTF9UWVBFX1AgKHR5cGUpKQogICAgewogICAgICBpZiAobmFtZSkKCWVycm9yICgic2l6ZSBvZiBhcnJheSAlcUQgaGFzIG5vbi1pbnRlZ3JhbCB0eXBlICVxVCIsIG5hbWUsIHR5cGUpOwogICAgICBlbHNlCgllcnJvciAoInNpemUgb2YgYXJyYXkgaGFzIG5vbi1pbnRlZ3JhbCB0eXBlICVxVCIsIHR5cGUpOwogICAgICBzaXplID0gaW50ZWdlcl9vbmVfbm9kZTsKICAgICAgdHlwZSA9IFRSRUVfVFlQRSAoc2l6ZSk7CiAgICB9CgogIGlmIChhYmlfdmVyc2lvbl9hdF9sZWFzdCAoMikKICAgICAgLyogV2Ugc2hvdWxkIG9ubHkgaGFuZGxlIHZhbHVlIGRlcGVuZGVudCBleHByZXNzaW9ucyBzcGVjaWFsbHkuICAqLwogICAgICA/IHZhbHVlX2RlcGVuZGVudF9leHByZXNzaW9uX3AgKHNpemUpCiAgICAgIC8qIEJ1dCBmb3IgYWJpLTEsIHdlIGhhbmRsZWQgYWxsIGluc3RhbmNlcyBpbiB0ZW1wbGF0ZXMuIFRoaXMKCSBlZmZlY3RzIHRoZSBtYW5nbGluZ3MgcHJvZHVjZWQuICAqLwogICAgICA6IHByb2Nlc3NpbmdfdGVtcGxhdGVfZGVjbCkKICAgIHJldHVybiBidWlsZF9pbmRleF90eXBlIChidWlsZF9taW4gKE1JTlVTX0VYUFIsIHNpemV0eXBlLAoJCQkJCXNpemUsIGludGVnZXJfb25lX25vZGUpKTsKCiAgLyogVGhlIHNpemUgbWlnaHQgYmUgdGhlIHJlc3VsdCBvZiBhIGNhc3QuICAqLwogIFNUUklQX1RZUEVfTk9QUyAoc2l6ZSk7CgogIC8qIEl0IG1pZ2h0IGJlIGEgY29uc3QgdmFyaWFibGUgb3IgZW51bWVyYXRpb24gY29uc3RhbnQuICAqLwogIHNpemUgPSBpbnRlZ3JhbF9jb25zdGFudF92YWx1ZSAoc2l6ZSk7CgogIC8qIE5vcm1hbGx5LCB0aGUgYXJyYXktYm91bmQgd2lsbCBiZSBhIGNvbnN0YW50LiAgKi8KICBpZiAoVFJFRV9DT0RFIChzaXplKSA9PSBJTlRFR0VSX0NTVCkKICAgIHsKICAgICAgLyogQ2hlY2sgdG8gc2VlIGlmIHRoZSBhcnJheSBib3VuZCBvdmVyZmxvd2VkLiAgTWFrZSB0aGF0IGFuCgkgZXJyb3IsIG5vIG1hdHRlciBob3cgZ2VuZXJvdXMgd2UncmUgYmVpbmcuICAqLwogICAgICBpbnQgb2xkX2ZsYWdfcGVkYW50aWNfZXJyb3JzID0gZmxhZ19wZWRhbnRpY19lcnJvcnM7CiAgICAgIGludCBvbGRfcGVkYW50aWMgPSBwZWRhbnRpYzsKICAgICAgcGVkYW50aWMgPSBmbGFnX3BlZGFudGljX2Vycm9ycyA9IDE7CiAgICAgIGNvbnN0YW50X2V4cHJlc3Npb25fd2FybmluZyAoc2l6ZSk7CiAgICAgIHBlZGFudGljID0gb2xkX3BlZGFudGljOwogICAgICBmbGFnX3BlZGFudGljX2Vycm9ycyA9IG9sZF9mbGFnX3BlZGFudGljX2Vycm9yczsKCiAgICAgIC8qIEFuIGFycmF5IG11c3QgaGF2ZSBhIHBvc2l0aXZlIG51bWJlciBvZiBlbGVtZW50cy4gICovCiAgICAgIGlmIChJTlRfQ1NUX0xUIChzaXplLCBpbnRlZ2VyX3plcm9fbm9kZSkpCgl7CgkgIGlmIChuYW1lKQoJICAgIGVycm9yICgic2l6ZSBvZiBhcnJheSAlcUQgaXMgbmVnYXRpdmUiLCBuYW1lKTsKCSAgZWxzZQoJICAgIGVycm9yICgic2l6ZSBvZiBhcnJheSBpcyBuZWdhdGl2ZSIpOwoJICBzaXplID0gaW50ZWdlcl9vbmVfbm9kZTsKCX0KICAgICAgLyogQXMgYW4gZXh0ZW5zaW9uIHdlIGFsbG93IHplcm8tc2l6ZWQgYXJyYXlzLiAgV2UgYWx3YXlzIGFsbG93CgkgdGhlbSBpbiBzeXN0ZW0gaGVhZGVycyBiZWNhdXNlIGdsaWJjIHVzZXMgdGhlbS4gICovCiAgICAgIGVsc2UgaWYgKGludGVnZXJfemVyb3AgKHNpemUpICYmIHBlZGFudGljICYmICFpbl9zeXN0ZW1faGVhZGVyKQoJewoJICBpZiAobmFtZSkKCSAgICBwZWR3YXJuICgiSVNPIEMrKyBmb3JiaWRzIHplcm8tc2l6ZSBhcnJheSAlcUQiLCBuYW1lKTsKCSAgZWxzZQoJICAgIHBlZHdhcm4gKCJJU08gQysrIGZvcmJpZHMgemVyby1zaXplIGFycmF5Iik7Cgl9CiAgICB9CiAgZWxzZSBpZiAoVFJFRV9DT05TVEFOVCAoc2l6ZSkpCiAgICB7CiAgICAgIC8qIGAoaW50KSAmZm4nIGlzIG5vdCBhIHZhbGlkIGFycmF5IGJvdW5kLiAgKi8KICAgICAgaWYgKG5hbWUpCgllcnJvciAoInNpemUgb2YgYXJyYXkgJXFEIGlzIG5vdCBhbiBpbnRlZ3JhbCBjb25zdGFudC1leHByZXNzaW9uIiwKICAgICAgICAgICAgICAgbmFtZSk7CiAgICAgIGVsc2UKCWVycm9yICgic2l6ZSBvZiBhcnJheSBpcyBub3QgYW4gaW50ZWdyYWwgY29uc3RhbnQtZXhwcmVzc2lvbiIpOwogICAgfQogIGVsc2UgaWYgKHBlZGFudGljKQogICAgewogICAgICBpZiAobmFtZSkKCXBlZHdhcm4gKCJJU08gQysrIGZvcmJpZHMgdmFyaWFibGUtc2l6ZSBhcnJheSAlcUQiLCBuYW1lKTsKICAgICAgZWxzZQoJcGVkd2FybiAoIklTTyBDKysgZm9yYmlkcyB2YXJpYWJsZS1zaXplIGFycmF5Iik7CiAgICB9CgogIGlmIChwcm9jZXNzaW5nX3RlbXBsYXRlX2RlY2wgJiYgIVRSRUVfQ09OU1RBTlQgKHNpemUpKQogICAgLyogQSB2YXJpYWJsZSBzaXplZCBhcnJheS4gICovCiAgICBpdHlwZSA9IGJ1aWxkX21pbiAoTUlOVVNfRVhQUiwgc2l6ZXR5cGUsIHNpemUsIGludGVnZXJfb25lX25vZGUpOwogIGVsc2UKICAgIHsKICAgICAgSE9TVF9XSURFX0lOVCBzYXZlZF9wcm9jZXNzaW5nX3RlbXBsYXRlX2RlY2w7CgogICAgICAvKiBDb21wdXRlIHRoZSBpbmRleCBvZiB0aGUgbGFyZ2VzdCBlbGVtZW50IGluIHRoZSBhcnJheS4gIEl0IGlzCiAgICAgCSBvbmUgbGVzcyB0aGFuIHRoZSBudW1iZXIgb2YgZWxlbWVudHMgaW4gdGhlIGFycmF5LiAgV2Ugc2F2ZQogICAgIAkgYW5kIHJlc3RvcmUgUFJPQ0VTU0lOR19URU1QTEFURV9ERUNMIHNvIHRoYXQgY29tcHV0YXRpb25zIGluCiAgICAgCSBjcF9idWlsZF9iaW5hcnlfb3Agd2lsbCBiZSBhcHByb3ByaWF0ZWx5IGZvbGRlZC4gICovCiAgICAgIHNhdmVkX3Byb2Nlc3NpbmdfdGVtcGxhdGVfZGVjbCA9IHByb2Nlc3NpbmdfdGVtcGxhdGVfZGVjbDsKICAgICAgcHJvY2Vzc2luZ190ZW1wbGF0ZV9kZWNsID0gMDsKICAgICAgaXR5cGUgPSBjcF9idWlsZF9iaW5hcnlfb3AgKE1JTlVTX0VYUFIsCgkJCQkgIGNwX2NvbnZlcnQgKHNzaXpldHlwZSwgc2l6ZSksCgkJCQkgIGNwX2NvbnZlcnQgKHNzaXpldHlwZSwgaW50ZWdlcl9vbmVfbm9kZSkpOwogICAgICBpdHlwZSA9IGZvbGQgKGl0eXBlKTsKICAgICAgcHJvY2Vzc2luZ190ZW1wbGF0ZV9kZWNsID0gc2F2ZWRfcHJvY2Vzc2luZ190ZW1wbGF0ZV9kZWNsOwoKICAgICAgaWYgKCFUUkVFX0NPTlNUQU5UIChpdHlwZSkpCgkvKiBBIHZhcmlhYmxlIHNpemVkIGFycmF5LiAgKi8KCWl0eXBlID0gdmFyaWFibGVfc2l6ZSAoaXR5cGUpOwogICAgICAvKiBNYWtlIHN1cmUgdGhhdCB0aGVyZSB3YXMgbm8gb3ZlcmZsb3cgd2hlbiBjcmVhdGluZyB0byBhIHNpZ25lZAogICAgIAkgaW5kZXggdHlwZS4gIChGb3IgZXhhbXBsZSwgb24gYSAzMi1iaXQgbWFjaGluZSwgYW4gYXJyYXkgd2l0aAogICAgIAkgc2l6ZSAyXjMyIC0gMSBpcyB0b28gYmlnLikgICovCiAgICAgIGVsc2UgaWYgKFRSRUVfT1ZFUkZMT1cgKGl0eXBlKSkKCXsKCSAgZXJyb3IgKCJvdmVyZmxvdyBpbiBhcnJheSBkaW1lbnNpb24iKTsKCSAgVFJFRV9PVkVSRkxPVyAoaXR5cGUpID0gMDsKCX0KICAgIH0KCiAgLyogQ3JlYXRlIGFuZCByZXR1cm4gdGhlIGFwcHJvcHJpYXRlIGluZGV4IHR5cGUuICAqLwogIHJldHVybiBidWlsZF9pbmRleF90eXBlIChpdHlwZSk7Cn0KCi8qIFJldHVybnMgdGhlIHNjb3BlIChpZiBhbnkpIGluIHdoaWNoIHRoZSBlbnRpdHkgZGVjbGFyZWQgYnkKICAgREVDTEFSQVRPUiB3aWxsIGJlIGxvY2F0ZWQuICBJZiB0aGUgZW50aXR5IHdhcyBkZWNsYXJlZCB3aXRoIGFuCiAgIHVucXVhbGlmaWVkIG5hbWUsIE5VTExfVFJFRSBpcyByZXR1cm5lZC4gICovCgp0cmVlCmdldF9zY29wZV9vZl9kZWNsYXJhdG9yIChjb25zdCBjcF9kZWNsYXJhdG9yICpkZWNsYXJhdG9yKQp7CiAgd2hpbGUgKGRlY2xhcmF0b3IgJiYgZGVjbGFyYXRvci0+a2luZCAhPSBjZGtfaWQpCiAgICBkZWNsYXJhdG9yID0gZGVjbGFyYXRvci0+ZGVjbGFyYXRvcjsKCiAgLyogSWYgdGhlIGRlY2xhcmF0b3ItaWQgaXMgYSBTQ09QRV9SRUYsIHRoZSBzY29wZSBpbiB3aGljaCB0aGUKICAgICBkZWNsYXJhdGlvbiBvY2N1cnMgaXMgdGhlIGZpcnN0IG9wZXJhbmQuICAqLwogIGlmIChkZWNsYXJhdG9yCiAgICAgICYmIGRlY2xhcmF0b3ItPnUuaWQucXVhbGlmeWluZ19zY29wZSkKICAgIHJldHVybiBkZWNsYXJhdG9yLT51LmlkLnF1YWxpZnlpbmdfc2NvcGU7CgogIC8qIE90aGVyd2lzZSwgdGhlIGRlY2xhcmF0b3IgaXMgbm90IGEgcXVhbGlmaWVkIG5hbWU7IHRoZSBlbnRpdHkgd2lsbAogICAgIGJlIGRlY2xhcmVkIGluIHRoZSBjdXJyZW50IHNjb3BlLiAgKi8KICByZXR1cm4gTlVMTF9UUkVFOwp9CgovKiBSZXR1cm5zIGFuIEFSUkFZX1RZUEUgZm9yIGFuIGFycmF5IHdpdGggU0laRSBlbGVtZW50cyBvZiB0aGUKICAgaW5kaWNhdGVkIFRZUEUuICBJZiBub24tTlVMTCwgTkFNRSBpcyB0aGUgTkFNRSBvZiB0aGUgZGVjbGFyYXRpb24KICAgd2l0aCB0aGlzIHR5cGUuICAqLwoKc3RhdGljIHRyZWUKY3JlYXRlX2FycmF5X3R5cGVfZm9yX2RlY2wgKHRyZWUgbmFtZSwgdHJlZSB0eXBlLCB0cmVlIHNpemUpCnsKICB0cmVlIGl0eXBlID0gTlVMTF9UUkVFOwogIGNvbnN0IGNoYXIqIGVycm9yX21zZzsKCiAgLyogSWYgdGhpbmdzIGhhdmUgYWxyZWFkeSBnb25lIGF3cnksIGJhaWwgbm93LiAgKi8KICBpZiAodHlwZSA9PSBlcnJvcl9tYXJrX25vZGUgfHwgc2l6ZSA9PSBlcnJvcl9tYXJrX25vZGUpCiAgICByZXR1cm4gZXJyb3JfbWFya19ub2RlOwoKICAvKiBBc3N1bWUgdGhhdCBldmVyeXRoaW5nIHdpbGwgZ28gT0suICAqLwogIGVycm9yX21zZyA9IE5VTEw7CgogIC8qIFRoZXJlIGFyZSBzb21lIHR5cGVzIHdoaWNoIGNhbm5vdCBiZSBhcnJheSBlbGVtZW50cy4gICovCiAgc3dpdGNoIChUUkVFX0NPREUgKHR5cGUpKQogICAgewogICAgY2FzZSBWT0lEX1RZUEU6CiAgICAgIGVycm9yX21zZyA9ICJhcnJheSBvZiB2b2lkIjsKICAgICAgYnJlYWs7CgogICAgY2FzZSBGVU5DVElPTl9UWVBFOgogICAgICBlcnJvcl9tc2cgPSAiYXJyYXkgb2YgZnVuY3Rpb25zIjsKICAgICAgYnJlYWs7CgogICAgY2FzZSBSRUZFUkVOQ0VfVFlQRToKICAgICAgZXJyb3JfbXNnID0gImFycmF5IG9mIHJlZmVyZW5jZXMiOwogICAgICBicmVhazsKCiAgICBjYXNlIE1FVEhPRF9UWVBFOgogICAgICBlcnJvcl9tc2cgPSAiYXJyYXkgb2YgZnVuY3Rpb24gbWVtYmVycyI7CiAgICAgIGJyZWFrOwoKICAgIGRlZmF1bHQ6CiAgICAgIGJyZWFrOwogICAgfQoKICAvKiBJZiBzb21ldGhpbmcgd2VudCB3cm9uZywgaXNzdWUgYW4gZXJyb3ItbWVzc2FnZSBhbmQgcmV0dXJuLiAgKi8KICBpZiAoZXJyb3JfbXNnKQogICAgewogICAgICBpZiAobmFtZSkKCWVycm9yICgiZGVjbGFyYXRpb24gb2YgJXFEIGFzICVzIiwgbmFtZSwgZXJyb3JfbXNnKTsKICAgICAgZWxzZQoJZXJyb3IgKCJjcmVhdGluZyAlcyIsIGVycm9yX21zZyk7CgogICAgICByZXR1cm4gZXJyb3JfbWFya19ub2RlOwogICAgfQoKICAvKiBbZGNsLmFycmF5XQoKICAgICBUaGUgY29uc3RhbnQgZXhwcmVzc2lvbnMgdGhhdCBzcGVjaWZ5IHRoZSBib3VuZHMgb2YgdGhlIGFycmF5cwogICAgIGNhbiBiZSBvbWl0dGVkIG9ubHkgZm9yIHRoZSBmaXJzdCBtZW1iZXIgb2YgdGhlIHNlcXVlbmNlLiAgKi8KICBpZiAoVFJFRV9DT0RFICh0eXBlKSA9PSBBUlJBWV9UWVBFICYmICFUWVBFX0RPTUFJTiAodHlwZSkpCiAgICB7CiAgICAgIGlmIChuYW1lKQoJZXJyb3IgKCJkZWNsYXJhdGlvbiBvZiAlcUQgYXMgbXVsdGlkaW1lbnNpb25hbCBhcnJheSBtdXN0ICIKICAgICAgICAgICAgICAgImhhdmUgYm91bmRzIGZvciBhbGwgZGltZW5zaW9ucyBleGNlcHQgdGhlIGZpcnN0IiwKICAgICAgICAgICAgICAgbmFtZSk7CiAgICAgIGVsc2UKCWVycm9yICgibXVsdGlkaW1lbnNpb25hbCBhcnJheSBtdXN0IGhhdmUgYm91bmRzIGZvciBhbGwgIgogICAgICAgICAgICAgICAiZGltZW5zaW9ucyBleGNlcHQgdGhlIGZpcnN0Iik7CgogICAgICByZXR1cm4gZXJyb3JfbWFya19ub2RlOwogICAgfQoKICAvKiBGaWd1cmUgb3V0IHRoZSBpbmRleCB0eXBlIGZvciB0aGUgYXJyYXkuICAqLwogIGlmIChzaXplKQogICAgaXR5cGUgPSBjb21wdXRlX2FycmF5X2luZGV4X3R5cGUgKG5hbWUsIHNpemUpOwoKICAvKiBbZGNsLmFycmF5XQogICAgIFQgaXMgY2FsbGVkIHRoZSBhcnJheSBlbGVtZW50IHR5cGU7IHRoaXMgdHlwZSBzaGFsbCBub3QgYmUgWy4uLl0gYW4KICAgICBhYnN0cmFjdCBjbGFzcyB0eXBlLiAgKi8KICBhYnN0cmFjdF92aXJ0dWFsc19lcnJvciAobmFtZSwgdHlwZSk7CgogIHJldHVybiBidWlsZF9jcGx1c19hcnJheV90eXBlICh0eXBlLCBpdHlwZSk7Cn0KCi8qIENoZWNrIHRoYXQgaXQncyBPSyB0byBkZWNsYXJlIGEgZnVuY3Rpb24gd2l0aCB0aGUgaW5kaWNhdGVkIFRZUEUuCiAgIFNGSyBpbmRpY2F0ZXMgdGhlIGtpbmQgb2Ygc3BlY2lhbCBmdW5jdGlvbiAoaWYgYW55KSB0aGF0IHRoaXMKICAgZnVuY3Rpb24gaXMuICBPUFRZUEUgaXMgdGhlIHR5cGUgZ2l2ZW4gaW4gYSBjb252ZXJzaW9uIG9wZXJhdG9yCiAgIGRlY2xhcmF0aW9uLCBvciB0aGUgY2xhc3MgdHlwZSBmb3IgYSBjb25zdHJ1Y3Rvci9kZXN0cnVjdG9yLgogICBSZXR1cm5zIHRoZSBhY3R1YWwgcmV0dXJuIHR5cGUgb2YgdGhlIGZ1bmN0aW9uOyB0aGF0CiAgIG1heSBiZSBkaWZmZXJlbnQgdGhhbiBUWVBFIGlmIGFuIGVycm9yIG9jY3Vycywgb3IgZm9yIGNlcnRhaW4KICAgc3BlY2lhbCBmdW5jdGlvbnMuICAqLwoKc3RhdGljIHRyZWUKY2hlY2tfc3BlY2lhbF9mdW5jdGlvbl9yZXR1cm5fdHlwZSAoc3BlY2lhbF9mdW5jdGlvbl9raW5kIHNmaywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJlZSB0eXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0cmVlIG9wdHlwZSkKewogIHN3aXRjaCAoc2ZrKQogICAgewogICAgY2FzZSBzZmtfY29uc3RydWN0b3I6CiAgICAgIGlmICh0eXBlKQoJZXJyb3IgKCJyZXR1cm4gdHlwZSBzcGVjaWZpY2F0aW9uIGZvciBjb25zdHJ1Y3RvciBpbnZhbGlkIik7CgogICAgICBpZiAodGFyZ2V0bS5jeHguY2R0b3JfcmV0dXJuc190aGlzICgpICYmICFUWVBFX0ZPUl9KQVZBIChvcHR5cGUpKQoJdHlwZSA9IGJ1aWxkX3BvaW50ZXJfdHlwZSAob3B0eXBlKTsKICAgICAgZWxzZQoJdHlwZSA9IHZvaWRfdHlwZV9ub2RlOwogICAgICBicmVhazsKCiAgICBjYXNlIHNma19kZXN0cnVjdG9yOgogICAgICBpZiAodHlwZSkKCWVycm9yICgicmV0dXJuIHR5cGUgc3BlY2lmaWNhdGlvbiBmb3IgZGVzdHJ1Y3RvciBpbnZhbGlkIik7CiAgICAgIC8qIFdlIGNhbid0IHVzZSB0aGUgcHJvcGVyIHJldHVybiB0eXBlIGhlcmUgYmVjYXVzZSB3ZSBydW4gaW50bwoJIHByb2JsZW1zIHdpdGggYW1iaWd1b3VzIGJhc2VzIGFuZCBjb3ZhcmlhbnQgcmV0dXJucy4KCSBKYXZhIGNsYXNzZXMgYXJlIGxlZnQgdW5jaGFuZ2VkIGJlY2F1c2UgKHZvaWQgKikgaXNuJ3QgYSB2YWxpZAoJIEphdmEgdHlwZSwgYW5kIHdlIGRvbid0IHdhbnQgdG8gY2hhbmdlIHRoZSBKYXZhIEFCSS4gICovCiAgICAgIGlmICh0YXJnZXRtLmN4eC5jZHRvcl9yZXR1cm5zX3RoaXMgKCkgJiYgIVRZUEVfRk9SX0pBVkEgKG9wdHlwZSkpCgl0eXBlID0gYnVpbGRfcG9pbnRlcl90eXBlICh2b2lkX3R5cGVfbm9kZSk7CiAgICAgIGVsc2UKCXR5cGUgPSB2b2lkX3R5cGVfbm9kZTsKICAgICAgYnJlYWs7CgogICAgY2FzZSBzZmtfY29udmVyc2lvbjoKICAgICAgaWYgKHR5cGUgJiYgIXNhbWVfdHlwZV9wICh0eXBlLCBvcHR5cGUpKQoJZXJyb3IgKCJvcGVyYXRvciAlcVQgZGVjbGFyZWQgdG8gcmV0dXJuICVxVCIsIG9wdHlwZSwgdHlwZSk7CiAgICAgIGVsc2UgaWYgKHR5cGUpCglwZWR3YXJuICgicmV0dXJuIHR5cGUgc3BlY2lmaWVkIGZvciAlPG9wZXJhdG9yICVUJT4iLCAgb3B0eXBlKTsKICAgICAgdHlwZSA9IG9wdHlwZTsKICAgICAgYnJlYWs7CgogICAgZGVmYXVsdDoKICAgICAgZ2NjX3VucmVhY2hhYmxlICgpOwogICAgfQoKICByZXR1cm4gdHlwZTsKfQoKLyogQSB2YXJpYWJsZSBvciBkYXRhIG1lbWJlciAod2hvc2UgdW5xdWFsaWZpZWQgbmFtZSBpcyBJREVOVElGSUVSKQogICBoYXMgYmVlbiBkZWNsYXJlZCB3aXRoIHRoZSBpbmRpY2F0ZWQgVFlQRS4gIElmIHRoZSBUWVBFIGlzIG5vdAogICBhY2NlcHRhYmxlLCBpc3N1ZSBhbiBlcnJvciBtZXNzYWdlIGFuZCByZXR1cm4gYSB0eXBlIHRvIHVzZSBmb3IKICAgZXJyb3ItcmVjb3ZlcnkgcHVycG9zZXMuICAqLwoKdHJlZQpjaGVja192YXJfdHlwZSAodHJlZSBpZGVudGlmaWVyLCB0cmVlIHR5cGUpCnsKICBpZiAoVk9JRF9UWVBFX1AgKHR5cGUpKQogICAgewogICAgICBpZiAoIWlkZW50aWZpZXIpCgllcnJvciAoInVubmFtZWQgdmFyaWFibGUgb3IgZmllbGQgZGVjbGFyZWQgdm9pZCIpOwogICAgICBlbHNlIGlmIChUUkVFX0NPREUgKGlkZW50aWZpZXIpID09IElERU5USUZJRVJfTk9ERSkKCXsKCSAgZ2NjX2Fzc2VydCAoIUlERU5USUZJRVJfT1BOQU1FX1AgKGlkZW50aWZpZXIpKTsKCSAgZXJyb3IgKCJ2YXJpYWJsZSBvciBmaWVsZCAlcUUgZGVjbGFyZWQgdm9pZCIsIGlkZW50aWZpZXIpOwoJfQogICAgICBlbHNlCgllcnJvciAoInZhcmlhYmxlIG9yIGZpZWxkIGRlY2xhcmVkIHZvaWQiKTsKICAgICAgdHlwZSA9IGludGVnZXJfdHlwZV9ub2RlOwogICAgfQogIAogIHJldHVybiB0eXBlOwp9CgovKiBHaXZlbiBkZWNsc3BlY3MgYW5kIGEgZGVjbGFyYXRvciAoYWJzdHJhY3Qgb3Igb3RoZXJ3aXNlKSwgZGV0ZXJtaW5lCiAgIHRoZSBuYW1lIGFuZCB0eXBlIG9mIHRoZSBvYmplY3QgZGVjbGFyZWQgYW5kIGNvbnN0cnVjdCBhIERFQ0wgbm9kZQogICBmb3IgaXQuCgogICBERUNMU1BFQ1MgaXMgYSBjaGFpbiBvZiB0cmVlX2xpc3Qgbm9kZXMgd2hvc2UgdmFsdWUgZmllbGRzCiAgICBhcmUgdGhlIHN0b3JhZ2UgY2xhc3NlcyBhbmQgdHlwZSBzcGVjaWZpZXJzLgoKICAgREVDTF9DT05URVhUIHNheXMgd2hpY2ggc3ludGFjdGljIGNvbnRleHQgdGhpcyBkZWNsYXJhdGlvbiBpcyBpbjoKICAgICBOT1JNQUwgZm9yIG1vc3QgY29udGV4dHMuICBNYWtlIGEgVkFSX0RFQ0wgb3IgRlVOQ1RJT05fREVDTCBvciBUWVBFX0RFQ0wuCiAgICAgRlVOQ0RFRiBmb3IgYSBmdW5jdGlvbiBkZWZpbml0aW9uLiAgTGlrZSBOT1JNQUwgYnV0IGEgZmV3IGRpZmZlcmVudAogICAgICBlcnJvciBtZXNzYWdlcyBpbiBlYWNoIGNhc2UuICBSZXR1cm4gdmFsdWUgbWF5IGJlIHplcm8gbWVhbmluZwogICAgICB0aGlzIGRlZmluaXRpb24gaXMgdG9vIHNjcmV3eSB0byB0cnkgdG8gcGFyc2UuCiAgICAgTUVNRlVOQ0RFRiBmb3IgYSBmdW5jdGlvbiBkZWZpbml0aW9uLiAgTGlrZSBGVU5DREVGIGJ1dCBwcmVwYXJlcyB0bwogICAgICBoYW5kbGUgbWVtYmVyIGZ1bmN0aW9ucyAod2hpY2ggaGF2ZSBGSUVMRCBjb250ZXh0KS4KICAgICAgUmV0dXJuIHZhbHVlIG1heSBiZSB6ZXJvIG1lYW5pbmcgdGhpcyBkZWZpbml0aW9uIGlzIHRvbyBzY3Jld3kgdG8KICAgICAgdHJ5IHRvIHBhcnNlLgogICAgIFBBUk0gZm9yIGEgcGFyYW1ldGVyIGRlY2xhcmF0aW9uIChlaXRoZXIgd2l0aGluIGEgZnVuY3Rpb24gcHJvdG90eXBlCiAgICAgIG9yIGJlZm9yZSBhIGZ1bmN0aW9uIGJvZHkpLiAgTWFrZSBhIFBBUk1fREVDTCwgb3IgcmV0dXJuIHZvaWRfdHlwZV9ub2RlLgogICAgIENBVENIUEFSTSBmb3IgYSBwYXJhbWV0ZXIgZGVjbGFyYXRpb24gYmVmb3JlIGEgY2F0Y2ggY2xhdXNlLgogICAgIFRZUEVOQU1FIGlmIGZvciBhIHR5cGVuYW1lIChpbiBhIGNhc3Qgb3Igc2l6ZW9mKS4KICAgICAgRG9uJ3QgbWFrZSBhIERFQ0wgbm9kZTsganVzdCByZXR1cm4gdGhlIC4uLl9UWVBFIG5vZGUuCiAgICAgRklFTEQgZm9yIGEgc3RydWN0IG9yIHVuaW9uIGZpZWxkOyBtYWtlIGEgRklFTERfREVDTC4KICAgICBCSVRGSUVMRCBmb3IgYSBmaWVsZCB3aXRoIHNwZWNpZmllZCB3aWR0aC4KICAgSU5JVElBTElaRUQgaXMgMSBpZiB0aGUgZGVjbCBoYXMgYW4gaW5pdGlhbGl6ZXIuCgogICBBVFRSTElTVCBpcyBhIHBvaW50ZXIgdG8gdGhlIGxpc3Qgb2YgYXR0cmlidXRlcywgd2hpY2ggbWF5IGJlIE5VTEwKICAgaWYgdGhlcmUgYXJlIG5vbmU7ICpBVFRSTElTVCBtYXkgYmUgbW9kaWZpZWQgaWYgYXR0cmlidXRlcyBmcm9tIGluc2lkZQogICB0aGUgZGVjbGFyYXRvciBzaG91bGQgYmUgYXBwbGllZCB0byB0aGUgZGVjbGFyYXRpb24uCgogICBXaGVuIHRoaXMgZnVuY3Rpb24gaXMgY2FsbGVkLCBzY29waW5nIHZhcmlhYmxlcyAoc3VjaCBhcwogICBDVVJSRU5UX0NMQVNTX1RZUEUpIHNob3VsZCByZWZsZWN0IHRoZSBzY29wZSBpbiB3aGljaCB0aGUKICAgZGVjbGFyYXRpb24gb2NjdXJzLCBub3QgdGhlIHNjb3BlIGluIHdoaWNoIHRoZSBuZXcgZGVjbGFyYXRpb24gd2lsbAogICBiZSBwbGFjZWQuICBGb3IgZXhhbXBsZSwgb246CgogICAgIHZvaWQgUzo6ZigpIHsgLi4uIH0KCiAgIHdoZW4gZ3Jva2RlY2xhcmF0b3IgaXMgY2FsbGVkIGZvciBgUzo6ZicsIHRoZSBDVVJSRU5UX0NMQVNTX1RZUEUKICAgc2hvdWxkIG5vdCBiZSBgUycuICAqLwoKdHJlZQpncm9rZGVjbGFyYXRvciAoY29uc3QgY3BfZGVjbGFyYXRvciAqZGVjbGFyYXRvciwKCQljb25zdCBjcF9kZWNsX3NwZWNpZmllcl9zZXEgKmRlY2xzcGVjcywKICAgICAgICAgICAgICAgIGVudW0gZGVjbF9jb250ZXh0IGRlY2xfY29udGV4dCwKICAgICAgICAgICAgICAgIGludCBpbml0aWFsaXplZCwKICAgICAgICAgICAgICAgIHRyZWUqIGF0dHJsaXN0KQp7CiAgdHJlZSB0eXBlID0gTlVMTF9UUkVFOwogIGludCBsb25nbG9uZyA9IDA7CiAgaW50IHR5cGVfcXVhbHM7CiAgaW50IHZpcnR1YWxwLCBleHBsaWNpdHAsIGZyaWVuZHAsIGlubGluZXAsIHN0YXRpY3A7CiAgaW50IGV4cGxpY2l0X2ludCA9IDA7CiAgaW50IGV4cGxpY2l0X2NoYXIgPSAwOwogIGludCBkZWZhdWx0ZWRfaW50ID0gMDsKICB0cmVlIGRlcGVuZGFudF9uYW1lID0gTlVMTF9UUkVFOwoKICB0cmVlIHR5cGVkZWZfZGVjbCA9IE5VTExfVFJFRTsKICBjb25zdCBjaGFyICpuYW1lID0gTlVMTDsKICB0cmVlIHR5cGVkZWZfdHlwZSA9IE5VTExfVFJFRTsKICBpbnQgZnVuY2RlZl9mbGFnID0gMDsKICBjcF9kZWNsYXJhdG9yX2tpbmQgaW5uZXJtb3N0X2NvZGUgPSBjZGtfZXJyb3I7CiAgaW50IGJpdGZpZWxkID0gMDsKI2lmIDAKICAvKiBTZWUgdGhlIGNvZGUgYmVsb3cgdGhhdCB1c2VkIHRoaXMuICAqLwogIHRyZWUgZGVjbF9hdHRyID0gTlVMTF9UUkVFOwojZW5kaWYKCiAgLyogS2VlcCB0cmFjayBvZiB3aGF0IHNvcnQgb2YgZnVuY3Rpb24gaXMgYmVpbmcgcHJvY2Vzc2VkCiAgICAgc28gdGhhdCB3ZSBjYW4gd2FybiBhYm91dCBkZWZhdWx0IHJldHVybiB2YWx1ZXMsIG9yIGV4cGxpY2l0CiAgICAgcmV0dXJuIHZhbHVlcyB3aGljaCBkbyBub3QgbWF0Y2ggcHJlc2NyaWJlZCBkZWZhdWx0cy4gICovCiAgc3BlY2lhbF9mdW5jdGlvbl9raW5kIHNmayA9IHNma19ub25lOwoKICB0cmVlIGRuYW1lID0gTlVMTF9UUkVFOwogIHRyZWUgY3Rvcl9yZXR1cm5fdHlwZSA9IE5VTExfVFJFRTsKICBlbnVtIG92ZXJsb2FkX2ZsYWdzIGZsYWdzID0gTk9fU1BFQ0lBTDsKICBjcF9jdl9xdWFscyBxdWFscyA9IFRZUEVfVU5RVUFMSUZJRUQ7CiAgdHJlZSByYWlzZXMgPSBOVUxMX1RSRUU7CiAgaW50IHRlbXBsYXRlX2NvdW50ID0gMDsKICB0cmVlIHJldHVybmVkX2F0dHJzID0gTlVMTF9UUkVFOwogIHRyZWUgcGFybXMgPSBOVUxMX1RSRUU7CiAgY29uc3QgY3BfZGVjbGFyYXRvciAqaWRfZGVjbGFyYXRvcjsKICAvKiBUaGUgdW5xdWFsaWZpZWQgbmFtZSBvZiB0aGUgZGVjbGFyYXRvcjsgZWl0aGVyIGFuCiAgICAgSURFTlRJRklFUl9OT0RFLCBCSVRfTk9UX0VYUFIsIG9yIFRFTVBMQVRFX0lEX0VYUFIuICAqLwogIHRyZWUgdW5xdWFsaWZpZWRfaWQ7CiAgLyogVGhlIGNsYXNzIHR5cGUsIGlmIGFueSwgaW4gd2hpY2ggdGhpcyBlbnRpdHkgaXMgbG9jYXRlZCwKICAgICBvciBOVUxMX1RSRUUgaWYgbm9uZS4gIE5vdGUgdGhhdCB0aGlzIHZhbHVlIG1heSBiZSBkaWZmZXJlbnQgZnJvbQogICAgIHRoZSBjdXJyZW50IGNsYXNzIHR5cGU7IGZvciBleGFtcGxlIGlmIGFuIGF0dGVtcHQgaXMgbWFkZSB0byBkZWNsYXJlCiAgICAgIkE6OmYiIGluc2lkZSAiQiIsIHRoaXMgdmFsdWUgd2lsbCBiZSAiQSIuICAqLwogIHRyZWUgY3R5cGUgPSBjdXJyZW50X2NsYXNzX3R5cGU7CiAgLyogVGhlIE5BTUVTUEFDRV9ERUNMIGZvciB0aGUgbmFtZXNwYWNlIGluIHdoaWNoIHRoaXMgZW50aXR5IGlzCiAgICAgbG9jYXRlZC4gIElmIGFuIHVucXVhbGlmaWVkIG5hbWUgaXMgdXNlZCB0byBkZWNsYXJlIHRoZSBlbnRpdHksCiAgICAgdGhpcyB2YWx1ZSB3aWxsIGJlIE5VTExfVFJFRSwgZXZlbiBpZiB0aGUgZW50aXR5IGlzIGxvY2F0ZWQgYXQKICAgICBuYW1lc3BhY2Ugc2NvcGUuICAqLwogIHRyZWUgaW5fbmFtZXNwYWNlID0gTlVMTF9UUkVFOwogIGNwX2RlY2xfc3BlYyBkczsKICBjcF9zdG9yYWdlX2NsYXNzIHN0b3JhZ2VfY2xhc3M7CiAgYm9vbCB1bnNpZ25lZF9wLCBzaWduZWRfcCwgc2hvcnRfcCwgbG9uZ19wLCB0aHJlYWRfcDsKICAvKiBBUFBMRSBMT0NBTCBDVyBhc20gYmxvY2tzICovCiAgYm9vbCBpYXNtX3A7CiAgYm9vbCB0eXBlX3dhc19lcnJvcl9tYXJrX25vZGUgPSBmYWxzZTsKCiAgc2lnbmVkX3AgPSBkZWNsc3BlY3MtPnNwZWNzWyhpbnQpZHNfc2lnbmVkXTsKICB1bnNpZ25lZF9wID0gZGVjbHNwZWNzLT5zcGVjc1soaW50KWRzX3Vuc2lnbmVkXTsKICBzaG9ydF9wID0gZGVjbHNwZWNzLT5zcGVjc1soaW50KWRzX3Nob3J0XTsKICBsb25nX3AgPSBkZWNsc3BlY3MtPnNwZWNzWyhpbnQpZHNfbG9uZ107CiAgdGhyZWFkX3AgPSBkZWNsc3BlY3MtPnNwZWNzWyhpbnQpZHNfdGhyZWFkXTsKICAvKiBBUFBMRSBMT0NBTCBDVyBhc20gYmxvY2tzICovCiAgaWFzbV9wID0gZGVjbHNwZWNzLT5zcGVjc1soaW50KWRzX2lhc21fYXNtXTsKCiAgaWYgKGRlY2xfY29udGV4dCA9PSBGVU5DREVGKQogICAgZnVuY2RlZl9mbGFnID0gMSwgZGVjbF9jb250ZXh0ID0gTk9STUFMOwogIGVsc2UgaWYgKGRlY2xfY29udGV4dCA9PSBNRU1GVU5DREVGKQogICAgZnVuY2RlZl9mbGFnID0gLTEsIGRlY2xfY29udGV4dCA9IEZJRUxEOwogIGVsc2UgaWYgKGRlY2xfY29udGV4dCA9PSBCSVRGSUVMRCkKICAgIGJpdGZpZWxkID0gMSwgZGVjbF9jb250ZXh0ID0gRklFTEQ7CgogIC8qIExvb2sgaW5zaWRlIGEgZGVjbGFyYXRvciBmb3IgdGhlIG5hbWUgYmVpbmcgZGVjbGFyZWQKICAgICBhbmQgZ2V0IGl0IGFzIGEgc3RyaW5nLCBmb3IgYW4gZXJyb3IgbWVzc2FnZS4gICovCiAgZm9yIChpZF9kZWNsYXJhdG9yID0gZGVjbGFyYXRvcjsKICAgICAgIGlkX2RlY2xhcmF0b3I7CiAgICAgICBpZF9kZWNsYXJhdG9yID0gaWRfZGVjbGFyYXRvci0+ZGVjbGFyYXRvcikKICAgIHsKICAgICAgaWYgKGlkX2RlY2xhcmF0b3ItPmtpbmQgIT0gY2RrX2lkKQoJaW5uZXJtb3N0X2NvZGUgPSBpZF9kZWNsYXJhdG9yLT5raW5kOwoKICAgICAgc3dpdGNoIChpZF9kZWNsYXJhdG9yLT5raW5kKQoJewoJY2FzZSBjZGtfZnVuY3Rpb246CgkgIGlmIChpZF9kZWNsYXJhdG9yLT5kZWNsYXJhdG9yCgkgICAgICAmJiBpZF9kZWNsYXJhdG9yLT5kZWNsYXJhdG9yLT5raW5kID09IGNka19pZCkKCSAgICB7CgkgICAgICBzZmsgPSBpZF9kZWNsYXJhdG9yLT5kZWNsYXJhdG9yLT51LmlkLnNmazsKCSAgICAgIGlmIChzZmsgPT0gc2ZrX2Rlc3RydWN0b3IpCgkJZmxhZ3MgPSBEVE9SX0ZMQUc7CgkgICAgfQoJICBicmVhazsKCgljYXNlIGNka19pZDoKCSAgewoJICAgIHRyZWUgcXVhbGlmeWluZ19zY29wZSA9IGlkX2RlY2xhcmF0b3ItPnUuaWQucXVhbGlmeWluZ19zY29wZTsKCSAgICB0cmVlIGRlY2wgPSBpZF9kZWNsYXJhdG9yLT51LmlkLnVucXVhbGlmaWVkX25hbWU7CgkgICAgaWYgKCFkZWNsKQoJICAgICAgYnJlYWs7CgkgICAgaWYgKHF1YWxpZnlpbmdfc2NvcGUpCgkgICAgICB7CgkJaWYgKFRZUEVfUCAocXVhbGlmeWluZ19zY29wZSkpCgkJICB7CgkJICAgIGN0eXBlID0gcXVhbGlmeWluZ19zY29wZTsKCQkgICAgaWYgKGlubmVybW9zdF9jb2RlICE9IGNka19mdW5jdGlvbgoJCQkmJiBjdXJyZW50X2NsYXNzX3R5cGUKCQkJJiYgIVVOSVFVRUxZX0RFUklWRURfRlJPTV9QIChjdHlwZSwKCQkJCQkJICAgICBjdXJyZW50X2NsYXNzX3R5cGUpKQoJCSAgICAgIHsKCQkJZXJyb3IgKCJ0eXBlICVxVCBpcyBub3QgZGVyaXZlZCBmcm9tIHR5cGUgJXFUIiwKCQkJICAgICAgIGN0eXBlLCBjdXJyZW50X2NsYXNzX3R5cGUpOwoJCQlyZXR1cm4gZXJyb3JfbWFya19ub2RlOwoJCSAgICAgIH0KCQkgIH0KCQllbHNlIGlmIChUUkVFX0NPREUgKHF1YWxpZnlpbmdfc2NvcGUpID09IE5BTUVTUEFDRV9ERUNMKQoJCSAgaW5fbmFtZXNwYWNlID0gcXVhbGlmeWluZ19zY29wZTsKCSAgICAgIH0KCSAgICAvKiBBUFBMRSBMT0NBTCBiZWdpbiBtYWlubGluZSAyMDA1LTEyLTI3IDQ0MzEwOTEgKi8KCSAgICBzd2l0Y2ggKFRSRUVfQ09ERSAoZGVjbCkpCgkgICAgICB7CgkgICAgICBjYXNlIEJJVF9OT1RfRVhQUjoKCQl7CgkJICB0cmVlIHR5cGU7CgoJCSAgaWYgKGlubmVybW9zdF9jb2RlICE9IGNka19mdW5jdGlvbikKCQkgICAgewoJCSAgICAgIGVycm9yICgiZGVjbGFyYXRpb24gb2YgJXFEIGFzIG5vbi1mdW5jdGlvbiIsIGRlY2wpOwoJCSAgICAgIHJldHVybiBlcnJvcl9tYXJrX25vZGU7CgkJICAgIH0KCQkgIGVsc2UgaWYgKCFxdWFsaWZ5aW5nX3Njb3BlIAoJCQkgICAmJiAhKGN1cnJlbnRfY2xhc3NfdHlwZSAmJiBhdF9jbGFzc19zY29wZV9wICgpKSkKCQkgICAgewoJCSAgICAgIGVycm9yICgiZGVjbGFyYXRpb24gb2YgJXFEIGFzIG5vbi1tZW1iZXIiLCBkZWNsKTsKCQkgICAgICByZXR1cm4gZXJyb3JfbWFya19ub2RlOwoJCSAgICB9CgkJICAKCQkgIHR5cGUgPSBUUkVFX09QRVJBTkQgKGRlY2wsIDApOwoJCSAgbmFtZSA9IElERU5USUZJRVJfUE9JTlRFUiAoY29uc3RydWN0b3JfbmFtZSAodHlwZSkpOwoJCX0KCQlicmVhazsKCgkgICAgICBjYXNlIFRFTVBMQVRFX0lEX0VYUFI6CgkJewoJCSAgdHJlZSBmbnMgPSBUUkVFX09QRVJBTkQgKGRlY2wsIDApOwoKCQkgIGRuYW1lID0gZm5zOwoJCSAgaWYgKFRSRUVfQ09ERSAoZG5hbWUpID09IENPTVBPTkVOVF9SRUYpCgkJICAgIGRuYW1lID0gVFJFRV9PUEVSQU5EIChkbmFtZSwgMSk7CgkJICBpZiAoVFJFRV9DT0RFIChkbmFtZSkgIT0gSURFTlRJRklFUl9OT0RFKQoJCSAgICB7CgkJICAgICAgZ2NjX2Fzc2VydCAoaXNfb3ZlcmxvYWRlZF9mbiAoZG5hbWUpKTsKCQkgICAgICBkbmFtZSA9IERFQ0xfTkFNRSAoZ2V0X2ZpcnN0X2ZuIChkbmFtZSkpOwoJCSAgICB9CgkJfQoJCS8qIEZhbGwgdGhyb3VnaC4gICovCgoJICAgICAgY2FzZSBJREVOVElGSUVSX05PREU6CgkJaWYgKFRSRUVfQ09ERSAoZGVjbCkgPT0gSURFTlRJRklFUl9OT0RFKQoJCSAgZG5hbWUgPSBkZWNsOwoKCQlpZiAoQ19JU19SRVNFUlZFRF9XT1JEIChkbmFtZSkpCgkJICB7CgkJICAgIGVycm9yICgiZGVjbGFyYXRvci1pZCBtaXNzaW5nOyB1c2luZyByZXNlcnZlZCB3b3JkICVxRCIsCgkJCSAgIGRuYW1lKTsKCQkgICAgbmFtZSA9IElERU5USUZJRVJfUE9JTlRFUiAoZG5hbWUpOwoJCSAgfQoJCWVsc2UgaWYgKCFJREVOVElGSUVSX1RZUEVOQU1FX1AgKGRuYW1lKSkKCQkgIG5hbWUgPSBJREVOVElGSUVSX1BPSU5URVIgKGRuYW1lKTsKCQllbHNlCgkJICB7CgkJICAgIGdjY19hc3NlcnQgKGZsYWdzID09IE5PX1NQRUNJQUwpOwoJCSAgICBmbGFncyA9IFRZUEVOQU1FX0ZMQUc7CgkJICAgIGN0b3JfcmV0dXJuX3R5cGUgPSBUUkVFX1RZUEUgKGRuYW1lKTsKCQkgICAgc2ZrID0gc2ZrX2NvbnZlcnNpb247CgkJICAgIGlmIChpc190eXBlbmFtZV9hdF9nbG9iYWxfc2NvcGUgKGRuYW1lKSkKCQkgICAgICBuYW1lID0gSURFTlRJRklFUl9QT0lOVEVSIChkbmFtZSk7CgkJICAgIGVsc2UKCQkgICAgICBuYW1lID0gIjxpbnZhbGlkIG9wZXJhdG9yPiI7CgkJICB9CgkJYnJlYWs7CgogICAgICAgICAgICAgIC8qIEFQUExFIExPQ0FMIGVuZCBtYWlubGluZSAyMDA1LTEyLTI3IDQ0MzEwOTEgKi8KCSAgICAgIGRlZmF1bHQ6CgkJZ2NjX3VucmVhY2hhYmxlICgpOwoJICAgICAgfQoJICAgIGJyZWFrOwoKCSAgY2FzZSBjZGtfYXJyYXk6CgkgIGNhc2UgY2RrX3BvaW50ZXI6CgkgIGNhc2UgY2RrX3JlZmVyZW5jZToKCSAgY2FzZSBjZGtfcHRybWVtOgoJICAgIGJyZWFrOwoKCSAgY2FzZSBjZGtfZXJyb3I6CgkgICAgYnJlYWs7CgoJICBkZWZhdWx0OgoJICAgIGdjY191bnJlYWNoYWJsZSAoKTsKCSAgfQoJfQogICAgICBpZiAoaWRfZGVjbGFyYXRvci0+a2luZCA9PSBjZGtfaWQpCglicmVhazsKICAgIH0KCiAgLyogQSBmdW5jdGlvbiBkZWZpbml0aW9uJ3MgZGVjbGFyYXRvciBtdXN0IGhhdmUgdGhlIGZvcm0gb2YKICAgICBhIGZ1bmN0aW9uIGRlY2xhcmF0b3IuICAqLwoKICBpZiAoZnVuY2RlZl9mbGFnICYmIGlubmVybW9zdF9jb2RlICE9IGNka19mdW5jdGlvbikKICAgIHJldHVybiAwOwoKICBpZiAoKChkbmFtZSAmJiBJREVOVElGSUVSX09QTkFNRV9QIChkbmFtZSkpIHx8IGZsYWdzID09IFRZUEVOQU1FX0ZMQUcpCiAgICAgICYmIGlubmVybW9zdF9jb2RlICE9IGNka19mdW5jdGlvbgogICAgICAmJiAhIChjdHlwZSAmJiAhZGVjbHNwZWNzLT5hbnlfc3BlY2lmaWVyc19wKSkKICAgIHsKICAgICAgZXJyb3IgKCJkZWNsYXJhdGlvbiBvZiAlcUQgYXMgbm9uLWZ1bmN0aW9uIiwgZG5hbWUpOwogICAgICByZXR1cm4gZXJyb3JfbWFya19ub2RlOwogICAgfQoKICAvKiBBbnl0aGluZyBkZWNsYXJlZCBvbmUgbGV2ZWwgZG93biBmcm9tIHRoZSB0b3AgbGV2ZWwKICAgICBtdXN0IGJlIG9uZSBvZiB0aGUgcGFyYW1ldGVycyBvZiBhIGZ1bmN0aW9uCiAgICAgKGJlY2F1c2UgdGhlIGJvZHkgaXMgYXQgbGVhc3QgdHdvIGxldmVscyBkb3duKS4gICovCgogIC8qIFRoaXMgaGV1cmlzdGljIGNhbm5vdCBiZSBhcHBsaWVkIHRvIEMrKyBub2RlcyEgRml4ZWQsIGhvd2V2ZXIsCiAgICAgYnkgbm90IGFsbG93aW5nIEMrKyBjbGFzcyBkZWZpbml0aW9ucyB0byBzcGVjaWZ5IHRoZWlyIHBhcmFtZXRlcnMKICAgICB3aXRoIHhkZWNscyAobXVzdCBiZSBzcGVjLmQgaW4gdGhlIHBhcm1saXN0KS4KCiAgICAgU2luY2Ugd2Ugbm93IHdhaXQgdG8gcHVzaCBhIGNsYXNzIHNjb3BlIHVudGlsIHdlIGFyZSBzdXJlIHRoYXQKICAgICB3ZSBhcmUgaW4gYSBsZWdpdGltYXRlIG1ldGhvZCBjb250ZXh0LCB3ZSBtdXN0IHNldCBvbGRjbmFtZQogICAgIGV4cGxpY2l0bHkgKHNpbmNlIGN1cnJlbnRfY2xhc3NfbmFtZSBpcyBub3QgeWV0IGFsaXZlKS4KCiAgICAgV2UgYWxzbyB3YW50IHRvIGF2b2lkIGNhbGxpbmcgdGhpcyBhIFBBUk0gaWYgaXQgaXMgaW4gYSBuYW1lc3BhY2UuICAqLwoKICBpZiAoZGVjbF9jb250ZXh0ID09IE5PUk1BTCAmJiAhdG9wbGV2ZWxfYmluZGluZ3NfcCAoKSkKICAgIHsKICAgICAgc3RydWN0IGNwX2JpbmRpbmdfbGV2ZWwgKmIgPSBjdXJyZW50X2JpbmRpbmdfbGV2ZWw7CiAgICAgIGN1cnJlbnRfYmluZGluZ19sZXZlbCA9IGItPmxldmVsX2NoYWluOwogICAgICBpZiAoY3VycmVudF9iaW5kaW5nX2xldmVsICE9IDAgJiYgdG9wbGV2ZWxfYmluZGluZ3NfcCAoKSkKCWRlY2xfY29udGV4dCA9IFBBUk07CiAgICAgIGN1cnJlbnRfYmluZGluZ19sZXZlbCA9IGI7CiAgICB9CgogIGlmIChuYW1lID09IE5VTEwpCiAgICBuYW1lID0gZGVjbF9jb250ZXh0ID09IFBBUk0gPyAicGFyYW1ldGVyIiA6ICJ0eXBlIG5hbWUiOwoKICAvKiBJZiB0aGVyZSB3ZXJlIG11bHRpcGxlIHR5cGVzIHNwZWNpZmllZCBpbiB0aGUgZGVjbC1zcGVjaWZpZXItc2VxLAogICAgIGlzc3VlIGFuIGVycm9yIG1lc3NhZ2UuICAqLwogIGlmIChkZWNsc3BlY3MtPm11bHRpcGxlX3R5cGVzX3ApCiAgICBlcnJvciAoInR3byBvciBtb3JlIGRhdGEgdHlwZXMgaW4gZGVjbGFyYXRpb24gb2YgJXFzIiwgbmFtZSk7CiAgLyogRXh0cmFjdCB0aGUgYmFzaWMgdHlwZSBmcm9tIHRoZSBkZWNsLXNwZWNpZmllci1zZXEuICAqLwogIHR5cGUgPSBkZWNsc3BlY3MtPnR5cGU7CiAgaWYgKHR5cGUgPT0gZXJyb3JfbWFya19ub2RlKQogICAgewogICAgICB0eXBlID0gTlVMTF9UUkVFOwogICAgICB0eXBlX3dhc19lcnJvcl9tYXJrX25vZGUgPSB0cnVlOwogICAgfQoKICAvKiBBUFBMRSBMT0NBTCBiZWdpbiB1bmF2YWlsYWJsZSBhdHRyaWJ1dGUgKHJhZGFyIDI4MDk2OTcpIC0tYm93ZGlkZ2UgKi8KICAvKiBJZiB0aGUgZW50aXJlIGRlY2xhcmF0aW9uIGlzIGl0c2VsZiB0YWdnZWQgYXMgdW5hdmFpbGFibGUgdGhlbgogICAgIHN1cHByZXNzIHJlcG9ydHMgb2YgdW5hdmFpbGFibGUvZGVwcmVjYXRlZCBpdGVtcy4gIElmIHRoZQogICAgIGVudGlyZSBkZWNsYXJhdGlvbiBpcyB0YWdnZWQgYXMgb25seSBkZXByZWNhdGVkIHdlIHN0aWxsCiAgICAgcmVwb3J0IHVuYXZhaWxhYmxlIHVzZXMuICAqLwogIGlmICh0eXBlICYmIFRSRUVfREVQUkVDQVRFRCAodHlwZSkgJiYgVFJFRV9VTkFWQUlMQUJMRSAodHlwZSkpIAogICAgewogICAgICBpZiAoZGVwcmVjYXRlZF9zdGF0ZSAhPSBERVBSRUNBVEVEX1VOQVZBSUxBQkxFX1NVUFBSRVNTKSAKCXdhcm5fZGVwcmVjYXRlZF91c2UgKHR5cGUpOwogICAgfQogIGVsc2UKICAvKiBBUFBMRSBMT0NBTCBlbmQgdW5hdmFpbGFibGUgYXR0cmlidXRlIChyYWRhciAyODA5Njk3KSAtLWJvd2RpZGdlICovCiAgLyogSWYgdGhlIGVudGlyZSBkZWNsYXJhdGlvbiBpcyBpdHNlbGYgdGFnZ2VkIGFzIGRlcHJlY2F0ZWQgdGhlbgogICAgIHN1cHByZXNzIHJlcG9ydHMgb2YgZGVwcmVjYXRlZCBpdGVtcy4gICovCiAgaWYgKHR5cGUgJiYgVFJFRV9ERVBSRUNBVEVEICh0eXBlKQogICAgICAmJiBkZXByZWNhdGVkX3N0YXRlICE9IERFUFJFQ0FURURfU1VQUFJFU1MpCiAgICB3YXJuX2RlcHJlY2F0ZWRfdXNlICh0eXBlKTsKICBpZiAodHlwZSAmJiBUUkVFX0NPREUgKHR5cGUpID09IFRZUEVfREVDTCkKICAgIHsKICAgICAgdHlwZWRlZl9kZWNsID0gdHlwZTsKICAgICAgdHlwZSA9IFRSRUVfVFlQRSAodHlwZWRlZl9kZWNsKTsKICAgIH0KICAvKiBObyB0eXBlIGF0IGFsbDogZGVmYXVsdCB0byBgaW50JywgYW5kIHNldCBERUZBVUxURURfSU5UCiAgICAgYmVjYXVzZSBpdCB3YXMgbm90IGEgdXNlci1kZWZpbmVkIHR5cGVkZWYuICAqLwogIGlmICh0eXBlID09IE5VTExfVFJFRSAmJiAoc2lnbmVkX3AgfHwgdW5zaWduZWRfcCB8fCBsb25nX3AgfHwgc2hvcnRfcCkpCiAgICB7CiAgICAgIC8qIFRoZXNlIGltcGx5ICdpbnQnLiAgKi8KICAgICAgdHlwZSA9IGludGVnZXJfdHlwZV9ub2RlOwogICAgICBkZWZhdWx0ZWRfaW50ID0gMTsKICAgIH0KICAvKiBHYXRoZXIgZmxhZ3MuICAqLwogIGV4cGxpY2l0X2ludCA9IGRlY2xzcGVjcy0+ZXhwbGljaXRfaW50X3A7CiAgZXhwbGljaXRfY2hhciA9IGRlY2xzcGVjcy0+ZXhwbGljaXRfY2hhcl9wOwoKICAvKiBDaGVjayBmb3IgcmVwZWF0ZWQgZGVjbC1zcGVjaWZpZXJzLiAgKi8KICBmb3IgKGRzID0gZHNfZmlyc3Q7IGRzICE9IGRzX2xhc3Q7ICsrZHMpCiAgICB7CiAgICAgIHVuc2lnbmVkIGNvdW50ID0gZGVjbHNwZWNzLT5zcGVjc1soaW50KWRzXTsKICAgICAgaWYgKGNvdW50IDwgMikKCWNvbnRpbnVlOwogICAgICAvKiBUaGUgImxvbmciIHNwZWNpZmllciBpcyBhIHNwZWNpYWwgY2FzZSBiZWNhdXNlIG9mCgkgImxvbmcgbG9uZyIuICAqLwogICAgICBpZiAoZHMgPT0gZHNfbG9uZykKCXsKCSAgaWYgKGNvdW50ID4gMikKCSAgICBlcnJvciAoIiU8bG9uZyBsb25nIGxvbmclPiBpcyB0b28gbG9uZyBmb3IgR0NDIik7CgkgIGVsc2UgaWYgKHBlZGFudGljICYmICFpbl9zeXN0ZW1faGVhZGVyICYmIHdhcm5fbG9uZ19sb25nKQoJICAgIHBlZHdhcm4gKCJJU08gQysrIGRvZXMgbm90IHN1cHBvcnQgJTxsb25nIGxvbmclPiIpOwoJICBlbHNlCgkgICAgbG9uZ2xvbmcgPSAxOwoJfQogICAgICBlbHNlIGlmIChkZWNsc3BlY3MtPnNwZWNzWyhpbnQpZHNdID4gMSkKCXsKCSAgc3RhdGljIGNvbnN0IGNoYXIgKmNvbnN0IGRlY2xfc3BlY19uYW1lc1tdID0gewoJICAgICJzaWduZWQiLAoJICAgICJ1bnNpZ25lZCIsCgkgICAgInNob3J0IiwKCSAgICAibG9uZyIsCgkgICAgImNvbnN0IiwKCSAgICAidm9sYXRpbGUiLAoJICAgICJyZXN0cmljdCIsCgkgICAgImlubGluZSIsCgkgICAgInZpcnR1YWwiLAoJICAgICJleHBsaWNpdCIsCgkgICAgImZyaWVuZCIsCgkgICAgInR5cGVkZWYiLAoJICAgICJfX2NvbXBsZXgiLAoJICAgICJfX3RocmVhZCIKCSAgICAvKiBBUFBMRSBMT0NBTCBDVyBhc20gYmxvY2tzLiAqLwoJICAgICwgImFzbSIKCSAgfTsKCSAgZXJyb3IgKCJkdXBsaWNhdGUgJXFzIiwgZGVjbF9zcGVjX25hbWVzWyhpbnQpZHNdKTsKCX0KICAgIH0KCiNpZiAwCiAgLyogU2VlIHRoZSBjb2RlIGJlbG93IHRoYXQgdXNlZCB0aGlzLiAgKi8KICBpZiAodHlwZWRlZl9kZWNsKQogICAgZGVjbF9hdHRyID0gREVDTF9BVFRSSUJVVEVTICh0eXBlZGVmX2RlY2wpOwojZW5kaWYKICB0eXBlZGVmX3R5cGUgPSB0eXBlOwoKCiAgaWYgKHNmayAhPSBzZmtfY29udmVyc2lvbikKICAgIGN0b3JfcmV0dXJuX3R5cGUgPSBjdHlwZTsKCiAgaWYgKHNmayAhPSBzZmtfbm9uZSkKICAgIHR5cGUgPSBjaGVja19zcGVjaWFsX2Z1bmN0aW9uX3JldHVybl90eXBlIChzZmssIHR5cGUsCgkJCQkJICAgICAgIGN0b3JfcmV0dXJuX3R5cGUpOwogIGVsc2UgaWYgKHR5cGUgPT0gTlVMTF9UUkVFKQogICAgewogICAgICBpbnQgaXNfbWFpbjsKCiAgICAgIGV4cGxpY2l0X2ludCA9IC0xOwoKICAgICAgLyogV2UgaGFuZGxlIGBtYWluJyBzcGVjaWFsbHkgaGVyZSwgYmVjYXVzZSAnbWFpbiAoKSB7IH0nIGlzIHNvCgkgY29tbW9uLiAgV2l0aCBubyBvcHRpb25zLCBpdCBpcyBhbGxvd2VkLiAgV2l0aCAtV3JldHVybi10eXBlLAoJIGl0IGlzIGEgd2FybmluZy4gIEl0IGlzIG9ubHkgYW4gZXJyb3Igd2l0aCAtcGVkYW50aWMtZXJyb3JzLiAgKi8KICAgICAgaXNfbWFpbiA9IChmdW5jZGVmX2ZsYWcKCQkgJiYgZG5hbWUgJiYgTUFJTl9OQU1FX1AgKGRuYW1lKQoJCSAmJiBjdHlwZSA9PSBOVUxMX1RSRUUKCQkgJiYgaW5fbmFtZXNwYWNlID09IE5VTExfVFJFRQoJCSAmJiBjdXJyZW50X25hbWVzcGFjZSA9PSBnbG9iYWxfbmFtZXNwYWNlKTsKCiAgICAgIGlmICh0eXBlX3dhc19lcnJvcl9tYXJrX25vZGUpCgkvKiBXZSd2ZSBhbHJlYWR5IGlzc3VlZCBhbiBlcnJvciwgZG9uJ3QgY29tcGxhaW4gbW9yZS4gICovOwogICAgICBlbHNlIGlmIChpbl9zeXN0ZW1faGVhZGVyIHx8IGZsYWdfbXNfZXh0ZW5zaW9ucykKCS8qIEFsbG93IGl0LCBzaWdoLiAgKi87CiAgICAgIGVsc2UgaWYgKHBlZGFudGljIHx8ICEgaXNfbWFpbikKCXBlZHdhcm4gKCJJU08gQysrIGZvcmJpZHMgZGVjbGFyYXRpb24gb2YgJXFzIHdpdGggbm8gdHlwZSIsIG5hbWUpOwogICAgICBlbHNlIGlmICh3YXJuX3JldHVybl90eXBlKQoJd2FybmluZyAoIklTTyBDKysgZm9yYmlkcyBkZWNsYXJhdGlvbiBvZiAlcXMgd2l0aCBubyB0eXBlIiwgbmFtZSk7CgogICAgICB0eXBlID0gaW50ZWdlcl90eXBlX25vZGU7CiAgICB9CgogIGN0eXBlID0gTlVMTF9UUkVFOwoKICAvKiBOb3cgcHJvY2VzcyB0aGUgbW9kaWZpZXJzIHRoYXQgd2VyZSBzcGVjaWZpZWQKICAgICBhbmQgY2hlY2sgZm9yIGludmFsaWQgY29tYmluYXRpb25zLiAgKi8KCiAgLyogTG9uZyBkb3VibGUgaXMgYSBzcGVjaWFsIGNvbWJpbmF0aW9uLiAgKi8KICBpZiAobG9uZ19wICYmIFRZUEVfTUFJTl9WQVJJQU5UICh0eXBlKSA9PSBkb3VibGVfdHlwZV9ub2RlKQogICAgewogICAgICBsb25nX3AgPSBmYWxzZTsKICAgICAgdHlwZSA9IGJ1aWxkX3F1YWxpZmllZF90eXBlIChsb25nX2RvdWJsZV90eXBlX25vZGUsCgkJCQkgICBjcF90eXBlX3F1YWxzICh0eXBlKSk7CiAgICB9CgogIC8qIENoZWNrIGFsbCBvdGhlciB1c2VzIG9mIHR5cGUgbW9kaWZpZXJzLiAgKi8KCiAgaWYgKHVuc2lnbmVkX3AgfHwgc2lnbmVkX3AgfHwgbG9uZ19wIHx8IHNob3J0X3ApCiAgICB7CiAgICAgIGludCBvayA9IDA7CgogICAgICBpZiAoVFJFRV9DT0RFICh0eXBlKSA9PSBSRUFMX1RZUEUpCgllcnJvciAoInNob3J0LCBzaWduZWQgb3IgdW5zaWduZWQgaW52YWxpZCBmb3IgJXFzIiwgbmFtZSk7CiAgICAgIGVsc2UgaWYgKFRSRUVfQ09ERSAodHlwZSkgIT0gSU5URUdFUl9UWVBFKQoJZXJyb3IgKCJsb25nLCBzaG9ydCwgc2lnbmVkIG9yIHVuc2lnbmVkIGludmFsaWQgZm9yICVxcyIsIG5hbWUpOwogICAgICBlbHNlIGlmIChsb25nX3AgJiYgc2hvcnRfcCkKCWVycm9yICgibG9uZyBhbmQgc2hvcnQgc3BlY2lmaWVkIHRvZ2V0aGVyIGZvciAlcXMiLCBuYW1lKTsKICAgICAgZWxzZSBpZiAoKGxvbmdfcCB8fCBzaG9ydF9wKSAmJiBleHBsaWNpdF9jaGFyKQoJZXJyb3IgKCJsb25nIG9yIHNob3J0IHNwZWNpZmllZCB3aXRoIGNoYXIgZm9yICVxcyIsIG5hbWUpOwogICAgICBlbHNlIGlmICgobG9uZ19wfHwgc2hvcnRfcCkgJiYgVFJFRV9DT0RFICh0eXBlKSA9PSBSRUFMX1RZUEUpCgllcnJvciAoImxvbmcgb3Igc2hvcnQgc3BlY2lmaWVkIHdpdGggZmxvYXRpbmcgdHlwZSBmb3IgJXFzIiwgbmFtZSk7CiAgICAgIGVsc2UgaWYgKHNpZ25lZF9wICYmIHVuc2lnbmVkX3ApCgllcnJvciAoInNpZ25lZCBhbmQgdW5zaWduZWQgZ2l2ZW4gdG9nZXRoZXIgZm9yICVxcyIsIG5hbWUpOwogICAgICBlbHNlCgl7CgkgIG9rID0gMTsKCSAgaWYgKCFleHBsaWNpdF9pbnQgJiYgIWRlZmF1bHRlZF9pbnQgJiYgIWV4cGxpY2l0X2NoYXIgJiYgcGVkYW50aWMpCgkgICAgewoJICAgICAgcGVkd2FybiAoImxvbmcsIHNob3J0LCBzaWduZWQgb3IgdW5zaWduZWQgdXNlZCBpbnZhbGlkbHkgZm9yICVxcyIsCgkJICAgICAgIG5hbWUpOwoJICAgICAgaWYgKGZsYWdfcGVkYW50aWNfZXJyb3JzKQoJCW9rID0gMDsKCSAgICB9Cgl9CgogICAgICAvKiBEaXNjYXJkIHRoZSB0eXBlIG1vZGlmaWVycyBpZiB0aGV5IGFyZSBpbnZhbGlkLiAgKi8KICAgICAgaWYgKCEgb2spCgl7CgkgIHVuc2lnbmVkX3AgPSBmYWxzZTsKCSAgc2lnbmVkX3AgPSBmYWxzZTsKCSAgbG9uZ19wID0gZmFsc2U7CgkgIHNob3J0X3AgPSBmYWxzZTsKCSAgbG9uZ2xvbmcgPSAwOwoJfQogICAgfQoKICAvKiBEZWNpZGUgd2hldGhlciBhbiBpbnRlZ2VyIHR5cGUgaXMgc2lnbmVkIG9yIG5vdC4KICAgICBPcHRpb25hbGx5IHRyZWF0IGJpdGZpZWxkcyBhcyBzaWduZWQgYnkgZGVmYXVsdC4gICovCiAgaWYgKHVuc2lnbmVkX3AKICAgICAgLyogW2NsYXNzLmJpdF0KCgkgSXQgaXMgaW1wbGVtZW50YXRpb24tZGVmaW5lZCB3aGV0aGVyIGEgcGxhaW4gKG5laXRoZXIKCSBleHBsaWNpdGx5IHNpZ25lZCBvciB1bnNpZ25lZCkgY2hhciwgc2hvcnQsIGludCwgb3IgbG9uZwoJIGJpdC1maWVsZCBpcyBzaWduZWQgb3IgdW5zaWduZWQuCgoJIE5hdHVyYWxseSwgd2UgZXh0ZW5kIHRoaXMgdG8gbG9uZyBsb25nIGFzIHdlbGwuICBOb3RlIHRoYXQKCSB0aGlzIGRvZXMgbm90IGluY2x1ZGUgd2NoYXJfdC4gICovCiAgICAgIHx8IChiaXRmaWVsZCAmJiAhZmxhZ19zaWduZWRfYml0ZmllbGRzCgkgICYmICFzaWduZWRfcAoJICAvKiBBIHR5cGVkZWYgZm9yIHBsYWluIGBpbnQnIHdpdGhvdXQgYHNpZ25lZCcgY2FuIGJlCgkgICAgIGNvbnRyb2xsZWQganVzdCBsaWtlIHBsYWluIGBpbnQnLCBidXQgYSB0eXBlZGVmIGZvcgoJICAgICBgc2lnbmVkIGludCcgY2Fubm90IGJlIHNvIGNvbnRyb2xsZWQuICAqLwoJICAmJiAhKHR5cGVkZWZfZGVjbAoJICAgICAgICYmIENfVFlQRURFRl9FWFBMSUNJVExZX1NJR05FRCAodHlwZWRlZl9kZWNsKSkKCSAgJiYgKFRSRUVfQ09ERSAodHlwZSkgPT0gSU5URUdFUl9UWVBFCgkgICAgICB8fCBUUkVFX0NPREUgKHR5cGUpID09IENIQVJfVFlQRSkKCSAgJiYgIXNhbWVfdHlwZV9wIChUWVBFX01BSU5fVkFSSUFOVCAodHlwZSksIHdjaGFyX3R5cGVfbm9kZSkpKQogICAgewogICAgICBpZiAobG9uZ2xvbmcpCgl0eXBlID0gbG9uZ19sb25nX3Vuc2lnbmVkX3R5cGVfbm9kZTsKICAgICAgZWxzZSBpZiAobG9uZ19wKQoJdHlwZSA9IGxvbmdfdW5zaWduZWRfdHlwZV9ub2RlOwogICAgICBlbHNlIGlmIChzaG9ydF9wKQoJdHlwZSA9IHNob3J0X3Vuc2lnbmVkX3R5cGVfbm9kZTsKICAgICAgZWxzZSBpZiAodHlwZSA9PSBjaGFyX3R5cGVfbm9kZSkKCXR5cGUgPSB1bnNpZ25lZF9jaGFyX3R5cGVfbm9kZTsKICAgICAgZWxzZSBpZiAodHlwZWRlZl9kZWNsKQoJdHlwZSA9IGNfY29tbW9uX3Vuc2lnbmVkX3R5cGUgKHR5cGUpOwogICAgICBlbHNlCgl0eXBlID0gdW5zaWduZWRfdHlwZV9ub2RlOwogICAgfQogIGVsc2UgaWYgKHNpZ25lZF9wICYmIHR5cGUgPT0gY2hhcl90eXBlX25vZGUpCiAgICB0eXBlID0gc2lnbmVkX2NoYXJfdHlwZV9ub2RlOwogIGVsc2UgaWYgKGxvbmdsb25nKQogICAgdHlwZSA9IGxvbmdfbG9uZ19pbnRlZ2VyX3R5cGVfbm9kZTsKICBlbHNlIGlmIChsb25nX3ApCiAgICB0eXBlID0gbG9uZ19pbnRlZ2VyX3R5cGVfbm9kZTsKICBlbHNlIGlmIChzaG9ydF9wKQogICAgdHlwZSA9IHNob3J0X2ludGVnZXJfdHlwZV9ub2RlOwoKICBpZiAoZGVjbHNwZWNzLT5zcGVjc1soaW50KWRzX2NvbXBsZXhdKQogICAgewogICAgICBpZiAoVFJFRV9DT0RFICh0eXBlKSAhPSBJTlRFR0VSX1RZUEUgJiYgVFJFRV9DT0RFICh0eXBlKSAhPSBSRUFMX1RZUEUpCgllcnJvciAoImNvbXBsZXggaW52YWxpZCBmb3IgJXFzIiwgbmFtZSk7CiAgICAgIC8qIElmIHdlIGp1c3QgaGF2ZSAiY29tcGxleCIsIGl0IGlzIGVxdWl2YWxlbnQgdG8KCSAiY29tcGxleCBkb3VibGUiLCBidXQgaWYgYW55IG1vZGlmaWVycyBhdCBhbGwgYXJlIHNwZWNpZmllZCBpdCBpcwoJIHRoZSBjb21wbGV4IGZvcm0gb2YgVFlQRS4gIEUuZywgImNvbXBsZXggc2hvcnQiIGlzCgkgImNvbXBsZXggc2hvcnQgaW50Ii4gICovCgogICAgICBlbHNlIGlmIChkZWZhdWx0ZWRfaW50ICYmICEgbG9uZ2xvbmcKCSAgICAgICAmJiAhIChsb25nX3AgfHwgc2hvcnRfcCB8fCBzaWduZWRfcCB8fCB1bnNpZ25lZF9wKSkKCXR5cGUgPSBjb21wbGV4X2RvdWJsZV90eXBlX25vZGU7CiAgICAgIGVsc2UgaWYgKHR5cGUgPT0gaW50ZWdlcl90eXBlX25vZGUpCgl0eXBlID0gY29tcGxleF9pbnRlZ2VyX3R5cGVfbm9kZTsKICAgICAgZWxzZSBpZiAodHlwZSA9PSBmbG9hdF90eXBlX25vZGUpCgl0eXBlID0gY29tcGxleF9mbG9hdF90eXBlX25vZGU7CiAgICAgIGVsc2UgaWYgKHR5cGUgPT0gZG91YmxlX3R5cGVfbm9kZSkKCXR5cGUgPSBjb21wbGV4X2RvdWJsZV90eXBlX25vZGU7CiAgICAgIGVsc2UgaWYgKHR5cGUgPT0gbG9uZ19kb3VibGVfdHlwZV9ub2RlKQoJdHlwZSA9IGNvbXBsZXhfbG9uZ19kb3VibGVfdHlwZV9ub2RlOwogICAgICBlbHNlCgl0eXBlID0gYnVpbGRfY29tcGxleF90eXBlICh0eXBlKTsKICAgIH0KCiAgdHlwZV9xdWFscyA9IFRZUEVfVU5RVUFMSUZJRUQ7CiAgaWYgKGRlY2xzcGVjcy0+c3BlY3NbKGludClkc19jb25zdF0pCiAgICB0eXBlX3F1YWxzIHw9IFRZUEVfUVVBTF9DT05TVDsKICBpZiAoZGVjbHNwZWNzLT5zcGVjc1soaW50KWRzX3ZvbGF0aWxlXSkKICAgIHR5cGVfcXVhbHMgfD0gVFlQRV9RVUFMX1ZPTEFUSUxFOwogIGlmIChkZWNsc3BlY3MtPnNwZWNzWyhpbnQpZHNfcmVzdHJpY3RdKQogICAgdHlwZV9xdWFscyB8PSBUWVBFX1FVQUxfUkVTVFJJQ1Q7CiAgaWYgKHNmayA9PSBzZmtfY29udmVyc2lvbiAmJiB0eXBlX3F1YWxzICE9IFRZUEVfVU5RVUFMSUZJRUQpCiAgICBlcnJvciAoInF1YWxpZmllcnMgYXJlIG5vdCBhbGxvd2VkIG9uIGRlY2xhcmF0aW9uIG9mICU8b3BlcmF0b3IgJVQlPiIsCiAgICAgICAgICAgY3Rvcl9yZXR1cm5fdHlwZSk7CgogIGlmIChUUkVFX0NPREUgKHR5cGUpID09IEZVTkNUSU9OX1RZUEUgCiAgICAgICYmIHR5cGVfcXVhbHMgIT0gVFlQRV9VTlFVQUxJRklFRCkKICAgIHsKICAgICAgLyogVGhpcyB3YXMgYW4gZXJyb3IgaW4gQysrOTggKGN2LXF1YWxpZmllcnMgY2Fubm90IGJlIGFkZGVkIHRvCiAgICAgICAgIGEgZnVuY3Rpb24gdHlwZSksIGJ1dCBEUiAyOTUgbWFrZXMgdGhlIGNvZGUgd2VsbC1mb3JtZWQgYnkKICAgICAgICAgZHJvcHBpbmcgdGhlIGV4dHJhIHF1YWxpZmllcnMuICovCiAgICAgIGlmIChwZWRhbnRpYykKICAgICAgICB7CiAgICAgICAgICB0cmVlIGJhZF90eXBlID0gYnVpbGRfcXVhbGlmaWVkX3R5cGUgKHR5cGUsIHR5cGVfcXVhbHMpOwogICAgICAgICAgcGVkd2FybiAoImlnbm9yaW5nICVxViBxdWFsaWZpZXJzIGFkZGVkIHRvIGZ1bmN0aW9uIHR5cGUgJXFUIiwKICAgICAgICAgICAgICAgICAgIGJhZF90eXBlLCB0eXBlKTsKICAgICAgICB9CiAgICAgIHR5cGVfcXVhbHMgPSBUWVBFX1VOUVVBTElGSUVEOwogICAgfQogIHR5cGVfcXVhbHMgfD0gY3BfdHlwZV9xdWFscyAodHlwZSk7CiAgdHlwZSA9IGNwX2J1aWxkX3F1YWxpZmllZF90eXBlX3JlYWwKICAgICh0eXBlLCB0eXBlX3F1YWxzLCAoKHR5cGVkZWZfZGVjbCAmJiAhREVDTF9BUlRJRklDSUFMICh0eXBlZGVmX2RlY2wpCiAJCQkgPyB0Zl9pZ25vcmVfYmFkX3F1YWxzIDogMCkgfCB0Zl9lcnJvciB8IHRmX3dhcm5pbmcpKTsKICAvKiBXZSBtaWdodCBoYXZlIGlnbm9yZWQgb3IgcmVqZWN0ZWQgc29tZSBvZiB0aGUgcXVhbGlmaWVycy4gICovCiAgdHlwZV9xdWFscyA9IGNwX3R5cGVfcXVhbHMgKHR5cGUpOwoKICBzdGF0aWNwID0gMDsKICBpbmxpbmVwID0gISEgZGVjbHNwZWNzLT5zcGVjc1soaW50KWRzX2lubGluZV07CiAgdmlydHVhbHAgPSAhISBkZWNsc3BlY3MtPnNwZWNzWyhpbnQpZHNfdmlydHVhbF07CiAgZXhwbGljaXRwID0gISEgZGVjbHNwZWNzLT5zcGVjc1soaW50KWRzX2V4cGxpY2l0XTsKCiAgc3RvcmFnZV9jbGFzcyA9IGRlY2xzcGVjcy0+c3RvcmFnZV9jbGFzczsKICBpZiAoc3RvcmFnZV9jbGFzcyA9PSBzY19zdGF0aWMpCiAgICBzdGF0aWNwID0gMSArIChkZWNsX2NvbnRleHQgPT0gRklFTEQpOwoKICBpZiAodmlydHVhbHAgJiYgc3RhdGljcCA9PSAyKQogICAgewogICAgICBlcnJvciAoIm1lbWJlciAlcUQgY2Fubm90IGJlIGRlY2xhcmVkIGJvdGggdmlydHVhbCBhbmQgc3RhdGljIiwgZG5hbWUpOwogICAgICBzdGF0aWNwID0gMDsKICAgIH0KICBmcmllbmRwID0gISEgZGVjbHNwZWNzLT5zcGVjc1soaW50KWRzX2ZyaWVuZF07CgogIGlmIChkZXBlbmRhbnRfbmFtZSAmJiAhZnJpZW5kcCkKICAgIHsKICAgICAgZXJyb3IgKCIlPCVUOjolRCU+IGlzIG5vdCBhIHZhbGlkIGRlY2xhcmF0b3IiLCBjdHlwZSwgZGVwZW5kYW50X25hbWUpOwogICAgICByZXR1cm4gdm9pZF90eXBlX25vZGU7CiAgICB9CgogIC8qIElzc3VlIGVycm9ycyBhYm91dCB1c2Ugb2Ygc3RvcmFnZSBjbGFzc2VzIGZvciBwYXJhbWV0ZXJzLiAgKi8KICBpZiAoZGVjbF9jb250ZXh0ID09IFBBUk0pCiAgICB7CiAgICAgIGlmIChkZWNsc3BlY3MtPnNwZWNzWyhpbnQpZHNfdHlwZWRlZl0pCgllcnJvciAoInR5cGVkZWYgZGVjbGFyYXRpb24gaW52YWxpZCBpbiBwYXJhbWV0ZXIgZGVjbGFyYXRpb24iKTsKICAgICAgZWxzZSBpZiAoc3RvcmFnZV9jbGFzcyA9PSBzY19zdGF0aWMKCSAgICAgICB8fCBzdG9yYWdlX2NsYXNzID09IHNjX2V4dGVybgoJICAgICAgIHx8IHRocmVhZF9wKQoJZXJyb3IgKCJzdG9yYWdlIGNsYXNzIHNwZWNpZmllcnMgaW52YWxpZCBpbiBwYXJhbWV0ZXIgZGVjbGFyYXRpb25zIik7CiAgICB9CgogIC8qIEdpdmUgZXJyb3IgaWYgYHZpcnR1YWwnIGlzIHVzZWQgb3V0c2lkZSBvZiBjbGFzcyBkZWNsYXJhdGlvbi4gICovCiAgaWYgKHZpcnR1YWxwCiAgICAgICYmIChjdXJyZW50X2NsYXNzX25hbWUgPT0gTlVMTF9UUkVFIHx8IGRlY2xfY29udGV4dCAhPSBGSUVMRCkpCiAgICB7CiAgICAgIGVycm9yICgidmlydHVhbCBvdXRzaWRlIGNsYXNzIGRlY2xhcmF0aW9uIik7CiAgICAgIHZpcnR1YWxwID0gMDsKICAgIH0KCiAgLyogU3RhdGljIGFub255bW91cyB1bmlvbnMgYXJlIGRlYWx0IHdpdGggaGVyZS4gICovCiAgaWYgKHN0YXRpY3AgJiYgZGVjbF9jb250ZXh0ID09IFRZUEVOQU1FCiAgICAgICYmIGRlY2xzcGVjcy0+dHlwZQogICAgICAmJiBBTk9OX0FHR1JfVFlQRV9QIChkZWNsc3BlY3MtPnR5cGUpKQogICAgZGVjbF9jb250ZXh0ID0gRklFTEQ7CgogIC8qIFdhcm4gYWJvdXQgc3RvcmFnZSBjbGFzc2VzIHRoYXQgYXJlIGludmFsaWQgZm9yIGNlcnRhaW4KICAgICBraW5kcyBvZiBkZWNsYXJhdGlvbnMgKHBhcmFtZXRlcnMsIHR5cGVuYW1lcywgZXRjLikuICAqLwogIGlmIChkZWNsc3BlY3MtPm11bHRpcGxlX3N0b3JhZ2VfY2xhc3Nlc19wKQogICAgZXJyb3IgKCJtdWx0aXBsZSBzdG9yYWdlIGNsYXNzZXMgaW4gZGVjbGFyYXRpb24gb2YgJXFzIiwgbmFtZSk7CiAgZWxzZSBpZiAodGhyZWFkX3AKCSAgICYmICgoc3RvcmFnZV9jbGFzcwoJCSYmIHN0b3JhZ2VfY2xhc3MgIT0gc2NfZXh0ZXJuCgkJJiYgc3RvcmFnZV9jbGFzcyAhPSBzY19zdGF0aWMpCgkgICAgICAgfHwgZGVjbHNwZWNzLT5zcGVjc1soaW50KWRzX3R5cGVkZWZdKSkKICAgIHsKICAgICAgZXJyb3IgKCJtdWx0aXBsZSBzdG9yYWdlIGNsYXNzZXMgaW4gZGVjbGFyYXRpb24gb2YgJXFzIiwgbmFtZSk7CiAgICAgIHRocmVhZF9wID0gZmFsc2U7CiAgICB9CiAgZWxzZSBpZiAoZGVjbF9jb250ZXh0ICE9IE5PUk1BTAoJICAgJiYgKChzdG9yYWdlX2NsYXNzICE9IHNjX25vbmUKCQkmJiBzdG9yYWdlX2NsYXNzICE9IHNjX211dGFibGUpCgkgICAgICAgfHwgdGhyZWFkX3ApKQogICAgewogICAgICBpZiAoKGRlY2xfY29udGV4dCA9PSBQQVJNIHx8IGRlY2xfY29udGV4dCA9PSBDQVRDSFBBUk0pCgkgICYmIChzdG9yYWdlX2NsYXNzID09IHNjX3JlZ2lzdGVyCgkgICAgICB8fCBzdG9yYWdlX2NsYXNzID09IHNjX2F1dG8pKQoJOwogICAgICBlbHNlIGlmIChkZWNsc3BlY3MtPnNwZWNzWyhpbnQpZHNfdHlwZWRlZl0pCgk7CiAgICAgIGVsc2UgaWYgKGRlY2xfY29udGV4dCA9PSBGSUVMRAoJICAgICAgIC8qIEMrKyBhbGxvd3Mgc3RhdGljIGNsYXNzIGVsZW1lbnRzLiAgKi8KCSAgICAgICAmJiBzdG9yYWdlX2NsYXNzID09IHNjX3N0YXRpYykKCS8qIEMrKyBhbHNvIGFsbG93cyBpbmxpbmVzIGFuZCBzaWduZWQgYW5kIHVuc2lnbmVkIGVsZW1lbnRzLAoJICAgYnV0IGluIHRob3NlIGNhc2VzIHdlIGRvbid0IGNvbWUgaW4gaGVyZS4gICovCgk7CiAgICAgIGVsc2UKCXsKCSAgaWYgKGRlY2xfY29udGV4dCA9PSBGSUVMRCkKCSAgICBlcnJvciAoInN0b3JhZ2UgY2xhc3Mgc3BlY2lmaWVkIGZvciAlcXMiLCBuYW1lKTsKCSAgZWxzZQoJICAgIHsKCSAgICAgIGlmIChkZWNsX2NvbnRleHQgPT0gUEFSTSB8fCBkZWNsX2NvbnRleHQgPT0gQ0FUQ0hQQVJNKQoJCWVycm9yICgic3RvcmFnZSBjbGFzcyBzcGVjaWZpZWQgZm9yIHBhcmFtZXRlciAlcXMiLCBuYW1lKTsKCSAgICAgIGVsc2UKCQllcnJvciAoInN0b3JhZ2UgY2xhc3Mgc3BlY2lmaWVkIGZvciB0eXBlbmFtZSIpOwoJICAgIH0KCSAgaWYgKHN0b3JhZ2VfY2xhc3MgPT0gc2NfcmVnaXN0ZXIKCSAgICAgIHx8IHN0b3JhZ2VfY2xhc3MgPT0gc2NfYXV0bwoJICAgICAgfHwgc3RvcmFnZV9jbGFzcyA9PSBzY19leHRlcm4KCSAgICAgIHx8IHRocmVhZF9wKQoJICAgIHN0b3JhZ2VfY2xhc3MgPSBzY19ub25lOwoJfQogICAgfQogIGVsc2UgaWYgKHN0b3JhZ2VfY2xhc3MgPT0gc2NfZXh0ZXJuICYmIGluaXRpYWxpemVkCgkgICAmJiAhZnVuY2RlZl9mbGFnKQogICAgewogICAgICBpZiAodG9wbGV2ZWxfYmluZGluZ3NfcCAoKSkKCXsKCSAgLyogSXQncyBjb21tb24gcHJhY3RpY2UgKGFuZCBjb21wbGV0ZWx5IHZhbGlkKSB0byBoYXZlIGEgY29uc3QKCSAgICAgYmUgaW5pdGlhbGl6ZWQgYW5kIGRlY2xhcmVkIGV4dGVybi4gICovCgkgIGlmICghKHR5cGVfcXVhbHMgJiBUWVBFX1FVQUxfQ09OU1QpKQoJICAgIHdhcm5pbmcgKCIlcXMgaW5pdGlhbGl6ZWQgYW5kIGRlY2xhcmVkICU8ZXh0ZXJuJT4iLCBuYW1lKTsKCX0KICAgICAgZWxzZQoJZXJyb3IgKCIlcXMgaGFzIGJvdGggJTxleHRlcm4lPiBhbmQgaW5pdGlhbGl6ZXIiLCBuYW1lKTsKICAgIH0KICBlbHNlIGlmIChzdG9yYWdlX2NsYXNzID09IHNjX2V4dGVybiAmJiBmdW5jZGVmX2ZsYWcKCSAgICYmICEgdG9wbGV2ZWxfYmluZGluZ3NfcCAoKSkKICAgIGVycm9yICgibmVzdGVkIGZ1bmN0aW9uICVxcyBkZWNsYXJlZCAlPGV4dGVybiU+IiwgbmFtZSk7CiAgZWxzZSBpZiAodG9wbGV2ZWxfYmluZGluZ3NfcCAoKSkKICAgIHsKICAgICAgaWYgKHN0b3JhZ2VfY2xhc3MgPT0gc2NfYXV0bykKCWVycm9yICgidG9wLWxldmVsIGRlY2xhcmF0aW9uIG9mICVxcyBzcGVjaWZpZXMgJTxhdXRvJT4iLCBuYW1lKTsKICAgIH0KICBlbHNlIGlmICh0aHJlYWRfcAoJICAgJiYgc3RvcmFnZV9jbGFzcyAhPSBzY19leHRlcm4KCSAgICYmIHN0b3JhZ2VfY2xhc3MgIT0gc2Nfc3RhdGljKQogICAgewogICAgICBlcnJvciAoImZ1bmN0aW9uLXNjb3BlICVxcyBpbXBsaWNpdGx5IGF1dG8gYW5kIGRlY2xhcmVkICU8X190aHJlYWQlPiIsCgkgICAgIG5hbWUpOwogICAgICB0aHJlYWRfcCA9IGZhbHNlOwogICAgfQoKICBpZiAoc3RvcmFnZV9jbGFzcyAmJiBmcmllbmRwKQogICAgZXJyb3IgKCJzdG9yYWdlIGNsYXNzIHNwZWNpZmllcnMgaW52YWxpZCBpbiBmcmllbmQgZnVuY3Rpb24gZGVjbGFyYXRpb25zIik7CgogIGlmICghaWRfZGVjbGFyYXRvcikKICAgIHVucXVhbGlmaWVkX2lkID0gTlVMTF9UUkVFOwogIGVsc2UKICAgIHsKICAgICAgdW5xdWFsaWZpZWRfaWQgPSBpZF9kZWNsYXJhdG9yLT51LmlkLnVucXVhbGlmaWVkX25hbWU7CiAgICAgIC8qIEFQUExFIExPQ0FMIGJlZ2luIG1haW5saW5lIDIwMDUtMTItMjcgNDQzMTA5MSAqLwogICAgICBzd2l0Y2ggKFRSRUVfQ09ERSAodW5xdWFsaWZpZWRfaWQpKQoJewoJY2FzZSBCSVRfTk9UX0VYUFI6CgkgIHVucXVhbGlmaWVkX2lkCgkgICAgPSBjb25zdHJ1Y3Rvcl9uYW1lIChUUkVFX09QRVJBTkQgKHVucXVhbGlmaWVkX2lkLCAwKSk7CgkgIGJyZWFrOwoKICAgICAgICAvKiBBUFBMRSBMT0NBTCBlbmQgbWFpbmxpbmUgMjAwNS0xMi0yNyA0NDMxMDkxICovCgljYXNlIElERU5USUZJRVJfTk9ERToKCWNhc2UgVEVNUExBVEVfSURfRVhQUjoKCSAgYnJlYWs7CgoJZGVmYXVsdDoKCSAgZ2NjX3VucmVhY2hhYmxlICgpOwoJfQogICAgfQoKICAvKiBEZXRlcm1pbmUgdGhlIHR5cGUgb2YgdGhlIGVudGl0eSBkZWNsYXJlZCBieSByZWN1cnJpbmcgb24gdGhlCiAgICAgZGVjbGFyYXRvci4gICovCiAgZm9yICg7IGRlY2xhcmF0b3I7IGRlY2xhcmF0b3IgPSBkZWNsYXJhdG9yLT5kZWNsYXJhdG9yKQogICAgewogICAgICBjb25zdCBjcF9kZWNsYXJhdG9yICppbm5lcl9kZWNsYXJhdG9yOwogICAgICB0cmVlIGF0dHJzOwoKICAgICAgaWYgKHR5cGUgPT0gZXJyb3JfbWFya19ub2RlKQoJcmV0dXJuIGVycm9yX21hcmtfbm9kZTsKCiAgICAgIGF0dHJzID0gZGVjbGFyYXRvci0+YXR0cmlidXRlczsKICAgICAgaWYgKGF0dHJzKQoJewoJICBpbnQgYXR0cl9mbGFnczsKCgkgIGF0dHJfZmxhZ3MgPSAwOwoJICBpZiAoZGVjbGFyYXRvciA9PSBOVUxMIHx8IGRlY2xhcmF0b3ItPmtpbmQgPT0gY2RrX2lkKQoJICAgIGF0dHJfZmxhZ3MgfD0gKGludCkgQVRUUl9GTEFHX0RFQ0xfTkVYVDsKCSAgaWYgKGRlY2xhcmF0b3ItPmtpbmQgPT0gY2RrX2Z1bmN0aW9uKQoJICAgIGF0dHJfZmxhZ3MgfD0gKGludCkgQVRUUl9GTEFHX0ZVTkNUSU9OX05FWFQ7CgkgIGlmIChkZWNsYXJhdG9yLT5raW5kID09IGNka19hcnJheSkKCSAgICBhdHRyX2ZsYWdzIHw9IChpbnQpIEFUVFJfRkxBR19BUlJBWV9ORVhUOwoJICByZXR1cm5lZF9hdHRycyA9IGRlY2xfYXR0cmlidXRlcyAoJnR5cGUsCgkJCQkJICAgIGNoYWlub24gKHJldHVybmVkX2F0dHJzLCBhdHRycyksCgkJCQkJICAgIGF0dHJfZmxhZ3MpOwoJfQoKICAgICAgaWYgKGRlY2xhcmF0b3ItPmtpbmQgPT0gY2RrX2lkKQoJYnJlYWs7CgogICAgICBpbm5lcl9kZWNsYXJhdG9yID0gZGVjbGFyYXRvci0+ZGVjbGFyYXRvcjsKCiAgICAgIHN3aXRjaCAoZGVjbGFyYXRvci0+a2luZCkKCXsKCWNhc2UgY2RrX2FycmF5OgoJICB0eXBlID0gY3JlYXRlX2FycmF5X3R5cGVfZm9yX2RlY2wgKGRuYW1lLCB0eXBlLAoJCQkJCSAgICAgZGVjbGFyYXRvci0+dS5hcnJheS5ib3VuZHMpOwoJICBicmVhazsKCgljYXNlIGNka19mdW5jdGlvbjoKCSAgewoJICAgIHRyZWUgYXJnX3R5cGVzOwoJICAgIGludCBmdW5jZGVjbF9wOwoKCSAgICAvKiBEZWNsYXJpbmcgYSBmdW5jdGlvbiB0eXBlLgoJICAgICAgIE1ha2Ugc3VyZSB3ZSBoYXZlIGEgdmFsaWQgdHlwZSBmb3IgdGhlIGZ1bmN0aW9uIHRvIHJldHVybi4gICovCgoJICAgIC8qIFdlIG5vdyBrbm93IHRoYXQgdGhlIFRZUEVfUVVBTFMgZG9uJ3QgYXBwbHkgdG8gdGhlCiAgICAgICAgICAgICAgIGRlY2wsIGJ1dCB0byBpdHMgcmV0dXJuIHR5cGUuICAqLwoJICAgIHR5cGVfcXVhbHMgPSBUWVBFX1VOUVVBTElGSUVEOwoKCSAgICAvKiBXYXJuIGFib3V0IHNvbWUgdHlwZXMgZnVuY3Rpb25zIGNhbid0IHJldHVybi4gICovCgoJICAgIGlmIChUUkVFX0NPREUgKHR5cGUpID09IEZVTkNUSU9OX1RZUEUpCgkgICAgICB7CgkJZXJyb3IgKCIlcXMgZGVjbGFyZWQgYXMgZnVuY3Rpb24gcmV0dXJuaW5nIGEgZnVuY3Rpb24iLCBuYW1lKTsKCQl0eXBlID0gaW50ZWdlcl90eXBlX25vZGU7CgkgICAgICB9CgkgICAgaWYgKFRSRUVfQ09ERSAodHlwZSkgPT0gQVJSQVlfVFlQRSkKCSAgICAgIHsKCQllcnJvciAoIiVxcyBkZWNsYXJlZCBhcyBmdW5jdGlvbiByZXR1cm5pbmcgYW4gYXJyYXkiLCBuYW1lKTsKCQl0eXBlID0gaW50ZWdlcl90eXBlX25vZGU7CgkgICAgICB9CgoJICAgIC8qIFBpY2sgdXAgdHlwZSBxdWFsaWZpZXJzIHdoaWNoIHNob3VsZCBiZSBhcHBsaWVkIHRvIGB0aGlzJy4gICovCgkgICAgcXVhbHMgPSBkZWNsYXJhdG9yLT51LmZ1bmN0aW9uLnF1YWxpZmllcnM7CgoJICAgIC8qIFBpY2sgdXAgdGhlIGV4Y2VwdGlvbiBzcGVjaWZpY2F0aW9ucy4gICovCgkgICAgcmFpc2VzID0gZGVjbGFyYXRvci0+dS5mdW5jdGlvbi5leGNlcHRpb25fc3BlY2lmaWNhdGlvbjsKCgkgICAgLyogU2F5IGl0J3MgYSBkZWZpbml0aW9uIG9ubHkgZm9yIHRoZSBDQUxMX0VYUFIKCSAgICAgICBjbG9zZXN0IHRvIHRoZSBpZGVudGlmaWVyLiAgKi8KCSAgICBmdW5jZGVjbF9wID0gaW5uZXJfZGVjbGFyYXRvciAmJiBpbm5lcl9kZWNsYXJhdG9yLT5raW5kID09IGNka19pZDsKCgkgICAgaWYgKGN0eXBlID09IE5VTExfVFJFRQoJCSYmIGRlY2xfY29udGV4dCA9PSBGSUVMRAoJCSYmIGZ1bmNkZWNsX3AKCQkmJiAoZnJpZW5kcCA9PSAwIHx8IGRuYW1lID09IGN1cnJlbnRfY2xhc3NfbmFtZSkpCgkgICAgICBjdHlwZSA9IGN1cnJlbnRfY2xhc3NfdHlwZTsKCgkgICAgaWYgKGN0eXBlICYmIHNmayA9PSBzZmtfY29udmVyc2lvbikKCSAgICAgIFRZUEVfSEFTX0NPTlZFUlNJT04gKGN0eXBlKSA9IDE7CgkgICAgaWYgKGN0eXBlICYmIChzZmsgPT0gc2ZrX2NvbnN0cnVjdG9yCgkJCSAgfHwgc2ZrID09IHNma19kZXN0cnVjdG9yKSkKCSAgICAgIHsKCQkvKiBXZSBhcmUgd2l0aGluIGEgY2xhc3MncyBzY29wZS4gSWYgb3VyIGRlY2xhcmF0b3IgbmFtZQoJCSAgIGlzIHRoZSBzYW1lIGFzIHRoZSBjbGFzcyBuYW1lLCBhbmQgd2UgYXJlIGRlZmluaW5nCgkJICAgYSBmdW5jdGlvbiwgdGhlbiBpdCBpcyBhIGNvbnN0cnVjdG9yL2Rlc3RydWN0b3IsIGFuZAoJCSAgIHRoZXJlZm9yZSByZXR1cm5zIGEgdm9pZCB0eXBlLiAgKi8KCgkJaWYgKGZsYWdzID09IERUT1JfRkxBRykKCQkgIHsKCQkgICAgLyogSVNPIEMrKyAxMi40LzIuICBBIGRlc3RydWN0b3IgbWF5IG5vdCBiZQoJCSAgICAgICBkZWNsYXJlZCBjb25zdCBvciB2b2xhdGlsZS4gIEEgZGVzdHJ1Y3RvciBtYXkKCQkgICAgICAgbm90IGJlIHN0YXRpYy4gICovCgkJICAgIGlmIChzdGF0aWNwID09IDIpCgkJICAgICAgZXJyb3IgKCJkZXN0cnVjdG9yIGNhbm5vdCBiZSBzdGF0aWMgbWVtYmVyIGZ1bmN0aW9uIik7CgkJICAgIGlmIChxdWFscykKCQkgICAgICB7CgkJCWVycm9yICgiZGVzdHJ1Y3RvcnMgbWF5IG5vdCBiZSBjdi1xdWFsaWZpZWQiKTsKCQkJcXVhbHMgPSBUWVBFX1VOUVVBTElGSUVEOwoJCSAgICAgIH0KCQkgICAgaWYgKGRlY2xfY29udGV4dCA9PSBGSUVMRCkKCQkgICAgICB7CgkJCWlmICghIG1lbWJlcl9mdW5jdGlvbl9vcl9lbHNlIChjdHlwZSwKCQkJCQkJICAgICAgIGN1cnJlbnRfY2xhc3NfdHlwZSwKCQkJCQkJICAgICAgIGZsYWdzKSkKCQkJICByZXR1cm4gdm9pZF90eXBlX25vZGU7CgkJICAgICAgfQoJCSAgfQoJCWVsc2UgICAgICAgICAgICAvKiBJdCdzIGEgY29uc3RydWN0b3IuICAqLwoJCSAgewoJCSAgICBpZiAoZXhwbGljaXRwID09IDEpCgkJICAgICAgZXhwbGljaXRwID0gMjsKCQkgICAgLyogSVNPIEMrKyAxMi4xLiAgQSBjb25zdHJ1Y3RvciBtYXkgbm90IGJlCgkJICAgICAgIGRlY2xhcmVkIGNvbnN0IG9yIHZvbGF0aWxlLiAgQSBjb25zdHJ1Y3RvciBtYXkKCQkgICAgICAgbm90IGJlIHZpcnR1YWwuICBBIGNvbnN0cnVjdG9yIG1heSBub3QgYmUKCQkgICAgICAgc3RhdGljLiAgKi8KCQkgICAgaWYgKHN0YXRpY3AgPT0gMikKCQkgICAgICBlcnJvciAoImNvbnN0cnVjdG9yIGNhbm5vdCBiZSBzdGF0aWMgbWVtYmVyIGZ1bmN0aW9uIik7CgkJICAgIGlmICh2aXJ0dWFscCkKCQkgICAgICB7CgkJCXBlZHdhcm4gKCJjb25zdHJ1Y3RvcnMgY2Fubm90IGJlIGRlY2xhcmVkIHZpcnR1YWwiKTsKCQkJdmlydHVhbHAgPSAwOwoJCSAgICAgIH0KCQkgICAgaWYgKHF1YWxzKQoJCSAgICAgIHsKCQkJZXJyb3IgKCJjb25zdHJ1Y3RvcnMgbWF5IG5vdCBiZSBjdi1xdWFsaWZpZWQiKTsKCQkJcXVhbHMgPSBUWVBFX1VOUVVBTElGSUVEOwoJCSAgICAgIH0KCQkgICAgaWYgKGRlY2xfY29udGV4dCA9PSBGSUVMRCkKCQkgICAgICB7CgkJCWlmICghIG1lbWJlcl9mdW5jdGlvbl9vcl9lbHNlIChjdHlwZSwKCQkJCQkJICAgICAgIGN1cnJlbnRfY2xhc3NfdHlwZSwKCQkJCQkJICAgICAgIGZsYWdzKSkKCQkJICByZXR1cm4gdm9pZF90eXBlX25vZGU7CgkJCVRZUEVfSEFTX0NPTlNUUlVDVE9SIChjdHlwZSkgPSAxOwoJCQlpZiAoc2ZrICE9IHNma19jb25zdHJ1Y3RvcikKCQkJICByZXR1cm4gTlVMTF9UUkVFOwoJCSAgICAgIH0KCQkgIH0KCQlpZiAoZGVjbF9jb250ZXh0ID09IEZJRUxEKQoJCSAgc3RhdGljcCA9IDA7CgkgICAgICB9CgkgICAgZWxzZSBpZiAoZnJpZW5kcCkKCSAgICAgIHsKCQlpZiAoaW5pdGlhbGl6ZWQpCgkJICBlcnJvciAoImNhbid0IGluaXRpYWxpemUgZnJpZW5kIGZ1bmN0aW9uICVxcyIsIG5hbWUpOwoJCWlmICh2aXJ0dWFscCkKCQkgIHsKCQkgICAgLyogQ2Fubm90IGJlIGJvdGggZnJpZW5kIGFuZCB2aXJ0dWFsLiAgKi8KCQkgICAgZXJyb3IgKCJ2aXJ0dWFsIGZ1bmN0aW9ucyBjYW5ub3QgYmUgZnJpZW5kcyIpOwoJCSAgICBmcmllbmRwID0gMDsKCQkgIH0KCQlpZiAoZGVjbF9jb250ZXh0ID09IE5PUk1BTCkKCQkgIGVycm9yICgiZnJpZW5kIGRlY2xhcmF0aW9uIG5vdCBpbiBjbGFzcyBkZWZpbml0aW9uIik7CgkJaWYgKGN1cnJlbnRfZnVuY3Rpb25fZGVjbCAmJiBmdW5jZGVmX2ZsYWcpCgkJICBlcnJvciAoImNhbid0IGRlZmluZSBmcmllbmQgZnVuY3Rpb24gJXFzIGluIGEgbG9jYWwgIgogICAgICAgICAgICAgICAgICAgICAgICAgImNsYXNzIGRlZmluaXRpb24iLAogICAgICAgICAgICAgICAgICAgICAgICAgbmFtZSk7CgkgICAgICB9CgoJICAgIGFyZ190eXBlcyA9IGdyb2twYXJtcyAoZGVjbGFyYXRvci0+dS5mdW5jdGlvbi5wYXJhbWV0ZXJzLAoJCQkJICAgJnBhcm1zKTsKCgkgICAgaWYgKGlubmVyX2RlY2xhcmF0b3IKCQkmJiBpbm5lcl9kZWNsYXJhdG9yLT5raW5kID09IGNka19pZAoJCSYmIGlubmVyX2RlY2xhcmF0b3ItPnUuaWQuc2ZrID09IHNma19kZXN0cnVjdG9yCgkJJiYgYXJnX3R5cGVzICE9IHZvaWRfbGlzdF9ub2RlKQoJICAgICAgewoJCWVycm9yICgiZGVzdHJ1Y3RvcnMgbWF5IG5vdCBoYXZlIHBhcmFtZXRlcnMiKTsKCQlhcmdfdHlwZXMgPSB2b2lkX2xpc3Rfbm9kZTsKCQlwYXJtcyA9IE5VTExfVFJFRTsKCSAgICAgIH0KCgkgICAgdHlwZSA9IGJ1aWxkX2Z1bmN0aW9uX3R5cGUgKHR5cGUsIGFyZ190eXBlcyk7CiAgICAgICAgICAgIHR5cGUgPSBjcF9idWlsZF9xdWFsaWZpZWRfdHlwZSAodHlwZSwgcXVhbHMpOwoJICB9CgkgIGJyZWFrOwoKCWNhc2UgY2RrX3BvaW50ZXI6CgljYXNlIGNka19yZWZlcmVuY2U6CgljYXNlIGNka19wdHJtZW06CgkgIC8qIEZpbHRlciBvdXQgcG9pbnRlcnMtdG8tcmVmZXJlbmNlcyBhbmQgcmVmZXJlbmNlcy10by1yZWZlcmVuY2VzLgoJICAgICBXZSBjYW4gZ2V0IHRoZXNlIGlmIGEgVFlQRV9ERUNMIGlzIHVzZWQuICAqLwoKCSAgaWYgKFRSRUVfQ09ERSAodHlwZSkgPT0gUkVGRVJFTkNFX1RZUEUpCgkgICAgewoJICAgICAgZXJyb3IgKGRlY2xhcmF0b3ItPmtpbmQgPT0gY2RrX3JlZmVyZW5jZQoJCSAgICAgPyAiY2Fubm90IGRlY2xhcmUgcmVmZXJlbmNlIHRvICVxI1QiCgkJICAgICA6ICJjYW5ub3QgZGVjbGFyZSBwb2ludGVyIHRvICVxI1QiLCB0eXBlKTsKCSAgICAgIHR5cGUgPSBUUkVFX1RZUEUgKHR5cGUpOwoJICAgIH0KCSAgZWxzZSBpZiAoVk9JRF9UWVBFX1AgKHR5cGUpKQoJICAgIHsKCSAgICAgIGlmIChkZWNsYXJhdG9yLT5raW5kID09IGNka19yZWZlcmVuY2UpCgkJZXJyb3IgKCJjYW5ub3QgZGVjbGFyZSByZWZlcmVuY2UgdG8gJXEjVCIsIHR5cGUpOwoJICAgICAgZWxzZSBpZiAoZGVjbGFyYXRvci0+a2luZCA9PSBjZGtfcHRybWVtKQoJCWVycm9yICgiY2Fubm90IGRlY2xhcmUgcG9pbnRlciB0byAlcSNUIG1lbWJlciIsIHR5cGUpOwoJICAgIH0KCgkgIC8qIFdlIG5vdyBrbm93IHRoYXQgdGhlIFRZUEVfUVVBTFMgZG9uJ3QgYXBwbHkgdG8gdGhlIGRlY2wsCgkgICAgIGJ1dCB0byB0aGUgdGFyZ2V0IG9mIHRoZSBwb2ludGVyLiAgKi8KCSAgdHlwZV9xdWFscyA9IFRZUEVfVU5RVUFMSUZJRUQ7CgoJICBpZiAoZGVjbGFyYXRvci0+a2luZCA9PSBjZGtfcHRybWVtCgkgICAgICAmJiAoVFJFRV9DT0RFICh0eXBlKSA9PSBGVU5DVElPTl9UWVBFCgkJICB8fCAocXVhbHMgJiYgVFJFRV9DT0RFICh0eXBlKSA9PSBNRVRIT0RfVFlQRSkpKQoJICAgIHsKCSAgICAgIHRyZWUgZHVtbXk7CgkgICAgICAKICAgICAgICAgICAgICAvKiBJZiB0aGUgdHlwZSBpcyBhIEZVTkNUSU9OX1RZUEUsIHBpY2sgdXAgdGhlCiAgICAgICAgICAgICAgICAgcXVhbGlmaWVycyBmcm9tIHRoYXQgZnVuY3Rpb24gdHlwZS4gTm8gb3RoZXIKICAgICAgICAgICAgICAgICBxdWFsaWZpZXJzIG1heSBiZSBzdXBwbGllZC4gKi8KICAgICAgICAgICAgICBpZiAoVFJFRV9DT0RFICh0eXBlKSA9PSBGVU5DVElPTl9UWVBFKQogICAgICAgICAgICAgICAgcXVhbHMgPSBjcF90eXBlX3F1YWxzICh0eXBlKTsKCgkgICAgICBkdW1teSA9IGJ1aWxkX2RlY2wgKFRZUEVfREVDTCwgTlVMTF9UUkVFLCB0eXBlKTsKCSAgICAgIGdyb2tfbWV0aG9kX3F1YWxzIChkZWNsYXJhdG9yLT51LnBvaW50ZXIuY2xhc3NfdHlwZSwKCQkJCSBkdW1teSwgcXVhbHMpOwoJICAgICAgdHlwZSA9IFRSRUVfVFlQRSAoZHVtbXkpOwoJICAgICAgcXVhbHMgPSBUWVBFX1VOUVVBTElGSUVEOwoJICAgIH0KCgkgIGlmIChkZWNsYXJhdG9yLT5raW5kID09IGNka19yZWZlcmVuY2UpCgkgICAgewoJICAgICAgaWYgKCFWT0lEX1RZUEVfUCAodHlwZSkpCgkJdHlwZSA9IGJ1aWxkX3JlZmVyZW5jZV90eXBlICh0eXBlKTsKCSAgICB9CgkgIGVsc2UgaWYgKFRSRUVfQ09ERSAodHlwZSkgPT0gTUVUSE9EX1RZUEUpCgkgICAgdHlwZSA9IGJ1aWxkX3B0cm1lbWZ1bmNfdHlwZSAoYnVpbGRfcG9pbnRlcl90eXBlICh0eXBlKSk7CgkgIGVsc2UgaWYgKGRlY2xhcmF0b3ItPmtpbmQgPT0gY2RrX3B0cm1lbSkKCSAgICB7CgkgICAgICAvKiBXZSBtaWdodCBoYXZlIHBhcnNlZCBhIG5hbWVzcGFjZSBhcyB0aGUgY2xhc3MgdHlwZS4gICovCgkgICAgICBpZiAoVFJFRV9DT0RFIChkZWNsYXJhdG9yLT51LnBvaW50ZXIuY2xhc3NfdHlwZSkKCQkgID09IE5BTUVTUEFDRV9ERUNMKQoJCXsKCQkgIGVycm9yICgiJXFEIGlzIGEgbmFtZXNwYWNlIiwKCQkJIGRlY2xhcmF0b3ItPnUucG9pbnRlci5jbGFzc190eXBlKTsKCQkgIHR5cGUgPSBidWlsZF9wb2ludGVyX3R5cGUgKHR5cGUpOwoJCX0KCSAgICAgIGVsc2UgaWYgKGRlY2xhcmF0b3ItPnUucG9pbnRlci5jbGFzc190eXBlID09IGVycm9yX21hcmtfbm9kZSkKCQkvKiBXZSB3aWxsIGFscmVhZHkgaGF2ZSBjb21wbGFpbmVkLiAgKi8KCQl0eXBlID0gZXJyb3JfbWFya19ub2RlOwoJICAgICAgZWxzZQoJCXR5cGUgPSBidWlsZF9wdHJtZW1fdHlwZSAoZGVjbGFyYXRvci0+dS5wb2ludGVyLmNsYXNzX3R5cGUsCgkJCQkJICB0eXBlKTsKCSAgICB9CgkgIGVsc2UKCSAgICB0eXBlID0gYnVpbGRfcG9pbnRlcl90eXBlICh0eXBlKTsKCgkgIC8qIFByb2Nlc3MgYSBsaXN0IG9mIHR5cGUgbW9kaWZpZXIga2V5d29yZHMgKHN1Y2ggYXMKCSAgICAgY29uc3Qgb3Igdm9sYXRpbGUpIHRoYXQgd2VyZSBnaXZlbiBpbnNpZGUgdGhlIGAqJyBvciBgJicuICAqLwoKCSAgaWYgKGRlY2xhcmF0b3ItPnUucG9pbnRlci5xdWFsaWZpZXJzKQoJICAgIHsKCSAgICAgIHR5cGUKCQk9IGNwX2J1aWxkX3F1YWxpZmllZF90eXBlICh0eXBlLAoJCQkJCSAgIGRlY2xhcmF0b3ItPnUucG9pbnRlci5xdWFsaWZpZXJzKTsKCSAgICAgIHR5cGVfcXVhbHMgPSBjcF90eXBlX3F1YWxzICh0eXBlKTsKCSAgICB9CgkgIGN0eXBlID0gTlVMTF9UUkVFOwoJICBicmVhazsKCgljYXNlIGNka19lcnJvcjoKCSAgYnJlYWs7CgoJZGVmYXVsdDoKCSAgZ2NjX3VucmVhY2hhYmxlICgpOwoJfQogICAgfQoKICBpZiAodW5xdWFsaWZpZWRfaWQgJiYgVFJFRV9DT0RFICh1bnF1YWxpZmllZF9pZCkgPT0gVEVNUExBVEVfSURfRVhQUgogICAgICAmJiBUUkVFX0NPREUgKHR5cGUpICE9IEZVTkNUSU9OX1RZUEUKICAgICAgJiYgVFJFRV9DT0RFICh0eXBlKSAhPSBNRVRIT0RfVFlQRSkKICAgIHsKICAgICAgZXJyb3IgKCJ0ZW1wbGF0ZS1pZCAlcUQgdXNlZCBhcyBhIGRlY2xhcmF0b3IiLAoJICAgICB1bnF1YWxpZmllZF9pZCk7CiAgICAgIHVucXVhbGlmaWVkX2lkID0gZG5hbWU7CiAgICB9CgogIC8qIElmIERFQ0xBUkFUT1IgaXMgbm9uLU5VTEwsIHdlIGtub3cgaXQgaXMgYSBjZGtfaWQgZGVjbGFyYXRvcjsKICAgICBvdGhlcndpc2UsIHdlIHdvdWxkIG5vdCBoYXZlIGV4aXRlZCB0aGUgbG9vcCBhYm92ZS4gICovCiAgaWYgKGRlY2xhcmF0b3IKICAgICAgJiYgZGVjbGFyYXRvci0+dS5pZC5xdWFsaWZ5aW5nX3Njb3BlCiAgICAgICYmIFRZUEVfUCAoZGVjbGFyYXRvci0+dS5pZC5xdWFsaWZ5aW5nX3Njb3BlKSkKICAgIHsKICAgICAgdHJlZSB0OwoKICAgICAgY3R5cGUgPSBkZWNsYXJhdG9yLT51LmlkLnF1YWxpZnlpbmdfc2NvcGU7CiAgICAgIGN0eXBlID0gVFlQRV9NQUlOX1ZBUklBTlQgKGN0eXBlKTsKICAgICAgdCA9IGN0eXBlOwogICAgICB3aGlsZSAodCAhPSBOVUxMX1RSRUUgJiYgQ0xBU1NfVFlQRV9QICh0KSkKCXsKCSAgLyogWW91J3JlIHN1cHBvc2VkIHRvIGhhdmUgb25lIGB0ZW1wbGF0ZSA8Li4uPicgZm9yIGV2ZXJ5CgkgICAgIHRlbXBsYXRlIGNsYXNzLCBidXQgeW91IGRvbid0IG5lZWQgb25lIGZvciBhIGZ1bGwKCSAgICAgc3BlY2lhbGl6YXRpb24uICBGb3IgZXhhbXBsZToKCgkgICAgICAgdGVtcGxhdGUgPGNsYXNzIFQ+IHN0cnVjdCBTe307CgkgICAgICAgdGVtcGxhdGUgPD4gc3RydWN0IFM8aW50PiB7IHZvaWQgZigpOyB9OwoJICAgICAgIHZvaWQgUzxpbnQ+OjpmICgpIHt9CgoJICAgICBpcyBjb3JyZWN0OyB0aGVyZSBzaG91bGRuJ3QgYmUgYSBgdGVtcGxhdGUgPD4nIGZvciB0aGUKCSAgICAgZGVmaW5pdGlvbiBvZiBgUzxpbnQ+OjpmJy4gICovCgkgIGlmIChDTEFTU1RZUEVfVEVNUExBVEVfSU5GTyAodCkKCSAgICAgICYmIChDTEFTU1RZUEVfVEVNUExBVEVfSU5TVEFOVElBVElPTiAodCkKCQkgIHx8IHVzZXNfdGVtcGxhdGVfcGFybXMgKENMQVNTVFlQRV9USV9BUkdTICh0KSkpCgkgICAgICAmJiBQUklNQVJZX1RFTVBMQVRFX1AgKENMQVNTVFlQRV9USV9URU1QTEFURSAodCkpKQoJICAgIHRlbXBsYXRlX2NvdW50ICs9IDE7CgoJICB0ID0gVFlQRV9NQUlOX0RFQ0wgKHQpOwoJICB0ID0gREVDTF9DT05URVhUICh0KTsKCX0KCiAgICAgIGlmIChjdHlwZSA9PSBjdXJyZW50X2NsYXNzX3R5cGUpCgl7CgkgIC8qIGNsYXNzIEEgewoJICAgICAgIHZvaWQgQTo6ZiAoKTsKCSAgICAgfTsKCgkgICAgIElzIHRoaXMgaWxsLWZvcm1lZD8gICovCgoJICBpZiAocGVkYW50aWMpCgkgICAgcGVkd2FybiAoImV4dHJhIHF1YWxpZmljYXRpb24gJTwlVDo6JT4gb24gbWVtYmVyICVxcyBpZ25vcmVkIiwKCQkJY3R5cGUsIG5hbWUpOwoJfQogICAgICBlbHNlIGlmIChUUkVFX0NPREUgKHR5cGUpID09IEZVTkNUSU9OX1RZUEUpCgl7CgkgIHRyZWUgc25hbWUgPSBkZWNsYXJhdG9yLT51LmlkLnVucXVhbGlmaWVkX25hbWU7CgoJICBpZiAoVFJFRV9DT0RFIChzbmFtZSkgPT0gSURFTlRJRklFUl9OT0RFCgkgICAgICAmJiBORVdfREVMRVRFX09QTkFNRV9QIChzbmFtZSkpCgkgICAgLyogT3ZlcmxvYWRlZCBvcGVyYXRvciBuZXcgYW5kIG9wZXJhdG9yIGRlbGV0ZQoJICAgICAgIGFyZSBhbHdheXMgc3RhdGljIGZ1bmN0aW9ucy4gICovCgkgICAgOwoJICBlbHNlIGlmIChjdXJyZW50X2NsYXNzX3R5cGUgPT0gTlVMTF9UUkVFIHx8IGZyaWVuZHApCgkgICAgdHlwZQoJICAgICAgPSBidWlsZF9tZXRob2RfdHlwZV9kaXJlY3RseSAoY3R5cGUsCgkJCQkJICAgIFRSRUVfVFlQRSAodHlwZSksCgkJCQkJICAgIFRZUEVfQVJHX1RZUEVTICh0eXBlKSk7CgkgIGVsc2UKCSAgICB7CgkgICAgICBlcnJvciAoImNhbm5vdCBkZWNsYXJlIG1lbWJlciBmdW5jdGlvbiAlPCVUOjolcyU+IHdpdGhpbiAlPCVUJT4iLAogCQkgICAgIGN0eXBlLCBuYW1lLCBjdXJyZW50X2NsYXNzX3R5cGUpOwoJICAgICAgcmV0dXJuIGVycm9yX21hcmtfbm9kZTsKCSAgICB9Cgl9CiAgICAgIGVsc2UgaWYgKGRlY2xzcGVjcy0+c3BlY3NbKGludClkc190eXBlZGVmXQoJICAgICAgIHx8IENPTVBMRVRFX1RZUEVfUCAoY29tcGxldGVfdHlwZSAoY3R5cGUpKSkKCXsKCSAgLyogSGF2ZSB0byBtb3ZlIHRoaXMgY29kZSBlbHNld2hlcmUgaW4gdGhpcyBmdW5jdGlvbi4KCSAgICAgdGhpcyBjb2RlIGlzIHVzZWQgZm9yIGkuZS4sIHR5cGVkZWYgaW50IEE6Ok07IE0gKnBtOwoKCSAgICAgSXQgaXM/ICBIb3c/IGphc29uIDEwLzIvOTQgKi8KCgkgIGlmIChjdXJyZW50X2NsYXNzX3R5cGUpCgkgICAgewoJICAgICAgZXJyb3IgKCJjYW5ub3QgZGVjbGFyZSBtZW1iZXIgJTwlVDo6JXMlPiB3aXRoaW4gJXFUIiwKCQkgICAgIGN0eXBlLCBuYW1lLCBjdXJyZW50X2NsYXNzX3R5cGUpOwoJICAgICAgcmV0dXJuIHZvaWRfdHlwZV9ub2RlOwoJICAgIH0KCX0KICAgICAgZWxzZQoJewoJICBjeHhfaW5jb21wbGV0ZV90eXBlX2Vycm9yIChOVUxMX1RSRUUsIGN0eXBlKTsKCSAgcmV0dXJuIGVycm9yX21hcmtfbm9kZTsKCX0KICAgIH0KCiAgaWYgKHJldHVybmVkX2F0dHJzKQogICAgewogICAgICBpZiAoYXR0cmxpc3QpCgkqYXR0cmxpc3QgPSBjaGFpbm9uIChyZXR1cm5lZF9hdHRycywgKmF0dHJsaXN0KTsKICAgICAgZWxzZQoJYXR0cmxpc3QgPSAmcmV0dXJuZWRfYXR0cnM7CiAgICB9CgogIC8qIE5vdyBUWVBFIGhhcyB0aGUgYWN0dWFsIHR5cGUuICAqLwoKICAvKiBEaWQgYXJyYXkgc2l6ZSBjYWxjdWxhdGlvbnMgb3ZlcmZsb3c/ICAqLwoKICBpZiAoVFJFRV9DT0RFICh0eXBlKSA9PSBBUlJBWV9UWVBFCiAgICAgICYmIENPTVBMRVRFX1RZUEVfUCAodHlwZSkKICAgICAgJiYgVFJFRV9PVkVSRkxPVyAoVFlQRV9TSVpFICh0eXBlKSkpCiAgICB7CiAgICAgIGVycm9yICgic2l6ZSBvZiBhcnJheSAlcXMgaXMgdG9vIGxhcmdlIiwgbmFtZSk7CiAgICAgIC8qIElmIHdlIHByb2NlZWQgd2l0aCB0aGUgYXJyYXkgdHlwZSBhcyBpdCBpcywgd2UnbGwgZXZlbnR1YWxseQoJIGNyYXNoIGluIHRyZWVfbG93X2NzdCgpLiAgKi8KICAgICAgdHlwZSA9IGVycm9yX21hcmtfbm9kZTsKICAgIH0KCiAgaWYgKChkZWNsX2NvbnRleHQgPT0gRklFTEQgfHwgZGVjbF9jb250ZXh0ID09IFBBUk0pCiAgICAgICYmICFwcm9jZXNzaW5nX3RlbXBsYXRlX2RlY2wKICAgICAgJiYgdmFyaWFibHlfbW9kaWZpZWRfdHlwZV9wICh0eXBlLCBOVUxMX1RSRUUpKQogICAgewogICAgICBpZiAoZGVjbF9jb250ZXh0ID09IEZJRUxEKQoJZXJyb3IgKCJkYXRhIG1lbWJlciBtYXkgbm90IGhhdmUgdmFyaWFibHkgbW9kaWZpZWQgdHlwZSAlcVQiLCB0eXBlKTsKICAgICAgZWxzZQoJZXJyb3IgKCJwYXJhbWV0ZXIgbWF5IG5vdCBoYXZlIHZhcmlhYmx5IG1vZGlmaWVkIHR5cGUgJXFUIiwgdHlwZSk7CiAgICAgIHR5cGUgPSBlcnJvcl9tYXJrX25vZGU7CiAgICB9CgogIGlmIChleHBsaWNpdHAgPT0gMSB8fCAoZXhwbGljaXRwICYmIGZyaWVuZHApKQogICAgewogICAgICAvKiBbZGNsLmZjdC5zcGVjXSBUaGUgZXhwbGljaXQgc3BlY2lmaWVyIHNoYWxsIG9ubHkgYmUgdXNlZCBpbgogICAgICAgICBkZWNsYXJhdGlvbnMgb2YgY29uc3RydWN0b3JzIHdpdGhpbiBhIGNsYXNzIGRlZmluaXRpb24uICAqLwogICAgICBlcnJvciAoIm9ubHkgZGVjbGFyYXRpb25zIG9mIGNvbnN0cnVjdG9ycyBjYW4gYmUgJTxleHBsaWNpdCU+Iik7CiAgICAgIGV4cGxpY2l0cCA9IDA7CiAgICB9CgogIGlmIChzdG9yYWdlX2NsYXNzID09IHNjX211dGFibGUpCiAgICB7CiAgICAgIGlmIChkZWNsX2NvbnRleHQgIT0gRklFTEQgfHwgZnJpZW5kcCkKICAgICAgICB7CgkgIGVycm9yICgibm9uLW1lbWJlciAlcXMgY2Fubm90IGJlIGRlY2xhcmVkICU8bXV0YWJsZSU+IiwgbmFtZSk7CgkgIHN0b3JhZ2VfY2xhc3MgPSBzY19ub25lOwogICAgICAgIH0KICAgICAgZWxzZSBpZiAoZGVjbF9jb250ZXh0ID09IFRZUEVOQU1FIHx8IGRlY2xzcGVjcy0+c3BlY3NbKGludClkc190eXBlZGVmXSkKCXsKCSAgZXJyb3IgKCJub24tb2JqZWN0IG1lbWJlciAlcXMgY2Fubm90IGJlIGRlY2xhcmVkICU8bXV0YWJsZSU+IiwgbmFtZSk7CgkgIHN0b3JhZ2VfY2xhc3MgPSBzY19ub25lOwoJfQogICAgICBlbHNlIGlmIChUUkVFX0NPREUgKHR5cGUpID09IEZVTkNUSU9OX1RZUEUKICAgICAgICAgICAgICAgfHwgVFJFRV9DT0RFICh0eXBlKSA9PSBNRVRIT0RfVFlQRSkKICAgICAgICB7CgkgIGVycm9yICgiZnVuY3Rpb24gJXFzIGNhbm5vdCBiZSBkZWNsYXJlZCAlPG11dGFibGUlPiIsIG5hbWUpOwoJICBzdG9yYWdlX2NsYXNzID0gc2Nfbm9uZTsKICAgICAgICB9CiAgICAgIGVsc2UgaWYgKHN0YXRpY3ApCgl7CgkgIGVycm9yICgic3RhdGljICVxcyBjYW5ub3QgYmUgZGVjbGFyZWQgJTxtdXRhYmxlJT4iLCBuYW1lKTsKCSAgc3RvcmFnZV9jbGFzcyA9IHNjX25vbmU7Cgl9CiAgICAgIGVsc2UgaWYgKHR5cGVfcXVhbHMgJiBUWVBFX1FVQUxfQ09OU1QpCgl7CgkgIGVycm9yICgiY29uc3QgJXFzIGNhbm5vdCBiZSBkZWNsYXJlZCAlPG11dGFibGUlPiIsIG5hbWUpOwoJICBzdG9yYWdlX2NsYXNzID0gc2Nfbm9uZTsKCX0KICAgIH0KCiAgLyogSWYgdGhpcyBpcyBkZWNsYXJpbmcgYSB0eXBlZGVmIG5hbWUsIHJldHVybiBhIFRZUEVfREVDTC4gICovCiAgaWYgKGRlY2xzcGVjcy0+c3BlY3NbKGludClkc190eXBlZGVmXSAmJiBkZWNsX2NvbnRleHQgIT0gVFlQRU5BTUUpCiAgICB7CiAgICAgIHRyZWUgZGVjbDsKCiAgICAgIC8qIE5vdGUgdGhhdCB0aGUgZ3JhbW1hciByZWplY3RzIHN0b3JhZ2UgY2xhc3NlcwoJIGluIHR5cGVuYW1lcywgZmllbGRzIG9yIHBhcmFtZXRlcnMuICAqLwogICAgICBpZiAoY3VycmVudF9sYW5nX25hbWUgPT0gbGFuZ19uYW1lX2phdmEpCglUWVBFX0ZPUl9KQVZBICh0eXBlKSA9IDE7CgogICAgICBpZiAoZGVjbF9jb250ZXh0ID09IEZJRUxEKQoJZGVjbCA9IGJ1aWxkX2xhbmdfZGVjbCAoVFlQRV9ERUNMLCB1bnF1YWxpZmllZF9pZCwgdHlwZSk7CiAgICAgIGVsc2UKCWRlY2wgPSBidWlsZF9kZWNsIChUWVBFX0RFQ0wsIHVucXVhbGlmaWVkX2lkLCB0eXBlKTsKICAgICAgaWYgKGlkX2RlY2xhcmF0b3IgJiYgZGVjbGFyYXRvci0+dS5pZC5xdWFsaWZ5aW5nX3Njb3BlKQoJZXJyb3IgKCIlSnR5cGVkZWYgbmFtZSBtYXkgbm90IGJlIGEgbmVzdGVkLW5hbWUtc3BlY2lmaWVyIiwgZGVjbCk7CgogICAgICBpZiAoZGVjbF9jb250ZXh0ICE9IEZJRUxEKQoJewoJICBpZiAoIWN1cnJlbnRfZnVuY3Rpb25fZGVjbCkKCSAgICBERUNMX0NPTlRFWFQgKGRlY2wpID0gRlJPQl9DT05URVhUIChjdXJyZW50X25hbWVzcGFjZSk7CgkgIGVsc2UgaWYgKERFQ0xfTUFZQkVfSU5fQ0hBUkdFX0NPTlNUUlVDVE9SX1AgKGN1cnJlbnRfZnVuY3Rpb25fZGVjbCkKCQkgICB8fCAoREVDTF9NQVlCRV9JTl9DSEFSR0VfREVTVFJVQ1RPUl9QIAoJCSAgICAgICAoY3VycmVudF9mdW5jdGlvbl9kZWNsKSkpCgkgICAgLyogVGhlIFRZUEVfREVDTCBpcyAiYWJzdHJhY3QiIGJlY2F1c2UgdGhlcmUgd2lsbCBiZQoJICAgICAgIGNsb25lcyBvZiB0aGlzIGNvbnN0cnVjdG9yL2Rlc3RydWN0b3IsIGFuZCB0aGVyZSB3aWxsCgkgICAgICAgYmUgY29waWVzIG9mIHRoaXMgVFlQRV9ERUNMIGdlbmVyYXRlZCBpbiB0aG9zZQoJICAgICAgIGNsb25lcy4gICovCgkgICAgREVDTF9BQlNUUkFDVCAoZGVjbCkgPSAxOwoJfQogICAgICBlbHNlIGlmIChjb25zdHJ1Y3Rvcl9uYW1lX3AgKHVucXVhbGlmaWVkX2lkLCBjdXJyZW50X2NsYXNzX3R5cGUpKQoJcGVkd2FybiAoIklTTyBDKysgZm9yYmlkcyBuZXN0ZWQgdHlwZSAlcUQgd2l0aCBzYW1lIG5hbWUgIgoJCSAiYXMgZW5jbG9zaW5nIGNsYXNzIiwKCQkgdW5xdWFsaWZpZWRfaWQpOwoKICAgICAgLyogSWYgdGhlIHVzZXIgZGVjbGFyZXMgInR5cGVkZWYgc3RydWN0IHsuLi59IGZvbyIgdGhlbiB0aGUKCSBzdHJ1Y3Qgd2lsbCBoYXZlIGFuIGFub255bW91cyBuYW1lLiAgRmlsbCB0aGF0IG5hbWUgaW4gbm93LgoJIE5vdGhpbmcgY2FuIHJlZmVyIHRvIGl0LCBzbyBub3RoaW5nIG5lZWRzIGtub3cgYWJvdXQgdGhlIG5hbWUKCSBjaGFuZ2UuICAqLwogICAgICBpZiAodHlwZSAhPSBlcnJvcl9tYXJrX25vZGUKCSAgJiYgdW5xdWFsaWZpZWRfaWQKCSAgJiYgVFlQRV9OQU1FICh0eXBlKQoJICAmJiBUUkVFX0NPREUgKFRZUEVfTkFNRSAodHlwZSkpID09IFRZUEVfREVDTAoJICAmJiBUWVBFX0FOT05ZTU9VU19QICh0eXBlKQoJICAvKiBEb24ndCBkbyB0aGlzIGlmIHRoZXJlIGFyZSBhdHRyaWJ1dGVzLiAgKi8KCSAgJiYgKCFhdHRybGlzdCB8fCAhKmF0dHJsaXN0KQoJICAmJiBjcF90eXBlX3F1YWxzICh0eXBlKSA9PSBUWVBFX1VOUVVBTElGSUVEKQoJewoJICB0cmVlIG9sZG5hbWUgPSBUWVBFX05BTUUgKHR5cGUpOwoJICB0cmVlIHQ7CgoJICAvKiBSZXBsYWNlIHRoZSBhbm9ueW1vdXMgbmFtZSB3aXRoIHRoZSByZWFsIG5hbWUgZXZlcnl3aGVyZS4gICovCgkgIGZvciAodCA9IFRZUEVfTUFJTl9WQVJJQU5UICh0eXBlKTsgdDsgdCA9IFRZUEVfTkVYVF9WQVJJQU5UICh0KSkKCSAgICBpZiAoVFlQRV9OQU1FICh0KSA9PSBvbGRuYW1lKQoJICAgICAgVFlQRV9OQU1FICh0KSA9IGRlY2w7CgoJICBpZiAoVFlQRV9MQU5HX1NQRUNJRklDICh0eXBlKSkKCSAgICBUWVBFX1dBU19BTk9OWU1PVVMgKHR5cGUpID0gMTsKCgkgIC8qIElmIHRoaXMgaXMgYSB0eXBlZGVmIHdpdGhpbiBhIHRlbXBsYXRlIGNsYXNzLCB0aGUgbmVzdGVkCgkgICAgIHR5cGUgaXMgYSAobm9uLXByaW1hcnkpIHRlbXBsYXRlLiAgVGhlIG5hbWUgZm9yIHRoZQoJICAgICB0ZW1wbGF0ZSBuZWVkcyB1cGRhdGluZyBhcyB3ZWxsLiAgKi8KCSAgaWYgKFRZUEVfTEFOR19TUEVDSUZJQyAodHlwZSkgJiYgQ0xBU1NUWVBFX1RFTVBMQVRFX0lORk8gKHR5cGUpKQoJICAgIERFQ0xfTkFNRSAoQ0xBU1NUWVBFX1RJX1RFTVBMQVRFICh0eXBlKSkKCSAgICAgID0gVFlQRV9JREVOVElGSUVSICh0eXBlKTsKCgkgIC8qIEZJWE1FIHJlbWFuZ2xlIG1lbWJlciBmdW5jdGlvbnM7IG1lbWJlciBmdW5jdGlvbnMgb2YgYQoJICAgICB0eXBlIHdpdGggZXh0ZXJuYWwgbGlua2FnZSBoYXZlIGV4dGVybmFsIGxpbmthZ2UuICAqLwoJfQoKICAgICAgaWYgKHF1YWxzKQoJewoJICBpZiAoY3R5cGUgPT0gTlVMTF9UUkVFKQoJICAgIHsKICAgICAgICAgICAgICBpZiAoVFJFRV9DT0RFICh0eXBlKSA9PSBNRVRIT0RfVFlQRSkKCQljdHlwZSA9IFRZUEVfTUVUSE9EX0JBU0VUWVBFICh0eXBlKTsKICAgICAgICAgICAgICAvKiBBbnkgcXVhbGlmaWVycyBvbiBhIGZ1bmN0aW9uIHR5cGUgdHlwZWRlZiBoYXZlCiAgICAgICAgICAgICAgICAgYWxyZWFkeSBiZWVuIGRlYWx0IHdpdGguICovCiAgICAgICAgICAgICAgZWxzZSBpZiAoVFJFRV9DT0RFICh0eXBlKSA9PSBGVU5DVElPTl9UWVBFKQogICAgICAgICAgICAgICAgcXVhbHMgPSBUWVBFX1VOUVVBTElGSUVEOwoJICAgIH0KCSAgaWYgKGN0eXBlICE9IE5VTExfVFJFRSkKCSAgICBncm9rX21ldGhvZF9xdWFscyAoY3R5cGUsIGRlY2wsIHF1YWxzKTsKCX0KCiAgICAgIGlmIChzaWduZWRfcAoJICB8fCAodHlwZWRlZl9kZWNsICYmIENfVFlQRURFRl9FWFBMSUNJVExZX1NJR05FRCAodHlwZWRlZl9kZWNsKSkpCglDX1RZUEVERUZfRVhQTElDSVRMWV9TSUdORUQgKGRlY2wpID0gMTsKCiAgICAgIGJhZF9zcGVjaWZpZXJzIChkZWNsLCAidHlwZSIsIHZpcnR1YWxwLCBxdWFscyAhPSBUWVBFX1VOUVVBTElGSUVELAoJCSAgICAgIGlubGluZXAsIGZyaWVuZHAsIHJhaXNlcyAhPSBOVUxMX1RSRUUpOwoKICAgICAgcmV0dXJuIGRlY2w7CiAgICB9CgogIC8qIERldGVjdCB0aGUgY2FzZSBvZiBhbiBhcnJheSB0eXBlIG9mIHVuc3BlY2lmaWVkIHNpemUKICAgICB3aGljaCBjYW1lLCBhcyBzdWNoLCBkaXJlY3QgZnJvbSBhIHR5cGVkZWYgbmFtZS4KICAgICBXZSBtdXN0IGNvcHkgdGhlIHR5cGUsIHNvIHRoYXQgdGhlIGFycmF5J3MgZG9tYWluIGNhbiBiZQogICAgIGluZGl2aWR1YWxseSBzZXQgYnkgdGhlIG9iamVjdCdzIGluaXRpYWxpemVyLiAgKi8KCiAgaWYgKHR5cGUgJiYgdHlwZWRlZl90eXBlCiAgICAgICYmIFRSRUVfQ09ERSAodHlwZSkgPT0gQVJSQVlfVFlQRSAmJiAhVFlQRV9ET01BSU4gKHR5cGUpCiAgICAgICYmIFRZUEVfTUFJTl9WQVJJQU5UICh0eXBlKSA9PSBUWVBFX01BSU5fVkFSSUFOVCAodHlwZWRlZl90eXBlKSkKICAgIHR5cGUgPSBidWlsZF9jcGx1c19hcnJheV90eXBlIChUUkVFX1RZUEUgKHR5cGUpLCBOVUxMX1RSRUUpOwoKICAvKiBEZXRlY3Qgd2hlcmUgd2UncmUgdXNpbmcgYSB0eXBlZGVmIG9mIGZ1bmN0aW9uIHR5cGUgdG8gZGVjbGFyZSBhCiAgICAgZnVuY3Rpb24uIFBBUk1TIHdpbGwgbm90IGJlIHNldCwgc28gd2UgbXVzdCBjcmVhdGUgaXQgbm93LiAgKi8KCiAgaWYgKHR5cGUgPT0gdHlwZWRlZl90eXBlICYmIFRSRUVfQ09ERSAodHlwZSkgPT0gRlVOQ1RJT05fVFlQRSkKICAgIHsKICAgICAgdHJlZSBkZWNscyA9IE5VTExfVFJFRTsKICAgICAgdHJlZSBhcmdzOwoKICAgICAgZm9yIChhcmdzID0gVFlQRV9BUkdfVFlQRVMgKHR5cGUpOyBhcmdzOyBhcmdzID0gVFJFRV9DSEFJTiAoYXJncykpCgl7CgkgIHRyZWUgZGVjbCA9IGNwX2J1aWxkX3Bhcm1fZGVjbCAoTlVMTF9UUkVFLCBUUkVFX1ZBTFVFIChhcmdzKSk7CgoJICBUUkVFX0NIQUlOIChkZWNsKSA9IGRlY2xzOwoJICBkZWNscyA9IGRlY2w7Cgl9CgogICAgICBwYXJtcyA9IG5yZXZlcnNlIChkZWNscyk7CgogICAgICBpZiAoZGVjbF9jb250ZXh0ICE9IFRZUEVOQU1FKQogICAgICAgIHsKICAgICAgICAgIC8qIEEgY3YtcXVhbGlmaWVyLXNlcSBzaGFsbCBvbmx5IGJlIHBhcnQgb2YgdGhlIGZ1bmN0aW9uIHR5cGUKICAgICAgICAgICAgIGZvciBhIG5vbi1zdGF0aWMgbWVtYmVyIGZ1bmN0aW9uLiBbOC4zLjUvNCBkY2wuZmN0XSAqLyAKICAgICAgICAgIGlmIChjcF90eXBlX3F1YWxzICh0eXBlKSAhPSBUWVBFX1VOUVVBTElGSUVECiAgICAgICAgICAgICAgJiYgKGN1cnJlbnRfY2xhc3NfdHlwZSA9PSBOVUxMX1RSRUUgfHwgc3RhdGljcCkgKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgZXJyb3IgKCJxdWFsaWZpZWQgZnVuY3Rpb24gdHlwZXMgY2Fubm90IGJlIHVzZWQgdG8gZGVjbGFyZSAlcyBmdW5jdGlvbnMiLAogICAgICAgICAgICAgICAgICAgICAoc3RhdGljcD8gInN0YXRpYyBtZW1iZXIiIDogImZyZWUiKSk7CiAgICAgICAgICAgICAgdHlwZSA9IFRZUEVfTUFJTl9WQVJJQU5UICh0eXBlKTsKICAgICAgICAgICAgfQogICAgICAgICAgCiAgICAgICAgICAvKiBUaGUgcXVhbGlmaWVycyBvbiB0aGUgZnVuY3Rpb24gdHlwZSBiZWNvbWUgdGhlIHF1YWxpZmllcnMgb24KICAgICAgICAgICAgIHRoZSBub24tc3RhdGljIG1lbWJlciBmdW5jdGlvbi4gKi8KICAgICAgICAgIHF1YWxzIHw9IGNwX3R5cGVfcXVhbHMgKHR5cGUpOwogICAgICAgIH0KICAgIH0KCiAgLyogSWYgdGhpcyBpcyBhIHR5cGUgbmFtZSAoc3VjaCBhcywgaW4gYSBjYXN0IG9yIHNpemVvZiksCiAgICAgY29tcHV0ZSB0aGUgdHlwZSBhbmQgcmV0dXJuIGl0IG5vdy4gICovCgogIGlmIChkZWNsX2NvbnRleHQgPT0gVFlQRU5BTUUpCiAgICB7CiAgICAgIC8qIE5vdGUgdGhhdCB0aGUgZ3JhbW1hciByZWplY3RzIHN0b3JhZ2UgY2xhc3NlcwoJIGluIHR5cGVuYW1lcywgZmllbGRzIG9yIHBhcmFtZXRlcnMuICAqLwogICAgICBpZiAodHlwZV9xdWFscyAhPSBUWVBFX1VOUVVBTElGSUVEKQoJdHlwZV9xdWFscyA9IFRZUEVfVU5RVUFMSUZJRUQ7CgogICAgICAvKiBTcGVjaWFsIGNhc2U6ICJmcmllbmQgY2xhc3MgZm9vIiBsb29rcyBsaWtlIGEgVFlQRU5BTUUgY29udGV4dC4gICovCiAgICAgIGlmIChmcmllbmRwKQoJewoJICBpZiAodHlwZV9xdWFscyAhPSBUWVBFX1VOUVVBTElGSUVEKQoJICAgIHsKCSAgICAgIGVycm9yICgidHlwZSBxdWFsaWZpZXJzIHNwZWNpZmllZCBmb3IgZnJpZW5kIGNsYXNzIGRlY2xhcmF0aW9uIik7CgkgICAgICB0eXBlX3F1YWxzID0gVFlQRV9VTlFVQUxJRklFRDsKCSAgICB9CgkgIGlmIChpbmxpbmVwKQoJICAgIHsKCSAgICAgIGVycm9yICgiJTxpbmxpbmUlPiBzcGVjaWZpZWQgZm9yIGZyaWVuZCBjbGFzcyBkZWNsYXJhdGlvbiIpOwoJICAgICAgaW5saW5lcCA9IDA7CgkgICAgfQoKCSAgaWYgKCFjdXJyZW50X2FnZ3IpCgkgICAgewoJICAgICAgLyogRG9uJ3QgYWxsb3cgZnJpZW5kIGRlY2xhcmF0aW9uIHdpdGhvdXQgYSBjbGFzcy1rZXkuICAqLwoJICAgICAgaWYgKFRSRUVfQ09ERSAodHlwZSkgPT0gVEVNUExBVEVfVFlQRV9QQVJNKQoJCXBlZHdhcm4gKCJ0ZW1wbGF0ZSBwYXJhbWV0ZXJzIGNhbm5vdCBiZSBmcmllbmRzIik7CgkgICAgICBlbHNlIGlmIChUUkVFX0NPREUgKHR5cGUpID09IFRZUEVOQU1FX1RZUEUpCgkgICAgICAgIHBlZHdhcm4gKCJmcmllbmQgZGVjbGFyYXRpb24gcmVxdWlyZXMgY2xhc3Mta2V5LCAiCgkJCSAiaS5lLiAlPGZyaWVuZCBjbGFzcyAlVDo6JUQlPiIsCgkJCSBUWVBFX0NPTlRFWFQgKHR5cGUpLCBUWVBFTkFNRV9UWVBFX0ZVTExOQU1FICh0eXBlKSk7CgkgICAgICBlbHNlCgkgICAgICAgIHBlZHdhcm4gKCJmcmllbmQgZGVjbGFyYXRpb24gcmVxdWlyZXMgY2xhc3Mta2V5LCAiCgkJCSAiaS5lLiAlPGZyaWVuZCAlI1QlPiIsCgkJCSB0eXBlKTsKCSAgICB9CgoJICAvKiBPbmx5IHRyeSB0byBkbyB0aGlzIHN0dWZmIGlmIHdlIGRpZG4ndCBhbHJlYWR5IGdpdmUgdXAuICAqLwoJICBpZiAodHlwZSAhPSBpbnRlZ2VyX3R5cGVfbm9kZSkKCSAgICB7CgkgICAgICAvKiBBIGZyaWVuZGx5IGNsYXNzPyAgKi8KCSAgICAgIGlmIChjdXJyZW50X2NsYXNzX3R5cGUpCgkJbWFrZV9mcmllbmRfY2xhc3MgKGN1cnJlbnRfY2xhc3NfdHlwZSwgVFlQRV9NQUlOX1ZBUklBTlQgKHR5cGUpLAoJCQkJICAgLypjb21wbGFpbj0qL3RydWUpOwoJICAgICAgZWxzZQoJCWVycm9yICgidHJ5aW5nIHRvIG1ha2UgY2xhc3MgJXFUIGEgZnJpZW5kIG9mIGdsb2JhbCBzY29wZSIsCiAgICAgICAgICAgICAgICAgICAgICAgdHlwZSk7CgoJICAgICAgdHlwZSA9IHZvaWRfdHlwZV9ub2RlOwoJICAgIH0KCX0KICAgICAgZWxzZSBpZiAocXVhbHMpCgl7CgkgIGlmIChjdHlwZSA9PSBOVUxMX1RSRUUpCgkgICAgewoJICAgICAgaWYgKFRSRUVfQ09ERSAodHlwZSkgIT0gTUVUSE9EX1RZUEUpCgkgICAgICAgIGVycm9yICgiaW52YWxpZCBxdWFsaWZpZXJzIG9uIG5vbi1tZW1iZXIgZnVuY3Rpb24gdHlwZSIpOwoJICAgICAgZWxzZQoJICAgICAgICBjdHlwZSA9IFRZUEVfTUVUSE9EX0JBU0VUWVBFICh0eXBlKTsKCSAgICB9CgkgIGlmIChjdHlwZSkKCSAgICB7CgkgICAgICB0cmVlIGR1bW15ID0gYnVpbGRfZGVjbCAoVFlQRV9ERUNMLCB1bnF1YWxpZmllZF9pZCwgdHlwZSk7CgkgICAgICBncm9rX21ldGhvZF9xdWFscyAoY3R5cGUsIGR1bW15LCBxdWFscyk7CgkgICAgICB0eXBlID0gVFJFRV9UWVBFIChkdW1teSk7CgkgICAgfQoJfQoKICAgICAgcmV0dXJuIHR5cGU7CiAgICB9CiAgZWxzZSBpZiAodW5xdWFsaWZpZWRfaWQgPT0gTlVMTF9UUkVFICYmIGRlY2xfY29udGV4dCAhPSBQQVJNCgkgICAmJiBkZWNsX2NvbnRleHQgIT0gQ0FUQ0hQQVJNCgkgICAmJiBUUkVFX0NPREUgKHR5cGUpICE9IFVOSU9OX1RZUEUKCSAgICYmICEgYml0ZmllbGQpCiAgICB7CiAgICAgIGVycm9yICgiYWJzdHJhY3QgZGVjbGFyYXRvciAlcVQgdXNlZCBhcyBkZWNsYXJhdGlvbiIsIHR5cGUpOwogICAgICByZXR1cm4gZXJyb3JfbWFya19ub2RlOwogICAgfQoKICAvKiBPbmx5IGZ1bmN0aW9ucyBtYXkgYmUgZGVjbGFyZWQgdXNpbmcgYW4gb3BlcmF0b3ItZnVuY3Rpb24taWQuICAqLwogIGlmICh1bnF1YWxpZmllZF9pZAogICAgICAmJiBJREVOVElGSUVSX09QTkFNRV9QICh1bnF1YWxpZmllZF9pZCkKICAgICAgJiYgVFJFRV9DT0RFICh0eXBlKSAhPSBGVU5DVElPTl9UWVBFCiAgICAgICYmIFRSRUVfQ09ERSAodHlwZSkgIT0gTUVUSE9EX1RZUEUpCiAgICB7CiAgICAgIGVycm9yICgiZGVjbGFyYXRpb24gb2YgJXFEIGFzIG5vbi1mdW5jdGlvbiIsIHVucXVhbGlmaWVkX2lkKTsKICAgICAgcmV0dXJuIGVycm9yX21hcmtfbm9kZTsKICAgIH0KCiAgLyogV2UgZG9uJ3QgY2hlY2sgcGFyYW1ldGVyIHR5cGVzIGhlcmUgYmVjYXVzZSB3ZSBjYW4gZW1pdCBhIGJldHRlcgogICAgIGVycm9yIG1lc3NhZ2UgbGF0ZXIuICAqLwogIGlmIChkZWNsX2NvbnRleHQgIT0gUEFSTSkKICAgIHR5cGUgPSBjaGVja192YXJfdHlwZSAodW5xdWFsaWZpZWRfaWQsIHR5cGUpOwoKICAvKiBOb3cgY3JlYXRlIHRoZSBkZWNsLCB3aGljaCBtYXkgYmUgYSBWQVJfREVDTCwgYSBQQVJNX0RFQ0wKICAgICBvciBhIEZVTkNUSU9OX0RFQ0wsIGRlcGVuZGluZyBvbiBERUNMX0NPTlRFWFQgYW5kIFRZUEUuICAqLwoKICBpZiAoZGVjbF9jb250ZXh0ID09IFBBUk0gfHwgZGVjbF9jb250ZXh0ID09IENBVENIUEFSTSkKICAgIHsKICAgICAgaWYgKGN0eXBlIHx8IGluX25hbWVzcGFjZSkKCWVycm9yICgiY2Fubm90IHVzZSAlPDo6JT4gaW4gcGFyYW1ldGVyIGRlY2xhcmF0aW9uIik7CgogICAgICAvKiBBIHBhcmFtZXRlciBkZWNsYXJlZCBhcyBhbiBhcnJheSBvZiBUIGlzIHJlYWxseSBhIHBvaW50ZXIgdG8gVC4KCSBPbmUgZGVjbGFyZWQgYXMgYSBmdW5jdGlvbiBpcyByZWFsbHkgYSBwb2ludGVyIHRvIGEgZnVuY3Rpb24uCgkgT25lIGRlY2xhcmVkIGFzIGEgbWVtYmVyIGlzIHJlYWxseSBhIHBvaW50ZXIgdG8gbWVtYmVyLiAgKi8KCiAgICAgIGlmIChUUkVFX0NPREUgKHR5cGUpID09IEFSUkFZX1RZUEUpCgl7CgkgIC8qIFRyYW5zZmVyIGNvbnN0LW5lc3Mgb2YgYXJyYXkgaW50byB0aGF0IG9mIHR5cGUgcG9pbnRlZCB0by4gICovCgkgIHR5cGUgPSBidWlsZF9wb2ludGVyX3R5cGUgKFRSRUVfVFlQRSAodHlwZSkpOwoJICB0eXBlX3F1YWxzID0gVFlQRV9VTlFVQUxJRklFRDsKCX0KICAgICAgZWxzZSBpZiAoVFJFRV9DT0RFICh0eXBlKSA9PSBGVU5DVElPTl9UWVBFKQoJdHlwZSA9IGJ1aWxkX3BvaW50ZXJfdHlwZSAodHlwZSk7CiAgICB9CgogIHsKICAgIHRyZWUgZGVjbDsKCiAgICBpZiAoZGVjbF9jb250ZXh0ID09IFBBUk0pCiAgICAgIHsKCWRlY2wgPSBjcF9idWlsZF9wYXJtX2RlY2wgKHVucXVhbGlmaWVkX2lkLCB0eXBlKTsKCgliYWRfc3BlY2lmaWVycyAoZGVjbCwgInBhcmFtZXRlciIsIHZpcnR1YWxwLCBxdWFscyAhPSBUWVBFX1VOUVVBTElGSUVELAoJCQlpbmxpbmVwLCBmcmllbmRwLCByYWlzZXMgIT0gTlVMTF9UUkVFKTsKICAgICAgfQogICAgZWxzZSBpZiAoZGVjbF9jb250ZXh0ID09IEZJRUxEKQogICAgICB7CgkvKiBUaGUgQzk5IGZsZXhpYmxlIGFycmF5IGV4dGVuc2lvbi4gICovCglpZiAoIXN0YXRpY3AgJiYgVFJFRV9DT0RFICh0eXBlKSA9PSBBUlJBWV9UWVBFCgkgICAgJiYgVFlQRV9ET01BSU4gKHR5cGUpID09IE5VTExfVFJFRSkKCSAgewoJICAgIHRyZWUgaXR5cGUgPSBjb21wdXRlX2FycmF5X2luZGV4X3R5cGUgKGRuYW1lLCBpbnRlZ2VyX3plcm9fbm9kZSk7CgkgICAgdHlwZSA9IGJ1aWxkX2NwbHVzX2FycmF5X3R5cGUgKFRSRUVfVFlQRSAodHlwZSksIGl0eXBlKTsKCSAgfQoKCWlmICh0eXBlID09IGVycm9yX21hcmtfbm9kZSkKCSAgewoJICAgIC8qIEhhcHBlbnMgd2hlbiBkZWNsYXJpbmcgYXJyYXlzIG9mIHNpemVzIHdoaWNoCgkgICAgICAgYXJlIGVycm9yX21hcmtfbm9kZSwgZm9yIGV4YW1wbGUuICAqLwoJICAgIGRlY2wgPSBOVUxMX1RSRUU7CgkgIH0KCWVsc2UgaWYgKGluX25hbWVzcGFjZSAmJiAhZnJpZW5kcCkKCSAgewoJICAgIC8qIFNvbWV0aGluZyBsaWtlIHN0cnVjdCBTIHsgaW50IE46Omo7IH07ICAqLwoJICAgIGVycm9yICgiaW52YWxpZCB1c2Ugb2YgJTw6OiU+Iik7CgkgICAgZGVjbCA9IE5VTExfVFJFRTsKCSAgfQoJZWxzZSBpZiAoVFJFRV9DT0RFICh0eXBlKSA9PSBGVU5DVElPTl9UWVBFKQoJICB7CgkgICAgaW50IHB1YmxpY3AgPSAwOwoJICAgIHRyZWUgZnVuY3Rpb25fY29udGV4dDsKCgkgICAgaWYgKGZyaWVuZHAgPT0gMCkKCSAgICAgIHsKCQlpZiAoY3R5cGUgPT0gTlVMTF9UUkVFKQoJCSAgY3R5cGUgPSBjdXJyZW50X2NsYXNzX3R5cGU7CgoJCWlmIChjdHlwZSA9PSBOVUxMX1RSRUUpCgkJICB7CgkJICAgIGVycm9yICgiY2FuJ3QgbWFrZSAlcUQgaW50byBhIG1ldGhvZCAtLSBub3QgaW4gYSBjbGFzcyIsCgkJCSAgIHVucXVhbGlmaWVkX2lkKTsKCQkgICAgcmV0dXJuIHZvaWRfdHlwZV9ub2RlOwoJCSAgfQoKCQkvKiBgYEEgdW5pb24gbWF5IFsgLi4uIF0gbm90IFsgaGF2ZSBdIHZpcnR1YWwgZnVuY3Rpb25zLicnCgkJICAgQVJNIDkuNSAqLwoJCWlmICh2aXJ0dWFscCAmJiBUUkVFX0NPREUgKGN0eXBlKSA9PSBVTklPTl9UWVBFKQoJCSAgewoJCSAgICBlcnJvciAoImZ1bmN0aW9uICVxRCBkZWNsYXJlZCB2aXJ0dWFsIGluc2lkZSBhIHVuaW9uIiwKCQkJICAgdW5xdWFsaWZpZWRfaWQpOwoJCSAgICByZXR1cm4gdm9pZF90eXBlX25vZGU7CgkJICB9CgoJCWlmIChORVdfREVMRVRFX09QTkFNRV9QICh1bnF1YWxpZmllZF9pZCkpCgkJICB7CgkJICAgIGlmICh2aXJ0dWFscCkKCQkgICAgICB7CgkJCWVycm9yICgiJXFEIGNhbm5vdCBiZSBkZWNsYXJlZCB2aXJ0dWFsLCBzaW5jZSBpdCAiCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiaXMgYWx3YXlzIHN0YXRpYyIsCgkJCSAgICAgICB1bnF1YWxpZmllZF9pZCk7CgkJCXZpcnR1YWxwID0gMDsKCQkgICAgICB9CgkJICB9CgkJZWxzZSBpZiAoc3RhdGljcCA8IDIpCgkJICB0eXBlID0gYnVpbGRfbWV0aG9kX3R5cGVfZGlyZWN0bHkgKGN0eXBlLAoJCQkJCQkgICAgIFRSRUVfVFlQRSAodHlwZSksCgkJCQkJCSAgICAgVFlQRV9BUkdfVFlQRVMgKHR5cGUpKTsKCSAgICAgIH0KCgkgICAgLyogQ2hlY2sgdGhhdCB0aGUgbmFtZSB1c2VkIGZvciBhIGRlc3RydWN0b3IgbWFrZXMgc2Vuc2UuICAqLwoJICAgIGlmIChzZmsgPT0gc2ZrX2Rlc3RydWN0b3IKCQkmJiAhc2FtZV90eXBlX3AgKFRSRUVfT1BFUkFORCAKCQkJCSAoaWRfZGVjbGFyYXRvci0+dS5pZC51bnF1YWxpZmllZF9uYW1lLCAwKSwKCQkJCSBjdHlwZSkpCgkgICAgICB7CgkJZXJyb3IgKCJkZWNsYXJhdGlvbiBvZiAlcUQgYXMgbWVtYmVyIG9mICVxVCIsIAoJCSAgICAgICBpZF9kZWNsYXJhdG9yLT51LmlkLnVucXVhbGlmaWVkX25hbWUsCgkJICAgICAgIGN0eXBlKTsKCQlyZXR1cm4gZXJyb3JfbWFya19ub2RlOwoJICAgICAgfQoKCSAgICAvKiBUZWxsIGdyb2tmbmRlY2wgaWYgaXQgbmVlZHMgdG8gc2V0IFRSRUVfUFVCTElDIG9uIHRoZSBub2RlLiAgKi8KCSAgICBmdW5jdGlvbl9jb250ZXh0ID0gKGN0eXBlICE9IE5VTExfVFJFRSkgPwoJICAgICAgZGVjbF9mdW5jdGlvbl9jb250ZXh0IChUWVBFX01BSU5fREVDTCAoY3R5cGUpKSA6IE5VTExfVFJFRTsKCSAgICBwdWJsaWNwID0gKCEgZnJpZW5kcCB8fCAhIHN0YXRpY3ApCgkgICAgICAmJiBmdW5jdGlvbl9jb250ZXh0ID09IE5VTExfVFJFRTsKCSAgICBkZWNsID0gZ3Jva2ZuZGVjbCAoY3R5cGUsIHR5cGUsCgkJCSAgICAgICBUUkVFX0NPREUgKHVucXVhbGlmaWVkX2lkKSAhPSBURU1QTEFURV9JRF9FWFBSCgkJCSAgICAgICA/IHVucXVhbGlmaWVkX2lkIDogZG5hbWUsCgkJCSAgICAgICBwYXJtcywKCQkJICAgICAgIHVucXVhbGlmaWVkX2lkLAoJCQkgICAgICAgdmlydHVhbHAsIGZsYWdzLCBxdWFscywgcmFpc2VzLAoJCQkgICAgICAgZnJpZW5kcCA/IC0xIDogMCwgZnJpZW5kcCwgcHVibGljcCwgaW5saW5lcCwKCQkJICAgICAgIHNmaywKCQkJICAgICAgIGZ1bmNkZWZfZmxhZywgdGVtcGxhdGVfY291bnQsIGluX25hbWVzcGFjZSwgYXR0cmxpc3QpOwoJICAgIGlmIChkZWNsID09IE5VTExfVFJFRSkKCSAgICAgIHJldHVybiBkZWNsOwojaWYgMAoJICAgIC8qIFRoaXMgY2xvYmJlcnMgdGhlIGF0dHJzIHN0b3JlZCBpbiBgZGVjbCcgZnJvbSBgYXR0cmxpc3QnLiAgKi8KCSAgICAvKiBUaGUgZGVjbCBhbmQgc2V0dGluZyBvZiBkZWNsX2F0dHIgaXMgYWxzbyB0dXJuZWQgb2ZmLiAgKi8KCSAgICBkZWNsID0gYnVpbGRfZGVjbF9hdHRyaWJ1dGVfdmFyaWFudCAoZGVjbCwgZGVjbF9hdHRyKTsKI2VuZGlmCgoJICAgIC8qIFtjbGFzcy5jb252LmN0b3JdCgoJICAgICAgIEEgY29uc3RydWN0b3IgZGVjbGFyZWQgd2l0aG91dCB0aGUgZnVuY3Rpb24tc3BlY2lmaWVyCgkgICAgICAgZXhwbGljaXQgdGhhdCBjYW4gYmUgY2FsbGVkIHdpdGggYSBzaW5nbGUgcGFyYW1ldGVyCgkgICAgICAgc3BlY2lmaWVzIGEgY29udmVyc2lvbiBmcm9tIHRoZSB0eXBlIG9mIGl0cyBmaXJzdAoJICAgICAgIHBhcmFtZXRlciB0byB0aGUgdHlwZSBvZiBpdHMgY2xhc3MuICBTdWNoIGEgY29uc3RydWN0b3IKCSAgICAgICBpcyBjYWxsZWQgYSBjb252ZXJ0aW5nIGNvbnN0cnVjdG9yLiAgKi8KCSAgICBpZiAoZXhwbGljaXRwID09IDIpCgkgICAgICBERUNMX05PTkNPTlZFUlRJTkdfUCAoZGVjbCkgPSAxOwoJICAgIGVsc2UgaWYgKERFQ0xfQ09OU1RSVUNUT1JfUCAoZGVjbCkpCgkgICAgICB7CgkJLyogVGhlIGNvbnN0cnVjdG9yIGNhbiBiZSBjYWxsZWQgd2l0aCBleGFjdGx5IG9uZQoJCSAgIHBhcmFtZXRlciBpZiB0aGVyZSBpcyBhdCBsZWFzdCBvbmUgcGFyYW1ldGVyLCBhbmQKCQkgICBhbnkgc3Vic2VxdWVudCBwYXJhbWV0ZXJzIGhhdmUgZGVmYXVsdCBhcmd1bWVudHMuCgkJICAgSWdub3JlIGFueSBjb21waWxlci1hZGRlZCBwYXJtcy4gICovCgkJdHJlZSBhcmdfdHlwZXMgPSBGVU5DVElPTl9GSVJTVF9VU0VSX1BBUk1UWVBFIChkZWNsKTsKCgkJaWYgKGFyZ190eXBlcyA9PSB2b2lkX2xpc3Rfbm9kZQoJCSAgICB8fCAoYXJnX3R5cGVzCgkJCSYmIFRSRUVfQ0hBSU4gKGFyZ190eXBlcykKCQkJJiYgVFJFRV9DSEFJTiAoYXJnX3R5cGVzKSAhPSB2b2lkX2xpc3Rfbm9kZQoJCQkmJiAhVFJFRV9QVVJQT1NFIChUUkVFX0NIQUlOIChhcmdfdHlwZXMpKSkpCgkJICBERUNMX05PTkNPTlZFUlRJTkdfUCAoZGVjbCkgPSAxOwoJICAgICAgfQoJICB9CgllbHNlIGlmIChUUkVFX0NPREUgKHR5cGUpID09IE1FVEhPRF9UWVBFKQoJICB7CgkgICAgLyogV2Ugb25seSBnZXQgaGVyZSBmb3IgZnJpZW5kIGRlY2xhcmF0aW9ucyBvZgoJICAgICAgIG1lbWJlcnMgb2Ygb3RoZXIgY2xhc3Nlcy4gICovCgkgICAgLyogQWxsIG1ldGhvZCBkZWNscyBhcmUgcHVibGljLCBzbyB0ZWxsIGdyb2tmbmRlY2wgdG8gc2V0CgkgICAgICAgVFJFRV9QVUJMSUMsIGFsc28uICAqLwoJICAgIGRlY2wgPSBncm9rZm5kZWNsIChjdHlwZSwgdHlwZSwKCQkJICAgICAgIFRSRUVfQ09ERSAodW5xdWFsaWZpZWRfaWQpICE9IFRFTVBMQVRFX0lEX0VYUFIKCQkJICAgICAgID8gdW5xdWFsaWZpZWRfaWQgOiBkbmFtZSwKCQkJICAgICAgIHBhcm1zLAoJCQkgICAgICAgdW5xdWFsaWZpZWRfaWQsCgkJCSAgICAgICB2aXJ0dWFscCwgZmxhZ3MsIHF1YWxzLCByYWlzZXMsCgkJCSAgICAgICBmcmllbmRwID8gLTEgOiAwLCBmcmllbmRwLCAxLCAwLCBzZmssCgkJCSAgICAgICBmdW5jZGVmX2ZsYWcsIHRlbXBsYXRlX2NvdW50LCBpbl9uYW1lc3BhY2UsIAoJCQkgICAgICAgYXR0cmxpc3QpOyAKCSAgICBpZiAoZGVjbCA9PSBOVUxMX1RSRUUpCgkgICAgICByZXR1cm4gTlVMTF9UUkVFOwoJICB9CgllbHNlIGlmICghc3RhdGljcCAmJiAhZGVwZW5kZW50X3R5cGVfcCAodHlwZSkKCQkgJiYgIUNPTVBMRVRFX1RZUEVfUCAoY29tcGxldGVfdHlwZSAodHlwZSkpCgkJICYmIChUUkVFX0NPREUgKHR5cGUpICE9IEFSUkFZX1RZUEUgfHwgaW5pdGlhbGl6ZWQgPT0gMCkpCgkgIHsKCSAgICBpZiAodW5xdWFsaWZpZWRfaWQpCgkgICAgICBlcnJvciAoImZpZWxkICVxRCBoYXMgaW5jb21wbGV0ZSB0eXBlIiwgdW5xdWFsaWZpZWRfaWQpOwoJICAgIGVsc2UKCSAgICAgIGVycm9yICgibmFtZSAlcVQgaGFzIGluY29tcGxldGUgdHlwZSIsIHR5cGUpOwoKCSAgICAvKiBJZiB3ZSdyZSBpbnN0YW50aWF0aW5nIGEgdGVtcGxhdGUsIHRlbGwgdGhlbSB3aGljaAoJICAgICAgIGluc3RhbnRpYXRpb24gbWFkZSB0aGUgZmllbGQncyB0eXBlIGJlIGluY29tcGxldGUuICAqLwoJICAgIGlmIChjdXJyZW50X2NsYXNzX3R5cGUKCQkmJiBUWVBFX05BTUUgKGN1cnJlbnRfY2xhc3NfdHlwZSkKCQkmJiBJREVOVElGSUVSX1RFTVBMQVRFIChUWVBFX0lERU5USUZJRVIgKGN1cnJlbnRfY2xhc3NfdHlwZSkpCgkJJiYgZGVjbHNwZWNzLT50eXBlCgkJJiYgZGVjbHNwZWNzLT50eXBlID09IHR5cGUpCgkgICAgICBlcnJvciAoIiAgaW4gaW5zdGFudGlhdGlvbiBvZiB0ZW1wbGF0ZSAlcVQiLAogICAgICAgICAgICAgICAgICAgICBjdXJyZW50X2NsYXNzX3R5cGUpOwoKCSAgICB0eXBlID0gZXJyb3JfbWFya19ub2RlOwoJICAgIGRlY2wgPSBOVUxMX1RSRUU7CgkgIH0KCWVsc2UKCSAgewoJICAgIGlmIChmcmllbmRwKQoJICAgICAgewoJCWVycm9yICgiJXFFIGlzIG5laXRoZXIgZnVuY3Rpb24gbm9yIG1lbWJlciBmdW5jdGlvbjsgIgogICAgICAgICAgICAgICAgICAgICAgICJjYW5ub3QgYmUgZGVjbGFyZWQgZnJpZW5kIiwgdW5xdWFsaWZpZWRfaWQpOwoJCWZyaWVuZHAgPSAwOwoJICAgICAgfQoJICAgIGRlY2wgPSBOVUxMX1RSRUU7CgkgIH0KCglpZiAoZnJpZW5kcCkKCSAgewoJICAgIC8qIEZyaWVuZHMgYXJlIHRyZWF0ZWQgc3BlY2lhbGx5LiAgKi8KCSAgICBpZiAoY3R5cGUgPT0gY3VycmVudF9jbGFzc190eXBlKQoJICAgICAgd2FybmluZyAoIm1lbWJlciBmdW5jdGlvbnMgYXJlIGltcGxpY2l0bHkgZnJpZW5kcyBvZiB0aGVpciBjbGFzcyIpOwogCSAgICBlbHNlIGlmIChkZWNsICYmIERFQ0xfTkFNRSAoZGVjbCkpCgkgICAgICB7CgkJaWYgKHRlbXBsYXRlX2NsYXNzX2RlcHRoIChjdXJyZW50X2NsYXNzX3R5cGUpID09IDApCgkJICB7CgkJICAgIGRlY2wgPSBjaGVja19leHBsaWNpdF9zcGVjaWFsaXphdGlvbgoJCSAgICAgICh1bnF1YWxpZmllZF9pZCwgZGVjbCwgdGVtcGxhdGVfY291bnQsCgkJICAgICAgIDIgKiAoZnVuY2RlZl9mbGFnICE9IDApICsgNCk7CgkJICAgIGlmIChkZWNsID09IGVycm9yX21hcmtfbm9kZSkKCQkgICAgICByZXR1cm4gZXJyb3JfbWFya19ub2RlOwoJCSAgfQoKCQlkZWNsID0gZG9fZnJpZW5kIChjdHlwZSwgdW5xdWFsaWZpZWRfaWQsIGRlY2wsCgkJCQkgICphdHRybGlzdCwgZmxhZ3MsIHF1YWxzLCBmdW5jZGVmX2ZsYWcpOwoJCXJldHVybiBkZWNsOwoJICAgICAgfQoJICAgIGVsc2UKCSAgICAgIHJldHVybiB2b2lkX3R5cGVfbm9kZTsKCSAgfQoKCS8qIFN0cnVjdHVyZSBmaWVsZC4gIEl0IG1heSBub3QgYmUgYSBmdW5jdGlvbiwgZXhjZXB0IGZvciBDKysuICAqLwoKCWlmIChkZWNsID09IE5VTExfVFJFRSkKCSAgewoJICAgIGlmIChpbml0aWFsaXplZCkKCSAgICAgIHsKCQlpZiAoIXN0YXRpY3ApCgkJICB7CgkJICAgIC8qIEFuIGF0dGVtcHQgaXMgYmVpbmcgbWFkZSB0byBpbml0aWFsaXplIGEgbm9uLXN0YXRpYwoJCSAgICAgICBtZW1iZXIuICBCdXQsIGZyb20gW2NsYXNzLm1lbV06CgoJCSAgICAgICA0IEEgbWVtYmVyLWRlY2xhcmF0b3IgY2FuIGNvbnRhaW4gYQoJCSAgICAgICBjb25zdGFudC1pbml0aWFsaXplciBvbmx5IGlmIGl0IGRlY2xhcmVzIGEgc3RhdGljCgkJICAgICAgIG1lbWJlciAoX2NsYXNzLnN0YXRpY18pIG9mIGludGVncmFsIG9yIGVudW1lcmF0aW9uCgkJICAgICAgIHR5cGUsIHNlZSBfY2xhc3Muc3RhdGljLmRhdGFfLgoKCQkgICAgICAgVGhpcyB1c2VkIHRvIGJlIHJlbGF0aXZlbHkgY29tbW9uIHByYWN0aWNlLCBidXQKCQkgICAgICAgdGhlIHJlc3Qgb2YgdGhlIGNvbXBpbGVyIGRvZXMgbm90IGNvcnJlY3RseQoJCSAgICAgICBoYW5kbGUgdGhlIGluaXRpYWxpemF0aW9uIHVubGVzcyB0aGUgbWVtYmVyIGlzCgkJICAgICAgIHN0YXRpYyBzbyB3ZSBtYWtlIGl0IHN0YXRpYyBiZWxvdy4gICovCgkJICAgIHBlZHdhcm4gKCJJU08gQysrIGZvcmJpZHMgaW5pdGlhbGl6YXRpb24gb2YgbWVtYmVyICVxRCIsCgkJCSAgICAgdW5xdWFsaWZpZWRfaWQpOwoJCSAgICBwZWR3YXJuICgibWFraW5nICVxRCBzdGF0aWMiLCB1bnF1YWxpZmllZF9pZCk7CgkJICAgIHN0YXRpY3AgPSAxOwoJCSAgfQoKCQlpZiAodXNlc190ZW1wbGF0ZV9wYXJtcyAodHlwZSkpCgkJICAvKiBXZSdsbCBjaGVjayBhdCBpbnN0YW50aWF0aW9uIHRpbWUuICAqLwoJCSAgOwoJCWVsc2UgaWYgKGNoZWNrX3N0YXRpY192YXJpYWJsZV9kZWZpbml0aW9uICh1bnF1YWxpZmllZF9pZCwKCQkJCQkJCSAgIHR5cGUpKQoJCSAgLyogSWYgd2UganVzdCByZXR1cm4gdGhlIGRlY2xhcmF0aW9uLCBjcmFzaGVzCgkJICAgICB3aWxsIHNvbWV0aW1lcyBvY2N1ci4gIFdlIHRoZXJlZm9yZSByZXR1cm4KCQkgICAgIHZvaWRfdHlwZV9ub2RlLCBhcyBpZiB0aGlzIHdhcyBhIGZyaWVuZAoJCSAgICAgZGVjbGFyYXRpb24sIHRvIGNhdXNlIGNhbGxlcnMgdG8gY29tcGxldGVseQoJCSAgICAgaWdub3JlIHRoaXMgZGVjbGFyYXRpb24uICAqLwoJCSAgcmV0dXJuIHZvaWRfdHlwZV9ub2RlOwoJICAgICAgfQoKCSAgICBpZiAoc3RhdGljcCkKCSAgICAgIHsKCQkvKiBDKysgYWxsb3dzIHN0YXRpYyBjbGFzcyBtZW1iZXJzLiAgQWxsIG90aGVyIHdvcmsKCQkgICBmb3IgdGhpcyBpcyBkb25lIGJ5IGdyb2tmaWVsZC4gICovCgkJZGVjbCA9IGJ1aWxkX2xhbmdfZGVjbCAoVkFSX0RFQ0wsIHVucXVhbGlmaWVkX2lkLCB0eXBlKTsKCQlzZXRfbGlua2FnZV9mb3Jfc3RhdGljX2RhdGFfbWVtYmVyIChkZWNsKTsKCQkvKiBFdmVuIGlmIHRoZXJlIGlzIGFuIGluLWNsYXNzIGluaXRpYWxpemF0aW9uLCBERUNMCgkJICAgaXMgY29uc2lkZXJlZCB1bmRlZmluZWQgdW50aWwgYW4gb3V0LW9mLWNsYXNzCgkJICAgZGVmaW5pdGlvbiBpcyBwcm92aWRlZC4gICovCgkJREVDTF9FWFRFUk5BTCAoZGVjbCkgPSAxOwoJICAgICAgfQoJICAgIGVsc2UKCSAgICAgIHsKCQlkZWNsID0gYnVpbGRfZGVjbCAoRklFTERfREVDTCwgdW5xdWFsaWZpZWRfaWQsIHR5cGUpOwoJCURFQ0xfTk9OQUREUkVTU0FCTEVfUCAoZGVjbCkgPSBiaXRmaWVsZDsKCQlpZiAoc3RvcmFnZV9jbGFzcyA9PSBzY19tdXRhYmxlKQoJCSAgewoJCSAgICBERUNMX01VVEFCTEVfUCAoZGVjbCkgPSAxOwoJCSAgICBzdG9yYWdlX2NsYXNzID0gc2Nfbm9uZTsKCQkgIH0KCSAgICAgIH0KCgkgICAgYmFkX3NwZWNpZmllcnMgKGRlY2wsICJmaWVsZCIsIHZpcnR1YWxwLCBxdWFscyAhPSBUWVBFX1VOUVVBTElGSUVELAoJCQkgICAgaW5saW5lcCwgZnJpZW5kcCwgcmFpc2VzICE9IE5VTExfVFJFRSk7CgkgIH0KICAgICAgfQogICAgZWxzZSBpZiAoVFJFRV9DT0RFICh0eXBlKSA9PSBGVU5DVElPTl9UWVBFCgkgICAgIHx8IFRSRUVfQ09ERSAodHlwZSkgPT0gTUVUSE9EX1RZUEUpCiAgICAgIHsKCXRyZWUgb3JpZ2luYWxfbmFtZTsKCWludCBwdWJsaWNwID0gMDsKCglpZiAoIXVucXVhbGlmaWVkX2lkKQoJICByZXR1cm4gTlVMTF9UUkVFOwoKCWlmIChUUkVFX0NPREUgKHVucXVhbGlmaWVkX2lkKSA9PSBURU1QTEFURV9JRF9FWFBSKQoJICBvcmlnaW5hbF9uYW1lID0gZG5hbWU7CgllbHNlCgkgIG9yaWdpbmFsX25hbWUgPSB1bnF1YWxpZmllZF9pZDsKCglpZiAoc3RvcmFnZV9jbGFzcyA9PSBzY19hdXRvKQoJICBlcnJvciAoInN0b3JhZ2UgY2xhc3MgJTxhdXRvJT4gaW52YWxpZCBmb3IgZnVuY3Rpb24gJXFzIiwgbmFtZSk7CgllbHNlIGlmIChzdG9yYWdlX2NsYXNzID09IHNjX3JlZ2lzdGVyKQoJICBlcnJvciAoInN0b3JhZ2UgY2xhc3MgJTxyZWdpc3RlciU+IGludmFsaWQgZm9yIGZ1bmN0aW9uICVxcyIsIG5hbWUpOwoJZWxzZSBpZiAodGhyZWFkX3ApCgkgIGVycm9yICgic3RvcmFnZSBjbGFzcyAlPF9fdGhyZWFkJT4gaW52YWxpZCBmb3IgZnVuY3Rpb24gJXFzIiwgbmFtZSk7CgoJLyogRnVuY3Rpb24gZGVjbGFyYXRpb24gbm90IGF0IHRvcCBsZXZlbC4KCSAgIFN0b3JhZ2UgY2xhc3NlcyBvdGhlciB0aGFuIGBleHRlcm4nIGFyZSBub3QgYWxsb3dlZAoJICAgYW5kIGBleHRlcm4nIG1ha2VzIG5vIGRpZmZlcmVuY2UuICAqLwoJaWYgKCEgdG9wbGV2ZWxfYmluZGluZ3NfcCAoKQoJICAgICYmIChzdG9yYWdlX2NsYXNzID09IHNjX3N0YXRpYwoJCXx8IGRlY2xzcGVjcy0+c3BlY3NbKGludClkc19pbmxpbmVdKQoJICAgICYmIHBlZGFudGljKQoJICB7CgkgICAgaWYgKHN0b3JhZ2VfY2xhc3MgPT0gc2Nfc3RhdGljKQoJICAgICAgcGVkd2FybiAoIiU8c3RhdGljJT4gc3BlY2lmaWVkIGludmFsaWQgZm9yIGZ1bmN0aW9uICVxcyAiCiAgICAgICAgICAgICAgICAgICAgICAgImRlY2xhcmVkIG91dCBvZiBnbG9iYWwgc2NvcGUiLCBuYW1lKTsKCSAgICBlbHNlCgkgICAgICBwZWR3YXJuICgiJTxpbmxpbmUlPiBzcGVjaWZpZXIgaW52YWxpZCBmb3IgZnVuY3Rpb24gJXFzICIKICAgICAgICAgICAgICAgICAgICAgICAiZGVjbGFyZWQgb3V0IG9mIGdsb2JhbCBzY29wZSIsIG5hbWUpOwoJICB9CgoJaWYgKGN0eXBlID09IE5VTExfVFJFRSkKCSAgewoJICAgIGlmICh2aXJ0dWFscCkKCSAgICAgIHsKCQllcnJvciAoInZpcnR1YWwgbm9uLWNsYXNzIGZ1bmN0aW9uICVxcyIsIG5hbWUpOwoJCXZpcnR1YWxwID0gMDsKCSAgICAgIH0KCSAgfQoJZWxzZSBpZiAoVFJFRV9DT0RFICh0eXBlKSA9PSBGVU5DVElPTl9UWVBFICYmIHN0YXRpY3AgPCAyCgkJICYmICFORVdfREVMRVRFX09QTkFNRV9QIChvcmlnaW5hbF9uYW1lKSkKCSAgdHlwZSA9IGJ1aWxkX21ldGhvZF90eXBlX2RpcmVjdGx5IChjdHlwZSwKCQkJCQkgICAgIFRSRUVfVFlQRSAodHlwZSksCgkJCQkJICAgICBUWVBFX0FSR19UWVBFUyAodHlwZSkpOwoKCS8qIFJlY29yZCBwcmVzZW5jZSBvZiBgc3RhdGljJy4gICovCglwdWJsaWNwID0gKGN0eXBlICE9IE5VTExfVFJFRQoJCSAgIHx8IHN0b3JhZ2VfY2xhc3MgPT0gc2NfZXh0ZXJuCgkJICAgfHwgc3RvcmFnZV9jbGFzcyAhPSBzY19zdGF0aWMpOwoKCWRlY2wgPSBncm9rZm5kZWNsIChjdHlwZSwgdHlwZSwgb3JpZ2luYWxfbmFtZSwgcGFybXMsIHVucXVhbGlmaWVkX2lkLAoJCQkgICB2aXJ0dWFscCwgZmxhZ3MsIHF1YWxzLCByYWlzZXMsCgkJCSAgIDEsIGZyaWVuZHAsCgkJCSAgIHB1YmxpY3AsIGlubGluZXAsIHNmaywgZnVuY2RlZl9mbGFnLAoJCQkgICB0ZW1wbGF0ZV9jb3VudCwgaW5fbmFtZXNwYWNlLCBhdHRybGlzdCk7CglpZiAoZGVjbCA9PSBOVUxMX1RSRUUpCgkgIHJldHVybiBOVUxMX1RSRUU7CgoJaWYgKHN0YXRpY3AgPT0gMSkKCSAgewoJICAgIGludCBpbnZhbGlkX3N0YXRpYyA9IDA7CgoJICAgIC8qIERvbid0IGFsbG93IGEgc3RhdGljIG1lbWJlciBmdW5jdGlvbiBpbiBhIGNsYXNzLCBhbmQgZm9yYmlkCgkgICAgICAgZGVjbGFyaW5nIG1haW4gdG8gYmUgc3RhdGljLiAgKi8KCSAgICBpZiAoVFJFRV9DT0RFICh0eXBlKSA9PSBNRVRIT0RfVFlQRSkKCSAgICAgIHsKCQlwZWR3YXJuICgiY2Fubm90IGRlY2xhcmUgbWVtYmVyIGZ1bmN0aW9uICVxRCB0byBoYXZlICIKICAgICAgICAgICAgICAgICAgICAgICAgICJzdGF0aWMgbGlua2FnZSIsIGRlY2wpOwoJCWludmFsaWRfc3RhdGljID0gMTsKCSAgICAgIH0KCSAgICBlbHNlIGlmIChjdXJyZW50X2Z1bmN0aW9uX2RlY2wpCgkgICAgICB7CgkJLyogRklYTUUgbmVlZCBhcm0gY2l0YXRpb24gKi8KCQllcnJvciAoImNhbm5vdCBkZWNsYXJlIHN0YXRpYyBmdW5jdGlvbiBpbnNpZGUgYW5vdGhlciBmdW5jdGlvbiIpOwoJCWludmFsaWRfc3RhdGljID0gMTsKCSAgICAgIH0KCgkgICAgaWYgKGludmFsaWRfc3RhdGljKQoJICAgICAgewoJCXN0YXRpY3AgPSAwOwoJCXN0b3JhZ2VfY2xhc3MgPSBzY19ub25lOwoJICAgICAgfQoJICB9CiAgICAgIH0KICAgIGVsc2UKICAgICAgewoJLyogSXQncyBhIHZhcmlhYmxlLiAgKi8KCgkvKiBBbiB1bmluaXRpYWxpemVkIGRlY2wgd2l0aCBgZXh0ZXJuJyBpcyBhIHJlZmVyZW5jZS4gICovCglkZWNsID0gZ3Jva3ZhcmRlY2wgKHR5cGUsIHVucXVhbGlmaWVkX2lkLAoJCQkgICAgZGVjbHNwZWNzLAoJCQkgICAgaW5pdGlhbGl6ZWQsCgkJCSAgICAodHlwZV9xdWFscyAmIFRZUEVfUVVBTF9DT05TVCkgIT0gMCwKCQkJICAgIGN0eXBlID8gY3R5cGUgOiBpbl9uYW1lc3BhY2UpOwoJYmFkX3NwZWNpZmllcnMgKGRlY2wsICJ2YXJpYWJsZSIsIHZpcnR1YWxwLCBxdWFscyAhPSBUWVBFX1VOUVVBTElGSUVELAoJCQlpbmxpbmVwLCBmcmllbmRwLCByYWlzZXMgIT0gTlVMTF9UUkVFKTsKCglpZiAoY3R5cGUpCgkgIHsKCSAgICBERUNMX0NPTlRFWFQgKGRlY2wpID0gY3R5cGU7CgkgICAgaWYgKHN0YXRpY3AgPT0gMSkKCSAgICAgIHsKICAgICAgICAgICAgICAgIHBlZHdhcm4gKCIlPHN0YXRpYyU+IG1heSBub3QgYmUgdXNlZCB3aGVuIGRlZmluaW5nICIKICAgICAgICAgICAgICAgICAgICAgICAgICIoYXMgb3Bwb3NlZCB0byBkZWNsYXJpbmcpIGEgc3RhdGljIGRhdGEgbWVtYmVyIik7CgkgICAgICAgIHN0YXRpY3AgPSAwOwoJCXN0b3JhZ2VfY2xhc3MgPSBzY19ub25lOwoJICAgICAgfQoJICAgIGlmIChzdG9yYWdlX2NsYXNzID09IHNjX3JlZ2lzdGVyICYmIFRSRUVfU1RBVElDIChkZWNsKSkKCSAgICAgIHsKCQllcnJvciAoInN0YXRpYyBtZW1iZXIgJXFEIGRlY2xhcmVkICU8cmVnaXN0ZXIlPiIsIGRlY2wpOwoJCXN0b3JhZ2VfY2xhc3MgPSBzY19ub25lOwoJICAgICAgfQoJICAgIGlmIChzdG9yYWdlX2NsYXNzID09IHNjX2V4dGVybiAmJiBwZWRhbnRpYykKCSAgICAgIHsKCSAgICAgICAgcGVkd2FybiAoImNhbm5vdCBleHBsaWNpdGx5IGRlY2xhcmUgbWVtYmVyICVxI0QgdG8gaGF2ZSAiCiAgICAgICAgICAgICAgICAgICAgICAgICAiZXh0ZXJuIGxpbmthZ2UiLAogICAgICAgICAgICAgICAgICAgICAgICAgZGVjbCk7CgkJc3RvcmFnZV9jbGFzcyA9IHNjX25vbmU7CgkgICAgICB9CgkgIH0KICAgICAgfQoKICAgIC8qIFJlY29yZCBgcmVnaXN0ZXInIGRlY2xhcmF0aW9uIGZvciB3YXJuaW5ncyBvbiAmCiAgICAgICBhbmQgaW4gY2FzZSBkb2luZyBzdHVwaWQgcmVnaXN0ZXIgYWxsb2NhdGlvbi4gICovCgogICAgaWYgKHN0b3JhZ2VfY2xhc3MgPT0gc2NfcmVnaXN0ZXIpCiAgICAgIERFQ0xfUkVHSVNURVIgKGRlY2wpID0gMTsKICAgIGVsc2UgaWYgKHN0b3JhZ2VfY2xhc3MgPT0gc2NfZXh0ZXJuKQogICAgICBERUNMX1RISVNfRVhURVJOIChkZWNsKSA9IDE7CiAgICBlbHNlIGlmIChzdG9yYWdlX2NsYXNzID09IHNjX3N0YXRpYykKICAgICAgREVDTF9USElTX1NUQVRJQyAoZGVjbCkgPSAxOwoKICAgIC8qIEFQUExFIExPQ0FMIGJlZ2luIENXIGFzbSBibG9ja3MgKi8KICAgIGlmIChpYXNtX3ApCiAgICAgIHsKCS8qIFJlY29yZCB0aGF0IHRoaXMgaXMgYSBkZWNsIG9mIGEgQ1ctc3R5bGUgYXNtIGZ1bmN0aW9uLiAgKi8KCWlmIChmbGFnX2lhc21fYmxvY2tzKQoJICB7CgkgICAgREVDTF9JQVNNX0FTTV9GVU5DVElPTiAoZGVjbCkgPSAxOwoJICAgIERFQ0xfSUFTTV9OT1JFVFVSTiAoZGVjbCkgPSAwOwoJICAgIERFQ0xfSUFTTV9GUkFNRV9TSVpFIChkZWNsKSA9IC0yOwoJICB9CgllbHNlCgkgIGVycm9yICgiYXNtIGZ1bmN0aW9ucyBub3QgZW5hYmxlZCwgdXNlIGAtZmFzbS1ibG9ja3MnIik7CiAgICAgIH0KICAgIC8qIEFQUExFIExPQ0FMIGVuZCBDVyBhc20gYmxvY2tzICovCgogICAgLyogUmVjb3JkIGNvbnN0YW5jeSBhbmQgdm9sYXRpbGl0eS4gIFRoZXJlJ3Mgbm8gbmVlZCB0byBkbyB0aGlzCiAgICAgICB3aGVuIHByb2Nlc3NpbmcgYSB0ZW1wbGF0ZTsgd2UnbGwgZG8gdGhpcyBmb3IgdGhlIGluc3RhbnRpYXRlZAogICAgICAgZGVjbGFyYXRpb24gYmFzZWQgb24gdGhlIHR5cGUgb2YgREVDTC4gICovCiAgICBpZiAoIXByb2Nlc3NpbmdfdGVtcGxhdGVfZGVjbCkKICAgICAgY3BfYXBwbHlfdHlwZV9xdWFsc190b19kZWNsICh0eXBlX3F1YWxzLCBkZWNsKTsKCiAgICByZXR1cm4gZGVjbDsKICB9Cn0KDAovKiBTdWJyb3V0aW5lIG9mIHN0YXJ0X2Z1bmN0aW9uLiAgRW5zdXJlIHRoYXQgZWFjaCBvZiB0aGUgcGFyYW1ldGVyCiAgIHR5cGVzIChhcyBsaXN0ZWQgaW4gUEFSTVMpIGlzIGNvbXBsZXRlLCBhcyBpcyByZXF1aXJlZCBmb3IgYQogICBmdW5jdGlvbiBkZWZpbml0aW9uLiAgKi8KCnN0YXRpYyB2b2lkCnJlcXVpcmVfY29tcGxldGVfdHlwZXNfZm9yX3Bhcm1zICh0cmVlIHBhcm1zKQp7CiAgZm9yICg7IHBhcm1zOyBwYXJtcyA9IFRSRUVfQ0hBSU4gKHBhcm1zKSkKICAgIHsKICAgICAgaWYgKGRlcGVuZGVudF90eXBlX3AgKFRSRUVfVFlQRSAocGFybXMpKSkKCWNvbnRpbnVlOwogICAgICBpZiAoVk9JRF9UWVBFX1AgKFRSRUVfVFlQRSAocGFybXMpKSkKICAgICAgICAvKiBncm9rcGFybXMgd2lsbCBoYXZlIGFscmVhZHkgaXNzdWVkIGFuIGVycm9yLiAgKi8KICAgICAgICBUUkVFX1RZUEUgKHBhcm1zKSA9IGVycm9yX21hcmtfbm9kZTsKICAgICAgZWxzZSBpZiAoY29tcGxldGVfdHlwZV9vcl9lbHNlIChUUkVFX1RZUEUgKHBhcm1zKSwgcGFybXMpKQoJewoJICBsYXlvdXRfZGVjbCAocGFybXMsIDApOwoJICBERUNMX0FSR19UWVBFIChwYXJtcykgPSB0eXBlX3Bhc3NlZF9hcyAoVFJFRV9UWVBFIChwYXJtcykpOwoJfQogICAgfQp9CgovKiBSZXR1cm5zIG5vbnplcm8gaWYgVCBpcyBhIGxvY2FsIHZhcmlhYmxlLiAgKi8KCmludApsb2NhbF92YXJpYWJsZV9wICh0cmVlIHQpCnsKICBpZiAoKFRSRUVfQ09ERSAodCkgPT0gVkFSX0RFQ0wKICAgICAgIC8qIEEgVkFSX0RFQ0wgd2l0aCBhIGNvbnRleHQgdGhhdCBpcyBhIF9UWVBFIGlzIGEgc3RhdGljIGRhdGEKCSAgbWVtYmVyLiAgKi8KICAgICAgICYmICFUWVBFX1AgKENQX0RFQ0xfQ09OVEVYVCAodCkpCiAgICAgICAvKiBBbnkgb3RoZXIgbm9uLWxvY2FsIHZhcmlhYmxlIG11c3QgYmUgYXQgbmFtZXNwYWNlIHNjb3BlLiAgKi8KICAgICAgICYmICFERUNMX05BTUVTUEFDRV9TQ09QRV9QICh0KSkKICAgICAgfHwgKFRSRUVfQ09ERSAodCkgPT0gUEFSTV9ERUNMKSkKICAgIHJldHVybiAxOwoKICByZXR1cm4gMDsKfQoKLyogUmV0dXJucyBub256ZXJvIGlmIFQgaXMgYW4gYXV0b21hdGljIGxvY2FsIHZhcmlhYmxlIG9yIGEgbGFiZWwuCiAgIChUaGVzZSBhcmUgdGhlIGRlY2xhcmF0aW9ucyB0aGF0IG5lZWQgdG8gYmUgcmVtYXBwZWQgd2hlbiB0aGUgY29kZQogICBjb250YWluaW5nIHRoZW0gaXMgZHVwbGljYXRlZC4pICAqLwoKaW50Cm5vbnN0YXRpY19sb2NhbF9kZWNsX3AgKHRyZWUgdCkKewogIHJldHVybiAoKGxvY2FsX3ZhcmlhYmxlX3AgKHQpICYmICFUUkVFX1NUQVRJQyAodCkpCgkgIHx8IFRSRUVfQ09ERSAodCkgPT0gTEFCRUxfREVDTAoJICB8fCBUUkVFX0NPREUgKHQpID09IFJFU1VMVF9ERUNMKTsKfQoKLyogTGlrZSBsb2NhbF92YXJpYWJsZV9wLCBidXQgc3VpdGFibGUgZm9yIHVzZSBhcyBhIHRyZWUtd2Fsa2luZwogICBmdW5jdGlvbi4gICovCgpzdGF0aWMgdHJlZQpsb2NhbF92YXJpYWJsZV9wX3dhbGtmbiAodHJlZSAqdHAsIGludCAqd2Fsa19zdWJ0cmVlcywKCQkJIHZvaWQgKmRhdGEgQVRUUklCVVRFX1VOVVNFRCkKewogIGlmIChsb2NhbF92YXJpYWJsZV9wICgqdHApICYmICFERUNMX0FSVElGSUNJQUwgKCp0cCkpCiAgICByZXR1cm4gKnRwOwogIGVsc2UgaWYgKFRZUEVfUCAoKnRwKSkKICAgICp3YWxrX3N1YnRyZWVzID0gMDsKCiAgcmV0dXJuIE5VTExfVFJFRTsKfQoKCi8qIENoZWNrIHRoYXQgQVJHLCB3aGljaCBpcyBhIGRlZmF1bHQtYXJndW1lbnQgZXhwcmVzc2lvbiBmb3IgYQogICBwYXJhbWV0ZXIgREVDTCwgaXMgdmFsaWQuICBSZXR1cm5zIEFSRywgb3IgRVJST1JfTUFSS19OT0RFLCBpZgogICBzb21ldGhpbmcgZ29lcyB3cm9uZy4gIERFQ0wgbWF5IGFsc28gYmUgYSBfVFlQRSBub2RlLCByYXRoZXIgdGhhbiBhCiAgIERFQ0wsIGlmIHRoZXJlIGlzIG5vIERFQ0wgYXZhaWxhYmxlLiAgKi8KCnRyZWUKY2hlY2tfZGVmYXVsdF9hcmd1bWVudCAodHJlZSBkZWNsLCB0cmVlIGFyZykKewogIHRyZWUgdmFyOwogIHRyZWUgZGVjbF90eXBlOwoKICBpZiAoVFJFRV9DT0RFIChhcmcpID09IERFRkFVTFRfQVJHKQogICAgLyogV2UgZ2V0IGEgREVGQVVMVF9BUkcgd2hlbiBsb29raW5nIGF0IGFuIGluLWNsYXNzIGRlY2xhcmF0aW9uCiAgICAgICB3aXRoIGEgZGVmYXVsdCBhcmd1bWVudC4gIElnbm9yZSB0aGUgYXJndW1lbnQgZm9yIG5vdzsgd2UnbGwKICAgICAgIGRlYWwgd2l0aCBpdCBhZnRlciB0aGUgY2xhc3MgaXMgY29tcGxldGUuICAqLwogICAgcmV0dXJuIGFyZzsKCiAgaWYgKHByb2Nlc3NpbmdfdGVtcGxhdGVfZGVjbCB8fCB1c2VzX3RlbXBsYXRlX3Bhcm1zIChhcmcpKQogICAgLyogV2UgZG9uJ3QgZG8gYW55dGhpbmcgY2hlY2tpbmcgdW50aWwgaW5zdGFudGlhdGlvbi10aW1lLiAgTm90ZQogICAgICAgdGhhdCB0aGVyZSBtYXkgYmUgdW5pbnN0YW50aWF0ZWQgYXJndW1lbnRzIGV2ZW4gZm9yIGFuCiAgICAgICBpbnN0YW50aWF0ZWQgZnVuY3Rpb24sIHNpbmNlIGRlZmF1bHQgYXJndW1lbnRzIGFyZSBub3QKICAgICAgIGluc3RhbnRpYXRlZCB1bnRpbCB0aGV5IGFyZSBuZWVkZWQuICAqLwogICAgcmV0dXJuIGFyZzsKCiAgaWYgKFRZUEVfUCAoZGVjbCkpCiAgICB7CiAgICAgIGRlY2xfdHlwZSA9IGRlY2w7CiAgICAgIGRlY2wgPSBOVUxMX1RSRUU7CiAgICB9CiAgZWxzZQogICAgZGVjbF90eXBlID0gVFJFRV9UWVBFIChkZWNsKTsKCiAgaWYgKGFyZyA9PSBlcnJvcl9tYXJrX25vZGUKICAgICAgfHwgZGVjbCA9PSBlcnJvcl9tYXJrX25vZGUKICAgICAgfHwgVFJFRV9UWVBFIChhcmcpID09IGVycm9yX21hcmtfbm9kZQogICAgICB8fCBkZWNsX3R5cGUgPT0gZXJyb3JfbWFya19ub2RlKQogICAgLyogU29tZXRoaW5nIGFscmVhZHkgd2VudCB3cm9uZy4gIFRoZXJlJ3Mgbm8gbmVlZCB0byBjaGVjawogICAgICAgZnVydGhlci4gICovCiAgICByZXR1cm4gZXJyb3JfbWFya19ub2RlOwoKICAvKiBbZGNsLmZjdC5kZWZhdWx0XQoKICAgICBBIGRlZmF1bHQgYXJndW1lbnQgZXhwcmVzc2lvbiBpcyBpbXBsaWNpdGx5IGNvbnZlcnRlZCB0byB0aGUKICAgICBwYXJhbWV0ZXIgdHlwZS4gICovCiAgaWYgKCFUUkVFX1RZUEUgKGFyZykKICAgICAgLyogQVBQTEUgTE9DQUwgcmFkYXIgNDE4NzkxNiAqLwogICAgICB8fCAhY2FuX2NvbnZlcnRfYXJnIChkZWNsX3R5cGUsIFRSRUVfVFlQRSAoYXJnKSwgYXJnLCBMT09LVVBfTk9STUFMKSkKICAgIHsKICAgICAgaWYgKGRlY2wpCgllcnJvciAoImRlZmF1bHQgYXJndW1lbnQgZm9yICVxI0QgaGFzIHR5cGUgJXFUIiwKICAgICAgICAgICAgICAgZGVjbCwgVFJFRV9UWVBFIChhcmcpKTsKICAgICAgZWxzZQoJZXJyb3IgKCJkZWZhdWx0IGFyZ3VtZW50IGZvciBwYXJhbWV0ZXIgb2YgdHlwZSAlcVQgaGFzIHR5cGUgJXFUIiwKICAgICAgICAgICAgICAgZGVjbF90eXBlLCBUUkVFX1RZUEUgKGFyZykpOwoKICAgICAgcmV0dXJuIGVycm9yX21hcmtfbm9kZTsKICAgIH0KCiAgLyogW2RjbC5mY3QuZGVmYXVsdF0KCiAgICAgTG9jYWwgdmFyaWFibGVzIHNoYWxsIG5vdCBiZSB1c2VkIGluIGRlZmF1bHQgYXJndW1lbnQKICAgICBleHByZXNzaW9ucy4KCiAgICAgVGhlIGtleXdvcmQgYHRoaXMnIHNoYWxsIG5vdCBiZSB1c2VkIGluIGEgZGVmYXVsdCBhcmd1bWVudCBvZiBhCiAgICAgbWVtYmVyIGZ1bmN0aW9uLiAgKi8KICB2YXIgPSB3YWxrX3RyZWVfd2l0aG91dF9kdXBsaWNhdGVzICgmYXJnLCBsb2NhbF92YXJpYWJsZV9wX3dhbGtmbiwKCQkJCSAgICAgIE5VTEwpOwogIGlmICh2YXIpCiAgICB7CiAgICAgIGVycm9yICgiZGVmYXVsdCBhcmd1bWVudCAlcUUgdXNlcyBsb2NhbCB2YXJpYWJsZSAlcUQiLCBhcmcsIHZhcik7CiAgICAgIHJldHVybiBlcnJvcl9tYXJrX25vZGU7CiAgICB9CgogIC8qIEFsbCBpcyB3ZWxsLiAgKi8KICByZXR1cm4gYXJnOwp9CgovKiBEZWNvZGUgdGhlIGxpc3Qgb2YgcGFyYW1ldGVyIHR5cGVzIGZvciBhIGZ1bmN0aW9uIHR5cGUuCiAgIEdpdmVuIHRoZSBsaXN0IG9mIHRoaW5ncyBkZWNsYXJlZCBpbnNpZGUgdGhlIHBhcmVucywKICAgcmV0dXJuIGEgbGlzdCBvZiB0eXBlcy4KCiAgIElmIHRoaXMgcGFyYW1ldGVyIGRvZXMgbm90IGVuZCB3aXRoIGFuIGVsbGlwc2lzLCB3ZSBhcHBlbmQKICAgdm9pZF9saXN0X25vZGUuCgogICAqUEFSTVMgaXMgc2V0IHRvIHRoZSBjaGFpbiBvZiBQQVJNX0RFQ0xzIGNyZWF0ZWQuICAqLwoKc3RhdGljIHRyZWUKZ3Jva3Bhcm1zIChjcF9wYXJhbWV0ZXJfZGVjbGFyYXRvciAqZmlyc3RfcGFybSwgdHJlZSAqcGFybXMpCnsKICB0cmVlIHJlc3VsdCA9IE5VTExfVFJFRTsKICB0cmVlIGRlY2xzID0gTlVMTF9UUkVFOwogIGludCBlbGxpcHNpcyA9ICFmaXJzdF9wYXJtIHx8IGZpcnN0X3Bhcm0tPmVsbGlwc2lzX3A7CiAgY3BfcGFyYW1ldGVyX2RlY2xhcmF0b3IgKnBhcm07CiAgaW50IGFueV9lcnJvciA9IDA7CgogIGZvciAocGFybSA9IGZpcnN0X3Bhcm07IHBhcm0gIT0gTlVMTDsgcGFybSA9IHBhcm0tPm5leHQpCiAgICB7CiAgICAgIHRyZWUgdHlwZSA9IE5VTExfVFJFRTsKICAgICAgdHJlZSBpbml0ID0gcGFybS0+ZGVmYXVsdF9hcmd1bWVudDsKICAgICAgdHJlZSBhdHRyczsKICAgICAgdHJlZSBkZWNsOwoKICAgICAgaWYgKHBhcm0gPT0gbm9fcGFyYW1ldGVycykKICAgICAgICBicmVhazsKCiAgICAgIGF0dHJzID0gcGFybS0+ZGVjbF9zcGVjaWZpZXJzLmF0dHJpYnV0ZXM7CiAgICAgIHBhcm0tPmRlY2xfc3BlY2lmaWVycy5hdHRyaWJ1dGVzID0gTlVMTF9UUkVFOwogICAgICBkZWNsID0gZ3Jva2RlY2xhcmF0b3IgKHBhcm0tPmRlY2xhcmF0b3IsICZwYXJtLT5kZWNsX3NwZWNpZmllcnMsCgkJCSAgICAgUEFSTSwgaW5pdCAhPSBOVUxMX1RSRUUsICZhdHRycyk7CiAgICAgIGlmICghIGRlY2wgfHwgVFJFRV9UWVBFIChkZWNsKSA9PSBlcnJvcl9tYXJrX25vZGUpCiAgICAgICAgY29udGludWU7CgogICAgICBpZiAoYXR0cnMpCgljcGx1c19kZWNsX2F0dHJpYnV0ZXMgKCZkZWNsLCBhdHRycywgMCk7CgogICAgICB0eXBlID0gVFJFRV9UWVBFIChkZWNsKTsKICAgICAgaWYgKFZPSURfVFlQRV9QICh0eXBlKSkKICAgICAgICB7CiAgICAgICAgICBpZiAoc2FtZV90eXBlX3AgKHR5cGUsIHZvaWRfdHlwZV9ub2RlKQogICAgICAgICAgICAgICYmICFERUNMX05BTUUgKGRlY2wpICYmICFyZXN1bHQgJiYgIXBhcm0tPm5leHQgJiYgIWVsbGlwc2lzKQogICAgICAgICAgICAvKiB0aGlzIGlzIGEgcGFybWxpc3Qgb2YgYCh2b2lkKScsIHdoaWNoIGlzIG9rLiAgKi8KICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICBjeHhfaW5jb21wbGV0ZV90eXBlX2Vycm9yIChkZWNsLCB0eXBlKTsKCSAgLyogSXQncyBub3QgYSBnb29kIGlkZWEgdG8gYWN0dWFsbHkgY3JlYXRlIHBhcmFtZXRlcnMgb2YKCSAgICAgdHlwZSBgdm9pZCc7IG90aGVyIHBhcnRzIG9mIHRoZSBjb21waWxlciBhc3N1bWUgdGhhdCBhCgkgICAgIHZvaWQgdHlwZSB0ZXJtaW5hdGVzIHRoZSBwYXJhbWV0ZXIgbGlzdC4gICovCgkgIHR5cGUgPSBlcnJvcl9tYXJrX25vZGU7CgkgIFRSRUVfVFlQRSAoZGVjbCkgPSBlcnJvcl9tYXJrX25vZGU7CiAgICAgICAgfQoKICAgICAgaWYgKHR5cGUgIT0gZXJyb3JfbWFya19ub2RlKQoJewoJICAvKiBUb3AtbGV2ZWwgcXVhbGlmaWVycyBvbiB0aGUgcGFyYW1ldGVycyBhcmUKCSAgICAgaWdub3JlZCBmb3IgZnVuY3Rpb24gdHlwZXMuICAqLwoJICB0eXBlID0gY3BfYnVpbGRfcXVhbGlmaWVkX3R5cGUgKHR5cGUsIDApOwoJICBpZiAoVFJFRV9DT0RFICh0eXBlKSA9PSBNRVRIT0RfVFlQRSkKCSAgICB7CgkgICAgICBlcnJvciAoInBhcmFtZXRlciAlcUQgaW52YWxpZGx5IGRlY2xhcmVkIG1ldGhvZCB0eXBlIiwgZGVjbCk7CgkgICAgICB0eXBlID0gYnVpbGRfcG9pbnRlcl90eXBlICh0eXBlKTsKCSAgICAgIFRSRUVfVFlQRSAoZGVjbCkgPSB0eXBlOwoJICAgIH0KCSAgZWxzZSBpZiAoYWJzdHJhY3RfdmlydHVhbHNfZXJyb3IgKGRlY2wsIHR5cGUpKQoJICAgIGFueV9lcnJvciA9IDE7ICAvKiBTZWVtcyBsaWtlIGEgZ29vZCBpZGVhLiAgKi8KCSAgZWxzZSBpZiAoUE9JTlRFUl9UWVBFX1AgKHR5cGUpKQoJICAgIHsKCSAgICAgIC8qIFtkY2wuZmN0XS82LCBwYXJhbWV0ZXIgdHlwZXMgY2Fubm90IGNvbnRhaW4gcG9pbnRlcnMKCQkgKHJlZmVyZW5jZXMpIHRvIGFycmF5cyBvZiB1bmtub3duIGJvdW5kLiAgKi8KCSAgICAgIHRyZWUgdCA9IFRSRUVfVFlQRSAodHlwZSk7CgkgICAgICBpbnQgcHRyID0gVFlQRV9QVFJfUCAodHlwZSk7CgogICAgICAgICAgICAgIHdoaWxlICgxKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICBpZiAoVFlQRV9QVFJfUCAodCkpCiAgICAgICAgICAgICAgICAgICAgcHRyID0gMTsKICAgICAgICAgICAgICAgICAgZWxzZSBpZiAoVFJFRV9DT0RFICh0KSAhPSBBUlJBWV9UWVBFKQogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICBlbHNlIGlmICghVFlQRV9ET01BSU4gKHQpKQoJICAgICAgICAgICAgYnJlYWs7CgkgICAgICAgICAgdCA9IFRSRUVfVFlQRSAodCk7CgkgICAgICAgIH0KCSAgICAgIGlmIChUUkVFX0NPREUgKHQpID09IEFSUkFZX1RZUEUpCgkJZXJyb3IgKCJwYXJhbWV0ZXIgJXFEIGluY2x1ZGVzICVzIHRvIGFycmF5IG9mIHVua25vd24gIgogICAgICAgICAgICAgICAgICAgICAgICJib3VuZCAlcVQiLAogICAgICAgICAgICAgICAgICAgICAgIGRlY2wsIHB0ciA/ICJwb2ludGVyIiA6ICJyZWZlcmVuY2UiLCB0KTsKCSAgICB9CgoJICBpZiAoIWFueV9lcnJvciAmJiBpbml0KQoJICAgIGluaXQgPSBjaGVja19kZWZhdWx0X2FyZ3VtZW50IChkZWNsLCBpbml0KTsKCSAgZWxzZQoJICAgIGluaXQgPSBOVUxMX1RSRUU7Cgl9CgogICAgICBUUkVFX0NIQUlOIChkZWNsKSA9IGRlY2xzOwogICAgICBkZWNscyA9IGRlY2w7CiAgICAgIHJlc3VsdCA9IHRyZWVfY29ucyAoaW5pdCwgdHlwZSwgcmVzdWx0KTsKICAgIH0KICBkZWNscyA9IG5yZXZlcnNlIChkZWNscyk7CiAgcmVzdWx0ID0gbnJldmVyc2UgKHJlc3VsdCk7CiAgaWYgKCFlbGxpcHNpcykKICAgIHJlc3VsdCA9IGNoYWlub24gKHJlc3VsdCwgdm9pZF9saXN0X25vZGUpOwogICpwYXJtcyA9IGRlY2xzOwoKICByZXR1cm4gcmVzdWx0Owp9CgoMCi8qIEQgaXMgYSBjb25zdHJ1Y3RvciBvciBvdmVybG9hZGVkIGBvcGVyYXRvcj0nLgoKICAgTGV0IFQgYmUgdGhlIGNsYXNzIGluIHdoaWNoIEQgaXMgZGVjbGFyZWQuIFRoZW4sIHRoaXMgZnVuY3Rpb24KICAgcmV0dXJuczoKCiAgIC0xIGlmIEQncyBpcyBhbiBpbGwtZm9ybWVkIGNvbnN0cnVjdG9yIG9yIGNvcHkgYXNzaWdubWVudCBvcGVyYXRvcgogICAgICB3aG9zZSBmaXJzdCBwYXJhbWV0ZXIgaXMgb2YgdHlwZSBgVCcuCiAgIDAgIGlmIEQgaXMgbm90IGEgY29weSBjb25zdHJ1Y3RvciBvciBjb3B5IGFzc2lnbm1lbnQKICAgICAgb3BlcmF0b3IuCiAgIDEgIGlmIEQgaXMgYSBjb3B5IGNvbnN0cnVjdG9yIG9yIGNvcHkgYXNzaWdubWVudCBvcGVyYXRvciB3aG9zZQogICAgICBmaXJzdCBwYXJhbWV0ZXIgaXMgYSByZWZlcmVuY2UgdG8gY29uc3QgcXVhbGlmaWVkIFQuCiAgIDIgIGlmIEQgaXMgYSBjb3B5IGNvbnN0cnVjdG9yIG9yIGNvcHkgYXNzaWdubWVudCBvcGVyYXRvciB3aG9zZQogICAgICBmaXJzdCBwYXJhbWV0ZXIgaXMgYSByZWZlcmVuY2UgdG8gbm9uLWNvbnN0IHF1YWxpZmllZCBULgoKICAgVGhpcyBmdW5jdGlvbiBjYW4gYmUgdXNlZCBhcyBhIHByZWRpY2F0ZS4gUG9zaXRpdmUgdmFsdWVzIGluZGljYXRlCiAgIGEgY29weSBjb25zdHJ1Y3RvciBhbmQgbm9uemVybyB2YWx1ZXMgaW5kaWNhdGUgYSBjb3B5IGFzc2lnbm1lbnQKICAgb3BlcmF0b3IuICAqLwoKaW50CmNvcHlfZm5fcCAodHJlZSBkKQp7CiAgdHJlZSBhcmdzOwogIHRyZWUgYXJnX3R5cGU7CiAgaW50IHJlc3VsdCA9IDE7CgogIGdjY19hc3NlcnQgKERFQ0xfRlVOQ1RJT05fTUVNQkVSX1AgKGQpKTsKCiAgaWYgKERFQ0xfVEVNUExBVEVfSU5GTyAoZCkgCiAgICAgICYmIERFQ0xfTUVNQkVSX1RFTVBMQVRFX1AgKERFQ0xfVElfVEVNUExBVEUgKGQpKSkKICAgIC8qIEluc3RhbnRpYXRpb25zIG9mIHRlbXBsYXRlIG1lbWJlciBmdW5jdGlvbnMgYXJlIG5ldmVyIGNvcHkKICAgICAgIGZ1bmN0aW9ucy4gIE5vdGUgdGhhdCBtZW1iZXIgZnVuY3Rpb25zIG9mIHRlbXBsYXRlZCBjbGFzc2VzIGFyZQogICAgICAgcmVwcmVzZW50ZWQgYXMgdGVtcGxhdGUgZnVuY3Rpb25zIGludGVybmFsbHksIGFuZCB3ZSBtdXN0CiAgICAgICBhY2NlcHQgdGhvc2UgYXMgY29weSBmdW5jdGlvbnMuICAqLwogICAgcmV0dXJuIDA7CgogIGFyZ3MgPSBGVU5DVElPTl9GSVJTVF9VU0VSX1BBUk1UWVBFIChkKTsKICBpZiAoIWFyZ3MpCiAgICByZXR1cm4gMDsKCiAgYXJnX3R5cGUgPSBUUkVFX1ZBTFVFIChhcmdzKTsKCiAgaWYgKFRZUEVfTUFJTl9WQVJJQU5UIChhcmdfdHlwZSkgPT0gREVDTF9DT05URVhUIChkKSkKICAgIHsKICAgICAgLyogUGFzcyBieSB2YWx1ZSBjb3B5IGFzc2lnbm1lbnQgb3BlcmF0b3IuICAqLwogICAgICByZXN1bHQgPSAtMTsKICAgIH0KICBlbHNlIGlmIChUUkVFX0NPREUgKGFyZ190eXBlKSA9PSBSRUZFUkVOQ0VfVFlQRQoJICAgJiYgVFlQRV9NQUlOX1ZBUklBTlQgKFRSRUVfVFlQRSAoYXJnX3R5cGUpKSA9PSBERUNMX0NPTlRFWFQgKGQpKQogICAgewogICAgICBpZiAoQ1BfVFlQRV9DT05TVF9QIChUUkVFX1RZUEUgKGFyZ190eXBlKSkpCglyZXN1bHQgPSAyOwogICAgfQogIGVsc2UKICAgIHJldHVybiAwOwoKICBhcmdzID0gVFJFRV9DSEFJTiAoYXJncyk7CgogIGlmIChhcmdzICYmIGFyZ3MgIT0gdm9pZF9saXN0X25vZGUgJiYgIVRSRUVfUFVSUE9TRSAoYXJncykpCiAgICAvKiBUaGVyZSBhcmUgbW9yZSBub24tb3B0aW9uYWwgYXJncy4gICovCiAgICByZXR1cm4gMDsKCiAgcmV0dXJuIHJlc3VsdDsKfQoKLyogUmVtZW1iZXIgYW55IHNwZWNpYWwgcHJvcGVydGllcyBvZiBtZW1iZXIgZnVuY3Rpb24gREVDTC4gICovCgp2b2lkIGdyb2tfc3BlY2lhbF9tZW1iZXJfcHJvcGVydGllcyAodHJlZSBkZWNsKQp7CiAgaWYgKCFERUNMX05PTlNUQVRJQ19NRU1CRVJfRlVOQ1RJT05fUChkZWNsKSkKICAgIDsgLyogTm90IHNwZWNpYWwuICAqLwogIGVsc2UgaWYgKERFQ0xfQ09OU1RSVUNUT1JfUCAoZGVjbCkpCiAgICB7CiAgICAgIGludCBjdG9yID0gY29weV9mbl9wIChkZWNsKTsKCiAgICAgIGlmIChjdG9yID4gMCkKCXsKCSAgLyogW2NsYXNzLmNvcHldCgogICAgIAkgICAgIEEgbm9uLXRlbXBsYXRlIGNvbnN0cnVjdG9yIGZvciBjbGFzcyBYIGlzIGEgY29weQogICAgIAkgICAgIGNvbnN0cnVjdG9yIGlmIGl0cyBmaXJzdCBwYXJhbWV0ZXIgaXMgb2YgdHlwZSBYJiwgY29uc3QKICAgICAJICAgICBYJiwgdm9sYXRpbGUgWCYgb3IgY29uc3Qgdm9sYXRpbGUgWCYsIGFuZCBlaXRoZXIgdGhlcmUKICAgICAJICAgICBhcmUgbm8gb3RoZXIgcGFyYW1ldGVycyBvciBlbHNlIGFsbCBvdGhlciBwYXJhbWV0ZXJzIGhhdmUKICAgICAJICAgICBkZWZhdWx0IGFyZ3VtZW50cy4gICovCgkgIFRZUEVfSEFTX0lOSVRfUkVGIChERUNMX0NPTlRFWFQgKGRlY2wpKSA9IDE7CgkgIGlmIChjdG9yID4gMSkKCSAgICBUWVBFX0hBU19DT05TVF9JTklUX1JFRiAoREVDTF9DT05URVhUIChkZWNsKSkgPSAxOwoJfQogICAgICBlbHNlIGlmIChzdWZmaWNpZW50X3Bhcm1zX3AgKEZVTkNUSU9OX0ZJUlNUX1VTRVJfUEFSTVRZUEUgKGRlY2wpKSkKCVRZUEVfSEFTX0RFRkFVTFRfQ09OU1RSVUNUT1IgKERFQ0xfQ09OVEVYVCAoZGVjbCkpID0gMTsKICAgIH0KICBlbHNlIGlmIChERUNMX09WRVJMT0FERURfT1BFUkFUT1JfUCAoZGVjbCkgPT0gTk9QX0VYUFIpCiAgICB7CiAgICAgIC8qIFtjbGFzcy5jb3B5XQoKICAgICAJIEEgbm9uLXRlbXBsYXRlIGFzc2lnbm1lbnQgb3BlcmF0b3IgZm9yIGNsYXNzIFggaXMgYSBjb3B5CiAgICAgCSBhc3NpZ25tZW50IG9wZXJhdG9yIGlmIGl0cyBwYXJhbWV0ZXIgaXMgb2YgdHlwZSBYLCBYJiwgY29uc3QKICAgICAJIFgmLCB2b2xhdGlsZSBYJiBvciBjb25zdCB2b2xhdGlsZSBYJi4gICovCgogICAgICBpbnQgYXNzb3AgPSBjb3B5X2ZuX3AgKGRlY2wpOwoKICAgICAgaWYgKGFzc29wKQoJewoJICBUWVBFX0hBU19BU1NJR05fUkVGIChERUNMX0NPTlRFWFQgKGRlY2wpKSA9IDE7CgkgIGlmIChhc3NvcCAhPSAxKQoJICAgIFRZUEVfSEFTX0NPTlNUX0FTU0lHTl9SRUYgKERFQ0xfQ09OVEVYVCAoZGVjbCkpID0gMTsKCX0KICAgIH0KfQoKLyogQ2hlY2sgYSBjb25zdHJ1Y3RvciBERUNMIGhhcyB0aGUgY29ycmVjdCBmb3JtLiAgQ29tcGxhaW5zCiAgIGlmIHRoZSBjbGFzcyBoYXMgYSBjb25zdHJ1Y3RvciBvZiB0aGUgZm9ybSBYKFgpLiAgKi8KCmludApncm9rX2N0b3JfcHJvcGVydGllcyAodHJlZSBjdHlwZSwgdHJlZSBkZWNsKQp7CiAgaW50IGN0b3JfcGFybSA9IGNvcHlfZm5fcCAoZGVjbCk7CgogIGlmIChjdG9yX3Bhcm0gPCAwKQogICAgewogICAgICAvKiBbY2xhc3MuY29weV0KCiAgICAgCSBBIGRlY2xhcmF0aW9uIG9mIGEgY29uc3RydWN0b3IgZm9yIGEgY2xhc3MgWCBpcyBpbGwtZm9ybWVkIGlmCiAgICAgCSBpdHMgZmlyc3QgcGFyYW1ldGVyIGlzIG9mIHR5cGUgKG9wdGlvbmFsbHkgY3YtcXVhbGlmaWVkKSBYCiAgICAgCSBhbmQgZWl0aGVyIHRoZXJlIGFyZSBubyBvdGhlciBwYXJhbWV0ZXJzIG9yIGVsc2UgYWxsIG90aGVyCiAgICAgCSBwYXJhbWV0ZXJzIGhhdmUgZGVmYXVsdCBhcmd1bWVudHMuCgogICAgIAkgV2UgKmRvbid0KiBjb21wbGFpbiBhYm91dCBtZW1iZXIgdGVtcGxhdGUgaW5zdGFudGlhdGlvbnMgdGhhdAogICAgIAkgaGF2ZSB0aGlzIGZvcm0sIHRob3VnaDsgdGhleSBjYW4gb2NjdXIgYXMgd2UgdHJ5IHRvIGRlY2lkZQogICAgIAkgd2hhdCBjb25zdHJ1Y3RvciB0byB1c2UgZHVyaW5nIG92ZXJsb2FkIHJlc29sdXRpb24uICBTaW5jZQogICAgIAkgb3ZlcmxvYWQgcmVzb2x1dGlvbiB3aWxsIG5ldmVyIHByZWZlciBzdWNoIGEgY29uc3RydWN0b3IgdG8KICAgICAJIHRoZSBub24tdGVtcGxhdGUgY29weSBjb25zdHJ1Y3RvciAod2hpY2ggaXMgZWl0aGVyIGV4cGxpY2l0bHkKICAgICAJIG9yIGltcGxpY2l0bHkgZGVmaW5lZCksIHRoZXJlJ3Mgbm8gbmVlZCB0byB3b3JyeSBhYm91dCB0aGVpcgogICAgIAkgZXhpc3RlbmNlLiAgVGhlb3JldGljYWxseSwgdGhleSBzaG91bGQgbmV2ZXIgZXZlbiBiZQogICAgIAkgaW5zdGFudGlhdGVkLCBidXQgdGhhdCdzIGhhcmQgdG8gZm9yZXN0YWxsLiAgKi8KICAgICAgZXJyb3IgKCJpbnZhbGlkIGNvbnN0cnVjdG9yOyB5b3UgcHJvYmFibHkgbWVhbnQgJTwlVCAoY29uc3QgJVQmKSU+IiwKCQljdHlwZSwgY3R5cGUpOwogICAgICByZXR1cm4gMDsKICAgIH0KCiAgcmV0dXJuIDE7Cn0KCi8qIEFuIG9wZXJhdG9yIHdpdGggdGhpcyBjb2RlIGlzIHVuYXJ5LCBidXQgY2FuIGFsc28gYmUgYmluYXJ5LiAgKi8KCnN0YXRpYyBpbnQKYW1iaV9vcF9wIChlbnVtIHRyZWVfY29kZSBjb2RlKQp7CiAgcmV0dXJuIChjb2RlID09IElORElSRUNUX1JFRgoJICB8fCBjb2RlID09IEFERFJfRVhQUgoJICB8fCBjb2RlID09IENPTlZFUlRfRVhQUgoJICB8fCBjb2RlID09IE5FR0FURV9FWFBSCgkgIHx8IGNvZGUgPT0gUFJFSU5DUkVNRU5UX0VYUFIKCSAgfHwgY29kZSA9PSBQUkVERUNSRU1FTlRfRVhQUik7Cn0KCi8qIEFuIG9wZXJhdG9yIHdpdGggdGhpcyBuYW1lIGNhbiBvbmx5IGJlIHVuYXJ5LiAgKi8KCnN0YXRpYyBpbnQKdW5hcnlfb3BfcCAoZW51bSB0cmVlX2NvZGUgY29kZSkKewogIHJldHVybiAoY29kZSA9PSBUUlVUSF9OT1RfRVhQUgoJICB8fCBjb2RlID09IEJJVF9OT1RfRVhQUgoJICB8fCBjb2RlID09IENPTVBPTkVOVF9SRUYKCSAgfHwgY29kZSA9PSBUWVBFX0VYUFIpOwp9CgovKiBERUNMIGlzIGEgZGVjbGFyYXRpb24gZm9yIGFuIG92ZXJsb2FkZWQgb3BlcmF0b3IuICBSZXR1cm5zIHRydWUgaWYKICAgdGhlIGRlY2xhcmF0aW9uIGlzIHZhbGlkOyBmYWxzZSBvdGhlcndpc2UuICBJZiBDT01QTEFJTiBpcyB0cnVlLAogICBlcnJvcnMgYXJlIGlzc3VlZCBmb3IgaW52YWxpZCBkZWNsYXJhdGlvbnMuICAqLwoKYm9vbApncm9rX29wX3Byb3BlcnRpZXMgKHRyZWUgZGVjbCwgYm9vbCBjb21wbGFpbikKewogIHRyZWUgYXJndHlwZXMgPSBUWVBFX0FSR19UWVBFUyAoVFJFRV9UWVBFIChkZWNsKSk7CiAgdHJlZSBhcmd0eXBlOwogIGludCBtZXRob2RwID0gKFRSRUVfQ09ERSAoVFJFRV9UWVBFIChkZWNsKSkgPT0gTUVUSE9EX1RZUEUpOwogIHRyZWUgbmFtZSA9IERFQ0xfTkFNRSAoZGVjbCk7CiAgZW51bSB0cmVlX2NvZGUgb3BlcmF0b3JfY29kZTsKICBpbnQgYXJpdHk7CiAgYm9vbCBvazsKICB0cmVlIGNsYXNzX3R5cGU7CgogIC8qIEFzc3VtZSB0aGF0IHRoZSBkZWNsYXJhdGlvbiBpcyB2YWxpZC4gICovCiAgb2sgPSB0cnVlOwoKICAvKiBDb3VudCB0aGUgbnVtYmVyIG9mIGFyZ3VtZW50cy4gICovCiAgZm9yIChhcmd0eXBlID0gYXJndHlwZXMsIGFyaXR5ID0gMDsKICAgICAgIGFyZ3R5cGUgJiYgYXJndHlwZSAhPSB2b2lkX2xpc3Rfbm9kZTsKICAgICAgIGFyZ3R5cGUgPSBUUkVFX0NIQUlOIChhcmd0eXBlKSkKICAgICsrYXJpdHk7CgogIGNsYXNzX3R5cGUgPSBERUNMX0NPTlRFWFQgKGRlY2wpOwogIGlmIChjbGFzc190eXBlICYmICFDTEFTU19UWVBFX1AgKGNsYXNzX3R5cGUpKQogICAgY2xhc3NfdHlwZSA9IE5VTExfVFJFRTsKCiAgaWYgKERFQ0xfQ09OVl9GTl9QIChkZWNsKSkKICAgIG9wZXJhdG9yX2NvZGUgPSBUWVBFX0VYUFI7CiAgZWxzZQogICAgZG8KICAgICAgewojZGVmaW5lIERFRl9PUEVSQVRPUihOQU1FLCBDT0RFLCBNQU5HTElORywgQVJJVFksIEFTU05fUCkJXAoJaWYgKGFuc2lfb3BuYW1lIChDT0RFKSA9PSBuYW1lKQkJCQlcCgkgIHsJCQkJCQkJXAoJICAgIG9wZXJhdG9yX2NvZGUgPSAoQ09ERSk7CQkJCVwKCSAgICBicmVhazsJCQkJCQlcCgkgIH0JCQkJCQkJXAoJZWxzZSBpZiAoYW5zaV9hc3NvcG5hbWUgKENPREUpID09IG5hbWUpCQkJXAoJICB7CQkJCQkJCVwKCSAgICBvcGVyYXRvcl9jb2RlID0gKENPREUpOwkJCQlcCgkgICAgREVDTF9BU1NJR05NRU5UX09QRVJBVE9SX1AgKGRlY2wpID0gMTsJCVwKCSAgICBicmVhazsJCQkJCQlcCgkgIH0KCiNpbmNsdWRlICJvcGVyYXRvcnMuZGVmIgojdW5kZWYgREVGX09QRVJBVE9SCgoJZ2NjX3VucmVhY2hhYmxlICgpOwogICAgICB9CiAgICB3aGlsZSAoMCk7CiAgZ2NjX2Fzc2VydCAob3BlcmF0b3JfY29kZSAhPSBMQVNUX0NQTFVTX1RSRUVfQ09ERSk7CiAgU0VUX09WRVJMT0FERURfT1BFUkFUT1JfQ09ERSAoZGVjbCwgb3BlcmF0b3JfY29kZSk7CgogIGlmIChjbGFzc190eXBlKQogICAgc3dpdGNoIChvcGVyYXRvcl9jb2RlKQogICAgICB7CiAgICAgIGNhc2UgTkVXX0VYUFI6CglUWVBFX0hBU19ORVdfT1BFUkFUT1IgKGNsYXNzX3R5cGUpID0gMTsKCWJyZWFrOwoKICAgICAgY2FzZSBERUxFVEVfRVhQUjoKCVRZUEVfR0VUU19ERUxFVEUgKGNsYXNzX3R5cGUpIHw9IDE7CglicmVhazsKCiAgICAgIGNhc2UgVkVDX05FV19FWFBSOgoJVFlQRV9IQVNfQVJSQVlfTkVXX09QRVJBVE9SIChjbGFzc190eXBlKSA9IDE7CglicmVhazsKCiAgICAgIGNhc2UgVkVDX0RFTEVURV9FWFBSOgoJVFlQRV9HRVRTX0RFTEVURSAoY2xhc3NfdHlwZSkgfD0gMjsKCWJyZWFrOwoKICAgICAgZGVmYXVsdDoKCWJyZWFrOwogICAgICB9CgogICAgLyogW2Jhc2ljLnN0ZC5keW5hbWljLmFsbG9jYXRpb25dLzE6CgogICAgICAgQSBwcm9ncmFtIGlzIGlsbC1mb3JtZWQgaWYgYW4gYWxsb2NhdGlvbiBmdW5jdGlvbiBpcyBkZWNsYXJlZAogICAgICAgaW4gYSBuYW1lc3BhY2Ugc2NvcGUgb3RoZXIgdGhhbiBnbG9iYWwgc2NvcGUgb3IgZGVjbGFyZWQgc3RhdGljCiAgICAgICBpbiBnbG9iYWwgc2NvcGUuCgogICAgICAgVGhlIHNhbWUgYWxzbyBob2xkcyB0cnVlIGZvciBkZWFsbG9jYXRpb24gZnVuY3Rpb25zLiAgKi8KICBpZiAob3BlcmF0b3JfY29kZSA9PSBORVdfRVhQUiB8fCBvcGVyYXRvcl9jb2RlID09IFZFQ19ORVdfRVhQUgogICAgICB8fCBvcGVyYXRvcl9jb2RlID09IERFTEVURV9FWFBSIHx8IG9wZXJhdG9yX2NvZGUgPT0gVkVDX0RFTEVURV9FWFBSKQogICAgewogICAgICBpZiAoREVDTF9OQU1FU1BBQ0VfU0NPUEVfUCAoZGVjbCkpCgl7CgkgIGlmIChDUF9ERUNMX0NPTlRFWFQgKGRlY2wpICE9IGdsb2JhbF9uYW1lc3BhY2UpCgkgICAgZXJyb3IgKCIlcUQgbWF5IG5vdCBiZSBkZWNsYXJlZCB3aXRoaW4gYSBuYW1lc3BhY2UiLCBkZWNsKTsKCSAgZWxzZSBpZiAoIVRSRUVfUFVCTElDIChkZWNsKSkKCSAgICBlcnJvciAoIiVxRCBtYXkgbm90IGJlIGRlY2xhcmVkIGFzIHN0YXRpYyIsIGRlY2wpOwoJfQogICAgfQoKICBpZiAob3BlcmF0b3JfY29kZSA9PSBORVdfRVhQUiB8fCBvcGVyYXRvcl9jb2RlID09IFZFQ19ORVdfRVhQUikKICAgIFRSRUVfVFlQRSAoZGVjbCkgPSBjb2VyY2VfbmV3X3R5cGUgKFRSRUVfVFlQRSAoZGVjbCkpOwogIGVsc2UgaWYgKG9wZXJhdG9yX2NvZGUgPT0gREVMRVRFX0VYUFIgfHwgb3BlcmF0b3JfY29kZSA9PSBWRUNfREVMRVRFX0VYUFIpCiAgICBUUkVFX1RZUEUgKGRlY2wpID0gY29lcmNlX2RlbGV0ZV90eXBlIChUUkVFX1RZUEUgKGRlY2wpKTsKICBlbHNlCiAgICB7CiAgICAgIC8qIEFuIG9wZXJhdG9yIGZ1bmN0aW9uIG11c3QgZWl0aGVyIGJlIGEgbm9uLXN0YXRpYyBtZW1iZXIgZnVuY3Rpb24KCSBvciBoYXZlIGF0IGxlYXN0IG9uZSBwYXJhbWV0ZXIgb2YgYSBjbGFzcywgYSByZWZlcmVuY2UgdG8gYSBjbGFzcywKCSBhbiBlbnVtZXJhdGlvbiwgb3IgYSByZWZlcmVuY2UgdG8gYW4gZW51bWVyYXRpb24uICAxMy40LjAuNiAqLwogICAgICBpZiAoISBtZXRob2RwIHx8IERFQ0xfU1RBVElDX0ZVTkNUSU9OX1AgKGRlY2wpKQoJewoJICBpZiAob3BlcmF0b3JfY29kZSA9PSBUWVBFX0VYUFIKCSAgICAgIHx8IG9wZXJhdG9yX2NvZGUgPT0gQ0FMTF9FWFBSCgkgICAgICB8fCBvcGVyYXRvcl9jb2RlID09IENPTVBPTkVOVF9SRUYKCSAgICAgIHx8IG9wZXJhdG9yX2NvZGUgPT0gQVJSQVlfUkVGCgkgICAgICB8fCBvcGVyYXRvcl9jb2RlID09IE5PUF9FWFBSKQoJICAgIGVycm9yICgiJXFEIG11c3QgYmUgYSBub25zdGF0aWMgbWVtYmVyIGZ1bmN0aW9uIiwgZGVjbCk7CgkgIGVsc2UKCSAgICB7CgkgICAgICB0cmVlIHA7CgoJICAgICAgaWYgKERFQ0xfU1RBVElDX0ZVTkNUSU9OX1AgKGRlY2wpKQoJCWVycm9yICgiJXFEIG11c3QgYmUgZWl0aGVyIGEgbm9uLXN0YXRpYyBtZW1iZXIgIgogICAgICAgICAgICAgICAgICAgICAgICJmdW5jdGlvbiBvciBhIG5vbi1tZW1iZXIgZnVuY3Rpb24iLCBkZWNsKTsKCgkgICAgICBmb3IgKHAgPSBhcmd0eXBlczsgcCAmJiBwICE9IHZvaWRfbGlzdF9ub2RlOyBwID0gVFJFRV9DSEFJTiAocCkpCgkJewoJCSAgdHJlZSBhcmcgPSBub25fcmVmZXJlbmNlIChUUkVFX1ZBTFVFIChwKSk7CgkJICAvKiBJU19BR0dSX1RZUEUsIHJhdGhlciB0aGFuIENMQVNTX1RZUEVfUCwgaXMgdXNlZAoJCSAgICAgYmVjYXVzZSB0aGVzZSBjaGVja3MgYXJlIHBlcmZvcm1lZCBldmVuIG9uCgkJICAgICB0ZW1wbGF0ZSBmdW5jdGlvbnMuICAqLwoJCSAgaWYgKElTX0FHR1JfVFlQRSAoYXJnKSB8fCBUUkVFX0NPREUgKGFyZykgPT0gRU5VTUVSQUxfVFlQRSkKCQkgICAgYnJlYWs7CgkJfQoKCSAgICAgIGlmICghcCB8fCBwID09IHZvaWRfbGlzdF9ub2RlKQoJCXsKCQkgIGlmICghY29tcGxhaW4pCgkJICAgIHJldHVybiBmYWxzZTsKCgkJICBlcnJvciAoIiVxRCBtdXN0IGhhdmUgYW4gYXJndW1lbnQgb2YgY2xhc3Mgb3IgIgoJCQkgImVudW1lcmF0ZWQgdHlwZSIsCgkJCSBkZWNsKTsKCQkgIG9rID0gZmFsc2U7CgkJfQoJICAgIH0KCX0KCiAgICAgIC8qIFRoZXJlIGFyZSBubyByZXN0cmljdGlvbnMgb24gdGhlIGFyZ3VtZW50cyB0byBhbiBvdmVybG9hZGVkCgkgIm9wZXJhdG9yICgpIi4gICovCiAgICAgIGlmIChvcGVyYXRvcl9jb2RlID09IENBTExfRVhQUikKCXJldHVybiBvazsKCiAgICAgIGlmIChJREVOVElGSUVSX1RZUEVOQU1FX1AgKG5hbWUpIAoJICAmJiAhIERFQ0xfVEVNUExBVEVfSU5GTyAoZGVjbCkKCSAgJiYgd2Fybl9jb252ZXJzaW9uCgkgIC8qIFdhcm4gb25seSBkZWNsYXJpbmcgdGhlIGZ1bmN0aW9uOyB0aGVyZSBpcyBubyBuZWVkIHRvCgkgICAgIHdhcm4gYWdhaW4gYWJvdXQgb3V0LW9mLWNsYXNzIGRlZmluaXRpb25zLiAgKi8KCSAgJiYgY2xhc3NfdHlwZSA9PSBjdXJyZW50X2NsYXNzX3R5cGUpCgl7CgkgIHRyZWUgdCA9IFRSRUVfVFlQRSAobmFtZSk7CgkgIGludCByZWYgPSAoVFJFRV9DT0RFICh0KSA9PSBSRUZFUkVOQ0VfVFlQRSk7CgkgIGNvbnN0IGNoYXIgKndoYXQgPSAwOwoKCSAgaWYgKHJlZikKCSAgICB0ID0gVFlQRV9NQUlOX1ZBUklBTlQgKFRSRUVfVFlQRSAodCkpOwoKCSAgaWYgKFRSRUVfQ09ERSAodCkgPT0gVk9JRF9UWVBFKQoJICAgIHdoYXQgPSAidm9pZCI7CgkgIGVsc2UgaWYgKGNsYXNzX3R5cGUpCgkgICAgewoJICAgICAgaWYgKHQgPT0gY3VycmVudF9jbGFzc190eXBlKQoJCXdoYXQgPSAidGhlIHNhbWUgdHlwZSI7CgkgICAgICAvKiBEb24ndCBmb3JjZSB0IHRvIGJlIGNvbXBsZXRlIGhlcmUuICAqLwoJICAgICAgZWxzZSBpZiAoSVNfQUdHUl9UWVBFICh0KQoJCSAgICAgICAmJiBDT01QTEVURV9UWVBFX1AgKHQpCgkJICAgICAgICYmIERFUklWRURfRlJPTV9QICh0LCBjbGFzc190eXBlKSkKCQl3aGF0ID0gImEgYmFzZSBjbGFzcyI7CgkgICAgfQoKCSAgaWYgKHdoYXQpCgkgICAgd2FybmluZyAoImNvbnZlcnNpb24gdG8gJXMlcyB3aWxsIG5ldmVyIHVzZSBhIHR5cGUgIgoJCSAgICAgImNvbnZlcnNpb24gb3BlcmF0b3IiLAoJCSAgICAgcmVmID8gImEgcmVmZXJlbmNlIHRvICIgOiAiIiwgd2hhdCk7Cgl9CiAgICAgIGlmIChvcGVyYXRvcl9jb2RlID09IENPTkRfRVhQUikKCXsKCSAgLyogMTMuNC4wLjMgKi8KCSAgZXJyb3IgKCJJU08gQysrIHByb2hpYml0cyBvdmVybG9hZGluZyBvcGVyYXRvciA/OiIpOwoJfQogICAgICBlbHNlIGlmIChhbWJpX29wX3AgKG9wZXJhdG9yX2NvZGUpKQoJewoJICBpZiAoYXJpdHkgPT0gMSkKCSAgICAvKiBXZSBwaWNrIHRoZSBvbmUtYXJndW1lbnQgb3BlcmF0b3IgY29kZXMgYnkgZGVmYXVsdCwgc28KCSAgICAgICB3ZSBkb24ndCBoYXZlIHRvIGNoYW5nZSBhbnl0aGluZy4gICovCgkgICAgOwoJICBlbHNlIGlmIChhcml0eSA9PSAyKQoJICAgIHsKCSAgICAgIC8qIElmIHdlIHRob3VnaHQgdGhpcyB3YXMgYSB1bmFyeSBvcGVyYXRvciwgd2Ugbm93IGtub3cKCQkgaXQgdG8gYmUgYSBiaW5hcnkgb3BlcmF0b3IuICAqLwoJICAgICAgc3dpdGNoIChvcGVyYXRvcl9jb2RlKQoJCXsKCQljYXNlIElORElSRUNUX1JFRjoKCQkgIG9wZXJhdG9yX2NvZGUgPSBNVUxUX0VYUFI7CgkJICBicmVhazsKCgkJY2FzZSBBRERSX0VYUFI6CgkJICBvcGVyYXRvcl9jb2RlID0gQklUX0FORF9FWFBSOwoJCSAgYnJlYWs7CgoJCWNhc2UgQ09OVkVSVF9FWFBSOgoJCSAgb3BlcmF0b3JfY29kZSA9IFBMVVNfRVhQUjsKCQkgIGJyZWFrOwoKCQljYXNlIE5FR0FURV9FWFBSOgoJCSAgb3BlcmF0b3JfY29kZSA9IE1JTlVTX0VYUFI7CgkJICBicmVhazsKCgkJY2FzZSBQUkVJTkNSRU1FTlRfRVhQUjoKCQkgIG9wZXJhdG9yX2NvZGUgPSBQT1NUSU5DUkVNRU5UX0VYUFI7CgkJICBicmVhazsKCgkJY2FzZSBQUkVERUNSRU1FTlRfRVhQUjoKCQkgIG9wZXJhdG9yX2NvZGUgPSBQT1NUREVDUkVNRU5UX0VYUFI7CgkJICBicmVhazsKCgkJZGVmYXVsdDoKCQkgIGdjY191bnJlYWNoYWJsZSAoKTsKCQl9CgoJICAgICAgU0VUX09WRVJMT0FERURfT1BFUkFUT1JfQ09ERSAoZGVjbCwgb3BlcmF0b3JfY29kZSk7CgoJICAgICAgaWYgKChvcGVyYXRvcl9jb2RlID09IFBPU1RJTkNSRU1FTlRfRVhQUgoJCSAgIHx8IG9wZXJhdG9yX2NvZGUgPT0gUE9TVERFQ1JFTUVOVF9FWFBSKQoJCSAgJiYgISBwcm9jZXNzaW5nX3RlbXBsYXRlX2RlY2wKCQkgICYmICEgc2FtZV90eXBlX3AgKFRSRUVfVkFMVUUgKFRSRUVfQ0hBSU4gKGFyZ3R5cGVzKSksIGludGVnZXJfdHlwZV9ub2RlKSkKCQl7CgkJICBpZiAobWV0aG9kcCkKCQkgICAgZXJyb3IgKCJwb3N0Zml4ICVxRCBtdXN0IHRha2UgJTxpbnQlPiBhcyBpdHMgYXJndW1lbnQiLAoJCQkgICAgICBkZWNsKTsKCQkgIGVsc2UKCQkgICAgZXJyb3IKCQkgICAgICAoInBvc3RmaXggJXFEIG11c3QgdGFrZSAlPGludCU+IGFzIGl0cyBzZWNvbmQgYXJndW1lbnQiLAoJCSAgICAgICBkZWNsKTsKCQl9CgkgICAgfQoJICBlbHNlCgkgICAgewoJICAgICAgaWYgKG1ldGhvZHApCgkJZXJyb3IgKCIlcUQgbXVzdCB0YWtlIGVpdGhlciB6ZXJvIG9yIG9uZSBhcmd1bWVudCIsIGRlY2wpOwoJICAgICAgZWxzZQoJCWVycm9yICgiJXFEIG11c3QgdGFrZSBlaXRoZXIgb25lIG9yIHR3byBhcmd1bWVudHMiLCBkZWNsKTsKCSAgICB9CgoJICAvKiBNb3JlIEVmZmVjdGl2ZSBDKysgcnVsZSA2LiAgKi8KCSAgaWYgKHdhcm5fZWNwcAoJICAgICAgJiYgKG9wZXJhdG9yX2NvZGUgPT0gUE9TVElOQ1JFTUVOVF9FWFBSCgkJICB8fCBvcGVyYXRvcl9jb2RlID09IFBPU1RERUNSRU1FTlRfRVhQUgoJCSAgfHwgb3BlcmF0b3JfY29kZSA9PSBQUkVJTkNSRU1FTlRfRVhQUgoJCSAgfHwgb3BlcmF0b3JfY29kZSA9PSBQUkVERUNSRU1FTlRfRVhQUikpCgkgICAgewoJICAgICAgdHJlZSBhcmcgPSBUUkVFX1ZBTFVFIChhcmd0eXBlcyk7CgkgICAgICB0cmVlIHJldCA9IFRSRUVfVFlQRSAoVFJFRV9UWVBFIChkZWNsKSk7CgkgICAgICBpZiAobWV0aG9kcCB8fCBUUkVFX0NPREUgKGFyZykgPT0gUkVGRVJFTkNFX1RZUEUpCgkJYXJnID0gVFJFRV9UWVBFIChhcmcpOwoJICAgICAgYXJnID0gVFlQRV9NQUlOX1ZBUklBTlQgKGFyZyk7CgkgICAgICBpZiAob3BlcmF0b3JfY29kZSA9PSBQUkVJTkNSRU1FTlRfRVhQUgoJCSAgfHwgb3BlcmF0b3JfY29kZSA9PSBQUkVERUNSRU1FTlRfRVhQUikKCQl7CgkJICBpZiAoVFJFRV9DT0RFIChyZXQpICE9IFJFRkVSRU5DRV9UWVBFCgkJICAgICAgfHwgIXNhbWVfdHlwZV9wIChUWVBFX01BSU5fVkFSSUFOVCAoVFJFRV9UWVBFIChyZXQpKSwKCQkJCSAgICAgICBhcmcpKQoJCSAgICB3YXJuaW5nICgicHJlZml4ICVxRCBzaG91bGQgcmV0dXJuICVxVCIsIGRlY2wsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnVpbGRfcmVmZXJlbmNlX3R5cGUgKGFyZykpOwoJCX0KCSAgICAgIGVsc2UKCQl7CgkJICBpZiAoIXNhbWVfdHlwZV9wIChUWVBFX01BSU5fVkFSSUFOVCAocmV0KSwgYXJnKSkKCQkgICAgd2FybmluZyAoInBvc3RmaXggJXFEIHNob3VsZCByZXR1cm4gJXFUIiwgZGVjbCwgYXJnKTsKCQl9CgkgICAgfQoJfQogICAgICBlbHNlIGlmICh1bmFyeV9vcF9wIChvcGVyYXRvcl9jb2RlKSkKCXsKCSAgaWYgKGFyaXR5ICE9IDEpCgkgICAgewoJICAgICAgaWYgKG1ldGhvZHApCgkJZXJyb3IgKCIlcUQgbXVzdCB0YWtlICU8dm9pZCU+IiwgZGVjbCk7CgkgICAgICBlbHNlCgkJZXJyb3IgKCIlcUQgbXVzdCB0YWtlIGV4YWN0bHkgb25lIGFyZ3VtZW50IiwgZGVjbCk7CgkgICAgfQoJfQogICAgICBlbHNlIC8qIGlmIChiaW5hcnlfb3BfcCAob3BlcmF0b3JfY29kZSkpICovCgl7CgkgIGlmIChhcml0eSAhPSAyKQoJICAgIHsKCSAgICAgIGlmIChtZXRob2RwKQoJCWVycm9yICgiJXFEIG11c3QgdGFrZSBleGFjdGx5IG9uZSBhcmd1bWVudCIsIGRlY2wpOwoJICAgICAgZWxzZQoJCWVycm9yICgiJXFEIG11c3QgdGFrZSBleGFjdGx5IHR3byBhcmd1bWVudHMiLCBkZWNsKTsKCSAgICB9CgoJICAvKiBNb3JlIEVmZmVjdGl2ZSBDKysgcnVsZSA3LiAgKi8KCSAgaWYgKHdhcm5fZWNwcAoJICAgICAgJiYgKG9wZXJhdG9yX2NvZGUgPT0gVFJVVEhfQU5ESUZfRVhQUgoJCSAgfHwgb3BlcmF0b3JfY29kZSA9PSBUUlVUSF9PUklGX0VYUFIKCQkgIHx8IG9wZXJhdG9yX2NvZGUgPT0gQ09NUE9VTkRfRVhQUikpCgkgICAgd2FybmluZyAoInVzZXItZGVmaW5lZCAlcUQgYWx3YXlzIGV2YWx1YXRlcyBib3RoIGFyZ3VtZW50cyIsCiAgICAgICAgICAgICAgICAgICAgIGRlY2wpOwoJfQoKICAgICAgLyogRWZmZWN0aXZlIEMrKyBydWxlIDIzLiAgKi8KICAgICAgaWYgKHdhcm5fZWNwcAoJICAmJiBhcml0eSA9PSAyCgkgICYmICFERUNMX0FTU0lHTk1FTlRfT1BFUkFUT1JfUCAoZGVjbCkKCSAgJiYgKG9wZXJhdG9yX2NvZGUgPT0gUExVU19FWFBSCgkgICAgICB8fCBvcGVyYXRvcl9jb2RlID09IE1JTlVTX0VYUFIKCSAgICAgIHx8IG9wZXJhdG9yX2NvZGUgPT0gVFJVTkNfRElWX0VYUFIKCSAgICAgIHx8IG9wZXJhdG9yX2NvZGUgPT0gTVVMVF9FWFBSCgkgICAgICB8fCBvcGVyYXRvcl9jb2RlID09IFRSVU5DX01PRF9FWFBSKQoJICAmJiBUUkVFX0NPREUgKFRSRUVfVFlQRSAoVFJFRV9UWVBFIChkZWNsKSkpID09IFJFRkVSRU5DRV9UWVBFKQoJd2FybmluZyAoIiVxRCBzaG91bGQgcmV0dXJuIGJ5IHZhbHVlIiwgZGVjbCk7CgogICAgICAvKiBbb3Zlci5vcGVyXS84ICovCiAgICAgIGZvciAoOyBhcmd0eXBlcyAmJiBhcmd0eXBlcyAhPSB2b2lkX2xpc3Rfbm9kZTsKICAgICAgICAgIGFyZ3R5cGVzID0gVFJFRV9DSEFJTiAoYXJndHlwZXMpKQogICAgICAgIGlmIChUUkVFX1BVUlBPU0UgKGFyZ3R5cGVzKSkKICAgICAgICAgIHsKICAgICAgICAgICAgVFJFRV9QVVJQT1NFIChhcmd0eXBlcykgPSBOVUxMX1RSRUU7CiAgICAgICAgICAgIGlmIChvcGVyYXRvcl9jb2RlID09IFBPU1RJTkNSRU1FTlRfRVhQUgoJCXx8IG9wZXJhdG9yX2NvZGUgPT0gUE9TVERFQ1JFTUVOVF9FWFBSKQogICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGlmIChwZWRhbnRpYykKICAgICAgICAgICAgICAgICAgcGVkd2FybiAoIiVxRCBjYW5ub3QgaGF2ZSBkZWZhdWx0IGFyZ3VtZW50cyIsIGRlY2wpOwogICAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgIGVycm9yICgiJXFEIGNhbm5vdCBoYXZlIGRlZmF1bHQgYXJndW1lbnRzIiwgZGVjbCk7CiAgICAgICAgICB9CgogICAgfQoKICByZXR1cm4gb2s7Cn0KDAovKiBSZXR1cm4gYSBzdHJpbmcgZ2l2aW5nIHRoZSBrZXl3b3JkIGFzc29jaWF0ZSB3aXRoIENPREUuICAqLwoKc3RhdGljIGNvbnN0IGNoYXIgKgp0YWdfbmFtZSAoZW51bSB0YWdfdHlwZXMgY29kZSkKewogIHN3aXRjaCAoY29kZSkKICAgIHsKICAgIGNhc2UgcmVjb3JkX3R5cGU6CiAgICAgIHJldHVybiAic3RydWN0IjsKICAgIGNhc2UgY2xhc3NfdHlwZToKICAgICAgcmV0dXJuICJjbGFzcyI7CiAgICBjYXNlIHVuaW9uX3R5cGU6CiAgICAgIHJldHVybiAidW5pb24iOwogICAgY2FzZSBlbnVtX3R5cGU6CiAgICAgIHJldHVybiAiZW51bSI7CiAgICBjYXNlIHR5cGVuYW1lX3R5cGU6CiAgICAgIHJldHVybiAidHlwZW5hbWUiOwogICAgZGVmYXVsdDoKICAgICAgZ2NjX3VucmVhY2hhYmxlICgpOwogICAgfQp9CgovKiBOYW1lIGxvb2t1cCBpbiBhbiBlbGFib3JhdGVkLXR5cGUtc3BlY2lmaWVyIChhZnRlciB0aGUga2V5d29yZAogICBpbmRpY2F0ZWQgYnkgVEFHX0NPREUpIGhhcyBmb3VuZCB0aGUgVFlQRV9ERUNMIERFQ0wuICBJZiB0aGUKICAgZWxhYm9yYXRlZC10eXBlLXNwZWNpZmllciBpcyBpbnZhbGlkLCBpc3N1ZSBhIGRpYWdub3N0aWMgYW5kIHJldHVybgogICBlcnJvcl9tYXJrX25vZGU7IG90aGVyd2lzZSwgcmV0dXJuIHRoZSAqX1RZUEUgdG8gd2hpY2ggaXQgcmVmZXJyZWQuCiAgIElmIEFMTE9XX1RFTVBMQVRFX1AgaXMgdHJ1ZSwgVFlQRSBtYXkgYmUgYSBjbGFzcyB0ZW1wbGF0ZS4gICovCgp0cmVlCmNoZWNrX2VsYWJvcmF0ZWRfdHlwZV9zcGVjaWZpZXIgKGVudW0gdGFnX3R5cGVzIHRhZ19jb2RlLAoJCQkJIHRyZWUgZGVjbCwKCQkJCSBib29sIGFsbG93X3RlbXBsYXRlX3ApCnsKICB0cmVlIHR5cGU7CgogIC8qIEluIHRoZSBjYXNlIG9mOgoKICAgICAgIHN0cnVjdCBTIHsgc3RydWN0IFMgKnA7IH07CgogICAgIG5hbWUgbG9va3VwIHdpbGwgZmluZCB0aGUgVFlQRV9ERUNMIGZvciB0aGUgaW1wbGljaXQgIlM6OlMiCiAgICAgdHlwZWRlZi4gIEFkanVzdCBmb3IgdGhhdCBoZXJlLiAgKi8KICBpZiAoREVDTF9TRUxGX1JFRkVSRU5DRV9QIChkZWNsKSkKICAgIGRlY2wgPSBUWVBFX05BTUUgKFRSRUVfVFlQRSAoZGVjbCkpOwoKICB0eXBlID0gVFJFRV9UWVBFIChkZWNsKTsKCiAgLyogQ2hlY2sgVEVNUExBVEVfVFlQRV9QQVJNIGZpcnN0IGJlY2F1c2UgREVDTF9JTVBMSUNJVF9UWVBFREVGX1AKICAgICBpcyBmYWxzZSBmb3IgdGhpcyBjYXNlIGFzIHdlbGwuICAqLwogIGlmIChUUkVFX0NPREUgKHR5cGUpID09IFRFTVBMQVRFX1RZUEVfUEFSTSkKICAgIHsKICAgICAgZXJyb3IgKCJ1c2luZyB0ZW1wbGF0ZSB0eXBlIHBhcmFtZXRlciAlcVQgYWZ0ZXIgJXFzIiwKCSAgICAgdHlwZSwgdGFnX25hbWUgKHRhZ19jb2RlKSk7CiAgICAgIHJldHVybiBlcnJvcl9tYXJrX25vZGU7CiAgICB9CiAgLyogICBbZGNsLnR5cGUuZWxhYl0KCiAgICAgICBJZiB0aGUgaWRlbnRpZmllciByZXNvbHZlcyB0byBhIHR5cGVkZWYtbmFtZSBvciBhIHRlbXBsYXRlCiAgICAgICB0eXBlLXBhcmFtZXRlciwgdGhlIGVsYWJvcmF0ZWQtdHlwZS1zcGVjaWZpZXIgaXMgaWxsLWZvcm1lZC4KCiAgICAgSW4gb3RoZXIgd29yZHMsIHRoZSBvbmx5IGxlZ2l0aW1hdGUgZGVjbGFyYXRpb24gdG8gdXNlIGluIHRoZQogICAgIGVsYWJvcmF0ZWQgdHlwZSBzcGVjaWZpZXIgaXMgdGhlIGltcGxpY2l0IHR5cGVkZWYgY3JlYXRlZCB3aGVuCiAgICAgdGhlIHR5cGUgaXMgZGVjbGFyZWQuICAqLwogIGVsc2UgaWYgKCFERUNMX0lNUExJQ0lUX1RZUEVERUZfUCAoZGVjbCkKCSAgICYmIHRhZ19jb2RlICE9IHR5cGVuYW1lX3R5cGUpCiAgICB7CiAgICAgIGVycm9yICgidXNpbmcgdHlwZWRlZi1uYW1lICVxRCBhZnRlciAlcXMiLCBkZWNsLCB0YWdfbmFtZSAodGFnX2NvZGUpKTsKICAgICAgY3BfZXJyb3JfYXQgKCIlcUQgaGFzIGEgcHJldmlvdXMgZGVjbGFyYXRpb24gaGVyZSIsIGRlY2wpOwogICAgICByZXR1cm4gZXJyb3JfbWFya19ub2RlOwogICAgfQogIGVsc2UgaWYgKFRSRUVfQ09ERSAodHlwZSkgIT0gUkVDT1JEX1RZUEUKCSAgICYmIFRSRUVfQ09ERSAodHlwZSkgIT0gVU5JT05fVFlQRQoJICAgJiYgdGFnX2NvZGUgIT0gZW51bV90eXBlCgkgICAmJiB0YWdfY29kZSAhPSB0eXBlbmFtZV90eXBlKQogICAgewogICAgICBlcnJvciAoIiVxVCByZWZlcnJlZCB0byBhcyAlcXMiLCB0eXBlLCB0YWdfbmFtZSAodGFnX2NvZGUpKTsKICAgICAgY3BfZXJyb3JfYXQgKCIlcVQgaGFzIGEgcHJldmlvdXMgZGVjbGFyYXRpb24gaGVyZSIsIHR5cGUpOwogICAgICByZXR1cm4gZXJyb3JfbWFya19ub2RlOwogICAgfQogIGVsc2UgaWYgKFRSRUVfQ09ERSAodHlwZSkgIT0gRU5VTUVSQUxfVFlQRQoJICAgJiYgdGFnX2NvZGUgPT0gZW51bV90eXBlCgkgICAmJiB0YWdfY29kZSAhPSB0eXBlbmFtZV90eXBlKQogICAgewogICAgICBlcnJvciAoIiVxVCByZWZlcnJlZCB0byBhcyBlbnVtIiwgdHlwZSk7CiAgICAgIGNwX2Vycm9yX2F0ICgiJXFUIGhhcyBhIHByZXZpb3VzIGRlY2xhcmF0aW9uIGhlcmUiLCB0eXBlKTsKICAgICAgcmV0dXJuIGVycm9yX21hcmtfbm9kZTsKICAgIH0KICBlbHNlIGlmICghYWxsb3dfdGVtcGxhdGVfcAoJICAgJiYgVFJFRV9DT0RFICh0eXBlKSA9PSBSRUNPUkRfVFlQRQoJICAgJiYgQ0xBU1NUWVBFX0lTX1RFTVBMQVRFICh0eXBlKSkKICAgIHsKICAgICAgLyogSWYgYSBjbGFzcyB0ZW1wbGF0ZSBhcHBlYXJzIGFzIGVsYWJvcmF0ZWQgdHlwZSBzcGVjaWZpZXIKCSB3aXRob3V0IGEgdGVtcGxhdGUgaGVhZGVyIHN1Y2ggYXM6CgoJICAgdGVtcGxhdGUgPGNsYXNzIFQ+IGNsYXNzIEMge307CgkgICB2b2lkIGYoY2xhc3MgQyk7CQkvLyBObyB0ZW1wbGF0ZSBoZWFkZXIgaGVyZQoKCSB0aGVuIHRoZSByZXF1aXJlZCB0ZW1wbGF0ZSBhcmd1bWVudCBpcyBtaXNzaW5nLiAgKi8KICAgICAgZXJyb3IgKCJ0ZW1wbGF0ZSBhcmd1bWVudCByZXF1aXJlZCBmb3IgJTwlcyAlVCU+IiwKCSAgICAgdGFnX25hbWUgKHRhZ19jb2RlKSwKCSAgICAgREVDTF9OQU1FIChDTEFTU1RZUEVfVElfVEVNUExBVEUgKHR5cGUpKSk7CiAgICAgIHJldHVybiBlcnJvcl9tYXJrX25vZGU7CiAgICB9CgogIHJldHVybiB0eXBlOwp9CgovKiBMb29rdXAgTkFNRSBpbiBlbGFib3JhdGUgdHlwZSBzcGVjaWZpZXIgaW4gc2NvcGUgYWNjb3JkaW5nIHRvCiAgIFNDT1BFIGFuZCBpc3N1ZSBkaWFnbm9zdGljcyBpZiBuZWNlc3NhcnkuCiAgIFJldHVybiAqX1RZUEUgbm9kZSB1cG9uIHN1Y2Nlc3MsIE5VTExfVFJFRSB3aGVuIHRoZSBOQU1FIGlzIG5vdAogICBmb3VuZCwgYW5kIEVSUk9SX01BUktfTk9ERSBmb3IgdHlwZSBlcnJvci4gICovCgpzdGF0aWMgdHJlZQpsb29rdXBfYW5kX2NoZWNrX3RhZyAoZW51bSB0YWdfdHlwZXMgdGFnX2NvZGUsIHRyZWUgbmFtZSwKCQkgICAgICB0YWdfc2NvcGUgc2NvcGUsIGJvb2wgdGVtcGxhdGVfaGVhZGVyX3ApCnsKICB0cmVlIHQ7CiAgdHJlZSBkZWNsOwogIGlmIChzY29wZSA9PSB0c19nbG9iYWwpCiAgICAvKiBBUFBMRSBMT0NBTCA0MTg0MjAzICovCiAgICBkZWNsID0gbG9va3VwX25hbWUgKG5hbWUsIDIpOwogIGVsc2UKICAgIGRlY2wgPSBsb29rdXBfdHlwZV9zY29wZSAobmFtZSwgc2NvcGUpOwoKICBpZiAoZGVjbCAmJiBERUNMX0NMQVNTX1RFTVBMQVRFX1AgKGRlY2wpKQogICAgZGVjbCA9IERFQ0xfVEVNUExBVEVfUkVTVUxUIChkZWNsKTsKCiAgaWYgKGRlY2wgJiYgVFJFRV9DT0RFIChkZWNsKSA9PSBUWVBFX0RFQ0wpCiAgICB7CiAgICAgIC8qIExvb2sgZm9yIGludmFsaWQgbmVzdGVkIHR5cGU6CgkgICBjbGFzcyBDIHsKCSAgICAgY2xhc3MgQyB7fTsKCSAgIH07ICAqLwogICAgICBpZiAoc2NvcGUgPT0gdHNfY3VycmVudCAmJiBERUNMX1NFTEZfUkVGRVJFTkNFX1AgKGRlY2wpKQoJewoJICBlcnJvciAoIiVxRCBoYXMgdGhlIHNhbWUgbmFtZSBhcyB0aGUgY2xhc3MgaW4gd2hpY2ggaXQgaXMgIgoJCSAiZGVjbGFyZWQiLAoJCSBkZWNsKTsKCSAgcmV0dXJuIGVycm9yX21hcmtfbm9kZTsKCX0KCiAgICAgIC8qIFR3byBjYXNlcyB3ZSBuZWVkIHRvIGNvbnNpZGVyIHdoZW4gZGVjaWRpbmcgaWYgYSBjbGFzcwoJIHRlbXBsYXRlIGlzIGFsbG93ZWQgYXMgYW4gZWxhYm9yYXRlZCB0eXBlIHNwZWNpZmllcjoKCSAxLiBJdCBpcyBhIHNlbGYgcmVmZXJlbmNlIHRvIGl0cyBvd24gY2xhc3MuCgkgMi4gSXQgY29tZXMgd2l0aCBhIHRlbXBsYXRlIGhlYWRlci4KCgkgRm9yIGV4YW1wbGU6CgoJICAgdGVtcGxhdGUgPGNsYXNzIFQ+IGNsYXNzIEMgewoJICAgICBjbGFzcyBDICpjMTsJCS8vIERFQ0xfU0VMRl9SRUZFUkVOQ0VfUCBpcyB0cnVlCgkgICAgIGNsYXNzIEQ7CgkgICB9OwoJICAgdGVtcGxhdGUgPGNsYXNzIFU+IGNsYXNzIEM7IC8vIHRlbXBsYXRlX2hlYWRlcl9wIGlzIHRydWUKCSAgIHRlbXBsYXRlIDxjbGFzcyBUPiBjbGFzcyBDPFQ+OjpEIHsKCSAgICAgY2xhc3MgQyAqYzI7CQkvLyBERUNMX1NFTEZfUkVGRVJFTkNFX1AgaXMgdHJ1ZQoJICAgfTsgICovCgogICAgICB0ID0gY2hlY2tfZWxhYm9yYXRlZF90eXBlX3NwZWNpZmllciAodGFnX2NvZGUsCgkJCQkJICAgZGVjbCwKCQkJCQkgICB0ZW1wbGF0ZV9oZWFkZXJfcAoJCQkJCSAgIHwgREVDTF9TRUxGX1JFRkVSRU5DRV9QIChkZWNsKSk7CiAgICAgIHJldHVybiB0OwogICAgfQogIGVsc2UKICAgIHJldHVybiBOVUxMX1RSRUU7Cn0KCi8qIEdldCB0aGUgc3RydWN0LCBlbnVtIG9yIHVuaW9uIChUQUdfQ09ERSBzYXlzIHdoaWNoKSB3aXRoIHRhZyBOQU1FLgogICBEZWZpbmUgdGhlIHRhZyBhcyBhIGZvcndhcmQtcmVmZXJlbmNlIGlmIGl0IGlzIG5vdCBkZWZpbmVkLgoKICAgSWYgYSBkZWNsYXJhdGlvbiBpcyBnaXZlbiwgcHJvY2VzcyBpdCBoZXJlLCBhbmQgcmVwb3J0IGFuIGVycm9yIGlmCiAgIG11bHRpcGxlIGRlY2xhcmF0aW9ucyBhcmUgbm90IGlkZW50aWNhbC4KCiAgIFNDT1BFIGlzIFRTX0NVUlJFTlQgd2hlbiB0aGlzIGlzIGFsc28gYSBkZWZpbml0aW9uLiAgT25seSBsb29rIGluCiAgIHRoZSBjdXJyZW50IGZyYW1lIGZvciB0aGUgbmFtZSAoc2luY2UgQysrIGFsbG93cyBuZXcgbmFtZXMgaW4gYW55CiAgIHNjb3BlLikgIEl0IGlzIFRTX1dJVEhJTl9FTkNMT1NJTkdfTk9OX0NMQVNTIGlmIHRoaXMgaXMgYSBmcmllbmQKICAgZGVjbGFyYXRpb24uICBPbmx5IGxvb2sgYmVnaW5uaW5nIGZyb20gdGhlIGN1cnJlbnQgc2NvcGUgb3V0d2FyZCB1cAogICB0aWxsIHRoZSBuZWFyZXN0IG5vbi1jbGFzcyBzY29wZS4gIE90aGVyd2lzZSBpdCBpcyBUU19HTE9CQUwuCgogICBURU1QTEFURV9IRUFERVJfUCBpcyB0cnVlIHdoZW4gdGhpcyBkZWNsYXJhdGlvbiBpcyBwcmVjZWRlZCBieQogICBhIHNldCBvZiB0ZW1wbGF0ZSBwYXJhbWV0ZXJzLiAgKi8KCnRyZWUKeHJlZl90YWcgKGVudW0gdGFnX3R5cGVzIHRhZ19jb2RlLCB0cmVlIG5hbWUsCgkgIHRhZ19zY29wZSBzY29wZSwgYm9vbCB0ZW1wbGF0ZV9oZWFkZXJfcCkKewogIGVudW0gdHJlZV9jb2RlIGNvZGU7CiAgdHJlZSB0OwogIHRyZWUgY29udGV4dCA9IE5VTExfVFJFRTsKCiAgdGltZXZhcl9wdXNoIChUVl9OQU1FX0xPT0tVUCk7CgogIGdjY19hc3NlcnQgKFRSRUVfQ09ERSAobmFtZSkgPT0gSURFTlRJRklFUl9OT0RFKTsKCiAgc3dpdGNoICh0YWdfY29kZSkKICAgIHsKICAgIGNhc2UgcmVjb3JkX3R5cGU6CiAgICBjYXNlIGNsYXNzX3R5cGU6CiAgICAgIGNvZGUgPSBSRUNPUkRfVFlQRTsKICAgICAgYnJlYWs7CiAgICBjYXNlIHVuaW9uX3R5cGU6CiAgICAgIGNvZGUgPSBVTklPTl9UWVBFOwogICAgICBicmVhazsKICAgIGNhc2UgZW51bV90eXBlOgogICAgICBjb2RlID0gRU5VTUVSQUxfVFlQRTsKICAgICAgYnJlYWs7CiAgICBkZWZhdWx0OgogICAgICBnY2NfdW5yZWFjaGFibGUgKCk7CiAgICB9CgogIC8qIEluIGNhc2Ugb2YgYW5vbnltb3VzIG5hbWUsIHhyZWZfdGFnIGlzIG9ubHkgY2FsbGVkIHRvCiAgICAgbWFrZSB0eXBlIG5vZGUgYW5kIHB1c2ggbmFtZS4gIE5hbWUgbG9va3VwIGlzIG5vdCByZXF1aXJlZC4gICovCiAgaWYgKEFOT05fQUdHUk5BTUVfUCAobmFtZSkpCiAgICB0ID0gTlVMTF9UUkVFOwogIGVsc2UKICAgIHQgPSBsb29rdXBfYW5kX2NoZWNrX3RhZyAgKHRhZ19jb2RlLCBuYW1lLAoJCQkgICAgICAgc2NvcGUsIHRlbXBsYXRlX2hlYWRlcl9wKTsKCiAgaWYgKHQgPT0gZXJyb3JfbWFya19ub2RlKQogICAgUE9QX1RJTUVWQVJfQU5EX1JFVFVSTiAoVFZfTkFNRV9MT09LVVAsIGVycm9yX21hcmtfbm9kZSk7CgogIGlmIChzY29wZSAhPSB0c19jdXJyZW50ICYmIHQgJiYgY3VycmVudF9jbGFzc190eXBlCiAgICAgICYmIHRlbXBsYXRlX2NsYXNzX2RlcHRoIChjdXJyZW50X2NsYXNzX3R5cGUpCiAgICAgICYmIHRlbXBsYXRlX2hlYWRlcl9wKQogICAgewogICAgICAvKiBTaW5jZSBTQ09QRSBpcyBub3QgVFNfQ1VSUkVOVCwgd2UgYXJlIG5vdCBsb29raW5nIGF0IGEKCSBkZWZpbml0aW9uIG9mIHRoaXMgdGFnLiAgU2luY2UsIGluIGFkZGl0aW9uLCB3ZSBhcmUgY3VycmVudGx5CgkgcHJvY2Vzc2luZyBhIChtZW1iZXIpIHRlbXBsYXRlIGRlY2xhcmF0aW9uIG9mIGEgdGVtcGxhdGUKCSBjbGFzcywgd2UgbXVzdCBiZSB2ZXJ5IGNhcmVmdWw7IGNvbnNpZGVyOgoKCSAgIHRlbXBsYXRlIDxjbGFzcyBYPgoJICAgc3RydWN0IFMxCgoJICAgdGVtcGxhdGUgPGNsYXNzIFU+CgkgICBzdHJ1Y3QgUzIKCSAgIHsgdGVtcGxhdGUgPGNsYXNzIFY+CgkgICBmcmllbmQgc3RydWN0IFMxOyB9OwoKCSBIZXJlLCB0aGUgUzI6OlMxIGRlY2xhcmF0aW9uIHNob3VsZCBub3QgYmUgY29uZnVzZWQgd2l0aCB0aGUKCSBvdXRlciBkZWNsYXJhdGlvbi4gIEluIHBhcnRpY3VsYXIsIHRoZSBpbm5lciB2ZXJzaW9uIHNob3VsZAoJIGhhdmUgYSB0ZW1wbGF0ZSBwYXJhbWV0ZXIgb2YgbGV2ZWwgMiwgbm90IGxldmVsIDEuICBUaGlzCgkgd291bGQgYmUgcGFydGljdWxhcmx5IGltcG9ydGFudCBpZiB0aGUgbWVtYmVyIGRlY2xhcmF0aW9uCgkgd2VyZSBpbnN0ZWFkOgoKCSAgIHRlbXBsYXRlIDxjbGFzcyBWID0gVT4gZnJpZW5kIHN0cnVjdCBTMTsKCgkgc2F5LCB3aGVuIHdlIHNob3VsZCB0c3Vic3QgaW50byBgVScgd2hlbiBpbnN0YW50aWF0aW5nCgkgUzIuICBPbiB0aGUgb3RoZXIgaGFuZCwgd2hlbiBwcmVzZW50ZWQgd2l0aDoKCgkgICB0ZW1wbGF0ZSA8Y2xhc3MgVD4KCSAgIHN0cnVjdCBTMSB7CgkgICAgIHRlbXBsYXRlIDxjbGFzcyBVPgoJICAgICBzdHJ1Y3QgUzIge307CgkgICAgIHRlbXBsYXRlIDxjbGFzcyBVPgoJICAgICBmcmllbmQgc3RydWN0IFMyOwoJICAgfTsKCgkgd2UgbXVzdCBmaW5kIHRoZSBpbm5lciBiaW5kaW5nIGV2ZW50dWFsbHkuICBXZQoJIGFjY29tcGxpc2ggdGhpcyBieSBtYWtpbmcgc3VyZSB0aGF0IHRoZSBuZXcgdHlwZSB3ZQoJIGNyZWF0ZSB0byByZXByZXNlbnQgdGhpcyBkZWNsYXJhdGlvbiBoYXMgdGhlIHJpZ2h0CgkgVFlQRV9DT05URVhULiAgKi8KICAgICAgY29udGV4dCA9IFRZUEVfQ09OVEVYVCAodCk7CiAgICAgIHQgPSBOVUxMX1RSRUU7CiAgICB9CgogIGlmICghIHQpCiAgICB7CiAgICAgIC8qIElmIG5vIHN1Y2ggdGFnIGlzIHlldCBkZWZpbmVkLCBjcmVhdGUgYSBmb3J3YXJkLXJlZmVyZW5jZSBub2RlCgkgYW5kIHJlY29yZCBpdCBhcyB0aGUgImRlZmluaXRpb24iLgoJIFdoZW4gYSByZWFsIGRlY2xhcmF0aW9uIG9mIHRoaXMgdHlwZSBpcyBmb3VuZCwKCSB0aGUgZm9yd2FyZC1yZWZlcmVuY2Ugd2lsbCBiZSBhbHRlcmVkIGludG8gYSByZWFsIHR5cGUuICAqLwogICAgICBpZiAoY29kZSA9PSBFTlVNRVJBTF9UWVBFKQoJewoJICBlcnJvciAoInVzZSBvZiBlbnVtICVxI0Qgd2l0aG91dCBwcmV2aW91cyBkZWNsYXJhdGlvbiIsIG5hbWUpOwoJICBQT1BfVElNRVZBUl9BTkRfUkVUVVJOIChUVl9OQU1FX0xPT0tVUCwgZXJyb3JfbWFya19ub2RlKTsKCX0KICAgICAgZWxzZQoJewoJICB0ID0gbWFrZV9hZ2dyX3R5cGUgKGNvZGUpOwoJICBUWVBFX0NPTlRFWFQgKHQpID0gY29udGV4dDsKCSAgLyogQVBQTEUgTE9DQUwgYmVnaW4gNDE4NDIwMyAqLwoJICAvKiBwdXNodGFnIG9ubHkgY2FyZXMgd2hldGhlciBTQ09QRSBpcyB6ZXJvIG9yIG5vdC4gICovCgkgIHQgPSBwdXNodGFnIChuYW1lLCB0LCBzY29wZSAhPSB0c19jdXJyZW50KTsKCSAgLyogQVBQTEUgTE9DQUwgZW5kIDQxODQyMDMgKi8KCX0KICAgIH0KICBlbHNlCiAgICB7CiAgICAgIGlmICh0ZW1wbGF0ZV9oZWFkZXJfcCAmJiBJU19BR0dSX1RZUEUgKHQpKQoJcmVkZWNsYXJlX2NsYXNzX3RlbXBsYXRlICh0LCBjdXJyZW50X3RlbXBsYXRlX3Bhcm1zKTsKICAgICAgZWxzZSBpZiAoIXByb2Nlc3NpbmdfdGVtcGxhdGVfZGVjbAoJICAgICAgICYmIENMQVNTX1RZUEVfUCAodCkKCSAgICAgICAmJiBDTEFTU1RZUEVfSVNfVEVNUExBVEUgKHQpKQoJewoJICBlcnJvciAoInJlZGVjbGFyYXRpb24gb2YgJXFUIGFzIGEgbm9uLXRlbXBsYXRlIiwgdCk7CgkgIHQgPSBlcnJvcl9tYXJrX25vZGU7Cgl9CiAgICAgIC8qIEFQUExFIExPQ0FMIDQxODQyMDMgKi8KICAgICAgLyogUmVtb3ZlIGNvZGUgdG8gbWFrZSBmcmllbmQgY2xhc3MgdmlzaWJsZSAqLwogICAgfQoKICBQT1BfVElNRVZBUl9BTkRfUkVUVVJOIChUVl9OQU1FX0xPT0tVUCwgdCk7Cn0KCnRyZWUKeHJlZl90YWdfZnJvbV90eXBlICh0cmVlIG9sZCwgdHJlZSBpZCwgdGFnX3Njb3BlIHNjb3BlKQp7CiAgZW51bSB0YWdfdHlwZXMgdGFnX2tpbmQ7CgogIGlmIChUUkVFX0NPREUgKG9sZCkgPT0gUkVDT1JEX1RZUEUpCiAgICB0YWdfa2luZCA9IChDTEFTU1RZUEVfREVDTEFSRURfQ0xBU1MgKG9sZCkgPyBjbGFzc190eXBlIDogcmVjb3JkX3R5cGUpOwogIGVsc2UKICAgIHRhZ19raW5kICA9IHVuaW9uX3R5cGU7CgogIGlmIChpZCA9PSBOVUxMX1RSRUUpCiAgICBpZCA9IFRZUEVfSURFTlRJRklFUiAob2xkKTsKCiAgcmV0dXJuIHhyZWZfdGFnICh0YWdfa2luZCwgaWQsIHNjb3BlLCBmYWxzZSk7Cn0KCi8qIENyZWF0ZSB0aGUgYmluZm8gaGllcmFyY2h5IGZvciBSRUYgd2l0aCAocG9zc2libHkgTlVMTCkgYmFzZSBsaXN0CiAgIEJBU0VfTElTVC4gIEZvciBlYWNoIGVsZW1lbnQgb24gQkFTRV9MSVNUIHRoZSBUUkVFX1BVUlBPU0UgaXMgYW4KICAgYWNjZXNzXyogbm9kZSwgYW5kIHRoZSBUUkVFX1ZBTFVFIGlzIHRoZSB0eXBlIG9mIHRoZSBiYXNlLWNsYXNzLgogICBOb24tTlVMTCBUUkVFX1RZUEUgaW5kaWNhdGVzIHZpcnR1YWwgaW5oZXJpdGFuY2UuICAqLwoKdm9pZAp4cmVmX2Jhc2V0eXBlcyAodHJlZSByZWYsIHRyZWUgYmFzZV9saXN0KQp7CiAgdHJlZSAqYmFzZXA7CiAgdHJlZSBiaW5mbywgYmFzZV9iaW5mbzsKICB1bnNpZ25lZCBtYXhfdmJhc2VzID0gMDsgLyogTWF4aW11bSBkaXJlY3QgJiBpbmRpcmVjdCB2aXJ0dWFsIGJhc2VzLiAgKi8KICB1bnNpZ25lZCBtYXhfYmFzZXMgPSAwOyAgLyogTWF4aW11bSBkaXJlY3QgYmFzZXMuICAqLwogIGludCBpOwogIHRyZWUgZGVmYXVsdF9hY2Nlc3M7CiAgdHJlZSBpZ29fcHJldjsgLyogVHJhY2sgSW5oZXJpdGFuY2UgR3JhcGggT3JkZXIuICAqLwoKICBpZiAocmVmID09IGVycm9yX21hcmtfbm9kZSkKICAgIHJldHVybjsKCiAgLyogVGhlIGJhc2Ugb2YgYSBkZXJpdmVkIGNsYXNzIGlzIHByaXZhdGUgYnkgZGVmYXVsdCwgYWxsIG90aGVycyBhcmUKICAgICBwdWJsaWMuICAqLwogIGRlZmF1bHRfYWNjZXNzID0gKFRSRUVfQ09ERSAocmVmKSA9PSBSRUNPUkRfVFlQRQoJCSAgICAmJiBDTEFTU1RZUEVfREVDTEFSRURfQ0xBU1MgKHJlZikKCQkgICAgPyBhY2Nlc3NfcHJpdmF0ZV9ub2RlIDogYWNjZXNzX3B1YmxpY19ub2RlKTsKCiAgLyogRmlyc3QsIG1ha2Ugc3VyZSB0aGF0IGFueSB0ZW1wbGF0ZXMgaW4gYmFzZS1jbGFzc2VzIGFyZQogICAgIGluc3RhbnRpYXRlZC4gIFRoaXMgZW5zdXJlcyB0aGF0IGlmIHdlIGNhbGwgb3Vyc2VsdmVzIHJlY3Vyc2l2ZWx5CiAgICAgd2UgZG8gbm90IGdldCBjb25mdXNlZCBhYm91dCB3aGljaCBjbGFzc2VzIGFyZSBtYXJrZWQgYW5kIHdoaWNoCiAgICAgYXJlIG5vdC4gICovCiAgYmFzZXAgPSAmYmFzZV9saXN0OwogIHdoaWxlICgqYmFzZXApCiAgICB7CiAgICAgIHRyZWUgYmFzZXR5cGUgPSBUUkVFX1ZBTFVFICgqYmFzZXApOwoKICAgICAgaWYgKCEocHJvY2Vzc2luZ190ZW1wbGF0ZV9kZWNsICYmIHVzZXNfdGVtcGxhdGVfcGFybXMgKGJhc2V0eXBlKSkKCSAgJiYgIWNvbXBsZXRlX3R5cGVfb3JfZWxzZSAoYmFzZXR5cGUsIE5VTEwpKQoJLyogQW4gaW5jb21wbGV0ZSB0eXBlLiAgUmVtb3ZlIGl0IGZyb20gdGhlIGxpc3QuICAqLwoJKmJhc2VwID0gVFJFRV9DSEFJTiAoKmJhc2VwKTsKICAgICAgZWxzZQoJewoJICBtYXhfYmFzZXMrKzsKCSAgaWYgKFRSRUVfVFlQRSAoKmJhc2VwKSkKCSAgICBtYXhfdmJhc2VzKys7CgkgIGlmIChDTEFTU19UWVBFX1AgKGJhc2V0eXBlKSkKCSAgICBtYXhfdmJhc2VzICs9IFZFQ19sZW5ndGggKHRyZWUsIENMQVNTVFlQRV9WQkFTRUNMQVNTRVMgKGJhc2V0eXBlKSk7CgkgIGJhc2VwID0gJlRSRUVfQ0hBSU4gKCpiYXNlcCk7Cgl9CiAgICB9CgogIFRZUEVfTUFSS0VEX1AgKHJlZikgPSAxOwoKICAvKiBUaGUgYmluZm8gc2xvdCBzaG91bGQgYmUgZW1wdHksIHVubGVzcyB0aGlzIGlzIGFuIChpbGwtZm9ybWVkKQogICAgIHJlZGVmaW5pdGlvbi4gICovCiAgZ2NjX2Fzc2VydCAoIVRZUEVfQklORk8gKHJlZikgfHwgVFlQRV9TSVpFIChyZWYpKTsKICBnY2NfYXNzZXJ0IChUWVBFX01BSU5fVkFSSUFOVCAocmVmKSA9PSByZWYpOwoKICBiaW5mbyA9IG1ha2VfdHJlZV9iaW5mbyAobWF4X2Jhc2VzKTsKCiAgVFlQRV9CSU5GTyAocmVmKSA9IGJpbmZvOwogIEJJTkZPX09GRlNFVCAoYmluZm8pID0gc2l6ZV96ZXJvX25vZGU7CiAgQklORk9fVFlQRSAoYmluZm8pID0gcmVmOwoKICBpZiAobWF4X2Jhc2VzKQogICAgewogICAgICBCSU5GT19CQVNFX0FDQ0VTU0VTIChiaW5mbykgPSBWRUNfYWxsb2MgKHRyZWUsIG1heF9iYXNlcyk7CiAgICAgIC8qIEFuIGFnZ3JlZ2F0ZSBjYW5ub3QgaGF2ZSBiYXNlY2xhc3Nlcy4gICovCiAgICAgIENMQVNTVFlQRV9OT05fQUdHUkVHQVRFIChyZWYpID0gMTsKCiAgICAgIGlmIChUUkVFX0NPREUgKHJlZikgPT0gVU5JT05fVFlQRSkKCWVycm9yICgiZGVyaXZlZCB1bmlvbiAlcVQgaW52YWxpZCIsIHJlZik7CiAgICB9CgogIGlmIChtYXhfYmFzZXMgPiAxKQogICAgewogICAgICBpZiAoVFlQRV9GT1JfSkFWQSAocmVmKSkKCWVycm9yICgiSmF2YSBjbGFzcyAlcVQgY2Fubm90IGhhdmUgbXVsdGlwbGUgYmFzZXMiLCByZWYpOwogICAgfQoKICBpZiAobWF4X3ZiYXNlcykKICAgIHsKICAgICAgQ0xBU1NUWVBFX1ZCQVNFQ0xBU1NFUyAocmVmKSA9IFZFQ19hbGxvYyAodHJlZSwgbWF4X3ZiYXNlcyk7CgogICAgICBpZiAoVFlQRV9GT1JfSkFWQSAocmVmKSkKCWVycm9yICgiSmF2YSBjbGFzcyAlcVQgY2Fubm90IGhhdmUgdmlydHVhbCBiYXNlcyIsIHJlZik7CiAgICB9CgogIGZvciAoaWdvX3ByZXYgPSBiaW5mbzsgYmFzZV9saXN0OyBiYXNlX2xpc3QgPSBUUkVFX0NIQUlOIChiYXNlX2xpc3QpKQogICAgewogICAgICB0cmVlIGFjY2VzcyA9IFRSRUVfUFVSUE9TRSAoYmFzZV9saXN0KTsKICAgICAgaW50IHZpYV92aXJ0dWFsID0gVFJFRV9UWVBFIChiYXNlX2xpc3QpICE9IE5VTExfVFJFRTsKICAgICAgdHJlZSBiYXNldHlwZSA9IFRSRUVfVkFMVUUgKGJhc2VfbGlzdCk7CgogICAgICBpZiAoYWNjZXNzID09IGFjY2Vzc19kZWZhdWx0X25vZGUpCglhY2Nlc3MgPSBkZWZhdWx0X2FjY2VzczsKCiAgICAgIGlmIChUUkVFX0NPREUgKGJhc2V0eXBlKSA9PSBUWVBFX0RFQ0wpCgliYXNldHlwZSA9IFRSRUVfVFlQRSAoYmFzZXR5cGUpOwogICAgICBpZiAoVFJFRV9DT0RFIChiYXNldHlwZSkgIT0gUkVDT1JEX1RZUEUKCSAgJiYgVFJFRV9DT0RFIChiYXNldHlwZSkgIT0gVFlQRU5BTUVfVFlQRQoJICAmJiBUUkVFX0NPREUgKGJhc2V0eXBlKSAhPSBURU1QTEFURV9UWVBFX1BBUk0KCSAgJiYgVFJFRV9DT0RFIChiYXNldHlwZSkgIT0gQk9VTkRfVEVNUExBVEVfVEVNUExBVEVfUEFSTSkKCXsKCSAgZXJyb3IgKCJiYXNlIHR5cGUgJXFUIGZhaWxzIHRvIGJlIGEgc3RydWN0IG9yIGNsYXNzIHR5cGUiLAoJCSBiYXNldHlwZSk7CgkgIGNvbnRpbnVlOwoJfQoKICAgICAgaWYgKFRZUEVfRk9SX0pBVkEgKGJhc2V0eXBlKSAmJiAoY3VycmVudF9sYW5nX2RlcHRoICgpID09IDApKQoJVFlQRV9GT1JfSkFWQSAocmVmKSA9IDE7CgogICAgICBiYXNlX2JpbmZvID0gTlVMTF9UUkVFOwogICAgICBpZiAoQ0xBU1NfVFlQRV9QIChiYXNldHlwZSkgJiYgIWRlcGVuZGVudF90eXBlX3AgKGJhc2V0eXBlKSkKCXsKCSAgYmFzZV9iaW5mbyA9IFRZUEVfQklORk8gKGJhc2V0eXBlKTsKCSAgLyogVGhlIG9yaWdpbmFsIGJhc2V0eXBlIGNvdWxkIGhhdmUgYmVlbiBhIHR5cGVkZWYnZCB0eXBlLiAgKi8KCSAgYmFzZXR5cGUgPSBCSU5GT19UWVBFIChiYXNlX2JpbmZvKTsKCgkgIC8qIEluaGVyaXQgZmxhZ3MgZnJvbSB0aGUgYmFzZS4gICovCgkgIFRZUEVfSEFTX05FV19PUEVSQVRPUiAocmVmKQoJICAgIHw9IFRZUEVfSEFTX05FV19PUEVSQVRPUiAoYmFzZXR5cGUpOwoJICBUWVBFX0hBU19BUlJBWV9ORVdfT1BFUkFUT1IgKHJlZikKCSAgICB8PSBUWVBFX0hBU19BUlJBWV9ORVdfT1BFUkFUT1IgKGJhc2V0eXBlKTsKCSAgVFlQRV9HRVRTX0RFTEVURSAocmVmKSB8PSBUWVBFX0dFVFNfREVMRVRFIChiYXNldHlwZSk7CgkgIFRZUEVfSEFTX0NPTlZFUlNJT04gKHJlZikgfD0gVFlQRV9IQVNfQ09OVkVSU0lPTiAoYmFzZXR5cGUpOwoJICBDTEFTU1RZUEVfRElBTU9ORF9TSEFQRURfUCAocmVmKQoJICAgIHw9IENMQVNTVFlQRV9ESUFNT05EX1NIQVBFRF9QIChiYXNldHlwZSk7CgkgIENMQVNTVFlQRV9SRVBFQVRFRF9CQVNFX1AgKHJlZikKCSAgICB8PSBDTEFTU1RZUEVfUkVQRUFURURfQkFTRV9QIChiYXNldHlwZSk7Cgl9CiAgICAgIAogICAgICAvKiBXZSBtdXN0IGRvIHRoaXMgdGVzdCBhZnRlciB3ZSd2ZSBzZWVuIHRocm91Z2ggYSB0eXBlZGVmCgkgdHlwZS4gICovCiAgICAgIGlmIChUWVBFX01BUktFRF9QIChiYXNldHlwZSkpCgl7CgkgIGlmIChiYXNldHlwZSA9PSByZWYpCgkgICAgZXJyb3IgKCJyZWN1cnNpdmUgdHlwZSAlcVQgdW5kZWZpbmVkIiwgYmFzZXR5cGUpOwoJICBlbHNlCgkgICAgZXJyb3IgKCJkdXBsaWNhdGUgYmFzZSB0eXBlICVxVCBpbnZhbGlkIiwgYmFzZXR5cGUpOwoJICBjb250aW51ZTsKCX0KICAgICAgVFlQRV9NQVJLRURfUCAoYmFzZXR5cGUpID0gMTsKCiAgICAgIGJhc2VfYmluZm8gPSBjb3B5X2JpbmZvIChiYXNlX2JpbmZvLCBiYXNldHlwZSwgcmVmLAoJCQkgICAgICAgJmlnb19wcmV2LCB2aWFfdmlydHVhbCk7CiAgICAgIGlmICghQklORk9fSU5IRVJJVEFOQ0VfQ0hBSU4gKGJhc2VfYmluZm8pKQoJQklORk9fSU5IRVJJVEFOQ0VfQ0hBSU4gKGJhc2VfYmluZm8pID0gYmluZm87CgogICAgICBCSU5GT19CQVNFX0FQUEVORCAoYmluZm8sIGJhc2VfYmluZm8pOwogICAgICBCSU5GT19CQVNFX0FDQ0VTU19BUFBFTkQgKGJpbmZvLCBhY2Nlc3MpOwogICAgfQoKICBpZiAoVkVDX3NwYWNlICh0cmVlLCBDTEFTU1RZUEVfVkJBU0VDTEFTU0VTIChyZWYpLCAxKSkKICAgIC8qIElmIHdlIGhhdmUgc3BhY2UgaW4gdGhlIHZiYXNlIHZlY3Rvciwgd2UgbXVzdCBoYXZlIHNoYXJlZCBhdAogICAgICAgbGVhc3Qgb25lIG9mIHRoZW0sIGFuZCBhcmUgdGhlcmVmb3JlIGRpYW1vbmQgc2hhcGVkLiAgKi8KICAgIENMQVNTVFlQRV9ESUFNT05EX1NIQVBFRF9QIChyZWYpID0gMTsKCiAgLyogVW5tYXJrIGFsbCB0aGUgdHlwZXMuICAqLwogIGZvciAoaSA9IDA7IEJJTkZPX0JBU0VfSVRFUkFURSAoYmluZm8sIGksIGJhc2VfYmluZm8pOyBpKyspCiAgICBUWVBFX01BUktFRF9QIChCSU5GT19UWVBFIChiYXNlX2JpbmZvKSkgPSAwOwogIFRZUEVfTUFSS0VEX1AgKHJlZikgPSAwOwoKICAvKiBOb3cgc2VlIGlmIHdlIGhhdmUgYSByZXBlYXRlZCBiYXNlIHR5cGUuICAqLwogIGlmICghQ0xBU1NUWVBFX1JFUEVBVEVEX0JBU0VfUCAocmVmKSkKICAgIHsKICAgICAgZm9yIChiYXNlX2JpbmZvID0gYmluZm87IGJhc2VfYmluZm87CgkgICBiYXNlX2JpbmZvID0gVFJFRV9DSEFJTiAoYmFzZV9iaW5mbykpCgl7CgkgIGlmIChUWVBFX01BUktFRF9QIChCSU5GT19UWVBFIChiYXNlX2JpbmZvKSkpCgkgICAgewoJICAgICAgQ0xBU1NUWVBFX1JFUEVBVEVEX0JBU0VfUCAocmVmKSA9IDE7CgkgICAgICBicmVhazsKCSAgICB9CgkgIFRZUEVfTUFSS0VEX1AgKEJJTkZPX1RZUEUgKGJhc2VfYmluZm8pKSA9IDE7Cgl9CiAgICAgIGZvciAoYmFzZV9iaW5mbyA9IGJpbmZvOyBiYXNlX2JpbmZvOwoJICAgYmFzZV9iaW5mbyA9IFRSRUVfQ0hBSU4gKGJhc2VfYmluZm8pKQoJaWYgKFRZUEVfTUFSS0VEX1AgKEJJTkZPX1RZUEUgKGJhc2VfYmluZm8pKSkKCSAgVFlQRV9NQVJLRURfUCAoQklORk9fVFlQRSAoYmFzZV9iaW5mbykpID0gMDsKCWVsc2UKCSAgYnJlYWs7CiAgICB9Cn0KCgwKLyogQmVnaW4gY29tcGlsaW5nIHRoZSBkZWZpbml0aW9uIG9mIGFuIGVudW1lcmF0aW9uIHR5cGUuCiAgIE5BTUUgaXMgaXRzIG5hbWUuCiAgIFJldHVybnMgdGhlIHR5cGUgb2JqZWN0LCBhcyB5ZXQgaW5jb21wbGV0ZS4KICAgQWxzbyByZWNvcmRzIGluZm8gYWJvdXQgaXQgc28gdGhhdCBidWlsZF9lbnVtZXJhdG9yCiAgIG1heSBiZSB1c2VkIHRvIGRlY2xhcmUgdGhlIGluZGl2aWR1YWwgdmFsdWVzIGFzIHRoZXkgYXJlIHJlYWQuICAqLwoKdHJlZQpzdGFydF9lbnVtICh0cmVlIG5hbWUpCnsKICB0cmVlIGVudW10eXBlOwoKICBnY2NfYXNzZXJ0IChUUkVFX0NPREUgKG5hbWUpID09IElERU5USUZJRVJfTk9ERSk7CgogIC8qIElmIHRoaXMgaXMgdGhlIHJlYWwgZGVmaW5pdGlvbiBmb3IgYSBwcmV2aW91cyBmb3J3YXJkIHJlZmVyZW5jZSwKICAgICBmaWxsIGluIHRoZSBjb250ZW50cyBpbiB0aGUgc2FtZSBvYmplY3QgdGhhdCB1c2VkIHRvIGJlIHRoZQogICAgIGZvcndhcmQgcmVmZXJlbmNlLiAgKi8KCiAgZW51bXR5cGUgPSBsb29rdXBfYW5kX2NoZWNrX3RhZyAoZW51bV90eXBlLCBuYW1lLAoJCQkJICAgLyp0YWdfc2NvcGU9Ki90c19jdXJyZW50LAoJCQkJICAgLyp0ZW1wbGF0ZV9oZWFkZXJfcD0qL2ZhbHNlKTsKCiAgaWYgKGVudW10eXBlICE9IE5VTExfVFJFRSAmJiBUUkVFX0NPREUgKGVudW10eXBlKSA9PSBFTlVNRVJBTF9UWVBFKQogICAgewogICAgICBlcnJvciAoIm11bHRpcGxlIGRlZmluaXRpb24gb2YgJXEjVCIsIGVudW10eXBlKTsKICAgICAgZXJyb3IgKCIlSnByZXZpb3VzIGRlZmluaXRpb24gaGVyZSIsIFRZUEVfTUFJTl9ERUNMIChlbnVtdHlwZSkpOwogICAgICAvKiBDbGVhciBvdXQgVFlQRV9WQUxVRVMsIGFuZCBzdGFydCBhZ2Fpbi4gICovCiAgICAgIFRZUEVfVkFMVUVTIChlbnVtdHlwZSkgPSBOVUxMX1RSRUU7CiAgICB9CiAgZWxzZQogICAgewogICAgICAvKiBJbiBjYXNlIG9mIGVycm9yLCBtYWtlIGEgZHVtbXkgZW51bSB0byBhbGxvdyBwYXJzaW5nIHRvCgkgY29udGludWUuICAqLwogICAgICBpZiAoZW51bXR5cGUgPT0gZXJyb3JfbWFya19ub2RlKQoJbmFtZSA9IG1ha2VfYW5vbl9uYW1lICgpOwoKICAgICAgZW51bXR5cGUgPSBtYWtlX25vZGUgKEVOVU1FUkFMX1RZUEUpOwogICAgICAvKiBBUFBMRSBMT0NBTCA0MTg0MjAzICovCiAgICAgIGVudW10eXBlID0gcHVzaHRhZyAobmFtZSwgZW51bXR5cGUsIDApOwogICAgfQoKICByZXR1cm4gZW51bXR5cGU7Cn0KCi8qIEFmdGVyIHByb2Nlc3NpbmcgYW5kIGRlZmluaW5nIGFsbCB0aGUgdmFsdWVzIG9mIGFuIGVudW1lcmF0aW9uIHR5cGUsCiAgIGluc3RhbGwgdGhlaXIgZGVjbHMgaW4gdGhlIGVudW1lcmF0aW9uIHR5cGUgYW5kIGZpbmlzaCBpdCBvZmYuCiAgIEVOVU1UWVBFIGlzIHRoZSB0eXBlIG9iamVjdCBhbmQgVkFMVUVTIGEgbGlzdCBvZiBuYW1lLXZhbHVlIHBhaXJzLiAgKi8KCnZvaWQKZmluaXNoX2VudW0gKHRyZWUgZW51bXR5cGUpCnsKICB0cmVlIHZhbHVlczsKICB0cmVlIGRlY2w7CiAgdHJlZSB2YWx1ZTsKICB0cmVlIG1pbm5vZGU7CiAgdHJlZSBtYXhub2RlOwogIHRyZWUgdDsKICBib29sIHVuc2lnbmVkcDsKICBib29sIHVzZV9zaG9ydF9lbnVtOwogIGludCBsb3dwcmVjOwogIGludCBoaWdocHJlYzsKICBpbnQgcHJlY2lzaW9uOwogIGludGVnZXJfdHlwZV9raW5kIGl0azsKICB0cmVlIHVuZGVybHlpbmdfdHlwZSA9IE5VTExfVFJFRTsKCiAgLyogV2UgYnVpbHQgdXAgdGhlIFZBTFVFUyBpbiByZXZlcnNlIG9yZGVyLiAgKi8KICBUWVBFX1ZBTFVFUyAoZW51bXR5cGUpID0gbnJldmVyc2UgKFRZUEVfVkFMVUVTIChlbnVtdHlwZSkpOwoKICAvKiBGb3IgYW4gZW51bSBkZWZpbmVkIGluIGEgdGVtcGxhdGUsIGp1c3Qgc2V0IHRoZSB0eXBlIG9mIHRoZSB2YWx1ZXM7CiAgICAgYWxsIGZ1cnRoZXIgcHJvY2Vzc2luZyBpcyBwb3N0cG9uZWQgdW50aWwgdGhlIHRlbXBsYXRlIGlzCiAgICAgaW5zdGFudGlhdGVkLiAgV2UgbmVlZCB0byBzZXQgdGhlIHR5cGUgc28gdGhhdCB0c3Vic3Qgb2YgYSBDT05TVF9ERUNMCiAgICAgd29ya3MuICAqLwogIGlmIChwcm9jZXNzaW5nX3RlbXBsYXRlX2RlY2wpCiAgICB7CiAgICAgIGZvciAodmFsdWVzID0gVFlQRV9WQUxVRVMgKGVudW10eXBlKTsKCSAgIHZhbHVlczsKCSAgIHZhbHVlcyA9IFRSRUVfQ0hBSU4gKHZhbHVlcykpCglUUkVFX1RZUEUgKFRSRUVfVkFMVUUgKHZhbHVlcykpID0gZW51bXR5cGU7CiAgICAgIGlmIChhdF9mdW5jdGlvbl9zY29wZV9wICgpKQoJYWRkX3N0bXQgKGJ1aWxkX21pbiAoVEFHX0RFRk4sIGVudW10eXBlKSk7CiAgICAgIHJldHVybjsKICAgIH0KCiAgLyogRGV0ZXJtaW5lIHRoZSBtaW5pbXVtIGFuZCBtYXhpbXVtIHZhbHVlcyBvZiB0aGUgZW51bWVyYXRvcnMuICAqLwogIGlmIChUWVBFX1ZBTFVFUyAoZW51bXR5cGUpKQogICAgewogICAgICBtaW5ub2RlID0gbWF4bm9kZSA9IE5VTExfVFJFRTsKCiAgICAgIGZvciAodmFsdWVzID0gVFlQRV9WQUxVRVMgKGVudW10eXBlKTsKCSAgIHZhbHVlczsKCSAgIHZhbHVlcyA9IFRSRUVfQ0hBSU4gKHZhbHVlcykpCgl7CgkgIGRlY2wgPSBUUkVFX1ZBTFVFICh2YWx1ZXMpOwoKCSAgLyogW2RjbC5lbnVtXTogRm9sbG93aW5nIHRoZSBjbG9zaW5nIGJyYWNlIG9mIGFuIGVudW0tc3BlY2lmaWVyLAoJICAgICBlYWNoIGVudW1lcmF0b3IgaGFzIHRoZSB0eXBlIG9mIGl0cyBlbnVtZXJhdGlvbi4gIFByaW9yIHRvIHRoZQoJICAgICBjbG9zaW5nIGJyYWNlLCB0aGUgdHlwZSBvZiBlYWNoIGVudW1lcmF0b3IgaXMgdGhlIHR5cGUgb2YgaXRzCgkgICAgIGluaXRpYWxpemluZyB2YWx1ZS4gICovCgkgIFRSRUVfVFlQRSAoZGVjbCkgPSBlbnVtdHlwZTsKCgkgIC8qIFVwZGF0ZSB0aGUgbWluaW11bSBhbmQgbWF4aW11bSB2YWx1ZXMsIGlmIGFwcHJvcHJpYXRlLiAgKi8KCSAgdmFsdWUgPSBERUNMX0lOSVRJQUwgKGRlY2wpOwoJICAvKiBGaWd1cmUgb3V0IHdoYXQgdGhlIG1pbmltdW0gYW5kIG1heGltdW0gdmFsdWVzIG9mIHRoZQoJICAgICBlbnVtZXJhdG9ycyBhcmUuICAqLwoJICBpZiAoIW1pbm5vZGUpCgkgICAgbWlubm9kZSA9IG1heG5vZGUgPSB2YWx1ZTsKCSAgZWxzZSBpZiAodHJlZV9pbnRfY3N0X2x0IChtYXhub2RlLCB2YWx1ZSkpCgkgICAgbWF4bm9kZSA9IHZhbHVlOwoJICBlbHNlIGlmICh0cmVlX2ludF9jc3RfbHQgKHZhbHVlLCBtaW5ub2RlKSkKCSAgICBtaW5ub2RlID0gdmFsdWU7Cgl9CiAgICB9CiAgZWxzZQogICAgLyogW2RjbC5lbnVtXQoKICAgICAgIElmIHRoZSBlbnVtZXJhdG9yLWxpc3QgaXMgZW1wdHksIHRoZSB1bmRlcmx5aW5nIHR5cGUgaXMgYXMgaWYKICAgICAgIHRoZSBlbnVtZXJhdGlvbiBoYWQgYSBzaW5nbGUgZW51bWVyYXRvciB3aXRoIHZhbHVlIDAuICAqLwogICAgbWlubm9kZSA9IG1heG5vZGUgPSBpbnRlZ2VyX3plcm9fbm9kZTsKCiAgLyogQ29tcHV0ZSB0aGUgbnVtYmVyIG9mIGJpdHMgcmVxdWlyZSB0byByZXByZXNlbnQgYWxsIHZhbHVlcyBvZiB0aGUKICAgICBlbnVtZXJhdGlvbi4gIFdlIG11c3QgZG8gdGhpcyBiZWZvcmUgdGhlIHR5cGUgb2YgTUlOTk9ERSBhbmQKICAgICBNQVhOT0RFIGFyZSB0cmFuc2Zvcm1lZCwgc2luY2UgbWluX3ByZWNpc2lvbiByZWxpZXMgb24gdGhlCiAgICAgVFJFRV9UWVBFIG9mIHRoZSB2YWx1ZSBpdCBpcyBwYXNzZWQuICAqLwogIHVuc2lnbmVkcCA9IHRyZWVfaW50X2NzdF9zZ24gKG1pbm5vZGUpID49IDA7CiAgbG93cHJlYyA9IG1pbl9wcmVjaXNpb24gKG1pbm5vZGUsIHVuc2lnbmVkcCk7CiAgaGlnaHByZWMgPSBtaW5fcHJlY2lzaW9uIChtYXhub2RlLCB1bnNpZ25lZHApOwogIHByZWNpc2lvbiA9IE1BWCAobG93cHJlYywgaGlnaHByZWMpOwoKICAvKiBEZXRlcm1pbmUgdGhlIHVuZGVybHlpbmcgdHlwZSBvZiB0aGUgZW51bWVyYXRpb24uCgogICAgICAgW2RjbC5lbnVtXQoKICAgICAgIFRoZSB1bmRlcmx5aW5nIHR5cGUgb2YgYW4gZW51bWVyYXRpb24gaXMgYW4gaW50ZWdyYWwgdHlwZSB0aGF0CiAgICAgICBjYW4gcmVwcmVzZW50IGFsbCB0aGUgZW51bWVyYXRvciB2YWx1ZXMgZGVmaW5lZCBpbiB0aGUKICAgICAgIGVudW1lcmF0aW9uLiAgSXQgaXMgaW1wbGVtZW50YXRpb24tZGVmaW5lZCB3aGljaCBpbnRlZ3JhbCB0eXBlIGlzCiAgICAgICB1c2VkIGFzIHRoZSB1bmRlcmx5aW5nIHR5cGUgZm9yIGFuIGVudW1lcmF0aW9uIGV4Y2VwdCB0aGF0IHRoZQogICAgICAgdW5kZXJseWluZyB0eXBlIHNoYWxsIG5vdCBiZSBsYXJnZXIgdGhhbiBpbnQgdW5sZXNzIHRoZSB2YWx1ZSBvZgogICAgICAgYW4gZW51bWVyYXRvciBjYW5ub3QgZml0IGluIGFuIGludCBvciB1bnNpZ25lZCBpbnQuCgogICAgIFdlIHVzZSAiaW50IiBvciBhbiAidW5zaWduZWQgaW50IiBhcyB0aGUgdW5kZXJseWluZyB0eXBlLCBldmVuIGlmCiAgICAgYSBzbWFsbGVyIGludGVncmFsIHR5cGUgd291bGQgd29yaywgdW5sZXNzIHRoZSB1c2VyIGhhcwogICAgIGV4cGxpY2l0bHkgcmVxdWVzdGVkIHRoYXQgd2UgdXNlIHRoZSBzbWFsbGVzdCBwb3NzaWJsZSB0eXBlLiAgVGhlCiAgICAgdXNlciBjYW4gcmVxdWVzdCB0aGF0IGZvciBhbGwgZW51bWVyYXRpb25zIHdpdGggYSBjb21tYW5kIGxpbmUKICAgICBmbGFnLCBvciBmb3IganVzdCBvbmUgZW51bWVyYXRpb24gd2l0aCBhbiBhdHRyaWJ1dGUuICAqLwoKICB1c2Vfc2hvcnRfZW51bSA9IGZsYWdfc2hvcnRfZW51bXMKICAgIHx8IGxvb2t1cF9hdHRyaWJ1dGUgKCJwYWNrZWQiLCBUWVBFX0FUVFJJQlVURVMgKGVudW10eXBlKSk7CgogIGZvciAoaXRrID0gKHVzZV9zaG9ydF9lbnVtID8gaXRrX2NoYXIgOiBpdGtfaW50KTsKICAgICAgIGl0ayAhPSBpdGtfbm9uZTsKICAgICAgIGl0aysrKQogICAgewogICAgICB1bmRlcmx5aW5nX3R5cGUgPSBpbnRlZ2VyX3R5cGVzW2l0a107CiAgICAgIGlmIChUWVBFX1BSRUNJU0lPTiAodW5kZXJseWluZ190eXBlKSA+PSBwcmVjaXNpb24KCSAgJiYgVFlQRV9VTlNJR05FRCAodW5kZXJseWluZ190eXBlKSA9PSB1bnNpZ25lZHApCglicmVhazsKICAgIH0KICBpZiAoaXRrID09IGl0a19ub25lKQogICAgewogICAgICAvKiBEUiAzNzcKCgkgSUYgbm8gaW50ZWdyYWwgdHlwZSBjYW4gcmVwcmVzZW50IGFsbCB0aGUgZW51bWVyYXRvciB2YWx1ZXMsIHRoZQoJIGVudW1lcmF0aW9uIGlzIGlsbC1mb3JtZWQuICAqLwogICAgICBlcnJvciAoIm5vIGludGVncmFsIHR5cGUgY2FuIHJlcHJlc2VudCBhbGwgb2YgdGhlIGVudW1lcmF0b3IgdmFsdWVzICIKCSAgICAgImZvciAlcVQiLCBlbnVtdHlwZSk7CiAgICAgIHByZWNpc2lvbiA9IFRZUEVfUFJFQ0lTSU9OIChsb25nX2xvbmdfaW50ZWdlcl90eXBlX25vZGUpOwogICAgICB1bmRlcmx5aW5nX3R5cGUgPSBpbnRlZ2VyX3R5cGVzW2l0a191bnNpZ25lZF9sb25nX2xvbmddOwogICAgfQoKICAvKiBDb21wdXRlIHRoZSBtaW5pdW0gYW5kIG1heGltdW0gdmFsdWVzIGZvciB0aGUgdHlwZS4KCiAgICAgW2RjbC5lbnVtXQoKICAgICBGb3IgYW4gZW51bWVyYXRpb24gd2hlcmUgZW1pbiBpcyB0aGUgc21hbGxlc3QgZW51bWVyYXRvciBhbmQgZW1heAogICAgIGlzIHRoZSBsYXJnZXN0LCB0aGUgdmFsdWVzIG9mIHRoZSBlbnVtZXJhdGlvbiBhcmUgdGhlIHZhbHVlcyBvZiB0aGUKICAgICB1bmRlcmx5aW5nIHR5cGUgaW4gdGhlIHJhbmdlIGJtaW4gdG8gYm1heCwgd2hlcmUgYm1pbiBhbmQgYm1heCBhcmUsCiAgICAgcmVzcGVjdGl2ZWx5LCB0aGUgc21hbGxlc3QgYW5kIGxhcmdlc3QgdmFsdWVzIG9mIHRoZSBzbWFsbGVzdCBiaXQtCiAgICAgZmllbGQgdGhhdCBjYW4gc3RvcmUgZW1pbiBhbmQgZW1heC4gICovCgogIC8qIFRoZSBtaWRkbGUtZW5kIGN1cnJlbnRseSBhc3N1bWVzIHRoYXQgdHlwZXMgd2l0aCBUWVBFX1BSRUNJU0lPTgogICAgIG5hcnJvd2VyIHRoYW4gdGhlaXIgdW5kZXJseWluZyB0eXBlIGFyZSBzdWl0YWJseSB6ZXJvIG9yIHNpZ24KICAgICBleHRlbmRlZCB0byBmaWxsIHRoZWlyIG1vZGUuICBnKysgZG9lc24ndCBtYWtlIHRoZXNlIGd1YXJhbnRlZXMuCiAgICAgVW50aWwgdGhlIG1pZGRsZS1lbmQgY2FuIHJlcHJlc2VudCBzdWNoIHBhcmFkb3hpY2FsIHR5cGVzLCB3ZQogICAgIHNldCB0aGUgVFlQRV9QUkVDSVNJT04gdG8gdGhlIHdpZHRoIG9mIHRoZSB1bmRlcmx5aW5nIHR5cGUuICAqLwogIFRZUEVfUFJFQ0lTSU9OIChlbnVtdHlwZSkgPSBUWVBFX1BSRUNJU0lPTiAodW5kZXJseWluZ190eXBlKTsKCiAgc2V0X21pbl9hbmRfbWF4X3ZhbHVlc19mb3JfaW50ZWdyYWxfdHlwZSAoZW51bXR5cGUsIHByZWNpc2lvbiwgdW5zaWduZWRwKTsKCiAgLyogW2RjbC5lbnVtXQoKICAgICBUaGUgdmFsdWUgb2Ygc2l6ZW9mKCkgYXBwbGllZCB0byBhbiBlbnVtZXJhdGlvbiB0eXBlLCBhbiBvYmplY3QKICAgICBvZiBhbiBlbnVtZXJhdGlvbiB0eXBlLCBvciBhbiBlbnVtZXJhdG9yLCBpcyB0aGUgdmFsdWUgb2Ygc2l6ZW9mKCkKICAgICBhcHBsaWVkIHRvIHRoZSB1bmRlcmx5aW5nIHR5cGUuICAqLwogIFRZUEVfU0laRSAoZW51bXR5cGUpID0gVFlQRV9TSVpFICh1bmRlcmx5aW5nX3R5cGUpOwogIFRZUEVfU0laRV9VTklUIChlbnVtdHlwZSkgPSBUWVBFX1NJWkVfVU5JVCAodW5kZXJseWluZ190eXBlKTsKICBUWVBFX01PREUgKGVudW10eXBlKSA9IFRZUEVfTU9ERSAodW5kZXJseWluZ190eXBlKTsKICBUWVBFX0FMSUdOIChlbnVtdHlwZSkgPSBUWVBFX0FMSUdOICh1bmRlcmx5aW5nX3R5cGUpOwogIFRZUEVfVVNFUl9BTElHTiAoZW51bXR5cGUpID0gVFlQRV9VU0VSX0FMSUdOICh1bmRlcmx5aW5nX3R5cGUpOwogIFRZUEVfVU5TSUdORUQgKGVudW10eXBlKSA9IFRZUEVfVU5TSUdORUQgKHVuZGVybHlpbmdfdHlwZSk7CgogIC8qIENvbnZlcnQgZWFjaCBvZiB0aGUgZW51bWVyYXRvcnMgdG8gdGhlIHR5cGUgb2YgdGhlIHVuZGVybHlpbmcKICAgICB0eXBlIG9mIHRoZSBlbnVtZXJhdGlvbi4gICovCiAgZm9yICh2YWx1ZXMgPSBUWVBFX1ZBTFVFUyAoZW51bXR5cGUpOyB2YWx1ZXM7IHZhbHVlcyA9IFRSRUVfQ0hBSU4gKHZhbHVlcykpCiAgICB7CiAgICAgIGRlY2wgPSBUUkVFX1ZBTFVFICh2YWx1ZXMpOwogICAgICB2YWx1ZSA9IHBlcmZvcm1faW1wbGljaXRfY29udmVyc2lvbiAodW5kZXJseWluZ190eXBlLAoJCQkJCSAgIERFQ0xfSU5JVElBTCAoZGVjbCkpOwoKICAgICAgLyogRG8gbm90IGNsb2JiZXIgc2hhcmVkIGludHMuICAqLwogICAgICB2YWx1ZSA9IGNvcHlfbm9kZSAodmFsdWUpOwogICAgICAKICAgICAgVFJFRV9UWVBFICh2YWx1ZSkgPSBlbnVtdHlwZTsKICAgICAgREVDTF9JTklUSUFMIChkZWNsKSA9IHZhbHVlOwogICAgICBUUkVFX1ZBTFVFICh2YWx1ZXMpID0gdmFsdWU7CiAgICB9CgogIC8qIEZpeCB1cCBhbGwgdmFyaWFudCB0eXBlcyBvZiB0aGlzIGVudW0gdHlwZS4gICovCiAgZm9yICh0ID0gVFlQRV9NQUlOX1ZBUklBTlQgKGVudW10eXBlKTsgdDsgdCA9IFRZUEVfTkVYVF9WQVJJQU5UICh0KSkKICAgIHsKICAgICAgVFlQRV9WQUxVRVMgKHQpID0gVFlQRV9WQUxVRVMgKGVudW10eXBlKTsKICAgICAgVFlQRV9NSU5fVkFMVUUgKHQpID0gVFlQRV9NSU5fVkFMVUUgKGVudW10eXBlKTsKICAgICAgVFlQRV9NQVhfVkFMVUUgKHQpID0gVFlQRV9NQVhfVkFMVUUgKGVudW10eXBlKTsKICAgICAgVFlQRV9TSVpFICh0KSA9IFRZUEVfU0laRSAoZW51bXR5cGUpOwogICAgICBUWVBFX1NJWkVfVU5JVCAodCkgPSBUWVBFX1NJWkVfVU5JVCAoZW51bXR5cGUpOwogICAgICBUWVBFX01PREUgKHQpID0gVFlQRV9NT0RFIChlbnVtdHlwZSk7CiAgICAgIFRZUEVfUFJFQ0lTSU9OICh0KSA9IFRZUEVfUFJFQ0lTSU9OIChlbnVtdHlwZSk7CiAgICAgIFRZUEVfQUxJR04gKHQpID0gVFlQRV9BTElHTiAoZW51bXR5cGUpOwogICAgICBUWVBFX1VTRVJfQUxJR04gKHQpID0gVFlQRV9VU0VSX0FMSUdOIChlbnVtdHlwZSk7CiAgICAgIFRZUEVfVU5TSUdORUQgKHQpID0gVFlQRV9VTlNJR05FRCAoZW51bXR5cGUpOwogICAgfQoKICAvKiBGaW5pc2ggZGVidWdnaW5nIG91dHB1dCBmb3IgdGhpcyB0eXBlLiAgKi8KICByZXN0X29mX3R5cGVfY29tcGlsYXRpb24gKGVudW10eXBlLCBuYW1lc3BhY2VfYmluZGluZ3NfcCAoKSk7Cn0KCi8qIEJ1aWxkIGFuZCBpbnN0YWxsIGEgQ09OU1RfREVDTCBmb3IgYW4gZW51bWVyYXRpb24gY29uc3RhbnQgb2YgdGhlCiAgIGVudW1lcmF0aW9uIHR5cGUgRU5VTVRZUEUgd2hvc2UgTkFNRSBhbmQgVkFMVUUgKGlmIGFueSkgYXJlIHByb3ZpZGVkLgogICBBc3NpZ25tZW50IG9mIHNlcXVlbnRpYWwgdmFsdWVzIGJ5IGRlZmF1bHQgaXMgaGFuZGxlZCBoZXJlLiAgKi8KCnZvaWQKYnVpbGRfZW51bWVyYXRvciAodHJlZSBuYW1lLCB0cmVlIHZhbHVlLCB0cmVlIGVudW10eXBlKQp7CiAgdHJlZSBkZWNsOwogIHRyZWUgY29udGV4dDsKICB0cmVlIHR5cGU7CgogIC8qIElmIHRoZSBWQUxVRSB3YXMgZXJyb25lb3VzLCBwcmV0ZW5kIGl0IHdhc24ndCB0aGVyZTsgdGhhdCB3aWxsCiAgICAgcmVzdWx0IGluIHRoZSBlbnVtIGJlaW5nIGFzc2lnbmVkIHRoZSBuZXh0IHZhbHVlIGluIHNlcXVlbmNlLiAgKi8KICBpZiAodmFsdWUgPT0gZXJyb3JfbWFya19ub2RlKQogICAgdmFsdWUgPSBOVUxMX1RSRUU7CgogIC8qIFJlbW92ZSBuby1vcCBjYXN0cyBmcm9tIHRoZSB2YWx1ZS4gICovCiAgaWYgKHZhbHVlKQogICAgU1RSSVBfVFlQRV9OT1BTICh2YWx1ZSk7CgogIGlmICghIHByb2Nlc3NpbmdfdGVtcGxhdGVfZGVjbCkKICAgIHsKICAgICAgLyogVmFsaWRhdGUgYW5kIGRlZmF1bHQgVkFMVUUuICAqLwogICAgICBpZiAodmFsdWUgIT0gTlVMTF9UUkVFKQoJewoJICB2YWx1ZSA9IGludGVncmFsX2NvbnN0YW50X3ZhbHVlICh2YWx1ZSk7CgoJICBpZiAoVFJFRV9DT0RFICh2YWx1ZSkgPT0gSU5URUdFUl9DU1QpCgkgICAgewoJICAgICAgdmFsdWUgPSBwZXJmb3JtX2ludGVncmFsX3Byb21vdGlvbnMgKHZhbHVlKTsKCSAgICAgIGNvbnN0YW50X2V4cHJlc3Npb25fd2FybmluZyAodmFsdWUpOwoJICAgIH0KCSAgZWxzZQoJICAgIHsKCSAgICAgIGVycm9yICgiZW51bWVyYXRvciB2YWx1ZSBmb3IgJXFEIG5vdCBpbnRlZ2VyIGNvbnN0YW50IiwgbmFtZSk7CgkgICAgICB2YWx1ZSA9IE5VTExfVFJFRTsKCSAgICB9Cgl9CgogICAgICAvKiBEZWZhdWx0IGJhc2VkIG9uIHByZXZpb3VzIHZhbHVlLiAgKi8KICAgICAgaWYgKHZhbHVlID09IE5VTExfVFJFRSkKCXsKCSAgaWYgKFRZUEVfVkFMVUVTIChlbnVtdHlwZSkpCgkgICAgewoJICAgICAgSE9TVF9XSURFX0lOVCBoaTsKCSAgICAgIHVuc2lnbmVkIEhPU1RfV0lERV9JTlQgbG87CgkgICAgICB0cmVlIHByZXZfdmFsdWU7CgkgICAgICBib29sIG92ZXJmbG93ZWQ7CgoJICAgICAgLyogVGhlIG5leHQgdmFsdWUgaXMgdGhlIHByZXZpb3VzIHZhbHVlIHBsdXMgb25lLiAgV2UgY2FuCgkgICAgICAgICBzYWZlbHkgYXNzdW1lIHRoYXQgdGhlIHByZXZpb3VzIHZhbHVlIGlzIGFuIElOVEVHRVJfQ1NULgoJCSBhZGRfZG91YmxlIGRvZXNuJ3Qga25vdyB0aGUgdHlwZSBvZiB0aGUgdGFyZ2V0IGV4cHJlc3Npb24sCgkJIHNvIHdlIG11c3QgY2hlY2sgd2l0aCBpbnRfZml0c190eXBlX3AgYXMgd2VsbC4gICovCgkgICAgICBwcmV2X3ZhbHVlID0gREVDTF9JTklUSUFMIChUUkVFX1ZBTFVFIChUWVBFX1ZBTFVFUyAoZW51bXR5cGUpKSk7CgkgICAgICBvdmVyZmxvd2VkID0gYWRkX2RvdWJsZSAoVFJFRV9JTlRfQ1NUX0xPVyAocHJldl92YWx1ZSksCgkJCQkgICAgICAgVFJFRV9JTlRfQ1NUX0hJR0ggKHByZXZfdmFsdWUpLAoJCQkJICAgICAgIDEsIDAsICZsbywgJmhpKTsKCSAgICAgIHZhbHVlID0gYnVpbGRfaW50X2NzdF93aWRlIChUUkVFX1RZUEUgKHByZXZfdmFsdWUpLCBsbywgaGkpOwoJICAgICAgb3ZlcmZsb3dlZCB8PSAhaW50X2ZpdHNfdHlwZV9wICh2YWx1ZSwgVFJFRV9UWVBFIChwcmV2X3ZhbHVlKSk7CgoJICAgICAgaWYgKG92ZXJmbG93ZWQpCgkJZXJyb3IgKCJvdmVyZmxvdyBpbiBlbnVtZXJhdGlvbiB2YWx1ZXMgYXQgJXFEIiwgbmFtZSk7CgkgICAgfQoJICBlbHNlCgkgICAgdmFsdWUgPSBpbnRlZ2VyX3plcm9fbm9kZTsKCX0KCiAgICAgIC8qIFJlbW92ZSBuby1vcCBjYXN0cyBmcm9tIHRoZSB2YWx1ZS4gICovCiAgICAgIFNUUklQX1RZUEVfTk9QUyAodmFsdWUpOwogICAgfQoKICAvKiBDKysgYXNzb2NpYXRlcyBlbnVtcyB3aXRoIGdsb2JhbCwgZnVuY3Rpb24sIG9yIGNsYXNzIGRlY2xhcmF0aW9ucy4gICovCiAgY29udGV4dCA9IGN1cnJlbnRfc2NvcGUgKCk7CgogIC8qIEJ1aWxkIHRoZSBhY3R1YWwgZW51bWVyYXRpb24gY29uc3RhbnQuICBOb3RlIHRoYXQgdGhlIGVudW1lcmF0aW9uCiAgICBjb25zdGFudHMgaGF2ZSB0aGUgdHlwZSBvZiB0aGVpciBpbml0aWFsaXplcnMgdW50aWwgdGhlCiAgICBlbnVtZXJhdGlvbiBpcyBjb21wbGV0ZToKCiAgICAgIFsgZGNsLmVudW0gXQoKICAgICAgRm9sbG93aW5nIHRoZSBjbG9zaW5nIGJyYWNlIG9mIGFuIGVudW0tc3BlY2lmaWVyLCBlYWNoIGVudW1lci0KICAgICAgYXRvciBoYXMgdGhlIHR5cGUgb2YgaXRzIGVudW1lcmF0aW9uLiAgUHJpb3IgdG8gdGhlIGNsb3NpbmcKICAgICAgYnJhY2UsIHRoZSB0eXBlIG9mIGVhY2ggZW51bWVyYXRvciBpcyB0aGUgdHlwZSBvZiBpdHMKICAgICAgaW5pdGlhbGl6aW5nIHZhbHVlLgoKICAgIEluIGZpbmlzaF9lbnVtIHdlIHdpbGwgcmVzZXQgdGhlIHR5cGUuICBPZiBjb3Vyc2UsIGlmIHdlJ3JlCiAgICBwcm9jZXNzaW5nIGEgdGVtcGxhdGUsIHRoZXJlIG1heSBiZSBubyB2YWx1ZS4gICovCiAgdHlwZSA9IHZhbHVlID8gVFJFRV9UWVBFICh2YWx1ZSkgOiBOVUxMX1RSRUU7CgogIGlmIChjb250ZXh0ICYmIGNvbnRleHQgPT0gY3VycmVudF9jbGFzc190eXBlKQogICAgLyogVGhpcyBlbnVtIGRlY2xhcmF0aW9uIGlzIGxvY2FsIHRvIHRoZSBjbGFzcy4gIFdlIG5lZWQgdGhlIGZ1bGwKICAgICAgIGxhbmdfZGVjbCBzbyB0aGF0IHdlIGNhbiByZWNvcmQgREVDTF9DTEFTU19DT05URVhULCBmb3IgZXhhbXBsZS4gICovCiAgICBkZWNsID0gYnVpbGRfbGFuZ19kZWNsIChDT05TVF9ERUNMLCBuYW1lLCB0eXBlKTsKICBlbHNlCiAgICAvKiBJdCdzIGEgZ2xvYmFsIGVudW0sIG9yIGl0J3MgbG9jYWwgdG8gYSBmdW5jdGlvbi4gIChOb3RlIGxvY2FsIHRvCiAgICAgIGEgZnVuY3Rpb24gY291bGQgbWVhbiBsb2NhbCB0byBhIGNsYXNzIG1ldGhvZC4gICovCiAgICBkZWNsID0gYnVpbGRfZGVjbCAoQ09OU1RfREVDTCwgbmFtZSwgdHlwZSk7CgogIERFQ0xfQ09OVEVYVCAoZGVjbCkgPSBGUk9CX0NPTlRFWFQgKGNvbnRleHQpOwogIFRSRUVfQ09OU1RBTlQgKGRlY2wpID0gMTsKICBUUkVFX0lOVkFSSUFOVCAoZGVjbCkgPSAxOwogIFRSRUVfUkVBRE9OTFkgKGRlY2wpID0gMTsKICBERUNMX0lOSVRJQUwgKGRlY2wpID0gdmFsdWU7CgogIGlmIChjb250ZXh0ICYmIGNvbnRleHQgPT0gY3VycmVudF9jbGFzc190eXBlKQogICAgLyogSW4gc29tZXRoaW5nIGxpa2UgYHN0cnVjdCBTIHsgZW51bSBFIHsgaSA9IDcgfTsgfTsnIHdlIHB1dCBgaScKICAgICAgIG9uIHRoZSBUWVBFX0ZJRUxEUyBsaXN0IGZvciBgUycuICAoVGhhdCdzIHNvIHRoYXQgeW91IGNhbiBzYXkKICAgICAgIHRoaW5ncyBsaWtlIGBTOjppJyBsYXRlci4pICAqLwogICAgZmluaXNoX21lbWJlcl9kZWNsYXJhdGlvbiAoZGVjbCk7CiAgZWxzZQogICAgcHVzaGRlY2wgKGRlY2wpOwoKICAvKiBBZGQgdGhpcyBlbnVtZXJhdGlvbiBjb25zdGFudCB0byB0aGUgbGlzdCBmb3IgdGhpcyB0eXBlLiAgKi8KICBUWVBFX1ZBTFVFUyAoZW51bXR5cGUpID0gdHJlZV9jb25zIChuYW1lLCBkZWNsLCBUWVBFX1ZBTFVFUyAoZW51bXR5cGUpKTsKfQoKDAovKiBXZSdyZSBkZWZpbmluZyBERUNMLiAgTWFrZSBzdXJlIHRoYXQgaXQncyB0eXBlIGlzIE9LLiAgKi8KCnN0YXRpYyB2b2lkCmNoZWNrX2Z1bmN0aW9uX3R5cGUgKHRyZWUgZGVjbCwgdHJlZSBjdXJyZW50X2Z1bmN0aW9uX3Bhcm1zKQp7CiAgdHJlZSBmbnR5cGUgPSBUUkVFX1RZUEUgKGRlY2wpOwogIHRyZWUgcmV0dXJuX3R5cGUgPSBjb21wbGV0ZV90eXBlIChUUkVFX1RZUEUgKGZudHlwZSkpOwoKICAvKiBJbiBhIGZ1bmN0aW9uIGRlZmluaXRpb24sIGFyZyB0eXBlcyBtdXN0IGJlIGNvbXBsZXRlLiAgKi8KICByZXF1aXJlX2NvbXBsZXRlX3R5cGVzX2Zvcl9wYXJtcyAoY3VycmVudF9mdW5jdGlvbl9wYXJtcyk7CgogIGlmIChkZXBlbmRlbnRfdHlwZV9wIChyZXR1cm5fdHlwZSkpCiAgICByZXR1cm47CiAgaWYgKCFDT01QTEVURV9PUl9WT0lEX1RZUEVfUCAocmV0dXJuX3R5cGUpKQogICAgewogICAgICBlcnJvciAoInJldHVybiB0eXBlICVxI1QgaXMgaW5jb21wbGV0ZSIsIFRSRUVfVFlQRSAoZm50eXBlKSk7CgogICAgICAvKiBNYWtlIGl0IHJldHVybiB2b2lkIGluc3RlYWQsIGJ1dCBkb24ndCBjaGFuZ2UgdGhlCgkgdHlwZSBvZiB0aGUgREVDTF9SRVNVTFQsIGluIGNhc2Ugd2UgaGF2ZSBhIG5hbWVkIHJldHVybiB2YWx1ZS4gICovCiAgICAgIGlmIChUUkVFX0NPREUgKGZudHlwZSkgPT0gTUVUSE9EX1RZUEUpCgl7CgkgIHRyZWUgY3R5cGUgPSBUUkVFX1RZUEUgKFRSRUVfVkFMVUUgKFRZUEVfQVJHX1RZUEVTIChmbnR5cGUpKSk7CgkgIFRSRUVfVFlQRSAoZGVjbCkKCSAgICA9IGJ1aWxkX21ldGhvZF90eXBlX2RpcmVjdGx5IChjdHlwZSwKCQkJCQkgIHZvaWRfdHlwZV9ub2RlLAoJCQkJCSAgRlVOQ1RJT05fQVJHX0NIQUlOIChkZWNsKSk7Cgl9CiAgICAgIGVsc2UKCVRSRUVfVFlQRSAoZGVjbCkKCSAgPSBidWlsZF9mdW5jdGlvbl90eXBlICh2b2lkX3R5cGVfbm9kZSwKCQkJCSBUWVBFX0FSR19UWVBFUyAoVFJFRV9UWVBFIChkZWNsKSkpOwogICAgICBUUkVFX1RZUEUgKGRlY2wpCgk9IGJ1aWxkX2V4Y2VwdGlvbl92YXJpYW50IChmbnR5cGUsCgkJCQkgICBUWVBFX1JBSVNFU19FWENFUFRJT05TIChmbnR5cGUpKTsKICAgIH0KICBlbHNlCiAgICBhYnN0cmFjdF92aXJ0dWFsc19lcnJvciAoZGVjbCwgVFJFRV9UWVBFIChmbnR5cGUpKTsKfQoKLyogQ3JlYXRlIHRoZSBGVU5DVElPTl9ERUNMIGZvciBhIGZ1bmN0aW9uIGRlZmluaXRpb24uCiAgIERFQ0xTUEVDUyBhbmQgREVDTEFSQVRPUiBhcmUgdGhlIHBhcnRzIG9mIHRoZSBkZWNsYXJhdGlvbjsKICAgdGhleSBkZXNjcmliZSB0aGUgZnVuY3Rpb24ncyBuYW1lIGFuZCB0aGUgdHlwZSBpdCByZXR1cm5zLAogICBidXQgdHdpc3RlZCB0b2dldGhlciBpbiBhIGZhc2hpb24gdGhhdCBwYXJhbGxlbHMgdGhlIHN5bnRheCBvZiBDLgoKICAgRkxBR1MgaXMgYSBiaXR3aXNlIG9yIG9mIFNGX1BSRV9QQVJTRUQgKGluZGljYXRpbmcgdGhhdCB0aGUKICAgREVDTEFSQVRPUiBpcyByZWFsbHkgdGhlIERFQ0wgZm9yIHRoZSBmdW5jdGlvbiB3ZSBhcmUgYWJvdXQgdG8KICAgcHJvY2VzcyBhbmQgdGhhdCBERUNMU1BFQ1Mgc2hvdWxkIGJlIGlnbm9yZWQpLCBTRl9JTkNMQVNTX0lOTElORQogICBpbmRpY2F0aW5nIHRoYXQgdGhlIGZ1bmN0aW9uIGlzIGFuIGlubGluZSBkZWZpbmVkIGluLWNsYXNzLgoKICAgVGhpcyBmdW5jdGlvbiBjcmVhdGVzIGEgYmluZGluZyBjb250ZXh0IGZvciB0aGUgZnVuY3Rpb24gYm9keQogICBhcyB3ZWxsIGFzIHNldHRpbmcgdXAgdGhlIEZVTkNUSU9OX0RFQ0wgaW4gY3VycmVudF9mdW5jdGlvbl9kZWNsLgoKICAgRm9yIEMrKywgd2UgbXVzdCBmaXJzdCBjaGVjayB3aGV0aGVyIHRoYXQgZGF0dW0gbWFrZXMgYW55IHNlbnNlLgogICBGb3IgZXhhbXBsZSwgImNsYXNzIEEgbG9jYWxfYSgxLDIpOyIgbWVhbnMgdGhhdCB2YXJpYWJsZSBsb2NhbF9hCiAgIGlzIGFuIGFnZ3JlZ2F0ZSBvZiB0eXBlIEEsIHdoaWNoIHNob3VsZCBoYXZlIGEgY29uc3RydWN0b3IKICAgYXBwbGllZCB0byBpdCB3aXRoIHRoZSBhcmd1bWVudCBsaXN0IFsxLCAyXS4gICovCgp2b2lkCnN0YXJ0X3ByZXBhcnNlZF9mdW5jdGlvbiAodHJlZSBkZWNsMSwgdHJlZSBhdHRycywgaW50IGZsYWdzKQp7CiAgdHJlZSBjdHlwZSA9IE5VTExfVFJFRTsKICB0cmVlIGZudHlwZTsKICB0cmVlIHJlc3R5cGU7CiAgaW50IGRvaW5nX2ZyaWVuZCA9IDA7CiAgc3RydWN0IGNwX2JpbmRpbmdfbGV2ZWwgKmJsOwogIHRyZWUgY3VycmVudF9mdW5jdGlvbl9wYXJtczsKICBzdHJ1Y3QgY19maWxlaW5mbyAqZmluZm8KICAgID0gZ2V0X2ZpbGVpbmZvIChsYmFzZW5hbWUgKExPQ0FUSU9OX0ZJTEUgKERFQ0xfU09VUkNFX0xPQ0FUSU9OIChkZWNsMSkpKSk7CgogIC8qIFNhbml0eSBjaGVjay4gICovCiAgZ2NjX2Fzc2VydCAoVFJFRV9DT0RFIChUUkVFX1ZBTFVFICh2b2lkX2xpc3Rfbm9kZSkpID09IFZPSURfVFlQRSk7CiAgZ2NjX2Fzc2VydCAoVFJFRV9DSEFJTiAodm9pZF9saXN0X25vZGUpID09IE5VTExfVFJFRSk7CgogIGZudHlwZSA9IFRSRUVfVFlQRSAoZGVjbDEpOwogIGlmIChUUkVFX0NPREUgKGZudHlwZSkgPT0gTUVUSE9EX1RZUEUpCiAgICBjdHlwZSA9IFRZUEVfTUVUSE9EX0JBU0VUWVBFIChmbnR5cGUpOwoKICAvKiBJU08gQysrIDExLjQvNS4gIEEgZnJpZW5kIGZ1bmN0aW9uIGRlZmluZWQgaW4gYSBjbGFzcyBpcyBpbgogICAgIHRoZSAobGV4aWNhbCkgc2NvcGUgb2YgdGhlIGNsYXNzIGluIHdoaWNoIGl0IGlzIGRlZmluZWQuICAqLwogIGlmICghY3R5cGUgJiYgREVDTF9GUklFTkRfUCAoZGVjbDEpKQogICAgewogICAgICBjdHlwZSA9IERFQ0xfRlJJRU5EX0NPTlRFWFQgKGRlY2wxKTsKCiAgICAgIC8qIENUWVBFIGNvdWxkIGJlIG51bGwgaGVyZSBpZiB3ZSdyZSBkZWFsaW5nIHdpdGggYSB0ZW1wbGF0ZTsKCSBmb3IgZXhhbXBsZSwgYGlubGluZSBmcmllbmQgZmxvYXQgZm9vKCknIGluc2lkZSBhIHRlbXBsYXRlCgkgd2lsbCBoYXZlIG5vIENUWVBFIHNldC4gICovCiAgICAgIGlmIChjdHlwZSAmJiBUUkVFX0NPREUgKGN0eXBlKSAhPSBSRUNPUkRfVFlQRSkKCWN0eXBlID0gTlVMTF9UUkVFOwogICAgICBlbHNlCglkb2luZ19mcmllbmQgPSAxOwogICAgfQoKICBpZiAoREVDTF9ERUNMQVJFRF9JTkxJTkVfUCAoZGVjbDEpCiAgICAgICYmIGxvb2t1cF9hdHRyaWJ1dGUgKCJub2lubGluZSIsIGF0dHJzKSkKICAgIHdhcm5pbmcgKCIlSmlubGluZSBmdW5jdGlvbiAlcUQgZ2l2ZW4gYXR0cmlidXRlIG5vaW5saW5lIiwgZGVjbDEsIGRlY2wxKTsKCiAgaWYgKERFQ0xfTUFZQkVfSU5fQ0hBUkdFX0NPTlNUUlVDVE9SX1AgKGRlY2wxKSkKICAgIC8qIFRoaXMgaXMgYSBjb25zdHJ1Y3Rvciwgd2UgbXVzdCBlbnN1cmUgdGhhdCBhbnkgZGVmYXVsdCBhcmdzCiAgICAgICBpbnRyb2R1Y2VkIGJ5IHRoaXMgZGVmaW5pdGlvbiBhcmUgcHJvcGFnYXRlZCB0byB0aGUgY2xvbmVzCiAgICAgICBub3cuIFRoZSBjbG9uZXMgYXJlIHVzZWQgZGlyZWN0bHkgaW4gb3ZlcmxvYWQgcmVzb2x1dGlvbi4gICovCiAgICBhZGp1c3RfY2xvbmVfYXJncyAoZGVjbDEpOwoKICAvKiBTb21ldGltZXMgd2UgZG9uJ3Qgbm90aWNlIHRoYXQgYSBmdW5jdGlvbiBpcyBhIHN0YXRpYyBtZW1iZXIsIGFuZAogICAgIGJ1aWxkIGEgTUVUSE9EX1RZUEUgZm9yIGl0LiAgRml4IHRoYXQgdXAgbm93LiAgKi8KICBpZiAoY3R5cGUgIT0gTlVMTF9UUkVFICYmIERFQ0xfU1RBVElDX0ZVTkNUSU9OX1AgKGRlY2wxKQogICAgICAmJiBUUkVFX0NPREUgKFRSRUVfVFlQRSAoZGVjbDEpKSA9PSBNRVRIT0RfVFlQRSkKICAgIHsKICAgICAgcmV2ZXJ0X3N0YXRpY19tZW1iZXJfZm4gKGRlY2wxKTsKICAgICAgY3R5cGUgPSBOVUxMX1RSRUU7CiAgICB9CgogIC8qIFNldCB1cCBjdXJyZW50X2NsYXNzX3R5cGUsIGFuZCBlbnRlciB0aGUgc2NvcGUgb2YgdGhlIGNsYXNzLCBpZgogICAgIGFwcHJvcHJpYXRlLiAgKi8KICBpZiAoY3R5cGUpCiAgICBwdXNoX25lc3RlZF9jbGFzcyAoY3R5cGUpOwogIGVsc2UgaWYgKERFQ0xfU1RBVElDX0ZVTkNUSU9OX1AgKGRlY2wxKSkKICAgIHB1c2hfbmVzdGVkX2NsYXNzIChERUNMX0NPTlRFWFQgKGRlY2wxKSk7CgogIC8qIE5vdyB0aGF0IHdlIGhhdmUgZW50ZXJlZCB0aGUgc2NvcGUgb2YgdGhlIGNsYXNzLCB3ZSBtdXN0IHJlc3RvcmUKICAgICB0aGUgYmluZGluZ3MgZm9yIGFueSB0ZW1wbGF0ZSBwYXJhbWV0ZXJzIHN1cnJvdW5kaW5nIERFQ0wxLCBpZiBpdAogICAgIGlzIGFuIGlubGluZSBtZW1iZXIgdGVtcGxhdGUuICAoT3JkZXIgaXMgaW1wb3J0YW50OyBjb25zaWRlciB0aGUKICAgICBjYXNlIHdoZXJlIGEgdGVtcGxhdGUgcGFyYW1ldGVyIGhhcyB0aGUgc2FtZSBuYW1lIGFzIGEgZmllbGQgb2YKICAgICB0aGUgY2xhc3MuKSAgSXQgaXMgbm90IHVudGlsIGFmdGVyIHRoaXMgcG9pbnQgdGhhdAogICAgIFBST0NFU1NJTkdfVEVNUExBVEVfREVDTCBpcyBndWFyYW50ZWVkIHRvIGJlIHNldCB1cCBjb3JyZWN0bHkuICAqLwogIGlmIChmbGFncyAmIFNGX0lOQ0xBU1NfSU5MSU5FKQogICAgbWF5YmVfYmVnaW5fbWVtYmVyX3RlbXBsYXRlX3Byb2Nlc3NpbmcgKGRlY2wxKTsKCiAgLyogRWZmZWN0aXZlIEMrKyBydWxlIDE1LiAgKi8KICBpZiAod2Fybl9lY3BwCiAgICAgICYmIERFQ0xfT1ZFUkxPQURFRF9PUEVSQVRPUl9QIChkZWNsMSkgPT0gTk9QX0VYUFIKICAgICAgJiYgVFJFRV9DT0RFIChUUkVFX1RZUEUgKGZudHlwZSkpID09IFZPSURfVFlQRSkKICAgIHdhcm5pbmcgKCIlPG9wZXJhdG9yPSU+IHNob3VsZCByZXR1cm4gYSByZWZlcmVuY2UgdG8gJTwqdGhpcyU+Iik7CgogIC8qIE1ha2UgdGhlIGluaXRfdmFsdWUgbm9uemVybyBzbyBwdXNoZGVjbCBrbm93cyB0aGlzIGlzIG5vdCB0ZW50YXRpdmUuCiAgICAgZXJyb3JfbWFya19ub2RlIGlzIHJlcGxhY2VkIGJlbG93IChpbiBwb3BsZXZlbCkgd2l0aCB0aGUgQkxPQ0suICAqLwogIGlmICghREVDTF9JTklUSUFMIChkZWNsMSkpCiAgICBERUNMX0lOSVRJQUwgKGRlY2wxKSA9IGVycm9yX21hcmtfbm9kZTsKCiAgLyogVGhpcyBmdW5jdGlvbiBleGlzdHMgaW4gc3RhdGljIHN0b3JhZ2UuCiAgICAgKFRoaXMgZG9lcyBub3QgbWVhbiBgc3RhdGljJyBpbiB0aGUgQyBzZW5zZSEpICAqLwogIFRSRUVfU1RBVElDIChkZWNsMSkgPSAxOwoKICAvKiBXZSBtdXN0IGNhbGwgcHVzaF90ZW1wbGF0ZV9kZWNsIGFmdGVyIGN1cnJlbnRfY2xhc3NfdHlwZSBpcyBzZXQKICAgICB1cC4gIChJZiB3ZSBhcmUgcHJvY2Vzc2luZyBpbmxpbmUgZGVmaW5pdGlvbnMgYWZ0ZXIgZXhpdGluZyBhCiAgICAgY2xhc3Mgc2NvcGUsIGN1cnJlbnRfY2xhc3NfdHlwZSB3aWxsIGJlIE5VTExfVFJFRSB1bnRpbCBzZXQgYWJvdmUKICAgICBieSBwdXNoX25lc3RlZF9jbGFzcy4pICAqLwogIGlmIChwcm9jZXNzaW5nX3RlbXBsYXRlX2RlY2wpCiAgICB7CiAgICAgIC8qIEZJWE1FOiBIYW5kbGUgZXJyb3JfbWFya19ub2RlIG1vcmUgZ3JhY2VmdWxseS4gICovCiAgICAgIHRyZWUgbmV3ZGVjbDEgPSBwdXNoX3RlbXBsYXRlX2RlY2wgKGRlY2wxKTsKICAgICAgaWYgKG5ld2RlY2wxICE9IGVycm9yX21hcmtfbm9kZSkKICAgICAgICBkZWNsMSA9IG5ld2RlY2wxOwogICAgfQoKICAvKiBXZSBhcmUgbm93IGluIHRoZSBzY29wZSBvZiB0aGUgZnVuY3Rpb24gYmVpbmcgZGVmaW5lZC4gICovCiAgY3VycmVudF9mdW5jdGlvbl9kZWNsID0gZGVjbDE7CgogIC8qIFNhdmUgdGhlIHBhcm0gbmFtZXMgb3IgZGVjbHMgZnJvbSB0aGlzIGZ1bmN0aW9uJ3MgZGVjbGFyYXRvcgogICAgIHdoZXJlIHN0b3JlX3Bhcm1fZGVjbHMgd2lsbCBmaW5kIHRoZW0uICAqLwogIGN1cnJlbnRfZnVuY3Rpb25fcGFybXMgPSBERUNMX0FSR1VNRU5UUyAoZGVjbDEpOwoKICAvKiBNYWtlIHN1cmUgdGhlIHBhcmFtZXRlciBhbmQgcmV0dXJuIHR5cGVzIGFyZSByZWFzb25hYmxlLiAgV2hlbgogICAgIHlvdSBkZWNsYXJlIGEgZnVuY3Rpb24sIHRoZXNlIHR5cGVzIGNhbiBiZSBpbmNvbXBsZXRlLCBidXQgdGhleQogICAgIG11c3QgYmUgY29tcGxldGUgd2hlbiB5b3UgZGVmaW5lIHRoZSBmdW5jdGlvbi4gICovCiAgY2hlY2tfZnVuY3Rpb25fdHlwZSAoZGVjbDEsIGN1cnJlbnRfZnVuY3Rpb25fcGFybXMpOwoKICAvKiBCdWlsZCB0aGUgcmV0dXJuIGRlY2xhcmF0aW9uIGZvciB0aGUgZnVuY3Rpb24uICAqLwogIHJlc3R5cGUgPSBUUkVFX1RZUEUgKGZudHlwZSk7CiAgLyogUHJvbW90ZSB0aGUgdmFsdWUgdG8gaW50IGJlZm9yZSByZXR1cm5pbmcgaXQuICAqLwogIGlmIChjX3Byb21vdGluZ19pbnRlZ2VyX3R5cGVfcCAocmVzdHlwZSkpCiAgICByZXN0eXBlID0gdHlwZV9wcm9tb3Rlc190byAocmVzdHlwZSk7CiAgaWYgKERFQ0xfUkVTVUxUIChkZWNsMSkgPT0gTlVMTF9UUkVFKQogICAgewogICAgICB0cmVlIHJlc2RlY2w7CgogICAgICByZXNkZWNsID0gYnVpbGRfZGVjbCAoUkVTVUxUX0RFQ0wsIDAsIFRZUEVfTUFJTl9WQVJJQU5UIChyZXN0eXBlKSk7CiAgICAgIERFQ0xfQVJUSUZJQ0lBTCAocmVzZGVjbCkgPSAxOwogICAgICBERUNMX0lHTk9SRURfUCAocmVzZGVjbCkgPSAxOwogICAgICBERUNMX1JFU1VMVCAoZGVjbDEpID0gcmVzZGVjbDsKCiAgICAgIGNwX2FwcGx5X3R5cGVfcXVhbHNfdG9fZGVjbCAoY3BfdHlwZV9xdWFscyAocmVzdHlwZSksIHJlc2RlY2wpOwogICAgfQoKICAvKiBJbml0aWFsaXplIFJUTCBtYWNoaW5lcnkuICBXZSBjYW5ub3QgZG8gdGhpcyB1bnRpbAogICAgIENVUlJFTlRfRlVOQ1RJT05fREVDTCBhbmQgREVDTF9SRVNVTFQgYXJlIHNldCB1cC4gIFdlIGRvIHRoaXMKICAgICBldmVuIHdoZW4gcHJvY2Vzc2luZyBhIHRlbXBsYXRlOyB0aGlzIGlzIGhvdyB3ZSBnZXQKICAgICBDRlVOIHNldCB1cCwgYW5kIG91ciBwZXItZnVuY3Rpb24gdmFyaWFibGVzIGluaXRpYWxpemVkLgogICAgIEZJWE1FIGZhY3RvciBvdXQgdGhlIG5vbi1SVEwgc3R1ZmYuICAqLwogIGJsID0gY3VycmVudF9iaW5kaW5nX2xldmVsOwogIGFsbG9jYXRlX3N0cnVjdF9mdW5jdGlvbiAoZGVjbDEpOwogIGN1cnJlbnRfYmluZGluZ19sZXZlbCA9IGJsOwoKICAvKiBFdmVuIHRob3VnaCB3ZSdyZSBpbnNpZGUgYSBmdW5jdGlvbiBib2R5LCB3ZSBzdGlsbCBkb24ndCB3YW50IHRvCiAgICAgY2FsbCBleHBhbmRfZXhwciB0byBjYWxjdWxhdGUgdGhlIHNpemUgb2YgYSB2YXJpYWJsZS1zaXplZCBhcnJheS4KICAgICBXZSBoYXZlbid0IG5lY2Vzc2FyaWx5IGFzc2lnbmVkIFJUTCB0byBhbGwgdmFyaWFibGVzIHlldCwgc28gaXQncwogICAgIG5vdCBzYWZlIHRvIHRyeSB0byBleHBhbmQgZXhwcmVzc2lvbnMgaW52b2x2aW5nIHRoZW0uICAqLwogIGNmdW4tPnhfZG9udF9zYXZlX3BlbmRpbmdfc2l6ZXNfcCA9IDE7CgogIC8qIFN0YXJ0IHRoZSBzdGF0ZW1lbnQtdHJlZSwgc3RhcnQgdGhlIHRyZWUgbm93LiAgKi8KICBERUNMX1NBVkVEX1RSRUUgKGRlY2wxKSA9IHB1c2hfc3RtdF9saXN0ICgpOwoKICAvKiBMZXQgdGhlIHVzZXIga25vdyB3ZSdyZSBjb21waWxpbmcgdGhpcyBmdW5jdGlvbi4gICovCiAgYW5ub3VuY2VfZnVuY3Rpb24gKGRlY2wxKTsKCiAgLyogUmVjb3JkIHRoZSBkZWNsIHNvIHRoYXQgdGhlIGZ1bmN0aW9uIG5hbWUgaXMgZGVmaW5lZC4KICAgICBJZiB3ZSBhbHJlYWR5IGhhdmUgYSBkZWNsIGZvciB0aGlzIG5hbWUsIGFuZCBpdCBpcyBhIEZVTkNUSU9OX0RFQ0wsCiAgICAgdXNlIHRoZSBvbGQgZGVjbC4gICovCiAgaWYgKCFwcm9jZXNzaW5nX3RlbXBsYXRlX2RlY2wgJiYgIShmbGFncyAmIFNGX1BSRV9QQVJTRUQpKQogICAgewogICAgICAvKiBBIHNwZWNpYWxpemF0aW9uIGlzIG5vdCB1c2VkIHRvIGd1aWRlIG92ZXJsb2FkIHJlc29sdXRpb24uICAqLwogICAgICBpZiAoIURFQ0xfRlVOQ1RJT05fTUVNQkVSX1AgKGRlY2wxKQoJICAmJiAhKERFQ0xfVVNFX1RFTVBMQVRFIChkZWNsMSkgJiYKCSAgICAgICBQUklNQVJZX1RFTVBMQVRFX1AgKERFQ0xfVElfVEVNUExBVEUgKGRlY2wxKSkpKQoJewoJICB0cmVlIG9sZGRlY2wgPSBwdXNoZGVjbCAoZGVjbDEpOwoKCSAgaWYgKG9sZGRlY2wgPT0gZXJyb3JfbWFya19ub2RlKQoJICAgIC8qIElmIHNvbWV0aGluZyB3ZW50IHdyb25nIHdoZW4gcmVnaXN0ZXJpbmcgdGhlIGRlY2xhcmF0aW9uLAoJICAgICAgIHVzZSBERUNMMTsgd2UgaGF2ZSB0byBoYXZlIGEgRlVOQ1RJT05fREVDTCB0byB1c2Ugd2hlbgoJICAgICAgIHBhcnNpbmcgdGhlIGJvZHkgb2YgdGhlIGZ1bmN0aW9uLiAgKi8KCSAgICA7CgkgIGVsc2UKCSAgICAvKiBBUFBMRSBMT0NBTCBiZWdpbiBvcHRpbWl6YXRpb24gcHJhZ21hcyAzMTI0MjM1LzM0MjAyNDIgKi8KCSAgICB7CgkgICAgICAvKiBPdGhlcndpc2UsIE9MRERFQ0wgaXMgZWl0aGVyIGEgcHJldmlvdXMgZGVjbGFyYXRpb24gb2YKCQkgdGhlIHNhbWUgZnVuY3Rpb24gb3IgREVDTDEgaXRzZWxmLiAgKi8KCSAgICAgIGNvcHlfZnVuY19jbF9wZl9vcHRzX21hcHBpbmcgKGRlY2wxLCBvbGRkZWNsKTsKCSAgICAgIGRlY2wxID0gb2xkZGVjbDsKCSAgICB9CgkgICAgLyogQVBQTEUgTE9DQUwgZW5kIG9wdGltaXphdGlvbiBwcmFnbWFzIDMxMjQyMzUvMzQyMDI0MiAqLwoJfQogICAgICBlbHNlCgl7CgkgIC8qIFdlIG5lZWQgdG8gc2V0IHRoZSBERUNMX0NPTlRFWFQuICAqLwoJICBpZiAoIURFQ0xfQ09OVEVYVCAoZGVjbDEpICYmIERFQ0xfVEVNUExBVEVfSU5GTyAoZGVjbDEpKQoJICAgIERFQ0xfQ09OVEVYVCAoZGVjbDEpID0gREVDTF9DT05URVhUIChERUNMX1RJX1RFTVBMQVRFIChkZWNsMSkpOwoJICAvKiBBbmQgbWFrZSBzdXJlIHdlIGhhdmUgZW5vdWdoIGRlZmF1bHQgYXJncy4gICovCgkgIGNoZWNrX2RlZmF1bHRfYXJncyAoZGVjbDEpOwoJfQogICAgICBmbnR5cGUgPSBUUkVFX1RZUEUgKGRlY2wxKTsKICAgIH0KCiAgLyogRGV0ZXJtaW5lIHRoZSBFTEYgdmlzaWJpbGl0eSBhdHRyaWJ1dGUgZm9yIHRoZSBmdW5jdGlvbi4gIFdlIG11c3QKICAgICBub3QgZG8gdGhpcyBiZWZvcmUgY2FsbGluZyAicHVzaGRlY2wiLCBhcyB3ZSBtdXN0IGFsbG93CiAgICAgImR1cGxpY2F0ZV9kZWNscyIgdG8gbWVyZ2UgYW55IGF0dHJpYnV0ZXMgYXBwcm9wcmlhdGVseS4gICovCiAgaWYgKCFERUNMX0NMT05FRF9GVU5DVElPTl9QIChkZWNsMSkpCiAgICBkZXRlcm1pbmVfdmlzaWJpbGl0eSAoZGVjbDEpOwoKICAvKiBSZXNldCB0aGVzZSBpbiBjYXNlIHRoZSBjYWxsIHRvIHB1c2hkZWNsIGNoYW5nZWQgdGhlbS4gICovCiAgY3VycmVudF9mdW5jdGlvbl9kZWNsID0gZGVjbDE7CiAgY2Z1bi0+ZGVjbCA9IGRlY2wxOwoKICAvKiBJZiB3ZSBhcmUgKGVycm9uZW91c2x5KSBkZWZpbmluZyBhIGZ1bmN0aW9uIHRoYXQgd2UgaGF2ZSBhbHJlYWR5CiAgICAgZGVmaW5lZCBiZWZvcmUsIHdpcGUgb3V0IHdoYXQgd2Uga25ldyBiZWZvcmUuICAqLwogIGlmICghREVDTF9QRU5ESU5HX0lOTElORV9QIChkZWNsMSkpCiAgICBERUNMX1NBVkVEX0ZVTkNUSU9OX0RBVEEgKGRlY2wxKSA9IE5VTEw7CgogIGlmIChjdHlwZSAmJiAhZG9pbmdfZnJpZW5kICYmICFERUNMX1NUQVRJQ19GVU5DVElPTl9QIChkZWNsMSkpCiAgICB7CiAgICAgIC8qIFdlIGtub3cgdGhhdCB0aGlzIHdhcyBzZXQgdXAgYnkgYGdyb2tjbGFzc2ZuJy4gIFdlIGRvIG5vdAoJIHdhaXQgdW50aWwgYHN0b3JlX3Bhcm1fZGVjbHMnLCBzaW5jZSBldmlsIHBhcnNlIGVycm9ycyBtYXkKCSBuZXZlciBnZXQgdXMgdG8gdGhhdCBwb2ludC4gIEhlcmUgd2Uga2VlcCB0aGUgY29uc2lzdGVuY3kKCSBiZXR3ZWVuIGBjdXJyZW50X2NsYXNzX3R5cGUnIGFuZCBgY3VycmVudF9jbGFzc19wdHInLiAgKi8KICAgICAgdHJlZSB0ID0gREVDTF9BUkdVTUVOVFMgKGRlY2wxKTsKCiAgICAgIGdjY19hc3NlcnQgKHQgIT0gTlVMTF9UUkVFICYmIFRSRUVfQ09ERSAodCkgPT0gUEFSTV9ERUNMKTsKICAgICAgZ2NjX2Fzc2VydCAoVFJFRV9DT0RFIChUUkVFX1RZUEUgKHQpKSA9PSBQT0lOVEVSX1RZUEUpOwoKICAgICAgY3BfZnVuY3Rpb25fY2hhaW4tPnhfY3VycmVudF9jbGFzc19yZWYKCT0gYnVpbGRfaW5kaXJlY3RfcmVmICh0LCBOVUxMKTsKICAgICAgY3BfZnVuY3Rpb25fY2hhaW4tPnhfY3VycmVudF9jbGFzc19wdHIgPSB0OwoKICAgICAgLyogQ29uc3RydWN0b3JzIGFuZCBkZXN0cnVjdG9ycyBuZWVkIHRvIGtub3cgd2hldGhlciB0aGV5J3JlICJpbgoJIGNoYXJnZSIgb2YgaW5pdGlhbGl6aW5nIHZpcnR1YWwgYmFzZSBjbGFzc2VzLiAgKi8KICAgICAgdCA9IFRSRUVfQ0hBSU4gKHQpOwogICAgICBpZiAoREVDTF9IQVNfSU5fQ0hBUkdFX1BBUk1fUCAoZGVjbDEpKQoJewoJICBjdXJyZW50X2luX2NoYXJnZV9wYXJtID0gdDsKCSAgdCA9IFRSRUVfQ0hBSU4gKHQpOwoJfQogICAgICBpZiAoREVDTF9IQVNfVlRUX1BBUk1fUCAoZGVjbDEpKQoJewoJICBnY2NfYXNzZXJ0IChERUNMX05BTUUgKHQpID09IHZ0dF9wYXJtX2lkZW50aWZpZXIpOwoJICBjdXJyZW50X3Z0dF9wYXJtID0gdDsKCX0KICAgIH0KCiAgaWYgKERFQ0xfSU5URVJGQUNFX0tOT1dOIChkZWNsMSkpCiAgICB7CiAgICAgIHRyZWUgY3R4ID0gZGVjbF9mdW5jdGlvbl9jb250ZXh0IChkZWNsMSk7CgogICAgICBpZiAoREVDTF9OT1RfUkVBTExZX0VYVEVSTiAoZGVjbDEpKQoJREVDTF9FWFRFUk5BTCAoZGVjbDEpID0gMDsKCiAgICAgIGlmIChjdHggIT0gTlVMTF9UUkVFICYmIERFQ0xfREVDTEFSRURfSU5MSU5FX1AgKGN0eCkKCSAgJiYgVFJFRV9QVUJMSUMgKGN0eCkpCgkvKiBUaGlzIGlzIGEgZnVuY3Rpb24gaW4gYSBsb2NhbCBjbGFzcyBpbiBhbiBleHRlcm4gaW5saW5lCgkgICBmdW5jdGlvbi4gICovCgljb21kYXRfbGlua2FnZSAoZGVjbDEpOwogICAgfQogIC8qIElmIHRoaXMgZnVuY3Rpb24gYmVsb25ncyB0byBhbiBpbnRlcmZhY2UsIGl0IGlzIHB1YmxpYy4KICAgICBJZiBpdCBiZWxvbmdzIHRvIHNvbWVvbmUgZWxzZSdzIGludGVyZmFjZSwgaXQgaXMgYWxzbyBleHRlcm5hbC4KICAgICBUaGlzIG9ubHkgYWZmZWN0cyBpbmxpbmVzIGFuZCB0ZW1wbGF0ZSBpbnN0YW50aWF0aW9ucy4gICovCiAgZWxzZSBpZiAoZmluZm8tPmludGVyZmFjZV91bmtub3duID09IDAKCSAgICYmICEgREVDTF9URU1QTEFURV9JTlNUQU5USUFUSU9OIChkZWNsMSkpCiAgICB7CiAgICAgIGlmIChERUNMX0RFQ0xBUkVEX0lOTElORV9QIChkZWNsMSkKCSAgfHwgREVDTF9URU1QTEFURV9JTlNUQU5USUFUSU9OIChkZWNsMSkKCSAgfHwgcHJvY2Vzc2luZ190ZW1wbGF0ZV9kZWNsKQoJewoJICBERUNMX0VYVEVSTkFMIChkZWNsMSkKCSAgICA9IChmaW5mby0+aW50ZXJmYWNlX29ubHkKCSAgICAgICB8fCAoREVDTF9ERUNMQVJFRF9JTkxJTkVfUCAoZGVjbDEpCgkJICAgJiYgISBmbGFnX2ltcGxlbWVudF9pbmxpbmVzCgkJICAgJiYgIURFQ0xfVklOREVYIChkZWNsMSkpKTsKCgkgIC8qIEZvciBXSU4zMiB3ZSBhbHNvIHdhbnQgdG8gcHV0IHRoZXNlIGluIGxpbmtvbmNlIHNlY3Rpb25zLiAgKi8KCSAgbWF5YmVfbWFrZV9vbmVfb25seSAoZGVjbDEpOwoJfQogICAgICBlbHNlCglERUNMX0VYVEVSTkFMIChkZWNsMSkgPSAwOwogICAgICBERUNMX05PVF9SRUFMTFlfRVhURVJOIChkZWNsMSkgPSAwOwogICAgICBERUNMX0lOVEVSRkFDRV9LTk9XTiAoZGVjbDEpID0gMTsKICAgICAgLyogSWYgdGhpcyBmdW5jdGlvbiBpcyBpbiBhbiBpbnRlcmZhY2UgaW1wbGVtZW50ZWQgaW4gdGhpcyBmaWxlLAoJIG1ha2Ugc3VyZSB0aGF0IHRoZSBiYWNrZW5kIGtub3dzIHRvIGVtaXQgdGhpcyBmdW5jdGlvbiAKCSBoZXJlLiAgKi8KICAgICAgaWYgKCFERUNMX0VYVEVSTkFMIChkZWNsMSkpCgltYXJrX25lZWRlZCAoZGVjbDEpOwogICAgfQogIGVsc2UgaWYgKGZpbmZvLT5pbnRlcmZhY2VfdW5rbm93biAmJiBmaW5mby0+aW50ZXJmYWNlX29ubHkKCSAgICYmICEgREVDTF9URU1QTEFURV9JTlNUQU5USUFUSU9OIChkZWNsMSkpCiAgICB7CiAgICAgIC8qIElmIE1VTFRJUExFX1NZTUJPTF9TUEFDRVMgaXMgZGVmaW5lZCBhbmQgd2Ugc2F3IGEgI3ByYWdtYQoJIGludGVyZmFjZSwgd2Ugd2lsbCBoYXZlIGJvdGggZmluZm8tPmludGVyZmFjZV91bmtub3duIGFuZAoJIGZpbmZvLT5pbnRlcmZhY2Vfb25seSBzZXQuICBJbiB0aGF0IGNhc2UsIHdlIGRvbid0IHdhbnQgdG8KCSB1c2UgdGhlIG5vcm1hbCBoZXVyaXN0aWNzIGJlY2F1c2Ugc29tZW9uZSB3aWxsIHN1cHBseSBhCgkgI3ByYWdtYSBpbXBsZW1lbnRhdGlvbiBlbHNld2hlcmUsIGFuZCBkZWR1Y2luZyBpdCBoZXJlIHdvdWxkCgkgcHJvZHVjZSBhIGNvbmZsaWN0LiAgKi8KICAgICAgY29tZGF0X2xpbmthZ2UgKGRlY2wxKTsKICAgICAgREVDTF9FWFRFUk5BTCAoZGVjbDEpID0gMDsKICAgICAgREVDTF9JTlRFUkZBQ0VfS05PV04gKGRlY2wxKSA9IDE7CiAgICAgIERFQ0xfREVGRVJfT1VUUFVUIChkZWNsMSkgPSAxOwogICAgfQogIGVsc2UKICAgIHsKICAgICAgLyogVGhpcyBpcyBhIGRlZmluaXRpb24sIG5vdCBhIHJlZmVyZW5jZS4KCSBTbyBjbGVhciBERUNMX0VYVEVSTkFMLiAgKi8KICAgICAgREVDTF9FWFRFUk5BTCAoZGVjbDEpID0gMDsKCiAgICAgIGlmICgoREVDTF9ERUNMQVJFRF9JTkxJTkVfUCAoZGVjbDEpCgkgICB8fCBERUNMX1RFTVBMQVRFX0lOU1RBTlRJQVRJT04gKGRlY2wxKSkKCSAgJiYgISBERUNMX0lOVEVSRkFDRV9LTk9XTiAoZGVjbDEpCgkgIC8qIERvbid0IHRyeSB0byBkZWZlciBuZXN0ZWQgZnVuY3Rpb25zIGZvciBub3cuICAqLwoJICAmJiAhIGRlY2xfZnVuY3Rpb25fY29udGV4dCAoZGVjbDEpKQoJREVDTF9ERUZFUl9PVVRQVVQgKGRlY2wxKSA9IDE7CiAgICAgIGVsc2UKCURFQ0xfSU5URVJGQUNFX0tOT1dOIChkZWNsMSkgPSAxOwogICAgfQoKICBiZWdpbl9zY29wZSAoc2tfZnVuY3Rpb25fcGFybXMsIGRlY2wxKTsKCiAgKytmdW5jdGlvbl9kZXB0aDsKCiAgaWYgKERFQ0xfREVTVFJVQ1RPUl9QIChkZWNsMSkKICAgICAgfHwgKERFQ0xfQ09OU1RSVUNUT1JfUCAoZGVjbDEpCgkgICYmIHRhcmdldG0uY3h4LmNkdG9yX3JldHVybnNfdGhpcyAoKSkpCiAgICB7CiAgICAgIGNkdG9yX2xhYmVsID0gYnVpbGRfZGVjbCAoTEFCRUxfREVDTCwgTlVMTF9UUkVFLCBOVUxMX1RSRUUpOwogICAgICBERUNMX0NPTlRFWFQgKGNkdG9yX2xhYmVsKSA9IGN1cnJlbnRfZnVuY3Rpb25fZGVjbDsKICAgIH0KCiAgLyogQVBQTEUgTE9DQUwgYmVnaW4gQ1cgYXNtIGJsb2NrcyAqLwogIC8qIElmIHRoaXMgd2FzIGEgZnVuY3Rpb24gZGVjbGFyZWQgYXMgYW4gYXNzZW1ibHkgZnVuY3Rpb24sIGNoYW5nZQogICAgIHRoZSBzdGF0ZSB0byBleHBlY3QgdG8gc2VlIEMrKyBkZWNscywgcG9zc2libHkgZm9sbG93ZWQgYnkgYXNzZW1ibHkKICAgICBjb2RlLiAgKi8KICBpZiAoREVDTF9JQVNNX0FTTV9GVU5DVElPTiAoY3VycmVudF9mdW5jdGlvbl9kZWNsKSkKICAgIHsKICAgICAgaWFzbV9zdGF0ZSA9IGlhc21fZGVjbHM7CiAgICAgIGlhc21faW5fZGVjbCA9IDA7CiAgICAgIGN1cnJlbnRfZnVuY3Rpb25fcmV0dXJuc19hYm5vcm1hbGx5ID0gMTsKICAgICAgVFJFRV9OT19XQVJOSU5HIChjdXJyZW50X2Z1bmN0aW9uX2RlY2wpID0gMTsKICAgIH0KICAvKiBBUFBMRSBMT0NBTCBlbmQgQ1cgYXNtIGJsb2NrcyAqLwoKICBzdGFydF9mbmFtZV9kZWNscyAoKTsKCiAgc3RvcmVfcGFybV9kZWNscyAoY3VycmVudF9mdW5jdGlvbl9wYXJtcyk7Cn0KCgovKiBMaWtlIHN0YXJ0X3ByZXBhcnNlZF9mdW5jdGlvbiwgZXhjZXB0IHRoYXQgaW5zdGVhZCBvZiBhCiAgIEZVTkNUSU9OX0RFQ0wsIHRoaXMgZnVuY3Rpb24gdGFrZXMgREVDTFNQRUNTIGFuZCBERUNMQVJBVE9SLgoKICAgUmV0dXJucyAxIG9uIHN1Y2Nlc3MuICBJZiB0aGUgREVDTEFSQVRPUiBpcyBub3Qgc3VpdGFibGUgZm9yIGEgZnVuY3Rpb24KICAgKGl0IGRlZmluZXMgYSBkYXR1bSBpbnN0ZWFkKSwgd2UgcmV0dXJuIDAsIHdoaWNoIHRlbGxzCiAgIHl5cGFyc2UgdG8gcmVwb3J0IGEgcGFyc2UgZXJyb3IuICAqLwoKaW50CnN0YXJ0X2Z1bmN0aW9uIChjcF9kZWNsX3NwZWNpZmllcl9zZXEgKmRlY2xzcGVjcywKCQljb25zdCBjcF9kZWNsYXJhdG9yICpkZWNsYXJhdG9yLAoJCXRyZWUgYXR0cnMpCnsKICB0cmVlIGRlY2wxOwoKICBpZiAoaGF2ZV9leHRlcm5fc3BlYykKICAgIHsKICAgICAgZGVjbHNwZWNzLT5zdG9yYWdlX2NsYXNzID0gc2NfZXh0ZXJuOwogICAgICAvKiBUaGlzIHNob3VsZCBvbmx5IGJlIGRvbmUgb25jZSBvbiB0aGUgb3V0ZXJtb3N0IGRlY2wuICAqLwogICAgICBoYXZlX2V4dGVybl9zcGVjID0gZmFsc2U7CiAgICB9CgogIGRlY2wxID0gZ3Jva2RlY2xhcmF0b3IgKGRlY2xhcmF0b3IsIGRlY2xzcGVjcywgRlVOQ0RFRiwgMSwgJmF0dHJzKTsKICAvKiBJZiB0aGUgZGVjbGFyYXRvciBpcyBub3Qgc3VpdGFibGUgZm9yIGEgZnVuY3Rpb24gZGVmaW5pdGlvbiwKICAgICBjYXVzZSBhIHN5bnRheCBlcnJvci4gICovCiAgaWYgKGRlY2wxID09IE5VTExfVFJFRSB8fCBUUkVFX0NPREUgKGRlY2wxKSAhPSBGVU5DVElPTl9ERUNMKQogICAgcmV0dXJuIDA7CgogIC8qIElmICNwcmFnbWEgd2VhayB3YXMgdXNlZCwgbWFyayB0aGUgZGVjbCB3ZWFrIG5vdy4gICovCiAgaWYgKGdsb2JhbF9zY29wZV9wIChjdXJyZW50X2JpbmRpbmdfbGV2ZWwpKQogICAgbWF5YmVfYXBwbHlfcHJhZ21hX3dlYWsgKGRlY2wxKTsKCiAgLyogQVBQTEUgTE9DQUwgYmVnaW4gb3B0aW1pemF0aW9uIHByYWdtYXMgMzEyNDIzNS8zNDIwMjQyICovCiAgLyogQnVpbGQgYSBtYXBwaW5nIGJldHdlZW4gdGhpcyBkZWNsIGFuZCB0aGUgcGVyLWZ1bmN0aW9uIG9wdGlvbnMgaW4KICAgICBlZmZlY3QgYXQgdGhpcyBwb2ludC4gICovCiAgcmVjb3JkX2Z1bmNfY2xfcGZfb3B0c19tYXBwaW5nIChkZWNsMSk7CiAgLyogQVBQTEUgTE9DQUwgZW5kIG9wdGltaXphdGlvbiBwcmFnbWFzIDMxMjQyMzUvMzQyMDI0MiAqLwoKICBpZiAoREVDTF9NQUlOX1AgKGRlY2wxKSkKICAgIC8qIG1haW4gbXVzdCByZXR1cm4gaW50LiAgZ3Jva2ZuZGVjbCBzaG91bGQgaGF2ZSBjb3JyZWN0ZWQgaXQKICAgICAgIChhbmQgaXNzdWVkIGEgZGlhZ25vc3RpYykgaWYgdGhlIHVzZXIgZ290IGl0IHdyb25nLiAgKi8KICAgIGdjY19hc3NlcnQgKHNhbWVfdHlwZV9wIChUUkVFX1RZUEUgKFRSRUVfVFlQRSAoZGVjbDEpKSwKCQkJICAgICBpbnRlZ2VyX3R5cGVfbm9kZSkpOwoKICBzdGFydF9wcmVwYXJzZWRfZnVuY3Rpb24gKGRlY2wxLCBhdHRycywgLypmbGFncz0qL1NGX0RFRkFVTFQpOwoKICByZXR1cm4gMTsKfQoMCi8qIFN0b3JlIHRoZSBwYXJhbWV0ZXIgZGVjbGFyYXRpb25zIGludG8gdGhlIGN1cnJlbnQgZnVuY3Rpb24gZGVjbGFyYXRpb24uCiAgIFRoaXMgaXMgY2FsbGVkIGFmdGVyIHBhcnNpbmcgdGhlIHBhcmFtZXRlciBkZWNsYXJhdGlvbnMsIGJlZm9yZQogICBkaWdlc3RpbmcgdGhlIGJvZHkgb2YgdGhlIGZ1bmN0aW9uLgoKICAgQWxzbyBpbnN0YWxsIHRvIGJpbmRpbmcgY29udG91ciByZXR1cm4gdmFsdWUgaWRlbnRpZmllciwgaWYgYW55LiAgKi8KCnN0YXRpYyB2b2lkCnN0b3JlX3Bhcm1fZGVjbHMgKHRyZWUgY3VycmVudF9mdW5jdGlvbl9wYXJtcykKewogIHRyZWUgZm5kZWNsID0gY3VycmVudF9mdW5jdGlvbl9kZWNsOwogIHRyZWUgcGFybTsKCiAgLyogVGhpcyBpcyBhIGNoYWluIG9mIGFueSBvdGhlciBkZWNscyB0aGF0IGNhbWUgaW4gYW1vbmcgdGhlIHBhcm0KICAgICBkZWNsYXJhdGlvbnMuICBJZiBhIHBhcm0gaXMgZGVjbGFyZWQgd2l0aCAgZW51bSB7Zm9vLCBiYXJ9IHg7CiAgICAgdGhlbiBDT05TVF9ERUNMcyBmb3IgZm9vIGFuZCBiYXIgYXJlIHB1dCBoZXJlLiAgKi8KICB0cmVlIG5vbnBhcm1zID0gTlVMTF9UUkVFOwoKICBpZiAoY3VycmVudF9mdW5jdGlvbl9wYXJtcykKICAgIHsKICAgICAgLyogVGhpcyBjYXNlIGlzIHdoZW4gdGhlIGZ1bmN0aW9uIHdhcyBkZWZpbmVkIHdpdGggYW4gQU5TSSBwcm90b3R5cGUuCgkgVGhlIHBhcm1zIGFscmVhZHkgaGF2ZSBkZWNscywgc28gd2UgbmVlZCBub3QgZG8gYW55dGhpbmcgaGVyZQoJIGV4Y2VwdCByZWNvcmQgdGhlbSBhcyBpbiBlZmZlY3QKCSBhbmQgY29tcGxhaW4gaWYgYW55IHJlZHVuZGFudCBvbGQtc3R5bGUgcGFybSBkZWNscyB3ZXJlIHdyaXR0ZW4uICAqLwoKICAgICAgdHJlZSBzcGVjcGFybXMgPSBjdXJyZW50X2Z1bmN0aW9uX3Bhcm1zOwogICAgICB0cmVlIG5leHQ7CgogICAgICAvKiBNdXN0IGNsZWFyIHRoaXMgYmVjYXVzZSBpdCBtaWdodCBjb250YWluIFRZUEVfREVDTHMgZGVjbGFyZWQKCSAgICAgYXQgY2xhc3MgbGV2ZWwuICAqLwogICAgICBjdXJyZW50X2JpbmRpbmdfbGV2ZWwtPm5hbWVzID0gTlVMTDsKCiAgICAgIC8qIElmIHdlJ3JlIGRvaW5nIHNlbWFudGljIGFuYWx5c2lzLCB0aGVuIHdlJ2xsIGNhbGwgcHVzaGRlY2wKCSAgICAgZm9yIGVhY2ggb2YgdGhlc2UuICBXZSBtdXN0IGRvIHRoZW0gaW4gcmV2ZXJzZSBvcmRlciBzbyB0aGF0CgkgICAgIHRoZXkgZW5kIGluIHRoZSBjb3JyZWN0IGZvcndhcmQgb3JkZXIuICAqLwogICAgICBzcGVjcGFybXMgPSBucmV2ZXJzZSAoc3BlY3Bhcm1zKTsKCiAgICAgIGZvciAocGFybSA9IHNwZWNwYXJtczsgcGFybTsgcGFybSA9IG5leHQpCgl7CgkgIG5leHQgPSBUUkVFX0NIQUlOIChwYXJtKTsKCSAgaWYgKFRSRUVfQ09ERSAocGFybSkgPT0gUEFSTV9ERUNMKQoJICAgIHsKCSAgICAgIGlmIChERUNMX05BTUUgKHBhcm0pID09IE5VTExfVFJFRQoJCSAgfHwgVFJFRV9DT0RFIChwYXJtKSAhPSBWT0lEX1RZUEUpCgkJcHVzaGRlY2wgKHBhcm0pOwoJICAgICAgZWxzZQoJCWVycm9yICgicGFyYW1ldGVyICVxRCBkZWNsYXJlZCB2b2lkIiwgcGFybSk7CgkgICAgfQoJICBlbHNlCgkgICAgewoJICAgICAgLyogSWYgd2UgZmluZCBhbiBlbnVtIGNvbnN0YW50IG9yIGEgdHlwZSB0YWcsCgkJIHB1dCBpdCBhc2lkZSBmb3IgdGhlIG1vbWVudC4gICovCgkgICAgICBUUkVFX0NIQUlOIChwYXJtKSA9IE5VTExfVFJFRTsKCSAgICAgIG5vbnBhcm1zID0gY2hhaW5vbiAobm9ucGFybXMsIHBhcm0pOwoJICAgIH0KCX0KCiAgICAgIC8qIEdldCB0aGUgZGVjbHMgaW4gdGhlaXIgb3JpZ2luYWwgY2hhaW4gb3JkZXIgYW5kIHJlY29yZCBpbiB0aGUKCSBmdW5jdGlvbi4gIFRoaXMgaXMgYWxsIGFuZCBvbmx5IHRoZSBQQVJNX0RFQ0xzIHRoYXQgd2VyZQoJIHB1c2hlZCBpbnRvIHNjb3BlIGJ5IHRoZSBsb29wIGFib3ZlLiAgKi8KICAgICAgREVDTF9BUkdVTUVOVFMgKGZuZGVjbCkgPSBnZXRkZWNscyAoKTsKICAgIH0KICBlbHNlCiAgICBERUNMX0FSR1VNRU5UUyAoZm5kZWNsKSA9IE5VTExfVFJFRTsKCiAgLyogTm93IHN0b3JlIHRoZSBmaW5hbCBjaGFpbiBvZiBkZWNscyBmb3IgdGhlIGFyZ3VtZW50cwogICAgIGFzIHRoZSBkZWNsLWNoYWluIG9mIHRoZSBjdXJyZW50IGxleGljYWwgc2NvcGUuCiAgICAgUHV0IHRoZSBlbnVtZXJhdG9ycyBpbiBhcyB3ZWxsLCBhdCB0aGUgZnJvbnQgc28gdGhhdAogICAgIERFQ0xfQVJHVU1FTlRTIGlzIG5vdCBtb2RpZmllZC4gICovCiAgY3VycmVudF9iaW5kaW5nX2xldmVsLT5uYW1lcyA9IGNoYWlub24gKG5vbnBhcm1zLCBERUNMX0FSR1VNRU5UUyAoZm5kZWNsKSk7CgogIC8qIEZvciBhIGNsb25lZCBmdW5jdGlvbiwgd2UndmUgYWxyZWFkeSBnb3QgYWxsIHRoZSBjb2RlIHdlIG5lZWQ7CiAgICAgdGhlcmUncyBubyBuZWVkIHRvIGFkZCBhbnkgZXh0cmEgYml0cy4gICovCiAgaWYgKCFERUNMX0NMT05FRF9GVU5DVElPTl9QIChmbmRlY2wpKQogICAgewogICAgICAvKiBEbyB0aGUgc3RhcnRpbmcgb2YgdGhlIGV4Y2VwdGlvbiBzcGVjaWZpY2F0aW9ucywgaWYgd2UgaGF2ZSBhbnkuICAqLwogICAgICBpZiAoZmxhZ19leGNlcHRpb25zICYmICFwcm9jZXNzaW5nX3RlbXBsYXRlX2RlY2wKCSAgJiYgZmxhZ19lbmZvcmNlX2VoX3NwZWNzCgkgICYmIFRZUEVfUkFJU0VTX0VYQ0VQVElPTlMgKFRSRUVfVFlQRSAoY3VycmVudF9mdW5jdGlvbl9kZWNsKSkpCgljdXJyZW50X2VoX3NwZWNfYmxvY2sgPSBiZWdpbl9laF9zcGVjX2Jsb2NrICgpOwogICAgfQp9CgoMCi8qIFdlIGhhdmUgZmluaXNoZWQgZG9pbmcgc2VtYW50aWMgYW5hbHlzaXMgb24gREVDTCwgYnV0IGhhdmUgbm90IHlldAogICBnZW5lcmF0ZWQgUlRMIGZvciBpdHMgYm9keS4gIFNhdmUgYXdheSBvdXIgY3VycmVudCBzdGF0ZSwgc28gdGhhdAogICB3aGVuIHdlIHdhbnQgdG8gZ2VuZXJhdGUgUlRMIGxhdGVyIHdlIGtub3cgd2hhdCB0byBkby4gICovCgpzdGF0aWMgdm9pZApzYXZlX2Z1bmN0aW9uX2RhdGEgKHRyZWUgZGVjbCkKewogIHN0cnVjdCBsYW5ndWFnZV9mdW5jdGlvbiAqZjsKCiAgLyogU2F2ZSB0aGUgbGFuZ3VhZ2Utc3BlY2lmaWMgcGVyLWZ1bmN0aW9uIGRhdGEgc28gdGhhdCB3ZSBjYW4KICAgICBnZXQgaXQgYmFjayB3aGVuIHdlIHJlYWxseSBleHBhbmQgdGhpcyBmdW5jdGlvbi4gICovCiAgZ2NjX2Fzc2VydCAoIURFQ0xfUEVORElOR19JTkxJTkVfUCAoZGVjbCkpOwoKICAvKiBNYWtlIGEgY29weS4gICovCiAgZiA9IEdHQ19ORVcgKHN0cnVjdCBsYW5ndWFnZV9mdW5jdGlvbik7CiAgbWVtY3B5IChmLCBjcF9mdW5jdGlvbl9jaGFpbiwgc2l6ZW9mIChzdHJ1Y3QgbGFuZ3VhZ2VfZnVuY3Rpb24pKTsKICBERUNMX1NBVkVEX0ZVTkNUSU9OX0RBVEEgKGRlY2wpID0gZjsKCiAgLyogQ2xlYXIgb3V0IHRoZSBiaXRzIHdlIGRvbid0IG5lZWQuICAqLwogIGYtPmJhc2UueF9zdG10X3RyZWUueF9jdXJfc3RtdF9saXN0ID0gTlVMTF9UUkVFOwogIGYtPnhfbmFtZWRfbGFiZWxfdXNlcyA9IE5VTEw7CiAgZi0+YmluZGluZ3MgPSBOVUxMOwogIGYtPnhfbG9jYWxfbmFtZXMgPSBOVUxMOwp9CgoKLyogU2V0IHRoZSByZXR1cm4gdmFsdWUgb2YgdGhlIGNvbnN0cnVjdG9yIChpZiBwcmVzZW50KS4gICovCgpzdGF0aWMgdm9pZApmaW5pc2hfY29uc3RydWN0b3JfYm9keSAodm9pZCkKewogIHRyZWUgdmFsOwogIHRyZWUgZXhwcnN0bXQ7CgogIGlmICh0YXJnZXRtLmN4eC5jZHRvcl9yZXR1cm5zX3RoaXMgKCkpCiAgICB7CiAgICAgIC8qIEFueSByZXR1cm4gZnJvbSBhIGNvbnN0cnVjdG9yIHdpbGwgZW5kIHVwIGhlcmUuICAqLwogICAgICBhZGRfc3RtdCAoYnVpbGRfc3RtdCAoTEFCRUxfRVhQUiwgY2R0b3JfbGFiZWwpKTsKCiAgICAgIHZhbCA9IERFQ0xfQVJHVU1FTlRTIChjdXJyZW50X2Z1bmN0aW9uX2RlY2wpOwogICAgICB2YWwgPSBidWlsZDIgKE1PRElGWV9FWFBSLCBUUkVFX1RZUEUgKHZhbCksCgkJICAgIERFQ0xfUkVTVUxUIChjdXJyZW50X2Z1bmN0aW9uX2RlY2wpLCB2YWwpOwogICAgICAvKiBSZXR1cm4gdGhlIGFkZHJlc3Mgb2YgdGhlIG9iamVjdC4gICovCiAgICAgIGV4cHJzdG10ID0gYnVpbGRfc3RtdCAoUkVUVVJOX0VYUFIsIHZhbCk7CiAgICAgIGFkZF9zdG10IChleHByc3RtdCk7CiAgICB9Cn0KCi8qIERvIGFsbCB0aGUgcHJvY2Vzc2luZyBmb3IgdGhlIGJlZ2lubmluZyBvZiBhIGRlc3RydWN0b3I7IHNldCB1cCB0aGUKICAgdnRhYmxlIHBvaW50ZXJzIGFuZCBjbGVhbnVwcyBmb3IgYmFzZXMgYW5kIG1lbWJlcnMuICAqLwoKc3RhdGljIHZvaWQKYmVnaW5fZGVzdHJ1Y3Rvcl9ib2R5ICh2b2lkKQp7CiAgdHJlZSBpZl9zdG10OwogIHRyZWUgY29tcG91bmRfc3RtdDsKICAvKiBBUFBMRSBMT0NBTCBiZWdpbiBtYWlubGluZSAyMDA2LTAxLTIyIDQ0MTY0NTIgKi8KICAvKiBJZiB0aGUgQ1VSUkVOVF9DTEFTU19UWVBFIGlzIGluY29tcGxldGUsIHdlIHdpbGwgaGF2ZSBhbHJlYWR5CiAgICAgaXNzdWVkIGFuIGVycm9yIG1lc3NhZ2UuIMpXZSBzdGlsbCB3YW50IHRvIHRyeSB0byBwcm9jZXNzIHRoZQogICAgIGJvZHkgb2YgdGhlIGZ1bmN0aW9uLCBidXQgaW5pdGlhbGl6ZV92dGJsX3B0cnMgd2lsbCBjcmFzaCBpZgogICAgIFRZUEVfQklORk8gaXMgTlVMTC4gyiovCiAgaWYgKCFDT01QTEVURV9UWVBFX1AgKGN1cnJlbnRfY2xhc3NfdHlwZSkpCiAgICByZXR1cm47CiAgLyogQVBQTEUgTE9DQUwgZW5kIG1haW5saW5lIDIwMDYtMDEtMjIgNDQxNjQ1MiAqLwoKICAvKiBJZiB0aGUgZHRvciBpcyBlbXB0eSwgYW5kIHdlIGtub3cgdGhlcmUgaXMgbm90IGFueSBwb3NzaWJsZQogICAgIHdheSB3ZSBjb3VsZCB1c2UgYW55IHZ0YWJsZSBlbnRyaWVzLCBiZWZvcmUgdGhleSBhcmUgcG9zc2libHkKICAgICBzZXQgYnkgYSBiYXNlIGNsYXNzIGR0b3IsIHdlIGRvbid0IGhhdmUgdG8gc2V0dXAgdGhlIHZ0YWJsZXMsCiAgICAgYXMgd2Uga25vdyB0aGF0IGFueSBiYXNlIGNsYXNzIGR0b3Igd2lsbCBzZXQgdXAgYW55IHZ0YWJsZXMKICAgICBpdCBuZWVkcy4gIFdlIGF2b2lkIE1JLCBiZWNhdXNlIG9uZSBiYXNlIGNsYXNzIGR0b3IgY2FuIGRvIGEKICAgICB2aXJ0dWFsIGRpc3BhdGNoIHRvIGFuIG92ZXJyaWRkZW4gZnVuY3Rpb24gdGhhdCB3b3VsZCBuZWVkIHRvCiAgICAgaGF2ZSBhIG5vbi1yZWxhdGVkIHZ0YWJsZSBzZXQgdXAsIHdlIGNhbm5vdCBhdm9pZCBzZXR0aW5nIHVwCiAgICAgdnRhYmxlcyBpbiB0aGF0IGNhc2UuICBXZSBjb3VsZCBjaGFuZ2UgdGhpcyB0byBzZWUgaWYgdGhlcmUKICAgICBpcyBqdXN0IG9uZSB2dGFibGUuCgogICAgID8/PyBJbiB0aGUgZGVzdHJ1Y3RvciBmb3IgYSBjbGFzcywgdGhlIHZ0YWJsZXMgYXJlIHNldAogICAgIGFwcHJvcHJpYXRlbHkgZm9yIHRoYXQgY2xhc3MuICBUaGVyZSB3aWxsIGJlIG5vIG5vbi1yZWxhdGVkCiAgICAgdnRhYmxlcy4gIGphc29uIDIwMDEtMTItMTEuICAqLwogIGlmX3N0bXQgPSBiZWdpbl9pZl9zdG10ICgpOwoKICAvKiBJZiBpdCBpcyBub3Qgc2FmZSB0byBhdm9pZCBzZXR0aW5nIHVwIHRoZSB2dGFibGVzLCB0aGVuCiAgICAgc29tZW9uZSB3aWxsIGNoYW5nZSB0aGUgY29uZGl0aW9uIHRvIGJlIGJvb2xlYW5fdHJ1ZV9ub2RlLgogICAgIChBY3R1YWxseSwgZm9yIG5vdywgd2UgZG8gbm90IGhhdmUgY29kZSB0byBzZXQgdGhlIGNvbmRpdGlvbgogICAgIGFwcHJvcHJpYXRlbHksIHNvIHdlIGp1c3QgYXNzdW1lIHRoYXQgd2UgYWx3YXlzIG5lZWQgdG8KICAgICBpbml0aWFsaXplIHRoZSB2dGFibGVzLikgICovCiAgZmluaXNoX2lmX3N0bXRfY29uZCAoYm9vbGVhbl90cnVlX25vZGUsIGlmX3N0bXQpOwoKICBjb21wb3VuZF9zdG10ID0gYmVnaW5fY29tcG91bmRfc3RtdCAoMCk7CgogIC8qIE1ha2UgYWxsIHZpcnR1YWwgZnVuY3Rpb24gdGFibGUgcG9pbnRlcnMgaW4gbm9uLXZpcnR1YWwgYmFzZQogICAgIGNsYXNzZXMgcG9pbnQgdG8gQ1VSUkVOVF9DTEFTU19UWVBFJ3MgdmlydHVhbCBmdW5jdGlvbgogICAgIHRhYmxlcy4gICovCiAgaW5pdGlhbGl6ZV92dGJsX3B0cnMgKGN1cnJlbnRfY2xhc3NfcHRyKTsKCiAgZmluaXNoX2NvbXBvdW5kX3N0bXQgKGNvbXBvdW5kX3N0bXQpOwogIGZpbmlzaF90aGVuX2NsYXVzZSAoaWZfc3RtdCk7CiAgZmluaXNoX2lmX3N0bXQgKGlmX3N0bXQpOwoKICAvKiBBbmQgaW5zZXJ0IGNsZWFudXBzIGZvciBvdXIgYmFzZXMgYW5kIG1lbWJlcnMgc28gdGhhdCB0aGV5CiAgICAgd2lsbCBiZSBwcm9wZXJseSBkZXN0cm95ZWQgaWYgd2UgdGhyb3cuICAqLwogIHB1c2hfYmFzZV9jbGVhbnVwcyAoKTsKfQoKLyogQXQgdGhlIGVuZCBvZiBldmVyeSBkZXN0cnVjdG9yIHdlIGdlbmVyYXRlIGNvZGUgdG8gZGVsZXRlIHRoZSBvYmplY3QgaWYKICAgbmVjZXNzYXJ5LiAgRG8gdGhhdCBub3cuICAqLwoKc3RhdGljIHZvaWQKZmluaXNoX2Rlc3RydWN0b3JfYm9keSAodm9pZCkKewogIHRyZWUgZXhwcnN0bXQ7CgogIC8qIEFueSByZXR1cm4gZnJvbSBhIGRlc3RydWN0b3Igd2lsbCBlbmQgdXAgaGVyZTsgdGhhdCB3YXkgYWxsIGJhc2UKICAgICBhbmQgbWVtYmVyIGNsZWFudXBzIHdpbGwgYmUgcnVuIHdoZW4gdGhlIGZ1bmN0aW9uIHJldHVybnMuICAqLwogIGFkZF9zdG10IChidWlsZF9zdG10IChMQUJFTF9FWFBSLCBjZHRvcl9sYWJlbCkpOwoKICAvKiBJbiBhIHZpcnR1YWwgZGVzdHJ1Y3Rvciwgd2UgbXVzdCBjYWxsIGRlbGV0ZS4gICovCiAgaWYgKERFQ0xfVklSVFVBTF9QIChjdXJyZW50X2Z1bmN0aW9uX2RlY2wpKQogICAgewogICAgICB0cmVlIGlmX3N0bXQ7CiAgICAgIHRyZWUgdmlydHVhbF9zaXplID0gY3h4X3NpemVvZiAoY3VycmVudF9jbGFzc190eXBlKTsKCiAgICAgIC8qIFtjbGFzcy5kdG9yXQoKICAgICAgQXQgdGhlIHBvaW50IG9mIGRlZmluaXRpb24gb2YgYSB2aXJ0dWFsIGRlc3RydWN0b3IgKGluY2x1ZGluZwogICAgICBhbiBpbXBsaWNpdCBkZWZpbml0aW9uKSwgbm9uLXBsYWNlbWVudCBvcGVyYXRvciBkZWxldGUgc2hhbGwKICAgICAgYmUgbG9va2VkIHVwIGluIHRoZSBzY29wZSBvZiB0aGUgZGVzdHJ1Y3RvcidzIGNsYXNzIGFuZCBpZgogICAgICBmb3VuZCBzaGFsbCBiZSBhY2Nlc3NpYmxlIGFuZCB1bmFtYmlndW91cy4gICovCiAgICAgIGV4cHJzdG10ID0gYnVpbGRfb3BfZGVsZXRlX2NhbGwKCShERUxFVEVfRVhQUiwgY3VycmVudF9jbGFzc19wdHIsIHZpcnR1YWxfc2l6ZSwKCSAvKmdsb2JhbF9wPSovZmFsc2UsIE5VTExfVFJFRSk7CgogICAgICBpZl9zdG10ID0gYmVnaW5faWZfc3RtdCAoKTsKICAgICAgZmluaXNoX2lmX3N0bXRfY29uZCAoYnVpbGQyIChCSVRfQU5EX0VYUFIsIGludGVnZXJfdHlwZV9ub2RlLAoJCQkJICAgY3VycmVudF9pbl9jaGFyZ2VfcGFybSwKCQkJCSAgIGludGVnZXJfb25lX25vZGUpLAoJCQkgICBpZl9zdG10KTsKICAgICAgZmluaXNoX2V4cHJfc3RtdCAoZXhwcnN0bXQpOwogICAgICBmaW5pc2hfdGhlbl9jbGF1c2UgKGlmX3N0bXQpOwogICAgICBmaW5pc2hfaWZfc3RtdCAoaWZfc3RtdCk7CiAgICB9CgogIGlmICh0YXJnZXRtLmN4eC5jZHRvcl9yZXR1cm5zX3RoaXMgKCkpCiAgICB7CiAgICAgIHRyZWUgdmFsOwoKICAgICAgdmFsID0gREVDTF9BUkdVTUVOVFMgKGN1cnJlbnRfZnVuY3Rpb25fZGVjbCk7CiAgICAgIHZhbCA9IGJ1aWxkMiAoTU9ESUZZX0VYUFIsIFRSRUVfVFlQRSAodmFsKSwKCQkgICAgREVDTF9SRVNVTFQgKGN1cnJlbnRfZnVuY3Rpb25fZGVjbCksIHZhbCk7CiAgICAgIC8qIFJldHVybiB0aGUgYWRkcmVzcyBvZiB0aGUgb2JqZWN0LiAgKi8KICAgICAgZXhwcnN0bXQgPSBidWlsZF9zdG10IChSRVRVUk5fRVhQUiwgdmFsKTsKICAgICAgYWRkX3N0bXQgKGV4cHJzdG10KTsKICAgIH0KfQoKLyogRG8gdGhlIG5lY2Vzc2FyeSBwcm9jZXNzaW5nIGZvciB0aGUgYmVnaW5uaW5nIG9mIGEgZnVuY3Rpb24gYm9keSwgd2hpY2gKICAgaW4gdGhpcyBjYXNlIGluY2x1ZGVzIG1lbWJlci1pbml0aWFsaXplcnMsIGJ1dCBub3QgdGhlIGNhdGNoIGNsYXVzZXMgb2YKICAgYSBmdW5jdGlvbi10cnktYmxvY2suICBDdXJyZW50bHksIHRoaXMgbWVhbnMgb3BlbmluZyBhIGJpbmRpbmcgbGV2ZWwKICAgZm9yIHRoZSBtZW1iZXItaW5pdGlhbGl6ZXJzIChpbiBhIGN0b3IpIGFuZCBtZW1iZXIgY2xlYW51cHMgKGluIGEgZHRvcikuCiAgIEluIG90aGVyIGZ1bmN0aW9ucywgdGhpcyBpc24ndCBuZWNlc3NhcnksIGJ1dCBpdCBkb2Vzbid0IGh1cnQuICAqLwoKdHJlZQpiZWdpbl9mdW5jdGlvbl9ib2R5ICh2b2lkKQp7CiAgdHJlZSBzdG10OwoKICBpZiAocHJvY2Vzc2luZ190ZW1wbGF0ZV9kZWNsKQogICAgLyogRG8gbm90aGluZyBub3cuICAqLzsKICBlbHNlCiAgICAvKiBBbHdheXMga2VlcCB0aGUgQkxPQ0sgbm9kZSBhc3NvY2lhdGVkIHdpdGggdGhlIG91dGVybW9zdCBwYWlyIG9mCiAgICAgICBjdXJseSBicmFjZXMgb2YgYSBmdW5jdGlvbi4gIFRoZXNlIGFyZSBuZWVkZWQgZm9yIGNvcnJlY3QKICAgICAgIG9wZXJhdGlvbiBvZiBkd2FyZm91dC5jLiAgKi8KICAgIGtlZXBfbmV4dF9sZXZlbCAodHJ1ZSk7CgogIHN0bXQgPSBiZWdpbl9jb21wb3VuZF9zdG10IChCQ1NfRk5fQk9EWSk7CgogIGlmIChwcm9jZXNzaW5nX3RlbXBsYXRlX2RlY2wpCiAgICAvKiBEbyBub3RoaW5nIG5vdy4gICovOwogIGVsc2UgaWYgKERFQ0xfREVTVFJVQ1RPUl9QIChjdXJyZW50X2Z1bmN0aW9uX2RlY2wpKQogICAgYmVnaW5fZGVzdHJ1Y3Rvcl9ib2R5ICgpOwoKICByZXR1cm4gc3RtdDsKfQoKLyogRG8gdGhlIHByb2Nlc3NpbmcgZm9yIHRoZSBlbmQgb2YgYSBmdW5jdGlvbiBib2R5LiAgQ3VycmVudGx5LCB0aGlzIG1lYW5zCiAgIGNsb3Npbmcgb3V0IHRoZSBjbGVhbnVwcyBmb3IgZnVsbHktY29uc3RydWN0ZWQgYmFzZXMgYW5kIG1lbWJlcnMsIGFuZCBpbgogICB0aGUgY2FzZSBvZiB0aGUgZGVzdHJ1Y3RvciwgZGVsZXRpbmcgdGhlIG9iamVjdCBpZiBkZXNpcmVkLiAgQWdhaW4sIHRoaXMKICAgaXMgb25seSBtZWFuaW5nZnVsIGZvciBbY2RddG9ycywgc2luY2UgdGhleSBhcmUgdGhlIG9ubHkgZnVuY3Rpb25zIHdoZXJlCiAgIHRoZXJlIGlzIGEgc2lnbmlmaWNhbnQgZGlzdGluY3Rpb24gYmV0d2VlbiB0aGUgbWFpbiBib2R5IGFuZCBhbnkKICAgZnVuY3Rpb24gY2F0Y2ggY2xhdXNlcy4gIEhhbmRsaW5nLCBzYXksIG1haW4oKSByZXR1cm4gc2VtYW50aWNzIGhlcmUKICAgd291bGQgYmUgd3JvbmcsIGFzIGZsb3dpbmcgb2ZmIHRoZSBlbmQgb2YgYSBmdW5jdGlvbiBjYXRjaCBjbGF1c2UgZm9yCiAgIG1haW4oKSB3b3VsZCBhbHNvIG5lZWQgdG8gcmV0dXJuIDAuICAqLwoKdm9pZApmaW5pc2hfZnVuY3Rpb25fYm9keSAodHJlZSBjb21wc3RtdCkKewogIC8qIENsb3NlIHRoZSBibG9jay4gICovCiAgZmluaXNoX2NvbXBvdW5kX3N0bXQgKGNvbXBzdG10KTsKCiAgaWYgKHByb2Nlc3NpbmdfdGVtcGxhdGVfZGVjbCkKICAgIC8qIERvIG5vdGhpbmcgbm93LiAgKi87CiAgZWxzZSBpZiAoREVDTF9DT05TVFJVQ1RPUl9QIChjdXJyZW50X2Z1bmN0aW9uX2RlY2wpKQogICAgZmluaXNoX2NvbnN0cnVjdG9yX2JvZHkgKCk7CiAgZWxzZSBpZiAoREVDTF9ERVNUUlVDVE9SX1AgKGN1cnJlbnRfZnVuY3Rpb25fZGVjbCkpCiAgICBmaW5pc2hfZGVzdHJ1Y3Rvcl9ib2R5ICgpOwp9CgovKiBGaW5pc2ggdXAgYSBmdW5jdGlvbiBkZWNsYXJhdGlvbiBhbmQgY29tcGlsZSB0aGF0IGZ1bmN0aW9uCiAgIGFsbCB0aGUgd2F5IHRvIGFzc2VtYmxlciBsYW5ndWFnZSBvdXRwdXQuICBUaGUgZnJlZSB0aGUgc3RvcmFnZQogICBmb3IgdGhlIGZ1bmN0aW9uIGRlZmluaXRpb24uCgogICBGTEFHUyBpcyBhIGJpdHdpc2Ugb3Igb2YgdGhlIGZvbGxvd2luZyB2YWx1ZXM6CiAgICAgMiAtIElOQ0xBU1NfSU5MSU5FCiAgICAgICBXZSBqdXN0IGZpbmlzaGVkIHByb2Nlc3NpbmcgdGhlIGJvZHkgb2YgYW4gaW4tY2xhc3MgaW5saW5lCiAgICAgICBmdW5jdGlvbiBkZWZpbml0aW9uLiAgKFRoaXMgcHJvY2Vzc2luZyB3aWxsIGhhdmUgdGFrZW4gcGxhY2UKICAgICAgIGFmdGVyIHRoZSBjbGFzcyBkZWZpbml0aW9uIGlzIGNvbXBsZXRlLikgICovCgp0cmVlCmZpbmlzaF9mdW5jdGlvbiAoaW50IGZsYWdzKQp7CiAgdHJlZSBmbmRlY2wgPSBjdXJyZW50X2Z1bmN0aW9uX2RlY2w7CiAgdHJlZSBmbnR5cGUsIGN0eXBlID0gTlVMTF9UUkVFOwogIGludCBpbmNsYXNzX2lubGluZSA9IChmbGFncyAmIDIpICE9IDA7CiAgaW50IG5lc3RlZDsKCiAgLyogV2hlbiB3ZSBnZXQgc29tZSBwYXJzZSBlcnJvcnMsIHdlIGNhbiBlbmQgdXAgd2l0aG91dCBhCiAgICAgY3VycmVudF9mdW5jdGlvbl9kZWNsLCBzbyBjb3BlLiAgKi8KICBpZiAoZm5kZWNsID09IE5VTExfVFJFRSkKICAgIHJldHVybiBlcnJvcl9tYXJrX25vZGU7CgogIGlmIChERUNMX05PTlNUQVRJQ19NRU1CRVJfRlVOQ1RJT05fUCAoZm5kZWNsKQogICAgICAmJiBERUNMX1ZJUlRVQUxfUCAoZm5kZWNsKQogICAgICAmJiAhcHJvY2Vzc2luZ190ZW1wbGF0ZV9kZWNsKQogICAgewogICAgICB0cmVlIGZuY2xhc3MgPSBERUNMX0NPTlRFWFQgKGZuZGVjbCk7CiAgICAgIGlmIChmbmRlY2wgPT0gQ0xBU1NUWVBFX0tFWV9NRVRIT0QgKGZuY2xhc3MpKQoJa2V5ZWRfY2xhc3NlcyA9IHRyZWVfY29ucyAoTlVMTF9UUkVFLCBmbmNsYXNzLCBrZXllZF9jbGFzc2VzKTsKICAgIH0KCiAgbmVzdGVkID0gZnVuY3Rpb25fZGVwdGggPiAxOwogIGZudHlwZSA9IFRSRUVfVFlQRSAoZm5kZWNsKTsKCiAgLyogIFRSRUVfUkVBRE9OTFkgKGZuZGVjbCkgPSAxOwogICAgICBUaGlzIGNhdXNlZCAmZm9vIHRvIGJlIG9mIHR5cGUgcHRyLXRvLWNvbnN0LWZ1bmN0aW9uCiAgICAgIHdoaWNoIHRoZW4gZ290IGEgd2FybmluZyB3aGVuIHN0b3JlZCBpbiBhIHB0ci10by1mdW5jdGlvbiB2YXJpYWJsZS4gICovCgogIGdjY19hc3NlcnQgKGJ1aWxkaW5nX3N0bXRfdHJlZSAoKSk7CgogIC8qIEZvciBhIGNsb25lZCBmdW5jdGlvbiwgd2UndmUgYWxyZWFkeSBnb3QgYWxsIHRoZSBjb2RlIHdlIG5lZWQ7CiAgICAgdGhlcmUncyBubyBuZWVkIHRvIGFkZCBhbnkgZXh0cmEgYml0cy4gICovCiAgaWYgKCFERUNMX0NMT05FRF9GVU5DVElPTl9QIChmbmRlY2wpKQogICAgewogICAgICBpZiAoREVDTF9NQUlOX1AgKGN1cnJlbnRfZnVuY3Rpb25fZGVjbCkpCgl7CgkgIHRyZWUgc3RtdDsKCgkgIC8qIE1ha2UgaXQgc28gdGhhdCBgbWFpbicgYWx3YXlzIHJldHVybnMgMCBieSBkZWZhdWx0IChvcgoJICAgICAxIGZvciBWTVMpLiAgKi8KI2lmIFZNU19UQVJHRVQKCSAgc3RtdCA9IGZpbmlzaF9yZXR1cm5fc3RtdCAoaW50ZWdlcl9vbmVfbm9kZSk7CiNlbHNlCgkgIHN0bXQgPSBmaW5pc2hfcmV0dXJuX3N0bXQgKGludGVnZXJfemVyb19ub2RlKTsKI2VuZGlmCgkgIC8qIEhhY2suICBXZSBkb24ndCB3YW50IHRoZSBtaWRkbGUtZW5kIHRvIHdhcm4gdGhhdCB0aGlzCgkgICAgIHJldHVybiBpcyB1bnJlYWNoYWJsZSwgc28gcHV0IHRoZSBzdGF0ZW1lbnQgb24gdGhlCgkgICAgIHNwZWNpYWwgbGluZSAwLiAgKi8KCSAgYW5ub3RhdGVfd2l0aF9maWxlX2xpbmUgKHN0bXQsIGlucHV0X2ZpbGVuYW1lLCAwKTsKCX0KCiAgICAgIC8qIEZpbmlzaCBkZWFsaW5nIHdpdGggZXhjZXB0aW9uIHNwZWNpZmllcnMuICAqLwogICAgICBpZiAoZmxhZ19leGNlcHRpb25zICYmICFwcm9jZXNzaW5nX3RlbXBsYXRlX2RlY2wKCSAgJiYgZmxhZ19lbmZvcmNlX2VoX3NwZWNzCgkgICYmIFRZUEVfUkFJU0VTX0VYQ0VQVElPTlMgKFRSRUVfVFlQRSAoY3VycmVudF9mdW5jdGlvbl9kZWNsKSkpCglmaW5pc2hfZWhfc3BlY19ibG9jayAoVFlQRV9SQUlTRVNfRVhDRVBUSU9OUwoJCQkgICAgICAoVFJFRV9UWVBFIChjdXJyZW50X2Z1bmN0aW9uX2RlY2wpKSwKCQkJICAgICAgY3VycmVudF9laF9zcGVjX2Jsb2NrKTsKICAgIH0KCiAgLyogSWYgd2UncmUgc2F2aW5nIHVwIHRyZWUgc3RydWN0dXJlLCB0aWUgb2ZmIHRoZSBmdW5jdGlvbiBub3cuICAqLwogIERFQ0xfU0FWRURfVFJFRSAoZm5kZWNsKSA9IHBvcF9zdG10X2xpc3QgKERFQ0xfU0FWRURfVFJFRSAoZm5kZWNsKSk7CgogIGZpbmlzaF9mbmFtZV9kZWNscyAoKTsKCiAgLyogSWYgdGhpcyBmdW5jdGlvbiBjYW4ndCB0aHJvdyBhbnkgZXhjZXB0aW9ucywgcmVtZW1iZXIgdGhhdC4gICovCiAgaWYgKCFwcm9jZXNzaW5nX3RlbXBsYXRlX2RlY2wKICAgICAgJiYgIWNwX2Z1bmN0aW9uX2NoYWluLT5jYW5fdGhyb3cKICAgICAgJiYgIWZsYWdfbm9uX2NhbGxfZXhjZXB0aW9ucykKICAgIFRSRUVfTk9USFJPVyAoZm5kZWNsKSA9IDE7CgogIC8qIFRoaXMgbXVzdCBjb21lIGFmdGVyIGV4cGFuZF9mdW5jdGlvbl9lbmQgYmVjYXVzZSBjbGVhbnVwcyBtaWdodAogICAgIGhhdmUgZGVjbGFyYXRpb25zIChmcm9tIGlubGluZSBmdW5jdGlvbnMpIHRoYXQgbmVlZCB0byBnbyBpbnRvCiAgICAgdGhpcyBmdW5jdGlvbidzIGJsb2Nrcy4gICovCgogIC8qIElmIHRoZSBjdXJyZW50IGJpbmRpbmcgbGV2ZWwgaXNuJ3QgdGhlIG91dGVybW9zdCBiaW5kaW5nIGxldmVsCiAgICAgZm9yIHRoaXMgZnVuY3Rpb24sIGVpdGhlciB0aGVyZSBpcyBhIGJ1Zywgb3Igd2UgaGF2ZSBleHBlcmllbmNlZAogICAgIHN5bnRheCBlcnJvcnMgYW5kIHRoZSBzdGF0ZW1lbnQgdHJlZSBpcyBtYWxmb3JtZWQuICAqLwogIGlmIChjdXJyZW50X2JpbmRpbmdfbGV2ZWwtPmtpbmQgIT0gc2tfZnVuY3Rpb25fcGFybXMpCiAgICB7CiAgICAgIC8qIE1ha2Ugc3VyZSB3ZSBoYXZlIGFscmVhZHkgZXhwZXJpZW5jZWQgZXJyb3JzLiAgKi8KICAgICAgZ2NjX2Fzc2VydCAoZXJyb3Jjb3VudCk7CgogICAgICAvKiBUaHJvdyBhd2F5IHRoZSBicm9rZW4gc3RhdGVtZW50IHRyZWUgYW5kIGV4dHJhIGJpbmRpbmcKICAgICAgICAgbGV2ZWxzLiAgKi8KICAgICAgREVDTF9TQVZFRF9UUkVFIChmbmRlY2wpID0gYWxsb2Nfc3RtdF9saXN0ICgpOwoKICAgICAgd2hpbGUgKGN1cnJlbnRfYmluZGluZ19sZXZlbC0+a2luZCAhPSBza19mdW5jdGlvbl9wYXJtcykKCXsKCSAgaWYgKGN1cnJlbnRfYmluZGluZ19sZXZlbC0+a2luZCA9PSBza19jbGFzcykKCSAgICBwb3BfbmVzdGVkX2NsYXNzICgpOwoJICBlbHNlCgkgICAgcG9wbGV2ZWwgKDAsIDAsIDApOwoJfQogICAgfQogIHBvcGxldmVsICgxLCAwLCAxKTsKCiAgLyogU3RhdGVtZW50cyBzaG91bGQgYWx3YXlzIGJlIGZ1bGwtZXhwcmVzc2lvbnMgYXQgdGhlIG91dGVybW9zdCBzZXQKICAgICBvZiBjdXJseSBicmFjZXMgZm9yIGEgZnVuY3Rpb24uICAqLwogIGdjY19hc3NlcnQgKHN0bXRzX2FyZV9mdWxsX2V4cHJzX3AgKCkpOwoKICAvKiBTZXQgdXAgdGhlIG5hbWVkIHJldHVybiB2YWx1ZSBvcHRpbWl6YXRpb24sIGlmIHdlIGNhbi4gIENhbmRpZGF0ZQogICAgIHZhcmlhYmxlcyBhcmUgc2VsZWN0ZWQgaW4gY2hlY2tfcmV0dXJuX3ZhbHVlLiAgKi8KICBpZiAoY3VycmVudF9mdW5jdGlvbl9yZXR1cm5fdmFsdWUpCiAgICB7CiAgICAgIHRyZWUgciA9IGN1cnJlbnRfZnVuY3Rpb25fcmV0dXJuX3ZhbHVlOwogICAgICB0cmVlIG91dGVyOwoKICAgICAgaWYgKHIgIT0gZXJyb3JfbWFya19ub2RlCgkgIC8qIFRoaXMgaXMgb25seSB3b3J0aCBkb2luZyBmb3IgZm5zIHRoYXQgcmV0dXJuIGluIG1lbW9yeS0tYW5kCgkgICAgIHNpbXBsZXIsIHNpbmNlIHdlIGRvbid0IGhhdmUgdG8gd29ycnkgYWJvdXQgcHJvbW90ZWQgbW9kZXMuICAqLwoJICAmJiBhZ2dyZWdhdGVfdmFsdWVfcCAoVFJFRV9UWVBFIChUUkVFX1RZUEUgKGZuZGVjbCkpLCBmbmRlY2wpCgkgIC8qIE9ubHkgYWxsb3cgdGhpcyBmb3IgdmFyaWFibGVzIGRlY2xhcmVkIGluIHRoZSBvdXRlciBzY29wZSBvZgoJICAgICB0aGUgZnVuY3Rpb24gc28gd2Uga25vdyB0aGF0IHRoZWlyIGxpZmV0aW1lIGFsd2F5cyBlbmRzIHdpdGggYQoJICAgICByZXR1cm47IHNlZSBnKysuZGcvb3B0L25ydjYuQy4gIFdlIGNvdWxkIGJlIG1vcmUgZmxleGlibGUgaWYKCSAgICAgd2Ugd2VyZSB0byBkbyB0aGlzIG9wdGltaXphdGlvbiBpbiB0cmVlLXNzYS4gICovCgkgICYmIChvdXRlciA9IEJMT0NLX1NVQkJMT0NLUyAoREVDTF9JTklUSUFMIChmbmRlY2wpKSkKCSAgLyogU2tpcCB0aGUgYXJ0aWZpY2lhbCBmdW5jdGlvbiBib2R5IGJsb2NrLiAgKi8KCSAgJiYgKG91dGVyID0gQkxPQ0tfU1VCQkxPQ0tTIChvdXRlcikpCgkgICYmIGNoYWluX21lbWJlciAociwgQkxPQ0tfVkFSUyAob3V0ZXIpKSkKCWZpbmFsaXplX25ydiAoJkRFQ0xfU0FWRURfVFJFRSAoZm5kZWNsKSwgciwgREVDTF9SRVNVTFQgKGZuZGVjbCkpOwoKICAgICAgY3VycmVudF9mdW5jdGlvbl9yZXR1cm5fdmFsdWUgPSBOVUxMX1RSRUU7CiAgICB9CgogIC8qIFJlbWVtYmVyIHRoYXQgd2Ugd2VyZSBpbiBjbGFzcyBzY29wZS4gICovCiAgaWYgKGN1cnJlbnRfY2xhc3NfbmFtZSkKICAgIGN0eXBlID0gY3VycmVudF9jbGFzc190eXBlOwoKICAvKiBNdXN0IG1hcmsgdGhlIFJFU1VMVF9ERUNMIGFzIGJlaW5nIGluIHRoaXMgZnVuY3Rpb24uICAqLwogIERFQ0xfQ09OVEVYVCAoREVDTF9SRVNVTFQgKGZuZGVjbCkpID0gZm5kZWNsOwoKICAvKiBTZXQgdGhlIEJMT0NLX1NVUEVSQ09OVEVYVCBvZiB0aGUgb3V0ZXJtb3N0IGZ1bmN0aW9uIHNjb3BlIHRvIHBvaW50CiAgICAgdG8gdGhlIEZVTkNUSU9OX0RFQ0wgbm9kZSBpdHNlbGYuICAqLwogIEJMT0NLX1NVUEVSQ09OVEVYVCAoREVDTF9JTklUSUFMIChmbmRlY2wpKSA9IGZuZGVjbDsKCiAgLyogU2F2ZSBhd2F5IGN1cnJlbnQgc3RhdGUsIGlmIGFwcHJvcHJpYXRlLiAgKi8KICBpZiAoIXByb2Nlc3NpbmdfdGVtcGxhdGVfZGVjbCkKICAgIHNhdmVfZnVuY3Rpb25fZGF0YSAoZm5kZWNsKTsKCiAgLyogQ29tcGxhaW4gaWYgdGhlcmUncyBqdXN0IG5vIHJldHVybiBzdGF0ZW1lbnQuICAqLwogIGlmICh3YXJuX3JldHVybl90eXBlCiAgICAgICYmIFRSRUVfQ09ERSAoVFJFRV9UWVBFIChmbnR5cGUpKSAhPSBWT0lEX1RZUEUKICAgICAgJiYgIWRlcGVuZGVudF90eXBlX3AgKFRSRUVfVFlQRSAoZm50eXBlKSkKICAgICAgJiYgIWN1cnJlbnRfZnVuY3Rpb25fcmV0dXJuc192YWx1ZSAmJiAhY3VycmVudF9mdW5jdGlvbl9yZXR1cm5zX251bGwKICAgICAgLyogRG9uJ3QgY29tcGxhaW4gaWYgd2UgYWJvcnQgb3IgdGhyb3cuICAqLwogICAgICAmJiAhY3VycmVudF9mdW5jdGlvbl9yZXR1cm5zX2Fibm9ybWFsbHkKICAgICAgJiYgIURFQ0xfTkFNRSAoREVDTF9SRVNVTFQgKGZuZGVjbCkpCiAgICAgIC8qIE5vcm1hbGx5LCB3aXRoIC1XcmV0dXJuLXR5cGUsIGZsb3cgd2lsbCBjb21wbGFpbi4gIFVubGVzcyB3ZSdyZSBhbgoJIGlubGluZSBmdW5jdGlvbiwgYXMgd2UgbWlnaHQgbmV2ZXIgYmUgY29tcGlsZWQgc2VwYXJhdGVseS4gICovCiAgICAgICYmIChERUNMX0lOTElORSAoZm5kZWNsKSB8fCBwcm9jZXNzaW5nX3RlbXBsYXRlX2RlY2wpCiAgICAgIC8qIFN0cnVjdG9yIHJldHVybiB2YWx1ZXMgKGlmIGFueSkgYXJlIHNldCBieSB0aGUgY29tcGlsZXIuICAqLwogICAgICAmJiAhREVDTF9DT05TVFJVQ1RPUl9QIChmbmRlY2wpCiAgICAgICYmICFERUNMX0RFU1RSVUNUT1JfUCAoZm5kZWNsKSkKICAgIHdhcm5pbmcgKCJubyByZXR1cm4gc3RhdGVtZW50IGluIGZ1bmN0aW9uIHJldHVybmluZyBub24tdm9pZCIpOwoKICAvKiBTdG9yZSB0aGUgZW5kIG9mIHRoZSBmdW5jdGlvbiwgc28gdGhhdCB3ZSBnZXQgZ29vZCBsaW5lIG51bWJlcgogICAgIGluZm8gZm9yIHRoZSBlcGlsb2d1ZS4gICovCiAgY2Z1bi0+ZnVuY3Rpb25fZW5kX2xvY3VzID0gaW5wdXRfbG9jYXRpb247CgogIC8qIEdlbmVyaWNpemUgYmVmb3JlIGlubGluaW5nLiAgKi8KICBpZiAoIXByb2Nlc3NpbmdfdGVtcGxhdGVfZGVjbCkKICAgIHsKICAgICAgc3RydWN0IGxhbmd1YWdlX2Z1bmN0aW9uICpmID0gREVDTF9TQVZFRF9GVU5DVElPTl9EQVRBIChmbmRlY2wpOwogICAgICBjcF9nZW5lcmljaXplIChmbmRlY2wpOwogICAgICAvKiBDbGVhciBvdXQgdGhlIGJpdHMgd2UgZG9uJ3QgbmVlZC4gICovCiAgICAgIGYtPnhfY3VycmVudF9jbGFzc19wdHIgPSBOVUxMOwogICAgICBmLT54X2N1cnJlbnRfY2xhc3NfcmVmID0gTlVMTDsKICAgICAgZi0+eF9laF9zcGVjX2Jsb2NrID0gTlVMTDsKICAgICAgZi0+eF9pbl9jaGFyZ2VfcGFybSA9IE5VTEw7CiAgICAgIGYtPnhfdnR0X3Bhcm0gPSBOVUxMOwogICAgICBmLT54X3JldHVybl92YWx1ZSA9IE5VTEw7CiAgICAgIGYtPmJpbmRpbmdzID0gTlVMTDsKCiAgICAgIC8qIEhhbmRsZSBhdHRyaWJ1dGUoKHdhcm5fdW51c2VkX3Jlc3VsdCkpLiAgUmVsaWVzIG9uIGdpbXBsZSBpbnB1dC4gICovCiAgICAgIGNfd2Fybl91bnVzZWRfcmVzdWx0ICgmREVDTF9TQVZFRF9UUkVFIChmbmRlY2wpKTsKICAgIH0KICAvKiBDbGVhciBvdXQgdGhlIGJpdHMgd2UgZG9uJ3QgbmVlZC4gICovCiAgbG9jYWxfbmFtZXMgPSBOVUxMOwogIG5hbWVkX2xhYmVsX3VzZXMgPSBOVUxMOwoKICAvKiBXZSdyZSBsZWF2aW5nIHRoZSBjb250ZXh0IG9mIHRoaXMgZnVuY3Rpb24sIHNvIHphcCBjZnVuLiAgSXQncyBzdGlsbCBpbgogICAgIERFQ0xfU1RSVUNUX0ZVTkNUSU9OLCBhbmQgd2UnbGwgcmVzdG9yZSBpdCBpbiB0cmVlX3Jlc3Rfb2ZfY29tcGlsYXRpb24uICAqLwogIGNmdW4gPSBOVUxMOwogIGN1cnJlbnRfZnVuY3Rpb25fZGVjbCA9IE5VTEw7CgogIC8qIElmIHRoaXMgaXMgYW4gaW4tY2xhc3MgaW5saW5lIGRlZmluaXRpb24sIHdlIG1heSBoYXZlIHRvIHBvcCB0aGUKICAgICBiaW5kaW5ncyBmb3IgdGhlIHRlbXBsYXRlIHBhcmFtZXRlcnMgdGhhdCB3ZSBhZGRlZCBpbgogICAgIG1heWJlX2JlZ2luX21lbWJlcl90ZW1wbGF0ZV9wcm9jZXNzaW5nIHdoZW4gc3RhcnRfZnVuY3Rpb24gd2FzCiAgICAgY2FsbGVkLiAgKi8KICBpZiAoaW5jbGFzc19pbmxpbmUpCiAgICBtYXliZV9lbmRfbWVtYmVyX3RlbXBsYXRlX3Byb2Nlc3NpbmcgKCk7CgogIC8qIExlYXZlIHRoZSBzY29wZSBvZiB0aGUgY2xhc3MuICAqLwogIGlmIChjdHlwZSkKICAgIHBvcF9uZXN0ZWRfY2xhc3MgKCk7CgogIC0tZnVuY3Rpb25fZGVwdGg7CgogIC8qIENsZWFuIHVwLiAgKi8KICBpZiAoISBuZXN0ZWQpCiAgICAvKiBMZXQgdGhlIGVycm9yIHJlcG9ydGluZyByb3V0aW5lcyBrbm93IHRoYXQgd2UncmUgb3V0c2lkZSBhCiAgICAgICBmdW5jdGlvbi4gIEZvciBhIG5lc3RlZCBmdW5jdGlvbiwgdGhpcyB2YWx1ZSBpcyB1c2VkIGluCiAgICAgICBjeHhfcG9wX2Z1bmN0aW9uX2NvbnRleHQgYW5kIHRoZW4gcmVzZXQgdmlhIHBvcF9mdW5jdGlvbl9jb250ZXh0LiAgKi8KICAgIGN1cnJlbnRfZnVuY3Rpb25fZGVjbCA9IE5VTExfVFJFRTsKCiAgcmV0dXJuIGZuZGVjbDsKfQoMCi8qIENyZWF0ZSB0aGUgRlVOQ1RJT05fREVDTCBmb3IgYSBmdW5jdGlvbiBkZWZpbml0aW9uLgogICBERUNMU1BFQ1MgYW5kIERFQ0xBUkFUT1IgYXJlIHRoZSBwYXJ0cyBvZiB0aGUgZGVjbGFyYXRpb247CiAgIHRoZXkgZGVzY3JpYmUgdGhlIHJldHVybiB0eXBlIGFuZCB0aGUgbmFtZSBvZiB0aGUgZnVuY3Rpb24sCiAgIGJ1dCB0d2lzdGVkIHRvZ2V0aGVyIGluIGEgZmFzaGlvbiB0aGF0IHBhcmFsbGVscyB0aGUgc3ludGF4IG9mIEMuCgogICBUaGlzIGZ1bmN0aW9uIGNyZWF0ZXMgYSBiaW5kaW5nIGNvbnRleHQgZm9yIHRoZSBmdW5jdGlvbiBib2R5CiAgIGFzIHdlbGwgYXMgc2V0dGluZyB1cCB0aGUgRlVOQ1RJT05fREVDTCBpbiBjdXJyZW50X2Z1bmN0aW9uX2RlY2wuCgogICBSZXR1cm5zIGEgRlVOQ1RJT05fREVDTCBvbiBzdWNjZXNzLgoKICAgSWYgdGhlIERFQ0xBUkFUT1IgaXMgbm90IHN1aXRhYmxlIGZvciBhIGZ1bmN0aW9uIChpdCBkZWZpbmVzIGEgZGF0dW0KICAgaW5zdGVhZCksIHdlIHJldHVybiAwLCB3aGljaCB0ZWxscyB5eXBhcnNlIHRvIHJlcG9ydCBhIHBhcnNlIGVycm9yLgoKICAgTWF5IHJldHVybiB2b2lkX3R5cGVfbm9kZSBpbmRpY2F0aW5nIHRoYXQgdGhpcyBtZXRob2QgaXMgYWN0dWFsbHkKICAgYSBmcmllbmQuICBTZWUgZ3Jva2ZpZWxkIGZvciBtb3JlIGRldGFpbHMuCgogICBDYW1lIGhlcmUgd2l0aCBhIGAucHVzaGxldmVsJyAuCgogICBETyBOT1QgTUFLRSBBTlkgQ0hBTkdFUyBUTyBUSElTIENPREUgV0lUSE9VVCBNQUtJTkcgQ09SUkVTUE9ORElORwogICBDSEFOR0VTIFRPIENPREUgSU4gYGdyb2tmaWVsZCcuICAqLwoKdHJlZQpzdGFydF9tZXRob2QgKGNwX2RlY2xfc3BlY2lmaWVyX3NlcSAqZGVjbHNwZWNzLAogICAgICAgICAgICAgIGNvbnN0IGNwX2RlY2xhcmF0b3IgKmRlY2xhcmF0b3IsIHRyZWUgYXR0cmxpc3QpCnsKICB0cmVlIGZuZGVjbCA9IGdyb2tkZWNsYXJhdG9yIChkZWNsYXJhdG9yLCBkZWNsc3BlY3MsIE1FTUZVTkNERUYsIDAsCgkJCQkmYXR0cmxpc3QpOwoKICBpZiAoZm5kZWNsID09IGVycm9yX21hcmtfbm9kZSkKICAgIHJldHVybiBlcnJvcl9tYXJrX25vZGU7CgogIGlmIChmbmRlY2wgPT0gTlVMTCB8fCBUUkVFX0NPREUgKGZuZGVjbCkgIT0gRlVOQ1RJT05fREVDTCkKICAgIHsKICAgICAgZXJyb3IgKCJpbnZhbGlkIG1lbWJlciBmdW5jdGlvbiBkZWNsYXJhdGlvbiIpOwogICAgICByZXR1cm4gZXJyb3JfbWFya19ub2RlOwogICAgfQoKICBpZiAoYXR0cmxpc3QpCiAgICBjcGx1c19kZWNsX2F0dHJpYnV0ZXMgKCZmbmRlY2wsIGF0dHJsaXN0LCAwKTsKCiAgLyogUGFzcyBmcmllbmRzIG90aGVyIHRoYW4gaW5saW5lIGZyaWVuZCBmdW5jdGlvbnMgYmFjay4gICovCiAgaWYgKGZuZGVjbCA9PSB2b2lkX3R5cGVfbm9kZSkKICAgIHJldHVybiBmbmRlY2w7CgogIGlmIChERUNMX0lOX0FHR1JfUCAoZm5kZWNsKSkKICAgIHsKICAgICAgaWYgKERFQ0xfQ09OVEVYVCAoZm5kZWNsKQoJICAmJiBUUkVFX0NPREUoIERFQ0xfQ09OVEVYVCAoZm5kZWNsKSkgIT0gTkFNRVNQQUNFX0RFQ0wpCgllcnJvciAoIiVxRCBpcyBhbHJlYWR5IGRlZmluZWQgaW4gY2xhc3MgJXFUIiwgZm5kZWNsLAoJICAgICAgIERFQ0xfQ09OVEVYVCAoZm5kZWNsKSk7CiAgICAgIHJldHVybiB2b2lkX3R5cGVfbm9kZTsKICAgIH0KCiAgY2hlY2tfdGVtcGxhdGVfc2hhZG93IChmbmRlY2wpOwoKICBERUNMX0RFQ0xBUkVEX0lOTElORV9QIChmbmRlY2wpID0gMTsKICBpZiAoZmxhZ19kZWZhdWx0X2lubGluZSkKICAgIERFQ0xfSU5MSU5FIChmbmRlY2wpID0gMTsKCiAgLyogV2UgcHJvY2VzcyBtZXRob2Qgc3BlY2lhbGl6YXRpb25zIGluIGZpbmlzaF9zdHJ1Y3RfMS4gICovCiAgaWYgKHByb2Nlc3NpbmdfdGVtcGxhdGVfZGVjbCAmJiAhREVDTF9URU1QTEFURV9TUEVDSUFMSVpBVElPTiAoZm5kZWNsKSkKICAgIHsKICAgICAgZm5kZWNsID0gcHVzaF90ZW1wbGF0ZV9kZWNsIChmbmRlY2wpOwogICAgICBpZiAoZm5kZWNsID09IGVycm9yX21hcmtfbm9kZSkKCXJldHVybiBmbmRlY2w7CiAgICB9CgogIGlmICghIERFQ0xfRlJJRU5EX1AgKGZuZGVjbCkpCiAgICB7CiAgICAgIGlmIChUUkVFX0NIQUlOIChmbmRlY2wpKQoJewoJICBmbmRlY2wgPSBjb3B5X25vZGUgKGZuZGVjbCk7CgkgIFRSRUVfQ0hBSU4gKGZuZGVjbCkgPSBOVUxMX1RSRUU7Cgl9CiAgICAgIGdyb2tfc3BlY2lhbF9tZW1iZXJfcHJvcGVydGllcyAoZm5kZWNsKTsKICAgIH0KCiAgY3BfZmluaXNoX2RlY2wgKGZuZGVjbCwgTlVMTF9UUkVFLCBOVUxMX1RSRUUsIDApOwoKICAvKiBNYWtlIGEgcGxhY2UgZm9yIHRoZSBwYXJtcy4gICovCiAgYmVnaW5fc2NvcGUgKHNrX2Z1bmN0aW9uX3Bhcm1zLCBmbmRlY2wpOwoKICBERUNMX0lOX0FHR1JfUCAoZm5kZWNsKSA9IDE7CiAgcmV0dXJuIGZuZGVjbDsKfQoKLyogR28gdGhyb3VnaCB0aGUgbW90aW9ucyBvZiBmaW5pc2hpbmcgYSBmdW5jdGlvbiBkZWZpbml0aW9uLgogICBXZSBkb24ndCBjb21waWxlIHRoaXMgbWV0aG9kIHVudGlsIGFmdGVyIHRoZSB3aG9sZSBjbGFzcyBoYXMKICAgYmVlbiBwcm9jZXNzZWQuCgogICBGSU5JU0hfTUVUSE9EIG11c3QgcmV0dXJuIHNvbWV0aGluZyB0aGF0IGxvb2tzIGFzIHRob3VnaCBpdAogICBjYW1lIGZyb20gR1JPS0ZJRUxEIChzaW5jZSB3ZSBhcmUgZGVmaW5pbmcgYSBtZXRob2QsIGFmdGVyIGFsbCkuCgogICBUaGlzIGlzIGNhbGxlZCBhZnRlciBwYXJzaW5nIHRoZSBib2R5IG9mIHRoZSBmdW5jdGlvbiBkZWZpbml0aW9uLgogICBTVE1UUyBpcyB0aGUgY2hhaW4gb2Ygc3RhdGVtZW50cyB0aGF0IG1ha2VzIHVwIHRoZSBmdW5jdGlvbiBib2R5LgoKICAgREVDTCBpcyB0aGUgLi4uX0RFQ0wgdGhhdCBgc3RhcnRfbWV0aG9kJyBwcm92aWRlZC4gICovCgp0cmVlCmZpbmlzaF9tZXRob2QgKHRyZWUgZGVjbCkKewogIHRyZWUgZm5kZWNsID0gZGVjbDsKICB0cmVlIG9sZF9pbml0aWFsOwoKICB0cmVlIGxpbms7CgogIGlmIChkZWNsID09IHZvaWRfdHlwZV9ub2RlKQogICAgcmV0dXJuIGRlY2w7CgogIG9sZF9pbml0aWFsID0gREVDTF9JTklUSUFMIChmbmRlY2wpOwoKICAvKiBVbmRvIHRoZSBsZXZlbCBmb3IgdGhlIHBhcm1zIChmcm9tIHN0YXJ0X21ldGhvZCkuCiAgICAgVGhpcyBpcyBsaWtlIHBvcGxldmVsLCBidXQgaXQgY2F1c2VzIG5vdGhpbmcgdG8gYmUKICAgICBzYXZlZC4gIFNhdmluZyBpbmZvcm1hdGlvbiBoZXJlIGNvbmZ1c2VzIHN5bWJvbC10YWJsZQogICAgIG91dHB1dCByb3V0aW5lcy4gIEJlc2lkZXMsIHRoaXMgaW5mb3JtYXRpb24gd2lsbAogICAgIGJlIGNvcnJlY3RseSBvdXRwdXQgd2hlbiB0aGlzIG1ldGhvZCBpcyBhY3R1YWxseQogICAgIGNvbXBpbGVkLiAgKi8KCiAgLyogQ2xlYXIgb3V0IHRoZSBtZWFuaW5ncyBvZiB0aGUgbG9jYWwgdmFyaWFibGVzIG9mIHRoaXMgbGV2ZWw7CiAgICAgYWxzbyByZWNvcmQgaW4gZWFjaCBkZWNsIHdoaWNoIGJsb2NrIGl0IGJlbG9uZ3MgdG8uICAqLwoKICBmb3IgKGxpbmsgPSBjdXJyZW50X2JpbmRpbmdfbGV2ZWwtPm5hbWVzOyBsaW5rOyBsaW5rID0gVFJFRV9DSEFJTiAobGluaykpCiAgICB7CiAgICAgIGlmIChERUNMX05BTUUgKGxpbmspICE9IE5VTExfVFJFRSkKCXBvcF9iaW5kaW5nIChERUNMX05BTUUgKGxpbmspLCBsaW5rKTsKICAgICAgZ2NjX2Fzc2VydCAoVFJFRV9DT0RFIChsaW5rKSAhPSBGVU5DVElPTl9ERUNMKTsKICAgICAgREVDTF9DT05URVhUIChsaW5rKSA9IE5VTExfVFJFRTsKICAgIH0KCiAgcG9wbGV2ZWwgKDAsIDAsIDApOwoKICBERUNMX0lOSVRJQUwgKGZuZGVjbCkgPSBvbGRfaW5pdGlhbDsKCiAgLyogV2UgdXNlZCB0byBjaGVjayBpZiB0aGUgY29udGV4dCBvZiBGTkRFQ0wgd2FzIGRpZmZlcmVudCBmcm9tCiAgICAgY3VycmVudF9jbGFzc190eXBlIGFzIGFub3RoZXIgd2F5IHRvIGdldCBpbnNpZGUgaGVyZS4gIFRoaXMgZGlkbid0IHdvcmsKICAgICBmb3IgU3RyaW5nLmNjIGluIGxpYmcrKy4gICovCiAgaWYgKERFQ0xfRlJJRU5EX1AgKGZuZGVjbCkpCiAgICB7CiAgICAgIFZFQ19zYWZlX3B1c2ggKHRyZWUsIENMQVNTVFlQRV9JTkxJTkVfRlJJRU5EUyAoY3VycmVudF9jbGFzc190eXBlKSwKCQkgICAgIGZuZGVjbCk7CiAgICAgIGRlY2wgPSB2b2lkX3R5cGVfbm9kZTsKICAgIH0KCiAgcmV0dXJuIGRlY2w7Cn0KDAoKLyogVkFSIGlzIGEgVkFSX0RFQ0wuICBJZiBpdHMgdHlwZSBpcyBpbmNvbXBsZXRlLCByZW1lbWJlciBWQVIgc28gdGhhdAogICB3ZSBjYW4gbGF5IGl0IG91dCBsYXRlciwgd2hlbiBhbmQgaWYgaXRzIHR5cGUgYmVjb21lcyBjb21wbGV0ZS4gICovCgp2b2lkCm1heWJlX3JlZ2lzdGVyX2luY29tcGxldGVfdmFyICh0cmVlIHZhcikKewogIGdjY19hc3NlcnQgKFRSRUVfQ09ERSAodmFyKSA9PSBWQVJfREVDTCk7CgogIC8qIEtlZXAgdHJhY2sgb2YgdmFyaWFibGVzIHdpdGggaW5jb21wbGV0ZSB0eXBlcy4gICovCiAgaWYgKCFwcm9jZXNzaW5nX3RlbXBsYXRlX2RlY2wgJiYgVFJFRV9UWVBFICh2YXIpICE9IGVycm9yX21hcmtfbm9kZQogICAgICAmJiBERUNMX0VYVEVSTkFMICh2YXIpKQogICAgewogICAgICB0cmVlIGlubmVyX3R5cGUgPSBUUkVFX1RZUEUgKHZhcik7CgogICAgICB3aGlsZSAoVFJFRV9DT0RFIChpbm5lcl90eXBlKSA9PSBBUlJBWV9UWVBFKQoJaW5uZXJfdHlwZSA9IFRSRUVfVFlQRSAoaW5uZXJfdHlwZSk7CiAgICAgIGlubmVyX3R5cGUgPSBUWVBFX01BSU5fVkFSSUFOVCAoaW5uZXJfdHlwZSk7CgogICAgICBpZiAoKCFDT01QTEVURV9UWVBFX1AgKGlubmVyX3R5cGUpICYmIENMQVNTX1RZUEVfUCAoaW5uZXJfdHlwZSkpCgkgIC8qIFJUVEkgVEQgZW50cmllcyBhcmUgY3JlYXRlZCB3aGlsZSBkZWZpbmluZyB0aGUgdHlwZV9pbmZvLiAgKi8KCSAgfHwgKFRZUEVfTEFOR19TUEVDSUZJQyAoaW5uZXJfdHlwZSkKCSAgICAgICYmIFRZUEVfQkVJTkdfREVGSU5FRCAoaW5uZXJfdHlwZSkpKQoJaW5jb21wbGV0ZV92YXJzID0gdHJlZV9jb25zIChpbm5lcl90eXBlLCB2YXIsIGluY29tcGxldGVfdmFycyk7CiAgICB9Cn0KCi8qIENhbGxlZCB3aGVuIGEgY2xhc3MgdHlwZSAoZ2l2ZW4gYnkgVFlQRSkgaXMgZGVmaW5lZC4gIElmIHRoZXJlIGFyZQogICBhbnkgZXhpc3RpbmcgVkFSX0RFQ0xzIHdob3NlIHR5cGUgaHNhIGJlZW4gY29tcGxldGVkIGJ5IHRoaXMKICAgZGVjbGFyYXRpb24sIHVwZGF0ZSB0aGVtIG5vdy4gICovCgp2b2lkCmNvbXBsZXRlX3ZhcnMgKHRyZWUgdHlwZSkKewogIHRyZWUgKmxpc3QgPSAmaW5jb21wbGV0ZV92YXJzOwoKICBnY2NfYXNzZXJ0IChDTEFTU19UWVBFX1AgKHR5cGUpKTsKICB3aGlsZSAoKmxpc3QpCiAgICB7CiAgICAgIGlmIChzYW1lX3R5cGVfcCAodHlwZSwgVFJFRV9QVVJQT1NFICgqbGlzdCkpKQoJewoJICB0cmVlIHZhciA9IFRSRUVfVkFMVUUgKCpsaXN0KTsKCSAgdHJlZSB0eXBlID0gVFJFRV9UWVBFICh2YXIpOwoJICAvKiBDb21wbGV0ZSB0aGUgdHlwZSBvZiB0aGUgdmFyaWFibGUuICBUaGUgVkFSX0RFQ0wgaXRzZWxmCgkgICAgIHdpbGwgYmUgbGFpZCBvdXQgaW4gZXhwYW5kX2V4cHIuICAqLwoJICBjb21wbGV0ZV90eXBlICh0eXBlKTsKCSAgY3BfYXBwbHlfdHlwZV9xdWFsc190b19kZWNsIChjcF90eXBlX3F1YWxzICh0eXBlKSwgdmFyKTsKCSAgLyogUmVtb3ZlIHRoaXMgZW50cnkgZnJvbSB0aGUgbGlzdC4gICovCgkgICpsaXN0ID0gVFJFRV9DSEFJTiAoKmxpc3QpOwoJfQogICAgICBlbHNlCglsaXN0ID0gJlRSRUVfQ0hBSU4gKCpsaXN0KTsKICAgIH0KCiAgLyogQ2hlY2sgZm9yIHBlbmRpbmcgZGVjbGFyYXRpb25zIHdoaWNoIG1heSBoYXZlIGFic3RyYWN0IHR5cGUuICAqLwogIGNvbXBsZXRlX3R5cGVfY2hlY2tfYWJzdHJhY3QgKHR5cGUpOwp9CgovKiBJZiBERUNMIGlzIG9mIGEgdHlwZSB3aGljaCBuZWVkcyBhIGNsZWFudXAsIGJ1aWxkIHRoYXQgY2xlYW51cAogICBoZXJlLiAgKi8KCnRyZWUKY3h4X21heWJlX2J1aWxkX2NsZWFudXAgKHRyZWUgZGVjbCkKewogIHRyZWUgdHlwZSA9IFRSRUVfVFlQRSAoZGVjbCk7CgogIGlmICh0eXBlICE9IGVycm9yX21hcmtfbm9kZSAmJiBUWVBFX0hBU19OT05UUklWSUFMX0RFU1RSVUNUT1IgKHR5cGUpKQogICAgewogICAgICBpbnQgZmxhZ3MgPSBMT09LVVBfTk9STUFMfExPT0tVUF9ERVNUUlVDVE9SOwogICAgICB0cmVlIHJ2YWw7CiAgICAgIGJvb2wgaGFzX3ZiYXNlcyA9IChUUkVFX0NPREUgKHR5cGUpID09IFJFQ09SRF9UWVBFCgkJCSAmJiBDTEFTU1RZUEVfVkJBU0VDTEFTU0VTICh0eXBlKSk7CiAgICAgIC8qIEFQUExFIExPQ0FMIGJlZ2luIEtFWFQgZG91YmxlIGRlc3RydWN0b3IgKi8KICAgICAgc3BlY2lhbF9mdW5jdGlvbl9raW5kIGR0b3IgPSBzZmtfY29tcGxldGVfZGVzdHJ1Y3RvcjsKICAgICAgaWYgKFRBUkdFVF9LRVhUQUJJCgkgICYmIGhhc19hcHBsZV9rZXh0X2NvbXBhdGliaWxpdHlfYXR0cl9wICh0eXBlKSkKCXsKCSAgLyogSWYgd2UgaGF2ZSBhIHRyaXZpYWwgb3BlcmF0b3IgZGVsZXRlICgpLCB3ZSBjYW4gZ28gYWhlYWQgYW5kCgkgICAgIGp1c3QgdXNlIHRoZSBkZWxldGluZyBkZXN0cnVjdG9yLCBzZmtfZGVsZXRpbmdfZGVzdHJ1Y3Rvci4gICovCgoJICBpZiAoISBoYXNfZW1wdHlfb3BlcmF0b3JfZGVsZXRlX3AgKHR5cGUpIHx8IHBlZGFudGljKQoJICAgIHsKCSAgICAgIGNwX3dhcm5pbmdfYXQgKCInJUQnIGlzIGFuIGluc3RhbmNlIG9mIGEgY2xhc3Mgd2hpY2ggZG9lcyAiCgkJCSAibm90IGFsbG93IGdsb2JhbCBvciBzdGFjay1iYXNlZCBvYmplY3RzOyBpdCAiCgkJCSAiZG9lcyBub3QgaGF2ZSBhbiBlbXB0eSBgb3BlcmF0b3IgZGVsZXRlJywgYW5kICIKCQkJICJzbyBpdCB3aWxsICoqIE5PVCAqKiBiZSBkZXN0cnVjdGVkLiIsIGRlY2wpOwoJICAgICAgcmV0dXJuIE5VTExfVFJFRTsKCSAgICB9CgkgIGR0b3IgPSBzZmtfZGVsZXRpbmdfZGVzdHJ1Y3RvcjsKCX0KICAgICAgLyogQVBQTEUgTE9DQUwgZW5kIEtFWFQgZG91YmxlIGRlc3RydWN0b3IgKi8KCiAgICAgIGlmIChUUkVFX0NPREUgKHR5cGUpID09IEFSUkFZX1RZUEUpCglydmFsID0gZGVjbDsKICAgICAgZWxzZQoJewoJICBjeHhfbWFya19hZGRyZXNzYWJsZSAoZGVjbCk7CgkgIHJ2YWwgPSBidWlsZF91bmFyeV9vcCAoQUREUl9FWFBSLCBkZWNsLCAwKTsKCX0KCiAgICAgIC8qIE9wdGltaXplIGZvciBzcGFjZSBvdmVyIHNwZWVkIGhlcmUuICAqLwogICAgICBpZiAoIWhhc192YmFzZXMgfHwgZmxhZ19leHBlbnNpdmVfb3B0aW1pemF0aW9ucykKCWZsYWdzIHw9IExPT0tVUF9OT05WSVJUVUFMOwoKICAgICAgcnZhbCA9IGJ1aWxkX2RlbGV0ZSAoVFJFRV9UWVBFIChydmFsKSwgcnZhbCwKCQkJICAgLyogQVBQTEUgTE9DQUwgS0VYVCBkb3VibGUgZGVzdHJ1Y3RvciAgKi8KCQkJICAgZHRvciwgZmxhZ3MsIDApOwoKICAgICAgcmV0dXJuIHJ2YWw7CiAgICB9CiAgcmV0dXJuIE5VTExfVFJFRTsKfQoMCi8qIFdoZW4gYSBzdG10IGhhcyBiZWVuIHBhcnNlZCwgdGhpcyBmdW5jdGlvbiBpcyBjYWxsZWQuICAqLwoKdm9pZApmaW5pc2hfc3RtdCAodm9pZCkKewp9CgovKiBERUNMIHdhcyBvcmlnaW5hbGx5IGNvbnN0cnVjdGVkIGFzIGEgbm9uLXN0YXRpYyBtZW1iZXIgZnVuY3Rpb24sCiAgIGJ1dCB0dXJuZWQgb3V0IHRvIGJlIHN0YXRpYy4gIFVwZGF0ZSBpdCBhY2NvcmRpbmdseS4gICovCgp2b2lkCnJldmVydF9zdGF0aWNfbWVtYmVyX2ZuICh0cmVlIGRlY2wpCnsKICB0cmVlIHRtcDsKICB0cmVlIGZ1bmN0aW9uID0gVFJFRV9UWVBFIChkZWNsKTsKICB0cmVlIGFyZ3MgPSBUWVBFX0FSR19UWVBFUyAoZnVuY3Rpb24pOwoKICBpZiAoY3BfdHlwZV9xdWFscyAoVFJFRV9UWVBFIChUUkVFX1ZBTFVFIChhcmdzKSkpCiAgICAgICE9IFRZUEVfVU5RVUFMSUZJRUQpCiAgICBlcnJvciAoInN0YXRpYyBtZW1iZXIgZnVuY3Rpb24gJXEjRCBkZWNsYXJlZCB3aXRoIHR5cGUgcXVhbGlmaWVycyIsIGRlY2wpOwoKICBhcmdzID0gVFJFRV9DSEFJTiAoYXJncyk7CiAgdG1wID0gYnVpbGRfZnVuY3Rpb25fdHlwZSAoVFJFRV9UWVBFIChmdW5jdGlvbiksIGFyZ3MpOwogIHRtcCA9IGJ1aWxkX3F1YWxpZmllZF90eXBlICh0bXAsIGNwX3R5cGVfcXVhbHMgKGZ1bmN0aW9uKSk7CiAgdG1wID0gYnVpbGRfZXhjZXB0aW9uX3ZhcmlhbnQgKHRtcCwKCQkJCSBUWVBFX1JBSVNFU19FWENFUFRJT05TIChmdW5jdGlvbikpOwogIFRSRUVfVFlQRSAoZGVjbCkgPSB0bXA7CiAgaWYgKERFQ0xfQVJHVU1FTlRTIChkZWNsKSkKICAgIERFQ0xfQVJHVU1FTlRTIChkZWNsKSA9IFRSRUVfQ0hBSU4gKERFQ0xfQVJHVU1FTlRTIChkZWNsKSk7CiAgREVDTF9TVEFUSUNfRlVOQ1RJT05fUCAoZGVjbCkgPSAxOwp9CgovKiBJbml0aWFsaXplIHRoZSB2YXJpYWJsZXMgdXNlZCBkdXJpbmcgY29tcGlsYXRpb24gb2YgYSBDKysKICAgZnVuY3Rpb24uICAqLwoKdm9pZApjeHhfcHVzaF9mdW5jdGlvbl9jb250ZXh0IChzdHJ1Y3QgZnVuY3Rpb24gKiBmKQp7CiAgc3RydWN0IGxhbmd1YWdlX2Z1bmN0aW9uICpwID0gR0dDX0NORVcgKHN0cnVjdCBsYW5ndWFnZV9mdW5jdGlvbik7CiAgZi0+bGFuZ3VhZ2UgPSBwOwoKICAvKiBXaGVuZXZlciB3ZSBzdGFydCBhIG5ldyBmdW5jdGlvbiwgd2UgZGVzdHJveSB0ZW1wb3JhcmllcyBpbiB0aGUKICAgICB1c3VhbCB3YXkuICAqLwogIGN1cnJlbnRfc3RtdF90cmVlICgpLT5zdG10c19hcmVfZnVsbF9leHByc19wID0gMTsKCiAgaWYgKGYtPmRlY2wpCiAgICB7CiAgICAgIHRyZWUgZm4gPSBmLT5kZWNsOwoKICAgICAgaWYgKERFQ0xfU0FWRURfRlVOQ1RJT05fREFUQSAoZm4pKQoJewoJICAvKiBJZiB3ZSBhbHJlYWR5IHBhcnNlZCB0aGlzIGZ1bmN0aW9uLCBhbmQgd2UncmUganVzdCBleHBhbmRpbmcgaXQKCSAgICAgbm93LCByZXN0b3JlIHNhdmVkIHN0YXRlLiAgKi8KCSAgKmNwX2Z1bmN0aW9uX2NoYWluID0gKkRFQ0xfU0FWRURfRlVOQ1RJT05fREFUQSAoZm4pOwoKCSAgLyogV2UgZG9uJ3QgbmVlZCB0aGUgc2F2ZWQgZGF0YSBhbnltb3JlLiAgVW5sZXNzIHRoaXMgaXMgYW4gaW5saW5lCgkgICAgIGZ1bmN0aW9uOyB3ZSBuZWVkIHRoZSBuYW1lZCByZXR1cm4gdmFsdWUgaW5mbyBmb3IKCSAgICAgZGVjbGFyZV9yZXR1cm5fdmFyaWFibGUuICAqLwoJICBpZiAoISBERUNMX0lOTElORSAoZm4pKQoJICAgIERFQ0xfU0FWRURfRlVOQ1RJT05fREFUQSAoZm4pID0gTlVMTDsKCX0KICAgIH0KfQoKLyogRnJlZSB0aGUgbGFuZ3VhZ2Utc3BlY2lmaWMgcGFydHMgb2YgRiwgbm93IHRoYXQgd2UndmUgZmluaXNoZWQKICAgY29tcGlsaW5nIHRoZSBmdW5jdGlvbi4gICovCgp2b2lkCmN4eF9wb3BfZnVuY3Rpb25fY29udGV4dCAoc3RydWN0IGZ1bmN0aW9uICogZikKewogIGYtPmxhbmd1YWdlID0gMDsKfQoKLyogUmV0dXJuIHdoaWNoIHRyZWUgc3RydWN0dXJlIGlzIHVzZWQgYnkgVCwgb3IgVFNfQ1BfR0VORVJJQyBpZiBUIGlzCiAgIG9uZSBvZiB0aGUgbGFuZ3VhZ2UtaW5kZXBlbmRlbnQgdHJlZXMuICAqLwoKZW51bSBjcF90cmVlX25vZGVfc3RydWN0dXJlX2VudW0KY3BfdHJlZV9ub2RlX3N0cnVjdHVyZSAodW5pb24gbGFuZ190cmVlX25vZGUgKiB0KQp7CiAgc3dpdGNoIChUUkVFX0NPREUgKCZ0LT5nZW5lcmljKSkKICAgIHsKICAgIGNhc2UgREVGQVVMVF9BUkc6CQlyZXR1cm4gVFNfQ1BfREVGQVVMVF9BUkc7CiAgICBjYXNlIElERU5USUZJRVJfTk9ERToJcmV0dXJuIFRTX0NQX0lERU5USUZJRVI7CiAgICBjYXNlIE9WRVJMT0FEOgkJcmV0dXJuIFRTX0NQX09WRVJMT0FEOwogICAgY2FzZSBURU1QTEFURV9QQVJNX0lOREVYOglyZXR1cm4gVFNfQ1BfVFBJOwogICAgY2FzZSBUSU5TVF9MRVZFTDoJCXJldHVybiBUU19DUF9USU5TVF9MRVZFTDsKICAgIGNhc2UgUFRSTUVNX0NTVDoJCXJldHVybiBUU19DUF9QVFJNRU07CiAgICBjYXNlIEJBU0VMSU5LOiAgICAgICAgICAgICAgcmV0dXJuIFRTX0NQX0JBU0VMSU5LOwogICAgZGVmYXVsdDoJCQlyZXR1cm4gVFNfQ1BfR0VORVJJQzsKICAgIH0KfQoKLyogQnVpbGQgdGhlIHZvaWRfbGlzdF9ub2RlICh2b2lkX3R5cGVfbm9kZSBoYXZpbmcgYmVlbiBjcmVhdGVkKS4gICovCnRyZWUKYnVpbGRfdm9pZF9saXN0X25vZGUgKHZvaWQpCnsKICB0cmVlIHQgPSBidWlsZF90cmVlX2xpc3QgKE5VTExfVFJFRSwgdm9pZF90eXBlX25vZGUpOwogIHJldHVybiB0Owp9Cgpib29sCmNwX21pc3Npbmdfbm9yZXR1cm5fb2tfcCAodHJlZSBkZWNsKQp7CiAgLyogQSBtaXNzaW5nIG5vcmV0dXJuIGlzIG9rIGZvciB0aGUgYG1haW4nIGZ1bmN0aW9uLiAgKi8KICByZXR1cm4gREVDTF9NQUlOX1AgKGRlY2wpOwp9CgovKiBSZXR1cm4gdGhlIENPTURBVCBncm91cCBpbnRvIHdoaWNoIERFQ0wgc2hvdWxkIGJlIHBsYWNlZC4gICovCgpjb25zdCBjaGFyICoKY3h4X2NvbWRhdF9ncm91cCAodHJlZSBkZWNsKQp7CiAgdHJlZSBuYW1lOwoKICAvKiBWaXJ0dWFsIHRhYmxlcywgY29uc3RydWN0aW9uIHZpcnR1YWwgdGFibGVzLCBhbmQgdmlydHVhbCB0YWJsZQogICAgIHRhYmxlcyBhbGwgZ28gaW4gYSBzaW5nbGUgQ09NREFUIGdyb3VwLCBuYW1lZCBhZnRlciB0aGUgcHJpbWFyeQogICAgIHZpcnR1YWwgdGFibGUuICAqLwogIGlmIChUUkVFX0NPREUgKGRlY2wpID09IFZBUl9ERUNMICYmIERFQ0xfVlRBQkxFX09SX1ZUVF9QIChkZWNsKSkKICAgIG5hbWUgPSBERUNMX0FTU0VNQkxFUl9OQU1FIChDTEFTU1RZUEVfVlRBQkxFUyAoREVDTF9DT05URVhUIChkZWNsKSkpOwogIC8qIEZvciBhbGwgb3RoZXIgREVDTHMsIHRoZSBDT01EQVQgZ3JvdXAgaXMgdGhlIG1hbmdsZWQgbmFtZSBvZiB0aGUKICAgICBkZWNsYXJhdGlvbiBpdHNlbGYuICAqLwogIGVsc2UKICAgIHsKICAgICAgd2hpbGUgKERFQ0xfVEhVTktfUCAoZGVjbCkpCgl7CgkgIC8qIElmIFRBUkdFVF9VU0VfTE9DQUxfVEhVTktfQUxJQVNfUCwgdXNlX3RodW5rIHB1dHMgdGhlIHRodW5rCgkgICAgIGludG8gdGhlIHNhbWUgc2VjdGlvbiBhcyB0aGUgdGFyZ2V0IGZ1bmN0aW9uLiAgSW4gdGhhdCBjYXNlCgkgICAgIHdlIG11c3QgcmV0dXJuIHRhcmdldCdzIG5hbWUuICAqLwoJICB0cmVlIHRhcmdldCA9IFRIVU5LX1RBUkdFVCAoZGVjbCk7CgkgIGlmIChUQVJHRVRfVVNFX0xPQ0FMX1RIVU5LX0FMSUFTX1AgKHRhcmdldCkKCSAgICAgICYmIERFQ0xfU0VDVElPTl9OQU1FICh0YXJnZXQpICE9IE5VTEwKCSAgICAgICYmIERFQ0xfT05FX09OTFkgKHRhcmdldCkpCgkgICAgZGVjbCA9IHRhcmdldDsKCSAgZWxzZQoJICAgIGJyZWFrOwoJfQogICAgICBuYW1lID0gREVDTF9BU1NFTUJMRVJfTkFNRSAoZGVjbCk7CiAgICB9CgogIHJldHVybiBJREVOVElGSUVSX1BPSU5URVIgKG5hbWUpOwp9CgojaW5jbHVkZSAiZ3QtY3AtZGVjbC5oIgo=