This article describes target-specific things about x86 in ELF linkers. I will use "x86" to refer to both x86-32 and x86-64.
Global Offset Table
_GLOBAL_OFFSET_TABLE_
is defined at the start of the
section .got.plt
. .got.plt
has 3 reserved
entries.
_GLOBAL_OFFSET_TABLE_[0]
stores the link-time address of
_DYNAMIC
for a legacy reason. It's unused now. See All
about Global Offset Table.
_GLOBAL_OFFSET_TABLE_[1]
and
_GLOBAL_OFFSET_TABLE_[2]
are for lazy binding PLT.
GOT optimization
See All about Global Offset Table#GOT optimization.
Procedure Linkage Table
Retpoline and Indirect Branch Tracking
ld.lld supports -z retpolineplt
for Spectre v2
mitigation.
See .note.gnu.property
below for Indirect Branch
Tracking.
See All about Procedure Linkage Table#x86 for detail.
Thread Local Storage
x86 uses TLS Variant II: the static TLS blocks are placed below the thread pointer.
Beside the traditional general dynamic and local dynamic TLS models, there are TLSDESC ABIs for x86-32 and x86-64.
The linker performs TLS optimization.
See All about thread-local storage.
.note.gnu.property
The linker parses input .note.gnu.property
sections and
recognize -z force-ibt
and -z shstk
to compute
the output .note.gnu.property
(type is
SHT_NOTE
) section.
The following code (extracted from ld.lld) describes the behavior.
Basically, without extra options, the output has the
GNU_PROPERTY_X86_FEATURE_1_IBT
bit if all input
.note.gnu.property
sections have the bit (logical AND).
-z force-ibt
forces setting the bit with a warning.
The output has the GNU_PROPERTY_X86_FEATURE_1_SHSK
bit
if all input .note.gnu.property
sections have the bit
(logical AND). -z shstk
forces setting the bit without a
warning.
1 | for (ELFFileBase *f : ctx.objectFiles) { |
See Control flow integrity for an overview of Intel CET.
.eh_frame
Clang since rL252300 emits .eh_frame
sections of type
SHT_X86_64_UNWIND
. It is unfortunate that
.eh_frame
does not use a dedicated section type but
nowadays
.gnu.linkonce.t.__x86.get_pc_thunk.bx
The magic symbol prefix .gnu.linkonce
was used before
COMDAT was introduced into ELF. .gnu.linkonce
was very
obsoleted now, but unfortunately
.gnu.linkonce.t.__x86.get_pc_thunk.bx
remained relevant in
glibc x86-32 until glibc 2.32 (2020-08).