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