]>
git.ipfire.org Git - thirdparty/binutils-gdb.git/blob - gdb/gdbserver/low-lynx.c
1 /* Low level interface to ptrace, for the remote server for GDB.
2 Copyright (C) 1986, 1987, 1993 Free Software Foundation, Inc.
4 This file is part of GDB.
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.
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.
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., 675 Mass Ave, Cambridge, MA 02139, USA. */
25 #include <sys/param.h>
29 #include <sys/signal.h>
31 #include <sys/kernel.h>
35 #include <sys/itimer.h>
37 #include <sys/resource.h>
40 #include <sys/ioctl.h>
46 char registers
[REGISTER_BYTES
];
48 #include <sys/ptrace.h>
50 /* Start an inferior process and returns its pid.
51 ALLARGS is a vector of program-name and args. */
54 create_inferior (program
, allargs
)
62 perror_with_name ("fork");
68 /* Switch child to it's own process group so that signals won't
69 directly affect gdbserver. */
73 ioctl (0, TIOCSPGRP
, &pgrp
);
75 ptrace (PTRACE_TRACEME
, 0, (PTRACE_ARG3_TYPE
)0, 0);
77 execv (program
, allargs
);
79 fprintf (stderr
, "GDBserver (process %d): Cannot exec %s: %s.\n",
81 errno
< sys_nerr
? sys_errlist
[errno
] : "unknown error");
89 /* Kill the inferior process. Make us have no inferior. */
94 if (inferior_pid
== 0)
96 ptrace (PTRACE_KILL
, inferior_pid
, 0, 0);
102 /* Wait for process, returns status */
119 if (pid
!= PIDGET(inferior_pid
))
120 perror_with_name ("wait");
122 thread_from_wait
= w
.w_tid
;
123 inferior_pid
= BUILDPID (inferior_pid
, w
.w_tid
);
126 && WSTOPSIG(w
) == SIGTRAP
)
130 realsig
= ptrace (PTRACE_GETTRACESIG
, inferior_pid
,
131 (PTRACE_ARG3_TYPE
)0, 0);
133 if (realsig
== SIGNEWTHREAD
)
135 /* Simply ignore new thread notification, as we can't do anything
136 useful with such threads. All ptrace calls at this point just
137 fail for no apparent reason. The thread will eventually get a
138 real signal when it becomes real. */
149 return ((unsigned char) WEXITSTATUS (w
));
151 else if (!WIFSTOPPED (w
))
154 return ((unsigned char) WTERMSIG (w
));
157 fetch_inferior_registers (0);
160 return ((unsigned char) WSTOPSIG (w
));
163 /* Resume execution of the inferior process.
164 If STEP is nonzero, single-step it.
165 If SIGNAL is nonzero, give it that signal. */
168 myresume (step
, signal
)
173 ptrace (step
? PTRACE_SINGLESTEP_ONE
: PTRACE_CONT
,
174 BUILDPID (inferior_pid
, cont_thread
== -1 ? 0 : cont_thread
),
177 perror_with_name ("ptrace");
181 #define offsetof(TYPE, MEMBER) ((unsigned long) &((TYPE *)0)->MEMBER)
183 /* Mapping between GDB register #s and offsets into econtext. Must be
184 consistent with REGISTER_NAMES macro in various tmXXX.h files. */
186 #define X(ENTRY)(offsetof(struct econtext, ENTRY))
189 /* Mappings from tm-i386v.h */
191 static int regmap
[] =
207 X(ecode
), /* Lynx doesn't give us either fs or gs, so */
208 X(fault
), /* we just substitute these two in the hopes
209 that they are useful. */
214 /* Mappings from tm-m68k.h */
216 static int regmap
[] =
228 X(regs
[10]), /* a2 */
229 X(regs
[11]), /* a3 */
230 X(regs
[12]), /* a4 */
231 X(regs
[13]), /* a5 */
232 X(regs
[14]), /* fp */
237 X(fregs
[0*3]), /* fp0 */
238 X(fregs
[1*3]), /* fp1 */
239 X(fregs
[2*3]), /* fp2 */
240 X(fregs
[3*3]), /* fp3 */
241 X(fregs
[4*3]), /* fp4 */
242 X(fregs
[5*3]), /* fp5 */
243 X(fregs
[6*3]), /* fp6 */
244 X(fregs
[7*3]), /* fp7 */
246 X(fcregs
[0]), /* fpcontrol */
247 X(fcregs
[1]), /* fpstatus */
248 X(fcregs
[2]), /* fpiaddr */
250 X(fault
), /* fpflags */
255 /* Mappings from tm-sparc.h */
257 #define FX(ENTRY)(offsetof(struct fcontext, ENTRY))
259 static int regmap
[] =
266 -1, /* g5->g7 aren't saved by Lynx */
279 -1,-1,-1,-1,-1,-1,-1,-1, /* l0 -> l7 */
281 -1,-1,-1,-1,-1,-1,-1,-1, /* i0 -> i7 */
283 FX(f
.fregs
[0]), /* f0 */
329 /* This routine handles some oddball cases for Sparc registers and LynxOS.
330 In partucular, it causes refs to G0, g5->7, and all fp regs to return zero.
331 It also handles knows where to find the I & L regs on the stack. */
334 fetch_inferior_registers (regno
)
340 #define WHATREGS_FLOAT 1
341 #define WHATREGS_GEN 2
342 #define WHATREGS_STACK 4
345 whatregs
= WHATREGS_FLOAT
| WHATREGS_GEN
| WHATREGS_STACK
;
346 else if (regno
>= L0_REGNUM
&& regno
<= I7_REGNUM
)
347 whatregs
= WHATREGS_STACK
;
348 else if (regno
>= FP0_REGNUM
&& regno
< FP0_REGNUM
+ 32)
349 whatregs
= WHATREGS_FLOAT
;
351 whatregs
= WHATREGS_GEN
;
353 if (whatregs
& WHATREGS_GEN
)
355 struct econtext ec
; /* general regs */
356 char buf
[MAX_REGISTER_RAW_SIZE
];
361 retval
= ptrace (PTRACE_GETREGS
,
362 BUILDPID (inferior_pid
, general_thread
),
363 (PTRACE_ARG3_TYPE
) &ec
,
366 perror_with_name ("Sparc fetch_inferior_registers(ptrace)");
368 memset (buf
, 0, REGISTER_RAW_SIZE (G0_REGNUM
));
369 supply_register (G0_REGNUM
, buf
);
370 supply_register (TBR_REGNUM
, (char *)&ec
.tbr
);
372 memcpy (®isters
[REGISTER_BYTE (G1_REGNUM
)], &ec
.g1
,
373 4 * REGISTER_RAW_SIZE (G1_REGNUM
));
374 for (i
= G1_REGNUM
; i
<= G1_REGNUM
+ 3; i
++)
375 register_valid
[i
] = 1;
377 supply_register (PS_REGNUM
, (char *)&ec
.psr
);
378 supply_register (Y_REGNUM
, (char *)&ec
.y
);
379 supply_register (PC_REGNUM
, (char *)&ec
.pc
);
380 supply_register (NPC_REGNUM
, (char *)&ec
.npc
);
381 supply_register (WIM_REGNUM
, (char *)&ec
.wim
);
383 memcpy (®isters
[REGISTER_BYTE (O0_REGNUM
)], ec
.o
,
384 8 * REGISTER_RAW_SIZE (O0_REGNUM
));
385 for (i
= O0_REGNUM
; i
<= O0_REGNUM
+ 7; i
++)
386 register_valid
[i
] = 1;
389 if (whatregs
& WHATREGS_STACK
)
394 sp
= read_register (SP_REGNUM
);
396 target_xfer_memory (sp
+ FRAME_SAVED_I0
,
397 ®isters
[REGISTER_BYTE(I0_REGNUM
)],
398 8 * REGISTER_RAW_SIZE (I0_REGNUM
), 0);
399 for (i
= I0_REGNUM
; i
<= I7_REGNUM
; i
++)
400 register_valid
[i
] = 1;
402 target_xfer_memory (sp
+ FRAME_SAVED_L0
,
403 ®isters
[REGISTER_BYTE(L0_REGNUM
)],
404 8 * REGISTER_RAW_SIZE (L0_REGNUM
), 0);
405 for (i
= L0_REGNUM
; i
<= L0_REGNUM
+ 7; i
++)
406 register_valid
[i
] = 1;
409 if (whatregs
& WHATREGS_FLOAT
)
411 struct fcontext fc
; /* fp regs */
416 retval
= ptrace (PTRACE_GETFPREGS
, BUILDPID (inferior_pid
, general_thread
), (PTRACE_ARG3_TYPE
) &fc
,
419 perror_with_name ("Sparc fetch_inferior_registers(ptrace)");
421 memcpy (®isters
[REGISTER_BYTE (FP0_REGNUM
)], fc
.f
.fregs
,
422 32 * REGISTER_RAW_SIZE (FP0_REGNUM
));
423 for (i
= FP0_REGNUM
; i
<= FP0_REGNUM
+ 31; i
++)
424 register_valid
[i
] = 1;
426 supply_register (FPS_REGNUM
, (char *)&fc
.fsr
);
431 /* This routine handles storing of the I & L regs for the Sparc. The trick
432 here is that they actually live on the stack. The really tricky part is
433 that when changing the stack pointer, the I & L regs must be written to
434 where the new SP points, otherwise the regs will be incorrect when the
435 process is started up again. We assume that the I & L regs are valid at
439 store_inferior_registers (regno
)
446 whatregs
= WHATREGS_FLOAT
| WHATREGS_GEN
| WHATREGS_STACK
;
447 else if (regno
>= L0_REGNUM
&& regno
<= I7_REGNUM
)
448 whatregs
= WHATREGS_STACK
;
449 else if (regno
>= FP0_REGNUM
&& regno
< FP0_REGNUM
+ 32)
450 whatregs
= WHATREGS_FLOAT
;
451 else if (regno
== SP_REGNUM
)
452 whatregs
= WHATREGS_STACK
| WHATREGS_GEN
;
454 whatregs
= WHATREGS_GEN
;
456 if (whatregs
& WHATREGS_GEN
)
458 struct econtext ec
; /* general regs */
461 ec
.tbr
= read_register (TBR_REGNUM
);
462 memcpy (&ec
.g1
, ®isters
[REGISTER_BYTE (G1_REGNUM
)],
463 4 * REGISTER_RAW_SIZE (G1_REGNUM
));
465 ec
.psr
= read_register (PS_REGNUM
);
466 ec
.y
= read_register (Y_REGNUM
);
467 ec
.pc
= read_register (PC_REGNUM
);
468 ec
.npc
= read_register (NPC_REGNUM
);
469 ec
.wim
= read_register (WIM_REGNUM
);
471 memcpy (ec
.o
, ®isters
[REGISTER_BYTE (O0_REGNUM
)],
472 8 * REGISTER_RAW_SIZE (O0_REGNUM
));
475 retval
= ptrace (PTRACE_SETREGS
, BUILDPID (inferior_pid
, general_thread
), (PTRACE_ARG3_TYPE
) &ec
,
478 perror_with_name ("Sparc fetch_inferior_registers(ptrace)");
481 if (whatregs
& WHATREGS_STACK
)
486 sp
= read_register (SP_REGNUM
);
488 if (regno
== -1 || regno
== SP_REGNUM
)
490 if (!register_valid
[L0_REGNUM
+5])
492 target_xfer_memory (sp
+ FRAME_SAVED_I0
,
493 ®isters
[REGISTER_BYTE (I0_REGNUM
)],
494 8 * REGISTER_RAW_SIZE (I0_REGNUM
), 1);
496 target_xfer_memory (sp
+ FRAME_SAVED_L0
,
497 ®isters
[REGISTER_BYTE (L0_REGNUM
)],
498 8 * REGISTER_RAW_SIZE (L0_REGNUM
), 1);
500 else if (regno
>= L0_REGNUM
&& regno
<= I7_REGNUM
)
502 if (!register_valid
[regno
])
504 if (regno
>= L0_REGNUM
&& regno
<= L0_REGNUM
+ 7)
505 regoffset
= REGISTER_BYTE (regno
) - REGISTER_BYTE (L0_REGNUM
)
508 regoffset
= REGISTER_BYTE (regno
) - REGISTER_BYTE (I0_REGNUM
)
510 target_xfer_memory (sp
+ regoffset
, ®isters
[REGISTER_BYTE (regno
)],
511 REGISTER_RAW_SIZE (regno
), 1);
515 if (whatregs
& WHATREGS_FLOAT
)
517 struct fcontext fc
; /* fp regs */
520 /* We read fcontext first so that we can get good values for fq_t... */
522 retval
= ptrace (PTRACE_GETFPREGS
, BUILDPID (inferior_pid
, general_thread
), (PTRACE_ARG3_TYPE
) &fc
,
525 perror_with_name ("Sparc fetch_inferior_registers(ptrace)");
527 memcpy (fc
.f
.fregs
, ®isters
[REGISTER_BYTE (FP0_REGNUM
)],
528 32 * REGISTER_RAW_SIZE (FP0_REGNUM
));
530 fc
.fsr
= read_register (FPS_REGNUM
);
533 retval
= ptrace (PTRACE_SETFPREGS
, BUILDPID (inferior_pid
, general_thread
), (PTRACE_ARG3_TYPE
) &fc
,
536 perror_with_name ("Sparc fetch_inferior_registers(ptrace)");
544 /* Return the offset relative to the start of the per-thread data to the
545 saved context block. */
548 lynx_registers_addr()
551 int ecpoff
= offsetof(st_t
, ecp
);
555 stblock
= (CORE_ADDR
) ptrace (PTRACE_THREADUSER
, BUILDPID (inferior_pid
, general_thread
),
556 (PTRACE_ARG3_TYPE
)0, 0);
558 perror_with_name ("PTRACE_THREADUSER");
560 ecp
= (CORE_ADDR
) ptrace (PTRACE_PEEKTHREAD
, BUILDPID (inferior_pid
, general_thread
),
561 (PTRACE_ARG3_TYPE
)ecpoff
, 0);
563 perror_with_name ("lynx_registers_addr(PTRACE_PEEKTHREAD)");
565 return ecp
- stblock
;
568 /* Fetch one or more registers from the inferior. REGNO == -1 to get
569 them all. We actually fetch more than requested, when convenient,
570 marking them as valid so we won't fetch them again. */
573 fetch_inferior_registers (ignored
)
580 ecp
= lynx_registers_addr();
582 for (regno
= 0; regno
< NUM_REGS
; regno
++)
584 int ptrace_fun
= PTRACE_PEEKTHREAD
;
586 #ifdef PTRACE_PEEKUSP
587 ptrace_fun
= regno
== SP_REGNUM
? PTRACE_PEEKUSP
: PTRACE_PEEKTHREAD
;
591 reg
= ptrace (ptrace_fun
, BUILDPID (inferior_pid
, general_thread
),
592 (PTRACE_ARG3_TYPE
) (ecp
+ regmap
[regno
]), 0);
594 perror_with_name ("fetch_inferior_registers(PTRACE_PEEKTHREAD)");
596 *(unsigned long *)®isters
[REGISTER_BYTE (regno
)] = reg
;
600 /* Store our register values back into the inferior.
601 If REGNO is -1, do this for all registers.
602 Otherwise, REGNO specifies which register (so we can save time). */
605 store_inferior_registers (ignored
)
612 ecp
= lynx_registers_addr();
614 for (regno
= 0; regno
< NUM_REGS
; regno
++)
616 int ptrace_fun
= PTRACE_POKEUSER
;
618 #ifdef PTRACE_POKEUSP
619 ptrace_fun
= regno
== SP_REGNUM
? PTRACE_POKEUSP
: PTRACE_POKEUSER
;
622 reg
= *(unsigned long *)®isters
[REGISTER_BYTE (regno
)];
625 ptrace (ptrace_fun
, BUILDPID (inferior_pid
, general_thread
),
626 (PTRACE_ARG3_TYPE
) (ecp
+ regmap
[regno
]), reg
);
628 perror_with_name ("PTRACE_POKEUSER");
634 /* NOTE! I tried using PTRACE_READDATA, etc., to read and write memory
635 in the NEW_SUN_PTRACE case.
636 It ought to be straightforward. But it appears that writing did
637 not write the data that I specified. I cannot understand where
638 it got the data that it actually did write. */
640 /* Copy LEN bytes from inferior's memory starting at MEMADDR
641 to debugger memory starting at MYADDR. */
644 read_inferior_memory (memaddr
, myaddr
, len
)
650 /* Round starting address down to longword boundary. */
651 register CORE_ADDR addr
= memaddr
& -sizeof (int);
652 /* Round ending address up; get number of longwords that makes. */
654 = (((memaddr
+ len
) - addr
) + sizeof (int) - 1) / sizeof (int);
655 /* Allocate buffer of that many longwords. */
656 register int *buffer
= (int *) alloca (count
* sizeof (int));
658 /* Read all the longwords */
659 for (i
= 0; i
< count
; i
++, addr
+= sizeof (int))
661 buffer
[i
] = ptrace (PTRACE_PEEKTEXT
, BUILDPID (inferior_pid
, general_thread
), addr
, 0);
664 /* Copy appropriate bytes out of the buffer. */
665 memcpy (myaddr
, (char *) buffer
+ (memaddr
& (sizeof (int) - 1)), len
);
668 /* Copy LEN bytes of data from debugger memory at MYADDR
669 to inferior's memory at MEMADDR.
670 On failure (cannot write the inferior)
671 returns the value of errno. */
674 write_inferior_memory (memaddr
, myaddr
, len
)
680 /* Round starting address down to longword boundary. */
681 register CORE_ADDR addr
= memaddr
& -sizeof (int);
682 /* Round ending address up; get number of longwords that makes. */
684 = (((memaddr
+ len
) - addr
) + sizeof (int) - 1) / sizeof (int);
685 /* Allocate buffer of that many longwords. */
686 register int *buffer
= (int *) alloca (count
* sizeof (int));
689 /* Fill start and end extra bytes of buffer with existing memory data. */
691 buffer
[0] = ptrace (PTRACE_PEEKTEXT
, BUILDPID (inferior_pid
, general_thread
), addr
, 0);
696 = ptrace (PTRACE_PEEKTEXT
, BUILDPID (inferior_pid
, general_thread
),
697 addr
+ (count
- 1) * sizeof (int), 0);
700 /* Copy data to be written over corresponding part of buffer */
702 memcpy ((char *) buffer
+ (memaddr
& (sizeof (int) - 1)), myaddr
, len
);
704 /* Write the entire buffer. */
706 for (i
= 0; i
< count
; i
++, addr
+= sizeof (int))
711 ptrace (PTRACE_POKETEXT
, BUILDPID (inferior_pid
, general_thread
), addr
, buffer
[i
]);
715 ptrace (PTRACE_POKETEXT): errno=%d, pid=0x%x, addr=0x%x, buffer[i] = 0x%x\n",
716 errno
, BUILDPID (inferior_pid
, general_thread
),
718 fprintf(stderr
, "Sleeping for 1 second\n");