summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bfd/ChangeLog4
-rw-r--r--bfd/elf-hppa.h59
2 files changed, 54 insertions, 9 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index 9d0dde1f393..95c0254d34f 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -5,6 +5,10 @@ Thu Sep 16 11:21:13 1999 Catherine Moore <clm@cygnus.com>
Thu Sep 16 10:48:17 1999 Jeffrey A Law (law@cygnus.com)
+ * elf-hppa.h (elf_hppa_final_link): If unable to find __gp in the
+ symbol table, then just compute a suitable value (but do not
+ create a __gp symbol).
+
* elf-hppa.h (elf_hppa_relocate_section): Allow undefined
symbols when building shared libraries.
(elf_hppa_final_link_relocate): Correct handling of PCREL
diff --git a/bfd/elf-hppa.h b/bfd/elf-hppa.h
index d0785b6812f..900247ce3a3 100644
--- a/bfd/elf-hppa.h
+++ b/bfd/elf-hppa.h
@@ -854,20 +854,61 @@ elf_hppa_final_link (abfd, info)
{
struct elf_link_hash_entry *gp;
bfd_vma gp_val;
+ struct elf64_hppa_link_hash_table *hppa_info;
- /* The linker script defines a value for __gp, we just need to
- install that value into magic place for the BFD. */
+ hppa_info = elf64_hppa_hash_table (info);
+
+ /* The linker script defines a value for __gp iff it was referenced
+ by one of the objects being linked. First try to find the symbol
+ in the hash table. If that fails, just compute the value __gp
+ should have had. */
gp = elf_link_hash_lookup (elf_hash_table (info), "__gp", false,
false, false);
- /* Adjust the value of __gp as we may want to slide it into the
- .plt section so that the stubs can access PLT entries without
- using an addil sequence. */
- gp->root.u.def.value += elf64_hppa_hash_table (info)->gp_offset;
+ if (gp)
+ {
+
+ /* Adjust the value of __gp as we may want to slide it into the
+ .plt section so that the stubs can access PLT entries without
+ using an addil sequence. */
+ gp->root.u.def.value += elf64_hppa_hash_table (info)->gp_offset;
+
+ gp_val = (gp->root.u.def.section->output_section->vma
+ + gp->root.u.def.section->output_offset
+ + gp->root.u.def.value);
+ }
+ else
+ {
+ asection *sec;
+
+
+ /* First look for a .plt section. If found, then __gp is the
+ address of the .plt + gp_offset.
+
+ If no .plt is found, then look for .dlt, .opd and .data (in
+ that order) and set __gp to the base address of whichever section
+ is found first. */
+
+ sec = hppa_info->plt_sec;
+ if (sec)
+ gp_val = (sec->output_offset
+ + sec->output_section->vma
+ + hppa_info->gp_offset);
+ else
+ {
+ sec = hppa_info->dlt_sec;
+ if (!sec)
+ sec = hppa_info->opd_sec;
+ if (!sec)
+ sec = bfd_get_section_by_name (abfd, ".data");
+ if (!sec)
+ return false;
+
+ gp_val = sec->output_offset + sec->output_section->vma;
+ }
+ }
- gp_val = (gp->root.u.def.section->output_section->vma
- + gp->root.u.def.section->output_offset
- + gp->root.u.def.value);
+ /* Install whatever value we found/computed for __gp. */
_bfd_set_gp_value (abfd, gp_val);
}