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