Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cmd/link: Setting rounding quantum to a value higher than 2M or smaller than 4K breaks. #62660

Closed
zhangfannie opened this issue Sep 15, 2023 · 6 comments
Labels
compiler/runtime Issues related to the Go compiler and/or runtime. NeedsFix The path to resolution is known, but the work has not been done.
Milestone

Comments

@zhangfannie
Copy link
Contributor

What version of Go are you using (go version)?

$ go version
go version devel go1.22-856cf23a8a Thu Sep 14 05:14:44 2023 +0000 linux/arm64

Does this issue reproduce with the latest release?

yes

What operating system and processor architecture are you using (go env)?

go env Output
$ go env


GO111MODULE='auto'
GOARCH='arm64'
GOBIN=''
GOCACHE='/home/fanzha02/.cache/go-build'
GOENV='/home/fanzha02/.config/go/env'
GOEXE=''
GOEXPERIMENT=''
GOFLAGS=''
GOHOSTARCH='arm64'
GOHOSTOS='linux'
GOINSECURE=''
GOMODCACHE='/home/fanzha02/go/pkg/mod'
GONOPROXY=''
GONOSUMDB=''
GOOS='linux'
GOPATH='/home/fanzha02/go'
GOPRIVATE=''
GOPROXY='https://proxy.golang.org,direct'
GOROOT='/home/fanzha02/work/go_project/govscode/gomain'
GOSUMDB='sum.golang.org'
GOTMPDIR=''
GOTOOLCHAIN='auto'
GOTOOLDIR='/home/fanzha02/work/go_project/govscode/gomain/pkg/tool/linux_arm64'
GOVCS=''
GOVERSION='devel go1.22-856cf23a8a Thu Sep 14 05:14:44 2023 +0000'
GCCGO='gccgo'
AR='ar'
CC='gcc'
CXX='g++'
CGO_ENABLED='1'
GOMOD='/home/fanzha02/work/go_project/govscode/gomain/src/go.mod'
GOWORK=''
CGO_CFLAGS='-O2 -g'
CGO_CPPFLAGS=''
CGO_CXXFLAGS='-O2 -g'
CGO_FFLAGS='-O2 -g'
CGO_LDFLAGS='-O2 -g'
PKG_CONFIG='pkg-config'
GOGCCFLAGS='-fPIC -pthread -Wl,--no-gc-sections -fmessage-length=0 -ffile-prefix-map=/tmp/go-build3689557035=/tmp/go-build -gno-record-gcc-switches'

What did you do?

Build a hello.go with:
$ go build -ldflags "-R 0x300000" -o hello_3M hello.go
Run with:
$ ./hello_3M

What did you expect to see?

Hello world!

What did you see instead?

Segment fault

@gopherbot gopherbot added the compiler/runtime Issues related to the Go compiler and/or runtime. label Sep 15, 2023
@zhangfannie
Copy link
Contributor Author

zhangfannie commented Sep 15, 2023

@cherrymui With fix patch #527822, trying different values of the -R flag, I noticed that the segment fault issue still occurs when passing value is larger than 2M or smaller than 4K on arm64 and amd64.

Output of compiling the program with -R 0x300000 on arm64 machine:

$ readelf -l ./hello_3M

Elf file type is EXEC (Executable file)
Entry point 0x35e7e0
There are 6 program headers, starting at offset 64

Program Headers:
  Type           Offset             VirtAddr           PhysAddr
                 FileSiz            MemSiz              Flags  Align
  PHDR           0x0000000000000040 0x0000000000300040 0x0000000000300040
                 0x0000000000000150 0x0000000000000150  R      0x300000
readelf: Error: the PHDR segment is not covered by a LOAD segment
  NOTE           0x0000000000000f9c 0x0000000000300f9c 0x0000000000300f9c
                 0x0000000000000064 0x0000000000000064  R      0x4
  LOAD           0xffffffffffe00000 0x0000000000100000 0x0000000000100000
                 0x000000000027ae64 0x000000000027ae64  R E    0x300000
  LOAD           0x0000000000100000 0x0000000000400000 0x0000000000400000
                 0x0000000000298740 0x0000000000298740  R      0x300000
  LOAD           0x0000000000600000 0x0000000000900000 0x0000000000900000
                 0x00000000000095c0 0x0000000000041730  RW     0x300000
  GNU_STACK      0x0000000000000000 0x0000000000000000 0x0000000000000000
                 0x0000000000000000 0x0000000000000000  RW     0x8

 Section to Segment mapping:
  Segment Sections...
   00
   01     .note.go.buildid
   02
   03     .rodata .typelink .itablink .gosymtab .gopclntab
   04     .go.buildinfo .noptrdata .data .bss .noptrbss
   05

From the log, we can notice that the first program header offset is less than 0, which should be the cause of the segment fault.
I wonder if we need to add some checks that when setting -R or -T results in incorrect values, an error is reported instead of a clueless segment fault.

@zhangfannie
Copy link
Contributor Author

I came up with another solution that may solve this problem, that is, if the frag is greater than e.Off , the alignment will not be performed.

func fixElfPhdr(e *ElfPhdr) {
	frag := int(e.Vaddr & (e.Align - 1))

	e.Off -= uint64(frag)
	e.Vaddr -= uint64(frag)
	e.Paddr -= uint64(frag)
	e.Filesz += uint64(frag)
	e.Memsz += uint64(frag)
}

@cherrymui
Copy link
Member

I don't think we really care about alignment less than 4K, which is the the minimal possible physical page size on many systems. If one sets -R less than 4K, it is asking for problems.

I'll look into the issue with alignment larger than 2M.

In the end we don't know or want to list exactly what memory layouts are supported on each system. We ensure the default works well. We do best effort support for some reasonable non-default values. Other than that, one is on their own.

@cherrymui cherrymui added this to the Unplanned milestone Sep 15, 2023
@cherrymui
Copy link
Member

0x300000 doesn't work not because it is larger than 2M, but because it is not a power of 2. 0x400000 does work. I think it is fine to reject -R value that is not a power of 2 or less than 4K. I don't think we need to go farther than that. I'll send a CL.

@heschi
Copy link
Contributor

heschi commented Sep 15, 2023

cc @golang/compiler

@heschi heschi added the NeedsFix The path to resolution is known, but the work has not been done. label Sep 15, 2023
@gopherbot
Copy link

Change https://go.dev/cl/528715 mentions this issue: cmd/link: reject invalid -R flag

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
compiler/runtime Issues related to the Go compiler and/or runtime. NeedsFix The path to resolution is known, but the work has not been done.
Projects
None yet
Development

No branches or pull requests

4 participants