Unaligned access exception

Asked by jdobry on 2018-01-26

Hello,

we have "packet" structs in array. This mean, that pointer to individual struct is unaligned. Cortex-A and Cortex-R support unaligned access (if SCTLR.A is 0)
Problem is that compiler make optimizations. One optimization is read/write two following 32bit values by instruction LDRD/STRD instruction.
But it is problem, Cortex-A/R did support unaligned access for LDR/STR but not for LDRD/STRD. In another word ARMv7 implementation support unaligned data accesses only by some load and store instructions. This mean that we need disable this optimization selectively for this usage only, or tell compiler: "this pointer is unaligned" But how?

See to ARM document ARM DDI 0406C.b ID072512 Chapter A3.2.1 Unaligned data access Table A3-1 Alignment requirements of load/store instructions

Question information

Language:
English Edit question
Status:
Solved
For:
GNU Arm Embedded Toolchain Edit question
Assignee:
No assignee Edit question
Solved by:
jdobry
Solved:
2018-02-01
Last query:
2018-02-01
Last reply:
jdobry (jdobry) said : #2

No, it looks similar, but isn't same.
Cortex-A/R can access to unaligned pointer. Problem is difference between LDR/STR and LDRD/STRD instructions.
First (LDR/STR) work without problem. Second (LDRD/STRD) used by optimalizator can't access unaligned memory.

jdobry (jdobry) said : #3

OK it isn't same issue, but solution is same. We are miss to use __attribute((__packed__)) somewhere in complex code.

Lets have this sample of C code
    typedef struct unaligned_struct {
      int a;
      int b;
    } __attribute((__packed__)) unaligned_struct_t;

    int unalignedTest (unaligned_struct_t *x)
    {
      return x->a + x->b;
    }

Without __attribute((__packed__)) it produce code like this:
       ldmia r0, {r0, r2}
        add r0, r0, r2
        bx lr

And with __attribute((__packed__)) magic it produce this correct code:
      ldr r2, [r0] @ unaligned
      ldr r0, [r0, #4] @ unaligned
      add r0, r0, r2
     bx lr

This code is aslo correct:
    typedef struct unaligned_struct {
      int a;
      int b;
    } __attribute((__packed__));

    int unalignedTest (struct unaligned_struct *x)
    {
      return x->a + x->b;
    }

Thanks for keeping us updating with the solution to your problem. Much appreciated!