2011-11-02 Tristan Gingold <gingold@adacore.com>
authorTristan Gingold <gingold@adacore.com>
Wed, 2 Nov 2011 16:28:31 +0000 (16:28 +0000)
committerTristan Gingold <gingold@adacore.com>
Wed, 2 Nov 2011 16:28:31 +0000 (16:28 +0000)
* emultempl/aix.em (read_file_list): New function.
(_handle_option): Handle '-f'.
* NEWS: Mention this feature.

ld/ChangeLog
ld/NEWS
ld/emultempl/aix.em

index 234a136..2042763 100644 (file)
@@ -1,3 +1,9 @@
+2011-11-02  Tristan Gingold  <gingold@adacore.com>
+
+       * emultempl/aix.em (read_file_list): New function.
+       (_handle_option): Handle '-f'.
+       * NEWS: Mention this feature.
+
 2011-11-02  Rainer Orth  <ro@CeBiTec.Uni-Bielefeld.DE>
 
        * configure.tgt (x86_64-*-solaris2*): Use $targ_extra_emuls for
diff --git a/ld/NEWS b/ld/NEWS
index dda27ec..162f598 100644 (file)
--- a/ld/NEWS
+++ b/ld/NEWS
@@ -1,5 +1,7 @@
 -*- text -*-
 
+* Add option -f FILE on AIX (for response file).
+
 * Add support for the Renesas RL78 architecture.
 
 * Add support for the Adapteva EPIPHANY architecture.
@@ -35,7 +37,7 @@ Changes in 2.21:
 * Extend .def file syntax by '== <ID>' for imports and exports. This allows
   to alias the import/export table name written in PE image.
 
-* Add --exlcude-all-symbols option to PE based linkers.  This prevents all
+* Add --exclude-all-symbols option to PE based linkers.  This prevents all
   symbols from automatically being exported.
 
 * Add support for the Renesas RX processor.
index d374c0c..f4660ec 100644 (file)
@@ -259,7 +259,7 @@ gld${EMULATION_NAME}_add_options
     {NULL, no_argument, NULL, 0}
   };
 
-  /* Options supported by the AIX linker which we do not support: -f,
+  /* Options supported by the AIX linker which we do not support:
      -S, -v, -Z, -bbindcmds, -bbinder, -bbindopts, -bcalls, -bcaps,
      -bcror15, -bdebugopt, -bdbg, -bdelcsect, -bex?, -bfilelist, -bfl,
      -bgcbypass, -bglink, -binsert, -bi, -bloadmap, -bl, -bmap, -bnl,
@@ -303,6 +303,76 @@ gld${EMULATION_NAME}_parse_args (int argc, char **argv)
   return FALSE;
 }
 
+/* Helper for option '-f', which specify a list of input files.
+   Contrary to the native linker, we don't support shell patterns
+   (simply because glob isn't always available).  */
+
+static void
+read_file_list (const char *filename)
+{
+  FILE *f;
+  /* An upper bound on the number of characters in the file.  */
+  long pos;
+  /* File in memory.  */
+  char *buffer;
+  size_t len;
+  char *b;
+  char *e;
+
+  f = fopen (filename, FOPEN_RT);
+  if (f == NULL)
+    {
+      einfo ("%F%P: cannot open %s\n", filename);
+      return;
+    }
+  if (fseek (f, 0L, SEEK_END) == -1)
+    goto error;
+  pos = ftell (f);
+  if (pos == -1)
+    goto error;
+  if (fseek (f, 0L, SEEK_SET) == -1)
+    goto error;
+
+  buffer = (char *) xmalloc (pos + 1);
+  len = fread (buffer, sizeof (char), pos, f);
+  if (len != (size_t) pos && ferror (f))
+    goto error;
+  /* Add a NUL terminator.  */
+  buffer[len] = '\0';
+  fclose (f);
+
+  /* Parse files.  */
+  b = buffer;
+  while (1)
+    {
+      /* Skip empty lines.  */
+      while (*b == '\n' || *b == '\r')
+        b++;
+
+      /* Stop if end of buffer.  */
+      if (b == buffer + len)
+        break;
+
+      /* Eat any byte until end of line.  */
+      for (e = b; *e != '\0'; e++)
+        if (*e == '\n' || *e == '\r')
+          break;
+
+      /* Replace end of line by nul.  */
+      if (*e != '\0')
+        *e++ = '\0';
+      
+      if (b != e)
+        lang_add_input_file (b, lang_input_file_is_search_file_enum, NULL);
+      b = e;
+    }
+  return;
+
+ error:
+  einfo ("%F%P: cannot read %s\n", optarg);
+  fclose (f);
+}
+
 static bfd_boolean
 gld${EMULATION_NAME}_handle_option (int optc)
 {
@@ -318,6 +388,12 @@ gld${EMULATION_NAME}_handle_option (int optc)
       /* Long option which just sets a flag.  */
       break;
 
+    case 'f':
+      /* This overrides --auxiliary.  This option specifies a file containing
+         a list of input files.  */
+      read_file_list (optarg);
+      break;
+
     case 'D':
       val = bfd_scan_vma (optarg, &end, 0);
       if (*end != '\0')