[PATCH]: Allow relative calculations for non-R_*_RELATIVE relocs.
Ian Lance Taylor
iant@google.com
Fri Feb 12 23:01:00 GMT 2010
David Miller <davem@davemloft.net> writes:
> 2010-02-12 David S. Miller <davem@davemloft.net>
>
> * output.h (Output_reloc<SHT_REL>::Output_reloc): Add
> is_symbolless parameter.
> (Output_reloc<SHT_REL>::is_symbolless): New.
> (Output_reloc<SHT_REL>::is_symbolless_): New.
> (Output_reloc<SHT_RELA>::Output_reloc): Add is_symbolless parameter.
> (Output_reloc<SHT_RELA>::is_symbolless): New.
> (Output_data_reloc::add_global): Handle is_symbolless.
> (Output_data_reloc::add_global_relative): Likewise.
> (Output_data_reloc::add_local): Likewise.
> (Output_data_reloc::add_local_relative): Likewise.
> (Output_data_reloc::add_symbolless_global_addend): New.
> (Output_data_reloc::add_symbolless_local_addend): New.
> * output.cc (Output_reloc<SHT_REL>::Output_reloc): Handle
> is_symbolless.
> (Output_reloc::set_needs_dynsym_index): Test ->is_symbolless_
> instead of ->is_relative_
> (Output_reloc::write_rel): Likewise.
> (Output_reloc::write): Likewise.
> (Output_reloc::compare): Do not attempt to sort by symbol index when
> ->is_symbolless is true.
>
> * sparc.cc (Target_sparc::Scan::local): Use
> ->add_symbolless_local_addend as needed.
> (Target_sparc::Scan::global): Use ->add_symbolless_global_addend as
> needed. Also, emit appropriate unaligned vs. aligned dynamic reloc
> based upon relocation offset.
> @@ -1053,7 +1066,8 @@ Output_reloc<elfcpp::SHT_REL, dynamic, size, big_endian>::
> }
> else if (r2.is_relative_)
> return 1;
> - else
> + else if (!this->is_symbolless_
> + && !r2.is_symbolless_)
> {
> unsigned int sym1 = this->get_symbol_index();
> unsigned int sym2 = r2.get_symbol_index();
I think we should sort symbolless relocs after relative relocs but
before other relocs. That is, instead of doing this, do
else
{
unsigned int sym1 = this->is_symbolless_ ? 0 : this->get_symbol_index();
unsigned int sym2 = r2.is_symbolless_ ? 0 : r2.get_symbol_index();
Or it might be simpler to just change get_symbol_index() to check
is_symbolless_, and then simplify write_rel(). Either way is fine
with me.
> + // Return whether this is a relocation which should not use
> + // a symbol, but which obtains it's addend from a symbol.
> + bool
> + is_symbolless() const
> + { return this->is_symbolless_; }
s/it's/its/
> @@ -1155,6 +1162,9 @@ class Output_reloc<elfcpp::SHT_REL, dynamic, size, big_endian>
> unsigned int type_ : 30;
> // True if the relocation is a RELATIVE relocation.
> bool is_relative_ : 1;
> + // True if the relocation is one which should not use
> + // a symbol, but which obtains it's addend from a symbol.
> + bool is_symbolless_ : 1;
> // True if the relocation is against a section symbol.
> bool is_section_symbol_ : 1;
> // If the reloc address is an input section in an object, the
s/it's/its/
Also this is going to make the struct one word larger. Please change
type_ to be a 29-bit bitfield. That should be fine in practice, and
the code already double-checks that the r_type value fits in the
field.
> + // Return whether this is a relocation which should not use
> + // a symbol, but which obtains it's addend from a symbol.
> + bool
> + is_symbolless() const
> + { return this->rel_.is_symbolless(); }
s/it's/its/
> + // Add a global relocation which does not use a symbol for the relocation,
> + // but which gets it's addend from a symbol.
s/it's/its/
This is OK with those changes.
Thanks.
Ian
More information about the Binutils
mailing list