From 42792306bab09ab1f432d6c3f18a4f005d0dc0a2 Mon Sep 17 00:00:00 2001 From: chaoticgd <43898262+chaoticgd@users.noreply.github.com> Date: Sat, 17 Feb 2024 14:01:31 +0000 Subject: [PATCH 1/2] Clean up mdebug format structs --- src/ccc/mdebug_section.cpp | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/src/ccc/mdebug_section.cpp b/src/ccc/mdebug_section.cpp index 9724208..c9bb90d 100644 --- a/src/ccc/mdebug_section.cpp +++ b/src/ccc/mdebug_section.cpp @@ -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; @@ -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; ) @@ -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); @@ -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 get_corruption_fixing_fudge_offset(s32 section_offset, const SymbolicHeader& hdrr); From af6f16a4350c3ae52198101a1a4ae66181a92745 Mon Sep 17 00:00:00 2001 From: chaoticgd <43898262+chaoticgd@users.noreply.github.com> Date: Sat, 17 Feb 2024 16:03:12 +0000 Subject: [PATCH 2/2] Add some more symbol accessor functions --- src/ccc/symbol_database.cpp | 107 ++++++++++++++++++++++++++++-------- src/ccc/symbol_database.h | 89 +++++++++++++++++------------- 2 files changed, 134 insertions(+), 62 deletions(-) diff --git a/src/ccc/symbol_database.cpp b/src/ccc/symbol_database.cpp index 9bcb012..10d4c27 100644 --- a/src/ccc/symbol_database.cpp +++ b/src/ccc/symbol_database.cpp @@ -140,6 +140,17 @@ typename SymbolList::NameToHandleMapIterators SymbolList return {iterators.first, iterators.second}; } +template +SymbolHandle SymbolList::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(); + } +} + template SymbolHandle SymbolList::first_handle_from_name(const std::string& name) const { @@ -725,14 +736,20 @@ 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 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 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 @@ -740,36 +757,57 @@ const Symbol* SymbolDatabase::first_symbol_from_starting_address(Address address return nullptr; } -Result SymbolDatabase::get_symbol_source(const std::string& name) -{ - SymbolSourceHandle handle = symbol_sources.first_handle_from_name(name); - if(!handle.valid()) { - Result 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 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 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 source = symbol_sources.create_symbol(name, SymbolSourceHandle(), nullptr); + CCC_RETURN_IF_ERROR(source); + handle = (*source)->handle(); + } + return handle; } Result SymbolDatabase::create_data_type_if_unique( @@ -855,6 +893,20 @@ Result 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); @@ -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() {} diff --git a/src/ccc/symbol_database.h b/src/ccc/symbol_database.h index 6e8fc08..0f87380 100644 --- a/src/ccc/symbol_database.h +++ b/src/ccc/symbol_database.h @@ -24,17 +24,21 @@ namespace ccc { CCC_X(SymbolSource, symbol_sources) // An enum for all the symbol types. -enum class SymbolDescriptor { - DATA_TYPE, - FUNCTION, - GLOBAL_VARIABLE, - LABEL, - LOCAL_VARIABLE, - MODULE, - PARAMETER_VARIABLE, - SECTION, - SOURCE_FILE, - SYMBOL_SOURCE +enum SymbolDescriptor { + DATA_TYPE = 1 << 0, + FUNCTION = 1 << 1, + GLOBAL_VARIABLE = 1 << 2, + LABEL = 1 << 3, + LOCAL_VARIABLE = 1 << 4, + MODULE = 1 << 5, + PARAMETER_VARIABLE = 1 << 6, + SECTION = 1 << 7, + SOURCE_FILE = 1 << 8, + SYMBOL_SOURCE = 1 << 9 +}; + +enum { + ALL_SYMBOL_TYPES = 0xffff }; // Forward declare all the different types of symbol objects. @@ -152,9 +156,11 @@ class SymbolList { using AddressToHandleMapIterators = Iterators; using NameToHandleMapIterators = Iterators; + // Lookup symbol by their address. AddressToHandleMapIterators handles_from_starting_address(Address address) const; AddressToHandleMapIterators handles_from_address_range(AddressRange range) const; SymbolHandle first_handle_from_starting_address(Address address) const; + SymbolHandle first_handle_after_address(Address address) const; NameToHandleMapIterators handles_from_name(const std::string& name) const; SymbolHandle first_handle_from_name(const std::string& name) const; @@ -163,8 +169,10 @@ class SymbolList { SymbolType* symbol_overlapping_address(Address address); const SymbolType* symbol_overlapping_address(Address address) const; - // Convert handles to underlying array indices, for the JSON code. + // Convert handles to underlying array indices. s32 index_from_handle(SymbolHandle handle) const; + + // Index into the underlying array. SymbolType& symbol_from_index(s32 index); const SymbolType& symbol_from_index(s32 index) const; @@ -358,7 +366,7 @@ class DataType : public Symbol { friend SourceFile; friend SymbolList; public: - static constexpr const SymbolDescriptor DESCRIPTOR = SymbolDescriptor::DATA_TYPE; + static constexpr const SymbolDescriptor DESCRIPTOR = DATA_TYPE; static constexpr const char* NAME = "Data Type"; static constexpr const u32 FLAGS = WITH_NAME_MAP; @@ -378,7 +386,7 @@ class Function : public Symbol { friend void write_json(); public: - static constexpr const SymbolDescriptor DESCRIPTOR = SymbolDescriptor::FUNCTION; + static constexpr const SymbolDescriptor DESCRIPTOR = FUNCTION; static constexpr const char* NAME = "Function"; static constexpr const u32 FLAGS = WITH_ADDRESS_MAP | WITH_NAME_MAP | NAME_NEEDS_DEMANGLING; @@ -434,7 +442,7 @@ class GlobalVariable : public Symbol { friend SourceFile; friend SymbolList; public: - static constexpr const SymbolDescriptor DESCRIPTOR = SymbolDescriptor::GLOBAL_VARIABLE; + static constexpr const SymbolDescriptor DESCRIPTOR = GLOBAL_VARIABLE; static constexpr const char* NAME = "Global Variable"; static constexpr u32 FLAGS = WITH_ADDRESS_MAP | WITH_NAME_MAP | NAME_NEEDS_DEMANGLING; @@ -457,7 +465,7 @@ class GlobalVariable : public Symbol { class Label : public Symbol { friend SymbolList