• Yonghong Song's avatar
    change frontend rewriter to better handle anonymous struct/union · 94d15bc8
    Yonghong Song authored
    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: default avatarYonghong Song <yhs@fb.com>
    94d15bc8
b_frontend_action.cc 34.7 KB