summaryrefslogtreecommitdiffstats
path: root/llvm/lib/ObjectYAML/DWARFEmitter.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/ObjectYAML/DWARFEmitter.cpp')
-rw-r--r--llvm/lib/ObjectYAML/DWARFEmitter.cpp181
1 files changed, 59 insertions, 122 deletions
diff --git a/llvm/lib/ObjectYAML/DWARFEmitter.cpp b/llvm/lib/ObjectYAML/DWARFEmitter.cpp
index 69f7d368ddc..d3c244e808b 100644
--- a/llvm/lib/ObjectYAML/DWARFEmitter.cpp
+++ b/llvm/lib/ObjectYAML/DWARFEmitter.cpp
@@ -19,6 +19,8 @@
#include "llvm/Support/raw_ostream.h"
#include "llvm/Support/SwapByteOrder.h"
+#include "DWARFVisitor.h"
+
#include <algorithm>
using namespace llvm;
@@ -117,130 +119,65 @@ void DWARFYAML::EmitPubSection(raw_ostream &OS,
}
}
-void DWARFYAML::EmitDebugInfo(raw_ostream &OS, const DWARFYAML::Data &DI) {
+/// \brief An extension of the DWARFYAML::ConstVisitor which writes compile
+/// units and DIEs to a stream.
+class DumpVisitor : public DWARFYAML::ConstVisitor {
+ raw_ostream &OS;
+
+protected:
+ virtual void onStartCompileUnit(const DWARFYAML::Unit &CU) {
+ writeInitialLength(CU.Length, OS, DebugInfo.IsLittleEndian);
+ writeInteger((uint16_t)CU.Version, OS, DebugInfo.IsLittleEndian);
+ writeInteger((uint32_t)CU.AbbrOffset, OS, DebugInfo.IsLittleEndian);
+ writeInteger((uint8_t)CU.AddrSize, OS, DebugInfo.IsLittleEndian);
+ }
- for (auto CU : DI.CompileUnits) {
- writeInitialLength(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 {
- 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);
- }
- }
+ virtual void onStartDIE(const DWARFYAML::Unit &CU,
+ const DWARFYAML::Entry &DIE) {
+ encodeULEB128(DIE.AbbrCode, OS);
+ }
+
+ virtual void onValue(const uint8_t U) {
+ writeInteger(U, OS, DebugInfo.IsLittleEndian);
+ }
+
+ virtual void onValue(const uint16_t U) {
+ writeInteger(U, OS, DebugInfo.IsLittleEndian);
+ }
+ virtual void onValue(const uint32_t U) {
+ writeInteger(U, OS, DebugInfo.IsLittleEndian);
}
+ virtual void onValue(const uint64_t U, const bool LEB = false) {
+ if (LEB)
+ encodeULEB128(U, OS);
+ else
+ writeInteger(U, OS, DebugInfo.IsLittleEndian);
+ }
+
+ virtual void onValue(const int64_t S, const bool LEB = false) {
+ if (LEB)
+ encodeSLEB128(S, OS);
+ else
+ writeInteger(S, OS, DebugInfo.IsLittleEndian);
+ }
+
+ virtual void onValue(const StringRef String) {
+ OS.write(String.data(), String.size());
+ OS.write('\0');
+ }
+
+ virtual void onValue(const MemoryBufferRef MBR) {
+ OS.write(MBR.getBufferStart(), MBR.getBufferSize());
+ }
+
+public:
+ DumpVisitor(const DWARFYAML::Data &DI, raw_ostream &Out)
+ : DWARFYAML::ConstVisitor(DI), OS(Out) {}
+};
+
+void DWARFYAML::EmitDebugInfo(raw_ostream &OS, const DWARFYAML::Data &DI) {
+ DumpVisitor Visitor(DI, OS);
+ Visitor.traverseDebugInfo();
}
static void EmitFileEntry(raw_ostream &OS, const DWARFYAML::File &File) {
OpenPOWER on IntegriCloud