gdb/sparc64-linux-tdep.c - gdb

Global variables defined

Functions defined

Macros defined

Source code

  1. /* Target-dependent code for GNU/Linux UltraSPARC.

  2.    Copyright (C) 2003-2015 Free Software Foundation, Inc.

  3.    This file is part of GDB.

  4.    This program is free software; you can redistribute it and/or modify
  5.    it under the terms of the GNU General Public License as published by
  6.    the Free Software Foundation; either version 3 of the License, or
  7.    (at your option) any later version.

  8.    This program is distributed in the hope that it will be useful,
  9.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  10.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  11.    GNU General Public License for more details.

  12.    You should have received a copy of the GNU General Public License
  13.    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */

  14. #include "defs.h"
  15. #include "frame.h"
  16. #include "frame-unwind.h"
  17. #include "dwarf2-frame.h"
  18. #include "regset.h"
  19. #include "regcache.h"
  20. #include "gdbarch.h"
  21. #include "gdbcore.h"
  22. #include "osabi.h"
  23. #include "solib-svr4.h"
  24. #include "symtab.h"
  25. #include "trad-frame.h"
  26. #include "tramp-frame.h"
  27. #include "xml-syscall.h"
  28. #include "linux-tdep.h"

  29. /* The syscall's XML filename for sparc 64-bit.  */
  30. #define XML_SYSCALL_FILENAME_SPARC64 "syscalls/sparc64-linux.xml"

  31. #include "sparc64-tdep.h"

  32. /* Signal trampoline support.  */

  33. static void sparc64_linux_sigframe_init (const struct tramp_frame *self,
  34.                                          struct frame_info *this_frame,
  35.                                          struct trad_frame_cache *this_cache,
  36.                                          CORE_ADDR func);

  37. /* See sparc-linux-tdep.c for details.  Note that 64-bit binaries only
  38.    use RT signals.  */

  39. static const struct tramp_frame sparc64_linux_rt_sigframe =
  40. {
  41.   SIGTRAMP_FRAME,
  42.   4,
  43.   {
  44.     { 0x82102065, -1 },                /* mov __NR_rt_sigreturn, %g1 */
  45.     { 0x91d0206d, -1 },                /* ta  0x6d */
  46.     { TRAMP_SENTINEL_INSN, -1 }
  47.   },
  48.   sparc64_linux_sigframe_init
  49. };

  50. static void
  51. sparc64_linux_sigframe_init (const struct tramp_frame *self,
  52.                              struct frame_info *this_frame,
  53.                              struct trad_frame_cache *this_cache,
  54.                              CORE_ADDR func)
  55. {
  56.   CORE_ADDR base, addr, sp_addr;
  57.   int regnum;

  58.   base = get_frame_register_unsigned (this_frame, SPARC_O1_REGNUM);
  59.   base += 128;

  60.   /* Offsets from <bits/sigcontext.h>.  */

  61.   /* Since %g0 is always zero, keep the identity encoding.  */
  62.   addr = base + 8;
  63.   sp_addr = base + ((SPARC_SP_REGNUM - SPARC_G0_REGNUM) * 8);
  64.   for (regnum = SPARC_G1_REGNUM; regnum <= SPARC_O7_REGNUM; regnum++)
  65.     {
  66.       trad_frame_set_reg_addr (this_cache, regnum, addr);
  67.       addr += 8;
  68.     }

  69.   trad_frame_set_reg_addr (this_cache, SPARC64_STATE_REGNUM, addr + 0);
  70.   trad_frame_set_reg_addr (this_cache, SPARC64_PC_REGNUM, addr + 8);
  71.   trad_frame_set_reg_addr (this_cache, SPARC64_NPC_REGNUM, addr + 16);
  72.   trad_frame_set_reg_addr (this_cache, SPARC64_Y_REGNUM, addr + 24);
  73.   trad_frame_set_reg_addr (this_cache, SPARC64_FPRS_REGNUM, addr + 28);

  74.   base = get_frame_register_unsigned (this_frame, SPARC_SP_REGNUM);
  75.   if (base & 1)
  76.     base += BIAS;

  77.   addr = get_frame_memory_unsigned (this_frame, sp_addr, 8);
  78.   if (addr & 1)
  79.     addr += BIAS;

  80.   for (regnum = SPARC_L0_REGNUM; regnum <= SPARC_I7_REGNUM; regnum++)
  81.     {
  82.       trad_frame_set_reg_addr (this_cache, regnum, addr);
  83.       addr += 8;
  84.     }
  85.   trad_frame_set_id (this_cache, frame_id_build (base, func));
  86. }

  87. /* Return the address of a system call's alternative return
  88.    address.  */

  89. static CORE_ADDR
  90. sparc64_linux_step_trap (struct frame_info *frame, unsigned long insn)
  91. {
  92.   /* __NR_rt_sigreturn is 101  */
  93.   if ((insn == 0x91d0206d)
  94.       && (get_frame_register_unsigned (frame, SPARC_G1_REGNUM) == 101))
  95.     {
  96.       struct gdbarch *gdbarch = get_frame_arch (frame);
  97.       enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);

  98.       ULONGEST sp = get_frame_register_unsigned (frame, SPARC_SP_REGNUM);
  99.       if (sp & 1)
  100.         sp += BIAS;

  101.       /* The kernel puts the sigreturn registers on the stack,
  102.          and this is where the signal unwinding state is take from
  103.          when returning from a signal.

  104.          A siginfo_t sits 192 bytes from the base of the stack.  This
  105.          siginfo_t is 128 bytes, and is followed by the sigreturn
  106.          register save area.  The saved PC sits at a 136 byte offset
  107.          into there.  */

  108.       return read_memory_unsigned_integer (sp + 192 + 128 + 136,
  109.                                            8, byte_order);
  110.     }

  111.   return 0;
  112. }


  113. const struct sparc_gregmap sparc64_linux_core_gregmap =
  114. {
  115.   32 * 8,                        /* %tstate */
  116.   33 * 8,                        /* %tpc */
  117.   34 * 8,                        /* %tnpc */
  118.   35 * 8,                        /* %y */
  119.   -1,                                /* %wim */
  120.   -1,                                /* %tbr */
  121.   1 * 8,                        /* %g1 */
  122.   16 * 8,                        /* %l0 */
  123.   8,                                /* y size */
  124. };


  125. static void
  126. sparc64_linux_supply_core_gregset (const struct regset *regset,
  127.                                    struct regcache *regcache,
  128.                                    int regnum, const void *gregs, size_t len)
  129. {
  130.   sparc64_supply_gregset (&sparc64_linux_core_gregmap,
  131.                           regcache, regnum, gregs);
  132. }

  133. static void
  134. sparc64_linux_collect_core_gregset (const struct regset *regset,
  135.                                     const struct regcache *regcache,
  136.                                     int regnum, void *gregs, size_t len)
  137. {
  138.   sparc64_collect_gregset (&sparc64_linux_core_gregmap,
  139.                            regcache, regnum, gregs);
  140. }

  141. static void
  142. sparc64_linux_supply_core_fpregset (const struct regset *regset,
  143.                                     struct regcache *regcache,
  144.                                     int regnum, const void *fpregs, size_t len)
  145. {
  146.   sparc64_supply_fpregset (&sparc64_bsd_fpregmap, regcache, regnum, fpregs);
  147. }

  148. static void
  149. sparc64_linux_collect_core_fpregset (const struct regset *regset,
  150.                                      const struct regcache *regcache,
  151.                                      int regnum, void *fpregs, size_t len)
  152. {
  153.   sparc64_collect_fpregset (&sparc64_bsd_fpregmap, regcache, regnum, fpregs);
  154. }

  155. /* Set the program counter for process PTID to PC.  */

  156. #define TSTATE_SYSCALL        0x0000000000000020ULL

  157. static void
  158. sparc64_linux_write_pc (struct regcache *regcache, CORE_ADDR pc)
  159. {
  160.   struct gdbarch_tdep *tdep = gdbarch_tdep (get_regcache_arch (regcache));
  161.   ULONGEST state;

  162.   regcache_cooked_write_unsigned (regcache, tdep->pc_regnum, pc);
  163.   regcache_cooked_write_unsigned (regcache, tdep->npc_regnum, pc + 4);

  164.   /* Clear the "in syscall" bit to prevent the kernel from
  165.      messing with the PCs we just installed, if we happen to be
  166.      within an interrupted system call that the kernel wants to
  167.      restart.

  168.      Note that after we return from the dummy call, the TSTATE et al.
  169.      registers will be automatically restored, and the kernel
  170.      continues to restart the system call at this point.  */
  171.   regcache_cooked_read_unsigned (regcache, SPARC64_STATE_REGNUM, &state);
  172.   state &= ~TSTATE_SYSCALL;
  173.   regcache_cooked_write_unsigned (regcache, SPARC64_STATE_REGNUM, state);
  174. }

  175. static LONGEST
  176. sparc64_linux_get_syscall_number (struct gdbarch *gdbarch,
  177.                                   ptid_t ptid)
  178. {
  179.   struct regcache *regcache = get_thread_regcache (ptid);
  180.   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
  181.   /* The content of a register.  */
  182.   gdb_byte buf[8];
  183.   /* The result.  */
  184.   LONGEST ret;

  185.   /* Getting the system call number from the register.
  186.      When dealing with the sparc architecture, this information
  187.      is stored at the %g1 register.  */
  188.   regcache_cooked_read (regcache, SPARC_G1_REGNUM, buf);

  189.   ret = extract_signed_integer (buf, 8, byte_order);

  190.   return ret;
  191. }


  192. /* Implement the "get_longjmp_target" gdbarch method.  */

  193. static int
  194. sparc64_linux_get_longjmp_target (struct frame_info *frame, CORE_ADDR *pc)
  195. {
  196.   struct gdbarch *gdbarch = get_frame_arch (frame);
  197.   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
  198.   CORE_ADDR jb_addr;
  199.   gdb_byte buf[8];

  200.   jb_addr = get_frame_register_unsigned (frame, SPARC_O0_REGNUM);

  201.   /* setjmp and longjmp in SPARC64 are implemented in glibc using the
  202.      setcontext and getcontext system calls respectively.  These
  203.      system calls operate on ucontext_t structures, which happen to
  204.      partially have the same structure than jmp_buf.  However the
  205.      ucontext returned by getcontext, and thus the jmp_buf structure
  206.      returned by setjmp, contains the context of the trap instruction
  207.      in the glibc __[sig]setjmp wrapper, not the context of the user
  208.      code calling setjmp.

  209.      %o7 in the jmp_buf structure is stored at offset 18*8 in the
  210.      mc_gregs array, which is itself located at offset 32 into
  211.      jmp_buf.  See bits/setjmp.h.  This register contains the address
  212.      of the 'call setjmp' instruction in user code.

  213.      In order to determine the longjmp target address in the
  214.      initiating frame we need to examine the call instruction itself,
  215.      in particular whether the annul bit is set.  If it is not set
  216.      then we need to jump over the instruction at the delay slot.  */

  217.   if (target_read_memory (jb_addr + 32 + (18 * 8), buf, 8))
  218.     return 0;

  219.   *pc = extract_unsigned_integer (buf, 8, gdbarch_byte_order (gdbarch));

  220.   if (!sparc_is_annulled_branch_insn (*pc))
  221.       *pc += 4; /* delay slot insn  */
  222.   *pc += 4; /* call insn  */

  223.   return 1;
  224. }



  225. static const struct regset sparc64_linux_gregset =
  226.   {
  227.     NULL,
  228.     sparc64_linux_supply_core_gregset,
  229.     sparc64_linux_collect_core_gregset
  230.   };

  231. static const struct regset sparc64_linux_fpregset =
  232.   {
  233.     NULL,
  234.     sparc64_linux_supply_core_fpregset,
  235.     sparc64_linux_collect_core_fpregset
  236.   };

  237. static void
  238. sparc64_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
  239. {
  240.   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);

  241.   linux_init_abi (info, gdbarch);

  242.   tdep->gregset = &sparc64_linux_gregset;
  243.   tdep->sizeof_gregset = 288;

  244.   tdep->fpregset = &sparc64_linux_fpregset;
  245.   tdep->sizeof_fpregset = 280;

  246.   tramp_frame_prepend_unwinder (gdbarch, &sparc64_linux_rt_sigframe);

  247.   /* Hook in the DWARF CFI frame unwinder.  */
  248.   dwarf2_append_unwinders (gdbarch);

  249.   sparc64_init_abi (info, gdbarch);

  250.   /* GNU/Linux has SVR4-style shared libraries...  */
  251.   set_gdbarch_skip_trampoline_code (gdbarch, find_solib_trampoline_target);
  252.   set_solib_svr4_fetch_link_map_offsets
  253.     (gdbarch, svr4_lp64_fetch_link_map_offsets);

  254.   /* ...which means that we need some special handling when doing
  255.      prologue analysis.  */
  256.   tdep->plt_entry_size = 16;

  257.   /* Enable TLS support.  */
  258.   set_gdbarch_fetch_tls_load_module_address (gdbarch,
  259.                                              svr4_fetch_objfile_link_map);

  260.   /* Make sure we can single-step over signal return system calls.  */
  261.   tdep->step_trap = sparc64_linux_step_trap;

  262.   /* Make sure we can single-step over longjmp calls.  */
  263.   set_gdbarch_get_longjmp_target (gdbarch, sparc64_linux_get_longjmp_target);

  264.   set_gdbarch_write_pc (gdbarch, sparc64_linux_write_pc);

  265.   /* Functions for 'catch syscall'.  */
  266.   set_xml_syscall_file_name (gdbarch, XML_SYSCALL_FILENAME_SPARC64);
  267.   set_gdbarch_get_syscall_number (gdbarch,
  268.                                   sparc64_linux_get_syscall_number);
  269. }


  270. /* Provide a prototype to silence -Wmissing-prototypes.  */
  271. extern void _initialize_sparc64_linux_tdep (void);

  272. void
  273. _initialize_sparc64_linux_tdep (void)
  274. {
  275.   gdbarch_register_osabi (bfd_arch_sparc, bfd_mach_sparc_v9,
  276.                           GDB_OSABI_LINUX, sparc64_linux_init_abi);
  277. }