ARM Technical Support Knowledge Articles

What does "Error: L6286E: Value out of range for relocation" mean?

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)

Answer

RVCT 2.0 and later

Reason 1

The L6286E error message can be 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 scatter-loading description file. For example:

LOAD 0x0A000000 0x1000000
{
  ROM1 +0x0
  {
    *(+RO)
  }
}

Can be changed to:

LOAD 0x0A000000 0x1000000
{
  ROM1 +0x0
  {
     *(+RO)
  }
  ROM1A +0x0
  {
    large.o (+RO)
  }
}

Reason 2

You may also see the linker generate this message, complaining about .ARM.exidx section, for example:

L6286: Value(0x9ff38980) out of range(-0x40000000 - 0x3fffffff) for relocation #0 (R_ARM_PREL31), wrt symbol xxx in XXXX.o(.ARM.exidx)

The cause of this error is due to the placement of .ARM.exidx (exception-handling index tables).  These tables must be located in a single execution region.  Also, the distance from the these tables to the C++ code that uses C++ exception handling, must be within the range -0x40000000 to 0x3fffffff. This behaviour is specified in section 4.4.1/4.4.2 of the ARM Exception Handling ABI (EHABI). The EHABI states that the R_ARM_PREL31 relocation, which .ARM.exidx uses, does not use the highest bit (bit 31) for calculating the relocation.

If you are seeing the above instance of this error, it is most likely that C++ code, which needs to access the .ARM.exidx sections, has been split-up and placed into separate execution regions, outside of the valid range (-0x40000000 - 0x3fffffff).

To resolve this error, if you have memory in between the separated execution regions, you can place the .ARM.exidx section there with the selector *(.ARM.exidx). For example:

LOAD_ROM 0x00000000
{
  ER1 0x00000000 ;the distance from ER2 to ER1 is out of range(0x40000000 - 0x3fffffff)
  {
    file1.o (+RO) ; from a C++ source
    * (+RO)
  }
  ERx 0x30000000
  {
    *(.ARM.exidx) ; Now the distance from the .ARM.exidx sections to ER1 and ER2 are both in the range.
  }
  ER2 0x60000000  
  {
    file2.o (+RO) ; from a C++ source
  }
  ER3 +0
  {
    * (+RW, +ZI)
  }

Otherwise, you will need to try placing the code into an execution region close enough to the tables (within the range of -0x40000000 - 0x3fffffff).

ARM Developer Suite

In ADS 1.2 and later the L6286E linker message looks 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 linkers had a slightly different linker message:

Error: L6286E: Relocation value out of range for relocation #0 in abc.o(.text)

This error message can typically occur in three cases:

If you are unsure whether the problem is caused by one of the first two cases, then the following will help you to identify and fix the problem:

  1. locate the object file mentioned in the linker error message (abc.o in above example), then:
  2. use 'fromelf -r abc.o' to identify the numbered relocation, then
  3. use 'fromelf -c abc.o' to display the instruction based on the offset displayed in (2).

If the instruction is not a BL, then follow (i) below, otherwise follow (ii) below.

  1. 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.

  2. 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-loading description 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 the https://silver.arm.com/browse because 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 ARM linkers in RVCT 2.0 and later do not suffer from the 4MB Thumb execution region restriction.

Article last edited on: 2012-06-27 16:06:29

Rate this article

[Bad]
|
|
[Good]
Disagree? Move your mouse over the bar and click

Did you find this article helpful? Yes No

How can we improve this article?

Link to this article
Copyright © 2011 ARM Limited. All rights reserved. External (Open), Non-Confidential