diff options
Diffstat (limited to 'bfd')
-rw-r--r-- | bfd/elfnn-aarch64.c | 93 | ||||
-rw-r--r-- | bfd/elfxx-aarch64.c | 37 | ||||
-rw-r--r-- | bfd/elfxx-aarch64.h | 36 |
3 files changed, 139 insertions, 27 deletions
diff --git a/bfd/elfnn-aarch64.c b/bfd/elfnn-aarch64.c index 94c9a01..e4c2f55 100644 --- a/bfd/elfnn-aarch64.c +++ b/bfd/elfnn-aarch64.c @@ -2546,6 +2546,12 @@ struct elf_aarch64_obj_tdata GNU_PROPERTY_AARCH64_FEATURE_1_BTI. */ int no_bti_warn; + /* Mark output with GCS based on -z gcs. */ + aarch64_gcs_type gcs_type; + /* Report linker warning/error for -z gcs-report based on + -z gcs. */ + aarch64_gcs_report gcs_report; + /* PLT type based on security. */ aarch64_plt_type plt_type; }; @@ -5024,7 +5030,7 @@ bfd_elfNN_aarch64_set_options (struct bfd *output_bfd, int fix_erratum_835769, erratum_84319_opts fix_erratum_843419, int no_apply_dynamic_relocs, - aarch64_bti_pac_info bp_info) + aarch64_gnu_prop_info gnu_prop_info) { struct elf_aarch64_link_hash_table *globals; @@ -5041,7 +5047,7 @@ bfd_elfNN_aarch64_set_options (struct bfd *output_bfd, elf_aarch64_tdata (output_bfd)->no_enum_size_warning = no_enum_warn; elf_aarch64_tdata (output_bfd)->no_wchar_size_warning = no_wchar_warn; - switch (bp_info.bti_type) + switch (gnu_prop_info.bti_type) { case BTI_WARN: elf_aarch64_tdata (output_bfd)->no_bti_warn = 0; @@ -5052,8 +5058,26 @@ bfd_elfNN_aarch64_set_options (struct bfd *output_bfd, default: break; } - elf_aarch64_tdata (output_bfd)->plt_type = bp_info.plt_type; - setup_plt_values (link_info, bp_info.plt_type); + + switch (gnu_prop_info.gcs_type) + { + case GCS_ALWAYS: + elf_aarch64_tdata (output_bfd)->gnu_and_prop + |= GNU_PROPERTY_AARCH64_FEATURE_1_GCS; + break; + case GCS_NEVER: + elf_aarch64_tdata (output_bfd)->gnu_and_prop + &= ~GNU_PROPERTY_AARCH64_FEATURE_1_GCS; + break; + + default: + break; + } + + elf_aarch64_tdata (output_bfd)->gcs_type = gnu_prop_info.gcs_type; + elf_aarch64_tdata (output_bfd)->gcs_report = gnu_prop_info.gcs_report; + elf_aarch64_tdata (output_bfd)->plt_type = gnu_prop_info.plt_type; + setup_plt_values (link_info, gnu_prop_info.plt_type); } static bfd_vma @@ -10619,7 +10643,12 @@ static bfd * elfNN_aarch64_link_setup_gnu_properties (struct bfd_link_info *info) { uint32_t prop = elf_aarch64_tdata (info->output_bfd)->gnu_and_prop; - bfd *pbfd = _bfd_aarch64_elf_link_setup_gnu_properties (info, &prop); + aarch64_gcs_report gcs_report + = elf_aarch64_tdata (info->output_bfd)->gcs_report; + aarch64_gcs_type gcs_type + = elf_aarch64_tdata (info->output_bfd)->gcs_type; + bfd *pbfd = _bfd_aarch64_elf_link_setup_gnu_properties (info, &prop, + gcs_report, gcs_type); elf_aarch64_tdata (info->output_bfd)->gnu_and_prop = prop; elf_aarch64_tdata (info->output_bfd)->plt_type |= (prop & GNU_PROPERTY_AARCH64_FEATURE_1_BTI) ? PLT_BTI : 0; @@ -10638,30 +10667,54 @@ elfNN_aarch64_merge_gnu_properties (struct bfd_link_info *info, { uint32_t prop = elf_aarch64_tdata (info->output_bfd)->gnu_and_prop; + aarch64_gcs_report gcs_report + = elf_aarch64_tdata (info->output_bfd)->gcs_report; + aarch64_gcs_type gcs_type + = elf_aarch64_tdata (info->output_bfd)->gcs_type; - /* If output has been marked with BTI using command line argument, give out - warning if necessary. */ /* Properties are merged per type, hence only check for warnings when merging GNU_PROPERTY_AARCH64_FEATURE_1_AND. */ - if (((aprop && aprop->pr_type == GNU_PROPERTY_AARCH64_FEATURE_1_AND) + if ((aprop && aprop->pr_type == GNU_PROPERTY_AARCH64_FEATURE_1_AND) || (bprop && bprop->pr_type == GNU_PROPERTY_AARCH64_FEATURE_1_AND)) - && (prop & GNU_PROPERTY_AARCH64_FEATURE_1_BTI) - && (!elf_aarch64_tdata (info->output_bfd)->no_bti_warn)) { - if ((aprop && !(aprop->u.number & GNU_PROPERTY_AARCH64_FEATURE_1_BTI)) - || !aprop) + /* If output has been marked with BTI using command line argument, give + out warning if necessary. */ + if ((prop & GNU_PROPERTY_AARCH64_FEATURE_1_BTI) + && (!elf_aarch64_tdata (info->output_bfd)->no_bti_warn)) { - _bfd_error_handler (_("%pB: warning: BTI turned on by -z force-bti when " - "all inputs do not have BTI in NOTE section."), - abfd); + if ((aprop && !(aprop->u.number & GNU_PROPERTY_AARCH64_FEATURE_1_BTI)) + || !aprop) + { + _bfd_error_handler (_("%pB: warning: BTI turned on by -z " + "force-bti when all inputs do not have BTI " + "in NOTE section."), abfd); + } + if ((bprop && !(bprop->u.number & GNU_PROPERTY_AARCH64_FEATURE_1_BTI)) + || !bprop) + { + _bfd_error_handler (_("%pB: warning: BTI turned on by -z " + "force-bti when all inputs do not have BTI " + "in NOTE section."), bbfd); + } } - if ((bprop && !(bprop->u.number & GNU_PROPERTY_AARCH64_FEATURE_1_BTI)) - || !bprop) + + /* If output has been marked with GCS using -z gcs and input + is missing GCS marking throw warning/error on + -z gcs-report=warning/error. */ + if ((prop & GNU_PROPERTY_AARCH64_FEATURE_1_GCS) && gcs_report != GCS_NONE) { - _bfd_error_handler (_("%pB: warning: BTI turned on by -z force-bti when " - "all inputs do not have BTI in NOTE section."), - bbfd); + if ((aprop && !(aprop->u.number & GNU_PROPERTY_AARCH64_FEATURE_1_GCS)) + || !aprop) + _bfd_aarch64_elf_check_gcs_report (gcs_report, abfd); + if ((bprop && !(bprop->u.number & GNU_PROPERTY_AARCH64_FEATURE_1_GCS)) + || !bprop) + _bfd_aarch64_elf_check_gcs_report (gcs_report, bbfd); } + + if (gcs_type == GCS_NEVER && aprop != NULL) + aprop->u.number &= ~GNU_PROPERTY_AARCH64_FEATURE_1_GCS; + if (gcs_type == GCS_NEVER && bprop != NULL) + bprop->u.number &= ~GNU_PROPERTY_AARCH64_FEATURE_1_GCS; } return _bfd_aarch64_elf_merge_gnu_properties (info, abfd, aprop, diff --git a/bfd/elfxx-aarch64.c b/bfd/elfxx-aarch64.c index d1279ad..abe1ea6 100644 --- a/bfd/elfxx-aarch64.c +++ b/bfd/elfxx-aarch64.c @@ -702,7 +702,9 @@ _bfd_aarch64_elf_write_core_note (bfd *abfd, char *buf, int *bufsiz, int note_ty GPROP accordingly. */ bfd * _bfd_aarch64_elf_link_setup_gnu_properties (struct bfd_link_info *info, - uint32_t *gprop) + uint32_t *gprop, + aarch64_gcs_report gcs_report, + aarch64_gcs_type gcs_type) { asection *sec; bfd *pbfd; @@ -738,6 +740,11 @@ _bfd_aarch64_elf_link_setup_gnu_properties (struct bfd_link_info *info, _bfd_error_handler (_("%pB: warning: BTI turned on by -z force-bti " "when all inputs do not have BTI in NOTE " "section."), ebfd); + + if ((gnu_prop & GNU_PROPERTY_AARCH64_FEATURE_1_GCS) + && !(prop->u.number & GNU_PROPERTY_AARCH64_FEATURE_1_GCS)) + _bfd_aarch64_elf_check_gcs_report (gcs_report, ebfd); + prop->u.number |= gnu_prop; prop->pr_kind = property_number; @@ -765,6 +772,14 @@ _bfd_aarch64_elf_link_setup_gnu_properties (struct bfd_link_info *info, elf_section_type (sec) = SHT_NOTE; } } + else if (ebfd != NULL && gcs_type == GCS_NEVER) + { + prop = _bfd_elf_get_property (ebfd, GNU_PROPERTY_AARCH64_FEATURE_1_AND, + 4); + prop->u.number &= ~GNU_PROPERTY_AARCH64_FEATURE_1_GCS; + if (prop->u.number == 0) + prop->pr_kind = property_remove; + } pbfd = _bfd_elf_link_setup_gnu_properties (info); @@ -785,7 +800,8 @@ _bfd_aarch64_elf_link_setup_gnu_properties (struct bfd_link_info *info, { gnu_prop = (p->property.u.number & (GNU_PROPERTY_AARCH64_FEATURE_1_PAC - | GNU_PROPERTY_AARCH64_FEATURE_1_BTI)); + | GNU_PROPERTY_AARCH64_FEATURE_1_BTI + | GNU_PROPERTY_AARCH64_FEATURE_1_GCS)); break; } else if (GNU_PROPERTY_AARCH64_FEATURE_1_AND < p->property.pr_type) @@ -922,3 +938,20 @@ _bfd_aarch64_elf_link_fixup_gnu_properties } } } + +/* Check AArch64 GCS report. */ +void +_bfd_aarch64_elf_check_gcs_report (aarch64_gcs_report gcs_report, bfd *ebfd) +{ + if (gcs_report == GCS_WARN) + _bfd_error_handler (_("%pB: warning: GCS turned on by -z gcs " + "on the output when all inputs do not have GCS in NOTE " + "section."), ebfd); + else if (gcs_report == GCS_ERROR) + { + _bfd_error_handler (_("%pB: error: GCS turned on by -z gcs " + "on the output when all inputs do not have GCS in " + "NOTE section."), ebfd); + _exit (EXIT_FAILURE); + } +} diff --git a/bfd/elfxx-aarch64.h b/bfd/elfxx-aarch64.h index f21e5ee..4852d33 100644 --- a/bfd/elfxx-aarch64.h +++ b/bfd/elfxx-aarch64.h @@ -46,6 +46,27 @@ typedef enum BTI_WARN = 1, /* BTI is enabled with -z force-bti. */ } aarch64_enable_bti_type; +/* To indicate whether GNU_PROPERTY_AARCH64_FEATURE_1_GCS bit is + enabled/disabled on the output when -z gcs linker + command line option is passed. */ +typedef enum +{ + GCS_NEVER = 0, /* gcs is disabled on output. */ + GCS_IMPLICIT = 1, /* gcs is deduced from input object. */ + GCS_ALWAYS = 2, /* gsc is enabled on output. */ +} aarch64_gcs_type; + +/* To indicate whether to generate linker warning/errors for + -z gcs-report when -z gcs=always is passed. */ +typedef enum +{ + GCS_NONE = 0, /* Does not emit any warning/error messages. */ + GCS_WARN = 1, /* Emit warning when the input objects are missing gcs + markings and output have gcs marking. */ + GCS_ERROR = 2, /* Emit error when the input objects are missing gcs + markings and output have gcs marking. */ +} aarch64_gcs_report; + /* A structure to encompass all information coming from BTI or PAC related command line options. This involves the "PLT_TYPE" to determine which version of PLTs to pick and "BTI_TYPE" to determine if @@ -54,7 +75,9 @@ typedef struct { aarch64_plt_type plt_type; aarch64_enable_bti_type bti_type; -} aarch64_bti_pac_info; + aarch64_gcs_type gcs_type; + aarch64_gcs_report gcs_report; +} aarch64_gnu_prop_info; /* An enum to define what kind of erratum fixes we should apply. This gives the user a bit more control over the sequences we generate. */ @@ -67,11 +90,11 @@ typedef enum extern void bfd_elf64_aarch64_set_options (bfd *, struct bfd_link_info *, int, int, int, int, erratum_84319_opts, int, - aarch64_bti_pac_info); + aarch64_gnu_prop_info); extern void bfd_elf32_aarch64_set_options (bfd *, struct bfd_link_info *, int, int, int, int, erratum_84319_opts, int, - aarch64_bti_pac_info); + aarch64_gnu_prop_info); /* AArch64 stub generation support for ELF64. Called from the linker. */ extern int elf64_aarch64_setup_section_lists @@ -146,8 +169,9 @@ _bfd_aarch64_elf_write_core_note (bfd *, char *, int *, int, ...); #define elf_backend_write_core_note _bfd_aarch64_elf_write_core_note extern bfd * -_bfd_aarch64_elf_link_setup_gnu_properties (struct bfd_link_info *, - uint32_t *); +_bfd_aarch64_elf_link_setup_gnu_properties (struct bfd_link_info *, uint32_t *, + aarch64_gcs_report, + aarch64_gcs_type); extern enum elf_property_kind _bfd_aarch64_elf_parse_gnu_properties (bfd *, unsigned int, @@ -157,6 +181,8 @@ extern bool _bfd_aarch64_elf_merge_gnu_properties (struct bfd_link_info *, bfd *, elf_property *, elf_property *, uint32_t); +extern void +_bfd_aarch64_elf_check_gcs_report (aarch64_gcs_report, bfd *); extern void _bfd_aarch64_elf_link_fixup_gnu_properties (struct bfd_link_info *, |