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