/* Low level interface to ptrace, for the remote server for GDB.
- Copyright (C) 1995-2018 Free Software Foundation, Inc.
+ Copyright (C) 1995-2020 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 "gdbsupport/agent.h"
#include "tdesc.h"
-#include "rsp-low.h"
-#include "signals-state-save-restore.h"
+#include "gdbsupport/rsp-low.h"
+#include "gdbsupport/signals-state-save-restore.h"
#include "nat/linux-nat.h"
#include "nat/linux-waitpid.h"
-#include "gdb_wait.h"
+#include "gdbsupport/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 "gdbsupport/filestuff.h"
#include "tracepoint.h"
#include "hostio.h"
#include <inttypes.h>
-#include "common-inferior.h"
+#include "gdbsupport/common-inferior.h"
#include "nat/fork-inferior.h"
-#include "environ.h"
-#include "common/scoped_restore.h"
+#include "gdbsupport/environ.h"
+#include "gdbsupport/gdb-sigmask.h"
+#include "gdbsupport/scoped_restore.h"
#ifndef ELFMAG0
/* Don't include <linux/elf.h> here. If it got included by gdb_proc_service.h
then ELFMAG0 will have been defined. If it didn't get included by
#endif
#include "nat/linux-namespaces.h"
-#ifndef SPUFS_MAGIC
-#define SPUFS_MAGIC 0x23c9b64e
-#endif
-
#ifdef HAVE_PERSONALITY
# include <sys/personality.h>
# if !HAVE_DECL_ADDR_NO_RANDOMIZE
#define O_LARGEFILE 0
#endif
+#ifndef AT_HWCAP2
+#define AT_HWCAP2 26
+#endif
+
/* Some targets did not define these ptrace constants from the start,
so gdbserver defines them locally here. In the future, these may
be removed after they are added to asm/ptrace.h. */
#ifdef HAVE_LINUX_BTRACE
# include "nat/linux-btrace.h"
-# include "btrace-common.h"
+# include "gdbsupport/btrace-common.h"
#endif
#ifndef HAVE_ELF32_AUXV_T
{
debug_printf ("HEW: Got fork event from LWP %ld, "
"new child is %d\n",
- ptid_get_lwp (ptid_of (event_thr)),
- ptid_get_pid (ptid));
+ ptid_of (event_thr).lwp (),
+ ptid.pid ());
}
/* Add the new process to the tables and clone the breakpoint
/* Get the event ptid. */
event_ptid = ptid_of (event_thr);
- event_pid = ptid_get_pid (event_ptid);
+ event_pid = event_ptid.pid ();
/* Save the syscall list from the execing process. */
proc = get_thread_process (event_thr);
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;
}
linux_attach_lwp (ptid_t ptid)
{
struct lwp_info *new_lwp;
- int lwpid = ptid_get_lwp (ptid);
+ int lwpid = ptid.lwp ();
if (ptrace (PTRACE_ATTACH, lwpid, (PTRACE_TYPE_ARG3) 0, (PTRACE_TYPE_ARG4) 0)
!= 0)
/* Is this a new thread? */
if (find_thread_ptid (ptid) == NULL)
{
- int lwpid = ptid_get_lwp (ptid);
+ int lwpid = ptid.lwp ();
int err;
if (debug_threads)
{
debug_printf ("Cannot attach to lwp %d: "
"thread is gone (%d: %s)\n",
- lwpid, err, strerror (err));
+ lwpid, err, safe_strerror (err));
}
}
else if (err != 0)
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)
{
debug_printf ("LKL: kill_lwp (SIGKILL) %s, 0, 0 (%s)\n",
target_pid_to_str (ptid_of (thr)),
- save_errno ? strerror (save_errno) : "OK");
+ save_errno ? safe_strerror (save_errno) : "OK");
}
errno = 0;
debug_printf ("LKL: PTRACE_KILL %s, 0, 0 (%s)\n",
target_pid_to_str (ptid_of (thr)),
- save_errno ? strerror (save_errno) : "OK");
+ save_errno ? safe_strerror (save_errno) : "OK");
}
}
kill_wait_lwp (struct lwp_info *lwp)
{
struct thread_info *thr = get_lwp_thread (lwp);
- int pid = ptid_get_pid (ptid_of (thr));
- int lwpid = ptid_get_lwp (ptid_of (thr));
+ int pid = ptid_of (thr).pid ();
+ int lwpid = ptid_of (thr).lwp ();
int wstat;
int res;
}
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)
{
/* Preparing to resume may try to write registers, and fail if the
lwp is zombie. If that happens, ignore the error. We'll handle
it below, when detach fails with ESRCH. */
- TRY
+ try
{
/* Flush any pending changes to the process's registers. */
regcache_invalidate_thread (thread);
if (the_low_target.prepare_to_resume != NULL)
the_low_target.prepare_to_resume (lwp);
}
- CATCH (ex, RETURN_MASK_ERROR)
+ catch (const gdb_exception_error &ex)
{
if (!check_ptrace_stopped_lwp_gone (lwp))
- throw_exception (ex);
+ throw;
}
- END_CATCH
lwpid = lwpid_of (thread);
if (ptrace (PTRACE_DETACH, lwpid, (PTRACE_TYPE_ARG3) 0,
if (ret == -1)
{
warning (_("Couldn't reap LWP %d while detaching: %s"),
- lwpid, strerror (errno));
+ lwpid, safe_strerror (errno));
}
else if (!WIFEXITED (status) && !WIFSIGNALED (status))
{
{
error (_("Can't detach %s: %s"),
target_pid_to_str (ptid_of (thread)),
- strerror (save_errno));
+ safe_strerror (save_errno));
}
}
else if (debug_threads)
}
static int
-linux_detach (int pid)
+linux_detach (process_info *process)
{
- struct process_info *process;
struct lwp_info *main_lwp;
- process = find_process_pid (pid);
- if (process == NULL)
- return -1;
-
/* As there's a step over already in progress, let it finish first,
otherwise nesting a stabilize_threads operation on top gets real
messy. */
complete_ongoing_step_over ();
/* Stop all threads before detaching. First, ptrace requires that
- the thread is stopped to sucessfully detach. Second, thread_db
+ the thread is stopped to successfully detach. Second, thread_db
may need to uninstall thread event breakpoints from memory, which
only works with a stopped process anyway. */
stop_all_lwps (0, NULL);
/* Detach from the clone lwps first. If the thread group exits just
while we're detaching, we must reap the clone lwps before we're
able to reap the leader. */
- for_each_thread (pid, linux_detach_lwp_callback);
+ for_each_thread (process->pid, linux_detach_lwp_callback);
- main_lwp = find_lwp_pid (ptid_t (pid));
+ main_lwp = find_lwp_pid (ptid_t (process->pid));
linux_detach_one_lwp (main_lwp);
the_target->mourn (process);
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)
/* Check for a lwp with a pending status. */
- if (ptid_equal (filter_ptid, minus_one_ptid) || ptid_is_pid (filter_ptid))
+ if (filter_ptid == minus_one_ptid || filter_ptid.is_pid ())
{
event_thread = find_thread_in_random ([&] (thread_info *thread)
{
if (debug_threads && event_thread)
debug_printf ("Got a pending child %ld\n", lwpid_of (event_thread));
}
- else if (!ptid_equal (filter_ptid, null_ptid))
+ else if (filter_ptid != null_ptid)
{
requested_child = find_lwp_pid (filter_ptid);
/* Make sure SIGCHLD is blocked until the sigsuspend below. Block
all signals while here. */
sigfillset (&block_mask);
- sigprocmask (SIG_BLOCK, &block_mask, &prev_mask);
+ gdb_sigmask (SIG_BLOCK, &block_mask, &prev_mask);
/* Always pull all events out of the kernel. We'll randomly select
an event LWP out of all that have events, to prevent
if (debug_threads)
debug_printf ("LWFE: waitpid(-1, ...) returned %d, %s\n",
- ret, errno ? strerror (errno) : "ERRNO-OK");
+ ret, errno ? safe_strerror (errno) : "ERRNO-OK");
if (ret > 0)
{
{
if (debug_threads)
debug_printf ("LLW: exit (no unwaited-for LWP)\n");
- sigprocmask (SIG_SETMASK, &prev_mask, NULL);
+ gdb_sigmask (SIG_SETMASK, &prev_mask, NULL);
return -1;
}
if (debug_threads)
debug_printf ("WNOHANG set, no event found\n");
- sigprocmask (SIG_SETMASK, &prev_mask, NULL);
+ gdb_sigmask (SIG_SETMASK, &prev_mask, NULL);
return 0;
}
debug_printf ("sigsuspend'ing\n");
sigsuspend (&prev_mask);
- sigprocmask (SIG_SETMASK, &prev_mask, NULL);
+ gdb_sigmask (SIG_SETMASK, &prev_mask, NULL);
goto retry;
}
- sigprocmask (SIG_SETMASK, &prev_mask, NULL);
+ gdb_sigmask (SIG_SETMASK, &prev_mask, NULL);
current_thread = event_thread;
static void
select_event_lwp (struct lwp_info **orig_lp)
{
- int random_selector;
struct thread_info *event_thread = NULL;
/* In all-stop, give preference to the LWP that is being
/* No single-stepping LWP. Select one at random, out of those
which have had events. */
- /* First see how many events we have. */
- int num_events = 0;
- for_each_thread ([&] (thread_info *thread)
- {
- lwp_info *lp = get_thread_lwp (thread);
-
- /* Count only resumed LWPs that have an event pending. */
- if (thread->last_status.kind == TARGET_WAITKIND_IGNORE
- && lp->status_pending_p)
- num_events++;
- });
- gdb_assert (num_events > 0);
-
- /* Now randomly pick a LWP out of those that have had
- events. */
- random_selector = (int)
- ((num_events * (double) rand ()) / (RAND_MAX + 1.0));
-
- if (debug_threads && num_events > 1)
- debug_printf ("SEL: Found %d SIGTRAP events, selecting #%d\n",
- num_events, random_selector);
-
- event_thread = find_thread ([&] (thread_info *thread)
+ event_thread = find_thread_in_random ([&] (thread_info *thread)
{
lwp_info *lp = get_thread_lwp (thread);
- /* Select only resumed LWPs that have an event pending. */
- if (thread->last_status.kind == TARGET_WAITKIND_IGNORE
- && lp->status_pending_p)
- if (random_selector-- == 0)
- return true;
-
- return false;
+ /* Only resumed LWPs that have an event pending. */
+ return (thread->last_status.kind == TARGET_WAITKIND_IGNORE
+ && lp->status_pending_p);
});
}
else
any_resumed = 0;
- if (ptid_equal (step_over_bkpt, null_ptid))
+ if (step_over_bkpt == null_ptid)
pid = linux_wait_for_event (ptid, &w, options);
else
{
if it's not the single_step_breakpoint we are hitting.
This avoids that a program would keep trapping a permanent breakpoint
forever. */
- if (!ptid_equal (step_over_bkpt, null_ptid)
+ if (step_over_bkpt != null_ptid
&& event_child->stop_reason == TARGET_STOPPED_BY_SW_BREAKPOINT
&& (event_child->stepping
|| !single_step_breakpoint_inserted_here (event_child->stop_pc)))
from among those that have had events. Giving equal priority
to all LWPs that have had events helps prevent
starvation. */
- if (ptid_equal (ptid, minus_one_ptid))
+ if (ptid == minus_one_ptid)
{
event_child->status_pending_p = 1;
event_child->status_pending = w;
ourstatus->value.sig = gdb_signal_from_host (WSTOPSIG (w));
}
- gdb_assert (ptid_equal (step_over_bkpt, null_ptid));
+ gdb_assert (step_over_bkpt == null_ptid);
if (debug_threads)
{
event_ptid = linux_wait_1 (ptid, ourstatus, target_options);
}
while ((target_options & TARGET_WNOHANG) == 0
- && ptid_equal (event_ptid, null_ptid)
+ && event_ptid == null_ptid
&& ourstatus->kind == TARGET_WAITKIND_IGNORE);
/* If at least one stop was reported, there may be more. A single
SIGCHLD can signal more than one child stop. */
if (target_is_async_p ()
&& (target_options & TARGET_WNOHANG) != 0
- && !ptid_equal (event_ptid, null_ptid))
+ && event_ptid != null_ptid)
async_file_mark ();
return event_ptid;
linux_resume_one_lwp (struct lwp_info *lwp,
int step, int signal, siginfo_t *info)
{
- TRY
+ try
{
linux_resume_one_lwp_throw (lwp, step, signal, info);
}
- CATCH (ex, RETURN_MASK_ERROR)
+ catch (const gdb_exception_error &ex)
{
if (!check_ptrace_stopped_lwp_gone (lwp))
- throw_exception (ex);
+ throw;
}
- END_CATCH
}
/* This function is called once per thread via for_each_thread.
for (int ndx = 0; ndx < n; ndx++)
{
ptid_t ptid = resume[ndx].thread;
- if (ptid_equal (ptid, minus_one_ptid)
+ if (ptid == minus_one_ptid
|| ptid == thread->id
/* Handle both 'pPID' and 'pPID.-1' as meaning 'all threads
of PID'. */
- || (ptid_get_pid (ptid) == pid_of (thread)
- && (ptid_is_pid (ptid)
- || ptid_get_lwp (ptid) == -1)))
+ || (ptid.pid () == pid_of (thread)
+ && (ptid.is_pid ()
+ || ptid.lwp () == -1)))
{
if (resume[ndx].kind == resume_stop
&& thread->last_resume_kind == resume_stop)
static void
complete_ongoing_step_over (void)
{
- if (!ptid_equal (step_over_bkpt, null_ptid))
+ if (step_over_bkpt != null_ptid)
{
struct lwp_info *lwp;
int wstat;
#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)
return;
if ((*the_low_target.cannot_store_register) (regno) == 0)
- error ("writing register %d: %s", regno, strerror (errno));
+ error ("writing register %d: %s", regno, safe_strerror (errno));
}
regaddr += sizeof (PTRACE_XFER_TYPE);
}
{
do
{
- /* fprintf is not async-signal-safe, so call write
- directly. */
- if (write (2, "sigchld_handler\n",
- sizeof ("sigchld_handler\n") - 1) < 0)
+ /* Use the async signal safe debug function. */
+ if (debug_write ("sigchld_handler\n",
+ sizeof ("sigchld_handler\n") - 1) < 0)
break; /* just ignore */
} while (0);
}
sigemptyset (&mask);
sigaddset (&mask, SIGCHLD);
- sigprocmask (SIG_BLOCK, &mask, NULL);
+ gdb_sigmask (SIG_BLOCK, &mask, NULL);
if (enable)
{
{
linux_event_pipe[0] = -1;
linux_event_pipe[1] = -1;
- sigprocmask (SIG_UNBLOCK, &mask, NULL);
+ gdb_sigmask (SIG_UNBLOCK, &mask, NULL);
warning ("creating event pipe failed.");
return previous;
linux_event_pipe[1] = -1;
}
- sigprocmask (SIG_UNBLOCK, &mask, NULL);
+ gdb_sigmask (SIG_UNBLOCK, &mask, NULL);
}
return previous;
return (*the_low_target.supports_range_stepping) ();
}
-/* Enumerate spufs IDs for process PID. */
-static int
-spu_enumerate_spu_ids (long pid, unsigned char *buf, CORE_ADDR offset, int len)
-{
- int pos = 0;
- int written = 0;
- char path[128];
- DIR *dir;
- struct dirent *entry;
-
- sprintf (path, "/proc/%ld/fd", pid);
- dir = opendir (path);
- if (!dir)
- return -1;
-
- rewinddir (dir);
- while ((entry = readdir (dir)) != NULL)
- {
- struct stat st;
- struct statfs stfs;
- int fd;
-
- fd = atoi (entry->d_name);
- if (!fd)
- continue;
-
- sprintf (path, "/proc/%ld/fd/%d", pid, fd);
- if (stat (path, &st) != 0)
- continue;
- if (!S_ISDIR (st.st_mode))
- continue;
-
- if (statfs (path, &stfs) != 0)
- continue;
- if (stfs.f_type != SPUFS_MAGIC)
- continue;
-
- if (pos >= offset && pos + 4 <= offset + len)
- {
- *(unsigned int *)(buf + pos - offset) = fd;
- written += 4;
- }
- pos += 4;
- }
-
- closedir (dir);
- return written;
-}
-
-/* Implements the to_xfer_partial interface for the TARGET_OBJECT_SPU
- object type, using the /proc file system. */
-static int
-linux_qxfer_spu (const char *annex, unsigned char *readbuf,
- unsigned const char *writebuf,
- CORE_ADDR offset, int len)
-{
- long pid = lwpid_of (current_thread);
- char buf[128];
- int fd = 0;
- int ret = 0;
-
- if (!writebuf && !readbuf)
- return -1;
-
- if (!*annex)
- {
- if (!readbuf)
- return -1;
- else
- return spu_enumerate_spu_ids (pid, readbuf, offset, len);
- }
-
- sprintf (buf, "/proc/%ld/fd/%s", pid, annex);
- fd = open (buf, writebuf? O_WRONLY : O_RDONLY);
- if (fd <= 0)
- return -1;
-
- if (offset != 0
- && lseek (fd, (off_t) offset, SEEK_SET) != (off_t) offset)
- {
- close (fd);
- return 0;
- }
-
- if (writebuf)
- ret = write (fd, writebuf, (size_t) len);
- else
- ret = read (fd, readbuf, (size_t) len);
-
- close (fd);
- return ret;
-}
-
#if defined PT_GETDSBT || defined PTRACE_GETFDPIC
struct target_loadseg
{
{
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
{
if (size == 0)
return;
- /* We use hex encoding - see common/rsp-low.h. */
+ /* We use hex encoding - see gdbsupport/rsp-low.h. */
buffer_grow_str (buffer, "<raw>\n");
while (size-- > 0)
enum btrace_read_type type)
{
struct btrace_data btrace;
- struct btrace_block *block;
enum btrace_error err;
- int i;
err = linux_read_btrace (&btrace, tinfo, type);
if (err != BTRACE_ERR_NONE)
buffer_grow_str (buffer, "<!DOCTYPE btrace SYSTEM \"btrace.dtd\">\n");
buffer_grow_str (buffer, "<btrace version=\"1.0\">\n");
- for (i = 0;
- VEC_iterate (btrace_block_s, btrace.variant.bts.blocks, i, block);
- i++)
+ for (const btrace_block &block : *btrace.variant.bts.blocks)
buffer_xml_printf (buffer, "<block begin=\"0x%s\" end=\"0x%s\"/>\n",
- paddress (block->begin), paddress (block->end));
+ paddress (block.begin), paddress (block.end));
buffer_grow_str0 (buffer, "</btrace>\n");
break;
return pc;
}
+/* See linux-low.h. */
+
+int
+linux_get_auxv (int wordsize, CORE_ADDR match, CORE_ADDR *valp)
+{
+ 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)
+ {
+ *valp = data_p[1];
+ return 1;
+ }
+ }
+ else
+ {
+ uint64_t *data_p = (uint64_t *) data;
+ if (data_p[0] == match)
+ {
+ *valp = data_p[1];
+ return 1;
+ }
+ }
+
+ offset += 2 * wordsize;
+ }
+
+ return 0;
+}
+
+/* See linux-low.h. */
+
+CORE_ADDR
+linux_get_hwcap (int wordsize)
+{
+ CORE_ADDR hwcap = 0;
+ linux_get_auxv (wordsize, AT_HWCAP, &hwcap);
+ return hwcap;
+}
+
+/* See linux-low.h. */
+
+CORE_ADDR
+linux_get_hwcap2 (int wordsize)
+{
+ CORE_ADDR hwcap2 = 0;
+ linux_get_auxv (wordsize, AT_HWCAP2, &hwcap2);
+ return hwcap2;
+}
-static struct target_ops linux_target_ops = {
+static process_stratum_target linux_target_ops = {
linux_create_inferior,
linux_post_create_inferior,
linux_attach,
#else
NULL,
#endif
- linux_qxfer_spu,
hostio_last_error_from_errno,
linux_qxfer_osdata,
linux_xfer_siginfo,
set_target_ops (&linux_target_ops);
linux_ptrace_init_warnings ();
+ linux_proc_init_warnings ();
sigchld_action.sa_handler = sigchld_handler;
sigemptyset (&sigchld_action.sa_mask);