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] 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