For ELF targets, GCC 11 will set SHF_GNU_RETAIN on the section of a
__attribute__((retain)) function/variable, if the configure-time GNU as
supports SHF_GNU_RETAIN (binutils 2.36 or above on Linux or FreeBSD).
'used' and 'retain' are orthogonal on ELF targets: 'used' does not
prevent the section from being discarded by ld --gc-sections.
(
On Windows, 'used' is coarse-grained. An attribute on a variable(function)
causes all variables(functions) in the object file to be retained.
)
As an example, to notify the fuzzer engine "American Fuzzy Lop" about persistent mode,
the user may define an unreferenced variable:
__attribute__((used, retain, section(".data.PERSIST_SIG"))) static char AFL_PERSISTENT[] = "##SIG_AFL_PERSISTENT##";
Without 'used', the definition can be discarded by the compiler. Without
'retain', the definition can be discarded by ld --gc-sections.
(
Before 'retain', previous ELF solutions require inline asm or linker tricks, e.g.
asm volatile(".reloc 0, R_X86_64_NONE, .data.DEFER_SIG"); (architecture dependent)
or define a non-local symbol in the section and use ld -u.
There was no elegant source-level solution.
)
Because 'used' and 'retain' will usually be used together, we
deliberately allow 'retain' on non-ELF targets to avoid -Wunknown-attributes.
We don't want users to write code dispatching on binary formats.
This patch sets !retain metadata on RetainAttr definitions. The backend is
responsible for setting SHF_GNU_RETAIN for ELF (if integrated assembler or
-fbinutils-version=2.36 or newer) and ignores the metadata for other binary
formats.
Should this be a target-specific attribute as it only has effects on ELF targets?