Introduction
IAR Embedded Workbench for ARM version 5.50 and later can optionally generate position-independent code and/or position-independent data.
Definition
- ROPI = Read-Only Position Independence. This concerns everything that is readonly in the ELF output from the linker. Note that this includes const data and data initializers, i.e. typically everything that is put in FLASH.
- RWPI = Read-Write Position Independence. This concerns everything that is readwrite in the ELF output from the linker.
- In the present version there is also an option --pi_veneers (position independent veneers, see the Development Guide for further information)
Compiler options
The following description is an excerpt from the Development Guide:
- Option: --ropi
Use this option to make the compiler generate code that uses PC-relative references to address code and read-only data.
When this option is used, these limitations apply:
* C++ constructions cannot be used
* The object attribute __ramfunc cannot be used
* Pointer constants cannot be initialized with the address of another constant, a string literal, or a function. However, writable variables can be initialized to constant addresses at runtime.
See also --no_rw_dynamic_init (below) and preprocessor symbol __ROPI__
- Option: --rwpi
Use this option to make the compiler generate code that uses the offset from the static base register (R9) to address-writable data.
When this option is used, these limitations apply:
* The object attribute __ramfunc cannot be used
* Pointer constants cannot be initialized with the address of a writable variable.
However, static writable variables can be initialized to writable variable addresses at runtime.
See also --no_rw_dynamic_init (below) and preprocessor symbol __RWPI__
- Option: --no_rw_dynamic_init
Use this option to disable runtime initialization of static C variables. C source code that is compiled with --ropi or --rwpi cannot have static pointer variables and constants initialized to addresses of objects that do not have a known address at link time. To solve this for writable static variables, the compiler generates code that performs the initialization at program startup (in the same way as dynamic initialization in C++).
Example
In each project where ROPI/RWPI is needed, the application design and development and debugging environment will be unique. The number of different possible use cases and needs of position independent code/data are probably not possible to foresee.
It's difficult to create an exhaustive example that covers all aspects - anyway here is an example trying to show some basics of ROPI and RWPI.
Download the example and follow the instructions in readme.pdf about how to build and run. There is also a STM32F4 Discovery board example.
Note:
You will probably get build errors with newer version of IAR Embedded Workbench for ARM. The solution is to replace
static __global_reg char* rwpi_data @ "R9";
with
#if (__VER__ < 6020000) static __global_reg char* rwpi_data @ "R9"; #else static __no_init char* rwpi_data @ R9; #endif