10.4.7. Run-Time Environment Options

The options listed in the subsections below control how the linker manages the run-time environment. See Run-Time Initialization for more about the run-time environment.

On the tiarmclang command-line they should be passed to the linker using the -Wl or -Xlinker option as described in Passing Options to the Linker.

10.4.7.1. Option Summary

--arg_size (--args)

Allocates memory to be used by the loader to pass arguments. See Allocate Memory for Use by the Loader to Pass Arguments (–arg_size Option).

--cinit_hold_wdt={on|off}

Hold (on) or do not hold (off) watchdog timer during cinit auto-initialization. See Initialization of Cinit and Watchdog Timer Hold.

--fill_value (-f)

Sets default fill values for holes within output sections; fill_value is a 32-bit constant. See Set Default Fill Value (--fill_value Option).

--minimize_trampolines

Places sections to minimize number of far trampolines required. See Minimizing the Number of Trampolines Required (--minimize_trampolines Option).

--ram_model (-cr)

Initializes variables at load time. See C Language Options (--ram_model and --rom_model Options).

--rom_model (-c)

Autoinitializes variables at run time. See C Language Options (--ram_model and --rom_model Options).

--trampolines

Generates far call trampolines; on by default. See Generate Far Call Trampolines (--trampolines Option).

--trampoline_min_spacing

When trampoline reservations are spaced more closely than the specified limit, tries to make them adjacent. See Making Trampoline Reservations Adjacent (--trampoline_min_spacing Option).

10.4.7.2. Allocate Memory for Use by the Loader to Pass Arguments (–arg_size Option)

The --arg_size option instructs the linker to allocate memory to be used by the loader to pass arguments from the command line of the loader to the program. The syntax of the --arg_size option is:

--arg_size = size

The size is the number of bytes to be allocated in target memory for command-line arguments.

By default, the linker creates the __c_args__ symbol and sets it to -1. When you specify --arg_size = size, the following occur:

  • The linker creates an uninitialized section named .args of size bytes.

  • The __c_args__ symbol contains the address of the .args section.

The loader and the target boot code use the .args section and the __c_args__ symbol to determine whether and how to pass arguments from the host to the target program. See Arguments to main for more information.

10.4.7.3. Set Default Fill Value (--fill_value Option)

The --fill_value option fills the holes formed within output sections. The syntax for the option is:

--fill_value=value

The argument value is a 32-bit constant (up to eight hexadecimal digits). If you do not use --fill_value, the linker uses 0 as the default fill value.

This example fills holes with the hexadecimal value ABCDABCD:

tiarmclang -Wl,--fill_value=0xABCDABCD file1.c.o file2.c.o

10.4.7.4. C Language Options (--ram_model and --rom_model Options)

The --ram_model and --rom_model options cause the linker to use linking conventions that are required by the C compiler. Both options inform the linker that the program is a C program and requires a boot routine.

  • The --ram_model option tells the linker to initialize variables at load time.

  • The --rom_model option tells the linker to autoinitialize variables at run time.

No default startup model is specified to the linker when the tiarmclang compiler runs the linker. Therefore, either the --rom_model (-c) or --ram_model (-cr) option must be passed to the linker on the tiarmclang command line using the -Wl or -Xlinker option or in the linker command file. For example:

tiarmclang -mcpu=cortex-m4 hello.c -o hello.out -Wl,-c,-llnk.cmd,-mhello.map

If neither the -c or -cr option is specified to tiarmclang when running the linker, the linker expects an entry point for the linked application to be identified (using the -e=<symbol> linker option). If -c or -cr is specified, then the linker assumes that the program entry point is _c_int00, which performs any needed auto-initialization and system setup, then calls the user’s main() function.

For more information, see Linking C/C++ Code, Autoinitializing Variables at Run Time (--rom_model), and Initializing Variables at Load Time (--ram_model).

10.4.7.5. Generate Far Call Trampolines (--trampolines Option)

The Arm device has PC-relative call and PC-relative branch instructions whose range is smaller than the entire address space. When these instructions are used, the destination address must be near enough to the instruction that the difference between the call and the destination fits in the available encoding bits. If the called function is too far away from the calling function, the linker generates an error or generates a trampoline, depending on the setting of the --trampolines option (on or off).

The alternative to a PC-relative call is an absolute call, which is often implemented as an indirect call: load the called address into a register, and call that register. This is often undesirable because it takes more instructions (speed- and size-wise) and requires an extra register to contain the address.

By default, the compiler generates calls that may require a trampoline if the destination is too far away. On some architectures, this type of call is called a “near call.”

The --trampolines option allows you to control the generation of trampolines. When set to “on”, this option causes the linker to generate a trampoline code section for each call that is linked out-of-range of its called destination. The trampoline code section contains a sequence of instructions that performs a transparent long branch to the original called address. Each calling instruction that is out-of-range from the called function is redirected to the trampoline.

The syntax for this option is:

--trampolines[=on|off]

The default setting is on. For Arm, trampolines are turned on by default.

For example, in a section of C code the bar function calls the foo function. The compiler generates this code for the function:

bar:
       ...
      call    foo     ; call the function "foo"
      ...

