[PATCH 3/6] bfd: refine handling of relocations between debugging sections

Jan Beulich jbeulich@suse.com
Tue Mar 2 09:48:30 GMT 2021

Preliminary remark: While relevant for Dwarf in particular, I would
assume other debug info formats have similar implications. If not, I've
no idea how to correctly deal with the Dwarf case.

Dwarf wants references between the various .debug_* sections to be
section relative. ELF, however, has section relative relocations on only
very few architectures. Hence normal 32-bit / 64-bit data relocations
get used (the ones with correspond to BFD_RELOC_{32,64}). For ELF output
this is not a problem by default as all these sections get placed at VA
zero. For PE output using VA 0 is not an option, as that would place the
section below the image base (see also "bfd: don't silently wrap or
truncate PE image section RVAs"). And even for ELF output this can be a
problem if these sections get assigned real VAs, e.g. when a program or
library wants to be able to access its own debug info.

For 32-bit relocations, relocation overflows would be reported if the
image base isn't small enough, while for 64-bit relocations bad output
(not a section relative value) would silently be generated.

Therefore the section VMA may not be used when determining the output
base for such relocations. Since this is a heuristic, quite a bit of
extra checking is being applied to make sure only the very few affected
relocation types get processed this way.

2021-02-XX  Jan Beulich  <jbeulich@suse.com>

	* reloc.c (bfd_perform_relocation): Force output base to zero
	for relocations between debugging sections.

--- a/bfd/reloc.c
+++ b/bfd/reloc.c
@@ -749,6 +749,30 @@ bfd_perform_relocation (bfd *abfd,
     output_base = reloc_target_output_section->vma;
+  /* Most architectures have no section relative ELF relocations.  They use
+     ordinary ones instead for representing section relative references between
+     debugging sections, which works fine as long as the section VMA gets set
+     to zero.  While this is the default for ELF output (albeit not a
+     requirement), in particular PE doesn't even allow zero VMAs for any of the
+     sections.  */
+  if(output_base && !howto->pc_relative
+     && bfd_get_flavour (abfd) == bfd_target_elf_flavour
+     && (reloc_target_output_section->flags
+	 & input_section->flags & SEC_DEBUGGING))
+    {
+      /* Since this is a heuristic, apply further checks in an attempt to
+	 exclude relocation types other than simple base ones.  */
+      unsigned int size = bfd_get_reloc_size (howto);
+      if (size && !(size & (size - 1))
+          && !(howto->bitsize & (howto->bitsize - 1))
+          && !howto->bitpos && !howto->rightshift
+          && !howto->negate && !howto->partial_inplace
+          && !(howto->src_mask & (howto->src_mask + 1))
+          && !(howto->dst_mask & (howto->dst_mask + 1)))
+	output_base = 0;
+    }
   output_base += symbol->section->output_offset;
   /* If symbol addresses are in octets, convert to bytes.  */

More information about the Binutils mailing list