Initial Commit

This commit is contained in:
Harshavardhan Musanalli
2025-08-16 15:15:18 +02:00
commit 912a283f7c
20 changed files with 3123 additions and 0 deletions

BIN
c-lang/loader Executable file

Binary file not shown.

77
c-lang/loader.c Normal file
View File

@@ -0,0 +1,77 @@
#include <stdio.h>
#include <bpf/libbpf.h>
#include <unistd.h>
#include <string.h>
int main() {
struct bpf_object *obj;
struct bpf_program *prog;
struct bpf_link *link;
struct bpf_map *target_map;
int err;
const char *target_filename = "/tmp/testfile";
int key = 0;
char value[256] = {0};
strncpy(value, target_filename, sizeof(value) - 1);
obj = bpf_object__open_file("tracepoint.o", NULL);
if (!obj) {
fprintf(stderr, "Error opening BPF object\n");
return 1;
}
// Clean up any existing maps first
bpf_object__unpin_maps(obj, "/sys/fs/bpf");
err = bpf_object__load(obj);
if (err) {
fprintf(stderr, "Error loading BPF object\n");
return 1;
}
target_map = bpf_object__find_map_by_name(obj, "target_filename_map");
if (!target_map) {
fprintf(stderr, "Error finding target_filename_map\n");
bpf_object__close(obj);
return 1;
}
err = bpf_map__update_elem(target_map, &key, sizeof(key), value, sizeof(value), BPF_ANY);
if (err) {
fprintf(stderr, "Error populating target_filename_map\n");
bpf_object__close(obj);
return 1;
}
prog = bpf_object__find_program_by_name(obj, "trace_openat");
if (!prog) {
fprintf(stderr, "Error finding BPF program\n");
bpf_object__close(obj);
return 1;
}
link = bpf_program__attach(prog);
if (!link) {
fprintf(stderr, "Error attaching BPF program\n");
bpf_object__close(obj);
return 1;
}
err = bpf_object__pin_maps(obj, "/sys/fs/bpf");
if (err) {
fprintf(stderr, "Error pinning BPF maps\n");
bpf_link__destroy(link);
bpf_object__close(obj);
return 1;
}
printf("BPF program loaded and maps pinned. Press Ctrl+C to exit.\n");
pause();
bpf_object__unpin_maps(obj, "/sys/fs/bpf");
bpf_link__destroy(link);
bpf_object__close(obj);
return 0;
}

BIN
c-lang/monitor Executable file

Binary file not shown.

45
c-lang/monitor.c Normal file
View File

@@ -0,0 +1,45 @@
#include <stdio.h>
#include <unistd.h>
#include <bpf/libbpf.h>
#include <bpf/bpf.h>
struct event {
__u32 pid;
__u32 uid;
char comm[16];
char filename[256];
};
// Simplified callback that actually works
static void handle_event(void *ctx, int cpu, void *data, unsigned int size)
{
struct event *e = data;
printf("PID: %d, UID: %d, CMD: %s, FILE: %s\n",
e->pid, e->uid, e->comm, e->filename);
}
int main()
{
struct perf_buffer *pb;
int map_fd;
map_fd = bpf_obj_get("/sys/fs/bpf/events");
if (map_fd < 0) {
fprintf(stderr, "Failed to get BPF map\n");
return 1;
}
// This is the ONLY working syntax across all libbpf versions
pb = perf_buffer__new(map_fd, 8, handle_event, NULL, NULL, NULL);
if (!pb) {
fprintf(stderr, "Failed to create perf buffer\n");
close(map_fd);
return 1;
}
printf("Monitoring started. Ctrl+C to exit.\n");
while (perf_buffer__poll(pb, 1000) >= 0);
close(map_fd);
return 0;
}

66
c-lang/tracepoint.c Normal file
View File

