From: Jonas Devlieghere Date: Mon, 2 Apr 2018 10:40:43 +0000 (+0000) Subject: [dsymutil] Upstream emitting of papertrail warnings. X-Git-Tag: llvmorg-7.0.0-rc1~9225 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=9e3e7a99e81dd9e500147e4914cbfaeb0c559d7d;p=platform%2Fupstream%2Fllvm.git [dsymutil] Upstream emitting of papertrail warnings. When running dsymutil as part of your build system, it can be desirable for warnings to be part of the end product, rather than just being emitted to the output stream. This patch upstreams that functionality. Differential revision: https://reviews.llvm.org/D44639 llvm-svn: 328965 --- diff --git a/llvm/docs/CommandGuide/dsymutil.rst b/llvm/docs/CommandGuide/dsymutil.rst index a89ee18..ceaa540 100644 --- a/llvm/docs/CommandGuide/dsymutil.rst +++ b/llvm/docs/CommandGuide/dsymutil.rst @@ -70,6 +70,13 @@ OPTIONS Specifies a ``path`` to prepend to all debug symbol object file paths. +.. option:: --papertrail + + When running dsymutil as part of your build system, it can be desirable for + warnings to be part of the end product, rather than just being emitted to the + output stream. When enabled warnings are embedded in the linked DWARF debug + information. + .. option:: -s, --symtab Dumps the symbol table found in *executable* or object file(s) and exits. diff --git a/llvm/lib/CodeGen/AsmPrinter/DIE.cpp b/llvm/lib/CodeGen/AsmPrinter/DIE.cpp index 6c9969d..b4ab6fa 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DIE.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/DIE.cpp @@ -746,6 +746,7 @@ void DIEBlock::EmitValue(const AsmPrinter *Asm, dwarf::Form Form) const { case dwarf::DW_FORM_block2: Asm->emitInt16(Size); break; case dwarf::DW_FORM_block4: Asm->emitInt32(Size); break; case dwarf::DW_FORM_block: Asm->EmitULEB128(Size); break; + case dwarf::DW_FORM_string: break; case dwarf::DW_FORM_data16: break; } diff --git a/llvm/test/tools/dsymutil/X86/papertrail-warnings.test b/llvm/test/tools/dsymutil/X86/papertrail-warnings.test new file mode 100644 index 0000000..c2dbabe --- /dev/null +++ b/llvm/test/tools/dsymutil/X86/papertrail-warnings.test @@ -0,0 +1,30 @@ +RUN: RC_DEBUG_OPTIONS=1 dsymutil -f %p/../Inputs/basic.macho.x86_64 -o - | llvm-dwarfdump -v - | FileCheck %s + +CHECK: .debug_info contents: +CHECK: Compile Unit: +CHECK: DW_TAG_compile_unit [1] * +CHECK: DW_AT_producer {{.*}}"dsymutil +CHECK: DW_AT_name {{.*}}"/Inputs/basic1.macho.x86_64.o" +CHECK: DW_TAG_constant [2] +CHECK: DW_AT_name {{.*}}"dsymutil_warning" +CHECK: DW_AT_artificial [DW_FORM_flag] (0x01) +CHECK: DW_AT_const_value {{.*}}"unable to open object file: No such file or directory" +CHECK: NULL +CHECK: Compile Unit: +CHECK: DW_TAG_compile_unit [1] * +CHECK: DW_AT_producer {{.*}}"dsymutil +CHECK: DW_AT_name {{.*}}"/Inputs/basic2.macho.x86_64.o" +CHECK: DW_TAG_constant [2] +CHECK: DW_AT_name {{.*}}"dsymutil_warning" +CHECK: DW_AT_artificial [DW_FORM_flag] (0x01) +CHECK: DW_AT_const_value {{.*}}"unable to open object file: No such file or directory" +CHECK: NULL +CHECK: Compile Unit: +CHECK: DW_TAG_compile_unit [1] * +CHECK: DW_AT_producer {{.*}}"dsymutil +CHECK: DW_AT_name {{.*}}"/Inputs/basic3.macho.x86_64.o" +CHECK: DW_TAG_constant [2] +CHECK: DW_AT_name {{.*}}"dsymutil_warning" +CHECK: DW_AT_artificial [DW_FORM_flag] (0x01) +CHECK: DW_AT_const_value {{.*}}"unable to open object file: No such file or directory" +CHECK: NULL \ No newline at end of file diff --git a/llvm/test/tools/dsymutil/cmdline.test b/llvm/test/tools/dsymutil/cmdline.test index ff1fc71..c9b5b2c 100644 --- a/llvm/test/tools/dsymutil/cmdline.test +++ b/llvm/test/tools/dsymutil/cmdline.test @@ -13,6 +13,7 @@ HELP: -no-swiftmodule-timestamp HELP: -num-threads= HELP: -o= HELP: -oso-prepend-path= +HELP: -papertrail HELP: -symtab HELP: -toolchain HELP: -update diff --git a/llvm/test/tools/dsymutil/debug-map-parsing.test b/llvm/test/tools/dsymutil/debug-map-parsing.test index 7cdfdea..928323c 100644 --- a/llvm/test/tools/dsymutil/debug-map-parsing.test +++ b/llvm/test/tools/dsymutil/debug-map-parsing.test @@ -80,7 +80,7 @@ NOT-FOUND-NEXT: triple: 'x86_64-apple-darwin' NOT-FOUND-NEXT: binary-path:{{.*}}/Inputs/basic.macho.x86_64 NOT-FOUND-NEXT: ... -Check that we correctly error out on invalid executatble. +Check that we correctly error out on invalid executable. NO-EXECUTABLE: cannot parse{{.*}}/inexistant': {{[Nn]o}} such file NO-EXECUTABLE-NOT: --- diff --git a/llvm/tools/dsymutil/DebugMap.h b/llvm/tools/dsymutil/DebugMap.h index 2173ba6..4b80bf0 100644 --- a/llvm/tools/dsymutil/DebugMap.h +++ b/llvm/tools/dsymutil/DebugMap.h @@ -176,6 +176,11 @@ public: return make_range(Symbols.begin(), Symbols.end()); } + bool empty() const { return Symbols.empty(); } + + void addWarning(StringRef Warning) { Warnings.push_back(Warning); } + const std::vector &getWarnings() const { return Warnings; } + void print(raw_ostream &OS) const; #ifndef NDEBUG void dump() const; @@ -194,6 +199,8 @@ private: DenseMap AddressToMapping; uint8_t Type; + std::vector Warnings; + /// For YAMLIO support. ///@{ friend yaml::MappingTraits; diff --git a/llvm/tools/dsymutil/DwarfLinker.cpp b/llvm/tools/dsymutil/DwarfLinker.cpp index 41f52e7..8b9a4b9 100644 --- a/llvm/tools/dsymutil/DwarfLinker.cpp +++ b/llvm/tools/dsymutil/DwarfLinker.cpp @@ -1481,6 +1481,10 @@ private: MaxDwarfVersion = Version; } + /// Emit warnings as Dwarf compile units to leave a trail after linking. + bool emitPaperTrailWarnings(const DebugMapObject &DMO, const DebugMap &Map, + OffsetsStringPool &StringPool); + /// Keeps track of relocations. class RelocationManager { struct ValidReloc { @@ -4118,6 +4122,64 @@ void DwarfLinker::DIECloner::cloneAllCompileUnits( } } +bool DwarfLinker::emitPaperTrailWarnings(const DebugMapObject &DMO, + const DebugMap &Map, + OffsetsStringPool &StringPool) { + if (DMO.getWarnings().empty() || !DMO.empty()) + return false; + + Streamer->switchToDebugInfoSection(/* Version */ 2); + DIE *CUDie = DIE::get(DIEAlloc, dwarf::DW_TAG_compile_unit); + CUDie->setOffset(11); + StringRef Producer = StringPool.internString("dsymutil"); + StringRef File = StringPool.internString(DMO.getObjectFilename()); + CUDie->addValue(DIEAlloc, dwarf::DW_AT_producer, dwarf::DW_FORM_strp, + DIEInteger(StringPool.getStringOffset(Producer))); + DIEBlock *String = new (DIEAlloc) DIEBlock(); + DIEBlocks.push_back(String); + for (auto &C : File) + String->addValue(DIEAlloc, dwarf::Attribute(0), dwarf::DW_FORM_data1, + DIEInteger(C)); + String->addValue(DIEAlloc, dwarf::Attribute(0), dwarf::DW_FORM_data1, + DIEInteger(0)); + + CUDie->addValue(DIEAlloc, dwarf::DW_AT_name, dwarf::DW_FORM_string, String); + for (const auto &Warning : DMO.getWarnings()) { + DIE &ConstDie = CUDie->addChild(DIE::get(DIEAlloc, dwarf::DW_TAG_constant)); + ConstDie.addValue( + DIEAlloc, dwarf::DW_AT_name, dwarf::DW_FORM_strp, + DIEInteger(StringPool.getStringOffset("dsymutil_warning"))); + ConstDie.addValue(DIEAlloc, dwarf::DW_AT_artificial, dwarf::DW_FORM_flag, + DIEInteger(1)); + ConstDie.addValue(DIEAlloc, dwarf::DW_AT_const_value, dwarf::DW_FORM_strp, + DIEInteger(StringPool.getStringOffset(Warning))); + } + unsigned Size = 4 /* FORM_strp */ + File.size() + 1 + + DMO.getWarnings().size() * (4 + 1 + 4) + + 1 /* End of children */; + DIEAbbrev Abbrev = CUDie->generateAbbrev(); + AssignAbbrev(Abbrev); + CUDie->setAbbrevNumber(Abbrev.getNumber()); + Size += getULEB128Size(Abbrev.getNumber()); + // Abbreviation ordering needed for classic compatibility. + for (auto &Child : CUDie->children()) { + Abbrev = Child.generateAbbrev(); + AssignAbbrev(Abbrev); + Child.setAbbrevNumber(Abbrev.getNumber()); + Size += getULEB128Size(Abbrev.getNumber()); + } + CUDie->setSize(Size); + auto &Asm = Streamer->getAsmPrinter(); + Asm.emitInt32(11 + CUDie->getSize() - 4); + Asm.emitInt16(2); + Asm.emitInt32(0); + Asm.emitInt8(Map.getTriple().isArch64Bit() ? 8 : 4); + Streamer->emitDIE(*CUDie); + OutputDebugInfoSize += 11 /* Header */ + Size; + + return true; +} + bool DwarfLinker::link(const DebugMap &Map) { if (!createStreamer(Map.getTriple(), OutFile)) return false; @@ -4184,8 +4246,10 @@ bool DwarfLinker::link(const DebugMap &Map) { continue; } - if (!LinkContext.ObjectFile) + if (emitPaperTrailWarnings(LinkContext.DMO, Map, OffsetsStringPool)) + continue; + if (!LinkContext.ObjectFile) continue; // Look for relocations that correspond to debug map entries. @@ -4232,6 +4296,11 @@ bool DwarfLinker::link(const DebugMap &Map) { } } + // If we haven't seen any CUs, pick an arbitrary valid Dwarf version anyway, + // to be able to emit papertrail warnings. + if (MaxDwarfVersion == 0) + MaxDwarfVersion = 3; + ThreadPool pool(2); // These variables manage the list of processed object files. diff --git a/llvm/tools/dsymutil/MachODebugMapParser.cpp b/llvm/tools/dsymutil/MachODebugMapParser.cpp index 88b8011..2ec0e62 100644 --- a/llvm/tools/dsymutil/MachODebugMapParser.cpp +++ b/llvm/tools/dsymutil/MachODebugMapParser.cpp @@ -24,10 +24,12 @@ using namespace llvm::object; class MachODebugMapParser { public: MachODebugMapParser(StringRef BinaryPath, ArrayRef Archs, - StringRef PathPrefix = "", bool Verbose = false) + StringRef PathPrefix = "", + bool PaperTrailWarnings = false, bool Verbose = false) : BinaryPath(BinaryPath), Archs(Archs.begin(), Archs.end()), - PathPrefix(PathPrefix), MainBinaryHolder(Verbose), - CurrentObjectHolder(Verbose), CurrentDebugMapObject(nullptr) {} + PathPrefix(PathPrefix), PaperTrailWarnings(PaperTrailWarnings), + MainBinaryHolder(Verbose), CurrentObjectHolder(Verbose), + CurrentDebugMapObject(nullptr) {} /// Parses and returns the DebugMaps of the input binary. The binary contains /// multiple maps in case it is a universal binary. @@ -42,6 +44,7 @@ private: std::string BinaryPath; SmallVector Archs; std::string PathPrefix; + bool PaperTrailWarnings; /// Owns the MemoryBuffer for the main binary. BinaryHolder MainBinaryHolder; @@ -102,6 +105,13 @@ private: warn_ostream() << "(" << MachOUtils::getArchName(Result->getTriple().getArchName()) << ") " << File << " " << Msg << "\n"; + + if (PaperTrailWarnings) { + if (!File.empty()) + Result->addDebugMapObject(File, sys::TimePoint()); + if (Result->end() != Result->begin()) + (*--Result->end())->addWarning(Msg.str()); + } } }; @@ -522,13 +532,14 @@ namespace llvm { namespace dsymutil { llvm::ErrorOr>> parseDebugMap(StringRef InputFile, ArrayRef Archs, - StringRef PrependPath, bool Verbose, bool InputIsYAML) { - if (!InputIsYAML) { - MachODebugMapParser Parser(InputFile, Archs, PrependPath, Verbose); - return Parser.parse(); - } else { + StringRef PrependPath, bool PaperTrailWarnings, bool Verbose, + bool InputIsYAML) { + if (InputIsYAML) return DebugMap::parseYAMLDebugMap(InputFile, PrependPath, Verbose); - } + + MachODebugMapParser Parser(InputFile, Archs, PrependPath, PaperTrailWarnings, + Verbose); + return Parser.parse(); } bool dumpStab(StringRef InputFile, ArrayRef Archs, diff --git a/llvm/tools/dsymutil/dsymutil.cpp b/llvm/tools/dsymutil/dsymutil.cpp index 533ff89..51118d3 100644 --- a/llvm/tools/dsymutil/dsymutil.cpp +++ b/llvm/tools/dsymutil/dsymutil.cpp @@ -147,6 +147,11 @@ static opt Toolchain("toolchain", desc("Embed toolchain information in dSYM bundle."), cat(DsymCategory)); +static opt + PaperTrailWarnings("papertrail", + desc("Embed warnings in the linked DWARF debug info."), + cat(DsymCategory)); + static bool createPlistFile(llvm::StringRef Bin, llvm::StringRef BundleRoot) { if (NoOutput) return true; @@ -430,6 +435,12 @@ int main(int argc, char **argv) { return 1; } + if (getenv("RC_DEBUG_OPTIONS")) + PaperTrailWarnings = true; + + if (PaperTrailWarnings && InputIsYAMLDebugMap) + warn_ostream() << "Paper trail warnings are not supported for YAML input"; + for (const auto &Arch : ArchFlags) if (Arch != "*" && Arch != "all" && !llvm::object::MachOObjectFile::isValidArch(Arch)) { @@ -445,8 +456,9 @@ int main(int argc, char **argv) { continue; } - auto DebugMapPtrsOrErr = parseDebugMap(InputFile, ArchFlags, OsoPrependPath, - Verbose, InputIsYAMLDebugMap); + auto DebugMapPtrsOrErr = + parseDebugMap(InputFile, ArchFlags, OsoPrependPath, PaperTrailWarnings, + Verbose, InputIsYAMLDebugMap); if (auto EC = DebugMapPtrsOrErr.getError()) { error_ostream() << "cannot parse the debug map for '" << InputFile diff --git a/llvm/tools/dsymutil/dsymutil.h b/llvm/tools/dsymutil/dsymutil.h index 4d7ea47..deaf332 100644 --- a/llvm/tools/dsymutil/dsymutil.h +++ b/llvm/tools/dsymutil/dsymutil.h @@ -59,7 +59,8 @@ struct LinkOptions { /// returned when the file is universal (aka fat) binary. ErrorOr>> parseDebugMap(StringRef InputFile, ArrayRef Archs, - StringRef PrependPath, bool Verbose, bool InputIsYAML); + StringRef PrependPath, bool PaperTrailWarnings, bool Verbose, + bool InputIsYAML); /// Dump the symbol table bool dumpStab(StringRef InputFile, ArrayRef Archs,