mirror of
https://github.com/ptitSeb/box64.git
synced 2025-05-09 00:21:32 +08:00
[ARM64_DYNAREC] Improved signal handling and flags handling (tbd on other archs)
This commit is contained in:
parent
ca8d569e63
commit
1d20968f82
@ -899,6 +899,7 @@ if(ARM_DYNAREC)
|
||||
${DYNAREC_SRC}
|
||||
|
||||
"${BOX64_ROOT}/src/dynarec/arm64/dynarec_arm64_functions.c"
|
||||
"${BOX64_ROOT}/src/dynarec/arm64/dynarec_arm64_arch.c"
|
||||
"${BOX64_ROOT}/src/dynarec/arm64/arm64_immenc.c"
|
||||
"${BOX64_ROOT}/src/dynarec/arm64/arm64_printer.c"
|
||||
"${BOX64_ROOT}/src/dynarec/arm64/dynarec_arm64_jmpnext.c"
|
||||
|
81
src/dynarec/arm64/dynarec_arm64_arch.c
Normal file
81
src/dynarec/arm64/dynarec_arm64_arch.c
Normal file
@ -0,0 +1,81 @@
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
#include <ucontext.h>
|
||||
|
||||
#include "debug.h"
|
||||
#include "dynablock.h"
|
||||
#include "x64emu.h"
|
||||
#include "emu/x64emu_private.h"
|
||||
#include "x64run.h"
|
||||
#include "emu/x64run_private.h"
|
||||
#include "dynarec/dynablock_private.h"
|
||||
#include "dynarec_arm64_arch.h"
|
||||
|
||||
size_t get_size_arch(dynarec_arm_t* dyn)
|
||||
{
|
||||
if(!box64_dynarec_nativeflags)
|
||||
return 0;
|
||||
return dyn->isize*sizeof(arch_flags_t);
|
||||
}
|
||||
|
||||
void populate_arch(dynarec_arm_t* dyn, void* p)
|
||||
{
|
||||
if(!box64_dynarec_nativeflags)
|
||||
return;
|
||||
|
||||
arch_flags_t* flags = p;
|
||||
for(int i=0; i<dyn->size; ++i) {
|
||||
flags[i].defered = dyn->insts[i].f_entry.dfnone==0;
|
||||
flags[i].vf = dyn->insts[i].need_nat_flags&NF_VF;
|
||||
flags[i].nf = dyn->insts[i].need_nat_flags&NF_SF;
|
||||
flags[i].eq = dyn->insts[i].need_nat_flags&NF_EQ;
|
||||
flags[i].cf = dyn->insts[i].need_nat_flags&NF_CF;
|
||||
flags[i].inv_cf = !dyn->insts[i].normal_carry;
|
||||
}
|
||||
}
|
||||
|
||||
int getX64AddressInst(dynablock_t* db, uintptr_t native_addr); // define is signal.c
|
||||
|
||||
// NZCV N
|
||||
#define NZCV_N 31
|
||||
// NZCV Z
|
||||
#define NZCV_Z 30
|
||||
// NZCV C
|
||||
#define NZCV_C 29
|
||||
// NZCV V
|
||||
#define NZCV_V 28
|
||||
|
||||
void adjust_arch(dynablock_t* db, x64emu_t* emu, ucontext_t* p, uintptr_t x64pc)
|
||||
{
|
||||
if(!db->arch_size || !db->arch)
|
||||
return;
|
||||
arch_flags_t* flags = db->arch;
|
||||
int ninst = getX64AddressInst(db, x64pc);
|
||||
printf_log(LOG_INFO, "adjust_arch(...), db=%p, x64pc=%p, nints=%d, flags:%s %c%c%c%c%s\n", db, (void*)x64pc, ninst, flags[ninst-1].defered?"defered":"", flags[ninst-1].vf?'V':' ', flags[ninst-1].nf?'S':' ', flags[ninst-1].eq?'Z':' ', flags[ninst-1].cf?'C':' ', (flags[ninst-1].cf && flags[ninst-1].inv_cf)?"inverted":"");
|
||||
if(ninst<0)
|
||||
return;
|
||||
if(ninst==0) {
|
||||
CHECK_FLAGS(emu);
|
||||
return;
|
||||
}
|
||||
if(flags[ninst-1].defered) {
|
||||
CHECK_FLAGS(emu);
|
||||
//return;
|
||||
}
|
||||
if(flags[ninst-1].nf) {
|
||||
CONDITIONAL_SET_FLAG(p->uc_mcontext.pstate&(1<<NZCV_N), F_SF);
|
||||
}
|
||||
if(flags[ninst-1].vf) {
|
||||
CONDITIONAL_SET_FLAG(p->uc_mcontext.pstate&(1<<NZCV_V), F_OF);
|
||||
}
|
||||
if(flags[ninst-1].eq) {
|
||||
CONDITIONAL_SET_FLAG(p->uc_mcontext.pstate&(1<<NZCV_Z), F_ZF);
|
||||
}
|
||||
if(flags[ninst-1].cf) {
|
||||
if(flags[ninst-1].inv_cf) {
|
||||
CONDITIONAL_SET_FLAG((p->uc_mcontext.pstate&(1<<NZCV_C))==0, F_CF);
|
||||
} else {
|
||||
CONDITIONAL_SET_FLAG(p->uc_mcontext.pstate&(1<<NZCV_C), F_CF);
|
||||
}
|
||||
}
|
||||
}
|
28
src/dynarec/arm64/dynarec_arm64_arch.h
Normal file
28
src/dynarec/arm64/dynarec_arm64_arch.h
Normal file
@ -0,0 +1,28 @@
|
||||
#ifndef __DYNAREC_ARM_ARCH_H__
|
||||
#define __DYNAREC_ARM_ARCH_H__
|
||||
|
||||
#include <stddef.h>
|
||||
#include <ucontext.h>
|
||||
|
||||
#include "x64emu.h"
|
||||
#include "box64context.h"
|
||||
#include "dynarec.h"
|
||||
#include "dynarec_arm64_private.h"
|
||||
|
||||
typedef struct arch_flags_s
|
||||
{
|
||||
uint8_t defered:1;
|
||||
uint8_t nf:1;
|
||||
uint8_t eq:1;
|
||||
uint8_t vf:1;
|
||||
uint8_t cf:1;
|
||||
uint8_t inv_cf:1;
|
||||
} arch_flags_t;
|
||||
|
||||
// get size of arch specific info (can be 0)
|
||||
size_t get_size_arch(dynarec_arm_t* dyn);
|
||||
//populate the array
|
||||
void populate_arch(dynarec_arm_t* dyn, void* p);
|
||||
//adjust flags and more
|
||||
void adjust_arch(dynablock_t* db, x64emu_t* emu, ucontext_t* p, uintptr_t native_addr);
|
||||
#endif // __DYNAREC_ARM_ARCH_H__
|
@ -21,6 +21,8 @@ typedef struct dynablock_s {
|
||||
uint8_t is32bits:1;
|
||||
int isize;
|
||||
instsize_t* instsize;
|
||||
void* arch; // arch dependant per inst info (can be NULL)
|
||||
size_t arch_size; // size of of arch dependant infos
|
||||
void* jmpnext; // a branch jmpnext code when block is marked
|
||||
} dynablock_t;
|
||||
|
||||
|
@ -17,6 +17,7 @@
|
||||
#include "arm64/arm64_printer.h"
|
||||
#include "arm64/dynarec_arm64_private.h"
|
||||
#include "arm64/dynarec_arm64_functions.h"
|
||||
#include "arm64/dynarec_arm64_arch.h"
|
||||
// Limit here is defined by LD litteral, that is 19bits
|
||||
#define MAXBLOCK_SIZE ((1<<19)-200)
|
||||
|
||||
@ -24,6 +25,9 @@
|
||||
#define UPDATE_SPECIFICS(A) updateNativeFlags(A)
|
||||
#define PREUPDATE_SPECIFICS(A)
|
||||
|
||||
#define ARCH_SIZE(A) get_size_arch(A)
|
||||
#define ARCH_FILL(A, B) populate_arch(A, B)
|
||||
#define ARCH_ADJUST(A, B, C, D) adjust_arch(A, B, C, D)
|
||||
#elif defined(LA64)
|
||||
|
||||
#define instruction_native_t instruction_la64_t
|
||||
@ -45,6 +49,10 @@
|
||||
#define RAZ_SPECIFIC(A, N)
|
||||
#define UPDATE_SPECIFICS(A)
|
||||
#define PREUPDATE_SPECIFICS(A) updateNativeFlags(A)
|
||||
|
||||
#define ARCH_SIZE(A) 0
|
||||
#define ARCH_FILL(A, B) {}
|
||||
#define ARCH_ADJUST(A, B, C, D) {}
|
||||
#elif defined(RV64)
|
||||
|
||||
#define instruction_native_t instruction_rv64_t
|
||||
@ -68,6 +76,10 @@
|
||||
#define RAZ_SPECIFIC(A, N)
|
||||
#define UPDATE_SPECIFICS(A)
|
||||
#define PREUPDATE_SPECIFICS(A) updateNativeFlags(A)
|
||||
|
||||
#define ARCH_SIZE(A) 0
|
||||
#define ARCH_FILL(A, B) {}
|
||||
#define ARCH_ADJUST(A, B, C, D) {}
|
||||
#else
|
||||
#error Unsupported platform
|
||||
#endif
|
||||
|
@ -562,6 +562,7 @@ void* FillBlock64(dynablock_t* block, uintptr_t addr, int alternate, int is32bit
|
||||
B+16 .. B+23 : jmpnext (or jmp_epilog) address. jumpnext is used when the block needs testing
|
||||
B+24 .. B+31 : empty (in case an architecture needs more than 2 opcodes)
|
||||
B+32 .. B+32+sz : instsize (compressed array with each instruction length on x64 and native side)
|
||||
C .. C+sz : arch: arch specific info (likes flags info) per inst (can be absent)
|
||||
|
||||
*/
|
||||
if(addr>=box64_nodynarec_start && addr<box64_nodynarec_end) {
|
||||
@ -725,14 +726,16 @@ void* FillBlock64(dynablock_t* block, uintptr_t addr, int alternate, int is32bit
|
||||
size_t insts_rsize = (helper.insts_size+2)*sizeof(instsize_t);
|
||||
insts_rsize = (insts_rsize+7)&~7; // round the size...
|
||||
size_t native_size = (helper.native_size+7)&~7; // round the size...
|
||||
size_t arch_size = ARCH_SIZE(&helper);
|
||||
// ok, now allocate mapped memory, with executable flag on
|
||||
size_t sz = sizeof(void*) + native_size + helper.table64size*sizeof(uint64_t) + 4*sizeof(void*) + insts_rsize;
|
||||
// dynablock_t* block (arm insts) table64 jmpnext code instsize
|
||||
size_t sz = sizeof(void*) + native_size + helper.table64size*sizeof(uint64_t) + 4*sizeof(void*) + insts_rsize + arch_size;
|
||||
// dynablock_t* block (arm insts) table64 jmpnext code instsize arch
|
||||
void* actual_p = (void*)AllocDynarecMap(sz);
|
||||
void* p = (void*)(((uintptr_t)actual_p) + sizeof(void*));
|
||||
void* tablestart = p + native_size;
|
||||
void* next = tablestart + helper.table64size*sizeof(uint64_t);
|
||||
void* instsize = next + 4*sizeof(void*);
|
||||
void* arch = instsize + insts_rsize;
|
||||
if(actual_p==NULL) {
|
||||
dynarec_log(LOG_INFO, "AllocDynarecMap(%p, %zu) failed, canceling block\n", block, sz);
|
||||
CancelBlock64(0);
|
||||
@ -784,6 +787,14 @@ void* FillBlock64(dynablock_t* block, uintptr_t addr, int alternate, int is32bit
|
||||
block->always_test = helper.always_test;
|
||||
block->dirty = block->always_test;
|
||||
block->is32bits = is32bits;
|
||||
if(arch_size) {
|
||||
block->arch = arch;
|
||||
block->arch_size = arch_size;
|
||||
ARCH_FILL(&helper, arch);
|
||||
} else {
|
||||
block->arch = NULL;
|
||||
block->arch_size = arch_size;
|
||||
}
|
||||
*(dynablock_t**)next = block;
|
||||
*(void**)(next+3*sizeof(void*)) = native_next;
|
||||
CreateJmpNext(block->jmpnext, next+3*sizeof(void*));
|
||||
|
@ -468,7 +468,7 @@ void convert_siginfo_to_32(void* d, void* s, int sig)
|
||||
int write_opcode(uintptr_t rip, uintptr_t native_ip, int is32bits);
|
||||
#define is_memprot_locked (1<<1)
|
||||
#define is_dyndump_locked (1<<8)
|
||||
void my_sigactionhandler_oldcode_32(int32_t sig, int simple, siginfo_t* info, void * ucntx, int* old_code, void* cur_db)
|
||||
void my_sigactionhandler_oldcode_32(x64emu_t* emu, int32_t sig, int simple, siginfo_t* info, void * ucntx, int* old_code, void* cur_db)
|
||||
{
|
||||
int Locks = unlockMutex();
|
||||
int log_minimum = (box64_showsegv)?LOG_NONE:((sig==SIGSEGV && my_context->is_sigaction[sig])?LOG_DEBUG:LOG_INFO);
|
||||
@ -477,7 +477,8 @@ void my_sigactionhandler_oldcode_32(int32_t sig, int simple, siginfo_t* info, vo
|
||||
|
||||
uintptr_t restorer = my_context->restorer[sig];
|
||||
// get that actual ESP first!
|
||||
x64emu_t *emu = thread_get_emu();
|
||||
if(!emu)
|
||||
emu = thread_get_emu();
|
||||
uintptr_t frame = R_RSP;
|
||||
#if defined(DYNAREC)
|
||||
#if defined(ARM64)
|
||||
|
@ -36,6 +36,7 @@
|
||||
#include "dynablock.h"
|
||||
#include "../dynarec/dynablock_private.h"
|
||||
#include "dynarec_native.h"
|
||||
#include "dynarec/dynarec_arch.h"
|
||||
#endif
|
||||
|
||||
|
||||
@ -491,6 +492,31 @@ uintptr_t getX64Address(dynablock_t* db, uintptr_t native_addr)
|
||||
} while(db->instsize[i].x64 || db->instsize[i].nat);
|
||||
return x64addr;
|
||||
}
|
||||
int getX64AddressInst(dynablock_t* db, uintptr_t x64pc)
|
||||
{
|
||||
uintptr_t x64addr = (uintptr_t)db->x64_addr;
|
||||
uintptr_t armaddr = (uintptr_t)db->block;
|
||||
int ret = 0;
|
||||
if(x64pc<(uintptr_t)db->x64_addr || x64pc>(uintptr_t)db->x64_addr+db->x64_size)
|
||||
return -1;
|
||||
int i = 0;
|
||||
do {
|
||||
int x64sz = 0;
|
||||
int armsz = 0;
|
||||
do {
|
||||
x64sz+=db->instsize[i].x64;
|
||||
armsz+=db->instsize[i].nat*4;
|
||||
++i;
|
||||
} while((db->instsize[i-1].x64==15) || (db->instsize[i-1].nat==15));
|
||||
// if the opcode is a NOP on ARM side (so armsz==0), it cannot be an address to find
|
||||
if((x64pc>=x64addr) && (x64pc<(x64addr+x64sz)))
|
||||
return ret;
|
||||
armaddr+=armsz;
|
||||
x64addr+=x64sz;
|
||||
ret++;
|
||||
} while(db->instsize[i].x64 || db->instsize[i].nat);
|
||||
return ret;
|
||||
}
|
||||
x64emu_t* getEmuSignal(x64emu_t* emu, ucontext_t* p, dynablock_t* db)
|
||||
{
|
||||
#if defined(ARM64)
|
||||
@ -927,16 +953,10 @@ int sigbus_specialcases(siginfo_t* info, void * ucntx, void* pc, void* _fpsimd)
|
||||
}
|
||||
|
||||
#ifdef BOX32
|
||||
void my_sigactionhandler_oldcode_32(int32_t sig, int simple, siginfo_t* info, void * ucntx, int* old_code, void* cur_db);
|
||||
void my_sigactionhandler_oldcode_32(ix64emu_t* emu, nt32_t sig, int simple, siginfo_t* info, void * ucntx, int* old_code, void* cur_db);
|
||||
#endif
|
||||
void my_sigactionhandler_oldcode(x64emu_t* emu, int32_t sig, int simple, siginfo_t* info, void * ucntx, int* old_code, void* cur_db)
|
||||
void my_sigactionhandler_oldcode_64(x64emu_t* emu, int32_t sig, int simple, siginfo_t* info, void * ucntx, int* old_code, void* cur_db)
|
||||
{
|
||||
#ifdef BOX32
|
||||
if(box64_is32bits) {
|
||||
my_sigactionhandler_oldcode_32(sig, simple, info, ucntx, old_code, cur_db);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
int Locks = unlockMutex();
|
||||
int log_minimum = (box64_showsegv)?LOG_NONE:LOG_DEBUG;
|
||||
|
||||
@ -1376,6 +1396,63 @@ void my_sigactionhandler_oldcode(x64emu_t* emu, int32_t sig, int simple, siginfo
|
||||
relockMutex(Locks);
|
||||
}
|
||||
|
||||
void my_sigactionhandler_oldcode(x64emu_t* emu, int32_t sig, int simple, siginfo_t* info, void * ucntx, int* old_code, void* cur_db, uintptr_t x64pc)
|
||||
{
|
||||
#define GO(A) uintptr_t old_##A = R_##A;
|
||||
GO(RAX);
|
||||
GO(RBX);
|
||||
GO(RCX);
|
||||
GO(RDX);
|
||||
GO(RBP);
|
||||
GO(RSP);
|
||||
GO(RDI);
|
||||
GO(RSI);
|
||||
GO(R8);
|
||||
GO(R9);
|
||||
GO(R10);
|
||||
GO(R11);
|
||||
GO(R12);
|
||||
GO(R13);
|
||||
GO(R14);
|
||||
GO(R15);
|
||||
GO(RIP);
|
||||
#undef GO
|
||||
#ifdef DYNAREC
|
||||
dynablock_t* db = cur_db;
|
||||
if(db) {
|
||||
copyUCTXreg2Emu(emu, ucntx, x64pc);
|
||||
adjustregs(emu);
|
||||
if(db && db->arch_size)
|
||||
ARCH_ADJUST(db, emu, ucntx, x64pc);
|
||||
}
|
||||
#endif
|
||||
#ifdef BOX32
|
||||
if(box64_is32bits) {
|
||||
my_sigactionhandler_oldcode_32(emu, sig, simple, info, ucntx, old_code, cur_db);
|
||||
} else
|
||||
#endif
|
||||
my_sigactionhandler_oldcode_64(emu, sig, simple, info, ucntx, old_code, cur_db);
|
||||
#define GO(A) R_##A = old_##A
|
||||
GO(RAX);
|
||||
GO(RBX);
|
||||
GO(RCX);
|
||||
GO(RDX);
|
||||
GO(RBP);
|
||||
GO(RSP);
|
||||
GO(RDI);
|
||||
GO(RSI);
|
||||
GO(R8);
|
||||
GO(R9);
|
||||
GO(R10);
|
||||
GO(R11);
|
||||
GO(R12);
|
||||
GO(R13);
|
||||
GO(R14);
|
||||
GO(R15);
|
||||
GO(RIP);
|
||||
#undef GO
|
||||
}
|
||||
|
||||
extern void* current_helper;
|
||||
#define USE_SIGNAL_MUTEX
|
||||
#ifdef USE_SIGNAL_MUTEX
|
||||
@ -1486,8 +1563,11 @@ void my_box64signalhandler(int32_t sig, siginfo_t* info, void * ucntx)
|
||||
emu = getEmuSignal(emu, p, db);
|
||||
// dynablock got auto-dirty! need to get out of it!!!
|
||||
if(emu->jmpbuf) {
|
||||
copyUCTXreg2Emu(emu, p, getX64Address(db, (uintptr_t)pc));
|
||||
uintptr_t x64pc = getX64Address(db, (uintptr_t)pc);
|
||||
copyUCTXreg2Emu(emu, p, x64pc);
|
||||
adjustregs(emu);
|
||||
if(db && db->arch_size)
|
||||
ARCH_ADJUST(db, emu, p, x64pc);
|
||||
#ifdef ARM64
|
||||
//TODO: Need proper SIMD/x87 register traking!
|
||||
/*if(fpsimd) {
|
||||
@ -1611,6 +1691,37 @@ dynarec_log(/*LOG_DEBUG*/LOG_INFO, "Repeated SIGSEGV with Access error on %p for
|
||||
int tid = GetTID();
|
||||
int mapped = memExist((uintptr_t)addr);
|
||||
const char* signame = (sig==SIGSEGV)?"SIGSEGV":((sig==SIGBUS)?"SIGBUS":((sig==SIGILL)?"SIGILL":"SIGABRT"));
|
||||
uintptr_t x64pc = (uintptr_t)-1;
|
||||
x64pc = R_RIP;
|
||||
rsp = (void*)R_RSP;
|
||||
#if defined(DYNAREC)
|
||||
#if defined(ARM64)
|
||||
if(db) {
|
||||
x64pc = getX64Address(db, (uintptr_t)pc);
|
||||
rsp = (void*)p->uc_mcontext.regs[10+_SP];
|
||||
}
|
||||
#elif defined(LA64)
|
||||
if(db && p->uc_mcontext.__gregs[4]>0x10000) {
|
||||
emu = (x64emu_t*)p->uc_mcontext.__gregs[4];
|
||||
}
|
||||
if(db) {
|
||||
x64pc = getX64Address(db, (uintptr_t)pc);
|
||||
rsp = (void*)p->uc_mcontext.__gregs[12+_SP];
|
||||
}
|
||||
#elif defined(RV64)
|
||||
if(db && p->uc_mcontext.__gregs[25]>0x10000) {
|
||||
emu = (x64emu_t*)p->uc_mcontext.__gregs[25];
|
||||
}
|
||||
if(db) {
|
||||
x64pc = getX64Address(db, (uintptr_t)pc);
|
||||
rsp = (void*)p->uc_mcontext.__gregs[9];
|
||||
}
|
||||
#else
|
||||
#error Unsupported Architecture
|
||||
#endif //arch
|
||||
#endif //DYNAREC
|
||||
if(!db && (sig==SIGSEGV) && ((uintptr_t)addr==(x64pc-1)))
|
||||
x64pc--;
|
||||
if(old_code==info->si_code && old_pc==pc && old_addr==addr && old_tid==tid && old_prot==prot) {
|
||||
printf_log(log_minimum, "%04d|Double %s (code=%d, pc=%p, addr=%p, prot=%02x)!\n", tid, signame, old_code, old_pc, old_addr, prot);
|
||||
exit(-1);
|
||||
@ -1643,41 +1754,10 @@ dynarec_log(/*LOG_DEBUG*/LOG_INFO, "Repeated SIGSEGV with Access error on %p for
|
||||
old_tid = tid;
|
||||
old_prot = prot;
|
||||
const char* name = (log_minimum<=box64_log)?GetNativeName(pc):NULL;
|
||||
uintptr_t x64pc = (uintptr_t)-1;
|
||||
const char* x64name = NULL;
|
||||
// Adjust RIP for special case of NULL function run
|
||||
if(sig==SIGSEGV && R_RIP==0x1 && (uintptr_t)info->si_addr==0x0)
|
||||
R_RIP = 0x0;
|
||||
x64pc = R_RIP;
|
||||
rsp = (void*)R_RSP;
|
||||
#if defined(DYNAREC)
|
||||
#if defined(ARM64)
|
||||
if(db) {
|
||||
x64pc = getX64Address(db, (uintptr_t)pc);
|
||||
rsp = (void*)p->uc_mcontext.regs[10+_SP];
|
||||
}
|
||||
#elif defined(LA64)
|
||||
if(db && p->uc_mcontext.__gregs[4]>0x10000) {
|
||||
emu = (x64emu_t*)p->uc_mcontext.__gregs[4];
|
||||
}
|
||||
if(db) {
|
||||
x64pc = getX64Address(db, (uintptr_t)pc);
|
||||
rsp = (void*)p->uc_mcontext.__gregs[12+_SP];
|
||||
}
|
||||
#elif defined(RV64)
|
||||
if(db && p->uc_mcontext.__gregs[25]>0x10000) {
|
||||
emu = (x64emu_t*)p->uc_mcontext.__gregs[25];
|
||||
}
|
||||
if(db) {
|
||||
x64pc = getX64Address(db, (uintptr_t)pc);
|
||||
rsp = (void*)p->uc_mcontext.__gregs[9];
|
||||
}
|
||||
#else
|
||||
#error Unsupported Architecture
|
||||
#endif //arch
|
||||
#endif //DYNAREC
|
||||
if(!db && (sig==SIGSEGV) && ((uintptr_t)addr==(x64pc-1)))
|
||||
x64pc--;
|
||||
if(log_minimum<=box64_log) {
|
||||
elfheader_t* elf = FindElfAddress(my_context, x64pc);
|
||||
if(elf) {
|
||||
@ -1877,7 +1957,7 @@ dynarec_log(/*LOG_DEBUG*/LOG_INFO, "Repeated SIGSEGV with Access error on %p for
|
||||
}
|
||||
relockMutex(Locks);
|
||||
if(my_context->signals[sig] && my_context->signals[sig]!=1) {
|
||||
my_sigactionhandler_oldcode(emu, sig, my_context->is_sigaction[sig]?0:1, info, ucntx, &old_code, db);
|
||||
my_sigactionhandler_oldcode(emu, sig, my_context->is_sigaction[sig]?0:1, info, ucntx, &old_code, db, x64pc);
|
||||
return;
|
||||
}
|
||||
// no handler (or double identical segfault)
|
||||
@ -1904,8 +1984,13 @@ void my_sigactionhandler(int32_t sig, siginfo_t* info, void * ucntx)
|
||||
#else
|
||||
void* db = NULL;
|
||||
#endif
|
||||
|
||||
my_sigactionhandler_oldcode(NULL, sig, 0, info, ucntx, NULL, db);
|
||||
x64emu_t* emu = thread_get_emu();
|
||||
uintptr_t x64pc = R_RIP;
|
||||
#ifdef DYNAREC
|
||||
if(db)
|
||||
x64pc = getX64Address(db, (uintptr_t)pc);
|
||||
#endif
|
||||
my_sigactionhandler_oldcode(emu, sig, 0, info, ucntx, NULL, db, x64pc);
|
||||
}
|
||||
|
||||
#ifndef DYNAREC
|
||||
@ -1983,7 +2068,7 @@ printf_log(LOG_NONE, "Emu Stack: %p 0x%lx%s\n", emu->init_stack, emu->size_stack
|
||||
printf_log(LOG_NONE, "SIGILL: Opcode at ip is %02hhx %02hhx %02hhx %02hhx %02hhx %02hhx\n", mem[0], mem[1], mem[2], mem[3], mem[4], mem[5]);
|
||||
}
|
||||
}
|
||||
my_sigactionhandler_oldcode(emu, sig, 0, &info, NULL, NULL, NULL);
|
||||
my_sigactionhandler_oldcode(emu, sig, 0, &info, NULL, NULL, NULL, R_RIP);
|
||||
}
|
||||
|
||||
void check_exec(x64emu_t* emu, uintptr_t addr)
|
||||
@ -2012,7 +2097,7 @@ void emit_interruption(x64emu_t* emu, int num, void* addr)
|
||||
elfname = ElfName(elf);
|
||||
printf_log(LOG_NONE, "Emit Interruption 0x%x at IP=%p(%s / %s) / addr=%p\n", num, (void*)R_RIP, x64name?x64name:"???", elfname?elfname:"?", addr);
|
||||
}
|
||||
my_sigactionhandler_oldcode(emu, SIGSEGV, 0, &info, NULL, NULL, NULL);
|
||||
my_sigactionhandler_oldcode(emu, SIGSEGV, 0, &info, NULL, NULL, NULL, R_RIP);
|
||||
}
|
||||
|
||||
void emit_div0(x64emu_t* emu, void* addr, int code)
|
||||
@ -2031,7 +2116,7 @@ void emit_div0(x64emu_t* emu, void* addr, int code)
|
||||
elfname = ElfName(elf);
|
||||
printf_log(LOG_NONE, "Emit Divide by 0 at IP=%p(%s / %s) / addr=%p\n", (void*)R_RIP, x64name?x64name:"???", elfname?elfname:"?", addr);
|
||||
}
|
||||
my_sigactionhandler_oldcode(emu, SIGSEGV, 0, &info, NULL, NULL, NULL);
|
||||
my_sigactionhandler_oldcode(emu, SIGSEGV, 0, &info, NULL, NULL, NULL, R_RIP);
|
||||
}
|
||||
|
||||
EXPORT sighandler_t my_signal(x64emu_t* emu, int signum, sighandler_t handler)
|
||||
|
Loading…
x
Reference in New Issue
Block a user