diff options
author | obrien <obrien@FreeBSD.org> | 2002-02-22 04:18:42 +0000 |
---|---|---|
committer | obrien <obrien@FreeBSD.org> | 2002-02-22 04:18:42 +0000 |
commit | 670387a18a22cf299c750186efe8ca24cebb7e05 (patch) | |
tree | 70c0d6a941b83c97839ec1237622c20ea8beb870 /contrib/binutils/bfd/elf64-ppc.c | |
parent | fc89183cdc6be5afa8deb7250fd15a20832ab528 (diff) | |
download | FreeBSD-src-670387a18a22cf299c750186efe8ca24cebb7e05.zip FreeBSD-src-670387a18a22cf299c750186efe8ca24cebb7e05.tar.gz |
Import of Binutils from the FSF 2.12 branch (pre-.0 release).
These bits are taken from the FSF anoncvs repo on 21-Feburary-2002 20:15 PST.
Diffstat (limited to 'contrib/binutils/bfd/elf64-ppc.c')
-rw-r--r-- | contrib/binutils/bfd/elf64-ppc.c | 76 |
1 files changed, 46 insertions, 30 deletions
diff --git a/contrib/binutils/bfd/elf64-ppc.c b/contrib/binutils/bfd/elf64-ppc.c index da339bb..097231a 100644 --- a/contrib/binutils/bfd/elf64-ppc.c +++ b/contrib/binutils/bfd/elf64-ppc.c @@ -156,11 +156,8 @@ static boolean ppc64_elf_finish_dynamic_sections /* Since .opd is an array of descriptors and each entry will end up with identical R_PPC64_RELATIVE relocs, there is really no need to propagate .opd relocs; The dynamic linker should be taught to - relocate .opd without reloc entries. FIXME: the dynamic linker - will need to know where and how large .opd is via a couple of new - DT_PPC64_* tags, or perhaps just with one reloc that specifies the - start of .opd via its offset and the size via its addend. Also, - .opd should be trimmed of unused values. */ + relocate .opd without reloc entries. FIXME: .opd should be trimmed + of unused values. */ #ifndef NO_OPD_RELOCS #define NO_OPD_RELOCS 0 #endif @@ -2500,20 +2497,15 @@ func_desc_adjust (h, inf) fdh = elf_link_hash_lookup (&htab->elf, h->root.root.string + 1, false, false, true); - if (fdh == NULL && info->shared) + if (fdh == NULL + && info->shared + && (h->root.type == bfd_link_hash_undefined + || h->root.type == bfd_link_hash_undefweak)) { bfd *abfd; asymbol *newsym; - /* Create it as undefined. */ - if (h->root.type == bfd_link_hash_undefined - || h->root.type == bfd_link_hash_undefweak) - abfd = h->root.u.undef.abfd; - else if (h->root.type == bfd_link_hash_defined - || h->root.type == bfd_link_hash_defweak) - abfd = h->root.u.def.section->owner; - else - abort (); + abfd = h->root.u.undef.abfd; newsym = bfd_make_empty_symbol (abfd); newsym->name = h->root.root.string + 1; newsym->section = bfd_und_section_ptr; @@ -2529,6 +2521,7 @@ func_desc_adjust (h, inf) { return false; } + fdh->elf_link_hash_flags &= ~ELF_LINK_NON_ELF; } if (fdh != NULL @@ -2540,13 +2533,16 @@ func_desc_adjust (h, inf) if (fdh->dynindx == -1) if (! bfd_elf64_link_record_dynamic_symbol (info, fdh)) return false; - fdh->plt.refcount = h->plt.refcount; fdh->elf_link_hash_flags |= (h->elf_link_hash_flags & (ELF_LINK_HASH_REF_REGULAR | ELF_LINK_HASH_REF_DYNAMIC | ELF_LINK_HASH_REF_REGULAR_NONWEAK | ELF_LINK_NON_GOT_REF)); - fdh->elf_link_hash_flags |= ELF_LINK_HASH_NEEDS_PLT; + if (ELF_ST_VISIBILITY (h->other) == STV_DEFAULT) + { + fdh->plt.refcount = h->plt.refcount; + fdh->elf_link_hash_flags |= ELF_LINK_HASH_NEEDS_PLT; + } ((struct ppc_link_hash_entry *) fdh)->is_func_descriptor = 1; fdh->root.root.string = h->root.root.string + 1; } @@ -2557,7 +2553,7 @@ func_desc_adjust (h, inf) This prevents a shared library from exporting syms that have been imported from another library. Function code syms that are really in the library we must leave global to prevent the - linker dragging a definition in from a static library. */ + linker dragging in a definition from a static library. */ force_local = (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0; _bfd_elf_link_hash_hide_symbol (info, h, force_local); } @@ -2996,10 +2992,12 @@ ppc64_elf_size_dynamic_sections (output_bfd, info) linker script /DISCARD/, so we'll be discarding the relocs too. */ } - else + else if (p->count != 0) { srel = elf_section_data (p->sec)->sreloc; srel->_raw_size += p->count * sizeof (Elf64_External_Rela); + if ((p->sec->output_section->flags & SEC_READONLY) != 0) + info->flags |= DF_TEXTREL; } } } @@ -3127,6 +3125,13 @@ ppc64_elf_size_dynamic_sections (output_bfd, info) return false; } + if (NO_OPD_RELOCS) + { + if (!add_dynamic_entry (DT_PPC64_OPD, 0) + || !add_dynamic_entry (DT_PPC64_OPDSZ, 0)) + return false; + } + if (relocs) { if (!add_dynamic_entry (DT_RELA, 0) @@ -3136,7 +3141,9 @@ ppc64_elf_size_dynamic_sections (output_bfd, info) /* If any dynamic relocs apply to a read-only section, then we need a DT_TEXTREL entry. */ - elf_link_hash_traverse (&htab->elf, readonly_dynrelocs, (PTR) info); + if ((info->flags & DF_TEXTREL) == 0) + elf_link_hash_traverse (&htab->elf, readonly_dynrelocs, + (PTR) info); if ((info->flags & DF_TEXTREL) != 0) { @@ -3248,7 +3255,7 @@ ppc64_elf_size_stubs (obfd, info, changed) /* If the .plt doesn't have any entries crossing a 64k boundary, then there is no need for bigger stubs. */ - if (next_64k <= plt_offset + htab->splt->_raw_size) + if (plt_offset + htab->splt->_raw_size <= next_64k) return true; /* OK, so we have at least one transition. Since .plt entries are @@ -3955,22 +3962,21 @@ ppc64_elf_relocate_section (output_bfd, info, input_bfd, input_section, time. */ skip = false; + relocate = false; outrel.r_offset = _bfd_elf_section_offset (output_bfd, info, input_section, rel->r_offset); if (outrel.r_offset == (bfd_vma) -1) skip = true; - + else if (outrel.r_offset == (bfd_vma) -2) + skip = true, relocate = true; outrel.r_offset += (input_section->output_section->vma + input_section->output_offset); outrel.r_addend = addend; if (skip) - { - relocate = false; - memset (&outrel, 0, sizeof outrel); - } + memset (&outrel, 0, sizeof outrel); else if (h != NULL && h->dynindx != -1 && !is_opd @@ -3979,10 +3985,7 @@ ppc64_elf_relocate_section (output_bfd, info, input_bfd, input_section, || !info->symbolic || (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0)) - { - relocate = false; - outrel.r_info = ELF64_R_INFO (h->dynindx, r_type); - } + outrel.r_info = ELF64_R_INFO (h->dynindx, r_type); else { /* This symbol is local, or marked to become local, @@ -4351,6 +4354,7 @@ ppc64_elf_finish_dynamic_sections (output_bfd, info) for (; dyncon < dynconend; dyncon++) { Elf_Internal_Dyn dyn; + asection *s; bfd_elf64_swap_dyn_in (dynobj, dyncon, &dyn); @@ -4364,6 +4368,18 @@ ppc64_elf_finish_dynamic_sections (output_bfd, info) + htab->sglink->output_offset); break; + case DT_PPC64_OPD: + s = bfd_get_section_by_name (output_bfd, ".opd"); + if (s != NULL) + dyn.d_un.d_ptr = s->vma; + break; + + case DT_PPC64_OPDSZ: + s = bfd_get_section_by_name (output_bfd, ".opd"); + if (s != NULL) + dyn.d_un.d_val = s->_raw_size; + break; + case DT_PLTGOT: dyn.d_un.d_ptr = (htab->splt->output_section->vma + htab->splt->output_offset); |