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