diff options
| author | Joey Jiao <joeyjiaojg@gmail.com> | 2021-06-24 08:52:50 +0800 |
|---|---|---|
| committer | Dmitry Vyukov <dvyukov@google.com> | 2021-06-25 16:24:23 +0200 |
| commit | ae6bf8ddebd14f2e21c155c0bdf555b92d3eaf7a (patch) | |
| tree | 05a2755fb9f3f294205fc04f4fb270661aaf010f /pkg/cover/backend | |
| parent | 0edbbe3140b553039d2ccaaf4d870cfb62f3864a (diff) | |
all: fix arm64 runtime pc not align with elf
Diffstat (limited to 'pkg/cover/backend')
| -rw-r--r-- | pkg/cover/backend/dwarf.go | 24 | ||||
| -rw-r--r-- | pkg/cover/backend/elf.go | 14 |
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] { |
