elf-x86_64.h 2.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  1. /* Copyright (C) 2014 Stony Brook University
  2. This file is part of Graphene Library OS.
  3. Graphene Library OS is free software: you can redistribute it and/or
  4. modify it under the terms of the GNU Lesser General Public License
  5. as published by the Free Software Foundation, either version 3 of the
  6. License, or (at your option) any later version.
  7. Graphene Library OS is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. GNU Lesser General Public License for more details.
  11. You should have received a copy of the GNU Lesser General Public License
  12. along with this program. If not, see <http://www.gnu.org/licenses/>. */
  13. /*
  14. * dl-machine-x86_64.h
  15. *
  16. * This files contain architecture-specific implementation of ELF dynamic
  17. * relocation function.
  18. * The source code is imported and modified from the GNU C Library.
  19. */
  20. #define ELF_MACHINE_NAME "x86_64"
  21. #include <sysdep.h>
  22. #include <sysdeps/generic/ldsodefs.h>
  23. #include "pal_internal.h"
  24. /* Return the link-time address of _DYNAMIC. Conveniently, this is the
  25. first element of the GOT. This must be inlined in a function which
  26. uses global data. */
  27. static inline Elf64_Addr __attribute__((unused)) elf_machine_dynamic(void) {
  28. /* This works because we have our GOT address available in the small PIC
  29. model. */
  30. return (Elf64_Addr)&_DYNAMIC;
  31. }
  32. /* Return the run-time load address of the shared object. */
  33. static inline Elf64_Addr __attribute__((unused)) elf_machine_load_address(void) {
  34. Elf64_Addr addr;
  35. /* The easy way is just the same as on x86:
  36. leaq _dl_start, %0
  37. leaq _dl_start(%%rip), %1
  38. subq %0, %1
  39. but this does not work with binutils since we then have
  40. a R_X86_64_32S relocation in a shared lib.
  41. Instead we store the address of _dl_start in the data section
  42. and compare it with the current value that we can get via
  43. an RIP relative addressing mode. Note that this is the address
  44. of _dl_start before any relocation performed at runtime. In case
  45. the binary is prelinked the resulting "address" is actually a
  46. load offset which is zero if the binary was loaded at the address
  47. it is prelinked for. */
  48. __asm__(
  49. "leaq " XSTRINGIFY(_ENTRY) "(%%rip), %0\n\t"
  50. "subq 1f(%%rip), %0\n\t"
  51. ".section\t.data.rel.ro\n"
  52. "1:\t.quad " XSTRINGIFY(_ENTRY) "\n\t"
  53. ".previous\n\t"
  54. : "=r"(addr)
  55. :
  56. : "cc");
  57. return addr;
  58. }