2002-12-06 Andrew Cagney <ac131313@redhat.com>
[deliverable/binutils-gdb.git] / gdb / gdbserver / low-lynx.c
CommitLineData
c906108c 1/* Low level interface to ptrace, for the remote server for GDB.
db728ff7 2 Copyright 1986, 1987, 1993, 1994, 1995, 1999, 2000, 2001, 2002
b6ba6518 3 Free Software Foundation, Inc.
c906108c 4
c5aa993b 5 This file is part of GDB.
c906108c 6
c5aa993b
JM
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
c906108c 11
c5aa993b
JM
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
c906108c 16
c5aa993b
JM
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA. */
c906108c
SS
21
22#include "server.h"
23#include "frame.h"
24#include "inferior.h"
25
26#include <stdio.h>
27#include <sys/param.h>
28#include <sys/dir.h>
29#define LYNXOS
30#include <sys/mem.h>
31#include <sys/signal.h>
32#include <sys/file.h>
33#include <sys/kernel.h>
34#ifndef __LYNXOS
35#define __LYNXOS
36#endif
37#include <sys/itimer.h>
38#include <sys/time.h>
39#include <sys/resource.h>
40#include <sys/proc.h>
41#include <signal.h>
42#include <sys/ioctl.h>
43#include <sgtty.h>
44#include <fcntl.h>
45#include <sys/wait.h>
46#include <sys/fpp.h>
47
5c44784c
JM
48static char my_registers[REGISTER_BYTES];
49char *registers = my_registers;
c906108c
SS
50
51#include <sys/ptrace.h>
52
53/* Start an inferior process and returns its pid.
54 ALLARGS is a vector of program-name and args. */
55
56int
fba45db2 57create_inferior (char *program, char **allargs)
c906108c
SS
58{
59 int pid;
60
61 pid = fork ();
62 if (pid < 0)
63 perror_with_name ("fork");
64
65 if (pid == 0)
66 {
67 int pgrp;
68
69 /* Switch child to it's own process group so that signals won't
c5aa993b 70 directly affect gdbserver. */
c906108c 71
c5aa993b
JM
72 pgrp = getpid ();
73 setpgrp (0, pgrp);
c906108c
SS
74 ioctl (0, TIOCSPGRP, &pgrp);
75
c5aa993b 76 ptrace (PTRACE_TRACEME, 0, (PTRACE_ARG3_TYPE) 0, 0);
c906108c
SS
77
78 execv (program, allargs);
79
80 fprintf (stderr, "GDBserver (process %d): Cannot exec %s: %s.\n",
c5aa993b 81 getpid (), program,
c906108c
SS
82 errno < sys_nerr ? sys_errlist[errno] : "unknown error");
83 fflush (stderr);
84 _exit (0177);
85 }
86
87 return pid;
88}
89
45b7b345
DJ
90/* Attaching is not supported. */
91int
92myattach (int pid)
93{
94 return -1;
95}
96
c906108c
SS
97/* Kill the inferior process. Make us have no inferior. */
98
99void
fba45db2 100kill_inferior (void)
c906108c
SS
101{
102 if (inferior_pid == 0)
103 return;
104 ptrace (PTRACE_KILL, inferior_pid, 0, 0);
105 wait (0);
106
107 inferior_pid = 0;
108}
109
110/* Return nonzero if the given thread is still alive. */
111int
fba45db2 112mythread_alive (int pid)
c906108c
SS
113{
114 /* Arggh. Apparently pthread_kill only works for threads within
115 the process that calls pthread_kill.
116
117 We want to avoid the lynx signal extensions as they simply don't
118 map well to the generic gdb interface we want to keep.
119
120 All we want to do is determine if a particular thread is alive;
121 it appears as if we can just make a harmless thread specific
122 ptrace call to do that. */
123 return (ptrace (PTRACE_THREADUSER,
124 BUILDPID (PIDGET (inferior_pid), pid), 0, 0) != -1);
125}
126
127/* Wait for process, returns status */
128
129unsigned char
fba45db2 130mywait (char *status)
c906108c
SS
131{
132 int pid;
133 union wait w;
134
135 while (1)
136 {
c5aa993b 137 enable_async_io ();
c906108c
SS
138
139 pid = wait (&w);
140
c5aa993b 141 disable_async_io ();
c906108c 142
c5aa993b 143 if (pid != PIDGET (inferior_pid))
c906108c
SS
144 perror_with_name ("wait");
145
146 thread_from_wait = w.w_tid;
147 inferior_pid = BUILDPID (inferior_pid, w.w_tid);
148
c5aa993b
JM
149 if (WIFSTOPPED (w)
150 && WSTOPSIG (w) == SIGTRAP)
c906108c
SS
151 {
152 int realsig;
153
154 realsig = ptrace (PTRACE_GETTRACESIG, inferior_pid,
c5aa993b 155 (PTRACE_ARG3_TYPE) 0, 0);
c906108c
SS
156
157 if (realsig == SIGNEWTHREAD)
158 {
159 /* It's a new thread notification. Nothing to do here since
c5aa993b
JM
160 the machine independent code in wait_for_inferior will
161 add the thread to the thread list and restart the thread
162 when pid != inferior_pid and pid is not in the thread list.
163 We don't even want to muck with realsig -- the code in
164 wait_for_inferior expects SIGTRAP. */
c906108c
SS
165 ;
166 }
167 }
168 break;
169 }
170
171 if (WIFEXITED (w))
172 {
173 *status = 'W';
174 return ((unsigned char) WEXITSTATUS (w));
175 }
176 else if (!WIFSTOPPED (w))
177 {
178 *status = 'X';
179 return ((unsigned char) WTERMSIG (w));
180 }
181
182 fetch_inferior_registers (0);
183
184 *status = 'T';
185 return ((unsigned char) WSTOPSIG (w));
186}
187
188/* Resume execution of the inferior process.
189 If STEP is nonzero, single-step it.
190 If SIGNAL is nonzero, give it that signal. */
191
192void
fba45db2 193myresume (int step, int signal)
c906108c
SS
194{
195 errno = 0;
196 ptrace (step ? PTRACE_SINGLESTEP_ONE : PTRACE_CONT,
197 BUILDPID (inferior_pid, cont_thread == -1 ? 0 : cont_thread),
198 1, signal);
199 if (errno)
200 perror_with_name ("ptrace");
201}
202
203#undef offsetof
204#define offsetof(TYPE, MEMBER) ((unsigned long) &((TYPE *)0)->MEMBER)
205
206/* Mapping between GDB register #s and offsets into econtext. Must be
207 consistent with REGISTER_NAMES macro in various tmXXX.h files. */
208
209#define X(ENTRY)(offsetof(struct econtext, ENTRY))
210
211#ifdef I386
212/* Mappings from tm-i386v.h */
213
214static int regmap[] =
215{
c5aa993b
JM
216 X (eax),
217 X (ecx),
218 X (edx),
219 X (ebx),
220 X (esp), /* sp */
221 X (ebp), /* fp */
222 X (esi),
223 X (edi),
224 X (eip), /* pc */
225 X (flags), /* ps */
226 X (cs),
227 X (ss),
228 X (ds),
229 X (es),
230 X (ecode), /* Lynx doesn't give us either fs or gs, so */
231 X (fault), /* we just substitute these two in the hopes
c906108c
SS
232 that they are useful. */
233};
234#endif
235
236#ifdef M68K
237/* Mappings from tm-m68k.h */
238
239static int regmap[] =
240{
c5aa993b
JM
241 X (regs[0]), /* d0 */
242 X (regs[1]), /* d1 */
243 X (regs[2]), /* d2 */
244 X (regs[3]), /* d3 */
245 X (regs[4]), /* d4 */
246 X (regs[5]), /* d5 */
247 X (regs[6]), /* d6 */
248 X (regs[7]), /* d7 */
249 X (regs[8]), /* a0 */
250 X (regs[9]), /* a1 */
251 X (regs[10]), /* a2 */
252 X (regs[11]), /* a3 */
253 X (regs[12]), /* a4 */
254 X (regs[13]), /* a5 */
255 X (regs[14]), /* fp */
c906108c 256 0, /* sp */
c5aa993b
JM
257 X (status), /* ps */
258 X (pc),
259
260 X (fregs[0 * 3]), /* fp0 */
261 X (fregs[1 * 3]), /* fp1 */
262 X (fregs[2 * 3]), /* fp2 */
263 X (fregs[3 * 3]), /* fp3 */
264 X (fregs[4 * 3]), /* fp4 */
265 X (fregs[5 * 3]), /* fp5 */
266 X (fregs[6 * 3]), /* fp6 */
267 X (fregs[7 * 3]), /* fp7 */
268
269 X (fcregs[0]), /* fpcontrol */
270 X (fcregs[1]), /* fpstatus */
271 X (fcregs[2]), /* fpiaddr */
272 X (ssw), /* fpcode */
273 X (fault), /* fpflags */
c906108c
SS
274};
275#endif
276
277#ifdef SPARC
278/* Mappings from tm-sparc.h */
279
280#define FX(ENTRY)(offsetof(struct fcontext, ENTRY))
281
282static int regmap[] =
283{
284 -1, /* g0 */
c5aa993b
JM
285 X (g1),
286 X (g2),
287 X (g3),
288 X (g4),
c906108c
SS
289 -1, /* g5->g7 aren't saved by Lynx */
290 -1,
291 -1,
292
c5aa993b
JM
293 X (o[0]),
294 X (o[1]),
295 X (o[2]),
296 X (o[3]),
297 X (o[4]),
298 X (o[5]),
299 X (o[6]), /* sp */
300 X (o[7]), /* ra */
301
302 -1, -1, -1, -1, -1, -1, -1, -1, /* l0 -> l7 */
303
304 -1, -1, -1, -1, -1, -1, -1, -1, /* i0 -> i7 */
305
306 FX (f.fregs[0]), /* f0 */
307 FX (f.fregs[1]),
308 FX (f.fregs[2]),
309 FX (f.fregs[3]),
310 FX (f.fregs[4]),
311 FX (f.fregs[5]),
312 FX (f.fregs[6]),
313 FX (f.fregs[7]),
314 FX (f.fregs[8]),
315 FX (f.fregs[9]),
316 FX (f.fregs[10]),
317 FX (f.fregs[11]),
318 FX (f.fregs[12]),
319 FX (f.fregs[13]),
320 FX (f.fregs[14]),
321 FX (f.fregs[15]),
322 FX (f.fregs[16]),
323 FX (f.fregs[17]),
324 FX (f.fregs[18]),
325 FX (f.fregs[19]),
326 FX (f.fregs[20]),
327 FX (f.fregs[21]),
328 FX (f.fregs[22]),
329 FX (f.fregs[23]),
330 FX (f.fregs[24]),
331 FX (f.fregs[25]),
332 FX (f.fregs[26]),
333 FX (f.fregs[27]),
334 FX (f.fregs[28]),
335 FX (f.fregs[29]),
336 FX (f.fregs[30]),
337 FX (f.fregs[31]),
338
339 X (y),
340 X (psr),
341 X (wim),
342 X (tbr),
343 X (pc),
344 X (npc),
345 FX (fsr), /* fpsr */
c906108c
SS
346 -1, /* cpsr */
347};
348#endif
349
350#ifdef SPARC
351
352/* This routine handles some oddball cases for Sparc registers and LynxOS.
353 In partucular, it causes refs to G0, g5->7, and all fp regs to return zero.
354 It also handles knows where to find the I & L regs on the stack. */
355
356void
fba45db2 357fetch_inferior_registers (int regno)
c906108c
SS
358{
359#if 0
360 int whatregs = 0;
361
362#define WHATREGS_FLOAT 1
363#define WHATREGS_GEN 2
364#define WHATREGS_STACK 4
365
366 if (regno == -1)
367 whatregs = WHATREGS_FLOAT | WHATREGS_GEN | WHATREGS_STACK;
368 else if (regno >= L0_REGNUM && regno <= I7_REGNUM)
369 whatregs = WHATREGS_STACK;
370 else if (regno >= FP0_REGNUM && regno < FP0_REGNUM + 32)
371 whatregs = WHATREGS_FLOAT;
372 else
373 whatregs = WHATREGS_GEN;
374
375 if (whatregs & WHATREGS_GEN)
376 {
c5aa993b 377 struct econtext ec; /* general regs */
c906108c
SS
378 char buf[MAX_REGISTER_RAW_SIZE];
379 int retval;
380 int i;
381
382 errno = 0;
383 retval = ptrace (PTRACE_GETREGS,
384 BUILDPID (inferior_pid, general_thread),
c5aa993b 385 (PTRACE_ARG3_TYPE) & ec,
c906108c
SS
386 0);
387 if (errno)
388 perror_with_name ("Sparc fetch_inferior_registers(ptrace)");
c5aa993b 389
c906108c
SS
390 memset (buf, 0, REGISTER_RAW_SIZE (G0_REGNUM));
391 supply_register (G0_REGNUM, buf);
c5aa993b 392 supply_register (TBR_REGNUM, (char *) &ec.tbr);
c906108c
SS
393
394 memcpy (&registers[REGISTER_BYTE (G1_REGNUM)], &ec.g1,
395 4 * REGISTER_RAW_SIZE (G1_REGNUM));
396 for (i = G1_REGNUM; i <= G1_REGNUM + 3; i++)
397 register_valid[i] = 1;
398
c5aa993b
JM
399 supply_register (PS_REGNUM, (char *) &ec.psr);
400 supply_register (Y_REGNUM, (char *) &ec.y);
401 supply_register (PC_REGNUM, (char *) &ec.pc);
402 supply_register (NPC_REGNUM, (char *) &ec.npc);
403 supply_register (WIM_REGNUM, (char *) &ec.wim);
c906108c
SS
404
405 memcpy (&registers[REGISTER_BYTE (O0_REGNUM)], ec.o,
406 8 * REGISTER_RAW_SIZE (O0_REGNUM));
407 for (i = O0_REGNUM; i <= O0_REGNUM + 7; i++)
408 register_valid[i] = 1;
409 }
410
411 if (whatregs & WHATREGS_STACK)
412 {
413 CORE_ADDR sp;
414 int i;
415
416 sp = read_register (SP_REGNUM);
417
418 target_xfer_memory (sp + FRAME_SAVED_I0,
c5aa993b 419 &registers[REGISTER_BYTE (I0_REGNUM)],
c906108c
SS
420 8 * REGISTER_RAW_SIZE (I0_REGNUM), 0);
421 for (i = I0_REGNUM; i <= I7_REGNUM; i++)
422 register_valid[i] = 1;
423
424 target_xfer_memory (sp + FRAME_SAVED_L0,
c5aa993b 425 &registers[REGISTER_BYTE (L0_REGNUM)],
c906108c
SS
426 8 * REGISTER_RAW_SIZE (L0_REGNUM), 0);
427 for (i = L0_REGNUM; i <= L0_REGNUM + 7; i++)
428 register_valid[i] = 1;
429 }
430
431 if (whatregs & WHATREGS_FLOAT)
432 {
c5aa993b 433 struct fcontext fc; /* fp regs */
c906108c
SS
434 int retval;
435 int i;
436
437 errno = 0;
c5aa993b 438 retval = ptrace (PTRACE_GETFPREGS, BUILDPID (inferior_pid, general_thread), (PTRACE_ARG3_TYPE) & fc,
c906108c
SS
439 0);
440 if (errno)
441 perror_with_name ("Sparc fetch_inferior_registers(ptrace)");
c5aa993b 442
c906108c
SS
443 memcpy (&registers[REGISTER_BYTE (FP0_REGNUM)], fc.f.fregs,
444 32 * REGISTER_RAW_SIZE (FP0_REGNUM));
445 for (i = FP0_REGNUM; i <= FP0_REGNUM + 31; i++)
446 register_valid[i] = 1;
447
c5aa993b 448 supply_register (FPS_REGNUM, (char *) &fc.fsr);
c906108c
SS
449 }
450#endif
451}
452
453/* This routine handles storing of the I & L regs for the Sparc. The trick
454 here is that they actually live on the stack. The really tricky part is
455 that when changing the stack pointer, the I & L regs must be written to
456 where the new SP points, otherwise the regs will be incorrect when the
457 process is started up again. We assume that the I & L regs are valid at
458 this point. */
459
460void
fba45db2 461store_inferior_registers (int regno)
c906108c
SS
462{
463#if 0
464 int whatregs = 0;
465
466 if (regno == -1)
467 whatregs = WHATREGS_FLOAT | WHATREGS_GEN | WHATREGS_STACK;
468 else if (regno >= L0_REGNUM && regno <= I7_REGNUM)
469 whatregs = WHATREGS_STACK;
470 else if (regno >= FP0_REGNUM && regno < FP0_REGNUM + 32)
471 whatregs = WHATREGS_FLOAT;
472 else if (regno == SP_REGNUM)
473 whatregs = WHATREGS_STACK | WHATREGS_GEN;
474 else
475 whatregs = WHATREGS_GEN;
476
477 if (whatregs & WHATREGS_GEN)
478 {
c5aa993b 479 struct econtext ec; /* general regs */
c906108c
SS
480 int retval;
481
482 ec.tbr = read_register (TBR_REGNUM);
483 memcpy (&ec.g1, &registers[REGISTER_BYTE (G1_REGNUM)],
484 4 * REGISTER_RAW_SIZE (G1_REGNUM));
485
486 ec.psr = read_register (PS_REGNUM);
487 ec.y = read_register (Y_REGNUM);
488 ec.pc = read_register (PC_REGNUM);
489 ec.npc = read_register (NPC_REGNUM);
490 ec.wim = read_register (WIM_REGNUM);
491
492 memcpy (ec.o, &registers[REGISTER_BYTE (O0_REGNUM)],
493 8 * REGISTER_RAW_SIZE (O0_REGNUM));
494
495 errno = 0;
c5aa993b 496 retval = ptrace (PTRACE_SETREGS, BUILDPID (inferior_pid, general_thread), (PTRACE_ARG3_TYPE) & ec,
c906108c
SS
497 0);
498 if (errno)
499 perror_with_name ("Sparc fetch_inferior_registers(ptrace)");
500 }
501
502 if (whatregs & WHATREGS_STACK)
503 {
504 int regoffset;
505 CORE_ADDR sp;
506
507 sp = read_register (SP_REGNUM);
508
509 if (regno == -1 || regno == SP_REGNUM)
510 {
c5aa993b
JM
511 if (!register_valid[L0_REGNUM + 5])
512 abort ();
c906108c
SS
513 target_xfer_memory (sp + FRAME_SAVED_I0,
514 &registers[REGISTER_BYTE (I0_REGNUM)],
515 8 * REGISTER_RAW_SIZE (I0_REGNUM), 1);
516
517 target_xfer_memory (sp + FRAME_SAVED_L0,
518 &registers[REGISTER_BYTE (L0_REGNUM)],
519 8 * REGISTER_RAW_SIZE (L0_REGNUM), 1);
520 }
521 else if (regno >= L0_REGNUM && regno <= I7_REGNUM)
522 {
523 if (!register_valid[regno])
c5aa993b 524 abort ();
c906108c
SS
525 if (regno >= L0_REGNUM && regno <= L0_REGNUM + 7)
526 regoffset = REGISTER_BYTE (regno) - REGISTER_BYTE (L0_REGNUM)
527 + FRAME_SAVED_L0;
528 else
529 regoffset = REGISTER_BYTE (regno) - REGISTER_BYTE (I0_REGNUM)
530 + FRAME_SAVED_I0;
531 target_xfer_memory (sp + regoffset, &registers[REGISTER_BYTE (regno)],
532 REGISTER_RAW_SIZE (regno), 1);
533 }
534 }
535
536 if (whatregs & WHATREGS_FLOAT)
537 {
c5aa993b 538 struct fcontext fc; /* fp regs */
c906108c
SS
539 int retval;
540
541/* We read fcontext first so that we can get good values for fq_t... */
542 errno = 0;
c5aa993b 543 retval = ptrace (PTRACE_GETFPREGS, BUILDPID (inferior_pid, general_thread), (PTRACE_ARG3_TYPE) & fc,
c906108c
SS
544 0);
545 if (errno)
546 perror_with_name ("Sparc fetch_inferior_registers(ptrace)");
c5aa993b 547
c906108c
SS
548 memcpy (fc.f.fregs, &registers[REGISTER_BYTE (FP0_REGNUM)],
549 32 * REGISTER_RAW_SIZE (FP0_REGNUM));
550
551 fc.fsr = read_register (FPS_REGNUM);
552
553 errno = 0;
c5aa993b 554 retval = ptrace (PTRACE_SETFPREGS, BUILDPID (inferior_pid, general_thread), (PTRACE_ARG3_TYPE) & fc,
c906108c
SS
555 0);
556 if (errno)
557 perror_with_name ("Sparc fetch_inferior_registers(ptrace)");
c5aa993b 558 }
c906108c
SS
559#endif
560}
561#endif /* SPARC */
562
563#ifndef SPARC
564
565/* Return the offset relative to the start of the per-thread data to the
566 saved context block. */
567
568static unsigned long
fba45db2 569lynx_registers_addr (void)
c906108c
SS
570{
571 CORE_ADDR stblock;
c5aa993b 572 int ecpoff = offsetof (st_t, ecp);
c906108c
SS
573 CORE_ADDR ecp;
574
575 errno = 0;
576 stblock = (CORE_ADDR) ptrace (PTRACE_THREADUSER, BUILDPID (inferior_pid, general_thread),
c5aa993b 577 (PTRACE_ARG3_TYPE) 0, 0);
c906108c
SS
578 if (errno)
579 perror_with_name ("PTRACE_THREADUSER");
580
581 ecp = (CORE_ADDR) ptrace (PTRACE_PEEKTHREAD, BUILDPID (inferior_pid, general_thread),
c5aa993b 582 (PTRACE_ARG3_TYPE) ecpoff, 0);
c906108c
SS
583 if (errno)
584 perror_with_name ("lynx_registers_addr(PTRACE_PEEKTHREAD)");
585
586 return ecp - stblock;
587}
588
589/* Fetch one or more registers from the inferior. REGNO == -1 to get
590 them all. We actually fetch more than requested, when convenient,
591 marking them as valid so we won't fetch them again. */
592
593void
fba45db2 594fetch_inferior_registers (int ignored)
c906108c
SS
595{
596 int regno;
597 unsigned long reg;
598 unsigned long ecp;
599
c5aa993b 600 ecp = lynx_registers_addr ();
c906108c
SS
601
602 for (regno = 0; regno < NUM_REGS; regno++)
603 {
604 int ptrace_fun = PTRACE_PEEKTHREAD;
605
606#ifdef PTRACE_PEEKUSP
607 ptrace_fun = regno == SP_REGNUM ? PTRACE_PEEKUSP : PTRACE_PEEKTHREAD;
608#endif
609
610 errno = 0;
611 reg = ptrace (ptrace_fun, BUILDPID (inferior_pid, general_thread),
612 (PTRACE_ARG3_TYPE) (ecp + regmap[regno]), 0);
613 if (errno)
614 perror_with_name ("fetch_inferior_registers(PTRACE_PEEKTHREAD)");
c5aa993b
JM
615
616 *(unsigned long *) &registers[REGISTER_BYTE (regno)] = reg;
c906108c
SS
617 }
618}
619
620/* Store our register values back into the inferior.
621 If REGNO is -1, do this for all registers.
622 Otherwise, REGNO specifies which register (so we can save time). */
623
624void
fba45db2 625store_inferior_registers (int ignored)
c906108c
SS
626{
627 int regno;
628 unsigned long reg;
629 unsigned long ecp;
630
c5aa993b 631 ecp = lynx_registers_addr ();
c906108c
SS
632
633 for (regno = 0; regno < NUM_REGS; regno++)
634 {
635 int ptrace_fun = PTRACE_POKEUSER;
636
637#ifdef PTRACE_POKEUSP
638 ptrace_fun = regno == SP_REGNUM ? PTRACE_POKEUSP : PTRACE_POKEUSER;
639#endif
640
c5aa993b 641 reg = *(unsigned long *) &registers[REGISTER_BYTE (regno)];
c906108c
SS
642
643 errno = 0;
644 ptrace (ptrace_fun, BUILDPID (inferior_pid, general_thread),
645 (PTRACE_ARG3_TYPE) (ecp + regmap[regno]), reg);
646 if (errno)
647 perror_with_name ("PTRACE_POKEUSER");
648 }
649}
650
651#endif /* ! SPARC */
652
653/* NOTE! I tried using PTRACE_READDATA, etc., to read and write memory
654 in the NEW_SUN_PTRACE case.
655 It ought to be straightforward. But it appears that writing did
656 not write the data that I specified. I cannot understand where
657 it got the data that it actually did write. */
658
659/* Copy LEN bytes from inferior's memory starting at MEMADDR
660 to debugger memory starting at MYADDR. */
661
662void
fba45db2 663read_inferior_memory (CORE_ADDR memaddr, char *myaddr, int len)
c906108c
SS
664{
665 register int i;
666 /* Round starting address down to longword boundary. */
9f30d7f5 667 register CORE_ADDR addr = memaddr & -(CORE_ADDR) sizeof (int);
c906108c
SS
668 /* Round ending address up; get number of longwords that makes. */
669 register int count
670 = (((memaddr + len) - addr) + sizeof (int) - 1) / sizeof (int);
671 /* Allocate buffer of that many longwords. */
672 register int *buffer = (int *) alloca (count * sizeof (int));
673
674 /* Read all the longwords */
675 for (i = 0; i < count; i++, addr += sizeof (int))
676 {
677 buffer[i] = ptrace (PTRACE_PEEKTEXT, BUILDPID (inferior_pid, general_thread), addr, 0);
678 }
679
680 /* Copy appropriate bytes out of the buffer. */
681 memcpy (myaddr, (char *) buffer + (memaddr & (sizeof (int) - 1)), len);
682}
683
684/* Copy LEN bytes of data from debugger memory at MYADDR
685 to inferior's memory at MEMADDR.
686 On failure (cannot write the inferior)
687 returns the value of errno. */
688
689int
fba45db2 690write_inferior_memory (CORE_ADDR memaddr, char *myaddr, int len)
c906108c
SS
691{
692 register int i;
693 /* Round starting address down to longword boundary. */
9f30d7f5 694 register CORE_ADDR addr = memaddr & -(CORE_ADDR) sizeof (int);
c906108c
SS
695 /* Round ending address up; get number of longwords that makes. */
696 register int count
697 = (((memaddr + len) - addr) + sizeof (int) - 1) / sizeof (int);
698 /* Allocate buffer of that many longwords. */
699 register int *buffer = (int *) alloca (count * sizeof (int));
700 extern int errno;
701
702 /* Fill start and end extra bytes of buffer with existing memory data. */
703
704 buffer[0] = ptrace (PTRACE_PEEKTEXT, BUILDPID (inferior_pid, general_thread), addr, 0);
705
706 if (count > 1)
707 {
708 buffer[count - 1]
709 = ptrace (PTRACE_PEEKTEXT, BUILDPID (inferior_pid, general_thread),
710 addr + (count - 1) * sizeof (int), 0);
711 }
712
713 /* Copy data to be written over corresponding part of buffer */
714
715 memcpy ((char *) buffer + (memaddr & (sizeof (int) - 1)), myaddr, len);
716
717 /* Write the entire buffer. */
718
719 for (i = 0; i < count; i++, addr += sizeof (int))
720 {
721 while (1)
722 {
723 errno = 0;
724 ptrace (PTRACE_POKETEXT, BUILDPID (inferior_pid, general_thread), addr, buffer[i]);
725 if (errno)
726 {
c5aa993b 727 fprintf (stderr, "\
c906108c 728ptrace (PTRACE_POKETEXT): errno=%d, pid=0x%x, addr=0x%x, buffer[i] = 0x%x\n",
c5aa993b
JM
729 errno, BUILDPID (inferior_pid, general_thread),
730 addr, buffer[i]);
731 fprintf (stderr, "Sleeping for 1 second\n");
732 sleep (1);
c906108c
SS
733 }
734 else
735 break;
736 }
737 }
738
739 return 0;
740}
4ce44c66
JM
741\f
742void
fba45db2 743initialize_low (void)
4ce44c66
JM
744{
745}
This page took 0.281366 seconds and 4 git commands to generate.