| ARM Technical Support Knowledge Articles | |
Applies to: ARM Developer Suite (ADS), RealView Compilation Tools (RVCT) for BREW, RealView Developer Kit (RVDK) for OKI, RealView Developer Kit (RVDK) for ST, RealView Developer Kit for XScale (RVXDK), RealView Development Suite (RVDS)
The ADS 1.2 (and later) linker message like:
Error: L6286E: Value(0x40db62) out of range(-0x400000 - 0x3fffff) for relocation
#64 (wrt symbol foo) in abc.o (.text)
The ADS 1.1 (and earlier) had a slightly different linker message:
Error: L6286E: Relocation value out of range for relocation #0 in abc.o(.text)
This can typically occur in three cases:
a) In handwritten assembler code, where the limited number of bits for a field within the instruction opcode is too small to refer to a symbol so far away. For example, for an LDR or STR where the offset is too large for the instruction (+/-4095 for ARM state LDR/STR instruction).
b) In large C/C++/asm projects built with ADS, containing large (>4MB) Thumb execution regions, because the ADS armlink cannot insert a "long branch veneer" within such large Thumb regions.
c) In Architecture 5TE (e.g XScale) projects built with early versions of ADS 1.2, because of a linker fault in the generation of long branch veneers, which is fixed in ADS 1.2 build 837 and later, downloadable from:
http://www.arm.com/support/downloads/ads12.html
If you are unsure whether the problem is caused by a) or b), then the following will help you to identify and fix the problem:
If the instruction is not a BL, then follow (i) below, otherwise follow (ii) below.
(i) If the problem instruction is not a BL instruction, change the source code to use an instruction sequence with no field size limitation. This should occur for handwritten assembler only, because the compiler is careful to use instructions which have no link-time limitations. For example, if the problem is the limited size of the LDR/STR offset field, then you should modify the code to load the address or offset from a literal pool, which can accommodate full 32-bit values.
(ii) For a BL instruction and you are using ADS, then the problem is that execution region is too large (4MB for a region containing Thumb, 32MB for ARM only regions). For example, a large application which puts Thumb code into a single large execution region:
LOAD 0x0A000000 0x1000000
{
BIGREGION +0x0
{
* (+RO)
}
}
If BIGREGION is larger than 4MB and you are using ADS, it is impossible to perform a Thumb BL from one end of the region to the other, and you will get the L6286E error. This is a fundamental restriction of the ADS 1.2 linker.
The workaround for ADS 1.2 is to limit your execution regions to less than 4MB (for regions containing Thumb code) or 32MB (for regions containing only ARM code). Large execution regions must be split into multiple smaller execution regions, so that the linker can insert interworking veneers between the regions. You can use the '.ANY' section descriptor in your scatter file execution regions to place any objects within them, up to the maximum limit. For example, replace the BIGREGION execution region with:
LOAD 0x0A000000 0x1000000
{
REGION1 +0x0 0x400000
{
.ANY (+RO)
}
REGION2 +0x0 0x400000
{
.ANY (+RO)
}
}
You must also be using patched armlink build 837 or later, downloadable from:
http://www.arm.com/support/downloads/ads12.htmlbecause a fix is required for the .ANY functionality.
.ANY is documented in section 5.2.5 of the ADS 1.2 Linker and Utilities Guide, but note that in armlink build 837 and later, the region filling behaviour has been modified so that the .ANY execution regions are filled evenly in turn (round robin). There must be enough .ANY regions of sufficient size to store your application code.
The newer RVCT linker does not suffer from the 4MB Thumb execution region restriction, however it is still possible for L6286E to be given.
In RVCT the L6286E message is generated when the linker is having difficulty placing veneers around a large code section in your image. When the linker is placing a veneer near a very large section it must decide whether to place the veneer before or after the large section. Once the linker has placed the veneer it will then need to place further veneers, these additional veneers may be placed between the original veneer and its target. This will increase the distance between the veneer and its target. The linker automatically allows for a certain increase in the distance between the veneer and its target when placing a veneer. However if a large number of veneers are placed between the veneer and its target, the allowance may not be sufficient and the target may be moved out of range of the veneer. If this occurs the linker will generate message L6286E.
To work around this you can move large code sections away from areas where the linker is placing many veneers. This can be done either by placing large sections in their own regions or by placing them first in the region they are located in using the +FIRST directive in the scatterfile. For example:
LOAD 0x0A000000 0x1000000
{
ROM1 +0x0
{
*(+RO)
}
}
Can be changed to:
LOAD 0x0A000000 0x1000000
{
ROM1 +0x0
{
*(+RO)
}
ROM1A +0x0
{
large.o (+RO)
}
}
Article last edited on: 2008-09-09 15:47:28
Did you find this article helpful? Yes No
How can we improve this article?