[llvm] 7678e8e - [llvm-lipo] Don't use a global LLVMContext

Arthur Eubanks via llvm-commits llvm-commits at lists.llvm.org
Mon Mar 21 10:43:31 PDT 2022


Author: Arthur Eubanks
Date: 2022-03-21T10:43:22-07:00
New Revision: 7678e8ebbbc90d227912638fb7f596febfe75bf6

URL: https://github.com/llvm/llvm-project/commit/7678e8ebbbc90d227912638fb7f596febfe75bf6
DIFF: https://github.com/llvm/llvm-project/commit/7678e8ebbbc90d227912638fb7f596febfe75bf6.diff

LOG: [llvm-lipo] Don't use a global LLVMContext

Fixes initialization order fiasco issue reported by
https://lab.llvm.org/buildbot/#builders/5/builds/20987

Added: 
    

Modified: 
    llvm/tools/llvm-lipo/llvm-lipo.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/tools/llvm-lipo/llvm-lipo.cpp b/llvm/tools/llvm-lipo/llvm-lipo.cpp
index aae14d29145ba..43dd97ed2c3be 100644
--- a/llvm/tools/llvm-lipo/llvm-lipo.cpp
+++ b/llvm/tools/llvm-lipo/llvm-lipo.cpp
@@ -35,7 +35,6 @@ using namespace llvm;
 using namespace llvm::object;
 
 static const StringRef ToolName = "llvm-lipo";
