I have a GCC project for a microcontroller. There are some functions in the run-time that must be replaced to adapt the environment:
_write_r
_sbreak_r
I have implemented the functions in a file sys.c. When I link the file sys.o with my project it works as expected. But when I added the sys.o to a library bsp.a and link the library with my project the libc.a implementation gets precedence and my replacement doesn't work anymore.
How can I control the linker that it first links my library before it takes the definitions from the libc? I would prefer a solution where the linker script controls this precedence.
Edit: The GCC is called by the development environment for the linking stage. It controls the ld
invokation and the ld
command line parameters can't be controlled directly.
Edit: The CPU is a Cotex-M3 NXP LPC1788.
When I run the gcc linking command with the -v option I get this information:
c:/arm/bin/../lib/gcc/arm-none-eabi/4.7.4/collect2.exe
--sysroot=arm\bin\../arm-none-eabi
-X
-o bin/test.elf
-n arm/bin/../lib/gcc/arm-none-eabi/4.7.4/armv7-m/crti.o arm/bin/../lib/gcc/arm-none-eabi/4.7.4/armv7-m/crtbegin.o arm/bin/../lib/gcc/arm-none-eabi/4.7.4/../../../../arm-none-eabi/lib/armv7-m/crt0.o
-LD:/mylibs
-LC:\arm\lib
-Lc:/arm/bin/../lib/gcc/arm-none-eabi/4.7.4/armv7-m
-Lc:/arm/bin/../lib/gcc/arm-none-eabi/4.7.4/../../../../arm-none-eabi/lib/armv7-m
-Lc:/arm/bin/../arm-none-eabi/lib/armv7-m
-Lc:/arm/bin/../lib/gcc/arm-none-eabi/4.7.4
-Lc:/arm/bin/../lib/gcc
-Lc:/arm/bin/../lib/gcc/arm-none-eabi/4.7.4/../../../../arm-none-eabi/lib
-Lc:/arm/bin/../arm-none-eabi/lib @C:\Users\harper\AppData\Local\Temp\cc9FN35g
--start-group -lgcc -lc --end-group
c:/arm/bin/../lib/gcc/arm-none-eabi/4.7.4/armv7-m/crtend.o
c:/arm/bin/../lib/gcc/arm-none-eabi/4.7.4/armv7-m/crtn.o
-T src\LPC1788_Flash.ld
Obviously there is a --start-group -gcc -lc --end-group
argument to collect2.exe
. But it has not been possible to add my library yet.
The file LPC1788_Flash.ld has this content:
ENTRY(Reset_Handler)
MEMORY {
FLASH (rx) : ORIGIN = 0, LENGTH = 512K
RAM (xrw) : ORIGON = 0x10000000, LENGTH = 64K
}
SECTIONS {
// a lot of input and output sections, like ...
.isr_vector : { . = ALIGN(4); KEEP(*(.isr_vector)) } >FLASH
.data : { ... } >RAM
.bss : { ... } >RAM
/DISCARD/ : {
libc.a ( * )
libm.a ( * )
libgcc.a ( * )
}
}
When you want to use the definitions of a source file of the custom library you have to make sure that the corresponding object file (of the library) is loaded before the system libraries are loaded to resolve externals.
This can be done by an explicit reference to a symbol of that file.
extern int _write_r();
void *magic = &_write_r;
This code should be placed so that the compiler will it not omit it due to optimization.
Using the linker script to build a group including the custom library with the system libraries is unfortunately not possible. The GROUP definitions of the linker script are processed after the groups defined by the built-in rules.