@@ -0,0 +1,66 @@
#include <linux/bpf.h>
#include <bpf/bpf_helpers.h>
struct sys_enter_args {
unsigned long long unused;
long syscall_nr;
unsigned long args[6];
};
struct event {
__u32 pid;
__u32 uid;
char comm[16];
char filename[256];
};
struct {
__uint(type, BPF_MAP_TYPE_PERF_EVENT_ARRAY);
__uint(key_size, sizeof(int));
__uint(value_size, sizeof(__u32));
} events SEC(".maps");
struct {
__uint(type, BPF_MAP_TYPE_ARRAY);
__uint(key_size, sizeof(int));
__uint(value_size, 256);
__uint(max_entries, 1);
__uint(map_flags, BPF_F_RDONLY_PROG); // Critical: Makes map read-only for BPF programs
} target_filename_map SEC(".maps");
SEC("tracepoint/syscalls/sys_enter_openat")
int trace_openat(struct sys_enter_args *ctx)
{
struct event e = {};
char *target_filename;
int key = 0;
// Read filename from syscall arguments
bpf_probe_read_user_str(e.filename, sizeof(e.filename), (void *)ctx->args[1]);
// Get target filename from map
target_filename = bpf_map_lookup_elem(&target_filename_map, &key);
if (!target_filename) {
return 0;
}
// Compare filenames - now safe because map is read-only
for (int i = 0; i < sizeof(e.filename); i++) {
if (e.filename[i] != target_filename[i]) {
return 0; // No match
}
if (e.filename[i] == 0 || target_filename[i] == 0) {
break; // End of string
}
}
// If we get here, filenames match
e.pid = bpf_get_current_pid_tgid() >> 32;
e.uid = bpf_get_current_uid_gid();
bpf_get_current_comm(&e.comm, sizeof(e.comm));
bpf_perf_event_output(ctx, &events, BPF_F_CURRENT_CPU, &e, sizeof(e));
return 0;
}
char LICENSE[] SEC("license") = "Dual BSD/GPL";

BIN
c-lang/tracepoint.o Normal file

Binary file not shown.

BIN
fim-ebpf Executable file

Binary file not shown.

5
gen.go Normal file
View File

@@ -0,0 +1,5 @@
package main
import "C"
//go:generate go run github.com/cilium/ebpf/cmd/bpf2go -tags linux tracepoint tracepoint.c

7
go.mod Normal file
View File

@@ -0,0 +1,7 @@
module fim-ebpf
go 1.24.2
require github.com/cilium/ebpf v0.19.0
require golang.org/x/sys v0.31.0 // indirect

26
go.sum Normal file
View File

@@ -0,0 +1,26 @@
github.com/cilium/ebpf v0.19.0 h1:Ro/rE64RmFBeA9FGjcTc+KmCeY6jXmryu6FfnzPRIao=
github.com/cilium/ebpf v0.19.0/go.mod h1:fLCgMo3l8tZmAdM3B2XqdFzXBpwkcSTroaVqN08OWVY=
github.com/go-quicktest/qt v1.101.1-0.20240301121107-c6c8733fa1e6 h1:teYtXy9B7y5lHTp8V9KPxpYRAVA7dozigQcMiBust1s=
github.com/go-quicktest/qt v1.101.1-0.20240301121107-c6c8733fa1e6/go.mod h1:p4lGIVX+8Wa6ZPNDvqcxq36XpUDLh42FLetFU7odllI=
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/josharian/native v1.1.0 h1:uuaP0hAbW7Y4l0ZRQ6C9zfb7Mg1mbFKry/xzDAfmtLA=
github.com/josharian/native v1.1.0/go.mod h1:7X/raswPFr05uY3HiLlYeyQntB6OO7E/d2Cu7qoaN2w=
github.com/jsimonetti/rtnetlink/v2 v2.0.1 h1:xda7qaHDSVOsADNouv7ukSuicKZO7GgVUCXxpaIEIlM=
github.com/jsimonetti/rtnetlink/v2 v2.0.1/go.mod h1:7MoNYNbb3UaDHtF8udiJo/RH6VsTKP1pqKLUTVCvToE=
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/mdlayher/netlink v1.7.2 h1:/UtM3ofJap7Vl4QWCPDGXY8d3GIY2UGSDbK+QWmY8/g=
github.com/mdlayher/netlink v1.7.2/go.mod h1:xraEF7uJbxLhc5fpHL4cPe221LI2bdttWlU+ZGLfQSw=
github.com/mdlayher/socket v0.4.1 h1:eM9y2/jlbs1M615oshPQOHZzj6R6wMT7bX5NPiQvn2U=
github.com/mdlayher/socket v0.4.1/go.mod h1:cAqeGjoufqdxWkD7DkpyS+wcefOtmu5OQ8KuoJGIReA=
github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8=
github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4=
golang.org/x/net v0.38.0 h1:vRMAPTMaeGqVhG5QyLJHqNDwecKTomGeqbnfZyKlBI8=
golang.org/x/net v0.38.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8=
golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o=
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.31.0 h1:ioabZlmFYtWhL+TRYpcnNlLwhyxaM9kWTDEmfnprqik=
golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=

