1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20: #include <stddef.h>
21: #include <ldsodefs.h>
22:
23:
24:
25: typedef void (*init_t) (int, char **, char **);
26:
27: #ifndef HAVE_INLINED_SYSCALLS
28:
29: extern int _dl_starting_up;
30: extern int _dl_starting_up_internal attribute_hidden;
31: #endif
32:
33:
34: static void
35: call_init (struct link_map *l, int argc, char **argv, char **env)
36: {
37: if (l->l_init_called)
38:
39: return;
40:
41:
42:
43: l->l_init_called = 1;
44:
45:
46: if (__builtin_expect (l->l_name[0], 'a') == '\0'
47: && l->l_type == lt_executable)
48: return;
49:
50:
51: if (l->l_info[DT_INIT] == NULL
52: && __builtin_expect (l->l_info[DT_INIT_ARRAY] == NULL, 1))
53: return;
54:
55:
56: if (__builtin_expect (GLRO(dl_debug_mask) & DL_DEBUG_IMPCALLS, 0))
57: _dl_debug_printf ("\ncalling init: %s\n\n",
58: l->l_name[0] ? l->l_name : rtld_progname);
59:
60:
61:
62:
63:
64: if (l->l_info[DT_INIT] != NULL)
65: {
66: init_t init = (init_t) DL_DT_INIT_ADDRESS
67: (l, l->l_addr + l->l_info[DT_INIT]->d_un.d_ptr);
68:
69:
70: init (argc, argv, env);
71: }
72:
73:
74: ElfW(Dyn) *init_array = l->l_info[DT_INIT_ARRAY];
75: if (init_array != NULL)
76: {
77: unsigned int j;
78: unsigned int jm;
79: ElfW(Addr) *addrs;
80:
81: jm = l->l_info[DT_INIT_ARRAYSZ]->d_un.d_val / sizeof (ElfW(Addr));
82:
83: addrs = (ElfW(Addr) *) (init_array->d_un.d_ptr + l->l_addr);
84: for (j = 0; j < jm; ++j)
85: ((init_t) addrs[j]) (argc, argv, env);
86: }
87: }
88:
89:
90: void
91: internal_function
92: _dl_init (struct link_map *main_map, int argc, char **argv, char **env)
93: {
94: ElfW(Dyn) *preinit_array = main_map->l_info[DT_PREINIT_ARRAY];
95: ElfW(Dyn) *preinit_array_size = main_map->l_info[DT_PREINIT_ARRAYSZ];
96: unsigned int i;
97:
98: if (__builtin_expect (GL(dl_initfirst) != NULL, 0))
99: {
100: call_init (GL(dl_initfirst), argc, argv, env);
101: GL(dl_initfirst) = NULL;
102: }
103:
104:
105: if (__builtin_expect (preinit_array != NULL, 0)
106: && preinit_array_size != NULL
107: && (i = preinit_array_size->d_un.d_val / sizeof (ElfW(Addr))) > 0)
108: {
109: ElfW(Addr) *addrs;
110: unsigned int cnt;
111:
112: if (__builtin_expect (GLRO(dl_debug_mask) & DL_DEBUG_IMPCALLS, 0))
113: _dl_debug_printf ("\ncalling preinit: %s\n\n",
114: main_map->l_name[0]
115: ? main_map->l_name : rtld_progname);
116:
117: addrs = (ElfW(Addr) *) (preinit_array->d_un.d_ptr + main_map->l_addr);
118: for (cnt = 0; cnt < i; ++cnt)
119: ((init_t) addrs[cnt]) (argc, argv, env);
120: }
121:
122:
123:
124:
125:
126:
127:
128:
129:
130:
131:
132: i = main_map->l_searchlist.r_nlist;
133: while (i-- > 0)
134: call_init (main_map->l_initfini[i], argc, argv, env);
135:
136: #ifndef HAVE_INLINED_SYSCALLS
137:
138: INTUSE(_dl_starting_up) = 0;
139: #endif
140: }
141: INTDEF (_dl_init)