[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [UNIKRAFT PATCH] lib/ukdebug: uk_asmndumpd(), uk_asmndumpk()
Introduces uk_asmndumpd() and uk_asmndumpk(). They are a variant of uk_asmdumpd() and uk_asmdumpk(). However, they take the number of bytes instead of number of instructions as argument for the decoding range. Signed-off-by: Simon Kuenzer <simon.kuenzer@xxxxxxxxx> --- lib/ukdebug/asmdump.c | 74 ++++++++++++++++++++++++++++++++ lib/ukdebug/exportsyms.uk | 2 + lib/ukdebug/include/uk/asmdump.h | 35 +++++++++++++++ 3 files changed, 111 insertions(+) diff --git a/lib/ukdebug/asmdump.c b/lib/ukdebug/asmdump.c index 7f992930..8001ca0c 100644 --- a/lib/ukdebug/asmdump.c +++ b/lib/ukdebug/asmdump.c @@ -91,6 +91,60 @@ static int _asmdump(struct out_dev *o, return total; } + +/** + * Disassemble <len> bytes with zydis starting + * with instruction at <instr> + */ +static int _asmndump(struct out_dev *o, + const void *instr, size_t len) +{ + ZydisDecoder dcr; + ZydisFormatter fmt; + ZydisDecodedInstruction ins; + char buf[128]; + int offset = 0; + int ret, total = 0; + __uptr addr = (__uptr) instr; + +#if __X86_32__ + if (!ZYAN_SUCCESS(ZydisDecoderInit(&dcr, + ZYDIS_MACHINE_MODE_LONG_COMPAT_32, + ZYDIS_ADDRESS_WIDTH_32))) + return -1; +#elif __X86_64__ + if (!ZYAN_SUCCESS(ZydisDecoderInit(&dcr, + ZYDIS_MACHINE_MODE_LONG_64, + ZYDIS_ADDRESS_WIDTH_64))) + return -1; +#else +#error libzydis: Unsupported architecture +#endif + + if (!ZYAN_SUCCESS(ZydisFormatterInit(&fmt, + ZYDIS_FORMATTER_STYLE_ATT))) + return -1; + + while (len) { + addr = ((__uptr) instr) + offset; + if (!ZYAN_SUCCESS(ZydisDecoderDecodeBuffer(&dcr, + (const void *) addr, + MIN(16u, len), + &ins))) + break; + ZydisFormatterFormatInstruction(&fmt, &ins, buf, sizeof(buf), + addr); + ret = outf(o, "%08"__PRIuptr" <+%d>: %hs\n", addr, offset, buf); + if (ret < 0) + return ret; + + total += ret; + offset += ins.length; + len -= ins.length; + } + + return total; +} #else /* CONFIG_LIBZYDIS */ #error No supported disassembler backend available. #endif /* CONFIG_LIBZYDIS */ @@ -105,6 +159,16 @@ void _uk_asmdumpd(const char *libname, const char *srcname, _asmdump(&o, instr, instr_count); } +void _uk_asmndumpd(const char *libname, const char *srcname, + unsigned int srcline, const void *instr, + size_t len) +{ + struct out_dev o; + + out_dev_init_debug(&o, libname, srcname, srcline); + _asmndump(&o, instr, len); +} + #if CONFIG_LIBUKDEBUG_PRINTK void _uk_asmdumpk(int lvl, const char *libname, const char *srcname, unsigned int srcline, @@ -115,4 +179,14 @@ void _uk_asmdumpk(int lvl, const char *libname, out_dev_init_kern(&o, lvl, libname, srcname, srcline); _asmdump(&o, instr, instr_count); } + +void _uk_asmndumpk(int lvl, const char *libname, + const char *srcname, unsigned int srcline, + const void *instr, size_t len) +{ + struct out_dev o; + + out_dev_init_kern(&o, lvl, libname, srcname, srcline); + _asmndump(&o, instr, len); +} #endif /* CONFIG_LIBUKDEBUG_PRINTK */ diff --git a/lib/ukdebug/exportsyms.uk b/lib/ukdebug/exportsyms.uk index f1e19900..6f001813 100644 --- a/lib/ukdebug/exportsyms.uk +++ b/lib/ukdebug/exportsyms.uk @@ -8,6 +8,8 @@ uk_hexdumpd _uk_hexdumpd _uk_hexdumpk _uk_asmdumpd +_uk_asmndumpd _uk_asmdumpk +_uk_asmndumpk uk_trace_buffer_free uk_trace_buffer_writep diff --git a/lib/ukdebug/include/uk/asmdump.h b/lib/ukdebug/include/uk/asmdump.h index a0468810..0bbefe0b 100644 --- a/lib/ukdebug/include/uk/asmdump.h +++ b/lib/ukdebug/include/uk/asmdump.h @@ -81,10 +81,22 @@ void _uk_asmdumpd(const char *libname, const char *srcname, #define uk_asmdumpd(instr, instr_count) \ _uk_asmdumpd(__STR_LIBNAME__, __STR_BASENAME__, \ __LINE__, (instr), (instr_count)) + +void _uk_asmndumpd(const char *libname, const char *srcname, + unsigned int srcline, const void *instr, + size_t len); + +#define uk_asmndumpd(instr, len) \ + _uk_asmndumpd(__STR_LIBNAME__, __STR_BASENAME__, \ + __LINE__, (instr), (len)) #else /* (defined UK_DEBUG) || CONFIG_LIBUKDEBUG_PRINTD */ static inline void uk_asmdumpd(const void *instr __unused, unsigned int instr_count __unused) {} + +static inline void uk_asmndumpd(const void *instr __unused, + size_t len __unused) +{} #endif #if CONFIG_LIBUKDEBUG_PRINTK @@ -99,10 +111,25 @@ void _uk_asmdumpk(int lvl, const char *libname, const char *srcname, _uk_asmdumpk((lvl), __STR_LIBNAME__, __STR_BASENAME__, \ __LINE__, (instr), (instr_count)); \ } while (0) + +void _uk_asmndumpk(int lvl, const char *libname, const char *srcname, + unsigned int srcline, const void *instr, + size_t len); + +#define uk_asmndumpk(lvl, instr, len) \ + do { \ + if ((lvl) <= KLVL_MAX) \ + _uk_asmdumpk((lvl), __STR_LIBNAME__, __STR_BASENAME__, \ + __LINE__, (instr), (len)); \ + } while (0) #else /* CONFIG_LIBUKDEBUG_PRINTK */ static inline void uk_asmdumpk(int lvl __unused, const void *instr __unused, unsigned int instr_count __unused) {} + +static inline void uk_asmndumpk(int lvl __unused, const void *instr __unused, + size_t len __unused) +{} #endif /* CONFIG_LIBUKDEBUG_PRINTK */ #else /* Backends */ @@ -114,10 +141,18 @@ static inline void uk_asmdumpd(const void *instr __unused, unsigned int instr_count __unused) {} +static inline void uk_asmndumpd(const void *instr __unused, + size_t len __unused) +{} + #if CONFIG_LIBUKDEBUG_PRINTK static inline void uk_asmdumpk(int lvl __unused, const void *instr __unused, unsigned int instr_count __unused) {} + +static inline void uk_asmndumpk(int lvl __unused, const void *instr __unused, + size_t len __unused) +{} #endif /* CONFIG_LIBUKDEBUG_PRINTK */ #endif /* Backends */ -- 2.20.1
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |