From cf8c2d3920e29515c91e0b0797b4b432369d1a7d Mon Sep 17 00:00:00 2001 From: Dmitry Vyukov Date: Fri, 17 Feb 2023 11:17:18 +0100 Subject: pkg/cover/backend: apply PC fix up only if .plt section is present We don't have much info about the case where the fix up was needed, nor we have any tests, but based on the existing comment it seems that the fix up should be applied only the kernel contains .plt section. --- pkg/cover/backend/dwarf.go | 33 +++++++++++++++------------------ pkg/cover/backend/elf.go | 21 +++++++++++++++++++++ 2 files changed, 36 insertions(+), 18 deletions(-) (limited to 'pkg') diff --git a/pkg/cover/backend/dwarf.go b/pkg/cover/backend/dwarf.go index 6f5bf59e9..e696421de 100644 --- a/pkg/cover/backend/dwarf.go +++ b/pkg/cover/backend/dwarf.go @@ -24,12 +24,16 @@ import ( ) type dwarfParams struct { - target *targets.Target - objDir string - srcDir string - buildDir string - moduleObj []string - hostModules []host.KernelModule + target *targets.Target + objDir string + srcDir string + buildDir string + moduleObj []string + hostModules []host.KernelModule + // Kernel coverage PCs in the [pcFixUpStart,pcFixUpEnd) range are offsetted by pcFixUpOffset. + pcFixUpStart uint64 + pcFixUpEnd uint64 + pcFixUpOffset uint64 readSymbols func(*Module, *symbolInfo) ([]*Symbol, error) readTextData func(*Module) ([]byte, error) readModuleCoverPoints func(*targets.Target, *Module, *symbolInfo) ([2][]uint64, error) @@ -189,23 +193,16 @@ func makeDWARFUnsafe(params *dwarfParams) (*Impl, error) { Symbolize: func(pcs map[*Module][]uint64) ([]Frame, error) { return symbolize(target, objDir, srcDir, buildDir, pcs) }, - RestorePC: makeRestorePC(target, pcBase), + RestorePC: makeRestorePC(params, pcBase), } return impl, nil } -func makeRestorePC(target *targets.Target, pcBase uint64) func(pc uint32) uint64 { +func makeRestorePC(params *dwarfParams, pcBase uint64) func(pc uint32) uint64 { return func(pcLow uint32) uint64 { - pc := PreviousInstructionPC(target, RestorePC(pcLow, uint32(pcBase>>32))) - // On arm64 as PLT is enabled by default, .text section is loaded after .plt section, - // so there is 0x18 bytes offset from module load address for .text section - // we need to remove the 0x18 bytes offset in order to correct module symbol address - if target.Arch == targets.ARM64 { - // TODO: avoid to hardcode the address - // Fix up kernel PCs, but not the test (userspace) PCs. - if pc >= 0x8000000000000000 && pc < 0xffffffd010000000 { - pc -= 0x18 - } + pc := PreviousInstructionPC(params.target, RestorePC(pcLow, uint32(pcBase>>32))) + if pc >= params.pcFixUpStart && pc < params.pcFixUpEnd { + pc -= params.pcFixUpOffset } return pc } diff --git a/pkg/cover/backend/elf.go b/pkg/cover/backend/elf.go index 5bc9fdfad..57908f43a 100644 --- a/pkg/cover/backend/elf.go +++ b/pkg/cover/backend/elf.go @@ -8,6 +8,7 @@ import ( "encoding/binary" "fmt" "io" + "path/filepath" "strings" "github.com/google/syzkaller/pkg/host" @@ -17,6 +18,23 @@ import ( func makeELF(target *targets.Target, objDir, srcDir, buildDir string, moduleObj []string, hostModules []host.KernelModule) (*Impl, error) { + var pcFixUpStart, pcFixUpEnd, pcFixUpOffset uint64 + if target.Arch == targets.ARM64 { + // On arm64 as PLT is enabled by default, .text section is loaded after .plt section, + // so there is 0x18 bytes offset from module load address for .text section + // we need to remove the 0x18 bytes offset in order to correct module symbol address + // TODO: obtain these values from the binary instead of hardcoding. + file, err := elf.Open(filepath.Join(objDir, target.KernelObject)) + if err != nil { + return nil, err + } + defer file.Close() + if file.Section(".plt") != nil { + pcFixUpStart = 0x8000000000000000 + pcFixUpEnd = 0xffffffd010000000 + pcFixUpOffset = 0x18 + } + } return makeDWARF(&dwarfParams{ target: target, objDir: objDir, @@ -24,6 +42,9 @@ func makeELF(target *targets.Target, objDir, srcDir, buildDir string, buildDir: buildDir, moduleObj: moduleObj, hostModules: hostModules, + pcFixUpStart: pcFixUpStart, + pcFixUpEnd: pcFixUpEnd, + pcFixUpOffset: pcFixUpOffset, readSymbols: elfReadSymbols, readTextData: elfReadTextData, readModuleCoverPoints: elfReadModuleCoverPoints, -- cgit mrf-deployment