This chapter contains the following sections:
Overview
Linker Invocation
Detailed Description of Linker Options
Libraries
Library Search Path
Linking with Libraries
Library Member Search Algorithm
Linker Output
Type Checking
Introduction
Recursive Type Checking
Type Checking between Functions
Missing Types
Linker Messages
This section gives a global overview of the process of linking programs for the TriCore and its derivatives. The linker executable name for the TriCore is lktri.
The linker combines relocatable object files, generated by the assembler, into one new relocatable object file (preferred extension .out). This file may be used as input in subsequent linker calls: the linkage process may be incremental. Normally the linker complains about unresolved external references. With incremental linking it is normal to have unresolved references in the output file. Incremental linking must be selected separately.
The linker can read normal object files and libraries of object modules. Modules in a library are included only when they are referenced. At the end of the linkage process the generated object, without unresolved references, will be called: a load module.
The TriCore linker is an overlaying linker. The compiler generates overlayable sections. An overlayable section contains space reservations for variables which, at C level, are local to a function. If functions do not call each other, their local variables can be overlayed in memory. It is a task of the linker to combine function call information into a call graph and to determine upon the structure of this call graph how sections can be overlayed, using the smallest amount of RAM.
Incremental linkage disables overlaying, so the last link phase should not be incremental, even if the incremental phase resolves all externals.
The following diagram shows the input files and output files of the linker:
Figure 9-1: TriCore Linker
The invocation of the TriCore linker is:
When you use a UNIX shell (C-shell, Bourne shell), options containing special characters (such as '( )' ) must be enclosed with "". The invocations for UNIX and PC are the same, except for the -? option in the C-shell:
lktri "-?" or lktri -\?
Options may appear in any order. Options start with a '-'. Only the -lx option is position dependent. Option may be combined: -rM is equal to -r -M. Options that require a filename or a string may be separated by a space or not: -oname is equal to -o name.
file can be any object file (.obj), or object library (.a) or incrementally linker (.out) files. The files are linked in the same order as they appear on the command line.
The linker recognizes the following options:
Option | Description | ||||||||||||||||||
-C | Link case insensitive (default case sensitive) | ||||||||||||||||||
-H or -? | Display invocation syntax | ||||||||||||||||||
-Ldirectory | Additional search path for system libraries | ||||||||||||||||||
-L | Skip system library search | ||||||||||||||||||
-M | Produce a link map (.lnl) | ||||||||||||||||||
-N | Turn off overlaying | ||||||||||||||||||
-O name | Specify basename of the resulting map files | ||||||||||||||||||
-V | Display version header only | ||||||||||||||||||
-WAE | Treat warning messages as errors | ||||||||||||||||||
-c | Produce a separate call graph file (.cal) | ||||||||||||||||||
-dfile |
Read description file information from file, '-' means stdin
-e |
Clean up if erroneous result |
-err |
Redirect error messages to error file (.elk) |
-ffile |
Read command line information from file, | '-' means stdin
-lx |
Search also in system library libx
.a |
-o filename |
Specify name of output file |
-r |
Suppress undefined symbol diagnostics |
-usymbol |
Enter symbol as undefined in the
symbol table |
-v or -t |
Verbose option. Print name of each file as it is processed |
-wn |
Suppress messages above warning level n. | |
Table 9-1: Options summary
With options that can be set from within EDE, you will
find a mouse icon that describes the corresponding action.
-?
-H
Display an explanation of the invocation syntax at stdout.
lktri -H
Select the | Linker/Locator Options... menu item. Disable the Link case sensitive check box in the Linker tab.
-C
Case sensitive
With this option the linker links case insensitive. The default is case sensitive linking.
To switch to case insensitive mode, enter:
lktri -C test.obj
Using the control program:
cctri -Wlk-C test.obj
Select the | Linker/Locator Options... menu item. Enable the Make a separate function call graph file (.cal) check box in the Linker tab.
-c
Generate separate call graph file (.cal).
To create a call graph file (test.cal), enter:
lktri -c test.obj
Using the control program:
cctri -Wlk-c test.obj
Section Linker Output.
Select the | Linker/Locator Options... menu item. Add the option to the Additional options field in the Linker tab.
-d file
A filename to read description file information from. If file is a '-', the information is read from standard input.
Read description file information from file instead of a .dsc file.
To read description file information from file tri.dsc, enter:
lktri -dtri.dsc test.obj
EDE always removes the output files when errors occur.
-e
Remove all link products such as temporary files, the resulting output file and the map file, in case an error occurred.
lktri -e test.obj
In EDE this option is not so useful. If you would use
this option you would not see the error messages in the
Build tab.
-err
The linker redirects error messages to a file with the same basename as the output file and the extension .elk. The default filename is a.elk.
To write errors to the file a.elk instead of stderr, enter:
lktri -err test.obj
To write errors to the file test.elk instead of stderr, enter:
lktri -err test.obj -otest.out
-f file
A filename for command line processing. If file is a '-', the information is read from standard input. You need to provide the EOF code to close stdin (usually Ctrl-Z or Ctrl-D on UNIX).
Use file for command line processing. To get around the limits on the size of the command line, it is possible to use command files. These command files contain the options that could not be part of the real command line. Command files can also be generated on the fly, for example by the make utility.
More than one -f option is allowed.
Some simple rules apply to the format of the command file:
1. It is possible to have multiple arguments on the same line in the command file.
2. To include whitespace in the argument, surround the argument with either single or double quotes.
3. If single or double quotes are to be used inside a quoted argument, we have to go by the following rules:
a. If the embedded quotes are only single or double quotes, use the opposite quote around the argument. Thus, if a argument should contain a double quote, surround the argument with single quotes.
b. If both types of quotes are used, we have to split the argument in such a way that each embedded quote is surrounded by the opposite type of quote.
Example:
"This has a single quote ' embedded"
or
'This has a double quote " embedded'
or
'This has a double quote " and \ a single quote '"' embedded"
4. Some operating systems impose limits on the length of lines within a text file. To circumvent this limitation it is possible to use continuation lines. These lines end with a backslash and newline. In a quoted argument, continuation lines will be appended without stripping any whitespace on the next line. For non-quoted arguments, all whitespace on the next line will be stripped.
Example:
"This is a continuation \ line" -> "This is a continuation line" control(file1(mode,type),\ file2(type)) -> control(file1(mode,type),file2(type))
5. It is possible to nest command line files up to 25 levels.
Suppose the file mycmds contains the following line:
-err test.obj
The command line can now be:
lktri -f mycmds
Select the | Directories... menu item. Add one or more directory paths to the Library Files Path field.
-L[directory]
The name of the directory to search for system libraries.
Add directory to the list of directories that are searched for system libraries. Directories specified with -L are searched before the standard directories specified by the environment variable CTRILIB. If you specify -L without a directory, the environment variable CTRILIB is not searched for system libraries. You can use the -L option more than once to add several directories to the search path for system libraries. The search path is created in the same order as in which the directories are specified on the command line.
lktri -Lc:\ctri\lib test.obj
Select the | Linker/Locator Options... menu item. Enable the Link default C libraries check box in the Linker tab. Optionally, select a floating point library.
-lx
A string to form the name of the system library libx.a.
Search also in system library libx.a, where x is a string. The linker first searches for system libraries in any directories specified with -Ldirectory, then in the standard directories specified with the environment variable CTRILIB, unless the -L option is used without a directory specified.
This option is position dependent (see section
Linking with Libraries).
To search in the system library libc.a after the user object and library are linked, enter:
lktri myobj.obj mylib.a -lc
Select the | Linker/Locator Options... menu item. Enable the Generate a linker listing file (.lnl) check box in the Linker
tab.
-M
Produce a link map (.lnl). If no output filename is specified the default name is a.lnl.
To create the map file a.lnl, enter:
lktri -M test.obj
Section Linker Output,
-O
.
Select the | Linker/Locator Options... menu item. Add the option to the Additional options field in the Linker tab.
-N
Turn off overlaying. This can be useful for debugging.
Select the | Linker/Locator Options... menu item. Add the option to the Additional options field in the Linker tab.
-Oname
The basename to be used for map files.
Use name as the default basename for the resulting map files.
To create the map file test.lnl using the linker, enter:
lktri -M -Otest test.obj
Using the control program:
cctri -Wlk-M -Wlk-Otest test.obj
Section Linker Output,
-M
.
-o filename
An output filename.
a.out
Use filename as output filename of the linker. If this option is omitted, the default filename is a.out.
To create the output file test.out instead of a.out, enter:
lktri test.obj -otest.out
Select the | Linker/Locator Options... menu item. Add the option to the Additional options field in the Linker tab.
-r
Specify incremental linking. No report is made for unresolved symbols, and the function overlaying is disabled.
Section Linker Output.
Select the | Linker/Locator Options... menu item. Add the option to the Additional options field in the Linker tab.
-usymbol
The name of a symbol to undefine.
Enter symbol as undefined in the symbol table. This is useful for linking from a library.
To force symbol main as undefined, enter:
lktri -u main mylib.a
Section Linking with Libraries.
-V
With this option you can display the version header of the linker. This option must be the only argument of lktri. Other options are ignored. The linker exits after displaying the version header.
lktri -V
TASKING TriCore object linker vx.yrz Build nnn Copyright 1996-year Altium BV Serial# 00000000
Select the | Linker/Locator Options... menu item. Enable the Print the name of each file as it is processed check box in the Linker tab.
-v
-t
Verbose option. Print the name of each file as it is processed.
lktri -v test.obj
lktri V008 (1): Embedded environment \ctri\etc\tri.dsc read, relaxed addressing mode check enabled lktri V003 (1): Starting pass 1 lktri V002 (1): File currently in progress: test.obj lktri E208 (0): Found unresolved external(s): _printf - (test.obj) __START - (test.obj) lktri V003 (1): Starting pass 2 lktri V002 (1): File currently in progress: test.obj lktri V005 (1): Removing file .\CD5668a.tld
Using the control program:
cctri -Wlk-v test.obj
Select the | Linker/Locator Options... menu item. Select a warning level from the Suppress warning messages above list box in the Linker tab.
-w level
A warning level between 0 and 9 (inclusive).
-w8
Give a warning level between 0 and 9 (inclusive). All warnings with a level above level are suppressed. The level of a message is printed between parentheses after the warning number. If you do not use the -w option, the default warning level is 8.
To suppresses warnings above level 5, enter:
lktri -w5 test.obj
Using the control program:
cctri -Wlk-w5 test.obj
Section Type Checking.
Select the | Linker/Locator Options... menu item. Enable the Treat warnings as if they were errors check box in the Linker
tab.
-WAE
Treat warning messages as errors. This also affects the return value of the application when only errors occur. A build process will now stop when warnings occur.
lktri -WAE test.obj
There are two kinds of libraries. One of them is the user library. If you make your own library of object modules, this library must be specified as an ordinary filename. The linker will not use any search path to find such a library. The file must have the extension .a. Example:
lktri start.obj -fobj.lnk mylib.a
or, if the library resides in a sub directory:
lktri start.obj -fobj.lnk libs\mylib.a (PC) lktri start.obj -fobj.lnk libs/mylib.a (UNIX)
The other kind of library is the system library. You must define system libraries with the -l option. With the option -lc you specify the system library libc.a.
In EDE you can specify the system libraries in the
Linker tab of the | Linker/Locator Options... menu item.
The linker searches for system library files according to the following algorithm:
1. Use the directories specified with the -Ldirectory options, in a left-to-right order. For example:
PC:
lktri -L..\lib -L\usr\local\lib start.obj -fobj.lnk -lc
UNIX:
lktri -L../lib -L/usr/local/lib start.obj -fobj.lnk -lc
2. If the -L option is not specified without a directory, check if the environment variable CTRILIB exists. If it does, use the contents as a directory specifier for library files. It is possible to specify more than one directory in the environment variable CTRILIB by separating the directories with a directory separator. Valid directory separators are:
Instead of using -L as in the example above, the same directory can be specified using CTRILIB:
PC:
set CTRILIB=..\lib;\usr\local\lib lktri start.obj -fobj.lnk -lc
UNIX:
CTRILIB=../lib:/usr/local/lib export CTRILIB lktri start.obj -fobj.lnk -lc
setenv CTRILIB ../lib:/usr/local/lib lktri start.obj -fobj.lnk -lc
3. Search in the lib/tc1 directory relative to the installation directory of lktri for library files.
PC:
UNIX:
The linker determines run-time which directory the binary is executed from to find this lib directory.
A directory name specified with the -Ldirectory option or in CTRILIB may or may not be terminated with a directory separator, because lktri inserts this separator, if omitted.
If you are linking from libraries, only those objects you need are extracted from the library. This implies that if you invoke the linker like:
lktri mylib.a
nothing is linked and no output file will be produced, because there are no unresolved symbols when the linker searches through mylib.a.
It is possible to force a symbol as undefined with the option -u:
lktri -u main mylib.a (space between -u and main is optional)
In this case the symbol main will be searched for in the library and (if found) the object containing main will be extracted. If this module contains new unresolved symbols, the linker looks again in mylib.a. This process repeats until no new unresolved symbols are found. See also the library member search algorithm in the next section.
The position of the library is important, if you specify:
lktri -lc myobj.obj mylib.a
the linker starts with searching the system library libc.a without unresolved symbols, thus no module will be extracted. After that, the user object and library are linked. When finished, all symbols from the C library remain unresolved. So, the correct invocation is:
lktri myobj.obj mylib.a -lc
All symbols which remain unresolved after linking myobj.obj and mylib.a will be searched for in the system library libc.a. Note that the link order for objects, user libraries and system libraries is the order in which they appear at the command line. Objects are always linked, object modules in libraries are only linked if they are needed.
A library built with artri always contains an index part at the beginning of the library. The linker scans this index while searching for unresolved externals. However, to keep the index as small as possible, only the defined symbols of the library members are recorded in this area.
When the linker finds a symbol that matches an unresolved external, the corresponding object file is extracted from the library and is processed. After processing the object file, the remaining library index is searched. If after a complete search unresolved externals are introduced, the library will be scanned again.
Using the -v option, you can follow the linker actions in respect to the libraries.
The linker produces an IEEE-695 object output file and, if requested, a map file, and/or a call graph file.
The linker output object is still relocatable. It is the task of the locator to determine the absolute addresses of the sections. The linker combines sections with the same name to one (bigger) output section.
The linker produces a map file if the option -M is specified. The name of the map file is the same as the name of the output file. The extension is .lnl. If no output filename is specified the default name is a.lnl. The map file is organized per linked object. Each object is divided in sections and symbols per section. The map file shows the relative position of each linked object from the start of the section.
The generated call graph will also be printed in the map file. The call graph contains an overview of which function calls are present. The call graph also contains information about the stack usage of the call graph. When a function is called, the stack usage before entering the function is written in front of the function name. The total stack usage of the function (including its calls) is written behind the function. The maximum stack usage of a function itself is written below the function. The number indicates the size of the stack usage (in bytes for the TriCore). See also the example.
The call graph can generate a message for the detection of a recursive function call, which is displayed as:
Call graph(s) ============= Call graph 1: function | +-- function1 !! RECURSIVE !!
The command line option -c forces the linker to generate a separate call graph file with a compressed call graph. The filename extension of this file is .cal.
If the linker is used for incremental linking, the -r option must be used. The effect is, that unresolved symbol diagnostics will not be generated, and overlaying is not done. In this case, the output of the linker can be used again as input object. A call graph will always be generated.
A sample map file (.lnl):
Call graph(s) ============= Call graph 1: _start ( 14 ) | +-( 4 )- _exit ( 2 ) | | | +-( 2 ) | +-( 2 )- main ( 12 ) | | | +-( 2 )- puts ( 10 ) | | | | | +-( 2 )- fputc ( 8 ) | | | | | | | +-( 2 )- _flsbuf ( 6 ) | | | | | | | | | +-( 2 )- _iowrite ( 2 ) | | | | | | | | | | | +-( 2 ) | | | | | | | | | +-( 2 )- _write ( 4 ) | | | | | | | | | | | +-( 2 )- _iowrite ( 2 ) | | | | | | | | | | | | | +-( 2 ) | | | | | | | | | | | +-( 2 ) | | | | | | | | | +-( 2 ) | | | | | | | +-( 2 ) | | | | | +-( 2 ) | | | +-( 2 ) | +-( 4 ) Maximum stack usage: 14
Pool offsets ============ Pool #1: zp_ovln (Total of 39 bytes) Pool: zp_ovln off siz puts() 0 6 fputc() 6 7 _flsbuf() 13 12 _write() 25 10 _iowrite() 35 4
Object: cstart.obj ================== Section:abs_65534 ( Start = 0x0 ) Section:.text ( Start = 0x0 ) 0x0000001c E __exit 0x00000000 E __START
Object: hello.obj ================= Section:.text ( Start = 0x1f ) 0x0000001f E _main Section:.string ( Start = 0x0 )
Object: _puts.obj ================= Section:.text ( Start = 0x28 ) 0x00000028 E _puts
Object: _fputc.obj ================== Section:.text ( Start = 0x78 ) 0x00000078 E _fputc
Object: _iob.obj ================ Section:.near_data ( Start = 0x0 ) 0x00000000 E __iob Section:.near_bss ( Start = 0x0 ) 0x00000000 E __ungetc
Object: _flsbuf.obj =================== Section:.text ( Start = 0x0102 ) 0x00000102 E __flsbuf
Object: _iowrite.obj ==================== Section:.text ( Start = 0x0314 ) 0x00000314 E __iowrite
Object: _write.obj ================== Section:.text ( Start = 0x0318 ) 0x00000318 E __write
The addresses in the map file are offsets relative to the start of the section in the output file. For instance, section .text of the object module hello.obj starts at offset 0x1f from the output .text section. Function main also starts at offset 0x1f from the start of the resulting .text section. The E after the address indicates the label is external.
When we take the following part of the call graph,
+----- _write ( 4 ) | +-( 2 )- _iowrite ( 2 ) | | | +-( 2 ) | +-( 2 )
we can see from the indentation in the structure of the tree that function _write calls function _iowrite. The total stack usage of function _write (including its calls) is given behind the function name:
_write ( 4 )
To determine the total stack usage we take the maximum of the following:
1. local usage before calling a function (the first value), added to the total usage of that function (the last value):
+-( 2 )- _iowrite ( 2 )
2. the usage of the function itself:
| +-( 2 )
By default the compiler and the assembler generate high-level type information. Unless you disable generation of type information (-gn), each object contains type information of high-level types. The linker compares this type information and warns you if there are conflicts. The linker distinguishes four types of conflicts:
1. Type not completely specified (W109). Occurs if you do not specify the depth of an array, or if you do not specify arguments in one of the function prototypes. The linker does not report this type of conflicts unless you specify a warning level 9 (-w9), default is warning level 8.
2. Compatible types, different definitions (W110). Occurs if for instance you link a long with an int. The TriCore takes both as 32 bits, so there will not be a problem. However, the code is not portable. Also structures or types with different names produce this warning. The warning level for this message is 8, so you can switch off this kind of message by specifying warning level 7 or less (-w7).
3. Signed/unsigned conflict (W111). If you link a signed int with an unsigned int, you get this message. In many cases there will be no problem, but the unsigned version can hold a bigger integer. The warning level of this warning is 6 and can be suppressed by specifying a warning level of 5 or less (-w5).
4. All other type conflicts (W112). If you get warning 112, there is probably a more serious type conflict. This can be a conflict in a function return type, a conflict in length between two built in types (short/long) or a completely different type. This warning has a level of 4, and can be switched off with warning level 3 or less (-w3).
The linker compares type recursively. For instance, the type of foo:
struct s1 { struct s2 *s2_ptr; }; struct s2 { int count; } sample; struct s1 foo = { &sample };
If you compile this source and link it with another compiled source with only struct s2 different:
struct s1 { struct s2 *s2_ptr; }; struct s2 { short count; }; extern struct s1 foo;
message W112 (type conflict) will be generated. Although struct s1 is the same in both cases, this is a real type conflict: For instance, the code "foo.s2_ptr->count++" produces different code in both objects.
If you have several conflicts in one symbol, the linker reports only the one with the lowest warning level. (The most serious one.)
If you use K&R style functions and disabled type checking for these functions with the -K option of ctri, it is not possible to check the type of the arguments and the number of arguments. Return types are 'int' if not specified. Prototypes are only needed if a function has a non-integer return type:
test2( par ) int par; { test1( par ); return test3( 1, 2 ); }
In this case, test1 (defined in another source) has a return type void, and test3 has a return type int, which is the default. At the default warning level, the linker does not report any conflict. If you should specify warning level 9 (-w9), the linker reports a 'not completely specified' type, because the linker is not able to check the arguments. Conflicts in return types cause real type conflicts at warning level 4.
If the source is ANSI style (which is recommended), the linker checks the types of all parameters, and the number of parameters. In this case the source of the example above looks like:
void test1( int ); /* ANSI style prototypes */ int test3( int, int ); test2( int par ) /* ANSI style function definition*/ { test1( par ); return test3( 1, 2 ); }
Another source, containing the definition of test1 and test3 may look like:
void test1( int one ) { /* ** code for function test1 */ . . . }
int test3( int one, int two ) { /* ** Code for function test3 */ . . . }
Prototypes are only needed for functions which are referenced before they are defined within one source. However, it is a good practice to include a prototype file with prototypes of all the functions in a file. If you do so, type checking for functions is done by the compiler. Nevertheless, if you do not compile all sources after you have changed the prototype file, the linker will report the type conflict.
It is possible to add ANSI style prototypes to K&R style C-code. In this case full type checking for functions becomes available. To accomplish this, make a new header file with all prototypes for all functions in your application. Include this file in each source, or tell the compiler to include it for you by means of the option -H:
cctri -c -Hproto.h *.c
In C you are allowed to define pointers to unspecified objects. The linker is not able to check such types. For instance:
struct s1 { struct s2 *s2_ptr; }; struct s1 foo;
The structure s2 is not specified. Because the linker is not able to check whether struct s2 is the same in all sources, a warning at level 9 will be generated:
It is possible that the struct s2 is known in an other source. If this source uses variable foo, a second message is generated, reporting a level 9 type conflict:
Because the type definition is not complete, the first warning reports that the linker cannot check the type, although this is allowed in C. This message is given once for each object for each incomplete type. The second warning reports a difference in types, an incomplete type versus a complete type. Note that al these warnings are only generated if you specify warning level 9 (-w9).
There are four kinds of messages: fatal messages, error messages, warning messages and verbose messages. Fatal messages are generated if the linker is not able to perform its task due to the severity of the error. In those situations, the exit code will be 2. Error messages will be reported if an error occurred which is not fatal for the linker. However, the output of the linker is not usable. The exit code in case of one or more error messages will be 1. Warning messages are generated if the linker detects potential errors, but the linker is unable to judge those errors. The exit code will be 0 in this case, indicating a usable .out file. Of course, if the linker reports no messages at all, the exit code is 0 also.
Each linker message has a built-in warning level. With option -wx it is possible to suppress messages with a warning level above x.
Verbose messages are generated only if the verbose option (-v) is on. They report the progress of the link process.
Linker messages have the following layout:
TASKING TriCore object linker vx.yrz Build nnn Copyright 1996-year Altium BV Serial# 00000000 lktri W112 (4) a.obj: Type conflict for symbol <f> in b.obj
The first line shows the banner of the TriCore linker. The second line reports a type conflict in the file a.obj. Apparently there is a conflicting type definition of the function f in module b.obj. The number between parentheses after the warning number, '(4)', shows the warning level.
There are four message groups:
1. Fatal (always level 0):
- Write error
- Out of memory
- Illegal input object
2. Error (always level 0):
- Unresolved symbols (and no incremental linking)
- Can't open input file
- Illegal recursive use of an non reentrant function
3. Warning (levels from 1 to 9):
- Type conflict between two symbols
- Illegal option (Ignored)
- No system library search path, and system library requested
4. Verbose (level not relevant, only given with option -v):
- Extracting files from a library
- Current file/library name
- Pass one or pass two
- Rescanning library for new unresolved symbols
- Cleaning up temp files
- warning level