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



Reviewed-by: Felipe Huici <felipe.huici@xxxxxxxxx>

On Tue, Mar 31, 2020 at 11:50 PM Simon Kuenzer <simon.kuenzer@xxxxxxxxx> 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__ */
> --
> 2.20.1
>
>
> _______________________________________________
> Minios-devel mailing list
> Minios-devel@xxxxxxxxxxxxxxxxxxxx
> https://lists.xenproject.org/mailman/listinfo/minios-devel

_______________________________________________
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®.