Add ppu_module::get_ref() to ease debugging

This commit is contained in:
Eladash 2023-07-22 12:03:45 +03:00 committed by Elad Ashkenazi
parent 9fc5f6271b
commit 99671b754f
2 changed files with 40 additions and 6 deletions

View file

@ -78,7 +78,7 @@ void ppu_module::validate(u32 reloc)
if (size && size != funcs[index].size) if (size && size != funcs[index].size)
{ {
if (size + 4 != funcs[index].size || *ensure(get_ptr<u32>(addr + size)) != ppu_instructions::NOP()) if (size + 4 != funcs[index].size || get_ref<u32>(addr + size) != ppu_instructions::NOP())
{ {
ppu_validator.error("%s.yml : function size mismatch at 0x%x(size=0x%x) (0x%x, 0x%x)", path, found, funcs[index].size, addr, size); ppu_validator.error("%s.yml : function size mismatch at 0x%x(size=0x%x) (0x%x, 0x%x)", path, found, funcs[index].size, addr, size);
} }
@ -733,7 +733,7 @@ bool ppu_module::analyse(u32 lib_toc, u32 entry, const u32 sec_end, const std::b
// Register TOC from entry point // Register TOC from entry point
if (entry && !lib_toc) if (entry && !lib_toc)
{ {
lib_toc = *ensure(get_ptr<u32>(entry)) ? *ensure(get_ptr<u32>(entry + 4)) : *ensure(get_ptr<u32>(entry + 20)); lib_toc = get_ref<u32>(entry) ? get_ref<u32>(entry + 4) : get_ref<u32>(entry + 20);
} }
// Secondary attempt // Secondary attempt
@ -1425,7 +1425,7 @@ bool ppu_module::analyse(u32 lib_toc, u32 entry, const u32 sec_end, const std::b
for (vm::cptr<u32> _ptr = vm::cast(block.first); _ptr.addr() < block.first + block.second;) for (vm::cptr<u32> _ptr = vm::cast(block.first); _ptr.addr() < block.first + block.second;)
{ {
const u32 iaddr = _ptr.addr(); const u32 iaddr = _ptr.addr();
const ppu_opcode_t op{*ensure(get_ptr<u32>(_ptr++))}; const ppu_opcode_t op{get_ref<u32>(_ptr++)};
const ppu_itype::type type = s_ppu_itype.decode(op.opcode); const ppu_itype::type type = s_ppu_itype.decode(op.opcode);
if (type == ppu_itype::B || type == ppu_itype::BC) if (type == ppu_itype::B || type == ppu_itype::BC)
@ -1499,7 +1499,7 @@ bool ppu_module::analyse(u32 lib_toc, u32 entry, const u32 sec_end, const std::b
for (vm::cptr<u32> _ptr = vm::cast(start); _ptr.addr() < next;) for (vm::cptr<u32> _ptr = vm::cast(start); _ptr.addr() < next;)
{ {
const u32 addr = _ptr.addr(); const u32 addr = _ptr.addr();
const ppu_opcode_t op{*ensure(get_ptr<u32>(_ptr++))}; const ppu_opcode_t op{get_ref<u32>(_ptr++)};
const ppu_itype::type type = s_ppu_itype.decode(op.opcode); const ppu_itype::type type = s_ppu_itype.decode(op.opcode);
if (type == ppu_itype::UNK) if (type == ppu_itype::UNK)
@ -1641,7 +1641,7 @@ bool ppu_module::analyse(u32 lib_toc, u32 entry, const u32 sec_end, const std::b
continue; continue;
} }
const u32 target = *ensure(get_ptr<u32>(rel.addr)); const u32 target = get_ref<u32>(rel.addr);
if (target % 4 || target < start || target >= end) if (target % 4 || target < start || target >= end)
{ {
@ -1718,7 +1718,7 @@ bool ppu_module::analyse(u32 lib_toc, u32 entry, const u32 sec_end, const std::b
for (; i_pos < lim; i_pos += 4) for (; i_pos < lim; i_pos += 4)
{ {
const u32 opc = *ensure(get_ptr<u32>(i_pos)); const u32 opc = get_ref<u32>(i_pos);
switch (auto type = s_ppu_itype.decode(opc)) switch (auto type = s_ppu_itype.decode(opc))
{ {

View file

@ -148,6 +148,40 @@ struct ppu_module
constexpr usz size_element = std::is_void_v<T> ? 0 : sizeof(std::conditional_t<std::is_void_v<T>, char, T>); constexpr usz size_element = std::is_void_v<T> ? 0 : sizeof(std::conditional_t<std::is_void_v<T>, char, T>);
return get_ptr<T>(addr.addr(), u32{size_element}); return get_ptr<T>(addr.addr(), u32{size_element});
} }
template <typename T>
to_be_t<T>& get_ref(u32 addr,
u32 line = __builtin_LINE(),
u32 col = __builtin_COLUMN(),
const char* file = __builtin_FILE(),
const char* func = __builtin_FUNCTION()) const
{
constexpr usz size_element = std::is_void_v<T> ? 0 : sizeof(std::conditional_t<std::is_void_v<T>, char, T>);
if (auto ptr = get_ptr<T>(addr, u32{size_element}))
{
return *ptr;
}
fmt::throw_exception("get_ref(): Failure! (addr=0x%x)%s", addr, src_loc{line, col, file, func});
return *std::add_pointer_t<to_be_t<T>>{};
}
template <typename T, typename U> requires requires (const U& obj) { +obj.size() * 0; }
to_be_t<T>& get_ref(U&& addr,
u32 line = __builtin_LINE(),
u32 col = __builtin_COLUMN(),
const char* file = __builtin_FILE(),
const char* func = __builtin_FUNCTION()) const
{
constexpr usz size_element = std::is_void_v<T> ? 0 : sizeof(std::conditional_t<std::is_void_v<T>, char, T>);
if (auto ptr = get_ptr<T>(addr.addr(), u32{size_element}))
{
return *ptr;
}
fmt::throw_exception("get_ref(): Failure! (addr=0x%x)%s", addr.addr(), src_loc{line, col, file, func});
return *std::add_pointer_t<to_be_t<T>>{};
}
}; };
struct main_ppu_module : public ppu_module struct main_ppu_module : public ppu_module