LyoKICAgIFNETCAtIFNpbXBsZSBEaXJlY3RNZWRpYSBMYXllcgogICAgQ29weXJpZ2h0IChDKSAxOTk3LTIwMTIgU2FtIExhbnRpbmdhCgogICAgVGhpcyBsaWJyYXJ5IGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vcgogICAgbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIExpYnJhcnkgR2VuZXJhbCBQdWJsaWMKICAgIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlcgogICAgdmVyc2lvbiAyIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLgoKICAgIFRoaXMgbGlicmFyeSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLAogICAgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YKICAgIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VCiAgICBMaWJyYXJ5IEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy4KCiAgICBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGlicmFyeSBHZW5lcmFsIFB1YmxpYwogICAgTGljZW5zZSBhbG9uZyB3aXRoIHRoaXMgbGlicmFyeTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZQogICAgRm91bmRhdGlvbiwgSW5jLiwgNTkgVGVtcGxlIFBsYWNlLCBTdWl0ZSAzMzAsIEJvc3RvbiwgTUEgIDAyMTExLTEzMDcgIFVTQQoKICAgIFNhbSBMYW50aW5nYQogICAgc2xvdWtlbkBsaWJzZGwub3JnCiovCiNpbmNsdWRlICJTRExfY29uZmlnLmgiCgovKgoJTWlOVCBhdWRpbyBkcml2ZXIKCXVzaW5nIFhCSU9TIGZ1bmN0aW9ucyAoRmFsY29uKQoKCVBhdHJpY2UgTWFuZGluLCBEaWRpZXIgTelxdWlnbm9uCiovCgojaW5jbHVkZSA8dW5pc3RkLmg+CiNpbmNsdWRlIDxzdXBwb3J0Lmg+CgovKiBNaW50IGluY2x1ZGVzICovCiNpbmNsdWRlIDxtaW50L29zYmluZC5oPgojaW5jbHVkZSA8bWludC9mYWxjb24uaD4KI2luY2x1ZGUgPG1pbnQvY29va2llLmg+CgojaW5jbHVkZSAiU0RMX2F1ZGlvLmgiCiNpbmNsdWRlICIuLi9TRExfYXVkaW9fYy5oIgojaW5jbHVkZSAiLi4vU0RMX3N5c2F1ZGlvLmgiCgojaW5jbHVkZSAiLi4vLi4vdmlkZW8vYXRhcmljb21tb24vU0RMX2F0YXJpbXhhbGxvY19jLmgiCiNpbmNsdWRlICIuLi8uLi92aWRlby9hdGFyaWNvbW1vbi9TRExfYXRhcmlzdXBlci5oIgoKI2luY2x1ZGUgIlNETF9taW50YXVkaW8uaCIKI2luY2x1ZGUgIlNETF9taW50YXVkaW9fZG1hOC5oIgoKLyotLS0gRGVmaW5lcyAtLS0qLwoKI2RlZmluZSBNSU5UX0FVRElPX0RSSVZFUl9OQU1FICJtaW50X3hiaW9zIgoKLyogRGVidWcgcHJpbnQgaW5mbyAqLwojZGVmaW5lIERFQlVHX05BTUUgImF1ZGlvOnhiaW9zOiAiCiNpZiAwCiNkZWZpbmUgREVCVUdfUFJJTlQod2hhdCkgXAoJeyBcCgkJcHJpbnRmIHdoYXQ7IFwKCX0KI2Vsc2UKI2RlZmluZSBERUJVR19QUklOVCh3aGF0KQojZW5kaWYKCi8qLS0tIFN0YXRpYyB2YXJpYWJsZXMgLS0tKi8KCnN0YXRpYyBsb25nIGNvb2tpZV9zbmQ7CgovKi0tLSBBdWRpbyBkcml2ZXIgZnVuY3Rpb25zIC0tLSovCgpzdGF0aWMgdm9pZCBNaW50X0Nsb3NlQXVkaW8oX1RISVMpOwpzdGF0aWMgaW50IE1pbnRfT3BlbkF1ZGlvKF9USElTLCBTRExfQXVkaW9TcGVjICpzcGVjKTsKc3RhdGljIHZvaWQgTWludF9Mb2NrQXVkaW8oX1RISVMpOwpzdGF0aWMgdm9pZCBNaW50X1VubG9ja0F1ZGlvKF9USElTKTsKCi8qIFRvIGNoZWNrL2luaXQgaGFyZHdhcmUgYXVkaW8gKi8Kc3RhdGljIGludCBNaW50X0NoZWNrQXVkaW8oX1RISVMsIFNETF9BdWRpb1NwZWMgKnNwZWMpOwpzdGF0aWMgdm9pZCBNaW50X0luaXRBdWRpbyhfVEhJUywgU0RMX0F1ZGlvU3BlYyAqc3BlYyk7CgovKi0tLSBBdWRpbyBkcml2ZXIgYm9vdHN0cmFwIGZ1bmN0aW9ucyAtLS0qLwoKc3RhdGljIGludCBBdWRpb19BdmFpbGFibGUodm9pZCkKewovKgl1bnNpZ25lZCBsb25nIGR1bW15OyovCgljb25zdCBjaGFyICplbnZyID0gU0RMX2dldGVudigiU0RMX0FVRElPRFJJVkVSIik7CgoJLypTRExfTWludEF1ZGlvX21pbnRfcHJlc2VudCA9IChHZXRjb29raWUoQ19NaU5ULCAmZHVtbXkpID09IENfRk9VTkQpOyovCglTRExfTWludEF1ZGlvX21pbnRfcHJlc2VudCA9IFNETF9GQUxTRTsKCgkvKiBXZSBjYW4ndCB1c2UgWEJJT1MgaW4gaW50ZXJydXB0IHdpdGggTWFnaWMsIGRvbid0IGtub3cgYWJvdXQgdGhyZWFkICovCgkvKmlmIChHZXRjb29raWUoQ19NYWdYLCAmZHVtbXkpID09IENfRk9VTkQpIHsKCQlyZXR1cm4oMCk7Cgl9Ki8KCgkvKiBDaGVjayBpZiB1c2VyIGFza2VkIGEgZGlmZmVyZW50IGF1ZGlvIGRyaXZlciAqLwoJaWYgKChlbnZyKSAmJiAoU0RMX3N0cmNtcChlbnZyLCBNSU5UX0FVRElPX0RSSVZFUl9OQU1FKSE9MCkpIHsKCQlERUJVR19QUklOVCgoREVCVUdfTkFNRSAidXNlciBhc2tlZCBhIGRpZmZlcmVudCBhdWRpbyBkcml2ZXJcbiIpKTsKCQlyZXR1cm4oMCk7Cgl9CgoJLyogQ29va2llIF9TTkQgcHJlc2VudCA/IGlmIG5vdCwgYXNzdW1lIFNUIG1hY2hpbmUgKi8KCWlmIChHZXRjb29raWUoQ19fU05ELCAmY29va2llX3NuZCkgPT0gQ19OT1RGT1VORCkgewoJCWNvb2tpZV9zbmQgPSBTTkRfUFNHOwoJfQoKCS8qIENoZWNrIGlmIHdlIGhhdmUgMTYgYml0cyBhdWRpbyAqLwoJaWYgKChjb29raWVfc25kICYgU05EXzE2QklUKT09MCkgewoJCURFQlVHX1BSSU5UKChERUJVR19OQU1FICJubyAxNiBiaXRzIHNvdW5kXG4iKSk7CgkJcmV0dXJuKDApOwoJfQoKCS8qIENoZWNrIGlmIGF1ZGlvIGlzIGxvY2thYmxlICovCglpZiAoTG9ja3NuZCgpIT0xKSB7CgkJREVCVUdfUFJJTlQoKERFQlVHX05BTUUgImF1ZGlvIGxvY2tlZCBieSBvdGhlciBhcHBsaWNhdGlvblxuIikpOwoJCXJldHVybigwKTsKCX0KCglVbmxvY2tzbmQoKTsKCglERUJVR19QUklOVCgoREVCVUdfTkFNRSAiWEJJT1MgYXVkaW8gYXZhaWxhYmxlIVxuIikpOwoJcmV0dXJuKDEpOwp9CgpzdGF0aWMgdm9pZCBBdWRpb19EZWxldGVEZXZpY2UoU0RMX0F1ZGlvRGV2aWNlICpkZXZpY2UpCnsKICAgIFNETF9mcmVlKGRldmljZS0+aGlkZGVuKTsKICAgIFNETF9mcmVlKGRldmljZSk7Cn0KCnN0YXRpYyBTRExfQXVkaW9EZXZpY2UgKkF1ZGlvX0NyZWF0ZURldmljZShpbnQgZGV2aW5kZXgpCnsKCVNETF9BdWRpb0RldmljZSAqdGhpczsKCgkvKiBJbml0aWFsaXplIGFsbCB2YXJpYWJsZXMgdGhhdCB3ZSBjbGVhbiBvbiBzaHV0ZG93biAqLwoJdGhpcyA9IChTRExfQXVkaW9EZXZpY2UgKilTRExfbWFsbG9jKHNpemVvZihTRExfQXVkaW9EZXZpY2UpKTsKICAgIGlmICggdGhpcyApIHsKICAgICAgICBTRExfbWVtc2V0KHRoaXMsIDAsIChzaXplb2YgKnRoaXMpKTsKICAgICAgICB0aGlzLT5oaWRkZW4gPSAoc3RydWN0IFNETF9Qcml2YXRlQXVkaW9EYXRhICopCiAgICAgICAgICAgICAgICBTRExfbWFsbG9jKChzaXplb2YgKnRoaXMtPmhpZGRlbikpOwogICAgfQogICAgaWYgKCAodGhpcyA9PSBOVUxMKSB8fCAodGhpcy0+aGlkZGVuID09IE5VTEwpICkgewogICAgICAgIFNETF9PdXRPZk1lbW9yeSgpOwogICAgICAgIGlmICggdGhpcyApIHsKICAgICAgICAgICAgU0RMX2ZyZWUodGhpcyk7CiAgICAgICAgfQogICAgICAgIHJldHVybigwKTsKICAgIH0KICAgIFNETF9tZW1zZXQodGhpcy0+aGlkZGVuLCAwLCAoc2l6ZW9mICp0aGlzLT5oaWRkZW4pKTsKCiAgICAvKiBTZXQgdGhlIGZ1bmN0aW9uIHBvaW50ZXJzICovCiAgICB0aGlzLT5PcGVuQXVkaW8gICA9IE1pbnRfT3BlbkF1ZGlvOwogICAgdGhpcy0+Q2xvc2VBdWRpbyAgPSBNaW50X0Nsb3NlQXVkaW87CiAgICB0aGlzLT5Mb2NrQXVkaW8gICA9IE1pbnRfTG9ja0F1ZGlvOwogICAgdGhpcy0+VW5sb2NrQXVkaW8gPSBNaW50X1VubG9ja0F1ZGlvOwogICAgdGhpcy0+ZnJlZSAgICAgICAgPSBBdWRpb19EZWxldGVEZXZpY2U7CgogICAgcmV0dXJuIHRoaXM7Cn0KCkF1ZGlvQm9vdFN0cmFwIE1JTlRBVURJT19YQklPU19ib290c3RyYXAgPSB7CglNSU5UX0FVRElPX0RSSVZFUl9OQU1FLCAiTWlOVCBYQklPUyBhdWRpbyBkcml2ZXIiLAoJQXVkaW9fQXZhaWxhYmxlLCBBdWRpb19DcmVhdGVEZXZpY2UKfTsKCnN0YXRpYyB2b2lkIE1pbnRfTG9ja0F1ZGlvKF9USElTKQp7CgkvKiBTdG9wIHJlcGxheSAqLwoJQnVmZm9wZXIoMCk7Cn0KCnN0YXRpYyB2b2lkIE1pbnRfVW5sb2NrQXVkaW8oX1RISVMpCnsKCS8qIFJlc3RhcnQgcmVwbGF5ICovCglCdWZmb3BlcihTQl9QTEFfRU5BfFNCX1BMQV9SUFQpOwp9CgpzdGF0aWMgdm9pZCBNaW50X0Nsb3NlQXVkaW8oX1RISVMpCnsKCS8qIFN0b3AgcmVwbGF5ICovCglTRExfTWludEF1ZGlvX1dhaXRUaHJlYWQoKTsKCUJ1ZmZvcGVyKDApOwoKCWlmICghU0RMX01pbnRBdWRpb19taW50X3ByZXNlbnQpIHsKCQkvKiBVbmluc3RhbGwgaW50ZXJydXB0ICovCgkJSmRpc2ludChNRlBfRE1BU09VTkQpOwoJfQoKCS8qIFdhaXQgaWYgY3VycmVudGx5IHBsYXlpbmcgc291bmQgKi8KCXdoaWxlIChTRExfTWludEF1ZGlvX211dGV4ICE9IDApIHsKCX0KCgkvKiBDbGVhciBidWZmZXJzICovCglpZiAoU0RMX01pbnRBdWRpb19hdWRpb2J1ZlswXSkgewoJCU1mcmVlKFNETF9NaW50QXVkaW9fYXVkaW9idWZbMF0pOwoJCVNETF9NaW50QXVkaW9fYXVkaW9idWZbMF0gPSBTRExfTWludEF1ZGlvX2F1ZGlvYnVmWzFdID0gTlVMTDsKCX0KCgkvKiBVbmxvY2sgc291bmQgc3lzdGVtICovCglVbmxvY2tzbmQoKTsKfQoKLyogRmFsY29uIFhCSU9TIGltcGxlbWVudGF0aW9uIG9mIERldmNvbm5lY3QoKSBpcyBidWdneSB3aXRoIGV4dGVybmFsIGNsb2NrICovCnN0YXRpYyB2b2lkIERldmNvbm5lY3QyKGludCBzcmMsIGludCBkc3QsIGludCBzY2xrLCBpbnQgcHJlKQp7CQkKCXN0YXRpYyBjb25zdCB1bnNpZ25lZCBzaG9ydCBNQVNLMVszXSA9IHsgMCwgMHg2MDAwLCAwIH07CglzdGF0aWMgY29uc3QgdW5zaWduZWQgc2hvcnQgTUFTSzJbNF0gPSB7IDB4RkZGMCwgMHhGRjhGLCAweEYwRkYsIDB4MEZGRiB9OwoJc3RhdGljIGNvbnN0IHVuc2lnbmVkIHNob3J0IElOREVYMVs0XSA9IHsgIDEsIDMsIDUsIDcgfTsKCXN0YXRpYyBjb25zdCB1bnNpZ25lZCBzaG9ydCBJTkRFWDJbNF0gPSB7ICAwLCAyLCA0LCA2IH07Cgl1bnNpZ25lZCBzaG9ydCBzeW5jX2RpdixkZXZfY3RybCxkZXN0X2N0cmw7Cgl2b2lkICpvbGRzdGFjazsKCglpZiAoZHN0PT0wKSB7CgkJcmV0dXJuOwoJfQoKCW9sZHN0YWNrPSh2b2lkICopU3VwZXIoMCk7CgoJZGV2X2N0cmwgPSBETUFBVURJT19JTy5kZXZfY3RybDsKCWRlc3RfY3RybCA9IERNQUFVRElPX0lPLmRlc3RfY3RybDsKCWRldl9jdHJsICY9IE1BU0syW3NyY107CgoJaWYgKHNyYz09QURDKSB7CgkJZGV2X2N0cmwgfD0gTUFTSzFbc2Nsa107Cgl9IGVsc2UgewoJCWRldl9jdHJsIHw9IChJTkRFWDFbc2Nsa10gPDwgKHNyYzw8NCkpOwoJfQoKCWlmIChkc3QgJiBETUFSRUMpIHsJCQoJCWRlc3RfY3RybCAmPSAweEZGRjA7CgkJZGVzdF9jdHJsIHw9IElOREVYMVtzcmNdOwoJfQoKCWlmIChkc3QgJiBEU1BSRUNWKSB7CQkKCQlkZXN0X2N0cmwgJj0gMHhGRjhGOwoJCWRlc3RfY3RybCB8PSAoSU5ERVgxW3NyY108PDQpOyAKCX0KCglpZiAoZHN0ICYgRVhUT1VUKSB7CQkKCQlkZXN0X2N0cmwgJj0gMHhGMEZGOwoJCWRlc3RfY3RybCB8PSAoSU5ERVgxW3NyY108PDgpOyAKCX0KCglpZiAoZHN0ICYgREFDKSB7CQkKCQlkZXZfY3RybCAmPSAweDBGRkY7CgkJZGV2X2N0cmwgfD0gTUFTSzFbc2Nsa107IAoJCWRlc3RfY3RybCAmPSAgMHgwRkZGOwoJCWRlc3RfY3RybCB8PSAoSU5ERVgyW3NyY108PDEyKTsgCgl9CgoJc3luY19kaXYgPSBETUFBVURJT19JTy5zeW5jX2RpdjsKCWlmIChzY2xrPT1DTEtFWFQpIHsKCQlwcmU8PD04OwoJCXN5bmNfZGl2ICY9IDB4RjBGRjsKCX0gZWxzZSB7CgkJc3luY19kaXYgJj0gMHhGRkYwOwoJfQoJc3luY19kaXYgfD0gcHJlOwoKCURNQUFVRElPX0lPLmRldl9jdHJsID0gZGV2X2N0cmw7CglETUFBVURJT19JTy5kZXN0X2N0cmwgPSBkZXN0X2N0cmw7CglETUFBVURJT19JTy5zeW5jX2RpdiA9IHN5bmNfZGl2OwoKCVN1cGVyVG9Vc2VyKG9sZHN0YWNrKTsKfQoKc3RhdGljIHZvaWQgTWludF9DaGVja0V4dGVybmFsQ2xvY2soX1RISVMpCnsKI2RlZmluZSBTSVpFX0JVRl9DTE9DS19NRUFTVVJFICg0NDEwMC8xMCkKCgljaGFyICpidWZmZXI7CglpbnQgaSwgajsKCgkvKiBEU1AgcHJlc2VudCB3aXRoIGl0cyBHUElPIHBvcnQgPyAqLwoJaWYgKChjb29raWVfc25kICYgU05EX0RTUCk9PTApIHsKCQlyZXR1cm47Cgl9CgoJYnVmZmVyID0gQXRhcmlfU3lzTWFsbG9jKFNJWkVfQlVGX0NMT0NLX01FQVNVUkUsIE1YX1NUUkFNKTsKCWlmIChidWZmZXI9PU5VTEwpIHsKCQlERUJVR19QUklOVCgoREVCVUdfTkFNRSAiTm90IGVub3VnaCBtZW1vcnkgZm9yIHRoZSBtZWFzdXJlXG4iKSk7CgkJcmV0dXJuOwoJfQoJU0RMX21lbXNldChidWZmZXIsIDAsIFNJWkVfQlVGX0NMT0NLX01FQVNVUkUpOwoKCUJ1ZmZvcGVyKDApOwoJU2V0dHJhY2tzKDAsMCk7CglTZXRtb250cmFja3MoMCk7CglTZXRtb2RlKE1PTk84KTsKCUpkaXNpbnQoTUZQX1RJTUVSQSk7CgoJZm9yIChpPTA7IGk8MjsgaSsrKSB7CgkJR3BpbyhHUElPX1NFVCw3KTsgICAgICAvKiBEU1AgcG9ydCBncGlvIG91dHB1dHMgKi8KCQlHcGlvKEdQSU9fV1JJVEUsMitpKTsgIC8qIDIyLjU3OTIvMjQuNTc2IE1IeiBmb3IgNDQuMS80OEtIeiAqLwoJCURldmNvbm5lY3QyKERNQVBMQVksIERBQywgQ0xLRVhULCBDTEs1MEspOyAgLyogTWF0cml4IGFuZCBjbG9jayBzb3VyY2UgKi8KCQlTZXRidWZmZXIoMCwgYnVmZmVyLCBidWZmZXIgKyBTSVpFX0JVRl9DTE9DS19NRUFTVVJFKTsJCSAgICAgICAgICAgLyogU2V0IGJ1ZmZlciAqLwoJCVhidGltZXIoWEJfVElNRVJBLCA1LCAzOCwgU0RMX01pbnRBdWRpb19YYmlvc0ludGVycnVwdE1lYXN1cmVDbG9jayk7IC8qIGRlbGF5IG1vZGUgdGltZXIgQSwgcHJlZGl2IC82NCwgMUtIeiAqLwoJCUplbmFiaW50KE1GUF9USU1FUkEpOwoJCVNETF9NaW50QXVkaW9fY2xvY2t0aWNzID0gMDsKCQlCdWZmb3BlcihTQl9QTEFfRU5BKTsKCQl1c2xlZXAoMTEwMDAwKTsKCgkJaWYoKEJ1ZmZvcGVyKC0xKSAmIDEpPT0wKSB7CgkJCWlmIChTRExfTWludEF1ZGlvX2Nsb2NrdGljcykgewoJCQkJdW5zaWduZWQgbG9uZyBraHo7CgoJCQkJa2h6ID0gKChTSVpFX0JVRl9DTE9DS19NRUFTVVJFL1NETF9NaW50QXVkaW9fY2xvY2t0aWNzKSArMSkgJiAweEZGRkZGRkZFOwoJCQkJREVCVUdfUFJJTlQoKERFQlVHX05BTUUgIm1lYXN1cmUgJWQ6IGZyZXE9JWx1IEtIelxuIiwgaSsxLCBraHopKTsKCgkJCQlpZihraHo9PTQ0KSB7CgkJCQkJZm9yIChqPTE7IGo8NDsgaisrKSB7CgkJCQkJCVNETF9NaW50QXVkaW9fQWRkRnJlcXVlbmN5KHRoaXMsIE1BU1RFUkNMT0NLXzQ0Sy8oTUFTVEVSUFJFRElWX0ZBTENPTiooMTw8aikpLCBNQVNURVJDTE9DS180NEssICgxPDxqKS0xLCAyK2kpOwoJCQkJCX0KCQkJCX0gZWxzZSBpZiAoa2h6PT00OCkgewoJCQkJCWZvciAoaj0xOyBqPDQ7IGorKykgewoJCQkJCQlTRExfTWludEF1ZGlvX0FkZEZyZXF1ZW5jeSh0aGlzLCBNQVNURVJDTE9DS180OEsvKE1BU1RFUlBSRURJVl9GQUxDT04qKDE8PGopKSwgTUFTVEVSQ0xPQ0tfNDhLLCAoMTw8aiktMSwgMitpKTsKCQkJCQl9CgkJCQl9CgkJCX0gZWxzZSB7CgkJCQlERUJVR19QUklOVCgoREVCVUdfTkFNRSAiTm8gbWVhc3VyZVxuIikpOwoJCQl9CgkJfSBlbHNlIHsKCQkJREVCVUdfUFJJTlQoKERFQlVHX05BTUUgIk5vIFNETUEgY2xvY2tcbiIpKTsKCQl9CgoJCUJ1ZmZvcGVyKDApOyAgICAgICAgICAgICAvKiBzdG9wICovCgkJSmRpc2ludChNRlBfVElNRVJBKTsgICAgIC8qIFVuaW5zdGFsbCBpbnRlcnJ1cHQgKi8KCX0KCglNZnJlZShidWZmZXIpOwp9CgpzdGF0aWMgaW50IE1pbnRfQ2hlY2tBdWRpbyhfVEhJUywgU0RMX0F1ZGlvU3BlYyAqc3BlYykKewoJaW50IGk7CgoJREVCVUdfUFJJTlQoKERFQlVHX05BTUUgImFza2VkOiAlZCBiaXRzLCAiLHNwZWMtPmZvcm1hdCAmIDB4MDBmZikpOwoJREVCVUdfUFJJTlQoKCJzaWduZWQ9JWQsICIsICgoc3BlYy0+Zm9ybWF0ICYgMHg4MDAwKSE9MCkpKTsKCURFQlVHX1BSSU5UKCgiYmlnIGVuZGlhbj0lZCwgIiwgKChzcGVjLT5mb3JtYXQgJiAweDEwMDApIT0wKSkpOwoJREVCVUdfUFJJTlQoKCJjaGFubmVscz0lZCwgIiwgc3BlYy0+Y2hhbm5lbHMpKTsKCURFQlVHX1BSSU5UKCgiZnJlcT0lZFxuIiwgc3BlYy0+ZnJlcSkpOwoKICAgIGlmIChzcGVjLT5jaGFubmVscyA+IDIpIHsKICAgICAgICBzcGVjLT5jaGFubmVscyA9IDI7ICAvKiBubyBtb3JlIHRoYW4gc3RlcmVvISAqLwogICAgfQoKCXNwZWMtPmZvcm1hdCB8PSAweDgwMDA7CS8qIEF1ZGlvIGlzIGFsd2F5cyBzaWduZWQgKi8KCWlmICgoc3BlYy0+Zm9ybWF0ICYgMHgwMGZmKT09MTYpIHsKCQlzcGVjLT5mb3JtYXQgfD0gMHgxMDAwOwkvKiBBdWRpbyBpcyBhbHdheXMgYmlnIGVuZGlhbiAqLwoJCXNwZWMtPmNoYW5uZWxzPTI7CS8qIDE2IGJpdHMgYWx3YXlzIHN0ZXJlbyAqLwoJfQoKCU1JTlRBVURJT19mcmVxY291bnQ9MDsKCgkvKiBBZGQgZXh0ZXJuYWwgY2xvY2tzIGlmIHByZXNlbnQgKi8KCU1pbnRfQ2hlY2tFeHRlcm5hbENsb2NrKHRoaXMpOwoKCS8qIFN0YW5kYXJkIGNsb2NrcyAqLwoJZm9yIChpPTE7aTwxMjtpKyspIHsKCQkvKiBSZW1vdmUgdW51c2FibGUgRmFsY29uIGNvZGVjIHByZWRpdmlzb3JzICovCgkJaWYgKChpPT02KSB8fCAoaT09OCkgfHwgKGk9PTEwKSkgewoJCQljb250aW51ZTsKCQl9CgkJU0RMX01pbnRBdWRpb19BZGRGcmVxdWVuY3kodGhpcywgTUFTVEVSQ0xPQ0tfRkFMQ09OMS8oTUFTVEVSUFJFRElWX0ZBTENPTiooaSsxKSksIE1BU1RFUkNMT0NLX0ZBTENPTjEsIGksIC0xKTsKCX0KCiNpZiAxCglmb3IgKGk9MDsgaTxNSU5UQVVESU9fZnJlcWNvdW50OyBpKyspIHsKCQlERUJVR19QUklOVCgoREVCVUdfTkFNRSAiZnJlcSAlZDogJWx1IEh6LCBjbG9jayAlbHUsIHByZWRpdiAlZFxuIiwKCQkJaSwgTUlOVEFVRElPX2ZyZXF1ZW5jaWVzW2ldLmZyZXF1ZW5jeSwgTUlOVEFVRElPX2ZyZXF1ZW5jaWVzW2ldLm1hc3RlcmNsb2NrLAoJCQlNSU5UQVVESU9fZnJlcXVlbmNpZXNbaV0ucHJlZGl2aXNvcgoJCSkpOwoJfQojZW5kaWYKCglNSU5UQVVESU9fbnVtZnJlcT1TRExfTWludEF1ZGlvX1NlYXJjaEZyZXF1ZW5jeSh0aGlzLCBzcGVjLT5mcmVxKTsKCXNwZWMtPmZyZXE9TUlOVEFVRElPX2ZyZXF1ZW5jaWVzW01JTlRBVURJT19udW1mcmVxXS5mcmVxdWVuY3k7CgoJREVCVUdfUFJJTlQoKERFQlVHX05BTUUgIm9idGFpbmVkOiAlZCBiaXRzLCAiLHNwZWMtPmZvcm1hdCAmIDB4MDBmZikpOwoJREVCVUdfUFJJTlQoKCJzaWduZWQ9JWQsICIsICgoc3BlYy0+Zm9ybWF0ICYgMHg4MDAwKSE9MCkpKTsKCURFQlVHX1BSSU5UKCgiYmlnIGVuZGlhbj0lZCwgIiwgKChzcGVjLT5mb3JtYXQgJiAweDEwMDApIT0wKSkpOwoJREVCVUdfUFJJTlQoKCJjaGFubmVscz0lZCwgIiwgc3BlYy0+Y2hhbm5lbHMpKTsKCURFQlVHX1BSSU5UKCgiZnJlcT0lZFxuIiwgc3BlYy0+ZnJlcSkpOwoKCXJldHVybiAwOwp9CgpzdGF0aWMgdm9pZCBNaW50X0luaXRBdWRpbyhfVEhJUywgU0RMX0F1ZGlvU3BlYyAqc3BlYykKewoJaW50IGNoYW5uZWxzX21vZGUsIHByZWRpdjsKCXZvaWQgKmJ1ZmZlcjsKCgkvKiBTdG9wIGN1cnJlbnRseSBwbGF5aW5nIHNvdW5kICovCglTRExfTWludEF1ZGlvX3F1aXRfdGhyZWFkID0gU0RMX0ZBTFNFOwoJU0RMX01pbnRBdWRpb190aHJlYWRfZmluaXNoZWQgPSBTRExfVFJVRTsKCVNETF9NaW50QXVkaW9fV2FpdFRocmVhZCgpOwoJQnVmZm9wZXIoMCk7CgoJLyogU2V0IHJlcGxheSB0cmFja3MgKi8KCVNldHRyYWNrcygwLDApOwoJU2V0bW9udHJhY2tzKDApOwoKCS8qIFNlbGVjdCByZXBsYXkgZm9ybWF0ICovCgljaGFubmVsc19tb2RlPVNURVJFTzE2OwoJc3dpdGNoIChzcGVjLT5mb3JtYXQgJiAweGZmKSB7CgkJY2FzZSA4OgoJCQlpZiAoc3BlYy0+Y2hhbm5lbHM9PTIpIHsKCQkJCWNoYW5uZWxzX21vZGU9U1RFUkVPODsKCQkJfSBlbHNlIHsKCQkJCWNoYW5uZWxzX21vZGU9TU9OTzg7CgkJCX0KCQkJYnJlYWs7Cgl9CglpZiAoU2V0bW9kZShjaGFubmVsc19tb2RlKTwwKSB7CgkJREVCVUdfUFJJTlQoKERFQlVHX05BTUUgIlNldG1vZGUoKSBmYWlsZWRcbiIpKTsKCX0KCglwcmVkaXYgPSBNSU5UQVVESU9fZnJlcXVlbmNpZXNbTUlOVEFVRElPX251bWZyZXFdLnByZWRpdmlzb3I7CglpZiAoTUlOVEFVRElPX2ZyZXF1ZW5jaWVzW01JTlRBVURJT19udW1mcmVxXS5ncGlvX2JpdHMgIT0gLTEpIHsKCQlHcGlvKEdQSU9fU0VULDcpOwkJLyogRFNQIHBvcnQgZ3BpbyBvdXRwdXRzICovCgkJR3BpbyhHUElPX1dSSVRFLCBNSU5UQVVESU9fZnJlcXVlbmNpZXNbTUlOVEFVRElPX251bWZyZXFdLmdwaW9fYml0cyk7CgkJRGV2Y29ubmVjdDIoRE1BUExBWSwgREFDfEVYVE9VVCwgQ0xLRVhULCBwcmVkaXYpOwoJfSBlbHNlIHsKCQlEZXZjb25uZWN0MihETUFQTEFZLCBEQUMsIENMSzI1TSwgcHJlZGl2KTsKCX0KCgkvKiBTZXQgYnVmZmVyICovCglidWZmZXIgPSBTRExfTWludEF1ZGlvX2F1ZGlvYnVmW1NETF9NaW50QXVkaW9fbnVtYnVmXTsKCWlmIChTZXRidWZmZXIoMCwgYnVmZmVyLCBidWZmZXIgKyBzcGVjLT5zaXplKTwwKSB7CgkJREVCVUdfUFJJTlQoKERFQlVHX05BTUUgIlNldGJ1ZmZlcigpIGZhaWxlZFxuIikpOwoJfQoJCglpZiAoU0RMX01pbnRBdWRpb19taW50X3ByZXNlbnQpIHsKCQlTRExfTWludEF1ZGlvX3RocmVhZF9waWQgPSB0Zm9yayhTRExfTWludEF1ZGlvX1RocmVhZCwgMCk7Cgl9IGVsc2UgewoJCS8qIEluc3RhbGwgaW50ZXJydXB0ICovCgkJSmRpc2ludChNRlBfRE1BU09VTkQpOwoJCS8qWGJ0aW1lcihYQl9USU1FUkEsIDgsIDEsIFNETF9NaW50QXVkaW9fWGJpb3NJbnRlcnJ1cHQpOyovCgkJWGJ0aW1lcihYQl9USU1FUkEsIDgsIDEsIFNETF9NaW50QXVkaW9fRG1hOEludGVycnVwdCk7CgkJSmVuYWJpbnQoTUZQX0RNQVNPVU5EKTsKCgkJaWYgKFNldGludGVycnVwdChTSV9USU1FUkEsIFNJX1BMQVkpPDApIHsKCQkJREVCVUdfUFJJTlQoKERFQlVHX05BTUUgIlNldGludGVycnVwdCgpIGZhaWxlZFxuIikpOwoJCX0KCX0KCgkvKiBHbyAqLwoJQnVmZm9wZXIoU0JfUExBX0VOQXxTQl9QTEFfUlBUKTsKCURFQlVHX1BSSU5UKChERUJVR19OQU1FICJoYXJkd2FyZSBpbml0aWFsaXplZFxuIikpOwp9CgpzdGF0aWMgaW50IE1pbnRfT3BlbkF1ZGlvKF9USElTLCBTRExfQXVkaW9TcGVjICpzcGVjKQp7CgkvKiBMb2NrIHNvdW5kIHN5c3RlbSAqLwoJaWYgKExvY2tzbmQoKSE9MSkgewogICAJICAgIFNETF9TZXRFcnJvcigiTWludF9PcGVuQXVkaW86IEF1ZGlvIHN5c3RlbSBhbHJlYWR5IGluIHVzZSIpOwogICAgICAgIHJldHVybigtMSk7Cgl9CgoJU0RMX01pbnRBdWRpb19kZXZpY2UgPSB0aGlzOwoKCS8qIENoZWNrIGF1ZGlvIGNhcGFiaWxpdGllcyAqLwoJaWYgKE1pbnRfQ2hlY2tBdWRpbyh0aGlzLCBzcGVjKT09LTEpIHsKCQlyZXR1cm4gLTE7Cgl9CgoJU0RMX0NhbGN1bGF0ZUF1ZGlvU3BlYyhzcGVjKTsKCgkvKiBBbGxvY2F0ZSBtZW1vcnkgZm9yIGF1ZGlvIGJ1ZmZlcnMgaW4gRE1BLWFibGUgUkFNICovCglERUJVR19QUklOVCgoREVCVUdfTkFNRSAiYnVmZmVyIHNpemU9JWRcbiIsIHNwZWMtPnNpemUpKTsKCglTRExfTWludEF1ZGlvX2F1ZGlvYnVmWzBdID0gQXRhcmlfU3lzTWFsbG9jKHNwZWMtPnNpemUgKjIsIE1YX1NUUkFNKTsKCWlmIChTRExfTWludEF1ZGlvX2F1ZGlvYnVmWzBdPT1OVUxMKSB7CgkJU0RMX1NldEVycm9yKCJNSU5UX09wZW5BdWRpbzogTm90IGVub3VnaCBtZW1vcnkgZm9yIGF1ZGlvIGJ1ZmZlciIpOwoJCXJldHVybiAoLTEpOwoJfQoJU0RMX01pbnRBdWRpb19hdWRpb2J1ZlsxXSA9IFNETF9NaW50QXVkaW9fYXVkaW9idWZbMF0gKyBzcGVjLT5zaXplIDsKCVNETF9NaW50QXVkaW9fbnVtYnVmPTA7CglTRExfbWVtc2V0KFNETF9NaW50QXVkaW9fYXVkaW9idWZbMF0sIHNwZWMtPnNpbGVuY2UsIHNwZWMtPnNpemUgKjIpOwoJU0RMX01pbnRBdWRpb19hdWRpb3NpemUgPSBzcGVjLT5zaXplOwoJU0RMX01pbnRBdWRpb19tdXRleCA9IDA7CgoJREVCVUdfUFJJTlQoKERFQlVHX05BTUUgImJ1ZmZlciAwIGF0IDB4JTA4eFxuIiwgU0RMX01pbnRBdWRpb19hdWRpb2J1ZlswXSkpOwoJREVCVUdfUFJJTlQoKERFQlVHX05BTUUgImJ1ZmZlciAxIGF0IDB4JTA4eFxuIiwgU0RMX01pbnRBdWRpb19hdWRpb2J1ZlsxXSkpOwoKCVNETF9NaW50QXVkaW9fQ2hlY2tGcHUoKTsKCgkvKiBTZXR1cCBhdWRpbyBoYXJkd2FyZSAqLwoJTWludF9Jbml0QXVkaW8odGhpcywgc3BlYyk7CgogICAgcmV0dXJuKDEpOwkvKiBXZSBkb24ndCB1c2UgU0RMIHRocmVhZGVkIGF1ZGlvICovCn0K