Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

link,kprobe: add arch prefixes for portable syscall wrapper support #304

Merged
merged 3 commits into from
Jun 10, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion examples/kprobe/bpf/kprobe_example.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ struct bpf_map_def SEC("maps") kprobe_map = {
.max_entries = 1,
};

SEC("kprobe/__x64_sys_execve")
SEC("kprobe/sys_execve")
int kprobe_execve() {
u32 key = 0;
u64 initval = 1, *valp;
Expand Down
4 changes: 2 additions & 2 deletions examples/kprobe/main.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// +build linux

// This program demonstrates attaching an eBPF program to a kernel symbol.
// The eBPF program will be attached to the start of the __x64_sys_execve
// The eBPF program will be attached to the start of the
// kernel function and prints out the number of times it has been called
// every second.
package main
Expand All @@ -24,7 +24,7 @@ const mapKey uint32 = 0
func main() {

// Name of the kernel function to trace.
fn := "__x64_sys_execve"
fn := "sys_execve"

// Subscribe to signals for terminating the program.
stopper := make(chan os.Signal, 1)
Expand Down
10 changes: 8 additions & 2 deletions link/kprobe.go
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,10 @@ func kprobe(symbol string, prog *ebpf.Program, ret bool) (*perfEvent, error) {
}

// Use kprobe PMU if the kernel has it available.
tp, err := pmuKprobe(symbol, ret)
tp, err := pmuKprobe(platformPrefix(symbol), ret)
if errors.Is(err, os.ErrNotExist) {
tp, err = pmuKprobe(symbol, ret)
}
if err == nil {
return tp, nil
}
Expand All @@ -140,7 +143,10 @@ func kprobe(symbol string, prog *ebpf.Program, ret bool) (*perfEvent, error) {
}

// Use tracefs if kprobe PMU is missing.
tp, err = tracefsKprobe(symbol, ret)
tp, err = tracefsKprobe(platformPrefix(symbol), ret)
if errors.Is(err, os.ErrNotExist) {
tp, err = tracefsKprobe(symbol, ret)
}
if err != nil {
return nil, fmt.Errorf("creating trace event '%s' in tracefs: %w", symbol, err)
}
Expand Down
13 changes: 2 additions & 11 deletions link/kprobe_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -288,18 +288,9 @@ func TestDetermineRetprobeBit(t *testing.T) {
func TestKprobeProgramCall(t *testing.T) {
m, p := newUpdaterMapProg(t, ebpf.Kprobe)

// Open Kprobe on `__x64_sys_getpid` and attach it
// Open Kprobe on `sys_getpid` and attach it
// to the ebpf program created above.
k, err := Kprobe("__x64_sys_getpid", p)
if errors.Is(err, os.ErrNotExist) {
// Use the correct symbol based on the kernel version.
// Since 4.17, syscalls symbols are generated with the `__x64_` prefix.
// https://github.com/torvalds/linux/commit/d5a00528b58cdb2c71206e18bd021e34c4eab878
k, err = Kprobe("sys_getpid", p)
if err != nil {
t.Fatal(err)
}
}
k, err := Kprobe("sys_getpid", p)
if err != nil {
t.Fatal(err)
}
Expand Down
2 changes: 1 addition & 1 deletion link/perf_event_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ func TestTraceEventTypePMU(t *testing.T) {
func TestTraceEventID(t *testing.T) {
c := qt.New(t)

eid, err := getTraceEventID("syscalls", "sys_enter_fork")
eid, err := getTraceEventID("syscalls", "sys_enter_execve")
lmb marked this conversation as resolved.
Show resolved Hide resolved
c.Assert(err, qt.IsNil)
c.Assert(eid, qt.Not(qt.Equals), 0)
}
Expand Down
25 changes: 25 additions & 0 deletions link/platform.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package link

import (
"fmt"
"runtime"
)

func platformPrefix(symbol string) string {

prefix := runtime.GOARCH

// per https://github.com/golang/go/blob/master/src/go/build/syslist.go
switch prefix {
ti-mo marked this conversation as resolved.
Show resolved Hide resolved
case "386":
prefix = "ia32"
case "amd64", "amd64p32":
prefix = "x64"
case "arm64", "arm64be":
prefix = "arm64"
default:
return symbol
}
ti-mo marked this conversation as resolved.
Show resolved Hide resolved

return fmt.Sprintf("__%s_%s", prefix, symbol)
}
2 changes: 1 addition & 1 deletion link/tracepoint_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ func TestTracepointErrors(t *testing.T) {
}

func TestTraceGetEventID(t *testing.T) {
_, err := getTraceEventID("syscalls", "sys_enter_open")
_, err := getTraceEventID("syscalls", "sys_enter_openat")
lmb marked this conversation as resolved.
Show resolved Hide resolved
if err != nil {
t.Fatal("Can't read trace event ID:", err)
}
Expand Down
7 changes: 7 additions & 0 deletions testdata/docker/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,13 @@ Building the image requires Docker. Run the build with:

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:
Expand Down