td_ta_map_lwp2thr.c 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  1. /* Which thread is running on an LWP?
  2. Copyright (C) 2003, 2004 Free Software Foundation, Inc.
  3. This file is part of the GNU C Library.
  4. The GNU C Library is free software; you can redistribute it and/or
  5. modify it under the terms of the GNU Lesser General Public
  6. License as published by the Free Software Foundation; either
  7. version 2.1 of the License, or (at your option) any later version.
  8. The GNU C Library is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  11. Lesser General Public License for more details.
  12. You should have received a copy of the GNU Lesser General Public
  13. License along with the GNU C Library; if not, write to the Free
  14. Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
  15. 02111-1307 USA. */
  16. #include "thread_dbP.h"
  17. #include <stdlib.h>
  18. #include <byteswap.h>
  19. #include <sys/procfs.h>
  20. td_err_e
  21. td_ta_map_lwp2thr (const td_thragent_t *ta_arg,
  22. lwpid_t lwpid, td_thrhandle_t *th)
  23. {
  24. td_thragent_t *const ta = (td_thragent_t *) ta_arg;
  25. ps_err_e err;
  26. td_err_e terr;
  27. prgregset_t regs;
  28. psaddr_t addr;
  29. LOG ("td_ta_map_lwp2thr");
  30. /* Test whether the TA parameter is ok. */
  31. if (! ta_ok (ta))
  32. return TD_BADTA;
  33. if (ta->ta_howto == ta_howto_unknown)
  34. {
  35. /* We need to read in from the inferior the instructions what to do. */
  36. psaddr_t howto;
  37. err = td_lookup (ta->ph, SYM_TH_UNIQUE_CONST_THREAD_AREA, &howto);
  38. if (err == PS_OK)
  39. {
  40. err = ps_pdread (ta->ph, howto,
  41. &ta->ta_howto_data.const_thread_area,
  42. sizeof ta->ta_howto_data.const_thread_area);
  43. if (err != PS_OK)
  44. return TD_ERR;
  45. ta->ta_howto = ta_howto_const_thread_area;
  46. if (ta->ta_howto_data.const_thread_area & 0xff000000U)
  47. ta->ta_howto_data.const_thread_area
  48. = bswap_32 (ta->ta_howto_data.const_thread_area);
  49. }
  50. else
  51. {
  52. switch (sizeof (regs[0]))
  53. {
  54. case 8:
  55. err = td_lookup (ta->ph, SYM_TH_UNIQUE_REGISTER64, &howto);
  56. if (err == PS_OK)
  57. ta->ta_howto = ta_howto_reg;
  58. else if (err == PS_NOSYM)
  59. {
  60. err = td_lookup (ta->ph,
  61. SYM_TH_UNIQUE_REGISTER64_THREAD_AREA,
  62. &howto);
  63. if (err == PS_OK)
  64. ta->ta_howto = ta_howto_reg_thread_area;
  65. }
  66. break;
  67. case 4:
  68. err = td_lookup (ta->ph, SYM_TH_UNIQUE_REGISTER32, &howto);
  69. if (err == PS_OK)
  70. ta->ta_howto = ta_howto_reg;
  71. else if (err == PS_NOSYM)
  72. {
  73. err = td_lookup (ta->ph,
  74. SYM_TH_UNIQUE_REGISTER32_THREAD_AREA,
  75. &howto);
  76. if (err == PS_OK)
  77. ta->ta_howto = ta_howto_reg_thread_area;
  78. }
  79. break;
  80. default:
  81. abort ();
  82. return TD_DBERR;
  83. }
  84. if (err != PS_OK)
  85. return TD_DBERR;
  86. /* For either of these methods we read in the same descriptor. */
  87. err = ps_pdread (ta->ph, howto,
  88. ta->ta_howto_data.reg, DB_SIZEOF_DESC);
  89. if (err != PS_OK)
  90. return TD_ERR;
  91. if (DB_DESC_SIZE (ta->ta_howto_data.reg) == 0)
  92. return TD_DBERR;
  93. if (DB_DESC_SIZE (ta->ta_howto_data.reg) & 0xff000000U)
  94. {
  95. /* Byte-swap these words, though we leave the size word
  96. in native order as the handy way to distinguish. */
  97. DB_DESC_OFFSET (ta->ta_howto_data.reg)
  98. = bswap_32 (DB_DESC_OFFSET (ta->ta_howto_data.reg));
  99. DB_DESC_NELEM (ta->ta_howto_data.reg)
  100. = bswap_32 (DB_DESC_NELEM (ta->ta_howto_data.reg));
  101. }
  102. }
  103. }
  104. switch (ta->ta_howto)
  105. {
  106. case ta_howto_unknown:
  107. return TD_DBERR;
  108. default:
  109. return TD_DBERR;
  110. case ta_howto_reg:
  111. /* On most machines, we are just looking at a register. */
  112. if (ps_lgetregs (ta->ph, lwpid, regs) != PS_OK)
  113. return TD_ERR;
  114. terr = _td_fetch_value_local (ta, ta->ta_howto_data.reg, -1,
  115. 0, regs, &addr);
  116. if (terr != TD_OK)
  117. return terr;
  118. /* In this descriptor the nelem word is overloaded as the bias. */
  119. addr += (int32_t) DB_DESC_NELEM (ta->ta_howto_data.reg);
  120. th->th_unique = addr;
  121. break;
  122. case ta_howto_const_thread_area:
  123. /* Some hosts don't have this call and this case won't be used. */
  124. # pragma weak ps_get_thread_area
  125. if (&ps_get_thread_area == NULL)
  126. return TD_NOCAPAB;
  127. /* A la x86-64, there is a constant magic index for get_thread_area. */
  128. if (ps_get_thread_area (ta->ph, lwpid,
  129. ta->ta_howto_data.const_thread_area,
  130. &th->th_unique) != PS_OK)
  131. return TD_ERR; /* XXX Other error value? */
  132. break;
  133. case ta_howto_reg_thread_area:
  134. if (&ps_get_thread_area == NULL)
  135. return TD_NOCAPAB;
  136. /* A la i386, there is a register with an index for get_thread_area. */
  137. if (ps_lgetregs (ta->ph, lwpid, regs) != PS_OK)
  138. return TD_ERR;
  139. terr = _td_fetch_value_local (ta, ta->ta_howto_data.reg_thread_area, -1,
  140. 0, regs, &addr);
  141. if (terr != TD_OK)
  142. return terr;
  143. /* In this descriptor the nelem word is overloaded as scale factor. */
  144. if (ps_get_thread_area
  145. (ta->ph, lwpid,
  146. ((addr - (psaddr_t) 0)
  147. >> DB_DESC_NELEM (ta->ta_howto_data.reg_thread_area)),
  148. &th->th_unique) != PS_OK)
  149. return TD_ERR; /* XXX Other error value? */
  150. break;
  151. }
  152. /* Found it. Now complete the `td_thrhandle_t' object. */
  153. th->th_ta_p = (td_thragent_t *) ta;
  154. return TD_OK;
  155. }