]> granicus.if.org Git - llvm/commitdiff
[ObjectYAML] Support for DWARF debug_info section
authorChris Bieneman <beanz@apple.com>
Thu, 22 Dec 2016 22:44:27 +0000 (22:44 +0000)
committerChris Bieneman <beanz@apple.com>
Thu, 22 Dec 2016 22:44:27 +0000 (22:44 +0000)
This patch adds support for YAML<->DWARF for debug_info sections.

This re-lands r290147, reverted in 290148, re-landed in r290204 after fixing the issue that caused bots to fail (thank you UBSan!), and reverted again in r290209 due to failures on big endian systems.

After adding support for preserving endianness, this should be good now.

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

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

index a6228b531ceaac1c5996fb3d59f948c1727f5cb9..920880cea10caeded9b4bc9bc72e7b0d467b7e5b 100644 (file)
@@ -82,6 +82,8 @@ public:
   Optional<uint64_t> getAsAddress() const;
   Optional<uint64_t> getAsSectionOffset() const;
   Optional<ArrayRef<uint8_t>> getAsBlock() const;
+  Optional<uint64_t> getAsCStringOffset() const;
+  Optional<uint64_t> getAsReferenceUVal() const;
   /// Get the fixed byte size for a given form.
   ///
   /// If the form always has a fixed valid byte size that doesn't depend on a
index 78bbe098b2d3f1c0069b4bed98f3b09f0d10157f..db7b59be90c2aeb8bda9fd6b24e0a0262b0bf0e0 100644 (file)
@@ -11,6 +11,7 @@
 #define LLVM_LIB_DEBUGINFO_DWARFUNIT_H
 
 #include "llvm/ADT/Optional.h"
+#include "llvm/ADT/iterator_range.h"
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/DebugInfo/DWARF/DWARFDebugAbbrev.h"
 #include "llvm/DebugInfo/DWARF/DWARFDebugInfoEntry.h"
@@ -127,6 +128,8 @@ class DWARFUnit {
   uint64_t BaseAddr;
   // The compile unit debug information entry items.
   std::vector<DWARFDebugInfoEntry> DieArray;
+  typedef iterator_range<std::vector<DWARFDebugInfoEntry>::iterator>
+      die_iterator_range;
 
   class DWOHolder {
     object::OwningBinary<object::ObjectFile> DWOFile;
@@ -293,6 +296,11 @@ public:
     return 0;
   }
 
+  die_iterator_range dies() {
+    extractDIEsIfNeeded(false);
+    return die_iterator_range(DieArray.begin(), DieArray.end());
+  }
+
 private:
   /// Size in bytes of the .debug_info data associated with this compile unit.
   size_t getDebugInfoSize() const { return Length + 4 - getHeaderSize(); }
index d73ff6c3eb7ff729474add2caa880ceaba116049..222cad61a9923b05257a95ce07fcc7ebc183c15d 100644 (file)
@@ -66,6 +66,25 @@ struct PubSection {
   std::vector<PubEntry> Entries;
 };
 
+struct FormValue {
+  llvm::yaml::Hex64 Value;
+  StringRef CStr;
+  std::vector<llvm::yaml::Hex8> BlockData;
+};
+
+struct Entry {
+  llvm::yaml::Hex32 AbbrCode;
+  std::vector<FormValue> Values;
+};
+
+struct Unit {
+  uint32_t Length;
+  uint16_t Version;
+  uint32_t AbbrOffset;
+  uint8_t AddrSize;
+  std::vector<Entry> Entries;
+};
+
 struct Data {
   bool IsLittleEndian;
   std::vector<Abbrev> AbbrevDecls;
@@ -76,6 +95,8 @@ struct Data {
 
   PubSection GNUPubNames;
   PubSection GNUPubTypes;
+  
+  std::vector<Unit> CompileUnits;
 
   bool isEmpty() const;
 };
@@ -83,12 +104,17 @@ struct Data {
 } // namespace llvm::DWARFYAML
 } // namespace llvm
 
+LLVM_YAML_IS_SEQUENCE_VECTOR(uint8_t)
 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::StringRef)
+LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::yaml::Hex8)
 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DWARFYAML::AttributeAbbrev)
 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DWARFYAML::Abbrev)
 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DWARFYAML::ARangeDescriptor)
 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DWARFYAML::ARange)
 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)
 
 namespace llvm {
 namespace yaml {
@@ -121,6 +147,18 @@ template <> struct MappingTraits<DWARFYAML::PubSection> {
   static void mapping(IO &IO, DWARFYAML::PubSection &Section);
 };
 
+template <> struct MappingTraits<DWARFYAML::Unit> {
+  static void mapping(IO &IO, DWARFYAML::Unit &Unit);
+};
+
+template <> struct MappingTraits<DWARFYAML::Entry> {
+  static void mapping(IO &IO, DWARFYAML::Entry &Entry);
+};
+
+template <> struct MappingTraits<DWARFYAML::FormValue> {
+  static void mapping(IO &IO, DWARFYAML::FormValue &FormValue);
+};
+
 #define HANDLE_DW_TAG(unused, name)                                            \
   io.enumCase(value, "DW_TAG_" #name, dwarf::DW_TAG_##name);
 
index 0cbf585f0322f1fce42088a46eaff8044b265161..6b7a924f514381f0c91ff9c9092fd26620028dd5 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::Hex8)
 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::yaml::Hex64)
 LLVM_YAML_IS_SEQUENCE_VECTOR(int64_t)
 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::MachOYAML::RebaseOpcode)
index b3f1a52e6b7c7315824c924819027f193c80f1ae..e48a6f0981b7210d1c3dae394447bfd29b1df82a 100644 (file)
@@ -661,3 +661,15 @@ Optional<ArrayRef<uint8_t>> DWARFFormValue::getAsBlock() const {
   return makeArrayRef(Value.data, Value.uval);
 }
 
