[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Minios-devel] [UNIKRAFT PATCH 2/3] lib/ukdebug: Provide uk_asmdumpd(), uk_asmdumpk()



I am sorry, this got sent wrongly. Please ignore.

Simon

On 31.03.20 23:37, Simon Kuenzer wrote:
This commit introduces `uk_asmdumpd()` and `uk_asmdumpk()`. These
methods print for a given instruction address the disassembled
representation to the DEBUG or KERN output. The calls are
automatically removed from the code when there is no supported
disassembler library available. This commit includes support for
libzydis.

Signed-off-by: Simon Kuenzer <simon.kuenzer@xxxxxxxxx>
---
  lib/ukdebug/Makefile.uk          |   1 +
  lib/ukdebug/asmdump.c            | 117 ++++++++++++++++++++++++++++
  lib/ukdebug/exportsyms.uk        |   2 +
  lib/ukdebug/include/uk/asmdump.h | 129 +++++++++++++++++++++++++++++++
  4 files changed, 249 insertions(+)
  create mode 100644 lib/ukdebug/asmdump.c
  create mode 100644 lib/ukdebug/include/uk/asmdump.h

diff --git a/lib/ukdebug/Makefile.uk b/lib/ukdebug/Makefile.uk
index 6b3acf7a..f06eeb87 100644
--- a/lib/ukdebug/Makefile.uk
+++ b/lib/ukdebug/Makefile.uk
@@ -10,6 +10,7 @@ LIBUKDEBUG_SRCS-y += $(LIBUKDEBUG_BASE)/print.c
  LIBUKDEBUG_SRCS-$(CONFIG_HAVE_LIBC) += $(LIBUKDEBUG_BASE)/snprintf.c
  LIBUKDEBUG_SRCS-y += $(LIBUKDEBUG_BASE)/outf.c
  LIBUKDEBUG_SRCS-y += $(LIBUKDEBUG_BASE)/hexdump.c
+LIBUKDEBUG_SRCS-$(CONFIG_LIBZYDIS) += $(LIBUKDEBUG_BASE)/asmdump.c
  LIBUKDEBUG_SRCS-$(CONFIG_LIBUKDEBUG_TRACEPOINTS) += $(LIBUKDEBUG_BASE)/trace.c
  LIBUKDEBUG_SRCS-$(CONFIG_LIBVFSCORE) += $(LIBUKDEBUG_BASE)/extra.ld
diff --git a/lib/ukdebug/asmdump.c b/lib/ukdebug/asmdump.c
new file mode 100644
index 00000000..f73b0d65
--- /dev/null
+++ b/lib/ukdebug/asmdump.c
@@ -0,0 +1,117 @@
+/* SPDX-License-Identifier: BSD-3-Clause */
+/*
+ * Dump disassembler output to kern/debug console
+ *
+ * Authors: Simon Kuenzer <simon.kuenzer@xxxxxxxxx>
+ *
+ *
+ * Copyright (c) 2020, NEC Europe Ltd., NEC Corporation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holder nor the names of its
+ *    contributors may be used to endorse or promote products derived from
+ *    this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <uk/asmdump.h>
+#include <uk/assert.h>
+#include <errno.h>
+#include "outf.h"
+
+#if CONFIG_LIBZYDIS
+#include <Zydis/Zydis.h>
+
+/**
+ * Disassemble <num_ins> instructions with zydis starting
+ * with instruction at <addr>
+ */
+static int _asmdump(struct out_dev *o,
+                  const void *instr, unsigned int count)
+{
+       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 (count) {
+               addr = ((__uptr) instr) + offset;
+               ZydisDecoderDecodeBuffer(&dcr, (const void *) addr, 16, &ins);
+               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;
+               count--;
+       }
+
+       return total;
+}
+#else /* CONFIG_LIBZYDIS */
+#error No supported disassembler backend available.
+#endif /* CONFIG_LIBZYDIS */
+
+void _uk_asmdumpd(const char *libname, const char *srcname,
+                 unsigned int srcline, const void *instr,
+                 unsigned int instr_count)
+{
+       struct out_dev o;
+
+       out_dev_init_debug(&o, libname, srcname, srcline);
+       _asmdump(&o, instr, instr_count);
+}
+
+#if CONFIG_LIBUKDEBUG_PRINTK
+void _uk_asmdumpk(int lvl, const char *libname,
+                 const char *srcname, unsigned int srcline,
+                 const void *instr, unsigned int instr_count)
+{
+       struct out_dev o;
+
+       out_dev_init_kern(&o, lvl, libname, srcname, srcline);
+       _asmdump(&o, instr, instr_count);
+}
+#endif /* CONFIG_LIBUKDEBUG_PRINTK */
diff --git a/lib/ukdebug/exportsyms.uk b/lib/ukdebug/exportsyms.uk
index 9763768f..f1e19900 100644
--- a/lib/ukdebug/exportsyms.uk
+++ b/lib/ukdebug/exportsyms.uk
@@ -7,5 +7,7 @@ uk_hexdumpf
  uk_hexdumpd
  _uk_hexdumpd
  _uk_hexdumpk
