Skip to content

.comm alignment operand is emitted as Mach-O log2 on every target, but ELF reads it as bytes #674

Description

@nahime0

Summary

The .comm directive's third operand is emitted as a hardcoded 3 for every target, but
that operand means different things on Mach-O and ELF:

  • Mach-O (as/clang): alignment as a power of two3 means 8-byte alignment.
  • ELF (GNU as): alignment in bytes3 means 3-byte alignment, which is not a
    power of two at all.

Where

src/codegen_support/data_section.rs:165:

for (label, size) in &self.comm_entries {
    out.push_str(&format!(".comm {}, {}, 3\n", label, size));
}

emit() takes no target parameter, so there is no way for the value to follow the object
format. Every common symbol in the program goes through this one site — the static-local
slots, the define() seen-flags, IR globals, the function-variant active symbols, the
concat scratch, and the stack-limit slot.

Why it surfaced

Adding _stack_limit as a common symbol for the stack-exhaustion guard made this reachable
on Linux images that had not previously been exercised with a fresh .comm symbol.

Expected

Emit the alignment the way the target's assembler reads it: the log2 exponent for Mach-O,
the byte count for ELF. Both should express the same intended 8-byte alignment.

Note

This is an assembler-syntax portability bug, not a codegen logic bug — the sizes and labels
are correct. It is worth an audit of the other directives emitted from the same section for
the same class of Mach-O/ELF operand divergence.

Metadata

Metadata

Assignees

No one assigned

    Labels

    area:codegenTouches target-aware assembly or backend lowering.area:platformTouches targets, object formats, linking, or platform support.type:fixCorrects broken or incompatible behavior.

    Type

    No type

    Projects

    Status
    Done

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions