Linker and Libraries Guide

Appendix E System V Release 4 (Version 1) Mapfiles


Note –

This appendix describes the original System V Release 4 mapfile language (version 1). Although this mapfile syntax remains supported, the version 2 mapfile language described in Chapter 9, Mapfiles is recommended for new applications.


The link-editor automatically and intelligently maps input sections from relocatable objects to segments in the output file being created. The -M option with an associated mapfile enables you to change the default mapping provided by the link-editor. In addition, new segments can be created, attributes modified, and symbol versioning information can be supplied with the mapfile.


Note –

When using a mapfile option, you can easily create an output file that does not execute. The link-editor knows how to produce a correct output file without the use of the mapfile option.


Sample mapfiles provided on the system reside in the /usr/lib/ld directory.

Mapfile Structure and Syntax

You can enter the following basic types of directives into a mapfile.

Each directive can span more than one line and can have any amount of white space, including new lines, as long as that white space is followed by a semicolon.

Typically, segment declarations are followed by mapping directives. 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, the segment is given default attributes. Such segment is 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.

Segment Declarations

A segment declaration creates a new segment in the output file, or changes the attribute values of an existing segment. An existing segment is one that you previously defined or one of the four built-in segments described immediately following.

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 shown in the following table.

Table E–1 Mapfile Segment Attributes

Attribute 

Value 

segment_type

LOAD | NOTE | NULL | STACK

segment_flags

? [E] [N] [O] [R] [W] [X]

virtual_address

Vnumber

physical_address

Pnumber

length

Lnumber

rounding

Rnumber

alignment

Anumber

Four built-in segments exist with the following default attribute values.

By default, the bss segment is disabled. Any sections of type SHT_NOBITS, which are its sole input, are captured in the data segment. See Table 7–5 for a full description of SHT_NOBITS sections. The simplest bss declaration is sufficient to enable the creation of a bss segment.

        bss =;

Any SHT_NOBITS sections is captured by this segment, rather than captured in the data segment. In its simplest form, this segment is aligned using the same defaults as applied to any other segment. The declaration can also provide additional segment attributes that both enable the segment creation, and assign the specified attributes.

The link-editor behaves as if these segments are declared before your mapfile is read in. See Mapfile Option Defaults.

Note the following when entering segment declarations.


Note –

If a virtual_address value is specified, the segment is placed at that virtual address. For the system kernel, this method creates a correct result. For files that start through exec(2), this method creates an incorrect output file because the segments do not have correct offsets relative to their page boundaries.


The ?E flag allows the creation of an empty segment. This empty segment has no sections associated with the segment. This segment can be a LOAD segment or a NULL segment. Empty LOAD segments can only be specified for executables. These segments must have a specified size and alignment. These segments result in the creation of memory reservations at process startup. Empty NULL segments provide for adding program header entries that can be used by post-processing utilities. These segments should have no additional attributes specified. Multiple definitions for LOAD segments and NULL segments are permitted.

The ?N flag enables you to control whether the ELF header, and any program headers are included as part of the first loadable segment. By default, the ELF header and program headers are included with the first segment. The information in these headers is used within the mapped image, typically 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 enables you control the order of sections in the output file. This flag is intended for use in conjunction with the -xF option to the compilers. 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 called .text%function_name.

For example, a file containing three functions, main(), foo() and bar(), when compiled with the -xF option, yields a relocatable object file with text for the three functions being placed 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;

The first declaration associates the ?O flag with the default text segment.

If the order of function definitions in the source file is main, foo, and bar, then the final executable contains 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 as follows.

        text: .text%bar: a.o;
        text: .text%bar: b.o;

The syntax allows for the following entry.

        text: .text%bar: a.o b.o;

However, this entry does not guarantee that function bar() from file a.o is placed before function bar() from file b.o. The second format is not recommended as the results are not reliable.

Mapping Directives

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 output file, 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 through a file_name declaration. The section attributes and their valid values are shown in the following table.

Table E–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]

Note the following points when entering mapping directives.

Section-Within-Segment Ordering

By using the following notation you can specify the order that sections are 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 are placed before any unnamed sections, and in the order they are listed in the mapfile.

