summaryrefslogtreecommitdiff
path: root/doc/link-relocs.txt
diff options
context:
space:
mode:
authorMichael Meeks <michael.meeks@novell.com>2005-07-21 10:35:48 +0000
committerMichael Meeks <michael.meeks@novell.com>2005-07-21 10:35:48 +0000
commitf978aa313fbf59e91eb17a430720bfe257a89872 (patch)
tree02fbe0dffb30be1420dcb17aae251e34e2c1aa28 /doc/link-relocs.txt
parentf5be153e5b51814aa9fa0b342d0ecc4965f1be70 (diff)
Upd.
Diffstat (limited to 'doc/link-relocs.txt')
-rw-r--r--doc/link-relocs.txt152
1 files changed, 151 insertions, 1 deletions
diff --git a/doc/link-relocs.txt b/doc/link-relocs.txt
index f6e399594..04c8d03d6 100644
--- a/doc/link-relocs.txt
+++ b/doc/link-relocs.txt
@@ -484,7 +484,7 @@ With just an appended '@PLT' the vtable then holds:
suitable for a call <foo@plt> - but we want an absolute
label reference there.
-bfd_howto_type -> (bfd/bfd.h) bfd_howto_struct:
+bfd_howto_type -> (bfd/bfd.h) reloc_howto_struct:
cf.
HOWTO(R_386_PLT32, 0, 2, 32, TRUE /* pc_relative */, 0, complain_overflow_bitfield,
bfd_elf_generic_reloc, "R_386_PLT32",
@@ -525,3 +525,153 @@ So - somehow the @PLTABS relocation is getting clobbered
This optimization requires GNU as and GNU ld. Not all systems
support this option. `-Wl,--gc-sections' is ignored without
`-static'.
+
+
+** So - patch works well for this case:
+
+ + VTable & PLT slot in main app object, (method already had
+ plt entry (?))
+ + we should be generating a non-symbol-driven relocation
+ *per* PLT slot (surely) - since these are not relative
+ jumps at all - but absolute fixups.
+ + ... Hmm ...
+
+** Function pointer equality -
+ + already an issue with the PLT -> eg elf32-i386.c:
+
+elf_i386_finish_dynamic_symbol:
+ if (!h->def_regular)
+ {
+ /* Mark the symbol as undefined, rather than as defined in
+ the .plt section. Leave the value if there were any
+ relocations where pointer equality matters (this is a clue
+ for the dynamic linker, to make function pointer
+ comparisons work between an application and shared
+ library), otherwise set it to zero. If a function is only
+ called from a binary, there is no need to slow down
+ shared libraries because of that. */
+ sym->st_shndx = SHN_UNDEF;
+ if (!h->pointer_equality_needed)
+ sym->st_value = 0;
+ }
+
+
+** Fuzzy understanding:
+
+ + What is a 'JUMP_SLOT' relocation we have 3 things:
+ + a plt entry
+ + a relocation pointing to it (should be relative)
+ + Does the runtime fix up use the .dyn.plt relocation data
+ to do the fixup ?: most likely ...
+ + ie. we need to output 2 relocations: 1 JUMP_SLOT
+ (done per-symbol)
+ and also 1 RELATIVE relocation - per vtable entry.
+ + we must already output 1 fixup per PLT entry - to
+ point at that PLT entry - but this is not a relocation
+ but an immediate link-time fixup (?)
+
+
+* elf32-i386.c (elf_i386_relocate_section):
+ + looks interesting - PLT code very light.
+
+ + bfd_elf32_swap_reloc_out -> (bfd/elflink.h)
+
+/* Translate an ELF reloc from internal format to external format. */
+void
+elf_swap_reloc_out (bfd *abfd,
+ const Elf_Internal_Rela *src,
+ bfd_byte *d)
+{
+ Elf_External_Rel *dst = (Elf_External_Rel *) d;
+ H_PUT_WORD (abfd, src->r_offset, dst->r_offset);
+ H_PUT_WORD (abfd, src->r_info, dst->r_info);
+}
+
+void
+elf_swap_reloca_out (bfd *abfd,
+ const Elf_Internal_Rela *src,
+ bfd_byte *d)
+{
+ Elf_External_Rela *dst = (Elf_External_Rela *) d;
+ H_PUT_WORD (abfd, src->r_offset, dst->r_offset);
+ H_PUT_WORD (abfd, src->r_info, dst->r_info);
+ H_PUT_SIGNED_WORD (abfd, src->r_addend, dst->r_addend);
+}
+
+
+* JUMP_SLOT relocation:
+ + offset points into .got.plt
+ + allows that to be fixed up idly.
+ + .rel.plt - contains symbol index to do fixup
+ + contents of <.got.plt> is
+ + <raw address> -> jump back into
+ equivalent PLT code
+
+ ** creating a jump-slot (PLT) reloc **
+ + write reloc itself to /.rel.plt/
+ -> /.got.plt/
+ + the reloc allows .got.plt to be relocated
+ with the library.
+ + create /.plt/ record
+ + assign index -> /.got.plt/ etc.
+ + write /.got.plt/ record
+ + initially points into relevant /.plt/ record
+ + <foreach referrer to symbol>
+ + create relative address to that code
+ + ie. call 790 <fprintf@plt> (pc-relative)
+
+ ** normal PLT code:
+
+** The input code has:
+
+RELOCATION RECORDS FOR [.gnu.linkonce.d._ZTV9BaseClass]:
+OFFSET TYPE VALUE
+00000008 R_386_PLT32ABS _ZN9BaseClass5doFooEv
+0000000c R_386_PLT32ABS _ZN9BaseClass5countEv
+00000010 R_386_PLT32ABS _ZN9BaseClassixEi
+ ie. the .d._ZTV9BaseClass is a section.
+ each of these is a location we want to add an
+ R_386_RELATIVE to.
+
+** Dynamic linker:
+ glibc/elf/do-rel.h: (elf_machine_lazy_rel)
+ cf. glibc/sysdeps/i386/dl-machine.h
+ + a JUMP_SLOT reloc has:
+
+__attribute__ ((always_inline))
+elf_machine_lazy_rel (struct link_map *map,
+ Elf32_Addr l_addr, const Elf32_Rel *reloc)
+{
+ Elf32_Addr *const reloc_addr = (void *) (l_addr + reloc->r_offset);
+ const unsigned int r_type = ELF32_R_TYPE (reloc->r_info);
+ /* Check for unexpected PLT reloc type. */
+ if (__builtin_expect (r_type == R_386_JMP_SLOT, 1))
+ {
+ if (__builtin_expect (map->l_mach.plt, 0) == 0)
+ *reloc_addr += l_addr;
+ else
+ *reloc_addr = (map->l_mach.plt
+ + (((Elf32_Addr) reloc_addr) - map->l_mach.gotplt) * 4);
+ }
+ else
+ _dl_reloc_bad_type (map, r_type, 1);
+}
+ This fixup occurs on the GOT reference.
+called from dynamic-link.h: ELF_DYNAMIC_DO_REL,
+and ELF_DYNAMIC_RELOCATE from glibc/elf/dl-reloc.c (_dl_relocate_object)
+
+ 'lazy' is only set for DT_PLTREL sections,
+ not DT_RELOC ones.
+
+ Otherwise (glibc/elf/do-rel.h):
+ for (; relative < r; ++relative)
+ DO_ELF_MACHINE_REL_RELATIVE (map, l_addr, relative);
+
+ + The runtime dylinker is very simple.
+
+
+
+
+
+* It must be the case that a more generic mechanism is doing
+ these fixups - via the reloc_howto_type table ? \ No newline at end of file