![]() It just wastes space for the majority of cases, but some awful ABIs do use multi-GOT, e.g. Technically the linker can use multiple entries for one symbol. The address of the GOT entry is insignificant. For subsequent GOT-generating relocations referencing the same symbol, the linker just reuses this entry. When the linker sees such a referenced symbol for the first time, it reserves an entry in GOT. 1Ī GOT-generating relocation references a symbol. The compiler can safely assume the address is either a link-time constant or the load base plus a constant. If the symbol has a non-default visibility, the definition must be defined in the component. See Copy relocations, canonical PLT entries and protected visibility for details. It essentially changes the third case (symbol lookup) to the first two cases. How does it work if the symbol is actually defined in a shared object? To avoid text relocations, there are copy relocations and canonical PLT entries. 1įor position dependent code ( -fno-pic), traditionally the compiler optimizes for statically linked executables and uses direct addressing (usually absolute relocations). For position independent code ( -fpie and -fpic), the compiler uses GOT indirection conservatively. If the symbol has the default visibility, the definition may be in a different component. See Copy relocations, canonical PLT entries and protected visibility for why GCC protected data uses (unneeded) indirection. Using the C/C++ internal linkage ( static, unnamed namespace) or protected/hidden visibility can avoid the indirection for -fpic. ![]() For -fpic code, the third case is used: since such a definition may be interposed by another definition at runtime, the compiler conservatively uses GOT indirection. However, on ELF, a non-local default visibility symbol in a shared object is preemptible by default. got entry Compiler behavior Defined symbolsĭefined symbols generally belong to the first and second cases. TODO: link to my future article about PLT. At link time the linker may find that the value is a constant. The compiler may emit a GOT-generating relocation and use an indirection in a conservative manner. Why do we need a GOT entry for a link-time constant? Well, at compile time it is probably undecided whether the entry may resolve to another component. got.plt holds symbol addresses used by PLT entries.got holds everything else. The table holds link-time constant entries and entries which are relocated by a dynamic relocation. got.plt) holds the symbol addresses which are referenced by text sections. The Global Offset Table (usually consists of. 1Īdrp x8, :got:var # R_AARCH64_ADR_GOT_PAGE The linker will create entries in the Global Offset Table. R_AARCH64_ADR_GOT_PAGE, R_X86_64_REX_GOTPCRELX) are called GOT-generating. The compiler emits code which uses position-independent addressing to extract the absolute virtual address from GOT. ![]() More commonly, the address is stored in the Global Offset Table (abbreviated as GOT). If the text section holds the address which is relocated by the dynamic relocation, this is called text relocations. See GNU indirect function for STT_GNU_IFUNC. The symbol is either potentially defined in another component or is a STT_GNU_IFUNC symbol. The linker emits a dynamic relocation to let the runtime loader perform a symbol lookup to determine the associated symbol value at runtime. Ldr w0, # R_AARCH64_LDST32_ABS_LO12_NCįor the third case, we need help from the runtime loader (abbreviated as ld.so). The text section can get the current program counter, then add the distance from PC to the symbol (PC-relative address), to compute the run-time virtual address. The first byte of the program image, the ELF header, is loaded at the load base. The difference between the link-time addresses of two symbols equals their virtual address difference at run-time. (For a FDPIC ABI for MMU-less Linux, the compiler may add an offset to the FDPIC register instead.) Load base plus constantįor the second case, this component is either a position-independent executable or a shared object. The text section can hold the absolute virtual address directly or use a PC-relative addressing. dependent on runtime computation by ld.soįor the first case, this component must be a position-dependent executable: a link-time address equals its virtual address at run-time.the load base plus a link-time constant.The reference arises from an address taken operation or a PLT entry. In an executable or shared object (called a component in ELF), a text section may need the absolute virtual address of a symbol (e.g.
0 Comments
Leave a Reply. |
AuthorWrite something about yourself. No need to be fancy, just an overview. ArchivesCategories |