From 69bc3eaa35c92378b58e5785e092b66b4b17e586 Mon Sep 17 00:00:00 2001 From: Dmitry Vyukov Date: Fri, 11 Dec 2020 18:04:06 +0100 Subject: pkg/cover: provide .text offset Move this logic out of syz-manager. It's too low level for manager and we have everything necessary to obtain it in pkg/cover without shelling out to readelf and parsing output. --- pkg/cover/backend/backend.go | 9 +++++---- pkg/cover/backend/elf.go | 22 ++++++++++++++-------- 2 files changed, 19 insertions(+), 12 deletions(-) (limited to 'pkg') diff --git a/pkg/cover/backend/backend.go b/pkg/cover/backend/backend.go index d712bcff8..7da6abfc5 100644 --- a/pkg/cover/backend/backend.go +++ b/pkg/cover/backend/backend.go @@ -9,10 +9,11 @@ import ( ) type Impl struct { - Units []*CompileUnit - Symbols []*Symbol - Frames []symbolizer.Frame - Symbolize func(pcs []uint64) ([]symbolizer.Frame, error) + Units []*CompileUnit + Symbols []*Symbol + Frames []symbolizer.Frame + TextOffset uint32 // high 32 bits of PCs + Symbolize func(pcs []uint64) ([]symbolizer.Frame, error) } type CompileUnit struct { diff --git a/pkg/cover/backend/elf.go b/pkg/cover/backend/elf.go index dba8e4f0f..0821f331a 100644 --- a/pkg/cover/backend/elf.go +++ b/pkg/cover/backend/elf.go @@ -29,15 +29,20 @@ func makeELF(target *targets.Target, objDir string) (*Impl, error) { } var coverPoints []uint64 var symbols []*Symbol + var textAddr uint64 errc := make(chan error, 1) go func() { var err error var tracePC uint64 - symbols, tracePC, err = readSymbols(file) + symbols, textAddr, tracePC, err = readSymbols(file) if err != nil { errc <- err return } + if target.OS == targets.FreeBSD { + // On FreeBSD .text address in ELF is 0, but .text is actually mapped at 0xffffffff. + textAddr = ^uint64(0) + } if target.Arch == targets.AMD64 { coverPoints, err = readCoverPoints(file, tracePC) } else { @@ -69,8 +74,9 @@ func makeELF(target *targets.Target, objDir string) (*Impl, error) { return nil, fmt.Errorf("failed to parse DWARF (set CONFIG_DEBUG_INFO=y?)") } impl := &Impl{ - Units: units, - Symbols: symbols, + Units: units, + Symbols: symbols, + TextOffset: uint32(textAddr >> 32), Symbolize: func(pcs []uint64) ([]symbolizer.Frame, error) { return symbolize(target, kernelObject, pcs) }, @@ -134,14 +140,14 @@ func buildSymbols(symbols []*Symbol, ranges []pcRange, coverPoints []uint64) []* return symbols } -func readSymbols(file *elf.File) ([]*Symbol, uint64, error) { +func readSymbols(file *elf.File) ([]*Symbol, uint64, uint64, error) { text := file.Section(".text") if text == nil { - return nil, 0, fmt.Errorf("no .text section in the object file") + return nil, 0, 0, fmt.Errorf("no .text section in the object file") } allSymbols, err := file.Symbols() if err != nil { - return nil, 0, fmt.Errorf("failed to read ELF symbols: %v", err) + return nil, 0, 0, fmt.Errorf("failed to read ELF symbols: %v", err) } var tracePC uint64 var symbols []*Symbol @@ -159,12 +165,12 @@ func readSymbols(file *elf.File) ([]*Symbol, uint64, error) { } } if tracePC == 0 { - return nil, 0, fmt.Errorf("no __sanitizer_cov_trace_pc symbol in the object file") + return nil, 0, 0, fmt.Errorf("no __sanitizer_cov_trace_pc symbol in the object file") } sort.Slice(symbols, func(i, j int) bool { return symbols[i].Start < symbols[j].Start }) - return symbols, tracePC, nil + return symbols, text.Addr, tracePC, nil } func readTextRanges(file *elf.File) ([]pcRange, []*CompileUnit, error) { -- cgit mrf-deployment