Linker and Libraries Guide

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 9–4 Predefined Conditional Expression Names

Name 

Meaning 

_ELF32

32–bit object 

_ELF64

64–bit object 

_sparc

Sparc machine (32 or 64–bit)

_x86

x86 machine (32 or 64–bit) 

true

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 9–5 Conditional Expression Operators

Operator 

Meaning 

&&

Logical AND 

||

Logical OR 

( expr )

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

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.

Those requiring more sophisticated macro processing should consider using an external macro processor, such as m4(1).