File: CoreFileMemoryRanges.cpp

package info (click to toggle)
llvm-toolchain-20 1%3A20.1.6-1~exp1
  • links: PTS, VCS
  • area: main
  • in suites: experimental
  • size: 2,111,304 kB
  • sloc: cpp: 7,438,677; ansic: 1,393,822; asm: 1,012,926; python: 241,650; f90: 86,635; objc: 75,479; lisp: 42,144; pascal: 17,286; sh: 10,027; ml: 5,082; perl: 4,730; awk: 3,523; makefile: 3,349; javascript: 2,251; xml: 892; fortran: 672
file content (86 lines) | stat: -rw-r--r-- 3,535 bytes parent folder | download | duplicates (6)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
//===-- CoreFileMemoryRanges.cpp --------------------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "lldb/Target/CoreFileMemoryRanges.h"

using namespace lldb;
using namespace lldb_private;

using Entry = CoreFileMemoryRanges::Entry;

static bool Overlaps(const Entry *region_one, const Entry *region_two) {
  return !(region_one->GetRangeEnd() < region_two->GetRangeBase() ||
           region_two->GetRangeEnd() < region_one->GetRangeBase());
}

static bool IntersectHelper(const Entry *region_one, const Entry *region_two) {
  return region_one->GetRangeBase() == region_two->GetRangeEnd() ||
         region_one->GetRangeEnd() == region_two->GetRangeBase();
}

static bool OnlyIntersects(const Entry *region_one, const Entry *region_two) {
  return IntersectHelper(region_one, region_two) ||
         IntersectHelper(region_two, region_one);
}

static bool PermissionsMatch(const Entry *region_one, const Entry *region_two) {
  return region_one->data.lldb_permissions == region_two->data.lldb_permissions;
}

// This assumes any overlapping ranges will share the same permissions
// and that adjacent ranges could have different permissions.
Status CoreFileMemoryRanges::FinalizeCoreFileSaveRanges() {
  Status error;
  this->Sort();
  for (size_t i = this->GetSize() - 1; i > 0; i--) {
    auto region_one = this->GetMutableEntryAtIndex(i);
    auto region_two = this->GetMutableEntryAtIndex(i - 1);
    if (Overlaps(region_one, region_two)) {
      // It's okay for interesecting regions to have different permissions but
      // if they overlap we fail because we don't know what to do with them.
      if (!PermissionsMatch(region_one, region_two)) {
        // Permissions mismatch and it's not a simple intersection.
        if (!OnlyIntersects(region_one, region_two)) {
          error = Status::FromErrorStringWithFormatv(
              "Memory region at {0}::{1} has different permssions than "
              "overlapping region at {2}::{3}",
              region_one->GetRangeBase(), region_one->GetRangeEnd(),
              region_two->GetRangeBase(), region_two->GetRangeEnd());
          return error;
        }
        // Simple intersection, we can just not merge these.
        else
          continue;
      }
      const addr_t base =
          std::min(region_one->GetRangeBase(), region_two->GetRangeBase());
      const addr_t byte_size =
          std::max(region_one->GetRangeEnd(), region_two->GetRangeEnd()) - base;

      region_two->SetRangeBase(base);
      region_two->SetByteSize(byte_size);

      // Because this is a range data vector, the entry has a base as well
      // as the data contained in the entry. So we have to update both.
      // And llvm::AddressRange isn't mutable so we have to create a new one.
      llvm::AddressRange range(base, base + byte_size);
      const CoreFileMemoryRange core_range = {
          range, region_two->data.lldb_permissions};
      region_two->data = core_range;
      // Erase is delete from [Inclusive, exclusive index).
      if (!this->Erase(i, i + 1)) {
        error = Status::FromErrorStringWithFormat(
            "Core file memory ranges mutated outside of "
            "CalculateCoreFileSaveRanges");
        return error;
      }
    }
  }

  return error;
}