1 // SPDX-License-Identifier: GPL-2.0 2 /* Copyright (c) 2021 Facebook */ 3 4 #include "vmlinux.h" 5 #include <bpf/bpf_helpers.h> 6 #include <bpf/bpf_tracing.h> 7 8 /* weak and shared between both files */ 9 const volatile int my_tid __weak; 10 long syscall_id __weak; 11 12 int output_val2; 13 int output_ctx2; 14 int output_weak2; /* should stay zero */ 15 16 /* same "subprog" name in all files, but it's ok because they all are static */ 17 static __noinline int subprog(int x) 18 { 19 /* but different formula */ 20 return x * 2; 21 } 22 23 /* Global functions can't be void */ 24 int set_output_val2(int x) 25 { 26 output_val2 = 2 * x + 2 * subprog(x); 27 return 2 * x; 28 } 29 30 /* This function can't be verified as global, as it assumes raw_tp/sys_enter 31 * context and accesses syscall id (second argument). So we mark it as 32 * __hidden, so that libbpf will mark it as static in the final object file, 33 * right before verifying it in the kernel. 34 * 35 * But we don't mark it as __hidden here, rather at extern site. __hidden is 36 * "contaminating" visibility, so it will get propagated from either extern or 37 * actual definition (including from the losing __weak definition). 38 */ 39 void set_output_ctx2(__u64 *ctx) 40 { 41 output_ctx2 = ctx[1]; /* long id, same as in BPF_PROG below */ 42 } 43 44 /* this weak instance should lose, because it will be processed second */ 45 __weak int set_output_weak(int x) 46 { 47 output_weak2 = x; 48 return 2 * x; 49 } 50 51 extern int set_output_val1(int x); 52 53 /* here we'll force set_output_ctx1() to be __hidden in the final obj file */ 54 __hidden extern void set_output_ctx1(__u64 *ctx); 55 56 SEC("raw_tp/sys_enter") 57 int BPF_PROG(handler2, struct pt_regs *regs, long id) 58 { 59 if (my_tid != (u32)bpf_get_current_pid_tgid() || id != syscall_id) 60 return 0; 61 62 set_output_val1(2000); 63 set_output_ctx1(ctx); /* ctx definition is hidden in BPF_PROG macro */ 64 65 /* keep input value the same across both files to avoid dependency on 66 * handler call order; differentiate by output_weak1 vs output_weak2. 67 */ 68 set_output_weak(42); 69 70 return 0; 71 } 72 73 char LICENSE[] SEC("license") = "GPL"; 74