To support ENDBR in Intel Control-flow Enforcement Technology (CET)
instructions:
https://software.intel.com/sites/default/files/managed/4d/2a/control-flow-enforcement-technology-preview.pdf
following changes to i386 psABI are required.
To program properties, add
#define GNU_PROPERTY_X86_FEATURE_1_AND 0xc0000002
#define GNU_PROPERTY_X86_FEATURE_1_ENDBR (1U << 0)
to indicate that all executable sections are compatible with ENDBR when
ENDBR instruction is inserted at:
a. All function entries.
b. All branch targets whose addresses have been taken.
GNU_PROPERTY_X86_FEATURE_1_ENDBR is set on output only if it is set on
all relocatable inputs, which means that glibc must be compiled with
ENDBR-enabled compiler.
The PLT section is changed to enable ENDBR for CET:
PLT0: push GOT[1]
bnd jmp *GOT[2]
nop
...
PLTn: endbr32
push namen_reloc_index
bnd jmp PLT0
together with the second PLT section:
PLTn: endbr32
bnd jmp *GOT[namen_index]
nop
BND prefix is also added so that ENDBR-enabled PLT is compatible with
MPX. GOT is an array of addresses. Initially, GOT[namen_index] is
filled with the address of the endbr32 instruction of the corresponding
entry in the first PLT section. The function, namen, is called via the
the endbr32 instruction in the second PLT entry. GOT[namen_index] is
updated to the actual address of the function, namen, at run-time.
Load-time processing
On an ENDBR capable processor, the following steps should be taken:
1. When loading an executable, if GNU_PROPERTY_X86_FEATURE_1_ENDBR is
set, enable ENDBR.
2. If ENDBR is enabled, when loading a shared library without
GNU_PROPERTY_X86_FEATURE_1_ENDBR, mark all pages in executable
PL_LOAD segments in legacy code page bitmap.
--
H.J.