* gdb.base/maint.exp: Only dump symbols from one source file
[deliverable/binutils-gdb.git] / gdb / gdbserver / low-lynx.c
1 /* Low level interface to ptrace, for the remote server for GDB.
2 Copyright 1986, 1987, 1993, 1994, 1995, 1999, 2000, 2001, 2002
3 Free Software Foundation, Inc.
4
5 This file is part of GDB.
6
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.
11
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.
16
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. */
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
48 static char my_registers[REGISTER_BYTES];
49 char *registers = my_registers;
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
56 int
57 create_inferior (char *program, 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
70 directly affect gdbserver. */
71
72 pgrp = getpid ();
73 setpgrp (0, pgrp);
74 ioctl (0, TIOCSPGRP, &pgrp);
75
76 ptrace (PTRACE_TRACEME, 0, (PTRACE_ARG3_TYPE) 0, 0);
77
78 execv (program, allargs);
79
80 fprintf (stderr, "GDBserver (process %d): Cannot exec %s: %s.\n",
81 getpid (), program,
82 errno < sys_nerr ? sys_errlist[errno] : "unknown error");
83 fflush (stderr);
84 _exit (0177);
85 }
86
87 return pid;
88 }
89
90 /* Attaching is not supported. */
91 int
92 myattach (int pid)
93 {
94 return -1;
95 }
96
97 /* Kill the inferior process. Make us have no inferior. */
98
99 void
100 kill_inferior (void)
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. */
111 int
112 mythread_alive (int pid)
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
129 unsigned char
130 mywait (char *status)
131 {
132 int pid;
133 union wait w;
134
135 while (1)
136 {
137 enable_async_io ();
138
139 pid = wait (&w);
140
141 disable_async_io ();
142
143 if (pid != PIDGET (inferior_pid))
144 perror_with_name ("wait");
145
146 thread_from_wait = w.w_tid;
147 inferior_pid = BUILDPID (inferior_pid, w.w_tid);
148
149 if (WIFSTOPPED (w)
150 && WSTOPSIG (w) == SIGTRAP)
151 {
152 int realsig;
153
154 realsig = ptrace (PTRACE_GETTRACESIG, inferior_pid,
155 (PTRACE_ARG3_TYPE) 0, 0);
156
157 if (realsig == SIGNEWTHREAD)
158 {
159 /* It's a new thread notification. Nothing to do here since
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. */
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
192 void
193 myresume (int step, int signal)
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
214 static int regmap[] =
215 {
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
232 that they are useful. */
233 };
234 #endif
235
236 #ifdef M68K
237 /* Mappings from tm-m68k.h */
238
239 static int regmap[] =
240 {
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 */
256 0, /* sp */
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 */
274 };
275 #endif
276
277 #ifdef SPARC
278 /* Mappings from tm-sparc.h */
279
280 #define FX(ENTRY)(offsetof(struct fcontext, ENTRY))
281
282 static int regmap[] =
283 {
284 -1, /* g0 */
285 X (g1),
286 X (g2),
287 X (g3),
288 X (g4),
289 -1, /* g5->g7 aren't saved by Lynx */
290 -1,
291 -1,
292
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 */
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
356 void
357 fetch_inferior_registers (int regno)
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 {
377 struct econtext ec; /* general regs */
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),
385 (PTRACE_ARG3_TYPE) & ec,
386 0);
387 if (errno)
388 perror_with_name ("Sparc fetch_inferior_registers(ptrace)");
389
390 memset (buf, 0, REGISTER_RAW_SIZE (G0_REGNUM));
391 supply_register (G0_REGNUM, buf);
392 supply_register (TBR_REGNUM, (char *) &ec.tbr);
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
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);
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,
419 &registers[REGISTER_BYTE (I0_REGNUM)],
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,
425 &registers[REGISTER_BYTE (L0_REGNUM)],
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 {
433 struct fcontext fc; /* fp regs */
434 int retval;
435 int i;
436
437 errno = 0;
438 retval = ptrace (PTRACE_GETFPREGS, BUILDPID (inferior_pid, general_thread), (PTRACE_ARG3_TYPE) & fc,
439 0);
440 if (errno)
441 perror_with_name ("Sparc fetch_inferior_registers(ptrace)");
442
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
448 supply_register (FPS_REGNUM, (char *) &fc.fsr);
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
460 void
461 store_inferior_registers (int regno)
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 {
479 struct econtext ec; /* general regs */
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;
496 retval = ptrace (PTRACE_SETREGS, BUILDPID (inferior_pid, general_thread), (PTRACE_ARG3_TYPE) & ec,
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 {
511 if (!register_valid[L0_REGNUM + 5])
512 abort ();
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])
524 abort ();
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 {
538 struct fcontext fc; /* fp regs */
539 int retval;
540
541 /* We read fcontext first so that we can get good values for fq_t... */
542 errno = 0;
543 retval = ptrace (PTRACE_GETFPREGS, BUILDPID (inferior_pid, general_thread), (PTRACE_ARG3_TYPE) & fc,
544 0);
545 if (errno)
546 perror_with_name ("Sparc fetch_inferior_registers(ptrace)");
547
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;
554 retval = ptrace (PTRACE_SETFPREGS, BUILDPID (inferior_pid, general_thread), (PTRACE_ARG3_TYPE) & fc,
555 0);
556 if (errno)
557 perror_with_name ("Sparc fetch_inferior_registers(ptrace)");
558 }
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
568 static unsigned long
569 lynx_registers_addr (void)
570 {
571 CORE_ADDR stblock;
572 int ecpoff = offsetof (st_t, ecp);
573 CORE_ADDR ecp;
574
575 errno = 0;
576 stblock = (CORE_ADDR) ptrace (PTRACE_THREADUSER, BUILDPID (inferior_pid, general_thread),
577 (PTRACE_ARG3_TYPE) 0, 0);
578 if (errno)
579 perror_with_name ("PTRACE_THREADUSER");
580
581 ecp = (CORE_ADDR) ptrace (PTRACE_PEEKTHREAD, BUILDPID (inferior_pid, general_thread),
582 (PTRACE_ARG3_TYPE) ecpoff, 0);
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
593 void
594 fetch_inferior_registers (int ignored)
595 {
596 int regno;
597 unsigned long reg;
598 unsigned long ecp;
599
600 ecp = lynx_registers_addr ();
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)");
615
616 *(unsigned long *) &registers[REGISTER_BYTE (regno)] = reg;
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
624 void
625 store_inferior_registers (int ignored)
626 {
627 int regno;
628 unsigned long reg;
629 unsigned long ecp;
630
631 ecp = lynx_registers_addr ();
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
641 reg = *(unsigned long *) &registers[REGISTER_BYTE (regno)];
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
662 void
663 read_inferior_memory (CORE_ADDR memaddr, char *myaddr, int len)
664 {
665 register int i;
666 /* Round starting address down to longword boundary. */
667 register CORE_ADDR addr = memaddr & -(CORE_ADDR) sizeof (int);
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
689 int
690 write_inferior_memory (CORE_ADDR memaddr, char *myaddr, int len)
691 {
692 register int i;
693 /* Round starting address down to longword boundary. */
694 register CORE_ADDR addr = memaddr & -(CORE_ADDR) sizeof (int);
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 {
727 fprintf (stderr, "\
728 ptrace (PTRACE_POKETEXT): errno=%d, pid=0x%x, addr=0x%x, buffer[i] = 0x%x\n",
729 errno, BUILDPID (inferior_pid, general_thread),
730 addr, buffer[i]);
731 fprintf (stderr, "Sleeping for 1 second\n");
732 sleep (1);
733 }
734 else
735 break;
736 }
737 }
738
739 return 0;
740 }
741 \f
742 void
743 initialize_low (void)
744 {
745 }
This page took 0.086462 seconds and 4 git commands to generate.