From 63b428e3861bed666525b3af56cd50e14ab30495 Mon Sep 17 00:00:00 2001 From: Hubert Tong Date: Wed, 15 Jan 2020 10:42:27 -0500 Subject: [PATCH] DWARFDebugLine.cpp: Format unknown line number standard opcodes Summary: This patch implements `formatv()` formatting for `dwarf::LineNumberOps` and makes use of it for the `llvm-dwarfdump --debug-line` dump. Previously, unknown line number standard opcodes would lead to undefined behaviour. The code would attempt to format the data pointer of an empty `StringRef` (a null pointer) using `%s`. According to the description for `format()`, use of that interface carries the "risk of `printf`". Passing a null pointer in place of an array to a C library function results in undefined behaviour. Reviewers: jhenderson, daltenty, stevewan Reviewed By: jhenderson Subscribers: aprantl, hiraditya, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D72369 --- llvm/include/llvm/BinaryFormat/Dwarf.h | 5 +++++ llvm/lib/BinaryFormat/Dwarf.cpp | 1 + llvm/lib/DebugInfo/DWARF/DWARFDebugLine.cpp | 6 ++++-- llvm/test/tools/llvm-dwarfdump/X86/debug-line.s | 2 +- 4 files changed, 11 insertions(+), 3 deletions(-) diff --git a/llvm/include/llvm/BinaryFormat/Dwarf.h b/llvm/include/llvm/BinaryFormat/Dwarf.h index 2ad2018..613cde9 100644 --- a/llvm/include/llvm/BinaryFormat/Dwarf.h +++ b/llvm/include/llvm/BinaryFormat/Dwarf.h @@ -654,6 +654,11 @@ template <> struct EnumTraits : public std::true_type { static constexpr char Type[4] = "TAG"; static constexpr StringRef (*StringFn)(unsigned) = &TagString; }; + +template <> struct EnumTraits : public std::true_type { + static constexpr char Type[4] = "LNS"; + static constexpr StringRef (*StringFn)(unsigned) = &LNStandardString; +}; } // End of namespace dwarf /// Dwarf constants format_provider diff --git a/llvm/lib/BinaryFormat/Dwarf.cpp b/llvm/lib/BinaryFormat/Dwarf.cpp index 9ca3317..c3da0e2 100644 --- a/llvm/lib/BinaryFormat/Dwarf.cpp +++ b/llvm/lib/BinaryFormat/Dwarf.cpp @@ -757,3 +757,4 @@ constexpr char llvm::dwarf::EnumTraits::Type[]; constexpr char llvm::dwarf::EnumTraits
::Type[]; constexpr char llvm::dwarf::EnumTraits::Type[]; constexpr char llvm::dwarf::EnumTraits::Type[]; +constexpr char llvm::dwarf::EnumTraits::Type[]; diff --git a/llvm/lib/DebugInfo/DWARF/DWARFDebugLine.cpp b/llvm/lib/DebugInfo/DWARF/DWARFDebugLine.cpp index 11adb1e..2eceadb 100644 --- a/llvm/lib/DebugInfo/DWARF/DWARFDebugLine.cpp +++ b/llvm/lib/DebugInfo/DWARF/DWARFDebugLine.cpp @@ -16,6 +16,7 @@ #include "llvm/DebugInfo/DWARF/DWARFRelocMap.h" #include "llvm/Support/Errc.h" #include "llvm/Support/Format.h" +#include "llvm/Support/FormatVariadic.h" #include "llvm/Support/WithColor.h" #include "llvm/Support/raw_ostream.h" #include @@ -114,8 +115,9 @@ void DWARFDebugLine::Prologue::dump(raw_ostream &OS, << format(" opcode_base: %u\n", OpcodeBase); for (uint32_t I = 0; I != StandardOpcodeLengths.size(); ++I) - OS << format("standard_opcode_lengths[%s] = %u\n", - LNStandardString(I + 1).data(), StandardOpcodeLengths[I]); + OS << formatv("standard_opcode_lengths[{0}] = {1}\n", + static_cast(I + 1), + StandardOpcodeLengths[I]); if (!IncludeDirectories.empty()) { // DWARF v5 starts directory indexes at 0. diff --git a/llvm/test/tools/llvm-dwarfdump/X86/debug-line.s b/llvm/test/tools/llvm-dwarfdump/X86/debug-line.s index c83d49f..7793d1a 100644 --- a/llvm/test/tools/llvm-dwarfdump/X86/debug-line.s +++ b/llvm/test/tools/llvm-dwarfdump/X86/debug-line.s @@ -30,7 +30,7 @@ # CHECK-NEXT: standard_opcode_lengths[DW_LNS_set_prologue_end] = 0 # CHECK-NEXT: standard_opcode_lengths[DW_LNS_set_epilogue_begin] = 0 # CHECK-NEXT: standard_opcode_lengths[DW_LNS_set_isa] = 1 -# CHECK-NEXT: standard_opcode_lengths[(null)] = 0 +# CHECK-NEXT: standard_opcode_lengths[DW_LNS_unknown_d] = 0 # CHECK-NEXT: include_directories[ 0] = "dir1/dir2" # CHECK-NEXT: file_names[ 0]: # CHECK-NEXT: name: "file1.c" -- 2.7.4