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

The following linker changes have been made:

Show/hidePlacing 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.

Show/hideLinker 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.

Show/hideLinker-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.

Alignment

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
copy_rw_data
    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:

Load$$region_name$$BaseLoad$$region_name$$LimitLoad$$region_name$$LengthLoad$$region_name$$RO$$BaseLoad$$region_name$$RO$$LimitLoad$$region_name$$RO$$LengthLoad$$region_name$$RW$$BaseLoad$$region_name$$RW$$LimitLoad$$region_name$$RW$$Length
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$$BaseImage$$RO$$Limit ; Equivalent to Image$$ER_RO$$LimitImage$$RW$$Base  ; Equivalent to Image$$ER_RW$$BaseImage$$RW$$Limit ; Equivalent to Image$$ER_RW$$LimitImage$$ZI$$Base  ; Equivalent to Image$$ER_ZI$$BaseImage$$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.

Show/hideBuild 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 error message L6463E: 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.

Show/hideC 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.

Show/hideRW 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.

Show/hideSee also

Copyright © 2011-2012 ARM. All rights reserved.ARM DUI 0593B
Non-ConfidentialID062912