12.5 Linker changes between RVCT v3.1 and RVCT v4.0

Various changes have been made to armlink in RVCT v4.0.

The following linker changes have been made:

Helper functions

Before RVCT v4.0, helper functions were implemented in helper library files such as h_tf.l, provided with the ARM compiler. All helper library filenames start with h_. RVCT v4.0 no longer requires helper libraries. Instead, all helper functions are generated by the compiler and become part of an object file.

Placing ARM library helper functions with scatter files

In RVCT v3.1 and earlier, the helper functions reside in libraries provided with the ARM compiler. Therefore, it was possible to use armlib and cpplib in a scatter file to inform the linker where to place these helper functions in memory.

In RVCT v4.0 and later, the helper functions are generated by the compiler in the resulting object files. They are no longer in the standard C libraries, so it is no longer possible to use armlib and cpplib in a scatter file. Instead, place the helper functions using *.* (i.__ARM_*) in your scatter file.

Warning L6932W when linking with helper libraries

When using RVCT v4.0 and later, you might see the following linker warning:

Warning: L6932W: Library reports warning: use of helper library h_xx.l is deprecated

Before RVCT v4.0, one reason for linking with a helper library is if an object file references the helper function __ARM_switch8. You can find this out by looking at verbose output from the linker using the --verbose option, for example:

Loading member object1.o from lib1.a.
reference :  strncmp
reference :  __ARM_switch8

In RVCT v4.0 and later, because helper libraries are no longer required, the verbose output from the linker might show, for example:

Loading member object2.o from lib2.a.
definition:  __ARM_common_switch8_thumb

In this case, the helper function __ARM_common_switch8_thumb is in the object file object2.o, rather than in a helper library.

So, if you are using RVCT v4.0 and the linker is generating warning message L6932W, it is likely that you are linking with objects or libraries that were built with RVCT v3.1, not RVCT v4.0.

Linker steering files and symbol visibility

In RVCT v3.1 the visibility of a symbol was overridden by the steering file or .directive commands IMPORT and EXPORT. When this occurred the linker issued a warning message, for example:

Warning: L6780W: STV_HIDDEN visibility removed from symbol hidden_symbol through EXPORT.

In RVCT v4.0 the steering file mechanism respects the visibility of the symbol, so an IMPORT or EXPORT of a STV_HIDDEN symbol is ignored. You can restore the v3.1 behavior with the --override_visibility command-line option.

Linker-defined symbols

In the majority of cases region related symbols behave identically to v3.1.

Section-relative symbols

The execution region Base and Limit symbols are now section-relative. There is no sensible section for a $$Length symbol so this remains absolute.

This means that the linker-defined symbol is assigned to the most appropriate section in the execution region. The following example shows this:

ExecRegion ER
RO Section 1 ; Image$$ER$$Base and Image$$ER$$RO$$Base, val 0
RO Section 2 ; Image$$ER$$RO$$Limit, val Limit(RO Section 2)
RW Section 1 ; Image$$ER$$RW$$Base, val 0
RW Section 2 ; Image$$ER$$Limit and Image$$ER$$RW$$Limit,
             ; val Limit(RW Section 2)
ZI Section 1 ; Image$$ER$$ZI$$Base, val 0
ZI Section 2 ; Image$$ER$$ZI$$Limit, val Limit(ZI Section 2)

In each case the value of the …$$Length symbol is the value of the …$$Limit symbol minus the …$$Base symbol.

If there is no appropriate section that exists in the execution region then the linker defines a zero-sized section of the appropriate type to hold the symbols.

Impact of the change

The change to section-relative symbols removes several special cases from the linker implementation, that might improve reliability. It also means that dynamic relocations work naturally on SysV and BPABI links.


The …$$Limit symbols are no longer guaranteed to be four-byte aligned because the limit of the section it is defined in might not be aligned to a four-byte boundary.

This might affect you if you have code that accidentally relies on the symbol values being aligned. If you require an aligned $$Limit or $$Length then you must align the symbol value yourself.

For example, the following legacy initialization code might fail if Image$$<Region_Name>$$Length is not word aligned:

    LDR R1,|Load$$region_name$$Base|
    LDR R0,|Image$$region_name$$Base|
    LDR R4,|Image$$region_name$$Length|
    ADD R4, R4, R0
    LDRNE  R3,[R1],#4
    STRNE  R3,[R0],#4
    CMP  R0,R4
    BNE  copy_rw_data

Writing your own initialization code is not recommended, because system initialization is more complex than in earlier toolchain releases. ARM recommends that you use the __main code provided with the ARM Compiler toolchain.

Delayed Relocations

The linker has introduced an extra address assignment and relocation pass after RW compression. This permits more information about load addresses to be used in linker-defined symbols.

