Quuxplusone / LLVMBugzillaTest

0 stars 0 forks source link

MC-COFF: multiple levels of linkonce_odr aliases produce an unlinkable COFF object #17529

Open Quuxplusone opened 10 years ago

Quuxplusone commented 10 years ago
Bugzilla Link PR17530
Status NEW
Importance P normal
Reported by Reid Kleckner (rnk@google.com)
Reported on 2013-10-09 19:32:31 -0700
Last modified on 2018-03-19 16:56:52 -0700
Version trunk
Hardware PC Windows NT
CC artem.tamazov@amd.com, david.majnemer@gmail.com, llvm-bugs@lists.llvm.org, peter@pcc.me.uk, rafael@espindo.la, ruiu@google.com
Fixed by commit(s)
Attachments
Blocks
Blocked by
See also
$ cat t.ll
@my_alias = alias linkonce_odr void ()* @my_inline
@my_alias2 = alias linkonce_odr void ()* @my_alias
define linkonce_odr void @my_inline() {
  ret void
}
define i32 @main() {
  call void @my_alias2()
  ret i32 0
}

$ llc t.ll -o tll.obj -filetype=obj && link tll.obj -defaultlib:libcmt.lib -
out:t.exe -nologo
tll.obj : error LNK2001: unresolved external symbol _my_alias2
tll.obj : error LNK2001: unresolved external symbol _my_alias

$ dumpbin /symbols tll.obj
COFF SYMBOL TABLE
000 00000000 SECT1  notype       Static       | .text
    Section length    8, #relocs    1, #linenums    0, checksum        0
002 00000000 SECT2  notype       Static       | .text$my_inline
    Section length    1, #relocs    0, #linenums    0, checksum        0, selection    2 (pick any)
004 00000001 ABS    notype       Static       | @feat.00
005 00000000 SECT2  notype ()    External     | _my_inline
006 00000000 SECT1  notype ()    External     | _main
007 00000000 UNDEF  notype       WeakExternal | _my_alias2
    Default index        9 library search
009 00000000 UNDEF  notype       WeakExternal | _my_alias
    Default index        5 library search

The symbol at index 7 points to index 9 which points to index 5.

Rui says that these weak external aliases are more like fallbacks.  The symbol
is still undefined, and if nobody provides a definition, then it is resolved to
the "default index".  So, it looks like you can't do this twice.  You can't
fallback to a fallback symbol.

I'm filing this as an MC bug, since any IR could hit this, but I'll probably
try to patch clang to avoid this.
Quuxplusone commented 10 years ago

"If a definition of sym1 is linked, then an external reference to the symbol is resolved normally. If a definition of sym1 is not linked, then all references to the weak external for sym1 refer to sym2 instead. The external symbol, sym2, must always be linked; typically, it is defined in the module that contains the weak reference to sym1."

Yep, sounds like we are violating that last sentence.

Quuxplusone commented 10 years ago

Woops, I meant destroy arguments left to right. We push cleanups left to right, which means we pop them right to left, which is wrong. Blech.

Quuxplusone commented 10 years ago
Woops, I meant destroy arguments left to right.  We push cleanups left to
right, which means we pop them right to left, which is wrong.  Blech.(In reply
to comment #2)
> Woops, I meant destroy arguments left to right.  We push cleanups left to
> right, which means we pop them right to left, which is wrong.  Blech.

Arg, that should've been on PR18035 obviously.
Quuxplusone commented 10 years ago
On ELF we implement aliases by just having another symbol pointing to the same
position in the file.

This has its own set of issues:

* Linkonce{_odr} aliases to weak symbols are very dangerous as it can lead to
comdats with different contents in different TUs.
* Aliases passing by a weak alias cannot be implemented properly, as the linker
will not resolve them with the same semantics as llvm. For example, given

@my_alias = alias linkonce_odr void ()* @my_func
@my_alias2 = alias void ()* @my_alias
define void @my_func() {
  ret void
}

my_alias2 will always point to the my_func, even if we link with a file with a
strong symbol for my_alias.

I intended to just rejects this cases in the backend. Would the same
implementation and restrictions work for COFF?