include/
authorAlan Modra <amodra@gmail.com>
Fri, 6 Jun 2008 06:02:00 +0000 (06:02 +0000)
committerAlan Modra <amodra@gmail.com>
Fri, 6 Jun 2008 06:02:00 +0000 (06:02 +0000)
* bfdlink.h (struct bfd_link_info): Add "path_separator".
bfd/
* elf32-spu.c (spu_elf_auto_overlay): Relax requirement that
file names be unique.  Specify archive:path in overlay script.
ld/
* ldlang.c (name_match): New function.
(unique_section_p, walk_wild_consider_section): Use it here.
(walk_wild_section_general): And here.
(archive_path): New function.
(walk_wild): Match archive:path filespecs.
(open_input_bfds): Don't load archive:path files.
* emultempl/spuelf.em (choose_target): Set path_separator.
* emulparams/elf32_spu.sh: Add ._ea.* sections to ._ea output.

bfd/ChangeLog
bfd/elf32-spu.c
include/ChangeLog
include/bfdlink.h
ld/ChangeLog
ld/emulparams/elf32_spu.sh
ld/emultempl/spuelf.em
ld/ldlang.c

index 470e3a2..b725c3c 100644 (file)
@@ -1,3 +1,8 @@
+2008-06-06  Alan Modra  <amodra@bigpond.net.au>
+
+       * elf32-spu.c (spu_elf_auto_overlay): Relax requirement that
+       file names be unique.  Specify archive:path in overlay script.
+
 2008-06-05  Alan Modra  <amodra@bigpond.net.au>
 
        PR ld/6590
