This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Weak symbols with GCC and ARMCC

Hi all,

I am trying to use the weak attribute for global initialized variable. It works for a function I am also trying to re-implement, but fail to do so for variable.  I am trying to do it for quite common scenario: I have layered structure to support applications and bootloader. Certain startup code and vector table I would like to re-implement (simplify) for bootloader. I am working only with object files (dropped using archives because of other linker limitations) so at the end the linker links together a lot of object files (the object files with strong symbols in bootloader case are listed first).

My implementation works without any issue with ARMClang v6.10.1 but has issues with both ARMCC and GCC (see versions below).

Code file1.c:

vect_table_ptr __attribute__((weak)) g_vect_table[] __attribute__((section("vect_table"))) =
...

file2.c:

vect_table_ptr  g_vect_table[] __attribute__((section("vect_table"))) =
...

Note for ARMCC I tried also with __weak and putting both attributes to the same call (joined with section). To be sure the symbols are global I also added extern declaration into the header but it didn't help.

So what happens when I try to compile is I get two instances of this symbol:

 - armlink complains it has multiple matches for this section and cannot all be FIRST/LAST (as vector table is) - it means it has two g_vect_table symbols

 - GCC is even weirder: it links and just put both symbols in the section (so table from file1.c and after that table from file2.c).

If I check (GCC version) object files I get the following (I changed the object filenames for clarity):

[user@ws gcc_build ] arm-none-eabi-nm file1.c.o                                                                                                                               

00000002 T app_vect_table_size
00000000 T default_handler
                   U drv_btmr_isr
                   U drv_dma_isr
                   U drv_spim_isr
00000000 V g_vect_table
                   U __main
                   U _stack_base
[user@ws gcc_build ] arm-none-eabi-nm file2.c.o   

                   U default_handler
                   U drv_dma_isr
                   U drv_spim_isr
00000000 D g_vect_table
                    U __main
                    U _stack_base

It shows g_vect_table from file1.c.o is weak symbol (V) and the one from file2.c.o is initialized data section (D) - which to me it seems correct. But when linking it puts both symbols there.

Does anybody have any idea how to use these weak symbols in this specific case? Issue is that C standard is not well defined for this and it is up to compiler implementation how to handle it.

I have quite some experience with weak symbols and didn't have issues as such in the past but right now I am quite puzzled as there was no way I could make it work. I would like to keep the codebase compilable with all three compilers.

Compiler versions I am using are:

GCC version:

arm-none-eabi-gcc (GNU Tools for ARM Embedded Processors) 5.4.1 20160919 (release) [ARM/embedded-5-branch revision 240496]

ARMCC version:

Product: MDK Professional 5.25 (Flex)
Component: ARM Compiler 5.06 update 6 for Certification (build 750)

Thanks for any comments or ideas and best regards,

Jure Menart