Earlier quoted context omitted.
> Why should every function start with endbr64 command? Aren't functions usually called directly? They're usually called directly, but unless the compiler can prove that they always are (e.g., if they're static and nothing in the same file takes the address), endbr64 is required. > Also, is it required to insert endbr64 command after function calls (for return address)? No, IBT is only for jmp and call. SS is the equ…
> but unless the compiler can prove that they always are (e.g., if they're static and nothing in the same file takes the address), endbr64 is required Then why not just have the compiler break down every non-static function into two blocks: a static function that contains all the logic, and a non-static function that just contains an IBT and a direct jump to the static function? (Or, better yet, place the non-static…
From a tooling perspective, what you're describing (two entrypoints for a function, the jump you mention is pointless) would require changes up and down the toolchain; it would affect the compiler, all linkers, all debuggers, etc. By contrast, just adding an additional instruction to the function prolog is relatively low-impact.
It's also worth noting that at the time code for a function is emitted, the compiler is not aware of whether the symbol will be exported and thus discoverable in some other module, or by symbol table lookup, so emitting the target instruction is essentially mandatory.