/* IBM S/390-specific support for 64-bit ELF
- Copyright (C) 2000-2020 Free Software Foundation, Inc.
+ Copyright (C) 2000-2021 Free Software Foundation, Inc.
Contributed Martin Schwidefsky (schwidefsky@de.ibm.com).
This file is part of BFD, the Binary File Descriptor library.
bfd_vma offset;
} tls_ldm_got;
- /* Small local sym cache. */
- struct sym_cache sym_cache;
-
/* Options passed from the linker. */
struct s390_elf_params *params;
};
/* Get the s390 ELF linker hash table from a link_info structure. */
#define elf_s390_hash_table(p) \
- (elf_hash_table_id ((struct elf_link_hash_table *) ((p)->hash)) \
- == S390_ELF_DATA ? ((struct elf_s390_link_hash_table *) ((p)->hash)) : NULL)
+ ((is_elf_hash_table ((p)->hash) \
+ && elf_hash_table_id (elf_hash_table (p)) == S390_ELF_DATA) \
+ ? (struct elf_s390_link_hash_table *) (p)->hash : NULL)
#define ELF64 1
#include "elf-s390-common.c"
edir = (struct elf_s390_link_hash_entry *) dir;
eind = (struct elf_s390_link_hash_entry *) ind;
- if (ind->dyn_relocs != NULL)
- {
- if (dir->dyn_relocs != NULL)
- {
- struct elf_dyn_relocs **pp;
- struct elf_dyn_relocs *p;
-
- /* Add reloc counts against the indirect sym to the direct sym
- list. Merge any entries against the same section. */
- for (pp = &ind->dyn_relocs; (p = *pp) != NULL; )
- {
- struct elf_dyn_relocs *q;
-
- for (q = dir->dyn_relocs; q != NULL; q = q->next)
- if (q->sec == p->sec)
- {
- q->pc_count += p->pc_count;
- q->count += p->count;
- *pp = p->next;
- break;
- }
- if (q == NULL)
- pp = &p->next;
- }
- *pp = dir->dyn_relocs;
- }
-
- dir->dyn_relocs = ind->dyn_relocs;
- ind->dyn_relocs = NULL;
- }
-
if (ind->root.type == bfd_link_hash_indirect
&& dir->got.refcount <= 0)
{
if (r_symndx < symtab_hdr->sh_info)
{
/* A local symbol. */
- isym = bfd_sym_from_r_symndx (&htab->sym_cache,
+ isym = bfd_sym_from_r_symndx (&htab->elf.sym_cache,
abfd, r_symndx);
if (isym == NULL)
return FALSE;
asection *s;
void *vpp;
- isym = bfd_sym_from_r_symndx (&htab->sym_cache,
+ isym = bfd_sym_from_r_symndx (&htab->elf.sym_cache,
abfd, r_symndx);
if (isym == NULL)
return FALSE;
return TRUE;
}
-/* Set DF_TEXTREL if we find any dynamic relocs that apply to
- read-only sections. */
-
-static bfd_boolean
-maybe_set_textrel (struct elf_link_hash_entry *h, void *info_p)
-{
- asection *sec;
-
- if (h->root.type == bfd_link_hash_indirect)
- return TRUE;
-
- sec = _bfd_elf_readonly_dynrelocs (h);
- if (sec != NULL)
- {
- struct bfd_link_info *info = (struct bfd_link_info *) info_p;
-
- info->flags |= DF_TEXTREL;
- info->callbacks->minfo
- (_("%pB: dynamic relocation against `%pT' in read-only section `%pA'\n"),
- sec->owner, h->root.root.string, sec);
-
- /* Not an error, just cut short the traversal. */
- return FALSE;
- }
- return TRUE;
-}
-
/* Set the sizes of the dynamic sections. */
static bfd_boolean
return FALSE;
}
- if (htab->elf.dynamic_sections_created)
- {
- /* Add some entries to the .dynamic section. We fill in the
- values later, in elf_s390_finish_dynamic_sections, but we
- must add the entries now so that we get the correct size for
- the .dynamic section. The DT_DEBUG entry is filled in by the
- dynamic linker and used by the debugger. */
-#define add_dynamic_entry(TAG, VAL) \
- _bfd_elf_add_dynamic_entry (info, TAG, VAL)
-
- if (bfd_link_executable (info))
- {
- if (!add_dynamic_entry (DT_DEBUG, 0))
- return FALSE;
- }
-
- if (htab->elf.splt->size != 0)
- {
- if (!add_dynamic_entry (DT_PLTGOT, 0)
- || !add_dynamic_entry (DT_PLTRELSZ, 0)
- || !add_dynamic_entry (DT_PLTREL, DT_RELA)
- || !add_dynamic_entry (DT_JMPREL, 0))
- return FALSE;
- }
-
- if (relocs)
- {
- if (!add_dynamic_entry (DT_RELA, 0)
- || !add_dynamic_entry (DT_RELASZ, 0)
- || !add_dynamic_entry (DT_RELAENT, sizeof (Elf64_External_Rela)))
- return FALSE;
-
- /* If any dynamic relocs apply to a read-only section,
- then we need a DT_TEXTREL entry. */
- if ((info->flags & DF_TEXTREL) == 0)
- elf_link_hash_traverse (&htab->elf, maybe_set_textrel, info);
-
- if ((info->flags & DF_TEXTREL) != 0)
- {
- if (!add_dynamic_entry (DT_TEXTREL, 0))
- return FALSE;
- }
- }
- }
-#undef add_dynamic_entry
-
- return TRUE;
+ return _bfd_elf_add_dynamic_tags (output_bfd, info, relocs);
}
/* Return the base VMA address which should be subtracted from real addresses
& 0xff00f000) == 0xe300c000
&& bfd_get_8 (input_bfd,
contents + rel->r_offset + 3) == 0x04))
- && (isym = bfd_sym_from_r_symndx (&htab->sym_cache,
+ && (isym = bfd_sym_from_r_symndx (&htab->elf.sym_cache,
input_bfd, r_symndx))
&& isym->st_shndx != SHN_ABS
&& h != htab->elf.hdynamic
bfd_put_64 (output_bfd, (bfd_vma) 0,
htab->elf.hgot->root.u.def.section->contents + 16);
}
- elf_section_data (htab->elf.sgot->output_section)
- ->this_hdr.sh_entsize = 8;
+ if (htab->elf.sgot != NULL && htab->elf.sgot->size > 0)
+ elf_section_data (htab->elf.sgot->output_section)
+ ->this_hdr.sh_entsize = 8;
}
/* Finish dynamic symbol for local IFUNC symbols. */
if (local_plt[i].plt.offset != (bfd_vma) -1)
{
asection *sec = local_plt[i].sec;
- isym = bfd_sym_from_r_symndx (&htab->sym_cache, ibfd, i);
+ isym = bfd_sym_from_r_symndx (&htab->elf.sym_cache, ibfd, i);
if (isym == NULL)
return FALSE;