1 /* Native-dependent code for Lynx running on i386's, for GDB.
2 Copyright 1988, 1989, 1991, 1992, 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. */
26 #include <sys/ptrace.h>
27 #include "/usr/include/sys/wait.h"
29 /* these values indicate the offset of the named register in the econtext
47 /* Currently these are not being used. So set them to 0 */
52 /* this table must line up with REGISTER_NAMES in m-i386.h */
53 static unsigned int regmap
[] =
61 /* Return the address in the core dump or inferior of register REGNO.
62 BLOCKEND is the address of the econtext structure */
65 register_addr (regno
, blockend
)
68 if (regno
< 0 || regno
>= NUM_REGS
)
69 error ("Invalid register number %d.", regno
);
71 return (blockend
+ regmap
[regno
] * sizeof (long));
74 /* Fetch one register. */
77 fetch_register (regno
, offset
, bpid
)
82 char buf
[MAX_REGISTER_RAW_SIZE
];
83 char mess
[128]; /* For messages */
86 regaddr
= register_addr (regno
, offset
);
87 for (i
= 0; i
< REGISTER_RAW_SIZE (regno
); i
+= sizeof (int))
90 *(int *) &buf
[i
] = ptrace (PTRACE_PEEKTHREAD
, bpid
,
91 (PTRACE_ARG3_TYPE
) regaddr
, 0);
92 regaddr
+= sizeof (int);
95 sprintf (mess
, "reading register %s (#%d)", reg_names
[regno
], regno
);
96 perror_with_name (mess
);
99 supply_register (regno
, buf
);
102 /* Store our register values back into the inferior.
103 If REGNO is -1, do this for all registers.
104 Otherwise, REGNO specifies which register (so we can save time). */
107 store_register (regno
, offset
, bpid
)
111 unsigned int regaddr
;
113 extern char registers
[];
116 regaddr
= register_addr (regno
, offset
);
117 for (i
= 0; i
< REGISTER_RAW_SIZE (regno
); i
+= sizeof(int))
120 ptrace (PTRACE_POKEUSER
, bpid
, (PTRACE_ARG3_TYPE
) regaddr
,
121 *(int *) ®isters
[REGISTER_BYTE (regno
) + i
]);
124 sprintf (mess
, "writing register number %d(%d)", regno
, i
);
125 perror_with_name (mess
);
127 regaddr
+= sizeof(int);
131 /* return an offset for use with register_addr() */
138 unsigned int specpage_off
, offset
= (char *) &s
.ecp
- (char *) &s
;
141 specpage_off
= ptrace (PTRACE_THREADUSER
, pid
, (PTRACE_ARG3_TYPE
) 0, 0);
143 perror_with_name ("ptrace");
145 offset
= ptrace (PTRACE_PEEKTHREAD
, pid
, (PTRACE_ARG3_TYPE
) offset
, 0)
148 perror_with_name ("ptrace");
152 /* Fetch all registers, or just one, from the child process. */
155 fetch_inferior_registers (regno
)
158 unsigned int offset
= fetch_offset (inferior_pid
);
162 for (regno
= 0; regno
< NUM_REGS
; regno
++)
163 fetch_register (regno
, offset
, inferior_pid
);
166 fetch_register (regno
, offset
, inferior_pid
);
169 /* Store all registers, or just one, to the child process. */
172 store_inferior_registers (regno
)
175 unsigned int offset
= fetch_offset (inferior_pid
);
179 for (regno
= 0; regno
< NUM_REGS
; regno
++)
180 store_register (regno
, offset
, inferior_pid
);
183 store_register (regno
, offset
, inferior_pid
);
186 /* Extract the register values out of the core file and store
187 them where `read_register' will find them.
189 CORE_REG_SECT points to the register values themselves, read into memory.
190 CORE_REG_SIZE is the size of that area.
191 WHICH says which set of registers we are handling (0 = int, 2 = float
192 on machines where they are discontiguous).
193 REG_ADDR is the offset from u.u_ar0 to the register values relative to
194 core_reg_sect. This is used with old-fashioned core files to
195 locate the registers in a large upage-plus-stack ".reg" section.
196 Original upage address X is at location core_reg_sect+x+reg_addr.
200 fetch_core_registers (core_reg_sect
, core_reg_size
, which
, reg_addr
)
202 unsigned core_reg_size
;
207 unsigned int regno
, addr
;
209 for (regno
= 0; regno
< NUM_REGS
; regno
++)
211 addr
= register_addr (regno
, (char *) &s
.ec
- (char *) &s
);
212 supply_register (regno
, core_reg_sect
+ addr
);
216 /* Wait for child to do something. Return pid of child, or -1 in case
217 of error; store status through argument pointer STATUS. */
232 set_sigint_trap(); /* Causes SIGINT to be passed on to the
242 if (save_errno
== EINTR
)
244 fprintf (stderr
, "Child process unexpectedly missing: %s.\n",
245 safe_strerror (save_errno
));
246 *status
= 42; /* Claim it exited with signal 42 */
250 if (pid
!= PIDGET (inferior_pid
)) /* Some other process?!? */
253 /* thread = WIFTID (*status);*/
254 thread
= *status
>> 16;
256 /* Initial thread value can only be acquired via wait, so we have to
257 resort to this hack. */
259 if (TIDGET (inferior_pid
) == 0)
261 inferior_pid
= BUILDPID (inferior_pid
, thread
);
262 add_thread (inferior_pid
);
265 pid
= BUILDPID (pid
, thread
);
271 /* Return the PC of the caller from the call frame. Assumes the subr prologue
272 has already been executed, and the frame pointer setup. If this is the
273 outermost frame, we check to see if we are in a system call by examining the
274 previous instruction. If so, then the return PC is actually at SP+4 because
275 system calls use a different calling sequence. */
278 i386lynx_saved_pc_after_call (frame
)
279 struct frame_info
*frame
;
282 static const char call_inst
[] = {0x9a, 0, 0, 0, 0, 8, 0}; /* lcall 0x8,0x0 */
284 read_memory (frame
->pc
- 7, opcode
, 7);
285 if (memcmp (opcode
, call_inst
, 7) == 0)
286 return read_memory_integer (read_register (SP_REGNUM
) + 4, 4);
288 return read_memory_integer (read_register (SP_REGNUM
), 4);
291 /* Convert a Lynx process ID to a string. Returns the string in a static
295 i386lynx_pid_to_str (pid
)
300 sprintf (buf
, "process %d thread %d", PIDGET (pid
), TIDGET (pid
));
This page took 0.034932 seconds and 4 git commands to generate.