#include "inferior.h"
#include "target.h"
#include "gdbcore.h"
+#include "elf-bfd.h" /* for elfcore_write_* */
#include "gdbcmd.h"
#include "gdbthread.h"
#include <sys/wait.h>
#include <signal.h>
#include <ctype.h>
+#include "gdb_assert.h"
+#include "inflow.h"
/*
* PROCFS.C
* Unixware
* AIX5
*
- * /proc works by immitating a file system: you open a simulated file
+ * /proc works by imitating a file system: you open a simulated file
* that represents the process you wish to interact with, and
* perform operations on that "file" in order to examine or change
* the state of the other process.
static char * procfs_make_note_section (bfd *, int *);
+static int procfs_can_use_hw_breakpoint (int, int, int);
+
struct target_ops procfs_ops; /* the target vector */
static void
procfs_ops.to_terminal_inferior = terminal_inferior;
procfs_ops.to_terminal_ours_for_output = terminal_ours_for_output;
procfs_ops.to_terminal_ours = terminal_ours;
+ procfs_ops.to_terminal_save_ours = terminal_save_ours;
procfs_ops.to_terminal_info = child_terminal_info;
procfs_ops.to_find_new_threads = procfs_find_new_threads;
procfs_ops.to_has_thread_control = tc_schedlock;
procfs_ops.to_find_memory_regions = proc_find_memory_regions;
procfs_ops.to_make_corefile_notes = procfs_make_note_section;
+ procfs_ops.to_can_use_hw_breakpoint = procfs_can_use_hw_breakpoint;
procfs_ops.to_magic = OPS_MAGIC;
}
}
+/* Convert a target address (a.k.a. CORE_ADDR) into a host address
+ (a.k.a void pointer)! */
+
+static void *
+procfs_address_to_host_pointer (CORE_ADDR addr)
+{
+ void *ptr;
+
+ gdb_assert (sizeof (ptr) == TYPE_LENGTH (builtin_type_void_data_ptr));
+ ADDRESS_TO_POINTER (builtin_type_void_data_ptr, &ptr, addr);
+ return ptr;
+}
+
/*
* Function: proc_set_watchpoint
*
prwatch_t *pwatch;
pwatch = (prwatch_t *) &arg.watch;
+ /* NOTE: cagney/2003-02-01: Even more horrible hack. Need to
+ convert a target address into something that can be stored in a
+ native data structure. */
#ifdef PCAGENT /* Horrible hack: only defined on Solaris 2.6+ */
- pwatch->pr_vaddr = (uintptr_t) address_to_host_pointer (addr);
+ pwatch->pr_vaddr = (uintptr_t) procfs_address_to_host_pointer (addr);
#else
- pwatch->pr_vaddr = (caddr_t) address_to_host_pointer (addr);
+ pwatch->pr_vaddr = (caddr_t) procfs_address_to_host_pointer (addr);
#endif
pwatch->pr_size = len;
pwatch->pr_wflags = wflags;
if (!proc_clear_current_fault (pi))
proc_warn (pi, "do_detach, clear_current_fault", __LINE__);
+ if (signo == 0 && !proc_clear_current_signal (pi))
+ proc_warn (pi, "do_detach, clear_current_signal", __LINE__);
+
if (!proc_set_run_on_last_close (pi))
proc_warn (pi, "do_detach, set_rlc", __LINE__);
}
static void
procfs_stop (void)
{
- extern pid_t inferior_process_group;
-
kill (-inferior_process_group, SIGINT);
}
return 0;
}
+/* Return non-zero if we can set a hardware watchpoint of type TYPE. TYPE
+ is one of bp_hardware_watchpoint, bp_read_watchpoint, bp_write_watchpoint,
+ or bp_hardware_watchpoint. CNT is the number of watchpoints used so
+ far.
+
+ Note: procfs_can_use_hw_breakpoint() is not yet used by all
+ procfs.c targets due to the fact that some of them still define
+ TARGET_CAN_USE_HARDWARE_WATCHPOINT. */
+
+static int
+procfs_can_use_hw_breakpoint (int type, int cnt, int othertype)
+{
+#ifndef TARGET_HAS_HARDWARE_WATCHPOINTS
+ return 0;
+#else
+ /* Due to the way that proc_set_watchpoint() is implemented, host
+ and target pointers must be of the same size. If they are not,
+ we can't use hardware watchpoints. This limitation is due to the
+ fact that proc_set_watchpoint() calls
+ procfs_address_to_host_pointer(); a close inspection of
+ procfs_address_to_host_pointer will reveal that an internal error
+ will be generated when the host and target pointer sizes are
+ different. */
+ if (sizeof (void *) != TYPE_LENGTH (builtin_type_void_data_ptr))
+ return 0;
+
+ /* Other tests here??? */
+
+ return 1;
+#endif
+}
+
/*
* Function: stopped_by_watchpoint
*
void *),
void *data)
{
- return (*func) (host_pointer_to_address ((void *) map->pr_vaddr),
+ return (*func) ((CORE_ADDR) map->pr_vaddr,
map->pr_size,
(map->pr_mflags & MA_READ) != 0,
(map->pr_mflags & MA_WRITE) != 0,
*/
static char *
-mappingflags (flags)
- long flags;
+mappingflags (long flags)
{
static char asciiflags[8];
-/* miscelaneous stubs: */
+/* miscellaneous stubs: */
/* The following satisfy a few random symbols mostly created by */
/* the solaris threads implementation, which I will chase down */
/* later. */
}
/* =================== GCORE .NOTE "MODULE" =================== */
+#if defined (UNIXWARE) || defined (PIOCOPENLWP) || defined (PCAGENT)
+/* gcore only implemented on solaris and unixware (so far) */
static char *
procfs_do_thread_registers (bfd *obfd, ptid_t ptid,
merged_pid = TIDGET (ptid) << 16 | PIDGET (ptid);
fill_gregset (&gregs, -1);
+#if defined (UNIXWARE)
+ note_data = (char *) elfcore_write_lwpstatus (obfd,
+ note_data,
+ note_size,
+ merged_pid,
+ stop_signal,
+ &gregs);
+#else
note_data = (char *) elfcore_write_prstatus (obfd,
- note_data,
- note_size,
+ note_data,
+ note_size,
merged_pid,
stop_signal,
- &gregs);
+ &gregs);
+#endif
fill_fpregset (&fpregs, -1);
note_data = (char *) elfcore_write_prfpreg (obfd,
note_data,
};
static int
-procfs_corefile_thread_callback (struct thread_info *ti, void *data)
+procfs_corefile_thread_callback (procinfo *pi, procinfo *thread, void *data)
{
struct procfs_corefile_thread_data *args = data;
- procinfo *pi = find_procinfo (PIDGET (ti->ptid), TIDGET (ti->ptid));
- if (pi != NULL && TIDGET (ti->ptid) != 0)
+ if (pi != NULL && thread->tid != 0)
{
ptid_t saved_ptid = inferior_ptid;
- inferior_ptid = ti->ptid;
- args->note_data = procfs_do_thread_registers (args->obfd, ti->ptid,
+ inferior_ptid = MERGEPID (pi->pid, thread->tid);
+ args->note_data = procfs_do_thread_registers (args->obfd, inferior_ptid,
args->note_data,
args->note_size);
inferior_ptid = saved_ptid;
char psargs[80] = {'\0'};
procinfo *pi = find_procinfo_or_die (PIDGET (inferior_ptid), 0);
char *note_data = NULL;
+ char *inf_args;
struct procfs_corefile_thread_data thread_args;
if (get_exec_file (0))
strncpy (fname, strrchr (get_exec_file (0), '/') + 1, sizeof (fname));
strncpy (psargs, get_exec_file (0),
sizeof (psargs));
- if (get_inferior_args ())
+
+ inf_args = get_inferior_args ();
+ if (inf_args && *inf_args &&
+ strlen (inf_args) < ((int) sizeof (psargs) - (int) strlen (psargs)))
{
strncat (psargs, " ",
sizeof (psargs) - strlen (psargs));
- strncat (psargs, get_inferior_args (),
+ strncat (psargs, inf_args,
sizeof (psargs) - strlen (psargs));
}
}
fname,
psargs);
+#ifdef UNIXWARE
+ fill_gregset (&gregs, -1);
+ note_data = elfcore_write_pstatus (obfd, note_data, note_size,
+ PIDGET (inferior_ptid),
+ stop_signal, &gregs);
+#endif
+
thread_args.obfd = obfd;
thread_args.note_data = note_data;
thread_args.note_size = note_size;
- iterate_over_threads (procfs_corefile_thread_callback, &thread_args);
+ proc_iterate_over_threads (pi, procfs_corefile_thread_callback, &thread_args);
+
if (thread_args.note_data == note_data)
{
/* iterate_over_threads didn't come up with any threads;
make_cleanup (xfree, note_data);
return note_data;
}
-
+#else /* !(Solaris or Unixware) */
+static char *
+procfs_make_note_section (bfd *obfd, int *note_size)
+{
+ error ("gcore not implemented for this host.");
+ return NULL; /* lint */
+}
+#endif /* Solaris or Unixware */
/* =================== END GCORE .NOTE "MODULE" =================== */