4

I'm using GCC compiler for Microblaze processor. Recently I have encountered a problem with variable alignment. I've noticed that sometimes the compiler allocates static variable to an unaligned address (the address is not divisible by 4), so if I send a pointer of the unaligned variable to any function I can get an unaligned access hardware exception.

I have two questions regarding that subject:

  • How can I make sure all my static variables are aligned? is there a flag that forces that? Currently I'm using the variable attribute:

    __attribute__((aligned(4)))
    

    But this is very uncomfortable, because I need to define it for every static variable I have, which does not make sense.

  • Is there a way to make sure my functions local variables (which are allocated in the stack) will be aligned? I mean is there a way to make sure my stack head is aligned, every function uses an aligned portion of the stack and any variable that is allocated in the stack is aligned.

Thanks.

Jabberwocky
  • 48,281
  • 17
  • 65
  • 115
Moshon
  • 71
  • 5
  • 2
    This sounds like a compiler bug. The compiler should take care of the alignement depending on the target architecture. – Jabberwocky Nov 29 '16 at 09:35
  • 1
    Note: Don't use compiler extensions where a standard alternative exists. Use the `_Alignas` specifier (resp. `stdalign.h` names). You can check the alignment your compiler should expect with `_Alignof`. I'd test the issue very thoroughly this before filing a bug report. – too honest for this site Nov 29 '16 at 09:58
  • I have tested the alignment. for types of size 1 the alignment is 1, so It could be possible to get unaligned variables. But my question is if there is a flag that makes the default alignment at least 4, or something of that nature. – Moshon Nov 29 '16 at 12:44
  • What flags are you passing to gcc? – Tim Nov 29 '16 at 21:45

1 Answers1

1

AFAIK there is no way to tell GCC that you want to enforce a certain alignment for the entire compilation unit. That is there is no compiler flag that goes something like "alignment_unit 4".

I'm no expert on the topic (and especially not on the Microblaze soft-core) but I did a little experimentation with GCC targeting the Intel x64 CPU of my PC and with IAR C targeting an ARM Cortex-M4 microcontroller.

SETUP 1 : global(file-level) variables

static uint64_t a = 0;
static uint8_t b = 0;
static uint16_t c = 0;
static uint16_t d = 0;
static uint8_t e = 0;

int main()
{   
    printf("&a = %u\n", &a);
    printf("&b = %u\n", &b);
    printf("&c = %u\n", &c);
    printf("&d = %u\n", &d);
    printf("&e = %u\n", &e);

    return 0;
}

SETUP 2 : local(function-level) variables

void some_func()
{    
    uint64_t a = 0;
    uint8_t b = 0;
    uint16_t c = 0;
    uint16_t d = 0;
    uint8_t e = 0;

    printf("&a = %u\n", &a);
    printf("&b = %u\n", &b);
    printf("&c = %u\n", &c);
    printf("&d = %u\n", &d);
    printf("&e = %u\n", &e);
}

int main()
{   
    some_func();    
    return 0;
}

I turned of all optimizations.

Neither setup resulted in 4 byte (or 8 byte for the PC) aligned variable addresses. That was the case for both compiler/platform combinations.

The only possible solution I can think of (as inelegant as it may be) is to create a header for custom types and put the following typedefs in there:

typedef __attribute__((aligned(4))) uint64_t ui64_aligned;
typedef __attribute__((aligned(4))) uint32_t ui32_aligned;
typedef __attribute__((aligned(4))) uint16_t ui16_aligned;
typedef __attribute__((aligned(4))) uint8_t ui8_aligned;

Then just use the "aligned types" whenever you need them. This way you'll have both "custom-aligned" and "auto-aligned" types and you won't compromise code readability either (too much..).

I know it's not exactly the solution you were looking for but this at least works (as far as my testing goes).