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>
65 /* On MSDOS, write temp files in current dir
66 because there's no place else we can expect to use. */
73 /* On certain systems, we have code that works by scanning the object file
74 directly. But this code uses system-specific header files and library
75 functions, so turn it off in a cross-compiler. */
78 #undef OBJECT_FORMAT_COFF
79 #undef OBJECT_FORMAT_ROSE
82 /* If we can't use a special method, use the ordinary one:
83 run nm to find what symbols are present.
84 In a cross-compiler, this means you need a cross nm,
85 but that isn't quite as unpleasant as special headers. */
87 #if !defined (OBJECT_FORMAT_COFF) && !defined (OBJECT_FORMAT_ROSE)
88 #define OBJECT_FORMAT_NONE
91 #ifdef OBJECT_FORMAT_COFF
101 #define ISCOFF(magic) \
102 ((magic) == U802WRMAGIC || (magic) == U802ROMAGIC || (magic) == U802TOCMAGIC)
105 #if defined (_AIX) || defined (USG)
112 #endif /* OBJECT_FORMAT_COFF */
114 #ifdef OBJECT_FORMAT_ROSE
121 #include <sys/mman.h>
125 #include <mach_o_format.h>
126 #include <mach_o_header.h>
127 #include <mach_o_vals.h>
128 #include <mach_o_types.h>
130 #endif /* OBJECT_FORMAT_ROSE */
132 #ifdef OBJECT_FORMAT_NONE
134 /* Default flags to pass to nm. */
136 #define NM_FLAGS "-p"
139 #endif /* OBJECT_FORMAT_NONE */
141 /* Linked lists of constructor and destructor names. */
157 /* Enumeration giving which pass this is for scanning the program file. */
160 PASS_FIRST
, /* without constructors */
161 PASS_SECOND
/* with constructors linked in */
164 #ifndef NO_SYS_SIGLIST
165 extern char *sys_siglist
[];
167 extern char *version_string
;
169 static int vflag
; /* true if -v */
170 static int rflag
; /* true if -r */
171 static int strip_flag
; /* true if -s */
173 static int debug
; /* true if -debug */
175 static int temp_filename_length
; /* Length of temp_filename */
176 static char *temp_filename
; /* Base of temp filenames */
177 static char *c_file
; /* <xxx>.c for constructor/destructor list. */
178 static char *o_file
; /* <xxx>.o for constructor/destructor list. */
179 static char *nm_file_name
; /* pathname of nm */
180 static char *strip_file_name
; /* pathname of strip */
182 static struct head constructors
; /* list of constructors found */
183 static struct head destructors
; /* list of destructors found */
185 extern char *getenv ();
186 extern char *mktemp ();
187 static void add_to_list ();
188 static void scan_prog_file ();
189 static void fork_execute ();
190 static void do_wait ();
191 static void write_c_file ();
192 static void my_exit ();
193 static void handler ();
194 static void maybe_unlink ();
195 static void choose_temp_base ();
204 extern char *sys_errlist
[];
206 static char buffer
[30];
211 if (e
> 0 && e
< sys_nerr
)
212 return sys_errlist
[e
];
214 sprintf (buffer
, "Unknown error %d", e
);
218 /* Delete tempfiles and exit function. */
224 if (c_file
!= 0 && c_file
[0])
225 maybe_unlink (c_file
);
227 if (o_file
!= 0 && o_file
[0])
228 maybe_unlink (o_file
);
234 /* Die when sys call fails. */
237 fatal_perror (string
, arg1
, arg2
, arg3
)
242 fprintf (stderr
, "collect: ");
243 fprintf (stderr
, string
, arg1
, arg2
, arg3
);
244 fprintf (stderr
, ": %s\n", my_strerror (e
));
251 fatal (string
, arg1
, arg2
, arg3
)
254 fprintf (stderr
, "collect: ");
255 fprintf (stderr
, string
, arg1
, arg2
, arg3
);
256 fprintf (stderr
, "\n");
260 /* Write error message. */
263 error (string
, arg1
, arg2
, arg3
, arg4
)
266 fprintf (stderr
, "collect: ");
267 fprintf (stderr
, string
, arg1
, arg2
, arg3
, arg4
);
268 fprintf (stderr
, "\n");
271 /* In case obstack is linked in, and abort is defined to fancy_abort,
272 provide a default entry. */
277 fatal ("internal error");
286 maybe_unlink (c_file
);
289 maybe_unlink (o_file
);
291 signal (signo
, SIG_DFL
);
292 kill (getpid (), signo
);
297 xcalloc (size1
, size2
)
300 generic
*ptr
= (generic
*) calloc (size1
, size2
);
304 fatal ("out of memory");
312 generic
*ptr
= (generic
*) malloc (size
);
316 fatal ("out of memory");
320 /* Make a copy of a string INPUT with size SIZE. */
323 savestring (input
, size
)
327 char *output
= (char *) xmalloc (size
+ 1);
328 bcopy (input
, output
, size
);
333 /* Decide whether the given symbol is:
334 a constructor (1), a destructor (2), or neither (0). */
340 struct names
{ char *name
; int len
; int ret
; int two_underscores
; };
342 register struct names
*p
;
344 register char *orig_s
= s
;
346 static struct names special
[] = {
347 #ifdef NO_DOLLAR_IN_LABEL
348 { "GLOBAL_.I.", sizeof ("GLOBAL_.I.")-1, 1, 0 },
349 { "GLOBAL_.D.", sizeof ("GLOBAL_.D.")-1, 2, 0 },
351 { "GLOBAL_$I$", sizeof ("GLOBAL_$I$")-1, 1, 0 },
352 { "GLOBAL_$D$", sizeof ("GLOBAL_$I$")-1, 2, 0 },
354 { "sti__", sizeof ("sti__")-1, 1, 1 },
355 { "std__", sizeof ("std__")-1, 2, 1 },
359 while ((ch
= *s
) == '_')
365 for (p
= &special
[0]; p
->len
> 0; p
++)
368 && (!p
->two_underscores
|| ((s
- orig_s
) >= 2))
369 && strncmp(s
, p
->name
, p
->len
) == 0)
378 /* Compute a string to use as the base of all temporary file names.
379 It is substituted for %g. */
384 char *base
= getenv ("TMPDIR");
387 if (base
== (char *)0)
390 if (access (P_tmpdir
, R_OK
| W_OK
) == 0)
393 if (base
== (char *)0)
395 if (access ("/usr/tmp", R_OK
| W_OK
) == 0)
403 temp_filename
= xmalloc (len
+ sizeof("/ccXXXXXX"));
404 strcpy (temp_filename
, base
);
405 if (len
> 0 && temp_filename
[len
-1] != '/')
406 temp_filename
[len
++] = '/';
407 strcpy (temp_filename
+ len
, "ccXXXXXX");
409 mktemp (temp_filename
);
410 temp_filename_length
= strlen (temp_filename
);
421 char *outfile
= "a.out";
430 char **ld1_argv
= (char **) xcalloc (sizeof (char *), argc
+2);
431 char **ld1
= ld1_argv
;
432 char **ld2_argv
= (char **) xcalloc (sizeof (char *), argc
+5);
433 char **ld2
= ld2_argv
;
435 int num_c_args
= argc
+7;
444 p
= (char *) getenv ("COLLECT_GCC_OPTIONS");
449 while (*q
&& *q
!= ' ') q
++;
450 if (*p
== '-' && p
[1] == 'm')
457 c_ptr
= c_argv
= (char **) xcalloc (sizeof (char *), num_c_args
);
460 fatal ("no arguments");
462 signal (SIGQUIT
, handler
);
463 signal (SIGINT
, handler
);
464 signal (SIGALRM
, handler
);
465 signal (SIGHUP
, handler
);
466 signal (SIGSEGV
, handler
);
467 signal (SIGBUS
, handler
);
469 /* Try to discover a valid linker/assembler/nm/strip to use. */
470 len
= strlen (argv
[0]);
472 if (len
>= sizeof ("ld")-1)
474 p
= argv
[0] + len
- sizeof ("ld") + 1;
475 if (strcmp (p
, "ld") == 0)
482 if (prefix
== (char *)0)
484 p
= strrchr (argv
[0], '/');
491 #ifdef STANDARD_EXEC_PREFIX
492 else if (access (STANDARD_EXEC_PREFIX
, X_OK
) == 0)
493 prefix
= STANDARD_EXEC_PREFIX
;
496 #ifdef MD_EXEC_PREFIX
497 else if (access (MD_EXEC_PREFIX
, X_OK
) == 0)
498 prefix
= MD_EXEC_PREFIX
;
501 else if (access ("/usr/ccs/gcc", X_OK
) == 0)
502 prefix
= "/usr/ccs/gcc/";
504 else if (access ("/usr/ccs/bin", X_OK
) == 0)
505 prefix
= "/usr/ccs/bin/";
511 clen
= len
= strlen (prefix
);
513 #ifdef STANDARD_BIN_PREFIX
514 if (clen
< sizeof (STANDARD_BIN_PREFIX
) - 1)
515 clen
= sizeof (STANDARD_BIN_PREFIX
) - 1;
518 #ifdef STANDARD_EXEC_PREFIX
519 if (clen
< sizeof (STANDARD_EXEC_PREFIX
) - 1)
520 clen
= sizeof (STANDARD_EXEC_PREFIX
) - 1;
523 /* Allocate enough string space for the longest possible pathnames. */
524 ld_file_name
= xcalloc (len
+ sizeof ("real-ld"), 1);
525 nm_file_name
= xcalloc (len
+ sizeof ("gnm"), 1);
526 strip_file_name
= xcalloc (len
+ sizeof ("gstrip"), 1);
528 /* Determine the full path name of the ld program to use. */
529 memcpy (ld_file_name
, prefix
, len
);
530 strcpy (ld_file_name
+ len
, "real-ld");
531 if (access (ld_file_name
, X_OK
) < 0)
533 strcpy (ld_file_name
+ len
, "gld");
534 if (access (ld_file_name
, X_OK
) < 0)
537 #ifdef REAL_LD_FILE_NAME
538 ld_file_name
= REAL_LD_FILE_NAME
;
540 ld_file_name
= (access ("/usr/bin/ld", X_OK
) == 0
541 ? "/usr/bin/ld" : "/bin/ld");
546 /* Determine the full path name of the C compiler to use. */
547 c_file_name
= getenv ("COLLECT_GCC");
548 if (c_file_name
== 0 || c_file_name
[0] != '/')
550 c_file_name
= xcalloc (clen
+ sizeof ("gcc"), 1);
551 memcpy (c_file_name
, prefix
, len
);
552 strcpy (c_file_name
+ len
, "gcc");
553 if (access (c_file_name
, X_OK
) < 0)
555 #ifdef STANDARD_BIN_PREFIX
556 strcpy (c_file_name
, STANDARD_BIN_PREFIX
);
557 strcat (c_file_name
, "gcc");
558 if (access (c_file_name
, X_OK
) < 0)
561 #ifdef STANDARD_EXEC_PREFIX
562 strcpy (c_file_name
, STANDARD_EXEC_PREFIX
);
563 strcat (c_file_name
, "gcc");
564 if (access (c_file_name
, X_OK
) < 0)
567 strcpy (c_file_name
, "gcc");
573 /* Determine the full path name of the nm to use. */
574 memcpy (nm_file_name
, prefix
, len
);
575 strcpy (nm_file_name
+ len
, "nm");
576 if (access (nm_file_name
, X_OK
) < 0)
578 strcpy (nm_file_name
+ len
, "gnm");
579 if (access (nm_file_name
, X_OK
) < 0)
582 #ifdef REAL_NM_FILE_NAME
583 nm_file_name
= REAL_NM_FILE_NAME
;
585 nm_file_name
= (access ("/usr/bin/nm", X_OK
) == 0
586 ? "/usr/bin/nm" : "/bin/nm");
591 /* Determine the full pathname of the strip to use. */
592 memcpy (strip_file_name
, prefix
, len
);
593 strcpy (strip_file_name
+ len
, "strip");
594 if (access (strip_file_name
, X_OK
) < 0)
596 strcpy (strip_file_name
+ len
, "gstrip");
597 if (access (strip_file_name
, X_OK
) < 0)
599 free (strip_file_name
);
600 #ifdef REAL_STRIP_FILE_NAME
601 strip_file_name
= REAL_STRIP_FILE_NAME
;
603 strip_file_name
= (access ("/usr/bin/strip", X_OK
) == 0
604 ? "/usr/bin/strip" : "/bin/strip");
609 *ld1
++ = *ld2
++ = "ld";
611 /* Make temp file names. */
613 c_file
= xcalloc (temp_filename_length
+ sizeof (".c"), 1);
614 o_file
= xcalloc (temp_filename_length
+ sizeof (".o"), 1);
615 sprintf (c_file
, "%s.c", temp_filename
);
616 sprintf (o_file
, "%s.o", temp_filename
);
617 *c_ptr
++ = c_file_name
;
622 /* !!! When GCC calls collect2,
623 it does not know whether it is calling collect2 or ld.
624 So collect2 cannot meaningfully understand any options
625 except those ld understands.
626 If you propose to make GCC pass some other option,
627 just imagine what will happen if ld is really ld!!! */
629 /* Parse arguments. Remember output file spec, pass the rest to ld. */
630 /* After the first file, put in the c++ rt0. */
633 while ((arg
= *++argv
) != (char *)0)
635 *ld1
++ = *ld2
++ = arg
;
641 if (!strcmp (arg
, "-debug"))
651 outfile
= (arg
[2] == '\0') ? argv
[1] : &arg
[2];
662 /* We must strip after the nm run, otherwise C++ linking
663 won't work. Thus we strip in the second ld run, or
664 else with strip if there is no second ld run. */
677 && (p
= strrchr (arg
, '.')) != (char *)0
678 && strcmp (p
, ".o") == 0)
685 /* Get any options that the upper GCC wants to pass to the sub-GCC. */
686 p
= (char *) getenv ("COLLECT_GCC_OPTIONS");
691 while (*q
&& *q
!= ' ') q
++;
692 if (*p
== '-' && (p
[1] == 'm' || p
[1] == 'f'))
693 *c_ptr
++ = savestring (p
, q
- p
);
700 *c_ptr
= *ld1
= *ld2
= (char *)0;
704 fprintf (stderr
, "collect2 version %s", version_string
);
705 #ifdef TARGET_VERSION
708 fprintf (stderr
, "\n");
714 fprintf (stderr
, "prefix = %s\n", prefix
);
715 fprintf (stderr
, "ld_file_name = %s\n", ld_file_name
);
716 fprintf (stderr
, "c_file_name = %s\n", c_file_name
);
717 fprintf (stderr
, "nm_file_name = %s\n", nm_file_name
);
718 fprintf (stderr
, "c_file = %s\n", c_file
);
719 fprintf (stderr
, "o_file = %s\n", o_file
);
721 ptr
= getenv ("COLLECT_GCC_OPTIONS");
723 fprintf (stderr
, "COLLECT_GCC_OPTIONS = %s\n", ptr
);
725 ptr
= getenv ("COLLECT_GCC");
727 fprintf (stderr
, "COLLECT_GCC = %s\n", ptr
);
729 ptr
= getenv ("COMPILER_PATH");
731 fprintf (stderr
, "COMPILER_PATH = %s\n", ptr
);
733 ptr
= getenv ("LIBRARY_PATH");
735 fprintf (stderr
, "LIBRARY_PATH = %s\n", ptr
);
737 fprintf (stderr
, "\n");
740 /* Load the program, searching all libraries.
741 Examine the namelist with nm and search it for static constructors
742 and destructors to call.
743 Write the constructor and destructor tables to a .s file and reload. */
745 fork_execute (ld_file_name
, ld1_argv
);
747 /* If -r, don't build the constructor or destructor list, just return now. */
751 scan_prog_file (outfile
, PASS_FIRST
);
755 fprintf (stderr
, "%d constructor(s) found\n", constructors
.number
);
756 fprintf (stderr
, "%d destructor(s) found\n", destructors
.number
);
759 if (constructors
.number
== 0 && destructors
.number
== 0)
761 /* Strip now if it was requested on the command line. */
764 char **strip_argv
= (char **) xcalloc (sizeof (char *), 3);
765 strip_argv
[0] = "strip";
766 strip_argv
[1] = outfile
;
767 strip_argv
[2] = (char *) 0;
768 fork_execute (strip_file_name
, strip_argv
);
773 outf
= fopen (c_file
, "w");
774 if (outf
== (FILE *)0)
775 fatal_perror ("%s", c_file
);
777 write_c_file (outf
, c_file
);
780 fatal_perror ("closing %s", c_file
);
784 fprintf (stderr
, "\n========== outfile = %s, c_file = %s\n", outfile
, c_file
);
785 write_c_file (stderr
, "stderr");
786 fprintf (stderr
, "========== end of c_file\n\n");
789 /* Assemble the constructor and destructor tables.
790 Link the tables in with the rest of the program. */
792 fork_execute (c_file_name
, c_argv
);
793 fork_execute (ld_file_name
, ld2_argv
);
795 /* Let scan_prog_file do any final mods (OSF/rose needs this for
796 constructors/destructors in shared libraries. */
797 scan_prog_file (outfile
, PASS_SECOND
);
799 maybe_unlink (c_file
);
800 maybe_unlink (o_file
);
805 /* Wait for a process to finish, and exit if a non-zero status is found. */
816 int sig
= status
& 0x7F;
819 if (sig
!= -1 && sig
!= 0)
821 #ifdef NO_SYS_SIGLIST
822 error ("%s terminated with signal %d %s",
825 (status
& 0200) ? ", core dumped" : "");
827 error ("%s terminated with signal %d [%s]%s",
831 (status
& 0200) ? ", core dumped" : "");
837 ret
= ((status
& 0xFF00) >> 8);
838 if (ret
!= -1 && ret
!= 0)
840 error ("%s returned %d exit status", prog
, ret
);
847 /* Fork and execute a program, and wait for the reply. */
850 fork_execute (prog
, argv
)
855 void (*int_handler
) ();
856 void (*quit_handler
) ();
863 fprintf (stderr
, "%s", prog
);
864 for (p_argv
= &argv
[1]; (str
= *p_argv
) != (char *)0; p_argv
++)
865 fprintf (stderr
, " %s", str
);
867 fprintf (stderr
, "\n");
875 fatal_perror ("vfork");
877 if (pid
== 0) /* child context */
880 fatal_perror ("executing %s", prog
);
883 int_handler
= (void (*) ())signal (SIGINT
, SIG_IGN
);
884 quit_handler
= (void (*) ())signal (SIGQUIT
, SIG_IGN
);
888 signal (SIGINT
, int_handler
);
889 signal (SIGQUIT
, quit_handler
);
893 /* Unlink a file unless we are debugging. */
902 fprintf (stderr
, "[Leaving %s]\n", file
);
906 /* Add a name to a linked list. */
909 add_to_list (head_ptr
, name
)
910 struct head
*head_ptr
;
913 struct id
*newid
= (struct id
*) xcalloc (sizeof (*newid
) + strlen (name
), 1);
914 static long sequence_number
= 0;
915 newid
->sequence
= ++sequence_number
;
916 strcpy (newid
->name
, name
);
919 head_ptr
->last
->next
= newid
;
921 head_ptr
->first
= newid
;
923 head_ptr
->last
= newid
;
927 /* Write: `prefix', the names on list LIST, `suffix'. */
930 write_list (stream
, prefix
, list
)
937 fprintf (stream
, "%sx%d,\n", prefix
, list
->sequence
);
943 write_list_with_asm (stream
, prefix
, list
)
950 fprintf (stream
, "%sx%d asm (\"%s\");\n",
951 prefix
, list
->sequence
, list
->name
);
956 /* Write the constructor/destructor tables. */
959 write_c_file (stream
, name
)
963 /* Write the tables as C code */
965 fprintf (stream
, "typedef void entry_pt();\n\n");
967 write_list_with_asm (stream
, "extern entry_pt ", constructors
.first
);
969 fprintf (stream
, "\nentry_pt * __CTOR_LIST__[] = {\n");
970 fprintf (stream
, "\t(entry_pt *) %d,\n", constructors
.number
);
971 write_list (stream
, "\t", constructors
.first
);
972 fprintf (stream
, "\t0\n};\n\n");
974 write_list_with_asm (stream
, "extern entry_pt ", destructors
.first
);
976 fprintf (stream
, "\nentry_pt * __DTOR_LIST__[] = {\n");
977 fprintf (stream
, "\t(entry_pt *) %d,\n", destructors
.number
);
978 write_list (stream
, "\t", destructors
.first
);
979 fprintf (stream
, "\t0\n};\n\n");
981 fprintf (stream
, "extern entry_pt __main;\n");
982 fprintf (stream
, "entry_pt *__main_reference = __main;\n\n");
986 #ifdef OBJECT_FORMAT_NONE
988 /* Generic version to scan the name list of the loaded program for
989 the symbols g++ uses for static constructors and destructors.
991 The constructor table begins at __CTOR_LIST__ and contains a count
992 of the number of pointers (or -1 if the constructors are built in a
993 separate section by the linker), followed by the pointers to the
994 constructor functions, terminated with a null pointer. The
995 destructor table has the same format, and begins at __DTOR_LIST__. */
998 scan_prog_file (prog_name
, which_pass
)
1000 enum pass which_pass
;
1002 void (*int_handler
) ();
1003 void (*quit_handler
) ();
1011 if (which_pass
!= PASS_FIRST
)
1014 nm_argv
[argc
++] = "nm";
1015 if (NM_FLAGS
[0] != '\0')
1016 nm_argv
[argc
++] = NM_FLAGS
;
1018 nm_argv
[argc
++] = prog_name
;
1019 nm_argv
[argc
++] = (char *)0;
1021 if (pipe (pipe_fd
) < 0)
1022 fatal_perror ("pipe");
1024 inf
= fdopen (pipe_fd
[0], "r");
1025 if (inf
== (FILE *)0)
1026 fatal_perror ("fdopen");
1028 /* Trace if needed. */
1034 fprintf (stderr
, "%s", nm_file_name
);
1035 for (p_argv
= &nm_argv
[1]; (str
= *p_argv
) != (char *)0; p_argv
++)
1036 fprintf (stderr
, " %s", str
);
1038 fprintf (stderr
, "\n");
1044 /* Spawn child nm on pipe */
1047 fatal_perror ("vfork");
1049 if (pid
== 0) /* child context */
1052 if (dup2 (pipe_fd
[1], 1) < 0)
1053 fatal_perror ("dup2 (%d, 1)", pipe_fd
[1]);
1055 if (close (pipe_fd
[0]) < 0)
1056 fatal_perror ("close (%d)", pipe_fd
[0]);
1058 if (close (pipe_fd
[1]) < 0)
1059 fatal_perror ("close (%d)", pipe_fd
[1]);
1061 execv (nm_file_name
, nm_argv
);
1062 fatal_perror ("executing %s", nm_file_name
);
1065 /* Parent context from here on. */
1066 int_handler
= (void (*) ())signal (SIGINT
, SIG_IGN
);
1067 quit_handler
= (void (*) ())signal (SIGQUIT
, SIG_IGN
);
1069 if (close (pipe_fd
[1]) < 0)
1070 fatal_perror ("close (%d)", pipe_fd
[1]);
1073 fprintf (stderr
, "\nnm output with constructors/destructors.\n");
1075 /* Read each line of nm output. */
1076 while (fgets (buf
, sizeof buf
, inf
) != (char *)0)
1081 /* If it contains a constructor or destructor name, add the name
1082 to the appropriate list. */
1084 for (p
= buf
; (ch
= *p
) != '\0' && ch
!= '\n' && ch
!= '_'; p
++)
1087 if (ch
== '\0' || ch
== '\n')
1091 /* Find the end of the symbol name.
1092 Don't include `|', because Encore nm can tack that on the end. */
1093 for (end
= p
; (ch2
= *end
) != '\0' && !isspace (ch2
) && ch2
!= '|';
1098 switch (is_ctor_dtor (name
))
1101 add_to_list (&constructors
, name
);
1105 add_to_list (&destructors
, name
);
1108 default: /* not a constructor or destructor */
1113 fprintf (stderr
, "\t%s\n", buf
);
1117 fprintf (stderr
, "\n");
1119 if (fclose (inf
) != 0)
1120 fatal_perror ("fclose of pipe");
1122 do_wait (nm_file_name
);
1124 signal (SIGINT
, int_handler
);
1125 signal (SIGQUIT
, quit_handler
);
1128 #endif /* OBJECT_FORMAT_NONE */
1132 * COFF specific stuff.
1135 #ifdef OBJECT_FORMAT_COFF
1137 #if defined(EXTENDED_COFF)
1138 # define GCC_SYMBOLS(X) (SYMHEADER(X).isymMax + SYMHEADER(X).iextMax)
1139 # define GCC_SYMENT SYMR
1140 # define GCC_OK_SYMBOL(X) ((X).st == stProc && (X).sc == scText)
1141 # define GCC_SYMINC(X) (1)
1142 # define GCC_SYMZERO(X) (SYMHEADER(X).isymMax)
1143 # define GCC_CHECK_HDR(X) (PSYMTAB(X) != 0)
1145 # define GCC_SYMBOLS(X) (HEADER(ldptr).f_nsyms)
1146 # define GCC_SYMENT SYMENT
1147 # define GCC_OK_SYMBOL(X) \
1148 (((X).n_sclass == C_EXT) && \
1149 (((X).n_type & N_TMASK) == (DT_NON << N_BTSHFT) || \
1150 ((X).n_type & N_TMASK) == (DT_FCN << N_BTSHFT)))
1151 # define GCC_SYMINC(X) ((X).n_numaux+1)
1152 # define GCC_SYMZERO(X) 0
1153 # define GCC_CHECK_HDR(X) (1)
1156 extern char *ldgetname ();
1158 /* COFF version to scan the name list of the loaded program for
1159 the symbols g++ uses for static constructors and destructors.
1161 The constructor table begins at __CTOR_LIST__ and contains a count
1162 of the number of pointers (or -1 if the constructors are built in a
1163 separate section by the linker), followed by the pointers to the
1164 constructor functions, terminated with a null pointer. The
1165 destructor table has the same format, and begins at __DTOR_LIST__. */
1168 scan_prog_file (prog_name
, which_pass
)
1170 enum pass which_pass
;
1173 int sym_index
, sym_count
;
1175 if (which_pass
!= PASS_FIRST
)
1178 if ((ldptr
= ldopen (prog_name
, ldptr
)) == NULL
)
1179 fatal ("%s: can't open as COFF file", prog_name
);
1181 if (!ISCOFF (HEADER(ldptr
).f_magic
))
1182 fatal ("%s: not a COFF file", prog_name
);
1184 if (GCC_CHECK_HDR (ldptr
))
1186 sym_count
= GCC_SYMBOLS (ldptr
);
1187 sym_index
= GCC_SYMZERO (ldptr
);
1188 while (sym_index
< sym_count
)
1192 if (ldtbread (ldptr
, sym_index
, &symbol
) <= 0)
1194 sym_index
+= GCC_SYMINC (symbol
);
1196 if (GCC_OK_SYMBOL (symbol
))
1200 if ((name
= ldgetname (ldptr
, &symbol
)) == NULL
)
1201 continue; /* should never happen */
1204 /* All AIX function names begin with a dot. */
1209 switch (is_ctor_dtor (name
))
1212 add_to_list (&constructors
, name
);
1216 add_to_list (&destructors
, name
);
1219 default: /* not a constructor or destructor */
1223 #if !defined(EXTENDED_COFF)
1225 fprintf (stderr
, "\tsec=%d class=%d type=%s%o %s\n",
1226 symbol
.n_scnum
, symbol
.n_sclass
,
1227 (symbol
.n_type
? "0" : ""), symbol
.n_type
,
1231 fprintf (stderr
, "\tiss = %5d, value = %5d, index = %5d, name = %s\n",
1232 symbol
.iss
, symbol
.value
, symbol
.index
, name
);
1238 (void) ldclose(ldptr
);
1241 #endif /* OBJECT_FORMAT_COFF */
1245 * OSF/rose specific stuff.
1248 #ifdef OBJECT_FORMAT_ROSE
1250 /* Union of the various load commands */
1252 typedef union load_union
1254 ldc_header_t hdr
; /* common header */
1255 load_cmd_map_command_t map
; /* map indexing other load cmds */
1256 interpreter_command_t iprtr
; /* interpreter pathname */
1257 strings_command_t str
; /* load commands strings section */
1258 region_command_t region
; /* region load command */
1259 reloc_command_t reloc
; /* relocation section */
1260 package_command_t pkg
; /* package load command */
1261 symbols_command_t sym
; /* symbol sections */
1262 entry_command_t ent
; /* program start section */
1263 gen_info_command_t info
; /* object information */
1264 func_table_command_t func
; /* function constructors/destructors */
1267 /* Structure to point to load command and data section in memory. */
1269 typedef struct load_all
1271 load_union_t
*load
; /* load command */
1272 char *section
; /* pointer to section */
1275 /* Structure to contain information about a file mapped into memory. */
1279 char *start
; /* start of map */
1280 char *name
; /* filename */
1281 long size
; /* size of the file */
1282 long rounded_size
; /* size rounded to page boundary */
1283 int fd
; /* file descriptor */
1284 int rw
; /* != 0 if opened read/write */
1285 int use_mmap
; /* != 0 if mmap'ed */
1288 extern int decode_mach_o_hdr ();
1290 extern int encode_mach_o_hdr ();
1292 static void bad_header ();
1294 static void print_header ();
1296 static void print_load_command ();
1298 static void add_func_table ();
1300 static struct file_info
*read_file ();
1302 static void end_file ();
1305 /* OSF/rose specific version to scan the name list of the loaded
1306 program for the symbols g++ uses for static constructors and
1309 The constructor table begins at __CTOR_LIST__ and contains a count
1310 of the number of pointers (or -1 if the constructors are built in a
1311 separate section by the linker), followed by the pointers to the
1312 constructor functions, terminated with a null pointer. The
1313 destructor table has the same format, and begins at __DTOR_LIST__. */
1316 scan_prog_file (prog_name
, which_pass
)
1318 enum pass which_pass
;
1322 load_all_t
*load_array
;
1323 load_all_t
*load_end
;
1324 load_all_t
*load_cmd
;
1325 int symbol_load_cmds
;
1331 struct file_info
*obj_file
;
1333 mo_lcid_t cmd_strings
= -1;
1334 symbol_info_t
*main_sym
= 0;
1335 int rw
= (which_pass
!= PASS_FIRST
);
1337 prog_fd
= open (prog_name
, (rw
) ? O_RDWR
: O_RDONLY
);
1339 fatal_perror ("can't read %s", prog_name
);
1341 obj_file
= read_file (prog_name
, prog_fd
, rw
);
1342 obj
= obj_file
->start
;
1344 status
= decode_mach_o_hdr (obj
, MO_SIZEOF_RAW_HDR
, MOH_HEADER_VERSION
, &hdr
);
1345 if (status
!= MO_HDR_CONV_SUCCESS
)
1346 bad_header (status
);
1349 /* Do some basic sanity checks. Note we explicitly use the big endian magic number,
1350 since the hardware will automatically swap bytes for us on loading little endian
1353 #ifndef CROSS_COMPILE
1354 if (hdr
.moh_magic
!= MOH_MAGIC_MSB
1355 || hdr
.moh_header_version
!= MOH_HEADER_VERSION
1356 || hdr
.moh_byte_order
!= OUR_BYTE_ORDER
1357 || hdr
.moh_data_rep_id
!= OUR_DATA_REP_ID
1358 || hdr
.moh_cpu_type
!= OUR_CPU_TYPE
1359 || hdr
.moh_cpu_subtype
!= OUR_CPU_SUBTYPE
1360 || hdr
.moh_vendor_type
!= OUR_VENDOR_TYPE
)
1362 fatal ("incompatibilities between object file & expected values");
1367 print_header (&hdr
);
1369 offset
= hdr
.moh_first_cmd_off
;
1370 load_end
= load_array
1371 = (load_all_t
*) xcalloc (sizeof (load_all_t
), hdr
.moh_n_load_cmds
+ 2);
1373 /* Build array of load commands, calculating the offsets */
1374 for (i
= 0; i
< hdr
.moh_n_load_cmds
; i
++)
1376 load_union_t
*load_hdr
; /* load command header */
1378 load_cmd
= load_end
++;
1379 load_hdr
= (load_union_t
*) (obj
+ offset
);
1381 /* If modifing the program file, copy the header. */
1384 load_union_t
*ptr
= (load_union_t
*) xmalloc (load_hdr
->hdr
.ldci_cmd_size
);
1385 memcpy (ptr
, load_hdr
, load_hdr
->hdr
.ldci_cmd_size
);
1388 /* null out old command map, because we will rewrite at the end. */
1389 if (ptr
->hdr
.ldci_cmd_type
== LDC_CMD_MAP
)
1391 cmd_strings
= ptr
->map
.lcm_ld_cmd_strings
;
1392 ptr
->hdr
.ldci_cmd_type
= LDC_UNDEFINED
;
1396 load_cmd
->load
= load_hdr
;
1397 if (load_hdr
->hdr
.ldci_section_off
> 0)
1398 load_cmd
->section
= obj
+ load_hdr
->hdr
.ldci_section_off
;
1401 print_load_command (load_hdr
, offset
, i
);
1403 offset
+= load_hdr
->hdr
.ldci_cmd_size
;
1406 /* If the last command is the load command map and is not undefined,
1407 decrement the count of load commands. */
1408 if (rw
&& load_end
[-1].load
->hdr
.ldci_cmd_type
== LDC_UNDEFINED
)
1411 hdr
.moh_n_load_cmds
--;
1414 /* Go through and process each symbol table section. */
1415 symbol_load_cmds
= 0;
1416 for (load_cmd
= load_array
; load_cmd
< load_end
; load_cmd
++)
1418 load_union_t
*load_hdr
= load_cmd
->load
;
1420 if (load_hdr
->hdr
.ldci_cmd_type
== LDC_SYMBOLS
)
1426 char *kind
= "unknown";
1428 switch (load_hdr
->sym
.symc_kind
)
1430 case SYMC_IMPORTS
: kind
= "imports"; break;
1431 case SYMC_DEFINED_SYMBOLS
: kind
= "defined"; break;
1432 case SYMC_STABS
: kind
= "stabs"; break;
1435 fprintf (stderr
, "\nProcessing symbol table #%d, offset = 0x%.8lx, kind = %s\n",
1436 symbol_load_cmds
, load_hdr
->hdr
.ldci_section_off
, kind
);
1439 if (load_hdr
->sym
.symc_kind
!= SYMC_DEFINED_SYMBOLS
)
1442 str_sect
= load_array
[load_hdr
->sym
.symc_strings_section
].section
;
1443 if (str_sect
== (char *)0)
1444 fatal ("string section missing");
1446 if (load_cmd
->section
== (char *)0)
1447 fatal ("section pointer missing");
1449 num_syms
= load_hdr
->sym
.symc_nentries
;
1450 for (i
= 0; i
< num_syms
; i
++)
1452 symbol_info_t
*sym
= ((symbol_info_t
*) load_cmd
->section
) + i
;
1453 char *name
= sym
->si_name
.symbol_name
+ str_sect
;
1463 if (*n
!= 'm' || (n
- name
) < 2 || strcmp (n
, "main"))
1470 switch (is_ctor_dtor (name
))
1473 add_to_list (&constructors
, name
);
1477 add_to_list (&destructors
, name
);
1480 default: /* not a constructor or destructor */
1486 fprintf (stderr
, "\ttype = 0x%.4x, sc = 0x%.2x, flags = 0x%.8x, name = %.30s\n",
1487 sym
->si_type
, sym
->si_sc_type
, sym
->si_flags
, name
);
1492 if (symbol_load_cmds
== 0)
1493 fatal ("no symbol table found");
1495 /* Update the program file now, rewrite header and load commands. At present,
1496 we assume that there is enough space after the last load command to insert
1497 one more. Since the first section written out is page aligned, and the
1498 number of load commands is small, this is ok for the present. */
1502 load_union_t
*load_map
;
1505 if (cmd_strings
== -1)
1506 fatal ("no cmd_strings found");
1508 /* Add __main to initializer list.
1509 If we are building a program instead of a shared library, don't
1510 do anything, since in the current version, you cannot do mallocs
1511 and such in the constructors. */
1513 if (main_sym
!= (symbol_info_t
*)0
1514 && ((hdr
.moh_flags
& MOH_EXECABLE_F
) == 0))
1515 add_func_table (&hdr
, load_array
, main_sym
, FNTC_INITIALIZATION
);
1518 fprintf (stderr
, "\nUpdating header and load commands.\n\n");
1520 hdr
.moh_n_load_cmds
++;
1521 size
= sizeof (load_cmd_map_command_t
) + (sizeof (mo_offset_t
) * (hdr
.moh_n_load_cmds
- 1));
1523 /* Create new load command map. */
1525 fprintf (stderr
, "load command map, %d cmds, new size %ld.\n",
1526 (int)hdr
.moh_n_load_cmds
, (long)size
);
1528 load_map
= (load_union_t
*) xcalloc (1, size
);
1529 load_map
->map
.ldc_header
.ldci_cmd_type
= LDC_CMD_MAP
;
1530 load_map
->map
.ldc_header
.ldci_cmd_size
= size
;
1531 load_map
->map
.lcm_ld_cmd_strings
= cmd_strings
;
1532 load_map
->map
.lcm_nentries
= hdr
.moh_n_load_cmds
;
1533 load_array
[hdr
.moh_n_load_cmds
-1].load
= load_map
;
1535 offset
= hdr
.moh_first_cmd_off
;
1536 for (i
= 0; i
< hdr
.moh_n_load_cmds
; i
++)
1538 load_map
->map
.lcm_map
[i
] = offset
;
1539 if (load_array
[i
].load
->hdr
.ldci_cmd_type
== LDC_CMD_MAP
)
1540 hdr
.moh_load_map_cmd_off
= offset
;
1542 offset
+= load_array
[i
].load
->hdr
.ldci_cmd_size
;
1545 hdr
.moh_sizeofcmds
= offset
- MO_SIZEOF_RAW_HDR
;
1548 print_header (&hdr
);
1551 status
= encode_mach_o_hdr (&hdr
, obj
, MO_SIZEOF_RAW_HDR
);
1552 if (status
!= MO_HDR_CONV_SUCCESS
)
1553 bad_header (status
);
1556 fprintf (stderr
, "writing load commands.\n\n");
1558 /* Write load commands */
1559 offset
= hdr
.moh_first_cmd_off
;
1560 for (i
= 0; i
< hdr
.moh_n_load_cmds
; i
++)
1562 load_union_t
*load_hdr
= load_array
[i
].load
;
1563 size_t size
= load_hdr
->hdr
.ldci_cmd_size
;
1566 print_load_command (load_hdr
, offset
, i
);
1568 memcpy (obj
+ offset
, load_hdr
, size
);
1573 end_file (obj_file
);
1575 if (close (prog_fd
))
1576 fatal_perror ("closing %s", prog_name
);
1579 fprintf (stderr
, "\n");
1583 /* Add a function table to the load commands to call a function
1584 on initiation or termination of the process. */
1587 add_func_table (hdr_p
, load_array
, sym
, type
)
1588 mo_header_t
*hdr_p
; /* pointer to global header */
1589 load_all_t
*load_array
; /* array of ptrs to load cmds */
1590 symbol_info_t
*sym
; /* pointer to symbol entry */
1591 int type
; /* fntc_type value */
1593 /* Add a new load command. */
1594 int num_cmds
= ++hdr_p
->moh_n_load_cmds
;
1595 int load_index
= num_cmds
- 1;
1596 size_t size
= sizeof (func_table_command_t
) + sizeof (mo_addr_t
);
1597 load_union_t
*ptr
= xcalloc (1, size
);
1598 load_all_t
*load_cmd
;
1601 /* Set the unresolved address bit in the header to force the loader to be
1602 used, since kernel exec does not call the initialization functions. */
1603 hdr_p
->moh_flags
|= MOH_UNRESOLVED_F
;
1605 load_cmd
= &load_array
[load_index
];
1606 load_cmd
->load
= ptr
;
1607 load_cmd
->section
= (char *)0;
1609 /* Fill in func table load command. */
1610 ptr
->func
.ldc_header
.ldci_cmd_type
= LDC_FUNC_TABLE
;
1611 ptr
->func
.ldc_header
.ldci_cmd_size
= size
;
1612 ptr
->func
.ldc_header
.ldci_section_off
= 0;
1613 ptr
->func
.ldc_header
.ldci_section_len
= 0;
1614 ptr
->func
.fntc_type
= type
;
1615 ptr
->func
.fntc_nentries
= 1;
1617 /* copy address, turn it from abs. address to (region,offset) if necessary. */
1618 /* Is the symbol already expressed as (region, offset)? */
1619 if ((sym
->si_flags
& SI_ABSOLUTE_VALUE_F
) == 0)
1621 ptr
->func
.fntc_entry_loc
[i
].adr_lcid
= sym
->si_value
.def_val
.adr_lcid
;
1622 ptr
->func
.fntc_entry_loc
[i
].adr_sctoff
= sym
->si_value
.def_val
.adr_sctoff
;
1625 /* If not, figure out which region it's in. */
1628 mo_vm_addr_t addr
= sym
->si_value
.abs_val
;
1631 for (i
= 0; i
< load_index
; i
++)
1633 if (load_array
[i
].load
->hdr
.ldci_cmd_type
== LDC_REGION
)
1635 region_command_t
*region_ptr
= &load_array
[i
].load
->region
;
1637 if ((region_ptr
->regc_flags
& REG_ABS_ADDR_F
) != 0
1638 && addr
>= region_ptr
->regc_addr
.vm_addr
1639 && addr
<= region_ptr
->regc_addr
.vm_addr
+ region_ptr
->regc_vm_size
)
1641 ptr
->func
.fntc_entry_loc
[0].adr_lcid
= i
;
1642 ptr
->func
.fntc_entry_loc
[0].adr_sctoff
= addr
- region_ptr
->regc_addr
.vm_addr
;
1650 fatal ("could not convert 0x%l.8x into a region", addr
);
1655 "%s function, region %d, offset = %ld (0x%.8lx)\n",
1656 (type
== FNTC_INITIALIZATION
) ? "init" : "term",
1657 (int)ptr
->func
.fntc_entry_loc
[i
].adr_lcid
,
1658 (long)ptr
->func
.fntc_entry_loc
[i
].adr_sctoff
,
1659 (long)ptr
->func
.fntc_entry_loc
[i
].adr_sctoff
);
1664 /* Print the global header for an OSF/rose object. */
1667 print_header (hdr_ptr
)
1668 mo_header_t
*hdr_ptr
;
1670 fprintf (stderr
, "\nglobal header:\n");
1671 fprintf (stderr
, "\tmoh_magic = 0x%.8lx\n", hdr_ptr
->moh_magic
);
1672 fprintf (stderr
, "\tmoh_major_version = %d\n", (int)hdr_ptr
->moh_major_version
);
1673 fprintf (stderr
, "\tmoh_minor_version = %d\n", (int)hdr_ptr
->moh_minor_version
);
1674 fprintf (stderr
, "\tmoh_header_version = %d\n", (int)hdr_ptr
->moh_header_version
);
1675 fprintf (stderr
, "\tmoh_max_page_size = %d\n", (int)hdr_ptr
->moh_max_page_size
);
1676 fprintf (stderr
, "\tmoh_byte_order = %d\n", (int)hdr_ptr
->moh_byte_order
);
1677 fprintf (stderr
, "\tmoh_data_rep_id = %d\n", (int)hdr_ptr
->moh_data_rep_id
);
1678 fprintf (stderr
, "\tmoh_cpu_type = %d\n", (int)hdr_ptr
->moh_cpu_type
);
1679 fprintf (stderr
, "\tmoh_cpu_subtype = %d\n", (int)hdr_ptr
->moh_cpu_subtype
);
1680 fprintf (stderr
, "\tmoh_vendor_type = %d\n", (int)hdr_ptr
->moh_vendor_type
);
1681 fprintf (stderr
, "\tmoh_load_map_cmd_off = %d\n", (int)hdr_ptr
->moh_load_map_cmd_off
);
1682 fprintf (stderr
, "\tmoh_first_cmd_off = %d\n", (int)hdr_ptr
->moh_first_cmd_off
);
1683 fprintf (stderr
, "\tmoh_sizeofcmds = %d\n", (int)hdr_ptr
->moh_sizeofcmds
);
1684 fprintf (stderr
, "\tmon_n_load_cmds = %d\n", (int)hdr_ptr
->moh_n_load_cmds
);
1685 fprintf (stderr
, "\tmoh_flags = 0x%.8lx", (long)hdr_ptr
->moh_flags
);
1687 if (hdr_ptr
->moh_flags
& MOH_RELOCATABLE_F
)
1688 fprintf (stderr
, ", relocatable");
1690 if (hdr_ptr
->moh_flags
& MOH_LINKABLE_F
)
1691 fprintf (stderr
, ", linkable");
1693 if (hdr_ptr
->moh_flags
& MOH_EXECABLE_F
)
1694 fprintf (stderr
, ", execable");
1696 if (hdr_ptr
->moh_flags
& MOH_EXECUTABLE_F
)
1697 fprintf (stderr
, ", executable");
1699 if (hdr_ptr
->moh_flags
& MOH_UNRESOLVED_F
)
1700 fprintf (stderr
, ", unresolved");
1702 fprintf (stderr
, "\n\n");
1707 /* Print a short summary of a load command. */
1710 print_load_command (load_hdr
, offset
, number
)
1711 load_union_t
*load_hdr
;
1715 mo_long_t type
= load_hdr
->hdr
.ldci_cmd_type
;
1716 char *type_str
= (char *)0;
1720 case LDC_UNDEFINED
: type_str
= "UNDEFINED"; break;
1721 case LDC_CMD_MAP
: type_str
= "CMD_MAP"; break;
1722 case LDC_INTERPRETER
: type_str
= "INTERPRETER"; break;
1723 case LDC_STRINGS
: type_str
= "STRINGS"; break;
1724 case LDC_REGION
: type_str
= "REGION"; break;
1725 case LDC_RELOC
: type_str
= "RELOC"; break;
1726 case LDC_PACKAGE
: type_str
= "PACKAGE"; break;
1727 case LDC_SYMBOLS
: type_str
= "SYMBOLS"; break;
1728 case LDC_ENTRY
: type_str
= "ENTRY"; break;
1729 case LDC_FUNC_TABLE
: type_str
= "FUNC_TABLE"; break;
1730 case LDC_GEN_INFO
: type_str
= "GEN_INFO"; break;
1734 "cmd %2d, sz: 0x%.2lx, coff: 0x%.3lx, doff: 0x%.6lx, dlen: 0x%.6lx",
1736 (long) load_hdr
->hdr
.ldci_cmd_size
,
1738 (long) load_hdr
->hdr
.ldci_section_off
,
1739 (long) load_hdr
->hdr
.ldci_section_len
);
1741 if (type_str
== (char *)0)
1742 fprintf (stderr
, ", ty: unknown (%ld)\n", (long) type
);
1744 else if (type
!= LDC_REGION
)
1745 fprintf (stderr
, ", ty: %s\n", type_str
);
1750 switch (load_hdr
->region
.regc_usage_type
)
1752 case REG_TEXT_T
: region
= ", .text"; break;
1753 case REG_DATA_T
: region
= ", .data"; break;
1754 case REG_BSS_T
: region
= ", .bss"; break;
1755 case REG_GLUE_T
: region
= ", .glue"; break;
1756 #if defined (REG_RDATA_T) && defined (REG_SDATA_T) && defined (REG_SBSS_T) /*mips*/
1757 case REG_RDATA_T
: region
= ", .rdata"; break;
1758 case REG_SDATA_T
: region
= ", .sdata"; break;
1759 case REG_SBSS_T
: region
= ", .sbss"; break;
1763 fprintf (stderr
, ", ty: %s, vaddr: 0x%.8lx, vlen: 0x%.6lx%s\n",
1765 (long) load_hdr
->region
.regc_vm_addr
,
1766 (long) load_hdr
->region
.regc_vm_size
,
1774 /* Fatal error when {en,de}code_mach_o_header fails. */
1780 char *msg
= (char *)0;
1784 case MO_ERROR_BAD_MAGIC
: msg
= "bad magic number"; break;
1785 case MO_ERROR_BAD_HDR_VERS
: msg
= "bad header version"; break;
1786 case MO_ERROR_BAD_RAW_HDR_VERS
: msg
= "bad raw header version"; break;
1787 case MO_ERROR_BUF2SML
: msg
= "raw header buffer too small"; break;
1788 case MO_ERROR_OLD_RAW_HDR_FILE
: msg
= "old raw header file"; break;
1789 case MO_ERROR_UNSUPPORTED_VERS
: msg
= "unsupported version"; break;
1792 if (msg
== (char *)0)
1793 fatal ("unknown {de,en}code_mach_o_hdr return value %d", status
);
1799 /* Read a file into a memory buffer. */
1801 static struct file_info
*
1802 read_file (name
, fd
, rw
)
1803 char *name
; /* filename */
1804 int fd
; /* file descriptor */
1805 int rw
; /* read/write */
1807 struct stat stat_pkt
;
1808 struct file_info
*p
= (struct file_info
*) xcalloc (sizeof (struct file_info
), 1);
1810 static int page_size
;
1813 if (fstat (fd
, &stat_pkt
) < 0)
1814 fatal_perror ("fstat %s", name
);
1817 p
->size
= stat_pkt
.st_size
;
1818 p
->rounded_size
= stat_pkt
.st_size
;
1824 fprintf (stderr
, "mmap %s, %s\n", name
, (rw
) ? "read/write" : "read-only");
1827 page_size
= sysconf (_SC_PAGE_SIZE
);
1829 p
->rounded_size
= ((p
->size
+ page_size
- 1) / page_size
) * page_size
;
1830 p
->start
= mmap ((caddr_t
)0,
1831 (rw
) ? p
->rounded_size
: p
->size
,
1832 (rw
) ? (PROT_READ
| PROT_WRITE
) : PROT_READ
,
1833 MAP_FILE
| MAP_VARIABLE
| MAP_SHARED
,
1837 if (p
->start
!= (char *)0 && p
->start
!= (char *)-1)
1841 #endif /* USE_MMAP */
1846 fprintf (stderr
, "read %s\n", name
);
1849 p
->start
= xmalloc (p
->size
);
1850 if (lseek (fd
, 0L, SEEK_SET
) < 0)
1851 fatal_perror ("lseek to 0 on %s", name
);
1853 len
= read (fd
, p
->start
, p
->size
);
1855 fatal_perror ("read %s", name
);
1858 fatal ("read %ld bytes, expected %ld, from %s", len
, p
->size
, name
);
1865 /* Do anything necessary to write a file back from memory. */
1869 struct file_info
*ptr
; /* file information block */
1877 fprintf (stderr
, "msync %s\n", ptr
->name
);
1879 if (msync (ptr
->start
, ptr
->rounded_size
, MS_ASYNC
))
1880 fatal_perror ("msync %s", ptr
->name
);
1884 fprintf (stderr
, "munmap %s\n", ptr
->name
);
1886 if (munmap (ptr
->start
, ptr
->size
))
1887 fatal_perror ("munmap %s", ptr
->name
);
1890 #endif /* USE_MMAP */
1897 fprintf (stderr
, "write %s\n", ptr
->name
);
1899 if (lseek (ptr
->fd
, 0L, SEEK_SET
) < 0)
1900 fatal_perror ("lseek to 0 on %s", ptr
->name
);
1902 len
= write (ptr
->fd
, ptr
->start
, ptr
->size
);
1904 fatal_perror ("read %s", ptr
->name
);
1906 if (len
!= ptr
->size
)
1907 fatal ("wrote %ld bytes, expected %ld, to %s", len
, ptr
->size
, ptr
->name
);
1910 free ((generic
*)ptr
->start
);
1913 free ((generic
*)ptr
);
1916 #endif /* OBJECT_FORMAT_ROSE */