TOC PREV NEXT INDEX DOC LIST MASTER INDEX



Linking and Executing Programs

This chapter provides information about linking and executing embedded Apex programs including the use of directives, declarations and other linker features. It consists of the following sections:


Linking and Executing - A Quick Overview

This section provides a brief overview of the process to link and execute an Ada program with Apex. A more detailed discussion of many of the aspects of linking and executing programs in Apex follows this section.

When linking an embedded program you often need additional control over the link process. The linker description file controls the program memory layout, and specifies additional linking parameters.

Apex processes the linker description file to produce a new description file that describes all the objects to be included in the link. Apex passes the new description file to the Apex Embedded linker (xlink) which produces the final executable object.

Rational supplies a default linker description file for each supported board configuration. This file is located with the LINKER_DESCRIPTION_FILE switch. You can specify your own linker description file by changing the value of this switch.

Downloading and Executing a Program

To execute an embedded program, it must first be downloaded to the target board. This can be accomplished through either the GUI or command-line interface.

Execute compiled programs by using the debugger, the GUI interface or the apex_execute command.

GUI Interface

To download and execute a program using the GUI interface, use the File > Download or File > Debug command. Note that if you use the File > Debug command, the Auto Load Program button is selected by default and the program is automatically downloaded to the target.

The File > Download command downloads an executable or kernel to the current target board. After downloading a program, the PC is set to the kernel starting address. When this command is selected, the Download dialog box is displayed:

This dialog box enables you to provide a list of executable files to be downloaded, shows the download process as it occurs (Verbose button) and dumps the sent packets into a file (Trace Packets button).

After downloading, execute the program normally using the File > Run command.

Command-Line Interface

Executable programs or the kernel can be downloaded to the currently set target board using the apex_download command.

To download and then run an executable on the target board, use the apex_execute command.

Each of these commands are discussed in detail in the Rational Apex Embedded Command Reference.


Linking in Detail

Linking Foreign Object Files

A foreign object file is any object file that would not naturally be included in the link by the Apex prelinker as part of the Ada closure of the main program. These objects could be created by other language compilers, or assemblers, or by even by the Apex Ada compiler. Regardless of the source, the object files must be in VOX relocatable object format to be include in the link.

To link foreign objects with your Ada program you can use pragma Link_With, or you can include the objects in the Objects section of the linker description file.

Ada modules included in the link as foreign objects must be compiled with pragma Not_Elaborated. Because these modules are not part of the Ada closure of the main program they are not elaborated, and therefore must not depend on elaboration code.

VOX relocatable object file format is discussed in detail in Object File Formats (VOX). Converting formats is discussed in "Format Converter" in the Utilities Guide.

Selective Linking

The Apex Embedded linker excludes subprograms from the final executable image if those subprograms cannot be called by the main program. For example, consider package Text_Io, which contains numerous subprograms for performing text input/output operations. If you do not use selective linking when using package Text_Io, all the subprograms contained in the package are linked with your application. Selective linking links only those subprograms from package Text_Io that your application uses.

Continuing with the example, suppose that you are using package Text_Io to display a simple sign-on message. The appropriate line of code looks like this:

By using selective linking, your program contains only that portion of package Text_Io required to support the Put_Line function. The remaining subprograms in package Text_Io (Delete, Reset, Set, Set_Input, New_Line, Get, Get_Line, etc.) are eliminated from the executable during the linking process.

The purpose of selective linking is to encourage the construction of general purpose and reusable code. All operations related to a particular function can be grouped together. Because the linker includes only those functions used by an application, you eliminate any size or download penalties normally incurred by having unnecessary functions included.

Selective linking is achieved as follows. The Embedded linker does a transitive closure of the relocation tables, starting with the symbol specified by the Entry option (usually __start). Each object file generated by the Apex compiler is divided into sections: Text for all instructions, Const for read-only data, Data for initialized data that can be written during execution, Bss for uninitialized data areas. The Apex compiler splits each Text, Const, Data and Bss section into subsections. For Text, a subsection is a subprogram but for Const, Data and Bss a subsection is a named data section with an external name. For example, the data sections that have names ending with the suffixes ..Const and ..Static, are all treated as subsections. Externally named objects, exception tables and the tables generated by the linker are all treated as subsections. When the linker performs the transitive closure of the relocation tables, all subsections that are referenced via symbolic relocation are tagged as needed. Any subsection not referenced is removed from the image.

