33
33
#include " llvm/Object/ObjectFile.h"
34
34
#include " llvm/Object/ELFObjectFile.h"
35
35
#include " llvm/Object/Wasm.h"
36
+ #include " llvm/Object/IRObjectFile.h"
36
37
#include " llvm/BinaryFormat/Wasm.h"
38
+ #include " llvm/IR/Module.h"
39
+ #include " llvm/IR/Constants.h"
37
40
38
41
using namespace swift ;
39
42
using namespace llvm ::opt;
@@ -172,6 +175,27 @@ extractLinkerFlagsFromObjectFile(const llvm::object::WasmObjectFile *ObjectFile,
172
175
return false ;
173
176
}
174
177
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
+
175
199
// / Look inside the binary 'Bin' and append any linker flags found in its
176
200
// / ".swift1_autolink_entries" section to 'LinkerFlags'. If 'Bin' is an archive,
177
201
// / recursively look inside all children within the archive. Return 'true' if
@@ -184,6 +208,8 @@ static bool extractLinkerFlags(const llvm::object::Binary *Bin,
184
208
return extractLinkerFlagsFromObjectFile (ObjectFile, LinkerFlags, Instance);
185
209
} else if (auto *ObjectFile = llvm::dyn_cast<llvm::object::WasmObjectFile>(Bin)) {
186
210
return extractLinkerFlagsFromObjectFile (ObjectFile, LinkerFlags, Instance);
211
+ } else if (auto *BitCodeFile = llvm::dyn_cast<llvm::object::IRObjectFile>(Bin)) {
212
+ return extractLinkerFlagsFromObjectFile (BitCodeFile, LinkerFlags, Instance);
187
213
} else if (auto *Archive = llvm::dyn_cast<llvm::object::Archive>(Bin)) {
188
214
llvm::Error Error = llvm::Error::success ();
189
215
for (const auto &Child : Archive->children (Error)) {
@@ -215,6 +241,7 @@ int autolink_extract_main(ArrayRef<const char *> Args, const char *Argv0,
215
241
void *MainAddr) {
216
242
CompilerInstance Instance;
217
243
PrintingDiagnosticConsumer PDC;
244
+ llvm::LLVMContext Context;
218
245
Instance.addDiagnosticConsumer (&PDC);
219
246
220
247
AutolinkExtractInvocation Invocation;
@@ -231,20 +258,28 @@ int autolink_extract_main(ArrayRef<const char *> Args, const char *Argv0,
231
258
232
259
// Extract the linker flags from the objects.
233
260
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) {
236
271
std::string message;
237
272
{
238
273
llvm::raw_string_ostream os (message);
239
- logAllUnhandledErrors (BinaryOwner .takeError (), os, " " );
274
+ logAllUnhandledErrors (Binary .takeError (), os, " " );
240
275
}
241
276
242
277
Instance.getDiags ().diagnose (SourceLoc (), diag::error_open_input_file,
243
278
BinaryFileName, message);
244
279
return 1 ;
245
280
}
246
281
247
- if (extractLinkerFlags (BinaryOwner-> getBinary (), Instance, BinaryFileName,
282
+ if (extractLinkerFlags (Binary-> get (), Instance, BinaryFileName,
248
283
LinkerFlags)) {
249
284
return 1 ;
250
285
}
0 commit comments