LCOV - code coverage report
Current view: top level - lib/DebugInfo/DWARF - DWARFDebugArangeSet.cpp (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 41 41 100.0 %
Date: 2018-10-20 13:21:21 Functions: 4 4 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : //===- DWARFDebugArangeSet.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/DWARFDebugArangeSet.h"
      11             : #include "llvm/Support/Format.h"
      12             : #include "llvm/Support/raw_ostream.h"
      13             : #include <cassert>
      14             : #include <cinttypes>
      15             : #include <cstdint>
      16             : #include <cstring>
      17             : 
      18             : using namespace llvm;
      19             : 
      20         131 : void DWARFDebugArangeSet::Descriptor::dump(raw_ostream &OS,
      21             :                                            uint32_t AddressSize) const {
      22         262 :   OS << format("[0x%*.*" PRIx64 ", ", AddressSize * 2, AddressSize * 2, Address)
      23         131 :      << format(" 0x%*.*" PRIx64 ")", AddressSize * 2, AddressSize * 2,
      24         262 :                getEndAddress());
      25         131 : }
      26             : 
      27         122 : void DWARFDebugArangeSet::clear() {
      28         122 :   Offset = -1U;
      29         122 :   std::memset(&HeaderData, 0, sizeof(Header));
      30             :   ArangeDescriptors.clear();
      31         122 : }
      32             : 
      33             : bool
      34        1174 : DWARFDebugArangeSet::extract(DataExtractor data, uint32_t *offset_ptr) {
      35        2348 :   if (data.isValidOffset(*offset_ptr)) {
      36        1062 :     ArangeDescriptors.clear();
      37        1062 :     Offset = *offset_ptr;
      38             : 
      39             :     // 7.20 Address Range Table
      40             :     //
      41             :     // Each set of entries in the table of address ranges contained in
      42             :     // the .debug_aranges section begins with a header consisting of: a
      43             :     // 4-byte length containing the length of the set of entries for this
      44             :     // compilation unit, not including the length field itself; a 2-byte
      45             :     // version identifier containing the value 2 for DWARF Version 2; a
      46             :     // 4-byte offset into the.debug_infosection; a 1-byte unsigned integer
      47             :     // containing the size in bytes of an address (or the offset portion of
      48             :     // an address for segmented addressing) on the target system; and a
      49             :     // 1-byte unsigned integer containing the size in bytes of a segment
      50             :     // descriptor on the target system. This header is followed by a series
      51             :     // of tuples. Each tuple consists of an address and a length, each in
      52             :     // the size appropriate for an address on the target architecture.
      53        1062 :     HeaderData.Length = data.getU32(offset_ptr);
      54        1062 :     HeaderData.Version = data.getU16(offset_ptr);
      55        1062 :     HeaderData.CuOffset = data.getU32(offset_ptr);
      56        1062 :     HeaderData.AddrSize = data.getU8(offset_ptr);
      57        1062 :     HeaderData.SegSize = data.getU8(offset_ptr);
      58             : 
      59             :     // Perform basic validation of the header fields.
      60        1062 :     if (!data.isValidOffsetForDataOfSize(Offset, HeaderData.Length) ||
      61        1057 :         (HeaderData.AddrSize != 4 && HeaderData.AddrSize != 8)) {
      62           5 :       clear();
      63           5 :       return false;
      64             :     }
      65             : 
      66             :     // The first tuple following the header in each set begins at an offset
      67             :     // that is a multiple of the size of a single tuple (that is, twice the
      68             :     // size of an address). The header is padded, if necessary, to the
      69             :     // appropriate boundary.
      70        1057 :     const uint32_t header_size = *offset_ptr - Offset;
      71        1057 :     const uint32_t tuple_size = HeaderData.AddrSize * 2;
      72             :     uint32_t first_tuple_offset = 0;
      73        2121 :     while (first_tuple_offset < header_size)
      74        1064 :       first_tuple_offset += tuple_size;
      75             : 
      76        1057 :     *offset_ptr = Offset + first_tuple_offset;
      77             : 
      78             :     Descriptor arangeDescriptor;
      79             : 
      80             :     static_assert(sizeof(arangeDescriptor.Address) ==
      81             :                       sizeof(arangeDescriptor.Length),
      82             :                   "Different datatypes for addresses and sizes!");
      83             :     assert(sizeof(arangeDescriptor.Address) >= HeaderData.AddrSize);
      84             : 
      85       67751 :     while (data.isValidOffset(*offset_ptr)) {
      86       66694 :       arangeDescriptor.Address = data.getUnsigned(offset_ptr, HeaderData.AddrSize);
      87       66694 :       arangeDescriptor.Length = data.getUnsigned(offset_ptr, HeaderData.AddrSize);
      88             : 
      89             :       // Each set of tuples is terminated by a 0 for the address and 0
      90             :       // for the length.
      91       66694 :       if (arangeDescriptor.Address || arangeDescriptor.Length)
      92       65637 :         ArangeDescriptors.push_back(arangeDescriptor);
      93             :       else
      94             :         break; // We are done if we get a zero address and length
      95             :     }
      96             : 
      97        1057 :     return !ArangeDescriptors.empty();
      98             :   }
      99             :   return false;
     100             : }
     101             : 
     102          89 : void DWARFDebugArangeSet::dump(raw_ostream &OS) const {
     103          89 :   OS << format("Address Range Header: length = 0x%8.8x, version = 0x%4.4x, ",
     104          89 :                HeaderData.Length, HeaderData.Version)
     105          89 :      << format("cu_offset = 0x%8.8x, addr_size = 0x%2.2x, seg_size = 0x%2.2x\n",
     106          89 :                HeaderData.CuOffset, HeaderData.AddrSize, HeaderData.SegSize);
     107             : 
     108         220 :   for (const auto &Desc : ArangeDescriptors) {
     109         131 :     Desc.dump(OS, HeaderData.AddrSize);
     110             :     OS << '\n';
     111             :   }
     112          89 : }

Generated by: LCOV version 1.13