X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=gdb%2Fsparc64-linux-tdep.c;h=a7f439fbb04dcc001181b719ac2f94ffa0f310e2;hb=b2a0dd767a59a4b1e343c178177dcaee55e540f1;hp=a381d2aa969d0116cf9852d448d867e20658bcc9;hpb=401e27fd717fcbc2efe00e332bdaa46846501323;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/sparc64-linux-tdep.c b/gdb/sparc64-linux-tdep.c index a381d2aa96..a7f439fbb0 100644 --- a/gdb/sparc64-linux-tdep.c +++ b/gdb/sparc64-linux-tdep.c @@ -1,6 +1,6 @@ /* Target-dependent code for GNU/Linux UltraSPARC. - Copyright (C) 2003-2014 Free Software Foundation, Inc. + Copyright (C) 2003-2020 Free Software Foundation, Inc. This file is part of GDB. @@ -20,7 +20,7 @@ #include "defs.h" #include "frame.h" #include "frame-unwind.h" -#include "dwarf2-frame.h" +#include "dwarf2/frame.h" #include "regset.h" #include "regcache.h" #include "gdbarch.h" @@ -33,6 +33,17 @@ #include "xml-syscall.h" #include "linux-tdep.h" +/* ADI specific si_code */ +#ifndef SEGV_ACCADI +#define SEGV_ACCADI 3 +#endif +#ifndef SEGV_ADIDERR +#define SEGV_ADIDERR 4 +#endif +#ifndef SEGV_ADIPERR +#define SEGV_ADIPERR 5 +#endif + /* The syscall's XML filename for sparc 64-bit. */ #define XML_SYSCALL_FILENAME_SPARC64 "syscalls/sparc64-linux.xml" @@ -53,9 +64,9 @@ static const struct tramp_frame sparc64_linux_rt_sigframe = SIGTRAMP_FRAME, 4, { - { 0x82102065, -1 }, /* mov __NR_rt_sigreturn, %g1 */ - { 0x91d0206d, -1 }, /* ta 0x6d */ - { TRAMP_SENTINEL_INSN, -1 } + { 0x82102065, ULONGEST_MAX }, /* mov __NR_rt_sigreturn, %g1 */ + { 0x91d0206d, ULONGEST_MAX }, /* ta 0x6d */ + { TRAMP_SENTINEL_INSN, ULONGEST_MAX } }, sparc64_linux_sigframe_init }; @@ -104,6 +115,61 @@ sparc64_linux_sigframe_init (const struct tramp_frame *self, } trad_frame_set_id (this_cache, frame_id_build (base, func)); } + +/* sparc64 GNU/Linux implementation of the handle_segmentation_fault + gdbarch hook. + Displays information related to ADI memory corruptions. */ + +static void +sparc64_linux_handle_segmentation_fault (struct gdbarch *gdbarch, + struct ui_out *uiout) +{ + if (gdbarch_bfd_arch_info (gdbarch)->bits_per_word != 64) + return; + + CORE_ADDR addr = 0; + long si_code = 0; + + try + { + /* Evaluate si_code to see if the segfault is ADI related. */ + si_code = parse_and_eval_long ("$_siginfo.si_code\n"); + + if (si_code >= SEGV_ACCADI && si_code <= SEGV_ADIPERR) + addr = parse_and_eval_long ("$_siginfo._sifields._sigfault.si_addr"); + } + catch (const gdb_exception &exception) + { + return; + } + + /* Print out ADI event based on sig_code value */ + switch (si_code) + { + case SEGV_ACCADI: /* adi not enabled */ + uiout->text ("\n"); + uiout->field_string ("sigcode-meaning", _("ADI disabled")); + uiout->text (_(" while accessing address ")); + uiout->field_core_addr ("bound-access", gdbarch, addr); + break; + case SEGV_ADIDERR: /* disrupting mismatch */ + uiout->text ("\n"); + uiout->field_string ("sigcode-meaning", _("ADI deferred mismatch")); + uiout->text (_(" while accessing address ")); + uiout->field_core_addr ("bound-access", gdbarch, addr); + break; + case SEGV_ADIPERR: /* precise mismatch */ + uiout->text ("\n"); + uiout->field_string ("sigcode-meaning", _("ADI precise mismatch")); + uiout->text (_(" while accessing address ")); + uiout->field_core_addr ("bound-access", gdbarch, addr); + break; + default: + break; + } + +} + /* Return the address of a system call's alternative return address. */ @@ -139,7 +205,7 @@ sparc64_linux_step_trap (struct frame_info *frame, unsigned long insn) } -const struct sparc_gregset sparc64_linux_core_gregset = +const struct sparc_gregmap sparc64_linux_core_gregmap = { 32 * 8, /* %tstate */ 33 * 8, /* %tpc */ @@ -158,7 +224,7 @@ sparc64_linux_supply_core_gregset (const struct regset *regset, struct regcache *regcache, int regnum, const void *gregs, size_t len) { - sparc64_supply_gregset (&sparc64_linux_core_gregset, + sparc64_supply_gregset (&sparc64_linux_core_gregmap, regcache, regnum, gregs); } @@ -167,7 +233,7 @@ sparc64_linux_collect_core_gregset (const struct regset *regset, const struct regcache *regcache, int regnum, void *gregs, size_t len) { - sparc64_collect_gregset (&sparc64_linux_core_gregset, + sparc64_collect_gregset (&sparc64_linux_core_gregmap, regcache, regnum, gregs); } @@ -176,7 +242,7 @@ sparc64_linux_supply_core_fpregset (const struct regset *regset, struct regcache *regcache, int regnum, const void *fpregs, size_t len) { - sparc64_supply_fpregset (&sparc64_bsd_fpregset, regcache, regnum, fpregs); + sparc64_supply_fpregset (&sparc64_bsd_fpregmap, regcache, regnum, fpregs); } static void @@ -184,7 +250,7 @@ sparc64_linux_collect_core_fpregset (const struct regset *regset, const struct regcache *regcache, int regnum, void *fpregs, size_t len) { - sparc64_collect_fpregset (&sparc64_bsd_fpregset, regcache, regnum, fpregs); + sparc64_collect_fpregset (&sparc64_bsd_fpregmap, regcache, regnum, fpregs); } /* Set the program counter for process PTID to PC. */ @@ -194,7 +260,7 @@ sparc64_linux_collect_core_fpregset (const struct regset *regset, static void sparc64_linux_write_pc (struct regcache *regcache, CORE_ADDR pc) { - struct gdbarch_tdep *tdep = gdbarch_tdep (get_regcache_arch (regcache)); + struct gdbarch_tdep *tdep = gdbarch_tdep (regcache->arch ()); ULONGEST state; regcache_cooked_write_unsigned (regcache, tdep->pc_regnum, pc); @@ -215,9 +281,9 @@ sparc64_linux_write_pc (struct regcache *regcache, CORE_ADDR pc) static LONGEST sparc64_linux_get_syscall_number (struct gdbarch *gdbarch, - ptid_t ptid) + thread_info *thread) { - struct regcache *regcache = get_thread_regcache (ptid); + struct regcache *regcache = get_thread_regcache (thread); enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); /* The content of a register. */ gdb_byte buf[8]; @@ -227,7 +293,7 @@ sparc64_linux_get_syscall_number (struct gdbarch *gdbarch, /* Getting the system call number from the register. When dealing with the sparc architecture, this information is stored at the %g1 register. */ - regcache_cooked_read (regcache, SPARC_G1_REGNUM, buf); + regcache->cooked_read (SPARC_G1_REGNUM, buf); ret = extract_signed_integer (buf, 8, byte_order); @@ -241,7 +307,6 @@ static int sparc64_linux_get_longjmp_target (struct frame_info *frame, CORE_ADDR *pc) { struct gdbarch *gdbarch = get_frame_arch (frame); - struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); CORE_ADDR jb_addr; gdb_byte buf[8]; @@ -280,6 +345,20 @@ sparc64_linux_get_longjmp_target (struct frame_info *frame, CORE_ADDR *pc) +static const struct regset sparc64_linux_gregset = + { + NULL, + sparc64_linux_supply_core_gregset, + sparc64_linux_collect_core_gregset + }; + +static const struct regset sparc64_linux_fpregset = + { + NULL, + sparc64_linux_supply_core_fpregset, + sparc64_linux_collect_core_fpregset + }; + static void sparc64_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) { @@ -287,12 +366,10 @@ sparc64_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) linux_init_abi (info, gdbarch); - tdep->gregset = regset_alloc (gdbarch, sparc64_linux_supply_core_gregset, - sparc64_linux_collect_core_gregset); + tdep->gregset = &sparc64_linux_gregset; tdep->sizeof_gregset = 288; - tdep->fpregset = regset_alloc (gdbarch, sparc64_linux_supply_core_fpregset, - sparc64_linux_collect_core_fpregset); + tdep->fpregset = &sparc64_linux_fpregset; tdep->sizeof_fpregset = 280; tramp_frame_prepend_unwinder (gdbarch, &sparc64_linux_rt_sigframe); @@ -324,17 +401,16 @@ sparc64_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) set_gdbarch_write_pc (gdbarch, sparc64_linux_write_pc); /* Functions for 'catch syscall'. */ - set_xml_syscall_file_name (XML_SYSCALL_FILENAME_SPARC64); + set_xml_syscall_file_name (gdbarch, XML_SYSCALL_FILENAME_SPARC64); set_gdbarch_get_syscall_number (gdbarch, sparc64_linux_get_syscall_number); + set_gdbarch_handle_segmentation_fault (gdbarch, + sparc64_linux_handle_segmentation_fault); } - - -/* Provide a prototype to silence -Wmissing-prototypes. */ -extern void _initialize_sparc64_linux_tdep (void); +void _initialize_sparc64_linux_tdep (); void -_initialize_sparc64_linux_tdep (void) +_initialize_sparc64_linux_tdep () { gdbarch_register_osabi (bfd_arch_sparc, bfd_mach_sparc_v9, GDB_OSABI_LINUX, sparc64_linux_init_abi);