gdb/sparc64-linux-tdep.c - gdb
Global variables defined
Functions defined
Macros defined
Source code
- #include "defs.h"
- #include "frame.h"
- #include "frame-unwind.h"
- #include "dwarf2-frame.h"
- #include "regset.h"
- #include "regcache.h"
- #include "gdbarch.h"
- #include "gdbcore.h"
- #include "osabi.h"
- #include "solib-svr4.h"
- #include "symtab.h"
- #include "trad-frame.h"
- #include "tramp-frame.h"
- #include "xml-syscall.h"
- #include "linux-tdep.h"
- #define XML_SYSCALL_FILENAME_SPARC64 "syscalls/sparc64-linux.xml"
- #include "sparc64-tdep.h"
- static void sparc64_linux_sigframe_init (const struct tramp_frame *self,
- struct frame_info *this_frame,
- struct trad_frame_cache *this_cache,
- CORE_ADDR func);
- static const struct tramp_frame sparc64_linux_rt_sigframe =
- {
- SIGTRAMP_FRAME,
- 4,
- {
- { 0x82102065, -1 },
- { 0x91d0206d, -1 },
- { TRAMP_SENTINEL_INSN, -1 }
- },
- sparc64_linux_sigframe_init
- };
- static void
- sparc64_linux_sigframe_init (const struct tramp_frame *self,
- struct frame_info *this_frame,
- struct trad_frame_cache *this_cache,
- CORE_ADDR func)
- {
- CORE_ADDR base, addr, sp_addr;
- int regnum;
- base = get_frame_register_unsigned (this_frame, SPARC_O1_REGNUM);
- base += 128;
-
-
- addr = base + 8;
- sp_addr = base + ((SPARC_SP_REGNUM - SPARC_G0_REGNUM) * 8);
- for (regnum = SPARC_G1_REGNUM; regnum <= SPARC_O7_REGNUM; regnum++)
- {
- trad_frame_set_reg_addr (this_cache, regnum, addr);
- addr += 8;
- }
- trad_frame_set_reg_addr (this_cache, SPARC64_STATE_REGNUM, addr + 0);
- trad_frame_set_reg_addr (this_cache, SPARC64_PC_REGNUM, addr + 8);
- trad_frame_set_reg_addr (this_cache, SPARC64_NPC_REGNUM, addr + 16);
- trad_frame_set_reg_addr (this_cache, SPARC64_Y_REGNUM, addr + 24);
- trad_frame_set_reg_addr (this_cache, SPARC64_FPRS_REGNUM, addr + 28);
- base = get_frame_register_unsigned (this_frame, SPARC_SP_REGNUM);
- if (base & 1)
- base += BIAS;
- addr = get_frame_memory_unsigned (this_frame, sp_addr, 8);
- if (addr & 1)
- addr += BIAS;
- for (regnum = SPARC_L0_REGNUM; regnum <= SPARC_I7_REGNUM; regnum++)
- {
- trad_frame_set_reg_addr (this_cache, regnum, addr);
- addr += 8;
- }
- trad_frame_set_id (this_cache, frame_id_build (base, func));
- }
- static CORE_ADDR
- sparc64_linux_step_trap (struct frame_info *frame, unsigned long insn)
- {
-
- if ((insn == 0x91d0206d)
- && (get_frame_register_unsigned (frame, SPARC_G1_REGNUM) == 101))
- {
- struct gdbarch *gdbarch = get_frame_arch (frame);
- enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
- ULONGEST sp = get_frame_register_unsigned (frame, SPARC_SP_REGNUM);
- if (sp & 1)
- sp += BIAS;
-
- return read_memory_unsigned_integer (sp + 192 + 128 + 136,
- 8, byte_order);
- }
- return 0;
- }
- const struct sparc_gregmap sparc64_linux_core_gregmap =
- {
- 32 * 8,
- 33 * 8,
- 34 * 8,
- 35 * 8,
- -1,
- -1,
- 1 * 8,
- 16 * 8,
- 8,
- };
- static void
- 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_gregmap,
- regcache, regnum, gregs);
- }
- static void
- 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_gregmap,
- regcache, regnum, gregs);
- }
- static void
- 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_fpregmap, regcache, regnum, fpregs);
- }
- static void
- 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_fpregmap, regcache, regnum, fpregs);
- }
- #define TSTATE_SYSCALL 0x0000000000000020ULL
- static void
- sparc64_linux_write_pc (struct regcache *regcache, CORE_ADDR pc)
- {
- struct gdbarch_tdep *tdep = gdbarch_tdep (get_regcache_arch (regcache));
- ULONGEST state;
- regcache_cooked_write_unsigned (regcache, tdep->pc_regnum, pc);
- regcache_cooked_write_unsigned (regcache, tdep->npc_regnum, pc + 4);
-
- regcache_cooked_read_unsigned (regcache, SPARC64_STATE_REGNUM, &state);
- state &= ~TSTATE_SYSCALL;
- regcache_cooked_write_unsigned (regcache, SPARC64_STATE_REGNUM, state);
- }
- static LONGEST
- sparc64_linux_get_syscall_number (struct gdbarch *gdbarch,
- ptid_t ptid)
- {
- struct regcache *regcache = get_thread_regcache (ptid);
- enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
-
- gdb_byte buf[8];
-
- LONGEST ret;
-
- regcache_cooked_read (regcache, SPARC_G1_REGNUM, buf);
- ret = extract_signed_integer (buf, 8, byte_order);
- return ret;
- }
- 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];
- jb_addr = get_frame_register_unsigned (frame, SPARC_O0_REGNUM);
-
- if (target_read_memory (jb_addr + 32 + (18 * 8), buf, 8))
- return 0;
- *pc = extract_unsigned_integer (buf, 8, gdbarch_byte_order (gdbarch));
- if (!sparc_is_annulled_branch_insn (*pc))
- *pc += 4;
- *pc += 4;
- return 1;
- }
- 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)
- {
- struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
- linux_init_abi (info, gdbarch);
- tdep->gregset = &sparc64_linux_gregset;
- tdep->sizeof_gregset = 288;
- tdep->fpregset = &sparc64_linux_fpregset;
- tdep->sizeof_fpregset = 280;
- tramp_frame_prepend_unwinder (gdbarch, &sparc64_linux_rt_sigframe);
-
- dwarf2_append_unwinders (gdbarch);
- sparc64_init_abi (info, gdbarch);
-
- set_gdbarch_skip_trampoline_code (gdbarch, find_solib_trampoline_target);
- set_solib_svr4_fetch_link_map_offsets
- (gdbarch, svr4_lp64_fetch_link_map_offsets);
-
- tdep->plt_entry_size = 16;
-
- set_gdbarch_fetch_tls_load_module_address (gdbarch,
- svr4_fetch_objfile_link_map);
-
- tdep->step_trap = sparc64_linux_step_trap;
-
- set_gdbarch_get_longjmp_target (gdbarch, sparc64_linux_get_longjmp_target);
- set_gdbarch_write_pc (gdbarch, sparc64_linux_write_pc);
-
- set_xml_syscall_file_name (gdbarch, XML_SYSCALL_FILENAME_SPARC64);
- set_gdbarch_get_syscall_number (gdbarch,
- sparc64_linux_get_syscall_number);
- }
- extern void _initialize_sparc64_linux_tdep (void);
- void
- _initialize_sparc64_linux_tdep (void)
- {
- gdbarch_register_osabi (bfd_arch_sparc, bfd_mach_sparc_v9,
- GDB_OSABI_LINUX, sparc64_linux_init_abi);
- }