GNU ld reports syntax-error when I specify an output section type as described in the official documentation - linker

The official GNU ld documentation says that I can specify an optional type for an output section:
section [address] [(type)] :
[AT(lma)]
[ALIGN(section_align) | ALIGN_WITH_INPUT]
[SUBALIGN(subsection_align)]
[constraint]
{
output-section-command
output-section-command
…
} [>region] [AT>lma_region] [:phdr :phdr …] [=fillexp]
If I do a full-text search for the pattern TYPE = in the source code of GNU ld, I find examples such as
SECTIONS {
.rom (NOLOAD) : { LONG(1234); }
.ro (READONLY) : { LONG(5678); }
.over (OVERLAY) : { LONG(0123); }
progbits (TYPE=SHT_PROGBITS) : { BYTE(1) }
(from GNU binutils # 658ba81aef5 in /ld/testsuite/ld-scripts/output-section-types.t)
However, I specify the following in my linker script
.bss ALIGN(4K) (TYPE = SHT_PROGBITS) : ALIGN(4K)
{
*(COMMON)
*(.bss .bss.*)
}
GNU ld reports an error in this line. Without (TYPE = SHT_PROGBITS), it works. Isn't this how it is supposed to work?
I'm using GNU binutils at version 2.34.

The syntax is perfectly fine. The problem is that the used GNU ld is outdated. The support to specify the output section type was relatively recently merged on 2022-02-16, as the changelog says. It should be available since GNU binutils 2.39.

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) }
....
}

libgcc_s.so: Error adding symbols: File in wrong format

When using GCC like gcc -march i486 -m32 -e Harimain -o bootpack.hrb bootpack.c hankaku.c naskfunc.o, the compiler worked well. But when I add -T link.ls it told me:
libgcc_s.so:Error adding symbols:File in wrong format
I am creating 32bit binary on 64bit PC. This is my linker script:
OUTPUT_FORMAT("binary");
SECTIONS
{
.head 0x0 : {
LONG(0x64 * 1024) /* 0 : stack+.data+heap の大きさ(4KBの倍数) */
LONG(0x69726148) /* 4 : シグネチャ "Hari" */
LONG(0) /* 8 : mmarea の大きさ(4KBの倍数) */
LONG(0x310000) /* 12 : スタック初期値&.data転送先 */
LONG(SIZEOF(.data)) /* 16 : .dataサイズ */
LONG(LOADADDR(.data)) /* 20 : .dataの初期値列のファイル位置 */
LONG(0xE9000000) /* 24 : 0xE9000000 */
LONG(main - 0x20) /* 28 : エントリアドレス - 0x20 */
LONG(0) /* 32 : heap領域(malloc領域)開始アドレス */
}
.text : { *(.text) }
.data 0x310000 : AT ( ADDR(.text) + SIZEOF(.text) ) {
*(.data)
*(.rodata*)
*(.bss)
} /DISCARD/ : { *(.eh_frame) }
}
The OS is Ubuntu 16.04 64-bit and GCC version is 5.4.0.
What is the problem, and how do I fix it?
GCC builds shared programs by default. So try adding -static to your command line. You will probably want also -ffreestanding.
My advice when doing these kind of things is to separate the compile and the linker commands, and do the linker using ld, not gcc. gcc assumes too many things when doing the linker phase.

How to solve the error in linker script?

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.

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