102
main.go Normal file
View File

@@ -0,0 +1,102 @@
package main
import (
"bytes"
"encoding/binary"
"errors"
"log"
"os"
"os/signal"
"syscall"
"unsafe"
"github.com/cilium/ebpf/link"
"github.com/cilium/ebpf/perf"
"github.com/cilium/ebpf/rlimit"
)
// event matches the C struct in your BPF program
type event struct {
Pid uint32
Uid uint32
Comm [16]byte
Filename [256]byte
}
func main() {
// Allow the current process to lock memory for eBPF resources
if err := rlimit.RemoveMemlock(); err != nil {
log.Fatal(err)
}
// Load the pre-compiled BPF program
objs := tracepointObjects{}
if err := loadTracepointObjects(&objs, nil); err != nil {
log.Fatalf("loading objects: %v", err)
}
defer objs.Close()
// Populate the target filename map (critical part)
targetFilename := "/tmp/testfile\x00" // Null-terminated
var filenameBuf [256]byte
copy(filenameBuf[:], targetFilename)
key := uint32(0)
if err := objs.TargetFilenameMap.Put(key, filenameBuf); err != nil {
log.Fatalf("putting target filename in map: %v", err)
}
// Attach the tracepoint
tp, err := link.Tracepoint("syscalls", "sys_enter_openat", objs.TraceOpenat, nil)
if err != nil {
log.Fatalf("attaching tracepoint: %v", err)
}
defer tp.Close()
// Set up perf event reader
rd, err := perf.NewReader(objs.Events, os.Getpagesize())
if err != nil {
log.Fatalf("creating perf event reader: %v", err)
}
defer rd.Close()
log.Println("Monitoring for openat() syscalls to /tmp/testfile...")
// Graceful shutdown
sig := make(chan os.Signal, 1)
signal.Notify(sig, syscall.SIGINT, syscall.SIGTERM)
go func() {
for {
record, err := rd.Read()
if err != nil {
if errors.Is(err, perf.ErrClosed) {
return
}
log.Printf("reading from perf reader: %v", err)
continue
}
if len(record.RawSample) < int(unsafe.Sizeof(event{})) {
log.Printf("invalid sample size: %d", len(record.RawSample))
continue
}
var e event
if err := binary.Read(bytes.NewBuffer(record.RawSample), binary.LittleEndian, &e); err != nil {
log.Printf("parsing event: %v", err)
continue
}
// Convert byte arrays to strings
comm := string(bytes.TrimRight(e.Comm[:], "\x00"))
filename := string(bytes.TrimRight(e.Filename[:], "\x00"))
log.Printf("PID: %d, UID: %d, CMD: %s, FILE: %s",
e.Pid, e.Uid, comm, filename)
}
}()
<-sig
log.Println("Shutting down...")
}

