GDB (API)
/home/stan/gdb/src/gdb/bsd-uthread.c
Go to the documentation of this file.
00001 /* BSD user-level threads support.
00002 
00003    Copyright (C) 2005-2013 Free Software Foundation, Inc.
00004 
00005    This file is part of GDB.
00006 
00007    This program is free software; you can redistribute it and/or modify
00008    it under the terms of the GNU General Public License as published by
00009    the Free Software Foundation; either version 3 of the License, or
00010    (at your option) any later version.
00011 
00012    This program is distributed in the hope that it will be useful,
00013    but WITHOUT ANY WARRANTY; without even the implied warranty of
00014    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015    GNU General Public License for more details.
00016 
00017    You should have received a copy of the GNU General Public License
00018    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
00019 
00020 #include "defs.h"
00021 #include "gdbcore.h"
00022 #include "gdbthread.h"
00023 #include "inferior.h"
00024 #include "objfiles.h"
00025 #include "observer.h"
00026 #include "regcache.h"
00027 #include "solib.h"
00028 #include "solist.h"
00029 #include "symfile.h"
00030 #include "target.h"
00031 
00032 #include "gdb_assert.h"
00033 #include "gdb_obstack.h"
00034 
00035 #include "bsd-uthread.h"
00036 
00037 /* HACK: Save the bsd_uthreads ops returned by bsd_uthread_target.  */
00038 static struct target_ops *bsd_uthread_ops_hack;
00039 
00040 
00041 /* Architecture-specific operations.  */
00042 
00043 /* Per-architecture data key.  */
00044 static struct gdbarch_data *bsd_uthread_data;
00045 
00046 struct bsd_uthread_ops
00047 {
00048   /* Supply registers for an inactive thread to a register cache.  */
00049   void (*supply_uthread)(struct regcache *, int, CORE_ADDR);
00050 
00051   /* Collect registers for an inactive thread from a register cache.  */
00052   void (*collect_uthread)(const struct regcache *, int, CORE_ADDR);
00053 };
00054 
00055 static void *
00056 bsd_uthread_init (struct obstack *obstack)
00057 {
00058   struct bsd_uthread_ops *ops;
00059 
00060   ops = OBSTACK_ZALLOC (obstack, struct bsd_uthread_ops);
00061   return ops;
00062 }
00063 
00064 /* Set the function that supplies registers from an inactive thread
00065    for architecture GDBARCH to SUPPLY_UTHREAD.  */
00066 
00067 void
00068 bsd_uthread_set_supply_uthread (struct gdbarch *gdbarch,
00069                                 void (*supply_uthread) (struct regcache *,
00070                                                         int, CORE_ADDR))
00071 {
00072   struct bsd_uthread_ops *ops = gdbarch_data (gdbarch, bsd_uthread_data);
00073   ops->supply_uthread = supply_uthread;
00074 }
00075 
00076 /* Set the function that collects registers for an inactive thread for
00077    architecture GDBARCH to SUPPLY_UTHREAD.  */
00078 
00079 void
00080 bsd_uthread_set_collect_uthread (struct gdbarch *gdbarch,
00081                          void (*collect_uthread) (const struct regcache *,
00082                                                   int, CORE_ADDR))
00083 {
00084   struct bsd_uthread_ops *ops = gdbarch_data (gdbarch, bsd_uthread_data);
00085   ops->collect_uthread = collect_uthread;
00086 }
00087 
00088 /* Magic number to help recognize a valid thread structure.  */
00089 #define BSD_UTHREAD_PTHREAD_MAGIC       0xd09ba115
00090 
00091 /* Check whether the thread structure at ADDR is valid.  */
00092 
00093 static void
00094 bsd_uthread_check_magic (CORE_ADDR addr)
00095 {
00096   enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch ());
00097   ULONGEST magic = read_memory_unsigned_integer (addr, 4, byte_order);
00098 
00099   if (magic != BSD_UTHREAD_PTHREAD_MAGIC)
00100     error (_("Bad magic"));
00101 }
00102 
00103 /* Thread states.  */
00104 #define BSD_UTHREAD_PS_RUNNING  0
00105 #define BSD_UTHREAD_PS_DEAD     18
00106 
00107 /* Address of the pointer to the thread structure for the running
00108    thread.  */
00109 static CORE_ADDR bsd_uthread_thread_run_addr;
00110 
00111 /* Address of the list of all threads.  */
00112 static CORE_ADDR bsd_uthread_thread_list_addr;
00113 
00114 /* Offsets of various "interesting" bits in the thread structure.  */
00115 static int bsd_uthread_thread_state_offset = -1;
00116 static int bsd_uthread_thread_next_offset = -1;
00117 static int bsd_uthread_thread_ctx_offset;
00118 
00119 /* Name of shared threads library.  */
00120 static const char *bsd_uthread_solib_name;
00121 
00122 /* Non-zero if the thread startum implemented by this module is active.  */
00123 static int bsd_uthread_active;
00124 
00125 static CORE_ADDR
00126 bsd_uthread_lookup_address (const char *name, struct objfile *objfile)
00127 {
00128   struct minimal_symbol *sym;
00129 
00130   sym = lookup_minimal_symbol (name, NULL, objfile);
00131   if (sym)
00132     return SYMBOL_VALUE_ADDRESS (sym);
00133 
00134   return 0;
00135 }
00136 
00137 static int
00138 bsd_uthread_lookup_offset (const char *name, struct objfile *objfile)
00139 {
00140   enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch ());
00141   CORE_ADDR addr;
00142 
00143   addr = bsd_uthread_lookup_address (name, objfile);
00144   if (addr == 0)
00145     return 0;
00146 
00147   return read_memory_unsigned_integer (addr, 4, byte_order);
00148 }
00149 
00150 static CORE_ADDR
00151 bsd_uthread_read_memory_address (CORE_ADDR addr)
00152 {
00153   struct type *ptr_type = builtin_type (target_gdbarch ())->builtin_data_ptr;
00154   return read_memory_typed_address (addr, ptr_type);
00155 }
00156 
00157 /* If OBJFILE contains the symbols corresponding to one of the
00158    supported user-level threads libraries, activate the thread stratum
00159    implemented by this module.  */
00160 
00161 static int
00162 bsd_uthread_activate (struct objfile *objfile)
00163 {
00164   struct gdbarch *gdbarch = target_gdbarch ();
00165   struct bsd_uthread_ops *ops = gdbarch_data (gdbarch, bsd_uthread_data);
00166 
00167   /* Skip if the thread stratum has already been activated.  */
00168   if (bsd_uthread_active)
00169     return 0;
00170 
00171   /* There's no point in enabling this module if no
00172      architecture-specific operations are provided.  */
00173   if (!ops->supply_uthread)
00174     return 0;
00175 
00176   bsd_uthread_thread_run_addr =
00177     bsd_uthread_lookup_address ("_thread_run", objfile);
00178   if (bsd_uthread_thread_run_addr == 0)
00179     return 0;
00180 
00181   bsd_uthread_thread_list_addr =
00182     bsd_uthread_lookup_address ("_thread_list", objfile);
00183   if (bsd_uthread_thread_list_addr == 0)
00184     return 0;
00185 
00186   bsd_uthread_thread_state_offset =
00187     bsd_uthread_lookup_offset ("_thread_state_offset", objfile);
00188   if (bsd_uthread_thread_state_offset == 0)
00189     return 0;
00190 
00191   bsd_uthread_thread_next_offset =
00192     bsd_uthread_lookup_offset ("_thread_next_offset", objfile);
00193   if (bsd_uthread_thread_next_offset == 0)
00194     return 0;
00195 
00196   bsd_uthread_thread_ctx_offset =
00197     bsd_uthread_lookup_offset ("_thread_ctx_offset", objfile);
00198 
00199   push_target (bsd_uthread_ops_hack);
00200   bsd_uthread_active = 1;
00201   return 1;
00202 }
00203 
00204 /* Cleanup due to deactivation.  */
00205 
00206 static void
00207 bsd_uthread_close (void)
00208 {
00209   bsd_uthread_active = 0;
00210   bsd_uthread_thread_run_addr = 0;
00211   bsd_uthread_thread_list_addr = 0;
00212   bsd_uthread_thread_state_offset = 0;
00213   bsd_uthread_thread_next_offset = 0;
00214   bsd_uthread_thread_ctx_offset = 0;
00215   bsd_uthread_solib_name = NULL;
00216 }
00217 
00218 /* Deactivate the thread stratum implemented by this module.  */
00219 
00220 static void
00221 bsd_uthread_deactivate (void)
00222 {
00223   /* Skip if the thread stratum has already been deactivated.  */
00224   if (!bsd_uthread_active)
00225     return;
00226 
00227   unpush_target (bsd_uthread_ops_hack);
00228 }
00229 
00230 static void
00231 bsd_uthread_inferior_created (struct target_ops *ops, int from_tty)
00232 {
00233   bsd_uthread_activate (NULL);
00234 }
00235 
00236 /* Likely candidates for the threads library.  */
00237 static const char *bsd_uthread_solib_names[] =
00238 {
00239   "/usr/lib/libc_r.so",         /* FreeBSD */
00240   "/usr/lib/libpthread.so",     /* OpenBSD */
00241   NULL
00242 };
00243 
00244 static void
00245 bsd_uthread_solib_loaded (struct so_list *so)
00246 {
00247   const char **names = bsd_uthread_solib_names;
00248 
00249   for (names = bsd_uthread_solib_names; *names; names++)
00250     {
00251       if (strncmp (so->so_original_name, *names, strlen (*names)) == 0)
00252         {
00253           solib_read_symbols (so, 0);
00254 
00255           if (bsd_uthread_activate (so->objfile))
00256             {
00257               bsd_uthread_solib_name = so->so_original_name;
00258               return;
00259             }
00260         }
00261     }
00262 }
00263 
00264 static void
00265 bsd_uthread_solib_unloaded (struct so_list *so)
00266 {
00267   if (!bsd_uthread_solib_name)
00268     return;
00269 
00270   if (strcmp (so->so_original_name, bsd_uthread_solib_name) == 0)
00271     bsd_uthread_deactivate ();
00272 }
00273 
00274 static void
00275 bsd_uthread_mourn_inferior (struct target_ops *ops)
00276 {
00277   struct target_ops *beneath = find_target_beneath (ops);
00278   beneath->to_mourn_inferior (beneath);
00279   bsd_uthread_deactivate ();
00280 }
00281 
00282 static void
00283 bsd_uthread_fetch_registers (struct target_ops *ops,
00284                              struct regcache *regcache, int regnum)
00285 {
00286   struct gdbarch *gdbarch = get_regcache_arch (regcache);
00287   struct bsd_uthread_ops *uthread_ops = gdbarch_data (gdbarch, bsd_uthread_data);
00288   CORE_ADDR addr = ptid_get_tid (inferior_ptid);
00289   struct target_ops *beneath = find_target_beneath (ops);
00290   CORE_ADDR active_addr;
00291 
00292   /* Always fetch the appropriate registers from the layer beneath.  */
00293   beneath->to_fetch_registers (beneath, regcache, regnum);
00294 
00295   /* FIXME: That might have gotten us more than we asked for.  Make
00296      sure we overwrite all relevant registers with values from the
00297      thread structure.  This can go once we fix the underlying target.  */
00298   regnum = -1;
00299 
00300   active_addr = bsd_uthread_read_memory_address (bsd_uthread_thread_run_addr);
00301   if (addr != 0 && addr != active_addr)
00302     {
00303       bsd_uthread_check_magic (addr);
00304       uthread_ops->supply_uthread (regcache, regnum,
00305                                    addr + bsd_uthread_thread_ctx_offset);
00306     }
00307 }
00308 
00309 static void
00310 bsd_uthread_store_registers (struct target_ops *ops,
00311                              struct regcache *regcache, int regnum)
00312 {
00313   struct gdbarch *gdbarch = get_regcache_arch (regcache);
00314   struct bsd_uthread_ops *uthread_ops = gdbarch_data (gdbarch, bsd_uthread_data);
00315   struct target_ops *beneath = find_target_beneath (ops);
00316   CORE_ADDR addr = ptid_get_tid (inferior_ptid);
00317   CORE_ADDR active_addr;
00318 
00319   active_addr = bsd_uthread_read_memory_address (bsd_uthread_thread_run_addr);
00320   if (addr != 0 && addr != active_addr)
00321     {
00322       bsd_uthread_check_magic (addr);
00323       uthread_ops->collect_uthread (regcache, regnum,
00324                                     addr + bsd_uthread_thread_ctx_offset);
00325     }
00326   else
00327     {
00328       /* Updating the thread that is currently running; pass the
00329          request to the layer beneath.  */
00330       beneath->to_store_registers (beneath, regcache, regnum);
00331     }
00332 }
00333 
00334 /* FIXME: This function is only there because otherwise GDB tries to
00335    invoke deprecate_xfer_memory.  */
00336 
00337 static LONGEST
00338 bsd_uthread_xfer_partial (struct target_ops *ops, enum target_object object,
00339                           const char *annex, gdb_byte *readbuf,
00340                           const gdb_byte *writebuf,
00341                           ULONGEST offset, LONGEST len)
00342 {
00343   gdb_assert (ops->beneath->to_xfer_partial);
00344   return ops->beneath->to_xfer_partial (ops->beneath, object, annex, readbuf,
00345                                         writebuf, offset, len);
00346 }
00347 
00348 static ptid_t
00349 bsd_uthread_wait (struct target_ops *ops,
00350                   ptid_t ptid, struct target_waitstatus *status, int options)
00351 {
00352   enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch ());
00353   CORE_ADDR addr;
00354   struct target_ops *beneath = find_target_beneath (ops);
00355 
00356   /* Pass the request to the layer beneath.  */
00357   ptid = beneath->to_wait (beneath, ptid, status, options);
00358 
00359   /* If the process is no longer alive, there's no point in figuring
00360      out the thread ID.  It will fail anyway.  */
00361   if (status->kind == TARGET_WAITKIND_SIGNALLED
00362       || status->kind == TARGET_WAITKIND_EXITED)
00363     return ptid;
00364 
00365   /* Fetch the corresponding thread ID, and augment the returned
00366      process ID with it.  */
00367   addr = bsd_uthread_read_memory_address (bsd_uthread_thread_run_addr);
00368   if (addr != 0)
00369     {
00370       gdb_byte buf[4];
00371 
00372       /* FIXME: For executables linked statically with the threads
00373          library, we end up here before the program has actually been
00374          executed.  In that case ADDR will be garbage since it has
00375          been read from the wrong virtual memory image.  */
00376       if (target_read_memory (addr, buf, 4) == 0)
00377         {
00378           ULONGEST magic = extract_unsigned_integer (buf, 4, byte_order);
00379           if (magic == BSD_UTHREAD_PTHREAD_MAGIC)
00380             ptid = ptid_build (ptid_get_pid (ptid), 0, addr);
00381         }
00382     }
00383 
00384   /* If INFERIOR_PTID doesn't have a tid member yet, and we now have a
00385      ptid with tid set, then ptid is still the initial thread of
00386      the process.  Notify GDB core about it.  */
00387   if (ptid_get_tid (inferior_ptid) == 0
00388       && ptid_get_tid (ptid) != 0 && !in_thread_list (ptid))
00389     thread_change_ptid (inferior_ptid, ptid);
00390 
00391   /* Don't let the core see a ptid without a corresponding thread.  */
00392   if (!in_thread_list (ptid) || is_exited (ptid))
00393     add_thread (ptid);
00394 
00395   return ptid;
00396 }
00397 
00398 static void
00399 bsd_uthread_resume (struct target_ops *ops,
00400                     ptid_t ptid, int step, enum gdb_signal sig)
00401 {
00402   /* Pass the request to the layer beneath.  */
00403   struct target_ops *beneath = find_target_beneath (ops);
00404   beneath->to_resume (beneath, ptid, step, sig);
00405 }
00406 
00407 static int
00408 bsd_uthread_thread_alive (struct target_ops *ops, ptid_t ptid)
00409 {
00410   enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch ());
00411   struct target_ops *beneath = find_target_beneath (ops);
00412   CORE_ADDR addr = ptid_get_tid (inferior_ptid);
00413 
00414   if (addr != 0)
00415     {
00416       int offset = bsd_uthread_thread_state_offset;
00417       ULONGEST state;
00418 
00419       bsd_uthread_check_magic (addr);
00420 
00421       state = read_memory_unsigned_integer (addr + offset, 4, byte_order);
00422       if (state == BSD_UTHREAD_PS_DEAD)
00423         return 0;
00424     }
00425 
00426   return beneath->to_thread_alive (beneath, ptid);
00427 }
00428 
00429 static void
00430 bsd_uthread_find_new_threads (struct target_ops *ops)
00431 {
00432   pid_t pid = ptid_get_pid (inferior_ptid);
00433   int offset = bsd_uthread_thread_next_offset;
00434   CORE_ADDR addr;
00435 
00436   addr = bsd_uthread_read_memory_address (bsd_uthread_thread_list_addr);
00437   while (addr != 0)
00438     {
00439       ptid_t ptid = ptid_build (pid, 0, addr);
00440 
00441       if (!in_thread_list (ptid) || is_exited (ptid))
00442         {
00443           /* If INFERIOR_PTID doesn't have a tid member yet, then ptid
00444              is still the initial thread of the process.  Notify GDB
00445              core about it.  */
00446           if (ptid_get_tid (inferior_ptid) == 0)
00447             thread_change_ptid (inferior_ptid, ptid);
00448           else
00449             add_thread (ptid);
00450         }
00451 
00452       addr = bsd_uthread_read_memory_address (addr + offset);
00453     }
00454 }
00455 
00456 /* Possible states a thread can be in.  */
00457 static char *bsd_uthread_state[] =
00458 {
00459   "RUNNING",
00460   "SIGTHREAD",
00461   "MUTEX_WAIT",
00462   "COND_WAIT",
00463   "FDLR_WAIT",
00464   "FDLW_WAIT",
00465   "FDR_WAIT",
00466   "FDW_WAIT",
00467   "FILE_WAIT",
00468   "POLL_WAIT",
00469   "SELECT_WAIT",
00470   "SLEEP_WAIT",
00471   "WAIT_WAIT",
00472   "SIGSUSPEND",
00473   "SIGWAIT",
00474   "SPINBLOCK",
00475   "JOIN",
00476   "SUSPENDED",
00477   "DEAD",
00478   "DEADLOCK"
00479 };
00480 
00481 /* Return a string describing th state of the thread specified by
00482    INFO.  */
00483 
00484 static char *
00485 bsd_uthread_extra_thread_info (struct thread_info *info)
00486 {
00487   enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch ());
00488   CORE_ADDR addr = ptid_get_tid (info->ptid);
00489 
00490   if (addr != 0)
00491     {
00492       int offset = bsd_uthread_thread_state_offset;
00493       ULONGEST state;
00494 
00495       state = read_memory_unsigned_integer (addr + offset, 4, byte_order);
00496       if (state < ARRAY_SIZE (bsd_uthread_state))
00497         return bsd_uthread_state[state];
00498     }
00499 
00500   return NULL;
00501 }
00502 
00503 static char *
00504 bsd_uthread_pid_to_str (struct target_ops *ops, ptid_t ptid)
00505 {
00506   if (ptid_get_tid (ptid) != 0)
00507     {
00508       static char buf[64];
00509 
00510       xsnprintf (buf, sizeof buf, "process %d, thread 0x%lx",
00511                  ptid_get_pid (ptid), ptid_get_tid (ptid));
00512       return buf;
00513     }
00514 
00515   return normal_pid_to_str (ptid);
00516 }
00517 
00518 static struct target_ops *
00519 bsd_uthread_target (void)
00520 {
00521   struct target_ops *t = XZALLOC (struct target_ops);
00522 
00523   t->to_shortname = "bsd-uthreads";
00524   t->to_longname = "BSD user-level threads";
00525   t->to_doc = "BSD user-level threads";
00526   t->to_close = bsd_uthread_close;
00527   t->to_mourn_inferior = bsd_uthread_mourn_inferior;
00528   t->to_fetch_registers = bsd_uthread_fetch_registers;
00529   t->to_store_registers = bsd_uthread_store_registers;
00530   t->to_xfer_partial = bsd_uthread_xfer_partial;
00531   t->to_wait = bsd_uthread_wait;
00532   t->to_resume = bsd_uthread_resume;
00533   t->to_thread_alive = bsd_uthread_thread_alive;
00534   t->to_find_new_threads = bsd_uthread_find_new_threads;
00535   t->to_extra_thread_info = bsd_uthread_extra_thread_info;
00536   t->to_pid_to_str = bsd_uthread_pid_to_str;
00537   t->to_stratum = thread_stratum;
00538   t->to_magic = OPS_MAGIC;
00539   bsd_uthread_ops_hack = t;
00540 
00541   return t;
00542 }
00543 
00544 /* Provide a prototype to silence -Wmissing-prototypes.  */
00545 extern initialize_file_ftype _initialize_bsd_uthread;
00546 
00547 void
00548 _initialize_bsd_uthread (void)
00549 {
00550   complete_target_initialization (bsd_uthread_target ());
00551 
00552   bsd_uthread_data = gdbarch_data_register_pre_init (bsd_uthread_init);
00553 
00554   observer_attach_inferior_created (bsd_uthread_inferior_created);
00555   observer_attach_solib_loaded (bsd_uthread_solib_loaded);
00556   observer_attach_solib_unloaded (bsd_uthread_solib_unloaded);
00557 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines