/* Machine independent support for SVR4 /proc (process file system) for GDB.
- Copyright (C) 1999, 2000, 2001, 2002, 2003, 2006, 2007
+ Copyright (C) 1999, 2000, 2001, 2002, 2003, 2006, 2007, 2008
Free Software Foundation, Inc.
Written by Michael Snyder at Cygnus Solutions.
static void procfs_detach (char *, int);
static void procfs_resume (ptid_t, int, enum target_signal);
static int procfs_can_run (void);
-static void procfs_stop (void);
+static void procfs_stop (ptid_t);
static void procfs_files_info (struct target_ops *);
static void procfs_fetch_registers (struct regcache *, int);
static void procfs_store_registers (struct regcache *, int);
struct target_ops procfs_ops; /* the target vector */
+#if defined (PR_MODEL_NATIVE) && (PR_MODEL_NATIVE == PR_MODEL_LP64)
+/* When GDB is built as 64-bit application on Solaris, the auxv data is
+ presented in 64-bit format. We need to provide a custom parser to handle
+ that. */
+static int
+procfs_auxv_parse (struct target_ops *ops, gdb_byte **readptr,
+ gdb_byte *endptr, CORE_ADDR *typep, CORE_ADDR *valp)
+{
+ const int pointer_size = TYPE_LENGTH (builtin_type_void_data_ptr);
+ gdb_byte *ptr = *readptr;
+
+ if (endptr == ptr)
+ return 0;
+
+ if (endptr - ptr < 8 * 2)
+ return -1;
+
+ *typep = extract_unsigned_integer (ptr, 4);
+ ptr += 8;
+ /* The size of data is always 64-bit. If the application is 32-bit,
+ it will be zero extended, as expected. */
+ *valp = extract_unsigned_integer (ptr, 8);
+ ptr += 8;
+
+ *readptr = ptr;
+ return 1;
+}
+#endif
+
static void
init_procfs_ops (void)
{
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;
+
+#if defined(PR_MODEL_NATIVE) && (PR_MODEL_NATIVE == PR_MODEL_LP64)
+ procfs_ops.to_auxv_parse = procfs_auxv_parse;
+#endif
+
procfs_ops.to_magic = OPS_MAGIC;
}
#endif
}
-#ifdef TM_I386SOL2_H /* Is it hokey to use this? */
+#if (defined(__i386__) || defined(__x86_64__)) && defined (sun)
#include <sys/sysi86.h>
#endif
}
-#endif /* TM_I386SOL2_H */
+/*
+ * Function: procfs_find_LDT_entry
+ *
+ * Input:
+ * ptid_t ptid; // The GDB-style pid-plus-LWP.
+ *
+ * Return:
+ * pointer to the corresponding LDT entry.
+ */
+
+struct ssd *
+procfs_find_LDT_entry (ptid_t ptid)
+{
+ gdb_gregset_t *gregs;
+ int key;
+ procinfo *pi;
+
+ /* Find procinfo for the lwp. */
+ if ((pi = find_procinfo (PIDGET (ptid), TIDGET (ptid))) == NULL)
+ {
+ warning (_("procfs_find_LDT_entry: could not find procinfo for %d:%d."),
+ PIDGET (ptid), TIDGET (ptid));
+ return NULL;
+ }
+ /* get its general registers. */
+ if ((gregs = proc_get_gregs (pi)) == NULL)
+ {
+ warning (_("procfs_find_LDT_entry: could not read gregs for %d:%d."),
+ PIDGET (ptid), TIDGET (ptid));
+ return NULL;
+ }
+ /* Now extract the GS register's lower 16 bits. */
+ key = (*gregs)[GS] & 0xffff;
+
+ /* Find the matching entry and return it. */
+ return proc_get_LDT_entry (pi, key);
+}
+
+#endif
/* =============== END, non-thread part of /proc "MODULE" =============== */
case PR_SYSENTRY:
if (syscall_is_lwp_exit (pi, what))
{
- printf_filtered (_("[%s exited]\n"),
- target_pid_to_str (retval));
+ if (print_thread_events)
+ printf_unfiltered (_("[%s exited]\n"),
+ target_pid_to_str (retval));
delete_thread (retval);
status->kind = TARGET_WAITKIND_SPURIOUS;
return retval;
temp_ptid = MERGEPID (pi->pid, temp_tid);
/* If not in GDB's thread list, add it. */
if (!in_thread_list (temp_ptid))
- {
- printf_filtered (_("[New %s]\n"),
- target_pid_to_str (temp_ptid));
- add_thread (temp_ptid);
- }
+ add_thread (temp_ptid);
+
/* Return to WFI, but tell it to immediately resume. */
status->kind = TARGET_WAITKIND_SPURIOUS;
return inferior_ptid;
}
else if (syscall_is_lwp_exit (pi, what))
{
- printf_filtered (_("[%s exited]\n"),
- target_pid_to_str (retval));
+ if (print_thread_events)
+ printf_unfiltered (_("[%s exited]\n"),
+ target_pid_to_str (retval));
delete_thread (retval);
status->kind = TARGET_WAITKIND_SPURIOUS;
return retval;
/* If not in GDB's thread list, add it. */
temp_ptid = MERGEPID (pi->pid, temp_tid);
if (!in_thread_list (temp_ptid))
- {
- printf_filtered (_("[New %s]\n"),
- target_pid_to_str (temp_ptid));
- add_thread (temp_ptid);
- }
+ add_thread (temp_ptid);
status->kind = TARGET_WAITKIND_STOPPED;
status->value.sig = 0;
* If we don't create a procinfo, resume may be unhappy
* later.
*/
- printf_filtered (_("[New %s]\n"), target_pid_to_str (retval));
add_thread (retval);
if (find_procinfo (PIDGET (retval), TIDGET (retval)) == NULL)
create_procinfo (PIDGET (retval), TIDGET (retval));
case TARGET_OBJECT_MEMORY:
if (readbuf)
return (*ops->deprecated_xfer_memory) (offset, readbuf, len,
- 0/*write*/, NULL, ops);
+ 0/*read*/, NULL, ops);
if (writebuf)
return (*ops->deprecated_xfer_memory) (offset, writebuf, len,
1/*write*/, NULL, ops);
*/
static void
-procfs_stop (void)
+procfs_stop (ptid_t ptid)
{
kill (-inferior_process_group, SIGINT);
}
return 0;
}
-#ifdef TM_I386SOL2_H
-/*
- * Function: procfs_find_LDT_entry
- *
- * Input:
- * ptid_t ptid; // The GDB-style pid-plus-LWP.
- *
- * Return:
- * pointer to the corresponding LDT entry.
- */
-
-struct ssd *
-procfs_find_LDT_entry (ptid_t ptid)
-{
- gdb_gregset_t *gregs;
- int key;
- procinfo *pi;
-
- /* Find procinfo for the lwp. */
- if ((pi = find_procinfo (PIDGET (ptid), TIDGET (ptid))) == NULL)
- {
- warning (_("procfs_find_LDT_entry: could not find procinfo for %d:%d."),
- PIDGET (ptid), TIDGET (ptid));
- return NULL;
- }
- /* get its general registers. */
- if ((gregs = proc_get_gregs (pi)) == NULL)
- {
- warning (_("procfs_find_LDT_entry: could not read gregs for %d:%d."),
- PIDGET (ptid), TIDGET (ptid));
- return NULL;
- }
- /* Now extract the GS register's lower 16 bits. */
- key = (*gregs)[GS] & 0xffff;
-
- /* Find the matching entry and return it. */
- return proc_get_LDT_entry (pi, key);
-}
-#endif /* TM_I386SOL2_H */
-
/*
* Memory Mappings Functions:
*/