122
main.go.bkp Normal file
View File

@@ -0,0 +1,122 @@
//go:build linux
// This program demonstrates how to attach an eBPF program to a tracepoint.
// The program is attached to the syscall/sys_enter_openat tracepoint and
// prints out the integer 123 every time the syscall is entered.
package main
import (
"errors"
"log"
"os"
"os/signal"
"syscall"
"github.com/cilium/ebpf"
"github.com/cilium/ebpf/asm"
"github.com/cilium/ebpf/link"
"github.com/cilium/ebpf/perf"
"github.com/cilium/ebpf/rlimit"
)
// Metadata for the eBPF program used in this example.
var progSpec = &ebpf.ProgramSpec{
Name: "fim_monitoring", // non-unique name, will appear in `bpftool prog list` while attached
Type: ebpf.TracePoint, // only TracePoint programs can be attached to trace events created by link.Tracepoint()
License: "GPL", // license must be GPL for calling kernel helpers like perf_event_output
}
func main() {
// Subscribe to signals for terminating the program.
stopper := make(chan os.Signal, 1)
signal.Notify(stopper, os.Interrupt, syscall.SIGTERM)
// Allow the current process to lock memory for eBPF resources.
if err := rlimit.RemoveMemlock(); err != nil {
log.Fatal(err)
}
// Create a perf event array for the kernel to write perf records to.
// These records will be read by userspace below.
events, err := ebpf.NewMap(&ebpf.MapSpec{
Type: ebpf.PerfEventArray,
Name: "my_perf_array",
})
if err != nil {
log.Fatalf("creating perf event array: %s", err)
}
defer events.Close()
// Open a perf reader from userspace into the perf event array
// created earlier.
rd, err := perf.NewReader(events, os.Getpagesize())
if err != nil {
log.Fatalf("creating event reader: %s", err)
}
defer rd.Close()
// Close the reader when the process receives a signal, which will exit
// the read loop.
go func() {
<-stopper
rd.Close()
}()
// Minimal program that writes the static value '123' to the perf ring on
// each event. Note that this program refers to the file descriptor of
// the perf event array created above, which needs to be created prior to the
// program being verified by and inserted into the kernel.
progSpec.Instructions = asm.Instructions{
// store the integer 123 at FP[-8]
asm.Mov.Imm(asm.R2, 123),
asm.StoreMem(asm.RFP, -8, asm.R2, asm.Word),
// load registers with arguments for call of FnPerfEventOutput
asm.LoadMapPtr(asm.R2, events.FD()), // file descriptor of the perf event array
asm.LoadImm(asm.R3, 0xffffffff, asm.DWord),
asm.Mov.Reg(asm.R4, asm.RFP),
asm.Add.Imm(asm.R4, -8),
asm.Mov.Imm(asm.R5, 4),
// call FnPerfEventOutput, an eBPF kernel helper
asm.FnPerfEventOutput.Call(),
// set exit code to 0
asm.Mov.Imm(asm.R0, 0),
asm.Return(),
}
// Instantiate and insert the program into the kernel.
prog, err := ebpf.NewProgram(progSpec)
if err != nil {
log.Fatalf("creating ebpf program: %s", err)
}
defer prog.Close()
// Open a trace event based on a pre-existing kernel hook (tracepoint).
// Each time a userspace program uses the 'openat()' syscall, the eBPF
// program specified above will be executed and a '123' value will appear
// in the perf ring.
tp, err := link.Tracepoint("syscalls", "sys_enter_openat", prog, nil)
if err != nil {
log.Fatalf("opening tracepoint: %s", err)
}
defer tp.Close()
log.Println("Waiting for events..")
for {
record, err := rd.Read()
if err != nil {
if errors.Is(err, perf.ErrClosed) {
log.Println("Received signal, exiting..")
return
}
log.Printf("reading from reader: %s", err)
continue
}
log.Println("Record:", record)
}
}

