diff options
author | Andreas Arnez <arnez@linux.vnet.ibm.com> | 2014-07-18 08:14:27 +0000 |
---|---|---|
committer | Ulrich Weigand <ulrich.weigand@de.ibm.com> | 2014-08-07 17:31:50 +0200 |
commit | 070bdf0b1a9b496bc1e7dc63cb2445a7e0e40de1 (patch) | |
tree | e20de3645c2f6fd61347a248a6d1e24cfe356627 | |
parent | 08f9f542cb977e0f69c407ad90c6809ec04a737e (diff) | |
download | binutils-gdb-070bdf0b1a9b496bc1e7dc63cb2445a7e0e40de1.tar.gz |
IA64 Linux: Define regset structures.
-rw-r--r-- | gdb/ChangeLog | 11 | ||||
-rw-r--r-- | gdb/ia64-linux-tdep.c | 90 |
2 files changed, 101 insertions, 0 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 2c2acdd75d9..7dd366b63c0 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,5 +1,16 @@ 2014-08-07 Andreas Arnez <arnez@linux.vnet.ibm.com> + * ia64-linux-tdep.c: Include "regset.h". + (ia64_linux_gregmap, ia64_linux_fpregmap): New register maps. + (IA64_LINUX_GREGS_SIZE, IA64_LINUX_FPREGS_SIZE): New macros. + (ia64_linux_supply_fpregset): New function. + (ia64_linux_gregset, ia64_linux_fpregset): New regsets. + (ia64_linux_regset_from_core_section): New function. + (ia64_linux_init_abi): Set regset_from_core_section gdbarch + method. + +2014-08-07 Andreas Arnez <arnez@linux.vnet.ibm.com> + * m68klinux-tdep.c: Include "regset.h". (m68k_linux_gregmap, m68k_linux_fpregmap): New register maps. (M68K_LINUX_GREGS_SIZE, M68K_LINUX_FPREGS_SIZE): New macros. diff --git a/gdb/ia64-linux-tdep.c b/gdb/ia64-linux-tdep.c index 128924e102c..3bdf2a106c5 100644 --- a/gdb/ia64-linux-tdep.c +++ b/gdb/ia64-linux-tdep.c @@ -26,6 +26,7 @@ #include "solib-svr4.h" #include "symtab.h" #include "linux-tdep.h" +#include "regset.h" #include <ctype.h> @@ -131,6 +132,91 @@ ia64_linux_stap_is_single_operand (struct gdbarch *gdbarch, const char *s) || isdigit (*s)); /* Literal number. */ } +/* Core file support. */ + +static const struct regcache_map_entry ia64_linux_gregmap[] = + { + { 32, IA64_GR0_REGNUM, 8 }, /* r0 ... r31 */ + { 1, REGCACHE_MAP_SKIP, 8 }, /* FIXME: NAT collection bits? */ + { 1, IA64_PR_REGNUM, 8 }, + { 8, IA64_BR0_REGNUM, 8 }, /* b0 ... b7 */ + { 1, IA64_IP_REGNUM, 8 }, + { 1, IA64_CFM_REGNUM, 8 }, + { 1, IA64_PSR_REGNUM, 8 }, + { 1, IA64_RSC_REGNUM, 8 }, + { 1, IA64_BSP_REGNUM, 8 }, + { 1, IA64_BSPSTORE_REGNUM, 8 }, + { 1, IA64_RNAT_REGNUM, 8 }, + { 1, IA64_CCV_REGNUM, 8 }, + { 1, IA64_UNAT_REGNUM, 8 }, + { 1, IA64_FPSR_REGNUM, 8 }, + { 1, IA64_PFS_REGNUM, 8 }, + { 1, IA64_LC_REGNUM, 8 }, + { 1, IA64_EC_REGNUM, 8 }, + { 0 } + }; + +/* Size of 'gregset_t', as defined by the Linux kernel. Note that + this is more than actually mapped in the regmap above. */ + +#define IA64_LINUX_GREGS_SIZE (128 * 8) + +static const struct regcache_map_entry ia64_linux_fpregmap[] = + { + { 128, IA64_FR0_REGNUM, 16 }, /* f0 ... f127 */ + { 0 } + }; + +#define IA64_LINUX_FPREGS_SIZE (128 * 16) + +static void +ia64_linux_supply_fpregset (const struct regset *regset, + struct regcache *regcache, + int regnum, const void *regs, size_t len) +{ + const gdb_byte f_zero[16] = { 0 }; + const gdb_byte f_one[16] = + { 0, 0, 0, 0, 0, 0, 0, 0x80, 0xff, 0xff, 0, 0, 0, 0, 0, 0 }; + + regcache_supply_regset (regset, regcache, regnum, regs, len); + + /* Kernel generated cores have fr1==0 instead of 1.0. Older GDBs + did the same. So ignore whatever might be recorded in fpregset_t + for fr0/fr1 and always supply their expected values. */ + if (regnum == -1 || regnum == IA64_FR0_REGNUM) + regcache_raw_supply (regcache, IA64_FR0_REGNUM, f_zero); + if (regnum == -1 || regnum == IA64_FR1_REGNUM) + regcache_raw_supply (regcache, IA64_FR1_REGNUM, f_one); +} + +static const struct regset ia64_linux_gregset = + { + ia64_linux_gregmap, + regcache_supply_regset, regcache_collect_regset + }; + +static const struct regset ia64_linux_fpregset = + { + ia64_linux_fpregmap, + ia64_linux_supply_fpregset, regcache_collect_regset + }; + +static const struct regset * +ia64_linux_regset_from_core_section (struct gdbarch *gdbarch, + const char *sect_name, + size_t sect_size) +{ + if (strcmp (sect_name, ".reg") == 0 + && sect_size >= IA64_LINUX_GREGS_SIZE) + return &ia64_linux_gregset; + + if (strcmp (sect_name, ".reg2") == 0 + && sect_size >= IA64_LINUX_FPREGS_SIZE) + return &ia64_linux_fpregset; + + return NULL; +} + static void ia64_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) { @@ -161,6 +247,10 @@ ia64_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) set_gdbarch_fetch_tls_load_module_address (gdbarch, svr4_fetch_objfile_link_map); + /* Core file support. */ + set_gdbarch_regset_from_core_section (gdbarch, + ia64_linux_regset_from_core_section); + /* SystemTap related. */ set_gdbarch_stap_register_prefixes (gdbarch, stap_register_prefixes); set_gdbarch_stap_register_indirection_prefixes (gdbarch, |