[PATCH] D88625: MCExpr::evaluateAsRelocatableImpl : allow evaluation of non-VK_None MCSymbolRefExpr when MCAsmLayout is available

Fangrui Song via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Mon Nov 2 16:26:48 PST 2020


MaskRay added a comment.

Changed to patch MCExpr::evaluateAsRelocatableImpl instead

In D88625#2369263 <https://reviews.llvm.org/D88625#2369263>, @jyknight wrote:

> In D88625#2328351 <https://reviews.llvm.org/D88625#2328351>, @MaskRay wrote:
>
>> In D88625#2328335 <https://reviews.llvm.org/D88625#2328335>, @jyknight wrote:
>>
>>>> I have tried adding the expression folding stuff to`MCExpr::evaluateAsRelocatableImpl` but I abandoned that idea because evaluateAsRelocatableImpl does not like a modifier different from VK_None (@PLT). (What does a at plt + 1 do? Relaxing the condition (== VK_None) may work... but the semantics are not very clear.
>>>
>>> `a at plt + 1` is perfectly fine -- that turns into a R_X86_64_PLT32 relocation with symbol "a" and addend 1.
>>>
>>> The interesting question is what this should do:
>>>
>>>   b=a+1 # no @plt!
>>>   ... b at plt
>>>
>>> It's certainly impossible to create a PLT referring to a function at address "a+1", in current object formats. So, probably this should be invalid. However, GAS seems to consider the modifier as more of an overall-modifier, resulting in the same thing as `a at plt + 1`. I agree that's probably not something we ought to support, since it seems wrong.
>>>
>>> But, it does still seem reasonable to put the !VK_None support into evaluateAsRelocatableImpl -- as long as the resolved MCValue has only a single symbol, no offset and no kind.
>>
>> The current way the patch implements the "if a fixup symbol is equated to an expression with an undefined symbol" logic is consistent with the step GNU as implements the check.
>> GNU as implements the logic when it is about to emit a relocation, not when folding expressions.
>
> All of this is pretty confusing. We //do// need to expand variable references, including those to undefined symbols, during expression evaluation in certain contexts, such as `.if`. We have some code in there to do this now (conditioning expansion based on "InSet"), but e.g.
>
>   x = a - 1
>   .if x + 1 == a
>   nop
>   .endif
>
> doesn't work with llvm, today, while it does in gas.



> OTOH, for something like the following, we definitely need to preserve the reference to b, and NOT try to expand it to a+1 too early (because we need to not emit the PLT relocation to global symbol a). Binutils' as compiles this as a PC32 relocation off of .text.a, while we generate a PLT32 relocation off of b; both of those seem probably fine.
>
>   b = a+1
>   
>   .section .text.foo
>   foo:
>   jmp b at PLT
>   
>   
>   .section .text.a
>   .globl a
>   a:
>   nop
>   nop

`b` is local (a symbol assignment does not copy the binding), so GNU as emits a relocation referencing the section symbol.
This patch does not change the behavior.

>> One major problem by moving the condition to MCExpr::evaluateAsRelocatableImpl is that we may do `isUndefined()` check too early (this special case does not kick in when the symbol is defined (`memcpy = __GI_memcpy; call memcpy ... __GI_memcpy: ...` should emit a relocation referencing memcpy, instead of __GI_memcpy)).
>
> I think we can ensure that we only do it at the right point, by checking whether we have the optional Layout object passed in. evaluateFixup calls evaluateAsRelocatable with a Layout object, but other uses that occur pre-layout will not.

It seems that the parse-time MCExpr::evaluateAsRelocatableImpl only takes actions if the value is absolute (not `isInSection()`),,,,, so MCExpr::evaluateAsRelocatableImpl actually works.
The whole infrastructure does give me an impression that it can have subtle behaviors in a few places....


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D88625/new/

https://reviews.llvm.org/D88625



More information about the llvm-commits mailing list