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 ();
221 while ((fd
= dup (oldfd
)) != newfd
) /* good enough for low fd's */
224 close (fdtmp
[--fdx
]);
232 extern char *sys_errlist
[];
234 static char buffer
[30];
239 if (e
> 0 && e
< sys_nerr
)
240 return sys_errlist
[e
];
242 sprintf (buffer
, "Unknown error %d", e
);
246 /* Delete tempfiles and exit function. */
252 if (c_file
!= 0 && c_file
[0])
253 maybe_unlink (c_file
);
255 if (o_file
!= 0 && o_file
[0])
256 maybe_unlink (o_file
);
262 /* Die when sys call fails. */
265 fatal_perror (string
, arg1
, arg2
, arg3
)
270 fprintf (stderr
, "collect: ");
271 fprintf (stderr
, string
, arg1
, arg2
, arg3
);
272 fprintf (stderr
, ": %s\n", my_strerror (e
));
279 fatal (string
, arg1
, arg2
, arg3
)
282 fprintf (stderr
, "collect: ");
283 fprintf (stderr
, string
, arg1
, arg2
, arg3
);
284 fprintf (stderr
, "\n");
288 /* Write error message. */
291 error (string
, arg1
, arg2
, arg3
, arg4
)
294 fprintf (stderr
, "collect: ");
295 fprintf (stderr
, string
, arg1
, arg2
, arg3
, arg4
);
296 fprintf (stderr
, "\n");
299 /* In case obstack is linked in, and abort is defined to fancy_abort,
300 provide a default entry. */
305 fatal ("internal error");
314 maybe_unlink (c_file
);
317 maybe_unlink (o_file
);
319 signal (signo
, SIG_DFL
);
320 kill (getpid (), signo
);
325 xcalloc (size1
, size2
)
328 generic
*ptr
= (generic
*) calloc (size1
, size2
);
332 fatal ("out of memory");
340 generic
*ptr
= (generic
*) malloc (size
);
344 fatal ("out of memory");
348 /* Make a copy of a string INPUT with size SIZE. */
351 savestring (input
, size
)
355 char *output
= (char *) xmalloc (size
+ 1);
356 bcopy (input
, output
, size
);
361 /* Decide whether the given symbol is:
362 a constructor (1), a destructor (2), or neither (0). */
368 struct names
{ char *name
; int len
; int ret
; int two_underscores
; };
370 register struct names
*p
;
372 register char *orig_s
= s
;
374 static struct names special
[] = {
375 #ifdef NO_DOLLAR_IN_LABEL
376 { "GLOBAL_.I.", sizeof ("GLOBAL_.I.")-1, 1, 0 },
377 { "GLOBAL_.D.", sizeof ("GLOBAL_.D.")-1, 2, 0 },
379 { "GLOBAL_$I$", sizeof ("GLOBAL_$I$")-1, 1, 0 },
380 { "GLOBAL_$D$", sizeof ("GLOBAL_$I$")-1, 2, 0 },
382 { "sti__", sizeof ("sti__")-1, 1, 1 },
383 { "std__", sizeof ("std__")-1, 2, 1 },
387 while ((ch
= *s
) == '_')
393 for (p
= &special
[0]; p
->len
> 0; p
++)
396 && (!p
->two_underscores
|| ((s
- orig_s
) >= 2))
397 && strncmp(s
, p
->name
, p
->len
) == 0)
406 /* Compute a string to use as the base of all temporary file names.
407 It is substituted for %g. */
412 char *base
= getenv ("TMPDIR");
415 if (base
== (char *)0)
418 if (access (P_tmpdir
, R_OK
| W_OK
) == 0)
421 if (base
== (char *)0)
423 if (access ("/usr/tmp", R_OK
| W_OK
) == 0)
431 temp_filename
= xmalloc (len
+ sizeof("/ccXXXXXX"));
432 strcpy (temp_filename
, base
);
433 if (len
> 0 && temp_filename
[len
-1] != '/')
434 temp_filename
[len
++] = '/';
435 strcpy (temp_filename
+ len
, "ccXXXXXX");
437 mktemp (temp_filename
);
438 temp_filename_length
= strlen (temp_filename
);
449 char *outfile
= "a.out";
458 char **ld1_argv
= (char **) xcalloc (sizeof (char *), argc
+2);
459 char **ld1
= ld1_argv
;
460 char **ld2_argv
= (char **) xcalloc (sizeof (char *), argc
+5);
461 char **ld2
= ld2_argv
;
463 int num_c_args
= argc
+7;
472 p
= (char *) getenv ("COLLECT_GCC_OPTIONS");
477 while (*q
&& *q
!= ' ') q
++;
478 if (*p
== '-' && p
[1] == 'm')
485 c_ptr
= c_argv
= (char **) xcalloc (sizeof (char *), num_c_args
);
488 fatal ("no arguments");
490 signal (SIGQUIT
, handler
);
491 signal (SIGINT
, handler
);
492 signal (SIGALRM
, handler
);
493 signal (SIGHUP
, handler
);
494 signal (SIGSEGV
, handler
);
495 signal (SIGBUS
, handler
);
497 /* Try to discover a valid linker/assembler/nm/strip to use. */
498 len
= strlen (argv
[0]);
500 if (len
>= sizeof ("ld")-1)
502 p
= argv
[0] + len
- sizeof ("ld") + 1;
503 if (strcmp (p
, "ld") == 0)
510 if (prefix
== (char *)0)
512 p
= rindex (argv
[0], '/');
519 #ifdef STANDARD_EXEC_PREFIX
520 else if (access (STANDARD_EXEC_PREFIX
, X_OK
) == 0)
521 prefix
= STANDARD_EXEC_PREFIX
;
524 #ifdef MD_EXEC_PREFIX
525 else if (access (MD_EXEC_PREFIX
, X_OK
) == 0)
526 prefix
= MD_EXEC_PREFIX
;
529 else if (access ("/usr/ccs/gcc", X_OK
) == 0)
530 prefix
= "/usr/ccs/gcc/";
532 else if (access ("/usr/ccs/bin", X_OK
) == 0)
533 prefix
= "/usr/ccs/bin/";
539 clen
= len
= strlen (prefix
);
541 #ifdef STANDARD_BIN_PREFIX
542 if (clen
< sizeof (STANDARD_BIN_PREFIX
) - 1)
543 clen
= sizeof (STANDARD_BIN_PREFIX
) - 1;
546 #ifdef STANDARD_EXEC_PREFIX
547 if (clen
< sizeof (STANDARD_EXEC_PREFIX
) - 1)
548 clen
= sizeof (STANDARD_EXEC_PREFIX
) - 1;
551 /* Allocate enough string space for the longest possible pathnames. */
552 ld_file_name
= xcalloc (len
+ sizeof ("real-ld"), 1);
553 nm_file_name
= xcalloc (len
+ sizeof ("gnm"), 1);
554 strip_file_name
= xcalloc (len
+ sizeof ("gstrip"), 1);
556 /* Determine the full path name of the ld program to use. */
557 bcopy (prefix
, ld_file_name
, len
);
558 strcpy (ld_file_name
+ len
, "real-ld");
559 if (access (ld_file_name
, X_OK
) < 0)
561 strcpy (ld_file_name
+ len
, "gld");
562 if (access (ld_file_name
, X_OK
) < 0)
565 #ifdef REAL_LD_FILE_NAME
566 ld_file_name
= REAL_LD_FILE_NAME
;
568 ld_file_name
= (access ("/usr/bin/ld", X_OK
) == 0
569 ? "/usr/bin/ld" : "/bin/ld");
574 /* Determine the full path name of the C compiler to use. */
575 c_file_name
= getenv ("COLLECT_GCC");
576 if (c_file_name
== 0 || c_file_name
[0] != '/')
578 c_file_name
= xcalloc (clen
+ sizeof ("gcc"), 1);
579 bcopy (prefix
, c_file_name
, len
);
580 strcpy (c_file_name
+ len
, "gcc");
581 if (access (c_file_name
, X_OK
) < 0)
583 #ifdef STANDARD_BIN_PREFIX
584 strcpy (c_file_name
, STANDARD_BIN_PREFIX
);
585 strcat (c_file_name
, "gcc");
586 if (access (c_file_name
, X_OK
) < 0)
589 #ifdef STANDARD_EXEC_PREFIX
590 strcpy (c_file_name
, STANDARD_EXEC_PREFIX
);
591 strcat (c_file_name
, "gcc");
592 if (access (c_file_name
, X_OK
) < 0)
595 strcpy (c_file_name
, "gcc");
601 /* Determine the full path name of the nm to use. */
602 bcopy (prefix
, nm_file_name
, len
);
603 strcpy (nm_file_name
+ len
, "nm");
604 if (access (nm_file_name
, X_OK
) < 0)
606 strcpy (nm_file_name
+ len
, "gnm");
607 if (access (nm_file_name
, X_OK
) < 0)
610 #ifdef REAL_NM_FILE_NAME
611 nm_file_name
= REAL_NM_FILE_NAME
;
613 nm_file_name
= (access ("/usr/bin/nm", X_OK
) == 0
614 ? "/usr/bin/nm" : "/bin/nm");
619 /* Determine the full pathname of the strip to use. */
620 bcopy (prefix
, strip_file_name
, len
);
621 strcpy (strip_file_name
+ len
, "strip");
622 if (access (strip_file_name
, X_OK
) < 0)
624 strcpy (strip_file_name
+ len
, "gstrip");
625 if (access (strip_file_name
, X_OK
) < 0)
627 free (strip_file_name
);
628 #ifdef REAL_STRIP_FILE_NAME
629 strip_file_name
= REAL_STRIP_FILE_NAME
;
631 strip_file_name
= (access ("/usr/bin/strip", X_OK
) == 0
632 ? "/usr/bin/strip" : "/bin/strip");
637 *ld1
++ = *ld2
++ = "ld";
639 /* Make temp file names. */
641 c_file
= xcalloc (temp_filename_length
+ sizeof (".c"), 1);
642 o_file
= xcalloc (temp_filename_length
+ sizeof (".o"), 1);
643 sprintf (c_file
, "%s.c", temp_filename
);
644 sprintf (o_file
, "%s.o", temp_filename
);
645 *c_ptr
++ = c_file_name
;
650 /* !!! When GCC calls collect2,
651 it does not know whether it is calling collect2 or ld.
652 So collect2 cannot meaningfully understand any options
653 except those ld understands.
654 If you propose to make GCC pass some other option,
655 just imagine what will happen if ld is really ld!!! */
657 /* Parse arguments. Remember output file spec, pass the rest to ld. */
658 /* After the first file, put in the c++ rt0. */
661 while ((arg
= *++argv
) != (char *)0)
663 *ld1
++ = *ld2
++ = arg
;
669 if (!strcmp (arg
, "-debug"))
679 outfile
= (arg
[2] == '\0') ? argv
[1] : &arg
[2];
690 /* We must strip after the nm run, otherwise C++ linking
691 won't work. Thus we strip in the second ld run, or
692 else with strip if there is no second ld run. */
705 && (p
= rindex (arg
, '.')) != (char *)0
706 && strcmp (p
, ".o") == 0)
713 /* Get any options that the upper GCC wants to pass to the sub-GCC. */
714 p
= (char *) getenv ("COLLECT_GCC_OPTIONS");
719 while (*q
&& *q
!= ' ') q
++;
720 if (*p
== '-' && (p
[1] == 'm' || p
[1] == 'f'))
721 *c_ptr
++ = savestring (p
, q
- p
);
728 *c_ptr
= *ld1
= *ld2
= (char *)0;
732 fprintf (stderr
, "collect2 version %s", version_string
);
733 #ifdef TARGET_VERSION
736 fprintf (stderr
, "\n");
742 fprintf (stderr
, "prefix = %s\n", prefix
);
743 fprintf (stderr
, "ld_file_name = %s\n", ld_file_name
);
744 fprintf (stderr
, "c_file_name = %s\n", c_file_name
);
745 fprintf (stderr
, "nm_file_name = %s\n", nm_file_name
);
746 fprintf (stderr
, "c_file = %s\n", c_file
);
747 fprintf (stderr
, "o_file = %s\n", o_file
);
749 ptr
= getenv ("COLLECT_GCC_OPTIONS");
751 fprintf (stderr
, "COLLECT_GCC_OPTIONS = %s\n", ptr
);
753 ptr
= getenv ("COLLECT_GCC");
755 fprintf (stderr
, "COLLECT_GCC = %s\n", ptr
);
757 ptr
= getenv ("COMPILER_PATH");
759 fprintf (stderr
, "COMPILER_PATH = %s\n", ptr
);
761 ptr
= getenv ("LIBRARY_PATH");
763 fprintf (stderr
, "LIBRARY_PATH = %s\n", ptr
);
765 fprintf (stderr
, "\n");
768 /* Load the program, searching all libraries.
769 Examine the namelist with nm and search it for static constructors
770 and destructors to call.
771 Write the constructor and destructor tables to a .s file and reload. */
773 fork_execute (ld_file_name
, ld1_argv
);
775 /* If -r, don't build the constructor or destructor list, just return now. */
779 scan_prog_file (outfile
, PASS_FIRST
);
783 fprintf (stderr
, "%d constructor(s) found\n", constructors
.number
);
784 fprintf (stderr
, "%d destructor(s) found\n", destructors
.number
);
787 if (constructors
.number
== 0 && destructors
.number
== 0)
789 /* Strip now if it was requested on the command line. */
792 char **strip_argv
= (char **) xcalloc (sizeof (char *), 3);
793 strip_argv
[0] = "strip";
794 strip_argv
[1] = outfile
;
795 strip_argv
[2] = (char *) 0;
796 fork_execute (strip_file_name
, strip_argv
);
801 outf
= fopen (c_file
, "w");
802 if (outf
== (FILE *)0)
803 fatal_perror ("%s", c_file
);
805 write_c_file (outf
, c_file
);
808 fatal_perror ("closing %s", c_file
);
812 fprintf (stderr
, "\n========== outfile = %s, c_file = %s\n", outfile
, c_file
);
813 write_c_file (stderr
, "stderr");
814 fprintf (stderr
, "========== end of c_file\n\n");
817 /* Assemble the constructor and destructor tables.
818 Link the tables in with the rest of the program. */
820 fork_execute (c_file_name
, c_argv
);
821 fork_execute (ld_file_name
, ld2_argv
);
823 /* Let scan_prog_file do any final mods (OSF/rose needs this for
824 constructors/destructors in shared libraries. */
825 scan_prog_file (outfile
, PASS_SECOND
);
827 maybe_unlink (c_file
);
828 maybe_unlink (o_file
);
833 /* Wait for a process to finish, and exit if a non-zero status is found. */
844 int sig
= status
& 0x7F;
847 if (sig
!= -1 && sig
!= 0)
849 #ifdef NO_SYS_SIGLIST
850 error ("%s terminated with signal %d %s",
853 (status
& 0200) ? ", core dumped" : "");
855 error ("%s terminated with signal %d [%s]%s",
859 (status
& 0200) ? ", core dumped" : "");
865 ret
= ((status
& 0xFF00) >> 8);
866 if (ret
!= -1 && ret
!= 0)
868 error ("%s returned %d exit status", prog
, ret
);
875 /* Fork and execute a program, and wait for the reply. */
878 fork_execute (prog
, argv
)
883 void (*int_handler
) ();
884 void (*quit_handler
) ();
891 fprintf (stderr
, "%s", prog
);
892 for (p_argv
= &argv
[1]; (str
= *p_argv
) != (char *)0; p_argv
++)
893 fprintf (stderr
, " %s", str
);
895 fprintf (stderr
, "\n");
903 fatal_perror ("vfork");
905 if (pid
== 0) /* child context */
908 fatal_perror ("executing %s", prog
);
911 int_handler
= (void (*) ())signal (SIGINT
, SIG_IGN
);
912 quit_handler
= (void (*) ())signal (SIGQUIT
, SIG_IGN
);
916 signal (SIGINT
, int_handler
);
917 signal (SIGQUIT
, quit_handler
);
921 /* Unlink a file unless we are debugging. */
930 fprintf (stderr
, "[Leaving %s]\n", file
);
934 /* Add a name to a linked list. */
937 add_to_list (head_ptr
, name
)
938 struct head
*head_ptr
;
941 struct id
*newid
= (struct id
*) xcalloc (sizeof (*newid
) + strlen (name
), 1);
942 static long sequence_number
= 0;
943 newid
->sequence
= ++sequence_number
;
944 strcpy (newid
->name
, name
);
947 head_ptr
->last
->next
= newid
;
949 head_ptr
->first
= newid
;
951 head_ptr
->last
= newid
;
955 /* Write: `prefix', the names on list LIST, `suffix'. */
958 write_list (stream
, prefix
, list
)
965 fprintf (stream
, "%sx%d,\n", prefix
, list
->sequence
);
971 write_list_with_asm (stream
, prefix
, list
)
978 fprintf (stream
, "%sx%d asm (\"%s\");\n",
979 prefix
, list
->sequence
, list
->name
);
984 /* Write the constructor/destructor tables. */
987 write_c_file (stream
, name
)
991 /* Write the tables as C code */
993 fprintf (stream
, "typedef void entry_pt();\n\n");
995 write_list_with_asm (stream
, "extern entry_pt ", constructors
.first
);
997 fprintf (stream
, "\nentry_pt * __CTOR_LIST__[] = {\n");
998 fprintf (stream
, "\t(entry_pt *) %d,\n", constructors
.number
);
999 write_list (stream
, "\t", constructors
.first
);
1000 fprintf (stream
, "\t0\n};\n\n");
1002 write_list_with_asm (stream
, "extern entry_pt ", destructors
.first
);
1004 fprintf (stream
, "\nentry_pt * __DTOR_LIST__[] = {\n");
1005 fprintf (stream
, "\t(entry_pt *) %d,\n", destructors
.number
);
1006 write_list (stream
, "\t", destructors
.first
);
1007 fprintf (stream
, "\t0\n};\n\n");
1009 fprintf (stream
, "extern entry_pt __main;\n");
1010 fprintf (stream
, "entry_pt *__main_reference = __main;\n\n");
1014 #ifdef OBJECT_FORMAT_NONE
1016 /* Generic version to scan the name list of the loaded program for
1017 the symbols g++ uses for static constructors and destructors.
1019 The constructor table begins at __CTOR_LIST__ and contains a count
1020 of the number of pointers (or -1 if the constructors are built in a
1021 separate section by the linker), followed by the pointers to the
1022 constructor functions, terminated with a null pointer. The
1023 destructor table has the same format, and begins at __DTOR_LIST__. */
1026 scan_prog_file (prog_name
, which_pass
)
1028 enum pass which_pass
;
1030 void (*int_handler
) ();
1031 void (*quit_handler
) ();
1039 if (which_pass
!= PASS_FIRST
)
1042 nm_argv
[argc
++] = "nm";
1043 if (NM_FLAGS
[0] != '\0')
1044 nm_argv
[argc
++] = NM_FLAGS
;
1046 nm_argv
[argc
++] = prog_name
;
1047 nm_argv
[argc
++] = (char *)0;
1049 if (pipe (pipe_fd
) < 0)
1050 fatal_perror ("pipe");
1052 inf
= fdopen (pipe_fd
[0], "r");
1053 if (inf
== (FILE *)0)
1054 fatal_perror ("fdopen");
1056 /* Trace if needed. */
1062 fprintf (stderr
, "%s", nm_file_name
);
1063 for (p_argv
= &nm_argv
[1]; (str
= *p_argv
) != (char *)0; p_argv
++)
1064 fprintf (stderr
, " %s", str
);
1066 fprintf (stderr
, "\n");
1072 /* Spawn child nm on pipe */
1075 fatal_perror ("vfork");
1077 if (pid
== 0) /* child context */
1080 if (dup2 (pipe_fd
[1], 1) < 0)
1081 fatal_perror ("dup2 (%d, 1)", pipe_fd
[1]);
1083 if (close (pipe_fd
[0]) < 0)
1084 fatal_perror ("close (%d)", pipe_fd
[0]);
1086 if (close (pipe_fd
[1]) < 0)
1087 fatal_perror ("close (%d)", pipe_fd
[1]);
1089 execv (nm_file_name
, nm_argv
);
1090 fatal_perror ("executing %s", nm_file_name
);
1093 /* Parent context from here on. */
1094 int_handler
= (void (*) ())signal (SIGINT
, SIG_IGN
);
1095 quit_handler
= (void (*) ())signal (SIGQUIT
, SIG_IGN
);
1097 if (close (pipe_fd
[1]) < 0)
1098 fatal_perror ("close (%d)", pipe_fd
[1]);
1101 fprintf (stderr
, "\nnm output with constructors/destructors.\n");
1103 /* Read each line of nm output. */
1104 while (fgets (buf
, sizeof buf
, inf
) != (char *)0)
1109 /* If it contains a constructor or destructor name, add the name
1110 to the appropriate list. */
1112 for (p
= buf
; (ch
= *p
) != '\0' && ch
!= '\n' && ch
!= '_'; p
++)
1115 if (ch
== '\0' || ch
== '\n')
1119 /* Find the end of the symbol name.
1120 Don't include `|', because Encore nm can tack that on the end. */
1121 for (end
= p
; (ch2
= *end
) != '\0' && !isspace (ch2
) && ch2
!= '|';
1126 switch (is_ctor_dtor (name
))
1129 add_to_list (&constructors
, name
);
1133 add_to_list (&destructors
, name
);
1136 default: /* not a constructor or destructor */
1141 fprintf (stderr
, "\t%s\n", buf
);
1145 fprintf (stderr
, "\n");
1147 if (fclose (inf
) != 0)
1148 fatal_perror ("fclose of pipe");
1150 do_wait (nm_file_name
);
1152 signal (SIGINT
, int_handler
);
1153 signal (SIGQUIT
, quit_handler
);
1156 #endif /* OBJECT_FORMAT_NONE */
1160 * COFF specific stuff.
1163 #ifdef OBJECT_FORMAT_COFF
1165 #if defined(EXTENDED_COFF)
1166 # define GCC_SYMBOLS(X) (SYMHEADER(X).isymMax + SYMHEADER(X).iextMax)
1167 # define GCC_SYMENT SYMR
1168 # define GCC_OK_SYMBOL(X) ((X).st == stProc && (X).sc == scText)
1169 # define GCC_SYMINC(X) (1)
1170 # define GCC_SYMZERO(X) (SYMHEADER(X).isymMax)
1171 # define GCC_CHECK_HDR(X) (PSYMTAB(X) != 0)
1173 # define GCC_SYMBOLS(X) (HEADER(ldptr).f_nsyms)
1174 # define GCC_SYMENT SYMENT
1175 # define GCC_OK_SYMBOL(X) \
1176 (((X).n_sclass == C_EXT) && \
1177 (((X).n_type & N_TMASK) == (DT_NON << N_BTSHFT) || \
1178 ((X).n_type & N_TMASK) == (DT_FCN << N_BTSHFT)))
1179 # define GCC_SYMINC(X) ((X).n_numaux+1)
1180 # define GCC_SYMZERO(X) 0
1181 # define GCC_CHECK_HDR(X) (1)
1184 extern char *ldgetname ();
1186 /* COFF version to scan the name list of the loaded program for
1187 the symbols g++ uses for static constructors and destructors.
1189 The constructor table begins at __CTOR_LIST__ and contains a count
1190 of the number of pointers (or -1 if the constructors are built in a
1191 separate section by the linker), followed by the pointers to the
1192 constructor functions, terminated with a null pointer. The
1193 destructor table has the same format, and begins at __DTOR_LIST__. */
1196 scan_prog_file (prog_name
, which_pass
)
1198 enum pass which_pass
;
1200 LDFILE
*ldptr
= NULL
;
1201 int sym_index
, sym_count
;
1203 if (which_pass
!= PASS_FIRST
)
1206 if ((ldptr
= ldopen (prog_name
, ldptr
)) == NULL
)
1207 fatal ("%s: can't open as COFF file", prog_name
);
1209 if (!MY_ISCOFF (HEADER (ldptr
).f_magic
))
1210 fatal ("%s: not a COFF file", prog_name
);
1212 if (GCC_CHECK_HDR (ldptr
))
1214 sym_count
= GCC_SYMBOLS (ldptr
);
1215 sym_index
= GCC_SYMZERO (ldptr
);
1216 while (sym_index
< sym_count
)
1220 if (ldtbread (ldptr
, sym_index
, &symbol
) <= 0)
1222 sym_index
+= GCC_SYMINC (symbol
);
1224 if (GCC_OK_SYMBOL (symbol
))
1228 if ((name
= ldgetname (ldptr
, &symbol
)) == NULL
)
1229 continue; /* should never happen */
1232 /* All AIX function names begin with a dot. */
1237 switch (is_ctor_dtor (name
))
1240 add_to_list (&constructors
, name
);
1244 add_to_list (&destructors
, name
);
1247 default: /* not a constructor or destructor */
1251 #if !defined(EXTENDED_COFF)
1253 fprintf (stderr
, "\tsec=%d class=%d type=%s%o %s\n",
1254 symbol
.n_scnum
, symbol
.n_sclass
,
1255 (symbol
.n_type
? "0" : ""), symbol
.n_type
,
1259 fprintf (stderr
, "\tiss = %5d, value = %5d, index = %5d, name = %s\n",
1260 symbol
.iss
, symbol
.value
, symbol
.index
, name
);
1266 (void) ldclose(ldptr
);
1269 #endif /* OBJECT_FORMAT_COFF */
1273 * OSF/rose specific stuff.
1276 #ifdef OBJECT_FORMAT_ROSE
1278 /* Union of the various load commands */
1280 typedef union load_union
1282 ldc_header_t hdr
; /* common header */
1283 load_cmd_map_command_t map
; /* map indexing other load cmds */
1284 interpreter_command_t iprtr
; /* interpreter pathname */
1285 strings_command_t str
; /* load commands strings section */
1286 region_command_t region
; /* region load command */
1287 reloc_command_t reloc
; /* relocation section */
1288 package_command_t pkg
; /* package load command */
1289 symbols_command_t sym
; /* symbol sections */
1290 entry_command_t ent
; /* program start section */
1291 gen_info_command_t info
; /* object information */
1292 func_table_command_t func
; /* function constructors/destructors */
1295 /* Structure to point to load command and data section in memory. */
1297 typedef struct load_all
1299 load_union_t
*load
; /* load command */
1300 char *section
; /* pointer to section */
1303 /* Structure to contain information about a file mapped into memory. */
1307 char *start
; /* start of map */
1308 char *name
; /* filename */
1309 long size
; /* size of the file */
1310 long rounded_size
; /* size rounded to page boundary */
1311 int fd
; /* file descriptor */
1312 int rw
; /* != 0 if opened read/write */
1313 int use_mmap
; /* != 0 if mmap'ed */
1316 extern int decode_mach_o_hdr ();
1318 extern int encode_mach_o_hdr ();
1320 static void bad_header ();
1322 static void print_header ();
1324 static void print_load_command ();
1326 static void add_func_table ();
1328 static struct file_info
*read_file ();
1330 static void end_file ();
1333 /* OSF/rose specific version to scan the name list of the loaded
1334 program for the symbols g++ uses for static constructors and
1337 The constructor table begins at __CTOR_LIST__ and contains a count
1338 of the number of pointers (or -1 if the constructors are built in a
1339 separate section by the linker), followed by the pointers to the
1340 constructor functions, terminated with a null pointer. The
1341 destructor table has the same format, and begins at __DTOR_LIST__. */
1344 scan_prog_file (prog_name
, which_pass
)
1346 enum pass which_pass
;
1350 load_all_t
*load_array
;
1351 load_all_t
*load_end
;
1352 load_all_t
*load_cmd
;
1353 int symbol_load_cmds
;
1359 struct file_info
*obj_file
;
1361 mo_lcid_t cmd_strings
= -1;
1362 symbol_info_t
*main_sym
= 0;
1363 int rw
= (which_pass
!= PASS_FIRST
);
1365 prog_fd
= open (prog_name
, (rw
) ? O_RDWR
: O_RDONLY
);
1367 fatal_perror ("can't read %s", prog_name
);
1369 obj_file
= read_file (prog_name
, prog_fd
, rw
);
1370 obj
= obj_file
->start
;
1372 status
= decode_mach_o_hdr (obj
, MO_SIZEOF_RAW_HDR
, MOH_HEADER_VERSION
, &hdr
);
1373 if (status
!= MO_HDR_CONV_SUCCESS
)
1374 bad_header (status
);
1377 /* Do some basic sanity checks. Note we explicitly use the big endian magic number,
1378 since the hardware will automatically swap bytes for us on loading little endian
1381 #ifndef CROSS_COMPILE
1382 if (hdr
.moh_magic
!= MOH_MAGIC_MSB
1383 || hdr
.moh_header_version
!= MOH_HEADER_VERSION
1384 || hdr
.moh_byte_order
!= OUR_BYTE_ORDER
1385 || hdr
.moh_data_rep_id
!= OUR_DATA_REP_ID
1386 || hdr
.moh_cpu_type
!= OUR_CPU_TYPE
1387 || hdr
.moh_cpu_subtype
!= OUR_CPU_SUBTYPE
1388 || hdr
.moh_vendor_type
!= OUR_VENDOR_TYPE
)
1390 fatal ("incompatibilities between object file & expected values");
1395 print_header (&hdr
);
1397 offset
= hdr
.moh_first_cmd_off
;
1398 load_end
= load_array
1399 = (load_all_t
*) xcalloc (sizeof (load_all_t
), hdr
.moh_n_load_cmds
+ 2);
1401 /* Build array of load commands, calculating the offsets */
1402 for (i
= 0; i
< hdr
.moh_n_load_cmds
; i
++)
1404 load_union_t
*load_hdr
; /* load command header */
1406 load_cmd
= load_end
++;
1407 load_hdr
= (load_union_t
*) (obj
+ offset
);
1409 /* If modifying the program file, copy the header. */
1412 load_union_t
*ptr
= (load_union_t
*) xmalloc (load_hdr
->hdr
.ldci_cmd_size
);
1413 bcopy ((generic
*)load_hdr
, (generic
*)ptr
, load_hdr
->hdr
.ldci_cmd_size
);
1416 /* null out old command map, because we will rewrite at the end. */
1417 if (ptr
->hdr
.ldci_cmd_type
== LDC_CMD_MAP
)
1419 cmd_strings
= ptr
->map
.lcm_ld_cmd_strings
;
1420 ptr
->hdr
.ldci_cmd_type
= LDC_UNDEFINED
;
1424 load_cmd
->load
= load_hdr
;
1425 if (load_hdr
->hdr
.ldci_section_off
> 0)
1426 load_cmd
->section
= obj
+ load_hdr
->hdr
.ldci_section_off
;
1429 print_load_command (load_hdr
, offset
, i
);
1431 offset
+= load_hdr
->hdr
.ldci_cmd_size
;
1434 /* If the last command is the load command map and is not undefined,
1435 decrement the count of load commands. */
1436 if (rw
&& load_end
[-1].load
->hdr
.ldci_cmd_type
== LDC_UNDEFINED
)
1439 hdr
.moh_n_load_cmds
--;
1442 /* Go through and process each symbol table section. */
1443 symbol_load_cmds
= 0;
1444 for (load_cmd
= load_array
; load_cmd
< load_end
; load_cmd
++)
1446 load_union_t
*load_hdr
= load_cmd
->load
;
1448 if (load_hdr
->hdr
.ldci_cmd_type
== LDC_SYMBOLS
)
1454 char *kind
= "unknown";
1456 switch (load_hdr
->sym
.symc_kind
)
1458 case SYMC_IMPORTS
: kind
= "imports"; break;
1459 case SYMC_DEFINED_SYMBOLS
: kind
= "defined"; break;
1460 case SYMC_STABS
: kind
= "stabs"; break;
1463 fprintf (stderr
, "\nProcessing symbol table #%d, offset = 0x%.8lx, kind = %s\n",
1464 symbol_load_cmds
, load_hdr
->hdr
.ldci_section_off
, kind
);
1467 if (load_hdr
->sym
.symc_kind
!= SYMC_DEFINED_SYMBOLS
)
1470 str_sect
= load_array
[load_hdr
->sym
.symc_strings_section
].section
;
1471 if (str_sect
== (char *)0)
1472 fatal ("string section missing");
1474 if (load_cmd
->section
== (char *)0)
1475 fatal ("section pointer missing");
1477 num_syms
= load_hdr
->sym
.symc_nentries
;
1478 for (i
= 0; i
< num_syms
; i
++)
1480 symbol_info_t
*sym
= ((symbol_info_t
*) load_cmd
->section
) + i
;
1481 char *name
= sym
->si_name
.symbol_name
+ str_sect
;
1491 if (*n
!= 'm' || (n
- name
) < 2 || strcmp (n
, "main"))
1498 switch (is_ctor_dtor (name
))
1501 add_to_list (&constructors
, name
);
1505 add_to_list (&destructors
, name
);
1508 default: /* not a constructor or destructor */
1514 fprintf (stderr
, "\ttype = 0x%.4x, sc = 0x%.2x, flags = 0x%.8x, name = %.30s\n",
1515 sym
->si_type
, sym
->si_sc_type
, sym
->si_flags
, name
);
1520 if (symbol_load_cmds
== 0)
1521 fatal ("no symbol table found");
1523 /* Update the program file now, rewrite header and load commands. At present,
1524 we assume that there is enough space after the last load command to insert
1525 one more. Since the first section written out is page aligned, and the
1526 number of load commands is small, this is ok for the present. */
1530 load_union_t
*load_map
;
1533 if (cmd_strings
== -1)
1534 fatal ("no cmd_strings found");
1536 /* Add __main to initializer list.
1537 If we are building a program instead of a shared library, don't
1538 do anything, since in the current version, you cannot do mallocs
1539 and such in the constructors. */
1541 if (main_sym
!= (symbol_info_t
*)0
1542 && ((hdr
.moh_flags
& MOH_EXECABLE_F
) == 0))
1543 add_func_table (&hdr
, load_array
, main_sym
, FNTC_INITIALIZATION
);
1546 fprintf (stderr
, "\nUpdating header and load commands.\n\n");
1548 hdr
.moh_n_load_cmds
++;
1549 size
= sizeof (load_cmd_map_command_t
) + (sizeof (mo_offset_t
) * (hdr
.moh_n_load_cmds
- 1));
1551 /* Create new load command map. */
1553 fprintf (stderr
, "load command map, %d cmds, new size %ld.\n",
1554 (int)hdr
.moh_n_load_cmds
, (long)size
);
1556 load_map
= (load_union_t
*) xcalloc (1, size
);
1557 load_map
->map
.ldc_header
.ldci_cmd_type
= LDC_CMD_MAP
;
1558 load_map
->map
.ldc_header
.ldci_cmd_size
= size
;
1559 load_map
->map
.lcm_ld_cmd_strings
= cmd_strings
;
1560 load_map
->map
.lcm_nentries
= hdr
.moh_n_load_cmds
;
1561 load_array
[hdr
.moh_n_load_cmds
-1].load
= load_map
;
1563 offset
= hdr
.moh_first_cmd_off
;
1564 for (i
= 0; i
< hdr
.moh_n_load_cmds
; i
++)
1566 load_map
->map
.lcm_map
[i
] = offset
;
1567 if (load_array
[i
].load
->hdr
.ldci_cmd_type
== LDC_CMD_MAP
)
1568 hdr
.moh_load_map_cmd_off
= offset
;
1570 offset
+= load_array
[i
].load
->hdr
.ldci_cmd_size
;
1573 hdr
.moh_sizeofcmds
= offset
- MO_SIZEOF_RAW_HDR
;
1576 print_header (&hdr
);
1579 status
= encode_mach_o_hdr (&hdr
, obj
, MO_SIZEOF_RAW_HDR
);
1580 if (status
!= MO_HDR_CONV_SUCCESS
)
1581 bad_header (status
);
1584 fprintf (stderr
, "writing load commands.\n\n");
1586 /* Write load commands */
1587 offset
= hdr
.moh_first_cmd_off
;
1588 for (i
= 0; i
< hdr
.moh_n_load_cmds
; i
++)
1590 load_union_t
*load_hdr
= load_array
[i
].load
;
1591 size_t size
= load_hdr
->hdr
.ldci_cmd_size
;
1594 print_load_command (load_hdr
, offset
, i
);
1596 bcopy ((generic
*)load_hdr
, (generic
*)(obj
+ offset
), size
);
1601 end_file (obj_file
);
1603 if (close (prog_fd
))
1604 fatal_perror ("closing %s", prog_name
);
1607 fprintf (stderr
, "\n");
1611 /* Add a function table to the load commands to call a function
1612 on initiation or termination of the process. */
1615 add_func_table (hdr_p
, load_array
, sym
, type
)
1616 mo_header_t
*hdr_p
; /* pointer to global header */
1617 load_all_t
*load_array
; /* array of ptrs to load cmds */
1618 symbol_info_t
*sym
; /* pointer to symbol entry */
1619 int type
; /* fntc_type value */
1621 /* Add a new load command. */
1622 int num_cmds
= ++hdr_p
->moh_n_load_cmds
;
1623 int load_index
= num_cmds
- 1;
1624 size_t size
= sizeof (func_table_command_t
) + sizeof (mo_addr_t
);
1625 load_union_t
*ptr
= xcalloc (1, size
);
1626 load_all_t
*load_cmd
;
1629 /* Set the unresolved address bit in the header to force the loader to be
1630 used, since kernel exec does not call the initialization functions. */
1631 hdr_p
->moh_flags
|= MOH_UNRESOLVED_F
;
1633 load_cmd
= &load_array
[load_index
];
1634 load_cmd
->load
= ptr
;
1635 load_cmd
->section
= (char *)0;
1637 /* Fill in func table load command. */
1638 ptr
->func
.ldc_header
.ldci_cmd_type
= LDC_FUNC_TABLE
;
1639 ptr
->func
.ldc_header
.ldci_cmd_size
= size
;
1640 ptr
->func
.ldc_header
.ldci_section_off
= 0;
1641 ptr
->func
.ldc_header
.ldci_section_len
= 0;
1642 ptr
->func
.fntc_type
= type
;
1643 ptr
->func
.fntc_nentries
= 1;
1645 /* copy address, turn it from abs. address to (region,offset) if necessary. */
1646 /* Is the symbol already expressed as (region, offset)? */
1647 if ((sym
->si_flags
& SI_ABSOLUTE_VALUE_F
) == 0)
1649 ptr
->func
.fntc_entry_loc
[i
].adr_lcid
= sym
->si_value
.def_val
.adr_lcid
;
1650 ptr
->func
.fntc_entry_loc
[i
].adr_sctoff
= sym
->si_value
.def_val
.adr_sctoff
;
1653 /* If not, figure out which region it's in. */
1656 mo_vm_addr_t addr
= sym
->si_value
.abs_val
;
1659 for (i
= 0; i
< load_index
; i
++)
1661 if (load_array
[i
].load
->hdr
.ldci_cmd_type
== LDC_REGION
)
1663 region_command_t
*region_ptr
= &load_array
[i
].load
->region
;
1665 if ((region_ptr
->regc_flags
& REG_ABS_ADDR_F
) != 0
1666 && addr
>= region_ptr
->regc_addr
.vm_addr
1667 && addr
<= region_ptr
->regc_addr
.vm_addr
+ region_ptr
->regc_vm_size
)
1669 ptr
->func
.fntc_entry_loc
[0].adr_lcid
= i
;
1670 ptr
->func
.fntc_entry_loc
[0].adr_sctoff
= addr
- region_ptr
->regc_addr
.vm_addr
;
1678 fatal ("could not convert 0x%l.8x into a region", addr
);
1683 "%s function, region %d, offset = %ld (0x%.8lx)\n",
1684 (type
== FNTC_INITIALIZATION
) ? "init" : "term",
1685 (int)ptr
->func
.fntc_entry_loc
[i
].adr_lcid
,
1686 (long)ptr
->func
.fntc_entry_loc
[i
].adr_sctoff
,
1687 (long)ptr
->func
.fntc_entry_loc
[i
].adr_sctoff
);
1692 /* Print the global header for an OSF/rose object. */
1695 print_header (hdr_ptr
)
1696 mo_header_t
*hdr_ptr
;
1698 fprintf (stderr
, "\nglobal header:\n");
1699 fprintf (stderr
, "\tmoh_magic = 0x%.8lx\n", hdr_ptr
->moh_magic
);
1700 fprintf (stderr
, "\tmoh_major_version = %d\n", (int)hdr_ptr
->moh_major_version
);
1701 fprintf (stderr
, "\tmoh_minor_version = %d\n", (int)hdr_ptr
->moh_minor_version
);
1702 fprintf (stderr
, "\tmoh_header_version = %d\n", (int)hdr_ptr
->moh_header_version
);
1703 fprintf (stderr
, "\tmoh_max_page_size = %d\n", (int)hdr_ptr
->moh_max_page_size
);
1704 fprintf (stderr
, "\tmoh_byte_order = %d\n", (int)hdr_ptr
->moh_byte_order
);
1705 fprintf (stderr
, "\tmoh_data_rep_id = %d\n", (int)hdr_ptr
->moh_data_rep_id
);
1706 fprintf (stderr
, "\tmoh_cpu_type = %d\n", (int)hdr_ptr
->moh_cpu_type
);
1707 fprintf (stderr
, "\tmoh_cpu_subtype = %d\n", (int)hdr_ptr
->moh_cpu_subtype
);
1708 fprintf (stderr
, "\tmoh_vendor_type = %d\n", (int)hdr_ptr
->moh_vendor_type
);
1709 fprintf (stderr
, "\tmoh_load_map_cmd_off = %d\n", (int)hdr_ptr
->moh_load_map_cmd_off
);
1710 fprintf (stderr
, "\tmoh_first_cmd_off = %d\n", (int)hdr_ptr
->moh_first_cmd_off
);
1711 fprintf (stderr
, "\tmoh_sizeofcmds = %d\n", (int)hdr_ptr
->moh_sizeofcmds
);
1712 fprintf (stderr
, "\tmon_n_load_cmds = %d\n", (int)hdr_ptr
->moh_n_load_cmds
);
1713 fprintf (stderr
, "\tmoh_flags = 0x%.8lx", (long)hdr_ptr
->moh_flags
);
1715 if (hdr_ptr
->moh_flags
& MOH_RELOCATABLE_F
)
1716 fprintf (stderr
, ", relocatable");
1718 if (hdr_ptr
->moh_flags
& MOH_LINKABLE_F
)
1719 fprintf (stderr
, ", linkable");
1721 if (hdr_ptr
->moh_flags
& MOH_EXECABLE_F
)
1722 fprintf (stderr
, ", execable");
1724 if (hdr_ptr
->moh_flags
& MOH_EXECUTABLE_F
)
1725 fprintf (stderr
, ", executable");
1727 if (hdr_ptr
->moh_flags
& MOH_UNRESOLVED_F
)
1728 fprintf (stderr
, ", unresolved");
1730 fprintf (stderr
, "\n\n");
1735 /* Print a short summary of a load command. */
1738 print_load_command (load_hdr
, offset
, number
)
1739 load_union_t
*load_hdr
;
1743 mo_long_t type
= load_hdr
->hdr
.ldci_cmd_type
;
1744 char *type_str
= (char *)0;
1748 case LDC_UNDEFINED
: type_str
= "UNDEFINED"; break;
1749 case LDC_CMD_MAP
: type_str
= "CMD_MAP"; break;
1750 case LDC_INTERPRETER
: type_str
= "INTERPRETER"; break;
1751 case LDC_STRINGS
: type_str
= "STRINGS"; break;
1752 case LDC_REGION
: type_str
= "REGION"; break;
1753 case LDC_RELOC
: type_str
= "RELOC"; break;
1754 case LDC_PACKAGE
: type_str
= "PACKAGE"; break;
1755 case LDC_SYMBOLS
: type_str
= "SYMBOLS"; break;
1756 case LDC_ENTRY
: type_str
= "ENTRY"; break;
1757 case LDC_FUNC_TABLE
: type_str
= "FUNC_TABLE"; break;
1758 case LDC_GEN_INFO
: type_str
= "GEN_INFO"; break;
1762 "cmd %2d, sz: 0x%.2lx, coff: 0x%.3lx, doff: 0x%.6lx, dlen: 0x%.6lx",
1764 (long) load_hdr
->hdr
.ldci_cmd_size
,
1766 (long) load_hdr
->hdr
.ldci_section_off
,
1767 (long) load_hdr
->hdr
.ldci_section_len
);
1769 if (type_str
== (char *)0)
1770 fprintf (stderr
, ", ty: unknown (%ld)\n", (long) type
);
1772 else if (type
!= LDC_REGION
)
1773 fprintf (stderr
, ", ty: %s\n", type_str
);
1778 switch (load_hdr
->region
.regc_usage_type
)
1780 case REG_TEXT_T
: region
= ", .text"; break;
1781 case REG_DATA_T
: region
= ", .data"; break;
1782 case REG_BSS_T
: region
= ", .bss"; break;
1783 case REG_GLUE_T
: region
= ", .glue"; break;
1784 #if defined (REG_RDATA_T) && defined (REG_SDATA_T) && defined (REG_SBSS_T) /*mips*/
1785 case REG_RDATA_T
: region
= ", .rdata"; break;
1786 case REG_SDATA_T
: region
= ", .sdata"; break;
1787 case REG_SBSS_T
: region
= ", .sbss"; break;
1791 fprintf (stderr
, ", ty: %s, vaddr: 0x%.8lx, vlen: 0x%.6lx%s\n",
1793 (long) load_hdr
->region
.regc_vm_addr
,
1794 (long) load_hdr
->region
.regc_vm_size
,
1802 /* Fatal error when {en,de}code_mach_o_header fails. */
1808 char *msg
= (char *)0;
1812 case MO_ERROR_BAD_MAGIC
: msg
= "bad magic number"; break;
1813 case MO_ERROR_BAD_HDR_VERS
: msg
= "bad header version"; break;
1814 case MO_ERROR_BAD_RAW_HDR_VERS
: msg
= "bad raw header version"; break;
1815 case MO_ERROR_BUF2SML
: msg
= "raw header buffer too small"; break;
1816 case MO_ERROR_OLD_RAW_HDR_FILE
: msg
= "old raw header file"; break;
1817 case MO_ERROR_UNSUPPORTED_VERS
: msg
= "unsupported version"; break;
1820 if (msg
== (char *)0)
1821 fatal ("unknown {de,en}code_mach_o_hdr return value %d", status
);
1827 /* Read a file into a memory buffer. */
1829 static struct file_info
*
1830 read_file (name
, fd
, rw
)
1831 char *name
; /* filename */
1832 int fd
; /* file descriptor */
1833 int rw
; /* read/write */
1835 struct stat stat_pkt
;
1836 struct file_info
*p
= (struct file_info
*) xcalloc (sizeof (struct file_info
), 1);
1838 static int page_size
;
1841 if (fstat (fd
, &stat_pkt
) < 0)
1842 fatal_perror ("fstat %s", name
);
1845 p
->size
= stat_pkt
.st_size
;
1846 p
->rounded_size
= stat_pkt
.st_size
;
1852 fprintf (stderr
, "mmap %s, %s\n", name
, (rw
) ? "read/write" : "read-only");
1855 page_size
= sysconf (_SC_PAGE_SIZE
);
1857 p
->rounded_size
= ((p
->size
+ page_size
- 1) / page_size
) * page_size
;
1858 p
->start
= mmap ((caddr_t
)0,
1859 (rw
) ? p
->rounded_size
: p
->size
,
1860 (rw
) ? (PROT_READ
| PROT_WRITE
) : PROT_READ
,
1861 MAP_FILE
| MAP_VARIABLE
| MAP_SHARED
,
1865 if (p
->start
!= (char *)0 && p
->start
!= (char *)-1)
1869 #endif /* USE_MMAP */
1874 fprintf (stderr
, "read %s\n", name
);
1877 p
->start
= xmalloc (p
->size
);
1878 if (lseek (fd
, 0L, SEEK_SET
) < 0)
1879 fatal_perror ("lseek to 0 on %s", name
);
1881 len
= read (fd
, p
->start
, p
->size
);
1883 fatal_perror ("read %s", name
);
1886 fatal ("read %ld bytes, expected %ld, from %s", len
, p
->size
, name
);
1893 /* Do anything necessary to write a file back from memory. */
1897 struct file_info
*ptr
; /* file information block */
1905 fprintf (stderr
, "msync %s\n", ptr
->name
);
1907 if (msync (ptr
->start
, ptr
->rounded_size
, MS_ASYNC
))
1908 fatal_perror ("msync %s", ptr
->name
);
1912 fprintf (stderr
, "munmap %s\n", ptr
->name
);
1914 if (munmap (ptr
->start
, ptr
->size
))
1915 fatal_perror ("munmap %s", ptr
->name
);
1918 #endif /* USE_MMAP */
1925 fprintf (stderr
, "write %s\n", ptr
->name
);
1927 if (lseek (ptr
->fd
, 0L, SEEK_SET
) < 0)
1928 fatal_perror ("lseek to 0 on %s", ptr
->name
);
1930 len
= write (ptr
->fd
, ptr
->start
, ptr
->size
);
1932 fatal_perror ("read %s", ptr
->name
);
1934 if (len
!= ptr
->size
)
1935 fatal ("wrote %ld bytes, expected %ld, to %s", len
, ptr
->size
, ptr
->name
);
1938 free ((generic
*)ptr
->start
);
1941 free ((generic
*)ptr
);
1944 #endif /* OBJECT_FORMAT_ROSE */