]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blob - gdb/gdbserver/spu-low.c
update copyright year range in GDB files
[thirdparty/binutils-gdb.git] / gdb / gdbserver / spu-low.c
1 /* Low level interface to SPUs, for the remote server for GDB.
2 Copyright (C) 2006-2017 Free Software Foundation, Inc.
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
10 the Free Software Foundation; either version 3 of the License, or
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
19 along with this program. If not, see <http://www.gnu.org/licenses/>. */
20
21 #include "server.h"
22
23 #include "gdb_wait.h"
24 #include <sys/ptrace.h>
25 #include <fcntl.h>
26 #include <unistd.h>
27 #include <sys/syscall.h>
28 #include "filestuff.h"
29 #include "hostio.h"
30
31 /* Some older glibc versions do not define this. */
32 #ifndef __WNOTHREAD
33 #define __WNOTHREAD 0x20000000 /* Don't wait on children of other
34 threads in this group */
35 #endif
36
37 #define PTRACE_TYPE_RET long
38 #define PTRACE_TYPE_ARG3 long
39
40 /* Number of registers. */
41 #define SPU_NUM_REGS 130
42 #define SPU_NUM_CORE_REGS 128
43
44 /* Special registers. */
45 #define SPU_ID_REGNUM 128
46 #define SPU_PC_REGNUM 129
47
48 /* PPU side system calls. */
49 #define INSTR_SC 0x44000002
50 #define NR_spu_run 0x0116
51
52 /* These are used in remote-utils.c. */
53 int using_threads = 0;
54
55 /* Defined in auto-generated file reg-spu.c. */
56 void init_registers_spu (void);
57 extern const struct target_desc *tdesc_spu;
58
59 /* Software breakpoint instruction. */
60 static const gdb_byte breakpoint[] = { 0x00, 0x00, 0x3f, 0xff };
61
62 /* Fetch PPU register REGNO. */
63 static CORE_ADDR
64 fetch_ppc_register (int regno)
65 {
66 PTRACE_TYPE_RET res;
67
68 int tid = ptid_get_lwp (current_ptid);
69
70 #ifndef __powerpc64__
71 /* If running as a 32-bit process on a 64-bit system, we attempt
72 to get the full 64-bit register content of the target process.
73 If the PPC special ptrace call fails, we're on a 32-bit system;
74 just fall through to the regular ptrace call in that case. */
75 {
76 char buf[8];
77
78 errno = 0;
79 ptrace ((PTRACE_TYPE_ARG1) PPC_PTRACE_PEEKUSR_3264, tid,
80 (PTRACE_TYPE_ARG3) (regno * 8), buf);
81 if (errno == 0)
82 ptrace ((PTRACE_TYPE_ARG1) PPC_PTRACE_PEEKUSR_3264, tid,
83 (PTRACE_TYPE_ARG3) (regno * 8 + 4), buf + 4);
84 if (errno == 0)
85 return (CORE_ADDR) *(unsigned long long *)buf;
86 }
87 #endif
88
89 errno = 0;
90 res = ptrace (PT_READ_U, tid,
91 (PTRACE_TYPE_ARG3) (regno * sizeof (PTRACE_TYPE_RET)), 0);
92 if (errno != 0)
93 {
94 char mess[128];
95 sprintf (mess, "reading PPC register #%d", regno);
96 perror_with_name (mess);
97 }
98
99 return (CORE_ADDR) (unsigned long) res;
100 }
101
102 /* Fetch WORD from PPU memory at (aligned) MEMADDR in thread TID. */
103 static int
104 fetch_ppc_memory_1 (int tid, CORE_ADDR memaddr, PTRACE_TYPE_RET *word)
105 {
106 errno = 0;
107
108 #ifndef __powerpc64__
109 if (memaddr >> 32)
110 {
111 unsigned long long addr_8 = (unsigned long long) memaddr;
112 ptrace ((PTRACE_TYPE_ARG1) PPC_PTRACE_PEEKTEXT_3264, tid,
113 (PTRACE_TYPE_ARG3) &addr_8, word);
114 }
115 else
116 #endif
117 *word = ptrace (PT_READ_I, tid, (PTRACE_TYPE_ARG3) (size_t) memaddr, 0);
118
119 return errno;
120 }
121
122 /* Store WORD into PPU memory at (aligned) MEMADDR in thread TID. */
123 static int
124 store_ppc_memory_1 (int tid, CORE_ADDR memaddr, PTRACE_TYPE_RET word)
125 {
126 errno = 0;
127
128 #ifndef __powerpc64__
129 if (memaddr >> 32)
130 {
131 unsigned long long addr_8 = (unsigned long long) memaddr;
132 ptrace ((PTRACE_TYPE_ARG1) PPC_PTRACE_POKEDATA_3264, tid,
133 (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. */
143 static int
144 fetch_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 = ptid_get_lwp (current_ptid);
154
155 buffer = XALLOCAVEC (PTRACE_TYPE_RET, count);
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. */
168 static int
169 store_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 = ptid_get_lwp (current_ptid);
179
180 buffer = XALLOCAVEC (PTRACE_TYPE_RET, count);
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)),
193 myaddr, len);
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. */
206 static int
207 parse_spufs_run (int *fd, CORE_ADDR *addr)
208 {
209 unsigned int insn;
210 CORE_ADDR pc = fetch_ppc_register (32); /* nip */
211
212 /* Fetch instruction preceding current NIP. */
213 if (fetch_ppc_memory (pc-4, (char *) &insn, 4) != 0)
214 return 0;
215 /* It should be a "sc" instruction. */
216 if (insn != 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. */
231 static int
232 spu_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", ptid_get_lwp (current_ptid), 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);
252 return 0;
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. */
267 static int
268 spu_create_inferior (char *program, char **allargs)
269 {
270 int pid;
271 ptid_t ptid;
272 struct process_info *proc;
273
274 pid = fork ();
275 if (pid < 0)
276 perror_with_name ("fork");
277
278 if (pid == 0)
279 {
280 close_most_fds ();
281 ptrace (PTRACE_TRACEME, 0, 0, 0);
282
283 setpgid (0, 0);
284
285 execv (program, allargs);
286 if (errno == ENOENT)
287 execvp (program, allargs);
288
289 fprintf (stderr, "Cannot exec %s: %s.\n", program,
290 strerror (errno));
291 fflush (stderr);
292 _exit (0177);
293 }
294
295 proc = add_process (pid, 0);
296 proc->tdesc = tdesc_spu;
297
298 ptid = ptid_build (pid, pid, 0);
299 add_thread (ptid, NULL);
300 return pid;
301 }
302
303 /* Attach to an inferior process. */
304 int
305 spu_attach (unsigned long pid)
306 {
307 ptid_t ptid;
308 struct process_info *proc;
309
310 if (ptrace (PTRACE_ATTACH, pid, 0, 0) != 0)
311 {
312 fprintf (stderr, "Cannot attach to process %ld: %s (%d)\n", pid,
313 strerror (errno), errno);
314 fflush (stderr);
315 _exit (0177);
316 }
317
318 proc = add_process (pid, 1);
319 proc->tdesc = tdesc_spu;
320 ptid = ptid_build (pid, pid, 0);
321 add_thread (ptid, NULL);
322 return 0;
323 }
324
325 /* Kill the inferior process. */
326 static int
327 spu_kill (int pid)
328 {
329 int status, ret;
330 struct process_info *process = find_process_pid (pid);
331 if (process == NULL)
332 return -1;
333
334 ptrace (PTRACE_KILL, pid, 0, 0);
335
336 do {
337 ret = waitpid (pid, &status, 0);
338 if (WIFEXITED (status) || WIFSIGNALED (status))
339 break;
340 } while (ret != -1 || errno != ECHILD);
341
342 clear_inferiors ();
343 remove_process (process);
344 return 0;
345 }
346
347 /* Detach from inferior process. */
348 static int
349 spu_detach (int pid)
350 {
351 struct process_info *process = find_process_pid (pid);
352 if (process == NULL)
353 return -1;
354
355 ptrace (PTRACE_DETACH, pid, 0, 0);
356
357 clear_inferiors ();
358 remove_process (process);
359 return 0;
360 }
361
362 static void
363 spu_mourn (struct process_info *process)
364 {
365 remove_process (process);
366 }
367
368 static void
369 spu_join (int pid)
370 {
371 int status, ret;
372
373 do {
374 ret = waitpid (pid, &status, 0);
375 if (WIFEXITED (status) || WIFSIGNALED (status))
376 break;
377 } while (ret != -1 || errno != ECHILD);
378 }
379
380 /* Return nonzero if the given thread is still alive. */
381 static int
382 spu_thread_alive (ptid_t ptid)
383 {
384 return ptid_equal (ptid, current_ptid);
385 }
386
387 /* Resume process. */
388 static void
389 spu_resume (struct thread_resume *resume_info, size_t n)
390 {
391 struct thread_info *thr = get_first_thread ();
392 size_t i;
393
394 for (i = 0; i < n; i++)
395 if (ptid_equal (resume_info[i].thread, minus_one_ptid)
396 || ptid_equal (resume_info[i].thread, ptid_of (thr)))
397 break;
398
399 if (i == n)
400 return;
401
402 /* We don't support hardware single-stepping right now, assume
403 GDB knows to use software single-stepping. */
404 if (resume_info[i].kind == resume_step)
405 fprintf (stderr, "Hardware single-step not supported.\n");
406
407 regcache_invalidate ();
408
409 errno = 0;
410 ptrace (PTRACE_CONT, ptid_get_lwp (ptid_of (thr)), 0, resume_info[i].sig);
411 if (errno)
412 perror_with_name ("ptrace");
413 }
414
415 /* Wait for process, returns status. */
416 static ptid_t
417 spu_wait (ptid_t ptid, struct target_waitstatus *ourstatus, int options)
418 {
419 int pid = ptid_get_pid (ptid);
420 int w;
421 int ret;
422
423 while (1)
424 {
425 ret = waitpid (pid, &w, WNOHANG | __WALL | __WNOTHREAD);
426
427 if (ret == -1)
428 {
429 if (errno != ECHILD)
430 perror_with_name ("waitpid");
431 }
432 else if (ret > 0)
433 break;
434
435 usleep (1000);
436 }
437
438 /* On the first wait, continue running the inferior until we are
439 blocked inside an spu_run system call. */
440 if (!server_waiting)
441 {
442 int fd;
443 CORE_ADDR addr;
444
445 while (!parse_spufs_run (&fd, &addr))
446 {
447 ptrace (PT_SYSCALL, pid, (PTRACE_TYPE_ARG3) 0, 0);
448 waitpid (pid, NULL, __WALL | __WNOTHREAD);
449 }
450 }
451
452 if (WIFEXITED (w))
453 {
454 fprintf (stderr, "\nChild exited with retcode = %x \n", WEXITSTATUS (w));
455 ourstatus->kind = TARGET_WAITKIND_EXITED;
456 ourstatus->value.integer = WEXITSTATUS (w);
457 clear_inferiors ();
458 return pid_to_ptid (ret);
459 }
460 else if (!WIFSTOPPED (w))
461 {
462 fprintf (stderr, "\nChild terminated with signal = %x \n", WTERMSIG (w));
463 ourstatus->kind = TARGET_WAITKIND_SIGNALLED;
464 ourstatus->value.sig = gdb_signal_from_host (WTERMSIG (w));
465 clear_inferiors ();
466 return pid_to_ptid (ret);
467 }
468
469 /* After attach, we may have received a SIGSTOP. Do not return this
470 as signal to GDB, or else it will try to continue with SIGSTOP ... */
471 if (!server_waiting)
472 {
473 ourstatus->kind = TARGET_WAITKIND_STOPPED;
474 ourstatus->value.sig = GDB_SIGNAL_0;
475 return ptid_build (ret, ret, 0);
476 }
477
478 ourstatus->kind = TARGET_WAITKIND_STOPPED;
479 ourstatus->value.sig = gdb_signal_from_host (WSTOPSIG (w));
480 return ptid_build (ret, ret, 0);
481 }
482
483 /* Fetch inferior registers. */
484 static void
485 spu_fetch_registers (struct regcache *regcache, int regno)
486 {
487 int fd;
488 CORE_ADDR addr;
489
490 /* We must be stopped on a spu_run system call. */
491 if (!parse_spufs_run (&fd, &addr))
492 return;
493
494 /* The ID register holds the spufs file handle. */
495 if (regno == -1 || regno == SPU_ID_REGNUM)
496 supply_register (regcache, SPU_ID_REGNUM, (char *)&fd);
497
498 /* The NPC register is found at ADDR. */
499 if (regno == -1 || regno == SPU_PC_REGNUM)
500 {
501 char buf[4];
502 if (fetch_ppc_memory (addr, buf, 4) == 0)
503 supply_register (regcache, SPU_PC_REGNUM, buf);
504 }
505
506 /* The GPRs are found in the "regs" spufs file. */
507 if (regno == -1 || (regno >= 0 && regno < SPU_NUM_CORE_REGS))
508 {
509 unsigned char buf[16*SPU_NUM_CORE_REGS];
510 char annex[32];
511 int i;
512
513 sprintf (annex, "%d/regs", fd);
514 if (spu_proc_xfer_spu (annex, buf, NULL, 0, sizeof buf) == sizeof buf)
515 for (i = 0; i < SPU_NUM_CORE_REGS; i++)
516 supply_register (regcache, i, buf + i*16);
517 }
518 }
519
520 /* Store inferior registers. */
521 static void
522 spu_store_registers (struct regcache *regcache, int regno)
523 {
524 int fd;
525 CORE_ADDR addr;
526
527 /* ??? Some callers use 0 to mean all registers. */
528 if (regno == 0)
529 regno = -1;
530
531 /* We must be stopped on a spu_run system call. */
532 if (!parse_spufs_run (&fd, &addr))
533 return;
534
535 /* The NPC register is found at ADDR. */
536 if (regno == -1 || regno == SPU_PC_REGNUM)
537 {
538 char buf[4];
539 collect_register (regcache, SPU_PC_REGNUM, buf);
540 store_ppc_memory (addr, buf, 4);
541 }
542
543 /* The GPRs are found in the "regs" spufs file. */
544 if (regno == -1 || (regno >= 0 && regno < SPU_NUM_CORE_REGS))
545 {
546 unsigned char buf[16*SPU_NUM_CORE_REGS];
547 char annex[32];
548 int i;
549
550 for (i = 0; i < SPU_NUM_CORE_REGS; i++)
551 collect_register (regcache, i, buf + i*16);
552
553 sprintf (annex, "%d/regs", fd);
554 spu_proc_xfer_spu (annex, NULL, buf, 0, sizeof buf);
555 }
556 }
557
558 /* Copy LEN bytes from inferior's memory starting at MEMADDR
559 to debugger memory starting at MYADDR. */
560 static int
561 spu_read_memory (CORE_ADDR memaddr, unsigned char *myaddr, int len)
562 {
563 int fd, ret;
564 CORE_ADDR addr;
565 char annex[32], lslr_annex[32], buf[32];
566 CORE_ADDR lslr;
567
568 /* We must be stopped on a spu_run system call. */
569 if (!parse_spufs_run (&fd, &addr))
570 return 0;
571
572 /* Use the "mem" spufs file to access SPU local store. */
573 sprintf (annex, "%d/mem", fd);
574 ret = spu_proc_xfer_spu (annex, myaddr, NULL, memaddr, len);
575 if (ret > 0)
576 return ret == len ? 0 : EIO;
577
578 /* SPU local store access wraps the address around at the
579 local store limit. We emulate this here. To avoid needing
580 an extra access to retrieve the LSLR, we only do that after
581 trying the original address first, and getting end-of-file. */
582 sprintf (lslr_annex, "%d/lslr", fd);
583 memset (buf, 0, sizeof buf);
584 if (spu_proc_xfer_spu (lslr_annex, (unsigned char *)buf, NULL,
585 0, sizeof buf) <= 0)
586 return ret;
587
588 lslr = strtoul (buf, NULL, 16);
589 ret = spu_proc_xfer_spu (annex, myaddr, NULL, memaddr & lslr, len);
590
591 return ret == len ? 0 : EIO;
592 }
593
594 /* Copy LEN bytes of data from debugger memory at MYADDR
595 to inferior's memory at MEMADDR.
596 On failure (cannot write the inferior)
597 returns the value of errno. */
598 static int
599 spu_write_memory (CORE_ADDR memaddr, const unsigned char *myaddr, int len)
600 {
601 int fd, ret;
602 CORE_ADDR addr;
603 char annex[32], lslr_annex[32], buf[32];
604 CORE_ADDR lslr;
605
606 /* We must be stopped on a spu_run system call. */
607 if (!parse_spufs_run (&fd, &addr))
608 return 0;
609
610 /* Use the "mem" spufs file to access SPU local store. */
611 sprintf (annex, "%d/mem", fd);
612 ret = spu_proc_xfer_spu (annex, NULL, myaddr, memaddr, len);
613 if (ret > 0)
614 return ret == len ? 0 : EIO;
615
616 /* SPU local store access wraps the address around at the
617 local store limit. We emulate this here. To avoid needing
618 an extra access to retrieve the LSLR, we only do that after
619 trying the original address first, and getting end-of-file. */
620 sprintf (lslr_annex, "%d/lslr", fd);
621 memset (buf, 0, sizeof buf);
622 if (spu_proc_xfer_spu (lslr_annex, (unsigned char *)buf, NULL,
623 0, sizeof buf) <= 0)
624 return ret;
625
626 lslr = strtoul (buf, NULL, 16);
627 ret = spu_proc_xfer_spu (annex, NULL, myaddr, memaddr & lslr, len);
628
629 return ret == len ? 0 : EIO;
630 }
631
632 /* Look up special symbols -- unneded here. */
633 static void
634 spu_look_up_symbols (void)
635 {
636 }
637
638 /* Send signal to inferior. */
639 static void
640 spu_request_interrupt (void)
641 {
642 struct thread_info *thr = get_first_thread ();
643
644 syscall (SYS_tkill, lwpid_of (thr), SIGINT);
645 }
646
647 /* Implementation of the target_ops method "sw_breakpoint_from_kind". */
648
649 static const gdb_byte *
650 spu_sw_breakpoint_from_kind (int kind, int *size)
651 {
652 *size = sizeof breakpoint;
653 return breakpoint;
654 }
655
656 static struct target_ops spu_target_ops = {
657 spu_create_inferior,
658 NULL, /* post_create_inferior */
659 spu_attach,
660 spu_kill,
661 spu_detach,
662 spu_mourn,
663 spu_join,
664 spu_thread_alive,
665 spu_resume,
666 spu_wait,
667 spu_fetch_registers,
668 spu_store_registers,
669 NULL, /* prepare_to_access_memory */
670 NULL, /* done_accessing_memory */
671 spu_read_memory,
672 spu_write_memory,
673 spu_look_up_symbols,
674 spu_request_interrupt,
675 NULL,
676 NULL, /* supports_z_point_type */
677 NULL,
678 NULL,
679 NULL, /* stopped_by_sw_breakpoint */
680 NULL, /* supports_stopped_by_sw_breakpoint */
681 NULL, /* stopped_by_hw_breakpoint */
682 NULL, /* supports_stopped_by_hw_breakpoint */
683 NULL, /* supports_hardware_single_step */
684 NULL,
685 NULL,
686 NULL,
687 NULL,
688 spu_proc_xfer_spu,
689 hostio_last_error_from_errno,
690 NULL, /* qxfer_osdata */
691 NULL, /* qxfer_siginfo */
692 NULL, /* supports_non_stop */
693 NULL, /* async */
694 NULL, /* start_non_stop */
695 NULL, /* supports_multi_process */
696 NULL, /* supports_fork_events */
697 NULL, /* supports_vfork_events */
698 NULL, /* supports_exec_events */
699 NULL, /* handle_new_gdb_connection */
700 NULL, /* handle_monitor_command */
701 NULL, /* core_of_thread */
702 NULL, /* read_loadmap */
703 NULL, /* process_qsupported */
704 NULL, /* supports_tracepoints */
705 NULL, /* read_pc */
706 NULL, /* write_pc */
707 NULL, /* thread_stopped */
708 NULL, /* get_tib_address */
709 NULL, /* pause_all */
710 NULL, /* unpause_all */
711 NULL, /* stabilize_threads */
712 NULL, /* install_fast_tracepoint_jump_pad */
713 NULL, /* emit_ops */
714 NULL, /* supports_disable_randomization */
715 NULL, /* get_min_fast_tracepoint_insn_len */
716 NULL, /* qxfer_libraries_svr4 */
717 NULL, /* support_agent */
718 NULL, /* support_btrace */
719 NULL, /* enable_btrace */
720 NULL, /* disable_btrace */
721 NULL, /* read_btrace */
722 NULL, /* read_btrace_conf */
723 NULL, /* supports_range_stepping */
724 NULL, /* pid_to_exec_file */
725 NULL, /* multifs_open */
726 NULL, /* multifs_unlink */
727 NULL, /* multifs_readlink */
728 NULL, /* breakpoint_kind_from_pc */
729 spu_sw_breakpoint_from_kind,
730 };
731
732 void
733 initialize_low (void)
734 {
735 set_target_ops (&spu_target_ops);
736 init_registers_spu ();
737 }