X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=bfd%2Felfnn-aarch64.c;h=1ec405ef1e00456371f6b301b6e1c63306cc753b;hb=3677b7296185e6abfe8327c00c460712151ade15;hp=756ffeb6bdad04ce7fc466e7f3c23c462c6a806a;hpb=0db131fb835e4c4f6a024e86743467e7e01c965e;p=binutils-gdb.git diff --git a/bfd/elfnn-aarch64.c b/bfd/elfnn-aarch64.c index 756ffeb6bda..1ec405ef1e0 100644 --- a/bfd/elfnn-aarch64.c +++ b/bfd/elfnn-aarch64.c @@ -1,5 +1,5 @@ /* AArch64-specific support for NN-bit ELF. - Copyright (C) 2009-2020 Free Software Foundation, Inc. + Copyright (C) 2009-2021 Free Software Foundation, Inc. Contributed by ARM Ltd. This file is part of BFD, the Binary File Descriptor library. @@ -2570,9 +2570,6 @@ struct elf_aarch64_link_hash_entry { struct elf_link_hash_entry root; - /* Track dynamic relocs copied for this symbol. */ - struct elf_dyn_relocs *dyn_relocs; - /* Since PLT entries have variable size, we need to record the index into .got.plt instead of recomputing it from the PLT offset. */ @@ -2646,9 +2643,6 @@ struct elf_aarch64_link_hash_table /* The bytes of the subsequent PLT entry. */ const bfd_byte *plt_entry; - /* Small local sym cache. */ - struct sym_cache sym_cache; - /* For convenience in allocate_dynrelocs. */ bfd *obfd; @@ -2685,20 +2679,9 @@ struct elf_aarch64_link_hash_table /* JUMP_SLOT relocs for variant PCS symbols may be present. */ int variant_pcs; - /* The offset into splt of the PLT entry for the TLS descriptor - resolver. Special values are 0, if not necessary (or not found - to be necessary yet), and -1 if needed but not determined - yet. */ - bfd_vma tlsdesc_plt; - /* The number of bytes in the PLT enty for the TLS descriptor. */ bfd_size_type tlsdesc_plt_entry_size; - /* The GOT offset for the lazy trampoline. Communicated to the - loader via DT_TLSDESC_GOT. The magic value (bfd_vma) -1 - indicates an offset is not allocated. */ - bfd_vma dt_tlsdesc_got; - /* Used by local STT_GNU_IFUNC symbols. */ htab_t loc_hash_table; void * loc_hash_memory; @@ -2728,7 +2711,6 @@ elfNN_aarch64_link_hash_newfunc (struct bfd_hash_entry *entry, table, string)); if (ret != NULL) { - ret->dyn_relocs = NULL; ret->got_type = GOT_UNKNOWN; ret->plt_got_offset = (bfd_vma) - 1; ret->stub_cache = NULL; @@ -2855,37 +2837,6 @@ elfNN_aarch64_copy_indirect_symbol (struct bfd_link_info *info, edir = (struct elf_aarch64_link_hash_entry *) dir; eind = (struct elf_aarch64_link_hash_entry *) ind; - if (eind->dyn_relocs != NULL) - { - if (edir->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 = &eind->dyn_relocs; (p = *pp) != NULL;) - { - struct elf_dyn_relocs *q; - - for (q = edir->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 = edir->dyn_relocs; - } - - edir->dyn_relocs = eind->dyn_relocs; - eind->dyn_relocs = NULL; - } - if (ind->root.type == bfd_link_hash_indirect) { /* Copy over PLT info. */ @@ -2903,11 +2854,11 @@ elfNN_aarch64_copy_indirect_symbol (struct bfd_link_info *info, static void elfNN_aarch64_merge_symbol_attribute (struct elf_link_hash_entry *h, - const Elf_Internal_Sym *isym, + unsigned int st_other, bfd_boolean definition ATTRIBUTE_UNUSED, bfd_boolean dynamic ATTRIBUTE_UNUSED) { - unsigned int isym_sto = isym->st_other & ~ELF_ST_VISIBILITY (-1); + unsigned int isym_sto = st_other & ~ELF_ST_VISIBILITY (-1); unsigned int h_sto = h->other & ~ELF_ST_VISIBILITY (-1); if (isym_sto == h_sto) @@ -2947,7 +2898,7 @@ static struct bfd_link_hash_table * elfNN_aarch64_link_hash_table_create (bfd *abfd) { struct elf_aarch64_link_hash_table *ret; - bfd_size_type amt = sizeof (struct elf_aarch64_link_hash_table); + size_t amt = sizeof (struct elf_aarch64_link_hash_table); ret = bfd_zmalloc (amt); if (ret == NULL) @@ -2967,7 +2918,7 @@ elfNN_aarch64_link_hash_table_create (bfd *abfd) ret->plt_entry = elfNN_aarch64_small_plt_entry; ret->tlsdesc_plt_entry_size = PLT_TLSDESC_ENTRY_SIZE; ret->obfd = abfd; - ret->dt_tlsdesc_got = (bfd_vma) - 1; + ret->root.tlsdesc_got = (bfd_vma) - 1; if (!bfd_hash_table_init (&ret->stub_hash_table, stub_hash_newfunc, sizeof (struct elf_aarch64_stub_hash_entry))) @@ -3177,10 +3128,6 @@ _bfd_aarch64_create_stub_section (asection *section, if (s_name == NULL) return NULL; - /* PR 25210. Set the right class on the stub_bfd. */ - elf_elfheader (htab->stub_bfd)->e_ident[EI_CLASS] = ELFCLASSNN; - BFD_ASSERT (ELFCLASSNN == get_elf_backend_data (htab->stub_bfd)->s->elfclass); - memcpy (s_name, section->name, namelen); memcpy (s_name + namelen, STUB_SUFFIX, sizeof (STUB_SUFFIX)); return (*htab->add_stub_section) (s_name, section); @@ -3282,7 +3229,7 @@ _bfd_aarch64_add_stub_entry_after (const char *stub_name, static bfd_boolean aarch64_build_one_stub (struct bfd_hash_entry *gen_entry, - void *in_arg ATTRIBUTE_UNUSED) + void *in_arg) { struct elf_aarch64_stub_hash_entry *stub_entry; asection *stub_sec; @@ -3295,10 +3242,22 @@ aarch64_build_one_stub (struct bfd_hash_entry *gen_entry, unsigned int template_size; const uint32_t *template; unsigned int i; + struct bfd_link_info *info; /* Massage our args to the form they really have. */ stub_entry = (struct elf_aarch64_stub_hash_entry *) gen_entry; + info = (struct bfd_link_info *) in_arg; + + /* Fail if the target section could not be assigned to an output + section. The user should fix his linker script. */ + if (stub_entry->target_section->output_section == NULL + && info->non_contiguous_regions) + info->callbacks->einfo (_("%F%P: Could not assign '%pA' to an output section. " + "Retry without " + "--enable-non-contiguous-regions.\n"), + stub_entry->target_section); + stub_sec = stub_entry->stub_sec; /* Make a note of the offset within the stubs for this entry. */ @@ -3460,7 +3419,7 @@ elfNN_aarch64_setup_section_lists (bfd *output_bfd, unsigned int top_id, top_index; asection *section; asection **input_list, **list; - bfd_size_type amt; + size_t amt; struct elf_aarch64_link_hash_table *htab = elf_aarch64_hash_table (info); @@ -3538,7 +3497,7 @@ elfNN_aarch64_next_input_section (struct bfd_link_info *info, asection *isec) { asection **list = htab->input_list + isec->output_section->index; - if (*list != bfd_abs_section_ptr) + if (*list != bfd_abs_section_ptr && (isec->flags & SEC_CODE) != 0) { /* Steal the link_sec pointer for our list. */ /* This happens to make the list in reverse order, @@ -3559,67 +3518,96 @@ elfNN_aarch64_next_input_section (struct bfd_link_info *info, asection *isec) static void group_sections (struct elf_aarch64_link_hash_table *htab, bfd_size_type stub_group_size, - bfd_boolean stubs_always_before_branch) + bfd_boolean stubs_always_after_branch) { - asection **list = htab->input_list + htab->top_index; + asection **list = htab->input_list; do { asection *tail = *list; + asection *head; if (tail == bfd_abs_section_ptr) continue; + /* Reverse the list: we must avoid placing stubs at the + beginning of the section because the beginning of the text + section may be required for an interrupt vector in bare metal + code. */ +#define NEXT_SEC PREV_SEC + head = NULL; while (tail != NULL) + { + /* Pop from tail. */ + asection *item = tail; + tail = PREV_SEC (item); + + /* Push on head. */ + NEXT_SEC (item) = head; + head = item; + } + + while (head != NULL) { asection *curr; - asection *prev; - bfd_size_type total; + asection *next; + bfd_vma stub_group_start = head->output_offset; + bfd_vma end_of_next; - curr = tail; - total = tail->size; - while ((prev = PREV_SEC (curr)) != NULL - && ((total += curr->output_offset - prev->output_offset) - < stub_group_size)) - curr = prev; + curr = head; + while (NEXT_SEC (curr) != NULL) + { + next = NEXT_SEC (curr); + end_of_next = next->output_offset + next->size; + if (end_of_next - stub_group_start >= stub_group_size) + /* End of NEXT is too far from start, so stop. */ + break; + /* Add NEXT to the group. */ + curr = next; + } - /* OK, the size from the start of CURR to the end is less + /* OK, the size from the start to the start of CURR is less than stub_group_size and thus can be handled by one stub - section. (Or the tail section is itself larger than + section. (Or the head section is itself larger than stub_group_size, in which case we may be toast.) We should really be keeping track of the total size of stubs added here, as stubs contribute to the final output section size. */ do { - prev = PREV_SEC (tail); + next = NEXT_SEC (head); /* Set up this stub group. */ - htab->stub_group[tail->id].link_sec = curr; + htab->stub_group[head->id].link_sec = curr; } - while (tail != curr && (tail = prev) != NULL); + while (head != curr && (head = next) != NULL); /* But wait, there's more! Input sections up to stub_group_size - bytes before the stub section can be handled by it too. */ - if (!stubs_always_before_branch) + bytes after the stub section can be handled by it too. */ + if (!stubs_always_after_branch) { - total = 0; - while (prev != NULL - && ((total += tail->output_offset - prev->output_offset) - < stub_group_size)) + stub_group_start = curr->output_offset + curr->size; + + while (next != NULL) { - tail = prev; - prev = PREV_SEC (tail); - htab->stub_group[tail->id].link_sec = curr; + end_of_next = next->output_offset + next->size; + if (end_of_next - stub_group_start >= stub_group_size) + /* End of NEXT is too far from stubs, so stop. */ + break; + /* Add NEXT to the stub group. */ + head = next; + next = NEXT_SEC (head); + htab->stub_group[head->id].link_sec = curr; } } - tail = prev; + head = next; } } - while (list-- != htab->input_list); + while (list++ != htab->input_list + htab->top_index); free (htab->input_list); } +#undef PREV_SEC #undef PREV_SEC #define AARCH64_BITS(x, pos, n) (((x) >> (pos)) & ((1 << (n)) - 1)) @@ -3937,8 +3925,9 @@ _bfd_aarch64_erratum_835769_scan (bfd *input_bfd, sec_data = elf_aarch64_section_data (section); - qsort (sec_data->map, sec_data->mapcount, - sizeof (elf_aarch64_section_map), elf_aarch64_compare_mapping); + if (sec_data->mapcount) + qsort (sec_data->map, sec_data->mapcount, + sizeof (elf_aarch64_section_map), elf_aarch64_compare_mapping); for (span = 0; span < sec_data->mapcount; span++) { @@ -4221,8 +4210,9 @@ _bfd_aarch64_erratum_843419_scan (bfd *input_bfd, asection *section, sec_data = elf_aarch64_section_data (section); - qsort (sec_data->map, sec_data->mapcount, - sizeof (elf_aarch64_section_map), elf_aarch64_compare_mapping); + if (sec_data->mapcount) + qsort (sec_data->map, sec_data->mapcount, + sizeof (elf_aarch64_section_map), elf_aarch64_compare_mapping); for (span = 0; span < sec_data->mapcount; span++) { @@ -4317,9 +4307,15 @@ elfNN_aarch64_size_stubs (bfd *output_bfd, for (input_bfd = info->input_bfds; input_bfd != NULL; input_bfd = input_bfd->link.next) - if (!_bfd_aarch64_erratum_835769_scan (input_bfd, info, - &num_erratum_835769_fixes)) - return FALSE; + { + if (!is_aarch64_elf (input_bfd) + || (input_bfd->flags & BFD_LINKER_CREATED) != 0) + continue; + + if (!_bfd_aarch64_erratum_835769_scan (input_bfd, info, + &num_erratum_835769_fixes)) + return FALSE; + } _bfd_aarch64_resize_stubs (htab); (*htab->layout_sections_again) (); @@ -4335,6 +4331,10 @@ elfNN_aarch64_size_stubs (bfd *output_bfd, { asection *section; + if (!is_aarch64_elf (input_bfd) + || (input_bfd->flags & BFD_LINKER_CREATED) != 0) + continue; + for (section = input_bfd->sections; section != NULL; section = section->next) @@ -4357,6 +4357,10 @@ elfNN_aarch64_size_stubs (bfd *output_bfd, asection *section; Elf_Internal_Sym *local_syms = NULL; + if (!is_aarch64_elf (input_bfd) + || (input_bfd->flags & BFD_LINKER_CREATED) != 0) + continue; + /* We'll need the symbol table in a second. */ symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr; if (symtab_hdr->sh_info == 0) @@ -4619,7 +4623,7 @@ elfNN_aarch64_size_stubs (bfd *output_bfd, return TRUE; -error_ret_free_local: + error_ret_free_local: return FALSE; } @@ -5511,7 +5515,7 @@ elfNN_aarch64_final_link_relocate (reloc_howto_type *howto, switch (bfd_r_type) { default: -bad_ifunc_reloc: + bad_ifunc_reloc: if (h->root.root.string) name = h->root.root.string; else @@ -5885,6 +5889,23 @@ bad_ifunc_reloc: bfd_set_error (bfd_error_bad_value); return bfd_reloc_notsupported; } + value = _bfd_aarch64_elf_resolve_relocation (input_bfd, bfd_r_type, + place, value, + signed_addend, + weak_undef_p); + break; + + case BFD_RELOC_AARCH64_BRANCH19: + case BFD_RELOC_AARCH64_TSTBR14: + if (h && h->root.type == bfd_link_hash_undefined) + { + _bfd_error_handler + /* xgettext:c-format */ + (_("%pB: conditional branch to undefined symbol `%s' " + "not allowed"), input_bfd, h->root.root.string); + bfd_set_error (bfd_error_bad_value); + return bfd_reloc_notsupported; + } /* Fall through. */ case BFD_RELOC_AARCH64_16: @@ -5892,7 +5913,6 @@ bad_ifunc_reloc: case BFD_RELOC_AARCH64_32: #endif case BFD_RELOC_AARCH64_ADD_LO12: - case BFD_RELOC_AARCH64_BRANCH19: case BFD_RELOC_AARCH64_LDST128_LO12: case BFD_RELOC_AARCH64_LDST16_LO12: case BFD_RELOC_AARCH64_LDST32_LO12: @@ -5908,7 +5928,6 @@ bad_ifunc_reloc: case BFD_RELOC_AARCH64_MOVW_G2_NC: case BFD_RELOC_AARCH64_MOVW_G2_S: case BFD_RELOC_AARCH64_MOVW_G3: - case BFD_RELOC_AARCH64_TSTBR14: value = _bfd_aarch64_elf_resolve_relocation (input_bfd, bfd_r_type, place, value, signed_addend, weak_undef_p); @@ -7123,7 +7142,7 @@ elfNN_aarch64_relocate_section (bfd *output_bfd, Try to catch this situation here and provide a more helpful error message to the user. */ - if (addend & ((1 << howto->rightshift) - 1) + if (addend & (((bfd_vma) 1 << howto->rightshift) - 1) /* FIXME: Are we testing all of the appropriate reloc types here ? */ && (real_r_type == BFD_RELOC_AARCH64_LD_LO19_PCREL @@ -7312,33 +7331,16 @@ elfNN_aarch64_print_private_bfd_data (bfd *abfd, void *ptr) containing valid data. */ /* xgettext:c-format */ - fprintf (file, _("private flags = %lx:"), elf_elfheader (abfd)->e_flags); + fprintf (file, _("private flags = 0x%lx:"), elf_elfheader (abfd)->e_flags); if (flags) - fprintf (file, _("")); + fprintf (file, _(" ")); fputc ('\n', file); return TRUE; } -/* Find dynamic relocs for H that apply to read-only sections. */ - -static asection * -readonly_dynrelocs (struct elf_link_hash_entry *h) -{ - struct elf_dyn_relocs *p; - - for (p = elf_aarch64_hash_entry (h)->dyn_relocs; p != NULL; p = p->next) - { - asection *s = p->sec->output_section; - - if (s != NULL && (s->flags & SEC_READONLY) != 0) - return p->sec; - } - return NULL; -} - /* Return true if we need copy relocation against EH. */ static bfd_boolean @@ -7347,7 +7349,7 @@ need_copy_relocation_p (struct elf_aarch64_link_hash_entry *eh) struct elf_dyn_relocs *p; asection *s; - for (p = eh->dyn_relocs; p != NULL; p = p->next) + for (p = eh->root.dyn_relocs; p != NULL; p = p->next) { /* If there is any pc-relative reference, we need to keep copy relocation to avoid propagating the relocation into runtime that current glibc @@ -7610,7 +7612,7 @@ elfNN_aarch64_check_relocs (bfd *abfd, struct bfd_link_info *info, 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->root.sym_cache, abfd, r_symndx); if (isym == NULL) return FALSE; @@ -7826,9 +7828,7 @@ elfNN_aarch64_check_relocs (bfd *abfd, struct bfd_link_info *info, relocations we need for this symbol. */ if (h != NULL) { - struct elf_aarch64_link_hash_entry *eh; - eh = (struct elf_aarch64_link_hash_entry *) h; - head = &eh->dyn_relocs; + head = &h->dyn_relocs; } else { @@ -7839,7 +7839,7 @@ elfNN_aarch64_check_relocs (bfd *abfd, struct bfd_link_info *info, asection *s; void **vpp; - isym = bfd_sym_from_r_symndx (&htab->sym_cache, + isym = bfd_sym_from_r_symndx (&htab->root.sym_cache, abfd, r_symndx); if (isym == NULL) return FALSE; @@ -7857,7 +7857,7 @@ elfNN_aarch64_check_relocs (bfd *abfd, struct bfd_link_info *info, p = *head; if (p == NULL || p->sec != sec) { - bfd_size_type amt = sizeof *p; + size_t amt = sizeof *p; p = ((struct elf_dyn_relocs *) bfd_zalloc (htab->root.dynobj, amt)); if (p == NULL) @@ -8423,7 +8423,7 @@ elfNN_aarch64_new_section_hook (bfd *abfd, asection *sec) if (!sec->used_by_bfd) { _aarch64_elf_section_data *sdata; - bfd_size_type amt = sizeof (*sdata); + size_t amt = sizeof (*sdata); sdata = bfd_zalloc (abfd, amt); if (sdata == NULL) @@ -8671,7 +8671,7 @@ elfNN_aarch64_allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf) type. */ /* TLSDESC PLT is now needed, but not yet determined. */ - htab->tlsdesc_plt = (bfd_vma) - 1; + htab->root.tlsdesc_plt = (bfd_vma) - 1; } if (got_type & GOT_TLS_GD) @@ -8687,7 +8687,7 @@ elfNN_aarch64_allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf) h->got.offset = (bfd_vma) - 1; } - if (eh->dyn_relocs == NULL) + if (h->dyn_relocs == NULL) return TRUE; /* In the shared -Bsymbolic case, discard space allocated for @@ -8708,7 +8708,7 @@ elfNN_aarch64_allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf) { struct elf_dyn_relocs **pp; - for (pp = &eh->dyn_relocs; (p = *pp) != NULL;) + for (pp = &h->dyn_relocs; (p = *pp) != NULL;) { p->count -= p->pc_count; p->pc_count = 0; @@ -8721,11 +8721,11 @@ elfNN_aarch64_allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf) /* Also discard relocs on undefined weak syms with non-default visibility. */ - if (eh->dyn_relocs != NULL && h->root.type == bfd_link_hash_undefweak) + if (h->dyn_relocs != NULL && h->root.type == bfd_link_hash_undefweak) { if (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT || UNDEFWEAK_NO_DYNAMIC_RELOC (info, h)) - eh->dyn_relocs = NULL; + h->dyn_relocs = NULL; /* Make sure undefined weak symbols are output as a dynamic symbol in PIEs. */ @@ -8764,13 +8764,13 @@ elfNN_aarch64_allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf) goto keep; } - eh->dyn_relocs = NULL; + h->dyn_relocs = NULL; keep:; } /* Finally, allocate space. */ - for (p = eh->dyn_relocs; p != NULL; p = p->next) + for (p = h->dyn_relocs; p != NULL; p = p->next) { asection *sreloc; @@ -8793,7 +8793,6 @@ elfNN_aarch64_allocate_ifunc_dynrelocs (struct elf_link_hash_entry *h, { struct bfd_link_info *info; struct elf_aarch64_link_hash_table *htab; - struct elf_aarch64_link_hash_entry *eh; /* An example of a bfd_link_hash_indirect symbol is versioned symbol. For example: __gxx_personality_v0(bfd_link_hash_indirect) @@ -8813,15 +8812,12 @@ elfNN_aarch64_allocate_ifunc_dynrelocs (struct elf_link_hash_entry *h, info = (struct bfd_link_info *) inf; htab = elf_aarch64_hash_table (info); - eh = (struct elf_aarch64_link_hash_entry *) h; - /* Since STT_GNU_IFUNC symbol must go through PLT, we handle it here if it is defined and referenced in a non-shared object. */ if (h->type == STT_GNU_IFUNC && h->def_regular) return _bfd_elf_allocate_ifunc_dyn_relocs (info, h, - &eh->dyn_relocs, - NULL, + &h->dyn_relocs, htab->plt_entry_size, htab->plt_header_size, GOT_ENTRY_SIZE, @@ -8848,33 +8844,6 @@ elfNN_aarch64_allocate_local_ifunc_dynrelocs (void **slot, void *inf) return elfNN_aarch64_allocate_ifunc_dynrelocs (h, inf); } -/* 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 = 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; -} - /* This is the most important function of all . Innocuosly named though ! */ @@ -8987,7 +8956,7 @@ elfNN_aarch64_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED, { htab->root.srelplt->size += RELOC_SIZE (htab); /* Note RELOC_COUNT not incremented here! */ - htab->tlsdesc_plt = (bfd_vma) - 1; + htab->root.tlsdesc_plt = (bfd_vma) - 1; } if (got_type & GOT_TLS_GD) @@ -9030,19 +8999,21 @@ elfNN_aarch64_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED, if (htab->root.srelplt) htab->sgotplt_jump_table_size = aarch64_compute_jump_table_size (htab); - if (htab->tlsdesc_plt) + if (htab->root.tlsdesc_plt) { if (htab->root.splt->size == 0) htab->root.splt->size += htab->plt_header_size; /* If we're not using lazy TLS relocations, don't generate the GOT and PLT entry required. */ - if (!(info->flags & DF_BIND_NOW)) + if ((info->flags & DF_BIND_NOW)) + htab->root.tlsdesc_plt = 0; + else { - htab->tlsdesc_plt = htab->root.splt->size; + htab->root.tlsdesc_plt = htab->root.splt->size; htab->root.splt->size += htab->tlsdesc_plt_entry_size; - htab->dt_tlsdesc_got = htab->root.sgot->size; + htab->root.tlsdesc_got = htab->root.sgot->size; htab->root.sgot->size += GOT_ENTRY_SIZE; } } @@ -9130,30 +9101,15 @@ elfNN_aarch64_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED, #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 (!_bfd_elf_add_dynamic_tags (output_bfd, info, relocs)) + return FALSE; if (htab->root.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 (htab->variant_pcs && !add_dynamic_entry (DT_AARCH64_VARIANT_PCS, 0)) return FALSE; - if (htab->tlsdesc_plt - && !(info->flags & DF_BIND_NOW) - && (!add_dynamic_entry (DT_TLSDESC_PLT, 0) - || !add_dynamic_entry (DT_TLSDESC_GOT, 0))) - return FALSE; - if ((elf_aarch64_tdata (output_bfd)->plt_type == PLT_BTI_PAC) && (!add_dynamic_entry (DT_AARCH64_BTI_PLT, 0) || !add_dynamic_entry (DT_AARCH64_PAC_PLT, 0))) @@ -9167,25 +9123,6 @@ elfNN_aarch64_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED, && !add_dynamic_entry (DT_AARCH64_PAC_PLT, 0)) return FALSE; } - - if (relocs) - { - if (!add_dynamic_entry (DT_RELA, 0) - || !add_dynamic_entry (DT_RELASZ, 0) - || !add_dynamic_entry (DT_RELAENT, RELOC_SIZE (htab))) - 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->root, maybe_set_textrel, info); - - if ((info->flags & DF_TEXTREL) != 0) - { - if (!add_dynamic_entry (DT_TEXTREL, 0)) - return FALSE; - } - } } #undef add_dynamic_entry @@ -9486,7 +9423,7 @@ elfNN_aarch64_finish_dynamic_symbol (bfd *output_bfd, } else { -do_glob_dat: + do_glob_dat: BFD_ASSERT ((h->got.offset & 1) == 0); bfd_put_NN (output_bfd, (bfd_vma) 0, htab->root.sgot->contents + h->got.offset); @@ -9575,8 +9512,11 @@ elfNN_aarch64_init_small_plt0_entry (bfd *output_bfd ATTRIBUTE_UNUSED, memcpy (htab->root.splt->contents, htab->plt0_entry, htab->plt_header_size); - elf_section_data (htab->root.splt->output_section)->this_hdr.sh_entsize = - htab->plt_header_size; + + /* PR 26312: Explicitly set the sh_entsize to 0 so that + consumers do not think that the section contains fixed + sized objects. */ + elf_section_data (htab->root.splt->output_section)->this_hdr.sh_entsize = 0; plt_got_2nd_ent = (htab->root.sgotplt->output_section->vma + htab->root.sgotplt->output_offset @@ -9657,14 +9597,14 @@ elfNN_aarch64_finish_dynamic_sections (bfd *output_bfd, case DT_TLSDESC_PLT: s = htab->root.splt; dyn.d_un.d_ptr = s->output_section->vma + s->output_offset - + htab->tlsdesc_plt; + + htab->root.tlsdesc_plt; break; case DT_TLSDESC_GOT: s = htab->root.sgot; - BFD_ASSERT (htab->dt_tlsdesc_got != (bfd_vma)-1); + BFD_ASSERT (htab->root.tlsdesc_got != (bfd_vma)-1); dyn.d_un.d_ptr = s->output_section->vma + s->output_offset - + htab->dt_tlsdesc_got; + + htab->root.tlsdesc_got; break; } @@ -9678,15 +9618,11 @@ elfNN_aarch64_finish_dynamic_sections (bfd *output_bfd, { elfNN_aarch64_init_small_plt0_entry (output_bfd, htab); - elf_section_data (htab->root.splt->output_section)-> - this_hdr.sh_entsize = htab->plt_entry_size; - - - if (htab->tlsdesc_plt && !(info->flags & DF_BIND_NOW)) + if (htab->root.tlsdesc_plt && !(info->flags & DF_BIND_NOW)) { - BFD_ASSERT (htab->dt_tlsdesc_got != (bfd_vma)-1); + BFD_ASSERT (htab->root.tlsdesc_got != (bfd_vma)-1); bfd_put_NN (output_bfd, (bfd_vma) 0, - htab->root.sgot->contents + htab->dt_tlsdesc_got); + htab->root.sgot->contents + htab->root.tlsdesc_got); const bfd_byte *entry = elfNN_aarch64_tlsdesc_small_plt_entry; htab->tlsdesc_plt_entry_size = PLT_TLSDESC_ENTRY_SIZE; @@ -9697,13 +9633,14 @@ elfNN_aarch64_finish_dynamic_sections (bfd *output_bfd, entry = elfNN_aarch64_tlsdesc_small_plt_bti_entry; } - memcpy (htab->root.splt->contents + htab->tlsdesc_plt, + memcpy (htab->root.splt->contents + htab->root.tlsdesc_plt, entry, htab->tlsdesc_plt_entry_size); { bfd_vma adrp1_addr = htab->root.splt->output_section->vma - + htab->root.splt->output_offset + htab->tlsdesc_plt + 4; + + htab->root.splt->output_offset + + htab->root.tlsdesc_plt + 4; bfd_vma adrp2_addr = adrp1_addr + 4; @@ -9715,10 +9652,10 @@ elfNN_aarch64_finish_dynamic_sections (bfd *output_bfd, htab->root.sgotplt->output_section->vma + htab->root.sgotplt->output_offset; - bfd_vma dt_tlsdesc_got = got_addr + htab->dt_tlsdesc_got; + bfd_vma dt_tlsdesc_got = got_addr + htab->root.tlsdesc_got; bfd_byte *plt_entry = - htab->root.splt->contents + htab->tlsdesc_plt; + htab->root.splt->contents + htab->root.tlsdesc_plt; /* First instruction in BTI enabled PLT stub is a BTI instruction so skip it. */