The linker recognizes an Include option to force a reference to a symbol and guarantee that the subsection containing that symbol is included in the executable. This is used for example, if an interrupt handler is loaded at a specific memory address to which the interrupt vector is already pointing. Although the interrupt handler is not referenced by any part of the executable, it must be downloaded to handle interrupts.

Static Ada address clauses for data objects are implemented as a Data, Const or Bss subsection. Because references to the object dereference the absolute address specified in the address clause, the relocation tables contain no symbolic references to address clause objects. The Embedded linker forces inclusion of all address clause objects to prevent removal by selective linking.

Another example of using the Include option is to include debugging routines that print complex data structures and are called from the debugger. Normally, selective linking eliminates these debugger routines because they are not called from the main program but the Include option includes the routines in the image.

The only other option available for selective linking is the No_Optimize option. When specified, No_Optimize turns off selective linking.

The Linker Options File

In Apex the Linker Options File is called the Linker Description file. This file is described in the following sections.

The Linker Description File

Note: The linker description file is generated by Apex and normally the object files identified in the OBJECT section are given full path names. Under some circumstances the user may want to identify additional object files that are not included in the Ada closure of their program. A fully rooted pathname may be used to identify these object files in the OBJECTS section, but a relative pathname may also be used. If the pathname begins with "./" then "." is interpreted as the full pathname of the directory containing the generated linker description file. A relative pathname without a leading "./" may also be given; in this case it is interpreted relative to the directory where the Embedded linker is invoked.

The linker description file controls the memory layout of your program and other details of the linking process.

The Linker Description File is located by the prelinker for the main subprogram main_unit.2.ada by first looking for the file main_unit.des. If main_unit.des is not found then the file identified by the LINKER_DESCRIPTION_FILE switch is used.

Normally the LINKER_DESCRIPTION_FILE is defined once for each board configuration and it is not required to supply program unique linker description files.

The Apex prelinker processes the linker description file, translating unit names to object files, and adding all the objects from the Ada closure of the main program. Apex then invokes the Embedded linker with the new description to produce the final executable object.

The linker description file generated by the prelinker resides in the .Rational/Compilation and has the same name as the file that contains the main unit with the .ada suffix replaced with .des.

Linker Description File Format

The overall syntax of the linker description file is as follows.

Options, objects andGroup declarations must be made in the order shown in the preceding list. Only one options declaration is allowed, so it must be first. Only one objects declaration is allowed, it must follow the options declaration. Any of the declarations can be omitted as long as their order is preserved.

Use as many Group declarations and as many For clauses as necessary. Each For clause is associated with a specific Group declaration and must immediately follow that Group declaration, so Group declarations and For clauses can be intermixed in the options file. There is more detail in Options Declaration. For information about including additional files in the link, see User-Specified Objects Declaration.

Names in the Linker Description File

When constructing an options file, a reserved word must have exactly the letters shown, however the letters can be either lower or upper case.

A meta name standing for an identifier in a syntax description is shown in lower case italics (for example, option, number, symbol_id).

Processing of all non-keyword identifiers is case sensitive. An identifier begins with a letter and can continue with letters, slashes, dots, underscore and digits.

All numeric values must be specified as unsigned strings of hexadecimal digits (for example, 1234, 0FFFF). The first character of a numeric value must be a decimal digit or 0x.

All optional items are shown in square brackets. For example,

indicates optional use of the Alignment clause.

A comment in an Options file begins with double hyphens. Just as in Ada, the remainder of the line is ignored. Comments appear anywhere except inside of lexical elements.

Variable Syntax

The text of certain switches may be substituted in the linker description file using the following syntax:

${SWITCH_NAME}

Only a small set of switches are recognized by this syntax:

