Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--agent/machine/arm/tcf/cpudefs-mdep.c22
-rw-r--r--agent/system/GNU/Linux/tcf/context-linux.c30
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) {

Back to the top