do-rel.h 3.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. /* -*- mode:c; c-file-style:"k&r"; c-basic-offset: 4; tab-width:4; indent-tabs-mode:nil; mode:auto-fill; fill-column:78; -*- */
  2. /* vim: set ts=4 sw=4 et tw=78 fo=cqt wm=0: */
  3. /* Copyright (C) 2014 OSCAR lab, Stony Brook University
  4. This file is part of Graphene Library OS.
  5. Graphene Library OS is free software: you can redistribute it and/or
  6. modify it under the terms of the GNU General Public License
  7. as published by the Free Software Foundation, either version 3 of the
  8. License, or (at your option) any later version.
  9. Graphene Library OS is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU General Public License for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with this program. If not, see <http://www.gnu.org/licenses/>. */
  15. /*
  16. * do-rel.h
  17. *
  18. * This files contain architecture-independent macros of ELF dynamic
  19. * relocation function.
  20. * The source code is imported and modified from the GNU C Library.
  21. */
  22. #include <pal_rtld.h>
  23. #include "dl-machine-x86_64.h"
  24. #define elf_dynamic_do_rel elf_dynamic_do_rela
  25. #define RELCOUNT_IDX VERSYMIDX (DT_RELACOUNT)
  26. #define Rel Rela
  27. #define elf_machine_rel elf_machine_rela
  28. #define elf_machine_rel_relative elf_machine_rela_relative
  29. #ifndef DO_ELF_MACHINE_REL_RELATIVE
  30. # define DO_ELF_MACHINE_REL_RELATIVE(l_addr, relative) \
  31. elf_machine_rel_relative (l_addr, relative, \
  32. (void *) (l_addr + relative->r_offset))
  33. #endif
  34. static void __attribute__((unused))
  35. elf_dynamic_do_rel (ElfW(Dyn) **l_info, ElfW(Addr) l_addr,
  36. ElfW(Addr) reladdr, ElfW(Addr) relsize,
  37. bool do_rel, bool do_rel_relative)
  38. {
  39. ElfW(Rel) *r = (void *) reladdr;
  40. ElfW(Rel) *end = (void *) (reladdr + relsize);
  41. if (!l_info[DT_SYMTAB])
  42. return;
  43. {
  44. ElfW(Sym) *symtab = (void *) D_PTR (l_info[DT_SYMTAB]);
  45. ElfW(Word) nrelative = (l_info[RELCOUNT_IDX] == NULL
  46. ? 0 : l_info[RELCOUNT_IDX]->d_un.d_val);
  47. ElfW(Rel) *relative = r;
  48. r = r + MIN (nrelative, relsize / sizeof (ElfW(Rel)));
  49. if (do_rel_relative)
  50. #ifndef RTLD_BOOTSTRAP
  51. /* This is defined in rtld.c, but nowhere in the static libc.a; make
  52. the reference weak so static programs can still link. This
  53. declaration cannot be done when compiling rtld.c (i.e. #ifdef
  54. RTLD_BOOTSTRAP) because rtld.c contains the common defn for
  55. _dl_rtld_map, which is incompatible with a weak decl in the same
  56. file. */
  57. # if !defined DO_RELA || defined ELF_MACHINE_REL_RELATIVE
  58. /* Rela platforms get the offset from r_addend and this must
  59. be copied in the relocation address. Therefore we can skip
  60. the relative relocations only if this is for rel
  61. relocations or rela relocations if they are computed as
  62. memory_loc += l_addr... */
  63. if (l_addr != 0)
  64. # else
  65. /* ...or we know the object has been prelinked. */
  66. if (l_addr != 0 || !l_info[VALIDX(DT_GNU_PRELINKED)])
  67. # endif
  68. #endif
  69. for (; relative < r; ++relative)
  70. DO_ELF_MACHINE_REL_RELATIVE (l_addr, relative);
  71. for (; r < end; ++r)
  72. elf_machine_rel (l_info, l_addr, r,
  73. &symtab[ELFW(R_SYM) (r->r_info)],
  74. (void *) (l_addr + r->r_offset),
  75. do_rel, do_rel_relative);
  76. }
  77. }
  78. #undef elf_dynamic_do_rel
  79. #undef Rel
  80. #undef elf_machine_rel
  81. #undef elf_machine_rel_relative
  82. #undef DO_ELF_MACHINE_REL_RELATIVE
  83. #undef RELCOUNT_IDX