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