diff --git a/SPECS/binutils-aarch64-properties.patch b/SPECS/binutils-aarch64-properties.patch new file mode 100644 index 0000000..5e1b7ce --- /dev/null +++ b/SPECS/binutils-aarch64-properties.patch @@ -0,0 +1,547 @@ +diff -rup binutils.orig/bfd/elfnn-aarch64.c binutils-2.30/bfd/elfnn-aarch64.c +--- binutils.orig/bfd/elfnn-aarch64.c 2020-11-04 14:53:52.144476367 +0000 ++++ binutils-2.30/bfd/elfnn-aarch64.c 2020-11-04 14:56:42.275422499 +0000 +@@ -2191,6 +2191,9 @@ struct elf_aarch64_obj_tdata + + /* Zero to warn when linking objects with incompatible wchar_t sizes. */ + int no_wchar_size_warning; ++ ++ /* All GNU_PROPERTY_AARCH64_FEATURE_1_AND properties. */ ++ uint32_t gnu_and_prop; + }; + + #define elf_aarch64_tdata(bfd) \ +@@ -9311,6 +9314,32 @@ elfNN_aarch64_backend_symbol_processing + sym->flags |= BSF_KEEP; + } + ++/* Implement elf_backend_setup_gnu_properties for AArch64. It serves as a ++ wrapper function for _bfd_aarch64_elf_link_setup_gnu_properties to account ++ for the effect of GNU properties of the output_bfd. */ ++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); ++ elf_aarch64_tdata (info->output_bfd)->gnu_and_prop = prop; ++ return pbfd; ++} ++ ++/* Implement elf_backend_merge_gnu_properties for AArch64. It serves as a ++ wrapper function for _bfd_aarch64_elf_merge_gnu_properties to account ++ for the effect of GNU properties of the output_bfd. */ ++static bfd_boolean ++elfNN_aarch64_merge_gnu_properties (struct bfd_link_info *info, ++ bfd *abfd, ++ elf_property *aprop, ++ elf_property *bprop) ++{ ++ uint32_t prop ++ = elf_aarch64_tdata (info->output_bfd)->gnu_and_prop; ++ return _bfd_aarch64_elf_merge_gnu_properties (info, abfd, aprop, ++ bprop, prop); ++} + + /* We use this so we can override certain functions + (though currently we don't). */ +@@ -9453,6 +9482,12 @@ const struct elf_size_info elfNN_aarch64 + #define elf_backend_symbol_processing \ + elfNN_aarch64_backend_symbol_processing + ++#define elf_backend_setup_gnu_properties \ ++ elfNN_aarch64_link_setup_gnu_properties ++ ++#define elf_backend_merge_gnu_properties \ ++ elfNN_aarch64_merge_gnu_properties ++ + #define elf_backend_can_refcount 1 + #define elf_backend_can_gc_sections 1 + #define elf_backend_plt_readonly 1 +diff -rup binutils.orig/bfd/elfxx-aarch64.c binutils-2.30/bfd/elfxx-aarch64.c +--- binutils.orig/bfd/elfxx-aarch64.c 2020-11-04 14:53:52.138476401 +0000 ++++ binutils-2.30/bfd/elfxx-aarch64.c 2020-11-04 14:56:42.276422492 +0000 +@@ -660,3 +660,183 @@ _bfd_aarch64_elf_write_core_note (bfd *a + } + } + } ++ ++/* Find the first input bfd with GNU property and merge it with GPROP. If no ++ such input is found, add it to a new section at the last input. Update ++ GPROP accordingly. */ ++bfd * ++_bfd_aarch64_elf_link_setup_gnu_properties (struct bfd_link_info *info, ++ uint32_t *gprop) ++{ ++ asection *sec; ++ bfd *pbfd; ++ bfd *ebfd = NULL; ++ elf_property *prop; ++ ++ uint32_t gnu_prop = *gprop; ++ ++ /* Find a normal input file with GNU property note. */ ++ for (pbfd = info->input_bfds; ++ pbfd != NULL; ++ pbfd = pbfd->link.next) ++ if (bfd_get_flavour (pbfd) == bfd_target_elf_flavour ++ && bfd_count_sections (pbfd) != 0) ++ { ++ ebfd = pbfd; ++ ++ if (elf_properties (pbfd) != NULL) ++ break; ++ } ++ ++ /* If ebfd != NULL it is either an input with property note or the last ++ input. Either way if we have gnu_prop, we should add it (by creating ++ a section if needed). */ ++ if (ebfd != NULL && gnu_prop) ++ { ++ prop = _bfd_elf_get_property (ebfd, ++ GNU_PROPERTY_AARCH64_FEATURE_1_AND, ++ 4); ++ prop->u.number |= gnu_prop; ++ prop->pr_kind = property_number; ++ ++ /* pbfd being NULL implies ebfd is the last input. Create the GNU ++ property note section. */ ++ if (pbfd == NULL) ++ { ++ sec = bfd_make_section_with_flags (ebfd, ++ NOTE_GNU_PROPERTY_SECTION_NAME, ++ (SEC_ALLOC ++ | SEC_LOAD ++ | SEC_IN_MEMORY ++ | SEC_READONLY ++ | SEC_HAS_CONTENTS ++ | SEC_DATA)); ++ if (sec == NULL) ++ info->callbacks->einfo ( ++ _("%F%P: failed to create GNU property section\n")); ++ ++ elf_section_type (sec) = SHT_NOTE; ++ } ++ } ++ ++ pbfd = _bfd_elf_link_setup_gnu_properties (info); ++ ++ if (bfd_link_relocatable (info)) ++ return pbfd; ++ ++ /* If pbfd has any GNU_PROPERTY_AARCH64_FEATURE_1_AND properties, update ++ gnu_prop accordingly. */ ++ if (pbfd != NULL) ++ { ++ elf_property_list *p; ++ ++ /* The property list is sorted in order of type. */ ++ for (p = elf_properties (pbfd); p; p = p->next) ++ { ++ /* Check for all GNU_PROPERTY_AARCH64_FEATURE_1_AND. */ ++ if (GNU_PROPERTY_AARCH64_FEATURE_1_AND == p->property.pr_type) ++ { ++ gnu_prop = (p->property.u.number ++ & (GNU_PROPERTY_AARCH64_FEATURE_1_PAC ++ | GNU_PROPERTY_AARCH64_FEATURE_1_BTI)); ++ break; ++ } ++ else if (GNU_PROPERTY_AARCH64_FEATURE_1_AND < p->property.pr_type) ++ break; ++ } ++ } ++ *gprop = gnu_prop; ++ return pbfd; ++} ++ ++/* Define elf_backend_parse_gnu_properties for AArch64. */ ++enum elf_property_kind ++_bfd_aarch64_elf_parse_gnu_properties (bfd *abfd, unsigned int type, ++ bfd_byte *ptr, unsigned int datasz) ++{ ++ elf_property *prop; ++ ++ switch (type) ++ { ++ case GNU_PROPERTY_AARCH64_FEATURE_1_AND: ++ if (datasz != 4) ++ { ++ _bfd_error_handler ++ ( _("error: %pB: "), ++ abfd, datasz); ++ return property_corrupt; ++ } ++ prop = _bfd_elf_get_property (abfd, type, datasz); ++ /* Combine properties of the same type. */ ++ prop->u.number |= bfd_h_get_32 (abfd, ptr); ++ prop->pr_kind = property_number; ++ break; ++ ++ default: ++ return property_ignored; ++ } ++ ++ return property_number; ++} ++ ++/* Merge AArch64 GNU property BPROP with APROP also accounting for PROP. ++ If APROP isn't NULL, merge it with BPROP and/or PROP. Vice-versa if BROP ++ isn't NULL. Return TRUE if there is any update to APROP or if BPROP should ++ be merge with ABFD. */ ++bfd_boolean ++_bfd_aarch64_elf_merge_gnu_properties (struct bfd_link_info *info ++ ATTRIBUTE_UNUSED, ++ bfd *abfd ATTRIBUTE_UNUSED, ++ elf_property *aprop, ++ elf_property *bprop, ++ uint32_t prop) ++{ ++ unsigned int orig_number; ++ bfd_boolean updated = FALSE; ++ unsigned int pr_type = aprop != NULL ? aprop->pr_type : bprop->pr_type; ++ ++ switch (pr_type) ++ { ++ case GNU_PROPERTY_AARCH64_FEATURE_1_AND: ++ { ++ if (aprop != NULL && bprop != NULL) ++ { ++ orig_number = aprop->u.number; ++ aprop->u.number = (orig_number & bprop->u.number) | prop; ++ updated = orig_number != aprop->u.number; ++ /* Remove the property if all feature bits are cleared. */ ++ if (aprop->u.number == 0) ++ aprop->pr_kind = property_remove; ++ break; ++ } ++ /* If either is NULL, the AND would be 0 so, if there is ++ any PROP, asign it to the input that is not NULL. */ ++ if (prop) ++ { ++ if (aprop != NULL) ++ { ++ orig_number = aprop->u.number; ++ aprop->u.number = prop; ++ updated = orig_number != aprop->u.number; ++ } ++ else ++ { ++ bprop->u.number = prop; ++ updated = TRUE; ++ } ++ } ++ /* No PROP and BPROP is NULL, so remove APROP. */ ++ else if (aprop != NULL) ++ { ++ aprop->pr_kind = property_remove; ++ updated = TRUE; ++ } ++ } ++ break; ++ ++ default: ++ abort (); ++ } ++ ++ return updated; ++} +diff -rup binutils.orig/bfd/elfxx-aarch64.h binutils-2.30/bfd/elfxx-aarch64.h +--- binutils.orig/bfd/elfxx-aarch64.h 2020-11-04 14:53:52.134476424 +0000 ++++ binutils-2.30/bfd/elfxx-aarch64.h 2020-11-04 14:56:42.276422492 +0000 +@@ -65,3 +65,19 @@ _bfd_aarch64_elf_write_core_note (bfd *, + #define elf_backend_grok_prstatus _bfd_aarch64_elf_grok_prstatus + #define elf_backend_grok_psinfo _bfd_aarch64_elf_grok_psinfo + #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 *); ++ ++extern enum elf_property_kind ++_bfd_aarch64_elf_parse_gnu_properties (bfd *, unsigned int, ++ bfd_byte *, unsigned int); ++ ++extern bfd_boolean ++_bfd_aarch64_elf_merge_gnu_properties (struct bfd_link_info *, bfd *, ++ elf_property *, elf_property *, ++ uint32_t); ++ ++#define elf_backend_parse_gnu_properties \ ++ _bfd_aarch64_elf_parse_gnu_properties +diff -rup binutils.orig/binutils/readelf.c binutils-2.30/binutils/readelf.c +--- binutils.orig/binutils/readelf.c 2020-11-04 14:53:51.723478764 +0000 ++++ binutils-2.30/binutils/readelf.c 2020-11-04 14:56:42.277422485 +0000 +@@ -17103,6 +17103,33 @@ decode_x86_feature_2 (unsigned int bitma + } + + static void ++decode_aarch64_feature_1_and (unsigned int bitmask) ++{ ++ while (bitmask) ++ { ++ unsigned int bit = bitmask & (- bitmask); ++ ++ bitmask &= ~ bit; ++ switch (bit) ++ { ++ case GNU_PROPERTY_AARCH64_FEATURE_1_BTI: ++ printf ("BTI"); ++ break; ++ ++ case GNU_PROPERTY_AARCH64_FEATURE_1_PAC: ++ printf ("PAC"); ++ break; ++ ++ default: ++ printf (_(""), bit); ++ break; ++ } ++ if (bitmask) ++ printf (", "); ++ } ++} ++ ++static void + print_gnu_property_note (Filedata * filedata, Elf_Internal_Note * pnote) + { + unsigned char * ptr = (unsigned char *) pnote->descdata; +@@ -17236,6 +17263,18 @@ print_gnu_property_note (Filedata * file + break; + } + } ++ else if (filedata->file_header.e_machine == EM_AARCH64) ++ { ++ if (type == GNU_PROPERTY_AARCH64_FEATURE_1_AND) ++ { ++ printf ("AArch64 feature: "); ++ if (datasz != 4) ++ printf (_(" "), datasz); ++ else ++ decode_aarch64_feature_1_and (byte_get (ptr, 4)); ++ goto next; ++ } ++ } + } + else + { +diff -rup binutils.orig/include/elf/common.h binutils-2.30/include/elf/common.h +--- binutils.orig/include/elf/common.h 2020-11-04 14:53:52.155476304 +0000 ++++ binutils-2.30/include/elf/common.h 2020-11-04 14:56:42.277422485 +0000 +@@ -832,6 +832,12 @@ + #define GNU_PROPERTY_X86_FEATURE_2_XSAVEOPT (1U << 8) + #define GNU_PROPERTY_X86_FEATURE_2_XSAVEC (1U << 9) + ++/* AArch64 specific GNU PROPERTY. */ ++#define GNU_PROPERTY_AARCH64_FEATURE_1_AND 0xc0000000 ++ ++#define GNU_PROPERTY_AARCH64_FEATURE_1_BTI (1U << 0) ++#define GNU_PROPERTY_AARCH64_FEATURE_1_PAC (1U << 1) ++ + /* Values used in GNU .note.ABI-tag notes (NT_GNU_ABI_TAG). */ + #define GNU_ABI_TAG_LINUX 0 + #define GNU_ABI_TAG_HURD 1 +diff -rup binutils.orig/ld/testsuite/ld-aarch64/aarch64-elf.exp binutils-2.30/ld/testsuite/ld-aarch64/aarch64-elf.exp +--- binutils.orig/ld/testsuite/ld-aarch64/aarch64-elf.exp 2020-11-04 14:53:51.843478081 +0000 ++++ binutils-2.30/ld/testsuite/ld-aarch64/aarch64-elf.exp 2020-11-04 14:56:42.278422479 +0000 +@@ -337,6 +337,10 @@ run_dump_test_lp64 "variant_pcs-r" + run_dump_test_lp64 "variant_pcs-shared" + run_dump_test_lp64 "variant_pcs-now" + ++run_dump_test "property-bti-pac1" ++run_dump_test "property-bti-pac2" ++run_dump_test "property-bti-pac3" ++ + set aarch64elflinktests { + {"ld-aarch64/so with global symbol" "-shared" "" "" {copy-reloc-so.s} + {} "copy-reloc-so.so"} +--- /dev/null 2020-11-04 08:04:13.849482156 +0000 ++++ binutils-2.30/ld/testsuite/ld-aarch64/property-bti-pac1.d 2020-11-04 14:56:42.278422479 +0000 +@@ -0,0 +1,11 @@ ++#name: GNU Property (single input, combine section) ++#source: property-bti-pac1.s ++#as: -march=armv8.5-a -defsym __mult__=0 ++#ld: -shared ++#readelf: -n ++#target: *linux* ++ ++Displaying notes found in: .note.gnu.property ++ Owner Data size Description ++ GNU 0x00000010 NT_GNU_PROPERTY_TYPE_0 ++ Properties: AArch64 feature: BTI, PAC +--- /dev/null 2020-11-04 08:04:13.849482156 +0000 ++++ binutils-2.30/ld/testsuite/ld-aarch64/property-bti-pac1.s 2020-11-04 14:56:42.278422479 +0000 +@@ -0,0 +1,37 @@ ++ .text ++ .globl _start ++ .type _start,@function ++_start: ++ mov x1, #2 ++.ifndef __mult__ ++ bl foo ++.endif ++ .section ".note.gnu.property", "a" ++ .p2align 3 ++ .long 1f - 0f /* name length */ ++ .long 5f - 2f /* data length */ ++ .long 5 /* note type */ ++0: .asciz "GNU" /* vendor name */ ++1: ++ .p2align 3 ++2: .long 0xc0000000 /* pr_type. */ ++ .long 4f - 3f /* pr_datasz. */ ++3: ++ .long 0x2 /* PAC. */ ++4: ++ .p2align 3 ++5: ++ .p2align 3 ++ .long 1f - 0f /* name length */ ++ .long 5f - 2f /* data length */ ++ .long 5 /* note type */ ++0: .asciz "GNU" /* vendor name */ ++1: ++ .p2align 3 ++2: .long 0xc0000000 /* pr_type. */ ++ .long 4f - 3f /* pr_datasz. */ ++3: ++ .long 0x1 /* BTI. */ ++4: ++ .p2align 3 ++5: +--- /dev/null 2020-11-04 08:04:13.849482156 +0000 ++++ binutils-2.30/ld/testsuite/ld-aarch64/property-bti-pac2.s 2020-11-04 14:56:42.278422479 +0000 +@@ -0,0 +1,50 @@ ++ .text ++ .global foo ++ .type foo, %function ++foo: ++ sub sp, sp, #16 ++ mov w0, 9 ++ str w0, [sp, 12] ++ ldr w0, [sp, 12] ++ add w0, w0, 4 ++ str w0, [sp, 12] ++ nop ++ add sp, sp, 16 ++ ret ++ .size foo, .-foo ++ .global bar ++ .type bar, %function ++.ifdef __property_bti__ ++ .section ".note.gnu.property", "a" ++ .p2align 3 ++ .long 1f - 0f /* name length */ ++ .long 5f - 2f /* data length */ ++ .long 5 /* note type */ ++0: .asciz "GNU" /* vendor name */ ++1: ++ .p2align 3 ++2: .long 0xc0000000 /* pr_type. */ ++ .long 4f - 3f /* pr_datasz. */ ++3: ++ .long 0x1 /* BTI. */ ++4: ++ .p2align 3 ++5: ++.endif ++.ifdef __property_pac__ ++ .section ".note.gnu.property", "a" ++ .p2align 3 ++ .long 1f - 0f /* name length */ ++ .long 5f - 2f /* data length */ ++ .long 5 /* note type */ ++0: .asciz "GNU" /* vendor name */ ++1: ++ .p2align 3 ++2: .long 0xc0000000 /* pr_type. */ ++ .long 4f - 3f /* pr_datasz. */ ++3: ++ .long 0x2 /* PAC. */ ++4: ++ .p2align 3 ++5: ++.endif +--- /dev/null 2020-11-04 08:04:13.849482156 +0000 ++++ binutils-2.30/ld/testsuite/ld-aarch64/property-bti-pac2.d 2020-11-04 14:56:42.278422479 +0000 +@@ -0,0 +1,12 @@ ++#name: GNU Property (combine multiple with BTI) ++#source: property-bti-pac1.s ++#source: property-bti-pac2.s ++#as: -mabi=lp64 -defsym __property_bti__=1 ++#ld: -e _start ++#readelf: -n ++#target: *linux* ++ ++Displaying notes found in: .note.gnu.property ++ Owner Data size Description ++ GNU 0x00000010 NT_GNU_PROPERTY_TYPE_0 ++ Properties: AArch64 feature: BTI +--- /dev/null 2020-11-04 08:04:13.849482156 +0000 ++++ binutils-2.30/ld/testsuite/ld-aarch64/property-bti-pac3.d 2020-11-04 14:56:42.278422479 +0000 +@@ -0,0 +1,12 @@ ++#name: GNU Property (combine multiple with PAC) ++#source: property-bti-pac1.s ++#source: property-bti-pac2.s ++#as: -mabi=lp64 -defsym __property_pac__=1 ++#ld: -e _start ++#readelf: -n ++#target: *linux* ++ ++Displaying notes found in: .note.gnu.property ++ Owner Data size Description ++ GNU 0x00000010 NT_GNU_PROPERTY_TYPE_0 ++ Properties: AArch64 feature: PAC +diff -rup binutils.orig/bfd/elfnn-aarch64.c binutils-2.30/bfd/elfnn-aarch64.c +--- binutils.orig/bfd/elfnn-aarch64.c 2020-11-25 11:53:26.648275978 +0000 ++++ binutils-2.30/bfd/elfnn-aarch64.c 2020-11-25 12:21:39.276864970 +0000 +@@ -9331,12 +9331,14 @@ elfNN_aarch64_link_setup_gnu_properties + for the effect of GNU properties of the output_bfd. */ + static bfd_boolean + elfNN_aarch64_merge_gnu_properties (struct bfd_link_info *info, +- bfd *abfd, +- elf_property *aprop, +- elf_property *bprop) ++ bfd *abfd, ++ bfd *bbfd ATTRIBUTE_UNUSED, ++ elf_property *aprop, ++ elf_property *bprop) + { + uint32_t prop + = elf_aarch64_tdata (info->output_bfd)->gnu_and_prop; ++ + return _bfd_aarch64_elf_merge_gnu_properties (info, abfd, aprop, + bprop, prop); + } +diff -rup binutils.orig/bfd/elfxx-aarch64.c binutils-2.30/bfd/elfxx-aarch64.c +--- binutils.orig/bfd/elfxx-aarch64.c 2020-11-25 11:53:26.655275930 +0000 ++++ binutils-2.30/bfd/elfxx-aarch64.c 2020-11-25 12:21:34.689895875 +0000 +@@ -22,6 +22,7 @@ + #include "elfxx-aarch64.h" + #include + #include ++#include "libbfd.h" + + #define MASK(n) ((1u << (n)) - 1) + +@@ -835,7 +836,10 @@ _bfd_aarch64_elf_merge_gnu_properties (s + break; + + default: +- abort (); ++ _bfd_error_handler ++ ( _("error: %pB: "), ++ abfd, pr_type); ++ return FALSE; + } + + return updated; +diff -rup binutils.orig/ld/testsuite/ld-aarch64/property-bti-pac1.d binutils-2.30/ld/testsuite/ld-aarch64/property-bti-pac1.d +--- binutils.orig/ld/testsuite/ld-aarch64/property-bti-pac1.d 2020-11-25 11:53:26.344278044 +0000 ++++ binutils-2.30/ld/testsuite/ld-aarch64/property-bti-pac1.d 2020-11-25 11:57:53.179471900 +0000 +@@ -1,6 +1,6 @@ + #name: GNU Property (single input, combine section) + #source: property-bti-pac1.s +-#as: -march=armv8.5-a -defsym __mult__=0 ++#as: -defsym __mult__=0 + #ld: -shared + #readelf: -n + #target: *linux* diff --git a/SPECS/binutils.spec b/SPECS/binutils.spec index 106de1b..dffae80 100644 --- a/SPECS/binutils.spec +++ b/SPECS/binutils.spec @@ -2,7 +2,7 @@ Summary: A GNU collection of binary utilities Name: %{?cross}binutils%{?_with_debug:-debug} Version: 2.30 -Release: 85%{?dist} +Release: 87%{?dist} License: GPLv3+ URL: https://sourceware.org/binutils @@ -506,6 +506,10 @@ Patch80: binutils-ld-IR-override.patch # Lifetime: Fixed in 2.31 Patch81: binutils-x86-tpause.patch +# Purpose: Add support for Aarch64 GNU Property notes +# Lifetime: Fixed in 2.34 +Patch82: binutils-aarch64-properties.patch + #---------------------------------------------------------------------------- Provides: bundled(libiberty) @@ -711,6 +715,7 @@ using libelf instead of BFD. %patch79 -p1 %patch80 -p1 %patch81 -p1 +%patch82 -p1 # We cannot run autotools as there is an exact requirement of autoconf-2.59. # FIXME - this is no longer true. Maybe try reinstating autotool use ? @@ -998,14 +1003,14 @@ $OUTPUT_FORMAT INPUT ( %{_libdir}/libopcodes.a -lbfd ) EOH -%else # !isnative +%else # For cross-binutils we drop the documentation. rm -rf %{buildroot}%{_infodir} # We keep these as one can have native + cross binutils of different versions. #rm -rf {buildroot}{_prefix}/share/locale #rm -rf {buildroot}{_mandir} rm -rf %{buildroot}%{_libdir}/libiberty.a -%endif # !isnative +%endif # This one comes from gcc rm -f %{buildroot}%{_infodir}/dir @@ -1042,7 +1047,7 @@ fi if [ $1 = 0 ]; then %{_sbindir}/alternatives --auto %{?cross}ld fi -%endif # both ld.gold and ld.bfd +%endif %if %{isnative} /sbin/ldconfig @@ -1053,8 +1058,8 @@ fi /sbin/install-info --info-dir=%{_infodir} %{_infodir}/gprof.info.gz /sbin/install-info --info-dir=%{_infodir} %{_infodir}/ld.info.gz /sbin/install-info --info-dir=%{_infodir} %{_infodir}/standards.info.gz -%endif # with docs -%endif # isnative +%endif +%endif exit 0 @@ -1066,7 +1071,7 @@ if [ $1 = 0 ]; then %{_sbindir}/alternatives --remove %{?cross}ld %{_bindir}/%{?cross}ld.bfd %{_sbindir}/alternatives --remove %{?cross}ld %{_bindir}/%{?cross}ld.gold fi -%endif # both ld.gold and ld.bfd +%endif %if %{isnative} if [ $1 = 0 ]; then @@ -1079,7 +1084,7 @@ if [ $1 = 0 ]; then /sbin/install-info --quiet --delete --info-dir=%{_infodir} %{_infodir}/standards.info.gz fi fi -%endif # isnative +%endif exit 0 @@ -1096,7 +1101,7 @@ exit 0 /sbin/install-info --delete --info-dir=%{_infodir} %{_infodir}/ld.info.gz /sbin/install-info --quiet --delete --info-dir=%{_infodir} %{_infodir}/standards.info.gz fi -%endif # isnative +%endif #---------------------------------------------------------------------------- @@ -1110,7 +1115,7 @@ exit 0 %ghost %{_bindir}/%{?cross}ld %else %{_bindir}/%{?cross}ld* -%endif # both ld.gold and ld.bfd +%endif %if %{with docs} %{_mandir}/man1/* @@ -1119,20 +1124,20 @@ exit 0 %{_infodir}/gprof.info.gz %{_infodir}/ld.info.gz %{_infodir}/standards.info.gz -%endif # with docs +%endif %if %{enable_shared} %{_libdir}/lib*.so %exclude %{_libdir}/libbfd.so %exclude %{_libdir}/libopcodes.so -%endif # enable_shared +%endif %if %{isnative} %if %{with docs} %{_infodir}/[^b]*info* %{_infodir}/binutils*info* -%endif # with docs +%endif %files devel %{_prefix}/include/* @@ -1142,12 +1147,18 @@ exit 0 %if %{with docs} %{_infodir}/bfd*info* -%endif # with docs +%endif -%endif # isnative +%endif #---------------------------------------------------------------------------- %changelog +* Wed Nov 25 2020 Nick Clifton - 2.30-87 +- Fix bug in patch for AArch64 GNU Property notes support. (#1889643) + +* Wed Nov 04 2020 Nick Clifton - 2.30-86 +- Add support for AArch64 GNU Property notes. (#1889643) + * Tue Nov 03 2020 Nick Clifton - 2.30-85 - Add support for the TPAUSE and UNWAIT instructions in the x86 assembler. (#1893292) diff --git a/bfd/Makefile.am b/bfd/Makefile.am index 3a41b44..6133330 100644 --- a/bfd/Makefile.am +++ b/bfd/Makefile.am @@ -1090,8 +1090,8 @@ DISTCLEANFILES = $(BUILD_CFILES) $(BUILD_HFILES) libtool-soversion bfdver.h: $(srcdir)/version.h $(srcdir)/development.sh $(srcdir)/Makefile.in @echo "creating $@" @bfd_version=`echo "$(VERSION)" | $(SED) -e 's/\([^\.]*\)\.*\([^\.]*\)\.*\([^\.]*\)\.*\([^\.]*\)\.*\([^\.]*\).*/\1.00\2.00\3.00\4.00\5/' -e 's/\([^\.]*\)\..*\(..\)\..*\(..\)\..*\(..\)\..*\(..\)$$/\1\2\3\4\5/'` ;\ - bfd_version_string="\"$(VERSION)-85.el8\"" ;\ - bfd_soversion="$(VERSION)-85.el8" ;\ + bfd_version_string="\"$(VERSION)-87.el8\"" ;\ + bfd_soversion="$(VERSION)-87.el8" ;\ bfd_version_package="\"$(PKGVERSION)\"" ;\ report_bugs_to="\"$(REPORT_BUGS_TO)\"" ;\ . $(srcdir)/development.sh ;\ diff --git a/bfd/Makefile.in b/bfd/Makefile.in index d2cd7dc..4d44462 100644 --- a/bfd/Makefile.in +++ b/bfd/Makefile.in @@ -2210,8 +2210,8 @@ stmp-lcoff-h: $(LIBCOFF_H_FILES) bfdver.h: $(srcdir)/version.h $(srcdir)/development.sh $(srcdir)/Makefile.in @echo "creating $@" @bfd_version=`echo "$(VERSION)" | $(SED) -e 's/\([^\.]*\)\.*\([^\.]*\)\.*\([^\.]*\)\.*\([^\.]*\)\.*\([^\.]*\).*/\1.00\2.00\3.00\4.00\5/' -e 's/\([^\.]*\)\..*\(..\)\..*\(..\)\..*\(..\)\..*\(..\)$$/\1\2\3\4\5/'` ;\ - bfd_version_string="\"$(VERSION)-85.el8\"" ;\ - bfd_soversion="$(VERSION)-85.el8" ;\ + bfd_version_string="\"$(VERSION)-87.el8\"" ;\ + bfd_soversion="$(VERSION)-87.el8" ;\ bfd_version_package="\"$(PKGVERSION)\"" ;\ report_bugs_to="\"$(REPORT_BUGS_TO)\"" ;\ . $(srcdir)/development.sh ;\ diff --git a/bfd/elfnn-aarch64.c b/bfd/elfnn-aarch64.c index 3a78aa0..68dc023 100644 --- a/bfd/elfnn-aarch64.c +++ b/bfd/elfnn-aarch64.c @@ -2191,6 +2191,9 @@ struct elf_aarch64_obj_tdata /* Zero to warn when linking objects with incompatible wchar_t sizes. */ int no_wchar_size_warning; + + /* All GNU_PROPERTY_AARCH64_FEATURE_1_AND properties. */ + uint32_t gnu_and_prop; }; #define elf_aarch64_tdata(bfd) \ @@ -9311,6 +9314,34 @@ elfNN_aarch64_backend_symbol_processing (bfd *abfd, asymbol *sym) sym->flags |= BSF_KEEP; } +/* Implement elf_backend_setup_gnu_properties for AArch64. It serves as a + wrapper function for _bfd_aarch64_elf_link_setup_gnu_properties to account + for the effect of GNU properties of the output_bfd. */ +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); + elf_aarch64_tdata (info->output_bfd)->gnu_and_prop = prop; + return pbfd; +} + +/* Implement elf_backend_merge_gnu_properties for AArch64. It serves as a + wrapper function for _bfd_aarch64_elf_merge_gnu_properties to account + for the effect of GNU properties of the output_bfd. */ +static bfd_boolean +elfNN_aarch64_merge_gnu_properties (struct bfd_link_info *info, + bfd *abfd, + bfd *bbfd ATTRIBUTE_UNUSED, + elf_property *aprop, + elf_property *bprop) +{ + uint32_t prop + = elf_aarch64_tdata (info->output_bfd)->gnu_and_prop; + + return _bfd_aarch64_elf_merge_gnu_properties (info, abfd, aprop, + bprop, prop); +} /* We use this so we can override certain functions (though currently we don't). */ @@ -9453,6 +9484,12 @@ const struct elf_size_info elfNN_aarch64_size_info = #define elf_backend_symbol_processing \ elfNN_aarch64_backend_symbol_processing +#define elf_backend_setup_gnu_properties \ + elfNN_aarch64_link_setup_gnu_properties + +#define elf_backend_merge_gnu_properties \ + elfNN_aarch64_merge_gnu_properties + #define elf_backend_can_refcount 1 #define elf_backend_can_gc_sections 1 #define elf_backend_plt_readonly 1 diff --git a/bfd/elfxx-aarch64.c b/bfd/elfxx-aarch64.c index 9d4aa8f..22abce8 100644 --- a/bfd/elfxx-aarch64.c +++ b/bfd/elfxx-aarch64.c @@ -22,6 +22,7 @@ #include "elfxx-aarch64.h" #include #include +#include "libbfd.h" #define MASK(n) ((1u << (n)) - 1) @@ -660,3 +661,186 @@ _bfd_aarch64_elf_write_core_note (bfd *abfd, char *buf, int *bufsiz, int note_ty } } } + +/* Find the first input bfd with GNU property and merge it with GPROP. If no + such input is found, add it to a new section at the last input. Update + GPROP accordingly. */ +bfd * +_bfd_aarch64_elf_link_setup_gnu_properties (struct bfd_link_info *info, + uint32_t *gprop) +{ + asection *sec; + bfd *pbfd; + bfd *ebfd = NULL; + elf_property *prop; + + uint32_t gnu_prop = *gprop; + + /* Find a normal input file with GNU property note. */ + for (pbfd = info->input_bfds; + pbfd != NULL; + pbfd = pbfd->link.next) + if (bfd_get_flavour (pbfd) == bfd_target_elf_flavour + && bfd_count_sections (pbfd) != 0) + { + ebfd = pbfd; + + if (elf_properties (pbfd) != NULL) + break; + } + + /* If ebfd != NULL it is either an input with property note or the last + input. Either way if we have gnu_prop, we should add it (by creating + a section if needed). */ + if (ebfd != NULL && gnu_prop) + { + prop = _bfd_elf_get_property (ebfd, + GNU_PROPERTY_AARCH64_FEATURE_1_AND, + 4); + prop->u.number |= gnu_prop; + prop->pr_kind = property_number; + + /* pbfd being NULL implies ebfd is the last input. Create the GNU + property note section. */ + if (pbfd == NULL) + { + sec = bfd_make_section_with_flags (ebfd, + NOTE_GNU_PROPERTY_SECTION_NAME, + (SEC_ALLOC + | SEC_LOAD + | SEC_IN_MEMORY + | SEC_READONLY + | SEC_HAS_CONTENTS + | SEC_DATA)); + if (sec == NULL) + info->callbacks->einfo ( + _("%F%P: failed to create GNU property section\n")); + + elf_section_type (sec) = SHT_NOTE; + } + } + + pbfd = _bfd_elf_link_setup_gnu_properties (info); + + if (bfd_link_relocatable (info)) + return pbfd; + + /* If pbfd has any GNU_PROPERTY_AARCH64_FEATURE_1_AND properties, update + gnu_prop accordingly. */ + if (pbfd != NULL) + { + elf_property_list *p; + + /* The property list is sorted in order of type. */ + for (p = elf_properties (pbfd); p; p = p->next) + { + /* Check for all GNU_PROPERTY_AARCH64_FEATURE_1_AND. */ + if (GNU_PROPERTY_AARCH64_FEATURE_1_AND == p->property.pr_type) + { + gnu_prop = (p->property.u.number + & (GNU_PROPERTY_AARCH64_FEATURE_1_PAC + | GNU_PROPERTY_AARCH64_FEATURE_1_BTI)); + break; + } + else if (GNU_PROPERTY_AARCH64_FEATURE_1_AND < p->property.pr_type) + break; + } + } + *gprop = gnu_prop; + return pbfd; +} + +/* Define elf_backend_parse_gnu_properties for AArch64. */ +enum elf_property_kind +_bfd_aarch64_elf_parse_gnu_properties (bfd *abfd, unsigned int type, + bfd_byte *ptr, unsigned int datasz) +{ + elf_property *prop; + + switch (type) + { + case GNU_PROPERTY_AARCH64_FEATURE_1_AND: + if (datasz != 4) + { + _bfd_error_handler + ( _("error: %pB: "), + abfd, datasz); + return property_corrupt; + } + prop = _bfd_elf_get_property (abfd, type, datasz); + /* Combine properties of the same type. */ + prop->u.number |= bfd_h_get_32 (abfd, ptr); + prop->pr_kind = property_number; + break; + + default: + return property_ignored; + } + + return property_number; +} + +/* Merge AArch64 GNU property BPROP with APROP also accounting for PROP. + If APROP isn't NULL, merge it with BPROP and/or PROP. Vice-versa if BROP + isn't NULL. Return TRUE if there is any update to APROP or if BPROP should + be merge with ABFD. */ +bfd_boolean +_bfd_aarch64_elf_merge_gnu_properties (struct bfd_link_info *info + ATTRIBUTE_UNUSED, + bfd *abfd ATTRIBUTE_UNUSED, + elf_property *aprop, + elf_property *bprop, + uint32_t prop) +{ + unsigned int orig_number; + bfd_boolean updated = FALSE; + unsigned int pr_type = aprop != NULL ? aprop->pr_type : bprop->pr_type; + + switch (pr_type) + { + case GNU_PROPERTY_AARCH64_FEATURE_1_AND: + { + if (aprop != NULL && bprop != NULL) + { + orig_number = aprop->u.number; + aprop->u.number = (orig_number & bprop->u.number) | prop; + updated = orig_number != aprop->u.number; + /* Remove the property if all feature bits are cleared. */ + if (aprop->u.number == 0) + aprop->pr_kind = property_remove; + break; + } + /* If either is NULL, the AND would be 0 so, if there is + any PROP, asign it to the input that is not NULL. */ + if (prop) + { + if (aprop != NULL) + { + orig_number = aprop->u.number; + aprop->u.number = prop; + updated = orig_number != aprop->u.number; + } + else + { + bprop->u.number = prop; + updated = TRUE; + } + } + /* No PROP and BPROP is NULL, so remove APROP. */ + else if (aprop != NULL) + { + aprop->pr_kind = property_remove; + updated = TRUE; + } + } + break; + + default: + _bfd_error_handler + ( _("error: %pB: "), + abfd, pr_type); + return FALSE; + } + + return updated; +} diff --git a/bfd/elfxx-aarch64.h b/bfd/elfxx-aarch64.h index 977faf3..653b6dd 100644 --- a/bfd/elfxx-aarch64.h +++ b/bfd/elfxx-aarch64.h @@ -65,3 +65,19 @@ _bfd_aarch64_elf_write_core_note (bfd *, char *, int *, int, ...); #define elf_backend_grok_prstatus _bfd_aarch64_elf_grok_prstatus #define elf_backend_grok_psinfo _bfd_aarch64_elf_grok_psinfo #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 *); + +extern enum elf_property_kind +_bfd_aarch64_elf_parse_gnu_properties (bfd *, unsigned int, + bfd_byte *, unsigned int); + +extern bfd_boolean +_bfd_aarch64_elf_merge_gnu_properties (struct bfd_link_info *, bfd *, + elf_property *, elf_property *, + uint32_t); + +#define elf_backend_parse_gnu_properties \ + _bfd_aarch64_elf_parse_gnu_properties diff --git a/binutils/readelf.c b/binutils/readelf.c index 974502d..4ec86b7 100644 --- a/binutils/readelf.c +++ b/binutils/readelf.c @@ -17103,6 +17103,33 @@ decode_x86_feature_2 (unsigned int bitmask) } static void +decode_aarch64_feature_1_and (unsigned int bitmask) +{ + while (bitmask) + { + unsigned int bit = bitmask & (- bitmask); + + bitmask &= ~ bit; + switch (bit) + { + case GNU_PROPERTY_AARCH64_FEATURE_1_BTI: + printf ("BTI"); + break; + + case GNU_PROPERTY_AARCH64_FEATURE_1_PAC: + printf ("PAC"); + break; + + default: + printf (_(""), bit); + break; + } + if (bitmask) + printf (", "); + } +} + +static void print_gnu_property_note (Filedata * filedata, Elf_Internal_Note * pnote) { unsigned char * ptr = (unsigned char *) pnote->descdata; @@ -17236,6 +17263,18 @@ print_gnu_property_note (Filedata * filedata, Elf_Internal_Note * pnote) break; } } + else if (filedata->file_header.e_machine == EM_AARCH64) + { + if (type == GNU_PROPERTY_AARCH64_FEATURE_1_AND) + { + printf ("AArch64 feature: "); + if (datasz != 4) + printf (_(" "), datasz); + else + decode_aarch64_feature_1_and (byte_get (ptr, 4)); + goto next; + } + } } else { diff --git a/include/elf/common.h b/include/elf/common.h index 36a731a..8a47074 100644 --- a/include/elf/common.h +++ b/include/elf/common.h @@ -832,6 +832,12 @@ #define GNU_PROPERTY_X86_FEATURE_2_XSAVEOPT (1U << 8) #define GNU_PROPERTY_X86_FEATURE_2_XSAVEC (1U << 9) +/* AArch64 specific GNU PROPERTY. */ +#define GNU_PROPERTY_AARCH64_FEATURE_1_AND 0xc0000000 + +#define GNU_PROPERTY_AARCH64_FEATURE_1_BTI (1U << 0) +#define GNU_PROPERTY_AARCH64_FEATURE_1_PAC (1U << 1) + /* Values used in GNU .note.ABI-tag notes (NT_GNU_ABI_TAG). */ #define GNU_ABI_TAG_LINUX 0 #define GNU_ABI_TAG_HURD 1 diff --git a/ld/testsuite/ld-aarch64/aarch64-elf.exp b/ld/testsuite/ld-aarch64/aarch64-elf.exp index 43bce26..3f4a043 100644 --- a/ld/testsuite/ld-aarch64/aarch64-elf.exp +++ b/ld/testsuite/ld-aarch64/aarch64-elf.exp @@ -337,6 +337,10 @@ run_dump_test_lp64 "variant_pcs-r" run_dump_test_lp64 "variant_pcs-shared" run_dump_test_lp64 "variant_pcs-now" +run_dump_test "property-bti-pac1" +run_dump_test "property-bti-pac2" +run_dump_test "property-bti-pac3" + set aarch64elflinktests { {"ld-aarch64/so with global symbol" "-shared" "" "" {copy-reloc-so.s} {} "copy-reloc-so.so"} diff --git a/ld/testsuite/ld-aarch64/property-bti-pac1.d b/ld/testsuite/ld-aarch64/property-bti-pac1.d new file mode 100644 index 0000000..405d96b --- /dev/null +++ b/ld/testsuite/ld-aarch64/property-bti-pac1.d @@ -0,0 +1,11 @@ +#name: GNU Property (single input, combine section) +#source: property-bti-pac1.s +#as: -defsym __mult__=0 +#ld: -shared +#readelf: -n +#target: *linux* + +Displaying notes found in: .note.gnu.property + Owner Data size Description + GNU 0x00000010 NT_GNU_PROPERTY_TYPE_0 + Properties: AArch64 feature: BTI, PAC diff --git a/ld/testsuite/ld-aarch64/property-bti-pac1.s b/ld/testsuite/ld-aarch64/property-bti-pac1.s new file mode 100644 index 0000000..414c927 --- /dev/null +++ b/ld/testsuite/ld-aarch64/property-bti-pac1.s @@ -0,0 +1,37 @@ + .text + .globl _start + .type _start,@function +_start: + mov x1, #2 +.ifndef __mult__ + bl foo +.endif + .section ".note.gnu.property", "a" + .p2align 3 + .long 1f - 0f /* name length */ + .long 5f - 2f /* data length */ + .long 5 /* note type */ +0: .asciz "GNU" /* vendor name */ +1: + .p2align 3 +2: .long 0xc0000000 /* pr_type. */ + .long 4f - 3f /* pr_datasz. */ +3: + .long 0x2 /* PAC. */ +4: + .p2align 3 +5: + .p2align 3 + .long 1f - 0f /* name length */ + .long 5f - 2f /* data length */ + .long 5 /* note type */ +0: .asciz "GNU" /* vendor name */ +1: + .p2align 3 +2: .long 0xc0000000 /* pr_type. */ + .long 4f - 3f /* pr_datasz. */ +3: + .long 0x1 /* BTI. */ +4: + .p2align 3 +5: diff --git a/ld/testsuite/ld-aarch64/property-bti-pac2.d b/ld/testsuite/ld-aarch64/property-bti-pac2.d new file mode 100644 index 0000000..bc2eaad --- /dev/null +++ b/ld/testsuite/ld-aarch64/property-bti-pac2.d @@ -0,0 +1,12 @@ +#name: GNU Property (combine multiple with BTI) +#source: property-bti-pac1.s +#source: property-bti-pac2.s +#as: -mabi=lp64 -defsym __property_bti__=1 +#ld: -e _start +#readelf: -n +#target: *linux* + +Displaying notes found in: .note.gnu.property + Owner Data size Description + GNU 0x00000010 NT_GNU_PROPERTY_TYPE_0 + Properties: AArch64 feature: BTI diff --git a/ld/testsuite/ld-aarch64/property-bti-pac2.s b/ld/testsuite/ld-aarch64/property-bti-pac2.s new file mode 100644 index 0000000..cdec8d9 --- /dev/null +++ b/ld/testsuite/ld-aarch64/property-bti-pac2.s @@ -0,0 +1,50 @@ + .text + .global foo + .type foo, %function +foo: + sub sp, sp, #16 + mov w0, 9 + str w0, [sp, 12] + ldr w0, [sp, 12] + add w0, w0, 4 + str w0, [sp, 12] + nop + add sp, sp, 16 + ret + .size foo, .-foo + .global bar + .type bar, %function +.ifdef __property_bti__ + .section ".note.gnu.property", "a" + .p2align 3 + .long 1f - 0f /* name length */ + .long 5f - 2f /* data length */ + .long 5 /* note type */ +0: .asciz "GNU" /* vendor name */ +1: + .p2align 3 +2: .long 0xc0000000 /* pr_type. */ + .long 4f - 3f /* pr_datasz. */ +3: + .long 0x1 /* BTI. */ +4: + .p2align 3 +5: +.endif +.ifdef __property_pac__ + .section ".note.gnu.property", "a" + .p2align 3 + .long 1f - 0f /* name length */ + .long 5f - 2f /* data length */ + .long 5 /* note type */ +0: .asciz "GNU" /* vendor name */ +1: + .p2align 3 +2: .long 0xc0000000 /* pr_type. */ + .long 4f - 3f /* pr_datasz. */ +3: + .long 0x2 /* PAC. */ +4: + .p2align 3 +5: +.endif diff --git a/ld/testsuite/ld-aarch64/property-bti-pac3.d b/ld/testsuite/ld-aarch64/property-bti-pac3.d new file mode 100644 index 0000000..5290f4b --- /dev/null +++ b/ld/testsuite/ld-aarch64/property-bti-pac3.d @@ -0,0 +1,12 @@ +#name: GNU Property (combine multiple with PAC) +#source: property-bti-pac1.s +#source: property-bti-pac2.s +#as: -mabi=lp64 -defsym __property_pac__=1 +#ld: -e _start +#readelf: -n +#target: *linux* + +Displaying notes found in: .note.gnu.property + Owner Data size Description + GNU 0x00000010 NT_GNU_PROPERTY_TYPE_0 + Properties: AArch64 feature: PAC