1 /* Collect static initialization info into data structures that can be
2 traversed by C++ initialization and finalization routines.
3 Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998,
4 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
5 Contributed by Chris Smith (csmith@convex.com).
6 Heavily modified by Michael Meissner (meissner@cygnus.com),
7 Per Bothner (bothner@cygnus.com), and John Gilmore (gnu@cygnus.com).
8
9 This file is part of GCC.
10
11 GCC is free software; you can redistribute it and/or modify it under
12 the terms of the GNU General Public License as published by the Free
13 Software Foundation; either version 2, or (at your option) any later
14 version.
15
16 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
17 WARRANTY; without even the implied warranty of MERCHANTABILITY or
18 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
19 for more details.
20
21 You should have received a copy of the GNU General Public License
22 along with GCC; see the file COPYING. If not, write to the Free
23 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
24 02111-1307, USA. */
25
26
27 /* Build tables of static constructors and destructors and run ld. */
28
29 #include "config.h"
30 #include "system.h"
31 #include "coretypes.h"
32 #include "tm.h"
33 #include <signal.h>
34 #if ! defined( SIGCHLD ) && defined( SIGCLD )
35 # define SIGCHLD SIGCLD
36 #endif
37
38 #ifdef vfork /* Autoconf may define this to fork for us. */
39 # define VFORK_STRING "fork"
40 #else
41 # define VFORK_STRING "vfork"
42 #endif
43 #ifdef HAVE_VFORK_H
44 #include <vfork.h>
45 #endif
46 #ifdef VMS
47 #define vfork() (decc$$alloc_vfork_blocks() >= 0 ? \
48 lib$get_current_invo_context(decc$$get_vfork_jmpbuf()) : -1)
49 #endif /* VMS */
50
51 #ifndef LIBRARY_PATH_ENV
52 #define LIBRARY_PATH_ENV "LIBRARY_PATH"
53 #endif
54
55 #define COLLECT
56
57 #include "collect2.h"
58 #include "demangle.h"
59 #include "obstack.h"
60 #include "intl.h"
61 #include "version.h"
62
63 /* On certain systems, we have code that works by scanning the object file
64 directly. But this code uses system-specific header files and library
65 functions, so turn it off in a cross-compiler. Likewise, the names of
66 the utilities are not correct for a cross-compiler; we have to hope that
67 cross-versions are in the proper directories. */
68
69 #ifdef CROSS_COMPILE
70 #undef SUNOS4_SHARED_LIBRARIES
71 #undef OBJECT_FORMAT_COFF
72 #undef MD_EXEC_PREFIX
73 #undef REAL_LD_FILE_NAME
74 #undef REAL_NM_FILE_NAME
75 #undef REAL_STRIP_FILE_NAME
76 #endif
77
78 /* If we cannot use a special method, use the ordinary one:
79 run nm to find what symbols are present.
80 In a cross-compiler, this means you need a cross nm,
81 but that is not quite as unpleasant as special headers. */
82
83 #if !defined (OBJECT_FORMAT_COFF)
84 #define OBJECT_FORMAT_NONE
85 #endif
86
87 #ifdef OBJECT_FORMAT_COFF
88
89 #include <a.out.h>
90 #include <ar.h>
91
92 #ifdef UMAX
93 #include <sgs.h>
94 #endif
95
96 /* Many versions of ldfcn.h define these. */
97 #ifdef FREAD
98 #undef FREAD
99 #undef FWRITE
100 #endif
101
102 #include <ldfcn.h>
103
104 /* Some systems have an ISCOFF macro, but others do not. In some cases
105 the macro may be wrong. MY_ISCOFF is defined in tm.h files for machines
106 that either do not have an ISCOFF macro in /usr/include or for those
107 where it is wrong. */
108
109 #ifndef MY_ISCOFF
110 #define MY_ISCOFF(X) ISCOFF (X)
111 #endif
112
113 #endif /* OBJECT_FORMAT_COFF */
114
115 #ifdef OBJECT_FORMAT_NONE
116
117 /* Default flags to pass to nm. */
118 #ifndef NM_FLAGS
119 #define NM_FLAGS "-n"
120 #endif
121
122 #endif /* OBJECT_FORMAT_NONE */
123
124 /* Some systems use __main in a way incompatible with its use in gcc, in these
125 cases use the macros NAME__MAIN to give a quoted symbol and SYMBOL__MAIN to
126 give the same symbol without quotes for an alternative entry point. */
127 #ifndef NAME__MAIN
128 #define NAME__MAIN "__main"
129 #endif
130
131 /* This must match tree.h. */
132 #define DEFAULT_INIT_PRIORITY 65535
133
134 #ifndef COLLECT_SHARED_INIT_FUNC
135 #define COLLECT_SHARED_INIT_FUNC(STREAM, FUNC) \
136 fprintf ((STREAM), "void _GLOBAL__DI() {\n\t%s();\n}\n", (FUNC))
137 #endif
138 #ifndef COLLECT_SHARED_FINI_FUNC
139 #define COLLECT_SHARED_FINI_FUNC(STREAM, FUNC) \
140 fprintf ((STREAM), "void _GLOBAL__DD() {\n\t%s();\n}\n", (FUNC))
141 #endif
142
143 #if defined (LDD_SUFFIX) || SUNOS4_SHARED_LIBRARIES
144 #define SCAN_LIBRARIES
145 #endif
146
147 #ifdef USE_COLLECT2
148 int do_collecting = 1;
149 #else
150 int do_collecting = 0;
151 #endif
152
153 #ifndef COLLECT_PARSE_FLAG
154 #define COLLECT_PARSE_FLAG(FLAG)
155 #endif
156
157 /* Nonzero if we should suppress the automatic demangling of identifiers
158 in linker error messages. Set from COLLECT_NO_DEMANGLE. */
159 int no_demangle;
160
161 /* Linked lists of constructor and destructor names. */
162
163 struct id
164 {
165 struct id *next;
166 int sequence;
167 char name[1];
168 };
169
170 struct head
171 {
172 struct id *first;
173 struct id *last;
174 int number;
175 };
176
177 /* Enumeration giving which pass this is for scanning the program file. */
178
179 enum pass {
180 PASS_FIRST, /* without constructors */
181 PASS_OBJ, /* individual objects */
182 PASS_LIB, /* looking for shared libraries */
183 PASS_SECOND /* with constructors linked in */
184 };
185
186 int vflag; /* true if -v */
187 static int rflag; /* true if -r */
188 static int strip_flag; /* true if -s */
189 #ifdef COLLECT_EXPORT_LIST
190 static int export_flag; /* true if -bE */
191 static int aix64_flag; /* true if -b64 */
192 #endif
193
194 int debug; /* true if -debug */
195
196 static int shared_obj; /* true if -shared */
197
198 static const char *c_file; /* <xxx>.c for constructor/destructor list. */
199 static const char *o_file; /* <xxx>.o for constructor/destructor list. */
200 #ifdef COLLECT_EXPORT_LIST
201 static const char *export_file; /* <xxx>.x for AIX export list. */
202 #endif
203 const char *ldout; /* File for ld errors. */
204 static const char *output_file; /* Output file for ld. */
205 static const char *nm_file_name; /* pathname of nm */
206 #ifdef LDD_SUFFIX
207 static const char *ldd_file_name; /* pathname of ldd (or equivalent) */
208 #endif
209 static const char *strip_file_name; /* pathname of strip */
210 const char *c_file_name; /* pathname of gcc */
211 static char *initname, *fininame; /* names of init and fini funcs */
212
213 static struct head constructors; /* list of constructors found */
214 static struct head destructors; /* list of destructors found */
215 #ifdef COLLECT_EXPORT_LIST
216 static struct head exports; /* list of exported symbols */
217 #endif
218 static struct head frame_tables; /* list of frame unwind info tables */
219
220 struct obstack temporary_obstack;
221 char * temporary_firstobj;
222
223 /* Holds the return value of pexecute and fork. */
224 int pid;
225
226 /* Structure to hold all the directories in which to search for files to
227 execute. */
228
229 struct prefix_list
230 {
231 const char *prefix; /* String to prepend to the path. */
232 struct prefix_list *next; /* Next in linked list. */
233 };
234
235 struct path_prefix
236 {
237 struct prefix_list *plist; /* List of prefixes to try */
238 int max_len; /* Max length of a prefix in PLIST */
239 const char *name; /* Name of this list (used in config stuff) */
240 };
241
242 #ifdef COLLECT_EXPORT_LIST
243 /* Lists to keep libraries to be scanned for global constructors/destructors. */
244 static struct head libs; /* list of libraries */
245 static struct path_prefix cmdline_lib_dirs; /* directories specified with -L */
246 static struct path_prefix libpath_lib_dirs; /* directories in LIBPATH */
247 static struct path_prefix *libpaths[3] = {&cmdline_lib_dirs,
248 &libpath_lib_dirs, NULL};
249 static const char *const libexts[3] = {"a", "so", NULL}; /* possible library extensions */
250 #endif
251
252 static void handler (int);
253 static int is_ctor_dtor (const char *);
254 static char *find_a_file (struct path_prefix *, const char *);
255 static void add_prefix (struct path_prefix *, const char *);
256 static void prefix_from_env (const char *, struct path_prefix *);
257 static void prefix_from_string (const char *, struct path_prefix *);
258 static void do_wait (const char *);
259 static void fork_execute (const char *, char **);
260 static void maybe_unlink (const char *);
261 static void add_to_list (struct head *, const char *);
262 static int extract_init_priority (const char *);
263 static void sort_ids (struct head *);
264 static void write_list (FILE *, const char *, struct id *);
265 #ifdef COLLECT_EXPORT_LIST
266 static void dump_list (FILE *, const char *, struct id *);
267 #endif
268 #if 0
269 static void dump_prefix_list (FILE *, const char *, struct prefix_list *);
270 #endif
271 static void write_list_with_asm (FILE *, const char *, struct id *);
272 static void write_c_file (FILE *, const char *);
273 static void write_c_file_stat (FILE *, const char *);
274 #ifndef LD_INIT_SWITCH
275 static void write_c_file_glob (FILE *, const char *);
276 #endif
277 static void scan_prog_file (const char *, enum pass);
278 #ifdef SCAN_LIBRARIES
279 static void scan_libraries (const char *);
280 #endif
281 #if LINK_ELIMINATE_DUPLICATE_LDIRECTORIES
282 static int is_in_args (const char *, const char **, const char **);
283 #endif
284 #ifdef COLLECT_EXPORT_LIST
285 #if 0
286 static int is_in_list (const char *, struct id *);
287 #endif
288 static void write_aix_file (FILE *, struct id *);
289 static char *resolve_lib_name (const char *);
290 #endif
291 static char *extract_string (const char **);
292
293 #ifndef HAVE_DUP2
294 static int
dup2(int oldfd,int newfd)295 dup2 (int oldfd, int newfd)
296 {
297 int fdtmp[256];
298 int fdx = 0;
299 int fd;
300
301 if (oldfd == newfd)
302 return oldfd;
303 close (newfd);
304 while ((fd = dup (oldfd)) != newfd && fd >= 0) /* good enough for low fd's */
305 fdtmp[fdx++] = fd;
306 while (fdx > 0)
307 close (fdtmp[--fdx]);
308
309 return fd;
310 }
311 #endif /* ! HAVE_DUP2 */
312
313 /* Delete tempfiles and exit function. */
314
315 void
collect_exit(int status)316 collect_exit (int status)
317 {
318 if (c_file != 0 && c_file[0])
319 maybe_unlink (c_file);
320
321 if (o_file != 0 && o_file[0])
322 maybe_unlink (o_file);
323
324 #ifdef COLLECT_EXPORT_LIST
325 if (export_file != 0 && export_file[0])
326 maybe_unlink (export_file);
327 #endif
328
329 if (ldout != 0 && ldout[0])
330 {
331 dump_file (ldout);
332 maybe_unlink (ldout);
333 }
334
335 if (status != 0 && output_file != 0 && output_file[0])
336 maybe_unlink (output_file);
337
338 exit (status);
339 }
340
341
342 /* Notify user of a non-error. */
343 void
notice(const char * msgid,...)344 notice (const char *msgid, ...)
345 {
346 va_list ap;
347
348 va_start (ap, msgid);
349 vfprintf (stderr, _(msgid), ap);
350 va_end (ap);
351 }
352
353 /* Die when sys call fails. */
354
355 void
fatal_perror(const char * msgid,...)356 fatal_perror (const char * msgid, ...)
357 {
358 int e = errno;
359 va_list ap;
360
361 va_start (ap, msgid);
362 fprintf (stderr, "collect2: ");
363 vfprintf (stderr, _(msgid), ap);
364 fprintf (stderr, ": %s\n", xstrerror (e));
365 va_end (ap);
366
367 collect_exit (FATAL_EXIT_CODE);
368 }
369
370 /* Just die. */
371
372 void
fatal(const char * msgid,...)373 fatal (const char * msgid, ...)
374 {
375 va_list ap;
376
377 va_start (ap, msgid);
378 fprintf (stderr, "collect2: ");
379 vfprintf (stderr, _(msgid), ap);
380 fprintf (stderr, "\n");
381 va_end (ap);
382
383 collect_exit (FATAL_EXIT_CODE);
384 }
385
386 /* Write error message. */
387
388 void
error(const char * msgid,...)389 error (const char * msgid, ...)
390 {
391 va_list ap;
392
393 va_start (ap, msgid);
394 fprintf (stderr, "collect2: ");
395 vfprintf (stderr, _(msgid), ap);
396 fprintf (stderr, "\n");
397 va_end(ap);
398 }
399
400 /* In case obstack is linked in, and abort is defined to fancy_abort,
401 provide a default entry. */
402
403 void
fancy_abort(void)404 fancy_abort (void)
405 {
406 fatal ("internal error");
407 }
408
409 static void
handler(int signo)410 handler (int signo)
411 {
412 if (c_file != 0 && c_file[0])
413 maybe_unlink (c_file);
414
415 if (o_file != 0 && o_file[0])
416 maybe_unlink (o_file);
417
418 if (ldout != 0 && ldout[0])
419 maybe_unlink (ldout);
420
421 #ifdef COLLECT_EXPORT_LIST
422 if (export_file != 0 && export_file[0])
423 maybe_unlink (export_file);
424 #endif
425
426 signal (signo, SIG_DFL);
427 kill (getpid (), signo);
428 }
429
430
431 int
file_exists(const char * name)432 file_exists (const char *name)
433 {
434 return access (name, R_OK) == 0;
435 }
436
437 /* Parse a reasonable subset of shell quoting syntax. */
438
439 static char *
extract_string(const char ** pp)440 extract_string (const char **pp)
441 {
442 const char *p = *pp;
443 int backquote = 0;
444 int inside = 0;
445
446 for (;;)
447 {
448 char c = *p;
449 if (c == '\0')
450 break;
451 ++p;
452 if (backquote)
453 obstack_1grow (&temporary_obstack, c);
454 else if (! inside && c == ' ')
455 break;
456 else if (! inside && c == '\\')
457 backquote = 1;
458 else if (c == '\'')
459 inside = !inside;
460 else
461 obstack_1grow (&temporary_obstack, c);
462 }
463
464 obstack_1grow (&temporary_obstack, '\0');
465 *pp = p;
466 return obstack_finish (&temporary_obstack);
467 }
468
469 void
dump_file(const char * name)470 dump_file (const char *name)
471 {
472 FILE *stream = fopen (name, "r");
473
474 if (stream == 0)
475 return;
476 while (1)
477 {
478 int c;
479 while (c = getc (stream),
480 c != EOF && (ISIDNUM (c) || c == '$' || c == '.'))
481 obstack_1grow (&temporary_obstack, c);
482 if (obstack_object_size (&temporary_obstack) > 0)
483 {
484 const char *word, *p;
485 char *result;
486 obstack_1grow (&temporary_obstack, '\0');
487 word = obstack_finish (&temporary_obstack);
488
489 if (*word == '.')
490 ++word, putc ('.', stderr);
491 p = word;
492 if (!strncmp (p, USER_LABEL_PREFIX, strlen (USER_LABEL_PREFIX)))
493 p += strlen (USER_LABEL_PREFIX);
494
495 if (no_demangle)
496 result = 0;
497 else
498 result = cplus_demangle (p, DMGL_PARAMS | DMGL_ANSI | DMGL_VERBOSE);
499
500 if (result)
501 {
502 int diff;
503 fputs (result, stderr);
504
505 diff = strlen (word) - strlen (result);
506 while (diff > 0 && c == ' ')
507 --diff, putc (' ', stderr);
508 while (diff < 0 && c == ' ')
509 ++diff, c = getc (stream);
510
511 free (result);
512 }
513 else
514 fputs (word, stderr);
515
516 fflush (stderr);
517 obstack_free (&temporary_obstack, temporary_firstobj);
518 }
519 if (c == EOF)
520 break;
521 putc (c, stderr);
522 }
523 fclose (stream);
524 }
525
526 /* Decide whether the given symbol is: a constructor (1), a destructor
527 (2), a routine in a shared object that calls all the constructors
528 (3) or destructors (4), a DWARF exception-handling table (5), or
529 nothing special (0). */
530
531 static int
is_ctor_dtor(const char * s)532 is_ctor_dtor (const char *s)
533 {
534 struct names { const char *const name; const int len; const int ret;
535 const int two_underscores; };
536
537 const struct names *p;
538 int ch;
539 const char *orig_s = s;
540
541 static const struct names special[] = {
542 #ifndef NO_DOLLAR_IN_LABEL
543 { "GLOBAL__I$", sizeof ("GLOBAL__I$")-1, 1, 0 },
544 { "GLOBAL__D$", sizeof ("GLOBAL__D$")-1, 2, 0 },
545 #else
546 #ifndef NO_DOT_IN_LABEL
547 { "GLOBAL__I.", sizeof ("GLOBAL__I.")-1, 1, 0 },
548 { "GLOBAL__D.", sizeof ("GLOBAL__D.")-1, 2, 0 },
549 #endif /* NO_DOT_IN_LABEL */
550 #endif /* NO_DOLLAR_IN_LABEL */
551 { "GLOBAL__I_", sizeof ("GLOBAL__I_")-1, 1, 0 },
552 { "GLOBAL__D_", sizeof ("GLOBAL__D_")-1, 2, 0 },
553 { "GLOBAL__F_", sizeof ("GLOBAL__F_")-1, 5, 0 },
554 { "GLOBAL__FI_", sizeof ("GLOBAL__FI_")-1, 3, 0 },
555 { "GLOBAL__FD_", sizeof ("GLOBAL__FD_")-1, 4, 0 },
556 { NULL, 0, 0, 0 }
557 };
558
559 while ((ch = *s) == '_')
560 ++s;
561
562 if (s == orig_s)
563 return 0;
564
565 for (p = &special[0]; p->len > 0; p++)
566 {
567 if (ch == p->name[0]
568 && (!p->two_underscores || ((s - orig_s) >= 2))
569 && strncmp(s, p->name, p->len) == 0)
570 {
571 return p->ret;
572 }
573 }
574 return 0;
575 }
576
577 /* We maintain two prefix lists: one from COMPILER_PATH environment variable
578 and one from the PATH variable. */
579
580 static struct path_prefix cpath, path;
581
582 #ifdef CROSS_COMPILE
583 /* This is the name of the target machine. We use it to form the name
584 of the files to execute. */
585
586 static const char *const target_machine = TARGET_MACHINE;
587 #endif
588
589 /* Search for NAME using prefix list PPREFIX. We only look for executable
590 files.
591
592 Return 0 if not found, otherwise return its name, allocated with malloc. */
593
594 static char *
find_a_file(struct path_prefix * pprefix,const char * name)595 find_a_file (struct path_prefix *pprefix, const char *name)
596 {
597 char *temp;
598 struct prefix_list *pl;
599 int len = pprefix->max_len + strlen (name) + 1;
600
601 if (debug)
602 fprintf (stderr, "Looking for '%s'\n", name);
603
604 #ifdef HOST_EXECUTABLE_SUFFIX
605 len += strlen (HOST_EXECUTABLE_SUFFIX);
606 #endif
607
608 temp = xmalloc (len);
609
610 /* Determine the filename to execute (special case for absolute paths). */
611
612 if (*name == '/'
613 #ifdef HAVE_DOS_BASED_FILE_SYSTEM
614 || (*name && name[1] == ':')
615 #endif
616 )
617 {
618 if (access (name, X_OK) == 0)
619 {
620 strcpy (temp, name);
621
622 if (debug)
623 fprintf (stderr, " - found: absolute path\n");
624
625 return temp;
626 }
627
628 #ifdef HOST_EXECUTABLE_SUFFIX
629 /* Some systems have a suffix for executable files.
630 So try appending that. */
631 strcpy (temp, name);
632 strcat (temp, HOST_EXECUTABLE_SUFFIX);
633
634 if (access (temp, X_OK) == 0)
635 return temp;
636 #endif
637
638 if (debug)
639 fprintf (stderr, " - failed to locate using absolute path\n");
640 }
641 else
642 for (pl = pprefix->plist; pl; pl = pl->next)
643 {
644 struct stat st;
645
646 strcpy (temp, pl->prefix);
647 strcat (temp, name);
648
649 if (stat (temp, &st) >= 0
650 && ! S_ISDIR (st.st_mode)
651 && access (temp, X_OK) == 0)
652 return temp;
653
654 #ifdef HOST_EXECUTABLE_SUFFIX
655 /* Some systems have a suffix for executable files.
656 So try appending that. */
657 strcat (temp, HOST_EXECUTABLE_SUFFIX);
658
659 if (stat (temp, &st) >= 0
660 && ! S_ISDIR (st.st_mode)
661 && access (temp, X_OK) == 0)
662 return temp;
663 #endif
664 }
665
666 if (debug && pprefix->plist == NULL)
667 fprintf (stderr, " - failed: no entries in prefix list\n");
668
669 free (temp);
670 return 0;
671 }
672
673 /* Add an entry for PREFIX to prefix list PPREFIX. */
674
675 static void
add_prefix(struct path_prefix * pprefix,const char * prefix)676 add_prefix (struct path_prefix *pprefix, const char *prefix)
677 {
678 struct prefix_list *pl, **prev;
679 int len;
680
681 if (pprefix->plist)
682 {
683 for (pl = pprefix->plist; pl->next; pl = pl->next)
684 ;
685 prev = &pl->next;
686 }
687 else
688 prev = &pprefix->plist;
689
690 /* Keep track of the longest prefix. */
691
692 len = strlen (prefix);
693 if (len > pprefix->max_len)
694 pprefix->max_len = len;
695
696 pl = xmalloc (sizeof (struct prefix_list));
697 pl->prefix = xstrdup (prefix);
698
699 if (*prev)
700 pl->next = *prev;
701 else
702 pl->next = (struct prefix_list *) 0;
703 *prev = pl;
704 }
705
706 /* Take the value of the environment variable ENV, break it into a path, and
707 add of the entries to PPREFIX. */
708
709 static void
prefix_from_env(const char * env,struct path_prefix * pprefix)710 prefix_from_env (const char *env, struct path_prefix *pprefix)
711 {
712 const char *p;
713 GET_ENVIRONMENT (p, env);
714
715 if (p)
716 prefix_from_string (p, pprefix);
717 }
718
719 static void
prefix_from_string(const char * p,struct path_prefix * pprefix)720 prefix_from_string (const char *p, struct path_prefix *pprefix)
721 {
722 const char *startp, *endp;
723 char *nstore = xmalloc (strlen (p) + 3);
724
725 if (debug)
726 fprintf (stderr, "Convert string '%s' into prefixes, separator = '%c'\n", p, PATH_SEPARATOR);
727
728 startp = endp = p;
729 while (1)
730 {
731 if (*endp == PATH_SEPARATOR || *endp == 0)
732 {
733 strncpy (nstore, startp, endp-startp);
734 if (endp == startp)
735 {
736 strcpy (nstore, "./");
737 }
738 else if (! IS_DIR_SEPARATOR (endp[-1]))
739 {
740 nstore[endp-startp] = DIR_SEPARATOR;
741 nstore[endp-startp+1] = 0;
742 }
743 else
744 nstore[endp-startp] = 0;
745
746 if (debug)
747 fprintf (stderr, " - add prefix: %s\n", nstore);
748
749 add_prefix (pprefix, nstore);
750 if (*endp == 0)
751 break;
752 endp = startp = endp + 1;
753 }
754 else
755 endp++;
756 }
757 }
758
759 /* Main program. */
760
761 int
main(int argc,char ** argv)762 main (int argc, char **argv)
763 {
764 static const char *const ld_suffix = "ld";
765 static const char *const real_ld_suffix = "real-ld";
766 static const char *const collect_ld_suffix = "collect-ld";
767 static const char *const nm_suffix = "nm";
768 static const char *const gnm_suffix = "gnm";
769 #ifdef LDD_SUFFIX
770 static const char *const ldd_suffix = LDD_SUFFIX;
771 #endif
772 static const char *const strip_suffix = "strip";
773 static const char *const gstrip_suffix = "gstrip";
774
775 #ifdef CROSS_COMPILE
776 /* If we look for a program in the compiler directories, we just use
777 the short name, since these directories are already system-specific.
778 But it we look for a program in the system directories, we need to
779 qualify the program name with the target machine. */
780
781 const char *const full_ld_suffix =
782 concat(target_machine, "-", ld_suffix, NULL);
783 const char *const full_nm_suffix =
784 concat (target_machine, "-", nm_suffix, NULL);
785 const char *const full_gnm_suffix =
786 concat (target_machine, "-", gnm_suffix, NULL);
787 #ifdef LDD_SUFFIX
788 const char *const full_ldd_suffix =
789 concat (target_machine, "-", ldd_suffix, NULL);
790 #endif
791 const char *const full_strip_suffix =
792 concat (target_machine, "-", strip_suffix, NULL);
793 const char *const full_gstrip_suffix =
794 concat (target_machine, "-", gstrip_suffix, NULL);
795 #else
796 const char *const full_ld_suffix = ld_suffix;
797 const char *const full_nm_suffix = nm_suffix;
798 const char *const full_gnm_suffix = gnm_suffix;
799 #ifdef LDD_SUFFIX
800 const char *const full_ldd_suffix = ldd_suffix;
801 #endif
802 const char *const full_strip_suffix = strip_suffix;
803 const char *const full_gstrip_suffix = gstrip_suffix;
804 #endif /* CROSS_COMPILE */
805
806 const char *arg;
807 FILE *outf;
808 #ifdef COLLECT_EXPORT_LIST
809 FILE *exportf;
810 #endif
811 const char *ld_file_name;
812 const char *p;
813 char **c_argv;
814 const char **c_ptr;
815 char **ld1_argv;
816 const char **ld1;
817 char **ld2_argv;
818 const char **ld2;
819 char **object_lst;
820 const char **object;
821 int first_file;
822 int num_c_args = argc+9;
823
824 no_demangle = !! getenv ("COLLECT_NO_DEMANGLE");
825
826 /* Suppress demangling by the real linker, which may be broken. */
827 putenv (xstrdup ("COLLECT_NO_DEMANGLE="));
828
829 #if defined (COLLECT2_HOST_INITIALIZATION)
830 /* Perform system dependent initialization, if necessary. */
831 COLLECT2_HOST_INITIALIZATION;
832 #endif
833
834 #ifdef SIGCHLD
835 /* We *MUST* set SIGCHLD to SIG_DFL so that the wait4() call will
836 receive the signal. A different setting is inheritable */
837 signal (SIGCHLD, SIG_DFL);
838 #endif
839
840 gcc_init_libintl ();
841
842 /* Do not invoke xcalloc before this point, since locale needs to be
843 set first, in case a diagnostic is issued. */
844
845 ld1 = (const char **)(ld1_argv = xcalloc(sizeof (char *), argc+3));
846 ld2 = (const char **)(ld2_argv = xcalloc(sizeof (char *), argc+10));
847 object = (const char **)(object_lst = xcalloc(sizeof (char *), argc));
848
849 #ifdef DEBUG
850 debug = 1;
851 #endif
852
853 /* Parse command line early for instances of -debug. This allows
854 the debug flag to be set before functions like find_a_file()
855 are called. */
856 {
857 int i;
858
859 for (i = 1; argv[i] != NULL; i ++)
860 {
861 if (! strcmp (argv[i], "-debug"))
862 debug = 1;
863 COLLECT_PARSE_FLAG (argv[i]);
864 }
865 vflag = debug;
866 }
867
868 #ifndef DEFAULT_A_OUT_NAME
869 output_file = "a.out";
870 #else
871 output_file = DEFAULT_A_OUT_NAME;
872 #endif
873
874 obstack_begin (&temporary_obstack, 0);
875 temporary_firstobj = obstack_alloc (&temporary_obstack, 0);
876
877 current_demangling_style = auto_demangling;
878 p = getenv ("COLLECT_GCC_OPTIONS");
879 while (p && *p)
880 {
881 const char *q = extract_string (&p);
882 if (*q == '-' && (q[1] == 'm' || q[1] == 'f'))
883 num_c_args++;
884 }
885 obstack_free (&temporary_obstack, temporary_firstobj);
886
887 /* -fno-profile-arcs -fno-test-coverage -fno-branch-probabilities
888 -fno-exceptions -w */
889 num_c_args += 5;
890
891 c_ptr = (const char **) (c_argv = xcalloc (sizeof (char *), num_c_args));
892
893 if (argc < 2)
894 fatal ("no arguments");
895
896 #ifdef SIGQUIT
897 if (signal (SIGQUIT, SIG_IGN) != SIG_IGN)
898 signal (SIGQUIT, handler);
899 #endif
900 if (signal (SIGINT, SIG_IGN) != SIG_IGN)
901 signal (SIGINT, handler);
902 #ifdef SIGALRM
903 if (signal (SIGALRM, SIG_IGN) != SIG_IGN)
904 signal (SIGALRM, handler);
905 #endif
906 #ifdef SIGHUP
907 if (signal (SIGHUP, SIG_IGN) != SIG_IGN)
908 signal (SIGHUP, handler);
909 #endif
910 if (signal (SIGSEGV, SIG_IGN) != SIG_IGN)
911 signal (SIGSEGV, handler);
912 #ifdef SIGBUS
913 if (signal (SIGBUS, SIG_IGN) != SIG_IGN)
914 signal (SIGBUS, handler);
915 #endif
916
917 /* Extract COMPILER_PATH and PATH into our prefix list. */
918 prefix_from_env ("COMPILER_PATH", &cpath);
919 prefix_from_env ("PATH", &path);
920
921 /* Try to discover a valid linker/nm/strip to use. */
922
923 /* Maybe we know the right file to use (if not cross). */
924 ld_file_name = 0;
925 #ifdef DEFAULT_LINKER
926 if (access (DEFAULT_LINKER, X_OK) == 0)
927 ld_file_name = DEFAULT_LINKER;
928 if (ld_file_name == 0)
929 #endif
930 #ifdef REAL_LD_FILE_NAME
931 ld_file_name = find_a_file (&path, REAL_LD_FILE_NAME);
932 if (ld_file_name == 0)
933 #endif
934 /* Search the (target-specific) compiler dirs for ld'. */
935 ld_file_name = find_a_file (&cpath, real_ld_suffix);
936 /* Likewise for `collect-ld'. */
937 if (ld_file_name == 0)
938 ld_file_name = find_a_file (&cpath, collect_ld_suffix);
939 /* Search the compiler directories for `ld'. We have protection against
940 recursive calls in find_a_file. */
941 if (ld_file_name == 0)
942 ld_file_name = find_a_file (&cpath, ld_suffix);
943 /* Search the ordinary system bin directories
944 for `ld' (if native linking) or `TARGET-ld' (if cross). */
945 if (ld_file_name == 0)
946 ld_file_name = find_a_file (&path, full_ld_suffix);
947
948 #ifdef REAL_NM_FILE_NAME
949 nm_file_name = find_a_file (&path, REAL_NM_FILE_NAME);
950 if (nm_file_name == 0)
951 #endif
952 nm_file_name = find_a_file (&cpath, gnm_suffix);
953 if (nm_file_name == 0)
954 nm_file_name = find_a_file (&path, full_gnm_suffix);
955 if (nm_file_name == 0)
956 nm_file_name = find_a_file (&cpath, nm_suffix);
957 if (nm_file_name == 0)
958 nm_file_name = find_a_file (&path, full_nm_suffix);
959
960 #ifdef LDD_SUFFIX
961 ldd_file_name = find_a_file (&cpath, ldd_suffix);
962 if (ldd_file_name == 0)
963 ldd_file_name = find_a_file (&path, full_ldd_suffix);
964 #endif
965
966 #ifdef REAL_STRIP_FILE_NAME
967 strip_file_name = find_a_file (&path, REAL_STRIP_FILE_NAME);
968 if (strip_file_name == 0)
969 #endif
970 strip_file_name = find_a_file (&cpath, gstrip_suffix);
971 if (strip_file_name == 0)
972 strip_file_name = find_a_file (&path, full_gstrip_suffix);
973 if (strip_file_name == 0)
974 strip_file_name = find_a_file (&cpath, strip_suffix);
975 if (strip_file_name == 0)
976 strip_file_name = find_a_file (&path, full_strip_suffix);
977
978 /* Determine the full path name of the C compiler to use. */
979 c_file_name = getenv ("COLLECT_GCC");
980 if (c_file_name == 0)
981 {
982 #ifdef CROSS_COMPILE
983 c_file_name = concat (target_machine, "-gcc", NULL);
984 #else
985 c_file_name = "gcc";
986 #endif
987 }
988
989 p = find_a_file (&cpath, c_file_name);
990
991 /* Here it should be safe to use the system search path since we should have
992 already qualified the name of the compiler when it is needed. */
993 if (p == 0)
994 p = find_a_file (&path, c_file_name);
995
996 if (p)
997 c_file_name = p;
998
999 *ld1++ = *ld2++ = ld_file_name;
1000
1001 /* Make temp file names. */
1002 c_file = make_temp_file (".c");
1003 o_file = make_temp_file (".o");
1004 #ifdef COLLECT_EXPORT_LIST
1005 export_file = make_temp_file (".x");
1006 #endif
1007 ldout = make_temp_file (".ld");
1008 *c_ptr++ = c_file_name;
1009 *c_ptr++ = "-x";
1010 *c_ptr++ = "c";
1011 *c_ptr++ = "-c";
1012 *c_ptr++ = "-o";
1013 *c_ptr++ = o_file;
1014
1015 #ifdef COLLECT_EXPORT_LIST
1016 /* Generate a list of directories from LIBPATH. */
1017 prefix_from_env ("LIBPATH", &libpath_lib_dirs);
1018 /* Add to this list also two standard directories where
1019 AIX loader always searches for libraries. */
1020 add_prefix (&libpath_lib_dirs, "/lib");
1021 add_prefix (&libpath_lib_dirs, "/usr/lib");
1022 #endif
1023
1024 /* Get any options that the upper GCC wants to pass to the sub-GCC.
1025
1026 AIX support needs to know if -shared has been specified before
1027 parsing commandline arguments. */
1028
1029 p = getenv ("COLLECT_GCC_OPTIONS");
1030 while (p && *p)
1031 {
1032 const char *q = extract_string (&p);
1033 if (*q == '-' && (q[1] == 'm' || q[1] == 'f'))
1034 *c_ptr++ = xstrdup (q);
1035 if (strcmp (q, "-EL") == 0 || strcmp (q, "-EB") == 0)
1036 *c_ptr++ = xstrdup (q);
1037 if (strcmp (q, "-shared") == 0)
1038 shared_obj = 1;
1039 if (*q == '-' && q[1] == 'B')
1040 {
1041 *c_ptr++ = xstrdup (q);
1042 if (q[2] == 0)
1043 {
1044 q = extract_string (&p);
1045 *c_ptr++ = xstrdup (q);
1046 }
1047 }
1048 }
1049 obstack_free (&temporary_obstack, temporary_firstobj);
1050 *c_ptr++ = "-fno-profile-arcs";
1051 *c_ptr++ = "-fno-test-coverage";
1052 *c_ptr++ = "-fno-branch-probabilities";
1053 *c_ptr++ = "-fno-exceptions";
1054 *c_ptr++ = "-w";
1055
1056 /* !!! When GCC calls collect2,
1057 it does not know whether it is calling collect2 or ld.
1058 So collect2 cannot meaningfully understand any options
1059 except those ld understands.
1060 If you propose to make GCC pass some other option,
1061 just imagine what will happen if ld is really ld!!! */
1062
1063 /* Parse arguments. Remember output file spec, pass the rest to ld. */
1064 /* After the first file, put in the c++ rt0. */
1065
1066 first_file = 1;
1067 while ((arg = *++argv) != (char *) 0)
1068 {
1069 *ld1++ = *ld2++ = arg;
1070
1071 if (arg[0] == '-')
1072 {
1073 switch (arg[1])
1074 {
1075 #ifdef COLLECT_EXPORT_LIST
1076 /* We want to disable automatic exports on AIX when user
1077 explicitly puts an export list in command line */
1078 case 'b':
1079 if (arg[2] == 'E' || strncmp (&arg[2], "export", 6) == 0)
1080 export_flag = 1;
1081 else if (arg[2] == '6' && arg[3] == '4')
1082 aix64_flag = 1;
1083 break;
1084 #endif
1085
1086 case 'd':
1087 if (!strcmp (arg, "-debug"))
1088 {
1089 /* Already parsed. */
1090 ld1--;
1091 ld2--;
1092 }
1093 break;
1094
1095 case 'l':
1096 if (first_file)
1097 {
1098 /* place o_file BEFORE this argument! */
1099 first_file = 0;
1100 ld2--;
1101 *ld2++ = o_file;
1102 *ld2++ = arg;
1103 }
1104 #ifdef COLLECT_EXPORT_LIST
1105 {
1106 /* Resolving full library name. */
1107 const char *s = resolve_lib_name (arg+2);
1108
1109 /* Saving a full library name. */
1110 add_to_list (&libs, s);
1111 }
1112 #endif
1113 break;
1114
1115 #ifdef COLLECT_EXPORT_LIST
1116 /* Saving directories where to search for libraries. */
1117 case 'L':
1118 add_prefix (&cmdline_lib_dirs, arg+2);
1119 break;
1120 #else
1121 #if LINK_ELIMINATE_DUPLICATE_LDIRECTORIES
1122 case 'L':
1123 if (is_in_args (arg, (const char **) ld1_argv, ld1-1))
1124 --ld1;
1125 break;
1126 #endif /* LINK_ELIMINATE_DUPLICATE_LDIRECTORIES */
1127 #endif
1128
1129 case 'o':
1130 if (arg[2] == '\0')
1131 output_file = *ld1++ = *ld2++ = *++argv;
1132 else if (1
1133 #ifdef SWITCHES_NEED_SPACES
1134 && ! strchr (SWITCHES_NEED_SPACES, arg[1])
1135 #endif
1136 )
1137
1138 output_file = &arg[2];
1139 break;
1140
1141 case 'r':
1142 if (arg[2] == '\0')
1143 rflag = 1;
1144 break;
1145
1146 case 's':
1147 if (arg[2] == '\0' && do_collecting)
1148 {
1149 /* We must strip after the nm run, otherwise C++ linking
1150 will not work. Thus we strip in the second ld run, or
1151 else with strip if there is no second ld run. */
1152 strip_flag = 1;
1153 ld1--;
1154 }
1155 break;
1156
1157 case 'v':
1158 if (arg[2] == '\0')
1159 vflag = 1;
1160 break;
1161 }
1162 }
1163 else if ((p = strrchr (arg, '.')) != (char *) 0
1164 && (strcmp (p, ".o") == 0 || strcmp (p, ".a") == 0
1165 || strcmp (p, ".so") == 0 || strcmp (p, ".lo") == 0
1166 || strcmp (p, ".obj") == 0))
1167 {
1168 if (first_file)
1169 {
1170 first_file = 0;
1171 if (p[1] == 'o')
1172 *ld2++ = o_file;
1173 else
1174 {
1175 /* place o_file BEFORE this argument! */
1176 ld2--;
1177 *ld2++ = o_file;
1178 *ld2++ = arg;
1179 }
1180 }
1181 if (p[1] == 'o' || p[1] == 'l')
1182 *object++ = arg;
1183 #ifdef COLLECT_EXPORT_LIST
1184 /* libraries can be specified directly, i.e. without -l flag. */
1185 else
1186 {
1187 /* Saving a full library name. */
1188 add_to_list (&libs, arg);
1189 }
1190 #endif
1191 }
1192 }
1193
1194 #ifdef COLLECT_EXPORT_LIST
1195 /* This is added only for debugging purposes. */
1196 if (debug)
1197 {
1198 fprintf (stderr, "List of libraries:\n");
1199 dump_list (stderr, "\t", libs.first);
1200 }
1201
1202 /* The AIX linker will discard static constructors in object files if
1203 nothing else in the file is referenced, so look at them first. */
1204 {
1205 const char **export_object_lst = (const char **)object_lst;
1206
1207 while (export_object_lst < object)
1208 scan_prog_file (*export_object_lst++, PASS_OBJ);
1209 }
1210 {
1211 struct id *list = libs.first;
1212
1213 for (; list; list = list->next)
1214 scan_prog_file (list->name, PASS_FIRST);
1215 }
1216
1217 if (exports.first)
1218 {
1219 char *buf = concat ("-bE:", export_file, NULL);
1220
1221 *ld1++ = buf;
1222 *ld2++ = buf;
1223
1224 exportf = fopen (export_file, "w");
1225 if (exportf == (FILE *) 0)
1226 fatal_perror ("fopen %s", export_file);
1227 write_aix_file (exportf, exports.first);
1228 if (fclose (exportf))
1229 fatal_perror ("fclose %s", export_file);
1230 }
1231 #endif
1232
1233 *c_ptr++ = c_file;
1234 *c_ptr = *ld1 = *object = (char *) 0;
1235
1236 if (vflag)
1237 {
1238 notice ("collect2 version %s", version_string);
1239 #ifdef TARGET_VERSION
1240 TARGET_VERSION;
1241 #endif
1242 fprintf (stderr, "\n");
1243 }
1244
1245 if (debug)
1246 {
1247 const char *ptr;
1248 fprintf (stderr, "ld_file_name = %s\n",
1249 (ld_file_name ? ld_file_name : "not found"));
1250 fprintf (stderr, "c_file_name = %s\n",
1251 (c_file_name ? c_file_name : "not found"));
1252 fprintf (stderr, "nm_file_name = %s\n",
1253 (nm_file_name ? nm_file_name : "not found"));
1254 #ifdef LDD_SUFFIX
1255 fprintf (stderr, "ldd_file_name = %s\n",
1256 (ldd_file_name ? ldd_file_name : "not found"));
1257 #endif
1258 fprintf (stderr, "strip_file_name = %s\n",
1259 (strip_file_name ? strip_file_name : "not found"));
1260 fprintf (stderr, "c_file = %s\n",
1261 (c_file ? c_file : "not found"));
1262 fprintf (stderr, "o_file = %s\n",
1263 (o_file ? o_file : "not found"));
1264
1265 ptr = getenv ("COLLECT_GCC_OPTIONS");
1266 if (ptr)
1267 fprintf (stderr, "COLLECT_GCC_OPTIONS = %s\n", ptr);
1268
1269 ptr = getenv ("COLLECT_GCC");
1270 if (ptr)
1271 fprintf (stderr, "COLLECT_GCC = %s\n", ptr);
1272
1273 ptr = getenv ("COMPILER_PATH");
1274 if (ptr)
1275 fprintf (stderr, "COMPILER_PATH = %s\n", ptr);
1276
1277 ptr = getenv (LIBRARY_PATH_ENV);
1278 if (ptr)
1279 fprintf (stderr, "%-20s= %s\n", LIBRARY_PATH_ENV, ptr);
1280
1281 fprintf (stderr, "\n");
1282 }
1283
1284 /* Load the program, searching all libraries and attempting to provide
1285 undefined symbols from repository information. */
1286
1287 /* On AIX we do this later. */
1288 #ifndef COLLECT_EXPORT_LIST
1289 do_tlink (ld1_argv, object_lst);
1290 #endif
1291
1292 /* If -r or they will be run via some other method, do not build the
1293 constructor or destructor list, just return now. */
1294 if (rflag
1295 #ifndef COLLECT_EXPORT_LIST
1296 || ! do_collecting
1297 #endif
1298 )
1299 {
1300 #ifdef COLLECT_EXPORT_LIST
1301 /* Do the link we avoided above if we are exiting. */
1302 do_tlink (ld1_argv, object_lst);
1303
1304 /* But make sure we delete the export file we may have created. */
1305 if (export_file != 0 && export_file[0])
1306 maybe_unlink (export_file);
1307 #endif
1308 maybe_unlink (c_file);
1309 maybe_unlink (o_file);
1310 return 0;
1311 }
1312
1313 /* Examine the namelist with nm and search it for static constructors
1314 and destructors to call.
1315 Write the constructor and destructor tables to a .s file and reload. */
1316
1317 /* On AIX we already scanned for global constructors/destructors. */
1318 #ifndef COLLECT_EXPORT_LIST
1319 scan_prog_file (output_file, PASS_FIRST);
1320 #endif
1321
1322 #ifdef SCAN_LIBRARIES
1323 scan_libraries (output_file);
1324 #endif
1325
1326 if (debug)
1327 {
1328 notice ("%d constructor(s) found\n", constructors.number);
1329 notice ("%d destructor(s) found\n", destructors.number);
1330 notice ("%d frame table(s) found\n", frame_tables.number);
1331 }
1332
1333 if (constructors.number == 0 && destructors.number == 0
1334 && frame_tables.number == 0
1335 #if defined (SCAN_LIBRARIES) || defined (COLLECT_EXPORT_LIST)
1336 /* If we will be running these functions ourselves, we want to emit
1337 stubs into the shared library so that we do not have to relink
1338 dependent programs when we add static objects. */
1339 && ! shared_obj
1340 #endif
1341 )
1342 {
1343 #ifdef COLLECT_EXPORT_LIST
1344 /* Do tlink without additional code generation. */
1345 do_tlink (ld1_argv, object_lst);
1346 #endif
1347 /* Strip now if it was requested on the command line. */
1348 if (strip_flag)
1349 {
1350 char **real_strip_argv = xcalloc (sizeof (char *), 3);
1351 const char ** strip_argv = (const char **) real_strip_argv;
1352
1353 strip_argv[0] = strip_file_name;
1354 strip_argv[1] = output_file;
1355 strip_argv[2] = (char *) 0;
1356 fork_execute ("strip", real_strip_argv);
1357 }
1358
1359 #ifdef COLLECT_EXPORT_LIST
1360 maybe_unlink (export_file);
1361 #endif
1362 maybe_unlink (c_file);
1363 maybe_unlink (o_file);
1364 return 0;
1365 }
1366
1367 /* Sort ctor and dtor lists by priority. */
1368 sort_ids (&constructors);
1369 sort_ids (&destructors);
1370
1371 maybe_unlink(output_file);
1372 outf = fopen (c_file, "w");
1373 if (outf == (FILE *) 0)
1374 fatal_perror ("fopen %s", c_file);
1375
1376 write_c_file (outf, c_file);
1377
1378 if (fclose (outf))
1379 fatal_perror ("fclose %s", c_file);
1380
1381 /* Tell the linker that we have initializer and finalizer functions. */
1382 #ifdef LD_INIT_SWITCH
1383 #ifdef COLLECT_EXPORT_LIST
1384 *ld2++ = concat (LD_INIT_SWITCH, ":", initname, ":", fininame, NULL);
1385 #else
1386 *ld2++ = LD_INIT_SWITCH;
1387 *ld2++ = initname;
1388 *ld2++ = LD_FINI_SWITCH;
1389 *ld2++ = fininame;
1390 #endif
1391 #endif
1392
1393 #ifdef COLLECT_EXPORT_LIST
1394 if (shared_obj)
1395 {
1396 /* If we did not add export flag to link arguments before, add it to
1397 second link phase now. No new exports should have been added. */
1398 if (! exports.first)
1399 *ld2++ = concat ("-bE:", export_file, NULL);
1400
1401 #ifndef LD_INIT_SWITCH
1402 add_to_list (&exports, initname);
1403 add_to_list (&exports, fininame);
1404 add_to_list (&exports, "_GLOBAL__DI");
1405 add_to_list (&exports, "_GLOBAL__DD");
1406 #endif
1407 exportf = fopen (export_file, "w");
1408 if (exportf == (FILE *) 0)
1409 fatal_perror ("fopen %s", export_file);
1410 write_aix_file (exportf, exports.first);
1411 if (fclose (exportf))
1412 fatal_perror ("fclose %s", export_file);
1413 }
1414 #endif
1415
1416 /* End of arguments to second link phase. */
1417 *ld2 = (char*) 0;
1418
1419 if (debug)
1420 {
1421 fprintf (stderr, "\n========== output_file = %s, c_file = %s\n",
1422 output_file, c_file);
1423 write_c_file (stderr, "stderr");
1424 fprintf (stderr, "========== end of c_file\n\n");
1425 #ifdef COLLECT_EXPORT_LIST
1426 fprintf (stderr, "\n========== export_file = %s\n", export_file);
1427 write_aix_file (stderr, exports.first);
1428 fprintf (stderr, "========== end of export_file\n\n");
1429 #endif
1430 }
1431
1432 /* Assemble the constructor and destructor tables.
1433 Link the tables in with the rest of the program. */
1434
1435 fork_execute ("gcc", c_argv);
1436 #ifdef COLLECT_EXPORT_LIST
1437 /* On AIX we must call tlink because of possible templates resolution. */
1438 do_tlink (ld2_argv, object_lst);
1439 #else
1440 /* Otherwise, simply call ld because tlink is already done. */
1441 fork_execute ("ld", ld2_argv);
1442
1443 /* Let scan_prog_file do any final mods (OSF/rose needs this for
1444 constructors/destructors in shared libraries. */
1445 scan_prog_file (output_file, PASS_SECOND);
1446 #endif
1447
1448 maybe_unlink (c_file);
1449 maybe_unlink (o_file);
1450
1451 #ifdef COLLECT_EXPORT_LIST
1452 maybe_unlink (export_file);
1453 #endif
1454
1455 return 0;
1456 }
1457
1458
1459 /* Wait for a process to finish, and exit if a nonzero status is found. */
1460
1461 int
collect_wait(const char * prog)1462 collect_wait (const char *prog)
1463 {
1464 int status;
1465
1466 pwait (pid, &status, 0);
1467 if (status)
1468 {
1469 if (WIFSIGNALED (status))
1470 {
1471 int sig = WTERMSIG (status);
1472 error ("%s terminated with signal %d [%s]%s",
1473 prog, sig, strsignal(sig),
1474 WCOREDUMP(status) ? ", core dumped" : "");
1475 collect_exit (FATAL_EXIT_CODE);
1476 }
1477
1478 if (WIFEXITED (status))
1479 return WEXITSTATUS (status);
1480 }
1481 return 0;
1482 }
1483
1484 static void
do_wait(const char * prog)1485 do_wait (const char *prog)
1486 {
1487 int ret = collect_wait (prog);
1488 if (ret != 0)
1489 {
1490 error ("%s returned %d exit status", prog, ret);
1491 collect_exit (ret);
1492 }
1493 }
1494
1495
1496 /* Execute a program, and wait for the reply. */
1497
1498 void
collect_execute(const char * prog,char ** argv,const char * redir)1499 collect_execute (const char *prog, char **argv, const char *redir)
1500 {
1501 char *errmsg_fmt;
1502 char *errmsg_arg;
1503 int redir_handle = -1;
1504 int stdout_save = -1;
1505 int stderr_save = -1;
1506
1507 if (vflag || debug)
1508 {
1509 char **p_argv;
1510 const char *str;
1511
1512 if (argv[0])
1513 fprintf (stderr, "%s", argv[0]);
1514 else
1515 notice ("[cannot find %s]", prog);
1516
1517 for (p_argv = &argv[1]; (str = *p_argv) != (char *) 0; p_argv++)
1518 fprintf (stderr, " %s", str);
1519
1520 fprintf (stderr, "\n");
1521 }
1522
1523 fflush (stdout);
1524 fflush (stderr);
1525
1526 /* If we cannot find a program we need, complain error. Do this here
1527 since we might not end up needing something that we could not find. */
1528
1529 if (argv[0] == 0)
1530 fatal ("cannot find `%s'", prog);
1531
1532 if (redir)
1533 {
1534 /* Open response file. */
1535 redir_handle = open (redir, O_WRONLY | O_TRUNC | O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
1536
1537 /* Duplicate the stdout and stderr file handles
1538 so they can be restored later. */
1539 stdout_save = dup (STDOUT_FILENO);
1540 if (stdout_save == -1)
1541 fatal_perror ("redirecting stdout: %s", redir);
1542 stderr_save = dup (STDERR_FILENO);
1543 if (stderr_save == -1)
1544 fatal_perror ("redirecting stdout: %s", redir);
1545
1546 /* Redirect stdout & stderr to our response file. */
1547 dup2 (redir_handle, STDOUT_FILENO);
1548 dup2 (redir_handle, STDERR_FILENO);
1549 }
1550
1551 pid = pexecute (argv[0], argv, argv[0], NULL, &errmsg_fmt, &errmsg_arg,
1552 (PEXECUTE_FIRST | PEXECUTE_LAST | PEXECUTE_SEARCH));
1553
1554 if (redir)
1555 {
1556 /* Restore stdout and stderr to their previous settings. */
1557 dup2 (stdout_save, STDOUT_FILENO);
1558 dup2 (stderr_save, STDERR_FILENO);
1559
1560 /* Close response file. */
1561 close (redir_handle);
1562 }
1563
1564 if (pid == -1)
1565 fatal_perror (errmsg_fmt, errmsg_arg);
1566 }
1567
1568 static void
fork_execute(const char * prog,char ** argv)1569 fork_execute (const char *prog, char **argv)
1570 {
1571 collect_execute (prog, argv, NULL);
1572 do_wait (prog);
1573 }
1574
1575 /* Unlink a file unless we are debugging. */
1576
1577 static void
maybe_unlink(const char * file)1578 maybe_unlink (const char *file)
1579 {
1580 if (!debug)
1581 unlink (file);
1582 else
1583 notice ("[Leaving %s]\n", file);
1584 }
1585
1586
1587 static long sequence_number = 0;
1588
1589 /* Add a name to a linked list. */
1590
1591 static void
add_to_list(struct head * head_ptr,const char * name)1592 add_to_list (struct head *head_ptr, const char *name)
1593 {
1594 struct id *newid = xcalloc (sizeof (struct id) + strlen (name), 1);
1595 struct id *p;
1596 strcpy (newid->name, name);
1597
1598 if (head_ptr->first)
1599 head_ptr->last->next = newid;
1600 else
1601 head_ptr->first = newid;
1602
1603 /* Check for duplicate symbols. */
1604 for (p = head_ptr->first;
1605 strcmp (name, p->name) != 0;
1606 p = p->next)
1607 ;
1608 if (p != newid)
1609 {
1610 head_ptr->last->next = 0;
1611 free (newid);
1612 return;
1613 }
1614
1615 newid->sequence = ++sequence_number;
1616 head_ptr->last = newid;
1617 head_ptr->number++;
1618 }
1619
1620 /* Grab the init priority number from an init function name that
1621 looks like "_GLOBAL_.I.12345.foo". */
1622
1623 static int
extract_init_priority(const char * name)1624 extract_init_priority (const char *name)
1625 {
1626 int pos = 0, pri;
1627
1628 while (name[pos] == '_')
1629 ++pos;
1630 pos += 10; /* strlen ("GLOBAL__X_") */
1631
1632 /* Extract init_p number from ctor/dtor name. */
1633 pri = atoi (name + pos);
1634 return pri ? pri : DEFAULT_INIT_PRIORITY;
1635 }
1636
1637 /* Insertion sort the ids from ctor/dtor list HEAD_PTR in descending order.
1638 ctors will be run from right to left, dtors from left to right. */
1639
1640 static void
sort_ids(struct head * head_ptr)1641 sort_ids (struct head *head_ptr)
1642 {
1643 /* id holds the current element to insert. id_next holds the next
1644 element to insert. id_ptr iterates through the already sorted elements
1645 looking for the place to insert id. */
1646 struct id *id, *id_next, **id_ptr;
1647
1648 id = head_ptr->first;
1649
1650 /* We don't have any sorted elements yet. */
1651 head_ptr->first = NULL;
1652
1653 for (; id; id = id_next)
1654 {
1655 id_next = id->next;
1656 id->sequence = extract_init_priority (id->name);
1657
1658 for (id_ptr = &(head_ptr->first); ; id_ptr = &((*id_ptr)->next))
1659 if (*id_ptr == NULL
1660 /* If the sequence numbers are the same, we put the id from the
1661 file later on the command line later in the list. */
1662 || id->sequence > (*id_ptr)->sequence
1663 /* Hack: do lexical compare, too.
1664 || (id->sequence == (*id_ptr)->sequence
1665 && strcmp (id->name, (*id_ptr)->name) > 0) */
1666 )
1667 {
1668 id->next = *id_ptr;
1669 *id_ptr = id;
1670 break;
1671 }
1672 }
1673
1674 /* Now set the sequence numbers properly so write_c_file works. */
1675 for (id = head_ptr->first; id; id = id->next)
1676 id->sequence = ++sequence_number;
1677 }
1678
1679 /* Write: `prefix', the names on list LIST, `suffix'. */
1680
1681 static void
write_list(FILE * stream,const char * prefix,struct id * list)1682 write_list (FILE *stream, const char *prefix, struct id *list)
1683 {
1684 while (list)
1685 {
1686 fprintf (stream, "%sx%d,\n", prefix, list->sequence);
1687 list = list->next;
1688 }
1689 }
1690
1691 #if LINK_ELIMINATE_DUPLICATE_LDIRECTORIES
1692 /* Given a STRING, return nonzero if it occurs in the list in range
1693 [ARGS_BEGIN,ARGS_END). */
1694
1695 static int
is_in_args(const char * string,const char ** args_begin,const char ** args_end)1696 is_in_args (const char *string, const char **args_begin,
1697 const char **args_end)
1698 {
1699 const char **args_pointer;
1700 for (args_pointer = args_begin; args_pointer != args_end; ++args_pointer)
1701 if (strcmp (string, *args_pointer) == 0)
1702 return 1;
1703 return 0;
1704 }
1705 #endif /* LINK_ELIMINATE_DUPLICATE_LDIRECTORIES */
1706
1707 #ifdef COLLECT_EXPORT_LIST
1708 /* This function is really used only on AIX, but may be useful. */
1709 #if 0
1710 static int
1711 is_in_list (const char *prefix, struct id *list)
1712 {
1713 while (list)
1714 {
1715 if (!strcmp (prefix, list->name)) return 1;
1716 list = list->next;
1717 }
1718 return 0;
1719 }
1720 #endif
1721 #endif /* COLLECT_EXPORT_LIST */
1722
1723 /* Added for debugging purpose. */
1724 #ifdef COLLECT_EXPORT_LIST
1725 static void
dump_list(FILE * stream,const char * prefix,struct id * list)1726 dump_list (FILE *stream, const char *prefix, struct id *list)
1727 {
1728 while (list)
1729 {
1730 fprintf (stream, "%s%s,\n", prefix, list->name);
1731 list = list->next;
1732 }
1733 }
1734 #endif
1735
1736 #if 0
1737 static void
1738 dump_prefix_list (FILE *stream, const char *prefix, struct prefix_list *list)
1739 {
1740 while (list)
1741 {
1742 fprintf (stream, "%s%s,\n", prefix, list->prefix);
1743 list = list->next;
1744 }
1745 }
1746 #endif
1747
1748 static void
write_list_with_asm(FILE * stream,const char * prefix,struct id * list)1749 write_list_with_asm (FILE *stream, const char *prefix, struct id *list)
1750 {
1751 while (list)
1752 {
1753 fprintf (stream, "%sx%d __asm__ (\"%s\");\n",
1754 prefix, list->sequence, list->name);
1755 list = list->next;
1756 }
1757 }
1758
1759 /* Write out the constructor and destructor tables statically (for a shared
1760 object), along with the functions to execute them. */
1761
1762 static void
write_c_file_stat(FILE * stream,const char * name ATTRIBUTE_UNUSED)1763 write_c_file_stat (FILE *stream, const char *name ATTRIBUTE_UNUSED)
1764 {
1765 const char *p, *q;
1766 char *prefix, *r;
1767 int frames = (frame_tables.number > 0);
1768
1769 /* Figure out name of output_file, stripping off .so version. */
1770 p = strrchr (output_file, '/');
1771 if (p == 0)
1772 p = output_file;
1773 else
1774 p++;
1775 q = p;
1776 while (q)
1777 {
1778 q = strchr (q,'.');
1779 if (q == 0)
1780 {
1781 q = p + strlen (p);
1782 break;
1783 }
1784 else
1785 {
1786 if (strncmp (q, ".so", 3) == 0)
1787 {
1788 q += 3;
1789 break;
1790 }
1791 else
1792 q++;
1793 }
1794 }
1795 /* q points to null at end of the string (or . of the .so version) */
1796 prefix = xmalloc (q - p + 1);
1797 strncpy (prefix, p, q - p);
1798 prefix[q - p] = 0;
1799 for (r = prefix; *r; r++)
1800 if (!ISALNUM ((unsigned char)*r))
1801 *r = '_';
1802 if (debug)
1803 notice ("\nwrite_c_file - output name is %s, prefix is %s\n",
1804 output_file, prefix);
1805
1806 initname = concat ("_GLOBAL__FI_", prefix, NULL);
1807 fininame = concat ("_GLOBAL__FD_", prefix, NULL);
1808
1809 free (prefix);
1810
1811 /* Write the tables as C code. */
1812
1813 fprintf (stream, "static int count;\n");
1814 fprintf (stream, "typedef void entry_pt();\n");
1815 write_list_with_asm (stream, "extern entry_pt ", constructors.first);
1816
1817 if (frames)
1818 {
1819 write_list_with_asm (stream, "extern void *", frame_tables.first);
1820
1821 fprintf (stream, "\tstatic void *frame_table[] = {\n");
1822 write_list (stream, "\t\t&", frame_tables.first);
1823 fprintf (stream, "\t0\n};\n");
1824
1825 /* This must match what's in frame.h. */
1826 fprintf (stream, "struct object {\n");
1827 fprintf (stream, " void *pc_begin;\n");
1828 fprintf (stream, " void *pc_end;\n");
1829 fprintf (stream, " void *fde_begin;\n");
1830 fprintf (stream, " void *fde_array;\n");
1831 fprintf (stream, " __SIZE_TYPE__ count;\n");
1832 fprintf (stream, " struct object *next;\n");
1833 fprintf (stream, "};\n");
1834
1835 fprintf (stream, "extern void __register_frame_info_table (void *, struct object *);\n");
1836 fprintf (stream, "extern void *__deregister_frame_info (void *);\n");
1837
1838 fprintf (stream, "static void reg_frame () {\n");
1839 fprintf (stream, "\tstatic struct object ob;\n");
1840 fprintf (stream, "\t__register_frame_info_table (frame_table, &ob);\n");
1841 fprintf (stream, "\t}\n");
1842
1843 fprintf (stream, "static void dereg_frame () {\n");
1844 fprintf (stream, "\t__deregister_frame_info (frame_table);\n");
1845 fprintf (stream, "\t}\n");
1846 }
1847
1848 fprintf (stream, "void %s() {\n", initname);
1849 if (constructors.number > 0 || frames)
1850 {
1851 fprintf (stream, "\tstatic entry_pt *ctors[] = {\n");
1852 write_list (stream, "\t\t", constructors.first);
1853 if (frames)
1854 fprintf (stream, "\treg_frame,\n");
1855 fprintf (stream, "\t};\n");
1856 fprintf (stream, "\tentry_pt **p;\n");
1857 fprintf (stream, "\tif (count++ != 0) return;\n");
1858 fprintf (stream, "\tp = ctors + %d;\n", constructors.number + frames);
1859 fprintf (stream, "\twhile (p > ctors) (*--p)();\n");
1860 }
1861 else
1862 fprintf (stream, "\t++count;\n");
1863 fprintf (stream, "}\n");
1864 write_list_with_asm (stream, "extern entry_pt ", destructors.first);
1865 fprintf (stream, "void %s() {\n", fininame);
1866 if (destructors.number > 0 || frames)
1867 {
1868 fprintf (stream, "\tstatic entry_pt *dtors[] = {\n");
1869 write_list (stream, "\t\t", destructors.first);
1870 if (frames)
1871 fprintf (stream, "\tdereg_frame,\n");
1872 fprintf (stream, "\t};\n");
1873 fprintf (stream, "\tentry_pt **p;\n");
1874 fprintf (stream, "\tif (--count != 0) return;\n");
1875 fprintf (stream, "\tp = dtors;\n");
1876 fprintf (stream, "\twhile (p < dtors + %d) (*p++)();\n",
1877 destructors.number + frames);
1878 }
1879 fprintf (stream, "}\n");
1880
1881 if (shared_obj)
1882 {
1883 COLLECT_SHARED_INIT_FUNC(stream, initname);
1884 COLLECT_SHARED_FINI_FUNC(stream, fininame);
1885 }
1886 }
1887
1888 /* Write the constructor/destructor tables. */
1889
1890 #ifndef LD_INIT_SWITCH
1891 static void
write_c_file_glob(FILE * stream,const char * name ATTRIBUTE_UNUSED)1892 write_c_file_glob (FILE *stream, const char *name ATTRIBUTE_UNUSED)
1893 {
1894 /* Write the tables as C code. */
1895
1896 int frames = (frame_tables.number > 0);
1897
1898 fprintf (stream, "typedef void entry_pt();\n\n");
1899
1900 write_list_with_asm (stream, "extern entry_pt ", constructors.first);
1901
1902 if (frames)
1903 {
1904 write_list_with_asm (stream, "extern void *", frame_tables.first);
1905
1906 fprintf (stream, "\tstatic void *frame_table[] = {\n");
1907 write_list (stream, "\t\t&", frame_tables.first);
1908 fprintf (stream, "\t0\n};\n");
1909
1910 /* This must match what's in frame.h. */
1911 fprintf (stream, "struct object {\n");
1912 fprintf (stream, " void *pc_begin;\n");
1913 fprintf (stream, " void *pc_end;\n");
1914 fprintf (stream, " void *fde_begin;\n");
1915 fprintf (stream, " void *fde_array;\n");
1916 fprintf (stream, " __SIZE_TYPE__ count;\n");
1917 fprintf (stream, " struct object *next;\n");
1918 fprintf (stream, "};\n");
1919
1920 fprintf (stream, "extern void __register_frame_info_table (void *, struct object *);\n");
1921 fprintf (stream, "extern void *__deregister_frame_info (void *);\n");
1922
1923 fprintf (stream, "static void reg_frame () {\n");
1924 fprintf (stream, "\tstatic struct object ob;\n");
1925 fprintf (stream, "\t__register_frame_info_table (frame_table, &ob);\n");
1926 fprintf (stream, "\t}\n");
1927
1928 fprintf (stream, "static void dereg_frame () {\n");
1929 fprintf (stream, "\t__deregister_frame_info (frame_table);\n");
1930 fprintf (stream, "\t}\n");
1931 }
1932
1933 fprintf (stream, "\nentry_pt * __CTOR_LIST__[] = {\n");
1934 fprintf (stream, "\t(entry_pt *) %d,\n", constructors.number + frames);
1935 write_list (stream, "\t", constructors.first);
1936 if (frames)
1937 fprintf (stream, "\treg_frame,\n");
1938 fprintf (stream, "\t0\n};\n\n");
1939
1940 write_list_with_asm (stream, "extern entry_pt ", destructors.first);
1941
1942 fprintf (stream, "\nentry_pt * __DTOR_LIST__[] = {\n");
1943 fprintf (stream, "\t(entry_pt *) %d,\n", destructors.number + frames);
1944 write_list (stream, "\t", destructors.first);
1945 if (frames)
1946 fprintf (stream, "\tdereg_frame,\n");
1947 fprintf (stream, "\t0\n};\n\n");
1948
1949 fprintf (stream, "extern entry_pt %s;\n", NAME__MAIN);
1950 fprintf (stream, "entry_pt *__main_reference = %s;\n\n", NAME__MAIN);
1951 }
1952 #endif /* ! LD_INIT_SWITCH */
1953
1954 static void
write_c_file(FILE * stream,const char * name)1955 write_c_file (FILE *stream, const char *name)
1956 {
1957 fprintf (stream, "#ifdef __cplusplus\nextern \"C\" {\n#endif\n");
1958 #ifndef LD_INIT_SWITCH
1959 if (! shared_obj)
1960 write_c_file_glob (stream, name);
1961 else
1962 #endif
1963 write_c_file_stat (stream, name);
1964 fprintf (stream, "#ifdef __cplusplus\n}\n#endif\n");
1965 }
1966
1967 #ifdef COLLECT_EXPORT_LIST
1968 static void
write_aix_file(FILE * stream,struct id * list)1969 write_aix_file (FILE *stream, struct id *list)
1970 {
1971 for (; list; list = list->next)
1972 {
1973 fputs (list->name, stream);
1974 putc ('\n', stream);
1975 }
1976 }
1977 #endif
1978
1979 #ifdef OBJECT_FORMAT_NONE
1980
1981 /* Generic version to scan the name list of the loaded program for
1982 the symbols g++ uses for static constructors and destructors.
1983
1984 The constructor table begins at __CTOR_LIST__ and contains a count
1985 of the number of pointers (or -1 if the constructors are built in a
1986 separate section by the linker), followed by the pointers to the
1987 constructor functions, terminated with a null pointer. The
1988 destructor table has the same format, and begins at __DTOR_LIST__. */
1989
1990 static void
scan_prog_file(const char * prog_name,enum pass which_pass)1991 scan_prog_file (const char *prog_name, enum pass which_pass)
1992 {
1993 void (*int_handler) (int);
1994 void (*quit_handler) (int);
1995 char *real_nm_argv[4];
1996 const char **nm_argv = (const char **) real_nm_argv;
1997 int argc = 0;
1998 int pipe_fd[2];
1999 char *p, buf[1024];
2000 FILE *inf;
2001
2002 if (which_pass == PASS_SECOND)
2003 return;
2004
2005 /* If we do not have an `nm', complain. */
2006 if (nm_file_name == 0)
2007 fatal ("cannot find `nm'");
2008
2009 nm_argv[argc++] = nm_file_name;
2010 if (NM_FLAGS[0] != '\0')
2011 nm_argv[argc++] = NM_FLAGS;
2012
2013 nm_argv[argc++] = prog_name;
2014 nm_argv[argc++] = (char *) 0;
2015
2016 if (pipe (pipe_fd) < 0)
2017 fatal_perror ("pipe");
2018
2019 inf = fdopen (pipe_fd[0], "r");
2020 if (inf == (FILE *) 0)
2021 fatal_perror ("fdopen");
2022
2023 /* Trace if needed. */
2024 if (vflag)
2025 {
2026 const char **p_argv;
2027 const char *str;
2028
2029 for (p_argv = &nm_argv[0]; (str = *p_argv) != (char *) 0; p_argv++)
2030 fprintf (stderr, " %s", str);
2031
2032 fprintf (stderr, "\n");
2033 }
2034
2035 fflush (stdout);
2036 fflush (stderr);
2037
2038 /* Spawn child nm on pipe. */
2039 pid = vfork ();
2040 if (pid == -1)
2041 fatal_perror (VFORK_STRING);
2042
2043 if (pid == 0) /* child context */
2044 {
2045 /* setup stdout */
2046 if (dup2 (pipe_fd[1], 1) < 0)
2047 fatal_perror ("dup2 %d 1", pipe_fd[1]);
2048
2049 if (close (pipe_fd[0]) < 0)
2050 fatal_perror ("close %d", pipe_fd[0]);
2051
2052 if (close (pipe_fd[1]) < 0)
2053 fatal_perror ("close %d", pipe_fd[1]);
2054
2055 execv (nm_file_name, real_nm_argv);
2056 fatal_perror ("execv %s", nm_file_name);
2057 }
2058
2059 /* Parent context from here on. */
2060 int_handler = (void (*) (int)) signal (SIGINT, SIG_IGN);
2061 #ifdef SIGQUIT
2062 quit_handler = (void (*) (int)) signal (SIGQUIT, SIG_IGN);
2063 #endif
2064
2065 if (close (pipe_fd[1]) < 0)
2066 fatal_perror ("close %d", pipe_fd[1]);
2067
2068 if (debug)
2069 fprintf (stderr, "\nnm output with constructors/destructors.\n");
2070
2071 /* Read each line of nm output. */
2072 while (fgets (buf, sizeof buf, inf) != (char *) 0)
2073 {
2074 int ch, ch2;
2075 char *name, *end;
2076
2077 /* If it contains a constructor or destructor name, add the name
2078 to the appropriate list. */
2079
2080 for (p = buf; (ch = *p) != '\0' && ch != '\n' && ch != '_'; p++)
2081 if (ch == ' ' && p[1] == 'U' && p[2] == ' ')
2082 break;
2083
2084 if (ch != '_')
2085 continue;
2086
2087 name = p;
2088 /* Find the end of the symbol name.
2089 Do not include `|', because Encore nm can tack that on the end. */
2090 for (end = p; (ch2 = *end) != '\0' && !ISSPACE (ch2) && ch2 != '|';
2091 end++)
2092 continue;
2093
2094
2095 *end = '\0';
2096 switch (is_ctor_dtor (name))
2097 {
2098 case 1:
2099 if (which_pass != PASS_LIB)
2100 add_to_list (&constructors, name);
2101 break;
2102
2103 case 2:
2104 if (which_pass != PASS_LIB)
2105 add_to_list (&destructors, name);
2106 break;
2107
2108 case 3:
2109 if (which_pass != PASS_LIB)
2110 fatal ("init function found in object %s", prog_name);
2111 #ifndef LD_INIT_SWITCH
2112 add_to_list (&constructors, name);
2113 #endif
2114 break;
2115
2116 case 4:
2117 if (which_pass != PASS_LIB)
2118 fatal ("fini function found in object %s", prog_name);
2119 #ifndef LD_FINI_SWITCH
2120 add_to_list (&destructors, name);
2121 #endif
2122 break;
2123
2124 case 5:
2125 if (which_pass != PASS_LIB)
2126 add_to_list (&frame_tables, name);
2127 break;
2128
2129 default: /* not a constructor or destructor */
2130 continue;
2131 }
2132
2133 if (debug)
2134 fprintf (stderr, "\t%s\n", buf);
2135 }
2136
2137 if (debug)
2138 fprintf (stderr, "\n");
2139
2140 if (fclose (inf) != 0)
2141 fatal_perror ("fclose");
2142
2143 do_wait (nm_file_name);
2144
2145 signal (SIGINT, int_handler);
2146 #ifdef SIGQUIT
2147 signal (SIGQUIT, quit_handler);
2148 #endif
2149 }
2150
2151 #if SUNOS4_SHARED_LIBRARIES
2152
2153 /* Routines to scan the SunOS 4 _DYNAMIC structure to find shared libraries
2154 that the output file depends upon and their initialization/finalization
2155 routines, if any. */
2156
2157 #include <a.out.h>
2158 #include <fcntl.h>
2159 #include <link.h>
2160 #include <sys/mman.h>
2161 #include <sys/param.h>
2162 #include <unistd.h>
2163 #include <sys/dir.h>
2164
2165 /* pointers to the object file */
2166 unsigned object; /* address of memory mapped file */
2167 unsigned objsize; /* size of memory mapped to file */
2168 char * code; /* pointer to code segment */
2169 char * data; /* pointer to data segment */
2170 struct nlist *symtab; /* pointer to symbol table */
2171 struct link_dynamic *ld;
2172 struct link_dynamic_2 *ld_2;
2173 struct head libraries;
2174
2175 /* Map the file indicated by NAME into memory and store its address. */
2176
2177 static void
mapfile(const char * name)2178 mapfile (const char *name)
2179 {
2180 int fp;
2181 struct stat s;
2182 if ((fp = open (name, O_RDONLY)) == -1)
2183 fatal ("unable to open file '%s'", name);
2184 if (fstat (fp, &s) == -1)
2185 fatal ("unable to stat file '%s'", name);
2186
2187 objsize = s.st_size;
2188 object = (unsigned) mmap (0, objsize, PROT_READ|PROT_WRITE, MAP_PRIVATE,
2189 fp, 0);
2190 if (object == (unsigned)-1)
2191 fatal ("unable to mmap file '%s'", name);
2192
2193 close (fp);
2194 }
2195
2196 /* Helpers for locatelib. */
2197
2198 static const char *libname;
2199
2200 static int
libselect(struct direct * d)2201 libselect (struct direct *d)
2202 {
2203 return (strncmp (libname, d->d_name, strlen (libname)) == 0);
2204 }
2205
2206 /* If one file has an additional numeric extension past LIBNAME, then put
2207 that one first in the sort. If both files have additional numeric
2208 extensions, then put the one with the higher number first in the sort.
2209
2210 We must verify that the extension is numeric, because Sun saves the
2211 original versions of patched libraries with a .FCS extension. Files with
2212 invalid extensions must go last in the sort, so that they will not be used. */
2213
2214 static int
libcompare(struct direct ** d1,struct direct ** d2)2215 libcompare (struct direct **d1, struct direct **d2)
2216 {
2217 int i1, i2 = strlen (libname);
2218 char *e1 = (*d1)->d_name + i2;
2219 char *e2 = (*d2)->d_name + i2;
2220
2221 while (*e1 && *e2 && *e1 == '.' && *e2 == '.'
2222 && e1[1] && ISDIGIT (e1[1]) && e2[1] && ISDIGIT (e2[1]))
2223 {
2224 ++e1;
2225 ++e2;
2226 i1 = strtol (e1, &e1, 10);
2227 i2 = strtol (e2, &e2, 10);
2228 if (i1 != i2)
2229 return i1 - i2;
2230 }
2231
2232 if (*e1)
2233 {
2234 /* It has a valid numeric extension, prefer this one. */
2235 if (*e1 == '.' && e1[1] && ISDIGIT (e1[1]))
2236 return 1;
2237 /* It has an invalid numeric extension, must prefer the other one. */
2238 else
2239 return -1;
2240 }
2241 else if (*e2)
2242 {
2243 /* It has a valid numeric extension, prefer this one. */
2244 if (*e2 == '.' && e2[1] && ISDIGIT (e2[1]))
2245 return -1;
2246 /* It has an invalid numeric extension, must prefer the other one. */
2247 else
2248 return 1;
2249 }
2250 else
2251 return 0;
2252 }
2253
2254 /* Given the name NAME of a dynamic dependency, find its pathname and add
2255 it to the list of libraries. */
2256
2257 static void
locatelib(const char * name)2258 locatelib (const char *name)
2259 {
2260 static const char **l;
2261 static int cnt;
2262 char buf[MAXPATHLEN];
2263 char *p, *q;
2264 const char **pp;
2265
2266 if (l == 0)
2267 {
2268 char *ld_rules;
2269 char *ldr = 0;
2270 /* counting elements in array, need 1 extra for null */
2271 cnt = 1;
2272 ld_rules = (char *) (ld_2->ld_rules + code);
2273 if (ld_rules)
2274 {
2275 cnt++;
2276 for (; *ld_rules != 0; ld_rules++)
2277 if (*ld_rules == ':')
2278 cnt++;
2279 ld_rules = (char *) (ld_2->ld_rules + code);
2280 ldr = xstrdup (ld_rules);
2281 }
2282 p = getenv ("LD_LIBRARY_PATH");
2283 q = 0;
2284 if (p)
2285 {
2286 cnt++;
2287 for (q = p ; *q != 0; q++)
2288 if (*q == ':')
2289 cnt++;
2290 q = xstrdup (p);
2291 }
2292 l = xmalloc ((cnt + 3) * sizeof (char *));
2293 pp = l;
2294 if (ldr)
2295 {
2296 *pp++ = ldr;
2297 for (; *ldr != 0; ldr++)
2298 if (*ldr == ':')
2299 {
2300 *ldr++ = 0;
2301 *pp++ = ldr;
2302 }
2303 }
2304 if (q)
2305 {
2306 *pp++ = q;
2307 for (; *q != 0; q++)
2308 if (*q == ':')
2309 {
2310 *q++ = 0;
2311 *pp++ = q;
2312 }
2313 }
2314 /* built in directories are /lib, /usr/lib, and /usr/local/lib */
2315 *pp++ = "/lib";
2316 *pp++ = "/usr/lib";
2317 *pp++ = "/usr/local/lib";
2318 *pp = 0;
2319 }
2320 libname = name;
2321 for (pp = l; *pp != 0 ; pp++)
2322 {
2323 struct direct **namelist;
2324 int entries;
2325 if ((entries = scandir (*pp, &namelist, libselect, libcompare)) > 0)
2326 {
2327 sprintf (buf, "%s/%s", *pp, namelist[entries - 1]->d_name);
2328 add_to_list (&libraries, buf);
2329 if (debug)
2330 fprintf (stderr, "%s\n", buf);
2331 break;
2332 }
2333 }
2334 if (*pp == 0)
2335 {
2336 if (debug)
2337 notice ("not found\n");
2338 else
2339 fatal ("dynamic dependency %s not found", name);
2340 }
2341 }
2342
2343 /* Scan the _DYNAMIC structure of the output file to find shared libraries
2344 that it depends upon and any constructors or destructors they contain. */
2345
2346 static void
scan_libraries(const char * prog_name)2347 scan_libraries (const char *prog_name)
2348 {
2349 struct exec *header;
2350 char *base;
2351 struct link_object *lo;
2352 char buff[MAXPATHLEN];
2353 struct id *list;
2354
2355 mapfile (prog_name);
2356 header = (struct exec *)object;
2357 if (N_BADMAG (*header))
2358 fatal ("bad magic number in file '%s'", prog_name);
2359 if (header->a_dynamic == 0)
2360 return;
2361
2362 code = (char *) (N_TXTOFF (*header) + (long) header);
2363 data = (char *) (N_DATOFF (*header) + (long) header);
2364 symtab = (struct nlist *) (N_SYMOFF (*header) + (long) header);
2365
2366 if (header->a_magic == ZMAGIC && header->a_entry == 0x20)
2367 {
2368 /* shared object */
2369 ld = (struct link_dynamic *) (symtab->n_value + code);
2370 base = code;
2371 }
2372 else
2373 {
2374 /* executable */
2375 ld = (struct link_dynamic *) data;
2376 base = code-PAGSIZ;
2377 }
2378
2379 if (debug)
2380 notice ("dynamic dependencies.\n");
2381
2382 ld_2 = (struct link_dynamic_2 *) ((long) ld->ld_un.ld_2 + (long)base);
2383 for (lo = (struct link_object *) ld_2->ld_need; lo;
2384 lo = (struct link_object *) lo->lo_next)
2385 {
2386 char *name;
2387 lo = (struct link_object *) ((long) lo + code);
2388 name = (char *) (code + lo->lo_name);
2389 if (lo->lo_library)
2390 {
2391 if (debug)
2392 fprintf (stderr, "\t-l%s.%d => ", name, lo->lo_major);
2393 sprintf (buff, "lib%s.so.%d.%d", name, lo->lo_major, lo->lo_minor);
2394 locatelib (buff);
2395 }
2396 else
2397 {
2398 if (debug)
2399 fprintf (stderr, "\t%s\n", name);
2400 add_to_list (&libraries, name);
2401 }
2402 }
2403
2404 if (debug)
2405 fprintf (stderr, "\n");
2406
2407 /* Now iterate through the library list adding their symbols to
2408 the list. */
2409 for (list = libraries.first; list; list = list->next)
2410 scan_prog_file (list->name, PASS_LIB);
2411 }
2412
2413 #else /* SUNOS4_SHARED_LIBRARIES */
2414 #ifdef LDD_SUFFIX
2415
2416 /* Use the List Dynamic Dependencies program to find shared libraries that
2417 the output file depends upon and their initialization/finalization
2418 routines, if any. */
2419
2420 static void
scan_libraries(const char * prog_name)2421 scan_libraries (const char *prog_name)
2422 {
2423 static struct head libraries; /* list of shared libraries found */
2424 struct id *list;
2425 void (*int_handler) (int);
2426 void (*quit_handler) (int);
2427 char *real_ldd_argv[4];
2428 const char **ldd_argv = (const char **) real_ldd_argv;
2429 int argc = 0;
2430 int pipe_fd[2];
2431 char buf[1024];
2432 FILE *inf;
2433
2434 /* If we do not have an `ldd', complain. */
2435 if (ldd_file_name == 0)
2436 {
2437 error ("cannot find `ldd'");
2438 return;
2439 }
2440
2441 ldd_argv[argc++] = ldd_file_name;
2442 ldd_argv[argc++] = prog_name;
2443 ldd_argv[argc++] = (char *) 0;
2444
2445 if (pipe (pipe_fd) < 0)
2446 fatal_perror ("pipe");
2447
2448 inf = fdopen (pipe_fd[0], "r");
2449 if (inf == (FILE *) 0)
2450 fatal_perror ("fdopen");
2451
2452 /* Trace if needed. */
2453 if (vflag)
2454 {
2455 const char **p_argv;
2456 const char *str;
2457
2458 for (p_argv = &ldd_argv[0]; (str = *p_argv) != (char *) 0; p_argv++)
2459 fprintf (stderr, " %s", str);
2460
2461 fprintf (stderr, "\n");
2462 }
2463
2464 fflush (stdout);
2465 fflush (stderr);
2466
2467 /* Spawn child ldd on pipe. */
2468 pid = vfork ();
2469 if (pid == -1)
2470 fatal_perror (VFORK_STRING);
2471
2472 if (pid == 0) /* child context */
2473 {
2474 /* setup stdout */
2475 if (dup2 (pipe_fd[1], 1) < 0)
2476 fatal_perror ("dup2 %d 1", pipe_fd[1]);
2477
2478 if (close (pipe_fd[0]) < 0)
2479 fatal_perror ("close %d", pipe_fd[0]);
2480
2481 if (close (pipe_fd[1]) < 0)
2482 fatal_perror ("close %d", pipe_fd[1]);
2483
2484 execv (ldd_file_name, real_ldd_argv);
2485 fatal_perror ("execv %s", ldd_file_name);
2486 }
2487
2488 /* Parent context from here on. */
2489 int_handler = (void (*) (int)) signal (SIGINT, SIG_IGN);
2490 #ifdef SIGQUIT
2491 quit_handler = (void (*) (int)) signal (SIGQUIT, SIG_IGN);
2492 #endif
2493
2494 if (close (pipe_fd[1]) < 0)
2495 fatal_perror ("close %d", pipe_fd[1]);
2496
2497 if (debug)
2498 notice ("\nldd output with constructors/destructors.\n");
2499
2500 /* Read each line of ldd output. */
2501 while (fgets (buf, sizeof buf, inf) != (char *) 0)
2502 {
2503 int ch2;
2504 char *name, *end, *p = buf;
2505
2506 /* Extract names of libraries and add to list. */
2507 PARSE_LDD_OUTPUT (p);
2508 if (p == 0)
2509 continue;
2510
2511 name = p;
2512 if (strncmp (name, "not found", sizeof ("not found") - 1) == 0)
2513 fatal ("dynamic dependency %s not found", buf);
2514
2515 /* Find the end of the symbol name. */
2516 for (end = p;
2517 (ch2 = *end) != '\0' && ch2 != '\n' && !ISSPACE (ch2) && ch2 != '|';
2518 end++)
2519 continue;
2520 *end = '\0';
2521
2522 if (access (name, R_OK) == 0)
2523 add_to_list (&libraries, name);
2524 else
2525 fatal ("unable to open dynamic dependency '%s'", buf);
2526
2527 if (debug)
2528 fprintf (stderr, "\t%s\n", buf);
2529 }
2530 if (debug)
2531 fprintf (stderr, "\n");
2532
2533 if (fclose (inf) != 0)
2534 fatal_perror ("fclose");
2535
2536 do_wait (ldd_file_name);
2537
2538 signal (SIGINT, int_handler);
2539 #ifdef SIGQUIT
2540 signal (SIGQUIT, quit_handler);
2541 #endif
2542
2543 /* Now iterate through the library list adding their symbols to
2544 the list. */
2545 for (list = libraries.first; list; list = list->next)
2546 scan_prog_file (list->name, PASS_LIB);
2547 }
2548
2549 #endif /* LDD_SUFFIX */
2550 #endif /* SUNOS4_SHARED_LIBRARIES */
2551
2552 #endif /* OBJECT_FORMAT_NONE */
2553
2554
2555 /*
2556 * COFF specific stuff.
2557 */
2558
2559 #ifdef OBJECT_FORMAT_COFF
2560
2561 #if defined (EXTENDED_COFF)
2562
2563 # define GCC_SYMBOLS(X) (SYMHEADER(X).isymMax + SYMHEADER(X).iextMax)
2564 # define GCC_SYMENT SYMR
2565 # define GCC_OK_SYMBOL(X) ((X).st == stProc || (X).st == stGlobal)
2566 # define GCC_SYMINC(X) (1)
2567 # define GCC_SYMZERO(X) (SYMHEADER(X).isymMax)
2568 # define GCC_CHECK_HDR(X) (PSYMTAB(X) != 0)
2569
2570 #else
2571
2572 # define GCC_SYMBOLS(X) (HEADER(ldptr).f_nsyms)
2573 # define GCC_SYMENT SYMENT
2574 # if defined (C_WEAKEXT)
2575 # define GCC_OK_SYMBOL(X) \
2576 (((X).n_sclass == C_EXT || (X).n_sclass == C_WEAKEXT) && \
2577 ((X).n_scnum > N_UNDEF) && \
2578 (aix64_flag \
2579 || (((X).n_type & N_TMASK) == (DT_NON << N_BTSHFT) \
2580 || ((X).n_type & N_TMASK) == (DT_FCN << N_BTSHFT))))
2581 # define GCC_UNDEF_SYMBOL(X) \
2582 (((X).n_sclass == C_EXT || (X).n_sclass == C_WEAKEXT) && \
2583 ((X).n_scnum == N_UNDEF))
2584 # else
2585 # define GCC_OK_SYMBOL(X) \
2586 (((X).n_sclass == C_EXT) && \
2587 ((X).n_scnum > N_UNDEF) && \
2588 (aix64_flag \
2589 || (((X).n_type & N_TMASK) == (DT_NON << N_BTSHFT) \
2590 || ((X).n_type & N_TMASK) == (DT_FCN << N_BTSHFT))))
2591 # define GCC_UNDEF_SYMBOL(X) \
2592 (((X).n_sclass == C_EXT) && ((X).n_scnum == N_UNDEF))
2593 # endif
2594 # define GCC_SYMINC(X) ((X).n_numaux+1)
2595 # define GCC_SYMZERO(X) 0
2596
2597 /* 0757 = U803XTOCMAGIC (AIX 4.3) and 0767 = U64_TOCMAGIC (AIX V5) */
2598 #ifdef _AIX51
2599 # define GCC_CHECK_HDR(X) \
2600 ((HEADER (X).f_magic == U802TOCMAGIC && ! aix64_flag) \
2601 || (HEADER (X).f_magic == 0767 && aix64_flag))
2602 #else
2603 # define GCC_CHECK_HDR(X) \
2604 ((HEADER (X).f_magic == U802TOCMAGIC && ! aix64_flag) \
2605 || (HEADER (X).f_magic == 0757 && aix64_flag))
2606 #endif
2607
2608 #endif
2609
2610 #ifdef COLLECT_EXPORT_LIST
2611 /* Array of standard AIX libraries which should not
2612 be scanned for ctors/dtors. */
2613 static const char *const aix_std_libs[] = {
2614 "/unix",
2615 "/lib/libc.a",
2616 "/lib/libm.a",
2617 "/lib/libc_r.a",
2618 "/lib/libm_r.a",
2619 "/usr/lib/libc.a",
2620 "/usr/lib/libm.a",
2621 "/usr/lib/libc_r.a",
2622 "/usr/lib/libm_r.a",
2623 "/usr/lib/threads/libc.a",
2624 "/usr/ccs/lib/libc.a",
2625 "/usr/ccs/lib/libm.a",
2626 "/usr/ccs/lib/libc_r.a",
2627 "/usr/ccs/lib/libm_r.a",
2628 NULL
2629 };
2630
2631 /* This function checks the filename and returns 1
2632 if this name matches the location of a standard AIX library. */
2633 static int ignore_library (const char *);
2634 static int
ignore_library(const char * name)2635 ignore_library (const char *name)
2636 {
2637 const char *const *p = &aix_std_libs[0];
2638 while (*p++ != NULL)
2639 if (! strcmp (name, *p)) return 1;
2640 return 0;
2641 }
2642 #endif /* COLLECT_EXPORT_LIST */
2643
2644 #if defined (HAVE_DECL_LDGETNAME) && !HAVE_DECL_LDGETNAME
2645 extern char *ldgetname (LDFILE *, GCC_SYMENT *);
2646 #endif
2647
2648 /* COFF version to scan the name list of the loaded program for
2649 the symbols g++ uses for static constructors and destructors.
2650
2651 The constructor table begins at __CTOR_LIST__ and contains a count
2652 of the number of pointers (or -1 if the constructors are built in a
2653 separate section by the linker), followed by the pointers to the
2654 constructor functions, terminated with a null pointer. The
2655 destructor table has the same format, and begins at __DTOR_LIST__. */
2656
2657 static void
scan_prog_file(const char * prog_name,enum pass which_pass)2658 scan_prog_file (const char *prog_name, enum pass which_pass)
2659 {
2660 LDFILE *ldptr = NULL;
2661 int sym_index, sym_count;
2662 int is_shared = 0;
2663
2664 if (which_pass != PASS_FIRST && which_pass != PASS_OBJ)
2665 return;
2666
2667 #ifdef COLLECT_EXPORT_LIST
2668 /* We do not need scanning for some standard C libraries. */
2669 if (which_pass == PASS_FIRST && ignore_library (prog_name))
2670 return;
2671
2672 /* On AIX we have a loop, because there is not much difference
2673 between an object and an archive. This trick allows us to
2674 eliminate scan_libraries() function. */
2675 do
2676 {
2677 #endif
2678 /* Some platforms (e.g. OSF4) declare ldopen as taking a
2679 non-const char * filename parameter, even though it will not
2680 modify that string. So we must cast away const-ness here,
2681 which will cause -Wcast-qual to burp. */
2682 if ((ldptr = ldopen ((char *)prog_name, ldptr)) != NULL)
2683 {
2684 if (! MY_ISCOFF (HEADER (ldptr).f_magic))
2685 fatal ("%s: not a COFF file", prog_name);
2686
2687 if (GCC_CHECK_HDR (ldptr))
2688 {
2689 sym_count = GCC_SYMBOLS (ldptr);
2690 sym_index = GCC_SYMZERO (ldptr);
2691
2692 #ifdef COLLECT_EXPORT_LIST
2693 /* Is current archive member a shared object? */
2694 is_shared = HEADER (ldptr).f_flags & F_SHROBJ;
2695 #endif
2696
2697 while (sym_index < sym_count)
2698 {
2699 GCC_SYMENT symbol;
2700
2701 if (ldtbread (ldptr, sym_index, &symbol) <= 0)
2702 break;
2703 sym_index += GCC_SYMINC (symbol);
2704
2705 if (GCC_OK_SYMBOL (symbol))
2706 {
2707 char *name;
2708
2709 if ((name = ldgetname (ldptr, &symbol)) == NULL)
2710 continue; /* Should never happen. */
2711
2712 #ifdef XCOFF_DEBUGGING_INFO
2713 /* All AIX function names have a duplicate entry
2714 beginning with a dot. */
2715 if (*name == '.')
2716 ++name;
2717 #endif
2718
2719 switch (is_ctor_dtor (name))
2720 {
2721 case 1:
2722 if (! is_shared)
2723 add_to_list (&constructors, name);
2724 #if defined (COLLECT_EXPORT_LIST) && !defined (LD_INIT_SWITCH)
2725 if (which_pass == PASS_OBJ)
2726 add_to_list (&exports, name);
2727 #endif
2728 break;
2729
2730 case 2:
2731 if (! is_shared)
2732 add_to_list (&destructors, name);
2733 #if defined (COLLECT_EXPORT_LIST) && !defined (LD_INIT_SWITCH)
2734 if (which_pass == PASS_OBJ)
2735 add_to_list (&exports, name);
2736 #endif
2737 break;
2738
2739 #ifdef COLLECT_EXPORT_LIST
2740 case 3:
2741 #ifndef LD_INIT_SWITCH
2742 if (is_shared)
2743 add_to_list (&constructors, name);
2744 #endif
2745 break;
2746
2747 case 4:
2748 #ifndef LD_INIT_SWITCH
2749 if (is_shared)
2750 add_to_list (&destructors, name);
2751 #endif
2752 break;
2753 #endif
2754
2755 case 5:
2756 if (! is_shared)
2757 add_to_list (&frame_tables, name);
2758 #if defined (COLLECT_EXPORT_LIST) && !defined (LD_INIT_SWITCH)
2759 if (which_pass == PASS_OBJ)
2760 add_to_list (&exports, name);
2761 #endif
2762 break;
2763
2764 default: /* not a constructor or destructor */
2765 #ifdef COLLECT_EXPORT_LIST
2766 /* Explicitly export all global symbols when
2767 building a shared object on AIX, but do not
2768 re-export symbols from another shared object
2769 and do not export symbols if the user
2770 provides an explicit export list. */
2771 if (shared_obj && !is_shared
2772 && which_pass == PASS_OBJ && !export_flag)
2773 add_to_list (&exports, name);
2774 #endif
2775 continue;
2776 }
2777
2778 if (debug)
2779 #if !defined(EXTENDED_COFF)
2780 fprintf (stderr, "\tsec=%d class=%d type=%s%o %s\n",
2781 symbol.n_scnum, symbol.n_sclass,
2782 (symbol.n_type ? "0" : ""), symbol.n_type,
2783 name);
2784 #else
2785 fprintf (stderr,
2786 "\tiss = %5d, value = %5ld, index = %5d, name = %s\n",
2787 symbol.iss, (long) symbol.value, symbol.index, name);
2788 #endif
2789 }
2790 }
2791 }
2792 #ifdef COLLECT_EXPORT_LIST
2793 else
2794 {
2795 /* If archive contains both 32-bit and 64-bit objects,
2796 we want to skip objects in other mode so mismatch normal. */
2797 if (debug)
2798 fprintf (stderr, "%s : magic=%o aix64=%d mismatch\n",
2799 prog_name, HEADER (ldptr).f_magic, aix64_flag);
2800 }
2801 #endif
2802 }
2803 else
2804 {
2805 fatal ("%s: cannot open as COFF file", prog_name);
2806 }
2807 #ifdef COLLECT_EXPORT_LIST
2808 /* On AIX loop continues while there are more members in archive. */
2809 }
2810 while (ldclose (ldptr) == FAILURE);
2811 #else
2812 /* Otherwise we simply close ldptr. */
2813 (void) ldclose(ldptr);
2814 #endif
2815 }
2816 #endif /* OBJECT_FORMAT_COFF */
2817
2818 #ifdef COLLECT_EXPORT_LIST
2819 /* Given a library name without "lib" prefix, this function
2820 returns a full library name including a path. */
2821 static char *
resolve_lib_name(const char * name)2822 resolve_lib_name (const char *name)
2823 {
2824 char *lib_buf;
2825 int i, j, l = 0;
2826
2827 for (i = 0; libpaths[i]; i++)
2828 if (libpaths[i]->max_len > l)
2829 l = libpaths[i]->max_len;
2830
2831 lib_buf = xmalloc (l + strlen(name) + 10);
2832
2833 for (i = 0; libpaths[i]; i++)
2834 {
2835 struct prefix_list *list = libpaths[i]->plist;
2836 for (; list; list = list->next)
2837 {
2838 /* The following lines are needed because path_prefix list
2839 may contain directories both with trailing '/' and
2840 without it. */
2841 const char *p = "";
2842 if (list->prefix[strlen(list->prefix)-1] != '/')
2843 p = "/";
2844 for (j = 0; libexts[j]; j++)
2845 {
2846 sprintf (lib_buf, "%s%slib%s.%s",
2847 list->prefix, p, name, libexts[j]);
2848 if (debug) fprintf (stderr, "searching for: %s\n", lib_buf);
2849 if (file_exists (lib_buf))
2850 {
2851 if (debug) fprintf (stderr, "found: %s\n", lib_buf);
2852 return (lib_buf);
2853 }
2854 }
2855 }
2856 }
2857 if (debug)
2858 fprintf (stderr, "not found\n");
2859 else
2860 fatal ("library lib%s not found", name);
2861 return (NULL);
2862 }
2863 #endif /* COLLECT_EXPORT_LIST */
2864