~ubuntu-branches/ubuntu/precise/eglibc/precise-201308281639

« back to all changes in this revision

Viewing changes to ports/sysdeps/unix/sysv/aix/start-libc.c

  • Committer: Package Import Robot
  • Author(s): Matthias Klose
  • Date: 2012-02-08 01:58:09 UTC
  • mfrom: (1.5.3) (288.1.12 precise)
  • Revision ID: package-import@ubuntu.com-20120208015809-ulscst7uteq3e22z
Tags: 2.15~pre6-0ubuntu10
Merge from Debian (r5151, 2.13-26).

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* Initialization code run first thing by the XCOFF startup code.  AIX version.
2
 
   Copyright (C) 2001, 2002 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, write to the Free
17
 
   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
18
 
   02111-1307 USA.  */
19
 
 
20
 
#include <stdlib.h>
21
 
#include <unistd.h>
22
 
#include <sys/types.h>
23
 
 
24
 
/* hack to use uchar's */
25
 
typedef unsigned char uchar;
26
 
#include <xcoff.h>
27
 
#include <rtinit.h>
28
 
#include <dlldr.h>
29
 
#include <bits/libc-lock.h>
30
 
 
31
 
extern void __libc_init_first (int argc, char **argv, char **envp);
32
 
 
33
 
/* XXX disable for now
34
 
extern int __libc_multiple_libcs; */
35
 
 
36
 
/* XXX normally defined in generic/dl-sydep.c, hack it into existance
37
 
extern void *__libc_stack_end; */
38
 
void *__libc_stack_end;
39
 
 
40
 
struct __libc_start_data_rec
41
 
{
42
 
  void *stack;
43
 
  void *toc;
44
 
  int argc;
45
 
  char **argv;
46
 
  char **envp;
47
 
  char *data;
48
 
  char *text;
49
 
  unsigned int mcount;
50
 
  unsigned int special;
51
 
  int (*main) (int, char **, char **);
52
 
  void (*init) (void);
53
 
  void (*fini) (void);
54
 
  void (*rtld_fini) (void);
55
 
};
56
 
 
57
 
extern struct __libc_start_data_rec __libc_start_data;
58
 
extern int errno;
59
 
 
60
 
/* The first piece of initialized data.  */
61
 
int __data_start = 0;
62
 
 
63
 
#ifndef HAVE_ELF
64
 
/* Since gcc/crtstuff.c won't define it unless the ELF format is used
65
 
   we will need to define it here.  */
66
 
void *__dso_handle = NULL;
67
 
#endif
68
 
 
69
 
/* AIX kernel function */
70
 
extern int __loadx (int flag, void *module, void *arg1, void *arg2,
71
 
                    void *arg3);
72
 
/* Needed by setenv */
73
 
char  **__environ;
74
 
 
75
 
/*
76
 
   Find __rtinit symbol
77
 
 
78
 
   __RTINIT *find_rtinit()
79
 
 
80
 
   __RTINIT        *rti - pointer to __rtinit data structure
81
 
 */
82
 
 
83
 
static __RTINIT *
84
 
find_rtinit (void)
85
 
{
86
 
  struct xcoffhdr *xcoff_hdr;
87
 
  SCNHDR *sec_hdr;
88
 
  SCNHDR *ldr_sec_hdr;
89
 
  SCNHDR *data_sec_hdr;
90
 
  LDSYM *ldsym_hdr;
91
 
  __RTINIT *rtl;
92
 
 
93
 
  xcoff_hdr = (struct xcoffhdr *) __libc_start_data.text;
94
 
  sec_hdr = (SCNHDR *) ((caddr_t) &xcoff_hdr->aouthdr
95
 
                        + xcoff_hdr->filehdr.f_opthdr);
96
 
  ldr_sec_hdr = (SCNHDR *) (sec_hdr + (xcoff_hdr->aouthdr.o_snloader - 1));
97
 
  ldsym_hdr = (LDSYM  *) ((caddr_t)xcoff_hdr + ldr_sec_hdr->s_scnptr
98
 
                          + LDHDRSZ);
99
 
 
100
 
  if ( __libc_start_data.mcount <= 0)
101
 
    {
102
 
      if (!ldr_sec_hdr->s_scnptr)
103
 
        return (__RTINIT *) 0;
104
 
 
105
 
      if (memcmp (ldsym_hdr, RTINIT_NAME, sizeof (RTINIT_NAME) - 1))
106
 
        return (__RTINIT *) 0;
107
 
    }
108
 
 
109
 
  data_sec_hdr   = (SCNHDR *) (sec_hdr + (xcoff_hdr->aouthdr.o_sndata - 1));
110
 
  rtl = (__RTINIT *) (ldsym_hdr->l_value
111
 
                      + (__libc_start_data.data - data_sec_hdr->s_vaddr));
112
 
  return rtl;
113
 
}
114
 
 
115
 
/*
116
 
   The mod_init1 calls every initialization function for a given module.
117
 
 
118
 
    void mod_init1(handler, rti)
119
 
 
120
 
    void *handler - if NULL init funtions for modules loaded at exec time
121
 
                    are being executed. Otherwise, the handler points to the
122
 
                    module loaded.
123
 
 
124
 
    __RTINIT *rti - pointer to __rtinit data structure (with rti->init_offset
125
 
                    not equal to zero)
126
 
 */
127
 
 
128
 
static void
129
 
mod_init1 (void *handler,__RTINIT *rtl)
130
 
