dl-startup.h 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. /*
  2. * Architecture specific code used by dl-startup.c
  3. * Copyright (C) 2019 Waldemar Brodkorb <wbx@uclibc-ng.org>
  4. * Ported from GNU libc
  5. * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
  6. */
  7. /* Copyright (C) 2011-2019 Free Software Foundation, Inc.
  8. The GNU C Library is free software; you can redistribute it and/or
  9. modify it under the terms of the GNU Lesser General Public License as
  10. published by the Free Software Foundation; either version 2.1 of the
  11. License, or (at your option) any later version.
  12. The GNU C Library is distributed in the hope that it will be useful,
  13. but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  15. Lesser General Public License for more details.
  16. You should have received a copy of the GNU Lesser General Public
  17. License along with the GNU C Library; if not, see
  18. <https://www.gnu.org/licenses/>. */
  19. #include <features.h>
  20. #include <sys/asm.h>
  21. #ifndef _RTLD_PROLOGUE
  22. # define _RTLD_PROLOGUE(entry) \
  23. ".globl\t" __STRING (entry) "\n\t" \
  24. ".type\t" __STRING (entry) ", @function\n" \
  25. __STRING (entry) ":\n\t"
  26. #endif
  27. #ifndef _RTLD_EPILOGUE
  28. # define _RTLD_EPILOGUE(entry) \
  29. ".size\t" __STRING (entry) ", . - " __STRING (entry) "\n\t"
  30. #endif
  31. #define STRINGXP(X) __STRING (X)
  32. __asm__(\
  33. ".text\n\
  34. " _RTLD_PROLOGUE (_start) "\
  35. mv a0, sp\n\
  36. jal _dl_start\n\
  37. # Stash user entry point in s0.\n\
  38. mv s0, a0\n\
  39. # See if we were run as a command with the executable file\n\
  40. # name as an extra leading argument.\n\
  41. lw a0, _dl_skip_args\n\
  42. # Load the original argument count.\n\
  43. " STRINGXP (REG_L) " a1, 0(sp)\n\
  44. # Subtract _dl_skip_args from it.\n\
  45. sub a1, a1, a0\n\
  46. # Adjust the stack pointer to skip _dl_skip_args words.\n\
  47. sll a0, a0, " STRINGXP (PTRLOG) "\n\
  48. add sp, sp, a0\n\
  49. # Save back the modified argument count.\n\
  50. " STRINGXP (REG_S) " a1, 0(sp)\n\
  51. # Pass our finalizer function to _start.\n\
  52. lla a0, _dl_fini\n\
  53. # Jump to the user entry point.\n\
  54. jr s0\n\
  55. " _RTLD_EPILOGUE (_start) "\
  56. .previous" \
  57. );
  58. /* Get a pointer to the argv array. On many platforms this can be just
  59. * the address of the first argument, on other platforms we need to
  60. * do something a little more subtle here. */
  61. #define GET_ARGV(ARGVP, ARGS) ARGVP = (((unsigned long*)ARGS)+1)
  62. /* Function calls are not safe until the GOT relocations have been done. */
  63. #define NO_FUNCS_BEFORE_BOOTSTRAP
  64. /* Handle relocation of the symbols in the dynamic loader. */
  65. static __always_inline
  66. void PERFORM_BOOTSTRAP_RELOC(ELF_RELOC *rpnt, ElfW(Addr) *reloc_addr,
  67. ElfW(Addr) symbol_addr, ElfW(Addr) load_addr, ElfW(Addr) *sym)
  68. {
  69. switch (ELF_R_TYPE(rpnt->r_info)) {
  70. case R_RISCV_NONE:
  71. break;
  72. case R_RISCV_JUMP_SLOT:
  73. *reloc_addr = symbol_addr + rpnt->r_addend;
  74. break;
  75. default:
  76. _dl_exit(1);
  77. }
  78. }