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