diff options
-rw-r--r-- | bfd/ChangeLog | 4 | ||||
-rw-r--r-- | bfd/elf-hppa.h | 59 |
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); } |