aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeff Law <law@redhat.com>1995-07-27 08:30:22 +0000
committerJeff Law <law@redhat.com>1995-07-27 08:30:22 +0000
commit46f569b40329c15225c9fc45552480b5b40a90f1 (patch)
tree5b402285d6beb9540bcdca28193218d49d4db093
parent068c9fd63f9a7ca5ec8ebc5aa1f758a4ea9f0405 (diff)
downloadgdb-46f569b40329c15225c9fc45552480b5b40a90f1.zip
gdb-46f569b40329c15225c9fc45552480b5b40a90f1.tar.gz
gdb-46f569b40329c15225c9fc45552480b5b40a90f1.tar.bz2
* hppa-tdep.c (hppa_fix_call_dummy): Rewrite code for calling
into shared libraries. Amazing... 7363 has required serious work in gcc, gas, bfd, and now gdb...
-rw-r--r--gdb/ChangeLog5
-rw-r--r--gdb/hppa-tdep.c58
2 files changed, 40 insertions, 23 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index c270905..f6475fe 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,8 @@
+Thu Jul 27 01:22:08 1995 Jeffrey A. Law <law@rtl.cygnus.com>
+
+ * hppa-tdep.c (hppa_fix_call_dummy): Rewrite code for calling
+ into shared libraries.
+
Wed Jul 26 23:33:34 1995 Michael Meissner <meissner@cygnus.com>
* config/rs6000/tm-rs6000.h (rs6000_framedata): Add offsets the
diff --git a/gdb/hppa-tdep.c b/gdb/hppa-tdep.c
index a0f582c..4869772 100644
--- a/gdb/hppa-tdep.c
+++ b/gdb/hppa-tdep.c
@@ -1465,9 +1465,11 @@ hppa_fix_call_dummy (dummy, pc, fun, nargs, args, type, gcc_p)
{
CORE_ADDR dyncall_addr;
struct minimal_symbol *msymbol;
+ struct minimal_symbol *trampoline;
int flags = read_register (FLAGS_REGNUM);
struct unwind_table_entry *u;
+ trampoline = NULL;
msymbol = lookup_minimal_symbol ("$$dyncall", NULL, NULL);
if (msymbol == NULL)
error ("Can't find an address for $$dyncall trampoline");
@@ -1545,19 +1547,20 @@ hppa_fix_call_dummy (dummy, pc, fun, nargs, args, type, gcc_p)
if (u && u->stub_type == IMPORT)
{
CORE_ADDR new_fun;
- msymbol = lookup_minimal_symbol ("__d_plt_call", NULL, NULL);
- if (msymbol == NULL)
- msymbol = lookup_minimal_symbol ("__gcc_plt_call", NULL, NULL);
- if (msymbol == NULL)
+ /* Prefer __gcc_plt_call over the HP supplied routine because
+ __gcc_plt_call works for any number of arguments. */
+ trampoline = lookup_minimal_symbol ("__gcc_plt_call", NULL, NULL);
+ if (trampoline == NULL)
+ trampoline = lookup_minimal_symbol ("__d_plt_call", NULL, NULL);
+
+ if (trampoline == 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);
+ new_fun = SYMBOL_VALUE_ADDRESS (trampoline);
- if (strcmp (SYMBOL_NAME (msymbol), "__d_plt_call"))
- write_register (22, fun);
- else
+ if (strcmp (SYMBOL_NAME (trampoline), "__d_plt_call") == 0)
{
/* We have to store the address of the stub in __shlib_funcptr. */
msymbol = lookup_minimal_symbol ("__shlib_funcptr", NULL,
@@ -1566,12 +1569,17 @@ hppa_fix_call_dummy (dummy, pc, fun, nargs, args, type, gcc_p)
error ("Can't find an address for __shlib_funcptr");
target_write_memory (SYMBOL_VALUE_ADDRESS (msymbol), (char *)&fun, 4);
+
+ /* We want sr4export to call __d_plt_call, so we claim it is
+ the final target. Clear trampoline. */
+ fun = new_fun;
+ trampoline = NULL;
}
- fun = new_fun;
}
-/* Store upper 21 bits of function address into ldil */
-
+ /* Store upper 21 bits of function address into ldil. fun will either be
+ the final target (most cases) or __d_plt_call when calling into a shared
+ library and __gcc_plt_call is not available. */
store_unsigned_integer
(&dummy[FUNC_LDIL_OFFSET],
INSTRUCTION_SIZE,
@@ -1579,8 +1587,7 @@ hppa_fix_call_dummy (dummy, pc, fun, nargs, args, type, gcc_p)
extract_unsigned_integer (&dummy[FUNC_LDIL_OFFSET],
INSTRUCTION_SIZE)));
-/* Store lower 11 bits of function address into ldo */
-
+ /* Store lower 11 bits of function address into ldo */
store_unsigned_integer
(&dummy[FUNC_LDO_OFFSET],
INSTRUCTION_SIZE,
@@ -1590,30 +1597,35 @@ hppa_fix_call_dummy (dummy, pc, fun, nargs, args, type, gcc_p)
#ifdef SR4EXPORT_LDIL_OFFSET
{
- CORE_ADDR sr4export_addr;
+ CORE_ADDR trampoline_addr;
- /* We still need sr4export's address too. */
+ /* We may still need sr4export's address too. */
- msymbol = lookup_minimal_symbol ("_sr4export", NULL, NULL);
- if (msymbol == NULL)
- error ("Can't find an address for _sr4export trampoline");
+ if (trampoline == NULL)
+ {
+ msymbol = lookup_minimal_symbol ("_sr4export", NULL, NULL);
+ if (msymbol == NULL)
+ error ("Can't find an address for _sr4export trampoline");
- sr4export_addr = SYMBOL_VALUE_ADDRESS (msymbol);
+ trampoline_addr = SYMBOL_VALUE_ADDRESS (msymbol);
+ }
+ else
+ trampoline_addr = SYMBOL_VALUE_ADDRESS (trampoline);
-/* Store upper 21 bits of sr4export's address into ldil */
+ /* Store upper 21 bits of trampoline's address into ldil */
store_unsigned_integer
(&dummy[SR4EXPORT_LDIL_OFFSET],
INSTRUCTION_SIZE,
- deposit_21 (sr4export_addr >> 11,
+ deposit_21 (trampoline_addr >> 11,
extract_unsigned_integer (&dummy[SR4EXPORT_LDIL_OFFSET],
INSTRUCTION_SIZE)));
-/* Store lower 11 bits of sr4export's address into ldo */
+ /* Store lower 11 bits of trampoline's address into ldo */
store_unsigned_integer
(&dummy[SR4EXPORT_LDO_OFFSET],
INSTRUCTION_SIZE,
- deposit_14 (sr4export_addr & MASK_11,
+ deposit_14 (trampoline_addr & MASK_11,
extract_unsigned_integer (&dummy[SR4EXPORT_LDO_OFFSET],
INSTRUCTION_SIZE)));
}