3.3.8. Veneer generation

Veneers are small sections of code generated by the linker and inserted into your program. armlink must generate veneers when a branch involves a destination beyond the branching range of the current state.

The range of a BL instruction is 32MB for ARM, 16MB for Thumb-2, and 4MB for Thumb. A veneer can, therefore, extend the range of the branch by becoming the intermediate target of the instruction and then setting the PC to the destination address. If ARM and Thumb are mixed, the veneer also changes processor state.

armlink supports the following veneer types:

armlink creates one input section called Veneer$$Code for each veneer. A veneer is generated only if no other existing veneer can satisfy the requirements. If two input sections contain a long branch to the same destination, only one veneer is generated. A veneer is only shared in this way if it can be reached by both sections.

If you are using ARMv4T, armlink generates veneers when a branch involves change of state between ARM and Thumb. In ARMv5 and above, the BLX instruction is used.

Veneer sharing

You can use the command-line option --no_veneershare to specify that veneers are not shared. This assigns ownership of the created veneer section to the object that created the veneer and so enables you to select veneers from a particular object in a scatter-loading description file, for example:

LR 0x8000
{
    ER_ROOT +0
    {
          object1.o(Veneer$$Code)
    }
}

Veneer sharing makes it impossible to assign an owning object. Using --no_veneershare, therefore, provides a more consistent image layout. This comes at the cost of a significant increase in code size.

Veneer variants

Veneers have different variants depending on the branching range you require:

Inline veneers

In this variant:

  • the veneer must be inserted just before the target section to be in range

  • an ARM-Thumb interworking veneer has a range of 256 bytes and so the function code must appear in the first 256 bytes immediately after the veneer code

  • a Thumb-ARM interworking veneer has a range of zero bytes and so the function code must appear immediately after the veneer code

  • an inline veneer is always position-independent.

These limitations mean that you cannot move inline veneers out of an execution region using Veneer$$Code. Use the command-line option --no_inlineveneer to prevent the generation of inline veneers.

Short branch veneers

In this variant:

  • an ARM-Thumb short branch veneer has a range of 4MB

  • a short branch veneer is always position-independent.

Long branch veneers

In this variant:

  • both ARM-Thumb and Thumb-ARM interworking veneers have a range of 232 bytes

  • armlink combines long branch capability with the state change capability, therefore, all long branch veneers are also interworking veneers

  • a long branch veneer is either absolute or position-independent.

When you are using veneers be aware of the following:

  • All veneers cannot be collected into one input section because the resulting veneer input section might not be within range of other input sections. If the sections are not within addressing range, long branching is not possible.

  • armlink generates position-independent variants of the veneers automatically. However, because such veneers are larger than non position-independent variants, armlink only does this where necessary, that is, where the source and destination execution regions are both position-independent and are rigidly related.

Veneers are generated to optimize code size. armlink, therefore, chooses the variant in order of preference:

  1. Inline veneer.

  2. Short branch veneer.

  3. Long veneer.

Copyright © 2002-2007 ARM Limited. All rights reserved.ARM DUI 0206H
Non-Confidential