This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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






Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]