[PATCH] D107533: Handle encoding personalities of same names but different kinds.
Vy Nguyen via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Wed Aug 11 22:58:08 PDT 2021
oontvoo added a comment.
In D107533#2940450 <https://reviews.llvm.org/D107533#2940450>, @int3 wrote:
> Interesting example...
Yep! this is "inspired" by for ios apps that try really hard to do funny things static linking
> after playing around with it for a bit, I'm not convinced that ld64 is actually behaving sensibly here 😕
>
> First, when linking against combined.o, the dylib symbol "wins":
> In contrast, the code in this diff lets the local symbol win. But... I put "wins" above in quotes because ld64 doesn't actually seem to consider the local symbol a valid candidate at all! If we remove `-lc++`:
Actually this diff doesn't change which symbol "wins" in the final output - (it's pretty inconsequential to that)
Similarly, without supplying `-lc++`, LLD would also fail with undefined symbol here.
$ ../bin/ld64.lld.darwinnew -arch "x86_64" -platform_version macos 10.15 11.0 -syslibroot "/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk" -lc++ -lSystem user_2.o combined.o -o lld_output
ld64.lld.darwinnew: warning: user_2.o has version 11.0.0, which is newer than target minimum of 10.15
ld64.lld.darwinnew: warning: combined.o has version 11.0.0, which is newer than target minimum of 10.15
$ llvm-objdump --macho --bind lld_output
lld_output:
Bind table:
segment section address type addend dylib symbol
__DATA_CONST __got 0x100002000 pointer 0 libc++ ___gxx_personality_v0
$ ../bin/ld64.lld.darwinnew -arch "x86_64" -platform_version macos 10.15 11.0 -syslibroot "/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk" -lSystem user_2.o combined.o -o lld_output
ld64.lld.darwinnew: warning: user_2.o has version 11.0.0, which is newer than target minimum of 10.15
ld64.lld.darwinnew: warning: combined.o has version 11.0.0, which is newer than target minimum of 10.15
ld64.lld.darwinnew: error: undefined symbol: ___gxx_personality_v0
>>> referenced by user_2.o
ld64.lld.darwinnew: error: undefined symbol: ___gxx_personality_v0
>>> referenced by user_2.o
> However, linking `user_1.o` and `defined.o` in place of `combined.o` does cause the personalities to be resolved to the global symbol (as expected):
`user_1.o` + `defined.o` is **not** the same thing as `combined.o` .
(The trick here was that `___gxx_personality_v0` was defined as private-extern in `defined.o`, ie., `T`, and `ld -r` changed it to local defined, ie `t` in `combined.o`)
> I'm not convinced that we should attempt to emulate this bizarre behavior. I don't see why the result of a link should differ depending on whether some of its intermediate inputs have been run through `ld -r`. Would it be possible to change your build system to work around this instead?
I think the most convoluted part here is how `ld -r` changes a a private extern to local 🤔
The rest of the things that we've observed here are by-products
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D107533/new/
https://reviews.llvm.org/D107533
More information about the llvm-commits
mailing list