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