mirror of
https://github.com/ziglang/zig.git
synced 2025-12-06 14:23:09 +00:00
std: fix os.linux.x86.syscall6
It was possible for `arg6` to be passed as an operand relative to esp. In that case, the `push` at the top clobbered esp and hence made the reference to arg6 invalid. This was manifesting in this branch as broken stack traces on x86-linux due to an `mmap2` syscall accidentally passing the page offset as non-zero! This commit fixes a bug introduced in cb0e6d8aa.
This commit is contained in:
parent
9901b9389e
commit
a12ce28224
@ -80,28 +80,32 @@ pub fn syscall6(
|
||||
arg5: usize,
|
||||
arg6: usize,
|
||||
) usize {
|
||||
// arg5/arg6 are passed via memory as we're out of registers if ebp is used as frame pointer, or
|
||||
// if we're compiling with PIC. We push arg5/arg6 on the stack before changing ebp/esp as the
|
||||
// compiler may reference arg5/arg6 as an offset relative to ebp/esp.
|
||||
// arg6 can't be passed to asm in a register because ebp might be reserved as the frame pointer
|
||||
// and there are no more GPRs available; so we'll need a memory operand for it. Adding that
|
||||
// memory operand means that on PIC we might need a reference to the GOT, which in turn needs
|
||||
// *its* own GPR, so we need to pass another arg in memory too! This is surprisingly hard to get
|
||||
// right, because we can't touch esp or ebp until we're done with the memory input (as that
|
||||
// input could be relative to esp or ebp).
|
||||
const args56: [2]usize = .{ arg5, arg6 };
|
||||
return asm volatile (
|
||||
\\ push %[arg5]
|
||||
\\ push %[arg6]
|
||||
\\ push %%edi
|
||||
\\ push %[args56]
|
||||
\\ push %%ebp
|
||||
\\ mov 12(%%esp), %%edi
|
||||
\\ mov 8(%%esp), %%ebp
|
||||
\\ mov 4(%%esp), %%ebp
|
||||
\\ mov %%edi, 4(%%esp)
|
||||
\\ // The saved %edi and %ebp are on the stack, and %ebp points to `args56`.
|
||||
\\ // Prepare the last two args, syscall, then pop the saved %ebp and %edi.
|
||||
\\ mov (%%ebp), %%edi
|
||||
\\ mov 4(%%ebp), %%ebp
|
||||
\\ int $0x80
|
||||
\\ pop %%ebp
|
||||
\\ pop %%edi
|
||||
\\ add $8, %%esp
|
||||
: [ret] "={eax}" (-> usize),
|
||||
: [number] "{eax}" (@intFromEnum(number)),
|
||||
[arg1] "{ebx}" (arg1),
|
||||
[arg2] "{ecx}" (arg2),
|
||||
[arg3] "{edx}" (arg3),
|
||||
[arg4] "{esi}" (arg4),
|
||||
[arg5] "rm" (arg5),
|
||||
[arg6] "rm" (arg6),
|
||||
[args56] "rm" (&args56),
|
||||
: .{ .memory = true });
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user