Support nested rewrite of trace arguments in bpf_trace_printk
authorBrenden Blanco <bblanco@plumgrid.com>
Wed, 12 Aug 2015 01:33:49 +0000 (18:33 -0700)
committerBrenden Blanco <bblanco@plumgrid.com>
Wed, 12 Aug 2015 01:33:49 +0000 (18:33 -0700)
There was an issue where the rewrite of bpf_trace_printk combined with
conversion of function argument to ctx->$reg was mangling the text. Fix
up this case and add a test.

Signed-off-by: Brenden Blanco <bblanco@plumgrid.com>
src/cc/frontends/clang/b_frontend_action.cc
tests/cc/test_clang.py

index 11a0221..b4350dc 100644 (file)
@@ -227,24 +227,24 @@ bool BTypeVisitor::VisitCallExpr(CallExpr *Call) {
         if (Decl->getName() == "incr_cksum_l3") {
           text = "bpf_l3_csum_replace_(" + fn_args_[0]->getName().str() + ", (u64)";
           text += args[0] + ", " + args[1] + ", " + args[2] + ", sizeof(" + args[2] + "))";
+          rewriter_.ReplaceText(SourceRange(Call->getLocStart(), Call->getLocEnd()), text);
         } else if (Decl->getName() == "incr_cksum_l4") {
           text = "bpf_l4_csum_replace_(" + fn_args_[0]->getName().str() + ", (u64)";
           text += args[0] + ", " + args[1] + ", " + args[2];
           text += ", ((" + args[3] + " & 0x1) << 4) | sizeof(" + args[2] + "))";
+          rewriter_.ReplaceText(SourceRange(Call->getLocStart(), Call->getLocEnd()), text);
         } else if (Decl->getName() == "bpf_trace_printk") {
           //  #define bpf_trace_printk(fmt, args...)
           //    ({ char _fmt[] = fmt; bpf_trace_printk_(_fmt, sizeof(_fmt), args...); })
           text = "({ char _fmt[] = " + args[0] + "; bpf_trace_printk_(_fmt, sizeof(_fmt)";
-          if (args.size() > 1)
-            text += "";
-          for (auto arg = args.begin() + 1; arg != args.end(); ++arg) {
-            text += *arg;
-            if (arg + 1 != args.end())
-              text += ", ";
+          if (args.size() <= 1) {
+            text += "); })";
+            rewriter_.ReplaceText(SourceRange(Call->getLocStart(), Call->getLocEnd()), text);
+          } else {
+            rewriter_.ReplaceText(SourceRange(Call->getLocStart(), Call->getArg(0)->getLocEnd()), text);
+            rewriter_.InsertTextAfter(Call->getLocEnd(), "); }");
           }
-          text += "); })";
         }
-        rewriter_.ReplaceText(SourceRange(Call->getLocStart(), Call->getLocEnd()), text);
       }
     }
   }
index a53b431..bd67b56 100755 (executable)
@@ -86,5 +86,17 @@ int do_request(struct pt_regs *ctx, struct request *req) {
         b = BPF(text=text, debug=0)
         fn = b.load_func("do_request", BPF.KPROBE)
 
+    def test_blk_start_request(self):
+        text = """
+#include <linux/blkdev.h>
+#include <uapi/linux/ptrace.h>
+int do_request(struct pt_regs *ctx, int req) {
+    bpf_trace_printk("req ptr: 0x%x\\n", req);
+    return 0;
+}
+"""
+        b = BPF(text=text, debug=0)
+        fn = b.load_func("do_request", BPF.KPROBE)
+
 if __name__ == "__main__":
     main()