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