gdb/sparc-linux-tdep.c - gdb
Global variables defined
Functions defined
Macros defined
Source code
- #include "defs.h"
- #include "dwarf2-frame.h"
- #include "frame.h"
- #include "frame-unwind.h"
- #include "gdbtypes.h"
- #include "regset.h"
- #include "gdbarch.h"
- #include "gdbcore.h"
- #include "osabi.h"
- #include "regcache.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_SPARC32 "syscalls/sparc-linux.xml"
- #include "sparc-tdep.h"
- static void sparc32_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 sparc32_linux_sigframe =
- {
- SIGTRAMP_FRAME,
- 4,
- {
- { 0x821020d8, -1 },
- { 0x91d02010, -1 },
- { TRAMP_SENTINEL_INSN, -1 }
- },
- sparc32_linux_sigframe_init
- };
- static const struct tramp_frame sparc32_linux_rt_sigframe =
- {
- SIGTRAMP_FRAME,
- 4,
- {
- { 0x82102065, -1 },
- { 0x91d02010, -1 },
- { TRAMP_SENTINEL_INSN, -1 }
- },
- sparc32_linux_sigframe_init
- };
- enum
- {
- SPARC_LINUX_SIGEMT = 7,
- SPARC_LINUX_SIGBUS = 10,
- SPARC_LINUX_SIGSYS = 12,
- SPARC_LINUX_SIGURG = 16,
- SPARC_LINUX_SIGSTOP = 17,
- SPARC_LINUX_SIGTSTP = 18,
- SPARC_LINUX_SIGCONT = 19,
- SPARC_LINUX_SIGCHLD = 20,
- SPARC_LINUX_SIGIO = 23,
- SPARC_LINUX_SIGPOLL = SPARC_LINUX_SIGIO,
- SPARC_LINUX_SIGLOST = 29,
- SPARC_LINUX_SIGPWR = SPARC_LINUX_SIGLOST,
- SPARC_LINUX_SIGUSR1 = 30,
- SPARC_LINUX_SIGUSR2 = 31,
- };
- static void
- sparc32_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);
- if (self == &sparc32_linux_rt_sigframe)
- base += 128;
-
- trad_frame_set_reg_addr (this_cache, SPARC32_PSR_REGNUM, base + 0);
- trad_frame_set_reg_addr (this_cache, SPARC32_PC_REGNUM, base + 4);
- trad_frame_set_reg_addr (this_cache, SPARC32_NPC_REGNUM, base + 8);
- trad_frame_set_reg_addr (this_cache, SPARC32_Y_REGNUM, base + 12);
-
- addr = base + 20;
- sp_addr = base + 16 + ((SPARC_SP_REGNUM - SPARC_G0_REGNUM) * 4);
- for (regnum = SPARC_G1_REGNUM; regnum <= SPARC_O7_REGNUM; regnum++)
- {
- trad_frame_set_reg_addr (this_cache, regnum, addr);
- addr += 4;
- }
- base = get_frame_register_unsigned (this_frame, SPARC_SP_REGNUM);
- addr = get_frame_memory_unsigned (this_frame, sp_addr, 4);
- for (regnum = SPARC_L0_REGNUM; regnum <= SPARC_I7_REGNUM; regnum++)
- {
- trad_frame_set_reg_addr (this_cache, regnum, addr);
- addr += 4;
- }
- trad_frame_set_id (this_cache, frame_id_build (base, func));
- }
- static CORE_ADDR
- sparc32_linux_step_trap (struct frame_info *frame, unsigned long insn)
- {
- if (insn == 0x91d02010)
- {
- ULONGEST sc_num = get_frame_register_unsigned (frame, SPARC_G1_REGNUM);
-
- if (sc_num == 101 || sc_num == 216)
- {
- struct gdbarch *gdbarch = get_frame_arch (frame);
- enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
- ULONGEST sp, pc_offset;
- sp = get_frame_register_unsigned (frame, SPARC_SP_REGNUM);
-
- pc_offset = 96 + 4;
- if (sc_num == 101)
- pc_offset += 128;
- return read_memory_unsigned_integer (sp + pc_offset, 4, byte_order);
- }
- }
- return 0;
- }
- const struct sparc_gregmap sparc32_linux_core_gregmap =
- {
- 32 * 4,
- 33 * 4,
- 34 * 4,
- 35 * 4,
- -1,
- -1,
- 1 * 4,
- 16 * 4,
- 4,
- };
- static void
- sparc32_linux_supply_core_gregset (const struct regset *regset,
- struct regcache *regcache,
- int regnum, const void *gregs, size_t len)
- {
- sparc32_supply_gregset (&sparc32_linux_core_gregmap,
- regcache, regnum, gregs);
- }
- static void
- sparc32_linux_collect_core_gregset (const struct regset *regset,
- const struct regcache *regcache,
- int regnum, void *gregs, size_t len)
- {
- sparc32_collect_gregset (&sparc32_linux_core_gregmap,
- regcache, regnum, gregs);
- }
- static void
- sparc32_linux_supply_core_fpregset (const struct regset *regset,
- struct regcache *regcache,
- int regnum, const void *fpregs, size_t len)
- {
- sparc32_supply_fpregset (&sparc32_bsd_fpregmap, regcache, regnum, fpregs);
- }
- static void
- sparc32_linux_collect_core_fpregset (const struct regset *regset,
- const struct regcache *regcache,
- int regnum, void *fpregs, size_t len)
- {
- sparc32_collect_fpregset (&sparc32_bsd_fpregmap, regcache, regnum, fpregs);
- }
- #define PSR_SYSCALL 0x00004000
- static void
- sparc_linux_write_pc (struct regcache *regcache, CORE_ADDR pc)
- {
- struct gdbarch_tdep *tdep = gdbarch_tdep (get_regcache_arch (regcache));
- ULONGEST psr;
- regcache_cooked_write_unsigned (regcache, tdep->pc_regnum, pc);
- regcache_cooked_write_unsigned (regcache, tdep->npc_regnum, pc + 4);
-
- regcache_cooked_read_unsigned (regcache, SPARC32_PSR_REGNUM, &psr);
- psr &= ~PSR_SYSCALL;
- regcache_cooked_write_unsigned (regcache, SPARC32_PSR_REGNUM, psr);
- }
- static LONGEST
- sparc32_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[4];
-
- LONGEST ret;
-
- regcache_cooked_read (regcache, SPARC_G1_REGNUM, buf);
- ret = extract_signed_integer (buf, 4, byte_order);
- return ret;
- }
- static enum gdb_signal
- sparc32_linux_gdb_signal_from_target (struct gdbarch *gdbarch,
- int signal)
- {
- switch (signal)
- {
- case SPARC_LINUX_SIGEMT:
- return GDB_SIGNAL_EMT;
- case SPARC_LINUX_SIGBUS:
- return GDB_SIGNAL_BUS;
- case SPARC_LINUX_SIGSYS:
- return GDB_SIGNAL_SYS;
- case SPARC_LINUX_SIGURG:
- return GDB_SIGNAL_URG;
- case SPARC_LINUX_SIGSTOP:
- return GDB_SIGNAL_STOP;
- case SPARC_LINUX_SIGTSTP:
- return GDB_SIGNAL_TSTP;
- case SPARC_LINUX_SIGCONT:
- return GDB_SIGNAL_CONT;
- case SPARC_LINUX_SIGCHLD:
- return GDB_SIGNAL_CHLD;
-
- case SPARC_LINUX_SIGIO:
- return GDB_SIGNAL_IO;
-
- case SPARC_LINUX_SIGLOST:
- return GDB_SIGNAL_LOST;
- case SPARC_LINUX_SIGUSR1:
- return GDB_SIGNAL_USR1;
- case SPARC_LINUX_SIGUSR2:
- return GDB_SIGNAL_USR2;
- }
- return linux_gdb_signal_from_target (gdbarch, signal);
- }
- static int
- sparc32_linux_gdb_signal_to_target (struct gdbarch *gdbarch,
- enum gdb_signal signal)
- {
- switch (signal)
- {
- case GDB_SIGNAL_EMT:
- return SPARC_LINUX_SIGEMT;
- case GDB_SIGNAL_BUS:
- return SPARC_LINUX_SIGBUS;
- case GDB_SIGNAL_SYS:
- return SPARC_LINUX_SIGSYS;
- case GDB_SIGNAL_URG:
- return SPARC_LINUX_SIGURG;
- case GDB_SIGNAL_STOP:
- return SPARC_LINUX_SIGSTOP;
- case GDB_SIGNAL_TSTP:
- return SPARC_LINUX_SIGTSTP;
- case GDB_SIGNAL_CONT:
- return SPARC_LINUX_SIGCONT;
- case GDB_SIGNAL_CHLD:
- return SPARC_LINUX_SIGCHLD;
- case GDB_SIGNAL_IO:
- return SPARC_LINUX_SIGIO;
- case GDB_SIGNAL_POLL:
- return SPARC_LINUX_SIGPOLL;
- case GDB_SIGNAL_LOST:
- return SPARC_LINUX_SIGLOST;
- case GDB_SIGNAL_PWR:
- return SPARC_LINUX_SIGPWR;
- case GDB_SIGNAL_USR1:
- return SPARC_LINUX_SIGUSR1;
- case GDB_SIGNAL_USR2:
- return SPARC_LINUX_SIGUSR2;
- }
- return linux_gdb_signal_to_target (gdbarch, signal);
- }
- static const struct regset sparc32_linux_gregset =
- {
- NULL,
- sparc32_linux_supply_core_gregset,
- sparc32_linux_collect_core_gregset
- };
- static const struct regset sparc32_linux_fpregset =
- {
- NULL,
- sparc32_linux_supply_core_fpregset,
- sparc32_linux_collect_core_fpregset
- };
- static void
- sparc32_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
- {
- struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
- linux_init_abi (info, gdbarch);
- tdep->gregset = &sparc32_linux_gregset;
- tdep->sizeof_gregset = 152;
- tdep->fpregset = &sparc32_linux_fpregset;
- tdep->sizeof_fpregset = 396;
- tramp_frame_prepend_unwinder (gdbarch, &sparc32_linux_sigframe);
- tramp_frame_prepend_unwinder (gdbarch, &sparc32_linux_rt_sigframe);
-
- set_gdbarch_skip_trampoline_code (gdbarch, find_solib_trampoline_target);
- set_solib_svr4_fetch_link_map_offsets
- (gdbarch, svr4_ilp32_fetch_link_map_offsets);
-
- tdep->plt_entry_size = 12;
-
- set_gdbarch_fetch_tls_load_module_address (gdbarch,
- svr4_fetch_objfile_link_map);
-
- tdep->step_trap = sparc32_linux_step_trap;
-
- dwarf2_append_unwinders (gdbarch);
- set_gdbarch_write_pc (gdbarch, sparc_linux_write_pc);
-
- set_xml_syscall_file_name (gdbarch, XML_SYSCALL_FILENAME_SPARC32);
- set_gdbarch_get_syscall_number (gdbarch,
- sparc32_linux_get_syscall_number);
- set_gdbarch_gdb_signal_from_target (gdbarch,
- sparc32_linux_gdb_signal_from_target);
- set_gdbarch_gdb_signal_to_target (gdbarch,
- sparc32_linux_gdb_signal_to_target);
- }
- extern void _initialize_sparc_linux_tdep (void);
- void
- _initialize_sparc_linux_tdep (void)
- {
- gdbarch_register_osabi (bfd_arch_sparc, 0, GDB_OSABI_LINUX,
- sparc32_linux_init_abi);
- }