elf-x86_64.h 2.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  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 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 Lesser 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 Lesser General Public License for more details.
  13. You should have received a copy of the GNU Lesser General Public License
  14. along with this program. If not, see <http://www.gnu.org/licenses/>. */
  15. /*
  16. * dl-machine-x86_64.h
  17. *
  18. * This files contain architecture-specific implementation of ELF dynamic
  19. * relocation function.
  20. * The source code is imported and modified from the GNU C Library.
  21. */
  22. #define ELF_MACHINE_NAME "x86_64"
  23. #include <sysdep.h>
  24. #include <sysdeps/generic/ldsodefs.h>
  25. #include "pal_internal.h"
  26. /* Return the link-time address of _DYNAMIC. Conveniently, this is the
  27. first element of the GOT. This must be inlined in a function which
  28. uses global data. */
  29. static inline Elf64_Addr __attribute__ ((unused))
  30. elf_machine_dynamic (void)
  31. {
  32. /* This works because we have our GOT address available in the small PIC
  33. model. */
  34. return (Elf64_Addr) &_DYNAMIC;
  35. }
  36. /* Return the run-time load address of the shared object. */
  37. static inline Elf64_Addr __attribute__ ((unused))
  38. elf_machine_load_address (void)
  39. {
  40. Elf64_Addr addr;
  41. /* The easy way is just the same as on x86:
  42. leaq _dl_start, %0
  43. leaq _dl_start(%%rip), %1
  44. subq %0, %1
  45. but this does not work with binutils since we then have
  46. a R_X86_64_32S relocation in a shared lib.
  47. Instead we store the address of _dl_start in the data section
  48. and compare it with the current value that we can get via
  49. an RIP relative addressing mode. Note that this is the address
  50. of _dl_start before any relocation performed at runtime. In case
  51. the binary is prelinked the resulting "address" is actually a
  52. load offset which is zero if the binary was loaded at the address
  53. it is prelinked for. */
  54. asm ("leaq " XSTRINGIFY(_ENTRY) "(%%rip), %0\n\t"
  55. "subq 1f(%%rip), %0\n\t"
  56. ".section\t.data.rel.ro\n"
  57. "1:\t.quad " XSTRINGIFY(_ENTRY) "\n\t"
  58. ".previous\n\t"
  59. : "=r" (addr) : : "cc");
  60. return addr;
  61. }