X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=gdb%2Fppc-linux-nat.c;h=40ea5893664bb717cdad749c7ecdd99412d60ca6;hb=2f91880f3afb3cc521111dfcc99b214c77aa97a1;hp=8d57b9d89d581858ae26ee7ca0d845ae7a9beb6a;hpb=ecd75fc8eed3bde86036141228074a20e55dcfc9;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/ppc-linux-nat.c b/gdb/ppc-linux-nat.c index 8d57b9d89d..40ea589366 100644 --- a/gdb/ppc-linux-nat.c +++ b/gdb/ppc-linux-nat.c @@ -1,6 +1,6 @@ /* PPC GNU/Linux native support. - Copyright (C) 1988-2014 Free Software Foundation, Inc. + Copyright (C) 1988-2017 Free Software Foundation, Inc. This file is part of GDB. @@ -18,18 +18,14 @@ along with this program. If not, see . */ #include "defs.h" -#include #include "observer.h" #include "frame.h" #include "inferior.h" #include "gdbthread.h" #include "gdbcore.h" #include "regcache.h" -#include "gdb_assert.h" #include "target.h" #include "linux-nat.h" - -#include #include #include #include @@ -37,7 +33,8 @@ #include "gdb_wait.h" #include #include -#include +#include "nat/gdb_ptrace.h" +#include "inf-ptrace.h" /* Prototypes for supply_gregset etc. */ #include "gregset.h" @@ -48,57 +45,7 @@ #include "elf/common.h" #include "auxv.h" -/* This sometimes isn't defined. */ -#ifndef PT_ORIG_R3 -#define PT_ORIG_R3 34 -#endif -#ifndef PT_TRAP -#define PT_TRAP 40 -#endif - -/* The PPC_FEATURE_* defines should be provided by . - If they aren't, we can provide them ourselves (their values are fixed - because they are part of the kernel ABI). They are used in the AT_HWCAP - entry of the AUXV. */ -#ifndef PPC_FEATURE_CELL -#define PPC_FEATURE_CELL 0x00010000 -#endif -#ifndef PPC_FEATURE_BOOKE -#define PPC_FEATURE_BOOKE 0x00008000 -#endif -#ifndef PPC_FEATURE_HAS_DFP -#define PPC_FEATURE_HAS_DFP 0x00000400 /* Decimal Floating Point. */ -#endif - -/* Glibc's headers don't define PTRACE_GETVRREGS so we cannot use a - configure time check. Some older glibc's (for instance 2.2.1) - don't have a specific powerpc version of ptrace.h, and fall back on - a generic one. In such cases, sys/ptrace.h defines - PTRACE_GETFPXREGS and PTRACE_SETFPXREGS to the same numbers that - ppc kernel's asm/ptrace.h defines PTRACE_GETVRREGS and - PTRACE_SETVRREGS to be. This also makes a configury check pretty - much useless. */ - -/* These definitions should really come from the glibc header files, - but Glibc doesn't know about the vrregs yet. */ -#ifndef PTRACE_GETVRREGS -#define PTRACE_GETVRREGS 18 -#define PTRACE_SETVRREGS 19 -#endif - -/* PTRACE requests for POWER7 VSX registers. */ -#ifndef PTRACE_GETVSXREGS -#define PTRACE_GETVSXREGS 27 -#define PTRACE_SETVSXREGS 28 -#endif - -/* Similarly for the ptrace requests for getting / setting the SPE - registers (ev0 -- ev31, acc, and spefscr). See the description of - gdb_evrregset_t for details. */ -#ifndef PTRACE_GETEVRREGS -#define PTRACE_GETEVRREGS 20 -#define PTRACE_SETEVRREGS 21 -#endif +#include "nat/ppc-linux.h" /* Similarly for the hardware watchpoint support. These requests are used when the PowerPC HWDEBUG ptrace interface is not available. */ @@ -550,7 +497,7 @@ fetch_register (struct regcache *regcache, int tid, int regno) CORE_ADDR regaddr = ppc_register_u_addr (gdbarch, regno); int bytes_transferred; unsigned int offset; /* Offset of registers within the u area. */ - gdb_byte buf[MAX_REGISTER_SIZE]; + gdb_byte buf[PPC_MAX_REGISTER_SIZE]; if (altivec_register_p (gdbarch, regno)) { @@ -863,12 +810,7 @@ static void ppc_linux_fetch_inferior_registers (struct target_ops *ops, struct regcache *regcache, int regno) { - /* Overload thread id onto process id. */ - int tid = ptid_get_lwp (inferior_ptid); - - /* No thread id, just use process id. */ - if (tid == 0) - tid = ptid_get_pid (inferior_ptid); + pid_t tid = get_ptrace_pid (regcache_get_ptid (regcache)); if (regno == -1) fetch_ppc_registers (regcache, tid); @@ -1037,7 +979,7 @@ store_register (const struct regcache *regcache, int tid, int regno) CORE_ADDR regaddr = ppc_register_u_addr (gdbarch, regno); int i; size_t bytes_to_transfer; - gdb_byte buf[MAX_REGISTER_SIZE]; + gdb_byte buf[PPC_MAX_REGISTER_SIZE]; if (altivec_register_p (gdbarch, regno)) { @@ -1444,7 +1386,8 @@ have_ptrace_hwdebug_interface (void) } static int -ppc_linux_can_use_hw_breakpoint (int type, int cnt, int ot) +ppc_linux_can_use_hw_breakpoint (struct target_ops *self, + enum bptype type, int cnt, int ot) { int total_hw_wp, total_hw_bp; @@ -1472,6 +1415,11 @@ ppc_linux_can_use_hw_breakpoint (int type, int cnt, int ot) } else if (type == bp_hardware_breakpoint) { + if (total_hw_bp == 0) + { + /* No hardware breakpoint support. */ + return 0; + } if (cnt > total_hw_bp) return -1; } @@ -1496,7 +1444,8 @@ ppc_linux_can_use_hw_breakpoint (int type, int cnt, int ot) } static int -ppc_linux_region_ok_for_hw_watchpoint (CORE_ADDR addr, int len) +ppc_linux_region_ok_for_hw_watchpoint (struct target_ops *self, + CORE_ADDR addr, int len) { /* Handle sub-8-byte quantities. */ if (len <= 0) @@ -1575,9 +1524,8 @@ hwdebug_find_thread_points_by_tid (int tid, int alloc_new) if the wanted one does not exist? */ if (alloc_new) { - t = xmalloc (sizeof (struct thread_points)); - t->hw_breaks - = xzalloc (max_slots_number * sizeof (struct hw_break_tuple)); + t = XNEW (struct thread_points); + t->hw_breaks = XCNEWVEC (struct hw_break_tuple, max_slots_number); t->tid = tid; VEC_safe_push (thread_points_p, ppc_threads, t); } @@ -1593,7 +1541,7 @@ hwdebug_insert_point (struct ppc_hw_breakpoint *b, int tid) { int i; long slot; - struct ppc_hw_breakpoint *p = xmalloc (sizeof (struct ppc_hw_breakpoint)); + struct ppc_hw_breakpoint *p = XNEW (struct ppc_hw_breakpoint); struct hw_break_tuple *hw_breaks; struct cleanup *c = make_cleanup (xfree, p); struct thread_points *t; @@ -1672,7 +1620,8 @@ ppc_linux_ranged_break_num_registers (struct target_ops *target) success, 1 if hardware breakpoints are not supported or -1 for failure. */ static int -ppc_linux_insert_hw_breakpoint (struct gdbarch *gdbarch, +ppc_linux_insert_hw_breakpoint (struct target_ops *self, + struct gdbarch *gdbarch, struct bp_target_info *bp_tgt) { struct lwp_info *lp; @@ -1684,7 +1633,7 @@ ppc_linux_insert_hw_breakpoint (struct gdbarch *gdbarch, p.version = PPC_DEBUG_CURRENT_VERSION; p.trigger_type = PPC_BREAKPOINT_TRIGGER_EXECUTE; p.condition_mode = PPC_BREAKPOINT_CONDITION_NONE; - p.addr = (uint64_t) bp_tgt->placed_address; + p.addr = (uint64_t) (bp_tgt->placed_address = bp_tgt->reqstd_address); p.condition_value = 0; if (bp_tgt->length) @@ -1708,7 +1657,8 @@ ppc_linux_insert_hw_breakpoint (struct gdbarch *gdbarch, } static int -ppc_linux_remove_hw_breakpoint (struct gdbarch *gdbarch, +ppc_linux_remove_hw_breakpoint (struct target_ops *self, + struct gdbarch *gdbarch, struct bp_target_info *bp_tgt) { struct lwp_info *lp; @@ -1744,13 +1694,13 @@ ppc_linux_remove_hw_breakpoint (struct gdbarch *gdbarch, } static int -get_trigger_type (int rw) +get_trigger_type (enum target_hw_bp_type type) { int t; - if (rw == hw_read) + if (type == hw_read) t = PPC_BREAKPOINT_TRIGGER_READ; - else if (rw == hw_write) + else if (type == hw_write) t = PPC_BREAKPOINT_TRIGGER_WRITE; else t = PPC_BREAKPOINT_TRIGGER_READ | PPC_BREAKPOINT_TRIGGER_WRITE; @@ -1765,7 +1715,7 @@ get_trigger_type (int rw) static int ppc_linux_insert_mask_watchpoint (struct target_ops *ops, CORE_ADDR addr, - CORE_ADDR mask, int rw) + CORE_ADDR mask, enum target_hw_bp_type rw) { struct lwp_info *lp; struct ppc_hw_breakpoint p; @@ -1793,7 +1743,7 @@ ppc_linux_insert_mask_watchpoint (struct target_ops *ops, CORE_ADDR addr, static int ppc_linux_remove_mask_watchpoint (struct target_ops *ops, CORE_ADDR addr, - CORE_ADDR mask, int rw) + CORE_ADDR mask, enum target_hw_bp_type rw) { struct lwp_info *lp; struct ppc_hw_breakpoint p; @@ -2011,7 +1961,8 @@ check_condition (CORE_ADDR watch_addr, struct expression *cond, the condition expression, thus only triggering the watchpoint when it is true. */ static int -ppc_linux_can_accel_watchpoint_condition (CORE_ADDR addr, int len, int rw, +ppc_linux_can_accel_watchpoint_condition (struct target_ops *self, + CORE_ADDR addr, int len, int rw, struct expression *cond) { CORE_ADDR data_value; @@ -2028,8 +1979,8 @@ ppc_linux_can_accel_watchpoint_condition (CORE_ADDR addr, int len, int rw, static void create_watchpoint_request (struct ppc_hw_breakpoint *p, CORE_ADDR addr, - int len, int rw, struct expression *cond, - int insert) + int len, enum target_hw_bp_type type, + struct expression *cond, int insert) { if (len == 1 || !(hwdebug_info.features & PPC_DEBUG_FEATURE_DATA_BP_RANGE)) @@ -2068,12 +2019,13 @@ create_watchpoint_request (struct ppc_hw_breakpoint *p, CORE_ADDR addr, } p->version = PPC_DEBUG_CURRENT_VERSION; - p->trigger_type = get_trigger_type (rw); + p->trigger_type = get_trigger_type (type); p->addr = (uint64_t) addr; } static int -ppc_linux_insert_watchpoint (CORE_ADDR addr, int len, int rw, +ppc_linux_insert_watchpoint (struct target_ops *self, CORE_ADDR addr, int len, + enum target_hw_bp_type type, struct expression *cond) { struct lwp_info *lp; @@ -2083,7 +2035,7 @@ ppc_linux_insert_watchpoint (CORE_ADDR addr, int len, int rw, { struct ppc_hw_breakpoint p; - create_watchpoint_request (&p, addr, len, rw, cond, 1); + create_watchpoint_request (&p, addr, len, type, cond, 1); ALL_LWPS (lp) hwdebug_insert_point (&p, ptid_get_lwp (lp->ptid)); @@ -2111,7 +2063,7 @@ ppc_linux_insert_watchpoint (CORE_ADDR addr, int len, int rw, } dabr_value = addr & ~(read_mode | write_mode); - switch (rw) + switch (type) { case hw_read: /* Set read and translate bits. */ @@ -2141,7 +2093,8 @@ ppc_linux_insert_watchpoint (CORE_ADDR addr, int len, int rw, } static int -ppc_linux_remove_watchpoint (CORE_ADDR addr, int len, int rw, +ppc_linux_remove_watchpoint (struct target_ops *self, CORE_ADDR addr, int len, + enum target_hw_bp_type type, struct expression *cond) { struct lwp_info *lp; @@ -2151,7 +2104,7 @@ ppc_linux_remove_watchpoint (CORE_ADDR addr, int len, int rw, { struct ppc_hw_breakpoint p; - create_watchpoint_request (&p, addr, len, rw, cond, 0); + create_watchpoint_request (&p, addr, len, type, cond, 0); ALL_LWPS (lp) hwdebug_remove_point (&p, ptid_get_lwp (lp->ptid)); @@ -2283,10 +2236,10 @@ ppc_linux_stopped_data_address (struct target_ops *target, CORE_ADDR *addr_p) } static int -ppc_linux_stopped_by_watchpoint (void) +ppc_linux_stopped_by_watchpoint (struct target_ops *ops) { CORE_ADDR addr; - return ppc_linux_stopped_data_address (¤t_target, &addr); + return ppc_linux_stopped_data_address (ops, &addr); } static int @@ -2334,12 +2287,7 @@ static void ppc_linux_store_inferior_registers (struct target_ops *ops, struct regcache *regcache, int regno) { - /* Overload thread id onto process id. */ - int tid = ptid_get_lwp (inferior_ptid); - - /* No thread id, just use process id. */ - if (tid == 0) - tid = ptid_get_pid (inferior_ptid); + pid_t tid = get_ptrace_pid (regcache_get_ptid (regcache)); if (regno >= 0) store_register (regcache, tid, regno); @@ -2407,7 +2355,7 @@ ppc_linux_target_wordsize (void) errno = 0; msr = (long) ptrace (PTRACE_PEEKUSER, tid, PT_MSR * 8, 0); - if (errno == 0 && msr < 0) + if (errno == 0 && ppc64_64bit_inferior_p (msr)) wordsize = 8; #endif @@ -2462,7 +2410,8 @@ ppc_linux_read_description (struct target_ops *ops) perror_with_name (_("Unable to fetch SPE registers")); } - if (have_ptrace_getsetvsxregs) + if (have_ptrace_getsetvsxregs + && (ppc_linux_get_hwcap () & PPC_FEATURE_HAS_VSX)) { gdb_vsxregset_t vsxregset; @@ -2475,7 +2424,8 @@ ppc_linux_read_description (struct target_ops *ops) perror_with_name (_("Unable to fetch VSX registers")); } - if (have_ptrace_getvrregs) + if (have_ptrace_getvrregs + && (ppc_linux_get_hwcap () & PPC_FEATURE_HAS_ALTIVEC)) { gdb_vrregset_t vrregset;