/* PPC GNU/Linux native support.
- Copyright (C) 1988-2016 Free Software Foundation, Inc.
+ Copyright (C) 1988-2018 Free Software Foundation, Inc.
This file is part of GDB.
along with this program. If not, see <http://www.gnu.org/licenses/>. */
#include "defs.h"
-#include "observer.h"
+#include "observable.h"
#include "frame.h"
#include "inferior.h"
#include "gdbthread.h"
#include <fcntl.h>
#include <sys/procfs.h>
#include "nat/gdb_ptrace.h"
+#include "inf-ptrace.h"
/* Prototypes for supply_gregset etc. */
#include "gregset.h"
{
int ret;
gdb_vsxregset_t regs;
- struct gdbarch *gdbarch = get_regcache_arch (regcache);
+ struct gdbarch *gdbarch = regcache->arch ();
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
int vsxregsize = register_size (gdbarch, tdep->ppc_vsr0_upper_regnum);
int ret;
int offset = 0;
gdb_vrregset_t regs;
- struct gdbarch *gdbarch = get_regcache_arch (regcache);
+ struct gdbarch *gdbarch = regcache->arch ();
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
int vrregsize = register_size (gdbarch, tdep->ppc_vr0_regnum);
static void
fetch_spe_register (struct regcache *regcache, int tid, int regno)
{
- struct gdbarch *gdbarch = get_regcache_arch (regcache);
+ struct gdbarch *gdbarch = regcache->arch ();
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
struct gdb_evrregset_t evrregs;
static void
fetch_register (struct regcache *regcache, int tid, int regno)
{
- struct gdbarch *gdbarch = get_regcache_arch (regcache);
+ struct gdbarch *gdbarch = regcache->arch ();
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
/* This isn't really an address. But ptrace thinks of it as one. */
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))
{
supply_vsxregset (struct regcache *regcache, gdb_vsxregset_t *vsxregsetp)
{
int i;
- struct gdbarch *gdbarch = get_regcache_arch (regcache);
+ struct gdbarch *gdbarch = regcache->arch ();
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
int vsxregsize = register_size (gdbarch, tdep->ppc_vsr0_upper_regnum);
supply_vrregset (struct regcache *regcache, gdb_vrregset_t *vrregsetp)
{
int i;
- struct gdbarch *gdbarch = get_regcache_arch (regcache);
+ struct gdbarch *gdbarch = regcache->arch ();
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
int num_of_vrregs = tdep->ppc_vrsave_regnum - tdep->ppc_vr0_regnum + 1;
int vrregsize = register_size (gdbarch, tdep->ppc_vr0_regnum);
static int
fetch_all_gp_regs (struct regcache *regcache, int tid)
{
- struct gdbarch *gdbarch = get_regcache_arch (regcache);
+ struct gdbarch *gdbarch = regcache->arch ();
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
gdb_gregset_t gregset;
static void
fetch_gp_regs (struct regcache *regcache, int tid)
{
- struct gdbarch *gdbarch = get_regcache_arch (regcache);
+ struct gdbarch *gdbarch = regcache->arch ();
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
int i;
static void
fetch_fp_regs (struct regcache *regcache, int tid)
{
- struct gdbarch *gdbarch = get_regcache_arch (regcache);
+ struct gdbarch *gdbarch = regcache->arch ();
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
int i;
fetch_ppc_registers (struct regcache *regcache, int tid)
{
int i;
- struct gdbarch *gdbarch = get_regcache_arch (regcache);
+ struct gdbarch *gdbarch = regcache->arch ();
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
fetch_gp_regs (regcache, tid);
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);
{
int ret;
gdb_vsxregset_t regs;
- struct gdbarch *gdbarch = get_regcache_arch (regcache);
+ struct gdbarch *gdbarch = regcache->arch ();
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
int vsxregsize = register_size (gdbarch, tdep->ppc_vsr0_upper_regnum);
int ret;
int offset = 0;
gdb_vrregset_t regs;
- struct gdbarch *gdbarch = get_regcache_arch (regcache);
+ struct gdbarch *gdbarch = regcache->arch ();
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
int vrregsize = register_size (gdbarch, tdep->ppc_vr0_regnum);
static void
store_spe_register (const struct regcache *regcache, int tid, int regno)
{
- struct gdbarch *gdbarch = get_regcache_arch (regcache);
+ struct gdbarch *gdbarch = regcache->arch ();
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
struct gdb_evrregset_t evrregs;
static void
store_register (const struct regcache *regcache, int tid, int regno)
{
- struct gdbarch *gdbarch = get_regcache_arch (regcache);
+ struct gdbarch *gdbarch = regcache->arch ();
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
/* This isn't really an address. But ptrace thinks of it as one. */
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))
{
fill_vsxregset (const struct regcache *regcache, gdb_vsxregset_t *vsxregsetp)
{
int i;
- struct gdbarch *gdbarch = get_regcache_arch (regcache);
+ struct gdbarch *gdbarch = regcache->arch ();
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
int vsxregsize = register_size (gdbarch, tdep->ppc_vsr0_upper_regnum);
fill_vrregset (const struct regcache *regcache, gdb_vrregset_t *vrregsetp)
{
int i;
- struct gdbarch *gdbarch = get_regcache_arch (regcache);
+ struct gdbarch *gdbarch = regcache->arch ();
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
int num_of_vrregs = tdep->ppc_vrsave_regnum - tdep->ppc_vr0_regnum + 1;
int vrregsize = register_size (gdbarch, tdep->ppc_vr0_regnum);
static int
store_all_gp_regs (const struct regcache *regcache, int tid, int regno)
{
- struct gdbarch *gdbarch = get_regcache_arch (regcache);
+ struct gdbarch *gdbarch = regcache->arch ();
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
gdb_gregset_t gregset;
static void
store_gp_regs (const struct regcache *regcache, int tid, int regno)
{
- struct gdbarch *gdbarch = get_regcache_arch (regcache);
+ struct gdbarch *gdbarch = regcache->arch ();
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
int i;
static void
store_fp_regs (const struct regcache *regcache, int tid, int regno)
{
- struct gdbarch *gdbarch = get_regcache_arch (regcache);
+ struct gdbarch *gdbarch = regcache->arch ();
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
int i;
store_ppc_registers (const struct regcache *regcache, int tid)
{
int i;
- struct gdbarch *gdbarch = get_regcache_arch (regcache);
+ struct gdbarch *gdbarch = regcache->arch ();
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
store_gp_regs (regcache, tid, -1);
{
int i;
long slot;
- struct ppc_hw_breakpoint *p = XNEW (struct ppc_hw_breakpoint);
+ gdb::unique_xmalloc_ptr<ppc_hw_breakpoint> p (XDUP (ppc_hw_breakpoint, b));
struct hw_break_tuple *hw_breaks;
- struct cleanup *c = make_cleanup (xfree, p);
struct thread_points *t;
struct hw_break_tuple *tuple;
- memcpy (p, b, sizeof (struct ppc_hw_breakpoint));
-
errno = 0;
- slot = ptrace (PPC_PTRACE_SETHWDEBUG, tid, 0, p);
+ slot = ptrace (PPC_PTRACE_SETHWDEBUG, tid, 0, p.get ());
if (slot < 0)
perror_with_name (_("Unexpected error setting breakpoint or watchpoint"));
if (hw_breaks[i].hw_break == NULL)
{
hw_breaks[i].slot = slot;
- hw_breaks[i].hw_break = p;
+ hw_breaks[i].hw_break = p.release ();
break;
}
gdb_assert (i != max_slots_number);
-
- discard_cleanups (c);
}
/* This function is a generic wrapper that is responsible for removing a
other kinds of values which are not acceptable in a condition
expression (e.g., lval_computed or lval_internalvar). */
static int
-num_memory_accesses (struct value *v)
+num_memory_accesses (const std::vector<value_ref_ptr> &chain)
{
int found_memory_cnt = 0;
- struct value *head = v;
/* The idea here is that evaluating an expression generates a series
of values, one holding the value of every subexpression. (The
notice that an expression contains an inferior function call.
FIXME. */
- for (; v; v = value_next (v))
+ for (const value_ref_ptr &iter : chain)
{
+ struct value *v = iter.get ();
+
/* Constants and values from the history are fine. */
if (VALUE_LVAL (v) == not_lval || deprecated_value_modifiable (v) == 0)
continue;
CORE_ADDR *data_value, int *len)
{
int pc = 1, num_accesses_left, num_accesses_right;
- struct value *left_val, *right_val, *left_chain, *right_chain;
+ struct value *left_val, *right_val;
+ std::vector<value_ref_ptr> left_chain, right_chain;
if (cond->elts[0].opcode != BINOP_EQUAL)
return 0;
num_accesses_left = num_memory_accesses (left_chain);
if (left_val == NULL || num_accesses_left < 0)
- {
- free_value_chain (left_chain);
-
- return 0;
- }
+ return 0;
fetch_subexp_value (cond, &pc, &right_val, NULL, &right_chain, 0);
num_accesses_right = num_memory_accesses (right_chain);
if (right_val == NULL || num_accesses_right < 0)
- {
- free_value_chain (left_chain);
- free_value_chain (right_chain);
-
- return 0;
- }
+ return 0;
if (num_accesses_left == 1 && num_accesses_right == 0
&& VALUE_LVAL (left_val) == lval_memory
*len = TYPE_LENGTH (check_typedef (value_type (right_val)));
}
else
- {
- free_value_chain (left_chain);
- free_value_chain (right_chain);
-
- return 0;
- }
-
- free_value_chain (left_chain);
- free_value_chain (right_chain);
+ return 0;
return 1;
}
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);
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;
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;
return isa205? tdesc_powerpc_isa205_32l : tdesc_powerpc_32l;
}
-void _initialize_ppc_linux_nat (void);
-
void
_initialize_ppc_linux_nat (void)
{
t->to_read_description = ppc_linux_read_description;
t->to_auxv_parse = ppc_linux_auxv_parse;
- observer_attach_thread_exit (ppc_linux_thread_exit);
+ gdb::observers::thread_exit.attach (ppc_linux_thread_exit);
/* Register the target. */
linux_nat_add_target (t);