This is an archive of the discontinued LLVM Phabricator instance.

LTO: Pass SF_Executable flag through to InputFile::Symbol
ClosedPublic

Authored by tobiasvk on Apr 10 2017, 11:53 AM.

Details

Summary

The linker needs to be able to determine whether a symbol is text or data to
handle the case of a common being overridden by a strong definition in an
archive. If the archive contains a text member of the same name as the common,
that function is discarded. However, if the archive contains a data member of
the same name, that strong definition overrides the common. This is a behavior
of ld.bfd, which the Qualcomm linker also supports in LTO.

Here's a test case to illustrate:

cat > 1.c << \!
int blah;
!

cat > 2.c << \!
int blah() {

return 0;

}
!

cat > 3.c << \!
int blah = 20;
!

clang -c 1.c
clang -c 2.c
clang -c 3.c

ar cr lib.a 2.o 3.o
ld 1.o lib.a -t

The correct output is:

1.o
(lib.a)3.o

Thanks to Shankar Easwaran and Hemant Kulkarni for the test case!

Diff Detail

Repository
rL LLVM

Event Timeline

tobiasvk created this revision.Apr 10 2017, 11:53 AM
davide requested changes to this revision.Apr 10 2017, 4:04 PM
davide added a subscriber: davide.

This needs a testcase.

This revision now requires changes to proceed.Apr 10 2017, 4:04 PM
pcc edited edge metadata.Apr 10 2017, 4:39 PM

This ld.bfd behaviour [0,1] is very strange. It appears to be loading archive members to resolve common symbols, but will only do so if the archive member's definition is neither a common symbol itself (which is reasonable enough I suppose) nor of function type (which doesn't really seem necessary to check). I have no strong objections to extending the API to allow clients to implement compatible behaviour, but I don't think we should implement it in lld for example.

Agreed with @davide that this needs a test case. I am working on a change to llvm-lto2 that adds a feature for dumping the LTO symbol table, which should allow you to test this. @tobiasvk would you be fine with waiting until that change lands?

[0] https://github.com/bminor/binutils-gdb/blob/8170f7693bc0a9442c0aa280197925db92d48ca6/bfd/elflink.c#L5372
[1] https://github.com/bminor/binutils-gdb/blob/8170f7693bc0a9442c0aa280197925db92d48ca6/bfd/elflink.c#L3124

lib/Object/IRSymtab.cpp
129 ↗(On Diff #94711)

clang-format

tobiasvk marked an inline comment as done.Apr 11 2017, 8:58 AM
In D31901#723155, @pcc wrote:

Agreed with @davide that this needs a test case. I am working on a change to llvm-lto2 that adds a feature for dumping the LTO symbol table, which should allow you to test this. @tobiasvk would you be fine with waiting until that change lands?

Yes, absolutely agree we need a test case. It's just currently not possible to test it inside llvm without the linker, so I couldn't add one. It would be great if you could add a symbol table dump feature to llvm-lto2. Please add me to the review when you get to it, so we can merge this once your patch has landed.

Thanks!

pcc added a comment.Apr 11 2017, 10:03 AM
In D31901#723155, @pcc wrote:

Agreed with @davide that this needs a test case. I am working on a change to llvm-lto2 that adds a feature for dumping the LTO symbol table, which should allow you to test this. @tobiasvk would you be fine with waiting until that change lands?

Yes, absolutely agree we need a test case. It's just currently not possible to test it inside llvm without the linker, so I couldn't add one. It would be great if you could add a symbol table dump feature to llvm-lto2. Please add me to the review when you get to it, so we can merge this once your patch has landed.

This is D31920, I added you as a subscriber.

tobiasvk updated this revision to Diff 95140.Apr 13 2017, 9:19 AM
tobiasvk edited edge metadata.

Add test case now that D31920 is merged.

pcc accepted this revision.Apr 13 2017, 9:23 AM

LGTM

This revision was automatically updated to reflect the committed changes.