| |||
| Home > Using Scatter-loading Description Files > Formal syntax of the scatter-loading description file > 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.
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.
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 evaluates
to nonzero then Expression is
evaluated otherwise Expression1 is
evaluated.Expression2
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.
The execution address related functions can only be used when
specifying a or base_address+ value.
They map to combinations of the linker defined symbols shown in Table 5.2.offset
Table 5.2. Execution address related functions
| Function | Linker defined symbol value |
|---|---|
ImageBase( |
Image$$ |
ImageLength( |
Image$$ |
ImageLimit( | 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 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.region_name
The ScatterAssert( 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 expressionScatterAssert function to write
more complex size checks than those allowed by the of
the region.max_size
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
| Function | Linker defined symbol value |
|---|---|
LoadBase( |
Load$$ |
LoadLength( |
Load$$ |
LoadLimit( |
Load$$ |
The parameter 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.region_name
The symbol related function, defined( returns zero
if global_symbol_name) is
not defined and nonzero if it is defined.global_symbol_name
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