diff options
author | Jeff Law <law@redhat.com> | 1994-12-29 02:31:10 +0000 |
---|---|---|
committer | Jeff Law <law@redhat.com> | 1994-12-29 02:31:10 +0000 |
commit | 3200aa595ba623e1dbc0aa0ebf801835cfa751f2 (patch) | |
tree | 5e31d8fa25ae699769788438ad1e150932cf3722 /gdb/hppa-tdep.c | |
parent | b6c1564694b444c90dc3852e629708a5a5961146 (diff) | |
download | gdb-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.c | 69 |
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. */ |