Why are there two 'KEEP' statements in this linker script section for the initialization array? - linker

I am currently working with a linker script and I noticed that there are two 'KEEP' statements in a specific section for the initialization array. The section looks like this:
.init_array :
{
PROVIDE_HIDDEN (__init_array_start = .);
KEEP (*(SORT(.init_array.*)))
KEEP (*(.init_array ))
PROVIDE_HIDDEN (__init_array_end = .);
} > ram
I am wondering why both of these 'KEEP' statements are necessary?
Any help would be greatly appreciated. Thank you.

Related

How to implement custom output section in GNU LD?

I'm trying to figure out how to define a custom output section in my application's LD file. So far, this is what I've come up with...
MEMORY
{
...
m_my_custom_section (RW) : ORIGIN = 0x00002400, LENGTH = 0x00000400
...
}
SECTIONS
{
...
.my_custom_section :
{
. = ALIGN(4);
KEEP(*(.my_custom_section))
. = ALIGN(4);
} > m_my_custom_section
...
}
Unfortunately, that's where I'm stuck. I'm unsure how to specify which parts of my code I want assigned to that section when the application links. Any help would be great. :)
I believe I found the answer here in #Mike Kinghan's comment:
In Standard C or C++ there are no syntactic means to define sections. Section definition normally is entirely the compiler's business. A compiler may have non-standard extensions that let you assign an object to a named section. For GCC see the documentation of __attribute__ ((section ("<section-name>"))) in Common Variable Attributes and Common Function Attributes Such extensions are for specialized purposes.

Create default sections in linker script

I have a very simple linker script as follows:
ENTRY(_start)
SECTIONS {
. = 1M; /* Load the kernel at 1M */
.text ALIGN (4K) : {
*(.multiboot) /* the multiboot header */
*(.text)
}
.data ALIGN (4K) : { *(.data) }
.bss ALIGN (4K) : { *(.bss) *(COMMON) }
}
While this works for a very basic assembly project, when I add in C, I want to make sure that no important sections from that get left out. The readelf -S output on some compiled C code shows at least a half dozen other sections that gcc's output includes, not including the debug sections.
I would like these sections to be included at the end, but I don't want to have to write it for every section (which could vary depending on whether I'm using debug, as well as on the contents of the C code).
Is there a way to make ld include any extra input sections without specifying them explicitly in the linker script?

Difference between *(.data), *(.data*) and *(.data.*) in linker script

Just curious to know what is the difference between such constructions (for text, data, rodata, bss etc) in linker script:
.data :
{
*(.data)
}
.data :
{
*(.data*)
}
.data :
{
*(.data.*)
}
In all cases we gather data sections from all object files, but the devil is in the detail.
Fast test showed that addresses in map file differ and in turn it influences the size of executable file.
I tried to find the information in ld documentation but found nothing (or just missed it).
I guess that it should be something very simple (so called obvious).
Any ideas will be highly appreciated.
In any place where you may use a specific file or section name, you may also use a wildcard pattern.
It works like a regular pattern
*(.data) - .data sections, Example: .data
*(.data*)- .data* section, Example: .dataTEST
*(.data.*) - .data.* section, Example: .data.TEST
Find more info here

GNU linker and linker script : Linker does not generate correct LMA

I have the following line in my linker script
JumpTable ABSOLUTE(0x2000000C): AT(eROData)
{
JumpTableStart = .;
*(.JumpSection);
. = ALIGN(4);
JumpTableEnd = .;
} > SRAM
eROData is an address from flash and assumes a value 0x1000xxxx
After linking, I notice that the linker assigns both VMA and LMA to the section JumpTable.
This is the listing from the list file.
2 .rodata 00000004 10001214 10001214 00001214 2**2
CONTENTS, ALLOC, LOAD, READONLY, DATA
3 JumpTable 00000140 2000000c 2000000c 00008954 2**2
CONTENTS, READONLY
No such problems with the .data section.
Is this a known GNU linker problem?
EDIT:
I noticed that if the section ".JumpSection" were defined in a C file, the LMA was correctly assigned.
I am facing this problem because the section is defined in an assembly file.
Have you faced this problem before?
EDIT - SOLUTION :
It turns out that .JumpSection had to be defined with correct attributes:
.section ".JumpSection","ax",%progbits
Only then would the linker behave correctly.
So here is what I found out. Perhaps this could save someone from hours of frustrating debugging.
My main problem was that there was a piece of assembly code that needed to be linked into SRAM space and loaded from flash space. So the VMA had to be a SRAM address and LMA a flash address.
In the past, I always succeeded in accomplishing above for functions/data defined in a c file. All I would need to do was assign a section attribute and modify the linker script appropriately.
INFERENCE 1: The linker allows a different LMA for standard TEXT and DATA sections although they may be named differently using the section attribute.
No such luck when the same was attempted in an assembly file. The linker refused to acknowledge that input section .JumpTable defined above was actually a user defined TEXT section.
The solution was then
To move the assembly code to a new file JumpTable.S.
Rename the the input section .JumpTable to .text
Modify the linker file as follows
.text :
{
*(EXCLUDE_FILE(*JumpTable.o) .text); /* Exclude .text of JumpTable.o and place others */
} > FLASH
JumpTable ABSOLUTE(0x2000000C) : AT (eROData) /* Link to SRAM and Load after const data */
{
JumpTableStart = .;
*JumpTable.o(.text); /* Place .text of JumpTable.o into JumpTable output section) */
JumpTableEnd = .;
} > SRAM
Maybe there is a better explanation/another root cause. But this saved my day for sure.

What is the use of defining symbols in linker script?

I am wondering what is the use of defining symbols in a linker script. Using a linker script to arrange different sections is understandable but defining new symbols in the script is not clear to me. I was reading an article which uses a linker script defining two new symbols but those symbols were not referenced anywhere else in the linker script or in the article. An example is the use of sbss and ebss symbols in the bss section as shown below :
ENTRY (loader)
SECTIONS
{ . = 0x00100000;
.text ALIGN (0x1000) :
{
*(.text)
}
.rodata ALIGN (0x1000) :
{
*(.rodata*)
}
.data ALIGN (0x1000) :
{
*(.data)
}
.bss :
{
sbss = .;
*(COMMON)
*(.bss)
ebss = .;
}
}
There are other symbols also which are frequently used such as etext , dataEnd etc. Please explain the use of defining such symbols when they are not referenced anywhere in the script.
vjain27,
I do not know why one would define symbols as your example linker script defines. This is mostly done in order to allow the executable to know the start and end of a section. This is useful if the data needs to be copied, or otherwise manipulated in memory.
When writing an x86 bootloader, I want the image to be a multiple of 512 bytes by using:
. = ALIGN(512);
in the linker script.
But then I need some way to know the exact size, and pass that to the al of my boot code which will to an int 13h BIOS call that loads data from hard disk to memory. So I wrote something like:
__stage2_size = .;
BYTE((ALIGN(.) / 512) - 1);
. = ALIGN(512);
and used __stage2_size on the boot script.

Resources