Skip to content

Unaligned memory access instructions are generated on thumbv7em-none-eabi target #137663

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
maximilian-maisel-bl opened this issue Feb 26, 2025 · 2 comments
Labels
C-bug Category: This is a bug. O-Arm Target: 32-bit Arm processors (armv6, armv7, thumb...), including 64-bit Arm in AArch32 state T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@maximilian-maisel-bl
Copy link

In some cases, unaligned memory access instructions are generated for the thumbv7em-none-eabi
embedded target. This crashes the program with a hard-fault error interrupt on thumbv7em MCU
variants like the XMC4800 that do not support unaligned memory access. Whether an thumbv7em MCU
supports unaligned memory access is indicated by by the UNALIGN_TRP bit in the CCR register,
see ARMv7 ARM.

This issue can be worked around by setting the rustflag target-feature=+strict-align though .cargo/config.tomlbut at the same time, this causes the following warning:

warning: unknown and unstable feature specified for `-Ctarget-feature`: `strict-align`
  |
  = note: it is still passed through to the codegen backend, but use of this feature might be
    unsound and the behavior of this feature can change in the future
  = help: consider filing a feature request

The following code snippet can trigger this issue in the derived Default implementation:

#[derive(Default)]
pub struct Config {
    pub sys_divider: u8,
    pub cpu_divider: bool,
    pub ccu_divider: bool,
    pub pb_divider: bool,
    pub ndiv: u8,
    pub pdiv: u8,
    pub kdiv: u8,
}

fn init_clock() {
    // Calling default on Config causes a hard-fault.
    let config = Config::default();
    core::hint::black_box(&config);
}

From this code, the following invalid unaligned store-word instruction is generated:

str.w   r0, [sp, #3] // The stack pointer `sp` is aligned correctly

The full minimal example together with the generated assembly code can be found at:
https://github.com/maximilian-maisel-bl/rust-thumbv7em-align-bug

A possible fix could be setting the strict align flag in the thumbv7em-none-eabi target spec file
similar to the changes made by #58060 for aarch64-unknown-none.

This bug might be related to #82945

Used rust version: rustc 1.87.0-nightly (617aad8c2 2025-02-24)

@maximilian-maisel-bl maximilian-maisel-bl added the C-bug Category: This is a bug. label Feb 26, 2025
@rustbot rustbot added the needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. label Feb 26, 2025
@maximilian-maisel-bl
Copy link
Author

Another workaround for this issue is to clear the UNALIGN_TRP bit in the CCR, e.g. through this code:

#[pre_init]                                                                                             
unsafe fn clear_unalign_trp() {                                                                           
    *(0xE000ED14 as *mut u32) = 0x200;                                                                    
}

This post in the Infineon forum indicates that this could be some kind of silicon issue.

However, doing this is not necessary when using gcc to program this MCU in C.

@jieyouxu jieyouxu added O-Arm Target: 32-bit Arm processors (armv6, armv7, thumb...), including 64-bit Arm in AArch32 state T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. and removed needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. labels Feb 26, 2025
@cosmikwolf
Copy link

For certain chips, including STM32H7A3, and certain memories, including DTCM the UNALIGNED bit is set in the UFSR even without the UNALIGN_TRP bit set in the SCB CCR when unaligned access occurs, which is what led me to this issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C-bug Category: This is a bug. O-Arm Target: 32-bit Arm processors (armv6, armv7, thumb...), including 64-bit Arm in AArch32 state T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

No branches or pull requests

4 participants