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) }
....
}
Related
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
I created a memory linker script and saved it as memory.ld in the eclipse ide : Project : properties : gcc linker : miscellaneous : I added -M -T memory.ld
memory.ld :
MEMORY
{
ram (rw) : ORIGIN = 0x4000000 , LENGTH = 2M
}
SECTIONS
{
RAM : { *(.myvarloc)
} > ram }
In my c program : I made a global declaration as:
__attribute__ ((section(".myvarloc")))
uint8 measurements [30];
ERRORS:
/usr/bin/ld: FEBRUARY section `.text' will not fit in region `ram'
/usr/bin/ld: region `ram' overflowed by 20018 bytes
/usr/lib/i386-linux-gnu/libc_nonshared.a(elf-init.oS): In function `__libc_csu_init':
(.text+0x2b): undefined reference to `__init_array_end'
/usr/lib/i386-linux-gnu/libc_nonshared.a(elf-init.oS): In function `__libc_csu_init':
(.text+0x31): undefined reference to `__init_array_start'
/usr/lib/i386-linux-gnu/libc_nonshared.a(elf-init.oS): In function `__libc_csu_init':
(.text+0x57): undefined reference to `__init_array_start'
/usr/bin/ld: FEBRUARY: hidden symbol `__init_array_end' isn't defined
/usr/bin/ld: final link failed: Bad value
collect2: error: ld returned 1 exit status
Depending on the compiler you are using (GCC?) and the processor for which you are compiling (x86?), the compiler will generate several segment references in the object files. The most common ones are .text for code segments, .data for initialized data and .bss for uninitialized data.
You can see which segments your compiler generates by using the nm utility on your object files.
I assume that until you provided your own linker script, the environment has provided some default script automatically and/or implicitly. But now that you have decided to "roll your own", you have to take care of all details yourself.
I cannot verify the details, but you could start with the following SECTIONS:
SECTIONS
{
.bss : { *(.myvarloc) }
.bss : { *(.bss) }
.data : { *(.data) }
.text : { *(.text) }
}
I'm not sure if this is the exact syntax your GCC linker (it depends a little on the version), but you can find more information in the manual.
I need to put the same object into different memory sections. I'm working on a DSP with separate data and program memory. The .text sections are normally stored inside the P-MEM. But I want to store the same code also inside the data memory. It is possible to copy it during run-time, but I think I should also be possible during link time.
This is what I'm looking for, but it's not working since I could not find a "copy" or "duplicate" instruction that would allow to put the same code in different sections.
MEMORY
{
/* MAP 1*/
VECS: org=0x00000000 len=0x00000400
PMEM: org=0x00000400 len=0x0000FC00
DMEM: org=0x80000000 len=0x0000F800
DMEM_FT: org=0x8000F800 len=0x00000800
}
SECTIONS
{
vectors > VECS
.text > PMEM <----- containing ALL code (also including func1.obj(.text) )
.bss > DMEM
.cinit > DMEM
.stack > DMEM
.far > DMEM
.switch > DMEM
.data > DMEM
.sysmem > DMEM
.const > DMEM
.cio > DMEM
dmem_mirror:
{
func1.obj(.text)
} > DMEM_FT
}
If I'm using the linker script above, it's clearly putting the func1.obj only inside the dmem_FT section (that`s what the linker is supposed to do!), but that is not what I want :-/ . I'm working with the Texas Instruments compiler and linker, but the syntax is the same as on a GCC linker.
A quick look at the GNU ld manual does not give an obvious solution. One possible solution does come to mind. You could do a partial (ld -r) link of func1.obj, sending all the sections except .text to the special section /DISCARD/ and only outputting the .text section to e.g. func1a.obj. Unfortunately, I think you'll see multiple symbol definition errors from the linker when you actually do the final link.
Im having problems when I define global variables in a basic C program for an ARM9 processor. I'm using EABI GNU compiler and the binary generated from a 12KB elf is 4GB! I assume the issue is with my scatter file but Im having trouble getting my head around it.
I have 256KB of ROM (base address 0xFFFF0000) and 32KBs of RAM (base 0x01000000)
SECTIONS {
. = 0xFFFF0000;
.text : {
* (vectors);
* (.text);
}
.rodata : { *(.rodata) }
. = 0x01000000;
sbss = .;
.data : { *(.data) }
.bss : { *(.bss) }
ebss = .;
bssSize = ebss - sbss;
}
And my program is as follows:
int a=10;
int main() {
int b=5;
b = (a>b)? a : b;
return b;
};
If I declare a as a local variable, i.e. there is no .data section then everything works.
fine. Any help greatly appreciated.
--16th March 2011--
Can anyone help with this, Im getting nowhere and have read the manuals, forums etc...
My boot, compile command and objcopy commands are pasted below
.section "vectors"
reset: b start
undef: b undef
swi: b swi
pabt: b pabt
dabt: b dabt
nop
irq: b irq
fiq: b fiq
.text
start:
ldr sp, =0x01006000
bl main
stop: b stop
arm-none-eabi-gcc -mcpu=arm926ej-s -Wall -nostartfiles -Wall main.c boot.s -o main.elf -T \ scatter_file
arm-none-eabi-objcopy ./main.elf --output-target=binary ./main.bin
arm-none-eabi-objdump ./main.elf --disassemble-all > ./main.dis
I found the problem. The objcopy command will try to create the entire address space described in the linker script, from the lowest address to the highest including everything in between. You can tell it to just generate the ROM code as follows:
objcopy ./main.elf -j ROM --output-target=binary ./main.bin
I also changed the linker script slightly
MEMORY {
ram(WXAIL) : ORIGIN = 0x01000000, LENGTH = 32K
rom(RX) : ORIGIN = 0xFFFF0000, LENGTH = 32K
}
SECTIONS {
ROM : {
*(vectors);
*(.text);
*(.rodata);
} > rom
RAM : {
*(.data);
*(.bss);
} > ram
}
You are creating a file which will starts at address 0x01000000 and will contains at least up to address 0xFFFF0000. No wonder that it is nearly 4GB. What would you like? Try with options -R to remove the data segments if you don't want them (as it is probably the case if you are preparing a ROM initialization file).
Adding the (NOLOAD) argument worked for me. E.g.
MEMORY {
ram(WXAIL) : ORIGIN = 0x01000000, LENGTH = 32K
rom(RX) : ORIGIN = 0xFFFF0000, LENGTH = 32K
}
SECTIONS {
ROM : {
*(vectors);
*(.text);
*(.rodata);
} > rom
RAM (NOLOAD) : {
*(.data);
*(.bss);
} > ram
}
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