1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20: #include "thread_dbP.h"
21: #include <stdlib.h>
22: #include <byteswap.h>
23: #include <sys/procfs.h>
24:
25:
26: td_err_e
27: __td_ta_lookup_th_unique (const td_thragent_t *ta_arg,
28: lwpid_t lwpid, td_thrhandle_t *th)
29: {
30: td_thragent_t *const ta = (td_thragent_t *) ta_arg;
31: ps_err_e err;
32: td_err_e terr;
33: prgregset_t regs;
34: psaddr_t addr;
35:
36: LOG ("td_ta_map_lwp2thr");
37:
38:
39: if (! ta_ok (ta))
40: return TD_BADTA;
41:
42: if (ta->ta_howto == ta_howto_unknown)
43: {
44:
45: psaddr_t howto;
46:
47: err = td_lookup (ta->ph, SYM_TH_UNIQUE_CONST_THREAD_AREA, &howto);
48: if (err == PS_OK)
49: {
50: err = ps_pdread (ta->ph, howto,
51: &ta->ta_howto_data.const_thread_area,
52: sizeof ta->ta_howto_data.const_thread_area);
53: if (err != PS_OK)
54: return TD_ERR;
55: ta->ta_howto = ta_howto_const_thread_area;
56: if (ta->ta_howto_data.const_thread_area & 0xff000000U)
57: ta->ta_howto_data.const_thread_area
58: = bswap_32 (ta->ta_howto_data.const_thread_area);
59: }
60: else
61: {
62: switch (sizeof (regs[0]))
63: {
64: case 8:
65: err = td_lookup (ta->ph, SYM_TH_UNIQUE_REGISTER64, &howto);
66: if (err == PS_OK)
67: ta->ta_howto = ta_howto_reg;
68: else if (err == PS_NOSYM)
69: {
70: err = td_lookup (ta->ph,
71: SYM_TH_UNIQUE_REGISTER64_THREAD_AREA,
72: &howto);
73: if (err == PS_OK)
74: ta->ta_howto = ta_howto_reg_thread_area;
75: }
76: break;
77:
78: case 4:
79: err = td_lookup (ta->ph, SYM_TH_UNIQUE_REGISTER32, &howto);
80: if (err == PS_OK)
81: ta->ta_howto = ta_howto_reg;
82: else if (err == PS_NOSYM)
83: {
84: err = td_lookup (ta->ph,
85: SYM_TH_UNIQUE_REGISTER32_THREAD_AREA,
86: &howto);
87: if (err == PS_OK)
88: ta->ta_howto = ta_howto_reg_thread_area;
89: }
90: break;
91:
92: default:
93: abort ();
94: return TD_DBERR;
95: }
96:
97: if (err != PS_OK)
98: return TD_DBERR;
99:
100:
101: err = ps_pdread (ta->ph, howto,
102: ta->ta_howto_data.reg, DB_SIZEOF_DESC);
103: if (err != PS_OK)
104: return TD_ERR;
105: if (DB_DESC_SIZE (ta->ta_howto_data.reg) == 0)
106: return TD_DBERR;
107: if (DB_DESC_SIZE (ta->ta_howto_data.reg) & 0xff000000U)
108: {
109:
110:
111: DB_DESC_OFFSET (ta->ta_howto_data.reg)
112: = bswap_32 (DB_DESC_OFFSET (ta->ta_howto_data.reg));
113: DB_DESC_NELEM (ta->ta_howto_data.reg)
114: = bswap_32 (DB_DESC_NELEM (ta->ta_howto_data.reg));
115: }
116: }
117: }
118:
119: switch (ta->ta_howto)
120: {
121: default:
122: return TD_DBERR;
123:
124: case ta_howto_reg:
125:
126: if (ps_lgetregs (ta->ph, lwpid, regs) != PS_OK)
127: return TD_ERR;
128: terr = _td_fetch_value_local (ta, ta->ta_howto_data.reg, -1,
129: 0, regs, &addr);
130: if (terr != TD_OK)
131: return terr;
132:
133:
134: addr += (int32_t) DB_DESC_NELEM (ta->ta_howto_data.reg);
135: th->th_unique = addr;
136: break;
137:
138: case ta_howto_const_thread_area:
139:
140: # pragma weak ps_get_thread_area
141: if (&ps_get_thread_area == NULL)
142: return TD_NOCAPAB;
143:
144:
145: if (ps_get_thread_area (ta->ph, lwpid,
146: ta->ta_howto_data.const_thread_area,
147: &th->th_unique) != PS_OK)
148: return TD_ERR;
149: break;
150:
151: case ta_howto_reg_thread_area:
152: if (&ps_get_thread_area == NULL)
153: return TD_NOCAPAB;
154:
155:
156: if (ps_lgetregs (ta->ph, lwpid, regs) != PS_OK)
157: return TD_ERR;
158: terr = _td_fetch_value_local (ta, ta->ta_howto_data.reg_thread_area,
159: -1, 0, regs, &addr);
160: if (terr != TD_OK)
161: return terr;
162:
163: if (ps_get_thread_area
164: (ta->ph, lwpid,
165: ((addr - (psaddr_t) 0)
166: >> DB_DESC_NELEM (ta->ta_howto_data.reg_thread_area)),
167: &th->th_unique) != PS_OK)
168: return TD_ERR;
169: break;
170: }
171:
172:
173: th->th_ta_p = ta;
174:
175: return TD_OK;
176: }
177:
178: td_err_e
179: td_ta_map_lwp2thr (const td_thragent_t *ta_arg,
180: lwpid_t lwpid, td_thrhandle_t *th)
181: {
182: td_thragent_t *const ta = (td_thragent_t *) ta_arg;
183:
184:
185:
186:
187:
188:
189:
190: psaddr_t list;
191: td_err_e err = DB_GET_SYMBOL (list, ta, __stack_user);
192: if (err != TD_OK)
193: return err;
194:
195: err = DB_GET_FIELD (list, ta, list, list_t, next, 0);
196: if (err != TD_OK)
197: return err;
198:
199: if (list == 0)
200: {
201: if (ps_getpid (ta->ph) != lwpid)
202: return TD_ERR;
203: th->th_ta_p = ta;
204: th->th_unique = 0;
205: return TD_OK;
206: }
207:
208: return __td_ta_lookup_th_unique (ta_arg, lwpid, th);
209: }