X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=gdb%2Fm32r-linux-tdep.c;h=4c088ec0dee2b2b79ad850e4886dd04a669086c9;hb=e3ecd631339aaa2a4af57f59f0694671d4ce00ab;hp=7d18c12a775235430ca16c6d0df8a7a0bd35d93e;hpb=197e01b6dcd118b70ed3621b62b2ff3fa929d50f;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/m32r-linux-tdep.c b/gdb/m32r-linux-tdep.c index 7d18c12a77..4c088ec0de 100644 --- a/gdb/m32r-linux-tdep.c +++ b/gdb/m32r-linux-tdep.c @@ -1,12 +1,12 @@ /* Target-dependent code for GNU/Linux m32r. - Copyright (C) 2004 Free Software Foundation, Inc. + Copyright (C) 2004-2019 Free Software Foundation, Inc. This file is part of GDB. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -15,9 +15,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. */ + along with this program. If not, see . */ #include "defs.h" #include "gdbcore.h" @@ -29,15 +27,16 @@ #include "reggroups.h" #include "regset.h" -#include "gdb_string.h" - #include "glibc-tdep.h" #include "solib-svr4.h" +#include "symtab.h" #include "trad-frame.h" #include "frame-unwind.h" #include "m32r-tdep.h" +#include "linux-tdep.h" + /* Recognizing signal handler frames. */ @@ -85,7 +84,7 @@ static const gdb_byte linux_sigtramp_code[] = { the routine. Otherwise, return 0. */ static CORE_ADDR -m32r_linux_sigtramp_start (CORE_ADDR pc, struct frame_info *next_frame) +m32r_linux_sigtramp_start (CORE_ADDR pc, struct frame_info *this_frame) { gdb_byte buf[4]; @@ -99,7 +98,7 @@ m32r_linux_sigtramp_start (CORE_ADDR pc, struct frame_info *next_frame) if (pc % 2 != 0) { - if (!safe_frame_unwind_memory (next_frame, pc, buf, 2)) + if (!safe_frame_unwind_memory (this_frame, pc, buf, 2)) return 0; if (memcmp (buf, linux_sigtramp_code, 2) == 0) @@ -108,7 +107,7 @@ m32r_linux_sigtramp_start (CORE_ADDR pc, struct frame_info *next_frame) return 0; } - if (!safe_frame_unwind_memory (next_frame, pc, buf, 4)) + if (!safe_frame_unwind_memory (this_frame, pc, buf, 4)) return 0; if (memcmp (buf, linux_sigtramp_code, 4) != 0) @@ -133,7 +132,7 @@ static const gdb_byte linux_rt_sigtramp_code[] = { of the routine. Otherwise, return 0. */ static CORE_ADDR -m32r_linux_rt_sigtramp_start (CORE_ADDR pc, struct frame_info *next_frame) +m32r_linux_rt_sigtramp_start (CORE_ADDR pc, struct frame_info *this_frame) { gdb_byte buf[4]; @@ -148,12 +147,12 @@ m32r_linux_rt_sigtramp_start (CORE_ADDR pc, struct frame_info *next_frame) if (pc % 2 != 0) return 0; - if (!safe_frame_unwind_memory (next_frame, pc, buf, 4)) + if (!safe_frame_unwind_memory (this_frame, pc, buf, 4)) return 0; if (memcmp (buf, linux_rt_sigtramp_code, 4) == 0) { - if (!safe_frame_unwind_memory (next_frame, pc + 4, buf, 4)) + if (!safe_frame_unwind_memory (this_frame, pc + 4, buf, 4)) return 0; if (memcmp (buf, linux_rt_sigtramp_code + 4, 4) == 0) @@ -161,7 +160,7 @@ m32r_linux_rt_sigtramp_start (CORE_ADDR pc, struct frame_info *next_frame) } else if (memcmp (buf, linux_rt_sigtramp_code + 4, 4) == 0) { - if (!safe_frame_unwind_memory (next_frame, pc - 4, buf, 4)) + if (!safe_frame_unwind_memory (this_frame, pc - 4, buf, 4)) return 0; if (memcmp (buf, linux_rt_sigtramp_code, 4) == 0) @@ -172,8 +171,8 @@ m32r_linux_rt_sigtramp_start (CORE_ADDR pc, struct frame_info *next_frame) } static int -m32r_linux_pc_in_sigtramp (CORE_ADDR pc, char *name, - struct frame_info *next_frame) +m32r_linux_pc_in_sigtramp (CORE_ADDR pc, const char *name, + struct frame_info *this_frame) { /* If we have NAME, we can optimize the search. The trampolines are named __restore and __restore_rt. However, they aren't dynamically @@ -181,8 +180,8 @@ m32r_linux_pc_in_sigtramp (CORE_ADDR pc, char *name, be part of the preceding function. This should always be sigaction, __sigaction, or __libc_sigaction (all aliases to the same function). */ if (name == NULL || strstr (name, "sigaction") != NULL) - return (m32r_linux_sigtramp_start (pc, next_frame) != 0 - || m32r_linux_rt_sigtramp_start (pc, next_frame) != 0); + return (m32r_linux_sigtramp_start (pc, this_frame) != 0 + || m32r_linux_rt_sigtramp_start (pc, this_frame) != 0); return (strcmp ("__restore", name) == 0 || strcmp ("__restore_rt", name) == 0); @@ -223,7 +222,7 @@ struct m32r_frame_cache }; static struct m32r_frame_cache * -m32r_linux_sigtramp_frame_cache (struct frame_info *next_frame, +m32r_linux_sigtramp_frame_cache (struct frame_info *this_frame, void **this_cache) { struct m32r_frame_cache *cache; @@ -231,29 +230,29 @@ m32r_linux_sigtramp_frame_cache (struct frame_info *next_frame, int regnum; if ((*this_cache) != NULL) - return (*this_cache); + return (struct m32r_frame_cache *) (*this_cache); cache = FRAME_OBSTACK_ZALLOC (struct m32r_frame_cache); (*this_cache) = cache; - cache->saved_regs = trad_frame_alloc_saved_regs (next_frame); + cache->saved_regs = trad_frame_alloc_saved_regs (this_frame); - cache->base = frame_unwind_register_unsigned (next_frame, M32R_SP_REGNUM); + cache->base = get_frame_register_unsigned (this_frame, M32R_SP_REGNUM); sigcontext_addr = cache->base + 4; - cache->pc = frame_pc_unwind (next_frame); - addr = m32r_linux_sigtramp_start (cache->pc, next_frame); + cache->pc = get_frame_pc (this_frame); + addr = m32r_linux_sigtramp_start (cache->pc, this_frame); if (addr == 0) { /* If this is a RT signal trampoline, adjust SIGCONTEXT_ADDR accordingly. */ - addr = m32r_linux_rt_sigtramp_start (cache->pc, next_frame); + addr = m32r_linux_rt_sigtramp_start (cache->pc, this_frame); if (addr) sigcontext_addr += 128; else - addr = frame_func_unwind (next_frame); + addr = get_frame_func (this_frame); } cache->pc = addr; - cache->saved_regs = trad_frame_alloc_saved_regs (next_frame); + cache->saved_regs = trad_frame_alloc_saved_regs (this_frame); for (regnum = 0; regnum < sizeof (m32r_linux_sc_reg_offset) / 4; regnum++) { @@ -266,50 +265,50 @@ m32r_linux_sigtramp_frame_cache (struct frame_info *next_frame, } static void -m32r_linux_sigtramp_frame_this_id (struct frame_info *next_frame, +m32r_linux_sigtramp_frame_this_id (struct frame_info *this_frame, void **this_cache, struct frame_id *this_id) { struct m32r_frame_cache *cache = - m32r_linux_sigtramp_frame_cache (next_frame, this_cache); + m32r_linux_sigtramp_frame_cache (this_frame, this_cache); (*this_id) = frame_id_build (cache->base, cache->pc); } -static void -m32r_linux_sigtramp_frame_prev_register (struct frame_info *next_frame, - void **this_cache, - int regnum, int *optimizedp, - enum lval_type *lvalp, - CORE_ADDR *addrp, - int *realnump, gdb_byte *valuep) +static struct value * +m32r_linux_sigtramp_frame_prev_register (struct frame_info *this_frame, + void **this_cache, int regnum) { struct m32r_frame_cache *cache = - m32r_linux_sigtramp_frame_cache (next_frame, this_cache); + m32r_linux_sigtramp_frame_cache (this_frame, this_cache); - trad_frame_get_prev_register (next_frame, cache->saved_regs, regnum, - optimizedp, lvalp, addrp, realnump, valuep); + return trad_frame_get_prev_register (this_frame, cache->saved_regs, regnum); } -static const struct frame_unwind m32r_linux_sigtramp_frame_unwind = { - SIGTRAMP_FRAME, - m32r_linux_sigtramp_frame_this_id, - m32r_linux_sigtramp_frame_prev_register -}; - -static const struct frame_unwind * -m32r_linux_sigtramp_frame_sniffer (struct frame_info *next_frame) +static int +m32r_linux_sigtramp_frame_sniffer (const struct frame_unwind *self, + struct frame_info *this_frame, + void **this_cache) { - CORE_ADDR pc = frame_pc_unwind (next_frame); - char *name; + CORE_ADDR pc = get_frame_pc (this_frame); + const char *name; find_pc_partial_function (pc, &name, NULL, NULL); - if (m32r_linux_pc_in_sigtramp (pc, name, next_frame)) - return &m32r_linux_sigtramp_frame_unwind; + if (m32r_linux_pc_in_sigtramp (pc, name, this_frame)) + return 1; - return NULL; + return 0; } +static const struct frame_unwind m32r_linux_sigtramp_frame_unwind = { + SIGTRAMP_FRAME, + default_frame_unwind_stop_reason, + m32r_linux_sigtramp_frame_this_id, + m32r_linux_sigtramp_frame_prev_register, + NULL, + m32r_linux_sigtramp_frame_sniffer +}; + /* Mapping between the registers in `struct pt_regs' format and GDB's register array layout. */ @@ -345,19 +344,26 @@ static int m32r_pt_regs_offset[] = { #define SPU_OFFSET (4 * 23) #define SPI_OFFSET (4 * 26) +#define M32R_LINUX_GREGS_SIZE (4 * 28) + static void m32r_linux_supply_gregset (const struct regset *regset, struct regcache *regcache, int regnum, const void *gregs, size_t size) { - const char *regs = gregs; - unsigned long psw, bbpsw; + const gdb_byte *regs = (const gdb_byte *) gregs; + enum bfd_endian byte_order = + gdbarch_byte_order (regcache->arch ()); + ULONGEST psw, bbpsw; + gdb_byte buf[4]; + const gdb_byte *p; int i; - psw = *((unsigned long *) (regs + PSW_OFFSET)); - bbpsw = *((unsigned long *) (regs + BBPSW_OFFSET)); + psw = extract_unsigned_integer (regs + PSW_OFFSET, 4, byte_order); + bbpsw = extract_unsigned_integer (regs + BBPSW_OFFSET, 4, byte_order); + psw = ((0x00c1 & bbpsw) << 8) | ((0xc100 & psw) >> 8); - for (i = 0; i < sizeof (m32r_pt_regs_offset) / 4; i++) + for (i = 0; i < ARRAY_SIZE (m32r_pt_regs_offset); i++) { if (regnum != -1 && regnum != i) continue; @@ -365,69 +371,105 @@ m32r_linux_supply_gregset (const struct regset *regset, switch (i) { case PSW_REGNUM: - *((unsigned long *) (regs + m32r_pt_regs_offset[i])) = - ((0x00c1 & bbpsw) << 8) | ((0xc100 & psw) >> 8); + store_unsigned_integer (buf, 4, byte_order, psw); + p = buf; break; case CBR_REGNUM: - *((unsigned long *) (regs + m32r_pt_regs_offset[i])) = - ((psw >> 8) & 1); + store_unsigned_integer (buf, 4, byte_order, psw & 1); + p = buf; break; case M32R_SP_REGNUM: - if (psw & 0x8000) - *((unsigned long *) (regs + m32r_pt_regs_offset[i])) = - *((unsigned long *) (regs + SPU_OFFSET)); - else - *((unsigned long *) (regs + m32r_pt_regs_offset[i])) = - *((unsigned long *) (regs + SPI_OFFSET)); + p = regs + ((psw & 0x80) ? SPU_OFFSET : SPI_OFFSET); break; + default: + p = regs + m32r_pt_regs_offset[i]; } - regcache_raw_supply (current_regcache, i, - regs + m32r_pt_regs_offset[i]); + regcache->raw_supply (i, p); + } +} + +static void +m32r_linux_collect_gregset (const struct regset *regset, + const struct regcache *regcache, + int regnum, void *gregs, size_t size) +{ + gdb_byte *regs = (gdb_byte *) gregs; + int i; + enum bfd_endian byte_order = + gdbarch_byte_order (regcache->arch ()); + ULONGEST psw; + gdb_byte buf[4]; + + regcache->raw_collect (PSW_REGNUM, buf); + psw = extract_unsigned_integer (buf, 4, byte_order); + + for (i = 0; i < ARRAY_SIZE (m32r_pt_regs_offset); i++) + { + if (regnum != -1 && regnum != i) + continue; + + switch (i) + { + case PSW_REGNUM: + store_unsigned_integer (regs + PSW_OFFSET, 4, byte_order, + (psw & 0xc1) << 8); + store_unsigned_integer (regs + BBPSW_OFFSET, 4, byte_order, + (psw >> 8) & 0xc1); + break; + case CBR_REGNUM: + break; + case M32R_SP_REGNUM: + regcache->raw_collect + (i, regs + ((psw & 0x80) ? SPU_OFFSET : SPI_OFFSET)); + break; + default: + regcache->raw_collect (i, regs + m32r_pt_regs_offset[i]); + } } } -static struct regset m32r_linux_gregset = { - NULL, m32r_linux_supply_gregset +static const struct regset m32r_linux_gregset = { + NULL, + m32r_linux_supply_gregset, m32r_linux_collect_gregset }; -static const struct regset * -m32r_linux_regset_from_core_section (struct gdbarch *core_arch, - const char *sect_name, size_t sect_size) +static void +m32r_linux_iterate_over_regset_sections (struct gdbarch *gdbarch, + iterate_over_regset_sections_cb *cb, + void *cb_data, + const struct regcache *regcache) { - struct gdbarch_tdep *tdep = gdbarch_tdep (core_arch); - if (strcmp (sect_name, ".reg") == 0) - return &m32r_linux_gregset; - return NULL; + cb (".reg", M32R_LINUX_GREGS_SIZE, M32R_LINUX_GREGS_SIZE, &m32r_linux_gregset, + NULL, cb_data); } static void m32r_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) { - struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + + linux_init_abi (info, gdbarch); /* Since EVB register is not available for native debug, we reduce the number of registers. */ set_gdbarch_num_regs (gdbarch, M32R_NUM_REGS - 1); - frame_unwind_append_sniffer (gdbarch, m32r_linux_sigtramp_frame_sniffer); + frame_unwind_append_unwinder (gdbarch, &m32r_linux_sigtramp_frame_unwind); /* GNU/Linux uses SVR4-style shared libraries. */ + set_gdbarch_skip_trampoline_code (gdbarch, find_solib_trampoline_target); set_solib_svr4_fetch_link_map_offsets (gdbarch, svr4_ilp32_fetch_link_map_offsets); /* Core file support. */ - set_gdbarch_regset_from_core_section - (gdbarch, m32r_linux_regset_from_core_section); + set_gdbarch_iterate_over_regset_sections + (gdbarch, m32r_linux_iterate_over_regset_sections); /* Enable TLS support. */ set_gdbarch_fetch_tls_load_module_address (gdbarch, svr4_fetch_objfile_link_map); } -/* Provide a prototype to silence -Wmissing-prototypes. */ -extern void _initialize_m32r_linux_tdep (void); - void _initialize_m32r_linux_tdep (void) {