Summary
On PowerPC 32-bit (Linux), ALL aggregates are passed indirectly via pointer, regardless of size. The SVR4 ABI requires small structs (8 bytes or less) to be passed by value in GPRs, coerced to integer types.
Location
compiler/rustc_target/src/callconv/powerpc.rs, line 28
Bug
if arg.layout.pass_indirectly_in_non_rustic_abis(cx) || arg.layout.is_aggregate() {
arg.make_indirect();
}
ALL aggregates hit arg.make_indirect(). But the PowerPC 32-bit SVR4 ABI passes small structs by value:
- Structs <= 4 bytes: coerced to i32, passed in a single GPR
- Structs <= 8 bytes: coerced to i64, passed in a GPR pair
Clang's PPC32_SVR4_ABIInfo::classifyArgumentType implements this coercion.
Impact
When Rust's extern "C" fn(x: SmallStruct) calls a C function, Rust passes a pointer in r3 but C expects the struct value in r3(:r4). The callee reads the pointer as the struct value, causing data corruption.
PowerPC 32-bit Linux is a tier 3 target with limited FFI usage, but this is a genuine ABI violation.
Fix
For structs <= 8 bytes on PowerPC 32-bit SVR4 targets, coerce to integer register type instead of making indirect.
Spec
PowerPC SVR4 ABI Supplement, Chapter 3 -- "Structures and unions that fit in 1 or 2 general purpose registers are passed by value."
Summary
On PowerPC 32-bit (Linux), ALL aggregates are passed indirectly via pointer, regardless of size. The SVR4 ABI requires small structs (8 bytes or less) to be passed by value in GPRs, coerced to integer types.
Location
compiler/rustc_target/src/callconv/powerpc.rs, line 28Bug
ALL aggregates hit
arg.make_indirect(). But the PowerPC 32-bit SVR4 ABI passes small structs by value:Clang's
PPC32_SVR4_ABIInfo::classifyArgumentTypeimplements this coercion.Impact
When Rust's
extern "C" fn(x: SmallStruct)calls a C function, Rust passes a pointer in r3 but C expects the struct value in r3(:r4). The callee reads the pointer as the struct value, causing data corruption.PowerPC 32-bit Linux is a tier 3 target with limited FFI usage, but this is a genuine ABI violation.
Fix
For structs <= 8 bytes on PowerPC 32-bit SVR4 targets, coerce to integer register type instead of making indirect.
Spec
PowerPC SVR4 ABI Supplement, Chapter 3 -- "Structures and unions that fit in 1 or 2 general purpose registers are passed by value."