1 /* Native-dependent code for Linux running on i386's, for GDB.
3 This file is part of GDB.
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.
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.
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. */
23 /* For i386_linux_skip_solib_resolver */
29 #include <sys/ptrace.h>
31 #include <sys/procfs.h>
37 /* This is a duplicate of the table in i386-xdep.c. */
48 /* FIXME: These routine absolutely depends upon (NUM_REGS - NUM_FREGS)
49 being less than or equal to the number of registers that can be stored
50 in a gregset_t. Note that with the current scheme there will typically
51 be more registers actually stored in a gregset_t that what we know
52 about. This is bogus and should be fixed. */
54 /* Given a pointer to a general register set in /proc format (gregset_t *),
55 unpack the register contents and supply them as gdb's idea of the current
59 supply_gregset (gregsetp)
63 register greg_t *regp = (greg_t *) gregsetp;
65 for (regi = 0 ; regi < (NUM_REGS - NUM_FREGS) ; regi++)
67 supply_register (regi, (char *) (regp + regmap[regi]));
72 fill_gregset (gregsetp, regno)
77 register greg_t *regp = (greg_t *) gregsetp;
79 for (regi = 0 ; regi < (NUM_REGS - NUM_FREGS) ; regi++)
81 if ((regno == -1) || (regno == regi))
83 *(regp + regmap[regi]) = *(int *) ®isters[REGISTER_BYTE (regi)];
89 /* Given a pointer to a floating point register set in (fpregset_t *)
90 format, unpack the register contents and supply them as gdb's
91 idea of the current floating point register values. */
94 supply_fpregset (fpregsetp)
95 fpregset_t *fpregsetp;
99 from = (char *) &(fpregsetp->st_space[0]);
100 for (regi = FPSTART_REGNUM ; regi <= FPEND_REGNUM ; regi++)
102 supply_register(regi, from);
103 from += REGISTER_RAW_SIZE(regi);
107 /* Given a pointer to a floating point register set in (fpregset_t *)
108 format, update all of the registers from gdb's idea
109 of the current floating point register set. */
112 fill_fpregset (fpregsetp, regno)
113 fpregset_t *fpregsetp;
120 to = (char *) &(fpregsetp->st_space[0]);
121 for (regi = FPSTART_REGNUM ; regi <= FPEND_REGNUM ; regi++)
123 from = (char *) ®isters[REGISTER_BYTE (regi)];
124 memcpy (to, from, REGISTER_RAW_SIZE (regi));
125 to += REGISTER_RAW_SIZE(regi);
130 Get the whole floating point state of the process and
131 store the floating point stack into registers[].
137 char buf[FPREG_BYTES];
139 ret = ptrace (PTRACE_GETFPREGS, inferior_pid, 0, (int)buf);
142 warning ("Couldn't get floating point status");
146 for ( regno = 0; regno < NUM_FREGS; regno++ )
149 supply_register (NUM_REGS-NUM_FREGS+regno, buf + regno*4);
151 supply_register (NUM_REGS-NUM_FREGS+regno,
152 buf + FPENV_BYTES + (regno-7)*FPREG_RAW_SIZE);
159 Get the whole floating point state of the process and
160 replace the contents from registers[].
166 char buf[FPREG_BYTES];
168 ret = ptrace (PTRACE_GETFPREGS, inferior_pid, 0, (int)buf);
171 warning ("Couldn't get floating point status");
175 for ( regno = 0; regno < NUM_FREGS; regno++ )
177 if ( register_valid[regno] )
181 read_register_gen (NUM_REGS-NUM_FREGS+regno,
186 read_register_gen (NUM_REGS-NUM_FREGS+regno,
187 buf + FPENV_BYTES + (regno-7)*FPREG_RAW_SIZE);
192 ret = ptrace (PTRACE_SETFPREGS, inferior_pid, 0, (int)buf);
195 warning ("Couldn't write floating point status");
203 Get state of all non-fp registers of the process and
204 store into registers[].
210 char buf[17*sizeof(unsigned int)];
212 ret = ptrace (PTRACE_GETREGS, inferior_pid, 0, (int)buf);
215 warning ("Couldn't get registers");
219 for ( regno = 0; regno < NUM_REGS-NUM_FREGS; regno++ )
220 supply_register (regno, buf + register_addr (regno, U_REGS_OFFSET));
226 Get the whole non-floating-point register state of the process and
227 replace them in the process from registers[].
233 char buf[17*sizeof(unsigned int)];
235 ret = ptrace (PTRACE_GETREGS, inferior_pid, 0, (int)buf);
238 warning ("Couldn't get registers");
242 for ( regno = 0; regno < NUM_REGS-NUM_FREGS; regno++ )
244 if ( register_valid[regno] )
245 read_register_gen (regno, buf + register_addr (regno, U_REGS_OFFSET));
248 ret = ptrace (PTRACE_SETREGS, inferior_pid, 0, (int)buf);
252 warning ("Couldn't write floating point status");
259 /* Fetch registers from the child process.
260 Fetch all if regno == -1, otherwise fetch all ordinary
261 registers or all floating point registers depending
262 upon the value of regno. */
265 fetch_inferior_registers (regno)
268 if ( (regno < NUM_REGS - NUM_FREGS) || (regno == -1) )
271 if ( (regno >= NUM_REGS - NUM_FREGS) || (regno == -1) )
276 /* Store our register values back into the inferior.
277 If REGNO is -1, do this for all registers.
278 Otherwise, REGNO specifies which register, which
279 then determines whether we store all ordinary
280 registers or all of the floating point registers. */
283 store_inferior_registers (regno)
286 if ( (regno < NUM_REGS - NUM_FREGS) || (regno == -1) )
289 if ( (regno >= NUM_REGS - NUM_FREGS) || (regno == -1) )
294 /* Find the minimal symbol named NAME, and return both the minsym
295 struct and its objfile. This probably ought to be in minsym.c, but
296 everything there is trying to deal with things like C++ and
297 SOFUN_ADDRESS_MAYBE_TURQUOISE, ... Since this is so simple, it may
298 be considered too special-purpose for general consumption. */
300 static struct minimal_symbol *
301 find_minsym_and_objfile (char *name, struct objfile **objfile_p)
303 struct objfile *objfile;
305 ALL_OBJFILES (objfile)
307 struct minimal_symbol *msym;
309 ALL_OBJFILE_MSYMBOLS (objfile, msym)
311 if (SYMBOL_NAME (msym)
312 && STREQ (SYMBOL_NAME (msym), name))
314 *objfile_p = objfile;
325 skip_hurd_resolver (CORE_ADDR pc)
327 /* The HURD dynamic linker is part of the GNU C library, so many
328 GNU/Linux distributions use it. (All ELF versions, as far as I
329 know.) An unresolved PLT entry points to "_dl_runtime_resolve",
330 which calls "fixup" to patch the PLT, and then passes control to
333 We look for the symbol `_dl_runtime_resolve', and find `fixup' in
334 the same objfile. If we are at the entry point of `fixup', then
335 we set a breakpoint at the return address (at the top of the
336 stack), and continue.
338 It's kind of gross to do all these checks every time we're
339 called, since they don't change once the executable has gotten
340 started. But this is only a temporary hack --- upcoming versions
341 of Linux will provide a portable, efficient interface for
342 debugging programs that use shared libraries. */
344 struct objfile *objfile;
345 struct minimal_symbol *resolver
346 = find_minsym_and_objfile ("_dl_runtime_resolve", &objfile);
350 struct minimal_symbol *fixup
351 = lookup_minimal_symbol ("fixup", 0, objfile);
353 if (fixup && SYMBOL_VALUE_ADDRESS (fixup) == pc)
354 return (SAVED_PC_AFTER_CALL (get_current_frame ()));
361 /* See the comments for SKIP_SOLIB_RESOLVER at the top of infrun.c.
363 1) decides whether a PLT has sent us into the linker to resolve
364 a function reference, and
365 2) if so, tells us where to set a temporary breakpoint that will
366 trigger when the dynamic linker is done. */
369 i386_linux_skip_solib_resolver (CORE_ADDR pc)
373 /* Plug in functions for other kinds of resolvers here. */
374 result = skip_hurd_resolver (pc);