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