manually align int64 to 8bytes for syscall

114 views
Skip to first unread message

Jorropo

unread,
Mar 4, 2026, 4:49:31 AM (8 days ago) Mar 4
to golang-dev
How should this C code be translated to Go inside the runtime package ?

struct timespec {
    int64_t tv_sec;
    int32_t tv_nsec;
};

struct itimerspec {
    struct timespec it_interval;
    struct timespec it_value;
};

My first guess is:
type timespec struct{
  tv_sec int64
  tv_nsec int32
}

type itimerspec struct {
  it_interval timespec
  it_value timespec
}

However this is wrong in 2 ways due to int64_t being 8bytes aligned on mips O32 ABI and armv7 ABI.
1. theses structs can be stack allocated to a 4 bytes align giving a coin-flip on whether or not it is 8bytes aligned. (only causes problems if the kernel doesn't want to copy the 64bits value if it's unaligned)
2. the layout of itimerspec is wrong, since Go will think timespec is 12bytes wide, when it is 16bytes wide padding taken into account.

For point 2 you can manually add _ int32 in itimerspec.
I don't know how to fix point 1 without manually adding something like:
type timespec struct{
  _ align8
  tv_sec int64
  tv_nsec int32
}

or:
type timespec struct{
  tv_sec int64_aligned8
  tv_nsec int32
}

to the compiler.

Russ Cox

unread,
Mar 4, 2026, 8:37:39 AM (7 days ago) Mar 4
to Jorropo, golang-dev
On 32-bit systems, we should 64-bit-align every stack value that contains an int64, uint64, float64, or complex128.
We don't do that yet only because no one has done the work to make sure that every stack frame is itself 64-bit aligned.
(If the frames aren't aligned then 64-bit alignment within the frame is meaningless.)

This was go.dev/issue/599 and was folded into go.dev/issue/36606, but I think the latter may have lost the nuance about needing to align stack frames.

Best,
Russ




Jorropo

unread,
Mar 4, 2026, 9:17:13 AM (7 days ago) Mar 4
to Russ Cox, golang-dev
When one thing in the frame request an align bigger than ABI promised stack pointer align (for example using 32 bytes registers with AVX*)
C compilers reserve align-1 of throw away stack space then uses an AND to align the stack pointer to the requested align.

I wonder what would break if we did that.

*AVX has a different instruction for unaligned loads, but on certain architectures they take a couple more cycles and or generate multiple load uops.

Alessandro Arzilli

unread,
Mar 4, 2026, 9:39:29 AM (7 days ago) Mar 4
to Jorropo, golang-dev, Russ Cox
On Wed, 04 Mar 2026 15:16:41 +0100, Jorropo <jorro...@gmail.com> wrote:
> When one thing in the frame request an align bigger than ABI promised stack
> pointer align (for example using 32 bytes registers with AVX*)
> C compilers reserve align-1 of throw away stack space then uses an AND to
> align the stack pointer to the requested align.
>
> I wonder what would break if we did that.

The PCSP tables and therefore the GC?

Jorropo

unread,
Mar 4, 2026, 9:46:03 AM (7 days ago) Mar 4
to Alessandro Arzilli, golang-dev, Russ Cox
What if we set RBP to the aligned SP ?

If the table references are RBP+off would be fine.
If the table references are SP-off should be fine. 

Jorropo

unread,
Mar 4, 2026, 9:49:21 AM (7 days ago) Mar 4
to Alessandro Arzilli, golang-dev, Russ Cox
No would be a bit more complex. But it sounds fixable.

Russ Cox

unread,
Mar 4, 2026, 11:46:55 AM (7 days ago) Mar 4
to Jorropo, Alessandro Arzilli, golang-dev
We shouldn't do anything special in certain functions based on what's in the frame.
We should instead just make sure to align the top-of-stack properly,
set frame sizes to preserve that alignment (on 386, that means 4 mod 8,
since the CALL instruction will add another 4), 
and then make sure all the stack switch routines also align things properly.
It's entirely doable; no one has taken the time.

Best,
Russ


Reply all
Reply to author
Forward
0 new messages