Removing SET_RETURN_ADDRESS - hopefully it'll never be needed again.
This commit is contained in:
parent
8789fd4134
commit
ecf0988ddb
|
@ -104,7 +104,7 @@ void IVMFunction::OnBreakpointHit(ThreadState* thread_state, IntCode* i) {
|
||||||
|
|
||||||
#undef TRACE_SOURCE_OFFSET
|
#undef TRACE_SOURCE_OFFSET
|
||||||
|
|
||||||
int IVMFunction::CallImpl(ThreadState* thread_state, uint64_t return_address) {
|
int IVMFunction::CallImpl(ThreadState* thread_state) {
|
||||||
// Setup register file on stack.
|
// Setup register file on stack.
|
||||||
auto stack = (IVMStack*)thread_state->backend_data();
|
auto stack = (IVMStack*)thread_state->backend_data();
|
||||||
auto register_file = (Register*)stack->Alloc(register_count_);
|
auto register_file = (Register*)stack->Alloc(register_count_);
|
||||||
|
@ -120,8 +120,6 @@ int IVMFunction::CallImpl(ThreadState* thread_state, uint64_t return_address) {
|
||||||
ics.did_saturate = 0;
|
ics.did_saturate = 0;
|
||||||
ics.access_callbacks = thread_state->runtime()->access_callbacks();
|
ics.access_callbacks = thread_state->runtime()->access_callbacks();
|
||||||
ics.thread_state = thread_state;
|
ics.thread_state = thread_state;
|
||||||
ics.return_address = return_address;
|
|
||||||
ics.call_return_address = 0;
|
|
||||||
|
|
||||||
volatile int* suspend_flag_address = thread_state->suspend_flag_address();
|
volatile int* suspend_flag_address = thread_state->suspend_flag_address();
|
||||||
|
|
||||||
|
|
|
@ -31,8 +31,7 @@ public:
|
||||||
protected:
|
protected:
|
||||||
virtual int AddBreakpointImpl(runtime::Breakpoint* breakpoint);
|
virtual int AddBreakpointImpl(runtime::Breakpoint* breakpoint);
|
||||||
virtual int RemoveBreakpointImpl(runtime::Breakpoint* breakpoint);
|
virtual int RemoveBreakpointImpl(runtime::Breakpoint* breakpoint);
|
||||||
virtual int CallImpl(runtime::ThreadState* thread_state,
|
virtual int CallImpl(runtime::ThreadState* thread_state);
|
||||||
uint64_t return_address);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
IntCode* GetIntCodeAtSourceOffset(uint64_t offset);
|
IntCode* GetIntCodeAtSourceOffset(uint64_t offset);
|
||||||
|
|
|
@ -580,9 +580,7 @@ uint32_t IntCode_CALL_XX(IntCodeState& ics, const IntCode* i, uint32_t reg) {
|
||||||
ics.thread_state->runtime()->ResolveFunction(symbol_info->address(), &fn);
|
ics.thread_state->runtime()->ResolveFunction(symbol_info->address(), &fn);
|
||||||
XEASSERTNOTNULL(fn);
|
XEASSERTNOTNULL(fn);
|
||||||
// TODO(benvanik): proper tail call support, somehow.
|
// TODO(benvanik): proper tail call support, somehow.
|
||||||
uint64_t return_address =
|
fn->Call(ics.thread_state);
|
||||||
(i->flags & CALL_TAIL) ? ics.return_address : ics.call_return_address;
|
|
||||||
fn->Call(ics.thread_state, return_address);
|
|
||||||
if (i->flags & CALL_TAIL) {
|
if (i->flags & CALL_TAIL) {
|
||||||
return IA_RETURN;
|
return IA_RETURN;
|
||||||
}
|
}
|
||||||
|
@ -647,19 +645,12 @@ int Translate_CALL_TRUE(TranslationContext& ctx, Instr* i) {
|
||||||
uint32_t IntCode_CALL_INDIRECT_XX(IntCodeState& ics, const IntCode* i, uint32_t reg) {
|
uint32_t IntCode_CALL_INDIRECT_XX(IntCodeState& ics, const IntCode* i, uint32_t reg) {
|
||||||
uint64_t target = ics.rf[reg].u32;
|
uint64_t target = ics.rf[reg].u32;
|
||||||
|
|
||||||
// Check if return address - if so, return.
|
|
||||||
if (target == ics.return_address) {
|
|
||||||
return IA_RETURN;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Real call.
|
// Real call.
|
||||||
Function* fn = NULL;
|
Function* fn = NULL;
|
||||||
ics.thread_state->runtime()->ResolveFunction(target, &fn);
|
ics.thread_state->runtime()->ResolveFunction(target, &fn);
|
||||||
XEASSERTNOTNULL(fn);
|
XEASSERTNOTNULL(fn);
|
||||||
// TODO(benvanik): proper tail call support, somehow.
|
// TODO(benvanik): proper tail call support, somehow.
|
||||||
uint64_t return_address =
|
fn->Call(ics.thread_state);
|
||||||
(i->flags & CALL_TAIL) ? ics.return_address : ics.call_return_address;
|
|
||||||
fn->Call(ics.thread_state, return_address);
|
|
||||||
if (i->flags & CALL_TAIL) {
|
if (i->flags & CALL_TAIL) {
|
||||||
return IA_RETURN;
|
return IA_RETURN;
|
||||||
}
|
}
|
||||||
|
@ -777,14 +768,6 @@ int Translate_RETURN_TRUE(TranslationContext& ctx, Instr* i) {
|
||||||
return DispatchToC(ctx, i, fns[i->src1.value->type]);
|
return DispatchToC(ctx, i, fns[i->src1.value->type]);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t IntCode_SET_RETURN_ADDRESS(IntCodeState& ics, const IntCode* i) {
|
|
||||||
ics.call_return_address = ics.rf[i->src1_reg].u32;
|
|
||||||
return IA_NEXT;
|
|
||||||
}
|
|
||||||
int Translate_SET_RETURN_ADDRESS(TranslationContext& ctx, Instr* i) {
|
|
||||||
return DispatchToC(ctx, i, IntCode_SET_RETURN_ADDRESS);
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t IntCode_BRANCH_XX(IntCodeState& ics, const IntCode* i, uint32_t reg) {
|
uint32_t IntCode_BRANCH_XX(IntCodeState& ics, const IntCode* i, uint32_t reg) {
|
||||||
return ics.rf[reg].u32;
|
return ics.rf[reg].u32;
|
||||||
}
|
}
|
||||||
|
@ -4028,7 +4011,6 @@ static const TranslateFn dispatch_table[] = {
|
||||||
Translate_CALL_INDIRECT_TRUE,
|
Translate_CALL_INDIRECT_TRUE,
|
||||||
Translate_RETURN,
|
Translate_RETURN,
|
||||||
Translate_RETURN_TRUE,
|
Translate_RETURN_TRUE,
|
||||||
Translate_SET_RETURN_ADDRESS,
|
|
||||||
|
|
||||||
Translate_BRANCH,
|
Translate_BRANCH,
|
||||||
Translate_BRANCH_TRUE,
|
Translate_BRANCH_TRUE,
|
||||||
|
|
|
@ -48,8 +48,6 @@ typedef struct {
|
||||||
int8_t did_saturate;
|
int8_t did_saturate;
|
||||||
runtime::RegisterAccessCallbacks* access_callbacks;
|
runtime::RegisterAccessCallbacks* access_callbacks;
|
||||||
runtime::ThreadState* thread_state;
|
runtime::ThreadState* thread_state;
|
||||||
uint64_t return_address;
|
|
||||||
uint64_t call_return_address;
|
|
||||||
} IntCodeState;
|
} IntCodeState;
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -11,11 +11,15 @@
|
||||||
|
|
||||||
#include <alloy/backend/x64/x64_emitter.h>
|
#include <alloy/backend/x64/x64_emitter.h>
|
||||||
#include <alloy/backend/x64/lowering/lowering_table.h>
|
#include <alloy/backend/x64/lowering/lowering_table.h>
|
||||||
|
#include <alloy/runtime/symbol_info.h>
|
||||||
|
#include <alloy/runtime/runtime.h>
|
||||||
|
#include <alloy/runtime/thread_state.h>
|
||||||
|
|
||||||
using namespace alloy;
|
using namespace alloy;
|
||||||
using namespace alloy::backend::x64;
|
using namespace alloy::backend::x64;
|
||||||
using namespace alloy::backend::x64::lowering;
|
using namespace alloy::backend::x64::lowering;
|
||||||
using namespace alloy::hir;
|
using namespace alloy::hir;
|
||||||
|
using namespace alloy::runtime;
|
||||||
|
|
||||||
using namespace Xbyak;
|
using namespace Xbyak;
|
||||||
|
|
||||||
|
@ -31,6 +35,49 @@ void Dummy() {
|
||||||
//
|
//
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO(benvanik): fancy stuff.
|
||||||
|
void CallThunk(void* raw_context, uint8_t* membase,
|
||||||
|
FunctionInfo* symbol_info) {
|
||||||
|
// TODO(benvanik): generate this thunk at runtime? or a shim?
|
||||||
|
auto thread_state = *((ThreadState**)raw_context);
|
||||||
|
|
||||||
|
Function* fn = NULL;
|
||||||
|
thread_state->runtime()->ResolveFunction(symbol_info->address(), &fn);
|
||||||
|
XEASSERTNOTNULL(fn);
|
||||||
|
fn->Call(thread_state);
|
||||||
|
}
|
||||||
|
void IssueCall(X64Emitter& e, FunctionInfo* symbol_info, uint32_t flags) {
|
||||||
|
e.mov(e.r8, (uint64_t)symbol_info);
|
||||||
|
e.mov(e.rax, (uint64_t)CallThunk);
|
||||||
|
if (flags & CALL_TAIL) {
|
||||||
|
e.jmp(e.rax);
|
||||||
|
} else {
|
||||||
|
e.call(e.rax);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void IndirectCallThunk(void* raw_context, uint8_t* membase,
|
||||||
|
uint64_t target_address) {
|
||||||
|
// TODO(benvanik): generate this thunk at runtime? or a shim?
|
||||||
|
auto thread_state = *((ThreadState**)raw_context);
|
||||||
|
}
|
||||||
|
void IssueCallIndirect(X64Emitter& e, Value* target, uint32_t flags) {
|
||||||
|
Reg64 r;
|
||||||
|
e.BeginOp(target, r, 0);
|
||||||
|
if (r != e.r8) {
|
||||||
|
e.mov(e.r8, r);
|
||||||
|
}
|
||||||
|
e.EndOp(r);
|
||||||
|
e.mov(e.rax, (uint64_t)IndirectCallThunk);
|
||||||
|
if (flags & CALL_TAIL) {
|
||||||
|
e.jmp(e.rax);
|
||||||
|
} else {
|
||||||
|
e.sub(e.rsp, 0x20);
|
||||||
|
e.call(e.rax);
|
||||||
|
e.add(e.rsp, 0x20);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Sets EFLAGs with zf for the given value.
|
// Sets EFLAGs with zf for the given value.
|
||||||
void CheckBoolean(X64Emitter& e, Value* v) {
|
void CheckBoolean(X64Emitter& e, Value* v) {
|
||||||
if (v->IsConstant()) {
|
if (v->IsConstant()) {
|
||||||
|
@ -259,9 +306,7 @@ void alloy::backend::x64::lowering::RegisterSequences(LoweringTable* table) {
|
||||||
// --------------------------------------------------------------------------
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
table->AddSequence(OPCODE_CALL, [](X64Emitter& e, Instr*& i) {
|
table->AddSequence(OPCODE_CALL, [](X64Emitter& e, Instr*& i) {
|
||||||
e.mov(e.rax, (uint64_t)Dummy);
|
IssueCall(e, i->src1.symbol_info, i->flags);
|
||||||
e.call(e.rax);
|
|
||||||
UNIMPLEMENTED_SEQ();
|
|
||||||
i = e.Advance(i);
|
i = e.Advance(i);
|
||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
|
@ -270,10 +315,7 @@ void alloy::backend::x64::lowering::RegisterSequences(LoweringTable* table) {
|
||||||
e.inLocalLabel();
|
e.inLocalLabel();
|
||||||
CheckBoolean(e, i->src1.value);
|
CheckBoolean(e, i->src1.value);
|
||||||
e.jne(".x", e.T_SHORT);
|
e.jne(".x", e.T_SHORT);
|
||||||
// TODO(benvanik): call
|
IssueCall(e, i->src2.symbol_info, i->flags);
|
||||||
e.mov(e.rax, (uint64_t)Dummy);
|
|
||||||
e.call(e.rax);
|
|
||||||
UNIMPLEMENTED_SEQ();
|
|
||||||
e.L(".x");
|
e.L(".x");
|
||||||
e.outLocalLabel();
|
e.outLocalLabel();
|
||||||
i = e.Advance(i);
|
i = e.Advance(i);
|
||||||
|
@ -281,9 +323,7 @@ void alloy::backend::x64::lowering::RegisterSequences(LoweringTable* table) {
|
||||||
});
|
});
|
||||||
|
|
||||||
table->AddSequence(OPCODE_CALL_INDIRECT, [](X64Emitter& e, Instr*& i) {
|
table->AddSequence(OPCODE_CALL_INDIRECT, [](X64Emitter& e, Instr*& i) {
|
||||||
e.mov(e.rax, (uint64_t)Dummy);
|
IssueCallIndirect(e, i->src1.value, i->flags);
|
||||||
e.call(e.rax);
|
|
||||||
UNIMPLEMENTED_SEQ();
|
|
||||||
i = e.Advance(i);
|
i = e.Advance(i);
|
||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
|
@ -292,10 +332,7 @@ void alloy::backend::x64::lowering::RegisterSequences(LoweringTable* table) {
|
||||||
e.inLocalLabel();
|
e.inLocalLabel();
|
||||||
CheckBoolean(e, i->src1.value);
|
CheckBoolean(e, i->src1.value);
|
||||||
e.jne(".x", e.T_SHORT);
|
e.jne(".x", e.T_SHORT);
|
||||||
// TODO(benvanik): call
|
IssueCallIndirect(e, i->src2.value, i->flags);
|
||||||
e.mov(e.rax, (uint64_t)Dummy);
|
|
||||||
e.call(e.rax);
|
|
||||||
UNIMPLEMENTED_SEQ();
|
|
||||||
e.L(".x");
|
e.L(".x");
|
||||||
e.outLocalLabel();
|
e.outLocalLabel();
|
||||||
i = e.Advance(i);
|
i = e.Advance(i);
|
||||||
|
@ -319,12 +356,6 @@ void alloy::backend::x64::lowering::RegisterSequences(LoweringTable* table) {
|
||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
|
|
||||||
table->AddSequence(OPCODE_SET_RETURN_ADDRESS, [](X64Emitter& e, Instr*& i) {
|
|
||||||
//UNIMPLEMENTED_SEQ();
|
|
||||||
i = e.Advance(i);
|
|
||||||
return true;
|
|
||||||
});
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
// --------------------------------------------------------------------------
|
||||||
// Branches
|
// Branches
|
||||||
// --------------------------------------------------------------------------
|
// --------------------------------------------------------------------------
|
||||||
|
|
|
@ -41,10 +41,8 @@ int X64Function::RemoveBreakpointImpl(Breakpoint* breakpoint) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int X64Function::CallImpl(ThreadState* thread_state, uint64_t return_address) {
|
int X64Function::CallImpl(ThreadState* thread_state) {
|
||||||
//typedef void(*call_t)(ThreadState* thread_state, uint64_t return_address);
|
typedef void(*call_t)(void* raw_context, uint8_t* membase);
|
||||||
//((call_t)machine_code_)(thread_state, return_address);
|
((call_t)machine_code_)(thread_state->raw_context(), thread_state->memory()->membase());
|
||||||
typedef void(*call_t)(ThreadState* thread_state, uint8_t* membase);
|
|
||||||
((call_t)machine_code_)(thread_state, thread_state->memory()->membase());
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,8 +30,7 @@ public:
|
||||||
protected:
|
protected:
|
||||||
virtual int AddBreakpointImpl(runtime::Breakpoint* breakpoint);
|
virtual int AddBreakpointImpl(runtime::Breakpoint* breakpoint);
|
||||||
virtual int RemoveBreakpointImpl(runtime::Breakpoint* breakpoint);
|
virtual int RemoveBreakpointImpl(runtime::Breakpoint* breakpoint);
|
||||||
virtual int CallImpl(runtime::ThreadState* thread_state,
|
virtual int CallImpl(runtime::ThreadState* thread_state);
|
||||||
uint64_t return_address);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void* machine_code_;
|
void* machine_code_;
|
||||||
|
|
|
@ -13,8 +13,9 @@ using namespace alloy;
|
||||||
using namespace alloy::frontend;
|
using namespace alloy::frontend;
|
||||||
|
|
||||||
|
|
||||||
ContextInfo::ContextInfo(size_t size) :
|
ContextInfo::ContextInfo(size_t size, uintptr_t thread_state_offset) :
|
||||||
size_(size) {
|
size_(size),
|
||||||
|
thread_state_offset_(thread_state_offset) {
|
||||||
}
|
}
|
||||||
|
|
||||||
ContextInfo::~ContextInfo() {
|
ContextInfo::~ContextInfo() {
|
||||||
|
|
|
@ -19,13 +19,16 @@ namespace frontend {
|
||||||
|
|
||||||
class ContextInfo {
|
class ContextInfo {
|
||||||
public:
|
public:
|
||||||
ContextInfo(size_t size);
|
ContextInfo(size_t size, uintptr_t thread_state_offset);
|
||||||
~ContextInfo();
|
~ContextInfo();
|
||||||
|
|
||||||
size_t size() const { return size_; }
|
size_t size() const { return size_; }
|
||||||
|
|
||||||
|
uintptr_t thread_state_offset() const { return thread_state_offset_; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
size_t size_;
|
size_t size_;
|
||||||
|
uintptr_t thread_state_offset_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -64,6 +64,10 @@ typedef union {
|
||||||
|
|
||||||
#pragma pack(push, 4)
|
#pragma pack(push, 4)
|
||||||
typedef struct XECACHEALIGN64 PPCContext_s {
|
typedef struct XECACHEALIGN64 PPCContext_s {
|
||||||
|
// Must be stored at 0x0 for now.
|
||||||
|
// TODO(benvanik): find a nice way to describe this to the JIT.
|
||||||
|
runtime::ThreadState* thread_state;
|
||||||
|
|
||||||
// Most frequently used registers first.
|
// Most frequently used registers first.
|
||||||
uint64_t r[32]; // General purpose registers
|
uint64_t r[32]; // General purpose registers
|
||||||
uint64_t lr; // Link register
|
uint64_t lr; // Link register
|
||||||
|
@ -194,7 +198,6 @@ typedef struct XECACHEALIGN64 PPCContext_s {
|
||||||
// current runtime and its data.
|
// current runtime and its data.
|
||||||
uint8_t* membase;
|
uint8_t* membase;
|
||||||
runtime::Runtime* runtime;
|
runtime::Runtime* runtime;
|
||||||
runtime::ThreadState* thread_state;
|
|
||||||
volatile int suspend_flag;
|
volatile int suspend_flag;
|
||||||
|
|
||||||
void SetRegFromString(const char* name, const char* value);
|
void SetRegFromString(const char* name, const char* value);
|
||||||
|
|
|
@ -35,7 +35,6 @@ int InstrEmit_branch(
|
||||||
// be correct for returns.
|
// be correct for returns.
|
||||||
if (lk) {
|
if (lk) {
|
||||||
Value* return_address = f.LoadConstant(cia + 4);
|
Value* return_address = f.LoadConstant(cia + 4);
|
||||||
f.SetReturnAddress(return_address);
|
|
||||||
f.StoreLR(return_address);
|
f.StoreLR(return_address);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -50,7 +50,9 @@ PPCFrontend::PPCFrontend(Runtime* runtime) :
|
||||||
Frontend(runtime) {
|
Frontend(runtime) {
|
||||||
InitializeIfNeeded();
|
InitializeIfNeeded();
|
||||||
|
|
||||||
ContextInfo* info = new ContextInfo(sizeof(PPCContext));
|
ContextInfo* info = new ContextInfo(
|
||||||
|
sizeof(PPCContext),
|
||||||
|
offsetof(PPCContext, thread_state));
|
||||||
// Add fields/etc.
|
// Add fields/etc.
|
||||||
context_info_ = info;
|
context_info_ = info;
|
||||||
}
|
}
|
||||||
|
|
|
@ -578,12 +578,6 @@ void HIRBuilder::ReturnTrue(Value* cond) {
|
||||||
EndBlock();
|
EndBlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
void HIRBuilder::SetReturnAddress(Value* value) {
|
|
||||||
Instr* i = AppendInstr(OPCODE_SET_RETURN_ADDRESS_info, 0);
|
|
||||||
i->set_src1(value);
|
|
||||||
i->src2.value = i->src3.value = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
void HIRBuilder::Branch(Label* label, uint32_t branch_flags) {
|
void HIRBuilder::Branch(Label* label, uint32_t branch_flags) {
|
||||||
Instr* i = AppendInstr(OPCODE_BRANCH_info, branch_flags);
|
Instr* i = AppendInstr(OPCODE_BRANCH_info, branch_flags);
|
||||||
i->src1.label = label;
|
i->src1.label = label;
|
||||||
|
|
|
@ -76,7 +76,6 @@ public:
|
||||||
void CallIndirectTrue(Value* cond, Value* value, uint32_t call_flags = 0);
|
void CallIndirectTrue(Value* cond, Value* value, uint32_t call_flags = 0);
|
||||||
void Return();
|
void Return();
|
||||||
void ReturnTrue(Value* cond);
|
void ReturnTrue(Value* cond);
|
||||||
void SetReturnAddress(Value* value);
|
|
||||||
|
|
||||||
void Branch(Label* label, uint32_t branch_flags = 0);
|
void Branch(Label* label, uint32_t branch_flags = 0);
|
||||||
void Branch(Block* block, uint32_t branch_flags = 0);
|
void Branch(Block* block, uint32_t branch_flags = 0);
|
||||||
|
|
|
@ -96,7 +96,6 @@ enum Opcode {
|
||||||
OPCODE_CALL_INDIRECT_TRUE,
|
OPCODE_CALL_INDIRECT_TRUE,
|
||||||
OPCODE_RETURN,
|
OPCODE_RETURN,
|
||||||
OPCODE_RETURN_TRUE,
|
OPCODE_RETURN_TRUE,
|
||||||
OPCODE_SET_RETURN_ADDRESS,
|
|
||||||
|
|
||||||
OPCODE_BRANCH,
|
OPCODE_BRANCH,
|
||||||
OPCODE_BRANCH_TRUE,
|
OPCODE_BRANCH_TRUE,
|
||||||
|
|
|
@ -86,12 +86,6 @@ DEFINE_OPCODE(
|
||||||
OPCODE_SIG_X_V,
|
OPCODE_SIG_X_V,
|
||||||
OPCODE_FLAG_BRANCH);
|
OPCODE_FLAG_BRANCH);
|
||||||
|
|
||||||
DEFINE_OPCODE(
|
|
||||||
OPCODE_SET_RETURN_ADDRESS,
|
|
||||||
"set_return_address",
|
|
||||||
OPCODE_SIG_X_V,
|
|
||||||
0);
|
|
||||||
|
|
||||||
DEFINE_OPCODE(
|
DEFINE_OPCODE(
|
||||||
OPCODE_BRANCH,
|
OPCODE_BRANCH,
|
||||||
"branch",
|
"branch",
|
||||||
|
|
|
@ -72,12 +72,12 @@ Breakpoint* Function::FindBreakpoint(uint64_t address) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
int Function::Call(ThreadState* thread_state, uint64_t return_address) {
|
int Function::Call(ThreadState* thread_state) {
|
||||||
ThreadState* original_thread_state = ThreadState::Get();
|
ThreadState* original_thread_state = ThreadState::Get();
|
||||||
if (original_thread_state != thread_state) {
|
if (original_thread_state != thread_state) {
|
||||||
ThreadState::Bind(thread_state);
|
ThreadState::Bind(thread_state);
|
||||||
}
|
}
|
||||||
int result = CallImpl(thread_state, return_address);
|
int result = CallImpl(thread_state);
|
||||||
if (original_thread_state != thread_state) {
|
if (original_thread_state != thread_state) {
|
||||||
ThreadState::Bind(original_thread_state);
|
ThreadState::Bind(original_thread_state);
|
||||||
}
|
}
|
||||||
|
@ -101,8 +101,7 @@ void ExternFunction::set_name(const char* name) {
|
||||||
name_ = xestrdupa(name);
|
name_ = xestrdupa(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
int ExternFunction::CallImpl(ThreadState* thread_state,
|
int ExternFunction::CallImpl(ThreadState* thread_state) {
|
||||||
uint64_t return_address) {
|
|
||||||
if (!handler_) {
|
if (!handler_) {
|
||||||
XELOGW("undefined extern call to %.8X %s", address(), name());
|
XELOGW("undefined extern call to %.8X %s", address(), name());
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -42,13 +42,13 @@ public:
|
||||||
int AddBreakpoint(Breakpoint* breakpoint);
|
int AddBreakpoint(Breakpoint* breakpoint);
|
||||||
int RemoveBreakpoint(Breakpoint* breakpoint);
|
int RemoveBreakpoint(Breakpoint* breakpoint);
|
||||||
|
|
||||||
int Call(ThreadState* thread_state, uint64_t return_address);
|
int Call(ThreadState* thread_state);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
Breakpoint* FindBreakpoint(uint64_t address);
|
Breakpoint* FindBreakpoint(uint64_t address);
|
||||||
virtual int AddBreakpointImpl(Breakpoint* breakpoint) { return 0; }
|
virtual int AddBreakpointImpl(Breakpoint* breakpoint) { return 0; }
|
||||||
virtual int RemoveBreakpointImpl(Breakpoint* breakpoint) { return 0; }
|
virtual int RemoveBreakpointImpl(Breakpoint* breakpoint) { return 0; }
|
||||||
virtual int CallImpl(ThreadState* thread_state, uint64_t return_address) = 0;
|
virtual int CallImpl(ThreadState* thread_state) = 0;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
Type type_;
|
Type type_;
|
||||||
|
@ -76,7 +76,7 @@ public:
|
||||||
void* arg1() const { return arg1_; }
|
void* arg1() const { return arg1_; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual int CallImpl(ThreadState* thread_state, uint64_t return_address);
|
virtual int CallImpl(ThreadState* thread_state);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
char* name_;
|
char* name_;
|
||||||
|
|
|
@ -165,7 +165,7 @@ int Processor::Execute(XenonThreadState* thread_state, uint64_t address) {
|
||||||
context->lr = lr;
|
context->lr = lr;
|
||||||
|
|
||||||
// Execute the function.
|
// Execute the function.
|
||||||
fn->Call(thread_state, lr);
|
fn->Call(thread_state);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -49,7 +49,7 @@ int alloy_sandbox(int argc, xechar_t** argv) {
|
||||||
ctx->lr = 0xBEBEBEBE;
|
ctx->lr = 0xBEBEBEBE;
|
||||||
ctx->r[5] = 10;
|
ctx->r[5] = 10;
|
||||||
ctx->r[25] = 25;
|
ctx->r[25] = 25;
|
||||||
fn->Call(thread_state, 0xBEBEBEBE);
|
fn->Call(thread_state);
|
||||||
auto result = ctx->r[11];
|
auto result = ctx->r[11];
|
||||||
|
|
||||||
delete thread_state;
|
delete thread_state;
|
||||||
|
|
Loading…
Reference in New Issue