aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ld/ChangeLog8
-rw-r--r--ld/ldexp.c22
-rw-r--r--ld/ldexp.h1
-rw-r--r--ld/pe-dll.c12
-rw-r--r--ld/testsuite/ld-pe/pe.exp2
-rw-r--r--ld/testsuite/ld-pe/reloc.d14
-rw-r--r--ld/testsuite/ld-pe/reloc.s13
7 files changed, 69 insertions, 3 deletions
diff --git a/ld/ChangeLog b/ld/ChangeLog
index 0f1da7f..95bb3f6 100644
--- a/ld/ChangeLog
+++ b/ld/ChangeLog
@@ -1,3 +1,11 @@
+2021-03-04 Jan Beulich <jbeulich@suse.com>
+
+ * ldexp.c (ldexp_is_final_sym_absolute): New.
+ * ldexp.h (ldexp_is_final_sym_absolute): Declare.
+ * pe-dll.c (generate_reloc): Skip absolute symbols.
+ * testsuite/ld-pe/reloc.s, testsuite/ld-pe/reloc.d: New.
+ * testsuite/ld-pe/pe.exp: Run new test.
+
2021-03-03 Alan Modra <amodra@gmail.com>
PR 27500
diff --git a/ld/ldexp.c b/ld/ldexp.c
index 0167845..7a95e56 100644
--- a/ld/ldexp.c
+++ b/ld/ldexp.c
@@ -1699,6 +1699,28 @@ ldexp_finalize_syms (void)
bfd_hash_traverse (&definedness_table, set_sym_sections, NULL);
}
+/* Determine whether a symbol is going to remain absolute even after
+ ldexp_finalize_syms() has run. */
+
+bfd_boolean
+ldexp_is_final_sym_absolute (const struct bfd_link_hash_entry *h)
+{
+ if (h->type == bfd_link_hash_defined
+ && h->u.def.section == bfd_abs_section_ptr)
+ {
+ const struct definedness_hash_entry *def;
+
+ if (!h->ldscript_def)
+ return TRUE;
+
+ def = symbol_defined (h->root.string);
+ if (def != NULL)
+ return def->final_sec == bfd_abs_section_ptr;
+ }
+
+ return FALSE;
+}
+
void
ldexp_finish (void)
{
diff --git a/ld/ldexp.h b/ld/ldexp.h
index d609617..1055053 100644
--- a/ld/ldexp.h
+++ b/ld/ldexp.h
@@ -239,6 +239,7 @@ bfd_vma exp_get_abs_int
(etree_type *, int, char *);
void ldexp_init (void);
void ldexp_finalize_syms (void);
+bfd_boolean ldexp_is_final_sym_absolute (const struct bfd_link_hash_entry *);
void ldexp_finish (void);
#endif
diff --git a/ld/pe-dll.c b/ld/pe-dll.c
index 3c82f8d..afcf6fe 100644
--- a/ld/pe-dll.c
+++ b/ld/pe-dll.c
@@ -1579,13 +1579,13 @@ generate_reloc (bfd *abfd, struct bfd_link_info *info)
&& relocs[i]->howto->type != pe_details->imagebase_reloc)
{
struct bfd_symbol *sym = *relocs[i]->sym_ptr_ptr;
+ const struct bfd_link_hash_entry *blhe
+ = bfd_wrapped_link_hash_lookup (abfd, info, sym->name,
+ FALSE, FALSE, FALSE);
/* Don't create relocs for undefined weak symbols. */
if (sym->flags == BSF_WEAK)
{
- struct bfd_link_hash_entry *blhe
- = bfd_wrapped_link_hash_lookup (abfd, info, sym->name,
- FALSE, FALSE, FALSE);
if (blhe && blhe->type == bfd_link_hash_undefweak)
{
/* Check aux sym and see if it is defined or not. */
@@ -1617,6 +1617,12 @@ generate_reloc (bfd *abfd, struct bfd_link_info *info)
if (!strcmp (s->name, ".eh_frame"))
continue;
}
+ /* Nor for absolute symbols. */
+ else if (blhe && ldexp_is_final_sym_absolute (blhe)
+ && (!blhe->linker_def
+ || (strcmp (sym->name, "__image_base__")
+ && strcmp (sym->name, U ("__ImageBase")))))
+ continue;
reloc_data[total_relocs].vma = sec_vma + relocs[i]->address;
reloc_data[total_relocs].idx = total_relocs;
diff --git a/ld/testsuite/ld-pe/pe.exp b/ld/testsuite/ld-pe/pe.exp
index de9e104..b1a2001 100644
--- a/ld/testsuite/ld-pe/pe.exp
+++ b/ld/testsuite/ld-pe/pe.exp
@@ -76,6 +76,8 @@ run_dump_test "longsecn-5"
run_dump_test "orphan"
run_dump_test "orphan_nu"
+run_dump_test "reloc"
+
run_dump_test "weakdef-1"
run_dump_test "pr19803"
diff --git a/ld/testsuite/ld-pe/reloc.d b/ld/testsuite/ld-pe/reloc.d
new file mode 100644
index 0000000..55888c3
--- /dev/null
+++ b/ld/testsuite/ld-pe/reloc.d
@@ -0,0 +1,14 @@
+#name: PE base relocations
+#ld: --enable-reloc-section
+#objdump: -p
+
+.*: file format .*
+
+#...
+PE File Base Relocations.*
+Virtual Address: .* Number of fixups 4
+[ ]*reloc 0 offset 0 .* (LOW|HIGHLOW|DIR64)
+[ ]*reloc 1 offset [248] .* (LOW|HIGHLOW|DIR64)
+[ ]*reloc 2 offset [124]0 .* (LOW|HIGHLOW|DIR64)
+[ ]*reloc 3 offset 0 .* ABSOLUTE
+#pass
diff --git a/ld/testsuite/ld-pe/reloc.s b/ld/testsuite/ld-pe/reloc.s
new file mode 100644
index 0000000..3ed2e02
--- /dev/null
+++ b/ld/testsuite/ld-pe/reloc.s
@@ -0,0 +1,13 @@
+ .data
+ .p2align 4
+start:
+ .dc.a __image_base__
+ .dc.a start
+ .dc.a __section_alignment__
+ .dc.a __file_alignment__
+ .dc.a __major_os_version__
+ .dc.a __minor_os_version__
+ .dc.a __major_subsystem_version__
+ .dc.a __minor_subsystem_version__
+ .dc.a end
+end: