From 46a49eb52e6402708446a7a71db8a29dbdb99139 Mon Sep 17 00:00:00 2001 From: Cherry Mui Date: Thu, 6 Apr 2023 20:26:55 -0400 Subject: [PATCH] cmd/internal/objfile: align the load address of ELF binary The ELF ABI just requires that the address and the offset of a segment are congruent modulo the alignment, but does not require the start address to be aligned. While usually the segment's start address is aligned, apparently the zig linker generates binary with unaligned address. At the run time, the memory mapping that contains the segment starts at an aligned address (rounding down). Use the aligned address for the load address, which matches the mapping. Apparently this is what the pprof library expects. Fixes #59466. Change-Id: Ife78909b20b7bc975ac4c76f2c5f5db325ddec9b Reviewed-on: https://go-review.googlesource.com/c/go/+/483035 TryBot-Result: Gopher Robot Reviewed-by: Than McIntosh Run-TryBot: Cherry Mui --- src/cmd/internal/objfile/elf.go | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/cmd/internal/objfile/elf.go b/src/cmd/internal/objfile/elf.go index c64c2540f4e..f25e4a65d6e 100644 --- a/src/cmd/internal/objfile/elf.go +++ b/src/cmd/internal/objfile/elf.go @@ -134,7 +134,12 @@ func (f *elfFile) goarch() string { func (f *elfFile) loadAddress() (uint64, error) { for _, p := range f.elf.Progs { if p.Type == elf.PT_LOAD && p.Flags&elf.PF_X != 0 { - return p.Vaddr, nil + // The memory mapping that contains the segment + // starts at an aligned address. Apparently this + // is what pprof expects, as it uses this and the + // start address of the mapping to compute PC + // delta. + return p.Vaddr - p.Vaddr%p.Align, nil } } return 0, fmt.Errorf("unknown load address")