* gdbserver/remote-utils.c (remote_open): Set gdbserver as "owner"
[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
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 /* Kill the inferior process. Make us have no inferior. */
91
92 void
93 kill_inferior (void)
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. */
104 int
105 mythread_alive (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
120 /* Wait for process, returns status */
121
122 unsigned char
123 mywait (char *status)
124 {
125 int pid;
126 union wait w;
127
128 while (1)
129 {
130 enable_async_io ();
131
132 pid = wait (&w);
133
134 disable_async_io ();
135
136 if (pid != PIDGET (inferior_pid))
137 perror_with_name ("wait");
138
139 thread_from_wait = w.w_tid;
140 inferior_pid = BUILDPID (inferior_pid, w.w_tid);
141
142 if (WIFSTOPPED (w)
143 && WSTOPSIG (w) == SIGTRAP)
144 {
145 int realsig;
146
147 realsig = ptrace (PTRACE_GETTRACESIG, inferior_pid,
148 (PTRACE_ARG3_TYPE) 0, 0);
149
150 if (realsig == SIGNEWTHREAD)
151 {
152 /* It's a new thread notification. Nothing to do here since
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. */
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
185 void
186 myresume (int step, int signal)
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
207 static int regmap[] =
208 {
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
225 that they are useful. */
226 };
227 #endif
228
229 #ifdef M68K
230 /* Mappings from tm-m68k.h */
231
232 static int regmap[] =
233 {
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 */
249 0, /* sp */
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 */
267 };
268 #endif
269
270 #ifdef SPARC
271 /* Mappings from tm-sparc.h */
272
273 #define FX(ENTRY)(offsetof(struct fcontext, ENTRY))
274
275 static int regmap[] =
276 {
277 -1, /* g0 */
278 X (g1),
279 X (g2),
280 X (g3),
281 X (g4),
282 -1, /* g5->g7 aren't saved by Lynx */
283 -1,
284 -1,
285
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 */
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
349 void
350 fetch_inferior_registers (int regno)
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 {
370 struct econtext ec; /* general regs */
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),
378 (PTRACE_ARG3_TYPE) & ec,
379 0);
380 if (errno)
381 perror_with_name ("Sparc fetch_inferior_registers(ptrace)");
382
383 memset (buf, 0, REGISTER_RAW_SIZE (G0_REGNUM));
384 supply_register (G0_REGNUM, buf);
385 supply_register (TBR_REGNUM, (char *) &ec.tbr);
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
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);
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,
412 &registers[REGISTER_BYTE (I0_REGNUM)],
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,
418 &registers[REGISTER_BYTE (L0_REGNUM)],
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 {
426 struct fcontext fc; /* fp regs */
427 int retval;
428 int i;
429
430 errno = 0;
431 retval = ptrace (PTRACE_GETFPREGS, BUILDPID (inferior_pid, general_thread), (PTRACE_ARG3_TYPE) & fc,
432 0);
433 if (errno)
434 perror_with_name ("Sparc fetch_inferior_registers(ptrace)");
435
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
441 supply_register (FPS_REGNUM, (char *) &fc.fsr);
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
453 void
454 store_inferior_registers (int regno)
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 {
472 struct econtext ec; /* general regs */
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;
489 retval = ptrace (PTRACE_SETREGS, BUILDPID (inferior_pid, general_thread), (PTRACE_ARG3_TYPE) & ec,
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 {
504 if (!register_valid[L0_REGNUM + 5])
505 abort ();
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])
517 abort ();
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 {
531 struct fcontext fc; /* fp regs */
532 int retval;
533
534 /* We read fcontext first so that we can get good values for fq_t... */
535 errno = 0;
536 retval = ptrace (PTRACE_GETFPREGS, BUILDPID (inferior_pid, general_thread), (PTRACE_ARG3_TYPE) & fc,
537 0);
538 if (errno)
539 perror_with_name ("Sparc fetch_inferior_registers(ptrace)");
540
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;
547 retval = ptrace (PTRACE_SETFPREGS, BUILDPID (inferior_pid, general_thread), (PTRACE_ARG3_TYPE) & fc,
548 0);
549 if (errno)
550 perror_with_name ("Sparc fetch_inferior_registers(ptrace)");
551 }
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
561 static unsigned long
562 lynx_registers_addr (void)
563 {
564 CORE_ADDR stblock;
565 int ecpoff = offsetof (st_t, ecp);
566 CORE_ADDR ecp;
567
568 errno = 0;
569 stblock = (CORE_ADDR) ptrace (PTRACE_THREADUSER, BUILDPID (inferior_pid, general_thread),
570 (PTRACE_ARG3_TYPE) 0, 0);
571 if (errno)
572 perror_with_name ("PTRACE_THREADUSER");
573
574 ecp = (CORE_ADDR) ptrace (PTRACE_PEEKTHREAD, BUILDPID (inferior_pid, general_thread),
575 (PTRACE_ARG3_TYPE) ecpoff, 0);
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
586 void
587 fetch_inferior_registers (int ignored)
588 {
589 int regno;
590 unsigned long reg;
591 unsigned long ecp;
592
593 ecp = lynx_registers_addr ();
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)");
608
609 *(unsigned long *) &registers[REGISTER_BYTE (regno)] = reg;
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
617 void
618 store_inferior_registers (int ignored)
619 {
620 int regno;
621 unsigned long reg;
622 unsigned long ecp;
623
624 ecp = lynx_registers_addr ();
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
634 reg = *(unsigned long *) &registers[REGISTER_BYTE (regno)];
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
655 void
656 read_inferior_memory (CORE_ADDR memaddr, char *myaddr, int len)
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
682 int
683 write_inferior_memory (CORE_ADDR memaddr, char *myaddr, int len)
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 {
720 fprintf (stderr, "\
721 ptrace (PTRACE_POKETEXT): errno=%d, pid=0x%x, addr=0x%x, buffer[i] = 0x%x\n",
722 errno, BUILDPID (inferior_pid, general_thread),
723 addr, buffer[i]);
724 fprintf (stderr, "Sleeping for 1 second\n");
725 sleep (1);
726 }
727 else
728 break;
729 }
730 }
731
732 return 0;
733 }
734 \f
735 void
736 initialize_low (void)
737 {
738 }
This page took 0.046021 seconds and 4 git commands to generate.