[llvm] r291546 - [ObjectYAML] Support for DWARF line tables

Chris Bieneman via llvm-commits llvm-commits at lists.llvm.org
Mon Jan 9 22:22:50 PST 2017


Author: cbieneman
Date: Tue Jan 10 00:22:49 2017
New Revision: 291546

URL: http://llvm.org/viewvc/llvm-project?rev=291546&view=rev
Log:
[ObjectYAML] Support for DWARF line tables

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.

Added:
    llvm/trunk/test/ObjectYAML/MachO/DWARF-debug_line.yaml
      - copied, changed from r291543, llvm/trunk/test/ObjectYAML/MachO/DWARF-debug_info.yaml
Modified:
    llvm/trunk/include/llvm/ObjectYAML/DWARFYAML.h
    llvm/trunk/include/llvm/ObjectYAML/MachOYAML.h
    llvm/trunk/include/llvm/Support/Dwarf.h
    llvm/trunk/lib/ObjectYAML/DWARFYAML.cpp
    llvm/trunk/test/ObjectYAML/MachO/DWARF-debug_info.yaml
    llvm/trunk/tools/obj2yaml/dwarf2yaml.cpp
    llvm/trunk/tools/yaml2obj/yaml2dwarf.cpp
    llvm/trunk/tools/yaml2obj/yaml2macho.cpp
    llvm/trunk/tools/yaml2obj/yaml2obj.h

Modified: llvm/trunk/include/llvm/ObjectYAML/DWARFYAML.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ObjectYAML/DWARFYAML.h?rev=291546&r1=291545&r2=291546&view=diff
==============================================================================
--- llvm/trunk/include/llvm/ObjectYAML/DWARFYAML.h (original)
+++ llvm/trunk/include/llvm/ObjectYAML/DWARFYAML.h Tue Jan 10 00:22:49 2017
@@ -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::DWARF
 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<DWARFYA
   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);
 
@@ -167,6 +220,26 @@ template <> struct ScalarEnumerationTrai
 #include "llvm/Support/Dwarf.def"
     io.enumFallback<Hex16>(value);
   }
+};
+
+#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)                                             \

Modified: llvm/trunk/include/llvm/ObjectYAML/MachOYAML.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ObjectYAML/MachOYAML.h?rev=291546&r1=291545&r2=291546&view=diff
==============================================================================
--- llvm/trunk/include/llvm/ObjectYAML/MachOYAML.h (original)
+++ llvm/trunk/include/llvm/ObjectYAML/MachOYAML.h Tue Jan 10 00:22:49 2017
@@ -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)

Modified: llvm/trunk/include/llvm/Support/Dwarf.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/Dwarf.h?rev=291546&r1=291545&r2=291546&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Support/Dwarf.h (original)
+++ llvm/trunk/include/llvm/Support/Dwarf.h Tue Jan 10 00:22:49 2017
@@ -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"
 };

Modified: llvm/trunk/lib/ObjectYAML/DWARFYAML.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ObjectYAML/DWARFYAML.cpp?rev=291546&r1=291545&r2=291546&view=diff
==============================================================================
--- llvm/trunk/lib/ObjectYAML/DWARFYAML.cpp (original)
+++ llvm/trunk/lib/ObjectYAML/DWARFYAML.cpp Tue Jan 10 00:22:49 2017
@@ -27,17 +27,18 @@ void MappingTraits<DWARFYAML::Data>::map
   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::ARangeDesc
 }
 
 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>::ma
   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

Modified: llvm/trunk/test/ObjectYAML/MachO/DWARF-debug_info.yaml
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/ObjectYAML/MachO/DWARF-debug_info.yaml?rev=291546&r1=291545&r2=291546&view=diff
==============================================================================
--- llvm/trunk/test/ObjectYAML/MachO/DWARF-debug_info.yaml (original)
+++ llvm/trunk/test/ObjectYAML/MachO/DWARF-debug_info.yaml Tue Jan 10 00:22:49 2017
@@ -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
+...
 ...
 
 

Copied: llvm/trunk/test/ObjectYAML/MachO/DWARF-debug_line.yaml (from r291543, llvm/trunk/test/ObjectYAML/MachO/DWARF-debug_info.yaml)
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/ObjectYAML/MachO/DWARF-debug_line.yaml?p2=llvm/trunk/test/ObjectYAML/MachO/DWARF-debug_line.yaml&p1=llvm/trunk/test/ObjectYAML/MachO/DWARF-debug_info.yaml&r1=291543&r2=291546&rev=291546&view=diff
==============================================================================
--- llvm/trunk/test/ObjectYAML/MachO/DWARF-debug_info.yaml (original)
+++ llvm/trunk/test/ObjectYAML/MachO/DWARF-debug_line.yaml Tue Jan 10 00:22:49 2017
@@ -6,11 +6,20 @@ FileHeader:
   cputype:         0x01000007
   cpusubtype:      0x00000003
   filetype:        0x0000000A
-  ncmds:           5
-  sizeofcmds:      1800
+  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
@@ -303,6 +312,16 @@ LinkEditData:
     - __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
@@ -383,6 +402,24 @@ DWARF:
       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
@@ -451,75 +488,109 @@ DWARF:
             - 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: DWARF:           
