The ELF specification contains enough features to allow position-independent code (PIC) to be written, which makes ELF shared libraries very flexible. However, it also means Yasm has to be able to generate a variety of strange relocation types in ELF object files, if it is to be an assembler which can write PIC.
Since ELF does not support segment-base references, the WRT
operator is not used
for its normal purpose; therefore Yasm’s elf32
output
format makes use of WRT
for a different purpose, namely the
PIC-specific relocation types.
elf32
defines five special symbols which you can use as
the right-hand side of the WRT
operator to obtain PIC
relocation types. They are ..gotpc
, ..gotoff
, ..got
,
..plt
and ..sym
. Their functions are summarized
here:
..gotpc
wrt ..gotpc
will end up giving the distance from the beginning of the current section to the global
offset table. (((_GLOBAL_OFFSET_TABLE_
)) is the standard
symbol name used to refer to the GOT.) So you would then need to add $$
to the result to get
the real address of the GOT...gotoff
wrt
..gotoff
will give the distance from the beginning of the GOT to the specified
location, so that adding on the address of the GOT would give the real address of the
location you wanted...got
wrt
..got
causes the linker to build an entry in the GOT containing the address of the symbol, and the
reference gives the distance from the beginning of the GOT to the entry; so you can add
on the address of the GOT, load from the resulting address, and end up with the address
of the symbol...plt
wrt ..plt
causes the
linker to build a procedure
linkage table entry for the symbol, and the reference gives the address of the PLT entry. You can only use this in
contexts which would generate a PC-relative relocation normally (i.e. as the destination
for CALL
or JMP
), since ELF
contains no relocation type to refer to PLT entries absolutely...sym
wrt ..sym
causes Yasm
to write an ordinary relocation, but instead of making the relocation relative to the
start of the section and then adding on the offset to the symbol, it will write a
relocation record aimed directly at the symbol in question. The distinction is a
necessary one due to a peculiarity of the dynamic linker.