X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=gdb%2Fm32r-linux-tdep.c;h=937a24b255280b840119fc5f3e025a0be1e795aa;hb=4e7b8beaa3b7b9ac8577b10afa9d58bb9d453b08;hp=5caf79b0137eb58d5b9584e9718f0e71ab08e69f;hpb=94afd7a6d348a66ea3fb35fdb8234b050ec8c779;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/m32r-linux-tdep.c b/gdb/m32r-linux-tdep.c index 5caf79b013..937a24b255 100644 --- a/gdb/m32r-linux-tdep.c +++ b/gdb/m32r-linux-tdep.c @@ -1,6 +1,6 @@ /* Target-dependent code for GNU/Linux m32r. - Copyright (C) 2004, 2007, 2008 Free Software Foundation, Inc. + Copyright (C) 2004-2016 Free Software Foundation, Inc. This file is part of GDB. @@ -27,8 +27,6 @@ #include "reggroups.h" #include "regset.h" -#include "gdb_string.h" - #include "glibc-tdep.h" #include "solib-svr4.h" #include "symtab.h" @@ -37,6 +35,8 @@ #include "frame-unwind.h" #include "m32r-tdep.h" +#include "linux-tdep.h" + /* Recognizing signal handler frames. */ @@ -171,7 +171,7 @@ m32r_linux_rt_sigtramp_start (CORE_ADDR pc, struct frame_info *this_frame) } static int -m32r_linux_pc_in_sigtramp (CORE_ADDR pc, char *name, +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 @@ -230,7 +230,7 @@ m32r_linux_sigtramp_frame_cache (struct frame_info *this_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 (this_frame); @@ -291,7 +291,7 @@ m32r_linux_sigtramp_frame_sniffer (const struct frame_unwind *self, void **this_cache) { CORE_ADDR pc = get_frame_pc (this_frame); - char *name; + const char *name; find_pc_partial_function (pc, &name, NULL, NULL); if (m32r_linux_pc_in_sigtramp (pc, name, this_frame)) @@ -302,6 +302,7 @@ m32r_linux_sigtramp_frame_sniffer (const struct frame_unwind *self, 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, @@ -343,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 (get_regcache_arch (regcache)); + 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; @@ -363,40 +371,77 @@ 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 (regcache, i, - regs + m32r_pt_regs_offset[i]); + regcache_raw_supply (regcache, i, p); } } -static struct regset m32r_linux_gregset = { - NULL, m32r_linux_supply_gregset +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 (get_regcache_arch (regcache)); + ULONGEST psw; + gdb_byte buf[4]; + + regcache_raw_collect (regcache, 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 (regcache, i, regs + + ((psw & 0x80) ? SPU_OFFSET : SPI_OFFSET)); + break; + default: + regcache_raw_collect (regcache, i, + regs + m32r_pt_regs_offset[i]); + } + } +} + +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_gregset, NULL, cb_data); } static void @@ -404,6 +449,8 @@ 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); @@ -416,8 +463,8 @@ m32r_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) (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,