Как избавиться от предупреждения ассемблера gcc, устанавливающего неверные атрибуты раздела для .init в коде C?

У меня есть следующий код C:

struct myStruct_t
{
    const char     m_name[60];
    const uint32_t m_data;
};

const struct myStruct_t myStruct
    __attribute__(( __aligned__( 64 ), section(".init") )) =
    {
        "myName",
        (uint32_t)&someOtherStruct
    };

Когда я компилирую в gcc 4.1.1 (для PS3), я получаю предупреждение:

1>c:/t/ccy6.s: Assembler messages:
1>c:/t/ccy6.s(106): Warning: setting incorrect section attributes for .init

Ассемблерный код, на который указывает предупреждение, — это предложение «.section» ниже:

            .section              .init,"aw",@progbits
            .align 6
            .type                 myStruct , @object
            .size                 myStruct , 64
myStruct :
            .ascii                "myName"
            .long                 someOtherStruct

Ему не нравится «w» (доступная для записи) часть флагов, поскольку содержимое .init доступно только для чтения, а «const» во всех возможных местах не заставляет компилятор не выплевывать «w». Как я могу сказать компилятору «нет, правда, это const, я не шучу»?


person Jim Buck    schedule 13.04.2009    source источник
comment
Какую версию GCC вы используете? Это не дает мне предупреждений с gcc-3.4.5   -  person e.James    schedule 14.04.2009
comment
4.1.1 (для PS3).. обновлен OP, чтобы отразить это. Хороший звонок, спасибо.   -  person Jim Buck    schedule 14.04.2009


Ответы (5)


Это проблема с автоматическим указанием GCC параметров для директивы .section. К счастью, параметр имени раздела копируется непосредственно в выходные данные сборки, что позволяет обойти эту проблему.

Эта директива:

__attribute__ ((section(".init")))

Генерирует эту сборку:

.section .init,"aw",@progbits

Чтобы убрать предупреждение, вы можете указать такой атрибут:

__attribute__ ((section(".init,\"ar\",@progbits ;")))

Что будет генерировать:

.section .init,"ar",@progbits ;"aw",@progbits

Точка с запятой помечает оставшуюся часть строки как комментарий, поэтому ассемблер игнорирует ее.

person Luke Gumbley    schedule 10.08.2010

Дикое предположение, но, возможно, атрибут, который он устанавливает неправильно, - это «aw», который предлагает мне «доступный для записи». Это все еще делает это, если все в вашей структуре является константой?

Редактировать: случайное гугление, кажется, предполагает, что «w» также может означать «слабый»?

person Dan Olson    schedule 13.04.2009
comment
Я изменил OP, чтобы везде поставить const, и получил тот же результат. Да, ему не нравится флаг записи из-за того, что .init доступен только для чтения. Почему gcc вообще выплевывает w и как я могу это предотвратить? (средство выделяемое, что здесь нормально) - person Jim Buck; 14.04.2009
comment
Хм, слабых не видел, но вот перезаписываемый (под разделом ELF): sourceware.org/binutils/docs/as/Section.html - person Jim Buck; 14.04.2009

На ПК GNU/Linux с GCC 4.3.3 файл .init недоступен для записи. Я не нашел в документации, как установить атрибуты раздела вручную.

Возможно, это не сильно поможет, но вот несколько советов:

  • Если вы хотите выполнить некоторый код до main(), вы можете использовать объект C++. Его конструктор будет вызываться до main(), а его деструктор после.
  • Вы можете написать небольшой инструмент, который будет вручную исправлять объектный файл. Я почти уверен, что это уже существует. Может быть здесь: http://www.eresi-project.org/.
  • Вы можете связаться с разработчиками GCC. Возможно, это ошибка.
person Bastien Léonard    schedule 14.04.2009
comment
Спасибо за ответ. С++, к сожалению, не вариант, и я на самом деле не хочу, чтобы .init был доступен для записи. Я просто пытаюсь удалить все предупреждения из кода. Эта структура хороша, если она доступна только для чтения, но да, она выглядит как ошибка gcc, которая везде выдает w вместо данных с const. - person Jim Buck; 14.04.2009

Ради бога, чувак, не пытайся использовать gcc как ассемблер! Я не вижу никаких причин, по которым эта вещь должна быть в разделе .init (это не код), но если она должна быть там, напишите код сборки, который вы хотите (у вас хорошее начало; просто отредактируйте), поместите его под контроль версий в соответствующее место для каждой платформы, и покончим с этим!

person Norman Ramsey    schedule 18.04.2009

Если вы хотите поместить myStruct в особое место, используйте файл компоновщика.

http://sourceware.org/binutils/docs-2.19/ld/Scripts.html#Scripts

person Markus Schnell    schedule 24.04.2009