1 /* $NetBSD: shlib.c,v 1.22 2008/04/28 20:23:03 martin Exp $ */
4 * Copyright (c) 1998 The NetBSD Foundation, Inc.
7 * This code is derived from software contributed to The NetBSD Foundation
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
37 #include <sys/param.h>
38 #include <sys/types.h>
42 #include <sys/exec_aout.h>
52 #include <link_aout.h>
57 * Standard directories to search for files specified by -l.
59 #ifndef STANDARD_SEARCH_DIRS
60 #define STANDARD_SEARCH_DIRS "/usr/lib"
64 * Actual vector of library search directories,
65 * including `-L'ed and LD_LIBRARY_PATH spec'd ones.
70 const char *standard_search_dirs
[] = {
79 search_dirs
= (char **)
80 xrealloc(search_dirs
, n_search_dirs
* sizeof search_dirs
[0]);
81 search_dirs
[n_search_dirs
- 2] = strdup(name
);
82 search_dirs
[n_search_dirs
- 1] =
83 xmalloc(sizeof(_PATH_EMUL_AOUT
) + strlen(name
));
84 strcpy(search_dirs
[n_search_dirs
- 1], _PATH_EMUL_AOUT
);
85 strcat(search_dirs
[n_search_dirs
- 1], name
);
89 remove_search_dir(name
)
94 for (n
= 0; n
< n_search_dirs
; n
++) {
95 if (strcmp(search_dirs
[n
], name
))
98 free(search_dirs
[n
+1]);
99 if (n
< (n_search_dirs
- 2))
100 bcopy(&search_dirs
[n
+2], &search_dirs
[n
],
101 (n_search_dirs
- n
- 2) * sizeof search_dirs
[0]);
107 add_search_path(path
)
110 register char *cp
, *dup
;
115 /* Add search directories from `path' */
116 path
= dup
= strdup(path
);
117 while ((cp
= strsep(&path
, ":")) != NULL
)
123 remove_search_path(path
)
126 register char *cp
, *dup
;
131 /* Remove search directories from `path' */
132 path
= dup
= strdup(path
);
133 while ((cp
= strsep(&path
, ":")) != NULL
)
134 remove_search_dir(cp
);
143 /* Append standard search directories */
144 n
= sizeof standard_search_dirs
/ sizeof standard_search_dirs
[0];
145 for (i
= 0; i
< n
; i
++)
146 add_search_dir(standard_search_dirs
[i
]);
150 * Return true if CP points to a valid dewey number.
151 * Decode and leave the result in the array DEWEY.
152 * Return the number of decoded entries in DEWEY.
162 for (n
= 0, i
= 0; i
< MAXDEWEY
; i
++) {
166 if (*cp
== '.') cp
++;
167 #ifdef SUNOS_LIB_COMPAT
170 if (!isdigit((unsigned char)*cp
))
174 dewey
[n
++] = strtol(cp
, &cp
, 10);
181 * Compare two dewey arrays.
182 * Return -1 if `d1' represents a smaller value than `d2'.
183 * Return 1 if `d1' represents a greater value than `d2'.
187 cmpndewey(d1
, n1
, d2
, n2
)
193 for (i
= 0; i
< n1
&& i
< n2
; i
++) {
209 errx(1, "cmpndewey: cant happen");
214 * Search directories for a shared library matching the given
215 * major and minor version numbers.
217 * MAJOR == -1 && MINOR == -1 --> find highest version
218 * MAJOR != -1 && MINOR == -1 --> find highest minor version
219 * MAJOR == -1 && MINOR != -1 --> invalid
220 * MAJOR != -1 && MINOR != -1 --> find highest micro version
223 /* Not interested in devices right now... */
228 findshlib(name
, majorp
, minorp
, do_dot_a
)
230 int *majorp
, *minorp
;
238 char *lname
, *path
= NULL
;
239 int major
= *majorp
, minor
= *minorp
;
241 len
= strlen(name
) + sizeof("lib");
242 #if defined(__SSP__) || defined(__SSP_ALL__)
243 lname
= xmalloc(len
);
248 sprintf(lname
, "lib%s", name
);
252 for (i
= 0; i
< n_search_dirs
; i
++) {
253 DIR *dd
= opendir(search_dirs
[i
]);
256 int found_dot_so
= 0;
261 while ((dp
= readdir(dd
)) != NULL
) {
267 if (do_dot_a
&& path
== NULL
&&
268 dp
->d_namlen
== len
+ 2 &&
269 strncmp(dp
->d_name
, lname
, len
) == 0 &&
270 (dp
->d_name
+len
)[0] == '.' &&
271 (dp
->d_name
+len
)[1] == 'a') {
273 path
= concat(search_dirs
[i
], "/", dp
->d_name
);
277 if (dp
->d_namlen
< len
+ 4)
279 if (strncmp(dp
->d_name
, lname
, len
) != 0)
281 if (strncmp(dp
->d_name
+len
, ".so.", 4) != 0)
284 if ((n
= getdewey(tmp
, dp
->d_name
+len
+4)) == 0)
287 if (major
!= -1 && found_dot_a
) { /* XXX */
293 /* verify the library is a.out */
294 xpath
= concat(search_dirs
[i
], "/", dp
->d_name
);
295 fp
= fopen(xpath
, "r");
300 if (sizeof(ex
) != fread(&ex
, 1, sizeof(ex
), fp
)) {
305 if (N_GETMAGIC(ex
) != ZMAGIC
306 || (N_GETFLAG(ex
) & EX_DYNAMIC
) == 0) {
310 if (major
== -1 && minor
== -1) {
311 goto compare_version
;
312 } else if (major
!= -1 && minor
== -1) {
314 goto compare_version
;
315 } else if (major
!= -1 && minor
!= -1) {
316 if (tmp
[0] == major
) {
317 if (n
== 1 || tmp
[1] >= minor
)
318 goto compare_version
;
322 /* else, this file does not qualify */
326 if (cmpndewey(tmp
, n
, dewey
, ndewey
) <= 0)
329 /* We have a better version */
333 path
= concat(search_dirs
[i
], "/", dp
->d_name
);
335 bcopy(tmp
, dewey
, sizeof(dewey
));
342 if (found_dot_a
|| found_dot_so
)
344 * There's a lib in this dir; take it.
348 #if defined(__SSP__) || defined(__SSP_ALL__)
356 * Utility functions shared with others.
361 * Like malloc but get fatal error if memory is exhausted.
367 void *result
= (void *)malloc(size
);
370 errx(1, "virtual memory exhausted");
376 * Like realloc but get fatal error if memory is exhausted.
385 result
= (ptr
== NULL
) ? malloc(size
) : realloc(ptr
, size
);
387 errx(1, "virtual memory exhausted");
393 * Return a newly-allocated string whose contents concatenate
394 * the strings S1, S2, S3.
398 const char *s1
, *s2
, *s3
;
400 int len1
= strlen(s1
),
404 char *result
= (char *)xmalloc(len1
+ len2
+ len3
+ 1);
407 strcpy(result
+ len1
, s2
);
408 strcpy(result
+ len1
+ len2
, s3
);
409 result
[len1
+ len2
+ len3
] = 0;