]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - gdb/spu-linux-nat.c
Return target_xfer_status in to_xfer_partial
[thirdparty/binutils-gdb.git] / gdb / spu-linux-nat.c
CommitLineData
771b4502 1/* SPU native-dependent code for GDB, the GNU debugger.
ecd75fc8 2 Copyright (C) 2006-2014 Free Software Foundation, Inc.
771b4502
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
771b4502
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/>. */
771b4502
UW
20
21#include "defs.h"
22#include "gdbcore.h"
0e9f083f 23#include <string.h>
771b4502
UW
24#include "target.h"
25#include "inferior.h"
dab06dbe 26#include "inf-child.h"
771b4502
UW
27#include "inf-ptrace.h"
28#include "regcache.h"
29#include "symfile.h"
30#include "gdb_wait.h"
d5b25491 31#include "gdbthread.h"
92107356 32#include "gdb_bfd.h"
771b4502
UW
33
34#include <sys/ptrace.h>
35#include <asm/ptrace.h>
36#include <sys/types.h>
771b4502
UW
37
38#include "spu-tdep.h"
39
40/* PPU side system calls. */
41#define INSTR_SC 0x44000002
42#define NR_spu_run 0x0116
43
44
45/* Fetch PPU register REGNO. */
4179a487 46static ULONGEST
771b4502
UW
47fetch_ppc_register (int regno)
48{
49 PTRACE_TYPE_RET res;
50
dfd4cc63 51 int tid = ptid_get_lwp (inferior_ptid);
771b4502 52 if (tid == 0)
dfd4cc63 53 tid = ptid_get_pid (inferior_ptid);
771b4502
UW
54
55#ifndef __powerpc64__
56 /* If running as a 32-bit process on a 64-bit system, we attempt
57 to get the full 64-bit register content of the target process.
58 If the PPC special ptrace call fails, we're on a 32-bit system;
59 just fall through to the regular ptrace call in that case. */
60 {
61 gdb_byte buf[8];
62
63 errno = 0;
64 ptrace (PPC_PTRACE_PEEKUSR_3264, tid,
65 (PTRACE_TYPE_ARG3) (regno * 8), buf);
66 if (errno == 0)
67 ptrace (PPC_PTRACE_PEEKUSR_3264, tid,
68 (PTRACE_TYPE_ARG3) (regno * 8 + 4), buf + 4);
69 if (errno == 0)
b9efddcd 70 return (ULONGEST) *(uint64_t *)buf;
771b4502
UW
71 }
72#endif
73
74 errno = 0;
75 res = ptrace (PT_READ_U, tid,
76 (PTRACE_TYPE_ARG3) (regno * sizeof (PTRACE_TYPE_RET)), 0);
77 if (errno != 0)
78 {
79 char mess[128];
80 xsnprintf (mess, sizeof mess, "reading PPC register #%d", regno);
81 perror_with_name (_(mess));
82 }
83
4179a487 84 return (ULONGEST) (unsigned long) res;
771b4502
UW
85}
86
87/* Fetch WORD from PPU memory at (aligned) MEMADDR in thread TID. */
88static int
4179a487 89fetch_ppc_memory_1 (int tid, ULONGEST memaddr, PTRACE_TYPE_RET *word)
771b4502
UW
90{
91 errno = 0;
92
93#ifndef __powerpc64__
94 if (memaddr >> 32)
95 {
b9efddcd 96 uint64_t addr_8 = (uint64_t) memaddr;
771b4502
UW
97 ptrace (PPC_PTRACE_PEEKTEXT_3264, tid, (PTRACE_TYPE_ARG3) &addr_8, word);
98 }
99 else
100#endif
101 *word = ptrace (PT_READ_I, tid, (PTRACE_TYPE_ARG3) (size_t) memaddr, 0);
102
103 return errno;
104}
105
106/* Store WORD into PPU memory at (aligned) MEMADDR in thread TID. */
107static int
4179a487 108store_ppc_memory_1 (int tid, ULONGEST memaddr, PTRACE_TYPE_RET word)
771b4502
UW
109{
110 errno = 0;
111
112#ifndef __powerpc64__
113 if (memaddr >> 32)
114 {
b9efddcd 115 uint64_t addr_8 = (uint64_t) memaddr;
771b4502
UW
116 ptrace (PPC_PTRACE_POKEDATA_3264, tid, (PTRACE_TYPE_ARG3) &addr_8, word);
117 }
118 else
119#endif
120 ptrace (PT_WRITE_D, tid, (PTRACE_TYPE_ARG3) (size_t) memaddr, word);
121
122 return errno;
123}
124
125/* Fetch LEN bytes of PPU memory at MEMADDR to MYADDR. */
126static int
4179a487 127fetch_ppc_memory (ULONGEST memaddr, gdb_byte *myaddr, int len)
771b4502
UW
128{
129 int i, ret;
130
4179a487 131 ULONGEST addr = memaddr & -(ULONGEST) sizeof (PTRACE_TYPE_RET);
771b4502
UW
132 int count = ((((memaddr + len) - addr) + sizeof (PTRACE_TYPE_RET) - 1)
133 / sizeof (PTRACE_TYPE_RET));
134 PTRACE_TYPE_RET *buffer;
135
dfd4cc63 136 int tid = ptid_get_lwp (inferior_ptid);
771b4502 137 if (tid == 0)
dfd4cc63 138 tid = ptid_get_pid (inferior_ptid);
771b4502
UW
139
140 buffer = (PTRACE_TYPE_RET *) alloca (count * sizeof (PTRACE_TYPE_RET));
141 for (i = 0; i < count; i++, addr += sizeof (PTRACE_TYPE_RET))
b9efddcd
UW
142 {
143 ret = fetch_ppc_memory_1 (tid, addr, &buffer[i]);
144 if (ret)
145 return ret;
146 }
771b4502
UW
147
148 memcpy (myaddr,
149 (char *) buffer + (memaddr & (sizeof (PTRACE_TYPE_RET) - 1)),
150 len);
151
152 return 0;
153}
154
155/* Store LEN bytes from MYADDR to PPU memory at MEMADDR. */
156static int
4179a487 157store_ppc_memory (ULONGEST memaddr, const gdb_byte *myaddr, int len)
771b4502
UW
158{
159 int i, ret;
160
4179a487 161 ULONGEST addr = memaddr & -(ULONGEST) sizeof (PTRACE_TYPE_RET);
771b4502
UW
162 int count = ((((memaddr + len) - addr) + sizeof (PTRACE_TYPE_RET) - 1)
163 / sizeof (PTRACE_TYPE_RET));
164 PTRACE_TYPE_RET *buffer;
165
dfd4cc63 166 int tid = ptid_get_lwp (inferior_ptid);
771b4502 167 if (tid == 0)
dfd4cc63 168 tid = ptid_get_pid (inferior_ptid);
771b4502
UW
169
170 buffer = (PTRACE_TYPE_RET *) alloca (count * sizeof (PTRACE_TYPE_RET));
171
172 if (addr != memaddr || len < (int) sizeof (PTRACE_TYPE_RET))
b9efddcd
UW
173 {
174 ret = fetch_ppc_memory_1 (tid, addr, &buffer[0]);
175 if (ret)
176 return ret;
177 }
771b4502
UW
178
179 if (count > 1)
b9efddcd
UW
180 {
181 ret = fetch_ppc_memory_1 (tid, addr + (count - 1)
771b4502 182 * sizeof (PTRACE_TYPE_RET),
b9efddcd
UW
183 &buffer[count - 1]);
184 if (ret)
185 return ret;
186 }
771b4502
UW
187
188 memcpy ((char *) buffer + (memaddr & (sizeof (PTRACE_TYPE_RET) - 1)),
189 myaddr, len);
190
191 for (i = 0; i < count; i++, addr += sizeof (PTRACE_TYPE_RET))
b9efddcd
UW
192 {
193 ret = store_ppc_memory_1 (tid, addr, buffer[i]);
194 if (ret)
195 return ret;
196 }
771b4502
UW
197
198 return 0;
199}
200
201
202/* If the PPU thread is currently stopped on a spu_run system call,
203 return to FD and ADDR the file handle and NPC parameter address
204 used with the system call. Return non-zero if successful. */
205static int
4179a487 206parse_spufs_run (int *fd, ULONGEST *addr)
771b4502 207{
f5656ead 208 enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch ());
771b4502 209 gdb_byte buf[4];
4179a487 210 ULONGEST pc = fetch_ppc_register (32); /* nip */
771b4502
UW
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. */
e17a4113 216 if (extract_unsigned_integer (buf, 4, byte_order) != INSTR_SC)
771b4502
UW
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. */
9b409511 231static enum target_xfer_status
771b4502
UW
232spu_proc_xfer_spu (const char *annex, gdb_byte *readbuf,
233 const gdb_byte *writebuf,
9b409511 234 ULONGEST offset, ULONGEST len, ULONGEST *xfered_len)
771b4502
UW
235{
236 char buf[128];
237 int fd = 0;
238 int ret = -1;
dfd4cc63 239 int pid = ptid_get_pid (inferior_ptid);
771b4502
UW
240
241 if (!annex)
9b409511 242 return TARGET_XFER_EOF;
771b4502
UW
243
244 xsnprintf (buf, sizeof buf, "/proc/%d/fd/%s", pid, annex);
245 fd = open (buf, writebuf? O_WRONLY : O_RDONLY);
246 if (fd <= 0)
2ed4b548 247 return TARGET_XFER_E_IO;
771b4502
UW
248
249 if (offset != 0
250 && lseek (fd, (off_t) offset, SEEK_SET) != (off_t) offset)
251 {
252 close (fd);
9b409511 253 return TARGET_XFER_EOF;
771b4502
UW
254 }
255
256 if (writebuf)
257 ret = write (fd, writebuf, (size_t) len);
258 else if (readbuf)
259 ret = read (fd, readbuf, (size_t) len);
260
261 close (fd);
9b409511
YQ
262 if (ret < 0)
263 return TARGET_XFER_E_IO;
264 else if (ret == 0)
265 return TARGET_XFER_EOF;
266 else
267 {
268 *xfered_len = (ULONGEST) ret;
269 return TARGET_XFER_OK;
270 }
771b4502
UW
271}
272
273
274/* Inferior memory should contain an SPE executable image at location ADDR.
275 Allocate a BFD representing that executable. Return NULL on error. */
276
277static void *
278spu_bfd_iovec_open (struct bfd *nbfd, void *open_closure)
279{
280 return open_closure;
281}
282
283static int
284spu_bfd_iovec_close (struct bfd *nbfd, void *stream)
285{
286 xfree (stream);
39ed5604
JK
287
288 /* Zero means success. */
289 return 0;
771b4502
UW
290}
291
292static file_ptr
293spu_bfd_iovec_pread (struct bfd *abfd, void *stream, void *buf,
294 file_ptr nbytes, file_ptr offset)
295{
4179a487 296 ULONGEST addr = *(ULONGEST *)stream;
771b4502
UW
297
298 if (fetch_ppc_memory (addr + offset, buf, nbytes) != 0)
299 {
300 bfd_set_error (bfd_error_invalid_operation);
301 return -1;
302 }
303
304 return nbytes;
305}
306
f6cf9273
AM
307static int
308spu_bfd_iovec_stat (struct bfd *abfd, void *stream, struct stat *sb)
309{
310 /* We don't have an easy way of finding the size of embedded spu
311 images. We could parse the in-memory ELF header and section
312 table to find the extent of the last section but that seems
313 pointless when the size is needed only for checks of other
314 parsed values in dbxread.c. */
315 sb->st_size = INT_MAX;
316 return 0;
317}
318
771b4502 319static bfd *
4179a487 320spu_bfd_open (ULONGEST addr)
771b4502
UW
321{
322 struct bfd *nbfd;
9592c5d0 323 asection *spu_name;
771b4502 324
4179a487 325 ULONGEST *open_closure = xmalloc (sizeof (ULONGEST));
771b4502
UW
326 *open_closure = addr;
327
64c31149
TT
328 nbfd = gdb_bfd_openr_iovec ("<in-memory>", "elf32-spu",
329 spu_bfd_iovec_open, open_closure,
330 spu_bfd_iovec_pread, spu_bfd_iovec_close,
331 spu_bfd_iovec_stat);
771b4502
UW
332 if (!nbfd)
333 return NULL;
334
335 if (!bfd_check_format (nbfd, bfd_object))
336 {
cbb099e8 337 gdb_bfd_unref (nbfd);
771b4502
UW
338 return NULL;
339 }
340
9592c5d0
UW
341 /* Retrieve SPU name note and update BFD name. */
342 spu_name = bfd_get_section_by_name (nbfd, ".note.spu_name");
343 if (spu_name)
344 {
345 int sect_size = bfd_section_size (nbfd, spu_name);
346 if (sect_size > 20)
347 {
348 char *buf = alloca (sect_size - 20 + 1);
349 bfd_get_section_contents (nbfd, spu_name, buf, 20, sect_size - 20);
350 buf[sect_size - 20] = '\0';
351
352 xfree ((char *)nbfd->filename);
353 nbfd->filename = xstrdup (buf);
354 }
355 }
356
771b4502
UW
357 return nbfd;
358}
359
360/* INFERIOR_FD is a file handle passed by the inferior to the
361 spu_run system call. Assuming the SPE context was allocated
362 by the libspe library, try to retrieve the main SPE executable
363 file from its copy within the target process. */
364static void
365spu_symbol_file_add_from_memory (int inferior_fd)
366{
4179a487 367 ULONGEST addr;
771b4502
UW
368 struct bfd *nbfd;
369
22c90ac1 370 gdb_byte id[128];
771b4502 371 char annex[32];
9b409511
YQ
372 ULONGEST len;
373 enum target_xfer_status status;
771b4502
UW
374
375 /* Read object ID. */
376 xsnprintf (annex, sizeof annex, "%d/object-id", inferior_fd);
9b409511
YQ
377 status = spu_proc_xfer_spu (annex, id, NULL, 0, sizeof id, &len);
378 if (status != TARGET_XFER_OK || len >= sizeof id)
771b4502
UW
379 return;
380 id[len] = 0;
22c90ac1 381 addr = strtoulst ((const char *) id, NULL, 16);
b9efddcd 382 if (!addr)
771b4502
UW
383 return;
384
385 /* Open BFD representing SPE executable and read its symbols. */
386 nbfd = spu_bfd_open (addr);
387 if (nbfd)
8ac244b4
TT
388 {
389 struct cleanup *cleanup = make_cleanup_bfd_unref (nbfd);
390
d64ad97c
YQ
391 symbol_file_add_from_bfd (nbfd, bfd_get_filename (nbfd),
392 SYMFILE_VERBOSE | SYMFILE_MAINLINE,
8ac244b4
TT
393 NULL, 0, NULL);
394 do_cleanups (cleanup);
395 }
771b4502
UW
396}
397
398
399/* Override the post_startup_inferior routine to continue running
400 the inferior until the first spu_run system call. */
401static void
402spu_child_post_startup_inferior (ptid_t ptid)
403{
404 int fd;
4179a487 405 ULONGEST addr;
771b4502 406
dfd4cc63 407 int tid = ptid_get_lwp (ptid);
771b4502 408 if (tid == 0)
dfd4cc63 409 tid = ptid_get_pid (ptid);
771b4502
UW
410
411 while (!parse_spufs_run (&fd, &addr))
412 {
413 ptrace (PT_SYSCALL, tid, (PTRACE_TYPE_ARG3) 0, 0);
414 waitpid (tid, NULL, __WALL | __WNOTHREAD);
415 }
416}
417
418/* Override the post_attach routine to try load the SPE executable
419 file image from its copy inside the target process. */
420static void
421spu_child_post_attach (int pid)
422{
423 int fd;
4179a487 424 ULONGEST addr;
771b4502
UW
425
426 /* Like child_post_startup_inferior, if we happened to attach to
427 the inferior while it wasn't currently in spu_run, continue
428 running it until we get back there. */
429 while (!parse_spufs_run (&fd, &addr))
430 {
431 ptrace (PT_SYSCALL, pid, (PTRACE_TYPE_ARG3) 0, 0);
432 waitpid (pid, NULL, __WALL | __WNOTHREAD);
433 }
434
435 /* If the user has not provided an executable file, try to extract
436 the image from inside the target process. */
437 if (!get_exec_file (0))
438 spu_symbol_file_add_from_memory (fd);
439}
440
441/* Wait for child PTID to do something. Return id of the child,
442 minus_one_ptid in case of error; store status into *OURSTATUS. */
443static ptid_t
117de6a9 444spu_child_wait (struct target_ops *ops,
47608cb1 445 ptid_t ptid, struct target_waitstatus *ourstatus, int options)
771b4502
UW
446{
447 int save_errno;
448 int status;
449 pid_t pid;
450
451 do
452 {
453 set_sigint_trap (); /* Causes SIGINT to be passed on to the
454 attached process. */
771b4502 455
dfd4cc63 456 pid = waitpid (ptid_get_pid (ptid), &status, 0);
771b4502
UW
457 if (pid == -1 && errno == ECHILD)
458 /* Try again with __WCLONE to check cloned processes. */
dfd4cc63 459 pid = waitpid (ptid_get_pid (ptid), &status, __WCLONE);
771b4502
UW
460
461 save_errno = errno;
462
463 /* Make sure we don't report an event for the exit of the
464 original program, if we've detached from it. */
dfd4cc63
LM
465 if (pid != -1 && !WIFSTOPPED (status)
466 && pid != ptid_get_pid (inferior_ptid))
771b4502
UW
467 {
468 pid = -1;
469 save_errno = EINTR;
470 }
471
771b4502
UW
472 clear_sigint_trap ();
473 }
474 while (pid == -1 && save_errno == EINTR);
475
476 if (pid == -1)
477 {
b9efddcd 478 warning (_("Child process unexpectedly missing: %s"),
771b4502
UW
479 safe_strerror (save_errno));
480
481 /* Claim it exited with unknown signal. */
482 ourstatus->kind = TARGET_WAITKIND_SIGNALLED;
a493e3e2 483 ourstatus->value.sig = GDB_SIGNAL_UNKNOWN;
fb66883a 484 return inferior_ptid;
771b4502
UW
485 }
486
487 store_waitstatus (ourstatus, status);
488 return pid_to_ptid (pid);
489}
490
491/* Override the fetch_inferior_register routine. */
492static void
28439f5e
PA
493spu_fetch_inferior_registers (struct target_ops *ops,
494 struct regcache *regcache, int regno)
771b4502
UW
495{
496 int fd;
4179a487 497 ULONGEST addr;
771b4502
UW
498
499 /* We must be stopped on a spu_run system call. */
500 if (!parse_spufs_run (&fd, &addr))
501 return;
502
503 /* The ID register holds the spufs file handle. */
504 if (regno == -1 || regno == SPU_ID_REGNUM)
505 {
e17a4113
UW
506 struct gdbarch *gdbarch = get_regcache_arch (regcache);
507 enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
e362b510 508 gdb_byte buf[4];
e17a4113 509 store_unsigned_integer (buf, 4, byte_order, fd);
56be3814 510 regcache_raw_supply (regcache, SPU_ID_REGNUM, buf);
771b4502
UW
511 }
512
513 /* The NPC register is found at ADDR. */
514 if (regno == -1 || regno == SPU_PC_REGNUM)
515 {
516 gdb_byte buf[4];
517 if (fetch_ppc_memory (addr, buf, 4) == 0)
56be3814 518 regcache_raw_supply (regcache, SPU_PC_REGNUM, buf);
771b4502
UW
519 }
520
521 /* The GPRs are found in the "regs" spufs file. */
522 if (regno == -1 || (regno >= 0 && regno < SPU_NUM_GPRS))
523 {
524 gdb_byte buf[16 * SPU_NUM_GPRS];
525 char annex[32];
526 int i;
9b409511 527 ULONGEST len;
771b4502
UW
528
529 xsnprintf (annex, sizeof annex, "%d/regs", fd);
9b409511
YQ
530 if ((spu_proc_xfer_spu (annex, buf, NULL, 0, sizeof buf, &len)
531 == TARGET_XFER_OK)
532 && len == sizeof buf)
771b4502 533 for (i = 0; i < SPU_NUM_GPRS; i++)
56be3814 534 regcache_raw_supply (regcache, i, buf + i*16);
771b4502
UW
535 }
536}
537
538/* Override the store_inferior_register routine. */
539static void
28439f5e
PA
540spu_store_inferior_registers (struct target_ops *ops,
541 struct regcache *regcache, int regno)
771b4502
UW
542{
543 int fd;
4179a487 544 ULONGEST addr;
771b4502
UW
545
546 /* We must be stopped on a spu_run system call. */
547 if (!parse_spufs_run (&fd, &addr))
548 return;
549
550 /* The NPC register is found at ADDR. */
551 if (regno == -1 || regno == SPU_PC_REGNUM)
552 {
553 gdb_byte buf[4];
56be3814 554 regcache_raw_collect (regcache, SPU_PC_REGNUM, buf);
771b4502
UW
555 store_ppc_memory (addr, buf, 4);
556 }
557
558 /* The GPRs are found in the "regs" spufs file. */
559 if (regno == -1 || (regno >= 0 && regno < SPU_NUM_GPRS))
560 {
561 gdb_byte buf[16 * SPU_NUM_GPRS];
562 char annex[32];
563 int i;
9b409511 564 ULONGEST len;
771b4502
UW
565
566 for (i = 0; i < SPU_NUM_GPRS; i++)
56be3814 567 regcache_raw_collect (regcache, i, buf + i*16);
771b4502
UW
568
569 xsnprintf (annex, sizeof annex, "%d/regs", fd);
9b409511 570 spu_proc_xfer_spu (annex, NULL, buf, 0, sizeof buf, &len);
771b4502
UW
571 }
572}
573
574/* Override the to_xfer_partial routine. */
9b409511 575static enum target_xfer_status
771b4502
UW
576spu_xfer_partial (struct target_ops *ops,
577 enum target_object object, const char *annex,
578 gdb_byte *readbuf, const gdb_byte *writebuf,
9b409511 579 ULONGEST offset, ULONGEST len, ULONGEST *xfered_len)
771b4502 580{
23d964e7 581 if (object == TARGET_OBJECT_SPU)
9b409511
YQ
582 return spu_proc_xfer_spu (annex, readbuf, writebuf, offset, len,
583 xfered_len);
23d964e7 584
771b4502
UW
585 if (object == TARGET_OBJECT_MEMORY)
586 {
587 int fd;
4179a487 588 ULONGEST addr;
d2ed6730
UW
589 char mem_annex[32], lslr_annex[32];
590 gdb_byte buf[32];
591 ULONGEST lslr;
9b409511 592 enum target_xfer_status ret;
771b4502
UW
593
594 /* We must be stopped on a spu_run system call. */
595 if (!parse_spufs_run (&fd, &addr))
9b409511 596 return TARGET_XFER_EOF;
771b4502
UW
597
598 /* Use the "mem" spufs file to access SPU local store. */
599 xsnprintf (mem_annex, sizeof mem_annex, "%d/mem", fd);
9b409511
YQ
600 ret = spu_proc_xfer_spu (mem_annex, readbuf, writebuf, offset, len,
601 xfered_len);
602 if (ret == TARGET_XFER_OK)
d2ed6730
UW
603 return ret;
604
605 /* SPU local store access wraps the address around at the
606 local store limit. We emulate this here. To avoid needing
607 an extra access to retrieve the LSLR, we only do that after
608 trying the original address first, and getting end-of-file. */
609 xsnprintf (lslr_annex, sizeof lslr_annex, "%d/lslr", fd);
610 memset (buf, 0, sizeof buf);
9b409511
YQ
611 if (spu_proc_xfer_spu (lslr_annex, buf, NULL, 0, sizeof buf, xfered_len)
612 != TARGET_XFER_OK)
d2ed6730
UW
613 return ret;
614
22c90ac1 615 lslr = strtoulst ((const char *) buf, NULL, 16);
d2ed6730 616 return spu_proc_xfer_spu (mem_annex, readbuf, writebuf,
9b409511 617 offset & lslr, len, xfered_len);
771b4502
UW
618 }
619
2ed4b548 620 return TARGET_XFER_E_IO;
771b4502
UW
621}
622
623/* Override the to_can_use_hw_breakpoint routine. */
624static int
625spu_can_use_hw_breakpoint (int type, int cnt, int othertype)
626{
627 return 0;
628}
629
bd1f7788
YQ
630/* -Wmissing-prototypes */
631extern initialize_file_ftype _initialize_spu_nat;
771b4502
UW
632
633/* Initialize SPU native target. */
634void
635_initialize_spu_nat (void)
636{
637 /* Generic ptrace methods. */
638 struct target_ops *t;
639 t = inf_ptrace_target ();
640
641 /* Add SPU methods. */
642 t->to_post_attach = spu_child_post_attach;
643 t->to_post_startup_inferior = spu_child_post_startup_inferior;
644 t->to_wait = spu_child_wait;
645 t->to_fetch_registers = spu_fetch_inferior_registers;
646 t->to_store_registers = spu_store_inferior_registers;
647 t->to_xfer_partial = spu_xfer_partial;
648 t->to_can_use_hw_breakpoint = spu_can_use_hw_breakpoint;
649
650 /* Register SPU target. */
651 add_target (t);
652}