LCOV - code coverage report
Current view: top level - lib/DebugInfo/DWARF - DWARFDebugRangeList.cpp (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 47 48 97.9 %
Date: 2018-07-13 00:08:38 Functions: 5 6 83.3 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : //===- DWARFDebugRangesList.cpp -------------------------------------------===//
       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 "llvm/DebugInfo/DWARF/DWARFDebugRangeList.h"
      11             : #include "llvm/DebugInfo/DWARF/DWARFContext.h"
      12             : #include "llvm/Support/Format.h"
      13             : #include "llvm/Support/raw_ostream.h"
      14             : #include <cinttypes>
      15             : #include <cstdint>
      16             : 
      17             : using namespace llvm;
      18             : 
      19             : // FIXME: There are several versions of this. Consolidate them.
      20             : template <typename... Ts>
      21           6 : static Error createError(char const *Fmt, const Ts &... Vals) {
      22             :   std::string Buffer;
      23           6 :   raw_string_ostream Stream(Buffer);
      24          12 :   Stream << format(Fmt, Vals...);
      25          18 :   return make_error<StringError>(Stream.str(), inconvertibleErrorCode());
      26             : }
      27             : 
      28        2580 : void DWARFDebugRangeList::clear() {
      29        2580 :   Offset = -1U;
      30        2580 :   AddressSize = 0;
      31             :   Entries.clear();
      32        2580 : }
      33             : 
      34        1210 : Error DWARFDebugRangeList::extract(const DWARFDataExtractor &data,
      35             :                                    uint32_t *offset_ptr) {
      36        1210 :   clear();
      37        2420 :   if (!data.isValidOffset(*offset_ptr))
      38           3 :     return createError("invalid range list offset 0x%" PRIx32, *offset_ptr);
      39             : 
      40        1207 :   AddressSize = data.getAddressSize();
      41        1207 :   if (AddressSize != 4 && AddressSize != 8)
      42           0 :     return createError("invalid address size: %d", AddressSize);
      43        1207 :   Offset = *offset_ptr;
      44             :   while (true) {
      45             :     RangeListEntry Entry;
      46        7799 :     Entry.SectionIndex = -1ULL;
      47             : 
      48        7799 :     uint32_t prev_offset = *offset_ptr;
      49        7799 :     Entry.StartAddress = data.getRelocatedAddress(offset_ptr);
      50        7799 :     Entry.EndAddress =
      51             :         data.getRelocatedAddress(offset_ptr, &Entry.SectionIndex);
      52             : 
      53             :     // Check that both values were extracted correctly.
      54        7799 :     if (*offset_ptr != prev_offset + 2 * AddressSize) {
      55           3 :       clear();
      56             :       return createError("invalid range list entry at offset 0x%" PRIx32,
      57           3 :                          prev_offset);
      58             :     }
      59        7796 :     if (Entry.isEndOfListEntry())
      60             :       break;
      61        6592 :     Entries.push_back(Entry);
      62        6592 :   }
      63             :   return Error::success();
      64             : }
      65             : 
      66          32 : void DWARFDebugRangeList::dump(raw_ostream &OS) const {
      67          32 :   for (const RangeListEntry &RLE : Entries) {
      68          96 :     const char *format_str = (AddressSize == 4
      69          96 :                               ? "%08x %08"  PRIx64 " %08"  PRIx64 "\n"
      70             :                               : "%08x %016" PRIx64 " %016" PRIx64 "\n");
      71         192 :     OS << format(format_str, Offset, RLE.StartAddress, RLE.EndAddress);
      72             :   }
      73          64 :   OS << format("%08x <End of list>\n", Offset);
      74          32 : }
      75             : 
      76        1160 : DWARFAddressRangesVector DWARFDebugRangeList::getAbsoluteRanges(
      77             :     llvm::Optional<BaseAddress> BaseAddr) const {
      78             :   DWARFAddressRangesVector Res;
      79        1160 :   for (const RangeListEntry &RLE : Entries) {
      80       12950 :     if (RLE.isBaseAddressSelectionEntry(AddressSize)) {
      81           6 :       BaseAddr = {RLE.EndAddress, RLE.SectionIndex};
      82           6 :       continue;
      83             :     }
      84             : 
      85             :     DWARFAddressRange E;
      86        6466 :     E.LowPC = RLE.StartAddress;
      87        6466 :     E.HighPC = RLE.EndAddress;
      88        6466 :     E.SectionIndex = RLE.SectionIndex;
      89             :     // Base address of a range list entry is determined by the closest preceding
      90             :     // base address selection entry in the same range list. It defaults to the
      91             :     // base address of the compilation unit if there is no such entry.
      92        6466 :     if (BaseAddr) {
      93        6461 :       E.LowPC += BaseAddr->Address;
      94        6461 :       E.HighPC += BaseAddr->Address;
      95        6461 :       if (E.SectionIndex == -1ULL)
      96        6400 :         E.SectionIndex = BaseAddr->SectionIndex;
      97             :     }
      98        6466 :     Res.push_back(E);
      99             :   }
     100        1160 :   return Res;
     101             : }

Generated by: LCOV version 1.13