Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /* Copyright (c) 2021 Facebook */
0003 
0004 #include "vmlinux.h"
0005 #include <bpf/bpf_helpers.h>
0006 #include <bpf/bpf_tracing.h>
0007 #include <bpf/bpf_core_read.h>
0008 
0009 /* weak and shared between both files */
0010 const volatile int my_tid __weak;
0011 long syscall_id __weak;
0012 
0013 int output_val2;
0014 int output_ctx2;
0015 int output_weak2; /* should stay zero */
0016 
0017 /* same "subprog" name in all files, but it's ok because they all are static */
0018 static __noinline int subprog(int x)
0019 {
0020     /* but different formula */
0021     return x * 2;
0022 }
0023 
0024 /* Global functions can't be void */
0025 int set_output_val2(int x)
0026 {
0027     output_val2 = 2 * x + 2 * subprog(x);
0028     return 2 * x;
0029 }
0030 
0031 /* This function can't be verified as global, as it assumes raw_tp/sys_enter
0032  * context and accesses syscall id (second argument). So we mark it as
0033  * __hidden, so that libbpf will mark it as static in the final object file,
0034  * right before verifying it in the kernel.
0035  *
0036  * But we don't mark it as __hidden here, rather at extern site. __hidden is
0037  * "contaminating" visibility, so it will get propagated from either extern or
0038  * actual definition (including from the losing __weak definition).
0039  */
0040 void set_output_ctx2(__u64 *ctx)
0041 {
0042     output_ctx2 = ctx[1]; /* long id, same as in BPF_PROG below */
0043 }
0044 
0045 /* this weak instance should lose, because it will be processed second */
0046 __weak int set_output_weak(int x)
0047 {
0048     static volatile int whatever;
0049 
0050     /* make sure we use CO-RE relocations in a weak function, this used to
0051      * cause problems for BPF static linker
0052      */
0053     whatever = 2 * bpf_core_type_size(struct task_struct);
0054 
0055     output_weak2 = x;
0056     return 2 * x;
0057 }
0058 
0059 extern int set_output_val1(int x);
0060 
0061 /* here we'll force set_output_ctx1() to be __hidden in the final obj file */
0062 __hidden extern void set_output_ctx1(__u64 *ctx);
0063 
0064 SEC("?raw_tp/sys_enter")
0065 int BPF_PROG(handler2, struct pt_regs *regs, long id)
0066 {
0067     static volatile int whatever;
0068 
0069     if (my_tid != (u32)bpf_get_current_pid_tgid() || id != syscall_id)
0070         return 0;
0071 
0072     /* make sure we have CO-RE relocations in main program */
0073     whatever = bpf_core_type_size(struct task_struct);
0074 
0075     set_output_val1(2000);
0076     set_output_ctx1(ctx); /* ctx definition is hidden in BPF_PROG macro */
0077 
0078     /* keep input value the same across both files to avoid dependency on
0079      * handler call order; differentiate by output_weak1 vs output_weak2.
0080      */
0081     set_output_weak(42);
0082 
0083     return 0;
0084 }
0085 
0086 char LICENSE[] SEC("license") = "GPL";