Skip to main content

Reference

Enum Reference 

Source
pub enum Reference {
Show 19 variants Call, Data, Got, GotBare, GotKept, Thread, Address { bytes: u8, }, Signed, Away, Short, AwayWide, Image, Section, GotOffset, GotFront, Slot, SlotKept, Tls(Tls), Field(Fixup),
}
Expand description

What kind of thing a relocation is asking the linker for.

The first four are the distance from the end of an instruction to something, which is what every reference the code makes is, because this compiler generates position independent code and nothing else. They are told apart by what the linker is allowed to do about each one. The last two are not distances from an instruction at all and are what a table of data asks for: the address itself, which is what an initializer holding the address of something holds, and how far something is from the front of the image, which is what a table the runtime reads holds.

Variants§

§

Call

A call, which the linker may satisfy with a stub that reaches further than the four bytes would. R_X86_64_PLT32 on ELF, and the same relocation a branch gets on the other two.

§

Data

A datum, reached from the instruction pointer. R_X86_64_PC32 on ELF.

§

Got

A slot of the global offset table, reached from the instruction pointer, holding the address of something another object may be the one that defines.

The distance to the slot rather than to the thing, which is the whole difference: the distance to the thing is a number only a link that puts the thing in this program can work out, and a shared library is a link that does not. R_X86_64_REX_GOTPCRELX on ELF, which says the instruction is a mov with a REX prefix and lets the linker turn it back into the lea it would have been if the symbol had been here all along.

§

GotBare

A slot of the global offset table read by an instruction the linker may rewrite that has no REX prefix, call *f@GOTPCREL(%rip) or a 32 bit mov. R_X86_64_GOTPCRELX on ELF.

§

GotKept

A slot of the global offset table read by an instruction the linker has to leave as it is, because it is not one of the few it knows how to rewrite: a store into the slot, or a load into a vector register. R_X86_64_GOTPCREL on ELF.

§

Thread

A slot of the global offset table, reached from the instruction pointer, holding how far into a thread’s own block of storage a thread-local variable sits.

An offset and not an address, which is what makes it a different relocation from the one above rather than the same one against a different symbol: a thread-local variable has one copy per thread and therefore no address for a link to write down, and what every copy has in common is where it sits inside the block. Adding the block’s own address, which the machine keeps in a segment register, is what turns one into the other, and that addition is in the code rather than in the relocation. R_X86_64_GOTTPOFF on ELF, which the linker turns into a constant in the instruction when it is making an executable and therefore knows how the blocks are laid out.

§

Address

The address itself, written into an image. int *p = &y; and nothing else in C.

Fields

§bytes: u8

How many bytes of it are written, which is the pointer width except on a target with a narrower relocation for it. R_X86_64_64 and R_X86_64_32 on ELF.

§

Signed

The address itself in four bytes of an x86-64 instruction that sign extends them to eight, which is an immediate on sixty four bits and a displacement. R_X86_64_32S on ELF, which is what code that is not position independent reaches its data with: table(,%rax,4) and movq $.LC0, %rdi. The linker checks the address fits in the lower two gigabytes, where R_X86_64_32 would let one between two and four through to come out negative.

§

Away

How far the thing is from where the four bytes holding the answer are, written into an image rather than reached by an instruction. .long target - . in an asm at file scope, which is how a table of places in a program says where each of them is in four bytes rather than eight and says it without anything having to be written into the table at startup.

The same relocation a load makes, with nothing after the hole, because what a load asks is the same question about the same four bytes. It is a kind of its own here all the same, and not Reference::Data with after left at zero, because the two formats count the answer from different ends: ELF counts from the front of the hole, which is what this wants, and COFF counts from the byte after it, which is what an instruction wants. Saying which is meant is what lets each writer answer for itself rather than one of them be quietly four out.

§

Short

How far the thing is from the end of two bytes holding the answer, which is a jump or a call in sixteen bit code to somewhere in another section. R_386_PC16 on ELF, and nothing on the other formats, which have no sixteen bit code to write it for.

§

AwayWide

