Keil™, An ARM® Company

RealView Linker and Utilities Guide

Expression evaluation in scatter-loading files

5.2.8. Expression evaluation in scatter-loading files

Scatter files frequently contain numeric constants that are specified as expressions. The linker also provides an assertion function called ScatterAssert that takes an expression as a parameter. An error message is generated if this expression does not evaluate to true. See ScatterAssert function for more information.

Expression usage

Expressions can be used in the following places:

  • load and execution region base_address

  • load and execution region +offset

  • load and execution region max_size

  • parameter for the ALIGN, FILL or PADVALUE keywords

  • parameter for the ScatterAssert function.

Expression rules

Expressions follow the C-Precedence rules and are made up of the following:

  • Decimal or hexadecimal numbers.

  • Arithmetic operators: +, -, /, *, ~, OR, and AND

    The OR and AND operators map to the C operators | and & respectively.

  • Logical operators: LOR, LAND, and !

    The LOR and LAND operators map to the C operators || and && respectively.

  • Relational operators: <, <=, >, >=, and ==

    Zero is returned when the expression evaluates to false and nonzero is returned when true.

  • Conditional operator: Expression ? Expression1 : Expression2

    This matches the C conditional operator. If Expression evaluates to nonzero then Expression1 is evaluated otherwise Expression2 is evaluated.

  • Functions that return numbers. See Builtin functions for more information.

All operators match their C counterparts in meaning and precedence.

Expressions are not case sensitive and parentheses can be used for clarity.

Builtin functions

The execution address related functions can only be used when specifying a base_address or +offset value. They map to combinations of the linker defined symbols shown in Table 5.2.

Table 5.2. Execution address related functions

FunctionLinker defined symbol value
ImageBase(region_name)
Image$$region_name$$Base
ImageLength(region_name)
Image$$region_name$$Length + Image$$region_name$$ZI$$Length
ImageLimit(region_name)
Image$$region_name$$Base + Image$$region_name$$Length + Image$$region_name$$ZI$$Length

See Table 4.1 for more information on region-related linker symbols.

The parameter region_name  can be either a load or an execution region name. Forward references are not allowed. The region_name can only refer to load or execution regions that have already been definedExample 5.4.

ScatterAssert function

The ScatterAssert(expression) function can be used at the top level, or within a load region. It is evaluated after the link has completed and gives an error message if expression evaluates to false. Example 5.7 shows how to use the ScatterAssert function to write more complex size checks than those allowed by the max_size of the region.

The load address related functions can only be used within the ScatterAssert function. They map to the three linker defined symbol values as shown in Table 5.3.

Table 5.3. Load address related functions

FunctionLinker defined symbol value
LoadBase(region_name)
Load$$region_name$$Base
LoadLength(region_name)
Load$$region_name$$Length
LoadLimit(region_name)
Load$$region_name$$Limit

The parameter region_name can be either a load or an execution region name. Forward references are not allowed. The region_name can only refer to load or execution regions that have already been defined.

Symbol related function

The symbol related function, defined(global_symbol_name) returns zero if global_symbol_name is not defined and nonzero if it is defined.

Examples

Example 5.3. Specifying the maximum size in terms of an expression

LR1 0x8000 (2 * 1024)
{
    ER1 +0 (1 * 1024)
    {
        *(+RO)
    }
    ER2 +0 (1 * 1024)
    {
        *(+RW +ZI)
    }
}

Example 5.4. Placing an execution region after another

LR1 0x8000
{
    ER1 0x100000
    {
        *+RO
    }
}
LR2 0x100000
{
    ER2 (ImageLimit(ER1))               ; Place ER2 after ER1 has finished
    {
        *(+RW +ZI)
    }
}

Example 5.5. Conditionalizing a base address based on the presence of a symbol

LR1 0x8000
{
    ER1 (defined(version1) ? 0x8000 : 0x10000)   ; Base address is 0x8000
                                                 ; if version1 is defined
                                                 ; 0x10000 if not
    {
        *(+RO)
    }
    ER2 +0
    {
        *(+RW +ZI)
    }
}

A combination of pre-processor macros and expressions is used in Example 5.6 to copy tightly packed execution regions to execution addresses in a page-boundary. Using the ALIGN scatter loading keyword aligns the load addresses of ER2 and ER3 as well as the execution addresses

Example 5.6. Aligning a base address in execution space but still tightly packed in load space

#! armcc -E
#DEFINE START_ADDRESS  0x100000
#DEFINE PAGE_ALIGNMENT 0x100000

#DEFINE MY_ALIGN(address, alignment) ((address +
(alignment-1)) AND ~(alignment-1))

LR1 0x8000
{
    ER0 +0
    {
        *(InRoot$$Sections)
    }
    ER1 START_ADDRESS
    {
        file1.o(*)
    }
    ER2 MY_ALIGN(ImageLimit(ER1), PAGE_ALIGNMENT)
    {
        file2.o(*)
    }
    ER3 MY_ALIGN(ImageLimit(ER2), PAGE_ALIGNMENT)
    {
        file3.o(*)
    }
}

Example 5.7. Using ScatterAssert to check the size of multiple regions

LR1 0x8000
{
    ER0 +0
    {
        *(+RO)
    }
    ER1 +0
    {
        file1.o(+RW)
    }
    ER2 +0
    {
        file2.o(+RW)
    }
    ScatterAssert((LoadLength(ER1) + LoadLength(ER2)) < 0x1000)
                                         ; LoadLength is compressed size
    ScatterAssert((ImageLength(ER1) + ImageLength(ER2)) < 0x2000)
                                         ; ImageLength is uncompressed size
}
ScatterAssert(ImageLength(LR1) < 0x3000) ; Check uncompressed size of LoadRegion
Copyright © 2007 ARM Limited. All rights reserved.ARM DUI 0377A