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