0

I'm using arm-none-eabi to compile source file. after compiling and generating elf file. I got the following symbols using nm command

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

I'm using gdb to debug, but I have problem with main symbol which is not defined. gdb generate following error :

Function "main" not defined.

when I change my entry point to main, it works fine. I'm developing bare metal program, so I didn't define main anywhere in my program.

I linked my program with those following libraries

(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

for my understanding, the main symbol is generated from one of the above libraries. my question is how can I or how can I avoid the compiler generating the undefined symbol main, or at least delete the undefined main symbol in the final elf file to avoid gdb error.

bouqbouq
  • 973
  • 2
  • 14
  • 34
  • Run the command you use to link the program with the -v option. You should see that some start up code is brought in (sometimes called crt0.o). That's where the reference to main() is coming from. – Richard Pennington Apr 28 '15 at 12:02

1 Answers1

2

To avoid gcc generating references to main, link your program with the -nostdlib gcc option:

-nostdlib: Do not use the standard system startup files or libraries when linking. No startup files and only the libraries you specify are passed to the linker, and options specifying linkage of the system libraries, such as -static-libgcc or -shared-libgcc, are ignored. The compiler may generate calls to memcmp, memset, memcpy and memmove. These entries are usually resolved by entries in libc. These entry points should be supplied through some other mechanism when this option is specified.

One of the standard libraries bypassed by -nostdlib and -nodefaultlibs is libgcc.a, a library of internal subroutines which GCC uses to overcome shortcomings of particular machines, or special needs for some languages. (See Interfacing to GCC Output, for more discussion of libgcc.a.) In most cases, you need libgcc.a even when you want to avoid other standard libraries. In other words, when you specify -nostdlib or -nodefaultlibs you should usually specify -lgcc as well. This ensures that you have no unresolved references to internal GCC library subroutines.

To avoid gcc generating calls to memcmp, memset, memcpy etc compile with gcc's -ffreestanding option. Or use "function attributes" syntax, e.g.:

/* 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();
}
scottt
  • 7,008
  • 27
  • 37
  • sorry I compiled with -nostdlib option but I stil get symbol U main using nm command. is that because I linked to those two libraries above. also is this option also available for `as` command – bouqbouq May 04 '15 at 07:39
  • That implies you're linking in a library that calls `main` (likely the C standard library or vendor startup code) explicitly. There's no equivalent option for `as` since `-nostdlib` only controls linking. Suggestion: stare at the link command in your Makefile. Is there a `-lc` or any suspicous objects that might call `main`? – scottt May 04 '15 at 08:41
  • yes I'm already linking with library that calls `main` it's located in `(GNU_ARM_TOOL)/lib/gcc/arm-none-eabi/4.8.4/armv7-ar/thumb/fpu`path. in this path there is `crti.o , crtn.o , libgcc.a crtbegin.o crtend libgcov.a ` . you mean to avoid generating `main` symbol I should not link to those libraries???. I'm looking for way to avoid generating `main` and link to the library that generate `main` in same time – bouqbouq May 04 '15 at 09:00
  • 1
    "I'm looking for way to avoid generating main and link to the library that generate main in same time" --> You're fighting the linker and the startup code for no gain. Don't do this. Either don't link with the startup code that calls `main` if you don't need it or link with the startup code and give it a` symbol. – scottt May 04 '15 at 18:58
  • If you know how to do the hardware initialization on your bare-metal platform and think you don't need the startup code, just add code like my `Restart_Handler()` above to initialize the `.data` and `.bss` segments. This works fine for C. – scottt May 04 '15 at 18:59
  • Link with the startup code, if for e.g. you need C++ static constructors support. If you really, really hate the name `main`, you can give your entry point `main` as an alias http://stackoverflow.com/questions/18278235/aliasing-of-symbol-using-gcc-binutils-works-intermittently – scottt May 04 '15 at 19:00