1243789Sdim//===-- DWARFDebugRangesList.cpp ------------------------------------------===//
2243789Sdim//
3243789Sdim//                     The LLVM Compiler Infrastructure
4243789Sdim//
5243789Sdim// This file is distributed under the University of Illinois Open Source
6243789Sdim// License. See LICENSE.TXT for details.
7243789Sdim//
8243789Sdim//===----------------------------------------------------------------------===//
9243789Sdim
10243789Sdim#include "DWARFDebugRangeList.h"
11243789Sdim#include "llvm/Support/Format.h"
12243789Sdim#include "llvm/Support/raw_ostream.h"
13243789Sdim
14243789Sdimusing namespace llvm;
15243789Sdim
16243789Sdimvoid DWARFDebugRangeList::clear() {
17243789Sdim  Offset = -1U;
18243789Sdim  AddressSize = 0;
19243789Sdim  Entries.clear();
20243789Sdim}
21243789Sdim
22243789Sdimbool DWARFDebugRangeList::extract(DataExtractor data, uint32_t *offset_ptr) {
23243789Sdim  clear();
24243789Sdim  if (!data.isValidOffset(*offset_ptr))
25243789Sdim    return false;
26243789Sdim  AddressSize = data.getAddressSize();
27243789Sdim  if (AddressSize != 4 && AddressSize != 8)
28243789Sdim    return false;
29243789Sdim  Offset = *offset_ptr;
30243789Sdim  while (true) {
31243789Sdim    RangeListEntry entry;
32243789Sdim    uint32_t prev_offset = *offset_ptr;
33243789Sdim    entry.StartAddress = data.getAddress(offset_ptr);
34243789Sdim    entry.EndAddress = data.getAddress(offset_ptr);
35243789Sdim    // Check that both values were extracted correctly.
36243789Sdim    if (*offset_ptr != prev_offset + 2 * AddressSize) {
37243789Sdim      clear();
38243789Sdim      return false;
39243789Sdim    }
40243789Sdim    if (entry.isEndOfListEntry())
41243789Sdim      break;
42243789Sdim    Entries.push_back(entry);
43243789Sdim  }
44243789Sdim  return true;
45243789Sdim}
46243789Sdim
47243789Sdimvoid DWARFDebugRangeList::dump(raw_ostream &OS) const {
48243789Sdim  for (int i = 0, n = Entries.size(); i != n; ++i) {
49243789Sdim    const char *format_str = (AddressSize == 4
50243789Sdim                              ? "%08x %08"  PRIx64 " %08"  PRIx64 "\n"
51243789Sdim                              : "%08x %016" PRIx64 " %016" PRIx64 "\n");
52243789Sdim    OS << format(format_str, Offset, Entries[i].StartAddress,
53243789Sdim                                     Entries[i].EndAddress);
54243789Sdim  }
55243789Sdim  OS << format("%08x <End of list>\n", Offset);
56243789Sdim}
57243789Sdim
58243789Sdimbool DWARFDebugRangeList::containsAddress(uint64_t BaseAddress,
59243789Sdim                                          uint64_t Address) const {
60243789Sdim  for (int i = 0, n = Entries.size(); i != n; ++i) {
61243789Sdim    if (Entries[i].isBaseAddressSelectionEntry(AddressSize))
62243789Sdim      BaseAddress = Entries[i].EndAddress;
63243789Sdim    else if (Entries[i].containsAddress(BaseAddress, Address))
64243789Sdim      return true;
65243789Sdim  }
66243789Sdim  return false;
67243789Sdim}
68