2009-04-01 Pedro Alves <pedro@codesourcery.com>
[deliverable/binutils-gdb.git] / gdb / gdbserver / spu-low.c
CommitLineData
a13e2c95 1/* Low level interface to SPUs, for the remote server for GDB.
0fb0cc75 2 Copyright (C) 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
a13e2c95
UW
3
4 Contributed by Ulrich Weigand <uweigand@de.ibm.com>.
5
6 This file is part of GDB.
7
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
a9762ec7 10 the Free Software Foundation; either version 3 of the License, or
a13e2c95
UW
11 (at your option) any later version.
12
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
a9762ec7 19 along with this program. If not, see <http://www.gnu.org/licenses/>. */
a13e2c95
UW
20
21#include "server.h"
22
23#include <sys/wait.h>
24#include <stdio.h>
25#include <sys/ptrace.h>
26#include <fcntl.h>
27#include <string.h>
28#include <stdlib.h>
29#include <unistd.h>
30#include <errno.h>
31#include <sys/syscall.h>
32
33/* Some older glibc versions do not define this. */
34#ifndef __WNOTHREAD
35#define __WNOTHREAD 0x20000000 /* Don't wait on children of other
1b3f6016 36 threads in this group */
a13e2c95
UW
37#endif
38
39#define PTRACE_TYPE_RET long
40#define PTRACE_TYPE_ARG3 long
41
42/* Number of registers. */
43#define SPU_NUM_REGS 130
44#define SPU_NUM_CORE_REGS 128
45
46/* Special registers. */
47#define SPU_ID_REGNUM 128
48#define SPU_PC_REGNUM 129
49
50/* PPU side system calls. */
51#define INSTR_SC 0x44000002
52#define NR_spu_run 0x0116
53
54/* Get current thread ID (Linux task ID). */
55#define current_tid ((struct inferior_list_entry *)current_inferior)->id
56
57/* These are used in remote-utils.c. */
58int using_threads = 0;
a13e2c95 59
d05b4ac3
UW
60/* Defined in auto-generated file reg-spu.c. */
61void init_registers_spu (void);
62
a13e2c95
UW
63
64/* Fetch PPU register REGNO. */
65static CORE_ADDR
66fetch_ppc_register (int regno)
67{
68 PTRACE_TYPE_RET res;
69
70 int tid = current_tid;
71
72#ifndef __powerpc64__
73 /* If running as a 32-bit process on a 64-bit system, we attempt
74 to get the full 64-bit register content of the target process.
75 If the PPC special ptrace call fails, we're on a 32-bit system;
76 just fall through to the regular ptrace call in that case. */
77 {
78 char buf[8];
79
80 errno = 0;
81 ptrace (PPC_PTRACE_PEEKUSR_3264, tid,
82 (PTRACE_TYPE_ARG3) (regno * 8), buf);
83 if (errno == 0)
84 ptrace (PPC_PTRACE_PEEKUSR_3264, tid,
85 (PTRACE_TYPE_ARG3) (regno * 8 + 4), buf + 4);
86 if (errno == 0)
87 return (CORE_ADDR) *(unsigned long long *)buf;
88 }
89#endif
90
91 errno = 0;
92 res = ptrace (PT_READ_U, tid,
1b3f6016 93 (PTRACE_TYPE_ARG3) (regno * sizeof (PTRACE_TYPE_RET)), 0);
a13e2c95
UW
94 if (errno != 0)
95 {
96 char mess[128];
97 sprintf (mess, "reading PPC register #%d", regno);
98 perror_with_name (mess);
99 }
100
101 return (CORE_ADDR) (unsigned long) res;
102}
103
104/* Fetch WORD from PPU memory at (aligned) MEMADDR in thread TID. */
105static int
106fetch_ppc_memory_1 (int tid, CORE_ADDR memaddr, PTRACE_TYPE_RET *word)
107{
108 errno = 0;
109
110#ifndef __powerpc64__
111 if (memaddr >> 32)
112 {
113 unsigned long long addr_8 = (unsigned long long) memaddr;
114 ptrace (PPC_PTRACE_PEEKTEXT_3264, tid, (PTRACE_TYPE_ARG3) &addr_8, word);
115 }
116 else
117#endif
118 *word = ptrace (PT_READ_I, tid, (PTRACE_TYPE_ARG3) (size_t) memaddr, 0);
119
120 return errno;
121}
122
123/* Store WORD into PPU memory at (aligned) MEMADDR in thread TID. */
124static int
125store_ppc_memory_1 (int tid, CORE_ADDR memaddr, PTRACE_TYPE_RET word)
126{
127 errno = 0;
128
129#ifndef __powerpc64__
130 if (memaddr >> 32)
131 {
132 unsigned long long addr_8 = (unsigned long long) memaddr;
133 ptrace (PPC_PTRACE_POKEDATA_3264, tid, (PTRACE_TYPE_ARG3) &addr_8, word);
134 }
135 else
136#endif
137 ptrace (PT_WRITE_D, tid, (PTRACE_TYPE_ARG3) (size_t) memaddr, word);
138
139 return errno;
140}
141
142/* Fetch LEN bytes of PPU memory at MEMADDR to MYADDR. */
143static int
144fetch_ppc_memory (CORE_ADDR memaddr, char *myaddr, int len)
145{
146 int i, ret;
147
148 CORE_ADDR addr = memaddr & -(CORE_ADDR) sizeof (PTRACE_TYPE_RET);
149 int count = ((((memaddr + len) - addr) + sizeof (PTRACE_TYPE_RET) - 1)
150 / sizeof (PTRACE_TYPE_RET));
151 PTRACE_TYPE_RET *buffer;
152
153 int tid = current_tid;
154
155 buffer = (PTRACE_TYPE_RET *) alloca (count * sizeof (PTRACE_TYPE_RET));
156 for (i = 0; i < count; i++, addr += sizeof (PTRACE_TYPE_RET))
157 if ((ret = fetch_ppc_memory_1 (tid, addr, &buffer[i])) != 0)
158 return ret;
159
160 memcpy (myaddr,
161 (char *) buffer + (memaddr & (sizeof (PTRACE_TYPE_RET) - 1)),
162 len);
163
164 return 0;
165}
166
167/* Store LEN bytes from MYADDR to PPU memory at MEMADDR. */
168static int
169store_ppc_memory (CORE_ADDR memaddr, char *myaddr, int len)
170{
171 int i, ret;
172
173 CORE_ADDR addr = memaddr & -(CORE_ADDR) sizeof (PTRACE_TYPE_RET);
174 int count = ((((memaddr + len) - addr) + sizeof (PTRACE_TYPE_RET) - 1)
175 / sizeof (PTRACE_TYPE_RET));
176 PTRACE_TYPE_RET *buffer;
177
178 int tid = current_tid;
179
180 buffer = (PTRACE_TYPE_RET *) alloca (count * sizeof (PTRACE_TYPE_RET));
181
182 if (addr != memaddr || len < (int) sizeof (PTRACE_TYPE_RET))
183 if ((ret = fetch_ppc_memory_1 (tid, addr, &buffer[0])) != 0)
184 return ret;
185
186 if (count > 1)
187 if ((ret = fetch_ppc_memory_1 (tid, addr + (count - 1)
188 * sizeof (PTRACE_TYPE_RET),
189 &buffer[count - 1])) != 0)
190 return ret;
191
192 memcpy ((char *) buffer + (memaddr & (sizeof (PTRACE_TYPE_RET) - 1)),
1b3f6016 193 myaddr, len);
a13e2c95
UW
194
195 for (i = 0; i < count; i++, addr += sizeof (PTRACE_TYPE_RET))
196 if ((ret = store_ppc_memory_1 (tid, addr, buffer[i])) != 0)
197 return ret;
198
199 return 0;
200}
201
202
203/* If the PPU thread is currently stopped on a spu_run system call,
204 return to FD and ADDR the file handle and NPC parameter address
205 used with the system call. Return non-zero if successful. */
1b3f6016 206static int
a13e2c95
UW
207parse_spufs_run (int *fd, CORE_ADDR *addr)
208{
209 char buf[4];
210 CORE_ADDR pc = fetch_ppc_register (32); /* nip */
211
212 /* Fetch instruction preceding current NIP. */
213 if (fetch_ppc_memory (pc-4, buf, 4) != 0)
214 return 0;
215 /* It should be a "sc" instruction. */
216 if (*(unsigned int *)buf != INSTR_SC)
217 return 0;
218 /* System call number should be NR_spu_run. */
219 if (fetch_ppc_register (0) != NR_spu_run)
220 return 0;
221
222 /* Register 3 contains fd, register 4 the NPC param pointer. */
223 *fd = fetch_ppc_register (34); /* orig_gpr3 */
224 *addr = fetch_ppc_register (4);
225 return 1;
226}
227
228
229/* Copy LEN bytes at OFFSET in spufs file ANNEX into/from READBUF or WRITEBUF,
230 using the /proc file system. */
231static int
232spu_proc_xfer_spu (const char *annex, unsigned char *readbuf,
233 const unsigned char *writebuf,
234 CORE_ADDR offset, int len)
235{
236 char buf[128];
237 int fd = 0;
238 int ret = -1;
239
240 if (!annex)
241 return 0;
242
243 sprintf (buf, "/proc/%ld/fd/%s", current_tid, annex);
244 fd = open (buf, writebuf? O_WRONLY : O_RDONLY);
245 if (fd <= 0)
246 return -1;
247
248 if (offset != 0
249 && lseek (fd, (off_t) offset, SEEK_SET) != (off_t) offset)
250 {
251 close (fd);
374c1d38 252 return 0;
a13e2c95
UW
253 }
254
255 if (writebuf)
256 ret = write (fd, writebuf, (size_t) len);
257 else if (readbuf)
258 ret = read (fd, readbuf, (size_t) len);
259
260 close (fd);
261 return ret;
262}
263
264
265/* Start an inferior process and returns its pid.
266 ALLARGS is a vector of program-name and args. */
267static int
268spu_create_inferior (char *program, char **allargs)
269{
270 int pid;
95954743 271 ptid_t ptid;
a13e2c95
UW
272
273 pid = fork ();
274 if (pid < 0)
275 perror_with_name ("fork");
276
277 if (pid == 0)
278 {
279 ptrace (PTRACE_TRACEME, 0, 0, 0);
280
281 setpgid (0, 0);
282
2b876972
DJ
283 execv (program, allargs);
284 if (errno == ENOENT)
285 execvp (program, allargs);
a13e2c95
UW
286
287 fprintf (stderr, "Cannot exec %s: %s.\n", program,
288 strerror (errno));
289 fflush (stderr);
290 _exit (0177);
291 }
292
95954743
PA
293 add_process (pid, 0);
294
295 ptid = ptid_build (pid, pid, 0);
296 add_thread (ptid, NULL);
a13e2c95
UW
297 return pid;
298}
299
300/* Attach to an inferior process. */
301int
302spu_attach (unsigned long pid)
303{
95954743
PA
304 ptid_t ptid;
305
a13e2c95
UW
306 if (ptrace (PTRACE_ATTACH, pid, 0, 0) != 0)
307 {
308 fprintf (stderr, "Cannot attach to process %ld: %s (%d)\n", pid,
309 strerror (errno), errno);
310 fflush (stderr);
311 _exit (0177);
312 }
313
95954743
PA
314 add_process (pid, 1);
315 ptid = ptid_build (pid, pid, 0);
316 add_thread (ptid, NULL);
a13e2c95
UW
317 return 0;
318}
319
320/* Kill the inferior process. */
95954743
PA
321static int
322spu_kill (int)
a13e2c95
UW
323{
324 ptrace (PTRACE_KILL, current_tid, 0, 0);
95954743
PA
325 remove_process (pid);
326 return 0;
a13e2c95
UW
327}
328
329/* Detach from inferior process. */
dd6953e1 330static int
95954743 331spu_detach (int pid)
a13e2c95
UW
332{
333 ptrace (PTRACE_DETACH, current_tid, 0, 0);
95954743 334 remove_process (pid);
dd6953e1 335 return 0;
a13e2c95
UW
336}
337
444d6139 338static void
95954743 339spu_join (int pid)
444d6139
PA
340{
341 int status, ret;
342
343 do {
344 ret = waitpid (current_tid, &status, 0);
345 if (WIFEXITED (status) || WIFSIGNALED (status))
346 break;
347 } while (ret != -1 || errno != ECHILD);
348}
349
a13e2c95
UW
350/* Return nonzero if the given thread is still alive. */
351static int
95954743 352spu_thread_alive (ptid_t ptid)
a13e2c95 353{
95954743 354 return ptid_get_lwp (ptid) == current_tid;
a13e2c95
UW
355}
356
357/* Resume process. */
358static void
2bd7c093 359spu_resume (struct thread_resume *resume_info, size_t n)
a13e2c95 360{
2bd7c093 361 size_t i;
a13e2c95 362
2bd7c093 363 for (i = 0; i < n; i++)
95954743
PA
364 if (ptid_equal (resume_info[i].thread, minus_one_ptid)
365 || ptid_get_lwp (resume_info[i].thread) == current_tid)
2bd7c093
PA
366 break;
367
368 if (i == n)
a13e2c95
UW
369 return;
370
371 /* We don't support hardware single-stepping right now, assume
372 GDB knows to use software single-stepping. */
bd99dc85 373 if (resume_info[i].kind == resume_step)
a13e2c95
UW
374 fprintf (stderr, "Hardware single-step not supported.\n");
375
376 regcache_invalidate ();
377
378 errno = 0;
2bd7c093 379 ptrace (PTRACE_CONT, current_tid, 0, resume_info[i].sig);
a13e2c95
UW
380 if (errno)
381 perror_with_name ("ptrace");
382}
383
384/* Wait for process, returns status. */
95954743
PA
385static ptid_t
386spu_wait (ptid_t ptid, struct target_waitstatus *ourstatus, int options)
a13e2c95
UW
387{
388 int tid = current_tid;
389 int w;
390 int ret;
391
a13e2c95
UW
392 while (1)
393 {
394 ret = waitpid (tid, &w, WNOHANG | __WALL | __WNOTHREAD);
395
396 if (ret == -1)
397 {
398 if (errno != ECHILD)
399 perror_with_name ("waitpid");
400 }
401 else if (ret > 0)
402 break;
403
404 usleep (1000);
405 }
406
407 /* On the first wait, continue running the inferior until we are
408 blocked inside an spu_run system call. */
409 if (!server_waiting)
410 {
411 int fd;
412 CORE_ADDR addr;
413
414 while (!parse_spufs_run (&fd, &addr))
415 {
416 ptrace (PT_SYSCALL, tid, (PTRACE_TYPE_ARG3) 0, 0);
417 waitpid (tid, NULL, __WALL | __WNOTHREAD);
418 }
419 }
420
5b1c542e
PA
421 ret = current_tid;
422
a13e2c95
UW
423 if (WIFEXITED (w))
424 {
425 fprintf (stderr, "\nChild exited with retcode = %x \n", WEXITSTATUS (w));
5b1c542e
PA
426 ourstatus->kind = TARGET_WAITKIND_EXITED;
427 ourstatus->value.integer = WEXITSTATUS (w);
a13e2c95 428 clear_inferiors ();
95954743
PA
429 remove_process (ret);
430 return pid_to_ptid (ret);
a13e2c95
UW
431 }
432 else if (!WIFSTOPPED (w))
433 {
434 fprintf (stderr, "\nChild terminated with signal = %x \n", WTERMSIG (w));
5b1c542e
PA
435 ourstatus->kind = TARGET_WAITKIND_SIGNALLED;
436 ourstatus->value.sig = target_signal_from_host (WTERMSIG (w));
a13e2c95 437 clear_inferiors ();
95954743
PA
438 remove_process (ret);
439 return pid_to_ptid (ret);
a13e2c95
UW
440 }
441
442 /* After attach, we may have received a SIGSTOP. Do not return this
443 as signal to GDB, or else it will try to continue with SIGSTOP ... */
444 if (!server_waiting)
445 {
5b1c542e
PA
446 ourstatus->kind = TARGET_WAITKIND_STOPPED;
447 ourstatus->value.sig = TARGET_SIGNAL_0;
95954743 448 return ptid_build (ret, ret, 0);
a13e2c95
UW
449 }
450
5b1c542e
PA
451 ourstatus->kind = TARGET_WAITKIND_STOPPED;
452 ourstatus->value.sig = target_signal_from_host (WSTOPSIG (w));
95954743 453 return ptid_build (ret, ret, 0);
a13e2c95
UW
454}
455
456/* Fetch inferior registers. */
457static void
458spu_fetch_registers (int regno)
459{
460 int fd;
461 CORE_ADDR addr;
462
463 /* ??? Some callers use 0 to mean all registers. */
464 if (regno == 0)
465 regno = -1;
466
467 /* We must be stopped on a spu_run system call. */
468 if (!parse_spufs_run (&fd, &addr))
469 return;
470
471 /* The ID register holds the spufs file handle. */
472 if (regno == -1 || regno == SPU_ID_REGNUM)
473 supply_register (SPU_ID_REGNUM, (char *)&fd);
474
475 /* The NPC register is found at ADDR. */
476 if (regno == -1 || regno == SPU_PC_REGNUM)
477 {
478 char buf[4];
479 if (fetch_ppc_memory (addr, buf, 4) == 0)
480 supply_register (SPU_PC_REGNUM, buf);
481 }
482
483 /* The GPRs are found in the "regs" spufs file. */
484 if (regno == -1 || (regno >= 0 && regno < SPU_NUM_CORE_REGS))
485 {
486 unsigned char buf[16*SPU_NUM_CORE_REGS];
487 char annex[32];
488 int i;
489
490 sprintf (annex, "%d/regs", fd);
491 if (spu_proc_xfer_spu (annex, buf, NULL, 0, sizeof buf) == sizeof buf)
492 for (i = 0; i < SPU_NUM_CORE_REGS; i++)
493 supply_register (i, buf + i*16);
494 }
495}
496
497/* Store inferior registers. */
498static void
499spu_store_registers (int regno)
500{
501 int fd;
502 CORE_ADDR addr;
503
504 /* ??? Some callers use 0 to mean all registers. */
505 if (regno == 0)
506 regno = -1;
507
508 /* We must be stopped on a spu_run system call. */
509 if (!parse_spufs_run (&fd, &addr))
510 return;
511
512 /* The NPC register is found at ADDR. */
513 if (regno == -1 || regno == SPU_PC_REGNUM)
514 {
515 char buf[4];
516 collect_register (SPU_PC_REGNUM, buf);
517 store_ppc_memory (addr, buf, 4);
518 }
519
520 /* The GPRs are found in the "regs" spufs file. */
521 if (regno == -1 || (regno >= 0 && regno < SPU_NUM_CORE_REGS))
522 {
523 unsigned char buf[16*SPU_NUM_CORE_REGS];
524 char annex[32];
525 int i;
526
527 for (i = 0; i < SPU_NUM_CORE_REGS; i++)
528 collect_register (i, buf + i*16);
529
530 sprintf (annex, "%d/regs", fd);
531 spu_proc_xfer_spu (annex, NULL, buf, 0, sizeof buf);
532 }
533}
534
535/* Copy LEN bytes from inferior's memory starting at MEMADDR
536 to debugger memory starting at MYADDR. */
537static int
538spu_read_memory (CORE_ADDR memaddr, unsigned char *myaddr, int len)
539{
540 int fd, ret;
541 CORE_ADDR addr;
542 char annex[32];
543
544 /* We must be stopped on a spu_run system call. */
545 if (!parse_spufs_run (&fd, &addr))
546 return 0;
547
548 /* Use the "mem" spufs file to access SPU local store. */
549 sprintf (annex, "%d/mem", fd);
550 ret = spu_proc_xfer_spu (annex, myaddr, NULL, memaddr, len);
551 return ret == len ? 0 : EIO;
552}
553
554/* Copy LEN bytes of data from debugger memory at MYADDR
555 to inferior's memory at MEMADDR.
556 On failure (cannot write the inferior)
557 returns the value of errno. */
558static int
559spu_write_memory (CORE_ADDR memaddr, const unsigned char *myaddr, int len)
560{
561 int fd, ret;
562 CORE_ADDR addr;
563 char annex[32];
564
565 /* We must be stopped on a spu_run system call. */
566 if (!parse_spufs_run (&fd, &addr))
567 return 0;
568
569 /* Use the "mem" spufs file to access SPU local store. */
570 sprintf (annex, "%d/mem", fd);
571 ret = spu_proc_xfer_spu (annex, NULL, myaddr, memaddr, len);
572 return ret == len ? 0 : EIO;
573}
574
575/* Look up special symbols -- unneded here. */
576static void
577spu_look_up_symbols (void)
578{
579}
580
581/* Send signal to inferior. */
582static void
ef57601b 583spu_request_interrupt (void)
a13e2c95 584{
ef57601b 585 syscall (SYS_tkill, current_tid, SIGINT);
a13e2c95
UW
586}
587
a13e2c95
UW
588static struct target_ops spu_target_ops = {
589 spu_create_inferior,
590 spu_attach,
591 spu_kill,
592 spu_detach,
444d6139 593 spu_join,
a13e2c95
UW
594 spu_thread_alive,
595 spu_resume,
596 spu_wait,
597 spu_fetch_registers,
598 spu_store_registers,
599 spu_read_memory,
600 spu_write_memory,
601 spu_look_up_symbols,
ef57601b 602 spu_request_interrupt,
a13e2c95 603 NULL,
ab39bf24
UW
604 NULL,
605 NULL,
606 NULL,
607 NULL,
608 NULL,
609 NULL,
0e7f50da 610 spu_proc_xfer_spu,
59a016f0 611 hostio_last_error_from_errno,
a13e2c95
UW
612};
613
614void
615initialize_low (void)
616{
617 static const unsigned char breakpoint[] = { 0x00, 0x00, 0x3f, 0xff };
618
619 set_target_ops (&spu_target_ops);
620 set_breakpoint_data (breakpoint, sizeof breakpoint);
d05b4ac3 621 init_registers_spu ();
a13e2c95 622}
This page took 0.206379 seconds and 4 git commands to generate.