LyoKICoKICoJCQlMaW51eCBNZWdhUkFJRCBkZXZpY2UgZHJpdmVyCiAqCiAqIENvcHlyaWdodCCpIDIwMDIgIExTSSBMb2dpYyBDb3Jwb3JhdGlvbi4KICoKICoJICAgVGhpcyBwcm9ncmFtIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vcgogKgkgICBtb2RpZnkgaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQogKgkgICBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyIHZlcnNpb24KICoJICAgMiBvZiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi4KICoKICogQ29weXJpZ2h0IChjKSAyMDAyICBSZWQgSGF0LCBJbmMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqCSAgLSBmaXhlcwogKgkgIC0gc3BlZWQtdXBzIChsaXN0IGhhbmRsaW5nIGZpeGVzLCBpc3N1ZWRfbGlzdCwgb3B0aW1pemF0aW9ucy4pCiAqCSAgLSBsb3RzIG9mIGNsZWFudXBzLgogKgogKiBDb3B5cmlnaHQgKGMpIDIwMDMgIENocmlzdG9waCBIZWxsd2lnICA8aGNoQGxzdC5kZT4KICoJICAtIG5ldy1zdHlsZSwgaG90cGx1Zy1hd2FyZSBwY2kgcHJvYmluZyBhbmQgc2NzaSByZWdpc3RyYXRpb24KICoKICogVmVyc2lvbiA6IHYyLjAwLjMgKEZlYiAxOSwgMjAwMykgLSBBdHVsIE11a2tlciA8QXR1bC5NdWtrZXJAbHNpbC5jb20+CiAqCiAqIERlc2NyaXB0aW9uOiBMaW51eCBkZXZpY2UgZHJpdmVyIGZvciBMU0kgTG9naWMgTWVnYVJBSUQgY29udHJvbGxlcgogKgogKiBTdXBwb3J0ZWQgY29udHJvbGxlcnM6IE1lZ2FSQUlEIDQxOCwgNDI4LCA0MzgsIDQ2NiwgNzYyLCA0NjcsIDQ3MSwgNDkwLCA0OTMKICoJCQkJCTUxOCwgNTIwLCA1MzEsIDUzMgogKgogKiBUaGlzIGRyaXZlciBpcyBzdXBwb3J0ZWQgYnkgTFNJIExvZ2ljLCB3aXRoIGFzc2lzdGFuY2UgZnJvbSBSZWQgSGF0LCBEZWxsLAogKiBhbmQgb3RoZXJzLiBQbGVhc2Ugc2VuZCB1cGRhdGVzIHRvIHRoZSBtYWlsaW5nIGxpc3QKICogbGludXgtc2NzaUB2Z2VyLmtlcm5lbC5vcmcgLgogKgogKi8KCiNpbmNsdWRlIDxsaW51eC9tbS5oPgojaW5jbHVkZSA8bGludXgvZnMuaD4KI2luY2x1ZGUgPGxpbnV4L2Jsa2Rldi5oPgojaW5jbHVkZSA8YXNtL3VhY2Nlc3MuaD4KI2luY2x1ZGUgPGFzbS9pby5oPgojaW5jbHVkZSA8bGludXgvZGVsYXkuaD4KI2luY2x1ZGUgPGxpbnV4L3Byb2NfZnMuaD4KI2luY2x1ZGUgPGxpbnV4L3JlYm9vdC5oPgojaW5jbHVkZSA8bGludXgvbW9kdWxlLmg+CiNpbmNsdWRlIDxsaW51eC9saXN0Lmg+CiNpbmNsdWRlIDxsaW51eC9pbnRlcnJ1cHQuaD4KI2luY2x1ZGUgPGxpbnV4L3BjaS5oPgojaW5jbHVkZSA8bGludXgvaW5pdC5oPgojaW5jbHVkZSA8c2NzaS9zY3NpY2FtLmg+CgojaW5jbHVkZSAic2NzaS5oIgojaW5jbHVkZSA8c2NzaS9zY3NpX2hvc3QuaD4KCiNpbmNsdWRlICJtZWdhcmFpZC5oIgoKI2RlZmluZSBNRUdBUkFJRF9NT0RVTEVfVkVSU0lPTiAiMi4wMC4zIgoKTU9EVUxFX0FVVEhPUiAoIkxTSSBMb2dpYyBDb3Jwb3JhdGlvbiIpOwpNT0RVTEVfREVTQ1JJUFRJT04gKCJMU0kgTG9naWMgTWVnYVJBSUQgZHJpdmVyIik7Ck1PRFVMRV9MSUNFTlNFICgiR1BMIik7Ck1PRFVMRV9WRVJTSU9OKE1FR0FSQUlEX01PRFVMRV9WRVJTSU9OKTsKCnN0YXRpYyB1bnNpZ25lZCBpbnQgbWF4X2NtZF9wZXJfbHVuID0gREVGX0NNRF9QRVJfTFVOOwptb2R1bGVfcGFyYW0obWF4X2NtZF9wZXJfbHVuLCB1aW50LCAwKTsKTU9EVUxFX1BBUk1fREVTQyhtYXhfY21kX3Blcl9sdW4sICJNYXhpbXVtIG51bWJlciBvZiBjb21tYW5kcyB3aGljaCBjYW4gYmUgaXNzdWVkIHRvIGEgc2luZ2xlIExVTiAoZGVmYXVsdD1ERUZfQ01EX1BFUl9MVU49NjMpIik7CgpzdGF0aWMgdW5zaWduZWQgc2hvcnQgaW50IG1heF9zZWN0b3JzX3Blcl9pbyA9IE1BWF9TRUNUT1JTX1BFUl9JTzsKbW9kdWxlX3BhcmFtKG1heF9zZWN0b3JzX3Blcl9pbywgdXNob3J0LCAwKTsKTU9EVUxFX1BBUk1fREVTQyhtYXhfc2VjdG9yc19wZXJfaW8sICJNYXhpbXVtIG51bWJlciBvZiBzZWN0b3JzIHBlciBJL08gcmVxdWVzdCAoZGVmYXVsdD1NQVhfU0VDVE9SU19QRVJfSU89MTI4KSIpOwoKCnN0YXRpYyB1bnNpZ25lZCBzaG9ydCBpbnQgbWF4X21ib3hfYnVzeV93YWl0ID0gTUJPWF9CVVNZX1dBSVQ7Cm1vZHVsZV9wYXJhbShtYXhfbWJveF9idXN5X3dhaXQsIHVzaG9ydCwgMCk7Ck1PRFVMRV9QQVJNX0RFU0MobWF4X21ib3hfYnVzeV93YWl0LCAiTWF4aW11bSB3YWl0IGZvciBtYWlsYm94IGluIG1pY3Jvc2Vjb25kcyBpZiBidXN5IChkZWZhdWx0PU1CT1hfQlVTWV9XQUlUPTEwKSIpOwoKI2RlZmluZSBSRElORE9PUihhZGFwdGVyKQkJcmVhZGwoKGFkYXB0ZXIpLT5iYXNlICsgMHgyMCkKI2RlZmluZSBSRE9VVERPT1IoYWRhcHRlcikJCXJlYWRsKChhZGFwdGVyKS0+YmFzZSArIDB4MkMpCiNkZWZpbmUgV1JJTkRPT1IoYWRhcHRlcix2YWx1ZSkJCXdyaXRlbCh2YWx1ZSwgKGFkYXB0ZXIpLT5iYXNlICsgMHgyMCkKI2RlZmluZSBXUk9VVERPT1IoYWRhcHRlcix2YWx1ZSkJd3JpdGVsKHZhbHVlLCAoYWRhcHRlciktPmJhc2UgKyAweDJDKQoKLyoKICogR2xvYmFsIHZhcmlhYmxlcwogKi8KCnN0YXRpYyBpbnQgaGJhX2NvdW50OwpzdGF0aWMgYWRhcHRlcl90ICpoYmFfc29mdF9zdGF0ZVtNQVhfQ09OVFJPTExFUlNdOwpzdGF0aWMgc3RydWN0IHByb2NfZGlyX2VudHJ5ICptZWdhX3Byb2NfZGlyX2VudHJ5OwoKLyogRm9yIGNvbnRyb2xsZXIgcmUtb3JkZXJpbmcgKi8Kc3RhdGljIHN0cnVjdCBtZWdhX2hiYXMgbWVnYV9oYmFzW01BWF9DT05UUk9MTEVSU107CgovKgogKiBUaGUgRmlsZSBPcGVyYXRpb25zIHN0cnVjdHVyZSBmb3IgdGhlIHNlcmlhbC9pb2N0bCBpbnRlcmZhY2Ugb2YgdGhlIGRyaXZlcgogKi8Kc3RhdGljIHN0cnVjdCBmaWxlX29wZXJhdGlvbnMgbWVnYWRldl9mb3BzID0gewoJLm93bmVyCQk9IFRISVNfTU9EVUxFLAoJLmlvY3RsCQk9IG1lZ2FkZXZfaW9jdGwsCgkub3BlbgkJPSBtZWdhZGV2X29wZW4sCn07CgovKgogKiBBcnJheSB0byBzdHJ1Y3R1cmVzIGZvciBzdG9yaW5nIHRoZSBpbmZvcm1hdGlvbiBhYm91dCB0aGUgY29udHJvbGxlcnMuIFRoaXMKICogaW5mb3JtYXRpb24gaXMgc2VudCB0byB0aGUgdXNlciBsZXZlbCBhcHBsaWNhdGlvbnMsIHdoZW4gdGhleSBkbyBhbiBpb2N0bAogKiBmb3IgdGhpcyBpbmZvcm1hdGlvbi4KICovCnN0YXRpYyBzdHJ1Y3QgbWNvbnRyb2xsZXIgbWNvbnRyb2xsZXJbTUFYX0NPTlRST0xMRVJTXTsKCi8qIFRoZSBjdXJyZW50IGRyaXZlciB2ZXJzaW9uICovCnN0YXRpYyB1MzIgZHJpdmVyX3ZlciA9IDB4MDIwMDAwMDA7CgovKiBtYWpvciBudW1iZXIgdXNlZCBieSB0aGUgZGV2aWNlIGZvciBjaGFyYWN0ZXIgaW50ZXJmYWNlICovCnN0YXRpYyBpbnQgbWFqb3I7CgojZGVmaW5lIElTX1JBSURfQ0goaGJhLCBjaCkJKCgoaGJhKS0+bWVnYV9jaF9jbGFzcyA+PiAoY2gpKSAmIDB4MDEpCgoKLyoKICogRGVidWcgdmFyaWFibGUgdG8gcHJpbnQgc29tZSBkaWFnbm9zdGljIG1lc3NhZ2VzCiAqLwpzdGF0aWMgaW50IHRyYWNlX2xldmVsOwoKLyoqCiAqIG1lZ2Ffc2V0dXBfbWFpbGJveCgpCiAqIEBhZGFwdGVyIC0gcG9pbnRlciB0byBvdXIgc29mdCBzdGF0ZQogKgogKiBBbGxvY2F0ZXMgYSA4IGJ5dGUgYWxpZ25lZCBtZW1vcnkgZm9yIHRoZSBoYW5kc2hha2UgbWFpbGJveC4KICovCnN0YXRpYyBpbnQKbWVnYV9zZXR1cF9tYWlsYm94KGFkYXB0ZXJfdCAqYWRhcHRlcikKewoJdW5zaWduZWQgbG9uZwlhbGlnbjsKCglhZGFwdGVyLT51bmFfbWJveDY0ID0gcGNpX2FsbG9jX2NvbnNpc3RlbnQoYWRhcHRlci0+ZGV2LAoJCQlzaXplb2YobWJveDY0X3QpLCAmYWRhcHRlci0+dW5hX21ib3g2NF9kbWEpOwoKCWlmKCAhYWRhcHRlci0+dW5hX21ib3g2NCApIHJldHVybiAtMTsKCQkKCWFkYXB0ZXItPm1ib3ggPSAmYWRhcHRlci0+dW5hX21ib3g2NC0+bWJveDsKCglhZGFwdGVyLT5tYm94ID0gKG1ib3hfdCAqKSgoKCh1bnNpZ25lZCBsb25nKSBhZGFwdGVyLT5tYm94KSArIDE1KSAmCgkJCSh+MFVMIF4gMHhGVUwpKTsKCglhZGFwdGVyLT5tYm94NjQgPSAobWJveDY0X3QgKikoKCh1bnNpZ25lZCBsb25nKWFkYXB0ZXItPm1ib3gpIC0gOCk7CgoJYWxpZ24gPSAoKHZvaWQgKilhZGFwdGVyLT5tYm94KSAtICgodm9pZCAqKSZhZGFwdGVyLT51bmFfbWJveDY0LT5tYm94KTsKCglhZGFwdGVyLT5tYm94X2RtYSA9IGFkYXB0ZXItPnVuYV9tYm94NjRfZG1hICsgOCArIGFsaWduOwoKCS8qCgkgKiBSZWdpc3RlciB0aGUgbWFpbGJveCBpZiB0aGUgY29udHJvbGxlciBpcyBhbiBpby1tYXBwZWQgY29udHJvbGxlcgoJICovCglpZiggYWRhcHRlci0+ZmxhZyAmIEJPQVJEX0lPTUFQICkgewoKCQlvdXRiX3AoYWRhcHRlci0+bWJveF9kbWEgJiAweEZGLAoJCQkJYWRhcHRlci0+aG9zdC0+aW9fcG9ydCArIE1CT1hfUE9SVDApOwoKCQlvdXRiX3AoKGFkYXB0ZXItPm1ib3hfZG1hID4+IDgpICYgMHhGRiwKCQkJCWFkYXB0ZXItPmhvc3QtPmlvX3BvcnQgKyBNQk9YX1BPUlQxKTsKCgkJb3V0Yl9wKChhZGFwdGVyLT5tYm94X2RtYSA+PiAxNikgJiAweEZGLAoJCQkJYWRhcHRlci0+aG9zdC0+aW9fcG9ydCArIE1CT1hfUE9SVDIpOwoKCQlvdXRiX3AoKGFkYXB0ZXItPm1ib3hfZG1hID4+IDI0KSAmIDB4RkYsCgkJCQlhZGFwdGVyLT5ob3N0LT5pb19wb3J0ICsgTUJPWF9QT1JUMyk7CgoJCW91dGJfcChFTkFCTEVfTUJPWF9CWVRFLAoJCQkJYWRhcHRlci0+aG9zdC0+aW9fcG9ydCArIEVOQUJMRV9NQk9YX1JFR0lPTik7CgoJCWlycV9hY2soYWRhcHRlcik7CgoJCWlycV9lbmFibGUoYWRhcHRlcik7Cgl9CgoJcmV0dXJuIDA7Cn0KCgovKgogKiBtZWdhX3F1ZXJ5X2FkYXB0ZXIoKQogKiBAYWRhcHRlciAtIHBvaW50ZXIgdG8gb3VyIHNvZnQgc3RhdGUKICoKICogSXNzdWUgdGhlIGFkYXB0ZXIgaW5xdWlyeSBjb21tYW5kcyB0byB0aGUgY29udHJvbGxlciBhbmQgZmluZCBvdXQKICogaW5mb3JtYXRpb24gYW5kIHBhcmFtZXRlciBhYm91dCB0aGUgZGV2aWNlcyBhdHRhY2hlZAogKi8Kc3RhdGljIGludAptZWdhX3F1ZXJ5X2FkYXB0ZXIoYWRhcHRlcl90ICphZGFwdGVyKQp7CglkbWFfYWRkcl90CXByb2RfaW5mb19kbWFfaGFuZGxlOwoJbWVnYV9pbnF1aXJ5MwkqaW5xdWlyeTM7Cgl1OAlyYXdfbWJveFtzaXplb2Yoc3RydWN0IG1ib3hfb3V0KV07CgltYm94X3QJKm1ib3g7CglpbnQJcmV0dmFsOwoKCS8qIEluaXRpYWxpemUgYWRhcHRlciBpbnF1aXJ5IG1haWxib3ggKi8KCgltYm94ID0gKG1ib3hfdCAqKXJhd19tYm94OwoKCW1lbXNldCgodm9pZCAqKWFkYXB0ZXItPm1lZ2FfYnVmZmVyLCAwLCBNRUdBX0JVRkZFUl9TSVpFKTsKCW1lbXNldCgmbWJveC0+bV9vdXQsIDAsIHNpemVvZihyYXdfbWJveCkpOwoKCS8qCgkgKiBUcnkgdG8gaXNzdWUgSW5xdWlyeTMgY29tbWFuZAoJICogaWYgbm90IHN1Y2NlZWRlZCwgdGhlbiBpc3N1ZSBNRUdBX01CT1hDTURfQURBUFRFUklOUSBjb21tYW5kIGFuZAoJICogdXBkYXRlIGVucXVpcnkzIHN0cnVjdHVyZQoJICovCgltYm94LT5tX291dC54ZmVyYWRkciA9ICh1MzIpYWRhcHRlci0+YnVmX2RtYV9oYW5kbGU7CgoJaW5xdWlyeTMgPSAobWVnYV9pbnF1aXJ5MyAqKWFkYXB0ZXItPm1lZ2FfYnVmZmVyOwoKCXJhd19tYm94WzBdID0gRkNfTkVXX0NPTkZJRzsJCS8qIGkuZS4gbWJveC0+Y21kPTB4QTEgKi8KCXJhd19tYm94WzJdID0gTkNfU1VCT1BfRU5RVUlSWTM7CS8qIGkuZS4gMHgwRiAqLwoJcmF3X21ib3hbM10gPSBFTlEzX0dFVF9TT0xJQ0lURURfRlVMTDsJLyogaS5lLiAweDAyICovCgoJLyogSXNzdWUgYSBibG9ja2luZyBjb21tYW5kIHRvIHRoZSBjYXJkICovCglpZiAoKHJldHZhbCA9IGlzc3VlX3NjYl9ibG9jayhhZGFwdGVyLCByYXdfbWJveCkpKSB7CgkJLyogdGhlIGFkYXB0ZXIgZG9lcyBub3Qgc3VwcG9ydCA0MGxkICovCgoJCW1yYWlkX2V4dF9pbnF1aXJ5CSpleHRfaW5xOwoJCW1yYWlkX2lucXVpcnkJCSppbnE7CgkJZG1hX2FkZHJfdAkJZG1hX2hhbmRsZTsKCgkJZXh0X2lucSA9IHBjaV9hbGxvY19jb25zaXN0ZW50KGFkYXB0ZXItPmRldiwKCQkJCXNpemVvZihtcmFpZF9leHRfaW5xdWlyeSksICZkbWFfaGFuZGxlKTsKCgkJaWYoIGV4dF9pbnEgPT0gTlVMTCApIHJldHVybiAtMTsKCgkJaW5xID0gJmV4dF9pbnEtPnJhaWRfaW5xOwoKCQltYm94LT5tX291dC54ZmVyYWRkciA9ICh1MzIpZG1hX2hhbmRsZTsKCgkJLyppc3N1ZSBvbGQgMHgwNCBjb21tYW5kIHRvIGFkYXB0ZXIgKi8KCQltYm94LT5tX291dC5jbWQgPSBNRUdBX01CT1hDTURfQURQRVhUSU5ROwoKCQlpc3N1ZV9zY2JfYmxvY2soYWRhcHRlciwgcmF3X21ib3gpOwoKCQkvKgoJCSAqIHVwZGF0ZSBFbnF1aXJ5MyBhbmQgUHJvZHVjdEluZm8gc3RydWN0dXJlcyB3aXRoCgkJICogbXJhaWRfaW5xdWlyeSBzdHJ1Y3R1cmUKCQkgKi8KCQltZWdhXzhfdG9fNDBsZChpbnEsIGlucXVpcnkzLAoJCQkJKG1lZ2FfcHJvZHVjdF9pbmZvICopJmFkYXB0ZXItPnByb2R1Y3RfaW5mbyk7CgoJCXBjaV9mcmVlX2NvbnNpc3RlbnQoYWRhcHRlci0+ZGV2LCBzaXplb2YobXJhaWRfZXh0X2lucXVpcnkpLAoJCQkJZXh0X2lucSwgZG1hX2hhbmRsZSk7CgoJfSBlbHNlIHsJCS8qYWRhcHRlciBzdXBwb3J0cyA0MGxkICovCgkJYWRhcHRlci0+ZmxhZyB8PSBCT0FSRF80MExEOwoKCQkvKgoJCSAqIGdldCBwcm9kdWN0X2luZm8sIHdoaWNoIGlzIHN0YXRpYyBpbmZvcm1hdGlvbiBhbmQgd2lsbCBiZQoJCSAqIHVuY2hhbmdlZAoJCSAqLwoJCXByb2RfaW5mb19kbWFfaGFuZGxlID0gcGNpX21hcF9zaW5nbGUoYWRhcHRlci0+ZGV2LCAodm9pZCAqKQoJCQkJJmFkYXB0ZXItPnByb2R1Y3RfaW5mbywKCQkJCXNpemVvZihtZWdhX3Byb2R1Y3RfaW5mbyksIFBDSV9ETUFfRlJPTURFVklDRSk7CgoJCW1ib3gtPm1fb3V0LnhmZXJhZGRyID0gcHJvZF9pbmZvX2RtYV9oYW5kbGU7CgoJCXJhd19tYm94WzBdID0gRkNfTkVXX0NPTkZJRzsJLyogaS5lLiBtYm94LT5jbWQ9MHhBMSAqLwoJCXJhd19tYm94WzJdID0gTkNfU1VCT1BfUFJPRFVDVF9JTkZPOwkvKiBpLmUuIDB4MEUgKi8KCgkJaWYgKChyZXR2YWwgPSBpc3N1ZV9zY2JfYmxvY2soYWRhcHRlciwgcmF3X21ib3gpKSkKCQkJcHJpbnRrKEtFUk5fV0FSTklORwoJCQkibWVnYXJhaWQ6IFByb2R1Y3RfaW5mbyBjbWQgZmFpbGVkIHdpdGggZXJyb3I6ICVkXG4iLAoJCQkJcmV0dmFsKTsKCgkJcGNpX3VubWFwX3NpbmdsZShhZGFwdGVyLT5kZXYsIHByb2RfaW5mb19kbWFfaGFuZGxlLAoJCQkJc2l6ZW9mKG1lZ2FfcHJvZHVjdF9pbmZvKSwgUENJX0RNQV9GUk9NREVWSUNFKTsKCX0KCgoJLyoKCSAqIGtlcm5lbCBzY2FucyB0aGUgY2hhbm5lbHMgZnJvbSAwIHRvIDw9IG1heF9jaGFubmVsCgkgKi8KCWFkYXB0ZXItPmhvc3QtPm1heF9jaGFubmVsID0KCQlhZGFwdGVyLT5wcm9kdWN0X2luZm8ubmNoYW5uZWxzICsgTlZJUlRfQ0hBTiAtMTsKCglhZGFwdGVyLT5ob3N0LT5tYXhfaWQgPSAxNjsJLyogbWF4IHRhcmdldHMgcGVyIGNoYW5uZWwgKi8KCglhZGFwdGVyLT5ob3N0LT5tYXhfbHVuID0gNzsJLyogVXB0byA3IGx1bnMgZm9yIG5vbiBkaXNrIGRldmljZXMgKi8KCglhZGFwdGVyLT5ob3N0LT5jbWRfcGVyX2x1biA9IG1heF9jbWRfcGVyX2x1bjsKCglhZGFwdGVyLT5udW1sZHJ2ID0gaW5xdWlyeTMtPm51bV9sZHJ2OwoKCWFkYXB0ZXItPm1heF9jbWRzID0gYWRhcHRlci0+cHJvZHVjdF9pbmZvLm1heF9jb21tYW5kczsKCglpZihhZGFwdGVyLT5tYXhfY21kcyA+IE1BWF9DT01NQU5EUykKCQlhZGFwdGVyLT5tYXhfY21kcyA9IE1BWF9DT01NQU5EUzsKCglhZGFwdGVyLT5ob3N0LT5jYW5fcXVldWUgPSBhZGFwdGVyLT5tYXhfY21kcyAtIDE7CgoJLyoKCSAqIEdldCB0aGUgbWF4aW11bSBudW1iZXIgb2Ygc2NhdHRlci1nYXRoZXIgZWxlbWVudHMgc3VwcG9ydGVkIGJ5IHRoaXMKCSAqIGZpcm13YXJlCgkgKi8KCW1lZ2FfZ2V0X21heF9zZ2woYWRhcHRlcik7CgoJYWRhcHRlci0+aG9zdC0+c2dfdGFibGVzaXplID0gYWRhcHRlci0+c2dsZW47CgoKCS8qIHVzZSBIUCBmaXJtd2FyZSBhbmQgYmlvcyB2ZXJzaW9uIGVuY29kaW5nICovCglpZiAoYWRhcHRlci0+cHJvZHVjdF9pbmZvLnN1YnN5c3ZpZCA9PSBIUF9TVUJTWVNfVklEKSB7CgkJc3ByaW50ZiAoYWRhcHRlci0+ZndfdmVyc2lvbiwgIiVjJWQlZC4lZCVkIiwKCQkJIGFkYXB0ZXItPnByb2R1Y3RfaW5mby5md192ZXJzaW9uWzJdLAoJCQkgYWRhcHRlci0+cHJvZHVjdF9pbmZvLmZ3X3ZlcnNpb25bMV0gPj4gOCwKCQkJIGFkYXB0ZXItPnByb2R1Y3RfaW5mby5md192ZXJzaW9uWzFdICYgMHgwZiwKCQkJIGFkYXB0ZXItPnByb2R1Y3RfaW5mby5md192ZXJzaW9uWzBdID4+IDgsCgkJCSBhZGFwdGVyLT5wcm9kdWN0X2luZm8uZndfdmVyc2lvblswXSAmIDB4MGYpOwoJCXNwcmludGYgKGFkYXB0ZXItPmJpb3NfdmVyc2lvbiwgIiVjJWQlZC4lZCVkIiwKCQkJIGFkYXB0ZXItPnByb2R1Y3RfaW5mby5iaW9zX3ZlcnNpb25bMl0sCgkJCSBhZGFwdGVyLT5wcm9kdWN0X2luZm8uYmlvc192ZXJzaW9uWzFdID4+IDgsCgkJCSBhZGFwdGVyLT5wcm9kdWN0X2luZm8uYmlvc192ZXJzaW9uWzFdICYgMHgwZiwKCQkJIGFkYXB0ZXItPnByb2R1Y3RfaW5mby5iaW9zX3ZlcnNpb25bMF0gPj4gOCwKCQkJIGFkYXB0ZXItPnByb2R1Y3RfaW5mby5iaW9zX3ZlcnNpb25bMF0gJiAweDBmKTsKCX0gZWxzZSB7CgkJbWVtY3B5KGFkYXB0ZXItPmZ3X3ZlcnNpb24sCgkJCQkoY2hhciAqKWFkYXB0ZXItPnByb2R1Y3RfaW5mby5md192ZXJzaW9uLCA0KTsKCQlhZGFwdGVyLT5md192ZXJzaW9uWzRdID0gMDsKCgkJbWVtY3B5KGFkYXB0ZXItPmJpb3NfdmVyc2lvbiwKCQkJCShjaGFyICopYWRhcHRlci0+cHJvZHVjdF9pbmZvLmJpb3NfdmVyc2lvbiwgNCk7CgoJCWFkYXB0ZXItPmJpb3NfdmVyc2lvbls0XSA9IDA7Cgl9CgoJcHJpbnRrKEtFUk5fTk9USUNFICJtZWdhcmFpZDogWyVzOiVzXSBkZXRlY3RlZCAlZCBsb2dpY2FsIGRyaXZlcy5cbiIsCgkJYWRhcHRlci0+ZndfdmVyc2lvbiwgYWRhcHRlci0+Ymlvc192ZXJzaW9uLCBhZGFwdGVyLT5udW1sZHJ2KTsKCgkvKgoJICogRG8gd2Ugc3VwcG9ydCBleHRlbmRlZCAoPjEwIGJ5dGVzKSBjZGJzCgkgKi8KCWFkYXB0ZXItPnN1cHBvcnRfZXh0X2NkYiA9IG1lZ2Ffc3VwcG9ydF9leHRfY2RiKGFkYXB0ZXIpOwoJaWYgKGFkYXB0ZXItPnN1cHBvcnRfZXh0X2NkYikKCQlwcmludGsoS0VSTl9OT1RJQ0UgIm1lZ2FyYWlkOiBzdXBwb3J0cyBleHRlbmRlZCBDREJzLlxuIik7CgoKCXJldHVybiAwOwp9CgovKioKICogbWVnYV9ydW5wZW5kcSgpCiAqIEBhZGFwdGVyIC0gcG9pbnRlciB0byBvdXIgc29mdCBzdGF0ZQogKgogKiBSdW5zIHRocm91Z2ggdGhlIGxpc3Qgb2YgcGVuZGluZyByZXF1ZXN0cy4KICovCnN0YXRpYyBpbmxpbmUgdm9pZAptZWdhX3J1bnBlbmRxKGFkYXB0ZXJfdCAqYWRhcHRlcikKewoJaWYoIWxpc3RfZW1wdHkoJmFkYXB0ZXItPnBlbmRpbmdfbGlzdCkpCgkJX19tZWdhX3J1bnBlbmRxKGFkYXB0ZXIpOwp9CgovKgogKiBtZWdhcmFpZF9xdWV1ZSgpCiAqIEBzY21kIC0gSXNzdWUgdGhpcyBzY3NpIGNvbW1hbmQKICogQGRvbmUgLSB0aGUgY2FsbGJhY2sgaG9vayBpbnRvIHRoZSBzY3NpIG1pZC1sYXllcgogKgogKiBUaGUgY29tbWFuZCBxdWV1aW5nIGVudHJ5IHBvaW50IGZvciB0aGUgbWlkLWxheWVyLgogKi8Kc3RhdGljIGludAptZWdhcmFpZF9xdWV1ZShTY3NpX0NtbmQgKnNjbWQsIHZvaWQgKCpkb25lKShTY3NpX0NtbmQgKikpCnsKCWFkYXB0ZXJfdAkqYWRhcHRlcjsKCXNjYl90CSpzY2I7CglpbnQJYnVzeT0wOwoKCWFkYXB0ZXIgPSAoYWRhcHRlcl90ICopc2NtZC0+ZGV2aWNlLT5ob3N0LT5ob3N0ZGF0YTsKCglzY21kLT5zY3NpX2RvbmUgPSBkb25lOwoKCgkvKgoJICogQWxsb2NhdGUgYW5kIGJ1aWxkIGEgU0NCIHJlcXVlc3QKCSAqIGJ1c3kgZmxhZyB3aWxsIGJlIHNldCBpZiBtZWdhX2J1aWxkX2NtZCgpIGNvbW1hbmQgY291bGQgbm90CgkgKiBhbGxvY2F0ZSBzY2IuIFdlIHdpbGwgcmV0dXJuIG5vbi16ZXJvIHN0YXR1cyBpbiB0aGF0IGNhc2UuCgkgKiBOT1RFOiBzY2IgY2FuIGJlIG51bGwgZXZlbiB0aG91Z2ggY2VydGFpbiBjb21tYW5kcyBjb21wbGV0ZWQKCSAqIHN1Y2Nlc3NmdWxseSwgZS5nLiwgTU9ERV9TRU5TRSBhbmQgVEVTVF9VTklUX1JFQURZLCB3ZSB3b3VsZAoJICogcmV0dXJuIDAgaW4gdGhhdCBjYXNlLgoJICovCgoJc2NiID0gbWVnYV9idWlsZF9jbWQoYWRhcHRlciwgc2NtZCwgJmJ1c3kpOwoKCWlmKHNjYikgewoJCXNjYi0+c3RhdGUgfD0gU0NCX1BFTkRROwoJCWxpc3RfYWRkX3RhaWwoJnNjYi0+bGlzdCwgJmFkYXB0ZXItPnBlbmRpbmdfbGlzdCk7CgoJCS8qCgkJICogQ2hlY2sgaWYgdGhlIEhCQSBpcyBpbiBxdWllc2NlbnQgc3RhdGUsIGUuZy4sIGR1cmluZyBhCgkJICogZGVsZXRlIGxvZ2ljYWwgZHJpdmUgb3BlcnRpb24uIElmIGl0IGlzLCBkb24ndCBydW4KCQkgKiB0aGUgcGVuZGluZ19saXN0LgoJCSAqLwoJCWlmKGF0b21pY19yZWFkKCZhZGFwdGVyLT5xdWllc2NlbnQpID09IDApIHsKCQkJbWVnYV9ydW5wZW5kcShhZGFwdGVyKTsKCQl9CgkJcmV0dXJuIDA7Cgl9CgoJcmV0dXJuIGJ1c3k7Cn0KCi8qKgogKiBtZWdhX2FsbG9jYXRlX3NjYigpCiAqIEBhZGFwdGVyIC0gcG9pbnRlciB0byBvdXIgc29mdCBzdGF0ZQogKiBAY21kIC0gc2NzaSBjb21tYW5kIGZyb20gdGhlIG1pZC1sYXllcgogKgogKiBBbGxvY2F0ZSBhIFNDQiBzdHJ1Y3R1cmUuIFRoaXMgaXMgdGhlIGNlbnRyYWwgc3RydWN0dXJlIGZvciBjb250cm9sbGVyCiAqIGNvbW1hbmRzLgogKi8Kc3RhdGljIGlubGluZSBzY2JfdCAqCm1lZ2FfYWxsb2NhdGVfc2NiKGFkYXB0ZXJfdCAqYWRhcHRlciwgU2NzaV9DbW5kICpjbWQpCnsKCXN0cnVjdCBsaXN0X2hlYWQgKmhlYWQgPSAmYWRhcHRlci0+ZnJlZV9saXN0OwoJc2NiX3QJKnNjYjsKCgkvKiBVbmxpbmsgY29tbWFuZCBmcm9tIEZyZWUgTGlzdCAqLwoJaWYoICFsaXN0X2VtcHR5KGhlYWQpICkgewoKCQlzY2IgPSBsaXN0X2VudHJ5KGhlYWQtPm5leHQsIHNjYl90LCBsaXN0KTsKCgkJbGlzdF9kZWxfaW5pdChoZWFkLT5uZXh0KTsKCgkJc2NiLT5zdGF0ZSA9IFNDQl9BQ1RJVkU7CgkJc2NiLT5jbWQgPSBjbWQ7CgkJc2NiLT5kbWFfdHlwZSA9IE1FR0FfRE1BX1RZUEVfTk9ORTsKCgkJcmV0dXJuIHNjYjsKCX0KCglyZXR1cm4gTlVMTDsKfQoKLyoqCiAqIG1lZ2FfZ2V0X2xkcnZfbnVtKCkKICogQGFkYXB0ZXIgLSBwb2ludGVyIHRvIG91ciBzb2Z0IHN0YXRlCiAqIEBjbWQgLSBzY3NpIG1pZCBsYXllciBjb21tYW5kCiAqIEBjaGFubmVsIC0gY2hhbm5lbCBvbiB0aGUgY29udHJvbGxlcgogKgogKiBDYWxjdWxhdGUgdGhlIGxvZ2ljYWwgZHJpdmUgbnVtYmVyIGJhc2VkIG9uIHRoZSBpbmZvcm1hdGlvbiBpbiBzY3NpIGNvbW1hbmQKICogYW5kIHRoZSBjaGFubmVsIG51bWJlci4KICovCnN0YXRpYyBpbmxpbmUgaW50Cm1lZ2FfZ2V0X2xkcnZfbnVtKGFkYXB0ZXJfdCAqYWRhcHRlciwgU2NzaV9DbW5kICpjbWQsIGludCBjaGFubmVsKQp7CglpbnQJCXRndDsKCWludAkJbGRydl9udW07CgoJdGd0ID0gY21kLT5kZXZpY2UtPmlkOwoJCglpZiAoIHRndCA+IGFkYXB0ZXItPnRoaXNfaWQgKQoJCXRndC0tOwkvKiB3ZSBkbyBub3QgZ2V0IGlucXVpcmVzIGZvciBpbml0aWF0b3IgaWQgKi8KCglsZHJ2X251bSA9IChjaGFubmVsICogMTUpICsgdGd0OwoKCgkvKgoJICogSWYgd2UgaGF2ZSBhIGxvZ2ljYWwgZHJpdmUgd2l0aCBib290IGVuYWJsZWQsIHByb2plY3QgaXQgZmlyc3QKCSAqLwoJaWYoIGFkYXB0ZXItPmJvb3RfbGRydl9lbmFibGVkICkgewoJCWlmKCBsZHJ2X251bSA9PSAwICkgewoJCQlsZHJ2X251bSA9IGFkYXB0ZXItPmJvb3RfbGRydjsKCQl9CgkJZWxzZSB7CgkJCWlmKCBsZHJ2X251bSA8PSBhZGFwdGVyLT5ib290X2xkcnYgKSB7CgkJCQlsZHJ2X251bS0tOwoJCQl9CgkJfQoJfQoKCS8qCgkgKiBJZiAiZGVsZXRlIGxvZ2ljYWwgZHJpdmUiIGZlYXR1cmUgaXMgZW5hYmxlZCBvbiB0aGlzIGNvbnRyb2xsZXIuCgkgKiBEbyBvbmx5IGlmIGF0IGxlYXN0IG9uZSBkZWxldGUgbG9naWNhbCBkcml2ZSBvcGVyYXRpb24gd2FzIGRvbmUuCgkgKgoJICogQWxzbywgYWZ0ZXIgbG9naWNhbCBkcml2ZSBkZWxldGlvbiwgaW5zdGVhZCBvZiBsb2dpY2FsIGRyaXZlIG51bWJlciwKCSAqIHRoZSB2YWx1ZSByZXR1cm5lZCBzaG91bGQgYmUgMHg4MCtsb2dpY2FsIGRyaXZlIGlkLgoJICoKCSAqIFRoZXNlIGlzIHZhbGlkIG9ubHkgZm9yIElPIGNvbW1hbmRzLgoJICovCgoJaWYgKGFkYXB0ZXItPnN1cHBvcnRfcmFuZG9tX2RlbCAmJiBhZGFwdGVyLT5yZWFkX2xkaWRtYXAgKQoJCXN3aXRjaCAoY21kLT5jbW5kWzBdKSB7CgkJY2FzZSBSRUFEXzY6CS8qIGZhbGwgdGhyb3VnaCAqLwoJCWNhc2UgV1JJVEVfNjoJLyogZmFsbCB0aHJvdWdoICovCgkJY2FzZSBSRUFEXzEwOgkvKiBmYWxsIHRocm91Z2ggKi8KCQljYXNlIFdSSVRFXzEwOgoJCQlsZHJ2X251bSArPSAweDgwOwoJCX0KCglyZXR1cm4gbGRydl9udW07Cn0KCi8qKgogKiBtZWdhX2J1aWxkX2NtZCgpCiAqIEBhZGFwdGVyIC0gcG9pbnRlciB0byBvdXIgc29mdCBzdGF0ZQogKiBAY21kIC0gUHJlcGFyZSB1c2luZyB0aGlzIHNjc2kgY29tbWFuZAogKiBAYnVzeSAtIGJ1c3kgZmxhZyBpZiBubyByZXNvdXJjZXMKICoKICogUHJlcGFyZXMgYSBjb21tYW5kIGFuZCBzY2F0dGVyIGdhdGhlciBsaXN0IGZvciB0aGUgY29udHJvbGxlci4gVGhpcyByb3V0aW5lCiAqIGFsc28gZmluZHMgb3V0IGlmIHRoZSBjb21tYW5kcyBpcyBpbnRlbmRlZCBmb3IgYSBsb2dpY2FsIGRyaXZlIG9yIGEKICogcGh5c2ljYWwgZGV2aWNlIGFuZCBwcmVwYXJlcyB0aGUgY29udHJvbGxlciBjb21tYW5kIGFjY29yZGluZ2x5LgogKgogKiBXZSBhbHNvIHJlLW9yZGVyIHRoZSBsb2dpY2FsIGRyaXZlcyBhbmQgcGh5c2ljYWwgZGV2aWNlcyBiYXNlZCBvbiB0aGVpcgogKiBib290IHNldHRpbmdzLgogKi8Kc3RhdGljIHNjYl90ICoKbWVnYV9idWlsZF9jbWQoYWRhcHRlcl90ICphZGFwdGVyLCBTY3NpX0NtbmQgKmNtZCwgaW50ICpidXN5KQp7CgltZWdhX2V4dF9wYXNzdGhydQkqZXB0aHJ1OwoJbWVnYV9wYXNzdGhydQkqcHRocnU7CglzY2JfdAkqc2NiOwoJbWJveF90CSptYm94OwoJbG9uZwlzZWc7CgljaGFyCWlzbG9naWNhbDsKCWludAltYXhfbGRydl9udW07CglpbnQJY2hhbm5lbCA9IDA7CglpbnQJdGFyZ2V0ID0gMDsKCWludAlsZHJ2X251bSA9IDA7ICAgLyogbG9naWNhbCBkcml2ZSBudW1iZXIgKi8KCgoJLyoKCSAqIGZpbHRlciB0aGUgaW50ZXJuYWwgYW5kIGlvY3RsIGNvbW1hbmRzCgkgKi8KCWlmKChjbWQtPmNtbmRbMF0gPT0gTUVHQV9JTlRFUk5BTF9DTUQpKSB7CgkJcmV0dXJuIGNtZC0+YnVmZmVyOwoJfQoKCgkvKgoJICogV2Uga25vdyB3aGF0IGNoYW5uZWxzIG91ciBsb2dpY2FsIGRyaXZlcyBhcmUgb24gLSBtZWdhX2ZpbmRfY2FyZCgpCgkgKi8KCWlzbG9naWNhbCA9IGFkYXB0ZXItPmxvZ2Rydl9jaGFuW2NtZC0+ZGV2aWNlLT5jaGFubmVsXTsKCgkvKgoJICogVGhlIHRoZW9yeTogSWYgcGh5c2ljYWwgZHJpdmUgaXMgY2hvc2VuIGZvciBib290LCBhbGwgdGhlIHBoeXNpY2FsCgkgKiBkZXZpY2VzIGFyZSBleHBvcnRlZCBiZWZvcmUgdGhlIGxvZ2ljYWwgZHJpdmVzLCBvdGhlcndpc2UgcGh5c2ljYWwKCSAqIGRldmljZXMgYXJlIHB1c2hlZCBhZnRlciBsb2dpY2FsIGRyaXZlcywgaW4gd2hpY2ggY2FzZSAtIEtlcm5lbCBzZWVzCgkgKiB0aGUgcGh5c2ljYWwgZGV2aWNlcyBvbiB2aXJ0dWFsIGNoYW5uZWwgd2hpY2ggaXMgb2J2aW91c2x5IGNvbnZlcnRlZAoJICogdG8gYWN0dWFsIGNoYW5uZWwgb24gdGhlIEhCQS4KCSAqLwoJaWYoIGFkYXB0ZXItPmJvb3RfcGRydl9lbmFibGVkICkgewoJCWlmKCBpc2xvZ2ljYWwgKSB7CgkJCS8qIGxvZ2ljYWwgY2hhbm5lbCAqLwoJCQljaGFubmVsID0gY21kLT5kZXZpY2UtPmNoYW5uZWwgLQoJCQkJYWRhcHRlci0+cHJvZHVjdF9pbmZvLm5jaGFubmVsczsKCQl9CgkJZWxzZSB7CgkJCS8qIHRoaXMgaXMgcGh5c2ljYWwgY2hhbm5lbCAqLwoJCQljaGFubmVsID0gY21kLT5kZXZpY2UtPmNoYW5uZWw7IAoJCQl0YXJnZXQgPSBjbWQtPmRldmljZS0+aWQ7CgoJCQkvKgoJCQkgKiBib290IGZyb20gYSBwaHlzaWNhbCBkaXNrLCB0aGF0IGRpc2sgbmVlZHMgdG8gYmUKCQkJICogZXhwb3NlZCBmaXJzdCBJRiBib3RoIHRoZSBjaGFubmVscyBhcmUgU0NTSSwgdGhlbgoJCQkgKiBib290aW5nIGZyb20gdGhlIHNlY29uZCBjaGFubmVsIGlzIG5vdCBhbGxvd2VkLgoJCQkgKi8KCQkJaWYoIHRhcmdldCA9PSAwICkgewoJCQkJdGFyZ2V0ID0gYWRhcHRlci0+Ym9vdF9wZHJ2X3RndDsKCQkJfQoJCQllbHNlIGlmKCB0YXJnZXQgPT0gYWRhcHRlci0+Ym9vdF9wZHJ2X3RndCApIHsKCQkJCXRhcmdldCA9IDA7CgkJCX0KCQl9Cgl9CgllbHNlIHsKCQlpZiggaXNsb2dpY2FsICkgewoJCQkvKiB0aGlzIGlzIHRoZSBsb2dpY2FsIGNoYW5uZWwgKi8KCQkJY2hhbm5lbCA9IGNtZC0+ZGV2aWNlLT5jaGFubmVsOwkKCQl9CgkJZWxzZSB7CgkJCS8qIHBoeXNpY2FsIGNoYW5uZWwgKi8KCQkJY2hhbm5lbCA9IGNtZC0+ZGV2aWNlLT5jaGFubmVsIC0gTlZJUlRfQ0hBTjsJCgkJCXRhcmdldCA9IGNtZC0+ZGV2aWNlLT5pZDsKCQl9Cgl9CgoKCWlmKGlzbG9naWNhbCkgewoKCQkvKiBoYXZlIGp1c3QgTFVOIDAgZm9yIGVhY2ggdGFyZ2V0IG9uIHZpcnR1YWwgY2hhbm5lbHMgKi8KCQlpZiAoY21kLT5kZXZpY2UtPmx1bikgewoJCQljbWQtPnJlc3VsdCA9IChESURfQkFEX1RBUkdFVCA8PCAxNik7CgkJCWNtZC0+c2NzaV9kb25lKGNtZCk7CgkJCXJldHVybiBOVUxMOwoJCX0KCgkJbGRydl9udW0gPSBtZWdhX2dldF9sZHJ2X251bShhZGFwdGVyLCBjbWQsIGNoYW5uZWwpOwoKCgkJbWF4X2xkcnZfbnVtID0gKGFkYXB0ZXItPmZsYWcgJiBCT0FSRF80MExEKSA/CgkJCU1BWF9MT0dJQ0FMX0RSSVZFU180MExEIDogTUFYX0xPR0lDQUxfRFJJVkVTXzhMRDsKCgkJLyoKCQkgKiBtYXhfbGRydl9udW0gaW5jcmVhc2VzIGJ5IDB4ODAgaWYgc29tZSBsb2dpY2FsIGRyaXZlIHdhcwoJCSAqIGRlbGV0ZWQuCgkJICovCgkJaWYoYWRhcHRlci0+cmVhZF9sZGlkbWFwKQoJCQltYXhfbGRydl9udW0gKz0gMHg4MDsKCgkJaWYobGRydl9udW0gPiBtYXhfbGRydl9udW0gKSB7CgkJCWNtZC0+cmVzdWx0ID0gKERJRF9CQURfVEFSR0VUIDw8IDE2KTsKCQkJY21kLT5zY3NpX2RvbmUoY21kKTsKCQkJcmV0dXJuIE5VTEw7CgkJfQoKCX0KCWVsc2UgewoJCWlmKCBjbWQtPmRldmljZS0+bHVuID4gNykgewoJCQkvKgoJCQkgKiBEbyBub3Qgc3VwcG9ydCBsdW4gPjcgZm9yIHBoeXNpY2FsbHkgYWNjZXNzZWQKCQkJICogZGV2aWNlcwoJCQkgKi8KCQkJY21kLT5yZXN1bHQgPSAoRElEX0JBRF9UQVJHRVQgPDwgMTYpOwoJCQljbWQtPnNjc2lfZG9uZShjbWQpOwoJCQlyZXR1cm4gTlVMTDsKCQl9Cgl9CgoJLyoKCSAqCgkgKiBMb2dpY2FsIGRyaXZlIGNvbW1hbmRzCgkgKgoJICovCglpZihpc2xvZ2ljYWwpIHsKCQlzd2l0Y2ggKGNtZC0+Y21uZFswXSkgewoJCWNhc2UgVEVTVF9VTklUX1JFQURZOgoJCQltZW1zZXQoY21kLT5yZXF1ZXN0X2J1ZmZlciwgMCwgY21kLT5yZXF1ZXN0X2J1ZmZsZW4pOwoKI2lmIE1FR0FfSEFWRV9DTFVTVEVSSU5HCgkJCS8qCgkJCSAqIERvIHdlIHN1cHBvcnQgY2x1c3RlcmluZyBhbmQgaXMgdGhlIHN1cHBvcnQgZW5hYmxlZAoJCQkgKiBJZiBubywgcmV0dXJuIHN1Y2Nlc3MgYWx3YXlzCgkJCSAqLwoJCQlpZiggIWFkYXB0ZXItPmhhc19jbHVzdGVyICkgewoJCQkJY21kLT5yZXN1bHQgPSAoRElEX09LIDw8IDE2KTsKCQkJCWNtZC0+c2NzaV9kb25lKGNtZCk7CgkJCQlyZXR1cm4gTlVMTDsKCQkJfQoKCQkJaWYoIShzY2IgPSBtZWdhX2FsbG9jYXRlX3NjYihhZGFwdGVyLCBjbWQpKSkgewoJCQkJKmJ1c3kgPSAxOwoJCQkJcmV0dXJuIE5VTEw7CgkJCX0KCgkJCXNjYi0+cmF3X21ib3hbMF0gPSBNRUdBX0NMVVNURVJfQ01EOwoJCQlzY2ItPnJhd19tYm94WzJdID0gTUVHQV9SRVNFUlZBVElPTl9TVEFUVVM7CgkJCXNjYi0+cmF3X21ib3hbM10gPSBsZHJ2X251bTsKCgkJCXNjYi0+ZG1hX2RpcmVjdGlvbiA9IFBDSV9ETUFfTk9ORTsKCgkJCXJldHVybiBzY2I7CiNlbHNlCgkJCWNtZC0+cmVzdWx0ID0gKERJRF9PSyA8PCAxNik7CgkJCWNtZC0+c2NzaV9kb25lKGNtZCk7CgkJCXJldHVybiBOVUxMOwojZW5kaWYKCgkJY2FzZSBNT0RFX1NFTlNFOgoJCQltZW1zZXQoY21kLT5yZXF1ZXN0X2J1ZmZlciwgMCwgY21kLT5jbW5kWzRdKTsKCQkJY21kLT5yZXN1bHQgPSAoRElEX09LIDw8IDE2KTsKCQkJY21kLT5zY3NpX2RvbmUoY21kKTsKCQkJcmV0dXJuIE5VTEw7CgoJCWNhc2UgUkVBRF9DQVBBQ0lUWToKCQljYXNlIElOUVVJUlk6CgoJCQlpZighKGFkYXB0ZXItPmZsYWcgJiAoMUwgPDwgY21kLT5kZXZpY2UtPmNoYW5uZWwpKSkgewoKCQkJCXByaW50ayhLRVJOX05PVElDRQoJCQkJCSJzY3NpJWQ6IHNjYW5uaW5nIHNjc2kgY2hhbm5lbCAlZCAiLAoJCQkJCQlhZGFwdGVyLT5ob3N0LT5ob3N0X25vLAoJCQkJCQljbWQtPmRldmljZS0+Y2hhbm5lbCk7CgkJCQlwcmludGsoImZvciBsb2dpY2FsIGRyaXZlcy5cbiIpOwoKCQkJCWFkYXB0ZXItPmZsYWcgfD0gKDFMIDw8IGNtZC0+ZGV2aWNlLT5jaGFubmVsKTsKCQkJfQoKCQkJLyogQWxsb2NhdGUgYSBTQ0IgYW5kIGluaXRpYWxpemUgcGFzc3RocnUgKi8KCQkJaWYoIShzY2IgPSBtZWdhX2FsbG9jYXRlX3NjYihhZGFwdGVyLCBjbWQpKSkgewoJCQkJKmJ1c3kgPSAxOwoJCQkJcmV0dXJuIE5VTEw7CgkJCX0KCQkJcHRocnUgPSBzY2ItPnB0aHJ1OwoKCQkJbWJveCA9IChtYm94X3QgKilzY2ItPnJhd19tYm94OwoJCQltZW1zZXQobWJveCwgMCwgc2l6ZW9mKHNjYi0+cmF3X21ib3gpKTsKCQkJbWVtc2V0KHB0aHJ1LCAwLCBzaXplb2YobWVnYV9wYXNzdGhydSkpOwoKCQkJcHRocnUtPnRpbWVvdXQgPSAwOwoJCQlwdGhydS0+YXJzID0gMTsKCQkJcHRocnUtPnJlcXNlbnNlbGVuID0gMTQ7CgkJCXB0aHJ1LT5pc2xvZ2ljYWwgPSAxOwoJCQlwdGhydS0+bG9nZHJ2ID0gbGRydl9udW07CgkJCXB0aHJ1LT5jZGJsZW4gPSBjbWQtPmNtZF9sZW47CgkJCW1lbWNweShwdGhydS0+Y2RiLCBjbWQtPmNtbmQsIGNtZC0+Y21kX2xlbik7CgoJCQlpZiggYWRhcHRlci0+aGFzXzY0Yml0X2FkZHIgKSB7CgkJCQltYm94LT5tX291dC5jbWQgPSBNRUdBX01CT1hDTURfUEFTU1RIUlU2NDsKCQkJfQoJCQllbHNlIHsKCQkJCW1ib3gtPm1fb3V0LmNtZCA9IE1FR0FfTUJPWENNRF9QQVNTVEhSVTsKCQkJfQoKCQkJc2NiLT5kbWFfZGlyZWN0aW9uID0gUENJX0RNQV9GUk9NREVWSUNFOwoKCQkJcHRocnUtPm51bXNnZWxlbWVudHMgPSBtZWdhX2J1aWxkX3NnbGlzdChhZGFwdGVyLCBzY2IsCgkJCQkmcHRocnUtPmRhdGF4ZmVyYWRkciwgJnB0aHJ1LT5kYXRheGZlcmxlbik7CgoJCQltYm94LT5tX291dC54ZmVyYWRkciA9IHNjYi0+cHRocnVfZG1hX2FkZHI7CgoJCQlyZXR1cm4gc2NiOwoKCQljYXNlIFJFQURfNjoKCQljYXNlIFdSSVRFXzY6CgkJY2FzZSBSRUFEXzEwOgoJCWNhc2UgV1JJVEVfMTA6CgkJY2FzZSBSRUFEXzEyOgoJCWNhc2UgV1JJVEVfMTI6CgoJCQkvKiBBbGxvY2F0ZSBhIFNDQiBhbmQgaW5pdGlhbGl6ZSBtYWlsYm94ICovCgkJCWlmKCEoc2NiID0gbWVnYV9hbGxvY2F0ZV9zY2IoYWRhcHRlciwgY21kKSkpIHsKCQkJCSpidXN5ID0gMTsKCQkJCXJldHVybiBOVUxMOwoJCQl9CgkJCW1ib3ggPSAobWJveF90ICopc2NiLT5yYXdfbWJveDsKCgkJCW1lbXNldChtYm94LCAwLCBzaXplb2Yoc2NiLT5yYXdfbWJveCkpOwoJCQltYm94LT5tX291dC5sb2dkcnYgPSBsZHJ2X251bTsKCgkJCS8qCgkJCSAqIEEgbGl0dGxlIGhhY2s6IDJuZCBiaXQgaXMgemVybyBmb3IgYWxsIHNjc2kgcmVhZAoJCQkgKiBjb21tYW5kcyBhbmQgaXMgc2V0IGZvciBhbGwgc2NzaSB3cml0ZSBjb21tYW5kcwoJCQkgKi8KCQkJaWYoIGFkYXB0ZXItPmhhc182NGJpdF9hZGRyICkgewoJCQkJbWJveC0+bV9vdXQuY21kID0gKCpjbWQtPmNtbmQgJiAweDAyKSA/CgkJCQkJTUVHQV9NQk9YQ01EX0xXUklURTY0OgoJCQkJCU1FR0FfTUJPWENNRF9MUkVBRDY0IDsKCQkJfQoJCQllbHNlIHsKCQkJCW1ib3gtPm1fb3V0LmNtZCA9ICgqY21kLT5jbW5kICYgMHgwMikgPwoJCQkJCU1FR0FfTUJPWENNRF9MV1JJVEU6CgkJCQkJTUVHQV9NQk9YQ01EX0xSRUFEIDsKCQkJfQoKCQkJLyoKCQkJICogNi1ieXRlIFJFQUQoMHgwOCkgb3IgV1JJVEUoMHgwQSkgY2RiCgkJCSAqLwoJCQlpZiggY21kLT5jbWRfbGVuID09IDYgKSB7CgkJCQltYm94LT5tX291dC5udW1zZWN0b3JzID0gKHUzMikgY21kLT5jbW5kWzRdOwoJCQkJbWJveC0+bV9vdXQubGJhID0KCQkJCQkoKHUzMiljbWQtPmNtbmRbMV0gPDwgMTYpIHwKCQkJCQkoKHUzMiljbWQtPmNtbmRbMl0gPDwgOCkgfAoJCQkJCSh1MzIpY21kLT5jbW5kWzNdOwoKCQkJCW1ib3gtPm1fb3V0LmxiYSAmPSAweDFGRkZGRjsKCiNpZiBNRUdBX0hBVkVfU1RBVFMKCQkJCS8qCgkJCQkgKiBUYWtlIG1vZHVsbyAweDgwLCBzaW5jZSB0aGUgbG9naWNhbCBkcml2ZQoJCQkJICogbnVtYmVyIGluY3JlYXNlcyBieSAweDgwIHdoZW4gYSBsb2dpY2FsCgkJCQkgKiBkcml2ZSB3YXMgZGVsZXRlZAoJCQkJICovCgkJCQlpZiAoKmNtZC0+Y21uZCA9PSBSRUFEXzYpIHsKCQkJCQlhZGFwdGVyLT5ucmVhZHNbbGRydl9udW0lMHg4MF0rKzsKCQkJCQlhZGFwdGVyLT5ucmVhZGJsb2Nrc1tsZHJ2X251bSUweDgwXSArPQoJCQkJCQltYm94LT5tX291dC5udW1zZWN0b3JzOwoJCQkJfSBlbHNlIHsKCQkJCQlhZGFwdGVyLT5ud3JpdGVzW2xkcnZfbnVtJTB4ODBdKys7CgkJCQkJYWRhcHRlci0+bndyaXRlYmxvY2tzW2xkcnZfbnVtJTB4ODBdICs9CgkJCQkJCW1ib3gtPm1fb3V0Lm51bXNlY3RvcnM7CgkJCQl9CiNlbmRpZgoJCQl9CgoJCQkvKgoJCQkgKiAxMC1ieXRlIFJFQUQoMHgyOCkgb3IgV1JJVEUoMHgyQSkgY2RiCgkJCSAqLwoJCQlpZiggY21kLT5jbWRfbGVuID09IDEwICkgewoJCQkJbWJveC0+bV9vdXQubnVtc2VjdG9ycyA9CgkJCQkJKHUzMiljbWQtPmNtbmRbOF0gfAoJCQkJCSgodTMyKWNtZC0+Y21uZFs3XSA8PCA4KTsKCQkJCW1ib3gtPm1fb3V0LmxiYSA9CgkJCQkJKCh1MzIpY21kLT5jbW5kWzJdIDw8IDI0KSB8CgkJCQkJKCh1MzIpY21kLT5jbW5kWzNdIDw8IDE2KSB8CgkJCQkJKCh1MzIpY21kLT5jbW5kWzRdIDw8IDgpIHwKCQkJCQkodTMyKWNtZC0+Y21uZFs1XTsKCiNpZiBNRUdBX0hBVkVfU1RBVFMKCQkJCWlmICgqY21kLT5jbW5kID09IFJFQURfMTApIHsKCQkJCQlhZGFwdGVyLT5ucmVhZHNbbGRydl9udW0lMHg4MF0rKzsKCQkJCQlhZGFwdGVyLT5ucmVhZGJsb2Nrc1tsZHJ2X251bSUweDgwXSArPQoJCQkJCQltYm94LT5tX291dC5udW1zZWN0b3JzOwoJCQkJfSBlbHNlIHsKCQkJCQlhZGFwdGVyLT5ud3JpdGVzW2xkcnZfbnVtJTB4ODBdKys7CgkJCQkJYWRhcHRlci0+bndyaXRlYmxvY2tzW2xkcnZfbnVtJTB4ODBdICs9CgkJCQkJCW1ib3gtPm1fb3V0Lm51bXNlY3RvcnM7CgkJCQl9CiNlbmRpZgoJCQl9CgoJCQkvKgoJCQkgKiAxMi1ieXRlIFJFQUQoMHhBOCkgb3IgV1JJVEUoMHhBQSkgY2RiCgkJCSAqLwoJCQlpZiggY21kLT5jbWRfbGVuID09IDEyICkgewoJCQkJbWJveC0+bV9vdXQubGJhID0KCQkJCQkoKHUzMiljbWQtPmNtbmRbMl0gPDwgMjQpIHwKCQkJCQkoKHUzMiljbWQtPmNtbmRbM10gPDwgMTYpIHwKCQkJCQkoKHUzMiljbWQtPmNtbmRbNF0gPDwgOCkgfAoJCQkJCSh1MzIpY21kLT5jbW5kWzVdOwoKCQkJCW1ib3gtPm1fb3V0Lm51bXNlY3RvcnMgPQoJCQkJCSgodTMyKWNtZC0+Y21uZFs2XSA8PCAyNCkgfAoJCQkJCSgodTMyKWNtZC0+Y21uZFs3XSA8PCAxNikgfAoJCQkJCSgodTMyKWNtZC0+Y21uZFs4XSA8PCA4KSB8CgkJCQkJKHUzMiljbWQtPmNtbmRbOV07CgojaWYgTUVHQV9IQVZFX1NUQVRTCgkJCQlpZiAoKmNtZC0+Y21uZCA9PSBSRUFEXzEyKSB7CgkJCQkJYWRhcHRlci0+bnJlYWRzW2xkcnZfbnVtJTB4ODBdKys7CgkJCQkJYWRhcHRlci0+bnJlYWRibG9ja3NbbGRydl9udW0lMHg4MF0gKz0KCQkJCQkJbWJveC0+bV9vdXQubnVtc2VjdG9yczsKCQkJCX0gZWxzZSB7CgkJCQkJYWRhcHRlci0+bndyaXRlc1tsZHJ2X251bSUweDgwXSsrOwoJCQkJCWFkYXB0ZXItPm53cml0ZWJsb2Nrc1tsZHJ2X251bSUweDgwXSArPQoJCQkJCQltYm94LT5tX291dC5udW1zZWN0b3JzOwoJCQkJfQojZW5kaWYKCQkJfQoKCQkJLyoKCQkJICogSWYgaXQgaXMgYSByZWFkIGNvbW1hbmQKCQkJICovCgkJCWlmKCAoKmNtZC0+Y21uZCAmIDB4MEYpID09IDB4MDggKSB7CgkJCQlzY2ItPmRtYV9kaXJlY3Rpb24gPSBQQ0lfRE1BX0ZST01ERVZJQ0U7CgkJCX0KCQkJZWxzZSB7CgkJCQlzY2ItPmRtYV9kaXJlY3Rpb24gPSBQQ0lfRE1BX1RPREVWSUNFOwoJCQl9CgoJCQkvKiBDYWxjdWxhdGUgU2NhdHRlci1HYXRoZXIgaW5mbyAqLwoJCQltYm94LT5tX291dC5udW1zZ2VsZW1lbnRzID0gbWVnYV9idWlsZF9zZ2xpc3QoYWRhcHRlciwgc2NiLAoJCQkJCSh1MzIgKikmbWJveC0+bV9vdXQueGZlcmFkZHIsICh1MzIgKikmc2VnKTsKCgkJCXJldHVybiBzY2I7CgojaWYgTUVHQV9IQVZFX0NMVVNURVJJTkcKCQljYXNlIFJFU0VSVkU6CS8qIEZhbGwgdGhyb3VnaCAqLwoJCWNhc2UgUkVMRUFTRToKCgkJCS8qCgkJCSAqIERvIHdlIHN1cHBvcnQgY2x1c3RlcmluZyBhbmQgaXMgdGhlIHN1cHBvcnQgZW5hYmxlZAoJCQkgKi8KCQkJaWYoICEgYWRhcHRlci0+aGFzX2NsdXN0ZXIgKSB7CgoJCQkJY21kLT5yZXN1bHQgPSAoRElEX0JBRF9UQVJHRVQgPDwgMTYpOwoJCQkJY21kLT5zY3NpX2RvbmUoY21kKTsKCQkJCXJldHVybiBOVUxMOwoJCQl9CgoJCQkvKiBBbGxvY2F0ZSBhIFNDQiBhbmQgaW5pdGlhbGl6ZSBtYWlsYm94ICovCgkJCWlmKCEoc2NiID0gbWVnYV9hbGxvY2F0ZV9zY2IoYWRhcHRlciwgY21kKSkpIHsKCQkJCSpidXN5ID0gMTsKCQkJCXJldHVybiBOVUxMOwoJCQl9CgoJCQlzY2ItPnJhd19tYm94WzBdID0gTUVHQV9DTFVTVEVSX0NNRDsKCQkJc2NiLT5yYXdfbWJveFsyXSA9ICggKmNtZC0+Y21uZCA9PSBSRVNFUlZFICkgPwoJCQkJTUVHQV9SRVNFUlZFX0xEIDogTUVHQV9SRUxFQVNFX0xEOwoKCQkJc2NiLT5yYXdfbWJveFszXSA9IGxkcnZfbnVtOwoKCQkJc2NiLT5kbWFfZGlyZWN0aW9uID0gUENJX0RNQV9OT05FOwoKCQkJcmV0dXJuIHNjYjsKI2VuZGlmCgoJCWRlZmF1bHQ6CgkJCWNtZC0+cmVzdWx0ID0gKERJRF9CQURfVEFSR0VUIDw8IDE2KTsKCQkJY21kLT5zY3NpX2RvbmUoY21kKTsKCQkJcmV0dXJuIE5VTEw7CgkJfQoJfQoKCS8qCgkgKiBQYXNzdGhydSBkcml2ZSBjb21tYW5kcwoJICovCgllbHNlIHsKCQkvKiBBbGxvY2F0ZSBhIFNDQiBhbmQgaW5pdGlhbGl6ZSBwYXNzdGhydSAqLwoJCWlmKCEoc2NiID0gbWVnYV9hbGxvY2F0ZV9zY2IoYWRhcHRlciwgY21kKSkpIHsKCQkJKmJ1c3kgPSAxOwoJCQlyZXR1cm4gTlVMTDsKCQl9CgoJCW1ib3ggPSAobWJveF90ICopc2NiLT5yYXdfbWJveDsKCQltZW1zZXQobWJveCwgMCwgc2l6ZW9mKHNjYi0+cmF3X21ib3gpKTsKCgkJaWYoIGFkYXB0ZXItPnN1cHBvcnRfZXh0X2NkYiApIHsKCgkJCWVwdGhydSA9IG1lZ2FfcHJlcGFyZV9leHRwYXNzdGhydShhZGFwdGVyLCBzY2IsIGNtZCwKCQkJCQljaGFubmVsLCB0YXJnZXQpOwoKCQkJbWJveC0+bV9vdXQuY21kID0gTUVHQV9NQk9YQ01EX0VYVFBUSFJVOwoKCQkJbWJveC0+bV9vdXQueGZlcmFkZHIgPSBzY2ItPmVwdGhydV9kbWFfYWRkcjsKCgkJfQoJCWVsc2UgewoKCQkJcHRocnUgPSBtZWdhX3ByZXBhcmVfcGFzc3RocnUoYWRhcHRlciwgc2NiLCBjbWQsCgkJCQkJY2hhbm5lbCwgdGFyZ2V0KTsKCgkJCS8qIEluaXRpYWxpemUgbWFpbGJveCAqLwoJCQlpZiggYWRhcHRlci0+aGFzXzY0Yml0X2FkZHIgKSB7CgkJCQltYm94LT5tX291dC5jbWQgPSBNRUdBX01CT1hDTURfUEFTU1RIUlU2NDsKCQkJfQoJCQllbHNlIHsKCQkJCW1ib3gtPm1fb3V0LmNtZCA9IE1FR0FfTUJPWENNRF9QQVNTVEhSVTsKCQkJfQoKCQkJbWJveC0+bV9vdXQueGZlcmFkZHIgPSBzY2ItPnB0aHJ1X2RtYV9hZGRyOwoKCQl9CgkJcmV0dXJuIHNjYjsKCX0KCXJldHVybiBOVUxMOwp9CgoKLyoqCiAqIG1lZ2FfcHJlcGFyZV9wYXNzdGhydSgpCiAqIEBhZGFwdGVyIC0gcG9pbnRlciB0byBvdXIgc29mdCBzdGF0ZQogKiBAc2NiIC0gb3VyIHNjc2kgY29udHJvbCBibG9jawogKiBAY21kIC0gc2NzaSBjb21tYW5kIGZyb20gdGhlIG1pZC1sYXllcgogKiBAY2hhbm5lbCAtIGFjdHVhbCBjaGFubmVsIG9uIHRoZSBjb250cm9sbGVyCiAqIEB0YXJnZXQgLSBhY3R1YWwgaWQgb24gdGhlIGNvbnRyb2xsZXIuCiAqCiAqIHByZXBhcmUgYSBjb21tYW5kIGZvciB0aGUgc2NzaSBwaHlzaWNhbCBkZXZpY2VzLgogKi8Kc3RhdGljIG1lZ2FfcGFzc3RocnUgKgptZWdhX3ByZXBhcmVfcGFzc3RocnUoYWRhcHRlcl90ICphZGFwdGVyLCBzY2JfdCAqc2NiLCBTY3NpX0NtbmQgKmNtZCwKCQlpbnQgY2hhbm5lbCwgaW50IHRhcmdldCkKewoJbWVnYV9wYXNzdGhydSAqcHRocnU7CgoJcHRocnUgPSBzY2ItPnB0aHJ1OwoJbWVtc2V0KHB0aHJ1LCAwLCBzaXplb2YgKG1lZ2FfcGFzc3RocnUpKTsKCgkvKiAwPTZzZWMvMT02MHNlYy8yPTEwbWluLzM9M2hycyAqLwoJcHRocnUtPnRpbWVvdXQgPSAyOwoKCXB0aHJ1LT5hcnMgPSAxOwoJcHRocnUtPnJlcXNlbnNlbGVuID0gMTQ7CglwdGhydS0+aXNsb2dpY2FsID0gMDsKCglwdGhydS0+Y2hhbm5lbCA9IChhZGFwdGVyLT5mbGFnICYgQk9BUkRfNDBMRCkgPyAwIDogY2hhbm5lbDsKCglwdGhydS0+dGFyZ2V0ID0gKGFkYXB0ZXItPmZsYWcgJiBCT0FSRF80MExEKSA/CgkJKGNoYW5uZWwgPDwgNCkgfCB0YXJnZXQgOiB0YXJnZXQ7CgoJcHRocnUtPmNkYmxlbiA9IGNtZC0+Y21kX2xlbjsKCXB0aHJ1LT5sb2dkcnYgPSBjbWQtPmRldmljZS0+bHVuOwoKCW1lbWNweShwdGhydS0+Y2RiLCBjbWQtPmNtbmQsIGNtZC0+Y21kX2xlbik7CgoJLyogTm90IHN1cmUgYWJvdXQgdGhlIGRpcmVjdGlvbiAqLwoJc2NiLT5kbWFfZGlyZWN0aW9uID0gUENJX0RNQV9CSURJUkVDVElPTkFMOwoKCS8qIFNwZWNpYWwgQ29kZSBmb3IgSGFuZGxpbmcgUkVBRF9DQVBBLyBJTlEgdXNpbmcgYm91bmNlIGJ1ZmZlcnMgKi8KCXN3aXRjaCAoY21kLT5jbW5kWzBdKSB7CgljYXNlIElOUVVJUlk6CgljYXNlIFJFQURfQ0FQQUNJVFk6CgkJaWYoIShhZGFwdGVyLT5mbGFnICYgKDFMIDw8IGNtZC0+ZGV2aWNlLT5jaGFubmVsKSkpIHsKCgkJCXByaW50ayhLRVJOX05PVElDRQoJCQkJInNjc2klZDogc2Nhbm5pbmcgc2NzaSBjaGFubmVsICVkIFtQJWRdICIsCgkJCQkJYWRhcHRlci0+aG9zdC0+aG9zdF9ubywKCQkJCQljbWQtPmRldmljZS0+Y2hhbm5lbCwgY2hhbm5lbCk7CgkJCXByaW50aygiZm9yIHBoeXNpY2FsIGRldmljZXMuXG4iKTsKCgkJCWFkYXB0ZXItPmZsYWcgfD0gKDFMIDw8IGNtZC0+ZGV2aWNlLT5jaGFubmVsKTsKCQl9CgkJLyogRmFsbCB0aHJvdWdoICovCglkZWZhdWx0OgoJCXB0aHJ1LT5udW1zZ2VsZW1lbnRzID0gbWVnYV9idWlsZF9zZ2xpc3QoYWRhcHRlciwgc2NiLAoJCQkJJnB0aHJ1LT5kYXRheGZlcmFkZHIsICZwdGhydS0+ZGF0YXhmZXJsZW4pOwoJCWJyZWFrOwoJfQoJcmV0dXJuIHB0aHJ1Owp9CgoKLyoqCiAqIG1lZ2FfcHJlcGFyZV9leHRwYXNzdGhydSgpCiAqIEBhZGFwdGVyIC0gcG9pbnRlciB0byBvdXIgc29mdCBzdGF0ZQogKiBAc2NiIC0gb3VyIHNjc2kgY29udHJvbCBibG9jawogKiBAY21kIC0gc2NzaSBjb21tYW5kIGZyb20gdGhlIG1pZC1sYXllcgogKiBAY2hhbm5lbCAtIGFjdHVhbCBjaGFubmVsIG9uIHRoZSBjb250cm9sbGVyCiAqIEB0YXJnZXQgLSBhY3R1YWwgaWQgb24gdGhlIGNvbnRyb2xsZXIuCiAqCiAqIHByZXBhcmUgYSBjb21tYW5kIGZvciB0aGUgc2NzaSBwaHlzaWNhbCBkZXZpY2VzLiBUaGlzIHJvdW50aW5lIHByZXBhcmVzCiAqIGNvbW1hbmRzIGZvciBkZXZpY2VzIHdoaWNoIGNhbiB0YWtlIGV4dGVuZGVkIENEQnMgKD4xMCBieXRlcykKICovCnN0YXRpYyBtZWdhX2V4dF9wYXNzdGhydSAqCm1lZ2FfcHJlcGFyZV9leHRwYXNzdGhydShhZGFwdGVyX3QgKmFkYXB0ZXIsIHNjYl90ICpzY2IsIFNjc2lfQ21uZCAqY21kLAoJCWludCBjaGFubmVsLCBpbnQgdGFyZ2V0KQp7CgltZWdhX2V4dF9wYXNzdGhydQkqZXB0aHJ1OwoKCWVwdGhydSA9IHNjYi0+ZXB0aHJ1OwoJbWVtc2V0KGVwdGhydSwgMCwgc2l6ZW9mKG1lZ2FfZXh0X3Bhc3N0aHJ1KSk7CgoJLyogMD02c2VjLzE9NjBzZWMvMj0xMG1pbi8zPTNocnMgKi8KCWVwdGhydS0+dGltZW91dCA9IDI7CgoJZXB0aHJ1LT5hcnMgPSAxOwoJZXB0aHJ1LT5yZXFzZW5zZWxlbiA9IDE0OwoJZXB0aHJ1LT5pc2xvZ2ljYWwgPSAwOwoKCWVwdGhydS0+Y2hhbm5lbCA9IChhZGFwdGVyLT5mbGFnICYgQk9BUkRfNDBMRCkgPyAwIDogY2hhbm5lbDsKCWVwdGhydS0+dGFyZ2V0ID0gKGFkYXB0ZXItPmZsYWcgJiBCT0FSRF80MExEKSA/CgkJKGNoYW5uZWwgPDwgNCkgfCB0YXJnZXQgOiB0YXJnZXQ7CgoJZXB0aHJ1LT5jZGJsZW4gPSBjbWQtPmNtZF9sZW47CgllcHRocnUtPmxvZ2RydiA9IGNtZC0+ZGV2aWNlLT5sdW47CgoJbWVtY3B5KGVwdGhydS0+Y2RiLCBjbWQtPmNtbmQsIGNtZC0+Y21kX2xlbik7CgoJLyogTm90IHN1cmUgYWJvdXQgdGhlIGRpcmVjdGlvbiAqLwoJc2NiLT5kbWFfZGlyZWN0aW9uID0gUENJX0RNQV9CSURJUkVDVElPTkFMOwoKCXN3aXRjaChjbWQtPmNtbmRbMF0pIHsKCWNhc2UgSU5RVUlSWToKCWNhc2UgUkVBRF9DQVBBQ0lUWToKCQlpZighKGFkYXB0ZXItPmZsYWcgJiAoMUwgPDwgY21kLT5kZXZpY2UtPmNoYW5uZWwpKSkgewoKCQkJcHJpbnRrKEtFUk5fTk9USUNFCgkJCQkic2NzaSVkOiBzY2FubmluZyBzY3NpIGNoYW5uZWwgJWQgW1AlZF0gIiwKCQkJCQlhZGFwdGVyLT5ob3N0LT5ob3N0X25vLAoJCQkJCWNtZC0+ZGV2aWNlLT5jaGFubmVsLCBjaGFubmVsKTsKCQkJcHJpbnRrKCJmb3IgcGh5c2ljYWwgZGV2aWNlcy5cbiIpOwoKCQkJYWRhcHRlci0+ZmxhZyB8PSAoMUwgPDwgY21kLT5kZXZpY2UtPmNoYW5uZWwpOwoJCX0KCQkvKiBGYWxsIHRocm91Z2ggKi8KCWRlZmF1bHQ6CgkJZXB0aHJ1LT5udW1zZ2VsZW1lbnRzID0gbWVnYV9idWlsZF9zZ2xpc3QoYWRhcHRlciwgc2NiLAoJCQkJJmVwdGhydS0+ZGF0YXhmZXJhZGRyLCAmZXB0aHJ1LT5kYXRheGZlcmxlbik7CgkJYnJlYWs7Cgl9CgoJcmV0dXJuIGVwdGhydTsKfQoKc3RhdGljIHZvaWQKX19tZWdhX3J1bnBlbmRxKGFkYXB0ZXJfdCAqYWRhcHRlcikKewoJc2NiX3QgKnNjYjsKCXN0cnVjdCBsaXN0X2hlYWQgKnBvcywgKm5leHQ7CgoJLyogSXNzdWUgYW55IHBlbmRpbmcgY29tbWFuZHMgdG8gdGhlIGNhcmQgKi8KCWxpc3RfZm9yX2VhY2hfc2FmZShwb3MsIG5leHQsICZhZGFwdGVyLT5wZW5kaW5nX2xpc3QpIHsKCgkJc2NiID0gbGlzdF9lbnRyeShwb3MsIHNjYl90LCBsaXN0KTsKCgkJaWYoICEoc2NiLT5zdGF0ZSAmIFNDQl9JU1NVRUQpICkgewoKCQkJaWYoIGlzc3VlX3NjYihhZGFwdGVyLCBzY2IpICE9IDAgKQoJCQkJcmV0dXJuOwoJCX0KCX0KCglyZXR1cm47Cn0KCgovKioKICogaXNzdWVfc2NiKCkKICogQGFkYXB0ZXIgLSBwb2ludGVyIHRvIG91ciBzb2Z0IHN0YXRlCiAqIEBzY2IgLSBzY3NpIGNvbnRyb2wgYmxvY2sKICoKICogUG9zdCBhIGNvbW1hbmQgdG8gdGhlIGNhcmQgaWYgdGhlIG1haWxib3ggaXMgYXZhaWxhYmxlLCBvdGhlcndpc2UgcmV0dXJuCiAqIGJ1c3kuIFdlIGFsc28gdGFrZSB0aGUgc2NiIGZyb20gdGhlIHBlbmRpbmcgbGlzdCBpZiB0aGUgbWFpbGJveCBpcwogKiBhdmFpbGFibGUuCiAqLwpzdGF0aWMgaW50Cmlzc3VlX3NjYihhZGFwdGVyX3QgKmFkYXB0ZXIsIHNjYl90ICpzY2IpCnsKCXZvbGF0aWxlIG1ib3g2NF90CSptYm94NjQgPSBhZGFwdGVyLT5tYm94NjQ7Cgl2b2xhdGlsZSBtYm94X3QJCSptYm94ID0gYWRhcHRlci0+bWJveDsKCXVuc2lnbmVkIGludAlpID0gMDsKCglpZih1bmxpa2VseShtYm94LT5tX2luLmJ1c3kpKSB7CgkJZG8gewoJCQl1ZGVsYXkoMSk7CgkJCWkrKzsKCQl9IHdoaWxlKCBtYm94LT5tX2luLmJ1c3kgJiYgKGkgPCBtYXhfbWJveF9idXN5X3dhaXQpICk7CgoJCWlmKG1ib3gtPm1faW4uYnVzeSkgcmV0dXJuIC0xOwoJfQoKCS8qIENvcHkgbWFpbGJveCBkYXRhIGludG8gaG9zdCBzdHJ1Y3R1cmUgKi8KCW1lbWNweSgoY2hhciAqKSZtYm94LT5tX291dCwgKGNoYXIgKilzY2ItPnJhd19tYm94LCAKCQkJc2l6ZW9mKHN0cnVjdCBtYm94X291dCkpOwoKCW1ib3gtPm1fb3V0LmNtZGlkID0gc2NiLT5pZHg7CS8qIFNldCBjbWRpZCAqLwoJbWJveC0+bV9pbi5idXN5ID0gMTsJCS8qIFNldCBidXN5ICovCgoKCS8qCgkgKiBJbmNyZW1lbnQgdGhlIHBlbmRpbmcgcXVldWUgY291bnRlcgoJICovCglhdG9taWNfaW5jKCZhZGFwdGVyLT5wZW5kX2NtZHMpOwoKCXN3aXRjaCAobWJveC0+bV9vdXQuY21kKSB7CgljYXNlIE1FR0FfTUJPWENNRF9MUkVBRDY0OgoJY2FzZSBNRUdBX01CT1hDTURfTFdSSVRFNjQ6CgljYXNlIE1FR0FfTUJPWENNRF9QQVNTVEhSVTY0OgoJY2FzZSBNRUdBX01CT1hDTURfRVhUUFRIUlU6CgkJbWJveDY0LT54ZmVyX3NlZ21lbnRfbG8gPSBtYm94LT5tX291dC54ZmVyYWRkcjsKCQltYm94NjQtPnhmZXJfc2VnbWVudF9oaSA9IDA7CgkJbWJveC0+bV9vdXQueGZlcmFkZHIgPSAweEZGRkZGRkZGOwoJCWJyZWFrOwoJZGVmYXVsdDoKCQltYm94NjQtPnhmZXJfc2VnbWVudF9sbyA9IDA7CgkJbWJveDY0LT54ZmVyX3NlZ21lbnRfaGkgPSAwOwoJfQoKCS8qCgkgKiBwb3N0IHRoZSBjb21tYW5kCgkgKi8KCXNjYi0+c3RhdGUgfD0gU0NCX0lTU1VFRDsKCglpZiggbGlrZWx5KGFkYXB0ZXItPmZsYWcgJiBCT0FSRF9NRU1NQVApICkgewoJCW1ib3gtPm1faW4ucG9sbCA9IDA7CgkJbWJveC0+bV9pbi5hY2sgPSAwOwoJCVdSSU5ET09SKGFkYXB0ZXIsIGFkYXB0ZXItPm1ib3hfZG1hIHwgMHgxKTsKCX0KCWVsc2UgewoJCWlycV9lbmFibGUoYWRhcHRlcik7CgkJaXNzdWVfY29tbWFuZChhZGFwdGVyKTsKCX0KCglyZXR1cm4gMDsKfQoKLyoKICogV2FpdCB1bnRpbCB0aGUgY29udHJvbGxlcidzIG1haWxib3ggaXMgYXZhaWxhYmxlCiAqLwpzdGF0aWMgaW5saW5lIGludAptZWdhX2J1c3l3YWl0X21ib3ggKGFkYXB0ZXJfdCAqYWRhcHRlcikKewoJaWYgKGFkYXB0ZXItPm1ib3gtPm1faW4uYnVzeSkKCQlyZXR1cm4gX19tZWdhX2J1c3l3YWl0X21ib3goYWRhcHRlcik7CglyZXR1cm4gMDsKfQoKLyoqCiAqIGlzc3VlX3NjYl9ibG9jaygpCiAqIEBhZGFwdGVyIC0gcG9pbnRlciB0byBvdXIgc29mdCBzdGF0ZQogKiBAcmF3X21ib3ggLSB0aGUgbWFpbGJveAogKgogKiBJc3N1ZSBhIHNjYiBpbiBzeW5jaHJvbm91cyBhbmQgbm9uLWludGVycnVwdCBtb2RlCiAqLwpzdGF0aWMgaW50Cmlzc3VlX3NjYl9ibG9jayhhZGFwdGVyX3QgKmFkYXB0ZXIsIHVfY2hhciAqcmF3X21ib3gpCnsKCXZvbGF0aWxlIG1ib3g2NF90ICptYm94NjQgPSBhZGFwdGVyLT5tYm94NjQ7Cgl2b2xhdGlsZSBtYm94X3QgKm1ib3ggPSBhZGFwdGVyLT5tYm94OwoJdTgJYnl0ZTsKCgkvKiBXYWl0IHVudGlsIG1haWxib3ggaXMgZnJlZSAqLwoJaWYobWVnYV9idXN5d2FpdF9tYm94IChhZGFwdGVyKSkKCQlnb3RvIGJ1Z19ibG9ja2VkX21haWxib3g7CgoJLyogQ29weSBtYWlsYm94IGRhdGEgaW50byBob3N0IHN0cnVjdHVyZSAqLwoJbWVtY3B5KChjaGFyICopIG1ib3gsIHJhd19tYm94LCBzaXplb2Yoc3RydWN0IG1ib3hfb3V0KSk7CgltYm94LT5tX291dC5jbWRpZCA9IDB4RkU7CgltYm94LT5tX2luLmJ1c3kgPSAxOwoKCXN3aXRjaCAocmF3X21ib3hbMF0pIHsKCWNhc2UgTUVHQV9NQk9YQ01EX0xSRUFENjQ6CgljYXNlIE1FR0FfTUJPWENNRF9MV1JJVEU2NDoKCWNhc2UgTUVHQV9NQk9YQ01EX1BBU1NUSFJVNjQ6CgljYXNlIE1FR0FfTUJPWENNRF9FWFRQVEhSVToKCQltYm94NjQtPnhmZXJfc2VnbWVudF9sbyA9IG1ib3gtPm1fb3V0LnhmZXJhZGRyOwoJCW1ib3g2NC0+eGZlcl9zZWdtZW50X2hpID0gMDsKCQltYm94LT5tX291dC54ZmVyYWRkciA9IDB4RkZGRkZGRkY7CgkJYnJlYWs7CglkZWZhdWx0OgoJCW1ib3g2NC0+eGZlcl9zZWdtZW50X2xvID0gMDsKCQltYm94NjQtPnhmZXJfc2VnbWVudF9oaSA9IDA7Cgl9CgoJaWYoIGxpa2VseShhZGFwdGVyLT5mbGFnICYgQk9BUkRfTUVNTUFQKSApIHsKCQltYm94LT5tX2luLnBvbGwgPSAwOwoJCW1ib3gtPm1faW4uYWNrID0gMDsKCQltYm94LT5tX2luLm51bXN0YXR1cyA9IDB4RkY7CgkJbWJveC0+bV9pbi5zdGF0dXMgPSAweEZGOwoJCVdSSU5ET09SKGFkYXB0ZXIsIGFkYXB0ZXItPm1ib3hfZG1hIHwgMHgxKTsKCgkJd2hpbGUoKHZvbGF0aWxlIHU4KW1ib3gtPm1faW4ubnVtc3RhdHVzID09IDB4RkYpCgkJCWNwdV9yZWxheCgpOwoKCQltYm94LT5tX2luLm51bXN0YXR1cyA9IDB4RkY7CgoJCXdoaWxlKCAodm9sYXRpbGUgdTgpbWJveC0+bV9pbi5wb2xsICE9IDB4NzcgKQoJCQljcHVfcmVsYXgoKTsKCgkJbWJveC0+bV9pbi5wb2xsID0gMDsKCQltYm94LT5tX2luLmFjayA9IDB4Nzc7CgoJCVdSSU5ET09SKGFkYXB0ZXIsIGFkYXB0ZXItPm1ib3hfZG1hIHwgMHgyKTsKCgkJd2hpbGUoUkRJTkRPT1IoYWRhcHRlcikgJiAweDIpCgkJCWNwdV9yZWxheCgpOwoJfQoJZWxzZSB7CgkJaXJxX2Rpc2FibGUoYWRhcHRlcik7CgkJaXNzdWVfY29tbWFuZChhZGFwdGVyKTsKCgkJd2hpbGUgKCEoKGJ5dGUgPSBpcnFfc3RhdGUoYWRhcHRlcikpICYgSU5UUl9WQUxJRCkpCgkJCWNwdV9yZWxheCgpOwoKCQlzZXRfaXJxX3N0YXRlKGFkYXB0ZXIsIGJ5dGUpOwoJCWlycV9lbmFibGUoYWRhcHRlcik7CgkJaXJxX2FjayhhZGFwdGVyKTsKCX0KCglyZXR1cm4gbWJveC0+bV9pbi5zdGF0dXM7CgpidWdfYmxvY2tlZF9tYWlsYm94OgoJcHJpbnRrKEtFUk5fV0FSTklORyAibWVnYXJhaWQ6IEJsb2NrZWQgbWFpbGJveC4uLi4uLiEhXG4iKTsKCXVkZWxheSAoMTAwMCk7CglyZXR1cm4gLTE7Cn0KCgovKioKICogbWVnYXJhaWRfaXNyX2lvbWFwcGVkKCkKICogQGlycSAtIGlycQogKiBAZGV2cCAtIHBvaW50ZXIgdG8gb3VyIHNvZnQgc3RhdGUKICogQHJlZ3MgLSB1bnVzZWQKICoKICogSW50ZXJydXB0IHNlcnZpY2Ugcm91dGluZSBmb3IgaW8tbWFwcGVkIGNvbnRyb2xsZXJzLgogKiBGaW5kIG91dCBpZiBvdXIgZGV2aWNlIGlzIGludGVycnVwdGluZy4gSWYgeWVzLCBhY2tub3dsZWRnZSB0aGUgaW50ZXJydXB0CiAqIGFuZCBzZXJ2aWNlIHRoZSBjb21wbGV0ZWQgY29tbWFuZHMuCiAqLwpzdGF0aWMgaXJxcmV0dXJuX3QKbWVnYXJhaWRfaXNyX2lvbWFwcGVkKGludCBpcnEsIHZvaWQgKmRldnAsIHN0cnVjdCBwdF9yZWdzICpyZWdzKQp7CglhZGFwdGVyX3QJKmFkYXB0ZXIgPSBkZXZwOwoJdW5zaWduZWQgbG9uZwlmbGFnczsKCXU4CXN0YXR1czsKCXU4CW5zdGF0dXM7Cgl1OAljb21wbGV0ZWRbTUFYX0ZJUk1XQVJFX1NUQVRVU107Cgl1OAlieXRlOwoJaW50CWhhbmRsZWQgPSAwOwoKCgkvKgoJICogbG9vcCB0aWxsIEYvVyBoYXMgbW9yZSBjb21tYW5kcyBmb3IgdXMgdG8gY29tcGxldGUuCgkgKi8KCXNwaW5fbG9ja19pcnFzYXZlKCZhZGFwdGVyLT5sb2NrLCBmbGFncyk7CgoJZG8gewoJCS8qIENoZWNrIGlmIGEgdmFsaWQgaW50ZXJydXB0IGlzIHBlbmRpbmcgKi8KCQlieXRlID0gaXJxX3N0YXRlKGFkYXB0ZXIpOwoJCWlmKCAoYnl0ZSAmIFZBTElEX0lOVFJfQllURSkgPT0gMCApIHsKCQkJLyoKCQkJICogTm8gbW9yZSBwZW5kaW5nIGNvbW1hbmRzCgkJCSAqLwoJCQlnb3RvIG91dF91bmxvY2s7CgkJfQoJCXNldF9pcnFfc3RhdGUoYWRhcHRlciwgYnl0ZSk7CgoJCXdoaWxlKChuc3RhdHVzID0gKHZvbGF0aWxlIHU4KWFkYXB0ZXItPm1ib3gtPm1faW4ubnVtc3RhdHVzKQoJCQkJPT0gMHhGRikKCQkJY3B1X3JlbGF4KCk7CgkJYWRhcHRlci0+bWJveC0+bV9pbi5udW1zdGF0dXMgPSAweEZGOwoKCQlzdGF0dXMgPSBhZGFwdGVyLT5tYm94LT5tX2luLnN0YXR1czsKCgkJLyoKCQkgKiBkZWNyZW1lbnQgdGhlIHBlbmRpbmcgcXVldWUgY291bnRlcgoJCSAqLwoJCWF0b21pY19zdWIobnN0YXR1cywgJmFkYXB0ZXItPnBlbmRfY21kcyk7CgoJCW1lbWNweShjb21wbGV0ZWQsICh2b2lkICopYWRhcHRlci0+bWJveC0+bV9pbi5jb21wbGV0ZWQsIAoJCQkJbnN0YXR1cyk7CgoJCS8qIEFja25vd2xlZGdlIGludGVycnVwdCAqLwoJCWlycV9hY2soYWRhcHRlcik7CgoJCW1lZ2FfY21kX2RvbmUoYWRhcHRlciwgY29tcGxldGVkLCBuc3RhdHVzLCBzdGF0dXMpOwoKCQltZWdhX3J1bmRvbmVxKGFkYXB0ZXIpOwoKCQloYW5kbGVkID0gMTsKCgkJLyogTG9vcCB0aHJvdWdoIGFueSBwZW5kaW5nIHJlcXVlc3RzICovCgkJaWYoYXRvbWljX3JlYWQoJmFkYXB0ZXItPnF1aWVzY2VudCkgPT0gMCkgewoJCQltZWdhX3J1bnBlbmRxKGFkYXB0ZXIpOwoJCX0KCgl9IHdoaWxlKDEpOwoKIG91dF91bmxvY2s6CgoJc3Bpbl91bmxvY2tfaXJxcmVzdG9yZSgmYWRhcHRlci0+bG9jaywgZmxhZ3MpOwoKCXJldHVybiBJUlFfUkVUVkFMKGhhbmRsZWQpOwp9CgoKLyoqCiAqIG1lZ2FyYWlkX2lzcl9tZW1tYXBwZWQoKQogKiBAaXJxIC0gaXJxCiAqIEBkZXZwIC0gcG9pbnRlciB0byBvdXIgc29mdCBzdGF0ZQogKiBAcmVncyAtIHVudXNlZAogKgogKiBJbnRlcnJ1cHQgc2VydmljZSByb3V0aW5lIGZvciBtZW1vcnktbWFwcGVkIGNvbnRyb2xsZXJzLgogKiBGaW5kIG91dCBpZiBvdXIgZGV2aWNlIGlzIGludGVycnVwdGluZy4gSWYgeWVzLCBhY2tub3dsZWRnZSB0aGUgaW50ZXJydXB0CiAqIGFuZCBzZXJ2aWNlIHRoZSBjb21wbGV0ZWQgY29tbWFuZHMuCiAqLwpzdGF0aWMgaXJxcmV0dXJuX3QKbWVnYXJhaWRfaXNyX21lbW1hcHBlZChpbnQgaXJxLCB2b2lkICpkZXZwLCBzdHJ1Y3QgcHRfcmVncyAqcmVncykKewoJYWRhcHRlcl90CSphZGFwdGVyID0gZGV2cDsKCXVuc2lnbmVkIGxvbmcJZmxhZ3M7Cgl1OAlzdGF0dXM7Cgl1MzIJZHdvcmQgPSAwOwoJdTgJbnN0YXR1czsKCXU4CWNvbXBsZXRlZFtNQVhfRklSTVdBUkVfU1RBVFVTXTsKCWludAloYW5kbGVkID0gMDsKCgoJLyoKCSAqIGxvb3AgdGlsbCBGL1cgaGFzIG1vcmUgY29tbWFuZHMgZm9yIHVzIHRvIGNvbXBsZXRlLgoJICovCglzcGluX2xvY2tfaXJxc2F2ZSgmYWRhcHRlci0+bG9jaywgZmxhZ3MpOwoKCWRvIHsKCQkvKiBDaGVjayBpZiBhIHZhbGlkIGludGVycnVwdCBpcyBwZW5kaW5nICovCgkJZHdvcmQgPSBSRE9VVERPT1IoYWRhcHRlcik7CgkJaWYoZHdvcmQgIT0gMHgxMDAwMTIzNCkgewoJCQkvKgoJCQkgKiBObyBtb3JlIHBlbmRpbmcgY29tbWFuZHMKCQkJICovCgkJCWdvdG8gb3V0X3VubG9jazsKCQl9CgkJV1JPVVRET09SKGFkYXB0ZXIsIDB4MTAwMDEyMzQpOwoKCQl3aGlsZSgobnN0YXR1cyA9ICh2b2xhdGlsZSB1OClhZGFwdGVyLT5tYm94LT5tX2luLm51bXN0YXR1cykKCQkJCT09IDB4RkYpIHsKCQkJY3B1X3JlbGF4KCk7CgkJfQoJCWFkYXB0ZXItPm1ib3gtPm1faW4ubnVtc3RhdHVzID0gMHhGRjsKCgkJc3RhdHVzID0gYWRhcHRlci0+bWJveC0+bV9pbi5zdGF0dXM7CgoJCS8qCgkJICogZGVjcmVtZW50IHRoZSBwZW5kaW5nIHF1ZXVlIGNvdW50ZXIKCQkgKi8KCQlhdG9taWNfc3ViKG5zdGF0dXMsICZhZGFwdGVyLT5wZW5kX2NtZHMpOwoKCQltZW1jcHkoY29tcGxldGVkLCAodm9pZCAqKWFkYXB0ZXItPm1ib3gtPm1faW4uY29tcGxldGVkLCAKCQkJCW5zdGF0dXMpOwoKCQkvKiBBY2tub3dsZWRnZSBpbnRlcnJ1cHQgKi8KCQlXUklORE9PUihhZGFwdGVyLCAweDIpOwoKCQloYW5kbGVkID0gMTsKCgkJd2hpbGUoIFJESU5ET09SKGFkYXB0ZXIpICYgMHgwMiApIGNwdV9yZWxheCgpOwoKCQltZWdhX2NtZF9kb25lKGFkYXB0ZXIsIGNvbXBsZXRlZCwgbnN0YXR1cywgc3RhdHVzKTsKCgkJbWVnYV9ydW5kb25lcShhZGFwdGVyKTsKCgkJLyogTG9vcCB0aHJvdWdoIGFueSBwZW5kaW5nIHJlcXVlc3RzICovCgkJaWYoYXRvbWljX3JlYWQoJmFkYXB0ZXItPnF1aWVzY2VudCkgPT0gMCkgewoJCQltZWdhX3J1bnBlbmRxKGFkYXB0ZXIpOwoJCX0KCgl9IHdoaWxlKDEpOwoKIG91dF91bmxvY2s6CgoJc3Bpbl91bmxvY2tfaXJxcmVzdG9yZSgmYWRhcHRlci0+bG9jaywgZmxhZ3MpOwoKCXJldHVybiBJUlFfUkVUVkFMKGhhbmRsZWQpOwp9Ci8qKgogKiBtZWdhX2NtZF9kb25lKCkKICogQGFkYXB0ZXIgLSBwb2ludGVyIHRvIG91ciBzb2Z0IHN0YXRlCiAqIEBjb21wbGV0ZWQgLSBhcnJheSBvZiBpZHMgb2YgY29tcGxldGVkIGNvbW1hbmRzCiAqIEBuc3RhdHVzIC0gbnVtYmVyIG9mIGNvbXBsZXRlZCBjb21tYW5kcwogKiBAc3RhdHVzIC0gc3RhdHVzIG9mIHRoZSBsYXN0IGNvbW1hbmQgY29tcGxldGVkCiAqCiAqIENvbXBsZXRlIHRoZSBjb21hbW5kcyBhbmQgY2FsbCB0aGUgc2NzaSBtaWQtbGF5ZXIgY2FsbGJhY2sgaG9va3MuCiAqLwpzdGF0aWMgdm9pZAptZWdhX2NtZF9kb25lKGFkYXB0ZXJfdCAqYWRhcHRlciwgdTggY29tcGxldGVkW10sIGludCBuc3RhdHVzLCBpbnQgc3RhdHVzKQp7CgltZWdhX2V4dF9wYXNzdGhydQkqZXB0aHJ1ID0gTlVMTDsKCXN0cnVjdCBzY2F0dGVybGlzdAkqc2dsOwoJU2NzaV9DbW5kCSpjbWQgPSBOVUxMOwoJbWVnYV9wYXNzdGhydQkqcHRocnUgPSBOVUxMOwoJbWJveF90CSptYm94ID0gTlVMTDsKCXU4CWM7CglzY2JfdAkqc2NiOwoJaW50CWlzbG9naWNhbDsKCWludAljbWRpZDsKCWludAlpOwoKCS8qCgkgKiBmb3IgYWxsIHRoZSBjb21tYW5kcyBjb21wbGV0ZWQsIGNhbGwgdGhlIG1pZC1sYXllciBjYWxsYmFjayByb3V0aW5lCgkgKiBhbmQgZnJlZSB0aGUgc2NiLgoJICovCglmb3IoIGkgPSAwOyBpIDwgbnN0YXR1czsgaSsrICkgewoKCQljbWRpZCA9IGNvbXBsZXRlZFtpXTsKCgkJaWYoIGNtZGlkID09IENNRElEX0lOVF9DTURTICkgeyAvKiBpbnRlcm5hbCBjb21tYW5kICovCgkJCXNjYiA9ICZhZGFwdGVyLT5pbnRfc2NiOwoJCQljbWQgPSBzY2ItPmNtZDsKCQkJbWJveCA9IChtYm94X3QgKilzY2ItPnJhd19tYm94OwoKCQkJLyoKCQkJICogSW50ZXJuYWwgY29tbWFuZCBpbnRlcmZhY2UgZG8gbm90IGZpcmUgdGhlIGV4dGVuZGVkCgkJCSAqIHBhc3N0aHJ1IG9yIDY0LWJpdCBwYXNzdGhydQoJCQkgKi8KCQkJcHRocnUgPSBzY2ItPnB0aHJ1OwoKCQl9CgkJZWxzZSB7CgkJCXNjYiA9ICZhZGFwdGVyLT5zY2JfbGlzdFtjbWRpZF07CgoJCQkvKgoJCQkgKiBNYWtlIHN1cmUgZi93IGhhcyBjb21wbGV0ZWQgYSB2YWxpZCBjb21tYW5kCgkJCSAqLwoJCQlpZiggIShzY2ItPnN0YXRlICYgU0NCX0lTU1VFRCkgfHwgc2NiLT5jbWQgPT0gTlVMTCApIHsKCQkJCXByaW50ayhLRVJOX0NSSVQKCQkJCQkibWVnYXJhaWQ6IGludmFsaWQgY29tbWFuZCAiKTsKCQkJCXByaW50aygiSWQgJWQsIHNjYi0+c3RhdGU6JXgsIHNjc2kgY21kOiVwXG4iLAoJCQkJCWNtZGlkLCBzY2ItPnN0YXRlLCBzY2ItPmNtZCk7CgoJCQkJY29udGludWU7CgkJCX0KCgkJCS8qCgkJCSAqIFdhcyBhIGFib3J0IGlzc3VlZCBmb3IgdGhpcyBjb21tYW5kCgkJCSAqLwoJCQlpZiggc2NiLT5zdGF0ZSAmIFNDQl9BQk9SVCApIHsKCgkJCQlwcmludGsoS0VSTl9XQVJOSU5HCgkJCQkibWVnYXJhaWQ6IGFib3J0ZWQgY21kICVseFsleF0gY29tcGxldGUuXG4iLAoJCQkJCXNjYi0+Y21kLT5zZXJpYWxfbnVtYmVyLCBzY2ItPmlkeCk7CgoJCQkJc2NiLT5jbWQtPnJlc3VsdCA9IChESURfQUJPUlQgPDwgMTYpOwoKCQkJCWxpc3RfYWRkX3RhaWwoU0NTSV9MSVNUKHNjYi0+Y21kKSwKCQkJCQkJJmFkYXB0ZXItPmNvbXBsZXRlZF9saXN0KTsKCgkJCQltZWdhX2ZyZWVfc2NiKGFkYXB0ZXIsIHNjYik7CgoJCQkJY29udGludWU7CgkJCX0KCgkJCS8qCgkJCSAqIFdhcyBhIHJlc2V0IGlzc3VlZCBmb3IgdGhpcyBjb21tYW5kCgkJCSAqLwoJCQlpZiggc2NiLT5zdGF0ZSAmIFNDQl9SRVNFVCApIHsKCgkJCQlwcmludGsoS0VSTl9XQVJOSU5HCgkJCQkibWVnYXJhaWQ6IHJlc2V0IGNtZCAlbHhbJXhdIGNvbXBsZXRlLlxuIiwKCQkJCQlzY2ItPmNtZC0+c2VyaWFsX251bWJlciwgc2NiLT5pZHgpOwoKCQkJCXNjYi0+Y21kLT5yZXN1bHQgPSAoRElEX1JFU0VUIDw8IDE2KTsKCgkJCQlsaXN0X2FkZF90YWlsKFNDU0lfTElTVChzY2ItPmNtZCksCgkJCQkJCSZhZGFwdGVyLT5jb21wbGV0ZWRfbGlzdCk7CgoJCQkJbWVnYV9mcmVlX3NjYiAoYWRhcHRlciwgc2NiKTsKCgkJCQljb250aW51ZTsKCQkJfQoKCQkJY21kID0gc2NiLT5jbWQ7CgkJCXB0aHJ1ID0gc2NiLT5wdGhydTsKCQkJZXB0aHJ1ID0gc2NiLT5lcHRocnU7CgkJCW1ib3ggPSAobWJveF90ICopc2NiLT5yYXdfbWJveDsKCiNpZiBNRUdBX0hBVkVfU1RBVFMKCQkJewoKCQkJaW50CWxvZ2RydiA9IG1ib3gtPm1fb3V0LmxvZ2RydjsKCgkJCWlzbG9naWNhbCA9IGFkYXB0ZXItPmxvZ2Rydl9jaGFuW2NtZC0+Y2hhbm5lbF07CgkJCS8qCgkJCSAqIE1haW50YWluIGFuIGVycm9yIGNvdW50ZXIgZm9yIHRoZSBsb2dpY2FsIGRyaXZlLgoJCQkgKiBTb21lIGFwcGxpY2F0aW9uIGxpa2UgU05NUCBhZ2VudCBuZWVkIHN1Y2gKCQkJICogc3RhdGlzdGljcwoJCQkgKi8KCQkJaWYoIHN0YXR1cyAmJiBpc2xvZ2ljYWwgJiYgKGNtZC0+Y21uZFswXSA9PSBSRUFEXzYgfHwKCQkJCQkJY21kLT5jbW5kWzBdID09IFJFQURfMTAgfHwKCQkJCQkJY21kLT5jbW5kWzBdID09IFJFQURfMTIpKSB7CgkJCQkvKgoJCQkJICogTG9naWNhbCBkcml2ZSBudW1iZXIgaW5jcmVhc2VzIGJ5IDB4ODAgd2hlbgoJCQkJICogYSBsb2dpY2FsIGRyaXZlIGlzIGRlbGV0ZWQKCQkJCSAqLwoJCQkJYWRhcHRlci0+cmRfZXJyb3JzW2xvZ2RydiUweDgwXSsrOwoJCQl9CgoJCQlpZiggc3RhdHVzICYmIGlzbG9naWNhbCAmJiAoY21kLT5jbW5kWzBdID09IFdSSVRFXzYgfHwKCQkJCQkJY21kLT5jbW5kWzBdID09IFdSSVRFXzEwIHx8CgkJCQkJCWNtZC0+Y21uZFswXSA9PSBXUklURV8xMikpIHsKCQkJCS8qCgkJCQkgKiBMb2dpY2FsIGRyaXZlIG51bWJlciBpbmNyZWFzZXMgYnkgMHg4MCB3aGVuCgkJCQkgKiBhIGxvZ2ljYWwgZHJpdmUgaXMgZGVsZXRlZAoJCQkJICovCgkJCQlhZGFwdGVyLT53cl9lcnJvcnNbbG9nZHJ2JTB4ODBdKys7CgkJCX0KCgkJCX0KI2VuZGlmCgkJfQoKCQkvKgoJCSAqIERvIG5vdCByZXR1cm4gdGhlIHByZXNlbmNlIG9mIGhhcmQgZGlzayBvbiB0aGUgY2hhbm5lbCBzbywKCQkgKiBpbnF1aXJ5IHNlbnQsIGFuZCByZXR1cm5lZCBkYXRhPT1oYXJkIGRpc2sgb3IgcmVtb3ZhYmxlCgkJICogaGFyZCBkaXNrIGFuZCBub3QgbG9naWNhbCwgcmVxdWVzdCBzaG91bGQgcmV0dXJuIGZhaWx1cmUhIC0KCQkgKiBQSgoJCSAqLwoJCWlzbG9naWNhbCA9IGFkYXB0ZXItPmxvZ2Rydl9jaGFuW2NtZC0+ZGV2aWNlLT5jaGFubmVsXTsKCQlpZiggY21kLT5jbW5kWzBdID09IElOUVVJUlkgJiYgIWlzbG9naWNhbCApIHsKCgkJCWlmKCBjbWQtPnVzZV9zZyApIHsKCQkJCXNnbCA9IChzdHJ1Y3Qgc2NhdHRlcmxpc3QgKikKCQkJCQljbWQtPnJlcXVlc3RfYnVmZmVyOwoKCQkJCWlmKCBzZ2wtPnBhZ2UgKSB7CgkJCQkJYyA9ICoodW5zaWduZWQgY2hhciAqKQoJCQkJCXBhZ2VfYWRkcmVzcygoJnNnbFswXSktPnBhZ2UpICsKCQkJCQkoJnNnbFswXSktPm9mZnNldDsgCgkJCQl9CgkJCQllbHNlIHsKCQkJCQlwcmludGsoS0VSTl9XQVJOSU5HCgkJCQkJCSJtZWdhcmFpZDogaW52YWxpZCBzZy5cbiIpOwoJCQkJCWMgPSAwOwoJCQkJfQoJCQl9CgkJCWVsc2UgewoJCQkJYyA9ICoodTggKiljbWQtPnJlcXVlc3RfYnVmZmVyOwoJCQl9CgoJCQlpZihJU19SQUlEX0NIKGFkYXB0ZXIsIGNtZC0+ZGV2aWNlLT5jaGFubmVsKSAmJgoJCQkJCSgoYyAmIDB4MUYgKSA9PSBUWVBFX0RJU0spKSB7CgkJCQlzdGF0dXMgPSAweEYwOwoJCQl9CgkJfQoKCQkvKiBjbGVhciByZXN1bHQ7IG90aGVyd2lzZSwgc3VjY2VzcyByZXR1cm5zIGNvcnJ1cHQgdmFsdWUgKi8KCQljbWQtPnJlc3VsdCA9IDA7CgoJCS8qIENvbnZlcnQgTWVnYVJBSUQgc3RhdHVzIHRvIExpbnV4IGVycm9yIGNvZGUgKi8KCQlzd2l0Y2ggKHN0YXR1cykgewoJCWNhc2UgMHgwMDoJLyogU1VDQ0VTUyAsIGkuZS4gU0NTSV9TVEFUVVNfR09PRCAqLwoJCQljbWQtPnJlc3VsdCB8PSAoRElEX09LIDw8IDE2KTsKCQkJYnJlYWs7CgoJCWNhc2UgMHgwMjoJLyogRVJST1JfQUJPUlRFRCwgaS5lLgoJCQkJICAgU0NTSV9TVEFUVVNfQ0hFQ0tfQ09ORElUSU9OICovCgoJCQkvKiBzZXQgc2Vuc2VfYnVmZmVyIGFuZCByZXN1bHQgZmllbGRzICovCgkJCWlmKCBtYm94LT5tX291dC5jbWQgPT0gTUVHQV9NQk9YQ01EX1BBU1NUSFJVIHx8CgkJCQltYm94LT5tX291dC5jbWQgPT0gTUVHQV9NQk9YQ01EX1BBU1NUSFJVNjQgKSB7CgoJCQkJbWVtY3B5KGNtZC0+c2Vuc2VfYnVmZmVyLCBwdGhydS0+cmVxc2Vuc2VhcmVhLAoJCQkJCQkxNCk7CgoJCQkJY21kLT5yZXN1bHQgPSAoRFJJVkVSX1NFTlNFIDw8IDI0KSB8CgkJCQkJKERJRF9PSyA8PCAxNikgfAoJCQkJCShDSEVDS19DT05ESVRJT04gPDwgMSk7CgkJCX0KCQkJZWxzZSB7CgkJCQlpZiAobWJveC0+bV9vdXQuY21kID09IE1FR0FfTUJPWENNRF9FWFRQVEhSVSkgewoKCQkJCQltZW1jcHkoY21kLT5zZW5zZV9idWZmZXIsCgkJCQkJCWVwdGhydS0+cmVxc2Vuc2VhcmVhLCAxNCk7CgoJCQkJCWNtZC0+cmVzdWx0ID0gKERSSVZFUl9TRU5TRSA8PCAyNCkgfAoJCQkJCQkoRElEX09LIDw8IDE2KSB8CgkJCQkJCShDSEVDS19DT05ESVRJT04gPDwgMSk7CgkJCQl9IGVsc2UgewoJCQkJCWNtZC0+c2Vuc2VfYnVmZmVyWzBdID0gMHg3MDsKCQkJCQljbWQtPnNlbnNlX2J1ZmZlclsyXSA9IEFCT1JURURfQ09NTUFORDsKCQkJCQljbWQtPnJlc3VsdCB8PSAoQ0hFQ0tfQ09ORElUSU9OIDw8IDEpOwoJCQkJfQoJCQl9CgkJCWJyZWFrOwoKCQljYXNlIDB4MDg6CS8qIEVSUl9ERVNUX0RSSVZFX0ZBSUxFRCwgaS5lLgoJCQkJICAgU0NTSV9TVEFUVVNfQlVTWSAqLwoJCQljbWQtPnJlc3VsdCB8PSAoRElEX0JVU19CVVNZIDw8IDE2KSB8IHN0YXR1czsKCQkJYnJlYWs7CgoJCWRlZmF1bHQ6CiNpZiBNRUdBX0hBVkVfQ0xVU1RFUklORwoJCQkvKgoJCQkgKiBJZiBURVNUX1VOSVRfUkVBRFkgZmFpbHMsIHdlIGtub3cKCQkJICogTUVHQV9SRVNFUlZBVElPTl9TVEFUVVMgZmFpbGVkCgkJCSAqLwoJCQlpZiggY21kLT5jbW5kWzBdID09IFRFU1RfVU5JVF9SRUFEWSApIHsKCQkJCWNtZC0+cmVzdWx0IHw9IChESURfRVJST1IgPDwgMTYpIHwKCQkJCQkoUkVTRVJWQVRJT05fQ09ORkxJQ1QgPDwgMSk7CgkJCX0KCQkJZWxzZQoJCQkvKgoJCQkgKiBFcnJvciBjb2RlIHJldHVybmVkIGlzIDEgaWYgUmVzZXJ2ZSBvciBSZWxlYXNlCgkJCSAqIGZhaWxlZCBvciB0aGUgaW5wdXQgcGFyYW1ldGVyIGlzIGludmFsaWQKCQkJICovCgkJCWlmKCBzdGF0dXMgPT0gMSAmJgoJCQkJKGNtZC0+Y21uZFswXSA9PSBSRVNFUlZFIHx8CgkJCQkJIGNtZC0+Y21uZFswXSA9PSBSRUxFQVNFKSApIHsKCgkJCQljbWQtPnJlc3VsdCB8PSAoRElEX0VSUk9SIDw8IDE2KSB8CgkJCQkJKFJFU0VSVkFUSU9OX0NPTkZMSUNUIDw8IDEpOwoJCQl9CgkJCWVsc2UKI2VuZGlmCgkJCQljbWQtPnJlc3VsdCB8PSAoRElEX0JBRF9UQVJHRVQgPDwgMTYpfHN0YXR1czsKCQl9CgoJCS8qCgkJICogT25seSBmcmVlIFNDQnMgZm9yIHRoZSBjb21tYW5kcyBjb21pbmcgZG93biBmcm9tIHRoZQoJCSAqIG1pZC1sYXllciwgbm90IGZvciB3aGljaCB3ZXJlIGlzc3VlZCBpbnRlcm5hbGx5CgkJICoKCQkgKiBGb3IgaW50ZXJuYWwgY29tbWFuZCwgcmVzdG9yZSB0aGUgc3RhdHVzIHJldHVybmVkIGJ5IHRoZQoJCSAqIGZpcm13YXJlIHNvIHRoYXQgdXNlciBjYW4gaW50ZXJwcmV0IGl0LgoJCSAqLwoJCWlmKCBjbWRpZCA9PSBDTURJRF9JTlRfQ01EUyApIHsgLyogaW50ZXJuYWwgY29tbWFuZCAqLwoJCQljbWQtPnJlc3VsdCA9IHN0YXR1czsKCgkJCS8qCgkJCSAqIFJlbW92ZSB0aGUgaW50ZXJuYWwgY29tbWFuZCBmcm9tIHRoZSBwZW5kaW5nIGxpc3QKCQkJICovCgkJCWxpc3RfZGVsX2luaXQoJnNjYi0+bGlzdCk7CgkJCXNjYi0+c3RhdGUgPSBTQ0JfRlJFRTsKCQl9CgkJZWxzZSB7CgkJCW1lZ2FfZnJlZV9zY2IoYWRhcHRlciwgc2NiKTsKCQl9CgoJCS8qIEFkZCBTY3NpX0NvbW1hbmQgdG8gZW5kIG9mIGNvbXBsZXRlZCBxdWV1ZSAqLwoJCWxpc3RfYWRkX3RhaWwoU0NTSV9MSVNUKGNtZCksICZhZGFwdGVyLT5jb21wbGV0ZWRfbGlzdCk7Cgl9Cn0KCgovKgogKiBtZWdhX3J1bnBlbmRxKCkKICoKICogUnVuIHRocm91Z2ggdGhlIGxpc3Qgb2YgY29tcGxldGVkIHJlcXVlc3RzIGFuZCBmaW5pc2ggaXQKICovCnN0YXRpYyB2b2lkCm1lZ2FfcnVuZG9uZXEgKGFkYXB0ZXJfdCAqYWRhcHRlcikKewoJU2NzaV9DbW5kICpjbWQ7CglzdHJ1Y3QgbGlzdF9oZWFkICpwb3M7CgoJbGlzdF9mb3JfZWFjaChwb3MsICZhZGFwdGVyLT5jb21wbGV0ZWRfbGlzdCkgewoKCQlTY3NpX1BvaW50ZXIqIHNwb3MgPSAoU2NzaV9Qb2ludGVyICopcG9zOwoKCQljbWQgPSBsaXN0X2VudHJ5KHNwb3MsIFNjc2lfQ21uZCwgU0NwKTsKCQljbWQtPnNjc2lfZG9uZShjbWQpOwoJfQoKCUlOSVRfTElTVF9IRUFEKCZhZGFwdGVyLT5jb21wbGV0ZWRfbGlzdCk7Cn0KCgovKgogKiBGcmVlIGEgU0NCIHN0cnVjdHVyZQogKiBOb3RlOiBXZSBhc3N1bWUgdGhlIHNjc2kgY29tbWFuZHMgYXNzb2NpYXRlZCB3aXRoIHRoaXMgc2NiIGlzIG5vdCBmcmVlIHlldC4KICovCnN0YXRpYyB2b2lkCm1lZ2FfZnJlZV9zY2IoYWRhcHRlcl90ICphZGFwdGVyLCBzY2JfdCAqc2NiKQp7Cglzd2l0Y2goIHNjYi0+ZG1hX3R5cGUgKSB7CgoJY2FzZSBNRUdBX0RNQV9UWVBFX05PTkU6CgkJYnJlYWs7CgoJY2FzZSBNRUdBX0JVTEtfREFUQToKCQlwY2lfdW5tYXBfcGFnZShhZGFwdGVyLT5kZXYsIHNjYi0+ZG1hX2hfYnVsa2RhdGEsCgkJCXNjYi0+Y21kLT5yZXF1ZXN0X2J1ZmZsZW4sIHNjYi0+ZG1hX2RpcmVjdGlvbik7CgkJYnJlYWs7CgoJY2FzZSBNRUdBX1NHTElTVDoKCQlwY2lfdW5tYXBfc2coYWRhcHRlci0+ZGV2LCBzY2ItPmNtZC0+cmVxdWVzdF9idWZmZXIsCgkJCXNjYi0+Y21kLT51c2Vfc2csIHNjYi0+ZG1hX2RpcmVjdGlvbik7CgkJYnJlYWs7CgoJZGVmYXVsdDoKCQlicmVhazsKCX0KCgkvKgoJICogUmVtb3ZlIGZyb20gdGhlIHBlbmRpbmcgbGlzdAoJICovCglsaXN0X2RlbF9pbml0KCZzY2ItPmxpc3QpOwoKCS8qIExpbmsgdGhlIHNjYiBiYWNrIGludG8gZnJlZSBsaXN0ICovCglzY2ItPnN0YXRlID0gU0NCX0ZSRUU7CglzY2ItPmNtZCA9IE5VTEw7CgoJbGlzdF9hZGQoJnNjYi0+bGlzdCwgJmFkYXB0ZXItPmZyZWVfbGlzdCk7Cn0KCgpzdGF0aWMgaW50Cl9fbWVnYV9idXN5d2FpdF9tYm94IChhZGFwdGVyX3QgKmFkYXB0ZXIpCnsKCXZvbGF0aWxlIG1ib3hfdCAqbWJveCA9IGFkYXB0ZXItPm1ib3g7Cglsb25nIGNvdW50ZXI7CgoJZm9yIChjb3VudGVyID0gMDsgY291bnRlciA8IDEwMDAwOyBjb3VudGVyKyspIHsKCQlpZiAoIW1ib3gtPm1faW4uYnVzeSkKCQkJcmV0dXJuIDA7CgkJdWRlbGF5KDEwMCk7IHlpZWxkKCk7Cgl9CglyZXR1cm4gLTE7CQkvKiBnaXZlIHVwIGFmdGVyIDEgc2Vjb25kICovCn0KCi8qCiAqIENvcGllcyBkYXRhIHRvIFNHTElTVAogKiBOb3RlOiBGb3IgNjQgYml0IGNhcmRzLCB3ZSBuZWVkIGEgbWluaW11bSBvZiBvbmUgU0cgZWxlbWVudCBmb3IgcmVhZC93cml0ZQogKi8Kc3RhdGljIGludAptZWdhX2J1aWxkX3NnbGlzdChhZGFwdGVyX3QgKmFkYXB0ZXIsIHNjYl90ICpzY2IsIHUzMiAqYnVmLCB1MzIgKmxlbikKewoJc3RydWN0IHNjYXR0ZXJsaXN0CSpzZ2w7CglzdHJ1Y3QgcGFnZQkqcGFnZTsKCXVuc2lnbmVkIGxvbmcJb2Zmc2V0OwoJU2NzaV9DbW5kCSpjbWQ7CglpbnQJc2djbnQ7CglpbnQJaWR4OwoKCWNtZCA9IHNjYi0+Y21kOwoKCS8qIFNjYXR0ZXItZ2F0aGVyIG5vdCB1c2VkICovCglpZiggIWNtZC0+dXNlX3NnICkgewoKCQlwYWdlID0gdmlydF90b19wYWdlKGNtZC0+cmVxdWVzdF9idWZmZXIpOwoJCW9mZnNldCA9IG9mZnNldF9pbl9wYWdlKGNtZC0+cmVxdWVzdF9idWZmZXIpOwoKCQlzY2ItPmRtYV9oX2J1bGtkYXRhID0gcGNpX21hcF9wYWdlKGFkYXB0ZXItPmRldiwKCQkJCQkJICBwYWdlLCBvZmZzZXQsCgkJCQkJCSAgY21kLT5yZXF1ZXN0X2J1ZmZsZW4sCgkJCQkJCSAgc2NiLT5kbWFfZGlyZWN0aW9uKTsKCQlzY2ItPmRtYV90eXBlID0gTUVHQV9CVUxLX0RBVEE7CgoJCS8qCgkJICogV2UgbmVlZCB0byBoYW5kbGUgc3BlY2lhbCA2NC1iaXQgY29tbWFuZHMgdGhhdCBuZWVkIGEKCQkgKiBtaW5pbXVtIG9mIDEgU0cKCQkgKi8KCQlpZiggYWRhcHRlci0+aGFzXzY0Yml0X2FkZHIgKSB7CgkJCXNjYi0+c2dsNjRbMF0uYWRkcmVzcyA9IHNjYi0+ZG1hX2hfYnVsa2RhdGE7CgkJCXNjYi0+c2dsNjRbMF0ubGVuZ3RoID0gY21kLT5yZXF1ZXN0X2J1ZmZsZW47CgkJCSpidWYgPSAodTMyKXNjYi0+c2dsX2RtYV9hZGRyOwoJCQkqbGVuID0gKHUzMiljbWQtPnJlcXVlc3RfYnVmZmxlbjsKCQkJcmV0dXJuIDE7CgkJfQoJCWVsc2UgewoJCQkqYnVmID0gKHUzMilzY2ItPmRtYV9oX2J1bGtkYXRhOwoJCQkqbGVuID0gKHUzMiljbWQtPnJlcXVlc3RfYnVmZmxlbjsKCQl9CgkJcmV0dXJuIDA7Cgl9CgoJc2dsID0gKHN0cnVjdCBzY2F0dGVybGlzdCAqKWNtZC0+cmVxdWVzdF9idWZmZXI7CgoJLyoKCSAqIENvcHkgU2NhdHRlci1HYXRoZXIgbGlzdCBpbmZvIGludG8gY29udHJvbGxlciBzdHJ1Y3R1cmUuCgkgKgoJICogVGhlIG51bWJlciBvZiBzZyBlbGVtZW50cyByZXR1cm5lZCBtdXN0IG5vdCBleGNlZWQgb3VyIGxpbWl0CgkgKi8KCXNnY250ID0gcGNpX21hcF9zZyhhZGFwdGVyLT5kZXYsIHNnbCwgY21kLT51c2Vfc2csCgkJCXNjYi0+ZG1hX2RpcmVjdGlvbik7CgoJc2NiLT5kbWFfdHlwZSA9IE1FR0FfU0dMSVNUOwoKCWlmKCBzZ2NudCA+IGFkYXB0ZXItPnNnbGVuICkgQlVHKCk7CgoJZm9yKCBpZHggPSAwOyBpZHggPCBzZ2NudDsgaWR4KyssIHNnbCsrICkgewoKCQlpZiggYWRhcHRlci0+aGFzXzY0Yml0X2FkZHIgKSB7CgkJCXNjYi0+c2dsNjRbaWR4XS5hZGRyZXNzID0gc2dfZG1hX2FkZHJlc3Moc2dsKTsKCQkJc2NiLT5zZ2w2NFtpZHhdLmxlbmd0aCA9IHNnX2RtYV9sZW4oc2dsKTsKCQl9CgkJZWxzZSB7CgkJCXNjYi0+c2dsW2lkeF0uYWRkcmVzcyA9IHNnX2RtYV9hZGRyZXNzKHNnbCk7CgkJCXNjYi0+c2dsW2lkeF0ubGVuZ3RoID0gc2dfZG1hX2xlbihzZ2wpOwoJCX0KCX0KCgkvKiBSZXNldCBwb2ludGVyIGFuZCBsZW5ndGggZmllbGRzICovCgkqYnVmID0gc2NiLT5zZ2xfZG1hX2FkZHI7CgoJLyoKCSAqIEZvciBwYXNzdGhydSBjb21tYW5kLCBkYXRheGZlcmxlbiBtdXN0IGJlIHNldCwgZXZlbiBmb3IgY29tbWFuZHMKCSAqIHdpdGggYSBzZyBsaXN0CgkgKi8KCSpsZW4gPSAodTMyKWNtZC0+cmVxdWVzdF9idWZmbGVuOwoKCS8qIFJldHVybiBjb3VudCBvZiBTRyByZXF1ZXN0cyAqLwoJcmV0dXJuIHNnY250Owp9CgoKLyoKICogbWVnYV84X3RvXzQwbGQoKQogKgogKiB0YWtlcyBhbGwgaW5mbyBpbiBBZGFwdGVySW5xdWlyeSBzdHJ1Y3R1cmUgYW5kIHB1dHMgaXQgaW50byBQcm9kdWN0SW5mbyBhbmQKICogRW5xdWlyeTMgc3RydWN0dXJlcyBmb3IgbGF0ZXIgdXNlCiAqLwpzdGF0aWMgdm9pZAptZWdhXzhfdG9fNDBsZChtcmFpZF9pbnF1aXJ5ICppbnF1aXJ5LCBtZWdhX2lucXVpcnkzICplbnF1aXJ5MywKCQltZWdhX3Byb2R1Y3RfaW5mbyAqcHJvZHVjdF9pbmZvKQp7CglpbnQgaTsKCglwcm9kdWN0X2luZm8tPm1heF9jb21tYW5kcyA9IGlucXVpcnktPmFkYXB0ZXJfaW5mby5tYXhfY29tbWFuZHM7CgllbnF1aXJ5My0+cmVidWlsZF9yYXRlID0gaW5xdWlyeS0+YWRhcHRlcl9pbmZvLnJlYnVpbGRfcmF0ZTsKCXByb2R1Y3RfaW5mby0+bmNoYW5uZWxzID0gaW5xdWlyeS0+YWRhcHRlcl9pbmZvLm5jaGFubmVsczsKCglmb3IgKGkgPSAwOyBpIDwgNDsgaSsrKSB7CgkJcHJvZHVjdF9pbmZvLT5md192ZXJzaW9uW2ldID0KCQkJaW5xdWlyeS0+YWRhcHRlcl9pbmZvLmZ3X3ZlcnNpb25baV07CgoJCXByb2R1Y3RfaW5mby0+Ymlvc192ZXJzaW9uW2ldID0KCQkJaW5xdWlyeS0+YWRhcHRlcl9pbmZvLmJpb3NfdmVyc2lvbltpXTsKCX0KCWVucXVpcnkzLT5jYWNoZV9mbHVzaF9pbnRlcnZhbCA9CgkJaW5xdWlyeS0+YWRhcHRlcl9pbmZvLmNhY2hlX2ZsdXNoX2ludGVydmFsOwoKCXByb2R1Y3RfaW5mby0+ZHJhbV9zaXplID0gaW5xdWlyeS0+YWRhcHRlcl9pbmZvLmRyYW1fc2l6ZTsKCgllbnF1aXJ5My0+bnVtX2xkcnYgPSBpbnF1aXJ5LT5sb2dkcnZfaW5mby5udW1fbGRydjsKCglmb3IgKGkgPSAwOyBpIDwgTUFYX0xPR0lDQUxfRFJJVkVTXzhMRDsgaSsrKSB7CgkJZW5xdWlyeTMtPmxkcnZfc2l6ZVtpXSA9IGlucXVpcnktPmxvZ2Rydl9pbmZvLmxkcnZfc2l6ZVtpXTsKCQllbnF1aXJ5My0+bGRydl9wcm9wW2ldID0gaW5xdWlyeS0+bG9nZHJ2X2luZm8ubGRydl9wcm9wW2ldOwoJCWVucXVpcnkzLT5sZHJ2X3N0YXRlW2ldID0gaW5xdWlyeS0+bG9nZHJ2X2luZm8ubGRydl9zdGF0ZVtpXTsKCX0KCglmb3IgKGkgPSAwOyBpIDwgKE1BWF9QSFlTSUNBTF9EUklWRVMpOyBpKyspCgkJZW5xdWlyeTMtPnBkcnZfc3RhdGVbaV0gPSBpbnF1aXJ5LT5wZHJ2X2luZm8ucGRydl9zdGF0ZVtpXTsKfQoKc3RhdGljIGlubGluZSB2b2lkCm1lZ2FfZnJlZV9zZ2woYWRhcHRlcl90ICphZGFwdGVyKQp7CglzY2JfdAkqc2NiOwoJaW50CWk7CgoJZm9yKGkgPSAwOyBpIDwgYWRhcHRlci0+bWF4X2NtZHM7IGkrKykgewoKCQlzY2IgPSAmYWRhcHRlci0+c2NiX2xpc3RbaV07CgoJCWlmKCBzY2ItPnNnbDY0ICkgewoJCQlwY2lfZnJlZV9jb25zaXN0ZW50KGFkYXB0ZXItPmRldiwKCQkJCXNpemVvZihtZWdhX3NnbDY0KSAqIGFkYXB0ZXItPnNnbGVuLAoJCQkJc2NiLT5zZ2w2NCwKCQkJCXNjYi0+c2dsX2RtYV9hZGRyKTsKCgkJCXNjYi0+c2dsNjQgPSBOVUxMOwoJCX0KCgkJaWYoIHNjYi0+cHRocnUgKSB7CgkJCXBjaV9mcmVlX2NvbnNpc3RlbnQoYWRhcHRlci0+ZGV2LCBzaXplb2YobWVnYV9wYXNzdGhydSksCgkJCQlzY2ItPnB0aHJ1LCBzY2ItPnB0aHJ1X2RtYV9hZGRyKTsKCgkJCXNjYi0+cHRocnUgPSBOVUxMOwoJCX0KCgkJaWYoIHNjYi0+ZXB0aHJ1ICkgewoJCQlwY2lfZnJlZV9jb25zaXN0ZW50KGFkYXB0ZXItPmRldiwKCQkJCXNpemVvZihtZWdhX2V4dF9wYXNzdGhydSksCgkJCQlzY2ItPmVwdGhydSwgc2NiLT5lcHRocnVfZG1hX2FkZHIpOwoKCQkJc2NiLT5lcHRocnUgPSBOVUxMOwoJCX0KCgl9Cn0KCgovKgogKiBHZXQgaW5mb3JtYXRpb24gYWJvdXQgdGhlIGNhcmQvZHJpdmVyCiAqLwpjb25zdCBjaGFyICoKbWVnYXJhaWRfaW5mbyhzdHJ1Y3QgU2NzaV9Ib3N0ICpob3N0KQp7CglzdGF0aWMgY2hhciBidWZmZXJbNTEyXTsKCWFkYXB0ZXJfdCAqYWRhcHRlcjsKCglhZGFwdGVyID0gKGFkYXB0ZXJfdCAqKWhvc3QtPmhvc3RkYXRhOwoKCXNwcmludGYgKGJ1ZmZlciwKCQkgIkxTSSBMb2dpYyBNZWdhUkFJRCAlcyAlZCBjb21tYW5kcyAlZCB0YXJncyAlZCBjaGFucyAlZCBsdW5zIiwKCQkgYWRhcHRlci0+ZndfdmVyc2lvbiwgYWRhcHRlci0+cHJvZHVjdF9pbmZvLm1heF9jb21tYW5kcywKCQkgYWRhcHRlci0+aG9zdC0+bWF4X2lkLCBhZGFwdGVyLT5ob3N0LT5tYXhfY2hhbm5lbCwKCQkgYWRhcHRlci0+aG9zdC0+bWF4X2x1bik7CglyZXR1cm4gYnVmZmVyOwp9CgovKgogKiBBYm9ydCBhIHByZXZpb3VzIFNDU0kgcmVxdWVzdC4gT25seSBjb21tYW5kcyBvbiB0aGUgcGVuZGluZyBsaXN0IGNhbiBiZQogKiBhYm9ydGVkLiBBbGwgdGhlIGNvbW1hbmRzIGlzc3VlZCB0byB0aGUgRi9XIG11c3QgY29tcGxldGUuCiAqLwpzdGF0aWMgaW50Cm1lZ2FyYWlkX2Fib3J0KFNjc2lfQ21uZCAqY21kKQp7CglhZGFwdGVyX3QJKmFkYXB0ZXI7CglpbnQJCXJ2YWw7CgoJYWRhcHRlciA9IChhZGFwdGVyX3QgKiljbWQtPmRldmljZS0+aG9zdC0+aG9zdGRhdGE7CgoJcnZhbCA9ICBtZWdhcmFpZF9hYm9ydF9hbmRfcmVzZXQoYWRhcHRlciwgY21kLCBTQ0JfQUJPUlQpOwoKCS8qCgkgKiBUaGlzIGlzIHJlcXVpcmVkIGhlcmUgdG8gY29tcGxldGUgYW55IGNvbXBsZXRlZCByZXF1ZXN0cwoJICogdG8gYmUgY29tbXVuaWNhdGVkIG92ZXIgdG8gdGhlIG1pZCBsYXllci4KCSAqLwoJbWVnYV9ydW5kb25lcShhZGFwdGVyKTsKCglyZXR1cm4gcnZhbDsKfQoKCnN0YXRpYyBpbnQKbWVnYXJhaWRfcmVzZXQoU2NzaV9DbW5kICpjbWQpCnsKCWFkYXB0ZXJfdAkqYWRhcHRlcjsKCW1lZ2FjbWRfdAltYzsKCWludAkJcnZhbDsKCglhZGFwdGVyID0gKGFkYXB0ZXJfdCAqKWNtZC0+ZGV2aWNlLT5ob3N0LT5ob3N0ZGF0YTsKCiNpZiBNRUdBX0hBVkVfQ0xVU1RFUklORwoJbWMuY21kID0gTUVHQV9DTFVTVEVSX0NNRDsKCW1jLm9wY29kZSA9IE1FR0FfUkVTRVRfUkVTRVJWQVRJT05TOwoKCXNwaW5fdW5sb2NrX2lycSgmYWRhcHRlci0+bG9jayk7CglpZiggbWVnYV9pbnRlcm5hbF9jb21tYW5kKGFkYXB0ZXIsIExPQ0tfSU5ULCAmbWMsIE5VTEwpICE9IDAgKSB7CgkJcHJpbnRrKEtFUk5fV0FSTklORwoJCQkJIm1lZ2FyYWlkOiByZXNlcnZhdGlvbiByZXNldCBmYWlsZWQuXG4iKTsKCX0KCWVsc2UgewoJCXByaW50ayhLRVJOX0lORk8gIm1lZ2FyYWlkOiByZXNlcnZhdGlvbiByZXNldC5cbiIpOwoJfQoJc3Bpbl9sb2NrX2lycSgmYWRhcHRlci0+bG9jayk7CiNlbmRpZgoKCXJ2YWwgPSAgbWVnYXJhaWRfYWJvcnRfYW5kX3Jlc2V0KGFkYXB0ZXIsIGNtZCwgU0NCX1JFU0VUKTsKCgkvKgoJICogVGhpcyBpcyByZXF1aXJlZCBoZXJlIHRvIGNvbXBsZXRlIGFueSBjb21wbGV0ZWQgcmVxdWVzdHMKCSAqIHRvIGJlIGNvbW11bmljYXRlZCBvdmVyIHRvIHRoZSBtaWQgbGF5ZXIuCgkgKi8KCW1lZ2FfcnVuZG9uZXEoYWRhcHRlcik7CgoJcmV0dXJuIHJ2YWw7Cn0KCgoKLyoqCiAqIG1lZ2FyYWlkX2Fib3J0X2FuZF9yZXNldCgpCiAqIEBhZGFwdGVyIC0gbWVnYXJhaWQgc29mdCBzdGF0ZQogKiBAY21kIC0gc2NzaSBjb21tYW5kIHRvIGJlIGFib3J0ZWQgb3IgcmVzZXQKICogQGFvciAtIGFib3J0IG9yIHJlc2V0IGZsYWcKICoKICogVHJ5IHRvIGxvY2F0ZSB0aGUgc2NzaSBjb21tYW5kIGluIHRoZSBwZW5kaW5nIHF1ZXVlLiBJZiBmb3VuZCBhbmQgaXMgbm90CiAqIGlzc3VlZCB0byB0aGUgY29udHJvbGxlciwgYWJvcnQvcmVzZXQgaXQuIE90aGVyd2lzZSByZXR1cm4gZmFpbHVyZQogKi8Kc3RhdGljIGludAptZWdhcmFpZF9hYm9ydF9hbmRfcmVzZXQoYWRhcHRlcl90ICphZGFwdGVyLCBTY3NpX0NtbmQgKmNtZCwgaW50IGFvcikKewoJc3RydWN0IGxpc3RfaGVhZAkqcG9zLCAqbmV4dDsKCXNjYl90CQkJKnNjYjsKCglwcmludGsoS0VSTl9XQVJOSU5HICJtZWdhcmFpZDogJXMtJWx4IGNtZD0leCA8Yz0lZCB0PSVkIGw9JWQ+XG4iLAoJICAgICAoYW9yID09IFNDQl9BQk9SVCk/ICJBQk9SVElORyI6IlJFU0VUIiwgY21kLT5zZXJpYWxfbnVtYmVyLAoJICAgICBjbWQtPmNtbmRbMF0sIGNtZC0+ZGV2aWNlLT5jaGFubmVsLCAKCSAgICAgY21kLT5kZXZpY2UtPmlkLCBjbWQtPmRldmljZS0+bHVuKTsKCglpZihsaXN0X2VtcHR5KCZhZGFwdGVyLT5wZW5kaW5nX2xpc3QpKQoJCXJldHVybiBGQUxTRTsKCglsaXN0X2Zvcl9lYWNoX3NhZmUocG9zLCBuZXh0LCAmYWRhcHRlci0+cGVuZGluZ19saXN0KSB7CgoJCXNjYiA9IGxpc3RfZW50cnkocG9zLCBzY2JfdCwgbGlzdCk7CgoJCWlmIChzY2ItPmNtZCA9PSBjbWQpIHsgLyogRm91bmQgY29tbWFuZCAqLwoKCQkJc2NiLT5zdGF0ZSB8PSBhb3I7CgoJCQkvKgoJCQkgKiBDaGVjayBpZiB0aGlzIGNvbW1hbmQgaGFzIGZpcm1hcmUgb3dlbmVyc2hpcC4gSWYKCQkJICogeWVzLCB3ZSBjYW5ub3QgcmVzZXQgdGhpcyBjb21tYW5kLiBXaGVuZXZlciwgZi93CgkJCSAqIGNvbXBsZXRlcyB0aGlzIGNvbW1hbmQsIHdlIHdpbGwgcmV0dXJuIGFwcHJvcHJpYXRlCgkJCSAqIHN0YXR1cyBmcm9tIElTUi4KCQkJICovCgkJCWlmKCBzY2ItPnN0YXRlICYgU0NCX0lTU1VFRCApIHsKCgkJCQlwcmludGsoS0VSTl9XQVJOSU5HCgkJCQkJIm1lZ2FyYWlkOiAlcy0lbHhbJXhdLCBmdyBvd25lci5cbiIsCgkJCQkJKGFvcj09U0NCX0FCT1JUKSA/ICJBQk9SVElORyI6IlJFU0VUIiwKCQkJCQljbWQtPnNlcmlhbF9udW1iZXIsIHNjYi0+aWR4KTsKCgkJCQlyZXR1cm4gRkFMU0U7CgkJCX0KCQkJZWxzZSB7CgoJCQkJLyoKCQkJCSAqIE5vdCB5ZXQgaXNzdWVkISBSZW1vdmUgZnJvbSB0aGUgcGVuZGluZwoJCQkJICogbGlzdAoJCQkJICovCgkJCQlwcmludGsoS0VSTl9XQVJOSU5HCgkJCQkJIm1lZ2FyYWlkOiAlcy0lbHhbJXhdLCBkcml2ZXIgb3duZXIuXG4iLAoJCQkJCShhb3I9PVNDQl9BQk9SVCkgPyAiQUJPUlRJTkciOiJSRVNFVCIsCgkJCQkJY21kLT5zZXJpYWxfbnVtYmVyLCBzY2ItPmlkeCk7CgoJCQkJbWVnYV9mcmVlX3NjYihhZGFwdGVyLCBzY2IpOwoKCQkJCWlmKCBhb3IgPT0gU0NCX0FCT1JUICkgewoJCQkJCWNtZC0+cmVzdWx0ID0gKERJRF9BQk9SVCA8PCAxNik7CgkJCQl9CgkJCQllbHNlIHsKCQkJCQljbWQtPnJlc3VsdCA9IChESURfUkVTRVQgPDwgMTYpOwoJCQkJfQoKCQkJCWxpc3RfYWRkX3RhaWwoU0NTSV9MSVNUKGNtZCksCgkJCQkJCSZhZGFwdGVyLT5jb21wbGV0ZWRfbGlzdCk7CgoJCQkJcmV0dXJuIFRSVUU7CgkJCX0KCQl9Cgl9CgoJcmV0dXJuIEZBTFNFOwp9CgpzdGF0aWMgaW5saW5lIGludAptYWtlX2xvY2FsX3BkZXYoYWRhcHRlcl90ICphZGFwdGVyLCBzdHJ1Y3QgcGNpX2RldiAqKnBkZXYpCnsKCSpwZGV2ID0ga21hbGxvYyhzaXplb2Yoc3RydWN0IHBjaV9kZXYpLCBHRlBfS0VSTkVMKTsKCglpZiggKnBkZXYgPT0gTlVMTCApIHJldHVybiAtMTsKCgltZW1jcHkoKnBkZXYsIGFkYXB0ZXItPmRldiwgc2l6ZW9mKHN0cnVjdCBwY2lfZGV2KSk7CgoJaWYoIHBjaV9zZXRfZG1hX21hc2soKnBkZXYsIDB4ZmZmZmZmZmYpICE9IDAgKSB7CgkJa2ZyZWUoKnBkZXYpOwoJCXJldHVybiAtMTsKCX0KCglyZXR1cm4gMDsKfQoKc3RhdGljIGlubGluZSB2b2lkCmZyZWVfbG9jYWxfcGRldihzdHJ1Y3QgcGNpX2RldiAqcGRldikKewoJa2ZyZWUocGRldik7Cn0KCi8qKgogKiBtZWdhX2FsbG9jYXRlX2lucXVpcnkoKQogKiBAZG1hX2hhbmRsZSAtIGhhbmRsZSByZXR1cm5lZCBmb3IgZG1hIGFkZHJlc3MKICogQHBkZXYgLSBoYW5kbGUgdG8gcGNpIGRldmljZQogKgogKiBhbGxvY2F0ZXMgbWVtb3J5IGZvciBpbnF1aXJ5IHN0cnVjdHVyZQogKi8Kc3RhdGljIGlubGluZSB2b2lkICoKbWVnYV9hbGxvY2F0ZV9pbnF1aXJ5KGRtYV9hZGRyX3QgKmRtYV9oYW5kbGUsIHN0cnVjdCBwY2lfZGV2ICpwZGV2KQp7CglyZXR1cm4gcGNpX2FsbG9jX2NvbnNpc3RlbnQocGRldiwgc2l6ZW9mKG1lZ2FfaW5xdWlyeTMpLCBkbWFfaGFuZGxlKTsKfQoKCnN0YXRpYyBpbmxpbmUgdm9pZAptZWdhX2ZyZWVfaW5xdWlyeSh2b2lkICppbnF1aXJ5LCBkbWFfYWRkcl90IGRtYV9oYW5kbGUsIHN0cnVjdCBwY2lfZGV2ICpwZGV2KQp7CglwY2lfZnJlZV9jb25zaXN0ZW50KHBkZXYsIHNpemVvZihtZWdhX2lucXVpcnkzKSwgaW5xdWlyeSwgZG1hX2hhbmRsZSk7Cn0KCgojaWZkZWYgQ09ORklHX1BST0NfRlMKLyogRm9sbG93aW5nIGNvZGUgaGFuZGxlcyAvcHJvYyBmcyAgKi8KCiNkZWZpbmUgQ1JFQVRFX1JFQURfUFJPQyhzdHJpbmcsIGZ1bmMpCWNyZWF0ZV9wcm9jX3JlYWRfZW50cnkoc3RyaW5nLAlcCgkJCQkJU19JUlVTUiB8IFNfSUZSRUcsCQlcCgkJCQkJY29udHJvbGxlcl9wcm9jX2Rpcl9lbnRyeSwJXAoJCQkJCWZ1bmMsIGFkYXB0ZXIpCgovKioKICogbWVnYV9jcmVhdGVfcHJvY19lbnRyeSgpCiAqIEBpbmRleCAtIGluZGV4IGluIHNvZnQgc3RhdGUgYXJyYXkKICogQHBhcmVudCAtIHBhcmVudCBub2RlIGZvciB0aGlzIC9wcm9jIGVudHJ5CiAqCiAqIENyZWF0ZXMgL3Byb2MgZW50cmllcyBmb3Igb3VyIGNvbnRyb2xsZXJzLgogKi8Kc3RhdGljIHZvaWQKbWVnYV9jcmVhdGVfcHJvY19lbnRyeShpbnQgaW5kZXgsIHN0cnVjdCBwcm9jX2Rpcl9lbnRyeSAqcGFyZW50KQp7CglzdHJ1Y3QgcHJvY19kaXJfZW50cnkJKmNvbnRyb2xsZXJfcHJvY19kaXJfZW50cnkgPSBOVUxMOwoJdTgJCXN0cmluZ1s2NF0gPSB7IDAgfTsKCWFkYXB0ZXJfdAkqYWRhcHRlciA9IGhiYV9zb2Z0X3N0YXRlW2luZGV4XTsKCglzcHJpbnRmKHN0cmluZywgImhiYSVkIiwgYWRhcHRlci0+aG9zdC0+aG9zdF9ubyk7CgoJY29udHJvbGxlcl9wcm9jX2Rpcl9lbnRyeSA9CgkJYWRhcHRlci0+Y29udHJvbGxlcl9wcm9jX2Rpcl9lbnRyeSA9IHByb2NfbWtkaXIoc3RyaW5nLCBwYXJlbnQpOwoKCWlmKCFjb250cm9sbGVyX3Byb2NfZGlyX2VudHJ5KSB7CgkJcHJpbnRrKEtFUk5fV0FSTklORyAiXG5tZWdhcmFpZDogcHJvY19ta2RpciBmYWlsZWRcbiIpOwoJCXJldHVybjsKCX0KCWFkYXB0ZXItPnByb2NfcmVhZCA9IENSRUFURV9SRUFEX1BST0MoImNvbmZpZyIsIHByb2NfcmVhZF9jb25maWcpOwoJYWRhcHRlci0+cHJvY19zdGF0ID0gQ1JFQVRFX1JFQURfUFJPQygic3RhdCIsIHByb2NfcmVhZF9zdGF0KTsKCWFkYXB0ZXItPnByb2NfbWJveCA9IENSRUFURV9SRUFEX1BST0MoIm1haWxib3giLCBwcm9jX3JlYWRfbWJveCk7CiNpZiBNRUdBX0hBVkVfRU5IX1BST0MKCWFkYXB0ZXItPnByb2NfcnIgPSBDUkVBVEVfUkVBRF9QUk9DKCJyZWJ1aWxkLXJhdGUiLCBwcm9jX3JlYnVpbGRfcmF0ZSk7CglhZGFwdGVyLT5wcm9jX2JhdHRlcnkgPSBDUkVBVEVfUkVBRF9QUk9DKCJiYXR0ZXJ5LXN0YXR1cyIsCgkJCXByb2NfYmF0dGVyeSk7CgoJLyoKCSAqIERpc3BsYXkgZWFjaCBwaHlzaWNhbCBkcml2ZSBvbiBpdHMgY2hhbm5lbAoJICovCglhZGFwdGVyLT5wcm9jX3BkcnZzdGF0WzBdID0gQ1JFQVRFX1JFQURfUFJPQygiZGlza2RyaXZlcy1jaDAiLAoJCQkJCXByb2NfcGRydl9jaDApOwoJYWRhcHRlci0+cHJvY19wZHJ2c3RhdFsxXSA9IENSRUFURV9SRUFEX1BST0MoImRpc2tkcml2ZXMtY2gxIiwKCQkJCQlwcm9jX3BkcnZfY2gxKTsKCWFkYXB0ZXItPnByb2NfcGRydnN0YXRbMl0gPSBDUkVBVEVfUkVBRF9QUk9DKCJkaXNrZHJpdmVzLWNoMiIsCgkJCQkJcHJvY19wZHJ2X2NoMik7CglhZGFwdGVyLT5wcm9jX3BkcnZzdGF0WzNdID0gQ1JFQVRFX1JFQURfUFJPQygiZGlza2RyaXZlcy1jaDMiLAoJCQkJCXByb2NfcGRydl9jaDMpOwoKCS8qCgkgKiBEaXNwbGF5IGEgc2V0IG9mIHVwIHRvIDEwIGxvZ2ljYWwgZHJpdmUgdGhyb3VnaCBlYWNoIG9mIGZvbGxvd2luZwoJICogL3Byb2MgZW50cmllcwoJICovCglhZGFwdGVyLT5wcm9jX3JkcnZzdGF0WzBdID0gQ1JFQVRFX1JFQURfUFJPQygicmFpZGRyaXZlcy0wLTkiLAoJCQkJCXByb2NfcmRydl8xMCk7CglhZGFwdGVyLT5wcm9jX3JkcnZzdGF0WzFdID0gQ1JFQVRFX1JFQURfUFJPQygicmFpZGRyaXZlcy0xMC0xOSIsCgkJCQkJcHJvY19yZHJ2XzIwKTsKCWFkYXB0ZXItPnByb2NfcmRydnN0YXRbMl0gPSBDUkVBVEVfUkVBRF9QUk9DKCJyYWlkZHJpdmVzLTIwLTI5IiwKCQkJCQlwcm9jX3JkcnZfMzApOwoJYWRhcHRlci0+cHJvY19yZHJ2c3RhdFszXSA9IENSRUFURV9SRUFEX1BST0MoInJhaWRkcml2ZXMtMzAtMzkiLAoJCQkJCXByb2NfcmRydl80MCk7CiNlbmRpZgp9CgoKLyoqCiAqIHByb2NfcmVhZF9jb25maWcoKQogKiBAcGFnZSAtIGJ1ZmZlciB0byB3cml0ZSB0aGUgZGF0YSBpbgogKiBAc3RhcnQgLSB3aGVyZSB0aGUgYWN0dWFsIGRhdGEgaGFzIGJlZW4gd3JpdHRlbiBpbiBwYWdlCiAqIEBvZmZzZXQgLSBzYW1lIG1lYW5pbmcgYXMgdGhlIHJlYWQgc3lzdGVtIGNhbGwKICogQGNvdW50IC0gc2FtZSBtZWFuaW5nIGFzIHRoZSByZWFkIHN5c3RlbSBjYWxsCiAqIEBlb2YgLSBzZXQgaWYgbm8gbW9yZSBkYXRhIG5lZWRzIHRvIGJlIHJldHVybmVkCiAqIEBkYXRhIC0gcG9pbnRlciB0byBvdXIgc29mdCBzdGF0ZQogKgogKiBEaXNwbGF5IGNvbmZpZ3VyYXRpb24gaW5mb3JtYXRpb24gYWJvdXQgdGhlIGNvbnRyb2xsZXIuCiAqLwpzdGF0aWMgaW50CnByb2NfcmVhZF9jb25maWcoY2hhciAqcGFnZSwgY2hhciAqKnN0YXJ0LCBvZmZfdCBvZmZzZXQsIGludCBjb3VudCwgaW50ICplb2YsCgkJdm9pZCAqZGF0YSkKewoKCWFkYXB0ZXJfdCAqYWRhcHRlciA9IChhZGFwdGVyX3QgKilkYXRhOwoJaW50IGxlbiA9IDA7CgoJbGVuICs9IHNwcmludGYocGFnZStsZW4sICIlcyIsIE1FR0FSQUlEX1ZFUlNJT04pOwoKCWlmKGFkYXB0ZXItPnByb2R1Y3RfaW5mby5wcm9kdWN0X25hbWVbMF0pCgkJbGVuICs9IHNwcmludGYocGFnZStsZW4sICIlc1xuIiwKCQkJCWFkYXB0ZXItPnByb2R1Y3RfaW5mby5wcm9kdWN0X25hbWUpOwoKCWxlbiArPSBzcHJpbnRmKHBhZ2UrbGVuLCAiQ29udHJvbGxlciBUeXBlOiAiKTsKCglpZiggYWRhcHRlci0+ZmxhZyAmIEJPQVJEX01FTU1BUCApIHsKCQlsZW4gKz0gc3ByaW50ZihwYWdlK2xlbiwKCQkJIjQzOC80NjYvNDY3LzQ3MS80OTMvNTE4LzUyMC81MzEvNTMyXG4iKTsKCX0KCWVsc2UgewoJCWxlbiArPSBzcHJpbnRmKHBhZ2UrbGVuLAoJCQkiNDE4LzQyOC80MzRcbiIpOwoJfQoKCWlmKGFkYXB0ZXItPmZsYWcgJiBCT0FSRF80MExEKSB7CgkJbGVuICs9IHNwcmludGYocGFnZStsZW4sCgkJCQkiQ29udHJvbGxlciBTdXBwb3J0cyA0MCBMb2dpY2FsIERyaXZlc1xuIik7Cgl9CgoJaWYoYWRhcHRlci0+ZmxhZyAmIEJPQVJEXzY0QklUKSB7CgkJbGVuICs9IHNwcmludGYocGFnZStsZW4sCgkJIkNvbnRyb2xsZXIgY2FwYWJsZSBvZiA2NC1iaXQgbWVtb3J5IGFkZHJlc3NpbmdcbiIpOwoJfQoJaWYoIGFkYXB0ZXItPmhhc182NGJpdF9hZGRyICkgewoJCWxlbiArPSBzcHJpbnRmKHBhZ2UrbGVuLAoJCQkiQ29udHJvbGxlciB1c2luZyA2NC1iaXQgbWVtb3J5IGFkZHJlc3NpbmdcbiIpOwoJfQoJZWxzZSB7CgkJbGVuICs9IHNwcmludGYocGFnZStsZW4sCgkJCSJDb250cm9sbGVyIGlzIG5vdCB1c2luZyA2NC1iaXQgbWVtb3J5IGFkZHJlc3NpbmdcbiIpOwoJfQoKCWxlbiArPSBzcHJpbnRmKHBhZ2UrbGVuLCAiQmFzZSA9ICUwOGx4LCBJcnEgPSAlZCwgIiwgYWRhcHRlci0+YmFzZSwKCQkJYWRhcHRlci0+aG9zdC0+aXJxKTsKCglsZW4gKz0gc3ByaW50ZihwYWdlK2xlbiwgIkxvZ2ljYWwgRHJpdmVzID0gJWQsIENoYW5uZWxzID0gJWRcbiIsCgkJCWFkYXB0ZXItPm51bWxkcnYsIGFkYXB0ZXItPnByb2R1Y3RfaW5mby5uY2hhbm5lbHMpOwoKCWxlbiArPSBzcHJpbnRmKHBhZ2UrbGVuLCAiVmVyc2lvbiA9JXM6JXMsIERSQU0gPSAlZE1iXG4iLAoJCQlhZGFwdGVyLT5md192ZXJzaW9uLCBhZGFwdGVyLT5iaW9zX3ZlcnNpb24sCgkJCWFkYXB0ZXItPnByb2R1Y3RfaW5mby5kcmFtX3NpemUpOwoKCWxlbiArPSBzcHJpbnRmKHBhZ2UrbGVuLAoJCSJDb250cm9sbGVyIFF1ZXVlIERlcHRoID0gJWQsIERyaXZlciBRdWV1ZSBEZXB0aCA9ICVkXG4iLAoJCWFkYXB0ZXItPnByb2R1Y3RfaW5mby5tYXhfY29tbWFuZHMsIGFkYXB0ZXItPm1heF9jbWRzKTsKCglsZW4gKz0gc3ByaW50ZihwYWdlK2xlbiwgInN1cHBvcnRfZXh0X2NkYiAgICA9ICVkXG4iLAoJCQlhZGFwdGVyLT5zdXBwb3J0X2V4dF9jZGIpOwoJbGVuICs9IHNwcmludGYocGFnZStsZW4sICJzdXBwb3J0X3JhbmRvbV9kZWwgPSAlZFxuIiwKCQkJYWRhcHRlci0+c3VwcG9ydF9yYW5kb21fZGVsKTsKCWxlbiArPSBzcHJpbnRmKHBhZ2UrbGVuLCAiYm9vdF9sZHJ2X2VuYWJsZWQgID0gJWRcbiIsCgkJCWFkYXB0ZXItPmJvb3RfbGRydl9lbmFibGVkKTsKCWxlbiArPSBzcHJpbnRmKHBhZ2UrbGVuLCAiYm9vdF9sZHJ2ICAgICAgICAgID0gJWRcbiIsCgkJCWFkYXB0ZXItPmJvb3RfbGRydik7CglsZW4gKz0gc3ByaW50ZihwYWdlK2xlbiwgImJvb3RfcGRydl9lbmFibGVkICA9ICVkXG4iLAoJCQlhZGFwdGVyLT5ib290X3BkcnZfZW5hYmxlZCk7CglsZW4gKz0gc3ByaW50ZihwYWdlK2xlbiwgImJvb3RfcGRydl9jaCAgICAgICA9ICVkXG4iLAoJCQlhZGFwdGVyLT5ib290X3BkcnZfY2gpOwoJbGVuICs9IHNwcmludGYocGFnZStsZW4sICJib290X3BkcnZfdGd0ICAgICAgPSAlZFxuIiwKCQkJYWRhcHRlci0+Ym9vdF9wZHJ2X3RndCk7CglsZW4gKz0gc3ByaW50ZihwYWdlK2xlbiwgInF1aWVzY2VudCAgICAgICAgICA9ICVkXG4iLAoJCQlhdG9taWNfcmVhZCgmYWRhcHRlci0+cXVpZXNjZW50KSk7CglsZW4gKz0gc3ByaW50ZihwYWdlK2xlbiwgImhhc19jbHVzdGVyICAgICAgICA9ICVkXG4iLAoJCQlhZGFwdGVyLT5oYXNfY2x1c3Rlcik7CgoJbGVuICs9IHNwcmludGYocGFnZStsZW4sICJcbk1vZHVsZSBQYXJhbWV0ZXJzOlxuIik7CglsZW4gKz0gc3ByaW50ZihwYWdlK2xlbiwgIm1heF9jbWRfcGVyX2x1biAgICA9ICVkXG4iLAoJCQltYXhfY21kX3Blcl9sdW4pOwoJbGVuICs9IHNwcmludGYocGFnZStsZW4sICJtYXhfc2VjdG9yc19wZXJfaW8gPSAlZFxuIiwKCQkJbWF4X3NlY3RvcnNfcGVyX2lvKTsKCgkqZW9mID0gMTsKCglyZXR1cm4gbGVuOwp9CgoKCi8qKgogKiBwcm9jX3JlYWRfc3RhdCgpCiAqIEBwYWdlIC0gYnVmZmVyIHRvIHdyaXRlIHRoZSBkYXRhIGluCiAqIEBzdGFydCAtIHdoZXJlIHRoZSBhY3R1YWwgZGF0YSBoYXMgYmVlbiB3cml0dGVuIGluIHBhZ2UKICogQG9mZnNldCAtIHNhbWUgbWVhbmluZyBhcyB0aGUgcmVhZCBzeXN0ZW0gY2FsbAogKiBAY291bnQgLSBzYW1lIG1lYW5pbmcgYXMgdGhlIHJlYWQgc3lzdGVtIGNhbGwKICogQGVvZiAtIHNldCBpZiBubyBtb3JlIGRhdGEgbmVlZHMgdG8gYmUgcmV0dXJuZWQKICogQGRhdGEgLSBwb2ludGVyIHRvIG91ciBzb2Z0IHN0YXRlCiAqCiAqIERpYXBsYXkgc3RhdGlzdGljYWwgaW5mb3JtYXRpb24gYWJvdXQgdGhlIEkvTyBhY3Rpdml0eS4KICovCnN0YXRpYyBpbnQKcHJvY19yZWFkX3N0YXQoY2hhciAqcGFnZSwgY2hhciAqKnN0YXJ0LCBvZmZfdCBvZmZzZXQsIGludCBjb3VudCwgaW50ICplb2YsCgkJdm9pZCAqZGF0YSkKewoJYWRhcHRlcl90CSphZGFwdGVyOwoJaW50CWxlbjsKCWludAlpOwoKCWkgPSAwOwkvKiBhdm9pZCBjb21waWxhdGlvbiB3YXJuaW5ncyAqLwoJbGVuID0gMDsKCWFkYXB0ZXIgPSAoYWRhcHRlcl90ICopZGF0YTsKCglsZW4gPSBzcHJpbnRmKHBhZ2UsICJTdGF0aXN0aWNhbCBJbmZvcm1hdGlvbiBmb3IgdGhpcyBjb250cm9sbGVyXG4iKTsKCWxlbiArPSBzcHJpbnRmKHBhZ2UrbGVuLCAicGVuZF9jbWRzID0gJWRcbiIsCgkJCWF0b21pY19yZWFkKCZhZGFwdGVyLT5wZW5kX2NtZHMpKTsKI2lmIE1FR0FfSEFWRV9TVEFUUwoJZm9yKGkgPSAwOyBpIDwgYWRhcHRlci0+bnVtbGRydjsgaSsrKSB7CgkJbGVuICs9IHNwcmludGYocGFnZStsZW4sICJMb2dpY2FsIERyaXZlICVkOlxuIiwgaSk7CgoJCWxlbiArPSBzcHJpbnRmKHBhZ2UrbGVuLAoJCQkiXHRSZWFkcyBJc3N1ZWQgPSAlbHUsIFdyaXRlcyBJc3N1ZWQgPSAlbHVcbiIsCgkJCWFkYXB0ZXItPm5yZWFkc1tpXSwgYWRhcHRlci0+bndyaXRlc1tpXSk7CgoJCWxlbiArPSBzcHJpbnRmKHBhZ2UrbGVuLAoJCQkiXHRTZWN0b3JzIFJlYWQgPSAlbHUsIFNlY3RvcnMgV3JpdHRlbiA9ICVsdVxuIiwKCQkJYWRhcHRlci0+bnJlYWRibG9ja3NbaV0sIGFkYXB0ZXItPm53cml0ZWJsb2Nrc1tpXSk7CgoJCWxlbiArPSBzcHJpbnRmKHBhZ2UrbGVuLAoJCQkiXHRSZWFkIGVycm9ycyA9ICVsdSwgV3JpdGUgZXJyb3JzID0gJWx1XG5cbiIsCgkJCWFkYXB0ZXItPnJkX2Vycm9yc1tpXSwgYWRhcHRlci0+d3JfZXJyb3JzW2ldKTsKCX0KI2Vsc2UKCWxlbiArPSBzcHJpbnRmKHBhZ2UrbGVuLAoJCQkiSU8gYW5kIGVycm9yIGNvdW50ZXJzIG5vdCBjb21waWxlZCBpbiBkcml2ZXIuXG4iKTsKI2VuZGlmCgoJKmVvZiA9IDE7CgoJcmV0dXJuIGxlbjsKfQoKCi8qKgogKiBwcm9jX3JlYWRfbWJveCgpCiAqIEBwYWdlIC0gYnVmZmVyIHRvIHdyaXRlIHRoZSBkYXRhIGluCiAqIEBzdGFydCAtIHdoZXJlIHRoZSBhY3R1YWwgZGF0YSBoYXMgYmVlbiB3cml0dGVuIGluIHBhZ2UKICogQG9mZnNldCAtIHNhbWUgbWVhbmluZyBhcyB0aGUgcmVhZCBzeXN0ZW0gY2FsbAogKiBAY291bnQgLSBzYW1lIG1lYW5pbmcgYXMgdGhlIHJlYWQgc3lzdGVtIGNhbGwKICogQGVvZiAtIHNldCBpZiBubyBtb3JlIGRhdGEgbmVlZHMgdG8gYmUgcmV0dXJuZWQKICogQGRhdGEgLSBwb2ludGVyIHRvIG91ciBzb2Z0IHN0YXRlCiAqCiAqIERpc3BsYXkgbWFpbGJveCBpbmZvcm1hdGlvbiBmb3IgdGhlIGxhc3QgY29tbWFuZCBpc3N1ZWQuIFRoaXMgaW5mb3JtYXRpb24KICogaXMgZ29vZCBmb3IgZGVidWdnaW5nLgogKi8Kc3RhdGljIGludApwcm9jX3JlYWRfbWJveChjaGFyICpwYWdlLCBjaGFyICoqc3RhcnQsIG9mZl90IG9mZnNldCwgaW50IGNvdW50LCBpbnQgKmVvZiwKCQl2b2lkICpkYXRhKQp7CgoJYWRhcHRlcl90CSphZGFwdGVyID0gKGFkYXB0ZXJfdCAqKWRhdGE7Cgl2b2xhdGlsZSBtYm94X3QJKm1ib3ggPSBhZGFwdGVyLT5tYm94OwoJaW50CWxlbiA9IDA7CgoJbGVuID0gc3ByaW50ZihwYWdlLCAiQ29udGVudHMgb2YgTWFpbCBCb3ggU3RydWN0dXJlXG4iKTsKCWxlbiArPSBzcHJpbnRmKHBhZ2UrbGVuLCAiICBGdyBDb21tYW5kICAgPSAweCUwMnhcbiIsIAoJCQltYm94LT5tX291dC5jbWQpOwoJbGVuICs9IHNwcmludGYocGFnZStsZW4sICIgIENtZCBTZXF1ZW5jZSA9IDB4JTAyeFxuIiwgCgkJCW1ib3gtPm1fb3V0LmNtZGlkKTsKCWxlbiArPSBzcHJpbnRmKHBhZ2UrbGVuLCAiICBObyBvZiBTZWN0b3JzPSAlMDRkXG4iLCAKCQkJbWJveC0+bV9vdXQubnVtc2VjdG9ycyk7CglsZW4gKz0gc3ByaW50ZihwYWdlK2xlbiwgIiAgTEJBICAgICAgICAgID0gMHglMDJ4XG4iLCAKCQkJbWJveC0+bV9vdXQubGJhKTsKCWxlbiArPSBzcHJpbnRmKHBhZ2UrbGVuLCAiICBEVEEgICAgICAgICAgPSAweCUwOHhcbiIsIAoJCQltYm94LT5tX291dC54ZmVyYWRkcik7CglsZW4gKz0gc3ByaW50ZihwYWdlK2xlbiwgIiAgTG9naWNhbCBEcml2ZT0gMHglMDJ4XG4iLCAKCQkJbWJveC0+bV9vdXQubG9nZHJ2KTsKCWxlbiArPSBzcHJpbnRmKHBhZ2UrbGVuLCAiICBObyBvZiBTRyBFbG10PSAweCUwMnhcbiIsCgkJCW1ib3gtPm1fb3V0Lm51bXNnZWxlbWVudHMpOwoJbGVuICs9IHNwcmludGYocGFnZStsZW4sICIgIEJ1c3kgICAgICAgICA9ICUwMXhcbiIsIAoJCQltYm94LT5tX2luLmJ1c3kpOwoJbGVuICs9IHNwcmludGYocGFnZStsZW4sICIgIFN0YXR1cyAgICAgICA9IDB4JTAyeFxuIiwgCgkJCW1ib3gtPm1faW4uc3RhdHVzKTsKCgkqZW9mID0gMTsKCglyZXR1cm4gbGVuOwp9CgoKLyoqCiAqIHByb2NfcmVidWlsZF9yYXRlKCkKICogQHBhZ2UgLSBidWZmZXIgdG8gd3JpdGUgdGhlIGRhdGEgaW4KICogQHN0YXJ0IC0gd2hlcmUgdGhlIGFjdHVhbCBkYXRhIGhhcyBiZWVuIHdyaXR0ZW4gaW4gcGFnZQogKiBAb2Zmc2V0IC0gc2FtZSBtZWFuaW5nIGFzIHRoZSByZWFkIHN5c3RlbSBjYWxsCiAqIEBjb3VudCAtIHNhbWUgbWVhbmluZyBhcyB0aGUgcmVhZCBzeXN0ZW0gY2FsbAogKiBAZW9mIC0gc2V0IGlmIG5vIG1vcmUgZGF0YSBuZWVkcyB0byBiZSByZXR1cm5lZAogKiBAZGF0YSAtIHBvaW50ZXIgdG8gb3VyIHNvZnQgc3RhdGUKICoKICogRGlzcGxheSBjdXJyZW50IHJlYnVpbGQgcmF0ZQogKi8Kc3RhdGljIGludApwcm9jX3JlYnVpbGRfcmF0ZShjaGFyICpwYWdlLCBjaGFyICoqc3RhcnQsIG9mZl90IG9mZnNldCwgaW50IGNvdW50LCBpbnQgKmVvZiwKCQl2b2lkICpkYXRhKQp7CglhZGFwdGVyX3QJKmFkYXB0ZXIgPSAoYWRhcHRlcl90ICopZGF0YTsKCWRtYV9hZGRyX3QJZG1hX2hhbmRsZTsKCWNhZGRyX3QJCWlucXVpcnk7CglzdHJ1Y3QgcGNpX2RldgkqcGRldjsKCWludAlsZW4gPSAwOwoKCWlmKCBtYWtlX2xvY2FsX3BkZXYoYWRhcHRlciwgJnBkZXYpICE9IDAgKSB7CgkJKmVvZiA9IDE7CgkJcmV0dXJuIGxlbjsKCX0KCglpZiggKGlucXVpcnkgPSBtZWdhX2FsbG9jYXRlX2lucXVpcnkoJmRtYV9oYW5kbGUsIHBkZXYpKSA9PSBOVUxMICkgewoJCWZyZWVfbG9jYWxfcGRldihwZGV2KTsKCQkqZW9mID0gMTsKCQlyZXR1cm4gbGVuOwoJfQoKCWlmKCBtZWdhX2FkYXBpbnEoYWRhcHRlciwgZG1hX2hhbmRsZSkgIT0gMCApIHsKCgkJbGVuID0gc3ByaW50ZihwYWdlLCAiQWRhcHRlciBpbnF1aXJ5IGZhaWxlZC5cbiIpOwoKCQlwcmludGsoS0VSTl9XQVJOSU5HICJtZWdhcmFpZDogaW5xdWlyeSBmYWlsZWQuXG4iKTsKCgkJbWVnYV9mcmVlX2lucXVpcnkoaW5xdWlyeSwgZG1hX2hhbmRsZSwgcGRldik7CgoJCWZyZWVfbG9jYWxfcGRldihwZGV2KTsKCgkJKmVvZiA9IDE7CgoJCXJldHVybiBsZW47Cgl9CgoJaWYoIGFkYXB0ZXItPmZsYWcgJiBCT0FSRF80MExEICkgewoJCWxlbiA9IHNwcmludGYocGFnZSwgIlJlYnVpbGQgUmF0ZTogWyVkJSVdXG4iLAoJCQkoKG1lZ2FfaW5xdWlyeTMgKilpbnF1aXJ5KS0+cmVidWlsZF9yYXRlKTsKCX0KCWVsc2UgewoJCWxlbiA9IHNwcmludGYocGFnZSwgIlJlYnVpbGQgUmF0ZTogWyVkJSVdXG4iLAoJCQkoKG1yYWlkX2V4dF9pbnF1aXJ5ICopCgkJCWlucXVpcnkpLT5yYWlkX2lucS5hZGFwdGVyX2luZm8ucmVidWlsZF9yYXRlKTsKCX0KCgoJbWVnYV9mcmVlX2lucXVpcnkoaW5xdWlyeSwgZG1hX2hhbmRsZSwgcGRldik7CgoJZnJlZV9sb2NhbF9wZGV2KHBkZXYpOwoKCSplb2YgPSAxOwoKCXJldHVybiBsZW47Cn0KCgovKioKICogcHJvY19iYXR0ZXJ5KCkKICogQHBhZ2UgLSBidWZmZXIgdG8gd3JpdGUgdGhlIGRhdGEgaW4KICogQHN0YXJ0IC0gd2hlcmUgdGhlIGFjdHVhbCBkYXRhIGhhcyBiZWVuIHdyaXR0ZW4gaW4gcGFnZQogKiBAb2Zmc2V0IC0gc2FtZSBtZWFuaW5nIGFzIHRoZSByZWFkIHN5c3RlbSBjYWxsCiAqIEBjb3VudCAtIHNhbWUgbWVhbmluZyBhcyB0aGUgcmVhZCBzeXN0ZW0gY2FsbAogKiBAZW9mIC0gc2V0IGlmIG5vIG1vcmUgZGF0YSBuZWVkcyB0byBiZSByZXR1cm5lZAogKiBAZGF0YSAtIHBvaW50ZXIgdG8gb3VyIHNvZnQgc3RhdGUKICoKICogRGlzcGxheSBpbmZvcm1hdGlvbiBhYm91dCB0aGUgYmF0dGVyeSBtb2R1bGUgb24gdGhlIGNvbnRyb2xsZXIuCiAqLwpzdGF0aWMgaW50CnByb2NfYmF0dGVyeShjaGFyICpwYWdlLCBjaGFyICoqc3RhcnQsIG9mZl90IG9mZnNldCwgaW50IGNvdW50LCBpbnQgKmVvZiwKCQl2b2lkICpkYXRhKQp7CglhZGFwdGVyX3QJKmFkYXB0ZXIgPSAoYWRhcHRlcl90ICopZGF0YTsKCWRtYV9hZGRyX3QJZG1hX2hhbmRsZTsKCWNhZGRyX3QJCWlucXVpcnk7CglzdHJ1Y3QgcGNpX2RldgkqcGRldjsKCXU4CWJhdHRlcnlfc3RhdHVzID0gMDsKCWNoYXIJc3RyWzI1Nl07CglpbnQJbGVuID0gMDsKCglpZiggbWFrZV9sb2NhbF9wZGV2KGFkYXB0ZXIsICZwZGV2KSAhPSAwICkgewoJCSplb2YgPSAxOwoJCXJldHVybiBsZW47Cgl9CgoJaWYoIChpbnF1aXJ5ID0gbWVnYV9hbGxvY2F0ZV9pbnF1aXJ5KCZkbWFfaGFuZGxlLCBwZGV2KSkgPT0gTlVMTCApIHsKCQlmcmVlX2xvY2FsX3BkZXYocGRldik7CgkJKmVvZiA9IDE7CgkJcmV0dXJuIGxlbjsKCX0KCglpZiggbWVnYV9hZGFwaW5xKGFkYXB0ZXIsIGRtYV9oYW5kbGUpICE9IDAgKSB7CgoJCWxlbiA9IHNwcmludGYocGFnZSwgIkFkYXB0ZXIgaW5xdWlyeSBmYWlsZWQuXG4iKTsKCgkJcHJpbnRrKEtFUk5fV0FSTklORyAibWVnYXJhaWQ6IGlucXVpcnkgZmFpbGVkLlxuIik7CgoJCW1lZ2FfZnJlZV9pbnF1aXJ5KGlucXVpcnksIGRtYV9oYW5kbGUsIHBkZXYpOwoKCQlmcmVlX2xvY2FsX3BkZXYocGRldik7CgoJCSplb2YgPSAxOwoKCQlyZXR1cm4gbGVuOwoJfQoKCWlmKCBhZGFwdGVyLT5mbGFnICYgQk9BUkRfNDBMRCApIHsKCQliYXR0ZXJ5X3N0YXR1cyA9ICgobWVnYV9pbnF1aXJ5MyAqKWlucXVpcnkpLT5iYXR0ZXJ5X3N0YXR1czsKCX0KCWVsc2UgewoJCWJhdHRlcnlfc3RhdHVzID0gKChtcmFpZF9leHRfaW5xdWlyeSAqKWlucXVpcnkpLT4KCQkJcmFpZF9pbnEuYWRhcHRlcl9pbmZvLmJhdHRlcnlfc3RhdHVzOwoJfQoKCS8qCgkgKiBEZWNvZGUgdGhlIGJhdHRlcnkgc3RhdHVzCgkgKi8KCXNwcmludGYoc3RyLCAiQmF0dGVyeSBTdGF0dXM6WyVkXSIsIGJhdHRlcnlfc3RhdHVzKTsKCglpZihiYXR0ZXJ5X3N0YXR1cyA9PSBNRUdBX0JBVFRfQ0hBUkdFX0RPTkUpCgkJc3RyY2F0KHN0ciwgIiBDaGFyZ2UgRG9uZSIpOwoKCWlmKGJhdHRlcnlfc3RhdHVzICYgTUVHQV9CQVRUX01PRFVMRV9NSVNTSU5HKQoJCXN0cmNhdChzdHIsICIgTW9kdWxlIE1pc3NpbmciKTsKCQoJaWYoYmF0dGVyeV9zdGF0dXMgJiBNRUdBX0JBVFRfTE9XX1ZPTFRBR0UpCgkJc3RyY2F0KHN0ciwgIiBMb3cgVm9sdGFnZSIpOwoJCglpZihiYXR0ZXJ5X3N0YXR1cyAmIE1FR0FfQkFUVF9URU1QX0hJR0gpCgkJc3RyY2F0KHN0ciwgIiBUZW1wZXJhdHVyZSBIaWdoIik7CgkKCWlmKGJhdHRlcnlfc3RhdHVzICYgTUVHQV9CQVRUX1BBQ0tfTUlTU0lORykKCQlzdHJjYXQoc3RyLCAiIFBhY2sgTWlzc2luZyIpOwoJCglpZihiYXR0ZXJ5X3N0YXR1cyAmIE1FR0FfQkFUVF9DSEFSR0VfSU5QUk9HKQoJCXN0cmNhdChzdHIsICIgQ2hhcmdlIEluLXByb2dyZXNzIik7CgkKCWlmKGJhdHRlcnlfc3RhdHVzICYgTUVHQV9CQVRUX0NIQVJHRV9GQUlMKQoJCXN0cmNhdChzdHIsICIgQ2hhcmdlIEZhaWwiKTsKCQoJaWYoYmF0dGVyeV9zdGF0dXMgJiBNRUdBX0JBVFRfQ1lDTEVTX0VYQ0VFREVEKQoJCXN0cmNhdChzdHIsICIgQ3ljbGVzIEV4Y2VlZGVkIik7CgoJbGVuID0gc3ByaW50ZihwYWdlLCAiJXNcbiIsIHN0cik7CgoKCW1lZ2FfZnJlZV9pbnF1aXJ5KGlucXVpcnksIGRtYV9oYW5kbGUsIHBkZXYpOwoKCWZyZWVfbG9jYWxfcGRldihwZGV2KTsKCgkqZW9mID0gMTsKCglyZXR1cm4gbGVuOwp9CgoKLyoqCiAqIHByb2NfcGRydl9jaDAoKQogKiBAcGFnZSAtIGJ1ZmZlciB0byB3cml0ZSB0aGUgZGF0YSBpbgogKiBAc3RhcnQgLSB3aGVyZSB0aGUgYWN0dWFsIGRhdGEgaGFzIGJlZW4gd3JpdHRlbiBpbiBwYWdlCiAqIEBvZmZzZXQgLSBzYW1lIG1lYW5pbmcgYXMgdGhlIHJlYWQgc3lzdGVtIGNhbGwKICogQGNvdW50IC0gc2FtZSBtZWFuaW5nIGFzIHRoZSByZWFkIHN5c3RlbSBjYWxsCiAqIEBlb2YgLSBzZXQgaWYgbm8gbW9yZSBkYXRhIG5lZWRzIHRvIGJlIHJldHVybmVkCiAqIEBkYXRhIC0gcG9pbnRlciB0byBvdXIgc29mdCBzdGF0ZQogKgogKiBEaXNwbGF5IGluZm9ybWF0aW9uIGFib3V0IHRoZSBwaHlzaWNhbCBkcml2ZXMgb24gcGh5c2ljYWwgY2hhbm5lbCAwLgogKi8Kc3RhdGljIGludApwcm9jX3BkcnZfY2gwKGNoYXIgKnBhZ2UsIGNoYXIgKipzdGFydCwgb2ZmX3Qgb2Zmc2V0LCBpbnQgY291bnQsIGludCAqZW9mLAoJCXZvaWQgKmRhdGEpCnsKCWFkYXB0ZXJfdCAqYWRhcHRlciA9IChhZGFwdGVyX3QgKilkYXRhOwoKCSplb2YgPSAxOwoKCXJldHVybiAocHJvY19wZHJ2KGFkYXB0ZXIsIHBhZ2UsIDApKTsKfQoKCi8qKgogKiBwcm9jX3BkcnZfY2gxKCkKICogQHBhZ2UgLSBidWZmZXIgdG8gd3JpdGUgdGhlIGRhdGEgaW4KICogQHN0YXJ0IC0gd2hlcmUgdGhlIGFjdHVhbCBkYXRhIGhhcyBiZWVuIHdyaXR0ZW4gaW4gcGFnZQogKiBAb2Zmc2V0IC0gc2FtZSBtZWFuaW5nIGFzIHRoZSByZWFkIHN5c3RlbSBjYWxsCiAqIEBjb3VudCAtIHNhbWUgbWVhbmluZyBhcyB0aGUgcmVhZCBzeXN0ZW0gY2FsbAogKiBAZW9mIC0gc2V0IGlmIG5vIG1vcmUgZGF0YSBuZWVkcyB0byBiZSByZXR1cm5lZAogKiBAZGF0YSAtIHBvaW50ZXIgdG8gb3VyIHNvZnQgc3RhdGUKICoKICogRGlzcGxheSBpbmZvcm1hdGlvbiBhYm91dCB0aGUgcGh5c2ljYWwgZHJpdmVzIG9uIHBoeXNpY2FsIGNoYW5uZWwgMS4KICovCnN0YXRpYyBpbnQKcHJvY19wZHJ2X2NoMShjaGFyICpwYWdlLCBjaGFyICoqc3RhcnQsIG9mZl90IG9mZnNldCwgaW50IGNvdW50LCBpbnQgKmVvZiwKCQl2b2lkICpkYXRhKQp7CglhZGFwdGVyX3QgKmFkYXB0ZXIgPSAoYWRhcHRlcl90ICopZGF0YTsKCgkqZW9mID0gMTsKCglyZXR1cm4gKHByb2NfcGRydihhZGFwdGVyLCBwYWdlLCAxKSk7Cn0KCgovKioKICogcHJvY19wZHJ2X2NoMigpCiAqIEBwYWdlIC0gYnVmZmVyIHRvIHdyaXRlIHRoZSBkYXRhIGluCiAqIEBzdGFydCAtIHdoZXJlIHRoZSBhY3R1YWwgZGF0YSBoYXMgYmVlbiB3cml0dGVuIGluIHBhZ2UKICogQG9mZnNldCAtIHNhbWUgbWVhbmluZyBhcyB0aGUgcmVhZCBzeXN0ZW0gY2FsbAogKiBAY291bnQgLSBzYW1lIG1lYW5pbmcgYXMgdGhlIHJlYWQgc3lzdGVtIGNhbGwKICogQGVvZiAtIHNldCBpZiBubyBtb3JlIGRhdGEgbmVlZHMgdG8gYmUgcmV0dXJuZWQKICogQGRhdGEgLSBwb2ludGVyIHRvIG91ciBzb2Z0IHN0YXRlCiAqCiAqIERpc3BsYXkgaW5mb3JtYXRpb24gYWJvdXQgdGhlIHBoeXNpY2FsIGRyaXZlcyBvbiBwaHlzaWNhbCBjaGFubmVsIDIuCiAqLwpzdGF0aWMgaW50CnByb2NfcGRydl9jaDIoY2hhciAqcGFnZSwgY2hhciAqKnN0YXJ0LCBvZmZfdCBvZmZzZXQsIGludCBjb3VudCwgaW50ICplb2YsCgkJdm9pZCAqZGF0YSkKewoJYWRhcHRlcl90ICphZGFwdGVyID0gKGFkYXB0ZXJfdCAqKWRhdGE7CgoJKmVvZiA9IDE7CgoJcmV0dXJuIChwcm9jX3BkcnYoYWRhcHRlciwgcGFnZSwgMikpOwp9CgoKLyoqCiAqIHByb2NfcGRydl9jaDMoKQogKiBAcGFnZSAtIGJ1ZmZlciB0byB3cml0ZSB0aGUgZGF0YSBpbgogKiBAc3RhcnQgLSB3aGVyZSB0aGUgYWN0dWFsIGRhdGEgaGFzIGJlZW4gd3JpdHRlbiBpbiBwYWdlCiAqIEBvZmZzZXQgLSBzYW1lIG1lYW5pbmcgYXMgdGhlIHJlYWQgc3lzdGVtIGNhbGwKICogQGNvdW50IC0gc2FtZSBtZWFuaW5nIGFzIHRoZSByZWFkIHN5c3RlbSBjYWxsCiAqIEBlb2YgLSBzZXQgaWYgbm8gbW9yZSBkYXRhIG5lZWRzIHRvIGJlIHJldHVybmVkCiAqIEBkYXRhIC0gcG9pbnRlciB0byBvdXIgc29mdCBzdGF0ZQogKgogKiBEaXNwbGF5IGluZm9ybWF0aW9uIGFib3V0IHRoZSBwaHlzaWNhbCBkcml2ZXMgb24gcGh5c2ljYWwgY2hhbm5lbCAzLgogKi8Kc3RhdGljIGludApwcm9jX3BkcnZfY2gzKGNoYXIgKnBhZ2UsIGNoYXIgKipzdGFydCwgb2ZmX3Qgb2Zmc2V0LCBpbnQgY291bnQsIGludCAqZW9mLAoJCXZvaWQgKmRhdGEpCnsKCWFkYXB0ZXJfdCAqYWRhcHRlciA9IChhZGFwdGVyX3QgKilkYXRhOwoKCSplb2YgPSAxOwoKCXJldHVybiAocHJvY19wZHJ2KGFkYXB0ZXIsIHBhZ2UsIDMpKTsKfQoKCi8qKgogKiBwcm9jX3BkcnYoKQogKiBAcGFnZSAtIGJ1ZmZlciB0byB3cml0ZSB0aGUgZGF0YSBpbgogKiBAYWRhcHRlciAtIHBvaW50ZXIgdG8gb3VyIHNvZnQgc3RhdGUKICoKICogRGlzcGxheSBpbmZvcm1hdGlvbiBhYm91dCB0aGUgcGh5c2ljYWwgZHJpdmVzLgogKi8Kc3RhdGljIGludApwcm9jX3BkcnYoYWRhcHRlcl90ICphZGFwdGVyLCBjaGFyICpwYWdlLCBpbnQgY2hhbm5lbCkKewoJZG1hX2FkZHJfdAlkbWFfaGFuZGxlOwoJY2hhcgkJKnNjc2lfaW5xOwoJZG1hX2FkZHJfdAlzY3NpX2lucV9kbWFfaGFuZGxlOwoJY2FkZHJfdAkJaW5xdWlyeTsKCXN0cnVjdCBwY2lfZGV2CSpwZGV2OwoJdTgJKnBkcnZfc3RhdGU7Cgl1OAlzdGF0ZTsKCWludAl0Z3Q7CglpbnQJbWF4X2NoYW5uZWxzOwoJaW50CWxlbiA9IDA7CgljaGFyCXN0cls4MF07CglpbnQJaTsKCglpZiggbWFrZV9sb2NhbF9wZGV2KGFkYXB0ZXIsICZwZGV2KSAhPSAwICkgewoJCXJldHVybiBsZW47Cgl9CgoJaWYoIChpbnF1aXJ5ID0gbWVnYV9hbGxvY2F0ZV9pbnF1aXJ5KCZkbWFfaGFuZGxlLCBwZGV2KSkgPT0gTlVMTCApIHsKCQlnb3RvIGZyZWVfcGRldjsKCX0KCglpZiggbWVnYV9hZGFwaW5xKGFkYXB0ZXIsIGRtYV9oYW5kbGUpICE9IDAgKSB7CgkJbGVuID0gc3ByaW50ZihwYWdlLCAiQWRhcHRlciBpbnF1aXJ5IGZhaWxlZC5cbiIpOwoKCQlwcmludGsoS0VSTl9XQVJOSU5HICJtZWdhcmFpZDogaW5xdWlyeSBmYWlsZWQuXG4iKTsKCgkJZ290byBmcmVlX2lucXVpcnk7Cgl9CgoKCXNjc2lfaW5xID0gcGNpX2FsbG9jX2NvbnNpc3RlbnQocGRldiwgMjU2LCAmc2NzaV9pbnFfZG1hX2hhbmRsZSk7CgoJaWYoIHNjc2lfaW5xID09IE5VTEwgKSB7CgkJbGVuID0gc3ByaW50ZihwYWdlLCAibWVtb3J5IG5vdCBhdmFpbGFibGUgZm9yIHNjc2kgaW5xLlxuIik7CgoJCWdvdG8gZnJlZV9pbnF1aXJ5OwoJfQoKCWlmKCBhZGFwdGVyLT5mbGFnICYgQk9BUkRfNDBMRCApIHsKCQlwZHJ2X3N0YXRlID0gKChtZWdhX2lucXVpcnkzICopaW5xdWlyeSktPnBkcnZfc3RhdGU7Cgl9CgllbHNlIHsKCQlwZHJ2X3N0YXRlID0gKChtcmFpZF9leHRfaW5xdWlyeSAqKWlucXVpcnkpLT4KCQkJcmFpZF9pbnEucGRydl9pbmZvLnBkcnZfc3RhdGU7Cgl9CgoJbWF4X2NoYW5uZWxzID0gYWRhcHRlci0+cHJvZHVjdF9pbmZvLm5jaGFubmVsczsKCglpZiggY2hhbm5lbCA+PSBtYXhfY2hhbm5lbHMgKSB7CgkJZ290byBmcmVlX3BjaTsKCX0KCglmb3IoIHRndCA9IDA7IHRndCA8PSBNQVhfVEFSR0VUOyB0Z3QrKyApIHsKCgkJaSA9IGNoYW5uZWwqMTYgKyB0Z3Q7CgoJCXN0YXRlID0gKihwZHJ2X3N0YXRlICsgaSk7CgoJCXN3aXRjaCggc3RhdGUgJiAweDBGICkgewoKCQljYXNlIFBEUlZfT05MSU5FOgoJCQlzcHJpbnRmKHN0ciwKCQkJIkNoYW5uZWw6JTJkIElkOiUyZCBTdGF0ZTogT25saW5lIiwKCQkJCWNoYW5uZWwsIHRndCk7CgkJCWJyZWFrOwoKCQljYXNlIFBEUlZfRkFJTEVEOgoJCQlzcHJpbnRmKHN0ciwKCQkJIkNoYW5uZWw6JTJkIElkOiUyZCBTdGF0ZTogRmFpbGVkIiwKCQkJCWNoYW5uZWwsIHRndCk7CgkJCWJyZWFrOwoKCQljYXNlIFBEUlZfUkJMRDoKCQkJc3ByaW50ZihzdHIsCgkJCSJDaGFubmVsOiUyZCBJZDolMmQgU3RhdGU6IFJlYnVpbGQiLAoJCQkJY2hhbm5lbCwgdGd0KTsKCQkJYnJlYWs7CgoJCWNhc2UgUERSVl9IT1RTUEFSRToKCQkJc3ByaW50ZihzdHIsCgkJCSJDaGFubmVsOiUyZCBJZDolMmQgU3RhdGU6IEhvdCBzcGFyZSIsCgkJCQljaGFubmVsLCB0Z3QpOwoJCQlicmVhazsKCgkJZGVmYXVsdDoKCQkJc3ByaW50ZihzdHIsCgkJCSJDaGFubmVsOiUyZCBJZDolMmQgU3RhdGU6IFVuLWNvbmZpZ3VyZWQiLAoJCQkJY2hhbm5lbCwgdGd0KTsKCQkJYnJlYWs7CgoJCX0KCgkJLyoKCQkgKiBUaGlzIGludGVyZmFjZSBkaXNwbGF5cyBpbnF1aXJpZXMgZm9yIGRpc2sgZHJpdmVzCgkJICogb25seS4gSW5xdXJpZXMgZm9yIGxvZ2ljYWwgZHJpdmVzIGFuZCBub24tZGlzawoJCSAqIGRldmljZXMgYXJlIGF2YWlsYWJsZSB0aHJvdWdoIC9wcm9jL3Njc2kvc2NzaQoJCSAqLwoJCW1lbXNldChzY3NpX2lucSwgMCwgMjU2KTsKCQlpZiggbWVnYV9pbnRlcm5hbF9kZXZfaW5xdWlyeShhZGFwdGVyLCBjaGFubmVsLCB0Z3QsCgkJCQlzY3NpX2lucV9kbWFfaGFuZGxlKSB8fAoJCQkJKHNjc2lfaW5xWzBdICYgMHgxRikgIT0gVFlQRV9ESVNLICkgewoJCQljb250aW51ZTsKCQl9CgoJCS8qCgkJICogQ2hlY2sgZm9yIG92ZXJmbG93LiBXZSBwcmludCBsZXNzIHRoYW4gMjQwCgkJICogY2hhcmFjdGVycyBmb3IgaW5xdWlyeQoJCSAqLwoJCWlmKCAobGVuICsgMjQwKSA+PSBQQUdFX1NJWkUgKSBicmVhazsKCgkJbGVuICs9IHNwcmludGYocGFnZStsZW4sICIlcy5cbiIsIHN0cik7CgoJCWxlbiArPSBtZWdhX3ByaW50X2lucXVpcnkocGFnZStsZW4sIHNjc2lfaW5xKTsKCX0KCmZyZWVfcGNpOgoJcGNpX2ZyZWVfY29uc2lzdGVudChwZGV2LCAyNTYsIHNjc2lfaW5xLCBzY3NpX2lucV9kbWFfaGFuZGxlKTsKZnJlZV9pbnF1aXJ5OgoJbWVnYV9mcmVlX2lucXVpcnkoaW5xdWlyeSwgZG1hX2hhbmRsZSwgcGRldik7CmZyZWVfcGRldjoKCWZyZWVfbG9jYWxfcGRldihwZGV2KTsKCglyZXR1cm4gbGVuOwp9CgoKLyoKICogRGlzcGxheSBzY3NpIGlucXVpcnkKICovCnN0YXRpYyBpbnQKbWVnYV9wcmludF9pbnF1aXJ5KGNoYXIgKnBhZ2UsIGNoYXIgKnNjc2lfaW5xKQp7CglpbnQJbGVuID0gMDsKCWludAlpOwoKCWxlbiA9IHNwcmludGYocGFnZSwgIiAgVmVuZG9yOiAiKTsKCWZvciggaSA9IDg7IGkgPCAxNjsgaSsrICkgewoJCWxlbiArPSBzcHJpbnRmKHBhZ2UrbGVuLCAiJWMiLCBzY3NpX2lucVtpXSk7Cgl9CgoJbGVuICs9IHNwcmludGYocGFnZStsZW4sICIgIE1vZGVsOiAiKTsKCglmb3IoIGkgPSAxNjsgaSA8IDMyOyBpKysgKSB7CgkJbGVuICs9IHNwcmludGYocGFnZStsZW4sICIlYyIsIHNjc2lfaW5xW2ldKTsKCX0KCglsZW4gKz0gc3ByaW50ZihwYWdlK2xlbiwgIiAgUmV2OiAiKTsKCglmb3IoIGkgPSAzMjsgaSA8IDM2OyBpKysgKSB7CgkJbGVuICs9IHNwcmludGYocGFnZStsZW4sICIlYyIsIHNjc2lfaW5xW2ldKTsKCX0KCglsZW4gKz0gc3ByaW50ZihwYWdlK2xlbiwgIlxuIik7CgoJaSA9IHNjc2lfaW5xWzBdICYgMHgxZjsKCglsZW4gKz0gc3ByaW50ZihwYWdlK2xlbiwgIiAgVHlwZTogICAlcyAiLAoJCWkgPCBNQVhfU0NTSV9ERVZJQ0VfQ09ERSA/IHNjc2lfZGV2aWNlX3R5cGVzW2ldIDoKCQkgICAiVW5rbm93biAgICAgICAgICAiKTsKCglsZW4gKz0gc3ByaW50ZihwYWdlK2xlbiwKCSIgICAgICAgICAgICAgICAgIEFOU0kgU0NTSSByZXZpc2lvbjogJTAyeCIsIHNjc2lfaW5xWzJdICYgMHgwNyk7CgoJaWYoIChzY3NpX2lucVsyXSAmIDB4MDcpID09IDEgJiYgKHNjc2lfaW5xWzNdICYgMHgwZikgPT0gMSApCgkJbGVuICs9IHNwcmludGYocGFnZStsZW4sICIgQ0NTXG4iKTsKCWVsc2UKCQlsZW4gKz0gc3ByaW50ZihwYWdlK2xlbiwgIlxuIik7CgoJcmV0dXJuIGxlbjsKfQoKCi8qKgogKiBwcm9jX3JkcnZfMTAoKQogKiBAcGFnZSAtIGJ1ZmZlciB0byB3cml0ZSB0aGUgZGF0YSBpbgogKiBAc3RhcnQgLSB3aGVyZSB0aGUgYWN0dWFsIGRhdGEgaGFzIGJlZW4gd3JpdHRlbiBpbiBwYWdlCiAqIEBvZmZzZXQgLSBzYW1lIG1lYW5pbmcgYXMgdGhlIHJlYWQgc3lzdGVtIGNhbGwKICogQGNvdW50IC0gc2FtZSBtZWFuaW5nIGFzIHRoZSByZWFkIHN5c3RlbSBjYWxsCiAqIEBlb2YgLSBzZXQgaWYgbm8gbW9yZSBkYXRhIG5lZWRzIHRvIGJlIHJldHVybmVkCiAqIEBkYXRhIC0gcG9pbnRlciB0byBvdXIgc29mdCBzdGF0ZQogKgogKiBEaXNwbGF5IHJlYWwgdGltZSBpbmZvcm1hdGlvbiBhYm91dCB0aGUgbG9naWNhbCBkcml2ZXMgMCB0aHJvdWdoIDkuCiAqLwpzdGF0aWMgaW50CnByb2NfcmRydl8xMChjaGFyICpwYWdlLCBjaGFyICoqc3RhcnQsIG9mZl90IG9mZnNldCwgaW50IGNvdW50LCBpbnQgKmVvZiwKCQl2b2lkICpkYXRhKQp7CglhZGFwdGVyX3QgKmFkYXB0ZXIgPSAoYWRhcHRlcl90ICopZGF0YTsKCgkqZW9mID0gMTsKCglyZXR1cm4gKHByb2NfcmRydihhZGFwdGVyLCBwYWdlLCAwLCA5KSk7Cn0KCgovKioKICogcHJvY19yZHJ2XzIwKCkKICogQHBhZ2UgLSBidWZmZXIgdG8gd3JpdGUgdGhlIGRhdGEgaW4KICogQHN0YXJ0IC0gd2hlcmUgdGhlIGFjdHVhbCBkYXRhIGhhcyBiZWVuIHdyaXR0ZW4gaW4gcGFnZQogKiBAb2Zmc2V0IC0gc2FtZSBtZWFuaW5nIGFzIHRoZSByZWFkIHN5c3RlbSBjYWxsCiAqIEBjb3VudCAtIHNhbWUgbWVhbmluZyBhcyB0aGUgcmVhZCBzeXN0ZW0gY2FsbAogKiBAZW9mIC0gc2V0IGlmIG5vIG1vcmUgZGF0YSBuZWVkcyB0byBiZSByZXR1cm5lZAogKiBAZGF0YSAtIHBvaW50ZXIgdG8gb3VyIHNvZnQgc3RhdGUKICoKICogRGlzcGxheSByZWFsIHRpbWUgaW5mb3JtYXRpb24gYWJvdXQgdGhlIGxvZ2ljYWwgZHJpdmVzIDAgdGhyb3VnaCA5LgogKi8Kc3RhdGljIGludApwcm9jX3JkcnZfMjAoY2hhciAqcGFnZSwgY2hhciAqKnN0YXJ0LCBvZmZfdCBvZmZzZXQsIGludCBjb3VudCwgaW50ICplb2YsCgkJdm9pZCAqZGF0YSkKewoJYWRhcHRlcl90ICphZGFwdGVyID0gKGFkYXB0ZXJfdCAqKWRhdGE7CgoJKmVvZiA9IDE7CgoJcmV0dXJuIChwcm9jX3JkcnYoYWRhcHRlciwgcGFnZSwgMTAsIDE5KSk7Cn0KCgovKioKICogcHJvY19yZHJ2XzMwKCkKICogQHBhZ2UgLSBidWZmZXIgdG8gd3JpdGUgdGhlIGRhdGEgaW4KICogQHN0YXJ0IC0gd2hlcmUgdGhlIGFjdHVhbCBkYXRhIGhhcyBiZWVuIHdyaXR0ZW4gaW4gcGFnZQogKiBAb2Zmc2V0IC0gc2FtZSBtZWFuaW5nIGFzIHRoZSByZWFkIHN5c3RlbSBjYWxsCiAqIEBjb3VudCAtIHNhbWUgbWVhbmluZyBhcyB0aGUgcmVhZCBzeXN0ZW0gY2FsbAogKiBAZW9mIC0gc2V0IGlmIG5vIG1vcmUgZGF0YSBuZWVkcyB0byBiZSByZXR1cm5lZAogKiBAZGF0YSAtIHBvaW50ZXIgdG8gb3VyIHNvZnQgc3RhdGUKICoKICogRGlzcGxheSByZWFsIHRpbWUgaW5mb3JtYXRpb24gYWJvdXQgdGhlIGxvZ2ljYWwgZHJpdmVzIDAgdGhyb3VnaCA5LgogKi8Kc3RhdGljIGludApwcm9jX3JkcnZfMzAoY2hhciAqcGFnZSwgY2hhciAqKnN0YXJ0LCBvZmZfdCBvZmZzZXQsIGludCBjb3VudCwgaW50ICplb2YsCgkJdm9pZCAqZGF0YSkKewoJYWRhcHRlcl90ICphZGFwdGVyID0gKGFkYXB0ZXJfdCAqKWRhdGE7CgoJKmVvZiA9IDE7CgoJcmV0dXJuIChwcm9jX3JkcnYoYWRhcHRlciwgcGFnZSwgMjAsIDI5KSk7Cn0KCgovKioKICogcHJvY19yZHJ2XzQwKCkKICogQHBhZ2UgLSBidWZmZXIgdG8gd3JpdGUgdGhlIGRhdGEgaW4KICogQHN0YXJ0IC0gd2hlcmUgdGhlIGFjdHVhbCBkYXRhIGhhcyBiZWVuIHdyaXR0ZW4gaW4gcGFnZQogKiBAb2Zmc2V0IC0gc2FtZSBtZWFuaW5nIGFzIHRoZSByZWFkIHN5c3RlbSBjYWxsCiAqIEBjb3VudCAtIHNhbWUgbWVhbmluZyBhcyB0aGUgcmVhZCBzeXN0ZW0gY2FsbAogKiBAZW9mIC0gc2V0IGlmIG5vIG1vcmUgZGF0YSBuZWVkcyB0byBiZSByZXR1cm5lZAogKiBAZGF0YSAtIHBvaW50ZXIgdG8gb3VyIHNvZnQgc3RhdGUKICoKICogRGlzcGxheSByZWFsIHRpbWUgaW5mb3JtYXRpb24gYWJvdXQgdGhlIGxvZ2ljYWwgZHJpdmVzIDAgdGhyb3VnaCA5LgogKi8Kc3RhdGljIGludApwcm9jX3JkcnZfNDAoY2hhciAqcGFnZSwgY2hhciAqKnN0YXJ0LCBvZmZfdCBvZmZzZXQsIGludCBjb3VudCwgaW50ICplb2YsCgkJdm9pZCAqZGF0YSkKewoJYWRhcHRlcl90ICphZGFwdGVyID0gKGFkYXB0ZXJfdCAqKWRhdGE7CgoJKmVvZiA9IDE7CgoJcmV0dXJuIChwcm9jX3JkcnYoYWRhcHRlciwgcGFnZSwgMzAsIDM5KSk7Cn0KCgovKioKICogcHJvY19yZHJ2KCkKICogQHBhZ2UgLSBidWZmZXIgdG8gd3JpdGUgdGhlIGRhdGEgaW4KICogQGFkYXB0ZXIgLSBwb2ludGVyIHRvIG91ciBzb2Z0IHN0YXRlCiAqIEBzdGFydCAtIHN0YXJ0aW5nIGxvZ2ljYWwgZHJpdmUgdG8gZGlzcGxheQogKiBAZW5kIC0gZW5kaW5nIGxvZ2ljYWwgZHJpdmUgdG8gZGlzcGxheQogKgogKiBXZSBkbyBub3QgcHJpbnQgdGhlIGlucXVpcnkgaW5mb3JtYXRpb24gc2luY2UgaXRzIGFscmVhZHkgYXZhaWxhYmxlIHRocm91Z2gKICogL3Byb2Mvc2NzaS9zY3NpIGludGVyZmFjZQogKi8Kc3RhdGljIGludApwcm9jX3JkcnYoYWRhcHRlcl90ICphZGFwdGVyLCBjaGFyICpwYWdlLCBpbnQgc3RhcnQsIGludCBlbmQgKQp7CglkbWFfYWRkcl90CWRtYV9oYW5kbGU7Cglsb2dkcnZfcGFyYW0JKmxwYXJhbTsKCW1lZ2FjbWRfdAltYzsKCWNoYXIJCSpkaXNrX2FycmF5OwoJZG1hX2FkZHJfdAlkaXNrX2FycmF5X2RtYV9oYW5kbGU7CgljYWRkcl90CQlpbnF1aXJ5OwoJc3RydWN0IHBjaV9kZXYJKnBkZXY7Cgl1OAkqcmRydl9zdGF0ZTsKCWludAludW1fbGRydjsKCXUzMglhcnJheV9zejsKCWludAlsZW4gPSAwOwoJaW50CWk7CgoJaWYoIG1ha2VfbG9jYWxfcGRldihhZGFwdGVyLCAmcGRldikgIT0gMCApIHsKCQlyZXR1cm4gbGVuOwoJfQoKCWlmKCAoaW5xdWlyeSA9IG1lZ2FfYWxsb2NhdGVfaW5xdWlyeSgmZG1hX2hhbmRsZSwgcGRldikpID09IE5VTEwgKSB7CgkJZnJlZV9sb2NhbF9wZGV2KHBkZXYpOwoJCXJldHVybiBsZW47Cgl9CgoJaWYoIG1lZ2FfYWRhcGlucShhZGFwdGVyLCBkbWFfaGFuZGxlKSAhPSAwICkgewoKCQlsZW4gPSBzcHJpbnRmKHBhZ2UsICJBZGFwdGVyIGlucXVpcnkgZmFpbGVkLlxuIik7CgoJCXByaW50ayhLRVJOX1dBUk5JTkcgIm1lZ2FyYWlkOiBpbnF1aXJ5IGZhaWxlZC5cbiIpOwoKCQltZWdhX2ZyZWVfaW5xdWlyeShpbnF1aXJ5LCBkbWFfaGFuZGxlLCBwZGV2KTsKCgkJZnJlZV9sb2NhbF9wZGV2KHBkZXYpOwoKCQlyZXR1cm4gbGVuOwoJfQoKCW1lbXNldCgmbWMsIDAsIHNpemVvZihtZWdhY21kX3QpKTsKCglpZiggYWRhcHRlci0+ZmxhZyAmIEJPQVJEXzQwTEQgKSB7CgkJYXJyYXlfc3ogPSBzaXplb2YoZGlza19hcnJheV80MGxkKTsKCgkJcmRydl9zdGF0ZSA9ICgobWVnYV9pbnF1aXJ5MyAqKWlucXVpcnkpLT5sZHJ2X3N0YXRlOwoKCQludW1fbGRydiA9ICgobWVnYV9pbnF1aXJ5MyAqKWlucXVpcnkpLT5udW1fbGRydjsKCX0KCWVsc2UgewoJCWFycmF5X3N6ID0gc2l6ZW9mKGRpc2tfYXJyYXlfOGxkKTsKCgkJcmRydl9zdGF0ZSA9ICgobXJhaWRfZXh0X2lucXVpcnkgKilpbnF1aXJ5KS0+CgkJCXJhaWRfaW5xLmxvZ2Rydl9pbmZvLmxkcnZfc3RhdGU7CgoJCW51bV9sZHJ2ID0gKChtcmFpZF9leHRfaW5xdWlyeSAqKWlucXVpcnkpLT4KCQkJcmFpZF9pbnEubG9nZHJ2X2luZm8ubnVtX2xkcnY7Cgl9CgoJZGlza19hcnJheSA9IHBjaV9hbGxvY19jb25zaXN0ZW50KHBkZXYsIGFycmF5X3N6LAoJCQkmZGlza19hcnJheV9kbWFfaGFuZGxlKTsKCglpZiggZGlza19hcnJheSA9PSBOVUxMICkgewoJCWxlbiA9IHNwcmludGYocGFnZSwgIm1lbW9yeSBub3QgYXZhaWxhYmxlLlxuIik7CgoJCW1lZ2FfZnJlZV9pbnF1aXJ5KGlucXVpcnksIGRtYV9oYW5kbGUsIHBkZXYpOwoKCQlmcmVlX2xvY2FsX3BkZXYocGRldik7CgoJCXJldHVybiBsZW47Cgl9CgoJbWMueGZlcmFkZHIgPSAodTMyKWRpc2tfYXJyYXlfZG1hX2hhbmRsZTsKCglpZiggYWRhcHRlci0+ZmxhZyAmIEJPQVJEXzQwTEQgKSB7CgkJbWMuY21kID0gRkNfTkVXX0NPTkZJRzsKCQltYy5vcGNvZGUgPSBPUF9EQ01EX1JFQURfQ09ORklHOwoKCQlpZiggbWVnYV9pbnRlcm5hbF9jb21tYW5kKGFkYXB0ZXIsIExPQ0tfSU5ULCAmbWMsIE5VTEwpICkgewoKCQkJbGVuID0gc3ByaW50ZihwYWdlLCAiNDBMRCByZWFkIGNvbmZpZyBmYWlsZWQuXG4iKTsKCgkJCW1lZ2FfZnJlZV9pbnF1aXJ5KGlucXVpcnksIGRtYV9oYW5kbGUsIHBkZXYpOwoKCQkJcGNpX2ZyZWVfY29uc2lzdGVudChwZGV2LCBhcnJheV9zeiwgZGlza19hcnJheSwKCQkJCQlkaXNrX2FycmF5X2RtYV9oYW5kbGUpOwoKCQkJZnJlZV9sb2NhbF9wZGV2KHBkZXYpOwoKCQkJcmV0dXJuIGxlbjsKCQl9CgoJfQoJZWxzZSB7CgkJbWMuY21kID0gTkVXX1JFQURfQ09ORklHXzhMRDsKCgkJaWYoIG1lZ2FfaW50ZXJuYWxfY29tbWFuZChhZGFwdGVyLCBMT0NLX0lOVCwgJm1jLCBOVUxMKSApIHsKCgkJCW1jLmNtZCA9IFJFQURfQ09ORklHXzhMRDsKCgkJCWlmKCBtZWdhX2ludGVybmFsX2NvbW1hbmQoYWRhcHRlciwgTE9DS19JTlQsICZtYywKCQkJCQkJTlVMTCkgKXsKCgkJCQlsZW4gPSBzcHJpbnRmKHBhZ2UsCgkJCQkJIjhMRCByZWFkIGNvbmZpZyBmYWlsZWQuXG4iKTsKCgkJCQltZWdhX2ZyZWVfaW5xdWlyeShpbnF1aXJ5LCBkbWFfaGFuZGxlLCBwZGV2KTsKCgkJCQlwY2lfZnJlZV9jb25zaXN0ZW50KHBkZXYsIGFycmF5X3N6LAoJCQkJCQlkaXNrX2FycmF5LAoJCQkJCQlkaXNrX2FycmF5X2RtYV9oYW5kbGUpOwoKCQkJCWZyZWVfbG9jYWxfcGRldihwZGV2KTsKCgkJCQlyZXR1cm4gbGVuOwoJCQl9CgkJfQoJfQoKCWZvciggaSA9IHN0YXJ0OyBpIDwgKCAoZW5kKzEgPCBudW1fbGRydikgPyBlbmQrMSA6IG51bV9sZHJ2ICk7IGkrKyApIHsKCgkJaWYoIGFkYXB0ZXItPmZsYWcgJiBCT0FSRF80MExEICkgewoJCQlscGFyYW0gPQoJCQkmKChkaXNrX2FycmF5XzQwbGQgKilkaXNrX2FycmF5KS0+bGRydltpXS5scGFyYW07CgkJfQoJCWVsc2UgewoJCQlscGFyYW0gPQoJCQkmKChkaXNrX2FycmF5XzhsZCAqKWRpc2tfYXJyYXkpLT5sZHJ2W2ldLmxwYXJhbTsKCQl9CgoJCS8qCgkJICogQ2hlY2sgZm9yIG92ZXJmbG93LiBXZSBwcmludCBsZXNzIHRoYW4gMjQwIGNoYXJhY3RlcnMgZm9yCgkJICogaW5mb3JtYXRpb24gYWJvdXQgZWFjaCBsb2dpY2FsIGRyaXZlLgoJCSAqLwoJCWlmKCAobGVuICsgMjQwKSA+PSBQQUdFX1NJWkUgKSBicmVhazsKCgkJbGVuICs9IHNwcmludGYocGFnZStsZW4sICJMb2dpY2FsIGRyaXZlOiUyZDosICIsIGkpOwoKCQlzd2l0Y2goIHJkcnZfc3RhdGVbaV0gJiAweDBGICkgewoJCWNhc2UgUkRSVl9PRkZMSU5FOgoJCQlsZW4gKz0gc3ByaW50ZihwYWdlK2xlbiwgInN0YXRlOiBvZmZsaW5lIik7CgkJCWJyZWFrOwoKCQljYXNlIFJEUlZfREVHUkFERUQ6CgkJCWxlbiArPSBzcHJpbnRmKHBhZ2UrbGVuLCAic3RhdGU6IGRlZ3JhZGVkIik7CgkJCWJyZWFrOwoKCQljYXNlIFJEUlZfT1BUSU1BTDoKCQkJbGVuICs9IHNwcmludGYocGFnZStsZW4sICJzdGF0ZTogb3B0aW1hbCIpOwoJCQlicmVhazsKCgkJY2FzZSBSRFJWX0RFTEVURUQ6CgkJCWxlbiArPSBzcHJpbnRmKHBhZ2UrbGVuLCAic3RhdGU6IGRlbGV0ZWQiKTsKCQkJYnJlYWs7CgoJCWRlZmF1bHQ6CgkJCWxlbiArPSBzcHJpbnRmKHBhZ2UrbGVuLCAic3RhdGU6IHVua25vd24iKTsKCQkJYnJlYWs7CgkJfQoKCQkvKgoJCSAqIENoZWNrIGlmIGNoZWNrIGNvbnNpc3RlbmN5IG9yIGluaXRpYWxpemF0aW9uIGlzIGdvaW5nIG9uCgkJICogZm9yIHRoaXMgbG9naWNhbCBkcml2ZS4KCQkgKi8KCQlpZiggKHJkcnZfc3RhdGVbaV0gJiAweEYwKSA9PSAweDIwICkgewoJCQlsZW4gKz0gc3ByaW50ZihwYWdlK2xlbiwKCQkJCQkiLCBjaGVjay1jb25zaXN0ZW5jeSBpbiBwcm9ncmVzcyIpOwoJCX0KCQllbHNlIGlmKCAocmRydl9zdGF0ZVtpXSAmIDB4RjApID09IDB4MTAgKSB7CgkJCWxlbiArPSBzcHJpbnRmKHBhZ2UrbGVuLAoJCQkJCSIsIGluaXRpYWxpemF0aW9uIGluIHByb2dyZXNzIik7CgkJfQoJCQoJCWxlbiArPSBzcHJpbnRmKHBhZ2UrbGVuLCAiXG4iKTsKCgkJbGVuICs9IHNwcmludGYocGFnZStsZW4sICJTcGFuIGRlcHRoOiUzZCwgIiwKCQkJCWxwYXJhbS0+c3Bhbl9kZXB0aCk7CgoJCWxlbiArPSBzcHJpbnRmKHBhZ2UrbGVuLCAiUkFJRCBsZXZlbDolM2QsICIsCgkJCQlscGFyYW0tPmxldmVsKTsKCgkJbGVuICs9IHNwcmludGYocGFnZStsZW4sICJTdHJpcGUgc2l6ZTolM2QsICIsCgkJCQlscGFyYW0tPnN0cmlwZV9zeiA/IGxwYXJhbS0+c3RyaXBlX3N6LzI6IDEyOCk7CgoJCWxlbiArPSBzcHJpbnRmKHBhZ2UrbGVuLCAiUm93IHNpemU6JTNkXG4iLAoJCQkJbHBhcmFtLT5yb3dfc2l6ZSk7CgoKCQlsZW4gKz0gc3ByaW50ZihwYWdlK2xlbiwgIlJlYWQgUG9saWN5OiAiKTsKCgkJc3dpdGNoKGxwYXJhbS0+cmVhZF9haGVhZCkgewoKCQljYXNlIE5PX1JFQURfQUhFQUQ6CgkJCWxlbiArPSBzcHJpbnRmKHBhZ2UrbGVuLCAiTm8gcmVhZCBhaGVhZCwgIik7CgkJCWJyZWFrOwoKCQljYXNlIFJFQURfQUhFQUQ6CgkJCWxlbiArPSBzcHJpbnRmKHBhZ2UrbGVuLCAiUmVhZCBhaGVhZCwgIik7CgkJCWJyZWFrOwoKCQljYXNlIEFEQVBfUkVBRF9BSEVBRDoKCQkJbGVuICs9IHNwcmludGYocGFnZStsZW4sICJBZGFwdGl2ZSwgIik7CgkJCWJyZWFrOwoKCQl9CgoJCWxlbiArPSBzcHJpbnRmKHBhZ2UrbGVuLCAiV3JpdGUgUG9saWN5OiAiKTsKCgkJc3dpdGNoKGxwYXJhbS0+d3JpdGVfbW9kZSkgewoKCQljYXNlIFdSTU9ERV9XUklURV9USFJVOgoJCQlsZW4gKz0gc3ByaW50ZihwYWdlK2xlbiwgIldyaXRlIHRocnUsICIpOwoJCQlicmVhazsKCgkJY2FzZSBXUk1PREVfV1JJVEVfQkFDSzoKCQkJbGVuICs9IHNwcmludGYocGFnZStsZW4sICJXcml0ZSBiYWNrLCAiKTsKCQkJYnJlYWs7CgkJfQoKCQlsZW4gKz0gc3ByaW50ZihwYWdlK2xlbiwgIkNhY2hlIFBvbGljeTogIik7CgoJCXN3aXRjaChscGFyYW0tPmRpcmVjdF9pbykgewoKCQljYXNlIENBQ0hFRF9JTzoKCQkJbGVuICs9IHNwcmludGYocGFnZStsZW4sICJDYWNoZWQgSU9cblxuIik7CgkJCWJyZWFrOwoKCQljYXNlIERJUkVDVF9JTzoKCQkJbGVuICs9IHNwcmludGYocGFnZStsZW4sICJEaXJlY3QgSU9cblxuIik7CgkJCWJyZWFrOwoJCX0KCX0KCgltZWdhX2ZyZWVfaW5xdWlyeShpbnF1aXJ5LCBkbWFfaGFuZGxlLCBwZGV2KTsKCglwY2lfZnJlZV9jb25zaXN0ZW50KHBkZXYsIGFycmF5X3N6LCBkaXNrX2FycmF5LAoJCQlkaXNrX2FycmF5X2RtYV9oYW5kbGUpOwoKCWZyZWVfbG9jYWxfcGRldihwZGV2KTsKCglyZXR1cm4gbGVuOwp9CgojZW5kaWYKCgovKioKICogbWVnYXJhaWRfYmlvc3BhcmFtKCkKICoKICogUmV0dXJuIHRoZSBkaXNrIGdlb21ldHJ5IGZvciBhIHBhcnRpY3VsYXIgZGlzawogKi8Kc3RhdGljIGludAptZWdhcmFpZF9iaW9zcGFyYW0oc3RydWN0IHNjc2lfZGV2aWNlICpzZGV2LCBzdHJ1Y3QgYmxvY2tfZGV2aWNlICpiZGV2LAoJCSAgICBzZWN0b3JfdCBjYXBhY2l0eSwgaW50IGdlb21bXSkKewoJYWRhcHRlcl90CSphZGFwdGVyOwoJdW5zaWduZWQgY2hhcgkqYmg7CglpbnQJaGVhZHM7CglpbnQJc2VjdG9yczsKCWludAljeWxpbmRlcnM7CglpbnQJcnZhbDsKCgkvKiBHZXQgcG9pbnRlciB0byBob3N0IGNvbmZpZyBzdHJ1Y3R1cmUgKi8KCWFkYXB0ZXIgPSAoYWRhcHRlcl90ICopc2Rldi0+aG9zdC0+aG9zdGRhdGE7CgoJaWYgKElTX1JBSURfQ0goYWRhcHRlciwgc2Rldi0+Y2hhbm5lbCkpIHsKCQkJLyogRGVmYXVsdCBoZWFkcyAoNjQpICYgc2VjdG9ycyAoMzIpICovCgkJCWhlYWRzID0gNjQ7CgkJCXNlY3RvcnMgPSAzMjsKCQkJY3lsaW5kZXJzID0gKHVsb25nKWNhcGFjaXR5IC8gKGhlYWRzICogc2VjdG9ycyk7CgoJCQkvKgoJCQkgKiBIYW5kbGUgZXh0ZW5kZWQgdHJhbnNsYXRpb24gc2l6ZSBmb3IgbG9naWNhbCBkcml2ZXMKCQkJICogPiAxR2IKCQkJICovCgkJCWlmICgodWxvbmcpY2FwYWNpdHkgPj0gMHgyMDAwMDApIHsKCQkJCWhlYWRzID0gMjU1OwoJCQkJc2VjdG9ycyA9IDYzOwoJCQkJY3lsaW5kZXJzID0gKHVsb25nKWNhcGFjaXR5IC8gKGhlYWRzICogc2VjdG9ycyk7CgkJCX0KCgkJCS8qIHJldHVybiByZXN1bHQgKi8KCQkJZ2VvbVswXSA9IGhlYWRzOwoJCQlnZW9tWzFdID0gc2VjdG9yczsKCQkJZ2VvbVsyXSA9IGN5bGluZGVyczsKCX0KCWVsc2UgewoJCWJoID0gc2NzaV9iaW9zX3B0YWJsZShiZGV2KTsKCgkJaWYoIGJoICkgewoJCQlydmFsID0gc2NzaV9wYXJ0c2l6ZShiaCwgY2FwYWNpdHksCgkJCQkJICAgICZnZW9tWzJdLCAmZ2VvbVswXSwgJmdlb21bMV0pOwoJCQlrZnJlZShiaCk7CgkJCWlmKCBydmFsICE9IC0xICkKCQkJCXJldHVybiBydmFsOwoJCX0KCgkJcHJpbnRrKEtFUk5fSU5GTwoJCSJtZWdhcmFpZDogaW52YWxpZCBwYXJ0aXRpb24gb24gdGhpcyBkaXNrIG9uIGNoYW5uZWwgJWRcbiIsCgkJCQlzZGV2LT5jaGFubmVsKTsKCgkJLyogRGVmYXVsdCBoZWFkcyAoNjQpICYgc2VjdG9ycyAoMzIpICovCgkJaGVhZHMgPSA2NDsKCQlzZWN0b3JzID0gMzI7CgkJY3lsaW5kZXJzID0gKHVsb25nKWNhcGFjaXR5IC8gKGhlYWRzICogc2VjdG9ycyk7CgoJCS8qIEhhbmRsZSBleHRlbmRlZCB0cmFuc2xhdGlvbiBzaXplIGZvciBsb2dpY2FsIGRyaXZlcyA+IDFHYiAqLwoJCWlmICgodWxvbmcpY2FwYWNpdHkgPj0gMHgyMDAwMDApIHsKCQkJaGVhZHMgPSAyNTU7CgkJCXNlY3RvcnMgPSA2MzsKCQkJY3lsaW5kZXJzID0gKHVsb25nKWNhcGFjaXR5IC8gKGhlYWRzICogc2VjdG9ycyk7CgkJfQoKCQkvKiByZXR1cm4gcmVzdWx0ICovCgkJZ2VvbVswXSA9IGhlYWRzOwoJCWdlb21bMV0gPSBzZWN0b3JzOwoJCWdlb21bMl0gPSBjeWxpbmRlcnM7Cgl9CgoJcmV0dXJuIDA7Cn0KCi8qKgogKiBtZWdhX2luaXRfc2NiKCkKICogQGFkYXB0ZXIgLSBwb2ludGVyIHRvIG91ciBzb2Z0IHN0YXRlCiAqCiAqIEFsbG9jYXRlIG1lbW9yeSBmb3IgdGhlIHZhcmlvdXMgcG9pbnRlcnMgaW4gdGhlIHNjYiBzdHJ1Y3R1cmVzOgogKiBzY2F0dGVyLWdhdGhlciBsaXN0IHBvaW50ZXIsIHBhc3N0aHJ1IGFuZCBleHRlbmRlZCBwYXNzdGhydSBzdHJ1Y3R1cmUKICogcG9pbnRlcnMuCiAqLwpzdGF0aWMgaW50Cm1lZ2FfaW5pdF9zY2IoYWRhcHRlcl90ICphZGFwdGVyKQp7CglzY2JfdAkqc2NiOwoJaW50CWk7CgoJZm9yKCBpID0gMDsgaSA8IGFkYXB0ZXItPm1heF9jbWRzOyBpKysgKSB7CgoJCXNjYiA9ICZhZGFwdGVyLT5zY2JfbGlzdFtpXTsKCgkJc2NiLT5zZ2w2NCA9IE5VTEw7CgkJc2NiLT5zZ2wgPSBOVUxMOwoJCXNjYi0+cHRocnUgPSBOVUxMOwoJCXNjYi0+ZXB0aHJ1ID0gTlVMTDsKCX0KCglmb3IoIGkgPSAwOyBpIDwgYWRhcHRlci0+bWF4X2NtZHM7IGkrKyApIHsKCgkJc2NiID0gJmFkYXB0ZXItPnNjYl9saXN0W2ldOwoKCQlzY2ItPmlkeCA9IGk7CgoJCXNjYi0+c2dsNjQgPSBwY2lfYWxsb2NfY29uc2lzdGVudChhZGFwdGVyLT5kZXYsCgkJCQlzaXplb2YobWVnYV9zZ2w2NCkgKiBhZGFwdGVyLT5zZ2xlbiwKCQkJCSZzY2ItPnNnbF9kbWFfYWRkcik7CgoJCXNjYi0+c2dsID0gKG1lZ2Ffc2dsaXN0ICopc2NiLT5zZ2w2NDsKCgkJaWYoICFzY2ItPnNnbCApIHsKCQkJcHJpbnRrKEtFUk5fV0FSTklORyAiUkFJRDogQ2FuJ3QgYWxsb2NhdGUgc2dsaXN0LlxuIik7CgkJCW1lZ2FfZnJlZV9zZ2woYWRhcHRlcik7CgkJCXJldHVybiAtMTsKCQl9CgoJCXNjYi0+cHRocnUgPSBwY2lfYWxsb2NfY29uc2lzdGVudChhZGFwdGVyLT5kZXYsCgkJCQlzaXplb2YobWVnYV9wYXNzdGhydSksCgkJCQkmc2NiLT5wdGhydV9kbWFfYWRkcik7CgoJCWlmKCAhc2NiLT5wdGhydSApIHsKCQkJcHJpbnRrKEtFUk5fV0FSTklORyAiUkFJRDogQ2FuJ3QgYWxsb2NhdGUgcGFzc3RocnUuXG4iKTsKCQkJbWVnYV9mcmVlX3NnbChhZGFwdGVyKTsKCQkJcmV0dXJuIC0xOwoJCX0KCgkJc2NiLT5lcHRocnUgPSBwY2lfYWxsb2NfY29uc2lzdGVudChhZGFwdGVyLT5kZXYsCgkJCQlzaXplb2YobWVnYV9leHRfcGFzc3RocnUpLAoJCQkJJnNjYi0+ZXB0aHJ1X2RtYV9hZGRyKTsKCgkJaWYoICFzY2ItPmVwdGhydSApIHsKCQkJcHJpbnRrKEtFUk5fV0FSTklORwoJCQkJIkNhbid0IGFsbG9jYXRlIGV4dGVuZGVkIHBhc3N0aHJ1LlxuIik7CgkJCW1lZ2FfZnJlZV9zZ2woYWRhcHRlcik7CgkJCXJldHVybiAtMTsKCQl9CgoKCQlzY2ItPmRtYV90eXBlID0gTUVHQV9ETUFfVFlQRV9OT05FOwoKCQkvKgoJCSAqIExpbmsgdG8gZnJlZSBsaXN0CgkJICogbG9jayBub3QgcmVxdWlyZWQgc2luY2Ugd2UgYXJlIGxvYWRpbmcgdGhlIGRyaXZlciwgc28gbm8KCQkgKiBjb21tYW5kcyBwb3NzaWJsZSByaWdodCBub3cuCgkJICovCgkJc2NiLT5zdGF0ZSA9IFNDQl9GUkVFOwoJCXNjYi0+Y21kID0gTlVMTDsKCQlsaXN0X2FkZCgmc2NiLT5saXN0LCAmYWRhcHRlci0+ZnJlZV9saXN0KTsKCX0KCglyZXR1cm4gMDsKfQoKCi8qKgogKiBtZWdhZGV2X29wZW4oKQogKiBAaW5vZGUgLSB1bnVzZWQKICogQGZpbGVwIC0gdW51c2VkCiAqCiAqIFJvdXRpbmVzIGZvciB0aGUgY2hhcmFjdGVyL2lvY3RsIGludGVyZmFjZSB0byB0aGUgZHJpdmVyLiBGaW5kIG91dCBpZiB0aGlzCiAqIGlzIGEgdmFsaWQgb3Blbi4gSWYgeWVzLCBpbmNyZW1lbnQgdGhlIG1vZHVsZSB1c2UgY291bnQgc28gdGhhdCBpdCBjYW5ub3QKICogYmUgdW5sb2FkZWQuCiAqLwpzdGF0aWMgaW50Cm1lZ2FkZXZfb3BlbiAoc3RydWN0IGlub2RlICppbm9kZSwgc3RydWN0IGZpbGUgKmZpbGVwKQp7CgkvKgoJICogT25seSBhbGxvdyBzdXBlcnVzZXIgdG8gYWNjZXNzIHByaXZhdGUgaW9jdGwgaW50ZXJmYWNlCgkgKi8KCWlmKCAhY2FwYWJsZShDQVBfU1lTX0FETUlOKSApIHJldHVybiAtRUFDQ0VTOwoKCXJldHVybiAwOwp9CgoKLyoqCiAqIG1lZ2FkZXZfaW9jdGwoKQogKiBAaW5vZGUgLSBPdXIgZGV2aWNlIGlub2RlCiAqIEBmaWxlcCAtIHVudXNlZAogKiBAY21kIC0gaW9jdGwgY29tbWFuZAogKiBAYXJnIC0gdXNlciBidWZmZXIKICoKICogaW9jdGwgZW50cnkgcG9pbnQgZm9yIG91ciBwcml2YXRlIGlvY3RsIGludGVyZmFjZS4gV2UgbW92ZSB0aGUgZGF0YSBpbiBmcm9tCiAqIHRoZSB1c2VyIHNwYWNlLCBwcmVwYXJlIHRoZSBjb21tYW5kIChpZiBuZWNlc3NhcnksIGNvbnZlcnQgdGhlIG9sZCBNSU1ECiAqIGlvY3RsIHRvIG5ldyBpb2N0bCBjb21tYW5kKSwgYW5kIGlzc3VlIGEgc3luY2hyb25vdXMgY29tbWFuZCB0byB0aGUKICogY29udHJvbGxlci4KICovCnN0YXRpYyBpbnQKbWVnYWRldl9pb2N0bChzdHJ1Y3QgaW5vZGUgKmlub2RlLCBzdHJ1Y3QgZmlsZSAqZmlsZXAsIHVuc2lnbmVkIGludCBjbWQsCgkJdW5zaWduZWQgbG9uZyBhcmcpCnsKCWFkYXB0ZXJfdAkqYWRhcHRlcjsKCW5pdGlvY3RsX3QJdWlvYzsKCWludAkJYWRhcG5vOwoJaW50CQlydmFsOwoJbWVnYV9wYXNzdGhydQlfX3VzZXIgKnVwdGhydTsJLyogdXNlciBhZGRyZXNzIGZvciBwYXNzdGhydSAqLwoJbWVnYV9wYXNzdGhydQkqcHRocnU7CQkvKiBjb3B5IHVzZXIgcGFzc3RocnUgaGVyZSAqLwoJZG1hX2FkZHJfdAlwdGhydV9kbWFfaG5kbDsKCXZvaWQJCSpkYXRhID0gTlVMTDsJLyogZGF0YSB0byBiZSB0cmFuc2ZlcnJlZCAqLwoJZG1hX2FkZHJfdAlkYXRhX2RtYV9obmRsOwkvKiBkbWEgaGFuZGxlIGZvciBkYXRhIHhmZXIgYXJlYSAqLwoJbWVnYWNtZF90CW1jOwoJbWVnYXN0YXRfdAlfX3VzZXIgKnVzdGF0czsKCWludAkJbnVtX2xkcnY7Cgl1MzIJCXV4ZmVyYWRkciA9IDA7CglzdHJ1Y3QgcGNpX2RldgkqcGRldjsKCgl1c3RhdHMgPSBOVUxMOyAvKiBhdm9pZCBjb21waWxhdGlvbiB3YXJuaW5ncyAqLwoJbnVtX2xkcnYgPSAwOwoKCS8qCgkgKiBNYWtlIHN1cmUgb25seSBVU0NTSUNNRCBhcmUgaXNzdWVkIHRocm91Z2ggdGhpcyBpbnRlcmZhY2UuCgkgKiBNSU1EIGFwcGxpY2F0aW9uIHdvdWxkIHN0aWxsIGZpcmUgZGlmZmVyZW50IGNvbW1hbmQuCgkgKi8KCWlmKCAoX0lPQ19UWVBFKGNtZCkgIT0gTUVHQUlPQ19NQUdJQykgJiYgKGNtZCAhPSBVU0NTSUNNRCkgKSB7CgkJcmV0dXJuIC1FSU5WQUw7Cgl9CgoJLyoKCSAqIENoZWNrIGFuZCBjb252ZXJ0IGEgcG9zc2libGUgTUlNRCBjb21tYW5kIHRvIE5JVCBjb21tYW5kLgoJICogbWVnYV9tX3RvX24oKSBjb3BpZXMgdGhlIGRhdGEgZnJvbSB0aGUgdXNlciBzcGFjZSwgc28gd2UgZG8gbm90CgkgKiBoYXZlIHRvIGRvIGl0IGhlcmUuCgkgKiBOT1RFOiBXZSB3aWxsIG5lZWQgc29tZSB1c2VyIGFkZHJlc3MgdG8gY29weW91dCB0aGUgZGF0YSwgdGhlcmVmb3JlCgkgKiB0aGUgaW50ZWZhY2UgbGF5ZXIgd2lsbCBhbHNvIHByb3ZpZGUgdXMgd2l0aCB0aGUgcmVxdWlyZWQgdXNlcgoJICogYWRkcmVzc2VzLgoJICovCgltZW1zZXQoJnVpb2MsIDAsIHNpemVvZihuaXRpb2N0bF90KSk7CglpZiggKHJ2YWwgPSBtZWdhX21fdG9fbiggKHZvaWQgX191c2VyICopYXJnLCAmdWlvYykpICE9IDAgKQoJCXJldHVybiBydmFsOwoKCglzd2l0Y2goIHVpb2Mub3Bjb2RlICkgewoKCWNhc2UgR0VUX0RSSVZFUl9WRVI6CgkJaWYoIHB1dF91c2VyKGRyaXZlcl92ZXIsICh1MzIgX191c2VyICopdWlvYy51aW9jX3VhZGRyKSApCgkJCXJldHVybiAoLUVGQVVMVCk7CgoJCWJyZWFrOwoKCWNhc2UgR0VUX05fQURBUDoKCQlpZiggcHV0X3VzZXIoaGJhX2NvdW50LCAodTMyIF9fdXNlciAqKXVpb2MudWlvY191YWRkcikgKQoJCQlyZXR1cm4gKC1FRkFVTFQpOwoKCQkvKgoJCSAqIFNodWNrcy4gTUlNRCBpbnRlcmZhY2UgcmV0dXJucyBhIHBvc2l0aXZlIHZhbHVlIGZvciBudW1iZXIKCQkgKiBvZiBhZGFwdGVycy4gVE9ETzogQ2hhbmdlIGl0IHRvIHJldHVybiAwIHdoZW4gdGhlcmUgaXMgbm8KCQkgKiBhcHBsaWNhdGlvIHVzaW5nIG1pbWQgaW50ZXJmYWNlLgoJCSAqLwoJCXJldHVybiBoYmFfY291bnQ7CgoJY2FzZSBHRVRfQURBUF9JTkZPOgoKCQkvKgoJCSAqIFdoaWNoIGFkYXB0ZXIKCQkgKi8KCQlpZiggKGFkYXBubyA9IEdFVEFEQVAodWlvYy5hZGFwbm8pKSA+PSBoYmFfY291bnQgKQoJCQlyZXR1cm4gKC1FTk9ERVYpOwoKCQlpZiggY29weV90b191c2VyKHVpb2MudWlvY191YWRkciwgbWNvbnRyb2xsZXIrYWRhcG5vLAoJCQkJc2l6ZW9mKHN0cnVjdCBtY29udHJvbGxlcikpICkKCQkJcmV0dXJuICgtRUZBVUxUKTsKCQlicmVhazsKCiNpZiBNRUdBX0hBVkVfU1RBVFMKCgljYXNlIEdFVF9TVEFUUzoKCQkvKgoJCSAqIFdoaWNoIGFkYXB0ZXIKCQkgKi8KCQlpZiggKGFkYXBubyA9IEdFVEFEQVAodWlvYy5hZGFwbm8pKSA+PSBoYmFfY291bnQgKQoJCQlyZXR1cm4gKC1FTk9ERVYpOwoKCQlhZGFwdGVyID0gaGJhX3NvZnRfc3RhdGVbYWRhcG5vXTsKCgkJdXN0YXRzID0gdWlvYy51aW9jX3VhZGRyOwoKCQlpZiggY29weV9mcm9tX3VzZXIoJm51bV9sZHJ2LCAmdXN0YXRzLT5udW1fbGRydiwgc2l6ZW9mKGludCkpICkKCQkJcmV0dXJuICgtRUZBVUxUKTsKCgkJLyoKCQkgKiBDaGVjayBmb3IgdGhlIHZhbGlkaXR5IG9mIHRoZSBsb2dpY2FsIGRyaXZlIG51bWJlcgoJCSAqLwoJCWlmKCBudW1fbGRydiA+PSBNQVhfTE9HSUNBTF9EUklWRVNfNDBMRCApIHJldHVybiAtRUlOVkFMOwoKCQlpZiggY29weV90b191c2VyKHVzdGF0cy0+bnJlYWRzLCBhZGFwdGVyLT5ucmVhZHMsCgkJCQkJbnVtX2xkcnYqc2l6ZW9mKHUzMikpICkKCQkJcmV0dXJuIC1FRkFVTFQ7CgoJCWlmKCBjb3B5X3RvX3VzZXIodXN0YXRzLT5ucmVhZGJsb2NrcywgYWRhcHRlci0+bnJlYWRibG9ja3MsCgkJCQkJbnVtX2xkcnYqc2l6ZW9mKHUzMikpICkKCQkJcmV0dXJuIC1FRkFVTFQ7CgoJCWlmKCBjb3B5X3RvX3VzZXIodXN0YXRzLT5ud3JpdGVzLCBhZGFwdGVyLT5ud3JpdGVzLAoJCQkJCW51bV9sZHJ2KnNpemVvZih1MzIpKSApCgkJCXJldHVybiAtRUZBVUxUOwoKCQlpZiggY29weV90b191c2VyKHVzdGF0cy0+bndyaXRlYmxvY2tzLCBhZGFwdGVyLT5ud3JpdGVibG9ja3MsCgkJCQkJbnVtX2xkcnYqc2l6ZW9mKHUzMikpICkKCQkJcmV0dXJuIC1FRkFVTFQ7CgoJCWlmKCBjb3B5X3RvX3VzZXIodXN0YXRzLT5yZF9lcnJvcnMsIGFkYXB0ZXItPnJkX2Vycm9ycywKCQkJCQludW1fbGRydipzaXplb2YodTMyKSkgKQoJCQlyZXR1cm4gLUVGQVVMVDsKCgkJaWYoIGNvcHlfdG9fdXNlcih1c3RhdHMtPndyX2Vycm9ycywgYWRhcHRlci0+d3JfZXJyb3JzLAoJCQkJCW51bV9sZHJ2KnNpemVvZih1MzIpKSApCgkJCXJldHVybiAtRUZBVUxUOwoKCQlyZXR1cm4gMDsKCiNlbmRpZgoJY2FzZSBNQk9YX0NNRDoKCgkJLyoKCQkgKiBXaGljaCBhZGFwdGVyCgkJICovCgkJaWYoIChhZGFwbm8gPSBHRVRBREFQKHVpb2MuYWRhcG5vKSkgPj0gaGJhX2NvdW50ICkKCQkJcmV0dXJuICgtRU5PREVWKTsKCgkJYWRhcHRlciA9IGhiYV9zb2Z0X3N0YXRlW2FkYXBub107CgoJCS8qCgkJICogRGVsZXRpb24gb2YgbG9naWNhbCBkcml2ZSBpcyBhIHNwZWNpYWwgY2FzZS4gVGhlIGFkYXB0ZXIKCQkgKiBzaG91bGQgYmUgcXVpZXNjZW50IGJlZm9yZSB0aGlzIGNvbW1hbmQgaXMgaXNzdWVkLgoJCSAqLwoJCWlmKCB1aW9jLnVpb2Nfcm1ib3hbMF0gPT0gRkNfREVMX0xPR0RSViAmJgoJCQkJdWlvYy51aW9jX3JtYm94WzJdID09IE9QX0RFTF9MT0dEUlYgKSB7CgoJCQkvKgoJCQkgKiBEbyB3ZSBzdXBwb3J0IHRoaXMgZmVhdHVyZQoJCQkgKi8KCQkJaWYoICFhZGFwdGVyLT5zdXBwb3J0X3JhbmRvbV9kZWwgKSB7CgkJCQlwcmludGsoS0VSTl9XQVJOSU5HICJtZWdhcmFpZDogbG9nZHJ2ICIpOwoJCQkJcHJpbnRrKCJkZWxldGUgb24gbm9uLXN1cHBvcnRpbmcgRi9XLlxuIik7CgoJCQkJcmV0dXJuICgtRUlOVkFMKTsKCQkJfQoKCQkJcnZhbCA9IG1lZ2FfZGVsX2xvZ2RydiggYWRhcHRlciwgdWlvYy51aW9jX3JtYm94WzNdICk7CgoJCQlpZiggcnZhbCA9PSAwICkgewoJCQkJbWVtc2V0KCZtYywgMCwgc2l6ZW9mKG1lZ2FjbWRfdCkpOwoKCQkJCW1jLnN0YXR1cyA9IHJ2YWw7CgoJCQkJcnZhbCA9IG1lZ2Ffbl90b19tKCh2b2lkIF9fdXNlciAqKWFyZywgJm1jKTsKCQkJfQoKCQkJcmV0dXJuIHJ2YWw7CgkJfQoJCS8qCgkJICogVGhpcyBpbnRlcmZhY2Ugb25seSBzdXBwb3J0IHRoZSByZWd1bGFyIHBhc3N0aHJ1IGNvbW1hbmRzLgoJCSAqIFJlamVjdCBleHRlbmRlZCBwYXNzdGhydSBhbmQgNjQtYml0IHBhc3N0aHJ1CgkJICovCgkJaWYoIHVpb2MudWlvY19ybWJveFswXSA9PSBNRUdBX01CT1hDTURfUEFTU1RIUlU2NCB8fAoJCQl1aW9jLnVpb2Nfcm1ib3hbMF0gPT0gTUVHQV9NQk9YQ01EX0VYVFBUSFJVICkgewoKCQkJcHJpbnRrKEtFUk5fV0FSTklORyAibWVnYXJhaWQ6IHJlamVjdGVkIHBhc3N0aHJ1LlxuIik7CgoJCQlyZXR1cm4gKC1FSU5WQUwpOwoJCX0KCgkJLyoKCQkgKiBGb3IgYWxsIGludGVybmFsIGNvbW1hbmRzLCB0aGUgYnVmZmVyIG11c3QgYmUgYWxsb2NhdGVkIGluCgkJICogPDRHQiBhZGRyZXNzIHJhbmdlCgkJICovCgkJaWYoIG1ha2VfbG9jYWxfcGRldihhZGFwdGVyLCAmcGRldikgIT0gMCApCgkJCXJldHVybiAtRUlPOwoKCQkvKiBJcyBpdCBhIHBhc3N0aHJ1IGNvbW1hbmQgb3IgYSBEQ01EICovCgkJaWYoIHVpb2MudWlvY19ybWJveFswXSA9PSBNRUdBX01CT1hDTURfUEFTU1RIUlUgKSB7CgkJCS8qIFBhc3N0aHJ1IGNvbW1hbmRzICovCgoJCQlwdGhydSA9IHBjaV9hbGxvY19jb25zaXN0ZW50KHBkZXYsCgkJCQkJc2l6ZW9mKG1lZ2FfcGFzc3RocnUpLAoJCQkJCSZwdGhydV9kbWFfaG5kbCk7CgoJCQlpZiggcHRocnUgPT0gTlVMTCApIHsKCQkJCWZyZWVfbG9jYWxfcGRldihwZGV2KTsKCQkJCXJldHVybiAoLUVOT01FTSk7CgkJCX0KCgkJCS8qCgkJCSAqIFRoZSB1c2VyIHBhc3N0aHJ1IHN0cnVjdHVyZQoJCQkgKi8KCQkJdXB0aHJ1ID0gKG1lZ2FfcGFzc3RocnUgX191c2VyICopTUJPWCh1aW9jKS0+eGZlcmFkZHI7CgoJCQkvKgoJCQkgKiBDb3B5IGluIHRoZSB1c2VyIHBhc3N0aHJ1IGhlcmUuCgkJCSAqLwoJCQlpZiggY29weV9mcm9tX3VzZXIocHRocnUsIHVwdGhydSwKCQkJCQkJc2l6ZW9mKG1lZ2FfcGFzc3RocnUpKSApIHsKCgkJCQlwY2lfZnJlZV9jb25zaXN0ZW50KHBkZXYsCgkJCQkJCXNpemVvZihtZWdhX3Bhc3N0aHJ1KSwgcHRocnUsCgkJCQkJCXB0aHJ1X2RtYV9obmRsKTsKCgkJCQlmcmVlX2xvY2FsX3BkZXYocGRldik7CgoJCQkJcmV0dXJuICgtRUZBVUxUKTsKCQkJfQoKCQkJLyoKCQkJICogSXMgdGhlcmUgYSBkYXRhIHRyYW5zZmVyCgkJCSAqLwoJCQlpZiggcHRocnUtPmRhdGF4ZmVybGVuICkgewoJCQkJZGF0YSA9IHBjaV9hbGxvY19jb25zaXN0ZW50KHBkZXYsCgkJCQkJCXB0aHJ1LT5kYXRheGZlcmxlbiwKCQkJCQkJJmRhdGFfZG1hX2huZGwpOwoKCQkJCWlmKCBkYXRhID09IE5VTEwgKSB7CgkJCQkJcGNpX2ZyZWVfY29uc2lzdGVudChwZGV2LAoJCQkJCQkJc2l6ZW9mKG1lZ2FfcGFzc3RocnUpLAoJCQkJCQkJcHRocnUsCgkJCQkJCQlwdGhydV9kbWFfaG5kbCk7CgoJCQkJCWZyZWVfbG9jYWxfcGRldihwZGV2KTsKCgkJCQkJcmV0dXJuICgtRU5PTUVNKTsKCQkJCX0KCgkJCQkvKgoJCQkJICogU2F2ZSB0aGUgdXNlciBhZGRyZXNzIGFuZCBwb2ludCB0aGUga2VybmVsCgkJCQkgKiBhZGRyZXNzIGF0IGp1c3QgYWxsb2NhdGVkIG1lbW9yeQoJCQkJICovCgkJCQl1eGZlcmFkZHIgPSBwdGhydS0+ZGF0YXhmZXJhZGRyOwoJCQkJcHRocnUtPmRhdGF4ZmVyYWRkciA9IGRhdGFfZG1hX2huZGw7CgkJCX0KCgoJCQkvKgoJCQkgKiBJcyBkYXRhIGNvbWluZyBkb3duLXN0cmVhbQoJCQkgKi8KCQkJaWYoIHB0aHJ1LT5kYXRheGZlcmxlbiAmJiAodWlvYy5mbGFncyAmIFVJT0NfV1IpICkgewoJCQkJLyoKCQkJCSAqIEdldCB0aGUgdXNlciBkYXRhCgkJCQkgKi8KCQkJCWlmKCBjb3B5X2Zyb21fdXNlcihkYXRhLCAoY2hhciBfX3VzZXIgKil1eGZlcmFkZHIsCgkJCQkJCQlwdGhydS0+ZGF0YXhmZXJsZW4pICkgewoJCQkJCXJ2YWwgPSAoLUVGQVVMVCk7CgkJCQkJZ290byBmcmVlbWVtX2FuZF9yZXR1cm47CgkJCQl9CgkJCX0KCgkJCW1lbXNldCgmbWMsIDAsIHNpemVvZihtZWdhY21kX3QpKTsKCgkJCW1jLmNtZCA9IE1FR0FfTUJPWENNRF9QQVNTVEhSVTsKCQkJbWMueGZlcmFkZHIgPSAodTMyKXB0aHJ1X2RtYV9obmRsOwoKCQkJLyoKCQkJICogSXNzdWUgdGhlIGNvbW1hbmQKCQkJICovCgkJCW1lZ2FfaW50ZXJuYWxfY29tbWFuZChhZGFwdGVyLCBMT0NLX0lOVCwgJm1jLCBwdGhydSk7CgoJCQlydmFsID0gbWVnYV9uX3RvX20oKHZvaWQgX191c2VyICopYXJnLCAmbWMpOwoKCQkJaWYoIHJ2YWwgKSBnb3RvIGZyZWVtZW1fYW5kX3JldHVybjsKCgoJCQkvKgoJCQkgKiBJcyBkYXRhIGdvaW5nIHVwLXN0cmVhbQoJCQkgKi8KCQkJaWYoIHB0aHJ1LT5kYXRheGZlcmxlbiAmJiAodWlvYy5mbGFncyAmIFVJT0NfUkQpICkgewoJCQkJaWYoIGNvcHlfdG9fdXNlcigoY2hhciBfX3VzZXIgKil1eGZlcmFkZHIsIGRhdGEsCgkJCQkJCQlwdGhydS0+ZGF0YXhmZXJsZW4pICkgewoJCQkJCXJ2YWwgPSAoLUVGQVVMVCk7CgkJCQl9CgkJCX0KCgkJCS8qCgkJCSAqIFNlbmQgdGhlIHJlcXVlc3Qgc2Vuc2UgZGF0YSBhbHNvLCBpcnJlc3BlY3RpdmUgb2YKCQkJICogd2hldGhlciB0aGUgdXNlciBoYXMgYXNrZWQgZm9yIGl0IG9yIG5vdC4KCQkJICovCgkJCWNvcHlfdG9fdXNlcih1cHRocnUtPnJlcXNlbnNlYXJlYSwKCQkJCQlwdGhydS0+cmVxc2Vuc2VhcmVhLCAxNCk7CgpmcmVlbWVtX2FuZF9yZXR1cm46CgkJCWlmKCBwdGhydS0+ZGF0YXhmZXJsZW4gKSB7CgkJCQlwY2lfZnJlZV9jb25zaXN0ZW50KHBkZXYsCgkJCQkJCXB0aHJ1LT5kYXRheGZlcmxlbiwgZGF0YSwKCQkJCQkJZGF0YV9kbWFfaG5kbCk7CgkJCX0KCgkJCXBjaV9mcmVlX2NvbnNpc3RlbnQocGRldiwgc2l6ZW9mKG1lZ2FfcGFzc3RocnUpLAoJCQkJCXB0aHJ1LCBwdGhydV9kbWFfaG5kbCk7CgoJCQlmcmVlX2xvY2FsX3BkZXYocGRldik7CgoJCQlyZXR1cm4gcnZhbDsKCQl9CgkJZWxzZSB7CgkJCS8qIERDTUQgY29tbWFuZHMgKi8KCgkJCS8qCgkJCSAqIElzIHRoZXJlIGEgZGF0YSB0cmFuc2ZlcgoJCQkgKi8KCQkJaWYoIHVpb2MueGZlcmxlbiApIHsKCQkJCWRhdGEgPSBwY2lfYWxsb2NfY29uc2lzdGVudChwZGV2LAoJCQkJCQl1aW9jLnhmZXJsZW4sICZkYXRhX2RtYV9obmRsKTsKCgkJCQlpZiggZGF0YSA9PSBOVUxMICkgewoJCQkJCWZyZWVfbG9jYWxfcGRldihwZGV2KTsKCQkJCQlyZXR1cm4gKC1FTk9NRU0pOwoJCQkJfQoKCQkJCXV4ZmVyYWRkciA9IE1CT1godWlvYyktPnhmZXJhZGRyOwoJCQl9CgoJCQkvKgoJCQkgKiBJcyBkYXRhIGNvbWluZyBkb3duLXN0cmVhbQoJCQkgKi8KCQkJaWYoIHVpb2MueGZlcmxlbiAmJiAodWlvYy5mbGFncyAmIFVJT0NfV1IpICkgewoJCQkJLyoKCQkJCSAqIEdldCB0aGUgdXNlciBkYXRhCgkJCQkgKi8KCQkJCWlmKCBjb3B5X2Zyb21fdXNlcihkYXRhLCAoY2hhciBfX3VzZXIgKil1eGZlcmFkZHIsCgkJCQkJCQl1aW9jLnhmZXJsZW4pICkgewoKCQkJCQlwY2lfZnJlZV9jb25zaXN0ZW50KHBkZXYsCgkJCQkJCQl1aW9jLnhmZXJsZW4sCgkJCQkJCQlkYXRhLCBkYXRhX2RtYV9obmRsKTsKCgkJCQkJZnJlZV9sb2NhbF9wZGV2KHBkZXYpOwoKCQkJCQlyZXR1cm4gKC1FRkFVTFQpOwoJCQkJfQoJCQl9CgoJCQltZW1jcHkoJm1jLCBNQk9YKHVpb2MpLCBzaXplb2YobWVnYWNtZF90KSk7CgoJCQltYy54ZmVyYWRkciA9ICh1MzIpZGF0YV9kbWFfaG5kbDsKCgkJCS8qCgkJCSAqIElzc3VlIHRoZSBjb21tYW5kCgkJCSAqLwoJCQltZWdhX2ludGVybmFsX2NvbW1hbmQoYWRhcHRlciwgTE9DS19JTlQsICZtYywgTlVMTCk7CgoJCQlydmFsID0gbWVnYV9uX3RvX20oKHZvaWQgX191c2VyICopYXJnLCAmbWMpOwoKCQkJaWYoIHJ2YWwgKSB7CgkJCQlpZiggdWlvYy54ZmVybGVuICkgewoJCQkJCXBjaV9mcmVlX2NvbnNpc3RlbnQocGRldiwKCQkJCQkJCXVpb2MueGZlcmxlbiwgZGF0YSwKCQkJCQkJCWRhdGFfZG1hX2huZGwpOwoJCQkJfQoKCQkJCWZyZWVfbG9jYWxfcGRldihwZGV2KTsKCgkJCQlyZXR1cm4gcnZhbDsKCQkJfQoKCQkJLyoKCQkJICogSXMgZGF0YSBnb2luZyB1cC1zdHJlYW0KCQkJICovCgkJCWlmKCB1aW9jLnhmZXJsZW4gJiYgKHVpb2MuZmxhZ3MgJiBVSU9DX1JEKSApIHsKCQkJCWlmKCBjb3B5X3RvX3VzZXIoKGNoYXIgX191c2VyICopdXhmZXJhZGRyLCBkYXRhLAoJCQkJCQkJdWlvYy54ZmVybGVuKSApIHsKCgkJCQkJcnZhbCA9ICgtRUZBVUxUKTsKCQkJCX0KCQkJfQoKCQkJaWYoIHVpb2MueGZlcmxlbiApIHsKCQkJCXBjaV9mcmVlX2NvbnNpc3RlbnQocGRldiwKCQkJCQkJdWlvYy54ZmVybGVuLCBkYXRhLAoJCQkJCQlkYXRhX2RtYV9obmRsKTsKCQkJfQoKCQkJZnJlZV9sb2NhbF9wZGV2KHBkZXYpOwoKCQkJcmV0dXJuIHJ2YWw7CgkJfQoKCWRlZmF1bHQ6CgkJcmV0dXJuICgtRUlOVkFMKTsKCX0KCglyZXR1cm4gMDsKfQoKLyoqCiAqIG1lZ2FfbV90b19uKCkKICogQGFyZyAtIHVzZXIgYWRkcmVzcwogKiBAdWlvYyAtIG5ldyBpb2N0bCBzdHJ1Y3R1cmUKICoKICogQSB0aGluIGxheWVyIHRvIGNvbnZlcnQgb2xkZXIgbWltZCBpbnRlcmZhY2UgaW9jdGwgc3RydWN0dXJlIHRvIE5JVCBpb2N0bAogKiBzdHJ1Y3R1cmUKICoKICogQ29udmVydHMgdGhlIG9sZGVyIG1pbWQgaW9jdGwgc3RydWN0dXJlIHRvIG5ld2VyIE5JVCBzdHJ1Y3R1cmUKICovCnN0YXRpYyBpbnQKbWVnYV9tX3RvX24odm9pZCBfX3VzZXIgKmFyZywgbml0aW9jdGxfdCAqdWlvYykKewoJc3RydWN0IHVpb2N0bF90CXVpb2NfbWltZDsKCWNoYXIJc2lnbmF0dXJlWzhdID0gezB9OwoJdTgJb3Bjb2RlOwoJdTgJc3Vib3Bjb2RlOwoKCgkvKgoJICogY2hlY2sgaXMgdGhlIGFwcGxpY2F0aW9uIGNvbmZvcm1zIHRvIE5JVC4gV2UgZG8gbm90IGhhdmUgdG8gZG8gbXVjaAoJICogaW4gdGhhdCBjYXNlLgoJICogV2UgZXhwbG9pdCB0aGUgZmFjdCB0aGF0IHRoZSBzaWduYXR1cmUgaXMgc3RvcmVkIGluIHRoZSB2ZXJ5CgkgKiBiZWdpbmluZyBvZiB0aGUgc3RydWN0dXJlLgoJICovCgoJaWYoIGNvcHlfZnJvbV91c2VyKHNpZ25hdHVyZSwgYXJnLCA3KSApCgkJcmV0dXJuICgtRUZBVUxUKTsKCglpZiggbWVtY21wKHNpZ25hdHVyZSwgIk1FR0FOSVQiLCA3KSA9PSAwICkgewoKCQkvKgoJCSAqIE5PVEUgTk9URTogVGhlIG5pdCBpb2N0bCBpcyBzdGlsbCB1bmRlciBmbHV4IGJlY2F1c2Ugb2YKCQkgKiBjaGFuZ2Ugb2YgbWFpbGJveCBkZWZpbml0aW9uLCBpbiBIUEUuIE5vIGFwcGxpY2F0aW9ucyB5ZXQKCQkgKiB1c2UgdGhpcyBpbnRlcmZhY2UgYW5kIGxldCdzIG5vdCBoYXZlIGFwcGxpY2F0aW9ucyB1c2UgdGhpcwoJCSAqIGludGVyZmFjZSB0aWxsIHRoZSBuZXcgc3BlY2lmaXRpb25zIGFyZSBpbiBwbGFjZS4KCQkgKi8KCQlyZXR1cm4gLUVJTlZBTDsKI2lmIDAKCQlpZiggY29weV9mcm9tX3VzZXIodWlvYywgYXJnLCBzaXplb2Yobml0aW9jdGxfdCkpICkKCQkJcmV0dXJuICgtRUZBVUxUKTsKCQlyZXR1cm4gMDsKI2VuZGlmCgl9CgoJLyoKCSAqIEVsc2UgYXNzdW1lIHdlIGhhdmUgbWltZCB1aW9jdGxfdCBhcyBhcmcuIENvbnZlcnQgdG8gbml0aW9jdGxfdAoJICoKCSAqIEdldCB0aGUgdXNlciBpb2N0bCBzdHJ1Y3R1cmUKCSAqLwoJaWYoIGNvcHlfZnJvbV91c2VyKCZ1aW9jX21pbWQsIGFyZywgc2l6ZW9mKHN0cnVjdCB1aW9jdGxfdCkpICkKCQlyZXR1cm4gKC1FRkFVTFQpOwoKCgkvKgoJICogR2V0IHRoZSBvcGNvZGUgYW5kIHN1Ym9wY29kZSBmb3IgdGhlIGNvbW1hbmRzCgkgKi8KCW9wY29kZSA9IHVpb2NfbWltZC51aS5mY3Mub3Bjb2RlOwoJc3Vib3Bjb2RlID0gdWlvY19taW1kLnVpLmZjcy5zdWJvcGNvZGU7CgoJc3dpdGNoIChvcGNvZGUpIHsKCWNhc2UgMHg4MjoKCgkJc3dpdGNoIChzdWJvcGNvZGUpIHsKCgkJY2FzZSBNRUdBSU9DX1FEUlZSVkVSOgkvKiBRdWVyeSBkcml2ZXIgdmVyc2lvbiAqLwoJCQl1aW9jLT5vcGNvZGUgPSBHRVRfRFJJVkVSX1ZFUjsKCQkJdWlvYy0+dWlvY191YWRkciA9IHVpb2NfbWltZC5kYXRhOwoJCQlicmVhazsKCgkJY2FzZSBNRUdBSU9DX1FOQURBUDoJLyogR2V0ICMgb2YgYWRhcHRlcnMgKi8KCQkJdWlvYy0+b3Bjb2RlID0gR0VUX05fQURBUDsKCQkJdWlvYy0+dWlvY191YWRkciA9IHVpb2NfbWltZC5kYXRhOwoJCQlicmVhazsKCgkJY2FzZSBNRUdBSU9DX1FBREFQSU5GTzoJLyogR2V0IGFkYXB0ZXIgaW5mb3JtYXRpb24gKi8KCQkJdWlvYy0+b3Bjb2RlID0gR0VUX0FEQVBfSU5GTzsKCQkJdWlvYy0+YWRhcG5vID0gdWlvY19taW1kLnVpLmZjcy5hZGFwbm87CgkJCXVpb2MtPnVpb2NfdWFkZHIgPSB1aW9jX21pbWQuZGF0YTsKCQkJYnJlYWs7CgoJCWRlZmF1bHQ6CgkJCXJldHVybigtRUlOVkFMKTsKCQl9CgoJCWJyZWFrOwoKCgljYXNlIDB4ODE6CgoJCXVpb2MtPm9wY29kZSA9IE1CT1hfQ01EOwoJCXVpb2MtPmFkYXBubyA9IHVpb2NfbWltZC51aS5mY3MuYWRhcG5vOwoKCQltZW1jcHkodWlvYy0+dWlvY19ybWJveCwgdWlvY19taW1kLm1ib3gsIDE4KTsKCgkJdWlvYy0+eGZlcmxlbiA9IHVpb2NfbWltZC51aS5mY3MubGVuZ3RoOwoKCQlpZiggdWlvY19taW1kLm91dGxlbiApIHVpb2MtPmZsYWdzID0gVUlPQ19SRDsKCQlpZiggdWlvY19taW1kLmlubGVuICkgdWlvYy0+ZmxhZ3MgfD0gVUlPQ19XUjsKCgkJYnJlYWs7CgoJY2FzZSAweDgwOgoKCQl1aW9jLT5vcGNvZGUgPSBNQk9YX0NNRDsKCQl1aW9jLT5hZGFwbm8gPSB1aW9jX21pbWQudWkuZmNzLmFkYXBubzsKCgkJbWVtY3B5KHVpb2MtPnVpb2Nfcm1ib3gsIHVpb2NfbWltZC5tYm94LCAxOCk7CgoJCS8qCgkJICogQ2hvb3NlIHRoZSB4ZmVybGVuIGJpZ2dlciBvZiBpbnB1dCBhbmQgb3V0cHV0IGRhdGEKCQkgKi8KCQl1aW9jLT54ZmVybGVuID0gdWlvY19taW1kLm91dGxlbiA+IHVpb2NfbWltZC5pbmxlbiA/CgkJCXVpb2NfbWltZC5vdXRsZW4gOiB1aW9jX21pbWQuaW5sZW47CgoJCWlmKCB1aW9jX21pbWQub3V0bGVuICkgdWlvYy0+ZmxhZ3MgPSBVSU9DX1JEOwoJCWlmKCB1aW9jX21pbWQuaW5sZW4gKSB1aW9jLT5mbGFncyB8PSBVSU9DX1dSOwoKCQlicmVhazsKCglkZWZhdWx0OgoJCXJldHVybiAoLUVJTlZBTCk7CgoJfQoKCXJldHVybiAwOwp9CgovKgogKiBtZWdhX25fdG9fbSgpCiAqIEBhcmcgLSB1c2VyIGFkZHJlc3MKICogQG1jIC0gbWFpbGJveCBjb21tYW5kCiAqCiAqIFVwZGF0ZXMgdGhlIHN0YXR1cyBpbmZvcm1hdGlvbiB0byB0aGUgYXBwbGljYXRpb24sIGRlcGVuZGluZyBvbiBhcHBsaWNhdGlvbgogKiBjb25mb3JtcyB0byBvbGRlciBtaW1kIGlvY3RsIGludGVyZmFjZSBvciBuZXdlciBOSVQgaW9jdGwgaW50ZXJmYWNlCiAqLwpzdGF0aWMgaW50Cm1lZ2Ffbl90b19tKHZvaWQgX191c2VyICphcmcsIG1lZ2FjbWRfdCAqbWMpCnsKCW5pdGlvY3RsX3QJX191c2VyICp1aW9jcDsKCW1lZ2FjbWRfdAlfX3VzZXIgKnVtYzsKCW1lZ2FfcGFzc3RocnUJX191c2VyICp1cHRocnU7CglzdHJ1Y3QgdWlvY3RsX3QJX191c2VyICp1aW9jX21pbWQ7CgljaGFyCXNpZ25hdHVyZVs4XSA9IHswfTsKCgkvKgoJICogY2hlY2sgaXMgdGhlIGFwcGxpY2F0aW9uIGNvbmZvcm1zIHRvIE5JVC4KCSAqLwoJaWYoIGNvcHlfZnJvbV91c2VyKHNpZ25hdHVyZSwgYXJnLCA3KSApCgkJcmV0dXJuIC1FRkFVTFQ7CgoJaWYoIG1lbWNtcChzaWduYXR1cmUsICJNRUdBTklUIiwgNykgPT0gMCApIHsKCgkJdWlvY3AgPSBhcmc7CgoJCWlmKCBwdXRfdXNlcihtYy0+c3RhdHVzLCAodTggX191c2VyICopJk1CT1hfUCh1aW9jcCktPnN0YXR1cykgKQoJCQlyZXR1cm4gKC1FRkFVTFQpOwoKCQlpZiggbWMtPmNtZCA9PSBNRUdBX01CT1hDTURfUEFTU1RIUlUgKSB7CgoJCQl1bWMgPSBNQk9YX1AodWlvY3ApOwoKCQkJaWYgKGdldF91c2VyKHVwdGhydSwgKG1lZ2FfcGFzc3RocnUgX191c2VyICogX191c2VyICopJnVtYy0+eGZlcmFkZHIpKQoJCQkJcmV0dXJuIC1FRkFVTFQ7CgoJCQlpZiggcHV0X3VzZXIobWMtPnN0YXR1cywgKHU4IF9fdXNlciAqKSZ1cHRocnUtPnNjc2lzdGF0dXMpKQoJCQkJcmV0dXJuICgtRUZBVUxUKTsKCQl9Cgl9CgllbHNlIHsKCQl1aW9jX21pbWQgPSBhcmc7CgoJCWlmKCBwdXRfdXNlcihtYy0+c3RhdHVzLCAodTggX191c2VyICopJnVpb2NfbWltZC0+bWJveFsxN10pICkKCQkJcmV0dXJuICgtRUZBVUxUKTsKCgkJaWYoIG1jLT5jbWQgPT0gTUVHQV9NQk9YQ01EX1BBU1NUSFJVICkgewoKCQkJdW1jID0gKG1lZ2FjbWRfdCBfX3VzZXIgKil1aW9jX21pbWQtPm1ib3g7CgoJCQlpZiAoZ2V0X3VzZXIodXB0aHJ1LCAobWVnYV9wYXNzdGhydSBfX3VzZXIgKiBfX3VzZXIgKikmdW1jLT54ZmVyYWRkcikpCgkJCQlyZXR1cm4gKC1FRkFVTFQpOwoKCQkJaWYoIHB1dF91c2VyKG1jLT5zdGF0dXMsICh1OCBfX3VzZXIgKikmdXB0aHJ1LT5zY3Npc3RhdHVzKSApCgkJCQlyZXR1cm4gKC1FRkFVTFQpOwoJCX0KCX0KCglyZXR1cm4gMDsKfQoKCi8qCiAqIE1FR0FSQUlEICdGVycgY29tbWFuZHMuCiAqLwoKLyoqCiAqIG1lZ2FfaXNfYmlvc19lbmFibGVkKCkKICogQGFkYXB0ZXIgLSBwb2ludGVyIHRvIG91ciBzb2Z0IHN0YXRlCiAqCiAqIGlzc3VlIGNvbW1hbmQgdG8gZmluZCBvdXQgaWYgdGhlIEJJT1MgaXMgZW5hYmxlZCBmb3IgdGhpcyBjb250cm9sbGVyCiAqLwpzdGF0aWMgaW50Cm1lZ2FfaXNfYmlvc19lbmFibGVkKGFkYXB0ZXJfdCAqYWRhcHRlcikKewoJdW5zaWduZWQgY2hhcglyYXdfbWJveFtzaXplb2Yoc3RydWN0IG1ib3hfb3V0KV07CgltYm94X3QJKm1ib3g7CglpbnQJcmV0OwoKCW1ib3ggPSAobWJveF90ICopcmF3X21ib3g7CgoJbWVtc2V0KCZtYm94LT5tX291dCwgMCwgc2l6ZW9mKHJhd19tYm94KSk7CgoJbWVtc2V0KCh2b2lkICopYWRhcHRlci0+bWVnYV9idWZmZXIsIDAsIE1FR0FfQlVGRkVSX1NJWkUpOwoKCW1ib3gtPm1fb3V0LnhmZXJhZGRyID0gKHUzMilhZGFwdGVyLT5idWZfZG1hX2hhbmRsZTsKCglyYXdfbWJveFswXSA9IElTX0JJT1NfRU5BQkxFRDsKCXJhd19tYm94WzJdID0gR0VUX0JJT1M7CgoKCXJldCA9IGlzc3VlX3NjYl9ibG9jayhhZGFwdGVyLCByYXdfbWJveCk7CgoJcmV0dXJuICooY2hhciAqKWFkYXB0ZXItPm1lZ2FfYnVmZmVyOwp9CgoKLyoqCiAqIG1lZ2FfZW51bV9yYWlkX3Njc2koKQogKiBAYWRhcHRlciAtIHBvaW50ZXIgdG8gb3VyIHNvZnQgc3RhdGUKICoKICogRmluZCBvdXQgd2hhdCBjaGFubmVscyBhcmUgUkFJRC9TQ1NJLiBUaGlzIGluZm9ybWF0aW9uIGlzIHVzZWQgdG8KICogZGlmZmVyZW50aWF0ZSB0aGUgdmlydHVhbCBjaGFubmVscyBhbmQgcGh5c2ljYWwgY2hhbm5lbHMgYW5kIHRvIHN1cHBvcnQKICogUk9NQiBmZWF0dXJlIGFuZCBub24tZGlzayBkZXZpY2VzLgogKi8Kc3RhdGljIHZvaWQKbWVnYV9lbnVtX3JhaWRfc2NzaShhZGFwdGVyX3QgKmFkYXB0ZXIpCnsKCXVuc2lnbmVkIGNoYXIgcmF3X21ib3hbc2l6ZW9mKHN0cnVjdCBtYm94X291dCldOwoJbWJveF90ICptYm94OwoJaW50IGk7CgoJbWJveCA9IChtYm94X3QgKilyYXdfbWJveDsKCgltZW1zZXQoJm1ib3gtPm1fb3V0LCAwLCBzaXplb2YocmF3X21ib3gpKTsKCgkvKgoJICogaXNzdWUgY29tbWFuZCB0byBmaW5kIG91dCB3aGF0IGNoYW5uZWxzIGFyZSByYWlkL3Njc2kKCSAqLwoJcmF3X21ib3hbMF0gPSBDSE5MX0NMQVNTOwoJcmF3X21ib3hbMl0gPSBHRVRfQ0hOTF9DTEFTUzsKCgltZW1zZXQoKHZvaWQgKilhZGFwdGVyLT5tZWdhX2J1ZmZlciwgMCwgTUVHQV9CVUZGRVJfU0laRSk7CgoJbWJveC0+bV9vdXQueGZlcmFkZHIgPSAodTMyKWFkYXB0ZXItPmJ1Zl9kbWFfaGFuZGxlOwoKCS8qCgkgKiBOb24tUk9NQiBmaXJtd2FyZSBmYWlsIHRoaXMgY29tbWFuZCwgc28gYWxsIGNoYW5uZWxzCgkgKiBtdXN0IGJlIHNob3duIFJBSUQKCSAqLwoJYWRhcHRlci0+bWVnYV9jaF9jbGFzcyA9IDB4RkY7CgoJaWYoIWlzc3VlX3NjYl9ibG9jayhhZGFwdGVyLCByYXdfbWJveCkpIHsKCQlhZGFwdGVyLT5tZWdhX2NoX2NsYXNzID0gKigoY2hhciAqKWFkYXB0ZXItPm1lZ2FfYnVmZmVyKTsKCgl9CgoJZm9yKCBpID0gMDsgaSA8IGFkYXB0ZXItPnByb2R1Y3RfaW5mby5uY2hhbm5lbHM7IGkrKyApIHsgCgkJaWYoIChhZGFwdGVyLT5tZWdhX2NoX2NsYXNzID4+IGkpICYgMHgwMSApIHsKCQkJcHJpbnRrKEtFUk5fSU5GTyAibWVnYXJhaWQ6IGNoYW5uZWxbJWRdIGlzIHJhaWQuXG4iLAoJCQkJCWkpOwoJCX0KCQllbHNlIHsKCQkJcHJpbnRrKEtFUk5fSU5GTyAibWVnYXJhaWQ6IGNoYW5uZWxbJWRdIGlzIHNjc2kuXG4iLAoJCQkJCWkpOwoJCX0KCX0KCglyZXR1cm47Cn0KCgovKioKICogbWVnYV9nZXRfYm9vdF9kcnYoKQogKiBAYWRhcHRlciAtIHBvaW50ZXIgdG8gb3VyIHNvZnQgc3RhdGUKICoKICogRmluZCBvdXQgd2hpY2ggZGV2aWNlIGlzIHRoZSBib290IGRldmljZS4gTm90ZSwgYW55IGxvZ2ljYWwgZHJpdmUgb3IgYW55CiAqIHBoeWljYWwgZGV2aWNlIChlLmcuLCBhIENEUk9NKSBjYW4gYmUgZGVzaWduYXRlZCBhcyBhIGJvb3QgZGV2aWNlLgogKi8Kc3RhdGljIHZvaWQKbWVnYV9nZXRfYm9vdF9kcnYoYWRhcHRlcl90ICphZGFwdGVyKQp7CglzdHJ1Y3QgcHJpdmF0ZV9iaW9zX2RhdGEJKnBydl9iaW9zX2RhdGE7Cgl1bnNpZ25lZCBjaGFyCXJhd19tYm94W3NpemVvZihzdHJ1Y3QgbWJveF9vdXQpXTsKCW1ib3hfdAkqbWJveDsKCXUxNglja3N1bSA9IDA7Cgl1OAkqY2tzdW1fcDsKCXU4CWJvb3RfcGRydjsKCWludAlpOwoKCW1ib3ggPSAobWJveF90ICopcmF3X21ib3g7CgoJbWVtc2V0KCZtYm94LT5tX291dCwgMCwgc2l6ZW9mKHJhd19tYm94KSk7CgoJcmF3X21ib3hbMF0gPSBCSU9TX1BWVF9EQVRBOwoJcmF3X21ib3hbMl0gPSBHRVRfQklPU19QVlRfREFUQTsKCgltZW1zZXQoKHZvaWQgKilhZGFwdGVyLT5tZWdhX2J1ZmZlciwgMCwgTUVHQV9CVUZGRVJfU0laRSk7CgoJbWJveC0+bV9vdXQueGZlcmFkZHIgPSAodTMyKWFkYXB0ZXItPmJ1Zl9kbWFfaGFuZGxlOwoKCWFkYXB0ZXItPmJvb3RfbGRydl9lbmFibGVkID0gMDsKCWFkYXB0ZXItPmJvb3RfbGRydiA9IDA7CgoJYWRhcHRlci0+Ym9vdF9wZHJ2X2VuYWJsZWQgPSAwOwoJYWRhcHRlci0+Ym9vdF9wZHJ2X2NoID0gMDsKCWFkYXB0ZXItPmJvb3RfcGRydl90Z3QgPSAwOwoKCWlmKGlzc3VlX3NjYl9ibG9jayhhZGFwdGVyLCByYXdfbWJveCkgPT0gMCkgewoJCXBydl9iaW9zX2RhdGEgPQoJCQkoc3RydWN0IHByaXZhdGVfYmlvc19kYXRhICopYWRhcHRlci0+bWVnYV9idWZmZXI7CgoJCWNrc3VtID0gMDsKCQlja3N1bV9wID0gKGNoYXIgKilwcnZfYmlvc19kYXRhOwoJCWZvciAoaSA9IDA7IGkgPCAxNDsgaSsrICkgewoJCQlja3N1bSArPSAodTE2KSgqY2tzdW1fcCsrKTsKCQl9CgoJCWlmIChwcnZfYmlvc19kYXRhLT5ja3N1bSA9PSAodTE2KSgwLWNrc3VtKSApIHsKCgkJCS8qCgkJCSAqIElmIE1TQiBpcyBzZXQsIGEgcGh5c2ljYWwgZHJpdmUgaXMgc2V0IGFzIGJvb3QKCQkJICogZGV2aWNlCgkJCSAqLwoJCQlpZiggcHJ2X2Jpb3NfZGF0YS0+Ym9vdF9kcnYgJiAweDgwICkgewoJCQkJYWRhcHRlci0+Ym9vdF9wZHJ2X2VuYWJsZWQgPSAxOwoJCQkJYm9vdF9wZHJ2ID0gcHJ2X2Jpb3NfZGF0YS0+Ym9vdF9kcnYgJiAweDdGOwoJCQkJYWRhcHRlci0+Ym9vdF9wZHJ2X2NoID0gYm9vdF9wZHJ2IC8gMTY7CgkJCQlhZGFwdGVyLT5ib290X3BkcnZfdGd0ID0gYm9vdF9wZHJ2ICUgMTY7CgkJCX0KCQkJZWxzZSB7CgkJCQlhZGFwdGVyLT5ib290X2xkcnZfZW5hYmxlZCA9IDE7CgkJCQlhZGFwdGVyLT5ib290X2xkcnYgPSBwcnZfYmlvc19kYXRhLT5ib290X2RydjsKCQkJfQoJCX0KCX0KCn0KCi8qKgogKiBtZWdhX3N1cHBvcnRfcmFuZG9tX2RlbCgpCiAqIEBhZGFwdGVyIC0gcG9pbnRlciB0byBvdXIgc29mdCBzdGF0ZQogKgogKiBGaW5kIG91dCBpZiB0aGlzIGNvbnRyb2xsZXIgc3VwcG9ydHMgcmFuZG9tIGRlbGV0aW9uIGFuZCBhZGRpdGlvbiBvZgogKiBsb2dpY2FsIGRyaXZlcwogKi8Kc3RhdGljIGludAptZWdhX3N1cHBvcnRfcmFuZG9tX2RlbChhZGFwdGVyX3QgKmFkYXB0ZXIpCnsKCXVuc2lnbmVkIGNoYXIgcmF3X21ib3hbc2l6ZW9mKHN0cnVjdCBtYm94X291dCldOwoJbWJveF90ICptYm94OwoJaW50IHJ2YWw7CgoJbWJveCA9IChtYm94X3QgKilyYXdfbWJveDsKCgltZW1zZXQoJm1ib3gtPm1fb3V0LCAwLCBzaXplb2YocmF3X21ib3gpKTsKCgkvKgoJICogaXNzdWUgY29tbWFuZAoJICovCglyYXdfbWJveFswXSA9IEZDX0RFTF9MT0dEUlY7CglyYXdfbWJveFsyXSA9IE9QX1NVUF9ERUxfTE9HRFJWOwoKCXJ2YWwgPSBpc3N1ZV9zY2JfYmxvY2soYWRhcHRlciwgcmF3X21ib3gpOwoKCXJldHVybiAhcnZhbDsKfQoKCi8qKgogKiBtZWdhX3N1cHBvcnRfZXh0X2NkYigpCiAqIEBhZGFwdGVyIC0gcG9pbnRlciB0byBvdXIgc29mdCBzdGF0ZQogKgogKiBGaW5kIG91dCBpZiB0aGlzIGZpcm13YXJlIHN1cHBvcnQgY2RibGVuID4gMTAKICovCnN0YXRpYyBpbnQKbWVnYV9zdXBwb3J0X2V4dF9jZGIoYWRhcHRlcl90ICphZGFwdGVyKQp7Cgl1bnNpZ25lZCBjaGFyIHJhd19tYm94W3NpemVvZihzdHJ1Y3QgbWJveF9vdXQpXTsKCW1ib3hfdCAqbWJveDsKCWludCBydmFsOwoKCW1ib3ggPSAobWJveF90ICopcmF3X21ib3g7CgoJbWVtc2V0KCZtYm94LT5tX291dCwgMCwgc2l6ZW9mKHJhd19tYm94KSk7CgkvKgoJICogaXNzdWUgY29tbWFuZCB0byBmaW5kIG91dCBpZiBjb250cm9sbGVyIHN1cHBvcnRzIGV4dGVuZGVkIENEQnMuCgkgKi8KCXJhd19tYm94WzBdID0gMHhBNDsKCXJhd19tYm94WzJdID0gMHgxNjsKCglydmFsID0gaXNzdWVfc2NiX2Jsb2NrKGFkYXB0ZXIsIHJhd19tYm94KTsKCglyZXR1cm4gIXJ2YWw7Cn0KCgovKioKICogbWVnYV9kZWxfbG9nZHJ2KCkKICogQGFkYXB0ZXIgLSBwb2ludGVyIHRvIG91ciBzb2Z0IHN0YXRlCiAqIEBsb2dkcnYgLSBsb2dpY2FsIGRyaXZlIHRvIGJlIGRlbGV0ZWQKICoKICogRGVsZXRlIHRoZSBzcGVjaWZpZWQgbG9naWNhbCBkcml2ZS4gSXQgaXMgdGhlIHJlc3BvbnNpYmlsaXR5IG9mIHRoZSB1c2VyCiAqIGFwcCB0byBsZXQgdGhlIE9TIGtub3cgYWJvdXQgdGhpcyBvcGVyYXRpb24uCiAqLwpzdGF0aWMgaW50Cm1lZ2FfZGVsX2xvZ2RydihhZGFwdGVyX3QgKmFkYXB0ZXIsIGludCBsb2dkcnYpCnsKCXVuc2lnbmVkIGxvbmcgZmxhZ3M7CglzY2JfdCAqc2NiOwoJaW50IHJ2YWw7CgoJLyoKCSAqIFN0b3Agc2VuZGluZyBjb21tYW5kcyB0byB0aGUgY29udHJvbGxlciwgcXVldWUgdGhlbSBpbnRlcm5hbGx5LgoJICogV2hlbiBkZWxldGlvbiBpcyBjb21wbGV0ZSwgSVNSIHdpbGwgZmx1c2ggdGhlIHF1ZXVlLgoJICovCglhdG9taWNfc2V0KCZhZGFwdGVyLT5xdWllc2NlbnQsIDEpOwoKCS8qCgkgKiBXYWl0IHRpbGwgYWxsIHRoZSBpc3N1ZWQgY29tbWFuZHMgYXJlIGNvbXBsZXRlIGFuZCB0aGVyZSBhcmUgbm8KCSAqIGNvbW1hbmRzIGluIHRoZSBwZW5kaW5nIHF1ZXVlCgkgKi8KCXdoaWxlIChhdG9taWNfcmVhZCgmYWRhcHRlci0+cGVuZF9jbWRzKSA+IDAgfHwKCSAgICAgICAhbGlzdF9lbXB0eSgmYWRhcHRlci0+cGVuZGluZ19saXN0KSkKCQltc2xlZXAoMTAwMCk7CS8qIHNsZWVwIGZvciAxcyAqLwoKCXJ2YWwgPSBtZWdhX2RvX2RlbF9sb2dkcnYoYWRhcHRlciwgbG9nZHJ2KTsKCglzcGluX2xvY2tfaXJxc2F2ZSgmYWRhcHRlci0+bG9jaywgZmxhZ3MpOwoKCS8qCgkgKiBJZiBkZWxldGUgb3BlcmF0aW9uIHdhcyBzdWNjZXNzZnVsLCBhZGQgMHg4MCB0byB0aGUgbG9naWNhbCBkcml2ZQoJICogaWRzIGZvciBjb21tYW5kcyBpbiB0aGUgcGVuZGluZyBxdWV1ZS4KCSAqLwoJaWYgKGFkYXB0ZXItPnJlYWRfbGRpZG1hcCkgewoJCXN0cnVjdCBsaXN0X2hlYWQgKnBvczsKCQlsaXN0X2Zvcl9lYWNoKHBvcywgJmFkYXB0ZXItPnBlbmRpbmdfbGlzdCkgewoJCQlzY2IgPSBsaXN0X2VudHJ5KHBvcywgc2NiX3QsIGxpc3QpOwoJCQlpZiAoc2NiLT5wdGhydS0+bG9nZHJ2IDwgMHg4MCApCgkJCQlzY2ItPnB0aHJ1LT5sb2dkcnYgKz0gMHg4MDsKCQl9Cgl9CgoJYXRvbWljX3NldCgmYWRhcHRlci0+cXVpZXNjZW50LCAwKTsKCgltZWdhX3J1bnBlbmRxKGFkYXB0ZXIpOwoKCXNwaW5fdW5sb2NrX2lycXJlc3RvcmUoJmFkYXB0ZXItPmxvY2ssIGZsYWdzKTsKCglyZXR1cm4gcnZhbDsKfQoKCnN0YXRpYyBpbnQKbWVnYV9kb19kZWxfbG9nZHJ2KGFkYXB0ZXJfdCAqYWRhcHRlciwgaW50IGxvZ2RydikKewoJbWVnYWNtZF90CW1jOwoJaW50CXJ2YWw7CgoJbWVtc2V0KCAmbWMsIDAsIHNpemVvZihtZWdhY21kX3QpKTsKCgltYy5jbWQgPSBGQ19ERUxfTE9HRFJWOwoJbWMub3Bjb2RlID0gT1BfREVMX0xPR0RSVjsKCW1jLnN1Ym9wY29kZSA9IGxvZ2RydjsKCglydmFsID0gbWVnYV9pbnRlcm5hbF9jb21tYW5kKGFkYXB0ZXIsIExPQ0tfSU5ULCAmbWMsIE5VTEwpOwoKCS8qIGxvZyB0aGlzIGV2ZW50ICovCglpZihydmFsKSB7CgkJcHJpbnRrKEtFUk5fV0FSTklORyAibWVnYXJhaWQ6IERlbGV0ZSBMRC0lZCBmYWlsZWQuIiwgbG9nZHJ2KTsKCQlyZXR1cm4gcnZhbDsKCX0KCgkvKgoJICogQWZ0ZXIgZGVsZXRpbmcgZmlyc3QgbG9naWNhbCBkcml2ZSwgdGhlIGxvZ2ljYWwgZHJpdmVzIG11c3QgYmUKCSAqIGFkZHJlc3NlZCBieSBhZGRpbmcgMHg4MCB0byB0aGUgbG9naWNhbCBkcml2ZSBpZC4KCSAqLwoJYWRhcHRlci0+cmVhZF9sZGlkbWFwID0gMTsKCglyZXR1cm4gcnZhbDsKfQoKCi8qKgogKiBtZWdhX2dldF9tYXhfc2dsKCkKICogQGFkYXB0ZXIgLSBwb2ludGVyIHRvIG91ciBzb2Z0IHN0YXRlCiAqCiAqIEZpbmQgb3V0IHRoZSBtYXhpbXVtIG51bWJlciBvZiBzY2F0dGVyLWdhdGhlciBlbGVtZW50cyBzdXBwb3J0ZWQgYnkgdGhpcwogKiB2ZXJzaW9uIG9mIHRoZSBmaXJtd2FyZQogKi8Kc3RhdGljIHZvaWQKbWVnYV9nZXRfbWF4X3NnbChhZGFwdGVyX3QgKmFkYXB0ZXIpCnsKCXVuc2lnbmVkIGNoYXIJcmF3X21ib3hbc2l6ZW9mKHN0cnVjdCBtYm94X291dCldOwoJbWJveF90CSptYm94OwoKCW1ib3ggPSAobWJveF90ICopcmF3X21ib3g7CgoJbWVtc2V0KG1ib3gsIDAsIHNpemVvZihyYXdfbWJveCkpOwoKCW1lbXNldCgodm9pZCAqKWFkYXB0ZXItPm1lZ2FfYnVmZmVyLCAwLCBNRUdBX0JVRkZFUl9TSVpFKTsKCgltYm94LT5tX291dC54ZmVyYWRkciA9ICh1MzIpYWRhcHRlci0+YnVmX2RtYV9oYW5kbGU7CgoJcmF3X21ib3hbMF0gPSBNQUlOX01JU0NfT1BDT0RFOwoJcmF3X21ib3hbMl0gPSBHRVRfTUFYX1NHX1NVUFBPUlQ7CgoKCWlmKCBpc3N1ZV9zY2JfYmxvY2soYWRhcHRlciwgcmF3X21ib3gpICkgewoJCS8qCgkJICogZi93IGRvZXMgbm90IHN1cHBvcnQgdGhpcyBjb21tYW5kLiBDaG9vc2UgdGhlIGRlZmF1bHQgdmFsdWUKCQkgKi8KCQlhZGFwdGVyLT5zZ2xlbiA9IE1JTl9TR0xJU1Q7Cgl9CgllbHNlIHsKCQlhZGFwdGVyLT5zZ2xlbiA9ICooKGNoYXIgKilhZGFwdGVyLT5tZWdhX2J1ZmZlcik7CgkJCgkJLyoKCQkgKiBNYWtlIHN1cmUgdGhpcyBpcyBub3QgbW9yZSB0aGFuIHRoZSByZXNvdXJjZXMgd2UgYXJlCgkJICogcGxhbm5pbmcgdG8gYWxsb2NhdGUKCQkgKi8KCQlpZiAoIGFkYXB0ZXItPnNnbGVuID4gTUFYX1NHTElTVCApCgkJCWFkYXB0ZXItPnNnbGVuID0gTUFYX1NHTElTVDsKCX0KCglyZXR1cm47Cn0KCgovKioKICogbWVnYV9zdXBwb3J0X2NsdXN0ZXIoKQogKiBAYWRhcHRlciAtIHBvaW50ZXIgdG8gb3VyIHNvZnQgc3RhdGUKICoKICogRmluZCBvdXQgaWYgdGhpcyBmaXJtd2FyZSBzdXBwb3J0IGNsdXN0ZXIgY2FsbHMuCiAqLwpzdGF0aWMgaW50Cm1lZ2Ffc3VwcG9ydF9jbHVzdGVyKGFkYXB0ZXJfdCAqYWRhcHRlcikKewoJdW5zaWduZWQgY2hhcglyYXdfbWJveFtzaXplb2Yoc3RydWN0IG1ib3hfb3V0KV07CgltYm94X3QJKm1ib3g7CgoJbWJveCA9IChtYm94X3QgKilyYXdfbWJveDsKCgltZW1zZXQobWJveCwgMCwgc2l6ZW9mKHJhd19tYm94KSk7CgoJbWVtc2V0KCh2b2lkICopYWRhcHRlci0+bWVnYV9idWZmZXIsIDAsIE1FR0FfQlVGRkVSX1NJWkUpOwoKCW1ib3gtPm1fb3V0LnhmZXJhZGRyID0gKHUzMilhZGFwdGVyLT5idWZfZG1hX2hhbmRsZTsKCgkvKgoJICogVHJ5IHRvIGdldCB0aGUgaW5pdGlhdG9yIGlkLiBUaGlzIGNvbW1hbmQgd2lsbCBzdWNjZWVkIGlmZiB0aGUKCSAqIGNsdXN0ZXJpbmcgaXMgYXZhaWxhYmxlIG9uIHRoaXMgSEJBLgoJICovCglyYXdfbWJveFswXSA9IE1FR0FfR0VUX1RBUkdFVF9JRDsKCglpZiggaXNzdWVfc2NiX2Jsb2NrKGFkYXB0ZXIsIHJhd19tYm94KSA9PSAwICkgewoKCQkvKgoJCSAqIENsdXN0ZXIgc3VwcG9ydCBhdmFpbGFibGUuIEdldCB0aGUgaW5pdGlhdG9yIHRhcmdldCBpZC4KCQkgKiBUZWxsIG91ciBpZCB0byBtaWQtbGF5ZXIgdG9vLgoJCSAqLwoJCWFkYXB0ZXItPnRoaXNfaWQgPSAqKHUzMiAqKWFkYXB0ZXItPm1lZ2FfYnVmZmVyOwoJCWFkYXB0ZXItPmhvc3QtPnRoaXNfaWQgPSBhZGFwdGVyLT50aGlzX2lkOwoKCQlyZXR1cm4gMTsKCX0KCglyZXR1cm4gMDsKfQoKCi8qKgogKiBtZWdhX2FkYXBpbnEoKQogKiBAYWRhcHRlciAtIHBvaW50ZXIgdG8gb3VyIHNvZnQgc3RhdGUKICogQGRtYV9oYW5kbGUgLSBETUEgYWRkcmVzcyBvZiB0aGUgYnVmZmVyCiAqCiAqIElzc3VlIGludGVybmFsIGNvbWFtbmRzIHdoaWxlIGludGVycnVwdHMgYXJlIGF2YWlsYWJsZS4KICogV2Ugb25seSBpc3N1ZSBkaXJlY3QgbWFpbGJveCBjb21tYW5kcyBmcm9tIHdpdGhpbiB0aGUgZHJpdmVyLiBpb2N0bCgpCiAqIGludGVyZmFjZSB1c2luZyB0aGVzZSByb3V0aW5lcyBjYW4gaXNzdWUgcGFzc3RocnUgY29tbWFuZHMuCiAqLwpzdGF0aWMgaW50Cm1lZ2FfYWRhcGlucShhZGFwdGVyX3QgKmFkYXB0ZXIsIGRtYV9hZGRyX3QgZG1hX2hhbmRsZSkKewoJbWVnYWNtZF90CW1jOwoKCW1lbXNldCgmbWMsIDAsIHNpemVvZihtZWdhY21kX3QpKTsKCglpZiggYWRhcHRlci0+ZmxhZyAmIEJPQVJEXzQwTEQgKSB7CgkJbWMuY21kID0gRkNfTkVXX0NPTkZJRzsKCQltYy5vcGNvZGUgPSBOQ19TVUJPUF9FTlFVSVJZMzsKCQltYy5zdWJvcGNvZGUgPSBFTlEzX0dFVF9TT0xJQ0lURURfRlVMTDsKCX0KCWVsc2UgewoJCW1jLmNtZCA9IE1FR0FfTUJPWENNRF9BRFBFWFRJTlE7Cgl9CgoJbWMueGZlcmFkZHIgPSAodTMyKWRtYV9oYW5kbGU7CgoJaWYgKCBtZWdhX2ludGVybmFsX2NvbW1hbmQoYWRhcHRlciwgTE9DS19JTlQsICZtYywgTlVMTCkgIT0gMCApIHsKCQlyZXR1cm4gLTE7Cgl9CgoJcmV0dXJuIDA7Cn0KCgovKiogbWVnYV9pbnRlcm5hbF9kZXZfaW5xdWlyeSgpCiAqIEBhZGFwdGVyIC0gcG9pbnRlciB0byBvdXIgc29mdCBzdGF0ZQogKiBAY2ggLSBjaGFubmVsIGZvciB0aGlzIGRldmljZQogKiBAdGd0IC0gSUQgb2YgdGhpcyBkZXZpY2UKICogQGJ1Zl9kbWFfaGFuZGxlIC0gRE1BIGFkZHJlc3Mgb2YgdGhlIGJ1ZmZlcgogKgogKiBJc3N1ZSB0aGUgc2NzaSBpbnF1aXJ5IGZvciB0aGUgc3BlY2lmaWVkIGRldmljZS4KICovCnN0YXRpYyBpbnQKbWVnYV9pbnRlcm5hbF9kZXZfaW5xdWlyeShhZGFwdGVyX3QgKmFkYXB0ZXIsIHU4IGNoLCB1OCB0Z3QsCgkJZG1hX2FkZHJfdCBidWZfZG1hX2hhbmRsZSkKewoJbWVnYV9wYXNzdGhydQkqcHRocnU7CglkbWFfYWRkcl90CXB0aHJ1X2RtYV9oYW5kbGU7CgltZWdhY21kX3QJbWM7CglpbnQJCXJ2YWw7CglzdHJ1Y3QgcGNpX2RldgkqcGRldjsKCgoJLyoKCSAqIEZvciBhbGwgaW50ZXJuYWwgY29tbWFuZHMsIHRoZSBidWZmZXIgbXVzdCBiZSBhbGxvY2F0ZWQgaW4gPDRHQgoJICogYWRkcmVzcyByYW5nZQoJICovCglpZiggbWFrZV9sb2NhbF9wZGV2KGFkYXB0ZXIsICZwZGV2KSAhPSAwICkgcmV0dXJuIC0xOwoKCXB0aHJ1ID0gcGNpX2FsbG9jX2NvbnNpc3RlbnQocGRldiwgc2l6ZW9mKG1lZ2FfcGFzc3RocnUpLAoJCQkmcHRocnVfZG1hX2hhbmRsZSk7CgoJaWYoIHB0aHJ1ID09IE5VTEwgKSB7CgkJZnJlZV9sb2NhbF9wZGV2KHBkZXYpOwoJCXJldHVybiAtMTsKCX0KCglwdGhydS0+dGltZW91dCA9IDI7CglwdGhydS0+YXJzID0gMTsKCXB0aHJ1LT5yZXFzZW5zZWxlbiA9IDE0OwoJcHRocnUtPmlzbG9naWNhbCA9IDA7CgoJcHRocnUtPmNoYW5uZWwgPSAoYWRhcHRlci0+ZmxhZyAmIEJPQVJEXzQwTEQpID8gMCA6IGNoOwoKCXB0aHJ1LT50YXJnZXQgPSAoYWRhcHRlci0+ZmxhZyAmIEJPQVJEXzQwTEQpID8gKGNoIDw8IDQpfHRndCA6IHRndDsKCglwdGhydS0+Y2RibGVuID0gNjsKCglwdGhydS0+Y2RiWzBdID0gSU5RVUlSWTsKCXB0aHJ1LT5jZGJbMV0gPSAwOwoJcHRocnUtPmNkYlsyXSA9IDA7CglwdGhydS0+Y2RiWzNdID0gMDsKCXB0aHJ1LT5jZGJbNF0gPSAyNTU7CglwdGhydS0+Y2RiWzVdID0gMDsKCgoJcHRocnUtPmRhdGF4ZmVyYWRkciA9ICh1MzIpYnVmX2RtYV9oYW5kbGU7CglwdGhydS0+ZGF0YXhmZXJsZW4gPSAyNTY7CgoJbWVtc2V0KCZtYywgMCwgc2l6ZW9mKG1lZ2FjbWRfdCkpOwoKCW1jLmNtZCA9IE1FR0FfTUJPWENNRF9QQVNTVEhSVTsKCW1jLnhmZXJhZGRyID0gKHUzMilwdGhydV9kbWFfaGFuZGxlOwoKCXJ2YWwgPSBtZWdhX2ludGVybmFsX2NvbW1hbmQoYWRhcHRlciwgTE9DS19JTlQsICZtYywgcHRocnUpOwoKCXBjaV9mcmVlX2NvbnNpc3RlbnQocGRldiwgc2l6ZW9mKG1lZ2FfcGFzc3RocnUpLCBwdGhydSwKCQkJcHRocnVfZG1hX2hhbmRsZSk7CgoJZnJlZV9sb2NhbF9wZGV2KHBkZXYpOwoKCXJldHVybiBydmFsOwp9CgoKLyoqCiAqIG1lZ2FfaW50ZXJuYWxfY29tbWFuZCgpCiAqIEBhZGFwdGVyIC0gcG9pbnRlciB0byBvdXIgc29mdCBzdGF0ZQogKiBAbHMgLSB0aGUgc2NvcGUgb2YgdGhlIGV4Y2x1c2lvbiBsb2NrLgogKiBAbWMgLSB0aGUgbWFpbGJveCBjb21tYW5kCiAqIEBwdGhydSAtIFBhc3N0aHJ1IHN0cnVjdHVyZSBmb3IgRENEQiBjb21tYW5kcwogKgogKiBJc3N1ZSB0aGUgaW50ZXJuYWwgY29tbWFuZHMgaW4gaW50ZXJydXB0IG1vZGUuCiAqIFRoZSBsYXN0IGFyZ3VtZW50IGlzIHRoZSBhZGRyZXNzIG9mIHRoZSBwYXNzdGhydSBzdHJ1Y3R1cmUgaWYgdGhlIGNvbW1hbmQKICogdG8gYmUgZmlyZWQgaXMgYSBwYXNzdGhydSBjb21tYW5kCiAqCiAqIGxvY2tzY29wZSBzcGVjaWZpZXMgd2hldGhlciB0aGUgY2FsbGVyIGhhcyBhbHJlYWR5IGFjcXVpcmVkIHRoZSBsb2NrLiBPZgogKiBjb3Vyc2UsIHRoZSBjYWxsZXIgbXVzdCBrbm93IHdoaWNoIGxvY2sgd2UgYXJlIHRhbGtpbmcgYWJvdXQuCiAqCiAqIE5vdGU6IHBhcmFtZXRlciAncHRocnUnIGlzIG51bGwgZm9yIG5vbi1wYXNzdGhydSBjb21tYW5kcy4KICovCnN0YXRpYyBpbnQKbWVnYV9pbnRlcm5hbF9jb21tYW5kKGFkYXB0ZXJfdCAqYWRhcHRlciwgbG9ja3Njb3BlX3QgbHMsIG1lZ2FjbWRfdCAqbWMsCgkJbWVnYV9wYXNzdGhydSAqcHRocnUgKQp7CglTY3NpX0NtbmQJKnNjbWQ7CglzdHJ1Y3QJc2NzaV9kZXZpY2UgKnNkZXY7Cgl1bnNpZ25lZCBsb25nCWZsYWdzID0gMDsKCXNjYl90CSpzY2I7CglpbnQJcnZhbDsKCgkvKgoJICogVGhlIGludGVybmFsIGNvbW1hbmRzIHNoYXJlIG9uZSBjb21tYW5kIGlkIGFuZCBoZW5jZSBhcmUKCSAqIHNlcmlhbGl6ZWQuIFRoaXMgaXMgc28gYmVjYXVzZSB3ZSB3YW50IHRvIHJlc2VydmUgbWF4aW11bSBudW1iZXIgb2YKCSAqIGF2YWlsYWJsZSBjb21tYW5kIGlkcyBmb3IgdGhlIEkvTyBjb21tYW5kcy4KCSAqLwoJZG93bigmYWRhcHRlci0+aW50X210eCk7CgoJc2NiID0gJmFkYXB0ZXItPmludF9zY2I7CgltZW1zZXQoc2NiLCAwLCBzaXplb2Yoc2NiX3QpKTsKCglzY21kID0gJmFkYXB0ZXItPmludF9zY21kOwoJbWVtc2V0KHNjbWQsIDAsIHNpemVvZihTY3NpX0NtbmQpKTsKCglzZGV2ID0ga21hbGxvYyhzaXplb2Yoc3RydWN0IHNjc2lfZGV2aWNlKSwgR0ZQX0tFUk5FTCk7CgltZW1zZXQoc2RldiwgMCwgc2l6ZW9mKHN0cnVjdCBzY3NpX2RldmljZSkpOwoJc2NtZC0+ZGV2aWNlID0gc2RldjsKCglzY21kLT5kZXZpY2UtPmhvc3QgPSBhZGFwdGVyLT5ob3N0OwoJc2NtZC0+YnVmZmVyID0gKHZvaWQgKilzY2I7CglzY21kLT5jbW5kWzBdID0gTUVHQV9JTlRFUk5BTF9DTUQ7CgoJc2NiLT5zdGF0ZSB8PSBTQ0JfQUNUSVZFOwoJc2NiLT5jbWQgPSBzY21kOwoKCW1lbWNweShzY2ItPnJhd19tYm94LCBtYywgc2l6ZW9mKG1lZ2FjbWRfdCkpOwoKCS8qCgkgKiBJcyBpdCBhIHBhc3N0aHJ1IGNvbW1hbmQKCSAqLwoJaWYoIG1jLT5jbWQgPT0gTUVHQV9NQk9YQ01EX1BBU1NUSFJVICkgewoKCQlzY2ItPnB0aHJ1ID0gcHRocnU7Cgl9CgoJc2NiLT5pZHggPSBDTURJRF9JTlRfQ01EUzsKCglzY21kLT5zdGF0ZSA9IDA7CgoJLyoKCSAqIEdldCB0aGUgbG9jayBvbmx5IGlmIHRoZSBjYWxsZXIgaGFzIG5vdCBhY3F1aXJlZCBpdCBhbHJlYWR5CgkgKi8KCWlmKCBscyA9PSBMT0NLX0lOVCApIHNwaW5fbG9ja19pcnFzYXZlKCZhZGFwdGVyLT5sb2NrLCBmbGFncyk7CgoJbWVnYXJhaWRfcXVldWUoc2NtZCwgbWVnYV9pbnRlcm5hbF9kb25lKTsKCglpZiggbHMgPT0gTE9DS19JTlQgKSBzcGluX3VubG9ja19pcnFyZXN0b3JlKCZhZGFwdGVyLT5sb2NrLCBmbGFncyk7CgoJLyoKCSAqIFdhaXQgdGlsbCB0aGlzIGNvbW1hbmQgZmluaXNoZXMuIERvIG5vdCB1c2UKCSAqIHdhaXRfZXZlbnRfaW50ZXJydXB0aWJsZSgpLiBJdCBjYXVzZXMgcGFuaWMgaWYgQ1RSTC1DIGlzIGhpdCB3aGVuCgkgKiBkdW1waW5nIGUuZy4sIHBoeXNpY2FsIGRpc2sgaW5mb3JtYXRpb24gdGhyb3VnaCAvcHJvYyBpbnRlcmZhY2UuCgkgKi8KI2lmIDAKCXdhaXRfZXZlbnRfaW50ZXJydXB0aWJsZShhZGFwdGVyLT5pbnRfd2FpdHEsIHNjbWQtPnN0YXRlKTsKI2VuZGlmCgl3YWl0X2V2ZW50KGFkYXB0ZXItPmludF93YWl0cSwgc2NtZC0+c3RhdGUpOwoKCXJ2YWwgPSBzY21kLT5yZXN1bHQ7CgltYy0+c3RhdHVzID0gc2NtZC0+cmVzdWx0OwoJa2ZyZWUoc2Rldik7CgoJLyoKCSAqIFByaW50IGEgZGVidWcgbWVzc2FnZSBmb3IgYWxsIGZhaWxlZCBjb21tYW5kcy4gQXBwbGljYXRpb25zIGNhbiB1c2UKCSAqIHRoaXMgaW5mb3JtYXRpb24uCgkgKi8KCWlmKCBzY21kLT5yZXN1bHQgJiYgdHJhY2VfbGV2ZWwgKSB7CgkJcHJpbnRrKCJtZWdhcmFpZDogY21kIFsleCwgJXgsICV4XSBzdGF0dXM6WyV4XVxuIiwKCQkJbWMtPmNtZCwgbWMtPm9wY29kZSwgbWMtPnN1Ym9wY29kZSwgc2NtZC0+cmVzdWx0KTsKCX0KCgl1cCgmYWRhcHRlci0+aW50X210eCk7CgoJcmV0dXJuIHJ2YWw7Cn0KCgovKioKICogbWVnYV9pbnRlcm5hbF9kb25lKCkKICogQHNjbWQgLSBpbnRlcm5hbCBzY3NpIGNvbW1hbmQKICoKICogQ2FsbGJhY2sgcm91dGluZSBmb3IgaW50ZXJuYWwgY29tbWFuZHMuCiAqLwpzdGF0aWMgdm9pZAptZWdhX2ludGVybmFsX2RvbmUoU2NzaV9DbW5kICpzY21kKQp7CglhZGFwdGVyX3QJKmFkYXB0ZXI7CgoJYWRhcHRlciA9IChhZGFwdGVyX3QgKilzY21kLT5kZXZpY2UtPmhvc3QtPmhvc3RkYXRhOwoKCXNjbWQtPnN0YXRlID0gMTsgLyogdGhyZWFkIHdhaXRpbmcgZm9yIGl0cyBjb21tYW5kIHRvIGNvbXBsZXRlICovCgoJLyoKCSAqIFNlZSBjb21tZW50IGluIG1lZ2FfaW50ZXJuYWxfY29tbWFuZCgpIHJvdXRpbmUgZm9yCgkgKiB3YWl0X2V2ZW50X2ludGVycnVwdGlibGUoKQoJICovCiNpZiAwCgl3YWtlX3VwX2ludGVycnVwdGlibGUoJmFkYXB0ZXItPmludF93YWl0cSk7CiNlbmRpZgoJd2FrZV91cCgmYWRhcHRlci0+aW50X3dhaXRxKTsKCn0KCgpzdGF0aWMgc3RydWN0IHNjc2lfaG9zdF90ZW1wbGF0ZSBtZWdhcmFpZF90ZW1wbGF0ZSA9IHsKCS5tb2R1bGUJCQkJPSBUSElTX01PRFVMRSwKCS5uYW1lCQkJCT0gIk1lZ2FSQUlEIiwKCS5wcm9jX25hbWUJCQk9ICJtZWdhcmFpZCIsCgkuaW5mbwkJCQk9IG1lZ2FyYWlkX2luZm8sCgkucXVldWVjb21tYW5kCQkJPSBtZWdhcmFpZF9xdWV1ZSwJCgkuYmlvc19wYXJhbQkJCT0gbWVnYXJhaWRfYmlvc3BhcmFtLAoJLm1heF9zZWN0b3JzCQkJPSBNQVhfU0VDVE9SU19QRVJfSU8sCgkuY2FuX3F1ZXVlCQkJPSBNQVhfQ09NTUFORFMsCgkudGhpc19pZAkJCT0gREVGQVVMVF9JTklUSUFUT1JfSUQsCgkuc2dfdGFibGVzaXplCQkJPSBNQVhfU0dMSVNULAoJLmNtZF9wZXJfbHVuCQkJPSBERUZfQ01EX1BFUl9MVU4sCgkudXNlX2NsdXN0ZXJpbmcJCQk9IEVOQUJMRV9DTFVTVEVSSU5HLAoJLmVoX2Fib3J0X2hhbmRsZXIJCT0gbWVnYXJhaWRfYWJvcnQsCgkuZWhfZGV2aWNlX3Jlc2V0X2hhbmRsZXIJPSBtZWdhcmFpZF9yZXNldCwKCS5laF9idXNfcmVzZXRfaGFuZGxlcgkJPSBtZWdhcmFpZF9yZXNldCwKCS5laF9ob3N0X3Jlc2V0X2hhbmRsZXIJCT0gbWVnYXJhaWRfcmVzZXQsCn07CgpzdGF0aWMgaW50IF9fZGV2aW5pdAptZWdhcmFpZF9wcm9iZV9vbmUoc3RydWN0IHBjaV9kZXYgKnBkZXYsIGNvbnN0IHN0cnVjdCBwY2lfZGV2aWNlX2lkICppZCkKewoJc3RydWN0IFNjc2lfSG9zdCAqaG9zdDsKCWFkYXB0ZXJfdCAqYWRhcHRlcjsKCXVuc2lnbmVkIGxvbmcgbWVnYV9iYXNlcG9ydCwgdGJhc2UsIGZsYWcgPSAwOwoJdTE2IHN1YnN5c2lkLCBzdWJzeXN2aWQ7Cgl1OCBwY2lfYnVzLCBwY2lfZGV2X2Z1bmM7CglpbnQgaXJxLCBpLCBqOwoJaW50IGVycm9yID0gLUVOT0RFVjsKCglpZiAocGNpX2VuYWJsZV9kZXZpY2UocGRldikpCgkJZ290byBvdXQ7CglwY2lfc2V0X21hc3RlcihwZGV2KTsKCglwY2lfYnVzID0gcGRldi0+YnVzLT5udW1iZXI7CglwY2lfZGV2X2Z1bmMgPSBwZGV2LT5kZXZmbjsKCgkvKgoJICogVGhlIG1lZ2FyYWlkMyBzdHVmZiByZXBvcnRzIHRoZSBJRCBvZiB0aGUgSW50ZWwgcGFydCB3aGljaCBpcyBub3QKCSAqIHJlbW90ZWx5IHNwZWNpZmljIHRvIHRoZSBtZWdhcmFpZAoJICovCglpZiAocGRldi0+dmVuZG9yID09IFBDSV9WRU5ET1JfSURfSU5URUwpIHsKCQl1MTYgbWFnaWM7CgkJLyoKCQkgKiBEb24ndCBmYWxsIG92ZXIgdGhlIENvbXBhcSBtYW5hZ2VtZW50IGNhcmRzIHVzaW5nIHRoZSBzYW1lCgkJICogUENJIGlkZW50aWZpZXIKCQkgKi8KCQlpZiAocGRldi0+c3Vic3lzdGVtX3ZlbmRvciA9PSBQQ0lfVkVORE9SX0lEX0NPTVBBUSAmJgoJCSAgICBwZGV2LT5zdWJzeXN0ZW1fZGV2aWNlID09IDB4QzAwMCkKCQkgICAJcmV0dXJuIC1FTk9ERVY7CgkJLyogTm93IGNoZWNrIHRoZSBtYWdpYyBzaWduYXR1cmUgYnl0ZSAqLwoJCXBjaV9yZWFkX2NvbmZpZ193b3JkKHBkZXYsIFBDSV9DT05GX0FNSVNJRywgJm1hZ2ljKTsKCQlpZiAobWFnaWMgIT0gSEJBX1NJR05BVFVSRV80NzEgJiYgbWFnaWMgIT0gSEJBX1NJR05BVFVSRSkKCQkJcmV0dXJuIC1FTk9ERVY7CgkJLyogT2sgaXQgaXMgcHJvYmFibHkgYSBtZWdhcmFpZCAqLwoJfQoKCS8qCgkgKiBGb3IgdGhlc2UgdmVuZG9yIGFuZCBkZXZpY2UgaWRzLCBzaWduYXR1cmUgb2Zmc2V0cyBhcmUgbm90CgkgKiB2YWxpZCBhbmQgNjQgYml0IGlzIGltcGxpY2l0CgkgKi8KCWlmIChpZC0+ZHJpdmVyX2RhdGEgJiBCT0FSRF82NEJJVCkKCQlmbGFnIHw9IEJPQVJEXzY0QklUOwoJZWxzZSB7CgkJdTMyIG1hZ2ljNjQ7CgoJCXBjaV9yZWFkX2NvbmZpZ19kd29yZChwZGV2LCBQQ0lfQ09ORl9BTUlTSUc2NCwgJm1hZ2ljNjQpOwoJCWlmIChtYWdpYzY0ID09IEhCQV9TSUdOQVRVUkVfNjRCSVQpCgkJCWZsYWcgfD0gQk9BUkRfNjRCSVQ7Cgl9CgoJc3Vic3lzdmlkID0gcGRldi0+c3Vic3lzdGVtX3ZlbmRvcjsKCXN1YnN5c2lkID0gcGRldi0+c3Vic3lzdGVtX2RldmljZTsKCglwcmludGsoS0VSTl9OT1RJQ0UgIm1lZ2FyYWlkOiBmb3VuZCAweCU0LjA0eDoweCU0LjA0eDpidXMgJWQ6IiwKCQlpZC0+dmVuZG9yLCBpZC0+ZGV2aWNlLCBwY2lfYnVzKTsKCglwcmludGsoInNsb3QgJWQ6ZnVuYyAlZFxuIiwKCQlQQ0lfU0xPVChwY2lfZGV2X2Z1bmMpLCBQQ0lfRlVOQyhwY2lfZGV2X2Z1bmMpKTsKCgkvKiBSZWFkIHRoZSBiYXNlIHBvcnQgYW5kIElSUSBmcm9tIFBDSSAqLwoJbWVnYV9iYXNlcG9ydCA9IHBjaV9yZXNvdXJjZV9zdGFydChwZGV2LCAwKTsKCWlycSA9IHBkZXYtPmlycTsKCgl0YmFzZSA9IG1lZ2FfYmFzZXBvcnQ7CglpZiAocGNpX3Jlc291cmNlX2ZsYWdzKHBkZXYsIDApICYgSU9SRVNPVVJDRV9NRU0pIHsKCQlmbGFnIHw9IEJPQVJEX01FTU1BUDsKCgkJaWYgKCFyZXF1ZXN0X21lbV9yZWdpb24obWVnYV9iYXNlcG9ydCwgMTI4LCAibWVnYXJhaWQiKSkgewoJCQlwcmludGsoS0VSTl9XQVJOSU5HICJtZWdhcmFpZDogbWVtIHJlZ2lvbiBidXN5IVxuIik7CgkJCWdvdG8gb3V0X2Rpc2FibGVfZGV2aWNlOwoJCX0KCgkJbWVnYV9iYXNlcG9ydCA9ICh1bnNpZ25lZCBsb25nKWlvcmVtYXAobWVnYV9iYXNlcG9ydCwgMTI4KTsKCQlpZiAoIW1lZ2FfYmFzZXBvcnQpIHsKCQkJcHJpbnRrKEtFUk5fV0FSTklORwoJCQkgICAgICAgIm1lZ2FyYWlkOiBjb3VsZCBub3QgbWFwIGhiYSBtZW1vcnlcbiIpOwoJCQlnb3RvIG91dF9yZWxlYXNlX3JlZ2lvbjsKCQl9Cgl9IGVsc2UgewoJCWZsYWcgfD0gQk9BUkRfSU9NQVA7CgkJbWVnYV9iYXNlcG9ydCArPSAweDEwOwoKCQlpZiAoIXJlcXVlc3RfcmVnaW9uKG1lZ2FfYmFzZXBvcnQsIDE2LCAibWVnYXJhaWQiKSkKCQkJZ290byBvdXRfZGlzYWJsZV9kZXZpY2U7Cgl9CgoJLyogSW5pdGlhbGl6ZSBTQ1NJIEhvc3Qgc3RydWN0dXJlICovCglob3N0ID0gc2NzaV9ob3N0X2FsbG9jKCZtZWdhcmFpZF90ZW1wbGF0ZSwgc2l6ZW9mKGFkYXB0ZXJfdCkpOwoJaWYgKCFob3N0KQoJCWdvdG8gb3V0X2lvdW5tYXA7CgoJYWRhcHRlciA9IChhZGFwdGVyX3QgKilob3N0LT5ob3N0ZGF0YTsKCW1lbXNldChhZGFwdGVyLCAwLCBzaXplb2YoYWRhcHRlcl90KSk7CgoJcHJpbnRrKEtFUk5fTk9USUNFCgkJInNjc2klZDpGb3VuZCBNZWdhUkFJRCBjb250cm9sbGVyIGF0IDB4JWx4LCBJUlE6JWRcbiIsCgkJaG9zdC0+aG9zdF9ubywgbWVnYV9iYXNlcG9ydCwgaXJxKTsKCglhZGFwdGVyLT5iYXNlID0gbWVnYV9iYXNlcG9ydDsKCglJTklUX0xJU1RfSEVBRCgmYWRhcHRlci0+ZnJlZV9saXN0KTsKCUlOSVRfTElTVF9IRUFEKCZhZGFwdGVyLT5wZW5kaW5nX2xpc3QpOwoJSU5JVF9MSVNUX0hFQUQoJmFkYXB0ZXItPmNvbXBsZXRlZF9saXN0KTsKCglhZGFwdGVyLT5mbGFnID0gZmxhZzsKCXNwaW5fbG9ja19pbml0KCZhZGFwdGVyLT5sb2NrKTsKCXNjc2lfYXNzaWduX2xvY2soaG9zdCwgJmFkYXB0ZXItPmxvY2spOwoKCWhvc3QtPmNtZF9wZXJfbHVuID0gbWF4X2NtZF9wZXJfbHVuOwoJaG9zdC0+bWF4X3NlY3RvcnMgPSBtYXhfc2VjdG9yc19wZXJfaW87CgoJYWRhcHRlci0+ZGV2ID0gcGRldjsKCWFkYXB0ZXItPmhvc3QgPSBob3N0OwoKCWFkYXB0ZXItPmhvc3QtPmlycSA9IGlycTsKCglpZiAoZmxhZyAmIEJPQVJEX01FTU1BUCkKCQlhZGFwdGVyLT5ob3N0LT5iYXNlID0gdGJhc2U7CgllbHNlIHsKCQlhZGFwdGVyLT5ob3N0LT5pb19wb3J0ID0gdGJhc2U7CgkJYWRhcHRlci0+aG9zdC0+bl9pb19wb3J0ID0gMTY7Cgl9CgoJYWRhcHRlci0+aG9zdC0+dW5pcXVlX2lkID0gKHBjaV9idXMgPDwgOCkgfCBwY2lfZGV2X2Z1bmM7CgoJLyoKCSAqIEFsbG9jYXRlIGJ1ZmZlciB0byBpc3N1ZSBpbnRlcm5hbCBjb21tYW5kcy4KCSAqLwoJYWRhcHRlci0+bWVnYV9idWZmZXIgPSBwY2lfYWxsb2NfY29uc2lzdGVudChhZGFwdGVyLT5kZXYsCgkJTUVHQV9CVUZGRVJfU0laRSwgJmFkYXB0ZXItPmJ1Zl9kbWFfaGFuZGxlKTsKCWlmICghYWRhcHRlci0+bWVnYV9idWZmZXIpIHsKCQlwcmludGsoS0VSTl9XQVJOSU5HICJtZWdhcmFpZDogb3V0IG9mIFJBTS5cbiIpOwoJCWdvdG8gb3V0X2hvc3RfcHV0OwoJfQoKCWFkYXB0ZXItPnNjYl9saXN0ID0ga21hbGxvYyhzaXplb2Yoc2NiX3QpICogTUFYX0NPTU1BTkRTLCBHRlBfS0VSTkVMKTsKCWlmICghYWRhcHRlci0+c2NiX2xpc3QpIHsKCQlwcmludGsoS0VSTl9XQVJOSU5HICJtZWdhcmFpZDogb3V0IG9mIFJBTS5cbiIpOwoJCWdvdG8gb3V0X2ZyZWVfY21kX2J1ZmZlcjsKCX0KCglpZiAocmVxdWVzdF9pcnEoaXJxLCAoYWRhcHRlci0+ZmxhZyAmIEJPQVJEX01FTU1BUCkgPwoJCQkJbWVnYXJhaWRfaXNyX21lbW1hcHBlZCA6IG1lZ2FyYWlkX2lzcl9pb21hcHBlZCwKCQkJCQlTQV9TSElSUSwgIm1lZ2FyYWlkIiwgYWRhcHRlcikpIHsKCQlwcmludGsoS0VSTl9XQVJOSU5HCgkJCSJtZWdhcmFpZDogQ291bGRuJ3QgcmVnaXN0ZXIgSVJRICVkIVxuIiwgaXJxKTsKCQlnb3RvIG91dF9mcmVlX3NjYl9saXN0OwoJfQoKCWlmIChtZWdhX3NldHVwX21haWxib3goYWRhcHRlcikpCgkJZ290byBvdXRfZnJlZV9pcnE7CgoJaWYgKG1lZ2FfcXVlcnlfYWRhcHRlcihhZGFwdGVyKSkKCQlnb3RvIG91dF9mcmVlX21ib3g7CgoJLyoKCSAqIEhhdmUgY2hlY2tzIGZvciBzb21lIGJ1Z2d5IGYvdwoJICovCglpZiAoKHN1YnN5c2lkID09IDB4MTExMSkgJiYgKHN1YnN5c3ZpZCA9PSAweDExMTEpKSB7CgkJLyoKCQkgKiBXaGljaCBmaXJtd2FyZQoJCSAqLwoJCWlmICghc3RyY21wKGFkYXB0ZXItPmZ3X3ZlcnNpb24sICIzLjAwIikgfHwKCQkJCSFzdHJjbXAoYWRhcHRlci0+ZndfdmVyc2lvbiwgIjMuMDEiKSkgewoKCQkJcHJpbnRrKCBLRVJOX1dBUk5JTkcKCQkJCSJtZWdhcmFpZDogWW91ciAgY2FyZCBpcyBhIERlbGwgUEVSQyAiCgkJCQkiMi9TQyBSQUlEIGNvbnRyb2xsZXIgd2l0aCAgIgoJCQkJImZpcm13YXJlXG5tZWdhcmFpZDogMy4wMCBvciAzLjAxLiAgIgoJCQkJIlRoaXMgZHJpdmVyIGlzIGtub3duIHRvIGhhdmUgIgoJCQkJImNvcnJ1cHRpb24gaXNzdWVzXG5tZWdhcmFpZDogd2l0aCAiCgkJCQkidGhvc2UgZmlybXdhcmUgdmVyc2lvbnMgb24gdGhpcyAiCgkJCQkic3BlY2lmaWMgY2FyZC4gIEluIG9yZGVyXG5tZWdhcmFpZDogIgoJCQkJInRvIHByb3RlY3QgeW91ciBkYXRhLCBwbGVhc2UgdXBncmFkZSAiCgkJCQkieW91ciBmaXJtd2FyZSB0byB2ZXJzaW9uXG5tZWdhcmFpZDogIgoJCQkJIjMuMTAgb3IgbGF0ZXIsIGF2YWlsYWJsZSBmcm9tIHRoZSAiCgkJCQkiRGVsbCBUZWNobmljYWwgU3VwcG9ydCB3ZWJcbiIKCQkJCSJtZWdhcmFpZDogc2l0ZSBhdFxuaHR0cDovL3N1cHBvcnQuIgoJCQkJImRlbGwuY29tL3VzL2VuL2ZpbGVsaWIvZG93bmxvYWQvIgoJCQkJImluZGV4LmFzcD9maWxlaWQ9Mjk0MFxuIgoJCQkpOwoJCX0KCX0KCgkvKgoJICogSWYgd2UgaGF2ZSBhIEhQIDFNKDB4NjBFNykvMk0oMHg2MEU4KSBjb250cm9sbGVyIHdpdGgKCSAqIGZpcm13YXJlIEguMDEuMDcsIEguMDEuMDgsIGFuZCBILjAxLjA5IGRpc2FibGUgNjQgYml0CgkgKiBzdXBwb3J0LCBzaW5jZSB0aGlzIGZpcm13YXJlIGNhbm5vdCBoYW5kbGUgNjQgYml0CgkgKiBhZGRyZXNzaW5nCgkgKi8KCWlmICgoc3Vic3lzdmlkID09IEhQX1NVQlNZU19WSUQpICYmCgkgICAgKChzdWJzeXNpZCA9PSAweDYwRTcpIHx8IChzdWJzeXNpZCA9PSAweDYwRTgpKSkgewoJCS8qCgkJICogd2hpY2ggZmlybXdhcmUKCQkgKi8KCQlpZiAoIXN0cmNtcChhZGFwdGVyLT5md192ZXJzaW9uLCAiSDAxLjA3IikgfHwKCQkgICAgIXN0cmNtcChhZGFwdGVyLT5md192ZXJzaW9uLCAiSDAxLjA4IikgfHwKCQkgICAgIXN0cmNtcChhZGFwdGVyLT5md192ZXJzaW9uLCAiSDAxLjA5IikgKSB7CgkJCXByaW50ayhLRVJOX1dBUk5JTkcKCQkJCSJtZWdhcmFpZDogRmlybXdhcmUgSC4wMS4wNywgIgoJCQkJIkguMDEuMDgsIGFuZCBILjAxLjA5IG9uIDFNLzJNICIKCQkJCSJjb250cm9sbGVyc1xuIgoJCQkJIm1lZ2FyYWlkOiBkbyBub3Qgc3VwcG9ydCA2NCBiaXQgIgoJCQkJImFkZHJlc3NpbmcuXG5tZWdhcmFpZDogRElTQUJMSU5HICIKCQkJCSI2NCBiaXQgc3VwcG9ydC5cbiIpOwoJCQlhZGFwdGVyLT5mbGFnICY9IH5CT0FSRF82NEJJVDsKCQl9Cgl9CgoJaWYgKG1lZ2FfaXNfYmlvc19lbmFibGVkKGFkYXB0ZXIpKQoJCW1lZ2FfaGJhc1toYmFfY291bnRdLmlzX2Jpb3NfZW5hYmxlZCA9IDE7CgltZWdhX2hiYXNbaGJhX2NvdW50XS5ob3N0ZGF0YV9hZGRyID0gYWRhcHRlcjsKCgkvKgoJICogRmluZCBvdXQgd2hpY2ggY2hhbm5lbCBpcyByYWlkIGFuZCB3aGljaCBpcyBzY3NpLiBUaGlzIGlzCgkgKiBmb3IgUk9NQiBzdXBwb3J0LgoJICovCgltZWdhX2VudW1fcmFpZF9zY3NpKGFkYXB0ZXIpOwoKCS8qCgkgKiBGaW5kIG91dCBpZiBhIGxvZ2ljYWwgZHJpdmUgaXMgc2V0IGFzIHRoZSBib290IGRyaXZlLiBJZgoJICogdGhlcmUgaXMgb25lLCB3aWxsIG1ha2UgdGhhdCBhcyB0aGUgZmlyc3QgbG9naWNhbCBkcml2ZS4KCSAqIFJPTUI6IERvIHdlIGhhdmUgdG8gYm9vdCBmcm9tIGEgcGh5c2ljYWwgZHJpdmUuIFRoZW4gYWxsCgkgKiB0aGUgcGh5c2ljYWwgZHJpdmVzIHdvdWxkIGFwcGVhciBiZWZvcmUgdGhlIGxvZ2ljYWwgZGlza3MuCgkgKiBFbHNlLCBhbGwgdGhlIHBoeXNpY2FsIGRyaXZlcyB3b3VsZCBiZSBleHBvcnRlZCB0byB0aGUgbWlkCgkgKiBsYXllciBhZnRlciBsb2dpY2FsIGRyaXZlcy4KCSAqLwoJbWVnYV9nZXRfYm9vdF9kcnYoYWRhcHRlcik7CgoJaWYgKGFkYXB0ZXItPmJvb3RfcGRydl9lbmFibGVkKSB7CgkJaiA9IGFkYXB0ZXItPnByb2R1Y3RfaW5mby5uY2hhbm5lbHM7CgkJZm9yKCBpID0gMDsgaSA8IGo7IGkrKyApCgkJCWFkYXB0ZXItPmxvZ2Rydl9jaGFuW2ldID0gMDsKCQlmb3IoIGkgPSBqOyBpIDwgTlZJUlRfQ0hBTiArIGo7IGkrKyApCgkJCWFkYXB0ZXItPmxvZ2Rydl9jaGFuW2ldID0gMTsKCX0gZWxzZSB7CgkJZm9yIChpID0gMDsgaSA8IE5WSVJUX0NIQU47IGkrKykKCQkJYWRhcHRlci0+bG9nZHJ2X2NoYW5baV0gPSAxOwoJCWZvciAoaSA9IE5WSVJUX0NIQU47IGkgPCBNQVhfQ0hBTk5FTFMrTlZJUlRfQ0hBTjsgaSsrKQoJCQlhZGFwdGVyLT5sb2dkcnZfY2hhbltpXSA9IDA7CgkJYWRhcHRlci0+bWVnYV9jaF9jbGFzcyA8PD0gTlZJUlRfQ0hBTjsKCX0KCgkvKgoJICogRG8gd2Ugc3VwcG9ydCByYW5kb20gZGVsZXRpb24gYW5kIGFkZGl0aW9uIG9mIGxvZ2ljYWwKCSAqIGRyaXZlcwoJICovCglhZGFwdGVyLT5yZWFkX2xkaWRtYXAgPSAwOwkvKiBzZXQgaXQgYWZ0ZXIgZmlyc3QgbG9nZHJ2CgkJCQkJCSAgIGRlbGV0ZSBjbWQgKi8KCWFkYXB0ZXItPnN1cHBvcnRfcmFuZG9tX2RlbCA9IG1lZ2Ffc3VwcG9ydF9yYW5kb21fZGVsKGFkYXB0ZXIpOwoKCS8qIEluaXRpYWxpemUgU0NCcyAqLwoJaWYgKG1lZ2FfaW5pdF9zY2IoYWRhcHRlcikpCgkJZ290byBvdXRfZnJlZV9tYm94OwoKCS8qCgkgKiBSZXNldCB0aGUgcGVuZGluZyBjb21tYW5kcyBjb3VudGVyCgkgKi8KCWF0b21pY19zZXQoJmFkYXB0ZXItPnBlbmRfY21kcywgMCk7CgoJLyoKCSAqIFJlc2V0IHRoZSBhZGFwdGVyIHF1aWVzY2VudCBmbGFnCgkgKi8KCWF0b21pY19zZXQoJmFkYXB0ZXItPnF1aWVzY2VudCwgMCk7CgoJaGJhX3NvZnRfc3RhdGVbaGJhX2NvdW50XSA9IGFkYXB0ZXI7CgoJLyoKCSAqIEZpbGwgaW4gdGhlIHN0cnVjdHVyZSB3aGljaCBuZWVkcyB0byBiZSBwYXNzZWQgYmFjayB0byB0aGUKCSAqIGFwcGxpY2F0aW9uIHdoZW4gaXQgZG9lcyBhbiBpb2N0bCgpIGZvciBjb250cm9sbGVyIHJlbGF0ZWQKCSAqIGluZm9ybWF0aW9uLgoJICovCglpID0gaGJhX2NvdW50OwoKCW1jb250cm9sbGVyW2ldLmJhc2UgPSBtZWdhX2Jhc2Vwb3J0OwoJbWNvbnRyb2xsZXJbaV0uaXJxID0gaXJxOwoJbWNvbnRyb2xsZXJbaV0ubnVtbGRydiA9IGFkYXB0ZXItPm51bWxkcnY7CgltY29udHJvbGxlcltpXS5wY2lidXMgPSBwY2lfYnVzOwoJbWNvbnRyb2xsZXJbaV0ucGNpZGV2ID0gaWQtPmRldmljZTsKCW1jb250cm9sbGVyW2ldLnBjaWZ1biA9IFBDSV9GVU5DIChwY2lfZGV2X2Z1bmMpOwoJbWNvbnRyb2xsZXJbaV0ucGNpaWQgPSAtMTsKCW1jb250cm9sbGVyW2ldLnBjaXZlbmRvciA9IGlkLT52ZW5kb3I7CgltY29udHJvbGxlcltpXS5wY2lzbG90ID0gUENJX1NMT1QocGNpX2Rldl9mdW5jKTsKCW1jb250cm9sbGVyW2ldLnVpZCA9IChwY2lfYnVzIDw8IDgpIHwgcGNpX2Rldl9mdW5jOwoKCgkvKiBTZXQgdGhlIE1vZGUgb2YgYWRkcmVzc2luZyB0byA2NCBiaXQgaWYgd2UgY2FuICovCglpZiAoKGFkYXB0ZXItPmZsYWcgJiBCT0FSRF82NEJJVCkgJiYgKHNpemVvZihkbWFfYWRkcl90KSA9PSA4KSkgewoJCXBjaV9zZXRfZG1hX21hc2socGRldiwgMHhmZmZmZmZmZmZmZmZmZmZmVUxMKTsKCQlhZGFwdGVyLT5oYXNfNjRiaXRfYWRkciA9IDE7Cgl9IGVsc2UgIHsKCQlwY2lfc2V0X2RtYV9tYXNrKHBkZXYsIDB4ZmZmZmZmZmYpOwoJCWFkYXB0ZXItPmhhc182NGJpdF9hZGRyID0gMDsKCX0KCQkKCWluaXRfTVVURVgoJmFkYXB0ZXItPmludF9tdHgpOwoJaW5pdF93YWl0cXVldWVfaGVhZCgmYWRhcHRlci0+aW50X3dhaXRxKTsKCglhZGFwdGVyLT50aGlzX2lkID0gREVGQVVMVF9JTklUSUFUT1JfSUQ7CglhZGFwdGVyLT5ob3N0LT50aGlzX2lkID0gREVGQVVMVF9JTklUSUFUT1JfSUQ7CgojaWYgTUVHQV9IQVZFX0NMVVNURVJJTkcKCS8qCgkgKiBJcyBjbHVzdGVyIHN1cHBvcnQgZW5hYmxlZCBvbiB0aGlzIGNvbnRyb2xsZXIKCSAqIE5vdGU6IEluIGEgY2x1c3RlciB0aGUgSEJBcyAoIHRoZSBpbml0aWF0b3JzICkgd2lsbCBoYXZlCgkgKiBkaWZmZXJlbnQgdGFyZ2V0IElEcyBhbmQgd2UgY2Fubm90IGFzc3VtZSBpdCB0byBiZSA3LiBDYWxsCgkgKiB0byBtZWdhX3N1cHBvcnRfY2x1c3RlcigpIHdpbGwgZ2V0IHRoZSB0YXJnZXQgaWRzIGFsc28gaWYKCSAqIHRoZSBjbHVzdGVyIHN1cHBvcnQgaXMgYXZhaWxhYmxlCgkgKi8KCWFkYXB0ZXItPmhhc19jbHVzdGVyID0gbWVnYV9zdXBwb3J0X2NsdXN0ZXIoYWRhcHRlcik7CglpZiAoYWRhcHRlci0+aGFzX2NsdXN0ZXIpIHsKCQlwcmludGsoS0VSTl9OT1RJQ0UKCQkJIm1lZ2FyYWlkOiBDbHVzdGVyIGRyaXZlciwgaW5pdGlhdG9yIGlkOiVkXG4iLAoJCQlhZGFwdGVyLT50aGlzX2lkKTsKCX0KI2VuZGlmCgoJcGNpX3NldF9kcnZkYXRhKHBkZXYsIGhvc3QpOwoKCW1lZ2FfY3JlYXRlX3Byb2NfZW50cnkoaGJhX2NvdW50LCBtZWdhX3Byb2NfZGlyX2VudHJ5KTsKCgllcnJvciA9IHNjc2lfYWRkX2hvc3QoaG9zdCwgJnBkZXYtPmRldik7CglpZiAoZXJyb3IpCgkJZ290byBvdXRfZnJlZV9tYm94OwoKCXNjc2lfc2Nhbl9ob3N0KGhvc3QpOwoJaGJhX2NvdW50Kys7CglyZXR1cm4gMDsKCiBvdXRfZnJlZV9tYm94OgoJcGNpX2ZyZWVfY29uc2lzdGVudChhZGFwdGVyLT5kZXYsIHNpemVvZihtYm94NjRfdCksCgkJCWFkYXB0ZXItPnVuYV9tYm94NjQsIGFkYXB0ZXItPnVuYV9tYm94NjRfZG1hKTsKIG91dF9mcmVlX2lycToKCWZyZWVfaXJxKGFkYXB0ZXItPmhvc3QtPmlycSwgYWRhcHRlcik7CiBvdXRfZnJlZV9zY2JfbGlzdDoKCWtmcmVlKGFkYXB0ZXItPnNjYl9saXN0KTsKIG91dF9mcmVlX2NtZF9idWZmZXI6CglwY2lfZnJlZV9jb25zaXN0ZW50KGFkYXB0ZXItPmRldiwgTUVHQV9CVUZGRVJfU0laRSwKCQkJYWRhcHRlci0+bWVnYV9idWZmZXIsIGFkYXB0ZXItPmJ1Zl9kbWFfaGFuZGxlKTsKIG91dF9ob3N0X3B1dDoKCXNjc2lfaG9zdF9wdXQoaG9zdCk7CiBvdXRfaW91bm1hcDoKCWlmIChmbGFnICYgQk9BUkRfTUVNTUFQKQoJCWlvdW5tYXAoKHZvaWQgKiltZWdhX2Jhc2Vwb3J0KTsKIG91dF9yZWxlYXNlX3JlZ2lvbjoKCWlmIChmbGFnICYgQk9BUkRfTUVNTUFQKQoJCXJlbGVhc2VfbWVtX3JlZ2lvbih0YmFzZSwgMTI4KTsKCWVsc2UKCQlyZWxlYXNlX3JlZ2lvbihtZWdhX2Jhc2Vwb3J0LCAxNik7CiBvdXRfZGlzYWJsZV9kZXZpY2U6CglwY2lfZGlzYWJsZV9kZXZpY2UocGRldik7CiBvdXQ6CglyZXR1cm4gZXJyb3I7Cn0KCnN0YXRpYyB2b2lkCl9fbWVnYXJhaWRfc2h1dGRvd24oYWRhcHRlcl90ICphZGFwdGVyKQp7Cgl1X2NoYXIJcmF3X21ib3hbc2l6ZW9mKHN0cnVjdCBtYm94X291dCldOwoJbWJveF90CSptYm94ID0gKG1ib3hfdCAqKXJhd19tYm94OwoJaW50CWk7CgoJLyogRmx1c2ggYWRhcHRlciBjYWNoZSAqLwoJbWVtc2V0KCZtYm94LT5tX291dCwgMCwgc2l6ZW9mKHJhd19tYm94KSk7CglyYXdfbWJveFswXSA9IEZMVVNIX0FEQVBURVI7CgoJZnJlZV9pcnEoYWRhcHRlci0+aG9zdC0+aXJxLCBhZGFwdGVyKTsKCgkvKiBJc3N1ZSBhIGJsb2NraW5nIChpbnRlcnJ1cHRzIGRpc2FibGVkKSBjb21tYW5kIHRvIHRoZSBjYXJkICovCglpc3N1ZV9zY2JfYmxvY2soYWRhcHRlciwgcmF3X21ib3gpOwoKCS8qIEZsdXNoIGRpc2tzIGNhY2hlICovCgltZW1zZXQoJm1ib3gtPm1fb3V0LCAwLCBzaXplb2YocmF3X21ib3gpKTsKCXJhd19tYm94WzBdID0gRkxVU0hfU1lTVEVNOwoKCS8qIElzc3VlIGEgYmxvY2tpbmcgKGludGVycnVwdHMgZGlzYWJsZWQpIGNvbW1hbmQgdG8gdGhlIGNhcmQgKi8KCWlzc3VlX3NjYl9ibG9jayhhZGFwdGVyLCByYXdfbWJveCk7CgkKCWlmIChhdG9taWNfcmVhZCgmYWRhcHRlci0+cGVuZF9jbWRzKSA+IDApCgkJcHJpbnRrKEtFUk5fV0FSTklORyAibWVnYXJhaWQ6IHBlbmRpbmcgY29tbWFuZHMhIVxuIik7CgoJLyoKCSAqIEhhdmUgYSBkZWxpYnJhdGUgZGVsYXkgdG8gbWFrZSBzdXJlIGFsbCB0aGUgY2FjaGVzIGFyZQoJICogYWN0dWFsbHkgZmx1c2hlZC4KCSAqLwoJZm9yIChpID0gMDsgaSA8PSAxMDsgaSsrKQoJCW1kZWxheSgxMDAwKTsKfQoKc3RhdGljIHZvaWQKbWVnYXJhaWRfcmVtb3ZlX29uZShzdHJ1Y3QgcGNpX2RldiAqcGRldikKewoJc3RydWN0IFNjc2lfSG9zdCAqaG9zdCA9IHBjaV9nZXRfZHJ2ZGF0YShwZGV2KTsKCWFkYXB0ZXJfdCAqYWRhcHRlciA9IChhZGFwdGVyX3QgKilob3N0LT5ob3N0ZGF0YTsKCWNoYXIJYnVmWzEyXSA9IHsgMCB9OwoKCXNjc2lfcmVtb3ZlX2hvc3QoaG9zdCk7CgoJX19tZWdhcmFpZF9zaHV0ZG93bihhZGFwdGVyKTsKCgkvKiBGcmVlIG91ciByZXNvdXJjZXMgKi8KCWlmIChhZGFwdGVyLT5mbGFnICYgQk9BUkRfTUVNTUFQKSB7CgkJaW91bm1hcCgodm9pZCAqKWFkYXB0ZXItPmJhc2UpOwoJCXJlbGVhc2VfbWVtX3JlZ2lvbihhZGFwdGVyLT5ob3N0LT5iYXNlLCAxMjgpOwoJfSBlbHNlCgkJcmVsZWFzZV9yZWdpb24oYWRhcHRlci0+YmFzZSwgMTYpOwoKCW1lZ2FfZnJlZV9zZ2woYWRhcHRlcik7CgojaWZkZWYgQ09ORklHX1BST0NfRlMKCWlmIChhZGFwdGVyLT5jb250cm9sbGVyX3Byb2NfZGlyX2VudHJ5KSB7CgkJcmVtb3ZlX3Byb2NfZW50cnkoInN0YXQiLCBhZGFwdGVyLT5jb250cm9sbGVyX3Byb2NfZGlyX2VudHJ5KTsKCQlyZW1vdmVfcHJvY19lbnRyeSgiY29uZmlnIiwKCQkJCWFkYXB0ZXItPmNvbnRyb2xsZXJfcHJvY19kaXJfZW50cnkpOwoJCXJlbW92ZV9wcm9jX2VudHJ5KCJtYWlsYm94IiwKCQkJCWFkYXB0ZXItPmNvbnRyb2xsZXJfcHJvY19kaXJfZW50cnkpOwojaWYgTUVHQV9IQVZFX0VOSF9QUk9DCgkJcmVtb3ZlX3Byb2NfZW50cnkoInJlYnVpbGQtcmF0ZSIsCgkJCQlhZGFwdGVyLT5jb250cm9sbGVyX3Byb2NfZGlyX2VudHJ5KTsKCQlyZW1vdmVfcHJvY19lbnRyeSgiYmF0dGVyeS1zdGF0dXMiLAoJCQkJYWRhcHRlci0+Y29udHJvbGxlcl9wcm9jX2Rpcl9lbnRyeSk7CgoJCXJlbW92ZV9wcm9jX2VudHJ5KCJkaXNrZHJpdmVzLWNoMCIsCgkJCQlhZGFwdGVyLT5jb250cm9sbGVyX3Byb2NfZGlyX2VudHJ5KTsKCQlyZW1vdmVfcHJvY19lbnRyeSgiZGlza2RyaXZlcy1jaDEiLAoJCQkJYWRhcHRlci0+Y29udHJvbGxlcl9wcm9jX2Rpcl9lbnRyeSk7CgkJcmVtb3ZlX3Byb2NfZW50cnkoImRpc2tkcml2ZXMtY2gyIiwKCQkJCWFkYXB0ZXItPmNvbnRyb2xsZXJfcHJvY19kaXJfZW50cnkpOwoJCXJlbW92ZV9wcm9jX2VudHJ5KCJkaXNrZHJpdmVzLWNoMyIsCgkJCQlhZGFwdGVyLT5jb250cm9sbGVyX3Byb2NfZGlyX2VudHJ5KTsKCgkJcmVtb3ZlX3Byb2NfZW50cnkoInJhaWRkcml2ZXMtMC05IiwKCQkJCWFkYXB0ZXItPmNvbnRyb2xsZXJfcHJvY19kaXJfZW50cnkpOwoJCXJlbW92ZV9wcm9jX2VudHJ5KCJyYWlkZHJpdmVzLTEwLTE5IiwKCQkJCWFkYXB0ZXItPmNvbnRyb2xsZXJfcHJvY19kaXJfZW50cnkpOwoJCXJlbW92ZV9wcm9jX2VudHJ5KCJyYWlkZHJpdmVzLTIwLTI5IiwKCQkJCWFkYXB0ZXItPmNvbnRyb2xsZXJfcHJvY19kaXJfZW50cnkpOwoJCXJlbW92ZV9wcm9jX2VudHJ5KCJyYWlkZHJpdmVzLTMwLTM5IiwKCQkJCWFkYXB0ZXItPmNvbnRyb2xsZXJfcHJvY19kaXJfZW50cnkpOwojZW5kaWYKCQlzcHJpbnRmKGJ1ZiwgImhiYSVkIiwgYWRhcHRlci0+aG9zdC0+aG9zdF9ubyk7CgkJcmVtb3ZlX3Byb2NfZW50cnkoYnVmLCBtZWdhX3Byb2NfZGlyX2VudHJ5KTsKCX0KI2VuZGlmCgoJcGNpX2ZyZWVfY29uc2lzdGVudChhZGFwdGVyLT5kZXYsIE1FR0FfQlVGRkVSX1NJWkUsCgkJCWFkYXB0ZXItPm1lZ2FfYnVmZmVyLCBhZGFwdGVyLT5idWZfZG1hX2hhbmRsZSk7CglrZnJlZShhZGFwdGVyLT5zY2JfbGlzdCk7CglwY2lfZnJlZV9jb25zaXN0ZW50KGFkYXB0ZXItPmRldiwgc2l6ZW9mKG1ib3g2NF90KSwKCQkJYWRhcHRlci0+dW5hX21ib3g2NCwgYWRhcHRlci0+dW5hX21ib3g2NF9kbWEpOwoKCXNjc2lfaG9zdF9wdXQoaG9zdCk7CglwY2lfZGlzYWJsZV9kZXZpY2UocGRldik7CgoJaGJhX2NvdW50LS07Cn0KCnN0YXRpYyB2b2lkCm1lZ2FyYWlkX3NodXRkb3duKHN0cnVjdCBkZXZpY2UgKmRldikKewoJc3RydWN0IFNjc2lfSG9zdCAqaG9zdCA9IHBjaV9nZXRfZHJ2ZGF0YSh0b19wY2lfZGV2KGRldikpOwoJYWRhcHRlcl90ICphZGFwdGVyID0gKGFkYXB0ZXJfdCAqKWhvc3QtPmhvc3RkYXRhOwoKCV9fbWVnYXJhaWRfc2h1dGRvd24oYWRhcHRlcik7Cn0KCnN0YXRpYyBzdHJ1Y3QgcGNpX2RldmljZV9pZCBtZWdhcmFpZF9wY2lfdGJsW10gPSB7Cgl7UENJX1ZFTkRPUl9JRF9ERUxMLCBQQ0lfREVWSUNFX0lEX0RJU0NPVkVSWSwKCQlQQ0lfQU5ZX0lELCBQQ0lfQU5ZX0lELCAwLCAwLCAwfSwKCXtQQ0lfVkVORE9SX0lEX0RFTEwsIFBDSV9ERVZJQ0VfSURfUEVSQzRfREksCgkJUENJX0FOWV9JRCwgUENJX0FOWV9JRCwgMCwgMCwgQk9BUkRfNjRCSVR9LAoJe1BDSV9WRU5ET1JfSURfTFNJX0xPR0lDLCBQQ0lfREVWSUNFX0lEX1BFUkM0X1FDX1ZFUkRFLAoJCVBDSV9BTllfSUQsIFBDSV9BTllfSUQsIDAsIDAsIEJPQVJEXzY0QklUfSwKCXtQQ0lfVkVORE9SX0lEX0FNSSwgUENJX0RFVklDRV9JRF9BTUlfTUVHQVJBSUQsCgkJUENJX0FOWV9JRCwgUENJX0FOWV9JRCwgMCwgMCwgMH0sCgl7UENJX1ZFTkRPUl9JRF9BTUksIFBDSV9ERVZJQ0VfSURfQU1JX01FR0FSQUlEMiwKCQlQQ0lfQU5ZX0lELCBQQ0lfQU5ZX0lELCAwLCAwLCAwfSwKCXtQQ0lfVkVORE9SX0lEX0FNSSwgUENJX0RFVklDRV9JRF9BTUlfTUVHQVJBSUQzLAoJCVBDSV9BTllfSUQsIFBDSV9BTllfSUQsIDAsIDAsIDB9LAoJe1BDSV9WRU5ET1JfSURfSU5URUwsIFBDSV9ERVZJQ0VfSURfQU1JX01FR0FSQUlEMywKCQlQQ0lfQU5ZX0lELCBQQ0lfQU5ZX0lELCAwLCAwLCAwfSwKCXtQQ0lfVkVORE9SX0lEX0xTSV9MT0dJQywgUENJX0RFVklDRV9JRF9BTUlfTUVHQVJBSUQzLAoJCVBDSV9BTllfSUQsIFBDSV9BTllfSUQsIDAsIDAsIDB9LAoJezAsfQp9OwpNT0RVTEVfREVWSUNFX1RBQkxFKHBjaSwgbWVnYXJhaWRfcGNpX3RibCk7CgpzdGF0aWMgc3RydWN0IHBjaV9kcml2ZXIgbWVnYXJhaWRfcGNpX2RyaXZlciA9IHsKCS5uYW1lCQk9ICJtZWdhcmFpZCIsCgkuaWRfdGFibGUJPSBtZWdhcmFpZF9wY2lfdGJsLAoJLnByb2JlCQk9IG1lZ2FyYWlkX3Byb2JlX29uZSwKCS5yZW1vdmUJCT0gX19kZXZleGl0X3AobWVnYXJhaWRfcmVtb3ZlX29uZSksCgkuZHJpdmVyCQk9IHsKCQkuc2h1dGRvd24gPSBtZWdhcmFpZF9zaHV0ZG93biwKCX0sCn07CgpzdGF0aWMgaW50IF9faW5pdCBtZWdhcmFpZF9pbml0KHZvaWQpCnsKCWludCBlcnJvcjsKCglpZiAoKG1heF9jbWRfcGVyX2x1biA8PSAwKSB8fCAobWF4X2NtZF9wZXJfbHVuID4gTUFYX0NNRF9QRVJfTFVOKSkKCQltYXhfY21kX3Blcl9sdW4gPSBNQVhfQ01EX1BFUl9MVU47CglpZiAobWF4X21ib3hfYnVzeV93YWl0ID4gTUJPWF9CVVNZX1dBSVQpCgkJbWF4X21ib3hfYnVzeV93YWl0ID0gTUJPWF9CVVNZX1dBSVQ7CgojaWZkZWYgQ09ORklHX1BST0NfRlMKCW1lZ2FfcHJvY19kaXJfZW50cnkgPSBwcm9jX21rZGlyKCJtZWdhcmFpZCIsICZwcm9jX3Jvb3QpOwoJaWYgKCFtZWdhX3Byb2NfZGlyX2VudHJ5KSB7CgkJcHJpbnRrKEtFUk5fV0FSTklORwoJCQkJIm1lZ2FyYWlkOiBmYWlsZWQgdG8gY3JlYXRlIG1lZ2FyYWlkIHJvb3RcbiIpOwoJfQojZW5kaWYKCWVycm9yID0gcGNpX21vZHVsZV9pbml0KCZtZWdhcmFpZF9wY2lfZHJpdmVyKTsKCWlmIChlcnJvcikgewojaWZkZWYgQ09ORklHX1BST0NfRlMKCQlyZW1vdmVfcHJvY19lbnRyeSgibWVnYXJhaWQiLCAmcHJvY19yb290KTsKI2VuZGlmCgkJcmV0dXJuIGVycm9yOwoJfQoKCS8qCgkgKiBSZWdpc3RlciB0aGUgZHJpdmVyIGFzIGEgY2hhcmFjdGVyIGRldmljZSwgZm9yIGFwcGxpY2F0aW9ucwoJICogdG8gYWNjZXNzIGl0IGZvciBpb2N0bHMuCgkgKiBGaXJzdCBhcmd1bWVudCAobWFqb3IpIHRvIHJlZ2lzdGVyX2NocmRldiBpbXBsaWVzIGEgZHluYW1pYwoJICogbWFqb3IgbnVtYmVyIGFsbG9jYXRpb24uCgkgKi8KCW1ham9yID0gcmVnaXN0ZXJfY2hyZGV2KDAsICJtZWdhZGV2IiwgJm1lZ2FkZXZfZm9wcyk7CglpZiAoIW1ham9yKSB7CgkJcHJpbnRrKEtFUk5fV0FSTklORwoJCQkJIm1lZ2FyYWlkOiBmYWlsZWQgdG8gcmVnaXN0ZXIgY2hhciBkZXZpY2VcbiIpOwoJfQoKCXJldHVybiAwOwp9CgpzdGF0aWMgdm9pZCBfX2V4aXQgbWVnYXJhaWRfZXhpdCh2b2lkKQp7CgkvKgoJICogVW5yZWdpc3RlciB0aGUgY2hhcmFjdGVyIGRldmljZSBpbnRlcmZhY2UgdG8gdGhlIGRyaXZlci4KCSAqLwoJdW5yZWdpc3Rlcl9jaHJkZXYobWFqb3IsICJtZWdhZGV2Iik7CgoJcGNpX3VucmVnaXN0ZXJfZHJpdmVyKCZtZWdhcmFpZF9wY2lfZHJpdmVyKTsKCiNpZmRlZiBDT05GSUdfUFJPQ19GUwoJcmVtb3ZlX3Byb2NfZW50cnkoIm1lZ2FyYWlkIiwgJnByb2Nfcm9vdCk7CiNlbmRpZgp9Cgptb2R1bGVfaW5pdChtZWdhcmFpZF9pbml0KTsKbW9kdWxlX2V4aXQobWVnYXJhaWRfZXhpdCk7CgovKiB2aTogc2V0IHRzPTggc3c9OCB0dz03ODogKi8K