[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