FS_ADDR_[1-8]
KERNEL_START
KRN_ADDR_[1-8]
NET_ADDR_[1-8]
NETWORK_TDM_START
RDT_SESSION_DATA
RUNTIMES
SERIAL_TDM_START
TDM_ADDR_[1-8]
USR_ADDR_[1-8]
USER_LINK_BLOCK
USER_LINK_BLOCK2
USER_LINK_BLOCK3

They must appear in all upper-case letters.

Options Declaration

Linker options are specified in the file using an Options declaration. If present, Options must be the first declaration in the file.

The keywords in an Options declaration are:

define symbol_id number
Define a symbol prior to linking
entry entry_id
Specify starting symbol name
kernel
Indicate to the Embedded linker that a KERNEL program or TDM program is being built
include symbol_id
Include a subsection in the executable, even if it is not referenced
Long_Calls
Insert routine that jumps to destination address when call spans more than maximum offset
map
Request a link map
No_Optimize
Suppress removal of unreferenced sections
origin number
Specify the initial value for `*' in an address_spec
strip
Exclude symbolic information groups in the link image

Each of these is described in more detail in the following sections.

Define

An absolute symbol is declared whose name is symbol_id and whose address is number. The symbol_id is an identifier. The absolute symbol definition overrides any symbol with the same name occurring in an input object file. Use this keyword to override a symbol definition or to provide an explicit definition for an otherwise unresolved reference.

Example:

This example tells the linker to put the symbol An_Unresolved_Ref in the symbol table and give it the absolute address 07cadfee.

Entry

This keyword tells the linker the starting symbol (entry point) of the executable image. The value of entry_id is placed in the VOX header information to inform debuggers and loaders of the starting address. entry_id can be any symbol. If no Entry option is specified, the default starting symbol is __start.

Example:

This example tells the linker that the address of the symbol My_Start is the entry point of the executable file.

Kernel

This keyword is used to link a kernel program. In this case, a Link_Block for the kernel program is not generated; instead a symbol, User_Link_Block is defined as the location of the user program link block as indicated by the Link_Block library directive.

Include

This keyword, with symbol_id, ensures that the subsection indicated by symbol_id is linked into the executable, even if it is normally eliminated by selective linking. For example:

Long_Calls

When a call from one subprogram to another spans more than the maximum offset allowed by the call instruction a link time error message will be emitted. The Long_Calls option may be used to tell the linker to replace the call to the destination subprogram by a call to a generated routine that will load the destination address into a register and jump indirect through the register. On most machines this will take several instructions.

This option is currently supported for PowerPC, RH32, and MIPS.

Map

This keyword tells the linker to produce a symbol map. The linker uses the root filename of the executable file but with the suffix .map.

No_Optimize

By default, the linker removes all object file sections that are not referenced (via external symbol references). The link map lists deleted sections. The No_Optimize keyword suppresses this optimization. If No_Optimize is specified, then sections that are normally deleted are included and fully linked in the resulting executable image.

Origin

number is the lowest address that is allocated to a group which does not have an absolute address via an address clause. It is the initial value for `*' in an address_spec.

For example:

In this example, the memory image begins at 50000 (hexadecimal).

Strip

Do not include the symbol table or string table in the executable file output by the Embedded linker. The symbol table and string table are not loaded into target memory but are used by the symbolic debugger. Symbolic debugging is not possible if this option is used.

User-Specified Objects Declaration

A user-specified Objects declaration in a linker description file indicates additional object files to include in the link. The Objects declaration is used in the xlink Options file to specify all of the objects and archives included in the link.

The Embedded linker takes as input relocatable object (VOX) files. The syntax for the Objects declaration where object is the filename of an object file is:

Ada object files need not be named explicitly in the Objects declaration. Use Ada unit names in place of object files names. This is the recommended method of specifying objects in the Options file. Each Ada unit name is looked up in the view and replaced it with the appropriate object files.

Group Declaration

The Group declaration tells the Embedded linker how the program is loaded into memory. Each Group declaration can have a For clause associated with it that tells the linker where to place that group in memory.

Before explaining how the Group declaration works, it is necessary to understand what an object file contains. Each object file that is input to the Embedded linker can contain the following kinds of sections:

