Changes from Paul Kranenburg which bring us into sync with his sources:
[unix-history] / gnu / usr.bin / ld / lib.c
CommitLineData
1136f72d 1/*
1c8a0fd5 2 * $Id: lib.c,v 1.9 1994/02/13 20:41:37 jkh Exp $ - library routines
1136f72d
PR
3 */
4
5#include <sys/param.h>
6#include <stdio.h>
7#include <stdlib.h>
1c8a0fd5 8#include <unistd.h>
1136f72d
PR
9#include <sys/types.h>
10#include <sys/stat.h>
11#include <sys/file.h>
12#include <sys/time.h>
1c8a0fd5 13#include <err.h>
1136f72d
PR
14#include <fcntl.h>
15#include <ar.h>
16#include <ranlib.h>
17#include <a.out.h>
18#include <stab.h>
19#include <string.h>
20#include <dirent.h>
1c8a0fd5 21#include <ctype.h>
1136f72d
PR
22
23#include "ld.h"
24
6a61ea88
JH
25static void linear_library __P((int, struct file_entry *));
26static void symdef_library __P((int, struct file_entry *, int));
27static struct file_entry *decode_library_subfile __P((int,
28 struct file_entry *,
29 int, int *));
1136f72d
PR
30
31/*
1c8a0fd5 32 * Search the library ENTRY, already open on descriptor FD. This means
1136f72d
PR
33 * deciding which library members to load, making a chain of `struct
34 * file_entry' for those members, and entering their global symbols in the
35 * hash table.
36 */
37
38void
1c8a0fd5
PR
39search_library(fd, entry)
40 int fd;
1136f72d
PR
41 struct file_entry *entry;
42{
43 int member_length;
44 register char *name;
45 register struct file_entry *subentry;
46
47 if (!(link_mode & FORCEARCHIVE) && !undefined_global_sym_count)
48 return;
49
50 /* Examine its first member, which starts SARMAG bytes in. */
1c8a0fd5 51 subentry = decode_library_subfile(fd, entry, SARMAG, &member_length);
1136f72d
PR
52 if (!subentry)
53 return;
54
55 name = subentry->filename;
56 free(subentry);
57
58 /* Search via __.SYMDEF if that exists, else linearly. */
59
60 if (!strcmp(name, "__.SYMDEF"))
1c8a0fd5 61 symdef_library(fd, entry, member_length);
1136f72d 62 else
1c8a0fd5 63 linear_library(fd, entry);
1136f72d
PR
64}
65
66/*
67 * Construct and return a file_entry for a library member. The library's
1c8a0fd5 68 * file_entry is library_entry, and the library is open on FD.
1136f72d
PR
69 * SUBFILE_OFFSET is the byte index in the library of this member's header.
70 * We store the length of the member into *LENGTH_LOC.
71 */
72
6a61ea88 73static struct file_entry *
1c8a0fd5
PR
74decode_library_subfile(fd, library_entry, subfile_offset, length_loc)
75 int fd;
1136f72d
PR
76 struct file_entry *library_entry;
77 int subfile_offset;
78 int *length_loc;
79{
80 int bytes_read;
81 register int namelen;
0f052032
JH
82 int member_length, content_length;
83 int starting_offset;
1136f72d
PR
84 register char *name;
85 struct ar_hdr hdr1;
86 register struct file_entry *subentry;
1558d71a 87
1c8a0fd5 88 lseek(fd, subfile_offset, 0);
1136f72d 89
1c8a0fd5 90 bytes_read = read(fd, &hdr1, sizeof hdr1);
1136f72d
PR
91 if (!bytes_read)
92 return 0; /* end of archive */
93
94 if (sizeof hdr1 != bytes_read)
1c8a0fd5
PR
95 errx(1, "%s: malformed library archive",
96 get_file_name(library_entry));
1136f72d
PR
97
98 if (sscanf(hdr1.ar_size, "%d", &member_length) != 1)
1c8a0fd5
PR
99 errx(1, "%s: malformatted header of archive member: %.*s",
100 get_file_name(library_entry),
101 sizeof(hdr1.ar_name), hdr1.ar_name);
1136f72d
PR
102
103 subentry = (struct file_entry *) xmalloc(sizeof(struct file_entry));
104 bzero(subentry, sizeof(struct file_entry));
105
106 for (namelen = 0;
107 namelen < sizeof hdr1.ar_name
108 && hdr1.ar_name[namelen] != 0 && hdr1.ar_name[namelen] != ' '
109 && hdr1.ar_name[namelen] != '/';
110 namelen++);
111
0f052032
JH
112 starting_offset = subfile_offset + sizeof hdr1;
113 content_length = member_length;
114
115#ifdef AR_EFMT1
116 /*
117 * BSD 4.4 extended AR format: #1/<namelen>, with name as the
118 * first <namelen> bytes of the file
119 */
6a61ea88
JH
120 if (strncmp(hdr1.ar_name, AR_EFMT1, sizeof(AR_EFMT1) - 1) == 0 &&
121 isdigit(hdr1.ar_name[sizeof(AR_EFMT1) - 1])) {
0f052032 122
6a61ea88 123 namelen = atoi(&hdr1.ar_name[sizeof(AR_EFMT1) - 1]);
0f052032 124 name = (char *)xmalloc(namelen + 1);
1c8a0fd5
PR
125 if (read(fd, name, namelen) != namelen)
126 errx(1, "%s: malformatted archive member: %.*s",
127 get_file_name(library_entry),
128 sizeof(hdr1.ar_name), hdr1.ar_name);
0f052032
JH
129 name[namelen] = 0;
130 content_length -= namelen;
131 starting_offset += namelen;
132 } else
133
134#endif
135 {
136 name = (char *)xmalloc(namelen + 1);
137 strncpy(name, hdr1.ar_name, namelen);
138 name[namelen] = 0;
139 }
1558d71a 140
1136f72d
PR
141 subentry->filename = name;
142 subentry->local_sym_name = name;
1c8a0fd5
PR
143 subentry->starting_offset = starting_offset;
144 subentry->superfile = library_entry;
145 subentry->total_size = content_length;
146#if 0
1136f72d
PR
147 subentry->symbols = 0;
148 subentry->strings = 0;
149 subentry->subfiles = 0;
1136f72d 150 subentry->chain = 0;
6a61ea88 151 subentry->flags = 0;
1c8a0fd5 152#endif
1136f72d
PR
153
154 (*length_loc) = member_length;
155
156 return subentry;
157}
158
6a61ea88 159static int subfile_wanted_p __P((struct file_entry *));
1136f72d
PR
160
161/*
1c8a0fd5 162 * Search a library that has a __.SYMDEF member. FD is a descriptor on
1136f72d
PR
163 * which the library is open. The file pointer is assumed to point at the
164 * __.SYMDEF data. ENTRY is the library's file_entry. MEMBER_LENGTH is the
165 * length of the __.SYMDEF data.
166 */
167
6a61ea88 168static void
1c8a0fd5
PR
169symdef_library(fd, entry, member_length)
170 int fd;
1136f72d
PR
171 struct file_entry *entry;
172 int member_length;
173{
174 int *symdef_data = (int *) xmalloc(member_length);
175 register struct ranlib *symdef_base;
176 char *sym_name_base;
6a61ea88 177 int nsymdefs;
1136f72d
PR
178 int length_of_strings;
179 int not_finished;
180 int bytes_read;
181 register int i;
182 struct file_entry *prev = 0;
183 int prev_offset = 0;
184
1c8a0fd5 185 bytes_read = read(fd, symdef_data, member_length);
1136f72d 186 if (bytes_read != member_length)
1c8a0fd5
PR
187 errx(1, "%s: malformatted __.SYMDEF",
188 get_file_name(entry));
1136f72d 189
6a61ea88
JH
190 nsymdefs = md_swap_long(*symdef_data) / sizeof(struct ranlib);
191 if (nsymdefs < 0 ||
192 nsymdefs * sizeof(struct ranlib) + 2 * sizeof(int) > member_length)
1c8a0fd5
PR
193 errx(1, "%s: malformatted __.SYMDEF",
194 get_file_name(entry));
1136f72d
PR
195
196 symdef_base = (struct ranlib *) (symdef_data + 1);
6a61ea88 197 length_of_strings = md_swap_long(*(int *) (symdef_base + nsymdefs));
1136f72d
PR
198
199 if (length_of_strings < 0
6a61ea88 200 || nsymdefs * sizeof(struct ranlib) + length_of_strings
1136f72d 201 + 2 * sizeof(int) > member_length)
1c8a0fd5
PR
202 errx(1, "%s: malformatted __.SYMDEF",
203 get_file_name(entry));
1136f72d 204
6a61ea88 205 sym_name_base = sizeof(int) + (char *) (symdef_base + nsymdefs);
1136f72d
PR
206
207 /* Check all the string indexes for validity. */
6a61ea88
JH
208 md_swapin_ranlib_hdr(symdef_base, nsymdefs);
209 for (i = 0; i < nsymdefs; i++) {
1136f72d
PR
210 register int index = symdef_base[i].ran_un.ran_strx;
211 if (index < 0 || index >= length_of_strings
212 || (index && *(sym_name_base + index - 1)))
1c8a0fd5
PR
213 errx(1, "%s: malformatted __.SYMDEF",
214 get_file_name(entry));
1136f72d
PR
215 }
216
217 /*
218 * Search the symdef data for members to load. Do this until one
219 * whole pass finds nothing to load.
220 */
221
222 not_finished = 1;
223 while (not_finished) {
224
225 not_finished = 0;
226
227 /*
228 * Scan all the symbols mentioned in the symdef for ones that
229 * we need. Load the library members that contain such
230 * symbols.
231 */
232
6a61ea88 233 for (i = 0; (i < nsymdefs &&
1136f72d
PR
234 ((link_mode & FORCEARCHIVE) ||
235 undefined_global_sym_count ||
236 common_defined_global_count)); i++) {
237
238 register symbol *sp;
239 int junk;
240 register int j;
241 register int offset = symdef_base[i].ran_off;
242 struct file_entry *subentry;
243
244
245 if (symdef_base[i].ran_un.ran_strx < 0)
246 continue;
247
248 sp = getsym_soft(sym_name_base
249 + symdef_base[i].ran_un.ran_strx);
250
251 /*
252 * If we find a symbol that appears to be needed,
253 * think carefully about the archive member that the
254 * symbol is in.
255 */
256
257 /*
258 * Per Mike Karels' recommendation, we no longer load
259 * library files if the only reference(s) that would
260 * be satisfied are 'common' references. This
261 * prevents some problems with name pollution (e.g. a
262 * global common 'utime' linked to a function).
263 */
264 if (!(link_mode & FORCEARCHIVE) &&
6a61ea88
JH
265 (!sp || sp->defined ||
266 (!(sp->flags & GS_REFERENCED) &&
267 !sp->sorefs)))
1136f72d
PR
268 continue;
269
270 /*
271 * Don't think carefully about any archive member
272 * more than once in a given pass.
273 */
274
275 if (prev_offset == offset)
276 continue;
277 prev_offset = offset;
278
279 /*
280 * Read the symbol table of the archive member.
281 */
282
1c8a0fd5 283 subentry = decode_library_subfile(fd,
1136f72d
PR
284 entry, offset, &junk);
285 if (subentry == 0)
1c8a0fd5 286 errx(1,
6a61ea88 287 "invalid offset for %s in symbol table of %s",
1136f72d
PR
288 sym_name_base
289 + symdef_base[i].ran_un.ran_strx,
290 entry->filename);
6a61ea88 291
1c8a0fd5 292 read_entry_symbols(fd, subentry);
1136f72d 293 subentry->strings = (char *)
1c8a0fd5
PR
294 alloca(subentry->string_size);
295 read_entry_strings(fd, subentry);
1136f72d
PR
296
297 /*
298 * Now scan the symbol table and decide whether to
299 * load.
300 */
301
302 if (!(link_mode & FORCEARCHIVE) &&
303 !subfile_wanted_p(subentry)) {
1c8a0fd5 304 if (subentry->symbols)
1136f72d
PR
305 free(subentry->symbols);
306 free(subentry);
307 } else {
308 /*
309 * This member is needed; load it. Since we
310 * are loading something on this pass, we
311 * must make another pass through the symdef
312 * data.
313 */
314
315 not_finished = 1;
316
1c8a0fd5 317 read_entry_relocation(fd, subentry);
1136f72d
PR
318 enter_file_symbols(subentry);
319
320 if (prev)
321 prev->chain = subentry;
322 else
323 entry->subfiles = subentry;
324 prev = subentry;
325
326 /*
327 * Clear out this member's symbols from the
328 * symdef data so that following passes won't
329 * waste time on them.
330 */
331
6a61ea88 332 for (j = 0; j < nsymdefs; j++) {
1136f72d
PR
333 if (symdef_base[j].ran_off == offset)
334 symdef_base[j].ran_un.ran_strx = -1;
335 }
1136f72d
PR
336
337 /*
1c8a0fd5
PR
338 * We'll read the strings again
339 * if we need them.
1136f72d 340 */
1136f72d
PR
341 subentry->strings = 0;
342 }
343 }
1c8a0fd5 344 }
1136f72d
PR
345
346 free(symdef_data);
347}
348
349/*
350 * Search a library that has no __.SYMDEF. ENTRY is the library's file_entry.
1c8a0fd5 351 * FD is the descriptor it is open on.
1136f72d
PR
352 */
353
6a61ea88 354static void
1c8a0fd5
PR
355linear_library(fd, entry)
356 int fd;
1136f72d
PR
357 struct file_entry *entry;
358{
359 register struct file_entry *prev = 0;
360 register int this_subfile_offset = SARMAG;
361
362 while ((link_mode & FORCEARCHIVE) ||
363 undefined_global_sym_count || common_defined_global_count) {
364
6a61ea88
JH
365 int member_length;
366 register struct file_entry *subentry;
1136f72d 367
1c8a0fd5 368 subentry = decode_library_subfile(fd, entry,
6a61ea88 369 this_subfile_offset, &member_length);
1136f72d
PR
370
371 if (!subentry)
372 return;
373
1c8a0fd5
PR
374 read_entry_symbols(fd, subentry);
375 subentry->strings = (char *)alloca(subentry->string_size);
376 read_entry_strings(fd, subentry);
1136f72d
PR
377
378 if (!(link_mode & FORCEARCHIVE) &&
379 !subfile_wanted_p(subentry)) {
1c8a0fd5 380 if (subentry->symbols)
1136f72d
PR
381 free(subentry->symbols);
382 free(subentry);
383 } else {
1c8a0fd5 384 read_entry_relocation(fd, subentry);
1136f72d
PR
385 enter_file_symbols(subentry);
386
387 if (prev)
388 prev->chain = subentry;
389 else
390 entry->subfiles = subentry;
391 prev = subentry;
392 subentry->strings = 0; /* Since space will dissapear
393 * on return */
394 }
395
396 this_subfile_offset += member_length + sizeof(struct ar_hdr);
397 if (this_subfile_offset & 1)
398 this_subfile_offset++;
399 }
400}
401
402/*
403 * ENTRY is an entry for a library member. Its symbols have been read into
404 * core, but not entered. Return nonzero if we ought to load this member.
405 */
406
6a61ea88 407static int
1136f72d
PR
408subfile_wanted_p(entry)
409 struct file_entry *entry;
410{
411 struct localsymbol *lsp, *lspend;
412#ifdef DOLLAR_KLUDGE
413 register int dollar_cond = 0;
414#endif
415
416 lspend = entry->symbols + entry->nsymbols;
417
418 for (lsp = entry->symbols; lsp < lspend; lsp++) {
419 register struct nlist *p = &lsp->nzlist.nlist;
6a61ea88
JH
420 register int type = p->n_type;
421 register char *name = p->n_un.n_strx + entry->strings;
422 register symbol *sp = getsym_soft(name);
1136f72d
PR
423
424 /*
425 * If the symbol has an interesting definition, we could
426 * potentially want it.
427 */
428 if (! (type & N_EXT)
429 || (type == (N_UNDF | N_EXT) && p->n_value == 0
430
431#ifdef DOLLAR_KLUDGE
432 && name[1] != '$'
433#endif
434 )
435#ifdef SET_ELEMENT_P
436 || SET_ELEMENT_P(type)
437 || set_element_prefixed_p(name)
438#endif
439 )
440 continue;
441
442
443#ifdef DOLLAR_KLUDGE
444 if (name[1] == '$') {
445 sp = getsym_soft(&name[2]);
446 dollar_cond = 1;
447 if (!sp)
448 continue;
6a61ea88 449 if (sp->flags & SP_REFERENCED) {
1136f72d
PR
450 if (write_map) {
451 print_file_name(entry, stdout);
452 fprintf(stdout, " needed due to $-conditional %s\n", name);
453 }
454 return 1;
455 }
456 continue;
457 }
458#endif
459
460 /*
461 * If this symbol has not been hashed, we can't be
462 * looking for it.
463 */
464
465 if (!sp)
466 continue;
467
468 /*
469 * We don't load a file if it merely satisfies a
470 * common reference (see explanation above in
471 * symdef_library()).
472 */
6a61ea88 473 if ((sp->flags & GS_REFERENCED) && !sp->defined) {
1136f72d
PR
474 /*
475 * This is a symbol we are looking for. It
476 * is either not yet defined or defined as a
477 * common.
478 */
479#ifdef DOLLAR_KLUDGE
480 if (dollar_cond)
481 continue;
482#endif
483 if (type == (N_UNDF | N_EXT)) {
484 /*
485 * Symbol being defined as common.
486 * Remember this, but don't load
487 * subfile just for this.
488 */
489
490 /*
491 * If it didn't used to be common, up
492 * the count of common symbols.
493 */
6a61ea88 494 if (!sp->common_size)
1136f72d
PR
495 common_defined_global_count++;
496
6a61ea88
JH
497 if (sp->common_size < p->n_value)
498 sp->common_size = p->n_value;
1136f72d
PR
499 if (!sp->defined)
500 undefined_global_sym_count--;
501 sp->defined = type;
502 continue;
503 }
504 if (write_map) {
505 print_file_name(entry, stdout);
506 fprintf(stdout, " needed due to %s\n", sp->name);
507 }
508 return 1;
509 } else {
6a61ea88
JH
510 /*
511 * Check for undefined symbols or commons
512 * in shared objects.
513 */
1136f72d 514 struct localsymbol *lsp;
6a61ea88
JH
515 int wascommon = sp->defined && sp->common_size;
516 int iscommon = type == (N_UNDF|N_EXT) && p->n_value;
517
518 if (wascommon) {
519 /*
520 * sp was defined as common by shared object.
521 */
522 if (iscommon && p->n_value < sp->common_size)
523 sp->common_size = p->n_value;
524 continue;
525 }
1136f72d 526
0f052032
JH
527 if (sp->sorefs == NULL)
528 continue;
529
1136f72d 530 for (lsp = sp->sorefs; lsp; lsp = lsp->next) {
6a61ea88 531 int type = lsp->nzlist.nlist.n_type;
1136f72d
PR
532 if ( (type & N_EXT) &&
533 (type & N_STAB) == 0 &&
534 type != (N_UNDF | N_EXT))
6a61ea88
JH
535 break; /* We don't need it */
536 }
537 if (lsp != NULL) {
538 /* There's a real definition */
539 if (iscommon)
540 /*
541 * But this member wants it to be
542 * a common; ignore it.
1c8a0fd5 543 */
6a61ea88
JH
544 continue;
545 }
546
547 if (iscommon) {
548 /*
549 * New symbol is common, just takes its
550 * size, but don't load.
551 */
552 sp->common_size = p->n_value;
553 sp->defined = type;
554 continue;
1136f72d 555 }
6a61ea88
JH
556
557 /*
558 * THIS STILL MISSES the case where one shared
559 * object defines a common and the next defines
560 * more strongly; fix this someday by making
561 * `struct glosym' and enter_global_ref() more
562 * symmetric.
563 */
7fc7155d 564
1136f72d
PR
565 if (write_map) {
566 print_file_name(entry, stdout);
1c8a0fd5
PR
567 fprintf(stdout,
568 " needed due to shared lib ref %s\n",
569 sp->name);
1136f72d
PR
570 }
571 return 1;
1136f72d
PR
572 }
573 }
574
575 return 0;
576}
577
578/*
579 * Read the symbols of dynamic entity ENTRY into core. Assume it is already
1c8a0fd5 580 * open, on descriptor FD.
1136f72d
PR
581 */
582void
1c8a0fd5 583read_shared_object(fd, entry)
1136f72d 584 struct file_entry *entry;
1c8a0fd5 585 int fd;
1136f72d 586{
6a61ea88
JH
587 struct _dynamic dyn;
588 struct section_dispatch_table sdt;
589 struct nlist *np;
590 struct nzlist *nzp;
591 int n, i, has_nz = 0;
1136f72d 592
6a61ea88 593 if (!(entry->flags & E_HEADER_VALID))
1c8a0fd5 594 read_header(fd, entry);
1136f72d
PR
595
596 /* Read DYNAMIC structure (first in data segment) */
1c8a0fd5
PR
597 if (lseek(fd, text_offset(entry) + entry->header.a_text, L_SET) ==
598 (off_t)-1)
599 err(1, "%s: lseek", get_file_name(entry));
600 if (read(fd, &dyn, sizeof dyn) != sizeof dyn) {
601 errx(1, "%s: premature EOF reading _dynamic",
602 get_file_name(entry));
1136f72d 603 }
6a61ea88 604 md_swapin__dynamic(&dyn);
1136f72d
PR
605
606 /* Check version */
6a61ea88 607 switch (dyn.d_version) {
1136f72d 608 default:
1c8a0fd5
PR
609 errx(1, "%s: unsupported _DYNAMIC version: %d",
610 get_file_name(entry), dyn.d_version);
1136f72d
PR
611 break;
612 case LD_VERSION_SUN:
613 break;
614 case LD_VERSION_BSD:
615 has_nz = 1;
616 break;
617 }
618
6a61ea88 619 /* Read Section Dispatch Table (from data segment) */
1c8a0fd5 620 if (lseek(fd,
6a61ea88
JH
621 text_offset(entry) + (long)dyn.d_un.d_sdt -
622 (DATA_START(entry->header) - N_DATOFF(entry->header)),
1c8a0fd5
PR
623 L_SET) == (off_t)-1)
624 err(1, "%s: lseek", get_file_name(entry));
625 if (read(fd, &sdt, sizeof sdt) != sizeof sdt)
626 errx(1, "%s: premature EOF reading sdt",
627 get_file_name(entry));
6a61ea88 628 md_swapin_section_dispatch_table(&sdt);
1136f72d
PR
629
630 /* Read symbols (text segment) */
6a61ea88 631 n = sdt.sdt_strings - sdt.sdt_nzlist;
1136f72d
PR
632 entry->nsymbols = n /
633 (has_nz ? sizeof(struct nzlist) : sizeof(struct nlist));
1c8a0fd5 634 nzp = (struct nzlist *)(np = (struct nlist *)alloca (n));
1136f72d
PR
635 entry->symbols = (struct localsymbol *)
636 xmalloc(entry->nsymbols * sizeof(struct localsymbol));
1c8a0fd5
PR
637
638 if (lseek(fd,
639 text_offset(entry) + (long)sdt.sdt_nzlist -
6a61ea88 640 (TEXT_START(entry->header) - N_TXTOFF(entry->header)),
1c8a0fd5
PR
641 L_SET) == (off_t)-1)
642 err(1, "%s: lseek", get_file_name(entry));
643 if (read(fd, (char *)nzp, n) != n)
644 errx(1, "%s: premature EOF reading symbols ",
645 get_file_name(entry));
646
1136f72d
PR
647 if (has_nz)
648 md_swapin_zsymbols(nzp, entry->nsymbols);
649 else
650 md_swapin_symbols(np, entry->nsymbols);
651
652 /* Convert to structs localsymbol */
653 for (i = 0; i < entry->nsymbols; i++) {
654 if (has_nz) {
655 entry->symbols[i].nzlist = *nzp++;
656 } else {
657 entry->symbols[i].nzlist.nlist = *np++;
658 entry->symbols[i].nzlist.nz_size = 0;
659 }
660 entry->symbols[i].symbol = NULL;
661 entry->symbols[i].next = NULL;
6a61ea88 662 entry->symbols[i].entry = entry;
1136f72d 663 entry->symbols[i].gotslot_offset = -1;
6a61ea88 664 entry->symbols[i].flags = 0;
1136f72d
PR
665 }
666
667 /* Read strings (text segment) */
6a61ea88 668 n = entry->string_size = sdt.sdt_str_sz;
1c8a0fd5 669 entry->strings = (char *)alloca(n);
6a61ea88 670 entry->strings_offset = text_offset(entry) + sdt.sdt_strings;
1c8a0fd5
PR
671 if (lseek(fd,
672 entry->strings_offset -
6a61ea88 673 (TEXT_START(entry->header) - N_TXTOFF(entry->header)),
1c8a0fd5
PR
674 L_SET) == (off_t)-1)
675 err(1, "%s: lseek", get_file_name(entry));
676 if (read(fd, entry->strings, n) != n)
677 errx(1, "%s: premature EOF reading strings",
678 get_file_name(entry));
1136f72d
PR
679 enter_file_symbols (entry);
680 entry->strings = 0;
681
0f052032
JH
682 /*
683 * Load any subsidiary shared objects.
684 */
6a61ea88
JH
685 if (sdt.sdt_sods) {
686 struct sod sod;
0f052032 687 off_t offset;
6a61ea88 688 struct file_entry *prev = NULL;
0f052032 689
6a61ea88 690 offset = (off_t)sdt.sdt_sods;
0f052032 691 while (1) {
6a61ea88 692 struct file_entry *subentry;
0f052032
JH
693 char *libname, name[MAXPATHLEN]; /*XXX*/
694
6a61ea88
JH
695 subentry = (struct file_entry *)
696 xmalloc(sizeof(struct file_entry));
697 bzero(subentry, sizeof(struct file_entry));
698 subentry->superfile = entry;
699
1c8a0fd5
PR
700 if (lseek(fd,
701 offset - (TEXT_START(entry->header) -
702 N_TXTOFF(entry->header)),
703 L_SET) == (off_t)-1)
704 err(1, "%s: lseek", get_file_name(entry));
705 if (read(fd, &sod, sizeof(sod)) != sizeof(sod))
706 errx(1, "%s: premature EOF reding sod",
707 get_file_name(entry));
6a61ea88 708 md_swapin_sod(&sod, 1);
1c8a0fd5
PR
709 if (lseek(fd,
710 (off_t)sod.sod_name - (TEXT_START(entry->header) -
711 N_TXTOFF(entry->header)),
712 L_SET) == (off_t)-1)
713 err(1, "%s: lseek", get_file_name(entry));
714 (void)read(fd, name, sizeof(name)); /*XXX*/
6a61ea88
JH
715 if (sod.sod_library) {
716 int sod_major = sod.sod_major;
717 int sod_minor = sod.sod_minor;
0f052032
JH
718
719 libname = findshlib(name,
6a61ea88 720 &sod_major, &sod_minor, 0);
0f052032 721 if (libname == NULL)
1c8a0fd5 722 errx(1,"no shared -l%s.%d.%d available",
6a61ea88 723 name, sod.sod_major, sod.sod_minor);
0f052032
JH
724 subentry->filename = libname;
725 subentry->local_sym_name = concat("-l", name, "");
726 } else {
727 subentry->filename = strdup(name);
728 subentry->local_sym_name = strdup(name);
729 }
730 read_file_symbols(subentry);
731
732 if (prev)
733 prev->chain = subentry;
734 else
735 entry->subfiles = subentry;
736 prev = subentry;
1c8a0fd5 737 fd = file_open(entry);
6a61ea88 738 if ((offset = (off_t)sod.sod_next) == 0)
0f052032
JH
739 break;
740 }
741 }
742#ifdef SUN_COMPAT
743 if (link_mode & SILLYARCHIVE) {
744 char *cp, *sa_name;
745 char armag[SARMAG];
746 int fd;
747 struct file_entry *subentry;
748
749 sa_name = strdup(entry->filename);
750 if (sa_name == NULL)
751 goto out;
752 cp = sa_name + strlen(sa_name) - 1;
753 while (cp > sa_name) {
754 if (!isdigit(*cp) && *cp != '.')
755 break;
756 --cp;
757 }
758 if (cp <= sa_name || *cp != 'o') {
759 /* Not in `libxxx.so.n.m' form */
760 free(sa_name);
761 goto out;
762 }
763
764 *cp = 'a';
765 if ((fd = open(sa_name, O_RDONLY, 0)) < 0)
766 goto out;
767
768 /* Read archive magic */
769 bzero(armag, SARMAG);
770 (void)read(fd, armag, SARMAG);
771 (void)close(fd);
772 if (strncmp(armag, ARMAG, SARMAG) != 0) {
1c8a0fd5 773 warnx("%s: malformed silly archive",
0f052032
JH
774 get_file_name(entry));
775 goto out;
776 }
777
778 subentry = (struct file_entry *)
779 xmalloc(sizeof(struct file_entry));
780 bzero(subentry, sizeof(struct file_entry));
781
782 entry->silly_archive = subentry;
783 subentry->superfile = entry;
784 subentry->filename = sa_name;
785 subentry->local_sym_name = sa_name;
6a61ea88 786 subentry->flags |= E_IS_LIBRARY;
0f052032
JH
787 search_library(file_open(subentry), subentry);
788out:
789 ;
1136f72d 790 }
0f052032 791#endif
1136f72d
PR
792}
793
794#undef major
795#undef minor
796
797int
798findlib(p)
799struct file_entry *p;
800{
1136f72d 801 int i;
1c8a0fd5 802 int fd = -1;
1136f72d
PR
803 int major = -1, minor = -1;
804 char *cp, *fname = NULL;
805
6a61ea88 806 if (!(p->flags & E_SEARCH_DYNAMIC))
1136f72d
PR
807 goto dot_a;
808
0f052032 809 fname = findshlib(p->filename, &major, &minor, 1);
1136f72d 810
1c8a0fd5 811 if (fname && (fd = open(fname, O_RDONLY, 0)) > 0) {
1136f72d
PR
812 p->filename = fname;
813 p->lib_major = major;
814 p->lib_minor = minor;
6a61ea88 815 p->flags &= ~E_SEARCH_DIRS;
1c8a0fd5 816 return fd;
1136f72d 817 }
1c8a0fd5 818 (void)free(fname);
1136f72d
PR
819
820dot_a:
6a61ea88 821 p->flags &= ~E_SEARCH_DYNAMIC;
1136f72d
PR
822 if (cp = strrchr(p->filename, '/')) {
823 *cp++ = '\0';
824 fname = concat(concat(p->filename, "/lib", cp), ".a", "");
825 *(--cp) = '/';
826 } else
827 fname = concat("lib", p->filename, ".a");
828
829 for (i = 0; i < n_search_dirs; i++) {
1c8a0fd5
PR
830 register char *path
831 = concat(search_dirs[i], "/", fname);
832 fd = open(path, O_RDONLY, 0);
833 if (fd > 0) {
834 p->filename = path;
6a61ea88 835 p->flags &= ~E_SEARCH_DIRS;
1136f72d
PR
836 break;
837 }
1c8a0fd5 838 (void)free(path);
1136f72d 839 }
1c8a0fd5
PR
840 (void)free(fname);
841 return fd;
1136f72d
PR
842}
843