2290
probe.out Normal file

File diff suppressed because it is too large Load Diff

71
tracepoint.c Normal file
View File

@@ -0,0 +1,71 @@
#include <linux/bpf.h>
#include <bpf/bpf_helpers.h>
#include <bpf/bpf_tracing.h>
struct sys_enter_args {
unsigned long long unused;
long syscall_nr;
unsigned long args[6];
};
struct event {
__u32 pid;
__u32 uid;
char comm[16];
char filename[256];
};
struct {
__uint(type, BPF_MAP_TYPE_PERF_EVENT_ARRAY);
__uint(key_size, sizeof(int));
__uint(value_size, sizeof(int));
__uint(max_entries, 1024);
} events SEC(".maps");
struct {
__uint(type, BPF_MAP_TYPE_HASH);
__uint(key_size, sizeof(int));
__uint(value_size, 256); // Max filename length
__uint(max_entries, 1);
} target_filename_map SEC(".maps");
SEC("tracepoint/syscalls/sys_enter_openat")
int trace_openat(struct sys_enter_args *ctx)
{
int zero = 0;
char *target = bpf_map_lookup_elem(&target_filename_map, &zero);
if (!target) {
return 0;
}
struct event e = {};
long ret;
// Read filename safely
ret = bpf_probe_read_user_str(e.filename, sizeof(e.filename), (void *)ctx->args[1]);
if (ret <= 0) {
return 0;
}
// Compare strings properly
for (int i = 0; i < sizeof(e.filename); i++) {
if (e.filename[i] != target[i]) {
return 0;
}
// Stop at null terminator
if (e.filename[i] == '\0') {
break;
}
}
// Fill event data
e.pid = bpf_get_current_pid_tgid() >> 32;
e.uid = bpf_get_current_uid_gid();
bpf_get_current_comm(&e.comm, sizeof(e.comm));
// Submit event
bpf_perf_event_output(ctx, &events, BPF_F_CURRENT_CPU, &e, sizeof(e));
return 0;
}
char LICENSE[] SEC("license") = "Dual BSD/GPL";

40
tracepoint.c.bkp Normal file
View File

@@ -0,0 +1,40 @@
//go:build ignore
#include "common.h"
char __license[] SEC("license") = "Dual MIT/GPL";
struct {
__uint(type, BPF_MAP_TYPE_ARRAY);
__type(key, u32);
__type(value, u64);
__uint(max_entries, 1);
} counting_map SEC(".maps");
// This struct is defined according to the following format file:
// /sys/kernel/tracing/events/kmem/mm_page_alloc/format
struct alloc_info {
/* The first 8 bytes is not allowed to read */
unsigned long pad;
unsigned long pfn;
unsigned int order;
unsigned int gfp_flags;
int migratetype;
};
// This tracepoint is defined in mm/page_alloc.c:__alloc_pages_nodemask()
// Userspace pathname: /sys/kernel/tracing/events/kmem/mm_page_alloc
SEC("tracepoint/kmem/mm_page_alloc")
int mm_page_alloc(struct alloc_info *info) {
u32 key = 0;
u64 initval = 1, *valp;
valp = bpf_map_lookup_elem(&counting_map, &key);
if (!valp) {
bpf_map_update_elem(&counting_map, &key, &initval, BPF_ANY);
return 0;
}
__sync_fetch_and_add(valp, 1);
return 0;
}

BIN
tracepoint.o Normal file

Binary file not shown.

136
tracepoint_bpfeb.go Normal file
View File

