diff options
| author | Dmitry Vyukov <dvyukov@google.com> | 2023-02-17 11:17:18 +0100 |
|---|---|---|
| committer | Dmitry Vyukov <dvyukov@google.com> | 2023-02-17 15:02:29 +0100 |
| commit | cf8c2d3920e29515c91e0b0797b4b432369d1a7d (patch) | |
| tree | 4edb1d0ee739b3ce1009a548b48e9a67f27d5418 /pkg | |
| parent | 95d024ce4254a321e35cc93ef67b1d8d6cee1d26 (diff) | |
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.
Diffstat (limited to 'pkg')
| -rw-r--r-- | pkg/cover/backend/dwarf.go | 33 | ||||
| -rw-r--r-- | pkg/cover/backend/elf.go | 21 |
2 files changed, 36 insertions, 18 deletions
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, |
