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