Skip to content

Commit 476db5b

Browse files
committed
[Autolink Extract] Keep a set of linker flags instead of vector
Otherwise we can duplicate linker flags across input binaries, which can result in very large linkerr invocation commands. Resolves #58380
1 parent d34d88d commit 476db5b

File tree

2 files changed

+31
-7
lines changed

2 files changed

+31
-7
lines changed

lib/DriverTool/autolink_extract_main.cpp

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818

1919
#include <string>
2020
#include <vector>
21+
#include <set>
2122

2223
#include "swift/AST/DiagnosticsFrontend.h"
2324
#include "swift/Frontend/Frontend.h"
@@ -38,6 +39,23 @@
3839
using namespace swift;
3940
using namespace llvm::opt;
4041

42+
// Identifiers hash just like pointers.
43+
template<> struct llvm::DenseMapInfo<std::string> {
44+
static std::string getEmptyKey() {
45+
return swift::Identifier::getEmptyKey().str().str();
46+
}
47+
static std::string getTombstoneKey() {
48+
return swift::Identifier::getTombstoneKey().str().str();
49+
}
50+
static unsigned getHashValue(std::string Val) {
51+
std::hash<std::string> Hasher;
52+
return Hasher(Val);
53+
}
54+
static bool isEqual(std::string LHS, std::string RHS) {
55+
return LHS == RHS;
56+
}
57+
};
58+
4159
class AutolinkExtractInvocation {
4260
private:
4361
std::string MainExecutablePath;
@@ -112,7 +130,7 @@ class AutolinkExtractInvocation {
112130
/// Return 'true' if there was an error, and 'false' otherwise.
113131
static bool
114132
extractLinkerFlagsFromObjectFile(const llvm::object::ObjectFile *ObjectFile,
115-
std::vector<std::string> &LinkerFlags,
133+
llvm::SetVector<std::string> &LinkerFlags,
116134
CompilerInstance &Instance) {
117135
// Search for the section we hold autolink entries in
118136
for (auto &Section : ObjectFile->sections()) {
@@ -141,7 +159,7 @@ extractLinkerFlagsFromObjectFile(const llvm::object::ObjectFile *ObjectFile,
141159
SectionData->split(SplitFlags, llvm::StringRef("\0", 1), -1,
142160
/*KeepEmpty=*/false);
143161
for (const auto &Flag : SplitFlags)
144-
LinkerFlags.push_back(Flag.str());
162+
LinkerFlags.insert(Flag.str());
145163
}
146164
}
147165
return false;
@@ -152,7 +170,7 @@ extractLinkerFlagsFromObjectFile(const llvm::object::ObjectFile *ObjectFile,
152170
/// 'true' if there was an error, and 'false' otherwise.
153171
static bool
154172
extractLinkerFlagsFromObjectFile(const llvm::object::WasmObjectFile *ObjectFile,
155-
std::vector<std::string> &LinkerFlags,
173+
llvm::SetVector<std::string> &LinkerFlags,
156174
CompilerInstance &Instance) {
157175
// Search for the data segment we hold autolink entries in
158176
for (const llvm::object::WasmSegment &Segment : ObjectFile->dataSegments()) {
@@ -165,7 +183,7 @@ extractLinkerFlagsFromObjectFile(const llvm::object::WasmObjectFile *ObjectFile,
165183
SegmentData.split(SplitFlags, llvm::StringRef("\0", 1), -1,
166184
/*KeepEmpty=*/false);
167185
for (const auto &Flag : SplitFlags)
168-
LinkerFlags.push_back(Flag.str());
186+
LinkerFlags.insert(Flag.str());
169187
}
170188
}
171189
return false;
@@ -178,7 +196,7 @@ extractLinkerFlagsFromObjectFile(const llvm::object::WasmObjectFile *ObjectFile,
178196
static bool extractLinkerFlags(const llvm::object::Binary *Bin,
179197
CompilerInstance &Instance,
180198
StringRef BinaryFileName,
181-
std::vector<std::string> &LinkerFlags) {
199+
llvm::SetVector<std::string> &LinkerFlags) {
182200
if (auto *ObjectFile = llvm::dyn_cast<llvm::object::ELFObjectFileBase>(Bin)) {
183201
return extractLinkerFlagsFromObjectFile(ObjectFile, LinkerFlags, Instance);
184202
} else if (auto *ObjectFile =
@@ -227,7 +245,7 @@ int autolink_extract_main(ArrayRef<const char *> Args, const char *Argv0,
227245
return 1;
228246
}
229247

230-
std::vector<std::string> LinkerFlags;
248+
llvm::SetVector<std::string> LinkerFlags;
231249

232250
// Extract the linker flags from the objects.
233251
for (const auto &BinaryFileName : Invocation.getInputFilenames()) {

test/AutolinkExtract/import.swift

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,16 @@
11
// RUN: %empty-directory(%t)
22
// RUN: %target-swiftc_driver -emit-module -emit-module-path %t/empty.swiftmodule -module-name empty -module-link-name empty %S/empty.swift
33
// RUN: %target-swiftc_driver -c %s -I %t -o %t/import_experimental.o
4-
// RUN: %target-swift-autolink-extract %t/import_experimental.o -o - | %FileCheck --check-prefix CHECK-%target-object-format %s
4+
// RUN: %target-swiftc_driver -c %s -I %t -o %t/import_experimental_again.o
5+
// RUN: %target-swift-autolink-extract %t/import_experimental.o %t/import_experimental_again.o -o - | %FileCheck --check-prefix CHECK-%target-object-format %s
6+
7+
// RUN: %target-swift-autolink-extract %t/import_experimental.o %t/import_experimental_again.o -o - | %FileCheck --check-prefix UNIQUE %s
58

69
// REQUIRES: autolink-extract
710

11+
// UNIQUE-COUNT-1: -lswiftCore
12+
// UNIQUE-COUNT-1: -lempty
13+
814
// CHECK-elf-DAG: -lswiftCore
915
// CHECK-elf-DAG: -lempty
1016

0 commit comments

Comments
 (0)