diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 1a8b4b0fa2..f732014ffd 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,14 @@ +2002-06-16 John David Anglin + + * elf-hppa.h (elf_hppa_final_link): Fix formatting in comment. + Skip excluded sections in determing __gp value. + (elf_hppa_final_link_relocate): Use the symbol's address in + R_PARISC_FPTR64 relocations that don't need an opd entry. + * elf64-hppa.c (allocate_dynrel_entries): Simplify code. + (elf64_hppa_finalize_dynreloc): Likewise. + (elf64_hppa_size_dynamic_sections): Move comments and fix typo. + (elf64_hppa_finish_dynamic_symbol): Break up assert. + 2002-06-14 Sergey Grigoriev * pei-i386.c (COFF_SECTION_ALIGNMENT_ENTRIES): Enable 16 byte diff --git a/bfd/elf-hppa.h b/bfd/elf-hppa.h index 99a66f4e18..d5a3d15d4e 100644 --- a/bfd/elf-hppa.h +++ b/bfd/elf-hppa.h @@ -1296,22 +1296,22 @@ elf_hppa_final_link (abfd, info) 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. */ + that order) and set __gp to the base address of whichever + section is found first. */ sec = hppa_info->plt_sec; - if (sec) + if (sec && ! (sec->flags & SEC_EXCLUDE)) gp_val = (sec->output_offset + sec->output_section->vma + hppa_info->gp_offset); else { sec = hppa_info->dlt_sec; - if (!sec) + if (!sec || (sec->flags & SEC_EXCLUDE)) sec = hppa_info->opd_sec; - if (!sec) + if (!sec || (sec->flags & SEC_EXCLUDE)) sec = bfd_get_section_by_name (abfd, ".data"); - if (!sec) + if (!sec || (sec->flags & SEC_EXCLUDE)) return false; gp_val = sec->output_offset + sec->output_section->vma; @@ -2074,11 +2074,14 @@ elf_hppa_final_link_relocate (rel, input_bfd, output_bfd, hppa_info->opd_sec->contents + dyn_h->opd_offset + 24); } - /* We want the value of the OPD offset for this symbol, not - the symbol's actual address. */ - value = (dyn_h->opd_offset - + hppa_info->opd_sec->output_offset - + hppa_info->opd_sec->output_section->vma); + if (dyn_h->want_opd) + /* We want the value of the OPD offset for this symbol. */ + value = (dyn_h->opd_offset + + hppa_info->opd_sec->output_offset + + hppa_info->opd_sec->output_section->vma); + else + /* We want the address of the symbol. */ + value += addend; bfd_put_64 (input_bfd, value, hit_data); return bfd_reloc_ok; diff --git a/bfd/elf64-hppa.c b/bfd/elf64-hppa.c index cc4694348f..6a69d98d7f 100644 --- a/bfd/elf64-hppa.c +++ b/bfd/elf64-hppa.c @@ -1532,15 +1532,11 @@ allocate_dynrel_entries (dyn_h, data) for (rent = dyn_h->reloc_entries; rent; rent = rent->next) { - switch (rent->type) - { - case R_PARISC_FPTR64: - /* Allocate one iff we are building a shared library and don't - want an opd entry. */ - if (!x->info->shared && dyn_h->want_opd) - continue; - break; - } + /* Allocate one iff we are building a shared library, the relocation + isn't a R_PARISC_FPTR64, or we don't want an opd entry. */ + if (!shared && rent->type == R_PARISC_FPTR64 && dyn_h->want_opd) + continue; + hppa_info->other_rel_sec->_raw_size += sizeof (Elf64_External_Rela); /* Make sure this symbol gets into the dynamic symbol table if it is @@ -1722,10 +1718,9 @@ elf64_hppa_size_dynamic_sections (output_bfd, info) if (strcmp (name, ".plt") == 0) { + /* Strip this section if we don't need it; see the comment below. */ if (s->_raw_size == 0) { - /* Strip this section if we don't need it; see the - comment below. */ strip = true; } else @@ -1736,24 +1731,29 @@ elf64_hppa_size_dynamic_sections (output_bfd, info) } else if (strcmp (name, ".dlt") == 0) { + /* Strip this section if we don't need it; see the comment below. */ if (s->_raw_size == 0) { - /* Strip this section if we don't need it; see the - comment below. */ strip = true; } } else if (strcmp (name, ".opd") == 0) { + /* Strip this section if we don't need it; see the comment below. */ if (s->_raw_size == 0) { - /* Strip this section if we don't need it; see the - comment below. */ strip = true; } } - else if (strncmp (name, ".rela", 4) == 0) + else if (strncmp (name, ".rela", 5) == 0) { + /* If we don't need this section, strip it from the output file. + This is mostly to handle .rela.bss and .rela.plt. We must + create both sections in create_dynamic_sections, because they + must be created before the linker maps input sections to output + sections. The linker does that before adjust_dynamic_symbol + is called, and it is that function which decides whether + anything needs to go into these sections. */ if (s->_raw_size == 0) { /* If we don't need this section, strip it from the @@ -1951,9 +1951,6 @@ elf64_hppa_finish_dynamic_symbol (output_bfd, info, h, sym) spltrel = hppa_info->plt_rel_sec; sdltrel = hppa_info->dlt_rel_sec; - BFD_ASSERT (stub != NULL && splt != NULL - && sopd != NULL && sdlt != NULL) - /* Incredible. It is actually necessary to NOT use the symbol's real value when building the dynamic symbol table for a shared library. At least for symbols that refer to functions. @@ -1963,6 +1960,8 @@ elf64_hppa_finish_dynamic_symbol (output_bfd, info, h, sym) the original values (in elf64_hppa_link_output_symbol_hook). */ if (dyn_h && dyn_h->want_opd) { + BFD_ASSERT (sopd != NULL) + /* Save away the original value and section index so that we can restore them later. */ dyn_h->st_value = sym->st_value; @@ -1984,6 +1983,8 @@ elf64_hppa_finish_dynamic_symbol (output_bfd, info, h, sym) bfd_vma value; Elf_Internal_Rela rel; + BFD_ASSERT (splt != NULL && spltrel != NULL) + /* We do not actually care about the value in the PLT entry if we are creating a shared library and the symbol is still undefined, we create a dynamic relocation to fill @@ -2034,6 +2035,8 @@ elf64_hppa_finish_dynamic_symbol (output_bfd, info, h, sym) int insn; unsigned int max_offset; + BFD_ASSERT (stub != NULL) + /* Install the generic stub template. We are modifying the contents of the stub section, so we do not @@ -2357,15 +2360,10 @@ elf64_hppa_finalize_dynreloc (dyn_h, data) { Elf64_Internal_Rela rel; - switch (rent->type) - { - case R_PARISC_FPTR64: - /* Allocate one iff we are building a shared library and don't - want an opd entry. */ - if (!info->shared && dyn_h->want_opd) - continue; - break; - } + /* Allocate one iff we are building a shared library, the relocation + isn't a R_PARISC_FPTR64, or we don't want an opd entry. */ + if (!info->shared && rent->type == R_PARISC_FPTR64 && dyn_h->want_opd) + continue; /* Create a dynamic relocation for this entry.