diff options
Diffstat (limited to 'bfd')
-rw-r--r-- | bfd/ChangeLog | 9 | ||||
-rw-r--r-- | bfd/elf-linker-x86.h | 3 | ||||
-rw-r--r-- | bfd/elfxx-x86.c | 64 |
3 files changed, 70 insertions, 6 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 468c6f6..9650b3d 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,12 @@ +2020-10-09 H.J. Lu <hongjiu.lu@intel.com> + + PR gas/26703 + * elf-linker-x86.h (elf_linker_x86_params): Add isa_level. + * elfxx-x86.c (_bfd_x86_elf_merge_gnu_properties): Merge + GNU_PROPERTY_X86_ISA_1_V[234]. + (_bfd_x86_elf_link_setup_gnu_properties): Generate + GNU_PROPERTY_X86_ISA_1_V[234] for -z x86-64-v[234]. + 2020-10-06 H.J. Lu <hongjiu.lu@intel.com> PR ld/26711 diff --git a/bfd/elf-linker-x86.h b/bfd/elf-linker-x86.h index d0cb20d..77e8196 100644 --- a/bfd/elf-linker-x86.h +++ b/bfd/elf-linker-x86.h @@ -55,6 +55,9 @@ struct elf_linker_x86_params /* TRUE if --dynamic-linker is passed at command-line. */ unsigned int has_dynamic_linker : 1; + /* X86-64 ISA level needed. */ + unsigned int isa_level; + /* Report missing IBT and SHSTK properties. */ enum elf_x86_cet_report cet_report; 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) { |