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