Basic function analysis.
Finds basic blocks and estimates proper function bounds. Seems legit for compiled code.
This commit is contained in:
@@ -23,6 +23,7 @@
|
||||
#define XE_OPTION_LOG_INFO 1
|
||||
#define XE_OPTION_LOG_DEBUG 1
|
||||
#define XE_OPTION_LOG_CPU 1
|
||||
#define XE_OPTION_LOG_SDB 0
|
||||
#define XE_OPTION_LOG_GPU 1
|
||||
#define XE_OPTION_LOG_KERNEL 1
|
||||
|
||||
|
||||
@@ -56,6 +56,14 @@ typedef enum {
|
||||
class InstrType;
|
||||
|
||||
|
||||
static inline int32_t XEEXTS16(uint32_t v) {
|
||||
return (int32_t)((int16_t)v);
|
||||
}
|
||||
static inline int32_t XEEXTS26(uint32_t v) {
|
||||
return v & 0x02000000 ? (int32_t)v | 0xFC000000 : (int32_t)(v);
|
||||
}
|
||||
|
||||
|
||||
typedef struct {
|
||||
InstrType* type;
|
||||
uint32_t address;
|
||||
@@ -97,6 +105,14 @@ typedef struct {
|
||||
} DS;
|
||||
// kXEPPCInstrFormatX
|
||||
// kXEPPCInstrFormatXL
|
||||
struct {
|
||||
uint32_t LK : 1;
|
||||
uint32_t : 10;
|
||||
uint32_t BB : 5;
|
||||
uint32_t BI : 5;
|
||||
uint32_t BO : 5;
|
||||
uint32_t OPCD : 6;
|
||||
} XL;
|
||||
struct {
|
||||
uint32_t : 1;
|
||||
uint32_t : 10;
|
||||
@@ -114,7 +130,7 @@ typedef struct {
|
||||
// kXEPPCInstrFormatVA
|
||||
// kXEPPCInstrFormatVX
|
||||
// kXEPPCInstrFormatVXR
|
||||
} data;
|
||||
};
|
||||
} InstrData;
|
||||
|
||||
class Instr {
|
||||
|
||||
@@ -45,8 +45,9 @@ public:
|
||||
class Symbol {
|
||||
public:
|
||||
enum SymbolType {
|
||||
Function = 0,
|
||||
Variable = 1,
|
||||
Function = 0,
|
||||
Variable = 1,
|
||||
ExceptionEntry = 2,
|
||||
};
|
||||
|
||||
virtual ~Symbol() {}
|
||||
@@ -57,6 +58,18 @@ protected:
|
||||
Symbol(SymbolType type) : symbol_type(type) {}
|
||||
};
|
||||
|
||||
class ExceptionEntrySymbol;
|
||||
|
||||
class FunctionBlock {
|
||||
public:
|
||||
uint32_t start_address;
|
||||
uint32_t end_address;
|
||||
|
||||
vector<FunctionBlock*> incoming_blocks;
|
||||
FunctionBlock* outgoing_block;
|
||||
uint32_t outgoing_address;
|
||||
};
|
||||
|
||||
class FunctionSymbol : public Symbol {
|
||||
public:
|
||||
enum FunctionType {
|
||||
@@ -64,6 +77,10 @@ public:
|
||||
Kernel = 1,
|
||||
User = 2,
|
||||
};
|
||||
enum Flags {
|
||||
kFlagSaveGprLr = 1 << 1,
|
||||
kFlagRestGprLr = 1 << 2,
|
||||
};
|
||||
|
||||
FunctionSymbol() : Symbol(Function) {}
|
||||
virtual ~FunctionSymbol() {}
|
||||
@@ -74,9 +91,13 @@ public:
|
||||
FunctionType type;
|
||||
uint32_t flags;
|
||||
|
||||
ExceptionEntrySymbol* ee;
|
||||
|
||||
vector<FunctionCall*> incoming_calls;
|
||||
vector<FunctionCall*> outgoing_calls;
|
||||
vector<VariableAccess*> variable_accesses;
|
||||
|
||||
map<uint32_t, FunctionBlock*> blocks;
|
||||
};
|
||||
|
||||
class VariableSymbol : public Symbol {
|
||||
@@ -88,6 +109,15 @@ public:
|
||||
char *name;
|
||||
};
|
||||
|
||||
class ExceptionEntrySymbol : public Symbol {
|
||||
public:
|
||||
ExceptionEntrySymbol() : Symbol(ExceptionEntry) {}
|
||||
virtual ~ExceptionEntrySymbol() {}
|
||||
|
||||
uint32_t address;
|
||||
FunctionSymbol* function;
|
||||
};
|
||||
|
||||
|
||||
class SymbolDatabase {
|
||||
public:
|
||||
@@ -96,6 +126,7 @@ public:
|
||||
|
||||
int Analyze();
|
||||
|
||||
ExceptionEntrySymbol* GetOrInsertExceptionEntry(uint32_t address);
|
||||
FunctionSymbol* GetOrInsertFunction(uint32_t address);
|
||||
VariableSymbol* GetOrInsertVariable(uint32_t address);
|
||||
FunctionSymbol* GetFunction(uint32_t address);
|
||||
@@ -105,6 +136,7 @@ public:
|
||||
int GetAllFunctions(vector<FunctionSymbol*>& functions);
|
||||
|
||||
void Dump();
|
||||
void DumpFunctionBlocks(FunctionSymbol* fn);
|
||||
|
||||
private:
|
||||
typedef std::map<uint32_t, Symbol*> SymbolMap;
|
||||
@@ -114,9 +146,12 @@ private:
|
||||
int AddImports(const xe_xex2_import_library_t *library);
|
||||
int AddMethodHints();
|
||||
int AnalyzeFunction(FunctionSymbol* fn);
|
||||
int FillHoles();
|
||||
bool FillHoles();
|
||||
int FlushQueue();
|
||||
|
||||
bool IsValueInTextRange(uint32_t value);
|
||||
bool IsRestGprLr(uint32_t addr);
|
||||
|
||||
xe_memory_ref memory_;
|
||||
kernel::UserModule* module_;
|
||||
size_t function_count_;
|
||||
|
||||
@@ -57,6 +57,11 @@ void xe_log_line(const xechar_t* file_path, const uint32_t line_number,
|
||||
#else
|
||||
#define XELOGCPU(fmt, ...) XE_EMPTY_MACRO
|
||||
#endif
|
||||
#if XE_OPTION(LOG_SDB)
|
||||
#define XELOGSDB(fmt, ...) XELOGCORE('S', fmt, ##__VA_ARGS__)
|
||||
#else
|
||||
#define XELOGSDB(fmt, ...) XE_EMPTY_MACRO
|
||||
#endif
|
||||
#if XE_OPTION(LOG_GPU)
|
||||
#define XELOGGPU(fmt, ...) XELOGCORE('G', fmt, ##__VA_ARGS__)
|
||||
#else
|
||||
|
||||
Reference in New Issue
Block a user