]> gcc.gnu.org Git - gcc.git/blob - gcc/collect2.c
entered into RCS
[gcc.git] / gcc / collect2.c
1 /* Collect static initialization info into data structures
2 that can be traversed by C++ initialization and finalization
3 routines.
4
5 Copyright (C) 1992 Free Software Foundation, Inc.
6 Contributed by Chris Smith (csmith@convex.com).
7 Heavily modified by Michael Meissner (meissner@osf.org),
8 Per Bothner (bothner@cygnus.com), and John Gilmore (gnu@cygnus.com).
9
10 This file is part of GNU CC.
11
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)
15 any later version.
16
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.
21
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. */
25
26
27 /* Build tables of static constructors and destructors and run ld. */
28
29 #include <sys/types.h>
30 #include <stdio.h>
31 #include <ctype.h>
32 #include <errno.h>
33 #include <signal.h>
34 #include <sys/file.h>
35 #include <sys/stat.h>
36 #ifdef NO_WAIT_H
37 #include <sys/wait.h>
38 #endif
39
40 #ifndef errno
41 extern int errno;
42 #endif
43
44 #define COLLECT
45
46 #include "config.h"
47
48 #ifndef __STDC__
49 #define generic char
50 #define const
51
52 #else
53 #define generic void
54 #endif
55
56 #ifdef USG
57 #define vfork fork
58 #endif
59
60 #ifndef R_OK
61 #define R_OK 4
62 #define W_OK 2
63 #define X_OK 1
64 #endif
65
66 /* On MSDOS, write temp files in current dir
67 because there's no place else we can expect to use. */
68 #if __MSDOS__
69 #ifndef P_tmpdir
70 #define P_tmpdir "./"
71 #endif
72 #endif
73 \f
74 /* On certain systems, we have code that works by scanning the object file
75 directly. But this code uses system-specific header files and library
76 functions, so turn it off in a cross-compiler. */
77
78 #ifdef CROSS_COMPILE
79 #undef OBJECT_FORMAT_COFF
80 #undef OBJECT_FORMAT_ROSE
81 #endif
82
83 /* If we can't use a special method, use the ordinary one:
84 run nm to find what symbols are present.
85 In a cross-compiler, this means you need a cross nm,
86 but that isn't quite as unpleasant as special headers. */
87
88 #if !defined (OBJECT_FORMAT_COFF) && !defined (OBJECT_FORMAT_ROSE)
89 #define OBJECT_FORMAT_NONE
90 #endif
91
92 #ifdef OBJECT_FORMAT_COFF
93
94 #include <a.out.h>
95 #include <ar.h>
96
97 #ifdef UMAX
98 #include <sgs.h>
99 #endif
100
101 #ifdef _AIX
102 #define ISCOFF(magic) \
103 ((magic) == U802WRMAGIC || (magic) == U802ROMAGIC || (magic) == U802TOCMAGIC)
104 #endif
105
106 #if defined (_AIX) || defined (USG)
107 #undef FREAD
108 #undef FWRITE
109 #endif
110
111 #include <ldfcn.h>
112
113 /* Mips-news overrides this macro. */
114 #ifndef MY_ISCOFF
115 #define MY_ISCOFF(X) ISCOFF (X)
116 #endif
117
118 #endif /* OBJECT_FORMAT_COFF */
119
120 #ifdef OBJECT_FORMAT_ROSE
121
122 #ifdef _OSF_SOURCE
123 #define USE_MMAP
124 #endif
125
126 #ifdef USE_MMAP
127 #include <sys/mman.h>
128 #endif
129
130 #include <unistd.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>
135
136 #endif /* OBJECT_FORMAT_ROSE */
137
138 #ifdef OBJECT_FORMAT_NONE
139
140 /* Default flags to pass to nm. */
141 #ifndef NM_FLAGS
142 #define NM_FLAGS "-p"
143 #endif
144
145 #endif /* OBJECT_FORMAT_NONE */
146 \f
147 /* Linked lists of constructor and destructor names. */
148
149 struct id
150 {
151 struct id *next;
152 int sequence;
153 char name[1];
154 };
155
156 struct head
157 {
158 struct id *first;
159 struct id *last;
160 int number;
161 };
162
163 /* Enumeration giving which pass this is for scanning the program file. */
164
165 enum pass {
166 PASS_FIRST, /* without constructors */
167 PASS_SECOND /* with constructors linked in */
168 };
169
170 #ifndef NO_SYS_SIGLIST
171 extern char *sys_siglist[];
172 #endif
173 extern char *version_string;
174
175 static int vflag; /* true if -v */
176 static int rflag; /* true if -r */
177 static int strip_flag; /* true if -s */
178
179 static int debug; /* true if -debug */
180
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 */
187
188 static struct head constructors; /* list of constructors found */
189 static struct head destructors; /* list of destructors found */
190
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 ();
202
203 generic *xcalloc ();
204 generic *xmalloc ();
205
206 extern char *index ();
207 extern char *rindex ();
208 \f
209 #ifdef NO_DUP2
210 dup2 (oldfd, newfd)
211 int oldfd;
212 int newfd;
213 {
214 int fdtmp[256];
215 int fdx = 0;
216 int fd;
217
218 if (oldfd == newfd)
219 return 0;
220 close (newfd);
221 while ((fd = dup (oldfd)) != newfd) /* good enough for low fd's */
222 fdtmp[fdx++] = fd;
223 while (fdx > 0)
224 close (fdtmp[--fdx]);
225 }
226 #endif
227
228 char *
229 my_strerror (e)
230 int e;
231 {
232 extern char *sys_errlist[];
233 extern int sys_nerr;
234 static char buffer[30];
235
236 if (!e)
237 return "";
238
239 if (e > 0 && e < sys_nerr)
240 return sys_errlist[e];
241
242 sprintf (buffer, "Unknown error %d", e);
243 return buffer;
244 }
245 \f
246 /* Delete tempfiles and exit function. */
247
248 static void
249 my_exit (status)
250 int status;
251 {
252 if (c_file != 0 && c_file[0])
253 maybe_unlink (c_file);
254
255 if (o_file != 0 && o_file[0])
256 maybe_unlink (o_file);
257
258 exit (status);
259 }
260
261 \f
262 /* Die when sys call fails. */
263
264 static void
265 fatal_perror (string, arg1, arg2, arg3)
266 char *string;
267 {
268 int e = errno;
269
270 fprintf (stderr, "collect: ");
271 fprintf (stderr, string, arg1, arg2, arg3);
272 fprintf (stderr, ": %s\n", my_strerror (e));
273 my_exit (1);
274 }
275
276 /* Just die. */
277
278 static void
279 fatal (string, arg1, arg2, arg3)
280 char *string;
281 {
282 fprintf (stderr, "collect: ");
283 fprintf (stderr, string, arg1, arg2, arg3);
284 fprintf (stderr, "\n");
285 my_exit (1);
286 }
287
288 /* Write error message. */
289
290 static void
291 error (string, arg1, arg2, arg3, arg4)
292 char *string;
293 {
294 fprintf (stderr, "collect: ");
295 fprintf (stderr, string, arg1, arg2, arg3, arg4);
296 fprintf (stderr, "\n");
297 }
298
299 /* In case obstack is linked in, and abort is defined to fancy_abort,
300 provide a default entry. */
301
302 void
303 fancy_abort ()
304 {
305 fatal ("internal error");
306 }
307
308 \f
309 static void
310 handler (signo)
311 int signo;
312 {
313 if (c_file[0])
314 maybe_unlink (c_file);
315
316 if (o_file[0])
317 maybe_unlink (o_file);
318
319 signal (signo, SIG_DFL);
320 kill (getpid (), signo);
321 }
322
323 \f
324 generic *
325 xcalloc (size1, size2)
326 int size1, size2;
327 {
328 generic *ptr = (generic *) calloc (size1, size2);
329 if (ptr)
330 return ptr;
331
332 fatal ("out of memory");
333 return (generic *)0;
334 }
335
336 generic *
337 xmalloc (size)
338 int size;
339 {
340 generic *ptr = (generic *) malloc (size);
341 if (ptr)
342 return ptr;
343
344 fatal ("out of memory");
345 return (generic *)0;
346 }
347
348 /* Make a copy of a string INPUT with size SIZE. */
349
350 char *
351 savestring (input, size)
352 char *input;
353 int size;
354 {
355 char *output = (char *) xmalloc (size + 1);
356 bcopy (input, output, size);
357 output[size] = 0;
358 return output;
359 }
360 \f
361 /* Decide whether the given symbol is:
362 a constructor (1), a destructor (2), or neither (0). */
363
364 static int
365 is_ctor_dtor (s)
366 char *s;
367 {
368 struct names { char *name; int len; int ret; int two_underscores; };
369
370 register struct names *p;
371 register int ch;
372 register char *orig_s = s;
373
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 },
378 #else
379 { "GLOBAL_$I$", sizeof ("GLOBAL_$I$")-1, 1, 0 },
380 { "GLOBAL_$D$", sizeof ("GLOBAL_$I$")-1, 2, 0 },
381 #endif
382 { "sti__", sizeof ("sti__")-1, 1, 1 },
383 { "std__", sizeof ("std__")-1, 2, 1 },
384 { NULL, 0, 0, 0 }
385 };
386
387 while ((ch = *s) == '_')
388 ++s;
389
390 if (s == orig_s)
391 return 0;
392
393 for (p = &special[0]; p->len > 0; p++)
394 {
395 if (ch == p->name[0]
396 && (!p->two_underscores || ((s - orig_s) >= 2))
397 && strncmp(s, p->name, p->len) == 0)
398 {
399 return p->ret;
400 }
401 }
402 return 0;
403 }
404
405 \f
406 /* Compute a string to use as the base of all temporary file names.
407 It is substituted for %g. */
408
409 static void
410 choose_temp_base ()
411 {
412 char *base = getenv ("TMPDIR");
413 int len;
414
415 if (base == (char *)0)
416 {
417 #ifdef P_tmpdir
418 if (access (P_tmpdir, R_OK | W_OK) == 0)
419 base = P_tmpdir;
420 #endif
421 if (base == (char *)0)
422 {
423 if (access ("/usr/tmp", R_OK | W_OK) == 0)
424 base = "/usr/tmp/";
425 else
426 base = "/tmp/";
427 }
428 }
429
430 len = strlen (base);
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");
436
437 mktemp (temp_filename);
438 temp_filename_length = strlen (temp_filename);
439 }
440
441 \f
442 /* Main program. */
443
444 int
445 main (argc, argv)
446 int argc;
447 char *argv[];
448 {
449 char *outfile = "a.out";
450 char *arg;
451 FILE *outf;
452 char *ld_file_name;
453 char *c_file_name;
454 char *p;
455 char *prefix;
456 char **c_argv;
457 char **c_ptr;
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;
462 int first_file;
463 int num_c_args = argc+7;
464 int len;
465 int clen;
466
467 #ifdef DEBUG
468 debug = 1;
469 vflag = 1;
470 #endif
471
472 p = (char *) getenv ("COLLECT_GCC_OPTIONS");
473 if (p)
474 while (*p)
475 {
476 char *q = p;
477 while (*q && *q != ' ') q++;
478 if (*p == '-' && p[1] == 'm')
479 num_c_args++;
480
481 if (*q) q++;
482 p = q;
483 }
484
485 c_ptr = c_argv = (char **) xcalloc (sizeof (char *), num_c_args);
486
487 if (argc < 2)
488 fatal ("no arguments");
489
490 signal (SIGQUIT, handler);
491 signal (SIGINT, handler);
492 signal (SIGALRM, handler);
493 signal (SIGHUP, handler);
494 signal (SIGSEGV, handler);
495 signal (SIGBUS, handler);
496
497 /* Try to discover a valid linker/assembler/nm/strip to use. */
498 len = strlen (argv[0]);
499 prefix = (char *)0;
500 if (len >= sizeof ("ld")-1)
501 {
502 p = argv[0] + len - sizeof ("ld") + 1;
503 if (strcmp (p, "ld") == 0)
504 {
505 prefix = argv[0];
506 *p = '\0';
507 }
508 }
509
510 if (prefix == (char *)0)
511 {
512 p = rindex (argv[0], '/');
513 if (p != (char *)0)
514 {
515 prefix = argv[0];
516 p[1] = '\0';
517 }
518
519 #ifdef STANDARD_EXEC_PREFIX
520 else if (access (STANDARD_EXEC_PREFIX, X_OK) == 0)
521 prefix = STANDARD_EXEC_PREFIX;
522 #endif
523
524 #ifdef MD_EXEC_PREFIX
525 else if (access (MD_EXEC_PREFIX, X_OK) == 0)
526 prefix = MD_EXEC_PREFIX;
527 #endif
528
529 else if (access ("/usr/ccs/gcc", X_OK) == 0)
530 prefix = "/usr/ccs/gcc/";
531
532 else if (access ("/usr/ccs/bin", X_OK) == 0)
533 prefix = "/usr/ccs/bin/";
534
535 else
536 prefix = "/bin/";
537 }
538
539 clen = len = strlen (prefix);
540
541 #ifdef STANDARD_BIN_PREFIX
542 if (clen < sizeof (STANDARD_BIN_PREFIX) - 1)
543 clen = sizeof (STANDARD_BIN_PREFIX) - 1;
544 #endif
545
546 #ifdef STANDARD_EXEC_PREFIX
547 if (clen < sizeof (STANDARD_EXEC_PREFIX) - 1)
548 clen = sizeof (STANDARD_EXEC_PREFIX) - 1;
549 #endif
550
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);
555
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)
560 {
561 strcpy (ld_file_name + len, "gld");
562 if (access (ld_file_name, X_OK) < 0)
563 {
564 free (ld_file_name);
565 #ifdef REAL_LD_FILE_NAME
566 ld_file_name = REAL_LD_FILE_NAME;
567 #else
568 ld_file_name = (access ("/usr/bin/ld", X_OK) == 0
569 ? "/usr/bin/ld" : "/bin/ld");
570 #endif
571 }
572 }
573
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] != '/')
577 {
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)
582 {
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)
587 #endif
588 {
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)
593 #endif
594 {
595 strcpy (c_file_name, "gcc");
596 }
597 }
598 }
599 }
600
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)
605 {
606 strcpy (nm_file_name + len, "gnm");
607 if (access (nm_file_name, X_OK) < 0)
608 {
609 free (nm_file_name);
610 #ifdef REAL_NM_FILE_NAME
611 nm_file_name = REAL_NM_FILE_NAME;
612 #else
613 nm_file_name = (access ("/usr/bin/nm", X_OK) == 0
614 ? "/usr/bin/nm" : "/bin/nm");
615 #endif
616 }
617 }
618
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)
623 {
624 strcpy (strip_file_name + len, "gstrip");
625 if (access (strip_file_name, X_OK) < 0)
626 {
627 free (strip_file_name);
628 #ifdef REAL_STRIP_FILE_NAME
629 strip_file_name = REAL_STRIP_FILE_NAME;
630 #else
631 strip_file_name = (access ("/usr/bin/strip", X_OK) == 0
632 ? "/usr/bin/strip" : "/bin/strip");
633 #endif
634 }
635 }
636
637 *ld1++ = *ld2++ = "ld";
638
639 /* Make temp file names. */
640 choose_temp_base ();
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;
646 *c_ptr++ = "-c";
647 *c_ptr++ = "-o";
648 *c_ptr++ = o_file;
649
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!!! */
656
657 /* Parse arguments. Remember output file spec, pass the rest to ld. */
658 /* After the first file, put in the c++ rt0. */
659
660 first_file = 1;
661 while ((arg = *++argv) != (char *)0)
662 {
663 *ld1++ = *ld2++ = arg;
664
665 if (arg[0] == '-')
666 switch (arg[1])
667 {
668 case 'd':
669 if (!strcmp (arg, "-debug"))
670 {
671 debug = 1;
672 vflag = 1;
673 ld1--;
674 ld2--;
675 }
676 break;
677
678 case 'o':
679 outfile = (arg[2] == '\0') ? argv[1] : &arg[2];
680 break;
681
682 case 'r':
683 if (arg[2] == '\0')
684 rflag = 1;
685 break;
686
687 case 's':
688 if (arg[2] == '\0')
689 {
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. */
693 strip_flag = 1;
694 ld1--;
695 }
696 break;
697
698 case 'v':
699 if (arg[2] == '\0')
700 vflag = 1;
701 break;
702 }
703
704 else if (first_file
705 && (p = rindex (arg, '.')) != (char *)0
706 && strcmp (p, ".o") == 0)
707 {
708 first_file = 0;
709 *ld2++ = o_file;
710 }
711 }
712
713 /* Get any options that the upper GCC wants to pass to the sub-GCC. */
714 p = (char *) getenv ("COLLECT_GCC_OPTIONS");
715 if (p)
716 while (*p)
717 {
718 char *q = p;
719 while (*q && *q != ' ') q++;
720 if (*p == '-' && (p[1] == 'm' || p[1] == 'f'))
721 *c_ptr++ = savestring (p, q - p);
722
723 if (*q) q++;
724 p = q;
725 }
726
727 *c_ptr++ = c_file;
728 *c_ptr = *ld1 = *ld2 = (char *)0;
729
730 if (vflag)
731 {
732 fprintf (stderr, "collect2 version %s", version_string);
733 #ifdef TARGET_VERSION
734 TARGET_VERSION;
735 #endif
736 fprintf (stderr, "\n");
737 }
738
739 if (debug)
740 {
741 char *ptr;
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);
748
749 ptr = getenv ("COLLECT_GCC_OPTIONS");
750 if (ptr)
751 fprintf (stderr, "COLLECT_GCC_OPTIONS = %s\n", ptr);
752
753 ptr = getenv ("COLLECT_GCC");
754 if (ptr)
755 fprintf (stderr, "COLLECT_GCC = %s\n", ptr);
756
757 ptr = getenv ("COMPILER_PATH");
758 if (ptr)
759 fprintf (stderr, "COMPILER_PATH = %s\n", ptr);
760
761 ptr = getenv ("LIBRARY_PATH");
762 if (ptr)
763 fprintf (stderr, "LIBRARY_PATH = %s\n", ptr);
764
765 fprintf (stderr, "\n");
766 }
767
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. */
772
773 fork_execute (ld_file_name, ld1_argv);
774
775 /* If -r, don't build the constructor or destructor list, just return now. */
776 if (rflag)
777 return 0;
778
779 scan_prog_file (outfile, PASS_FIRST);
780
781 if (debug)
782 {
783 fprintf (stderr, "%d constructor(s) found\n", constructors.number);
784 fprintf (stderr, "%d destructor(s) found\n", destructors.number);
785 }
786
787 if (constructors.number == 0 && destructors.number == 0)
788 {
789 /* Strip now if it was requested on the command line. */
790 if (strip_flag)
791 {
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);
797 }
798 return 0;
799 }
800
801 outf = fopen (c_file, "w");
802 if (outf == (FILE *)0)
803 fatal_perror ("%s", c_file);
804
805 write_c_file (outf, c_file);
806
807 if (fclose (outf))
808 fatal_perror ("closing %s", c_file);
809
810 if (debug)
811 {
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");
815 }
816
817 /* Assemble the constructor and destructor tables.
818 Link the tables in with the rest of the program. */
819
820 fork_execute (c_file_name, c_argv);
821 fork_execute (ld_file_name, ld2_argv);
822
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);
826
827 maybe_unlink (c_file);
828 maybe_unlink (o_file);
829 return 0;
830 }
831
832 \f
833 /* Wait for a process to finish, and exit if a non-zero status is found. */
834
835 static void
836 do_wait (prog)
837 char *prog;
838 {
839 int status;
840
841 wait (&status);
842 if (status)
843 {
844 int sig = status & 0x7F;
845 int ret;
846
847 if (sig != -1 && sig != 0)
848 {
849 #ifdef NO_SYS_SIGLIST
850 error ("%s terminated with signal %d %s",
851 prog,
852 sig,
853 (status & 0200) ? ", core dumped" : "");
854 #else
855 error ("%s terminated with signal %d [%s]%s",
856 prog,
857 sig,
858 sys_siglist[sig],
859 (status & 0200) ? ", core dumped" : "");
860 #endif
861
862 my_exit (127);
863 }
864
865 ret = ((status & 0xFF00) >> 8);
866 if (ret != -1 && ret != 0)
867 {
868 error ("%s returned %d exit status", prog, ret);
869 my_exit (ret);
870 }
871 }
872 }
873
874 \f
875 /* Fork and execute a program, and wait for the reply. */
876
877 static void
878 fork_execute (prog, argv)
879 char *prog;
880 char **argv;
881 {
882 int pid;
883 void (*int_handler) ();
884 void (*quit_handler) ();
885
886 if (vflag || debug)
887 {
888 char **p_argv;
889 char *str;
890
891 fprintf (stderr, "%s", prog);
892 for (p_argv = &argv[1]; (str = *p_argv) != (char *)0; p_argv++)
893 fprintf (stderr, " %s", str);
894
895 fprintf (stderr, "\n");
896 }
897
898 fflush (stdout);
899 fflush (stderr);
900
901 pid = vfork ();
902 if (pid == -1)
903 fatal_perror ("vfork");
904
905 if (pid == 0) /* child context */
906 {
907 execvp (prog, argv);
908 fatal_perror ("executing %s", prog);
909 }
910
911 int_handler = (void (*) ())signal (SIGINT, SIG_IGN);
912 quit_handler = (void (*) ())signal (SIGQUIT, SIG_IGN);
913
914 do_wait (prog);
915
916 signal (SIGINT, int_handler);
917 signal (SIGQUIT, quit_handler);
918 }
919
920 \f
921 /* Unlink a file unless we are debugging. */
922
923 static void
924 maybe_unlink (file)
925 char *file;
926 {
927 if (!debug)
928 unlink (file);
929 else
930 fprintf (stderr, "[Leaving %s]\n", file);
931 }
932
933 \f
934 /* Add a name to a linked list. */
935
936 static void
937 add_to_list (head_ptr, name)
938 struct head *head_ptr;
939 char *name;
940 {
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);
945
946 if (head_ptr->first)
947 head_ptr->last->next = newid;
948 else
949 head_ptr->first = newid;
950
951 head_ptr->last = newid;
952 head_ptr->number++;
953 }
954
955 /* Write: `prefix', the names on list LIST, `suffix'. */
956
957 static void
958 write_list (stream, prefix, list)
959 FILE *stream;
960 char *prefix;
961 struct id *list;
962 {
963 while (list)
964 {
965 fprintf (stream, "%sx%d,\n", prefix, list->sequence);
966 list = list->next;
967 }
968 }
969
970 static void
971 write_list_with_asm (stream, prefix, list)
972 FILE *stream;
973 char *prefix;
974 struct id *list;
975 {
976 while (list)
977 {
978 fprintf (stream, "%sx%d asm (\"%s\");\n",
979 prefix, list->sequence, list->name);
980 list = list->next;
981 }
982 }
983
984 /* Write the constructor/destructor tables. */
985
986 static void
987 write_c_file (stream, name)
988 FILE *stream;
989 char *name;
990 {
991 /* Write the tables as C code */
992
993 fprintf (stream, "typedef void entry_pt();\n\n");
994
995 write_list_with_asm (stream, "extern entry_pt ", constructors.first);
996
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");
1001
1002 write_list_with_asm (stream, "extern entry_pt ", destructors.first);
1003
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");
1008
1009 fprintf (stream, "extern entry_pt __main;\n");
1010 fprintf (stream, "entry_pt *__main_reference = __main;\n\n");
1011 }
1012
1013 \f
1014 #ifdef OBJECT_FORMAT_NONE
1015
1016 /* Generic version to scan the name list of the loaded program for
1017 the symbols g++ uses for static constructors and destructors.
1018
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__. */
1024
1025 static void
1026 scan_prog_file (prog_name, which_pass)
1027 char *prog_name;
1028 enum pass which_pass;
1029 {
1030 void (*int_handler) ();
1031 void (*quit_handler) ();
1032 char *nm_argv[4];
1033 int pid;
1034 int argc = 0;
1035 int pipe_fd[2];
1036 char *p, buf[1024];
1037 FILE *inf;
1038
1039 if (which_pass != PASS_FIRST)
1040 return;
1041
1042 nm_argv[argc++] = "nm";
1043 if (NM_FLAGS[0] != '\0')
1044 nm_argv[argc++] = NM_FLAGS;
1045
1046 nm_argv[argc++] = prog_name;
1047 nm_argv[argc++] = (char *)0;
1048
1049 if (pipe (pipe_fd) < 0)
1050 fatal_perror ("pipe");
1051
1052 inf = fdopen (pipe_fd[0], "r");
1053 if (inf == (FILE *)0)
1054 fatal_perror ("fdopen");
1055
1056 /* Trace if needed. */
1057 if (vflag)
1058 {
1059 char **p_argv;
1060 char *str;
1061
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);
1065
1066 fprintf (stderr, "\n");
1067 }
1068
1069 fflush (stdout);
1070 fflush (stderr);
1071
1072 /* Spawn child nm on pipe */
1073 pid = vfork ();
1074 if (pid == -1)
1075 fatal_perror ("vfork");
1076
1077 if (pid == 0) /* child context */
1078 {
1079 /* setup stdout */
1080 if (dup2 (pipe_fd[1], 1) < 0)
1081 fatal_perror ("dup2 (%d, 1)", pipe_fd[1]);
1082
1083 if (close (pipe_fd[0]) < 0)
1084 fatal_perror ("close (%d)", pipe_fd[0]);
1085
1086 if (close (pipe_fd[1]) < 0)
1087 fatal_perror ("close (%d)", pipe_fd[1]);
1088
1089 execv (nm_file_name, nm_argv);
1090 fatal_perror ("executing %s", nm_file_name);
1091 }
1092
1093 /* Parent context from here on. */
1094 int_handler = (void (*) ())signal (SIGINT, SIG_IGN);
1095 quit_handler = (void (*) ())signal (SIGQUIT, SIG_IGN);
1096
1097 if (close (pipe_fd[1]) < 0)
1098 fatal_perror ("close (%d)", pipe_fd[1]);
1099
1100 if (debug)
1101 fprintf (stderr, "\nnm output with constructors/destructors.\n");
1102
1103 /* Read each line of nm output. */
1104 while (fgets (buf, sizeof buf, inf) != (char *)0)
1105 {
1106 int ch, ch2;
1107 char *name, *end;
1108
1109 /* If it contains a constructor or destructor name, add the name
1110 to the appropriate list. */
1111
1112 for (p = buf; (ch = *p) != '\0' && ch != '\n' && ch != '_'; p++)
1113 ;
1114
1115 if (ch == '\0' || ch == '\n')
1116 continue;
1117
1118 name = p;
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 != '|';
1122 end++)
1123 continue;
1124
1125 *end = '\0';
1126 switch (is_ctor_dtor (name))
1127 {
1128 case 1:
1129 add_to_list (&constructors, name);
1130 break;
1131
1132 case 2:
1133 add_to_list (&destructors, name);
1134 break;
1135
1136 default: /* not a constructor or destructor */
1137 continue;
1138 }
1139
1140 if (debug)
1141 fprintf (stderr, "\t%s\n", buf);
1142 }
1143
1144 if (debug)
1145 fprintf (stderr, "\n");
1146
1147 if (fclose (inf) != 0)
1148 fatal_perror ("fclose of pipe");
1149
1150 do_wait (nm_file_name);
1151
1152 signal (SIGINT, int_handler);
1153 signal (SIGQUIT, quit_handler);
1154 }
1155
1156 #endif /* OBJECT_FORMAT_NONE */
1157
1158 \f
1159 /*
1160 * COFF specific stuff.
1161 */
1162
1163 #ifdef OBJECT_FORMAT_COFF
1164
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)
1172 #else
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)
1182 #endif
1183
1184 extern char *ldgetname ();
1185
1186 /* COFF version to scan the name list of the loaded program for
1187 the symbols g++ uses for static constructors and destructors.
1188
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__. */
1194
1195 static void
1196 scan_prog_file (prog_name, which_pass)
1197 char *prog_name;
1198 enum pass which_pass;
1199 {
1200 LDFILE *ldptr = NULL;
1201 int sym_index, sym_count;
1202
1203 if (which_pass != PASS_FIRST)
1204 return;
1205
1206 if ((ldptr = ldopen (prog_name, ldptr)) == NULL)
1207 fatal ("%s: can't open as COFF file", prog_name);
1208
1209 if (!MY_ISCOFF (HEADER (ldptr).f_magic))
1210 fatal ("%s: not a COFF file", prog_name);
1211
1212 if (GCC_CHECK_HDR (ldptr))
1213 {
1214 sym_count = GCC_SYMBOLS (ldptr);
1215 sym_index = GCC_SYMZERO (ldptr);
1216 while (sym_index < sym_count)
1217 {
1218 GCC_SYMENT symbol;
1219
1220 if (ldtbread (ldptr, sym_index, &symbol) <= 0)
1221 break;
1222 sym_index += GCC_SYMINC (symbol);
1223
1224 if (GCC_OK_SYMBOL (symbol))
1225 {
1226 char *name;
1227
1228 if ((name = ldgetname (ldptr, &symbol)) == NULL)
1229 continue; /* should never happen */
1230
1231 #ifdef _AIX
1232 /* All AIX function names begin with a dot. */
1233 if (*name++ != '.')
1234 continue;
1235 #endif
1236
1237 switch (is_ctor_dtor (name))
1238 {
1239 case 1:
1240 add_to_list (&constructors, name);
1241 break;
1242
1243 case 2:
1244 add_to_list (&destructors, name);
1245 break;
1246
1247 default: /* not a constructor or destructor */
1248 continue;
1249 }
1250
1251 #if !defined(EXTENDED_COFF)
1252 if (debug)
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,
1256 name);
1257 #else
1258 if (debug)
1259 fprintf (stderr, "\tiss = %5d, value = %5d, index = %5d, name = %s\n",
1260 symbol.iss, symbol.value, symbol.index, name);
1261 #endif
1262 }
1263 }
1264 }
1265
1266 (void) ldclose(ldptr);
1267 }
1268
1269 #endif /* OBJECT_FORMAT_COFF */
1270
1271 \f
1272 /*
1273 * OSF/rose specific stuff.
1274 */
1275
1276 #ifdef OBJECT_FORMAT_ROSE
1277
1278 /* Union of the various load commands */
1279
1280 typedef union load_union
1281 {
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 */
1293 } load_union_t;
1294
1295 /* Structure to point to load command and data section in memory. */
1296
1297 typedef struct load_all
1298 {
1299 load_union_t *load; /* load command */
1300 char *section; /* pointer to section */
1301 } load_all_t;
1302
1303 /* Structure to contain information about a file mapped into memory. */
1304
1305 struct file_info
1306 {
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 */
1314 };
1315
1316 extern int decode_mach_o_hdr ();
1317
1318 extern int encode_mach_o_hdr ();
1319
1320 static void bad_header ();
1321
1322 static void print_header ();
1323
1324 static void print_load_command ();
1325
1326 static void add_func_table ();
1327
1328 static struct file_info *read_file ();
1329
1330 static void end_file ();
1331
1332 \f
1333 /* OSF/rose specific version to scan the name list of the loaded
1334 program for the symbols g++ uses for static constructors and
1335 destructors.
1336
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__. */
1342
1343 static void
1344 scan_prog_file (prog_name, which_pass)
1345 char *prog_name;
1346 enum pass which_pass;
1347 {
1348 char *obj;
1349 mo_header_t hdr;
1350 load_all_t *load_array;
1351 load_all_t *load_end;
1352 load_all_t *load_cmd;
1353 int symbol_load_cmds;
1354 off_t offset;
1355 int i;
1356 int num_syms;
1357 int status;
1358 char *str_sect;
1359 struct file_info *obj_file;
1360 int prog_fd;
1361 mo_lcid_t cmd_strings = -1;
1362 symbol_info_t *main_sym = 0;
1363 int rw = (which_pass != PASS_FIRST);
1364
1365 prog_fd = open (prog_name, (rw) ? O_RDWR : O_RDONLY);
1366 if (prog_fd < 0)
1367 fatal_perror ("can't read %s", prog_name);
1368
1369 obj_file = read_file (prog_name, prog_fd, rw);
1370 obj = obj_file->start;
1371
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);
1375
1376
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
1379 integers. */
1380
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)
1389 {
1390 fatal ("incompatibilities between object file & expected values");
1391 }
1392 #endif
1393
1394 if (debug)
1395 print_header (&hdr);
1396
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);
1400
1401 /* Build array of load commands, calculating the offsets */
1402 for (i = 0; i < hdr.moh_n_load_cmds; i++)
1403 {
1404 load_union_t *load_hdr; /* load command header */
1405
1406 load_cmd = load_end++;
1407 load_hdr = (load_union_t *) (obj + offset);
1408
1409 /* If modifying the program file, copy the header. */
1410 if (rw)
1411 {
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);
1414 load_hdr = ptr;
1415
1416 /* null out old command map, because we will rewrite at the end. */
1417 if (ptr->hdr.ldci_cmd_type == LDC_CMD_MAP)
1418 {
1419 cmd_strings = ptr->map.lcm_ld_cmd_strings;
1420 ptr->hdr.ldci_cmd_type = LDC_UNDEFINED;
1421 }
1422 }
1423
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;
1427
1428 if (debug)
1429 print_load_command (load_hdr, offset, i);
1430
1431 offset += load_hdr->hdr.ldci_cmd_size;
1432 }
1433
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)
1437 {
1438 load_end--;
1439 hdr.moh_n_load_cmds--;
1440 }
1441
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++)
1445 {
1446 load_union_t *load_hdr = load_cmd->load;
1447
1448 if (load_hdr->hdr.ldci_cmd_type == LDC_SYMBOLS)
1449 {
1450 symbol_load_cmds++;
1451
1452 if (debug)
1453 {
1454 char *kind = "unknown";
1455
1456 switch (load_hdr->sym.symc_kind)
1457 {
1458 case SYMC_IMPORTS: kind = "imports"; break;
1459 case SYMC_DEFINED_SYMBOLS: kind = "defined"; break;
1460 case SYMC_STABS: kind = "stabs"; break;
1461 }
1462
1463 fprintf (stderr, "\nProcessing symbol table #%d, offset = 0x%.8lx, kind = %s\n",
1464 symbol_load_cmds, load_hdr->hdr.ldci_section_off, kind);
1465 }
1466
1467 if (load_hdr->sym.symc_kind != SYMC_DEFINED_SYMBOLS)
1468 continue;
1469
1470 str_sect = load_array[load_hdr->sym.symc_strings_section].section;
1471 if (str_sect == (char *)0)
1472 fatal ("string section missing");
1473
1474 if (load_cmd->section == (char *)0)
1475 fatal ("section pointer missing");
1476
1477 num_syms = load_hdr->sym.symc_nentries;
1478 for (i = 0; i < num_syms; i++)
1479 {
1480 symbol_info_t *sym = ((symbol_info_t *) load_cmd->section) + i;
1481 char *name = sym->si_name.symbol_name + str_sect;
1482
1483 if (name[0] != '_')
1484 continue;
1485
1486 if (rw)
1487 {
1488 char *n = name;
1489 while (*n == '_')
1490 ++n;
1491 if (*n != 'm' || (n - name) < 2 || strcmp (n, "main"))
1492 continue;
1493
1494 main_sym = sym;
1495 }
1496 else
1497 {
1498 switch (is_ctor_dtor (name))
1499 {
1500 case 1:
1501 add_to_list (&constructors, name);
1502 break;
1503
1504 case 2:
1505 add_to_list (&destructors, name);
1506 break;
1507
1508 default: /* not a constructor or destructor */
1509 continue;
1510 }
1511 }
1512
1513 if (debug)
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);
1516 }
1517 }
1518 }
1519
1520 if (symbol_load_cmds == 0)
1521 fatal ("no symbol table found");
1522
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. */
1527
1528 if (rw)
1529 {
1530 load_union_t *load_map;
1531 size_t size;
1532
1533 if (cmd_strings == -1)
1534 fatal ("no cmd_strings found");
1535
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. */
1540
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);
1544
1545 if (debug)
1546 fprintf (stderr, "\nUpdating header and load commands.\n\n");
1547
1548 hdr.moh_n_load_cmds++;
1549 size = sizeof (load_cmd_map_command_t) + (sizeof (mo_offset_t) * (hdr.moh_n_load_cmds - 1));
1550
1551 /* Create new load command map. */
1552 if (debug)
1553 fprintf (stderr, "load command map, %d cmds, new size %ld.\n",
1554 (int)hdr.moh_n_load_cmds, (long)size);
1555
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;
1562
1563 offset = hdr.moh_first_cmd_off;
1564 for (i = 0; i < hdr.moh_n_load_cmds; i++)
1565 {
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;
1569
1570 offset += load_array[i].load->hdr.ldci_cmd_size;
1571 }
1572
1573 hdr.moh_sizeofcmds = offset - MO_SIZEOF_RAW_HDR;
1574
1575 if (debug)
1576 print_header (&hdr);
1577
1578 /* Write header */
1579 status = encode_mach_o_hdr (&hdr, obj, MO_SIZEOF_RAW_HDR);
1580 if (status != MO_HDR_CONV_SUCCESS)
1581 bad_header (status);
1582
1583 if (debug)
1584 fprintf (stderr, "writing load commands.\n\n");
1585
1586 /* Write load commands */
1587 offset = hdr.moh_first_cmd_off;
1588 for (i = 0; i < hdr.moh_n_load_cmds; i++)
1589 {
1590 load_union_t *load_hdr = load_array[i].load;
1591 size_t size = load_hdr->hdr.ldci_cmd_size;
1592
1593 if (debug)
1594 print_load_command (load_hdr, offset, i);
1595
1596 bcopy ((generic *)load_hdr, (generic *)(obj + offset), size);
1597 offset += size;
1598 }
1599 }
1600
1601 end_file (obj_file);
1602
1603 if (close (prog_fd))
1604 fatal_perror ("closing %s", prog_name);
1605
1606 if (debug)
1607 fprintf (stderr, "\n");
1608 }
1609
1610 \f
1611 /* Add a function table to the load commands to call a function
1612 on initiation or termination of the process. */
1613
1614 static void
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 */
1620 {
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;
1627 int i;
1628
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;
1632
1633 load_cmd = &load_array[load_index];
1634 load_cmd->load = ptr;
1635 load_cmd->section = (char *)0;
1636
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;
1644
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)
1648 {
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;
1651 }
1652
1653 /* If not, figure out which region it's in. */
1654 else
1655 {
1656 mo_vm_addr_t addr = sym->si_value.abs_val;
1657 int found = 0;
1658
1659 for (i = 0; i < load_index; i++)
1660 {
1661 if (load_array[i].load->hdr.ldci_cmd_type == LDC_REGION)
1662 {
1663 region_command_t *region_ptr = &load_array[i].load->region;
1664
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)
1668 {
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;
1671 found++;
1672 break;
1673 }
1674 }
1675 }
1676
1677 if (!found)
1678 fatal ("could not convert 0x%l.8x into a region", addr);
1679 }
1680
1681 if (debug)
1682 fprintf (stderr,
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);
1688
1689 }
1690
1691 \f
1692 /* Print the global header for an OSF/rose object. */
1693
1694 static void
1695 print_header (hdr_ptr)
1696 mo_header_t *hdr_ptr;
1697 {
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);
1714
1715 if (hdr_ptr->moh_flags & MOH_RELOCATABLE_F)
1716 fprintf (stderr, ", relocatable");
1717
1718 if (hdr_ptr->moh_flags & MOH_LINKABLE_F)
1719 fprintf (stderr, ", linkable");
1720
1721 if (hdr_ptr->moh_flags & MOH_EXECABLE_F)
1722 fprintf (stderr, ", execable");
1723
1724 if (hdr_ptr->moh_flags & MOH_EXECUTABLE_F)
1725 fprintf (stderr, ", executable");
1726
1727 if (hdr_ptr->moh_flags & MOH_UNRESOLVED_F)
1728 fprintf (stderr, ", unresolved");
1729
1730 fprintf (stderr, "\n\n");
1731 return;
1732 }
1733
1734 \f
1735 /* Print a short summary of a load command. */
1736
1737 static void
1738 print_load_command (load_hdr, offset, number)
1739 load_union_t *load_hdr;
1740 size_t offset;
1741 int number;
1742 {
1743 mo_long_t type = load_hdr->hdr.ldci_cmd_type;
1744 char *type_str = (char *)0;
1745
1746 switch (type)
1747 {
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;
1759 }
1760
1761 fprintf (stderr,
1762 "cmd %2d, sz: 0x%.2lx, coff: 0x%.3lx, doff: 0x%.6lx, dlen: 0x%.6lx",
1763 number,
1764 (long) load_hdr->hdr.ldci_cmd_size,
1765 (long) offset,
1766 (long) load_hdr->hdr.ldci_section_off,
1767 (long) load_hdr->hdr.ldci_section_len);
1768
1769 if (type_str == (char *)0)
1770 fprintf (stderr, ", ty: unknown (%ld)\n", (long) type);
1771
1772 else if (type != LDC_REGION)
1773 fprintf (stderr, ", ty: %s\n", type_str);
1774
1775 else
1776 {
1777 char *region = "";
1778 switch (load_hdr->region.regc_usage_type)
1779 {
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;
1788 #endif
1789 }
1790
1791 fprintf (stderr, ", ty: %s, vaddr: 0x%.8lx, vlen: 0x%.6lx%s\n",
1792 type_str,
1793 (long) load_hdr->region.regc_vm_addr,
1794 (long) load_hdr->region.regc_vm_size,
1795 region);
1796 }
1797
1798 return;
1799 }
1800
1801 \f
1802 /* Fatal error when {en,de}code_mach_o_header fails. */
1803
1804 static void
1805 bad_header (status)
1806 int status;
1807 {
1808 char *msg = (char *)0;
1809
1810 switch (status)
1811 {
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;
1818 }
1819
1820 if (msg == (char *)0)
1821 fatal ("unknown {de,en}code_mach_o_hdr return value %d", status);
1822 else
1823 fatal ("%s", msg);
1824 }
1825
1826 \f
1827 /* Read a file into a memory buffer. */
1828
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 */
1834 {
1835 struct stat stat_pkt;
1836 struct file_info *p = (struct file_info *) xcalloc (sizeof (struct file_info), 1);
1837 #ifdef USE_MMAP
1838 static int page_size;
1839 #endif
1840
1841 if (fstat (fd, &stat_pkt) < 0)
1842 fatal_perror ("fstat %s", name);
1843
1844 p->name = name;
1845 p->size = stat_pkt.st_size;
1846 p->rounded_size = stat_pkt.st_size;
1847 p->fd = fd;
1848 p->rw = rw;
1849
1850 #ifdef USE_MMAP
1851 if (debug)
1852 fprintf (stderr, "mmap %s, %s\n", name, (rw) ? "read/write" : "read-only");
1853
1854 if (page_size == 0)
1855 page_size = sysconf (_SC_PAGE_SIZE);
1856
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,
1862 fd,
1863 0L);
1864
1865 if (p->start != (char *)0 && p->start != (char *)-1)
1866 p->use_mmap = 1;
1867
1868 else
1869 #endif /* USE_MMAP */
1870 {
1871 long len;
1872
1873 if (debug)
1874 fprintf (stderr, "read %s\n", name);
1875
1876 p->use_mmap = 0;
1877 p->start = xmalloc (p->size);
1878 if (lseek (fd, 0L, SEEK_SET) < 0)
1879 fatal_perror ("lseek to 0 on %s", name);
1880
1881 len = read (fd, p->start, p->size);
1882 if (len < 0)
1883 fatal_perror ("read %s", name);
1884
1885 if (len != p->size)
1886 fatal ("read %ld bytes, expected %ld, from %s", len, p->size, name);
1887 }
1888
1889 return p;
1890 }
1891
1892 \f
1893 /* Do anything necessary to write a file back from memory. */
1894
1895 static void
1896 end_file (ptr)
1897 struct file_info *ptr; /* file information block */
1898 {
1899 #ifdef USE_MMAP
1900 if (ptr->use_mmap)
1901 {
1902 if (ptr->rw)
1903 {
1904 if (debug)
1905 fprintf (stderr, "msync %s\n", ptr->name);
1906
1907 if (msync (ptr->start, ptr->rounded_size, MS_ASYNC))
1908 fatal_perror ("msync %s", ptr->name);
1909 }
1910
1911 if (debug)
1912 fprintf (stderr, "munmap %s\n", ptr->name);
1913
1914 if (munmap (ptr->start, ptr->size))
1915 fatal_perror ("munmap %s", ptr->name);
1916 }
1917 else
1918 #endif /* USE_MMAP */
1919 {
1920 if (ptr->rw)
1921 {
1922 long len;
1923
1924 if (debug)
1925 fprintf (stderr, "write %s\n", ptr->name);
1926
1927 if (lseek (ptr->fd, 0L, SEEK_SET) < 0)
1928 fatal_perror ("lseek to 0 on %s", ptr->name);
1929
1930 len = write (ptr->fd, ptr->start, ptr->size);
1931 if (len < 0)
1932 fatal_perror ("read %s", ptr->name);
1933
1934 if (len != ptr->size)
1935 fatal ("wrote %ld bytes, expected %ld, to %s", len, ptr->size, ptr->name);
1936 }
1937
1938 free ((generic *)ptr->start);
1939 }
1940
1941 free ((generic *)ptr);
1942 }
1943
1944 #endif /* OBJECT_FORMAT_ROSE */
This page took 0.127831 seconds and 5 git commands to generate.