Skip to content

Commit 840e507

Browse files
authored
[lld] Do not implicitly link non "public" libraries (llvm#97639)
The LC_SUB_CLIENT Mach-O command and the `allowable-clients` TBD entry specify that the given framework (or library?) can only be linked directly from the specified names, even if it is sitting in `/usr/lib` or `/System/Library/Frameworks`. Add a check for those conditions before checking if a library should be implicitly linked, and link against their umbrella if they have allowable clients. The code needs to be in both the binary libraries and the interface libraries. Add a test that reproduces the scenario in which a framework reexports a private framework that sits in `/System/Library/Frameworks`, and check for the symbols of the reexported framework to be associated with the public framework, and not the private one.
1 parent fe8933b commit 840e507

File tree

2 files changed

+57
-2
lines changed

2 files changed

+57
-2
lines changed

lld/MachO/InputFiles.cpp

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1725,7 +1725,10 @@ DylibFile::DylibFile(MemoryBufferRef mb, DylibFile *umbrella,
17251725
}
17261726

17271727
// Initialize symbols.
1728-
exportingFile = isImplicitlyLinked(installName) ? this : this->umbrella;
1728+
bool canBeImplicitlyLinked = findCommand(hdr, LC_SUB_CLIENT) == nullptr;
1729+
exportingFile = (canBeImplicitlyLinked && isImplicitlyLinked(installName))
1730+
? this
1731+
: this->umbrella;
17291732

17301733
const auto *dyldInfo = findCommand<dyld_info_command>(hdr, LC_DYLD_INFO_ONLY);
17311734
const auto *exportsTrie =
@@ -1884,7 +1887,10 @@ DylibFile::DylibFile(const InterfaceFile &interface, DylibFile *umbrella,
18841887

18851888
checkAppExtensionSafety(interface.isApplicationExtensionSafe());
18861889

1887-
exportingFile = isImplicitlyLinked(installName) ? this : umbrella;
1890+
bool canBeImplicitlyLinked = interface.allowableClients().size() == 0;
1891+
exportingFile = (canBeImplicitlyLinked && isImplicitlyLinked(installName))
1892+
? this
1893+
: umbrella;
18881894
auto addSymbol = [&](const llvm::MachO::Symbol &symbol,
18891895
const Twine &name) -> void {
18901896
StringRef savedName = saver().save(name);
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
# REQUIRES: arm
2+
# RUN: rm -rf %t; split-file %s %t
3+
# RUN: ln -s Versions/A/FrameworkPublic.tbd %t/System/Library/Frameworks/FrameworkPublic.framework/
4+
# RUN: ln -s Versions/A/FrameworkPrivate.tbd %t/System/Library/Frameworks/FrameworkPrivate.framework/
5+
# RUN: llvm-mc -filetype obj -triple arm64-apple-macos11.0 %t/test.s -o %t/test.o
6+
# RUN: %lld -arch arm64 -platform_version macos 11.0 11.0 -o %t/test -syslibroot %t -framework FrameworkPublic %t/test.o
7+
8+
# RUN: llvm-objdump --bind --no-show-raw-insn -d %t/test | FileCheck %s
9+
# CHECK: Bind table:
10+
# CHECK-DAG: __DATA __data {{.*}} pointer 0 FrameworkPublic _funcPublic
11+
# CHECK-DAG: __DATA __data {{.*}} pointer 0 FrameworkPublic _funcPrivate
12+
13+
#--- System/Library/Frameworks/FrameworkPublic.framework/Versions/A/FrameworkPublic.tbd
14+
--- !tapi-tbd
15+
tbd-version: 4
16+
targets: [ arm64-macos ]
17+
install-name: '/System/Library/Frameworks/FrameworkPublic.framework/Versions/A/FrameworkPublic'
18+
current-version: 1.0.0
19+
reexported-libraries:
20+
- targets: [ arm64-macos ]
21+
libraries: [ '/System/Library/Frameworks/FrameworkPrivate.framework/Versions/A/FrameworkPrivate' ]
22+
exports:
23+
- targets: [ arm64-macos ]
24+
symbols: [ '_funcPublic' ]
25+
...
26+
#--- System/Library/Frameworks/FrameworkPrivate.framework/Versions/A/FrameworkPrivate.tbd
27+
--- !tapi-tbd
28+
tbd-version: 4
29+
targets: [ arm64-macos ]
30+
install-name: '/System/Library/Frameworks/FrameworkPrivate.framework/Versions/A/FrameworkPrivate'
31+
current-version: 1.0.0
32+
allowable-clients:
33+
- targets: [ arm64-macos ]
34+
clients: [ FrameworkPublic ]
35+
exports:
36+
- targets: [ arm64-macos ]
37+
symbols: [ '_funcPrivate' ]
38+
...
39+
#--- test.s
40+
.text
41+
.globl _main
42+
43+
_main:
44+
ret
45+
46+
.data
47+
.quad _funcPublic
48+
.quad _funcPrivate
49+

0 commit comments

Comments
 (0)