diff options
Diffstat (limited to 'bfd/elfxx-x86.c')
-rw-r--r-- | bfd/elfxx-x86.c | 64 |
1 files changed, 58 insertions, 6 deletions
diff --git a/bfd/elfxx-x86.c b/bfd/elfxx-x86.c index 143aae4..4a0360f 100644 --- a/bfd/elfxx-x86.c +++ b/bfd/elfxx-x86.c @@ -2337,6 +2337,8 @@ _bfd_x86_elf_merge_gnu_properties (struct bfd_link_info *info, { 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 @@ -2366,10 +2368,32 @@ _bfd_x86_elf_merge_gnu_properties (struct bfd_link_info *info, || (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) { @@ -2384,6 +2408,7 @@ _bfd_x86_elf_merge_gnu_properties (struct bfd_link_info *info, /* 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. */ @@ -2396,6 +2421,7 @@ _bfd_x86_elf_merge_gnu_properties (struct bfd_link_info *info, /* 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; } } @@ -2409,10 +2435,8 @@ _bfd_x86_elf_merge_gnu_properties (struct bfd_link_info *info, 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) @@ -2490,7 +2514,7 @@ _bfd_x86_elf_link_setup_gnu_properties 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; @@ -2532,6 +2556,24 @@ _bfd_x86_elf_link_setup_gnu_properties if (!(htab->params->cet_report & (cet_report_ibt | cet_report_shstk))) htab->params->cet_report = cet_report_none; + switch (htab->params->isa_level) + { + case 0: + isa_level = 0; + 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 (ebfd != NULL) { prop = NULL; @@ -2546,6 +2588,16 @@ _bfd_x86_elf_link_setup_gnu_properties 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) { |