| • Entry Point: | Setting the entry point | |
| • File Commands: | Commands dealing with files | |
| • Format Commands: | Commands dealing with object file formats | |
| • REGION_ALIAS: | Assign alias names to memory regions | |
| • Miscellaneous Commands: | Other linker script commands | |
1 Setting the Entry Point
The first instruction to execute in a program is called the entry point. You can use theENTRY linker script command to set the entry point. The argument is a symbol name:ENTRY(symbol)
- the ‘-e’ entry command-line option;
- the
ENTRY(symbol)command in a linker script; - the value of a target-specific symbol, if it is defined; For many targets this is
start, but PE- and BeOS-based systems for example check a list of possible entry symbols, matching the first one found. - the address of the first byte of the ‘.text’ section, if present;
- The address
0.
2 Commands Dealing with Files
Several linker script commands deal with files.
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
INCLUDEup to 10 levels deep.
You can placeINCLUDEdirectives at the top level, inMEMORYorSECTIONScommands, or in output section descriptions. INPUT(file, file, …)INPUT(file file …)- The
INPUTcommand directs the linker to include the named files in the link, as though they were named on the command line.
For example, if you always want to include subr.o any time you do a link, but you can’t be bothered to put it on every link command line, then you can put ‘INPUT (subr.o)’ in your linker script.
In fact, if you like, you can list all of your input files in the linker script, and then invoke the linker with nothing but a ‘-T’ option.
In case a sysroot prefix is configured, and the filename starts with the ‘/’ character, and the script being processed was located inside the sysroot prefix, the filename will be looked for in the sysroot prefix. Otherwise, the linker will try to open the file in the current directory. If it is not found, the linker will search through the archive library search path. The sysroot prefix can also be forced by specifying=as the first character in the filename path, or prefixing the filename path with$SYSROOT. See also the description of ‘-L’ in Command-line Options.
If you use ‘INPUT (-lfile)’,ldwill transform the name tolibfile.a, as with the command-line argument ‘-l’.
When you use theINPUTcommand in an implicit linker script, the files will be included in the link at the point at which the linker script file is included. This can affect archive searching. GROUP(file, file, …)GROUP(file file …)- The
GROUPcommand is likeINPUT, except that the named files should all be archives, and they are searched repeatedly until no new undefined references are created. See the description of ‘-(’ in Command-line Options. AS_NEEDED(file, file, …)AS_NEEDED(file file …)- This construct can appear only inside of the
INPUTorGROUPcommands, among other filenames. The files listed will be handled as if they appear directly in theINPUTorGROUPcommands, with the exception of ELF shared libraries, that will be added only when they are actually needed. This construct essentially enables --as-needed option for all the files listed inside of it and restores previous --as-needed resp. --no-as-needed setting afterwards. OUTPUT(filename)- The
OUTPUTcommand names the output file. UsingOUTPUT(filename)in the linker script is exactly like using ‘-o filename’ on the command line (see Command Line Options). If both are used, the command-line option takes precedence.
You can use theOUTPUTcommand to define a default name for the output file other than the usual default of a.out. SEARCH_DIR(path)- The
SEARCH_DIRcommand adds path to the list of paths whereldlooks for archive libraries. UsingSEARCH_DIR(path)is exactly like using ‘-L path’ on the command line (see Command-line Options). If both are used, then the linker will search both paths. Paths specified using the command-line option are searched first. STARTUP(filename)- The
STARTUPcommand is just like theINPUTcommand, except that filename will become the first input file to be linked, as though it were specified first on the command line. This may be useful when using a system in which the entry point is always the start of the first file.
3 Commands Dealing with Object File Formats
A couple of linker script commands deal with object file formats.
OUTPUT_FORMAT(bfdname)OUTPUT_FORMAT(default, big, little)- The
OUTPUT_FORMATcommand names the BFD format to use for the output file (see BFD). UsingOUTPUT_FORMAT(bfdname)is exactly like using ‘--oformat bfdname’ on the command line (see Command-line Options). If both are used, the command line option takes precedence.
You can useOUTPUT_FORMATwith three arguments to use different formats based on the ‘-EB’ and ‘-EL’ command-line options. This permits the linker script to set the output format based on the desired endianness.
If neither ‘-EB’ nor ‘-EL’ are used, then the output format will be the first argument, default. If ‘-EB’ is used, the output format will be the second argument, big. If ‘-EL’ is used, the output format will be the third argument, little.
For example, the default linker script for the MIPS ELF target uses this command:
This says that the default format for the output file is ‘elf32-bigmips’, but if the user uses the ‘-EL’ command-line option, the output file will be created in the ‘elf32-littlemips’ format.OUTPUT_FORMAT(elf32-bigmips, elf32-bigmips, elf32-littlemips)
TARGET(bfdname)- The
TARGETcommand names the BFD format to use when reading input files. It affects subsequentINPUTandGROUPcommands. This command is like using ‘-b bfdname’ on the command line (see Command-line Options). If theTARGETcommand is used butOUTPUT_FORMATis not, then the lastTARGETcommand is also used to set the format for the output file. See BFD.
4 Assign alias names to memory regions
Alias names can be added to existing memory regions created with the MEMORY command. Each name corresponds to at most one memory region.
The
Suppose we have an application for embedded systems which come with various memory storage devices. All have a general purpose, volatile memory
The notation
The base linker script that deals with the output sections follows. It includes the system dependent
Now we need three different
REGION_ALIAS(alias, region)
REGION_ALIAS function creates an alias name alias for the memory region region. This allows a flexible mapping of output sections to memory regions. An example follows.Suppose we have an application for embedded systems which come with various memory storage devices. All have a general purpose, volatile memory
RAM that allows code execution or data storage. Some may have a read-only, non-volatile memory ROM that allows code execution and read-only data access. The last variant is a read-only, non-volatile memory ROM2 with read-only data access and no code execution capability. We have four output sections:.textprogram code;.rodataread-only data;.dataread-write initialized data;.bssread-write zero initialized data.
A, B and C:| Section | Variant A | Variant B | Variant C |
| .text | RAM | ROM | ROM |
| .rodata | RAM | ROM | ROM2 |
| .data | RAM | RAM/ROM | RAM/ROM2 |
| .bss | RAM | RAM | RAM |
RAM/ROM or RAM/ROM2 means that this section is loaded into region ROM or ROM2 respectively. Please note that the load address of the .data section starts in all three variants at the end of the .rodata section.The base linker script that deals with the output sections follows. It includes the system dependent
linkcmds.memory file that describes the memory layout:INCLUDE linkcmds.memory
SECTIONS
{
.text :
{
*(.text)
} > REGION_TEXT
.rodata :
{
*(.rodata)
rodata_end = .;
} > REGION_RODATA
.data : AT (rodata_end)
{
data_start = .;
*(.data)
} > REGION_DATA
data_size = SIZEOF(.data);
data_load_start = LOADADDR(.data);
.bss :
{
*(.bss)
} > REGION_BSS
}
linkcmds.memory files to define memory regions and alias names. The content of linkcmds.memory for the three variants A, B and C:A- Here everything goes into the
RAM.
MEMORY { RAM : ORIGIN = 0, LENGTH = 4M } REGION_ALIAS("REGION_TEXT", RAM); REGION_ALIAS("REGION_RODATA", RAM); REGION_ALIAS("REGION_DATA", RAM); REGION_ALIAS("REGION_BSS", RAM); B- Program code and read-only data go into the
ROM. Read-write data goes into theRAM. An image of the initialized data is loaded into theROMand will be copied during system start into theRAM.
MEMORY { ROM : ORIGIN = 0, LENGTH = 3M RAM : ORIGIN = 0x10000000, LENGTH = 1M } REGION_ALIAS("REGION_TEXT", ROM); REGION_ALIAS("REGION_RODATA", ROM); REGION_ALIAS("REGION_DATA", RAM); REGION_ALIAS("REGION_BSS", RAM); C- Program code goes into the
ROM. Read-only data goes into theROM2. Read-write data goes into theRAM. An image of the initialized data is loaded into theROM2and will be copied during system start into theRAM.
MEMORY { ROM : ORIGIN = 0, LENGTH = 2M ROM2 : ORIGIN = 0x10000000, LENGTH = 1M RAM : ORIGIN = 0x20000000, LENGTH = 1M } REGION_ALIAS("REGION_TEXT", ROM); REGION_ALIAS("REGION_RODATA", ROM2); REGION_ALIAS("REGION_DATA", RAM); REGION_ALIAS("REGION_BSS", RAM);
.data section from ROM or ROM2 into the RAM if necessary:#include <string.h>
extern char data_start [];
extern char data_size [];
extern char data_load_start [];
void copy_data(void)
{
if (data_start != data_load_start)
{
memcpy(data_start, data_load_start, (size_t) data_size);
}
}
5 Other Linker Script Commands
There are a few other linker scripts commands.
ASSERT(exp, message)- Ensure that exp is non-zero. If it is zero, then exit the linker with an error code, and print message.
Note that assertions are checked before the final stages of linking take place. This means that expressions involving symbols PROVIDEd inside section definitions will fail if the user has not set values for those symbols. The only exception to this rule is PROVIDEd symbols that just reference dot. Thus an assertion like this:
will fail if.stack : { PROVIDE (__stack = .); PROVIDE (__stack_size = 0x100); ASSERT ((__stack > (_end + __stack_size)), "Error: No room left for the stack"); }__stack_sizeis not defined elsewhere. Symbols PROVIDEd outside of section definitions are evaluated earlier, so they can be used inside ASSERTions. Thus:
will work.PROVIDE (__stack_size = 0x100); .stack : { PROVIDE (__stack = .); ASSERT ((__stack > (_end + __stack_size)), "Error: No room left for the stack"); } EXTERN(symbol symbol …)- Force symbol to be entered in the output file as an undefined symbol. Doing this may, for example, trigger linking of additional modules from standard libraries. You may list several symbols for each
EXTERN, and you may useEXTERNmultiple times. This command has the same effect as the ‘-u’ command-line option. FORCE_COMMON_ALLOCATION- This command has the same effect as the ‘-d’ command-line option: to make
ldassign space to common symbols even if a relocatable output file is specified (‘-r’). INHIBIT_COMMON_ALLOCATION- This command has the same effect as the ‘--no-define-common’ command-line option: to make
ldomit the assignment of addresses to common symbols even for a non-relocatable output file. FORCE_GROUP_ALLOCATION- This command has the same effect as the ‘--force-group-allocation’ command-line option: to make
ldplace section group members like normal input sections, and to delete the section groups even if a relocatable output file is specified (‘-r’). INSERT [ AFTER | BEFORE ] output_section- This command is typically used in a script specified by ‘-T’ to augment the default
SECTIONSwith, for example, overlays. It inserts all prior linker script statements after (or before) output_section, and also causes ‘-T’ to not override the default linker script. The exact insertion point is as for orphan sections. See Location Counter. The insertion happens after the linker has mapped input sections to output sections. Prior to the insertion, since ‘-T’ scripts are parsed before the default linker script, statements in the ‘-T’ script occur before the default linker script statements in the internal linker representation of the script. In particular, input section assignments will be made to ‘-T’ output sections before those in the default script. Here is an example of how a ‘-T’ script usingINSERTmight look:
SECTIONS { OVERLAY : { .ov1 { ov1*(.text) } .ov2 { ov2*(.text) } } } INSERT AFTER .text; NOCROSSREFS(section section …)- This command may be used to tell
ldto issue an error about any references among certain output sections.
In certain types of programs, particularly on embedded systems when using overlays, when one section is loaded into memory, another section will not be. Any direct references between the two sections would be errors. For example, it would be an error if code in one section called a function defined in the other section.
TheNOCROSSREFScommand takes a list of output section names. Iflddetects any cross references between the sections, it reports an error and returns a non-zero exit status. Note that theNOCROSSREFScommand uses output section names, not input section names. NOCROSSREFS_TO(tosection fromsection …)- This command may be used to tell
ldto issue an error about any references to one section from a list of other sections.
TheNOCROSSREFScommand is useful when ensuring that two or more output sections are entirely independent but there are situations where a one-way dependency is needed. For example, in a multi-core application there may be shared code that can be called from each core but for safety must never call back.
TheNOCROSSREFS_TOcommand takes a list of output section names. The first section can not be referenced from any of the other sections. Iflddetects any references to the first section from any of the other sections, it reports an error and returns a non-zero exit status. Note that theNOCROSSREFS_TOcommand uses output section names, not input section names. OUTPUT_ARCH(bfdarch)- Specify a particular output machine architecture. The argument is one of the names used by the BFD library (see BFD). You can see the architecture of an object file by using the
objdumpprogram with the ‘-f’ option. LD_FEATURE(string)- This command may be used to modify
ldbehavior. If string is"SANE_EXPR"then absolute symbols and numbers in a script are simply treated as numbers everywhere. See Expression Section.

No comments:
Post a Comment