1 //===-- CoreFileMemoryRanges.cpp --------------------------------*- C++ -*-===//
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
7 //===----------------------------------------------------------------------===//
9 #include "lldb/Target/CoreFileMemoryRanges.h"
12 using namespace lldb_private
;
14 using Entry
= CoreFileMemoryRanges::Entry
;
16 static 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());
21 static 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();
26 static bool OnlyIntersects(const Entry
*region_one
, const Entry
*region_two
) {
27 return IntersectHelper(region_one
, region_two
) ||
28 IntersectHelper(region_two
, region_one
);
31 static bool PermissionsMatch(const Entry
*region_one
, const Entry
*region_two
) {
32 return region_one
->data
.lldb_permissions
== region_two
->data
.lldb_permissions
;
35 // This assumes any overlapping ranges will share the same permissions
36 // and that adjacent ranges could have different permissions.
37 Status
CoreFileMemoryRanges::FinalizeCoreFileSaveRanges() {
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
)) {
49 error
= Status::FromErrorStringWithFormatv(
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());
56 // Simple intersection, we can just not merge these.
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
;
65 region_two
->SetRangeBase(base
);
66 region_two
->SetByteSize(byte_size
);
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)) {
77 error
= Status::FromErrorStringWithFormat(
78 "Core file memory ranges mutated outside of "
79 "CalculateCoreFileSaveRanges");