bool
InterceptRouting::GenerateRelocatedCode() {
uint32_t tramp_size = GetTrampolineBuffer()->GetBufferSize();
origin_ =
new
CodeMemBlock(entry_->patched_addr, tramp_size);
relocated_ =
new
CodeMemBlock();
auto
buffer = (
void
*)entry_->patched_addr;
#if defined(TARGET_ARCH_ARM)
if
(entry_->thumb_mode) {
buffer = (
void
*)((addr_t)buffer + 1);
}
#endif
GenRelocateCodeAndBranch(buffer, origin_, relocated_);
if
(relocated_->size == 0) {
ERROR_LOG(
"[insn relocate]] failed"
);
return
false
;
}
entry_->relocated_addr = relocated_->addr;
memcpy
((
void
*)entry_->origin_insns, (
void
*)origin_->addr, origin_->size);
entry_->origin_insn_size = origin_->size;
DEBUG_LOG(
"[insn relocate] origin %p - %d"
, origin_->addr, origin_->size);
log_hex_format((uint8_t *)origin_->addr, origin_->size);
DEBUG_LOG(
"[insn relocate] relocated %p - %d"
, relocated_->addr, relocated_->size);
log_hex_format((uint8_t *)relocated_->addr, relocated_->size);
return
true
;
}
void
GenRelocateCode(
void
*buffer, CodeMemBlock *origin, CodeMemBlock *relocated,
bool
branch) {
relo_ctx_t ctx = {0};
ctx.buffer = ctx.buffer_cursor = (uint8_t *)buffer;
ctx.buffer_size = origin->size;
ctx.src_vmaddr = (addr_t)origin->addr;
ctx.dst_vmaddr = (addr_t)relocated->addr;
ctx.origin = origin;
relo_relocate(&ctx, branch);
relocated->reset(ctx.relocated->addr, ctx.relocated->size);
}
void
GenRelocateCodeAndBranch(
void
*buffer, CodeMemBlock *origin, CodeMemBlock *relocated) {
GenRelocateCode(buffer, origin, relocated,
true
);
}
int
relo_relocate(relo_ctx_t *ctx,
bool
branch) {
int
relocated_insn_count = 0;
TurboAssembler turbo_assembler_(0);
#define _ turbo_assembler_.
auto
relocated_buffer = turbo_assembler_.GetCodeBuffer();
......
int
new_origin_len = (addr_t)ctx->buffer_cursor - (addr_t)ctx->buffer;
ctx->origin->reset(ctx->origin->addr, new_origin_len);
if
(branch) {
CodeGen codegen(&turbo_assembler_);
codegen.LiteralLdrBranch(ctx->origin->addr + ctx->origin->size);
}
turbo_assembler_.RelocBind();
{
auto
code = AssemblyCodeBuilder::FinalizeFromTurboAssembler(&turbo_assembler_);
ctx->relocated = code;
}
return
0;
}
void
CodeGen::LiteralLdrBranch(uint64_t address) {
auto
turbo_assembler_ =
reinterpret_cast
<TurboAssembler *>(
this
->assembler_);
#define _ turbo_assembler_->
auto
label = RelocLabel::withData(address);
turbo_assembler_->AppendRelocLabel(label);
_ Ldr(TMP_REG_0, label);
_ br(TMP_REG_0);
#undef _
}