The same distance written into eight bytes, which is .quad target - .. The kernel’s jump label table says where each key is that way on x86-64, and the key is in another section from the table, so it is a relocation. R_X86_64_PC64 on ELF.

§

Image

How far the thing is from the front of the loaded image, written into four bytes.

What every field of a Windows unwind table is. The table is read at run time by code that already has the image’s own address, so four bytes of distance from it reach anything in an image a linker will build, which eight bytes of address would have cost twice as much to say and a distance from the table itself could not have said at all: a row is looked up by address in a sorted table, and a row whose meaning depended on where the row was would not sort. IMAGE_REL_AMD64_ADDR32NB.

ELF has no relocation of this kind because nothing it writes asks the question. Its unwind records are found by walking rather than by binary search, and what they hold is the ordinary distance from the record to the function.

§

Section

How far the thing is from the front of the section it is in, written into the four bytes of displacement of an address that is counted from a register.

What a Windows thread finds its copy of a thread-local variable with. Every thread has a copy of the image’s .tls section, the register holds where this thread’s copy is, and the variable is as far into the copy as it is into the section. IMAGE_REL_AMD64_SECREL, and nothing on ELF or Mach-O, which reach thread-local storage through a table slot instead.

§

GotOffset

How far the thing is from the front of the global offset table, in four bytes.

What position independent code on i386 reaches its own data with. That machine has no addressing from the instruction pointer, so a function finds the table once, keeps its address in a register, and reaches everything this file defines as that register plus a constant: leal .LC0@GOTOFF(%ebx), %eax. R_386_GOTOFF on ELF.

§

GotFront

How far the front of the global offset table is from the four bytes themselves, which is how i386 code finds the table in the first place.

addl $_GLOBAL_OFFSET_TABLE_, %ebx straight after a call that left its own return address in %ebx. The addend makes up the difference between where the four bytes are and where the instruction starts, which is the address the call left behind. R_386_GOTPC on ELF.

§

Slot

Where a slot of the global offset table is, as a distance from the front of the table, read by an instruction the linker may rewrite into one that does not go through the slot at all.

The i386 counterpart of Reference::Got, counted from the register holding the table rather than from the instruction pointer: movl foo@GOT(%ebx), %eax and call *foo@GOT(%ebx). R_386_GOT32X on ELF.

§

SlotKept

The same slot read or written by an instruction the linker has to leave as it is, because it is not one of the few it knows how to rewrite. R_386_GOT32 on ELF.

§

Tls(Tls)

One of the ways i386 code reaches a thread-local variable, which the model says which.

Apart from Reference::Thread because this machine has a relocation for each step of each model rather than the one x86-64 needs from a compiler that only writes one of them, and a file of assembly may use any of them. See Tls.

§

Field(Fixup)

Some bits of an AArch64 instruction, which the fixup says which and how to fill in.

Its own kind rather than one of the above, because on this machine a reference is not four bytes of distance: it is a field of a word, and a name takes two instructions to reach, adrp for its page and an add or a load for the low twelve bits of it. Each of those is its own relocation, and the fixup is already the name of one.

Implementations§

Source§

impl Reference

Source

pub const fn kept(self) -> Reference

The same reference with the linker not allowed to rewrite the instruction, which is what gas writes under -mrelax-relocations=no: a slot of the global offset table is read through the slot whatever the instruction is. Every other reference is itself.

Trait Implementations§

Source§

impl Clone for Reference

Source§

fn clone(&self) -> Self

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Copy for Reference

Source§

impl Debug for Reference

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Eq for Reference

Source§

impl PartialEq for Reference

Source§

fn eq(&self, other: &Self) -> bool

Equality operator ==. Read more
1.0.0 (const: unstable) · Source§

fn ne(&self, other: &Rhs) -> bool

Inequality operator !=. Read more
Source§

impl StructuralPartialEq for Reference

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<Q, K> Equivalent<K> for Q
where Q: Eq + ?Sized, K: Borrow<Q> + ?Sized,

Source§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
Source§

impl<Q, K> Equivalent<K> for Q
where Q: Eq + ?Sized, K: Borrow<Q> + ?Sized,

Source§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.