Skip to content

Misaligned memory access causing segfault with f128 on i386 #10856

@jean-dao

Description

@jean-dao

Zig Version

0.10.0-dev.657+f5471299d

Steps to Reproduce

foo.zig:

pub fn main() void {
    var buf: f128 = 0;
    var foo: f64 = @floatCast(f64, buf + 0);
    _ = foo;
}

Run zig run foo.zig -target i386-linux-none -mcpu pentium4 (will segfault).

Expected Behavior

No segfault.

Actual Behavior

Running zig run foo.zig -target i386-linux-none -mcpu pentium4 will segfault:

Segmentation fault at address 0x0
???:?:?: 0x42d426 in ??? (???)
foo.zig:3:40: 0x4258c3 in main (foo)
    var foo: f64 = @floatCast(f64, buf + 0);
                                       ^
/home/jean/src/zig/stage1/lib/zig/std/start.zig:551:22: 0x4203ea in std.start.callMain (foo)
            root.main();
                     ^
/home/jean/src/zig/stage1/lib/zig/std/start.zig:495:12: 0x405412 in std.start.callMainWithArgs (foo)
    return @call(.{ .modifier = .always_inline }, callMain, .{});
           ^
/home/jean/src/zig/stage1/lib/zig/std/start.zig:409:17: 0x404682 in std.start.posixCallMainAndExit (foo)
    std.os.exit(@call(.{ .modifier = .always_inline }, callMainWithArgs, .{ argc, argv, envp }));
                ^
/home/jean/src/zig/stage1/lib/zig/std/start.zig:322:5: 0x40452d in std.start._start (foo)
    @call(.{ .modifier = .never_inline }, posixCallMainAndExit, .{});
    ^
Aborted (core dumped)

Running the program from gdb, I get more info:

Program received signal SIGSEGV, Segmentation fault.
0x0042d426 in __addtf3 ()
(ins)(gdb) disas
Dump of assembler code for function __addtf3:
   0x0042d3f0 <+0>:     push   %ebp
   0x0042d3f1 <+1>:     mov    %esp,%ebp
   0x0042d3f3 <+3>:     push   %esi
   0x0042d3f4 <+4>:     sub    $0x14,%esp
   0x0042d3f7 <+7>:     mov    0x8(%ebp),%esi
   0x0042d3fa <+10>:    mov    0xc(%ebp),%edx
   0x0042d3fd <+13>:    sub    $0x4,%esp
   0x0042d400 <+16>:    lea    -0x18(%ebp),%ecx
   0x0042d403 <+19>:    push   0x28(%ebp)
   0x0042d406 <+22>:    push   0x24(%ebp)
   0x0042d409 <+25>:    push   0x20(%ebp)
   0x0042d40c <+28>:    push   0x1c(%ebp)
   0x0042d40f <+31>:    push   0x18(%ebp)
   0x0042d412 <+34>:    push   0x14(%ebp)
   0x0042d415 <+37>:    push   0x10(%ebp)
   0x0042d418 <+40>:    call   0x42d440 <compiler_rt.addXf3.addXf3.48>
   0x0042d41d <+45>:    add    $0x20,%esp
   0x0042d420 <+48>:    movaps -0x18(%ebp),%xmm0
   0x0042d424 <+52>:    mov    %esi,%eax
=> 0x0042d426 <+54>:    movaps %xmm0,(%esi)
   0x0042d429 <+57>:    add    $0x14,%esp
   0x0042d42c <+60>:    pop    %esi
   0x0042d42d <+61>:    pop    %ebp
   0x0042d42e <+62>:    ret    $0x4
End of assembler dump.
(ins)(gdb) i r esi
esi            0xffffd338          -11464

From my findings, movaps works only with align(16) addresses, which is not the case here. adding an align(16) to the foo variable in the example fixes the issue.

Metadata

Metadata

Assignees

No one assigned

    Labels

    arch-x8632-bit x86bugObserved behavior contradicts documented or intended behavior

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions