[v3] ld: warn about PE base relocations to sections above .reloc

Message ID 2d20b96a-5360-f65a-3649-a51325d0925d@suse.com
State New
Headers show
Series
  • [v3] ld: warn about PE base relocations to sections above .reloc
Related show

Commit Message

H.J. Lu via Binutils March 30, 2021, 1:50 p.m.
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/
2021-03-XX  Jan Beulich  <jbeulich@suse.com>

	* pe-dll.c (generate_reloc): Bail immediately when .reloc is
	being discarded. Warn when relocated entry is above .reloc.
---
v3: Bail early from generate_reloc() when .reloc is being discarded.
    Drop testsuite adjustments.
v2: Wrap string literal in _().

Comments

H.J. Lu via Binutils April 4, 2021, 9:11 a.m. | #1
On Tue, Mar 30, 2021 at 03:50:26PM +0200, Jan Beulich wrote:
> 	* pe-dll.c (generate_reloc): Bail immediately when .reloc is

> 	being discarded. Warn when relocated entry is above .reloc.


OK.

-- 
Alan Modra
Australia Development Lab, IBM

Patch

--- a/ld/pe-dll.c
+++ b/ld/pe-dll.c
@@ -1516,7 +1516,7 @@  generate_reloc (bfd *abfd, struct bfd_li
   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_li
 		  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,