Skip dereferences inside bpf_probe_reads calls (#1824)

* Skip all dereferences inside bpf_probe_read calls

If the user decides to rely on a manual call to bpf_probe_read, we
don't try to rewrite its last argument.  This is needed as the
rewriter starts to recognize and rewrite more and more dereferences.

* tools: fix dereferences following 1a765a17
diff --git a/src/cc/frontends/clang/b_frontend_action.cc b/src/cc/frontends/clang/b_frontend_action.cc
index a1e1bda..ab9b6f4 100644
--- a/src/cc/frontends/clang/b_frontend_action.cc
+++ b/src/cc/frontends/clang/b_frontend_action.cc
@@ -281,10 +281,7 @@
   if (VarDecl *V = dyn_cast<VarDecl>(Call->getCalleeDecl())) {
     if (V->getName() == "bpf_probe_read" && Call->getNumArgs() >= 3) {
       const Expr *E = Call->getArg(2)->IgnoreParenCasts();
-      if (const UnaryOperator *UnaryExpr = dyn_cast<UnaryOperator>(E)) {
-        if (UnaryExpr->getOpcode() == UO_AddrOf)
-          whitelist_.insert(E);
-      }
+      whitelist_.insert(E);
       return true;
     }
   }
diff --git a/tools/biosnoop.py b/tools/biosnoop.py
index 32d83e5..7f61180 100755
--- a/tools/biosnoop.py
+++ b/tools/biosnoop.py
@@ -94,8 +94,9 @@
         data.len = req->__data_len;
         data.sector = req->__sector;
         bpf_probe_read(&data.name, sizeof(data.name), valp->name);
+        struct gendisk *rq_disk = req->rq_disk;
         bpf_probe_read(&data.disk_name, sizeof(data.disk_name),
-                       req->rq_disk->disk_name);
+                       rq_disk->disk_name);
     }
 
 /*
diff --git a/tools/filelife.py b/tools/filelife.py
index 6756f31..0f4e269 100755
--- a/tools/filelife.py
+++ b/tools/filelife.py
@@ -84,14 +84,14 @@
     delta = (bpf_ktime_get_ns() - *tsp) / 1000000;
     birth.delete(&dentry);
 
-    if (dentry->d_name.len == 0)
+    struct qstr d_name = dentry->d_name;
+    if (d_name.len == 0)
         return 0;
 
     if (bpf_get_current_comm(&data.comm, sizeof(data.comm)) == 0) {
         data.pid = pid;
         data.delta = delta;
-        bpf_probe_read(&data.fname, sizeof(data.fname),
-            (void *)dentry->d_name.name);
+        bpf_probe_read(&data.fname, sizeof(data.fname), d_name.name);
     }
 
     events.perf_submit(ctx, &data, sizeof(data));
diff --git a/tools/fileslower.py b/tools/fileslower.py
index 04e2e61..5caa4ca 100755
--- a/tools/fileslower.py
+++ b/tools/fileslower.py
@@ -111,8 +111,9 @@
     val.sz = count;
     val.ts = bpf_ktime_get_ns();
 
-    val.name_len = de->d_name.len;
-    bpf_probe_read(&val.name, sizeof(val.name), (void *)de->d_name.name);
+    struct qstr d_name = de->d_name;
+    val.name_len = d_name.len;
+    bpf_probe_read(&val.name, sizeof(val.name), d_name.name);
     bpf_get_current_comm(&val.comm, sizeof(val.comm));
     entryinfo.update(&pid, &val);
 
diff --git a/tools/filetop.py b/tools/filetop.py
index 8677665..454dfd8 100755
--- a/tools/filetop.py
+++ b/tools/filetop.py
@@ -100,14 +100,15 @@
     // skip I/O lacking a filename
     struct dentry *de = file->f_path.dentry;
     int mode = file->f_inode->i_mode;
-    if (de->d_name.len == 0 || TYPE_FILTER)
+    struct qstr d_name = de->d_name;
+    if (d_name.len == 0 || TYPE_FILTER)
         return 0;
 
     // store counts and sizes by pid & file
     struct info_t info = {.pid = pid};
     bpf_get_current_comm(&info.comm, sizeof(info.comm));
-    info.name_len = de->d_name.len;
-    bpf_probe_read(&info.name, sizeof(info.name), (void *)de->d_name.name);
+    info.name_len = d_name.len;
+    bpf_probe_read(&info.name, sizeof(info.name), d_name.name);
     if (S_ISREG(mode)) {
         info.type = 'R';
     } else if (S_ISSOCK(mode)) {
diff --git a/tools/mdflush.py b/tools/mdflush.py
index 15ad79e..1d29bf1 100755
--- a/tools/mdflush.py
+++ b/tools/mdflush.py
@@ -44,11 +44,11 @@
  * and maintenance burden.
  */
 #ifdef bio_dev
-    bpf_probe_read(&data.disk, sizeof(data.disk), bio->bi_disk->disk_name);
+    struct gendisk *bi_disk = bio->bi_disk;
 #else
-    bpf_probe_read(&data.disk, sizeof(data.disk),
-                   bio->bi_bdev->bd_disk->disk_name);
+    struct gendisk *bi_disk = bio->bi_bdev->bd_disk;
 #endif
+    bpf_probe_read(&data.disk, sizeof(data.disk), bi_disk->disk_name);
     events.perf_submit(ctx, &data, sizeof(data));
     return 0;
 }
diff --git a/tools/slabratetop.py b/tools/slabratetop.py
index f1911b0..101c585 100755
--- a/tools/slabratetop.py
+++ b/tools/slabratetop.py
@@ -87,7 +87,8 @@
 int kprobe__kmem_cache_alloc(struct pt_regs *ctx, struct kmem_cache *cachep)
 {
     struct info_t info = {};
-    bpf_probe_read(&info.name, sizeof(info.name), (void *)cachep->name);
+    const char *name = cachep->name;
+    bpf_probe_read(&info.name, sizeof(info.name), name);
 
     struct val_t *valp, zero = {};
     valp = counts.lookup_or_init(&info, &zero);