[llvm] 69c8fb1 - [DWARF5] Added support for debug_macro section parsing and dumping in llvm-dwarfdump.

Sourabh Singh Tomar via llvm-commits llvm-commits at lists.llvm.org
Thu Apr 2 23:55:14 PDT 2020


Author: Sourabh Singh Tomar
Date: 2020-04-03T12:23:51+05:30
New Revision: 69c8fb1c65fe54e2a15ff7339cdebb70ee290bd1

URL: https://github.com/llvm/llvm-project/commit/69c8fb1c65fe54e2a15ff7339cdebb70ee290bd1
DIFF: https://github.com/llvm/llvm-project/commit/69c8fb1c65fe54e2a15ff7339cdebb70ee290bd1.diff

LOG: [DWARF5] Added support for debug_macro section parsing and dumping in llvm-dwarfdump.

Summary:
This patch adds parsing and dumping DWARFv5 .debug_macro section in llvm-dwarfdump,
it does not introduce any new switch. Existing switch "--debug-macro"
should be used to dump macinfo or macro section.

Reviewed By: dblaikie, ikudrin, jhenderson

Differential Revision: https://reviews.llvm.org/D73086

Added: 
    llvm/test/DebugInfo/X86/debug-macro-macinfo.s
    llvm/test/DebugInfo/X86/debug-macro-v5.s
    llvm/test/DebugInfo/X86/unsupported-dwarf64-debug-macro-v5.s
    llvm/test/DebugInfo/X86/unsupported-opcode_operands_table-debug-macro-v5.s

Modified: 
    llvm/include/llvm/DebugInfo/DWARF/DWARFContext.h
    llvm/include/llvm/DebugInfo/DWARF/DWARFDebugMacro.h
    llvm/include/llvm/DebugInfo/DWARF/DWARFObject.h
    llvm/lib/DebugInfo/DWARF/DWARFContext.cpp
    llvm/lib/DebugInfo/DWARF/DWARFDebugMacro.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/include/llvm/DebugInfo/DWARF/DWARFContext.h b/llvm/include/llvm/DebugInfo/DWARF/DWARFContext.h
index 4f2130cd9399..c448c5f690a3 100644
--- a/llvm/include/llvm/DebugInfo/DWARF/DWARFContext.h
+++ b/llvm/include/llvm/DebugInfo/DWARF/DWARFContext.h
@@ -61,6 +61,7 @@ class DWARFContext : public DIContext {
   std::unique_ptr<DWARFDebugLine> Line;
   std::unique_ptr<DWARFDebugFrame> DebugFrame;
   std::unique_ptr<DWARFDebugFrame> EHFrame;
+  std::unique_ptr<DWARFDebugMacro> Macro;
   std::unique_ptr<DWARFDebugMacro> Macinfo;
   std::unique_ptr<DWARFDebugNames> Names;
   std::unique_ptr<AppleAcceleratorTable> AppleNames;
@@ -104,6 +105,15 @@ class DWARFContext : public DIContext {
 
   std::unique_ptr<const DWARFObject> DObj;
 
+  /// Helper enum to distinguish between macro[.dwo] and macinfo[.dwo]
+  /// section.
+  enum MacroSecType {
+    MacinfoSection,
+    MacinfoDwoSection,
+    MacroSection
+    // FIXME: Add support for.debug_macro.dwo section.
+  };
+
 public:
   DWARFContext(std::unique_ptr<const DWARFObject> DObj,
                std::string DWPName = "",
@@ -272,12 +282,15 @@ class DWARFContext : public DIContext {
   /// Get a pointer to the parsed eh frame information object.
   const DWARFDebugFrame *getEHFrame();
 
-  /// Get a pointer to the parsed DebugMacro object.
+  /// Get a pointer to the parsed DebugMacinfo information object.
   const DWARFDebugMacro *getDebugMacinfo();
 
-  /// Get a pointer to the parsed dwo DebugMacro object.
+  /// Get a pointer to the parsed DebugMacinfoDWO information object.
   const DWARFDebugMacro *getDebugMacinfoDWO();
 
+  /// Get a pointer to the parsed DebugMacro information object.
+  const DWARFDebugMacro *getDebugMacro();
+
   /// Get a reference to the parsed accelerator table object.
   const DWARFDebugNames &getDebugNames();
 
@@ -382,6 +395,10 @@ class DWARFContext : public DIContext {
   }
 
 private:
+  /// Parse a macro[.dwo] or macinfo[.dwo] section.
+  std::unique_ptr<DWARFDebugMacro>
+  parseMacroOrMacinfo(MacroSecType SectionType);
+
   /// Return the compile unit which contains instruction with provided
   /// address.
   /// TODO: change input parameter from "uint64_t Address"

diff  --git a/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugMacro.h b/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugMacro.h
index e666c82bca08..9d60cdc62152 100644
--- a/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugMacro.h
+++ b/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugMacro.h
@@ -10,7 +10,10 @@
 #define LLVM_DEBUGINFO_DWARF_DWARFDEBUGMACRO_H
 
 #include "llvm/ADT/SmallVector.h"
-#include "llvm/Support/DataExtractor.h"
+#include "llvm/DebugInfo/DWARF/DWARFDataExtractor.h"
+#include "llvm/Support/Errc.h"
+#include "llvm/Support/Error.h"
+#include "llvm/Support/WithColor.h"
 #include <cstdint>
 
 namespace llvm {
@@ -18,6 +21,45 @@ namespace llvm {
 class raw_ostream;
 
 class DWARFDebugMacro {
+  /// DWARFv5 section 6.3.1 Macro Information Header.
+  enum HeaderFlagMask {
+#define HANDLE_MACRO_FLAG(ID, NAME) MACRO_##NAME = ID,
+#include "llvm/BinaryFormat/Dwarf.def"
+  };
+  struct MacroHeader {
+    /// Macro version information number.
+    uint16_t Version = 0;
+
+    /// The bits of the flags field are interpreted as a set of flags, some of
+    /// which may indicate that additional fields follow. The following flags,
+    /// beginning with the least significant bit, are defined:
+    /// offset_size_flag:
+    ///   If the offset_size_flag is zero, the header is for a 32-bit DWARF
+    ///   format macro section and all offsets are 4 bytes long; if it is one,
+    ///   the header is for a 64-bit DWARF format macro section and all offsets
+    ///   are 8 bytes long.
+    /// debug_line_offset_flag:
+    ///   If the debug_line_offset_flag is one, the debug_line_offset field (see
+    ///   below) is present. If zero, that field is omitted.
+    /// opcode_operands_table_flag:
+    ///   If the opcode_operands_table_flag is one, the opcode_operands_table
+    ///   field (see below) is present. If zero, that field is omitted.
+    uint8_t Flags;
+
+    /// debug_line_offset
+    ///   An offset in the .debug_line section of the beginning of the line
+    ///   number information in the containing compilation unit, encoded as a
+    ///   4-byte offset for a 32-bit DWARF format macro section and an 8-byte
+    ///   offset for a 64-bit DWARF format macro section.
+    uint64_t DebugLineOffset;
+
+    /// Print the macro header from the debug_macro section.
+    void dumpMacroHeader(raw_ostream &OS) const;
+
+    /// Parse the debug_macro header.
+    Error parseMacroHeader(DWARFDataExtractor Data, uint64_t *Offset);
+  };
+
   /// A single macro entry within a macro list.
   struct Entry {
     /// The type of the macro entry.
@@ -40,6 +82,10 @@ class DWARFDebugMacro {
   };
 
   struct MacroList {
+    // A value 0 in the `Header.Version` field indicates that we're parsing
+    // a macinfo[.dwo] section which doesn't have header itself, hence
+    // for that case other fields in the `Header` are uninitialized.
+    MacroHeader Header;
     SmallVector<Entry, 4> Macros;
     uint64_t Offset;
   };
@@ -50,11 +96,13 @@ class DWARFDebugMacro {
 public:
   DWARFDebugMacro() = default;
 
-  /// Print the macro list found within the debug_macinfo section.
+  /// Print the macro list found within the debug_macinfo/debug_macro section.
   void dump(raw_ostream &OS) const;
 
-  /// Parse the debug_macinfo section accessible via the 'data' parameter.
-  void parse(DataExtractor data);
+  /// Parse the debug_macinfo/debug_macro section accessible via the 'Data'
+  /// parameter.
+  Error parse(DataExtractor StringExtractor, DWARFDataExtractor Data,
+              bool IsMacro);
 
   /// Return whether the section has any entries.
   bool empty() const { return MacroLists.empty(); }

diff  --git a/llvm/include/llvm/DebugInfo/DWARF/DWARFObject.h b/llvm/include/llvm/DebugInfo/DWARF/DWARFObject.h
index fbcde7d7cd78..89fccf04a01d 100644
--- a/llvm/include/llvm/DebugInfo/DWARF/DWARFObject.h
+++ b/llvm/include/llvm/DebugInfo/DWARF/DWARFObject.h
@@ -47,6 +47,7 @@ class DWARFObject {
   virtual StringRef getStrSection() const { return ""; }
   virtual const DWARFSection &getRangesSection() const { return Dummy; }
   virtual const DWARFSection &getRnglistsSection() const { return Dummy; }
+  virtual const DWARFSection &getMacroSection() const { return Dummy; }
   virtual StringRef getMacinfoSection() const { return ""; }
   virtual StringRef getMacinfoDWOSection() const { return ""; }
   virtual const DWARFSection &getPubnamesSection() const { return Dummy; }

diff  --git a/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp b/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp
index 908128b0205c..b3f7c6dab7e5 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp
@@ -292,6 +292,36 @@ static void dumpRnglistsSection(
   }
 }
 
+std::unique_ptr<DWARFDebugMacro>
+DWARFContext::parseMacroOrMacinfo(MacroSecType SectionType) {
+  auto Macro = std::make_unique<DWARFDebugMacro>();
+  auto ParseAndDump = [&](DWARFDataExtractor &Data, bool IsMacro) {
+    if (Error Err = Macro->parse(getStringExtractor(), Data, IsMacro)) {
+      RecoverableErrorHandler(std::move(Err));
+      Macro = nullptr;
+    }
+  };
+  switch (SectionType) {
+  case MacinfoSection: {
+    DWARFDataExtractor Data(DObj->getMacinfoSection(), isLittleEndian(), 0);
+    ParseAndDump(Data, /*IsMacro=*/false);
+    break;
+  }
+  case MacinfoDwoSection: {
+    DWARFDataExtractor Data(DObj->getMacinfoDWOSection(), isLittleEndian(), 0);
+    ParseAndDump(Data, /*IsMacro=*/false);
+    break;
+  }
+  case MacroSection: {
+    DWARFDataExtractor Data(*DObj, DObj->getMacroSection(), isLittleEndian(),
+                            0);
+    ParseAndDump(Data, /*IsMacro=*/true);
+    break;
+  }
+  }
+  return std::move(Macro);
+}
+
 static void dumpLoclistsSection(raw_ostream &OS, DIDumpOptions DumpOpts,
                                 DWARFDataExtractor Data,
                                 const MCRegisterInfo *MRI,
@@ -444,14 +474,22 @@ void DWARFContext::dump(
                                    DObj->getEHFrameSection().Data))
     getEHFrame()->dump(OS, getRegisterInfo(), *Off);
 
+  if (shouldDump(Explicit, ".debug_macro", DIDT_ID_DebugMacro,
+                 DObj->getMacroSection().Data)) {
+    if (auto Macro = getDebugMacro())
+      Macro->dump(OS);
+  }
+
   if (shouldDump(Explicit, ".debug_macinfo", DIDT_ID_DebugMacro,
                  DObj->getMacinfoSection())) {
-    getDebugMacinfo()->dump(OS);
+    if (auto Macinfo = getDebugMacinfo())
+      Macinfo->dump(OS);
   }
 
   if (shouldDump(Explicit, ".debug_macinfo.dwo", DIDT_ID_DebugMacro,
                  DObj->getMacinfoDWOSection())) {
-    getDebugMacinfoDWO()->dump(OS);
+    if (auto MacinfoDWO = getDebugMacinfoDWO())
+      MacinfoDWO->dump(OS);
   }
 
   if (shouldDump(Explicit, ".debug_aranges", DIDT_ID_DebugAranges,
@@ -815,27 +853,24 @@ const DWARFDebugFrame *DWARFContext::getEHFrame() {
   return DebugFrame.get();
 }
 
-const DWARFDebugMacro *DWARFContext::getDebugMacinfoDWO() {
-  if (MacinfoDWO)
-    return MacinfoDWO.get();
-
-  DataExtractor MacinfoDWOData(DObj->getMacinfoDWOSection(), isLittleEndian(),
-                               0);
-  MacinfoDWO.reset(new DWARFDebugMacro());
-  MacinfoDWO->parse(MacinfoDWOData);
-  return MacinfoDWO.get();
+const DWARFDebugMacro *DWARFContext::getDebugMacro() {
+  if (!Macro)
+    Macro = parseMacroOrMacinfo(MacroSection);
+  return Macro.get();
 }
 
 const DWARFDebugMacro *DWARFContext::getDebugMacinfo() {
-  if (Macinfo)
-    return Macinfo.get();
-
-  DataExtractor MacinfoData(DObj->getMacinfoSection(), isLittleEndian(), 0);
-  Macinfo.reset(new DWARFDebugMacro());
-  Macinfo->parse(MacinfoData);
+  if (!Macinfo)
+    Macinfo = parseMacroOrMacinfo(MacinfoSection);
   return Macinfo.get();
 }
 
+const DWARFDebugMacro *DWARFContext::getDebugMacinfoDWO() {
+  if (!MacinfoDWO)
+    MacinfoDWO = parseMacroOrMacinfo(MacinfoDwoSection);
+  return MacinfoDWO.get();
+}
+
 template <typename T>
 static T &getAccelTable(std::unique_ptr<T> &Cache, const DWARFObject &Obj,
                         const DWARFSection &Section, StringRef StringSection,
@@ -1476,6 +1511,7 @@ class DWARFObjInMemory final : public DWARFObject {
   DWARFSectionMap PubtypesSection;
   DWARFSectionMap GnuPubnamesSection;
   DWARFSectionMap GnuPubtypesSection;
+  DWARFSectionMap MacroSection;
 
   DWARFSectionMap *mapNameToDWARFSection(StringRef Name) {
     return StringSwitch<DWARFSectionMap *>(Name)
@@ -1503,6 +1539,7 @@ class DWARFObjInMemory final : public DWARFObject {
         .Case("apple_namespaces", &AppleNamespacesSection)
         .Case("apple_namespac", &AppleNamespacesSection)
         .Case("apple_objc", &AppleObjCSection)
+        .Case("debug_macro", &MacroSection)
         .Default(nullptr);
   }
 
@@ -1847,6 +1884,7 @@ class DWARFObjInMemory final : public DWARFObject {
   const DWARFSection &getRnglistsSection() const override {
     return RnglistsSection;
   }
+  const DWARFSection &getMacroSection() const override { return MacroSection; }
   StringRef getMacinfoSection() const override { return MacinfoSection; }
   StringRef getMacinfoDWOSection() const override { return MacinfoDWOSection; }
   const DWARFSection &getPubnamesSection() const override { return PubnamesSection; }

diff  --git a/llvm/lib/DebugInfo/DWARF/DWARFDebugMacro.cpp b/llvm/lib/DebugInfo/DWARF/DWARFDebugMacro.cpp
index 2e06e14ee3be..362301c95614 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFDebugMacro.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFDebugMacro.cpp
@@ -8,6 +8,8 @@
 
 #include "llvm/DebugInfo/DWARF/DWARFDebugMacro.h"
 #include "llvm/BinaryFormat/Dwarf.h"
+#include "llvm/DebugInfo/DWARF/DWARFContext.h"
+#include "llvm/DebugInfo/DWARF/DWARFDataExtractor.h"
 #include "llvm/Support/WithColor.h"
 #include "llvm/Support/raw_ostream.h"
 #include <cstdint>
@@ -15,10 +17,22 @@
 using namespace llvm;
 using namespace dwarf;
 
+void DWARFDebugMacro::MacroHeader::dumpMacroHeader(raw_ostream &OS) const {
+  // FIXME: Add support for dumping opcode_operands_table
+  OS << format("macro header: version = 0x%04" PRIx16 ", flags = 0x%02" PRIx8,
+               Version, Flags);
+  if (Flags & MACRO_DEBUG_LINE_OFFSET)
+    OS << format(", debug_line_offset = 0x%04" PRIx64 "\n", DebugLineOffset);
+  else
+    OS << "\n";
+}
+
 void DWARFDebugMacro::dump(raw_ostream &OS) const {
   unsigned IndLevel = 0;
   for (const auto &Macros : MacroLists) {
     OS << format("0x%08" PRIx64 ":\n", Macros.Offset);
+    if (Macros.Header.Version >= 5)
+      Macros.Header.dumpMacroHeader(OS);
     for (const Entry &E : Macros.Macros) {
       // There should not be DW_MACINFO_end_file when IndLevel is Zero. However,
       // this check handles the case of corrupted ".debug_macinfo" section.
@@ -28,22 +42,34 @@ void DWARFDebugMacro::dump(raw_ostream &OS) const {
       for (unsigned I = 0; I < IndLevel; I++)
         OS << "  ";
       IndLevel += (E.Type == DW_MACINFO_start_file);
-
-      WithColor(OS, HighlightColor::Macro).get() << MacinfoString(E.Type);
+      // Based on which version we are handling choose appropriate macro forms.
+      if (Macros.Header.Version >= 5)
+        WithColor(OS, HighlightColor::Macro).get() << MacroString(E.Type);
+      else
+        WithColor(OS, HighlightColor::Macro).get() << MacinfoString(E.Type);
       switch (E.Type) {
       default:
-        // Got a corrupted ".debug_macinfo" section (invalid macinfo type).
+        // Got a corrupted ".debug_macinfo/.debug_macro" section (invalid
+        // macinfo type).
         break;
-      case DW_MACINFO_define:
-      case DW_MACINFO_undef:
+        // debug_macro and debug_macinfo share some common encodings.
+        // DW_MACRO_define     == DW_MACINFO_define
+        // DW_MACRO_undef      == DW_MACINFO_undef
+        // DW_MACRO_start_file == DW_MACINFO_start_file
+        // DW_MACRO_end_file   == DW_MACINFO_end_file
+        // For readability/uniformity we are using DW_MACRO_*.
+      case DW_MACRO_define:
+      case DW_MACRO_undef:
+      case DW_MACRO_define_strp:
+      case DW_MACRO_undef_strp:
         OS << " - lineno: " << E.Line;
         OS << " macro: " << E.MacroStr;
         break;
-      case DW_MACINFO_start_file:
+      case DW_MACRO_start_file:
         OS << " - lineno: " << E.Line;
         OS << " filenum: " << E.File;
         break;
-      case DW_MACINFO_end_file:
+      case DW_MACRO_end_file:
         break;
       case DW_MACINFO_vendor_ext:
         OS << " - constant: " << E.ExtConstant;
@@ -55,23 +81,29 @@ void DWARFDebugMacro::dump(raw_ostream &OS) const {
   }
 }
 
-void DWARFDebugMacro::parse(DataExtractor data) {
+Error DWARFDebugMacro::parse(DataExtractor StringExtractor,
+                             DWARFDataExtractor Data, bool IsMacro) {
   uint64_t Offset = 0;
   MacroList *M = nullptr;
-  while (data.isValidOffset(Offset)) {
+  while (Data.isValidOffset(Offset)) {
     if (!M) {
       MacroLists.emplace_back();
       M = &MacroLists.back();
       M->Offset = Offset;
+      if (IsMacro) {
+        auto Err = M->Header.parseMacroHeader(Data, &Offset);
+        if (Err)
+          return std::move(Err);
+      }
     }
     // A macro list entry consists of:
     M->Macros.emplace_back();
     Entry &E = M->Macros.back();
     // 1. Macinfo type
-    E.Type = data.getULEB128(&Offset);
+    E.Type = Data.getULEB128(&Offset);
 
     if (E.Type == 0) {
-      // Reached end of a ".debug_macinfo" section contribution.
+      // Reached end of a ".debug_macinfo/debug_macro" section contribution.
       M = nullptr;
       continue;
     }
@@ -81,28 +113,64 @@ void DWARFDebugMacro::parse(DataExtractor data) {
       // Got a corrupted ".debug_macinfo" section (invalid macinfo type).
       // Push the corrupted entry to the list and halt parsing.
       E.Type = DW_MACINFO_invalid;
-      return;
-    case DW_MACINFO_define:
-    case DW_MACINFO_undef:
+      return Error::success();
+    // debug_macro and debug_macinfo share some common encodings.
+    // DW_MACRO_define     == DW_MACINFO_define
+    // DW_MACRO_undef      == DW_MACINFO_undef
+    // DW_MACRO_start_file == DW_MACINFO_start_file
+    // DW_MACRO_end_file   == DW_MACINFO_end_file
+    // For readibility/uniformity we are using DW_MACRO_*.
+    case DW_MACRO_define:
+    case DW_MACRO_undef:
       // 2. Source line
-      E.Line = data.getULEB128(&Offset);
+      E.Line = Data.getULEB128(&Offset);
       // 3. Macro string
-      E.MacroStr = data.getCStr(&Offset);
+      E.MacroStr = Data.getCStr(&Offset);
       break;
-    case DW_MACINFO_start_file:
+    case DW_MACRO_define_strp:
+    case DW_MACRO_undef_strp: {
+      uint64_t StrOffset = 0;
       // 2. Source line
-      E.Line = data.getULEB128(&Offset);
+      E.Line = Data.getULEB128(&Offset);
+      // 3. Macro string
+      // FIXME: Add support for DWARF64
+      StrOffset = Data.getRelocatedValue(/*OffsetSize=*/4, &Offset);
+      E.MacroStr = StringExtractor.getCStr(&StrOffset);
+      break;
+    }
+    case DW_MACRO_start_file:
+      // 2. Source line
+      E.Line = Data.getULEB128(&Offset);
       // 3. Source file id
-      E.File = data.getULEB128(&Offset);
+      E.File = Data.getULEB128(&Offset);
       break;
-    case DW_MACINFO_end_file:
+    case DW_MACRO_end_file:
       break;
     case DW_MACINFO_vendor_ext:
       // 2. Vendor extension constant
-      E.ExtConstant = data.getULEB128(&Offset);
+      E.ExtConstant = Data.getULEB128(&Offset);
       // 3. Vendor extension string
-      E.ExtStr = data.getCStr(&Offset);
+      E.ExtStr = Data.getCStr(&Offset);
       break;
     }
   }
+  return Error::success();
+}
+
+Error DWARFDebugMacro::MacroHeader::parseMacroHeader(DWARFDataExtractor Data,
+                                                     uint64_t *Offset) {
+  Version = Data.getU16(Offset);
+  uint8_t FlagData = Data.getU8(Offset);
+  // FIXME: Add support for DWARF64
+  if (FlagData & MACRO_OFFSET_SIZE)
+    return createStringError(errc::not_supported, "DWARF64 is not supported");
+
+  // FIXME: Add support for parsing opcode_operands_table
+  if (FlagData & MACRO_OPCODE_OPERANDS_TABLE)
+    return createStringError(errc::not_supported,
+                             "opcode_operands_table is not supported");
+  Flags = FlagData;
+  if (Flags & MACRO_DEBUG_LINE_OFFSET)
+    DebugLineOffset = Data.getU32(Offset);
+  return Error::success();
 }

diff  --git a/llvm/test/DebugInfo/X86/debug-macro-macinfo.s b/llvm/test/DebugInfo/X86/debug-macro-macinfo.s
new file mode 100644
index 000000000000..a5337cafc907
--- /dev/null
+++ b/llvm/test/DebugInfo/X86/debug-macro-macinfo.s
@@ -0,0 +1,47 @@
+## This test checks that llvm-dwarfdump can dump both debug_macro and debug_macinfo
+## sections present in the same object.
+
+# RUN: llvm-mc -triple x86_64-unknown-linux -filetype=obj %s -o -| \
+# RUN:   llvm-dwarfdump -debug-macro - | FileCheck -strict-whitespace -match-full-lines %s
+
+#      CHECK:.debug_macro contents:
+# CHECK-NEXT:0x00000000:
+# CHECK-NEXT:macro header: version = 0x0005, flags = 0x02, debug_line_offset = 0x0000
+# CHECK-NEXT:DW_MACRO_start_file - lineno: 0 filenum: 0
+# CHECK-NEXT:  DW_MACRO_define_strp - lineno: 1 macro: DWARF_VERSION 5
+# CHECK-NEXT:DW_MACRO_end_file
+
+#      CHECK:.debug_macinfo contents:
+# CHECK-NEXT:0x00000000:
+# CHECK-NEXT:DW_MACINFO_start_file - lineno: 0 filenum: 2
+# CHECK-NEXT:  DW_MACINFO_define - lineno: 6 macro: DWARF_VERSION 4
+# CHECK-NEXT:DW_MACINFO_end_file
+
+	.section	.debug_macro,"", at progbits
+.Lcu_macro_begin0:
+	.short	5                      # Macro information version
+	.byte	2                       # Flags: 32 bit, debug_line_offset present
+	.long	0                       # debug_line_offset
+	.byte	3                       # DW_MACRO_start_file
+	.byte	0                       # Line Number
+	.byte	0                       # File Number
+	.byte	5                       # DW_MACRO_define_strp
+	.byte	1                       # Line Number
+	.long	.Linfo_string0          # Macro String
+	.byte	4                       # DW_MACRO_end_file
+	.byte	0                       # End Of Macro List Mark
+
+	.section	.debug_macinfo,"", at progbits
+.Lcu_macro_begin1:
+	.byte	3                       # DW_MACINFO_start_file
+	.byte	0                       # Line Number
+	.byte	2                       # File Number
+	.byte	1                       # DW_MACINFO_define
+	.byte	6                       # Line Number
+	.asciz	"DWARF_VERSION 4"      # Macro String
+	.byte	4                       # DW_MACINFO_end_file
+	.byte	0                       # End Of Macro List Mark
+
+	.section	.debug_str,"MS", at progbits,1
+.Linfo_string0:
+	.asciz	"DWARF_VERSION 5"

diff  --git a/llvm/test/DebugInfo/X86/debug-macro-v5.s b/llvm/test/DebugInfo/X86/debug-macro-v5.s
new file mode 100644
index 000000000000..b4e577257455
--- /dev/null
+++ b/llvm/test/DebugInfo/X86/debug-macro-v5.s
@@ -0,0 +1,54 @@
+## This test checks llvm-dwarfdump can dump debug_macro section containing
+## multiple macro units.
+
+# RUN: llvm-mc -triple x86_64-unknown-linux -filetype=obj %s -o -| \
+# RUN:   llvm-dwarfdump -debug-macro - | FileCheck -strict-whitespace -match-full-lines %s
+
+#      CHECK:.debug_macro contents:
+# CHECK-NEXT:0x00000000:
+# CHECK-NEXT:macro header: version = 0x0005, flags = 0x02, debug_line_offset = 0x0000
+# CHECK-NEXT:DW_MACRO_start_file - lineno: 0 filenum: 0
+# CHECK-NEXT:  DW_MACRO_start_file - lineno: 1 filenum: 6
+# CHECK-NEXT:    DW_MACRO_define_strp - lineno: 1 macro: FOO 5
+# CHECK-NEXT:  DW_MACRO_end_file
+# CHECK-NEXT:  DW_MACRO_undef_strp - lineno: 8 macro: WORLD1
+# CHECK-NEXT:DW_MACRO_end_file
+
+#      CHECK:0x{{.*}}:
+# CHECK-NEXT:macro header: version = 0x0005, flags = 0x00
+# CHECK-NEXT:DW_MACRO_define_strp - lineno: 0 macro: WORLD 2
+
+	.section	.debug_macro,"", at progbits
+.Lcu_macro_begin0:
+	.short	5                      # Macro information version
+	.byte	2                       # Flags: 32 bit, debug_line_offset present
+	.long	0                       # debug_line_offset
+	.byte	3                       # DW_MACRO_start_file
+	.byte	0                       # Line Number
+	.byte	0                       # File Number
+	.byte	3                       # DW_MACRO_start_file
+	.byte	1                       # Line Number
+	.byte	6                       # File Number
+	.byte	5                       # DW_MACRO_define_strp
+	.byte	1                       # Line Number
+	.long	.Linfo_string0          # Macro String
+	.byte	4                       # DW_MACRO_end_file
+	.byte	6                       # DW_MACRO_undef_strp
+	.byte	8                       # Line Number
+	.long	.Linfo_string1          # Macro String
+	.byte	4                       # DW_MACRO_end_file
+	.byte	0                       # End Of Macro List Mark
+	.short	5                      # Macro information version
+	.byte	0                       # Flags: 32 bit
+	.byte	5                       # DW_MACRO_define_strp
+	.byte	0                       # Line Number
+	.long	.Linfo_string2          # Macro String
+	.byte	0                       # End Of Macro List Mark
+
+	.section	.debug_str,"MS", at progbits,1
+.Linfo_string0:
+	.asciz	"FOO 5"
+.Linfo_string1:
+	.asciz	"WORLD1"
+.Linfo_string2:
+	.asciz	"WORLD 2"

diff  --git a/llvm/test/DebugInfo/X86/unsupported-dwarf64-debug-macro-v5.s b/llvm/test/DebugInfo/X86/unsupported-dwarf64-debug-macro-v5.s
new file mode 100644
index 000000000000..a06c97ccf5e7
--- /dev/null
+++ b/llvm/test/DebugInfo/X86/unsupported-dwarf64-debug-macro-v5.s
@@ -0,0 +1,13 @@
+## This test checks llvm-dwarfdump emits correct error diagnostics for the
+## unsupported case where DWARF64 flag is present in the debug_macro section header.
+
+# RUN: llvm-mc -triple x86_64-unknown-linux -filetype=obj %s -o -| \
+# RUN:   not llvm-dwarfdump -debug-macro - /dev/null 2>&1 | FileCheck %s
+
+# CHECK:error: DWARF64 is not supported
+
+	.section	.debug_macro,"", at progbits
+.Lcu_macro_begin0:
+	.short	5                      # Macro information version
+	.byte	3                       # Flags: 64 bit, debug_line_offset present
+	.quad	0                       # debug_line_offset

diff  --git a/llvm/test/DebugInfo/X86/unsupported-opcode_operands_table-debug-macro-v5.s b/llvm/test/DebugInfo/X86/unsupported-opcode_operands_table-debug-macro-v5.s
new file mode 100644
index 000000000000..39e557ec5c4e
--- /dev/null
+++ b/llvm/test/DebugInfo/X86/unsupported-opcode_operands_table-debug-macro-v5.s
@@ -0,0 +1,13 @@
+## This test checks llvm-dwarfdump emits correct error diagnostics for the
+## unsupported case where the opcode_operands_table flag is present in the
+## debug_macro section header.
+
+# RUN: llvm-mc -triple x86_64-unknown-linux -filetype=obj %s -o -| \
+# RUN:   not llvm-dwarfdump -debug-macro - /dev/null 2>&1 | FileCheck %s
+
+# CHECK:error: opcode_operands_table is not supported
+
+	.section	.debug_macro,"", at progbits
+.Lcu_macro_begin0:
+	.short	5                      # Macro information version
+	.byte	4                       # Flags: 32 bit, debug_line_offset absent, opcode_operands_table present


        


More information about the llvm-commits mailing list