Skip to main content

IAR Embedded Workbench for Arm 9.70.x

Using branch protection in your application

In this section:

To use branch protection, you must make a couple of small modifications to the application startup code. You can also control how the linker checks that all linked application modules support branch protection.

Branch Target Identification

To use Branch Target Identification (BTI), you must compile your application with ‑‑branch_protection=bti or --branch_protection=bti+pac-ret, and enable BTI in the startup code by setting the BTI_EN bit in the processor CONTROL register. If you are using the cstartup.s file, the best way of implementing this is by defining the function __low_level_init. For more information about cstartup.s and __low_level_init, see System startup and termination.

#include <arm_acle.h>
void __low_level_init(void)
{
  unsigned int old_ctrl = __arm_rsr("CONTROL");
  __arm_wsr("CONTROL", old_ctrl | 0x10);
  // Enables BTI by setting bit #4 in CONTROL
}

Caution

In the IDE, use the Project>Options>C/C++ Compiler>Code>Branch target identification to enable BTI.

Pointer Authentication

To use Pointer Authentication (PAC), you must compile your application with ‑‑branch_protection=pac-ret or --branch_protection=bti+pac-ret, and initialize an authentication key and enable PAC in the startup code. If you are using the cstartup.s file, the best way of implementing this is by defining the function __low_level_init. For more information about cstartup.s and __low_level_init, see System startup and termination.

void __low_level_init(void)
{
  // Set up a 128-bit key in 4 parts:
  __arm_wsr("PAC_KEY_P_0", key[0]);
  __arm_wsr("PAC_KEY_P_1", key[1]);
  __arm_wsr("PAC_KEY_P_2", key[2]);
  __arm_wsr("PAC_KEY_P_3", key[3]);
  unsigned int old_ctrl = __arm_rsr("CONTROL");
  __arm_wsr("CONTROL", old_ctrl | 0x40);
  // Enables PAC by setting bit #6 in CONTROL
}

Caution

In the IDE, use the Project>Options>C/C++ Compiler>Code>Pointer authentication to enable PAC.

Linking

To ensure that all modules of the application use PAC, BTI, or both, you can use one or more of these options to control how the linker checks the modules at link time: