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