@@ -0,0 +1,136 @@
// Code generated by bpf2go; DO NOT EDIT.
//go:build (mips || mips64 || ppc64 || s390x) && linux
package main
import (
"bytes"
_ "embed"
"fmt"
"io"
"github.com/cilium/ebpf"
)
// loadTracepoint returns the embedded CollectionSpec for tracepoint.
func loadTracepoint() (*ebpf.CollectionSpec, error) {
reader := bytes.NewReader(_TracepointBytes)
spec, err := ebpf.LoadCollectionSpecFromReader(reader)
if err != nil {
return nil, fmt.Errorf("can't load tracepoint: %w", err)
}
return spec, err
}
// loadTracepointObjects loads tracepoint and converts it into a struct.
//
// The following types are suitable as obj argument:
//
// *tracepointObjects
// *tracepointPrograms
// *tracepointMaps
//
// See ebpf.CollectionSpec.LoadAndAssign documentation for details.
func loadTracepointObjects(obj interface{}, opts *ebpf.CollectionOptions) error {
spec, err := loadTracepoint()
if err != nil {
return err
}
return spec.LoadAndAssign(obj, opts)
}
// tracepointSpecs contains maps and programs before they are loaded into the kernel.
//
// It can be passed ebpf.CollectionSpec.Assign.
type tracepointSpecs struct {
tracepointProgramSpecs
tracepointMapSpecs
tracepointVariableSpecs
}
// tracepointProgramSpecs contains programs before they are loaded into the kernel.
//
// It can be passed ebpf.CollectionSpec.Assign.
type tracepointProgramSpecs struct {
TraceOpenat *ebpf.ProgramSpec `ebpf:"trace_openat"`
}
// tracepointMapSpecs contains maps before they are loaded into the kernel.
//
// It can be passed ebpf.CollectionSpec.Assign.
type tracepointMapSpecs struct {
Events *ebpf.MapSpec `ebpf:"events"`
TargetFilenameMap *ebpf.MapSpec `ebpf:"target_filename_map"`
}
// tracepointVariableSpecs contains global variables before they are loaded into the kernel.
//
// It can be passed ebpf.CollectionSpec.Assign.
type tracepointVariableSpecs struct {
}
// tracepointObjects contains all objects after they have been loaded into the kernel.
//
// It can be passed to loadTracepointObjects or ebpf.CollectionSpec.LoadAndAssign.
type tracepointObjects struct {
tracepointPrograms
tracepointMaps
tracepointVariables
}
func (o *tracepointObjects) Close() error {
return _TracepointClose(
&o.tracepointPrograms,
&o.tracepointMaps,
)
}
// tracepointMaps contains all maps after they have been loaded into the kernel.
//
// It can be passed to loadTracepointObjects or ebpf.CollectionSpec.LoadAndAssign.
type tracepointMaps struct {
Events *ebpf.Map `ebpf:"events"`
TargetFilenameMap *ebpf.Map `ebpf:"target_filename_map"`
}
func (m *tracepointMaps) Close() error {
return _TracepointClose(
m.Events,
m.TargetFilenameMap,
)
}
// tracepointVariables contains all global variables after they have been loaded into the kernel.
//
// It can be passed to loadTracepointObjects or ebpf.CollectionSpec.LoadAndAssign.
type tracepointVariables struct {
}
// tracepointPrograms contains all programs after they have been loaded into the kernel.
//
// It can be passed to loadTracepointObjects or ebpf.CollectionSpec.LoadAndAssign.
type tracepointPrograms struct {
TraceOpenat *ebpf.Program `ebpf:"trace_openat"`
}
func (p *tracepointPrograms) Close() error {
return _TracepointClose(
p.TraceOpenat,
)
}
func _TracepointClose(closers ...io.Closer) error {
for _, closer := range closers {
if err := closer.Close(); err != nil {
return err
}
}
return nil
}
// Do not access this directly.
//
//go:embed tracepoint_bpfeb.o
var _TracepointBytes []byte

BIN
tracepoint_bpfeb.o Normal file

Binary file not shown.

136
tracepoint_bpfel.go Normal file
View File

