Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEugene Tarassov2013-03-28 00:24:01 +0000
committerEugene Tarassov2013-03-28 00:24:01 +0000
commite1402d80a7144dbfcae8eec40d9d7340e8f1222d (patch)
tree4edcc6719b87403b25a86d3c7807a166a4927824
parent9aa27e8ae7648132594246b28e8c7bc99df26ebd (diff)
downloadorg.eclipse.tcf.agent-e1402d80a7144dbfcae8eec40d9d7340e8f1222d.tar.gz
org.eclipse.tcf.agent-e1402d80a7144dbfcae8eec40d9d7340e8f1222d.tar.xz
org.eclipse.tcf.agent-e1402d80a7144dbfcae8eec40d9d7340e8f1222d.zip
TCF Agent: fixed access to ARM debug registers on Linux
-rw-r--r--agent/machine/arm/tcf/cpudefs-mdep.c48
-rw-r--r--agent/machine/arm/tcf/regset-mdep.h4
2 files changed, 26 insertions, 26 deletions
diff --git a/agent/machine/arm/tcf/cpudefs-mdep.c b/agent/machine/arm/tcf/cpudefs-mdep.c
index cba02f4c..756709e5 100644
--- a/agent/machine/arm/tcf/cpudefs-mdep.c
+++ b/agent/machine/arm/tcf/cpudefs-mdep.c
@@ -57,7 +57,7 @@ RegisterDefinition regs_def[] = {
{ "cpsr", REG_OFFSET(user.regs.uregs[16]), 4, -1, -1},
{ "orig_r0", REG_OFFSET(user.regs.uregs[17]), 4, -1, -1},
{ "debug", 0, 0, -1, -1, 0, 0, 1, 1 }, /* 18 */
- { "bp_info", REG_OFFSET(other.bp_info), 4, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, regs_def + 18},
+ { "bp_info", REG_OFFSET(other.bp_info), 4, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, regs_def + 18},
{ "bvr0", REG_OFFSET(other.bp[0].vr), 4, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, regs_def + 18},
{ "bcr0", REG_OFFSET(other.bp[0].cr), 4, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, regs_def + 18},
{ NULL, 0, 0, 0, 0},
@@ -80,45 +80,43 @@ static RegisterDefinition * cpsr_def = NULL;
#if !defined(PTRACE_SETHBPREGS)
#define PTRACE_SETHBPREGS 30
#endif
-#define MAX_HWP 1
-static int offset_to_regnum(size_t offset) {
- int bp_id = (offset - 4) >> 3;
- int reg_offset = 1 + (((offset - 4) >> 2) & 1);
- if (offset == 0) return 0;
- trace (LOG_ALWAYS,"offset_to_regnum offset %x, bp_id %x, reg_offset %x", offset, bp_id, reg_offset);
- if (bp_id >= MAX_HWP) return - (((bp_id - MAX_HWP) << 1) + reg_offset);
- return (bp_id << 1) + reg_offset;
+static int offset_to_regnum(size_t offset, size_t * done_offs) {
+ assert(sizeof(user_hbpreg_struct) == 8);
+ if (offset >= REG_OFFSET(other.bp) && offset < REG_OFFSET(other.bp) + MAX_HBP * 8) {
+ int idx = (offset - REG_OFFSET(other.bp)) / 4;
+ *done_offs = REG_OFFSET(other.bp) + idx * 4;
+ return 1 + idx;
+ }
+ if (offset >= REG_OFFSET(other.wp) && offset < REG_OFFSET(other.wp) + MAX_HWP * 8) {
+ int idx = (offset - REG_OFFSET(other.wp)) / 4;
+ *done_offs = REG_OFFSET(other.wp) + idx * 4;
+ return -idx;
+ }
+ *done_offs = REG_OFFSET(other.bp_info);
+ return 0;
}
int mdep_get_other_regs(pid_t pid, REG_SET * data,
size_t data_offs, size_t data_size,
size_t * done_offs, size_t * done_size) {
- size_t size = 0;
+ int reg_num = 0;
assert(data_offs >= offsetof(REG_SET, other));
assert(data_offs + data_size <= offsetof(REG_SET, other) + sizeof(data->other));
- /* bp registers can only be accessed 1 at a time */
- for (size = data_offs - offsetof(REG_SET, other); size < sizeof(data->other); size += 4) {
- trace (LOG_ALWAYS,"get_other_registers %x", offset_to_regnum(size));
- if (ptrace(PTRACE_GETHBPREGS, pid, offset_to_regnum (size), (char *)&data->other + size) < 0) return -1;
- }
- *done_offs = offsetof(REG_SET, other);
- *done_size = sizeof(data->other);
+ reg_num = offset_to_regnum(data_offs, done_offs);
+ if (ptrace(PTRACE_GETHBPREGS, pid, reg_num, (char *)data + *done_offs) < 0) return -1;
+ *done_size = 4;
return 0;
}
int mdep_set_other_regs(pid_t pid, REG_SET * data,
size_t data_offs, size_t data_size,
size_t * done_offs, size_t * done_size) {
- size_t size = 0;
+ int reg_num = 0;
assert(data_offs >= offsetof(REG_SET, other));
assert(data_offs + data_size <= offsetof(REG_SET, other) + sizeof(data->other));
- /* bp registers can only be accessed 1 at a time */
- for (size = data_offs - offsetof(REG_SET, other); size < data_offs + data_size - offsetof(REG_SET, other); size += 4) {
- trace (LOG_ALWAYS,"set_other_registers %x", offset_to_regnum(size));
- if (ptrace(PTRACE_SETHBPREGS, pid, offset_to_regnum(size), (char *)&data->other + size) < 0) return -1;
- }
- *done_offs = offsetof(REG_SET, other);
- *done_size = sizeof(data->other);
+ reg_num = offset_to_regnum(data_offs, done_offs);
+ if (ptrace(PTRACE_SETHBPREGS, pid, reg_num, (char *)data + *done_offs) < 0) return -1;
+ *done_size = 4;
return 0;
}
diff --git a/agent/machine/arm/tcf/regset-mdep.h b/agent/machine/arm/tcf/regset-mdep.h
index b3b4c790..1b12de8f 100644
--- a/agent/machine/arm/tcf/regset-mdep.h
+++ b/agent/machine/arm/tcf/regset-mdep.h
@@ -18,6 +18,8 @@
#define TRAP_OFFSET 0
#define MAX_HBP 1
+#define MAX_HWP 1
+
typedef struct {
uint32_t vr;
uint32_t cr;
@@ -26,7 +28,7 @@ typedef struct {
struct user_hbpregs_struct {
uint32_t bp_info;
user_hbpreg_struct bp[MAX_HBP];
-// user_hbpreg_struct wp[MAX_HBP];
+ user_hbpreg_struct wp[MAX_HWP];
};
/* additional CPU registers */

Back to the top