{
131
 
  __RTINIT_DESCRIPTOR  *descriptor;
132
 
 
133
 
  descriptor = (__RTINIT_DESCRIPTOR *) ((caddr_t) &rtl->rtl
134
 
                                        + rtl->init_offset);
135
 
  while (descriptor->f != NULL)
136
 
    {
137
 
      if (!(descriptor->flags & _RT_CALLED))
138
 
        {
139
 
          descriptor->flags |= _RT_CALLED;
140
 
          (descriptor->f) (handler, rtl, descriptor);  /* execute init/fini */
141
 
        }
142
 
      descriptor = (__RTINIT_DESCRIPTOR *) ((caddr_t) descriptor
143
 
                                            + rtl->__rtinit_descriptor_size);
144
 
    }
145
 
}
146
 
 
147
 
/* The modinit() function performs run-time linking, if enabled, and calling
148
 
   the init() function for all loaded modules.  */
149
 
 
150
 
#define DL_BUFFER_SIZE 1000
151
 
 
152
 
static int
153
 
modinit (void)
154
 
{
155
 
  int *handler = 0;
156
 
  __RTINIT *rtinit_info = 0;
157
 
  int flag;
158
 
  DL_INFO dl_buffer[DL_BUFFER_SIZE];
159
 
  DL_INFO *dl_info = dl_buffer;
160
 
  int i;
161
 
 
162
 
  /* Find __rtinit symbols */
163
 
  rtinit_info = find_rtinit ();
164
 
 
165
 
  flag = DL_EXECQ;
166
 
  if (rtinit_info && rtinit_info->rtl)
167
 
    flag |= DL_LOAD_RTL;
168
 
 
169
 
  /* Get a list of modules that have __rtinit */
170
 
  if (__loadx (flag, dl_info, (void *) sizeof (dl_buffer), NULL, NULL))
171
 
    exit (0x90);
172
 
 
173
 
  if (dl_info[0].dlinfo_xflags & DL_INFO_OK)
174
 
    {
175
 
      rtinit_info = find_rtinit ();
176
 
      if ((rtinit_info != NULL) & (rtinit_info->rtl != NULL))
177
 
        {
178
 
          if ((*rtinit_info->rtl) (dl_info, 0))
179
 
            exit (0x90);
180
 
        }
181
 
    }
182
 
 
183
 
  /* Initialization each module loaded that has __rtinit. */
184
 
  if (dl_info[0].dlinfo_xflags & DL_INFO_OK)
185
 
    {
186
 
      for (i = 1; i < dl_info[0].dlinfo_arraylen + 1; ++i)
187
 
        if (dl_info[i].dlinfo_flags & DL_HAS_RTINIT)
188
 
          {
189
 
            rtinit_info = find_rtini t();
190
 
            if (rtinit_info)
191
 
              mod_init1 (handler, rtinit_info);
192
 
          }
193
 
    }
194
 
 
195
 
  return 0;
196
 
}
197
 
 
198
 
 
199
 
void
200
 
__libc_start_init (void)
201
 
{
202
 
  /* Do run-time linking, if enabled and call the init()
203
 
     for all loaded modules. */
204
 
  if (__libc_start_data.mcount != __libc_start_data.special)
205
 
    modinit ();
206
 
}
207
 
 
208
 
/* For now these are just stubs. */
209
 
void
210
 
__libc_start_fini (void)
211
 
{
212
 
}
213
 
 
214
 
void
215
 
__libc_start_rtld_fini (void)
216
 
{
217
 
}
218
 
 
219
 
 
220
 
int
221
 
__libc_start_main (void)
222
 
{
223
 
  /* Store the lowest stack address.  */
224
 
  __libc_stack_end = __libc_start_data.stack;
225
 
 
226
 
  /* Used by setenv */
227
 
  __environ = __libc_start_data.envp;
228
 
 
229
 
#ifndef SHARED
230
 
  /* Clear errno. */
231
 
    errno = 0;
232
 
 
233
 
  /* Some security at this point.  Prevent starting a SUID binary where
234
 
     the standard file descriptors are not opened.  We have to do this
235
 
     only for statically linked applications since otherwise the dynamic
236
 
     loader did the work already.  */
237
 
  if (__builtin_expect (__libc_enable_secure, 0))
238
 
    __libc_check_standard_fds ();
239
 
 
240
 
#endif
241
 
 
242
 
  /* Register the destructor of the dynamic linker if there is any.  */
243
 
  if (__builtin_expect (__libc_start_data.rtld_fini != NULL, 1))
244
 
    __cxa_atexit ((void (*) (void *)) __libc_start_data.rtld_fini, NULL, NULL);
245
 
 
246
 
  /* Call the initializer of the libc.  This is only needed here if we
247
 
     are compiling for the static library in which case we haven't
248
 
     run the constructors in `_dl_start_user'.  */
249
 
#ifndef SHARED
250
 
  __libc_init_first (__libc_start_data.argc, __libc_start_data.argv,
251
 
                     __libc_start_data.envp);
252
 
#endif
253
 
 
254
 
  /* Register the destructor of the program, if any.  */
255
 
  if (__libc_start_data.fini)
256
 
    __cxa_atexit ((void (*) (void *)) __libc_start_data.fini, NULL, NULL);
257
 
 
258
 
  /* Call the initializer of the program, if any.  */
259
 
  if (__libc_start_data.init)
260
 
    (*__libc_start_data.init) ();
261
 
 
262
 
  exit ((*__libc_start_data.main) (__libc_start_data.argc,
263
 
                                   __libc_start_data.argv,
264
 
                                   __libc_start_data.envp));
265
 
}