3333#include " llvm/Object/ObjectFile.h"
3434#include " llvm/Object/ELFObjectFile.h"
3535#include " llvm/Object/Wasm.h"
36+ #include " llvm/Object/IRObjectFile.h"
3637#include " llvm/BinaryFormat/Wasm.h"
38+ #include " llvm/IR/Module.h"
39+ #include " llvm/IR/Constants.h"
3740
3841using namespace swift ;
3942using namespace llvm ::opt;
@@ -172,6 +175,27 @@ extractLinkerFlagsFromObjectFile(const llvm::object::WasmObjectFile *ObjectFile,
172175 return false ;
173176}
174177
178+ static bool
179+ extractLinkerFlagsFromObjectFile (const llvm::object::IRObjectFile *ObjectFile,
180+ std::vector<std::string> &LinkerFlags,
181+ CompilerInstance &Instance) {
182+ for (const auto &M : ObjectFile->modules ()) {
183+ llvm::GlobalVariable *var = M.getGlobalVariable (" _swift1_autolink_entries" , true );
184+ if (!var) continue ;
185+ if (auto Entries = dyn_cast<llvm::ConstantDataArray>(var->getInitializer ())) {
186+ StringRef SegmentData = Entries->getAsString ();
187+ // entries are null-terminated, so extract them and push them into
188+ // the set.
189+ llvm::SmallVector<llvm::StringRef, 4 > SplitFlags;
190+ SegmentData.split (SplitFlags, llvm::StringRef (" \0 " , 1 ), -1 ,
191+ /* KeepEmpty=*/ false );
192+ for (const auto &Flag : SplitFlags)
193+ LinkerFlags.push_back (Flag.str ());
194+ }
195+ }
196+ return false ;
197+ }
198+
175199// / Look inside the binary 'Bin' and append any linker flags found in its
176200// / ".swift1_autolink_entries" section to 'LinkerFlags'. If 'Bin' is an archive,
177201// / recursively look inside all children within the archive. Return 'true' if
@@ -184,6 +208,8 @@ static bool extractLinkerFlags(const llvm::object::Binary *Bin,
184208 return extractLinkerFlagsFromObjectFile (ObjectFile, LinkerFlags, Instance);
185209 } else if (auto *ObjectFile = llvm::dyn_cast<llvm::object::WasmObjectFile>(Bin)) {
186210 return extractLinkerFlagsFromObjectFile (ObjectFile, LinkerFlags, Instance);
211+ } else if (auto *BitCodeFile = llvm::dyn_cast<llvm::object::IRObjectFile>(Bin)) {
212+ return extractLinkerFlagsFromObjectFile (BitCodeFile, LinkerFlags, Instance);
187213 } else if (auto *Archive = llvm::dyn_cast<llvm::object::Archive>(Bin)) {
188214 llvm::Error Error = llvm::Error::success ();
189215 for (const auto &Child : Archive->children (Error)) {
@@ -215,6 +241,7 @@ int autolink_extract_main(ArrayRef<const char *> Args, const char *Argv0,
215241 void *MainAddr) {
216242 CompilerInstance Instance;
217243 PrintingDiagnosticConsumer PDC;
244+ llvm::LLVMContext Context;
218245 Instance.addDiagnosticConsumer (&PDC);
219246
220247 AutolinkExtractInvocation Invocation;
@@ -231,20 +258,28 @@ int autolink_extract_main(ArrayRef<const char *> Args, const char *Argv0,
231258
232259 // Extract the linker flags from the objects.
233260 for (const auto &BinaryFileName : Invocation.getInputFilenames ()) {
234- auto BinaryOwner = llvm::object::createBinary (BinaryFileName);
235- if (!BinaryOwner) {
261+ auto FileOrErr = llvm::MemoryBuffer::getFileOrSTDIN (BinaryFileName, /* FileSize=*/ -1 ,
262+ /* RequiresNullTerminator=*/ false );
263+ if (std::error_code EC = FileOrErr.getError ()) {
264+ Instance.getDiags ().diagnose (SourceLoc (), diag::error_open_input_file,
265+ BinaryFileName, EC.message ());
266+ return 1 ;
267+ }
268+ std::unique_ptr<llvm::MemoryBuffer> &Buffer = FileOrErr.get ();
269+ auto Binary = llvm::object::createBinary (Buffer->getMemBufferRef (), &Context);
270+ if (!Binary) {
236271 std::string message;
237272 {
238273 llvm::raw_string_ostream os (message);
239- logAllUnhandledErrors (BinaryOwner .takeError (), os, " " );
274+ logAllUnhandledErrors (Binary .takeError (), os, " " );
240275 }
241276
242277 Instance.getDiags ().diagnose (SourceLoc (), diag::error_open_input_file,
243278 BinaryFileName, message);
244279 return 1 ;
245280 }
246281
247- if (extractLinkerFlags (BinaryOwner-> getBinary (), Instance, BinaryFileName,
282+ if (extractLinkerFlags (Binary-> get (), Instance, BinaryFileName,
248283 LinkerFlags)) {
249284 return 1 ;
250285 }
0 commit comments