cb5e2fa1d47d6c4208d3138ef963d38e0a31e14c
[gcc.git] / gcc / collect2.c
1 /* Collect static initialization info into data structures that can be
2 traversed by C++ initialization and finalization routines.
3 Copyright (C) 1992, 93-99, 2000 Free Software Foundation, Inc.
4 Contributed by Chris Smith (csmith@convex.com).
5 Heavily modified by Michael Meissner (meissner@cygnus.com),
6 Per Bothner (bothner@cygnus.com), and John Gilmore (gnu@cygnus.com).
7
8 This file is part of GNU CC.
9
10 GNU CC is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 2, or (at your option)
13 any later version.
14
15 GNU CC is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
19
20 You should have received a copy of the GNU General Public License
21 along with GNU CC; see the file COPYING. If not, write to
22 the Free Software Foundation, 59 Temple Place - Suite 330,
23 Boston, MA 02111-1307, USA. */
24
25
26 /* Build tables of static constructors and destructors and run ld. */
27
28 #include "config.h"
29 #include "system.h"
30 #include <signal.h>
31
32 #ifdef vfork /* Autoconf may define this to fork for us. */
33 # define VFORK_STRING "fork"
34 #else
35 # define VFORK_STRING "vfork"
36 #endif
37 #ifdef HAVE_VFORK_H
38 #include <vfork.h>
39 #endif
40 #ifdef VMS
41 #define vfork() (decc$$alloc_vfork_blocks() >= 0 ? \
42 lib$get_current_invo_context(decc$$get_vfork_jmpbuf()) : -1)
43 #endif /* VMS */
44
45 #ifndef LIBRARY_PATH_ENV
46 #define LIBRARY_PATH_ENV "LIBRARY_PATH"
47 #endif
48
49 #define COLLECT
50
51 #include "collect2.h"
52 #include "demangle.h"
53 #include "obstack.h"
54 #include "intl.h"
55
56 /* Obstack allocation and deallocation routines. */
57 #define obstack_chunk_alloc xmalloc
58 #define obstack_chunk_free free
59 \f
60 /* On certain systems, we have code that works by scanning the object file
61 directly. But this code uses system-specific header files and library
62 functions, so turn it off in a cross-compiler. Likewise, the names of
63 the utilities are not correct for a cross-compiler; we have to hope that
64 cross-versions are in the proper directories. */
65
66 #ifdef CROSS_COMPILE
67 #undef SUNOS4_SHARED_LIBRARIES
68 #undef OBJECT_FORMAT_COFF
69 #undef OBJECT_FORMAT_ROSE
70 #undef MD_EXEC_PREFIX
71 #undef REAL_LD_FILE_NAME
72 #undef REAL_NM_FILE_NAME
73 #undef REAL_STRIP_FILE_NAME
74 #endif
75
76 /* If we cannot use a special method, use the ordinary one:
77 run nm to find what symbols are present.
78 In a cross-compiler, this means you need a cross nm,
79 but that is not quite as unpleasant as special headers. */
80
81 #if !defined (OBJECT_FORMAT_COFF) && !defined (OBJECT_FORMAT_ROSE)
82 #define OBJECT_FORMAT_NONE
83 #endif
84
85 #ifdef OBJECT_FORMAT_COFF
86
87 #include <a.out.h>
88 #include <ar.h>
89
90 #ifdef UMAX
91 #include <sgs.h>
92 #endif
93
94 /* Many versions of ldfcn.h define these. */
95 #ifdef FREAD
96 #undef FREAD
97 #undef FWRITE
98 #endif
99
100 #include <ldfcn.h>
101
102 /* Some systems have an ISCOFF macro, but others do not. In some cases
103 the macro may be wrong. MY_ISCOFF is defined in tm.h files for machines
104 that either do not have an ISCOFF macro in /usr/include or for those
105 where it is wrong. */
106
107 #ifndef MY_ISCOFF
108 #define MY_ISCOFF(X) ISCOFF (X)
109 #endif
110
111 #endif /* OBJECT_FORMAT_COFF */
112
113 #ifdef OBJECT_FORMAT_ROSE
114
115 #ifdef _OSF_SOURCE
116 #define USE_MMAP
117 #endif
118
119 #ifdef USE_MMAP
120 #include <sys/mman.h>
121 #endif
122
123 #include <unistd.h>
124 #include <mach_o_format.h>
125 #include <mach_o_header.h>
126 #include <mach_o_vals.h>
127 #include <mach_o_types.h>
128
129 #endif /* OBJECT_FORMAT_ROSE */
130
131 #ifdef OBJECT_FORMAT_NONE
132
133 /* Default flags to pass to nm. */
134 #ifndef NM_FLAGS
135 #define NM_FLAGS "-n"
136 #endif
137
138 #endif /* OBJECT_FORMAT_NONE */
139
140 /* Some systems use __main in a way incompatible with its use in gcc, in these
141 cases use the macros NAME__MAIN to give a quoted symbol and SYMBOL__MAIN to
142 give the same symbol without quotes for an alternative entry point. You
143 must define both, or neither. */
144 #ifndef NAME__MAIN
145 #define NAME__MAIN "__main"
146 #define SYMBOL__MAIN __main
147 #endif
148
149 /* This must match tree.h. */
150 #define DEFAULT_INIT_PRIORITY 65535
151
152 #if defined (LDD_SUFFIX) || SUNOS4_SHARED_LIBRARIES
153 #define SCAN_LIBRARIES
154 #endif
155
156 #ifdef USE_COLLECT2
157 int do_collecting = 1;
158 #else
159 int do_collecting = 0;
160 #endif
161 \f
162 /* Linked lists of constructor and destructor names. */
163
164 struct id
165 {
166 struct id *next;
167 int sequence;
168 char name[1];
169 };
170
171 struct head
172 {
173 struct id *first;
174 struct id *last;
175 int number;
176 };
177
178 /* Enumeration giving which pass this is for scanning the program file. */
179
180 enum pass {
181 PASS_FIRST, /* without constructors */
182 PASS_OBJ, /* individual objects */
183 PASS_LIB, /* looking for shared libraries */
184 PASS_SECOND /* with constructors linked in */
185 };
186
187 extern char *version_string;
188
189 int vflag; /* true if -v */
190 static int rflag; /* true if -r */
191 static int strip_flag; /* true if -s */
192 #ifdef COLLECT_EXPORT_LIST
193 static int export_flag; /* true if -bE */
194 static int aix64_flag; /* true if -b64 */
195 #endif
196
197 int debug; /* true if -debug */
198
199 static int shared_obj; /* true if -shared */
200
201 static const char *c_file; /* <xxx>.c for constructor/destructor list. */
202 static const char *o_file; /* <xxx>.o for constructor/destructor list. */
203 #ifdef COLLECT_EXPORT_LIST
204 static const char *export_file; /* <xxx>.x for AIX export list. */
205 static const char *import_file; /* <xxx>.p for AIX import list. */
206 #endif
207 const char *ldout; /* File for ld errors. */
208 static const char *output_file; /* Output file for ld. */
209 static const char *nm_file_name; /* pathname of nm */
210 #ifdef LDD_SUFFIX
211 static const char *ldd_file_name; /* pathname of ldd (or equivalent) */
212 #endif
213 static const char *strip_file_name; /* pathname of strip */
214 const char *c_file_name; /* pathname of gcc */
215 static char *initname, *fininame; /* names of init and fini funcs */
216
217 static struct head constructors; /* list of constructors found */
218 static struct head destructors; /* list of destructors found */
219 #ifdef COLLECT_EXPORT_LIST
220 static struct head exports; /* list of exported symbols */
221 static struct head imports; /* list of imported symbols */
222 static struct head undefined; /* list of undefined symbols */
223 #endif
224 static struct head frame_tables; /* list of frame unwind info tables */
225
226 struct obstack temporary_obstack;
227 struct obstack permanent_obstack;
228 char * temporary_firstobj;
229
230 /* Holds the return value of pexecute. */
231 int pexecute_pid;
232
233 /* Defined in the automatically-generated underscore.c. */
234 extern int prepends_underscore;
235
236 #ifndef GET_ENV_PATH_LIST
237 #define GET_ENV_PATH_LIST(VAR,NAME) do { (VAR) = getenv (NAME); } while (0)
238 #endif
239
240 /* Structure to hold all the directories in which to search for files to
241 execute. */
242
243 struct prefix_list
244 {
245 const char *prefix; /* String to prepend to the path. */
246 struct prefix_list *next; /* Next in linked list. */
247 };
248
249 struct path_prefix
250 {
251 struct prefix_list *plist; /* List of prefixes to try */
252 int max_len; /* Max length of a prefix in PLIST */
253 const char *name; /* Name of this list (used in config stuff) */
254 };
255
256 #ifdef COLLECT_EXPORT_LIST
257 /* Lists to keep libraries to be scanned for global constructors/destructors. */
258 static struct head libs; /* list of libraries */
259 static struct path_prefix cmdline_lib_dirs; /* directories specified with -L */
260 static struct path_prefix libpath_lib_dirs; /* directories in LIBPATH */
261 static struct path_prefix *libpaths[3] = {&cmdline_lib_dirs,
262 &libpath_lib_dirs, NULL};
263 static const char *libexts[3] = {"a", "so", NULL}; /* possible library extentions */
264 #endif
265
266 static void handler PROTO((int));
267 static int is_ctor_dtor PROTO((const char *));
268 static char *find_a_file PROTO((struct path_prefix *, const char *));
269 static void add_prefix PROTO((struct path_prefix *, const char *));
270 static void prefix_from_env PROTO((const char *, struct path_prefix *));
271 static void prefix_from_string PROTO((const char *, struct path_prefix *));
272 static void do_wait PROTO((const char *));
273 static void fork_execute PROTO((const char *, char **));
274 static void maybe_unlink PROTO((const char *));
275 static void add_to_list PROTO((struct head *, const char *));
276 static int extract_init_priority PROTO((const char *));
277 static void sort_ids PROTO((struct head *));
278 static void write_list PROTO((FILE *, const char *, struct id *));
279 #ifdef COLLECT_EXPORT_LIST
280 static void dump_list PROTO((FILE *, const char *, struct id *));
281 #endif
282 #if 0
283 static void dump_prefix_list PROTO((FILE *, const char *, struct prefix_list *));
284 #endif
285 static void write_list_with_asm PROTO((FILE *, const char *, struct id *));
286 static void write_c_file PROTO((FILE *, const char *));
287 static void write_c_file_stat PROTO((FILE *, const char *));
288 #ifndef LD_INIT_SWITCH
289 static void write_c_file_glob PROTO((FILE *, const char *));
290 #endif
291 static void scan_prog_file PROTO((const char *, enum pass));
292 #ifdef SCAN_LIBRARIES
293 static void scan_libraries PROTO((const char *));
294 #endif
295 #ifdef COLLECT_EXPORT_LIST
296 static int is_in_list PROTO((const char *, struct id *));
297 static void write_aix_file PROTO((FILE *, struct id *));
298 static char *resolve_lib_name PROTO((const char *));
299 static int use_import_list PROTO((const char *));
300 static int ignore_library PROTO((const char *));
301 #endif
302 static char *extract_string PROTO((const char **));
303 \f
304 #ifdef NO_DUP2
305 int
306 dup2 (oldfd, newfd)
307 int oldfd;
308 int newfd;
309 {
310 int fdtmp[256];
311 int fdx = 0;
312 int fd;
313
314 if (oldfd == newfd)
315 return oldfd;
316 close (newfd);
317 while ((fd = dup (oldfd)) != newfd && fd >= 0) /* good enough for low fd's */
318 fdtmp[fdx++] = fd;
319 while (fdx > 0)
320 close (fdtmp[--fdx]);
321
322 return fd;
323 }
324 #endif
325 \f
326 /* Delete tempfiles and exit function. */
327
328 void
329 collect_exit (status)
330 int status;
331 {
332 if (c_file != 0 && c_file[0])
333 maybe_unlink (c_file);
334
335 if (o_file != 0 && o_file[0])
336 maybe_unlink (o_file);
337
338 #ifdef COLLECT_EXPORT_LIST
339 if (export_file != 0 && export_file[0])
340 maybe_unlink (export_file);
341
342 if (import_file != 0 && import_file[0])
343 maybe_unlink (import_file);
344 #endif
345
346 if (ldout != 0 && ldout[0])
347 {
348 dump_file (ldout);
349 maybe_unlink (ldout);
350 }
351
352 if (status != 0 && output_file != 0 && output_file[0])
353 maybe_unlink (output_file);
354
355 exit (status);
356 }
357
358 \f
359 /* Notify user of a non-error. */
360 void
361 notice VPROTO((const char *msgid, ...))
362 {
363 #ifndef ANSI_PROTOTYPES
364 const char *msgid;
365 #endif
366 va_list ap;
367
368 VA_START (ap, msgid);
369
370 #ifndef ANSI_PROTOTYPES
371 msgid = va_arg (ap, const char *);
372 #endif
373
374 vfprintf (stderr, _(msgid), ap);
375 va_end (ap);
376 }
377
378 /* Die when sys call fails. */
379
380 void
381 fatal_perror VPROTO((const char * msgid, ...))
382 {
383 #ifndef ANSI_PROTOTYPES
384 const char *msgid;
385 #endif
386 int e = errno;
387 va_list ap;
388
389 VA_START (ap, msgid);
390
391 #ifndef ANSI_PROTOTYPES
392 msgid = va_arg (ap, const char *);
393 #endif
394
395 fprintf (stderr, "collect2: ");
396 vfprintf (stderr, _(msgid), ap);
397 fprintf (stderr, ": %s\n", xstrerror (e));
398 va_end (ap);
399
400 collect_exit (FATAL_EXIT_CODE);
401 }
402
403 /* Just die. */
404
405 void
406 fatal VPROTO((const char * msgid, ...))
407 {
408 #ifndef ANSI_PROTOTYPES
409 const char *msgid;
410 #endif
411 va_list ap;
412
413 VA_START (ap, msgid);
414
415 #ifndef ANSI_PROTOTYPES
416 msgid = va_arg (ap, const char *);
417 #endif
418
419 fprintf (stderr, "collect2: ");
420 vfprintf (stderr, _(msgid), ap);
421 fprintf (stderr, "\n");
422 va_end (ap);
423
424 collect_exit (FATAL_EXIT_CODE);
425 }
426
427 /* Write error message. */
428
429 void
430 error VPROTO((const char * msgid, ...))
431 {
432 #ifndef ANSI_PROTOTYPES
433 const char * msgid;
434 #endif
435 va_list ap;
436
437 VA_START (ap, msgid);
438
439 #ifndef ANSI_PROTOTYPES
440 msgid = va_arg (ap, const char *);
441 #endif
442
443 fprintf (stderr, "collect2: ");
444 vfprintf (stderr, _(msgid), ap);
445 fprintf (stderr, "\n");
446 va_end(ap);
447 }
448
449 /* In case obstack is linked in, and abort is defined to fancy_abort,
450 provide a default entry. */
451
452 void
453 fancy_abort ()
454 {
455 fatal ("internal error");
456 }
457 \f
458 static void
459 handler (signo)
460 int signo;
461 {
462 if (c_file != 0 && c_file[0])
463 maybe_unlink (c_file);
464
465 if (o_file != 0 && o_file[0])
466 maybe_unlink (o_file);
467
468 if (ldout != 0 && ldout[0])
469 maybe_unlink (ldout);
470
471 #ifdef COLLECT_EXPORT_LIST
472 if (export_file != 0 && export_file[0])
473 maybe_unlink (export_file);
474
475 if (import_file != 0 && import_file[0])
476 maybe_unlink (import_file);
477 #endif
478
479 signal (signo, SIG_DFL);
480 kill (getpid (), signo);
481 }
482
483 \f
484 int
485 file_exists (name)
486 const char *name;
487 {
488 return access (name, R_OK) == 0;
489 }
490
491 /* Parse a reasonable subset of shell quoting syntax. */
492
493 static char *
494 extract_string (pp)
495 const char **pp;
496 {
497 const char *p = *pp;
498 int backquote = 0;
499 int inside = 0;
500
501 for (;;)
502 {
503 char c = *p;
504 if (c == '\0')
505 break;
506 ++p;
507 if (backquote)
508 obstack_1grow (&temporary_obstack, c);
509 else if (! inside && c == ' ')
510 break;
511 else if (! inside && c == '\\')
512 backquote = 1;
513 else if (c == '\'')
514 inside = !inside;
515 else
516 obstack_1grow (&temporary_obstack, c);
517 }
518
519 obstack_1grow (&temporary_obstack, '\0');
520 *pp = p;
521 return obstack_finish (&temporary_obstack);
522 }
523 \f
524 void
525 dump_file (name)
526 const char *name;
527 {
528 FILE *stream = fopen (name, "r");
529 int no_demangle = !! getenv ("COLLECT_NO_DEMANGLE");
530
531 if (stream == 0)
532 return;
533 while (1)
534 {
535 int c;
536 while (c = getc (stream),
537 c != EOF && (ISALNUM (c) || c == '_' || c == '$' || c == '.'))
538 obstack_1grow (&temporary_obstack, c);
539 if (obstack_object_size (&temporary_obstack) > 0)
540 {
541 const char *word, *p;
542 char *result;
543 obstack_1grow (&temporary_obstack, '\0');
544 word = obstack_finish (&temporary_obstack);
545
546 if (*word == '.')
547 ++word, putc ('.', stderr);
548 p = word;
549 if (*p == '_' && prepends_underscore)
550 ++p;
551
552 if (no_demangle)
553 result = 0;
554 else
555 result = cplus_demangle (p, DMGL_PARAMS | DMGL_ANSI);
556
557 if (result)
558 {
559 int diff;
560 fputs (result, stderr);
561
562 diff = strlen (word) - strlen (result);
563 while (diff > 0)
564 --diff, putc (' ', stderr);
565 while (diff < 0 && c == ' ')
566 ++diff, c = getc (stream);
567
568 free (result);
569 }
570 else
571 fputs (word, stderr);
572
573 fflush (stderr);
574 obstack_free (&temporary_obstack, temporary_firstobj);
575 }
576 if (c == EOF)
577 break;
578 putc (c, stderr);
579 }
580 fclose (stream);
581 }
582 \f
583 /* Decide whether the given symbol is:
584 a constructor (1), a destructor (2), or neither (0). */
585
586 static int
587 is_ctor_dtor (s)
588 const char *s;
589 {
590 struct names { const char *name; int len; int ret; int two_underscores; };
591
592 register struct names *p;
593 register int ch;
594 register const char *orig_s = s;
595
596 static struct names special[] = {
597 #ifdef NO_DOLLAR_IN_LABEL
598 #ifdef NO_DOT_IN_LABEL
599 { "GLOBAL__I_", sizeof ("GLOBAL__I_")-1, 1, 0 },
600 { "GLOBAL__D_", sizeof ("GLOBAL__D_")-1, 2, 0 },
601 { "GLOBAL__F_", sizeof ("GLOBAL__F_")-1, 5, 0 },
602 #else
603 { "GLOBAL_.I.", sizeof ("GLOBAL_.I.")-1, 1, 0 },
604 { "GLOBAL_.D.", sizeof ("GLOBAL_.D.")-1, 2, 0 },
605 { "GLOBAL_.F.", sizeof ("GLOBAL_.F.")-1, 5, 0 },
606 #endif
607 #else
608 { "GLOBAL_$I$", sizeof ("GLOBAL_$I$")-1, 1, 0 },
609 { "GLOBAL_$D$", sizeof ("GLOBAL_$D$")-1, 2, 0 },
610 { "GLOBAL_$F$", sizeof ("GLOBAL_$F$")-1, 5, 0 },
611 #endif
612 { "GLOBAL__FI_", sizeof ("GLOBAL__FI_")-1, 3, 0 },
613 { "GLOBAL__FD_", sizeof ("GLOBAL__FD_")-1, 4, 0 },
614 #ifdef CFRONT_LOSSAGE /* Do not collect cfront initialization functions.
615 cfront has its own linker procedure to collect them;
616 if collect2 gets them too, they get collected twice
617 when the cfront procedure is run and the compiler used
618 for linking happens to be GCC. */
619 { "sti__", sizeof ("sti__")-1, 1, 1 },
620 { "std__", sizeof ("std__")-1, 2, 1 },
621 #endif /* CFRONT_LOSSAGE */
622 { NULL, 0, 0, 0 }
623 };
624
625 while ((ch = *s) == '_')
626 ++s;
627
628 if (s == orig_s)
629 return 0;
630
631 for (p = &special[0]; p->len > 0; p++)
632 {
633 if (ch == p->name[0]
634 && (!p->two_underscores || ((s - orig_s) >= 2))
635 && strncmp(s, p->name, p->len) == 0)
636 {
637 return p->ret;
638 }
639 }
640 return 0;
641 }
642 \f
643 /* We maintain two prefix lists: one from COMPILER_PATH environment variable
644 and one from the PATH variable. */
645
646 static struct path_prefix cpath, path;
647
648 #ifdef CROSS_COMPILE
649 /* This is the name of the target machine. We use it to form the name
650 of the files to execute. */
651
652 static const char *const target_machine = TARGET_MACHINE;
653 #endif
654
655 /* Search for NAME using prefix list PPREFIX. We only look for executable
656 files.
657
658 Return 0 if not found, otherwise return its name, allocated with malloc. */
659
660 static char *
661 find_a_file (pprefix, name)
662 struct path_prefix *pprefix;
663 const char *name;
664 {
665 char *temp;
666 struct prefix_list *pl;
667 int len = pprefix->max_len + strlen (name) + 1;
668
669 if (debug)
670 fprintf (stderr, "Looking for '%s'\n", name);
671
672 #ifdef EXECUTABLE_SUFFIX
673 len += strlen (EXECUTABLE_SUFFIX);
674 #endif
675
676 temp = xmalloc (len);
677
678 /* Determine the filename to execute (special case for absolute paths). */
679
680 if (*name == '/'
681 #ifdef HAVE_DOS_BASED_FILE_SYSTEM
682 || (*name && name[1] == ':')
683 #endif
684 )
685 {
686 if (access (name, X_OK) == 0)
687 {
688 strcpy (temp, name);
689
690 if (debug)
691 fprintf (stderr, " - found: absolute path\n");
692
693 return temp;
694 }
695
696 #ifdef EXECUTABLE_SUFFIX
697 /* Some systems have a suffix for executable files.
698 So try appending that. */
699 strcpy (temp, name);
700 strcat (temp, EXECUTABLE_SUFFIX);
701
702 if (access (temp, X_OK) == 0)
703 return temp;
704 #endif
705
706 if (debug)
707 fprintf (stderr, " - failed to locate using absolute path\n");
708 }
709 else
710 for (pl = pprefix->plist; pl; pl = pl->next)
711 {
712 struct stat st;
713
714 strcpy (temp, pl->prefix);
715 strcat (temp, name);
716
717 if (stat (temp, &st) >= 0
718 && ! S_ISDIR (st.st_mode)
719 && access (temp, X_OK) == 0)
720 return temp;
721
722 #ifdef EXECUTABLE_SUFFIX
723 /* Some systems have a suffix for executable files.
724 So try appending that. */
725 strcat (temp, EXECUTABLE_SUFFIX);
726
727 if (stat (temp, &st) >= 0
728 && ! S_ISDIR (st.st_mode)
729 && access (temp, X_OK) == 0)
730 return temp;
731 #endif
732 }
733
734 if (debug && pprefix->plist == NULL)
735 fprintf (stderr, " - failed: no entries in prefix list\n");
736
737 free (temp);
738 return 0;
739 }
740
741 /* Add an entry for PREFIX to prefix list PPREFIX. */
742
743 static void
744 add_prefix (pprefix, prefix)
745 struct path_prefix *pprefix;
746 const char *prefix;
747 {
748 struct prefix_list *pl, **prev;
749 int len;
750
751 if (pprefix->plist)
752 {
753 for (pl = pprefix->plist; pl->next; pl = pl->next)
754 ;
755 prev = &pl->next;
756 }
757 else
758 prev = &pprefix->plist;
759
760 /* Keep track of the longest prefix */
761
762 len = strlen (prefix);
763 if (len > pprefix->max_len)
764 pprefix->max_len = len;
765
766 pl = (struct prefix_list *) xmalloc (sizeof (struct prefix_list));
767 pl->prefix = xstrdup (prefix);
768
769 if (*prev)
770 pl->next = *prev;
771 else
772 pl->next = (struct prefix_list *) 0;
773 *prev = pl;
774 }
775 \f
776 /* Take the value of the environment variable ENV, break it into a path, and
777 add of the entries to PPREFIX. */
778
779 static void
780 prefix_from_env (env, pprefix)
781 const char *env;
782 struct path_prefix *pprefix;
783 {
784 const char *p;
785 GET_ENV_PATH_LIST (p, env);
786
787 if (p)
788 prefix_from_string (p, pprefix);
789 }
790
791 static void
792 prefix_from_string (p, pprefix)
793 const char *p;
794 struct path_prefix *pprefix;
795 {
796 const char *startp, *endp;
797 char *nstore = (char *) xmalloc (strlen (p) + 3);
798
799 if (debug)
800 fprintf (stderr, "Convert string '%s' into prefixes, separator = '%c'\n", p, PATH_SEPARATOR);
801
802 startp = endp = p;
803 while (1)
804 {
805 if (*endp == PATH_SEPARATOR || *endp == 0)
806 {
807 strncpy (nstore, startp, endp-startp);
808 if (endp == startp)
809 {
810 strcpy (nstore, "./");
811 }
812 else if (! IS_DIR_SEPARATOR (endp[-1]))
813 {
814 nstore[endp-startp] = DIR_SEPARATOR;
815 nstore[endp-startp+1] = 0;
816 }
817 else
818 nstore[endp-startp] = 0;
819
820 if (debug)
821 fprintf (stderr, " - add prefix: %s\n", nstore);
822
823 add_prefix (pprefix, nstore);
824 if (*endp == 0)
825 break;
826 endp = startp = endp + 1;
827 }
828 else
829 endp++;
830 }
831 }
832 \f
833 /* Main program. */
834
835 int main PROTO ((int, char *[]));
836 int
837 main (argc, argv)
838 int argc;
839 char *argv[];
840 {
841 const char *ld_suffix = "ld";
842 const char *full_ld_suffix = ld_suffix;
843 const char *real_ld_suffix = "real-ld";
844 const char *collect_ld_suffix = "collect-ld";
845 const char *nm_suffix = "nm";
846 const char *full_nm_suffix = nm_suffix;
847 const char *gnm_suffix = "gnm";
848 const char *full_gnm_suffix = gnm_suffix;
849 #ifdef LDD_SUFFIX
850 const char *ldd_suffix = LDD_SUFFIX;
851 const char *full_ldd_suffix = ldd_suffix;
852 #endif
853 const char *strip_suffix = "strip";
854 const char *full_strip_suffix = strip_suffix;
855 const char *gstrip_suffix = "gstrip";
856 const char *full_gstrip_suffix = gstrip_suffix;
857 const char *arg;
858 FILE *outf;
859 #ifdef COLLECT_EXPORT_LIST
860 FILE *exportf;
861 FILE *importf;
862 #endif
863 const char *ld_file_name;
864 const char *p;
865 char **c_argv;
866 const char **c_ptr;
867 char **ld1_argv;
868 const char **ld1;
869 char **ld2_argv;
870 const char **ld2;
871 char **object_lst;
872 const char **object;
873 int first_file;
874 int num_c_args = argc+9;
875
876 #if defined (COLLECT2_HOST_INITIALIZATION)
877 /* Perform system dependant initialization, if neccessary. */
878 COLLECT2_HOST_INITIALIZATION;
879 #endif
880
881 #ifdef HAVE_LC_MESSAGES
882 setlocale (LC_MESSAGES, "");
883 #endif
884 (void) bindtextdomain (PACKAGE, localedir);
885 (void) textdomain (PACKAGE);
886
887 /* Do not invoke xcalloc before this point, since locale needs to be
888 set first, in case a diagnostic is issued. */
889
890 ld1 = (const char **)(ld1_argv = (char **) xcalloc(sizeof (char *), argc+3));
891 ld2 = (const char **)(ld2_argv = (char **) xcalloc(sizeof (char *), argc+10));
892 object = (const char **)(object_lst = (char **) xcalloc(sizeof (char *), argc));
893
894 #ifdef DEBUG
895 debug = 1;
896 #endif
897
898 /* Parse command line early for instances of -debug. This allows
899 the debug flag to be set before functions like find_a_file()
900 are called. */
901 {
902 int i;
903
904 for (i = 1; argv[i] != NULL; i ++)
905 if (! strcmp (argv[i], "-debug"))
906 debug = 1;
907 vflag = debug;
908 }
909
910 #ifndef DEFAULT_A_OUT_NAME
911 output_file = "a.out";
912 #else
913 output_file = DEFAULT_A_OUT_NAME;
914 #endif
915
916 obstack_begin (&temporary_obstack, 0);
917 obstack_begin (&permanent_obstack, 0);
918 temporary_firstobj = (char *) obstack_alloc (&temporary_obstack, 0);
919
920 current_demangling_style = gnu_demangling;
921 p = getenv ("COLLECT_GCC_OPTIONS");
922 while (p && *p)
923 {
924 const char *q = extract_string (&p);
925 if (*q == '-' && (q[1] == 'm' || q[1] == 'f'))
926 num_c_args++;
927 }
928 obstack_free (&temporary_obstack, temporary_firstobj);
929
930 /* -fno-exceptions -w */
931 num_c_args += 2;
932
933 c_ptr = (const char **)
934 (c_argv = (char **) xcalloc (sizeof (char *), num_c_args));
935
936 if (argc < 2)
937 fatal ("no arguments");
938
939 #ifdef SIGQUIT
940 if (signal (SIGQUIT, SIG_IGN) != SIG_IGN)
941 signal (SIGQUIT, handler);
942 #endif
943 if (signal (SIGINT, SIG_IGN) != SIG_IGN)
944 signal (SIGINT, handler);
945 #ifdef SIGALRM
946 if (signal (SIGALRM, SIG_IGN) != SIG_IGN)
947 signal (SIGALRM, handler);
948 #endif
949 #ifdef SIGHUP
950 if (signal (SIGHUP, SIG_IGN) != SIG_IGN)
951 signal (SIGHUP, handler);
952 #endif
953 if (signal (SIGSEGV, SIG_IGN) != SIG_IGN)
954 signal (SIGSEGV, handler);
955 #ifdef SIGBUS
956 if (signal (SIGBUS, SIG_IGN) != SIG_IGN)
957 signal (SIGBUS, handler);
958 #endif
959
960 /* Extract COMPILER_PATH and PATH into our prefix list. */
961 prefix_from_env ("COMPILER_PATH", &cpath);
962 prefix_from_env ("PATH", &path);
963
964 #ifdef CROSS_COMPILE
965 /* If we look for a program in the compiler directories, we just use
966 the short name, since these directories are already system-specific.
967 But it we look for a program in the system directories, we need to
968 qualify the program name with the target machine. */
969
970 full_ld_suffix = concat(target_machine, "-", ld_suffix, NULL);
971
972 #if 0
973 full_gld_suffix = concat (target_machine, "-", gld_suffix, NULL);
974 #endif
975
976 full_nm_suffix = concat (target_machine, "-", nm_suffix, NULL);
977
978 full_gnm_suffix = concat (target_machine, "-", gnm_suffix, NULL);
979
980 #ifdef LDD_SUFFIX
981 full_ldd_suffix = concat (target_machine, "-", ldd_suffix, NULL);
982 #endif
983
984 full_strip_suffix = concat (target_machine, "-", strip_suffix, NULL);
985
986 full_gstrip_suffix = concat (target_machine, "-", gstrip_suffix, NULL);
987 #endif /* CROSS_COMPILE */
988
989 /* Try to discover a valid linker/nm/strip to use. */
990
991 /* Maybe we know the right file to use (if not cross). */
992 ld_file_name = 0;
993 #ifdef DEFAULT_LINKER
994 if (access (DEFAULT_LINKER, X_OK) == 0)
995 ld_file_name = DEFAULT_LINKER;
996 if (ld_file_name == 0)
997 #endif
998 #ifdef REAL_LD_FILE_NAME
999 ld_file_name = find_a_file (&path, REAL_LD_FILE_NAME);
1000 if (ld_file_name == 0)
1001 #endif
1002 /* Search the (target-specific) compiler dirs for ld'. */
1003 ld_file_name = find_a_file (&cpath, real_ld_suffix);
1004 /* Likewise for `collect-ld'. */
1005 if (ld_file_name == 0)
1006 ld_file_name = find_a_file (&cpath, collect_ld_suffix);
1007 /* Search the compiler directories for `ld'. We have protection against
1008 recursive calls in find_a_file. */
1009 if (ld_file_name == 0)
1010 ld_file_name = find_a_file (&cpath, ld_suffix);
1011 /* Search the ordinary system bin directories
1012 for `ld' (if native linking) or `TARGET-ld' (if cross). */
1013 if (ld_file_name == 0)
1014 ld_file_name = find_a_file (&path, full_ld_suffix);
1015
1016 #ifdef REAL_NM_FILE_NAME
1017 nm_file_name = find_a_file (&path, REAL_NM_FILE_NAME);
1018 if (nm_file_name == 0)
1019 #endif
1020 nm_file_name = find_a_file (&cpath, gnm_suffix);
1021 if (nm_file_name == 0)
1022 nm_file_name = find_a_file (&path, full_gnm_suffix);
1023 if (nm_file_name == 0)
1024 nm_file_name = find_a_file (&cpath, nm_suffix);
1025 if (nm_file_name == 0)
1026 nm_file_name = find_a_file (&path, full_nm_suffix);
1027
1028 #ifdef LDD_SUFFIX
1029 ldd_file_name = find_a_file (&cpath, ldd_suffix);
1030 if (ldd_file_name == 0)
1031 ldd_file_name = find_a_file (&path, full_ldd_suffix);
1032 #endif
1033
1034 #ifdef REAL_STRIP_FILE_NAME
1035 strip_file_name = find_a_file (&path, REAL_STRIP_FILE_NAME);
1036 if (strip_file_name == 0)
1037 #endif
1038 strip_file_name = find_a_file (&cpath, gstrip_suffix);
1039 if (strip_file_name == 0)
1040 strip_file_name = find_a_file (&path, full_gstrip_suffix);
1041 if (strip_file_name == 0)
1042 strip_file_name = find_a_file (&cpath, strip_suffix);
1043 if (strip_file_name == 0)
1044 strip_file_name = find_a_file (&path, full_strip_suffix);
1045
1046 /* Determine the full path name of the C compiler to use. */
1047 c_file_name = getenv ("COLLECT_GCC");
1048 if (c_file_name == 0)
1049 {
1050 #ifdef CROSS_COMPILE
1051 c_file_name = concat (target_machine, "-gcc", NULL);
1052 #else
1053 c_file_name = "gcc";
1054 #endif
1055 }
1056
1057 p = find_a_file (&cpath, c_file_name);
1058
1059 /* Here it should be safe to use the system search path since we should have
1060 already qualified the name of the compiler when it is needed. */
1061 if (p == 0)
1062 p = find_a_file (&path, c_file_name);
1063
1064 if (p)
1065 c_file_name = p;
1066
1067 *ld1++ = *ld2++ = ld_file_name;
1068
1069 /* Make temp file names. */
1070 c_file = make_temp_file (".c");
1071 o_file = make_temp_file (".o");
1072 #ifdef COLLECT_EXPORT_LIST
1073 export_file = make_temp_file (".x");
1074 import_file = make_temp_file (".p");
1075 #endif
1076 ldout = make_temp_file (".ld");
1077 *c_ptr++ = c_file_name;
1078 *c_ptr++ = "-x";
1079 *c_ptr++ = "c";
1080 *c_ptr++ = "-c";
1081 *c_ptr++ = "-o";
1082 *c_ptr++ = o_file;
1083
1084 #ifdef COLLECT_EXPORT_LIST
1085 /* Generate a list of directories from LIBPATH. */
1086 prefix_from_env ("LIBPATH", &libpath_lib_dirs);
1087 /* Add to this list also two standard directories where
1088 AIX loader always searches for libraries. */
1089 add_prefix (&libpath_lib_dirs, "/lib");
1090 add_prefix (&libpath_lib_dirs, "/usr/lib");
1091 #endif
1092
1093 /* Get any options that the upper GCC wants to pass to the sub-GCC.
1094
1095 AIX support needs to know if -shared has been specified before
1096 parsing commandline arguments. */
1097
1098 p = getenv ("COLLECT_GCC_OPTIONS");
1099 while (p && *p)
1100 {
1101 const char *q = extract_string (&p);
1102 if (*q == '-' && (q[1] == 'm' || q[1] == 'f'))
1103 *c_ptr++ = obstack_copy0 (&permanent_obstack, q, strlen (q));
1104 if (strcmp (q, "-EL") == 0 || strcmp (q, "-EB") == 0)
1105 *c_ptr++ = obstack_copy0 (&permanent_obstack, q, strlen (q));
1106 if (strncmp (q, "-shared", sizeof ("-shared") - 1) == 0)
1107 shared_obj = 1;
1108 }
1109 obstack_free (&temporary_obstack, temporary_firstobj);
1110 *c_ptr++ = "-fno-exceptions";
1111 *c_ptr++ = "-w";
1112
1113 /* !!! When GCC calls collect2,
1114 it does not know whether it is calling collect2 or ld.
1115 So collect2 cannot meaningfully understand any options
1116 except those ld understands.
1117 If you propose to make GCC pass some other option,
1118 just imagine what will happen if ld is really ld!!! */
1119
1120 /* Parse arguments. Remember output file spec, pass the rest to ld. */
1121 /* After the first file, put in the c++ rt0. */
1122
1123 first_file = 1;
1124 while ((arg = *++argv) != (char *) 0)
1125 {
1126 *ld1++ = *ld2++ = arg;
1127
1128 if (arg[0] == '-')
1129 {
1130 switch (arg[1])
1131 {
1132 #ifdef COLLECT_EXPORT_LIST
1133 /* We want to disable automatic exports on AIX when user
1134 explicitly puts an export list in command line */
1135 case 'b':
1136 if (arg[2] == 'E' || strncmp (&arg[2], "export", 6) == 0)
1137 export_flag = 1;
1138 else if (arg[2] == '6' && arg[3] == '4')
1139 aix64_flag = 1;
1140 break;
1141 #endif
1142
1143 case 'd':
1144 if (!strcmp (arg, "-debug"))
1145 {
1146 /* Already parsed. */
1147 ld1--;
1148 ld2--;
1149 }
1150 break;
1151
1152 case 'l':
1153 if (first_file)
1154 {
1155 /* place o_file BEFORE this argument! */
1156 first_file = 0;
1157 ld2--;
1158 *ld2++ = o_file;
1159 *ld2++ = arg;
1160 }
1161 #ifdef COLLECT_EXPORT_LIST
1162 {
1163 /* Resolving full library name. */
1164 const char *s = resolve_lib_name (arg+2);
1165
1166 /* If we will use an import list for this library,
1167 we should exclude it from ld args. */
1168 if (use_import_list (s))
1169 {
1170 ld1--;
1171 ld2--;
1172 }
1173
1174 /* Saving a full library name. */
1175 add_to_list (&libs, s);
1176 }
1177 #endif
1178 break;
1179
1180 #ifdef COLLECT_EXPORT_LIST
1181 /* Saving directories where to search for libraries. */
1182 case 'L':
1183 add_prefix (&cmdline_lib_dirs, arg+2);
1184 break;
1185 #endif
1186
1187 case 'o':
1188 if (arg[2] == '\0')
1189 output_file = *ld1++ = *ld2++ = *++argv;
1190 else if (1
1191 #ifdef SWITCHES_NEED_SPACES
1192 && ! index (SWITCHES_NEED_SPACES, arg[1])
1193 #endif
1194 )
1195
1196 output_file = &arg[2];
1197 break;
1198
1199 case 'r':
1200 if (arg[2] == '\0')
1201 rflag = 1;
1202 break;
1203
1204 case 's':
1205 if (arg[2] == '\0' && do_collecting)
1206 {
1207 /* We must strip after the nm run, otherwise C++ linking
1208 will not work. Thus we strip in the second ld run, or
1209 else with strip if there is no second ld run. */
1210 strip_flag = 1;
1211 ld1--;
1212 }
1213 break;
1214
1215 case 'v':
1216 if (arg[2] == '\0')
1217 vflag = 1;
1218 break;
1219 }
1220 }
1221 else if ((p = rindex (arg, '.')) != (char *) 0
1222 && (strcmp (p, ".o") == 0 || strcmp (p, ".a") == 0
1223 || strcmp (p, ".so") == 0))
1224 {
1225 if (first_file)
1226 {
1227 first_file = 0;
1228 if (p[1] == 'o')
1229 *ld2++ = o_file;
1230 else
1231 {
1232 /* place o_file BEFORE this argument! */
1233 ld2--;
1234 *ld2++ = o_file;
1235 *ld2++ = arg;
1236 }
1237 }
1238 if (p[1] == 'o')
1239 *object++ = arg;
1240 #ifdef COLLECT_EXPORT_LIST
1241 /* libraries can be specified directly, i.e. without -l flag. */
1242 else
1243 {
1244 /* If we will use an import list for this library,
1245 we should exclude it from ld args. */
1246 if (use_import_list (arg))
1247 {
1248 ld1--;
1249 ld2--;
1250 }
1251
1252 /* Saving a full library name. */
1253 add_to_list (&libs, arg);
1254 }
1255 #endif
1256 }
1257 }
1258
1259 #ifdef COLLECT_EXPORT_LIST
1260 /* This is added only for debugging purposes. */
1261 if (debug)
1262 {
1263 fprintf (stderr, "List of libraries:\n");
1264 dump_list (stderr, "\t", libs.first);
1265 }
1266
1267 /* The AIX linker will discard static constructors in object files if
1268 nothing else in the file is referenced, so look at them first. */
1269 {
1270 const char **export_object_lst = (const char **)object_lst;
1271
1272 while (export_object_lst < object)
1273 scan_prog_file (*export_object_lst++, PASS_OBJ);
1274 }
1275 {
1276 struct id *list = libs.first;
1277
1278 for (; list; list = list->next)
1279 scan_prog_file (list->name, PASS_FIRST);
1280 }
1281
1282 if (exports.first)
1283 {
1284 char *buf = xmalloc (strlen (export_file) + 5);
1285
1286 sprintf (buf, "-bE:%s", export_file);
1287 *ld1++ = buf;
1288 *ld2++ = buf;
1289
1290 exportf = fopen (export_file, "w");
1291 if (exportf == (FILE *) 0)
1292 fatal_perror ("fopen %s", export_file);
1293 write_aix_file (exportf, exports.first);
1294 if (fclose (exportf))
1295 fatal_perror ("fclose %s", export_file);
1296 }
1297
1298 if (imports.first)
1299 {
1300 char *buf = xmalloc (strlen (import_file) + 5);
1301
1302 sprintf (buf, "-bI:%s", import_file);
1303 *ld1++ = buf;
1304 *ld2++ = buf;
1305
1306 importf = fopen (import_file, "w");
1307 if (importf == (FILE *) 0)
1308 fatal_perror ("%s", import_file);
1309 fputs ("#! .\n", importf);
1310 write_aix_file (importf, imports.first);
1311 if (fclose (importf))
1312 fatal_perror ("fclose %s", import_file);
1313 }
1314 #endif
1315
1316 *c_ptr++ = c_file;
1317 *c_ptr = *ld1 = *object = (char *) 0;
1318
1319 if (vflag)
1320 {
1321 notice ("collect2 version %s", version_string);
1322 #ifdef TARGET_VERSION
1323 TARGET_VERSION;
1324 #endif
1325 fprintf (stderr, "\n");
1326 }
1327
1328 if (debug)
1329 {
1330 const char *ptr;
1331 fprintf (stderr, "ld_file_name = %s\n",
1332 (ld_file_name ? ld_file_name : "not found"));
1333 fprintf (stderr, "c_file_name = %s\n",
1334 (c_file_name ? c_file_name : "not found"));
1335 fprintf (stderr, "nm_file_name = %s\n",
1336 (nm_file_name ? nm_file_name : "not found"));
1337 #ifdef LDD_SUFFIX
1338 fprintf (stderr, "ldd_file_name = %s\n",
1339 (ldd_file_name ? ldd_file_name : "not found"));
1340 #endif
1341 fprintf (stderr, "strip_file_name = %s\n",
1342 (strip_file_name ? strip_file_name : "not found"));
1343 fprintf (stderr, "c_file = %s\n",
1344 (c_file ? c_file : "not found"));
1345 fprintf (stderr, "o_file = %s\n",
1346 (o_file ? o_file : "not found"));
1347
1348 ptr = getenv ("COLLECT_GCC_OPTIONS");
1349 if (ptr)
1350 fprintf (stderr, "COLLECT_GCC_OPTIONS = %s\n", ptr);
1351
1352 ptr = getenv ("COLLECT_GCC");
1353 if (ptr)
1354 fprintf (stderr, "COLLECT_GCC = %s\n", ptr);
1355
1356 ptr = getenv ("COMPILER_PATH");
1357 if (ptr)
1358 fprintf (stderr, "COMPILER_PATH = %s\n", ptr);
1359
1360 ptr = getenv (LIBRARY_PATH_ENV);
1361 if (ptr)
1362 fprintf (stderr, "%-20s= %s\n", LIBRARY_PATH_ENV, ptr);
1363
1364 fprintf (stderr, "\n");
1365 }
1366
1367 /* Load the program, searching all libraries and attempting to provide
1368 undefined symbols from repository information. */
1369
1370 /* On AIX we do this later. */
1371 #ifndef COLLECT_EXPORT_LIST
1372 do_tlink (ld1_argv, object_lst);
1373 #endif
1374
1375 /* If -r or they will be run via some other method, do not build the
1376 constructor or destructor list, just return now. */
1377 if (rflag
1378 #ifndef COLLECT_EXPORT_LIST
1379 || ! do_collecting
1380 #endif
1381 )
1382 {
1383 #ifdef COLLECT_EXPORT_LIST
1384 /* Do the link we avoided above if we are exiting. */
1385 do_tlink (ld1_argv, object_lst);
1386
1387 /* But make sure we delete the export file we may have created. */
1388 if (export_file != 0 && export_file[0])
1389 maybe_unlink (export_file);
1390 if (import_file != 0 && import_file[0])
1391 maybe_unlink (import_file);
1392 #endif
1393 maybe_unlink (c_file);
1394 maybe_unlink (o_file);
1395 return 0;
1396 }
1397
1398 /* Examine the namelist with nm and search it for static constructors
1399 and destructors to call.
1400 Write the constructor and destructor tables to a .s file and reload. */
1401
1402 /* On AIX we already scanned for global constructors/destructors. */
1403 #ifndef COLLECT_EXPORT_LIST
1404 scan_prog_file (output_file, PASS_FIRST);
1405 #endif
1406
1407 #ifdef SCAN_LIBRARIES
1408 scan_libraries (output_file);
1409 #endif
1410
1411 if (debug)
1412 {
1413 notice ("%d constructor(s) found\n", constructors.number);
1414 notice ("%d destructor(s) found\n", destructors.number);
1415 notice ("%d frame table(s) found\n", frame_tables.number);
1416 }
1417
1418 if (constructors.number == 0 && destructors.number == 0
1419 && frame_tables.number == 0
1420 #if defined (SCAN_LIBRARIES) || defined (COLLECT_EXPORT_LIST)
1421 /* If we will be running these functions ourselves, we want to emit
1422 stubs into the shared library so that we do not have to relink
1423 dependent programs when we add static objects. */
1424 && ! shared_obj
1425 #endif
1426 )
1427 {
1428 #ifdef COLLECT_EXPORT_LIST
1429 /* Do tlink without additional code generation */
1430 do_tlink (ld1_argv, object_lst);
1431 #endif
1432 /* Strip now if it was requested on the command line. */
1433 if (strip_flag)
1434 {
1435 char **real_strip_argv = (char **) xcalloc (sizeof (char *), 3);
1436 const char ** strip_argv = (const char **) real_strip_argv;
1437
1438 strip_argv[0] = strip_file_name;
1439 strip_argv[1] = output_file;
1440 strip_argv[2] = (char *) 0;
1441 fork_execute ("strip", real_strip_argv);
1442 }
1443
1444 #ifdef COLLECT_EXPORT_LIST
1445 maybe_unlink (export_file);
1446 maybe_unlink (import_file);
1447 #endif
1448 maybe_unlink (c_file);
1449 maybe_unlink (o_file);
1450 return 0;
1451 }
1452
1453 /* Sort ctor and dtor lists by priority. */
1454 sort_ids (&constructors);
1455 sort_ids (&destructors);
1456
1457 maybe_unlink(output_file);
1458 outf = fopen (c_file, "w");
1459 if (outf == (FILE *) 0)
1460 fatal_perror ("fopen %s", c_file);
1461
1462 write_c_file (outf, c_file);
1463
1464 if (fclose (outf))
1465 fatal_perror ("fclose %s", c_file);
1466
1467 /* Tell the linker that we have initializer and finalizer functions. */
1468 #ifdef LD_INIT_SWITCH
1469 #ifdef COLLECT_EXPORT_LIST
1470 {
1471 /* option name + functions + colons + NULL */
1472 char *buf = xmalloc (strlen (LD_INIT_SWITCH)
1473 + strlen(initname) + strlen(fininame) + 3);
1474 sprintf (buf, "%s:%s:%s", LD_INIT_SWITCH, initname, fininame);
1475 *ld2++ = buf;
1476 }
1477 #else
1478 *ld2++ = LD_INIT_SWITCH;
1479 *ld2++ = initname;
1480 *ld2++ = LD_FINI_SWITCH;
1481 *ld2++ = fininame;
1482 #endif
1483 #endif
1484
1485 #ifdef COLLECT_EXPORT_LIST
1486 if (shared_obj)
1487 {
1488 /* If we did not add export flag to link arguments before, add it to
1489 second link phase now. No new exports should have been added. */
1490 if (! exports.first)
1491 {
1492 char *buf = xmalloc (strlen (export_file) + 5);
1493
1494 sprintf (buf, "-bE:%s", export_file);
1495 *ld2++ = buf;
1496 }
1497
1498 add_to_list (&exports, initname);
1499 add_to_list (&exports, fininame);
1500 add_to_list (&exports, "_GLOBAL__DI");
1501 add_to_list (&exports, "_GLOBAL__DD");
1502 exportf = fopen (export_file, "w");
1503 if (exportf == (FILE *) 0)
1504 fatal_perror ("fopen %s", export_file);
1505 write_aix_file (exportf, exports.first);
1506 if (fclose (exportf))
1507 fatal_perror ("fclose %s", export_file);
1508 }
1509 #endif
1510
1511 /* End of arguments to second link phase. */
1512 *ld2 = (char*) 0;
1513
1514 if (debug)
1515 {
1516 fprintf (stderr, "\n========== output_file = %s, c_file = %s\n",
1517 output_file, c_file);
1518 write_c_file (stderr, "stderr");
1519 fprintf (stderr, "========== end of c_file\n\n");
1520 #ifdef COLLECT_EXPORT_LIST
1521 fprintf (stderr, "\n========== export_file = %s\n", export_file);
1522 write_aix_file (stderr, exports.first);
1523 fprintf (stderr, "========== end of export_file\n\n");
1524 #endif
1525 }
1526
1527 /* Assemble the constructor and destructor tables.
1528 Link the tables in with the rest of the program. */
1529
1530 fork_execute ("gcc", c_argv);
1531 #ifdef COLLECT_EXPORT_LIST
1532 /* On AIX we must call tlink because of possible templates resolution */
1533 do_tlink (ld2_argv, object_lst);
1534 #else
1535 /* Otherwise, simply call ld because tlink is already done */
1536 fork_execute ("ld", ld2_argv);
1537
1538 /* Let scan_prog_file do any final mods (OSF/rose needs this for
1539 constructors/destructors in shared libraries. */
1540 scan_prog_file (output_file, PASS_SECOND);
1541 #endif
1542
1543 maybe_unlink (c_file);
1544 maybe_unlink (o_file);
1545
1546 #ifdef COLLECT_EXPORT_LIST
1547 maybe_unlink (export_file);
1548 maybe_unlink (import_file);
1549 #endif
1550
1551 return 0;
1552 }
1553
1554 \f
1555 /* Wait for a process to finish, and exit if a non-zero status is found. */
1556
1557 int
1558 collect_wait (prog)
1559 const char *prog;
1560 {
1561 int status;
1562
1563 pwait (pexecute_pid, &status, 0);
1564 if (status)
1565 {
1566 if (WIFSIGNALED (status))
1567 {
1568 int sig = WTERMSIG (status);
1569 error ("%s terminated with signal %d [%s]%s",
1570 prog, sig, strsignal(sig),
1571 status & 0200 ? "" : ", core dumped");
1572 collect_exit (FATAL_EXIT_CODE);
1573 }
1574
1575 if (WIFEXITED (status))
1576 return WEXITSTATUS (status);
1577 }
1578 return 0;
1579 }
1580
1581 static void
1582 do_wait (prog)
1583 const char *prog;
1584 {
1585 int ret = collect_wait (prog);
1586 if (ret != 0)
1587 {
1588 error ("%s returned %d exit status", prog, ret);
1589 collect_exit (ret);
1590 }
1591 }
1592
1593 \f
1594 /* Execute a program, and wait for the reply. */
1595
1596 void
1597 collect_execute (prog, argv, redir)
1598 const char *prog;
1599 char **argv;
1600 const char *redir;
1601 {
1602 char *errmsg_fmt;
1603 char *errmsg_arg;
1604 int redir_handle = -1;
1605 int stdout_save = -1;
1606 int stderr_save = -1;
1607
1608 if (vflag || debug)
1609 {
1610 char **p_argv;
1611 const char *str;
1612
1613 if (argv[0])
1614 fprintf (stderr, "%s", argv[0]);
1615 else
1616 notice ("[cannot find %s]", prog);
1617
1618 for (p_argv = &argv[1]; (str = *p_argv) != (char *) 0; p_argv++)
1619 fprintf (stderr, " %s", str);
1620
1621 fprintf (stderr, "\n");
1622 }
1623
1624 fflush (stdout);
1625 fflush (stderr);
1626
1627 /* If we cannot find a program we need, complain error. Do this here
1628 since we might not end up needing something that we could not find. */
1629
1630 if (argv[0] == 0)
1631 fatal ("cannot find `%s'", prog);
1632
1633 if (redir)
1634 {
1635 /* Open response file. */
1636 redir_handle = open (redir, O_WRONLY | O_TRUNC | O_CREAT);
1637
1638 /* Duplicate the stdout and stderr file handles
1639 so they can be restored later. */
1640 stdout_save = dup (STDOUT_FILENO);
1641 if (stdout_save == -1)
1642 fatal_perror ("redirecting stdout: %s", redir);
1643 stderr_save = dup (STDERR_FILENO);
1644 if (stderr_save == -1)
1645 fatal_perror ("redirecting stdout: %s", redir);
1646
1647 /* Redirect stdout & stderr to our response file. */
1648 dup2 (redir_handle, STDOUT_FILENO);
1649 dup2 (redir_handle, STDERR_FILENO);
1650 }
1651
1652 pexecute_pid = pexecute (argv[0], argv, argv[0], NULL,
1653 &errmsg_fmt, &errmsg_arg,
1654 (PEXECUTE_FIRST | PEXECUTE_LAST | PEXECUTE_SEARCH));
1655
1656 if (redir)
1657 {
1658 /* Restore stdout and stderr to their previous settings. */
1659 dup2 (stdout_save, STDOUT_FILENO);
1660 dup2 (stderr_save, STDERR_FILENO);
1661
1662 /* Close reponse file. */
1663 close (redir_handle);
1664 }
1665
1666 if (pexecute_pid == -1)
1667 fatal_perror (errmsg_fmt, errmsg_arg);
1668 }
1669
1670 static void
1671 fork_execute (prog, argv)
1672 const char *prog;
1673 char **argv;
1674 {
1675 collect_execute (prog, argv, NULL);
1676 do_wait (prog);
1677 }
1678 \f
1679 /* Unlink a file unless we are debugging. */
1680
1681 static void
1682 maybe_unlink (file)
1683 const char *file;
1684 {
1685 if (!debug)
1686 unlink (file);
1687 else
1688 notice ("[Leaving %s]\n", file);
1689 }
1690
1691 \f
1692 static long sequence_number = 0;
1693
1694 /* Add a name to a linked list. */
1695
1696 static void
1697 add_to_list (head_ptr, name)
1698 struct head *head_ptr;
1699 const char *name;
1700 {
1701 struct id *newid
1702 = (struct id *) xcalloc (sizeof (struct id) + strlen (name), 1);
1703 struct id *p;
1704 strcpy (newid->name, name);
1705
1706 if (head_ptr->first)
1707 head_ptr->last->next = newid;
1708 else
1709 head_ptr->first = newid;
1710
1711 /* Check for duplicate symbols. */
1712 for (p = head_ptr->first;
1713 strcmp (name, p->name) != 0;
1714 p = p->next)
1715 ;
1716 if (p != newid)
1717 {
1718 head_ptr->last->next = 0;
1719 free (newid);
1720 return;
1721 }
1722
1723 newid->sequence = ++sequence_number;
1724 head_ptr->last = newid;
1725 head_ptr->number++;
1726 }
1727
1728 /* Grab the init priority number from an init function name that
1729 looks like "_GLOBAL_.I.12345.foo". */
1730
1731 static int
1732 extract_init_priority (name)
1733 const char *name;
1734 {
1735 int pos = 0, pri;
1736
1737 while (name[pos] == '_')
1738 ++pos;
1739 pos += 10; /* strlen ("GLOBAL__X_") */
1740
1741 /* Extract init_p number from ctor/dtor name. */
1742 pri = atoi (name + pos);
1743 return pri ? pri : DEFAULT_INIT_PRIORITY;
1744 }
1745
1746 /* Insertion sort the ids from ctor/dtor list HEAD_PTR in descending order.
1747 ctors will be run from right to left, dtors from left to right. */
1748
1749 static void
1750 sort_ids (head_ptr)
1751 struct head *head_ptr;
1752 {
1753 /* id holds the current element to insert. id_next holds the next
1754 element to insert. id_ptr iterates through the already sorted elements
1755 looking for the place to insert id. */
1756 struct id *id, *id_next, **id_ptr;
1757
1758 id = head_ptr->first;
1759
1760 /* We don't have any sorted elements yet. */
1761 head_ptr->first = NULL;
1762
1763 for (; id; id = id_next)
1764 {
1765 id_next = id->next;
1766 id->sequence = extract_init_priority (id->name);
1767
1768 for (id_ptr = &(head_ptr->first); ; id_ptr = &((*id_ptr)->next))
1769 if (*id_ptr == NULL
1770 /* If the sequence numbers are the same, we put the id from the
1771 file later on the command line later in the list. */
1772 || id->sequence > (*id_ptr)->sequence
1773 /* Hack: do lexical compare, too.
1774 || (id->sequence == (*id_ptr)->sequence
1775 && strcmp (id->name, (*id_ptr)->name) > 0) */
1776 )
1777 {
1778 id->next = *id_ptr;
1779 *id_ptr = id;
1780 break;
1781 }
1782 }
1783
1784 /* Now set the sequence numbers properly so write_c_file works. */
1785 for (id = head_ptr->first; id; id = id->next)
1786 id->sequence = ++sequence_number;
1787 }
1788
1789 /* Write: `prefix', the names on list LIST, `suffix'. */
1790
1791 static void
1792 write_list (stream, prefix, list)
1793 FILE *stream;
1794 const char *prefix;
1795 struct id *list;
1796 {
1797 while (list)
1798 {
1799 fprintf (stream, "%sx%d,\n", prefix, list->sequence);
1800 list = list->next;
1801 }
1802 }
1803
1804 #ifdef COLLECT_EXPORT_LIST
1805 /* This function is really used only on AIX, but may be useful. */
1806 static int
1807 is_in_list (prefix, list)
1808 const char *prefix;
1809 struct id *list;
1810 {
1811 while (list)
1812 {
1813 if (!strcmp (prefix, list->name)) return 1;
1814 list = list->next;
1815 }
1816 return 0;
1817 }
1818 #endif
1819
1820 /* Added for debugging purpose. */
1821 #ifdef COLLECT_EXPORT_LIST
1822 static void
1823 dump_list (stream, prefix, list)
1824 FILE *stream;
1825 const char *prefix;
1826 struct id *list;
1827 {
1828 while (list)
1829 {
1830 fprintf (stream, "%s%s,\n", prefix, list->name);
1831 list = list->next;
1832 }
1833 }
1834 #endif
1835
1836 #if 0
1837 static void
1838 dump_prefix_list (stream, prefix, list)
1839 FILE *stream;
1840 const char *prefix;
1841 struct prefix_list *list;
1842 {
1843 while (list)
1844 {
1845 fprintf (stream, "%s%s,\n", prefix, list->prefix);
1846 list = list->next;
1847 }
1848 }
1849 #endif
1850
1851 static void
1852 write_list_with_asm (stream, prefix, list)
1853 FILE *stream;
1854 const char *prefix;
1855 struct id *list;
1856 {
1857 while (list)
1858 {
1859 fprintf (stream, "%sx%d __asm__ (\"%s\");\n",
1860 prefix, list->sequence, list->name);
1861 list = list->next;
1862 }
1863 }
1864
1865 /* Write out the constructor and destructor tables statically (for a shared
1866 object), along with the functions to execute them. */
1867
1868 static void
1869 write_c_file_stat (stream, name)
1870 FILE *stream;
1871 const char *name ATTRIBUTE_UNUSED;
1872 {
1873 const char *p, *q;
1874 char *prefix, *r;
1875 int frames = (frame_tables.number > 0);
1876
1877 /* Figure out name of output_file, stripping off .so version. */
1878 p = rindex (output_file, '/');
1879 if (p == 0)
1880 p = output_file;
1881 else
1882 p++;
1883 q = p;
1884 while (q)
1885 {
1886 q = index (q,'.');
1887 if (q == 0)
1888 {
1889 q = p + strlen (p);
1890 break;
1891 }
1892 else
1893 {
1894 if (strncmp (q, ".so", 3) == 0)
1895 {
1896 q += 3;
1897 break;
1898 }
1899 else
1900 q++;
1901 }
1902 }
1903 /* q points to null at end of the string (or . of the .so version) */
1904 prefix = xmalloc (q - p + 1);
1905 strncpy (prefix, p, q - p);
1906 prefix[q - p] = 0;
1907 for (r = prefix; *r; r++)
1908 if (!ISALNUM ((unsigned char)*r))
1909 *r = '_';
1910 if (debug)
1911 notice ("\nwrite_c_file - output name is %s, prefix is %s\n",
1912 output_file, prefix);
1913
1914 #define INIT_NAME_FORMAT "_GLOBAL__FI_%s"
1915 initname = xmalloc (strlen (prefix) + sizeof (INIT_NAME_FORMAT) - 2);
1916 sprintf (initname, INIT_NAME_FORMAT, prefix);
1917
1918 #define FINI_NAME_FORMAT "_GLOBAL__FD_%s"
1919 fininame = xmalloc (strlen (prefix) + sizeof (FINI_NAME_FORMAT) - 2);
1920 sprintf (fininame, FINI_NAME_FORMAT, prefix);
1921
1922 free (prefix);
1923
1924 /* Write the tables as C code */
1925
1926 fprintf (stream, "static int count;\n");
1927 fprintf (stream, "typedef void entry_pt();\n");
1928 write_list_with_asm (stream, "extern entry_pt ", constructors.first);
1929
1930 if (frames)
1931 {
1932 write_list_with_asm (stream, "extern void *", frame_tables.first);
1933
1934 fprintf (stream, "\tstatic void *frame_table[] = {\n");
1935 write_list (stream, "\t\t&", frame_tables.first);
1936 fprintf (stream, "\t0\n};\n");
1937
1938 /* This must match what's in frame.h. */
1939 fprintf (stream, "struct object {\n");
1940 fprintf (stream, " void *pc_begin;\n");
1941 fprintf (stream, " void *pc_end;\n");
1942 fprintf (stream, " void *fde_begin;\n");
1943 fprintf (stream, " void *fde_array;\n");
1944 fprintf (stream, " __SIZE_TYPE__ count;\n");
1945 fprintf (stream, " struct object *next;\n");
1946 fprintf (stream, "};\n");
1947
1948 fprintf (stream, "extern void __register_frame_info_table (void *, struct object *);\n");
1949 fprintf (stream, "extern void *__deregister_frame_info (void *);\n");
1950
1951 fprintf (stream, "static void reg_frame () {\n");
1952 fprintf (stream, "\tstatic struct object ob;\n");
1953 fprintf (stream, "\t__register_frame_info_table (frame_table, &ob);\n");
1954 fprintf (stream, "\t}\n");
1955
1956 fprintf (stream, "static void dereg_frame () {\n");
1957 fprintf (stream, "\t__deregister_frame_info (frame_table);\n");
1958 fprintf (stream, "\t}\n");
1959 }
1960
1961 fprintf (stream, "void %s() {\n", initname);
1962 if (constructors.number > 0 || frames)
1963 {
1964 fprintf (stream, "\tstatic entry_pt *ctors[] = {\n");
1965 write_list (stream, "\t\t", constructors.first);
1966 if (frames)
1967 fprintf (stream, "\treg_frame,\n");
1968 fprintf (stream, "\t};\n");
1969 fprintf (stream, "\tentry_pt **p;\n");
1970 fprintf (stream, "\tif (count++ != 0) return;\n");
1971 fprintf (stream, "\tp = ctors + %d;\n", constructors.number + frames);
1972 fprintf (stream, "\twhile (p > ctors) (*--p)();\n");
1973 }
1974 else
1975 fprintf (stream, "\t++count;\n");
1976 fprintf (stream, "}\n");
1977 write_list_with_asm (stream, "extern entry_pt ", destructors.first);
1978 fprintf (stream, "void %s() {\n", fininame);
1979 if (destructors.number > 0 || frames)
1980 {
1981 fprintf (stream, "\tstatic entry_pt *dtors[] = {\n");
1982 write_list (stream, "\t\t", destructors.first);
1983 if (frames)
1984 fprintf (stream, "\tdereg_frame,\n");
1985 fprintf (stream, "\t};\n");
1986 fprintf (stream, "\tentry_pt **p;\n");
1987 fprintf (stream, "\tif (--count != 0) return;\n");
1988 fprintf (stream, "\tp = dtors;\n");
1989 fprintf (stream, "\twhile (p < dtors + %d) (*p++)();\n",
1990 destructors.number + frames);
1991 }
1992 fprintf (stream, "}\n");
1993
1994 if (shared_obj)
1995 {
1996 fprintf (stream, "void _GLOBAL__DI() {\n\t%s();\n}\n", initname);
1997 fprintf (stream, "void _GLOBAL__DD() {\n\t%s();\n}\n", fininame);
1998 }
1999 }
2000
2001 /* Write the constructor/destructor tables. */
2002
2003 #ifndef LD_INIT_SWITCH
2004 static void
2005 write_c_file_glob (stream, name)
2006 FILE *stream;
2007 const char *name ATTRIBUTE_UNUSED;
2008 {
2009 /* Write the tables as C code */
2010
2011 int frames = (frame_tables.number > 0);
2012
2013 fprintf (stream, "typedef void entry_pt();\n\n");
2014
2015 write_list_with_asm (stream, "extern entry_pt ", constructors.first);
2016
2017 if (frames)
2018 {
2019 write_list_with_asm (stream, "extern void *", frame_tables.first);
2020
2021 fprintf (stream, "\tstatic void *frame_table[] = {\n");
2022 write_list (stream, "\t\t&", frame_tables.first);
2023 fprintf (stream, "\t0\n};\n");
2024
2025 /* This must match what's in frame.h. */
2026 fprintf (stream, "struct object {\n");
2027 fprintf (stream, " void *pc_begin;\n");
2028 fprintf (stream, " void *pc_end;\n");
2029 fprintf (stream, " void *fde_begin;\n");
2030 fprintf (stream, " void *fde_array;\n");
2031 fprintf (stream, " __SIZE_TYPE__ count;\n");
2032 fprintf (stream, " struct object *next;\n");
2033 fprintf (stream, "};\n");
2034
2035 fprintf (stream, "extern void __register_frame_info_table (void *, struct object *);\n");
2036 fprintf (stream, "extern void *__deregister_frame_info (void *);\n");
2037
2038 fprintf (stream, "static void reg_frame () {\n");
2039 fprintf (stream, "\tstatic struct object ob;\n");
2040 fprintf (stream, "\t__register_frame_info_table (frame_table, &ob);\n");
2041 fprintf (stream, "\t}\n");
2042
2043 fprintf (stream, "static void dereg_frame () {\n");
2044 fprintf (stream, "\t__deregister_frame_info (frame_table);\n");
2045 fprintf (stream, "\t}\n");
2046 }
2047
2048 fprintf (stream, "\nentry_pt * __CTOR_LIST__[] = {\n");
2049 fprintf (stream, "\t(entry_pt *) %d,\n", constructors.number + frames);
2050 write_list (stream, "\t", constructors.first);
2051 if (frames)
2052 fprintf (stream, "\treg_frame,\n");
2053 fprintf (stream, "\t0\n};\n\n");
2054
2055 write_list_with_asm (stream, "extern entry_pt ", destructors.first);
2056
2057 fprintf (stream, "\nentry_pt * __DTOR_LIST__[] = {\n");
2058 fprintf (stream, "\t(entry_pt *) %d,\n", destructors.number + frames);
2059 write_list (stream, "\t", destructors.first);
2060 if (frames)
2061 fprintf (stream, "\tdereg_frame,\n");
2062 fprintf (stream, "\t0\n};\n\n");
2063
2064 fprintf (stream, "extern entry_pt %s;\n", NAME__MAIN);
2065 fprintf (stream, "entry_pt *__main_reference = %s;\n\n", NAME__MAIN);
2066 }
2067 #endif /* ! LD_INIT_SWITCH */
2068
2069 static void
2070 write_c_file (stream, name)
2071 FILE *stream;
2072 const char *name;
2073 {
2074 fprintf (stream, "#ifdef __cplusplus\nextern \"C\" {\n#endif\n");
2075 #ifndef LD_INIT_SWITCH
2076 if (! shared_obj)
2077 write_c_file_glob (stream, name);
2078 else
2079 #endif
2080 write_c_file_stat (stream, name);
2081 fprintf (stream, "#ifdef __cplusplus\n}\n#endif\n");
2082 }
2083
2084 #ifdef COLLECT_EXPORT_LIST
2085 static void
2086 write_aix_file (stream, list)
2087 FILE *stream;
2088 struct id *list;
2089 {
2090 for (; list; list = list->next)
2091 {
2092 fputs (list->name, stream);
2093 putc ('\n', stream);
2094 }
2095 }
2096 #endif
2097 \f
2098 #ifdef OBJECT_FORMAT_NONE
2099
2100 /* Generic version to scan the name list of the loaded program for
2101 the symbols g++ uses for static constructors and destructors.
2102
2103 The constructor table begins at __CTOR_LIST__ and contains a count
2104 of the number of pointers (or -1 if the constructors are built in a
2105 separate section by the linker), followed by the pointers to the
2106 constructor functions, terminated with a null pointer. The
2107 destructor table has the same format, and begins at __DTOR_LIST__. */
2108
2109 static void
2110 scan_prog_file (prog_name, which_pass)
2111 const char *prog_name;
2112 enum pass which_pass;
2113 {
2114 void (*int_handler) PROTO ((int));
2115 void (*quit_handler) PROTO ((int));
2116 char *real_nm_argv[4];
2117 const char **nm_argv = (const char **) real_nm_argv;
2118 int pid;
2119 int argc = 0;
2120 int pipe_fd[2];
2121 char *p, buf[1024];
2122 FILE *inf;
2123
2124 if (which_pass == PASS_SECOND)
2125 return;
2126
2127 /* If we do not have an `nm', complain. */
2128 if (nm_file_name == 0)
2129 fatal ("cannot find `nm'");
2130
2131 nm_argv[argc++] = nm_file_name;
2132 if (NM_FLAGS[0] != '\0')
2133 nm_argv[argc++] = NM_FLAGS;
2134
2135 nm_argv[argc++] = prog_name;
2136 nm_argv[argc++] = (char *) 0;
2137
2138 if (pipe (pipe_fd) < 0)
2139 fatal_perror ("pipe");
2140
2141 inf = fdopen (pipe_fd[0], "r");
2142 if (inf == (FILE *) 0)
2143 fatal_perror ("fdopen");
2144
2145 /* Trace if needed. */
2146 if (vflag)
2147 {
2148 const char **p_argv;
2149 const char *str;
2150
2151 for (p_argv = &nm_argv[0]; (str = *p_argv) != (char *) 0; p_argv++)
2152 fprintf (stderr, " %s", str);
2153
2154 fprintf (stderr, "\n");
2155 }
2156
2157 fflush (stdout);
2158 fflush (stderr);
2159
2160 /* Spawn child nm on pipe */
2161 pid = vfork ();
2162 if (pid == -1)
2163 fatal_perror (VFORK_STRING);
2164
2165 if (pid == 0) /* child context */
2166 {
2167 /* setup stdout */
2168 if (dup2 (pipe_fd[1], 1) < 0)
2169 fatal_perror ("dup2 %d 1", pipe_fd[1]);
2170
2171 if (close (pipe_fd[0]) < 0)
2172 fatal_perror ("close %d", pipe_fd[0]);
2173
2174 if (close (pipe_fd[1]) < 0)
2175 fatal_perror ("close %d", pipe_fd[1]);
2176
2177 execv (nm_file_name, real_nm_argv);
2178 fatal_perror ("execvp %s", nm_file_name);
2179 }
2180
2181 /* Parent context from here on. */
2182 int_handler = (void (*) PROTO ((int))) signal (SIGINT, SIG_IGN);
2183 #ifdef SIGQUIT
2184 quit_handler = (void (*) PROTO ((int))) signal (SIGQUIT, SIG_IGN);
2185 #endif
2186
2187 if (close (pipe_fd[1]) < 0)
2188 fatal_perror ("close %d", pipe_fd[1]);
2189
2190 if (debug)
2191 fprintf (stderr, "\nnm output with constructors/destructors.\n");
2192
2193 /* Read each line of nm output. */
2194 while (fgets (buf, sizeof buf, inf) != (char *) 0)
2195 {
2196 int ch, ch2;
2197 char *name, *end;
2198
2199 /* If it contains a constructor or destructor name, add the name
2200 to the appropriate list. */
2201
2202 for (p = buf; (ch = *p) != '\0' && ch != '\n' && ch != '_'; p++)
2203 if (ch == ' ' && p[1] == 'U' && p[2] == ' ')
2204 break;
2205
2206 if (ch != '_')
2207 continue;
2208
2209 name = p;
2210 /* Find the end of the symbol name.
2211 Do not include `|', because Encore nm can tack that on the end. */
2212 for (end = p; (ch2 = *end) != '\0' && !ISSPACE (ch2) && ch2 != '|';
2213 end++)
2214 continue;
2215
2216
2217 *end = '\0';
2218 switch (is_ctor_dtor (name))
2219 {
2220 case 1:
2221 if (which_pass != PASS_LIB)
2222 add_to_list (&constructors, name);
2223 break;
2224
2225 case 2:
2226 if (which_pass != PASS_LIB)
2227 add_to_list (&destructors, name);
2228 break;
2229
2230 case 3:
2231 if (which_pass != PASS_LIB)
2232 fatal ("init function found in object %s", prog_name);
2233 #ifndef LD_INIT_SWITCH
2234 add_to_list (&constructors, name);
2235 #endif
2236 break;
2237
2238 case 4:
2239 if (which_pass != PASS_LIB)
2240 fatal ("fini function found in object %s", prog_name);
2241 #ifndef LD_FINI_SWITCH
2242 add_to_list (&destructors, name);
2243 #endif
2244 break;
2245
2246 case 5:
2247 if (which_pass != PASS_LIB)
2248 add_to_list (&frame_tables, name);
2249 break;
2250
2251 default: /* not a constructor or destructor */
2252 continue;
2253 }
2254
2255 if (debug)
2256 fprintf (stderr, "\t%s\n", buf);
2257 }
2258
2259 if (debug)
2260 fprintf (stderr, "\n");
2261
2262 if (fclose (inf) != 0)
2263 fatal_perror ("fclose");
2264
2265 do_wait (nm_file_name);
2266
2267 signal (SIGINT, int_handler);
2268 #ifdef SIGQUIT
2269 signal (SIGQUIT, quit_handler);
2270 #endif
2271 }
2272
2273 #if SUNOS4_SHARED_LIBRARIES
2274
2275 /* Routines to scan the SunOS 4 _DYNAMIC structure to find shared libraries
2276 that the output file depends upon and their initialization/finalization
2277 routines, if any. */
2278
2279 #include <a.out.h>
2280 #include <fcntl.h>
2281 #include <link.h>
2282 #include <sys/mman.h>
2283 #include <sys/param.h>
2284 #include <unistd.h>
2285 #include <sys/dir.h>
2286
2287 /* pointers to the object file */
2288 unsigned object; /* address of memory mapped file */
2289 unsigned objsize; /* size of memory mapped to file */
2290 char * code; /* pointer to code segment */
2291 char * data; /* pointer to data segment */
2292 struct nlist *symtab; /* pointer to symbol table */
2293 struct link_dynamic *ld;
2294 struct link_dynamic_2 *ld_2;
2295 struct head libraries;
2296
2297 /* Map the file indicated by NAME into memory and store its address. */
2298
2299 static void mapfile PROTO ((const char *));
2300
2301 static void
2302 mapfile (name)
2303 const char *name;
2304 {
2305 int fp;
2306 struct stat s;
2307 if ((fp = open (name, O_RDONLY)) == -1)
2308 fatal ("unable to open file '%s'", name);
2309 if (fstat (fp, &s) == -1)
2310 fatal ("unable to stat file '%s'", name);
2311
2312 objsize = s.st_size;
2313 object = (unsigned) mmap (0, objsize, PROT_READ|PROT_WRITE, MAP_PRIVATE,
2314 fp, 0);
2315 if (object == (unsigned)-1)
2316 fatal ("unable to mmap file '%s'", name);
2317
2318 close (fp);
2319 }
2320
2321 /* Helpers for locatelib. */
2322
2323 static const char *libname;
2324
2325 static int libselect PROTO ((struct direct *));
2326
2327 static int
2328 libselect (d)
2329 struct direct *d;
2330 {
2331 return (strncmp (libname, d->d_name, strlen (libname)) == 0);
2332 }
2333
2334 /* If one file has an additional numeric extension past LIBNAME, then put
2335 that one first in the sort. If both files have additional numeric
2336 extensions, then put the one with the higher number first in the sort.
2337
2338 We must verify that the extension is numeric, because Sun saves the
2339 original versions of patched libraries with a .FCS extension. Files with
2340 invalid extensions must go last in the sort, so that they will not be used. */
2341 static int libcompare PROTO ((struct direct **, struct direct **));
2342
2343 static int
2344 libcompare (d1, d2)
2345 struct direct **d1, **d2;
2346 {
2347 int i1, i2 = strlen (libname);
2348 char *e1 = (*d1)->d_name + i2;
2349 char *e2 = (*d2)->d_name + i2;
2350
2351 while (*e1 && *e2 && *e1 == '.' && *e2 == '.'
2352 && e1[1] && ISDIGIT (e1[1]) && e2[1] && ISDIGIT (e2[1]))
2353 {
2354 ++e1;
2355 ++e2;
2356 i1 = strtol (e1, &e1, 10);
2357 i2 = strtol (e2, &e2, 10);
2358 if (i1 != i2)
2359 return i1 - i2;
2360 }
2361
2362 if (*e1)
2363 {
2364 /* It has a valid numeric extension, prefer this one. */
2365 if (*e1 == '.' && e1[1] && ISDIGIT (e1[1]))
2366 return 1;
2367 /* It has a invalid numeric extension, must prefer the other one. */
2368 else
2369 return -1;
2370 }
2371 else if (*e2)
2372 {
2373 /* It has a valid numeric extension, prefer this one. */
2374 if (*e2 == '.' && e2[1] && ISDIGIT (e2[1]))
2375 return -1;
2376 /* It has a invalid numeric extension, must prefer the other one. */
2377 else
2378 return 1;
2379 }
2380 else
2381 return 0;
2382 }
2383
2384 /* Given the name NAME of a dynamic dependency, find its pathname and add
2385 it to the list of libraries. */
2386 static void locatelib PROTO ((const char *));
2387
2388 static void
2389 locatelib (name)
2390 const char *name;
2391 {
2392 static const char **l;
2393 static int cnt;
2394 char buf[MAXPATHLEN];
2395 char *p, *q;
2396 const char **pp;
2397
2398 if (l == 0)
2399 {
2400 char *ld_rules;
2401 char *ldr = 0;
2402 /* counting elements in array, need 1 extra for null */
2403 cnt = 1;
2404 ld_rules = (char *) (ld_2->ld_rules + code);
2405 if (ld_rules)
2406 {
2407 cnt++;
2408 for (; *ld_rules != 0; ld_rules++)
2409 if (*ld_rules == ':')
2410 cnt++;
2411 ld_rules = (char *) (ld_2->ld_rules + code);
2412 ldr = xstrdup (ld_rules);
2413 }
2414 p = getenv ("LD_LIBRARY_PATH");
2415 q = 0;
2416 if (p)
2417 {
2418 cnt++;
2419 for (q = p ; *q != 0; q++)
2420 if (*q == ':')
2421 cnt++;
2422 q = xstrdup (p);
2423 }
2424 l = (const char **) xmalloc ((cnt + 3) * sizeof (char *));
2425 pp = l;
2426 if (ldr)
2427 {
2428 *pp++ = ldr;
2429 for (; *ldr != 0; ldr++)
2430 if (*ldr == ':')
2431 {
2432 *ldr++ = 0;
2433 *pp++ = ldr;
2434 }
2435 }
2436 if (q)
2437 {
2438 *pp++ = q;
2439 for (; *q != 0; q++)
2440 if (*q == ':')
2441 {
2442 *q++ = 0;
2443 *pp++ = q;
2444 }
2445 }
2446 /* built in directories are /lib, /usr/lib, and /usr/local/lib */
2447 *pp++ = "/lib";
2448 *pp++ = "/usr/lib";
2449 *pp++ = "/usr/local/lib";
2450 *pp = 0;
2451 }
2452 libname = name;
2453 for (pp = l; *pp != 0 ; pp++)
2454 {
2455 struct direct **namelist;
2456 int entries;
2457 if ((entries = scandir (*pp, &namelist, libselect, libcompare)) > 0)
2458 {
2459 sprintf (buf, "%s/%s", *pp, namelist[entries - 1]->d_name);
2460 add_to_list (&libraries, buf);
2461 if (debug)
2462 fprintf (stderr, "%s\n", buf);
2463 break;
2464 }
2465 }
2466 if (*pp == 0)
2467 {
2468 if (debug)
2469 notice ("not found\n");
2470 else
2471 fatal ("dynamic dependency %s not found", name);
2472 }
2473 }
2474
2475 /* Scan the _DYNAMIC structure of the output file to find shared libraries
2476 that it depends upon and any constructors or destructors they contain. */
2477
2478 static void
2479 scan_libraries (prog_name)
2480 const char *prog_name;
2481 {
2482 struct exec *header;
2483 char *base;
2484 struct link_object *lo;
2485 char buff[MAXPATHLEN];
2486 struct id *list;
2487
2488 mapfile (prog_name);
2489 header = (struct exec *)object;
2490 if (N_BADMAG (*header))
2491 fatal ("bad magic number in file '%s'", prog_name);
2492 if (header->a_dynamic == 0)
2493 return;
2494
2495 code = (char *) (N_TXTOFF (*header) + (long) header);
2496 data = (char *) (N_DATOFF (*header) + (long) header);
2497 symtab = (struct nlist *) (N_SYMOFF (*header) + (long) header);
2498
2499 if (header->a_magic == ZMAGIC && header->a_entry == 0x20)
2500 {
2501 /* shared object */
2502 ld = (struct link_dynamic *) (symtab->n_value + code);
2503 base = code;
2504 }
2505 else
2506 {
2507 /* executable */
2508 ld = (struct link_dynamic *) data;
2509 base = code-PAGSIZ;
2510 }
2511
2512 if (debug)
2513 notice ("dynamic dependencies.\n");
2514
2515 ld_2 = (struct link_dynamic_2 *) ((long) ld->ld_un.ld_2 + (long)base);
2516 for (lo = (struct link_object *) ld_2->ld_need; lo;
2517 lo = (struct link_object *) lo->lo_next)
2518 {
2519 char *name;
2520 lo = (struct link_object *) ((long) lo + code);
2521 name = (char *) (code + lo->lo_name);
2522 if (lo->lo_library)
2523 {
2524 if (debug)
2525 fprintf (stderr, "\t-l%s.%d => ", name, lo->lo_major);
2526 sprintf (buff, "lib%s.so.%d.%d", name, lo->lo_major, lo->lo_minor);
2527 locatelib (buff);
2528 }
2529 else
2530 {
2531 if (debug)
2532 fprintf (stderr, "\t%s\n", name);
2533 add_to_list (&libraries, name);
2534 }
2535 }
2536
2537 if (debug)
2538 fprintf (stderr, "\n");
2539
2540 /* now iterate through the library list adding their symbols to
2541 the list. */
2542 for (list = libraries.first; list; list = list->next)
2543 scan_prog_file (list->name, PASS_LIB);
2544 }
2545
2546 #else /* SUNOS4_SHARED_LIBRARIES */
2547 #ifdef LDD_SUFFIX
2548
2549 /* Use the List Dynamic Dependencies program to find shared libraries that
2550 the output file depends upon and their initialization/finalization
2551 routines, if any. */
2552
2553 static void
2554 scan_libraries (prog_name)
2555 const char *prog_name;
2556 {
2557 static struct head libraries; /* list of shared libraries found */
2558 struct id *list;
2559 void (*int_handler) PROTO ((int));
2560 void (*quit_handler) PROTO ((int));
2561 char *real_ldd_argv[4];
2562 const char **ldd_argv = (const char **) real_ldd_argv;
2563 int pid;
2564 int argc = 0;
2565 int pipe_fd[2];
2566 char buf[1024];
2567 FILE *inf;
2568
2569 /* If we do not have an `ldd', complain. */
2570 if (ldd_file_name == 0)
2571 {
2572 error ("cannot find `ldd'");
2573 return;
2574 }
2575
2576 ldd_argv[argc++] = ldd_file_name;
2577 ldd_argv[argc++] = prog_name;
2578 ldd_argv[argc++] = (char *) 0;
2579
2580 if (pipe (pipe_fd) < 0)
2581 fatal_perror ("pipe");
2582
2583 inf = fdopen (pipe_fd[0], "r");
2584 if (inf == (FILE *) 0)
2585 fatal_perror ("fdopen");
2586
2587 /* Trace if needed. */
2588 if (vflag)
2589 {
2590 const char **p_argv;
2591 const char *str;
2592
2593 for (p_argv = &ldd_argv[0]; (str = *p_argv) != (char *) 0; p_argv++)
2594 fprintf (stderr, " %s", str);
2595
2596 fprintf (stderr, "\n");
2597 }
2598
2599 fflush (stdout);
2600 fflush (stderr);
2601
2602 /* Spawn child ldd on pipe */
2603 pid = vfork ();
2604 if (pid == -1)
2605 fatal_perror (VFORK_STRING);
2606
2607 if (pid == 0) /* child context */
2608 {
2609 /* setup stdout */
2610 if (dup2 (pipe_fd[1], 1) < 0)
2611 fatal_perror ("dup2 %d 1", pipe_fd[1]);
2612
2613 if (close (pipe_fd[0]) < 0)
2614 fatal_perror ("close %d", pipe_fd[0]);
2615
2616 if (close (pipe_fd[1]) < 0)
2617 fatal_perror ("close %d", pipe_fd[1]);
2618
2619 execv (ldd_file_name, real_ldd_argv);
2620 fatal_perror ("execv %s", ldd_file_name);
2621 }
2622
2623 /* Parent context from here on. */
2624 int_handler = (void (*) PROTO ((int))) signal (SIGINT, SIG_IGN);
2625 #ifdef SIGQUIT
2626 quit_handler = (void (*) PROTO ((int))) signal (SIGQUIT, SIG_IGN);
2627 #endif
2628
2629 if (close (pipe_fd[1]) < 0)
2630 fatal_perror ("close %d", pipe_fd[1]);
2631
2632 if (debug)
2633 notice ("\nldd output with constructors/destructors.\n");
2634
2635 /* Read each line of ldd output. */
2636 while (fgets (buf, sizeof buf, inf) != (char *) 0)
2637 {
2638 int ch, ch2;
2639 char *name, *end, *p = buf;
2640
2641 /* Extract names of libraries and add to list. */
2642 PARSE_LDD_OUTPUT (p);
2643 if (p == 0)
2644 continue;
2645
2646 name = p;
2647 if (strncmp (name, "not found", sizeof ("not found") - 1) == 0)
2648 fatal ("dynamic dependency %s not found", buf);
2649
2650 /* Find the end of the symbol name. */
2651 for (end = p;
2652 (ch2 = *end) != '\0' && ch2 != '\n' && !ISSPACE (ch2) && ch2 != '|';
2653 end++)
2654 continue;
2655 *end = '\0';
2656
2657 if (access (name, R_OK) == 0)
2658 add_to_list (&libraries, name);
2659 else
2660 fatal ("unable to open dynamic dependency '%s'", buf);
2661
2662 if (debug)
2663 fprintf (stderr, "\t%s\n", buf);
2664 }
2665 if (debug)
2666 fprintf (stderr, "\n");
2667
2668 if (fclose (inf) != 0)
2669 fatal_perror ("fclose");
2670
2671 do_wait (ldd_file_name);
2672
2673 signal (SIGINT, int_handler);
2674 #ifdef SIGQUIT
2675 signal (SIGQUIT, quit_handler);
2676 #endif
2677
2678 /* now iterate through the library list adding their symbols to
2679 the list. */
2680 for (list = libraries.first; list; list = list->next)
2681 scan_prog_file (list->name, PASS_LIB);
2682 }
2683
2684 #endif /* LDD_SUFFIX */
2685 #endif /* SUNOS4_SHARED_LIBRARIES */
2686
2687 #endif /* OBJECT_FORMAT_NONE */
2688
2689 \f
2690 /*
2691 * COFF specific stuff.
2692 */
2693
2694 #ifdef OBJECT_FORMAT_COFF
2695
2696 #if defined(EXTENDED_COFF)
2697 # define GCC_SYMBOLS(X) (SYMHEADER(X).isymMax + SYMHEADER(X).iextMax)
2698 # define GCC_SYMENT SYMR
2699 # define GCC_OK_SYMBOL(X) ((X).st == stProc || (X).st == stGlobal)
2700 # define GCC_SYMINC(X) (1)
2701 # define GCC_SYMZERO(X) (SYMHEADER(X).isymMax)
2702 # define GCC_CHECK_HDR(X) (PSYMTAB(X) != 0)
2703 #else
2704 # define GCC_SYMBOLS(X) (HEADER(ldptr).f_nsyms)
2705 # define GCC_SYMENT SYMENT
2706 # define GCC_OK_SYMBOL(X) \
2707 (((X).n_sclass == C_EXT) && \
2708 ((X).n_scnum > N_UNDEF) && \
2709 (aix64_flag \
2710 || (((X).n_type & N_TMASK) == (DT_NON << N_BTSHFT) \
2711 || ((X).n_type & N_TMASK) == (DT_FCN << N_BTSHFT))))
2712 # define GCC_UNDEF_SYMBOL(X) \
2713 (((X).n_sclass == C_EXT) && ((X).n_scnum == N_UNDEF))
2714 # define GCC_SYMINC(X) ((X).n_numaux+1)
2715 # define GCC_SYMZERO(X) 0
2716 # define GCC_CHECK_HDR(X) \
2717 ((HEADER (X).f_magic == U802TOCMAGIC && ! aix64_flag) \
2718 || (HEADER (X).f_magic == 0757 && aix64_flag))
2719 #endif
2720
2721 extern char *ldgetname ();
2722
2723 /* COFF version to scan the name list of the loaded program for
2724 the symbols g++ uses for static constructors and destructors.
2725
2726 The constructor table begins at __CTOR_LIST__ and contains a count
2727 of the number of pointers (or -1 if the constructors are built in a
2728 separate section by the linker), followed by the pointers to the
2729 constructor functions, terminated with a null pointer. The
2730 destructor table has the same format, and begins at __DTOR_LIST__. */
2731
2732 static void
2733 scan_prog_file (prog_name, which_pass)
2734 const char *prog_name;
2735 enum pass which_pass;
2736 {
2737 LDFILE *ldptr = NULL;
2738 int sym_index, sym_count;
2739 int is_shared = 0;
2740 #ifdef COLLECT_EXPORT_LIST
2741 /* Should we generate an import list for given prog_name? */
2742 int import_flag = (which_pass == PASS_OBJ ? 0 : use_import_list (prog_name));
2743 #endif
2744
2745 if (which_pass != PASS_FIRST && which_pass != PASS_OBJ)
2746 return;
2747
2748 #ifdef COLLECT_EXPORT_LIST
2749 /* We do not need scanning for some standard C libraries. */
2750 if (which_pass == PASS_FIRST && ignore_library (prog_name))
2751 return;
2752
2753 /* On AIX we have a loop, because there is not much difference
2754 between an object and an archive. This trick allows us to
2755 eliminate scan_libraries() function. */
2756 do
2757 {
2758 #endif
2759 /* Some platforms (e.g. OSF4) declare ldopen as taking a
2760 non-const char * filename parameter, even though it will not
2761 modify that string. So we must cast away const-ness here,
2762 which will cause -Wcast-qual to burp. */
2763 if ((ldptr = ldopen ((char *)prog_name, ldptr)) != NULL)
2764 {
2765 if (! MY_ISCOFF (HEADER (ldptr).f_magic))
2766 fatal ("%s: not a COFF file", prog_name);
2767
2768 if (GCC_CHECK_HDR (ldptr))
2769 {
2770 sym_count = GCC_SYMBOLS (ldptr);
2771 sym_index = GCC_SYMZERO (ldptr);
2772
2773 #ifdef COLLECT_EXPORT_LIST
2774 /* Is current archive member a shared object? */
2775 is_shared = HEADER (ldptr).f_flags & F_SHROBJ;
2776 #endif
2777
2778 while (sym_index < sym_count)
2779 {
2780 GCC_SYMENT symbol;
2781
2782 if (ldtbread (ldptr, sym_index, &symbol) <= 0)
2783 break;
2784 sym_index += GCC_SYMINC (symbol);
2785
2786 if (GCC_OK_SYMBOL (symbol))
2787 {
2788 char *name;
2789
2790 if ((name = ldgetname (ldptr, &symbol)) == NULL)
2791 continue; /* should never happen */
2792
2793 #ifdef XCOFF_DEBUGGING_INFO
2794 /* All AIX function names have a duplicate entry
2795 beginning with a dot. */
2796 if (*name == '.')
2797 ++name;
2798 #endif
2799
2800 switch (is_ctor_dtor (name))
2801 {
2802 case 1:
2803 if (! is_shared)
2804 add_to_list (&constructors, name);
2805 #ifdef COLLECT_EXPORT_LIST
2806 if (which_pass == PASS_OBJ)
2807 add_to_list (&exports, name);
2808 /* If this symbol was undefined and we are building
2809 an import list, we should add a symbol to this
2810 list. */
2811 else
2812 if (import_flag
2813 && is_in_list (name, undefined.first))
2814 add_to_list (&imports, name);
2815 #endif
2816 break;
2817
2818 case 2:
2819 if (! is_shared)
2820 add_to_list (&destructors, name);
2821 #ifdef COLLECT_EXPORT_LIST
2822 if (which_pass == PASS_OBJ)
2823 add_to_list (&exports, name);
2824 /* If this symbol was undefined and we are building
2825 an import list, we should add a symbol to this
2826 list. */
2827 else
2828 if (import_flag
2829 && is_in_list (name, undefined.first))
2830 add_to_list (&imports, name);
2831 #endif
2832 break;
2833
2834 #ifdef COLLECT_EXPORT_LIST
2835 case 3:
2836 #ifndef LD_INIT_SWITCH
2837 if (is_shared)
2838 add_to_list (&constructors, name);
2839 #endif
2840 break;
2841
2842 case 4:
2843 #ifndef LD_INIT_SWITCH
2844 if (is_shared)
2845 add_to_list (&destructors, name);
2846 #endif
2847 break;
2848 #endif
2849
2850 case 5:
2851 if (! is_shared)
2852 add_to_list (&frame_tables, name);
2853 break;
2854
2855 default: /* not a constructor or destructor */
2856 #ifdef COLLECT_EXPORT_LIST
2857 /* If we are building a shared object on AIX we need
2858 to explicitly export all global symbols or add
2859 them to import list. */
2860 if (shared_obj)
2861 {
2862 if (which_pass == PASS_OBJ && (! export_flag))
2863 add_to_list (&exports, name);
2864 else if (! is_shared
2865 && which_pass == PASS_FIRST
2866 && import_flag
2867 && is_in_list(name, undefined.first))
2868 add_to_list (&imports, name);
2869 }
2870 #endif
2871 continue;
2872 }
2873
2874 if (debug)
2875 #if !defined(EXTENDED_COFF)
2876 fprintf (stderr, "\tsec=%d class=%d type=%s%o %s\n",
2877 symbol.n_scnum, symbol.n_sclass,
2878 (symbol.n_type ? "0" : ""), symbol.n_type,
2879 name);
2880 #else
2881 fprintf (stderr,
2882 "\tiss = %5d, value = %5ld, index = %5d, name = %s\n",
2883 symbol.iss, (long) symbol.value, symbol.index, name);
2884 #endif
2885 }
2886 #ifdef COLLECT_EXPORT_LIST
2887 /* If we are building a shared object we should collect
2888 information about undefined symbols for later
2889 import list generation. */
2890 else if (shared_obj && GCC_UNDEF_SYMBOL (symbol))
2891 {
2892 char *name;
2893
2894 if ((name = ldgetname (ldptr, &symbol)) == NULL)
2895 continue; /* should never happen */
2896
2897 /* All AIX function names have a duplicate entry
2898 beginning with a dot. */
2899 if (*name == '.')
2900 ++name;
2901 add_to_list (&undefined, name);
2902 }
2903 #endif
2904 }
2905 }
2906 #ifdef COLLECT_EXPORT_LIST
2907 else
2908 {
2909 /* If archive contains both 32-bit and 64-bit objects,
2910 we want to skip objects in other mode so mismatch normal. */
2911 if (debug)
2912 fprintf (stderr, "%s : magic=%o aix64=%d mismatch\n",
2913 prog_name, HEADER (ldptr).f_magic, aix64_flag);
2914 }
2915 #endif
2916 }
2917 else
2918 {
2919 fatal ("%s: cannot open as COFF file", prog_name);
2920 }
2921 #ifdef COLLECT_EXPORT_LIST
2922 /* On AIX loop continues while there are more members in archive. */
2923 }
2924 while (ldclose (ldptr) == FAILURE);
2925 #else
2926 /* Otherwise we simply close ldptr. */
2927 (void) ldclose(ldptr);
2928 #endif
2929 }
2930
2931
2932 #ifdef COLLECT_EXPORT_LIST
2933
2934 /* This new function is used to decide whether we should
2935 generate import list for an object or to use it directly. */
2936 static int
2937 use_import_list (prog_name)
2938 const char *prog_name;
2939 {
2940 char *p;
2941
2942 /* If we do not build a shared object then import list should not be used. */
2943 if (! shared_obj) return 0;
2944
2945 /* Currently we check only for libgcc, but this can be changed in future. */
2946 p = strstr (prog_name, "libgcc.a");
2947 if (p != 0 && (strlen (p) == sizeof ("libgcc.a") - 1))
2948 return 1;
2949 return 0;
2950 }
2951
2952 /* Given a library name without "lib" prefix, this function
2953 returns a full library name including a path. */
2954 static char *
2955 resolve_lib_name (name)
2956 const char *name;
2957 {
2958 char *lib_buf;
2959 int i, j, l = 0;
2960
2961 for (i = 0; libpaths[i]; i++)
2962 if (libpaths[i]->max_len > l)
2963 l = libpaths[i]->max_len;
2964
2965 lib_buf = xmalloc (l + strlen(name) + 10);
2966
2967 for (i = 0; libpaths[i]; i++)
2968 {
2969 struct prefix_list *list = libpaths[i]->plist;
2970 for (; list; list = list->next)
2971 {
2972 for (j = 0; libexts[j]; j++)
2973 {
2974 /* The following lines are needed because path_prefix list
2975 may contain directories both with trailing '/' and
2976 without it. */
2977 const char *p = "";
2978 if (list->prefix[strlen(list->prefix)-1] != '/')
2979 p = "/";
2980 sprintf (lib_buf, "%s%slib%s.%s",
2981 list->prefix, p, name, libexts[j]);
2982 if (debug) fprintf (stderr, "searching for: %s\n", lib_buf);
2983 if (file_exists (lib_buf))
2984 {
2985 if (debug) fprintf (stderr, "found: %s\n", lib_buf);
2986 return (lib_buf);
2987 }
2988 }
2989 }
2990 }
2991 if (debug)
2992 fprintf (stderr, "not found\n");
2993 else
2994 fatal ("Library lib%s not found", name);
2995 return (NULL);
2996 }
2997
2998 /* Array of standard AIX libraries which should not
2999 be scanned for ctors/dtors. */
3000 static const char *aix_std_libs[] = {
3001 "/unix",
3002 "/lib/libc.a",
3003 "/lib/libc_r.a",
3004 "/usr/lib/libc.a",
3005 "/usr/lib/libc_r.a",
3006 "/usr/lib/threads/libc.a",
3007 "/usr/ccs/lib/libc.a",
3008 "/usr/ccs/lib/libc_r.a",
3009 NULL
3010 };
3011
3012 /* This function checks the filename and returns 1
3013 if this name matches the location of a standard AIX library. */
3014 static int
3015 ignore_library (name)
3016 const char *name;
3017 {
3018 const char **p = &aix_std_libs[0];
3019 while (*p++ != NULL)
3020 if (! strcmp (name, *p)) return 1;
3021 return 0;
3022 }
3023
3024 #endif
3025
3026 #endif /* OBJECT_FORMAT_COFF */
3027
3028 \f
3029 /*
3030 * OSF/rose specific stuff.
3031 */
3032
3033 #ifdef OBJECT_FORMAT_ROSE
3034
3035 /* Union of the various load commands */
3036
3037 typedef union load_union
3038 {
3039 ldc_header_t hdr; /* common header */
3040 load_cmd_map_command_t map; /* map indexing other load cmds */
3041 interpreter_command_t iprtr; /* interpreter pathname */
3042 strings_command_t str; /* load commands strings section */
3043 region_command_t region; /* region load command */
3044 reloc_command_t reloc; /* relocation section */
3045 package_command_t pkg; /* package load command */
3046 symbols_command_t sym; /* symbol sections */
3047 entry_command_t ent; /* program start section */
3048 gen_info_command_t info; /* object information */
3049 func_table_command_t func; /* function constructors/destructors */
3050 } load_union_t;
3051
3052 /* Structure to point to load command and data section in memory. */
3053
3054 typedef struct load_all
3055 {
3056 load_union_t *load; /* load command */
3057 char *section; /* pointer to section */
3058 } load_all_t;
3059
3060 /* Structure to contain information about a file mapped into memory. */
3061
3062 struct file_info
3063 {
3064 char *start; /* start of map */
3065 char *name; /* filename */
3066 long size; /* size of the file */
3067 long rounded_size; /* size rounded to page boundary */
3068 int fd; /* file descriptor */
3069 int rw; /* != 0 if opened read/write */
3070 int use_mmap; /* != 0 if mmap'ed */
3071 };
3072
3073 extern int decode_mach_o_hdr ();
3074 extern int encode_mach_o_hdr ();
3075
3076 static void add_func_table PROTO((mo_header_t *, load_all_t *,
3077 symbol_info_t *, int));
3078 static void print_header PROTO((mo_header_t *));
3079 static void print_load_command PROTO((load_union_t *, size_t, int));
3080 static void bad_header PROTO((int));
3081 static struct file_info *read_file PROTO((const char *, int, int));
3082 static void end_file PROTO((struct file_info *));
3083 \f
3084 /* OSF/rose specific version to scan the name list of the loaded
3085 program for the symbols g++ uses for static constructors and
3086 destructors.
3087
3088 The constructor table begins at __CTOR_LIST__ and contains a count
3089 of the number of pointers (or -1 if the constructors are built in a
3090 separate section by the linker), followed by the pointers to the
3091 constructor functions, terminated with a null pointer. The
3092 destructor table has the same format, and begins at __DTOR_LIST__. */
3093
3094 static void
3095 scan_prog_file (prog_name, which_pass)
3096 const char *prog_name;
3097 enum pass which_pass;
3098 {
3099 char *obj;
3100 mo_header_t hdr;
3101 load_all_t *load_array;
3102 load_all_t *load_end;
3103 load_all_t *load_cmd;
3104 int symbol_load_cmds;
3105 off_t offset;
3106 int i;
3107 int num_syms;
3108 int status;
3109 char *str_sect;
3110 struct file_info *obj_file;
3111 int prog_fd;
3112 mo_lcid_t cmd_strings = -1;
3113 symbol_info_t *main_sym = 0;
3114 int rw = (which_pass != PASS_FIRST);
3115
3116 prog_fd = open (prog_name, (rw) ? O_RDWR : O_RDONLY);
3117 if (prog_fd < 0)
3118 fatal_perror ("open %s", prog_name);
3119
3120 obj_file = read_file (prog_name, prog_fd, rw);
3121 obj = obj_file->start;
3122
3123 status = decode_mach_o_hdr (obj, MO_SIZEOF_RAW_HDR, MOH_HEADER_VERSION, &hdr);
3124 if (status != MO_HDR_CONV_SUCCESS)
3125 bad_header (status);
3126
3127
3128 /* Do some basic sanity checks. Note we explicitly use the big endian magic number,
3129 since the hardware will automatically swap bytes for us on loading little endian
3130 integers. */
3131
3132 #ifndef CROSS_COMPILE
3133 if (hdr.moh_magic != MOH_MAGIC_MSB
3134 || hdr.moh_header_version != MOH_HEADER_VERSION
3135 || hdr.moh_byte_order != OUR_BYTE_ORDER
3136 || hdr.moh_data_rep_id != OUR_DATA_REP_ID
3137 || hdr.moh_cpu_type != OUR_CPU_TYPE
3138 || hdr.moh_cpu_subtype != OUR_CPU_SUBTYPE
3139 || hdr.moh_vendor_type != OUR_VENDOR_TYPE)
3140 {
3141 fatal ("incompatibilities between object file & expected values");
3142 }
3143 #endif
3144
3145 if (debug)
3146 print_header (&hdr);
3147
3148 offset = hdr.moh_first_cmd_off;
3149 load_end = load_array
3150 = (load_all_t *) xcalloc (sizeof (load_all_t), hdr.moh_n_load_cmds + 2);
3151
3152 /* Build array of load commands, calculating the offsets */
3153 for (i = 0; i < hdr.moh_n_load_cmds; i++)
3154 {
3155 load_union_t *load_hdr; /* load command header */
3156
3157 load_cmd = load_end++;
3158 load_hdr = (load_union_t *) (obj + offset);
3159
3160 /* If modifying the program file, copy the header. */
3161 if (rw)
3162 {
3163 load_union_t *ptr = (load_union_t *) xmalloc (load_hdr->hdr.ldci_cmd_size);
3164 bcopy ((char *)load_hdr, (char *)ptr, load_hdr->hdr.ldci_cmd_size);
3165 load_hdr = ptr;
3166
3167 /* null out old command map, because we will rewrite at the end. */
3168 if (ptr->hdr.ldci_cmd_type == LDC_CMD_MAP)
3169 {
3170 cmd_strings = ptr->map.lcm_ld_cmd_strings;
3171 ptr->hdr.ldci_cmd_type = LDC_UNDEFINED;
3172 }
3173 }
3174
3175 load_cmd->load = load_hdr;
3176 if (load_hdr->hdr.ldci_section_off > 0)
3177 load_cmd->section = obj + load_hdr->hdr.ldci_section_off;
3178
3179 if (debug)
3180 print_load_command (load_hdr, offset, i);
3181
3182 offset += load_hdr->hdr.ldci_cmd_size;
3183 }
3184
3185 /* If the last command is the load command map and is not undefined,
3186 decrement the count of load commands. */
3187 if (rw && load_end[-1].load->hdr.ldci_cmd_type == LDC_UNDEFINED)
3188 {
3189 load_end--;
3190 hdr.moh_n_load_cmds--;
3191 }
3192
3193 /* Go through and process each symbol table section. */
3194 symbol_load_cmds = 0;
3195 for (load_cmd = load_array; load_cmd < load_end; load_cmd++)
3196 {
3197 load_union_t *load_hdr = load_cmd->load;
3198
3199 if (load_hdr->hdr.ldci_cmd_type == LDC_SYMBOLS)
3200 {
3201 symbol_load_cmds++;
3202
3203 if (debug)
3204 {
3205 const char *kind = "unknown";
3206
3207 switch (load_hdr->sym.symc_kind)
3208 {
3209 case SYMC_IMPORTS: kind = "imports"; break;
3210 case SYMC_DEFINED_SYMBOLS: kind = "defined"; break;
3211 case SYMC_STABS: kind = "stabs"; break;
3212 }
3213
3214 notice ("\nProcessing symbol table #%d, offset = 0x%.8lx, kind = %s\n",
3215 symbol_load_cmds, load_hdr->hdr.ldci_section_off, kind);
3216 }
3217
3218 if (load_hdr->sym.symc_kind != SYMC_DEFINED_SYMBOLS)
3219 continue;
3220
3221 str_sect = load_array[load_hdr->sym.symc_strings_section].section;
3222 if (str_sect == (char *) 0)
3223 fatal ("string section missing");
3224
3225 if (load_cmd->section == (char *) 0)
3226 fatal ("section pointer missing");
3227
3228 num_syms = load_hdr->sym.symc_nentries;
3229 for (i = 0; i < num_syms; i++)
3230 {
3231 symbol_info_t *sym = ((symbol_info_t *) load_cmd->section) + i;
3232 char *name = sym->si_name.symbol_name + str_sect;
3233
3234 if (name[0] != '_')
3235 continue;
3236
3237 if (rw)
3238 {
3239 char *n = name + strlen (name) - strlen (NAME__MAIN);
3240
3241 if ((n - name) < 0 || strcmp (n, NAME__MAIN))
3242 continue;
3243 while (n != name)
3244 if (*--n != '_')
3245 continue;
3246
3247 main_sym = sym;
3248 }
3249 else
3250 {
3251 switch (is_ctor_dtor (name))
3252 {
3253 case 1:
3254 add_to_list (&constructors, name);
3255 break;
3256
3257 case 2:
3258 add_to_list (&destructors, name);
3259 break;
3260
3261 default: /* not a constructor or destructor */
3262 continue;
3263 }
3264 }
3265
3266 if (debug)
3267 fprintf (stderr, "\ttype = 0x%.4x, sc = 0x%.2x, flags = 0x%.8x, name = %.30s\n",
3268 sym->si_type, sym->si_sc_type, sym->si_flags, name);
3269 }
3270 }
3271 }
3272
3273 if (symbol_load_cmds == 0)
3274 fatal ("no symbol table found");
3275
3276 /* Update the program file now, rewrite header and load commands. At present,
3277 we assume that there is enough space after the last load command to insert
3278 one more. Since the first section written out is page aligned, and the
3279 number of load commands is small, this is ok for the present. */
3280
3281 if (rw)
3282 {
3283 load_union_t *load_map;
3284 size_t size;
3285
3286 if (cmd_strings == -1)
3287 fatal ("no cmd_strings found");
3288
3289 /* Add __main to initializer list.
3290 If we are building a program instead of a shared library, do not
3291 do anything, since in the current version, you cannot do mallocs
3292 and such in the constructors. */
3293
3294 if (main_sym != (symbol_info_t *) 0
3295 && ((hdr.moh_flags & MOH_EXECABLE_F) == 0))
3296 add_func_table (&hdr, load_array, main_sym, FNTC_INITIALIZATION);
3297
3298 if (debug)
3299 notice ("\nUpdating header and load commands.\n\n");
3300
3301 hdr.moh_n_load_cmds++;
3302 size = sizeof (load_cmd_map_command_t) + (sizeof (mo_offset_t) * (hdr.moh_n_load_cmds - 1));
3303
3304 /* Create new load command map. */
3305 if (debug)
3306 notice ("load command map, %d cmds, new size %ld.\n",
3307 (int) hdr.moh_n_load_cmds, (long) size);
3308
3309 load_map = (load_union_t *) xcalloc (1, size);
3310 load_map->map.ldc_header.ldci_cmd_type = LDC_CMD_MAP;
3311 load_map->map.ldc_header.ldci_cmd_size = size;
3312 load_map->map.lcm_ld_cmd_strings = cmd_strings;
3313 load_map->map.lcm_nentries = hdr.moh_n_load_cmds;
3314 load_array[hdr.moh_n_load_cmds-1].load = load_map;
3315
3316 offset = hdr.moh_first_cmd_off;
3317 for (i = 0; i < hdr.moh_n_load_cmds; i++)
3318 {
3319 load_map->map.lcm_map[i] = offset;
3320 if (load_array[i].load->hdr.ldci_cmd_type == LDC_CMD_MAP)
3321 hdr.moh_load_map_cmd_off = offset;
3322
3323 offset += load_array[i].load->hdr.ldci_cmd_size;
3324 }
3325
3326 hdr.moh_sizeofcmds = offset - MO_SIZEOF_RAW_HDR;
3327
3328 if (debug)
3329 print_header (&hdr);
3330
3331 /* Write header */
3332 status = encode_mach_o_hdr (&hdr, obj, MO_SIZEOF_RAW_HDR);
3333 if (status != MO_HDR_CONV_SUCCESS)
3334 bad_header (status);
3335
3336 if (debug)
3337 notice ("writing load commands.\n\n");
3338
3339 /* Write load commands */
3340 offset = hdr.moh_first_cmd_off;
3341 for (i = 0; i < hdr.moh_n_load_cmds; i++)
3342 {
3343 load_union_t *load_hdr = load_array[i].load;
3344 size_t size = load_hdr->hdr.ldci_cmd_size;
3345
3346 if (debug)
3347 print_load_command (load_hdr, offset, i);
3348
3349 bcopy ((char *) load_hdr, (char *) (obj + offset), size);
3350 offset += size;
3351 }
3352 }
3353
3354 end_file (obj_file);
3355
3356 if (close (prog_fd))
3357 fatal_perror ("close %s", prog_name);
3358
3359 if (debug)
3360 fprintf (stderr, "\n");
3361 }
3362
3363 \f
3364 /* Add a function table to the load commands to call a function
3365 on initiation or termination of the process. */
3366
3367 static void
3368 add_func_table (hdr_p, load_array, sym, type)
3369 mo_header_t *hdr_p; /* pointer to global header */
3370 load_all_t *load_array; /* array of ptrs to load cmds */
3371 symbol_info_t *sym; /* pointer to symbol entry */
3372 int type; /* fntc_type value */
3373 {
3374 /* Add a new load command. */
3375 int num_cmds = ++hdr_p->moh_n_load_cmds;
3376 int load_index = num_cmds - 1;
3377 size_t size = sizeof (func_table_command_t) + sizeof (mo_addr_t);
3378 load_union_t *ptr = xcalloc (1, size);
3379 load_all_t *load_cmd;
3380 int i;
3381
3382 /* Set the unresolved address bit in the header to force the loader to be
3383 used, since kernel exec does not call the initialization functions. */
3384 hdr_p->moh_flags |= MOH_UNRESOLVED_F;
3385
3386 load_cmd = &load_array[load_index];
3387 load_cmd->load = ptr;
3388 load_cmd->section = (char *) 0;
3389
3390 /* Fill in func table load command. */
3391 ptr->func.ldc_header.ldci_cmd_type = LDC_FUNC_TABLE;
3392 ptr->func.ldc_header.ldci_cmd_size = size;
3393 ptr->func.ldc_header.ldci_section_off = 0;
3394 ptr->func.ldc_header.ldci_section_len = 0;
3395 ptr->func.fntc_type = type;
3396 ptr->func.fntc_nentries = 1;
3397
3398 /* copy address, turn it from abs. address to (region,offset) if necessary. */
3399 /* Is the symbol already expressed as (region, offset)? */
3400 if ((sym->si_flags & SI_ABSOLUTE_VALUE_F) == 0)
3401 {
3402 ptr->func.fntc_entry_loc[i].adr_lcid = sym->si_value.def_val.adr_lcid;
3403 ptr->func.fntc_entry_loc[i].adr_sctoff = sym->si_value.def_val.adr_sctoff;
3404 }
3405
3406 /* If not, figure out which region it's in. */
3407 else
3408 {
3409 mo_vm_addr_t addr = sym->si_value.abs_val;
3410 int found = 0;
3411
3412 for (i = 0; i < load_index; i++)
3413 {
3414 if (load_array[i].load->hdr.ldci_cmd_type == LDC_REGION)
3415 {
3416 region_command_t *region_ptr = &load_array[i].load->region;
3417
3418 if ((region_ptr->regc_flags & REG_ABS_ADDR_F) != 0
3419 && addr >= region_ptr->regc_addr.vm_addr
3420 && addr <= region_ptr->regc_addr.vm_addr + region_ptr->regc_vm_size)
3421 {
3422 ptr->func.fntc_entry_loc[0].adr_lcid = i;
3423 ptr->func.fntc_entry_loc[0].adr_sctoff = addr - region_ptr->regc_addr.vm_addr;
3424 found++;
3425 break;
3426 }
3427 }
3428 }
3429
3430 if (!found)
3431 fatal ("could not convert 0x%l.8x into a region", addr);
3432 }
3433
3434 if (debug)
3435 notice ("%s function, region %d, offset = %ld (0x%.8lx)\n",
3436 type == FNTC_INITIALIZATION ? "init" : "term",
3437 (int) ptr->func.fntc_entry_loc[i].adr_lcid,
3438 (long) ptr->func.fntc_entry_loc[i].adr_sctoff,
3439 (long) ptr->func.fntc_entry_loc[i].adr_sctoff);
3440
3441 }
3442
3443 \f
3444 /* Print the global header for an OSF/rose object. */
3445
3446 static void
3447 print_header (hdr_ptr)
3448 mo_header_t *hdr_ptr;
3449 {
3450 fprintf (stderr, "\nglobal header:\n");
3451 fprintf (stderr, "\tmoh_magic = 0x%.8lx\n", hdr_ptr->moh_magic);
3452 fprintf (stderr, "\tmoh_major_version = %d\n", (int)hdr_ptr->moh_major_version);
3453 fprintf (stderr, "\tmoh_minor_version = %d\n", (int)hdr_ptr->moh_minor_version);
3454 fprintf (stderr, "\tmoh_header_version = %d\n", (int)hdr_ptr->moh_header_version);
3455 fprintf (stderr, "\tmoh_max_page_size = %d\n", (int)hdr_ptr->moh_max_page_size);
3456 fprintf (stderr, "\tmoh_byte_order = %d\n", (int)hdr_ptr->moh_byte_order);
3457 fprintf (stderr, "\tmoh_data_rep_id = %d\n", (int)hdr_ptr->moh_data_rep_id);
3458 fprintf (stderr, "\tmoh_cpu_type = %d\n", (int)hdr_ptr->moh_cpu_type);
3459 fprintf (stderr, "\tmoh_cpu_subtype = %d\n", (int)hdr_ptr->moh_cpu_subtype);
3460 fprintf (stderr, "\tmoh_vendor_type = %d\n", (int)hdr_ptr->moh_vendor_type);
3461 fprintf (stderr, "\tmoh_load_map_cmd_off = %d\n", (int)hdr_ptr->moh_load_map_cmd_off);
3462 fprintf (stderr, "\tmoh_first_cmd_off = %d\n", (int)hdr_ptr->moh_first_cmd_off);
3463 fprintf (stderr, "\tmoh_sizeofcmds = %d\n", (int)hdr_ptr->moh_sizeofcmds);
3464 fprintf (stderr, "\tmon_n_load_cmds = %d\n", (int)hdr_ptr->moh_n_load_cmds);
3465 fprintf (stderr, "\tmoh_flags = 0x%.8lx", (long)hdr_ptr->moh_flags);
3466
3467 if (hdr_ptr->moh_flags & MOH_RELOCATABLE_F)
3468 fprintf (stderr, ", relocatable");
3469
3470 if (hdr_ptr->moh_flags & MOH_LINKABLE_F)
3471 fprintf (stderr, ", linkable");
3472
3473 if (hdr_ptr->moh_flags & MOH_EXECABLE_F)
3474 fprintf (stderr, ", execable");
3475
3476 if (hdr_ptr->moh_flags & MOH_EXECUTABLE_F)
3477 fprintf (stderr, ", executable");
3478
3479 if (hdr_ptr->moh_flags & MOH_UNRESOLVED_F)
3480 fprintf (stderr, ", unresolved");
3481
3482 fprintf (stderr, "\n\n");
3483 return;
3484 }
3485
3486 \f
3487 /* Print a short summary of a load command. */
3488
3489 static void
3490 print_load_command (load_hdr, offset, number)
3491 load_union_t *load_hdr;
3492 size_t offset;
3493 int number;
3494 {
3495 mo_long_t type = load_hdr->hdr.ldci_cmd_type;
3496 const char *type_str = (char *) 0;
3497
3498 switch (type)
3499 {
3500 case LDC_UNDEFINED: type_str = "UNDEFINED"; break;
3501 case LDC_CMD_MAP: type_str = "CMD_MAP"; break;
3502 case LDC_INTERPRETER: type_str = "INTERPRETER"; break;
3503 case LDC_STRINGS: type_str = "STRINGS"; break;
3504 case LDC_REGION: type_str = "REGION"; break;
3505 case LDC_RELOC: type_str = "RELOC"; break;
3506 case LDC_PACKAGE: type_str = "PACKAGE"; break;
3507 case LDC_SYMBOLS: type_str = "SYMBOLS"; break;
3508 case LDC_ENTRY: type_str = "ENTRY"; break;
3509 case LDC_FUNC_TABLE: type_str = "FUNC_TABLE"; break;
3510 case LDC_GEN_INFO: type_str = "GEN_INFO"; break;
3511 }
3512
3513 fprintf (stderr,
3514 "cmd %2d, sz: 0x%.2lx, coff: 0x%.3lx, doff: 0x%.6lx, dlen: 0x%.6lx",
3515 number,
3516 (long) load_hdr->hdr.ldci_cmd_size,
3517 (long) offset,
3518 (long) load_hdr->hdr.ldci_section_off,
3519 (long) load_hdr->hdr.ldci_section_len);
3520
3521 if (type_str == (char *) 0)
3522 fprintf (stderr, ", ty: unknown (%ld)\n", (long) type);
3523
3524 else if (type != LDC_REGION)
3525 fprintf (stderr, ", ty: %s\n", type_str);
3526
3527 else
3528 {
3529 const char *region = "";
3530 switch (load_hdr->region.regc_usage_type)
3531 {
3532 case REG_TEXT_T: region = ", .text"; break;
3533 case REG_DATA_T: region = ", .data"; break;
3534 case REG_BSS_T: region = ", .bss"; break;
3535 case REG_GLUE_T: region = ", .glue"; break;
3536 #if defined (REG_RDATA_T) && defined (REG_SDATA_T) && defined (REG_SBSS_T) /*mips*/
3537 case REG_RDATA_T: region = ", .rdata"; break;
3538 case REG_SDATA_T: region = ", .sdata"; break;
3539 case REG_SBSS_T: region = ", .sbss"; break;
3540 #endif
3541 }
3542
3543 fprintf (stderr, ", ty: %s, vaddr: 0x%.8lx, vlen: 0x%.6lx%s\n",
3544 type_str,
3545 (long) load_hdr->region.regc_vm_addr,
3546 (long) load_hdr->region.regc_vm_size,
3547 region);
3548 }
3549
3550 return;
3551 }
3552
3553 \f
3554 /* Fatal error when {en,de}code_mach_o_header fails. */
3555
3556 static void
3557 bad_header (status)
3558 int status;
3559 {
3560 switch (status)
3561 {
3562 case MO_ERROR_BAD_MAGIC: fatal ("bad magic number");
3563 case MO_ERROR_BAD_HDR_VERS: fatal ("bad header version");
3564 case MO_ERROR_BAD_RAW_HDR_VERS: fatal ("bad raw header version");
3565 case MO_ERROR_BUF2SML: fatal ("raw header buffer too small");
3566 case MO_ERROR_OLD_RAW_HDR_FILE: fatal ("old raw header file");
3567 case MO_ERROR_UNSUPPORTED_VERS: fatal ("unsupported version");
3568 default:
3569 fatal ("unknown {de,en}code_mach_o_hdr return value %d", status);
3570 }
3571 }
3572
3573 \f
3574 /* Read a file into a memory buffer. */
3575
3576 static struct file_info *
3577 read_file (name, fd, rw)
3578 const char *name; /* filename */
3579 int fd; /* file descriptor */
3580 int rw; /* read/write */
3581 {
3582 struct stat stat_pkt;
3583 struct file_info *p = (struct file_info *) xcalloc (sizeof (struct file_info), 1);
3584 #ifdef USE_MMAP
3585 static int page_size;
3586 #endif
3587
3588 if (fstat (fd, &stat_pkt) < 0)
3589 fatal_perror ("fstat %s", name);
3590
3591 p->name = name;
3592 p->size = stat_pkt.st_size;
3593 p->rounded_size = stat_pkt.st_size;
3594 p->fd = fd;
3595 p->rw = rw;
3596
3597 #ifdef USE_MMAP
3598 if (debug)
3599 fprintf (stderr, "mmap %s, %s\n", name, (rw) ? "read/write" : "read-only");
3600
3601 if (page_size == 0)
3602 page_size = sysconf (_SC_PAGE_SIZE);
3603
3604 p->rounded_size = ((p->size + page_size - 1) / page_size) * page_size;
3605 p->start = mmap ((caddr_t) 0,
3606 (rw) ? p->rounded_size : p->size,
3607 (rw) ? (PROT_READ | PROT_WRITE) : PROT_READ,
3608 MAP_FILE | MAP_VARIABLE | MAP_SHARED,
3609 fd,
3610 0L);
3611
3612 if (p->start != (char *) 0 && p->start != (char *) -1)
3613 p->use_mmap = 1;
3614
3615 else
3616 #endif /* USE_MMAP */
3617 {
3618 long len;
3619
3620 if (debug)
3621 fprintf (stderr, "read %s\n", name);
3622
3623 p->use_mmap = 0;
3624 p->start = xmalloc (p->size);
3625 if (lseek (fd, 0L, SEEK_SET) < 0)
3626 fatal_perror ("lseek %s 0", name);
3627
3628 len = read (fd, p->start, p->size);
3629 if (len < 0)
3630 fatal_perror ("read %s", name);
3631
3632 if (len != p->size)
3633 fatal ("read %ld bytes, expected %ld, from %s", len, p->size, name);
3634 }
3635
3636 return p;
3637 }
3638 \f
3639 /* Do anything necessary to write a file back from memory. */
3640
3641 static void
3642 end_file (ptr)
3643 struct file_info *ptr; /* file information block */
3644 {
3645 #ifdef USE_MMAP
3646 if (ptr->use_mmap)
3647 {
3648 if (ptr->rw)
3649 {
3650 if (debug)
3651 fprintf (stderr, "msync %s\n", ptr->name);
3652
3653 if (msync (ptr->start, ptr->rounded_size, MS_ASYNC))
3654 fatal_perror ("msync %s", ptr->name);
3655 }
3656
3657 if (debug)
3658 fprintf (stderr, "munmap %s\n", ptr->name);
3659
3660 if (munmap (ptr->start, ptr->size))
3661 fatal_perror ("munmap %s", ptr->name);
3662 }
3663 else
3664 #endif /* USE_MMAP */
3665 {
3666 if (ptr->rw)
3667 {
3668 long len;
3669
3670 if (debug)
3671 fprintf (stderr, "write %s\n", ptr->name);
3672
3673 if (lseek (ptr->fd, 0L, SEEK_SET) < 0)
3674 fatal_perror ("lseek %s 0", ptr->name);
3675
3676 len = write (ptr->fd, ptr->start, ptr->size);
3677 if (len < 0)
3678 fatal_perror ("write %s", ptr->name);
3679
3680 if (len != ptr->size)
3681 fatal ("wrote %ld bytes, expected %ld, to %s", len, ptr->size, ptr->name);
3682 }
3683
3684 free (ptr->start);
3685 }
3686
3687 free (ptr);
3688 }
3689
3690 #endif /* OBJECT_FORMAT_ROSE */