<div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote">On Tue, Jan 17, 2017 at 7:24 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:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div class="gmail-HOEnZb"><div class="gmail-h5">Teresa Johnson via llvm-dev <<a href="mailto:llvm-dev@lists.llvm.org">llvm-dev@lists.llvm.org</a>> writes:<br>
<br>
> I was wondering though what happens if we have an alias, which may or may<br>
> not be weak itself, to a non-odr weak symbol that isn't prevailing. In that<br>
> case, do we eventually want references via the alias to go to the<br>
> prevailing copy (in another module), or to the original copy in the alias's<br>
> module? I looked at some examples without ThinLTO, and am a little<br>
> confused. Current (non-ThinLTO) behavior in some cases seems to depend on<br>
> opt level.<br>
><br>
> Example:<br>
><br>
> $ cat weak12main.c<br>
> extern void test2();<br>
> int main() {<br>
>   test2();<br>
> }<br>
><br>
> $ cat weak1.c<br>
> #include <stdio.h><br>
><br>
> void weakalias() __attribute__((weak, alias ("f")));<br>
> void strongalias() __attribute__((alias ("f")));<br>
><br>
> void f () __attribute__ ((weak));<br>
> void f()<br>
> {<br>
>   printf("In weak1.c:f\n");<br>
> }<br>
> void test1() {<br>
>   printf("Call f() from weak1.c:\n");<br>
>   f();<br>
>   printf("Call weakalias() from weak1.c:\n");<br>
>   weakalias();<br>
>   printf("Call strongalias() from weak1.c:\n");<br>
>   strongalias();<br>
> }<br>
><br>
> $ cat weak2.c<br>
> #include <stdio.h><br>
><br>
> void f () __attribute__ ((weak));<br>
> void f()<br>
> {<br>
>   printf("In weak2.c:f\n");<br>
> }<br>
> extern void test1();<br>
> void test2()<br>
> {<br>
>   test1();<br>
>   printf("Call f() from weak2.c\n");<br>
>   f();<br>
> }<br>
><br>
> If I link weak1.c before weak2.c, nothing is surprising (we always invoke<br>
> weak1.c:f at both -O0 and -O2):<br>
><br>
> $ clang weak12main.c weak1.c weak2.c -O0<br>
> $ a.out<br>
> Call f() from weak1.c:<br>
> In weak1.c:f<br>
> Call weakalias() from weak1.c:<br>
> In weak1.c:f<br>
> Call strongalias() from weak1.c:<br>
> In weak1.c:f<br>
> Call f() from weak2.c<br>
> In weak1.c:f<br>
><br>
> $ clang weak12main.c weak1.c weak2.c -O2<br>
> $ a.out<br>
> Call f() from weak1.c:<br>
> In weak1.c:f<br>
> Call weakalias() from weak1.c:<br>
> In weak1.c:f<br>
> Call strongalias() from weak1.c:<br>
> In weak1.c:f<br>
> Call f() from weak2.c<br>
> In weak1.c:f<br>
><br>
> If I instead link weak2.c first, so it's copy of f() is prevailing, I still<br>
> get weak1.c:f for the call via weakalias() (both opt levels), and for<br>
> strongalias() when building at -O0. At -O2 the compiler replaces the call<br>
> to strongalias() with a call to f(), so it get's the weak2 copy in that<br>
> case.<br>
><br>
> $ clang weak12main.c weak2.c weak1.c -O2<br>
> $ a.out<br>
> Call f() from weak1.c:<br>
> In weak2.c:f<br>
> Call weakalias() from weak1.c:<br>
> In weak1.c:f<br>
> Call strongalias() from weak1.c:<br>
> In weak2.c:f<br>
> Call f() from weak2.c<br>
> In weak2.c:f<br>
><br>
> $ clang weak12main.c weak2.c weak1.c -O0<br>
> $ a.out<br>
> Call f() from weak1.c:<br>
> In weak2.c:f<br>
> Call weakalias() from weak1.c:<br>
> In weak1.c:f<br>
> Call strongalias() from weak1.c:<br>
> In weak1.c:f<br>
> Call f() from weak2.c<br>
> In weak2.c:f<br>
><br>
> I'm wondering what the expected/correct behavior is? Depending on what is<br>
> correct, we need to handle this differently in ThinLTO mode. Let's say<br>
> weak1.c's copy of f() is not prevailing and I am going to drop it (it needs<br>
> to be removed completely, not turned into available_externally to ensure it<br>
> isn't inlined since weak isInterposable). If we want the aliases in weak1.c<br>
> to reference the original version, then copying is correct (e.g. weakalias<br>
> and strong alias would each become a copy of weak1.c's f()). If we however<br>
> want them to resolve to the prevailing copy of f(), then we need to turn<br>
> the aliases into declarations (external linkage in the case of strongalias<br>
> and external weak in the case of weakalias?).<br>
><br>
> I also tried the case where f() was in a comdat, because I also need to<br>
> handle that case in ThinLTO (when f() is not prevailing, drop it from the<br>
> comdat and remove the comdat from that module). Interestingly, in this case<br>
> when weak2.c is prevailing, I get the following warning when linking and<br>
> get a seg fault at runtime:<br>
><br>
> weak1.o:weak1.o:function test1: warning: relocation refers to discarded<br>
> section<br>
><br>
> Presumably the aliases still refer to the copy in weak1.c, which is in the<br>
> comdat that gets dropped by the linker. So is it not legal to have an alias<br>
> to a weak symbol in a comdat (i.e. alias from outside the comdat)? We don't<br>
> complain in the compiler.<br>
<br>
</div></div>The rule should be that the alias to aliasee link is never broken. The<br>
reason being that an alias at the file level is just another symbol with<br>
the same value.<br>
<br>
So if foo is an alias to bar, accessing that foo will always be the same<br>
as accessing that bar, regardless of either of them being weak. I say<br>
*that* foo and *that* bar because symbol resolution may pick another foo<br>
and another bar.<br></blockquote><div><br></div><div>Are you just talking about the comdat case? If this also applies to the non-comdat case, I'm not sure how this works in the following situation (copied from an example in my response just now to pcc):</div><div><br></div><div>If a module contains the following, and both @x and @y are non-prevailing in that module:</div><div><br></div><div><div>@x = weak global ...<br></div><div>@y = weak alias @x</div><div><br></div><div>and the prevailing def for @x is in moduleX with a different value than the prevailing def for @y which comes from moduleY. Just because they are aliased in this module doesn't mean they must be aliased elsewhere, right? For this case (weak non-prevailing alias to a weak non-prevailing def) I think it should eventually become:</div></div><div><br></div><div><div>@x = external global</div><div>@y = external global</div></div><div><br></div><div>Trying to understand how this fits with your comment that "The rule should be that the alias to aliasee link is never broken", unless that is just referring to the case I mentioned just above about when they are both in comdats.</div><div><br></div><div>Thanks,</div><div>Teresa</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
<br>
Cheers,<br>
Rafael<br>
</blockquote></div><br><br clear="all"><div><br></div>-- <br><div class="gmail_signature"><span style="font-family:times;font-size:medium"><table cellspacing="0" cellpadding="0"><tbody><tr style="color:rgb(85,85,85);font-family:sans-serif;font-size:small"><td nowrap style="border-top:2px solid rgb(213,15,37)">Teresa Johnson |</td><td nowrap style="border-top:2px solid rgb(51,105,232)"> Software Engineer |</td><td nowrap style="border-top:2px solid rgb(0,153,57)"> <a href="mailto:tejohnson@google.com" target="_blank">tejohnson@google.com</a> |</td><td nowrap style="border-top:2px solid rgb(238,178,17)"> 408-460-2413</td></tr></tbody></table></span></div>
</div></div>