aboutsummaryrefslogtreecommitdiff
path: root/gdb/hppa-tdep.c
diff options
context:
space:
mode:
authorJeff Law <law@redhat.com>1994-12-29 02:31:10 +0000
committerJeff Law <law@redhat.com>1994-12-29 02:31:10 +0000
commit3200aa595ba623e1dbc0aa0ebf801835cfa751f2 (patch)
tree5e31d8fa25ae699769788438ad1e150932cf3722 /gdb/hppa-tdep.c
parentb6c1564694b444c90dc3852e629708a5a5961146 (diff)
downloadgdb-3200aa595ba623e1dbc0aa0ebf801835cfa751f2.zip
gdb-3200aa595ba623e1dbc0aa0ebf801835cfa751f2.tar.gz
gdb-3200aa595ba623e1dbc0aa0ebf801835cfa751f2.tar.bz2
* hppa-tdep.c (hppa_fix_call_dummy): Prefer import stubs over
export stubs and actual shared library functions so that lazy binding works correctly. Try both __d_plt_call and __gcc_plt_call trampolines for calling import stubs.
Diffstat (limited to 'gdb/hppa-tdep.c')
-rw-r--r--gdb/hppa-tdep.c69
1 files changed, 54 insertions, 15 deletions
diff --git a/gdb/hppa-tdep.c b/gdb/hppa-tdep.c
index 1b96ba9..fb08ba8 100644
--- a/gdb/hppa-tdep.c
+++ b/gdb/hppa-tdep.c
@@ -1419,16 +1419,48 @@ hppa_fix_call_dummy (dummy, pc, fun, nargs, args, type, gcc_p)
else
{
+#ifndef GDB_TARGET_IS_PA_ELF
/* FUN could be either an export stub, or the real address of a
- function in a shared library.
+ function in a shared library. We must call an import stub
+ rather than the export stub or real function for lazy binding
+ to work correctly. */
+ if (som_solib_get_got_by_pc (fun))
+ {
+ struct objfile *objfile;
+ struct minimal_symbol *funsymbol, *stub_symbol;
+ CORE_ADDR newfun = 0;
- To call this function we need to get the GOT/DP value for the target
- function. Do this by calling shared library support routines in
- somsolib.c. Once the GOT value is in %r19 we can call the procedure
- in the normal fashion. */
+ funsymbol = lookup_minimal_symbol_by_pc (fun);
+ if (!funsymbol)
+ error ("Unable to find minimal symbol for target fucntion.\n");
-#ifndef GDB_TARGET_IS_PA_ELF
- write_register (19, som_solib_get_got_by_pc (fun));
+ /* Search all the object files for an import symbol with the
+ right name. */
+ ALL_OBJFILES (objfile)
+ {
+ stub_symbol = lookup_minimal_symbol (SYMBOL_NAME (funsymbol),
+ objfile);
+ /* Found a symbol with the right name. */
+ if (stub_symbol)
+ {
+ struct unwind_table_entry *u;
+ /* It must be a shared library trampoline. */
+ if (SYMBOL_TYPE (stub_symbol) != mst_solib_trampoline)
+ continue;
+
+ /* It must also be an import stub. */
+ u = find_unwind_entry (SYMBOL_VALUE (stub_symbol));
+ if (!u || u->stub_type != IMPORT)
+ continue;
+
+ /* OK. Looks like the correct import stub. */
+ newfun = SYMBOL_VALUE (stub_symbol);
+ fun = newfun;
+ }
+ }
+ if (newfun == 0)
+ write_register (19, som_solib_get_got_by_pc (fun));
+ }
#endif
}
@@ -1444,20 +1476,27 @@ hppa_fix_call_dummy (dummy, pc, fun, nargs, args, type, gcc_p)
CORE_ADDR new_fun;
msymbol = lookup_minimal_symbol ("__d_plt_call", (struct objfile *) NULL);
if (msymbol == NULL)
- error ("Can't find an address for __d_plt_call trampoline");
+ msymbol = lookup_minimal_symbol ("__gcc_plt_call", NULL);
+
+ if (msymbol == NULL)
+ error ("Can't find an address for __d_plt_call or __gcc_plt_call trampoline");
/* This is where sr4export will jump to. */
new_fun = SYMBOL_VALUE_ADDRESS (msymbol);
- /* We have to store the address of the stub in __shlib_funcptr. */
- msymbol = lookup_minimal_symbol ("__shlib_funcptr",
- (struct objfile *)NULL);
- if (msymbol == NULL)
- error ("Can't find an address for __shlib_funcptr");
+ if (strcmp (SYMBOL_NAME (msymbol), "__d_plt_call"))
+ write_register (22, fun);
+ else
+ {
+ /* We have to store the address of the stub in __shlib_funcptr. */
+ msymbol = lookup_minimal_symbol ("__shlib_funcptr",
+ (struct objfile *)NULL);
+ if (msymbol == NULL)
+ error ("Can't find an address for __shlib_funcptr");
- target_write_memory (SYMBOL_VALUE_ADDRESS (msymbol), (char *)&fun, 4);
+ target_write_memory (SYMBOL_VALUE_ADDRESS (msymbol), (char *)&fun, 4);
+ }
fun = new_fun;
-
}
/* We still need sr4export's address too. */