1 /* Copyright (C) 1999, 2000, 2001 Free Software Foundation, Inc.
2 This file is part of the GNU C Library.
4 The GNU C Library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Lesser General Public
6 License as published by the Free Software Foundation; either
7 version 2.1 of the License, or (at your option) any later version.
9 The GNU C Library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Lesser General Public License for more details.
14 You should have received a copy of the GNU Lesser General Public
15 License along with the GNU C Library; if not, write to the Free
16 Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
22 #include <sys/types.h>
27 #define NUM_SHARED_OBJECTS 32
29 int _dl_numso
= NUM_SHARED_OBJECTS
;
30 DL_SODATA
*_dl_sotable
= NULL
;
33 _dl_open (const char *file
, int mode
, const void *caller
)
38 int bsize
= _dl_numso
* sizeof (DL_INFO
);
39 DL_INFO
*dl_info
= malloc (bsize
);
44 /* 1st time thru initial shared object data table. */
45 if (_dl_sotable
== NULL
)
47 _dl_sotable
= (DL_SODATA
*) calloc (_dl_numso
, sizeof (DL_SODATA
));
48 if (_dl_sotable
== NULL
)
51 __loadx (DL_POSTLOADQ
, dl_info
, bsize
, NULL
);
52 while (!(dl_info
[0].dlinfo_xflags
& DL_INFO_OK
)
53 || dl_info
[0].dlinfo_arraylen
== 0)
56 dl_info
= realloc (dl_info
, bsize
);
60 __loadx (DL_POSTLOADQ
, dl_info
, bsize
, NULL
);
64 /* Validate mode bits. */
65 if (!(mode
& RTLD_NOW
) && !(mode
& RTLD_LAZY
))
72 /* Load the module. */
73 handle
= (void *) __loadx (DL_LOAD
| DL_LOAD_RTL
| DL_LOAD_LDX1
,
74 dl_info
, bsize
, file
, NULL
);
82 /* Was dl_info buffer to small to get info. */
83 while (!(dl_info
[0].dlinfo_xflags
& DL_INFO_OK
)
84 || dl_info
[0].dlinfo_arraylen
== 0)
87 dl_info
= realloc (dl_info
, bsize
);
90 (void) __unload ((void *) handle
);
94 __loadx (DL_POSTLOADQ
| DL_LOAD_RTL
, dl_info
, bsize
, handle
);
97 /* Get an empty entry in the shared object table. */
98 for (entry
= 0; entry
< _dl_numso
; ++entry
)
99 if (_dl_sotable
[entry
].type
== 0)
102 /* See if the table needs to be increased. */
103 if (entry
== _dl_numso
)
105 new_so
= (DL_SODATA
*) realloc (_dl_sotable
,
106 _dl_numso
* 2 * sizeof (DL_SODATA
));
110 memset (new_so
+ _dl_numso
, '\0', _dl_numso
* sizeof (DL_SODATA
));
112 _dl_sotable
= new_so
;
115 /* See if this is syscall (look for /unix in file). */
116 if (strcmp ("/unix", file
) == 0)
118 _dl_sotable
[entry
].index
= dl_info
[1].dlinfo_index
;
119 _dl_sotable
[entry
].dataorg
= dl_info
[1].dlinfo_dataorg
;
120 _dl_sotable
[entry
].handle
= handle
;
121 _dl_sotable
[entry
].type
= DL_UNIX_SYSCALL
;
125 _dl_sotable
[entry
].index
= dl_info
[1].dlinfo_index
;
126 _dl_sotable
[entry
].dataorg
= dl_info
[1].dlinfo_dataorg
;
127 _dl_sotable
[entry
].handle
= handle
;
128 _dl_sotable
[entry
].type
= DL_GETSYM
;
132 return (void *) entry
;