summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMark Wielaard <mjw@redhat.com>2009-08-06 10:41:46 +0200
committerMark Wielaard <mjw@redhat.com>2009-08-06 10:41:46 +0200
commit3d9889977397098d14c5be50f1dfef1c3eeb508f (patch)
tree7b9b3d345b5d126113ab3220ae93e5373b422d75
parent68d47ee749911aa9babdfe37efd85db115e316be (diff)
downloadsystemtap-steved-3d9889977397098d14c5be50f1dfef1c3eeb508f.tar.gz
systemtap-steved-3d9889977397098d14c5be50f1dfef1c3eeb508f.tar.xz
systemtap-steved-3d9889977397098d14c5be50f1dfef1c3eeb508f.zip
PR10491 Don't assign to REG_IP if it isn't an lvalue (s390 and ia64).
To fixup REG_IP to show the correct value after a [ku]probe trap we assigned the address of the actual instruction pointer of the probed instruction. That doesn't work on architectures, s390 and ia64, where REG_IP is not a simple lvalue. Just don't try to fixup the address in those cases. If this isn't enough, the uprobe_stmt_num.exp testcase will point this out. * runtime/regs.h: Define REG_IP_LVALUE for x86_64, i386, powerpc64 and arm. * tapsets.cxx (dwarf_derived_probe_group::emit_module_decls): Only fixup REG_IP when REG_IP_LVALUE is defined. (uprobe_derived_probe_group::emit_module_decls): Likewise. (kprobe_derived_probe_group::emit_module_decls): Likewise.
-rw-r--r--runtime/regs.h5
-rw-r--r--tapsets.cxx30
2 files changed, 35 insertions, 0 deletions
diff --git a/runtime/regs.h b/runtime/regs.h
index 123d7601..d80cdf0a 100644
--- a/runtime/regs.h
+++ b/runtime/regs.h
@@ -13,17 +13,20 @@
#if defined (STAPCONF_X86_UNIREGS) && (defined (__x86_64__) || defined (__i386__))
#define REG_IP(regs) regs->ip
+#define REG_IP_LVALUE 1
#define REG_SP(regs) regs->sp
#define REG_FP(regs) regs->bp
#elif defined (__x86_64__)
#define REG_IP(regs) regs->rip
+#define REG_IP_LVALUE 1
#define REG_SP(regs) regs->rsp
#elif defined (__i386__)
#define REG_IP(regs) regs->eip
+#define REG_IP_LVALUE 1
#define REG_SP(regs) regs->esp
#define REG_FP(regs) regs->ebp
@@ -34,12 +37,14 @@
#elif defined (__powerpc64__)
#define REG_IP(regs) regs->nip
+#define REG_IP_LVALUE 1
#define REG_SP(regs) regs->gpr[1]
#define REG_LINK(regs) regs->link
#elif defined (__arm__)
#define REG_IP(regs) regs->ARM_pc
+#define REG_IP_LVALUE 1
#define REG_SP(regs) regs->ARM_sp
#define REG_LINK(regs) regs->ARM_lr
diff --git a/tapsets.cxx b/tapsets.cxx
index b1ca2998..66cb2383 100644
--- a/tapsets.cxx
+++ b/tapsets.cxx
@@ -3030,6 +3030,8 @@ dwarf_derived_probe_group::emit_module_decls (systemtap_session& s)
// Make it look like the IP is set as it wouldn't have been replaced
// by a breakpoint instruction when calling real probe handler. Reset
// IP regs on return, so we don't confuse kprobes. PR10458
+ // But only for architectures where REG_IP is a proper lvalue. PR10491
+ s.op->newline() << "#ifdef REG_IP_LVALUE";
s.op->newline() << "{";
s.op->indent(1);
s.op->newline() << "unsigned long kprobes_ip = REG_IP(c->regs);";
@@ -3037,6 +3039,9 @@ dwarf_derived_probe_group::emit_module_decls (systemtap_session& s)
s.op->newline() << "(*sdp->ph) (c);";
s.op->newline() << "REG_IP(regs) = kprobes_ip;";
s.op->newline(-1) << "}";
+ s.op->newline() << "#else";
+ s.op->newline() << "(*sdp->ph) (c);";
+ s.op->newline() << "#endif";
common_probe_entryfn_epilogue (s.op);
s.op->newline() << "return 0;";
@@ -3064,6 +3069,8 @@ dwarf_derived_probe_group::emit_module_decls (systemtap_session& s)
// Make it look like the IP is set as it wouldn't have been replaced
// by a breakpoint instruction when calling real probe handler. Reset
// IP regs on return, so we don't confuse kprobes. PR10458
+ // But only for architectures where REG_IP is a proper lvalue. PR10491
+ s.op->newline() << "#ifdef REG_IP_LVALUE";
s.op->newline() << "{";
s.op->indent(1);
s.op->newline() << "unsigned long kprobes_ip = REG_IP(c->regs);";
@@ -3071,6 +3078,9 @@ dwarf_derived_probe_group::emit_module_decls (systemtap_session& s)
s.op->newline() << "(*sdp->ph) (c);";
s.op->newline() << "REG_IP(regs) = kprobes_ip;";
s.op->newline(-1) << "}";
+ s.op->newline() << "#else";
+ s.op->newline() << "(*sdp->ph) (c);";
+ s.op->newline() << "#endif";
common_probe_entryfn_epilogue (s.op);
s.op->newline() << "return 0;";
@@ -4447,6 +4457,8 @@ uprobe_derived_probe_group::emit_module_decls (systemtap_session& s)
// Make it look like the IP is set as it would in the actual user
// task when calling real probe handler. Reset IP regs on return, so
// we don't confuse uprobes. PR10458
+ // But only for architectures where REG_IP is a proper lvalue. PR10491
+ s.op->newline() << "#ifdef REG_IP_LVALUE";
s.op->newline() << "{";
s.op->indent(1);
s.op->newline() << "unsigned long uprobes_ip = REG_IP(c->regs);";
@@ -4454,6 +4466,9 @@ uprobe_derived_probe_group::emit_module_decls (systemtap_session& s)
s.op->newline() << "(*sups->ph) (c);";
s.op->newline() << "REG_IP(regs) = uprobes_ip;";
s.op->newline(-1) << "}";
+ s.op->newline() << "#else";
+ s.op->newline() << "(*sdp->ph) (c);";
+ s.op->newline() << "#endif";
common_probe_entryfn_epilogue (s.op);
s.op->newline(-1) << "}";
@@ -4470,6 +4485,8 @@ uprobe_derived_probe_group::emit_module_decls (systemtap_session& s)
// Make it look like the IP is set as it would in the actual user
// task when calling real probe handler. Reset IP regs on return, so
// we don't confuse uprobes. PR10458
+ // But only for architectures where REG_IP is a proper lvalue. PR10491
+ s.op->newline() << "#ifdef REG_IP_LVALUE";
s.op->newline() << "{";
s.op->indent(1);
s.op->newline() << "unsigned long uprobes_ip = REG_IP(c->regs);";
@@ -4477,6 +4494,9 @@ uprobe_derived_probe_group::emit_module_decls (systemtap_session& s)
s.op->newline() << "(*sups->ph) (c);";
s.op->newline() << "REG_IP(regs) = uprobes_ip;";
s.op->newline(-1) << "}";
+ s.op->newline() << "#else";
+ s.op->newline() << "(*sdp->ph) (c);";
+ s.op->newline() << "#endif";
common_probe_entryfn_epilogue (s.op);
s.op->newline(-1) << "}";
@@ -4970,6 +4990,8 @@ kprobe_derived_probe_group::emit_module_decls (systemtap_session& s)
// Make it look like the IP is set as it wouldn't have been replaced
// by a breakpoint instruction when calling real probe handler. Reset
// IP regs on return, so we don't confuse kprobes. PR10458
+ // But only for architectures where REG_IP is a proper lvalue. PR10491
+ s.op->newline() << "#ifdef REG_IP_LVALUE";
s.op->newline() << "{";
s.op->indent(1);
s.op->newline() << "unsigned long kprobes_ip = REG_IP(c->regs);";
@@ -4977,6 +4999,9 @@ kprobe_derived_probe_group::emit_module_decls (systemtap_session& s)
s.op->newline() << "(*sdp->ph) (c);";
s.op->newline() << "REG_IP(regs) = kprobes_ip;";
s.op->newline(-1) << "}";
+ s.op->newline() << "#else";
+ s.op->newline() << "(*sdp->ph) (c);";
+ s.op->newline() << "#endif";
common_probe_entryfn_epilogue (s.op);
s.op->newline() << "return 0;";
@@ -5004,6 +5029,8 @@ kprobe_derived_probe_group::emit_module_decls (systemtap_session& s)
// Make it look like the IP is set as it wouldn't have been replaced
// by a breakpoint instruction when calling real probe handler. Reset
// IP regs on return, so we don't confuse kprobes. PR10458
+ // But only for architectures where REG_IP is a proper lvalue. PR10491
+ s.op->newline() << "#ifdef REG_IP_LVALUE";
s.op->newline() << "{";
s.op->indent(1);
s.op->newline() << "unsigned long kprobes_ip = REG_IP(c->regs);";
@@ -5011,6 +5038,9 @@ kprobe_derived_probe_group::emit_module_decls (systemtap_session& s)
s.op->newline() << "(*sdp->ph) (c);";
s.op->newline() << "REG_IP(regs) = kprobes_ip;";
s.op->newline(-1) << "}";
+ s.op->newline() << "#else";
+ s.op->newline() << "(*sdp->ph) (c);";
+ s.op->newline() << "#endif";
common_probe_entryfn_epilogue (s.op);
s.op->newline() << "return 0;";