ld: warn about PE base relocations to sections above .reloc
authorJan Beulich <jbeulich@suse.com>
Tue, 6 Apr 2021 08:54:57 +0000 (10:54 +0200)
committerJan Beulich <jbeulich@suse.com>
Tue, 6 Apr 2021 08:54:57 +0000 (10:54 +0200)
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.

ld/ChangeLog
ld/pe-dll.c

index d12ba7732c3ebd59c41f8d1fe1333b4ef32e52b8..71aa06ab45acdd9053ec07e9ea1420f4ddf39605 100644 (file)
@@ -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
index cdb343bb98b50cae623466e30609da6e5d25ef35..e7b82ba6ffadf74dc1b9ee71dc13d48336941e51 100644 (file)
@@ -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,