diff --git a/devel/gdb/Makefile b/devel/gdb/Makefile index 66abc21d8070..ce27f4e7b213 100644 --- a/devel/gdb/Makefile +++ b/devel/gdb/Makefile @@ -1,180 +1,180 @@ # Created by: Steven Kreuzer PORTNAME= gdb DISTVERSION= 11.1 -PORTREVISION= 1 +PORTREVISION= 2 CATEGORIES= devel MASTER_SITES= GNU MAINTAINER= pizzamig@FreeBSD.org COMMENT= GNU Project Debugger LICENSE= GPLv3 LICENSE_FILE= ${WRKSRC}/COPYING3 # untested on sparc64, might work NOT_FOR_ARCHS= sparc64 LIB_DEPENDS= libgmp.so:math/gmp \ libmpfr.so:math/mpfr TEST_DEPENDS= runtest:misc/dejagnu USES= compiler:c++11-lang cpe gmake libtool makeinfo pkgconfig tar:xz USE_PYTHON= flavors py3kplist TEST_TARGET= check CPE_VENDOR= gnu GNU_CONFIGURE= yes CONFIGURE_ENV= CONFIGURED_M4=m4 CONFIGURED_BISON=byacc CONFIGURE_ARGS= --program-suffix=${DISTVERSION:S/.//g} \ --enable-targets=all --enable-64-bit-bfd \ --with-separate-debug-dir=/usr/lib/debug \ ${ICONV_CONFIGURE_ARG} \ --with-expat=yes --with-libexpat-prefix=${LOCALBASE} \ --without-libunwind-ia64 --with-system-zlib CONFIGURE_OUTSOURCE= yes CFLAGS:= ${CFLAGS:C/ +$//} # blanks at EOL creep in sometimes CFLAGS+= -DRL_NO_COMPAT EXCLUDE= dejagnu expect sim texinfo intl EXTRACT_AFTER_ARGS= ${EXCLUDE:S/^/--exclude /} LIB_DEPENDS+= libexpat.so:textproc/expat2 VER= ${DISTVERSION:S/.//g} PLIST_SUB= VER=${VER} OPTIONS_DEFINE= DEBUG GDB_LINK GUILE KGDB NLS PYTHON SOURCE_HIGHLIGHT TUI OPTIONS_DEFAULT= GDB_LINK KGDB NLS PYTHON SOURCE_HIGHLIGHT TUI OPTIONS_DEFAULT+= PORT_READLINE PORT_ICONV SYSTEM_ZLIB OPTIONS_SINGLE= READLINE ICONV ZLIB OPTIONS_SINGLE_READLINE= BUNDLED_READLINE PORT_READLINE OPTIONS_SINGLE_ICONV= PORT_ICONV SYSTEM_ICONV OPTIONS_SINGLE_ZLIB= BUNDLED_ZLIB SYSTEM_ZLIB GDB_LINK_DESC= Create ${PREFIX}/bin/gdb symlink KGDB_DESC= Kernel Debugging Support BUNDLED_READLINE_DESC= from gdb distfile BUNDLED_ZLIB_DESC= from gdb distfile PORT_READLINE_DESC= from devel/readline port PORT_ICONV_DESC= use libiconv, with wider charset support SOURCE_HIGHLIGHT_DESC= Source Code Styling SYSTEM_ICONV_DESC= use libc iconv, with no wchar support SYSTEM_ZLIB_DESC= use system zlib TUI_DESC= Text User Interface enabled OPTIONS_SUB= yes BUNDLED_READLINE_CONFIGURE_OFF= --with-system-readline DEBUG_CFLAGS= -g DEBUG_VARS= STRIP= GUILE_CONFIGURE_WITH= guile GUILE_LIB_DEPENDS= libguile-2.2.so:lang/guile2 NLS_USES= gettext-runtime PORT_READLINE_USES= readline PORT_ICONV_USES= iconv:wchar_t PYTHON_CONFIGURE_ON= --with-python=${PYTHON_CMD} PYTHON_CONFIGURE_OFF= --without-python PYTHON_USES= python:3.6+ SOURCE_HIGHLIGHT_WITH= source-highlight SOURCE_HIGHLIGHT_LIB_DEPENDS= \ libsource-highlight.so:textproc/source-highlight SYSTEM_ICONV_USES= iconv SYSTEM_ZLIB_WITH= system-zlib TUI_CONFIGURE_ENABLE= tui .include .if ${PORT_OPTIONS:MPYTHON} .if ${PYTHON_VER} != ${PYTHON_DEFAULT} PKGNAMESUFFIX= ${PYTHON_PKGNAMESUFFIX} .endif .endif .if ${PORT_OPTIONS:MPYTHON} && exists(/usr/lib/libc++.so.1) USE_GITHUB= nodefault GH_ACCOUNT= bsdjhb:libcxx GH_PROJECT= libcxx-gdbpy:libcxx GH_TAGNAME= 03d0d9b:libcxx # Workaround USE_GITHUB preventing the default DISTFILES DISTFILES= ${DISTNAME}${EXTRACT_SUFX} PLIST_SUB+= LIBCXX="" .else PLIST_SUB+= LIBCXX="@comment " .endif .if ! ${PORT_OPTIONS:MBUNDLED_ZLIB} EXCLUDE+= zlib .endif .if ${ARCH} == amd64 CONFIGURE_TARGET= x86_64-portbld-freebsd${OSREL} .endif .if ${CHOSEN_COMPILER_TYPE} == clang CFLAGS+= -Wno-extended-offsetof .endif post-patch: @${REINPLACE_CMD} -e 's|$$| [GDB v${DISTVERSION} for FreeBSD]|' \ ${WRKSRC}/gdb/version.in post-patch-KGDB-on: @${CP} -r ${FILESDIR}/kgdb/*.[ch] ${WRKSRC}/gdb/ @${PATCH} -d ${PATCH_WRKSRC} ${PATCH_ARGS} < ${FILESDIR}/extrapatch-kgdb do-install: ${INSTALL_PROGRAM} ${INSTALL_WRKSRC}/gdb/gdb \ ${STAGEDIR}${PREFIX}/bin/gdb${VER} ${INSTALL_MAN} ${WRKSRC}/gdb/doc/gdb.1 \ ${STAGEDIR}${MAN1PREFIX}/man/man1/gdb${VER}.1 (cd ${INSTALL_WRKSRC}/gdb/data-directory ; \ ${SETENV} ${MAKE_ENV} ${MAKE_CMD} ${MAKE_ARGS} install-syscalls ) do-install-KGDB-on: ${INSTALL_PROGRAM} ${INSTALL_WRKSRC}/gdb/kgdb \ ${STAGEDIR}${PREFIX}/bin/kgdb${VER} ${INSTALL_MAN} ${FILESDIR}/kgdb/kgdb.1 \ ${STAGEDIR}${MAN1PREFIX}/man/man1/kgdb${VER}.1 do-install-TUI-on: ${LN} -sf gdb${VER} ${STAGEDIR}${PREFIX}/bin/gdbtui${VER} do-install-GDB_LINK-on: ${LN} -sf gdb${VER} ${STAGEDIR}${PREFIX}/bin/gdb ${LN} -sf gdb${VER}.1 ${STAGEDIR}${MAN1PREFIX}/man/man1/gdb.1 .if ${PORT_OPTIONS:MKGDB} ${LN} -sf kgdb${VER} ${STAGEDIR}${PREFIX}/bin/kgdb ${LN} -sf kgdb${VER}.1 ${STAGEDIR}${MAN1PREFIX}/man/man1/kgdb.1 .endif do-install-PYTHON-on: (cd ${INSTALL_WRKSRC}/gdb ; \ ${SETENV} ${MAKE_ENV} ${MAKE_CMD} ${MAKE_ARGS} install-python ) (cd ${INSTALL_WRKSRC}/gdb/data-directory ; \ ${SETENV} ${MAKE_ENV} ${MAKE_CMD} ${MAKE_ARGS} install-python ) @(cd ${STAGEDIR}${PREFIX}/share/gdb/python && \ ${PYTHON_CMD} -m compileall .) . for f in gdb gdb/command gdb/function gdb/printer @(cd ${STAGEDIR}${PREFIX}/share/gdb/python/${f} ; ${CHMOD} 644 *.py* ) . endfor .if exists(/usr/lib/libc++.so.1) @(cd ${WRKSRC_libcxx} ; \ ${SETENV} ${MAKE_ENV} ${MAKE} ${MAKE_ARGS} install ) @(cd ${STAGEDIR}${PREFIX}/share/gdb/auto-load/usr/lib && \ ${PYTHON_CMD} -m compileall .) @(cd ${STAGEDIR}${PREFIX}/share/libcxx-gdbpy/libcxx && \ ${PYTHON_CMD} -m compileall .) .endif do-install-GUILE-on: (cd ${INSTALL_WRKSRC}/gdb ; \ ${SETENV} ${MAKE_ENV} ${MAKE_CMD} ${MAKE_ARGS} install-guile ) (cd ${INSTALL_WRKSRC}/gdb/data-directory ; \ ${SETENV} ${MAKE_ENV} ${MAKE_CMD} ${MAKE_ARGS} install-guile ) .include diff --git a/devel/gdb/files/kgdb/aarch64-fbsd-kern.c b/devel/gdb/files/kgdb/aarch64-fbsd-kern.c index 8c0bac8dfc0b..6cdbb66397b0 100644 --- a/devel/gdb/files/kgdb/aarch64-fbsd-kern.c +++ b/devel/gdb/files/kgdb/aarch64-fbsd-kern.c @@ -1,199 +1,199 @@ /*- * Copyright (c) 2017 John Baldwin * 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. * * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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 AUTHORS 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. */ /* Target-dependent code for FreeBSD/aarch64 kernels. */ #include "defs.h" #include "aarch64-tdep.h" #include "frame-unwind.h" #include "gdbarch.h" #include "gdbcore.h" #include "osabi.h" #include "regcache.h" #include "regset.h" #include "solib.h" #include "target.h" #include "trad-frame.h" #include "kgdb.h" static const struct regcache_map_entry aarch64_fbsd_pcbmap[] = { { 30, AARCH64_X0_REGNUM, 8 }, /* x0 ... x29 */ { 1, AARCH64_PC_REGNUM, 8 }, { 1, REGCACHE_MAP_SKIP, 8 }, { 1, AARCH64_SP_REGNUM, 8 }, { 0 } }; static const struct regset aarch64_fbsd_pcbregset = { aarch64_fbsd_pcbmap, regcache_supply_regset, regcache_collect_regset }; static void aarch64_fbsd_supply_pcb(struct regcache *regcache, CORE_ADDR pcb_addr) { gdb_byte buf[8 * 33]; if (target_read_memory (pcb_addr, buf, sizeof buf) == 0) regcache_supply_regset (&aarch64_fbsd_pcbregset, regcache, -1, buf, sizeof (buf)); } static struct trad_frame_cache * aarch64_fbsd_trapframe_cache (struct frame_info *this_frame, void **this_cache) { struct gdbarch *gdbarch = get_frame_arch (this_frame); enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); struct trad_frame_cache *cache; CORE_ADDR func, pc, sp; const char *name; int i; if (*this_cache != NULL) return ((struct trad_frame_cache *)*this_cache); cache = trad_frame_cache_zalloc (this_frame); *this_cache = cache; func = get_frame_func (this_frame); sp = get_frame_register_unsigned (this_frame, AARCH64_SP_REGNUM); find_pc_partial_function (func, &name, NULL, NULL); if (strcmp(name, "fork_trampoline") == 0 && get_frame_pc (this_frame) == func) { /* fork_exit hasn't been called (kthread has never run), so SP hasn't been initialized yet. The stack pointer is stored in the X2 in the pcb. */ sp = get_frame_register_unsigned (this_frame, AARCH64_X0_REGNUM + 2); } trad_frame_set_reg_addr (cache, AARCH64_SP_REGNUM, sp); trad_frame_set_reg_addr (cache, AARCH64_LR_REGNUM, sp + 8); trad_frame_set_reg_addr (cache, AARCH64_PC_REGNUM, sp + 16); trad_frame_set_reg_addr (cache, AARCH64_CPSR_REGNUM, sp + 24); for (i = 0; i < 30; i++) trad_frame_set_reg_addr (cache, AARCH64_X0_REGNUM + i, sp + 32 + i * 8); /* Read $PC from trap frame. */ pc = read_memory_unsigned_integer (sp + 16, 8, byte_order); if (pc == 0 && strcmp(name, "fork_trampoline") == 0) { /* Initial frame of a kthread; terminate backtrace. */ trad_frame_set_id (cache, outer_frame_id); } else { /* Construct the frame ID using the function start. */ trad_frame_set_id (cache, frame_id_build (sp + 8 * 34, func)); } return cache; } static void aarch64_fbsd_trapframe_this_id (struct frame_info *this_frame, void **this_cache, struct frame_id *this_id) { struct trad_frame_cache *cache = aarch64_fbsd_trapframe_cache (this_frame, this_cache); trad_frame_get_id (cache, this_id); } static struct value * aarch64_fbsd_trapframe_prev_register (struct frame_info *this_frame, void **this_cache, int regnum) { struct trad_frame_cache *cache = aarch64_fbsd_trapframe_cache (this_frame, this_cache); return trad_frame_get_register (cache, this_frame, regnum); } static int aarch64_fbsd_trapframe_sniffer (const struct frame_unwind *self, struct frame_info *this_frame, void **this_prologue_cache) { const char *name; find_pc_partial_function (get_frame_func (this_frame), &name, NULL, NULL); return (name && ((strcmp (name, "handle_el1h_sync") == 0) || (strcmp (name, "handle_el1h_irq") == 0) || (strcmp (name, "handle_el0_sync") == 0) || (strcmp (name, "handle_el0_irq") == 0) || (strcmp (name, "handle_el0_error") == 0) || (strcmp (name, "fork_trampoline") == 0))); } static const struct frame_unwind aarch64_fbsd_trapframe_unwind = { "aarch64 FreeBSD kernel trap", SIGTRAMP_FRAME, default_frame_unwind_stop_reason, aarch64_fbsd_trapframe_this_id, aarch64_fbsd_trapframe_prev_register, NULL, aarch64_fbsd_trapframe_sniffer }; /* Implement the 'init_osabi' method of struct gdb_osabi_handler. */ static void aarch64_fbsd_kernel_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) { struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); frame_unwind_prepend_unwinder (gdbarch, &aarch64_fbsd_trapframe_unwind); set_solib_ops (gdbarch, &kld_so_ops); /* Enable longjmp. */ tdep->jb_pc = 13; fbsd_vmcore_set_supply_pcb (gdbarch, aarch64_fbsd_supply_pcb); fbsd_vmcore_set_cpu_pcb_addr (gdbarch, kgdb_trgt_stop_pcb); /* The kernel is linked at a virtual address with the upper 4 bits set, so all 64 bits of virtual addresses need to be treated as significant. */ set_gdbarch_significant_addr_bit (gdbarch, 64); } void _initialize_aarch64_kgdb_tdep (); void -_initialize_aarch64_kgdb_tdep () +_initialize_aarch64_kgdb_tdep () { gdbarch_register_osabi_sniffer(bfd_arch_aarch64, bfd_target_elf_flavour, fbsd_kernel_osabi_sniffer); gdbarch_register_osabi (bfd_arch_aarch64, 0, GDB_OSABI_FREEBSD_KERNEL, aarch64_fbsd_kernel_init_abi); } diff --git a/devel/gdb/files/kgdb/arm-fbsd-kern.c b/devel/gdb/files/kgdb/arm-fbsd-kern.c index 4ae80313dbc3..552c3a95a257 100644 --- a/devel/gdb/files/kgdb/arm-fbsd-kern.c +++ b/devel/gdb/files/kgdb/arm-fbsd-kern.c @@ -1,211 +1,211 @@ /*- * Copyright (c) 2018 John Baldwin * 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. * * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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 AUTHORS 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. */ /* Target-dependent code for FreeBSD/arm kernels. */ #include "defs.h" #include "arm-tdep.h" #include "frame-unwind.h" #include "gdbcore.h" #include "osabi.h" #include "regcache.h" #include "regset.h" #include "solib.h" #include "target.h" #include "trad-frame.h" #include "kgdb.h" static const struct regcache_map_entry arm_fbsd_pcbmap[] = { { 9, 4, 4 }, /* r4 ... r12 */ { 1, ARM_SP_REGNUM, 4 }, { 1, ARM_LR_REGNUM, 4 }, { 1, ARM_PC_REGNUM, 4 }, { 0 } }; static const struct regset arm_fbsd_pcbregset = { arm_fbsd_pcbmap, regcache_supply_regset, regcache_collect_regset }; static void arm_fbsd_supply_pcb(struct regcache *regcache, CORE_ADDR pcb_addr) { gdb_byte buf[4 * 12]; if (target_read_memory (pcb_addr, buf, sizeof buf) == 0) regcache->supply_regset (&arm_fbsd_pcbregset, -1, buf, sizeof (buf)); /* * XXX: This is a gross hack, but the ARM frame unwinders need the value * of xPSR to determine if Thumb mode is active. FreeBSD's kernels never * use Thumb. */ regcache->raw_supply_unsigned(ARM_PS_REGNUM, 0); } #define PSR_MODE 0x0000001f /* mode mask */ #define PSR_USR32_MODE 0x00000010 static struct trad_frame_cache * arm_fbsd_trapframe_cache (struct frame_info *this_frame, void **this_cache) { struct gdbarch *gdbarch = get_frame_arch (this_frame); enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); struct trad_frame_cache *cache; uint32_t psr; CORE_ADDR func, pc, sp; const char *name; int i; if (*this_cache != NULL) return ((struct trad_frame_cache *)*this_cache); cache = trad_frame_cache_zalloc (this_frame); *this_cache = cache; func = get_frame_func (this_frame); sp = get_frame_register_unsigned (this_frame, ARM_SP_REGNUM); find_pc_partial_function (func, &name, NULL, NULL); /* Read $PSR to determine where SP and LR are. */ psr = read_memory_unsigned_integer (sp, 4, byte_order); for (i = 0; i <= 12; i++) trad_frame_set_reg_addr (cache, ARM_A1_REGNUM + i, sp + 4 + i * 4); if ((psr & PSR_MODE) == PSR_USR32_MODE) { trad_frame_set_reg_addr (cache, ARM_SP_REGNUM, sp + 14 * 4); trad_frame_set_reg_addr (cache, ARM_LR_REGNUM, sp + 15 * 4); } else { trad_frame_set_reg_addr (cache, ARM_SP_REGNUM, sp + 16 * 4); trad_frame_set_reg_addr (cache, ARM_LR_REGNUM, sp + 17 * 4); } trad_frame_set_reg_addr (cache, ARM_PC_REGNUM, sp + 18 * 4); trad_frame_set_reg_addr (cache, ARM_PS_REGNUM, sp); /* Read $PC from trap frame. */ pc = read_memory_unsigned_integer (sp + 18 * 4, 4, byte_order); if (pc == 0 && strcmp(name, "swi_entry") == 0) { /* Initial frame of a kthread; terminate backtrace. */ trad_frame_set_id (cache, outer_frame_id); } else { /* Construct the frame ID using the function start. */ trad_frame_set_id (cache, frame_id_build (sp + 4 * 19, func)); } return cache; } static void arm_fbsd_trapframe_this_id (struct frame_info *this_frame, void **this_cache, struct frame_id *this_id) { struct trad_frame_cache *cache = arm_fbsd_trapframe_cache (this_frame, this_cache); trad_frame_get_id (cache, this_id); } static struct value * arm_fbsd_trapframe_prev_register (struct frame_info *this_frame, void **this_cache, int regnum) { struct trad_frame_cache *cache = arm_fbsd_trapframe_cache (this_frame, this_cache); return trad_frame_get_register (cache, this_frame, regnum); } static int arm_fbsd_trapframe_sniffer (const struct frame_unwind *self, struct frame_info *this_frame, void **this_prologue_cache) { const char *name; find_pc_partial_function (get_frame_func (this_frame), &name, NULL, NULL); return (name && ((strcmp (name, "data_abort_entry") == 0) || (strcmp (name, "prefetch_abort_entry") == 0) || (strcmp (name, "undefined_entry") == 0) || (strcmp (name, "exception_exit") == 0) || (strcmp (name, "irq_entry") == 0) || (strcmp (name, "swi_entry") == 0) || (strcmp (name, "swi_exit") == 0))); } static const struct frame_unwind arm_fbsd_trapframe_unwind = { "arm FreeBSD kernel trap", SIGTRAMP_FRAME, default_frame_unwind_stop_reason, arm_fbsd_trapframe_this_id, arm_fbsd_trapframe_prev_register, NULL, arm_fbsd_trapframe_sniffer }; /* Implement the 'init_osabi' method of struct gdb_osabi_handler. */ static void arm_fbsd_kernel_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) { struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); frame_unwind_prepend_unwinder (gdbarch, &arm_fbsd_trapframe_unwind); set_solib_ops (gdbarch, &kld_so_ops); tdep->jb_pc = 24; tdep->jb_elt_size = 4; fbsd_vmcore_set_supply_pcb (gdbarch, arm_fbsd_supply_pcb); fbsd_vmcore_set_cpu_pcb_addr (gdbarch, kgdb_trgt_stop_pcb); /* Single stepping. */ set_gdbarch_software_single_step (gdbarch, arm_software_single_step); } void _initialize_arm_kgdb_tdep (); void -_initialize_arm_kgdb_tdep () +_initialize_arm_kgdb_tdep () { gdbarch_register_osabi_sniffer(bfd_arch_arm, bfd_target_elf_flavour, fbsd_kernel_osabi_sniffer); gdbarch_register_osabi (bfd_arch_arm, 0, GDB_OSABI_FREEBSD_KERNEL, arm_fbsd_kernel_init_abi); } diff --git a/devel/gdb/files/kgdb/mipsfbsd-kern.c b/devel/gdb/files/kgdb/mipsfbsd-kern.c index 78c9c44a2ca4..303473e543c5 100644 --- a/devel/gdb/files/kgdb/mipsfbsd-kern.c +++ b/devel/gdb/files/kgdb/mipsfbsd-kern.c @@ -1,294 +1,294 @@ /* * Copyright (c) 2007 Juniper Networks, Inc. * Copyright (c) 2004 Marcel Moolenaar * 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. * * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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 AUTHORS 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 "defs.h" #include "frame-unwind.h" #include "osabi.h" #include "regcache.h" #include "solib.h" #include "trad-frame.h" #include "mips-tdep.h" #ifdef __mips__ #include #include #include #endif #include "kgdb.h" /* Size of struct trapframe in registers. */ #define TRAPFRAME_WORDS 74 /* From sys/mips/include/pcb.h. Offsets in the pcb_context[] array. */ #define FBSD_PCB_REG_S0 0 #define FBSD_PCB_REG_S1 1 #define FBSD_PCB_REG_S2 2 #define FBSD_PCB_REG_S3 3 #define FBSD_PCB_REG_S4 4 #define FBSD_PCB_REG_S5 5 #define FBSD_PCB_REG_S6 6 #define FBSD_PCB_REG_S7 7 #define FBSD_PCB_REG_SP 8 #define FBSD_PCB_REG_S8 9 #define FBSD_PCB_REG_RA 10 #define FBSD_PCB_REG_SR 11 #define FBSD_PCB_REG_GP 12 #define FBSD_PCB_REG_PC 13 #ifdef __mips__ _Static_assert(TRAPFRAME_WORDS * sizeof(register_t) == sizeof(struct trapframe), "TRAPFRAME_WORDS mismatch"); _Static_assert(FBSD_PCB_REG_S0 == PCB_REG_S0, "PCB_REG_S0 mismatch"); _Static_assert(FBSD_PCB_REG_S1 == PCB_REG_S1, "PCB_REG_S1 mismatch"); _Static_assert(FBSD_PCB_REG_S2 == PCB_REG_S2, "PCB_REG_S2 mismatch"); _Static_assert(FBSD_PCB_REG_S3 == PCB_REG_S3, "PCB_REG_S3 mismatch"); _Static_assert(FBSD_PCB_REG_S4 == PCB_REG_S4, "PCB_REG_S4 mismatch"); _Static_assert(FBSD_PCB_REG_S5 == PCB_REG_S5, "PCB_REG_S5 mismatch"); _Static_assert(FBSD_PCB_REG_S6 == PCB_REG_S6, "PCB_REG_S6 mismatch"); _Static_assert(FBSD_PCB_REG_S7 == PCB_REG_S7, "PCB_REG_S7 mismatch"); _Static_assert(FBSD_PCB_REG_SP == PCB_REG_SP, "PCB_REG_SP mismatch"); _Static_assert(FBSD_PCB_REG_S8 == PCB_REG_S8, "PCB_REG_S8 mismatch"); _Static_assert(FBSD_PCB_REG_RA == PCB_REG_RA, "PCB_REG_RA mismatch"); _Static_assert(FBSD_PCB_REG_SR == PCB_REG_SR, "PCB_REG_SR mismatch"); _Static_assert(FBSD_PCB_REG_GP == PCB_REG_GP, "PCB_REG_GP mismatch"); _Static_assert(FBSD_PCB_REG_PC == PCB_REG_PC, "PCB_REG_PC mismatch"); #endif static void mipsfbsd_supply_pcb(struct regcache *regcache, CORE_ADDR pcb_addr) { struct gdbarch *gdbarch = regcache->arch (); size_t regsize = mips_isa_regsize (gdbarch); gdb_byte buf[regsize * (FBSD_PCB_REG_PC + 1)]; /* Read the entire pcb_context[] array in one go. The pcb_context[] array is after the pcb_regs member which is a trapframe. */ if (target_read_memory (pcb_addr + TRAPFRAME_WORDS * regsize, buf, sizeof(buf)) != 0) return; regcache->raw_supply_unsigned (MIPS_ZERO_REGNUM, 0); regcache->raw_supply (MIPS_S2_REGNUM - 2, buf + (regsize * FBSD_PCB_REG_S0)); regcache->raw_supply (MIPS_S2_REGNUM - 1, buf + (regsize * FBSD_PCB_REG_S1)); regcache->raw_supply (MIPS_S2_REGNUM, buf + (regsize * FBSD_PCB_REG_S2)); regcache->raw_supply (MIPS_S2_REGNUM + 1, buf + (regsize * FBSD_PCB_REG_S3)); regcache->raw_supply (MIPS_S2_REGNUM + 2, buf + (regsize * FBSD_PCB_REG_S4)); regcache->raw_supply (MIPS_S2_REGNUM + 3, buf + (regsize * FBSD_PCB_REG_S5)); regcache->raw_supply (MIPS_S2_REGNUM + 4, buf + (regsize * FBSD_PCB_REG_S6)); regcache->raw_supply (MIPS_S2_REGNUM + 5, buf + (regsize * FBSD_PCB_REG_S7)); regcache->raw_supply (MIPS_SP_REGNUM, buf + (regsize * FBSD_PCB_REG_SP)); regcache->raw_supply (MIPS_S2_REGNUM + 6, buf + (regsize * FBSD_PCB_REG_S8)); regcache->raw_supply (MIPS_RA_REGNUM, buf + (regsize * FBSD_PCB_REG_RA)); regcache->raw_supply (MIPS_PS_REGNUM, buf + (regsize * FBSD_PCB_REG_SR)); regcache->raw_supply (MIPS_GP_REGNUM, buf + (regsize * FBSD_PCB_REG_GP)); regcache->raw_supply (MIPS_EMBED_PC_REGNUM, buf + (regsize * FBSD_PCB_REG_PC)); } static struct trad_frame_cache * mipsfbsd_trapframe_cache (struct frame_info *this_frame, void **this_cache) { struct gdbarch *gdbarch = get_frame_arch (this_frame); size_t regsize = mips_isa_regsize (gdbarch); struct trad_frame_cache *cache; CORE_ADDR addr, func, sp; int regnum; if (*this_cache != NULL) return ((struct trad_frame_cache *)*this_cache); cache = trad_frame_cache_zalloc (this_frame); *this_cache = cache; func = get_frame_func (this_frame); sp = get_frame_register_signed (this_frame, MIPS_SP_REGNUM + gdbarch_num_regs (gdbarch)); /* Skip over CALLFRAME_SIZ. */ addr = sp; if (regsize == 8) addr += regsize * 4; else addr += regsize * (4 + 2); /* GPRs. Skip zero. */ addr += regsize; for (regnum = MIPS_AT_REGNUM; regnum <= MIPS_RA_REGNUM; regnum++) { trad_frame_set_reg_addr (cache, regnum + gdbarch_num_regs (gdbarch), addr); addr += regsize; } regnum = MIPS_PS_REGNUM; trad_frame_set_reg_addr (cache, regnum + gdbarch_num_regs (gdbarch), addr); addr += regsize; /* HI and LO. */ regnum = mips_regnum (gdbarch)->lo; trad_frame_set_reg_addr (cache, regnum + gdbarch_num_regs (gdbarch), addr); addr += regsize; regnum = mips_regnum (gdbarch)->hi; trad_frame_set_reg_addr (cache, regnum + gdbarch_num_regs (gdbarch), addr); addr += regsize; /* BADVADDR. */ regnum = mips_regnum (gdbarch)->badvaddr; trad_frame_set_reg_addr (cache, regnum + gdbarch_num_regs (gdbarch), addr); addr += regsize; /* CAUSE. */ regnum = mips_regnum (gdbarch)->cause; trad_frame_set_reg_addr (cache, regnum + gdbarch_num_regs (gdbarch), addr); addr += regsize; /* PC. */ regnum = mips_regnum (gdbarch)->pc; trad_frame_set_reg_addr (cache, regnum + gdbarch_num_regs (gdbarch), addr); trad_frame_set_id (cache, frame_id_build (sp + TRAPFRAME_WORDS * regsize, func)); return cache; } static void mipsfbsd_trapframe_this_id (struct frame_info *this_frame, void **this_cache, struct frame_id *this_id) { struct trad_frame_cache *cache = mipsfbsd_trapframe_cache (this_frame, this_cache); trad_frame_get_id (cache, this_id); } static struct value * mipsfbsd_trapframe_prev_register (struct frame_info *this_frame, void **this_cache, int regnum) { struct trad_frame_cache *cache = mipsfbsd_trapframe_cache (this_frame, this_cache); return trad_frame_get_register (cache, this_frame, regnum); } static int mipsfbsd_trapframe_sniffer (const struct frame_unwind *self, struct frame_info *this_frame, void **this_prologue_cache) { const char *name; find_pc_partial_function (get_frame_func (this_frame), &name, NULL, NULL); return (name && ((strcmp(name, "MipsKernIntr") == 0) || (strcmp(name, "MipsKernGenException") == 0) || (strcmp(name, "MipsTLBInvalidException") == 0))); } static const struct frame_unwind mipsfbsd_trapframe_unwind = { "mips FreeBSD kernel trap", SIGTRAMP_FRAME, default_frame_unwind_stop_reason, mipsfbsd_trapframe_this_id, mipsfbsd_trapframe_prev_register, NULL, mipsfbsd_trapframe_sniffer }; static void mipsfbsd_kernel_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) { enum mips_abi abi = mips_abi (gdbarch); set_gdbarch_software_single_step (gdbarch, mips_software_single_step); switch (abi) { case MIPS_ABI_O32: break; case MIPS_ABI_N32: set_gdbarch_long_double_bit (gdbarch, 128); /* These floatformats should probably be renamed. MIPS uses the same 128-bit IEEE floating point format that IA-64 uses, except that the quiet/signalling NaN bit is reversed (GDB does not distinguish between quiet and signalling NaNs). */ set_gdbarch_long_double_format (gdbarch, floatformats_ia64_quad); break; case MIPS_ABI_N64: set_gdbarch_long_double_bit (gdbarch, 128); /* These floatformats should probably be renamed. MIPS uses the same 128-bit IEEE floating point format that IA-64 uses, except that the quiet/signalling NaN bit is reversed (GDB does not distinguish between quiet and signalling NaNs). */ set_gdbarch_long_double_format (gdbarch, floatformats_ia64_quad); break; } frame_unwind_prepend_unwinder (gdbarch, &mipsfbsd_trapframe_unwind); set_solib_ops (gdbarch, &kld_so_ops); fbsd_vmcore_set_supply_pcb (gdbarch, mipsfbsd_supply_pcb); fbsd_vmcore_set_cpu_pcb_addr (gdbarch, kgdb_trgt_stop_pcb); } void _initialize_mips_kgdb_tdep (); void -_initialize_mips_kgdb_tdep () +_initialize_mips_kgdb_tdep () { gdbarch_register_osabi_sniffer(bfd_arch_mips, bfd_target_elf_flavour, fbsd_kernel_osabi_sniffer); gdbarch_register_osabi (bfd_arch_mips, 0, GDB_OSABI_FREEBSD_KERNEL, mipsfbsd_kernel_init_abi); } diff --git a/devel/gdb/files/kgdb/riscv-fbsd-kern.c b/devel/gdb/files/kgdb/riscv-fbsd-kern.c index 5d648fd0db83..ebdead34c2b4 100644 --- a/devel/gdb/files/kgdb/riscv-fbsd-kern.c +++ b/devel/gdb/files/kgdb/riscv-fbsd-kern.c @@ -1,205 +1,205 @@ /*- * Copyright (c) 2018 John Baldwin * 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. * * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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 AUTHORS 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. */ /* Target-dependent code for FreeBSD/riscv64 kernels. */ #include "defs.h" #include "riscv-tdep.h" #include "frame-unwind.h" #include "gdbarch.h" #include "gdbcore.h" #include "osabi.h" #include "regcache.h" #include "regset.h" #include "solib.h" #include "target.h" #include "trad-frame.h" #include "kgdb.h" static const struct regcache_map_entry riscv_fbsd_pcbmap[] = { { 1, RISCV_RA_REGNUM, 0 }, { 1, RISCV_SP_REGNUM, 0 }, { 1, RISCV_GP_REGNUM, 0 }, { 1, RISCV_TP_REGNUM, 0 }, { 2, RISCV_FP_REGNUM, 0 }, /* s0 - s1 */ { 10, 18, 0 }, /* s2 - s11 */ { 0 } }; static const struct regset riscv_fbsd_pcbregset = { riscv_fbsd_pcbmap, regcache_supply_regset, regcache_collect_regset }; static void riscv_fbsd_supply_pcb(struct regcache *regcache, CORE_ADDR pcb_addr) { gdb_byte buf[16 * riscv_abi_xlen (regcache->arch ())]; /* Always give a value for PC in case the PCB isn't readable. */ regcache->raw_supply_zeroed (RISCV_PC_REGNUM); regcache->raw_supply_zeroed (RISCV_ZERO_REGNUM); if (target_read_memory (pcb_addr, buf, sizeof buf) == 0) { regcache->supply_regset (&riscv_fbsd_pcbregset, -1, buf, sizeof (buf)); /* Supply the RA as PC as well to simulate the PC as if the thread had just returned. */ regcache->raw_supply (RISCV_PC_REGNUM, buf); } } static const struct regcache_map_entry riscv_fbsd_tfmap[] = { { 1, RISCV_RA_REGNUM, 0 }, { 1, RISCV_SP_REGNUM, 0 }, { 1, RISCV_GP_REGNUM, 0 }, { 1, RISCV_TP_REGNUM, 0 }, { 3, 5, 0 }, /* t0 - t2 */ { 4, 28, 0 }, /* t3 - t6 */ { 2, RISCV_FP_REGNUM, 0 }, /* s0 - s1 */ { 10, 18, 0 }, /* s2 - s11 */ { 8, RISCV_A0_REGNUM, 0 }, /* a0 - a7 */ { 1, RISCV_PC_REGNUM, 0 }, { 1, RISCV_CSR_SSTATUS_REGNUM, 0 }, { 1, RISCV_CSR_STVAL_REGNUM, 0 }, { 1, RISCV_CSR_SCAUSE_REGNUM, 0 }, { 0 } }; static struct trad_frame_cache * riscv_fbsd_trapframe_cache (struct frame_info *this_frame, void **this_cache) { struct gdbarch *gdbarch = get_frame_arch (this_frame); enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); struct trad_frame_cache *cache; CORE_ADDR func, pc, sp; const char *name; int xlen; if (*this_cache != NULL) return ((struct trad_frame_cache *)*this_cache); cache = trad_frame_cache_zalloc (this_frame); *this_cache = cache; sp = get_frame_register_unsigned (this_frame, RISCV_SP_REGNUM); xlen = riscv_isa_xlen (gdbarch); trad_frame_set_reg_regmap (cache, riscv_fbsd_tfmap, sp, 35 * xlen); /* Read $PC from trap frame. */ func = get_frame_func (this_frame); find_pc_partial_function (func, &name, NULL, NULL); pc = read_memory_unsigned_integer (sp + 31 * xlen, xlen, byte_order); if (pc == 0 && strcmp(name, "fork_trampoline") == 0) { /* Initial frame of a kthread; terminate backtrace. */ trad_frame_set_id (cache, outer_frame_id); } else { /* Construct the frame ID using the function start. */ trad_frame_set_id (cache, frame_id_build (sp + 35 * xlen, func)); } return cache; } static void riscv_fbsd_trapframe_this_id (struct frame_info *this_frame, void **this_cache, struct frame_id *this_id) { struct trad_frame_cache *cache = riscv_fbsd_trapframe_cache (this_frame, this_cache); trad_frame_get_id (cache, this_id); } static struct value * riscv_fbsd_trapframe_prev_register (struct frame_info *this_frame, void **this_cache, int regnum) { struct trad_frame_cache *cache = riscv_fbsd_trapframe_cache (this_frame, this_cache); return trad_frame_get_register (cache, this_frame, regnum); } static int riscv_fbsd_trapframe_sniffer (const struct frame_unwind *self, struct frame_info *this_frame, void **this_prologue_cache) { const char *name; find_pc_partial_function (get_frame_func (this_frame), &name, NULL, NULL); return (name != NULL && ((strcmp (name, "cpu_exception_handler_user") == 0) || (strcmp (name, "cpu_exception_handler_supervisor") == 0))); } static const struct frame_unwind riscv_fbsd_trapframe_unwind = { "riscv FreeBSD kernel trap", SIGTRAMP_FRAME, default_frame_unwind_stop_reason, riscv_fbsd_trapframe_this_id, riscv_fbsd_trapframe_prev_register, NULL, riscv_fbsd_trapframe_sniffer }; /* Implement the 'init_osabi' method of struct gdb_osabi_handler. */ static void riscv_fbsd_kernel_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) { frame_unwind_prepend_unwinder (gdbarch, &riscv_fbsd_trapframe_unwind); set_solib_ops (gdbarch, &kld_so_ops); set_gdbarch_software_single_step (gdbarch, riscv_software_single_step); fbsd_vmcore_set_supply_pcb (gdbarch, riscv_fbsd_supply_pcb); fbsd_vmcore_set_cpu_pcb_addr (gdbarch, kgdb_trgt_stop_pcb); } void _initialize_riscv_kgdb_tdep (); void -_initialize_riscv_kgdb_tdep () +_initialize_riscv_kgdb_tdep () { gdbarch_register_osabi_sniffer(bfd_arch_riscv, bfd_target_elf_flavour, fbsd_kernel_osabi_sniffer); gdbarch_register_osabi (bfd_arch_riscv, 0, GDB_OSABI_FREEBSD_KERNEL, riscv_fbsd_kernel_init_abi); }