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: GOLD handling of weak symbols (including x86 vs. ARM)


Cary Coutant <ccoutant@google.com> writes:
>> ===================================================================
>> --- gold/i386.cc ? ? ? ?2010-11-09 08:21:13.000000000 +0000
>> +++ gold/i386.cc ? ? ? ?2010-11-09 08:21:23.000000000 +0000
>> -// Return whether we need to make a PLT entry for a relocation of a
>> -// given type against a STT_GNU_IFUNC symbol.
>> +// Get the Reference_flags for a particular relocation.
>>
>> -bool
>> -Target_i386::Scan::reloc_needs_plt_for_ifunc(Sized_relobj<32, false>* object,
>> - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?unsigned int r_type)
>> +int
>> +Target_i386::Scan::get_reference_flags(unsigned int r_type)
>> ?{
>> ? switch (r_type)
>> ? ? {
>> ? ? case elfcpp::R_386_NONE:
>> ? ? case elfcpp::R_386_GNU_VTINHERIT:
>> ? ? case elfcpp::R_386_GNU_VTENTRY:
>> - ? ? ?return false;
>> + ? ?case elfcpp::R_386_GOTPC:
>> + ? ? ?// No symbol reference.
>> + ? ? ?return 0;
>
>> +// Return whether we need to make a PLT entry for a relocation of a
>> +// given type against a STT_GNU_IFUNC symbol.
>> +
>> +bool
>> +Target_i386::Scan::reloc_needs_plt_for_ifunc(Sized_relobj<32, false>* object,
>> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?unsigned int r_type)
>> +{
>> + ?int flags = get_reference_flags(r_type);
>> + ?if (flags & Symbol::TLS_REF)
>> + ? ?gold_error(_("%s: unsupported TLS reloc %u for IFUNC symbol"),
>> + ? ? ? ? ? ? ? object->name().c_str(), r_type);
>> + ?return flags != 0;
>> +}
>
> It looks like reloc_needs_plt_for_ifunc will now return a different
> answer for R_386_GOTPC than it did before. Was that a bug before?

Not a bug exactly, because you should never see a R_386_GOTPC against
an IFUNC symbol in the first place.  I think the only way to convince
the assembler to emit such a reloc is to use .reloc explicitly, such
as with:

	.reloc	.+1,R_386_GOTPC,foo
	.byte	5,0,0,0,0

But even if you did that, it would be wasted effort, because the
addl still wouldn't reference foo at all.  Although it's customary
to emit the reloc against _GLOBAL_OFFSET_TABLE_, the value of the
relocation is the same regardless of which symbol you use.

But yeah, it was a deliberate change, because it seemed strange
to treat this reloc differently from R_386_NONE, even though both
relocations treat the symbol in essentially the same way.  So it
was an attempt to improve consistency rather than a bug fix.

I should have remembered to mention it in the original post, sorry.
As you probably saw, I made the same change for R_X86_64_GOTPC32 and
R_X86_64_GOTPC64 on the x86_64 port, for the same reasons.

> This function could probably use a comment explaining why (flags != 0)
> is the right answer.

My understanding was that a PLT is needed whenever a value for the
IFUNC symbol is needed.  Would a comment like:

  // The flags are nonzero iff the symbol's value is needed in the
  // relocation calculation.

be OK?  (In case this sounds like it's relying on undocumented
behaviour, I had added a comment about 0 above the defintion of
Reference_flags.  I agree it's good to mention it here though.)

If the comment is OK, I'll made the same change to the other ports.

Richard


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