diff options
author | David Blaikie <dblaikie@gmail.com> | 2014-03-25 01:44:02 +0000 |
---|---|---|
committer | David Blaikie <dblaikie@gmail.com> | 2014-03-25 01:44:02 +0000 |
commit | b13d54f5880b2dafadd89182ee9adaff11fa9cf3 (patch) | |
tree | 13bb06196737d105a47493ce7045cf68ff6bfc95 /lib/DebugInfo/DWARFDebugLoc.cpp | |
parent | 6cfebbd64d6a4dc80706d8f8eba066d3fb8b1749 (diff) | |
download | llvm-b13d54f5880b2dafadd89182ee9adaff11fa9cf3.tar.gz llvm-b13d54f5880b2dafadd89182ee9adaff11fa9cf3.tar.bz2 llvm-b13d54f5880b2dafadd89182ee9adaff11fa9cf3.tar.xz |
DebugInfo: Support debug_loc under fission
Implement debug_loc.dwo, as well as llvm-dwarfdump support for dumping
this section.
Outlined in the DWARF5 spec and http://gcc.gnu.org/wiki/DebugFission the
debug_loc.dwo section has more variation than the standard debug_loc,
allowing 3 different forms of entry (plus the end of list entry). GCC
seems to, and Clang certainly, only use one form, so I've just
implemented dumping support for that for now.
It wasn't immediately obvious that there was a good refactoring to share
the implementation of dumping support between debug_loc and
debug_loc.dwo, so they're separate for now - ideas welcome or I may come
back to it at some point.
As per a comment in the code, we could choose different forms that may
reduce the number of debug_addr entries we emit, but that will require
further study.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@204697 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/DebugInfo/DWARFDebugLoc.cpp')
-rw-r--r-- | lib/DebugInfo/DWARFDebugLoc.cpp | 52 |
1 files changed, 52 insertions, 0 deletions
diff --git a/lib/DebugInfo/DWARFDebugLoc.cpp b/lib/DebugInfo/DWARFDebugLoc.cpp index 5f0ff0240d..e4aa5dcce2 100644 --- a/lib/DebugInfo/DWARFDebugLoc.cpp +++ b/lib/DebugInfo/DWARFDebugLoc.cpp @@ -11,6 +11,7 @@ #include "llvm/Support/Compiler.h" #include "llvm/Support/Format.h" #include "llvm/Support/raw_ostream.h" +#include "llvm/Support/Dwarf.h" using namespace llvm; @@ -74,3 +75,54 @@ void DWARFDebugLoc::parse(DataExtractor data, unsigned AddressSize) { if (data.isValidOffset(Offset)) llvm::errs() << "error: failed to consume entire .debug_loc section\n"; } + +void DWARFDebugLocDWO::parse(DataExtractor data) { + uint32_t Offset = 0; + while (data.isValidOffset(Offset)) { + Locations.resize(Locations.size() + 1); + LocationList &Loc = Locations.back(); + Loc.Offset = Offset; + dwarf::LocationListEntry Kind; + while ((Kind = static_cast<dwarf::LocationListEntry>( + data.getU8(&Offset))) != dwarf::DW_LLE_end_of_list_entry) { + + if (Kind != dwarf::DW_LLE_start_length_entry) { + llvm::errs() << "error: dumping support for LLE of kind " << (int)Kind + << " not implemented\n"; + return; + } + + Entry E; + + E.Start = data.getULEB128(&Offset); + E.Length = data.getU32(&Offset); + + unsigned Bytes = data.getU16(&Offset); + // A single location description describing the location of the object... + StringRef str = data.getData().substr(Offset, Bytes); + Offset += Bytes; + E.Loc.resize(str.size()); + std::copy(str.begin(), str.end(), E.Loc.begin()); + + Loc.Entries.push_back(std::move(E)); + } + } +} + +void DWARFDebugLocDWO::dump(raw_ostream &OS) const { + for (const LocationList &L : Locations) { + OS << format("0x%8.8x: ", L.Offset); + const unsigned Indent = 12; + for (const Entry &E : L.Entries) { + if (&E != L.Entries.begin()) + OS.indent(Indent); + OS << "Beginning address index: " << E.Start << '\n'; + OS.indent(Indent) << " Length: " << E.Length << '\n'; + OS.indent(Indent) << " Location description: "; + for (unsigned char Loc : E.Loc) + OS << format("%2.2x ", Loc); + OS << "\n\n"; + } + } +} + |