/* 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, 2011
+ 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008, 2009, 2010, 2011, 2012
Free Software Foundation, Inc.
Contributed by Chris Smith (csmith@convex.com).
Heavily modified by Michael Meissner (meissner@cygnus.com),
static const char *target_system_root = "";
#endif
+/* Whether we may unlink the output file, which should be set as soon as we
+ know we have successfully produced it. This is typically useful to prevent
+ blindly attempting to unlink a read-only output that the target linker
+ would leave untouched. */
+bool may_unlink_output_file = false;
+
/* Structure to hold all the directories in which to search for files to
execute. */
#ifdef SCAN_LIBRARIES
static void scan_libraries (const char *);
#endif
-#if LINK_ELIMINATE_DUPLICATE_LDIRECTORIES
-static int is_in_args (const char *, const char **, const char **);
-#endif
#ifdef COLLECT_EXPORT_LIST
#if 0
static int is_in_list (const char *, struct id *);
files contain LTO info. The linker command line LTO_LD_ARGV
represents the linker command that would produce a final executable
without the use of LTO. OBJECT_LST is a vector of object file names
- appearing in LTO_LD_ARGV that are to be considerd for link-time
+ appearing in LTO_LD_ARGV that are to be considered for link-time
recompilation, where OBJECT is a pointer to the last valid element.
(This awkward convention avoids an impedance mismatch with the
usage of similarly-named variables in main().) The elements of
main (int argc, char **argv)
{
static const char *const ld_suffix = "ld";
- static const char *const plugin_ld_suffix = PLUGIN_LD;
+ static const char *const plugin_ld_suffix = PLUGIN_LD_SUFFIX;
static const char *const real_ld_suffix = "real-ld";
static const char *const collect_ld_suffix = "collect-ld";
static const char *const nm_suffix = "nm";
const char **ld2;
char **object_lst;
const char **object;
+#ifdef TARGET_AIX_VERSION
+ int object_nbr = argc;
+#endif
int first_file;
int num_c_args;
char **old_argv;
"configuration");
#endif
}
+#ifdef TARGET_AIX_VERSION
+ else
+ {
+ /* File containing a list of input files to process. */
+
+ FILE *stream;
+ char buf[MAXPATHLEN + 2];
+ /* Number of additionnal object files. */
+ int add_nbr = 0;
+ /* Maximum of additionnal object files before vector
+ expansion. */
+ int add_max = 0;
+ const char *list_filename = arg + 2;
+
+ /* Accept -fFILENAME and -f FILENAME. */
+ if (*list_filename == '\0' && argv[1])
+ {
+ ++argv;
+ list_filename = *argv;
+ *ld1++ = *ld2++ = *argv;
+ }
+
+ stream = fopen (list_filename, "r");
+ if (stream == NULL)
+ fatal_error ("can't open %s: %m", list_filename);
+
+ while (fgets (buf, sizeof buf, stream) != NULL)
+ {
+ /* Remove end of line. */
+ int len = strlen (buf);
+ if (len >= 1 && buf[len - 1] =='\n')
+ buf[len - 1] = '\0';
+
+ /* Put on object vector.
+ Note: we only expanse vector here, so we must keep
+ extra space for remaining arguments. */
+ if (add_nbr >= add_max)
+ {
+ int pos =
+ object - CONST_CAST2 (const char **, char **,
+ object_lst);
+ add_max = (add_max == 0) ? 16 : add_max * 2;
+ object_lst = XRESIZEVEC (char *, object_lst,
+ object_nbr + add_max);
+ object = CONST_CAST2 (const char **, char **,
+ object_lst) + pos;
+ object_nbr += add_max;
+ }
+ *object++ = xstrdup (buf);
+ add_nbr++;
+ }
+ fclose (stream);
+ }
+#endif
break;
case 'l':
case 'L':
add_prefix (&cmdline_lib_dirs, arg+2);
break;
-#else
-#if LINK_ELIMINATE_DUPLICATE_LDIRECTORIES
- case 'L':
- if (is_in_args (arg,
- CONST_CAST2 (const char **, char **, ld1_argv),
- ld1 - 1))
- --ld1;
- break;
-#endif /* LINK_ELIMINATE_DUPLICATE_LDIRECTORIES */
#endif
case 'o':
do_wait (prog, pex);
}
\f
-/* Unlink a file unless we are debugging. */
+/* Unlink FILE unless we are debugging or this is the output_file
+ and we may not unlink it. */
static void
maybe_unlink (const char *file)
{
- if (!debug)
- unlink_if_ordinary (file);
- else
- notice ("[Leaving %s]\n", file);
+ if (debug)
+ {
+ notice ("[Leaving %s]\n", file);
+ return;
+ }
+
+ if (file == output_file && !may_unlink_output_file)
+ return;
+
+ unlink_if_ordinary (file);
}
/* Call maybe_unlink on the NULL-terminated list, FILE_LIST. */
}
}
-#if LINK_ELIMINATE_DUPLICATE_LDIRECTORIES
-/* Given a STRING, return nonzero if it occurs in the list in range
- [ARGS_BEGIN,ARGS_END). */
-
-static int
-is_in_args (const char *string, const char **args_begin,
- const char **args_end)
-{
- const char **args_pointer;
- for (args_pointer = args_begin; args_pointer != args_end; ++args_pointer)
- if (strcmp (string, *args_pointer) == 0)
- return 1;
- return 0;
-}
-#endif /* LINK_ELIMINATE_DUPLICATE_LDIRECTORIES */
-
#ifdef COLLECT_EXPORT_LIST
/* This function is really used only on AIX, but may be useful. */
#if 0
/* LTO objects must be in a known format. This check prevents
us from accepting an archive containing LTO objects, which
- gcc cannnot currently handle. */
+ gcc cannot currently handle. */
if (which_pass == PASS_LTOINFO && !maybe_lto_object_file (prog_name))
return;