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; 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; 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); std::optional<std::span<const u8>> block = get_virtual(address, size);
CCC_RETURN_IF_ERROR(block); if(!block.has_value()) {
return false;
}
memcpy(dest, block->data(), size); memcpy(dest, block->data(), size);
return Result<void>(); return true;
} }
} }

View File

@ -125,18 +125,20 @@ struct ElfFile {
const ElfProgramHeader* entry_point_segment() const; const ElfProgramHeader* entry_point_segment() const;
// Retrieve a block of data in an ELF file given its address and size. // 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 // Copy a block of data in an ELF file to the destination buffer given its
// address and size. // 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. // Retrieve an object of type T from an ELF file given its address.
template <typename T> 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)); std::optional<std::span<const u8>> result = get_virtual(address, sizeof(T));
CCC_RETURN_IF_ERROR(result); if(!result.has_value()) {
return std::nullopt;
}
return *(T*) result->data(); return *(T*) result->data();
} }
@ -144,10 +146,12 @@ struct ElfFile {
// Retrieve an array of objects of type T from an ELF file given its // Retrieve an array of objects of type T from an ELF file given its
// address and element count. // address and element count.
template <typename T> 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)); std::optional<std::span<const u8>> result = get_virtual(address, element_count * sizeof(T));
CCC_RETURN_IF_ERROR(result); if(!result.has_value()) {
return std::nullopt;
}
return std::span<const T>((T*) result->data(), (T*) (result->data() + result->size())); 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) u32 ElfMemoryReader::read8(u32 address)
{ {
ccc::Result<u8> result = m_elf.get_object_virtual<u8>(address); std::optional<u8> result = m_elf.get_object_virtual<u8>(address);
if (!result.success()) if (!result.has_value())
return 0; return 0;
return *result; return *result;
@ -1021,8 +1021,8 @@ u32 ElfMemoryReader::read8(u32 address)
u32 ElfMemoryReader::read8(u32 address, bool& valid) u32 ElfMemoryReader::read8(u32 address, bool& valid)
{ {
ccc::Result<u8> result = m_elf.get_object_virtual<u8>(address); std::optional<u8> result = m_elf.get_object_virtual<u8>(address);
valid = result.success(); valid = result.has_value();
if (!valid) if (!valid)
return 0; return 0;
@ -1031,8 +1031,8 @@ u32 ElfMemoryReader::read8(u32 address, bool& valid)
u32 ElfMemoryReader::read16(u32 address) u32 ElfMemoryReader::read16(u32 address)
{ {
ccc::Result<u16> result = m_elf.get_object_virtual<u16>(address); std::optional<u16> result = m_elf.get_object_virtual<u16>(address);
if (!result.success()) if (!result.has_value())
return 0; return 0;
return *result; return *result;
@ -1040,8 +1040,8 @@ u32 ElfMemoryReader::read16(u32 address)
u32 ElfMemoryReader::read16(u32 address, bool& valid) u32 ElfMemoryReader::read16(u32 address, bool& valid)
{ {
ccc::Result<u16> result = m_elf.get_object_virtual<u16>(address); std::optional<u16> result = m_elf.get_object_virtual<u16>(address);
valid = result.success(); valid = result.has_value();
if (!valid) if (!valid)
return 0; return 0;
@ -1050,8 +1050,8 @@ u32 ElfMemoryReader::read16(u32 address, bool& valid)
u32 ElfMemoryReader::read32(u32 address) u32 ElfMemoryReader::read32(u32 address)
{ {
ccc::Result<u32> result = m_elf.get_object_virtual<u32>(address); std::optional<u32> result = m_elf.get_object_virtual<u32>(address);
if (!result.success()) if (!result.has_value())
return 0; return 0;
return *result; return *result;
@ -1059,8 +1059,8 @@ u32 ElfMemoryReader::read32(u32 address)
u32 ElfMemoryReader::read32(u32 address, bool& valid) u32 ElfMemoryReader::read32(u32 address, bool& valid)
{ {
ccc::Result<u32> result = m_elf.get_object_virtual<u32>(address); std::optional<u32> result = m_elf.get_object_virtual<u32>(address);
valid = result.success(); valid = result.has_value();
if (!valid) if (!valid)
return 0; return 0;
@ -1069,8 +1069,8 @@ u32 ElfMemoryReader::read32(u32 address, bool& valid)
u64 ElfMemoryReader::read64(u32 address) u64 ElfMemoryReader::read64(u32 address)
{ {
ccc::Result<u64> result = m_elf.get_object_virtual<u64>(address); std::optional<u64> result = m_elf.get_object_virtual<u64>(address);
if (!result.success()) if (!result.has_value())
return 0; return 0;
return *result; return *result;
@ -1078,8 +1078,8 @@ u64 ElfMemoryReader::read64(u32 address)
u64 ElfMemoryReader::read64(u32 address, bool& valid) u64 ElfMemoryReader::read64(u32 address, bool& valid)
{ {
ccc::Result<u64> result = m_elf.get_object_virtual<u64>(address); std::optional<u64> result = m_elf.get_object_virtual<u64>(address);
valid = result.success(); valid = result.has_value();
if (!valid) if (!valid)
return 0; return 0;