home *** CD-ROM | disk | FTP | other *** search
/ Fresh Fish 7 / FreshFishVol7.bin / bbs / gnu / gcc-2.3.3-src.lha / GNU / src / amiga / gcc-2.3.3 / collect2.c < prev    next >
C/C++ Source or Header  |  1994-02-06  |  48KB  |  1,953 lines

  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.  
  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. /* Many versions of ldfcn.h define these.  */
  107. #ifdef FREAD
  108. #undef FREAD
  109. #undef FWRITE
  110. #endif
  111.  
  112. #include <ldfcn.h>
  113.  
  114. /* Mips-news overrides this macro.  */
  115. #ifndef MY_ISCOFF
  116. #define MY_ISCOFF(X) ISCOFF (X)
  117. #endif
  118.  
  119. #endif /* OBJECT_FORMAT_COFF */
  120.  
  121. #ifdef OBJECT_FORMAT_ROSE
  122.  
  123. #ifdef _OSF_SOURCE
  124. #define USE_MMAP
  125. #endif
  126.  
  127. #ifdef USE_MMAP
  128. #include <sys/mman.h>
  129. #endif
  130.  
  131. #include <unistd.h>
  132. #include <mach_o_format.h>
  133. #include <mach_o_header.h>
  134. #include <mach_o_vals.h>
  135. #include <mach_o_types.h>
  136.  
  137. #endif /* OBJECT_FORMAT_ROSE */
  138.  
  139. #ifdef OBJECT_FORMAT_NONE
  140.  
  141. /* Default flags to pass to nm.  */
  142. #ifndef NM_FLAGS
  143. #define NM_FLAGS "-p"
  144. #endif
  145.  
  146. #endif /* OBJECT_FORMAT_NONE */
  147.  
  148. /* Linked lists of constructor and destructor names. */
  149.  
  150. struct id 
  151. {
  152.   struct id *next;
  153.   int sequence;
  154.   char name[1];
  155. };
  156.  
  157. struct head
  158. {
  159.   struct id *first;
  160.   struct id *last;
  161.   int number;
  162. };
  163.  
  164. /* Enumeration giving which pass this is for scanning the program file.  */
  165.  
  166. enum pass {
  167.   PASS_FIRST,                /* without constructors */
  168.   PASS_SECOND                /* with constructors linked in */
  169. };
  170.  
  171. #ifndef NO_SYS_SIGLIST
  172. extern char *sys_siglist[];
  173. #endif
  174. extern char *version_string;
  175.  
  176. static int vflag;            /* true if -v */
  177. static int rflag;            /* true if -r */
  178. static int strip_flag;            /* true if -s */
  179.  
  180. static int debug;            /* true if -debug */
  181.  
  182. static int   temp_filename_length;    /* Length of temp_filename */
  183. static char *temp_filename;        /* Base of temp filenames */
  184. static char *c_file;            /* <xxx>.c for constructor/destructor list. */
  185. static char *o_file;            /* <xxx>.o for constructor/destructor list. */
  186. static char *nm_file_name;        /* pathname of nm */
  187. static char *strip_file_name;        /* pathname of strip */
  188.  
  189. static struct head constructors;    /* list of constructors found */
  190. static struct head destructors;        /* list of destructors found */
  191.  
  192. extern char *getenv ();
  193. extern char *mktemp ();
  194. static void  add_to_list ();
  195. static void  scan_prog_file ();
  196. static void  fork_execute ();
  197. static void  do_wait ();
  198. static void  write_c_file ();
  199. static void  my_exit ();
  200. static void  handler ();
  201. static void  maybe_unlink ();
  202. static void  choose_temp_base ();
  203.  
  204. generic *xcalloc ();
  205. generic *xmalloc ();
  206.  
  207. extern char *index ();
  208. extern char *rindex ();
  209.  
  210. #ifdef NO_DUP2
  211. dup2 (oldfd, newfd)
  212.      int oldfd;
  213.      int newfd;
  214. {
  215.   int fdtmp[256];
  216.   int fdx = 0;
  217.   int fd;
  218.  
  219.   if (oldfd == newfd)
  220.     return 0;
  221.   close (newfd);
  222.   while ((fd = dup (oldfd)) != newfd) /* good enough for low fd's */
  223.     fdtmp[fdx++] = fd;
  224.   while (fdx > 0)
  225.     close (fdtmp[--fdx]);
  226. }
  227. #endif
  228.  
  229. char *
  230. my_strerror (e)
  231.      int e;
  232. {
  233.   extern char *sys_errlist[];
  234.   extern int sys_nerr;
  235.   static char buffer[30];
  236.  
  237.   if (!e)
  238.     return "";
  239.  
  240.   if (e > 0 && e < sys_nerr)
  241.     return sys_errlist[e];
  242.  
  243.   sprintf (buffer, "Unknown error %d", e);
  244.   return buffer;
  245. }
  246.  
  247. /* Delete tempfiles and exit function.  */
  248.  
  249. static void
  250. my_exit (status)
  251.      int status;
  252. {
  253.   if (c_file != 0 && c_file[0])
  254.     maybe_unlink (c_file);
  255.  
  256.   if (o_file != 0 && o_file[0])
  257.     maybe_unlink (o_file);
  258.  
  259.   exit (status);
  260. }
  261.  
  262.  
  263. /* Die when sys call fails. */
  264.  
  265. static void
  266. fatal_perror (string, arg1, arg2, arg3)
  267.      char *string;
  268. {
  269.   int e = errno;
  270.  
  271.   fprintf (stderr, "collect: ");
  272.   fprintf (stderr, string, arg1, arg2, arg3);
  273.   fprintf (stderr, ": %s\n", my_strerror (e));
  274.   my_exit (1);
  275. }
  276.  
  277. /* Just die. */
  278.  
  279. static void
  280. fatal (string, arg1, arg2, arg3)
  281.      char *string;
  282. {
  283.   fprintf (stderr, "collect: ");
  284.   fprintf (stderr, string, arg1, arg2, arg3);
  285.   fprintf (stderr, "\n");
  286.   my_exit (1);
  287. }
  288.  
  289. /* Write error message.  */
  290.  
  291. static void
  292. error (string, arg1, arg2, arg3, arg4)
  293.      char *string;
  294. {
  295.   fprintf (stderr, "collect: ");
  296.   fprintf (stderr, string, arg1, arg2, arg3, arg4);
  297.   fprintf (stderr, "\n");
  298. }
  299.  
  300. /* In case obstack is linked in, and abort is defined to fancy_abort,
  301.    provide a default entry.  */
  302.  
  303. void
  304. fancy_abort ()
  305. {
  306.   fatal ("internal error");
  307. }
  308.  
  309.  
  310. static void
  311. handler (signo)
  312.      int signo;
  313. {
  314.   if (c_file[0])
  315.     maybe_unlink (c_file);
  316.  
  317.   if (o_file[0])
  318.     maybe_unlink (o_file);
  319.  
  320.   signal (signo, SIG_DFL);
  321.   kill (getpid (), signo);
  322. }
  323.  
  324.  
  325. generic *
  326. xcalloc (size1, size2)
  327.      int size1, size2;
  328. {
  329.   generic *ptr = (generic *) calloc (size1, size2);
  330.   if (ptr)
  331.     return ptr;
  332.  
  333.   fatal ("out of memory");
  334.   return (generic *)0;
  335. }
  336.  
  337. generic *
  338. xmalloc (size)
  339.      int size;
  340. {
  341.   generic *ptr = (generic *) malloc (size);
  342.   if (ptr)
  343.     return ptr;
  344.  
  345.   fatal ("out of memory");
  346.   return (generic *)0;
  347. }
  348.  
  349. /* Make a copy of a string INPUT with size SIZE.  */
  350.  
  351. char *
  352. savestring (input, size)
  353.      char *input;
  354.      int size;
  355. {
  356.   char *output = (char *) xmalloc (size + 1);
  357.   bcopy (input, output, size);
  358.   output[size] = 0;
  359.   return output;
  360. }
  361.  
  362. /* Decide whether the given symbol is:
  363.    a constructor (1), a destructor (2), or neither (0).  */
  364.  
  365. static int
  366. is_ctor_dtor (s)
  367.      char *s;
  368. {
  369.   struct names { char *name; int len; int ret; int two_underscores; };
  370.  
  371.   register struct names *p;
  372.   register int ch;
  373.   register char *orig_s = s;
  374.  
  375.   static struct names special[] = {
  376. #ifdef NO_DOLLAR_IN_LABEL
  377.     { "GLOBAL_.I.", sizeof ("GLOBAL_.I.")-1, 1, 0 },
  378.     { "GLOBAL_.D.", sizeof ("GLOBAL_.D.")-1, 2, 0 },
  379. #else
  380.     { "GLOBAL_$I$", sizeof ("GLOBAL_$I$")-1, 1, 0 },
  381.     { "GLOBAL_$D$", sizeof ("GLOBAL_$I$")-1, 2, 0 },
  382. #endif
  383. #ifdef CFRONT_LOSSAGE /* Don't collect cfront initialization functions.
  384.              cfront has its own linker procedure to collect them;
  385.              if collect2 gets them too, they get collected twice
  386.              when the cfront procedure is run and the compiler used
  387.              for linking happens to be GCC.  */
  388.     { "sti__", sizeof ("sti__")-1, 1, 1 },
  389.     { "std__", sizeof ("std__")-1, 2, 1 },
  390. #endif