Using config.ini variables in ldscript.ld - linker

In my config.ini file I have defined these variables:
# Where will system be loaded when started (for which address to prepare it)
LOAD_ADDR = 0x100000
RAM_ADDR = 0x300000
ROM_ADDR = 0x200000
STACK_ADDR = 0x600000
Which I then use in the .data section of the linker script ldscript.ld:
SECTIONS {
.code LOAD_ADDR :
{ /* This is line 9 */
kernel_code_addr = .;
/* instructions */
*?/boot/startup.asm.o ( .text* )
*( .text* )
}
.data RAM_ADDR : AT(ROM_ADDR)
{
kernel_data_addr = .;
/* read only data (constants), initialized global variables */
* ( .rodata* .data* )
}
.bss :
{
*( .bss* COMMON* )
. = ALIGN (4096);
}
/* ... */
}
But running make fails while linking with this error:
[linking build/04_Debugging.elf]
ld:build/ldscript.ld:9: non constant or forward reference address expression for section .data
make: *** [Makefile:87: build/04_Debugging.elf] Error 1
When I replace RAM_ADDR and ROM_ADDR in the code with their values, make finishes nicely and everything works.
What causes this error? Why can I use LOAD_ADDR with no errors?

The linker does not seem to load the variables you defined in config.ini.
You can use INCLUDE in your linker script to include another file.
From https://ftp.gnu.org/old-gnu/Manuals/ld-2.9.1/html_chapter/ld_3.html
INCLUDE filename
Include the linker script filename at this point. The file will be searched for in the current directory, and in any directory specified with the -L option. You can nest calls to INCLUDE up to 10 levels deep.
So if you add INCLUDE config.ini to the start of your linker script it should work.

Another approach is to use the C preprocessor to generate your linker script.
You can use -imacros to load a config.h that defines the symbols you want, then use them in the linkerscript.ld.h and generate the linker script before using it to link
gcc -imacros config.h -E linkerscript.ld.h -o linkerscript.ld

Related

Stack initialisation in GNU ARM toolchain

Checking the startup file provided as an example in the GNU ARM toolchain, I couldnt understand one thing.
Code snippets provided here are taken from examples included in GNU ARM Embedded Toolchain files downloaded from official website. Code compiles and everything seems to be good.
I am wondering why they wrote this code exactly like that, why they are using same names for example?
I am wondering why my linker is not complaining about multiple definition error for __StackTop and __StackLimit. Here is the part of the file startup_ARMCM0.S
.syntax unified
.arch armv6-m
.section .stack
.align 3
#ifdef __STACK_SIZE
.equ Stack_Size, _*emphasized text*_STACK_SIZE
#else
.equ Stack_Size, 0xc00
#endif
.globl __StackTop
.globl __StackLimit
__StackLimit:
.space Stack_Size
.size __StackLimit, . - __StackLimit
__StackTop:
.size __StackTop, . - __StackTop
If the linker is defining the same symbols: __StackTop and __StackLimit.
.stack_dummy (COPY):
{
*(.stack*)
} > RAM
/* Set stack top to end of RAM, and stack limit move down by
* size of stack_dummy section */
__StackTop = ORIGIN(RAM) + LENGTH(RAM);
__StackLimit = __StackTop - SIZEOF(.stack_dummy);
PROVIDE(__stack = __StackTop);
While checking linker documentation, it was written that, given the example:
SECTIONS
{
.text :
{
*(.text)
_etext = .;
PROVIDE(etext = .);
}
}
In this example, if the program defines _etext (with a leading
underscore), the linker will give a multiple definition error. If, on
the other hand, the program defines etext (with no leading
underscore), the linker will silently use the definition in
the program. If the program references etext but does not define
it, the linker will use the definition in the linker script.
Also, when using readelf -s just to check symbols generated from assembly file startup_ARMCM0.S without linking, I can see the symbol __StackTop and __StackLimit with one values. While, after linking they have the values set up by the linker (keeping in mind that the value of the linker is actually stored in address of the symbol).

