diff --git a/lib/DriverTool/autolink_extract_main.cpp b/lib/DriverTool/autolink_extract_main.cpp index 76825313eb3f1..f79923e10a741 100644 --- a/lib/DriverTool/autolink_extract_main.cpp +++ b/lib/DriverTool/autolink_extract_main.cpp @@ -32,6 +32,8 @@ #include "llvm/Object/Archive.h" #include "llvm/Object/ObjectFile.h" #include "llvm/Object/ELFObjectFile.h" +#include "llvm/Object/Wasm.h" +#include "llvm/BinaryFormat/Wasm.h" using namespace swift; using namespace llvm::opt; @@ -145,6 +147,30 @@ extractLinkerFlagsFromObjectFile(const llvm::object::ObjectFile *ObjectFile, return false; } +/// Look inside the object file 'WasmObjectFile' and append any linker flags +/// found in its ".swift1_autolink_entries" section to 'LinkerFlags'. Return +/// 'true' if there was an error, and 'false' otherwise. +static bool +extractLinkerFlagsFromObjectFile(const llvm::object::WasmObjectFile *ObjectFile, + std::vector &LinkerFlags, + CompilerInstance &Instance) { + // Search for the data segment we hold autolink entries in + for (const llvm::object::WasmSegment &Segment : ObjectFile->dataSegments()) { + if (Segment.Data.Name == ".swift1_autolink_entries") { + + StringRef SegmentData = llvm::toStringRef(Segment.Data.Content); + // entries are null-terminated, so extract them and push them into + // the set. + llvm::SmallVector SplitFlags; + SegmentData.split(SplitFlags, llvm::StringRef("\0", 1), -1, + /*KeepEmpty=*/false); + for (const auto &Flag : SplitFlags) + LinkerFlags.push_back(Flag.str()); + } + } + return false; +} + /// Look inside the binary 'Bin' and append any linker flags found in its /// ".swift1_autolink_entries" section to 'LinkerFlags'. If 'Bin' is an archive, /// recursively look inside all children within the archive. Return 'true' if @@ -155,6 +181,9 @@ static bool extractLinkerFlags(const llvm::object::Binary *Bin, std::vector &LinkerFlags) { if (auto *ObjectFile = llvm::dyn_cast(Bin)) { return extractLinkerFlagsFromObjectFile(ObjectFile, LinkerFlags, Instance); + } else if (auto *ObjectFile = + llvm::dyn_cast(Bin)) { + return extractLinkerFlagsFromObjectFile(ObjectFile, LinkerFlags, Instance); } else if (auto *Archive = llvm::dyn_cast(Bin)) { llvm::Error Error = llvm::Error::success(); for (const auto &Child : Archive->children(Error)) {