Be aware that:

  • Load$$region_name$$Base is the address of region_name prior to C-library initialization

  • Load$$region_name$$Limit is the limit of region_name prior to C-library initialization

  • Image$$region_name$$Base is the address of region_name after C-library initialization

  • Image$$region_name$$Limit is the limit of region_name after C-library initialization.

Load Region Symbols have the following properties:

  • They are ABSOLUTE because section-relative symbols can only have Execution addresses.

  • They take into account RW compression

  • They do not include ZI because it does not exist prior to C-library initialization.

In addition to Load$$region_name$$Base, the linker now supports the following linker-defined symbols:

Limits of Delayed Relocation

All relocations from RW compressed execution regions must be performed prior to compression because the linker cannot resolve a delayed relocation on compressed data.

If the linker detects a relocation from a RW-compressed region REGION to a linker-defined symbol that depends on RW compression then the linker disables compression for REGION.

Load Region Symbols

RVCT v4.0 now permits linker-defined symbols for load regions. They follow the same principle as the Load$$ symbols for execution regions. Because a load region might contain many execution regions it is not always possible to define the $$RO and $$RW components. Therefore, load region symbols only describe the region as a whole.

; Base address of <Load Region Name>

; Load Address of last byte of content in Load region.

; Limit - Base
Image-related symbols

The RVCT v4.0 linker implements these in the same way as the execution region-related symbols.

They are defined only when scatter files are not used. This means that they are available for the --sysv and --bpabi linking models.

Image$$RO$$Base  ; Equivalent to Image$$ER_RO$$Base
Image$$RO$$Limit ; Equivalent to Image$$ER_RO$$Limit
Image$$RW$$Base  ; Equivalent to Image$$ER_RW$$Base
Image$$RW$$Limit ; Equivalent to Image$$ER_RW$$Limit
Image$$ZI$$Base  ; Equivalent to Image$$ER_ZI$$Base
Image$$ZI$$Limit ; Equivalent to Image$$ER_ZI$$Limit
Interaction with ZEROPAD

An execution region with the ZEROPAD keyword writes all ZI data into the file:

  • Image$$ symbols define execution addresses post initialization.

    In this case, it does not matter that the zero bytes are in the file or generated. So for Image$$ symbols, ZEROPAD does not affect the values of the linker-defined symbols.

  • Load$$ symbols define load addresses pre initialization.

    In this case, any zero bytes written to the file are visible, Therefore, the Limit and Length take into account the zero bytes written into the file.

Build attributes

The RVCT v4.0 linker fully supports reading and writing of the ABI Build Attributes section. The linker can now check more properties such as wchar_t and enum size. This might result in the linker diagnosing errors in old objects that might have inconsistencies in the Build Attributes. Most of the Build Attributes messages can be downgraded to permit armlink to continue.

The --cpu option now checks the FPU attributes if the CPU chosen has a built-in FPU. For example, --cpu=cortex-a8 implies --fpu=vfpv3. In RVCT v3.1 the --cpu option only checked the build attributes of the chosen CPU.

The error message L6463U: Input Objects contain <archtype> instructions but could not find valid target for <archtype> architecture based on object attributes. Suggest using --cpu option to select a specific cpu. is given in one of two situations:

  • The ELF file contains instructions from architecture archtype yet the Build Attributes claim that archtype is not supported.

  • The Build Attributes are inconsistent enough that the linker cannot map them to an existing CPU.

If setting the --cpu option still fails, the option --force_explicit_attr causes the linker to retry the CPU mapping using Build Attributes constructed from --cpu=archtype. This might help if the Error is being given solely because of inconsistent Build Attributes.

C library initialization

A change to the linker when dealing with C library initialization code causes specially named sections in the linker map file created with the --map command-line option. You can ignore these specially named sections.

ARM Linux

When building a shared object the linker automatically imports any reference with STV_DEFAULT visibility that is undefined. This matches the behavior of GCC. This might result in some failed links now being successful.

Prelink support reserves some extra space, this results in slightly larger images and shared objects. The prelink support can be turned off with --no_prelink_support.

There have been numerous small changes with regards to symbol visibility, these are described in the Symbol visibility changes.

RW compression

Some error handling code is run later so that information from RW compression can be used. In almost all cases, this means more customer programs are able to link. There is one case where RVCT v4.0 has removed a special case so that it could diagnose more RW compression errors.

Multiple in-place execution regions with RW compression are no longer a special case. It was possible to write:

    LR1 0x0
        ER1 +0 { file1.o(+RW) }
        ER2 +0 { file2.o(+RW) }

This is no longer possible under v4.0 and the linker gives an error message that ER1 decompresses over ER2. This change has been made to permit the linker to diagnose:

    LR1 0x0
        ER1 +0 { file1.o(+RW) }
        ER2 +0 { file2.o(+RO) }   ; NOTE RO not RW

This fails at runtime on RVCT v3.1.

Non-ConfidentialPDF file icon PDF versionARM DUI0530M
Copyright © 2010-2016 ARM Limited or its affiliates. All rights reserved.