18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 28c2ecf20Sopenharmony_ci 38c2ecf20Sopenharmony_ci#include <stdio.h> 48c2ecf20Sopenharmony_ci#include <stdlib.h> 58c2ecf20Sopenharmony_ci#include <signal.h> 68c2ecf20Sopenharmony_ci#include <unistd.h> 78c2ecf20Sopenharmony_ci#include <stdbool.h> 88c2ecf20Sopenharmony_ci#include <string.h> 98c2ecf20Sopenharmony_ci#include <stdint.h> 108c2ecf20Sopenharmony_ci#include <fcntl.h> 118c2ecf20Sopenharmony_ci#include <linux/bpf.h> 128c2ecf20Sopenharmony_ci#include <sys/ioctl.h> 138c2ecf20Sopenharmony_ci#include <sys/resource.h> 148c2ecf20Sopenharmony_ci#include <sys/types.h> 158c2ecf20Sopenharmony_ci#include <sys/stat.h> 168c2ecf20Sopenharmony_ci#include <linux/perf_event.h> 178c2ecf20Sopenharmony_ci 188c2ecf20Sopenharmony_ci#include <bpf/libbpf.h> 198c2ecf20Sopenharmony_ci#include "bpf_load.h" 208c2ecf20Sopenharmony_ci#include "bpf_util.h" 218c2ecf20Sopenharmony_ci#include "perf-sys.h" 228c2ecf20Sopenharmony_ci#include "trace_helpers.h" 238c2ecf20Sopenharmony_ci 248c2ecf20Sopenharmony_ci#define CHECK_PERROR_RET(condition) ({ \ 258c2ecf20Sopenharmony_ci int __ret = !!(condition); \ 268c2ecf20Sopenharmony_ci if (__ret) { \ 278c2ecf20Sopenharmony_ci printf("FAIL: %s:\n", __func__); \ 288c2ecf20Sopenharmony_ci perror(" "); \ 298c2ecf20Sopenharmony_ci return -1; \ 308c2ecf20Sopenharmony_ci } \ 318c2ecf20Sopenharmony_ci}) 328c2ecf20Sopenharmony_ci 338c2ecf20Sopenharmony_ci#define CHECK_AND_RET(condition) ({ \ 348c2ecf20Sopenharmony_ci int __ret = !!(condition); \ 358c2ecf20Sopenharmony_ci if (__ret) \ 368c2ecf20Sopenharmony_ci return -1; \ 378c2ecf20Sopenharmony_ci}) 388c2ecf20Sopenharmony_ci 398c2ecf20Sopenharmony_cistatic __u64 ptr_to_u64(void *ptr) 408c2ecf20Sopenharmony_ci{ 418c2ecf20Sopenharmony_ci return (__u64) (unsigned long) ptr; 428c2ecf20Sopenharmony_ci} 438c2ecf20Sopenharmony_ci 448c2ecf20Sopenharmony_ci#define PMU_TYPE_FILE "/sys/bus/event_source/devices/%s/type" 458c2ecf20Sopenharmony_cistatic int bpf_find_probe_type(const char *event_type) 468c2ecf20Sopenharmony_ci{ 478c2ecf20Sopenharmony_ci char buf[256]; 488c2ecf20Sopenharmony_ci int fd, ret; 498c2ecf20Sopenharmony_ci 508c2ecf20Sopenharmony_ci ret = snprintf(buf, sizeof(buf), PMU_TYPE_FILE, event_type); 518c2ecf20Sopenharmony_ci CHECK_PERROR_RET(ret < 0 || ret >= sizeof(buf)); 528c2ecf20Sopenharmony_ci 538c2ecf20Sopenharmony_ci fd = open(buf, O_RDONLY); 548c2ecf20Sopenharmony_ci CHECK_PERROR_RET(fd < 0); 558c2ecf20Sopenharmony_ci 568c2ecf20Sopenharmony_ci ret = read(fd, buf, sizeof(buf)); 578c2ecf20Sopenharmony_ci close(fd); 588c2ecf20Sopenharmony_ci CHECK_PERROR_RET(ret < 0 || ret >= sizeof(buf)); 598c2ecf20Sopenharmony_ci 608c2ecf20Sopenharmony_ci errno = 0; 618c2ecf20Sopenharmony_ci ret = (int)strtol(buf, NULL, 10); 628c2ecf20Sopenharmony_ci CHECK_PERROR_RET(errno); 638c2ecf20Sopenharmony_ci return ret; 648c2ecf20Sopenharmony_ci} 658c2ecf20Sopenharmony_ci 668c2ecf20Sopenharmony_ci#define PMU_RETPROBE_FILE "/sys/bus/event_source/devices/%s/format/retprobe" 678c2ecf20Sopenharmony_cistatic int bpf_get_retprobe_bit(const char *event_type) 688c2ecf20Sopenharmony_ci{ 698c2ecf20Sopenharmony_ci char buf[256]; 708c2ecf20Sopenharmony_ci int fd, ret; 718c2ecf20Sopenharmony_ci 728c2ecf20Sopenharmony_ci ret = snprintf(buf, sizeof(buf), PMU_RETPROBE_FILE, event_type); 738c2ecf20Sopenharmony_ci CHECK_PERROR_RET(ret < 0 || ret >= sizeof(buf)); 748c2ecf20Sopenharmony_ci 758c2ecf20Sopenharmony_ci fd = open(buf, O_RDONLY); 768c2ecf20Sopenharmony_ci CHECK_PERROR_RET(fd < 0); 778c2ecf20Sopenharmony_ci 788c2ecf20Sopenharmony_ci ret = read(fd, buf, sizeof(buf)); 798c2ecf20Sopenharmony_ci close(fd); 808c2ecf20Sopenharmony_ci CHECK_PERROR_RET(ret < 0 || ret >= sizeof(buf)); 818c2ecf20Sopenharmony_ci CHECK_PERROR_RET(strlen(buf) < strlen("config:")); 828c2ecf20Sopenharmony_ci 838c2ecf20Sopenharmony_ci errno = 0; 848c2ecf20Sopenharmony_ci ret = (int)strtol(buf + strlen("config:"), NULL, 10); 858c2ecf20Sopenharmony_ci CHECK_PERROR_RET(errno); 868c2ecf20Sopenharmony_ci return ret; 878c2ecf20Sopenharmony_ci} 888c2ecf20Sopenharmony_ci 898c2ecf20Sopenharmony_cistatic int test_debug_fs_kprobe(int prog_fd_idx, const char *fn_name, 908c2ecf20Sopenharmony_ci __u32 expected_fd_type) 918c2ecf20Sopenharmony_ci{ 928c2ecf20Sopenharmony_ci __u64 probe_offset, probe_addr; 938c2ecf20Sopenharmony_ci __u32 len, prog_id, fd_type; 948c2ecf20Sopenharmony_ci char buf[256]; 958c2ecf20Sopenharmony_ci int err; 968c2ecf20Sopenharmony_ci 978c2ecf20Sopenharmony_ci len = sizeof(buf); 988c2ecf20Sopenharmony_ci err = bpf_task_fd_query(getpid(), event_fd[prog_fd_idx], 0, buf, &len, 998c2ecf20Sopenharmony_ci &prog_id, &fd_type, &probe_offset, 1008c2ecf20Sopenharmony_ci &probe_addr); 1018c2ecf20Sopenharmony_ci if (err < 0) { 1028c2ecf20Sopenharmony_ci printf("FAIL: %s, for event_fd idx %d, fn_name %s\n", 1038c2ecf20Sopenharmony_ci __func__, prog_fd_idx, fn_name); 1048c2ecf20Sopenharmony_ci perror(" :"); 1058c2ecf20Sopenharmony_ci return -1; 1068c2ecf20Sopenharmony_ci } 1078c2ecf20Sopenharmony_ci if (strcmp(buf, fn_name) != 0 || 1088c2ecf20Sopenharmony_ci fd_type != expected_fd_type || 1098c2ecf20Sopenharmony_ci probe_offset != 0x0 || probe_addr != 0x0) { 1108c2ecf20Sopenharmony_ci printf("FAIL: bpf_trace_event_query(event_fd[%d]):\n", 1118c2ecf20Sopenharmony_ci prog_fd_idx); 1128c2ecf20Sopenharmony_ci printf("buf: %s, fd_type: %u, probe_offset: 0x%llx," 1138c2ecf20Sopenharmony_ci " probe_addr: 0x%llx\n", 1148c2ecf20Sopenharmony_ci buf, fd_type, probe_offset, probe_addr); 1158c2ecf20Sopenharmony_ci return -1; 1168c2ecf20Sopenharmony_ci } 1178c2ecf20Sopenharmony_ci return 0; 1188c2ecf20Sopenharmony_ci} 1198c2ecf20Sopenharmony_ci 1208c2ecf20Sopenharmony_cistatic int test_nondebug_fs_kuprobe_common(const char *event_type, 1218c2ecf20Sopenharmony_ci const char *name, __u64 offset, __u64 addr, bool is_return, 1228c2ecf20Sopenharmony_ci char *buf, __u32 *buf_len, __u32 *prog_id, __u32 *fd_type, 1238c2ecf20Sopenharmony_ci __u64 *probe_offset, __u64 *probe_addr) 1248c2ecf20Sopenharmony_ci{ 1258c2ecf20Sopenharmony_ci int is_return_bit = bpf_get_retprobe_bit(event_type); 1268c2ecf20Sopenharmony_ci int type = bpf_find_probe_type(event_type); 1278c2ecf20Sopenharmony_ci struct perf_event_attr attr = {}; 1288c2ecf20Sopenharmony_ci int fd; 1298c2ecf20Sopenharmony_ci 1308c2ecf20Sopenharmony_ci if (type < 0 || is_return_bit < 0) { 1318c2ecf20Sopenharmony_ci printf("FAIL: %s incorrect type (%d) or is_return_bit (%d)\n", 1328c2ecf20Sopenharmony_ci __func__, type, is_return_bit); 1338c2ecf20Sopenharmony_ci return -1; 1348c2ecf20Sopenharmony_ci } 1358c2ecf20Sopenharmony_ci 1368c2ecf20Sopenharmony_ci attr.sample_period = 1; 1378c2ecf20Sopenharmony_ci attr.wakeup_events = 1; 1388c2ecf20Sopenharmony_ci if (is_return) 1398c2ecf20Sopenharmony_ci attr.config |= 1 << is_return_bit; 1408c2ecf20Sopenharmony_ci 1418c2ecf20Sopenharmony_ci if (name) { 1428c2ecf20Sopenharmony_ci attr.config1 = ptr_to_u64((void *)name); 1438c2ecf20Sopenharmony_ci attr.config2 = offset; 1448c2ecf20Sopenharmony_ci } else { 1458c2ecf20Sopenharmony_ci attr.config1 = 0; 1468c2ecf20Sopenharmony_ci attr.config2 = addr; 1478c2ecf20Sopenharmony_ci } 1488c2ecf20Sopenharmony_ci attr.size = sizeof(attr); 1498c2ecf20Sopenharmony_ci attr.type = type; 1508c2ecf20Sopenharmony_ci 1518c2ecf20Sopenharmony_ci fd = sys_perf_event_open(&attr, -1, 0, -1, 0); 1528c2ecf20Sopenharmony_ci CHECK_PERROR_RET(fd < 0); 1538c2ecf20Sopenharmony_ci 1548c2ecf20Sopenharmony_ci CHECK_PERROR_RET(ioctl(fd, PERF_EVENT_IOC_ENABLE, 0) < 0); 1558c2ecf20Sopenharmony_ci CHECK_PERROR_RET(ioctl(fd, PERF_EVENT_IOC_SET_BPF, prog_fd[0]) < 0); 1568c2ecf20Sopenharmony_ci CHECK_PERROR_RET(bpf_task_fd_query(getpid(), fd, 0, buf, buf_len, 1578c2ecf20Sopenharmony_ci prog_id, fd_type, probe_offset, probe_addr) < 0); 1588c2ecf20Sopenharmony_ci 1598c2ecf20Sopenharmony_ci return 0; 1608c2ecf20Sopenharmony_ci} 1618c2ecf20Sopenharmony_ci 1628c2ecf20Sopenharmony_cistatic int test_nondebug_fs_probe(const char *event_type, const char *name, 1638c2ecf20Sopenharmony_ci __u64 offset, __u64 addr, bool is_return, 1648c2ecf20Sopenharmony_ci __u32 expected_fd_type, 1658c2ecf20Sopenharmony_ci __u32 expected_ret_fd_type, 1668c2ecf20Sopenharmony_ci char *buf, __u32 buf_len) 1678c2ecf20Sopenharmony_ci{ 1688c2ecf20Sopenharmony_ci __u64 probe_offset, probe_addr; 1698c2ecf20Sopenharmony_ci __u32 prog_id, fd_type; 1708c2ecf20Sopenharmony_ci int err; 1718c2ecf20Sopenharmony_ci 1728c2ecf20Sopenharmony_ci err = test_nondebug_fs_kuprobe_common(event_type, name, 1738c2ecf20Sopenharmony_ci offset, addr, is_return, 1748c2ecf20Sopenharmony_ci buf, &buf_len, &prog_id, 1758c2ecf20Sopenharmony_ci &fd_type, &probe_offset, 1768c2ecf20Sopenharmony_ci &probe_addr); 1778c2ecf20Sopenharmony_ci if (err < 0) { 1788c2ecf20Sopenharmony_ci printf("FAIL: %s, " 1798c2ecf20Sopenharmony_ci "for name %s, offset 0x%llx, addr 0x%llx, is_return %d\n", 1808c2ecf20Sopenharmony_ci __func__, name ? name : "", offset, addr, is_return); 1818c2ecf20Sopenharmony_ci perror(" :"); 1828c2ecf20Sopenharmony_ci return -1; 1838c2ecf20Sopenharmony_ci } 1848c2ecf20Sopenharmony_ci if ((is_return && fd_type != expected_ret_fd_type) || 1858c2ecf20Sopenharmony_ci (!is_return && fd_type != expected_fd_type)) { 1868c2ecf20Sopenharmony_ci printf("FAIL: %s, incorrect fd_type %u\n", 1878c2ecf20Sopenharmony_ci __func__, fd_type); 1888c2ecf20Sopenharmony_ci return -1; 1898c2ecf20Sopenharmony_ci } 1908c2ecf20Sopenharmony_ci if (name) { 1918c2ecf20Sopenharmony_ci if (strcmp(name, buf) != 0) { 1928c2ecf20Sopenharmony_ci printf("FAIL: %s, incorrect buf %s\n", __func__, buf); 1938c2ecf20Sopenharmony_ci return -1; 1948c2ecf20Sopenharmony_ci } 1958c2ecf20Sopenharmony_ci if (probe_offset != offset) { 1968c2ecf20Sopenharmony_ci printf("FAIL: %s, incorrect probe_offset 0x%llx\n", 1978c2ecf20Sopenharmony_ci __func__, probe_offset); 1988c2ecf20Sopenharmony_ci return -1; 1998c2ecf20Sopenharmony_ci } 2008c2ecf20Sopenharmony_ci } else { 2018c2ecf20Sopenharmony_ci if (buf_len != 0) { 2028c2ecf20Sopenharmony_ci printf("FAIL: %s, incorrect buf %p\n", 2038c2ecf20Sopenharmony_ci __func__, buf); 2048c2ecf20Sopenharmony_ci return -1; 2058c2ecf20Sopenharmony_ci } 2068c2ecf20Sopenharmony_ci 2078c2ecf20Sopenharmony_ci if (probe_addr != addr) { 2088c2ecf20Sopenharmony_ci printf("FAIL: %s, incorrect probe_addr 0x%llx\n", 2098c2ecf20Sopenharmony_ci __func__, probe_addr); 2108c2ecf20Sopenharmony_ci return -1; 2118c2ecf20Sopenharmony_ci } 2128c2ecf20Sopenharmony_ci } 2138c2ecf20Sopenharmony_ci return 0; 2148c2ecf20Sopenharmony_ci} 2158c2ecf20Sopenharmony_ci 2168c2ecf20Sopenharmony_cistatic int test_debug_fs_uprobe(char *binary_path, long offset, bool is_return) 2178c2ecf20Sopenharmony_ci{ 2188c2ecf20Sopenharmony_ci const char *event_type = "uprobe"; 2198c2ecf20Sopenharmony_ci struct perf_event_attr attr = {}; 2208c2ecf20Sopenharmony_ci char buf[256], event_alias[sizeof("test_1234567890")]; 2218c2ecf20Sopenharmony_ci __u64 probe_offset, probe_addr; 2228c2ecf20Sopenharmony_ci __u32 len, prog_id, fd_type; 2238c2ecf20Sopenharmony_ci int err, res, kfd, efd; 2248c2ecf20Sopenharmony_ci ssize_t bytes; 2258c2ecf20Sopenharmony_ci 2268c2ecf20Sopenharmony_ci snprintf(buf, sizeof(buf), "/sys/kernel/debug/tracing/%s_events", 2278c2ecf20Sopenharmony_ci event_type); 2288c2ecf20Sopenharmony_ci kfd = open(buf, O_WRONLY | O_APPEND, 0); 2298c2ecf20Sopenharmony_ci CHECK_PERROR_RET(kfd < 0); 2308c2ecf20Sopenharmony_ci 2318c2ecf20Sopenharmony_ci res = snprintf(event_alias, sizeof(event_alias), "test_%d", getpid()); 2328c2ecf20Sopenharmony_ci CHECK_PERROR_RET(res < 0 || res >= sizeof(event_alias)); 2338c2ecf20Sopenharmony_ci 2348c2ecf20Sopenharmony_ci res = snprintf(buf, sizeof(buf), "%c:%ss/%s %s:0x%lx", 2358c2ecf20Sopenharmony_ci is_return ? 'r' : 'p', event_type, event_alias, 2368c2ecf20Sopenharmony_ci binary_path, offset); 2378c2ecf20Sopenharmony_ci CHECK_PERROR_RET(res < 0 || res >= sizeof(buf)); 2388c2ecf20Sopenharmony_ci CHECK_PERROR_RET(write(kfd, buf, strlen(buf)) < 0); 2398c2ecf20Sopenharmony_ci 2408c2ecf20Sopenharmony_ci close(kfd); 2418c2ecf20Sopenharmony_ci kfd = -1; 2428c2ecf20Sopenharmony_ci 2438c2ecf20Sopenharmony_ci snprintf(buf, sizeof(buf), "/sys/kernel/debug/tracing/events/%ss/%s/id", 2448c2ecf20Sopenharmony_ci event_type, event_alias); 2458c2ecf20Sopenharmony_ci efd = open(buf, O_RDONLY, 0); 2468c2ecf20Sopenharmony_ci CHECK_PERROR_RET(efd < 0); 2478c2ecf20Sopenharmony_ci 2488c2ecf20Sopenharmony_ci bytes = read(efd, buf, sizeof(buf)); 2498c2ecf20Sopenharmony_ci CHECK_PERROR_RET(bytes <= 0 || bytes >= sizeof(buf)); 2508c2ecf20Sopenharmony_ci close(efd); 2518c2ecf20Sopenharmony_ci buf[bytes] = '\0'; 2528c2ecf20Sopenharmony_ci 2538c2ecf20Sopenharmony_ci attr.config = strtol(buf, NULL, 0); 2548c2ecf20Sopenharmony_ci attr.type = PERF_TYPE_TRACEPOINT; 2558c2ecf20Sopenharmony_ci attr.sample_period = 1; 2568c2ecf20Sopenharmony_ci attr.wakeup_events = 1; 2578c2ecf20Sopenharmony_ci kfd = sys_perf_event_open(&attr, -1, 0, -1, PERF_FLAG_FD_CLOEXEC); 2588c2ecf20Sopenharmony_ci CHECK_PERROR_RET(kfd < 0); 2598c2ecf20Sopenharmony_ci CHECK_PERROR_RET(ioctl(kfd, PERF_EVENT_IOC_SET_BPF, prog_fd[0]) < 0); 2608c2ecf20Sopenharmony_ci CHECK_PERROR_RET(ioctl(kfd, PERF_EVENT_IOC_ENABLE, 0) < 0); 2618c2ecf20Sopenharmony_ci 2628c2ecf20Sopenharmony_ci len = sizeof(buf); 2638c2ecf20Sopenharmony_ci err = bpf_task_fd_query(getpid(), kfd, 0, buf, &len, 2648c2ecf20Sopenharmony_ci &prog_id, &fd_type, &probe_offset, 2658c2ecf20Sopenharmony_ci &probe_addr); 2668c2ecf20Sopenharmony_ci if (err < 0) { 2678c2ecf20Sopenharmony_ci printf("FAIL: %s, binary_path %s\n", __func__, binary_path); 2688c2ecf20Sopenharmony_ci perror(" :"); 2698c2ecf20Sopenharmony_ci return -1; 2708c2ecf20Sopenharmony_ci } 2718c2ecf20Sopenharmony_ci if ((is_return && fd_type != BPF_FD_TYPE_URETPROBE) || 2728c2ecf20Sopenharmony_ci (!is_return && fd_type != BPF_FD_TYPE_UPROBE)) { 2738c2ecf20Sopenharmony_ci printf("FAIL: %s, incorrect fd_type %u\n", __func__, 2748c2ecf20Sopenharmony_ci fd_type); 2758c2ecf20Sopenharmony_ci return -1; 2768c2ecf20Sopenharmony_ci } 2778c2ecf20Sopenharmony_ci if (strcmp(binary_path, buf) != 0) { 2788c2ecf20Sopenharmony_ci printf("FAIL: %s, incorrect buf %s\n", __func__, buf); 2798c2ecf20Sopenharmony_ci return -1; 2808c2ecf20Sopenharmony_ci } 2818c2ecf20Sopenharmony_ci if (probe_offset != offset) { 2828c2ecf20Sopenharmony_ci printf("FAIL: %s, incorrect probe_offset 0x%llx\n", __func__, 2838c2ecf20Sopenharmony_ci probe_offset); 2848c2ecf20Sopenharmony_ci return -1; 2858c2ecf20Sopenharmony_ci } 2868c2ecf20Sopenharmony_ci 2878c2ecf20Sopenharmony_ci close(kfd); 2888c2ecf20Sopenharmony_ci return 0; 2898c2ecf20Sopenharmony_ci} 2908c2ecf20Sopenharmony_ci 2918c2ecf20Sopenharmony_ciint main(int argc, char **argv) 2928c2ecf20Sopenharmony_ci{ 2938c2ecf20Sopenharmony_ci struct rlimit r = {RLIM_INFINITY, RLIM_INFINITY}; 2948c2ecf20Sopenharmony_ci extern char __executable_start; 2958c2ecf20Sopenharmony_ci char filename[256], buf[256]; 2968c2ecf20Sopenharmony_ci __u64 uprobe_file_offset; 2978c2ecf20Sopenharmony_ci 2988c2ecf20Sopenharmony_ci snprintf(filename, sizeof(filename), "%s_kern.o", argv[0]); 2998c2ecf20Sopenharmony_ci if (setrlimit(RLIMIT_MEMLOCK, &r)) { 3008c2ecf20Sopenharmony_ci perror("setrlimit(RLIMIT_MEMLOCK)"); 3018c2ecf20Sopenharmony_ci return 1; 3028c2ecf20Sopenharmony_ci } 3038c2ecf20Sopenharmony_ci 3048c2ecf20Sopenharmony_ci if (load_kallsyms()) { 3058c2ecf20Sopenharmony_ci printf("failed to process /proc/kallsyms\n"); 3068c2ecf20Sopenharmony_ci return 1; 3078c2ecf20Sopenharmony_ci } 3088c2ecf20Sopenharmony_ci 3098c2ecf20Sopenharmony_ci if (load_bpf_file(filename)) { 3108c2ecf20Sopenharmony_ci printf("%s", bpf_log_buf); 3118c2ecf20Sopenharmony_ci return 1; 3128c2ecf20Sopenharmony_ci } 3138c2ecf20Sopenharmony_ci 3148c2ecf20Sopenharmony_ci /* test two functions in the corresponding *_kern.c file */ 3158c2ecf20Sopenharmony_ci CHECK_AND_RET(test_debug_fs_kprobe(0, "blk_mq_start_request", 3168c2ecf20Sopenharmony_ci BPF_FD_TYPE_KPROBE)); 3178c2ecf20Sopenharmony_ci CHECK_AND_RET(test_debug_fs_kprobe(1, "blk_account_io_done", 3188c2ecf20Sopenharmony_ci BPF_FD_TYPE_KRETPROBE)); 3198c2ecf20Sopenharmony_ci 3208c2ecf20Sopenharmony_ci /* test nondebug fs kprobe */ 3218c2ecf20Sopenharmony_ci CHECK_AND_RET(test_nondebug_fs_probe("kprobe", "bpf_check", 0x0, 0x0, 3228c2ecf20Sopenharmony_ci false, BPF_FD_TYPE_KPROBE, 3238c2ecf20Sopenharmony_ci BPF_FD_TYPE_KRETPROBE, 3248c2ecf20Sopenharmony_ci buf, sizeof(buf))); 3258c2ecf20Sopenharmony_ci#ifdef __x86_64__ 3268c2ecf20Sopenharmony_ci /* set a kprobe on "bpf_check + 0x5", which is x64 specific */ 3278c2ecf20Sopenharmony_ci CHECK_AND_RET(test_nondebug_fs_probe("kprobe", "bpf_check", 0x5, 0x0, 3288c2ecf20Sopenharmony_ci false, BPF_FD_TYPE_KPROBE, 3298c2ecf20Sopenharmony_ci BPF_FD_TYPE_KRETPROBE, 3308c2ecf20Sopenharmony_ci buf, sizeof(buf))); 3318c2ecf20Sopenharmony_ci#endif 3328c2ecf20Sopenharmony_ci CHECK_AND_RET(test_nondebug_fs_probe("kprobe", "bpf_check", 0x0, 0x0, 3338c2ecf20Sopenharmony_ci true, BPF_FD_TYPE_KPROBE, 3348c2ecf20Sopenharmony_ci BPF_FD_TYPE_KRETPROBE, 3358c2ecf20Sopenharmony_ci buf, sizeof(buf))); 3368c2ecf20Sopenharmony_ci CHECK_AND_RET(test_nondebug_fs_probe("kprobe", NULL, 0x0, 3378c2ecf20Sopenharmony_ci ksym_get_addr("bpf_check"), false, 3388c2ecf20Sopenharmony_ci BPF_FD_TYPE_KPROBE, 3398c2ecf20Sopenharmony_ci BPF_FD_TYPE_KRETPROBE, 3408c2ecf20Sopenharmony_ci buf, sizeof(buf))); 3418c2ecf20Sopenharmony_ci CHECK_AND_RET(test_nondebug_fs_probe("kprobe", NULL, 0x0, 3428c2ecf20Sopenharmony_ci ksym_get_addr("bpf_check"), false, 3438c2ecf20Sopenharmony_ci BPF_FD_TYPE_KPROBE, 3448c2ecf20Sopenharmony_ci BPF_FD_TYPE_KRETPROBE, 3458c2ecf20Sopenharmony_ci NULL, 0)); 3468c2ecf20Sopenharmony_ci CHECK_AND_RET(test_nondebug_fs_probe("kprobe", NULL, 0x0, 3478c2ecf20Sopenharmony_ci ksym_get_addr("bpf_check"), true, 3488c2ecf20Sopenharmony_ci BPF_FD_TYPE_KPROBE, 3498c2ecf20Sopenharmony_ci BPF_FD_TYPE_KRETPROBE, 3508c2ecf20Sopenharmony_ci buf, sizeof(buf))); 3518c2ecf20Sopenharmony_ci CHECK_AND_RET(test_nondebug_fs_probe("kprobe", NULL, 0x0, 3528c2ecf20Sopenharmony_ci ksym_get_addr("bpf_check"), true, 3538c2ecf20Sopenharmony_ci BPF_FD_TYPE_KPROBE, 3548c2ecf20Sopenharmony_ci BPF_FD_TYPE_KRETPROBE, 3558c2ecf20Sopenharmony_ci 0, 0)); 3568c2ecf20Sopenharmony_ci 3578c2ecf20Sopenharmony_ci /* test nondebug fs uprobe */ 3588c2ecf20Sopenharmony_ci /* the calculation of uprobe file offset is based on gcc 7.3.1 on x64 3598c2ecf20Sopenharmony_ci * and the default linker script, which defines __executable_start as 3608c2ecf20Sopenharmony_ci * the start of the .text section. The calculation could be different 3618c2ecf20Sopenharmony_ci * on different systems with different compilers. The right way is 3628c2ecf20Sopenharmony_ci * to parse the ELF file. We took a shortcut here. 3638c2ecf20Sopenharmony_ci */ 3648c2ecf20Sopenharmony_ci uprobe_file_offset = (__u64)main - (__u64)&__executable_start; 3658c2ecf20Sopenharmony_ci CHECK_AND_RET(test_nondebug_fs_probe("uprobe", (char *)argv[0], 3668c2ecf20Sopenharmony_ci uprobe_file_offset, 0x0, false, 3678c2ecf20Sopenharmony_ci BPF_FD_TYPE_UPROBE, 3688c2ecf20Sopenharmony_ci BPF_FD_TYPE_URETPROBE, 3698c2ecf20Sopenharmony_ci buf, sizeof(buf))); 3708c2ecf20Sopenharmony_ci CHECK_AND_RET(test_nondebug_fs_probe("uprobe", (char *)argv[0], 3718c2ecf20Sopenharmony_ci uprobe_file_offset, 0x0, true, 3728c2ecf20Sopenharmony_ci BPF_FD_TYPE_UPROBE, 3738c2ecf20Sopenharmony_ci BPF_FD_TYPE_URETPROBE, 3748c2ecf20Sopenharmony_ci buf, sizeof(buf))); 3758c2ecf20Sopenharmony_ci 3768c2ecf20Sopenharmony_ci /* test debug fs uprobe */ 3778c2ecf20Sopenharmony_ci CHECK_AND_RET(test_debug_fs_uprobe((char *)argv[0], uprobe_file_offset, 3788c2ecf20Sopenharmony_ci false)); 3798c2ecf20Sopenharmony_ci CHECK_AND_RET(test_debug_fs_uprobe((char *)argv[0], uprobe_file_offset, 3808c2ecf20Sopenharmony_ci true)); 3818c2ecf20Sopenharmony_ci 3828c2ecf20Sopenharmony_ci return 0; 3838c2ecf20Sopenharmony_ci} 384