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