X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=bfd%2Felfxx-x86.c;h=035b5c5c64c4207018accb279d7957064336700c;hb=refs%2Fheads%2Fconcurrent-displaced-stepping-2020-04-01;hp=2e0e01e31d0d81bf9b6da15c2e06cdb3418e3cf1;hpb=dc1e8a474f904419abaa27da4be5b0f735a87255;p=deliverable%2Fbinutils-gdb.git diff --git a/bfd/elfxx-x86.c b/bfd/elfxx-x86.c index 2e0e01e31d..035b5c5c64 100644 --- a/bfd/elfxx-x86.c +++ b/bfd/elfxx-x86.c @@ -131,7 +131,7 @@ elf_x86_allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf) if (h->type == STT_GNU_IFUNC && h->def_regular) { - if (_bfd_elf_allocate_ifunc_dyn_relocs (info, h, &eh->dyn_relocs, + if (_bfd_elf_allocate_ifunc_dyn_relocs (info, h, &h->dyn_relocs, &htab->readonly_dynrelocs_against_ifunc, plt_entry_size, (htab->plt.has_plt0 @@ -347,7 +347,8 @@ elf_x86_allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf) (but if both R_386_TLS_IE_32 and R_386_TLS_IE is present, we need two), R_386_TLS_GD and R_X86_64_TLSGD need one if local symbol and two if global. No dynamic relocation against - resolved undefined weak symbol in executable. */ + resolved undefined weak symbol in executable. No dynamic + relocation against non-preemptible absolute symbol. */ if (tls_type == GOT_TLS_IE_BOTH) htab->elf.srelgot->size += 2 * htab->sizeof_reloc; else if ((GOT_TLS_GD_P (tls_type) && h->dynindx == -1) @@ -359,7 +360,9 @@ elf_x86_allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf) && ((ELF_ST_VISIBILITY (h->other) == STV_DEFAULT && !resolved_to_zero) || h->root.type != bfd_link_hash_undefweak) - && (bfd_link_pic (info) + && ((bfd_link_pic (info) + && !(h->dynindx == -1 + && ABS_SYMBOL_P (h))) || WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, 0, h))) htab->elf.srelgot->size += htab->sizeof_reloc; if (GOT_TLS_GDESC_P (tls_type)) @@ -372,7 +375,7 @@ elf_x86_allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf) else 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 @@ -393,7 +396,7 @@ elf_x86_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; @@ -407,7 +410,7 @@ elf_x86_allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf) if (htab->target_os == is_vxworks) { struct elf_dyn_relocs **pp; - for (pp = &eh->dyn_relocs; (p = *pp) != NULL; ) + for (pp = &h->dyn_relocs; (p = *pp) != NULL; ) { if (strcmp (p->sec->output_section->name, ".tls_vars") == 0) *pp = p->next; @@ -418,7 +421,7 @@ elf_x86_allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf) /* Also discard relocs on undefined weak syms with non-default visibility or in PIE. */ - if (eh->dyn_relocs != NULL) + if (h->dyn_relocs != NULL) { if (h->root.type == bfd_link_hash_undefweak) { @@ -434,7 +437,7 @@ elf_x86_allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf) that we can branch to 0 without PLT. */ struct elf_dyn_relocs **pp; - for (pp = &eh->dyn_relocs; (p = *pp) != NULL; ) + for (pp = &h->dyn_relocs; (p = *pp) != NULL; ) if (p->pc_count == 0) *pp = p->next; else @@ -447,12 +450,12 @@ elf_x86_allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf) /* Make sure undefined weak symbols are output as dynamic symbols in PIEs for dynamic non-GOT non-PLT reloations. */ - if (eh->dyn_relocs != NULL + if (h->dyn_relocs != NULL && !bfd_elf_link_record_dynamic_symbol (info, h)) return FALSE; } else - eh->dyn_relocs = NULL; + h->dyn_relocs = NULL; } else if (h->dynindx == -1 && !h->forced_local @@ -469,7 +472,7 @@ elf_x86_allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf) which turn out to need copy relocs. */ struct elf_dyn_relocs **pp; - for (pp = &eh->dyn_relocs; (p = *pp) != NULL; ) + for (pp = &h->dyn_relocs; (p = *pp) != NULL; ) { if (p->pc_count != 0) *pp = p->next; @@ -510,13 +513,13 @@ elf_x86_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; @@ -529,62 +532,6 @@ elf_x86_allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf) 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_x86_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; -} - -/* 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 *inf) -{ - asection *sec; - - if (h->root.type == bfd_link_hash_indirect) - return TRUE; - - /* Skip local IFUNC symbols. */ - if (h->forced_local && h->type == STT_GNU_IFUNC) - return TRUE; - - sec = readonly_dynrelocs (h); - if (sec != NULL) - { - struct bfd_link_info *info = (struct bfd_link_info *) inf; - - info->flags |= DF_TEXTREL; - /* xgettext:c-format */ - info->callbacks->minfo (_("%pB: dynamic relocation against `%pT' " - "in read-only section `%pA'\n"), - sec->owner, h->root.root.string, sec); - - if ((info->warn_shared_textrel && bfd_link_pic (info)) - || info->error_textrel) - /* xgettext:c-format */ - info->callbacks->einfo (_("%P: %pB: warning: relocation against `%s' " - "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; -} - /* Allocate space in .plt, .got and associated reloc sections for local dynamic relocs. */ @@ -952,6 +899,100 @@ _bfd_x86_elf_link_check_relocs (bfd *abfd, struct bfd_link_info *info) return _bfd_elf_link_check_relocs (abfd, info); } +bfd_boolean +_bfd_elf_x86_valid_reloc_p (asection *input_section, + struct bfd_link_info *info, + struct elf_x86_link_hash_table *htab, + const Elf_Internal_Rela *rel, + struct elf_link_hash_entry *h, + Elf_Internal_Sym *sym, + Elf_Internal_Shdr *symtab_hdr, + bfd_boolean *no_dynreloc_p) +{ + bfd_boolean valid_p = TRUE; + + *no_dynreloc_p = FALSE; + + /* Check If relocation against non-preemptible absolute symbol is + valid in PIC. FIXME: Can't use SYMBOL_REFERENCES_LOCAL_P since + it may call _bfd_elf_link_hide_sym_by_version and result in + ld-elfvers/ vers21 test failure. */ + if (bfd_link_pic (info) + && (h == NULL || SYMBOL_REFERENCES_LOCAL (info, h))) + { + const struct elf_backend_data *bed; + unsigned int r_type; + Elf_Internal_Rela irel; + + /* Skip non-absolute symbol. */ + if (h) + { + if (!ABS_SYMBOL_P (h)) + return valid_p; + } + else if (sym->st_shndx != SHN_ABS) + return valid_p; + + bed = get_elf_backend_data (input_section->owner); + r_type = ELF32_R_TYPE (rel->r_info); + irel = *rel; + + /* Only allow relocations against absolute symbol, which can be + resolved as absolute value + addend. GOTPCREL relocations + are allowed since absolute value + addend is stored in the + GOT slot. */ + if (bed->target_id == X86_64_ELF_DATA) + { + r_type &= ~R_X86_64_converted_reloc_bit; + valid_p = (r_type == R_X86_64_64 + || r_type == R_X86_64_32 + || r_type == R_X86_64_32S + || r_type == R_X86_64_16 + || r_type == R_X86_64_8 + || r_type == R_X86_64_GOTPCREL + || r_type == R_X86_64_GOTPCRELX + || r_type == R_X86_64_REX_GOTPCRELX); + if (!valid_p) + { + unsigned int r_symndx = htab->r_sym (rel->r_info); + irel.r_info = htab->r_info (r_symndx, r_type); + } + } + else + valid_p = (r_type == R_386_32 + || r_type == R_386_16 + || r_type == R_386_8); + + if (valid_p) + *no_dynreloc_p = TRUE; + else + { + const char *name; + arelent internal_reloc; + + if (!bed->elf_info_to_howto (input_section->owner, + &internal_reloc, &irel) + || internal_reloc.howto == NULL) + abort (); + + if (h) + name = h->root.root.string; + else + name = bfd_elf_sym_name (input_section->owner, symtab_hdr, + sym, NULL); + info->callbacks->einfo + /* xgettext:c-format */ + (_("%F%P: %pB: relocation %s against absolute symbol " + "`%s' in section `%pA' is disallowed\n"), + input_section->owner, internal_reloc.howto->name, name, + input_section); + bfd_set_error (bfd_error_bad_value); + } + } + + return valid_p; +} + /* Set the sizes of the dynamic sections. */ bfd_boolean @@ -1020,8 +1061,7 @@ _bfd_x86_elf_size_dynamic_sections (bfd *output_bfd, && (info->flags & DF_TEXTREL) == 0) { info->flags |= DF_TEXTREL; - if ((info->warn_shared_textrel && bfd_link_pic (info)) - || info->error_textrel) + if (bfd_link_textrel_check (info)) /* xgettext:c-format */ info->callbacks->einfo (_("%P: %pB: warning: relocation " @@ -1065,7 +1105,7 @@ _bfd_x86_elf_size_dynamic_sections (bfd *output_bfd, || *local_tls_type == GOT_TLS_IE_BOTH) s->size += htab->got_entry_size; } - if (bfd_link_pic (info) + if ((bfd_link_pic (info) && *local_tls_type != GOT_ABS) || GOT_TLS_GD_ANY_P (*local_tls_type) || (*local_tls_type & GOT_TLS_IE)) { @@ -1372,7 +1412,8 @@ _bfd_x86_elf_size_dynamic_sections (bfd *output_bfd, /* 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); + elf_link_hash_traverse (&htab->elf, + _bfd_elf_maybe_set_textrel, info); if ((info->flags & DF_TEXTREL) != 0) { @@ -1688,37 +1729,6 @@ _bfd_x86_elf_copy_indirect_symbol (struct bfd_link_info *info, edir = (struct elf_x86_link_hash_entry *) dir; eind = (struct elf_x86_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 && dir->got.refcount <= 0) { @@ -1855,7 +1865,7 @@ _bfd_x86_elf_adjust_dynamic_symbol (struct bfd_link_info *info, struct elf_dyn_relocs **pp; eh = (struct elf_x86_link_hash_entry *) h; - for (pp = &eh->dyn_relocs; (p = *pp) != NULL; ) + for (pp = &h->dyn_relocs; (p = *pp) != NULL; ) { pc_count += p->pc_count; p->count -= p->pc_count; @@ -1983,7 +1993,7 @@ _bfd_x86_elf_adjust_dynamic_symbol (struct bfd_link_info *info, /* If we don't find any dynamic relocs in read-only sections, then we'll be keeping the dynamic relocs and avoiding the copy reloc. */ - if (!readonly_dynrelocs (h)) + if (!_bfd_elf_readonly_dynrelocs (h)) { h->non_got_ref = 0; return TRUE; @@ -2354,8 +2364,7 @@ _bfd_x86_elf_get_synthetic_symtab (bfd *abfd, count = n; for (j = 0; plts[j].name != NULL; j++) - if (plts[j].contents != NULL) - free (plts[j].contents); + free (plts[j].contents); free (dynrelbuf); @@ -2998,6 +3007,23 @@ _bfd_x86_elf_link_setup_gnu_properties : bed->plt_alignment); } + if (bfd_link_executable (info) + && !info->nointerp + && !htab->params->has_dynamic_linker + && htab->params->static_before_all_inputs) + { + /* Report error for dynamic input objects if -static is passed at + command-line before all input files without --dynamic-linker + unless --no-dynamic-linker is used. */ + bfd *abfd; + + for (abfd = info->input_bfds; abfd != NULL; abfd = abfd->link.next) + if ((abfd->flags & DYNAMIC)) + info->callbacks->einfo + (_("%X%P: attempted static link of dynamic object `%pB'\n"), + abfd); + } + return pbfd; }