brintos

brintos / llvm-project-archived public Read only

0
0
Text · 5.3 KiB · a23e43b Raw
140 lines · cpp
1//===----------------------------------------------------------------------===//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/Utility/VirtualDataExtractor.h"10#include <cassert>11 12using namespace lldb;13using namespace lldb_private;14 15VirtualDataExtractor::VirtualDataExtractor(const void *data,16                                           offset_t data_length,17                                           ByteOrder byte_order,18                                           uint32_t addr_size,19                                           LookupTable lookup_table)20    : DataExtractor(data, data_length, byte_order, addr_size),21      m_lookup_table(std::move(lookup_table)) {22  m_lookup_table.Sort();23}24 25VirtualDataExtractor::VirtualDataExtractor(const DataBufferSP &data_sp,26                                           ByteOrder byte_order,27                                           uint32_t addr_size,28                                           LookupTable lookup_table)29    : DataExtractor(data_sp, byte_order, addr_size),30      m_lookup_table(std::move(lookup_table)) {31  m_lookup_table.Sort();32}33 34const VirtualDataExtractor::LookupTable::Entry *35VirtualDataExtractor::FindEntry(offset_t virtual_addr) const {36  // Use RangeDataVector's binary search instead of linear search.37  return m_lookup_table.FindEntryThatContains(virtual_addr);38}39 40bool VirtualDataExtractor::ValidateVirtualRead(offset_t virtual_addr,41                                               offset_t length) const {42  const LookupTable::Entry *entry = FindEntry(virtual_addr);43  if (!entry)44    return false;45 46  // Assert that the read does not cross entry boundaries.47  // RangeData.Contains() checks if a range is fully contained.48  assert(entry->Contains(LookupTable::Range(virtual_addr, length)) &&49         "Read crosses lookup table entry boundary");50 51  // Also validate that the physical offset is within the data buffer.52  // RangeData.data contains the physical offset.53  offset_t physical_offset = entry->data + (virtual_addr - entry->base);54  return ValidOffsetForDataOfSize(physical_offset, length);55}56 57const void *VirtualDataExtractor::GetData(offset_t *offset_ptr,58                                          offset_t length) const {59  // Override to treat offset as virtual address.60  if (!offset_ptr)61    return nullptr;62 63  offset_t virtual_addr = *offset_ptr;64 65  if (!ValidateVirtualRead(virtual_addr, length))66    return nullptr;67 68  const LookupTable::Entry *entry = FindEntry(virtual_addr);69  assert(entry && "ValidateVirtualRead should have found an entry");70 71  offset_t physical_offset = entry->data + (virtual_addr - entry->base);72  // Use base class PeekData directly to avoid recursion.73  const void *result = DataExtractor::PeekData(physical_offset, length);74 75  if (result) {76    // Advance the virtual offset pointer.77    *offset_ptr += length;78  }79 80  return result;81}82 83const uint8_t *VirtualDataExtractor::PeekData(offset_t offset,84                                              offset_t length) const {85  // Override to treat offset as virtual address.86  if (!ValidateVirtualRead(offset, length))87    return nullptr;88 89  const LookupTable::Entry *entry = FindEntry(offset);90  assert(entry && "ValidateVirtualRead should have found an entry");91 92  offset_t physical_offset = entry->data + (offset - entry->base);93  // Use the base class PeekData with the physical offset.94  return DataExtractor::PeekData(physical_offset, length);95}96 97uint8_t VirtualDataExtractor::GetU8_unchecked(offset_t *offset_ptr) const {98  offset_t virtual_addr = *offset_ptr;99  const LookupTable::Entry *entry = FindEntry(virtual_addr);100  assert(entry && "Unchecked methods require valid virtual address");101 102  offset_t physical_offset = entry->data + (virtual_addr - entry->base);103  uint8_t result = DataExtractor::GetU8_unchecked(&physical_offset);104  *offset_ptr += 1;105  return result;106}107 108uint16_t VirtualDataExtractor::GetU16_unchecked(offset_t *offset_ptr) const {109  offset_t virtual_addr = *offset_ptr;110  const LookupTable::Entry *entry = FindEntry(virtual_addr);111  assert(entry && "Unchecked methods require valid virtual address");112 113  offset_t physical_offset = entry->data + (virtual_addr - entry->base);114  uint16_t result = DataExtractor::GetU16_unchecked(&physical_offset);115  *offset_ptr += 2;116  return result;117}118 119uint32_t VirtualDataExtractor::GetU32_unchecked(offset_t *offset_ptr) const {120  offset_t virtual_addr = *offset_ptr;121  const LookupTable::Entry *entry = FindEntry(virtual_addr);122  assert(entry && "Unchecked methods require valid virtual address");123 124  offset_t physical_offset = entry->data + (virtual_addr - entry->base);125  uint32_t result = DataExtractor::GetU32_unchecked(&physical_offset);126  *offset_ptr += 4;127  return result;128}129 130uint64_t VirtualDataExtractor::GetU64_unchecked(offset_t *offset_ptr) const {131  offset_t virtual_addr = *offset_ptr;132  const LookupTable::Entry *entry = FindEntry(virtual_addr);133  assert(entry && "Unchecked methods require valid virtual address");134 135  offset_t physical_offset = entry->data + (virtual_addr - entry->base);136  uint64_t result = DataExtractor::GetU64_unchecked(&physical_offset);137  *offset_ptr += 8;138  return result;139}140