@@ -0,0 +1,136 @@
// Code generated by bpf2go; DO NOT EDIT.
//go:build (386 || amd64 || arm || arm64 || loong64 || mips64le || mipsle || ppc64le || riscv64 || wasm) && linux
package main
import (
"bytes"
_ "embed"
"fmt"
"io"
"github.com/cilium/ebpf"
)
// loadTracepoint returns the embedded CollectionSpec for tracepoint.
func loadTracepoint() (*ebpf.CollectionSpec, error) {
reader := bytes.NewReader(_TracepointBytes)
spec, err := ebpf.LoadCollectionSpecFromReader(reader)
if err != nil {
return nil, fmt.Errorf("can't load tracepoint: %w", err)
}
return spec, err
}
// loadTracepointObjects loads tracepoint and converts it into a struct.
//
// The following types are suitable as obj argument:
//
// *tracepointObjects
// *tracepointPrograms
// *tracepointMaps
//
// See ebpf.CollectionSpec.LoadAndAssign documentation for details.
func loadTracepointObjects(obj interface{}, opts *ebpf.CollectionOptions) error {
spec, err := loadTracepoint()
if err != nil {
return err
}
return spec.LoadAndAssign(obj, opts)
}
// tracepointSpecs contains maps and programs before they are loaded into the kernel.
//
// It can be passed ebpf.CollectionSpec.Assign.
type tracepointSpecs struct {
tracepointProgramSpecs
tracepointMapSpecs
tracepointVariableSpecs
}
// tracepointProgramSpecs contains programs before they are loaded into the kernel.
//
// It can be passed ebpf.CollectionSpec.Assign.
type tracepointProgramSpecs struct {
TraceOpenat *ebpf.ProgramSpec `ebpf:"trace_openat"`
}
// tracepointMapSpecs contains maps before they are loaded into the kernel.
//
// It can be passed ebpf.CollectionSpec.Assign.
type tracepointMapSpecs struct {
Events *ebpf.MapSpec `ebpf:"events"`
TargetFilenameMap *ebpf.MapSpec `ebpf:"target_filename_map"`
}
// tracepointVariableSpecs contains global variables before they are loaded into the kernel.
//
// It can be passed ebpf.CollectionSpec.Assign.
type tracepointVariableSpecs struct {
}
// tracepointObjects contains all objects after they have been loaded into the kernel.
//
// It can be passed to loadTracepointObjects or ebpf.CollectionSpec.LoadAndAssign.
type tracepointObjects struct {
tracepointPrograms
tracepointMaps
tracepointVariables
}
func (o *tracepointObjects) Close() error {
return _TracepointClose(
&o.tracepointPrograms,
&o.tracepointMaps,
)
}
// tracepointMaps contains all maps after they have been loaded into the kernel.
//
// It can be passed to loadTracepointObjects or ebpf.CollectionSpec.LoadAndAssign.
type tracepointMaps struct {
Events *ebpf.Map `ebpf:"events"`
TargetFilenameMap *ebpf.Map `ebpf:"target_filename_map"`
}
func (m *tracepointMaps) Close() error {
return _TracepointClose(
m.Events,
m.TargetFilenameMap,
)
}
// tracepointVariables contains all global variables after they have been loaded into the kernel.
//
// It can be passed to loadTracepointObjects or ebpf.CollectionSpec.LoadAndAssign.
type tracepointVariables struct {
}
// tracepointPrograms contains all programs after they have been loaded into the kernel.
//
// It can be passed to loadTracepointObjects or ebpf.CollectionSpec.LoadAndAssign.
type tracepointPrograms struct {
TraceOpenat *ebpf.Program `ebpf:"trace_openat"`
}
func (p *tracepointPrograms) Close() error {
return _TracepointClose(
p.TraceOpenat,
)
}
func _TracepointClose(closers ...io.Closer) error {
for _, closer := range closers {
if err := closer.Close(); err != nil {
return err
}
}
return nil
}
// Do not access this directly.
//
//go:embed tracepoint_bpfel.o
var _TracepointBytes []byte

BIN
tracepoint_bpfel.o Normal file

Binary file not shown.