]> gcc.gnu.org Git - gcc.git/blame - gcc/collect2.c
(bytecode.realclean): Don't delete bi-lexer.c.
[gcc.git] / gcc / collect2.c
CommitLineData
4e81a331
RS
1/* Collect static initialization info into data structures
2 that can be traversed by C++ initialization and finalization
3 routines.
4
4d1a011f 5 Copyright (C) 1992, 1993 Free Software Foundation, Inc.
4e81a331
RS
6 Contributed by Chris Smith (csmith@convex.com).
7 Heavily modified by Michael Meissner (meissner@osf.org),
8 Per Bothner (bothner@cygnus.com), and John Gilmore (gnu@cygnus.com).
9
10This file is part of GNU CC.
11
12GNU CC is free software; you can redistribute it and/or modify
13it under the terms of the GNU General Public License as published by
14the Free Software Foundation; either version 2, or (at your option)
15any later version.
16
17GNU CC is distributed in the hope that it will be useful,
18but WITHOUT ANY WARRANTY; without even the implied warranty of
19MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20GNU General Public License for more details.
21
22You should have received a copy of the GNU General Public License
23along with GNU CC; see the file COPYING. If not, write to
24the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
25
26
27/* Build tables of static constructors and destructors and run ld. */
28
29#include <sys/types.h>
30#include <stdio.h>
4e81a331 31#include <ctype.h>
4e81a331
RS
32#include <errno.h>
33#include <signal.h>
34#include <sys/file.h>
35#include <sys/stat.h>
e6701a47 36#ifdef NO_WAIT_H
4e81a331 37#include <sys/wait.h>
e6701a47 38#endif
4e81a331 39
ed5b9462
RS
40#ifndef errno
41extern int errno;
42#endif
43
4e81a331
RS
44#define COLLECT
45
46#include "config.h"
47
48#ifndef __STDC__
4e81a331 49#define generic char
4e81a331
RS
50#define const
51
52#else
4e81a331 53#define generic void
4e81a331
RS
54#endif
55
ed5b9462
RS
56#ifdef USG
57#define vfork fork
58#endif
59
4d1a011f
RK
60/* Add prototype support. */
61#ifndef PROTO
62#if defined (USE_PROTOTYPES) ? USE_PROTOTYPES : defined (__STDC__)
63#define PROTO(ARGS) ARGS
64#else
65#define PROTO(ARGS) ()
66#endif
67#endif
68
ed5b9462
RS
69#ifndef R_OK
70#define R_OK 4
71#define W_OK 2
72#define X_OK 1
73#endif
74
75/* On MSDOS, write temp files in current dir
76 because there's no place else we can expect to use. */
77#if __MSDOS__
78#ifndef P_tmpdir
79#define P_tmpdir "./"
80#endif
81#endif
82\f
83/* On certain systems, we have code that works by scanning the object file
84 directly. But this code uses system-specific header files and library
bb59f9a6
RS
85 functions, so turn it off in a cross-compiler. Likewise, the names of
86 the utilities aren't correct for a cross-compiler; we have to hope that
87 cross-versions are in the proper directories. */
ed5b9462
RS
88
89#ifdef CROSS_COMPILE
90#undef OBJECT_FORMAT_COFF
91#undef OBJECT_FORMAT_ROSE
bb59f9a6
RS
92#undef MD_EXEC_PREFIX
93#undef REAL_LD_FILE_NAME
94#undef REAL_NM_FILE_NAME
95#undef REAL_STRIP_FILE_NAME
ed5b9462
RS
96#endif
97
98/* If we can't use a special method, use the ordinary one:
99 run nm to find what symbols are present.
100 In a cross-compiler, this means you need a cross nm,
101 but that isn't quite as unpleasant as special headers. */
102
103#if !defined (OBJECT_FORMAT_COFF) && !defined (OBJECT_FORMAT_ROSE)
104#define OBJECT_FORMAT_NONE
105#endif
106
107#ifdef OBJECT_FORMAT_COFF
108
109#include <a.out.h>
110#include <ar.h>
111
112#ifdef UMAX
113#include <sgs.h>
114#endif
115
033ba47c
RS
116/* Many versions of ldfcn.h define these. */
117#ifdef FREAD
ed5b9462
RS
118#undef FREAD
119#undef FWRITE
120#endif
121
122#include <ldfcn.h>
123
7243ba7d
RK
124/* Some systems have an ISCOFF macro, but others do not. In some cases
125 the macro may be wrong. MY_ISCOFF is defined in tm.h files for machines
126 that either do not have an ISCOFF macro in /usr/include or for those
127 where it is wrong. */
128
e99467d2
RS
129#ifndef MY_ISCOFF
130#define MY_ISCOFF(X) ISCOFF (X)
131#endif
132
ed5b9462
RS
133#endif /* OBJECT_FORMAT_COFF */
134
4e81a331
RS
135#ifdef OBJECT_FORMAT_ROSE
136
137#ifdef _OSF_SOURCE
138#define USE_MMAP
139#endif
140
141#ifdef USE_MMAP
142#include <sys/mman.h>
143#endif
144
145#include <unistd.h>
146#include <mach_o_format.h>
147#include <mach_o_header.h>
148#include <mach_o_vals.h>
149#include <mach_o_types.h>
ed5b9462 150
4e81a331
RS
151#endif /* OBJECT_FORMAT_ROSE */
152
ed5b9462
RS
153#ifdef OBJECT_FORMAT_NONE
154
4e81a331
RS
155/* Default flags to pass to nm. */
156#ifndef NM_FLAGS
157#define NM_FLAGS "-p"
158#endif
159
ed5b9462 160#endif /* OBJECT_FORMAT_NONE */
d6cf3187
RS
161
162/* Some systems use __main in a way incompatible with its use in gcc, in these
163 cases use the macros NAME__MAIN to give a quoted symbol and SYMBOL__MAIN to
164 give the same symbol without quotes for an alternative entry point. You
165 must define both, or niether. */
166#ifndef NAME__MAIN
167#define NAME__MAIN "__main"
168#define SYMBOL__MAIN __main
169#endif
170
4e81a331
RS
171\f
172/* Linked lists of constructor and destructor names. */
173
174struct id
175{
176 struct id *next;
177 int sequence;
178 char name[1];
179};
180
181struct head
182{
183 struct id *first;
184 struct id *last;
185 int number;
186};
187
188/* Enumeration giving which pass this is for scanning the program file. */
189
190enum pass {
191 PASS_FIRST, /* without constructors */
192 PASS_SECOND /* with constructors linked in */
193};
194
ed5b9462 195#ifndef NO_SYS_SIGLIST
4e81a331 196extern char *sys_siglist[];
ed5b9462 197#endif
4e81a331
RS
198extern char *version_string;
199
200static int vflag; /* true if -v */
201static int rflag; /* true if -r */
a87104d9 202static int strip_flag; /* true if -s */
4e81a331
RS
203
204static int debug; /* true if -debug */
205
206static int temp_filename_length; /* Length of temp_filename */
207static char *temp_filename; /* Base of temp filenames */
208static char *c_file; /* <xxx>.c for constructor/destructor list. */
209static char *o_file; /* <xxx>.o for constructor/destructor list. */
0cdd3ddd 210static char *output_file; /* Output file for ld. */
4e81a331 211static char *nm_file_name; /* pathname of nm */
a87104d9 212static char *strip_file_name; /* pathname of strip */
4e81a331
RS
213
214static struct head constructors; /* list of constructors found */
215static struct head destructors; /* list of destructors found */
216
ed5b9462
RS
217extern char *getenv ();
218extern char *mktemp ();
4d1a011f
RK
219extern FILE *fdopen ();
220
221/* Structure to hold all the directories in which to search for files to
222 execute. */
223
224struct prefix_list
225{
226 char *prefix; /* String to prepend to the path. */
227 struct prefix_list *next; /* Next in linked list. */
228};
229
230struct path_prefix
231{
232 struct prefix_list *plist; /* List of prefixes to try */
233 int max_len; /* Max length of a prefix in PLIST */
234 char *name; /* Name of this list (used in config stuff) */
235};
236
237static void my_exit PROTO((int));
238static void handler PROTO((int));
239static int is_ctor_dtor PROTO((char *));
240static void choose_temp_base PROTO((void));
241static int is_in_prefix_list PROTO((struct path_prefix *, char *, int));
242static char *find_a_file PROTO((struct path_prefix *, char *));
243static void add_prefix PROTO((struct path_prefix *, char *));
244static void prefix_from_env PROTO((char *, struct path_prefix *));
245static void do_wait PROTO((char *));
246static void fork_execute PROTO((char *, char **));
247static void maybe_unlink PROTO((char *));
248static void add_to_list PROTO((struct head *, char *));
249static void write_list PROTO((FILE *, char *, struct id *));
250static void write_list_with_asm PROTO((FILE *, char *, struct id *));
251static void write_c_file PROTO((FILE *, char *));
252static void scan_prog_file PROTO((char *, enum pass));
ed5b9462
RS
253
254generic *xcalloc ();
255generic *xmalloc ();
3f7cc57a
MS
256
257extern char *index ();
258extern char *rindex ();
4e81a331 259\f
f28e8a68 260#ifdef NO_DUP2
4d1a011f 261int
f28e8a68
RS
262dup2 (oldfd, newfd)
263 int oldfd;
264 int newfd;
265{
266 int fdtmp[256];
267 int fdx = 0;
268 int fd;
269
270 if (oldfd == newfd)
271 return 0;
272 close (newfd);
273 while ((fd = dup (oldfd)) != newfd) /* good enough for low fd's */
274 fdtmp[fdx++] = fd;
275 while (fdx > 0)
276 close (fdtmp[--fdx]);
4d1a011f
RK
277
278 return 0;
f28e8a68
RS
279}
280#endif
281
ed5b9462 282char *
1fab8e81 283my_strerror (e)
4e81a331
RS
284 int e;
285{
286 extern char *sys_errlist[];
287 extern int sys_nerr;
288 static char buffer[30];
289
290 if (!e)
291 return "";
292
293 if (e > 0 && e < sys_nerr)
294 return sys_errlist[e];
295
296 sprintf (buffer, "Unknown error %d", e);
297 return buffer;
298}
4e81a331
RS
299\f
300/* Delete tempfiles and exit function. */
301
302static void
303my_exit (status)
304 int status;
305{
ed5b9462 306 if (c_file != 0 && c_file[0])
4e81a331
RS
307 maybe_unlink (c_file);
308
ed5b9462 309 if (o_file != 0 && o_file[0])
4e81a331
RS
310 maybe_unlink (o_file);
311
0cdd3ddd
RS
312 if (status != 0 && output_file != 0 && output_file[0])
313 maybe_unlink (output_file);
314
4e81a331
RS
315 exit (status);
316}
317
318\f
4e81a331
RS
319/* Die when sys call fails. */
320
4e81a331 321static void
1fab8e81
RS
322fatal_perror (string, arg1, arg2, arg3)
323 char *string;
4e81a331 324{
4e81a331
RS
325 int e = errno;
326
626e18ea 327 fprintf (stderr, "collect2: ");
1fab8e81
RS
328 fprintf (stderr, string, arg1, arg2, arg3);
329 fprintf (stderr, ": %s\n", my_strerror (e));
4e81a331
RS
330 my_exit (1);
331}
332
333/* Just die. */
334
4e81a331 335static void
1fab8e81
RS
336fatal (string, arg1, arg2, arg3)
337 char *string;
4e81a331 338{
626e18ea 339 fprintf (stderr, "collect2: ");
1fab8e81 340 fprintf (stderr, string, arg1, arg2, arg3);
4e81a331 341 fprintf (stderr, "\n");
4e81a331
RS
342 my_exit (1);
343}
344
345/* Write error message. */
346
4e81a331 347static void
1fab8e81
RS
348error (string, arg1, arg2, arg3, arg4)
349 char *string;
4e81a331 350{
626e18ea 351 fprintf (stderr, "collect2: ");
1fab8e81 352 fprintf (stderr, string, arg1, arg2, arg3, arg4);
4e81a331 353 fprintf (stderr, "\n");
4e81a331
RS
354}
355
4e81a331
RS
356/* In case obstack is linked in, and abort is defined to fancy_abort,
357 provide a default entry. */
358
359void
360fancy_abort ()
361{
362 fatal ("internal error");
363}
364
365\f
366static void
367handler (signo)
368 int signo;
369{
b31a1e3f 370 if (c_file != 0 && c_file[0])
4e81a331
RS
371 maybe_unlink (c_file);
372
b31a1e3f 373 if (o_file != 0 && o_file[0])
4e81a331
RS
374 maybe_unlink (o_file);
375
376 signal (signo, SIG_DFL);
4e81a331
RS
377 kill (getpid (), signo);
378}
379
380\f
381generic *
382xcalloc (size1, size2)
ed5b9462 383 int size1, size2;
4e81a331 384{
ed5b9462 385 generic *ptr = (generic *) calloc (size1, size2);
4e81a331
RS
386 if (ptr)
387 return ptr;
388
1fab8e81 389 fatal ("out of memory");
4e81a331
RS
390 return (generic *)0;
391}
392
393generic *
394xmalloc (size)
ed5b9462 395 int size;
4e81a331 396{
ed5b9462 397 generic *ptr = (generic *) malloc (size);
4e81a331
RS
398 if (ptr)
399 return ptr;
400
1fab8e81 401 fatal ("out of memory");
4e81a331
RS
402 return (generic *)0;
403}
404
ed5b9462
RS
405/* Make a copy of a string INPUT with size SIZE. */
406
407char *
408savestring (input, size)
409 char *input;
410 int size;
411{
412 char *output = (char *) xmalloc (size + 1);
1fab8e81
RS
413 bcopy (input, output, size);
414 output[size] = 0;
ed5b9462
RS
415 return output;
416}
417\f
418/* Decide whether the given symbol is:
419 a constructor (1), a destructor (2), or neither (0). */
420
421static int
422is_ctor_dtor (s)
423 char *s;
424{
425 struct names { char *name; int len; int ret; int two_underscores; };
426
427 register struct names *p;
428 register int ch;
429 register char *orig_s = s;
430
431 static struct names special[] = {
432#ifdef NO_DOLLAR_IN_LABEL
7cbfceab 433#ifdef NO_DOT_IN_LABEL
c52d2678
RS
434 { "GLOBAL__I_", sizeof ("GLOBAL__I_")-1, 1, 0 },
435 { "GLOBAL__D_", sizeof ("GLOBAL__D_")-1, 2, 0 },
7cbfceab 436#else
ed5b9462
RS
437 { "GLOBAL_.I.", sizeof ("GLOBAL_.I.")-1, 1, 0 },
438 { "GLOBAL_.D.", sizeof ("GLOBAL_.D.")-1, 2, 0 },
7cbfceab 439#endif
ed5b9462
RS
440#else
441 { "GLOBAL_$I$", sizeof ("GLOBAL_$I$")-1, 1, 0 },
5555d6d1 442 { "GLOBAL_$D$", sizeof ("GLOBAL_$D$")-1, 2, 0 },
ed5b9462 443#endif
c1af0346
RS
444#ifdef CFRONT_LOSSAGE /* Don't collect cfront initialization functions.
445 cfront has its own linker procedure to collect them;
446 if collect2 gets them too, they get collected twice
447 when the cfront procedure is run and the compiler used
448 for linking happens to be GCC. */
ed5b9462
RS
449 { "sti__", sizeof ("sti__")-1, 1, 1 },
450 { "std__", sizeof ("std__")-1, 2, 1 },
7a646ee5 451#endif /* CFRONT_LOSSAGE */
ed5b9462
RS
452 { NULL, 0, 0, 0 }
453 };
454
455 while ((ch = *s) == '_')
456 ++s;
457
458 if (s == orig_s)
459 return 0;
460
461 for (p = &special[0]; p->len > 0; p++)
462 {
463 if (ch == p->name[0]
464 && (!p->two_underscores || ((s - orig_s) >= 2))
465 && strncmp(s, p->name, p->len) == 0)
466 {
467 return p->ret;
468 }
469 }
470 return 0;
471}
472
4e81a331
RS
473\f
474/* Compute a string to use as the base of all temporary file names.
475 It is substituted for %g. */
476
477static void
ed5b9462 478choose_temp_base ()
4e81a331
RS
479{
480 char *base = getenv ("TMPDIR");
481 int len;
482
483 if (base == (char *)0)
484 {
485#ifdef P_tmpdir
486 if (access (P_tmpdir, R_OK | W_OK) == 0)
487 base = P_tmpdir;
488#endif
489 if (base == (char *)0)
490 {
491 if (access ("/usr/tmp", R_OK | W_OK) == 0)
492 base = "/usr/tmp/";
493 else
494 base = "/tmp/";
495 }
496 }
497
498 len = strlen (base);
aee42e27 499 temp_filename = xmalloc (len + sizeof("/ccXXXXXX") + 1);
4e81a331
RS
500 strcpy (temp_filename, base);
501 if (len > 0 && temp_filename[len-1] != '/')
502 temp_filename[len++] = '/';
503 strcpy (temp_filename + len, "ccXXXXXX");
504
505 mktemp (temp_filename);
506 temp_filename_length = strlen (temp_filename);
507}
bb59f9a6 508\f
45840c57
RK
509/* Routine to add variables to the environment. */
510
511#ifndef HAVE_PUTENV
512
4d1a011f 513int
45840c57
RK
514putenv (str)
515 char *str;
516{
517#ifndef VMS /* nor about VMS */
518
519 extern char **environ;
520 char **old_environ = environ;
521 char **envp;
522 int num_envs = 0;
523 int name_len = 1;
524 int str_len = strlen (str);
525 char *p = str;
526 int ch;
527
528 while ((ch = *p++) != '\0' && ch != '=')
529 name_len++;
530
531 if (!ch)
532 abort ();
533
534 /* Search for replacing an existing environment variable, and
535 count the number of total environment variables. */
536 for (envp = old_environ; *envp; envp++)
537 {
538 num_envs++;
539 if (!strncmp (str, *envp, name_len))
540 {
541 *envp = str;
4d1a011f 542 return 0;
45840c57
RK
543 }
544 }
545
546 /* Add a new environment variable */
547 environ = (char **) xmalloc (sizeof (char *) * (num_envs+2));
548 *environ = str;
549 bcopy (old_environ, environ+1, sizeof (char *) * (num_envs+1));
4d1a011f 550 return 0;
45840c57
RK
551#endif /* VMS */
552}
553
554#endif /* HAVE_PUTENV */
555\f
bb59f9a6
RS
556/* By default, colon separates directories in a path. */
557#ifndef PATH_SEPARATOR
558#define PATH_SEPARATOR ':'
559#endif
560
bb59f9a6
RS
561/* We maintain two prefix lists: one from COMPILER_PATH environment variable
562 and one from the PATH variable. */
563
564static struct path_prefix cpath, path;
565
566#ifdef CROSS_COMPILE
567/* This is the name of the target machine. We use it to form the name
568 of the files to execute. */
569
570static char *target_machine = TARGET_MACHINE;
571#endif
720653a3 572
45840c57 573/* Names under which we were executed. Never return one of those files in our
720653a3
RK
574 searches. */
575
7223feb0 576static struct path_prefix our_file_names;
bb59f9a6 577\f
7223feb0
DE
578/* Determine if STRING is in PPREFIX.
579
580 This utility is currently only used to look up file names. Prefix lists
581 record directory names. This matters to us because the latter has a
582 trailing slash, so I've added a flag to handle both. */
583
584static int
585is_in_prefix_list (pprefix, string, filep)
586 struct path_prefix *pprefix;
587 char *string;
588 int filep;
589{
590 struct prefix_list *pl;
591
592 if (filep)
593 {
594 int len = strlen (string);
595
596 for (pl = pprefix->plist; pl; pl = pl->next)
597 {
598 if (strncmp (pl->prefix, string, len) == 0
599 && strcmp (pl->prefix + len, "/") == 0)
600 return 1;
601 }
602 }
603 else
604 {
605 for (pl = pprefix->plist; pl; pl = pl->next)
606 {
607 if (strcmp (pl->prefix, string) == 0)
608 return 1;
609 }
610 }
611
612 return 0;
613}
614
bb59f9a6
RS
615/* Search for NAME using prefix list PPREFIX. We only look for executable
616 files.
617
618 Return 0 if not found, otherwise return its name, allocated with malloc. */
619
620static char *
621find_a_file (pprefix, name)
622 struct path_prefix *pprefix;
623 char *name;
624{
625 char *temp;
626 struct prefix_list *pl;
627 int len = pprefix->max_len + strlen (name) + 1;
628
629#ifdef EXECUTABLE_SUFFIX
630 len += strlen (EXECUTABLE_SUFFIX);
631#endif
632
633 temp = xmalloc (len);
634
635 /* Determine the filename to execute (special case for absolute paths). */
636
637 if (*name == '/')
638 {
e8fda1f9 639 if (access (name, X_OK) == 0)
bb59f9a6
RS
640 {
641 strcpy (temp, name);
642 return temp;
643 }
644 }
645 else
646 for (pl = pprefix->plist; pl; pl = pl->next)
647 {
648 strcpy (temp, pl->prefix);
649 strcat (temp, name);
7223feb0 650 if (! is_in_prefix_list (&our_file_names, temp, 1)
aee3a549
RK
651 /* This is a kludge, but there seems no way around it. */
652 && strcmp (temp, "./ld") != 0
45840c57 653 && access (temp, X_OK) == 0)
bb59f9a6
RS
654 return temp;
655
656#ifdef EXECUTABLE_SUFFIX
657 /* Some systems have a suffix for executable files.
658 So try appending that. */
659 strcat (temp, EXECUTABLE_SUFFIX);
7223feb0 660 if (! is_in_prefix_list (&our_file_names, temp, 1)
45840c57 661 && access (temp, X_OK) == 0)
bb59f9a6
RS
662 return temp;
663#endif
664 }
665
666 free (temp);
667 return 0;
668}
669
670/* Add an entry for PREFIX to prefix list PPREFIX. */
671
672static void
673add_prefix (pprefix, prefix)
674 struct path_prefix *pprefix;
675 char *prefix;
676{
677 struct prefix_list *pl, **prev;
678 int len;
679
680 if (pprefix->plist)
681 {
682 for (pl = pprefix->plist; pl->next; pl = pl->next)
683 ;
684 prev = &pl->next;
685 }
686 else
687 prev = &pprefix->plist;
688
689 /* Keep track of the longest prefix */
690
691 len = strlen (prefix);
692 if (len > pprefix->max_len)
693 pprefix->max_len = len;
694
695 pl = (struct prefix_list *) xmalloc (sizeof (struct prefix_list));
696 pl->prefix = savestring (prefix, len);
697
698 if (*prev)
699 pl->next = *prev;
700 else
701 pl->next = (struct prefix_list *) 0;
702 *prev = pl;
703}
704\f
705/* Take the value of the environment variable ENV, break it into a path, and
706 add of the entries to PPREFIX. */
707
708static void
709prefix_from_env (env, pprefix)
710 char *env;
711 struct path_prefix *pprefix;
712{
713 char *p = getenv (env);
714
715 if (p)
716 {
717 char *startp, *endp;
718 char *nstore = (char *) xmalloc (strlen (p) + 3);
719
720 startp = endp = p;
721 while (1)
722 {
723 if (*endp == PATH_SEPARATOR || *endp == 0)
724 {
725 strncpy (nstore, startp, endp-startp);
726 if (endp == startp)
727 {
728 strcpy (nstore, "./");
729 }
730 else if (endp[-1] != '/')
731 {
732 nstore[endp-startp] = '/';
733 nstore[endp-startp+1] = 0;
734 }
735 else
736 nstore[endp-startp] = 0;
4e81a331 737
bb59f9a6
RS
738 add_prefix (pprefix, nstore);
739 if (*endp == 0)
740 break;
741 endp = startp = endp + 1;
742 }
743 else
744 endp++;
745 }
746 }
747}
4e81a331
RS
748\f
749/* Main program. */
750
751int
752main (argc, argv)
753 int argc;
754 char *argv[];
755{
bb59f9a6
RS
756 char *ld_suffix = "ld";
757 char *full_ld_suffix = ld_suffix;
758 char *real_ld_suffix = "real-ld";
e8fda1f9 759 char *full_real_ld_suffix = real_ld_suffix;
98552524 760#if 0
bb59f9a6
RS
761 char *gld_suffix = "gld";
762 char *full_gld_suffix = gld_suffix;
98552524 763#endif
bb59f9a6
RS
764 char *nm_suffix = "nm";
765 char *full_nm_suffix = nm_suffix;
766 char *gnm_suffix = "gnm";
767 char *full_gnm_suffix = gnm_suffix;
768 char *strip_suffix = "strip";
769 char *full_strip_suffix = strip_suffix;
770 char *gstrip_suffix = "gstrip";
771 char *full_gstrip_suffix = gstrip_suffix;
4e81a331
RS
772 char *arg;
773 FILE *outf;
774 char *ld_file_name;
775 char *c_file_name;
588e387f 776 char *collect_name;
7223feb0 777 char *collect_names;
4e81a331 778 char *p;
ed5b9462
RS
779 char **c_argv;
780 char **c_ptr;
4e81a331
RS
781 char **ld1_argv = (char **) xcalloc (sizeof (char *), argc+2);
782 char **ld1 = ld1_argv;
783 char **ld2_argv = (char **) xcalloc (sizeof (char *), argc+5);
784 char **ld2 = ld2_argv;
785 int first_file;
ed5b9462 786 int num_c_args = argc+7;
4e81a331
RS
787 int len;
788 int clen;
789
790#ifdef DEBUG
791 debug = 1;
792 vflag = 1;
793#endif
794
0cdd3ddd
RS
795 output_file = "a.out";
796
45840c57 797 /* We must check that we do not call ourselves in an infinite
588e387f
DE
798 recursion loop. We append the name used for us to the COLLECT_NAMES
799 environment variable.
45840c57 800
7223feb0
DE
801 In practice, collect will rarely invoke itself. This can happen now
802 that we are no longer called gld. A perfect example is when running
803 gcc in a build directory that has been installed. When looking for
804 ld's, we'll find our installed version and believe that's the real ld. */
45840c57 805
588e387f
DE
806 /* We must also append COLLECT_NAME to COLLECT_NAMES to watch for the
807 previous version of collect (the one that used COLLECT_NAME and only
808 handled two levels of recursion). If we don't we may mutually recurse
809 forever. This can happen (I think) when bootstrapping the old version
810 and a new one is installed (rare, but we should handle it).
811 ??? Hopefully references to COLLECT_NAME can be removed at some point. */
812
813 collect_name = (char *) getenv ("COLLECT_NAME");
7223feb0 814 collect_names = (char *) getenv ("COLLECT_NAMES");
45840c57 815
7223feb0 816 p = (char *) xmalloc (strlen ("COLLECT_NAMES=")
588e387f 817 + (collect_name ? strlen (collect_name) + 1 : 0)
7223feb0
DE
818 + (collect_names ? strlen (collect_names) + 1 : 0)
819 + strlen (argv[0]) + 1);
588e387f
DE
820 strcpy (p, "COLLECT_NAMES=");
821 if (collect_name != 0)
822 sprintf (p + strlen (p), "%s%c", collect_name, PATH_SEPARATOR);
7223feb0 823 if (collect_names != 0)
588e387f
DE
824 sprintf (p + strlen (p), "%s%c", collect_names, PATH_SEPARATOR);
825 strcat (p, argv[0]);
45840c57
RK
826 putenv (p);
827
7223feb0
DE
828 prefix_from_env ("COLLECT_NAMES", &our_file_names);
829
588e387f
DE
830 /* Set environment variable COLLECT_NAME to our name so the previous version
831 of collect won't find us. If it does we'll mutually recurse forever.
832 This can happen when bootstrapping the new version and an old version is
833 installed.
834 ??? Hopefully this bit of code can be removed at some point. */
835
836 p = xmalloc (strlen ("COLLECT_NAME=") + strlen (argv[0]) + 1);
837 sprintf (p, "COLLECT_NAME=%s", argv[0]);
838 putenv (p);
839
ed5b9462
RS
840 p = (char *) getenv ("COLLECT_GCC_OPTIONS");
841 if (p)
842 while (*p)
843 {
844 char *q = p;
845 while (*q && *q != ' ') q++;
17704846 846 if (*p == '-' && p[1] == 'm')
ed5b9462
RS
847 num_c_args++;
848
849 if (*q) q++;
850 p = q;
851 }
852
853 c_ptr = c_argv = (char **) xcalloc (sizeof (char *), num_c_args);
854
4e81a331
RS
855 if (argc < 2)
856 fatal ("no arguments");
857
8ab861c7 858#ifdef SIGQUIT
915ee623
JW
859 if (signal (SIGQUIT, SIG_IGN) != SIG_IGN)
860 signal (SIGQUIT, handler);
8ab861c7 861#endif
915ee623
JW
862 if (signal (SIGINT, SIG_IGN) != SIG_IGN)
863 signal (SIGINT, handler);
8ab861c7 864#ifdef SIGALRM
915ee623
JW
865 if (signal (SIGALRM, SIG_IGN) != SIG_IGN)
866 signal (SIGALRM, handler);
8ab861c7
RK
867#endif
868#ifdef SIGHUP
915ee623
JW
869 if (signal (SIGHUP, SIG_IGN) != SIG_IGN)
870 signal (SIGHUP, handler);
8ab861c7 871#endif
915ee623
JW
872 if (signal (SIGSEGV, SIG_IGN) != SIG_IGN)
873 signal (SIGSEGV, handler);
8ab861c7 874#ifdef SIGBUS
915ee623
JW
875 if (signal (SIGBUS, SIG_IGN) != SIG_IGN)
876 signal (SIGBUS, handler);
8ab861c7 877#endif
4e81a331 878
bb59f9a6
RS
879 /* Extract COMPILER_PATH and PATH into our prefix list. */
880 prefix_from_env ("COMPILER_PATH", &cpath);
881 prefix_from_env ("PATH", &path);
4e81a331 882
bb59f9a6
RS
883#ifdef CROSS_COMPILE
884 /* If we look for a program in the compiler directories, we just use
885 the short name, since these directories are already system-specific.
886 But it we look for a took in the system directories, we need to
887 qualify the program name with the target machine. */
888
889 full_ld_suffix
aee42e27 890 = xcalloc (strlen (ld_suffix) + strlen (target_machine) + 2, 1);
46c74083 891 strcpy (full_ld_suffix, target_machine);
bb59f9a6 892 strcat (full_ld_suffix, "-");
46c74083 893 strcat (full_ld_suffix, ld_suffix);
bb59f9a6
RS
894
895 full_real_ld_suffix
aee42e27 896 = xcalloc (strlen (real_ld_suffix) + strlen (target_machine) + 2, 1);
46c74083 897 strcpy (full_real_ld_suffix, target_machine);
bb59f9a6 898 strcat (full_real_ld_suffix, "-");
46c74083 899 strcat (full_real_ld_suffix, real_ld_suffix);
bb59f9a6 900
98552524 901#if 0
bb59f9a6 902 full_gld_suffix
aee42e27 903 = xcalloc (strlen (gld_suffix) + strlen (target_machine) + 2, 1);
46c74083 904 strcpy (full_gld_suffix, target_machine);
bb59f9a6 905 strcat (full_gld_suffix, "-");
46c74083 906 strcat (full_gld_suffix, gld_suffix);
98552524 907#endif
bb59f9a6
RS
908
909 full_nm_suffix
aee42e27 910 = xcalloc (strlen (nm_suffix) + strlen (target_machine) + 2, 1);
46c74083 911 strcpy (full_nm_suffix, target_machine);
bb59f9a6 912 strcat (full_nm_suffix, "-");
46c74083 913 strcat (full_nm_suffix, nm_suffix);
bb59f9a6
RS
914
915 full_gnm_suffix
aee42e27 916 = xcalloc (strlen (gnm_suffix) + strlen (target_machine) + 2, 1);
46c74083 917 strcpy (full_gnm_suffix, target_machine);
bb59f9a6 918 strcat (full_gnm_suffix, "-");
46c74083 919 strcat (full_gnm_suffix, gnm_suffix);
bb59f9a6
RS
920
921 full_strip_suffix
aee42e27 922 = xcalloc (strlen (strip_suffix) + strlen (target_machine) + 2, 1);
46c74083 923 strcpy (full_strip_suffix, target_machine);
bb59f9a6 924 strcat (full_strip_suffix, "-");
46c74083 925 strcat (full_strip_suffix, strip_suffix);
bb59f9a6
RS
926
927 full_gstrip_suffix
aee42e27 928 = xcalloc (strlen (gstrip_suffix) + strlen (target_machine) + 2, 1);
46c74083 929 strcpy (full_gstrip_suffix, target_machine);
bb59f9a6 930 strcat (full_gstrip_suffix, "-");
46c74083 931 strcat (full_gstrip_suffix, gstrip_suffix);
bb59f9a6
RS
932#endif /* CROSS_COMPILE */
933
934 /* Try to discover a valid linker/nm/strip to use. */
935
98552524 936#if 0
bb59f9a6
RS
937 /* Search the (target-specific) compiler dirs for `gld'. */
938 ld_file_name = find_a_file (&cpath, gld_suffix);
939 /* Search the ordinary system bin directories
46c74083 940 for `gld' (if native linking) or `TARGET-gld' (if cross). */
bb59f9a6
RS
941 if (ld_file_name == 0)
942 ld_file_name = find_a_file (&path, full_gld_suffix);
6c61ac77
DE
943#else
944 ld_file_name = 0;
98552524 945#endif
bb59f9a6
RS
946 /* Likewise for `real-ld'. */
947 if (ld_file_name == 0)
948 ld_file_name = find_a_file (&cpath, real_ld_suffix);
949 if (ld_file_name == 0)
950 ld_file_name = find_a_file (&path, full_real_ld_suffix);
951 /* Maybe we know the right file to use (if not cross). */
952#ifdef REAL_LD_FILE_NAME
953 if (ld_file_name == 0)
954 ld_file_name = find_a_file (&path, REAL_LD_FILE_NAME);
4e81a331 955#endif
f820b898
ILT
956 if (ld_file_name == 0)
957 ld_file_name = find_a_file (&cpath, full_ld_suffix);
bb59f9a6 958 /* Search the ordinary system bin directories
46c74083 959 for `ld' (if native linking) or `TARGET-ld' (if cross). */
bb59f9a6
RS
960 if (ld_file_name == 0)
961 ld_file_name = find_a_file (&path, full_ld_suffix);
962
7223feb0
DE
963 /* If we've invoked ourselves, try again with LD_FILE_NAME. */
964
965 if (collect_names != 0)
966 {
967 if (ld_file_name != 0)
968 {
969 argv[0] = ld_file_name;
970 execvp (argv[0], argv);
971 }
972 fatal ("cannot find `ld'");
973 }
974
bb59f9a6
RS
975 nm_file_name = find_a_file (&cpath, gnm_suffix);
976 if (nm_file_name == 0)
977 nm_file_name = find_a_file (&path, full_gnm_suffix);
978 if (nm_file_name == 0)
979 nm_file_name = find_a_file (&cpath, nm_suffix);
980#ifdef REAL_NM_FILE_NAME
981 if (nm_file_name == 0)
982 nm_file_name = find_a_file (&path, REAL_NM_FILE_NAME);
aaf625e5 983#endif
bb59f9a6
RS
984 if (nm_file_name == 0)
985 nm_file_name = find_a_file (&path, full_nm_suffix);
986
987 strip_file_name = find_a_file (&cpath, gstrip_suffix);
988 if (strip_file_name == 0)
989 strip_file_name = find_a_file (&path, full_gstrip_suffix);
990 if (strip_file_name == 0)
991 strip_file_name = find_a_file (&cpath, strip_suffix);
992#ifdef REAL_STRIP_FILE_NAME
993 if (strip_file_name == 0)
994 strip_file_name = find_a_file (&path, REAL_STRIP_FILE_NAME);
4e81a331 995#endif
bb59f9a6
RS
996 if (strip_file_name == 0)
997 strip_file_name = find_a_file (&path, full_strip_suffix);
4e81a331 998
a87104d9 999 /* Determine the full path name of the C compiler to use. */
ed5b9462 1000 c_file_name = getenv ("COLLECT_GCC");
5365d6ee 1001 if (c_file_name == 0)
4e81a331 1002 {
bb59f9a6 1003#ifdef CROSS_COMPILE
aee42e27 1004 c_file_name = xcalloc (sizeof ("gcc-") + strlen (target_machine) + 1, 1);
46c74083
RS
1005 strcpy (c_file_name, target_machine);
1006 strcat (c_file_name, "-gcc");
4e81a331 1007#else
bb59f9a6 1008 c_file_name = "gcc";
a87104d9 1009#endif
a87104d9
MM
1010 }
1011
bb59f9a6
RS
1012 p = find_a_file (&cpath, c_file_name);
1013
1014 /* Here it should be safe to use the system search path since we should have
1015 already qualified the name of the compiler when it is needed. */
1016 if (p == 0)
1017 p = find_a_file (&path, c_file_name);
1018
1019 if (p)
1020 c_file_name = p;
4e81a331 1021
45840c57 1022 *ld1++ = *ld2++ = ld_file_name;
4e81a331
RS
1023
1024 /* Make temp file names. */
1025 choose_temp_base ();
1026 c_file = xcalloc (temp_filename_length + sizeof (".c"), 1);
1027 o_file = xcalloc (temp_filename_length + sizeof (".o"), 1);
1028 sprintf (c_file, "%s.c", temp_filename);
1029 sprintf (o_file, "%s.o", temp_filename);
ed5b9462 1030 *c_ptr++ = c_file_name;
4e81a331
RS
1031 *c_ptr++ = "-c";
1032 *c_ptr++ = "-o";
1033 *c_ptr++ = o_file;
1034
ed5b9462
RS
1035 /* !!! When GCC calls collect2,
1036 it does not know whether it is calling collect2 or ld.
1037 So collect2 cannot meaningfully understand any options
1038 except those ld understands.
1039 If you propose to make GCC pass some other option,
1040 just imagine what will happen if ld is really ld!!! */
1041
4e81a331 1042 /* Parse arguments. Remember output file spec, pass the rest to ld. */
ed5b9462
RS
1043 /* After the first file, put in the c++ rt0. */
1044
4e81a331
RS
1045 first_file = 1;
1046 while ((arg = *++argv) != (char *)0)
1047 {
1048 *ld1++ = *ld2++ = arg;
1049
1050 if (arg[0] == '-')
1051 switch (arg[1])
1052 {
1053 case 'd':
1054 if (!strcmp (arg, "-debug"))
1055 {
1056 debug = 1;
1057 vflag = 1;
1058 ld1--;
1059 ld2--;
1060 }
1061 break;
1062
4e81a331 1063 case 'o':
0cdd3ddd 1064 output_file = (arg[2] == '\0') ? argv[1] : &arg[2];
4e81a331
RS
1065 break;
1066
1067 case 'r':
1068 if (arg[2] == '\0')
1069 rflag = 1;
1070 break;
1071
a87104d9
MM
1072 case 's':
1073 if (arg[2] == '\0')
1074 {
1075 /* We must strip after the nm run, otherwise C++ linking
1076 won't work. Thus we strip in the second ld run, or
1077 else with strip if there is no second ld run. */
1078 strip_flag = 1;
1079 ld1--;
1080 }
1081 break;
1082
4e81a331
RS
1083 case 'v':
1084 if (arg[2] == '\0')
1085 vflag = 1;
1086 break;
1087 }
1088
1089 else if (first_file
3f7cc57a 1090 && (p = rindex (arg, '.')) != (char *)0
4e81a331
RS
1091 && strcmp (p, ".o") == 0)
1092 {
1093 first_file = 0;
1094 *ld2++ = o_file;
1095 }
1096 }
1097
ed5b9462
RS
1098 /* Get any options that the upper GCC wants to pass to the sub-GCC. */
1099 p = (char *) getenv ("COLLECT_GCC_OPTIONS");
1100 if (p)
1101 while (*p)
1102 {
1103 char *q = p;
1104 while (*q && *q != ' ') q++;
1105 if (*p == '-' && (p[1] == 'm' || p[1] == 'f'))
1106 *c_ptr++ = savestring (p, q - p);
1107
1108 if (*q) q++;
1109 p = q;
1110 }
1111
4e81a331
RS
1112 *c_ptr++ = c_file;
1113 *c_ptr = *ld1 = *ld2 = (char *)0;
1114
1115 if (vflag)
1116 {
ed5b9462 1117 fprintf (stderr, "collect2 version %s", version_string);
4e81a331
RS
1118#ifdef TARGET_VERSION
1119 TARGET_VERSION;
1120#endif
1121 fprintf (stderr, "\n");
1122 }
1123
1124 if (debug)
1125 {
ed5b9462 1126 char *ptr;
a1549b15
RS
1127 fprintf (stderr, "ld_file_name = %s\n",
1128 (ld_file_name ? ld_file_name : "not found"));
1129 fprintf (stderr, "c_file_name = %s\n",
1130 (c_file_name ? c_file_name : "not found"));
1131 fprintf (stderr, "nm_file_name = %s\n",
1132 (nm_file_name ? nm_file_name : "not found"));
1133 fprintf (stderr, "strip_file_name = %s\n",
1134 (strip_file_name ? strip_file_name : "not found"));
1135 fprintf (stderr, "c_file = %s\n",
1136 (c_file ? c_file : "not found"));
1137 fprintf (stderr, "o_file = %s\n",
1138 (o_file ? o_file : "not found"));
ed5b9462 1139
7223feb0
DE
1140 ptr = getenv ("COLLECT_NAMES");
1141 if (ptr)
1142 fprintf (stderr, "COLLECT_NAMES = %s\n", ptr);
1143
ed5b9462
RS
1144 ptr = getenv ("COLLECT_GCC_OPTIONS");
1145 if (ptr)
1146 fprintf (stderr, "COLLECT_GCC_OPTIONS = %s\n", ptr);
1147
1148 ptr = getenv ("COLLECT_GCC");
1149 if (ptr)
1150 fprintf (stderr, "COLLECT_GCC = %s\n", ptr);
1151
1152 ptr = getenv ("COMPILER_PATH");
1153 if (ptr)
1154 fprintf (stderr, "COMPILER_PATH = %s\n", ptr);
1155
1156 ptr = getenv ("LIBRARY_PATH");
1157 if (ptr)
1158 fprintf (stderr, "LIBRARY_PATH = %s\n", ptr);
1159
1160 fprintf (stderr, "\n");
4e81a331
RS
1161 }
1162
1163 /* Load the program, searching all libraries.
1164 Examine the namelist with nm and search it for static constructors
1165 and destructors to call.
1166 Write the constructor and destructor tables to a .s file and reload. */
1167
aee3a549 1168 fork_execute ("ld", ld1_argv);
4e81a331
RS
1169
1170 /* If -r, don't build the constructor or destructor list, just return now. */
1171 if (rflag)
1172 return 0;
1173
0cdd3ddd 1174 scan_prog_file (output_file, PASS_FIRST);
4e81a331
RS
1175
1176 if (debug)
1177 {
1178 fprintf (stderr, "%d constructor(s) found\n", constructors.number);
1179 fprintf (stderr, "%d destructor(s) found\n", destructors.number);
1180 }
1181
1182 if (constructors.number == 0 && destructors.number == 0)
a87104d9
MM
1183 {
1184 /* Strip now if it was requested on the command line. */
1185 if (strip_flag)
1186 {
1187 char **strip_argv = (char **) xcalloc (sizeof (char *), 3);
aee3a549 1188 strip_argv[0] = strip_file_name;
0cdd3ddd 1189 strip_argv[1] = output_file;
a87104d9 1190 strip_argv[2] = (char *) 0;
aee3a549 1191 fork_execute ("strip", strip_argv);
a87104d9
MM
1192 }
1193 return 0;
1194 }
4e81a331
RS
1195
1196 outf = fopen (c_file, "w");
1197 if (outf == (FILE *)0)
1fab8e81 1198 fatal_perror ("%s", c_file);
4e81a331
RS
1199
1200 write_c_file (outf, c_file);
1201
1202 if (fclose (outf))
1fab8e81 1203 fatal_perror ("closing %s", c_file);
4e81a331
RS
1204
1205 if (debug)
1206 {
0cdd3ddd
RS
1207 fprintf (stderr, "\n========== output_file = %s, c_file = %s\n",
1208 output_file, c_file);
4e81a331
RS
1209 write_c_file (stderr, "stderr");
1210 fprintf (stderr, "========== end of c_file\n\n");
1211 }
1212
1213 /* Assemble the constructor and destructor tables.
1214 Link the tables in with the rest of the program. */
1215
aee3a549
RK
1216 fork_execute ("gcc", c_argv);
1217 fork_execute ("ld", ld2_argv);
4e81a331
RS
1218
1219 /* Let scan_prog_file do any final mods (OSF/rose needs this for
1220 constructors/destructors in shared libraries. */
0cdd3ddd 1221 scan_prog_file (output_file, PASS_SECOND);
4e81a331
RS
1222
1223 maybe_unlink (c_file);
1224 maybe_unlink (o_file);
1225 return 0;
1226}
1227
1228\f
1229/* Wait for a process to finish, and exit if a non-zero status is found. */
1230
1231static void
1232do_wait (prog)
1233 char *prog;
1234{
1235 int status;
1236
1237 wait (&status);
1238 if (status)
1239 {
ed5b9462 1240 int sig = status & 0x7F;
4e81a331
RS
1241 int ret;
1242
1243 if (sig != -1 && sig != 0)
1244 {
ed5b9462
RS
1245#ifdef NO_SYS_SIGLIST
1246 error ("%s terminated with signal %d %s",
1247 prog,
1248 sig,
1249 (status & 0200) ? ", core dumped" : "");
1250#else
4e81a331
RS
1251 error ("%s terminated with signal %d [%s]%s",
1252 prog,
1253 sig,
1254 sys_siglist[sig],
1255 (status & 0200) ? ", core dumped" : "");
ed5b9462 1256#endif
4e81a331
RS
1257
1258 my_exit (127);
1259 }
1260
ed5b9462 1261 ret = ((status & 0xFF00) >> 8);
4e81a331
RS
1262 if (ret != -1 && ret != 0)
1263 {
1264 error ("%s returned %d exit status", prog, ret);
1265 my_exit (ret);
1266 }
1267 }
1268}
1269
1270\f
1271/* Fork and execute a program, and wait for the reply. */
1272
1273static void
1274fork_execute (prog, argv)
1275 char *prog;
1276 char **argv;
1277{
1278 int pid;
4e81a331
RS
1279
1280 if (vflag || debug)
1281 {
1282 char **p_argv;
1283 char *str;
1284
aee3a549
RK
1285 if (argv[0])
1286 fprintf (stderr, "%s", argv[0]);
bb59f9a6 1287 else
aee3a549 1288 fprintf (stderr, "[cannot find %s]", prog);
bb59f9a6 1289
4e81a331
RS
1290 for (p_argv = &argv[1]; (str = *p_argv) != (char *)0; p_argv++)
1291 fprintf (stderr, " %s", str);
1292
1293 fprintf (stderr, "\n");
1294 }
1295
1296 fflush (stdout);
1297 fflush (stderr);
1298
bb59f9a6
RS
1299 /* If we can't find a program we need, complain error. Do this here
1300 since we might not end up needing something that we couldn't find. */
1301
aee3a549
RK
1302 if (argv[0] == 0)
1303 fatal ("cannot find `%s'", prog);
bb59f9a6 1304
4e81a331
RS
1305 pid = vfork ();
1306 if (pid == -1)
cf0c751a
JW
1307 {
1308#ifdef vfork
1309 fatal_perror ("fork");
1310#else
1311 fatal_perror ("vfork");
1312#endif
1313 }
4e81a331
RS
1314
1315 if (pid == 0) /* child context */
1316 {
aee3a549 1317 execvp (argv[0], argv);
1fab8e81 1318 fatal_perror ("executing %s", prog);
4e81a331
RS
1319 }
1320
4e81a331 1321 do_wait (prog);
4e81a331
RS
1322}
1323
1324\f
1325/* Unlink a file unless we are debugging. */
1326
1327static void
1328maybe_unlink (file)
1329 char *file;
1330{
1331 if (!debug)
1332 unlink (file);
1333 else
1334 fprintf (stderr, "[Leaving %s]\n", file);
1335}
1336
1337\f
1338/* Add a name to a linked list. */
1339
1340static void
1341add_to_list (head_ptr, name)
1342 struct head *head_ptr;
1343 char *name;
1344{
1345 struct id *newid = (struct id *) xcalloc (sizeof (*newid) + strlen (name), 1);
1346 static long sequence_number = 0;
1347 newid->sequence = ++sequence_number;
1348 strcpy (newid->name, name);
1349
1350 if (head_ptr->first)
1351 head_ptr->last->next = newid;
1352 else
1353 head_ptr->first = newid;
1354
1355 head_ptr->last = newid;
1356 head_ptr->number++;
1357}
1358
1359/* Write: `prefix', the names on list LIST, `suffix'. */
1360
1361static void
1362write_list (stream, prefix, list)
1363 FILE *stream;
1364 char *prefix;
1365 struct id *list;
1366{
1367 while (list)
1368 {
1369 fprintf (stream, "%sx%d,\n", prefix, list->sequence);
1370 list = list->next;
1371 }
1372}
1373
1374static void
1375write_list_with_asm (stream, prefix, list)
1376 FILE *stream;
1377 char *prefix;
1378 struct id *list;
1379{
1380 while (list)
1381 {
c7af43d8 1382 fprintf (stream, "%sx%d __asm__ (\"%s\");\n",
4e81a331
RS
1383 prefix, list->sequence, list->name);
1384 list = list->next;
1385 }
1386}
1387
1388/* Write the constructor/destructor tables. */
1389
1390static void
1391write_c_file (stream, name)
1392 FILE *stream;
1393 char *name;
1394{
1395 /* Write the tables as C code */
1396
1397 fprintf (stream, "typedef void entry_pt();\n\n");
1398
17704846 1399 write_list_with_asm (stream, "extern entry_pt ", constructors.first);
4e81a331
RS
1400
1401 fprintf (stream, "\nentry_pt * __CTOR_LIST__[] = {\n");
1402 fprintf (stream, "\t(entry_pt *) %d,\n", constructors.number);
ed5b9462 1403 write_list (stream, "\t", constructors.first);
4e81a331
RS
1404 fprintf (stream, "\t0\n};\n\n");
1405
17704846 1406 write_list_with_asm (stream, "extern entry_pt ", destructors.first);
4e81a331
RS
1407
1408 fprintf (stream, "\nentry_pt * __DTOR_LIST__[] = {\n");
1409 fprintf (stream, "\t(entry_pt *) %d,\n", destructors.number);
ed5b9462 1410 write_list (stream, "\t", destructors.first);
4e81a331
RS
1411 fprintf (stream, "\t0\n};\n\n");
1412
d6cf3187
RS
1413 fprintf (stream, "extern entry_pt %s;\n", NAME__MAIN);
1414 fprintf (stream, "entry_pt *__main_reference = %s;\n\n", NAME__MAIN);
4e81a331
RS
1415}
1416
1417\f
ed5b9462 1418#ifdef OBJECT_FORMAT_NONE
4e81a331 1419
ed5b9462
RS
1420/* Generic version to scan the name list of the loaded program for
1421 the symbols g++ uses for static constructors and destructors.
4e81a331
RS
1422
1423 The constructor table begins at __CTOR_LIST__ and contains a count
1424 of the number of pointers (or -1 if the constructors are built in a
1425 separate section by the linker), followed by the pointers to the
1426 constructor functions, terminated with a null pointer. The
1427 destructor table has the same format, and begins at __DTOR_LIST__. */
1428
1429static void
1430scan_prog_file (prog_name, which_pass)
1431 char *prog_name;
1432 enum pass which_pass;
1433{
ed5b9462
RS
1434 void (*int_handler) ();
1435 void (*quit_handler) ();
4e81a331
RS
1436 char *nm_argv[4];
1437 int pid;
1438 int argc = 0;
1439 int pipe_fd[2];
1440 char *p, buf[1024];
1441 FILE *inf;
1442
1443 if (which_pass != PASS_FIRST)
1444 return;
1445
bb59f9a6
RS
1446 /* If we don't have an `nm', complain. */
1447 if (nm_file_name == 0)
1448 fatal ("cannot find `nm'");
1449
ed5b9462 1450 nm_argv[argc++] = "nm";
4e81a331 1451 if (NM_FLAGS[0] != '\0')
ed5b9462 1452 nm_argv[argc++] = NM_FLAGS;
4e81a331 1453
ed5b9462
RS
1454 nm_argv[argc++] = prog_name;
1455 nm_argv[argc++] = (char *)0;
4e81a331
RS
1456
1457 if (pipe (pipe_fd) < 0)
1458 fatal_perror ("pipe");
1459
1460 inf = fdopen (pipe_fd[0], "r");
1461 if (inf == (FILE *)0)
1462 fatal_perror ("fdopen");
1463
1464 /* Trace if needed. */
1465 if (vflag)
1466 {
1467 char **p_argv;
1468 char *str;
1469
1470 fprintf (stderr, "%s", nm_file_name);
1471 for (p_argv = &nm_argv[1]; (str = *p_argv) != (char *)0; p_argv++)
1472 fprintf (stderr, " %s", str);
1473
1474 fprintf (stderr, "\n");
1475 }
1476
1477 fflush (stdout);
1478 fflush (stderr);
1479
1480 /* Spawn child nm on pipe */
1481 pid = vfork ();
1482 if (pid == -1)
cf0c751a
JW
1483 {
1484#ifdef vfork
1485 fatal_perror ("fork");
1486#else
1487 fatal_perror ("vfork");
1488#endif
1489 }
4e81a331
RS
1490
1491 if (pid == 0) /* child context */
1492 {
1493 /* setup stdout */
1494 if (dup2 (pipe_fd[1], 1) < 0)
1fab8e81 1495 fatal_perror ("dup2 (%d, 1)", pipe_fd[1]);
4e81a331
RS
1496
1497 if (close (pipe_fd[0]) < 0)
1fab8e81 1498 fatal_perror ("close (%d)", pipe_fd[0]);
4e81a331
RS
1499
1500 if (close (pipe_fd[1]) < 0)
1fab8e81 1501 fatal_perror ("close (%d)", pipe_fd[1]);
4e81a331
RS
1502
1503 execv (nm_file_name, nm_argv);
1fab8e81 1504 fatal_perror ("executing %s", nm_file_name);
4e81a331
RS
1505 }
1506
1507 /* Parent context from here on. */
ed5b9462 1508 int_handler = (void (*) ())signal (SIGINT, SIG_IGN);
8ab861c7 1509#ifdef SIGQUIT
ed5b9462 1510 quit_handler = (void (*) ())signal (SIGQUIT, SIG_IGN);
8ab861c7 1511#endif
4e81a331
RS
1512
1513 if (close (pipe_fd[1]) < 0)
1fab8e81 1514 fatal_perror ("close (%d)", pipe_fd[1]);
4e81a331
RS
1515
1516 if (debug)
1517 fprintf (stderr, "\nnm output with constructors/destructors.\n");
1518
1519 /* Read each line of nm output. */
1520 while (fgets (buf, sizeof buf, inf) != (char *)0)
1521 {
1522 int ch, ch2;
ed5b9462 1523 char *name, *end;
4e81a331
RS
1524
1525 /* If it contains a constructor or destructor name, add the name
1526 to the appropriate list. */
1527
1528 for (p = buf; (ch = *p) != '\0' && ch != '\n' && ch != '_'; p++)
1529 ;
1530
1531 if (ch == '\0' || ch == '\n')
1532 continue;
ed5b9462
RS
1533
1534 name = p;
1535 /* Find the end of the symbol name.
1536 Don't include `|', because Encore nm can tack that on the end. */
1537 for (end = p; (ch2 = *end) != '\0' && !isspace (ch2) && ch2 != '|';
1538 end++)
1539 continue;
4e81a331
RS
1540
1541 *end = '\0';
ed5b9462 1542 switch (is_ctor_dtor (name))
4e81a331 1543 {
ed5b9462
RS
1544 case 1:
1545 add_to_list (&constructors, name);
1546 break;
4e81a331 1547
ed5b9462
RS
1548 case 2:
1549 add_to_list (&destructors, name);
1550 break;
4e81a331 1551
ed5b9462
RS
1552 default: /* not a constructor or destructor */
1553 continue;
4e81a331
RS
1554 }
1555
4e81a331
RS
1556 if (debug)
1557 fprintf (stderr, "\t%s\n", buf);
1558 }
1559
1560 if (debug)
1561 fprintf (stderr, "\n");
1562
1563 if (fclose (inf) != 0)
1564 fatal_perror ("fclose of pipe");
1565
1566 do_wait (nm_file_name);
1567
1568 signal (SIGINT, int_handler);
8ab861c7 1569#ifdef SIGQUIT
4e81a331 1570 signal (SIGQUIT, quit_handler);
8ab861c7 1571#endif
4e81a331
RS
1572}
1573
ed5b9462
RS
1574#endif /* OBJECT_FORMAT_NONE */
1575
1576\f
1577/*
1578 * COFF specific stuff.
1579 */
1580
1581#ifdef OBJECT_FORMAT_COFF
1582
1583#if defined(EXTENDED_COFF)
17704846
JW
1584# define GCC_SYMBOLS(X) (SYMHEADER(X).isymMax + SYMHEADER(X).iextMax)
1585# define GCC_SYMENT SYMR
1586# define GCC_OK_SYMBOL(X) ((X).st == stProc && (X).sc == scText)
1587# define GCC_SYMINC(X) (1)
1588# define GCC_SYMZERO(X) (SYMHEADER(X).isymMax)
1589# define GCC_CHECK_HDR(X) (PSYMTAB(X) != 0)
ed5b9462 1590#else
17704846
JW
1591# define GCC_SYMBOLS(X) (HEADER(ldptr).f_nsyms)
1592# define GCC_SYMENT SYMENT
ed5b9462
RS
1593# define GCC_OK_SYMBOL(X) \
1594 (((X).n_sclass == C_EXT) && \
1595 (((X).n_type & N_TMASK) == (DT_NON << N_BTSHFT) || \
1596 ((X).n_type & N_TMASK) == (DT_FCN << N_BTSHFT)))
17704846
JW
1597# define GCC_SYMINC(X) ((X).n_numaux+1)
1598# define GCC_SYMZERO(X) 0
1599# define GCC_CHECK_HDR(X) (1)
ed5b9462
RS
1600#endif
1601
1602extern char *ldgetname ();
1603
1604/* COFF version to scan the name list of the loaded program for
1605 the symbols g++ uses for static constructors and destructors.
1606
1607 The constructor table begins at __CTOR_LIST__ and contains a count
1608 of the number of pointers (or -1 if the constructors are built in a
1609 separate section by the linker), followed by the pointers to the
1610 constructor functions, terminated with a null pointer. The
1611 destructor table has the same format, and begins at __DTOR_LIST__. */
1612
1613static void
1614scan_prog_file (prog_name, which_pass)
1615 char *prog_name;
1616 enum pass which_pass;
1617{
f3c3d3df 1618 LDFILE *ldptr = NULL;
ed5b9462
RS
1619 int sym_index, sym_count;
1620
1621 if (which_pass != PASS_FIRST)
1622 return;
1623
1624 if ((ldptr = ldopen (prog_name, ldptr)) == NULL)
1625 fatal ("%s: can't open as COFF file", prog_name);
1626
e99467d2 1627 if (!MY_ISCOFF (HEADER (ldptr).f_magic))
ed5b9462
RS
1628 fatal ("%s: not a COFF file", prog_name);
1629
17704846 1630 if (GCC_CHECK_HDR (ldptr))
ed5b9462 1631 {
17704846
JW
1632 sym_count = GCC_SYMBOLS (ldptr);
1633 sym_index = GCC_SYMZERO (ldptr);
1634 while (sym_index < sym_count)
1635 {
1636 GCC_SYMENT symbol;
ed5b9462 1637
17704846
JW
1638 if (ldtbread (ldptr, sym_index, &symbol) <= 0)
1639 break;
1640 sym_index += GCC_SYMINC (symbol);
ed5b9462 1641
17704846
JW
1642 if (GCC_OK_SYMBOL (symbol))
1643 {
1644 char *name;
ed5b9462 1645
17704846
JW
1646 if ((name = ldgetname (ldptr, &symbol)) == NULL)
1647 continue; /* should never happen */
ed5b9462
RS
1648
1649#ifdef _AIX
17704846
JW
1650 /* All AIX function names begin with a dot. */
1651 if (*name++ != '.')
1652 continue;
ed5b9462
RS
1653#endif
1654
17704846
JW
1655 switch (is_ctor_dtor (name))
1656 {
1657 case 1:
1658 add_to_list (&constructors, name);
1659 break;
ed5b9462 1660
17704846
JW
1661 case 2:
1662 add_to_list (&destructors, name);
1663 break;
ed5b9462 1664
17704846
JW
1665 default: /* not a constructor or destructor */
1666 continue;
1667 }
ed5b9462
RS
1668
1669#if !defined(EXTENDED_COFF)
17704846
JW
1670 if (debug)
1671 fprintf (stderr, "\tsec=%d class=%d type=%s%o %s\n",
1672 symbol.n_scnum, symbol.n_sclass,
1673 (symbol.n_type ? "0" : ""), symbol.n_type,
1674 name);
ed5b9462 1675#else
17704846
JW
1676 if (debug)
1677 fprintf (stderr, "\tiss = %5d, value = %5d, index = %5d, name = %s\n",
1678 symbol.iss, symbol.value, symbol.index, name);
ed5b9462 1679#endif
17704846 1680 }
ed5b9462
RS
1681 }
1682 }
1683
1684 (void) ldclose(ldptr);
1685}
1686
1687#endif /* OBJECT_FORMAT_COFF */
4e81a331
RS
1688
1689\f
1690/*
1691 * OSF/rose specific stuff.
1692 */
1693
1694#ifdef OBJECT_FORMAT_ROSE
1695
1696/* Union of the various load commands */
1697
1698typedef union load_union
1699{
1700 ldc_header_t hdr; /* common header */
1701 load_cmd_map_command_t map; /* map indexing other load cmds */
ed5b9462 1702 interpreter_command_t iprtr; /* interpreter pathname */
4e81a331
RS
1703 strings_command_t str; /* load commands strings section */
1704 region_command_t region; /* region load command */
1705 reloc_command_t reloc; /* relocation section */
1706 package_command_t pkg; /* package load command */
1707 symbols_command_t sym; /* symbol sections */
1708 entry_command_t ent; /* program start section */
1709 gen_info_command_t info; /* object information */
1710 func_table_command_t func; /* function constructors/destructors */
1711} load_union_t;
1712
1713/* Structure to point to load command and data section in memory. */
1714
1715typedef struct load_all
1716{
1717 load_union_t *load; /* load command */
1718 char *section; /* pointer to section */
1719} load_all_t;
1720
1721/* Structure to contain information about a file mapped into memory. */
1722
1723struct file_info
1724{
1725 char *start; /* start of map */
1726 char *name; /* filename */
1727 long size; /* size of the file */
1728 long rounded_size; /* size rounded to page boundary */
1729 int fd; /* file descriptor */
1730 int rw; /* != 0 if opened read/write */
1731 int use_mmap; /* != 0 if mmap'ed */
1732};
1733
ed5b9462 1734extern int decode_mach_o_hdr ();
ed5b9462 1735extern int encode_mach_o_hdr ();
4e81a331 1736
4d1a011f
RK
1737static void add_func_table PROTO((mo_header_t *, load_all_t *,
1738 symbol_info_t *, int));
1739static void print_header PROTO((mo_header_t *));
1740static void print_load_command PROTO((load_union_t*, size_t, int));
1741static void bad_header PROTO((int));
1742static struct file_info *read_file PROTO((hcar *, int, int));
1743static void end_file PROTO((struct file_info *));
4e81a331
RS
1744\f
1745/* OSF/rose specific version to scan the name list of the loaded
1746 program for the symbols g++ uses for static constructors and
1747 destructors.
1748
1749 The constructor table begins at __CTOR_LIST__ and contains a count
1750 of the number of pointers (or -1 if the constructors are built in a
1751 separate section by the linker), followed by the pointers to the
1752 constructor functions, terminated with a null pointer. The
1753 destructor table has the same format, and begins at __DTOR_LIST__. */
1754
1755static void
1756scan_prog_file (prog_name, which_pass)
1757 char *prog_name;
1758 enum pass which_pass;
1759{
1760 char *obj;
1761 mo_header_t hdr;
1762 load_all_t *load_array;
1763 load_all_t *load_end;
1764 load_all_t *load_cmd;
1765 int symbol_load_cmds;
1766 off_t offset;
1767 int i;
1768 int num_syms;
1769 int status;
1770 char *str_sect;
1771 struct file_info *obj_file;
1772 int prog_fd;
1773 mo_lcid_t cmd_strings = -1;
1774 symbol_info_t *main_sym = 0;
1775 int rw = (which_pass != PASS_FIRST);
1776
1777 prog_fd = open (prog_name, (rw) ? O_RDWR : O_RDONLY);
1778 if (prog_fd < 0)
1fab8e81 1779 fatal_perror ("can't read %s", prog_name);
4e81a331
RS
1780
1781 obj_file = read_file (prog_name, prog_fd, rw);
1782 obj = obj_file->start;
1783
1784 status = decode_mach_o_hdr (obj, MO_SIZEOF_RAW_HDR, MOH_HEADER_VERSION, &hdr);
1785 if (status != MO_HDR_CONV_SUCCESS)
1786 bad_header (status);
1787
1788
1789 /* Do some basic sanity checks. Note we explicitly use the big endian magic number,
1790 since the hardware will automatically swap bytes for us on loading little endian
1791 integers. */
1792
1793#ifndef CROSS_COMPILE
1794 if (hdr.moh_magic != MOH_MAGIC_MSB
1795 || hdr.moh_header_version != MOH_HEADER_VERSION
1796 || hdr.moh_byte_order != OUR_BYTE_ORDER
1797 || hdr.moh_data_rep_id != OUR_DATA_REP_ID
1798 || hdr.moh_cpu_type != OUR_CPU_TYPE
1799 || hdr.moh_cpu_subtype != OUR_CPU_SUBTYPE
1800 || hdr.moh_vendor_type != OUR_VENDOR_TYPE)
1801 {
1fab8e81 1802 fatal ("incompatibilities between object file & expected values");
4e81a331
RS
1803 }
1804#endif
1805
1806 if (debug)
1807 print_header (&hdr);
1808
1809 offset = hdr.moh_first_cmd_off;
1810 load_end = load_array
1811 = (load_all_t *) xcalloc (sizeof (load_all_t), hdr.moh_n_load_cmds + 2);
1812
1813 /* Build array of load commands, calculating the offsets */
1814 for (i = 0; i < hdr.moh_n_load_cmds; i++)
1815 {
1816 load_union_t *load_hdr; /* load command header */
1817
1818 load_cmd = load_end++;
1819 load_hdr = (load_union_t *) (obj + offset);
1820
f72aed24 1821 /* If modifying the program file, copy the header. */
4e81a331
RS
1822 if (rw)
1823 {
1824 load_union_t *ptr = (load_union_t *) xmalloc (load_hdr->hdr.ldci_cmd_size);
7c0891a1 1825 bcopy ((generic *)load_hdr, (generic *)ptr, load_hdr->hdr.ldci_cmd_size);
4e81a331
RS
1826 load_hdr = ptr;
1827
1828 /* null out old command map, because we will rewrite at the end. */
1829 if (ptr->hdr.ldci_cmd_type == LDC_CMD_MAP)
1830 {
1831 cmd_strings = ptr->map.lcm_ld_cmd_strings;
1832 ptr->hdr.ldci_cmd_type = LDC_UNDEFINED;
1833 }
1834 }
1835
1836 load_cmd->load = load_hdr;
1837 if (load_hdr->hdr.ldci_section_off > 0)
1838 load_cmd->section = obj + load_hdr->hdr.ldci_section_off;
1839
1840 if (debug)
1841 print_load_command (load_hdr, offset, i);
1842
1843 offset += load_hdr->hdr.ldci_cmd_size;
1844 }
1845
1846 /* If the last command is the load command map and is not undefined,
1847 decrement the count of load commands. */
1848 if (rw && load_end[-1].load->hdr.ldci_cmd_type == LDC_UNDEFINED)
1849 {
1850 load_end--;
1851 hdr.moh_n_load_cmds--;
1852 }
1853
1854 /* Go through and process each symbol table section. */
1855 symbol_load_cmds = 0;
1856 for (load_cmd = load_array; load_cmd < load_end; load_cmd++)
1857 {
1858 load_union_t *load_hdr = load_cmd->load;
1859
1860 if (load_hdr->hdr.ldci_cmd_type == LDC_SYMBOLS)
1861 {
1862 symbol_load_cmds++;
1863
1864 if (debug)
1865 {
ed5b9462 1866 char *kind = "unknown";
4e81a331
RS
1867
1868 switch (load_hdr->sym.symc_kind)
1869 {
1870 case SYMC_IMPORTS: kind = "imports"; break;
1871 case SYMC_DEFINED_SYMBOLS: kind = "defined"; break;
1872 case SYMC_STABS: kind = "stabs"; break;
1873 }
1874
1875 fprintf (stderr, "\nProcessing symbol table #%d, offset = 0x%.8lx, kind = %s\n",
1876 symbol_load_cmds, load_hdr->hdr.ldci_section_off, kind);
1877 }
1878
1879 if (load_hdr->sym.symc_kind != SYMC_DEFINED_SYMBOLS)
1880 continue;
1881
ed5b9462 1882 str_sect = load_array[load_hdr->sym.symc_strings_section].section;
4e81a331
RS
1883 if (str_sect == (char *)0)
1884 fatal ("string section missing");
1885
1886 if (load_cmd->section == (char *)0)
1887 fatal ("section pointer missing");
1888
1889 num_syms = load_hdr->sym.symc_nentries;
1890 for (i = 0; i < num_syms; i++)
1891 {
1892 symbol_info_t *sym = ((symbol_info_t *) load_cmd->section) + i;
1893 char *name = sym->si_name.symbol_name + str_sect;
4e81a331
RS
1894
1895 if (name[0] != '_')
1896 continue;
1897
4e81a331
RS
1898 if (rw)
1899 {
d6cf3187
RS
1900 char *n = name + strlen (name) - strlen (NAME__MAIN);
1901
1902 if ((n - name) < 0 || strcmp (n, NAME__MAIN))
4e81a331 1903 continue;
d6cf3187
RS
1904 while (n != name)
1905 if (*--n != '_')
1906 continue;
4e81a331
RS
1907
1908 main_sym = sym;
1909 }
ed5b9462 1910 else
4e81a331 1911 {
ed5b9462
RS
1912 switch (is_ctor_dtor (name))
1913 {
1914 case 1:
1915 add_to_list (&constructors, name);
1916 break;
1917
1918 case 2:
1919 add_to_list (&destructors, name);
1920 break;
1921
1922 default: /* not a constructor or destructor */
1923 continue;
1924 }
4e81a331
RS
1925 }
1926
4e81a331
RS
1927 if (debug)
1928 fprintf (stderr, "\ttype = 0x%.4x, sc = 0x%.2x, flags = 0x%.8x, name = %.30s\n",
1929 sym->si_type, sym->si_sc_type, sym->si_flags, name);
1930 }
1931 }
1932 }
1933
1934 if (symbol_load_cmds == 0)
1fab8e81 1935 fatal ("no symbol table found");
4e81a331
RS
1936
1937 /* Update the program file now, rewrite header and load commands. At present,
1938 we assume that there is enough space after the last load command to insert
1939 one more. Since the first section written out is page aligned, and the
1940 number of load commands is small, this is ok for the present. */
1941
1942 if (rw)
1943 {
1944 load_union_t *load_map;
1945 size_t size;
1946
1947 if (cmd_strings == -1)
1fab8e81
RS
1948 fatal ("no cmd_strings found");
1949
1950 /* Add __main to initializer list.
1951 If we are building a program instead of a shared library, don't
1952 do anything, since in the current version, you cannot do mallocs
1953 and such in the constructors. */
4e81a331 1954
1fab8e81
RS
1955 if (main_sym != (symbol_info_t *)0
1956 && ((hdr.moh_flags & MOH_EXECABLE_F) == 0))
4e81a331
RS
1957 add_func_table (&hdr, load_array, main_sym, FNTC_INITIALIZATION);
1958
1959 if (debug)
1960 fprintf (stderr, "\nUpdating header and load commands.\n\n");
1961
1962 hdr.moh_n_load_cmds++;
1963 size = sizeof (load_cmd_map_command_t) + (sizeof (mo_offset_t) * (hdr.moh_n_load_cmds - 1));
1964
1965 /* Create new load command map. */
1966 if (debug)
1967 fprintf (stderr, "load command map, %d cmds, new size %ld.\n",
1968 (int)hdr.moh_n_load_cmds, (long)size);
1969
1970 load_map = (load_union_t *) xcalloc (1, size);
1971 load_map->map.ldc_header.ldci_cmd_type = LDC_CMD_MAP;
1972 load_map->map.ldc_header.ldci_cmd_size = size;
1973 load_map->map.lcm_ld_cmd_strings = cmd_strings;
1974 load_map->map.lcm_nentries = hdr.moh_n_load_cmds;
1975 load_array[hdr.moh_n_load_cmds-1].load = load_map;
1976
1977 offset = hdr.moh_first_cmd_off;
1978 for (i = 0; i < hdr.moh_n_load_cmds; i++)
1979 {
1980 load_map->map.lcm_map[i] = offset;
1981 if (load_array[i].load->hdr.ldci_cmd_type == LDC_CMD_MAP)
1982 hdr.moh_load_map_cmd_off = offset;
1983
1984 offset += load_array[i].load->hdr.ldci_cmd_size;
1985 }
1986
1987 hdr.moh_sizeofcmds = offset - MO_SIZEOF_RAW_HDR;
1988
1989 if (debug)
1990 print_header (&hdr);
1991
1992 /* Write header */
1993 status = encode_mach_o_hdr (&hdr, obj, MO_SIZEOF_RAW_HDR);
1994 if (status != MO_HDR_CONV_SUCCESS)
1995 bad_header (status);
1996
1997 if (debug)
1998 fprintf (stderr, "writing load commands.\n\n");
1999
2000 /* Write load commands */
2001 offset = hdr.moh_first_cmd_off;
2002 for (i = 0; i < hdr.moh_n_load_cmds; i++)
2003 {
2004 load_union_t *load_hdr = load_array[i].load;
2005 size_t size = load_hdr->hdr.ldci_cmd_size;
2006
2007 if (debug)
2008 print_load_command (load_hdr, offset, i);
2009
7c0891a1 2010 bcopy ((generic *)load_hdr, (generic *)(obj + offset), size);
4e81a331
RS
2011 offset += size;
2012 }
2013 }
2014
2015 end_file (obj_file);
2016
2017 if (close (prog_fd))
1fab8e81 2018 fatal_perror ("closing %s", prog_name);
4e81a331
RS
2019
2020 if (debug)
2021 fprintf (stderr, "\n");
2022}
2023
2024\f
2025/* Add a function table to the load commands to call a function
ed5b9462 2026 on initiation or termination of the process. */
4e81a331
RS
2027
2028static void
2029add_func_table (hdr_p, load_array, sym, type)
2030 mo_header_t *hdr_p; /* pointer to global header */
2031 load_all_t *load_array; /* array of ptrs to load cmds */
2032 symbol_info_t *sym; /* pointer to symbol entry */
2033 int type; /* fntc_type value */
2034{
2035 /* Add a new load command. */
2036 int num_cmds = ++hdr_p->moh_n_load_cmds;
2037 int load_index = num_cmds - 1;
2038 size_t size = sizeof (func_table_command_t) + sizeof (mo_addr_t);
2039 load_union_t *ptr = xcalloc (1, size);
2040 load_all_t *load_cmd;
2041 int i;
2042
2043 /* Set the unresolved address bit in the header to force the loader to be
2044 used, since kernel exec does not call the initialization functions. */
2045 hdr_p->moh_flags |= MOH_UNRESOLVED_F;
2046
2047 load_cmd = &load_array[load_index];
2048 load_cmd->load = ptr;
2049 load_cmd->section = (char *)0;
2050
2051 /* Fill in func table load command. */
2052 ptr->func.ldc_header.ldci_cmd_type = LDC_FUNC_TABLE;
2053 ptr->func.ldc_header.ldci_cmd_size = size;
2054 ptr->func.ldc_header.ldci_section_off = 0;
2055 ptr->func.ldc_header.ldci_section_len = 0;
2056 ptr->func.fntc_type = type;
2057 ptr->func.fntc_nentries = 1;
2058
2059 /* copy address, turn it from abs. address to (region,offset) if necessary. */
2060 /* Is the symbol already expressed as (region, offset)? */
2061 if ((sym->si_flags & SI_ABSOLUTE_VALUE_F) == 0)
2062 {
2063 ptr->func.fntc_entry_loc[i].adr_lcid = sym->si_value.def_val.adr_lcid;
2064 ptr->func.fntc_entry_loc[i].adr_sctoff = sym->si_value.def_val.adr_sctoff;
2065 }
2066
2067 /* If not, figure out which region it's in. */
2068 else
2069 {
2070 mo_vm_addr_t addr = sym->si_value.abs_val;
2071 int found = 0;
2072
2073 for (i = 0; i < load_index; i++)
2074 {
2075 if (load_array[i].load->hdr.ldci_cmd_type == LDC_REGION)
2076 {
2077 region_command_t *region_ptr = &load_array[i].load->region;
2078
2079 if ((region_ptr->regc_flags & REG_ABS_ADDR_F) != 0
2080 && addr >= region_ptr->regc_addr.vm_addr
2081 && addr <= region_ptr->regc_addr.vm_addr + region_ptr->regc_vm_size)
2082 {
2083 ptr->func.fntc_entry_loc[0].adr_lcid = i;
2084 ptr->func.fntc_entry_loc[0].adr_sctoff = addr - region_ptr->regc_addr.vm_addr;
2085 found++;
2086 break;
2087 }
2088 }
2089 }
2090
2091 if (!found)
2092 fatal ("could not convert 0x%l.8x into a region", addr);
2093 }
2094
2095 if (debug)
2096 fprintf (stderr,
2097 "%s function, region %d, offset = %ld (0x%.8lx)\n",
2098 (type == FNTC_INITIALIZATION) ? "init" : "term",
2099 (int)ptr->func.fntc_entry_loc[i].adr_lcid,
2100 (long)ptr->func.fntc_entry_loc[i].adr_sctoff,
2101 (long)ptr->func.fntc_entry_loc[i].adr_sctoff);
2102
2103}
2104
2105\f
2106/* Print the global header for an OSF/rose object. */
2107
2108static void
2109print_header (hdr_ptr)
2110 mo_header_t *hdr_ptr;
2111{
2112 fprintf (stderr, "\nglobal header:\n");
2113 fprintf (stderr, "\tmoh_magic = 0x%.8lx\n", hdr_ptr->moh_magic);
2114 fprintf (stderr, "\tmoh_major_version = %d\n", (int)hdr_ptr->moh_major_version);
2115 fprintf (stderr, "\tmoh_minor_version = %d\n", (int)hdr_ptr->moh_minor_version);
2116 fprintf (stderr, "\tmoh_header_version = %d\n", (int)hdr_ptr->moh_header_version);
2117 fprintf (stderr, "\tmoh_max_page_size = %d\n", (int)hdr_ptr->moh_max_page_size);
2118 fprintf (stderr, "\tmoh_byte_order = %d\n", (int)hdr_ptr->moh_byte_order);
2119 fprintf (stderr, "\tmoh_data_rep_id = %d\n", (int)hdr_ptr->moh_data_rep_id);
2120 fprintf (stderr, "\tmoh_cpu_type = %d\n", (int)hdr_ptr->moh_cpu_type);
2121 fprintf (stderr, "\tmoh_cpu_subtype = %d\n", (int)hdr_ptr->moh_cpu_subtype);
2122 fprintf (stderr, "\tmoh_vendor_type = %d\n", (int)hdr_ptr->moh_vendor_type);
2123 fprintf (stderr, "\tmoh_load_map_cmd_off = %d\n", (int)hdr_ptr->moh_load_map_cmd_off);
2124 fprintf (stderr, "\tmoh_first_cmd_off = %d\n", (int)hdr_ptr->moh_first_cmd_off);
2125 fprintf (stderr, "\tmoh_sizeofcmds = %d\n", (int)hdr_ptr->moh_sizeofcmds);
2126 fprintf (stderr, "\tmon_n_load_cmds = %d\n", (int)hdr_ptr->moh_n_load_cmds);
2127 fprintf (stderr, "\tmoh_flags = 0x%.8lx", (long)hdr_ptr->moh_flags);
2128
2129 if (hdr_ptr->moh_flags & MOH_RELOCATABLE_F)
2130 fprintf (stderr, ", relocatable");
2131
2132 if (hdr_ptr->moh_flags & MOH_LINKABLE_F)
2133 fprintf (stderr, ", linkable");
2134
2135 if (hdr_ptr->moh_flags & MOH_EXECABLE_F)
2136 fprintf (stderr, ", execable");
2137
2138 if (hdr_ptr->moh_flags & MOH_EXECUTABLE_F)
2139 fprintf (stderr, ", executable");
2140
2141 if (hdr_ptr->moh_flags & MOH_UNRESOLVED_F)
2142 fprintf (stderr, ", unresolved");
2143
2144 fprintf (stderr, "\n\n");
2145 return;
2146}
2147
2148\f
2149/* Print a short summary of a load command. */
2150
2151static void
2152print_load_command (load_hdr, offset, number)
2153 load_union_t *load_hdr;
2154 size_t offset;
2155 int number;
2156{
2157 mo_long_t type = load_hdr->hdr.ldci_cmd_type;
2158 char *type_str = (char *)0;
2159
2160 switch (type)
2161 {
2162 case LDC_UNDEFINED: type_str = "UNDEFINED"; break;
2163 case LDC_CMD_MAP: type_str = "CMD_MAP"; break;
2164 case LDC_INTERPRETER: type_str = "INTERPRETER"; break;
2165 case LDC_STRINGS: type_str = "STRINGS"; break;
2166 case LDC_REGION: type_str = "REGION"; break;
2167 case LDC_RELOC: type_str = "RELOC"; break;
2168 case LDC_PACKAGE: type_str = "PACKAGE"; break;
2169 case LDC_SYMBOLS: type_str = "SYMBOLS"; break;
2170 case LDC_ENTRY: type_str = "ENTRY"; break;
2171 case LDC_FUNC_TABLE: type_str = "FUNC_TABLE"; break;
2172 case LDC_GEN_INFO: type_str = "GEN_INFO"; break;
2173 }
2174
2175 fprintf (stderr,
2176 "cmd %2d, sz: 0x%.2lx, coff: 0x%.3lx, doff: 0x%.6lx, dlen: 0x%.6lx",
2177 number,
2178 (long) load_hdr->hdr.ldci_cmd_size,
2179 (long) offset,
2180 (long) load_hdr->hdr.ldci_section_off,
2181 (long) load_hdr->hdr.ldci_section_len);
2182
2183 if (type_str == (char *)0)
2184 fprintf (stderr, ", ty: unknown (%ld)\n", (long) type);
2185
2186 else if (type != LDC_REGION)
2187 fprintf (stderr, ", ty: %s\n", type_str);
2188
2189 else
2190 {
2191 char *region = "";
2192 switch (load_hdr->region.regc_usage_type)
2193 {
2194 case REG_TEXT_T: region = ", .text"; break;
2195 case REG_DATA_T: region = ", .data"; break;
2196 case REG_BSS_T: region = ", .bss"; break;
2197 case REG_GLUE_T: region = ", .glue"; break;
2198#if defined (REG_RDATA_T) && defined (REG_SDATA_T) && defined (REG_SBSS_T) /*mips*/
2199 case REG_RDATA_T: region = ", .rdata"; break;
2200 case REG_SDATA_T: region = ", .sdata"; break;
2201 case REG_SBSS_T: region = ", .sbss"; break;
2202#endif
2203 }
2204
2205 fprintf (stderr, ", ty: %s, vaddr: 0x%.8lx, vlen: 0x%.6lx%s\n",
2206 type_str,
2207 (long) load_hdr->region.regc_vm_addr,
2208 (long) load_hdr->region.regc_vm_size,
2209 region);
2210 }
2211
2212 return;
2213}
2214
2215\f
2216/* Fatal error when {en,de}code_mach_o_header fails. */
2217
2218static void
2219bad_header (status)
2220 int status;
2221{
2222 char *msg = (char *)0;
2223
2224 switch (status)
2225 {
2226 case MO_ERROR_BAD_MAGIC: msg = "bad magic number"; break;
2227 case MO_ERROR_BAD_HDR_VERS: msg = "bad header version"; break;
2228 case MO_ERROR_BAD_RAW_HDR_VERS: msg = "bad raw header version"; break;
2229 case MO_ERROR_BUF2SML: msg = "raw header buffer too small"; break;
2230 case MO_ERROR_OLD_RAW_HDR_FILE: msg = "old raw header file"; break;
2231 case MO_ERROR_UNSUPPORTED_VERS: msg = "unsupported version"; break;
2232 }
2233
2234 if (msg == (char *)0)
2235 fatal ("unknown {de,en}code_mach_o_hdr return value %d", status);
2236 else
2237 fatal ("%s", msg);
2238}
2239
2240\f
2241/* Read a file into a memory buffer. */
2242
2243static struct file_info *
2244read_file (name, fd, rw)
2245 char *name; /* filename */
2246 int fd; /* file descriptor */
2247 int rw; /* read/write */
2248{
2249 struct stat stat_pkt;
2250 struct file_info *p = (struct file_info *) xcalloc (sizeof (struct file_info), 1);
2251#ifdef USE_MMAP
2252 static int page_size;
2253#endif
2254
2255 if (fstat (fd, &stat_pkt) < 0)
2256 fatal_perror ("fstat %s", name);
2257
2258 p->name = name;
2259 p->size = stat_pkt.st_size;
2260 p->rounded_size = stat_pkt.st_size;
2261 p->fd = fd;
2262 p->rw = rw;
2263
2264#ifdef USE_MMAP
2265 if (debug)
2266 fprintf (stderr, "mmap %s, %s\n", name, (rw) ? "read/write" : "read-only");
2267
2268 if (page_size == 0)
2269 page_size = sysconf (_SC_PAGE_SIZE);
2270
2271 p->rounded_size = ((p->size + page_size - 1) / page_size) * page_size;
2272 p->start = mmap ((caddr_t)0,
2273 (rw) ? p->rounded_size : p->size,
2274 (rw) ? (PROT_READ | PROT_WRITE) : PROT_READ,
2275 MAP_FILE | MAP_VARIABLE | MAP_SHARED,
2276 fd,
2277 0L);
2278
2279 if (p->start != (char *)0 && p->start != (char *)-1)
2280 p->use_mmap = 1;
2281
2282 else
2283#endif /* USE_MMAP */
2284 {
2285 long len;
2286
2287 if (debug)
2288 fprintf (stderr, "read %s\n", name);
2289
2290 p->use_mmap = 0;
2291 p->start = xmalloc (p->size);
2292 if (lseek (fd, 0L, SEEK_SET) < 0)
2293 fatal_perror ("lseek to 0 on %s", name);
2294
2295 len = read (fd, p->start, p->size);
2296 if (len < 0)
2297 fatal_perror ("read %s", name);
2298
2299 if (len != p->size)
2300 fatal ("read %ld bytes, expected %ld, from %s", len, p->size, name);
2301 }
2302
2303 return p;
2304}
4e81a331
RS
2305\f
2306/* Do anything necessary to write a file back from memory. */
2307
2308static void
2309end_file (ptr)
2310 struct file_info *ptr; /* file information block */
2311{
2312#ifdef USE_MMAP
2313 if (ptr->use_mmap)
2314 {
2315 if (ptr->rw)
2316 {
2317 if (debug)
2318 fprintf (stderr, "msync %s\n", ptr->name);
2319
2320 if (msync (ptr->start, ptr->rounded_size, MS_ASYNC))
2321 fatal_perror ("msync %s", ptr->name);
2322 }
2323
2324 if (debug)
2325 fprintf (stderr, "munmap %s\n", ptr->name);
2326
2327 if (munmap (ptr->start, ptr->size))
2328 fatal_perror ("munmap %s", ptr->name);
2329 }
2330 else
2331#endif /* USE_MMAP */
2332 {
2333 if (ptr->rw)
2334 {
2335 long len;
2336
2337 if (debug)
2338 fprintf (stderr, "write %s\n", ptr->name);
2339
2340 if (lseek (ptr->fd, 0L, SEEK_SET) < 0)
2341 fatal_perror ("lseek to 0 on %s", ptr->name);
2342
2343 len = write (ptr->fd, ptr->start, ptr->size);
2344 if (len < 0)
2345 fatal_perror ("read %s", ptr->name);
2346
2347 if (len != ptr->size)
2348 fatal ("wrote %ld bytes, expected %ld, to %s", len, ptr->size, ptr->name);
2349 }
2350
2351 free ((generic *)ptr->start);
2352 }
2353
2354 free ((generic *)ptr);
2355}
2356
2357#endif /* OBJECT_FORMAT_ROSE */
This page took 0.348627 seconds and 5 git commands to generate.