Text
machine instructions
Const
constant initialized data (read only)
Data
initialized data (read/write)
Void
uninitialized data
Bss
uninitialized data

With the default Group declarations, the linker builds an executable program that contains four groups corresponding to these four sections. The linker does this by collecting together the Text sections from all of the object files into one group of text. The same is true for Const, Data and Bss. This grouping is a natural one because many embedded system applications put the Text and Const into ROM.

The linker provides the user complete control of where each section from each object file is placed in memory.

The syntax for a Group declaration is:

All of the sections that are named are collected in one group and that group is named Group_Id. Each of the sections in a group must be of the same kind: Text, Const, Data, Void or Bss.

Name a specific section or specific sections in one of the ways listed under Specific Sections. Name larger collections of sections, called default sections, in one the ways listed under Default Sections.

Specific Sections

object_filename'section

This form identifies a specific section of a particular object file. The object_filename must be specified in the Objects declaration and the path name in the Group declaration must be identical to the path name in the Objects declaration.

object_filename'Text
object_filename'Const
object_filename'Data
object_filename'Void
object_filename'Bss

unit_name'section

unit_name must be a unit that is in one of the Apex views on the search path. This form indicates all of the sections of the given type that comprise the unit.

unit_name'Text
unit_name'Const
unit_name'Data
unit_name/Void
unit_name'Bss

Default Sections

archive_name'section

Name objects that are located in the RTS archive or any archive library with the simple object filename. Alternatively, archive_name'section indicates all sections that are brought in from the archive.

archive_name'Text
archive_name'Const
archive_name'Data
archive_name'Void
archive_name'Bss

section

The Text, Const, Data, Void and Bss sections without prefixes refer to all sections not explicitly named in any other Group directive.

Text
Const
Data
Void
Bss

Void Groups

A Void group is an uninitialized data group just like Bss. Void groups are generated by the linker and are used as a place holder to prevent the linker from allocating another group at the specified address. The only difference between a Void group and a Bss group is that the runtime system does not attempt to zero a Void group. A Void group is generated by the linker for:

Image Groups

Image groups provide a RAM copy of a ROM group. Image groups are designed for two purposes.

The initial values of the data variables are placed in one group and an image of the group is allocated and initialized by copying the initial values to the image. For example,

The startup routine then copies Data_Group to Data_Group_Image before execution of the program. The Embedded linker ensures that all references to objects and symbols in Data_Group refer to the image.

Exception Group

The Exception group is a constant group built by the linker and contains the compacted exception tables used during exception processing. Its size is not know until all of the other groups in the memory image have been allocated target addresses in the memory image. Normally, the Exception group is placed at the end of the memory image due to this unusual constraint.

If, for some reason, you want to put the Exception group somewhere other than at the end of the memory image, special actions are required.

1 . Link the program to determine the size of the Exception group (__Exception_Group).

2 . Allocate a hole in the memory image for the Exception group by modifying the linker description file:

3 . Insert the Exception group where the hole was allocated:

For clauses

The For clause is used to locate a group at a particular memory address or relative to another group. The syntax is

address is either absolute or relative. Absolute addresses are hexadecimal numbers, while relative addresses have the following formats:

*
Current address
* + number
Current address plus number

An asterisk indicates the current address relative to previous For clauses. Groups without an accompanying For clause are located in the first free block of memory starting at the origin.

The default alignment is the largest of the alignments of all of the sections in the group. On most RISC targets, the default alignment generated is 8. Examples:

1 . for Bss_Group use at 01000;

Locate group Bss_Group at physical address hexadecimal 01000

2 . for Bss_Group use at 01000 .. 01FFF;

Locate group Bss_Group at physical address range 01000 .. 01FFF, padding at the end of the group if necessary, up to and including address 01FFF. An error message is generated if the group cannot fit in the specified range. If an address range is specified for a group and the size of the range is larger than the size of the group, null padding is added at the end of the group. The null padding is represented by bytes of zero.

3 . for Bss_Group use at * .. * + 0FFF;

Same as example (2), except the starting address of the group is the current address.

4 . for Bss_Group use align 01000 at * .. * + 01FFF;

