|
[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 |