This is an archive of the discontinued LLVM Phabricator instance.

[COFF] Make the autogenerated .weak.<name>.default symbols static
AbandonedPublic

Authored by mstorsjo on Dec 19 2019, 8:53 AM.

Details

Summary

If we have references to the same extern_weak in multiple objects, all of them would generate external symbols with the same name. Make them static to avoid duplicate definitions; nothing should need to refer to this symbol outside of the current object.

GCC/binutils seems to handle the same by not using a fixed string for the ".default" suffix, but instead using the name of some other defined external symbol from the same object (which is supposed to be unique among objects unless there are other duplicate definitions).

Diff Detail

Event Timeline

mstorsjo created this revision.Dec 19 2019, 8:53 AM
Herald added a project: Restricted Project. · View Herald TranscriptDec 19 2019, 8:53 AM
Herald added a subscriber: hiraditya. · View Herald Transcript
rnk added inline comments.Dec 27 2019, 3:04 PM
llvm/lib/MC/WinCOFFObjectWriter.cpp
369

While here, I think it would be better to hoist the cast into the entry block, rename the parameter to MCSymGeneric, and have a new local variable const auto &MCSym = cast<MCSymbolCOFF>(MCSymGeneric);

383

I think we can assign static storage here.

400

So, we could move the old storage class calculation here.

415

Can this be factored so we only check for weak externals once? We do it above and assign it to Local. All this StorageClass code is dead for the weak external case, so we can hoist this new StorageClass up to that block, and hoist the old StorageClass code into the else block.

mstorsjo updated this revision to Diff 235473.Dec 28 2019, 4:50 AM
mstorsjo marked 4 inline comments as done.

Did as suggested. As some of the moved blocks are larger than what was left unmoved, parts of the diff is a bit nonobvious though.

rnk accepted this revision.Dec 28 2019, 12:55 PM

lgtm, thanks!

This revision is now accepted and ready to land.Dec 28 2019, 12:55 PM
This revision was automatically updated to reflect the committed changes.

Ok, so apparently this doesn't work, as MS link.exe rejects object files, where a IMAGE_SYM_CLASS_WEAK_EXTERNAL symbol points at a symbol which isn't external - so I had to revert it.

Are there any other options then, than trying to do what GCC/binutils does, by changing the suffix .default into something that more hopefully is unique? They use the name of another defined (probably non-comdat) external symbol from the same object (that should be unique) as suffix. But that feels like a much larger mess to implement.

FWIW, right now this is blocking me from llvm with clang itself for mingw targets, since we started using an external thread_local variable.

mstorsjo reopened this revision.Dec 28 2019, 3:02 PM
This revision is now accepted and ready to land.Dec 28 2019, 3:02 PM
mstorsjo requested review of this revision.Dec 28 2019, 3:02 PM

Are there any other options then, than trying to do what GCC/binutils does, by changing the suffix .default into something that more hopefully is unique? They use the name of another defined (probably non-comdat) external symbol from the same object (that should be unique) as suffix. But that feels like a much larger mess to implement.

FWIW, right now this is blocking me from llvm with clang itself for mingw targets, since we started using an external thread_local variable.

Making lld more lenient with multiple object files with the same default absolute symbol for the address zero should fix the primary issue wrt the TLS initializer function (although I haven't tried rebuilding everything with that in place), which I implemented in D71981. Implementing something similar to binutils with making unique names for the weak default symbols would still be nice though.

rnk added a comment.Jan 2 2020, 4:57 PM

I guess if the absolute symbol change is enough to unblock you, I'd leave this alone for now. The gnu behavior seems error prone and difficult to implement.

In D71711#1802223, @rnk wrote:

I guess if the absolute symbol change is enough to unblock you, I'd leave this alone for now. The gnu behavior seems error prone and difficult to implement.

Yeah, it seems hard to do sensibly - but it'd be necessary (in the generic case, not for the present weak tls init function case) if the linker errors out on combinations of absolute zero and regular. So strictly, it'd be necessary for clang+ld.bfd, for a wider use of weak, and also for lld if we change that aspect there.

mstorsjo abandoned this revision.Mar 14 2020, 1:17 AM

Superseded by D75989.