diff options
-rw-r--r-- | agent/machine/arm/tcf/cpudefs-mdep.c | 22 | ||||
-rw-r--r-- | agent/system/GNU/Linux/tcf/context-linux.c | 30 |
2 files changed, 37 insertions, 15 deletions
diff --git a/agent/machine/arm/tcf/cpudefs-mdep.c b/agent/machine/arm/tcf/cpudefs-mdep.c index 30f67fff..e4794440 100644 --- a/agent/machine/arm/tcf/cpudefs-mdep.c +++ b/agent/machine/arm/tcf/cpudefs-mdep.c @@ -107,6 +107,7 @@ RegisterDefinition * regs_index = NULL; static unsigned regs_cnt = 0; static unsigned regs_max = 0; +/* Note: don't use BKPT instruction - it is not supported by 32-bit Linux kernel */ unsigned char BREAK_INST[] = { 0xf0, 0x01, 0xf0, 0xe7 }; static RegisterDefinition * pc_def = NULL; @@ -1104,7 +1105,7 @@ static int arm_get_next_address(Context * ctx, ContextExtensionARM * ext) { } } - ext->step_to_thumb = to_thumb; + ext->step_to_thumb = to_thumb || (arm_next & 2) != 0; ext->step_addr = arm_next; return 0; } @@ -1115,17 +1116,28 @@ static int enable_sw_stepping_mode(Context * ctx) { assert(!grp->exited); assert(!ext->sw_stepping); if (arm_get_next_address(ctx, ext) < 0) return -1; - trace(LOG_CONTEXT, "enable_sw_stepping_mode %s 0x%08x", ctx->id, (unsigned)ext->step_addr); + trace(LOG_CONTEXT, "enable_sw_stepping_mode %s 0x%08x %d", ctx->id, (unsigned)ext->step_addr, ext->step_to_thumb); if (ext->step_to_thumb) { - static uint8_t bp_thumb[] = { 0x00, 0xbe }; +#if defined(__aarch64__) + static uint8_t bp_thumb[] = { 0x70, 0xbe }; +#else + /* Note: don't use BKPT instruction - it is not supported by 32-bit Linux kernel */ + static uint8_t bp_thumb[] = { 0x01, 0xde }; +#endif ext->opcode_size = sizeof(bp_thumb); if (context_read_mem(grp, ext->step_addr, ext->opcode, ext->opcode_size) < 0) return -1; if (context_write_mem(grp, ext->step_addr, bp_thumb, ext->opcode_size) < 0) return -1; } else { - ext->opcode_size = sizeof(BREAK_INST); +#if defined(__aarch64__) + static uint8_t bp_arm[] = { 0x70, 0xbe, 0x20, 0xe1 }; +#else + /* Note: don't use BKPT instruction - it is not supported by 32-bit Linux kernel */ + static uint8_t bp_arm[] = { 0xf0, 0x01, 0xf0, 0xe7 }; +#endif + ext->opcode_size = sizeof(bp_arm); if (context_read_mem(grp, ext->step_addr, ext->opcode, ext->opcode_size) < 0) return -1; - if (context_write_mem(grp, ext->step_addr, BREAK_INST, ext->opcode_size) < 0) return -1; + if (context_write_mem(grp, ext->step_addr, bp_arm, ext->opcode_size) < 0) return -1; } ext->sw_stepping = 1; run_ctrl_lock(); diff --git a/agent/system/GNU/Linux/tcf/context-linux.c b/agent/system/GNU/Linux/tcf/context-linux.c index d07fd2f7..e6d304bd 100644 --- a/agent/system/GNU/Linux/tcf/context-linux.c +++ b/agent/system/GNU/Linux/tcf/context-linux.c @@ -1187,6 +1187,14 @@ int context_get_isa(Context * ctx, ContextAddress addr, ContextISA * isa) { isa->max_instruction_size = 15; } else if (strcmp(s, "ARM") == 0) { +#if defined(__aarch64__) + static uint8_t bp_arm[] = { 0x70, 0xbe, 0x20, 0xe1 }; +#else + /* Note: don't use BKPT instruction - it is not supported by 32-bit Linux kernel */ + static uint8_t bp_arm[] = { 0xf0, 0x01, 0xf0, 0xe7 }; +#endif + isa->bp_encoding = bp_arm; + isa->bp_size = sizeof(bp_arm); isa->max_instruction_size = 4; isa->alignment = 4; } @@ -1195,9 +1203,14 @@ int context_get_isa(Context * ctx, ContextAddress addr, ContextISA * isa) { isa->alignment = 4; } else if (strcmp(s, "Thumb") == 0 || strcmp(s, "ThumbEE") == 0) { - static uint8_t bp_thumb[] = { 0x00, 0xbe }; +#if defined(__aarch64__) + static uint8_t bp_thumb[] = { 0x70, 0xbe }; +#else + /* Note: don't use BKPT instruction - it is not supported by 32-bit Linux kernel */ + static uint8_t bp_thumb[] = { 0x01, 0xde }; +#endif isa->bp_encoding = bp_thumb; - isa->bp_size = 2; + isa->bp_size = sizeof(bp_thumb); isa->max_instruction_size = 4; isa->alignment = 2; } @@ -1597,9 +1610,8 @@ static void event_pid_stopped(pid_t pid, int signal, int event, int syscall) { if (signal != SIGSTOP && signal != SIGTRAP) { sigset_set(&ctx->pending_signals, signal, 1); #if defined(__arm__) - /* On ARM, Linux kernel appears to use SIGILL to lazily enable vector registers */ if (signal == SIGILL && !EXT(ctx->mem)->crt0_done) { - /* Ignore */ + /* On ARM, Linux kernel appears to use SIGILL to lazily enable vector registers */ } else #endif @@ -1621,12 +1633,12 @@ static void event_pid_stopped(pid_t pid, int signal, int event, int syscall) { get_PC(ctx, &pc0); + memset(ext->regs_valid, 0, sizeof(REG_SET)); #if defined(__powerpc__) || defined(__powerpc64__) /* Don't retrieve registers from an exiting process, causes kernel critical messages */ if (event != PTRACE_EVENT_EXIT) #endif - memset(ext->regs_valid, 0, sizeof(REG_SET)); get_PC(ctx, &pc1); if (syscall) { @@ -1833,11 +1845,9 @@ static int cmp_linux_tid(Context * ctx, const char * v) { } static int cmp_linux_kernel_name(Context * ctx, const char * v) { - struct utsname un; - if (uname(&un) != 0) { - return 0; - } - return (strcmp(un.sysname, v)== 0); + struct utsname buf; + if (uname(&buf) != 0) return 0; + return strcmp(buf.sysname, v) == 0; } void init_contexts_sys_dep(void) { |