Eliminate the generation of incorrect dynamic copy relocations on AArch64.
Relates: #1452170
This commit is contained in:
parent
da381ca746
commit
54f319436b
139
binutils-2.28-aarch64-copy-relocs.patch
Normal file
139
binutils-2.28-aarch64-copy-relocs.patch
Normal file
@ -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
|
@ -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 (_("<corrupt GNU_HWCAP>\n"));
|
||||
- break;
|
||||
+ error (_("<corrupt GNU_HWCAP>\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, _(" <corrupt name field>"));
|
||||
+ print_symbol (-20, _(" <corrupt name>"));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@@ -16533,7 +16548,7 @@ print_gnu_build_attribute_name (Elf_Inte
|
||||
{
|
||||
case GNU_BUILD_ATTRIBUTE_VERSION:
|
||||
text = _("<version>");
|
||||
- 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 = _("<relro>");
|
||||
- expected_types = "!+";
|
||||
+ expected_types = bool_expected;
|
||||
++ name;
|
||||
break;
|
||||
case GNU_BUILD_ATTRIBUTE_STACK_SIZE:
|
||||
text = _("<stack size>");
|
||||
- expected_types = "*";
|
||||
+ expected_types = number_expected;
|
||||
++ name;
|
||||
break;
|
||||
case GNU_BUILD_ATTRIBUTE_TOOL:
|
||||
text = _("<tool>");
|
||||
- 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 = _("<PIC>");
|
||||
- expected_types = "*";
|
||||
+ expected_types = number_expected;
|
||||
++ name;
|
||||
break;
|
||||
case GNU_BUILD_ATTRIBUTE_SHORT_ENUM:
|
||||
text = _("<short enum>");
|
||||
- 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, _("<unknown attribute>"));
|
||||
- return 0;
|
||||
+ static char tmpbuf [128];
|
||||
+ error (_("unrecognised byte in name field: %d\n"), * name);
|
||||
+ sprintf (tmpbuf, _("<unknown:_%d>"), * 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;
|
||||
|
@ -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 <nickc@redhat.com> 2.28-7
|
||||
- Eliminate the generation of incorrect dynamic copy relocations on AArch64.
|
||||
(#1452170)
|
||||
|
||||
* Mon May 15 2017 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 2.28-6
|
||||
- Rebuilt for https://fedoraproject.org/wiki/Fedora_26_27_Mass_Rebuild
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user