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);