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 Mapfiles in the Link-Editor 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.

Segment declarations.

Mapping directives.

Section-to-segment ordering.

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 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.

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.

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.

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 82 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.

text –
LOAD, ?RX,
no virtual_address,
physical_address, or
length specified.
alignment values are set to
defaults per CPU type.

data –
LOAD, ?RWX,
no virtual_address,
physical_address, or
length specified.
alignment values are set to
defaults per CPU type.

bss – disabled,
LOAD, ?RWX,
no virtual_address,
physical_address, or
length specified.
alignment values are set to
defaults per CPU type.

note –
NOTE.

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
Figure 16, Table 16, ELF Section Types, sh_type 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.

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,
NOTE, NULL
or STACK. If unspecified, the
segment type 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.

One segment_type of value
STACK is permitted. Only the
access requirements of the segment, selected from
the segment_flags, can be
specified.

Note -
The link-editor calculates the addresses and
length of the current segment based on the
previous segment's attribute values.

LOAD segments can have an
explicitly specified
virtual_address value 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 the alignment is specified. Other segments
still have the default alignment unless their
alignment values 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 the
output file is created.

If an alignment value is not
specified for a segment, the alignment is set to the
built-in default. This default differs from one CPU
to another and might even differ between software
revisions.

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 segment's virtual address is rounded
to the next address that conforms to the value that
is given. This value only effects the segments that
the value is specified for. If no value is given, no
rounding is performed.

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 83 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.

You must choose at most one
section_type from the
section_types listed
previously. The section_types
listed previously are built-in types. For more
information on section_types, see
Section Headers.

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
that the flag is not set. No spaces are allowed
between the question mark, exclamation marks, and
the individual flags that make up the
section_flags value.

file_name can be any legal file
name, of the form *filename, or
of the form
archive_name(component_name),
for example,
/lib/libc.a(printf.o). The
link-editor does not check the syntax of file
names.

If a file_name is of the form
*filename, the link-editor
determines the basename(1) of the file from the
command line. This base name is used to match
against the specified file name.
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 as
follows.

S1 : $PROGBITS;
S2 : $PROGBITS;

The $PROGBITS sections are mapped
to segment S1.

Section-Within-Segment Ordering

By using the following notation you can specify the order that
sections are placed within a segment.

The sections that are named in the preceding 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.