views:

259

answers:

2

I have a function:

void testfunction() {
 static char_t theChar1 = 1;
 static unsigned char smallArray[1];
 static unsigned char largeArray[135];
    ...
}

and a linker file:

  . = ALIGN(4);
  _edata = . ;
  PROVIDE (edata = .);

  .bss (NOLOAD) :
  {
    __bss_start = . ;
    __bss_start__ = . ;
    *(.bss)
    *(.bss.*)
    *(COMMON)
    . = ALIGN(4);
  } > ramEXT

  . = ALIGN(4);
  __bss_end__ = . ;
  PROVIDE (__bss_end = .);

I need static arrays (.bss data) to align on 4 byte boundaries, but it seems arrays refuse to do so. Structures and primitive types align fine (see the fill lines), but the arrays are all over. Here's my map file:

 .data.firstTimeFlag.7295
                0xa000098c        0x4 output/file1.o
 .data.theChar1.5869
                0xa0000990        0x1 output/file2.o
 *fill*         0xa0000991        0x3 00
 .data.debounce
                0xa0000994      0x270 output/file3.o

...

 .bss.initialized.5826
                0xa000812c        0x1 output/file2.o
 *fill*         0xa000812d        0x3 00
 .bss.allocator.5825
                0xa0008130       0x34 output/file2.o
 .bss.largeArray.5869
                0xa0008164       0x87 output/file2.o
 .bss.smallArray.5868
                0xa00081eb        0x1 output/file2.o
 .bss.initialized.5897
                0xa00081ec        0x1 output/file2.o
 *fill*         0xa00081ed        0x3 00
 .bss.allocator.5896

Anyone know how to align arrays?

+1  A: 

I'm not sure you can do this with a linker script, and I'm puzzled as to your goal; the alignment attribute attached to each assembler declaration presumably meets the ABI and machine requirements. Are you trying to increase cache hit rate? Compensate for non-conforming type punning in the source code?

One thing you can "easily" do is add the gnu alignment extension to the C source.

static unsigned char smallArray[1] __attribute__ ((aligned (4)));

Update: Hmm, a large third-party macro library that generates obviously non-conforming code? (If it was standard-conforming code it would presumably work fine. :-) Ok, this is a frightful kludge, but I can almost guarantee it will "work", FSDO "work", and not require debugging the macro lib...You could post-process the compiler's assembly language output. Local static bss symbols are not layout sensitive and are typically declared in a single .comm or .lcomm directive, for which the last parameter is likely to be the alignment amount.

This parameter is what __attribute__ changes. You could change them all during the build with a script of some kind...

DigitalRoss
It's unfortunately a lot more complicated than I've made the question. I'm using a library that has huge macros which auto-create functions and arrays from one little line of code. The macros break when these large arrays occur (start) in the middle of word boundaries, but work fine when they start on a word boundary. I still don't know what's going on exactly, and I thought this might be a quick fix. It might be the macros themselves, of course, but that's going to require a bit more digging. It's no small wonder why I hate macros.
Jeff Lamb
By the way, I think your solution would work, but I'm trying to find out if it's possible through a linker file. To use your solution would require me to modify an externally supplied library.
Jeff Lamb
Response to the update:I rebuilt the lib with the aligned(4) directive and the code works fine. I think I'm just going to inform the third party that the code they've supplied is broken. We're paying them for using it, so I don't want to debug code more than I have to.
Jeff Lamb
+1  A: 

In systems I've worked on, the linker parameters could be controlled to set the alignment of the start of each section--but not the alignment of individual variables within the section. The alignment of individual variables was determined by the compiler, according to the variable's type.

You may be able to use some sort of compiler pragma, platform-specific of course.

An alternative is to define your array as an array of whatever type you need aligned to, such as uint32_t.

I'm curious to know what you're trying to achieve--it sounds as though you're doing something a little unusual and platform-specific, if you have this alignment requirement. Best to create platform-independent code if at all possible, of course.

Craig McQueen
Honestly it's probably a bug with this nasty library macro I'm using. It works for word aligned arrays, but not otherwise. I'm still working on it.
Jeff Lamb