Fixing a bunch of valgrind errors and reworking globals.
This commit is contained in:
@@ -45,9 +45,16 @@ ModuleGenerator::ModuleGenerator(
|
||||
sdb_ = sdb;
|
||||
context_ = context;
|
||||
gen_module_ = gen_module;
|
||||
di_builder_ = NULL;
|
||||
}
|
||||
|
||||
ModuleGenerator::~ModuleGenerator() {
|
||||
for (std::map<uint32_t, CodegenFunction*>::iterator it =
|
||||
functions_.begin(); it != functions_.end(); ++it) {
|
||||
delete it->second;
|
||||
}
|
||||
|
||||
delete di_builder_;
|
||||
xe_memory_release(memory_);
|
||||
}
|
||||
|
||||
@@ -59,7 +66,7 @@ int ModuleGenerator::Generate() {
|
||||
// fine grained than this, but for now it's something.
|
||||
xechar_t dir[2048];
|
||||
XEIGNORE(xestrcpy(dir, XECOUNT(dir), module_->path()));
|
||||
xechar_t *slash = xestrrchr(dir, '/');
|
||||
xechar_t* slash = xestrrchr(dir, '/');
|
||||
if (slash) {
|
||||
*(slash + 1) = 0;
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
#include <llvm/Bitcode/ReaderWriter.h>
|
||||
#include <llvm/ExecutionEngine/GenericValue.h>
|
||||
#include <llvm/ExecutionEngine/ExecutionEngine.h>
|
||||
#include <llvm/IR/Constants.h>
|
||||
#include <llvm/IR/DataLayout.h>
|
||||
#include <llvm/IR/DerivedTypes.h>
|
||||
#include <llvm/IR/LLVMContext.h>
|
||||
@@ -108,6 +109,11 @@ int ExecModule::Prepare() {
|
||||
new Module(module_->name(), *context_.get()));
|
||||
// TODO(benavnik): addModuleFlag?
|
||||
|
||||
// Inject globals.
|
||||
// This should be done ASAP to ensure that JITed functions can use the
|
||||
// constant addresses.
|
||||
XEEXPECTZERO(InjectGlobals());
|
||||
|
||||
// Link shared module into generated module.
|
||||
// This gives us a single module that we can optimize and prevents the need
|
||||
// for foreward declarations.
|
||||
@@ -165,19 +171,41 @@ XECLEANUP:
|
||||
return result_code;
|
||||
}
|
||||
|
||||
int ExecModule::InjectGlobals() {
|
||||
LLVMContext& context = *context_.get();
|
||||
const DataLayout* dl = engine_->getDataLayout();
|
||||
Type* voidPtrTy = PointerType::getUnqual(Type::getVoidTy(context));
|
||||
Type* intPtrTy = dl->getIntPtrType(context);
|
||||
GlobalVariable* gv;
|
||||
|
||||
// xe_memory_base
|
||||
// This is the base void* pointer to the memory space.
|
||||
gv = new GlobalVariable(
|
||||
*gen_module_,
|
||||
voidPtrTy,
|
||||
true,
|
||||
GlobalValue::ExternalLinkage,
|
||||
0,
|
||||
"xe_memory_base");
|
||||
// Align to 64b - this makes SSE faster.
|
||||
gv->setAlignment(64);
|
||||
gv->setInitializer(ConstantExpr::getIntToPtr(
|
||||
ConstantInt::get(intPtrTy, (uintptr_t)xe_memory_addr(memory_, 0)),
|
||||
voidPtrTy));
|
||||
|
||||
// xe_ppc_state
|
||||
// ...
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ExecModule::Init() {
|
||||
// Run static initializers. I'm not sure we'll have any, but who knows.
|
||||
engine_->runStaticConstructorsDestructors(gen_module_.get(), false);
|
||||
|
||||
// Prepare init options.
|
||||
xe_module_init_options_t init_options;
|
||||
xe_zero_struct(&init_options, sizeof(init_options));
|
||||
init_options.memory_base = xe_memory_addr(memory_, 0);
|
||||
|
||||
// Grab the init function and call it.
|
||||
Function* xe_module_init = gen_module_->getFunction("xe_module_init");
|
||||
std::vector<GenericValue> args;
|
||||
args.push_back(GenericValue(&init_options));
|
||||
GenericValue ret = engine_->runFunction(xe_module_init, args);
|
||||
|
||||
return ret.IntVal.getSExtValue();
|
||||
|
||||
@@ -71,8 +71,8 @@ int Processor::Setup() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
LLVMContext* dummy_context = new LLVMContext();
|
||||
Module* dummy_module = new Module("dummy", *dummy_context);
|
||||
dummy_context_ = auto_ptr<LLVMContext>(new LLVMContext());
|
||||
Module* dummy_module = new Module("dummy", *dummy_context_.get());
|
||||
|
||||
std::string error_message;
|
||||
engine_ = shared_ptr<ExecutionEngine>(
|
||||
|
||||
@@ -22,6 +22,19 @@ using namespace xe::cpu::sdb;
|
||||
using namespace xe::kernel;
|
||||
|
||||
|
||||
FunctionBlock::FunctionBlock() :
|
||||
start_address(0), end_address(0),
|
||||
outgoing_type(kTargetUnknown), outgoing_address(0),
|
||||
outgoing_function(0) {
|
||||
}
|
||||
|
||||
FunctionSymbol::FunctionSymbol() :
|
||||
Symbol(Function),
|
||||
start_address(0), end_address(0), name(0),
|
||||
type(Unknown), flags(0),
|
||||
kernel_export(0), ee(0) {
|
||||
}
|
||||
|
||||
FunctionSymbol::~FunctionSymbol() {
|
||||
delete name;
|
||||
for (std::map<uint32_t, FunctionBlock*>::iterator it = blocks.begin();
|
||||
@@ -68,10 +81,20 @@ FunctionBlock* FunctionSymbol::SplitBlock(uint32_t address) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
VariableSymbol::VariableSymbol() :
|
||||
Symbol(Variable),
|
||||
address(0), name(0) {
|
||||
}
|
||||
|
||||
VariableSymbol::~VariableSymbol() {
|
||||
delete name;
|
||||
}
|
||||
|
||||
ExceptionEntrySymbol::ExceptionEntrySymbol() :
|
||||
Symbol(ExceptionEntry),
|
||||
address(0), function(0) {
|
||||
}
|
||||
|
||||
SymbolDatabase::SymbolDatabase(
|
||||
xe_memory_ref memory, ExportResolver* export_resolver, UserModule* module) {
|
||||
memory_ = xe_memory_retain(memory);
|
||||
@@ -419,6 +442,7 @@ int SymbolDatabase::AddImports(const xe_xex2_import_library_t* library) {
|
||||
}
|
||||
}
|
||||
|
||||
xe_free(import_infos);
|
||||
xe_xex2_release(xex);
|
||||
return 0;
|
||||
}
|
||||
@@ -438,6 +462,7 @@ int SymbolDatabase::AddMethodHints() {
|
||||
// TODO(benvanik): something with prolog_length?
|
||||
}
|
||||
|
||||
xe_free(method_infos);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
Binary file not shown.
@@ -21,15 +21,16 @@
|
||||
|
||||
// NOTE: only headers in this directory should be included.
|
||||
#include "xethunk.h"
|
||||
#include <xenia/cpu/ppc/state.h>
|
||||
|
||||
|
||||
// The base pointer that all guest addresses should be relative to.
|
||||
static void* xe_memory_base;
|
||||
// Global CPU state.
|
||||
// Instructions that dereference the state use this.
|
||||
// TODO(benvanik): noalias/invariant/etc?s
|
||||
static xe_ppc_state_t* xe_ppc_state;
|
||||
|
||||
|
||||
int xe_module_init(xe_module_init_options_t *options) {
|
||||
xe_memory_base = options->memory_base;
|
||||
|
||||
int xe_module_init() {
|
||||
// TODO(benvanik): setup call table, etc?
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -17,11 +17,4 @@
|
||||
#define XENIA_CPU_XELIB_H_
|
||||
|
||||
|
||||
typedef struct {
|
||||
void* memory_base;
|
||||
|
||||
// TODO(benvanik): execute call thunk
|
||||
} xe_module_init_options_t;
|
||||
|
||||
|
||||
#endif // XENIA_CPU_XELIB_H_
|
||||
|
||||
@@ -2,17 +2,7 @@
|
||||
target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
|
||||
target triple = "x86_64-apple-macosx10.8.0"
|
||||
|
||||
%struct.xe_module_init_options_t = type { i8* }
|
||||
|
||||
@xe_memory_base = internal global i8* null, align 8
|
||||
|
||||
define i32 @xe_module_init(%struct.xe_module_init_options_t* %options) nounwind uwtable ssp {
|
||||
%1 = alloca %struct.xe_module_init_options_t*, align 8
|
||||
store %struct.xe_module_init_options_t* %options, %struct.xe_module_init_options_t** %1, align 8
|
||||
%2 = load %struct.xe_module_init_options_t** %1, align 8
|
||||
%3 = getelementptr inbounds %struct.xe_module_init_options_t* %2, i32 0, i32 0
|
||||
%4 = load i8** %3, align 8
|
||||
store i8* %4, i8** @xe_memory_base, align 8
|
||||
define i32 @xe_module_init() nounwind uwtable ssp {
|
||||
ret i32 0
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user