-
Notifications
You must be signed in to change notification settings - Fork 18k
runtime: document that freebsd/amd64 requires COMPAT_FREEBSD32 #7056
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
Labels
Milestone
Comments
Could you please review issue #7025 and try the recommendations in the issue. Labels changed: added repo-main, os-freebsd. |
Something rather bizarre seems to be happening here... the sys_freebsd_amd64.s file has no INT $0x80 instructions - they are all SYSCALL (as they should be for native AMD64). On a FreeBSD amd64 9.2-RELEASE host, a basic hello.go compiled with the Go 1.1.1 FreeBSD binary distribution results in the following for runtime.settls (note the 0x0f 0x05 syscall instruction): $ objdump -d hello 000000000041e2f0 <runtime.settls>: 41e2f0: 48 83 ec 08 sub $0x8,%rsp 41e2f4: 48 83 c7 10 add $0x10,%rdi 41e2f8: 48 89 3c 24 mov %rdi,(%rsp) 41e2fc: 48 89 e6 mov %rsp,%rsi 41e2ff: 48 c7 c7 81 00 00 00 mov $0x81,%rdi 41e306: 48 c7 c0 a5 00 00 00 mov $0xa5,%rax 41e30d: 0f 05 syscall ... The exact same code compiled with Go tip (or with the Go 1.2 binary distribution) produces the following (note the 0xcd 0x80 or int $0x80 instruction, along with the additional mov instruction): $ objdump -d hello 0000000000422120 <runtime.settls>: 422120: 48 83 ec 08 sub $0x8,%rsp 422124: 48 83 c7 10 add $0x10,%rdi 422128: 48 89 3c 24 mov %rdi,(%rsp) 42212c: 48 89 e6 mov %rsp,%rsi 42212f: 48 c7 c7 81 00 00 00 mov $0x81,%rdi 422136: 48 c7 c0 a5 00 00 00 mov $0xa5,%rax 42213d: 4c 89 d1 mov %r10,%rcx 422140: cd 80 int $0x80 ... Using Go tip to manually compile a .s file (with 'go tool 6a' and 'go tool 6l') that only has a main.init and main.main, both containing single SYSCALL instructions, results in the following: 6.out: file format elf64-x86-64-freebsd Disassembly of section .text: 0000000000400c00 <main.init>: 400c00: 0f 05 syscall ... 0000000000400c10 <main.main>: 400c10: 0f 05 syscall ... So the SYSCALL instruction is being preserved in this case. However, whatever is causing it is definitely converting the ASYSCALL into an AINT prior to liblink - changing the AINT opcode in liblink/asm6.c results in a corresponding binary change for runtime.settls and others. And this seems to be FreeBSD amd64 specific (it does not happen on linux/amd64 or openbsd/amd64...) |
New install FreeBSD system, New intall go with ports /usr/ports/lang/go. Go env: GOARCH="amd64" GOBIN="/usr/local/go/bin" GOCHAR="6" GOEXE="" GOHOSTARCH="amd64" GOHOSTOS="freebsd" GOOS="freebsd" GOPATH="/opt/workspace/gopkg" GORACE="" GOROOT="/usr/local/go" GOTOOLDIR="/usr/local/go/pkg/tool/freebsd_amd64" TERM="dumb" CC="cc" GOGCCFLAGS="-g -O2 -fPIC -m64 -pthread" CXX="g++" CGO_ENABLED="1" |
Ports go 1.2 source: SHA256 (go1.2.src.tar.gz) = 9ab83fb8eafe39f4204ef0f8e84e5ff7e8f1d533ddb05f51e6dc81503e8c0ae4 SIZE (go1.2.src.tar.gz) = 9519109 Download url: http://go.googlecode.com/files/go1.2.src.tar.gz That sure,not found $0x80 in sys_freebsd_amd64.s: grep -R -i 0x80 go/src/pkg/runtime/*|grep freebsd go/src/pkg/runtime/sys_freebsd_386.s: INT $0x80 go/src/pkg/runtime/sys_freebsd_386.s: INT $0x80 go/src/pkg/runtime/sys_freebsd_386.s: INT $0x80 go/src/pkg/runtime/sys_freebsd_386.s: INT $0x80 go/src/pkg/runtime/sys_freebsd_386.s: INT $0x80 go/src/pkg/runtime/sys_freebsd_386.s: INT $0x80 go/src/pkg/runtime/sys_freebsd_386.s: INT $0x80 go/src/pkg/runtime/sys_freebsd_386.s: INT $0x80 go/src/pkg/runtime/sys_freebsd_386.s: INT $0x80 go/src/pkg/runtime/sys_freebsd_386.s: INT $0x80 go/src/pkg/runtime/sys_freebsd_386.s: INT $0x80 go/src/pkg/runtime/sys_freebsd_386.s: INT $0x80 go/src/pkg/runtime/sys_freebsd_386.s: INT $0x80 go/src/pkg/runtime/sys_freebsd_386.s: INT $0x80 go/src/pkg/runtime/sys_freebsd_386.s: INT $0x80 go/src/pkg/runtime/sys_freebsd_386.s: INT $0x80 go/src/pkg/runtime/sys_freebsd_386.s: INT $0x80 go/src/pkg/runtime/sys_freebsd_386.s: INT $0x80 go/src/pkg/runtime/sys_freebsd_386.s: INT $0x80 go/src/pkg/runtime/sys_freebsd_386.s: INT $0x80 go/src/pkg/runtime/sys_freebsd_386.s: INT $0x80 go/src/pkg/runtime/sys_freebsd_386.s: 1-byte: 0x80=present, 0x60=dpl<<5, 0x1F=type go/src/pkg/runtime/sys_freebsd_386.s: 1-byte: 0x80=limit is *4k, 0x40=32-bit operand size, go/src/pkg/runtime/sys_freebsd_386.s: INT $0x80 go/src/pkg/runtime/sys_freebsd_386.s: INT $0x80 go/src/pkg/runtime/sys_freebsd_386.s: INT $0x80 go/src/pkg/runtime/sys_freebsd_386.s: INT $0x80 go/src/pkg/runtime/zstring_freebsd_amd64.c:Runeself = 0x80 , |
@jsing I cannot reproduce this on the freebsd machine I have here deadwood(~/src) % uname -a FreeBSD deadwood.local 9.1-RELEASE FreeBSD 9.1-RELEASE #0 r243825: Tue Dec 4 09:23:10 UTC 2012 root@farrell.cse.buffalo.edu:/usr/obj/usr/src/sys/GENERIC amd64 deadwood(~/src) % go version go version go1.2 freebsd/amd64 deadwood(~/src) % which go /usr/local/go/bin/go # from go1.2.freebsd-amd64.tar.gz a simple hello word program (and cmd/go itself) works as expected and produces a working binary that uses SYSCALL. |
Ugh. This is caused by revision 94272206b0cb, which added the following line to sys_freebsd_amd64.s: #define SYSCALL MOVQ R10, CX; INT $0x80 This was done as a workaround for issue #6372, however the "fix" effectively switches FreeBSD to i386 style system calls and requires FreeBSD amd64 kernels to be compiled with COMPAT_FREEBSD32 option kernel. |
According to http://www.freebsd.org/cgi/query-pr.cgi?pr=182161 this was fixed on 6 Oct last year. For tip at least we should update the FreeBSD builders and revert the fix. I think for 1.2.x we need to tell people to ensure COMPAT_FREEBSD32 is enabled. |
That FreeBSD issue is not fixed in 9.2, only in 9-STABLE. http://svnweb.freebsd.org/base/release/9.2.0/sys/amd64/amd64/vm_machdep.c?revision=255898&view=markup It does seem to be fixed in 10.0. |
Yes, 10.0 fixed. http://svnweb.freebsd.org/base/release/10.0.0/sys/amd64/amd64/vm_machdep.c?view=markup But,"bus error" without COMPAT_FREEBSD32. |
Issue #7025 has been merged into this issue. |
To summarize the problem: FreeBSD amd64 kernels always support SYSCALL for invoking system calls; they support INT $0x80 only when COMPAT_FREEBSD32 is enabled. But SYSCALL is buggy (issue #6372) except on very new FreeBSDs. So on those older FreeBSDs we have a choice between "use INT $0x80", which crashes reliably when COMPAT_FREEBSD32 is missing, or "use SYSCALL", which crashes randomly on all systems except very new kernels. Today we choose the former. That seems like the right choice to me. This doesn't seem to have been a particularly big problem for Go 1.2, so I think we can leave things alone for Go 1.3. Let's document that due to a FreeBSD kernel bug, freebsd/amd64 systems require kernels built with COMPAT_FREEBSD32 (since Go 1.2). Once the widely used released FreeBSD kernels all have the SYSCALL bug fix, we can go back to SYSCALL. But not for Go 1.3. Labels changed: added documentation. |
CL https://golang.org/cl/88070045 mentions this issue. |
This issue was updated by revision 59f6c81. LGTM=bradfitz R=golang-codereviews, bradfitz CC=golang-codereviews https://golang.org/cl/88070045 |
Fixed (documented) by https://code.google.com/p/go/source/detail?r=9e0c5daed8e4 Moved the larger long-term issue into issue #7813 (using SYSCALL instead of INT $0x80) Status changed to Fixed. |
This issue was closed.
Sign up for free
to subscribe to this conversation on GitHub.
Already have an account?
Sign in.
by im16hot:
The text was updated successfully, but these errors were encountered: