cgcclinkerkeiliar

Place segments of external static library to specific locations


My application calls some functions which are placed in an external static library. I link the external static library to my application and everything works (in this case I'm using GCC).

Nevertheless, the locations (addresses) of text, .data and .bss sections of the library are chosen by the linker. I can choose/change their locations by modifying the linker script, but it's tedious as I have to specify all the functions, variables, etc. of the library. What I mean it's something like:

. = 0x1000; /* new location */
KEEP(*(.text.library_function1));
KEEP(*(.text.library_function2));
[...]

An alternative solution is to build the external library by placing a section attribute for each function/variable, and then modifying the linker by re-locating the whole section. Something like:

/* C source file */
unsigned char __attribute__((section (".myLibrarySection"))) variable1[10];
unsigned char __attribute__((section (".myLibrarySection"))) variable2[10];

/* Linker script */
. = 0x1000;
KEEP(*(.myLibrarySection))

However, I'd like to be able to relocate entire .text, .data and .bss segments of an external static library without the need of using these tricks.

I'd like something like this (in linker script):

. = 0x1000;
KEEP(*(.text.library_file_name))

Is it possible using GCC toolchain?

Is it possible using other toolchains (IAR, Keil, etc.)?


Solution

  • You can use the archive:filename syntax in ld.

    First place all the .o files from your external library into a static library .a file, if they aren't already. That is the normal way static library binaries are distributed.

    Then in the linker script, specify:

    .text.special : {
        . = 0x1000;
        *libspecial.a:*(.text .text.*)
    }
    
    .text {
        *(.text .text.*)
    }
    

    The wildcard will pick all the files coming from libspecial.a and place them in the first section. The later wildcard will then pick anything left over. If there is a need to place the .text.special section after the normal section, you can use EXCLUDE_FILE directive in a similar way.