Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add more symbol accessor functions, clean up mdebug format structs #178

Merged
merged 2 commits into from
Feb 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 11 additions & 6 deletions src/ccc/mdebug_section.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@

namespace ccc::mdebug {

// MIPS debug symbol table headers.
// See include/coff/sym.h from GNU binutils for more information.

CCC_PACKED_STRUCT(SymbolicHeader,
/* 0x00 */ s16 magic;
/* 0x02 */ s16 version_stamp;
Expand Down Expand Up @@ -54,7 +57,7 @@ CCC_PACKED_STRUCT(FileDescriptor,
/* 0x3c */ u32 f_merge : 1;
/* 0x3c */ u32 f_readin : 1;
/* 0x3c */ u32 f_big_endian : 1;
/* 0x4c */ u32 reserved_1 : 22;
/* 0x3c */ u32 reserved_1 : 22;
/* 0x40 */ s32 cb_line_offset;
/* 0x44 */ s32 cb_line;
)
Expand All @@ -74,16 +77,17 @@ CCC_PACKED_STRUCT(ProcedureDescriptor,
/* 0x26 */ s16 pcreg;
/* 0x28 */ s32 ln_low;
/* 0x2c */ s32 ln_high;
/* 0x30 */ s32 cb_line_offset;
/* 0x30 */ u32 cb_line_offset;
)
static_assert(sizeof(ProcedureDescriptor) == 0x34);

CCC_PACKED_STRUCT(SymbolHeader,
/* 0x0 */ u32 iss;
/* 0x4 */ u32 value;
/* 0x8:00 */ u32 st : 6;
/* 0x8:06 */ u32 sc : 5;
/* 0x8:11 */ u32 reserved : 1;
/* 0x8:12 */ u32 index : 20;
/* 0x8 */ u32 st : 6;
/* 0x8 */ u32 sc : 5;
/* 0x8 */ u32 reserved : 1;
/* 0x8 */ u32 index : 20;
)
static_assert(sizeof(SymbolHeader) == 0xc);

Expand All @@ -92,6 +96,7 @@ CCC_PACKED_STRUCT(ExternalSymbolHeader,
/* 0x2 */ s16 ifd;
/* 0x4 */ SymbolHeader symbol;
)
static_assert(sizeof(ExternalSymbolHeader) == 0x10);

static void print_symbol(FILE* out, const Symbol& symbol);
static Result<s32> get_corruption_fixing_fudge_offset(s32 section_offset, const SymbolicHeader& hdrr);
Expand Down
107 changes: 83 additions & 24 deletions src/ccc/symbol_database.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,17 @@ typename SymbolList<SymbolType>::NameToHandleMapIterators SymbolList<SymbolType>
return {iterators.first, iterators.second};
}

template <typename SymbolType>
SymbolHandle<SymbolType> SymbolList<SymbolType>::first_handle_after_address(Address address) const
{
auto iterator = m_address_to_handle.upper_bound(address.value);
if(iterator != m_address_to_handle.end()) {
return iterator->second;
} else {
return SymbolHandle<SymbolType>();
}
}

template <typename SymbolType>
SymbolHandle<SymbolType> SymbolList<SymbolType>::first_handle_from_name(const std::string& name) const
{
Expand Down Expand Up @@ -725,51 +736,78 @@ s32 SymbolDatabase::symbol_count() const
return sum;
}

const Symbol* SymbolDatabase::first_symbol_from_starting_address(Address address) const
const Symbol* SymbolDatabase::first_symbol_starting_at_address(
Address address, u32 descriptors, SymbolDescriptor* descriptor_out) const
{
#define CCC_X(SymbolType, symbol_list) \
if constexpr(SymbolType::FLAGS & WITH_ADDRESS_MAP) { \
const SymbolHandle<SymbolType> handle = symbol_list.first_handle_from_starting_address(address); \
const SymbolType* symbol = symbol_list.symbol_from_handle(handle); \
if(symbol) { \
return symbol; \
if(descriptors & SymbolType::DESCRIPTOR) { \
const SymbolHandle<SymbolType> handle = symbol_list.first_handle_from_starting_address(address); \
const SymbolType* symbol = symbol_list.symbol_from_handle(handle); \
if(symbol) { \
if(descriptor_out) { \
*descriptor_out = SymbolType::DESCRIPTOR; \
} \
return symbol; \
} \
} \
}
CCC_FOR_EACH_SYMBOL_TYPE_DO_X
#undef CCC_X
return nullptr;
}

Result<SymbolSourceHandle> SymbolDatabase::get_symbol_source(const std::string& name)
{
SymbolSourceHandle handle = symbol_sources.first_handle_from_name(name);
if(!handle.valid()) {
Result<SymbolSource*> source = symbol_sources.create_symbol(name, SymbolSourceHandle(), nullptr);
CCC_RETURN_IF_ERROR(source);
handle = (*source)->handle();
}
return handle;
}

void SymbolDatabase::clear()
const Symbol* SymbolDatabase::first_symbol_after_address(
Address address, u32 descriptors, SymbolDescriptor* descriptor_out) const
{
#define CCC_X(SymbolType, symbol_list) symbol_list.clear();
const Symbol* result = nullptr;
#define CCC_X(SymbolType, symbol_list) \
if constexpr(SymbolType::FLAGS & WITH_ADDRESS_MAP) { \
if(descriptors & SymbolType::DESCRIPTOR) { \
const SymbolHandle<SymbolType> handle = symbol_list.first_handle_after_address(address); \
const SymbolType* symbol = symbol_list.symbol_from_handle(handle); \
if(symbol && (!result || symbol->address() < result->address())) { \
if(descriptor_out) { \
*descriptor_out = SymbolType::DESCRIPTOR; \
} \
result = symbol; \
} \
} \
}
CCC_FOR_EACH_SYMBOL_TYPE_DO_X
#undef CCC_X
return result;
}

void SymbolDatabase::destroy_symbols_from_sources(SymbolSourceRange source_range)
const Symbol* SymbolDatabase::first_symbol_overlapping_address(
Address address, u32 descriptors, SymbolDescriptor* descriptor_out) const
{
#define CCC_X(SymbolType, symbol_list) symbol_list.destroy_symbols_from_sources(source_range);
#define CCC_X(SymbolType, symbol_list) \
if constexpr(SymbolType::FLAGS & WITH_ADDRESS_MAP) { \
if(descriptors & SymbolType::DESCRIPTOR) { \
const SymbolType* symbol = symbol_list.symbol_overlapping_address(address); \
if(symbol) { \
if(descriptor_out) { \
*descriptor_out = SymbolType::DESCRIPTOR; \
} \
return symbol; \
} \
} \
}
CCC_FOR_EACH_SYMBOL_TYPE_DO_X
#undef CCC_X
return nullptr;
}

void SymbolDatabase::destroy_symbols_from_modules(ModuleRange module_range)
Result<SymbolSourceHandle> SymbolDatabase::get_symbol_source(const std::string& name)
{
#define CCC_X(SymbolType, symbol_list) symbol_list.destroy_symbols_from_modules(module_range);
CCC_FOR_EACH_SYMBOL_TYPE_DO_X
#undef CCC_X
SymbolSourceHandle handle = symbol_sources.first_handle_from_name(name);
if(!handle.valid()) {
Result<SymbolSource*> source = symbol_sources.create_symbol(name, SymbolSourceHandle(), nullptr);
CCC_RETURN_IF_ERROR(source);
handle = (*source)->handle();
}
return handle;
}

Result<DataType*> SymbolDatabase::create_data_type_if_unique(
Expand Down Expand Up @@ -855,6 +893,20 @@ Result<DataType*> SymbolDatabase::create_data_type_if_unique(
return nullptr;
}

void SymbolDatabase::destroy_symbols_from_sources(SymbolSourceRange source_range)
{
#define CCC_X(SymbolType, symbol_list) symbol_list.destroy_symbols_from_sources(source_range);
CCC_FOR_EACH_SYMBOL_TYPE_DO_X
#undef CCC_X
}

void SymbolDatabase::destroy_symbols_from_modules(ModuleRange module_range)
{
#define CCC_X(SymbolType, symbol_list) symbol_list.destroy_symbols_from_modules(module_range);
CCC_FOR_EACH_SYMBOL_TYPE_DO_X
#undef CCC_X
}

bool SymbolDatabase::destroy_function(FunctionHandle handle)
{
Function* function = functions.symbol_from_handle(handle);
Expand All @@ -874,6 +926,13 @@ bool SymbolDatabase::destroy_function(FunctionHandle handle)
return functions.destroy_symbol(handle);
}

void SymbolDatabase::clear()
{
#define CCC_X(SymbolType, symbol_list) symbol_list.clear();
CCC_FOR_EACH_SYMBOL_TYPE_DO_X
#undef CCC_X
}

// *****************************************************************************

MultiSymbolHandle::MultiSymbolHandle() {}
Expand Down
Loading
Loading