dl-start.S 2.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. /* Machine-dependent ELF startup code. OpenRISC version.
  2. Copyright (C) 2022-2026 Free Software Foundation, Inc.
  3. This file is part of the GNU C Library.
  4. The GNU C Library is free software; you can redistribute it and/or
  5. modify it under the terms of the GNU Lesser General Public
  6. License as published by the Free Software Foundation; either
  7. version 2.1 of the License, or (at your option) any later version.
  8. The GNU C Library is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  11. Lesser General Public License for more details.
  12. You should have received a copy of the GNU Lesser General Public
  13. License along with the GNU C Library; if not, see
  14. <https://www.gnu.org/licenses/>. */
  15. #include <sysdep.h>
  16. /* Initial entry point code for the dynamic linker.
  17. The function _dl_start is the real entry point;
  18. it's return value is the user program's entry point. */
  19. ENTRY (_start)
  20. /* Count arguments in r11 */
  21. l.ori r3, r1, 0
  22. l.movhi r11, 0
  23. 1:
  24. l.addi r3, r3, 4
  25. l.lwz r12, 0(r3)
  26. l.sfnei r12, 0
  27. l.addi r11, r11, 1
  28. l.bf 1b
  29. l.nop
  30. l.addi r11, r11, -1
  31. /* store argument counter to stack. */
  32. l.sw 0(r1), r11
  33. /* Load the PIC register. */
  34. l.jal 0x8
  35. l.movhi r16, gotpchi(_GLOBAL_OFFSET_TABLE_-4)
  36. l.ori r16, r16, gotpclo(_GLOBAL_OFFSET_TABLE_+0)
  37. l.add r16, r16, r9
  38. l.ori r3, r1, 0
  39. l.jal _dl_start
  40. l.nop
  41. /* Save user entry in a call saved reg. */
  42. l.ori r22, r11, 0
  43. /* Fall through to _dl_start_user. */
  44. _dl_start_user:
  45. /* Set up for _dl_init. */
  46. /* Load _rtld_local (a.k.a _dl_loaded). */
  47. l.lwz r12, got(_rtld_local)(r16)
  48. l.lwz r3, 0(r12)
  49. /* Load argc */
  50. l.lwz r18, got(_dl_argc)(r16)
  51. l.lwz r4, 0(r18)
  52. /* Load argv */
  53. l.lwz r20, got(_dl_argv)(r16)
  54. l.lwz r5, 0(r20)
  55. /* Load envp = &argv[argc + 1]. */
  56. l.slli r6, r4, 2
  57. l.addi r6, r6, 4
  58. l.add r6, r6, r5
  59. l.jal plt(_dl_init)
  60. l.nop
  61. /* Now set up for user entry.
  62. The already defined ABI loads argc and argv from the stack.
  63. argc = 0(r1)
  64. argv = r1 + 4
  65. */
  66. /* Load SP as argv - 4. */
  67. l.lwz r3, 0(r20)
  68. l.addi r1, r3, -4
  69. /* Save argc. */
  70. l.lwz r3, 0(r18)
  71. l.sw 0(r1), r3
  72. /* Pass _dl_fini function address to _start.
  73. Next start.S will then pass this as rtld_fini to __libc_start_main. */
  74. l.lwz r3, got(_dl_fini)(r16)
  75. l.jr r22
  76. l.nop
  77. END (_start)