This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
Re: [PATCH v3 0/2] Fix several mix up between octets and bytes in ELF program headers
> > How about r_addend
>
> Usually in *bytes*, but for sections like .debug_str, *octets* are required.
> So it depends on whether SEC_ELF_OCTETS is set for the section of the
> symbol.
In order to generate a relocation in GAS, at first a fixup is created:
gas_cgen_finish_insn()
+--gas_cgen_record_fixup_exp()
+--fix_new_exp()
+--fix_new_internal() <-- allocation of fixS object
In case the relocation is PC relative, MD_PCREL_FROM_SECTION(fix, section) is called later:
write_object_file()
+--bfd_map_over_sections (..., fix_segment, ...);
+--fix_segment()
+--fixup_segment()
+--md_pcrel_from_section()
...
return (fixP->fx_where + fixP->fx_frag->fr_address) >> OCTETS_PER_BYTE_POWER
While fixP->fx_where is in octets, the result has to be converted to bytes. It
is used within fixup_segment for calculations with other byte values:
...
add_number = fixP->fx_offset;
...
add_number += S_GET_VALUE (fixP->fx_addsy);
fixP->fx_offset = add_number;
if (fixP->fx_pcrel)
add_number -= MD_PCREL_FROM_SECTION (fixP, this_segment);
...
All fix ups, which could not be fixed up, are converted to relocations in
gas_cgen_tc_gen_reloc(). Here fixS::fx_offset/fx_addnumber is copied to
arelent::addend:
write_object_file()
+--bfd_map_over_sections()
+--write_relocs()
+--tc_gen_reloc()
+--gas_cgen_tc_gen_reloc()
...
reloc->addend = fixP->fx_addnumber;
...
All users of arelent::addend clearly deal with bytes, not octets.
Conversion between arelent::addend and elf_internal_rela::r_addend happens in
elf_slurp_reloc_table_from_section() and elf_write_relocs().
elf_internal_rela::r_addend has the following users:
- _bfd_elf_rela_local_sym():
+ rel->r_addend = _bfd_merged_section_offset(.., sym->st_value + rel->r_addend)
* Have a look at st_value later
* _bfd_merged_section_offset() deals with octets, not bytes
+ Two additional conversion required.
- bfd_elf_perform_complex_relocation()
+ decode_complex_addend(..., rel->r_addend)
* r_addend has special meaning for complex relocations and must not be
altered in this case
- elf_swap_reloc(a)_in/out(): No change
- elf_write_relocs(): Change: Convert arelent::address to octets (depending on SEC_ELF_OCTETS)
- elf_gc_smash_unused_vtentry_relocs(): No change
- elf_link_input_bfd: Four additional conversion required
- elf_reloc_link_order(): Copy from bfd_link_order_reloc::addend. That should be kept in bytes.
- elf_slurp_reloc_table_from_section(): Convert from octets to bytes (depending on SEC_ELF_OCTETS)
All other users are in readelf, which expects octets in all cases.
Conclusion: "Changing" Elf_Internal_Rela::r_addend to octets looks
straightforward as for r_offset.
At next, I will have a look for st_value and debug info.
Regards
Christian