From e8f6156df331e1073e4a69dfa73abc2c5db4bde6 Mon Sep 17 00:00:00 2001 From: baldurk Date: Mon, 26 Oct 2020 10:19:42 +0000 Subject: [PATCH] Compile fixes in linux process handling --- renderdoc/os/posix/linux/linux_process.cpp | 50 +++++++++++++++++++--- 1 file changed, 43 insertions(+), 7 deletions(-) diff --git a/renderdoc/os/posix/linux/linux_process.cpp b/renderdoc/os/posix/linux/linux_process.cpp index e36f54b16..2ffb25103 100644 --- a/renderdoc/os/posix/linux/linux_process.cpp +++ b/renderdoc/os/posix/linux/linux_process.cpp @@ -25,6 +25,7 @@ #include #include #include +#include #include #include #include @@ -190,17 +191,50 @@ static uint64_t get_nanotime() return ret; } +#if defined(__arm__) + +// for some reason arm doesn't have the same struct name. Sigh :( +#define user_regs_struct user_regs + +#define INST_PTR_REG ARM_pc + +#define BREAK_INST 0xe7f001f0ULL +#define BREAK_INST_BYTES_SIZE 4 +// on ARM seemingly the instruction isn't actually considered executed, so we don't have to modify +// the instruction pointer at all. +#define BREAK_INST_INST_PTR_ADJUST 0 + +#elif defined(__aarch64__) + +#define INST_PTR_REG pc + +#define BREAK_INST 0xd4200000ULL +#define BREAK_INST_BYTES_SIZE 4 +// on ARM seemingly the instruction isn't actually considered executed, so we don't have to modify +// the instruction pointer at all. +#define BREAK_INST_INST_PTR_ADJUST 0 + +#else + +#define BREAK_INST 0xccULL +#define BREAK_INST_BYTES_SIZE 1 +// step back over the instruction +#define BREAK_INST_INST_PTR_ADJUST 1 + #if ENABLED(RDOC_X64) #define INST_PTR_REG rip #else #define INST_PTR_REG eip #endif +#endif + static uint64_t get_child_ip(pid_t childPid) { user_regs_struct regs = {}; - long ptraceRet = ptrace(PTRACE_GETREGS, childPid, NULL, ®s); + iovec regs_iovec = {®s, sizeof(regs)}; + long ptraceRet = ptrace(PTRACE_GETREGSET, childPid, (void *)NT_PRSTATUS, ®s_iovec); if(ptraceRet == 0) return uint64_t(regs.INST_PTR_REG); @@ -278,7 +312,7 @@ bool StopChildAtMain(pid_t childPid) if(Linux_Debug_PtraceLogging()) RDCLOG("Child PID %u is stopped in StopAtMainInChild()", childPid); - long ptraceRet = 0; + int64_t ptraceRet = 0; // continue until exec ptraceRet = ptrace(PTRACE_SETOPTIONS, childPid, NULL, PTRACE_O_TRACEEXEC); @@ -437,7 +471,8 @@ bool StopChildAtMain(pid_t childPid) RDCLOG("Read word %llx from %p in child process %u running executable %s", (uint64_t)origEntryWord, entry, childPid, exepath.c_str()); - uint64_t breakpointWord = (origEntryWord & 0xffffffffffffff00ULL) | 0xccULL; + uint64_t breakpointWord = + (origEntryWord & (0xffffffffffffffffULL << (BREAK_INST_BYTES_SIZE * 8))) | BREAK_INST; // downcast back to long, if that means truncating ptraceRet = ptrace(PTRACE_POKETEXT, childPid, entry, (long)breakpointWord); RDCASSERTEQUAL(ptraceRet, 0); @@ -464,16 +499,17 @@ bool StopChildAtMain(pid_t childPid) user_regs_struct regs = {}; - ptraceRet = ptrace(PTRACE_GETREGS, childPid, NULL, ®s); + iovec regs_iovec = {®s, sizeof(regs)}; + ptraceRet = ptrace(PTRACE_GETREGSET, childPid, (void *)NT_PRSTATUS, ®s_iovec); RDCASSERTEQUAL(ptraceRet, 0); if(Linux_Debug_PtraceLogging()) RDCLOG("Process %u instruction pointer is at %llx, for entry point %p", childPid, (uint64_t)(regs.INST_PTR_REG), entry); - // step back past the byte we inserted the breakpoint on - regs.INST_PTR_REG--; - ptraceRet = ptrace(PTRACE_SETREGS, childPid, NULL, ®s); + // step back past the byte(s) we inserted the breakpoint on + regs.INST_PTR_REG -= BREAK_INST_INST_PTR_ADJUST; + ptraceRet = ptrace(PTRACE_SETREGSET, childPid, (void *)NT_PRSTATUS, ®s_iovec); RDCASSERTEQUAL(ptraceRet, 0); // restore the function