/* Collect static initialization info into data structures that can be
traversed by C++ initialization and finalization routines.
Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998,
- 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008, 2009, 2010
+ 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008, 2009, 2010, 2011
Free Software Foundation, Inc.
Contributed by Chris Smith (csmith@convex.com).
Heavily modified by Michael Meissner (meissner@cygnus.com),
#include "system.h"
#include "coretypes.h"
#include "tm.h"
-#include <signal.h>
-#if ! defined( SIGCHLD ) && defined( SIGCLD )
-# define SIGCHLD SIGCLD
-#endif
+#include "filenames.h"
/* TARGET_64BIT may be defined to use driver specific functionality. */
#undef TARGET_64BIT
static char *resolve_lib_name (const char *);
#endif
static char *extract_string (const char **);
+static void post_ld_pass (bool);
+static void process_args (int *argcp, char **argv);
/* Enumerations describing which pass this is for scanning the
program file ... */
prefix_from_env (const char *env, struct path_prefix *pprefix)
{
const char *p;
- GET_ENVIRONMENT (p, env);
+ p = getenv (env);
if (p)
prefix_from_string (p, pprefix);
size_t num_files;
if (!lto_wrapper)
- fatal ("COLLECT_LTO_WRAPPER must be set.");
+ fatal ("COLLECT_LTO_WRAPPER must be set");
num_lto_c_args++;
/* Run the linker again, this time replacing the object files
optimized by the LTO with the temporary file generated by the LTO. */
fork_execute ("ld", out_lto_ld_argv);
+ post_ld_pass (true);
free (lto_ld_argv);
maybe_unlink_list (lto_o_files);
{
/* Our caller is relying on us to do the link
even though there is no LTO back end work to be done. */
- fork_execute ("ld", lto_ld_argv);
+ fork_execute ("ld", lto_ld_argv);
+ post_ld_pass (false);
}
}
\f
int num_c_args;
char **old_argv;
- bool use_verbose = false;
-
old_argv = argv;
expandargv (&argc, &argv);
if (argv != old_argv)
at_file_supplied = 1;
+ process_args (&argc, argv);
+
num_c_args = argc + 9;
no_demangle = !! getenv ("COLLECT_NO_DEMANGLE");
/* Parse command line early for instances of -debug. This allows
the debug flag to be set before functions like find_a_file()
- are called. We also look for the -flto or -fwhopr flag to know
+ are called. We also look for the -flto or -flto-partition=none flag to know
what LTO mode we are in. */
{
int i;
+ bool no_partition = false;
for (i = 1; argv[i] != NULL; i ++)
{
if (! strcmp (argv[i], "-debug"))
debug = true;
- else if (! strcmp (argv[i], "-flto") && ! use_plugin)
- {
- use_verbose = true;
- lto_mode = LTO_MODE_LTO;
- }
- else if (! strncmp (argv[i], "-fwhopr", 7) && ! use_plugin)
- {
- use_verbose = true;
- lto_mode = LTO_MODE_WHOPR;
- }
+ else if (! strcmp (argv[i], "-flto-partition=none"))
+ no_partition = true;
+ else if ((! strncmp (argv[i], "-flto=", 6)
+ || ! strcmp (argv[i], "-flto")) && ! use_plugin)
+ lto_mode = LTO_MODE_WHOPR;
+ else if (!strncmp (argv[i], "-fno-lto", 8))
+ lto_mode = LTO_MODE_NONE;
else if (! strcmp (argv[i], "-plugin"))
{
use_plugin = true;
- use_verbose = true;
lto_mode = LTO_MODE_NONE;
}
#ifdef COLLECT_EXPORT_LIST
#endif
}
vflag = debug;
+ if (no_partition && lto_mode == LTO_MODE_WHOPR)
+ lto_mode = LTO_MODE_LTO;
}
#ifndef DEFAULT_A_OUT_NAME
*c_ptr++ = xstrdup (q);
}
}
- if (use_verbose && *q == '-' && q[1] == 'v' && q[2] == 0)
- {
- /* Turn on trace in collect2 if needed. */
- vflag = true;
- }
}
obstack_free (&temporary_obstack, temporary_firstobj);
*c_ptr++ = "-fno-profile-arcs";
break;
case 'f':
- if (strcmp (arg, "-flto") == 0
- || strncmp (arg, "-fwhopr", 7) == 0)
+ if (strncmp (arg, "-flto", 5) == 0)
{
#ifdef ENABLE_LTO
/* Do not pass LTO flag to the linker. */
*c_ptr = *ld1 = *object = (char *) 0;
if (vflag)
- {
- notice ("collect2 version %s", version_string);
-#ifdef TARGET_VERSION
- TARGET_VERSION;
-#endif
- fprintf (stderr, "\n");
- }
+ notice ("collect2 version %s\n", version_string);
if (helpflag)
{
#endif
if (lto_mode != LTO_MODE_NONE)
maybe_run_lto_and_relink (ld1_argv, object_lst, object, false);
+ else
+ post_ld_pass (false);
maybe_unlink (c_file);
maybe_unlink (o_file);
#ifdef COLLECT_EXPORT_LIST
maybe_unlink (export_file);
#endif
+ post_ld_pass (false);
+
maybe_unlink (c_file);
maybe_unlink (o_file);
return 0;
if (lto_mode)
maybe_run_lto_and_relink (ld2_argv, object_lst, object, true);
else
- fork_execute ("ld", ld2_argv);
+ {
+ fork_execute ("ld", ld2_argv);
+ post_ld_pass (false);
+ }
/* Let scan_prog_file do any final mods (OSF/rose needs this for
constructors/destructors in shared libraries. */
int frames = (frame_tables.number > 0);
/* Figure out name of output_file, stripping off .so version. */
- p = strrchr (output_file, '/');
- if (p == 0)
- p = output_file;
- else
- p++;
- q = p;
+ q = p = lbasename (output_file);
+
while (q)
{
q = strchr (q,'.');
}
else
{
- if (strncmp (q, SHLIB_SUFFIX, strlen (SHLIB_SUFFIX)) == 0)
+ if (filename_ncmp (q, SHLIB_SUFFIX, strlen (SHLIB_SUFFIX)) == 0)
{
q += strlen (SHLIB_SUFFIX);
break;
for (; list; list = list->next)
{
/* The following lines are needed because path_prefix list
- may contain directories both with trailing '/' and
+ may contain directories both with trailing DIR_SEPARATOR and
without it. */
const char *p = "";
- if (list->prefix[strlen(list->prefix)-1] != '/')
+ if (!IS_DIR_SEPARATOR (list->prefix[strlen(list->prefix)-1]))
p = "/";
for (j = 0; j < 2; j++)
{
return (NULL);
}
#endif /* COLLECT_EXPORT_LIST */
+
+#ifdef COLLECT_RUN_DSYMUTIL
+static int flag_dsym = false;
+static int flag_idsym = false;
+
+static void
+process_args (int *argcp, char **argv) {
+ int i, j;
+ int argc = *argcp;
+ for (i=0; i<argc; ++i)
+ {
+ if (strcmp (argv[i], "-dsym") == 0)
+ {
+ flag_dsym = true;
+ /* Remove the flag, as we handle all processing for it. */
+ j = i;
+ do
+ argv[j] = argv[j+1];
+ while (++j < argc);
+ --i;
+ argc = --(*argcp);
+ }
+ else if (strcmp (argv[i], "-idsym") == 0)
+ {
+ flag_idsym = true;
+ /* Remove the flag, as we handle all processing for it. */
+ j = i;
+ do
+ argv[j] = argv[j+1];
+ while (++j < argc);
+ --i;
+ argc = --(*argcp);
+ }
+ }
+}
+
+static void
+do_dsymutil (const char *output_file) {
+ const char *dsymutil = DSYMUTIL + 1;
+ struct pex_obj *pex;
+ char **real_argv = XCNEWVEC (char *, 3);
+ const char ** argv = CONST_CAST2 (const char **, char **,
+ real_argv);
+
+ argv[0] = dsymutil;
+ argv[1] = output_file;
+ argv[2] = (char *) 0;
+
+ pex = collect_execute (dsymutil, real_argv, NULL, NULL, PEX_LAST | PEX_SEARCH);
+ do_wait (dsymutil, pex);
+}
+
+static void
+post_ld_pass (bool temp_file) {
+ if (!(temp_file && flag_idsym) && !flag_dsym)
+ return;
+
+ do_dsymutil (output_file);
+}
+#else
+static void
+process_args (int *argcp ATTRIBUTE_UNUSED, char **argv ATTRIBUTE_UNUSED) { }
+static void post_ld_pass (bool temp_file ATTRIBUTE_UNUSED) { }
+#endif