import gdb-1999-11-16 snapshot
[deliverable/binutils-gdb.git] / gdb / gdbserver / low-linux.c
CommitLineData
c906108c
SS
1/* Low level interface to ptrace, for the remote server for GDB.
2 Copyright (C) 1995, 1996 Free Software Foundation, Inc.
3
c5aa993b 4 This file is part of GDB.
c906108c 5
c5aa993b
JM
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.
c906108c 10
c5aa993b
JM
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.
c906108c 15
c5aa993b
JM
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. */
c906108c
SS
20
21#include "defs.h"
22#include <sys/wait.h>
23#include "frame.h"
24#include "inferior.h"
25
26#include <stdio.h>
27#include <sys/param.h>
28#include <sys/dir.h>
5c44784c 29#include <sys/ptrace.h>
c906108c
SS
30#include <sys/user.h>
31#include <signal.h>
32#include <sys/ioctl.h>
c906108c
SS
33#include <fcntl.h>
34
35/***************Begin MY defs*********************/
36int quit_flag = 0;
5c44784c
JM
37static char my_registers[REGISTER_BYTES];
38char *registers = my_registers;
c906108c
SS
39
40/* Index within `registers' of the first byte of the space for
41 register N. */
42
43
44char buf2[MAX_REGISTER_RAW_SIZE];
45/***************End MY defs*********************/
46
5c44784c 47#ifdef HAVE_SYS_REG_H
c906108c
SS
48#include <sys/reg.h>
49#endif
50
5c44784c
JM
51/* Default the type of the ptrace transfer to int. */
52#ifndef PTRACE_XFER_TYPE
53#define PTRACE_XFER_TYPE int
54#endif
55
c906108c
SS
56extern char **environ;
57extern int errno;
58extern int inferior_pid;
59void quit (), perror_with_name ();
60int query ();
61
62/* Start an inferior process and returns its pid.
63 ALLARGS is a vector of program-name and args.
64 ENV is the environment vector to pass. */
65
66int
67create_inferior (program, allargs)
68 char *program;
69 char **allargs;
70{
71 int pid;
72
73 pid = fork ();
74 if (pid < 0)
75 perror_with_name ("fork");
76
77 if (pid == 0)
78 {
79 ptrace (PTRACE_TRACEME, 0, 0, 0);
80
81 execv (program, allargs);
82
83 fprintf (stderr, "Cannot exec %s: %s.\n", program,
84 errno < sys_nerr ? sys_errlist[errno] : "unknown error");
85 fflush (stderr);
86 _exit (0177);
87 }
88
89 return pid;
90}
91
92/* Kill the inferior process. Make us have no inferior. */
93
94void
95kill_inferior ()
96{
97 if (inferior_pid == 0)
98 return;
99 ptrace (PTRACE_KILL, inferior_pid, 0, 0);
100 wait (0);
c5aa993b 101/*************inferior_died ();****VK**************/
c906108c
SS
102}
103
104/* Return nonzero if the given thread is still alive. */
105int
106mythread_alive (pid)
107 int pid;
108{
109 return 1;
110}
111
112/* Wait for process, returns status */
113
114unsigned char
115mywait (status)
116 char *status;
117{
118 int pid;
119 union wait w;
120
121 pid = wait (&w);
122 if (pid != inferior_pid)
123 perror_with_name ("wait");
124
125 if (WIFEXITED (w))
126 {
127 fprintf (stderr, "\nChild exited with retcode = %x \n", WEXITSTATUS (w));
128 *status = 'W';
129 return ((unsigned char) WEXITSTATUS (w));
130 }
131 else if (!WIFSTOPPED (w))
132 {
133 fprintf (stderr, "\nChild terminated with signal = %x \n", WTERMSIG (w));
134 *status = 'X';
135 return ((unsigned char) WTERMSIG (w));
136 }
137
138 fetch_inferior_registers (0);
139
140 *status = 'T';
141 return ((unsigned char) WSTOPSIG (w));
142}
143
144/* Resume execution of the inferior process.
145 If STEP is nonzero, single-step it.
146 If SIGNAL is nonzero, give it that signal. */
147
148void
149myresume (step, signal)
150 int step;
151 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
5c44784c
JM
172#ifdef I386_GNULINUX_TARGET
173/* i386_register_raw_size[i] is the number of bytes of storage in the
174 actual machine representation for register i. */
175int i386_register_raw_size[MAX_NUM_REGS] = {
176 4, 4, 4, 4,
177 4, 4, 4, 4,
178 4, 4, 4, 4,
179 4, 4, 4, 4,
180 10, 10, 10, 10,
181 10, 10, 10, 10,
182 4, 4, 4, 4,
183 4, 4, 4, 4,
184 16, 16, 16, 16,
185 16, 16, 16, 16,
186 4
187};
188
189int i386_register_byte[MAX_NUM_REGS];
190
191static void
192initialize_arch()
193{
194 /* Initialize the table saying where each register starts in the
195 register file. */
196 {
197 int i, offset;
198
199 offset = 0;
200 for (i = 0; i < MAX_NUM_REGS; i++)
201 {
202 i386_register_byte[i] = offset;
203 offset += i386_register_raw_size[i];
204 }
205 }
206}
207
c906108c
SS
208/* this table must line up with REGISTER_NAMES in tm-i386v.h */
209/* symbols like 'EAX' come from <sys/reg.h> */
c5aa993b 210static int regmap[] =
c906108c
SS
211{
212 EAX, ECX, EDX, EBX,
213 UESP, EBP, ESI, EDI,
214 EIP, EFL, CS, SS,
215 DS, ES, FS, GS,
216};
217
218int
219i386_register_u_addr (blockend, regnum)
220 int blockend;
221 int regnum;
222{
223#if 0
224 /* this will be needed if fp registers are reinstated */
225 /* for now, you can look at them with 'info float'
226 * sys5 wont let you change them with ptrace anyway
227 */
c5aa993b 228 if (regnum >= FP0_REGNUM && regnum <= FP7_REGNUM)
c906108c
SS
229 {
230 int ubase, fpstate;
231 struct user u;
232 ubase = blockend + 4 * (SS + 1) - KSTKSZ;
c5aa993b 233 fpstate = ubase + ((char *) &u.u_fpstate - (char *) &u);
c906108c 234 return (fpstate + 0x1c + 10 * (regnum - FP0_REGNUM));
c5aa993b 235 }
c906108c
SS
236 else
237#endif
238 return (blockend + 4 * regmap[regnum]);
c5aa993b 239
c906108c 240}
5c44784c
JM
241#elif defined(TARGET_M68K)
242static void
243initialize_arch()
244{
245 return;
246}
247
c906108c 248/* This table must line up with REGISTER_NAMES in tm-m68k.h */
c5aa993b 249static int regmap[] =
c906108c
SS
250{
251#ifdef PT_D0
252 PT_D0, PT_D1, PT_D2, PT_D3, PT_D4, PT_D5, PT_D6, PT_D7,
253 PT_A0, PT_A1, PT_A2, PT_A3, PT_A4, PT_A5, PT_A6, PT_USP,
254 PT_SR, PT_PC,
255#else
256 14, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 15,
257 17, 18,
258#endif
259#ifdef PT_FP0
260 PT_FP0, PT_FP1, PT_FP2, PT_FP3, PT_FP4, PT_FP5, PT_FP6, PT_FP7,
261 PT_FPCR, PT_FPSR, PT_FPIAR
262#else
263 21, 24, 27, 30, 33, 36, 39, 42, 45, 46, 47
264#endif
265};
266
267/* BLOCKEND is the value of u.u_ar0, and points to the place where GS
268 is stored. */
269
270int
271m68k_linux_register_u_addr (blockend, regnum)
272 int blockend;
273 int regnum;
274{
c5aa993b 275 return (blockend + 4 * regmap[regnum]);
c906108c 276}
5c44784c
JM
277/* start-sanitize-ia64 */
278#elif defined(IA64_GNULINUX_TARGET)
279#undef NUM_FREGS
280#define NUM_FREGS 0
281
282#include <asm/ptrace_offsets.h>
283
284static 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,
4ce44c66
JM
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,
5c44784c
JM
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,
4ce44c66
JM
472 /* virtual frame pointer and virtual return address pointer */
473 -1, -1,
5c44784c
JM
474 /* other registers */
475 PT_PR,
476 PT_CR_IIP,
477 PT_CR_IPSR,
478 /* kernel registers not visible via ptrace interface (?) */
479 -1, -1, -1, -1, -1, -1, -1, -1,
480 /* hole */
481 -1, -1, -1, -1, -1, -1, -1, -1,
482 PT_AR_RSC,
483 PT_AR_BSP,
484 PT_AR_BSPSTORE,
485 PT_AR_RNAT,
486 -1,
487 -1, /* Not available: FCR, IA32 floating control register */
488 -1, -1,
489 -1, /* Not available: EFLAG */
490 -1, /* Not available: CSD */
491 -1, /* Not available: SSD */
492 -1, /* Not available: CFLG */
493 -1, /* Not available: FSR */
494 -1, /* Not available: FIR */
495 -1, /* Not available: FDR */
496 -1,
497 PT_AR_CCV,
498 -1, -1, -1,
499 PT_AR_UNAT,
500 -1, -1, -1,
501 PT_AR_FPSR,
502 -1, -1, -1,
503 -1, /* Not available: ITC */
504 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
505 -1, -1, -1, -1, -1, -1, -1, -1, -1,
11cf8741 506 PT_CR_IFS, /* was PT_AR_PFS, but it seemed bogus */
5c44784c
JM
507 PT_AR_LC,
508 -1, /* Not available: EC, the Epilog Count register */
509 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
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,
516 };
517
518int
519ia64_register_u_addr (int blockend, int regnum)
520{
521 int addr;
522
523 if (regnum < 0 || regnum >= NUM_REGS)
524 error ("Invalid register number %d.", regnum);
525
526 addr = u_offsets[regnum];
527 if (addr == -1)
528 addr = 0;
529
530 return addr;
531}
532
533initialize_arch()
534{
535 return;
536}
537/* end-sanitize-ia64 */
c906108c
SS
538#endif
539
540CORE_ADDR
541register_addr (regno, blockend)
542 int regno;
543 CORE_ADDR blockend;
544{
545 CORE_ADDR addr;
546
547 if (regno < 0 || regno >= ARCH_NUM_REGS)
548 error ("Invalid register number %d.", regno);
549
550 REGISTER_U_ADDR (addr, blockend, regno);
551
552 return addr;
553}
554
555/* Fetch one register. */
556
557static void
558fetch_register (regno)
559 int regno;
560{
5c44784c 561 CORE_ADDR regaddr;
c906108c
SS
562 register int i;
563
564 /* Offset of registers within the u area. */
565 unsigned int offset;
566
567 offset = U_REGS_OFFSET;
568
569 regaddr = register_addr (regno, offset);
5c44784c 570 for (i = 0; i < REGISTER_RAW_SIZE (regno); i += sizeof (PTRACE_XFER_TYPE))
c906108c
SS
571 {
572 errno = 0;
5c44784c
JM
573 *(PTRACE_XFER_TYPE *) &registers[REGISTER_BYTE (regno) + i] =
574 ptrace (PTRACE_PEEKUSER, inferior_pid, (PTRACE_ARG3_TYPE) regaddr, 0);
575 regaddr += sizeof (PTRACE_XFER_TYPE);
c906108c
SS
576 if (errno != 0)
577 {
578 /* Warning, not error, in case we are attached; sometimes the
579 kernel doesn't let us at the registers. */
580 char *err = strerror (errno);
581 char *msg = alloca (strlen (err) + 128);
582 sprintf (msg, "reading register %d: %s", regno, err);
583 error (msg);
584 goto error_exit;
585 }
586 }
c5aa993b 587error_exit:;
c906108c
SS
588}
589
590/* Fetch all registers, or just one, from the child process. */
591
592void
593fetch_inferior_registers (regno)
594 int regno;
595{
596 if (regno == -1 || regno == 0)
c5aa993b 597 for (regno = 0; regno < NUM_REGS - NUM_FREGS; regno++)
c906108c
SS
598 fetch_register (regno);
599 else
600 fetch_register (regno);
601}
602
603/* Store our register values back into the inferior.
604 If REGNO is -1, do this for all registers.
605 Otherwise, REGNO specifies which register (so we can save time). */
606
607void
608store_inferior_registers (regno)
609 int regno;
610{
5c44784c
JM
611 CORE_ADDR regaddr;
612 int i;
c906108c
SS
613 unsigned int offset = U_REGS_OFFSET;
614
615 if (regno >= 0)
616 {
617#if 0
618 if (CANNOT_STORE_REGISTER (regno))
619 return;
620#endif
621 regaddr = register_addr (regno, offset);
622 errno = 0;
623#if 0
624 if (regno == PCOQ_HEAD_REGNUM || regno == PCOQ_TAIL_REGNUM)
c5aa993b
JM
625 {
626 scratch = *(int *) &registers[REGISTER_BYTE (regno)] | 0x3;
627 ptrace (PT_WUREGS, inferior_pid, (PTRACE_ARG3_TYPE) regaddr,
628 scratch, 0);
629 if (errno != 0)
630 {
c906108c 631 /* Error, even if attached. Failing to write these two
c5aa993b
JM
632 registers is pretty serious. */
633 sprintf (buf, "writing register number %d", regno);
634 perror_with_name (buf);
635 }
636 }
c906108c
SS
637 else
638#endif
c5aa993b 639 for (i = 0; i < REGISTER_RAW_SIZE (regno); i += sizeof (int))
c906108c
SS
640 {
641 errno = 0;
5c44784c 642 ptrace (PTRACE_POKEUSER, inferior_pid, (PTRACE_ARG3_TYPE) regaddr,
c906108c
SS
643 *(int *) &registers[REGISTER_BYTE (regno) + i]);
644 if (errno != 0)
645 {
646 /* Warning, not error, in case we are attached; sometimes the
647 kernel doesn't let us at the registers. */
648 char *err = strerror (errno);
649 char *msg = alloca (strlen (err) + 128);
650 sprintf (msg, "writing register %d: %s",
651 regno, err);
652 error (msg);
653 return;
654 }
c5aa993b 655 regaddr += sizeof (int);
c906108c
SS
656 }
657 }
658 else
c5aa993b 659 for (regno = 0; regno < NUM_REGS - NUM_FREGS; regno++)
c906108c
SS
660 store_inferior_registers (regno);
661}
662
663/* NOTE! I tried using PTRACE_READDATA, etc., to read and write memory
664 in the NEW_SUN_PTRACE case.
665 It ought to be straightforward. But it appears that writing did
666 not write the data that I specified. I cannot understand where
667 it got the data that it actually did write. */
668
669/* Copy LEN bytes from inferior's memory starting at MEMADDR
670 to debugger memory starting at MYADDR. */
671
672void
673read_inferior_memory (memaddr, myaddr, len)
674 CORE_ADDR memaddr;
675 char *myaddr;
676 int len;
677{
678 register int i;
679 /* Round starting address down to longword boundary. */
5c44784c 680 register CORE_ADDR addr = memaddr & -sizeof (PTRACE_XFER_TYPE);
c906108c 681 /* Round ending address up; get number of longwords that makes. */
5c44784c
JM
682 register int count
683 = (((memaddr + len) - addr) + sizeof (PTRACE_XFER_TYPE) - 1)
684 / sizeof (PTRACE_XFER_TYPE);
c906108c 685 /* Allocate buffer of that many longwords. */
5c44784c
JM
686 register PTRACE_XFER_TYPE *buffer
687 = (PTRACE_XFER_TYPE *) alloca (count * sizeof (PTRACE_XFER_TYPE));
c906108c
SS
688
689 /* Read all the longwords */
5c44784c 690 for (i = 0; i < count; i++, addr += sizeof (PTRACE_XFER_TYPE))
c906108c
SS
691 {
692 buffer[i] = ptrace (PTRACE_PEEKTEXT, inferior_pid, addr, 0);
693 }
694
695 /* Copy appropriate bytes out of the buffer. */
5c44784c 696 memcpy (myaddr, (char *) buffer + (memaddr & (sizeof (PTRACE_XFER_TYPE) - 1)), len);
c906108c
SS
697}
698
699/* Copy LEN bytes of data from debugger memory at MYADDR
700 to inferior's memory at MEMADDR.
701 On failure (cannot write the inferior)
702 returns the value of errno. */
703
704int
705write_inferior_memory (memaddr, myaddr, len)
706 CORE_ADDR memaddr;
707 char *myaddr;
708 int len;
709{
710 register int i;
711 /* Round starting address down to longword boundary. */
5c44784c 712 register CORE_ADDR addr = memaddr & -sizeof (PTRACE_XFER_TYPE);
c906108c
SS
713 /* Round ending address up; get number of longwords that makes. */
714 register int count
5c44784c 715 = (((memaddr + len) - addr) + sizeof (PTRACE_XFER_TYPE) - 1) / sizeof (PTRACE_XFER_TYPE);
c906108c 716 /* Allocate buffer of that many longwords. */
5c44784c 717 register PTRACE_XFER_TYPE *buffer = (PTRACE_XFER_TYPE *) alloca (count * sizeof (PTRACE_XFER_TYPE));
c906108c
SS
718 extern int errno;
719
720 /* Fill start and end extra bytes of buffer with existing memory data. */
721
722 buffer[0] = ptrace (PTRACE_PEEKTEXT, inferior_pid, addr, 0);
723
724 if (count > 1)
725 {
726 buffer[count - 1]
727 = ptrace (PTRACE_PEEKTEXT, inferior_pid,
5c44784c 728 addr + (count - 1) * sizeof (PTRACE_XFER_TYPE), 0);
c906108c
SS
729 }
730
731 /* Copy data to be written over corresponding part of buffer */
732
5c44784c 733 memcpy ((char *) buffer + (memaddr & (sizeof (PTRACE_XFER_TYPE) - 1)), myaddr, len);
c906108c
SS
734
735 /* Write the entire buffer. */
736
5c44784c 737 for (i = 0; i < count; i++, addr += sizeof (PTRACE_XFER_TYPE))
c906108c
SS
738 {
739 errno = 0;
740 ptrace (PTRACE_POKETEXT, inferior_pid, addr, buffer[i]);
741 if (errno)
742 return errno;
743 }
744
745 return 0;
746}
747\f
748void
4ce44c66 749initialize_low ()
c906108c 750{
5c44784c 751 initialize_arch();
c906108c 752}
This page took 0.062393 seconds and 4 git commands to generate.