GNU ld's internal linker script uses (https://sourceware.org/git/?p=binutils-gdb.git;a=commit;h=add44f8d5c5c05e08b11e033127a744d61c26aee)
.text :
{
*(.text.unlikely .text.*_unlikely .text.unlikely.*)
*(.text.exit .text.exit.*)
*(.text.startup .text.startup.*)
*(.text.hot .text.hot.*)
*(SORT(.text.sorted.*))
*(.text .stub .text.* .gnu.linkonce.t.*)
/* .gnu.warning sections are handled specially by elf.em. */
*(.gnu.warning)
}Because *(.text.exit .text.exit.*) is ordered before *(.text .text.*), in a -ffunction-sections build, the C library function exit will be placed before other functions.
gold's -z keep-text-section-prefix has the same problem.
In lld, -z keep-text-section-prefix recognizes .text.{exit,hot,startup,unlikely,unknown}.*, but not .text.{exit,hot,startup,unlikely,unknown}, to avoid the strange placement problem.
In -fno-function-sections or -fno-unique-section-names mode, a function whose function_section_prefix is set to .exit"
will go to the output section .text instead of .text.exit when linked by lld.
To address the problem, append a dot to become .text.exit.