On Sat, Feb 27, 2021 at 5:12 PM 'Axel Wagner' via golang-nuts <golang-nuts@googlegroups.com> wrote: > > On Sat, Feb 27, 2021 at 11:19 PM Reto <reto@labrat.space> wrote: >> >> Now, as far as I can tell this forces non stdlib packages to adhere to >> exactly that. >> As far as I can tell x/sys is just a common namespace for the go authors, but >> as far as the compiler itself is concerned, that's a normal module not the >> stdlib. >> >> >> Or is this a wrong assumption? > > > I think you are correct in that the compiler does not give `x/sys` special > treatment. > > However, `x/sys` is still somewhat special, in that, as its maintained by the > Go team, they can make sure that `x/sys` stays up to date with regards to > implementation details. That is, the documentation of the `unsafe` rules is > more strict than it needs to be currently, to reserve the right to change the > implementation in the future. And `x/sys` can use a more lenient > interpretation, because if that implementation changes, it will be changed in > lockstep. > > Furthermore, I'm not sure that the compiler gives `syscall` special treatment > either. At least a cursory grep through `cmd/compile` for "syscall" seems to > give few hits. The most relevant seems > https://github.com/golang/go/blob/release-branch.go1.16/src/cmd/compile/internal/gc/esc.go#L386 > which notably isn't restricted to `syscall` - it applies to any function, > AIUI. This could basically mean that while the rule *states* "passing to > syscall.Syscall", it actually exempts any call, because the special casing > has not been done yet. But a future version *might*, so the rule still is > more specific.
Although rule 4 in the documentation of the unsafe package mentions syscall.Syscall, the implementation isn't restricted to the syscall package. It applies to any function that is written in assembly: that is, a function that is declared in Go without a body. We should perhaps tweak the docs to make that the rule. Or, we could observe that golang.org/x/sys.Syscall actually just forwards to syscall.Syscall, so they are in effect the same function. >> Reason I ask is because the code in x/sys clearly violates that rule. >> >> in unix/ioctl.go there's >> >> ``` >> // IoctlSetPointerInt performs an ioctl operation which sets an >> // integer value on fd, using the specified request number. The ioctl >> // argument is called with a pointer to the integer value, rather than >> // passing the integer value directly. >> func IoctlSetPointerInt(fd int, req uint, value int) error { >> v := int32(value) >> return ioctl(fd, req, uintptr(unsafe.Pointer(&v))) >> } >> ``` >> >> and the declaration of ioctl in zsyskall_linux.go: >> >> ``` >> func ioctl(fd int, req uint, arg uintptr) (err error) { >> _, _, e1 := Syscall(SYS_IOCTL, uintptr(fd), uintptr(req), >> uintptr(arg)) >> if e1 != 0 { >> err = errnoErr(e1) >> } >> return >> } >> ``` Now that you point this out, I'm actually not sure that this is OK. I don't know what keeps v pinned during this call. >> Now, for starters ioctl includes a pointless conversion of a uintptr to a >> uintptr, >> for the arg parameter can anyone tell me why? The functions in z*.go in x/sys are generated (by mksyscall.go). It's easier to always write a conversion to uintptr then to try to decide whether it is required or not. >> Second (and this is my actual question), isn't that in violation of the >> unsafe >> constraints cited above? >> >> IoctlSetPointerInt clearly converts a unsafe.Pointer to a uintptr and >> *doesn't* >> directly call syscall.Syscall. >> >> Why is this valid? I'm not sure it is. Ian -- You received this message because you are subscribed to the Google Groups "golang-nuts" group. To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/golang-nuts/CAOyqgcVZS%2BB4gqnjJzbhTrLvesAZ-vHipUXn2T5-9u79jBgXCw%40mail.gmail.com.