Windriver compiler linker file regex

is there a way to use regex to add all C object files starting with foo for example to the linker file bss section with Windriver compiler instead of adding them manually one by one
SECTIONS {
outputa 0x10000 :
{
foo1.o (.bss)
foo2.o (.bss)
......
foon.o (.bss)
}
Imagined solution
SECTIONS {
outputa 0x10000 :
{
foo*.o (.bss)
Yes, it is possible to use regex in linker script.
GROUP : {
.sectionname:{"foo*"(.bss) }
....
}

How to fail the build based on the conditional values of linker variables defined in linker script?

How to fail the build based on the conditional values of linker variables defined in linker script?
I am compiling C code using GCC. I defined a linker variable BINARY_TEST. If Value of BINARY_TEST > 32KB, then i want to Fail the build. How to write a conditional test and fail the build using linker script?
Please suggest any script.
SECTIONS
{
. = 0x0000 ;
.text :
{
*(.text)
*(.rdata)
}
.data :
{
*(*.data)
*(*.bss)
}
BINARY_TEST = . ;
/*Want something like below */
if (BINARY_TEST > 32KB)
Throw Error and stop
/* ******* */
END = . ;
}
How to write a conditional test and fail the build using linker script?
It seems to me that you could trivially implement the failure as a post-link step. E.g. in your Makefile:
foo.exe: foo.o
$(CC) -o foo.exe ...
nm foo.exe | grep BINARY_TEST | \
... commands to verify that symbol value < 32K, or fail
Here is one way to do this:
CHECK_BOOTLOADER_SIZE = 1 / (. <= 32768);
If the current position is beyond the limit, this will give an error message:
linker.ld:33 / by zero
Not the clearest error message but at least it includes the line number so that user can read the comments.

What does KEEP mean in a linker script?

The LD manual does not explain what the KEEP command does. Below is a snippet from a third-party linker script that features KEEP. What does the KEEP command do in ld?
SECTIONS
{
.text :
{
. = ALIGN(4);
_text = .;
PROVIDE(stext = .);
KEEP(*(.isr_vector))
KEEP(*(.init))
*(.text .text.*)
*(.rodata .rodata.*)
*(.gnu.linkonce.t.*)
*(.glue_7)
*(.glue_7t)
*(.gcc_except_table)
*(.gnu.linkonce.r.*)
. = ALIGN(4);
_etext = .;
_sidata = _etext;
PROVIDE(etext = .);
_fini = . ;
*(.fini)
} >flash
Afaik LD keeps the symbols in the section even if symbols are not referenced. (--gc-sections).
Usually used for sections that have some special meaning in the binary startup process, more or less to mark the roots of the dependency tree.
(For Sabuncu below)
Dependency tree:
If you eliminate unused code, you analyze the code and mark all reachable sections (code+global variables + constants).
So you pick a section, mark it as "used" and see what other (unused) section it references, then you mark those section as "used", and check what they reference etc.
The section that are not marked "used" are then redundant, and can be eliminated.
Since a section can reference multiple other sections (e.g. one procedure calling three different other ones), if you would draw the result you get a tree.
Roots:
The above principle however leaves us with a problem: what is the "first" section that is always used? The first node (root) of the tree so to speak? This is what "keep()" does, it tells the linker which sections (if available) are the first ones to look at. As a consequence these are always linked in.
Typically these are sections that are called from the program loader to perform tasks related to dynamic linking (can be optional, and OS/fileformat dependent), and the entry point of the program.
Minimal Linux IA-32 example that illustrates its usage
main.S
.section .text
.global _start
_start:
/* Dummy access so that after will be referenced and kept. */
mov after, %eax
/*mov keep, %eax*/
/* Exit system call. */
mov $1, %eax
/* Take the exit status 4 bytes after before. */
mov $4, %ebx
mov before(%ebx), %ebx
int $0x80
.section .before
before: .long 0
/* TODO why is the `"a"` required? */
.section .keep, "a"
keep: .long 1
.section .after
after: .long 2
link.ld
ENTRY(_start)
SECTIONS
{
. = 0x400000;
.text :
{
*(.text)
*(.before)
KEEP(*(.keep));
*(.keep)
*(.after)
}
}
Compile and run:
as --32 -o main.o main.S
ld --gc-sections -m elf_i386 -o main.out -T link.ld main.o
./main.out
echo $?
Output:
1
If we comment out the KEEP line the output is:
2
If we either:
add a dummy mov keep, %eax
remove --gc-sections
The output goes back to 1.
Tested on Ubuntu 14.04, Binutils 2.25.
Explanation
There is no reference to the symbol keep, and therefore its containing section .keep.
Therefore if garbage collection is enabled and we don't use KEEP to make an exception, that section will not be put in the executable.
Since we are adding 4 to the address of before, if the keep section is not present, then the exit status will be 2, which is present on the next .after section.
TODO: nothing happens if we remove the "a" from .keep, which makes it allocatable. I don't understand why that is so: that section will be put inside the .text segment, which because of it's magic name will be allocatable.
Force the linker to keep some specific sections
SECTIONS
{
....
....
*(.rodata .rodata.*)
KEEP(*(SORT(.scattered_array*)));
}

Linking the Linker script file to source code

I am new to GNU compiler.
I have a C source code file which contains some structures and variables in which I need to place certain variables at a particular locations.
So, I have written a linker script file and used the __ attribute__("SECTION") at variable declaration, in C source code.
I am using a GNU compiler (cygwin) to compile the source code and creating a .hex file using -objcopy option, but I am not getting how to link my linker script file at compilation to relocate the variables accordingly.
I am attaching the linker script file and the C source file for the reference.
Please help me link the linker script file to my source code, while creating the .hex file using GNU.
/*linker script file*/
/*defining memory regions*/
MEMORY
{
base_table_ram : org = 0x00700000, len = 0x00000100 /*base table area for BASE table*/
mem2 : org =0x00800200, len = 0x00000300 /* other structure variables*/
}
/*Sections directive definitions*/
SECTIONS
{
BASE_TABLE : { } > base_table_ram
GROUP :
{
.text : { } { *(SEG_HEADER) }
.data : { } { *(SEG_HEADER) }
.bss : { } { *(SEG_HEADER) }
} > mem2
}
C source code:
const UINT8 un8_Offset_1 __attribute__((section("BASE_TABLE"))) = 0x1A;
const UINT8 un8_Offset_2 __attribute__((section("BASE_TABLE"))) = 0x2A;
const UINT8 un8_Offset_3 __attribute__((section("BASE_TABLE"))) = 0x3A;
const UINT8 un8_Offset_4 __attribute__((section("BASE_TABLE"))) = 0x4A;
const UINT8 un8_Offset_5 __attribute__((section("BASE_TABLE"))) = 0x5A;
const UINT8 un8_Offset_6 __attribute__((section("SEG_HEADER"))) = 0x6A;
My intention is to place the variables of section "BASE_TABLE" at the address defined i the linker script file and the remaining variables at the "SEG_HEADER" defined in the linker script file above.
But after compilation when I look in to the .hex file the different section variables are located in different hex records, located at an address of 0x00, not the one given in linker script file .
Please help me in linking the linker script file to source code.
Are there any command line options to link the linker script file, if any plese provide me with the info how to use the options.
Thanks in advance,
SureshDN.
Try gcc -Xlinker -T (linker script name) (c sources files)
I first compile all my c files to object files and then link them with:
gcc -Xlinker -T"xxx.lds" (all object files)
From The gcc docs:
`-Xlinker OPTION'
Pass OPTION as an option to the linker. You can use this to
supply system-specific linker options which GNU CC does not know
how to recognize.
Thanks for the response ,
I have found one more linker option in GCC ,"ld" and teh option -T to link the sections to the source code.
ld -T (linker scriptname) -o (final objfile) (objectfile of source file)
Thanks
Suresh

Resources