brintos

brintos / llvm-project-archived public Read only

0
0
Text · 3.5 KiB · 6e4ca49 Raw
87 lines · cpp
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-exception6//7//===----------------------------------------------------------------------===//8 9#include "lldb/Target/CoreFileMemoryRanges.h"10 11using namespace lldb;12using namespace lldb_private;13 14using Entry = CoreFileMemoryRanges::Entry;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 permissions36// and that adjacent ranges could have different permissions.37Status CoreFileMemoryRanges::FinalizeCoreFileSaveRanges() {38  Status error;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 but45      // 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());54          return error;55        }56        // Simple intersection, we can just not merge these.57        else58          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 well69      // 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");80        return error;81      }82    }83  }84 85  return error;86}87