delve/vendor/github.com/aquasecurity/libbpfgo/helpers/elf.go
2021-07-31 17:16:26 +02:00

53 lines
1.4 KiB
Go

package helpers
import (
"debug/elf"
"errors"
"fmt"
)
// SymbolToOffset attempts to resolve a 'symbol' name in the binary found at
// 'path' to an offset. The offset can be used for attaching a u(ret)probe
func SymbolToOffset(path, symbol string) (uint32, error) {
f, err := elf.Open(path)
if err != nil {
return 0, fmt.Errorf("could not open elf file to resolve symbol offset: %v", err)
}
syms, err := f.Symbols()
if err != nil {
return 0, fmt.Errorf("could not open symbol section to resolve symbol offset: %v", err)
}
sectionsToSearchForSymbol := []*elf.Section{}
for i := range f.Sections {
if f.Sections[i].Flags == elf.SHF_ALLOC+elf.SHF_EXECINSTR {
sectionsToSearchForSymbol = append(sectionsToSearchForSymbol, f.Sections[i])
}
}
var executableSection *elf.Section
for i := range syms {
if syms[i].Name == symbol {
// Find what section the symbol is in by checking the executable section's
// addr space.
for m := range sectionsToSearchForSymbol {
if syms[i].Value > sectionsToSearchForSymbol[m].Addr &&
syms[i].Value < sectionsToSearchForSymbol[m].Addr+sectionsToSearchForSymbol[m].Size {
executableSection = sectionsToSearchForSymbol[m]
}
}
if executableSection == nil {
return 0, errors.New("could not find symbol in executable sections of binary")
}
return uint32(syms[i].Value - executableSection.Addr + executableSection.Offset), nil
}
}
return 0, fmt.Errorf("symbol not found")
}