[llvm-commits] [llvm] r139680 - in /llvm/trunk: lib/DebugInfo/CMakeLists.txt lib/DebugInfo/DWARFContext.cpp lib/DebugInfo/DWARFContext.h lib/DebugInfo/DWARFDebugArangeSet.cpp lib/DebugInfo/DWARFDebugArangeSet.h lib/DebugInfo/DWARFDebugAranges.cpp lib/DebugInfo/DWARFDebugAranges.h tools/llvm-dwarfdump/llvm-dwarfdump.cpp

Benjamin Kramer benny.kra at googlemail.com
Tue Sep 13 18:09:52 PDT 2011


Author: d0k
Date: Tue Sep 13 20:09:52 2011
New Revision: 139680

URL: http://llvm.org/viewvc/llvm-project?rev=139680&view=rev
Log:
DWARF: Port support for parsing .debug_aranges section from LLDB and wire it up to llvm-dwarfdump.

This is only one half of it, the part that caches address ranges from the DIEs when .debug_aranges is
not available will be ported soon.

Added:
    llvm/trunk/lib/DebugInfo/DWARFDebugArangeSet.cpp
    llvm/trunk/lib/DebugInfo/DWARFDebugArangeSet.h
    llvm/trunk/lib/DebugInfo/DWARFDebugAranges.cpp
    llvm/trunk/lib/DebugInfo/DWARFDebugAranges.h
Modified:
    llvm/trunk/lib/DebugInfo/CMakeLists.txt
    llvm/trunk/lib/DebugInfo/DWARFContext.cpp
    llvm/trunk/lib/DebugInfo/DWARFContext.h
    llvm/trunk/tools/llvm-dwarfdump/llvm-dwarfdump.cpp

Modified: llvm/trunk/lib/DebugInfo/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/CMakeLists.txt?rev=139680&r1=139679&r2=139680&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/CMakeLists.txt (original)
+++ llvm/trunk/lib/DebugInfo/CMakeLists.txt Tue Sep 13 20:09:52 2011
@@ -4,6 +4,8 @@
   DWARFCompileUnit.cpp
   DWARFContext.cpp
   DWARFDebugAbbrev.cpp
+  DWARFDebugArangeSet.cpp
+  DWARFDebugAranges.cpp
   DWARFDebugInfoEntry.cpp
   DWARFFormValue.cpp
   )

Modified: llvm/trunk/lib/DebugInfo/DWARFContext.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/DWARFContext.cpp?rev=139680&r1=139679&r2=139680&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/DWARFContext.cpp (original)
+++ llvm/trunk/lib/DebugInfo/DWARFContext.cpp Tue Sep 13 20:09:52 2011
@@ -8,12 +8,23 @@
 //===----------------------------------------------------------------------===//
 
 #include "DWARFContext.h"
+#include "llvm/Support/raw_ostream.h"
 using namespace llvm;
 
 void DWARFContext::dump(raw_ostream &OS) {
+  OS << ".debug_abbrev contents:\n";
   getDebugAbbrev()->dump(OS);
+
+  OS << "\n.debug_info contents:\n";
   for (unsigned i = 0, e = getNumCompileUnits(); i != e; ++i)
     getCompileUnitAtIndex(i)->dump(OS);
+
+  OS << "\n.debug_aranges contents:\n";
+  DataExtractor arangesData(getARangeSection(), isLittleEndian(), 0);
+  uint32_t offset = 0;
+  DWARFDebugArangeSet set;
+  while (set.extract(arangesData, &offset))
+    set.dump(OS);
 }
 
 const DWARFDebugAbbrev *DWARFContext::getDebugAbbrev() {
@@ -27,6 +38,17 @@
   return Abbrev.get();
 }
 
