Commit | Line | Data |
---|---|---|
d4f3574e SS |
1 | /* Native-dependent code for Linux running on i386's, for GDB. |
2 | ||
3 | This file is part of GDB. | |
4 | ||
5 | This program is free software; you can redistribute it and/or modify | |
6 | it under the terms of the GNU General Public License as published by | |
7 | the Free Software Foundation; either version 2 of the License, or | |
8 | (at your option) any later version. | |
9 | ||
10 | This program is distributed in the hope that it will be useful, | |
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
13 | GNU General Public License for more details. | |
14 | ||
15 | You should have received a copy of the GNU General Public License | |
16 | along with this program; if not, write to the Free Software | |
17 | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ | |
18 | ||
19 | #include "defs.h" | |
20 | #include "inferior.h" | |
21 | #include "gdbcore.h" | |
22 | ||
23 | /* For i386_linux_skip_solib_resolver */ | |
24 | #include "symtab.h" | |
25 | #include "frame.h" | |
26 | #include "symfile.h" | |
27 | #include "objfiles.h" | |
28 | ||
29 | #include <sys/ptrace.h> | |
30 | #include <sys/user.h> | |
31 | #include <sys/procfs.h> | |
32 | ||
33 | #ifdef HAVE_SYS_REG_H | |
34 | #include <sys/reg.h> | |
35 | #endif | |
36 | ||
37 | /* This is a duplicate of the table in i386-xdep.c. */ | |
38 | ||
39 | static int regmap[] = | |
40 | { | |
41 | EAX, ECX, EDX, EBX, | |
42 | UESP, EBP, ESI, EDI, | |
43 | EIP, EFL, CS, SS, | |
44 | DS, ES, FS, GS, | |
45 | }; | |
46 | ||
47 | ||
917317f4 JM |
48 | /* Given a pointer to a general register set in struct user format |
49 | (gregset_t *), unpack the register contents and supply them as | |
50 | gdb's idea of the current register values. */ | |
d4f3574e SS |
51 | void |
52 | supply_gregset (gregsetp) | |
53 | gregset_t *gregsetp; | |
54 | { | |
55 | register int regi; | |
56 | register greg_t *regp = (greg_t *) gregsetp; | |
57 | ||
917317f4 | 58 | for (regi = 0; regi < NUM_GREGS; regi++) |
d4f3574e SS |
59 | { |
60 | supply_register (regi, (char *) (regp + regmap[regi])); | |
61 | } | |
62 | } | |
63 | ||
917317f4 JM |
64 | /* Fill in a gregset_t object with selected data from a gdb-format |
65 | register file. | |
66 | - GREGSETP points to the gregset_t object to be filled. | |
67 | - GDB_REGS points to the GDB-style register file providing the data. | |
68 | - VALID is an array indicating which registers in GDB_REGS are | |
69 | valid; the parts of *GREGSETP that would hold registers marked | |
70 | invalid in GDB_REGS are left unchanged. If VALID is zero, all | |
71 | registers are assumed to be valid. */ | |
d4f3574e | 72 | void |
917317f4 JM |
73 | convert_to_gregset (gregset_t *gregsetp, |
74 | char *gdb_regs, | |
75 | signed char *valid) | |
d4f3574e SS |
76 | { |
77 | int regi; | |
78 | register greg_t *regp = (greg_t *) gregsetp; | |
79 | ||
917317f4 JM |
80 | for (regi = 0; regi < NUM_GREGS; regi++) |
81 | if (! valid || valid[regi]) | |
82 | *(regp + regmap[regi]) = * (int *) ®isters[REGISTER_BYTE (regi)]; | |
83 | } | |
84 | ||
85 | void | |
86 | fill_gregset (gregset_t *gregsetp, | |
87 | int regno) | |
88 | { | |
89 | if (regno == -1) | |
90 | convert_to_gregset (gregsetp, registers, 0); | |
91 | else | |
d4f3574e | 92 | { |
917317f4 JM |
93 | signed char valid[NUM_GREGS]; |
94 | memset (valid, 0, sizeof (valid)); | |
95 | valid[regno] = 1; | |
96 | convert_to_gregset (gregsetp, valid, valid); | |
d4f3574e SS |
97 | } |
98 | } | |
99 | ||
100 | ||
917317f4 JM |
101 | /* Where does st(N) start in the fpregset_t structure F? */ |
102 | #define FPREGSET_T_FPREG_OFFSET(f, n) \ | |
103 | ((char *) &(f)->st_space + (n) * 10) | |
d4f3574e | 104 | |
917317f4 JM |
105 | /* Fill GDB's register file with the floating-point register values in |
106 | *FPREGSETP. */ | |
d4f3574e | 107 | void |
917317f4 | 108 | supply_fpregset (fpregset_t *fpregsetp) |
d4f3574e | 109 | { |
917317f4 JM |
110 | int i; |
111 | ||
112 | /* Supply the floating-point registers. */ | |
113 | for (i = 0; i < 8; i++) | |
114 | supply_register (FP0_REGNUM + i, FPREGSET_T_FPREG_OFFSET (fpregsetp, i)); | |
115 | ||
116 | supply_register (FCTRL_REGNUM, (char *) &fpregsetp->cwd); | |
117 | supply_register (FSTAT_REGNUM, (char *) &fpregsetp->swd); | |
118 | supply_register (FTAG_REGNUM, (char *) &fpregsetp->twd); | |
119 | supply_register (FCOFF_REGNUM, (char *) &fpregsetp->fip); | |
120 | supply_register (FDS_REGNUM, (char *) &fpregsetp->fos); | |
121 | supply_register (FDOFF_REGNUM, (char *) &fpregsetp->foo); | |
122 | ||
123 | /* Extract the code segment and opcode from the "fcs" member. */ | |
124 | { | |
125 | long l; | |
126 | ||
127 | l = fpregsetp->fcs & 0xffff; | |
128 | supply_register (FCS_REGNUM, (char *) &l); | |
129 | ||
130 | l = (fpregsetp->fcs >> 16) & ((1 << 11) - 1); | |
131 | supply_register (FOP_REGNUM, (char *) &l); | |
132 | } | |
d4f3574e SS |
133 | } |
134 | ||
d4f3574e | 135 | |
917317f4 JM |
136 | /* Fill in an fpregset_t structure with selected data from a |
137 | gdb-format register file. | |
138 | - FPREGSETP points to the structure to be filled. | |
139 | - GDB_REGS points to the GDB-style register file providing the data. | |
140 | - VALID is an array indicating which registers in GDB_REGS are | |
141 | valid; the parts of *FPREGSETP that would hold registers marked | |
142 | invalid in GDB_REGS are left unchanged. If VALID is zero, all | |
143 | registers are assumed to be valid. */ | |
d4f3574e | 144 | void |
917317f4 JM |
145 | convert_to_fpregset (fpregset_t *fpregsetp, |
146 | char *gdb_regs, | |
147 | signed char *valid) | |
d4f3574e | 148 | { |
917317f4 JM |
149 | int i; |
150 | ||
151 | /* Fill in the floating-point registers. */ | |
152 | for (i = 0; i < 8; i++) | |
153 | if (!valid || valid[i]) | |
154 | memcpy (FPREGSET_T_FPREG_OFFSET (fpregsetp, i), | |
155 | ®isters[REGISTER_BYTE (FP0_REGNUM + i)], | |
156 | REGISTER_RAW_SIZE(FP0_REGNUM + i)); | |
157 | ||
158 | #define fill(MEMBER, REGNO) \ | |
159 | if (! valid || valid[(REGNO)]) \ | |
160 | memcpy (&fpregsetp->MEMBER, ®isters[REGISTER_BYTE (REGNO)], \ | |
161 | sizeof (fpregsetp->MEMBER)) | |
162 | ||
163 | fill (cwd, FCTRL_REGNUM); | |
164 | fill (swd, FSTAT_REGNUM); | |
165 | fill (twd, FTAG_REGNUM); | |
166 | fill (fip, FCOFF_REGNUM); | |
167 | fill (foo, FDOFF_REGNUM); | |
168 | fill (fos, FDS_REGNUM); | |
169 | ||
170 | #undef fill | |
171 | ||
172 | if (! valid || valid[FCS_REGNUM]) | |
173 | fpregsetp->fcs | |
174 | = ((fpregsetp->fcs & ~0xffff) | |
175 | | (* (int *) ®isters[REGISTER_BYTE (FCS_REGNUM)] & 0xffff)); | |
176 | ||
177 | if (! valid || valid[FOP_REGNUM]) | |
178 | fpregsetp->fcs | |
179 | = ((fpregsetp->fcs & 0xffff) | |
180 | | ((*(int *) ®isters[REGISTER_BYTE (FOP_REGNUM)] & ((1 << 11) - 1)) | |
181 | << 16)); | |
182 | } | |
d4f3574e | 183 | |
917317f4 JM |
184 | |
185 | /* Given a pointer to a floating point register set in (fpregset_t *) | |
186 | format, update all of the registers from gdb's idea of the current | |
187 | floating point register set. */ | |
188 | ||
189 | void | |
190 | fill_fpregset (fpregset_t *fpregsetp, | |
191 | int regno) | |
192 | { | |
193 | convert_to_fpregset (fpregsetp, registers, 0); | |
d4f3574e SS |
194 | } |
195 | ||
917317f4 JM |
196 | |
197 | /* Get the whole floating point state of the process and store the | |
198 | floating point stack into registers[]. */ | |
d4f3574e | 199 | static void |
917317f4 | 200 | fetch_fpregs () |
d4f3574e SS |
201 | { |
202 | int ret, regno; | |
917317f4 | 203 | fpregset_t buf; |
d4f3574e | 204 | |
917317f4 JM |
205 | ret = ptrace (PTRACE_GETFPREGS, inferior_pid, 0, (int) &buf); |
206 | if (ret < 0) | |
d4f3574e SS |
207 | { |
208 | warning ("Couldn't get floating point status"); | |
209 | return; | |
210 | } | |
211 | ||
917317f4 JM |
212 | /* ptrace fills an fpregset_t, so we can use the same function we do |
213 | for core files. */ | |
214 | supply_fpregset (&buf); | |
d4f3574e SS |
215 | } |
216 | ||
217 | ||
917317f4 JM |
218 | /* Set the inferior's floating-point registers to the values in |
219 | registers[] --- but only those registers marked valid. */ | |
d4f3574e | 220 | static void |
917317f4 | 221 | store_fpregs () |
d4f3574e | 222 | { |
917317f4 JM |
223 | int ret; |
224 | fpregset_t buf; | |
d4f3574e | 225 | |
917317f4 JM |
226 | ret = ptrace (PTRACE_GETFPREGS, inferior_pid, 0, (int) &buf); |
227 | if (ret < 0) | |
d4f3574e SS |
228 | { |
229 | warning ("Couldn't get floating point status"); | |
230 | return; | |
231 | } | |
232 | ||
917317f4 | 233 | convert_to_fpregset (&buf, registers, register_valid); |
d4f3574e | 234 | |
917317f4 JM |
235 | ret = ptrace (PTRACE_SETFPREGS, inferior_pid, 0, (int) &buf); |
236 | if (ret < 0) | |
d4f3574e SS |
237 | { |
238 | warning ("Couldn't write floating point status"); | |
239 | return; | |
240 | } | |
d4f3574e SS |
241 | } |
242 | ||
243 | ||
917317f4 JM |
244 | /* Read the general registers from the process, and store them |
245 | in registers[]. */ | |
d4f3574e | 246 | static void |
917317f4 | 247 | fetch_regs () |
d4f3574e SS |
248 | { |
249 | int ret, regno; | |
917317f4 | 250 | gregset_t buf; |
d4f3574e | 251 | |
917317f4 JM |
252 | ret = ptrace (PTRACE_GETREGS, inferior_pid, 0, (int) &buf); |
253 | if (ret < 0) | |
d4f3574e SS |
254 | { |
255 | warning ("Couldn't get registers"); | |
256 | return; | |
257 | } | |
258 | ||
917317f4 | 259 | supply_gregset (&buf); |
d4f3574e SS |
260 | } |
261 | ||
262 | ||
917317f4 JM |
263 | /* Set the inferior's general registers to the values in registers[] |
264 | --- but only those registers marked as valid. */ | |
d4f3574e | 265 | static void |
917317f4 | 266 | store_regs () |
d4f3574e SS |
267 | { |
268 | int ret, regno; | |
917317f4 | 269 | gregset_t buf; |
d4f3574e | 270 | |
917317f4 JM |
271 | ret = ptrace (PTRACE_GETREGS, inferior_pid, 0, (int) &buf); |
272 | if (ret < 0) | |
d4f3574e SS |
273 | { |
274 | warning ("Couldn't get registers"); | |
275 | return; | |
276 | } | |
277 | ||
917317f4 | 278 | convert_to_gregset (&buf, registers, register_valid); |
d4f3574e SS |
279 | |
280 | ret = ptrace (PTRACE_SETREGS, inferior_pid, 0, (int)buf); | |
917317f4 | 281 | if (ret < 0) |
d4f3574e | 282 | { |
917317f4 | 283 | warning ("Couldn't write registers"); |
d4f3574e SS |
284 | return; |
285 | } | |
d4f3574e SS |
286 | } |
287 | ||
288 | ||
289 | /* Fetch registers from the child process. | |
290 | Fetch all if regno == -1, otherwise fetch all ordinary | |
291 | registers or all floating point registers depending | |
292 | upon the value of regno. */ | |
293 | ||
294 | void | |
917317f4 | 295 | fetch_inferior_registers (int regno) |
d4f3574e | 296 | { |
917317f4 JM |
297 | if (regno < NUM_GREGS || regno == -1) |
298 | fetch_regs (); | |
d4f3574e | 299 | |
917317f4 JM |
300 | if (regno >= NUM_GREGS || regno == -1) |
301 | fetch_fpregs (); | |
d4f3574e SS |
302 | } |
303 | ||
304 | ||
305 | /* Store our register values back into the inferior. | |
306 | If REGNO is -1, do this for all registers. | |
307 | Otherwise, REGNO specifies which register, which | |
308 | then determines whether we store all ordinary | |
309 | registers or all of the floating point registers. */ | |
310 | ||
311 | void | |
312 | store_inferior_registers (regno) | |
313 | int regno; | |
314 | { | |
917317f4 JM |
315 | if (regno < NUM_GREGS || regno == -1) |
316 | store_regs (); | |
d4f3574e | 317 | |
917317f4 JM |
318 | if (regno >= NUM_GREGS || regno == -1) |
319 | store_fpregs (); | |
d4f3574e SS |
320 | } |
321 | ||
322 | ||
323 | /* Find the minimal symbol named NAME, and return both the minsym | |
324 | struct and its objfile. This probably ought to be in minsym.c, but | |
325 | everything there is trying to deal with things like C++ and | |
326 | SOFUN_ADDRESS_MAYBE_TURQUOISE, ... Since this is so simple, it may | |
327 | be considered too special-purpose for general consumption. */ | |
328 | ||
329 | static struct minimal_symbol * | |
330 | find_minsym_and_objfile (char *name, struct objfile **objfile_p) | |
331 | { | |
332 | struct objfile *objfile; | |
333 | ||
334 | ALL_OBJFILES (objfile) | |
335 | { | |
336 | struct minimal_symbol *msym; | |
337 | ||
338 | ALL_OBJFILE_MSYMBOLS (objfile, msym) | |
339 | { | |
340 | if (SYMBOL_NAME (msym) | |
341 | && STREQ (SYMBOL_NAME (msym), name)) | |
342 | { | |
343 | *objfile_p = objfile; | |
344 | return msym; | |
345 | } | |
346 | } | |
347 | } | |
348 | ||
349 | return 0; | |
350 | } | |
351 | ||
352 | ||
353 | static CORE_ADDR | |
354 | skip_hurd_resolver (CORE_ADDR pc) | |
355 | { | |
356 | /* The HURD dynamic linker is part of the GNU C library, so many | |
357 | GNU/Linux distributions use it. (All ELF versions, as far as I | |
358 | know.) An unresolved PLT entry points to "_dl_runtime_resolve", | |
359 | which calls "fixup" to patch the PLT, and then passes control to | |
360 | the function. | |
361 | ||
362 | We look for the symbol `_dl_runtime_resolve', and find `fixup' in | |
363 | the same objfile. If we are at the entry point of `fixup', then | |
364 | we set a breakpoint at the return address (at the top of the | |
365 | stack), and continue. | |
366 | ||
367 | It's kind of gross to do all these checks every time we're | |
368 | called, since they don't change once the executable has gotten | |
369 | started. But this is only a temporary hack --- upcoming versions | |
370 | of Linux will provide a portable, efficient interface for | |
371 | debugging programs that use shared libraries. */ | |
372 | ||
373 | struct objfile *objfile; | |
374 | struct minimal_symbol *resolver | |
375 | = find_minsym_and_objfile ("_dl_runtime_resolve", &objfile); | |
376 | ||
377 | if (resolver) | |
378 | { | |
379 | struct minimal_symbol *fixup | |
380 | = lookup_minimal_symbol ("fixup", 0, objfile); | |
381 | ||
382 | if (fixup && SYMBOL_VALUE_ADDRESS (fixup) == pc) | |
383 | return (SAVED_PC_AFTER_CALL (get_current_frame ())); | |
384 | } | |
385 | ||
386 | return 0; | |
387 | } | |
388 | ||
389 | ||
390 | /* See the comments for SKIP_SOLIB_RESOLVER at the top of infrun.c. | |
391 | This function: | |
392 | 1) decides whether a PLT has sent us into the linker to resolve | |
393 | a function reference, and | |
394 | 2) if so, tells us where to set a temporary breakpoint that will | |
395 | trigger when the dynamic linker is done. */ | |
396 | ||
397 | CORE_ADDR | |
398 | i386_linux_skip_solib_resolver (CORE_ADDR pc) | |
399 | { | |
400 | CORE_ADDR result; | |
401 | ||
402 | /* Plug in functions for other kinds of resolvers here. */ | |
403 | result = skip_hurd_resolver (pc); | |
404 | if (result) | |
405 | return result; | |
406 | ||
407 | return 0; | |
408 | } |