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:05:29 +0100
commitca31ab1d675c1e20cee5f8cb213c52e3d7352496 (patch)
tree8441f5bff6a4145d0693341bc00f536babd3a8b2 /gdb/linespec.c
parent8388016d7ff8b88d29f2427963f26a6b8bbb03b1 (diff)
downloadfsf-binutils-gdb-ca31ab1d675c1e20cee5f8cb213c52e3d7352496.zip
fsf-binutils-gdb-ca31ab1d675c1e20cee5f8cb213c52e3d7352496.tar.gz
fsf-binutils-gdb-ca31ab1d675c1e20cee5f8cb213c52e3d7352496.tar.bz2
Calling ifunc functions when resolver has debug info, user symbol same name
If the GNU ifunc resolver has the same name as the user visible symbol, and the resolver has debug info, then the DWARF info for the resolver masks the ifunc minsym. In that scenario, if you try calling the ifunc from GDB, you call the resolver instead. With the gnu-ifunc.exp testcase added in a following patch, you'd see: (gdb) p gnu_ifunc (3) $1 = (int (*)(int)) 0x400753 <final> (gdb) FAIL: gdb.base/gnu-ifunc.exp: resolver_attr=0: resolver_debug=1: resolved_debug=0: p gnu_ifunc (3) ^^^^^^^^^^^^^^^^ That is, we called the ifunc resolver manually, which returned a pointer to the ifunc target function ("final"). The "final" symbol is the function that GDB should have called automatically, ~~~~~~~~~~~~ int final (int arg) { return arg + 1; } ~~~~~~~~~ which is what happens if you don't have debug info for the resolver: (gdb) p gnu_ifunc (3) $1 = 4 (gdb) PASS: gdb.base/gnu-ifunc.exp: resolver_attr=0: resolver_debug=0: resolved_debug=1: p gnu_ifunc (3) ^^^^^^^^^^^^^^^^ or if the resolver's symbol has a different name from the ifunc (as is the case with modern uses of ifunc via __attribute__ ifunc, such as glibc uses): (gdb) p gnu_ifunc (3) $1 = 4 (gdb) PASS: gdb.base/gnu-ifunc.exp: resolver_attr=1: resolver_debug=1: resolved_debug=0: p gnu_ifunc (3) ^^^^^^^^^^^^^^^ in which case after this patch, you can still call the resolver directly if you want: (gdb) p gnu_ifunc_resolver (3) $1 = (int (*)(int)) 0x400753 <final> gdb/ChangeLog: 2018-04-26 Pedro Alves <palves@redhat.com> * c-exp.y (variable production): Prefer ifunc minsyms over regular function symbols. * symtab.c (find_gnu_ifunc): New function. * minsyms.h (lookup_msym_prefer): New enum. (lookup_minimal_symbol_by_pc_section): Replace 'want_trampoline' parameter by a lookup_msym_prefer parameter. * symtab.h (find_gnu_ifunc): New declaration.
Diffstat (limited to 'gdb/linespec.c')
-rw-r--r--gdb/linespec.c3
1 files changed, 3 insertions, 0 deletions
diff --git a/gdb/linespec.c b/gdb/linespec.c
index 7ef8012..8951c1e 100644
--- a/gdb/linespec.c
+++ b/gdb/linespec.c
@@ -4343,6 +4343,7 @@ add_minsym (struct minimal_symbol *minsym, struct objfile *objfile,
struct bound_minimal_symbol mo = {minsym, objfile};
msyms->push_back (mo);
+ return;
}
/* Search for minimal symbols called NAME. If SEARCH_PSPACE
@@ -4383,6 +4384,7 @@ search_minsyms_for_name (struct collect_info *info,
add_minsym (msym, objfile, nullptr,
info->state->list_mode,
&minsyms);
+ return false;
});
}
}
@@ -4398,6 +4400,7 @@ search_minsyms_for_name (struct collect_info *info,
{
add_minsym (msym, SYMTAB_OBJFILE (symtab), symtab,
info->state->list_mode, &minsyms);
+ return false;
});
}
}