+Optional<uint64_t> DWARFFormValue::getAsCStringOffset() const {
+  if (!isFormClass(FC_String) && Form == DW_FORM_string)
+    return None;
+  return Value.uval;
+}
+
+Optional<uint64_t> DWARFFormValue::getAsReferenceUVal() const {
+  if (!isFormClass(FC_Reference))
+    return None;
+  return Value.uval;
+}
+
index 3d647b0b0b1477a4d01c70e067bbd8ac472c363f..42a448a7bdfdf8d93bf3b42893df6e8e27ea8965 100644 (file)
@@ -22,8 +22,9 @@ bool DWARFYAML::Data::isEmpty() const {
 
 namespace yaml {
 
-void MappingTraits<DWARFYAML::Data>::mapping(
-    IO &IO, DWARFYAML::Data &DWARF) {
+void MappingTraits<DWARFYAML::Data>::mapping(IO &IO, DWARFYAML::Data &DWARF) {
+  auto oldContext = IO.getContext();
+  IO.setContext(&DWARF);
   IO.mapOptional("debug_str", DWARF.DebugStrings);
   IO.mapOptional("debug_abbrev", DWARF.AbbrevDecls);
   if(!DWARF.ARanges.empty() || !IO.outputting())
@@ -36,10 +37,12 @@ void MappingTraits<DWARFYAML::Data>::mapping(
     IO.mapOptional("debug_gnu_pubnames", DWARF.GNUPubNames);
   if(!DWARF.GNUPubTypes.Entries.empty() || !IO.outputting())
     IO.mapOptional("debug_gnu_pubtypes", DWARF.GNUPubTypes);
+  IO.mapOptional("debug_info", DWARF.CompileUnits);
+  IO.setContext(&oldContext);
 }
 
-void MappingTraits<DWARFYAML::Abbrev>::mapping(
-    IO &IO, DWARFYAML::Abbrev &Abbrev) {
+void MappingTraits<DWARFYAML::Abbrev>::mapping(IO &IO,
+                                               DWARFYAML::Abbrev &Abbrev) {
   IO.mapRequired("Code", Abbrev.Code);
   IO.mapRequired("Tag", Abbrev.Tag);
   IO.mapRequired("Children", Abbrev.Children);
@@ -90,6 +93,28 @@ void MappingTraits<DWARFYAML::PubSection>::mapping(
   IO.setContext(OldContext);
 }
 
+void MappingTraits<DWARFYAML::Unit>::mapping(IO &IO, DWARFYAML::Unit &Unit) {
+  IO.mapRequired("Length", Unit.Length);
+  IO.mapRequired("Version", Unit.Version);
+  IO.mapRequired("AbbrOffset", Unit.AbbrOffset);
+  IO.mapRequired("AddrSize", Unit.AddrSize);
+  IO.mapOptional("Entries", Unit.Entries);
+}
+
+void MappingTraits<DWARFYAML::Entry>::mapping(IO &IO, DWARFYAML::Entry &Entry) {
+  IO.mapRequired("AbbrCode", Entry.AbbrCode);
+  IO.mapRequired("Values", Entry.Values);
+}
+
+void MappingTraits<DWARFYAML::FormValue>::mapping(IO &IO,
+                                             DWARFYAML::FormValue &FormValue) {
+  IO.mapOptional("Value", FormValue.Value);
+  if(!FormValue.CStr.empty() || !IO.outputting())
+    IO.mapOptional("CStr", FormValue.CStr);
+  if(!FormValue.BlockData.empty() || !IO.outputting())
+    IO.mapOptional("BlockData", FormValue.BlockData);
+}
+
 } // namespace llvm::yaml
 
 } // namespace llvm
diff --git a/test/ObjectYAML/MachO/DWARF-debug_info.yaml b/test/ObjectYAML/MachO/DWARF-debug_info.yaml
new file mode 100644 (file)
index 0000000..9a616e9
--- /dev/null
@@ -0,0 +1,525 @@
+# RUN: yaml2obj %s | obj2yaml | FileCheck %s
+
+--- !mach-o
+FileHeader:      
+  magic:           0xFEEDFACF
+  cputype:         0x01000007
+  cpusubtype:      0x00000003
+  filetype:        0x0000000A
+  ncmds:           5
+  sizeofcmds:      1800
+  flags:           0x00000000
+  reserved:        0x00000000
+LoadCommands:    
+  - 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_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_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:          
+...
+
+
+#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:          
index 0fd646e23b98c8de51bcb719f84ddca73e9aaa3e..cf8b3e5b9273060ab4d7388ce0746e1cd08d6618 100644 (file)
 #include "Error.h"
 #include "llvm/DebugInfo/DWARF/DWARFContext.h"
 #include "llvm/DebugInfo/DWARF/DWARFDebugArangeSet.h"
+#include "llvm/DebugInfo/DWARF/DWARFFormValue.h"
 #include "llvm/ObjectYAML/DWARFYAML.h"
 
+#include <algorithm>
+
 using namespace llvm;
 
 void dumpDebugAbbrev(DWARFContextInMemory &DCtx, DWARFYAML::Data &Y) {
@@ -99,12 +102,120 @@ void dumpDebugPubSections(DWARFContextInMemory &DCtx, DWARFYAML::Data &Y) {
   dumpPubSection(DCtx, Y.GNUPubTypes, DCtx.getGnuPubTypesSection());
 }
 
-std::error_code dwarf2yaml(DWARFContextInMemory &DCtx,
-                           DWARFYAML::Data &Y) {
+void dumpDebugInfo(DWARFContextInMemory &DCtx, DWARFYAML::Data &Y) {
+  for (const auto &CU : DCtx.compile_units()) {
+    DWARFYAML::Unit NewUnit;
+    NewUnit.Length = CU->getLength();
+    NewUnit.Version = CU->getVersion();
+    NewUnit.AbbrOffset = CU->getAbbreviations()->getOffset();
+    NewUnit.AddrSize = CU->getAddressByteSize();
+    for (auto DIE : CU->dies()) {
+      DWARFYAML::Entry NewEntry;
+      DataExtractor EntryData = CU->getDebugInfoExtractor();
+      uint32_t offset = DIE.getOffset();
+
+      assert(EntryData.isValidOffset(offset) && "Invalid DIE Offset");
+      if (!EntryData.isValidOffset(offset))
+        continue;
+
+      NewEntry.AbbrCode = EntryData.getULEB128(&offset);
+
+      auto AbbrevDecl = DIE.getAbbreviationDeclarationPtr();
+      if (AbbrevDecl) {
+        for (const auto &AttrSpec : AbbrevDecl->attributes()) {
+          DWARFYAML::FormValue NewValue;
+          NewValue.Value = 0xDEADBEEFDEADBEEF;
+          DWARFDie DIEWrapper(CU.get(), &DIE);
+          auto FormValue = DIEWrapper.getAttributeValue(AttrSpec.Attr);
+          if(!FormValue)
+            return;
+          auto Form = FormValue.getValue().getForm();
+          bool indirect = false;
+          do {
+            indirect = false;
+            switch (Form) {
+            case dwarf::DW_FORM_addr:
+            case dwarf::DW_FORM_GNU_addr_index:
+              if (auto Val = FormValue.getValue().getAsAddress())
+                NewValue.Value = Val.getValue();
+              break;
+            case dwarf::DW_FORM_ref_addr:
+            case dwarf::DW_FORM_ref1:
+            case dwarf::DW_FORM_ref2:
+            case dwarf::DW_FORM_ref4:
+            case dwarf::DW_FORM_ref8:
+            case dwarf::DW_FORM_ref_udata:
+            case dwarf::DW_FORM_ref_sig8:
+              if (auto Val = FormValue.getValue().getAsReferenceUVal())
+                NewValue.Value = Val.getValue();
+              break;
+            case dwarf::DW_FORM_exprloc:
+            case dwarf::DW_FORM_block:
+            case dwarf::DW_FORM_block1:
+            case dwarf::DW_FORM_block2:
+            case dwarf::DW_FORM_block4:
+              if (auto Val = FormValue.getValue().getAsBlock()) {
+                auto BlockData = Val.getValue();
+                std::copy(BlockData.begin(), BlockData.end(),
+                          std::back_inserter(NewValue.BlockData));
+              }
+              NewValue.Value = NewValue.BlockData.size();
+              break;
+            case dwarf::DW_FORM_data1:
+            case dwarf::DW_FORM_flag:
+            case dwarf::DW_FORM_data2:
+            case dwarf::DW_FORM_data4:
+            case dwarf::DW_FORM_data8:
+            case dwarf::DW_FORM_sdata:
+            case dwarf::DW_FORM_udata:
+              if (auto Val = FormValue.getValue().getAsUnsignedConstant())
+                NewValue.Value = Val.getValue();
+              break;
+            case dwarf::DW_FORM_string:
+              if (auto Val = FormValue.getValue().getAsCString())
+                NewValue.CStr = Val.getValue();
+              break;
+            case dwarf::DW_FORM_indirect:
+              indirect = true;
+              if (auto Val = FormValue.getValue().getAsUnsignedConstant()) {
+                NewValue.Value = Val.getValue();
+                NewEntry.Values.push_back(NewValue);
+                Form = static_cast<dwarf::Form>(Val.getValue());
+              }
+              break;
+            case dwarf::DW_FORM_strp:
+            case dwarf::DW_FORM_sec_offset:
+            case dwarf::DW_FORM_GNU_ref_alt:
+            case dwarf::DW_FORM_GNU_strp_alt:
+            case dwarf::DW_FORM_line_strp:
+            case dwarf::DW_FORM_strp_sup:
+            case dwarf::DW_FORM_ref_sup:
+            case dwarf::DW_FORM_GNU_str_index:
+              if (auto Val = FormValue.getValue().getAsCStringOffset())
+                NewValue.Value = Val.getValue();
+              break;
+            case dwarf::DW_FORM_flag_present:
+              NewValue.Value = 1;
+              break;
+            default:
+              break;
+            }
+          } while (indirect);
+          NewEntry.Values.push_back(NewValue);
+        }
+      }
+
+      NewUnit.Entries.push_back(NewEntry);
+    }
+    Y.CompileUnits.push_back(NewUnit);
+  }
+}
+
+std::error_code dwarf2yaml(DWARFContextInMemory &DCtx, DWARFYAML::Data &Y) {
   dumpDebugAbbrev(DCtx, Y);
   dumpDebugStrings(DCtx, Y);
   dumpDebugARanges(DCtx, Y);
   dumpDebugPubSections(DCtx, Y);
-
+  dumpDebugInfo(DCtx, Y);
   return obj2yaml_error::success;
 }
index 525c44ce7abcb1663b5456495beb4bf49d5304b8..283b0df0f625a4cd4302ee9a417b7e797fff7e88 100644 (file)
@@ -18,6 +18,8 @@
 #include "llvm/Support/raw_ostream.h"
 #include "llvm/Support/SwapByteOrder.h"
 
+#include <algorithm>
+
 using namespace llvm;
 
 template <typename T>
@@ -104,4 +106,130 @@ void yaml2pubsection(raw_ostream &OS, const DWARFYAML::PubSection &Sect,
     OS.write(Entry.Name.data(), Entry.Name.size());
     OS.write('\0');
   }
-}
\ No newline at end of file
+}
+
+void yaml2debug_info(raw_ostream &OS, const DWARFYAML::Data &DI) {
+
+  for (auto CU : DI.CompileUnits) {
+    writeInteger((uint32_t)CU.Length, OS, DI.IsLittleEndian);
+    writeInteger((uint16_t)CU.Version, OS, DI.IsLittleEndian);
+    writeInteger((uint32_t)CU.AbbrOffset, OS, DI.IsLittleEndian);
+    writeInteger((uint8_t)CU.AddrSize, OS, DI.IsLittleEndian);
+
+    auto FirstAbbrevCode = CU.Entries[0].AbbrCode;
+
+    for (auto Entry : CU.Entries) {
+      encodeULEB128(Entry.AbbrCode, OS);
+      if (Entry.AbbrCode == 0u)
+        continue;
+      bool Indirect = false;
+      assert(Entry.AbbrCode - FirstAbbrevCode < DI.AbbrevDecls.size() &&
+             "Out of range AbbCode");
+      auto &Abbrev = DI.AbbrevDecls[Entry.AbbrCode - FirstAbbrevCode];
+
+      auto FormVal = Entry.Values.begin();
+      auto AbbrForm = Abbrev.Attributes.begin();
+      for (;
+           FormVal != Entry.Values.end() && AbbrForm != Abbrev.Attributes.end();
+           ++FormVal, ++AbbrForm) {
+        dwarf::Form Form = AbbrForm->Form;
+        do {
+          bool Indirect = false;
+          switch (Form) {
+          case dwarf::DW_FORM_addr:
+            writeVariableSizedInteger(FormVal->Value, CU.AddrSize, OS,
+                                      DI.IsLittleEndian);
+            break;
+          case dwarf::DW_FORM_ref_addr: {
+            // TODO: Handle DWARF32/DWARF64 after Line Table data is done
+            auto writeSize = CU.Version == 2 ? CU.AddrSize : 4;
+            writeVariableSizedInteger(FormVal->Value, writeSize, OS,
+                                      DI.IsLittleEndian);
+            break;
+          }
+          case dwarf::DW_FORM_exprloc:
+          case dwarf::DW_FORM_block:
+            encodeULEB128(FormVal->BlockData.size(), OS);
+            OS.write(reinterpret_cast<char *>(&FormVal->BlockData[0]),
+                     FormVal->BlockData.size());
+            break;
+          case dwarf::DW_FORM_block1: {
+            auto writeSize = FormVal->BlockData.size();
+            writeInteger((uint8_t)writeSize, OS, DI.IsLittleEndian);
+            OS.write(reinterpret_cast<char *>(&FormVal->BlockData[0]),
+                     FormVal->BlockData.size());
+            break;
+          }
+          case dwarf::DW_FORM_block2: {
+            auto writeSize = FormVal->BlockData.size();
+            writeInteger((uint16_t)writeSize, OS, DI.IsLittleEndian);
+            OS.write(reinterpret_cast<char *>(&FormVal->BlockData[0]),
+                     FormVal->BlockData.size());
+            break;
+          }
+          case dwarf::DW_FORM_block4: {
+            auto writeSize = FormVal->BlockData.size();
+            writeInteger((uint32_t)writeSize, OS, DI.IsLittleEndian);
+            OS.write(reinterpret_cast<char *>(&FormVal->BlockData[0]),
+                     FormVal->BlockData.size());
+            break;
+          }
+          case dwarf::DW_FORM_data1:
+          case dwarf::DW_FORM_ref1:
+          case dwarf::DW_FORM_flag:
+            writeInteger((uint8_t)FormVal->Value, OS, DI.IsLittleEndian);
+            break;
+          case dwarf::DW_FORM_data2:
+          case dwarf::DW_FORM_ref2:
+            writeInteger((uint16_t)FormVal->Value, OS, DI.IsLittleEndian);
+            break;
+          case dwarf::DW_FORM_data4:
+          case dwarf::DW_FORM_ref4:
+            writeInteger((uint32_t)FormVal->Value, OS, DI.IsLittleEndian);
+            break;
+          case dwarf::DW_FORM_data8:
+          case dwarf::DW_FORM_ref8:
+            writeInteger((uint64_t)FormVal->Value, OS, DI.IsLittleEndian);
+            break;
+          case dwarf::DW_FORM_sdata:
+            encodeSLEB128(FormVal->Value, OS);
+            break;
+          case dwarf::DW_FORM_udata:
+          case dwarf::DW_FORM_ref_udata:
+            encodeULEB128(FormVal->Value, OS);
+            break;
+          case dwarf::DW_FORM_string:
+            OS.write(FormVal->CStr.data(), FormVal->CStr.size());
+            OS.write('\0');
+            break;
+          case dwarf::DW_FORM_indirect:
+            encodeULEB128(FormVal->Value, OS);
+            Indirect = true;
+            Form = static_cast<dwarf::Form>((uint64_t)FormVal->Value);
+            ++FormVal;
+            break;
+          case dwarf::DW_FORM_strp:
+          case dwarf::DW_FORM_sec_offset:
+          case dwarf::DW_FORM_GNU_ref_alt:
+          case dwarf::DW_FORM_GNU_strp_alt:
+          case dwarf::DW_FORM_line_strp:
+          case dwarf::DW_FORM_strp_sup:
+          case dwarf::DW_FORM_ref_sup:
+            // TODO: Handle DWARF32/64
+            writeInteger((uint32_t)FormVal->Value, OS, DI.IsLittleEndian);
+            break;
+          case dwarf::DW_FORM_ref_sig8:
+            writeInteger((uint64_t)FormVal->Value, OS, DI.IsLittleEndian);
+            break;
+          case dwarf::DW_FORM_GNU_addr_index:
+          case dwarf::DW_FORM_GNU_str_index:
+            encodeULEB128(FormVal->Value, OS);
+            break;
+          default:
+            break;
+          }
+        } while (Indirect);
+      }
+    }
+  }
+}
index 13414502c031d33b34e3d2a9a5833e2bf8a61cf4..a41ec55d73be1b01ceb034edc8f391ae06d530b4 100644 (file)
@@ -278,6 +278,8 @@ Error MachOWriter::writeSectionData(raw_ostream &OS) {
             yaml2pubsection(OS, Obj.DWARF.PubNames, Obj.IsLittleEndian);
           } else if (0 == strncmp(&Sec.sectname[0], "__debug_pubtypes", 16)) {
             yaml2pubsection(OS, Obj.DWARF.PubTypes, Obj.IsLittleEndian);
+          } else if (0 == strncmp(&Sec.sectname[0], "__debug_info", 16)) {
+            yaml2debug_info(OS, Obj.DWARF);
           }
         } else {
           // Fills section data with 0xDEADBEEF
index 756fe49619698758db438c03925cef2df2f0da7c..7cad4ca8675f29b63372ca10b53a951f9daf15af 100644 (file)
@@ -45,5 +45,6 @@ void yaml2debug_aranges(llvm::raw_ostream &OS, const llvm::DWARFYAML::Data &DI);
 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);
 
 #endif