* config/tc-alpha.c (O_samegp): New.
[external/binutils.git] / gdb / gdbserver / linux-low.c
1 /* Low level interface to ptrace, for the remote server for GDB.
2    Copyright 1995, 1996, 1998, 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 <sys/wait.h>
24
25 #include <stdio.h>
26 #include <sys/param.h>
27 #include <sys/dir.h>
28 #include <sys/ptrace.h>
29 #include <sys/user.h>
30 #include <signal.h>
31 #include <sys/ioctl.h>
32 #include <fcntl.h>
33 #include <string.h>
34
35 /***************Begin MY defs*********************/
36 static char my_registers[REGISTER_BYTES];
37 char *registers = my_registers;
38 /***************End MY defs*********************/
39
40 #ifdef HAVE_SYS_REG_H
41 #include <sys/reg.h>
42 #endif
43
44 #define PTRACE_ARG3_TYPE long
45 #define PTRACE_XFER_TYPE int
46
47 extern int errno;
48
49 static void initialize_arch (void);
50
51 /* Start an inferior process and returns its pid.
52    ALLARGS is a vector of program-name and args. */
53
54 int
55 create_inferior (char *program, char **allargs)
56 {
57   int pid;
58
59   pid = fork ();
60   if (pid < 0)
61     perror_with_name ("fork");
62
63   if (pid == 0)
64     {
65       ptrace (PTRACE_TRACEME, 0, 0, 0);
66
67       execv (program, allargs);
68
69       fprintf (stderr, "Cannot exec %s: %s.\n", program,
70                strerror (errno));
71       fflush (stderr);
72       _exit (0177);
73     }
74
75   return pid;
76 }
77
78 /* Attach to an inferior process.  */
79
80 int
81 myattach (int pid)
82 {
83   if (ptrace (PTRACE_ATTACH, pid, 0, 0) != 0)
84     {
85       fprintf (stderr, "Cannot attach to process %d: %s (%d)\n", pid,
86                errno < sys_nerr ? sys_errlist[errno] : "unknown error",
87                errno);
88       fflush (stderr);
89       _exit (0177);
90     }
91
92   return 0;
93 }
94
95 /* Kill the inferior process.  Make us have no inferior.  */
96
97 void
98 kill_inferior (void)
99 {
100   if (inferior_pid == 0)
101     return;
102   ptrace (PTRACE_KILL, inferior_pid, 0, 0);
103   wait (0);
104 }
105
106 /* Return nonzero if the given thread is still alive.  */
107 int
108 mythread_alive (int pid)
109 {
110   return 1;
111 }
112
113 /* Wait for process, returns status */
114
115 unsigned char
116 mywait (char *status)
117 {
118   int pid;
119   union wait w;
120
121   enable_async_io ();
122   pid = waitpid (inferior_pid, (int *)&w, 0);
123   disable_async_io ();
124   if (pid != inferior_pid)
125     perror_with_name ("wait");
126
127   if (WIFEXITED (w))
128     {
129       fprintf (stderr, "\nChild exited with retcode = %x \n", WEXITSTATUS (w));
130       *status = 'W';
131       return ((unsigned char) WEXITSTATUS (w));
132     }
133   else if (!WIFSTOPPED (w))
134     {
135       fprintf (stderr, "\nChild terminated with signal = %x \n", WTERMSIG (w));
136       *status = 'X';
137       return ((unsigned char) WTERMSIG (w));
138     }
139
140   fetch_inferior_registers (0);
141
142   *status = 'T';
143   return ((unsigned char) WSTOPSIG (w));
144 }
145
146 /* Resume execution of the inferior process.
147    If STEP is nonzero, single-step it.
148    If SIGNAL is nonzero, give it that signal.  */
149
150 void
151 myresume (int step, int signal)
152 {
153   errno = 0;
154   ptrace (step ? PTRACE_SINGLESTEP : PTRACE_CONT, inferior_pid, 1, signal);
155   if (errno)
156     perror_with_name ("ptrace");
157 }
158
159
160 #if !defined (offsetof)
161 #define offsetof(TYPE, MEMBER) ((unsigned long) &((TYPE *)0)->MEMBER)
162 #endif
163
164 /* U_REGS_OFFSET is the offset of the registers within the u area.  */
165 #if !defined (U_REGS_OFFSET)
166 #define U_REGS_OFFSET \
167   ptrace (PT_READ_U, inferior_pid, \
168           (PTRACE_ARG3_TYPE) (offsetof (struct user, u_ar0)), 0) \
169     - KERNEL_U_ADDR
170 #endif
171
172 #ifdef I386_GNULINUX_TARGET
173 /* This module only supports access to the general purpose registers.
174    Adjust the relevant constants accordingly.
175
176    FIXME: kettenis/2001-03-28: We should really use PTRACE_GETREGS to
177    get at the registers.  Better yet, we should try to share code with
178    i386-linux-nat.c.  */
179 #undef NUM_FREGS
180 #define NUM_FREGS 0
181 #undef NUM_REGS
182 #define NUM_REGS NUM_GREGS
183
184 /* This stuff comes from i386-tdep.c.  */
185
186 /* i386_register_byte[i] is the offset into the register file of the
187    start of register number i.  We initialize this from
188    i386_register_raw_size.  */
189 int i386_register_byte[MAX_NUM_REGS];
190
191 /* i386_register_raw_size[i] is the number of bytes of storage in
192    GDB's register array occupied by register i.  */
193 int i386_register_raw_size[MAX_NUM_REGS] = {
194    4,  4,  4,  4,
195    4,  4,  4,  4,
196    4,  4,  4,  4,
197    4,  4,  4,  4,
198   10, 10, 10, 10,
199   10, 10, 10, 10,
200    4,  4,  4,  4,
201    4,  4,  4,  4,
202   16, 16, 16, 16,
203   16, 16, 16, 16,
204    4
205 };
206
207 static void
208 initialize_arch (void)
209 {
210   /* Initialize the table saying where each register starts in the
211      register file.  */
212   {
213     int i, offset;
214
215     offset = 0;
216     for (i = 0; i < MAX_NUM_REGS; i++)
217       {
218         i386_register_byte[i] = offset;
219         offset += i386_register_raw_size[i];
220       }
221   }
222 }
223
224 /* This stuff comes from i386-linux-nat.c.  */
225
226 /* Mapping between the general-purpose registers in `struct user'
227    format and GDB's register array layout.  */
228 static int regmap[] = 
229 {
230   EAX, ECX, EDX, EBX,
231   UESP, EBP, ESI, EDI,
232   EIP, EFL, CS, SS,
233   DS, ES, FS, GS
234 };
235
236 /* Return the address of register REGNUM.  BLOCKEND is the value of
237    u.u_ar0, which should point to the registers.  */
238
239 CORE_ADDR
240 register_u_addr (CORE_ADDR blockend, int regnum)
241 {
242   return (blockend + 4 * regmap[regnum]);
243 }
244 #elif defined(TARGET_M68K)
245 static void
246 initialize_arch (void)
247 {
248   return;
249 }
250
251 /* This table must line up with REGISTER_NAMES in tm-m68k.h */
252 static int regmap[] =
253 {
254 #ifdef PT_D0
255   PT_D0, PT_D1, PT_D2, PT_D3, PT_D4, PT_D5, PT_D6, PT_D7,
256   PT_A0, PT_A1, PT_A2, PT_A3, PT_A4, PT_A5, PT_A6, PT_USP,
257   PT_SR, PT_PC,
258 #else
259   14, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 15,
260   17, 18,
261 #endif
262 #ifdef PT_FP0
263   PT_FP0, PT_FP1, PT_FP2, PT_FP3, PT_FP4, PT_FP5, PT_FP6, PT_FP7,
264   PT_FPCR, PT_FPSR, PT_FPIAR
265 #else
266   21, 24, 27, 30, 33, 36, 39, 42, 45, 46, 47
267 #endif
268 };
269
270 /* BLOCKEND is the value of u.u_ar0, and points to the place where GS
271    is stored.  */
272
273 int
274 m68k_linux_register_u_addr (int blockend, int regnum)
275 {
276   return (blockend + 4 * regmap[regnum]);
277 }
278 #elif defined(IA64_GNULINUX_TARGET)
279 #undef NUM_FREGS
280 #define NUM_FREGS 0
281
282 #include <asm/ptrace_offsets.h>
283
284 static int u_offsets[] =
285   {
286     /* general registers */
287     -1,         /* gr0 not available; i.e, it's always zero */
288     PT_R1,
289     PT_R2,
290     PT_R3,
291     PT_R4,
292     PT_R5,
293     PT_R6,
294     PT_R7,
295     PT_R8,
296     PT_R9,
297     PT_R10,
298     PT_R11,
299     PT_R12,
300     PT_R13,
301     PT_R14,
302     PT_R15,
303     PT_R16,
304     PT_R17,
305     PT_R18,
306     PT_R19,
307     PT_R20,
308     PT_R21,
309     PT_R22,
310     PT_R23,
311     PT_R24,
312     PT_R25,
313     PT_R26,
314     PT_R27,
315     PT_R28,
316     PT_R29,
317     PT_R30,
318     PT_R31,
319     /* gr32 through gr127 not directly available via the ptrace interface */
320     -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
321     -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
322     -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
323     -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
324     -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
325     -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
326     /* Floating point registers */
327     -1, -1,     /* f0 and f1 not available (f0 is +0.0 and f1 is +1.0) */
328     PT_F2,
329     PT_F3,
330     PT_F4,
331     PT_F5,
332     PT_F6,
333     PT_F7,
334     PT_F8,
335     PT_F9,
336     PT_F10,
337     PT_F11,
338     PT_F12,
339     PT_F13,
340     PT_F14,
341     PT_F15,
342     PT_F16,
343     PT_F17,
344     PT_F18,
345     PT_F19,
346     PT_F20,
347     PT_F21,
348     PT_F22,
349     PT_F23,
350     PT_F24,
351     PT_F25,
352     PT_F26,
353     PT_F27,
354     PT_F28,
355     PT_F29,
356     PT_F30,
357     PT_F31,
358     PT_F32,
359     PT_F33,
360     PT_F34,
361     PT_F35,
362     PT_F36,
363     PT_F37,
364     PT_F38,
365     PT_F39,
366     PT_F40,
367     PT_F41,
368     PT_F42,
369     PT_F43,
370     PT_F44,
371     PT_F45,
372     PT_F46,
373     PT_F47,
374     PT_F48,
375     PT_F49,
376     PT_F50,
377     PT_F51,
378     PT_F52,
379     PT_F53,
380     PT_F54,
381     PT_F55,
382     PT_F56,
383     PT_F57,
384     PT_F58,
385     PT_F59,
386     PT_F60,
387     PT_F61,
388     PT_F62,
389     PT_F63,
390     PT_F64,
391     PT_F65,
392     PT_F66,
393     PT_F67,
394     PT_F68,
395     PT_F69,
396     PT_F70,
397     PT_F71,
398     PT_F72,
399     PT_F73,
400     PT_F74,
401     PT_F75,
402     PT_F76,
403     PT_F77,
404     PT_F78,
405     PT_F79,
406     PT_F80,
407     PT_F81,
408     PT_F82,
409     PT_F83,
410     PT_F84,
411     PT_F85,
412     PT_F86,
413     PT_F87,
414     PT_F88,
415     PT_F89,
416     PT_F90,
417     PT_F91,
418     PT_F92,
419     PT_F93,
420     PT_F94,
421     PT_F95,
422     PT_F96,
423     PT_F97,
424     PT_F98,
425     PT_F99,
426     PT_F100,
427     PT_F101,
428     PT_F102,
429     PT_F103,
430     PT_F104,
431     PT_F105,
432     PT_F106,
433     PT_F107,
434     PT_F108,
435     PT_F109,
436     PT_F110,
437     PT_F111,
438     PT_F112,
439     PT_F113,
440     PT_F114,
441     PT_F115,
442     PT_F116,
443     PT_F117,
444     PT_F118,
445     PT_F119,
446     PT_F120,
447     PT_F121,
448     PT_F122,
449     PT_F123,
450     PT_F124,
451     PT_F125,
452     PT_F126,
453     PT_F127,
454     /* predicate registers - we don't fetch these individually */
455     -1, -1, -1, -1, -1, -1, -1, -1,
456     -1, -1, -1, -1, -1, -1, -1, -1,
457     -1, -1, -1, -1, -1, -1, -1, -1,
458     -1, -1, -1, -1, -1, -1, -1, -1,
459     -1, -1, -1, -1, -1, -1, -1, -1,
460     -1, -1, -1, -1, -1, -1, -1, -1,
461     -1, -1, -1, -1, -1, -1, -1, -1,
462     -1, -1, -1, -1, -1, -1, -1, -1,
463     /* branch registers */
464     PT_B0,
465     PT_B1,
466     PT_B2,
467     PT_B3,
468     PT_B4,
469     PT_B5,
470     PT_B6,
471     PT_B7,
472     /* virtual frame pointer and virtual return address pointer */
473     -1, -1,
474     /* other registers */
475     PT_PR,
476     PT_CR_IIP,  /* ip */
477     PT_CR_IPSR, /* psr */
478     PT_CFM,     /* cfm */
479     /* kernel registers not visible via ptrace interface (?) */
480     -1, -1, -1, -1, -1, -1, -1, -1,
481     /* hole */
482     -1, -1, -1, -1, -1, -1, -1, -1,
483     PT_AR_RSC,
484     PT_AR_BSP,
485     PT_AR_BSPSTORE,
486     PT_AR_RNAT,
487     -1,
488     -1,         /* Not available: FCR, IA32 floating control register */
489     -1, -1,
490     -1,         /* Not available: EFLAG */
491     -1,         /* Not available: CSD */
492     -1,         /* Not available: SSD */
493     -1,         /* Not available: CFLG */
494     -1,         /* Not available: FSR */
495     -1,         /* Not available: FIR */
496     -1,         /* Not available: FDR */
497     -1,
498     PT_AR_CCV,
499     -1, -1, -1,
500     PT_AR_UNAT,
501     -1, -1, -1,
502     PT_AR_FPSR,
503     -1, -1, -1,
504     -1,         /* Not available: ITC */
505     -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
506     -1, -1, -1, -1, -1, -1, -1, -1, -1,
507     PT_AR_PFS,
508     PT_AR_LC,
509     -1,         /* Not available: EC, the Epilog Count register */
510     -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
511     -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
512     -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
513     -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
514     -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
515     -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
516     -1,
517     /* nat bits - not fetched directly; instead we obtain these bits from
518        either rnat or unat or from memory. */
519     -1, -1, -1, -1, -1, -1, -1, -1,
520     -1, -1, -1, -1, -1, -1, -1, -1,
521     -1, -1, -1, -1, -1, -1, -1, -1,
522     -1, -1, -1, -1, -1, -1, -1, -1,
523     -1, -1, -1, -1, -1, -1, -1, -1,
524     -1, -1, -1, -1, -1, -1, -1, -1,
525     -1, -1, -1, -1, -1, -1, -1, -1,
526     -1, -1, -1, -1, -1, -1, -1, -1,
527     -1, -1, -1, -1, -1, -1, -1, -1,
528     -1, -1, -1, -1, -1, -1, -1, -1,
529     -1, -1, -1, -1, -1, -1, -1, -1,
530     -1, -1, -1, -1, -1, -1, -1, -1,
531     -1, -1, -1, -1, -1, -1, -1, -1,
532     -1, -1, -1, -1, -1, -1, -1, -1,
533     -1, -1, -1, -1, -1, -1, -1, -1,
534     -1, -1, -1, -1, -1, -1, -1, -1,
535   };
536
537 int
538 ia64_register_u_addr (int blockend, int regnum)
539 {
540   int addr;
541
542   if (regnum < 0 || regnum >= NUM_REGS)
543     error ("Invalid register number %d.", regnum);
544
545   addr = u_offsets[regnum];
546   if (addr == -1)
547     addr = 0;
548
549   return addr;
550 }
551
552 static void
553 initialize_arch (void)
554 {
555   return;
556 }
557
558 #elif defined(ARM_GNULINUX_TARGET)
559 int arm_register_u_addr(blockend, regnum)
560      int blockend;
561      int regnum;
562 {
563   return blockend + REGISTER_BYTE(regnum);  
564 }
565
566 static void
567 initialize_arch ()
568 {
569 }
570 #endif
571
572 CORE_ADDR
573 register_addr (int regno, CORE_ADDR blockend)
574 {
575   CORE_ADDR addr;
576
577   if (regno < 0 || regno >= NUM_REGS)
578     error ("Invalid register number %d.", regno);
579
580   REGISTER_U_ADDR (addr, blockend, regno);
581
582   return addr;
583 }
584
585 /* Fetch one register.  */
586
587 static void
588 fetch_register (int regno)
589 {
590   CORE_ADDR regaddr;
591   register int i;
592
593   /* Offset of registers within the u area.  */
594   unsigned int offset;
595
596   offset = U_REGS_OFFSET;
597
598   regaddr = register_addr (regno, offset);
599   for (i = 0; i < REGISTER_RAW_SIZE (regno); i += sizeof (PTRACE_XFER_TYPE))
600     {
601       errno = 0;
602       *(PTRACE_XFER_TYPE *) &registers[REGISTER_BYTE (regno) + i] =
603         ptrace (PTRACE_PEEKUSER, inferior_pid, (PTRACE_ARG3_TYPE) regaddr, 0);
604       regaddr += sizeof (PTRACE_XFER_TYPE);
605       if (errno != 0)
606         {
607           /* Warning, not error, in case we are attached; sometimes the
608              kernel doesn't let us at the registers.  */
609           char *err = strerror (errno);
610           char *msg = alloca (strlen (err) + 128);
611           sprintf (msg, "reading register %d: %s", regno, err);
612           error (msg);
613           goto error_exit;
614         }
615     }
616 error_exit:;
617 }
618
619 /* Fetch all registers, or just one, from the child process.  */
620
621 void
622 fetch_inferior_registers (int regno)
623 {
624   if (regno == -1 || regno == 0)
625     for (regno = 0; regno < NUM_REGS - NUM_FREGS; regno++)
626       fetch_register (regno);
627   else
628     fetch_register (regno);
629 }
630
631 /* Store our register values back into the inferior.
632    If REGNO is -1, do this for all registers.
633    Otherwise, REGNO specifies which register (so we can save time).  */
634
635 void
636 store_inferior_registers (int regno)
637 {
638   CORE_ADDR regaddr;
639   int i;
640   unsigned int offset = U_REGS_OFFSET;
641
642   if (regno >= 0)
643     {
644 #if 0
645       if (CANNOT_STORE_REGISTER (regno))
646         return;
647 #endif
648       regaddr = register_addr (regno, offset);
649       errno = 0;
650 #if 0
651       if (regno == PCOQ_HEAD_REGNUM || regno == PCOQ_TAIL_REGNUM)
652         {
653           scratch = *(int *) &registers[REGISTER_BYTE (regno)] | 0x3;
654           ptrace (PT_WUREGS, inferior_pid, (PTRACE_ARG3_TYPE) regaddr,
655                   scratch, 0);
656           if (errno != 0)
657             {
658               /* Error, even if attached.  Failing to write these two
659                  registers is pretty serious.  */
660               sprintf (buf, "writing register number %d", regno);
661               perror_with_name (buf);
662             }
663         }
664       else
665 #endif
666         for (i = 0; i < REGISTER_RAW_SIZE (regno); i += sizeof (int))
667           {
668             errno = 0;
669             ptrace (PTRACE_POKEUSER, inferior_pid, (PTRACE_ARG3_TYPE) regaddr,
670                     *(int *) &registers[REGISTER_BYTE (regno) + i]);
671             if (errno != 0)
672               {
673                 /* Warning, not error, in case we are attached; sometimes the
674                    kernel doesn't let us at the registers.  */
675                 char *err = strerror (errno);
676                 char *msg = alloca (strlen (err) + 128);
677                 sprintf (msg, "writing register %d: %s",
678                          regno, err);
679                 error (msg);
680                 return;
681               }
682             regaddr += sizeof (int);
683           }
684     }
685   else
686     for (regno = 0; regno < NUM_REGS - NUM_FREGS; regno++)
687       store_inferior_registers (regno);
688 }
689
690 /* NOTE! I tried using PTRACE_READDATA, etc., to read and write memory
691    in the NEW_SUN_PTRACE case.
692    It ought to be straightforward.  But it appears that writing did
693    not write the data that I specified.  I cannot understand where
694    it got the data that it actually did write.  */
695
696 /* Copy LEN bytes from inferior's memory starting at MEMADDR
697    to debugger memory starting at MYADDR.  */
698
699 void
700 read_inferior_memory (CORE_ADDR memaddr, char *myaddr, int len)
701 {
702   register int i;
703   /* Round starting address down to longword boundary.  */
704   register CORE_ADDR addr = memaddr & -(CORE_ADDR) sizeof (PTRACE_XFER_TYPE);
705   /* Round ending address up; get number of longwords that makes.  */
706   register int count 
707     = (((memaddr + len) - addr) + sizeof (PTRACE_XFER_TYPE) - 1) 
708       / sizeof (PTRACE_XFER_TYPE);
709   /* Allocate buffer of that many longwords.  */
710   register PTRACE_XFER_TYPE *buffer 
711     = (PTRACE_XFER_TYPE *) alloca (count * sizeof (PTRACE_XFER_TYPE));
712
713   /* Read all the longwords */
714   for (i = 0; i < count; i++, addr += sizeof (PTRACE_XFER_TYPE))
715     {
716       buffer[i] = ptrace (PTRACE_PEEKTEXT, inferior_pid, (PTRACE_ARG3_TYPE) addr, 0);
717     }
718
719   /* Copy appropriate bytes out of the buffer.  */
720   memcpy (myaddr, (char *) buffer + (memaddr & (sizeof (PTRACE_XFER_TYPE) - 1)), len);
721 }
722
723 /* Copy LEN bytes of data from debugger memory at MYADDR
724    to inferior's memory at MEMADDR.
725    On failure (cannot write the inferior)
726    returns the value of errno.  */
727
728 int
729 write_inferior_memory (CORE_ADDR memaddr, char *myaddr, int len)
730 {
731   register int i;
732   /* Round starting address down to longword boundary.  */
733   register CORE_ADDR addr = memaddr & -(CORE_ADDR) sizeof (PTRACE_XFER_TYPE);
734   /* Round ending address up; get number of longwords that makes.  */
735   register int count
736   = (((memaddr + len) - addr) + sizeof (PTRACE_XFER_TYPE) - 1) / sizeof (PTRACE_XFER_TYPE);
737   /* Allocate buffer of that many longwords.  */
738   register PTRACE_XFER_TYPE *buffer = (PTRACE_XFER_TYPE *) alloca (count * sizeof (PTRACE_XFER_TYPE));
739   extern int errno;
740
741   /* Fill start and end extra bytes of buffer with existing memory data.  */
742
743   buffer[0] = ptrace (PTRACE_PEEKTEXT, inferior_pid,
744                       (PTRACE_ARG3_TYPE) addr, 0);
745
746   if (count > 1)
747     {
748       buffer[count - 1]
749         = ptrace (PTRACE_PEEKTEXT, inferior_pid,
750                   (PTRACE_ARG3_TYPE) (addr + (count - 1)
751                                       * sizeof (PTRACE_XFER_TYPE)),
752                   0);
753     }
754
755   /* Copy data to be written over corresponding part of buffer */
756
757   memcpy ((char *) buffer + (memaddr & (sizeof (PTRACE_XFER_TYPE) - 1)), myaddr, len);
758
759   /* Write the entire buffer.  */
760
761   for (i = 0; i < count; i++, addr += sizeof (PTRACE_XFER_TYPE))
762     {
763       errno = 0;
764       ptrace (PTRACE_POKETEXT, inferior_pid, (PTRACE_ARG3_TYPE) addr, buffer[i]);
765       if (errno)
766         return errno;
767     }
768
769   return 0;
770 }
771 \f
772 void
773 initialize_low (void)
774 {
775   initialize_arch ();
776 }