#include <sys/vfs.h>
#include "solib.h"
#include "linux-osdata.h"
-#include "cli/cli-utils.h"
+#include "linux-tdep.h"
#ifndef SPUFS_MAGIC
#define SPUFS_MAGIC 0x23c9b64e
struct lwp_info;
static struct lwp_info *add_lwp (ptid_t ptid);
static void purge_lwp_list (int pid);
+static void delete_lwp (ptid_t ptid);
static struct lwp_info *find_lwp_pid (ptid_t ptid);
\f
linux_enable_tracesysgood (ptid);
}
+/* Return the number of known LWPs in the tgid given by PID. */
+
+static int
+num_lwps (int pid)
+{
+ int count = 0;
+ struct lwp_info *lp;
+
+ for (lp = lwp_list; lp; lp = lp->next)
+ if (ptid_get_pid (lp->ptid) == pid)
+ count++;
+
+ return count;
+}
+
+/* Call delete_lwp with prototype compatible for make_cleanup. */
+
+static void
+delete_lwp_cleanup (void *lp_voidp)
+{
+ struct lwp_info *lp = lp_voidp;
+
+ delete_lwp (lp->ptid);
+}
+
static int
linux_child_follow_fork (struct target_ops *ops, int follow_child)
{
/* Detach new forked process? */
if (detach_fork)
{
+ struct cleanup *old_chain;
+
/* Before detaching from the child, remove all breakpoints
from it. If we forked, then this has already been taken
care of by infrun.c. If we vforked however, any
child_pid);
}
+ old_chain = save_inferior_ptid ();
+ inferior_ptid = ptid_build (child_pid, child_pid, 0);
+
+ child_lp = add_lwp (inferior_ptid);
+ child_lp->stopped = 1;
+ child_lp->last_resume_kind = resume_stop;
+ make_cleanup (delete_lwp_cleanup, child_lp);
+
+ /* CHILD_LP has new PID, therefore linux_nat_new_thread is not called for it.
+ See i386_inferior_data_get for the Linux kernel specifics.
+ Ensure linux_nat_prepare_to_resume will reset the hardware debug
+ registers. It is done by the linux_nat_new_thread call, which is
+ being skipped in add_lwp above for the first lwp of a pid. */
+ gdb_assert (num_lwps (GET_PID (child_lp->ptid)) == 1);
+ if (linux_nat_new_thread != NULL)
+ linux_nat_new_thread (child_lp);
+
+ if (linux_nat_prepare_to_resume != NULL)
+ linux_nat_prepare_to_resume (child_lp);
ptrace (PTRACE_DETACH, child_pid, 0, 0);
+
+ do_cleanups (old_chain);
}
else
{
}
}
-/* Return the number of known LWPs in the tgid given by PID. */
-
-static int
-num_lwps (int pid)
-{
- int count = 0;
- struct lwp_info *lp;
-
- for (lp = lwp_list; lp; lp = lp->next)
- if (ptid_get_pid (lp->ptid) == pid)
- count++;
-
- return count;
-}
-
/* Add the LWP specified by PID to the list. Return a pointer to the
structure describing the new LWP. The LWP should already be stopped
(with an exception for the very first LWP). */
return NULL;
}
+/* Iterate like iterate_over_lwps does except when forking-off a child call
+ CALLBACK with CALLBACK_DATA specifically only for that new child PID. */
+
+void
+linux_nat_iterate_watchpoint_lwps
+ (linux_nat_iterate_watchpoint_lwps_ftype callback, void *callback_data)
+{
+ int inferior_pid = ptid_get_pid (inferior_ptid);
+ struct inferior *inf = current_inferior ();
+
+ if (inf->pid == inferior_pid)
+ {
+ /* Iterate all the threads of the current inferior. Without specifying
+ INFERIOR_PID it would iterate all threads of all inferiors, which is
+ inappropriate for watchpoints. */
+
+ iterate_over_lwps (pid_to_ptid (inferior_pid), callback, callback_data);
+ }
+ else
+ {
+ /* Detaching a new child PID temporarily present in INFERIOR_PID. */
+
+ struct lwp_info *child_lp;
+ struct cleanup *old_chain;
+ pid_t child_pid = GET_PID (inferior_ptid);
+ ptid_t child_ptid = ptid_build (child_pid, child_pid, 0);
+
+ gdb_assert (!is_lwp (inferior_ptid));
+ gdb_assert (find_lwp_pid (child_ptid) == NULL);
+ child_lp = add_lwp (child_ptid);
+ child_lp->stopped = 1;
+ child_lp->last_resume_kind = resume_stop;
+ old_chain = make_cleanup (delete_lwp_cleanup, child_lp);
+
+ callback (child_lp, callback_data);
+
+ do_cleanups (old_chain);
+ }
+}
+
/* Update our internal state when changing from one checkpoint to
another indicated by NEW_PTID. We can only switch single-threaded
applications, so we only create one new LWP, and the previous list
return name1;
}
-/* Service function for corefiles and info proc. */
-
-static int
-read_mapping (FILE *mapfile,
- long long *addr,
- long long *endaddr,
- char *permissions,
- long long *offset,
- char *device, long long *inode, char *filename)
-{
- int ret = fscanf (mapfile, "%llx-%llx %s %llx %s %llx",
- addr, endaddr, permissions, offset, device, inode);
-
- filename[0] = '\0';
- if (ret > 0 && ret != EOF)
- {
- /* Eat everything up to EOL for the filename. This will prevent
- weird filenames (such as one with embedded whitespace) from
- confusing this code. It also makes this code more robust in
- respect to annotations the kernel may add after the filename.
-
- Note the filename is used for informational purposes
- only. */
- ret += fscanf (mapfile, "%[^\n]\n", filename);
- }
-
- return (ret != 0 && ret != EOF);
-}
-
-/* Fills the "to_find_memory_regions" target vector. Lists the memory
- regions in the inferior for a corefile. */
-
-static int
-linux_nat_find_memory_regions (find_memory_region_ftype func, void *obfd)
-{
- int pid = PIDGET (inferior_ptid);
- char mapsfilename[MAXPATHLEN];
- FILE *mapsfile;
- long long addr, endaddr, size, offset, inode;
- char permissions[8], device[8], filename[MAXPATHLEN];
- int read, write, exec;
- struct cleanup *cleanup;
-
- /* Compose the filename for the /proc memory map, and open it. */
- sprintf (mapsfilename, "/proc/%d/maps", pid);
- if ((mapsfile = fopen (mapsfilename, "r")) == NULL)
- error (_("Could not open %s."), mapsfilename);
- cleanup = make_cleanup_fclose (mapsfile);
-
- if (info_verbose)
- fprintf_filtered (gdb_stdout,
- "Reading memory regions from %s\n", mapsfilename);
-
- /* Now iterate until end-of-file. */
- while (read_mapping (mapsfile, &addr, &endaddr, &permissions[0],
- &offset, &device[0], &inode, &filename[0]))
- {
- size = endaddr - addr;
-
- /* Get the segment's permissions. */
- read = (strchr (permissions, 'r') != 0);
- write = (strchr (permissions, 'w') != 0);
- exec = (strchr (permissions, 'x') != 0);
-
- if (info_verbose)
- {
- fprintf_filtered (gdb_stdout,
- "Save segment, %s bytes at %s (%c%c%c)",
- plongest (size), paddress (target_gdbarch, addr),
- read ? 'r' : ' ',
- write ? 'w' : ' ', exec ? 'x' : ' ');
- if (filename[0])
- fprintf_filtered (gdb_stdout, " for %s", filename);
- fprintf_filtered (gdb_stdout, "\n");
- }
-
- /* Invoke the callback function to create the corefile
- segment. */
- func (addr, size, read, write, exec, obfd);
- }
- do_cleanups (cleanup);
- return 0;
-}
-
-static int
-find_signalled_thread (struct thread_info *info, void *data)
-{
- if (info->suspend.stop_signal != TARGET_SIGNAL_0
- && ptid_get_pid (info->ptid) == ptid_get_pid (inferior_ptid))
- return 1;
-
- return 0;
-}
-
-static enum target_signal
-find_stop_signal (void)
-{
- struct thread_info *info =
- iterate_over_threads (find_signalled_thread, NULL);
-
- if (info)
- return info->suspend.stop_signal;
- else
- return TARGET_SIGNAL_0;
-}
-
/* Records the thread's register state for the corefile note
section. */
static char *
-linux_nat_do_thread_registers (bfd *obfd, ptid_t ptid,
- char *note_data, int *note_size,
- enum target_signal stop_signal)
+linux_nat_collect_thread_registers (const struct regcache *regcache,
+ ptid_t ptid, bfd *obfd,
+ char *note_data, int *note_size,
+ enum target_signal stop_signal)
{
- unsigned long lwp = ptid_get_lwp (ptid);
- struct gdbarch *gdbarch = target_gdbarch;
- struct regcache *regcache = get_thread_arch_regcache (ptid, gdbarch);
+ struct gdbarch *gdbarch = get_regcache_arch (regcache);
const struct regset *regset;
int core_regset_p;
- struct cleanup *old_chain;
- struct core_regset_section *sect_list;
- char *gdb_regset;
-
- old_chain = save_inferior_ptid ();
- inferior_ptid = ptid;
- target_fetch_registers (regcache, -1);
- do_cleanups (old_chain);
+ gdb_gregset_t gregs;
+ gdb_fpregset_t fpregs;
core_regset_p = gdbarch_regset_from_core_section_p (gdbarch);
- sect_list = gdbarch_core_regset_sections (gdbarch);
-
- /* The loop below uses the new struct core_regset_section, which stores
- the supported section names and sizes for the core file. Note that
- note PRSTATUS needs to be treated specially. But the other notes are
- structurally the same, so they can benefit from the new struct. */
- if (core_regset_p && sect_list != NULL)
- while (sect_list->sect_name != NULL)
- {
- regset = gdbarch_regset_from_core_section (gdbarch,
- sect_list->sect_name,
- sect_list->size);
- gdb_assert (regset && regset->collect_regset);
- gdb_regset = xmalloc (sect_list->size);
- regset->collect_regset (regset, regcache, -1,
- gdb_regset, sect_list->size);
-
- if (strcmp (sect_list->sect_name, ".reg") == 0)
- note_data = (char *) elfcore_write_prstatus
- (obfd, note_data, note_size,
- lwp, target_signal_to_host (stop_signal),
- gdb_regset);
- else
- note_data = (char *) elfcore_write_register_note
- (obfd, note_data, note_size,
- sect_list->sect_name, gdb_regset,
- sect_list->size);
- xfree (gdb_regset);
- sect_list++;
- }
- /* For architectures that does not have the struct core_regset_section
- implemented, we use the old method. When all the architectures have
- the new support, the code below should be deleted. */
+ if (core_regset_p
+ && (regset = gdbarch_regset_from_core_section (gdbarch, ".reg",
+ sizeof (gregs)))
+ != NULL && regset->collect_regset != NULL)
+ regset->collect_regset (regset, regcache, -1, &gregs, sizeof (gregs));
else
- {
- gdb_gregset_t gregs;
- gdb_fpregset_t fpregs;
-
- if (core_regset_p
- && (regset = gdbarch_regset_from_core_section (gdbarch, ".reg",
- sizeof (gregs)))
- != NULL && regset->collect_regset != NULL)
- regset->collect_regset (regset, regcache, -1,
- &gregs, sizeof (gregs));
- else
- fill_gregset (regcache, &gregs, -1);
+ fill_gregset (regcache, &gregs, -1);
- note_data = (char *) elfcore_write_prstatus
- (obfd, note_data, note_size, lwp, target_signal_to_host (stop_signal),
- &gregs);
+ note_data = (char *) elfcore_write_prstatus
+ (obfd, note_data, note_size, ptid_get_lwp (ptid),
+ target_signal_to_host (stop_signal), &gregs);
- if (core_regset_p
- && (regset = gdbarch_regset_from_core_section (gdbarch, ".reg2",
- sizeof (fpregs)))
+ if (core_regset_p
+ && (regset = gdbarch_regset_from_core_section (gdbarch, ".reg2",
+ sizeof (fpregs)))
!= NULL && regset->collect_regset != NULL)
- regset->collect_regset (regset, regcache, -1,
- &fpregs, sizeof (fpregs));
- else
- fill_fpregset (regcache, &fpregs, -1);
+ regset->collect_regset (regset, regcache, -1, &fpregs, sizeof (fpregs));
+ else
+ fill_fpregset (regcache, &fpregs, -1);
- note_data = (char *) elfcore_write_prfpreg (obfd,
- note_data,
- note_size,
- &fpregs, sizeof (fpregs));
- }
+ note_data = (char *) elfcore_write_prfpreg (obfd, note_data, note_size,
+ &fpregs, sizeof (fpregs));
return note_data;
}
-struct linux_nat_corefile_thread_data
-{
- bfd *obfd;
- char *note_data;
- int *note_size;
- int num_notes;
- enum target_signal stop_signal;
-};
-
-/* Called by gdbthread.c once per thread. Records the thread's
- register state for the corefile note section. */
-
-static int
-linux_nat_corefile_thread_callback (struct lwp_info *ti, void *data)
-{
- struct linux_nat_corefile_thread_data *args = data;
-
- args->note_data = linux_nat_do_thread_registers (args->obfd,
- ti->ptid,
- args->note_data,
- args->note_size,
- args->stop_signal);
- args->num_notes++;
-
- return 0;
-}
-
-/* Enumerate spufs IDs for process PID. */
-
-static void
-iterate_over_spus (int pid, void (*callback) (void *, int), void *data)
-{
- char path[128];
- DIR *dir;
- struct dirent *entry;
-
- xsnprintf (path, sizeof path, "/proc/%d/fd", pid);
- dir = opendir (path);
- if (!dir)
- return;
-
- rewinddir (dir);
- while ((entry = readdir (dir)) != NULL)
- {
- struct stat st;
- struct statfs stfs;
- int fd;
-
- fd = atoi (entry->d_name);
- if (!fd)
- continue;
-
- xsnprintf (path, sizeof path, "/proc/%d/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;
-
- callback (data, fd);
- }
-
- closedir (dir);
-}
-
-/* Generate corefile notes for SPU contexts. */
-
-struct linux_spu_corefile_data
-{
- bfd *obfd;
- char *note_data;
- int *note_size;
-};
-
-static void
-linux_spu_corefile_callback (void *data, int fd)
-{
- struct linux_spu_corefile_data *args = data;
- int i;
-
- static const char *spu_files[] =
- {
- "object-id",
- "mem",
- "regs",
- "fpcr",
- "lslr",
- "decr",
- "decr_status",
- "signal1",
- "signal1_type",
- "signal2",
- "signal2_type",
- "event_mask",
- "event_status",
- "mbox_info",
- "ibox_info",
- "wbox_info",
- "dma_info",
- "proxydma_info",
- };
-
- for (i = 0; i < sizeof (spu_files) / sizeof (spu_files[0]); i++)
- {
- char annex[32], note_name[32];
- gdb_byte *spu_data;
- LONGEST spu_len;
-
- xsnprintf (annex, sizeof annex, "%d/%s", fd, spu_files[i]);
- spu_len = target_read_alloc (¤t_target, TARGET_OBJECT_SPU,
- annex, &spu_data);
- if (spu_len > 0)
- {
- xsnprintf (note_name, sizeof note_name, "SPU/%s", annex);
- args->note_data = elfcore_write_note (args->obfd, args->note_data,
- args->note_size, note_name,
- NT_SPU, spu_data, spu_len);
- xfree (spu_data);
- }
- }
-}
-
-static char *
-linux_spu_make_corefile_notes (bfd *obfd, char *note_data, int *note_size)
-{
- struct linux_spu_corefile_data args;
-
- args.obfd = obfd;
- args.note_data = note_data;
- args.note_size = note_size;
-
- iterate_over_spus (PIDGET (inferior_ptid),
- linux_spu_corefile_callback, &args);
-
- return args.note_data;
-}
-
/* Fills the "to_make_corefile_note" target vector. Builds the note
section for a corefile, and returns it in a malloc buffer. */
static char *
linux_nat_make_corefile_notes (bfd *obfd, int *note_size)
{
- struct linux_nat_corefile_thread_data thread_args;
- /* 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 filter = pid_to_ptid (ptid_get_pid (inferior_ptid));
- gdb_byte *auxv;
- int auxv_len;
-
- if (get_exec_file (0))
- {
- strncpy (fname, lbasename (get_exec_file (0)), sizeof (fname));
- strncpy (psargs, get_exec_file (0), sizeof (psargs));
- if (get_inferior_args ())
- {
- 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,
- note_size, fname, psargs);
- }
-
- /* Dump information for threads. */
- thread_args.obfd = obfd;
- thread_args.note_data = note_data;
- thread_args.note_size = note_size;
- thread_args.num_notes = 0;
- thread_args.stop_signal = find_stop_signal ();
- iterate_over_lwps (filter, linux_nat_corefile_thread_callback, &thread_args);
- gdb_assert (thread_args.num_notes != 0);
- note_data = thread_args.note_data;
-
- auxv_len = target_read_alloc (¤t_target, TARGET_OBJECT_AUXV,
- NULL, &auxv);
- if (auxv_len > 0)
- {
- note_data = elfcore_write_note (obfd, note_data, note_size,
- "CORE", NT_AUXV, auxv, auxv_len);
- xfree (auxv);
- }
-
- note_data = linux_spu_make_corefile_notes (obfd, note_data, note_size);
-
- make_cleanup (xfree, note_data);
- return note_data;
-}
-
-/* Implement the "info proc" command. */
-
-static void
-linux_nat_info_proc (struct target_ops *ops, char *args,
- enum info_proc_what what)
-{
- /* A long is used for pid instead of an int to avoid a loss of precision
- compiler warning from the output of strtoul. */
- long pid = PIDGET (inferior_ptid);
- FILE *procfile;
- char buffer[MAXPATHLEN];
- char fname1[MAXPATHLEN], fname2[MAXPATHLEN];
- int cmdline_f = (what == IP_MINIMAL || what == IP_CMDLINE || what == IP_ALL);
- int cwd_f = (what == IP_MINIMAL || what == IP_CWD || what == IP_ALL);
- int exe_f = (what == IP_MINIMAL || what == IP_EXE || what == IP_ALL);
- int mappings_f = (what == IP_MAPPINGS || what == IP_ALL);
- int status_f = (what == IP_STATUS || what == IP_ALL);
- int stat_f = (what == IP_STAT || what == IP_ALL);
- struct stat dummy;
-
- if (args && isdigit (args[0]))
- pid = strtoul (args, &args, 10);
-
- args = skip_spaces (args);
- if (args && args[0])
- error (_("Too many parameters: %s"), args);
-
- if (pid == 0)
- error (_("No current process: you must name one."));
-
- sprintf (fname1, "/proc/%ld", pid);
- if (stat (fname1, &dummy) != 0)
- error (_("No /proc directory: '%s'"), fname1);
-
- printf_filtered (_("process %ld\n"), pid);
- if (cmdline_f)
- {
- sprintf (fname1, "/proc/%ld/cmdline", pid);
- if ((procfile = fopen (fname1, "r")) != NULL)
- {
- struct cleanup *cleanup = make_cleanup_fclose (procfile);
-
- if (fgets (buffer, sizeof (buffer), procfile))
- printf_filtered ("cmdline = '%s'\n", buffer);
- else
- warning (_("unable to read '%s'"), fname1);
- do_cleanups (cleanup);
- }
- else
- warning (_("unable to open /proc file '%s'"), fname1);
- }
- if (cwd_f)
- {
- sprintf (fname1, "/proc/%ld/cwd", pid);
- memset (fname2, 0, sizeof (fname2));
- if (readlink (fname1, fname2, sizeof (fname2)) > 0)
- printf_filtered ("cwd = '%s'\n", fname2);
- else
- warning (_("unable to read link '%s'"), fname1);
- }
- if (exe_f)
- {
- sprintf (fname1, "/proc/%ld/exe", pid);
- memset (fname2, 0, sizeof (fname2));
- if (readlink (fname1, fname2, sizeof (fname2)) > 0)
- printf_filtered ("exe = '%s'\n", fname2);
- else
- warning (_("unable to read link '%s'"), fname1);
- }
- if (mappings_f)
- {
- sprintf (fname1, "/proc/%ld/maps", pid);
- if ((procfile = fopen (fname1, "r")) != NULL)
- {
- long long addr, endaddr, size, offset, inode;
- char permissions[8], device[8], filename[MAXPATHLEN];
- struct cleanup *cleanup;
-
- cleanup = make_cleanup_fclose (procfile);
- printf_filtered (_("Mapped address spaces:\n\n"));
- if (gdbarch_addr_bit (target_gdbarch) == 32)
- {
- printf_filtered ("\t%10s %10s %10s %10s %7s\n",
- "Start Addr",
- " End Addr",
- " Size", " Offset", "objfile");
- }
- else
- {
- printf_filtered (" %18s %18s %10s %10s %7s\n",
- "Start Addr",
- " End Addr",
- " Size", " Offset", "objfile");
- }
-
- while (read_mapping (procfile, &addr, &endaddr, &permissions[0],
- &offset, &device[0], &inode, &filename[0]))
- {
- size = endaddr - addr;
-
- /* FIXME: carlton/2003-08-27: Maybe the printf_filtered
- calls here (and possibly above) should be abstracted
- out into their own functions? Andrew suggests using
- a generic local_address_string instead to print out
- the addresses; that makes sense to me, too. */
-
- if (gdbarch_addr_bit (target_gdbarch) == 32)
- {
- printf_filtered ("\t%#10lx %#10lx %#10x %#10x %7s\n",
- (unsigned long) addr, /* FIXME: pr_addr */
- (unsigned long) endaddr,
- (int) size,
- (unsigned int) offset,
- filename[0] ? filename : "");
- }
- else
- {
- printf_filtered (" %#18lx %#18lx %#10x %#10x %7s\n",
- (unsigned long) addr, /* FIXME: pr_addr */
- (unsigned long) endaddr,
- (int) size,
- (unsigned int) offset,
- filename[0] ? filename : "");
- }
- }
-
- do_cleanups (cleanup);
- }
- else
- warning (_("unable to open /proc file '%s'"), fname1);
- }
- if (status_f)
- {
- sprintf (fname1, "/proc/%ld/status", pid);
- if ((procfile = fopen (fname1, "r")) != NULL)
- {
- struct cleanup *cleanup = make_cleanup_fclose (procfile);
-
- while (fgets (buffer, sizeof (buffer), procfile) != NULL)
- puts_filtered (buffer);
- do_cleanups (cleanup);
- }
- else
- warning (_("unable to open /proc file '%s'"), fname1);
- }
- if (stat_f)
- {
- sprintf (fname1, "/proc/%ld/stat", pid);
- if ((procfile = fopen (fname1, "r")) != NULL)
- {
- int itmp;
- char ctmp;
- long ltmp;
- struct cleanup *cleanup = make_cleanup_fclose (procfile);
-
- if (fscanf (procfile, "%d ", &itmp) > 0)
- printf_filtered (_("Process: %d\n"), itmp);
- 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);
- if (fscanf (procfile, "%d ", &itmp) > 0)
- printf_filtered (_("Parent process: %d\n"), itmp);
- if (fscanf (procfile, "%d ", &itmp) > 0)
- printf_filtered (_("Process group: %d\n"), itmp);
- if (fscanf (procfile, "%d ", &itmp) > 0)
- printf_filtered (_("Session id: %d\n"), itmp);
- if (fscanf (procfile, "%d ", &itmp) > 0)
- printf_filtered (_("TTY: %d\n"), itmp);
- if (fscanf (procfile, "%d ", &itmp) > 0)
- printf_filtered (_("TTY owner process group: %d\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, "%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
- do_cleanups (cleanup);
- }
- else
- warning (_("unable to open /proc file '%s'"), fname1);
- }
+ /* FIXME: uweigand/2011-10-06: Once all GNU/Linux architectures have been
+ converted to gdbarch_core_regset_sections, this function can go away. */
+ return linux_make_corefile_notes (target_gdbarch, obfd, note_size,
+ linux_nat_collect_thread_registers);
}
/* Implement the to_xfer_partial interface for memory reads using the /proc
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;
- t->to_info_proc = linux_nat_info_proc;
super_xfer_partial = t->to_xfer_partial;
t->to_xfer_partial = linux_xfer_partial;