Blame


1 e8a7b969 2004-12-27 devnull #include <u.h>
2 e8a7b969 2004-12-27 devnull #include <thread_db.h>
3 e8a7b969 2004-12-27 devnull #include <sys/ptrace.h>
4 e8a7b969 2004-12-27 devnull #include <errno.h>
5 e8a7b969 2004-12-27 devnull #include <sys/procfs.h> /* psaddr_t */
6 e8a7b969 2004-12-27 devnull #include <libc.h>
7 e8a7b969 2004-12-27 devnull #include <mach.h>
8 e8a7b969 2004-12-27 devnull
9 dd944ec7 2005-01-23 devnull typedef struct Ptprog Ptprog;
10 dd944ec7 2005-01-23 devnull struct Pprog
11 dd944ec7 2005-01-23 devnull {
12 dd944ec7 2005-01-23 devnull Pthread *t;
13 dd944ec7 2005-01-23 devnull uint nt;
14 dd944ec7 2005-01-23 devnull };
15 dd944ec7 2005-01-23 devnull
16 dd944ec7 2005-01-23 devnull typedef struct Pthread Pthread;
17 dd944ec7 2005-01-23 devnull struct Pthread
18 dd944ec7 2005-01-23 devnull {
19 dd944ec7 2005-01-23 devnull td_thrhandle_t handle;
20 dd944ec7 2005-01-23 devnull };
21 dd944ec7 2005-01-23 devnull
22 dd944ec7 2005-01-23 devnull void
23 dd944ec7 2005-01-23 devnull pthreadattach(int pid)
24 dd944ec7 2005-01-23 devnull {
25 dd944ec7 2005-01-23 devnull
26 dd944ec7 2005-01-23 devnull }
27 dd944ec7 2005-01-23 devnull
28 dd944ec7 2005-01-23 devnull void pthreadattach()
29 dd944ec7 2005-01-23 devnull set up mapping
30 dd944ec7 2005-01-23 devnull
31 dd944ec7 2005-01-23 devnull Regs *pthreadregs()
32 dd944ec7 2005-01-23 devnull int npthread();
33 dd944ec7 2005-01-23 devnull
34 dd944ec7 2005-01-23 devnull
35 dd944ec7 2005-01-23 devnull
36 dd944ec7 2005-01-23 devnull static int td_get_allthreads(td_thragent_t*, td_thrhandle_t**);
37 dd944ec7 2005-01-23 devnull static int terr(int);
38 dd944ec7 2005-01-23 devnull
39 dd944ec7 2005-01-23 devnull
40 dd944ec7 2005-01-23 devnull Regs*
41 dd944ec7 2005-01-23 devnull threadregs()
42 dd944ec7 2005-01-23 devnull {
43 dd944ec7 2005-01-23 devnull
44 dd944ec7 2005-01-23 devnull }
45 dd944ec7 2005-01-23 devnull
46 dd944ec7 2005-01-23 devnull
47 dd944ec7 2005-01-23 devnull
48 dd944ec7 2005-01-23 devnull typedef struct AllThread AllThread;
49 dd944ec7 2005-01-23 devnull struct AllThread
50 dd944ec7 2005-01-23 devnull {
51 dd944ec7 2005-01-23 devnull td_thrhandle_t *a;
52 dd944ec7 2005-01-23 devnull int n;
53 dd944ec7 2005-01-23 devnull int err;
54 dd944ec7 2005-01-23 devnull };
55 dd944ec7 2005-01-23 devnull
56 dd944ec7 2005-01-23 devnull static int
57 dd944ec7 2005-01-23 devnull thritercb(const td_thrhandle_t *th, void *cb)
58 dd944ec7 2005-01-23 devnull {
59 dd944ec7 2005-01-23 devnull td_thrhandle_t **p;
60 dd944ec7 2005-01-23 devnull AllThread *a;
61 dd944ec7 2005-01-23 devnull int n;
62 dd944ec7 2005-01-23 devnull
63 dd944ec7 2005-01-23 devnull a = cb;
64 dd944ec7 2005-01-23 devnull if((a->n&(a->n-1)) == 0){
65 dd944ec7 2005-01-23 devnull if(a->n == 0)
66 dd944ec7 2005-01-23 devnull n = 1;
67 dd944ec7 2005-01-23 devnull else
68 dd944ec7 2005-01-23 devnull n = a->n<<1;
69 dd944ec7 2005-01-23 devnull if((p = realloc(a->a, n*sizeof a->a[0])) == 0){
70 dd944ec7 2005-01-23 devnull a->err = -1;
71 dd944ec7 2005-01-23 devnull return -1; /* stop iteration */
72 dd944ec7 2005-01-23 devnull }
73 dd944ec7 2005-01-23 devnull a->a = p;
74 dd944ec7 2005-01-23 devnull }
75 dd944ec7 2005-01-23 devnull a->a[a->n++] = *th;
76 dd944ec7 2005-01-23 devnull return 0;
77 dd944ec7 2005-01-23 devnull }
78 dd944ec7 2005-01-23 devnull
79 dd944ec7 2005-01-23 devnull int
80 dd944ec7 2005-01-23 devnull td_get_allthreads(td_thragent_t *ta, td_thrhandle_t **pall)
81 dd944ec7 2005-01-23 devnull {
82 dd944ec7 2005-01-23 devnull int e;
83 dd944ec7 2005-01-23 devnull AllThread a;
84 dd944ec7 2005-01-23 devnull
85 dd944ec7 2005-01-23 devnull a.a = nil;
86 dd944ec7 2005-01-23 devnull a.n = 0;
87 dd944ec7 2005-01-23 devnull a.err = 0;
88 dd944ec7 2005-01-23 devnull if((e = td_ta_thr_iter(ta, thritercb, &a,
89 dd944ec7 2005-01-23 devnull TD_THR_ANY_STATE,
90 dd944ec7 2005-01-23 devnull TD_THR_LOWEST_PRIORITY,
91 dd944ec7 2005-01-23 devnull TD_SIGNO_MASK,
92 dd944ec7 2005-01-23 devnull TD_THR_ANY_USER_FLAGS)) != TD_OK){
93 dd944ec7 2005-01-23 devnull werrstr("%s", terr(e));
94 dd944ec7 2005-01-23 devnull return -1;
95 dd944ec7 2005-01-23 devnull }
96 dd944ec7 2005-01-23 devnull
97 dd944ec7 2005-01-23 devnull if(a.err){
98 dd944ec7 2005-01-23 devnull free(a.a);
99 dd944ec7 2005-01-23 devnull return -1;
100 dd944ec7 2005-01-23 devnull }
101 dd944ec7 2005-01-23 devnull
102 dd944ec7 2005-01-23 devnull *pall = a.a;
103 dd944ec7 2005-01-23 devnull return a.n;
104 dd944ec7 2005-01-23 devnull }
105 dd944ec7 2005-01-23 devnull
106 e8a7b969 2004-12-27 devnull static char *tderrstr[] =
107 e8a7b969 2004-12-27 devnull {
108 e8a7b969 2004-12-27 devnull [TD_OK] "no error",
109 e8a7b969 2004-12-27 devnull [TD_ERR] "some error",
110 e8a7b969 2004-12-27 devnull [TD_NOTHR] "no matching thread found",
111 e8a7b969 2004-12-27 devnull [TD_NOSV] "no matching synchronization handle found",
112 e8a7b969 2004-12-27 devnull [TD_NOLWP] "no matching light-weight process found",
113 e8a7b969 2004-12-27 devnull [TD_BADPH] "invalid process handle",
114 e8a7b969 2004-12-27 devnull [TD_BADTH] "invalid thread handle",
115 e8a7b969 2004-12-27 devnull [TD_BADSH] "invalid synchronization handle",
116 e8a7b969 2004-12-27 devnull [TD_BADTA] "invalid thread agent",
117 e8a7b969 2004-12-27 devnull [TD_BADKEY] "invalid key",
118 e8a7b969 2004-12-27 devnull [TD_NOMSG] "no event available",
119 e8a7b969 2004-12-27 devnull [TD_NOFPREGS] "no floating-point register content available",
120 e8a7b969 2004-12-27 devnull [TD_NOLIBTHREAD] "application not linked with thread library",
121 e8a7b969 2004-12-27 devnull [TD_NOEVENT] "requested event is not supported",
122 e8a7b969 2004-12-27 devnull [TD_NOEVENT] "requested event is not supported",
123 e8a7b969 2004-12-27 devnull [TD_NOCAPAB] "capability not available",
124 e8a7b969 2004-12-27 devnull [TD_DBERR] "internal debug library error",
125 e8a7b969 2004-12-27 devnull [TD_NOAPLIC] "operation is not applicable",
126 e8a7b969 2004-12-27 devnull [TD_NOTSD] "no thread-specific data available",
127 e8a7b969 2004-12-27 devnull [TD_MALLOC] "out of memory",
128 e8a7b969 2004-12-27 devnull [TD_PARTIALREG] "not entire register set was read or written",
129 e8a7b969 2004-12-27 devnull [TD_NOXREGS] "X register set not available for given threads",
130 e8a7b969 2004-12-27 devnull [TD_TLSDEFER] "thread has not yet allocated TLS for given module",
131 e8a7b969 2004-12-27 devnull [TD_VERSION] "version mismatch twixt libpthread and libthread_db",
132 e8a7b969 2004-12-27 devnull [TD_NOTLS] "there is no TLS segment in the given module",
133 e8a7b969 2004-12-27 devnull };
134 e8a7b969 2004-12-27 devnull
135 e8a7b969 2004-12-27 devnull static char*
136 e8a7b969 2004-12-27 devnull terr(int e)
137 e8a7b969 2004-12-27 devnull {
138 e8a7b969 2004-12-27 devnull static char buf[50];
139 e8a7b969 2004-12-27 devnull
140 e8a7b969 2004-12-27 devnull if(e < 0 || e >= nelem(tderrstr) || tderrstr[e] == nil){
141 e8a7b969 2004-12-27 devnull snprint(buf, sizeof buf, "thread err %d", e);
142 e8a7b969 2004-12-27 devnull return buf;
143 e8a7b969 2004-12-27 devnull }
144 e8a7b969 2004-12-27 devnull return tderrstr[e];
145 e8a7b969 2004-12-27 devnull }
146 e8a7b969 2004-12-27 devnull
147 dd944ec7 2005-01-23 devnull /*
148 dd944ec7 2005-01-23 devnull * bottom-end functions for libthread_db to call
149 dd944ec7 2005-01-23 devnull */
150 dd944ec7 2005-01-23 devnull enum
151 dd944ec7 2005-01-23 devnull {
152 dd944ec7 2005-01-23 devnull PS_OK,
153 dd944ec7 2005-01-23 devnull PS_ERR,
154 dd944ec7 2005-01-23 devnull PS_BADPID,
155 dd944ec7 2005-01-23 devnull PS_BADLWPID,
156 dd944ec7 2005-01-23 devnull PS_BADADDR,
157 dd944ec7 2005-01-23 devnull PS_NOSYM,
158 dd944ec7 2005-01-23 devnull PS_NOFPREGS,
159 dd944ec7 2005-01-23 devnull };
160 dd944ec7 2005-01-23 devnull
161 dd944ec7 2005-01-23 devnull pid_t
162 dd944ec7 2005-01-23 devnull ps_getpid(struct ps_prochandle *ph)
163 dd944ec7 2005-01-23 devnull {
164 dd944ec7 2005-01-23 devnull return ph->pid;
165 dd944ec7 2005-01-23 devnull }
166 dd944ec7 2005-01-23 devnull
167 dd944ec7 2005-01-23 devnull int
168 dd944ec7 2005-01-23 devnull ps_pstop(const struct ps_prochandle *ph)
169 dd944ec7 2005-01-23 devnull {
170 dd944ec7 2005-01-23 devnull return PS_ERR;
171 dd944ec7 2005-01-23 devnull }
172 dd944ec7 2005-01-23 devnull
173 dd944ec7 2005-01-23 devnull int
174 dd944ec7 2005-01-23 devnull ps_pcontinue(const struct ps_prochandle *ph)
175 dd944ec7 2005-01-23 devnull {
176 dd944ec7 2005-01-23 devnull return PS_ERR;
177 dd944ec7 2005-01-23 devnull }
178 dd944ec7 2005-01-23 devnull
179 dd944ec7 2005-01-23 devnull int
180 dd944ec7 2005-01-23 devnull ps_lstop(const struct ps_prochandle *ph)
181 dd944ec7 2005-01-23 devnull {
182 dd944ec7 2005-01-23 devnull return PS_ERR;
183 dd944ec7 2005-01-23 devnull }
184 dd944ec7 2005-01-23 devnull
185 dd944ec7 2005-01-23 devnull int
186 dd944ec7 2005-01-23 devnull ps_lcontinue(const struct ps_prochandle *ph)
187 dd944ec7 2005-01-23 devnull {
188 dd944ec7 2005-01-23 devnull return PS_ERR;
189 dd944ec7 2005-01-23 devnull }
190 dd944ec7 2005-01-23 devnull
191 dd944ec7 2005-01-23 devnull /* read/write data or text memory */
192 dd944ec7 2005-01-23 devnull int
193 dd944ec7 2005-01-23 devnull ps_pdread(struct ps_prochandle *ph, psaddr_t addr, void *v, size_t sz)
194 dd944ec7 2005-01-23 devnull {
195 dd944ec7 2005-01-23 devnull if(get1(ph->map, addr, v, sz) < 0)
196 dd944ec7 2005-01-23 devnull return PS_ERR;
197 dd944ec7 2005-01-23 devnull return PS_OK;
198 dd944ec7 2005-01-23 devnull }
199 dd944ec7 2005-01-23 devnull
200 dd944ec7 2005-01-23 devnull int
201 dd944ec7 2005-01-23 devnull ps_pdwrite(struct ps_prochandle *ph, psaddr_t addr, void *v, size_t sz)
202 dd944ec7 2005-01-23 devnull {
203 dd944ec7 2005-01-23 devnull if(put1(ph->map, addr, v, sz) < 0)
204 dd944ec7 2005-01-23 devnull return PS_ERR;
205 dd944ec7 2005-01-23 devnull return PS_OK;
206 dd944ec7 2005-01-23 devnull }
207 dd944ec7 2005-01-23 devnull
208 dd944ec7 2005-01-23 devnull int
209 dd944ec7 2005-01-23 devnull ps_ptread(struct ps_prochandle *ph, psaddr_t addr, void *v, size_t sz)
210 dd944ec7 2005-01-23 devnull {
211 dd944ec7 2005-01-23 devnull return ps_pdread(ph, addr, v, sz);
212 dd944ec7 2005-01-23 devnull }
213 dd944ec7 2005-01-23 devnull
214 dd944ec7 2005-01-23 devnull int
215 dd944ec7 2005-01-23 devnull ps_ptwrite(struct ps_prochandle *ph, psaddr_t addr, void *v, size_t sz)
216 dd944ec7 2005-01-23 devnull {
217 dd944ec7 2005-01-23 devnull return ps_pdwrite(ph, addr, v, sz);
218 dd944ec7 2005-01-23 devnull }
219 dd944ec7 2005-01-23 devnull
220 dd944ec7 2005-01-23 devnull int
221 dd944ec7 2005-01-23 devnull ps_lgetregs(struct ps_prochandle *ph, lwpid_t lwp, prgregset_t regs)
222 dd944ec7 2005-01-23 devnull {
223 dd944ec7 2005-01-23 devnull int i;
224 dd944ec7 2005-01-23 devnull
225 dd944ec7 2005-01-23 devnull USED(ph);
226 dd944ec7 2005-01-23 devnull if(corhdr == nil)
227 dd944ec7 2005-01-23 devnull return sys_ps_lgetregs(ph, lwp, regs);
228 dd944ec7 2005-01-23 devnull for(i=0; i<corhdr->nthread; i++){
229 dd944ec7 2005-01-23 devnull if(corhdr->thread[i].id == lwp){
230 dd944ec7 2005-01-23 devnull ureg2prgregset(corhdr->thread[i].ureg, regs);
231 dd944ec7 2005-01-23 devnull return PS_OK;
232 dd944ec7 2005-01-23 devnull }
233 dd944ec7 2005-01-23 devnull }
234 dd944ec7 2005-01-23 devnull return PS_ERR;
235 dd944ec7 2005-01-23 devnull }
236 dd944ec7 2005-01-23 devnull
237 dd944ec7 2005-01-23 devnull int
238 dd944ec7 2005-01-23 devnull ps_lsetregs(struct ps_prochandle *ph, lwpid_t lwp, prgregset_t regs)
239 dd944ec7 2005-01-23 devnull {
240 dd944ec7 2005-01-23 devnull if(corhdr == nil)
241 dd944ec7 2005-01-23 devnull return sys_ps_lsetregs(ph, lwp, regs);
242 dd944ec7 2005-01-23 devnull return PS_ERR;
243 dd944ec7 2005-01-23 devnull }
244 dd944ec7 2005-01-23 devnull
245 dd944ec7 2005-01-23 devnull int
246 dd944ec7 2005-01-23 devnull ps_lgetfpregs(struct ps_prochandle *ph, lwpid_t lwp, prfpregset_t *fpregs)
247 dd944ec7 2005-01-23 devnull {
248 dd944ec7 2005-01-23 devnull if(corhdr == nil)
249 dd944ec7 2005-01-23 devnull return sys_ps_lgetfpregs(ph, lwp, fpregs);
250 dd944ec7 2005-01-23 devnull /* BUG - Look in core dump. */
251 dd944ec7 2005-01-23 devnull return PS_ERR:
252 dd944ec7 2005-01-23 devnull }
253 dd944ec7 2005-01-23 devnull
254 dd944ec7 2005-01-23 devnull int
255 dd944ec7 2005-01-23 devnull ps_lsetfpregs(struct ps_prochandle *ph, lwpid_t lwp, prfpregset_t *fpregs)
256 dd944ec7 2005-01-23 devnull {
257 dd944ec7 2005-01-23 devnull if(corhdr == nil)
258 dd944ec7 2005-01-23 devnull return sys_ps_lsetfpregs(ph, lwp, fpregs);
259 dd944ec7 2005-01-23 devnull return PS_ERR;
260 dd944ec7 2005-01-23 devnull }
261 dd944ec7 2005-01-23 devnull
262 dd944ec7 2005-01-23 devnull /* Fetch the special per-thread address associated with the given LWP.
263 dd944ec7 2005-01-23 devnull This call is only used on a few platforms (most use a normal register).
264 dd944ec7 2005-01-23 devnull The meaning of the `int' parameter is machine-dependent. */
265 dd944ec7 2005-01-23 devnull int
266 dd944ec7 2005-01-23 devnull ps_get_thread_area(struct ps_prochandle *ph, lwpid_t lwp, int xxx, psaddr_t *addr)
267 dd944ec7 2005-01-23 devnull {
268 dd944ec7 2005-01-23 devnull return sys_ps_get_thread_area(ph, lwp, xxx, addr);
269 dd944ec7 2005-01-23 devnull }
270 dd944ec7 2005-01-23 devnull
271 dd944ec7 2005-01-23 devnull int
272 dd944ec7 2005-01-23 devnull ps_pglobal_lookup(struct ps_prochandle *ph, char *object_name, char *sym_name, psaddr_t *sym_addr)
273 dd944ec7 2005-01-23 devnull {
274 dd944ec7 2005-01-23 devnull Fhdr *fp;
275 dd944ec7 2005-01-23 devnull ulong addr;
276 dd944ec7 2005-01-23 devnull
277 dd944ec7 2005-01-23 devnull if((fp = findhdr(object_name)) == nil){
278 dd944ec7 2005-01-23 devnull print("libmach pthread: lookup %d %s %s => no such hdr\n", ph->pid, object_name, sym_name);
279 dd944ec7 2005-01-23 devnull return PS_NOSYM;
280 dd944ec7 2005-01-23 devnull }
281 dd944ec7 2005-01-23 devnull if(elfsymlookup(fp->elf, sym_name, &addr) < 0){
282 dd944ec7 2005-01-23 devnull print("libmach pthread: lookup %d %s %s => name not found\n", ph->pid, object_name, sym_name);
283 dd944ec7 2005-01-23 devnull return PS_NOSYM;
284 dd944ec7 2005-01-23 devnull }
285 dd944ec7 2005-01-23 devnull /* print("libmach pthread: lookup %d %s %s => 0x%lux\n", ph->pid, object_name, sym_name, addr); */
286 dd944ec7 2005-01-23 devnull *sym_addr = (void*)(addr+fp->base);
287 dd944ec7 2005-01-23 devnull return PS_OK;
288 dd944ec7 2005-01-23 devnull }
289 dd944ec7 2005-01-23 devnull