Size-Symbol Declarations

Size-symbol declarations enable you to 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. The link-editor does not check the syntax of the symbol_name.

File Control Directives

File control directives enable you 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.

Mapping Example

The following example is a user-defined mapfile. The numbers on the left are included in the example for tutorial purposes. Only the information to the right of the numbers actually appears in the mapfile.


Example E–1 User-Defined Mapfile

    1.  elephant : .data : peanuts.o *popcorn.o; 
    2.  monkey : $PROGBITS ?AX; 
    3.  monkey : .data; 
    4.  monkey = LOAD V0x80000000 L0x4000; 
    5.  donkey : .data; 
    6.  donkey = ?RX A0x1000; 
    7.  text = V0x80008000;

Four separate segments are manipulated in this example. The implicitly declared segment elephant (line 1) receives all of the .data sections from the files peanuts.o and popcorn.o. Notice that *popcorn.o matches any popcorn.o file that can be supplied to the link-edit. The file need not be in the current directory. On the other hand, if /var/tmp/peanuts.o was supplied to the link-edit, it does not match peanuts.o because it is not preceded by an *.

The implicitly declared segment monkey (line 2) receives all sections that are both $PROGBITS and allocatable-executable (?AX), as well as all sections not already in the segment elephant with the name .data (line 3). The .data sections entering the monkey segment need not be $PROGBITS or allocatable-executable because the section_type and section_flags values are entered on a separate line from the section_name value.

An “and” relationship exists between attributes on the same line as illustrated by $PROGBITS “and” ?AX on line 2. An “or” relationship exists between attributes for the same segment that span more than one line, as illustrated by $PROGBITS ?AX on line 2 “or” .data on line 3.

The monkey segment is implicitly declared in line 2 with segment_type value LOAD, segment_flags value RWX, and no virtual_address, physical_address, length or alignment values specified (defaults are used). In line 4 the segment_type value of monkey is set to LOAD. Because the segment_type attribute value does not change, no warning is issued. The virtual_address value is set to 0x80000000 and the maximum length value to 0x4000.

Line 5 implicitly declares the donkey segment. The entrance criteria are designed to route all .data sections to this segment. Actually, no sections fall into this segment because the entrance criteria for monkey in line 3 capture all of these sections. In line 6, the segment_flags value is set to ?RX and the alignment value is set to 0x1000. Because both of these attribute values changed, a warning is issued.

Line 7 sets the virtual_address value of the text segment to 0x80008000.

The example of a user-defined mapfile is designed to cause warnings for illustration purposes. If you want to change the order of the directives to avoid warnings, use the following example.

    1.  elephant : .data : peanuts.o *popcorn.o; 
    4.  monkey = LOAD V0x80000000 L0x4000; 
    2.  monkey : $PROGBITS ?AX; 
    3.  monkey : .data; 
    6.  donkey = ?RX A0x1000; 
    5.  donkey : .data; 
    7.  text = V0x80008000;

The following mapfile example uses the segment-within-section ordering.

    1.  text = LOAD ?RXN V0xf0004000; 
    2.  text | .text; 
    3.  text | .rodata; 
    4.  text : $PROGBITS ?A!W; 
    5.  data = LOAD ?RWX R0x1000;

The text and data segments are manipulated in this example. Line 1 declares the text segment to have a virtual_address of 0xf0004000 and to not include the ELF header or any program headers as part of this segment's address calculations. Lines 2 and 3 turn on section-within-segment ordering and specify that the .text and .rodata sections are the first two sections in this segment. The result is that the .text section have a virtual address of 0xf0004000, and the .rodata section immediately follows that address.

Any other $PROGBITS section that makes up the text segment follows the .rodata section. Line 5 declares the data segment and specifies that its virtual address must begin on a 0x1000 byte boundary. The first section that constitutes the data segment also resides on a 0x1000 byte boundary within the file image.

Mapfile Option Defaults

The link-editor defines four built-in segments (text, data, bss and note) with default segment_attribute_values and corresponding default mapping directives. Even though the link-editor does not use an actual mapfile to provide the defaults, the model of a default mapfile helps illustrate what happens when the link-editor encounters your mapfile.

