|
13 | 13 | #include "llvm/IR/Function.h" |
14 | 14 | #include "llvm/IR/GlobalVariable.h" |
15 | 15 | #include "llvm/IR/Module.h" |
| 16 | +#include "llvm/Object/MachOUniversal.h" |
| 17 | +#include "llvm/Support/FormatVariadic.h" |
16 | 18 | #include "llvm/Support/TargetRegistry.h" |
17 | 19 | #include "llvm/Target/TargetMachine.h" |
18 | 20 |
|
@@ -302,6 +304,51 @@ StaticLibraryDefinitionGenerator::Load(ObjectLayer &L, const char *FileName) { |
302 | 304 | return Create(L, std::move(*ArchiveBuffer)); |
303 | 305 | } |
304 | 306 |
|
| 307 | +Expected<std::unique_ptr<StaticLibraryDefinitionGenerator>> |
| 308 | +StaticLibraryDefinitionGenerator::Load(ObjectLayer &L, const char *FileName, |
| 309 | + const Triple &TT) { |
| 310 | + auto B = object::createBinary(FileName); |
| 311 | + if (!B) |
| 312 | + return B.takeError(); |
| 313 | + |
| 314 | + // If this is a regular archive then create an instance from it. |
| 315 | + if (isa<object::Archive>(B->getBinary())) |
| 316 | + return Create(L, std::move(B->takeBinary().second)); |
| 317 | + |
| 318 | + // If this is a universal binary then search for a slice matching the given |
| 319 | + // Triple. |
| 320 | + if (auto *UB = cast<object::MachOUniversalBinary>(B->getBinary())) { |
| 321 | + for (const auto &Obj : UB->objects()) { |
| 322 | + auto ObjTT = Obj.getTriple(); |
| 323 | + if (ObjTT.getArch() == TT.getArch() && |
| 324 | + ObjTT.getSubArch() == TT.getSubArch() && |
| 325 | + ObjTT.getVendor() == TT.getVendor()) { |
| 326 | + // We found a match. Create an instance from a buffer covering this |
| 327 | + // slice. |
| 328 | + auto SliceBuffer = MemoryBuffer::getFileSlice(FileName, Obj.getSize(), |
| 329 | + Obj.getOffset()); |
| 330 | + if (!SliceBuffer) |
| 331 | + return make_error<StringError>( |
| 332 | + Twine("Could not create buffer for ") + TT.str() + " slice of " + |
| 333 | + FileName + ": [ " + formatv("{0:x}", Obj.getOffset()) + |
| 334 | + " .. " + formatv("{0:x}", Obj.getOffset() + Obj.getSize()) + |
| 335 | + ": " + SliceBuffer.getError().message(), |
| 336 | + SliceBuffer.getError()); |
| 337 | + return Create(L, std::move(*SliceBuffer)); |
| 338 | + } |
| 339 | + } |
| 340 | + |
| 341 | + return make_error<StringError>(Twine("Universal binary ") + FileName + |
| 342 | + " does not contain a slice for " + |
| 343 | + TT.str(), |
| 344 | + inconvertibleErrorCode()); |
| 345 | + } |
| 346 | + |
| 347 | + return make_error<StringError>(Twine("Unrecognized file type for ") + |
| 348 | + FileName, |
| 349 | + inconvertibleErrorCode()); |
| 350 | +} |
| 351 | + |
305 | 352 | Expected<std::unique_ptr<StaticLibraryDefinitionGenerator>> |
306 | 353 | StaticLibraryDefinitionGenerator::Create( |
307 | 354 | ObjectLayer &L, std::unique_ptr<MemoryBuffer> ArchiveBuffer) { |
|
0 commit comments