16.4 Changing the Default Function Allocation

The assembly code associated with a C/C++ function can be placed at an absolute address. This can be accomplished by using the address attribute and specifying the virtual address of the function, see 8.11 Variable Attributes.

Functions can also be placed at specific positions by placing them in a user-defined section and then linking this section at an appropriate address, see 8.11 Variable Attributes.

To place executable code into the eXecute-Only Memory (XOM) memory region, use a custom linker script to map the text input sections to a new output section. Next, map the output section to the desired XOM region. This must be performed in conjunction with the -mpure-code option (see 5.7.1 Options Specific to PIC32C/SAM Devices). This option ensures that text sections do not contain read-only data, which would be inaccessible if such data was present in XOM, and places a special flag on text sections to indicate that they contain purely code and no data. The use of XOM can help protect firmware from being stolen or reverse engineered by third parties. For example, add the following to your linker script.
SECTIONS
{
 .purecode :
 {
 INPUT_SECTION_FLAGS (SHF_ARM_PURECODE) *(.text .text.*)
 } > purecode_memory
}

This change will ensure that input sections whose name matches .text or .text.* and which are marked with the SHF_ARM_PURCODE section flag (set by the -mpure-code option), will be placed in the .purecode output section. That .purecode output section will be mapped to a memory region named purecode_memory, which must have previously been defined using the MEMORY command to associate it with the desired XOM locations on your target device. For more information on linker scripts, see the MPLAB XC32 Assembler, Linker, and Utilities User's Guide (DS50002186).