]>
Commit | Line | Data |
---|---|---|
052b6a6c | 1 | /* Machine-dependent ELF startup code. PowerPC version. |
b168057a | 2 | Copyright (C) 1995-2015 Free Software Foundation, Inc. |
052b6a6c UD |
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 | |
41bdb6e2 AJ |
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. | |
052b6a6c UD |
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 | |
41bdb6e2 | 13 | Lesser General Public License for more details. |
052b6a6c | 14 | |
41bdb6e2 | 15 | You should have received a copy of the GNU Lesser General Public |
59ba27a6 PE |
16 | License along with the GNU C Library; if not, see |
17 | <http://www.gnu.org/licenses/>. */ | |
052b6a6c UD |
18 | |
19 | #include <sysdep.h> | |
20 | ||
21 | /* Initial entry point code for the dynamic linker. | |
22 | The C function `_dl_start' is the real entry point; | |
23 | its return value is the user program's entry point. */ | |
24 | ENTRY(_start) | |
25 | /* We start with the following on the stack, from top: | |
26 | argc (4 bytes); | |
27 | arguments for program (terminated by NULL); | |
28 | environment variables (terminated by NULL); | |
29 | arguments for the program loader. */ | |
30 | ||
31 | /* Call _dl_start with one parameter pointing at argc */ | |
217eb19b | 32 | mr r3,r1 |
052b6a6c UD |
33 | /* (we have to frob the stack pointer a bit to allow room for |
34 | _dl_start to save the link register). */ | |
217eb19b UD |
35 | li r4,0 |
36 | addi r1,r1,-16 | |
37 | stw r4,0(r1) | |
052b6a6c UD |
38 | bl _dl_start@local |
39 | ||
5a59a3a5 | 40 | /* FALLTHRU */ |
9759bbf1 | 41 | _dl_start_user: |
052b6a6c UD |
42 | /* Now, we do our main work of calling initialisation procedures. |
43 | The ELF ABI doesn't say anything about parameters for these, | |
44 | so we just pass argc, argv, and the environment. | |
45 | Changing these is strongly discouraged (not least because argc is | |
46 | passed by value!). */ | |
47 | ||
48 | /* Put our GOT pointer in r31, */ | |
91d2a845 WS |
49 | SETUP_GOT_ACCESS(r31,got_label) |
50 | addis r31,r31,_GLOBAL_OFFSET_TABLE_-got_label@ha | |
51 | addi r31,r31,_GLOBAL_OFFSET_TABLE_-got_label@l | |
052b6a6c | 52 | /* the address of _start in r30, */ |
217eb19b | 53 | mr r30,r3 |
5a59a3a5 | 54 | /* &_dl_argc in 29, &_dl_argv in 27, and _dl_loaded in 28. */ |
37fb1dc0 | 55 | lwz r28,_rtld_local@got(r31) |
217eb19b | 56 | lwz r29,_dl_argc@got(r31) |
4243cbea | 57 | lwz r27,__GI__dl_argv@got(r31) |
5a59a3a5 | 58 | |
b6299091 | 59 | /* Call _dl_init (_dl_loaded, _dl_argc, _dl_argv, _dl_argv+_dl_argc+1). */ |
217eb19b | 60 | lwz r3,0(r28) |
5a59a3a5 GK |
61 | lwz r4,0(r29) |
62 | lwz r5,0(r27) | |
63 | slwi r6,r4,2 | |
64 | add r6,r5,r6 | |
65 | addi r6,r6,4 | |
c5684fdb | 66 | bl _dl_init@local |
ec215d43 | 67 | |
052b6a6c UD |
68 | /* Now, to conform to the ELF ABI, we have to: */ |
69 | /* Pass argc (actually _dl_argc) in r3; */ | |
217eb19b | 70 | lwz r3,0(r29) |
052b6a6c | 71 | /* pass argv (actually _dl_argv) in r4; */ |
217eb19b | 72 | lwz r4,0(r27) |
052b6a6c | 73 | /* pass envp (actually _dl_argv+_dl_argc+1) in r5; */ |
217eb19b UD |
74 | slwi r5,r3,2 |
75 | add r6,r4,r5 | |
76 | addi r5,r6,4 | |
2ccdea26 | 77 | /* pass the auxiliary vector in r6. This is passed to us just after _envp. */ |
217eb19b UD |
78 | 2: lwzu r0,4(r6) |
79 | cmpwi r0,0 | |
052b6a6c | 80 | bne 2b |
217eb19b | 81 | addi r6,r6,4 |
052b6a6c | 82 | /* Pass a termination function pointer (in this case _dl_fini) in r7. */ |
217eb19b | 83 | lwz r7,_dl_fini@got(r31) |
052b6a6c | 84 | /* Now, call the start function in r30... */ |
217eb19b | 85 | mtctr r30 |
052b6a6c UD |
86 | /* Pass the stack pointer in r1 (so far so good), pointing to a NULL value. |
87 | (This lets our startup code distinguish between a program linked statically, | |
88 | which linux will call with argc on top of the stack which will hopefully | |
89 | never be zero, and a dynamically linked program which will always have | |
90 | a NULL on the top of the stack). | |
91 | Take the opportunity to clear LR, so anyone who accidentally returns | |
92 | from _start gets SEGV. Also clear the next few words of the stack. */ | |
93 | ||
9759bbf1 | 94 | _dl_main_dispatch: |
217eb19b UD |
95 | li r31,0 |
96 | stw r31,0(r1) | |
97 | mtlr r31 | |
98 | stw r31,4(r1) | |
99 | stw r31,8(r1) | |
100 | stw r31,12(r1) | |
052b6a6c UD |
101 | /* Go do it! */ |
102 | bctr | |
103 | END(_start) |