[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




 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.