If the foo function is placed out-of-range from the call to foo that is inside of bar, then with --trampolines the linker changes the original call to foo into a call to foo_trampoline as shown:

bar:
      ...
      call    foo_trampoline  ; call a trampoline for foo
      ...

The above code generates a trampoline code section called foo_trampoline, which contains code that executes a long branch to the original called function, foo. For example:

foo_trampoline:
      branch_long     foo

Trampolines can be shared among calls to the same called function. The only requirement is that all calls to the called function be linked near the called function’s trampoline.

When the linker produces a map file (the --map_file option) and it has produced one or more trampolines, then the map file will contain statistics about what trampolines were generated to reach which functions. A list of calls for each trampoline is also provided in the map file.

Note

The Linker Assumes R13 Contains the Stack Pointer Assembly language programmers must be aware that the linker assumes R13 contains the stack pointer. The linker must save and restore values on the stack in trampoline code that it generates. If you do not use R13 as the stack pointer, you should use the linker option that disables trampolines, --trampolines=off. Otherwise, trampolines could corrupt memory and overwrite register values.

10.4.7.5.1. Advantages and Disadvantages of Using Trampolines

The advantage of using trampolines is that you can treat all calls as near calls, which are faster and more efficient. You will only need to modify those calls that don’t reach. In addition, there is little need to consider the relative placement of functions that call each other. Cases where calls must go through a trampoline are less common than near calls.

While generating far call trampolines provides a more straightforward solution, trampolines have the disadvantage that they are somewhat slower than directly calling a function. They require both a call and a branch. Additionally, while inline code could be tailored to the environment of the call, trampolines are generated in a more general manner, and may be slightly less efficient than inline code.

An alternative method to creating a trampoline code section for a call that cannot reach its called function is to actually modify the source code for the call. In some cases this can be done without affecting the size of the code. However, in general, this approach is extremely difficult, especially when the size of the code is affected by the transformation.

10.4.7.5.2. Minimizing the Number of Trampolines Required (--minimize_trampolines Option)

The --minimize_trampolines option attempts to place sections so as to minimize the number of far call trampolines required, possibly at the expense of optimal memory packing. The syntax is:

--minimize_trampolines=postorder

The argument selects a heuristic to use. The postorder heuristic attempts to place functions before their callers, so that the PC-relative offset to the callee is known when the caller is placed. By placing the callee first, its address is known when the caller is placed so the linker can definitively know if a trampoline is required. The argument selects a heuristic to use. The postorder heuristic attempts to place functions before their callers, so that the PC-relative offset to the callee is known when the caller is placed. By placing the callee first, its address is known when the caller is placed so the linker can definitively know if a trampoline is required.

10.4.7.5.3. Making Trampoline Reservations Adjacent (--trampoline_min_spacing Option)

When a call is placed and the callee’s address is unknown, the linker must provisionally reserve space for a far call trampoline in case the callee turns out to be too far away. Even if the callee ends up being close enough, the trampoline reservation can interfere with optimal placement for very large code sections.

When trampoline reservations are spaced more closely than the specified limit, use the --trampoline_min_spacing option to try to make them adjacent. The syntax is:

--trampoline_min_spacing=size

A higher value minimizes fragmentation, but may result in more trampolines. A lower value may reduce trampolines, at the expense of fragmentation and linker running time. Specifying 0 for this option disables coalescing. The default is 16K.

10.4.7.5.4. Carrying Trampolines From Load Space to Run Space

It is sometimes useful to load code in one location in memory and run it in another. The linker provides the capability to specify separate load and run allocations for a section. The burden of actually copying the code from the load space to the run space is left to you.

A copy function must be executed before the real function can be executed in its run space. To facilitate this copy function, the assembler provides the .label directive, which allows you to define a load-time address. These load-time addresses can then be used to determine the start address and size of the code to be copied. However, this mechanism will not work if the code contains a call that requires a trampoline to reach its called function. This is because the trampoline code is generated at link time, after the load-time addresses associated with the .label directive have been defined. If the linker detects the definition of a .label symbol in an input section that contains a trampoline call, then a warning is generated.

To solve this problem, you can use the START(), END(), and SIZE() operators (see Address and Dimension Operators. These operators allow you to define symbols to represent the load-time start address and size inside the linker command file. These symbols can be referenced by the copy code, and their values are not resolved until link time, after the trampoline sections have been allocated.

Here is an example of how you could use the START() and SIZE() operators in association with an output section to copy the trampoline code section along with the code containing the calls that need trampolines:

SECTIONS
{   .foo : load = ROM, run = RAM, start(foo_start), size(foo_size)
           { x.o(.text) }

    .text: {} > ROM

    .far : { --library=rts.lib(.text) } > FAR_MEM
}

A function in x.c.o contains an run-time-support call. The run-time-support library is placed in far memory and so the call is out-of-range. A trampoline section will be added to the .foo output section by the linker. The copy code can refer to the symbols foo_start and foo_size as parameters for the load start address and size of the entire .foo output section. This allows the copy code to copy the trampoline section along with the original x.c.o code in .text from its load space to its run space.

See Using Linker Symbols in C/C++ Applications for information about referring to linker symbols in C/C++ code.