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 XA and its derivatives.
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 XA linker is an overlaying linker. The compiler generates overlayable sections for functions that pass parameters via direct addressable memory. Based upon the call information supplied by the compiler, the linker builds a call graph, and deduces from the structure of this call graph how sections can be overlayed, using the smallest amount of RAM. The best theoretical possible solution is created by the linker.
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: Linker
The invocation of the 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:
lkxa "-?" or lkxa -\?
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 | ||||||||||||||||||||
-? or -H | Display invocation syntax and options | ||||||||||||||||||||
-C | Link case insensitive (default case sensitive) | ||||||||||||||||||||
-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 | ||||||||||||||||||||
-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 |
Specify incremental linking |
-s |
Produce a Safer C report file (.sfc) |
-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.
lkxa -H
Select the EDE | Linker/Locator Options... menu item. Disable the Link case sensitive check box in the Linker tab.
-C
Case sensitive
With this option lkxa links case insensitive. The default is case sensitive linking.
To switch to case insensitive mode, enter:
lkxa -C test.obj
Using the control program:
ccxa -Wlk-C test.obj
Select the EDE | 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:
lkxa -c test.obj
Using the control program:
ccxa -Wlk-c test.obj
Section Linker Output.
Select the EDE | 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 dscxa, enter:
lkxa -ddscxa test.obj
Using the control program:
ccxa -Wlk-ddscxa test.obj
EDE always calls the linker with the -e
option.
-e
Remove all link products such as temporary files, the resulting output file and the map file, in case an error occurred.
lkxa -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:
lkxa -err test.obj
To write errors to the file test.elk instead of stderr, enter:
lkxa -err test.obj -otest.out
Select the EDE | Linker/Locator Options... menu item. Add the option to the Additional options field in the Linker tab.
-f file
A filename for command line processing. The filename "-" may be used to denote standard input.
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:
lkxa -f mycmds
Select the EDE | 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 CXALIB. If you specify -L without a directory, the environment variable CXALIB is not searched for system libraries. You may 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.
lkxa -Lc:\cxa\lib\xa test.obj
Select the EDE | Linker/Locator Options... menu item. Add the option to the Additional options field in the Linker tab.
-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 CXALIB, 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 libcs.a after the user object and library are linked, enter:
lkxa myobj.obj mylib.a -lcs
Select the EDE | 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:
lkxa -M test.obj
Section Linker Output,
-O
.
Select the EDE | 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 EDE | 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:
lkxa -M -Otest test.obj
Using the control program:
ccxa -Wlk-M -Wlk-Otest test.obj
Section Linker Output,
-M
.
Select the EDE | Linker/Locator Options... menu item. Add the option to the Additional options field in the Linker tab.
-ofilename
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:
lkxa test.obj -otest.out
Select the EDE | 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 EDE | Safer C Compiler Options| Project Options... menu item. Enable the
Produce a Safer C report check box in the Safer C tab. The check box is available when Safer C is enabled.
-s
If you specify the -s option, a report is generated specifying the Safer C checks used during C compiliation for each module used during linking. This is done in a cross reference table.
A separate list of modules without Safer C checks is printed below the table. The report filename is the output filename with extension .sfc.
The linker passes Safer C settings to the resulting output file. The set of Safer C checks of the linked file is the lowest common denominator of all the checks specified for the individual modules.
If you do not specify the -s option, all Safer C settings of the linked modules will be lost and the output file will not contain any Safer C settings.
lkax x.obj y.obj -S
Select the EDE | 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:
lkxa -u main mylib.a
Section Linking with Libraries.
Select the EDE | Linker/Locator Options... menu item. Add the option to the Additional options field in the Linker tab.
-V
With this option you can display the version header of the linker. This option must be the only argument of lkxa. Other options are ignored. The linker exits after displaying the version header.
lkxa -V
XA object linker va.b rc SN00000000-015 (c) year TASKING, Inc.
Select the EDE | 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.
lkxa -v test.obj
lkxa V008 (1): Embedded environment \cxa\etc\xa.dsc read, relaxed addressing mode check enabled lkxa V003 (1): Starting pass 1 lkxa V002 (1): File currently in progress: test.obj lkxa E208 (0): Found unresolved external(s): _printf - (test.obj) __START - (test.obj) lkxa V003 (1): Starting pass 2 lkxa V002 (1): File currently in progress: test.obj lkxa V005 (1): Removing file .\CD5668a.tld
Using the control program:
ccxa -Wlk-v test.obj
Select the EDE | 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:
lkxa -w5 test.obj
Using the control program:
ccxa -Wlk-w5 test.obj
Section Type Checking.
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:
lkxa start.obj -fobj.lnk mylib.a
or, if the library resides in a sub directory:
lkxa start.obj -fobj.lnk libs\mylib.a (PC) lkxa 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 -lcs you specify the system library libcs.a.
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:
lkxa -L..\lib\xa -L\usr\local\lib start.obj -fobj.lnk -lcs
UNIX:
lkxa -L../lib/xa -L/usr/local/lib start.obj -fobj.lnk -lcs
2. If the -L option is not specified without a directory, check if the environment variable CXALIB 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 CXALIB 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 CXALIB:
PC:
set CXALIB=..\lib\xa;\usr\local\lib lkxa start.obj -fobj.lnk -lcs
UNIX:
CXALIB=../lib/xa:/usr/local/lib export CXALIB lkxa start.obj -fobj.lnk -lcs
setenv CXALIB ../lib/xa:/usr/local/lib lkxa start.obj -fobj.lnk -lcs
3. Search in the lib directory relative to the installation directory of lkxa for library files.
PC:
UNIX:
The linker determines run-time which directory the binary is executed from to find this lib directory.
4. If the library is still not found, search in the processor specific subdirectory of the lib directory relative to the installation directory of lkxa for library files. For example:
PC:
C:\CXA\LIB\XA
UNIX:
/usr/local/cxa/lib/xa
A directory name specified with the -Ldirectory option or in CXALIB may or may not be terminated with a directory separator, because lkxa 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:
lkxa 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:
lkxa -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:
lkxa -lcs myobj.obj mylib.a
the linker starts with searching the system library libcs.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:
lkxa myobj.obj mylib.a -lcs
All symbols which remain unresolved after linking myobj.obj and mylib.a will be searched for in the system library libsb.a.
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 arxa 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. Hence, the linker is unaware of new unresolved symbols while including library members.
This implies that in the first scan only those members are included which where directly referenced by the linked object. The linker will link the library members, and after that scan the library again. This process repeats until no externals can be resolved by the library anymore. Due to the small index part, rescanning is very fast. The order of the library members in the library is of no importance.
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, a call graph file and/or a Safer C report 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 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:
Call graph(s) ============= Call graph 1: main | +-- puts | +-- fputc | +-- _flsbuf | +-- _iowrite | | | +-- _simo | +-- _write | +-- _iowrite | +-- _simo
Object: hello.obj ================= Section:HELLO_PR ( Start = 0x0 ) 0x00000000 E _main Section:CXA_INI_NE ( Start = 0x0 )
Object: puts.obj ================ Section:PUTS_PR ( Start = 0x0 ) 0x00000000 E _puts
Object: start.obj ================= Section:CXA_RTL_PR ( Start = 0x0 ) 0x00000036 E __EXIT 0x00000000 E __START Section: generated0 ( Start = 0x0 ) Section:RESET_VECTOR ( Start = 0x0 )
Object: init.obj ================ Section:CXA_RTL_PR ( Start = 0x3a ) 0x0000003a E __INITSEG
Object: _iob.obj ================ Section:CXA_INI_NE ( Start = 0xd ) 0x0000000e E __iob Section:_IOB_CLR_NE ( Start = 0x0 ) 0x00000000 E __ungetc
Object: fputc.obj ================= Section:FPUTC_PR ( Start = 0x0 ) 0x00000000 E _fputc
Object: exit.obj ================ Section:EXIT_PR ( Start = 0x0 ) 0x00000000 E _exit
Object: _flsbuf.obj =================== Section:_FLSBUF_PR ( Start = 0x0 ) 0x00000000 E __flsbuf
Object: _iowrite.obj ==================== Section:_IOWRITE_CLR_NE ( Start = 0x0 ) Section:_IOWRITE_PR ( Start = 0x0 ) 0x00000000 E __iowrite
Object: _simio.obj ================== Section:_SIMIO_PR ( Start = 0x0 ) 0x00000000 E __simi 0x0000000c E __simo
Object: _write.obj ================== Section:_WRITE_PR ( Start = 0x0 ) 0x00000000 E __write
The addresses in the map file are offsets relative to the start of the section in the output file. For instance, section CXA_RTL_PR of the object module init.obj starts at offset 0x3a from the output CXA_RTL_PR section. __INITSEG also starts at offset 0x3a from the start of the resulting CXA_RTL_PR section. The E after the address indicates the label is external.
With the -s option the linker produces a Safer C report file. This output file contains a report of the Safer C checks used during compilation of C modules. It also contains linker/locator Safer C information. The name of the Safer C report file is the name of the output file with extension .sfc.
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 short with an int. The XA takes both as 16 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, 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 is 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:
ccxa -c -Hproto.h -N *.c
The -N switch instructs the compiler to report prototypes which are still missing, thus making 100% type checking possible.
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:
XA object linker vx.y rz SN00000000-000 (c) year TASKING, Inc. lkxa W112 (4) a.o: Type conflict for symbol <f> in b.o
The first line shows the banner of the XA 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
Section Type Checking.
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