Выравнивание статических массивов в разделе .bss файла компоновщика
-
21-09-2019 - |
Вопрос
У меня есть функция:
void testfunction() {
static char_t theChar1 = 1;
static unsigned char smallArray[1];
static unsigned char largeArray[135];
...
}
и файл компоновщика:
. = ALIGN(4);
_edata = . ;
PROVIDE (edata = .);
.bss (NOLOAD) :
{
__bss_start = . ;
__bss_start__ = . ;
*(.bss)
*(.bss.*)
*(COMMON)
. = ALIGN(4);
} > ramEXT
. = ALIGN(4);
__bss_end__ = . ;
PROVIDE (__bss_end = .);
Мне нужны статические массивы (данные .bss) для выравнивания по 4-байтовым границам, но, похоже, массивы отказываются это делать.Структуры и примитивные типы выровнены нормально (см. Линии заливки), но массивы повсюду.Вот мой файл карты:
.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
Кто-нибудь знает, как выровнять массивы?
Решение
Я не уверен, что вы можете сделать это с помощью сценария компоновщика, и я озадачен вашей целью;атрибут выравнивания, прикрепленный к каждому объявлению ассемблера, предположительно, соответствует требованиям ABI и machine.Вы пытаетесь увеличить частоту попадания в кэш?Компенсировать несоответствующий тип каламбуры в исходном коде?
Одна вещь, которую вы можете "легко" сделать, это добавить расширение gnu alignment к исходному коду C.
static unsigned char smallArray[1] __attribute__ ((aligned (4)));
Обновить:Хм, большая сторонняя библиотека макросов, которая генерирует явно несоответствующий код?(Если бы это был код, соответствующий стандарту, он, предположительно, работал бы нормально.:-) Хорошо, это ужасная ошибка, но я могу почти гарантировать, что она "сработает", FSDO "сработает" и не потребует отладки библиотеки макросов ... Вы могли бы постобработать выходные данные компилятора на языке ассемблера.Локальные статические символы bss не зависят от компоновки и обычно объявляются в одном .comm
или .lcomm
директива, для которой последним параметром, скорее всего, будет сумма выравнивания.
Этот параметр - это то, что __attribute__
Изменения.Вы могли бы изменить их все во время сборки с помощью какого-нибудь скрипта...
Другие советы
В системах, над которыми я работал, параметрами компоновщика можно было управлять, чтобы задать выравнивание начала каждого раздела, но не выравнивание отдельных переменных внутри раздела.Выравнивание отдельных переменных было определено компилятором в соответствии с типом переменной.
Возможно, вы сможете использовать какую-то прагму компилятора, конечно, зависящую от конкретной платформы.
Альтернативой является определение вашего массива как массива любого типа, который вам нужно выровнять, например uint32_t.
Мне любопытно узнать, чего вы пытаетесь достичь - звучит так, как будто вы делаете что-то немного необычное и зависящее от конкретной платформы, если у вас есть такое требование к выравниванию.Лучше всего создавать платформенно-независимый код, если это вообще возможно, конечно.