#include "cli/cli-decode.h" /* for add_info */
#include "gdb_string.h"
+#include <signal.h>
+
#include "linux-nat.h"
#ifndef O_LARGEFILE
};
/* Function: linux_corefile_thread_callback
- *
+ *
* Called by gdbthread.c once per thread.
* Records the thread's register state for the corefile note section.
*/
inferior_ptid = ti->ptid;
registers_changed ();
- target_fetch_registers (-1); /* FIXME should not be necessary;
+ target_fetch_registers (-1); /* FIXME should not be necessary;
fill_gregset should do it automatically. */
args->note_data = linux_do_thread_registers (args->obfd,
ti->ptid,
args->num_notes++;
inferior_ptid = saved_ptid;
registers_changed ();
- target_fetch_registers (-1); /* FIXME should not be necessary;
+ target_fetch_registers (-1); /* FIXME should not be necessary;
fill_gregset should do it automatically. */
return 0;
}
+/* Function: linux_do_registers
+ *
+ * Records the register state for the corefile note section.
+ */
+
+static char *
+linux_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_do_thread_registers (obfd,
+ ptid_build (ptid_get_pid (inferior_ptid),
+ ptid_get_pid (inferior_ptid),
+ 0),
+ note_data, note_size);
+ return note_data;
+}
+
/* Function: linux_make_note_section
*
* Fills the "to_make_corefile_note" target vector.
- * Builds the note section for a corefile, and returns it
- * in a malloc buffer.
+ * Builds the note section for a corefile, and returns it
+ * in a malloc buffer.
*/
static char *
char psargs[80] = { '\0' };
char *note_data = NULL;
ptid_t current_ptid = inferior_ptid;
+ char *auxv;
+ int auxv_len;
if (get_exec_file (0))
{
{
/* iterate_over_threads didn't come up with any threads;
just use inferior_ptid. */
- note_data = linux_do_thread_registers (obfd, inferior_ptid,
- note_data, note_size);
+ note_data = linux_do_registers (obfd, inferior_ptid,
+ note_data, note_size);
}
else
{
note_data = thread_args.note_data;
}
+ auxv_len = target_auxv_read (¤t_target, &auxv);
+ if (auxv_len > 0)
+ {
+ note_data = elfcore_write_note (obfd, note_data, note_size,
+ "CORE", NT_AUXV, auxv, auxv_len);
+ xfree (auxv);
+ }
+
make_cleanup (xfree, note_data);
return note_data;
}
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 0 /* Don't know how architecture-dependent the rest is...
+#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);
close (fd);
return ret;
}
+
+/* Parse LINE as a signal set and add its set bits to SIGS. */
+
+static void
+linux_proc_add_line_to_sigset (const char *line, sigset_t *sigs)
+{
+ int len = strlen (line) - 1;
+ const char *p;
+ int signum;
+
+ if (line[len] != '\n')
+ error ("Could not parse signal set: %s", line);
+
+ p = line;
+ signum = len * 4;
+ while (len-- > 0)
+ {
+ int digit;
+
+ if (*p >= '0' && *p <= '9')
+ digit = *p - '0';
+ else if (*p >= 'a' && *p <= 'f')
+ digit = *p - 'a' + 10;
+ else
+ error ("Could not parse signal set: %s", line);
+
+ signum -= 4;
+
+ if (digit & 1)
+ sigaddset (sigs, signum + 1);
+ if (digit & 2)
+ sigaddset (sigs, signum + 2);
+ if (digit & 4)
+ sigaddset (sigs, signum + 3);
+ if (digit & 8)
+ sigaddset (sigs, signum + 4);
+
+ p++;
+ }
+}
+
+/* Find process PID's pending signals from /proc/pid/status and set SIGS
+ to match. */
+
+void
+linux_proc_pending_signals (int pid, sigset_t *pending, sigset_t *blocked, sigset_t *ignored)
+{
+ FILE *procfile;
+ char buffer[MAXPATHLEN], fname[MAXPATHLEN];
+ int signum;
+
+ sigemptyset (pending);
+ sigemptyset (blocked);
+ sigemptyset (ignored);
+ sprintf (fname, "/proc/%d/status", pid);
+ procfile = fopen (fname, "r");
+ if (procfile == NULL)
+ error ("Could not open %s", fname);
+
+ while (fgets (buffer, MAXPATHLEN, procfile) != NULL)
+ {
+ /* Normal queued signals are on the SigPnd line in the status
+ file. However, 2.6 kernels also have a "shared" pending queue
+ for delivering signals to a thread group, so check for a ShdPnd
+ line also.
+
+ Unfortunately some Red Hat kernels include the shared pending queue
+ but not the ShdPnd status field. */
+
+ if (strncmp (buffer, "SigPnd:\t", 8) == 0)
+ linux_proc_add_line_to_sigset (buffer + 8, pending);
+ else if (strncmp (buffer, "ShdPnd:\t", 8) == 0)
+ linux_proc_add_line_to_sigset (buffer + 8, pending);
+ else if (strncmp (buffer, "SigBlk:\t", 8) == 0)
+ linux_proc_add_line_to_sigset (buffer + 8, blocked);
+ else if (strncmp (buffer, "SigIgn:\t", 8) == 0)
+ linux_proc_add_line_to_sigset (buffer + 8, ignored);
+ }
+
+ fclose (procfile);
+}