Linker Scripts: Difference between revisions

m
Undo revision 27012 by Xtex (talk)
[unchecked revision][unchecked revision]
m (Undo revision 27012 by Xtex (talk))
Tag: Undo
 
(6 intermediate revisions by 3 users not shown)
Line 1:
{{In Progress}}
 
[[LD|GNU ld]] supports configuration of the linking process via the use of linker scripts. Linker scripts are written in a specialized scripting language specific to the GNU ld application. While the use of a linker script file is not strictly required by <tt>ld</tt>, it provides a more more maintainable alternative to specifying complex configuration options as arguments on the command line. A Linker script's principal use is specifying the format and layout of the final executable binary. This is of particular relevance to operating-system development, where executable binaries will often require specific file layouts in order to be recognized by certain [[Bootloader|bootloaders]]. [[GRUB|GNU GRUB]] is one such bootloader.<br/>
Linker scripts are typically invoked via the use of the <tt>-T script.ld</tt> command line argument when calling the <tt>ld</tt> application.
Line 21 ⟶ 19:
</pre>
 
The <tt>OUTPUT_FORMAT</tt> directive takes a single argument. It specifies the output format of the executable. To find out what output formats are supported by your system binutils and GCC, the <code lang="bash">objdump -i</code> command may be used.
 
Some commonly used formats are detailed below:
Line 102 ⟶ 100:
}
 
.text : ALIGN(0x1000CONSTANT(MAXPAGESIZE)) {
_TEXT_START_ = .;
*(.text)
Line 108 ⟶ 106:
}
 
.data : ALIGN(0x1000CONSTANT(MAXPAGESIZE)) {
_DATA_START_ = .;
*(.data)
Line 114 ⟶ 112:
}
 
.bss : ALIGN(0x1000CONSTANT(MAXPAGESIZE)) {
_BSS_START_ = .;
*(.bss)
Line 123 ⟶ 121:
 
This script tells the linker to place code from the ".text" section in startup.o at the beginning, starting at logical address <tt>_KERNEL_BASE_</tt>.
This is then followed by page-aligned sections for all ".text", ".data" and ".bss" sections of all the other input files. If your sections are not properly page aligned and separated, GNU ld will generate a "LOAD segment with RWX permissions" warning.
 
Note that different architectures have different page sizes. You can modify the size of "<tt>MAXPAGESIZE</tt>" by adding "<tt>-z max-page-size=0x1000</tt>" switch to the linker. This behavior only exists on GNU ld.
 
Linker symbols are defined holding the start and end address of each section. These symbols have external linkage within the application and are accessible as pointers within the code. Additional information on linker file symbols can be found below.
 
==== KEEP ====
 
The <tt>KEEP</tt> statement within a linker script will instruct the linker to keep the specified section, even if no symbols inside it are referenced. This statement is used within the <tt>SECTIONS</tt> section of the linker script. This becomes relevant when garbage collection is performed at link time, enabled by passing the <tt>--gc-sections</tt> switch to the linker. The <tt>KEEP</tt> statement instructs the linker to use the specified section as a root node when creating a dependency graph, looking for unused sections. Essentially forcing the section to be marked as used.
 
This statement is commonly seen in linker scripts targeting the [[:Category:ARM|ARM]] architecture for placing the interrupt vector table at offset <tt>0x00000000</tt>. Without this directive the table, which might not be referenced explicitly in code, would be pruned out.
 
<pre>
SECTIONS
{
.text :
{
KEEP(*(.text.ivt))
*(.text.boot)
*(.text*)
} > ROM
 
/** ... **/
}
</pre>
 
== Symbols ==
Line 151 ⟶ 171:
An example usage of these symbols in C code can be seen below:
 
<sourcesyntaxhighlight lang="c">
/** Externally linked symbol */
extern uintptr_t _etext;
Line 157 ⟶ 177:
/** Pointer to the binary data at the address stored in the symbol expression. */
uint32_t* item = &_etext;
</syntaxhighlight>
</source>