-
Notifications
You must be signed in to change notification settings - Fork 17.8k
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: use libsystem_kernel.dylib or libSystem.dylib for syscalls on macOS #17490
Comments
I agree that we have to do this. I'm not sure who is actually going to do it, though. |
Note that the trouble with #16570 comes from fetching the current time, and that is something that is so performance critical that we might want to continue to use our own implementation even if we use libSystem for other syscall. |
We got into a discussion about how to do this over on #17200. I believe this can be done without forcing external linking. But I also don't know who is going to do it, my plate is full for the foreseeable future. |
Agree we should do this at some point. It's not terribly high priority though. |
This is about using the system calls. We already link against libSystem.dylib when cgo is in use. |
Hi, I made a CL for x86. https://go-review.googlesource.com/c/50290/ |
CL https://golang.org/cl/50290 mentions this issue. |
Change https://golang.org/cl/54871 mentions this issue: |
Currently, we have a workaround for solaris that enforce aboslute addressing for external symbols. However, We don't want to use the workaround for darwin. This CL also refactors code a little bit, because the original function name is not appropriate now. Updates #17490 Change-Id: Id21f9cdf33dca6a40647226be49010c2c324ee24 Reviewed-on: https://go-review.googlesource.com/54871 Reviewed-by: Ian Lance Taylor <iant@golang.org> Run-TryBot: Ian Lance Taylor <iant@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org>
Despite the release-blocker label I don't see this happening for Go 1.10. Moving to Go 1.11. If we really want to do this we need to make sure work starts at the beginning of the cycle. |
Nick Kledzik suggested in e-mail:
|
Update golang/go#17490 Change-Id: I29feed5ddea976b39bd4c43bd1ff5942f47df083 Reviewed-on: https://go-review.googlesource.com/c/154661 Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Update golang/go#17490 Change-Id: I55ea10ce2eb5fb1c0518a57900e78e5f0a29b893 Reviewed-on: https://go-review.googlesource.com/c/154662 Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Update golang/go#17490 Change-Id: Iaec54b8ffda1a24d4c8b5671185d570fb8683155 Reviewed-on: https://go-review.googlesource.com/c/154663 Reviewed-by: Ian Lance Taylor <iant@golang.org>
Change https://golang.org/cl/155737 mentions this issue: |
Change https://golang.org/cl/156346 mentions this issue: |
Missed this one. Update golang/go#17490. Change-Id: I5ab2197f9981b712b37d3060f72209bebcadf291 Reviewed-on: https://go-review.googlesource.com/c/156346 Run-TryBot: Keith Randall <khr@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Ian Lance Taylor <iant@golang.org>
Change https://golang.org/cl/156365 mentions this issue: |
upstream git hash: 1775db3 Update #17490 Change-Id: I95e3c57137756c5c7a9b7334075caef66f205231 Reviewed-on: https://go-review.googlesource.com/c/156365 Run-TryBot: Keith Randall <khr@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Ian Lance Taylor <iant@golang.org>
Go 1.12 switched to using libSystem.dylib for system calls, because Apple recommends against doing direct system calls that Go 1.11 and earlier did. For more information, see: golang/go#17490 https://developer.apple.com/library/archive/qa/qa1118/_index.html While the old syscall package was relatively easy to support in TinyGo (just implement syscall.Syscall*), this got a whole lot harder with Go 1.12 as all syscalls now go through CGo magic to call the underlying libSystem functions. Therefore, this commit overrides the stdlib syscall package with a custom package that performs calls with libc (libSystem). This may be useful not just for darwin but for other platforms as well that do not place the stable ABI at the syscall boundary like Linux but at the libc boundary. Only a very minimal part of the syscall package has been implemented, to get the tests to pass. More calls can easily be added in the future.
Go 1.12 switched to using libSystem.dylib for system calls, because Apple recommends against doing direct system calls that Go 1.11 and earlier did. For more information, see: golang/go#17490 https://developer.apple.com/library/archive/qa/qa1118/_index.html While the old syscall package was relatively easy to support in TinyGo (just implement syscall.Syscall*), this got a whole lot harder with Go 1.12 as all syscalls now go through CGo magic to call the underlying libSystem functions. Therefore, this commit overrides the stdlib syscall package with a custom package that performs calls with libc (libSystem). This may be useful not just for darwin but for other platforms as well that do not place the stable ABI at the syscall boundary like Linux but at the libc boundary. Only a very minimal part of the syscall package has been implemented, to get the tests to pass. More calls can easily be added in the future.
Go 1.12 switched to using libSystem.dylib for system calls, because Apple recommends against doing direct system calls that Go 1.11 and earlier did. For more information, see: golang/go#17490 https://developer.apple.com/library/archive/qa/qa1118/_index.html While the old syscall package was relatively easy to support in TinyGo (just implement syscall.Syscall*), this got a whole lot harder with Go 1.12 as all syscalls now go through CGo magic to call the underlying libSystem functions. Therefore, this commit overrides the stdlib syscall package with a custom package that performs calls with libc (libSystem). This may be useful not just for darwin but for other platforms as well that do not place the stable ABI at the syscall boundary like Linux but at the libc boundary. Only a very minimal part of the syscall package has been implemented, to get the tests to pass. More calls can easily be added in the future.
Go 1.12 switched to using libSystem.dylib for system calls, because Apple recommends against doing direct system calls that Go 1.11 and earlier did. For more information, see: golang/go#17490 https://developer.apple.com/library/archive/qa/qa1118/_index.html While the old syscall package was relatively easy to support in TinyGo (just implement syscall.Syscall*), this got a whole lot harder with Go 1.12 as all syscalls now go through CGo magic to call the underlying libSystem functions. Therefore, this commit overrides the stdlib syscall package with a custom package that performs calls with libc (libSystem). This may be useful not just for darwin but for other platforms as well that do not place the stable ABI at the syscall boundary like Linux but at the libc boundary. Only a very minimal part of the syscall package has been implemented, to get the tests to pass. More calls can easily be added in the future.
Change https://golang.org/cl/197938 mentions this issue: |
While understanding why syscall.Read is 2x slower on darwin/amd64, I found out that, contrary to popular belief, the slowdown is not due to the migration to use libSystem.dylib instead of direct SYSCALLs, i.e., CL 141639 (and #17490), but due to a subtle change introduced in CL 141639. Previously, syscall.Read used syscall.Syscall(SYS_READ), whose preamble called runtime.entersyscall, but after CL 141639, syscall.Read changes to call runtime.syscall_syscall instead, which in turn calls runtime.entersyscallblock instead of runtime.entersyscall. And the entire 2x slow down can be attributed to this change. I think this is unnecessary as even though syscalls like Read might block, it does not always block, so there is no need to handoff P proactively for each Read. Additionally, we have been fine with not handing off P for each Read prior to Go 1.12, so we probably don't need to change it. This changes restores the pre-Go 1.12 behavior, where syscall preamble uses runtime.entersyscall, and we rely on sysmon to take P back from g blocked in syscalls. Change-Id: If76e97b5a7040cf1c10380a567c4f5baec3121ba Reviewed-on: https://go-review.googlesource.com/c/go/+/197938 Run-TryBot: Minux Ma <minux@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Keith Randall <khr@golang.org> Reviewed-by: Ian Lance Taylor <iant@golang.org>
Change https://golang.org/cl/200103 mentions this issue: |
…ssion While understanding why syscall.Read is 2x slower on darwin/amd64, I found out that, contrary to popular belief, the slowdown is not due to the migration to use libSystem.dylib instead of direct SYSCALLs, i.e., CL 141639 (and #17490), but due to a subtle change introduced in CL 141639. Previously, syscall.Read used syscall.Syscall(SYS_READ), whose preamble called runtime.entersyscall, but after CL 141639, syscall.Read changes to call runtime.syscall_syscall instead, which in turn calls runtime.entersyscallblock instead of runtime.entersyscall. And the entire 2x slow down can be attributed to this change. I think this is unnecessary as even though syscalls like Read might block, it does not always block, so there is no need to handoff P proactively for each Read. Additionally, we have been fine with not handing off P for each Read prior to Go 1.12, so we probably don't need to change it. This changes restores the pre-Go 1.12 behavior, where syscall preamble uses runtime.entersyscall, and we rely on sysmon to take P back from g blocked in syscalls. Updates #34712 Change-Id: If76e97b5a7040cf1c10380a567c4f5baec3121ba Reviewed-on: https://go-review.googlesource.com/c/go/+/197938 Run-TryBot: Minux Ma <minux@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Keith Randall <khr@golang.org> Reviewed-by: Ian Lance Taylor <iant@golang.org> (cherry picked from commit c1635ad) Reviewed-on: https://go-review.googlesource.com/c/go/+/200103 Run-TryBot: Alexander Rakoczy <alex@golang.org> Reviewed-by: Cherry Zhang <cherryyz@google.com>
Change https://golang.org/cl/227037 mentions this issue: |
+----------------------------------------------------------------------+ | Hello, if you are reading this and run macOS, please test this code: | | | | $ GO111MODULE=on go get golang.org/dl/gotip@latest | | $ gotip download | | $ GODEBUG=x509roots=1 gotip test crypto/x509 -v -run TestSystemRoots | +----------------------------------------------------------------------+ We currently have two code paths to extract system roots on macOS: one uses cgo to invoke a maze of Security.framework APIs; the other is a horrible fallback that runs "/usr/bin/security verify-cert" on every root that has custom policies to check if it's trusted for SSL. The fallback is not only terrifying because it shells out to a binary, but also because it lets in certificates that are not trusted roots but are signed by trusted roots, and because it applies some filters (EKUs and expiration) only to roots with custom policies, as the others are not passed to verify-cert. The other code path, of course, requires cgo, so can't be used when cross-compiling and involves a large ball of C. It's all a mess, and it broke oh-so-many times (#14514, #16532, #19436, #20990, #21416, #24437, #24652, #25649, #26073, #27958, #28025, #28092, #29497, #30471, #30672, #30763, #30889, #32891, #38215, #38365, ...). Since macOS does not have a stable syscall ABI, we already dynamically link and invoke libSystem.dylib regardless of cgo availability (#17490). How that works is that functions in package syscall (like syscall.Open) take the address of assembly trampolines (like libc_open_trampoline) that jump to symbols imported with cgo_import_dynamic (like libc_open), and pass them along with arguments to syscall.syscall (which is implemented as runtime.syscall_syscall). syscall_syscall informs the scheduler and profiler, and then uses asmcgocall to switch to a system stack and invoke runtime.syscall. The latter is an assembly trampoline that unpacks the Go ABI arguments passed to syscall.syscall, finally calls the remote function, and puts the return value on the Go stack. (This last bit is the part that cgo compiles from a C wrapper.) We can do something similar to link and invoke Security.framework! The one difference is that runtime.syscall and friends check errors based on the errno convention, which Security doesn't follow, so I added runtime.syscallNoErr which just skips interpreting the return value. We only need a variant with six arguments because the calling convention is register-based, and extra arguments simply zero out some registers. That's plumbed through as crypto/x509/internal/macOS.syscall. The rest of that package is a set of wrappers for Security.framework and Core Foundation functions, like syscall is for libSystem. In theory, as long as macOS respects ABI backwards compatibility (a.k.a. as long as binaries built for a previous OS version keep running) this should be stable, as the final result is not different from what a C compiler would make. (One exception might be dictionary key strings, which we make our own copy of instead of using the dynamic symbol. If they change the value of those strings things might break. But why would they.) Finally, I rewrote the crypto/x509 cgo logic in Go using those wrappers. It works! I tried to make it match 1:1 the old logic, so that root_darwin_amd64.go can be reviewed by comparing it to root_cgo_darwin_amd64.go. The only difference is that we do proper error handling now, and assume that if there is no error the return values are there, while before we'd just check for nil pointers and move on. I kept the cgo logic to help with review and testing, but we should delete it once we are confident the new code works. The nocgo logic is gone and we shall never speak of it again. Fixes #32604 Fixes #19561 Fixes #38365 Awakens Cthulhu Change-Id: Id850962bad667f71e3af594bdfebbbb1edfbcbb4 Reviewed-on: https://go-review.googlesource.com/c/go/+/227037 Reviewed-by: Katie Hockman <katie@golang.org>
As I understand it, Go currently has its own syscall wrappers for Darwin. This is explicitly against what Apple recommends, precisely because they're not willing to commit to a particular syscall ABI. This leads to issues like #16570, and although we've been lucky in that things have generally been backward-compatible so far, there's no guarantee that it'll continue to happen. It doesn't seem inconceivable to me that we'd at some point end up having to specify "build for macOS 10.13+" vs. "build for 10.12 and below", for example.
Linking against libsystem_kernel.dylib (or the broader libSystem.dylib) would put Go back in line with Apple's recommendations for the platform, and the library is guaranteed to exist on all macOS boxes.
Apologies if this has been suggested before and people have already gone over good reasons not to do it, but I'm currently struggling to figure out what appears to be another Sierra incompatibility related to #16570 above (still haven't figured it out enough to post a reproducible bug) and am wishing we didn't have to deal with these issues.
The text was updated successfully, but these errors were encountered: