OSDN Git Service

ldso: mark _start hidden
[uclinux-h8/uClibc.git] / ldso / ldso / bfin / dl-startup.h
1      /* Copyright (C) 2003 Red Hat, Inc.
2         Contributed by Alexandre Oliva <aoliva@redhat.com>
3
4 This file is part of uClibc.
5
6 uClibc is free software; you can redistribute it and/or modify it
7 under the terms of the GNU Lesser General Public License as
8 published by the Free Software Foundation; either version 2.1 of the
9 License, or (at your option) any later version.
10
11 uClibc is distributed in the hope that it will be useful, but WITHOUT
12 ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 Library General Public License for more details.
15
16 You should have received a copy of the GNU Lesser General Public
17 License along with uClibc; see the file COPYING.LIB.  If not, write to
18 the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139,
19 USA.  */
20
21 /* Any assembly language/system dependent hacks needed to setup
22  * boot1.c so it will work as expected and cope with whatever platform
23  * specific wierdness is needed for this architecture.
24  */
25
26 /* At program start-up, p0 contains a pointer to a
27    elf32_fdpic_loadmap that describes how the executable was loaded
28    into memory.  p1 contains a pointer to the interpreter (our!)
29    loadmap, if there is an interpreter, or 0 if we're being run as an
30    executable.  p2 holds a pointer to the interpreter's dynamic
31    section, if there is an interpreter, or to the executable's dynamic
32    section, otherwise.  If the executable is not dynamic, gr18 is 0.
33
34    We rely on the fact that the linker adds a pointer to the
35    _GLOBAL_OFFSET_TABLE_ as the last ROFIXUP entry, and that
36    __self_reloc returns the relocated pointer to us, so that we can
37    use this value to initialize the PIC register.  */
38
39 __asm__(
40         "       .text\n"
41         "       .global __start\n"
42         "       .type   __start,@function\n"
43         /* Build system expects a "_start" for the entry point;
44            provide it as it's free to do so with aliases.  */
45         "       .hidden __start\n"
46         "       .set    _start, __start\n"
47         "       .global _start\n"
48         "       .hidden _start\n"
49         "__start:\n"
50         "       call    .Lcall\n"
51         ".Lcall:\n"
52         "       R4 = RETS;\n"
53         "       SP += -32;\n"
54         "       R5 = P0;\n"
55         "       R6 = P1;\n"
56         "       R7 = P2;\n"
57         "       R0.L = .Lcall;\n"
58         "       R0.H = .Lcall;\n"
59         "       R1.L = __ROFIXUP_LIST__;\n"
60         "       R1.H = __ROFIXUP_LIST__;\n"
61         "       R2.L = __ROFIXUP_END__;\n"
62         "       R2.H = __ROFIXUP_END__;\n"
63         "       R1 = R1 - R0;\n"
64         "       R1 = R1 + R4;\n"
65         "       R2 = R2 - R0;\n"
66         "       R2 = R2 + R4;\n"
67         "       R0 = P1;\n"
68         "       CC = R0 == 0;\n"
69         "       IF CC R0 = P0;\n"
70         "       CALL    ___self_reloc;\n"
71         "       P3 = R0;\n"
72         "       P5 = R0;\n"
73         "       R1 = R5;\n"
74         "       R2 = R6;\n"
75         "       [SP + 12] = R7;\n"
76         "       P0 = SP;\n"
77         "       P0 += 24;\n"
78         "       [SP + 16] = P0;\n"
79         "       P0 += 8;\n"
80         "       [SP + 20] = P0;\n"
81         "       CALL    __dl_start;\n"
82         "       /* Pass our FINI ptr() to the user in P1 */\n"
83         "       R7 = [P5 + __dl_fini@FUNCDESC_GOT17M4];\n"
84         "       P4 = [SP + 24];\n"
85         "       P3 = [SP + 28];\n"
86         "       P0 = R5;\n"
87         "       SP += 32;\n"
88         "       JUMP (P4);\n"
89         "       .size   __start,.-__start\n"
90 );
91
92 #undef DL_START
93 #define DL_START(X)   \
94 static void  __attribute__ ((used)) \
95 _dl_start (Elf32_Addr dl_boot_got_pointer, \
96            struct elf32_fdpic_loadmap *dl_boot_progmap, \
97            struct elf32_fdpic_loadmap *dl_boot_ldsomap, \
98            Elf32_Dyn *dl_boot_ldso_dyn_pointer, \
99            struct funcdesc_value *dl_main_funcdesc, \
100            X)
101
102 /*
103  * Get a pointer to the argv array.  On many platforms this can be just
104  * the address of the first argument, on other platforms we need to
105  * do something a little more subtle here.
106  */
107 #define GET_ARGV(ARGVP, ARGS) ARGVP = (((unsigned long*) ARGS) + 1)
108
109 /*
110  * Here is a macro to perform a relocation.  This is only used when
111  * bootstrapping the dynamic loader.  RELP is the relocation that we
112  * are performing, REL is the pointer to the address we are relocating.
113  * SYMBOL is the symbol involved in the relocation, and LOAD is the
114  * load address.
115  */
116 #define PERFORM_BOOTSTRAP_RELOC(RELP,REL,SYMBOL,LOAD,SYMTAB) \
117         switch(ELF_R_TYPE((RELP)->r_info)){                             \
118         case R_BFIN_BYTE4_DATA:                                                 \
119           *(REL) += (SYMBOL);                                           \
120           break;                                                        \
121         case R_BFIN_FUNCDESC_VALUE:                                     \
122           {                                                             \
123             struct funcdesc_value fv = {                                \
124               (void*)((SYMBOL) + *(REL)),                               \
125               (LOAD).got_value                                          \
126             };                                                          \
127             *(struct funcdesc_value volatile *)(REL) = fv;              \
128             break;                                                      \
129           }                                                             \
130         default:                                                        \
131           _dl_exit(1);                                                  \
132         }
133
134 /*
135  * Transfer control to the user's application, once the dynamic loader
136  * is done.  We return the address of the function's entry point to
137  * _dl_boot, see boot1_arch.h.
138  */
139 #define START() do {                                                    \
140   struct elf_resolve *exec_mod = _dl_loaded_modules;                    \
141   dl_main_funcdesc->entry_point = _dl_elf_main;                         \
142   while (exec_mod->libtype != elf_executable)                           \
143     exec_mod = exec_mod->next;                                          \
144   dl_main_funcdesc->got_value = exec_mod->loadaddr.got_value;           \
145   return;                                                               \
146 } while (0)