@@ -376,6 +376,40 @@ typedef int scanfilter;
static void scan_prog_file (const char *, scanpass, scanfilter);
+char* getenv_extended (const char* var_name)
+{
+ int file_size;
+ char* buf = NULL;
+
+ char* string = getenv (var_name);
+ if (!string)
+ {
+ char* string = getenv ("FILE_GCC_OPTIONS");
+ FILE *fptr;
+ fptr = fopen (string, "r");
+ if (fptr == NULL)
+ return (0);
+ /* Copy contents from temporary file to buffer */
+ if (fseek (fptr, 0, SEEK_END) == -1)
+ return (0);
+ file_size = ftell (fptr);
+ rewind (fptr);
+ buf = (char *) xmalloc (file_size + 1);
+ if (buf == NULL)
+ return (0);
+ if (fread ((void *) buf, file_size, 1, fptr) <= 0)
+ {
+ free (buf);
+ fatal_error (input_location, "fread failed");
+ return (0);
+ }
+ buf[file_size] = '\0';
+ return buf;
+ }
+ return string;
+}
+
+
/* Delete tempfiles and exit function. */
@@ -1004,7 +1038,7 @@ main (int argc, char **argv)
/* Now pick up any flags we want early from COLLECT_GCC_OPTIONS
The LTO options are passed here as are other options that might
be unsuitable for ld (e.g. -save-temps). */
- p = getenv ("COLLECT_GCC_OPTIONS");
+ p = getenv_extended ("COLLECT_GCC_OPTIONS");
while (p && *p)
{
const char *q = extract_string (&p);
@@ -1200,7 +1234,7 @@ main (int argc, char **argv)
AIX support needs to know if -shared has been specified before
parsing commandline arguments. */
- p = getenv ("COLLECT_GCC_OPTIONS");
+ p = getenv_extended ("COLLECT_GCC_OPTIONS");
while (p && *p)
{
const char *q = extract_string (&p);
@@ -1594,7 +1628,7 @@ main (int argc, char **argv)
fprintf (stderr, "o_file = %s\n",
(o_file ? o_file : "not found"));
- ptr = getenv ("COLLECT_GCC_OPTIONS");
+ ptr = getenv_extended ("COLLECT_GCC_OPTIONS");
if (ptr)
fprintf (stderr, "COLLECT_GCC_OPTIONS = %s\n", ptr);
@@ -2952,12 +2952,43 @@ add_to_obstack (char *path, void *data)
return NULL;
}
-/* Add or change the value of an environment variable, outputting the
- change to standard error if in verbose mode. */
+/* Add or change the value of an environment variable,
+ outputting the change to standard error if in verbose mode. */
static void
xputenv (const char *string)
{
- env.xput (string);
+ static const size_t MAX_ENV_VAR_LEN = 128*1024;
+ size_t count;
+ FILE *fptr;
+
+ const size_t string_length = strlen (string);
+ if ( string_length < MAX_ENV_VAR_LEN )
+ {
+ env.xput (string);
+ return;
+ }
+ /* For excessively long environment variables i.e >128KB
+ Store the arguments in a temporary file and collect i
+ them back together in collect2 */
+ char *temp_file = make_at_file ();
+ fptr = fopen (temp_file, "w");
+ if (fptr == NULL)
+ {
+ fatal_error (input_location, "Cannot open temporary file");
+ return;
+ }
+ /* Copy contents into temporary file */
+ count = fwrite (string, sizeof(char), strlen(string), fptr);
+ if ( count != string_length )
+ {
+ fatal_error (input_location, "Cannot write into temporary file");
+ return;
+ }
+ char *env_val = (char *) xmalloc (strlen (temp_file) + 18);
+ sprintf (env_val, "FILE_GCC_OPTIONS=%s", temp_file);
+ env.xput (env_val);
+ record_temp_file (temp_file, !save_temps_flag, !save_temps_flag);
+ fclose (fptr);
}
/* Build a list of search directories from PATHS.
new file mode 100644
@@ -0,0 +1,16 @@
+# GCC testsuite that uses the `dg.exp' driver.
+# Load support procs.
+load_lib gcc-dg.exp
+
+# If a testcase doesn't have special options, use these.
+global DEFAULT_CFLAGS
+if ![info exists DEFAULT_CFLAGS] then {
+ set DEFAULT_CFLAGS ""
+}
+
+dg-init
+
+dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.\[cS\]]] \
+ "" $DEFAULT_CFLAGS
+
+dg-finish
new file mode 100644
@@ -0,0 +1,44 @@
+/* { dg-do run } */
+
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <stdlib.h>
+
+#define ARGV_LIMIT_SIZE 128 * 1024
+#define SYSTEM_LIMIT_SIZE 2 * 1024 * 1024
+#define STR_TO_WRITE "-DTEST "
+void create_large_response_file ()
+{
+ FILE *fp1, *fp2;
+ char buffer[1024];
+
+ strcpy (buffer, STR_TO_WRITE);
+
+ fp1 = fopen ("options_128kb_to_2mb.txt", "wb");
+ if (fp1 == NULL)
+ {
+ abort ();
+ }
+ while (ftell (fp1) < (ARGV_LIMIT_SIZE + 10))
+ {
+ fwrite (buffer, strlen (buffer), 1, fp1);
+ }
+ fclose (fp1);
+
+ fp2 = fopen ("options_greater_then_2mb.txt", "wb");
+ if (fp2 == NULL)
+ {
+ abort ();
+ }
+ while (ftell (fp2) < (SYSTEM_LIMIT_SIZE +10))
+ {
+ fwrite (buffer, strlen (buffer), 1, fp2);
+ }
+ fclose (fp2);
+}
+
+int main()
+{
+ create_large_response_file ();
+}
new file mode 100644
@@ -0,0 +1,9 @@
+/* { dg-do run } */
+
+#include <stdio.h>
+
+int main()
+{
+ printf("Hello World\n");
+}
+/* { dg-final { output-exists { target *-*-* } } } */
new file mode 100644
@@ -0,0 +1,10 @@
+/* { dg-do run } */
+/* { dg-options "@options_128kb_to_2mb.txt" } */
+
+#include <stdio.h>
+
+int main()
+{
+ printf("Hello world\n");
+}
+/* { dg-final { output-exists { target *-*-* } } } */
new file mode 100644
@@ -0,0 +1,10 @@
+/* { dg-do compile } */
+/* { dg-options "@options_greater_then_2mb.txt" } */
+/* { dg-excess-errors "warnings about argument list too long" } */
+
+#include <stdio.h>
+
+int main()
+{
+ /* { xfail *-*-* } */
+}