Skip to content

AAPCS va_arg: on-stack path missing big-endian right-adjustment for sub-slot values #460

@SebTardif

Description

@SebTardif

Bug

In compiler/rustc_codegen_llvm/src/va_arg.rs:256, the AAPCS64 va_arg on-stack path passes ForceRightAdjust::No, skipping the big-endian right-adjustment for values smaller than the 8-byte stack slot.

The register path (lines 238-242) correctly applies this adjustment, and other big-endian targets (PPC64, Sparc64, MIPS) all use ForceRightAdjust::Yes for their on-stack paths.

Per the AAPCS64 spec, when a non-aggregate argument is smaller than its stack slot, on big-endian targets the value is right-adjusted within the 8-byte slot. Clang implements this explicitly in EmitAAPCSVAArg.

Impact

On big-endian AArch64 targets (aarch64_be-unknown-linux-gnu, etc.), va_arg::<i32>() and va_arg::<u32>() read the wrong 4 bytes from an 8-byte stack slot when the argument has spilled past the register save area (more than 8 integer varargs). This is silent data corruption.

Fix

Change ForceRightAdjust::No to ForceRightAdjust::Yes on line 256.

Metadata

Metadata

Assignees

No one assigned

    Labels

    I-wrongWrong result or data corruptionP-mediumMedium impact: affects specific usage patternsbugSomething isn't working

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions