/
elf.go
59 lines (47 loc) · 1.9 KB
/
elf.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
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: %w", err)
}
regularSymbols, regularSymbolsErr := f.Symbols()
dynamicSymbols, dynamicSymbolsErr := f.DynamicSymbols()
// Only if we failed getting both regular and dynamic symbols - then we abort.
if regularSymbolsErr != nil && dynamicSymbolsErr != nil {
return 0, fmt.Errorf("could not open regular or dynamic symbol sections to resolve symbol offset: %w %s", regularSymbolsErr, dynamicSymbolsErr)
}
// Concatenating into a single list.
// The list can have duplications, but we will find the first occurrence which is sufficient.
syms := append(regularSymbols, dynamicSymbols...)
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 j := range syms {
if syms[j].Name == symbol {
// Find what section the symbol is in by checking the executable section's
// addr space.
for m := range sectionsToSearchForSymbol {
if syms[j].Value > sectionsToSearchForSymbol[m].Addr &&
syms[j].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[j].Value - executableSection.Addr + executableSection.Offset), nil
}
}
return 0, fmt.Errorf("symbol %s not found in %s", symbol, path)
}