-#CHECK:   debug_info:      
-#CHECK:     - Length:          117
-#CHECK:       Version:         4
-#CHECK:       AbbrOffset:      0
-#CHECK:       AddrSize:        8
-#CHECK:       Entries:         
-#CHECK:         - AbbrCode:        0x00000001
-#CHECK:           Values:          
-#CHECK:             - Value:           0x0000000000000001
-#CHECK:             - Value:           0x000000000000000C
-#CHECK:             - Value:           0x0000000000000038
-#CHECK:             - Value:           0x0000000000000000
-#CHECK:             - Value:           0x0000000000000046
-#CHECK:             - Value:           0x0000000100000F50
-#CHECK:             - Value:           0x0000000000000034
-#CHECK:         - AbbrCode:        0x00000002
-#CHECK:           Values:          
-#CHECK:             - Value:           0x0000000100000F50
-#CHECK:             - Value:           0x0000000000000034
-#CHECK:             - Value:           0x0000000000000001
-#CHECK:               BlockData:       
-#CHECK:                 - 0x56
-#CHECK:             - Value:           0x0000000000000076
-#CHECK:             - Value:           0x0000000000000001
-#CHECK:             - Value:           0x0000000000000003
-#CHECK:             - Value:           0x0000000000000001
-#CHECK:             - Value:           0x0000000000000060
-#CHECK:             - Value:           0x0000000000000001
-#CHECK:         - AbbrCode:        0x00000003
-#CHECK:           Values:          
-#CHECK:             - Value:           0x0000000000000002
-#CHECK:               BlockData:       
-#CHECK:                 - 0x91
-#CHECK:                 - 0x78
-#CHECK:             - Value:           0x000000000000007B
-#CHECK:             - Value:           0x0000000000000001
-#CHECK:             - Value:           0x0000000000000003
-#CHECK:             - Value:           0x0000000000000060
-#CHECK:         - AbbrCode:        0x00000003
-#CHECK:           Values:          
-#CHECK:             - Value:           0x0000000000000002
-#CHECK:               BlockData:       
-#CHECK:                 - 0x91
-#CHECK:                 - 0x70
-#CHECK:             - Value:           0x0000000000000080
-#CHECK:             - Value:           0x0000000000000001
-#CHECK:             - Value:           0x0000000000000003
-#CHECK:             - Value:           0x0000000000000067
-#CHECK:         - AbbrCode:        0x00000000
-#CHECK:           Values:          
-#CHECK:         - AbbrCode:        0x00000004
-#CHECK:           Values:          
-#CHECK:             - Value:           0x0000000000000085
-#CHECK:             - Value:           0x0000000000000005
-#CHECK:             - Value:           0x0000000000000004
-#CHECK:         - AbbrCode:        0x00000005
-#CHECK:           Values:          
-#CHECK:             - Value:           0x000000000000006C
-#CHECK:         - AbbrCode:        0x00000005
-#CHECK:           Values:          
-#CHECK:             - Value:           0x0000000000000071
-#CHECK:         - AbbrCode:        0x00000004
-#CHECK:           Values:          
-#CHECK:             - Value:           0x0000000000000089
-#CHECK:             - Value:           0x0000000000000006
-#CHECK:             - Value:           0x0000000000000001
-#CHECK:         - AbbrCode:        0x00000000
-#CHECK:           Values:          
+#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: ...

Modified: llvm/trunk/tools/obj2yaml/dwarf2yaml.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/obj2yaml/dwarf2yaml.cpp?rev=291546&r1=291545&r2=291546&view=diff
==============================================================================
--- llvm/trunk/tools/obj2yaml/dwarf2yaml.cpp (original)
+++ llvm/trunk/tools/obj2yaml/dwarf2yaml.cpp Tue Jan 10 00:22:49 2017
@@ -127,7 +127,7 @@ void dumpDebugInfo(DWARFContextInMemory
           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
   }
 }
 
+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;
 }

Modified: llvm/trunk/tools/yaml2obj/yaml2dwarf.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/yaml2obj/yaml2dwarf.cpp?rev=291546&r1=291545&r2=291546&view=diff
==============================================================================
--- llvm/trunk/tools/yaml2obj/yaml2dwarf.cpp (original)
+++ llvm/trunk/tools/yaml2obj/yaml2dwarf.cpp Tue Jan 10 00:22:49 2017
@@ -233,3 +233,98 @@ void yaml2debug_info(raw_ostream &OS, co
     }
   }
 }
+
+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);
+          }
+        }
+      }
+    }
+  }
+}

Modified: llvm/trunk/tools/yaml2obj/yaml2macho.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/yaml2obj/yaml2macho.cpp?rev=291546&r1=291545&r2=291546&view=diff
==============================================================================
--- llvm/trunk/tools/yaml2obj/yaml2macho.cpp (original)
+++ llvm/trunk/tools/yaml2obj/yaml2macho.cpp Tue Jan 10 00:22:49 2017
@@ -280,6 +280,8 @@ Error MachOWriter::writeSectionData(raw_
             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

Modified: llvm/trunk/tools/yaml2obj/yaml2obj.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/yaml2obj/yaml2obj.h?rev=291546&r1=291545&r2=291546&view=diff
==============================================================================
--- llvm/trunk/tools/yaml2obj/yaml2obj.h (original)
+++ llvm/trunk/tools/yaml2obj/yaml2obj.h Tue Jan 10 00:22:49 2017
@@ -46,5 +46,6 @@ void yaml2pubsection(llvm::raw_ostream &
                      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




More information about the llvm-commits mailing list