/* BSD user-level threads support.
- Copyright (C) 2005, 2007 Free Software Foundation, Inc.
+ Copyright (C) 2005, 2007, 2008, 2009 Free Software Foundation, Inc.
This file is part of GDB.
return read_memory_unsigned_integer (addr, 4);
}
+static CORE_ADDR
+bsd_uthread_read_memory_address (CORE_ADDR addr)
+{
+ struct type *ptr_type = builtin_type (target_gdbarch)->builtin_data_ptr;
+ return read_memory_typed_address (addr, ptr_type);
+}
+
/* If OBJFILE contains the symbols corresponding to one of the
supported user-level threads libraries, activate the thread stratum
implemented by this module. */
return 1;
}
-/* Deactivate the thread stratum implemented by this module. */
+/* Cleanup due to deactivation. */
static void
-bsd_uthread_deactivate (void)
+bsd_uthread_close (int quitting)
{
- /* Skip if the thread stratum has already been deactivated. */
- if (!bsd_uthread_active)
- return;
-
bsd_uthread_active = 0;
- unpush_target (bsd_uthread_ops_hack);
-
bsd_uthread_thread_run_addr = 0;
bsd_uthread_thread_list_addr = 0;
bsd_uthread_thread_state_offset = 0;
bsd_uthread_solib_name = NULL;
}
-void
+/* Deactivate the thread stratum implemented by this module. */
+
+static void
+bsd_uthread_deactivate (void)
+{
+ /* Skip if the thread stratum has already been deactivated. */
+ if (!bsd_uthread_active)
+ return;
+
+ unpush_target (bsd_uthread_ops_hack);
+}
+
+static void
bsd_uthread_inferior_created (struct target_ops *ops, int from_tty)
{
bsd_uthread_activate (NULL);
NULL
};
-void
+static void
bsd_uthread_solib_loaded (struct so_list *so)
{
const char **names = bsd_uthread_solib_names;
if (bsd_uthread_activate (so->objfile))
{
- bsd_uthread_solib_name == so->so_original_name;
+ bsd_uthread_solib_name = so->so_original_name;
return;
}
}
}
}
-void
+static void
bsd_uthread_solib_unloaded (struct so_list *so)
{
if (!bsd_uthread_solib_name)
}
static void
-bsd_uthread_mourn_inferior (void)
+bsd_uthread_mourn_inferior (struct target_ops *ops)
{
- find_target_beneath (bsd_uthread_ops_hack)->to_mourn_inferior ();
+ struct target_ops *beneath = find_target_beneath (bsd_uthread_ops_hack);
+ beneath->to_mourn_inferior (beneath);
bsd_uthread_deactivate ();
}
static void
bsd_uthread_fetch_registers (struct regcache *regcache, int regnum)
{
- struct gdbarch *gdbarch = current_gdbarch;
+ struct gdbarch *gdbarch = get_regcache_arch (regcache);
struct bsd_uthread_ops *ops = gdbarch_data (gdbarch, bsd_uthread_data);
CORE_ADDR addr = ptid_get_tid (inferior_ptid);
CORE_ADDR active_addr;
thread structure. This can go once we fix the underlying target. */
regnum = -1;
- active_addr = read_memory_typed_address (bsd_uthread_thread_run_addr,
- builtin_type_void_data_ptr);
+ active_addr = bsd_uthread_read_memory_address (bsd_uthread_thread_run_addr);
if (addr != 0 && addr != active_addr)
{
bsd_uthread_check_magic (addr);
static void
bsd_uthread_store_registers (struct regcache *regcache, int regnum)
{
- struct gdbarch *gdbarch = current_gdbarch;
+ struct gdbarch *gdbarch = get_regcache_arch (regcache);
struct bsd_uthread_ops *ops = gdbarch_data (gdbarch, bsd_uthread_data);
CORE_ADDR addr = ptid_get_tid (inferior_ptid);
CORE_ADDR active_addr;
- active_addr = read_memory_typed_address (bsd_uthread_thread_run_addr,
- builtin_type_void_data_ptr);
+ active_addr = bsd_uthread_read_memory_address (bsd_uthread_thread_run_addr);
if (addr != 0 && addr != active_addr)
{
bsd_uthread_check_magic (addr);
}
static ptid_t
-bsd_uthread_wait (ptid_t ptid, struct target_waitstatus *status)
+bsd_uthread_wait (struct target_ops *ops,
+ ptid_t ptid, struct target_waitstatus *status)
{
CORE_ADDR addr;
+ struct target_ops *beneath = find_target_beneath (bsd_uthread_ops_hack);
/* Pass the request to the layer beneath. */
- ptid = find_target_beneath (bsd_uthread_ops_hack)->to_wait (ptid, status);
+ ptid = beneath->to_wait (beneath, ptid, status);
/* If the process is no longer alive, there's no point in figuring
out the thread ID. It will fail anyway. */
/* Fetch the corresponding thread ID, and augment the returned
process ID with it. */
- addr = read_memory_typed_address (bsd_uthread_thread_run_addr,
- builtin_type_void_data_ptr);
+ addr = bsd_uthread_read_memory_address (bsd_uthread_thread_run_addr);
if (addr != 0)
{
gdb_byte buf[4];
}
}
- /* HACK: Twiddle INFERIOR_PTID such that the initial thread of a
- process isn't recognized as a new thread. */
- if (ptid_get_tid (ptid) != 0 && !in_thread_list (ptid)
- && ptid_get_tid (inferior_ptid) == 0)
- {
- add_thread (ptid);
- inferior_ptid = ptid;
- }
+ /* If INFERIOR_PTID doesn't have a tid member yet, and we now have a
+ ptid with tid set, then ptid is still the initial thread of
+ the process. Notify GDB core about it. */
+ if (ptid_get_tid (inferior_ptid) == 0
+ && ptid_get_tid (ptid) != 0 && !in_thread_list (ptid))
+ thread_change_ptid (inferior_ptid, ptid);
+
+ /* Don't let the core see a ptid without a corresponding thread. */
+ if (!in_thread_list (ptid) || is_exited (ptid))
+ add_thread (ptid);
return ptid;
}
int offset = bsd_uthread_thread_next_offset;
CORE_ADDR addr;
- addr = read_memory_typed_address (bsd_uthread_thread_list_addr,
- builtin_type_void_data_ptr);
+ addr = bsd_uthread_read_memory_address (bsd_uthread_thread_list_addr);
while (addr != 0)
{
ptid_t ptid = ptid_build (pid, 0, addr);
- if (!in_thread_list (ptid))
- add_thread (ptid);
+ if (!in_thread_list (ptid) || is_exited (ptid))
+ {
+ /* If INFERIOR_PTID doesn't have a tid member yet, then ptid
+ is still the initial thread of the process. Notify GDB
+ core about it. */
+ if (ptid_get_tid (inferior_ptid) == 0)
+ thread_change_ptid (inferior_ptid, ptid);
+ else
+ add_thread (ptid);
+ }
- addr = read_memory_typed_address (addr + offset,
- builtin_type_void_data_ptr);
+ addr = bsd_uthread_read_memory_address (addr + offset);
}
}
}
static char *
-bsd_uthread_pid_to_str (ptid_t ptid)
+bsd_uthread_pid_to_str (struct target_ops *ops, ptid_t ptid)
{
if (ptid_get_tid (ptid) != 0)
{
return normal_pid_to_str (ptid);
}
-struct target_ops *
+static struct target_ops *
bsd_uthread_target (void)
{
struct target_ops *t = XZALLOC (struct target_ops);
t->to_shortname = "bsd-uthreads";
t->to_longname = "BSD user-level threads";
t->to_doc = "BSD user-level threads";
+ t->to_close = bsd_uthread_close;
t->to_mourn_inferior = bsd_uthread_mourn_inferior;
t->to_fetch_registers = bsd_uthread_fetch_registers;
t->to_store_registers = bsd_uthread_store_registers;
return t;
}
+/* Provide a prototype to silence -Wmissing-prototypes. */
+extern initialize_file_ftype _initialize_bsd_uthread;
+
void
_initialize_bsd_uthread (void)
{