ELF Relocation Notes

From Linux/Xtensa
Revision as of 15:07, 18 August 2013 by Baruch (talk | contribs) (New page: '''Note:''' macros and data structures that are mentioned below refer to uClibc source code, unless otherwise stated. The Global Offset Table (GOT; resides in the <tt>.got</tt> section) h...)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search

Note: macros and data structures that are mentioned below refer to uClibc source code, unless otherwise stated.

The Global Offset Table (GOT; resides in the .got section) has only one pointer entry. The link editor keeps in this GOT entry a pointer to the .dynamic section. At run-time the dynamic linker sets the same entry to point to the _dl_linux_resolve() routine. This pointer is later replicated to the beginning of each PLT chunk using the R_XTENSA_RTLD type 1 relocation (see below).

The "real" GOT is pointed at from and array of (offset, length) pairs (xtensa_got_location data type) at the .got.loc section. The offset and size of this array are kept in xtensa specific .dynamic section tags named DT_XTENSA_GOT_LOC_OFF and DT_XTENSA_GOT_LOC_SZ, respectively. This "real" GOT is part of .text section, and as such is flagged for read and execute only. However, xtensa specific macros (PERFORM_BOOTSTRAP_GOT at start-up time, INIT_GOT at run-time load [elf_machine_runtime_setup() in glibc]) use _dl_mprotect() to change the protection bits on the .text pages pointed from the .got.loc section, and allow write access.

Open questions:

  1. The sections .got.loc and .xt.lit look identical, why are both needed?
  2. The .got.loc section contains a short array of GOT locations at the beginning, and is mostly filled with zeros, why?
  3. Are .xt.lit and .xt.prop really needed at run-time?

Xtensa run-time relocations as implemented in _dl_do_reloc():

R_XTENSA_GLOB_DAT, R_XTENSA_JMP_SLOT
Relocate to symbol address + addend. In terms of the Intel psABI the calculation is 'S + A'.
R_XTENSA_RTLD
This includes two relocation types selected by the addend field. Type 1 inserts a pointer to the _dl_linux_resolve() routine (taken by the dynamic linker from the first (and only) entry of the .got section). Type 2 inserts a pointer to the per-module 'struct elf_resolve' data structure. According to the binutils elf_xtensa_finish_dynamic_sections() routine, this relocation is emitted at the beginning of each PLT "chunk". Each Chunk holds up to 254 PLT entries. The _dl_linux_resolve() pointer, and the link map pointer (struct elf_resolve) are the first two parameters of the initial PLT routine (elf_xtensa_le_plt_entry[]).
R_XTENSA_RELATIVE
Used to adjust internal pointers in the "real" GOT according to the current load address, mainly in shared libraries.