как мога да попреча на компилатора 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 използва за преодоляване на недостатъците на определени машини или специални нужди за някои езици. (Вижте Взаимодействие с GCC изход, за повече обсъждане на libgcc.a.) В повечето случаи имате нужда от 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 контролира само свързването. Предложение: взирайте се в командата за връзка във вашия 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
Връзка с кода за стартиране, ако за напр. имате нужда от поддръжка на статични конструктори на C++. Ако наистина, наистина мразите името main, можете да дадете входната си точка main като псевдоним stackoverflow.com/questions/18278235/ - person scottt; 04.05.2015