Created
September 2, 2021 02:56
-
-
Save prashantv/07d8d8a46322127cc9c4ff1001476265 to your computer and use it in GitHub Desktop.
elf symbol lookup file offset
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package elfsym | |
import ( | |
"bytes" | |
"debug/elf" | |
"fmt" | |
"io/ioutil" | |
) | |
type Symbol struct { | |
elfSym elf.Symbol | |
fileOffset uint64 | |
} | |
func (s *Symbol) Name() string { | |
return s.elfSym.Name | |
} | |
func (s *Symbol) FileOffset() uint64 { | |
return s.fileOffset | |
} | |
func Lookup(binary, symbol string) (*Symbol, error) { | |
bs, err := ioutil.ReadFile(binary) | |
if err != nil { | |
return nil, fmt.Errorf("load file: %w", err) | |
} | |
e, err := elf.NewFile(bytes.NewReader(bs)) | |
if err != nil { | |
return nil, fmt.Errorf("parse ELF: %w", err) | |
} | |
syms, err := e.Symbols() | |
if err != nil { | |
return nil, fmt.Errorf("load symbols: %w", err) | |
} | |
for _, s := range syms { | |
if s.Name == symbol { | |
return createSymbol(s, e.Progs) | |
} | |
} | |
return nil, fmt.Errorf("could not find symbol %q", symbol) | |
} | |
func createSymbol(sym elf.Symbol, progs []*elf.Prog) (*Symbol, error) { | |
// sym.Value is the virtual address, but we want the physical offset | |
// so we map to the physical offset using any PT_LOAD program headers | |
// that apply to this location. | |
var offsetFix uint64 | |
for _, p := range progs { | |
if p.Type != elf.PT_LOAD { | |
continue | |
} | |
if sym.Value >= p.Vaddr && sym.Value <= (p.Vaddr+p.Filesz) { | |
offsetFix += p.Off - p.Vaddr | |
} | |
} | |
return &Symbol{ | |
elfSym: sym, | |
fileOffset: sym.Value + offsetFix, | |
}, nil | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment