X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=gdb%2Fgdbserver%2Flinux-sparc-low.c;h=5a601ee304c8f3d8ccddd45337dbd5c738265219;hb=4c5aa8e0b1b4439f73ef1f82344e408b989f85df;hp=dc9c0ccad88035eeff29ef960755ff1b4e4c8fa6;hpb=1faeff088bbbd037d7769d214378b4faf805fa2e;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/gdbserver/linux-sparc-low.c b/gdb/gdbserver/linux-sparc-low.c index dc9c0ccad8..5a601ee304 100644 --- a/gdb/gdbserver/linux-sparc-low.c +++ b/gdb/gdbserver/linux-sparc-low.c @@ -1,5 +1,5 @@ /* Low level interface to ptrace, for the remote server for GDB. - Copyright (C) 1995-1996, 1998-2012 Free Software Foundation, Inc. + Copyright (C) 1995-2019 Free Software Foundation, Inc. This file is part of GDB. @@ -19,7 +19,7 @@ #include "server.h" #include "linux-low.h" -#include +#include "nat/gdb_ptrace.h" #include "gdb_proc_service.h" @@ -100,6 +100,7 @@ static const struct regs_range_t fpregs_ranges[] = { /* Defined in auto-generated file reg-sparc64.c. */ void init_registers_sparc64 (void); +extern const struct target_desc *tdesc_sparc64; static int sparc_cannot_store_register (int regno) @@ -119,19 +120,21 @@ sparc_fill_gregset_to_stack (struct regcache *regcache, const void *buf) int i; CORE_ADDR addr = 0; unsigned char tmp_reg_buf[8]; - const int l0_regno = find_regno("l0"); + const int l0_regno = find_regno (regcache->tdesc, "l0"); const int i7_regno = l0_regno + 15; /* These registers have to be stored in the stack. */ - memcpy(&addr, ((char *) buf) + sparc_regmap[find_regno("sp")], sizeof(addr)); + memcpy (&addr, + ((char *) buf) + sparc_regmap[find_regno (regcache->tdesc, "sp")], + sizeof (addr)); addr += BIAS; for (i = l0_regno; i <= i7_regno; i++) { collect_register (regcache, i, tmp_reg_buf); - (*the_target->write_memory) (addr, tmp_reg_buf, sizeof(tmp_reg_buf)); - addr += sizeof(tmp_reg_buf); + (*the_target->write_memory) (addr, tmp_reg_buf, sizeof (tmp_reg_buf)); + addr += sizeof (tmp_reg_buf); } } @@ -169,19 +172,21 @@ sparc_store_gregset_from_stack (struct regcache *regcache, const void *buf) int i; CORE_ADDR addr = 0; unsigned char tmp_reg_buf[8]; - const int l0_regno = find_regno("l0"); + const int l0_regno = find_regno (regcache->tdesc, "l0"); const int i7_regno = l0_regno + 15; /* These registers have to be obtained from the stack. */ - memcpy(&addr, ((char *) buf) + sparc_regmap[find_regno("sp")], sizeof(addr)); + memcpy (&addr, + ((char *) buf) + sparc_regmap[find_regno (regcache->tdesc, "sp")], + sizeof (addr)); addr += BIAS; for (i = l0_regno; i <= i7_regno; i++) { - (*the_target->read_memory) (addr, tmp_reg_buf, sizeof(tmp_reg_buf)); + (*the_target->read_memory) (addr, tmp_reg_buf, sizeof (tmp_reg_buf)); supply_register (regcache, i, tmp_reg_buf); - addr += sizeof(tmp_reg_buf); + addr += sizeof (tmp_reg_buf); } } @@ -192,7 +197,7 @@ sparc_store_gregset (struct regcache *regcache, const void *buf) char zerobuf[8]; int range; - memset (zerobuf, 0, sizeof(zerobuf)); + memset (zerobuf, 0, sizeof (zerobuf)); for (range = 0; range < N_GREGS_RANGES; range++) for (i = gregs_ranges[range].regno_start; @@ -218,32 +223,28 @@ sparc_store_fpregset (struct regcache *regcache, const void *buf) supply_register (regcache, i, ((char *) buf) + sparc_regmap[i]); } -extern int debug_threads; - -static CORE_ADDR -sparc_get_pc (struct regcache *regcache) -{ - unsigned long pc; - collect_register_by_name (regcache, "pc", &pc); - if (debug_threads) - fprintf (stderr, "stop pc is %08lx\n", pc); - return pc; -} - -static const unsigned char sparc_breakpoint[INSN_SIZE] = { +static const gdb_byte sparc_breakpoint[INSN_SIZE] = { 0x91, 0xd0, 0x20, 0x01 }; #define sparc_breakpoint_len INSN_SIZE +/* Implementation of linux_target_ops method "sw_breakpoint_from_kind". */ + +static const unsigned char * +sparc_sw_breakpoint_from_kind (int kind, int *size) +{ + *size = sparc_breakpoint_len; + return sparc_breakpoint; +} static int sparc_breakpoint_at (CORE_ADDR where) { unsigned char insn[INSN_SIZE]; - (*the_target->read_memory) (where, (unsigned char *) insn, sizeof(insn)); + (*the_target->read_memory) (where, (unsigned char *) insn, sizeof (insn)); - if (memcmp(sparc_breakpoint, insn, sizeof(insn)) == 0) + if (memcmp (sparc_breakpoint, insn, sizeof (insn)) == 0) return 1; /* If necessary, recognize more trap instructions here. GDB only @@ -252,46 +253,74 @@ sparc_breakpoint_at (CORE_ADDR where) return 0; } -/* We only place breakpoints in empty marker functions, and thread locking - is outside of the function. So rather than importing software single-step, - we can just run until exit. */ -static CORE_ADDR -sparc_reinsert_addr (void) +static void +sparc_arch_setup (void) { - struct regcache *regcache = get_thread_regcache (current_inferior, 1); - CORE_ADDR lr; - /* O7 is the equivalent to the 'lr' of other archs. */ - collect_register_by_name (regcache, "o7", &lr); - return lr; + current_process ()->tdesc = tdesc_sparc64; } - -struct regset_info target_regsets[] = { +static struct regset_info sparc_regsets[] = { { PTRACE_GETREGS, PTRACE_SETREGS, 0, sizeof (elf_gregset_t), GENERAL_REGS, sparc_fill_gregset, sparc_store_gregset }, { PTRACE_GETFPREGS, PTRACE_SETFPREGS, 0, sizeof (fpregset_t), FP_REGS, sparc_fill_fpregset, sparc_store_fpregset }, - { 0, 0, 0, -1, -1, NULL, NULL } + NULL_REGSET }; +static struct regsets_info sparc_regsets_info = + { + sparc_regsets, /* regsets */ + 0, /* num_regsets */ + NULL, /* disabled_regsets */ + }; + +static struct usrregs_info sparc_usrregs_info = + { + sparc_num_regs, + /* No regmap needs to be provided since this impl. doesn't use + USRREGS. */ + NULL + }; + +static struct regs_info regs_info = + { + NULL, /* regset_bitmap */ + &sparc_usrregs_info, + &sparc_regsets_info + }; + +static const struct regs_info * +sparc_regs_info (void) +{ + return ®s_info; +} + struct linux_target_ops the_low_target = { - init_registers_sparc64, - sparc_num_regs, - /* No regmap needs to be provided since this impl. doesn't use USRREGS. */ - NULL, - NULL, + sparc_arch_setup, + sparc_regs_info, sparc_cannot_fetch_register, sparc_cannot_store_register, - sparc_get_pc, + NULL, /* fetch_register */ + linux_get_pc_64bit, /* No sparc_set_pc is needed. */ NULL, - (const unsigned char *) sparc_breakpoint, - sparc_breakpoint_len, - sparc_reinsert_addr, + NULL, /* breakpoint_kind_from_pc */ + sparc_sw_breakpoint_from_kind, + NULL, /* get_next_pcs */ 0, sparc_breakpoint_at, + NULL, /* supports_z_point_type */ NULL, NULL, NULL, NULL, NULL, NULL }; + +void +initialize_low_arch (void) +{ + /* Initialize the Linux target descriptions. */ + init_registers_sparc64 (); + + initialize_regsets_info (&sparc_regsets_info); +}