X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=bfd%2Felfxx-x86.c;h=fc783b0e988252bdc9f2a9d717510fe4db02f8f8;hb=65c574f6dd066a239a94c2df0e1e12d50eae06c9;hp=40aac664f4a060125ecb6b4f540cf64d00ae3cbc;hpb=b44ee3a8cf21294eeb079ffbada7eeb559a9c6b4;p=deliverable%2Fbinutils-gdb.git diff --git a/bfd/elfxx-x86.c b/bfd/elfxx-x86.c index 40aac664f4..fc783b0e98 100644 --- a/bfd/elfxx-x86.c +++ b/bfd/elfxx-x86.c @@ -1,5 +1,5 @@ /* x86 specific support for ELF - Copyright (C) 2017-2018 Free Software Foundation, Inc. + Copyright (C) 2017-2020 Free Software Foundation, Inc. This file is part of BFD, the Binary File Descriptor library. @@ -1238,7 +1238,7 @@ _bfd_x86_elf_size_dynamic_sections (bfd *output_bfd, { /* Strip these too. */ } - else if (htab->is_reloc_section (bfd_get_section_name (dynobj, s))) + else if (htab->is_reloc_section (bfd_section_name (s))) { if (s->size != 0 && s != htab->elf.srelplt @@ -1280,8 +1280,7 @@ _bfd_x86_elf_size_dynamic_sections (bfd *output_bfd, it is empty. Update its section alignment now since it is non-empty. */ if (s == htab->elf.iplt) - bfd_set_section_alignment (s->owner, s, - htab->plt.iplt_alignment); + bfd_set_section_alignment (s, htab->plt.iplt_alignment); /* Allocate memory for the section contents. We use bfd_zalloc here in case unused entries are not reclaimed before the @@ -1381,7 +1380,8 @@ _bfd_x86_elf_size_dynamic_sections (bfd *output_bfd, { info->callbacks->einfo (_("%P%X: read-only segment has dynamic IFUNC relocations;" - " recompile with -fPIC\n")); + " recompile with %s\n"), + bfd_link_dll (info) ? "-fPIC" : "-fPIE"); bfd_set_error (bfd_error_bad_value); return FALSE; } @@ -2170,17 +2170,18 @@ _bfd_x86_elf_get_synthetic_symtab (bfd *abfd, bfd_vma); bfd_boolean (*valid_plt_reloc_p) (unsigned int); + dynrelbuf = NULL; if (count == 0) - return -1; + goto bad_return; dynrelbuf = (arelent **) bfd_malloc (relsize); if (dynrelbuf == NULL) - return -1; + goto bad_return; dynrelcount = bfd_canonicalize_dynamic_reloc (abfd, dynrelbuf, dynsyms); if (dynrelcount <= 0) - return -1; + goto bad_return; /* Sort the relocs by address. */ qsort (dynrelbuf, dynrelcount, sizeof (arelent *), @@ -2401,6 +2402,7 @@ _bfd_x86_elf_parse_gnu_properties (bfd *abfd, unsigned int type, bfd_boolean _bfd_x86_elf_merge_gnu_properties (struct bfd_link_info *info, bfd *abfd ATTRIBUTE_UNUSED, + bfd *bbfd ATTRIBUTE_UNUSED, elf_property *aprop, elf_property *bprop) { @@ -2422,9 +2424,14 @@ _bfd_x86_elf_merge_gnu_properties (struct bfd_link_info *info, aprop->pr_kind = property_remove; updated = TRUE; } - return updated; } - goto or_property; + else + { + number = aprop->u.number; + aprop->u.number = number | bprop->u.number; + updated = number != (unsigned int) aprop->u.number; + } + return updated; } else if (pr_type == GNU_PROPERTY_X86_COMPAT_ISA_1_NEEDED || (pr_type >= GNU_PROPERTY_X86_UINT32_OR_LO @@ -2432,7 +2439,6 @@ _bfd_x86_elf_merge_gnu_properties (struct bfd_link_info *info, { if (aprop != NULL && bprop != NULL) { -or_property: number = aprop->u.number; aprop->u.number = number | bprop->u.number; /* Remove the property if all bits are empty. */ @@ -2474,12 +2480,18 @@ or_property: 2. If APROP is NULL, remove x86 feature. 3. Otherwise, do nothing. */ + const struct elf_backend_data *bed + = get_elf_backend_data (info->output_bfd); + struct elf_x86_link_hash_table *htab + = elf_x86_hash_table (info, bed->target_id); + if (!htab) + abort (); if (aprop != NULL && bprop != NULL) { features = 0; - if (info->ibt) + if (htab->params->ibt) features = GNU_PROPERTY_X86_FEATURE_1_IBT; - if (info->shstk) + if (htab->params->shstk) features |= GNU_PROPERTY_X86_FEATURE_1_SHSTK; number = aprop->u.number; /* Add GNU_PROPERTY_X86_FEATURE_1_IBT and @@ -2492,25 +2504,25 @@ or_property: } else { + /* There should be no AND properties since some input doesn't + have them. Set IBT and SHSTK properties for -z ibt and -z + shstk if needed. */ features = 0; - if (info->ibt) + if (htab->params->ibt) features = GNU_PROPERTY_X86_FEATURE_1_IBT; - if (info->shstk) + if (htab->params->shstk) features |= GNU_PROPERTY_X86_FEATURE_1_SHSTK; if (features) { - /* Add GNU_PROPERTY_X86_FEATURE_1_IBT and - GNU_PROPERTY_X86_FEATURE_1_SHSTK. */ if (aprop != NULL) { - number = aprop->u.number; - aprop->u.number = number | features; - updated = number != (unsigned int) aprop->u.number; + updated = features != (unsigned int) aprop->u.number; + aprop->u.number = features; } else { - bprop->u.number |= features; updated = TRUE; + bprop->u.number = features; } } else if (aprop != NULL) @@ -2551,12 +2563,6 @@ _bfd_x86_elf_link_setup_gnu_properties unsigned int class_align = ABI_64_P (info->output_bfd) ? 3 : 2; unsigned int got_align; - features = 0; - if (info->ibt) - features = GNU_PROPERTY_X86_FEATURE_1_IBT; - if (info->shstk) - features |= GNU_PROPERTY_X86_FEATURE_1_SHSTK; - /* Find a normal input file with GNU property note. */ for (pbfd = info->input_bfds; pbfd != NULL; @@ -2576,6 +2582,20 @@ _bfd_x86_elf_link_setup_gnu_properties if (htab == NULL) return pbfd; + features = 0; + if (htab->params->ibt) + { + features = GNU_PROPERTY_X86_FEATURE_1_IBT; + htab->params->cet_report &= ~cet_report_ibt; + } + if (htab->params->shstk) + { + features |= GNU_PROPERTY_X86_FEATURE_1_SHSTK; + htab->params->cet_report &= ~cet_report_shstk; + } + if (!(htab->params->cet_report & (cet_report_ibt | cet_report_shstk))) + htab->params->cet_report = cet_report_none; + if (ebfd != NULL) { prop = NULL; @@ -2604,7 +2624,7 @@ _bfd_x86_elf_link_setup_gnu_properties if (sec == NULL) info->callbacks->einfo (_("%F%P: failed to create GNU property section\n")); - if (!bfd_set_section_alignment (ebfd, sec, class_align)) + if (!bfd_set_section_alignment (sec, class_align)) { error_alignment: info->callbacks->einfo (_("%F%pA: failed to align section\n"), @@ -2615,6 +2635,54 @@ error_alignment: } } + if (htab->params->cet_report) + { + /* Report missing IBT and SHSTK properties. */ + bfd *abfd; + const char *msg; + elf_property_list *p; + bfd_boolean missing_ibt, missing_shstk; + bfd_boolean check_ibt + = !!(htab->params->cet_report & cet_report_ibt); + bfd_boolean check_shstk + = !!(htab->params->cet_report & cet_report_shstk); + + if ((htab->params->cet_report & cet_report_warning)) + msg = _("%P: %pB: warning: missing %s\n"); + else + msg = _("%X%P: %pB: error: missing %s\n"); + + for (abfd = info->input_bfds; abfd != NULL; abfd = abfd->link.next) + if (!(abfd->flags & (DYNAMIC | BFD_PLUGIN | BFD_LINKER_CREATED)) + && bfd_get_flavour (abfd) == bfd_target_elf_flavour) + { + for (p = elf_properties (abfd); p; p = p->next) + if (p->property.pr_type == GNU_PROPERTY_X86_FEATURE_1_AND) + break; + + missing_ibt = check_ibt; + missing_shstk = check_shstk; + if (p) + { + missing_ibt &= !(p->property.u.number + & GNU_PROPERTY_X86_FEATURE_1_IBT); + missing_shstk &= !(p->property.u.number + & GNU_PROPERTY_X86_FEATURE_1_SHSTK); + } + if (missing_ibt || missing_shstk) + { + const char *missing; + if (missing_ibt && missing_shstk) + missing = _("IBT and SHSTK properties"); + else if (missing_ibt) + missing = _("IBT property"); + else + missing = _("SHSTK property"); + info->callbacks->einfo (msg, abfd, missing); + } + } + } + pbfd = _bfd_elf_link_setup_gnu_properties (info); htab->r_info = init_table->r_info; @@ -2625,7 +2693,7 @@ error_alignment: htab->plt0_pad_byte = init_table->plt0_pad_byte; - use_ibt_plt = info->ibtplt || info->ibt; + use_ibt_plt = htab->params->ibtplt || htab->params->ibt; if (!use_ibt_plt && pbfd != NULL) { /* Check if GNU_PROPERTY_X86_FEATURE_1_IBT is on. */ @@ -2770,11 +2838,11 @@ error_alignment: instead of in create_dynamic_sections so that they are always properly aligned even if create_dynamic_sections isn't called. */ sec = htab->elf.sgot; - if (!bfd_set_section_alignment (dynobj, sec, got_align)) + if (!bfd_set_section_alignment (sec, got_align)) goto error_alignment; sec = htab->elf.sgotplt; - if (!bfd_set_section_alignment (dynobj, sec, got_align)) + if (!bfd_set_section_alignment (sec, got_align)) goto error_alignment; /* Create the ifunc sections here so that check_relocs can be @@ -2812,8 +2880,7 @@ error_alignment: = bfd_log2 (htab->non_lazy_plt->plt_entry_size); sec = pltsec; - if (!bfd_set_section_alignment (sec->owner, sec, - plt_alignment)) + if (!bfd_set_section_alignment (sec, plt_alignment)) goto error_alignment; /* Create the GOT procedure linkage table. */ @@ -2823,8 +2890,7 @@ error_alignment: if (sec == NULL) info->callbacks->einfo (_("%F%P: failed to create GOT PLT section\n")); - if (!bfd_set_section_alignment (dynobj, sec, - non_lazy_plt_alignment)) + if (!bfd_set_section_alignment (sec, non_lazy_plt_alignment)) goto error_alignment; htab->plt_got = sec; @@ -2844,11 +2910,10 @@ error_alignment: if (sec == NULL) info->callbacks->einfo (_("%F%P: failed to create IBT-enabled PLT section\n")); - if (!bfd_set_section_alignment (dynobj, sec, - plt_alignment)) + if (!bfd_set_section_alignment (sec, plt_alignment)) goto error_alignment; } - else if (info->bndplt && ABI_64_P (dynobj)) + else if (htab->params->bndplt && ABI_64_P (dynobj)) { /* Create the second PLT for Intel MPX support. MPX PLT is supported only for non-NaCl target in 64-bit @@ -2859,8 +2924,7 @@ error_alignment: if (sec == NULL) info->callbacks->einfo (_("%F%P: failed to create BND PLT section\n")); - if (!bfd_set_section_alignment (dynobj, sec, - non_lazy_plt_alignment)) + if (!bfd_set_section_alignment (sec, non_lazy_plt_alignment)) goto error_alignment; } @@ -2880,7 +2944,7 @@ error_alignment: if (sec == NULL) info->callbacks->einfo (_("%F%P: failed to create PLT .eh_frame section\n")); - if (!bfd_set_section_alignment (dynobj, sec, class_align)) + if (!bfd_set_section_alignment (sec, class_align)) goto error_alignment; htab->plt_eh_frame = sec; @@ -2893,7 +2957,7 @@ error_alignment: if (sec == NULL) info->callbacks->einfo (_("%F%P: failed to create GOT PLT .eh_frame section\n")); - if (!bfd_set_section_alignment (dynobj, sec, class_align)) + if (!bfd_set_section_alignment (sec, class_align)) goto error_alignment; htab->plt_got_eh_frame = sec; @@ -2907,7 +2971,7 @@ error_alignment: if (sec == NULL) info->callbacks->einfo (_("%F%P: failed to create the second PLT .eh_frame section\n")); - if (!bfd_set_section_alignment (dynobj, sec, class_align)) + if (!bfd_set_section_alignment (sec, class_align)) goto error_alignment; htab->plt_second_eh_frame = sec; @@ -2926,7 +2990,7 @@ error_alignment: section backwards, resulting in a warning and section lma not being set properly. It later leads to a "File truncated" error. */ - if (!bfd_set_section_alignment (sec->owner, sec, 0)) + if (!bfd_set_section_alignment (sec, 0)) goto error_alignment; htab->plt.iplt_alignment = (normal_target @@ -2940,8 +3004,9 @@ error_alignment: /* Fix up x86 GNU properties. */ void -_bfd_x86_elf_link_fixup_gnu_properties (struct bfd_link_info *info, - elf_property_list **listp) +_bfd_x86_elf_link_fixup_gnu_properties + (struct bfd_link_info *info ATTRIBUTE_UNUSED, + elf_property_list **listp) { elf_property_list *p; @@ -2957,18 +3022,18 @@ _bfd_x86_elf_link_fixup_gnu_properties (struct bfd_link_info *info, || (type >= GNU_PROPERTY_X86_UINT32_OR_AND_LO && type <= GNU_PROPERTY_X86_UINT32_OR_AND_HI)) { - if (p->property.u.number == 0) + if (p->property.u.number == 0 + && (type == GNU_PROPERTY_X86_COMPAT_ISA_1_NEEDED + || (type >= GNU_PROPERTY_X86_UINT32_AND_LO + && type <= GNU_PROPERTY_X86_UINT32_AND_HI) + || (type >= GNU_PROPERTY_X86_UINT32_OR_LO + && type <= GNU_PROPERTY_X86_UINT32_OR_HI))) { /* Remove empty property. */ *listp = p->next; continue; } - /* Mark x86-specific properties with X86_UINT32_VALID for - non-relocatable output. */ - if (!bfd_link_relocatable (info)) - p->property.u.number |= GNU_PROPERTY_X86_UINT32_VALID; - listp = &p->next; } else if (type > GNU_PROPERTY_HIPROC) @@ -2978,3 +3043,15 @@ _bfd_x86_elf_link_fixup_gnu_properties (struct bfd_link_info *info, } } } + +void +_bfd_elf_linker_x86_set_options (struct bfd_link_info * info, + struct elf_linker_x86_params *params) +{ + const struct elf_backend_data *bed + = get_elf_backend_data (info->output_bfd); + struct elf_x86_link_hash_table *htab + = elf_x86_hash_table (info, bed->target_id); + if (htab != NULL) + htab->params = params; +}