change frontend rewriter to better handle anonymous struct/union
Kernel Commit 29e48ce87f1e ("task_struct: Allow randomized layout") (https://patchwork.kernel.org/patch/9797817/) permits to randomize a section of kernel task_struct data structure. This only takes effect when CONFIG_GCC_PLUGINS and CONFIG_GCC_PLUGIN_RANDSTRUCT are set. When randomization does not happen, an anonymous struct is introduced in task_struct data structure by gcc when compiling the kernel. To make field offset compatible, task_struct will have the same anonymous struct. The patch is at http://www.spinics.net/lists/kernel/msg2644958.html. Otherwise, bpf program may get wrong data from the kernel. Currently, bcc bpf_probe_read rewriter does not support anonymous struct/union. For example, with the above compiler-clang.h patch, examples/tracing/task_switch.py will have the following error: /virtual/main.c:16:18: error: internal error: opLoc is invalid while preparing probe rewrite key.prev_pid = prev->pid; ^ For anonymous structure, opcode source location ("->") is not available and hence the above failure. We could use memberLoc ("pid") which is available for anonymous struct/union. For example, for struct sock *skp; ...; u32 saddr = skp->__sk_common.skc_rcv_saddr; The old way for bpf_probe_read rewrite: bpf_probe_read(&_val, sizeof(_val), (u64)skp + offsetof(struct sock, __sk_common.skc_rcv_saddr)); The new way: bpf_probe_read(&_val, sizeof(_val), (u64)&skp->__sk_common.skc_rcv_saddr); The new way is similar to what typical bpf programs may do manually. Signed-off-by: Yonghong Song <yhs@fb.com>
Showing
Please register or sign in to comment