1
diff -urN gdb-orig/gdb/gdbserver/linux-low.c gdb-6.6/gdb/gdbserver/linux-low.c
2
--- gdb-orig/gdb/gdbserver/linux-low.c 2006-10-17 18:02:27.000000000 +0200
3
+++ gdb-6.6/gdb/gdbserver/linux-low.c 2006-12-13 21:37:42.965524856 +0100
7
#include <sys/syscall.h>
8
+#include <sys/types.h>
13
+#define SPUFS_MAGIC 0x23c9b64e
16
#ifndef PTRACE_GETSIGINFO
17
# define PTRACE_GETSIGINFO 0x4202
18
@@ -1631,6 +1638,115 @@
23
+/* Enumerate spufs IDs for process PID. */
25
+spu_enumerate_spu_ids (long pid, unsigned char *buf, CORE_ADDR offset, int len)
31
+ struct dirent *entry;
33
+ sprintf (path, "/proc/%ld/fd", pid);
34
+ dir = opendir (path);
39
+ while ((entry = readdir (dir)) != NULL)
45
+ fd = atoi (entry->d_name);
49
+ sprintf (path, "/proc/%ld/fd/%d", pid, fd);
50
+ if (stat (path, &st) != 0)
52
+ if (!S_ISDIR (st.st_mode))
55
+ if (statfs (path, &stfs) != 0)
57
+ if (stfs.f_type != SPUFS_MAGIC)
60
+ if (pos >= offset && pos + 4 <= offset + len)
62
+ *(unsigned int *)(buf + pos - offset) = fd;
72
+/* Implements the to_xfer_partial interface for the TARGET_OBJECT_SPU
73
+ object type, using the /proc file system */
75
+linux_spu_qxfer_partial (const char *annex, unsigned char *readbuf,
76
+ unsigned const char *writebuf,
77
+ CORE_ADDR offset, int len)
83
+ if (!writebuf && !readbuf)
91
+ return spu_enumerate_spu_ids (inferior_pid, readbuf, offset, len);
94
+ sprintf (buf, "/proc/%ld/fd/%s", inferior_pid, annex);
96
+ printf ("access [%s] |offset [%lld] | len [%d]\n", buf, offset, len);
98
+ fd = open (buf, writebuf? O_WRONLY : O_RDONLY);
103
+ && lseek (fd, (off_t) offset, SEEK_SET) != (off_t) offset)
110
+ ret = write (fd, writebuf, (size_t) len);
112
+ ret = read (fd, readbuf, (size_t) len);
118
+/* Implements the to_xfer_partial interface */
120
+linux_qxfer_partial (const char *object_name, const char *annex,
121
+ unsigned char *readbuf, unsigned const char *writebuf,
122
+ CORE_ADDR offset, int len)
124
+ if (strncmp (object_name, "spu", 3) == 0)
125
+ return linux_spu_qxfer_partial
126
+ (annex, readbuf, writebuf, offset, len);
131
static struct target_ops linux_target_ops = {
132
linux_create_inferior,
134
@@ -1660,6 +1776,7 @@
138
+ linux_qxfer_partial,
142
diff -urN gdb-orig/gdb/gdbserver/linux-ppc64-low.c gdb-6.6/gdb/gdbserver/linux-ppc64-low.c
143
--- gdb-orig/gdb/gdbserver/linux-ppc64-low.c 2006-12-13 21:36:19.942498256 +0100
144
+++ gdb-6.6/gdb/gdbserver/linux-ppc64-low.c 2006-12-13 21:36:28.193575472 +0100
150
+#define INSTR_SC 0x44000002
151
+#define NR_spu_run 0x0116
153
+/* If the PPU thread is currently stopped on a spu_run system call,
154
+ return to FD and ADDR the file handle and NPC parameter address
155
+ used with the system call. Return non-zero if successful. */
157
+parse_spufs_run (int *fd, CORE_ADDR *addr)
160
+ unsigned long pc, r0, r3, r4;
161
+ collect_register_by_name ("pc", &pc);
163
+ /* Fetch instruction preceding current NIP. */
164
+ if ((*the_target->read_memory) (pc - 4, (unsigned char *) &insn, 4) != 0)
166
+ /* It should be a "sc" instruction. */
167
+ if (insn != INSTR_SC)
169
+ /* System call number should be NR_spu_run. */
170
+ collect_register_by_name ("r0", &r0);
171
+ if (r0 != NR_spu_run)
174
+ /* Register 3 contains fd, register 4 the NPC param pointer. */
175
+ collect_register_by_name ("orig_r3", &r3);
176
+ collect_register_by_name ("r4", &r4);
178
+ *addr = (CORE_ADDR) r4;
189
- collect_register_by_name ("pc", &pc);
190
- return (CORE_ADDR) pc;
191
+ if (parse_spufs_run (&fd, &addr))
194
+ (*the_target->read_memory) (addr, (unsigned char *) &pc, 4);
195
+ return ((CORE_ADDR)1 << 63) | ((CORE_ADDR)fd << 32) | (CORE_ADDR) (pc - 4);
200
+ collect_register_by_name ("pc", &pc);
201
+ return (CORE_ADDR) pc;
206
ppc_set_pc (CORE_ADDR pc)
208
- unsigned long newpc = pc;
212
- supply_register_by_name ("pc", &newpc);
213
+ if (parse_spufs_run (&fd, &addr))
215
+ unsigned int newpc = pc;
216
+ (*the_target->write_memory) (addr, (unsigned char *) &newpc, 4);
220
+ unsigned long newpc = pc;
221
+ supply_register_by_name ("pc", &newpc);
225
/* Correct in either endianness.
230
- (*the_target->read_memory) (where, (unsigned char *) &insn, 4);
231
- if (insn == ppc_breakpoint)
233
- /* If necessary, recognize more trap instructions here. GDB only uses the
235
+ if (where & ((CORE_ADDR)1 << 63))
237
+ char mem_annex[32];
238
+ sprintf (mem_annex, "%d/mem", (int)((where >> 32) & 0x7fffffff));
239
+ (*the_target->qxfer_partial) ("spu", mem_annex, (unsigned char *) &insn,
240
+ NULL, where & 0xffffffff, 4);
241
+ if (insn == 0x3fff)
246
+ (*the_target->read_memory) (where, (unsigned char *) &insn, 4);
247
+ if (insn == ppc_breakpoint)
249
+ /* If necessary, recognize more trap instructions here. GDB only uses
257
/* Provide only a fill function for the general register set. ps_lgetregs
258
will use this for NPTL support. */
260
diff -urN gdb-orig/gdb/gdbserver/linux-ppc-low.c gdb-6.6/gdb/gdbserver/linux-ppc-low.c
261
--- gdb-orig/gdb/gdbserver/linux-ppc-low.c 2006-12-13 21:36:19.946497648 +0100
262
+++ gdb-6.6/gdb/gdbserver/linux-ppc-low.c 2006-12-13 21:36:28.197574864 +0100
268
+#define INSTR_SC 0x44000002
269
+#define NR_spu_run 0x0116
271
+/* If the PPU thread is currently stopped on a spu_run system call,
272
+ return to FD and ADDR the file handle and NPC parameter address
273
+ used with the system call. Return non-zero if successful. */
275
+parse_spufs_run (int *fd, CORE_ADDR *addr)
277
+ unsigned long insn, pc, r0, r3, r4;
278
+ collect_register_by_name ("pc", &pc);
280
+ /* Fetch instruction preceding current NIP. */
281
+ if ((*the_target->read_memory) (pc - 4, (unsigned char *) &insn, 4) != 0)
283
+ /* It should be a "sc" instruction. */
284
+ if (insn != INSTR_SC)
286
+ /* System call number should be NR_spu_run. */
287
+ collect_register_by_name ("r0", &r0);
288
+ if (r0 != NR_spu_run)
291
+ /* Register 3 contains fd, register 4 the NPC param pointer. */
292
+ collect_register_by_name ("orig_r3", &r3);
293
+ collect_register_by_name ("r4", &r4);
295
+ *addr = (CORE_ADDR) r4;
306
- collect_register_by_name ("pc", &pc);
307
- return (CORE_ADDR) pc;
308
+ if (parse_spufs_run (&fd, &addr))
311
+ (*the_target->read_memory) (addr, (unsigned char *) &pc, 4);
312
+ return ((CORE_ADDR)1 << 63) | ((CORE_ADDR)fd << 32) | (CORE_ADDR) (pc - 4);
317
+ collect_register_by_name ("pc", &pc);
318
+ return (CORE_ADDR) pc;
323
ppc_set_pc (CORE_ADDR pc)
325
- unsigned long newpc = pc;
329
- supply_register_by_name ("pc", &newpc);
330
+ if (parse_spufs_run (&fd, &addr))
332
+ unsigned int newpc = pc;
333
+ (*the_target->write_memory) (addr, (unsigned char *) &newpc, 4);
337
+ unsigned long newpc = pc;
338
+ supply_register_by_name ("pc", &newpc);
342
/* Correct in either endianness. Note that this file is
343
@@ -102,11 +155,24 @@
347
- (*the_target->read_memory) (where, (unsigned char *) &insn, 4);
348
- if (insn == ppc_breakpoint)
350
- /* If necessary, recognize more trap instructions here. GDB only uses the
352
+ if (where & ((CORE_ADDR)1 << 63))
354
+ char mem_annex[32];
355
+ sprintf (mem_annex, "%d/mem", (int)((where >> 32) & 0x7fffffff));
356
+ (*the_target->qxfer_partial) ("spu", mem_annex, (unsigned char *) &insn,
357
+ NULL, where & 0xffffffff, 4);
358
+ if (insn == 0x3fff)
363
+ (*the_target->read_memory) (where, (unsigned char *) &insn, 4);
364
+ if (insn == ppc_breakpoint)
366
+ /* If necessary, recognize more trap instructions here. GDB only uses