Veneers have different capabilities and use different code pieces. The linker selects the most appropriate, smallest, and fastest depending on the branching requirements:
used to perform only a state change
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 so the function entry point must appear within 256 bytes of the veneer
a Thumb-ARM interworking veneer has a range of zero bytes so the function entry point must appear immediately after the veneer
an inline veneer is always position-independent.
Short branch veneer:
an interworking Thumb to ARM short branch veneer has a range of 32MB, the range for an ARM instruction
a short branch veneer is always position-independent.
Long branch veneer:
can branch anywhere in the 4GB address space
all long branch veneers are also interworking veneers
there are different long branch veneers for absolute or position-independent code.
When you are using veneers be aware of the following:
The inline veneer limitations mean that you cannot move inline veneers out of an execution region using a scatter file. Use the command-line option
--no_inlineveneerto prevent the generation of inline veneers.
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.
The linker generates position-independent variants of the veneers automatically. However, because such veneers are larger than non position-independent variants, the linker 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:
Short branch veneer.