+const DWARFDebugAranges *DWARFContext::getDebugAranges() {
+  if (Aranges)
+    return Aranges.get();
+
+  DataExtractor arangesData(getARangeSection(), isLittleEndian(), 0);
+
+  Aranges.reset(new DWARFDebugAranges());
+  Aranges->extract(arangesData);
+  return Aranges.get();
+}
+
 void DWARFContext::parseCompileUnits() {
   uint32_t offset = 0;
   const DataExtractor &debug_info_data = DataExtractor(getInfoSection(),

Modified: llvm/trunk/lib/DebugInfo/DWARFContext.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/DWARFContext.h?rev=139680&r1=139679&r2=139680&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/DWARFContext.h (original)
+++ llvm/trunk/lib/DebugInfo/DWARFContext.h Tue Sep 13 20:09:52 2011
@@ -11,14 +11,13 @@
 #define LLVM_DEBUGINFO_DWARFCONTEXT_H
 
 #include "DWARFCompileUnit.h"
+#include "DWARFDebugAranges.h"
 #include "llvm/DebugInfo/DIContext.h"
 #include "llvm/ADT/OwningPtr.h"
 #include "llvm/ADT/SmallVector.h"
 
 namespace llvm {
 
-class DWARFDebugAbbrev;
-
 /// DWARFContext
 /// This data structure is the top level entity that deals with dwarf debug
 /// information parsing. The actual data is supplied through pure virtual
@@ -28,6 +27,7 @@
 
   SmallVector<DWARFCompileUnit, 1> CUs;
   OwningPtr<DWARFDebugAbbrev> Abbrev;
+  OwningPtr<DWARFDebugAranges> Aranges;
 
   DWARFContext(DWARFContext &); // = delete
   DWARFContext &operator=(DWARFContext &); // = delete
@@ -54,6 +54,9 @@
   /// Get a pointer to the parsed DebugAbbrev object.
   const DWARFDebugAbbrev *getDebugAbbrev();
 
+  /// Get a pointer to the parsed DebugAranges object.
+  const DWARFDebugAranges *getDebugAranges();
+
   bool isLittleEndian() const { return IsLittleEndian; }
 
   virtual StringRef getInfoSection() = 0;

Added: llvm/trunk/lib/DebugInfo/DWARFDebugArangeSet.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/DWARFDebugArangeSet.cpp?rev=139680&view=auto
==============================================================================
--- llvm/trunk/lib/DebugInfo/DWARFDebugArangeSet.cpp (added)
+++ llvm/trunk/lib/DebugInfo/DWARFDebugArangeSet.cpp Tue Sep 13 20:09:52 2011
@@ -0,0 +1,140 @@
+//===-- DWARFDebugArangeSet.cpp -------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "DWARFDebugArangeSet.h"
+#include "llvm/Support/Format.h"
+#include "llvm/Support/raw_ostream.h"
+#include <cassert>
+using namespace llvm;
+
+void DWARFDebugArangeSet::clear() {
+  Offset = -1U;
+  std::memset(&Header, 0, sizeof(Header));
+  ArangeDescriptors.clear();
+}
+
+void DWARFDebugArangeSet::compact() {
+  if (ArangeDescriptors.empty())
+    return;
+
+  // Iterate through all arange descriptors and combine any ranges that
+  // overlap or have matching boundaries. The ArangeDescriptors are assumed
+  // to be in ascending order.
+  uint32_t i = 0;
+  while (i + 1 < ArangeDescriptors.size()) {
+    if (ArangeDescriptors[i].getEndAddress() >= ArangeDescriptors[i+1].Address){
+      // The current range ends at or exceeds the start of the next address
+      // range. Compute the max end address between the two and use that to
+      // make the new length.
+      const uint64_t max_end_addr =
+        std::max(ArangeDescriptors[i].getEndAddress(),
+                 ArangeDescriptors[i+1].getEndAddress());
+      ArangeDescriptors[i].Length = max_end_addr - ArangeDescriptors[i].Address;
+      // Now remove the next entry as it was just combined with the previous one
+      ArangeDescriptors.erase(ArangeDescriptors.begin()+i+1);
+    } else {
+      // Discontiguous address range, just proceed to the next one.
+      ++i;
+    }
+  }
+}
+
+bool
+DWARFDebugArangeSet::extract(DataExtractor data, uint32_t *offset_ptr) {
+  if (data.isValidOffset(*offset_ptr)) {
+    ArangeDescriptors.clear();
+    Offset = *offset_ptr;
+
+    // 7.20 Address Range Table
+    //
+    // Each set of entries in the table of address ranges contained in
+    // the .debug_aranges section begins with a header consisting of: a
+    // 4-byte length containing the length of the set of entries for this
+    // compilation unit, not including the length field itself; a 2-byte
+    // version identifier containing the value 2 for DWARF Version 2; a
+    // 4-byte offset into the.debug_infosection; a 1-byte unsigned integer
+    // containing the size in bytes of an address (or the offset portion of
+    // an address for segmented addressing) on the target system; and a
+    // 1-byte unsigned integer containing the size in bytes of a segment
+    // descriptor on the target system. This header is followed by a series
+    // of tuples. Each tuple consists of an address and a length, each in
+    // the size appropriate for an address on the target architecture.
+    Header.Length = data.getU32(offset_ptr);
+    Header.Version = data.getU16(offset_ptr);
+    Header.CuOffset = data.getU32(offset_ptr);
+    Header.AddrSize = data.getU8(offset_ptr);
+    Header.SegSize = data.getU8(offset_ptr);
+
+    // The first tuple following the header in each set begins at an offset
+    // that is a multiple of the size of a single tuple (that is, twice the
+    // size of an address). The header is padded, if necessary, to the
+    // appropriate boundary.
+    const uint32_t header_size = *offset_ptr - Offset;
+    const uint32_t tuple_size = Header.AddrSize * 2;
+    uint32_t first_tuple_offset = 0;
+    while (first_tuple_offset < header_size)
+      first_tuple_offset += tuple_size;
+
+    *offset_ptr = Offset + first_tuple_offset;
+
+    Descriptor arangeDescriptor;
+
+    assert(sizeof(arangeDescriptor.Address) == sizeof(arangeDescriptor.Length));
+    assert(sizeof(arangeDescriptor.Address) >= Header.AddrSize);
+
+    while (data.isValidOffset(*offset_ptr)) {
+      arangeDescriptor.Address = data.getUnsigned(offset_ptr, Header.AddrSize);
+      arangeDescriptor.Length = data.getUnsigned(offset_ptr, Header.AddrSize);
+
+      // Each set of tuples is terminated by a 0 for the address and 0
+      // for the length.
+      if (arangeDescriptor.Address || arangeDescriptor.Length)
+        ArangeDescriptors.push_back(arangeDescriptor);
+      else
+        break; // We are done if we get a zero address and length
+    }
+
+    return !ArangeDescriptors.empty();
+  }
+  return false;
+}
+
+void DWARFDebugArangeSet::dump(raw_ostream &OS) const {
+  OS << format("Address Range Header: length = 0x%8.8x, version = 0x%4.4x, ",
+               Header.Length, Header.Version)
+     << format("cu_offset = 0x%8.8x, addr_size = 0x%2.2x, seg_size = 0x%2.2x\n",
+               Header.CuOffset, Header.AddrSize, Header.SegSize);
+
+  const uint32_t hex_width = Header.AddrSize * 2;
+  for (DescriptorConstIter pos = ArangeDescriptors.begin(),
+       end = ArangeDescriptors.end(); pos != end; ++pos)
+    OS << format("[0x%*.*llx -", hex_width, hex_width, pos->Address)
+       << format(" 0x%*.*llx)\n", hex_width, hex_width, pos->getEndAddress());
+}
+
+
+class DescriptorContainsAddress {
+  const uint64_t Address;
+public:
+  DescriptorContainsAddress(uint64_t address) : Address(address) {}
+  bool operator()(const DWARFDebugArangeSet::Descriptor &desc) const {
+    return Address >= desc.Address && Address < (desc.Address + desc.Length);
+  }
+};
+
+uint32_t DWARFDebugArangeSet::findAddress(uint64_t address) const {
+  DescriptorConstIter end = ArangeDescriptors.end();
+  DescriptorConstIter pos =
+    std::find_if(ArangeDescriptors.begin(), end, // Range
+                 DescriptorContainsAddress(address)); // Predicate
+  if (pos != end)
+    return Header.CuOffset;
+
+  return -1U;
+}

Added: llvm/trunk/lib/DebugInfo/DWARFDebugArangeSet.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/DWARFDebugArangeSet.h?rev=139680&view=auto
==============================================================================
--- llvm/trunk/lib/DebugInfo/DWARFDebugArangeSet.h (added)
+++ llvm/trunk/lib/DebugInfo/DWARFDebugArangeSet.h Tue Sep 13 20:09:52 2011
@@ -0,0 +1,75 @@
+//===-- DWARFDebugArangeSet.h -----------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_DEBUGINFO_DWARFDEBUGARANGESET_H
+#define LLVM_DEBUGINFO_DWARFDEBUGARANGESET_H
+
+#include "llvm/Support/DataExtractor.h"
+#include <vector>
+
+namespace llvm {
+
+class raw_ostream;
+
+class DWARFDebugArangeSet {
+public:
+  struct Header {
+    // The total length of the entries for that set, not including the length
+    // field itself.
+    uint32_t Length;
+    // The DWARF version number.
+    uint16_t Version;
+    // The offset from the beginning of the .debug_info section of the
+    // compilation unit entry referenced by the table.
+    uint32_t CuOffset;
+    // The size in bytes of an address on the target architecture. For segmented
+    // addressing, this is the size of the offset portion of the address.
+    uint8_t AddrSize;
+    // The size in bytes of a segment descriptor on the target architecture.
+    // If the target system uses a flat address space, this value is 0.
+    uint8_t SegSize;
+  };
+
+  struct Descriptor {
+    uint64_t Address;
+    uint64_t Length;
+    uint64_t getEndAddress() const { return Address + Length; }
+  };
+
+private:
+  typedef std::vector<Descriptor> DescriptorColl;
+  typedef DescriptorColl::iterator DescriptorIter;
+  typedef DescriptorColl::const_iterator DescriptorConstIter;
+
+  uint32_t Offset;
+  Header Header;
+  DescriptorColl ArangeDescriptors;
+
+public:
+  DWARFDebugArangeSet() { clear(); }
+  void clear();
+  void compact();
+  bool extract(DataExtractor data, uint32_t *offset_ptr);
+  void dump(raw_ostream &OS) const;
+
+  uint32_t getCompileUnitDIEOffset() const { return Header.CuOffset; }
+  uint32_t getOffsetOfNextEntry() const { return Offset + Header.Length + 4; }
+  uint32_t findAddress(uint64_t address) const;
+  uint32_t getNumDescriptors() const { return ArangeDescriptors.size(); }
+  const struct Header &getHeader() const { return Header; }
+  const Descriptor *getDescriptor(uint32_t i) const {
+    if (i < ArangeDescriptors.size())
+      return &ArangeDescriptors[i];
+    return NULL;
+  }
+};
+
+}
+
+#endif

Added: llvm/trunk/lib/DebugInfo/DWARFDebugAranges.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/DWARFDebugAranges.cpp?rev=139680&view=auto
==============================================================================
--- llvm/trunk/lib/DebugInfo/DWARFDebugAranges.cpp (added)
+++ llvm/trunk/lib/DebugInfo/DWARFDebugAranges.cpp Tue Sep 13 20:09:52 2011
@@ -0,0 +1,210 @@
+//===-- DWARFDebugAranges.cpp -----------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "DWARFDebugAranges.h"
+#include "DWARFCompileUnit.h"
+#include "DWARFContext.h"
+#include "llvm/Support/Format.h"
+#include "llvm/Support/raw_ostream.h"
+#include <algorithm>
+#include <cassert>
+using namespace llvm;
+
+// Compare function DWARFDebugAranges::Range structures
+static bool RangeLessThan(const DWARFDebugAranges::Range &range1,
+                          const DWARFDebugAranges::Range &range2) {
+  return range1.LoPC < range2.LoPC;
+}
+
+namespace {
+  class CountArangeDescriptors {
+  public:
+    CountArangeDescriptors(uint32_t &count_ref) : Count(count_ref) {}
+    void operator()(const DWARFDebugArangeSet &set) {
+      Count += set.getNumDescriptors();
+    }
+    uint32_t &Count;
+  };
+
+  class AddArangeDescriptors {
+  public:
+    AddArangeDescriptors(DWARFDebugAranges::RangeColl &ranges)
+      : RangeCollection(ranges) {}
+    void operator()(const DWARFDebugArangeSet& set) {
+      const DWARFDebugArangeSet::Descriptor* arange_desc_ptr;
+      DWARFDebugAranges::Range range;
+      range.Offset = set.getCompileUnitDIEOffset();
+
+      for (uint32_t i=0; (arange_desc_ptr = set.getDescriptor(i)) != NULL; ++i){
+        range.LoPC = arange_desc_ptr->Address;
+        range.Length = arange_desc_ptr->Length;
+
+        // Insert each item in increasing address order so binary searching
+        // can later be done!
+        DWARFDebugAranges::RangeColl::iterator insert_pos =
+          std::lower_bound(RangeCollection.begin(), RangeCollection.end(),
+                           range, RangeLessThan);
+        RangeCollection.insert(insert_pos, range);
+      }
+    }
+    DWARFDebugAranges::RangeColl& RangeCollection;
+  };
+}
+
+bool DWARFDebugAranges::extract(DataExtractor debug_aranges_data) {
+  if (debug_aranges_data.isValidOffset(0)) {
+    uint32_t offset = 0;
+
+    typedef std::vector<DWARFDebugArangeSet> SetCollection;
+    typedef SetCollection::const_iterator SetCollectionIter;
+    SetCollection sets;
+
+    DWARFDebugArangeSet set;
+    Range range;
+    while (set.extract(debug_aranges_data, &offset))
+      sets.push_back(set);
+
+    uint32_t count = 0;
+
+    std::for_each(sets.begin(), sets.end(), CountArangeDescriptors(count));
+
+    if (count > 0) {
+      Aranges.reserve(count);
+      AddArangeDescriptors range_adder(Aranges);
+      std::for_each(sets.begin(), sets.end(), range_adder);
+    }
+  }
+  return false;
+}
+
+void DWARFDebugAranges::dump(raw_ostream &OS) const {
+  const uint32_t num_ranges = getNumRanges();
+  for (uint32_t i = 0; i < num_ranges; ++i) {
+    const Range &range = Aranges[i];
+    OS << format("0x%8.8x: [0x%8.8llx - 0x%8.8llx)", range.Offset,
+                 (uint64_t)range.LoPC, (uint64_t)range.HiPC());
+  }
+}
+
+void DWARFDebugAranges::Range::dump(raw_ostream &OS) const {
+  OS << format("{0x%8.8x}: [0x%8.8llx - 0x%8.8llx)\n", Offset, LoPC, HiPC());
+}
+
+void DWARFDebugAranges::appendRange(uint32_t offset, uint64_t low_pc,
+                                    uint64_t high_pc) {
+  if (!Aranges.empty()) {
+    if (Aranges.back().Offset == offset && Aranges.back().HiPC() == low_pc) {
+      Aranges.back().setHiPC(high_pc);
+      return;
+    }
+  }
+  Aranges.push_back(Range(low_pc, high_pc, offset));
+}
+
+void DWARFDebugAranges::sort(bool minimize, uint32_t n) {
+  const size_t orig_arange_size = Aranges.size();
+  // Size of one? If so, no sorting is needed
+  if (orig_arange_size <= 1)
+    return;
+  // Sort our address range entries
+  std::stable_sort(Aranges.begin(), Aranges.end(), RangeLessThan);
+
+  if (!minimize)
+    return;
+
+  // Most address ranges are contiguous from function to function
+  // so our new ranges will likely be smaller. We calculate the size
+  // of the new ranges since although std::vector objects can be resized,
+  // the will never reduce their allocated block size and free any excesss
+  // memory, so we might as well start a brand new collection so it is as
+  // small as possible.
+
+  // First calculate the size of the new minimal arange vector
+  // so we don't have to do a bunch of re-allocations as we
+  // copy the new minimal stuff over to the new collection.
+  size_t minimal_size = 1;
+  for (size_t i = 1; i < orig_arange_size; ++i) {
+    if (!Range::SortedOverlapCheck(Aranges[i-1], Aranges[i], n))
+      ++minimal_size;
+  }
+
+  // If the sizes are the same, then no consecutive aranges can be
+  // combined, we are done.
+  if (minimal_size == orig_arange_size)
+    return;
+
+  // Else, make a new RangeColl that _only_ contains what we need.
+  RangeColl minimal_aranges;
+  minimal_aranges.resize(minimal_size);
+  uint32_t j = 0;
+  minimal_aranges[j] = Aranges[0];
+  for (size_t i = 1; i < orig_arange_size; ++i) {
+    if(Range::SortedOverlapCheck (minimal_aranges[j], Aranges[i], n)) {
+      minimal_aranges[j].setHiPC (Aranges[i].HiPC());
+    } else {
+      // Only increment j if we aren't merging
+      minimal_aranges[++j] = Aranges[i];
+    }
+  }
+  assert (j+1 == minimal_size);
+
+  // Now swap our new minimal aranges into place. The local
+  // minimal_aranges will then contian the old big collection
+  // which will get freed.
+  minimal_aranges.swap(Aranges);
+}
+
+uint32_t DWARFDebugAranges::findAddress(uint64_t address) const {
+  if (!Aranges.empty()) {
+    Range range(address);
+    RangeCollIterator begin = Aranges.begin();
+    RangeCollIterator end = Aranges.end();
+    RangeCollIterator pos = lower_bound(begin, end, range, RangeLessThan);
+
+    if (pos != end && pos->LoPC <= address && address < pos->HiPC()) {
+      return pos->Offset;
+    } else if (pos != begin) {
+      --pos;
+      if (pos->LoPC <= address && address < pos->HiPC())
+        return (*pos).Offset;
+    }
+  }
+  return -1U;
+}
+
+bool
+DWARFDebugAranges::allRangesAreContiguous(uint64_t &LoPC, uint64_t &HiPC) const{
+  if (Aranges.empty())
+    return false;
+
+  uint64_t next_addr = 0;
+  RangeCollIterator begin = Aranges.begin();
+  for (RangeCollIterator pos = begin, end = Aranges.end(); pos != end;
+       ++pos) {
+    if (pos != begin && pos->LoPC != next_addr)
+      return false;
+    next_addr = pos->HiPC();
+  }
+  // We checked for empty at the start of function so front() will be valid.
+  LoPC = Aranges.front().LoPC;
+  // We checked for empty at the start of function so back() will be valid.
+  HiPC = Aranges.back().HiPC();
+  return true;
+}
+
+bool DWARFDebugAranges::getMaxRange(uint64_t &LoPC, uint64_t &HiPC) const {
+  if (Aranges.empty())
+    return false;
+  // We checked for empty at the start of function so front() will be valid.
+  LoPC = Aranges.front().LoPC;
+  // We checked for empty at the start of function so back() will be valid.
+  HiPC = Aranges.back().HiPC();
+  return true;
+}
+

Added: llvm/trunk/lib/DebugInfo/DWARFDebugAranges.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/DWARFDebugAranges.h?rev=139680&view=auto
==============================================================================
--- llvm/trunk/lib/DebugInfo/DWARFDebugAranges.h (added)
+++ llvm/trunk/lib/DebugInfo/DWARFDebugAranges.h Tue Sep 13 20:09:52 2011
@@ -0,0 +1,97 @@
+//===-- DWARFDebugAranges.h -------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_DEBUGINFO_DWARFDEBUGARANGES_H
+#define LLVM_DEBUGINFO_DWARFDEBUGARANGES_H
+
+#include "DWARFDebugArangeSet.h"
+#include <list>
+
+namespace llvm {
+
+class DWARFContext;
+
+class DWARFDebugAranges {
+public:
+  struct Range {
+    explicit Range(uint64_t lo = -1ULL, uint64_t hi = -1ULL,
+                   uint32_t off = -1U)
+      : LoPC(lo), Length(hi-lo), Offset(off) {}
+
+    void clear() {
+      LoPC = -1ULL;
+      Length = 0;
+      Offset = -1U;
+    }
+
+    void setHiPC(uint64_t HiPC) {
+      if (HiPC == -1ULL || HiPC <= LoPC)
+        Length = 0;
+      else
+        Length = HiPC - LoPC;
+    }
+    uint64_t HiPC() const {
+      if (Length)
+        return LoPC + Length;
+      return -1ULL;
+    }
+    bool isValidRange() const { return Length > 0; }
+
+    static bool SortedOverlapCheck(const Range &curr_range,
+                                   const Range &next_range, uint32_t n) {
+      if (curr_range.Offset != next_range.Offset)
+        return false;
+      return curr_range.HiPC() + n >= next_range.LoPC;
+    }
+
+    bool contains(const Range &range) const {
+      return LoPC <= range.LoPC && range.HiPC() <= HiPC();
+    }
+
+    void dump(raw_ostream &OS) const;
+    uint64_t LoPC; // Start of address range
+    uint32_t Length; // End of address range (not including this address)
+    uint32_t Offset; // Offset of the compile unit or die
+  };
+
+  void clear() { Aranges.clear(); }
+  bool allRangesAreContiguous(uint64_t& LoPC, uint64_t& HiPC) const;
+  bool getMaxRange(uint64_t& LoPC, uint64_t& HiPC) const;
+  bool extract(DataExtractor debug_aranges_data);
+
+  // Use append range multiple times and then call sort
+  void appendRange(uint32_t cu_offset, uint64_t low_pc, uint64_t high_pc);
+  void sort(bool minimize, uint32_t n);
+
+  const Range *rangeAtIndex(uint32_t idx) const {
+    if (idx < Aranges.size())
+      return &Aranges[idx];
+    return NULL;
+  }
+  void dump(raw_ostream &OS) const;
+  uint32_t findAddress(uint64_t address) const;
+  bool isEmpty() const { return Aranges.empty(); }
+  uint32_t getNumRanges() const { return Aranges.size(); }
+
+  uint32_t offsetAtIndex(uint32_t idx) const {
+    if (idx < Aranges.size())
+      return Aranges[idx].Offset;
+    return -1U;
+  }
+
+  typedef std::vector<Range>              RangeColl;
+  typedef RangeColl::const_iterator       RangeCollIterator;
+
+private:
+  RangeColl Aranges;
+};
+
+}
+
+#endif

Modified: llvm/trunk/tools/llvm-dwarfdump/llvm-dwarfdump.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-dwarfdump/llvm-dwarfdump.cpp?rev=139680&r1=139679&r2=139680&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-dwarfdump/llvm-dwarfdump.cpp (original)
+++ llvm/trunk/tools/llvm-dwarfdump/llvm-dwarfdump.cpp Tue Sep 13 20:09:52 2011
@@ -52,6 +52,7 @@
   StringRef DebugInfoSection;
   StringRef DebugAbbrevSection;
   StringRef DebugLineSection;
+  StringRef DebugArangesSection;
 
   error_code ec;
   for (ObjectFile::section_iterator i = Obj->begin_sections(),
@@ -67,11 +68,14 @@
       DebugAbbrevSection = data;
     else if (name.endswith("debug_line"))
       DebugLineSection = data;
+    else if (name.endswith("debug_aranges"))
+      DebugArangesSection = data;
   }
 
   OwningPtr<DIContext> dictx(DIContext::getDWARFContext(/*FIXME*/true,
                                                         DebugInfoSection,
-                                                        DebugAbbrevSection));
+                                                        DebugAbbrevSection,
+                                                        DebugArangesSection));
   dictx->dump(outs());
 }
 





More information about the llvm-commits mailing list