как я могу запретить компилятору arm-none-eabi генерировать основной символ

Я использую arm-none-eabi для компиляции исходного файла. после компиляции и создания файла elf. Я получил следующие символы с помощью команды nm

00021da8 T ISR_Init
         U main
         U malloc
010008b0 D MASTER_AHB_MAP

Я использую gdb для отладки, но у меня проблема с символом main, который не определен. gdb генерирует следующую ошибку:

Function "main" not defined.

когда я меняю точку входа на основную, все работает нормально. Я разрабатываю программу на чистом железе, поэтому я нигде не определял main в своей программе.

Я связал свою программу со следующими библиотеками

(GNU_ARM_TOOL)/lib/gcc/arm-none-eabi/4.8.4/armv7-ar/thumb/fpu
(GNU_ARM_TOOL)/arm-none-eabi/lib/armv7-ar/thumb/fpu

насколько я понимаю, символ main генерируется из одной из вышеуказанных библиотек. мой вопрос в том, как я могу или как я могу избежать генерации компилятором неопределенного символа main или, по крайней мере, удалить неопределенный символ main в конечном файле elf, чтобы избежать ошибки gdb.


person mikmik    schedule 28.04.2015    source источник
comment
Запустите команду, которую вы используете для компоновки программы с параметром -v. Вы должны увидеть, что введен некоторый код запуска (иногда называемый crt0.o). Отсюда и ссылка на main().   -  person Richard Pennington    schedule 28.04.2015


Ответы (1)


Чтобы gcc не создавал ссылки на main, свяжите свою программу с параметром -nostdlib gcc:

-nostdlib: Не используйте стандартные системные файлы запуска или библиотеки при компоновке. Компоновщику не передаются файлы запуска, а только указанные вами библиотеки, а параметры, определяющие привязку системных библиотек, такие как -static-libgcc или -shared-libgcc, игнорируются. Компилятор может генерировать вызовы memcmp, memset, memcpy и memmove. Эти записи обычно разрешаются записями в libc. Эти точки входа должны предоставляться через какой-либо другой механизм, если указан этот параметр.

Одной из стандартных библиотек, которую игнорируют -nostdlib и -nodefaultlibs, является libgcc.a, библиотека внутренних подпрограмм, которую GCC использует для преодоления недостатков конкретных машин или особых потребностей некоторых языков. (Подробнее о libgcc.a см. в разделе Взаимодействие с выводом GCC.) В большинстве случаев вам нужна libgcc.a, даже если вы хотите избежать использования других стандартных библиотек. Другими словами, когда вы указываете -nostdlib или -nodefaultlibs, вы обычно должны указывать и -lgcc. Это гарантирует отсутствие неразрешенных ссылок на подпрограммы внутренней библиотеки GCC.

Чтобы gcc не генерировал вызовы memcmp, memset, memcpy и т. д., компилируйте с параметром -ffreestanding gcc. Или используйте синтаксис «атрибутов функции», например:

/* defined in the linker script gcc.ld */
extern int __etext, __data_start__, __data_end__, __bss_start__, __bss_end__;

/* make gcc not translate the data copy loop into a memcpy() call
 *
 * See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=56888
 * Note that just passing optimize("freestanding", "no-builtin")
 * as a function attribute here doesn't work on
 * gcc-arm-embedded 2014 (gcc 4.9.3) */
__attribute__((optimize("freestanding", "no-builtin",
                        "no-tree-loop-distribute-patterns")))
void Reset_Handler()
{
        int *src, *dst;
        for (src = &__etext, dst = &__data_start__;
                        dst != &__data_end__;
                        src++, dst++)
                *dst = *src;
        for (dst = &__bss_start__; dst < &__bss_end__; dst++)
            *dst = 0;

        main();
}
person scottt    schedule 03.05.2015
comment
извините, я скомпилировал с опцией -nostdlib, но я все еще получаю символ U main с помощью команды nm. это потому, что я связался с этими двумя библиотеками выше. также эта опция также доступна для команды as - person mikmik; 04.05.2015
comment
Это означает, что вы связываетесь с библиотекой, которая явно вызывает main (вероятно, стандартную библиотеку C или код запуска поставщика). Для as нет эквивалентной опции, так как -nostdlib управляет только связыванием. Предложение: посмотрите на команду link в вашем Makefile. Есть ли -lc или какие-либо подозрительные объекты, которые могут вызывать main? - person scottt; 04.05.2015
comment
да, я уже связываюсь с библиотекой, которая вызывает main, она находится в (GNU_ARM_TOOL)/lib/gcc/arm-none-eabi/4.8.4/armv7-ar/thumb/fpupath. в этом пути есть crti.o , crtn.o , libgcc.a crtbegin.o crtend libgcov.a . вы имеете в виду, чтобы избежать создания символа main, я не должен ссылаться на эти библиотеки???. Я ищу способ избежать генерации main и ссылки на библиотеку, которая генерирует main одновременно - person mikmik; 04.05.2015
comment
Я ищу способ избежать генерации main и ссылки на библиотеку, которые генерируют main одновременно --> Вы боретесь с компоновщиком и кодом запуска без какой-либо выгоды. Не делай этого. Либо не связывайтесь с кодом запуска, который вызывает main, если он вам не нужен, либо связывайтесь с кодом запуска и дайте ему символ `. - person scottt; 04.05.2015
comment
Если вы знаете, как выполнить аппаратную инициализацию на вашей платформе без операционной системы, и считаете, что код запуска вам не нужен, просто добавьте код, подобный Restart_Handler() выше, для инициализации сегментов .data и .bss. Это отлично работает для C. - person scottt; 04.05.2015
comment
Ссылка с кодом запуска, если, например. вам нужна поддержка статических конструкторов С++. Если вы действительно ненавидите имя main, вы можете указать свою точку входа main в качестве псевдонима stackoverflow.com/questions/18278235/ - person scottt; 04.05.2015