You can enter four basic types of directives into a mapfile:
Segment declarations
Mapping directives
Size-symbol declarations
File control directives
Each directive can span more than one line and can have any amount of white space (including new-lines) as long as it is followed by a semicolon. You can enter zero or more directives in a mapfile. (Entering zero directives causes the link-editor to ignore the mapfile and use its own defaults.)
Typically, segment declarations are followed by mapping directives, that is, you declare a segment and then define the criteria by which a section becomes part of that segment. If you enter a mapping directive or size-symbol declaration without first declaring the segment to which you are mapping (except for built-in segments, explained later), the segment is given default attributes as explained below. Such segment is then an "implicitly declared segment."
Size-symbol declarations and file control directives can appear anywhere in a mapfile.
The following sections describe each directive type. For all syntax discussions, the following notations apply:
All entries in constant width, all colons, semicolons, equal signs, and at (@) signs are typed in literally.
All entries in italics are substitutable.
{ ... }* means "zero or more."
{ ... }+ means "one or more."
[ ... ] means "optional."
section_names and segment_names follow the same rules as C identifiers, where a period (.) is treated as a letter (for example, .bss is a legal name).
section_names, segment_names, file_names, and symbol_names are case sensitive; everything else is not case sensitive.
Spaces (or new-lines) can appear anywhere except before a number or in the middle of a name or value.
Comments beginning with # and ending at a newline can appear anywhere that a space can appear.
A segment declaration creates a new segment in the a.out or changes the attribute values of an existing segment. (An existing segment is one that you previously defined or one of the three built-in segments described below.)
A segment declaration has the following syntax:
segment_name = {segment_attribute_value}*; |
For each segment_name, you can specify any number of segment_attribute_values in any order, each separated by a space. (Only one attribute value is allowed for each segment attribute.) The segment attributes and their valid values are as follows:
Table 8-1 Mapfile Segment Attributes
Attribute |
Value |
---|---|
segment_type |
LOAD | NOTE |
segment_flags |
? [E] [N] [O] [R] [W] [X] |
virtual_address |
Vnumber |
physical_address |
Pnumber |
length |
Lnumber |
rounding |
Rnumber |
alignment |
Anumber |
There are three built-in segments with the following default attribute values:
text (LOAD, ?RX, no virtual_address, physical_address, or length specified, alignment values set to defaults per CPU type)
data (LOAD, ?RWX, no virtual_address, physical_address, or length specified, alignment values set to defaults per CPU type)
note (NOTE)
The link-editor behaves as if these segments are declared before your mapfile is read in. See "Mapfile Option Defaults" for more information.
Note the following when entering segment declarations:
A number can be hexadecimal, decimal, or octal, following the same rules as in the C language.
No space is allowed between the V, P, L, R, or A and the number.
The segment_type value can be either LOAD or NOTE.
The segment_type value defaults to LOAD.
The segment_flags values are R for readable, W for writable, X for executable, and O for order. No spaces are allowed between the question mark (?) and the individual flags that make up the segment_flags value.
The segment_flags value for a LOAD segment defaults to RWX.
NOTE segments cannot be assigned any segment attribute value other than a segment_type.
Implicitly declared segments default to segment_type value LOAD, segment_flags value RWX, a default virtual_address, physical_address, and alignment value, and have no length limit.
The link-editor calculates the addresses and length of the current segment based on the previous segment's attribute values. Also, even though implicitly declared segments default to "no length limit," machine memory limitations still apply.
LOAD segments can have an explicitly specified virtual_address value and/or physical_address value, as well as a maximum segment length value.
If a segment has a segment_flags value of ? with nothing following, the value defaults to not readable, not writable, and not executable.
The alignment value is used in calculating the virtual address of the beginning of the segment. This alignment only affects the segment for which it is specified; other segments still have the default alignment unless their alignments are also changed.
If any of the virtual_address, physical_address, or length attribute values are not set, the link-editor calculates these values as it builds the a.out.
If an alignment value is not specified for a segment, it is set to the built-in default. (The default differs from one CPU to another and might even differ between kernel versions. You should check the appropriate documentation for these numbers).
If both a virtual_address and an alignment value are specified for a segment, the virtual_address value takes priority.
If a virtual_address value is specified for a segment, the alignment field in the program header contains the default alignment value.
If the rounding value is set for a segment, that segments virtual address will be rounded to the next address that conforms to the value given. This value only effects the segments that it is specified for. If no value is given, no rounding is performed.
The ?E flag allows the creation of an empty segment; this is a segment that has no sections associated with it. This segment can only be specified for executables, and must be of type LOAD with a specified size and alignment. Multiple segment definitions of this type are permitted.
The ?N flag lets you control whether the ELF header, and any program headers will be included as part of the first loadable segment. By default, the ELF header and program headers are included with the first segment, as the information in these headers is used within the mapped image (commonly by the runtime linker). The use of the ?N option causes the virtual address calculations for the image to start at the first section of the first segment.
The ?O flag lets you control the order of sections in the final relocatable object, executable file, or shared object. This flag is intended for use in conjunction with the -xF option to the compiler(s). When a file is compiled with the -xF option, each function in that file is placed in a separate section with the same attributes as the .text section. These sections are now called .text%function_name.
For example, a file containing three functions main(), foo() and bar(), when compiled with the -xF option, will yield an object file with text for the three functions in sections called .text%main, .text%foo, and .text%bar. Because the -xF option forces one function per section, the use of the ?O flag to control the order of sections in effect controls the order of functions.
Consider the following user-defined mapfile:
text = LOAD ?RXO; text: .text%foo; text: .text%bar; text: .text%main; |
If the order of function definitions in the source file is main, foo, and bar, then the final executable will contain functions in the order foo, bar, and main.
For static functions with the same name the file names must also be used. The ?O flag forces the ordering of sections as requested in the mapfile. For example, if a static function bar() exists in files a.o and b.o, and function bar() from file a.o is to be placed before function bar() from file b.o, then the mapfile entries should read:
text: .text%bar: a.o; text: .text%bar: b.o; |
Although the syntax allows for the entry:
text: .text%bar: a.o b.o; |
this entry does not guarantee that function bar() from file a.o will be placed before function bar() from file b.o. The second format is not recommended as the results are not reliable.
If a virtual_address value is specified, the segment is placed at that virtual address. For the system kernel this creates a correct result. For files that start via exec(2), this method creates an incorrect a.out file because the segments do not have correct offsets relative to their page boundaries.
A mapping directive instructs the link-editor how to map input sections to output segments. Basically, you name the segment that you are mapping to and indicate what the attributes of a section must be in order to map into the named segment. The set of section_attribute_values that a section must have to map into a specific segment is called the "entrance criteria" for that segment. In order to be placed in a specified segment of the a.out, a section must meet the entrance criteria for a segment exactly.
A mapping directive has the following syntax:
segment_name : {section_attribute_value}* [: {file_name}+]; |
For a segment_name, you specify any number of section_attribute_values in any order, each separated by a space. (At most, one section attribute value is allowed for each section attribute.) You can also specify that the section must come from a certain .o file(s) via the file_name substitutable. The section attributes and their valid values are as follows:
Table 8-2 Section Attributes
Section Attribute |
Value |
---|---|
section_name |
any valid section name |
section_type |
$PROGBITS $SYMTAB $STRTAB $REL $RELA $NOTE $NOBITS |
section_flags |
? [[!]A] [[!]W] [[!]X] |
Notice the following when entering mapping directives:
You must choose at most one section_type from the section_types listed above. The section_types listed above are built-in types. For more information on section_types, see "Sections".
The section_flags values are A for allocatable, W for writable, or X for executable. If an individual flag is preceded by an exclamation mark (!), the link-editor checks to make sure that the flag is not set. No spaces are allowed between the question mark, exclamation mark(s), and the individual flags that make up the section_flags value.
file_name can be any legal file name and can be of the form archive_name(component_name), for example, /usr/lib/libc.a(printf.o). A file name can be of the form *filename (see next bullet item). Notice that the link-editor does not check the syntax of file names.
If a file_name is of the form *filename, the link-editor simulates a basename(1) on the file name from the command line and uses that to match against the specified filename. In other words, the filename from the mapfile only needs to match the last part of the file name from the command line. (See "Mapping Example".)
If you use the -l option during a link-edit, and the library after the -l option is in the current directory, you must precede the library with ./ (or the entire path name) in the mapfile in order to create a match.
More than one directive line can appear for a particular output segment; for example, the following set of directives is legal:
S1 : $PROGBITS; S1 : $NOBITS; |
Entering more than one mapping directive line for a segment is the only way to specify multiple values of a section attribute.
A section can match more than one entrance criteria. In this case, the first segment encountered in the mapfile with that entrance criteria is used; for example, if a mapfile reads:
S1 : $PROGBITS; S2 : $PROGBITS; |
the $PROGBITS sections are mapped to segment S1.
By using the following notation it is possible to specify the order that sections will be placed within a segment:
segment_name | section_name1; segment_name | section_name2; segment_name | section_name3; |
The sections that are named in the above form will be placed before any unnamed sections, and in the order they are listed in the mapfile.
Size-symbol declarations let you define a new global-absolute symbol that represents the size, in bytes, of the specified segment. This symbol can be referenced in your object files. A size-symbol declaration has the following syntax:
segment_name @ symbol_name; |
symbol_name can be any legal C identifier, although the link-editor does not check the syntax of the symbol_name.
File control directives allow users to specify which version definitions within shared objects are to be made available during a link-edit. The file control definition has the following syntax:
shared_object_name - version_name [ version_name ... ]; |
version_name is a version definition name contained within the specified shared_object_name. For more information on version control, see "Specifying a Version Binding".