dl-sysdep.h 2.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. /*
  2. * Various assembly language/system dependent hacks that are required
  3. * so that we can minimize the amount of platform specific code.
  4. * Copyright (C) 2000-2004 by Erik Andersen <andersen@codepoet.org>
  5. */
  6. /* Define this if the system uses RELOCA. */
  7. #undef ELF_USES_RELOCA
  8. #include <elf.h>
  9. /* Initialization sequence for the GOT. */
  10. #define INIT_GOT(GOT_BASE,MODULE) \
  11. do { \
  12. GOT_BASE[2] = (unsigned long) _dl_linux_resolve; \
  13. GOT_BASE[1] = (unsigned long) MODULE; \
  14. } while(0)
  15. /* Here we define the magic numbers that this dynamic loader should accept */
  16. #define MAGIC1 EM_386
  17. #undef MAGIC2
  18. /* Used for error messages */
  19. #define ELF_TARGET "386"
  20. struct elf_resolve;
  21. extern unsigned long _dl_linux_resolver(struct elf_resolve * tpnt, int reloc_entry);
  22. /* ELF_RTYPE_CLASS_PLT iff TYPE describes relocation of a PLT entry or
  23. TLS variable, so undefined references should not be allowed to
  24. define the value.
  25. ELF_RTYPE_CLASS_NOCOPY iff TYPE should not be allowed to resolve to one
  26. of the main executable's symbols, as for a COPY reloc. */
  27. #define elf_machine_type_class(type) \
  28. ((((type) == R_386_JMP_SLOT || (type) == R_386_TLS_DTPMOD32 \
  29. || (type) == R_386_TLS_DTPOFF32 || (type) == R_386_TLS_TPOFF32 \
  30. || (type) == R_386_TLS_TPOFF) * ELF_RTYPE_CLASS_PLT) \
  31. | (((type) == R_386_COPY) * ELF_RTYPE_CLASS_COPY))
  32. /* Return the link-time address of _DYNAMIC. Conveniently, this is the
  33. first element of the GOT, a special entry that is never relocated. */
  34. extern const Elf32_Addr _GLOBAL_OFFSET_TABLE_[] attribute_hidden;
  35. static __always_inline Elf32_Addr __attribute__ ((unused, const))
  36. elf_machine_dynamic (void)
  37. {
  38. /* This produces a GOTOFF reloc that resolves to zero at link time, so in
  39. fact just loads from the GOT register directly. By doing it without
  40. an asm we can let the compiler choose any register. */
  41. return _GLOBAL_OFFSET_TABLE_[0];
  42. }
  43. extern Elf32_Dyn bygotoff[] __asm__ ("_DYNAMIC") attribute_hidden;
  44. /* Return the run-time load address of the shared object. */
  45. static __always_inline Elf32_Addr attribute_unused
  46. elf_machine_load_address (void)
  47. {
  48. /* Compute the difference between the runtime address of _DYNAMIC as seen
  49. by a GOTOFF reference, and the link-time address found in the special
  50. unrelocated first GOT entry. */
  51. return (Elf32_Addr) &bygotoff - elf_machine_dynamic ();
  52. }
  53. static __always_inline void
  54. elf_machine_relative (Elf32_Addr load_off, const Elf32_Addr rel_addr,
  55. Elf32_Word relative_count)
  56. {
  57. Elf32_Rel * rpnt = (void *) rel_addr;
  58. --rpnt;
  59. do {
  60. Elf32_Addr *const reloc_addr = (void *) (load_off + (++rpnt)->r_offset);
  61. *reloc_addr += load_off;
  62. } while (--relative_count);
  63. }