1 //===------ dwarf2yaml.cpp - obj2yaml conversion tool -----------*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #include "Error.h" 11 #include "llvm/DebugInfo/DWARF/DWARFContext.h" 12 #include "llvm/DebugInfo/DWARF/DWARFDebugArangeSet.h" 13 #include "llvm/ObjectYAML/DWARFYAML.h" 14 15 using namespace llvm; 16 17 void dumpDebugAbbrev(DWARFContextInMemory &DCtx, DWARFYAML::Data &Y) { 18 auto AbbrevSetPtr = DCtx.getDebugAbbrev(); 19 if (AbbrevSetPtr) { 20 for (auto AbbrvDeclSet : *AbbrevSetPtr) { 21 for (auto AbbrvDecl : AbbrvDeclSet.second) { 22 DWARFYAML::Abbrev Abbrv; 23 Abbrv.Code = AbbrvDecl.getCode(); 24 Abbrv.Tag = AbbrvDecl.getTag(); 25 Abbrv.Children = AbbrvDecl.hasChildren() ? dwarf::DW_CHILDREN_yes 26 : dwarf::DW_CHILDREN_no; 27 for (auto Attribute : AbbrvDecl.attributes()) { 28 DWARFYAML::AttributeAbbrev AttAbrv; 29 AttAbrv.Attribute = Attribute.Attr; 30 AttAbrv.Form = Attribute.Form; 31 Abbrv.Attributes.push_back(AttAbrv); 32 } 33 Y.AbbrevDecls.push_back(Abbrv); 34 } 35 } 36 } 37 } 38 39 void dumpDebugStrings(DWARFContextInMemory &DCtx, DWARFYAML::Data &Y) { 40 StringRef RemainingTable = DCtx.getStringSection(); 41 while (RemainingTable.size() > 0) { 42 auto SymbolPair = RemainingTable.split('\0'); 43 RemainingTable = SymbolPair.second; 44 Y.DebugStrings.push_back(SymbolPair.first); 45 } 46 } 47 48 void dumpDebugARanges(DWARFContextInMemory &DCtx, DWARFYAML::Data &Y) { 49 DataExtractor ArangesData(DCtx.getARangeSection(), DCtx.isLittleEndian(), 0); 50 uint32_t Offset = 0; 51 DWARFDebugArangeSet Set; 52 53 while (Set.extract(ArangesData, &Offset)) { 54 DWARFYAML::ARange Range; 55 Range.Length = Set.getHeader().Length; 56 Range.Version = Set.getHeader().Version; 57 Range.CuOffset = Set.getHeader().CuOffset; 58 Range.AddrSize = Set.getHeader().AddrSize; 59 Range.SegSize = Set.getHeader().SegSize; 60 for (auto Descriptor : Set.descriptors()) { 61 DWARFYAML::ARangeDescriptor Desc; 62 Desc.Address = Descriptor.Address; 63 Desc.Length = Descriptor.Length; 64 Range.Descriptors.push_back(Desc); 65 } 66 Y.ARanges.push_back(Range); 67 } 68 } 69 70 void dumpPubSection(DWARFContextInMemory &DCtx, DWARFYAML::PubSection &Y, 71 StringRef Section) { 72 DataExtractor PubSectionData(Section, DCtx.isLittleEndian(), 0); 73 uint32_t Offset = 0; 74 Y.Length = PubSectionData.getU32(&Offset); 75 Y.Version = PubSectionData.getU16(&Offset); 76 Y.UnitOffset = PubSectionData.getU32(&Offset); 77 Y.UnitSize = PubSectionData.getU32(&Offset); 78 while (Offset < Y.Length) { 79 DWARFYAML::PubEntry NewEntry; 80 NewEntry.DieOffset = PubSectionData.getU32(&Offset); 81 if (Y.IsGNUStyle) 82 NewEntry.Descriptor = PubSectionData.getU8(&Offset); 83 NewEntry.Name = PubSectionData.getCStr(&Offset); 84 Y.Entries.push_back(NewEntry); 85 } 86 } 87 88 void dumpDebugPubSections(DWARFContextInMemory &DCtx, DWARFYAML::Data &Y) { 89 Y.PubNames.IsGNUStyle = false; 90 dumpPubSection(DCtx, Y.PubNames, DCtx.getPubNamesSection()); 91 92 Y.PubTypes.IsGNUStyle = false; 93 dumpPubSection(DCtx, Y.PubTypes, DCtx.getPubTypesSection()); 94 95 Y.GNUPubNames.IsGNUStyle = true; 96 dumpPubSection(DCtx, Y.GNUPubNames, DCtx.getGnuPubNamesSection()); 97 98 Y.GNUPubTypes.IsGNUStyle = true; 99 dumpPubSection(DCtx, Y.GNUPubTypes, DCtx.getGnuPubTypesSection()); 100 } 101 102 std::error_code dwarf2yaml(DWARFContextInMemory &DCtx, 103 DWARFYAML::Data &Y) { 104 dumpDebugAbbrev(DCtx, Y); 105 dumpDebugStrings(DCtx, Y); 106 dumpDebugARanges(DCtx, Y); 107 dumpDebugPubSections(DCtx, Y); 108 109 return obj2yaml_error::success; 110 } 111