[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.
bfd/
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,
else
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