]> Git Repo - binutils.git/blob - gdb/gdbserver/low-lynx.c
import gdb-1999-11-01 snapshot
[binutils.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., 59 Temple Place - Suite 330,
19    Boston, MA 02111-1307, USA.  */
20
21 #include "server.h"
22 #include "frame.h"
23 #include "inferior.h"
24
25 #include <stdio.h>
26 #include <sys/param.h>
27 #include <sys/dir.h>
28 #define LYNXOS
29 #include <sys/mem.h>
30 #include <sys/signal.h>
31 #include <sys/file.h>
32 #include <sys/kernel.h>
33 #ifndef __LYNXOS
34 #define __LYNXOS
35 #endif
36 #include <sys/itimer.h>
37 #include <sys/time.h>
38 #include <sys/resource.h>
39 #include <sys/proc.h>
40 #include <signal.h>
41 #include <sys/ioctl.h>
42 #include <sgtty.h>
43 #include <fcntl.h>
44 #include <sys/wait.h>
45 #include <sys/fpp.h>
46
47 static char my_registers[REGISTER_BYTES];
48 char *registers = my_registers;
49
50 #include <sys/ptrace.h>
51
52 /* Start an inferior process and returns its pid.
53    ALLARGS is a vector of program-name and args. */
54
55 int
56 create_inferior (program, allargs)
57      char *program;
58      char **allargs;
59 {
60   int pid;
61
62   pid = fork ();
63   if (pid < 0)
64     perror_with_name ("fork");
65
66   if (pid == 0)
67     {
68       int pgrp;
69
70       /* Switch child to it's own process group so that signals won't
71          directly affect gdbserver. */
72
73       pgrp = getpid ();
74       setpgrp (0, pgrp);
75       ioctl (0, TIOCSPGRP, &pgrp);
76
77       ptrace (PTRACE_TRACEME, 0, (PTRACE_ARG3_TYPE) 0, 0);
78
79       execv (program, allargs);
80
81       fprintf (stderr, "GDBserver (process %d):  Cannot exec %s: %s.\n",
82                getpid (), program,
83                errno < sys_nerr ? sys_errlist[errno] : "unknown error");
84       fflush (stderr);
85       _exit (0177);
86     }
87
88   return pid;
89 }
90
91 /* Kill the inferior process.  Make us have no inferior.  */
92
93 void
94 kill_inferior ()
95 {
96   if (inferior_pid == 0)
97     return;
98   ptrace (PTRACE_KILL, inferior_pid, 0, 0);
99   wait (0);
100
101   inferior_pid = 0;
102 }
103
104 /* Return nonzero if the given thread is still alive.  */
105 int
106 mythread_alive (pid)
107      int pid;
108 {
109   /* Arggh.  Apparently pthread_kill only works for threads within
110      the process that calls pthread_kill.
111
112      We want to avoid the lynx signal extensions as they simply don't
113      map well to the generic gdb interface we want to keep.
114
115      All we want to do is determine if a particular thread is alive;
116      it appears as if we can just make a harmless thread specific
117      ptrace call to do that.  */
118   return (ptrace (PTRACE_THREADUSER,
119                   BUILDPID (PIDGET (inferior_pid), pid), 0, 0) != -1);
120 }
121
122 /* Wait for process, returns status */
123
124 unsigned char
125 mywait (status)
126      char *status;
127 {
128   int pid;
129   union wait w;
130
131   while (1)
132     {
133       enable_async_io ();
134
135       pid = wait (&w);
136
137       disable_async_io ();
138
139       if (pid != PIDGET (inferior_pid))
140         perror_with_name ("wait");
141
142       thread_from_wait = w.w_tid;
143       inferior_pid = BUILDPID (inferior_pid, w.w_tid);
144
145       if (WIFSTOPPED (w)
146           && WSTOPSIG (w) == SIGTRAP)
147         {
148           int realsig;
149
150           realsig = ptrace (PTRACE_GETTRACESIG, inferior_pid,
151                             (PTRACE_ARG3_TYPE) 0, 0);
152
153           if (realsig == SIGNEWTHREAD)
154             {
155               /* It's a new thread notification.  Nothing to do here since
156                  the machine independent code in wait_for_inferior will
157                  add the thread to the thread list and restart the thread
158                  when pid != inferior_pid and pid is not in the thread list.
159                  We don't even want to muck with realsig -- the code in
160                  wait_for_inferior expects SIGTRAP.  */
161               ;
162             }
163         }
164       break;
165     }
166
167   if (WIFEXITED (w))
168     {
169       *status = 'W';
170       return ((unsigned char) WEXITSTATUS (w));
171     }
172   else if (!WIFSTOPPED (w))
173     {
174       *status = 'X';
175       return ((unsigned char) WTERMSIG (w));
176     }
177
178   fetch_inferior_registers (0);
179
180   *status = 'T';
181   return ((unsigned char) WSTOPSIG (w));
182 }
183
184 /* Resume execution of the inferior process.
185    If STEP is nonzero, single-step it.
186    If SIGNAL is nonzero, give it that signal.  */
187
188 void
189 myresume (step, signal)
190      int step;
191      int signal;
192 {
193   errno = 0;
194   ptrace (step ? PTRACE_SINGLESTEP_ONE : PTRACE_CONT,
195           BUILDPID (inferior_pid, cont_thread == -1 ? 0 : cont_thread),
196           1, signal);
197   if (errno)
198     perror_with_name ("ptrace");
199 }
200
201 #undef offsetof
202 #define offsetof(TYPE, MEMBER) ((unsigned long) &((TYPE *)0)->MEMBER)
203
204 /* Mapping between GDB register #s and offsets into econtext.  Must be
205    consistent with REGISTER_NAMES macro in various tmXXX.h files. */
206
207 #define X(ENTRY)(offsetof(struct econtext, ENTRY))
208
209 #ifdef I386
210 /* Mappings from tm-i386v.h */
211
212 static int regmap[] =
213 {
214   X (eax),
215   X (ecx),
216   X (edx),
217   X (ebx),
218   X (esp),                      /* sp */
219   X (ebp),                      /* fp */
220   X (esi),
221   X (edi),
222   X (eip),                      /* pc */
223   X (flags),                    /* ps */
224   X (cs),
225   X (ss),
226   X (ds),
227   X (es),
228   X (ecode),                    /* Lynx doesn't give us either fs or gs, so */
229   X (fault),                    /* we just substitute these two in the hopes
230                                    that they are useful. */
231 };
232 #endif
233
234 #ifdef M68K
235 /* Mappings from tm-m68k.h */
236
237 static int regmap[] =
238 {
239   X (regs[0]),                  /* d0 */
240   X (regs[1]),                  /* d1 */
241   X (regs[2]),                  /* d2 */
242   X (regs[3]),                  /* d3 */
243   X (regs[4]),                  /* d4 */
244   X (regs[5]),                  /* d5 */
245   X (regs[6]),                  /* d6 */
246   X (regs[7]),                  /* d7 */
247   X (regs[8]),                  /* a0 */
248   X (regs[9]),                  /* a1 */
249   X (regs[10]),                 /* a2 */
250   X (regs[11]),                 /* a3 */
251   X (regs[12]),                 /* a4 */
252   X (regs[13]),                 /* a5 */
253   X (regs[14]),                 /* fp */
254   0,                            /* sp */
255   X (status),                   /* ps */
256   X (pc),
257
258   X (fregs[0 * 3]),             /* fp0 */
259   X (fregs[1 * 3]),             /* fp1 */
260   X (fregs[2 * 3]),             /* fp2 */
261   X (fregs[3 * 3]),             /* fp3 */
262   X (fregs[4 * 3]),             /* fp4 */
263   X (fregs[5 * 3]),             /* fp5 */
264   X (fregs[6 * 3]),             /* fp6 */
265   X (fregs[7 * 3]),             /* fp7 */
266
267   X (fcregs[0]),                /* fpcontrol */
268   X (fcregs[1]),                /* fpstatus */
269   X (fcregs[2]),                /* fpiaddr */
270   X (ssw),                      /* fpcode */
271   X (fault),                    /* fpflags */
272 };
273 #endif
274
275 #ifdef SPARC
276 /* Mappings from tm-sparc.h */
277
278 #define FX(ENTRY)(offsetof(struct fcontext, ENTRY))
279
280 static int regmap[] =
281 {
282   -1,                           /* g0 */
283   X (g1),
284   X (g2),
285   X (g3),
286   X (g4),
287   -1,                           /* g5->g7 aren't saved by Lynx */
288   -1,
289   -1,
290
291   X (o[0]),
292   X (o[1]),
293   X (o[2]),
294   X (o[3]),
295   X (o[4]),
296   X (o[5]),
297   X (o[6]),                     /* sp */
298   X (o[7]),                     /* ra */
299
300   -1, -1, -1, -1, -1, -1, -1, -1,       /* l0 -> l7 */
301
302   -1, -1, -1, -1, -1, -1, -1, -1,       /* i0 -> i7 */
303
304   FX (f.fregs[0]),              /* f0 */
305   FX (f.fregs[1]),
306   FX (f.fregs[2]),
307   FX (f.fregs[3]),
308   FX (f.fregs[4]),
309   FX (f.fregs[5]),
310   FX (f.fregs[6]),
311   FX (f.fregs[7]),
312   FX (f.fregs[8]),
313   FX (f.fregs[9]),
314   FX (f.fregs[10]),
315   FX (f.fregs[11]),
316   FX (f.fregs[12]),
317   FX (f.fregs[13]),
318   FX (f.fregs[14]),
319   FX (f.fregs[15]),
320   FX (f.fregs[16]),
321   FX (f.fregs[17]),
322   FX (f.fregs[18]),
323   FX (f.fregs[19]),
324   FX (f.fregs[20]),
325   FX (f.fregs[21]),
326   FX (f.fregs[22]),
327   FX (f.fregs[23]),
328   FX (f.fregs[24]),
329   FX (f.fregs[25]),
330   FX (f.fregs[26]),
331   FX (f.fregs[27]),
332   FX (f.fregs[28]),
333   FX (f.fregs[29]),
334   FX (f.fregs[30]),
335   FX (f.fregs[31]),
336
337   X (y),
338   X (psr),
339   X (wim),
340   X (tbr),
341   X (pc),
342   X (npc),
343   FX (fsr),                     /* fpsr */
344   -1,                           /* cpsr */
345 };
346 #endif
347
348 #ifdef SPARC
349
350 /* This routine handles some oddball cases for Sparc registers and LynxOS.
351    In partucular, it causes refs to G0, g5->7, and all fp regs to return zero.
352    It also handles knows where to find the I & L regs on the stack.  */
353
354 void
355 fetch_inferior_registers (regno)
356      int regno;
357 {
358 #if 0
359   int whatregs = 0;
360
361 #define WHATREGS_FLOAT 1
362 #define WHATREGS_GEN 2
363 #define WHATREGS_STACK 4
364
365   if (regno == -1)
366     whatregs = WHATREGS_FLOAT | WHATREGS_GEN | WHATREGS_STACK;
367   else if (regno >= L0_REGNUM && regno <= I7_REGNUM)
368     whatregs = WHATREGS_STACK;
369   else if (regno >= FP0_REGNUM && regno < FP0_REGNUM + 32)
370     whatregs = WHATREGS_FLOAT;
371   else
372     whatregs = WHATREGS_GEN;
373
374   if (whatregs & WHATREGS_GEN)
375     {
376       struct econtext ec;       /* general regs */
377       char buf[MAX_REGISTER_RAW_SIZE];
378       int retval;
379       int i;
380
381       errno = 0;
382       retval = ptrace (PTRACE_GETREGS,
383                        BUILDPID (inferior_pid, general_thread),
384                        (PTRACE_ARG3_TYPE) & ec,
385                        0);
386       if (errno)
387         perror_with_name ("Sparc fetch_inferior_registers(ptrace)");
388
389       memset (buf, 0, REGISTER_RAW_SIZE (G0_REGNUM));
390       supply_register (G0_REGNUM, buf);
391       supply_register (TBR_REGNUM, (char *) &ec.tbr);
392
393       memcpy (&registers[REGISTER_BYTE (G1_REGNUM)], &ec.g1,
394               4 * REGISTER_RAW_SIZE (G1_REGNUM));
395       for (i = G1_REGNUM; i <= G1_REGNUM + 3; i++)
396         register_valid[i] = 1;
397
398       supply_register (PS_REGNUM, (char *) &ec.psr);
399       supply_register (Y_REGNUM, (char *) &ec.y);
400       supply_register (PC_REGNUM, (char *) &ec.pc);
401       supply_register (NPC_REGNUM, (char *) &ec.npc);
402       supply_register (WIM_REGNUM, (char *) &ec.wim);
403
404       memcpy (&registers[REGISTER_BYTE (O0_REGNUM)], ec.o,
405               8 * REGISTER_RAW_SIZE (O0_REGNUM));
406       for (i = O0_REGNUM; i <= O0_REGNUM + 7; i++)
407         register_valid[i] = 1;
408     }
409
410   if (whatregs & WHATREGS_STACK)
411     {
412       CORE_ADDR sp;
413       int i;
414
415       sp = read_register (SP_REGNUM);
416
417       target_xfer_memory (sp + FRAME_SAVED_I0,
418                           &registers[REGISTER_BYTE (I0_REGNUM)],
419                           8 * REGISTER_RAW_SIZE (I0_REGNUM), 0);
420       for (i = I0_REGNUM; i <= I7_REGNUM; i++)
421         register_valid[i] = 1;
422
423       target_xfer_memory (sp + FRAME_SAVED_L0,
424                           &registers[REGISTER_BYTE (L0_REGNUM)],
425                           8 * REGISTER_RAW_SIZE (L0_REGNUM), 0);
426       for (i = L0_REGNUM; i <= L0_REGNUM + 7; i++)
427         register_valid[i] = 1;
428     }
429
430   if (whatregs & WHATREGS_FLOAT)
431     {
432       struct fcontext fc;       /* fp regs */
433       int retval;
434       int i;
435
436       errno = 0;
437       retval = ptrace (PTRACE_GETFPREGS, BUILDPID (inferior_pid, general_thread), (PTRACE_ARG3_TYPE) & fc,
438                        0);
439       if (errno)
440         perror_with_name ("Sparc fetch_inferior_registers(ptrace)");
441
442       memcpy (&registers[REGISTER_BYTE (FP0_REGNUM)], fc.f.fregs,
443               32 * REGISTER_RAW_SIZE (FP0_REGNUM));
444       for (i = FP0_REGNUM; i <= FP0_REGNUM + 31; i++)
445         register_valid[i] = 1;
446
447       supply_register (FPS_REGNUM, (char *) &fc.fsr);
448     }
449 #endif
450 }
451
452 /* This routine handles storing of the I & L regs for the Sparc.  The trick
453    here is that they actually live on the stack.  The really tricky part is
454    that when changing the stack pointer, the I & L regs must be written to
455    where the new SP points, otherwise the regs will be incorrect when the
456    process is started up again.   We assume that the I & L regs are valid at
457    this point.  */
458
459 void
460 store_inferior_registers (regno)
461      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 ()
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 (ignored)
595      int ignored;
596 {
597   int regno;
598   unsigned long reg;
599   unsigned long ecp;
600
601   ecp = lynx_registers_addr ();
602
603   for (regno = 0; regno < NUM_REGS; regno++)
604     {
605       int ptrace_fun = PTRACE_PEEKTHREAD;
606
607 #ifdef PTRACE_PEEKUSP
608       ptrace_fun = regno == SP_REGNUM ? PTRACE_PEEKUSP : PTRACE_PEEKTHREAD;
609 #endif
610
611       errno = 0;
612       reg = ptrace (ptrace_fun, BUILDPID (inferior_pid, general_thread),
613                     (PTRACE_ARG3_TYPE) (ecp + regmap[regno]), 0);
614       if (errno)
615         perror_with_name ("fetch_inferior_registers(PTRACE_PEEKTHREAD)");
616
617       *(unsigned long *) &registers[REGISTER_BYTE (regno)] = reg;
618     }
619 }
620
621 /* Store our register values back into the inferior.
622    If REGNO is -1, do this for all registers.
623    Otherwise, REGNO specifies which register (so we can save time).  */
624
625 void
626 store_inferior_registers (ignored)
627      int ignored;
628 {
629   int regno;
630   unsigned long reg;
631   unsigned long ecp;
632
633   ecp = lynx_registers_addr ();
634
635   for (regno = 0; regno < NUM_REGS; regno++)
636     {
637       int ptrace_fun = PTRACE_POKEUSER;
638
639 #ifdef PTRACE_POKEUSP
640       ptrace_fun = regno == SP_REGNUM ? PTRACE_POKEUSP : PTRACE_POKEUSER;
641 #endif
642
643       reg = *(unsigned long *) &registers[REGISTER_BYTE (regno)];
644
645       errno = 0;
646       ptrace (ptrace_fun, BUILDPID (inferior_pid, general_thread),
647               (PTRACE_ARG3_TYPE) (ecp + regmap[regno]), reg);
648       if (errno)
649         perror_with_name ("PTRACE_POKEUSER");
650     }
651 }
652
653 #endif /* ! SPARC */
654
655 /* NOTE! I tried using PTRACE_READDATA, etc., to read and write memory
656    in the NEW_SUN_PTRACE case.
657    It ought to be straightforward.  But it appears that writing did
658    not write the data that I specified.  I cannot understand where
659    it got the data that it actually did write.  */
660
661 /* Copy LEN bytes from inferior's memory starting at MEMADDR
662    to debugger memory starting at MYADDR.  */
663
664 void
665 read_inferior_memory (memaddr, myaddr, len)
666      CORE_ADDR memaddr;
667      char *myaddr;
668      int len;
669 {
670   register int i;
671   /* Round starting address down to longword boundary.  */
672   register CORE_ADDR addr = memaddr & -sizeof (int);
673   /* Round ending address up; get number of longwords that makes.  */
674   register int count
675   = (((memaddr + len) - addr) + sizeof (int) - 1) / sizeof (int);
676   /* Allocate buffer of that many longwords.  */
677   register int *buffer = (int *) alloca (count * sizeof (int));
678
679   /* Read all the longwords */
680   for (i = 0; i < count; i++, addr += sizeof (int))
681     {
682       buffer[i] = ptrace (PTRACE_PEEKTEXT, BUILDPID (inferior_pid, general_thread), addr, 0);
683     }
684
685   /* Copy appropriate bytes out of the buffer.  */
686   memcpy (myaddr, (char *) buffer + (memaddr & (sizeof (int) - 1)), len);
687 }
688
689 /* Copy LEN bytes of data from debugger memory at MYADDR
690    to inferior's memory at MEMADDR.
691    On failure (cannot write the inferior)
692    returns the value of errno.  */
693
694 int
695 write_inferior_memory (memaddr, myaddr, len)
696      CORE_ADDR memaddr;
697      char *myaddr;
698      int len;
699 {
700   register int i;
701   /* Round starting address down to longword boundary.  */
702   register CORE_ADDR addr = memaddr & -sizeof (int);
703   /* Round ending address up; get number of longwords that makes.  */
704   register int count
705   = (((memaddr + len) - addr) + sizeof (int) - 1) / sizeof (int);
706   /* Allocate buffer of that many longwords.  */
707   register int *buffer = (int *) alloca (count * sizeof (int));
708   extern int errno;
709
710   /* Fill start and end extra bytes of buffer with existing memory data.  */
711
712   buffer[0] = ptrace (PTRACE_PEEKTEXT, BUILDPID (inferior_pid, general_thread), addr, 0);
713
714   if (count > 1)
715     {
716       buffer[count - 1]
717         = ptrace (PTRACE_PEEKTEXT, BUILDPID (inferior_pid, general_thread),
718                   addr + (count - 1) * sizeof (int), 0);
719     }
720
721   /* Copy data to be written over corresponding part of buffer */
722
723   memcpy ((char *) buffer + (memaddr & (sizeof (int) - 1)), myaddr, len);
724
725   /* Write the entire buffer.  */
726
727   for (i = 0; i < count; i++, addr += sizeof (int))
728     {
729       while (1)
730         {
731           errno = 0;
732           ptrace (PTRACE_POKETEXT, BUILDPID (inferior_pid, general_thread), addr, buffer[i]);
733           if (errno)
734             {
735               fprintf (stderr, "\
736 ptrace (PTRACE_POKETEXT): errno=%d, pid=0x%x, addr=0x%x, buffer[i] = 0x%x\n",
737                        errno, BUILDPID (inferior_pid, general_thread),
738                        addr, buffer[i]);
739               fprintf (stderr, "Sleeping for 1 second\n");
740               sleep (1);
741             }
742           else
743             break;
744         }
745     }
746
747   return 0;
748 }
This page took 0.065975 seconds and 4 git commands to generate.