From f997662837a2cfc302b034e33da7a2dd900277a2 Mon Sep 17 00:00:00 2001 From: Leon Hwang Date: Sun, 24 Nov 2024 22:41:52 +0800 Subject: [PATCH] bpflbr: Remove vmlinux requirement for disasm Signed-off-by: Leon Hwang --- internal/bpflbr/disasm.go | 29 ++++++++++++++++++++--------- internal/bpflbr/dump.go | 34 ++++++++++++++++++++++++---------- internal/bpflbr/error.go | 8 ++++++++ internal/bpflbr/lbr.go | 4 ++++ internal/bpflbr/vmlinux.go | 2 +- main.go | 28 +++++++++++++++++++--------- 6 files changed, 76 insertions(+), 29 deletions(-) create mode 100644 internal/bpflbr/error.go diff --git a/internal/bpflbr/disasm.go b/internal/bpflbr/disasm.go index ad2453a..e640aa3 100644 --- a/internal/bpflbr/disasm.go +++ b/internal/bpflbr/disasm.go @@ -5,6 +5,7 @@ package bpflbr import ( "debug/elf" + "errors" "fmt" "os" "strconv" @@ -81,19 +82,29 @@ func dumpKfunc(kfunc string, bytes uint) { data, ok := readKcore(kaddr, uint(bytes)) assert.True(ok, "Failed to read kcore for %s", kfunc) + var addr2line *Addr2Line + vmlinux, err := FindVmlinux() - assert.NoErr(err, "Failed to find vmlinux: %v") - VerboseLog("Found vmlinux: %s", vmlinux) + if err != nil { + if errors.Is(err, ErrNotFound) { + VerboseLog("Dbgsym vmlinux not found") + } else { + assert.NoErr(err, "Failed to find vmlinux: %v") + } + } + if err == nil { + VerboseLog("Found vmlinux: %s", vmlinux) - textAddr, err := ReadTextAddrFromVmlinux(vmlinux) - assert.NoErr(err, "Failed to read .text address from vmlinux: %v") + textAddr, err := ReadTextAddrFromVmlinux(vmlinux) + assert.NoErr(err, "Failed to read .text address from vmlinux: %v") - kaslrOffset := textAddr - kallsyms.Stext() - VerboseLog("KASLR offset: %#x", kaslrOffset) + kaslrOffset := textAddr - kallsyms.Stext() + VerboseLog("KASLR offset: 0x%x", kaslrOffset) - VerboseLog("Creating addr2line from vmlinux ..") - addr2line, err := NewAddr2Line(vmlinux, kaslrOffset, kallsyms.SysBPF()) - assert.NoErr(err, "Failed to create addr2line: %v") + VerboseLog("Creating addr2line from vmlinux ..") + addr2line, err = NewAddr2Line(vmlinux, kaslrOffset, kallsyms.SysBPF()) + assert.NoErr(err, "Failed to create addr2line: %v") + } engine, err := gapstone.New(int(gapstone.CS_ARCH_X86), int(gapstone.CS_MODE_64)) assert.NoErr(err, "Failed to create engine: %v") diff --git a/internal/bpflbr/dump.go b/internal/bpflbr/dump.go index 78ef285..2495863 100644 --- a/internal/bpflbr/dump.go +++ b/internal/bpflbr/dump.go @@ -4,6 +4,7 @@ package bpflbr import ( + "errors" "fmt" "log" "strconv" @@ -35,19 +36,29 @@ func DumpProg(pf []ProgFlag) { kallsyms, err := NewKallsyms() assert.NoErr(err, "Failed to read /proc/kallsyms: %v") + var addr2line *Addr2Line + vmlinux, err := FindVmlinux() - assert.NoErr(err, "Failed to find vmlinux: %v") - VerboseLog("Found vmlinux: %s", vmlinux) + if err != nil { + if errors.Is(err, ErrNotFound) { + VerboseLog("Dbgsym vmlinux not found") + } else { + assert.NoErr(err, "Failed to find vmlinux: %v") + } + } + if err == nil { + VerboseLog("Found vmlinux: %s", vmlinux) - textAddr, err := ReadTextAddrFromVmlinux(vmlinux) - assert.NoErr(err, "Failed to read .text address from vmlinux: %v") + textAddr, err := ReadTextAddrFromVmlinux(vmlinux) + assert.NoErr(err, "Failed to read .text address from vmlinux: %v") - kaslrOffset := textAddr - kallsyms.Stext() - VerboseLog("KASLR offset: %#x", kaslrOffset) + kaslrOffset := textAddr - kallsyms.Stext() + VerboseLog("KASLR offset: 0x%x", kaslrOffset) - VerboseLog("Creating addr2line from vmlinux ..") - addr2line, err := NewAddr2Line(vmlinux, kaslrOffset, kallsyms.SysBPF()) - assert.NoErr(err, "Failed to create addr2line: %v") + VerboseLog("Creating addr2line from vmlinux ..") + addr2line, err = NewAddr2Line(vmlinux, kaslrOffset, kallsyms.SysBPF()) + assert.NoErr(err, "Failed to create addr2line: %v") + } engine, err := gapstone.New(int(gapstone.CS_ARCH_X86), int(gapstone.CS_MODE_64)) assert.NoErr(err, "Failed to create engine: %v") @@ -134,7 +145,10 @@ func DumpProg(pf []ProgFlag) { } } if endpoint != nil { - fmt.Fprintf(&sb, "\t; %s+%#x %s:%d", endpoint.funcName, endpoint.offset, endpoint.fileName, endpoint.fileLine) + fmt.Fprintf(&sb, "\t; %s+%#x", endpoint.funcName, endpoint.offset) + if endpoint.fileName != "" { + fmt.Fprintf(&sb, " %s:%d", endpoint.fileName, endpoint.fileLine) + } if endpoint.isProg { fmt.Fprintf(&sb, " [bpf]") } diff --git a/internal/bpflbr/error.go b/internal/bpflbr/error.go new file mode 100644 index 0000000..f2604eb --- /dev/null +++ b/internal/bpflbr/error.go @@ -0,0 +1,8 @@ +// Copyright 2024 Leon Hwang. +// SPDX-License-Identifier: Apache-2.0 + +package bpflbr + +import "errors" + +var ErrNotFound = errors.New("not found") diff --git a/internal/bpflbr/lbr.go b/internal/bpflbr/lbr.go index 265ab11..c3eee42 100644 --- a/internal/bpflbr/lbr.go +++ b/internal/bpflbr/lbr.go @@ -144,6 +144,10 @@ func getLineInfo(addr uintptr, progs *bpfProgs, a2l *Addr2Line, ksyms *Kallsyms) ep.offset = addr - uintptr(ksym.addr) } + if a2l == nil { + return &ep + } + li, err := a2l.get(addr) if err != nil { return &ep diff --git a/internal/bpflbr/vmlinux.go b/internal/bpflbr/vmlinux.go index b27827e..d87645d 100644 --- a/internal/bpflbr/vmlinux.go +++ b/internal/bpflbr/vmlinux.go @@ -58,7 +58,7 @@ func FindVmlinux() (string, error) { } } - return "", errors.New("vmlinux file not found") + return "", ErrNotFound } // ReadTextAddrFromVmlinux reads .text section address from vmlinux file. diff --git a/main.go b/main.go index 9134710..3ae635f 100644 --- a/main.go +++ b/main.go @@ -58,19 +58,29 @@ func main() { kallsyms, err := bpflbr.NewKallsyms() assert.NoErr(err, "Failed to read /proc/kallsyms: %v") + var addr2line *bpflbr.Addr2Line + vmlinux, err := bpflbr.FindVmlinux() - assert.NoErr(err, "Failed to find vmlinux: %v") - bpflbr.VerboseLog("Found vmlinux: %s", vmlinux) + if err != nil { + if errors.Is(err, bpflbr.ErrNotFound) { + bpflbr.VerboseLog("Dbgsym vmlinux not found") + } else { + assert.NoErr(err, "Failed to find vmlinux: %v") + } + } + if err == nil { + bpflbr.VerboseLog("Found vmlinux: %s", vmlinux) - textAddr, err := bpflbr.ReadTextAddrFromVmlinux(vmlinux) - assert.NoErr(err, "Failed to read .text address from vmlinux: %v") + textAddr, err := bpflbr.ReadTextAddrFromVmlinux(vmlinux) + assert.NoErr(err, "Failed to read .text address from vmlinux: %v") - kaslrOffset := textAddr - kallsyms.Stext() - bpflbr.VerboseLog("KASLR offset: 0x%x", kaslrOffset) + kaslrOffset := textAddr - kallsyms.Stext() + bpflbr.VerboseLog("KASLR offset: 0x%x", kaslrOffset) - bpflbr.VerboseLog("Creating addr2line from vmlinux ..") - addr2line, err := bpflbr.NewAddr2Line(vmlinux, kaslrOffset, kallsyms.SysBPF()) - assert.NoErr(err, "Failed to create addr2line: %v") + bpflbr.VerboseLog("Creating addr2line from vmlinux ..") + addr2line, err = bpflbr.NewAddr2Line(vmlinux, kaslrOffset, kallsyms.SysBPF()) + assert.NoErr(err, "Failed to create addr2line: %v") + } engine, err := gapstone.New(int(gapstone.CS_ARCH_X86), int(gapstone.CS_MODE_64)) assert.NoErr(err, "Failed to create capstone engine: %v")