15.3. Filling Holes and Padding Functions¶
15.3.1. Introduction¶
The TI Arm Clang Compiler Tools (tiarmclang) support techniques for placing undefined or trap instructions in gaps in code memory. If execution accidentally or maliciously branches into a gap between functions, such undefined or trap instructions can prevent unintended instructions from being performed.
Values from 0xde00 to 0xdeff are interpreted as intentionally undefined on Arm devices.
15.3.2. Fill Operator¶
You can specify how to fill holes in output sections using the SECTIONS directive examples shown in the Filling Holes. The method that uses the fill() operator as follows is most applicable to improving application security, because it provides control over both the value used to fill holes and the size of that value.
For example, if the linker command file applies the fill() operator to the “.func” section as follows, an 8-byte hole is inserted at the beginning of the “.func” output section. The fill(0xdeee,0x10) operation fills that 8-byte hole with four instances of the 16-bit wide fill value, 0xdeee.
SECTIONS
{
...
/* fill() operator uses 16-bit fill width instead of 32-bit default */
.func : { .+=0x0008; *(.text:func) } fill(0xdeee,0x10) > MEM
...
}
15.3.3. Pad Attribute¶
The pad function attribute tells the linker to insert at least 32-bits of padding both before and after the definition of a function that is defined in its own subsection. The fill() operator can then be applied to the output section where the function is placed to encode a specific value into the padding space that is inserted before and after the subsection where the function is defined.
For example, suppose an application contains the following function:
#include <stdio.h>
__attribute__((pad))
int main() {
printf("This function is padded.\n");
return 0;
}
If the linker command file contains the following fill() operator, the resulting linked application contains two UDF (0xdeee) instructions inserted both before and after the definition of main():
SECTIONS
{
...
.main: { hello_pad.o(.text.main) } fill(0xdeee,16) > MEM
...
}