LyoKICogKEMpIENvcHlyaWdodCAyMDAyLCAyMDAzCiAqIERhbmllbCBFbmdzdHL2bSwgT21pY3JvbiBDZXRpIEFCLCBkYW5pZWxAb21pY3Jvbi5zZQogKgogKiAoQykgQ29weXJpZ2h0IDIwMDIKICogU3lzZ28gUmVhbC1UaW1lIFNvbHV0aW9ucywgR21iSCA8d3d3LmVsaW5vcy5jb20+CiAqIEFsZXggWnVlcGtlIDxhenVAc3lzZ28uZGU+CiAqCiAqIFNlZSBmaWxlIENSRURJVFMgZm9yIGxpc3Qgb2YgcGVvcGxlIHdobyBjb250cmlidXRlZCB0byB0aGlzCiAqIHByb2plY3QuCiAqCiAqIFRoaXMgcHJvZ3JhbSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IKICogbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgYXMKICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlciB2ZXJzaW9uIDIgb2YKICogdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uCiAqCiAqIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLAogKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZgogKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlCiAqIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIGFsb25nIHdpdGggdGhpcyBwcm9ncmFtOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlCiAqIEZvdW5kYXRpb24sIEluYy4sIDU5IFRlbXBsZSBQbGFjZSwgU3VpdGUgMzMwLCBCb3N0b24sCiAqIE1BIDAyMTExLTEzMDcgVVNBCiAqLwoKI2luY2x1ZGUgPGNvbW1vbi5oPgojaW5jbHVkZSA8YXNtL2lvLmg+CiNpbmNsdWRlIDxwY2kuaD4KI2luY2x1ZGUgPGFzbS9pYy9zYzUyMC5oPgoKI2RlZmluZSBQUk9CRV9CVUZGRVJfU0laRSAxMDI0CnN0YXRpYyB1bnNpZ25lZCBjaGFyIGJ1ZmZlcltQUk9CRV9CVUZGRVJfU0laRV07CgojZGVmaW5lIFNDNTIwX01BWF9GTEFTSF9CQU5LUyAgMQojZGVmaW5lIFNDNTIwX0ZMQVNIX0JBTkswX0JBU0UgMHgzODAwMDAwMCAgLyogQk9PVENTICovCiNkZWZpbmUgU0M1MjBfRkxBU0hfQkFOS1NJWkUgICAweDgwMDAwMDAKCiNkZWZpbmUgQTI5TFY2NDFESF9TSVpFICAgICAgICAweDgwMDAwMAojZGVmaW5lIEEyOUxWNjQxREhfU0VDVE9SUyAgICAgMTI4CgojZGVmaW5lIEEyOUxWNjQxTUhfU0laRSAgICAgICAgMHg4MDAwMDAKI2RlZmluZSBBMjlMVjY0MU1IX1NFQ1RPUlMgICAgIDEyOAoKI2RlZmluZSBJMjhGMzIwSjNBX1NJWkUgICAgICAgIDB4NDAwMDAwCiNkZWZpbmUgSTI4RjMyMEozQV9TRUNUT1JTICAgICAzMgoKI2RlZmluZSBJMjhGNjQwSjNBX1NJWkUgICAgICAgIDB4ODAwMDAwCiNkZWZpbmUgSTI4RjY0MEozQV9TRUNUT1JTICAgICA2NAoKI2RlZmluZSBJMjhGMTI4SjNBX1NJWkUgICAgICAgIDB4MTAwMDAwMAojZGVmaW5lIEkyOEYxMjhKM0FfU0VDVE9SUyAgICAgMTI4CgpmbGFzaF9pbmZvX3QgICAgZmxhc2hfaW5mb1tTQzUyMF9NQVhfRkxBU0hfQkFOS1NdOwoKI2RlZmluZSBSRUFEWSAxCiNkZWZpbmUgRVJSICAgMgojZGVmaW5lIFRNTyAgIDQKCi8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICovCgpzdGF0aWMgdTMyIF9wcm9iZV9mbGFzaCh1MzIgYWRkciwgdTMyIGJ3LCBpbnQgaWwpCnsKCXUzMiByZXN1bHQ9MDsKCgkvKiBGaXJzdCBkbyBhbiB1bmxvY2sgY3ljbGUgZm9yIHRoZSBiZW5lZml0IG9mCgkgKiBkZXZpY2VzIHRoYXQgbmVlZCBpdCAqLwoKCXN3aXRjaCAoYncpIHsKCgljYXNlIDE6CgkJKih2b2xhdGlsZSB1OCopKGFkZHIrMHg1NTU1KSA9IDB4YWE7CgkJKih2b2xhdGlsZSB1OCopKGFkZHIrMHgyYWFhKSA9IDB4NTU7CgkJKih2b2xhdGlsZSB1OCopKGFkZHIrMHg1NTU1KSA9IDB4OTA7CgoJCS8qIFJlYWQgdmVuZG9yICovCgkJcmVzdWx0ID0gKih2b2xhdGlsZSB1OCopYWRkcjsKCQlyZXN1bHQgPDw9IDE2OwoKCQkvKiBSZWFkIGRldmljZSAqLwoJCXJlc3VsdCB8PSAqKHZvbGF0aWxlIHU4KikoYWRkcisyKTsKCgkJLyogUmV0dXJuIGRldmljZSB0byBkYXRhIG1vZGUgKi8KCQkqKHZvbGF0aWxlIHU4KilhZGRyID0gMHhmZjsKCQkqKHZvbGF0aWxlIHU4KikoYWRkcisweDU1NTUpLCAweGYwOwoJCWJyZWFrOwoKCWNhc2UgMjoKCQkqKHZvbGF0aWxlIHUxNiopKGFkZHIrMHhhYWFhKSA9IDB4YWFhYTsKCQkqKHZvbGF0aWxlIHUxNiopKGFkZHIrMHg1NTU0KSA9IDB4NTU1NTsKCgkJLyogSXNzdWUgaWRlbnRpZmljYXRpb24gY29tbWFuZCAqLwoJCWlmIChpbCA9PSAyKSB7CgkJCSoodm9sYXRpbGUgdTE2KikoYWRkcisweGFhYWEpID0gMHg5MDkwOwoKCQkJLyogUmVhZCB2ZW5kb3IgKi8KCQkJcmVzdWx0ID0gKih2b2xhdGlsZSB1OCopYWRkcjsKCQkJcmVzdWx0IDw8PSAxNjsKCgkJCS8qIFJlYWQgZGV2aWNlICovCgkJCXJlc3VsdCB8PSAqKHZvbGF0aWxlIHU4KikoYWRkcisyKTsKCgkJCS8qIFJldHVybiBkZXZpY2UgdG8gZGF0YSBtb2RlICovCgkJCSoodm9sYXRpbGUgdTE2KilhZGRyID0gIDB4ZmZmZjsKCQkJKih2b2xhdGlsZSB1MTYqKShhZGRyKzB4YWFhYSksIDB4ZjBmMDsKCgkJfSBlbHNlIHsKCQkJKih2b2xhdGlsZSB1OCopKGFkZHIrMHhhYWFhKSA9IDB4OTA7CgkJCS8qIFJlYWQgdmVuZG9yICovCgkJCXJlc3VsdCA9ICoodm9sYXRpbGUgdTE2KilhZGRyOwoJCQlyZXN1bHQgPDw9IDE2OwoKCQkJLyogUmVhZCBkZXZpY2UgKi8KCQkJcmVzdWx0IHw9ICoodm9sYXRpbGUgdTE2KikoYWRkcisyKTsKCgkJCS8qIFJldHVybiBkZXZpY2UgdG8gZGF0YSBtb2RlICovCgkJCSoodm9sYXRpbGUgdTgqKWFkZHIgPSAweGZmOwoJCQkqKHZvbGF0aWxlIHU4KikoYWRkcisweGFhYWEpLCAweGYwOwoJCX0KCgkJYnJlYWs7CgoJIGNhc2UgNDoKCQkqKHZvbGF0aWxlIHUzMiopKGFkZHIrMHg1NTU0KSA9IDB4YWFhYWFhYWE7CgkJKih2b2xhdGlsZSB1MzIqKShhZGRyKzB4YWFhOCkgPSAweDU1NTU1NTU1OwoKCQlzd2l0Y2ggKGlsKSB7CgkJY2FzZSAxOgoJCQkvKiBJc3N1ZSBpZGVudGlmaWNhdGlvbiBjb21tYW5kICovCgkJCSoodm9sYXRpbGUgdTgqKShhZGRyKzB4NTU1NCkgPSAweDkwOwoKCQkJLyogUmVhZCB2ZW5kb3IgKi8KCQkJcmVzdWx0ID0gKih2b2xhdGlsZSB1MTYqKWFkZHI7CgkJCXJlc3VsdCA8PD0gMTY7CgoJCQkvKiBSZWFkIGRldmljZSAqLwoJCQlyZXN1bHQgfD0gKih2b2xhdGlsZSB1MTYqKShhZGRyKzQpOwoKCQkJLyogUmV0dXJuIGRldmljZSB0byBkYXRhIG1vZGUgKi8KCQkJKih2b2xhdGlsZSB1OCopYWRkciA9ICAweGZmOwoJCQkqKHZvbGF0aWxlIHU4KikoYWRkcisweDU1NTQpLCAweGYwOwoJCQlicmVhazsKCgkJY2FzZSAyOgoJCQkvKiBJc3N1ZSBpZGVudGlmaWNhdGlvbiBjb21tYW5kICovCgkJCSoodm9sYXRpbGUgdTMyKikoYWRkciArIDB4NTU1NCkgPSAweDAwOTAwMDkwOwoKCQkJLyogUmVhZCB2ZW5kb3IgKi8KCQkJcmVzdWx0ID0gKih2b2xhdGlsZSB1MTYqKWFkZHI7CgkJCXJlc3VsdCA8PD0gMTY7CgoJCQkvKiBSZWFkIGRldmljZSAqLwoJCQlyZXN1bHQgfD0gKih2b2xhdGlsZSB1MTYqKShhZGRyKzQpOwoKCQkJLyogUmV0dXJuIGRldmljZSB0byBkYXRhIG1vZGUgKi8KCQkJKih2b2xhdGlsZSB1MzIqKWFkZHIgPSAgMHgwMGZmMDBmZjsKCQkJKih2b2xhdGlsZSB1MzIqKShhZGRyKzB4NTU1NCksIDB4MDBmMDAwZjA7CgkJCWJyZWFrOwoKCQljYXNlIDQ6CgkJCS8qIElzc3VlIGlkZW50aWZpY2F0aW9uIGNvbW1hbmQgKi8KCQkJKih2b2xhdGlsZSB1MzIqKShhZGRyKzB4NTU1NCkgPSAweDkwOTA5MDkwOwoKCQkJLyogUmVhZCB2ZW5kb3IgKi8KCQkJcmVzdWx0ID0gKih2b2xhdGlsZSB1OCopYWRkcjsKCQkJcmVzdWx0IDw8PSAxNjsKCgkJCS8qIFJlYWQgZGV2aWNlICovCgkJCXJlc3VsdCB8PSAqKHZvbGF0aWxlIHU4KikoYWRkcis0KTsKCgkJCS8qIFJldHVybiBkZXZpY2UgdG8gZGF0YSBtb2RlICovCgkJCSoodm9sYXRpbGUgdTMyKilhZGRyID0gIDB4ZmZmZmZmZmY7CgkJCSoodm9sYXRpbGUgdTMyKikoYWRkcisweDU1NTQpLCAweGYwZjBmMGYwOwoJCQlicmVhazsKCQl9CgkJYnJlYWs7Cgl9CgoJcmV0dXJuIHJlc3VsdDsKfQoKZXh0ZXJuIGludCBfcHJvYmVfZmxhc2hfZW5kOwphc20gKCJfcHJvYmVfZmxhc2hfZW5kOlxuIgogICAgICIubG9uZyAwXG4iKTsKCnN0YXRpYyBpbnQgaWRlbnRpZnlfZmxhc2godW5zaWduZWQgYWRkcmVzcywgaW50IHdpZHRoKQp7CglpbnQgaXM7CglpbnQgZGV2aWNlOwoJaW50IHZlbmRvcjsKCWludCBzaXplOwoJdW5zaWduZWQgcmVzOwoKCXUzMiAoKl9wcm9iZV9mbGFzaF9wdHIpKHUzMiBhLCB1MzIgYncsIGludCBpbCk7CgoJc2l6ZSA9ICh1bnNpZ25lZCkmX3Byb2JlX2ZsYXNoX2VuZCAtICh1bnNpZ25lZClfcHJvYmVfZmxhc2g7CgoJaWYgKHNpemUgPiBQUk9CRV9CVUZGRVJfU0laRSkgewoJCXByaW50ZigiX3Byb2JlX2ZsYXNoKCkgcm91dGluZSB0b28gbGFyZ2UgKCVkKSAlcCAtICVwXG4iLAoJCSAgICAgICBzaXplLCAmX3Byb2JlX2ZsYXNoX2VuZCwgX3Byb2JlX2ZsYXNoKTsKCQlyZXR1cm4gMDsKCX0KCgltZW1jcHkoYnVmZmVyLCBfcHJvYmVfZmxhc2gsIHNpemUpOwoJX3Byb2JlX2ZsYXNoX3B0ciA9ICh2b2lkKilidWZmZXI7CgoJaXMgPSBkaXNhYmxlX2ludGVycnVwdHMoKTsKCXJlcyA9IF9wcm9iZV9mbGFzaF9wdHIoYWRkcmVzcywgd2lkdGgsIDEpOwoJaWYgKGlzKSB7CgkJZW5hYmxlX2ludGVycnVwdHMoKTsKCX0KCgl2ZW5kb3IgPSByZXMgPj4gMTY7CglkZXZpY2UgPSByZXMgJiAweGZmZmY7CgoJcmV0dXJuIHJlczsKfQoKdWxvbmcgZmxhc2hfaW5pdCh2b2lkKQp7CglpbnQgaSwgajsKCXVsb25nIHNpemUgPSAwOwoKCWZvciAoaSA9IDA7IGkgPCBTQzUyMF9NQVhfRkxBU0hfQkFOS1M7IGkrKykgewoJCXVuc2lnbmVkIGlkOwoJCXVsb25nIGZsYXNoYmFzZSA9IDA7CgkJaW50IHNlY3RzaXplID0gMDsKCgkJbWVtc2V0KGZsYXNoX2luZm9baV0ucHJvdGVjdCwgMCwgQ0ZHX01BWF9GTEFTSF9TRUNUKTsKCQlzd2l0Y2ggKGkpIHsKCQljYXNlIDA6CgkJCWZsYXNoYmFzZSA9IFNDNTIwX0ZMQVNIX0JBTkswX0JBU0U7CgkJCWJyZWFrOwoJCWRlZmF1bHQ6CgkJCXBhbmljKCJjb25maWd1cmVkIHRvbyBtYW55IGZsYXNoIGJhbmtzIVxuIik7CgkJfQoKCQlpZCA9IGlkZW50aWZ5X2ZsYXNoKGZsYXNoYmFzZSwgMik7CgkJc3dpdGNoIChpZCkgewoJCWNhc2UgMHgwMDAxMjJkNzoKCQkJLyogMjlMVjY0MURIICovCgkJCWZsYXNoX2luZm9baV0uZmxhc2hfaWQgPQoJCQkJKEFNRF9NQU5VRkFDVCAmIEZMQVNIX1ZFTkRNQVNLKSB8CgkJCQkoQU1EX0lEX0xWNjQwVSAmIEZMQVNIX1RZUEVNQVNLKTsKCgkJCWZsYXNoX2luZm9baV0uc2l6ZSA9IEEyOUxWNjQxREhfU0laRTsKCQkJZmxhc2hfaW5mb1tpXS5zZWN0b3JfY291bnQgPSBBMjlMVjY0MURIX1NFQ1RPUlM7CgkJCXNlY3RzaXplID0gQTI5TFY2NDFESF9TSVpFL0EyOUxWNjQxREhfU0VDVE9SUzsKCQkJcHJpbnRmKCJCYW5rICVkOiBBTUQgMjlMVjY0MURIXG4iLCBpKTsKCQkJYnJlYWs7CgoJCWNhc2UgMHgwMDAxMjI3RToKCQkJLyogMjlMVjY0MU1IICovCgkJCWZsYXNoX2luZm9baV0uZmxhc2hfaWQgPQoJCQkJKEFNRF9NQU5VRkFDVCAmIEZMQVNIX1ZFTkRNQVNLKSB8CgkJCQkoQU1EX0lEX0RMNjQwICYgRkxBU0hfVFlQRU1BU0spOwoKCQkJZmxhc2hfaW5mb1tpXS5zaXplID0gQTI5TFY2NDFNSF9TSVpFOwoJCQlmbGFzaF9pbmZvW2ldLnNlY3Rvcl9jb3VudCA9IEEyOUxWNjQxTUhfU0VDVE9SUzsKCQkJc2VjdHNpemUgPSBBMjlMVjY0MU1IX1NJWkUvQTI5TFY2NDFNSF9TRUNUT1JTOwoJCQlwcmludGYoIkJhbmsgJWQ6IEFNRCAyOUxWNjQxTUhcbiIsIGkpOwoJCQlicmVhazsKCgkJY2FzZSAweDAwODkwMDE2OgoJCQkvKiAyOEYzMjBKM0EgKi8KCQkJZmxhc2hfaW5mb1tpXS5mbGFzaF9pZCA9CgkJCQkoSU5URUxfTUFOVUZBQ1QgJiBGTEFTSF9WRU5ETUFTSykgfAoJCQkJKElOVEVMX0lEXzI4RjMyMEozQSAmIEZMQVNIX1RZUEVNQVNLKTsKCgkJCWZsYXNoX2luZm9baV0uc2l6ZSA9IEkyOEYzMjBKM0FfU0laRTsKCQkJZmxhc2hfaW5mb1tpXS5zZWN0b3JfY291bnQgPSBJMjhGMzIwSjNBX1NFQ1RPUlM7CgkJCXNlY3RzaXplID0gSTI4RjMyMEozQV9TSVpFL0kyOEYzMjBKM0FfU0VDVE9SUzsKCQkJcHJpbnRmKCJCYW5rICVkOiBJbnRlbCAyOEYzMjBKM0FcbiIsIGkpOwoJCQlicmVhazsKCgkJY2FzZSAweDAwODkwMDE3OgoJCQkvKiAyOEY2NDBKM0EgKi8KCQkJZmxhc2hfaW5mb1tpXS5mbGFzaF9pZCA9CgkJCQkoSU5URUxfTUFOVUZBQ1QgJiBGTEFTSF9WRU5ETUFTSykgfAoJCQkJKElOVEVMX0lEXzI4RjY0MEozQSAmIEZMQVNIX1RZUEVNQVNLKTsKCgkJCWZsYXNoX2luZm9baV0uc2l6ZSA9IEkyOEY2NDBKM0FfU0laRTsKCQkJZmxhc2hfaW5mb1tpXS5zZWN0b3JfY291bnQgPSBJMjhGNjQwSjNBX1NFQ1RPUlM7CgkJCXNlY3RzaXplID0gSTI4RjY0MEozQV9TSVpFL0kyOEY2NDBKM0FfU0VDVE9SUzsKCQkJcHJpbnRmKCJCYW5rICVkOiBJbnRlbCAyOEY2NDBKM0FcbiIsIGkpOwoJCQlicmVhazsKCgkJY2FzZSAweDAwODkwMDE4OgoJCQkvKiAyOEYxMjhKM0EgKi8KCQkJZmxhc2hfaW5mb1tpXS5mbGFzaF9pZCA9CgkJCQkoSU5URUxfTUFOVUZBQ1QgJiBGTEFTSF9WRU5ETUFTSykgfAoJCQkJKElOVEVMX0lEXzI4RjEyOEozQSAmIEZMQVNIX1RZUEVNQVNLKTsKCgkJCWZsYXNoX2luZm9baV0uc2l6ZSA9IEkyOEYxMjhKM0FfU0laRTsKCQkJZmxhc2hfaW5mb1tpXS5zZWN0b3JfY291bnQgPSBJMjhGMTI4SjNBX1NFQ1RPUlM7CgkJCXNlY3RzaXplID0gSTI4RjEyOEozQV9TSVpFL0kyOEYxMjhKM0FfU0VDVE9SUzsKCQkJcHJpbnRmKCJCYW5rICVkOiBJbnRlbCAyOEYxMjhKM0FcbiIsIGkpOwoJCQlicmVhazsKCgkJZGVmYXVsdDoKCQkJcHJpbnRmKCJCYW5rICVkIGhhdmUgdW5rbm93biBmbGFzaCAlMDh4XG4iLCBpLCBpZCk7CgkJCWZsYXNoX2luZm9baV0uZmxhc2hfaWQgPSBGTEFTSF9VTktOT1dOOwoJCQljb250aW51ZTsKCQl9CgoJCWZvciAoaiA9IDA7IGogPCBmbGFzaF9pbmZvW2ldLnNlY3Rvcl9jb3VudDsgaisrKSB7CgkJCWZsYXNoX2luZm9baV0uc3RhcnRbal0gPSBmbGFzaGJhc2UgKyBqICogc2VjdHNpemU7CgkJfQoJCXNpemUgKz0gZmxhc2hfaW5mb1tpXS5zaXplOwoKCQlmbGFzaF9wcm90ZWN0KEZMQUdfUFJPVEVDVF9DTEVBUiwKCQkJICAgICAgZmxhc2hfaW5mb1tpXS5zdGFydFswXSwKCQkJICAgICAgIGZsYXNoX2luZm9baV0uc3RhcnRbMF0gKyBmbGFzaF9pbmZvW2ldLnNpemUgLSAxLAoJCQkgICAgICAmZmxhc2hfaW5mb1tpXSk7Cgl9CgoJLyoKCSAqIFByb3RlY3QgbW9uaXRvciBhbmQgZW52aXJvbm1lbnQgc2VjdG9ycwoJICovCglmbGFzaF9wcm90ZWN0KEZMQUdfUFJPVEVDVF9TRVQsCgkJICAgICAgaTM4NmJvb3Rfc3RhcnQsCgkJICAgICAgaTM4NmJvb3RfZW5kLAoJCSAgICAgICZmbGFzaF9pbmZvWzBdKTsKI2lmZGVmIENGR19FTlZfQUREUgoJZmxhc2hfcHJvdGVjdChGTEFHX1BST1RFQ1RfU0VULAoJCSAgICAgIENGR19FTlZfQUREUiwKCQkgICAgICBDRkdfRU5WX0FERFIgKyBDRkdfRU5WX1NJWkUgLSAxLAoJCSAgICAgICZmbGFzaF9pbmZvWzBdKTsKI2VuZGlmCglyZXR1cm4gc2l6ZTsKfQoKLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogKi8Kdm9pZCBmbGFzaF9wcmludF9pbmZvKGZsYXNoX2luZm9fdCAqaW5mbykKewoJaW50IGk7CgoJc3dpdGNoIChpbmZvLT5mbGFzaF9pZCAmIEZMQVNIX1ZFTkRNQVNLKSB7CgljYXNlIChJTlRFTF9NQU5VRkFDVCAmIEZMQVNIX1ZFTkRNQVNLKToKCQlwcmludGYoIklOVEVMOiAiKTsKCQlzd2l0Y2ggKGluZm8tPmZsYXNoX2lkICYgRkxBU0hfVFlQRU1BU0spIHsKCQljYXNlIChJTlRFTF9JRF8yOEYzMjBKM0EgJiBGTEFTSF9UWVBFTUFTSyk6CgkJCXByaW50ZigiMXggSTI4RjMyMEozQSAoMzJNYml0KVxuIik7CgkJCWJyZWFrOwoJCWNhc2UgKElOVEVMX0lEXzI4RjY0MEozQSAmIEZMQVNIX1RZUEVNQVNLKToKCQkJcHJpbnRmKCIxeCBJMjhGNjQwSjNBICg2NE1iaXQpXG4iKTsKCQkJYnJlYWs7CgkJY2FzZSAoSU5URUxfSURfMjhGMTI4SjNBICYgRkxBU0hfVFlQRU1BU0spOgoJCQlwcmludGYoIjF4IEkyOEYxMjhKM0EgKDEyOE1iaXQpXG4iKTsKCQkJYnJlYWs7CgkJZGVmYXVsdDoKCQkJcHJpbnRmKCJVbmtub3duIENoaXAgVHlwZVxuIik7CgkJCWdvdG8gZG9uZTsKCQkJYnJlYWs7CgkJfQoKCQlicmVhazsKCgljYXNlIChBTURfTUFOVUZBQ1QgJiBGTEFTSF9WRU5ETUFTSyk6CgkJcHJpbnRmKCJBTUQ6ICAgIik7CgkJc3dpdGNoIChpbmZvLT5mbGFzaF9pZCAmIEZMQVNIX1RZUEVNQVNLKSB7CgkJY2FzZSAoQU1EX0lEX0xWNjQwVSAmIEZMQVNIX1RZUEVNQVNLKToKCQkJcHJpbnRmKCIxeCBBTUQyOUxWNjQxREggKDY0TWJpdClcbiIpOwoJCQlicmVhazsKCQljYXNlIChBTURfSURfREw2NDAgJiBGTEFTSF9UWVBFTUFTSyk6CgkJCXByaW50ZigiMXggQU1EMjlMVjY0MU1IICg2NE1iaXQpXG4iKTsKCQkJYnJlYWs7CgkJZGVmYXVsdDoKCQkJcHJpbnRmKCJVbmtub3duIENoaXAgVHlwZVxuIik7CgkJCWdvdG8gZG9uZTsKCQkJYnJlYWs7CgkJfQoKCQlicmVhazsKCWRlZmF1bHQ6CgkJcHJpbnRmKCJVbmtub3duIFZlbmRvciAiKTsKCQlicmVhazsKCX0KCglwcmludGYoIiAgU2l6ZTogJWxkIE1CIGluICVkIFNlY3RvcnNcbiIsCgkgICAgICAgaW5mby0+c2l6ZSA+PiAyMCwgaW5mby0+c2VjdG9yX2NvdW50KTsKCglwcmludGYoIiAgU2VjdG9yIFN0YXJ0IEFkZHJlc3NlczoiKTsKCWZvciAoaSA9IDA7IGkgPCBpbmZvLT5zZWN0b3JfY291bnQ7IGkrKykgewoJCWlmICgoaSAlIDUpID09IDApIHsKCQkJcHJpbnRmICgiXG4gICAiKTsKCQl9CgkJcHJpbnRmICgiICUwOGxYJXMiLCBpbmZvLT5zdGFydFtpXSwKCQkJaW5mby0+cHJvdGVjdFtpXSA/ICIgKFJPKSIgOiAiICAgICAiKTsKCX0KCXByaW50ZiAoIlxuIik7Cgpkb25lOgoJcmV0dXJuOwp9CgovKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAqLwoKc3RhdGljIHUzMiBfYW1kX2VyYXNlX2ZsYXNoKHUzMiBhZGRyLCB1MzIgc2VjdG9yKQp7Cgl1bnNpZ25lZCBlbGFwc2VkOwoKCS8qIElzc3VlIGVyYXNlICovCgkqKHZvbGF0aWxlIHUxNiopKGFkZHIgKyAweGFhYWEpID0gMHgwMEFBOwoJKih2b2xhdGlsZSB1MTYqKShhZGRyICsgMHg1NTU0KSA9IDB4MDA1NTsKCSoodm9sYXRpbGUgdTE2KikoYWRkciArIDB4YWFhYSkgPSAweDAwODA7CgkvKiBBbmQgb25lIHVubG9jayAqLwoJKih2b2xhdGlsZSB1MTYqKShhZGRyICsgMHhhYWFhKSA9IDB4MDBBQTsKCSoodm9sYXRpbGUgdTE2KikoYWRkciArIDB4NTU1NCkgPSAweDAwNTU7CgkvKiBTZWN0b3IgZXJhc2UgY29tbWFuZCBjb21lcyBsYXN0ICovCgkqKHZvbGF0aWxlIHUxNiopKGFkZHIgKyBzZWN0b3IpID0gMHgwMDMwOwoKCWVsYXBzZWQgPSAqKHZvbGF0aWxlIHUxNiopKDB4ZmZmZWYwMDArU0M1MjBfU1dUTVJNSUxMSSk7IC8qIGR1bW15IHJlYWQgKi8KCWVsYXBzZWQgPSAwOwoJd2hpbGUgKCgoKih2b2xhdGlsZSB1MTYqKShhZGRyICsgc2VjdG9yKSkgJiAweDAwODApICE9IDB4MDA4MCkgewoKCQllbGFwc2VkICs9ICoodm9sYXRpbGUgdTE2KikoMHhmZmZlZjAwMCtTQzUyMF9TV1RNUk1JTExJKTsKCQlpZiAoZWxhcHNlZCA+ICgoQ0ZHX0ZMQVNIX0VSQVNFX1RPVVQvQ0ZHX0haKSAqIDEwMDApKSB7CgkJCSoodm9sYXRpbGUgdTE2KikoYWRkcikgPSAweDAwZjA7CgkJCXJldHVybiAxOwoJCX0KCX0KCgkqKHZvbGF0aWxlIHUxNiopKGFkZHIpID0gMHgwMGYwOwoKCXJldHVybiAwOwp9CgpleHRlcm4gaW50IF9hbWRfZXJhc2VfZmxhc2hfZW5kOwphc20gKCJfYW1kX2VyYXNlX2ZsYXNoX2VuZDpcbiIKICAgICAiLmxvbmcgMFxuIik7CgovKiB0aGlzIG5lZWRzIHRvIGJlIGlubGluZWQsIHRoZSBTV1RNUk1NSUxMSSByZWdpc3RlciBpcyByZXNldCBieSBlYWNoIHJlYWQgKi8KI2RlZmluZSBfX3VkZWxheShkZWxheSkgXAp7CVwKCXVuc2lnbmVkIG1pY3JvOyBcCgl1bnNpZ25lZCBtaWxsaT0wOyBcCglcCgltaWNybyA9ICoodm9sYXRpbGUgdTE2KikoMHhmZmZlZjAwMCtTQzUyMF9TV1RNUk1JTExJKTsgXAoJIFwKCWZvciAoOzspIHsgXAoJCVwKCQltaWxsaSArPSAqKHZvbGF0aWxlIHUxNiopKDB4ZmZmZWYwMDArU0M1MjBfU1dUTVJNSUxMSSk7IFwKCQltaWNybyA9ICoodm9sYXRpbGUgdTE2KikoMHhmZmZlZjAwMCtTQzUyMF9TV1RNUk1JQ1JPKTsgXAoJCVwKCQlpZiAoKGRlbGF5KSA8PSAobWljcm8gKyAobWlsbGkgKiAxMDAwKSkpIHsgXAoJCQlicmVhazsgXAoJCX0gXAoJfSBcCn0gd2hpbGUgKDApCgpzdGF0aWMgdTMyIF9pbnRlbF9lcmFzZV9mbGFzaCh1MzIgYWRkciwgdTMyIHNlY3RvcikKewoJdW5zaWduZWQgZWxhcHNlZDsKCgkqKHZvbGF0aWxlIHUxNiopKGFkZHIgKyBzZWN0b3IpID0gMHgwMDUwOyAgIC8qIGNsZWFyIHN0YXR1cyByZWdpc3RlciAqLwoJKih2b2xhdGlsZSB1MTYqKShhZGRyICsgc2VjdG9yKSA9IDB4MDAyMDsgICAvKiBlcmFzZSBzZXR1cCAqLwoJKih2b2xhdGlsZSB1MTYqKShhZGRyICsgc2VjdG9yKSA9IDB4MDBEMDsgICAvKiBlcmFzZSBjb25maXJtICovCgoJLyogV2FpdCBhdCBsZWFzdCA4MHVzIC0gbGV0J3Mgd2FpdCAxIG1zICovCglfX3VkZWxheSgxMDAwKTsKCgllbGFwc2VkID0gMDsKCXdoaWxlICgoKCoodm9sYXRpbGUgdTE2KikoYWRkciArIHNlY3RvcikpICYgMHgwMDgwKSAhPSAweDAwODApIHsKCQllbGFwc2VkICs9ICoodm9sYXRpbGUgdTE2KikoMHhmZmZlZjAwMCtTQzUyMF9TV1RNUk1JTExJKTsKCQlpZiAoZWxhcHNlZCA+ICgoQ0ZHX0ZMQVNIX0VSQVNFX1RPVVQvQ0ZHX0haKSAqIDEwMDApKSB7CgkJCSoodm9sYXRpbGUgdTE2KikoYWRkciArIHNlY3RvcikgPSAweDAwQjA7ICAvKiBzdXNwZW5kIGVyYXNlICAgICAgKi8KCQkJKih2b2xhdGlsZSB1MTYqKShhZGRyICsgc2VjdG9yKSA9IDB4MDBGRjsgIC8qIHJlc2V0IHRvIHJlYWQgbW9kZSAqLwoJCQlyZXR1cm4gMTsKCQl9Cgl9CgoJKih2b2xhdGlsZSB1MTYqKShhZGRyICsgc2VjdG9yKSA9IDB4MDBGRjsgIC8qIHJlc2V0IHRvIHJlYWQgbW9kZSAqLwoKCXJldHVybiAwOwp9CgpleHRlcm4gaW50IF9pbnRlbF9lcmFzZV9mbGFzaF9lbmQ7CmFzbSAoIl9pbnRlbF9lcmFzZV9mbGFzaF9lbmQ6XG4iCiAgICAgIi5sb25nIDBcbiIpOwoKaW50IGZsYXNoX2VyYXNlKGZsYXNoX2luZm9fdCAqaW5mbywgaW50IHNfZmlyc3QsIGludCBzX2xhc3QpCnsKCXUzMiAoKl9lcmFzZV9mbGFzaF9wdHIpKHUzMiBhLCB1MzIgc28pOwoJaW50IHByb3Q7CglpbnQgc2VjdDsKCXVuc2lnbmVkIHNpemU7CgoJaWYgKChzX2ZpcnN0IDwgMCkgfHwgKHNfZmlyc3QgPiBzX2xhc3QpKSB7CgkJaWYgKGluZm8tPmZsYXNoX2lkID09IEZMQVNIX1VOS05PV04pIHsKCQkJcHJpbnRmKCItIG1pc3NpbmdcbiIpOwoJCX0gZWxzZSB7CgkJCXByaW50ZigiLSBubyBzZWN0b3JzIHRvIGVyYXNlXG4iKTsKCQl9CgkJcmV0dXJuIDE7Cgl9CgoJaWYgKChpbmZvLT5mbGFzaF9pZCAmIEZMQVNIX1ZFTkRNQVNLKSA9PSAoQU1EX01BTlVGQUNUICYgRkxBU0hfVkVORE1BU0spKSB7CgkJc2l6ZSA9ICh1bnNpZ25lZCkmX2FtZF9lcmFzZV9mbGFzaF9lbmQgLSAodW5zaWduZWQpX2FtZF9lcmFzZV9mbGFzaDsKCgkJaWYgKHNpemUgPiBQUk9CRV9CVUZGRVJfU0laRSkgewoJCQlwcmludGYoIl9hbWRfZXJhc2VfZmxhc2goKSByb3V0aW5lIHRvbyBsYXJnZSAoJWQpICVwIC0gJXBcbiIsCgkJCSAgICAgICBzaXplLCAmX2FtZF9lcmFzZV9mbGFzaF9lbmQsIF9hbWRfZXJhc2VfZmxhc2gpOwoJCQlyZXR1cm4gMDsKCQl9CgoJCW1lbWNweShidWZmZXIsIF9hbWRfZXJhc2VfZmxhc2gsIHNpemUpOwoJCV9lcmFzZV9mbGFzaF9wdHIgPSAodm9pZCopYnVmZmVyOwoKCX0gZWxzZSBpZiAoKGluZm8tPmZsYXNoX2lkICYgRkxBU0hfVkVORE1BU0spID09IChJTlRFTF9NQU5VRkFDVCAmIEZMQVNIX1ZFTkRNQVNLKSkgewoJCXNpemUgPSAodW5zaWduZWQpJl9pbnRlbF9lcmFzZV9mbGFzaF9lbmQgLSAodW5zaWduZWQpX2ludGVsX2VyYXNlX2ZsYXNoOwoKCQlpZiAoc2l6ZSA+IFBST0JFX0JVRkZFUl9TSVpFKSB7CgkJCXByaW50ZigiX2ludGVsX2VyYXNlX2ZsYXNoKCkgcm91dGluZSB0b28gbGFyZ2UgKCVkKSAlcCAtICVwXG4iLAoJCQkgICAgICAgc2l6ZSwgJl9pbnRlbF9lcmFzZV9mbGFzaF9lbmQsIF9pbnRlbF9lcmFzZV9mbGFzaCk7CgkJCXJldHVybiAwOwoJCX0KCgkJbWVtY3B5KGJ1ZmZlciwgX2ludGVsX2VyYXNlX2ZsYXNoLCBzaXplKTsKCQlfZXJhc2VfZmxhc2hfcHRyID0gKHZvaWQqKWJ1ZmZlcjsKCX0gZWxzZSB7CgkJcHJpbnRmICgiQ2FuJ3QgZXJhc2UgdW5rbm93biBmbGFzaCB0eXBlIC0gYWJvcnRlZFxuIik7CgkJcmV0dXJuIDE7Cgl9CgoJcHJvdCA9IDA7Cglmb3IgKHNlY3Q9c19maXJzdDsgc2VjdDw9c19sYXN0OyArK3NlY3QpIHsKCQlpZiAoaW5mby0+cHJvdGVjdFtzZWN0XSkgewoJCQlwcm90Kys7CgkJfQoJfQoKCWlmIChwcm90KSB7CgkJcHJpbnRmICgiLSBXYXJuaW5nOiAlZCBwcm90ZWN0ZWQgc2VjdG9ycyB3aWxsIG5vdCBiZSBlcmFzZWQhXG4iLCBwcm90KTsKCX0gZWxzZSB7CgkJcHJpbnRmICgiXG4iKTsKCX0KCgkvKiBTdGFydCBlcmFzZSBvbiB1bnByb3RlY3RlZCBzZWN0b3JzICovCglmb3IgKHNlY3QgPSBzX2ZpcnN0OyBzZWN0PD1zX2xhc3Q7IHNlY3QrKykgewoKCQlpZiAoaW5mby0+cHJvdGVjdFtzZWN0XSA9PSAwKSB7IC8qIG5vdCBwcm90ZWN0ZWQgKi8KCQkJaW50IHJlczsKCQkJaW50IGZsYWc7CgoJCQkvKiBEaXNhYmxlIGludGVycnVwdHMgd2hpY2ggbWlnaHQgY2F1c2UgYSB0aW1lb3V0IGhlcmUgKi8KCQkJZmxhZyA9IGRpc2FibGVfaW50ZXJydXB0cygpOwoKCQkJcmVzID0gX2VyYXNlX2ZsYXNoX3B0cihpbmZvLT5zdGFydFswXSwgaW5mby0+c3RhcnRbc2VjdF0taW5mby0+c3RhcnRbMF0pOwoKCQkJLyogcmUtZW5hYmxlIGludGVycnVwdHMgaWYgbmVjZXNzYXJ5ICovCgkJCWlmIChmbGFnKSB7CgkJCQllbmFibGVfaW50ZXJydXB0cygpOwoJCQl9CgoJCQlpZiAocmVzKSB7CgkJCQlwcmludGYoIkVyYXNlIHRpbWVkIG91dCwgc2VjdG9yICVkXG4iLCBzZWN0KTsKCQkJCXJldHVybiByZXM7CgkJCX0KCgkJCXB1dGMoJy4nKTsKCQl9Cgl9CgoJcmV0dXJuIDA7Cn0KCi8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICogV3JpdGUgYSB3b3JkIHRvIEZsYXNoLCByZXR1cm5zOgogKiAwIC0gT0sKICogMSAtIHdyaXRlIHRpbWVvdXQKICogMiAtIEZsYXNoIG5vdCBlcmFzZWQKICovCnN0YXRpYyBpbnQgX2FtZF93cml0ZV93b3JkKHVuc2lnbmVkIHN0YXJ0LCB1bnNpZ25lZCBkZXN0LCB1MTYgZGF0YSkKewoJdm9sYXRpbGUgdTE2ICphZGRyMiA9ICh2b2xhdGlsZSB1MTYqKXN0YXJ0OwoJdm9sYXRpbGUgdTE2ICpkZXN0MiA9ICh2b2xhdGlsZSB1MTYqKWRlc3Q7Cgl2b2xhdGlsZSB1MTYgKmRhdGEyID0gKHZvbGF0aWxlIHUxNiopJmRhdGE7CglpbnQgaTsKCXVuc2lnbmVkIGVsYXBzZWQ7CgoJLyogQ2hlY2sgaWYgRmxhc2ggaXMgKHN1ZmZpY2llbnRseSkgZXJhc2VkICovCglpZiAoKCooKHZvbGF0aWxlIHUxNiopZGVzdCkgJiAodTE2KWRhdGEpICE9ICh1MTYpZGF0YSkgewoJCXJldHVybiAyOwoJfQoKCWZvciAoaSA9IDA7IGkgPCAyOyBpKyspIHsKCgkJYWRkcjJbMHg1NTU1XSA9IDB4MDBBQTsKCQlhZGRyMlsweDJhYWFdID0gMHgwMDU1OwoJCWFkZHIyWzB4NTU1NV0gPSAweDAwQTA7CgoJCWRlc3QyW2ldID0gKGRhdGEgPj4gKGkqMTYpKSAmIDB4ZmZmZjsKCgkJZWxhcHNlZCA9ICoodm9sYXRpbGUgdTE2KikoMHhmZmZlZjAwMCtTQzUyMF9TV1RNUk1JTExJKTsgLyogZHVtbXkgcmVhZCAqLwoJCWVsYXBzZWQgPSAwOwoKCQkvKiBkYXRhIHBvbGxpbmcgZm9yIEQ3ICovCgkJd2hpbGUgKChkZXN0MltpXSAmIDB4MDA4MCkgIT0gKGRhdGEyW2ldICYgMHgwMDgwKSkgewoJCQllbGFwc2VkICs9ICoodm9sYXRpbGUgdTE2KikoMHhmZmZlZjAwMCtTQzUyMF9TV1RNUk1JTExJKTsKCQkJaWYgKGVsYXBzZWQgPiAoKENGR19GTEFTSF9XUklURV9UT1VUL0NGR19IWikgKiAxMDAwKSkgewoJCQkJYWRkcjJbaV0gPSAweDAwZjA7CgkJCQlyZXR1cm4gMTsKCQkJfQoJCX0KCX0KCglhZGRyMltpXSA9IDB4MDBmMDsKCglyZXR1cm4gMDsKfQoKZXh0ZXJuIGludCBfYW1kX3dyaXRlX3dvcmRfZW5kOwphc20gKCJfYW1kX3dyaXRlX3dvcmRfZW5kOlxuIgogICAgICIubG9uZyAwXG4iKTsKCnN0YXRpYyBpbnQgX2ludGVsX3dyaXRlX3dvcmQodW5zaWduZWQgc3RhcnQsIHVuc2lnbmVkIGRlc3QsIHVuc2lnbmVkIGRhdGEpCnsKCWludCBpOwoJdW5zaWduZWQgZWxhcHNlZDsKCgkvKiBDaGVjayBpZiBGbGFzaCBpcyAoc3VmZmljaWVudGx5KSBlcmFzZWQgKi8KCWlmICgoKigodm9sYXRpbGUgdTE2KilkZXN0KSAmICh1MTYpZGF0YSkgIT0gKHUxNilkYXRhKSB7CgkJcmV0dXJuIDI7Cgl9CgoJZm9yIChpID0gMDsgaSA8IDI7IGkrKykgewoKCQkqKHZvbGF0aWxlIHUxNiopKGRlc3QrMippKSA9IDB4MDA0MDsgLyogd3JpdGUgc2V0dXAgKi8KCQkqKHZvbGF0aWxlIHUxNiopKGRlc3QrMippKSA9IChkYXRhID4+IChpKjE2KSkgJiAweGZmZmY7CgoJCWVsYXBzZWQgPSAqKHZvbGF0aWxlIHUxNiopKDB4ZmZmZWYwMDArU0M1MjBfU1dUTVJNSUxMSSk7IC8qIGR1bW15IHJlYWQgKi8KCQllbGFwc2VkID0gMDsKCgkJLyogZGF0YSBwb2xsaW5nIGZvciBENyAqLwoJCXdoaWxlICgoKih2b2xhdGlsZSB1MTYqKWRlc3QgJiAweDAwODApICE9IDB4MDA4MCkgewoJCQllbGFwc2VkICs9ICoodm9sYXRpbGUgdTE2KikoMHhmZmZlZjAwMCtTQzUyMF9TV1RNUk1JTExJKTsKCQkJaWYgKGVsYXBzZWQgPiAoKENGR19GTEFTSF9XUklURV9UT1VUL0NGR19IWikgKiAxMDAwKSkgewoJCQkJKih2b2xhdGlsZSB1MTYqKWRlc3QgPSAweDAwZmY7CgkJCQlyZXR1cm4gMTsKCQkJfQoJCX0KCX0KCgkqKHZvbGF0aWxlIHUxNiopZGVzdCA9IDB4MDBmZjsKCgoJcmV0dXJuIDA7Cn0KCmV4dGVybiBpbnQgX2ludGVsX3dyaXRlX3dvcmRfZW5kOwphc20gKCJfaW50ZWxfd3JpdGVfd29yZF9lbmQ6XG4iCiAgICAgIi5sb25nIDBcbiIpOwoKLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogKiBDb3B5IG1lbW9yeSB0byBmbGFzaCwgcmV0dXJuczoKICogMCAtIE9LCiAqIDEgLSB3cml0ZSB0aW1lb3V0CiAqIDIgLSBGbGFzaCBub3QgZXJhc2VkCiAqIDMgLSBVbnN1cHBvcnRlZCBmbGFzaCB0eXBlCiAqLwoKaW50IHdyaXRlX2J1ZmYoZmxhc2hfaW5mb190ICppbmZvLCB1Y2hhciAqc3JjLCB1bG9uZyBhZGRyLCB1bG9uZyBjbnQpCnsKCXVsb25nIGNwLCB3cCwgZGF0YTsKCWludCBpLCBsLCByYzsKCWludCBmbGFnOwoJdTMyICgqX3dyaXRlX3dvcmRfcHRyKSh1bnNpZ25lZCBzdGFydCwgdW5zaWduZWQgZGVzdCwgdW5zaWduZWQgZGF0YSk7Cgl1bnNpZ25lZCBzaXplOwoKCWlmICgoaW5mby0+Zmxhc2hfaWQgJiBGTEFTSF9WRU5ETUFTSykgPT0gKEFNRF9NQU5VRkFDVCAmIEZMQVNIX1ZFTkRNQVNLKSkgewoJCXNpemUgPSAodW5zaWduZWQpJl9hbWRfd3JpdGVfd29yZF9lbmQgLSAodW5zaWduZWQpX2FtZF93cml0ZV93b3JkOwoKCQlpZiAoc2l6ZSA+IFBST0JFX0JVRkZFUl9TSVpFKSB7CgkJCXByaW50ZigiX2FtZF93cml0ZV93b3JkKCkgcm91dGluZSB0b28gbGFyZ2UgKCVkKSAlcCAtICVwXG4iLAoJCQkgICAgICAgc2l6ZSwgJl9hbWRfd3JpdGVfd29yZF9lbmQsIF9hbWRfd3JpdGVfd29yZCk7CgkJCXJldHVybiAwOwoJCX0KCgkJbWVtY3B5KGJ1ZmZlciwgX2FtZF93cml0ZV93b3JkLCBzaXplKTsKCQlfd3JpdGVfd29yZF9wdHIgPSAodm9pZCopYnVmZmVyOwoKCX0gZWxzZSBpZiAoKGluZm8tPmZsYXNoX2lkICYgRkxBU0hfVkVORE1BU0spID09IChJTlRFTF9NQU5VRkFDVCAmIEZMQVNIX1ZFTkRNQVNLKSkgewoJCXNpemUgPSAodW5zaWduZWQpJl9pbnRlbF93cml0ZV93b3JkX2VuZCAtICh1bnNpZ25lZClfaW50ZWxfd3JpdGVfd29yZDsKCgkJaWYgKHNpemUgPiBQUk9CRV9CVUZGRVJfU0laRSkgewoJCQlwcmludGYoIl9pbnRlbF93cml0ZV93b3JkKCkgcm91dGluZSB0b28gbGFyZ2UgKCVkKSAlcCAtICVwXG4iLAoJCQkgICAgICAgc2l6ZSwgJl9pbnRlbF93cml0ZV93b3JkX2VuZCwgX2ludGVsX3dyaXRlX3dvcmQpOwoJCQlyZXR1cm4gMDsKCQl9CgoJCW1lbWNweShidWZmZXIsIF9pbnRlbF93cml0ZV93b3JkLCBzaXplKTsKCQlfd3JpdGVfd29yZF9wdHIgPSAodm9pZCopYnVmZmVyOwoJfSBlbHNlIHsKCQlwcmludGYgKCJDYW4ndCBwcm9ncmFtIHVua25vd24gZmxhc2ggdHlwZSAtIGFib3J0ZWRcbiIpOwoJCXJldHVybiAzOwoJfQoKCXdwID0gKGFkZHIgJiB+Myk7CS8qIGdldCBsb3dlciB3b3JkIGFsaWduZWQgYWRkcmVzcyAqLwoKCS8qCgkgKiBoYW5kbGUgdW5hbGlnbmVkIHN0YXJ0IGJ5dGVzCgkgKi8KCWlmICgobCA9IGFkZHIgLSB3cCkgIT0gMCkgewoJCWRhdGEgPSAwOwoJCWZvciAoaT0wLCBjcD13cDsgaTxsOyArK2ksICsrY3ApIHsKCQkJZGF0YSB8PSAoKih1Y2hhciAqKWNwKSA8PCAoOCppKTsKCQl9CgkJZm9yICg7IGk8NCAmJiBjbnQ+MDsgKytpKSB7CgkJCWRhdGEgfD0gKnNyYysrIDw8ICg4KmkpOwoJCQktLWNudDsKCQkJKytjcDsKCQl9CgkJZm9yICg7IGNudD09MCAmJiBpPDQ7ICsraSwgKytjcCkgewoJCQlkYXRhIHw9ICgqKHVjaGFyICopY3ApICA8PCAoOCppKTsKCQl9CgoJCS8qIERpc2FibGUgaW50ZXJydXB0cyB3aGljaCBtaWdodCBjYXVzZSBhIHRpbWVvdXQgaGVyZSAqLwoJCWZsYWcgPSBkaXNhYmxlX2ludGVycnVwdHMoKTsKCgkJcmMgPSBfd3JpdGVfd29yZF9wdHIoaW5mby0+c3RhcnRbMF0sIHdwLCBkYXRhKTsKCgkJLyogcmUtZW5hYmxlIGludGVycnVwdHMgaWYgbmVjZXNzYXJ5ICovCgkJaWYgKGZsYWcpIHsKCQkJZW5hYmxlX2ludGVycnVwdHMoKTsKCQl9CgkJaWYgKHJjICE9IDApIHsKCQkJcmV0dXJuIHJjOwoJCX0KCQl3cCArPSA0OwoJfQoKCS8qCgkgKiBoYW5kbGUgd29yZCBhbGlnbmVkIHBhcnQKCSAqLwoJd2hpbGUgKGNudCA+PSA0KSB7CgkJZGF0YSA9IDA7CgoJCWZvciAoaT0wOyBpPDQ7ICsraSkgewoJCQlkYXRhIHw9ICpzcmMrKyA8PCAoOCppKTsKCQl9CgoJCS8qIERpc2FibGUgaW50ZXJydXB0cyB3aGljaCBtaWdodCBjYXVzZSBhIHRpbWVvdXQgaGVyZSAqLwoJCWZsYWcgPSBkaXNhYmxlX2ludGVycnVwdHMoKTsKCgkJcmMgPSBfd3JpdGVfd29yZF9wdHIoaW5mby0+c3RhcnRbMF0sIHdwLCBkYXRhKTsKCgkJLyogcmUtZW5hYmxlIGludGVycnVwdHMgaWYgbmVjZXNzYXJ5ICovCgkJaWYgKGZsYWcpIHsKCQkJZW5hYmxlX2ludGVycnVwdHMoKTsKCQl9CgkJaWYgKHJjICE9IDApIHsKCQkJcmV0dXJuIHJjOwoJCX0KCQl3cCAgKz0gNDsKCQljbnQgLT0gNDsKCX0KCglpZiAoY250ID09IDApIHsKCQlyZXR1cm4gMDsKCX0KCgkvKgoJICogaGFuZGxlIHVuYWxpZ25lZCB0YWlsIGJ5dGVzCgkgKi8KCWRhdGEgPSAwOwoJZm9yIChpPTAsIGNwPXdwOyBpPDQgJiYgY250PjA7ICsraSwgKytjcCkgewoJCWRhdGEgfD0gKnNyYysrIDw8ICg4KmkpOwoJCS0tY250OwoJfQoKCWZvciAoOyBpPDQ7ICsraSwgKytjcCkgewoJCWRhdGEgfD0gKCoodWNoYXIgKiljcCkgPDwgKDgqaSk7Cgl9CgoJLyogRGlzYWJsZSBpbnRlcnJ1cHRzIHdoaWNoIG1pZ2h0IGNhdXNlIGEgdGltZW91dCBoZXJlICovCglmbGFnID0gZGlzYWJsZV9pbnRlcnJ1cHRzKCk7CgoJcmMgPSBfd3JpdGVfd29yZF9wdHIoaW5mby0+c3RhcnRbMF0sIHdwLCBkYXRhKTsKCgkvKiByZS1lbmFibGUgaW50ZXJydXB0cyBpZiBuZWNlc3NhcnkgKi8KCWlmIChmbGFnKSB7CgkJZW5hYmxlX2ludGVycnVwdHMoKTsKCX0KCglyZXR1cm4gcmM7Cn0K