/* GNU/Linux/x86-64 specific low level interface, for the remote server
for GDB.
- Copyright (C) 2002-2017 Free Software Foundation, Inc.
+ Copyright (C) 2002-2019 Free Software Foundation, Inc.
This file is part of GDB.
#include "linux-low.h"
#include "i387-fp.h"
#include "x86-low.h"
-#include "x86-xstate.h"
+#include "gdbsupport/x86-xstate.h"
#include "nat/gdb_ptrace.h"
#ifdef __x86_64__
#include "elf/common.h"
#endif
-#include "agent.h"
+#include "gdbsupport/agent.h"
#include "tdesc.h"
#include "tracepoint.h"
#include "ax.h"
#include <sys/reg.h>
#include <sys/procfs.h>
-#include "nat/gdb_ptrace.h"
#include <sys/uio.h>
#ifndef PTRACE_GET_THREAD_AREA
#endif
{
- struct lwp_info *lwp = find_lwp_pid (pid_to_ptid (lwpid));
+ struct lwp_info *lwp = find_lwp_pid (ptid_t (lwpid));
struct thread_info *thr = get_lwp_thread (lwp);
struct regcache *regcache = get_thread_regcache (thr, 1);
unsigned int desc[4];
collect_register_by_name (regcache, "orig_eax",
((char *) buf) + ORIG_EAX * REGSIZE);
+
+#ifdef __x86_64__
+ /* Sign extend EAX value to avoid potential syscall restart
+ problems.
+
+ See amd64_linux_collect_native_gregset() in gdb/amd64-linux-nat.c
+ for a detailed explanation. */
+ if (register_size (regcache->tdesc, 0) == 4)
+ {
+ void *ptr = ((gdb_byte *) buf
+ + i386_regmap[find_regno (regcache->tdesc, "eax")]);
+
+ *(int64_t *) ptr = *(int32_t *) ptr;
+ }
+#endif
}
static void
return info;
}
+/* Called when a process is being deleted. */
+
+static void
+x86_linux_delete_process (struct arch_process_info *info)
+{
+ xfree (info);
+}
+
/* Target routine for linux_new_fork. */
static void
gdb_assert_not_reached ("failed to return tdesc");
}
-/* Callback for find_inferior. Stops iteration when a thread with a
- given PID is found. */
-
-static int
-same_process_callback (struct inferior_list_entry *entry, void *data)
-{
- int pid = *(int *) data;
-
- return (ptid_get_pid (entry->id) == pid);
-}
-
-/* Callback for for_each_inferior. Calls the arch_setup routine for
- each process. */
-
-static void
-x86_arch_setup_process_callback (struct inferior_list_entry *entry)
-{
- int pid = ptid_get_pid (entry->id);
-
- /* Look up any thread of this processes. */
- current_thread
- = (struct thread_info *) find_inferior (&all_threads,
- same_process_callback, &pid);
-
- the_low_target.arch_setup ();
-}
-
/* Update all the target description of all processes; a new GDB
connected, and it may or not support xml target descriptions. */
release the current regcache objects. */
regcache_release ();
- for_each_inferior (&all_processes, x86_arch_setup_process_callback);
+ for_each_process ([] (process_info *proc) {
+ int pid = proc->pid;
+
+ /* Look up any thread of this process. */
+ current_thread = find_any_thread_of_pid (pid);
+
+ the_low_target.arch_setup ();
+ });
current_thread = saved_thread;
}
if (startswith (feature, "xmlRegisters="))
{
char *copy = xstrdup (feature + 13);
- char *p;
- for (p = strtok (copy, ","); p != NULL; p = strtok (NULL, ","))
+ char *saveptr;
+ for (char *p = strtok_r (copy, ",", &saveptr);
+ p != NULL;
+ p = strtok_r (NULL, ",", &saveptr))
{
if (strcmp (p, "i386") == 0)
{
static void
append_insns (CORE_ADDR *to, size_t len, const unsigned char *buf)
{
- write_inferior_memory (*to, buf, len);
+ target_write_memory (*to, buf, len);
*to += len;
}
offset = *jump_entry - (*trampoline + sizeof (jump_insn));
memcpy (buf, jump_insn, sizeof (jump_insn));
memcpy (buf + 1, &offset, 4);
- write_inferior_memory (*trampoline, buf, sizeof (jump_insn));
+ target_write_memory (*trampoline, buf, sizeof (jump_insn));
/* Use a 16-bit relative jump instruction to jump to the trampoline. */
offset = (*trampoline - (tpaddr + sizeof (small_jump_insn))) & 0xffff;
mention that something has gone awry. */
if (!warned_about_fast_tracepoints)
{
- warning ("4-byte fast tracepoints not available; %s\n", errbuf);
+ warning ("4-byte fast tracepoints not available; %s", errbuf);
warned_about_fast_tracepoints = 1;
}
return 5;
}
memcpy (buf, &diff, sizeof (int));
- write_inferior_memory (from, buf, sizeof (int));
+ target_write_memory (from, buf, sizeof (int));
}
static void
}
memcpy (buf, &diff, sizeof (int));
- write_inferior_memory (from, buf, sizeof (int));
+ target_write_memory (from, buf, sizeof (int));
}
static void
/* need to fix up i386 siginfo if host is amd64 */
x86_siginfo_fixup,
x86_linux_new_process,
+ x86_linux_delete_process,
x86_linux_new_thread,
+ x86_linux_delete_thread,
x86_linux_new_fork,
x86_linux_prepare_to_resume,
x86_linux_process_qsupported,
{
/* Initialize the Linux target descriptions. */
#ifdef __x86_64__
- tdesc_amd64_linux_no_xml = XNEW (struct target_desc);
+ tdesc_amd64_linux_no_xml = allocate_target_description ();
copy_target_description (tdesc_amd64_linux_no_xml,
amd64_linux_read_description (X86_XSTATE_SSE_MASK,
false));
tdesc_amd64_linux_no_xml->xmltarget = xmltarget_amd64_linux_no_xml;
#endif
-#if GDB_SELF_TEST
- initialize_low_tdesc ();
-#endif
-
- tdesc_i386_linux_no_xml = XNEW (struct target_desc);
+ tdesc_i386_linux_no_xml = allocate_target_description ();
copy_target_description (tdesc_i386_linux_no_xml,
i386_linux_read_description (X86_XSTATE_SSE_MASK));
tdesc_i386_linux_no_xml->xmltarget = xmltarget_i386_linux_no_xml;