1 /* Collect static initialization info into data structures
2 that can be traversed by C++ initialization and finalization
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).
10 This file is part of GNU CC.
12 GNU CC is free software; you can redistribute it and/or modify
13 it under the terms of the GNU General Public License as published by
14 the Free Software Foundation; either version 2, or (at your option)
17 GNU CC is distributed in the hope that it will be useful,
18 but WITHOUT ANY WARRANTY; without even the implied warranty of
19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 GNU General Public License for more details.
22 You should have received a copy of the GNU General Public License
23 along with GNU CC; see the file COPYING. If not, write to
24 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
27 /* Build tables of static constructors and destructors and run ld. */
29 #include <sys/types.h>
66 /* On MSDOS, write temp files in current dir
67 because there's no place else we can expect to use. */
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. */
79 #undef OBJECT_FORMAT_COFF
80 #undef OBJECT_FORMAT_ROSE
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. */
88 #if !defined (OBJECT_FORMAT_COFF) && !defined (OBJECT_FORMAT_ROSE)
89 #define OBJECT_FORMAT_NONE
92 #ifdef OBJECT_FORMAT_COFF
102 #define ISCOFF(magic) \
103 ((magic) == U802WRMAGIC || (magic) == U802ROMAGIC || (magic) == U802TOCMAGIC)
106 #if defined (_AIX) || defined (USG)
113 /* Mips-news overrides this macro. */
115 #define MY_ISCOFF(X) ISCOFF (X)
118 #endif /* OBJECT_FORMAT_COFF */
120 #ifdef OBJECT_FORMAT_ROSE
127 #include <sys/mman.h>
131 #include <mach_o_format.h>
132 #include <mach_o_header.h>
133 #include <mach_o_vals.h>
134 #include <mach_o_types.h>
136 #endif /* OBJECT_FORMAT_ROSE */
138 #ifdef OBJECT_FORMAT_NONE
140 /* Default flags to pass to nm. */
142 #define NM_FLAGS "-p"
145 #endif /* OBJECT_FORMAT_NONE */
147 /* Linked lists of constructor and destructor names. */
163 /* Enumeration giving which pass this is for scanning the program file. */
166 PASS_FIRST
, /* without constructors */
167 PASS_SECOND
/* with constructors linked in */
170 #ifndef NO_SYS_SIGLIST
171 extern char *sys_siglist
[];
173 extern char *version_string
;
175 static int vflag
; /* true if -v */
176 static int rflag
; /* true if -r */
177 static int strip_flag
; /* true if -s */
179 static int debug
; /* true if -debug */
181 static int temp_filename_length
; /* Length of temp_filename */
182 static char *temp_filename
; /* Base of temp filenames */
183 static char *c_file
; /* <xxx>.c for constructor/destructor list. */
184 static char *o_file
; /* <xxx>.o for constructor/destructor list. */
185 static char *nm_file_name
; /* pathname of nm */
186 static char *strip_file_name
; /* pathname of strip */
188 static struct head constructors
; /* list of constructors found */
189 static struct head destructors
; /* list of destructors found */
191 extern char *getenv ();
192 extern char *mktemp ();
193 static void add_to_list ();
194 static void scan_prog_file ();
195 static void fork_execute ();
196 static void do_wait ();
197 static void write_c_file ();
198 static void my_exit ();
199 static void handler ();
200 static void maybe_unlink ();
201 static void choose_temp_base ();
206 extern char *index ();
207 extern char *rindex ();
213 extern char *sys_errlist
[];
215 static char buffer
[30];
220 if (e
> 0 && e
< sys_nerr
)
221 return sys_errlist
[e
];
223 sprintf (buffer
, "Unknown error %d", e
);
227 /* Delete tempfiles and exit function. */
233 if (c_file
!= 0 && c_file
[0])
234 maybe_unlink (c_file
);
236 if (o_file
!= 0 && o_file
[0])
237 maybe_unlink (o_file
);
243 /* Die when sys call fails. */
246 fatal_perror (string
, arg1
, arg2
, arg3
)
251 fprintf (stderr
, "collect: ");
252 fprintf (stderr
, string
, arg1
, arg2
, arg3
);
253 fprintf (stderr
, ": %s\n", my_strerror (e
));
260 fatal (string
, arg1
, arg2
, arg3
)
263 fprintf (stderr
, "collect: ");
264 fprintf (stderr
, string
, arg1
, arg2
, arg3
);
265 fprintf (stderr
, "\n");
269 /* Write error message. */
272 error (string
, arg1
, arg2
, arg3
, arg4
)
275 fprintf (stderr
, "collect: ");
276 fprintf (stderr
, string
, arg1
, arg2
, arg3
, arg4
);
277 fprintf (stderr
, "\n");
280 /* In case obstack is linked in, and abort is defined to fancy_abort,
281 provide a default entry. */
286 fatal ("internal error");
295 maybe_unlink (c_file
);
298 maybe_unlink (o_file
);
300 signal (signo
, SIG_DFL
);
301 kill (getpid (), signo
);
306 xcalloc (size1
, size2
)
309 generic
*ptr
= (generic
*) calloc (size1
, size2
);
313 fatal ("out of memory");
321 generic
*ptr
= (generic
*) malloc (size
);
325 fatal ("out of memory");
329 /* Make a copy of a string INPUT with size SIZE. */
332 savestring (input
, size
)
336 char *output
= (char *) xmalloc (size
+ 1);
337 bcopy (input
, output
, size
);
342 /* Decide whether the given symbol is:
343 a constructor (1), a destructor (2), or neither (0). */
349 struct names
{ char *name
; int len
; int ret
; int two_underscores
; };
351 register struct names
*p
;
353 register char *orig_s
= s
;
355 static struct names special
[] = {
356 #ifdef NO_DOLLAR_IN_LABEL
357 { "GLOBAL_.I.", sizeof ("GLOBAL_.I.")-1, 1, 0 },
358 { "GLOBAL_.D.", sizeof ("GLOBAL_.D.")-1, 2, 0 },
360 { "GLOBAL_$I$", sizeof ("GLOBAL_$I$")-1, 1, 0 },
361 { "GLOBAL_$D$", sizeof ("GLOBAL_$I$")-1, 2, 0 },
363 { "sti__", sizeof ("sti__")-1, 1, 1 },
364 { "std__", sizeof ("std__")-1, 2, 1 },
368 while ((ch
= *s
) == '_')
374 for (p
= &special
[0]; p
->len
> 0; p
++)
377 && (!p
->two_underscores
|| ((s
- orig_s
) >= 2))
378 && strncmp(s
, p
->name
, p
->len
) == 0)
387 /* Compute a string to use as the base of all temporary file names.
388 It is substituted for %g. */
393 char *base
= getenv ("TMPDIR");
396 if (base
== (char *)0)
399 if (access (P_tmpdir
, R_OK
| W_OK
) == 0)
402 if (base
== (char *)0)
404 if (access ("/usr/tmp", R_OK
| W_OK
) == 0)
412 temp_filename
= xmalloc (len
+ sizeof("/ccXXXXXX"));
413 strcpy (temp_filename
, base
);
414 if (len
> 0 && temp_filename
[len
-1] != '/')
415 temp_filename
[len
++] = '/';
416 strcpy (temp_filename
+ len
, "ccXXXXXX");
418 mktemp (temp_filename
);
419 temp_filename_length
= strlen (temp_filename
);
430 char *outfile
= "a.out";
439 char **ld1_argv
= (char **) xcalloc (sizeof (char *), argc
+2);
440 char **ld1
= ld1_argv
;
441 char **ld2_argv
= (char **) xcalloc (sizeof (char *), argc
+5);
442 char **ld2
= ld2_argv
;
444 int num_c_args
= argc
+7;
453 p
= (char *) getenv ("COLLECT_GCC_OPTIONS");
458 while (*q
&& *q
!= ' ') q
++;
459 if (*p
== '-' && p
[1] == 'm')
466 c_ptr
= c_argv
= (char **) xcalloc (sizeof (char *), num_c_args
);
469 fatal ("no arguments");
471 signal (SIGQUIT
, handler
);
472 signal (SIGINT
, handler
);
473 signal (SIGALRM
, handler
);
474 signal (SIGHUP
, handler
);
475 signal (SIGSEGV
, handler
);
476 signal (SIGBUS
, handler
);
478 /* Try to discover a valid linker/assembler/nm/strip to use. */
479 len
= strlen (argv
[0]);
481 if (len
>= sizeof ("ld")-1)
483 p
= argv
[0] + len
- sizeof ("ld") + 1;
484 if (strcmp (p
, "ld") == 0)
491 if (prefix
== (char *)0)
493 p
= rindex (argv
[0], '/');
500 #ifdef STANDARD_EXEC_PREFIX
501 else if (access (STANDARD_EXEC_PREFIX
, X_OK
) == 0)
502 prefix
= STANDARD_EXEC_PREFIX
;
505 #ifdef MD_EXEC_PREFIX
506 else if (access (MD_EXEC_PREFIX
, X_OK
) == 0)
507 prefix
= MD_EXEC_PREFIX
;
510 else if (access ("/usr/ccs/gcc", X_OK
) == 0)
511 prefix
= "/usr/ccs/gcc/";
513 else if (access ("/usr/ccs/bin", X_OK
) == 0)
514 prefix
= "/usr/ccs/bin/";
520 clen
= len
= strlen (prefix
);
522 #ifdef STANDARD_BIN_PREFIX
523 if (clen
< sizeof (STANDARD_BIN_PREFIX
) - 1)
524 clen
= sizeof (STANDARD_BIN_PREFIX
) - 1;
527 #ifdef STANDARD_EXEC_PREFIX
528 if (clen
< sizeof (STANDARD_EXEC_PREFIX
) - 1)
529 clen
= sizeof (STANDARD_EXEC_PREFIX
) - 1;
532 /* Allocate enough string space for the longest possible pathnames. */
533 ld_file_name
= xcalloc (len
+ sizeof ("real-ld"), 1);
534 nm_file_name
= xcalloc (len
+ sizeof ("gnm"), 1);
535 strip_file_name
= xcalloc (len
+ sizeof ("gstrip"), 1);
537 /* Determine the full path name of the ld program to use. */
538 bcopy (prefix
, ld_file_name
, len
);
539 strcpy (ld_file_name
+ len
, "real-ld");
540 if (access (ld_file_name
, X_OK
) < 0)
542 strcpy (ld_file_name
+ len
, "gld");
543 if (access (ld_file_name
, X_OK
) < 0)
546 #ifdef REAL_LD_FILE_NAME
547 ld_file_name
= REAL_LD_FILE_NAME
;
549 ld_file_name
= (access ("/usr/bin/ld", X_OK
) == 0
550 ? "/usr/bin/ld" : "/bin/ld");
555 /* Determine the full path name of the C compiler to use. */
556 c_file_name
= getenv ("COLLECT_GCC");
557 if (c_file_name
== 0 || c_file_name
[0] != '/')
559 c_file_name
= xcalloc (clen
+ sizeof ("gcc"), 1);
560 bcopy (prefix
, c_file_name
, len
);
561 strcpy (c_file_name
+ len
, "gcc");
562 if (access (c_file_name
, X_OK
) < 0)
564 #ifdef STANDARD_BIN_PREFIX
565 strcpy (c_file_name
, STANDARD_BIN_PREFIX
);
566 strcat (c_file_name
, "gcc");
567 if (access (c_file_name
, X_OK
) < 0)
570 #ifdef STANDARD_EXEC_PREFIX
571 strcpy (c_file_name
, STANDARD_EXEC_PREFIX
);
572 strcat (c_file_name
, "gcc");
573 if (access (c_file_name
, X_OK
) < 0)
576 strcpy (c_file_name
, "gcc");
582 /* Determine the full path name of the nm to use. */
583 bcopy (prefix
, nm_file_name
, len
);
584 strcpy (nm_file_name
+ len
, "nm");
585 if (access (nm_file_name
, X_OK
) < 0)
587 strcpy (nm_file_name
+ len
, "gnm");
588 if (access (nm_file_name
, X_OK
) < 0)
591 #ifdef REAL_NM_FILE_NAME
592 nm_file_name
= REAL_NM_FILE_NAME
;
594 nm_file_name
= (access ("/usr/bin/nm", X_OK
) == 0
595 ? "/usr/bin/nm" : "/bin/nm");
600 /* Determine the full pathname of the strip to use. */
601 bcopy (prefix
, strip_file_name
, len
);
602 strcpy (strip_file_name
+ len
, "strip");
603 if (access (strip_file_name
, X_OK
) < 0)
605 strcpy (strip_file_name
+ len
, "gstrip");
606 if (access (strip_file_name
, X_OK
) < 0)
608 free (strip_file_name
);
609 #ifdef REAL_STRIP_FILE_NAME
610 strip_file_name
= REAL_STRIP_FILE_NAME
;
612 strip_file_name
= (access ("/usr/bin/strip", X_OK
) == 0
613 ? "/usr/bin/strip" : "/bin/strip");
618 *ld1
++ = *ld2
++ = "ld";
620 /* Make temp file names. */
622 c_file
= xcalloc (temp_filename_length
+ sizeof (".c"), 1);
623 o_file
= xcalloc (temp_filename_length
+ sizeof (".o"), 1);
624 sprintf (c_file
, "%s.c", temp_filename
);
625 sprintf (o_file
, "%s.o", temp_filename
);
626 *c_ptr
++ = c_file_name
;
631 /* !!! When GCC calls collect2,
632 it does not know whether it is calling collect2 or ld.
633 So collect2 cannot meaningfully understand any options
634 except those ld understands.
635 If you propose to make GCC pass some other option,
636 just imagine what will happen if ld is really ld!!! */
638 /* Parse arguments. Remember output file spec, pass the rest to ld. */
639 /* After the first file, put in the c++ rt0. */
642 while ((arg
= *++argv
) != (char *)0)
644 *ld1
++ = *ld2
++ = arg
;
650 if (!strcmp (arg
, "-debug"))
660 outfile
= (arg
[2] == '\0') ? argv
[1] : &arg
[2];
671 /* We must strip after the nm run, otherwise C++ linking
672 won't work. Thus we strip in the second ld run, or
673 else with strip if there is no second ld run. */
686 && (p
= rindex (arg
, '.')) != (char *)0
687 && strcmp (p
, ".o") == 0)
694 /* Get any options that the upper GCC wants to pass to the sub-GCC. */
695 p
= (char *) getenv ("COLLECT_GCC_OPTIONS");
700 while (*q
&& *q
!= ' ') q
++;
701 if (*p
== '-' && (p
[1] == 'm' || p
[1] == 'f'))
702 *c_ptr
++ = savestring (p
, q
- p
);
709 *c_ptr
= *ld1
= *ld2
= (char *)0;
713 fprintf (stderr
, "collect2 version %s", version_string
);
714 #ifdef TARGET_VERSION
717 fprintf (stderr
, "\n");
723 fprintf (stderr
, "prefix = %s\n", prefix
);
724 fprintf (stderr
, "ld_file_name = %s\n", ld_file_name
);
725 fprintf (stderr
, "c_file_name = %s\n", c_file_name
);
726 fprintf (stderr
, "nm_file_name = %s\n", nm_file_name
);
727 fprintf (stderr
, "c_file = %s\n", c_file
);
728 fprintf (stderr
, "o_file = %s\n", o_file
);
730 ptr
= getenv ("COLLECT_GCC_OPTIONS");
732 fprintf (stderr
, "COLLECT_GCC_OPTIONS = %s\n", ptr
);
734 ptr
= getenv ("COLLECT_GCC");
736 fprintf (stderr
, "COLLECT_GCC = %s\n", ptr
);
738 ptr
= getenv ("COMPILER_PATH");
740 fprintf (stderr
, "COMPILER_PATH = %s\n", ptr
);
742 ptr
= getenv ("LIBRARY_PATH");
744 fprintf (stderr
, "LIBRARY_PATH = %s\n", ptr
);
746 fprintf (stderr
, "\n");
749 /* Load the program, searching all libraries.
750 Examine the namelist with nm and search it for static constructors
751 and destructors to call.
752 Write the constructor and destructor tables to a .s file and reload. */
754 fork_execute (ld_file_name
, ld1_argv
);
756 /* If -r, don't build the constructor or destructor list, just return now. */
760 scan_prog_file (outfile
, PASS_FIRST
);
764 fprintf (stderr
, "%d constructor(s) found\n", constructors
.number
);
765 fprintf (stderr
, "%d destructor(s) found\n", destructors
.number
);
768 if (constructors
.number
== 0 && destructors
.number
== 0)
770 /* Strip now if it was requested on the command line. */
773 char **strip_argv
= (char **) xcalloc (sizeof (char *), 3);
774 strip_argv
[0] = "strip";
775 strip_argv
[1] = outfile
;
776 strip_argv
[2] = (char *) 0;
777 fork_execute (strip_file_name
, strip_argv
);
782 outf
= fopen (c_file
, "w");
783 if (outf
== (FILE *)0)
784 fatal_perror ("%s", c_file
);
786 write_c_file (outf
, c_file
);
789 fatal_perror ("closing %s", c_file
);
793 fprintf (stderr
, "\n========== outfile = %s, c_file = %s\n", outfile
, c_file
);
794 write_c_file (stderr
, "stderr");
795 fprintf (stderr
, "========== end of c_file\n\n");
798 /* Assemble the constructor and destructor tables.
799 Link the tables in with the rest of the program. */
801 fork_execute (c_file_name
, c_argv
);
802 fork_execute (ld_file_name
, ld2_argv
);
804 /* Let scan_prog_file do any final mods (OSF/rose needs this for
805 constructors/destructors in shared libraries. */
806 scan_prog_file (outfile
, PASS_SECOND
);
808 maybe_unlink (c_file
);
809 maybe_unlink (o_file
);
814 /* Wait for a process to finish, and exit if a non-zero status is found. */
825 int sig
= status
& 0x7F;
828 if (sig
!= -1 && sig
!= 0)
830 #ifdef NO_SYS_SIGLIST
831 error ("%s terminated with signal %d %s",
834 (status
& 0200) ? ", core dumped" : "");
836 error ("%s terminated with signal %d [%s]%s",
840 (status
& 0200) ? ", core dumped" : "");
846 ret
= ((status
& 0xFF00) >> 8);
847 if (ret
!= -1 && ret
!= 0)
849 error ("%s returned %d exit status", prog
, ret
);
856 /* Fork and execute a program, and wait for the reply. */
859 fork_execute (prog
, argv
)
864 void (*int_handler
) ();
865 void (*quit_handler
) ();
872 fprintf (stderr
, "%s", prog
);
873 for (p_argv
= &argv
[1]; (str
= *p_argv
) != (char *)0; p_argv
++)
874 fprintf (stderr
, " %s", str
);
876 fprintf (stderr
, "\n");
884 fatal_perror ("vfork");
886 if (pid
== 0) /* child context */
889 fatal_perror ("executing %s", prog
);
892 int_handler
= (void (*) ())signal (SIGINT
, SIG_IGN
);
893 quit_handler
= (void (*) ())signal (SIGQUIT
, SIG_IGN
);
897 signal (SIGINT
, int_handler
);
898 signal (SIGQUIT
, quit_handler
);
902 /* Unlink a file unless we are debugging. */
911 fprintf (stderr
, "[Leaving %s]\n", file
);
915 /* Add a name to a linked list. */
918 add_to_list (head_ptr
, name
)
919 struct head
*head_ptr
;
922 struct id
*newid
= (struct id
*) xcalloc (sizeof (*newid
) + strlen (name
), 1);
923 static long sequence_number
= 0;
924 newid
->sequence
= ++sequence_number
;
925 strcpy (newid
->name
, name
);
928 head_ptr
->last
->next
= newid
;
930 head_ptr
->first
= newid
;
932 head_ptr
->last
= newid
;
936 /* Write: `prefix', the names on list LIST, `suffix'. */
939 write_list (stream
, prefix
, list
)
946 fprintf (stream
, "%sx%d,\n", prefix
, list
->sequence
);
952 write_list_with_asm (stream
, prefix
, list
)
959 fprintf (stream
, "%sx%d asm (\"%s\");\n",
960 prefix
, list
->sequence
, list
->name
);
965 /* Write the constructor/destructor tables. */
968 write_c_file (stream
, name
)
972 /* Write the tables as C code */
974 fprintf (stream
, "typedef void entry_pt();\n\n");
976 write_list_with_asm (stream
, "extern entry_pt ", constructors
.first
);
978 fprintf (stream
, "\nentry_pt * __CTOR_LIST__[] = {\n");
979 fprintf (stream
, "\t(entry_pt *) %d,\n", constructors
.number
);
980 write_list (stream
, "\t", constructors
.first
);
981 fprintf (stream
, "\t0\n};\n\n");
983 write_list_with_asm (stream
, "extern entry_pt ", destructors
.first
);
985 fprintf (stream
, "\nentry_pt * __DTOR_LIST__[] = {\n");
986 fprintf (stream
, "\t(entry_pt *) %d,\n", destructors
.number
);
987 write_list (stream
, "\t", destructors
.first
);
988 fprintf (stream
, "\t0\n};\n\n");
990 fprintf (stream
, "extern entry_pt __main;\n");
991 fprintf (stream
, "entry_pt *__main_reference = __main;\n\n");
995 #ifdef OBJECT_FORMAT_NONE
997 /* Generic version to scan the name list of the loaded program for
998 the symbols g++ uses for static constructors and destructors.
1000 The constructor table begins at __CTOR_LIST__ and contains a count
1001 of the number of pointers (or -1 if the constructors are built in a
1002 separate section by the linker), followed by the pointers to the
1003 constructor functions, terminated with a null pointer. The
1004 destructor table has the same format, and begins at __DTOR_LIST__. */
1007 scan_prog_file (prog_name
, which_pass
)
1009 enum pass which_pass
;
1011 void (*int_handler
) ();
1012 void (*quit_handler
) ();
1020 if (which_pass
!= PASS_FIRST
)
1023 nm_argv
[argc
++] = "nm";
1024 if (NM_FLAGS
[0] != '\0')
1025 nm_argv
[argc
++] = NM_FLAGS
;
1027 nm_argv
[argc
++] = prog_name
;
1028 nm_argv
[argc
++] = (char *)0;
1030 if (pipe (pipe_fd
) < 0)
1031 fatal_perror ("pipe");
1033 inf
= fdopen (pipe_fd
[0], "r");
1034 if (inf
== (FILE *)0)
1035 fatal_perror ("fdopen");
1037 /* Trace if needed. */
1043 fprintf (stderr
, "%s", nm_file_name
);
1044 for (p_argv
= &nm_argv
[1]; (str
= *p_argv
) != (char *)0; p_argv
++)
1045 fprintf (stderr
, " %s", str
);
1047 fprintf (stderr
, "\n");
1053 /* Spawn child nm on pipe */
1056 fatal_perror ("vfork");
1058 if (pid
== 0) /* child context */
1061 if (dup2 (pipe_fd
[1], 1) < 0)
1062 fatal_perror ("dup2 (%d, 1)", pipe_fd
[1]);
1064 if (close (pipe_fd
[0]) < 0)
1065 fatal_perror ("close (%d)", pipe_fd
[0]);
1067 if (close (pipe_fd
[1]) < 0)
1068 fatal_perror ("close (%d)", pipe_fd
[1]);
1070 execv (nm_file_name
, nm_argv
);
1071 fatal_perror ("executing %s", nm_file_name
);
1074 /* Parent context from here on. */
1075 int_handler
= (void (*) ())signal (SIGINT
, SIG_IGN
);
1076 quit_handler
= (void (*) ())signal (SIGQUIT
, SIG_IGN
);
1078 if (close (pipe_fd
[1]) < 0)
1079 fatal_perror ("close (%d)", pipe_fd
[1]);
1082 fprintf (stderr
, "\nnm output with constructors/destructors.\n");
1084 /* Read each line of nm output. */
1085 while (fgets (buf
, sizeof buf
, inf
) != (char *)0)
1090 /* If it contains a constructor or destructor name, add the name
1091 to the appropriate list. */
1093 for (p
= buf
; (ch
= *p
) != '\0' && ch
!= '\n' && ch
!= '_'; p
++)
1096 if (ch
== '\0' || ch
== '\n')
1100 /* Find the end of the symbol name.
1101 Don't include `|', because Encore nm can tack that on the end. */
1102 for (end
= p
; (ch2
= *end
) != '\0' && !isspace (ch2
) && ch2
!= '|';
1107 switch (is_ctor_dtor (name
))
1110 add_to_list (&constructors
, name
);
1114 add_to_list (&destructors
, name
);
1117 default: /* not a constructor or destructor */
1122 fprintf (stderr
, "\t%s\n", buf
);
1126 fprintf (stderr
, "\n");
1128 if (fclose (inf
) != 0)
1129 fatal_perror ("fclose of pipe");
1131 do_wait (nm_file_name
);
1133 signal (SIGINT
, int_handler
);
1134 signal (SIGQUIT
, quit_handler
);
1137 #endif /* OBJECT_FORMAT_NONE */
1141 * COFF specific stuff.
1144 #ifdef OBJECT_FORMAT_COFF
1146 #if defined(EXTENDED_COFF)
1147 # define GCC_SYMBOLS(X) (SYMHEADER(X).isymMax + SYMHEADER(X).iextMax)
1148 # define GCC_SYMENT SYMR
1149 # define GCC_OK_SYMBOL(X) ((X).st == stProc && (X).sc == scText)
1150 # define GCC_SYMINC(X) (1)
1151 # define GCC_SYMZERO(X) (SYMHEADER(X).isymMax)
1152 # define GCC_CHECK_HDR(X) (PSYMTAB(X) != 0)
1154 # define GCC_SYMBOLS(X) (HEADER(ldptr).f_nsyms)
1155 # define GCC_SYMENT SYMENT
1156 # define GCC_OK_SYMBOL(X) \
1157 (((X).n_sclass == C_EXT) && \
1158 (((X).n_type & N_TMASK) == (DT_NON << N_BTSHFT) || \
1159 ((X).n_type & N_TMASK) == (DT_FCN << N_BTSHFT)))
1160 # define GCC_SYMINC(X) ((X).n_numaux+1)
1161 # define GCC_SYMZERO(X) 0
1162 # define GCC_CHECK_HDR(X) (1)
1165 extern char *ldgetname ();
1167 /* COFF version to scan the name list of the loaded program for
1168 the symbols g++ uses for static constructors and destructors.
1170 The constructor table begins at __CTOR_LIST__ and contains a count
1171 of the number of pointers (or -1 if the constructors are built in a
1172 separate section by the linker), followed by the pointers to the
1173 constructor functions, terminated with a null pointer. The
1174 destructor table has the same format, and begins at __DTOR_LIST__. */
1177 scan_prog_file (prog_name
, which_pass
)
1179 enum pass which_pass
;
1181 LDFILE
*ldptr
= NULL
;
1182 int sym_index
, sym_count
;
1184 if (which_pass
!= PASS_FIRST
)
1187 if ((ldptr
= ldopen (prog_name
, ldptr
)) == NULL
)
1188 fatal ("%s: can't open as COFF file", prog_name
);
1190 if (!MY_ISCOFF (HEADER (ldptr
).f_magic
))
1191 fatal ("%s: not a COFF file", prog_name
);
1193 if (GCC_CHECK_HDR (ldptr
))
1195 sym_count
= GCC_SYMBOLS (ldptr
);
1196 sym_index
= GCC_SYMZERO (ldptr
);
1197 while (sym_index
< sym_count
)
1201 if (ldtbread (ldptr
, sym_index
, &symbol
) <= 0)
1203 sym_index
+= GCC_SYMINC (symbol
);
1205 if (GCC_OK_SYMBOL (symbol
))
1209 if ((name
= ldgetname (ldptr
, &symbol
)) == NULL
)
1210 continue; /* should never happen */
1213 /* All AIX function names begin with a dot. */
1218 switch (is_ctor_dtor (name
))
1221 add_to_list (&constructors
, name
);
1225 add_to_list (&destructors
, name
);
1228 default: /* not a constructor or destructor */
1232 #if !defined(EXTENDED_COFF)
1234 fprintf (stderr
, "\tsec=%d class=%d type=%s%o %s\n",
1235 symbol
.n_scnum
, symbol
.n_sclass
,
1236 (symbol
.n_type
? "0" : ""), symbol
.n_type
,
1240 fprintf (stderr
, "\tiss = %5d, value = %5d, index = %5d, name = %s\n",
1241 symbol
.iss
, symbol
.value
, symbol
.index
, name
);
1247 (void) ldclose(ldptr
);
1250 #endif /* OBJECT_FORMAT_COFF */
1254 * OSF/rose specific stuff.
1257 #ifdef OBJECT_FORMAT_ROSE
1259 /* Union of the various load commands */
1261 typedef union load_union
1263 ldc_header_t hdr
; /* common header */
1264 load_cmd_map_command_t map
; /* map indexing other load cmds */
1265 interpreter_command_t iprtr
; /* interpreter pathname */
1266 strings_command_t str
; /* load commands strings section */
1267 region_command_t region
; /* region load command */
1268 reloc_command_t reloc
; /* relocation section */
1269 package_command_t pkg
; /* package load command */
1270 symbols_command_t sym
; /* symbol sections */
1271 entry_command_t ent
; /* program start section */
1272 gen_info_command_t info
; /* object information */
1273 func_table_command_t func
; /* function constructors/destructors */
1276 /* Structure to point to load command and data section in memory. */
1278 typedef struct load_all
1280 load_union_t
*load
; /* load command */
1281 char *section
; /* pointer to section */
1284 /* Structure to contain information about a file mapped into memory. */
1288 char *start
; /* start of map */
1289 char *name
; /* filename */
1290 long size
; /* size of the file */
1291 long rounded_size
; /* size rounded to page boundary */
1292 int fd
; /* file descriptor */
1293 int rw
; /* != 0 if opened read/write */
1294 int use_mmap
; /* != 0 if mmap'ed */
1297 extern int decode_mach_o_hdr ();
1299 extern int encode_mach_o_hdr ();
1301 static void bad_header ();
1303 static void print_header ();
1305 static void print_load_command ();
1307 static void add_func_table ();
1309 static struct file_info
*read_file ();
1311 static void end_file ();
1314 /* OSF/rose specific version to scan the name list of the loaded
1315 program for the symbols g++ uses for static constructors and
1318 The constructor table begins at __CTOR_LIST__ and contains a count
1319 of the number of pointers (or -1 if the constructors are built in a
1320 separate section by the linker), followed by the pointers to the
1321 constructor functions, terminated with a null pointer. The
1322 destructor table has the same format, and begins at __DTOR_LIST__. */
1325 scan_prog_file (prog_name
, which_pass
)
1327 enum pass which_pass
;
1331 load_all_t
*load_array
;
1332 load_all_t
*load_end
;
1333 load_all_t
*load_cmd
;
1334 int symbol_load_cmds
;
1340 struct file_info
*obj_file
;
1342 mo_lcid_t cmd_strings
= -1;
1343 symbol_info_t
*main_sym
= 0;
1344 int rw
= (which_pass
!= PASS_FIRST
);
1346 prog_fd
= open (prog_name
, (rw
) ? O_RDWR
: O_RDONLY
);
1348 fatal_perror ("can't read %s", prog_name
);
1350 obj_file
= read_file (prog_name
, prog_fd
, rw
);
1351 obj
= obj_file
->start
;
1353 status
= decode_mach_o_hdr (obj
, MO_SIZEOF_RAW_HDR
, MOH_HEADER_VERSION
, &hdr
);
1354 if (status
!= MO_HDR_CONV_SUCCESS
)
1355 bad_header (status
);
1358 /* Do some basic sanity checks. Note we explicitly use the big endian magic number,
1359 since the hardware will automatically swap bytes for us on loading little endian
1362 #ifndef CROSS_COMPILE
1363 if (hdr
.moh_magic
!= MOH_MAGIC_MSB
1364 || hdr
.moh_header_version
!= MOH_HEADER_VERSION
1365 || hdr
.moh_byte_order
!= OUR_BYTE_ORDER
1366 || hdr
.moh_data_rep_id
!= OUR_DATA_REP_ID
1367 || hdr
.moh_cpu_type
!= OUR_CPU_TYPE
1368 || hdr
.moh_cpu_subtype
!= OUR_CPU_SUBTYPE
1369 || hdr
.moh_vendor_type
!= OUR_VENDOR_TYPE
)
1371 fatal ("incompatibilities between object file & expected values");
1376 print_header (&hdr
);
1378 offset
= hdr
.moh_first_cmd_off
;
1379 load_end
= load_array
1380 = (load_all_t
*) xcalloc (sizeof (load_all_t
), hdr
.moh_n_load_cmds
+ 2);
1382 /* Build array of load commands, calculating the offsets */
1383 for (i
= 0; i
< hdr
.moh_n_load_cmds
; i
++)
1385 load_union_t
*load_hdr
; /* load command header */
1387 load_cmd
= load_end
++;
1388 load_hdr
= (load_union_t
*) (obj
+ offset
);
1390 /* If modifying the program file, copy the header. */
1393 load_union_t
*ptr
= (load_union_t
*) xmalloc (load_hdr
->hdr
.ldci_cmd_size
);
1394 bcopy ((generic
*)load_hdr
, (generic
*)ptr
, load_hdr
->hdr
.ldci_cmd_size
);
1397 /* null out old command map, because we will rewrite at the end. */
1398 if (ptr
->hdr
.ldci_cmd_type
== LDC_CMD_MAP
)
1400 cmd_strings
= ptr
->map
.lcm_ld_cmd_strings
;
1401 ptr
->hdr
.ldci_cmd_type
= LDC_UNDEFINED
;
1405 load_cmd
->load
= load_hdr
;
1406 if (load_hdr
->hdr
.ldci_section_off
> 0)
1407 load_cmd
->section
= obj
+ load_hdr
->hdr
.ldci_section_off
;
1410 print_load_command (load_hdr
, offset
, i
);
1412 offset
+= load_hdr
->hdr
.ldci_cmd_size
;
1415 /* If the last command is the load command map and is not undefined,
1416 decrement the count of load commands. */
1417 if (rw
&& load_end
[-1].load
->hdr
.ldci_cmd_type
== LDC_UNDEFINED
)
1420 hdr
.moh_n_load_cmds
--;
1423 /* Go through and process each symbol table section. */
1424 symbol_load_cmds
= 0;
1425 for (load_cmd
= load_array
; load_cmd
< load_end
; load_cmd
++)
1427 load_union_t
*load_hdr
= load_cmd
->load
;
1429 if (load_hdr
->hdr
.ldci_cmd_type
== LDC_SYMBOLS
)
1435 char *kind
= "unknown";
1437 switch (load_hdr
->sym
.symc_kind
)
1439 case SYMC_IMPORTS
: kind
= "imports"; break;
1440 case SYMC_DEFINED_SYMBOLS
: kind
= "defined"; break;
1441 case SYMC_STABS
: kind
= "stabs"; break;
1444 fprintf (stderr
, "\nProcessing symbol table #%d, offset = 0x%.8lx, kind = %s\n",
1445 symbol_load_cmds
, load_hdr
->hdr
.ldci_section_off
, kind
);
1448 if (load_hdr
->sym
.symc_kind
!= SYMC_DEFINED_SYMBOLS
)
1451 str_sect
= load_array
[load_hdr
->sym
.symc_strings_section
].section
;
1452 if (str_sect
== (char *)0)
1453 fatal ("string section missing");
1455 if (load_cmd
->section
== (char *)0)
1456 fatal ("section pointer missing");
1458 num_syms
= load_hdr
->sym
.symc_nentries
;
1459 for (i
= 0; i
< num_syms
; i
++)
1461 symbol_info_t
*sym
= ((symbol_info_t
*) load_cmd
->section
) + i
;
1462 char *name
= sym
->si_name
.symbol_name
+ str_sect
;
1472 if (*n
!= 'm' || (n
- name
) < 2 || strcmp (n
, "main"))
1479 switch (is_ctor_dtor (name
))
1482 add_to_list (&constructors
, name
);
1486 add_to_list (&destructors
, name
);
1489 default: /* not a constructor or destructor */
1495 fprintf (stderr
, "\ttype = 0x%.4x, sc = 0x%.2x, flags = 0x%.8x, name = %.30s\n",
1496 sym
->si_type
, sym
->si_sc_type
, sym
->si_flags
, name
);
1501 if (symbol_load_cmds
== 0)
1502 fatal ("no symbol table found");
1504 /* Update the program file now, rewrite header and load commands. At present,
1505 we assume that there is enough space after the last load command to insert
1506 one more. Since the first section written out is page aligned, and the
1507 number of load commands is small, this is ok for the present. */
1511 load_union_t
*load_map
;
1514 if (cmd_strings
== -1)
1515 fatal ("no cmd_strings found");
1517 /* Add __main to initializer list.
1518 If we are building a program instead of a shared library, don't
1519 do anything, since in the current version, you cannot do mallocs
1520 and such in the constructors. */
1522 if (main_sym
!= (symbol_info_t
*)0
1523 && ((hdr
.moh_flags
& MOH_EXECABLE_F
) == 0))
1524 add_func_table (&hdr
, load_array
, main_sym
, FNTC_INITIALIZATION
);
1527 fprintf (stderr
, "\nUpdating header and load commands.\n\n");
1529 hdr
.moh_n_load_cmds
++;
1530 size
= sizeof (load_cmd_map_command_t
) + (sizeof (mo_offset_t
) * (hdr
.moh_n_load_cmds
- 1));
1532 /* Create new load command map. */
1534 fprintf (stderr
, "load command map, %d cmds, new size %ld.\n",
1535 (int)hdr
.moh_n_load_cmds
, (long)size
);
1537 load_map
= (load_union_t
*) xcalloc (1, size
);
1538 load_map
->map
.ldc_header
.ldci_cmd_type
= LDC_CMD_MAP
;
1539 load_map
->map
.ldc_header
.ldci_cmd_size
= size
;
1540 load_map
->map
.lcm_ld_cmd_strings
= cmd_strings
;
1541 load_map
->map
.lcm_nentries
= hdr
.moh_n_load_cmds
;
1542 load_array
[hdr
.moh_n_load_cmds
-1].load
= load_map
;
1544 offset
= hdr
.moh_first_cmd_off
;
1545 for (i
= 0; i
< hdr
.moh_n_load_cmds
; i
++)
1547 load_map
->map
.lcm_map
[i
] = offset
;
1548 if (load_array
[i
].load
->hdr
.ldci_cmd_type
== LDC_CMD_MAP
)
1549 hdr
.moh_load_map_cmd_off
= offset
;
1551 offset
+= load_array
[i
].load
->hdr
.ldci_cmd_size
;
1554 hdr
.moh_sizeofcmds
= offset
- MO_SIZEOF_RAW_HDR
;
1557 print_header (&hdr
);
1560 status
= encode_mach_o_hdr (&hdr
, obj
, MO_SIZEOF_RAW_HDR
);
1561 if (status
!= MO_HDR_CONV_SUCCESS
)
1562 bad_header (status
);
1565 fprintf (stderr
, "writing load commands.\n\n");
1567 /* Write load commands */
1568 offset
= hdr
.moh_first_cmd_off
;
1569 for (i
= 0; i
< hdr
.moh_n_load_cmds
; i
++)
1571 load_union_t
*load_hdr
= load_array
[i
].load
;
1572 size_t size
= load_hdr
->hdr
.ldci_cmd_size
;
1575 print_load_command (load_hdr
, offset
, i
);
1577 bcopy ((generic
*)load_hdr
, (generic
*)(obj
+ offset
), size
);
1582 end_file (obj_file
);
1584 if (close (prog_fd
))
1585 fatal_perror ("closing %s", prog_name
);
1588 fprintf (stderr
, "\n");
1592 /* Add a function table to the load commands to call a function
1593 on initiation or termination of the process. */
1596 add_func_table (hdr_p
, load_array
, sym
, type
)
1597 mo_header_t
*hdr_p
; /* pointer to global header */
1598 load_all_t
*load_array
; /* array of ptrs to load cmds */
1599 symbol_info_t
*sym
; /* pointer to symbol entry */
1600 int type
; /* fntc_type value */
1602 /* Add a new load command. */
1603 int num_cmds
= ++hdr_p
->moh_n_load_cmds
;
1604 int load_index
= num_cmds
- 1;
1605 size_t size
= sizeof (func_table_command_t
) + sizeof (mo_addr_t
);
1606 load_union_t
*ptr
= xcalloc (1, size
);
1607 load_all_t
*load_cmd
;
1610 /* Set the unresolved address bit in the header to force the loader to be
1611 used, since kernel exec does not call the initialization functions. */
1612 hdr_p
->moh_flags
|= MOH_UNRESOLVED_F
;
1614 load_cmd
= &load_array
[load_index
];
1615 load_cmd
->load
= ptr
;
1616 load_cmd
->section
= (char *)0;
1618 /* Fill in func table load command. */
1619 ptr
->func
.ldc_header
.ldci_cmd_type
= LDC_FUNC_TABLE
;
1620 ptr
->func
.ldc_header
.ldci_cmd_size
= size
;
1621 ptr
->func
.ldc_header
.ldci_section_off
= 0;
1622 ptr
->func
.ldc_header
.ldci_section_len
= 0;
1623 ptr
->func
.fntc_type
= type
;
1624 ptr
->func
.fntc_nentries
= 1;
1626 /* copy address, turn it from abs. address to (region,offset) if necessary. */
1627 /* Is the symbol already expressed as (region, offset)? */
1628 if ((sym
->si_flags
& SI_ABSOLUTE_VALUE_F
) == 0)
1630 ptr
->func
.fntc_entry_loc
[i
].adr_lcid
= sym
->si_value
.def_val
.adr_lcid
;
1631 ptr
->func
.fntc_entry_loc
[i
].adr_sctoff
= sym
->si_value
.def_val
.adr_sctoff
;
1634 /* If not, figure out which region it's in. */
1637 mo_vm_addr_t addr
= sym
->si_value
.abs_val
;
1640 for (i
= 0; i
< load_index
; i
++)
1642 if (load_array
[i
].load
->hdr
.ldci_cmd_type
== LDC_REGION
)
1644 region_command_t
*region_ptr
= &load_array
[i
].load
->region
;
1646 if ((region_ptr
->regc_flags
& REG_ABS_ADDR_F
) != 0
1647 && addr
>= region_ptr
->regc_addr
.vm_addr
1648 && addr
<= region_ptr
->regc_addr
.vm_addr
+ region_ptr
->regc_vm_size
)
1650 ptr
->func
.fntc_entry_loc
[0].adr_lcid
= i
;
1651 ptr
->func
.fntc_entry_loc
[0].adr_sctoff
= addr
- region_ptr
->regc_addr
.vm_addr
;
1659 fatal ("could not convert 0x%l.8x into a region", addr
);
1664 "%s function, region %d, offset = %ld (0x%.8lx)\n",
1665 (type
== FNTC_INITIALIZATION
) ? "init" : "term",
1666 (int)ptr
->func
.fntc_entry_loc
[i
].adr_lcid
,
1667 (long)ptr
->func
.fntc_entry_loc
[i
].adr_sctoff
,
1668 (long)ptr
->func
.fntc_entry_loc
[i
].adr_sctoff
);
1673 /* Print the global header for an OSF/rose object. */
1676 print_header (hdr_ptr
)
1677 mo_header_t
*hdr_ptr
;
1679 fprintf (stderr
, "\nglobal header:\n");
1680 fprintf (stderr
, "\tmoh_magic = 0x%.8lx\n", hdr_ptr
->moh_magic
);
1681 fprintf (stderr
, "\tmoh_major_version = %d\n", (int)hdr_ptr
->moh_major_version
);
1682 fprintf (stderr
, "\tmoh_minor_version = %d\n", (int)hdr_ptr
->moh_minor_version
);
1683 fprintf (stderr
, "\tmoh_header_version = %d\n", (int)hdr_ptr
->moh_header_version
);
1684 fprintf (stderr
, "\tmoh_max_page_size = %d\n", (int)hdr_ptr
->moh_max_page_size
);
1685 fprintf (stderr
, "\tmoh_byte_order = %d\n", (int)hdr_ptr
->moh_byte_order
);
1686 fprintf (stderr
, "\tmoh_data_rep_id = %d\n", (int)hdr_ptr
->moh_data_rep_id
);
1687 fprintf (stderr
, "\tmoh_cpu_type = %d\n", (int)hdr_ptr
->moh_cpu_type
);
1688 fprintf (stderr
, "\tmoh_cpu_subtype = %d\n", (int)hdr_ptr
->moh_cpu_subtype
);
1689 fprintf (stderr
, "\tmoh_vendor_type = %d\n", (int)hdr_ptr
->moh_vendor_type
);
1690 fprintf (stderr
, "\tmoh_load_map_cmd_off = %d\n", (int)hdr_ptr
->moh_load_map_cmd_off
);
1691 fprintf (stderr
, "\tmoh_first_cmd_off = %d\n", (int)hdr_ptr
->moh_first_cmd_off
);
1692 fprintf (stderr
, "\tmoh_sizeofcmds = %d\n", (int)hdr_ptr
->moh_sizeofcmds
);
1693 fprintf (stderr
, "\tmon_n_load_cmds = %d\n", (int)hdr_ptr
->moh_n_load_cmds
);
1694 fprintf (stderr
, "\tmoh_flags = 0x%.8lx", (long)hdr_ptr
->moh_flags
);
1696 if (hdr_ptr
->moh_flags
& MOH_RELOCATABLE_F
)
1697 fprintf (stderr
, ", relocatable");
1699 if (hdr_ptr
->moh_flags
& MOH_LINKABLE_F
)
1700 fprintf (stderr
, ", linkable");
1702 if (hdr_ptr
->moh_flags
& MOH_EXECABLE_F
)
1703 fprintf (stderr
, ", execable");
1705 if (hdr_ptr
->moh_flags
& MOH_EXECUTABLE_F
)
1706 fprintf (stderr
, ", executable");
1708 if (hdr_ptr
->moh_flags
& MOH_UNRESOLVED_F
)
1709 fprintf (stderr
, ", unresolved");
1711 fprintf (stderr
, "\n\n");
1716 /* Print a short summary of a load command. */
1719 print_load_command (load_hdr
, offset
, number
)
1720 load_union_t
*load_hdr
;
1724 mo_long_t type
= load_hdr
->hdr
.ldci_cmd_type
;
1725 char *type_str
= (char *)0;
1729 case LDC_UNDEFINED
: type_str
= "UNDEFINED"; break;
1730 case LDC_CMD_MAP
: type_str
= "CMD_MAP"; break;
1731 case LDC_INTERPRETER
: type_str
= "INTERPRETER"; break;
1732 case LDC_STRINGS
: type_str
= "STRINGS"; break;
1733 case LDC_REGION
: type_str
= "REGION"; break;
1734 case LDC_RELOC
: type_str
= "RELOC"; break;
1735 case LDC_PACKAGE
: type_str
= "PACKAGE"; break;
1736 case LDC_SYMBOLS
: type_str
= "SYMBOLS"; break;
1737 case LDC_ENTRY
: type_str
= "ENTRY"; break;
1738 case LDC_FUNC_TABLE
: type_str
= "FUNC_TABLE"; break;
1739 case LDC_GEN_INFO
: type_str
= "GEN_INFO"; break;
1743 "cmd %2d, sz: 0x%.2lx, coff: 0x%.3lx, doff: 0x%.6lx, dlen: 0x%.6lx",
1745 (long) load_hdr
->hdr
.ldci_cmd_size
,
1747 (long) load_hdr
->hdr
.ldci_section_off
,
1748 (long) load_hdr
->hdr
.ldci_section_len
);
1750 if (type_str
== (char *)0)
1751 fprintf (stderr
, ", ty: unknown (%ld)\n", (long) type
);
1753 else if (type
!= LDC_REGION
)
1754 fprintf (stderr
, ", ty: %s\n", type_str
);
1759 switch (load_hdr
->region
.regc_usage_type
)
1761 case REG_TEXT_T
: region
= ", .text"; break;
1762 case REG_DATA_T
: region
= ", .data"; break;
1763 case REG_BSS_T
: region
= ", .bss"; break;
1764 case REG_GLUE_T
: region
= ", .glue"; break;
1765 #if defined (REG_RDATA_T) && defined (REG_SDATA_T) && defined (REG_SBSS_T) /*mips*/
1766 case REG_RDATA_T
: region
= ", .rdata"; break;
1767 case REG_SDATA_T
: region
= ", .sdata"; break;
1768 case REG_SBSS_T
: region
= ", .sbss"; break;
1772 fprintf (stderr
, ", ty: %s, vaddr: 0x%.8lx, vlen: 0x%.6lx%s\n",
1774 (long) load_hdr
->region
.regc_vm_addr
,
1775 (long) load_hdr
->region
.regc_vm_size
,
1783 /* Fatal error when {en,de}code_mach_o_header fails. */
1789 char *msg
= (char *)0;
1793 case MO_ERROR_BAD_MAGIC
: msg
= "bad magic number"; break;
1794 case MO_ERROR_BAD_HDR_VERS
: msg
= "bad header version"; break;
1795 case MO_ERROR_BAD_RAW_HDR_VERS
: msg
= "bad raw header version"; break;
1796 case MO_ERROR_BUF2SML
: msg
= "raw header buffer too small"; break;
1797 case MO_ERROR_OLD_RAW_HDR_FILE
: msg
= "old raw header file"; break;
1798 case MO_ERROR_UNSUPPORTED_VERS
: msg
= "unsupported version"; break;
1801 if (msg
== (char *)0)
1802 fatal ("unknown {de,en}code_mach_o_hdr return value %d", status
);
1808 /* Read a file into a memory buffer. */
1810 static struct file_info
*
1811 read_file (name
, fd
, rw
)
1812 char *name
; /* filename */
1813 int fd
; /* file descriptor */
1814 int rw
; /* read/write */
1816 struct stat stat_pkt
;
1817 struct file_info
*p
= (struct file_info
*) xcalloc (sizeof (struct file_info
), 1);
1819 static int page_size
;
1822 if (fstat (fd
, &stat_pkt
) < 0)
1823 fatal_perror ("fstat %s", name
);
1826 p
->size
= stat_pkt
.st_size
;
1827 p
->rounded_size
= stat_pkt
.st_size
;
1833 fprintf (stderr
, "mmap %s, %s\n", name
, (rw
) ? "read/write" : "read-only");
1836 page_size
= sysconf (_SC_PAGE_SIZE
);
1838 p
->rounded_size
= ((p
->size
+ page_size
- 1) / page_size
) * page_size
;
1839 p
->start
= mmap ((caddr_t
)0,
1840 (rw
) ? p
->rounded_size
: p
->size
,
1841 (rw
) ? (PROT_READ
| PROT_WRITE
) : PROT_READ
,
1842 MAP_FILE
| MAP_VARIABLE
| MAP_SHARED
,
1846 if (p
->start
!= (char *)0 && p
->start
!= (char *)-1)
1850 #endif /* USE_MMAP */
1855 fprintf (stderr
, "read %s\n", name
);
1858 p
->start
= xmalloc (p
->size
);
1859 if (lseek (fd
, 0L, SEEK_SET
) < 0)
1860 fatal_perror ("lseek to 0 on %s", name
);
1862 len
= read (fd
, p
->start
, p
->size
);
1864 fatal_perror ("read %s", name
);
1867 fatal ("read %ld bytes, expected %ld, from %s", len
, p
->size
, name
);
1874 /* Do anything necessary to write a file back from memory. */
1878 struct file_info
*ptr
; /* file information block */
1886 fprintf (stderr
, "msync %s\n", ptr
->name
);
1888 if (msync (ptr
->start
, ptr
->rounded_size
, MS_ASYNC
))
1889 fatal_perror ("msync %s", ptr
->name
);
1893 fprintf (stderr
, "munmap %s\n", ptr
->name
);
1895 if (munmap (ptr
->start
, ptr
->size
))
1896 fatal_perror ("munmap %s", ptr
->name
);
1899 #endif /* USE_MMAP */
1906 fprintf (stderr
, "write %s\n", ptr
->name
);
1908 if (lseek (ptr
->fd
, 0L, SEEK_SET
) < 0)
1909 fatal_perror ("lseek to 0 on %s", ptr
->name
);
1911 len
= write (ptr
->fd
, ptr
->start
, ptr
->size
);
1913 fatal_perror ("read %s", ptr
->name
);
1915 if (len
!= ptr
->size
)
1916 fatal ("wrote %ld bytes, expected %ld, to %s", len
, ptr
->size
, ptr
->name
);
1919 free ((generic
*)ptr
->start
);
1922 free ((generic
*)ptr
);
1925 #endif /* OBJECT_FORMAT_ROSE */