(sim_resume): Clarify use of SIGGNAL.
[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
SS
276}
277#endif
278
279CORE_ADDR
280register_addr (regno, blockend)
281 int regno;
282 CORE_ADDR blockend;
283{
284 CORE_ADDR addr;
285
286 if (regno < 0 || regno >= ARCH_NUM_REGS)
287 error ("Invalid register number %d.", regno);
288
289 REGISTER_U_ADDR (addr, blockend, regno);
290
291 return addr;
292}
293
294/* Fetch one register. */
295
296static void
297fetch_register (regno)
298 int regno;
299{
5c44784c 300 CORE_ADDR regaddr;
c906108c
SS
301 register int i;
302
303 /* Offset of registers within the u area. */
304 unsigned int offset;
305
306 offset = U_REGS_OFFSET;
307
308 regaddr = register_addr (regno, offset);
5c44784c 309 for (i = 0; i < REGISTER_RAW_SIZE (regno); i += sizeof (PTRACE_XFER_TYPE))
c906108c
SS
310 {
311 errno = 0;
5c44784c
JM
312 *(PTRACE_XFER_TYPE *) &registers[REGISTER_BYTE (regno) + i] =
313 ptrace (PTRACE_PEEKUSER, inferior_pid, (PTRACE_ARG3_TYPE) regaddr, 0);
314 regaddr += sizeof (PTRACE_XFER_TYPE);
c906108c
SS
315 if (errno != 0)
316 {
317 /* Warning, not error, in case we are attached; sometimes the
318 kernel doesn't let us at the registers. */
319 char *err = strerror (errno);
320 char *msg = alloca (strlen (err) + 128);
321 sprintf (msg, "reading register %d: %s", regno, err);
322 error (msg);
323 goto error_exit;
324 }
325 }
c5aa993b 326error_exit:;
c906108c
SS
327}
328
329/* Fetch all registers, or just one, from the child process. */
330
331void
332fetch_inferior_registers (regno)
333 int regno;
334{
335 if (regno == -1 || regno == 0)
c5aa993b 336 for (regno = 0; regno < NUM_REGS - NUM_FREGS; regno++)
c906108c
SS
337 fetch_register (regno);
338 else
339 fetch_register (regno);
340}
341
342/* Store our register values back into the inferior.
343 If REGNO is -1, do this for all registers.
344 Otherwise, REGNO specifies which register (so we can save time). */
345
346void
347store_inferior_registers (regno)
348 int regno;
349{
5c44784c
JM
350 CORE_ADDR regaddr;
351 int i;
c906108c
SS
352 unsigned int offset = U_REGS_OFFSET;
353
354 if (regno >= 0)
355 {
356#if 0
357 if (CANNOT_STORE_REGISTER (regno))
358 return;
359#endif
360 regaddr = register_addr (regno, offset);
361 errno = 0;
362#if 0
363 if (regno == PCOQ_HEAD_REGNUM || regno == PCOQ_TAIL_REGNUM)
c5aa993b
JM
364 {
365 scratch = *(int *) &registers[REGISTER_BYTE (regno)] | 0x3;
366 ptrace (PT_WUREGS, inferior_pid, (PTRACE_ARG3_TYPE) regaddr,
367 scratch, 0);
368 if (errno != 0)
369 {
c906108c 370 /* Error, even if attached. Failing to write these two
c5aa993b
JM
371 registers is pretty serious. */
372 sprintf (buf, "writing register number %d", regno);
373 perror_with_name (buf);
374 }
375 }
c906108c
SS
376 else
377#endif
c5aa993b 378 for (i = 0; i < REGISTER_RAW_SIZE (regno); i += sizeof (int))
c906108c
SS
379 {
380 errno = 0;
5c44784c 381 ptrace (PTRACE_POKEUSER, inferior_pid, (PTRACE_ARG3_TYPE) regaddr,
c906108c
SS
382 *(int *) &registers[REGISTER_BYTE (regno) + i]);
383 if (errno != 0)
384 {
385 /* Warning, not error, in case we are attached; sometimes the
386 kernel doesn't let us at the registers. */
387 char *err = strerror (errno);
388 char *msg = alloca (strlen (err) + 128);
389 sprintf (msg, "writing register %d: %s",
390 regno, err);
391 error (msg);
392 return;
393 }
c5aa993b 394 regaddr += sizeof (int);
c906108c
SS
395 }
396 }
397 else
c5aa993b 398 for (regno = 0; regno < NUM_REGS - NUM_FREGS; regno++)
c906108c
SS
399 store_inferior_registers (regno);
400}
401
402/* NOTE! I tried using PTRACE_READDATA, etc., to read and write memory
403 in the NEW_SUN_PTRACE case.
404 It ought to be straightforward. But it appears that writing did
405 not write the data that I specified. I cannot understand where
406 it got the data that it actually did write. */
407
408/* Copy LEN bytes from inferior's memory starting at MEMADDR
409 to debugger memory starting at MYADDR. */
410
411void
412read_inferior_memory (memaddr, myaddr, len)
413 CORE_ADDR memaddr;
414 char *myaddr;
415 int len;
416{
417 register int i;
418 /* Round starting address down to longword boundary. */
5c44784c 419 register CORE_ADDR addr = memaddr & -sizeof (PTRACE_XFER_TYPE);
c906108c 420 /* Round ending address up; get number of longwords that makes. */
5c44784c
JM
421 register int count
422 = (((memaddr + len) - addr) + sizeof (PTRACE_XFER_TYPE) - 1)
423 / sizeof (PTRACE_XFER_TYPE);
c906108c 424 /* Allocate buffer of that many longwords. */
5c44784c
JM
425 register PTRACE_XFER_TYPE *buffer
426 = (PTRACE_XFER_TYPE *) alloca (count * sizeof (PTRACE_XFER_TYPE));
c906108c
SS
427
428 /* Read all the longwords */
5c44784c 429 for (i = 0; i < count; i++, addr += sizeof (PTRACE_XFER_TYPE))
c906108c
SS
430 {
431 buffer[i] = ptrace (PTRACE_PEEKTEXT, inferior_pid, addr, 0);
432 }
433
434 /* Copy appropriate bytes out of the buffer. */
5c44784c 435 memcpy (myaddr, (char *) buffer + (memaddr & (sizeof (PTRACE_XFER_TYPE) - 1)), len);
c906108c
SS
436}
437
438/* Copy LEN bytes of data from debugger memory at MYADDR
439 to inferior's memory at MEMADDR.
440 On failure (cannot write the inferior)
441 returns the value of errno. */
442
443int
444write_inferior_memory (memaddr, myaddr, len)
445 CORE_ADDR memaddr;
446 char *myaddr;
447 int len;
448{
449 register int i;
450 /* Round starting address down to longword boundary. */
5c44784c 451 register CORE_ADDR addr = memaddr & -sizeof (PTRACE_XFER_TYPE);
c906108c
SS
452 /* Round ending address up; get number of longwords that makes. */
453 register int count
5c44784c 454 = (((memaddr + len) - addr) + sizeof (PTRACE_XFER_TYPE) - 1) / sizeof (PTRACE_XFER_TYPE);
c906108c 455 /* Allocate buffer of that many longwords. */
5c44784c 456 register PTRACE_XFER_TYPE *buffer = (PTRACE_XFER_TYPE *) alloca (count * sizeof (PTRACE_XFER_TYPE));
c906108c
SS
457 extern int errno;
458
459 /* Fill start and end extra bytes of buffer with existing memory data. */
460
461 buffer[0] = ptrace (PTRACE_PEEKTEXT, inferior_pid, addr, 0);
462
463 if (count > 1)
464 {
465 buffer[count - 1]
466 = ptrace (PTRACE_PEEKTEXT, inferior_pid,
5c44784c 467 addr + (count - 1) * sizeof (PTRACE_XFER_TYPE), 0);
c906108c
SS
468 }
469
470 /* Copy data to be written over corresponding part of buffer */
471
5c44784c 472 memcpy ((char *) buffer + (memaddr & (sizeof (PTRACE_XFER_TYPE) - 1)), myaddr, len);
c906108c
SS
473
474 /* Write the entire buffer. */
475
5c44784c 476 for (i = 0; i < count; i++, addr += sizeof (PTRACE_XFER_TYPE))
c906108c
SS
477 {
478 errno = 0;
479 ptrace (PTRACE_POKETEXT, inferior_pid, addr, buffer[i]);
480 if (errno)
481 return errno;
482 }
483
484 return 0;
485}
486\f
487void
4ce44c66 488initialize_low ()
c906108c 489{
5c44784c 490 initialize_arch();
c906108c 491}
This page took 0.055903 seconds and 4 git commands to generate.