td_ta_map_lwp2thr.c 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  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, see
  14. <http://www.gnu.org/licenses/>. */
  15. #include "thread_dbP.h"
  16. #include <stdlib.h>
  17. #include <byteswap.h>
  18. #include <sys/procfs.h>
  19. td_err_e
  20. td_ta_map_lwp2thr (const td_thragent_t *ta_arg,
  21. lwpid_t lwpid, td_thrhandle_t *th)
  22. {
  23. td_thragent_t *const ta = (td_thragent_t *) ta_arg;
  24. ps_err_e err;
  25. td_err_e terr;
  26. prgregset_t regs;
  27. psaddr_t addr;
  28. LOG ("td_ta_map_lwp2thr");
  29. /* Test whether the TA parameter is ok. */
  30. if (! ta_ok (ta))
  31. return TD_BADTA;
  32. if (ta->ta_howto == ta_howto_unknown)
  33. {
  34. /* We need to read in from the inferior the instructions what to do. */
  35. psaddr_t howto;
  36. err = td_lookup (ta->ph, SYM_TH_UNIQUE_CONST_THREAD_AREA, &howto);
  37. if (err == PS_OK)
  38. {
  39. err = ps_pdread (ta->ph, howto,
  40. &ta->ta_howto_data.const_thread_area,
  41. sizeof ta->ta_howto_data.const_thread_area);
  42. if (err != PS_OK)
  43. return TD_ERR;
  44. ta->ta_howto = ta_howto_const_thread_area;
  45. if (ta->ta_howto_data.const_thread_area & 0xff000000U)
  46. ta->ta_howto_data.const_thread_area
  47. = bswap_32 (ta->ta_howto_data.const_thread_area);
  48. }
  49. else
  50. {
  51. switch (sizeof (regs[0]))
  52. {
  53. case 8:
  54. err = td_lookup (ta->ph, SYM_TH_UNIQUE_REGISTER64, &howto);
  55. if (err == PS_OK)
  56. ta->ta_howto = ta_howto_reg;
  57. else if (err == PS_NOSYM)
  58. {
  59. err = td_lookup (ta->ph,
  60. SYM_TH_UNIQUE_REGISTER64_THREAD_AREA,
  61. &howto);
  62. if (err == PS_OK)
  63. ta->ta_howto = ta_howto_reg_thread_area;
  64. }
  65. break;
  66. case 4:
  67. err = td_lookup (ta->ph, SYM_TH_UNIQUE_REGISTER32, &howto);
  68. if (err == PS_OK)
  69. ta->ta_howto = ta_howto_reg;
  70. else if (err == PS_NOSYM)
  71. {
  72. err = td_lookup (ta->ph,
  73. SYM_TH_UNIQUE_REGISTER32_THREAD_AREA,
  74. &howto);
  75. if (err == PS_OK)
  76. ta->ta_howto = ta_howto_reg_thread_area;
  77. }
  78. break;
  79. default:
  80. abort ();
  81. return TD_DBERR;
  82. }
  83. if (err != PS_OK)
  84. return TD_DBERR;
  85. /* For either of these methods we read in the same descriptor. */
  86. err = ps_pdread (ta->ph, howto,
  87. ta->ta_howto_data.reg, DB_SIZEOF_DESC);
  88. if (err != PS_OK)
  89. return TD_ERR;
  90. if (DB_DESC_SIZE (ta->ta_howto_data.reg) == 0)
  91. return TD_DBERR;
  92. if (DB_DESC_SIZE (ta->ta_howto_data.reg) & 0xff000000U)
  93. {
  94. /* Byte-swap these words, though we leave the size word
  95. in native order as the handy way to distinguish. */
  96. DB_DESC_OFFSET (ta->ta_howto_data.reg)
  97. = bswap_32 (DB_DESC_OFFSET (ta->ta_howto_data.reg));
  98. DB_DESC_NELEM (ta->ta_howto_data.reg)
  99. = bswap_32 (DB_DESC_NELEM (ta->ta_howto_data.reg));
  100. }
  101. }
  102. }
  103. switch (ta->ta_howto)
  104. {
  105. case ta_howto_unknown:
  106. return TD_DBERR;
  107. default:
  108. return TD_DBERR;
  109. case ta_howto_reg:
  110. /* On most machines, we are just looking at a register. */
  111. if (ps_lgetregs (ta->ph, lwpid, regs) != PS_OK)
  112. return TD_ERR;
  113. terr = _td_fetch_value_local (ta, ta->ta_howto_data.reg, -1,
  114. 0, regs, &addr);
  115. if (terr != TD_OK)
  116. return terr;
  117. /* In this descriptor the nelem word is overloaded as the bias. */
  118. addr += (int32_t) DB_DESC_NELEM (ta->ta_howto_data.reg);
  119. th->th_unique = addr;
  120. break;
  121. case ta_howto_const_thread_area:
  122. /* Some hosts don't have this call and this case won't be used. */
  123. # pragma weak ps_get_thread_area
  124. if (&ps_get_thread_area == NULL)
  125. return TD_NOCAPAB;
  126. /* A la x86-64, there is a constant magic index for get_thread_area. */
  127. if (ps_get_thread_area (ta->ph, lwpid,
  128. ta->ta_howto_data.const_thread_area,
  129. &th->th_unique) != PS_OK)
  130. return TD_ERR; /* XXX Other error value? */
  131. break;
  132. case ta_howto_reg_thread_area:
  133. if (&ps_get_thread_area == NULL)
  134. return TD_NOCAPAB;
  135. /* A la i386, there is a register with an index for get_thread_area. */
  136. if (ps_lgetregs (ta->ph, lwpid, regs) != PS_OK)
  137. return TD_ERR;
  138. terr = _td_fetch_value_local (ta, ta->ta_howto_data.reg_thread_area, -1,
  139. 0, regs, &addr);
  140. if (terr != TD_OK)
  141. return terr;
  142. /* In this descriptor the nelem word is overloaded as scale factor. */
  143. if (ps_get_thread_area
  144. (ta->ph, lwpid,
  145. ((addr - (psaddr_t) 0)
  146. >> DB_DESC_NELEM (ta->ta_howto_data.reg_thread_area)),
  147. &th->th_unique) != PS_OK)
  148. return TD_ERR; /* XXX Other error value? */
  149. break;
  150. }
  151. /* Found it. Now complete the `td_thrhandle_t' object. */
  152. th->th_ta_p = (td_thragent_t *) ta;
  153. return TD_OK;
  154. }