aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJan Beulich <jbeulich@suse.com>2021-04-06 10:54:57 +0200
committerJan Beulich <jbeulich@suse.com>2021-04-06 10:54:57 +0200
commitbd3d1480a80effbbf3eedf1bd51368730ec9078d (patch)
tree3e8e96c1c85af04173449ac81abf74b245a6e004
parentd811a7cf74fa8523f67a13c0527b27f4954e9ae1 (diff)
downloadgdb-bd3d1480a80effbbf3eedf1bd51368730ec9078d.zip
gdb-bd3d1480a80effbbf3eedf1bd51368730ec9078d.tar.gz
gdb-bd3d1480a80effbbf3eedf1bd51368730ec9078d.tar.bz2
ld: warn about PE base relocations to sections above .reloc
Due to a bogus linker script, or perhaps because a section doesn't get placed by a linker script while default placement puts it too high up, sections can end up above .reloc. Since the process of determining its contents (and hence its size) happens before final section placement, relocations needed for such sections would no longer point at the correct address in the final binary. Warn about this (down the road this may want to become an error, unless size determination and content creation for .reloc would get decoupled). To avoid triggering the warning when .reloc gets discarded, suppress populating the section in the first place in this case.
-rw-r--r--ld/ChangeLog5
-rw-r--r--ld/pe-dll.c11
2 files changed, 15 insertions, 1 deletions
diff --git a/ld/ChangeLog b/ld/ChangeLog
index d12ba77..71aa06a 100644
--- a/ld/ChangeLog
+++ b/ld/ChangeLog
@@ -1,3 +1,8 @@
+2021-04-06 Jan Beulich <jbeulich@suse.com>
+
+ * pe-dll.c (generate_reloc): Bail immediately when .reloc is
+ being discarded. Warn when relocated entry is above .reloc.
+
2021-04-05 Alan Modra <amodra@gmail.com>
* configure.ac: Move initfini-array arg handling earlier. Don't
diff --git a/ld/pe-dll.c b/ld/pe-dll.c
index cdb343b..e7b82ba 100644
--- a/ld/pe-dll.c
+++ b/ld/pe-dll.c
@@ -1516,7 +1516,7 @@ generate_reloc (bfd *abfd, struct bfd_link_info *info)
bfd *b;
struct bfd_section *s;
- if (reloc_s == NULL)
+ if (reloc_s == NULL || reloc_s->output_section == bfd_abs_section_ptr)
return;
total_relocs = 0;
for (b = info->input_bfds; b; b = b->link.next)
@@ -1627,6 +1627,15 @@ generate_reloc (bfd *abfd, struct bfd_link_info *info)
reloc_data[total_relocs].vma = sec_vma + relocs[i]->address;
reloc_data[total_relocs].idx = total_relocs;
+ /* Since we're only about to determine .reloc's size,
+ subsequent output section VMA calculations will shift up
+ sections at this or higher addresses. Relocations for
+ such sections would hence end up not being correct. */
+ if (reloc_data[total_relocs].vma
+ >= reloc_s->output_section->vma)
+ einfo (_("%P: base relocation for section `%s' above "
+ ".reloc section\n"), s->output_section->name);
+
#define BITS_AND_SHIFT(bits, shift) (bits * 1000 | shift)
switch BITS_AND_SHIFT (relocs[i]->howto->bitsize,