Conditional Input
Lines within a mapfile
can be conditionalized to only apply to a
specific ELFCLASS
(32 or 64-bit) or machine type.
$if expr .... [$elif expr] .... [$else] .... $endif
A conditional input expression evaluates to a logical true or
false value. Each of the directives
($if
, $elif
, $else
, and
$endif
) appear alone on a line. The expressions in
$if
and subsequent $elif
lines are
evaluated in order until an expression that evaluates to true
is found. Text following a line with a false value is
discarded. The text following a successful directive line is treated normally.
Text here refers to any material, that is not part of the
conditional structure. Once a successful $if
or
$elif
has been found, and its text processed, succeeding
$elif
and $else
lines, together with their
text, are discarded. If all the expressions are zero, and there is a
$else
, the text following the $else
is
treated normally.
The scope of an $if
directive cannot extend across multiple
mapfiles
. An $if
directive must be
terminated by a matching $endif
within the
mapfile
that uses the $if
directive, or
the link-editor issues an error.
The link-editor maintains an internal table of names that can be used in the
logical expressions evaluated by $if
and
$elif
. At startup, this table is initialized with each of the
names in the following table that apply to the output object being created.
Table 10-4 Predefined Conditional Expression Names
Name | Meaning |
---|---|
|
32-bit object |
|
64-bit object |
|
shared object |
|
executable object |
|
relocatable object |
|
SPARC machine (32 or 64-bit) |
|
x86 machine (32 or 64-bit) |
|
Always defined |
The names are case sensitive, and must be used exactly as shown. For example,
true
is defined, but TRUE
is not. Any of
these names can be used by themselves as a logical expression. For example.
$if _ELF64 .... $endif
This example will evaluate to true, and allow the link-editor
to process the enclosed text, when the output object is 64-bit. Although numeric
values are not allowed in these logical expressions, a special exception is made for
the value 1
, which evaluates to true, and
0
for false.
Any undefined name evaluates to false. It is common to use
the undefined name false
to mark lines of input that should be
unconditionally skipped.
$if false .... $endif
More complex logical expressions can be written, using the operators shown in the following table.
Table 10-5 Conditional Expression Operators
Operator | Meaning |
---|---|
|
Logical |
|
Logical |
|
Sub-expression |
|
Negate boolean value of following expression |
Expressions are evaluated from left to right. Sub-expressions are evaluated before enclosing expressions.
For example, the lines in the following construct will be evaluated when building 64-bit objects for x86 platforms.
$if _ELF64 && _x86 .... $endif
The $add
directive can be used to add a new name to the
link-editor's table of known names. Using the previous example, it might be
convenient to define the name amd64
to stand for 64-bit x86
objects, in order to simplify $if
directives.
$if _ELF64 && _x86 $add amd64 $endif
This can be used to simplify the previous example.
$if amd64 .... $endif
New names can also be added to the link-editor's table of known names by
using the link-editor's -z mapfile-add
option. This option is
useful when mapfile
input needs to be conditionally enabled
based on an attribute of the external environment, such as the compiler being
used.
The $clear
directive is the reverse of the
$add
directive. It is used to remove names from the internal
table.
$clear amd64
The effect of the $add
directive persists beyond the end of the
mapfile
that uses $add
, and is visible
to any subsequent mapfile
that is processed by the link-editor
in the same link operation. If this is not desired, use $clear
at
the end of the mapfile
containing the $add
to remove the definition.
Finally, the $error
directive causes the link-editor to print
all remaining text on the line as a fatal error, and halt the link operation. The
$error
directive can be used to ensure that a programmer
porting an object to a new machine type will not be able to silently build an
incorrect object that is missing a necessary mapfile
definition.
$if _sparc .... $elif _x86 .... $else $error unknown machine type $endif
C language programmers will recognize that the syntax used for
mapfile
conditional input resembles that of the C
preprocessor macro language. This similarity is intentional. However,
mapfile
conditional input directives are by design
considerably less powerful than those provided by the C preprocessor. They provide
only the most basic facilities required to support linking operations in a cross
platform environment.
Among the significant differences between the two languages.
-
The C preprocessor defines a full macro language, and the macros are applied to both the source text, and to the expressions evaluated by the
#if
and#elif
preprocessor statements. Link-editormapfiles
do not implement a macro capability. -
The expressions evaluated by the C preprocessor involve numeric types, and a rich set of operators.
Mapfile
logical expressions involve boolean true and false values, and a limited set of operators. -
C preprocessor expressions involve arbitrary numeric values, possibly defined as macros, and
defined()
is used to evaluate whether a given macro is defined or not, yielding a true (nonzero) or false (zero) value.Mapfile
logical expressions only manipulate boolean values, and names are used directly without adefined()
operation. The specified names are considered to be true if they exist in the link-editor's table of known names, and false otherwise.
Those requiring more sophisticated macro processing should consider using an
external macro processor, such as
m4
(1)
.