Unaligned Pointer Access on ARM and SPARC in C
In the C programming language, writing to a pointer that is not
properly aligned to the data type's natural boundary invokes undefined
behavior and can trigger fatal hardware exceptions on strict-alignment
architectures like SPARC and ARM. This article explains the mechanics of
memory alignment, how CPU memory interfaces enforce these constraints at
the hardware level, why unaligned stores generate CPU faults (such as
Alignment Fault Data Aborts or unaligned access traps), and how the
operating system translates these hardware events into signals like
SIGBUS.
What Is Memory Alignment in C?
Every basic data type in C requires a natural alignment boundary corresponding to its size. For example:
- A 16-bit integer (
short, 2 bytes) must reside at an address divisible by 2 (the least significant bit of the address must be0). - A 32-bit integer (
intoruint32_t, 4 bytes) must reside at an address divisible by 4 (the last two bits must be00). - A 64-bit integer or double (
uint64_tordouble, 8 bytes) must reside at an address divisible by 8 (the last three bits must be000).
When code forces an unaligned pointer using pointer casting, it violates C's alignment guarantees:
char buffer[8];
int *unaligned_ptr = (int *)&buffer[1]; // Misaligned address (offset by 1)
*unaligned_ptr = 42; // Triggers undefined behaviorThe CPU Memory Bus and Word Boundaries
CPUs do not access system memory in single-byte increments. Instead, memory controllers and internal data buses fetch and store data in chunks of 32, 64, or 128 bits.
When a processor executes a 32-bit store instruction, the hardware expects the target address to align precisely with the physical lanes of the memory bus. If an address is 4-byte aligned, the 32 bits fit neatly into a single memory controller slot or L1 cache word. If an address is misaligned (e.g., starting at an odd address), the 32-bit write would cross physical word or cache-line boundaries, requiring the memory controller to perform two separate bus cycles, read-modify-write operations, and byte-lane routing.
How Hardware Exceptions Are Triggered
Architectures such as SPARC and certain configurations of ARM do not perform automatic multi-cycle stitching for arbitrary unaligned loads and stores. Instead, they check the alignment in hardware during instruction execution.
1. SPARC Architecture
SPARC was designed around strict RISC principles where simplicity and
predictable cycle counts are paramount. When an instruction like
ST (Store Word) or STD (Store Doubleword)
executes:
- The Address Generation Unit (AGU) computes the effective address.
- The CPU evaluates the lowest bits of the effective address directly.
- If a 32-bit store operation sees that the lowest two bits are not
00, the instruction execution halts immediately. - The CPU raises a
mem_address_not_alignedhardware trap (typically trap type0x34).
2. ARM Architecture
ARM architectures handle alignment based on the architecture version and system configuration:
- Older cores (ARMv5 and earlier) generally cannot handle unaligned
accesses natively. A 32-bit store (
STR) to an unaligned address often resulted in data corruption or an immediate alignment fault. - On modern ARM cores (ARMv6, ARMv7, and ARMv8 AArch32/AArch64),
hardware support for unaligned access exists, but strict alignment
enforcement can be toggled via the System Control Register
(
SCTLR). When the alignment check bit (Abit) is set to1, any unaligned access immediately causes a Data Abort exception. - Even with unaligned access enabled, certain instructions (such as
load/store multiples like
LDM/STM, atomic instructions likeLDREX/STREX, and certain NEON SIMD operations) strictly require natural alignment. Attempting an unaligned store using these instructions causes the CPU core to generate an Alignment Fault Data Abort.
From Hardware Exception to Process Termination
Once the CPU detects the alignment violation, the execution shifts from user space to kernel space:
- Hardware Trap Vector: The processor halts the offending instruction before committing the write to cache or memory. It sets exception syndrome registers with the faulting address and jumps to the exception vector table in kernel memory.
- Kernel Handler: The operating system's kernel exception handler identifies the trap as an unaligned access violation.
- Signal Generation: In POSIX-compliant environments
like Linux or Solaris running on SPARC/ARM, the kernel creates a
SIGBUS(Bus Error) signal, setting the signal's subcode toBUS_ADRALN(Invalid address alignment). - Process Termination: Unless the application has
established a custom signal handler for
SIGBUS, the operating system terminates the process and generates a core dump.