/* Low level interface to ptrace, for the remote server for GDB.
- Copyright (C) 1995-2018 Free Software Foundation, Inc.
+ Copyright (C) 1995-2019 Free Software Foundation, Inc.
This file is part of GDB.
#include "server.h"
#include "linux-low.h"
#include "nat/linux-osdata.h"
-#include "agent.h"
+#include "common/agent.h"
#include "tdesc.h"
-#include "rsp-low.h"
-#include "signals-state-save-restore.h"
+#include "common/rsp-low.h"
+#include "common/signals-state-save-restore.h"
#include "nat/linux-nat.h"
#include "nat/linux-waitpid.h"
-#include "gdb_wait.h"
+#include "common/gdb_wait.h"
#include "nat/gdb_ptrace.h"
#include "nat/linux-ptrace.h"
#include "nat/linux-procfs.h"
#include <sys/stat.h>
#include <sys/vfs.h>
#include <sys/uio.h>
-#include "filestuff.h"
+#include "common/filestuff.h"
#include "tracepoint.h"
#include "hostio.h"
#include <inttypes.h>
-#include "common-inferior.h"
+#include "common/common-inferior.h"
#include "nat/fork-inferior.h"
-#include "environ.h"
+#include "common/environ.h"
#include "common/scoped_restore.h"
#ifndef ELFMAG0
/* Don't include <linux/elf.h> here. If it got included by gdb_proc_service.h
#ifdef HAVE_LINUX_BTRACE
# include "nat/linux-btrace.h"
-# include "btrace-common.h"
+# include "common/btrace-common.h"
#endif
#ifndef HAVE_ELF32_AUXV_T
lwp->waitstatus.kind = TARGET_WAITKIND_IGNORE;
+ lwp->thread = add_thread (ptid, lwp);
+
if (the_low_target.new_thread != NULL)
the_low_target.new_thread (lwp);
- lwp->thread = add_thread (ptid, lwp);
-
return lwp;
}
ptid_t ptid = ptid_t (pid, pid, 0);
int err;
+ proc = linux_add_process (pid, 1);
+
/* Attach to PID. We will check for other threads
soon. */
err = linux_attach_lwp (ptid);
if (err != 0)
{
- std::string reason = linux_ptrace_attach_fail_reason_string (ptid, err);
+ remove_process (proc);
+ std::string reason = linux_ptrace_attach_fail_reason_string (ptid, err);
error ("Cannot attach to process %ld: %s", pid, reason.c_str ());
}
- proc = linux_add_process (pid, 1);
-
/* Don't ignore the initial SIGSTOP if we just attached to this
process. It will be collected by wait shortly. */
initial_thread = find_thread_ptid (ptid_t (pid, pid, 0));
{
bool seen_one = false;
- thread_info *thread = find_thread (pid, [&] (thread_info *thread)
+ thread_info *thread = find_thread (pid, [&] (thread_info *thr_arg)
{
if (!seen_one)
{
}
static int
-linux_kill (int pid)
+linux_kill (process_info *process)
{
- struct process_info *process;
- struct lwp_info *lwp;
-
- process = find_process_pid (pid);
- if (process == NULL)
- return -1;
+ int pid = process->pid;
/* If we're killing a running inferior, make sure it is stopped
first, as PTRACE_KILL will not work otherwise. */
/* See the comment in linux_kill_one_lwp. We did not kill the first
thread in the list, so do so now. */
- lwp = find_lwp_pid (ptid_t (pid));
+ lwp_info *lwp = find_lwp_pid (ptid_t (pid));
if (lwp == NULL)
{
}
static void
-linux_join (process_info *proc)
+linux_join (int pid)
{
int status, ret;
do {
- ret = my_waitpid (proc->pid, &status, 0);
+ ret = my_waitpid (pid, &status, 0);
if (WIFEXITED (status) || WIFSIGNALED (status))
break;
} while (ret != -1 || errno != ECHILD);
struct lwp_info *
find_lwp_pid (ptid_t ptid)
{
- thread_info *thread = find_thread ([&] (thread_info *thread)
+ thread_info *thread = find_thread ([&] (thread_info *thr_arg)
{
int lwp = ptid.lwp () != 0 ? ptid.lwp () : ptid.pid ();
- return thread->id.lwp () == lwp;
+ return thr_arg->id.lwp () == lwp;
});
if (thread == NULL)
struct lwp_info *
iterate_over_lwps (ptid_t filter,
- iterate_over_lwps_ftype callback,
- void *data)
+ gdb::function_view<iterate_over_lwps_ftype> callback)
{
- thread_info *thread = find_thread (filter, [&] (thread_info *thread)
+ thread_info *thread = find_thread (filter, [&] (thread_info *thr_arg)
{
- lwp_info *lwp = get_thread_lwp (thread);
+ lwp_info *lwp = get_thread_lwp (thr_arg);
- return callback (lwp, data);
+ return callback (lwp);
});
if (thread == NULL)
#endif
if (res < 0)
{
- if (errno == EIO)
+ if (errno == EIO
+ || (errno == EINVAL && regset->type == OPTIONAL_REGS))
{
- /* If we get EIO on a regset, do not try it again for
- this process mode. */
+ /* If we get EIO on a regset, or an EINVAL and the regset is
+ optional, do not try it again for this process mode. */
disable_regset (regsets_info, regset);
}
else if (errno == ENODATA)
if (res < 0)
{
- if (errno == EIO)
+ if (errno == EIO
+ || (errno == EINVAL && regset->type == OPTIONAL_REGS))
{
- /* If we get EIO on a regset, do not try it again for
- this process mode. */
+ /* If we get EIO on a regset, or an EINVAL and the regset is
+ optional, do not try it again for this process mode. */
disable_regset (regsets_info, regset);
}
else if (errno == ESRCH)
{
const char *sep;
CORE_ADDR *addrp;
- int len;
+ int name_len;
sep = strchr (annex, '=');
if (sep == NULL)
break;
- len = sep - annex;
- if (len == 5 && startswith (annex, "start"))
+ name_len = sep - annex;
+ if (name_len == 5 && startswith (annex, "start"))
addrp = &lm_addr;
- else if (len == 4 && startswith (annex, "prev"))
+ else if (name_len == 4 && startswith (annex, "prev"))
addrp = &lm_prev;
else
{
return pc;
}
+/* Fetch the entry MATCH from the auxv vector, where entries are length
+ WORDSIZE. If no entry was found, return zero. */
+
+static CORE_ADDR
+linux_get_auxv (int wordsize, CORE_ADDR match)
+{
+ gdb_byte *data = (gdb_byte *) alloca (2 * wordsize);
+ int offset = 0;
+
+ gdb_assert (wordsize == 4 || wordsize == 8);
+
+ while ((*the_target->read_auxv) (offset, data, 2 * wordsize) == 2 * wordsize)
+ {
+ if (wordsize == 4)
+ {
+ uint32_t *data_p = (uint32_t *)data;
+ if (data_p[0] == match)
+ return data_p[1];
+ }
+ else
+ {
+ uint64_t *data_p = (uint64_t *)data;
+ if (data_p[0] == match)
+ return data_p[1];
+ }
+
+ offset += 2 * wordsize;
+ }
+
+ return 0;
+}
+
+/* See linux-low.h. */
+
+CORE_ADDR
+linux_get_hwcap (int wordsize)
+{
+ return linux_get_auxv (wordsize, AT_HWCAP);
+}
+
+/* See linux-low.h. */
+
+CORE_ADDR
+linux_get_hwcap2 (int wordsize)
+{
+ return linux_get_auxv (wordsize, AT_HWCAP2);
+}
static struct target_ops linux_target_ops = {
linux_create_inferior,