-static LLVMContext LLVMCtx;
 
 [[noreturn]] static void reportError(Twine Message) {
   WithColor::error(errs(), ToolName) << Message << "\n";
@@ -119,7 +118,7 @@ struct Config {
   LipoAction ActionToPerform;
 };
 
-static Slice createSliceFromArchive(const Archive &A) {
+static Slice createSliceFromArchive(LLVMContext &LLVMCtx, const Archive &A) {
   Expected<Slice> ArchiveOrSlice = Slice::create(A, &LLVMCtx);
   if (!ArchiveOrSlice)
     reportError(A.getFileName(), ArchiveOrSlice.takeError());
@@ -317,7 +316,7 @@ static Config parseLipoOptions(ArrayRef<const char *> ArgsArr) {
 }
 
 static SmallVector<OwningBinary<Binary>, 1>
-readInputBinaries(ArrayRef<InputFile> InputFiles) {
+readInputBinaries(LLVMContext &LLVMCtx, ArrayRef<InputFile> InputFiles) {
   SmallVector<OwningBinary<Binary>, 1> InputBinaries;
   for (const InputFile &IF : InputFiles) {
     Expected<OwningBinary<Binary>> BinaryOrErr =
@@ -329,11 +328,10 @@ readInputBinaries(ArrayRef<InputFile> InputFiles) {
         !B->isIR())
       reportError("File " + IF.FileName + " has unsupported binary format");
     if (IF.ArchType && (B->isMachO() || B->isArchive() || B->isIR())) {
-      const auto S = B->isMachO()
-                         ? Slice(*cast<MachOObjectFile>(B))
-                         : B->isArchive()
-                               ? createSliceFromArchive(*cast<Archive>(B))
-                               : createSliceFromIR(*cast<IRObjectFile>(B), 0);
+      const auto S = B->isMachO() ? Slice(*cast<MachOObjectFile>(B))
+                     : B->isArchive()
+                         ? createSliceFromArchive(LLVMCtx, *cast<Archive>(B))
+                         : createSliceFromIR(*cast<IRObjectFile>(B), 0);
       const auto SpecifiedCPUType = MachO::getCPUTypeFromArchitecture(
                                         MachO::getArchitectureFromName(
                                             Triple(*IF.ArchType).getArchName()))
@@ -381,7 +379,8 @@ verifyArch(ArrayRef<OwningBinary<Binary>> InputBinaries,
   exit(EXIT_SUCCESS);
 }
 
-static void printBinaryArchs(const Binary *Binary, raw_ostream &OS) {
+static void printBinaryArchs(LLVMContext &LLVMCtx, const Binary *Binary,
+                             raw_ostream &OS) {
   // Prints trailing space for compatibility with cctools lipo.
   if (auto UO = dyn_cast<MachOUniversalBinary>(Binary)) {
     for (const auto &O : UO->objects()) {
@@ -409,7 +408,8 @@ static void printBinaryArchs(const Binary *Binary, raw_ostream &OS) {
       if (ArchiveOrError) {
         consumeError(MachOObjOrError.takeError());
         consumeError(IROrError.takeError());
-        OS << createSliceFromArchive(**ArchiveOrError).getArchString() << " ";
+        OS << createSliceFromArchive(LLVMCtx, **ArchiveOrError).getArchString()
+           << " ";
         continue;
       }
       consumeError(ArchiveOrError.takeError());
@@ -435,21 +435,21 @@ static void printBinaryArchs(const Binary *Binary, raw_ostream &OS) {
 }
 
 [[noreturn]] static void
-printArchs(ArrayRef<OwningBinary<Binary>> InputBinaries) {
+printArchs(LLVMContext &LLVMCtx, ArrayRef<OwningBinary<Binary>> InputBinaries) {
   assert(InputBinaries.size() == 1 && "Incorrect number of input binaries");
-  printBinaryArchs(InputBinaries.front().getBinary(), outs());
+  printBinaryArchs(LLVMCtx, InputBinaries.front().getBinary(), outs());
   exit(EXIT_SUCCESS);
 }
 
 [[noreturn]] static void
-printInfo(ArrayRef<OwningBinary<Binary>> InputBinaries) {
+printInfo(LLVMContext &LLVMCtx, ArrayRef<OwningBinary<Binary>> InputBinaries) {
   // Group universal and thin files together for compatibility with cctools lipo
   for (auto &IB : InputBinaries) {
     const Binary *Binary = IB.getBinary();
     if (Binary->isMachOUniversalBinary()) {
       outs() << "Architectures in the fat file: " << Binary->getFileName()
              << " are: ";
-      printBinaryArchs(Binary, outs());
+      printBinaryArchs(LLVMCtx, Binary, outs());
     }
   }
   for (auto &IB : InputBinaries) {
@@ -458,13 +458,14 @@ printInfo(ArrayRef<OwningBinary<Binary>> InputBinaries) {
       assert(Binary->isMachO() && "expected MachO binary");
       outs() << "Non-fat file: " << Binary->getFileName()
              << " is architecture: ";
-      printBinaryArchs(Binary, outs());
+      printBinaryArchs(LLVMCtx, Binary, outs());
     }
   }
   exit(EXIT_SUCCESS);
 }
 
-[[noreturn]] static void thinSlice(ArrayRef<OwningBinary<Binary>> InputBinaries,
+[[noreturn]] static void thinSlice(LLVMContext &LLVMCtx,
+                                   ArrayRef<OwningBinary<Binary>> InputBinaries,
                                    StringRef ArchType,
                                    StringRef OutputFileName) {
   assert(!ArchType.empty() && "The architecture type should be non-empty");
@@ -552,7 +553,7 @@ static void checkUnusedAlignments(ArrayRef<Slice> Slices,
 // Updates vector ExtractedObjects with the MachOObjectFiles extracted from
 // Universal Binary files to transfer ownership.
 static SmallVector<Slice, 2>
-buildSlices(ArrayRef<OwningBinary<Binary>> InputBinaries,
+buildSlices(LLVMContext &LLVMCtx, ArrayRef<OwningBinary<Binary>> InputBinaries,
             const StringMap<const uint32_t> &Alignments,
             SmallVectorImpl<std::unique_ptr<SymbolicFile>> &ExtractedObjects) {
   SmallVector<Slice, 2> Slices;
@@ -583,7 +584,7 @@ buildSlices(ArrayRef<OwningBinary<Binary>> InputBinaries,
     } else if (const auto *O = dyn_cast<MachOObjectFile>(InputBinary)) {
       Slices.emplace_back(*O);
     } else if (const auto *A = dyn_cast<Archive>(InputBinary)) {
-      Slices.push_back(createSliceFromArchive(*A));
+      Slices.push_back(createSliceFromArchive(LLVMCtx, *A));
     } else if (const auto *IRO = dyn_cast<IRObjectFile>(InputBinary)) {
       // Original Apple's lipo set the alignment to 0
       Expected<Slice> SliceOrErr = Slice::create(*IRO, 0);
@@ -600,16 +601,15 @@ buildSlices(ArrayRef<OwningBinary<Binary>> InputBinaries,
   return Slices;
 }
 
-[[noreturn]] static void
-createUniversalBinary(ArrayRef<OwningBinary<Binary>> InputBinaries,
-                      const StringMap<const uint32_t> &Alignments,
-                      StringRef OutputFileName) {
+[[noreturn]] static void createUniversalBinary(
+    LLVMContext &LLVMCtx, ArrayRef<OwningBinary<Binary>> InputBinaries,
+    const StringMap<const uint32_t> &Alignments, StringRef OutputFileName) {
   assert(InputBinaries.size() >= 1 && "Incorrect number of input binaries");
   assert(!OutputFileName.empty() && "Create expects a single output file");
 
   SmallVector<std::unique_ptr<SymbolicFile>, 1> ExtractedObjects;
   SmallVector<Slice, 1> Slices =
-      buildSlices(InputBinaries, Alignments, ExtractedObjects);
+      buildSlices(LLVMCtx, InputBinaries, Alignments, ExtractedObjects);
   checkArchDuplicates(Slices);
   checkUnusedAlignments(Slices, Alignments);
 
@@ -621,7 +621,7 @@ createUniversalBinary(ArrayRef<OwningBinary<Binary>> InputBinaries,
 }
 
 [[noreturn]] static void
-extractSlice(ArrayRef<OwningBinary<Binary>> InputBinaries,
+extractSlice(LLVMContext &LLVMCtx, ArrayRef<OwningBinary<Binary>> InputBinaries,
              const StringMap<const uint32_t> &Alignments, StringRef ArchType,
              StringRef OutputFileName) {
   assert(!ArchType.empty() &&
@@ -637,7 +637,7 @@ extractSlice(ArrayRef<OwningBinary<Binary>> InputBinaries,
 
   SmallVector<std::unique_ptr<SymbolicFile>, 2> ExtractedObjects;
   SmallVector<Slice, 2> Slices =
-      buildSlices(InputBinaries, Alignments, ExtractedObjects);
+      buildSlices(LLVMCtx, InputBinaries, Alignments, ExtractedObjects);
   erase_if(Slices, [ArchType](const Slice &S) {
     return ArchType != S.getArchString();
   });
@@ -680,7 +680,8 @@ buildReplacementSlices(ArrayRef<OwningBinary<Binary>> ReplacementBinaries,
 }
 
 [[noreturn]] static void
-replaceSlices(ArrayRef<OwningBinary<Binary>> InputBinaries,
+replaceSlices(LLVMContext &LLVMCtx,
+              ArrayRef<OwningBinary<Binary>> InputBinaries,
               const StringMap<const uint32_t> &Alignments,
               StringRef OutputFileName, ArrayRef<InputFile> ReplacementFiles) {
   assert(InputBinaries.size() == 1 && "Incorrect number of input binaries");
@@ -692,13 +693,13 @@ replaceSlices(ArrayRef<OwningBinary<Binary>> InputBinaries,
                 " must be a fat file when the -replace option is specified");
 
   SmallVector<OwningBinary<Binary>, 1> ReplacementBinaries =
-      readInputBinaries(ReplacementFiles);
+      readInputBinaries(LLVMCtx, ReplacementFiles);
 
   StringMap<Slice> ReplacementSlices =
       buildReplacementSlices(ReplacementBinaries, Alignments);
   SmallVector<std::unique_ptr<SymbolicFile>, 2> ExtractedObjects;
   SmallVector<Slice, 2> Slices =
-      buildSlices(InputBinaries, Alignments, ExtractedObjects);
+      buildSlices(LLVMCtx, InputBinaries, Alignments, ExtractedObjects);
 
   for (auto &Slice : Slices) {
     auto It = ReplacementSlices.find(Slice.getArchString());
@@ -725,30 +726,33 @@ replaceSlices(ArrayRef<OwningBinary<Binary>> InputBinaries,
 int main(int argc, char **argv) {
   InitLLVM X(argc, argv);
   Config C = parseLipoOptions(makeArrayRef(argv + 1, argc));
+  LLVMContext LLVMCtx;
   SmallVector<OwningBinary<Binary>, 1> InputBinaries =
-      readInputBinaries(C.InputFiles);
+      readInputBinaries(LLVMCtx, C.InputFiles);
 
   switch (C.ActionToPerform) {
   case LipoAction::VerifyArch:
     verifyArch(InputBinaries, C.VerifyArchList);
     break;
   case LipoAction::PrintArchs:
-    printArchs(InputBinaries);
+    printArchs(LLVMCtx, InputBinaries);
     break;
   case LipoAction::PrintInfo:
-    printInfo(InputBinaries);
+    printInfo(LLVMCtx, InputBinaries);
     break;
   case LipoAction::ThinArch:
-    thinSlice(InputBinaries, C.ArchType, C.OutputFile);
+    thinSlice(LLVMCtx, InputBinaries, C.ArchType, C.OutputFile);
     break;
   case LipoAction::ExtractArch:
-    extractSlice(InputBinaries, C.SegmentAlignments, C.ArchType, C.OutputFile);
+    extractSlice(LLVMCtx, InputBinaries, C.SegmentAlignments, C.ArchType,
+                 C.OutputFile);
     break;
   case LipoAction::CreateUniversal:
-    createUniversalBinary(InputBinaries, C.SegmentAlignments, C.OutputFile);
+    createUniversalBinary(LLVMCtx, InputBinaries, C.SegmentAlignments,
+                          C.OutputFile);
     break;
   case LipoAction::ReplaceArch:
-    replaceSlices(InputBinaries, C.SegmentAlignments, C.OutputFile,
+    replaceSlices(LLVMCtx, InputBinaries, C.SegmentAlignments, C.OutputFile,
                   C.ReplacementFiles);
     break;
   }


        


More information about the llvm-commits mailing list