// Copyright 2017 Dolphin Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later #pragma once #include #include #include #include #include #include "Common/CommonTypes.h" class PPCSymbolDB; namespace Core { class CPUThreadGuard; } struct RSOEntry { u32 next_entry; u32 prev_entry; u32 section_count; u32 section_table_offset; u32 name_offset; u32 name_size; u32 version; u32 bss_size; }; struct RSOSectionInfo { u8 prolog_section_index; u8 epilog_section_index; u8 unresolved_section_index; u8 bss_section_index; u32 prolog_offset; u32 epilog_offset; u32 unresolved_offset; }; struct RSORelocationTables { u32 internals_offset; u32 internals_size; u32 externals_offset; u32 externals_size; }; struct RSOSymbolTables { u32 exports_offset; u32 exports_size; u32 exports_name_table; u32 imports_offset; u32 imports_size; u32 imports_name_table; }; struct RSOHeader { RSOEntry entry; RSOSectionInfo section_info; RSORelocationTables relocation_tables; RSOSymbolTables symbol_tables; }; struct RSOSection { u32 offset; u32 size; }; struct RSOImport { u32 name_offset; u32 code_offset; u32 entry_offset; }; struct RSOExport { u32 name_offset; u32 code_offset; u32 section_index; u32 hash; }; enum class RSORelocationTableType { Internals, Externals }; template struct RSORelocationTableEntry { u32 r_offset; u32 r_info; u32 r_addend; }; using RSOInternalsEntry = RSORelocationTableEntry; using RSOExternalsEntry = RSORelocationTableEntry; class RSOHeaderView { public: void Load(const Core::CPUThreadGuard& guard, u32 address); u32 GetNextEntry() const; u32 GetPrevEntry() const; u32 GetSectionCount() const; u32 GetSectionTableOffset() const; const std::string& GetName() const; u32 GetVersion() const; u32 GetBssSectionSize() const; u32 GetPrologSectionIndex() const; u32 GetEpilogSectionIndex() const; u32 GetUnresolvedSectionIndex() const; u32 GetBssSectionIndex() const; u32 GetPrologSectionOffset() const; u32 GetEpilogSectionOffset() const; u32 GetUnresolvedSectionOffset() const; u32 GetInternalsOffset() const; u32 GetInternalsSize() const; u32 GetExternalsOffset() const; u32 GetExternalsSize() const; u32 GetExportsOffset() const; u32 GetExportsSize() const; u32 GetExportsNameTable() const; u32 GetImportsOffset() const; u32 GetImportsSize() const; u32 GetImportsNameTable() const; private: RSOHeader m_header{}; std::string m_name; u32 m_address = 0; }; class RSOSectionsView { public: void Load(const Core::CPUThreadGuard& guard, u32 address, std::size_t count = 1); std::size_t Count() const; const RSOSection& GetSection(std::size_t index) const; const std::vector& GetSections() const; private: std::vector m_sections; u32 m_address = 0; }; class RSOImportsView { public: void Load(const Core::CPUThreadGuard& guard, u32 address, std::size_t count = 1); std::size_t Count() const; const RSOImport& GetImport(std::size_t index) const; const std::vector& GetImports() const; private: std::vector m_imports; u32 m_address = 0; }; class RSOExportsView { public: void Load(const Core::CPUThreadGuard& guard, u32 address, std::size_t count = 1); std::size_t Count() const; const RSOExport& GetExport(std::size_t index) const; const std::vector& GetExports() const; private: std::vector m_exports; u32 m_address = 0; }; class RSOInternalsView { public: void Load(const Core::CPUThreadGuard& guard, u32 address, std::size_t count = 1); std::size_t Count() const; const RSOInternalsEntry& GetEntry(std::size_t index) const; const std::vector& GetEntries() const; private: std::vector m_entries; u32 m_address = 0; }; class RSOExternalsView { public: void Load(const Core::CPUThreadGuard& guard, u32 address, std::size_t count = 1); std::size_t Count() const; const RSOExternalsEntry& GetEntry(std::size_t index) const; const std::vector& GetEntries() const; private: std::vector m_entries; u32 m_address = 0; }; class RSOView { public: void LoadHeader(const Core::CPUThreadGuard& guard, u32 address); void LoadSections(const Core::CPUThreadGuard& guard); void LoadImports(const Core::CPUThreadGuard& guard); void LoadExports(const Core::CPUThreadGuard& guard); void LoadInternals(const Core::CPUThreadGuard& guard); void LoadExternals(const Core::CPUThreadGuard& guard); void LoadAll(const Core::CPUThreadGuard& guard, u32 address); void Apply(const Core::CPUThreadGuard& guard, PPCSymbolDB* symbol_db) const; u32 GetNextEntry() const; u32 GetPrevEntry() const; u32 GetVersion() const; u32 GetAddress() const; std::size_t GetSectionCount() const; const RSOSection& GetSection(std::size_t index) const; const std::vector& GetSections() const; std::size_t GetImportsCount() const; const RSOImport& GetImport(std::size_t index) const; std::string GetImportName(const Core::CPUThreadGuard& guard, const RSOImport& rso_import) const; const std::vector& GetImports() const; std::size_t GetExportsCount() const; const RSOExport& GetExport(std::size_t index) const; std::string GetExportName(const Core::CPUThreadGuard& guard, const RSOExport& rso_export) const; u32 GetExportAddress(const RSOExport& rso_export) const; const std::vector& GetExports() const; std::size_t GetInternalsCount() const; const RSOInternalsEntry& GetInternalsEntry(std::size_t index) const; const std::vector& GetInternals() const; std::size_t GetExternalsCount() const; const RSOExternalsEntry& GetExternalsEntry(std::size_t index) const; const std::vector& GetExternals() const; const std::string& GetName() const; std::string GetName(const Core::CPUThreadGuard& guard, const RSOImport& rso_import) const; std::string GetName(const Core::CPUThreadGuard& guard, const RSOExport& rso_export) const; u32 GetProlog() const; u32 GetEpilog() const; u32 GetUnresolved() const; private: RSOHeaderView m_header; RSOSectionsView m_sections; RSOImportsView m_imports; RSOExportsView m_exports; RSOInternalsView m_internals; RSOExternalsView m_externals; u32 m_address = 0; }; class RSOChainView { public: bool Load(const Core::CPUThreadGuard& guard, u32 address); void Apply(const Core::CPUThreadGuard& guard, PPCSymbolDB* symbol_db) const; void Clear(); const std::list& GetChain() const; private: bool LoadNextChain(const Core::CPUThreadGuard& guard, const RSOView& view); bool LoadPrevChain(const Core::CPUThreadGuard& guard, const RSOView& view); std::list m_chain; };