Within LLVM, fixups are used to represent information in instructions which is currently unknown. During instruction encoding, if some information is unknown (such as a memory location of an external symbol), it is encoded as if the value is equal to 0 and a fixup is emitted which contains information on how to rewrite the value when information is known.
The assembler goes through a stage of relaxation, applying fixups and modifying instruction values when they become known to the system. Once complete, any remaining fixups are converted to relocations and stored in the object file.
ELF Relocation types for a target are defined as an enum in the LLVM
support header include/llvm/Support/ELF.h
and are
referred to as
llvm::ELF::
.
RELOCNAME
Note | |
---|---|
It is vital that these relocations have the same enumerated values as in the linker, otherwise the linker will not be able to understand and handle the object file correctly. |
An example from the OpenRISC 1000 implementation is given below.
enum { R_OR1K_NONE = 0, R_OR1K_32 = 1, ... R_OR1K_RELATIVE = 21 };
Fixups are defined in
lib/Target/
, with (in the
general case) one fixup being created for each relocation type defined
above, with the exception of the no relocation required reloc.
arch
/MCTargetDesc/
arch
FixupKinds.h
These go into an enum called Fixups
. The enum
has its first item set to the value of
FirstTargetFixupKind
and ends with a marker for
LastTargetFixupKind
. The total number of fixups
is then defined as NumTargetFixupKinds = LastTargetFixupKind
- FirstTargetFixupKind
. An example of the fixups used in
the OpenRISC 1000 implementation is shown below.
enum Fixups { // Results in R_OR1K_32 fixup_OR1K_32 = FirstTargetFixupKind, // Results in R_OR1K_16 fixup_OR1K_16, // Results in R_OR1K_8 fixup_OR1K_8, // Results in R_OR1K_LO_16_IN_INSN fixup_OR1K_LO16_INSN, ... // Marker LastTargetFixupKind, NumTargetFixupKinds = LastTargetFixupKind - FirstTargetFixupKind }