X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=bfd%2Felf64-s390.c;h=6e7b5d94c201fab308c175f98ee35e816cbd4901;hb=239e1f3afa2f6bc24acde3b81481f933b40a3531;hp=222e1e44bf810a5376c54fa8263436fc947cd301;hpb=f8df10f4f595488c4b6a8e49ffc99721d5aefdba;p=binutils-gdb.git diff --git a/bfd/elf64-s390.c b/bfd/elf64-s390.c index 222e1e44bf8..6e7b5d94c20 100644 --- a/bfd/elf64-s390.c +++ b/bfd/elf64-s390.c @@ -1,5 +1,5 @@ /* IBM S/390-specific support for 64-bit ELF - Copyright 2000, 2001 Free Software Foundation, Inc. + Copyright 2000, 2001, 2002 Free Software Foundation, Inc. Contributed Martin Schwidefsky (schwidefsky@de.ibm.com). This file is part of BFD, the Binary File Descriptor library. @@ -45,7 +45,7 @@ static boolean elf_s390_check_relocs PARAMS ((bfd *, struct bfd_link_info *, asection *, const Elf_Internal_Rela *)); static asection *elf_s390_gc_mark_hook - PARAMS ((bfd *, struct bfd_link_info *, Elf_Internal_Rela *, + PARAMS ((asection *, struct bfd_link_info *, Elf_Internal_Rela *, struct elf_link_hash_entry *, Elf_Internal_Sym *)); static boolean elf_s390_gc_sweep_hook PARAMS ((bfd *, struct bfd_link_info *, asection *, @@ -424,13 +424,13 @@ elf_s390_link_hash_table_create (abfd) struct elf_s390_link_hash_table *ret; bfd_size_type amt = sizeof (struct elf_s390_link_hash_table); - ret = (struct elf_s390_link_hash_table *) bfd_alloc (abfd, amt); + ret = (struct elf_s390_link_hash_table *) bfd_malloc (amt); if (ret == NULL) return NULL; if (! _bfd_elf_link_hash_table_init (&ret->elf, abfd, link_hash_newfunc)) { - bfd_release (abfd, ret); + free (ret); return NULL; } @@ -471,7 +471,7 @@ create_got_section (dynobj, info) (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY | SEC_LINKER_CREATED | SEC_READONLY)) - || ! bfd_set_section_alignment (dynobj, htab->srelgot, 2)) + || ! bfd_set_section_alignment (dynobj, htab->srelgot, 3)) return false; return true; } @@ -776,7 +776,7 @@ elf_s390_check_relocs (abfd, info, sec, relocs) flags |= SEC_ALLOC | SEC_LOAD; if (sreloc == NULL || ! bfd_set_section_flags (dynobj, sreloc, flags) - || ! bfd_set_section_alignment (dynobj, sreloc, 2)) + || ! bfd_set_section_alignment (dynobj, sreloc, 3)) return false; } elf_section_data (sec)->sreloc = sreloc; @@ -839,7 +839,7 @@ elf_s390_check_relocs (abfd, info, sec, relocs) /* This relocation describes which C++ vtable entries are actually used. Record for later use during GC. */ case R_390_GNU_VTENTRY: - if (!_bfd_elf64_gc_record_vtentry (abfd, sec, h, rel->r_offset)) + if (!_bfd_elf64_gc_record_vtentry (abfd, sec, h, rel->r_addend)) return false; break; @@ -855,8 +855,8 @@ elf_s390_check_relocs (abfd, info, sec, relocs) relocation. */ static asection * -elf_s390_gc_mark_hook (abfd, info, rel, h, sym) - bfd *abfd; +elf_s390_gc_mark_hook (sec, info, rel, h, sym) + asection *sec; struct bfd_link_info *info ATTRIBUTE_UNUSED; Elf_Internal_Rela *rel; struct elf_link_hash_entry *h; @@ -886,15 +886,7 @@ elf_s390_gc_mark_hook (abfd, info, rel, h, sym) } } else - { - if (!(elf_bad_symtab (abfd) - && ELF_ST_BIND (sym->st_info) != STB_LOCAL) - && ! ((sym->st_shndx <= 0 || sym->st_shndx >= SHN_LORESERVE) - && sym->st_shndx != SHN_COMMON)) - { - return bfd_section_from_elf_index (abfd, sym->st_shndx); - } - } + return bfd_section_from_elf_index (sec->owner, sym->st_shndx); return NULL; } @@ -1025,14 +1017,16 @@ elf_s390_adjust_dynamic_symbol (info, h) /* If this is a function, put it in the procedure linkage table. We will fill in the contents of the procedure linkage table later - (although we could actually do it here). */ + (although we could actually do it here). */ if (h->type == STT_FUNC || (h->elf_link_hash_flags & ELF_LINK_HASH_NEEDS_PLT) != 0) { if (h->plt.refcount <= 0 || (! info->shared && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_DYNAMIC) == 0 - && (h->elf_link_hash_flags & ELF_LINK_HASH_REF_DYNAMIC) == 0)) + && (h->elf_link_hash_flags & ELF_LINK_HASH_REF_DYNAMIC) == 0 + && h->root.type != bfd_link_hash_undefweak + && h->root.type != bfd_link_hash_undefined)) { /* This case can occur if we saw a PLT32 reloc in an input file, but the symbol was never referred to by a dynamic @@ -1173,10 +1167,12 @@ allocate_dynrelocs (h, inf) struct elf_s390_link_hash_entry *eh; struct elf_s390_dyn_relocs *p; - if (h->root.type == bfd_link_hash_indirect - || h->root.type == bfd_link_hash_warning) + if (h->root.type == bfd_link_hash_indirect) return true; + if (h->root.type == bfd_link_hash_warning) + h = (struct elf_link_hash_entry *) h->root.u.i.link; + info = (struct bfd_link_info *) inf; htab = elf_s390_hash_table (info); @@ -1343,6 +1339,9 @@ readonly_dynrelocs (h, inf) struct elf_s390_link_hash_entry *eh; struct elf_s390_dyn_relocs *p; + if (h->root.type == bfd_link_hash_warning) + h = (struct elf_link_hash_entry *) h->root.u.i.link; + eh = (struct elf_s390_link_hash_entry *) h; for (p = eh->dyn_relocs; p != NULL; p = p->next) { @@ -1422,10 +1421,12 @@ elf_s390_size_dynamic_sections (output_bfd, info) linker script /DISCARD/, so we'll be discarding the relocs too. */ } - else + else if (p->count != 0) { srela = elf_section_data (p->sec)->sreloc; srela->_raw_size += p->count * sizeof (Elf64_External_Rela); + if ((p->sec->output_section->flags & SEC_READONLY) != 0) + info->flags |= DF_TEXTREL; } } } @@ -1547,7 +1548,9 @@ elf_s390_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) { @@ -1582,6 +1585,9 @@ elf_s390_relocate_section (output_bfd, info, input_bfd, input_section, Elf_Internal_Rela *rel; Elf_Internal_Rela *relend; + if (info->relocateable) + return true; + htab = elf_s390_hash_table (info); symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr; sym_hashes = elf_sym_hashes (input_bfd); @@ -1611,30 +1617,9 @@ elf_s390_relocate_section (output_bfd, info, input_bfd, input_section, bfd_set_error (bfd_error_bad_value); return false; } - howto = elf_howto_table + r_type; + howto = elf_howto_table + r_type; r_symndx = ELF64_R_SYM (rel->r_info); - - if (info->relocateable) - { - /* This is a relocateable link. We don't have to change - anything, unless the reloc is against a section symbol, - in which case we have to adjust according to where the - section symbol winds up in the output section. */ - if (r_symndx < symtab_hdr->sh_info) - { - sym = local_syms + r_symndx; - if (ELF_ST_TYPE (sym->st_info) == STT_SECTION) - { - sec = local_sections[r_symndx]; - rel->r_addend += sec->output_offset + sym->st_value; - } - } - - continue; - } - - /* This is a final link. */ h = NULL; sym = NULL; sec = NULL; @@ -1890,28 +1875,21 @@ elf_s390_relocate_section (output_bfd, info, input_bfd, input_section, time. */ skip = false; + relocate = false; - if (elf_section_data (input_section)->stab_info == NULL) - outrel.r_offset = rel->r_offset; - else - { - off = (_bfd_stab_section_offset - (output_bfd, htab->elf.stab_info, input_section, - &elf_section_data (input_section)->stab_info, - rel->r_offset)); - if (off == (bfd_vma) -1) - skip = true; - outrel.r_offset = off; - } + 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); if (skip) - { - memset (&outrel, 0, sizeof outrel); - relocate = false; - } + memset (&outrel, 0, sizeof outrel); else if (h != NULL && h->dynindx != -1 && (r_type == R_390_PC16 @@ -1924,7 +1902,6 @@ elf_s390_relocate_section (output_bfd, info, input_bfd, input_section, || (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_addend = rel->r_addend; } @@ -1958,9 +1935,11 @@ elf_s390_relocate_section (output_bfd, info, input_bfd, input_section, break; } + /* Dynamic relocs are not propagated for SEC_DEBUGGING sections + because such sections are not SEC_ALLOC and thus ld.so will + not process them. */ if (unresolved_reloc - && !(info->shared - && (input_section->flags & SEC_DEBUGGING) != 0 + && !((input_section->flags & SEC_DEBUGGING) != 0 && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_DYNAMIC) != 0)) (*_bfd_error_handler) (_("%s(%s+0x%lx): unresolvable relocation against symbol `%s'"), @@ -2333,7 +2312,7 @@ static boolean elf_s390_object_p (abfd) bfd *abfd; { - return bfd_default_set_arch_mach (abfd, bfd_arch_s390, bfd_mach_s390_esame); + return bfd_default_set_arch_mach (abfd, bfd_arch_s390, bfd_mach_s390_64); } /* @@ -2360,6 +2339,7 @@ const struct elf_size_info s390_elf64_size_info = bfd_elf64_write_out_phdrs, bfd_elf64_write_shdrs_and_ehdr, bfd_elf64_write_relocs, + bfd_elf64_swap_symbol_in, bfd_elf64_swap_symbol_out, bfd_elf64_slurp_reloc_table, bfd_elf64_slurp_symbol_table, @@ -2387,6 +2367,7 @@ const struct elf_size_info s390_elf64_size_info = #define elf_backend_want_plt_sym 0 #define elf_backend_got_header_size 24 #define elf_backend_plt_header_size PLT_ENTRY_SIZE +#define elf_backend_rela_normal 1 #define elf_info_to_howto elf_s390_info_to_howto