X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=gdb%2Fppc-linux-nat.c;h=84c14a1ae9efdd381748e704404d84e8afb93108;hb=0154d99053a95392380cd4629a89b0ac46df3737;hp=eb0ccc6c7f36dff7e492945e2473a2c323dd36aa;hpb=a64dc96c258bcb9d5dc19b9470491cd7da5051b3;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/ppc-linux-nat.c b/gdb/ppc-linux-nat.c index eb0ccc6c7f..84c14a1ae9 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-2016 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,7 @@ #include "gdb_wait.h" #include #include -#include +#include "nat/gdb_ptrace.h" /* Prototypes for supply_gregset etc. */ #include "gregset.h" @@ -48,57 +44,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. */ @@ -1445,7 +1391,7 @@ have_ptrace_hwdebug_interface (void) static int ppc_linux_can_use_hw_breakpoint (struct target_ops *self, - int type, int cnt, int ot) + enum bptype type, int cnt, int ot) { int total_hw_wp, total_hw_bp; @@ -1473,6 +1419,11 @@ ppc_linux_can_use_hw_breakpoint (struct target_ops *self, } else if (type == bp_hardware_breakpoint) { + if (total_hw_bp == 0) + { + /* No hardware breakpoint support. */ + return 0; + } if (cnt > total_hw_bp) return -1; } @@ -1497,7 +1448,8 @@ ppc_linux_can_use_hw_breakpoint (struct target_ops *self, } 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) @@ -1576,9 +1528,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); } @@ -1594,7 +1545,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; @@ -1686,7 +1637,7 @@ ppc_linux_insert_hw_breakpoint (struct target_ops *self, 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) @@ -1747,13 +1698,13 @@ ppc_linux_remove_hw_breakpoint (struct target_ops *self, } 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; @@ -1768,7 +1719,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; @@ -1796,7 +1747,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; @@ -2014,7 +1965,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; @@ -2031,8 +1983,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)) @@ -2071,12 +2023,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; @@ -2086,7 +2039,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)); @@ -2114,7 +2067,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. */ @@ -2144,7 +2097,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; @@ -2154,7 +2108,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)); @@ -2410,7 +2364,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 @@ -2465,7 +2419,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; @@ -2478,7 +2433,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;