mirror of https://github.com/golang/go.git
runtime: add padding to Linux kernel structures
Go exchanges siginfo and sigevent structures with the kernel. They contain unions, but Go's use is limited to the first few fields. Pad out the rest so the size Go sees is the same as what the Linux kernel sees. This is a follow-up to CL 342052 which added the sigevent struct without padding, and to CL 353136 which added the padding but with an assertion that confused several type-checkers. It updates the siginfo struct as well so there are no bad examples in the defs_linux_*.go files. Reviewed-on: https://go-review.googlesource.com/c/go/+/353136 Change-Id: I9610632ff0ec43eba91f560536f5441fa907b36f Reviewed-on: https://go-review.googlesource.com/c/go/+/360094 Run-TryBot: Ian Lance Taylor <iant@golang.org> Reviewed-by: Ian Lance Taylor <iant@golang.org> Reviewed-by: Michael Pratt <mpratt@google.com>
This commit is contained in:
parent
6f327f7b88
commit
a97c527ac4
|
|
@ -3,6 +3,8 @@
|
|||
|
||||
package runtime
|
||||
|
||||
import "unsafe"
|
||||
|
||||
const (
|
||||
_EINTR = 0x4
|
||||
_EAGAIN = 0xb
|
||||
|
|
@ -166,7 +168,7 @@ type sigactiont struct {
|
|||
sa_mask uint64
|
||||
}
|
||||
|
||||
type siginfo struct {
|
||||
type siginfoFields struct {
|
||||
si_signo int32
|
||||
si_errno int32
|
||||
si_code int32
|
||||
|
|
@ -174,6 +176,13 @@ type siginfo struct {
|
|||
si_addr uint32
|
||||
}
|
||||
|
||||
type siginfo struct {
|
||||
siginfoFields
|
||||
|
||||
// Pad struct to the max size in the kernel.
|
||||
_ [_si_max_size - unsafe.Sizeof(siginfoFields{})]byte
|
||||
}
|
||||
|
||||
type stackt struct {
|
||||
ss_sp *byte
|
||||
ss_flags int32
|
||||
|
|
@ -229,7 +238,7 @@ type itimerval struct {
|
|||
it_value timeval
|
||||
}
|
||||
|
||||
type sigevent struct {
|
||||
type sigeventFields struct {
|
||||
value uintptr
|
||||
signo int32
|
||||
notify int32
|
||||
|
|
@ -237,6 +246,13 @@ type sigevent struct {
|
|||
sigev_notify_thread_id int32
|
||||
}
|
||||
|
||||
type sigevent struct {
|
||||
sigeventFields
|
||||
|
||||
// Pad struct to the max size in the kernel.
|
||||
_ [_sigev_max_size - unsafe.Sizeof(sigeventFields{})]byte
|
||||
}
|
||||
|
||||
type epollevent struct {
|
||||
events uint32
|
||||
data [8]byte // to match amd64
|
||||
|
|
|
|||
|
|
@ -3,6 +3,8 @@
|
|||
|
||||
package runtime
|
||||
|
||||
import "unsafe"
|
||||
|
||||
const (
|
||||
_EINTR = 0x4
|
||||
_EAGAIN = 0xb
|
||||
|
|
@ -128,7 +130,7 @@ type sigactiont struct {
|
|||
sa_mask uint64
|
||||
}
|
||||
|
||||
type siginfo struct {
|
||||
type siginfoFields struct {
|
||||
si_signo int32
|
||||
si_errno int32
|
||||
si_code int32
|
||||
|
|
@ -136,6 +138,13 @@ type siginfo struct {
|
|||
si_addr uint64
|
||||
}
|
||||
|
||||
type siginfo struct {
|
||||
siginfoFields
|
||||
|
||||
// Pad struct to the max size in the kernel.
|
||||
_ [_si_max_size - unsafe.Sizeof(siginfoFields{})]byte
|
||||
}
|
||||
|
||||
type itimerspec struct {
|
||||
it_interval timespec
|
||||
it_value timespec
|
||||
|
|
@ -146,7 +155,7 @@ type itimerval struct {
|
|||
it_value timeval
|
||||
}
|
||||
|
||||
type sigevent struct {
|
||||
type sigeventFields struct {
|
||||
value uintptr
|
||||
signo int32
|
||||
notify int32
|
||||
|
|
@ -154,6 +163,13 @@ type sigevent struct {
|
|||
sigev_notify_thread_id int32
|
||||
}
|
||||
|
||||
type sigevent struct {
|
||||
sigeventFields
|
||||
|
||||
// Pad struct to the max size in the kernel.
|
||||
_ [_sigev_max_size - unsafe.Sizeof(sigeventFields{})]byte
|
||||
}
|
||||
|
||||
type epollevent struct {
|
||||
events uint32
|
||||
data [8]byte // unaligned uintptr
|
||||
|
|
|
|||
|
|
@ -4,6 +4,8 @@
|
|||
|
||||
package runtime
|
||||
|
||||
import "unsafe"
|
||||
|
||||
// Constants
|
||||
const (
|
||||
_EINTR = 0x4
|
||||
|
|
@ -169,7 +171,7 @@ type itimerval struct {
|
|||
it_value timeval
|
||||
}
|
||||
|
||||
type sigevent struct {
|
||||
type sigeventFields struct {
|
||||
value uintptr
|
||||
signo int32
|
||||
notify int32
|
||||
|
|
@ -177,7 +179,14 @@ type sigevent struct {
|
|||
sigev_notify_thread_id int32
|
||||
}
|
||||
|
||||
type siginfo struct {
|
||||
type sigevent struct {
|
||||
sigeventFields
|
||||
|
||||
// Pad struct to the max size in the kernel.
|
||||
_ [_sigev_max_size - unsafe.Sizeof(sigeventFields{})]byte
|
||||
}
|
||||
|
||||
type siginfoFields struct {
|
||||
si_signo int32
|
||||
si_errno int32
|
||||
si_code int32
|
||||
|
|
@ -185,6 +194,13 @@ type siginfo struct {
|
|||
si_addr uint32
|
||||
}
|
||||
|
||||
type siginfo struct {
|
||||
siginfoFields
|
||||
|
||||
// Pad struct to the max size in the kernel.
|
||||
_ [_si_max_size - unsafe.Sizeof(siginfoFields{})]byte
|
||||
}
|
||||
|
||||
type sigactiont struct {
|
||||
sa_handler uintptr
|
||||
sa_flags uint32
|
||||
|
|
|
|||
|
|
@ -3,6 +3,8 @@
|
|||
|
||||
package runtime
|
||||
|
||||
import "unsafe"
|
||||
|
||||
const (
|
||||
_EINTR = 0x4
|
||||
_EAGAIN = 0xb
|
||||
|
|
@ -128,7 +130,7 @@ type sigactiont struct {
|
|||
sa_mask uint64
|
||||
}
|
||||
|
||||
type siginfo struct {
|
||||
type siginfoFields struct {
|
||||
si_signo int32
|
||||
si_errno int32
|
||||
si_code int32
|
||||
|
|
@ -136,6 +138,13 @@ type siginfo struct {
|
|||
si_addr uint64
|
||||
}
|
||||
|
||||
type siginfo struct {
|
||||
siginfoFields
|
||||
|
||||
// Pad struct to the max size in the kernel.
|
||||
_ [_si_max_size - unsafe.Sizeof(siginfoFields{})]byte
|
||||
}
|
||||
|
||||
type itimerspec struct {
|
||||
it_interval timespec
|
||||
it_value timespec
|
||||
|
|
@ -146,7 +155,7 @@ type itimerval struct {
|
|||
it_value timeval
|
||||
}
|
||||
|
||||
type sigevent struct {
|
||||
type sigeventFields struct {
|
||||
value uintptr
|
||||
signo int32
|
||||
notify int32
|
||||
|
|
@ -154,6 +163,13 @@ type sigevent struct {
|
|||
sigev_notify_thread_id int32
|
||||
}
|
||||
|
||||
type sigevent struct {
|
||||
sigeventFields
|
||||
|
||||
// Pad struct to the max size in the kernel.
|
||||
_ [_sigev_max_size - unsafe.Sizeof(sigeventFields{})]byte
|
||||
}
|
||||
|
||||
type epollevent struct {
|
||||
events uint32
|
||||
_pad uint32
|
||||
|
|
|
|||
|
|
@ -6,6 +6,8 @@
|
|||
|
||||
package runtime
|
||||
|
||||
import "unsafe"
|
||||
|
||||
const (
|
||||
_EINTR = 0x4
|
||||
_EAGAIN = 0xb
|
||||
|
|
@ -134,7 +136,7 @@ type sigactiont struct {
|
|||
sa_restorer uintptr
|
||||
}
|
||||
|
||||
type siginfo struct {
|
||||
type siginfoFields struct {
|
||||
si_signo int32
|
||||
si_code int32
|
||||
si_errno int32
|
||||
|
|
@ -143,6 +145,13 @@ type siginfo struct {
|
|||
si_addr uint64
|
||||
}
|
||||
|
||||
type siginfo struct {
|
||||
siginfoFields
|
||||
|
||||
// Pad struct to the max size in the kernel.
|
||||
_ [_si_max_size - unsafe.Sizeof(siginfoFields{})]byte
|
||||
}
|
||||
|
||||
type itimerspec struct {
|
||||
it_interval timespec
|
||||
it_value timespec
|
||||
|
|
@ -153,7 +162,7 @@ type itimerval struct {
|
|||
it_value timeval
|
||||
}
|
||||
|
||||
type sigevent struct {
|
||||
type sigeventFields struct {
|
||||
value uintptr
|
||||
signo int32
|
||||
notify int32
|
||||
|
|
@ -161,6 +170,13 @@ type sigevent struct {
|
|||
sigev_notify_thread_id int32
|
||||
}
|
||||
|
||||
type sigevent struct {
|
||||
sigeventFields
|
||||
|
||||
// Pad struct to the max size in the kernel.
|
||||
_ [_sigev_max_size - unsafe.Sizeof(sigeventFields{})]byte
|
||||
}
|
||||
|
||||
type epollevent struct {
|
||||
events uint32
|
||||
pad_cgo_0 [4]byte
|
||||
|
|
|
|||
|
|
@ -6,6 +6,8 @@
|
|||
|
||||
package runtime
|
||||
|
||||
import "unsafe"
|
||||
|
||||
const (
|
||||
_EINTR = 0x4
|
||||
_EAGAIN = 0xb
|
||||
|
|
@ -129,7 +131,7 @@ type sigactiont struct {
|
|||
sa_restorer uintptr
|
||||
}
|
||||
|
||||
type siginfo struct {
|
||||
type siginfoFields struct {
|
||||
si_signo int32
|
||||
si_code int32
|
||||
si_errno int32
|
||||
|
|
@ -137,6 +139,13 @@ type siginfo struct {
|
|||
si_addr uint32
|
||||
}
|
||||
|
||||
type siginfo struct {
|
||||
siginfoFields
|
||||
|
||||
// Pad struct to the max size in the kernel.
|
||||
_ [_si_max_size - unsafe.Sizeof(siginfoFields{})]byte
|
||||
}
|
||||
|
||||
type itimerspec struct {
|
||||
it_interval timespec
|
||||
it_value timespec
|
||||
|
|
@ -147,7 +156,7 @@ type itimerval struct {
|
|||
it_value timeval
|
||||
}
|
||||
|
||||
type sigevent struct {
|
||||
type sigeventFields struct {
|
||||
value uintptr
|
||||
signo int32
|
||||
notify int32
|
||||
|
|
@ -155,6 +164,13 @@ type sigevent struct {
|
|||
sigev_notify_thread_id int32
|
||||
}
|
||||
|
||||
type sigevent struct {
|
||||
sigeventFields
|
||||
|
||||
// Pad struct to the max size in the kernel.
|
||||
_ [_sigev_max_size - unsafe.Sizeof(sigeventFields{})]byte
|
||||
}
|
||||
|
||||
type epollevent struct {
|
||||
events uint32
|
||||
pad_cgo_0 [4]byte
|
||||
|
|
|
|||
|
|
@ -3,6 +3,8 @@
|
|||
|
||||
package runtime
|
||||
|
||||
import "unsafe"
|
||||
|
||||
const (
|
||||
_EINTR = 0x4
|
||||
_EAGAIN = 0xb
|
||||
|
|
@ -129,7 +131,7 @@ type sigactiont struct {
|
|||
sa_mask uint64
|
||||
}
|
||||
|
||||
type siginfo struct {
|
||||
type siginfoFields struct {
|
||||
si_signo int32
|
||||
si_errno int32
|
||||
si_code int32
|
||||
|
|
@ -137,6 +139,13 @@ type siginfo struct {
|
|||
si_addr uint64
|
||||
}
|
||||
|
||||
type siginfo struct {
|
||||
siginfoFields
|
||||
|
||||
// Pad struct to the max size in the kernel.
|
||||
_ [_si_max_size - unsafe.Sizeof(siginfoFields{})]byte
|
||||
}
|
||||
|
||||
type itimerspec struct {
|
||||
it_interval timespec
|
||||
it_value timespec
|
||||
|
|
@ -147,7 +156,7 @@ type itimerval struct {
|
|||
it_value timeval
|
||||
}
|
||||
|
||||
type sigevent struct {
|
||||
type sigeventFields struct {
|
||||
value uintptr
|
||||
signo int32
|
||||
notify int32
|
||||
|
|
@ -155,6 +164,13 @@ type sigevent struct {
|
|||
sigev_notify_thread_id int32
|
||||
}
|
||||
|
||||
type sigevent struct {
|
||||
sigeventFields
|
||||
|
||||
// Pad struct to the max size in the kernel.
|
||||
_ [_sigev_max_size - unsafe.Sizeof(sigeventFields{})]byte
|
||||
}
|
||||
|
||||
type epollevent struct {
|
||||
events uint32
|
||||
pad_cgo_0 [4]byte
|
||||
|
|
|
|||
|
|
@ -3,6 +3,8 @@
|
|||
|
||||
package runtime
|
||||
|
||||
import "unsafe"
|
||||
|
||||
const (
|
||||
_EINTR = 0x4
|
||||
_EAGAIN = 0xb
|
||||
|
|
@ -129,7 +131,7 @@ type sigactiont struct {
|
|||
sa_mask uint64
|
||||
}
|
||||
|
||||
type siginfo struct {
|
||||
type siginfoFields struct {
|
||||
si_signo int32
|
||||
si_errno int32
|
||||
si_code int32
|
||||
|
|
@ -137,6 +139,13 @@ type siginfo struct {
|
|||
si_addr uint64
|
||||
}
|
||||
|
||||
type siginfo struct {
|
||||
siginfoFields
|
||||
|
||||
// Pad struct to the max size in the kernel.
|
||||
_ [_si_max_size - unsafe.Sizeof(siginfoFields{})]byte
|
||||
}
|
||||
|
||||
type itimerspec struct {
|
||||
it_interval timespec
|
||||
it_value timespec
|
||||
|
|
@ -147,7 +156,7 @@ type itimerval struct {
|
|||
it_value timeval
|
||||
}
|
||||
|
||||
type sigevent struct {
|
||||
type sigeventFields struct {
|
||||
value uintptr
|
||||
signo int32
|
||||
notify int32
|
||||
|
|
@ -155,6 +164,13 @@ type sigevent struct {
|
|||
sigev_notify_thread_id int32
|
||||
}
|
||||
|
||||
type sigevent struct {
|
||||
sigeventFields
|
||||
|
||||
// Pad struct to the max size in the kernel.
|
||||
_ [_sigev_max_size - unsafe.Sizeof(sigeventFields{})]byte
|
||||
}
|
||||
|
||||
type epollevent struct {
|
||||
events uint32
|
||||
pad_cgo_0 [4]byte
|
||||
|
|
|
|||
|
|
@ -4,6 +4,8 @@
|
|||
|
||||
package runtime
|
||||
|
||||
import "unsafe"
|
||||
|
||||
const (
|
||||
_EINTR = 0x4
|
||||
_EAGAIN = 0xb
|
||||
|
|
@ -126,7 +128,7 @@ type sigactiont struct {
|
|||
sa_mask uint64
|
||||
}
|
||||
|
||||
type siginfo struct {
|
||||
type siginfoFields struct {
|
||||
si_signo int32
|
||||
si_errno int32
|
||||
si_code int32
|
||||
|
|
@ -134,6 +136,13 @@ type siginfo struct {
|
|||
si_addr uint64
|
||||
}
|
||||
|
||||
type siginfo struct {
|
||||
siginfoFields
|
||||
|
||||
// Pad struct to the max size in the kernel.
|
||||
_ [_si_max_size - unsafe.Sizeof(siginfoFields{})]byte
|
||||
}
|
||||
|
||||
type itimerspec struct {
|
||||
it_interval timespec
|
||||
it_value timespec
|
||||
|
|
@ -144,7 +153,7 @@ type itimerval struct {
|
|||
it_value timeval
|
||||
}
|
||||
|
||||
type sigevent struct {
|
||||
type sigeventFields struct {
|
||||
value uintptr
|
||||
signo int32
|
||||
notify int32
|
||||
|
|
@ -152,6 +161,13 @@ type sigevent struct {
|
|||
sigev_notify_thread_id int32
|
||||
}
|
||||
|
||||
type sigevent struct {
|
||||
sigeventFields
|
||||
|
||||
// Pad struct to the max size in the kernel.
|
||||
_ [_sigev_max_size - unsafe.Sizeof(sigeventFields{})]byte
|
||||
}
|
||||
|
||||
type epollevent struct {
|
||||
events uint32
|
||||
pad_cgo_0 [4]byte
|
||||
|
|
|
|||
|
|
@ -4,6 +4,8 @@
|
|||
|
||||
package runtime
|
||||
|
||||
import "unsafe"
|
||||
|
||||
const (
|
||||
_EINTR = 0x4
|
||||
_EAGAIN = 0xb
|
||||
|
|
@ -125,7 +127,7 @@ type sigactiont struct {
|
|||
sa_mask uint64
|
||||
}
|
||||
|
||||
type siginfo struct {
|
||||
type siginfoFields struct {
|
||||
si_signo int32
|
||||
si_errno int32
|
||||
si_code int32
|
||||
|
|
@ -133,6 +135,13 @@ type siginfo struct {
|
|||
si_addr uint64
|
||||
}
|
||||
|
||||
type siginfo struct {
|
||||
siginfoFields
|
||||
|
||||
// Pad struct to the max size in the kernel.
|
||||
_ [_si_max_size - unsafe.Sizeof(siginfoFields{})]byte
|
||||
}
|
||||
|
||||
type itimerspec struct {
|
||||
it_interval timespec
|
||||
it_value timespec
|
||||
|
|
@ -143,7 +152,7 @@ type itimerval struct {
|
|||
it_value timeval
|
||||
}
|
||||
|
||||
type sigevent struct {
|
||||
type sigeventFields struct {
|
||||
value uintptr
|
||||
signo int32
|
||||
notify int32
|
||||
|
|
@ -151,6 +160,13 @@ type sigevent struct {
|
|||
sigev_notify_thread_id int32
|
||||
}
|
||||
|
||||
type sigevent struct {
|
||||
sigeventFields
|
||||
|
||||
// Pad struct to the max size in the kernel.
|
||||
_ [_sigev_max_size - unsafe.Sizeof(sigeventFields{})]byte
|
||||
}
|
||||
|
||||
type epollevent struct {
|
||||
events uint32
|
||||
pad_cgo_0 [4]byte
|
||||
|
|
|
|||
|
|
@ -8,11 +8,16 @@ package runtime
|
|||
|
||||
import "unsafe"
|
||||
|
||||
const SiginfoMaxSize = _si_max_size
|
||||
const SigeventMaxSize = _sigev_max_size
|
||||
|
||||
var NewOSProc0 = newosproc0
|
||||
var Mincore = mincore
|
||||
var Add = add
|
||||
|
||||
type EpollEvent epollevent
|
||||
type Siginfo siginfo
|
||||
type Sigevent sigevent
|
||||
|
||||
func Epollctl(epfd, op, fd int32, ev unsafe.Pointer) int32 {
|
||||
return epollctl(epfd, op, fd, (*epollevent)(ev))
|
||||
|
|
|
|||
|
|
@ -440,6 +440,11 @@ func pipe() (r, w int32, errno int32)
|
|||
func pipe2(flags int32) (r, w int32, errno int32)
|
||||
func setNonblock(fd int32)
|
||||
|
||||
const (
|
||||
_si_max_size = 128
|
||||
_sigev_max_size = 64
|
||||
)
|
||||
|
||||
//go:nosplit
|
||||
//go:nowritebarrierrec
|
||||
func setsig(i uint32, fn uintptr) {
|
||||
|
|
@ -636,12 +641,11 @@ func setThreadCPUProfiler(hz int32) {
|
|||
spec.it_interval.setNsec(1e9 / int64(hz))
|
||||
|
||||
var timerid int32
|
||||
sevp := &sigevent{
|
||||
notify: _SIGEV_THREAD_ID,
|
||||
signo: _SIGPROF,
|
||||
sigev_notify_thread_id: int32(mp.procid),
|
||||
}
|
||||
ret := timer_create(_CLOCK_THREAD_CPUTIME_ID, sevp, &timerid)
|
||||
var sevp sigevent
|
||||
sevp.notify = _SIGEV_THREAD_ID
|
||||
sevp.signo = _SIGPROF
|
||||
sevp.sigev_notify_thread_id = int32(mp.procid)
|
||||
ret := timer_create(_CLOCK_THREAD_CPUTIME_ID, &sevp, &timerid)
|
||||
if ret != 0 {
|
||||
// If we cannot create a timer for this M, leave profileTimerValid false
|
||||
// to fall back to the process-wide setitimer profiler.
|
||||
|
|
|
|||
|
|
@ -61,3 +61,14 @@ func TestEpollctlErrorSign(t *testing.T) {
|
|||
t.Errorf("epollctl = %v, want %v", v, -EBADF)
|
||||
}
|
||||
}
|
||||
|
||||
func TestKernelStructSize(t *testing.T) {
|
||||
// Check that the Go definitions of structures exchanged with the kernel are
|
||||
// the same size as what the kernel defines.
|
||||
if have, want := unsafe.Sizeof(Siginfo{}), uintptr(SiginfoMaxSize); have != want {
|
||||
t.Errorf("Go's siginfo struct is %d bytes long; kernel expects %d", have, want)
|
||||
}
|
||||
if have, want := unsafe.Sizeof(Sigevent{}), uintptr(SigeventMaxSize); have != want {
|
||||
t.Errorf("Go's sigevent struct is %d bytes long; kernel expects %d", have, want)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue