aboutsummaryrefslogtreecommitdiffstats
path: root/pkg/cover/backend
diff options
context:
space:
mode:
authorJoey Jiao <joeyjiaojg@gmail.com>2021-06-24 08:52:50 +0800
committerDmitry Vyukov <dvyukov@google.com>2021-06-25 16:24:23 +0200
commitae6bf8ddebd14f2e21c155c0bdf555b92d3eaf7a (patch)
tree05a2755fb9f3f294205fc04f4fb270661aaf010f /pkg/cover/backend
parent0edbbe3140b553039d2ccaaf4d870cfb62f3864a (diff)
all: fix arm64 runtime pc not align with elf
Diffstat (limited to 'pkg/cover/backend')
-rw-r--r--pkg/cover/backend/dwarf.go24
-rw-r--r--pkg/cover/backend/elf.go14
2 files changed, 24 insertions, 14 deletions
diff --git a/pkg/cover/backend/dwarf.go b/pkg/cover/backend/dwarf.go
index 23a1e8ce9..7a9abd221 100644
--- a/pkg/cover/backend/dwarf.go
+++ b/pkg/cover/backend/dwarf.go
@@ -7,6 +7,7 @@ import (
"bufio"
"bytes"
"debug/dwarf"
+ "debug/elf"
"encoding/binary"
"fmt"
"io/ioutil"
@@ -30,25 +31,30 @@ type containerFns struct {
}
type Arch struct {
- callLen int
- opcodeOffset int
- opcodes [2]byte
- target func(arch *Arch, insn []byte, pc uint64, opcode byte) uint64
+ callLen int
+ relaOffset uint64
+ opcodeOffset int
+ opcodes [2]byte
+ callRelocType uint64
+ target func(arch *Arch, insn []byte, pc uint64, opcode byte) uint64
}
var arches = map[string]Arch{
targets.AMD64: {
- callLen: 5,
- opcodes: [2]byte{0xe8, 0xe8},
+ callLen: 5,
+ relaOffset: 1,
+ opcodes: [2]byte{0xe8, 0xe8},
+ callRelocType: uint64(elf.R_X86_64_PLT32),
target: func(arch *Arch, insn []byte, pc uint64, opcode byte) uint64 {
off := uint64(int64(int32(binary.LittleEndian.Uint32(insn[1:]))))
return pc + off + uint64(arch.callLen)
},
},
targets.ARM64: {
- callLen: 4,
- opcodeOffset: 3,
- opcodes: [2]byte{0x94, 0x97},
+ callLen: 4,
+ opcodeOffset: 3,
+ opcodes: [2]byte{0x94, 0x97},
+ callRelocType: uint64(elf.R_AARCH64_CALL26),
target: func(arch *Arch, insn []byte, pc uint64, opcode byte) uint64 {
off := uint64(binary.LittleEndian.Uint32(insn)) & ((1 << 24) - 1)
if opcode == arch.opcodes[1] {
diff --git a/pkg/cover/backend/elf.go b/pkg/cover/backend/elf.go
index 94e6fdd8c..227356eef 100644
--- a/pkg/cover/backend/elf.go
+++ b/pkg/cover/backend/elf.go
@@ -40,7 +40,9 @@ func elfReadSymbols(module *Module, info *symbolInfo) ([]*Symbol, error) {
if err != nil {
return nil, fmt.Errorf("failed to read ELF symbols: %v", err)
}
- info.textAddr = text.Addr
+ if module.Name == "" {
+ info.textAddr = text.Addr
+ }
var symbols []*Symbol
for i, symb := range allSymbols {
text := symb.Value >= text.Addr && symb.Value+symb.Size <= text.Addr+text.Size
@@ -133,7 +135,8 @@ func elfReadModuleCoverPoints(target *targets.Target, module *Module, info *symb
if err != nil {
return pcs, err
}
- offset := uint64(arches[target.Arch].opcodeOffset)
+ callRelocType := arches[target.Arch].callRelocType
+ relaOffset := arches[target.Arch].relaOffset
for _, s := range file.Sections {
if s.Type != elf.SHT_RELA { // nolint: misspell
continue
@@ -146,10 +149,11 @@ func elfReadModuleCoverPoints(target *targets.Target, module *Module, info *symb
}
return pcs, err
}
- // Note: this assumes that call instruction is 1 byte.
- pc := module.Addr + rel.Off - 1
+ if (rel.Info & 0xffffffff) != callRelocType {
+ continue
+ }
+ pc := module.Addr + rel.Off - relaOffset
index := int(elf.R_SYM64(rel.Info)) - 1
- pc -= offset
if info.tracePCIdx[index] {
pcs[0] = append(pcs[0], pc)
} else if info.traceCmpIdx[index] {