unix: align the getdents buffer getdents64 stores a 64-bit d_ino at the start of every entry, so the entries are aligned only if the buffer is. Go promises no alignment for a []byte, and sparc64 faults on the misaligned store rather than fixing it up, returning EFAULT. Buffers from make are already 8-aligned, so this is a no-op unless the caller passes a sub-slice. Updates golang/go#55000 Change-Id: I3724af7c4ef7debc4bdd9d0b1c3130c312094957 GitHub-Last-Rev: 2d416d91ae1f7ad56c32636521af5b2c61a567b2 GitHub-Pull-Request: golang/sys#291 Reviewed-on: https://go-review.googlesource.com/c/sys/+/822906 LUCI-TryBot-Result: golang-scoped@luci-project-accounts.iam.gserviceaccount.com <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Reviewed-by: Kirill Kolyshkin <kolyshkin@gmail.com> Reviewed-by: Ian Lance Taylor <iant@golang.org> Auto-Submit: Ian Lance Taylor <iant@golang.org> Reviewed-by: Michael Pratt <mpratt@google.com> Reviewed-by: Junyang Shao <shaojunyang@google.com>
diff --git a/unix/syscall_linux.go b/unix/syscall_linux.go index 6926057..8fbfb0d 100644 --- a/unix/syscall_linux.go +++ b/unix/syscall_linux.go
@@ -1991,7 +1991,24 @@ return fsconfig(fd, FSCONFIG_CMD_RECONFIGURE, nil, nil, 0) } -//sys Getdents(fd int, buf []byte) (n int, err error) = SYS_GETDENTS64 +//sys getdents(fd int, buf []byte) (n int, err error) = SYS_GETDENTS64 + +// Getdents reads directory entries from fd into buf. +func Getdents(fd int, buf []byte) (n int, err error) { + // getdents64 stores d_ino with a 64-bit write, which faults on + // strict-alignment targets unless buf is 8-aligned. + if len(buf) > 0 { + if off := int(-uintptr(unsafe.Pointer(&buf[0])) & 7); off > 0 && off < len(buf) { + n, err = getdents(fd, buf[off:]) + if n > 0 { + copy(buf, buf[off:off+n]) + } + return n, err + } + } + return getdents(fd, buf) +} + //sysnb Getpgid(pid int) (pgid int, err error) func Getpgrp() (pid int) {
diff --git a/unix/zsyscall_linux.go b/unix/zsyscall_linux.go index 5788c2a..86d3b56 100644 --- a/unix/zsyscall_linux.go +++ b/unix/zsyscall_linux.go
@@ -943,7 +943,7 @@ // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func Getdents(fd int, buf []byte) (n int, err error) { +func getdents(fd int, buf []byte) (n int, err error) { var _p0 unsafe.Pointer if len(buf) > 0 { _p0 = unsafe.Pointer(&buf[0])