diff options
author | Ulrich Weigand <uweigand@de.ibm.com> | 2013-09-13 14:17:31 +0000 |
---|---|---|
committer | Ulrich Weigand <uweigand@de.ibm.com> | 2013-09-13 14:17:31 +0000 |
commit | 4ac33720d6022079e8b038e795e40f0e06a4012c (patch) | |
tree | d8f025080163d46f3730e61fae2a14b59654f68e /gdb/s390-tdep.c | |
parent | 2ccd146855365598ad2644ef8139f2f2a6747b90 (diff) | |
download | gdb-4ac33720d6022079e8b038e795e40f0e06a4012c.zip gdb-4ac33720d6022079e8b038e795e40f0e06a4012c.tar.gz gdb-4ac33720d6022079e8b038e795e40f0e06a4012c.tar.bz2 |
gdb/ChangeLog:
2013-09-13 Andreas Arnez <arnez@linux.vnet.ibm.com>
* NEWS: Mention TDB support.
* features/s390-tdb.xml: New file.
* features/s390-te-linux64.xml: New file.
* features/s390x-te-linux64.xml: New file.
* features/Makefile (WHICH): Add new tdescs above.
(s390-te-linux64-expedite): Set.
(s390x-te-linux64-expedite): Set.
* features/s390-te-linux64.c: New file (generated).
* features/s390x-te-linux64.c: New file (generated).
* regformats/s390-te-linux64.dat: New file (generated).
* regformats/s390x-te-linux64.dat: New file (generated).
* s390-tdep.h (HWCAP_S390_HIGH_GPRS): Define.
(HWCAP_S390_TE): Likewise.
(S390_TDB_DWORD0_REGNUM): Likewise.
(S390_TDB_DWORD0_REGNUM): Likewise.
(S390_TDB_ABORT_CODE_REGNUM): Likewise.
(S390_TDB_CONFLICT_TOKEN_REGNUM): Likewise.
(S390_TDB_ATIA_REGNUM): Likewise.
(S390_TDB_R0_REGNUM): Likewise.
(S390_TDB_R1_REGNUM): Likewise.
(S390_TDB_R2_REGNUM): Likewise.
(S390_TDB_R3_REGNUM): Likewise.
(S390_TDB_R4_REGNUM): Likewise.
(S390_TDB_R5_REGNUM): Likewise.
(S390_TDB_R6_REGNUM): Likewise.
(S390_TDB_R7_REGNUM): Likewise.
(S390_TDB_R8_REGNUM): Likewise.
(S390_TDB_R9_REGNUM): Likewise.
(S390_TDB_R10_REGNUM): Likewise.
(S390_TDB_R11_REGNUM): Likewise.
(S390_TDB_R12_REGNUM): Likewise.
(S390_TDB_R13_REGNUM): Likewise.
(S390_TDB_R14_REGNUM): Likewise.
(S390_TDB_R15_REGNUM): Likewise.
(S390_NUM_REGS): Increase.
(S390_IS_TDBREGSET_REGNUM): New macro.
(s390_regmap_tdb): Declare.
(s390_sizeof_tdbregset): Define.
(tdesc_s390_te_linux64): Declare.
(tdesc_s390x_te_linux64): Likewise.
* s390-tdep.c: Add includes for "auxv.h", <elf.h>,
"features/s390-te-linux64.c", and "features/s390x-te-linux64.c".
(s390_regmap_tdb): New regmap.
(s390_supply_tdb_regset): New function.
(s390_tdb_regset): New regset.
(s390_linux64v2_regset_sections): Add TDB regset to list.
(s390x_linux64v2_regset_sections): Likewise.
(s390_regset_from_core_section): Recognize TDB core note section.
(s390_core_read_description): If HWCAP indicates TE support,
select tdesc_s390_te_linux64 or tdesc_s390_s390x_te_linux64.
(s390_gdbarch_init): Handle TDB regset.
(_initialize_s390_tdep): Initialize new tdescs.
* s390-nat.c (HWCAP_S390_HIGH_GPRS): Remove define.
(have_regset_tdb): New variable.
(s390_native_supply): Support register invalidation.
(fetch_regset): Invalidate registers if ptrace yields ENODATA.
(check_regset): Treat ENODATA as "regset exists".
(s390_linux_fetch_inferior_registers): Add TDB.
(s390_read_description): Check for TDB existence and select
appropriate tdesc.
* gdbserver/Makefile.in (clean): Add removal of new makefile
targets.
(s390-te-linux64.c): New makefile target.
(s390x-te-linux64.c): Likewise.
* gdbserver/configure.srv (srv_regobj): Append new objects
s390-te-linux64.o and s390x-te-linux64.o.
(srv_xmlfiles): Append new files s390-te-linux64.xml,
s390x-te-linux64.xml, and s390-tdb.xml.
* gdbserver/linux-s390-low.c (init_registers_s390_te_linux64): New
declaration.
(tdesc_s390_te_linux64): Likewise.
(init_registers_s390x_te_linux64): Likewise.
(tdesc_s390x_te_linux64): Likewise.
(s390_check_regset): Treat ENODATA as "regset exists".
(s390_arch_setup): Add TDB regset support.
(initialize_low_arch): Initialize registers for new tdescs.
gdb/doc/ChangeLog:
2013-09-13 Andreas Arnez <arnez@linux.vnet.ibm.com>
* gdb.texinfo (Decimal Floating Point format): Mention S/390.
(Standard Target Features): Add new node to menu.
(S/390 and System z Features): New node.
gdb/testsuite/ChangeLog:
2013-09-13 Andreas Arnez <arnez@linux.vnet.ibm.com>
* gdb.arch/s390-tdbregs.c: New file.
* gdb.arch/s390-tdbregs.exp: New file.
Diffstat (limited to 'gdb/s390-tdep.c')
-rw-r--r-- | gdb/s390-tdep.c | 85 |
1 files changed, 82 insertions, 3 deletions
diff --git a/gdb/s390-tdep.c b/gdb/s390-tdep.c index f28bdce..c340758 100644 --- a/gdb/s390-tdep.c +++ b/gdb/s390-tdep.c @@ -44,6 +44,7 @@ #include "prologue-value.h" #include "linux-tdep.h" #include "s390-tdep.h" +#include "auxv.h" #include "stap-probe.h" #include "ax.h" @@ -51,6 +52,7 @@ #include "user-regs.h" #include "cli/cli-utils.h" #include <ctype.h> +#include <elf.h> #include "features/s390-linux32.c" #include "features/s390-linux32v1.c" @@ -58,9 +60,11 @@ #include "features/s390-linux64.c" #include "features/s390-linux64v1.c" #include "features/s390-linux64v2.c" +#include "features/s390-te-linux64.c" #include "features/s390x-linux64.c" #include "features/s390x-linux64v1.c" #include "features/s390x-linux64v2.c" +#include "features/s390x-te-linux64.c" /* The tdep structure. */ @@ -568,6 +572,30 @@ const short s390_regmap_system_call[] = -1, -1 }; +const short s390_regmap_tdb[] = + { + 0x00, S390_TDB_DWORD0_REGNUM, + 0x08, S390_TDB_ABORT_CODE_REGNUM, + 0x10, S390_TDB_CONFLICT_TOKEN_REGNUM, + 0x18, S390_TDB_ATIA_REGNUM, + 0x80, S390_TDB_R0_REGNUM, + 0x88, S390_TDB_R1_REGNUM, + 0x90, S390_TDB_R2_REGNUM, + 0x98, S390_TDB_R3_REGNUM, + 0xa0, S390_TDB_R4_REGNUM, + 0xa8, S390_TDB_R5_REGNUM, + 0xb0, S390_TDB_R6_REGNUM, + 0xb8, S390_TDB_R7_REGNUM, + 0xc0, S390_TDB_R8_REGNUM, + 0xc8, S390_TDB_R9_REGNUM, + 0xd0, S390_TDB_R10_REGNUM, + 0xd8, S390_TDB_R11_REGNUM, + 0xe0, S390_TDB_R12_REGNUM, + 0xe8, S390_TDB_R13_REGNUM, + 0xf0, S390_TDB_R14_REGNUM, + 0xf8, S390_TDB_R15_REGNUM, + -1, -1 + }; /* Supply register REGNUM from the register set REGSET to register cache @@ -579,7 +607,25 @@ s390_supply_regset (const struct regset *regset, struct regcache *regcache, const short *map; for (map = regset->descr; map[0] >= 0; map += 2) if (regnum == -1 || regnum == map[1]) - regcache_raw_supply (regcache, map[1], (const char *)regs + map[0]); + regcache_raw_supply (regcache, map[1], + regs ? (const char *)regs + map[0] : NULL); +} + +/* Supply the TDB regset. Like s390_supply_regset, but invalidate the + TDB registers unless the TDB format field is valid. */ + +static void +s390_supply_tdb_regset (const struct regset *regset, struct regcache *regcache, + int regnum, const void *regs, size_t len) +{ + ULONGEST tdw; + enum register_status ret; + int i; + + s390_supply_regset (regset, regcache, regnum, regs, len); + ret = regcache_cooked_read_unsigned (regcache, S390_TDB_DWORD0_REGNUM, &tdw); + if (ret != REG_VALID || (tdw >> 56) != 1) + s390_supply_regset (regset, regcache, regnum, NULL, len); } /* Collect register REGNUM from the register cache REGCACHE and store @@ -639,6 +685,12 @@ static const struct regset s390_system_call_regset = { s390_collect_regset }; +static const struct regset s390_tdb_regset = { + s390_regmap_tdb, + s390_supply_tdb_regset, + s390_collect_regset +}; + static struct core_regset_section s390_linux32_regset_sections[] = { { ".reg", s390_sizeof_gregset, "general-purpose" }, @@ -687,6 +739,7 @@ static struct core_regset_section s390_linux64v2_regset_sections[] = { ".reg-s390-high-gprs", 16*4, "s390 GPR upper halves" }, { ".reg-s390-last-break", 8, "s930 last-break address" }, { ".reg-s390-system-call", 4, "s390 system-call" }, + { ".reg-s390-tdb", s390_sizeof_tdbregset, "s390 TDB" }, { NULL, 0} }; @@ -711,6 +764,7 @@ static struct core_regset_section s390x_linux64v2_regset_sections[] = { ".reg2", s390_sizeof_fpregset, "floating-point" }, { ".reg-s390-last-break", 8, "s930 last-break address" }, { ".reg-s390-system-call", 4, "s390 system-call" }, + { ".reg-s390-tdb", s390_sizeof_tdbregset, "s390 TDB" }, { NULL, 0} }; @@ -739,6 +793,9 @@ s390_regset_from_core_section (struct gdbarch *gdbarch, if (strcmp (sect_name, ".reg-s390-system-call") == 0 && sect_size >= 4) return &s390_system_call_regset; + if (strcmp (sect_name, ".reg-s390-tdb") == 0 && sect_size >= 256) + return &s390_tdb_regset; + return NULL; } @@ -750,6 +807,9 @@ s390_core_read_description (struct gdbarch *gdbarch, asection *v1 = bfd_get_section_by_name (abfd, ".reg-s390-last-break"); asection *v2 = bfd_get_section_by_name (abfd, ".reg-s390-system-call"); asection *section = bfd_get_section_by_name (abfd, ".reg"); + unsigned long hwcap = 0; + + target_auxv_search (target, AT_HWCAP, &hwcap); if (!section) return NULL; @@ -757,14 +817,16 @@ s390_core_read_description (struct gdbarch *gdbarch, { case s390_sizeof_gregset: if (high_gprs) - return (v2? tdesc_s390_linux64v2 : + return ((hwcap & HWCAP_S390_TE) ? tdesc_s390_te_linux64 : + v2? tdesc_s390_linux64v2 : v1? tdesc_s390_linux64v1 : tdesc_s390_linux64); else return (v2? tdesc_s390_linux32v2 : v1? tdesc_s390_linux32v1 : tdesc_s390_linux32); case s390x_sizeof_gregset: - return (v2? tdesc_s390x_linux64v2 : + return ((hwcap & HWCAP_S390_TE) ? tdesc_s390x_te_linux64 : + v2? tdesc_s390x_linux64v2 : v1? tdesc_s390x_linux64v1 : tdesc_s390x_linux64); default: @@ -3012,6 +3074,11 @@ s390_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) "r0h", "r1h", "r2h", "r3h", "r4h", "r5h", "r6h", "r7h", "r8h", "r9h", "r10h", "r11h", "r12h", "r13h", "r14h", "r15h" }; + static const char *const tdb_regs[] = { + "tdb0", "tac", "tct", "atia", + "tr0", "tr1", "tr2", "tr3", "tr4", "tr5", "tr6", "tr7", + "tr8", "tr9", "tr10", "tr11", "tr12", "tr13", "tr14", "tr15" + }; const struct tdesc_feature *feature; int i, valid_p = 1; @@ -3089,6 +3156,16 @@ s390_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) valid_p = 0; } + /* Transaction diagnostic block. */ + feature = tdesc_find_feature (tdesc, "org.gnu.gdb.s390.tdb"); + if (feature) + { + for (i = 0; i < ARRAY_SIZE (tdb_regs); i++) + valid_p &= tdesc_numbered_register (feature, tdesc_data, + S390_TDB_DWORD0_REGNUM + i, + tdb_regs[i]); + } + if (!valid_p) { tdesc_data_cleanup (tdesc_data); @@ -3305,7 +3382,9 @@ _initialize_s390_tdep (void) initialize_tdesc_s390_linux64 (); initialize_tdesc_s390_linux64v1 (); initialize_tdesc_s390_linux64v2 (); + initialize_tdesc_s390_te_linux64 (); initialize_tdesc_s390x_linux64 (); initialize_tdesc_s390x_linux64v1 (); initialize_tdesc_s390x_linux64v2 (); + initialize_tdesc_s390x_te_linux64 (); } |