From 6c5432eb45a2d5378e350ad309103b9372909dea Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Mon, 14 Jan 2013 00:02:24 -0800 Subject: [PATCH] Symbol database skeleton. --- include/xenia/cpu.h | 2 + include/xenia/cpu/sdb.h | 81 +++++++++++++++++++++++++++++++++++++ src/cpu/cpu.cc | 7 ++++ src/cpu/sdb.cc | 88 +++++++++++++++++++++++++++++++++++++++++ src/cpu/sources.gypi | 1 + 5 files changed, 179 insertions(+) create mode 100644 include/xenia/cpu/sdb.h create mode 100644 src/cpu/sdb.cc diff --git a/include/xenia/cpu.h b/include/xenia/cpu.h index 72f598dcc..61f19be8c 100644 --- a/include/xenia/cpu.h +++ b/include/xenia/cpu.h @@ -13,6 +13,7 @@ #include #include +#include #include #include @@ -33,6 +34,7 @@ void xe_cpu_release(xe_cpu_ref cpu); xe_pal_ref xe_cpu_get_pal(xe_cpu_ref cpu); xe_memory_ref xe_cpu_get_memory(xe_cpu_ref cpu); +xe_sdb_ref xe_cpu_get_sdb(xe_cpu_ref cpu); int xe_cpu_prepare_module(xe_cpu_ref cpu, xe_module_ref module, xe_kernel_export_resolver_ref export_resolver); diff --git a/include/xenia/cpu/sdb.h b/include/xenia/cpu/sdb.h new file mode 100644 index 000000000..255f80d44 --- /dev/null +++ b/include/xenia/cpu/sdb.h @@ -0,0 +1,81 @@ +/** + ****************************************************************************** + * 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 + +#include + +#include + + +struct xe_sdb_function; +typedef struct xe_sdb_function xe_sdb_function_t; +struct xe_sdb_variable; +typedef struct xe_sdb_variable xe_sdb_variable_t; + + +typedef struct { + uint32_t address; + xe_sdb_function_t *source; + xe_sdb_function_t *target; +} xe_sdb_function_call_t; + +typedef struct { + uint32_t address; + xe_sdb_function_t *source; + xe_sdb_variable_t *target; +} xe_sdb_variable_access_t; + +typedef enum { + kXESDBFunctionUnknown = 0, + kXESDBFunctionKernel = 1, + kXESDBFunctionUser = 2, +} xe_sdb_function_type; + +struct xe_sdb_function { + uint32_t start_address; + uint32_t end_address; + char *name; + xe_sdb_function_type type; + uint32_t flags; + + std::vector incoming_calls; + std::vector outgoing_calls; + std::vector variable_accesses; +}; + +struct xe_sdb_variable { + uint32_t address; + char *name; +}; + + +struct xe_sdb; +typedef struct xe_sdb* xe_sdb_ref; + + +xe_sdb_ref xe_sdb_create(xe_memory_ref memory); +xe_sdb_ref xe_sdb_retain(xe_sdb_ref sdb); +void xe_sdb_release(xe_sdb_ref sdb); + +xe_sdb_function_t* xe_sdb_insert_function(xe_sdb_ref sdb, uint32_t address); +xe_sdb_variable_t* xe_sdb_insert_variable(xe_sdb_ref sdb, uint32_t address); + +xe_sdb_function_t* xe_sdb_get_function(xe_sdb_ref sdb, uint32_t address); +xe_sdb_variable_t* xe_sdb_get_variable(xe_sdb_ref sdb, uint32_t address); + +void xe_sdb_dump(xe_sdb_ref sdb); + +int xe_sdb_analyze_module(xe_sdb_ref sdb, xe_module_ref module); + + +#endif // XENIA_CPU_SDB_H_ diff --git a/src/cpu/cpu.cc b/src/cpu/cpu.cc index 881898be7..1378ceee7 100644 --- a/src/cpu/cpu.cc +++ b/src/cpu/cpu.cc @@ -49,6 +49,7 @@ typedef struct xe_cpu { xe_pal_ref pal; xe_memory_ref memory; + xe_sdb_ref sdb; std::vector entries; @@ -70,6 +71,7 @@ xe_cpu_ref xe_cpu_create(xe_pal_ref pal, xe_memory_ref memory, cpu->pal = xe_pal_retain(pal); cpu->memory = xe_memory_retain(memory); + cpu->sdb = xe_sdb_create(memory); LLVMLinkInInterpreter(); LLVMLinkInJIT(); @@ -97,6 +99,7 @@ void xe_cpu_dealloc(xe_cpu_ref cpu) { delete cpu->engine; llvm_shutdown(); + xe_sdb_release(cpu->sdb); xe_memory_release(cpu->memory); xe_pal_release(cpu->pal); } @@ -118,6 +121,10 @@ xe_memory_ref xe_cpu_get_memory(xe_cpu_ref cpu) { return xe_memory_retain(cpu->memory); } +xe_sdb_ref xe_cpu_get_sdb(xe_cpu_ref cpu) { + return xe_sdb_retain(cpu->sdb); +} + int xe_cpu_setup_engine(xe_cpu_ref cpu, Module *gen_module) { if (cpu->engine) { // Engine already initialized - just add the module. diff --git a/src/cpu/sdb.cc b/src/cpu/sdb.cc new file mode 100644 index 000000000..3452d2d76 --- /dev/null +++ b/src/cpu/sdb.cc @@ -0,0 +1,88 @@ +/** + ****************************************************************************** + * 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. * + ****************************************************************************** + */ + +#include + + +struct xe_sdb { + xe_ref_t ref; + + xe_memory_ref memory; +}; + + +xe_sdb_ref xe_sdb_create(xe_memory_ref memory) { + xe_sdb_ref sdb = (xe_sdb_ref)xe_calloc(sizeof(xe_sdb)); + xe_ref_init((xe_ref)sdb); + + sdb->memory = xe_memory_retain(memory); + + return sdb; +} + +void xe_sdb_dealloc(xe_sdb_ref sdb) { + xe_memory_release(sdb->memory); +} + +xe_sdb_ref xe_sdb_retain(xe_sdb_ref sdb) { + xe_ref_retain((xe_ref)sdb); + return sdb; +} + +void xe_sdb_release(xe_sdb_ref sdb) { + xe_ref_release((xe_ref)sdb, (xe_ref_dealloc_t)xe_sdb_dealloc); +} + +xe_sdb_function_t* xe_sdb_insert_function(xe_sdb_ref sdb, uint32_t address) { + return NULL; +} + +xe_sdb_variable_t* xe_sdb_insert_variable(xe_sdb_ref sdb, uint32_t address) { + return NULL; +} + +xe_sdb_function_t* xe_sdb_get_function(xe_sdb_ref sdb, uint32_t address) { + return NULL; +} + +xe_sdb_variable_t* xe_sdb_get_variable(xe_sdb_ref sdb, uint32_t address) { + return NULL; +} + +void xe_sdb_dump(xe_sdb_ref sdb) { + // TODO(benvanik): dump all functions and symbols +} + +int xe_sdb_analyze_function(xe_sdb_ref sdb, xe_sdb_function_t *fn) { + // Ignore functions already analyzed. + if (fn->type != kXESDBFunctionUnknown) { + return 0; + } + + // TODO(benvanik): analysis. + // Search forward from start address to find the end address. + // Use branch tracking to figure that out. + return 0; +} + +int xe_sdb_analyze_module(xe_sdb_ref sdb, xe_module_ref module) { + // TODO(benvanik): analysis. + // Iteratively run passes over the db: + // - for each import: + // - insert fn and setup as a thunk + // - for each export + // - insert fn or variable + // - queue fn + // - insert entry point + // - queue entry point + // - while (process_queue.length()): + // - fn = shift() + // - analyze_function(fn) + return 0; +} diff --git a/src/cpu/sources.gypi b/src/cpu/sources.gypi index 1c7d2d0e0..6b330125b 100644 --- a/src/cpu/sources.gypi +++ b/src/cpu/sources.gypi @@ -3,6 +3,7 @@ 'sources': [ 'codegen.cc', 'cpu.cc', + 'sdb.cc', ], 'includes': [