The following example shows how a mapfile would appear for the link-editor defaults. The link-editor begins execution behaving as if the mapfile has already been read in. Then the link-editor reads your mapfile and either augments or makes changes to the defaults.

        text = LOAD ?RX; 
        text : ?A!W; 
        data = LOAD ?RWX; 
        data : ?AW; 
        note = NOTE; 
        note : $NOTE;

As each segment declaration in your mapfile is read in, it is compared to the existing list of segment declarations as follows.

  1. If the segment does not already exist in the mapfile but another with the same segment-type value exists, the segment is added before all of the existing segments of the same segment_type.

  2. If none of the segments in the existing mapfile has the same segment_type value as the segment just read in, then the segment is added by segment_type value to maintain the following order.

    INTERP

    LOAD

    DYNAMIC

    NOTE

  3. If the segment is of segment_type LOAD and you have defined a virtual_address value for this LOADable segment, the segment is placed before any LOADable segments without a defined virtual_address value or with a higher virtual_address value, but after any segments with a virtual_address value that is lower.

As each mapping directive in a mapfile is read in, the directive is added after any other mapping directives that you already specified for the same segment but before the default mapping directives for that segment.

Internal Map Structure

One of the most important data structures in the ELF-based link-editor is the map structure. A default map structure, corresponding to the model default mapfile, is used by the link-editor. Any user mapfile augments or overrides certain values in the default map structure.

A typical although somewhat simplified map structure is illustrated in Figure E–1. The “Entrance Criteria” boxes correspond to the information in the default mapping directives. The “Segment Attribute Descriptors” boxes correspond to the information in the default segment declarations. The “Output Section Descriptors” boxes give the detailed attributes of the sections that fall under each segment. The sections themselves are shown in circles.

Figure E–1 Simple Map Structure

A simplified map structure.

The link-editor performs the following steps when mapping sections to segments.

  1. When a section is read in, the link-editor checks the list of Entrance Criteria looking for a match. All specified criteria must be matched.

    In Figure E–1, a section that falls into the text segment must have a section_type value of $PROGBITS and have a section_flags value of ?A!W. It need not have the name .text since no name is specified in the Entrance Criteria. The section can be either X or !X in the section_flags value because nothing was specified for the execute bit in the Entrance Criteria.

    If no Entrance Criteria match is found, the section is placed at the end of the output file after all other segments. No program header entry is created for this information.

  2. When the section falls into a segment, the link-editor checks the list of existing Output Section Descriptors in that segment as follows.

    If the section attribute values match those of an existing Output Section Descriptor exactly, the section is placed at the end of the list of sections associated with that Output Section Descriptor.

    For instance, a section with a section_name value of .data1, a section_type value of $PROGBITS, and a section_flags value of ?AWX falls into the second Entrance Criteria box in Figure E–1, placing it in the data segment. The section matches the second Output Section Descriptor box exactly (.data1, $PROGBITS, ?AWX) and is added to the end of the list associated with that box. The .data1 sections from fido.o, rover.o, and sam.o illustrate this point.

    If no matching Output Section Descriptor is found but other Output Section Descriptors of the same section_type exist, a new Output Section Descriptor is created with the same attribute values as the section and that section is associated with the new Output Section Descriptor. The Output Section Descriptor and the section are placed after the last Output Section Descriptor of the same section type. The .data2 section in Figure E–1 was placed in this manner.

    If no other Output Section Descriptors of the indicated section type exist, a new Output Section Descriptor is created and the section is placed in that section.


    Note –

    If the input section has a user-defined section type value between SHT_LOUSER and SHT_HIUSER, it is treated as a $PROGBITS section. No method exists for naming this section_type value in the mapfile, but these sections can be redirected using the other attribute value specifications (section_flags, section_name) in the entrance criteria.


  3. If a segment contains no sections after all of the command line object files and libraries are read in, no program header entry is produced for that segment.


Note –

Input sections of type $SYMTAB, $STRTAB, $REL, and $RELA are used internally by the link-editor. Directives that refer to these section types can only map output sections produced by the link-editor to segments.