diff options
Diffstat (limited to 'tools')
| -rw-r--r-- | tools/llc/llc.cpp | 4 | ||||
| -rw-r--r-- | tools/llvm-cvtres/CMakeLists.txt | 1 | ||||
| -rw-r--r-- | tools/llvm-cvtres/llvm-cvtres.cpp | 100 | ||||
| -rw-r--r-- | tools/llvm-cvtres/llvm-cvtres.h | 6 | ||||
| -rw-r--r-- | tools/llvm-dwp/llvm-dwp.cpp | 2 | ||||
| -rw-r--r-- | tools/llvm-lto/llvm-lto.cpp | 24 | ||||
| -rw-r--r-- | tools/llvm-pdbdump/Analyze.cpp | 1 | ||||
| -rw-r--r-- | tools/llvm-pdbdump/CompactTypeDumpVisitor.cpp | 10 | ||||
| -rw-r--r-- | tools/llvm-pdbdump/CompactTypeDumpVisitor.h | 8 | ||||
| -rw-r--r-- | tools/llvm-pdbdump/LLVMOutputStyle.cpp | 119 | ||||
| -rw-r--r-- | tools/llvm-pdbdump/LLVMOutputStyle.h | 12 | ||||
| -rw-r--r-- | tools/llvm-pdbdump/PdbYaml.cpp | 2 | ||||
| -rw-r--r-- | tools/llvm-pdbdump/YAMLOutputStyle.h | 1 | ||||
| -rw-r--r-- | tools/llvm-pdbdump/YamlTypeDumper.cpp | 1 | ||||
| -rw-r--r-- | tools/llvm-pdbdump/llvm-pdbdump.cpp | 86 | ||||
| -rw-r--r-- | tools/llvm-readobj/COFFDumper.cpp | 99 | ||||
| -rw-r--r-- | tools/opt/opt.cpp | 12 |
17 files changed, 323 insertions, 165 deletions
diff --git a/tools/llc/llc.cpp b/tools/llc/llc.cpp index 8c786950036f..589005943045 100644 --- a/tools/llc/llc.cpp +++ b/tools/llc/llc.cpp @@ -356,9 +356,7 @@ static bool addPass(PassManagerBase &PM, const char *argv0, } Pass *P; - if (PI->getTargetMachineCtor()) - P = PI->getTargetMachineCtor()(&TPC.getTM<TargetMachine>()); - else if (PI->getNormalCtor()) + if (PI->getNormalCtor()) P = PI->getNormalCtor()(); else { errs() << argv0 << ": cannot create pass: " << PI->getPassName() << "\n"; diff --git a/tools/llvm-cvtres/CMakeLists.txt b/tools/llvm-cvtres/CMakeLists.txt index 52edccac8165..e912030e205e 100644 --- a/tools/llvm-cvtres/CMakeLists.txt +++ b/tools/llvm-cvtres/CMakeLists.txt @@ -1,4 +1,5 @@ set(LLVM_LINK_COMPONENTS + Object Option Support ) diff --git a/tools/llvm-cvtres/llvm-cvtres.cpp b/tools/llvm-cvtres/llvm-cvtres.cpp index f03e0b772e1b..96f7437ab5f6 100644 --- a/tools/llvm-cvtres/llvm-cvtres.cpp +++ b/tools/llvm-cvtres/llvm-cvtres.cpp @@ -14,17 +14,23 @@ #include "llvm-cvtres.h" +#include "llvm/ADT/StringSwitch.h" +#include "llvm/Object/Binary.h" +#include "llvm/Object/WindowsResource.h" #include "llvm/Option/Arg.h" #include "llvm/Option/ArgList.h" #include "llvm/Option/Option.h" +#include "llvm/Support/BinaryStreamError.h" #include "llvm/Support/Error.h" #include "llvm/Support/ManagedStatic.h" +#include "llvm/Support/Path.h" #include "llvm/Support/PrettyStackTrace.h" #include "llvm/Support/Process.h" #include "llvm/Support/Signals.h" #include "llvm/Support/raw_ostream.h" using namespace llvm; +using namespace object; namespace { @@ -61,6 +67,28 @@ public: static ExitOnError ExitOnErr; } +LLVM_ATTRIBUTE_NORETURN void reportError(Twine Msg) { + errs() << Msg; + exit(1); +} + +static void reportError(StringRef Input, std::error_code EC) { + reportError(Twine(Input) + ": " + EC.message() + ".\n"); +} + +void error(std::error_code EC) { + if (!EC) + return; + reportError(EC.message() + ".\n"); +} + +void error(Error EC) { + if (!EC) + return; + handleAllErrors(std::move(EC), + [&](const ErrorInfoBase &EI) { reportError(EI.message()); }); +} + int main(int argc_, const char *argv_[]) { sys::PrintStackTraceOnErrorSignal(argv_[0]); PrettyStackTraceProgram X(argc_, argv_); @@ -76,11 +104,79 @@ int main(int argc_, const char *argv_[]) { CvtResOptTable T; unsigned MAI, MAC; - ArrayRef<const char *> ArgsArr = makeArrayRef(argv_, argc_); + ArrayRef<const char *> ArgsArr = makeArrayRef(argv_ + 1, argc_); opt::InputArgList InputArgs = T.ParseArgs(ArgsArr, MAI, MAC); - if (InputArgs.hasArg(OPT_HELP)) + if (InputArgs.hasArg(OPT_HELP)) { T.PrintHelp(outs(), "cvtres", "Resource Converter", false); + return 0; + } + + machine Machine; + + if (InputArgs.hasArg(OPT_MACHINE)) { + std::string MachineString = InputArgs.getLastArgValue(OPT_MACHINE).upper(); + Machine = StringSwitch<machine>(MachineString) + .Case("ARM", machine::ARM) + .Case("X64", machine::X64) + .Case("X86", machine::X86) + .Default(machine::UNKNOWN); + if (Machine == machine::UNKNOWN) + reportError("Unsupported machine architecture"); + } else { + outs() << "Machine architecture not specified; assumed X64.\n"; + Machine = machine::X64; + } + + std::vector<std::string> InputFiles = InputArgs.getAllArgValues(OPT_INPUT); + + if (InputFiles.size() == 0) { + reportError("No input file specified"); + } + + SmallString<128> OutputFile; + + if (InputArgs.hasArg(OPT_OUT)) { + OutputFile = InputArgs.getLastArgValue(OPT_OUT); + } else { + OutputFile = StringRef(InputFiles[0]); + llvm::sys::path::replace_extension(OutputFile, ".obj"); + } + + for (const auto &File : InputFiles) { + Expected<object::OwningBinary<object::Binary>> BinaryOrErr = + object::createBinary(File); + if (!BinaryOrErr) + reportError(File, errorToErrorCode(BinaryOrErr.takeError())); + + Binary &Binary = *BinaryOrErr.get().getBinary(); + + WindowsResource *RF = dyn_cast<WindowsResource>(&Binary); + if (!RF) + reportError(File + ": unrecognized file format.\n"); + int EntryNumber = 0; + Expected<ResourceEntryRef> EntryOrErr = RF->getHeadEntry(); + if (!EntryOrErr) + error(EntryOrErr.takeError()); + ResourceEntryRef Entry = EntryOrErr.get(); + bool End = false; + while (!End) { + error(Entry.moveNext(End)); + EntryNumber++; + } + outs() << "Number of resources: " << EntryNumber << "\n"; + } + outs() << "Machine: "; + switch (Machine) { + case machine::ARM: + outs() << "ARM\n"; + break; + case machine::X86: + outs() << "X86\n"; + break; + default: + outs() << "X64\n"; + } return 0; } diff --git a/tools/llvm-cvtres/llvm-cvtres.h b/tools/llvm-cvtres/llvm-cvtres.h index eeaba1969036..2e45b66461f0 100644 --- a/tools/llvm-cvtres/llvm-cvtres.h +++ b/tools/llvm-cvtres/llvm-cvtres.h @@ -10,4 +10,10 @@ #ifndef LLVM_TOOLS_LLVMCVTRES_LLVMCVTRES_H #define LLVM_TOOLS_LLVMCVTRES_LLVMCVTRES_H +#include <system_error> + +void error(std::error_code EC); + +enum class machine { UNKNOWN = 0, ARM, X64, X86 }; + #endif diff --git a/tools/llvm-dwp/llvm-dwp.cpp b/tools/llvm-dwp/llvm-dwp.cpp index 0c4af7576608..f8d00b3b5534 100644 --- a/tools/llvm-dwp/llvm-dwp.cpp +++ b/tools/llvm-dwp/llvm-dwp.cpp @@ -373,7 +373,7 @@ handleCompressedSection(std::deque<SmallString<32>> &UncompressedSections, return createError(Name, Dec.takeError()); UncompressedSections.emplace_back(); - if (Error E = Dec->decompress(UncompressedSections.back())) + if (Error E = Dec->resizeAndDecompress(UncompressedSections.back())) return createError(Name, std::move(E)); Name = Name.substr(2); // Drop ".z" diff --git a/tools/llvm-lto/llvm-lto.cpp b/tools/llvm-lto/llvm-lto.cpp index 2458d3d123ca..ccc673be4570 100644 --- a/tools/llvm-lto/llvm-lto.cpp +++ b/tools/llvm-lto/llvm-lto.cpp @@ -669,24 +669,30 @@ private: if (!ThinLTOIndex.empty()) errs() << "Warning: -thinlto-index ignored for codegen stage"; + std::vector<std::unique_ptr<MemoryBuffer>> InputBuffers; for (auto &Filename : InputFilenames) { LLVMContext Ctx; - auto TheModule = loadModule(Filename, Ctx); - - auto Buffer = ThinGenerator.codegen(*TheModule); + auto InputOrErr = MemoryBuffer::getFile(Filename); + error(InputOrErr, "error " + CurrentActivity); + InputBuffers.push_back(std::move(*InputOrErr)); + ThinGenerator.addModule(Filename, InputBuffers.back()->getBuffer()); + } + ThinGenerator.setCodeGenOnly(true); + ThinGenerator.run(); + for (auto BinName : + zip(ThinGenerator.getProducedBinaries(), InputFilenames)) { std::string OutputName = OutputFilename; - if (OutputName.empty()) { - OutputName = Filename + ".thinlto.o"; - } - if (OutputName == "-") { - outs() << Buffer->getBuffer(); + if (OutputName.empty()) + OutputName = std::get<1>(BinName) + ".thinlto.o"; + else if (OutputName == "-") { + outs() << std::get<0>(BinName)->getBuffer(); return; } std::error_code EC; raw_fd_ostream OS(OutputName, EC, sys::fs::OpenFlags::F_None); error(EC, "error opening the file '" + OutputName + "'"); - OS << Buffer->getBuffer(); + OS << std::get<0>(BinName)->getBuffer(); } } diff --git a/tools/llvm-pdbdump/Analyze.cpp b/tools/llvm-pdbdump/Analyze.cpp index ab4477ed7bad..3a026e5d2451 100644 --- a/tools/llvm-pdbdump/Analyze.cpp +++ b/tools/llvm-pdbdump/Analyze.cpp @@ -14,7 +14,6 @@ #include "llvm/DebugInfo/CodeView/CVTypeVisitor.h" #include "llvm/DebugInfo/CodeView/TypeDatabase.h" #include "llvm/DebugInfo/CodeView/TypeDatabaseVisitor.h" -#include "llvm/DebugInfo/CodeView/TypeDeserializer.h" #include "llvm/DebugInfo/CodeView/TypeRecord.h" #include "llvm/DebugInfo/CodeView/TypeVisitorCallbackPipeline.h" #include "llvm/DebugInfo/CodeView/TypeVisitorCallbacks.h" diff --git a/tools/llvm-pdbdump/CompactTypeDumpVisitor.cpp b/tools/llvm-pdbdump/CompactTypeDumpVisitor.cpp index 5ad0bfad26c1..3b609ae50c1c 100644 --- a/tools/llvm-pdbdump/CompactTypeDumpVisitor.cpp +++ b/tools/llvm-pdbdump/CompactTypeDumpVisitor.cpp @@ -29,15 +29,15 @@ static StringRef getLeafName(TypeLeafKind K) { return StringRef(); } -CompactTypeDumpVisitor::CompactTypeDumpVisitor(TypeDatabase &TypeDB, +CompactTypeDumpVisitor::CompactTypeDumpVisitor(TypeCollection &Types, ScopedPrinter *W) - : CompactTypeDumpVisitor(TypeDB, TypeIndex(TypeIndex::FirstNonSimpleIndex), + : CompactTypeDumpVisitor(Types, TypeIndex(TypeIndex::FirstNonSimpleIndex), W) {} -CompactTypeDumpVisitor::CompactTypeDumpVisitor(TypeDatabase &TypeDB, +CompactTypeDumpVisitor::CompactTypeDumpVisitor(TypeCollection &Types, TypeIndex FirstTI, ScopedPrinter *W) - : W(W), TI(FirstTI), Offset(0), TypeDB(TypeDB) {} + : W(W), TI(FirstTI), Offset(0), Types(Types) {} Error CompactTypeDumpVisitor::visitTypeBegin(CVType &Record) { return Error::success(); @@ -46,7 +46,7 @@ Error CompactTypeDumpVisitor::visitTypeBegin(CVType &Record) { Error CompactTypeDumpVisitor::visitTypeEnd(CVType &Record) { uint32_t I = TI.getIndex(); StringRef Leaf = getLeafName(Record.Type); - StringRef Name = TypeDB.getTypeName(TI); + StringRef Name = Types.getTypeName(TI); W->printString( llvm::formatv("Index: {0:x} ({1:N} bytes, offset {2:N}) {3} \"{4}\"", I, Record.length(), Offset, Leaf, Name) diff --git a/tools/llvm-pdbdump/CompactTypeDumpVisitor.h b/tools/llvm-pdbdump/CompactTypeDumpVisitor.h index 76fafc93e030..41ccea0c2e90 100644 --- a/tools/llvm-pdbdump/CompactTypeDumpVisitor.h +++ b/tools/llvm-pdbdump/CompactTypeDumpVisitor.h @@ -17,7 +17,7 @@ namespace llvm { class ScopedPrinter; namespace codeview { -class TypeDatabase; +class TypeCollection; } namespace pdb { @@ -26,8 +26,8 @@ namespace pdb { /// Dumps records on a single line, and ignores member records. class CompactTypeDumpVisitor : public codeview::TypeVisitorCallbacks { public: - CompactTypeDumpVisitor(codeview::TypeDatabase &TypeDB, ScopedPrinter *W); - CompactTypeDumpVisitor(codeview::TypeDatabase &TypeDB, + CompactTypeDumpVisitor(codeview::TypeCollection &Types, ScopedPrinter *W); + CompactTypeDumpVisitor(codeview::TypeCollection &Types, codeview::TypeIndex FirstTI, ScopedPrinter *W); /// Paired begin/end actions for all types. Receives all record data, @@ -40,7 +40,7 @@ private: codeview::TypeIndex TI; uint32_t Offset; - codeview::TypeDatabase &TypeDB; + codeview::TypeCollection &Types; }; } // end namespace pdb diff --git a/tools/llvm-pdbdump/LLVMOutputStyle.cpp b/tools/llvm-pdbdump/LLVMOutputStyle.cpp index c4fecb80ea5a..07d3b226d7c6 100644 --- a/tools/llvm-pdbdump/LLVMOutputStyle.cpp +++ b/tools/llvm-pdbdump/LLVMOutputStyle.cpp @@ -14,9 +14,9 @@ #include "StreamUtil.h" #include "llvm-pdbdump.h" -#include "llvm/DebugInfo/CodeView/CVTypeDumper.h" #include "llvm/DebugInfo/CodeView/CVTypeVisitor.h" #include "llvm/DebugInfo/CodeView/EnumTables.h" +#include "llvm/DebugInfo/CodeView/LazyRandomTypeCollection.h" #include "llvm/DebugInfo/CodeView/Line.h" #include "llvm/DebugInfo/CodeView/ModuleDebugFileChecksumFragment.h" #include "llvm/DebugInfo/CodeView/ModuleDebugFragmentVisitor.h" @@ -25,7 +25,6 @@ #include "llvm/DebugInfo/CodeView/ModuleDebugUnknownFragment.h" #include "llvm/DebugInfo/CodeView/SymbolDumper.h" #include "llvm/DebugInfo/CodeView/TypeDatabaseVisitor.h" -#include "llvm/DebugInfo/CodeView/TypeDeserializer.h" #include "llvm/DebugInfo/CodeView/TypeDumpVisitor.h" #include "llvm/DebugInfo/CodeView/TypeVisitorCallbackPipeline.h" #include "llvm/DebugInfo/MSF/MappedBlockStream.h" @@ -84,7 +83,7 @@ struct PageStats { class C13RawVisitor : public C13DebugFragmentVisitor { public: - C13RawVisitor(ScopedPrinter &P, PDBFile &F, TypeDatabase &IPI) + C13RawVisitor(ScopedPrinter &P, PDBFile &F, LazyRandomTypeCollection &IPI) : C13DebugFragmentVisitor(F), P(P), IPI(IPI) {} Error handleLines() override { @@ -160,7 +159,7 @@ public: if (auto EC = printFileName("FileName", L.Header->FileID)) return EC; - if (auto EC = dumpTypeRecord("Function", IPI, L.Header->Inlinee)) + if (auto EC = dumpTypeRecord("Function", L.Header->Inlinee)) return EC; P.printNumber("SourceLine", L.Header->SourceLineNum); if (IL.hasExtraFiles()) { @@ -176,11 +175,11 @@ public: } private: - Error dumpTypeRecord(StringRef Label, TypeDatabase &DB, TypeIndex Index) { - CompactTypeDumpVisitor CTDV(DB, Index, &P); + Error dumpTypeRecord(StringRef Label, TypeIndex Index) { + CompactTypeDumpVisitor CTDV(IPI, Index, &P); DictScope D(P, Label); - if (DB.contains(Index)) { - CVType &Type = DB.getTypeRecord(Index); + if (IPI.contains(Index)) { + CVType Type = IPI.getType(Index); if (auto EC = codeview::visitTypeRecord(Type, CTDV)) return EC; } else { @@ -199,7 +198,7 @@ private: } ScopedPrinter &P; - TypeDatabase &IPI; + LazyRandomTypeCollection &IPI; }; } @@ -609,14 +608,19 @@ Error LLVMOutputStyle::dumpTpiStream(uint32_t StreamIdx) { VerLabel = "IPI Version"; } - if (!DumpRecordBytes && !DumpRecords && !DumpTpiHash) - return Error::success(); - auto Tpi = (StreamIdx == StreamTPI) ? File.getPDBTpiStream() : File.getPDBIpiStream(); if (!Tpi) return Tpi.takeError(); + auto ExpectedTypes = initializeTypeDatabase(StreamIdx); + if (!ExpectedTypes) + return ExpectedTypes.takeError(); + auto &Types = *ExpectedTypes; + + if (!DumpRecordBytes && !DumpRecords && !DumpTpiHash) + return Error::success(); + std::unique_ptr<DictScope> StreamScope; std::unique_ptr<ListScope> RecordScope; @@ -624,25 +628,19 @@ Error LLVMOutputStyle::dumpTpiStream(uint32_t StreamIdx) { P.printNumber(VerLabel, Tpi->getTpiVersion()); P.printNumber("Record count", Tpi->getNumTypeRecords()); - Optional<TypeDatabase> &StreamDB = (StreamIdx == StreamTPI) ? TypeDB : ItemDB; - std::vector<std::unique_ptr<TypeVisitorCallbacks>> Visitors; - if (!StreamDB.hasValue()) { - StreamDB.emplace(Tpi->getNumTypeRecords()); - Visitors.push_back(make_unique<TypeDatabaseVisitor>(*StreamDB)); - } // If we're in dump mode, add a dumper with the appropriate detail level. if (DumpRecords) { std::unique_ptr<TypeVisitorCallbacks> Dumper; if (opts::raw::CompactRecords) - Dumper = make_unique<CompactTypeDumpVisitor>(*StreamDB, &P); + Dumper = make_unique<CompactTypeDumpVisitor>(Types, &P); else { - assert(TypeDB.hasValue()); + assert(TpiTypes); - auto X = make_unique<TypeDumpVisitor>(*TypeDB, &P, false); + auto X = make_unique<TypeDumpVisitor>(*TpiTypes, &P, false); if (StreamIdx == StreamIPI) - X->setItemDB(*ItemDB); + X->setIpiTypes(*IpiTypes); Dumper = std::move(X); } Visitors.push_back(std::move(Dumper)); @@ -660,23 +658,18 @@ Error LLVMOutputStyle::dumpTpiStream(uint32_t StreamIdx) { if (DumpRecords || DumpRecordBytes) RecordScope = llvm::make_unique<ListScope>(P, "Records"); - bool HadError = false; - - TypeIndex T(TypeIndex::FirstNonSimpleIndex); - for (auto Type : Tpi->types(&HadError)) { + Optional<TypeIndex> I = Types.getFirst(); + while (I) { std::unique_ptr<DictScope> OneRecordScope; if ((DumpRecords || DumpRecordBytes) && !opts::raw::CompactRecords) OneRecordScope = llvm::make_unique<DictScope>(P, ""); - if (auto EC = codeview::visitTypeRecord(Type, Pipeline)) + auto T = Types.getType(*I); + if (auto EC = codeview::visitTypeRecord(T, *I, Pipeline)) return EC; - - ++T; + I = Types.getNext(*I); } - if (HadError) - return make_error<RawError>(raw_error_code::corrupt_file, - "TPI stream contained corrupt record"); if (DumpTpiHash) { DictScope DD(P, "Hash"); @@ -711,35 +704,26 @@ Error LLVMOutputStyle::dumpTpiStream(uint32_t StreamIdx) { return Error::success(); } -Error LLVMOutputStyle::buildTypeDatabase(uint32_t SN) { - assert(SN == StreamIPI || SN == StreamTPI); - - auto &DB = (SN == StreamIPI) ? ItemDB : TypeDB; - - if (DB.hasValue()) - return Error::success(); - +Expected<codeview::LazyRandomTypeCollection &> +LLVMOutputStyle::initializeTypeDatabase(uint32_t SN) { + auto &TypeCollection = (SN == StreamTPI) ? TpiTypes : IpiTypes; auto Tpi = (SN == StreamTPI) ? File.getPDBTpiStream() : File.getPDBIpiStream(); - if (!Tpi) return Tpi.takeError(); - DB.emplace(Tpi->getNumTypeRecords()); - - TypeDatabaseVisitor DBV(*DB); - - auto HashValues = Tpi->getHashValues(); - if (HashValues.empty()) - return codeview::visitTypeStream(Tpi->typeArray(), DBV); - - TypeVisitorCallbackPipeline Pipeline; - Pipeline.addCallbackToPipeline(DBV); - - TpiHashVerifier HashVerifier(HashValues, Tpi->getNumHashBuckets()); - Pipeline.addCallbackToPipeline(HashVerifier); + if (!TypeCollection) { + // Initialize the type collection, even if we're not going to dump it. This + // way if some other part of the dumper decides it wants to use some or all + // of the records for whatever purposes, it can still access them lazily. + auto &Types = Tpi->typeArray(); + uint32_t Count = Tpi->getNumTypeRecords(); + auto Offsets = Tpi->getTypeIndexOffsets(); + TypeCollection = + llvm::make_unique<LazyRandomTypeCollection>(Types, Count, Offsets); + } - return codeview::visitTypeStream(Tpi->typeArray(), Pipeline); + return *TypeCollection; } Error LLVMOutputStyle::dumpDbiStream() { @@ -814,11 +798,13 @@ Error LLVMOutputStyle::dumpDbiStream() { return EC; if (ShouldDumpSymbols) { - if (auto EC = buildTypeDatabase(StreamTPI)) - return EC; + auto ExpectedTypes = initializeTypeDatabase(StreamTPI); + if (!ExpectedTypes) + return ExpectedTypes.takeError(); + auto &Types = *ExpectedTypes; ListScope SS(P, "Symbols"); - codeview::CVSymbolDumper SD(P, *TypeDB, nullptr, false); + codeview::CVSymbolDumper SD(P, Types, nullptr, false); bool HadError = false; for (auto S : ModS.symbols(&HadError)) { DictScope LL(P, ""); @@ -839,10 +825,11 @@ Error LLVMOutputStyle::dumpDbiStream() { } if (opts::raw::DumpLineInfo) { ListScope SS(P, "LineInfo"); - if (auto EC = buildTypeDatabase(StreamIPI)) - return EC; - - C13RawVisitor V(P, File, *ItemDB); + auto ExpectedTypes = initializeTypeDatabase(StreamIPI); + if (!ExpectedTypes) + return ExpectedTypes.takeError(); + auto &IpiItems = *ExpectedTypes; + C13RawVisitor V(P, File, IpiItems); if (auto EC = codeview::visitModuleDebugFragments( ModS.linesAndChecksums(), V)) return EC; @@ -960,10 +947,12 @@ Error LLVMOutputStyle::dumpPublicsStream() { P.printList("Section Offsets", Publics->getSectionOffsets(), printSectionOffset); ListScope L(P, "Symbols"); - if (auto EC = buildTypeDatabase(StreamTPI)) - return EC; + auto ExpectedTypes = initializeTypeDatabase(StreamTPI); + if (!ExpectedTypes) + return ExpectedTypes.takeError(); + auto &Tpi = *ExpectedTypes; - codeview::CVSymbolDumper SD(P, *TypeDB, nullptr, false); + codeview::CVSymbolDumper SD(P, Tpi, nullptr, false); bool HadError = false; for (auto S : Publics->getSymbols(&HadError)) { DictScope DD(P, ""); diff --git a/tools/llvm-pdbdump/LLVMOutputStyle.h b/tools/llvm-pdbdump/LLVMOutputStyle.h index b0e7e3406b36..184dc4e1f44d 100644 --- a/tools/llvm-pdbdump/LLVMOutputStyle.h +++ b/tools/llvm-pdbdump/LLVMOutputStyle.h @@ -21,6 +21,11 @@ namespace llvm { class BitVector; + +namespace codeview { +class LazyRandomTypeCollection; +} + namespace pdb { class LLVMOutputStyle : public OutputStyle { public: @@ -29,7 +34,8 @@ public: Error dump() override; private: - Error buildTypeDatabase(uint32_t SN); + Expected<codeview::LazyRandomTypeCollection &> + initializeTypeDatabase(uint32_t SN); Error dumpFileHeaders(); Error dumpStreamSummary(); @@ -54,8 +60,8 @@ private: PDBFile &File; ScopedPrinter P; - Optional<codeview::TypeDatabase> TypeDB; - Optional<codeview::TypeDatabase> ItemDB; + std::unique_ptr<codeview::LazyRandomTypeCollection> TpiTypes; + std::unique_ptr<codeview::LazyRandomTypeCollection> IpiTypes; SmallVector<std::string, 32> StreamPurposes; }; } diff --git a/tools/llvm-pdbdump/PdbYaml.cpp b/tools/llvm-pdbdump/PdbYaml.cpp index 6527bec31a77..dd32eca14c1d 100644 --- a/tools/llvm-pdbdump/PdbYaml.cpp +++ b/tools/llvm-pdbdump/PdbYaml.cpp @@ -19,7 +19,6 @@ #include "llvm/DebugInfo/CodeView/SymbolDeserializer.h" #include "llvm/DebugInfo/CodeView/SymbolSerializer.h" #include "llvm/DebugInfo/CodeView/SymbolVisitorCallbackPipeline.h" -#include "llvm/DebugInfo/CodeView/TypeDeserializer.h" #include "llvm/DebugInfo/CodeView/TypeSerializer.h" #include "llvm/DebugInfo/CodeView/TypeVisitorCallbackPipeline.h" #include "llvm/DebugInfo/PDB/Native/PDBFile.h" @@ -371,7 +370,6 @@ void MappingContextTraits<PdbInlineeInfo, SerializationContext>::mapping( void MappingContextTraits<PdbTpiRecord, pdb::yaml::SerializationContext>:: mapping(IO &IO, pdb::yaml::PdbTpiRecord &Obj, pdb::yaml::SerializationContext &Context) { - if (IO.outputting()) { // For PDB to Yaml, deserialize into a high level record type, then dump it. consumeError(codeview::visitTypeRecord(Obj.Record, Context.Dumper)); diff --git a/tools/llvm-pdbdump/YAMLOutputStyle.h b/tools/llvm-pdbdump/YAMLOutputStyle.h index 517c7d86d7ab..068312aec450 100644 --- a/tools/llvm-pdbdump/YAMLOutputStyle.h +++ b/tools/llvm-pdbdump/YAMLOutputStyle.h @@ -13,7 +13,6 @@ #include "OutputStyle.h" #include "PdbYaml.h" -#include "llvm/DebugInfo/CodeView/CVTypeDumper.h" #include "llvm/Support/ScopedPrinter.h" #include "llvm/Support/YAMLTraits.h" diff --git a/tools/llvm-pdbdump/YamlTypeDumper.cpp b/tools/llvm-pdbdump/YamlTypeDumper.cpp index 3e447ca60b61..beb700720954 100644 --- a/tools/llvm-pdbdump/YamlTypeDumper.cpp +++ b/tools/llvm-pdbdump/YamlTypeDumper.cpp @@ -13,7 +13,6 @@ #include "llvm/DebugInfo/CodeView/CVTypeVisitor.h" #include "llvm/DebugInfo/CodeView/EnumTables.h" -#include "llvm/DebugInfo/CodeView/TypeDeserializer.h" #include "llvm/DebugInfo/CodeView/TypeRecord.h" #include "llvm/DebugInfo/CodeView/TypeSerializer.h" #include "llvm/DebugInfo/CodeView/TypeVisitorCallbackPipeline.h" diff --git a/tools/llvm-pdbdump/llvm-pdbdump.cpp b/tools/llvm-pdbdump/llvm-pdbdump.cpp index 0e5913fa3c93..1767c3cfda85 100644 --- a/tools/llvm-pdbdump/llvm-pdbdump.cpp +++ b/tools/llvm-pdbdump/llvm-pdbdump.cpp @@ -31,9 +31,12 @@ #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/StringExtras.h" #include "llvm/Config/config.h" +#include "llvm/DebugInfo/CodeView/LazyRandomTypeCollection.h" #include "llvm/DebugInfo/CodeView/ModuleDebugFileChecksumFragment.h" #include "llvm/DebugInfo/CodeView/ModuleDebugInlineeLinesFragment.h" #include "llvm/DebugInfo/CodeView/ModuleDebugLineFragment.h" +#include "llvm/DebugInfo/CodeView/TypeStreamMerger.h" +#include "llvm/DebugInfo/CodeView/TypeTableBuilder.h" #include "llvm/DebugInfo/MSF/MSFBuilder.h" #include "llvm/DebugInfo/PDB/GenericError.h" #include "llvm/DebugInfo/PDB/IPDBEnumChildren.h" @@ -67,6 +70,7 @@ #include "llvm/Support/Format.h" #include "llvm/Support/ManagedStatic.h" #include "llvm/Support/MemoryBuffer.h" +#include "llvm/Support/Path.h" #include "llvm/Support/PrettyStackTrace.h" #include "llvm/Support/Process.h" #include "llvm/Support/Regex.h" @@ -99,6 +103,9 @@ cl::SubCommand AnalyzeSubcommand("analyze", "Analyze various aspects of a PDB's structure"); +cl::SubCommand MergeSubcommand("merge", + "Merge multiple PDBs into a single PDB"); + cl::OptionCategory TypeCategory("Symbol Type Options"); cl::OptionCategory FilterCategory("Filtering and Sorting Options"); cl::OptionCategory OtherOptions("Other Options"); @@ -365,9 +372,9 @@ cl::opt<std::string> YamlPdbOutputFile("pdb", cl::desc("the name of the PDB file to write"), cl::sub(YamlToPdbSubcommand)); -cl::list<std::string> InputFilename(cl::Positional, - cl::desc("<input YAML file>"), cl::Required, - cl::sub(YamlToPdbSubcommand)); +cl::opt<std::string> InputFilename(cl::Positional, + cl::desc("<input YAML file>"), cl::Required, + cl::sub(YamlToPdbSubcommand)); } namespace pdb2yaml { @@ -440,6 +447,15 @@ cl::list<std::string> InputFilename(cl::Positional, cl::desc("<input PDB file>"), cl::Required, cl::sub(AnalyzeSubcommand)); } + +namespace merge { +cl::list<std::string> InputFilenames(cl::Positional, + cl::desc("<input PDB files>"), + cl::OneOrMore, cl::sub(MergeSubcommand)); +cl::opt<std::string> + PdbOutputFile("pdb", cl::desc("the name of the PDB file to write"), + cl::sub(MergeSubcommand)); +} } static ExitOnError ExitOnErr; @@ -827,6 +843,57 @@ static void dumpPretty(StringRef Path) { outs().flush(); } +static void mergePdbs() { + BumpPtrAllocator Allocator; + TypeTableBuilder MergedTpi(Allocator); + TypeTableBuilder MergedIpi(Allocator); + + // Create a Tpi and Ipi type table with all types from all input files. + for (const auto &Path : opts::merge::InputFilenames) { + std::unique_ptr<IPDBSession> Session; + auto &File = loadPDB(Path, Session); + SmallVector<TypeIndex, 128> SourceToDest; + if (File.hasPDBTpiStream()) { + SourceToDest.clear(); + auto &Tpi = ExitOnErr(File.getPDBTpiStream()); + ExitOnErr(codeview::mergeTypeStreams(MergedIpi, MergedTpi, SourceToDest, + nullptr, Tpi.typeArray())); + } + if (File.hasPDBIpiStream()) { + SourceToDest.clear(); + auto &Ipi = ExitOnErr(File.getPDBIpiStream()); + ExitOnErr(codeview::mergeTypeStreams(MergedIpi, MergedTpi, SourceToDest, + nullptr, Ipi.typeArray())); + } + } + + // Then write the PDB. + PDBFileBuilder Builder(Allocator); + ExitOnErr(Builder.initialize(4096)); + // Add each of the reserved streams. We might not put any data in them, + // but at least they have to be present. + for (uint32_t I = 0; I < kSpecialStreamCount; ++I) + ExitOnErr(Builder.getMsfBuilder().addStream(0)); + + auto &DestTpi = Builder.getTpiBuilder(); + auto &DestIpi = Builder.getIpiBuilder(); + MergedTpi.ForEachRecord( + [&DestTpi](TypeIndex TI, MutableArrayRef<uint8_t> Data) { + DestTpi.addTypeRecord(Data, None); + }); + MergedIpi.ForEachRecord( + [&DestIpi](TypeIndex TI, MutableArrayRef<uint8_t> Data) { + DestIpi.addTypeRecord(Data, None); + }); + + SmallString<64> OutFile(opts::merge::PdbOutputFile); + if (OutFile.empty()) { + OutFile = opts::merge::InputFilenames[0]; + llvm::sys::path::replace_extension(OutFile, "merged.pdb"); + } + ExitOnErr(Builder.commit(OutFile)); +} + int main(int argc_, const char *argv_[]) { // Print a stack trace if we signal out. sys::PrintStackTraceOnErrorSignal(argv_[0]); @@ -894,7 +961,12 @@ int main(int argc_, const char *argv_[]) { if (opts::PdbToYamlSubcommand) { pdb2Yaml(opts::pdb2yaml::InputFilename.front()); } else if (opts::YamlToPdbSubcommand) { - yamlToPdb(opts::yaml2pdb::InputFilename.front()); + if (opts::yaml2pdb::YamlPdbOutputFile.empty()) { + SmallString<16> OutputFilename(opts::yaml2pdb::InputFilename.getValue()); + sys::path::replace_extension(OutputFilename, ".pdb"); + opts::yaml2pdb::YamlPdbOutputFile = OutputFilename.str(); + } + yamlToPdb(opts::yaml2pdb::InputFilename); } else if (opts::AnalyzeSubcommand) { dumpAnalysis(opts::analyze::InputFilename.front()); } else if (opts::PrettySubcommand) { @@ -943,6 +1015,12 @@ int main(int argc_, const char *argv_[]) { exit(1); } diff(opts::diff::InputFilenames[0], opts::diff::InputFilenames[1]); + } else if (opts::MergeSubcommand) { + if (opts::merge::InputFilenames.size() < 2) { + errs() << "merge subcommand requires at least 2 input files.\n"; + exit(1); + } + mergePdbs(); } outs().flush(); diff --git a/tools/llvm-readobj/COFFDumper.cpp b/tools/llvm-readobj/COFFDumper.cpp index aca7de840d80..78bfa558e4a3 100644 --- a/tools/llvm-readobj/COFFDumper.cpp +++ b/tools/llvm-readobj/COFFDumper.cpp @@ -22,8 +22,9 @@ #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/SmallString.h" #include "llvm/ADT/StringExtras.h" -#include "llvm/DebugInfo/CodeView/CVTypeDumper.h" +#include "llvm/DebugInfo/CodeView/CVTypeVisitor.h" #include "llvm/DebugInfo/CodeView/CodeView.h" +#include "llvm/DebugInfo/CodeView/LazyRandomTypeCollection.h" #include "llvm/DebugInfo/CodeView/Line.h" #include "llvm/DebugInfo/CodeView/ModuleDebugFileChecksumFragment.h" #include "llvm/DebugInfo/CodeView/ModuleDebugInlineeLinesFragment.h" @@ -34,19 +35,20 @@ #include "llvm/DebugInfo/CodeView/SymbolDumpDelegate.h" #include "llvm/DebugInfo/CodeView/SymbolDumper.h" #include "llvm/DebugInfo/CodeView/SymbolRecord.h" +#include "llvm/DebugInfo/CodeView/TypeDatabase.h" #include "llvm/DebugInfo/CodeView/TypeDumpVisitor.h" #include "llvm/DebugInfo/CodeView/TypeIndex.h" #include "llvm/DebugInfo/CodeView/TypeRecord.h" #include "llvm/DebugInfo/CodeView/TypeStreamMerger.h" #include "llvm/DebugInfo/CodeView/TypeTableBuilder.h" +#include "llvm/DebugInfo/CodeView/TypeTableCollection.h" #include "llvm/Object/COFF.h" #include "llvm/Object/ObjectFile.h" -#include "llvm/Support/BinaryByteStream.h" #include "llvm/Support/BinaryStreamReader.h" #include "llvm/Support/COFF.h" -#include "llvm/Support/ConvertUTF.h" #include "llvm/Support/Casting.h" #include "llvm/Support/Compiler.h" +#include "llvm/Support/ConvertUTF.h" #include "llvm/Support/DataExtractor.h" #include "llvm/Support/FormatVariadic.h" #include "llvm/Support/Path.h" @@ -71,7 +73,7 @@ class COFFDumper : public ObjDumper { public: friend class COFFObjectDumpDelegate; COFFDumper(const llvm::object::COFFObjectFile *Obj, ScopedPrinter &Writer) - : ObjDumper(Writer), Obj(Obj), Writer(Writer), TypeDB(100) {} + : ObjDumper(Writer), Obj(Obj), Writer(Writer), Types(100) {} void printFileHeaders() override; void printSections() override; @@ -107,7 +109,7 @@ private: void printFileNameForOffset(StringRef Label, uint32_t FileOffset); void printTypeIndex(StringRef FieldName, TypeIndex TI) { // Forward to CVTypeDumper for simplicity. - CVTypeDumper::printTypeIndex(Writer, FieldName, TI, TypeDB); + codeview::printTypeIndex(Writer, FieldName, TI, Types); } void printCodeViewSymbolsSubsection(StringRef Subsection, @@ -155,14 +157,13 @@ private: bool RelocCached = false; RelocMapTy RelocMap; - BinaryByteStream ChecksumContents; VarStreamArray<FileChecksumEntry> CVFileChecksumTable; - BinaryByteStream StringTableContents; StringTableRef CVStringTable; ScopedPrinter &Writer; - TypeDatabase TypeDB; + BinaryByteStream TypeContents; + LazyRandomTypeCollection Types; }; class COFFObjectDumpDelegate : public SymbolDumpDelegate { @@ -775,14 +776,13 @@ void COFFDumper::initializeFileAndStringTables(BinaryStreamReader &Reader) { switch (ModuleDebugFragmentKind(SubType)) { case ModuleDebugFragmentKind::FileChecksums: { - ChecksumContents = BinaryByteStream(Contents, support::little); - BinaryStreamReader CSR(ChecksumContents); + BinaryStreamReader CSR(Contents, support::little); error(CSR.readArray(CVFileChecksumTable, CSR.getLength())); break; } case ModuleDebugFragmentKind::StringTable: { - StringTableContents = BinaryByteStream(Contents, support::little); - error(CVStringTable.initialize(StringTableContents)); + BinaryStreamRef ST(Contents, support::little); + error(CVStringTable.initialize(ST)); } break; default: break; @@ -812,8 +812,7 @@ void COFFDumper::printCodeViewSymbolSection(StringRef SectionName, if (Magic != COFF::DEBUG_SECTION_MAGIC) return error(object_error::parse_failed); - BinaryByteStream FileAndStrings(Data, support::little); - BinaryStreamReader FSReader(FileAndStrings); + BinaryStreamReader FSReader(Data, support::little); initializeFileAndStringTables(FSReader); // TODO: Convert this over to using ModuleSubstreamVisitor. @@ -889,8 +888,7 @@ void COFFDumper::printCodeViewSymbolSection(StringRef SectionName, } case ModuleDebugFragmentKind::FrameData: { // First four bytes is a relocation against the function. - BinaryByteStream S(Contents, llvm::support::little); - BinaryStreamReader SR(S); + BinaryStreamReader SR(Contents, llvm::support::little); const uint32_t *CodePtr; error(SR.readObject(CodePtr)); StringRef LinkageName; @@ -934,8 +932,7 @@ void COFFDumper::printCodeViewSymbolSection(StringRef SectionName, ListScope S(W, "FunctionLineTable"); W.printString("LinkageName", Name); - BinaryByteStream LineTableInfo(FunctionLineTables[Name], support::little); - BinaryStreamReader Reader(LineTableInfo); + BinaryStreamReader Reader(FunctionLineTables[Name], support::little); ModuleDebugLineFragmentRef LineInfo; error(LineInfo.initialize(Reader)); @@ -982,12 +979,9 @@ void COFFDumper::printCodeViewSymbolsSubsection(StringRef Subsection, Subsection.bytes_end()); auto CODD = llvm::make_unique<COFFObjectDumpDelegate>(*this, Section, Obj, SectionContents); - - CVSymbolDumper CVSD(W, TypeDB, std::move(CODD), - opts::CodeViewSubsectionBytes); - BinaryByteStream Stream(BinaryData, llvm::support::little); + CVSymbolDumper CVSD(W, Types, std::move(CODD), opts::CodeViewSubsectionBytes); CVSymbolArray Symbols; - BinaryStreamReader Reader(Stream); + BinaryStreamReader Reader(BinaryData, llvm::support::little); if (auto EC = Reader.readArray(Symbols, Reader.getLength())) { consumeError(std::move(EC)); W.flush(); @@ -1002,8 +996,7 @@ void COFFDumper::printCodeViewSymbolsSubsection(StringRef Subsection, } void COFFDumper::printCodeViewFileChecksums(StringRef Subsection) { - BinaryByteStream S(Subsection, llvm::support::little); - BinaryStreamReader SR(S); + BinaryStreamReader SR(Subsection, llvm::support::little); ModuleDebugFileChecksumFragmentRef Checksums; error(Checksums.initialize(SR)); @@ -1021,8 +1014,7 @@ void COFFDumper::printCodeViewFileChecksums(StringRef Subsection) { } void COFFDumper::printCodeViewInlineeLines(StringRef Subsection) { - BinaryByteStream S(Subsection, llvm::support::little); - BinaryStreamReader SR(S); + BinaryStreamReader SR(Subsection, llvm::support::little); ModuleDebugInlineeLineFragmentRef Lines; error(Lines.initialize(SR)); @@ -1072,18 +1064,17 @@ void COFFDumper::mergeCodeViewTypes(TypeTableBuilder &CVIDs, error(consume(Data, Magic)); if (Magic != 4) error(object_error::parse_failed); - ArrayRef<uint8_t> Bytes(reinterpret_cast<const uint8_t *>(Data.data()), - Data.size()); - BinaryByteStream Stream(Bytes, llvm::support::little); + CVTypeArray Types; - BinaryStreamReader Reader(Stream); + BinaryStreamReader Reader(Data, llvm::support::little); if (auto EC = Reader.readArray(Types, Reader.getLength())) { consumeError(std::move(EC)); W.flush(); error(object_error::parse_failed); } - - if (auto EC = mergeTypeStreams(CVIDs, CVTypes, nullptr, Types)) + SmallVector<TypeIndex, 128> SourceToDest; + if (auto EC = + mergeTypeStreams(CVIDs, CVTypes, SourceToDest, nullptr, Types)) return error(std::move(EC)); } } @@ -1105,12 +1096,11 @@ void COFFDumper::printCodeViewTypeSection(StringRef SectionName, if (Magic != COFF::DEBUG_SECTION_MAGIC) return error(object_error::parse_failed); - CVTypeDumper CVTD(TypeDB); - TypeDumpVisitor TDV(TypeDB, &W, opts::CodeViewSubsectionBytes); - if (auto EC = CVTD.dump({Data.bytes_begin(), Data.bytes_end()}, TDV)) { - W.flush(); - error(llvm::errorToErrorCode(std::move(EC))); - } + Types.reset(Data); + + TypeDumpVisitor TDV(Types, &W, opts::CodeViewSubsectionBytes); + error(codeview::visitTypeStream(Types, TDV)); + W.flush(); } void COFFDumper::printSections() { @@ -1650,35 +1640,22 @@ void llvm::dumpCodeViewMergedTypes(ScopedPrinter &Writer, TypeBuf.append(Record.begin(), Record.end()); }); - TypeDatabase TypeDB(CVTypes.records().size()); + TypeTableCollection TpiTypes(CVTypes.records()); { ListScope S(Writer, "MergedTypeStream"); - CVTypeDumper CVTD(TypeDB); - TypeDumpVisitor TDV(TypeDB, &Writer, opts::CodeViewSubsectionBytes); - if (auto EC = CVTD.dump( - {TypeBuf.str().bytes_begin(), TypeBuf.str().bytes_end()}, TDV)) { - Writer.flush(); - error(std::move(EC)); - } + TypeDumpVisitor TDV(TpiTypes, &Writer, opts::CodeViewSubsectionBytes); + error(codeview::visitTypeStream(TpiTypes, TDV)); + Writer.flush(); } // Flatten the id stream and print it next. The ID stream refers to names from // the type stream. - SmallString<0> IDBuf; - IDTable.ForEachRecord([&](TypeIndex TI, ArrayRef<uint8_t> Record) { - IDBuf.append(Record.begin(), Record.end()); - }); - + TypeTableCollection IpiTypes(IDTable.records()); { ListScope S(Writer, "MergedIDStream"); - TypeDatabase IDDB(IDTable.records().size()); - CVTypeDumper CVTD(IDDB); - TypeDumpVisitor TDV(TypeDB, &Writer, opts::CodeViewSubsectionBytes); - TDV.setItemDB(IDDB); - if (auto EC = CVTD.dump( - {IDBuf.str().bytes_begin(), IDBuf.str().bytes_end()}, TDV)) { - Writer.flush(); - error(std::move(EC)); - } + TypeDumpVisitor TDV(TpiTypes, &Writer, opts::CodeViewSubsectionBytes); + TDV.setIpiTypes(IpiTypes); + error(codeview::visitTypeStream(IpiTypes, TDV)); + Writer.flush(); } } diff --git a/tools/opt/opt.cpp b/tools/opt/opt.cpp index c362dff3a3e0..bef197d603ca 100644 --- a/tools/opt/opt.cpp +++ b/tools/opt/opt.cpp @@ -24,6 +24,7 @@ #include "llvm/Analysis/TargetTransformInfo.h" #include "llvm/Bitcode/BitcodeWriterPass.h" #include "llvm/CodeGen/CommandFlags.h" +#include "llvm/CodeGen/TargetPassConfig.h" #include "llvm/IR/DataLayout.h" #include "llvm/IR/DebugInfo.h" #include "llvm/IR/IRPrintingPasses.h" @@ -579,6 +580,13 @@ int main(int argc, char **argv) { NoOutput = true; } + if (TM) { + // FIXME: We should dyn_cast this when supported. + auto <M = static_cast<LLVMTargetMachine &>(*TM); + Pass *TPC = LTM.createPassConfig(Passes); + Passes.add(TPC); + } + // Create a new optimization pass for each one specified on the command line for (unsigned i = 0; i < PassList.size(); ++i) { if (StandardLinkOpts && @@ -619,9 +627,7 @@ int main(int argc, char **argv) { const PassInfo *PassInf = PassList[i]; Pass *P = nullptr; - if (PassInf->getTargetMachineCtor()) - P = PassInf->getTargetMachineCtor()(TM.get()); - else if (PassInf->getNormalCtor()) + if (PassInf->getNormalCtor()) P = PassInf->getNormalCtor()(); else errs() << argv[0] << ": cannot create pass: " |