+_uk_asmdumpd
+_uk_asmdumpk
  uk_trace_buffer_free
  uk_trace_buffer_writep
diff --git a/lib/ukdebug/include/uk/asmdump.h b/lib/ukdebug/include/uk/asmdump.h
new file mode 100644
index 00000000..a0468810
--- /dev/null
+++ b/lib/ukdebug/include/uk/asmdump.h
@@ -0,0 +1,129 @@
+/* SPDX-License-Identifier: BSD-3-Clause */
+/*
+ * Dump disassembler output to kern/debug console
+ *
+ * Authors: Simon Kuenzer <simon.kuenzer@xxxxxxxxx>
+ *
+ *
+ * Copyright (c) 2020, NEC Europe Ltd., NEC Corporation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holder nor the names of its
+ *    contributors may be used to endorse or promote products derived from
+ *    this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __UKDEBUG_ASMDUMP__
+#define __UKDEBUG_ASMDUMP__
+
+/**
+ * NOTE: Please note, this file defines only variants that print disassembler
+ *       output to the KERN and DEBUG console: uk_asmdumpd(), ukasmdumpk().
+ *       They are intended for debugging purpose only because the calls get
+ *       removed if there is no supported disassembler backend available
+ *       (e.g., libzydis).
+ */
+
+#include <stdio.h>
+#include <uk/print.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * The following block is only enabled if supported backends are available.
+ * TODO: In order to add support for another backend library, extend this
+ *       #if-condition and implement a printing handler (_asmdump())
+ *       in `asmdump.c`
+ */
+#if CONFIG_LIBZYDIS
+
+#ifdef __IN_LIBUKDEBUG__
+/*
+ * This redefinition of CONFIG_LIBUKDEBUG_PRINTD is doing the trick to
+ * switch on the correct declaration of uk_hexdumpd() when we are compiling
+ * this library and have the global debug switch CONFIG_LIBUKDEBUG_PRINTD
+ * not enabled.
+ */
+#if !defined CONFIG_LIBUKDEBUG_PRINTD || !CONFIG_LIBUKDEBUG_PRINTD
+#undef CONFIG_LIBUKDEBUG_PRINTD
+#define CONFIG_LIBUKDEBUG_PRINTD 1
+#endif
+#endif /* __IN_LIBUKDEBUG__ */
+
+#if (defined UK_DEBUG) || CONFIG_LIBUKDEBUG_PRINTD
+/* Please use uk_asmdumpd() instead */
+void _uk_asmdumpd(const char *libname, const char *srcname,
+                 unsigned int srcline, const void *instr,
+                 unsigned int instr_count);
+
+#define uk_asmdumpd(instr, instr_count)                                        
\
+       _uk_asmdumpd(__STR_LIBNAME__, __STR_BASENAME__,                 \
+                    __LINE__, (instr), (instr_count))
+#else /* (defined UK_DEBUG) || CONFIG_LIBUKDEBUG_PRINTD */
+static inline void uk_asmdumpd(const void *instr __unused,
+                             unsigned int instr_count __unused)
+{}
+#endif
+
+#if CONFIG_LIBUKDEBUG_PRINTK
+/* Please use uk_asmdumpk() instead */
+void _uk_asmdumpk(int lvl, const char *libname, const char *srcname,
+                unsigned int srcline, const void *instr,
+                unsigned int instr_count);
+
+#define uk_asmdumpk(lvl, instr, instr_count)                           \
+       do {                                                            \
+               if ((lvl) <= KLVL_MAX)                                  \
+                       _uk_asmdumpk((lvl), __STR_LIBNAME__, __STR_BASENAME__, \
+                                    __LINE__, (instr), (instr_count)); \
+       } while (0)
+#else /* CONFIG_LIBUKDEBUG_PRINTK */
+static inline void uk_asmdumpk(int lvl __unused, const void *instr __unused,
+                             unsigned int instr_count __unused)
+{}
+#endif /* CONFIG_LIBUKDEBUG_PRINTK */
+
+#else /* Backends */
+/*
+ * In case there is no supported backend, we remove the asmdump(d|k)
+ * calls from the code:
+ */
+static inline void uk_asmdumpd(const void *instr __unused,
+                              unsigned int instr_count __unused)
+{}
+
+#if CONFIG_LIBUKDEBUG_PRINTK
+static inline void uk_asmdumpk(int lvl __unused, const void *instr __unused,
+                              unsigned int instr_count __unused)
+{}
+#endif /* CONFIG_LIBUKDEBUG_PRINTK */
+
+#endif /* Backends */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __UKDEBUG_ASMDUMP__ */


_______________________________________________
Minios-devel mailing list
Minios-devel@xxxxxxxxxxxxxxxxxxxx
https://lists.xenproject.org/mailman/listinfo/minios-devel

 


Rackspace

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