<div dir="ltr">No, I don't think this is related to PR34301. Why do you think so? This is not also related to whether a symbol is a local or not.<div><br></div><div>The problem this patch is dealing with is that a direct reference to a weak symbol is not representable if the symbol is resolved to a shared symbol. Since it is not representable, there are only two choices: create an executable that doesn't work correctly, or try not to resolve it to a shared symbol. What we are currently doing is the former. This patch changes it to the latter.</div></div><div class="gmail_extra"><br><div class="gmail_quote">On Tue, Nov 28, 2017 at 5:06 PM, Rafael Avila de Espindola <span dir="ltr"><<a href="mailto:rafael.espindola@gmail.com" target="_blank">rafael.espindola@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">This is an explicit regression of PR34301, no? If so I don't think we<br>
should do it.<br>
<br>
The complication you describe comes from the compiler assuming that a<br>
symbol is local and leaving the linker to do magic if it turns out it is<br>
not.<br>
<br>
The only way I see out of this is changing the compiler to not make such<br>
assumptions and have the linker optimize the converse: improve access<br>
when the symbol is local.<br>
<br>
The optimization of access to local symbols already exists.<br>
<br>
In llvm we now have a dso_local flag in the IR. All that is missing is<br>
<br>
* Having clang set it in the cases shouldAssumeDSOLocal currently<br>
  guesses the symbol is local.<br>
<br>
* Change shouldAssumeDSOLocal to just return dso_local<br>
<br>
* Add an option to clang (-fno-assume-local-<wbr>declarations?) to have it<br>
  not guess that declarations are local even without -fPIC.<br>
<br>
* Make that option the default.<br>
<br>
Cheers,<br>
Rafael<br>
<div class="HOEnZb"><div class="h5"><br>
<br>
Rui Ueyama <<a href="mailto:ruiu@google.com">ruiu@google.com</a>> writes:<br>
<br>
> This patch changes the existing broken semantics of the linker with a new,<br>
> simplified one. So, I'll copy the comment that I added in this patch here<br>
> for those who are interested in linker's weak undefined symbol semantics<br>
> when dynamic linking involved.<br>
><br>
> ======<br>
><br>
> Exported weak symbols are not representable unless they are resolved<br>
> through GOT. We simply export weak symbols only when -shared or -pie<br>
> were given.<br>
><br>
> As a result, if an weak symbol cannot be resolved within the current<br>
> output file, and if no -shared nor -pie were given, the symbol is<br>
> resolved to zero at link-time. If you want to give it a second chance<br>
> to be resolved at load-time, you need to pass -shared or -pie.<br>
><br>
> So, why are they not representable? To understand that, assume the<br>
> following code:<br>
><br>
>   __attribute__((weak)) int foo();<br>
>   void bar() { if (foo) foo(); }<br>
><br>
> If this code is compiled without -fPIC, function pointer foo in the<br>
> "if" is compiled to a direct reference to a function. The linker would<br>
> create a PLT entry for foo and use its address as a function pointer<br>
> value for foo. It would usually work, because when you jump to foo's<br>
> PLT, it in turn jumps to foo's real function definition.<br>
><br>
> However, that mechanism can result in a bad combination of pointer<br>
> values if the symbol is weak. Symbol foo's function pointer value is<br>
> always non-zero because it is resolved to a linker-synthesized foo's<br>
> PLT entry (that means the "if" condition is always true). But, if the<br>
> loader cannot resolve foo at load-time, it leaves foo's PLT entry zero.<br>
> That means when you jump there, it then jumps to an unexpected<br>
> address, and the program crashes. As a result, if foo cannot be<br>
> resolved at load-time, the program crashes. This is apparently what<br>
> users would not expect.<br>
><br>
> If all references to symbol foo go through GOT, weak symbols are<br>
> representable. If the loader cannot resolve foo, it leaves foo's GOT<br>
> entry zero, and the "if" condition simply becomes false.<br>
><br>
> So, we want to export weak symbols only when we know they are<br>
> referenced through GOT.<br>
><br>
> (The decision we are making here is not perfect; even if -shared or<br>
> -pie are given to the linker, input object files may have direct<br>
> references to weak symbols. We'll report them as errors in<br>
> scanRelocations. Likewise, even if -shared nor -pie were not given,<br>
> all relocations to weak symbols could go through GOT. Even so, we<br>
> won't export them, because it is hard to detect it ahead of time. It<br>
> is also generally preferable to let users explicitly control the<br>
> linker's behavior via command line options rather than changing<br>
> the behavior implicitly depending on existence or absense of some<br>
> relocations.)<br>
><br>
> On Sat, Nov 4, 2017 at 5:31 PM, Rui Ueyama <<a href="mailto:ruiu@google.com">ruiu@google.com</a>> wrote:<br>
><br>
>> This is the first step to simplify and improve relocation handling in lld.<br>
>> I'd like to submit it so that I can make further changes. Can you take a<br>
>> look?<br>
>><br>
>> On Sat, Nov 4, 2017 at 5:27 PM, Rui Ueyama via Phabricator <<br>
>> <a href="mailto:reviews@reviews.llvm.org">reviews@reviews.llvm.org</a>> wrote:<br>
>><br>
>>> ruiu updated this revision to Diff 121606.<br>
>>> ruiu added a comment.<br>
>>> Herald added a subscriber: arichardson.<br>
>>><br>
>>> - Rebased<br>
>>><br>
>>><br>
>>> <a href="https://reviews.llvm.org/D39392" rel="noreferrer" target="_blank">https://reviews.llvm.org/<wbr>D39392</a><br>
>>><br>
>>> Files:<br>
>>>   lld/ELF/Relocations.cpp<br>
>>>   lld/ELF/Symbols.cpp<br>
>>>   lld/test/ELF/weak-undef-<wbr>export.s<br>
>>>   lld/test/ELF/weak-undef-pic-<wbr>nopic.s<br>
>>><br>
>>><br>
>><br>
</div></div></blockquote></div><br></div>