You copied the Doc URL to your clipboard.

How do I import linker-defined symbols of ZI sections to C/C++ in ARM Compiler 6?

Article ID: 150181989

Published date: 10 Jan 2018

Last updated: -

Applies to: ARM Compiler 6

Problem/Question

How do I import linker-defined symbols of ZI sections to C/C++ in ARM Compiler 6?

Scenario

In the Arm Compiler 5 (armcc), you can place a variable in a ZI data section with an undecorated name (one not prefixed by .bss.) by using the zero_init attribute. After that, you can access the start address of that section by the linker-defined input section symbols. For example:

/*! In armcc, put the variable in the ZI section “myData” */

__attribute__ ((section(“myData”), zero_init)) uint32_t g_wDemo;

/*! The base address of the ZI section “myData” can be accessed with the following symbol */

extern uint32_t myData$$Base;

In the ARM Compiler 6 (armclang), the variable attribute zero_init is no longer supported. To put a variable in a specific ZI data section, the section name must start with .bss. to get the same behavior. For example:

/*! In armclang, put the variable in the ZI section “myData” */

__attribute__ ((section(“.bss.myData)) uint32_t g_wDemo;

However, the result in the linker-generated input section symbols has the format .bss.xxxx$$Base, which is not a valid C/C++ symbol name. For example:

/*! It’s NOT a valid C/C++ symbol name*/

extern uint32_t .bss.myData$$Base;

Answer

You can use either of the following methods to resolve this issue:

  • Method A, which is more direct.

  • Method B, which has better binary interoperability between toolchains.

Method A: Use the keyword __asm__

Both Arm Compiler 5 and Arm Compiler 6 support the keyword __asm__, which can give a different symbol name to a variable. For example:

/*! In armcc, put the variable in the ZI section “myData” */

__attribute__ ((section(“.bss.myData”))) uint32_t g_wDemo;

/*! The base address of the ZI section “myData” can be accessed in C*/

extern uint32_t myData __asm__(“.bss.myData$$Base”);

Note: The keyword __asm__ is not guaranteed to be supported by other non-Arm tool chains.

Method B: Define a bridge symbol

Although you cannot import linker-defined symbols for ZI sections directly, these symbols are still accessible in assembly language. By defining a new symbol in assembly as a bridge, the start address of the target ZI section is accessible in C/C++ source code. For example, you declare a ZI variable in a C source file:

__attribute__ ((section(".bss.myData"))) uint32_t g_wDemo;

In the assembly source code, you can create a new symbol for the linker-generated symbol:

; Assembly code in the Arm style syntax

IMPORT |.bss.myData$$Base|

EXPORT myData

myData DCD |.bss.myData$$Base|

// Assembly code in the GNU style syntax

.global .bss.myData$$Base

.global myData

.type myData, “common”

myData: .word .bss.myData$$Base

In c source files, you can add a reference for the new symbol:

/* Address for .bss.myData */

extern const uint32_t *myData;

Then, you can read the start address of the ZI section .bss.myData from the constant pointer myData.

Workaround

N/A

Example

N/A

Was this page helpful? Yes No