Same as example (3) except starting address for Bss_Group is aligned on a multiple of 01000.

ROM Model

Sample Options File

When placing a program into ROM, partition the program in groups for Text, Const, Data and for Bss, as illustrated in the following sample Options file:

Place the Text_Group in ROM because it is never modified during program execution. Do not place the Bss_Group in ROM but in RAM because it represents variables with uninitialized values. These variables are (presumably) written in as the program executes.

The Data_Group contains the program variables that have static initial values. This group must be in ROM because of these initial values. However, these objects are C/C++ variables and can be changed during program execution. This presents a conflict because the value of a variable that is in ROM cannot be changed.

The solution is to use image groups to put the Data_Group into ROM and copy it into RAM during the initialization of the program. The linker makes all references to objects in the Data_Group point to the RAM image, not the one in ROM. This permits the objects to have initial values but allow these values to change during the execution of the program.

To accomplish this RAM imaging of a ROM group, the linker requires that the Options file define an image for the group.

The preceding directives must be changed as follows:

In the example above, the RAM image of My_Data_Group starts at 04000 + the size of the My_Bss_Group.

When the program begins, the ROM image of the group is automatically copied into RAM by the runtime system startup routine.

Example

The following example shows how the address clause is used to control both the RAM and ROM for Data_Group.

Sample Description File for Placing a Program in ROM

Suppose a program is to be put into 16K ROM at address 01000. The following Options file can be used to load the program.

The layout of the load image specified by the above directives is shown in Figure 1 .

Figure 1 Load Image Layout

Reading the Link Map

Default Linker Description File shows the default linker description files which were used to link the queens program. Queens Map shows part of the resulting link map.

Deleted Sections

The link map may have a section named "Deleted Sections". This part of the link map lists the symbols that are not referenced by the program. These symbols and their corresponding subsections are deleted from the image by selective linking.

Shown in Figure 2 , _R_create.0LJXPY04AcST0cN3LL is not referenced anywhere in the program and so its associated section, SUBSECTION 1, is deleted from the image during the selective linking process.

Figure 2 Deleted Sections

Default Linker Description File

Queens Map

The link block is a static object included in every user program.

The program_text group spans 83112 bytes from address 0200038 to 020144df.The first line shows the entire group. The other lines show the contribution of each unit.

Reading Symbol Information in the Link Map

The link map begins with memory layout information for all the groups as described in Default Linker Description File and Queens Map. Following the group information is a description of the object files that are linked. Symbols In the Link Map shows part of the object section from the queens example program link map. Two object file sections are shown: board_management.1'text, and board_management.2'text.

Symbols In the Link Map

Each section begins with the complete pathname to the object file followed by 'Text, 'Data, 'Const or 'Bss, which tells what kind of section it is. Underneath the pathname is a list of all the symbols in that section. Each symbol has an address, a type and a name. The type is a single letter as follows:

A
Absolute
T
Text
D
Data
C
Const
B
Bss
S
Symbolic debugging record

If the type letter is lower case, the symbol is a local symbol, visible only in the section.

The symbol begins with _R_ if it is an Ada symbol. Names that begin with X are used to build exception tables and are ignored by the debugger.

Ada symbols contain the unqualified object name plus a hash string to ensure the uniqueness of overload names.

Link Date and Time

The time and date are contained in hexadecimal format in the link map symbol Program_Signature. The Apex linker generates a program signature in the VOX file, for example:

Using Program_Signature.phl.25650d.32f178f1.0 as an example, the format of the program signature is as follows:

The Apex linker generates two symbols with the value of the address of the program signature:

The first symbol can be used to programmatically access its program signature with pragma Interface_Name (for example, to print out its link time).

The second symbol is used by the debugger to match up VOX files with programs running on the target. The three values jjjjjj, ssssssss, and f are the hexadecimal values of the program signature fields: julian day, seconds past midnight, and flags, respectively.


Rational Software Corporation 
http://www.rational.com
support@rational.com
techpubs@rational.com
Copyright © 1993-2002, Rational Software Corporation. All rights reserved.
TOC PREV NEXT INDEX DOC LIST MASTER INDEX TECHNOTES APEX TIPS