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