Debugger: Improve function scanner performance for unmapped addresses

This commit is contained in:
chaoticgd 2024-11-14 23:27:20 +00:00 committed by Ty
parent 9da4459ab3
commit ce6103be30
3 changed files with 36 additions and 30 deletions

View File

@ -93,7 +93,7 @@ const ElfProgramHeader* ElfFile::entry_point_segment() const
return entry_segment;
}
Result<std::span<const u8>> ElfFile::get_virtual(u32 address, u32 size) const
std::optional<std::span<const u8>> ElfFile::get_virtual(u32 address, u32 size) const
{
u32 end_address = address + size;
@ -109,17 +109,19 @@ Result<std::span<const u8>> ElfFile::get_virtual(u32 address, u32 size) const
}
}
return CCC_FAILURE("No ELF segment for address range 0x%x to 0x%x.", address, end_address);
return std::nullopt;
}
Result<void> ElfFile::copy_virtual(u8* dest, u32 address, u32 size) const
bool ElfFile::copy_virtual(u8* dest, u32 address, u32 size) const
{
Result<std::span<const u8>> block = get_virtual(address, size);
CCC_RETURN_IF_ERROR(block);
std::optional<std::span<const u8>> block = get_virtual(address, size);
if(!block.has_value()) {
return false;
}
memcpy(dest, block->data(), size);
return Result<void>();
return true;
}
}

View File

@ -125,18 +125,20 @@ struct ElfFile {
const ElfProgramHeader* entry_point_segment() const;
// Retrieve a block of data in an ELF file given its address and size.
Result<std::span<const u8>> get_virtual(u32 address, u32 size) const;
std::optional<std::span<const u8>> get_virtual(u32 address, u32 size) const;
// Copy a block of data in an ELF file to the destination buffer given its
// address and size.
Result<void> copy_virtual(u8* dest, u32 address, u32 size) const;
bool copy_virtual(u8* dest, u32 address, u32 size) const;
// Retrieve an object of type T from an ELF file given its address.
template <typename T>
Result<T> get_object_virtual(u32 address) const
std::optional<T> get_object_virtual(u32 address) const
{
Result<std::span<const u8>> result = get_virtual(address, sizeof(T));
CCC_RETURN_IF_ERROR(result);
std::optional<std::span<const u8>> result = get_virtual(address, sizeof(T));
if(!result.has_value()) {
return std::nullopt;
}
return *(T*) result->data();
}
@ -144,10 +146,12 @@ struct ElfFile {
// Retrieve an array of objects of type T from an ELF file given its
// address and element count.
template <typename T>
Result<std::span<const T>> get_array_virtual(u32 address, u32 element_count) const
std::optional<std::span<const T>> get_array_virtual(u32 address, u32 element_count) const
{
Result<std::span<const u8>> result = get_virtual(address, element_count * sizeof(T));
CCC_RETURN_IF_ERROR(result);
std::optional<std::span<const u8>> result = get_virtual(address, element_count * sizeof(T));
if(!result.has_value()) {
return std::nullopt;
}
return std::span<const T>((T*) result->data(), (T*) (result->data() + result->size()));
}

View File

@ -1012,8 +1012,8 @@ ElfMemoryReader::ElfMemoryReader(const ccc::ElfFile& elf)
u32 ElfMemoryReader::read8(u32 address)
{
ccc::Result<u8> result = m_elf.get_object_virtual<u8>(address);
if (!result.success())
std::optional<u8> result = m_elf.get_object_virtual<u8>(address);
if (!result.has_value())
return 0;
return *result;
@ -1021,8 +1021,8 @@ u32 ElfMemoryReader::read8(u32 address)
u32 ElfMemoryReader::read8(u32 address, bool& valid)
{
ccc::Result<u8> result = m_elf.get_object_virtual<u8>(address);
valid = result.success();
std::optional<u8> result = m_elf.get_object_virtual<u8>(address);
valid = result.has_value();
if (!valid)
return 0;
@ -1031,8 +1031,8 @@ u32 ElfMemoryReader::read8(u32 address, bool& valid)
u32 ElfMemoryReader::read16(u32 address)
{
ccc::Result<u16> result = m_elf.get_object_virtual<u16>(address);
if (!result.success())
std::optional<u16> result = m_elf.get_object_virtual<u16>(address);
if (!result.has_value())
return 0;
return *result;
@ -1040,8 +1040,8 @@ u32 ElfMemoryReader::read16(u32 address)
u32 ElfMemoryReader::read16(u32 address, bool& valid)
{
ccc::Result<u16> result = m_elf.get_object_virtual<u16>(address);
valid = result.success();
std::optional<u16> result = m_elf.get_object_virtual<u16>(address);
valid = result.has_value();
if (!valid)
return 0;
@ -1050,8 +1050,8 @@ u32 ElfMemoryReader::read16(u32 address, bool& valid)
u32 ElfMemoryReader::read32(u32 address)
{
ccc::Result<u32> result = m_elf.get_object_virtual<u32>(address);
if (!result.success())
std::optional<u32> result = m_elf.get_object_virtual<u32>(address);
if (!result.has_value())
return 0;
return *result;
@ -1059,8 +1059,8 @@ u32 ElfMemoryReader::read32(u32 address)
u32 ElfMemoryReader::read32(u32 address, bool& valid)
{
ccc::Result<u32> result = m_elf.get_object_virtual<u32>(address);
valid = result.success();
std::optional<u32> result = m_elf.get_object_virtual<u32>(address);
valid = result.has_value();
if (!valid)
return 0;
@ -1069,8 +1069,8 @@ u32 ElfMemoryReader::read32(u32 address, bool& valid)
u64 ElfMemoryReader::read64(u32 address)
{
ccc::Result<u64> result = m_elf.get_object_virtual<u64>(address);
if (!result.success())
std::optional<u64> result = m_elf.get_object_virtual<u64>(address);
if (!result.has_value())
return 0;
return *result;
@ -1078,8 +1078,8 @@ u64 ElfMemoryReader::read64(u32 address)
u64 ElfMemoryReader::read64(u32 address, bool& valid)
{
ccc::Result<u64> result = m_elf.get_object_virtual<u64>(address);
valid = result.success();
std::optional<u64> result = m_elf.get_object_virtual<u64>(address);
valid = result.has_value();
if (!valid)
return 0;