index e6e0093..e11e1d7 100644 (file)
@@ -3544,37 +3544,20 @@ spu_elf_auto_overlay (struct bfd_link_info *info,
       for (i = 1; i < bfd_count; ++i)
        if (strcmp (bfd_arr[i - 1]->filename, bfd_arr[i]->filename) == 0)
          {
-           if (bfd_arr[i - 1]->my_archive && bfd_arr[i]->my_archive)
+           if (bfd_arr[i - 1]->my_archive == bfd_arr[i]->my_archive)
              {
-               if (bfd_arr[i - 1]->my_archive == bfd_arr[i]->my_archive)
+               if (bfd_arr[i - 1]->my_archive && bfd_arr[i]->my_archive)
                  info->callbacks->einfo (_("%s duplicated in %s\n"),
-                                         bfd_arr[i - 1]->filename,
-                                         bfd_arr[i - 1]->my_archive->filename);
-               else
-                 info->callbacks->einfo (_("%s in both %s and %s\n"),
-                                         bfd_arr[i - 1]->filename,
-                                         bfd_arr[i - 1]->my_archive->filename,
+                                         bfd_arr[i]->filename,
                                          bfd_arr[i]->my_archive->filename);
+               else
+                 info->callbacks->einfo (_("%s duplicated\n"),
+                                         bfd_arr[i]->filename);
+               ok = FALSE;
              }
-           else if (bfd_arr[i - 1]->my_archive)
-             info->callbacks->einfo (_("%s in %s and as an object\n"),
-                                     bfd_arr[i - 1]->filename,
-                                     bfd_arr[i - 1]->my_archive->filename);
-           else if (bfd_arr[i]->my_archive)
-             info->callbacks->einfo (_("%s in %s and as an object\n"),
-                                     bfd_arr[i]->filename,
-                                     bfd_arr[i]->my_archive->filename);
-           else
-             info->callbacks->einfo (_("%s duplicated\n"),
-                                     bfd_arr[i]->filename);
-           ok = FALSE;
          }
       if (!ok)
        {
-         /* FIXME: modify plain object files from foo.o to ./foo.o
-            and emit EXCLUDE_FILE to handle the duplicates in
-            archives.  There is a pathological case we can't handle:
-            We may have duplicate file names within a single archive.  */
          info->callbacks->einfo (_("sorry, no support for duplicate "
                                    "object files in auto-overlay script\n"));
          bfd_set_error (bfd_error_bad_value);
@@ -3750,9 +3733,11 @@ spu_elf_auto_overlay (struct bfd_link_info *info,
        {
          asection *sec = ovly_sections[2 * j];
 
-         if (fprintf (script, "   [%c]%s (%s)\n",
-                      sec->owner->filename[0],
-                      sec->owner->filename + 1,
+         if (fprintf (script, "   %s%c%s (%s)\n",
+                      (sec->owner->my_archive != NULL
+                       ? sec->owner->my_archive->filename : ""),
+                      info->path_separator,
+                      sec->owner->filename,
                       sec->name) <= 0)
            goto file_err;
          if (sec->segment_mark)
@@ -3762,9 +3747,11 @@ spu_elf_auto_overlay (struct bfd_link_info *info,
                {
                  struct function_info *call_fun = call->fun;
                  sec = call_fun->sec;
-                 if (fprintf (script, "   [%c]%s (%s)\n",
-                              sec->owner->filename[0],
-                              sec->owner->filename + 1,
+                 if (fprintf (script, "   %s%c%s (%s)\n",
+                              (sec->owner->my_archive != NULL
+                               ? sec->owner->my_archive->filename : ""),
+                              info->path_separator,
+                              sec->owner->filename,
                               sec->name) <= 0)
                    goto file_err;
                  for (call = call_fun->call_list; call; call = call->next)
@@ -3777,10 +3764,13 @@ spu_elf_auto_overlay (struct bfd_link_info *info,
       for (j = base; j < i; j++)
        {
          asection *sec = ovly_sections[2 * j + 1];
-         if (sec != NULL && fprintf (script, "   [%c]%s (%s)\n",
-                                     sec->owner->filename[0],
-                                     sec->owner->filename + 1,
-                                     sec->name) <= 0)
+         if (sec != NULL
+             && fprintf (script, "   %s%c%s (%s)\n",
+                         (sec->owner->my_archive != NULL
+                          ? sec->owner->my_archive->filename : ""),
+                         info->path_separator,
+                         sec->owner->filename,
+                         sec->name) <= 0)
            goto file_err;
 
          sec = ovly_sections[2 * j];
@@ -3791,10 +3781,13 @@ spu_elf_auto_overlay (struct bfd_link_info *info,
                {
                  struct function_info *call_fun = call->fun;
                  sec = call_fun->rodata;
-                 if (sec != NULL && fprintf (script, "   [%c]%s (%s)\n",
-                                             sec->owner->filename[0],
-                                             sec->owner->filename + 1,
-                                             sec->name) <= 0)
+                 if (sec != NULL
+                     && fprintf (script, "   %s%c%s (%s)\n",
+                                 (sec->owner->my_archive != NULL
+                                  ? sec->owner->my_archive->filename : ""),
+                                 info->path_separator,
+                                 sec->owner->filename,
+                                 sec->name) <= 0)
                    goto file_err;
                  for (call = call_fun->call_list; call; call = call->next)
                    if (call->is_pasted)
index 9b0140c..4e399f3 100644 (file)
@@ -1,3 +1,7 @@
+2008-06-06  Alan Modra  <amodra@bigpond.net.au>
+
+       * bfdlink.h (struct bfd_link_info): Add "path_separator".
+
 2008-04-10  Andreas Krebbel  <krebbel1@de.ibm.com>
 
        * dis-asm.h (print_s390_disassembler_options):
index bcd4b4f..e683310 100644 (file)
@@ -372,6 +372,9 @@ struct bfd_link_info
      wrap_hash.  Used by PowerPC Linux for 'dot' symbols.  */
   char wrap_char;
 
+  /* Separator between archive and filename in linker script filespecs.  */
+  char path_separator;
+
   /* Function callbacks.  */
   const struct bfd_link_callbacks *callbacks;
 
index e724aa9..228d15f 100644 (file)
@@ -1,3 +1,14 @@
+2008-06-06  Alan Modra  <amodra@bigpond.net.au>
+
+       * ldlang.c (name_match): New function.
+       (unique_section_p, walk_wild_consider_section): Use it here.
+       (walk_wild_section_general): And here.
+       (archive_path): New function.
+       (walk_wild): Match archive:path filespecs.
+       (open_input_bfds): Don't load archive:path files.
+       * emultempl/spuelf.em (choose_target): Set path_separator.
+       * emulparams/elf32_spu.sh: Add ._ea.* sections to ._ea output.
+
 2008-06-04  Nick Clifton  <nickc@redhat.com>
 
        * ld.texinfo (Orphan Sections): Fix texi typo.
index 52a3e7b..8248d5d 100644 (file)
@@ -18,4 +18,4 @@ MAXPAGESIZE=0x80
 DATA_ADDR="ALIGN(${MAXPAGESIZE})"
 OTHER_BSS_SECTIONS=".toe ALIGN(128) : { *(.toe) } = 0"
 OTHER_SECTIONS=".note.spu_name 0 : { KEEP(*(.note.spu_name)) }
-  ._ea 0 : { KEEP(*(._ea)) }"
+  ._ea 0 : { KEEP(*(._ea)) KEEP(*(._ea.*)) }"
index a56d78f..3c8b7d3 100644 (file)
@@ -350,6 +350,7 @@ gld${EMULATION_NAME}_finish (void)
 static char *
 gld${EMULATION_NAME}_choose_target (int argc, char *argv[])
 {
+  link_info.path_separator = ':';
   my_argc = argc;
   my_argv = argv;
   return ldemul_default_target (argc, argv);
index c8aac29..8cf486e 100644 (file)
@@ -134,6 +134,38 @@ stat_alloc (size_t size)
   return obstack_alloc (&stat_obstack, size);
 }
 
+static int
+name_match (const char *pattern, const char *name)
+{
+  if (wildcardp (pattern))
+    return fnmatch (pattern, name, 0);
+  return strcmp (pattern, name);
+}
+
+/* If PATTERN is of the form archive:file, return a pointer to the
+   separator.  If not, return NULL.  */
+
+static char *
+archive_path (const char *pattern)
+{
+  char *p = NULL;
+
+  if (link_info.path_separator == 0)
+    return p;
+
+  p = strchr (pattern, link_info.path_separator);
+#ifdef HAVE_DOS_BASED_FILE_SYSTEM
+  if (p == NULL || link_info.path_separator != ':')
+    return p;
+
+  /* Assume a match on the second char is part of drive specifier,
+     as in "c:\silly.dos".  */
+  if (p == pattern + 1)
+    p = strchr (p + 1, link_info.path_separator);
+#endif
+  return p;
+}
+
 bfd_boolean
 unique_section_p (const asection *sec)
 {
@@ -147,12 +179,8 @@ unique_section_p (const asection *sec)
 
   secnam = sec->name;
   for (unam = unique_section_list; unam; unam = unam->next)
-    if (wildcardp (unam->name)
-       ? fnmatch (unam->name, secnam, 0) == 0
-       : strcmp (unam->name, secnam) == 0)
-      {
-       return TRUE;
-      }
+    if (name_match (unam->name, secnam) == 0)
+      return TRUE;
 
   return FALSE;
 }
@@ -175,17 +203,12 @@ walk_wild_consider_section (lang_wild_statement_type *ptr,
   bfd_boolean skip = FALSE;
   struct name_list *list_tmp;
 
-  /* Don't process sections from files which were
-     excluded.  */
+  /* Don't process sections from files which were excluded.  */
   for (list_tmp = sec->spec.exclude_name_list;
        list_tmp;
        list_tmp = list_tmp->next)
     {
-      bfd_boolean is_wildcard = wildcardp (list_tmp->name);
-      if (is_wildcard)
-       skip = fnmatch (list_tmp->name, file->filename, 0) == 0;
-      else
-       skip = strcmp (list_tmp->name, file->filename) == 0;
+      skip = name_match (list_tmp->name, file->filename) == 0;
 
       /* If this file is part of an archive, and the archive is
         excluded, exclude this file.  */
@@ -193,13 +216,8 @@ walk_wild_consider_section (lang_wild_statement_type *ptr,
          && file->the_bfd->my_archive != NULL
          && file->the_bfd->my_archive->filename != NULL)
        {
-         if (is_wildcard)
-           skip = fnmatch (list_tmp->name,
-                           file->the_bfd->my_archive->filename,
-                           0) == 0;
-         else
-           skip = strcmp (list_tmp->name,
-                          file->the_bfd->my_archive->filename) == 0;
+         skip = name_match (list_tmp->name,
+                            file->the_bfd->my_archive->filename) == 0;
        }
 
       if (skip)
@@ -236,10 +254,7 @@ walk_wild_section_general (lang_wild_statement_type *ptr,
            {
              const char *sname = bfd_get_section_name (file->the_bfd, s);
 
-             if (wildcardp (sec->spec.name))
-               skip = fnmatch (sec->spec.name, sname, 0) != 0;
-             else
-               skip = strcmp (sec->spec.name, sname) != 0;
+             skip = name_match (sec->spec.name, sname) != 0;
            }
 
          if (!skip)
@@ -780,6 +795,7 @@ static void
 walk_wild (lang_wild_statement_type *s, callback_t callback, void *data)
 {
   const char *file_spec = s->filename;
+  char *p;
 
   if (file_spec == NULL)
     {
@@ -789,6 +805,29 @@ walk_wild (lang_wild_statement_type *s, callback_t callback, void *data)
          walk_wild_file (s, f, callback, data);
        }
     }
+  else if ((p = archive_path (file_spec)) != NULL)
+    {
+      LANG_FOR_EACH_INPUT_STATEMENT (f)
+       {
+         if ((*(p + 1) == 0
+              || name_match (p + 1, f->filename) == 0)
+             && ((p != file_spec)
+                 == (f->the_bfd != NULL && f->the_bfd->my_archive != NULL)))
+           {
+             bfd_boolean skip = FALSE;
+
+             if (p != file_spec)
+               {
+                 const char *aname = f->the_bfd->my_archive->filename;
+                 *p = 0;
+                 skip = name_match (file_spec, aname) != 0;
+                 *p = link_info.path_separator;
+               }
+             if (!skip)
+               walk_wild_file (s, f, callback, data);
+           }
+       }
+    }
   else if (wildcardp (file_spec))
     {
       LANG_FOR_EACH_INPUT_STATEMENT (f)
@@ -2931,7 +2970,8 @@ open_input_bfds (lang_statement_union_type *s, bfd_boolean force)
        case lang_wild_statement_enum:
          /* Maybe we should load the file's symbols.  */
          if (s->wild_statement.filename
-             && ! wildcardp (s->wild_statement.filename))
+             && !wildcardp (s->wild_statement.filename)
+             && !archive_path (s->wild_statement.filename))
            lookup_name (s->wild_statement.filename);
          open_input_bfds (s->wild_statement.children.head, force);
          break;