cc: introduce helpers to access pt_regs in an arch-independent manner

Convert some of the examples and tools to use the new helpers.

Signed-off-by: Naveen N. Rao <naveen.n.rao@linux.vnet.ibm.com>
diff --git a/examples/lua/bashreadline.c b/examples/lua/bashreadline.c
index 0fab6f7..fad33d7 100644
--- a/examples/lua/bashreadline.c
+++ b/examples/lua/bashreadline.c
@@ -11,11 +11,11 @@
 {
 	struct str_t data  = {};
 	u32 pid;
-	if (!ctx->ax)
-		return 0;
-	pid = bpf_get_current_pid_tgid();
-	data.pid = pid;
-	bpf_probe_read(&data.str, sizeof(data.str), (void *)ctx->ax);
-	events.perf_submit(ctx,&data,sizeof(data));
-	return 0;
+        if (!PT_REGS_RC(ctx))
+          return 0;
+        pid = bpf_get_current_pid_tgid();
+        data.pid = pid;
+        bpf_probe_read(&data.str, sizeof(data.str), (void *)PT_REGS_RC(ctx));
+        events.perf_submit(ctx, &data, sizeof(data));
+        return 0;
 };
diff --git a/examples/lua/memleak.lua b/examples/lua/memleak.lua
index 71ef90d..27023aa 100755
--- a/examples/lua/memleak.lua
+++ b/examples/lua/memleak.lua
@@ -48,7 +48,7 @@
 
 int alloc_exit(struct pt_regs *ctx)
 {
-        u64 address = ctx->ax;
+        u64 address = PT_REGS_RC(ctx);
         u64 pid = bpf_get_current_pid_tgid();
         u64* size64 = sizes.lookup(&pid);
         struct alloc_info_t info = {0};
diff --git a/examples/lua/strlen_count.lua b/examples/lua/strlen_count.lua
index 6438d4e..553d043 100755
--- a/examples/lua/strlen_count.lua
+++ b/examples/lua/strlen_count.lua
@@ -20,13 +20,13 @@
 local program = string.gsub([[
 #include <uapi/linux/ptrace.h>
 int printarg(struct pt_regs *ctx) {
-  if (!ctx->di)
+  if (!PT_REGS_PARM1(ctx))
     return 0;
   u32 pid = bpf_get_current_pid_tgid();
   if (pid != PID)
     return 0;
   char str[128] = {};
-  bpf_probe_read(&str, sizeof(str), (void *)ctx->di);
+  bpf_probe_read(&str, sizeof(str), (void *)PT_REGS_PARM1(ctx));
   bpf_trace_printk("strlen(\"%s\")\n", &str);
   return 0;
 };
diff --git a/examples/tracing/strlen_count.py b/examples/tracing/strlen_count.py
index bc456fb..dfc98d3 100755
--- a/examples/tracing/strlen_count.py
+++ b/examples/tracing/strlen_count.py
@@ -24,13 +24,13 @@
 BPF_HASH(counts, struct key_t);
 
 int count(struct pt_regs *ctx) {
-    if (!ctx->si)
+    if (!PT_REGS_PARM2(ctx))
         return 0;
 
     struct key_t key = {};
     u64 zero = 0, *val;
 
-    bpf_probe_read(&key.c, sizeof(key.c), (void *)ctx->si);
+    bpf_probe_read(&key.c, sizeof(key.c), (void *)PT_REGS_PARM2(ctx));
     val = counts.lookup_or_init(&key, &zero);
     (*val)++;
     return 0;
diff --git a/examples/tracing/strlen_hist.py b/examples/tracing/strlen_hist.py
index cc80ead..65f7c73 100755
--- a/examples/tracing/strlen_hist.py
+++ b/examples/tracing/strlen_hist.py
@@ -37,7 +37,7 @@
 #include <uapi/linux/ptrace.h>
 BPF_HISTOGRAM(dist);
 int count(struct pt_regs *ctx) {
-    dist.increment(bpf_log2l(ctx->ax));
+    dist.increment(bpf_log2l(PT_REGS_RC(ctx)));
     return 0;
 }
 """
diff --git a/examples/tracing/strlen_snoop.py b/examples/tracing/strlen_snoop.py
index a75164e..9ee058a 100755
--- a/examples/tracing/strlen_snoop.py
+++ b/examples/tracing/strlen_snoop.py
@@ -26,7 +26,7 @@
 bpf_text = """
 #include <uapi/linux/ptrace.h>
 int printarg(struct pt_regs *ctx) {
-    if (!ctx->si)
+    if (!PT_REGS_PARM2(ctx))
         return 0;
 
     u32 pid = bpf_get_current_pid_tgid();
@@ -34,7 +34,7 @@
         return 0;
 
     char str[80] = {};
-    bpf_probe_read(&str, sizeof(str), (void *)ctx->si);
+    bpf_probe_read(&str, sizeof(str), (void *)PT_REGS_PARM2(ctx));
     bpf_trace_printk("%s\\n", &str);
 
     return 0;
diff --git a/examples/tracing/tcpv4connect.py b/examples/tracing/tcpv4connect.py
index 6841115..036ef72 100755
--- a/examples/tracing/tcpv4connect.py
+++ b/examples/tracing/tcpv4connect.py
@@ -37,7 +37,7 @@
 
 int kretprobe__tcp_v4_connect(struct pt_regs *ctx)
 {
-	int ret = ctx->ax;
+	int ret = PT_REGS_RC(ctx);
 	u32 pid = bpf_get_current_pid_tgid();
 
 	struct sock **skpp;
diff --git a/src/cc/export/helpers.h b/src/cc/export/helpers.h
index bdb5f75..86fd88f 100644
--- a/src/cc/export/helpers.h
+++ b/src/cc/export/helpers.h
@@ -410,5 +410,29 @@
 
 #define lock_xadd(ptr, val) ((void)__sync_fetch_and_add(ptr, val))
 
+#ifdef __powerpc__
+#define PT_REGS_PARM1(ctx)	((ctx)->gpr[3])
+#define PT_REGS_PARM2(ctx)	((ctx)->gpr[4])
+#define PT_REGS_PARM3(ctx)	((ctx)->gpr[5])
+#define PT_REGS_PARM4(ctx)	((ctx)->gpr[6])
+#define PT_REGS_PARM5(ctx)	((ctx)->gpr[7])
+#define PT_REGS_PARM6(ctx)	((ctx)->gpr[8])
+#define PT_REGS_RC(ctx)		((ctx)->gpr[3])
+#define PT_REGS_IP(ctx)		((ctx)->nip)
+#define PT_REGS_SP(ctx)		((ctx)->sp)
+#elif defined(__x86_64__)
+#define PT_REGS_PARM1(ctx)	((ctx)->di)
+#define PT_REGS_PARM2(ctx)	((ctx)->si)
+#define PT_REGS_PARM3(ctx)	((ctx)->dx)
+#define PT_REGS_PARM4(ctx)	((ctx)->cx)
+#define PT_REGS_PARM5(ctx)	((ctx)->r8)
+#define PT_REGS_PARM6(ctx)	((ctx)->r9)
+#define PT_REGS_RC(ctx)		((ctx)->ax)
+#define PT_REGS_IP(ctx)		((ctx)->ip)
+#define PT_REGS_SP(ctx)		((ctx)->sp)
+#else
+#error "bcc does not support this platform yet"
+#endif
+
 #endif
 )********"
diff --git a/src/python/bcc/tracepoint.py b/src/python/bcc/tracepoint.py
index 57807a8..70867d4 100644
--- a/src/python/bcc/tracepoint.py
+++ b/src/python/bcc/tracepoint.py
@@ -99,7 +99,7 @@
 int __trace_entry_update(struct pt_regs *ctx)
 {
         u64 tid = bpf_get_current_pid_tgid();
-        u64 val = ctx->di;
+        u64 val = PT_REGS_PARM1(ctx);
         __trace_di.update(&tid, &val);
         return 0;
 }
diff --git a/tests/python/test_trace2.c b/tests/python/test_trace2.c
index 0c21960..4c6ff33 100644
--- a/tests/python/test_trace2.c
+++ b/tests/python/test_trace2.c
@@ -6,7 +6,7 @@
 BPF_TABLE("hash", struct Ptr, struct Counters, stats, 1024);
 
 int count_sched(struct pt_regs *ctx) {
-  struct Ptr key = {.ptr=ctx->bx};
+  struct Ptr key = {.ptr = PT_REGS_PARM1(ctx)};
   struct Counters zleaf = {0};
   stats.lookup_or_init(&key, &zleaf)->stat1++;
   return 0;
diff --git a/tests/python/test_trace2.py b/tests/python/test_trace2.py
index 92a60fc..c400c08 100755
--- a/tests/python/test_trace2.py
+++ b/tests/python/test_trace2.py
@@ -15,11 +15,7 @@
 BPF_TABLE("hash", struct Ptr, struct Counters, stats, 1024);
 
 int count_sched(struct pt_regs *ctx) {
-#if defined(__powerpc__)
-  struct Ptr key = {.ptr=ctx->gpr[3]};
-#else
-  struct Ptr key = {.ptr=ctx->bx};
-#endif
+  struct Ptr key = {.ptr=PT_REGS_PARM1(ctx)};
   struct Counters zleaf = {0};
   stats.lookup_or_init(&key, &zleaf)->stat1++;
   return 0;
diff --git a/tests/python/test_trace3.c b/tests/python/test_trace3.c
index 50ec3a2..ebce261 100644
--- a/tests/python/test_trace3.c
+++ b/tests/python/test_trace3.c
@@ -28,22 +28,14 @@
 }
 
 int probe_blk_start_request(struct pt_regs *ctx) {
-#if defined(__powerpc__)
-  struct Request rq = {.rq = ctx->gpr[3]};
-#else
-  struct Request rq = {.rq = ctx->di};
-#endif
+  struct Request rq = {.rq = PT_REGS_PARM1(ctx)};
   struct Time tm = {.start = bpf_ktime_get_ns()};
   requests.update(&rq, &tm);
   return 0;
 }
 
 int probe_blk_update_request(struct pt_regs *ctx) {
-#if defined(__powerpc__)
-  struct Request rq = {.rq = ctx->gpr[3]};
-#else
-  struct Request rq = {.rq = ctx->di};
-#endif
+  struct Request rq = {.rq = PT_REGS_PARM1(ctx)};
   struct Time *tm = requests.lookup(&rq);
   if (!tm) return 0;
   u64 delta = bpf_ktime_get_ns() - tm->start;
diff --git a/tools/argdist.py b/tools/argdist.py
index 124ce40..89f57c3 100755
--- a/tools/argdist.py
+++ b/tools/argdist.py
@@ -264,7 +264,7 @@
         def _substitute_exprs(self):
                 def repl(expr):
                         expr = self._substitute_aliases(expr)
-                        return expr.replace("$retval", "ctx->ax")
+                        return expr.replace("$retval", "PT_REGS_RC(ctx)")
                 for i in range(0, len(self.exprs)):
                         self.exprs[i] = repl(self.exprs[i])
                 self.filter = repl(self.filter)
@@ -445,7 +445,7 @@
                 for alias, subst in Probe.aliases.items():
                         expr = expr.replace(subst, alias)
                 # Replace retval expression with $retval
-                expr = expr.replace("ctx->ax", "$retval")
+                expr = expr.replace("PT_REGS_RC(ctx)", "$retval")
                 # Replace ugly (*__param_val) expressions with param name
                 return re.sub(r"\(\*__(\w+)_val\)", r"\1", expr)
 
diff --git a/tools/bashreadline.py b/tools/bashreadline.py
index 984970a..2c1ff2a 100755
--- a/tools/bashreadline.py
+++ b/tools/bashreadline.py
@@ -30,11 +30,11 @@
 int printret(struct pt_regs *ctx) {
     struct str_t data  = {};
     u32 pid;
-    if (!ctx->ax)
+    if (!PT_REGS_RC(ctx))
         return 0;
     pid = bpf_get_current_pid_tgid();
     data.pid = pid;
-    bpf_probe_read(&data.str, sizeof(data.str), (void *)ctx->ax);
+    bpf_probe_read(&data.str, sizeof(data.str), (void *)PT_REGS_RC(ctx));
     events.perf_submit(ctx,&data,sizeof(data));
 
     return 0;
diff --git a/tools/btrfsslower.py b/tools/btrfsslower.py
index 44f4ab7..de0e3e0 100755
--- a/tools/btrfsslower.py
+++ b/tools/btrfsslower.py
@@ -210,7 +210,7 @@
     bpf_probe_read(&de, sizeof(de), &valp->fp->f_path.dentry);
 
     // populate output struct
-    u32 size = ctx->ax;
+    u32 size = PT_REGS_RC(ctx);
     struct data_t data = {.type = type, .size = size, .delta_us = delta_us,
         .pid = pid};
     data.ts_us = ts / 1000;
diff --git a/tools/cachestat.py b/tools/cachestat.py
index 71ee495..ed52c80 100755
--- a/tools/cachestat.py
+++ b/tools/cachestat.py
@@ -100,7 +100,7 @@
     u64 zero = 0, *val;
     u64 ip;
 
-    key.ip = ctx->ip;
+    key.ip = PT_REGS_IP(ctx);
     val = counts.lookup_or_init(&key, &zero);  // update counter
     (*val)++;
     return 0;
diff --git a/tools/dcsnoop.py b/tools/dcsnoop.py
index 6d3753f..75463be 100755
--- a/tools/dcsnoop.py
+++ b/tools/dcsnoop.py
@@ -86,7 +86,7 @@
     if (ep == 0) {
         return 0;   // missed entry
     }
-    if (ctx->ax == 0) {
+    if (PT_REGS_RC(ctx) == 0) {
         bpf_trace_printk("M %s\\n", ep->name);
     }
     entrybypid.delete(&pid);
diff --git a/tools/dcstat.py b/tools/dcstat.py
index 0da3967..26759fb 100755
--- a/tools/dcstat.py
+++ b/tools/dcstat.py
@@ -81,7 +81,7 @@
     int key = S_SLOW;
     u64 *leaf = stats.lookup(&key);
     if (leaf) (*leaf)++;
-    if (ctx->ax == 0) {
+    if (PT_REGS_RC(ctx) == 0) {
         key = S_MISS;
         leaf = stats.lookup(&key);
         if (leaf) (*leaf)++;
diff --git a/tools/execsnoop.py b/tools/execsnoop.py
index 93cf838..93b9215 100755
--- a/tools/execsnoop.py
+++ b/tools/execsnoop.py
@@ -105,7 +105,7 @@
 
 int kretprobe__sys_execve(struct pt_regs *ctx)
 {
-    bpf_trace_printk("RET %d\\n", ctx->ax);
+    bpf_trace_printk("RET %d\\n", PT_REGS_RC(ctx));
     return 0;
 }
 """
diff --git a/tools/ext4slower.py b/tools/ext4slower.py
index 55f8fa9..b0b72a5 100755
--- a/tools/ext4slower.py
+++ b/tools/ext4slower.py
@@ -205,7 +205,7 @@
     bpf_probe_read(&de, sizeof(de), &valp->fp->f_path.dentry);
 
     // populate output struct
-    u32 size = ctx->ax;
+    u32 size = PT_REGS_RC(ctx);
     struct data_t data = {.type = type, .size = size, .delta_us = delta_us,
         .pid = pid};
     data.ts_us = ts / 1000;
diff --git a/tools/funccount.py b/tools/funccount.py
index 427e7c1..fc949fe 100755
--- a/tools/funccount.py
+++ b/tools/funccount.py
@@ -68,7 +68,7 @@
     u64 *val;
     // the kprobe pc is slightly after the function starting address, align
     // back to the start (4 byte alignment) in order to match /proc/kallsyms
-    key.ip = ctx->ip & ~3ull;
+    key.ip = PT_REGS_IP(ctx) & ~3ull;
     val = counts.lookup(&key);
     if (!val)
         return 0;
diff --git a/tools/funclatency.py b/tools/funclatency.py
index 1968c94..f5618e0 100755
--- a/tools/funclatency.py
+++ b/tools/funclatency.py
@@ -132,7 +132,7 @@
         'BPF_HISTOGRAM(dist, ip_key_t);')
     # stash the IP on entry, as on return it's kretprobe_trampoline:
     bpf_text = bpf_text.replace('ENTRYSTORE',
-        'u64 ip = ctx->ip; ipaddr.update(&pid, &ip);')
+        'u64 ip = PT_REGS_IP(ctx); ipaddr.update(&pid, &ip);')
     bpf_text = bpf_text.replace('STORE',
         'u64 ip, *ipp = ipaddr.lookup(&pid); if (ipp) { ip = *ipp; ' +
         'dist.increment((ip_key_t){ip, bpf_log2l(delta)}); ' +
diff --git a/tools/gethostlatency.py b/tools/gethostlatency.py
index 79ec936..38120c6 100755
--- a/tools/gethostlatency.py
+++ b/tools/gethostlatency.py
@@ -44,14 +44,14 @@
 BPF_PERF_OUTPUT(events);
 
 int do_entry(struct pt_regs *ctx) {
-    if (!ctx->di)
+    if (!PT_REGS_PARM1(ctx))
         return 0;
 
     struct val_t val = {};
     u32 pid = bpf_get_current_pid_tgid();
 
     if (bpf_get_current_comm(&val.comm, sizeof(val.comm)) == 0) {
-        bpf_probe_read(&val.host, sizeof(val.host), (void *)ctx->di);
+        bpf_probe_read(&val.host, sizeof(val.host), (void *)PT_REGS_PARM1(ctx));
         val.pid = bpf_get_current_pid_tgid();
         val.ts = bpf_ktime_get_ns();
         start.update(&pid, &val);
diff --git a/tools/killsnoop.py b/tools/killsnoop.py
index f5f96a0..c57e1fa 100755
--- a/tools/killsnoop.py
+++ b/tools/killsnoop.py
@@ -98,7 +98,7 @@
     data.delta = tsp - valp->ts;
     data.ts = tsp / 1000;
     data.tpid = valp->tpid;
-    data.ret = ctx->ax;
+    data.ret = PT_REGS_RC(ctx);
     data.sig = valp->sig;
 
     events.perf_submit(ctx, &data, sizeof(data));
diff --git a/tools/memleak.py b/tools/memleak.py
index bc59b40..e8bf06f 100755
--- a/tools/memleak.py
+++ b/tools/memleak.py
@@ -191,7 +191,7 @@
 
 int alloc_exit(struct pt_regs *ctx)
 {
-        u64 address = ctx->ax;
+        u64 address = PT_REGS_RC(ctx);
         u64 pid = bpf_get_current_pid_tgid();
         u64* size64 = sizes.lookup(&pid);
         struct alloc_info_t info = {0};
diff --git a/tools/opensnoop.py b/tools/opensnoop.py
index e6fcb07..47f5713 100755
--- a/tools/opensnoop.py
+++ b/tools/opensnoop.py
@@ -97,7 +97,7 @@
     data.pid = valp->pid;
     data.delta = tsp - valp->ts;
     data.ts = tsp / 1000;
-    data.ret = ctx->ax;
+    data.ret = PT_REGS_RC(ctx);
 
     events.perf_submit(ctx, &data, sizeof(data));
     infotmp.delete(&pid);
diff --git a/tools/softirqs.py b/tools/softirqs.py
index 40545b3..dd24231 100755
--- a/tools/softirqs.py
+++ b/tools/softirqs.py
@@ -63,7 +63,7 @@
 int trace_start(struct pt_regs *ctx)
 {
     u32 pid = bpf_get_current_pid_tgid();
-    u64 ip = ctx->ip, ts = bpf_ktime_get_ns();
+    u64 ip = PT_REGS_IP(ctx), ts = bpf_ktime_get_ns();
     start.update(&pid, &ts);
     iptr.update(&pid, &ip);
     return 0;
diff --git a/tools/statsnoop.py b/tools/statsnoop.py
index cdf52f9..38455d5 100755
--- a/tools/statsnoop.py
+++ b/tools/statsnoop.py
@@ -97,7 +97,7 @@
     data.pid = valp->pid;
     data.delta = tsp - valp->ts;
     data.ts = tsp / 1000;
-    data.ret = ctx->ax;
+    data.ret = PT_REGS_RC(ctx);
 
     events.perf_submit(ctx, &data, sizeof(data));
     infotmp.delete(&pid);
diff --git a/tools/tcpaccept.py b/tools/tcpaccept.py
index 5c41e74..802f94f 100755
--- a/tools/tcpaccept.py
+++ b/tools/tcpaccept.py
@@ -74,7 +74,7 @@
 
 int kretprobe__inet_csk_accept(struct pt_regs *ctx)
 {
-    struct sock *newsk = (struct sock *)ctx->ax;
+    struct sock *newsk = (struct sock *)PT_REGS_RC(ctx);
     u32 pid = bpf_get_current_pid_tgid();
 
     if (newsk == NULL)
diff --git a/tools/tcpconnect.py b/tools/tcpconnect.py
index 273d214..02c1b3c 100755
--- a/tools/tcpconnect.py
+++ b/tools/tcpconnect.py
@@ -90,7 +90,7 @@
 
 static int trace_connect_return(struct pt_regs *ctx, short ipver)
 {
-    int ret = ctx->ax;
+    int ret = PT_REGS_RC(ctx);
     u32 pid = bpf_get_current_pid_tgid();
 
     struct sock **skpp;
diff --git a/tools/trace.py b/tools/trace.py
index 62d3143..9840233 100755
--- a/tools/trace.py
+++ b/tools/trace.py
@@ -202,13 +202,13 @@
                                 self.values.append(part)
 
         aliases = {
-                "retval": "ctx->ax",
-                "arg1": "ctx->di",
-                "arg2": "ctx->si",
-                "arg3": "ctx->dx",
-                "arg4": "ctx->cx",
-                "arg5": "ctx->r8",
-                "arg6": "ctx->r9",
+                "retval": "PT_REGS_RC(ctx)",
+                "arg1": "PT_REGS_PARM1(ctx)",
+                "arg2": "PT_REGS_PARM2(ctx)",
+                "arg3": "PT_REGS_PARM3(ctx)",
+                "arg4": "PT_REGS_PARM4(ctx)",
+                "arg5": "PT_REGS_PARM5(ctx)",
+                "arg6": "PT_REGS_PARM6(ctx)",
                 "$uid": "(unsigned)(bpf_get_current_uid_gid() & 0xffffffff)",
                 "$gid": "(unsigned)(bpf_get_current_uid_gid() >> 32)",
                 "$pid": "(unsigned)(bpf_get_current_pid_tgid() & 0xffffffff)",
diff --git a/tools/vfscount.py b/tools/vfscount.py
index 581c25a..f784d8e 100755
--- a/tools/vfscount.py
+++ b/tools/vfscount.py
@@ -28,7 +28,7 @@
     int do_count(struct pt_regs *ctx) {
     struct key_t key = {};
     u64 zero = 0, *val;
-    key.ip = ctx->ip;
+    key.ip = PT_REGS_IP(ctx);
     val = counts.lookup_or_init(&key, &zero);
     (*val)++;
     return 0;
diff --git a/tools/xfsslower.py b/tools/xfsslower.py
index 26f8af6..2e9c5b2 100755
--- a/tools/xfsslower.py
+++ b/tools/xfsslower.py
@@ -176,7 +176,7 @@
     bpf_probe_read(&de, sizeof(de), &valp->fp->f_path.dentry);
 
     // populate output struct
-    u32 size = ctx->ax;
+    u32 size = PT_REGS_RC(ctx);
     struct data_t data = {.type = type, .size = size, .delta_us = delta_us,
         .pid = pid};
     data.ts_us = ts / 1000;
diff --git a/tools/zfsslower.py b/tools/zfsslower.py
index 4337ead..4250c59 100755
--- a/tools/zfsslower.py
+++ b/tools/zfsslower.py
@@ -180,7 +180,7 @@
     bpf_probe_read(&de, sizeof(de), &valp->fp->f_path.dentry);
 
     // populate output struct
-    u32 size = ctx->ax;
+    u32 size = PT_REGS_RC(ctx);
     struct data_t data = {.type = type, .size = size, .delta_us = delta_us,
         .pid = pid};
     data.ts_us = ts / 1000;