/* x86 specific support for ELF
- Copyright (C) 2017-2020 Free Software Foundation, Inc.
+ Copyright (C) 2017-2021 Free Software Foundation, Inc.
This file is part of BFD, the Binary File Descriptor library.
void
_bfd_x86_elf_merge_symbol_attribute (struct elf_link_hash_entry *h,
- const Elf_Internal_Sym *isym,
+ unsigned int st_other,
bfd_boolean definition,
bfd_boolean dynamic ATTRIBUTE_UNUSED)
{
{
struct elf_x86_link_hash_entry *eh
= (struct elf_x86_link_hash_entry *) h;
- eh->def_protected = (ELF_ST_VISIBILITY (isym->st_other)
- == STV_PROTECTED);
+ eh->def_protected = ELF_ST_VISIBILITY (st_other) == STV_PROTECTED;
}
}
{
unsigned int number, features;
bfd_boolean updated = FALSE;
+ const struct elf_backend_data *bed;
+ struct elf_x86_link_hash_table *htab;
unsigned int pr_type = aprop != NULL ? aprop->pr_type : bprop->pr_type;
if (pr_type == GNU_PROPERTY_X86_COMPAT_ISA_1_USED
|| (pr_type >= GNU_PROPERTY_X86_UINT32_OR_LO
&& pr_type <= GNU_PROPERTY_X86_UINT32_OR_HI))
{
+ features = 0;
+ if (pr_type == GNU_PROPERTY_X86_ISA_1_NEEDED)
+ {
+ bed = get_elf_backend_data (info->output_bfd);
+ htab = elf_x86_hash_table (info, bed->target_id);
+ switch (htab->params->isa_level)
+ {
+ case 0:
+ break;
+ case 2:
+ features = GNU_PROPERTY_X86_ISA_1_V2;
+ break;
+ case 3:
+ features = GNU_PROPERTY_X86_ISA_1_V3;
+ break;
+ case 4:
+ features = GNU_PROPERTY_X86_ISA_1_V4;
+ break;
+ default:
+ abort ();
+ }
+ }
if (aprop != NULL && bprop != NULL)
{
number = aprop->u.number;
- aprop->u.number = number | bprop->u.number;
+ aprop->u.number = number | bprop->u.number | features;
/* Remove the property if all bits are empty. */
if (aprop->u.number == 0)
{
/* Only one of APROP and BPROP can be NULL. */
if (aprop != NULL)
{
+ aprop->u.number |= features;
if (aprop->u.number == 0)
{
/* Remove APROP if all bits are empty. */
/* Return TRUE if APROP is NULL and all bits of BPROP
aren't empty to indicate that BPROP should be added
to ABFD. */
+ bprop->u.number |= features;
updated = bprop->u.number != 0;
}
}
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);
+ bed = get_elf_backend_data (info->output_bfd);
+ htab = elf_x86_hash_table (info, bed->target_id);
if (!htab)
abort ();
if (aprop != NULL && bprop != NULL)
{
- features = 0;
- if (htab->params->ibt)
- features = GNU_PROPERTY_X86_FEATURE_1_IBT;
- if (htab->params->shstk)
- features |= GNU_PROPERTY_X86_FEATURE_1_SHSTK;
number = aprop->u.number;
- /* Add GNU_PROPERTY_X86_FEATURE_1_IBT and
- GNU_PROPERTY_X86_FEATURE_1_SHSTK. */
- aprop->u.number = (number & bprop->u.number) | features;
+ aprop->u.number = number & bprop->u.number;
+ if (pr_type == GNU_PROPERTY_X86_FEATURE_1_AND)
+ {
+ features = 0;
+ if (htab->params->ibt)
+ features = GNU_PROPERTY_X86_FEATURE_1_IBT;
+ if (htab->params->shstk)
+ features |= GNU_PROPERTY_X86_FEATURE_1_SHSTK;
+ /* Add GNU_PROPERTY_X86_FEATURE_1_IBT and
+ GNU_PROPERTY_X86_FEATURE_1_SHSTK. */
+ aprop->u.number |= features;
+ }
updated = number != (unsigned int) aprop->u.number;
/* Remove the property if all feature bits are cleared. */
if (aprop->u.number == 0)
have them. Set IBT and SHSTK properties for -z ibt and -z
shstk if needed. */
features = 0;
- if (htab->params->ibt)
- features = GNU_PROPERTY_X86_FEATURE_1_IBT;
- if (htab->params->shstk)
- features |= GNU_PROPERTY_X86_FEATURE_1_SHSTK;
+ if (pr_type == GNU_PROPERTY_X86_FEATURE_1_AND)
+ {
+ if (htab->params->ibt)
+ features = GNU_PROPERTY_X86_FEATURE_1_IBT;
+ if (htab->params->shstk)
+ features |= GNU_PROPERTY_X86_FEATURE_1_SHSTK;
+ }
if (features)
{
if (aprop != NULL)
asection *sec, *pltsec;
bfd *dynobj;
bfd_boolean use_ibt_plt;
- unsigned int plt_alignment, features;
+ unsigned int plt_alignment, features, isa_level;
struct elf_x86_link_hash_table *htab;
bfd *pbfd;
bfd *ebfd = NULL;
if (htab->params->ibt)
{
features = GNU_PROPERTY_X86_FEATURE_1_IBT;
- htab->params->cet_report &= ~cet_report_ibt;
+ htab->params->cet_report &= ~prop_report_ibt;
}
if (htab->params->shstk)
{
features |= GNU_PROPERTY_X86_FEATURE_1_SHSTK;
- htab->params->cet_report &= ~cet_report_shstk;
+ htab->params->cet_report &= ~prop_report_shstk;
+ }
+ if (!(htab->params->cet_report & (prop_report_ibt | prop_report_shstk)))
+ htab->params->cet_report = prop_report_none;
+ if (htab->params->lam_u48)
+ {
+ features |= GNU_PROPERTY_X86_FEATURE_1_LAM_U48;
+ htab->params->lam_u48_report = prop_report_none;
+ }
+ if (htab->params->lam_u57)
+ {
+ features |= GNU_PROPERTY_X86_FEATURE_1_LAM_U57;
+ htab->params->lam_u57_report = prop_report_none;
+ }
+
+ switch (htab->params->isa_level)
+ {
+ case 0:
+ isa_level = 0;
+ break;
+ case 1:
+ isa_level = GNU_PROPERTY_X86_ISA_1_BASELINE;
+ break;
+ case 2:
+ isa_level = GNU_PROPERTY_X86_ISA_1_V2;
+ break;
+ case 3:
+ isa_level = GNU_PROPERTY_X86_ISA_1_V3;
+ break;
+ case 4:
+ isa_level = GNU_PROPERTY_X86_ISA_1_V4;
+ break;
+ default:
+ abort ();
}
- if (!(htab->params->cet_report & (cet_report_ibt | cet_report_shstk)))
- htab->params->cet_report = cet_report_none;
if (ebfd != NULL)
{
prop = NULL;
if (features)
{
- /* If features is set, add GNU_PROPERTY_X86_FEATURE_1_IBT and
- GNU_PROPERTY_X86_FEATURE_1_SHSTK. */
+ /* If features is set, add GNU_PROPERTY_X86_FEATURE_1_IBT,
+ GNU_PROPERTY_X86_FEATURE_1_SHSTK,
+ GNU_PROPERTY_X86_FEATURE_1_LAM_U48 and
+ GNU_PROPERTY_X86_FEATURE_1_LAM_U57. */
prop = _bfd_elf_get_property (ebfd,
GNU_PROPERTY_X86_FEATURE_1_AND,
4);
prop->pr_kind = property_number;
}
+ if (isa_level)
+ {
+ /* If ISA level is set, add GNU_PROPERTY_X86_ISA_1_NEEDED. */
+ prop = _bfd_elf_get_property (ebfd,
+ GNU_PROPERTY_X86_ISA_1_NEEDED,
+ 4);
+ prop->u.number |= isa_level;
+ prop->pr_kind = property_number;
+ }
+
/* Create the GNU property note section if needed. */
if (prop != NULL && pbfd == NULL)
{
}
}
- if (htab->params->cet_report)
+ if (htab->params->cet_report
+ || htab->params->lam_u48_report
+ || htab->params->lam_u57_report)
{
- /* Report missing IBT and SHSTK properties. */
+ /* Report missing IBT, SHSTK and LAM properties. */
bfd *abfd;
- const char *msg;
+ const char *warning_msg = _("%P: %pB: warning: missing %s\n");
+ const char *error_msg = _("%X%P: %pB: error: missing %s\n");
+ const char *cet_msg = NULL;
+ const char *lam_u48_msg = NULL;
+ const char *lam_u57_msg = NULL;
+ const char *missing;
elf_property_list *p;
bfd_boolean missing_ibt, missing_shstk;
+ bfd_boolean missing_lam_u48, missing_lam_u57;
bfd_boolean check_ibt
- = !!(htab->params->cet_report & cet_report_ibt);
+ = (htab->params->cet_report
+ && (htab->params->cet_report & prop_report_ibt));
bfd_boolean check_shstk
- = !!(htab->params->cet_report & cet_report_shstk);
+ = (htab->params->cet_report
+ && (htab->params->cet_report & prop_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");
+ if (htab->params->cet_report)
+ {
+ if ((htab->params->cet_report & prop_report_warning))
+ cet_msg = warning_msg;
+ else
+ cet_msg = error_msg;
+ }
+ if (htab->params->lam_u48_report)
+ {
+ if ((htab->params->lam_u48_report & prop_report_warning))
+ lam_u48_msg = warning_msg;
+ else
+ lam_u48_msg = error_msg;
+ }
+ if (htab->params->lam_u57_report)
+ {
+ if ((htab->params->lam_u57_report & prop_report_warning))
+ lam_u57_msg = warning_msg;
+ else
+ lam_u57_msg = error_msg;
+ }
for (abfd = info->input_bfds; abfd != NULL; abfd = abfd->link.next)
if (!(abfd->flags & (DYNAMIC | BFD_PLUGIN | BFD_LINKER_CREATED))
missing_ibt = check_ibt;
missing_shstk = check_shstk;
+ missing_lam_u48 = !!lam_u48_msg;
+ missing_lam_u57 = !!lam_u57_msg;
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);
+ missing_lam_u48 &= !(p->property.u.number
+ & GNU_PROPERTY_X86_FEATURE_1_LAM_U48);
+ missing_lam_u57 &= !(p->property.u.number
+ & GNU_PROPERTY_X86_FEATURE_1_LAM_U57);
}
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);
+ info->callbacks->einfo (cet_msg, abfd, missing);
+ }
+ if (missing_lam_u48)
+ {
+ missing = _("LAM_U48 property");
+ info->callbacks->einfo (lam_u48_msg, abfd, missing);
+ }
+ if (missing_lam_u57)
+ {
+ missing = _("LAM_U57 property");
+ info->callbacks->einfo (lam_u57_msg, abfd, missing);
}
}
}
htab->interp = s;
}
- /* Don't change PLT section alignment for NaCl since it uses
- 64-byte PLT entry and sets PLT section alignment to 32
- bytes. Don't create additional PLT sections for NaCl. */
if (normal_target)
{
flagword pltflags = (bed->dynamic_sec_flags
if (use_ibt_plt)
{
/* Create the second PLT for Intel IBT support. IBT
- PLT is supported only for non-NaCl target and is
- is needed only for lazy binding. */
+ PLT is needed only for lazy binding. */
sec = bfd_make_section_anyway_with_flags (dynobj,
".plt.sec",
pltflags);
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
- mode and is needed only for lazy binding. */
+ PLT is supported only in 64-bit mode and is needed
+ only for lazy binding. */
sec = bfd_make_section_anyway_with_flags (dynobj,
".plt.sec",
pltflags);
void
_bfd_x86_elf_link_fixup_gnu_properties
- (struct bfd_link_info *info ATTRIBUTE_UNUSED,
- elf_property_list **listp)
+ (struct bfd_link_info *info, elf_property_list **listp)
{
elf_property_list *p;
continue;
}
+ /* Keep LAM features only for 64-bit output. */
+ if (type == GNU_PROPERTY_X86_FEATURE_1_AND
+ && !ABI_64_P (info->output_bfd))
+ p->property.u.number &= ~(GNU_PROPERTY_X86_FEATURE_1_LAM_U48
+ | GNU_PROPERTY_X86_FEATURE_1_LAM_U57);
+
listp = &p->next;
}
else if (type > GNU_PROPERTY_HIPROC)