LLDB mainline
CoreFileMemoryRanges.cpp
Go to the documentation of this file.
1//===-- CoreFileMemoryRanges.cpp --------------------------------*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
10
11using namespace lldb;
12using namespace lldb_private;
13
15
16static bool Overlaps(const Entry *region_one, const Entry *region_two) {
17 return !(region_one->GetRangeEnd() < region_two->GetRangeBase() ||
18 region_two->GetRangeEnd() < region_one->GetRangeBase());
19}
20
21static bool IntersectHelper(const Entry *region_one, const Entry *region_two) {
22 return region_one->GetRangeBase() == region_two->GetRangeEnd() ||
23 region_one->GetRangeEnd() == region_two->GetRangeBase();
24}
25
26static bool OnlyIntersects(const Entry *region_one, const Entry *region_two) {
27 return IntersectHelper(region_one, region_two) ||
28 IntersectHelper(region_two, region_one);
29}
30
31static bool PermissionsMatch(const Entry *region_one, const Entry *region_two) {
32 return region_one->data.lldb_permissions == region_two->data.lldb_permissions;
33}
34
35// This assumes any overlapping ranges will share the same permissions
36// and that adjacent ranges could have different permissions.
39 this->Sort();
40 for (size_t i = this->GetSize() - 1; i > 0; i--) {
41 auto region_one = this->GetMutableEntryAtIndex(i);
42 auto region_two = this->GetMutableEntryAtIndex(i - 1);
43 if (Overlaps(region_one, region_two)) {
44 // It's okay for interesecting regions to have different permissions but
45 // if they overlap we fail because we don't know what to do with them.
46 if (!PermissionsMatch(region_one, region_two)) {
47 // Permissions mismatch and it's not a simple intersection.
48 if (!OnlyIntersects(region_one, region_two)) {
50 "Memory region at {0}::{1} has different permssions than "
51 "overlapping region at {2}::{3}",
52 region_one->GetRangeBase(), region_one->GetRangeEnd(),
53 region_two->GetRangeBase(), region_two->GetRangeEnd());
54 return error;
55 }
56 // Simple intersection, we can just not merge these.
57 else
58 continue;
59 }
60 const addr_t base =
61 std::min(region_one->GetRangeBase(), region_two->GetRangeBase());
62 const addr_t byte_size =
63 std::max(region_one->GetRangeEnd(), region_two->GetRangeEnd()) - base;
64
65 region_two->SetRangeBase(base);
66 region_two->SetByteSize(byte_size);
67
68 // Because this is a range data vector, the entry has a base as well
69 // as the data contained in the entry. So we have to update both.
70 // And llvm::AddressRange isn't mutable so we have to create a new one.
71 llvm::AddressRange range(base, base + byte_size);
72 const CoreFileMemoryRange core_range = {
73 range, region_two->data.lldb_permissions};
74 region_two->data = core_range;
75 // Erase is delete from [Inclusive, exclusive index).
76 if (!this->Erase(i, i + 1)) {
78 "Core file memory ranges mutated outside of "
79 "CalculateCoreFileSaveRanges");
80 return error;
81 }
82 }
83 }
84
85 return error;
86}
static llvm::raw_ostream & error(Stream &strm)
static bool OnlyIntersects(const Entry *region_one, const Entry *region_two)
static bool Overlaps(const Entry *region_one, const Entry *region_two)
static bool IntersectHelper(const Entry *region_one, const Entry *region_two)
static bool PermissionsMatch(const Entry *region_one, const Entry *region_two)
Status FinalizeCoreFileSaveRanges()
Finalize and merge all overlapping ranges in this collection.
An error handling class.
Definition: Status.h:118
static Status FromErrorStringWithFormat(const char *format,...) __attribute__((format(printf
Definition: Status.cpp:106
static Status static Status FromErrorStringWithFormatv(const char *format, Args &&...args)
Definition: Status.h:151
A class that represents a running process on the host machine.
Definition: SBAddress.h:15
uint64_t addr_t
Definition: lldb-types.h:80
uint32_t lldb_permissions
The address range to save into the core file.