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