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