This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
+ the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 51 Franklin Street, Fifth Floor,
- Boston, MA 02110-1301, USA. */
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
#include "defs.h"
#include "inferior.h"
ptrace (PTRACE_SETOPTIONS, pid, 0, options);
}
-void
-child_post_attach (int pid)
+static void
+linux_child_post_attach (int pid)
{
linux_enable_event_reporting (pid_to_ptid (pid));
check_for_thread_db ();
check_for_thread_db ();
}
-int
-child_follow_fork (struct target_ops *ops, int follow_child)
+static int
+linux_child_follow_fork (struct target_ops *ops, int follow_child)
{
ptid_t last_ptid;
struct target_waitstatus last_status;
}
\f
-void
-child_insert_fork_catchpoint (int pid)
+static void
+linux_child_insert_fork_catchpoint (int pid)
{
if (! linux_supports_tracefork (pid))
error (_("Your system does not support fork catchpoints."));
}
-void
-child_insert_vfork_catchpoint (int pid)
+static void
+linux_child_insert_vfork_catchpoint (int pid)
{
if (!linux_supports_tracefork (pid))
error (_("Your system does not support vfork catchpoints."));
}
-void
-child_insert_exec_catchpoint (int pid)
+static void
+linux_child_insert_exec_catchpoint (int pid)
{
if (!linux_supports_tracefork (pid))
error (_("Your system does not support exec catchpoints."));
/* Prototypes for local functions. */
static int stop_wait_callback (struct lwp_info *lp, void *data);
static int linux_nat_thread_alive (ptid_t ptid);
+static char *linux_child_pid_to_exec_file (int pid);
\f
/* Convert wait status STATUS to a string. Used for printing debug
messages only. */
{
ourstatus->kind = TARGET_WAITKIND_EXECD;
ourstatus->value.execd_pathname
- = xstrdup (child_pid_to_exec_file (pid));
+ = xstrdup (linux_child_pid_to_exec_file (pid));
if (linux_parent_pid)
{
if (lp->status != 0
&& WIFSTOPPED (lp->status) && WSTOPSIG (lp->status) == SIGTRAP
&& breakpoint_inserted_here_p (read_pc_pid (lp->ptid) -
- DECR_PC_AFTER_BREAK))
+ gdbarch_decr_pc_after_break
+ (current_gdbarch)))
{
if (debug_linux_nat)
fprintf_unfiltered (gdb_stdlog,
target_pid_to_str (lp->ptid));
/* Back up the PC if necessary. */
- if (DECR_PC_AFTER_BREAK)
- write_pc_pid (read_pc_pid (lp->ptid) - DECR_PC_AFTER_BREAK, lp->ptid);
+ if (gdbarch_decr_pc_after_break (current_gdbarch))
+ write_pc_pid (read_pc_pid (lp->ptid) - gdbarch_decr_pc_after_break
+ (current_gdbarch),
+ lp->ptid);
/* Throw away the SIGTRAP. */
lp->status = 0;
/* Accepts an integer PID; Returns a string representing a file that
can be opened to get the symbols for the child process. */
-char *
-child_pid_to_exec_file (int pid)
+static char *
+linux_child_pid_to_exec_file (int pid)
{
char *name1, *name2;
gdb_fpxregset_t fpxregs;
#endif
unsigned long lwp = ptid_get_lwp (ptid);
- struct gdbarch *gdbarch = current_gdbarch;
+ struct regcache *regcache = get_thread_regcache (ptid);
+ struct gdbarch *gdbarch = get_regcache_arch (regcache);
const struct regset *regset;
int core_regset_p;
+ struct cleanup *old_chain;
+
+ old_chain = save_inferior_ptid ();
+ inferior_ptid = ptid;
+ target_fetch_registers (regcache, -1);
+ do_cleanups (old_chain);
core_regset_p = gdbarch_regset_from_core_section_p (gdbarch);
if (core_regset_p
&& (regset = gdbarch_regset_from_core_section (gdbarch, ".reg",
sizeof (gregs))) != NULL
&& regset->collect_regset != NULL)
- regset->collect_regset (regset, current_regcache, -1,
+ regset->collect_regset (regset, regcache, -1,
&gregs, sizeof (gregs));
else
- fill_gregset (&gregs, -1);
+ fill_gregset (regcache, &gregs, -1);
note_data = (char *) elfcore_write_prstatus (obfd,
note_data,
&& (regset = gdbarch_regset_from_core_section (gdbarch, ".reg2",
sizeof (fpregs))) != NULL
&& regset->collect_regset != NULL)
- regset->collect_regset (regset, current_regcache, -1,
+ regset->collect_regset (regset, regcache, -1,
&fpregs, sizeof (fpregs));
else
- fill_fpregset (&fpregs, -1);
+ fill_fpregset (regcache, &fpregs, -1);
note_data = (char *) elfcore_write_prfpreg (obfd,
note_data,
&& (regset = gdbarch_regset_from_core_section (gdbarch, ".reg-xfp",
sizeof (fpxregs))) != NULL
&& regset->collect_regset != NULL)
- regset->collect_regset (regset, current_regcache, -1,
+ regset->collect_regset (regset, regcache, -1,
&fpxregs, sizeof (fpxregs));
else
- fill_fpxregset (&fpxregs, -1);
+ fill_fpxregset (regcache, &fpxregs, -1);
note_data = (char *) elfcore_write_prxfpreg (obfd,
note_data,
linux_nat_corefile_thread_callback (struct lwp_info *ti, void *data)
{
struct linux_nat_corefile_thread_data *args = data;
- ptid_t saved_ptid = inferior_ptid;
- inferior_ptid = ti->ptid;
- registers_changed ();
- target_fetch_registers (-1); /* FIXME should not be necessary;
- fill_gregset should do it automatically. */
args->note_data = linux_nat_do_thread_registers (args->obfd,
ti->ptid,
args->note_data,
args->note_size);
args->num_notes++;
- inferior_ptid = saved_ptid;
- registers_changed ();
- target_fetch_registers (-1); /* FIXME should not be necessary;
- fill_gregset should do it automatically. */
+
return 0;
}
linux_nat_do_registers (bfd *obfd, ptid_t ptid,
char *note_data, int *note_size)
{
- registers_changed ();
- target_fetch_registers (-1); /* FIXME should not be necessary;
- fill_gregset should do it automatically. */
return linux_nat_do_thread_registers (obfd,
ptid_build (ptid_get_pid (inferior_ptid),
ptid_get_pid (inferior_ptid),
0),
note_data, note_size);
- return note_data;
}
/* Fills the "to_make_corefile_note" target vector. Builds the note
{
struct linux_nat_corefile_thread_data thread_args;
struct cleanup *old_chain;
+ /* The variable size must be >= sizeof (prpsinfo_t.pr_fname). */
char fname[16] = { '\0' };
+ /* The variable size must be >= sizeof (prpsinfo_t.pr_psargs). */
char psargs[80] = { '\0' };
char *note_data = NULL;
ptid_t current_ptid = inferior_ptid;
strncpy (psargs, get_exec_file (0), sizeof (psargs));
if (get_inferior_args ())
{
- strncat (psargs, " ", sizeof (psargs) - strlen (psargs));
- strncat (psargs, get_inferior_args (),
- sizeof (psargs) - strlen (psargs));
+ char *string_end;
+ char *psargs_end = psargs + sizeof (psargs);
+
+ /* linux_elfcore_write_prpsinfo () handles zero unterminated
+ strings fine. */
+ string_end = memchr (psargs, 0, sizeof (psargs));
+ if (string_end != NULL)
+ {
+ *string_end++ = ' ';
+ strncpy (string_end, get_inferior_args (),
+ psargs_end - string_end);
+ }
}
note_data = (char *) elfcore_write_prpsinfo (obfd,
note_data,
char permissions[8], device[8], filename[MAXPATHLEN];
printf_filtered (_("Mapped address spaces:\n\n"));
- if (TARGET_ADDR_BIT == 32)
+ if (gdbarch_addr_bit (current_gdbarch) == 32)
{
printf_filtered ("\t%10s %10s %10s %10s %7s\n",
"Start Addr",
a generic local_address_string instead to print out
the addresses; that makes sense to me, too. */
- if (TARGET_ADDR_BIT == 32)
+ if (gdbarch_addr_bit (current_gdbarch) == 32)
{
printf_filtered ("\t%#10lx %#10lx %#10x %#10x %7s\n",
(unsigned long) addr, /* FIXME: pr_addr */
{
int itmp;
char ctmp;
+ long ltmp;
if (fscanf (procfile, "%d ", &itmp) > 0)
printf_filtered (_("Process: %d\n"), itmp);
- if (fscanf (procfile, "%s ", &buffer[0]) > 0)
+ if (fscanf (procfile, "(%[^)]) ", &buffer[0]) > 0)
printf_filtered (_("Exec file: %s\n"), buffer);
if (fscanf (procfile, "%c ", &ctmp) > 0)
printf_filtered (_("State: %c\n"), ctmp);
printf_filtered (_("TTY: %d\n"), itmp);
if (fscanf (procfile, "%d ", &itmp) > 0)
printf_filtered (_("TTY owner process group: %d\n"), itmp);
- if (fscanf (procfile, "%u ", &itmp) > 0)
- printf_filtered (_("Flags: 0x%x\n"), itmp);
- if (fscanf (procfile, "%u ", &itmp) > 0)
- printf_filtered (_("Minor faults (no memory page): %u\n"),
- (unsigned int) itmp);
- if (fscanf (procfile, "%u ", &itmp) > 0)
- printf_filtered (_("Minor faults, children: %u\n"),
- (unsigned int) itmp);
- if (fscanf (procfile, "%u ", &itmp) > 0)
- printf_filtered (_("Major faults (memory page faults): %u\n"),
- (unsigned int) itmp);
- if (fscanf (procfile, "%u ", &itmp) > 0)
- printf_filtered (_("Major faults, children: %u\n"),
- (unsigned int) itmp);
- if (fscanf (procfile, "%d ", &itmp) > 0)
- printf_filtered ("utime: %d\n", itmp);
- if (fscanf (procfile, "%d ", &itmp) > 0)
- printf_filtered ("stime: %d\n", itmp);
- if (fscanf (procfile, "%d ", &itmp) > 0)
- printf_filtered ("utime, children: %d\n", itmp);
- if (fscanf (procfile, "%d ", &itmp) > 0)
- printf_filtered ("stime, children: %d\n", itmp);
- if (fscanf (procfile, "%d ", &itmp) > 0)
- printf_filtered (_("jiffies remaining in current time slice: %d\n"),
- itmp);
- if (fscanf (procfile, "%d ", &itmp) > 0)
- printf_filtered ("'nice' value: %d\n", itmp);
- if (fscanf (procfile, "%u ", &itmp) > 0)
- printf_filtered (_("jiffies until next timeout: %u\n"),
- (unsigned int) itmp);
- if (fscanf (procfile, "%u ", &itmp) > 0)
- printf_filtered ("jiffies until next SIGALRM: %u\n",
- (unsigned int) itmp);
- if (fscanf (procfile, "%d ", &itmp) > 0)
- printf_filtered (_("start time (jiffies since system boot): %d\n"),
- itmp);
- if (fscanf (procfile, "%u ", &itmp) > 0)
- printf_filtered (_("Virtual memory size: %u\n"),
- (unsigned int) itmp);
- if (fscanf (procfile, "%u ", &itmp) > 0)
- printf_filtered (_("Resident set size: %u\n"), (unsigned int) itmp);
- if (fscanf (procfile, "%u ", &itmp) > 0)
- printf_filtered ("rlim: %u\n", (unsigned int) itmp);
- if (fscanf (procfile, "%u ", &itmp) > 0)
- printf_filtered (_("Start of text: 0x%x\n"), itmp);
- if (fscanf (procfile, "%u ", &itmp) > 0)
- printf_filtered (_("End of text: 0x%x\n"), itmp);
- if (fscanf (procfile, "%u ", &itmp) > 0)
- printf_filtered (_("Start of stack: 0x%x\n"), itmp);
+ if (fscanf (procfile, "%lu ", <mp) > 0)
+ printf_filtered (_("Flags: 0x%lx\n"), ltmp);
+ if (fscanf (procfile, "%lu ", <mp) > 0)
+ printf_filtered (_("Minor faults (no memory page): %lu\n"),
+ (unsigned long) ltmp);
+ if (fscanf (procfile, "%lu ", <mp) > 0)
+ printf_filtered (_("Minor faults, children: %lu\n"),
+ (unsigned long) ltmp);
+ if (fscanf (procfile, "%lu ", <mp) > 0)
+ printf_filtered (_("Major faults (memory page faults): %lu\n"),
+ (unsigned long) ltmp);
+ if (fscanf (procfile, "%lu ", <mp) > 0)
+ printf_filtered (_("Major faults, children: %lu\n"),
+ (unsigned long) ltmp);
+ if (fscanf (procfile, "%ld ", <mp) > 0)
+ printf_filtered (_("utime: %ld\n"), ltmp);
+ if (fscanf (procfile, "%ld ", <mp) > 0)
+ printf_filtered (_("stime: %ld\n"), ltmp);
+ if (fscanf (procfile, "%ld ", <mp) > 0)
+ printf_filtered (_("utime, children: %ld\n"), ltmp);
+ if (fscanf (procfile, "%ld ", <mp) > 0)
+ printf_filtered (_("stime, children: %ld\n"), ltmp);
+ if (fscanf (procfile, "%ld ", <mp) > 0)
+ printf_filtered (_("jiffies remaining in current time slice: %ld\n"),
+ ltmp);
+ if (fscanf (procfile, "%ld ", <mp) > 0)
+ printf_filtered (_("'nice' value: %ld\n"), ltmp);
+ if (fscanf (procfile, "%lu ", <mp) > 0)
+ printf_filtered (_("jiffies until next timeout: %lu\n"),
+ (unsigned long) ltmp);
+ if (fscanf (procfile, "%lu ", <mp) > 0)
+ printf_filtered (_("jiffies until next SIGALRM: %lu\n"),
+ (unsigned long) ltmp);
+ if (fscanf (procfile, "%ld ", <mp) > 0)
+ printf_filtered (_("start time (jiffies since system boot): %ld\n"),
+ ltmp);
+ if (fscanf (procfile, "%lu ", <mp) > 0)
+ printf_filtered (_("Virtual memory size: %lu\n"),
+ (unsigned long) ltmp);
+ if (fscanf (procfile, "%lu ", <mp) > 0)
+ printf_filtered (_("Resident set size: %lu\n"), (unsigned long) ltmp);
+ if (fscanf (procfile, "%lu ", <mp) > 0)
+ printf_filtered (_("rlim: %lu\n"), (unsigned long) ltmp);
+ if (fscanf (procfile, "%lu ", <mp) > 0)
+ printf_filtered (_("Start of text: 0x%lx\n"), ltmp);
+ if (fscanf (procfile, "%lu ", <mp) > 0)
+ printf_filtered (_("End of text: 0x%lx\n"), ltmp);
+ if (fscanf (procfile, "%lu ", <mp) > 0)
+ printf_filtered (_("Start of stack: 0x%lx\n"), ltmp);
#if 0 /* Don't know how architecture-dependent the rest is...
Anyway the signal bitmap info is available from "status". */
- if (fscanf (procfile, "%u ", &itmp) > 0) /* FIXME arch? */
- printf_filtered (_("Kernel stack pointer: 0x%x\n"), itmp);
- if (fscanf (procfile, "%u ", &itmp) > 0) /* FIXME arch? */
- printf_filtered (_("Kernel instr pointer: 0x%x\n"), itmp);
- if (fscanf (procfile, "%d ", &itmp) > 0)
- printf_filtered (_("Pending signals bitmap: 0x%x\n"), itmp);
- if (fscanf (procfile, "%d ", &itmp) > 0)
- printf_filtered (_("Blocked signals bitmap: 0x%x\n"), itmp);
- if (fscanf (procfile, "%d ", &itmp) > 0)
- printf_filtered (_("Ignored signals bitmap: 0x%x\n"), itmp);
- if (fscanf (procfile, "%d ", &itmp) > 0)
- printf_filtered (_("Catched signals bitmap: 0x%x\n"), itmp);
- if (fscanf (procfile, "%u ", &itmp) > 0) /* FIXME arch? */
- printf_filtered (_("wchan (system call): 0x%x\n"), itmp);
+ if (fscanf (procfile, "%lu ", <mp) > 0) /* FIXME arch? */
+ printf_filtered (_("Kernel stack pointer: 0x%lx\n"), ltmp);
+ if (fscanf (procfile, "%lu ", <mp) > 0) /* FIXME arch? */
+ printf_filtered (_("Kernel instr pointer: 0x%lx\n"), ltmp);
+ if (fscanf (procfile, "%ld ", <mp) > 0)
+ printf_filtered (_("Pending signals bitmap: 0x%lx\n"), ltmp);
+ if (fscanf (procfile, "%ld ", <mp) > 0)
+ printf_filtered (_("Blocked signals bitmap: 0x%lx\n"), ltmp);
+ if (fscanf (procfile, "%ld ", <mp) > 0)
+ printf_filtered (_("Ignored signals bitmap: 0x%lx\n"), ltmp);
+ if (fscanf (procfile, "%ld ", <mp) > 0)
+ printf_filtered (_("Catched signals bitmap: 0x%lx\n"), ltmp);
+ if (fscanf (procfile, "%lu ", <mp) > 0) /* FIXME arch? */
+ printf_filtered (_("wchan (system call): 0x%lx\n"), ltmp);
#endif
fclose (procfile);
}
offset, len);
}
-#ifndef FETCH_INFERIOR_REGISTERS
-
-/* Return the address in the core dump or inferior of register
- REGNO. */
+/* Create a prototype generic Linux target. The client can override
+ it with local methods. */
-static CORE_ADDR
-linux_register_u_offset (int regno)
+static void
+linux_target_install_ops (struct target_ops *t)
{
- /* FIXME drow/2005-09-04: The hardcoded use of register_addr should go
- away. This requires disentangling the various definitions of it
- (particularly alpha-nat.c's). */
- return register_addr (regno, 0);
-}
-
-#endif
+ t->to_insert_fork_catchpoint = linux_child_insert_fork_catchpoint;
+ t->to_insert_vfork_catchpoint = linux_child_insert_vfork_catchpoint;
+ t->to_insert_exec_catchpoint = linux_child_insert_exec_catchpoint;
+ t->to_pid_to_exec_file = linux_child_pid_to_exec_file;
+ t->to_post_startup_inferior = linux_child_post_startup_inferior;
+ t->to_post_attach = linux_child_post_attach;
+ t->to_follow_fork = linux_child_follow_fork;
+ t->to_find_memory_regions = linux_nat_find_memory_regions;
+ t->to_make_corefile_notes = linux_nat_make_corefile_notes;
-/* Create a prototype generic Linux target. The client can override
- it with local methods. */
+ super_xfer_partial = t->to_xfer_partial;
+ t->to_xfer_partial = linux_xfer_partial;
+}
struct target_ops *
linux_target (void)
{
struct target_ops *t;
-#ifdef FETCH_INFERIOR_REGISTERS
t = inf_ptrace_target ();
-#else
- t = inf_ptrace_trad_target (linux_register_u_offset);
-#endif
- t->to_insert_fork_catchpoint = child_insert_fork_catchpoint;
- t->to_insert_vfork_catchpoint = child_insert_vfork_catchpoint;
- t->to_insert_exec_catchpoint = child_insert_exec_catchpoint;
- t->to_pid_to_exec_file = child_pid_to_exec_file;
- t->to_post_startup_inferior = linux_child_post_startup_inferior;
- t->to_post_attach = child_post_attach;
- t->to_follow_fork = child_follow_fork;
- t->to_find_memory_regions = linux_nat_find_memory_regions;
- t->to_make_corefile_notes = linux_nat_make_corefile_notes;
+ linux_target_install_ops (t);
- super_xfer_partial = t->to_xfer_partial;
- t->to_xfer_partial = linux_xfer_partial;
+ return t;
+}
+
+struct target_ops *
+linux_trad_target (CORE_ADDR (*register_u_offset)(struct gdbarch *, int, int))
+{
+ struct target_ops *t;
+
+ t = inf_ptrace_trad_target (register_u_offset);
+ linux_target_install_ops (t);
return t;
}