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. It updates the siginfo struct as well so there are no bad
examples in the defs_linux_*.go files.

Change-Id: Id991d4a57826677dd7e6cc30ad113fa3b321cddf
Reviewed-on: https://go-review.googlesource.com/c/go/+/353136
Run-TryBot: Rhys Hiltner <rhys@justin.tv>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Michael Pratt <mpratt@google.com>
Trust: Michael Knyszek <mknyszek@google.com>
This commit is contained in:
Rhys Hiltner 2021-09-29 17:35:27 -07:00 committed by Michael Pratt
parent e8a85e90ac
commit f0db7eae74
11 changed files with 122 additions and 0 deletions

View File

@ -3,6 +3,8 @@
package runtime
import "internal/goarch"
const (
_EINTR = 0x4
_EAGAIN = 0xb
@ -172,6 +174,11 @@ type siginfo struct {
si_code int32
// below here is a union; si_addr is the only field we use
si_addr uint32
// Pad struct to the max size in the kernel. Account for the 3 32-bit
// fields, the alignment to this architecture's pointer size, and the final
// pointer-length field.
_ [_si_max_size - (3*4 + (1-4/goarch.PtrSize)*4 + 1*goarch.PtrSize)]byte
}
type stackt struct {
@ -235,6 +242,10 @@ type sigevent struct {
notify int32
// below here is a union; sigev_notify_thread_id is the only field we use
sigev_notify_thread_id int32
// Pad struct to the max size in the kernel. Account for the pointer-length
// field and the 3 32-bit fields.
_ [_sigev_max_size - (1*goarch.PtrSize + 3*4)]byte
}
type epollevent struct {

View File

@ -3,6 +3,8 @@
package runtime
import "internal/goarch"
const (
_EINTR = 0x4
_EAGAIN = 0xb
@ -134,6 +136,11 @@ type siginfo struct {
si_code int32
// below here is a union; si_addr is the only field we use
si_addr uint64
// Pad struct to the max size in the kernel. Account for the 3 32-bit
// fields, the alignment to this architecture's pointer size, and the final
// pointer-length field.
_ [_si_max_size - (3*4 + (1-4/goarch.PtrSize)*4 + 1*goarch.PtrSize)]byte
}
type itimerspec struct {
@ -152,6 +159,10 @@ type sigevent struct {
notify int32
// below here is a union; sigev_notify_thread_id is the only field we use
sigev_notify_thread_id int32
// Pad struct to the max size in the kernel. Account for the pointer-length
// field and the 3 32-bit fields.
_ [_sigev_max_size - (1*goarch.PtrSize + 3*4)]byte
}
type epollevent struct {

View File

@ -4,6 +4,8 @@
package runtime
import "internal/goarch"
// Constants
const (
_EINTR = 0x4
@ -175,6 +177,10 @@ type sigevent struct {
notify int32
// below here is a union; sigev_notify_thread_id is the only field we use
sigev_notify_thread_id int32
// Pad struct to the max size in the kernel. Account for the pointer-length
// field and the 3 32-bit fields.
_ [_sigev_max_size - (1*goarch.PtrSize + 3*4)]byte
}
type siginfo struct {
@ -183,6 +189,11 @@ type siginfo struct {
si_code int32
// below here is a union; si_addr is the only field we use
si_addr uint32
// Pad struct to the max size in the kernel. Account for the 3 32-bit
// fields, the alignment to this architecture's pointer size, and the final
// pointer-length field.
_ [_si_max_size - (3*4 + (1-4/goarch.PtrSize)*4 + 1*goarch.PtrSize)]byte
}
type sigactiont struct {

View File

@ -3,6 +3,8 @@
package runtime
import "internal/goarch"
const (
_EINTR = 0x4
_EAGAIN = 0xb
@ -134,6 +136,11 @@ type siginfo struct {
si_code int32
// below here is a union; si_addr is the only field we use
si_addr uint64
// Pad struct to the max size in the kernel. Account for the 3 32-bit
// fields, the alignment to this architecture's pointer size, and the final
// pointer-length field.
_ [_si_max_size - (3*4 + (1-4/goarch.PtrSize)*4 + 1*goarch.PtrSize)]byte
}
type itimerspec struct {
@ -152,6 +159,10 @@ type sigevent struct {
notify int32
// below here is a union; sigev_notify_thread_id is the only field we use
sigev_notify_thread_id int32
// Pad struct to the max size in the kernel. Account for the pointer-length
// field and the 3 32-bit fields.
_ [_sigev_max_size - (1*goarch.PtrSize + 3*4)]byte
}
type epollevent struct {

View File

@ -8,6 +8,8 @@
package runtime
import "internal/goarch"
const (
_EINTR = 0x4
_EAGAIN = 0xb
@ -143,6 +145,11 @@ type siginfo struct {
__pad0 [1]int32
// below here is a union; si_addr is the only field we use
si_addr uint64
// Pad struct to the max size in the kernel. Account for the 3 32-bit
// fields, the alignment to this architecture's pointer size, and the final
// pointer-length field.
_ [_si_max_size - (3*4 + (1-4/goarch.PtrSize)*4 + 1*goarch.PtrSize)]byte
}
type itimerspec struct {
@ -161,6 +168,10 @@ type sigevent struct {
notify int32
// below here is a union; sigev_notify_thread_id is the only field we use
sigev_notify_thread_id int32
// Pad struct to the max size in the kernel. Account for the pointer-length
// field and the 3 32-bit fields.
_ [_sigev_max_size - (1*goarch.PtrSize + 3*4)]byte
}
type epollevent struct {

View File

@ -8,6 +8,8 @@
package runtime
import "internal/goarch"
const (
_EINTR = 0x4
_EAGAIN = 0xb
@ -137,6 +139,11 @@ type siginfo struct {
si_errno int32
// below here is a union; si_addr is the only field we use
si_addr uint32
// Pad struct to the max size in the kernel. Account for the 3 32-bit
// fields, the alignment to this architecture's pointer size, and the final
// pointer-length field.
_ [_si_max_size - (3*4 + (1-4/goarch.PtrSize)*4 + 1*goarch.PtrSize)]byte
}
type itimerspec struct {
@ -155,6 +162,10 @@ type sigevent struct {
notify int32
// below here is a union; sigev_notify_thread_id is the only field we use
sigev_notify_thread_id int32
// Pad struct to the max size in the kernel. Account for the pointer-length
// field and the 3 32-bit fields.
_ [_sigev_max_size - (1*goarch.PtrSize + 3*4)]byte
}
type epollevent struct {

View File

@ -3,6 +3,8 @@
package runtime
import "internal/goarch"
const (
_EINTR = 0x4
_EAGAIN = 0xb
@ -135,6 +137,11 @@ type siginfo struct {
si_code int32
// below here is a union; si_addr is the only field we use
si_addr uint64
// Pad struct to the max size in the kernel. Account for the 3 32-bit
// fields, the alignment to this architecture's pointer size, and the final
// pointer-length field.
_ [_si_max_size - (3*4 + (1-4/goarch.PtrSize)*4 + 1*goarch.PtrSize)]byte
}
type itimerspec struct {
@ -153,6 +160,10 @@ type sigevent struct {
notify int32
// below here is a union; sigev_notify_thread_id is the only field we use
sigev_notify_thread_id int32
// Pad struct to the max size in the kernel. Account for the pointer-length
// field and the 3 32-bit fields.
_ [_sigev_max_size - (1*goarch.PtrSize + 3*4)]byte
}
type epollevent struct {

View File

@ -3,6 +3,8 @@
package runtime
import "internal/goarch"
const (
_EINTR = 0x4
_EAGAIN = 0xb
@ -135,6 +137,11 @@ type siginfo struct {
si_code int32
// below here is a union; si_addr is the only field we use
si_addr uint64
// Pad struct to the max size in the kernel. Account for the 3 32-bit
// fields, the alignment to this architecture's pointer size, and the final
// pointer-length field.
_ [_si_max_size - (3*4 + (1-4/goarch.PtrSize)*4 + 1*goarch.PtrSize)]byte
}
type itimerspec struct {
@ -153,6 +160,10 @@ type sigevent struct {
notify int32
// below here is a union; sigev_notify_thread_id is the only field we use
sigev_notify_thread_id int32
// Pad struct to the max size in the kernel. Account for the pointer-length
// field and the 3 32-bit fields.
_ [_sigev_max_size - (1*goarch.PtrSize + 3*4)]byte
}
type epollevent struct {

View File

@ -4,6 +4,8 @@
package runtime
import "internal/goarch"
const (
_EINTR = 0x4
_EAGAIN = 0xb
@ -132,6 +134,11 @@ type siginfo struct {
si_code int32
// below here is a union; si_addr is the only field we use
si_addr uint64
// Pad struct to the max size in the kernel. Account for the 3 32-bit
// fields, the alignment to this architecture's pointer size, and the final
// pointer-length field.
_ [_si_max_size - (3*4 + (1-4/goarch.PtrSize)*4 + 1*goarch.PtrSize)]byte
}
type itimerspec struct {
@ -150,6 +157,10 @@ type sigevent struct {
notify int32
// below here is a union; sigev_notify_thread_id is the only field we use
sigev_notify_thread_id int32
// Pad struct to the max size in the kernel. Account for the pointer-length
// field and the 3 32-bit fields.
_ [_sigev_max_size - (1*goarch.PtrSize + 3*4)]byte
}
type epollevent struct {

View File

@ -4,6 +4,8 @@
package runtime
import "internal/goarch"
const (
_EINTR = 0x4
_EAGAIN = 0xb
@ -131,6 +133,11 @@ type siginfo struct {
si_code int32
// below here is a union; si_addr is the only field we use
si_addr uint64
// Pad struct to the max size in the kernel. Account for the 3 32-bit
// fields, the alignment to this architecture's pointer size, and the final
// pointer-length field.
_ [_si_max_size - (3*4 + (1-4/goarch.PtrSize)*4 + 1*goarch.PtrSize)]byte
}
type itimerspec struct {
@ -149,6 +156,10 @@ type sigevent struct {
notify int32
// below here is a union; sigev_notify_thread_id is the only field we use
sigev_notify_thread_id int32
// Pad struct to the max size in the kernel. Account for the pointer-length
// field and the 3 32-bit fields.
_ [_sigev_max_size - (1*goarch.PtrSize + 3*4)]byte
}
type epollevent struct {

View File

@ -440,6 +440,18 @@ 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
)
// Assert that the Go definitions of structures exchanged with the kernel are
// the same size as what the kernel defines.
var (
_ [_si_max_size]struct{} = [unsafe.Sizeof(siginfo{})]struct{}{}
_ [_sigev_max_size]struct{} = [unsafe.Sizeof(sigevent{})]struct{}{}
)
//go:nosplit
//go:nowritebarrierrec
func setsig(i uint32, fn uintptr) {