]> granicus.if.org Git - llvm/commitdiff
[ObjectYAML] Support for DWARF line tables
authorChris Bieneman <beanz@apple.com>
Tue, 10 Jan 2017 06:22:49 +0000 (06:22 +0000)
committerChris Bieneman <beanz@apple.com>
Tue, 10 Jan 2017 06:22:49 +0000 (06:22 +0000)
One more try... relanding r291541 with a fix to properly gate MaxOpsPerInst on DWARF version.

Description from r291541:

This patch re-lands r291470, which failed on Linux bots. The issue (I believe) was undefined behavior because the size of llvm::dwarf::LineNumberOps was not explcitly specified or consistently respected. The updated patch adds an explcit underlying type to the enum and preserves the size more correctly.

Original description:

This patch adds support for the DWARF debug_lines section. The line table state machine opcodes are preserved, so this can be used to test the state machine evaluation directly.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@291546 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/ObjectYAML/DWARFYAML.h
include/llvm/ObjectYAML/MachOYAML.h
include/llvm/Support/Dwarf.h
lib/ObjectYAML/DWARFYAML.cpp
test/ObjectYAML/MachO/DWARF-debug_info.yaml
test/ObjectYAML/MachO/DWARF-debug_line.yaml [new file with mode: 0644]
tools/obj2yaml/dwarf2yaml.cpp
tools/yaml2obj/yaml2dwarf.cpp
tools/yaml2obj/yaml2macho.cpp
tools/yaml2obj/yaml2obj.h

index 222cad61a9923b05257a95ce07fcc7ebc183c15d..d031b5ac404c5164e8ac465894e82389644b6891 100644 (file)
@@ -85,6 +85,41 @@ struct Unit {
   std::vector<Entry> Entries;
 };
 
+struct File {
+  StringRef Name;
+  uint64_t DirIdx;
+  uint64_t ModTime;
+  uint64_t Length;
+};
+
+struct LineTableOpcode {
+  dwarf::LineNumberOps Opcode;
+  uint64_t ExtLen;
+  dwarf::LineNumberExtendedOps SubOpcode;
+  uint64_t Data;
+  int64_t SData;
+  File FileEntry;
+  std::vector<llvm::yaml::Hex8> UnknownOpcodeData;
+  std::vector<llvm::yaml::Hex64> StandardOpcodeData;
+};
+
+struct LineTable {
+  uint32_t TotalLength;
+  uint64_t TotalLength64;
+  uint16_t Version;
+  uint64_t PrologueLength;
+  uint8_t MinInstLength;
+  uint8_t MaxOpsPerInst;
+  uint8_t DefaultIsStmt;
+  uint8_t LineBase;
+  uint8_t LineRange;
+  uint8_t OpcodeBase;
+  std::vector<uint8_t> StandardOpcodeLengths;
+  std::vector<StringRef> IncludeDirs;
+  std::vector<File> Files;
+  std::vector<LineTableOpcode> Opcodes;
+};
+
 struct Data {
   bool IsLittleEndian;
   std::vector<Abbrev> AbbrevDecls;
@@ -98,6 +133,8 @@ struct Data {
   
   std::vector<Unit> CompileUnits;
 
+  std::vector<LineTable> DebugLines;
+
   bool isEmpty() const;
 };
 
@@ -105,6 +142,7 @@ struct Data {
 } // namespace llvm
 
 LLVM_YAML_IS_SEQUENCE_VECTOR(uint8_t)
+LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::yaml::Hex64)
 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::StringRef)
 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::yaml::Hex8)
 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DWARFYAML::AttributeAbbrev)
@@ -115,6 +153,9 @@ LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DWARFYAML::PubEntry)
 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DWARFYAML::Unit)
 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DWARFYAML::FormValue)
 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DWARFYAML::Entry)
+LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DWARFYAML::File)
+LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DWARFYAML::LineTable)
+LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DWARFYAML::LineTableOpcode)
 
 namespace llvm {
 namespace yaml {
@@ -159,6 +200,18 @@ template <> struct MappingTraits<DWARFYAML::FormValue> {
   static void mapping(IO &IO, DWARFYAML::FormValue &FormValue);
 };
 
+template <> struct MappingTraits<DWARFYAML::File> {
+  static void mapping(IO &IO, DWARFYAML::File &File);
+};
+  
+template <> struct MappingTraits<DWARFYAML::LineTableOpcode> {
+  static void mapping(IO &IO, DWARFYAML::LineTableOpcode &LineTableOpcode);
+};
+
+template <> struct MappingTraits<DWARFYAML::LineTable> {
+  static void mapping(IO &IO, DWARFYAML::LineTable &LineTable);
+};
+
 #define HANDLE_DW_TAG(unused, name)                                            \
   io.enumCase(value, "DW_TAG_" #name, dwarf::DW_TAG_##name);
 
@@ -169,6 +222,26 @@ template <> struct ScalarEnumerationTraits<dwarf::Tag> {
   }
 };
 
+#define HANDLE_DW_LNS(unused, name)                                            \
+  io.enumCase(value, "DW_LNS_" #name, dwarf::DW_LNS_##name);
+
+template <> struct ScalarEnumerationTraits<dwarf::LineNumberOps> {
+  static void enumeration(IO &io, dwarf::LineNumberOps &value) {
+#include "llvm/Support/Dwarf.def"
+    io.enumFallback<Hex8>(value);
+  }
+};
+
+#define HANDLE_DW_LNE(unused, name)                                            \
+  io.enumCase(value, "DW_LNE_" #name, dwarf::DW_LNE_##name);
+
+template <> struct ScalarEnumerationTraits<dwarf::LineNumberExtendedOps> {
+  static void enumeration(IO &io, dwarf::LineNumberExtendedOps &value) {
+#include "llvm/Support/Dwarf.def"
+    io.enumFallback<Hex16>(value);
+  }
+};
+
 #define HANDLE_DW_AT(unused, name)                                             \
   io.enumCase(value, "DW_AT_" #name, dwarf::DW_AT_##name);
 
index 6b7a924f514381f0c91ff9c9092fd26620028dd5..9ec32d265bcae3ce4bf6a552109de8866daebd20 100644 (file)
@@ -139,7 +139,6 @@ struct UniversalBinary {
 
 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::MachOYAML::LoadCommand)
 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::MachOYAML::Section)
-LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::yaml::Hex64)
 LLVM_YAML_IS_SEQUENCE_VECTOR(int64_t)
 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::MachOYAML::RebaseOpcode)
 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::MachOYAML::BindOpcode)
index 1a984037da0909906c18183bd728ebb1512d109b..8336b9df9df0d890bf302712de51b93992658a82 100644 (file)
@@ -207,7 +207,7 @@ enum DiscriminantList {
 };
 
 /// Line Number Standard Opcode Encodings.
-enum LineNumberOps {
+enum LineNumberOps : uint8_t {
 #define HANDLE_DW_LNS(ID, NAME) DW_LNS_##NAME = ID,
 #include "llvm/Support/Dwarf.def"
 };
index 42a448a7bdfdf8d93bf3b42893df6e8e27ea8965..014e63fe7d34063ccd3ddb51df19964d417d9fc8 100644 (file)
@@ -27,17 +27,18 @@ void MappingTraits<DWARFYAML::Data>::mapping(IO &IO, DWARFYAML::Data &DWARF) {
   IO.setContext(&DWARF);
   IO.mapOptional("debug_str", DWARF.DebugStrings);
   IO.mapOptional("debug_abbrev", DWARF.AbbrevDecls);
-  if(!DWARF.ARanges.empty() || !IO.outputting())
+  if (!DWARF.ARanges.empty() || !IO.outputting())
     IO.mapOptional("debug_aranges", DWARF.ARanges);
-  if(!DWARF.PubNames.Entries.empty() || !IO.outputting())
+  if (!DWARF.PubNames.Entries.empty() || !IO.outputting())
     IO.mapOptional("debug_pubnames", DWARF.PubNames);
-  if(!DWARF.PubTypes.Entries.empty() || !IO.outputting())
+  if (!DWARF.PubTypes.Entries.empty() || !IO.outputting())
     IO.mapOptional("debug_pubtypes", DWARF.PubTypes);
-  if(!DWARF.GNUPubNames.Entries.empty() || !IO.outputting())
+  if (!DWARF.GNUPubNames.Entries.empty() || !IO.outputting())
     IO.mapOptional("debug_gnu_pubnames", DWARF.GNUPubNames);
-  if(!DWARF.GNUPubTypes.Entries.empty() || !IO.outputting())
+  if (!DWARF.GNUPubTypes.Entries.empty() || !IO.outputting())
     IO.mapOptional("debug_gnu_pubtypes", DWARF.GNUPubTypes);
   IO.mapOptional("debug_info", DWARF.CompileUnits);
+  IO.mapOptional("debug_line", DWARF.DebugLines);
   IO.setContext(&oldContext);
 }
 
@@ -62,7 +63,7 @@ void MappingTraits<DWARFYAML::ARangeDescriptor>::mapping(
 }
 
 void MappingTraits<DWARFYAML::ARange>::mapping(IO &IO,
-                                                DWARFYAML::ARange &Range) {
+                                               DWARFYAML::ARange &Range) {
   IO.mapRequired("Length", Range.Length);
   IO.mapRequired("Version", Range.Version);
   IO.mapRequired("CuOffset", Range.CuOffset);
@@ -106,15 +107,61 @@ void MappingTraits<DWARFYAML::Entry>::mapping(IO &IO, DWARFYAML::Entry &Entry) {
   IO.mapRequired("Values", Entry.Values);
 }
 
-void MappingTraits<DWARFYAML::FormValue>::mapping(IO &IO,
-                                             DWARFYAML::FormValue &FormValue) {
+void MappingTraits<DWARFYAML::FormValue>::mapping(
+    IO &IO, DWARFYAML::FormValue &FormValue) {
   IO.mapOptional("Value", FormValue.Value);
-  if(!FormValue.CStr.empty() || !IO.outputting())
+  if (!FormValue.CStr.empty() || !IO.outputting())
     IO.mapOptional("CStr", FormValue.CStr);
-  if(!FormValue.BlockData.empty() || !IO.outputting())
+  if (!FormValue.BlockData.empty() || !IO.outputting())
     IO.mapOptional("BlockData", FormValue.BlockData);
 }
 
+void MappingTraits<DWARFYAML::File>::mapping(IO &IO, DWARFYAML::File &File) {
+  IO.mapRequired("Name", File.Name);
+  IO.mapRequired("DirIdx", File.DirIdx);
+  IO.mapRequired("ModTime", File.ModTime);
+  IO.mapRequired("Length", File.Length);
+}
+
+void MappingTraits<DWARFYAML::LineTableOpcode>::mapping(
+    IO &IO, DWARFYAML::LineTableOpcode &LineTableOpcode) {
+  IO.mapRequired("Opcode", LineTableOpcode.Opcode);
+  if (LineTableOpcode.Opcode == dwarf::DW_LNS_extended_op) {
+    IO.mapRequired("ExtLen", LineTableOpcode.ExtLen);
+    IO.mapRequired("SubOpcode", LineTableOpcode.SubOpcode);
+  }
+
+  if (!LineTableOpcode.UnknownOpcodeData.empty() || !IO.outputting())
+    IO.mapOptional("UnknownOpcodeData", LineTableOpcode.UnknownOpcodeData);
+  if (!LineTableOpcode.UnknownOpcodeData.empty() || !IO.outputting())
+    IO.mapOptional("StandardOpcodeData", LineTableOpcode.StandardOpcodeData);
+  if (!LineTableOpcode.FileEntry.Name.empty() || !IO.outputting())
+    IO.mapOptional("FileEntry", LineTableOpcode.FileEntry);
+  if (LineTableOpcode.Opcode == dwarf::DW_LNS_advance_line || !IO.outputting())
+    IO.mapOptional("SData", LineTableOpcode.SData);
+  IO.mapOptional("Data", LineTableOpcode.Data);
+}
+
+void MappingTraits<DWARFYAML::LineTable>::mapping(
+    IO &IO, DWARFYAML::LineTable &LineTable) {
+  IO.mapRequired("TotalLength", LineTable.TotalLength);
+  if (LineTable.TotalLength == UINT32_MAX)
+    IO.mapRequired("TotalLength64", LineTable.TotalLength64);
+  IO.mapRequired("Version", LineTable.Version);
+  IO.mapRequired("PrologueLength", LineTable.PrologueLength);
+  IO.mapRequired("MinInstLength", LineTable.MinInstLength);
+  if(LineTable.Version >= 4)
+    IO.mapRequired("MaxOpsPerInst", LineTable.MaxOpsPerInst);
+  IO.mapRequired("DefaultIsStmt", LineTable.DefaultIsStmt);
+  IO.mapRequired("LineBase", LineTable.LineBase);
+  IO.mapRequired("LineRange", LineTable.LineRange);
+  IO.mapRequired("OpcodeBase", LineTable.OpcodeBase);
+  IO.mapRequired("StandardOpcodeLengths", LineTable.StandardOpcodeLengths);
+  IO.mapRequired("IncludeDirs", LineTable.IncludeDirs);
+  IO.mapRequired("Files", LineTable.Files);
+  IO.mapRequired("Opcodes", LineTable.Opcodes);
+}
+
 } // namespace llvm::yaml
 
 } // namespace llvm
index 9a616e9afb9d51bcb361c6c4242e6dc7dd83be05..b1b6b8ad19e8ce91ba441062909c108299e34ac1 100644 (file)
@@ -451,6 +451,58 @@ DWARF:
             - Value:           0x0000000000000001
         - AbbrCode:        0x00000000
           Values:          
+  debug_line:      
+    - TotalLength:     65
+      Version:         2
+      PrologueLength:  36
+      MinInstLength:   1
+      DefaultIsStmt:   1
+      LineBase:        251
+      LineRange:       14
+      OpcodeBase:      13
+      StandardOpcodeLengths: 
+        - 0
+        - 1
+        - 1
+        - 1
+        - 1
+        - 0
+        - 0
+        - 0
+        - 1
+        - 0
+        - 0
+        - 1
+      IncludeDirs:     
+      Files:           
+        - Name:            hello_world.c
+          DirIdx:          0
+          ModTime:         0
+          Length:          0
+      Opcodes:         
+        - Opcode:          DW_LNS_extended_op
+          ExtLen:          9
+          SubOpcode:       DW_LNE_set_address
+          Data:            4294971216
+        - Opcode:          0x14
+          Data:            4294971216
+        - Opcode:          DW_LNS_set_column
+          Data:            3
+        - Opcode:          DW_LNS_set_prologue_end
+          Data:            3
+        - Opcode:          DW_LNS_const_add_pc
+          Data:            3
+        - Opcode:          0xBB
+          Data:            3
+        - Opcode:          0xBB
+          Data:            3
+        - Opcode:          DW_LNS_advance_pc
+          Data:            11
+        - Opcode:          DW_LNS_extended_op
+          ExtLen:          1
+          SubOpcode:       DW_LNE_end_sequence
+          Data:            11
+...
 ...
 
 
diff --git a/test/ObjectYAML/MachO/DWARF-debug_line.yaml b/test/ObjectYAML/MachO/DWARF-debug_line.yaml
new file mode 100644 (file)
index 0000000..f461b78
--- /dev/null
@@ -0,0 +1,596 @@
+# RUN: yaml2obj %s | obj2yaml | FileCheck %s
+
+--- !mach-o
+FileHeader:      
+  magic:           0xFEEDFACF
+  cputype:         0x01000007
+  cpusubtype:      0x00000003
+  filetype:        0x0000000A
+  ncmds:           7
+  sizeofcmds:      1848
+  flags:           0x00000000
+  reserved:        0x00000000
+LoadCommands:    
+  - cmd:             LC_UUID
+    cmdsize:         24
+    uuid:            B4D48511-37F4-3ED4-AFA7-1683DCE69AC4
+  - cmd:             LC_SYMTAB
+    cmdsize:         24
+    symoff:          4096
+    nsyms:           2
+    stroff:          4128
+    strsize:         28
+  - cmd:             LC_SEGMENT_64
+    cmdsize:         72
+    segname:         __PAGEZERO
+    vmaddr:          0
+    vmsize:          4294967296
+    fileoff:         0
+    filesize:        0
+    maxprot:         0
+    initprot:        0
+    nsects:          0
+    flags:           0
+  - cmd:             LC_SEGMENT_64
+    cmdsize:         472
+    segname:         __TEXT
+    vmaddr:          4294967296
+    vmsize:          4096
+    fileoff:         0
+    filesize:        0
+    maxprot:         7
+    initprot:        5
+    nsects:          5
+    flags:           0
+    Sections:        
+      - sectname:        __text
+        segname:         __TEXT
+        addr:            0x0000000100000F50
+        size:            52
+        offset:          0x00000000
+        align:           4
+        reloff:          0x00000000
+        nreloc:          0
+        flags:           0x80000400
+        reserved1:       0x00000000
+        reserved2:       0x00000000
+        reserved3:       0x00000000
+      - sectname:        __stubs
+        segname:         __TEXT
+        addr:            0x0000000100000F84
+        size:            6
+        offset:          0x00000000
+        align:           1
+        reloff:          0x00000000
+        nreloc:          0
+        flags:           0x80000408
+        reserved1:       0x00000000
+        reserved2:       0x00000006
+        reserved3:       0x00000000
+      - sectname:        __stub_helper
+        segname:         __TEXT
+        addr:            0x0000000100000F8C
+        size:            26
+        offset:          0x00000000
+        align:           2
+        reloff:          0x00000000
+        nreloc:          0
+        flags:           0x80000400
+        reserved1:       0x00000000
+        reserved2:       0x00000000
+        reserved3:       0x00000000
+      - sectname:        __cstring
+        segname:         __TEXT
+        addr:            0x0000000100000FA6
+        size:            14
+        offset:          0x00000000
+        align:           0
+        reloff:          0x00000000
+        nreloc:          0
+        flags:           0x00000002
+        reserved1:       0x00000000
+        reserved2:       0x00000000
+        reserved3:       0x00000000
+      - sectname:        __unwind_info
+        segname:         __TEXT
+        addr:            0x0000000100000FB4
+        size:            72
+        offset:          0x00000000
+        align:           2
+        reloff:          0x00000000
+        nreloc:          0
+        flags:           0x00000000
+        reserved1:       0x00000000
+        reserved2:       0x00000000
+        reserved3:       0x00000000
+  - cmd:             LC_SEGMENT_64
+    cmdsize:         232
+    segname:         __DATA
+    vmaddr:          4294971392
+    vmsize:          4096
+    fileoff:         0
+    filesize:        0
+    maxprot:         7
+    initprot:        3
+    nsects:          2
+    flags:           0
+    Sections:        
+      - sectname:        __nl_symbol_ptr
+        segname:         __DATA
+        addr:            0x0000000100001000
+        size:            16
+        offset:          0x00000000
+        align:           3
+        reloff:          0x00000000
+        nreloc:          0
+        flags:           0x00000006
+        reserved1:       0x00000001
+        reserved2:       0x00000000
+        reserved3:       0x00000000
+      - sectname:        __la_symbol_ptr
+        segname:         __DATA
+        addr:            0x0000000100001010
+        size:            8
+        offset:          0x00000000
+        align:           3
+        reloff:          0x00000000
+        nreloc:          0
+        flags:           0x00000007
+        reserved1:       0x00000003
+        reserved2:       0x00000000
+        reserved3:       0x00000000
+  - cmd:             LC_SEGMENT_64
+    cmdsize:         72
+    segname:         __LINKEDIT
+    vmaddr:          4294975488
+    vmsize:          4096
+    fileoff:         4096
+    filesize:        60
+    maxprot:         7
+    initprot:        1
+    nsects:          0
+    flags:           0
+  - cmd:             LC_SEGMENT_64
+    cmdsize:         952
+    segname:         __DWARF
+    vmaddr:          4294979584
+    vmsize:          4096
+    fileoff:         8192
+    filesize:        764
+    maxprot:         7
+    initprot:        3
+    nsects:          11
+    flags:           0
+    Sections:        
+      - sectname:        __debug_line
+        segname:         __DWARF
+        addr:            0x0000000100003000
+        size:            69
+        offset:          0x00002000
+        align:           0
+        reloff:          0x00000000
+        nreloc:          0
+        flags:           0x00000000
+        reserved1:       0x00000000
+        reserved2:       0x00000000
+        reserved3:       0x00000000
+      - sectname:        __debug_pubnames
+        segname:         __DWARF
+        addr:            0x0000000100003045
+        size:            27
+        offset:          0x00002045
+        align:           0
+        reloff:          0x00000000
+        nreloc:          0
+        flags:           0x00000000
+        reserved1:       0x00000000
+        reserved2:       0x00000000
+        reserved3:       0x00000000
+      - sectname:        __debug_pubtypes
+        segname:         __DWARF
+        addr:            0x0000000100003060
+        size:            35
+        offset:          0x00002060
+        align:           0
+        reloff:          0x00000000
+        nreloc:          0
+        flags:           0x00000000
+        reserved1:       0x00000000
+        reserved2:       0x00000000
+        reserved3:       0x00000000
+      - sectname:        __debug_aranges
+        segname:         __DWARF
+        addr:            0x0000000100003083
+        size:            48
+        offset:          0x00002083
+        align:           0
+        reloff:          0x00000000
+        nreloc:          0
+        flags:           0x00000000
+        reserved1:       0x00000000
+        reserved2:       0x00000000
+        reserved3:       0x00000000
+      - sectname:        __debug_info
+        segname:         __DWARF
+        addr:            0x00000001000030B3
+        size:            121
+        offset:          0x000020B3
+        align:           0
+        reloff:          0x00000000
+        nreloc:          0
+        flags:           0x00000000
+        reserved1:       0x00000000
+        reserved2:       0x00000000
+        reserved3:       0x00000000
+      - sectname:        __debug_abbrev
+        segname:         __DWARF
+        addr:            0x000000010000312C
+        size:            76
+        offset:          0x0000212C
+        align:           0
+        reloff:          0x00000000
+        nreloc:          0
+        flags:           0x00000000
+        reserved1:       0x00000000
+        reserved2:       0x00000000
+        reserved3:       0x00000000
+      - sectname:        __debug_str
+        segname:         __DWARF
+        addr:            0x0000000100003178
+        size:            142
+        offset:          0x00002178
+        align:           0
+        reloff:          0x00000000
+        nreloc:          0
+        flags:           0x00000000
+        reserved1:       0x00000000
+        reserved2:       0x00000000
+        reserved3:       0x00000000
+      - sectname:        __apple_names
+        segname:         __DWARF
+        addr:            0x0000000100003206
+        size:            60
+        offset:          0x00002206
+        align:           0
+        reloff:          0x00000000
+        nreloc:          0
+        flags:           0x00000000
+        reserved1:       0x00000000
+        reserved2:       0x00000000
+        reserved3:       0x00000000
+      - sectname:        __apple_namespac
+        segname:         __DWARF
+        addr:            0x0000000100003242
+        size:            36
+        offset:          0x00002242
+        align:           0
+        reloff:          0x00000000
+        nreloc:          0
+        flags:           0x00000000
+        reserved1:       0x00000000
+        reserved2:       0x00000000
+        reserved3:       0x00000000
+      - sectname:        __apple_types
+        segname:         __DWARF
+        addr:            0x0000000100003266
+        size:            114
+        offset:          0x00002266
+        align:           0
+        reloff:          0x00000000
+        nreloc:          0
+        flags:           0x00000000
+        reserved1:       0x00000000
+        reserved2:       0x00000000
+        reserved3:       0x00000000
+      - sectname:        __apple_objc
+        segname:         __DWARF
+        addr:            0x00000001000032D8
+        size:            36
+        offset:          0x000022D8
+        align:           0
+        reloff:          0x00000000
+        nreloc:          0
+        flags:           0x00000000
+        reserved1:       0x00000000
+        reserved2:       0x00000000
+        reserved3:       0x00000000
+LinkEditData:    
+  NameList:        
+    - n_strx:          2
+      n_type:          0x0F
+      n_sect:          1
+      n_desc:          16
+      n_value:         4294967296
+    - n_strx:          22
+      n_type:          0x0F
+      n_sect:          1
+      n_desc:          0
+      n_value:         4294971216
+  StringTable:     
+    - ''
+    - ''
+    - __mh_execute_header
+    - _main
+DWARF:           
+  debug_str:       
+    - ''
+    - 'clang version 4.0.0 (trunk 288923) (llvm/trunk 288991)'
+    - hello_world.c
+    - /Users/cbieneman/dev/open-source/llvm-build-rel
+    - main
+    - argc
+    - argv
+    - int
+    - char
+  debug_abbrev:    
+    - Code:            0x00000001
+      Tag:             DW_TAG_compile_unit
+      Children:        DW_CHILDREN_yes
+      Attributes:      
+        - Attribute:       DW_AT_producer
+          Form:            DW_FORM_strp
+        - Attribute:       DW_AT_language
+          Form:            DW_FORM_data2
+        - Attribute:       DW_AT_name
+          Form:            DW_FORM_strp
+        - Attribute:       DW_AT_stmt_list
+          Form:            DW_FORM_sec_offset
+        - Attribute:       DW_AT_comp_dir
+          Form:            DW_FORM_strp
+        - Attribute:       DW_AT_low_pc
+          Form:            DW_FORM_addr
+        - Attribute:       DW_AT_high_pc
+          Form:            DW_FORM_data4
+    - Code:            0x00000002
+      Tag:             DW_TAG_subprogram
+      Children:        DW_CHILDREN_yes
+      Attributes:      
+        - Attribute:       DW_AT_low_pc
+          Form:            DW_FORM_addr
+        - Attribute:       DW_AT_high_pc
+          Form:            DW_FORM_data4
+        - Attribute:       DW_AT_frame_base
+          Form:            DW_FORM_exprloc
+        - Attribute:       DW_AT_name
+          Form:            DW_FORM_strp
+        - Attribute:       DW_AT_decl_file
+          Form:            DW_FORM_data1
+        - Attribute:       DW_AT_decl_line
+          Form:            DW_FORM_data1
+        - Attribute:       DW_AT_prototyped
+          Form:            DW_FORM_flag_present
+        - Attribute:       DW_AT_type
+          Form:            DW_FORM_ref4
+        - Attribute:       DW_AT_external
+          Form:            DW_FORM_flag_present
+    - Code:            0x00000003
+      Tag:             DW_TAG_formal_parameter
+      Children:        DW_CHILDREN_no
+      Attributes:      
+        - Attribute:       DW_AT_location
+          Form:            DW_FORM_exprloc
+        - Attribute:       DW_AT_name
+          Form:            DW_FORM_strp
+        - Attribute:       DW_AT_decl_file
+          Form:            DW_FORM_data1
+        - Attribute:       DW_AT_decl_line
+          Form:            DW_FORM_data1
+        - Attribute:       DW_AT_type
+          Form:            DW_FORM_ref4
+    - Code:            0x00000004
+      Tag:             DW_TAG_base_type
+      Children:        DW_CHILDREN_no
+      Attributes:      
+        - Attribute:       DW_AT_name
+          Form:            DW_FORM_strp
+        - Attribute:       DW_AT_encoding
+          Form:            DW_FORM_data1
+        - Attribute:       DW_AT_byte_size
+          Form:            DW_FORM_data1
+    - Code:            0x00000005
+      Tag:             DW_TAG_pointer_type
+      Children:        DW_CHILDREN_no
+      Attributes:      
+        - Attribute:       DW_AT_type
+          Form:            DW_FORM_ref4
+  debug_aranges:   
+    - Length:          44
+      Version:         2
+      CuOffset:        0
+      AddrSize:        8
+      SegSize:         0
+      Descriptors:     
+        - Address:         0x0000000100000F50
+          Length:          52
+  debug_pubnames:  
+    Length:          23
+    Version:         2
+    UnitOffset:      0
+    UnitSize:        121
+    Entries:         
+      - DieOffset:       0x0000002A
+        Name:            main
+  debug_pubtypes:  
+    Length:          31
+    Version:         2
+    UnitOffset:      0
+    UnitSize:        121
+    Entries:         
+      - DieOffset:       0x00000060
+        Name:            int
+      - DieOffset:       0x00000071
+        Name:            char
+  debug_info:      
+    - Length:          117
+      Version:         4
+      AbbrOffset:      0
+      AddrSize:        8
+      Entries:         
+        - AbbrCode:        0x00000001
+          Values:          
+            - Value:           0x0000000000000001
+            - Value:           0x000000000000000C
+            - Value:           0x0000000000000038
+            - Value:           0x0000000000000000
+            - Value:           0x0000000000000046
+            - Value:           0x0000000100000F50
+            - Value:           0x0000000000000034
+        - AbbrCode:        0x00000002
+          Values:          
+            - Value:           0x0000000100000F50
+            - Value:           0x0000000000000034
+            - Value:           0x0000000000000001
+              BlockData:       
+                - 0x56
+            - Value:           0x0000000000000076
+            - Value:           0x0000000000000001
+            - Value:           0x0000000000000003
+            - Value:           0x0000000000000001
+            - Value:           0x0000000000000060
+            - Value:           0x0000000000000001
+        - AbbrCode:        0x00000003
+          Values:          
+            - Value:           0x0000000000000002
+              BlockData:       
+                - 0x91
+                - 0x78
+            - Value:           0x000000000000007B
+            - Value:           0x0000000000000001
+            - Value:           0x0000000000000003
+            - Value:           0x0000000000000060
+        - AbbrCode:        0x00000003
+          Values:          
+            - Value:           0x0000000000000002
+              BlockData:       
+                - 0x91
+                - 0x70
+            - Value:           0x0000000000000080
+            - Value:           0x0000000000000001
+            - Value:           0x0000000000000003
+            - Value:           0x0000000000000067
+        - AbbrCode:        0x00000000
+          Values:          
+        - AbbrCode:        0x00000004
+          Values:          
+            - Value:           0x0000000000000085
+            - Value:           0x0000000000000005
+            - Value:           0x0000000000000004
+        - AbbrCode:        0x00000005
+          Values:          
+            - Value:           0x000000000000006C
+        - AbbrCode:        0x00000005
+          Values:          
+            - Value:           0x0000000000000071
+        - AbbrCode:        0x00000004
+          Values:          
+            - Value:           0x0000000000000089
+            - Value:           0x0000000000000006
+            - Value:           0x0000000000000001
+        - AbbrCode:        0x00000000
+          Values:          
+  debug_line:      
+    - TotalLength:     65
+      Version:         2
+      PrologueLength:  36
+      MinInstLength:   1
+      MaxOpsPerInst:   0
+      DefaultIsStmt:   1
+      LineBase:        251
+      LineRange:       14
+      OpcodeBase:      13
+      StandardOpcodeLengths: 
+        - 0
+        - 1
+        - 1
+        - 1
+        - 1
+        - 0
+        - 0
+        - 0
+        - 1
+        - 0
+        - 0
+        - 1
+      IncludeDirs:     
+      Files:           
+        - Name:            hello_world.c
+          DirIdx:          0
+          ModTime:         0
+          Length:          0
+      Opcodes:         
+        - Opcode:          DW_LNS_extended_op
+          ExtLen:          9
+          SubOpcode:       DW_LNE_set_address
+          Data:            4294971216
+        - Opcode:          0x14
+          Data:            4294971216
+        - Opcode:          DW_LNS_set_column
+          Data:            3
+        - Opcode:          DW_LNS_set_prologue_end
+          Data:            3
+        - Opcode:          DW_LNS_const_add_pc
+          Data:            3
+        - Opcode:          0xBB
+          Data:            3
+        - Opcode:          0xBB
+          Data:            3
+        - Opcode:          DW_LNS_advance_pc
+          Data:            11
+        - Opcode:          DW_LNS_extended_op
+          ExtLen:          1
+          SubOpcode:       DW_LNE_end_sequence
+          Data:            11
+...
+
+#CHECK:   debug_line:      
+#CHECK:     - TotalLength:     65
+#CHECK:       Version:         2
+#CHECK:       PrologueLength:  36
+#CHECK:       MinInstLength:   1
+#CHECK:       DefaultIsStmt:   1
+#CHECK:       LineBase:        251
+#CHECK:       LineRange:       14
+#CHECK:       OpcodeBase:      13
+#CHECK:       StandardOpcodeLengths: 
+#CHECK:         - 0
+#CHECK:         - 1
+#CHECK:         - 1
+#CHECK:         - 1
+#CHECK:         - 1
+#CHECK:         - 0
+#CHECK:         - 0
+#CHECK:         - 0
+#CHECK:         - 1
+#CHECK:         - 0
+#CHECK:         - 0
+#CHECK:         - 1
+#CHECK:       IncludeDirs:     
+#CHECK:       Files:           
+#CHECK:         - Name:            hello_world.c
+#CHECK:           DirIdx:          0
+#CHECK:           ModTime:         0
+#CHECK:           Length:          0
+#CHECK:       Opcodes:         
+#CHECK:         - Opcode:          DW_LNS_extended_op
+#CHECK:           ExtLen:          9
+#CHECK:           SubOpcode:       DW_LNE_set_address
+#CHECK:           Data:            4294971216
+#CHECK:         - Opcode:          0x14
+#CHECK:           Data:            4294971216
+#CHECK:         - Opcode:          DW_LNS_set_column
+#CHECK:           Data:            3
+#CHECK:         - Opcode:          DW_LNS_set_prologue_end
+#CHECK:           Data:            3
+#CHECK:         - Opcode:          DW_LNS_const_add_pc
+#CHECK:           Data:            3
+#CHECK:         - Opcode:          0xBB
+#CHECK:           Data:            3
+#CHECK:         - Opcode:          0xBB
+#CHECK:           Data:            3
+#CHECK:         - Opcode:          DW_LNS_advance_pc
+#CHECK:           Data:            11
+#CHECK:         - Opcode:          DW_LNS_extended_op
+#CHECK:           ExtLen:          1
+#CHECK:           SubOpcode:       DW_LNE_end_sequence
+#CHECK:           Data:            11
+#CHECK: ...
index cf8b3e5b9273060ab4d7388ce0746e1cd08d6618..cbf34ed5388a21c36cb889935d27c4c5d0ff7d73 100644 (file)
@@ -127,7 +127,7 @@ void dumpDebugInfo(DWARFContextInMemory &DCtx, DWARFYAML::Data &Y) {
           NewValue.Value = 0xDEADBEEFDEADBEEF;
           DWARFDie DIEWrapper(CU.get(), &DIE);
           auto FormValue = DIEWrapper.getAttributeValue(AttrSpec.Attr);
-          if(!FormValue)
+          if (!FormValue)
             return;
           auto Form = FormValue.getValue().getForm();
           bool indirect = false;
@@ -211,11 +211,137 @@ void dumpDebugInfo(DWARFContextInMemory &DCtx, DWARFYAML::Data &Y) {
   }
 }
 
+bool dumpFileEntry(DataExtractor &Data, uint32_t &Offset,
+                   DWARFYAML::File &File) {
+  File.Name = Data.getCStr(&Offset);
+  if (File.Name.empty())
+    return false;
+  File.DirIdx = Data.getULEB128(&Offset);
+  File.ModTime = Data.getULEB128(&Offset);
+  File.Length = Data.getULEB128(&Offset);
+  return true;
+}
+
+void dumpDebugLines(DWARFContextInMemory &DCtx, DWARFYAML::Data &Y) {
+  for (const auto &CU : DCtx.compile_units()) {
+    auto CUDIE = CU->getUnitDIE();
+    if (!CUDIE)
+      continue;
+    if (auto StmtOffset =
+            CUDIE.getAttributeValueAsSectionOffset(dwarf::DW_AT_stmt_list)) {
+      DWARFYAML::LineTable DebugLines;
+      DataExtractor LineData(DCtx.getLineSection().Data, DCtx.isLittleEndian(),
+                             CU->getAddressByteSize());
+      uint32_t Offset = *StmtOffset;
+      uint64_t SizeOfPrologueLength = 4;
+      DebugLines.TotalLength = LineData.getU32(&Offset);
+      uint64_t LineTableLength = DebugLines.TotalLength;
+      if (DebugLines.TotalLength == UINT32_MAX) {
+        DebugLines.TotalLength64 = LineData.getU64(&Offset);
+        LineTableLength = DebugLines.TotalLength64;
+        SizeOfPrologueLength = 8;
+      }
+      DebugLines.Version = LineData.getU16(&Offset);
+      DebugLines.PrologueLength =
+          LineData.getUnsigned(&Offset, SizeOfPrologueLength);
+      const uint64_t EndPrologue = DebugLines.PrologueLength + Offset;
+
+      DebugLines.MinInstLength = LineData.getU8(&Offset);
+      if (DebugLines.Version >= 4)
+        DebugLines.MaxOpsPerInst = LineData.getU8(&Offset);
+      DebugLines.DefaultIsStmt = LineData.getU8(&Offset);
+      DebugLines.LineBase = LineData.getU8(&Offset);
+      DebugLines.LineRange = LineData.getU8(&Offset);
+      DebugLines.OpcodeBase = LineData.getU8(&Offset);
+
+      DebugLines.StandardOpcodeLengths.reserve(DebugLines.OpcodeBase - 1);
+      for (uint8_t i = 1; i < DebugLines.OpcodeBase; ++i)
+        DebugLines.StandardOpcodeLengths.push_back(LineData.getU8(&Offset));
+
+      while (Offset < EndPrologue) {
+        StringRef Dir = LineData.getCStr(&Offset);
+        if (!Dir.empty())
+          DebugLines.IncludeDirs.push_back(Dir);
+        else
+          break;
+      }
+
+      while (Offset < EndPrologue) {
+        DWARFYAML::File TmpFile;
+        if (dumpFileEntry(LineData, Offset, TmpFile))
+          DebugLines.Files.push_back(TmpFile);
+        else
+          break;
+      }
+
+      const uint64_t LineEnd =
+          LineTableLength + *StmtOffset + SizeOfPrologueLength;
+      while (Offset < LineEnd) {
+        DWARFYAML::LineTableOpcode NewOp;
+        NewOp.Opcode = (dwarf::LineNumberOps)LineData.getU8(&Offset);
+        if (NewOp.Opcode == 0) {
+          auto StartExt = Offset;
+          NewOp.ExtLen = LineData.getULEB128(&Offset);
+          NewOp.SubOpcode =
+              (dwarf::LineNumberExtendedOps)LineData.getU8(&Offset);
+          switch (NewOp.SubOpcode) {
+          case dwarf::DW_LNE_set_address:
+          case dwarf::DW_LNE_set_discriminator:
+            NewOp.Data = LineData.getAddress(&Offset);
+            break;
+          case dwarf::DW_LNE_define_file:
+            dumpFileEntry(LineData, Offset, NewOp.FileEntry);
+            break;
+          case dwarf::DW_LNE_end_sequence:
+            break;
+          default:
+            while (Offset < StartExt + NewOp.ExtLen)
+              NewOp.UnknownOpcodeData.push_back(LineData.getU8(&Offset));
+          }
+        } else if (NewOp.Opcode < DebugLines.OpcodeBase) {
+          switch (NewOp.Opcode) {
+          case dwarf::DW_LNS_copy:
+          case dwarf::DW_LNS_negate_stmt:
+          case dwarf::DW_LNS_set_basic_block:
+          case dwarf::DW_LNS_const_add_pc:
+          case dwarf::DW_LNS_set_prologue_end:
+          case dwarf::DW_LNS_set_epilogue_begin:
+            break;
+
+          case dwarf::DW_LNS_advance_pc:
+          case dwarf::DW_LNS_set_file:
+          case dwarf::DW_LNS_set_column:
+          case dwarf::DW_LNS_set_isa:
+            NewOp.Data = LineData.getULEB128(&Offset);
+            break;
+
+          case dwarf::DW_LNS_advance_line:
+            NewOp.SData = LineData.getSLEB128(&Offset);
+            break;
+
+          case dwarf::DW_LNS_fixed_advance_pc:
+            NewOp.Data = LineData.getU16(&Offset);
+            break;
+
+          default:
+            for (uint8_t i = 0;
+                 i < DebugLines.StandardOpcodeLengths[NewOp.Opcode - 1]; ++i)
+              NewOp.StandardOpcodeData.push_back(LineData.getULEB128(&Offset));
+          }
+        }
+        DebugLines.Opcodes.push_back(NewOp);
+      }
+      Y.DebugLines.push_back(DebugLines);
+    }
+  }
+}
+
 std::error_code dwarf2yaml(DWARFContextInMemory &DCtx, DWARFYAML::Data &Y) {
   dumpDebugAbbrev(DCtx, Y);
   dumpDebugStrings(DCtx, Y);
   dumpDebugARanges(DCtx, Y);
   dumpDebugPubSections(DCtx, Y);
   dumpDebugInfo(DCtx, Y);
+  dumpDebugLines(DCtx, Y);
   return obj2yaml_error::success;
 }
index 8ba1190c56a7a3c8892da6f4b65ba33f74e2ade1..3ceb7772b9691c7c6ba0d2db14796ef88a068af4 100644 (file)
@@ -233,3 +233,98 @@ void yaml2debug_info(raw_ostream &OS, const DWARFYAML::Data &DI) {
     }
   }
 }
+
+void yaml2FileEntry(raw_ostream &OS, const DWARFYAML::File &File) {
+  OS.write(File.Name.data(), File.Name.size());
+  OS.write('\0');
+  encodeULEB128(File.DirIdx, OS);
+  encodeULEB128(File.ModTime, OS);
+  encodeULEB128(File.Length, OS);
+}
+
+void yaml2debug_line(raw_ostream &OS, const DWARFYAML::Data &DI) {
+  for (const auto LineTable : DI.DebugLines) {
+    writeInteger((uint32_t)LineTable.TotalLength, OS, DI.IsLittleEndian);
+    uint64_t SizeOfPrologueLength = 4;
+    if (LineTable.TotalLength == UINT32_MAX) {
+      writeInteger((uint64_t)LineTable.TotalLength64, OS, DI.IsLittleEndian);
+      SizeOfPrologueLength = 8;
+    }
+    writeInteger((uint16_t)LineTable.Version, OS, DI.IsLittleEndian);
+    writeVariableSizedInteger(LineTable.PrologueLength, SizeOfPrologueLength,
+                              OS, DI.IsLittleEndian);
+    writeInteger((uint8_t)LineTable.MinInstLength, OS, DI.IsLittleEndian);
+    if (LineTable.Version >= 4)
+      writeInteger((uint8_t)LineTable.MaxOpsPerInst, OS, DI.IsLittleEndian);
+    writeInteger((uint8_t)LineTable.DefaultIsStmt, OS, DI.IsLittleEndian);
+    writeInteger((uint8_t)LineTable.LineBase, OS, DI.IsLittleEndian);
+    writeInteger((uint8_t)LineTable.LineRange, OS, DI.IsLittleEndian);
+    writeInteger((uint8_t)LineTable.OpcodeBase, OS, DI.IsLittleEndian);
+
+    for (auto OpcodeLength : LineTable.StandardOpcodeLengths)
+      writeInteger((uint8_t)OpcodeLength, OS, DI.IsLittleEndian);
+
+    for (auto IncludeDir : LineTable.IncludeDirs) {
+      OS.write(IncludeDir.data(), IncludeDir.size());
+      OS.write('\0');
+    }
+    OS.write('\0');
+
+    for (auto File : LineTable.Files)
+      yaml2FileEntry(OS, File);
+    OS.write('\0');
+
+    for (auto Op : LineTable.Opcodes) {
+      writeInteger((uint8_t)Op.Opcode, OS, DI.IsLittleEndian);
+      if (Op.Opcode == 0) {
+        encodeULEB128(Op.ExtLen, OS);
+        writeInteger((uint8_t)Op.SubOpcode, OS, DI.IsLittleEndian);
+        switch (Op.SubOpcode) {
+        case dwarf::DW_LNE_set_address:
+        case dwarf::DW_LNE_set_discriminator:
+          writeVariableSizedInteger(Op.Data, DI.CompileUnits[0].AddrSize, OS,
+                                    DI.IsLittleEndian);
+          break;
+        case dwarf::DW_LNE_define_file:
+          yaml2FileEntry(OS, Op.FileEntry);
+          break;
+        case dwarf::DW_LNE_end_sequence:
+          break;
+        default:
+          for (auto OpByte : Op.UnknownOpcodeData)
+            writeInteger((uint8_t)OpByte, OS, DI.IsLittleEndian);
+        }
+      } else if (Op.Opcode < LineTable.OpcodeBase) {
+        switch (Op.Opcode) {
+        case dwarf::DW_LNS_copy:
+        case dwarf::DW_LNS_negate_stmt:
+        case dwarf::DW_LNS_set_basic_block:
+        case dwarf::DW_LNS_const_add_pc:
+        case dwarf::DW_LNS_set_prologue_end:
+        case dwarf::DW_LNS_set_epilogue_begin:
+          break;
+
+        case dwarf::DW_LNS_advance_pc:
+        case dwarf::DW_LNS_set_file:
+        case dwarf::DW_LNS_set_column:
+        case dwarf::DW_LNS_set_isa:
+          encodeULEB128(Op.Data, OS);
+          break;
+
+        case dwarf::DW_LNS_advance_line:
+          encodeSLEB128(Op.SData, OS);
+          break;
+
+        case dwarf::DW_LNS_fixed_advance_pc:
+          writeInteger((uint16_t)Op.Data, OS, DI.IsLittleEndian);
+          break;
+
+        default:
+          for (auto OpData : Op.StandardOpcodeData) {
+            encodeULEB128(OpData, OS);
+          }
+        }
+      }
+    }
+  }
+}
index a41ec55d73be1b01ceb034edc8f391ae06d530b4..cbc4d7ff50d5ebec56fd74ae7d0ce3c27a8905c9 100644 (file)
@@ -280,6 +280,8 @@ Error MachOWriter::writeSectionData(raw_ostream &OS) {
             yaml2pubsection(OS, Obj.DWARF.PubTypes, Obj.IsLittleEndian);
           } else if (0 == strncmp(&Sec.sectname[0], "__debug_info", 16)) {
             yaml2debug_info(OS, Obj.DWARF);
+          } else if (0 == strncmp(&Sec.sectname[0], "__debug_line", 16)) {
+            yaml2debug_line(OS, Obj.DWARF);
           }
         } else {
           // Fills section data with 0xDEADBEEF
index 7cad4ca8675f29b63372ca10b53a951f9daf15af..4a637366e1a16330529e671b6d352ecee179b763 100644 (file)
@@ -46,5 +46,6 @@ void yaml2pubsection(llvm::raw_ostream &OS,
                      const llvm::DWARFYAML::PubSection &Sect,
                      bool IsLittleEndian);
 void yaml2debug_info(llvm::raw_ostream &OS, const llvm::DWARFYAML::Data &DI);
+void yaml2debug_line(llvm::raw_ostream &OS, const llvm::DWARFYAML::Data &DI);
 
 #endif