From 210b97903b1182dbe4f6c51091223f1438f27003 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20R=C3=BChsen?= Date: Wed, 13 Nov 2024 17:47:54 +0100 Subject: [PATCH 1/4] Remove unused StrDataPtr() --- stringutil/stringutil.go | 5 ----- 1 file changed, 5 deletions(-) diff --git a/stringutil/stringutil.go b/stringutil/stringutil.go index 3d8b4a88..06a19988 100644 --- a/stringutil/stringutil.go +++ b/stringutil/stringutil.go @@ -84,8 +84,3 @@ func SplitN(s, sep string, f []string) int { func ByteSlice2String(b []byte) string { return *(*string)(unsafe.Pointer(&b)) } - -// StrDataPtr returns the string's underlying Data pointer through reflection. -func StrDataPtr(s string) *byte { - return unsafe.StringData(s) -} From 7ee48672580e777691702889dda1fcdfeb32c5d6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20R=C3=BChsen?= Date: Wed, 13 Nov 2024 17:49:16 +0100 Subject: [PATCH 2/4] Removed unused WriteTempFile() --- libpf/convenience.go | 20 -------------------- 1 file changed, 20 deletions(-) diff --git a/libpf/convenience.go b/libpf/convenience.go index 02c7cae1..1abdb604 100644 --- a/libpf/convenience.go +++ b/libpf/convenience.go @@ -5,9 +5,7 @@ package libpf // import "go.opentelemetry.io/ebpf-profiler/libpf" import ( "context" - "fmt" "math/rand/v2" - "os" "reflect" "time" "unsafe" @@ -15,24 +13,6 @@ import ( log "github.com/sirupsen/logrus" ) -// WriteTempFile writes a data buffer to a temporary file on the filesystem. It -// is the callers responsibility to clean up that file again. The function returns -// the filename if successful. -func WriteTempFile(data []byte, directory, prefix string) (string, error) { - file, err := os.CreateTemp(directory, prefix) - if err != nil { - return "", err - } - defer file.Close() - if _, err := file.Write(data); err != nil { - return "", fmt.Errorf("failed to write data to temporary file: %w", err) - } - if err := file.Sync(); err != nil { - return "", fmt.Errorf("failed to synchronize file data: %w", err) - } - return file.Name(), nil -} - // SleepWithJitter sleeps for baseDuration +/- jitter (jitter is [0..1]) func SleepWithJitter(baseDuration time.Duration, jitter float64) { time.Sleep(AddJitter(baseDuration, jitter)) From 38f97745f7a00f9c4f01b034fe11c459b8369f68 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20R=C3=BChsen?= Date: Wed, 13 Nov 2024 17:51:05 +0100 Subject: [PATCH 3/4] Removed unused TraceHashFromBytes() --- libpf/tracehash.go | 9 --------- 1 file changed, 9 deletions(-) diff --git a/libpf/tracehash.go b/libpf/tracehash.go index 71d1df22..be2bee3b 100644 --- a/libpf/tracehash.go +++ b/libpf/tracehash.go @@ -28,15 +28,6 @@ func TraceHashFromBytes(b []byte) (TraceHash, error) { return TraceHash{h}, nil } -// TraceHashFromString parses a byte slice of a trace hash into the internal data representation. -func TraceHashFromString(s string) (TraceHash, error) { - h, err := basehash.New128FromString(s) - if err != nil { - return TraceHash{}, err - } - return TraceHash{h}, nil -} - func (h TraceHash) Equal(other TraceHash) bool { return h.Hash128.Equal(other.Hash128) } From 278163909e7f1ee7d0ce6ce3dc819863f1825729 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20R=C3=BChsen?= Date: Wed, 13 Nov 2024 18:23:45 +0100 Subject: [PATCH 4/4] Removed unused functions from libpf/pfelf/pfelf.go --- libpf/pfelf/pfelf.go | 126 ------------------------------------------- 1 file changed, 126 deletions(-) diff --git a/libpf/pfelf/pfelf.go b/libpf/pfelf/pfelf.go index c3c66e08..a0dc8b67 100644 --- a/libpf/pfelf/pfelf.go +++ b/libpf/pfelf/pfelf.go @@ -20,24 +20,6 @@ import ( "go.opentelemetry.io/ebpf-profiler/libpf" ) -// SafeOpenELF opens the given ELF file in a safely way in that -// it recovers from panics inside elf.Open(). -// Under circumstances we see fatal errors from inside the runtime, which -// are not recoverable, e.g. "fatal error: runtime: out of memory". -func SafeOpenELF(name string) (elfFile *elf.File, err error) { - defer func() { - // debug/elf has issues with malformed ELF files - if r := recover(); r != nil { - if elfFile != nil { - elfFile.Close() - elfFile = nil - } - err = fmt.Errorf("failed to open ELF file (recovered from panic): %s", name) - } - }() - return elf.Open(name) -} - // HasDWARFData returns true if the provided ELF file contains actionable DWARF debugging // information. // This function does not call `elfFile.DWARF()` on purpose, as it can be extremely expensive in @@ -132,41 +114,6 @@ func GetDebugLink(elfFile *elf.File) (linkName string, crc32 int32, err error) { return ParseDebugLink(sectionData) } -// GetDebugAltLink returns the contents of the `.gnu_debugaltlink` section (path and build -// ID). If no link is present, ErrNoDebugLink is returned. -func GetDebugAltLink(elfFile *elf.File) (fileName, buildID string, err error) { - // The .gnu_debugaltlink section is not always present - sectionData, err := getSectionData(elfFile, ".gnu_debugaltlink") - if err != nil { - return "", "", ErrNoDebugLink - } - - // The whole .gnu_debugaltlink section consists of: - // 1) path to target (variable-length string) - // 2) null character separator (1 byte) - // 3) build ID (usually 20 bytes, but can vary) - // - // First, find the position of the null character: - nullCharIdx := bytes.IndexByte(sectionData, 0) - if nullCharIdx == -1 { - return "", "", nil - } - - // The path consists of all the characters before the first null character - path := strings.ToValidUTF8(string(sectionData[:nullCharIdx]), "") - - // Check that we can read a build ID: there should be at least 1 byte after the null character. - if nullCharIdx+1 == len(sectionData) { - return "", "", errors.New("malformed .gnu_debugaltlink section (missing build ID)") - } - - // The build ID consists of all the bytes after the first null character - buildIDBytes := sectionData[nullCharIdx+1:] - buildID = hex.EncodeToString(buildIDBytes) - - return path, buildID, nil -} - var ErrNoBuildID = errors.New("no build ID") var ubuntuKernelSignature = regexp.MustCompile(` \(Ubuntu[^)]*\)\n$`) @@ -303,32 +250,6 @@ func getNoteHexString(sectionBytes []byte, name string, noteType uint32) ( return hex.EncodeToString(sectionBytes[idxDataStart:idxDataEnd]), true, nil } -// GetLinuxBuildSalt extracts the linux kernel build salt from the provided ELF path. -// It is read from the .notes ELF section. -// It should be present in both kernel modules and the kernel image of most distro-vended kernel -// packages, and should be identical across all the files: kernel modules will have the same salt -// as their corresponding vmlinux image if they were built at the same time. -// This can be used to identify the kernel image corresponding to a module. -// See https://lkml.org/lkml/2018/7/3/1156 -func GetLinuxBuildSalt(filePath string) (salt string, found bool, err error) { - elfFile, err := SafeOpenELF(filePath) - if err != nil { - return "", false, fmt.Errorf("could not open %s: %w", filePath, err) - } - defer elfFile.Close() - - sectionData, err := getSectionData(elfFile, ".note.Linux") - if err != nil { - sectionData, err = getSectionData(elfFile, ".notes") - if err != nil { - return "", false, nil - } - } - - // 0x100 is defined as LINUX_ELFNOTE_BUILD_SALT in include/linux/build-salt.h - return getNoteHexString(sectionData, "Linux", 0x100) -} - func symbolMapFromELFSymbols(syms []elf.Symbol) *libpf.SymbolMap { symmap := &libpf.SymbolMap{} for _, sym := range syms { @@ -342,16 +263,6 @@ func symbolMapFromELFSymbols(syms []elf.Symbol) *libpf.SymbolMap { return symmap } -// GetSymbols gets the symbols of elf.File and returns them as libpf.SymbolMap for -// fast lookup by address and name. -func GetSymbols(elfFile *elf.File) (*libpf.SymbolMap, error) { - syms, err := elfFile.Symbols() - if err != nil { - return nil, err - } - return symbolMapFromELFSymbols(syms), nil -} - // GetDynamicSymbols gets the dynamic symbols of elf.File and returns them as libpf.SymbolMap for // fast lookup by address and name. func GetDynamicSymbols(elfFile *elf.File) (*libpf.SymbolMap, error) { @@ -362,43 +273,6 @@ func GetDynamicSymbols(elfFile *elf.File) (*libpf.SymbolMap, error) { return symbolMapFromELFSymbols(syms), nil } -// IsKernelModule returns true if the provided ELF file looks like a kernel module (an ELF with a -// .modinfo and .gnu.linkonce.this_module sections). -func IsKernelModule(file *elf.File) (bool, error) { - sectionFound, err := HasSection(file, ".modinfo") - if err != nil { - return false, err - } - - if !sectionFound { - return false, nil - } - - return HasSection(file, ".gnu.linkonce.this_module") -} - -// IsKernelImage returns true if the provided ELF file looks like a kernel image (an ELF with a -// __modver section). -func IsKernelImage(file *elf.File) (bool, error) { - return HasSection(file, "__modver") -} - -// IsKernelFile returns true if the provided ELF file looks like a kernel file (either a kernel -// image or a kernel module). -func IsKernelFile(file *elf.File) (bool, error) { - isModule, err := IsKernelImage(file) - if err != nil { - return false, err - } - - isImage, err := IsKernelModule(file) - if err != nil { - return false, err - } - - return isModule || isImage, nil -} - // IsGoBinary returns true if the provided file is a Go binary (= an ELF file with // a known Golang section). func IsGoBinary(file *elf.File) (bool, error) {