From 54f319436b81cd342e636e1f1ddfc95c33999b6b Mon Sep 17 00:00:00 2001 From: Nick Clifton Date: Jun 08 2017 08:34:56 +0000 Subject: Eliminate the generation of incorrect dynamic copy relocations on AArch64. Relates: #1452170 --- diff --git a/binutils-2.28-aarch64-copy-relocs.patch b/binutils-2.28-aarch64-copy-relocs.patch new file mode 100644 index 0000000..8072a02 --- /dev/null +++ b/binutils-2.28-aarch64-copy-relocs.patch @@ -0,0 +1,139 @@ +diff -rupN binutils.orig/bfd/elfnn-aarch64.c binutils-2.28/bfd/elfnn-aarch64.c +--- binutils.orig/bfd/elfnn-aarch64.c 2017-06-08 09:11:46.364977859 +0100 ++++ binutils-2.28/bfd/elfnn-aarch64.c 2017-06-08 09:15:46.901961364 +0100 +@@ -246,7 +246,7 @@ + || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_OFF_G0_NC \ + || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_OFF_G1) + +-#define ELIMINATE_COPY_RELOCS 0 ++#define ELIMINATE_COPY_RELOCS 1 + + /* Return size of a relocation entry. HTAB is the bfd's + elf_aarch64_link_hash_entry. */ +@@ -5152,12 +5152,25 @@ elfNN_aarch64_final_link_relocate (reloc + /* When generating a shared object or relocatable executable, these + relocations are copied into the output file to be resolved at + run time. */ +- if (((bfd_link_pic (info) == TRUE) +- || globals->root.is_relocatable_executable) +- && (input_section->flags & SEC_ALLOC) +- && (h == NULL +- || ELF_ST_VISIBILITY (h->other) == STV_DEFAULT +- || h->root.type != bfd_link_hash_undefweak)) ++ if (((bfd_link_pic (info) ++ || globals->root.is_relocatable_executable) ++ && (input_section->flags & SEC_ALLOC) ++ && (h == NULL ++ || ELF_ST_VISIBILITY (h->other) == STV_DEFAULT ++ || h->root.type != bfd_link_hash_undefweak)) ++ /* Or we are creating an executable, we may need to keep relocations ++ for symbols satisfied by a dynamic library if we manage to avoid ++ copy relocs for the symbol. */ ++ || (ELIMINATE_COPY_RELOCS ++ && !bfd_link_pic (info) ++ && h != NULL ++ && (input_section->flags & SEC_ALLOC) ++ && h->dynindx != -1 ++ && !h->non_got_ref ++ && ((h->def_dynamic ++ && !h->def_regular) ++ || h->root.type == bfd_link_hash_undefweak ++ || h->root.type == bfd_link_hash_undefined))) + { + Elf_Internal_Rela outrel; + bfd_byte *loc; +@@ -6822,6 +6835,25 @@ elfNN_aarch64_gc_sweep_hook (bfd *abfd, + return TRUE; + } + ++/* Return true if we have dynamic relocs against EH or any of its weak ++ aliases, that apply to read-only sections. */ ++ ++static bfd_boolean ++alias_readonly_dynrelocs (struct elf_aarch64_link_hash_entry *eh) ++{ ++ struct elf_dyn_relocs *p; ++ asection *s; ++ ++ for (p = eh->dyn_relocs; p != NULL; p = p->next) ++ { ++ s = p->sec->output_section; ++ if (s != NULL && (s->flags & SEC_READONLY) != 0) ++ return TRUE; ++ } ++ ++ return FALSE; ++} ++ + /* Adjust a symbol defined by a dynamic object and referenced by a + regular object. The current definition is in some section of the + dynamic object, but we're not including those sections. We have to +@@ -6895,6 +6927,19 @@ elfNN_aarch64_adjust_dynamic_symbol (str + return TRUE; + } + ++ if (ELIMINATE_COPY_RELOCS) ++ { ++ struct elf_aarch64_link_hash_entry *eh; ++ /* If we didn't find any dynamic relocs in read-only sections, then ++ we'll be keeping the dynamic relocs and avoiding the copy reloc. */ ++ eh = (struct elf_aarch64_link_hash_entry *) h; ++ if (eh->dyn_relocs && !alias_readonly_dynrelocs (eh)) ++ { ++ h->non_got_ref = 0; ++ return TRUE; ++ } ++ } ++ + /* We must allocate the symbol in our .dynbss section, which will + become part of the .bss section of the executable. There will be + an entry for this symbol in the .dynsym section. The dynamic +@@ -7167,7 +7212,16 @@ elfNN_aarch64_check_relocs (bfd *abfd, s + + /* No need to do anything if we're not creating a shared + object. */ +- if (! bfd_link_pic (info)) ++ if (!(bfd_link_pic (info) ++ /* If on the other hand, we are creating an executable, we ++ may need to keep relocations for symbols satisfied by a ++ dynamic library if we manage to avoid copy relocs for the ++ symbol. */ ++ || (ELIMINATE_COPY_RELOCS ++ && !bfd_link_pic (info) ++ && h != NULL ++ && (h->root.type == bfd_link_hash_defweak ++ || !h->def_regular)))) + break; + + { +diff -rupN binutils.orig/ld/testsuite/ld-aarch64/aarch64-elf.exp binutils-2.28/ld/testsuite/ld-aarch64/aarch64-elf.exp +--- binutils.orig/ld/testsuite/ld-aarch64/aarch64-elf.exp 2017-06-08 09:11:54.845871503 +0100 ++++ binutils-2.28/ld/testsuite/ld-aarch64/aarch64-elf.exp 2017-06-08 09:16:34.984358379 +0100 +@@ -323,6 +323,8 @@ set aarch64elflinktests { + {} "copy-reloc-so.so"} + {"ld-aarch64/exe with copy relocation" "-e0 tmpdir/copy-reloc-so.so" "" "" + {copy-reloc-exe.s} {{objdump -R copy-reloc.d}} "copy-reloc"} ++ {"ld-aarch64/exe with copy relocation elimination" "-e0 tmpdir/copy-reloc-so.so" "" "" ++ {copy-reloc-exe-eliminate.s} {{objdump -R copy-reloc-eliminate.d}} "copy-reloc-elimination"} + } + + run_ld_link_tests $aarch64elflinktests +diff -rupN binutils.orig/ld/testsuite/ld-aarch64/copy-reloc-eliminate.d binutils-2.28/ld/testsuite/ld-aarch64/copy-reloc-eliminate.d +--- binutils.orig/ld/testsuite/ld-aarch64/copy-reloc-eliminate.d 1970-01-01 01:00:00.000000000 +0100 ++++ binutils-2.28/ld/testsuite/ld-aarch64/copy-reloc-eliminate.d 2017-06-08 09:12:10.191679056 +0100 +@@ -0,0 +1,4 @@ ++.* ++DYNAMIC RELOCATION RECORDS ++OFFSET.*TYPE.*VALUE.* ++.*R_AARCH64_ABS64.*global_a +diff -rupN binutils.orig/ld/testsuite/ld-aarch64/copy-reloc-exe-eliminate.s binutils-2.28/ld/testsuite/ld-aarch64/copy-reloc-exe-eliminate.s +--- binutils.orig/ld/testsuite/ld-aarch64/copy-reloc-exe-eliminate.s 1970-01-01 01:00:00.000000000 +0100 ++++ binutils-2.28/ld/testsuite/ld-aarch64/copy-reloc-exe-eliminate.s 2017-06-08 09:12:10.191679056 +0100 +@@ -0,0 +1,7 @@ ++ .global p ++ .section .data.rel.ro,"aw",%progbits ++ .align 3 ++ .type p, %object ++ .size p, 8 ++p: ++ .xword global_a diff --git a/binutils-gnu-build-notes.patch b/binutils-gnu-build-notes.patch index ae6d5e5..71a1339 100644 --- a/binutils-gnu-build-notes.patch +++ b/binutils-gnu-build-notes.patch @@ -1462,3 +1462,187 @@ diff -rup binutils.orig/include/elf/common.h binutils-2.28/include/elf/common.h + .popsection + + +diff -rup binutils.orig/binutils/readelf.c binutils-2.28/binutils/readelf.c +--- binutils.orig/binutils/readelf.c 2017-05-15 17:12:12.760814593 +0100 ++++ binutils-2.28/binutils/readelf.c 2017-05-15 17:26:46.142293641 +0100 +@@ -4130,7 +4130,18 @@ get_section_type_name (unsigned int sh_t + if (elf_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS) + result = get_solaris_section_type (sh_type); + else +- result = NULL; ++ { ++ switch (sh_type) ++ { ++ case SHT_GNU_INCREMENTAL_INPUTS: result = "GNU_INCREMENTAL_INPUTS"; break; ++ case SHT_GNU_ATTRIBUTES: result = "GNU_ATTRIBUTES"; break; ++ case SHT_GNU_HASH: result = "GNU_HASH"; break; ++ case SHT_GNU_LIBLIST: result = "GNU_LIBLIST"; break; ++ default: ++ result = NULL; ++ break; ++ } ++ } + break; + } + +@@ -15928,8 +15939,8 @@ print_gnu_note (Elf_Internal_Note *pnote + printf (_(" Hardware Capabilities: ")); + if (pnote->descsz < 8) + { +- printf (_("\n")); +- break; ++ error (_("\n")); ++ return 0; + } + num_entries = byte_get ((unsigned char *) pnote->descdata, 4); + mask = byte_get ((unsigned char *) pnote->descdata + 4, 4); +@@ -16347,7 +16358,8 @@ print_symbol_for_build_attribute (FILE * + Elf_Internal_Sym * saved_sym = NULL; + Elf_Internal_Sym * sym; + +- if (saved_file == NULL || file != saved_file) ++ if (section_headers != NULL ++ && (saved_file == NULL || file != saved_file)) + { + Elf_Internal_Shdr * symsec; + +@@ -16497,9 +16509,12 @@ print_gnu_build_attribute_description (E + static bfd_boolean + print_gnu_build_attribute_name (Elf_Internal_Note * pnote) + { ++ static const char string_expected [2] = { GNU_BUILD_ATTRIBUTE_TYPE_STRING, 0 }; ++ static const char number_expected [2] = { GNU_BUILD_ATTRIBUTE_TYPE_NUMERIC, 0 }; ++ static const char bool_expected [3] = { GNU_BUILD_ATTRIBUTE_TYPE_BOOL_TRUE, GNU_BUILD_ATTRIBUTE_TYPE_BOOL_FALSE, 0 }; + char name_type; + char name_attribute; +- char * expected_types; ++ const char * expected_types; + const char * name = pnote->namedata; + const char * text; + int left; +@@ -16507,7 +16522,7 @@ print_gnu_build_attribute_name (Elf_Inte + if (name == NULL || pnote->namesz < 2) + { + error (_("corrupt name field in GNU build attribute note: size = %ld\n"), pnote->namesz); +- print_symbol (-20, _(" ")); ++ print_symbol (-20, _(" ")); + return FALSE; + } + +@@ -16533,7 +16548,7 @@ print_gnu_build_attribute_name (Elf_Inte + { + case GNU_BUILD_ATTRIBUTE_VERSION: + text = _(""); +- expected_types = "$"; ++ expected_types = string_expected; + ++ name; + break; + case GNU_BUILD_ATTRIBUTE_STACK_PROT: +@@ -16543,17 +16558,17 @@ print_gnu_build_attribute_name (Elf_Inte + break; + case GNU_BUILD_ATTRIBUTE_RELRO: + text = _(""); +- expected_types = "!+"; ++ expected_types = bool_expected; + ++ name; + break; + case GNU_BUILD_ATTRIBUTE_STACK_SIZE: + text = _(""); +- expected_types = "*"; ++ expected_types = number_expected; + ++ name; + break; + case GNU_BUILD_ATTRIBUTE_TOOL: + text = _(""); +- expected_types = "$"; ++ expected_types = string_expected; + ++ name; + break; + case GNU_BUILD_ATTRIBUTE_ABI: +@@ -16563,12 +16578,12 @@ print_gnu_build_attribute_name (Elf_Inte + break; + case GNU_BUILD_ATTRIBUTE_PIC: + text = _(""); +- expected_types = "*"; ++ expected_types = number_expected; + ++ name; + break; + case GNU_BUILD_ATTRIBUTE_SHORT_ENUM: + text = _(""); +- expected_types = "!+"; ++ expected_types = bool_expected; + ++ name; + break; + +@@ -16585,9 +16600,11 @@ print_gnu_build_attribute_name (Elf_Inte + } + else + { +- error (_("unexpected character in name field\n")); +- print_symbol (- left, _("")); +- return 0; ++ static char tmpbuf [128]; ++ error (_("unrecognised byte in name field: %d\n"), * name); ++ sprintf (tmpbuf, _(""), * name); ++ text = tmpbuf; ++ name ++; + } + expected_types = "*$!+"; + break; +@@ -16617,11 +16634,29 @@ print_gnu_build_attribute_name (Elf_Inte + { + case GNU_BUILD_ATTRIBUTE_TYPE_NUMERIC: + { +- unsigned int bytes = pnote->namesz - (name - pnote->namedata); +- unsigned long val = 0; ++ unsigned int bytes; ++ unsigned long long val = 0; + unsigned int shift = 0; + char * decoded = NULL; + ++ bytes = pnote->namesz - (name - pnote->namedata); ++ if (bytes > 0) ++ /* The -1 is because the name field is always 0 terminated, and we ++ want to be able to ensure that the shift in the while loop below ++ will not overflow. */ ++ -- bytes; ++ ++ if (bytes > sizeof (val)) ++ { ++ fprintf (stderr, "namesz %lx name %p namedata %p\n", ++ pnote->namesz, name, pnote->namedata); ++ error (_("corrupt numeric name field: too many bytes in the value: %x\n"), ++ bytes); ++ bytes = sizeof (val); ++ } ++ /* We do not bother to warn if bytes == 0 as this can ++ happen with some early versions of the gcc plugin. */ ++ + while (bytes --) + { + unsigned long byte = (* name ++) & 0xff; +@@ -16660,13 +16695,21 @@ print_gnu_build_attribute_name (Elf_Inte + } + + if (decoded != NULL) +- print_symbol (-left, decoded); ++ { ++ print_symbol (-left, decoded); ++ left = 0; ++ } ++ else if (val == 0) ++ { ++ printf ("0x0"); ++ left -= 3; ++ } + else + { + if (do_wide) +- left -= printf ("0x%lx", val); ++ left -= printf ("0x%llx", val); + else +- left -= printf ("0x%-.*lx", left, val); ++ left -= printf ("0x%-.*llx", left, val); + } + } + break; diff --git a/binutils.spec b/binutils.spec index 37794b4..5a49578 100644 --- a/binutils.spec +++ b/binutils.spec @@ -43,7 +43,7 @@ Summary: A GNU collection of binary utilities Name: %{?cross}binutils%{?_with_debug:-debug} Version: 2.28 -Release: 6%{?dist} +Release: 7%{?dist} License: GPLv3+ Group: Development/Tools URL: http://sources.redhat.com/binutils @@ -89,6 +89,8 @@ Patch18: binutils-2.28-gas-comp_dir.patch Patch19: binutils-2.28-ppc-dynamic-relocs.patch # Have readelf skip checks of the dynamic section when its type is SHT_NOBITS. Patch20: binutils-2.28-dynamic-section-warning.patch +# Fix incorrect generation of copy relocs on AArch64. +Patch21: binutils-2.28-aarch64-copy-relocs.patch Provides: bundled(libiberty) @@ -230,6 +232,7 @@ using libelf instead of BFD. %patch18 -p1 %patch19 -p1 %patch20 -p1 +%patch21 -p1 # We cannot run autotools as there is an exact requirement of autoconf-2.59. @@ -596,6 +599,10 @@ exit 0 %endif # %{isnative} %changelog +* Thu Jun 08 2017 Nick Clifton 2.28-7 +- Eliminate the generation of incorrect dynamic copy relocations on AArch64. + (#1452170) + * Mon May 15 2017 Fedora Release Engineering - 2.28-6 - Rebuilt for https://fedoraproject.org/wiki/Fedora_26_27_Mass_Rebuild