* remote-utils.c (prepare_resume_reply): Null-terminate packet.
[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). */
5472f405 55#define current_ptid ((struct inferior_list_entry *)current_inferior)->id
a13e2c95
UW
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
5472f405 70 int tid = ptid_get_lwp (current_ptid);
a13e2c95
UW
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
5472f405 153 int tid = ptid_get_lwp (current_ptid);
a13e2c95
UW
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
5472f405 178 int tid = ptid_get_lwp (current_ptid);
a13e2c95
UW
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
5472f405 243 sprintf (buf, "/proc/%ld/fd/%s", ptid_get_lwp (current_ptid), annex);
a13e2c95
UW
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 321static int
5472f405 322spu_kill (int pid)
a13e2c95 323{
5472f405
UW
324 struct process_info *process = find_process_pid (pid);
325 if (process == NULL)
326 return -1;
327
328 ptrace (PTRACE_KILL, pid, 0, 0);
329 remove_process (process);
95954743 330 return 0;
a13e2c95
UW
331}
332
333/* Detach from inferior process. */
dd6953e1 334static int
95954743 335spu_detach (int pid)
a13e2c95 336{
5472f405
UW
337 struct process_info *process = find_process_pid (pid);
338 if (process == NULL)
339 return -1;
340
341 ptrace (PTRACE_DETACH, pid, 0, 0);
342 remove_process (process);
dd6953e1 343 return 0;
a13e2c95
UW
344}
345
444d6139 346static void
95954743 347spu_join (int pid)
444d6139
PA
348{
349 int status, ret;
5472f405
UW
350 struct process_info *process;
351
352 process = find_process_pid (pid);
353 if (process == NULL)
354 return;
444d6139
PA
355
356 do {
5472f405 357 ret = waitpid (pid, &status, 0);
444d6139
PA
358 if (WIFEXITED (status) || WIFSIGNALED (status))
359 break;
360 } while (ret != -1 || errno != ECHILD);
361}
362
a13e2c95
UW
363/* Return nonzero if the given thread is still alive. */
364static int
95954743 365spu_thread_alive (ptid_t ptid)
a13e2c95 366{
5472f405 367 return ptid_equal (ptid, current_ptid);
a13e2c95
UW
368}
369
370/* Resume process. */
371static void
2bd7c093 372spu_resume (struct thread_resume *resume_info, size_t n)
a13e2c95 373{
2bd7c093 374 size_t i;
a13e2c95 375
2bd7c093 376 for (i = 0; i < n; i++)
95954743 377 if (ptid_equal (resume_info[i].thread, minus_one_ptid)
5472f405 378 || ptid_equal (resume_info[i].thread, current_ptid))
2bd7c093
PA
379 break;
380
381 if (i == n)
a13e2c95
UW
382 return;
383
384 /* We don't support hardware single-stepping right now, assume
385 GDB knows to use software single-stepping. */
bd99dc85 386 if (resume_info[i].kind == resume_step)
a13e2c95
UW
387 fprintf (stderr, "Hardware single-step not supported.\n");
388
389 regcache_invalidate ();
390
391 errno = 0;
5472f405 392 ptrace (PTRACE_CONT, ptid_get_lwp (current_ptid), 0, resume_info[i].sig);
a13e2c95
UW
393 if (errno)
394 perror_with_name ("ptrace");
395}
396
397/* Wait for process, returns status. */
95954743
PA
398static ptid_t
399spu_wait (ptid_t ptid, struct target_waitstatus *ourstatus, int options)
a13e2c95 400{
5472f405 401 int pid = ptid_get_pid (ptid);
a13e2c95
UW
402 int w;
403 int ret;
404
a13e2c95
UW
405 while (1)
406 {
5472f405 407 ret = waitpid (pid, &w, WNOHANG | __WALL | __WNOTHREAD);
a13e2c95
UW
408
409 if (ret == -1)
410 {
411 if (errno != ECHILD)
412 perror_with_name ("waitpid");
413 }
414 else if (ret > 0)
415 break;
416
417 usleep (1000);
418 }
419
420 /* On the first wait, continue running the inferior until we are
421 blocked inside an spu_run system call. */
422 if (!server_waiting)
423 {
424 int fd;
425 CORE_ADDR addr;
426
427 while (!parse_spufs_run (&fd, &addr))
428 {
5472f405
UW
429 ptrace (PT_SYSCALL, pid, (PTRACE_TYPE_ARG3) 0, 0);
430 waitpid (pid, NULL, __WALL | __WNOTHREAD);
a13e2c95
UW
431 }
432 }
433
a13e2c95
UW
434 if (WIFEXITED (w))
435 {
436 fprintf (stderr, "\nChild exited with retcode = %x \n", WEXITSTATUS (w));
5b1c542e
PA
437 ourstatus->kind = TARGET_WAITKIND_EXITED;
438 ourstatus->value.integer = WEXITSTATUS (w);
a13e2c95 439 clear_inferiors ();
5472f405 440 remove_process (find_process_pid (ret));
95954743 441 return pid_to_ptid (ret);
a13e2c95
UW
442 }
443 else if (!WIFSTOPPED (w))
444 {
445 fprintf (stderr, "\nChild terminated with signal = %x \n", WTERMSIG (w));
5b1c542e
PA
446 ourstatus->kind = TARGET_WAITKIND_SIGNALLED;
447 ourstatus->value.sig = target_signal_from_host (WTERMSIG (w));
a13e2c95 448 clear_inferiors ();
5472f405 449 remove_process (find_process_pid (ret));
95954743 450 return pid_to_ptid (ret);
a13e2c95
UW
451 }
452
453 /* After attach, we may have received a SIGSTOP. Do not return this
454 as signal to GDB, or else it will try to continue with SIGSTOP ... */
455 if (!server_waiting)
456 {
5b1c542e
PA
457 ourstatus->kind = TARGET_WAITKIND_STOPPED;
458 ourstatus->value.sig = TARGET_SIGNAL_0;
95954743 459 return ptid_build (ret, ret, 0);
a13e2c95
UW
460 }
461
5b1c542e
PA
462 ourstatus->kind = TARGET_WAITKIND_STOPPED;
463 ourstatus->value.sig = target_signal_from_host (WSTOPSIG (w));
95954743 464 return ptid_build (ret, ret, 0);
a13e2c95
UW
465}
466
467/* Fetch inferior registers. */
468static void
469spu_fetch_registers (int regno)
470{
471 int fd;
472 CORE_ADDR addr;
473
474 /* ??? Some callers use 0 to mean all registers. */
475 if (regno == 0)
476 regno = -1;
477
478 /* We must be stopped on a spu_run system call. */
479 if (!parse_spufs_run (&fd, &addr))
480 return;
481
482 /* The ID register holds the spufs file handle. */
483 if (regno == -1 || regno == SPU_ID_REGNUM)
484 supply_register (SPU_ID_REGNUM, (char *)&fd);
485
486 /* The NPC register is found at ADDR. */
487 if (regno == -1 || regno == SPU_PC_REGNUM)
488 {
489 char buf[4];
490 if (fetch_ppc_memory (addr, buf, 4) == 0)
491 supply_register (SPU_PC_REGNUM, buf);
492 }
493
494 /* The GPRs are found in the "regs" spufs file. */
495 if (regno == -1 || (regno >= 0 && regno < SPU_NUM_CORE_REGS))
496 {
497 unsigned char buf[16*SPU_NUM_CORE_REGS];
498 char annex[32];
499 int i;
500
501 sprintf (annex, "%d/regs", fd);
502 if (spu_proc_xfer_spu (annex, buf, NULL, 0, sizeof buf) == sizeof buf)
503 for (i = 0; i < SPU_NUM_CORE_REGS; i++)
504 supply_register (i, buf + i*16);
505 }
506}
507
508/* Store inferior registers. */
509static void
510spu_store_registers (int regno)
511{
512 int fd;
513 CORE_ADDR addr;
514
515 /* ??? Some callers use 0 to mean all registers. */
516 if (regno == 0)
517 regno = -1;
518
519 /* We must be stopped on a spu_run system call. */
520 if (!parse_spufs_run (&fd, &addr))
521 return;
522
523 /* The NPC register is found at ADDR. */
524 if (regno == -1 || regno == SPU_PC_REGNUM)
525 {
526 char buf[4];
527 collect_register (SPU_PC_REGNUM, buf);
528 store_ppc_memory (addr, buf, 4);
529 }
530
531 /* The GPRs are found in the "regs" spufs file. */
532 if (regno == -1 || (regno >= 0 && regno < SPU_NUM_CORE_REGS))
533 {
534 unsigned char buf[16*SPU_NUM_CORE_REGS];
535 char annex[32];
536 int i;
537
538 for (i = 0; i < SPU_NUM_CORE_REGS; i++)
539 collect_register (i, buf + i*16);
540
541 sprintf (annex, "%d/regs", fd);
542 spu_proc_xfer_spu (annex, NULL, buf, 0, sizeof buf);
543 }
544}
545
546/* Copy LEN bytes from inferior's memory starting at MEMADDR
547 to debugger memory starting at MYADDR. */
548static int
549spu_read_memory (CORE_ADDR memaddr, unsigned char *myaddr, int len)
550{
551 int fd, ret;
552 CORE_ADDR addr;
553 char annex[32];
554
555 /* We must be stopped on a spu_run system call. */
556 if (!parse_spufs_run (&fd, &addr))
557 return 0;
558
559 /* Use the "mem" spufs file to access SPU local store. */
560 sprintf (annex, "%d/mem", fd);
561 ret = spu_proc_xfer_spu (annex, myaddr, NULL, memaddr, len);
562 return ret == len ? 0 : EIO;
563}
564
565/* Copy LEN bytes of data from debugger memory at MYADDR
566 to inferior's memory at MEMADDR.
567 On failure (cannot write the inferior)
568 returns the value of errno. */
569static int
570spu_write_memory (CORE_ADDR memaddr, const unsigned char *myaddr, int len)
571{
572 int fd, ret;
573 CORE_ADDR addr;
574 char annex[32];
575
576 /* We must be stopped on a spu_run system call. */
577 if (!parse_spufs_run (&fd, &addr))
578 return 0;
579
580 /* Use the "mem" spufs file to access SPU local store. */
581 sprintf (annex, "%d/mem", fd);
582 ret = spu_proc_xfer_spu (annex, NULL, myaddr, memaddr, len);
583 return ret == len ? 0 : EIO;
584}
585
586/* Look up special symbols -- unneded here. */
587static void
588spu_look_up_symbols (void)
589{
590}
591
592/* Send signal to inferior. */
593static void
ef57601b 594spu_request_interrupt (void)
a13e2c95 595{
5472f405 596 syscall (SYS_tkill, ptid_get_lwp (current_ptid), SIGINT);
a13e2c95
UW
597}
598
a13e2c95
UW
599static struct target_ops spu_target_ops = {
600 spu_create_inferior,
601 spu_attach,
602 spu_kill,
603 spu_detach,
444d6139 604 spu_join,
a13e2c95
UW
605 spu_thread_alive,
606 spu_resume,
607 spu_wait,
608 spu_fetch_registers,
609 spu_store_registers,
610 spu_read_memory,
611 spu_write_memory,
612 spu_look_up_symbols,
ef57601b 613 spu_request_interrupt,
a13e2c95 614 NULL,
ab39bf24
UW
615 NULL,
616 NULL,
617 NULL,
618 NULL,
619 NULL,
620 NULL,
0e7f50da 621 spu_proc_xfer_spu,
59a016f0 622 hostio_last_error_from_errno,
a13e2c95
UW
623};
624
625void
626initialize_low (void)
627{
628 static const unsigned char breakpoint[] = { 0x00, 0x00, 0x3f, 0xff };
629
630 set_target_ops (&spu_target_ops);
631 set_breakpoint_data (breakpoint, sizeof breakpoint);
d05b4ac3 632 init_registers_spu ();
a13e2c95 633}
This page took 0.221003 seconds and 4 git commands to generate.