whatcanGOwrong
This commit is contained in:
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,60 @@
|
||||
/* This file excercises the ELF loader. It is not a valid BPF program. */
|
||||
|
||||
#include "common.h"
|
||||
|
||||
#if __clang_major__ >= 9
|
||||
|
||||
int __section("socket/tail") tail_1() {
|
||||
return 42;
|
||||
}
|
||||
|
||||
// Tail call map (program array) initialized with program pointers.
|
||||
struct {
|
||||
__uint(type, BPF_MAP_TYPE_PROG_ARRAY);
|
||||
__type(key, uint32_t);
|
||||
__type(value, uint32_t);
|
||||
__uint(max_entries, 2);
|
||||
__array(values, int());
|
||||
} prog_array_init __section(".maps") = {
|
||||
.values =
|
||||
{
|
||||
// Skip index 0 to exercise empty array slots.
|
||||
[1] = &tail_1,
|
||||
},
|
||||
};
|
||||
|
||||
int __section("socket/main") tail_main(void *ctx) {
|
||||
// If prog_array_init is correctly populated, the tail call
|
||||
// will succeed and the program will continue in tail_1 and
|
||||
// not return here.
|
||||
tail_call(ctx, &prog_array_init, 1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Inner map with a single possible entry.
|
||||
struct {
|
||||
__uint(type, BPF_MAP_TYPE_ARRAY);
|
||||
__uint(max_entries, 1);
|
||||
__type(key, uint32_t);
|
||||
__type(value, uint32_t);
|
||||
} inner_map __section(".maps");
|
||||
|
||||
// Outer map carrying a reference to the inner map.
|
||||
struct {
|
||||
__uint(type, BPF_MAP_TYPE_ARRAY_OF_MAPS);
|
||||
__uint(max_entries, 2);
|
||||
__type(key, uint32_t);
|
||||
__type(value, uint32_t);
|
||||
__array(values, typeof(inner_map));
|
||||
} outer_map_init __section(".maps") = {
|
||||
.values =
|
||||
{
|
||||
// Skip index 0 to exercise empty array slots.
|
||||
[1] = &inner_map,
|
||||
},
|
||||
};
|
||||
|
||||
#else
|
||||
#error This file has to be compiled with clang >= 9
|
||||
#endif
|
||||
@@ -0,0 +1,53 @@
|
||||
#pragma once
|
||||
|
||||
typedef _Bool bool;
|
||||
typedef unsigned short uint16_t;
|
||||
typedef unsigned int uint32_t;
|
||||
typedef unsigned long uint64_t;
|
||||
|
||||
enum libbpf_tristate {
|
||||
TRI_NO = 0,
|
||||
TRI_YES = 1,
|
||||
TRI_MODULE = 2,
|
||||
};
|
||||
|
||||
#define __section(NAME) __attribute__((section(NAME), used))
|
||||
#define __uint(name, val) int(*name)[val]
|
||||
#define __type(name, val) typeof(val) *name
|
||||
#define __array(name, val) typeof(val) *name[]
|
||||
|
||||
#define __kconfig __attribute__((section(".kconfig")))
|
||||
#define __ksym __attribute__((section(".ksyms")))
|
||||
|
||||
#define BPF_MAP_TYPE_HASH (1)
|
||||
#define BPF_MAP_TYPE_ARRAY (2)
|
||||
#define BPF_MAP_TYPE_PROG_ARRAY (3)
|
||||
#define BPF_MAP_TYPE_PERF_EVENT_ARRAY (4)
|
||||
#define BPF_MAP_TYPE_ARRAY_OF_MAPS (12)
|
||||
#define BPF_MAP_TYPE_HASH_OF_MAPS (13)
|
||||
|
||||
#define BPF_F_NO_PREALLOC (1U << 0)
|
||||
#define BPF_F_CURRENT_CPU (0xffffffffULL)
|
||||
|
||||
/* From tools/lib/bpf/libbpf.h */
|
||||
struct bpf_map_def {
|
||||
unsigned int type;
|
||||
unsigned int key_size;
|
||||
unsigned int value_size;
|
||||
unsigned int max_entries;
|
||||
unsigned int map_flags;
|
||||
};
|
||||
|
||||
static void *(*map_lookup_elem)(const void *map, const void *key) = (void *)1;
|
||||
|
||||
static long (*map_update_elem)(const void *map, const void *key, const void *value, uint64_t flags) = (void *)2;
|
||||
|
||||
static long (*trace_printk)(const char *fmt, uint32_t fmt_size, ...) = (void *)6;
|
||||
|
||||
static long (*tail_call)(void *ctx, void *prog_array_map, uint32_t index) = (void *)12;
|
||||
|
||||
static int (*perf_event_output)(const void *ctx, const void *map, uint64_t index, const void *data, uint64_t size) = (void *)25;
|
||||
|
||||
static uint32_t (*get_smp_processor_id)(void) = (void *)8;
|
||||
|
||||
static long (*for_each_map_elem)(const void *map, void *callback_fn, void *callback_ctx, uint64_t flags) = (void *)164;
|
||||
@@ -0,0 +1,26 @@
|
||||
# This Dockerfile generates a build environment for generating ELFs
|
||||
# of testdata programs. Run `make build` in this directory to build it.
|
||||
FROM golang:buster
|
||||
|
||||
COPY llvm-snapshot.gpg.key .
|
||||
|
||||
RUN apt-get update && \
|
||||
apt-get -y --no-install-recommends install ca-certificates gnupg && \
|
||||
apt-key add llvm-snapshot.gpg.key && \
|
||||
rm llvm-snapshot.gpg.key && \
|
||||
apt-get remove -y gnupg && \
|
||||
apt-get autoremove -y && \
|
||||
rm -rf /var/lib/apt/lists/*
|
||||
|
||||
COPY llvm.list /etc/apt/sources.list.d
|
||||
|
||||
RUN apt-get update && \
|
||||
apt-get -y --no-install-recommends install \
|
||||
make git \
|
||||
clang-format \
|
||||
clang-7 llvm-7 \
|
||||
clang-9 llvm-9 \
|
||||
clang-14 llvm-14 && \
|
||||
rm -rf /var/lib/apt/lists/*
|
||||
|
||||
RUN GOBIN=/usr/local/bin go install golang.org/x/tools/cmd/stringer@latest && rm -rf /go/pkg
|
||||
@@ -0,0 +1 @@
|
||||
ghcr.io/cilium/ebpf-builder
|
||||
@@ -0,0 +1,18 @@
|
||||
# Makefile to build and push the `cilium/ebpf` llvm builder Docker image.
|
||||
CONTAINER_ENGINE ?= docker
|
||||
|
||||
IMAGE := $(shell cat IMAGE)
|
||||
EPOCH := $(shell date +'%s')
|
||||
|
||||
ifndef IMAGE
|
||||
$(error IMAGE file not present in Makefile directory)
|
||||
endif
|
||||
|
||||
.PHONY: build push
|
||||
|
||||
build:
|
||||
${CONTAINER_ENGINE} build --no-cache . -t "$(IMAGE):$(EPOCH)"
|
||||
echo $(EPOCH) > VERSION
|
||||
|
||||
push:
|
||||
${CONTAINER_ENGINE} push "$(IMAGE):$(shell cat VERSION)"
|
||||
@@ -0,0 +1,32 @@
|
||||
# `cilium/ebpf` LLVM Builder Image
|
||||
|
||||
This is a simple Docker image to provide reproducible eBPF ELF builds across
|
||||
contributors' workstations. This standardizes on a single environment used to
|
||||
regenerate e.g. testdata ELFs and does not depend on the toolchain installed
|
||||
on the host machine.
|
||||
|
||||
Additionally, it reduces drift in the bytecode committed to the repository over
|
||||
time as the same exact clang + llc version is used throughout the development
|
||||
lifecycle. Only when upgrading or rebuilding the Docker image would changes in
|
||||
.elf files be expected (assuming the .c files are untouched).
|
||||
|
||||
## Building
|
||||
|
||||
Building the image requires Docker. Run the build with:
|
||||
|
||||
`make build`
|
||||
|
||||
This updates the `VERSION` file. Commit it and submit a PR upstream.
|
||||
|
||||
### Regeneration Testdata on non-x86 platforms
|
||||
|
||||
Before running `make`, ensure [Docker buildx](https://docs.docker.com/buildx/working-with-buildx/)
|
||||
is enabled. Additionally `QEMU user` and `binfmt` should be installed. On a Debian based distribution
|
||||
the command to add them is `apt install qemu-user-static binfmt-support`.
|
||||
|
||||
|
||||
## Pushing
|
||||
|
||||
After building, push the image to the Docker registry specified in `IMAGE` with:
|
||||
|
||||
`make push`
|
||||
@@ -0,0 +1 @@
|
||||
1666886595
|
||||
+52
@@ -0,0 +1,52 @@
|
||||
-----BEGIN PGP PUBLIC KEY BLOCK-----
|
||||
Version: GnuPG v1.4.12 (GNU/Linux)
|
||||
|
||||
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
|
||||
bXb5c6gCHESH5PXwPU4jQEE7Ib9J6sbk7ZT2Mw==
|
||||
=j+4q
|
||||
-----END PGP PUBLIC KEY BLOCK-----
|
||||
@@ -0,0 +1,13 @@
|
||||
# Taken from https://apt.llvm.org.
|
||||
|
||||
deb http://apt.llvm.org/buster/ llvm-toolchain-buster main
|
||||
deb-src http://apt.llvm.org/buster/ llvm-toolchain-buster main
|
||||
|
||||
deb http://apt.llvm.org/buster/ llvm-toolchain-buster-7 main
|
||||
deb-src http://apt.llvm.org/buster/ llvm-toolchain-buster-7 main
|
||||
|
||||
deb http://apt.llvm.org/buster/ llvm-toolchain-buster-9 main
|
||||
deb-src http://apt.llvm.org/buster/ llvm-toolchain-buster-9 main
|
||||
|
||||
deb http://apt.llvm.org/buster/ llvm-toolchain-buster-14 main
|
||||
deb-src http://apt.llvm.org/buster/ llvm-toolchain-buster-14 main
|
||||
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,22 @@
|
||||
// /* This file excercises freplace. */
|
||||
|
||||
#include "common.h"
|
||||
|
||||
char __license[] __section("license") = "MIT";
|
||||
|
||||
struct bpf_args {
|
||||
uint64_t args[0];
|
||||
};
|
||||
|
||||
__attribute__((noinline)) int subprog() {
|
||||
volatile int ret = 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
__section("raw_tracepoint/sched_process_exec") int sched_process_exec(struct bpf_args *ctx) {
|
||||
return subprog();
|
||||
}
|
||||
|
||||
__section("freplace/subprog") int replacement() {
|
||||
return 0;
|
||||
}
|
||||
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,10 @@
|
||||
/* This file excercises the ELF loader. It is not a valid BPF program. */
|
||||
|
||||
#include "common.h"
|
||||
|
||||
// Forward function declaration, never implemented.
|
||||
int fwd();
|
||||
|
||||
__section("socket") int call_fwd() {
|
||||
return fwd();
|
||||
}
|
||||
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,11 @@
|
||||
#include "common.h"
|
||||
|
||||
char __license[] __section("license") = "Dual MIT/GPL";
|
||||
|
||||
// This function declaration is incorrect on purpose.
|
||||
extern void bpf_kfunc_call_test_mem_len_pass1(void) __ksym;
|
||||
|
||||
__section("tc") int call_kfunc() {
|
||||
bpf_kfunc_call_test_mem_len_pass1();
|
||||
return 1;
|
||||
}
|
||||
BIN
Binary file not shown.
BIN
Binary file not shown.
@@ -0,0 +1,17 @@
|
||||
/* This file excercises the ELF loader. It is not a valid BPF program. */
|
||||
|
||||
#include "common.h"
|
||||
|
||||
#if __clang_major__ >= 9
|
||||
struct {
|
||||
__uint(type, BPF_MAP_TYPE_HASH);
|
||||
__type(key, uint32_t);
|
||||
__type(value, uint64_t);
|
||||
__uint(max_entries, 1);
|
||||
} hash_map __section(".maps") = {
|
||||
/* This forces a non-zero byte into the .maps section. */
|
||||
.key = (void *)1,
|
||||
};
|
||||
#else
|
||||
#error This file has to be compiled with clang >= 9
|
||||
#endif
|
||||
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,20 @@
|
||||
/* This file excercises the ELF loader. It is not a valid BPF program.
|
||||
*/
|
||||
|
||||
#include "common.h"
|
||||
|
||||
char __license[] __section("license") = "MIT";
|
||||
|
||||
struct {
|
||||
struct bpf_map_def def;
|
||||
uint32_t dummy;
|
||||
} invalid_map __section("maps") = {
|
||||
.def =
|
||||
{
|
||||
.type = BPF_MAP_TYPE_HASH,
|
||||
.key_size = 4,
|
||||
.value_size = 2,
|
||||
.max_entries = 1,
|
||||
},
|
||||
.dummy = 1,
|
||||
};
|
||||
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,26 @@
|
||||
/* This file excercises the ELF loader. It is not a valid BPF program. */
|
||||
|
||||
#include "common.h"
|
||||
|
||||
struct bpf_map_def dummy __section("maps") = {
|
||||
.type = BPF_MAP_TYPE_HASH,
|
||||
.key_size = sizeof(uint32_t),
|
||||
.value_size = sizeof(uint64_t),
|
||||
.max_entries = 1,
|
||||
.map_flags = 0,
|
||||
};
|
||||
|
||||
/* The static qualifier leads to clang not emitting a symbol. */
|
||||
static struct bpf_map_def hash_map __section("maps") = {
|
||||
.type = BPF_MAP_TYPE_HASH,
|
||||
.key_size = sizeof(uint32_t),
|
||||
.value_size = sizeof(uint64_t),
|
||||
.max_entries = 1,
|
||||
.map_flags = 0,
|
||||
};
|
||||
|
||||
__section("xdp") int xdp_prog() {
|
||||
uint32_t key = 0;
|
||||
void *p = map_lookup_elem(&hash_map, &key);
|
||||
return !!p;
|
||||
}
|
||||
BIN
Binary file not shown.
BIN
Binary file not shown.
@@ -0,0 +1,29 @@
|
||||
/* This file excercises the ELF loader. It is not a valid BPF program. */
|
||||
|
||||
#include "common.h"
|
||||
|
||||
#define PIN_GLOBAL_NS 2
|
||||
|
||||
// bpf_elf_map is a custom BPF map definition used by iproute2.
|
||||
// It contains the id, pinning, inner_id and inner_idx fields
|
||||
// in addition to the ones in struct bpf_map_def which is commonly
|
||||
// used in the kernel and libbpf.
|
||||
struct bpf_elf_map {
|
||||
unsigned int type;
|
||||
unsigned int size_key;
|
||||
unsigned int size_value;
|
||||
unsigned int max_elem;
|
||||
unsigned int flags;
|
||||
unsigned int id;
|
||||
unsigned int pinning;
|
||||
unsigned int inner_id;
|
||||
unsigned int inner_idx;
|
||||
};
|
||||
|
||||
struct bpf_elf_map hash_map __section("maps") = {
|
||||
.type = BPF_MAP_TYPE_HASH,
|
||||
.size_key = sizeof(uint32_t),
|
||||
.size_value = sizeof(uint64_t),
|
||||
.max_elem = 2,
|
||||
.pinning = PIN_GLOBAL_NS,
|
||||
};
|
||||
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,14 @@
|
||||
#include "common.h"
|
||||
|
||||
char __license[] __section("license") = "MIT";
|
||||
|
||||
extern int LINUX_KERNEL_VERSION __kconfig;
|
||||
extern int LINUX_HAS_SYSCALL_WRAPPER __kconfig;
|
||||
|
||||
__section("socket") int kernel_version() {
|
||||
return LINUX_KERNEL_VERSION;
|
||||
}
|
||||
|
||||
__section("socket") int syscall_wrapper() {
|
||||
return LINUX_HAS_SYSCALL_WRAPPER;
|
||||
}
|
||||
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,25 @@
|
||||
#include "common.h"
|
||||
|
||||
char __license[] __section("license") = "GPL-2.0";
|
||||
|
||||
extern int CONFIG_HZ __kconfig;
|
||||
|
||||
struct {
|
||||
__uint(type, BPF_MAP_TYPE_ARRAY);
|
||||
__uint(max_entries, 1);
|
||||
__type(key, uint32_t);
|
||||
__type(value, uint64_t);
|
||||
} array_map __section(".maps");
|
||||
|
||||
static long (*bpf_map_update_elem)(void *map, const void *key, const void *value, uint64_t flags) = (void *)2;
|
||||
|
||||
__section("socket") int kconfig() {
|
||||
uint32_t i;
|
||||
uint64_t val;
|
||||
|
||||
i = 0;
|
||||
val = CONFIG_HZ;
|
||||
bpf_map_update_elem(&array_map, &i, &val, 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,10 @@
|
||||
#include "common.h"
|
||||
|
||||
char __license[] __section("license") = "Dual MIT/GPL";
|
||||
|
||||
extern void bpf_testmod_test_mod_kfunc(int) __ksym;
|
||||
|
||||
__section("tc") int call_kfunc() {
|
||||
bpf_testmod_test_mod_kfunc(0);
|
||||
return 1;
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
#include "common.h"
|
||||
|
||||
char __license[] __section("license") = "Dual MIT/GPL";
|
||||
|
||||
extern void bpf_kfunc_call_test_mem_len_pass1(void *mem, int len) __ksym;
|
||||
|
||||
__section("tc") int call_kfunc() {
|
||||
bpf_kfunc_call_test_mem_len_pass1((void *)0, 0);
|
||||
return 1;
|
||||
}
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,196 @@
|
||||
/* This file excercises the ELF loader.
|
||||
*/
|
||||
|
||||
#include "common.h"
|
||||
|
||||
char __license[] __section("license") = "MIT";
|
||||
|
||||
#if __clang_major__ >= 9
|
||||
// Clang < 9 doesn't emit the necessary BTF for this to work.
|
||||
struct {
|
||||
__uint(type, BPF_MAP_TYPE_HASH);
|
||||
__type(key, uint32_t);
|
||||
__type(value, uint64_t);
|
||||
__uint(max_entries, 1);
|
||||
__uint(map_flags, BPF_F_NO_PREALLOC);
|
||||
} hash_map __section(".maps");
|
||||
|
||||
struct {
|
||||
__uint(type, BPF_MAP_TYPE_HASH);
|
||||
__uint(key_size, sizeof(uint32_t));
|
||||
__uint(value_size, sizeof(uint64_t));
|
||||
__uint(max_entries, 2);
|
||||
} hash_map2 __section(".maps");
|
||||
|
||||
struct {
|
||||
__uint(type, BPF_MAP_TYPE_HASH);
|
||||
__type(key, uint32_t);
|
||||
__type(value, uint64_t);
|
||||
__uint(max_entries, 1);
|
||||
__uint(pinning, 1 /* LIBBPF_PIN_BY_NAME */);
|
||||
} btf_pin __section(".maps");
|
||||
|
||||
// Named map type definition, without structure variable declaration.
|
||||
struct inner_map_t {
|
||||
__uint(type, BPF_MAP_TYPE_HASH);
|
||||
__type(key, uint32_t);
|
||||
__type(value, int);
|
||||
__uint(max_entries, 1);
|
||||
};
|
||||
|
||||
// Anonymous map type definition with structure variable declaration.
|
||||
struct {
|
||||
__uint(type, BPF_MAP_TYPE_ARRAY_OF_MAPS);
|
||||
__uint(key_size, sizeof(uint32_t));
|
||||
__uint(max_entries, 1);
|
||||
__array(values, struct inner_map_t);
|
||||
} btf_outer_map __section(".maps");
|
||||
|
||||
// Array of maps with anonymous inner struct.
|
||||
struct {
|
||||
__uint(type, BPF_MAP_TYPE_ARRAY_OF_MAPS);
|
||||
__uint(key_size, sizeof(uint32_t));
|
||||
__uint(max_entries, 1);
|
||||
__array(
|
||||
values, struct {
|
||||
__uint(type, BPF_MAP_TYPE_HASH);
|
||||
__uint(max_entries, 1);
|
||||
__type(key, uint32_t);
|
||||
__type(value, uint32_t);
|
||||
});
|
||||
} btf_outer_map_anon __section(".maps");
|
||||
|
||||
struct {
|
||||
__uint(type, BPF_MAP_TYPE_PERF_EVENT_ARRAY);
|
||||
__uint(max_entries, 4096);
|
||||
} perf_event_array __section(".maps");
|
||||
#else
|
||||
struct bpf_map_def hash_map __section("maps") = {
|
||||
.type = BPF_MAP_TYPE_HASH,
|
||||
.key_size = sizeof(uint32_t),
|
||||
.value_size = sizeof(uint64_t),
|
||||
.max_entries = 1,
|
||||
.map_flags = BPF_F_NO_PREALLOC,
|
||||
};
|
||||
|
||||
struct bpf_map_def hash_map2 __section("maps") = {
|
||||
.type = BPF_MAP_TYPE_HASH,
|
||||
.key_size = sizeof(uint32_t),
|
||||
.value_size = sizeof(uint64_t),
|
||||
.max_entries = 2,
|
||||
};
|
||||
|
||||
struct bpf_map_def perf_event_array __section("maps") = {
|
||||
.type = BPF_MAP_TYPE_PERF_EVENT_ARRAY,
|
||||
.max_entries = 4096,
|
||||
};
|
||||
#endif
|
||||
|
||||
struct bpf_map_def array_of_hash_map __section("maps") = {
|
||||
.type = BPF_MAP_TYPE_ARRAY_OF_MAPS,
|
||||
.key_size = sizeof(uint32_t),
|
||||
.max_entries = 2,
|
||||
};
|
||||
|
||||
static int __attribute__((noinline)) __section("static") static_fn(uint32_t arg) {
|
||||
return arg - 1;
|
||||
}
|
||||
|
||||
int __attribute__((noinline)) global_fn2(uint32_t arg) {
|
||||
return arg + 2;
|
||||
}
|
||||
|
||||
int __attribute__((noinline)) __section("other") global_fn3(uint32_t arg) {
|
||||
return arg + 1;
|
||||
}
|
||||
|
||||
int __attribute__((noinline)) global_fn(uint32_t arg) {
|
||||
return static_fn(arg) + global_fn2(arg) + global_fn3(arg);
|
||||
}
|
||||
|
||||
#if __clang_major__ >= 9
|
||||
static volatile unsigned int key1 = 0; // .bss
|
||||
static volatile unsigned int key2 = 1; // .data
|
||||
volatile const unsigned int key3 = 2; // .rodata
|
||||
static volatile const uint32_t arg; // .rodata, populated by loader
|
||||
// custom .rodata section, populated by loader
|
||||
static volatile const uint32_t arg2 __section(".rodata.test");
|
||||
#endif
|
||||
|
||||
__section("xdp") int xdp_prog() {
|
||||
#if __clang_major__ < 9
|
||||
unsigned int key1 = 0;
|
||||
unsigned int key2 = 1;
|
||||
unsigned int key3 = 2;
|
||||
uint32_t arg = 1;
|
||||
uint32_t arg2 = 2;
|
||||
#endif
|
||||
map_lookup_elem(&hash_map, (void *)&key1);
|
||||
map_lookup_elem(&hash_map2, (void *)&key2);
|
||||
map_lookup_elem(&hash_map2, (void *)&key3);
|
||||
return static_fn(arg) + global_fn(arg) + arg2;
|
||||
}
|
||||
|
||||
// This function has no relocations, and is thus parsed differently.
|
||||
__section("socket") int no_relocation() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Make sure we allow relocations generated by inline assembly.
|
||||
__section("socket/2") int asm_relocation() {
|
||||
int my_const;
|
||||
asm("%0 = MY_CONST ll" : "=r"(my_const));
|
||||
return my_const;
|
||||
}
|
||||
|
||||
#if __clang_major__ >= 9
|
||||
volatile const unsigned int uneg = -1;
|
||||
volatile const int neg = -2;
|
||||
static volatile const unsigned int static_uneg = -3;
|
||||
static volatile const int static_neg = -4;
|
||||
|
||||
__section("socket/3") int data_sections() {
|
||||
if (uneg != (unsigned int)-1)
|
||||
return __LINE__;
|
||||
|
||||
if (neg != -2)
|
||||
return __LINE__;
|
||||
|
||||
if (static_uneg != (unsigned int)-3)
|
||||
return __LINE__;
|
||||
|
||||
if (static_neg != -4)
|
||||
return __LINE__;
|
||||
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
__section("socket/3") int data_sections() {
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Up until LLVM 14, this program results in an .rodata.cst32 section
|
||||
* that is accessed by 'return values[i]'. For this section, no BTF is
|
||||
* emitted. 'values' cannot be rewritten, since there is no BTF info
|
||||
* describing the data section.
|
||||
*/
|
||||
__section("socket/4") int anon_const() {
|
||||
volatile int ctx = 0;
|
||||
|
||||
// 32 bytes wide results in a .rodata.cst32 section.
|
||||
#define values \
|
||||
(uint64_t[]) { \
|
||||
0x0, 0x1, 0x2, 0x3 \
|
||||
}
|
||||
|
||||
int i;
|
||||
for (i = 0; i < 3; i++) {
|
||||
if (ctx == values[i]) {
|
||||
return values[i];
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,88 @@
|
||||
/* This file is used for benchmarking NewCollection().
|
||||
*/
|
||||
|
||||
#include "../btf/testdata/bpf_core_read.h"
|
||||
#include "common.h"
|
||||
|
||||
char __license[] __section("license") = "Dual MIT/GPL";
|
||||
|
||||
struct bpf_map_def __section("maps") kprobe_map = {
|
||||
.type = BPF_MAP_TYPE_HASH,
|
||||
.key_size = sizeof(uint32_t),
|
||||
.value_size = sizeof(uint64_t),
|
||||
.max_entries = 128,
|
||||
};
|
||||
|
||||
static void *(*bpf_map_lookup_elem)(void *map, const void *key) = (void *)1;
|
||||
static long (*bpf_map_update_elem)(void *map, const void *key, const void *value, uint64_t flags) = (void *)2;
|
||||
static void *(*bpf_get_current_task)() = (void *)35;
|
||||
static long (*bpf_probe_read_kernel)(void *dst, uint32_t size, const void *unsafe_ptr) = (void *)113;
|
||||
|
||||
#pragma clang attribute push(__attribute__((preserve_access_index)), apply_to = record)
|
||||
struct ns_common {
|
||||
unsigned int inum;
|
||||
};
|
||||
struct mnt_namespace {
|
||||
struct ns_common ns;
|
||||
};
|
||||
struct nsproxy {
|
||||
struct mnt_namespace *mnt_ns;
|
||||
};
|
||||
struct task_struct {
|
||||
struct nsproxy *nsproxy;
|
||||
};
|
||||
#pragma clang attribute pop
|
||||
|
||||
static inline int impl() {
|
||||
uint64_t initval = 1, *valp;
|
||||
|
||||
struct task_struct *task = (struct task_struct *)bpf_get_current_task();
|
||||
uint32_t mntns = BPF_CORE_READ(task, nsproxy, mnt_ns, ns.inum);
|
||||
|
||||
valp = bpf_map_lookup_elem(&kprobe_map, &mntns);
|
||||
if (!valp) {
|
||||
bpf_map_update_elem(&kprobe_map, &mntns, &initval, 0);
|
||||
return 0;
|
||||
}
|
||||
__sync_fetch_and_add(valp, 1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define DEFINE_PROBE(i) \
|
||||
__section("kprobe/sys_execvea" #i) int kprobe_execve##i() { \
|
||||
return impl(); \
|
||||
}
|
||||
|
||||
DEFINE_PROBE(0);
|
||||
DEFINE_PROBE(1);
|
||||
DEFINE_PROBE(2);
|
||||
DEFINE_PROBE(3);
|
||||
DEFINE_PROBE(4);
|
||||
DEFINE_PROBE(5);
|
||||
DEFINE_PROBE(6);
|
||||
DEFINE_PROBE(7);
|
||||
DEFINE_PROBE(8);
|
||||
DEFINE_PROBE(9);
|
||||
|
||||
DEFINE_PROBE(10);
|
||||
DEFINE_PROBE(11);
|
||||
DEFINE_PROBE(12);
|
||||
DEFINE_PROBE(13);
|
||||
DEFINE_PROBE(14);
|
||||
DEFINE_PROBE(15);
|
||||
DEFINE_PROBE(16);
|
||||
DEFINE_PROBE(17);
|
||||
DEFINE_PROBE(18);
|
||||
DEFINE_PROBE(19);
|
||||
|
||||
DEFINE_PROBE(20);
|
||||
DEFINE_PROBE(21);
|
||||
DEFINE_PROBE(22);
|
||||
DEFINE_PROBE(23);
|
||||
DEFINE_PROBE(24);
|
||||
DEFINE_PROBE(25);
|
||||
DEFINE_PROBE(26);
|
||||
DEFINE_PROBE(27);
|
||||
DEFINE_PROBE(28);
|
||||
DEFINE_PROBE(29);
|
||||
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,23 @@
|
||||
/* This file excercises bpf_spin_lock. */
|
||||
|
||||
#include "common.h"
|
||||
|
||||
struct bpf_spin_lock {
|
||||
uint32_t val;
|
||||
};
|
||||
|
||||
struct hash_elem {
|
||||
int cnt;
|
||||
struct bpf_spin_lock lock;
|
||||
};
|
||||
|
||||
#if __clang_major__ >= 9
|
||||
struct {
|
||||
__uint(type, BPF_MAP_TYPE_HASH);
|
||||
__type(key, uint32_t);
|
||||
__type(value, struct hash_elem);
|
||||
__uint(max_entries, 2);
|
||||
} spin_lock_map __section(".maps");
|
||||
#else
|
||||
#error This file required clang >= 9
|
||||
#endif
|
||||
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,13 @@
|
||||
/* This file excercises the ELF loader. */
|
||||
|
||||
#include "common.h"
|
||||
|
||||
char __license[] __section("license") = "MIT";
|
||||
|
||||
struct bpf_args {
|
||||
uint64_t args[0];
|
||||
};
|
||||
|
||||
__section("raw_tracepoint/sched_process_exec") int sched_process_exec(struct bpf_args *ctx) {
|
||||
return 0;
|
||||
}
|
||||
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,29 @@
|
||||
#include "common.h"
|
||||
|
||||
char __license[] __section("license") = "MIT";
|
||||
|
||||
typedef char custkey[48];
|
||||
|
||||
struct {
|
||||
__uint(type, BPF_MAP_TYPE_HASH);
|
||||
__uint(max_entries, 2);
|
||||
__type(key, custkey);
|
||||
__type(value, uint32_t);
|
||||
} my_map __section(".maps");
|
||||
|
||||
static void *(*bpf_map_lookup_elem)(void *map, const void *key) = (void *)1;
|
||||
static long (*bpf_map_update_elem)(void *map, const void *key, const void *value, uint64_t flags) = (void *)2;
|
||||
|
||||
#define KEY "This string is allocated in the string section\n"
|
||||
|
||||
__section("xdp") int filter() {
|
||||
uint32_t *value = bpf_map_lookup_elem(&my_map, KEY);
|
||||
if (value)
|
||||
(*value)++;
|
||||
else {
|
||||
uint32_t newValue = 1;
|
||||
bpf_map_update_elem(&my_map, KEY, &newValue, 0);
|
||||
}
|
||||
|
||||
return 2;
|
||||
}
|
||||
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,38 @@
|
||||
/* This file excercises the ELF loader.
|
||||
*/
|
||||
|
||||
#include "common.h"
|
||||
|
||||
char __license[] __section("license") = "MIT";
|
||||
|
||||
struct bpf_map_def hash_map __section("maps") = {
|
||||
.type = BPF_MAP_TYPE_HASH,
|
||||
.key_size = sizeof(uint32_t),
|
||||
.value_size = sizeof(uint64_t),
|
||||
.max_entries = 1,
|
||||
};
|
||||
|
||||
static int sub_prog() {
|
||||
uint32_t key = 0;
|
||||
uint64_t val = 42;
|
||||
|
||||
map_update_elem(&hash_map, &key, &val, /* BPF_ANY */ 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
__section("xdp") int fp_relocation() {
|
||||
uint32_t key = 0;
|
||||
uint64_t val = 1;
|
||||
|
||||
map_update_elem(&hash_map, &key, &val, /* BPF_ANY */ 0);
|
||||
|
||||
for_each_map_elem(&hash_map, sub_prog, (void *)0, 0);
|
||||
|
||||
uint64_t *new_val = map_lookup_elem(&hash_map, &key);
|
||||
if (!new_val) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return *new_val;
|
||||
}
|
||||
Binary file not shown.
Binary file not shown.
Reference in New Issue
Block a user