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