8.4 Linker changes between RVCT v3.1 for µVision and RVCT v4.0 for µVision

Various changes have been made to armlink between RVCT v3.1 for µVision and RVCT v4.0 for µVision.

The following changes to armlink have been made:

Placing ARM library helper functions with scatter files

In RVCT v3.1 for µVision 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 for µVision 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.

Linker steering files and symbol visibility

In RVCT v3.1 for µVision 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 for µVision 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.
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$$$$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 for µVision 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.
Load$$LR$$Load_Region_Name$$Base   ; Base address of <Load Region Name> 
Load$$LR$$Load_Region_Name$$Limit  ; Load address of last byte of content in Load region.
Load$$LR$$Load_Region_Name$$Length ; Limit - Base
Image-related symbols
The RVCT v4.0 for µVision linker implements these in the same way as the execution region-related symbols.
They are defined only when scatter files are not used.
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 for µVision 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-R4F implies --fpu=vfpv3_d16. In RVCT v3.1 for μVision the --cpu option only checked the build attributes of the chosen CPU.
  • 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.

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 for µVision 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 used to be 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 for µVision.
Related reference
8.1 General changes between RVCT v3.1 for µVision and RVCT v4.0 for µVision
Related information
Optimization with RW data compression
Linker-defined symbols
Region-related symbols
Image$$ execution region symbols
Load$$ execution region symbols
Section-related symbols
Example of placing ARM library helper functions
Initialization of the execution environment and execution of the application
--cpu=name (armlink)
--force_explicit_attr (armlink)
--fpu=name (armlink)
--map, --no_map (armlink)
--override_visibility (armlink)
EXPORT (armlink)
IMPORT (armlink)
Execution region attributes
Non-ConfidentialPDF file icon PDF versionARM DUI0593E
Copyright © 2011, 2012, 2014, 2015 ARM. All rights reserved.