1*5796c8dcSSimon Schubert /* BSD user-level threads support. 2*5796c8dcSSimon Schubert 3*5796c8dcSSimon Schubert Copyright (C) 2005, 2007, 2008, 2009 Free Software Foundation, Inc. 4*5796c8dcSSimon Schubert 5*5796c8dcSSimon Schubert This file is part of GDB. 6*5796c8dcSSimon Schubert 7*5796c8dcSSimon Schubert This program is free software; you can redistribute it and/or modify 8*5796c8dcSSimon Schubert it under the terms of the GNU General Public License as published by 9*5796c8dcSSimon Schubert the Free Software Foundation; either version 3 of the License, or 10*5796c8dcSSimon Schubert (at your option) any later version. 11*5796c8dcSSimon Schubert 12*5796c8dcSSimon Schubert This program is distributed in the hope that it will be useful, 13*5796c8dcSSimon Schubert but WITHOUT ANY WARRANTY; without even the implied warranty of 14*5796c8dcSSimon Schubert MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15*5796c8dcSSimon Schubert GNU General Public License for more details. 16*5796c8dcSSimon Schubert 17*5796c8dcSSimon Schubert You should have received a copy of the GNU General Public License 18*5796c8dcSSimon Schubert along with this program. If not, see <http://www.gnu.org/licenses/>. */ 19*5796c8dcSSimon Schubert 20*5796c8dcSSimon Schubert #include "defs.h" 21*5796c8dcSSimon Schubert #include "gdbcore.h" 22*5796c8dcSSimon Schubert #include "gdbthread.h" 23*5796c8dcSSimon Schubert #include "inferior.h" 24*5796c8dcSSimon Schubert #include "objfiles.h" 25*5796c8dcSSimon Schubert #include "observer.h" 26*5796c8dcSSimon Schubert #include "regcache.h" 27*5796c8dcSSimon Schubert #include "solib.h" 28*5796c8dcSSimon Schubert #include "solist.h" 29*5796c8dcSSimon Schubert #include "symfile.h" 30*5796c8dcSSimon Schubert #include "target.h" 31*5796c8dcSSimon Schubert 32*5796c8dcSSimon Schubert #include "gdb_assert.h" 33*5796c8dcSSimon Schubert #include "gdb_obstack.h" 34*5796c8dcSSimon Schubert 35*5796c8dcSSimon Schubert #include "bsd-uthread.h" 36*5796c8dcSSimon Schubert 37*5796c8dcSSimon Schubert /* HACK: Save the bsd_uthreads ops returned by bsd_uthread_target. */ 38*5796c8dcSSimon Schubert static struct target_ops *bsd_uthread_ops_hack; 39*5796c8dcSSimon Schubert 40*5796c8dcSSimon Schubert 41*5796c8dcSSimon Schubert /* Architecture-specific operations. */ 42*5796c8dcSSimon Schubert 43*5796c8dcSSimon Schubert /* Per-architecture data key. */ 44*5796c8dcSSimon Schubert static struct gdbarch_data *bsd_uthread_data; 45*5796c8dcSSimon Schubert 46*5796c8dcSSimon Schubert struct bsd_uthread_ops 47*5796c8dcSSimon Schubert { 48*5796c8dcSSimon Schubert /* Supply registers for an inactive thread to a register cache. */ 49*5796c8dcSSimon Schubert void (*supply_uthread)(struct regcache *, int, CORE_ADDR); 50*5796c8dcSSimon Schubert 51*5796c8dcSSimon Schubert /* Collect registers for an inactive thread from a register cache. */ 52*5796c8dcSSimon Schubert void (*collect_uthread)(const struct regcache *, int, CORE_ADDR); 53*5796c8dcSSimon Schubert }; 54*5796c8dcSSimon Schubert 55*5796c8dcSSimon Schubert static void * 56*5796c8dcSSimon Schubert bsd_uthread_init (struct obstack *obstack) 57*5796c8dcSSimon Schubert { 58*5796c8dcSSimon Schubert struct bsd_uthread_ops *ops; 59*5796c8dcSSimon Schubert 60*5796c8dcSSimon Schubert ops = OBSTACK_ZALLOC (obstack, struct bsd_uthread_ops); 61*5796c8dcSSimon Schubert return ops; 62*5796c8dcSSimon Schubert } 63*5796c8dcSSimon Schubert 64*5796c8dcSSimon Schubert /* Set the function that supplies registers from an inactive thread 65*5796c8dcSSimon Schubert for architecture GDBARCH to SUPPLY_UTHREAD. */ 66*5796c8dcSSimon Schubert 67*5796c8dcSSimon Schubert void 68*5796c8dcSSimon Schubert bsd_uthread_set_supply_uthread (struct gdbarch *gdbarch, 69*5796c8dcSSimon Schubert void (*supply_uthread) (struct regcache *, 70*5796c8dcSSimon Schubert int, CORE_ADDR)) 71*5796c8dcSSimon Schubert { 72*5796c8dcSSimon Schubert struct bsd_uthread_ops *ops = gdbarch_data (gdbarch, bsd_uthread_data); 73*5796c8dcSSimon Schubert ops->supply_uthread = supply_uthread; 74*5796c8dcSSimon Schubert } 75*5796c8dcSSimon Schubert 76*5796c8dcSSimon Schubert /* Set the function that collects registers for an inactive thread for 77*5796c8dcSSimon Schubert architecture GDBARCH to SUPPLY_UTHREAD. */ 78*5796c8dcSSimon Schubert 79*5796c8dcSSimon Schubert void 80*5796c8dcSSimon Schubert bsd_uthread_set_collect_uthread (struct gdbarch *gdbarch, 81*5796c8dcSSimon Schubert void (*collect_uthread) (const struct regcache *, 82*5796c8dcSSimon Schubert int, CORE_ADDR)) 83*5796c8dcSSimon Schubert { 84*5796c8dcSSimon Schubert struct bsd_uthread_ops *ops = gdbarch_data (gdbarch, bsd_uthread_data); 85*5796c8dcSSimon Schubert ops->collect_uthread = collect_uthread; 86*5796c8dcSSimon Schubert } 87*5796c8dcSSimon Schubert 88*5796c8dcSSimon Schubert /* Magic number to help recognize a valid thread structure. */ 89*5796c8dcSSimon Schubert #define BSD_UTHREAD_PTHREAD_MAGIC 0xd09ba115 90*5796c8dcSSimon Schubert 91*5796c8dcSSimon Schubert /* Check whether the thread structure at ADDR is valid. */ 92*5796c8dcSSimon Schubert 93*5796c8dcSSimon Schubert static void 94*5796c8dcSSimon Schubert bsd_uthread_check_magic (CORE_ADDR addr) 95*5796c8dcSSimon Schubert { 96*5796c8dcSSimon Schubert enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch); 97*5796c8dcSSimon Schubert ULONGEST magic = read_memory_unsigned_integer (addr, 4, byte_order); 98*5796c8dcSSimon Schubert 99*5796c8dcSSimon Schubert if (magic != BSD_UTHREAD_PTHREAD_MAGIC) 100*5796c8dcSSimon Schubert error (_("Bad magic")); 101*5796c8dcSSimon Schubert } 102*5796c8dcSSimon Schubert 103*5796c8dcSSimon Schubert /* Thread states. */ 104*5796c8dcSSimon Schubert #define BSD_UTHREAD_PS_RUNNING 0 105*5796c8dcSSimon Schubert #define BSD_UTHREAD_PS_DEAD 18 106*5796c8dcSSimon Schubert 107*5796c8dcSSimon Schubert /* Address of the pointer to the the thread structure for the running 108*5796c8dcSSimon Schubert thread. */ 109*5796c8dcSSimon Schubert static CORE_ADDR bsd_uthread_thread_run_addr; 110*5796c8dcSSimon Schubert 111*5796c8dcSSimon Schubert /* Address of the list of all threads. */ 112*5796c8dcSSimon Schubert static CORE_ADDR bsd_uthread_thread_list_addr; 113*5796c8dcSSimon Schubert 114*5796c8dcSSimon Schubert /* Offsets of various "interesting" bits in the thread structure. */ 115*5796c8dcSSimon Schubert static int bsd_uthread_thread_state_offset = -1; 116*5796c8dcSSimon Schubert static int bsd_uthread_thread_next_offset = -1; 117*5796c8dcSSimon Schubert static int bsd_uthread_thread_ctx_offset; 118*5796c8dcSSimon Schubert 119*5796c8dcSSimon Schubert /* Name of shared threads library. */ 120*5796c8dcSSimon Schubert static const char *bsd_uthread_solib_name; 121*5796c8dcSSimon Schubert 122*5796c8dcSSimon Schubert /* Non-zero if the thread startum implemented by this module is active. */ 123*5796c8dcSSimon Schubert static int bsd_uthread_active; 124*5796c8dcSSimon Schubert 125*5796c8dcSSimon Schubert static CORE_ADDR 126*5796c8dcSSimon Schubert bsd_uthread_lookup_address (const char *name, struct objfile *objfile) 127*5796c8dcSSimon Schubert { 128*5796c8dcSSimon Schubert struct minimal_symbol *sym; 129*5796c8dcSSimon Schubert 130*5796c8dcSSimon Schubert sym = lookup_minimal_symbol (name, NULL, objfile); 131*5796c8dcSSimon Schubert if (sym) 132*5796c8dcSSimon Schubert return SYMBOL_VALUE_ADDRESS (sym); 133*5796c8dcSSimon Schubert 134*5796c8dcSSimon Schubert return 0; 135*5796c8dcSSimon Schubert } 136*5796c8dcSSimon Schubert 137*5796c8dcSSimon Schubert static int 138*5796c8dcSSimon Schubert bsd_uthread_lookup_offset (const char *name, struct objfile *objfile) 139*5796c8dcSSimon Schubert { 140*5796c8dcSSimon Schubert enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch); 141*5796c8dcSSimon Schubert CORE_ADDR addr; 142*5796c8dcSSimon Schubert 143*5796c8dcSSimon Schubert addr = bsd_uthread_lookup_address (name, objfile); 144*5796c8dcSSimon Schubert if (addr == 0) 145*5796c8dcSSimon Schubert return 0; 146*5796c8dcSSimon Schubert 147*5796c8dcSSimon Schubert return read_memory_unsigned_integer (addr, 4, byte_order); 148*5796c8dcSSimon Schubert } 149*5796c8dcSSimon Schubert 150*5796c8dcSSimon Schubert static CORE_ADDR 151*5796c8dcSSimon Schubert bsd_uthread_read_memory_address (CORE_ADDR addr) 152*5796c8dcSSimon Schubert { 153*5796c8dcSSimon Schubert struct type *ptr_type = builtin_type (target_gdbarch)->builtin_data_ptr; 154*5796c8dcSSimon Schubert return read_memory_typed_address (addr, ptr_type); 155*5796c8dcSSimon Schubert } 156*5796c8dcSSimon Schubert 157*5796c8dcSSimon Schubert /* If OBJFILE contains the symbols corresponding to one of the 158*5796c8dcSSimon Schubert supported user-level threads libraries, activate the thread stratum 159*5796c8dcSSimon Schubert implemented by this module. */ 160*5796c8dcSSimon Schubert 161*5796c8dcSSimon Schubert static int 162*5796c8dcSSimon Schubert bsd_uthread_activate (struct objfile *objfile) 163*5796c8dcSSimon Schubert { 164*5796c8dcSSimon Schubert struct gdbarch *gdbarch = target_gdbarch; 165*5796c8dcSSimon Schubert struct bsd_uthread_ops *ops = gdbarch_data (gdbarch, bsd_uthread_data); 166*5796c8dcSSimon Schubert 167*5796c8dcSSimon Schubert /* Skip if the thread stratum has already been activated. */ 168*5796c8dcSSimon Schubert if (bsd_uthread_active) 169*5796c8dcSSimon Schubert return 0; 170*5796c8dcSSimon Schubert 171*5796c8dcSSimon Schubert /* There's no point in enabling this module if no 172*5796c8dcSSimon Schubert architecture-specific operations are provided. */ 173*5796c8dcSSimon Schubert if (!ops->supply_uthread) 174*5796c8dcSSimon Schubert return 0; 175*5796c8dcSSimon Schubert 176*5796c8dcSSimon Schubert bsd_uthread_thread_run_addr = 177*5796c8dcSSimon Schubert bsd_uthread_lookup_address ("_thread_run", objfile); 178*5796c8dcSSimon Schubert if (bsd_uthread_thread_run_addr == 0) 179*5796c8dcSSimon Schubert return 0; 180*5796c8dcSSimon Schubert 181*5796c8dcSSimon Schubert bsd_uthread_thread_list_addr = 182*5796c8dcSSimon Schubert bsd_uthread_lookup_address ("_thread_list", objfile); 183*5796c8dcSSimon Schubert if (bsd_uthread_thread_list_addr == 0) 184*5796c8dcSSimon Schubert return 0; 185*5796c8dcSSimon Schubert 186*5796c8dcSSimon Schubert bsd_uthread_thread_state_offset = 187*5796c8dcSSimon Schubert bsd_uthread_lookup_offset ("_thread_state_offset", objfile); 188*5796c8dcSSimon Schubert if (bsd_uthread_thread_state_offset == 0) 189*5796c8dcSSimon Schubert return 0; 190*5796c8dcSSimon Schubert 191*5796c8dcSSimon Schubert bsd_uthread_thread_next_offset = 192*5796c8dcSSimon Schubert bsd_uthread_lookup_offset ("_thread_next_offset", objfile); 193*5796c8dcSSimon Schubert if (bsd_uthread_thread_next_offset == 0) 194*5796c8dcSSimon Schubert return 0; 195*5796c8dcSSimon Schubert 196*5796c8dcSSimon Schubert bsd_uthread_thread_ctx_offset = 197*5796c8dcSSimon Schubert bsd_uthread_lookup_offset ("_thread_ctx_offset", objfile); 198*5796c8dcSSimon Schubert 199*5796c8dcSSimon Schubert push_target (bsd_uthread_ops_hack); 200*5796c8dcSSimon Schubert bsd_uthread_active = 1; 201*5796c8dcSSimon Schubert return 1; 202*5796c8dcSSimon Schubert } 203*5796c8dcSSimon Schubert 204*5796c8dcSSimon Schubert /* Cleanup due to deactivation. */ 205*5796c8dcSSimon Schubert 206*5796c8dcSSimon Schubert static void 207*5796c8dcSSimon Schubert bsd_uthread_close (int quitting) 208*5796c8dcSSimon Schubert { 209*5796c8dcSSimon Schubert bsd_uthread_active = 0; 210*5796c8dcSSimon Schubert bsd_uthread_thread_run_addr = 0; 211*5796c8dcSSimon Schubert bsd_uthread_thread_list_addr = 0; 212*5796c8dcSSimon Schubert bsd_uthread_thread_state_offset = 0; 213*5796c8dcSSimon Schubert bsd_uthread_thread_next_offset = 0; 214*5796c8dcSSimon Schubert bsd_uthread_thread_ctx_offset = 0; 215*5796c8dcSSimon Schubert bsd_uthread_solib_name = NULL; 216*5796c8dcSSimon Schubert } 217*5796c8dcSSimon Schubert 218*5796c8dcSSimon Schubert /* Deactivate the thread stratum implemented by this module. */ 219*5796c8dcSSimon Schubert 220*5796c8dcSSimon Schubert static void 221*5796c8dcSSimon Schubert bsd_uthread_deactivate (void) 222*5796c8dcSSimon Schubert { 223*5796c8dcSSimon Schubert /* Skip if the thread stratum has already been deactivated. */ 224*5796c8dcSSimon Schubert if (!bsd_uthread_active) 225*5796c8dcSSimon Schubert return; 226*5796c8dcSSimon Schubert 227*5796c8dcSSimon Schubert unpush_target (bsd_uthread_ops_hack); 228*5796c8dcSSimon Schubert } 229*5796c8dcSSimon Schubert 230*5796c8dcSSimon Schubert static void 231*5796c8dcSSimon Schubert bsd_uthread_inferior_created (struct target_ops *ops, int from_tty) 232*5796c8dcSSimon Schubert { 233*5796c8dcSSimon Schubert bsd_uthread_activate (NULL); 234*5796c8dcSSimon Schubert } 235*5796c8dcSSimon Schubert 236*5796c8dcSSimon Schubert /* Likely candidates for the threads library. */ 237*5796c8dcSSimon Schubert static const char *bsd_uthread_solib_names[] = 238*5796c8dcSSimon Schubert { 239*5796c8dcSSimon Schubert "/usr/lib/libc_r.so", /* FreeBSD */ 240*5796c8dcSSimon Schubert "/usr/lib/libpthread.so", /* OpenBSD */ 241*5796c8dcSSimon Schubert NULL 242*5796c8dcSSimon Schubert }; 243*5796c8dcSSimon Schubert 244*5796c8dcSSimon Schubert static void 245*5796c8dcSSimon Schubert bsd_uthread_solib_loaded (struct so_list *so) 246*5796c8dcSSimon Schubert { 247*5796c8dcSSimon Schubert const char **names = bsd_uthread_solib_names; 248*5796c8dcSSimon Schubert 249*5796c8dcSSimon Schubert for (names = bsd_uthread_solib_names; *names; names++) 250*5796c8dcSSimon Schubert { 251*5796c8dcSSimon Schubert if (strncmp (so->so_original_name, *names, strlen (*names)) == 0) 252*5796c8dcSSimon Schubert { 253*5796c8dcSSimon Schubert solib_read_symbols (so, so->from_tty ? SYMFILE_VERBOSE : 0); 254*5796c8dcSSimon Schubert 255*5796c8dcSSimon Schubert if (bsd_uthread_activate (so->objfile)) 256*5796c8dcSSimon Schubert { 257*5796c8dcSSimon Schubert bsd_uthread_solib_name = so->so_original_name; 258*5796c8dcSSimon Schubert return; 259*5796c8dcSSimon Schubert } 260*5796c8dcSSimon Schubert } 261*5796c8dcSSimon Schubert } 262*5796c8dcSSimon Schubert } 263*5796c8dcSSimon Schubert 264*5796c8dcSSimon Schubert static void 265*5796c8dcSSimon Schubert bsd_uthread_solib_unloaded (struct so_list *so) 266*5796c8dcSSimon Schubert { 267*5796c8dcSSimon Schubert if (!bsd_uthread_solib_name) 268*5796c8dcSSimon Schubert return; 269*5796c8dcSSimon Schubert 270*5796c8dcSSimon Schubert if (strcmp (so->so_original_name, bsd_uthread_solib_name) == 0) 271*5796c8dcSSimon Schubert bsd_uthread_deactivate (); 272*5796c8dcSSimon Schubert } 273*5796c8dcSSimon Schubert 274*5796c8dcSSimon Schubert static void 275*5796c8dcSSimon Schubert bsd_uthread_mourn_inferior (struct target_ops *ops) 276*5796c8dcSSimon Schubert { 277*5796c8dcSSimon Schubert struct target_ops *beneath = find_target_beneath (ops); 278*5796c8dcSSimon Schubert beneath->to_mourn_inferior (beneath); 279*5796c8dcSSimon Schubert bsd_uthread_deactivate (); 280*5796c8dcSSimon Schubert } 281*5796c8dcSSimon Schubert 282*5796c8dcSSimon Schubert static void 283*5796c8dcSSimon Schubert bsd_uthread_fetch_registers (struct target_ops *ops, 284*5796c8dcSSimon Schubert struct regcache *regcache, int regnum) 285*5796c8dcSSimon Schubert { 286*5796c8dcSSimon Schubert struct gdbarch *gdbarch = get_regcache_arch (regcache); 287*5796c8dcSSimon Schubert struct bsd_uthread_ops *uthread_ops = gdbarch_data (gdbarch, bsd_uthread_data); 288*5796c8dcSSimon Schubert CORE_ADDR addr = ptid_get_tid (inferior_ptid); 289*5796c8dcSSimon Schubert struct target_ops *beneath = find_target_beneath (ops); 290*5796c8dcSSimon Schubert CORE_ADDR active_addr; 291*5796c8dcSSimon Schubert 292*5796c8dcSSimon Schubert /* Always fetch the appropriate registers from the layer beneath. */ 293*5796c8dcSSimon Schubert beneath->to_fetch_registers (beneath, regcache, regnum); 294*5796c8dcSSimon Schubert 295*5796c8dcSSimon Schubert /* FIXME: That might have gotten us more than we asked for. Make 296*5796c8dcSSimon Schubert sure we overwrite all relevant registers with values from the 297*5796c8dcSSimon Schubert thread structure. This can go once we fix the underlying target. */ 298*5796c8dcSSimon Schubert regnum = -1; 299*5796c8dcSSimon Schubert 300*5796c8dcSSimon Schubert active_addr = bsd_uthread_read_memory_address (bsd_uthread_thread_run_addr); 301*5796c8dcSSimon Schubert if (addr != 0 && addr != active_addr) 302*5796c8dcSSimon Schubert { 303*5796c8dcSSimon Schubert bsd_uthread_check_magic (addr); 304*5796c8dcSSimon Schubert uthread_ops->supply_uthread (regcache, regnum, 305*5796c8dcSSimon Schubert addr + bsd_uthread_thread_ctx_offset); 306*5796c8dcSSimon Schubert } 307*5796c8dcSSimon Schubert } 308*5796c8dcSSimon Schubert 309*5796c8dcSSimon Schubert static void 310*5796c8dcSSimon Schubert bsd_uthread_store_registers (struct target_ops *ops, 311*5796c8dcSSimon Schubert struct regcache *regcache, int regnum) 312*5796c8dcSSimon Schubert { 313*5796c8dcSSimon Schubert struct gdbarch *gdbarch = get_regcache_arch (regcache); 314*5796c8dcSSimon Schubert struct bsd_uthread_ops *uthread_ops = gdbarch_data (gdbarch, bsd_uthread_data); 315*5796c8dcSSimon Schubert struct target_ops *beneath = find_target_beneath (ops); 316*5796c8dcSSimon Schubert CORE_ADDR addr = ptid_get_tid (inferior_ptid); 317*5796c8dcSSimon Schubert CORE_ADDR active_addr; 318*5796c8dcSSimon Schubert 319*5796c8dcSSimon Schubert active_addr = bsd_uthread_read_memory_address (bsd_uthread_thread_run_addr); 320*5796c8dcSSimon Schubert if (addr != 0 && addr != active_addr) 321*5796c8dcSSimon Schubert { 322*5796c8dcSSimon Schubert bsd_uthread_check_magic (addr); 323*5796c8dcSSimon Schubert uthread_ops->collect_uthread (regcache, regnum, 324*5796c8dcSSimon Schubert addr + bsd_uthread_thread_ctx_offset); 325*5796c8dcSSimon Schubert } 326*5796c8dcSSimon Schubert else 327*5796c8dcSSimon Schubert { 328*5796c8dcSSimon Schubert /* Updating the thread that is currently running; pass the 329*5796c8dcSSimon Schubert request to the layer beneath. */ 330*5796c8dcSSimon Schubert beneath->to_store_registers (beneath, regcache, regnum); 331*5796c8dcSSimon Schubert } 332*5796c8dcSSimon Schubert } 333*5796c8dcSSimon Schubert 334*5796c8dcSSimon Schubert /* FIXME: This function is only there because otherwise GDB tries to 335*5796c8dcSSimon Schubert invoke deprecate_xfer_memory. */ 336*5796c8dcSSimon Schubert 337*5796c8dcSSimon Schubert static LONGEST 338*5796c8dcSSimon Schubert bsd_uthread_xfer_partial (struct target_ops *ops, enum target_object object, 339*5796c8dcSSimon Schubert const char *annex, gdb_byte *readbuf, 340*5796c8dcSSimon Schubert const gdb_byte *writebuf, 341*5796c8dcSSimon Schubert ULONGEST offset, LONGEST len) 342*5796c8dcSSimon Schubert { 343*5796c8dcSSimon Schubert gdb_assert (ops->beneath->to_xfer_partial); 344*5796c8dcSSimon Schubert return ops->beneath->to_xfer_partial (ops->beneath, object, annex, readbuf, 345*5796c8dcSSimon Schubert writebuf, offset, len); 346*5796c8dcSSimon Schubert } 347*5796c8dcSSimon Schubert 348*5796c8dcSSimon Schubert static ptid_t 349*5796c8dcSSimon Schubert bsd_uthread_wait (struct target_ops *ops, 350*5796c8dcSSimon Schubert ptid_t ptid, struct target_waitstatus *status, int options) 351*5796c8dcSSimon Schubert { 352*5796c8dcSSimon Schubert enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch); 353*5796c8dcSSimon Schubert CORE_ADDR addr; 354*5796c8dcSSimon Schubert struct target_ops *beneath = find_target_beneath (ops); 355*5796c8dcSSimon Schubert 356*5796c8dcSSimon Schubert /* Pass the request to the layer beneath. */ 357*5796c8dcSSimon Schubert ptid = beneath->to_wait (beneath, ptid, status, options); 358*5796c8dcSSimon Schubert 359*5796c8dcSSimon Schubert /* If the process is no longer alive, there's no point in figuring 360*5796c8dcSSimon Schubert out the thread ID. It will fail anyway. */ 361*5796c8dcSSimon Schubert if (status->kind == TARGET_WAITKIND_SIGNALLED 362*5796c8dcSSimon Schubert || status->kind == TARGET_WAITKIND_EXITED) 363*5796c8dcSSimon Schubert return ptid; 364*5796c8dcSSimon Schubert 365*5796c8dcSSimon Schubert /* Fetch the corresponding thread ID, and augment the returned 366*5796c8dcSSimon Schubert process ID with it. */ 367*5796c8dcSSimon Schubert addr = bsd_uthread_read_memory_address (bsd_uthread_thread_run_addr); 368*5796c8dcSSimon Schubert if (addr != 0) 369*5796c8dcSSimon Schubert { 370*5796c8dcSSimon Schubert gdb_byte buf[4]; 371*5796c8dcSSimon Schubert 372*5796c8dcSSimon Schubert /* FIXME: For executables linked statically with the threads 373*5796c8dcSSimon Schubert library, we end up here before the program has actually been 374*5796c8dcSSimon Schubert executed. In that case ADDR will be garbage since it has 375*5796c8dcSSimon Schubert been read from the wrong virtual memory image. */ 376*5796c8dcSSimon Schubert if (target_read_memory (addr, buf, 4) == 0) 377*5796c8dcSSimon Schubert { 378*5796c8dcSSimon Schubert ULONGEST magic = extract_unsigned_integer (buf, 4, byte_order); 379*5796c8dcSSimon Schubert if (magic == BSD_UTHREAD_PTHREAD_MAGIC) 380*5796c8dcSSimon Schubert ptid = ptid_build (ptid_get_pid (ptid), 0, addr); 381*5796c8dcSSimon Schubert } 382*5796c8dcSSimon Schubert } 383*5796c8dcSSimon Schubert 384*5796c8dcSSimon Schubert /* If INFERIOR_PTID doesn't have a tid member yet, and we now have a 385*5796c8dcSSimon Schubert ptid with tid set, then ptid is still the initial thread of 386*5796c8dcSSimon Schubert the process. Notify GDB core about it. */ 387*5796c8dcSSimon Schubert if (ptid_get_tid (inferior_ptid) == 0 388*5796c8dcSSimon Schubert && ptid_get_tid (ptid) != 0 && !in_thread_list (ptid)) 389*5796c8dcSSimon Schubert thread_change_ptid (inferior_ptid, ptid); 390*5796c8dcSSimon Schubert 391*5796c8dcSSimon Schubert /* Don't let the core see a ptid without a corresponding thread. */ 392*5796c8dcSSimon Schubert if (!in_thread_list (ptid) || is_exited (ptid)) 393*5796c8dcSSimon Schubert add_thread (ptid); 394*5796c8dcSSimon Schubert 395*5796c8dcSSimon Schubert return ptid; 396*5796c8dcSSimon Schubert } 397*5796c8dcSSimon Schubert 398*5796c8dcSSimon Schubert static void 399*5796c8dcSSimon Schubert bsd_uthread_resume (struct target_ops *ops, 400*5796c8dcSSimon Schubert ptid_t ptid, int step, enum target_signal sig) 401*5796c8dcSSimon Schubert { 402*5796c8dcSSimon Schubert /* Pass the request to the layer beneath. */ 403*5796c8dcSSimon Schubert struct target_ops *beneath = find_target_beneath (ops); 404*5796c8dcSSimon Schubert beneath->to_resume (beneath, ptid, step, sig); 405*5796c8dcSSimon Schubert } 406*5796c8dcSSimon Schubert 407*5796c8dcSSimon Schubert static int 408*5796c8dcSSimon Schubert bsd_uthread_thread_alive (struct target_ops *ops, ptid_t ptid) 409*5796c8dcSSimon Schubert { 410*5796c8dcSSimon Schubert enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch); 411*5796c8dcSSimon Schubert struct target_ops *beneath = find_target_beneath (ops); 412*5796c8dcSSimon Schubert CORE_ADDR addr = ptid_get_tid (inferior_ptid); 413*5796c8dcSSimon Schubert 414*5796c8dcSSimon Schubert if (addr != 0) 415*5796c8dcSSimon Schubert { 416*5796c8dcSSimon Schubert int offset = bsd_uthread_thread_state_offset; 417*5796c8dcSSimon Schubert ULONGEST state; 418*5796c8dcSSimon Schubert 419*5796c8dcSSimon Schubert bsd_uthread_check_magic (addr); 420*5796c8dcSSimon Schubert 421*5796c8dcSSimon Schubert state = read_memory_unsigned_integer (addr + offset, 4, byte_order); 422*5796c8dcSSimon Schubert if (state == BSD_UTHREAD_PS_DEAD) 423*5796c8dcSSimon Schubert return 0; 424*5796c8dcSSimon Schubert } 425*5796c8dcSSimon Schubert 426*5796c8dcSSimon Schubert return beneath->to_thread_alive (beneath, ptid); 427*5796c8dcSSimon Schubert } 428*5796c8dcSSimon Schubert 429*5796c8dcSSimon Schubert static void 430*5796c8dcSSimon Schubert bsd_uthread_find_new_threads (struct target_ops *ops) 431*5796c8dcSSimon Schubert { 432*5796c8dcSSimon Schubert pid_t pid = ptid_get_pid (inferior_ptid); 433*5796c8dcSSimon Schubert int offset = bsd_uthread_thread_next_offset; 434*5796c8dcSSimon Schubert CORE_ADDR addr; 435*5796c8dcSSimon Schubert 436*5796c8dcSSimon Schubert addr = bsd_uthread_read_memory_address (bsd_uthread_thread_list_addr); 437*5796c8dcSSimon Schubert while (addr != 0) 438*5796c8dcSSimon Schubert { 439*5796c8dcSSimon Schubert ptid_t ptid = ptid_build (pid, 0, addr); 440*5796c8dcSSimon Schubert 441*5796c8dcSSimon Schubert if (!in_thread_list (ptid) || is_exited (ptid)) 442*5796c8dcSSimon Schubert { 443*5796c8dcSSimon Schubert /* If INFERIOR_PTID doesn't have a tid member yet, then ptid 444*5796c8dcSSimon Schubert is still the initial thread of the process. Notify GDB 445*5796c8dcSSimon Schubert core about it. */ 446*5796c8dcSSimon Schubert if (ptid_get_tid (inferior_ptid) == 0) 447*5796c8dcSSimon Schubert thread_change_ptid (inferior_ptid, ptid); 448*5796c8dcSSimon Schubert else 449*5796c8dcSSimon Schubert add_thread (ptid); 450*5796c8dcSSimon Schubert } 451*5796c8dcSSimon Schubert 452*5796c8dcSSimon Schubert addr = bsd_uthread_read_memory_address (addr + offset); 453*5796c8dcSSimon Schubert } 454*5796c8dcSSimon Schubert } 455*5796c8dcSSimon Schubert 456*5796c8dcSSimon Schubert /* Possible states a thread can be in. */ 457*5796c8dcSSimon Schubert static char *bsd_uthread_state[] = 458*5796c8dcSSimon Schubert { 459*5796c8dcSSimon Schubert "RUNNING", 460*5796c8dcSSimon Schubert "SIGTHREAD", 461*5796c8dcSSimon Schubert "MUTEX_WAIT", 462*5796c8dcSSimon Schubert "COND_WAIT", 463*5796c8dcSSimon Schubert "FDLR_WAIT", 464*5796c8dcSSimon Schubert "FDLW_WAIT", 465*5796c8dcSSimon Schubert "FDR_WAIT", 466*5796c8dcSSimon Schubert "FDW_WAIT", 467*5796c8dcSSimon Schubert "FILE_WAIT", 468*5796c8dcSSimon Schubert "POLL_WAIT", 469*5796c8dcSSimon Schubert "SELECT_WAIT", 470*5796c8dcSSimon Schubert "SLEEP_WAIT", 471*5796c8dcSSimon Schubert "WAIT_WAIT", 472*5796c8dcSSimon Schubert "SIGSUSPEND", 473*5796c8dcSSimon Schubert "SIGWAIT", 474*5796c8dcSSimon Schubert "SPINBLOCK", 475*5796c8dcSSimon Schubert "JOIN", 476*5796c8dcSSimon Schubert "SUSPENDED", 477*5796c8dcSSimon Schubert "DEAD", 478*5796c8dcSSimon Schubert "DEADLOCK" 479*5796c8dcSSimon Schubert }; 480*5796c8dcSSimon Schubert 481*5796c8dcSSimon Schubert /* Return a string describing th state of the thread specified by 482*5796c8dcSSimon Schubert INFO. */ 483*5796c8dcSSimon Schubert 484*5796c8dcSSimon Schubert static char * 485*5796c8dcSSimon Schubert bsd_uthread_extra_thread_info (struct thread_info *info) 486*5796c8dcSSimon Schubert { 487*5796c8dcSSimon Schubert enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch); 488*5796c8dcSSimon Schubert CORE_ADDR addr = ptid_get_tid (info->ptid); 489*5796c8dcSSimon Schubert 490*5796c8dcSSimon Schubert if (addr != 0) 491*5796c8dcSSimon Schubert { 492*5796c8dcSSimon Schubert int offset = bsd_uthread_thread_state_offset; 493*5796c8dcSSimon Schubert ULONGEST state; 494*5796c8dcSSimon Schubert 495*5796c8dcSSimon Schubert state = read_memory_unsigned_integer (addr + offset, 4, byte_order); 496*5796c8dcSSimon Schubert if (state < ARRAY_SIZE (bsd_uthread_state)) 497*5796c8dcSSimon Schubert return bsd_uthread_state[state]; 498*5796c8dcSSimon Schubert } 499*5796c8dcSSimon Schubert 500*5796c8dcSSimon Schubert return NULL; 501*5796c8dcSSimon Schubert } 502*5796c8dcSSimon Schubert 503*5796c8dcSSimon Schubert static char * 504*5796c8dcSSimon Schubert bsd_uthread_pid_to_str (struct target_ops *ops, ptid_t ptid) 505*5796c8dcSSimon Schubert { 506*5796c8dcSSimon Schubert if (ptid_get_tid (ptid) != 0) 507*5796c8dcSSimon Schubert { 508*5796c8dcSSimon Schubert static char buf[64]; 509*5796c8dcSSimon Schubert 510*5796c8dcSSimon Schubert xsnprintf (buf, sizeof buf, "process %d, thread 0x%lx", 511*5796c8dcSSimon Schubert ptid_get_pid (ptid), ptid_get_tid (ptid)); 512*5796c8dcSSimon Schubert return buf; 513*5796c8dcSSimon Schubert } 514*5796c8dcSSimon Schubert 515*5796c8dcSSimon Schubert return normal_pid_to_str (ptid); 516*5796c8dcSSimon Schubert } 517*5796c8dcSSimon Schubert 518*5796c8dcSSimon Schubert static struct target_ops * 519*5796c8dcSSimon Schubert bsd_uthread_target (void) 520*5796c8dcSSimon Schubert { 521*5796c8dcSSimon Schubert struct target_ops *t = XZALLOC (struct target_ops); 522*5796c8dcSSimon Schubert 523*5796c8dcSSimon Schubert t->to_shortname = "bsd-uthreads"; 524*5796c8dcSSimon Schubert t->to_longname = "BSD user-level threads"; 525*5796c8dcSSimon Schubert t->to_doc = "BSD user-level threads"; 526*5796c8dcSSimon Schubert t->to_close = bsd_uthread_close; 527*5796c8dcSSimon Schubert t->to_mourn_inferior = bsd_uthread_mourn_inferior; 528*5796c8dcSSimon Schubert t->to_fetch_registers = bsd_uthread_fetch_registers; 529*5796c8dcSSimon Schubert t->to_store_registers = bsd_uthread_store_registers; 530*5796c8dcSSimon Schubert t->to_xfer_partial = bsd_uthread_xfer_partial; 531*5796c8dcSSimon Schubert t->to_wait = bsd_uthread_wait; 532*5796c8dcSSimon Schubert t->to_resume = bsd_uthread_resume; 533*5796c8dcSSimon Schubert t->to_thread_alive = bsd_uthread_thread_alive; 534*5796c8dcSSimon Schubert t->to_find_new_threads = bsd_uthread_find_new_threads; 535*5796c8dcSSimon Schubert t->to_extra_thread_info = bsd_uthread_extra_thread_info; 536*5796c8dcSSimon Schubert t->to_pid_to_str = bsd_uthread_pid_to_str; 537*5796c8dcSSimon Schubert t->to_stratum = thread_stratum; 538*5796c8dcSSimon Schubert t->to_magic = OPS_MAGIC; 539*5796c8dcSSimon Schubert bsd_uthread_ops_hack = t; 540*5796c8dcSSimon Schubert 541*5796c8dcSSimon Schubert return t; 542*5796c8dcSSimon Schubert } 543*5796c8dcSSimon Schubert 544*5796c8dcSSimon Schubert /* Provide a prototype to silence -Wmissing-prototypes. */ 545*5796c8dcSSimon Schubert extern initialize_file_ftype _initialize_bsd_uthread; 546*5796c8dcSSimon Schubert 547*5796c8dcSSimon Schubert void 548*5796c8dcSSimon Schubert _initialize_bsd_uthread (void) 549*5796c8dcSSimon Schubert { 550*5796c8dcSSimon Schubert add_target (bsd_uthread_target ()); 551*5796c8dcSSimon Schubert 552*5796c8dcSSimon Schubert bsd_uthread_data = gdbarch_data_register_pre_init (bsd_uthread_init); 553*5796c8dcSSimon Schubert 554*5796c8dcSSimon Schubert observer_attach_inferior_created (bsd_uthread_inferior_created); 555*5796c8dcSSimon Schubert observer_attach_solib_loaded (bsd_uthread_solib_loaded); 556*5796c8dcSSimon Schubert observer_attach_solib_unloaded (bsd_uthread_solib_unloaded); 557*5796c8dcSSimon Schubert } 558