Skip to content

Commit 8953af5

Browse files
committed
[Driver] Don't pass ELF shared objects to swift-autolink-extract
Prior to performing linking on ELF platforms (except the PS4) we extract autolink information from the object files that will be used during linking. The current implementation passes all the linker inputs that are marked as an TY_Object to swift-autolink-extract. There are a two cases where this is not necessary or problematic. In the first case, we are looking at an ELF shared object. Although harmless, this is wasted work. Specifically, the `.swift1_autolink_entries` entry in the object files are marked as `SHF_EXCLUDE`, meaning they will not be merged into the final product during linking. In the second case, we are linking against a linker script that looks like an ELF shared object (ends with `.so`). In the previous case, the autolink-extract step will succeed even if it does unnecessary work. In this case, the autolink-extract step will fail because it cannot recognize the linker script as an object file. You will observe an error something like this: ``` <unknown>:0: error: error opening input file '/path/to/libLinkerScript.so' (The file was not recognized as a valid object file ``` Although your linker will know what to do with it, autolink-extract will halt before you get to that point.
1 parent 270f734 commit 8953af5

File tree

3 files changed

+18
-2
lines changed

3 files changed

+18
-2
lines changed

lib/Driver/Driver.cpp

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2107,11 +2107,21 @@ void Driver::buildActions(SmallVectorImpl<const Action *> &TopLevelActions,
21072107
// On ELF platforms there's no built in autolinking mechanism, so we
21082108
// pull the info we need from the .o files directly and pass them as an
21092109
// argument input file to the linker.
2110+
const auto &Triple = TC.getTriple();
21102111
SmallVector<const Action *, 2> AutolinkExtractInputs;
21112112
for (const Action *A : AllLinkerInputs)
2112-
if (A->getType() == file_types::TY_Object)
2113+
if (A->getType() == file_types::TY_Object) {
2114+
// Shared objects on ELF platforms don't have a swift1_autolink_entries
2115+
// section in them because the section in the .o files is marked as
2116+
// SHF_EXCLUDE.
2117+
if (auto *IA = dyn_cast<InputAction>(A)) {
2118+
StringRef ObjectName = IA->getInputArg().getValue();
2119+
if (Triple.getObjectFormat() == llvm::Triple::ELF &&
2120+
ObjectName.endswith(".so"))
2121+
continue;
2122+
}
21132123
AutolinkExtractInputs.push_back(A);
2114-
const auto &Triple = TC.getTriple();
2124+
}
21152125
const bool AutolinkExtractRequired =
21162126
(Triple.getObjectFormat() == llvm::Triple::ELF && !Triple.isPS4()) ||
21172127
Triple.getObjectFormat() == llvm::Triple::Wasm ||

test/Driver/Inputs/libEmpty.so

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
/* Just an empty file that looks like an ELF shared object */
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
// RUN: %target-swiftc_driver -### %s %S/Inputs/libEmpty.so | %FileCheck %s
2+
3+
// REQUIRES: autolink-extract
4+
5+
// CHECK-NOT: swift-autolink-extract {{.+}}.o {{.+}}Inputs/libEmpty.so -o {{.+}}.autolink

0 commit comments

Comments
 (0)