aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bfd/ChangeLog11
-rw-r--r--bfd/elf64-x86-64.c46
-rw-r--r--ld/testsuite/ChangeLog10
-rw-r--r--ld/testsuite/ld-x86-64/copyreloc-lib.c1
-rw-r--r--ld/testsuite/ld-x86-64/copyreloc-main.c7
-rw-r--r--ld/testsuite/ld-x86-64/copyreloc-main.out0
-rw-r--r--ld/testsuite/ld-x86-64/copyreloc-main1.rd3
-rw-r--r--ld/testsuite/ld-x86-64/copyreloc-main2.rd4
-rw-r--r--ld/testsuite/ld-x86-64/x86-64.exp32
9 files changed, 103 insertions, 11 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index 010cf55..434db31 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,3 +1,14 @@
+2014-12-02 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elf64-x86-64.c (elf_x86_64_create_dynamic_sections): Always
+ allow copy relocs for building executables.
+ (elf_x86_64_check_relocs): Allow copy relocs for non-GOT
+ pc-relative relocation in shared object.
+ (elf_x86_64_adjust_dynamic_symbol): Allocate copy relocs for
+ PIE.
+ (elf_x86_64_relocate_section): Don't copy a pc-relative
+ relocation into the output file if the symbol needs copy reloc.
+
2014-12-02 Andrew Bennett <andrew.bennett@imgtec.com>
* elfxx-mips.c (mips_elf_calculate_relocation): Only check for
diff --git a/bfd/elf64-x86-64.c b/bfd/elf64-x86-64.c
index b10c0c1..60d2d59 100644
--- a/bfd/elf64-x86-64.c
+++ b/bfd/elf64-x86-64.c
@@ -1060,13 +1060,29 @@ elf_x86_64_create_dynamic_sections (bfd *dynobj,
return FALSE;
htab->sdynbss = bfd_get_linker_section (dynobj, ".dynbss");
- if (!info->shared)
- htab->srelbss = bfd_get_linker_section (dynobj, ".rela.bss");
-
- if (!htab->sdynbss
- || (!info->shared && !htab->srelbss))
+ if (!htab->sdynbss)
abort ();
+ if (info->executable)
+ {
+ /* Always allow copy relocs for building executables. */
+ asection *s;
+ s = bfd_get_linker_section (dynobj, ".rela.bss");
+ if (s == NULL)
+ {
+ const struct elf_backend_data *bed = get_elf_backend_data (dynobj);
+ s = bfd_make_section_anyway_with_flags (dynobj,
+ ".rela.bss",
+ (bed->dynamic_sec_flags
+ | SEC_READONLY));
+ if (s == NULL
+ || ! bfd_set_section_alignment (dynobj, s,
+ bed->s->log_file_align))
+ return FALSE;
+ }
+ htab->srelbss = s;
+ }
+
if (!info->no_ld_generated_unwind_info
&& htab->plt_eh_frame == NULL
&& htab->elf.splt != NULL)
@@ -1939,7 +1955,8 @@ do_size:
storing information in the relocs_copied field of the hash
table entry. A similar situation occurs when creating
shared libraries and symbol visibility changes render the
- symbol local.
+ symbol local. We allow copy relocs for non-GOT pc-relative
+ relocation.
If on the other hand, we are creating an executable, we
may need to keep relocations for symbols satisfied by a
@@ -1949,6 +1966,7 @@ do_size:
&& (sec->flags & SEC_ALLOC) != 0
&& (! IS_X86_64_PCREL_TYPE (r_type)
|| (h != NULL
+ && !h->non_got_ref
&& (! SYMBOLIC_BIND (info, h)
|| h->root.type == bfd_link_hash_defweak
|| !h->def_regular))))
@@ -2369,7 +2387,7 @@ elf_x86_64_adjust_dynamic_symbol (struct bfd_link_info *info,
only references to the symbol are via the global offset table.
For such cases we need not do anything here; the relocations will
be handled correctly by relocate_section. */
- if (info->shared)
+ if (!info->executable)
return TRUE;
/* If there are no references to this symbol that do not use the
@@ -2384,7 +2402,7 @@ elf_x86_64_adjust_dynamic_symbol (struct bfd_link_info *info,
return TRUE;
}
- if (ELIMINATE_COPY_RELOCS)
+ if (ELIMINATE_COPY_RELOCS && !info->shared)
{
eh = (struct elf_x86_64_link_hash_entry *) h;
for (p = eh->dyn_relocs; p != NULL; p = p->next)
@@ -4035,10 +4053,11 @@ elf_x86_64_relocate_section (bfd *output_bfd,
defined locally or for a branch. */
fail = !h->def_regular && !branch;
}
- else
+ else if (!h->needs_copy)
{
- /* Symbol isn't referenced locally. We only allow
- branch to symbol with non-default visibility. */
+ /* Symbol doesn't need copy reloc and isn't referenced
+ locally. We only allow branch to symbol with
+ non-default visibility. */
fail = (!branch
|| ELF_ST_VISIBILITY (h->other) == STV_DEFAULT);
}
@@ -4092,7 +4111,12 @@ direct:
if ((input_section->flags & SEC_ALLOC) == 0)
break;
+ /* Don't copy a pc-relative relocation into the output file
+ if the symbol needs copy reloc. */
if ((info->shared
+ && !(h != NULL
+ && h->needs_copy
+ && IS_X86_64_PCREL_TYPE (r_type))
&& (h == NULL
|| ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
|| h->root.type != bfd_link_hash_undefweak)
diff --git a/ld/testsuite/ChangeLog b/ld/testsuite/ChangeLog
index de784f7..70201ad 100644
--- a/ld/testsuite/ChangeLog
+++ b/ld/testsuite/ChangeLog
@@ -1,3 +1,13 @@
+2014-12-02 H.J. Lu <hongjiu.lu@intel.com>
+
+ * ld-x86-64/copyreloc-lib.c: New file.
+ * ld-x86-64/copyreloc-main.c: Likewise.
+ * ld-x86-64/copyreloc-main.out: Likewise.
+ * ld-x86-64/copyreloc-main1.rd: Likewise.
+ * ld-x86-64/copyreloc-main2.rd: Likewise.
+
+ * ld-x86-64/x86-64.exp: Run copyreloc tests.
+
2014-12-02 Andrew Bennett <andrew.bennett@imgtec.com>
* ld-mips-elf/mips-elf.exp: Add undefined weak overflow
diff --git a/ld/testsuite/ld-x86-64/copyreloc-lib.c b/ld/testsuite/ld-x86-64/copyreloc-lib.c
new file mode 100644
index 0000000..cbbc5e2
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/copyreloc-lib.c
@@ -0,0 +1 @@
+int a_glob = 2;
diff --git a/ld/testsuite/ld-x86-64/copyreloc-main.c b/ld/testsuite/ld-x86-64/copyreloc-main.c
new file mode 100644
index 0000000..430eefb
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/copyreloc-main.c
@@ -0,0 +1,7 @@
+extern int a_glob;
+
+int
+main (void)
+{
+ return a_glob != 2;
+}
diff --git a/ld/testsuite/ld-x86-64/copyreloc-main.out b/ld/testsuite/ld-x86-64/copyreloc-main.out
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/copyreloc-main.out
diff --git a/ld/testsuite/ld-x86-64/copyreloc-main1.rd b/ld/testsuite/ld-x86-64/copyreloc-main1.rd
new file mode 100644
index 0000000..dcb52dc
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/copyreloc-main1.rd
@@ -0,0 +1,3 @@
+#...
+[0-9a-f ]+R_X86_64_COPY+[0-9a-f ]+ +a_glob \+ 0
+#...
diff --git a/ld/testsuite/ld-x86-64/copyreloc-main2.rd b/ld/testsuite/ld-x86-64/copyreloc-main2.rd
new file mode 100644
index 0000000..d78ea2f
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/copyreloc-main2.rd
@@ -0,0 +1,4 @@
+#failif
+#...
+[0-9a-f ]+R_X86_64_NONE.*
+#...
diff --git a/ld/testsuite/ld-x86-64/x86-64.exp b/ld/testsuite/ld-x86-64/x86-64.exp
index 886469b..91c9dd9 100644
--- a/ld/testsuite/ld-x86-64/x86-64.exp
+++ b/ld/testsuite/ld-x86-64/x86-64.exp
@@ -392,6 +392,30 @@ if { [isnative] && [which $CC] != 0 } {
{{readelf {-Wr} plt-main.rd}} \
"plt-main" \
] \
+ [list \
+ "Build copyreloc-lib.so" \
+ "-shared" \
+ "-fPIC" \
+ { copyreloc-lib.c } \
+ {} \
+ "copyreloc-lib.so" \
+ ] \
+ [list \
+ "Build copyreloc-main with PIE without -fPIE (1)" \
+ "tmpdir/copyreloc-lib.so -pie" \
+ "" \
+ { copyreloc-main.c } \
+ {{readelf {-Wr} copyreloc-main1.rd}} \
+ "copyreloc-main" \
+ ] \
+ [list \
+ "Build copyreloc-main with PIE without -fPIE (2)" \
+ "tmpdir/copyreloc-lib.so -pie" \
+ "" \
+ { copyreloc-main.c } \
+ {{readelf {-Wr} copyreloc-main2.rd}} \
+ "copyreloc-main" \
+ ] \
]
run_ld_link_exec_tests [] [list \
@@ -414,6 +438,14 @@ if { [isnative] && [which $CC] != 0 } {
"plt-main.out" \
"-fPIC" \
] \
+ [list \
+ "Run copyreloc-main with PIE without -fPIE" \
+ "tmpdir/copyreloc-lib.so -pie" \
+ "" \
+ { copyreloc-main.c } \
+ "copyreloc-main" \
+ "copyreloc-main.out" \
+ ] \
]
if { [istarget "x86_64-*-linux*"] \