diff options
Diffstat (limited to 'gdb/mips-linux-tdep.c')
-rw-r--r-- | gdb/mips-linux-tdep.c | 153 |
1 files changed, 114 insertions, 39 deletions
diff --git a/gdb/mips-linux-tdep.c b/gdb/mips-linux-tdep.c index 6d0e7f6..8fe9a71 100644 --- a/gdb/mips-linux-tdep.c +++ b/gdb/mips-linux-tdep.c @@ -36,6 +36,7 @@ #include "solist.h" #include "symtab.h" #include "target-descriptions.h" +#include "regset.h" #include "mips-linux-tdep.h" #include "glibc-tdep.h" #include "linux-tdep.h" @@ -127,6 +128,16 @@ mips_supply_gregset (struct regcache *regcache, regcache_raw_supply (regcache, regi, zerobuf); } +static void +mips_supply_gregset_wrapper (const struct regset *regset, + struct regcache *regcache, + int regnum, const void *gregs, size_t len) +{ + gdb_assert (len == sizeof (mips_elf_gregset_t)); + + mips_supply_gregset (regcache, (const mips_elf_gregset_t *)gregs); +} + /* Pack our registers (or one register) into an elf_gregset_t. */ void @@ -185,6 +196,16 @@ mips_fill_gregset (const struct regcache *regcache, } } +static void +mips_fill_gregset_wrapper (const struct regset *regset, + const struct regcache *regcache, + int regnum, void *gregs, size_t len) +{ + gdb_assert (len == sizeof (mips_elf_gregset_t)); + + mips_fill_gregset (regcache, (mips_elf_gregset_t *)gregs, regnum); +} + /* Likewise, unpack an elf_fpregset_t. */ void @@ -212,6 +233,16 @@ mips_supply_fpregset (struct regcache *regcache, zerobuf); } +static void +mips_supply_fpregset_wrapper (const struct regset *regset, + struct regcache *regcache, + int regnum, const void *gregs, size_t len) +{ + gdb_assert (len == sizeof (mips_elf_fpregset_t)); + + mips_supply_fpregset (regcache, (const mips_elf_fpregset_t *)gregs); +} + /* Likewise, pack one or all floating point registers into an elf_fpregset_t. */ @@ -245,6 +276,16 @@ mips_fill_fpregset (const struct regcache *regcache, } } +static void +mips_fill_fpregset_wrapper (const struct regset *regset, + const struct regcache *regcache, + int regnum, void *gregs, size_t len) +{ + gdb_assert (len == sizeof (mips_elf_fpregset_t)); + + mips_fill_fpregset (regcache, (mips_elf_fpregset_t *)gregs, regnum); +} + /* Support for 64-bit ABIs. */ /* Figure out where the longjmp will land. @@ -342,6 +383,16 @@ mips64_supply_gregset (struct regcache *regcache, regcache_raw_supply (regcache, regi, zerobuf); } +static void +mips64_supply_gregset_wrapper (const struct regset *regset, + struct regcache *regcache, + int regnum, const void *gregs, size_t len) +{ + gdb_assert (len == sizeof (mips64_elf_gregset_t)); + + mips64_supply_gregset (regcache, (const mips64_elf_gregset_t *)gregs); +} + /* Pack our registers (or one register) into a 64-bit elf_gregset_t. */ void @@ -402,6 +453,16 @@ mips64_fill_gregset (const struct regcache *regcache, } } +static void +mips64_fill_gregset_wrapper (const struct regset *regset, + const struct regcache *regcache, + int regnum, void *gregs, size_t len) +{ + gdb_assert (len == sizeof (mips64_elf_gregset_t)); + + mips64_fill_gregset (regcache, (mips64_elf_gregset_t *)gregs, regnum); +} + /* Likewise, unpack an elf_fpregset_t. */ void @@ -440,6 +501,16 @@ mips64_supply_fpregset (struct regcache *regcache, (const gdb_byte *)(*fpregsetp + 32) + 4); } +static void +mips64_supply_fpregset_wrapper (const struct regset *regset, + struct regcache *regcache, + int regnum, const void *gregs, size_t len) +{ + gdb_assert (len == sizeof (mips64_elf_fpregset_t)); + + mips64_supply_fpregset (regcache, (const mips64_elf_fpregset_t *)gregs); +} + /* Likewise, pack one or all floating point registers into an elf_fpregset_t. */ @@ -508,72 +579,75 @@ mips64_fill_fpregset (const struct regcache *regcache, } } +static void +mips64_fill_fpregset_wrapper (const struct regset *regset, + const struct regcache *regcache, + int regnum, void *gregs, size_t len) +{ + gdb_assert (len == sizeof (mips64_elf_fpregset_t)); -/* Use a local version of this function to get the correct types for - regsets, until multi-arch core support is ready. */ + mips64_fill_fpregset (regcache, (mips64_elf_fpregset_t *)gregs, regnum); +} -static void -fetch_core_registers (struct regcache *regcache, - char *core_reg_sect, unsigned core_reg_size, - int which, CORE_ADDR reg_addr) +const struct regset * +mips_linux_regset_from_core_section (struct gdbarch *gdbarch, + const char *sect_name, size_t sect_size) { + struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); mips_elf_gregset_t gregset; mips_elf_fpregset_t fpregset; mips64_elf_gregset_t gregset64; mips64_elf_fpregset_t fpregset64; - if (which == 0) + if (strcmp (sect_name, ".reg") == 0) { - if (core_reg_size == sizeof (gregset)) + if (sect_size == sizeof (gregset)) { - memcpy ((char *) &gregset, core_reg_sect, sizeof (gregset)); - mips_supply_gregset (regcache, - (const mips_elf_gregset_t *) &gregset); + if (tdep->gregset == NULL) + tdep->gregset = regset_alloc (gdbarch, + mips_supply_gregset_wrapper, + mips_fill_gregset_wrapper); + return tdep->gregset; } - else if (core_reg_size == sizeof (gregset64)) + else if (sect_size == sizeof (gregset64)) { - memcpy ((char *) &gregset64, core_reg_sect, sizeof (gregset64)); - mips64_supply_gregset (regcache, - (const mips64_elf_gregset_t *) &gregset64); + if (tdep->gregset64 == NULL) + tdep->gregset64 = regset_alloc (gdbarch, + mips64_supply_gregset_wrapper, + mips64_fill_gregset_wrapper); + return tdep->gregset64; } else { warning (_("wrong size gregset struct in core file")); } } - else if (which == 2) + else if (strcmp (sect_name, ".reg2") == 0) { - if (core_reg_size == sizeof (fpregset)) + if (sect_size == sizeof (fpregset)) { - memcpy ((char *) &fpregset, core_reg_sect, sizeof (fpregset)); - mips_supply_fpregset (regcache, - (const mips_elf_fpregset_t *) &fpregset); + if (tdep->fpregset == NULL) + tdep->fpregset = regset_alloc (gdbarch, + mips_supply_fpregset_wrapper, + mips_fill_fpregset_wrapper); + return tdep->fpregset; } - else if (core_reg_size == sizeof (fpregset64)) + else if (sect_size == sizeof (fpregset64)) { - memcpy ((char *) &fpregset64, core_reg_sect, - sizeof (fpregset64)); - mips64_supply_fpregset (regcache, - (const mips64_elf_fpregset_t *) &fpregset64); + if (tdep->fpregset64 == NULL) + tdep->fpregset64 = regset_alloc (gdbarch, + mips64_supply_fpregset_wrapper, + mips64_fill_fpregset_wrapper); + return tdep->fpregset64; } else { warning (_("wrong size fpregset struct in core file")); } } -} - -/* Register that we are able to handle ELF file formats using standard - procfs "regset" structures. */ -static struct core_fns regset_core_fns = -{ - bfd_target_elf_flavour, /* core_flavour */ - default_check_format, /* check_format */ - default_core_sniffer, /* core_sniffer */ - fetch_core_registers, /* core_read_registers */ - NULL /* next */ -}; + return NULL; +} static const struct target_desc * mips_linux_core_read_description (struct gdbarch *gdbarch, @@ -1206,6 +1280,9 @@ mips_linux_init_abi (struct gdbarch_info info, set_gdbarch_core_read_description (gdbarch, mips_linux_core_read_description); + set_gdbarch_regset_from_core_section (gdbarch, + mips_linux_regset_from_core_section); + tdep->syscall_next_pc = mips_linux_syscall_next_pc; if (tdesc_data) @@ -1243,6 +1320,4 @@ _initialize_mips_linux_tdep (void) GDB_OSABI_LINUX, mips_linux_init_abi); } - - deprecated_add_core_fns (®set_core_fns); } |