/* GNU/Linux/ARM specific low level interface, for the remote server for GDB.
- Copyright (C) 1995-2016 Free Software Foundation, Inc.
+ Copyright (C) 1995-2017 Free Software Foundation, Inc.
This file is part of GDB.
{
ULONGEST res;
- (*the_target->read_memory) (memaddr, (unsigned char *) &res, len);
+ res = 0;
+ target_read_memory (memaddr, (unsigned char *) &res, len);
+
return res;
}
/* Fetch the thread-local storage pointer for libthread_db. */
ps_err_e
-ps_get_thread_area (const struct ps_prochandle *ph,
+ps_get_thread_area (struct ps_prochandle *ph,
lwpid_t lwpid, int idx, void **base)
{
if (ptrace (PTRACE_GET_THREAD_AREA, lwpid, NULL, base) != 0)
lwp->arch_private = info;
}
+/* Function to call when a thread is being deleted. */
+
+static void
+arm_delete_thread (struct arch_lwp_info *arch_lwp)
+{
+ xfree (arch_lwp);
+}
+
static void
arm_new_fork (struct process_info *parent, struct process_info *child)
{
/* Offset of PC register. */
int pc_offset = 0;
CORE_ADDR next_pc = 0;
- CORE_ADDR cpsr;
+ uint32_t cpsr;
gdb_assert (svc_number == __NR_sigreturn || svc_number == __NR_rt_sigreturn);
unsigned long this_instr;
unsigned long svc_operand;
- (*the_target->read_memory) (pc, (unsigned char *) &this_instr, 4);
+ target_read_memory (pc, (unsigned char *) &this_instr, 4);
svc_operand = (0x00ffffff & this_instr);
if (svc_operand) /* OABI. */
/* Fetch the next possible PCs after the current instruction executes. */
-static VEC (CORE_ADDR) *
+static std::vector<CORE_ADDR>
arm_gdbserver_get_next_pcs (struct regcache *regcache)
{
struct arm_get_next_pcs next_pcs_ctx;
- VEC (CORE_ADDR) *next_pcs = NULL;
arm_get_next_pcs_ctor (&next_pcs_ctx,
&get_next_pcs_ops,
1,
regcache);
- next_pcs = arm_get_next_pcs (&next_pcs_ctx);
-
- return next_pcs;
+ return arm_get_next_pcs (&next_pcs_ctx);
}
/* Support for hardware single step. */
return 0;
}
+/* Implementation of linux_target_ops method "get_syscall_trapinfo". */
+
+static void
+arm_get_syscall_trapinfo (struct regcache *regcache, int *sysno)
+{
+ if (arm_is_thumb_mode ())
+ collect_register_by_name (regcache, "r7", sysno);
+ else
+ {
+ unsigned long pc;
+ unsigned long insn;
+
+ collect_register_by_name (regcache, "pc", &pc);
+
+ if ((*the_target->read_memory) (pc - 4, (unsigned char *) &insn, 4))
+ *sysno = UNKNOWN_SYSCALL;
+ else
+ {
+ unsigned long svc_operand = (0x00ffffff & insn);
+
+ if (svc_operand)
+ {
+ /* OABI */
+ *sysno = svc_operand - 0x900000;
+ }
+ else
+ {
+ /* EABI */
+ collect_register_by_name (regcache, "r7", sysno);
+ }
+ }
+ }
+}
+
/* Register sets without using PTRACE_GETREGSET. */
static struct regset_info arm_regsets[] = {
NULL, /* siginfo_fixup */
arm_new_process,
arm_new_thread,
+ arm_delete_thread,
arm_new_fork,
arm_prepare_to_resume,
NULL, /* process_qsupported */
NULL, /* get_min_fast_tracepoint_insn_len */
NULL, /* supports_range_stepping */
arm_breakpoint_kind_from_current_state,
- arm_supports_hardware_single_step
+ arm_supports_hardware_single_step,
+ arm_get_syscall_trapinfo,
};
void