LINUX.ORG.RU

AVR GCC выкидывает неиспользуемые переменные, редиска

 , ,


0

1

Всем привет,

Имеем Atmel Studio, AVR GCC 8-бит v4.8.4, оптимизация -Os (по размеру) и нужно «зарезервировать» место в некоей секции, например для переменной uint32_t. В коде приложения эта переменная нигде не используется. Просто некий внешний патчер, в готовый бинарь, в это место будет записывать некоторое 4-х байтное значение (например, CRC).

Так вот, при линковке, линкер выкидывает эту переменную как бы я ее не объявлял. Не помогает ни volatile, ни attribute(used), ни const, ни static. Вообще, ничего не помогает, компилер/линкер тупо игнорит все, пока где-нибудь в коде эта переменная не заиспользуется, например не инкрементируется.

Вот это все не работает:

static uint32_t x __attribute__ ((section (".NRWWENDCRC"))) = 0x43524331;
volatile static uint32_t x __attribute__ ((section (".NRWWENDCRC"))) = 0x43524331;
volatile uint32_t x __attribute__ ((section (".NRWWENDCRC"))) = 0x43524331;
const uint32_t x __attribute__ ((section (".NRWWENDCRC"))) = 0x43524331;

static uint32_t x __attribute__ ((section (".NRWWENDCRC"), used)) = 0x43524331;
volatile static uint32_t x __attribute__ ((section (".NRWWENDCRC"), used)) = 0x43524331;
volatile uint32_t x __attribute__ ((section (".NRWWENDCRC"), used)) = 0x43524331;
const uint32_t x __attribute__ ((section (".NRWWENDCRC"), used)) = 0x43524331;

Строка линковки примерно такая:

-Wl,-Map=«$(OutputFileName).map» -Wl,--start-group -Wl,-lm -Wl,--end-group -Wl,--gc-sections -Wl, -section-start=.NRWWENDCRC=0x1ebfc -mmcu=at90can128 -Wl,--cref

Строка компилятора примерно такая:

-x c -funsigned-char -funsigned-bitfields -DNDEBUG -Os -fpack-struct -fshort-enums -Wall -Wextra -Wundef -mmcu=at90can128 -c -std=gnu89 -MD -MP -MF «$(@:%.o=%.d)» -MT"$(@:%.o=%.d)" -MT"$(@:%.o=%.o)"

Как я понимаю, отдельного файла линкера нет.

Знатоки, кто-нибудь сталкивался с таким? Помогайте :)

★★

Последнее исправление: kuzulis (всего исправлений: 3)

линкер выкидывает эту переменную

Сделать переменную частью структуры данных, тогда линковщик не сможет повлиять на её размер, если структура используется.

Dendy ★★★★★
()

__attribute__((used)) должно работать, если это не внутри статической библиотеки. У ld ещё есть флаг -u, которым можно заставить притянуть нужный символ.

xaizek ★★★★★
()

UPD: Пробовал такой вариант:

__attribute__ ((section (".NRWWENDCRC")))
const volatile static uint32_t x = APP_END_NRWW_AREA_CRC;

И потом при компиляции указать:

-DAPP_END_NRWW_AREA_CRC=0x43524331

не помогло.

kuzulis ★★
() автор топика
Последнее исправление: kuzulis (всего исправлений: 2)
Ответ на: комментарий от xaizek

__attribute__((used)) должно работать, если это не внутри статической библиотеки.

У меня нет никаких библиотек, не работает (я же раньше писал):

__attribute__ ((section (".NRWWENDCRC"))) __attribute__((used))
const volatile static uint32_t x = 0x43524331;

Нашел еще вот такой вариант:

Unfortunately I am not aware of a pragma to do this. There is however another solution. Change AppVersion to:

static char * AppVersion = "v3.05/10.oct.2015";
and add:
__asm__ ("" : : "" (AppVersion));
to your main function.

но не проверял, да и не хочу что-то добавлять в main ф-ю (в код).

kuzulis ★★
() автор топика
Последнее исправление: kuzulis (всего исправлений: 1)
Ответ на: комментарий от Dendy

Сделать переменную частью структуры данных, тогда линковщик не сможет повлиять на её размер, если структура используется.

Дык, у меня она (переменная) не используется нигде. В этом то и вся «фишка».

kuzulis ★★
() автор топика
Ответ на: комментарий от kuzulis

Нашел еще вот такой вариант:

Не работает тоже:

__attribute__ ((section (".NRWWENDCRC")))
static uint32_t x = 0x43524331;

int main( void )
{
    __asm__ (""::"" (x));
    ...
    ...
}

Гыыы..

kuzulis ★★
() автор топика
Ответ на: комментарий от UVV

Каким боком оно extern, если ему место надо выделить?

extern int foo;
int foo;

по-идее, должно в объектный модуль сделать символ foo с указателем на выделенное место.

monk ★★★★★
()
Ответ на: комментарий от UVV

вот тут пишут, чтобы ты убрал static

Да пофиг...

kuzulis ★★
() автор топика
Ответ на: комментарий от monk

по-идее, должно в объектный модуль сделать символ foo с указателем на выделенное место.

Также пофиг.

kuzulis ★★
() автор топика
Ответ на: комментарий от kuzulis

не работает (я же раньше писал)

Я читать умею, но говорю, что оно работает.

Сейчас заметил это

-Wl,--gc-sections
скорее всего оно же и вырезает. Атрибут то для компилятора. Если сделать нестатическим символом и добавить -Wl,-ux, то тоже должно заработать даже с gc-sections.

xaizek ★★★★★
()
Последнее исправление: xaizek (всего исправлений: 2)
Ответ на: комментарий от xaizek

У ld ещё есть флаг -u, которым можно заставить притянуть нужный символ.

Вооо, это кажется работает:

__attribute__ ((section (".NRWWENDCRC")))
uint32_t x = 0x43524331;

Обязательно нужно указывать без всяких static и volatile (по крайней мере у меня).

И для линкера команда:

-u x

Спасибки :)

kuzulis ★★
() автор топика
Последнее исправление: kuzulis (всего исправлений: 2)
Ответ на: комментарий от kuzulis

Во времена K&R такого не было! Совсем распоясались!

dzidzitop ★★
()

Выкидывает не GCC а линкер, который часть binutils. Обычно такое решается через скрипты линкера, но с командной строкой тоже можно извернутся ...

cvv ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.