/** ****************************************************************************** * Xenia : Xbox 360 Emulator Research Project * ****************************************************************************** * Copyright 2013 Ben Vanik. All rights reserved. * * Released under the BSD license - see LICENSE in the root for more details. * ****************************************************************************** */ #ifndef XENIA_CPU_SDB_H_ #define XENIA_CPU_SDB_H_ #include <xenia/core.h> #include <list> #include <map> #include <vector> #include <xenia/kernel/export.h> #include <xenia/kernel/user_module.h> namespace xe { namespace cpu { namespace sdb { class FunctionSymbol; class VariableSymbol; class FunctionCall { public: uint32_t address; FunctionSymbol* source; FunctionSymbol* target; }; class VariableAccess { public: uint32_t address; FunctionSymbol* source; VariableSymbol* target; }; class Symbol { public: enum SymbolType { Function = 0, Variable = 1, ExceptionEntry = 2, }; virtual ~Symbol() {} SymbolType symbol_type; protected: Symbol(SymbolType type) : symbol_type(type) {} }; class ExceptionEntrySymbol; class FunctionBlock { public: enum TargetType { kTargetUnknown = 0, kTargetBlock = 1, kTargetFunction = 2, kTargetLR = 3, kTargetCTR = 4, kTargetNone = 5, }; FunctionBlock(); uint32_t start_address; uint32_t end_address; vector<FunctionBlock*> incoming_blocks; TargetType outgoing_type; uint32_t outgoing_address; union { FunctionSymbol* outgoing_function; FunctionBlock* outgoing_block; }; }; class FunctionSymbol : public Symbol { public: enum FunctionType { Unknown = 0, Kernel = 1, User = 2, }; enum Flags { kFlagSaveGprLr = 1 << 1, kFlagRestGprLr = 1 << 2, }; FunctionSymbol(); virtual ~FunctionSymbol(); FunctionBlock* GetBlock(uint32_t address); FunctionBlock* SplitBlock(uint32_t address); uint32_t start_address; uint32_t end_address; char* name; FunctionType type; uint32_t flags; kernel::KernelExport* kernel_export; ExceptionEntrySymbol* ee; vector<FunctionCall*> incoming_calls; vector<FunctionCall*> outgoing_calls; vector<VariableAccess*> variable_accesses; map<uint32_t, FunctionBlock*> blocks; }; class VariableSymbol : public Symbol { public: VariableSymbol(); virtual ~VariableSymbol(); uint32_t address; char* name; }; class ExceptionEntrySymbol : public Symbol { public: ExceptionEntrySymbol(); virtual ~ExceptionEntrySymbol() {} uint32_t address; FunctionSymbol* function; }; class SymbolDatabase { public: SymbolDatabase(xe_memory_ref memory, kernel::ExportResolver* export_resolver); virtual ~SymbolDatabase(); virtual int Analyze(); ExceptionEntrySymbol* GetOrInsertExceptionEntry(uint32_t address); FunctionSymbol* GetOrInsertFunction(uint32_t address); VariableSymbol* GetOrInsertVariable(uint32_t address); FunctionSymbol* GetFunction(uint32_t address); VariableSymbol* GetVariable(uint32_t address); Symbol* GetSymbol(uint32_t address); int GetAllFunctions(vector<FunctionSymbol*>& functions); void Write(const char* file_name); void Dump(); void DumpFunctionBlocks(FunctionSymbol* fn); protected: typedef std::map<uint32_t, Symbol*> SymbolMap; typedef std::list<FunctionSymbol*> FunctionList; int AnalyzeFunction(FunctionSymbol* fn); int CompleteFunctionGraph(FunctionSymbol* fn); bool FillHoles(); int FlushQueue(); bool IsRestGprLr(uint32_t addr); virtual uint32_t GetEntryPoint() = 0; virtual bool IsValueInTextRange(uint32_t value) = 0; xe_memory_ref memory_; kernel::ExportResolver* export_resolver_; size_t function_count_; size_t variable_count_; SymbolMap symbols_; FunctionList scan_queue_; }; class RawSymbolDatabase : public SymbolDatabase { public: RawSymbolDatabase(xe_memory_ref memory, kernel::ExportResolver* export_resolver, uint32_t start_address, uint32_t end_address); virtual ~RawSymbolDatabase(); private: virtual uint32_t GetEntryPoint(); virtual bool IsValueInTextRange(uint32_t value); uint32_t start_address_; uint32_t end_address_; }; class XexSymbolDatabase : public SymbolDatabase { public: XexSymbolDatabase(xe_memory_ref memory, kernel::ExportResolver* export_resolver, kernel::UserModule* module); virtual ~XexSymbolDatabase(); virtual int Analyze(); private: int FindGplr(); int AddImports(const xe_xex2_import_library_t *library); int AddMethodHints(); virtual uint32_t GetEntryPoint(); virtual bool IsValueInTextRange(uint32_t value); kernel::UserModule* module_; }; } // namespace sdb } // namespace cpu } // namespace xe #endif // XENIA_CPU_SDB_H_