LyoKICAgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogICBpMmMtYWRhcC1pdGUuYyBpMmMtaHcgYWNjZXNzIGZvciB0aGUgSUlDIHBlcmlwaGVyYWwgb24gdGhlIElURSBNSVBTIHN5c3RlbQogICAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgIEhhaS1QYW8gRmFuLCBNb250YVZpc3RhIFNvZnR3YXJlLCBJbmMuCiAgIGhwZmFuQG12aXN0YS5jb20gb3Igc291cmNlQG12aXN0YS5jb20KCiAgIENvcHlyaWdodCAyMDAxIE1vbnRhVmlzdGEgU29mdHdhcmUgSW5jLgoKICAgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogICBUaGlzIGZpbGUgd2FzIGhpZ2hseSBsZXZlcmFnZWQgZnJvbSBpMmMtZWxla3Rvci5jLCB3aGljaCB3YXMgY3JlYXRlZAogICBieSBTaW1vbiBHLiBWb2dsIGFuZCBIYW5zIEJlcmdsdW5kOgoKIAogICAgIENvcHlyaWdodCAoQykgMTk5NS05NyBTaW1vbiBHLiBWb2dsCiAgICAgICAgICAgICAgICAgICAxOTk4LTk5IEhhbnMgQmVyZ2x1bmQKCiAgICBUaGlzIHByb2dyYW0gaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeQogICAgaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkKICAgIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlciB2ZXJzaW9uIDIgb2YgdGhlIExpY2Vuc2UsIG9yCiAgICAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLgoKICAgIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLAogICAgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YKICAgIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUKICAgIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuCgogICAgWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKICAgIGFsb25nIHdpdGggdGhpcyBwcm9ncmFtOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlCiAgICBGb3VuZGF0aW9uLCBJbmMuLCA2NzUgTWFzcyBBdmUsIENhbWJyaWRnZSwgTUEgMDIxMzksIFVTQS4JCSAgICAgKi8KLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLwoKLyogV2l0aCBzb21lIGNoYW5nZXMgZnJvbSBLefZzdGkgTeRsa2tpIDxrbWFsa2tpQGNjLmh1dC5maT4gYW5kIGV2ZW4KICAgRnJvZG8gTG9vaWphYXJkIDxmcm9kb2xAZGRzLm5sPiAqLwoKI2luY2x1ZGUgPGxpbnV4L2NvbmZpZy5oPgojaW5jbHVkZSA8bGludXgva2VybmVsLmg+CiNpbmNsdWRlIDxsaW51eC9pb3BvcnQuaD4KI2luY2x1ZGUgPGxpbnV4L21vZHVsZS5oPgojaW5jbHVkZSA8bGludXgvZGVsYXkuaD4KI2luY2x1ZGUgPGxpbnV4L3NsYWIuaD4KI2luY2x1ZGUgPGxpbnV4L2luaXQuaD4KI2luY2x1ZGUgPGxpbnV4L3dhaXQuaD4KI2luY2x1ZGUgPGFzbS9pcnEuaD4KI2luY2x1ZGUgPGFzbS9pby5oPgoKI2luY2x1ZGUgPGxpbnV4L2kyYy5oPgojaW5jbHVkZSA8bGludXgvaTJjLWFsZ28taXRlLmg+CiNpbmNsdWRlIDxsaW51eC9pMmMtYWRhcC1pdGUuaD4KI2luY2x1ZGUgIi4uL2kyYy1pdGUuaCIKCiNkZWZpbmUgREVGQVVMVF9CQVNFICAweDE0MDE0MDMwCiNkZWZpbmUgSVRFX0lJQ19JT19TSVpFCTB4NDAKI2RlZmluZSBERUZBVUxUX0lSUSAgIDAKI2RlZmluZSBERUZBVUxUX0NMT0NLIDB4MWIwZQkvKiBkZWZhdWx0IDE2TUh6LygyNysxNCkgPSA0MDBLSHogKi8KI2RlZmluZSBERUZBVUxUX09XTiAgIDB4NTUKCnN0YXRpYyBpbnQgYmFzZTsKc3RhdGljIGludCBpcnE7CnN0YXRpYyBpbnQgY2xvY2s7CnN0YXRpYyBpbnQgb3duOwoKc3RhdGljIHN0cnVjdCBpaWNfaXRlIGdwaTsKc3RhdGljIHdhaXRfcXVldWVfaGVhZF90IGlpY193YWl0OwpzdGF0aWMgaW50IGlpY19wZW5kaW5nOwpzdGF0aWMgc3BpbmxvY2tfdCBsb2NrOwoKLyogLS0tLS0gbG9jYWwgZnVuY3Rpb25zIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0JKi8KCnN0YXRpYyB2b2lkIGlpY19pdGVfc2V0aWljKHZvaWQgKmRhdGEsIGludCBjdGwsIHNob3J0IHZhbCkKewogICAgICAgIHVuc2lnbmVkIGxvbmcgaiA9IGppZmZpZXMgKyAxMDsKCglwcl9kZWJ1ZygiIFdyaXRlIDB4JTAyeCB0byAweCV4XG4iLCh1bnNpZ25lZCBzaG9ydCl2YWwsIGN0bCYweGZmKTsKI2lmZGVmIERFQlVHCgl3aGlsZSAodGltZV9iZWZvcmUoamlmZmllcywgaikpCgkJc2NoZWR1bGUoKTsKI2VuZGlmCglvdXR3KHZhbCxjdGwpOwp9CgpzdGF0aWMgc2hvcnQgaWljX2l0ZV9nZXRpaWModm9pZCAqZGF0YSwgaW50IGN0bCkKewoJc2hvcnQgdmFsOwoKCXZhbCA9IGludyhjdGwpOwoJcHJfZGVidWcoIlJlYWQgMHglMDJ4IGZyb20gMHgleFxuIiwodW5zaWduZWQgc2hvcnQpdmFsLCBjdGwmMHhmZik7CglyZXR1cm4gKHZhbCk7Cn0KCi8qIFJldHVybiBvdXIgc2xhdmUgYWRkcmVzcy4gIFRoaXMgaXMgdGhlIGFkZHJlc3MKICogcHV0IG9uIHRoZSBJMkMgYnVzIHdoZW4gYW5vdGhlciBtYXN0ZXIgb24gdGhlIGJ1cyB3YW50cyB0byBhZGRyZXNzIHVzCiAqIGFzIGEgc2xhdmUKICovCnN0YXRpYyBpbnQgaWljX2l0ZV9nZXRvd24odm9pZCAqZGF0YSkKewoJcmV0dXJuIChncGkuaWljX293bik7Cn0KCgpzdGF0aWMgaW50IGlpY19pdGVfZ2V0Y2xvY2sodm9pZCAqZGF0YSkKewoJcmV0dXJuIChncGkuaWljX2Nsb2NrKTsKfQoKCi8qIFB1dCB0aGlzIHByb2Nlc3MgdG8gc2xlZXAuICBXZSB3aWxsIHdha2UgdXAgd2hlbiB0aGUKICogSUlDIGNvbnRyb2xsZXIgaW50ZXJydXB0cy4KICovCnN0YXRpYyB2b2lkIGlpY19pdGVfd2FpdGZvcnBpbih2b2lkKSB7CiAgIERFRklORV9XQUlUKHdhaXQpOwogICBpbnQgdGltZW91dCA9IDI7CiAgIGxvbmcgZmxhZ3M7CgogICAvKiBJZiBpbnRlcnJ1cHRzIGFyZSBlbmFibGVkICh3aGljaCB0aGV5IGFyZSksIHRoZW4gcHV0IHRoZSBwcm9jZXNzIHRvCiAgICAqIHNsZWVwLiAgVGhpcyBwcm9jZXNzIHdpbGwgYmUgYXdha2VuZWQgYnkgdHdvIGV2ZW50cyAtLSBlaXRoZXIgdGhlCiAgICAqIHRoZSBJSUMgcGVyaXBoZXJhbCBpbnRlcnJ1cHRzIG9yIHRoZSB0aW1lb3V0IGV4cGlyZXMuIAogICAgKiBJZiBpbnRlcnJ1cHRzIGFyZSBub3QgZW5hYmxlZCB0aGVuIGRlbGF5IGZvciBhIHJlYXNvbmFibGUgYW1vdW50IAogICAgKiBvZiB0aW1lIGFuZCByZXR1cm4uCiAgICAqLwogICBpZiAoZ3BpLmlpY19pcnEgPiAwKSB7CglzcGluX2xvY2tfaXJxc2F2ZSgmbG9jaywgZmxhZ3MpOwoJaWYgKGlpY19wZW5kaW5nID09IDApIHsKCQlzcGluX3VubG9ja19pcnFyZXN0b3JlKCZsb2NrLCBmbGFncyk7CgkJcHJlcGFyZV90b193YWl0KCZpaWNfd2FpdCwgJndhaXQsIFRBU0tfSU5URVJSVVBUSUJMRSk7CgkJaWYgKHNjaGVkdWxlX3RpbWVvdXQodGltZW91dCpIWikpIHsKCQkJc3Bpbl9sb2NrX2lycXNhdmUoJmxvY2ssIGZsYWdzKTsKCQkJaWYgKGlpY19wZW5kaW5nID09IDEpIHsKCQkJCWlpY19wZW5kaW5nID0gMDsKCQkJfQoJCQlzcGluX3VubG9ja19pcnFyZXN0b3JlKCZsb2NrLCBmbGFncyk7CgkJfQoJCWZpbmlzaF93YWl0KCZpaWNfd2FpdCwgJndhaXQpOwoJfSBlbHNlIHsKCQlpaWNfcGVuZGluZyA9IDA7CgkJc3Bpbl91bmxvY2tfaXJxcmVzdG9yZSgmbG9jaywgZmxhZ3MpOwoJfQogICB9IGVsc2UgewogICAgICB1ZGVsYXkoMTAwKTsKICAgfQp9CgoKc3RhdGljIGlycXJldHVybl90IGlpY19pdGVfaGFuZGxlcihpbnQgdGhpc19pcnEsIHZvaWQgKmRldl9pZCwKCQkJCQkJCXN0cnVjdCBwdF9yZWdzICpyZWdzKQp7CglzcGluX2xvY2soJmxvY2spOwoJaWljX3BlbmRpbmcgPSAxOwoJc3Bpbl91bmxvY2soJmxvY2spOwoKCXdha2VfdXBfaW50ZXJydXB0aWJsZSgmaWljX3dhaXQpOwoKCXJldHVybiBJUlFfSEFORExFRDsKfQoKCi8qIExvY2sgdGhlIHJlZ2lvbiBvZiBtZW1vcnkgd2hlcmUgSS9PIHJlZ2lzdGVycyBleGlzdC4gIFJlcXVlc3Qgb3VyCiAqIGludGVycnVwdCBsaW5lIGFuZCByZWdpc3RlciBpdHMgYXNzb2NpYXRlZCBoYW5kbGVyLgogKi8Kc3RhdGljIGludCBpaWNfaHdfcmVzcmNfaW5pdCh2b2lkKQp7CglpZiAoIXJlcXVlc3RfcmVnaW9uKGdwaS5paWNfYmFzZSwgSVRFX0lJQ19JT19TSVpFLCAiaTJjIikpCgkJcmV0dXJuIC1FTk9ERVY7CiAgCglpZiAoZ3BpLmlpY19pcnEgPD0gMCkKCQlyZXR1cm4gMDsKCglpZiAocmVxdWVzdF9pcnEoZ3BpLmlpY19pcnEsIGlpY19pdGVfaGFuZGxlciwgMCwgIklURSBJSUMiLCAwKSA8IDApCgkJZ3BpLmlpY19pcnEgPSAwOwoJZWxzZQoJCWVuYWJsZV9pcnEoZ3BpLmlpY19pcnEpOwoKCXJldHVybiAwOwp9CgoKc3RhdGljIHZvaWQgaWljX2l0ZV9yZWxlYXNlKHZvaWQpCnsKCWlmIChncGkuaWljX2lycSA+IDApIHsKCQlkaXNhYmxlX2lycShncGkuaWljX2lycSk7CgkJZnJlZV9pcnEoZ3BpLmlpY19pcnEsIDApOwoJfQoJcmVsZWFzZV9yZWdpb24oZ3BpLmlpY19iYXNlICwgMik7Cn0KCi8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogKiBFbmNhcHN1bGF0ZSB0aGUgYWJvdmUgZnVuY3Rpb25zIGluIHRoZSBjb3JyZWN0IG9wZXJhdGlvbnMgc3RydWN0dXJlLgogKiBUaGlzIGlzIG9ubHkgZG9uZSB3aGVuIG1vcmUgdGhhbiBvbmUgaGFyZHdhcmUgYWRhcHRlciBpcyBzdXBwb3J0ZWQuCiAqLwpzdGF0aWMgc3RydWN0IGkyY19hbGdvX2lpY19kYXRhIGlpY19pdGVfZGF0YSA9IHsKCU5VTEwsCglpaWNfaXRlX3NldGlpYywKCWlpY19pdGVfZ2V0aWljLAoJaWljX2l0ZV9nZXRvd24sCglpaWNfaXRlX2dldGNsb2NrLAoJaWljX2l0ZV93YWl0Zm9ycGluLAoJODAsIDgwLCAxMDAsCQkvKgl3YWl0cywgdGltZW91dCAqLwp9OwoKc3RhdGljIHN0cnVjdCBpMmNfYWRhcHRlciBpaWNfaXRlX29wcyA9IHsKCS5vd25lcgkJPSBUSElTX01PRFVMRSwKCS5pZAkJPSBJMkNfSFdfSV9JSUMsCgkuYWxnb19kYXRhCT0gJmlpY19pdGVfZGF0YSwKCS5kZXYJCT0gewoJCS5uYW1lCT0gIklURSBJSUMgYWRhcHRlciIsCgl9LAp9OwoKLyogQ2FsbGVkIHdoZW4gdGhlIG1vZHVsZSBpcyBsb2FkZWQuICBUaGlzIGZ1bmN0aW9uIHN0YXJ0cyB0aGUKICogY2FzY2FkZSBvZiBjYWxscyB1cCB0aHJvdWdoIHRoZSBoaWVyYXJjaHkgb2YgaTJjIG1vZHVsZXMgKGkuZS4gdXAgdG8gdGhlCiAqICBhbGdvcml0aG0gbGF5ZXIgYW5kIGludG8gdG8gdGhlIGNvcmUgbGF5ZXIpCiAqLwpzdGF0aWMgaW50IF9faW5pdCBpaWNfaXRlX2luaXQodm9pZCkgCnsKCglzdHJ1Y3QgaWljX2l0ZSAqcGlpYyA9ICZncGk7CgoJcHJpbnRrKEtFUk5fSU5GTyAiSW5pdGlhbGl6ZSBJVEUgSUlDIGFkYXB0ZXIgbW9kdWxlXG4iKTsKCWlmIChiYXNlID09IDApCgkJcGlpYy0+aWljX2Jhc2UgPSBERUZBVUxUX0JBU0U7CgllbHNlCgkJcGlpYy0+aWljX2Jhc2UgPSBiYXNlOwoKCWlmIChpcnEgPT0gMCkKCQlwaWljLT5paWNfaXJxID0gREVGQVVMVF9JUlE7CgllbHNlCgkJcGlpYy0+aWljX2lycSA9IGlycTsKCglpZiAoY2xvY2sgPT0gMCkKCQlwaWljLT5paWNfY2xvY2sgPSBERUZBVUxUX0NMT0NLOwoJZWxzZQoJCXBpaWMtPmlpY19jbG9jayA9IGNsb2NrOwoKCWlmIChvd24gPT0gMCkKCQlwaWljLT5paWNfb3duID0gREVGQVVMVF9PV047CgllbHNlCgkJcGlpYy0+aWljX293biA9IG93bjsKCglpaWNfaXRlX2RhdGEuZGF0YSA9ICh2b2lkICopcGlpYzsKCWluaXRfd2FpdHF1ZXVlX2hlYWQoJmlpY193YWl0KTsKCXNwaW5fbG9ja19pbml0KCZsb2NrKTsKCWlmIChpaWNfaHdfcmVzcmNfaW5pdCgpID09IDApIHsKCQlpZiAoaTJjX2lpY19hZGRfYnVzKCZpaWNfaXRlX29wcykgPCAwKQoJCQlyZXR1cm4gLUVOT0RFVjsKCX0gZWxzZSB7CgkJcmV0dXJuIC1FTk9ERVY7Cgl9CglwcmludGsoS0VSTl9JTkZPICIgZm91bmQgZGV2aWNlIGF0ICUjeCBpcnEgJWQuXG4iLCAKCQlwaWljLT5paWNfYmFzZSwgcGlpYy0+aWljX2lycSk7CglyZXR1cm4gMDsKfQoKCnN0YXRpYyB2b2lkIGlpY19pdGVfZXhpdCh2b2lkKQp7CglpMmNfaWljX2RlbF9idXMoJmlpY19pdGVfb3BzKTsKICAgICAgICBpaWNfaXRlX3JlbGVhc2UoKTsKfQoKLyogSWYgbW9kdWxlcyBpcyBOT1QgZGVmaW5lZCB3aGVuIHRoaXMgZmlsZSBpcyBjb21waWxlZCwgdGhlbiB0aGUgTU9EVUxFXyoKICogbWFjcm9zIHdpbGwgcmVzb2x2ZSB0byBub3RoaW5nCiAqLwpNT0RVTEVfQVVUSE9SKCJNb250YVZpc3RhIFNvZnR3YXJlIDx3d3cubXZpc3RhLmNvbT4iKTsKTU9EVUxFX0RFU0NSSVBUSU9OKCJJMkMtQnVzIGFkYXB0ZXIgcm91dGluZXMgZm9yIElURSBJSUMgYnVzIGFkYXB0ZXIiKTsKTU9EVUxFX0xJQ0VOU0UoIkdQTCIpOwoKbW9kdWxlX3BhcmFtKGJhc2UsIGludCwgMCk7Cm1vZHVsZV9wYXJhbShpcnEsIGludCwgMCk7Cm1vZHVsZV9wYXJhbShjbG9jaywgaW50LCAwKTsKbW9kdWxlX3BhcmFtKG93biwgaW50LCAwKTsKCgovKiBDYWxsZWQgd2hlbiBtb2R1bGUgaXMgbG9hZGVkIG9yIHdoZW4ga2VybmVsIGlzIGluaXRpYWxpemVkLgogKiBJZiBNT0RVTEVTIGlzIGRlZmluZWQgd2hlbiB0aGlzIGZpbGUgaXMgY29tcGlsZWQsIHRoZW4gdGhpcyBmdW5jdGlvbiB3aWxsCiAqIHJlc29sdmUgdG8gaW5pdF9tb2R1bGUgKHRoZSBmdW5jdGlvbiBjYWxsZWQgd2hlbiBpbnNtb2QgaXMgaW52b2tlZCBmb3IgYQogKiBtb2R1bGUpLiAgT3RoZXJ3aXNlLCB0aGlzIGZ1bmN0aW9uIGlzIGNhbGxlZCBlYXJseSBpbiB0aGUgYm9vdCwgd2hlbiB0aGUKICoga2VybmVsIGlzIGludGlhbGl6ZWQuICBDaGVjayBvdXQgL2luY2x1ZGUvaW5pdC5oIHRvIHNlZSBob3cgdGhpcyB3b3Jrcy4KICovCm1vZHVsZV9pbml0KGlpY19pdGVfaW5pdCk7CgovKiBSZXNvbHZlcyB0byBtb2R1bGVfY2xlYW51cCB3aGVuIE1PRFVMRVMgaXMgZGVmaW5lZC4gKi8KbW9kdWxlX2V4aXQoaWljX2l0ZV9leGl0KTsgCg==