You copied the Doc URL to your clipboard.

How to use scatter files to link code that contains C++ exceptions

Article ID: 124825143

Published date: 24 Jul 2017

Last updated: -

Applies to: ARM Compiler 6, ARM Compiler 5

Problem/Question

How do I use scatter files to link code that contains C++ exceptions?

Scenario

This Knowledge Article is for software developers who use ARM Compiler 5 or ARM Compiler 6 to build code that contains C++ exceptions, and who use a custom scatter file to place ELF sections in the output image at specific memory addresses.

In this scenario, the following error message might be displayed when linking multiple object files and if the scatter file does not include suitable input section descriptions for .init_array, .ARM.exidx, and .ARM.extab sections:

Error: L6216E: Cannot use base/limit symbols for non-contiguous section .ARM.exidx
    

The problem does not occur if the appropriate input section descriptions are provided.

Answer

When compiling code that contains C++ exceptions, the following sections are generated automatically and added to output object files:

  • .init_array sections containing initialization code.

  • .ARM.exidx sections containing index entries for section unwinding.

  • .ARM.extab sections containing exception unwinding information.

These sections must be placed in a single, contiguous region in memory using input section descriptions in a custom scatter file. The following input section descriptions can be used for this purpose:

* (.init_array)    ; Input section description for all .init_array sections
* (0x70000001)     ; Input section description for all .ARM.exidx sections
* (.ARM.extab*)    ; Input section description for all .ARM.extab sections
    

.ARM.extab sections overlap with +RO sections. To place these two types of sections in different execution regions, use the .ANY module select pattern to select all +RO sections that are not .ARM.extab sections. This pattern matches any modules that do not match other module select patterns.

Workaround

N/A

Example

foo.cpp
#include <iostream>
  
extern int bar(void);
  
int main(void)
{
    try {
        throw bar();
    }
    catch (int exception) {
        std::cout << "Exception thrown: " << exception 	<< std::endl;
    }

    return 0;
}              
bar.cpp
int bar(void);
 
int bar(void)
{
    return 1;
}
scatter1.sct
LOAD 0x00000000
{
    ER1 0x00000000
    {
        foo.o (+RO)
        * (+RO)
    }
    ER2 0x01000000
    {
        bar.o (+RO)
    }
    ER3 +0
    {
        * (+RW, +ZI)
    }
    ARM_LIB_STACKHEAP +0 EMPTY 0x10000
    {
    }
}                           

When this example is built using ARM Compiler 6 with:

armclang --target=arm-arm-none-eabi -march=armv7-a -c foo.cpp -o foo.o
armclang --target=arm-arm-none-eabi -march=armv7-a -c bar.cpp -o bar.o
armlink --scatter=scatter1.sct foo.o bar.o -o image.axf
    

or using ARM Compiler 5 with:

armcc --cpu=7-A -c --exceptions foo.cpp -o foo.o
armcc --cpu=7-A -c --exceptions bar.cpp -o bar.o
armlink --scatter=scatter1.sct foo.o bar.o -o image.axf
    

the linker reports:

Error: L6216E: Cannot use base/limit symbols for non-contiguous section .ARM.exidx
Error: L6216E: Cannot use base/limit symbols for non-contiguous section .ARM.exidx
Finished: 0 information, 0 warning and 2 error messages.            

Using the following scatter file resolves the issue:

scatter2.sct
LOAD 0x00000000
{
    ER1 0x00000000
    {
        foo.o (+RO)
        * (.init_array)
        * (0x70000001)
        * (.ARM.extab*)
        .ANY (+RO)
    }
    ER2 0x01000000
    {
        bar.o (+RO)
    }
    ER3 +0
    {
        * (+RW, +ZI)
    }
    ARM_LIB_STACKHEAP +0 EMPTY 0x10000
    {
    }
}                            

Related Information

N/A

Was this page helpful? Yes No