aboutsummaryrefslogtreecommitdiff
path: root/gdb/linespec.c
diff options
context:
space:
mode:
authorPedro Alves <palves@redhat.com>2018-04-26 13:01:26 +0100
committerPedro Alves <palves@redhat.com>2018-04-26 13:06:21 +0100
commit3467ec66bc1f30cf3ed7f9fe75234c96fc9c92d5 (patch)
tree53e1794b06b1caf1108ab3c4ee90fc39637b2ce2 /gdb/linespec.c
parent28f4fa4d0540ac6a23930202f39782167667e373 (diff)
downloadgdb-3467ec66bc1f30cf3ed7f9fe75234c96fc9c92d5.zip
gdb-3467ec66bc1f30cf3ed7f9fe75234c96fc9c92d5.tar.gz
gdb-3467ec66bc1f30cf3ed7f9fe75234c96fc9c92d5.tar.bz2
Fix setting breakpoints on ifunc functions after they're already resolved
This fixes setting breakpoints on ifunc functions by name after the ifunc has already been resolved. In that case, if you have debug info for the ifunc resolver, without the fix, then gdb puts a breakpoint past the prologue of the resolver, instead of setting a breakpoint at the ifunc target: break gnu_ifunc Breakpoint 4 at 0x7ffff7bd36f2: file src/gdb/testsuite/gdb.base/gnu-ifunc-lib.c, line 34. (gdb) continue Continuing. [Inferior 1 (process 13300) exited normally] (gdb) above we should have stopped at "final", but didn't because we never resolved the ifunc to the final location. If you don't have debug info for the resolver, GDB manages to resolve the ifunc target, but, it should be setting a breakpoint after the prologue of the final function, and instead what you get is that GDB sets a breakpoint on the first address of the target function. With the gnu-ifunc.exp tests added by a later patch, we get, without the fix: (gdb) break gnu_ifunc Breakpoint 4 at 0x400753 (gdb) continue Continuing. Breakpoint 4, final (arg=1) at src/gdb/testsuite/gdb.base/gnu-ifunc-final.c:20 20 { vs, fixed: (gdb) break gnu_ifunc Breakpoint 4 at 0x40075a: file src/gdb/testsuite/gdb.base/gnu-ifunc-final.c, line 21. (gdb) continue Continuing. Breakpoint 4, final (arg=2) at src/gdb/testsuite/gdb.base/gnu-ifunc-final.c:21 21 return arg + 1; (gdb) Fix the problems above by moving the ifunc target resolving to linespec.c, before we skip a function's prologue. We need to save something in the sal, so that set_breakpoint_location_function knows that it needs to create a bp_gnu_ifunc_resolver bp_location. Might as well just save a pointer to the minsym. gdb/ChangeLog: 2018-04-26 Pedro Alves <palves@redhat.com> * breakpoint.c (set_breakpoint_location_function): Don't resolve ifunc targets here. Instead, if we have an ifunc minsym, use its address/name. (add_location_to_breakpoint): Store the minsym and the objfile in the breakpoint location. * breakpoint.h (bp_location) <msymbol, objfile>: New fields. * linespec.c (minsym_found): Resolve GNU ifunc targets here. Record the minsym in the sal. * symtab.h (symtab_and_line) <msymbol>: New field.
Diffstat (limited to 'gdb/linespec.c')
-rw-r--r--gdb/linespec.c26
1 files changed, 23 insertions, 3 deletions
diff --git a/gdb/linespec.c b/gdb/linespec.c
index 8951c1e..8a52f5e 100644
--- a/gdb/linespec.c
+++ b/gdb/linespec.c
@@ -4244,10 +4244,24 @@ minsym_found (struct linespec_state *self, struct objfile *objfile,
struct minimal_symbol *msymbol,
std::vector<symtab_and_line> *result)
{
- struct symtab_and_line sal;
+ bool want_start_sal;
CORE_ADDR func_addr;
- if (msymbol_is_function (objfile, msymbol, &func_addr))
+ bool is_function = msymbol_is_function (objfile, msymbol, &func_addr);
+
+ if (is_function)
+ {
+ const char *msym_name = MSYMBOL_LINKAGE_NAME (msymbol);
+
+ if (MSYMBOL_TYPE (msymbol) == mst_text_gnu_ifunc)
+ want_start_sal = gnu_ifunc_resolve_name (msym_name, &func_addr);
+ else
+ want_start_sal = true;
+ }
+
+ symtab_and_line sal;
+
+ if (is_function && want_start_sal)
{
sal = find_pc_sect_line (func_addr, NULL, 0);
@@ -4270,7 +4284,13 @@ minsym_found (struct linespec_state *self, struct objfile *objfile,
else
{
sal.objfile = objfile;
- sal.pc = MSYMBOL_VALUE_ADDRESS (objfile, msymbol);
+ sal.msymbol = msymbol;
+ /* Store func_addr, not the minsym's address in case this was an
+ ifunc that hasn't been resolved yet. */
+ if (is_function)
+ sal.pc = func_addr;
+ else
+ sal.pc = MSYMBOL_VALUE_ADDRESS (objfile, msymbol);
sal.pspace = current_program_space;
}