13df7d2f70bb316ebeec8a8c862b3da5386fbb145David Blaikie//===-- DWARFDebugLoc.cpp -------------------------------------------------===//
23df7d2f70bb316ebeec8a8c862b3da5386fbb145David Blaikie//
33df7d2f70bb316ebeec8a8c862b3da5386fbb145David Blaikie//                     The LLVM Compiler Infrastructure
43df7d2f70bb316ebeec8a8c862b3da5386fbb145David Blaikie//
53df7d2f70bb316ebeec8a8c862b3da5386fbb145David Blaikie// This file is distributed under the University of Illinois Open Source
63df7d2f70bb316ebeec8a8c862b3da5386fbb145David Blaikie// License. See LICENSE.TXT for details.
73df7d2f70bb316ebeec8a8c862b3da5386fbb145David Blaikie//
83df7d2f70bb316ebeec8a8c862b3da5386fbb145David Blaikie//===----------------------------------------------------------------------===//
93df7d2f70bb316ebeec8a8c862b3da5386fbb145David Blaikie
103df7d2f70bb316ebeec8a8c862b3da5386fbb145David Blaikie#include "DWARFDebugLoc.h"
113df7d2f70bb316ebeec8a8c862b3da5386fbb145David Blaikie#include "llvm/Support/Compiler.h"
123df7d2f70bb316ebeec8a8c862b3da5386fbb145David Blaikie#include "llvm/Support/Format.h"
133df7d2f70bb316ebeec8a8c862b3da5386fbb145David Blaikie#include "llvm/Support/raw_ostream.h"
1436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/Support/Dwarf.h"
153df7d2f70bb316ebeec8a8c862b3da5386fbb145David Blaikie
163df7d2f70bb316ebeec8a8c862b3da5386fbb145David Blaikieusing namespace llvm;
173df7d2f70bb316ebeec8a8c862b3da5386fbb145David Blaikie
183df7d2f70bb316ebeec8a8c862b3da5386fbb145David Blaikievoid DWARFDebugLoc::dump(raw_ostream &OS) const {
1936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  for (const LocationList &L : Locations) {
2036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    OS << format("0x%8.8x: ", L.Offset);
213df7d2f70bb316ebeec8a8c862b3da5386fbb145David Blaikie    const unsigned Indent = 12;
2236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    for (const Entry &E : L.Entries) {
2336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      if (&E != L.Entries.begin())
243df7d2f70bb316ebeec8a8c862b3da5386fbb145David Blaikie        OS.indent(Indent);
2536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      OS << "Beginning address offset: " << format("0x%016" PRIx64, E.Begin)
263df7d2f70bb316ebeec8a8c862b3da5386fbb145David Blaikie         << '\n';
270812304ad8c8eded9785acff3194e3f5058e5dbfDavid Blaikie      OS.indent(Indent) << "   Ending address offset: "
2836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                        << format("0x%016" PRIx64, E.End) << '\n';
290812304ad8c8eded9785acff3194e3f5058e5dbfDavid Blaikie      OS.indent(Indent) << "    Location description: ";
3036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      for (unsigned char Loc : E.Loc) {
3136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        OS << format("%2.2x ", Loc);
323df7d2f70bb316ebeec8a8c862b3da5386fbb145David Blaikie      }
333df7d2f70bb316ebeec8a8c862b3da5386fbb145David Blaikie      OS << "\n\n";
343df7d2f70bb316ebeec8a8c862b3da5386fbb145David Blaikie    }
353df7d2f70bb316ebeec8a8c862b3da5386fbb145David Blaikie  }
363df7d2f70bb316ebeec8a8c862b3da5386fbb145David Blaikie}
373df7d2f70bb316ebeec8a8c862b3da5386fbb145David Blaikie
383df7d2f70bb316ebeec8a8c862b3da5386fbb145David Blaikievoid DWARFDebugLoc::parse(DataExtractor data, unsigned AddressSize) {
393df7d2f70bb316ebeec8a8c862b3da5386fbb145David Blaikie  uint32_t Offset = 0;
4036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  while (data.isValidOffset(Offset+AddressSize-1)) {
413df7d2f70bb316ebeec8a8c862b3da5386fbb145David Blaikie    Locations.resize(Locations.size() + 1);
423df7d2f70bb316ebeec8a8c862b3da5386fbb145David Blaikie    LocationList &Loc = Locations.back();
433df7d2f70bb316ebeec8a8c862b3da5386fbb145David Blaikie    Loc.Offset = Offset;
443df7d2f70bb316ebeec8a8c862b3da5386fbb145David Blaikie    // 2.6.2 Location Lists
453df7d2f70bb316ebeec8a8c862b3da5386fbb145David Blaikie    // A location list entry consists of:
463df7d2f70bb316ebeec8a8c862b3da5386fbb145David Blaikie    while (true) {
473df7d2f70bb316ebeec8a8c862b3da5386fbb145David Blaikie      Entry E;
483df7d2f70bb316ebeec8a8c862b3da5386fbb145David Blaikie      RelocAddrMap::const_iterator AI = RelocMap.find(Offset);
493df7d2f70bb316ebeec8a8c862b3da5386fbb145David Blaikie      // 1. A beginning address offset. ...
503df7d2f70bb316ebeec8a8c862b3da5386fbb145David Blaikie      E.Begin = data.getUnsigned(&Offset, AddressSize);
513df7d2f70bb316ebeec8a8c862b3da5386fbb145David Blaikie      if (AI != RelocMap.end())
523df7d2f70bb316ebeec8a8c862b3da5386fbb145David Blaikie        E.Begin += AI->second.second;
533df7d2f70bb316ebeec8a8c862b3da5386fbb145David Blaikie
543df7d2f70bb316ebeec8a8c862b3da5386fbb145David Blaikie      AI = RelocMap.find(Offset);
553df7d2f70bb316ebeec8a8c862b3da5386fbb145David Blaikie      // 2. An ending address offset. ...
563df7d2f70bb316ebeec8a8c862b3da5386fbb145David Blaikie      E.End = data.getUnsigned(&Offset, AddressSize);
573df7d2f70bb316ebeec8a8c862b3da5386fbb145David Blaikie      if (AI != RelocMap.end())
583df7d2f70bb316ebeec8a8c862b3da5386fbb145David Blaikie        E.End += AI->second.second;
593df7d2f70bb316ebeec8a8c862b3da5386fbb145David Blaikie
603df7d2f70bb316ebeec8a8c862b3da5386fbb145David Blaikie      // The end of any given location list is marked by an end of list entry,
613df7d2f70bb316ebeec8a8c862b3da5386fbb145David Blaikie      // which consists of a 0 for the beginning address offset and a 0 for the
623df7d2f70bb316ebeec8a8c862b3da5386fbb145David Blaikie      // ending address offset.
633df7d2f70bb316ebeec8a8c862b3da5386fbb145David Blaikie      if (E.Begin == 0 && E.End == 0)
643df7d2f70bb316ebeec8a8c862b3da5386fbb145David Blaikie        break;
653df7d2f70bb316ebeec8a8c862b3da5386fbb145David Blaikie
663df7d2f70bb316ebeec8a8c862b3da5386fbb145David Blaikie      unsigned Bytes = data.getU16(&Offset);
673df7d2f70bb316ebeec8a8c862b3da5386fbb145David Blaikie      // A single location description describing the location of the object...
683df7d2f70bb316ebeec8a8c862b3da5386fbb145David Blaikie      StringRef str = data.getData().substr(Offset, Bytes);
693df7d2f70bb316ebeec8a8c862b3da5386fbb145David Blaikie      Offset += Bytes;
703df7d2f70bb316ebeec8a8c862b3da5386fbb145David Blaikie      E.Loc.reserve(str.size());
713df7d2f70bb316ebeec8a8c862b3da5386fbb145David Blaikie      std::copy(str.begin(), str.end(), std::back_inserter(E.Loc));
7236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      Loc.Entries.push_back(std::move(E));
733df7d2f70bb316ebeec8a8c862b3da5386fbb145David Blaikie    }
743df7d2f70bb316ebeec8a8c862b3da5386fbb145David Blaikie  }
7536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (data.isValidOffset(Offset))
7636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    llvm::errs() << "error: failed to consume entire .debug_loc section\n";
773df7d2f70bb316ebeec8a8c862b3da5386fbb145David Blaikie}
7836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
7936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesvoid DWARFDebugLocDWO::parse(DataExtractor data) {
8036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  uint32_t Offset = 0;
8136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  while (data.isValidOffset(Offset)) {
8236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Locations.resize(Locations.size() + 1);
8336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    LocationList &Loc = Locations.back();
8436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Loc.Offset = Offset;
8536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    dwarf::LocationListEntry Kind;
8636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    while ((Kind = static_cast<dwarf::LocationListEntry>(
8736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                data.getU8(&Offset))) != dwarf::DW_LLE_end_of_list_entry) {
8836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
8936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      if (Kind != dwarf::DW_LLE_start_length_entry) {
9036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        llvm::errs() << "error: dumping support for LLE of kind " << (int)Kind
9136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                     << " not implemented\n";
9236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        return;
9336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      }
9436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
9536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      Entry E;
9636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
9736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      E.Start = data.getULEB128(&Offset);
9836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      E.Length = data.getU32(&Offset);
9936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
10036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      unsigned Bytes = data.getU16(&Offset);
10136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      // A single location description describing the location of the object...
10236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      StringRef str = data.getData().substr(Offset, Bytes);
10336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      Offset += Bytes;
10436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      E.Loc.resize(str.size());
10536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      std::copy(str.begin(), str.end(), E.Loc.begin());
10636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
10736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      Loc.Entries.push_back(std::move(E));
10836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    }
10936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
11036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
11136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
11236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesvoid DWARFDebugLocDWO::dump(raw_ostream &OS) const {
11336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  for (const LocationList &L : Locations) {
11436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    OS << format("0x%8.8x: ", L.Offset);
11536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    const unsigned Indent = 12;
11636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    for (const Entry &E : L.Entries) {
11736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      if (&E != L.Entries.begin())
11836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        OS.indent(Indent);
11936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      OS << "Beginning address index: " << E.Start << '\n';
12036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      OS.indent(Indent) << "                 Length: " << E.Length << '\n';
12136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      OS.indent(Indent) << "   Location description: ";
12236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      for (unsigned char Loc : E.Loc)
12336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        OS << format("%2.2x ", Loc);
12436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      OS << "\n\n";
12536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    }
12636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
12736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
12836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
129