===== Linker Script ===== This page introduces the concepts of what a linker script is and how it is written. For a much better (in depth) documentation about Linker Scripts go to [[http://www.math.utah.edu/docs/info/ld_3.html|Linker Script Documentation]]. This document is based on the following document: [[http://www.emprog.com/support/documentation/thunderbench-Linker-Script-guide.pdf]] ==== What and Why ==== The main purpose of the linker script is to describe how the sections in the input files should be mapped into the output file, and to control the memory layout of the output file. Most linker scripts do nothing more than this. However, when necessary, the linker script can also direct the linker to perform many other operations, using the commands described below. The linker always uses a linker script. If you do not supply one yourself, the linker will use a default script that is compiled into the linker executable. You may supply your own linker script by using the ‘-T’ command line option. When you do this, your linker script will replace the default linker script. You may also use linker scripts implicitly by naming them as input files to the linker, as though they were files to be linked. ==== Simple Linker Script Example ==== Many linker scripts are fairly simple. The simplest possible linker script has just one command: ‘SECTIONS’. You use the ‘SECTIONS’ command to describe the memory layout of the output file. The ‘SECTIONS’ command is a powerful command. Here we will describe a simple use of it. Let’s assume your program consists only of code, initialized data, and uninitialized data. These will be in the ‘.text’, ‘.data’, and ‘.bss’ sections, respectively. Let’s assume further that these are the only sections which appear in your input files. For this example, let’s say that the code should be loaded at address 0x10000, and that the data should start at address 0x8000000. Here is a linker script which will do that: SECTIONS { . = 0x10000; .text : { *(.text) } . = 0x8000000; .data : { *(.data) } .bss : { *(.bss) } } You write the ‘SECTIONS’ command as the keyword ‘SECTIONS’, followed by a series of symbol assignments and output section descriptions enclosed in curly braces. The first line inside the ‘SECTIONS’ command of the above example sets the value of the special symbol ‘.’, which is the location counter. If you do not specify the address of an output section in some other way, the address is set from the current value of the location counter. The location counter is then incremented by the size of the output section. At the start of the ‘SECTIONS’ command, the location counter has the value ‘0’. The second line defines an output section, ‘.text’. The colon is required syntax which may be ignored for now. Within the curly braces after the output section name, you list the names of the input sections which should be placed into this output section. The ‘*’ is a wildcard which matches any file name. The expression ‘*(.text)’ means all ‘.text’ input sections in all input files. Since the location counter is ‘0x10000’ when the output section ‘.text’ is defined, the linker will set the address of the ‘.text’ section in the output file to be ‘0x10000’. The remaining lines define the ‘.data’ and ‘.bss’ sections in the output file. The linker will place the ‘.data’ output section at address ‘0x8000000’. After the linker places the ‘.data’ output section, the value of the location counter will be ‘0x8000000’ plus the size of the ‘.data’ output section. The effect is that the linker will place the ‘.bss’ output section immediately after the ‘.data’ output section in memory. The linker will ensure that each output section has the required alignment, by increasing the location counter if necessary. In this example, the specified addresses for the ‘.text’ and ‘.data’ sections will probably satisfy any alignment constraints, but the linker may have to create a small gap between the ‘.data’ and ‘.bss’ sections. That’s it! That’s a simple and complete linker script. ==== Setting an Entry Point ==== The first instruction to execute in a program is called the entry point. You can use the ENTRY linker script command to set the entry point. The argument is a symbol name: ENTRY(symbol) There are several ways to set the entry point. The linker will set the entry point by trying each of the following methods in order, and stopping when one of them succeeds: * the ‘-e’ entry command-line option; * the ENTRY(symbol) command in a linker script; * the value of the symbol start, if defined; * the address of the first byte of the ‘.text’ section, if present; * The address 0. ==== Manual Alignment ==== ALIGN(exp)is a command which returns the result of the current location counter (.) aligned to the next exp boundary. exp must be an expression whose value is a power of two. ALIGN doesn't change the value of the location counter - it just does arithmetic on it. In the following case, it simply defines the value of a variable (.). . = ALIGN(4);