[PATCH 7/8] PR ld/24600: BFD: Add general linker support for mapless archives

Maciej W. Rozycki macro@orcam.me.uk
Fri Sep 26 23:53:45 GMT 2025


From: Maciej W. Rozycki <macro@redhat.com>

Expand linker mapless archive support from XCOFF targets only across the 
remaining ones.  For this tranform BFD code used by AR to produce symbol 
maps to archive files such as to have a handler supplied to either write 
a map to a file or convert symbol data to an archive symbol definition 
table attached to an archive BFD as if read from a symbol map, but using 
pointers to member BFDs rather than file offsets.  Retain XCOFF handling 
code as it is.

Update documentation and adjust test cases accordingly now that mapless 
archives are accepted for link by all targets.

This, notably, has triggered test failures:

cris-elf  +FAIL: Regular archive w/o index link
cris-elf  +FAIL: Thin archive w/o index link
crisv32-linux  +FAIL: Regular archive w/o index link
crisv32-linux  +FAIL: Thin archive w/o index link

all caused by a segfault in `aout_get_external_symbols' trying to access 
`aout_data' data of an ELF BFD.

This comes from a combination of factors.  Firstly, ELF and Linux CRIS 
targets set the default BFD target to a.out and at the same time they 
set the default linker emulation to ELF.  Secondly, for mapless archives 
code in `bfd_check_format_matches' ignores the BFD target supplied by 
the linker and resorts to iterating over all the BFD formats to find one 
to match.  Thirdly, when called in the linker `bfd_generic_archive_p' 
accepts any archive file without any verification of its member files.  
Consequently the default a.out BFD target is chosen for ELF input.

This only affects the new feature and is not a regression, so shouldn't 
stop this change and will best be sorted independently.
---
Hi,

 The oddity of the CRIS target was recently discussed[1], but the change
applied doesn't seem sufficient, and it all seems to go back to an attempt 
to fix PR binutils/13278 issue with the plugin target[2], where archive 
validation has been disabled for the !target_defaulted case, which stands 
when `bfd_generic_archive_p' is called in the linker.

 Consequently any BFD target supplied is accepted for an archive with a 
map regardless of whether the target is compatible with the archive's 
members or not, and then for mapless archives all the elaborate target 
selection code in `bfd_check_format_matches' seems to be doing nothing, 
except for resorting to the default BFD target, which just happens to work 
for most targets.

 I think the checks that prevent archive validation need to be revisited 
and we also need to validate mapless archives; I fail to see the reason 
why we should not.  But then I don't think the lack of such a cleanup 
should be a showstopper for this feature because of one oddball target 
architecture.  There's no regression in existing functionality after all.

  Maciej

References:

[1] commit 28daddd33acc ("Make bfd_check_format better respect given 
    target"), 
    <https://inbox.sourceware.org/binutils/aJ_XqdlGa2fvBHi6@squeak.grove.modra.org/>

[2] commit b228303dd14e ("PR binutils/13278: --plugin doesn't work on 
    archive"),
    <https://inbox.sourceware.org/binutils/20111011064345.GM25970@bubble.grove.modra.org/>
---
 bfd/archive.c                       |  120 ++++++++++++++++++++++++++++++++----
 bfd/coff-rs6000.c                   |    4 -
 bfd/ecoff.c                         |    9 +-
 bfd/elflink.c                       |   38 ++++++++---
 bfd/format.c                        |    6 +
 bfd/libbfd-in.h                     |   11 ++-
 bfd/libbfd.h                        |   11 ++-
 bfd/linker.c                        |   38 ++++++++---
 bfd/opncls.c                        |    1 
 binutils/doc/binutils.texi          |   16 +---
 ld/testsuite/ld-archive/archive.exp |   21 ++----
 11 files changed, 208 insertions(+), 67 deletions(-)

binutils-bfd-ar-noindex.diff
Index: binutils-gdb/bfd/archive.c
===================================================================
--- binutils-gdb.orig/bfd/archive.c
+++ binutils-gdb/bfd/archive.c
@@ -811,7 +811,10 @@ _bfd_generic_get_elt_at_index (bfd *abfd
   carsym *entry;
 
   entry = bfd_ardata (abfd)->symdefs + sym_index;
-  return _bfd_get_elt_at_filepos (abfd, entry->u.file_offset, NULL);
+  if (bfd_ardata (abfd)->symdef_use_bfd)
+    return entry->u.abfd;
+  else
+    return _bfd_get_elt_at_filepos (abfd, entry->u.file_offset, NULL);
 }
 
 bfd *
@@ -961,6 +964,83 @@ bfd_generic_archive_p (bfd *abfd)
   return _bfd_no_cleanup;
 }
 
+/* Given archive ARCH and symbol map MAP counting ORL_COUNT entries
+   load the symbols for use by the archive.  */
+
+static bool
+_bfd_load_armap (bfd *abfd, unsigned int elength ATTRIBUTE_UNUSED,
+		 struct orl *map, unsigned int orl_count,
+		 int stridx ATTRIBUTE_UNUSED)
+{
+  struct artdata *ardata = bfd_ardata (abfd);
+  size_t symdef_size;
+  size_t counter;
+  carsym *set;
+
+  if (_bfd_mul_overflow (orl_count, sizeof (carsym), &symdef_size))
+    {
+      bfd_set_error (bfd_error_no_memory);
+      return false;
+    }
+  ardata->symdefs = (struct carsym *) bfd_alloc (abfd, symdef_size);
+  if (!ardata->symdefs)
+    {
+      bfd_set_error (bfd_error_no_memory);
+      return false;
+    }
+  ardata->symdef_count = orl_count;
+
+  for (counter = 0, set = ardata->symdefs;
+       counter < ardata->symdef_count;
+       counter++, set++)
+    {
+      bfd_size_type namelen = strlen (*(map[counter].name)) + 1;
+      char *name = bfd_alloc (abfd, namelen);
+
+      if (name == NULL)
+	{
+	  bfd_set_error (bfd_error_no_memory);
+	  goto release_symdefs;
+	}
+
+      memcpy (name, *(map[counter].name), namelen);
+      set->name = name;
+      set->u.abfd = map[counter].abfd;
+    }
+
+  ardata->symdef_use_bfd = true;
+  return true;
+
+ release_symdefs:
+  bfd_release (abfd, ardata->symdefs);
+  ardata->symdef_count = 0;
+  ardata->symdefs = NULL;
+  return false;
+}
+
+/* Iterate over members of archive ARCH starting from FIRST_ONE and
+   load their symbols for use by the archive.  */
+
+bool
+_bfd_make_armap (bfd *abfd, bfd *first_one)
+{
+  bfd **last_one;
+  bfd *next_one;
+
+  last_one = &(abfd->archive_next);
+  for (next_one = first_one;
+       next_one;
+       next_one = bfd_openr_next_archived_file (abfd, next_one))
+    {
+      *last_one = next_one;
+      last_one = &next_one->archive_next;
+    }
+  *last_one = NULL;
+  bfd_set_archive_head (abfd, first_one);
+
+  return _bfd_compute_and_push_armap (abfd, 0, _bfd_load_armap);
+}
+
 /* Some constants for a 32 bit BSD archive structure.  We do not
    support 64 bit archives presently; so far as I know, none actually
    exist.  Supporting them would require changing these constants, and
@@ -2212,7 +2292,8 @@ _bfd_write_archive_contents (bfd *arch)
 
   if (makemap && hasobjects)
     {
-      if (! _bfd_compute_and_write_armap (arch, (unsigned int) elength))
+      if (!_bfd_compute_and_push_armap (arch, (unsigned int) elength,
+					_bfd_write_armap))
 	return false;
     }
 
@@ -2310,10 +2391,31 @@ _bfd_write_archive_contents (bfd *arch)
   return false;
 }
 
-/* Note that the namidx for the first symbol is 0.  */
+/* Given archive ARCH write symbol map MAP counting ORL_COUNT entries
+   and using STRIDX bytes for symbol names to the archive file, with
+   ELENGTH holding the length of any extended name table.  */
 
 bool
-_bfd_compute_and_write_armap (bfd *arch, unsigned int elength)
+_bfd_write_armap (bfd *arch, unsigned int elength,
+		  struct orl *map, unsigned int orl_count, int stridx)
+{
+  /* Dunno if this is the best place for this info...  */
+  if (elength != 0)
+    elength += sizeof (struct ar_hdr);
+  elength += elength % 2;
+
+  return BFD_SEND (arch, write_armap,
+		   (arch, elength, map, orl_count, stridx));
+}
+
+/* Iterate over members of archive ARCH retrieving their symbols and then
+   push the symbols out using PUSH_ARMAP handler, giving it extended name
+   table length ELENGTH.  Note that the namidx for the first symbol is 0.  */
+
+bool
+_bfd_compute_and_push_armap
+  (bfd *arch, unsigned int elength,
+   bool (*push_armap) (bfd *, unsigned int, struct orl *, unsigned int, int))
 {
   char *first_name = NULL;
   bfd *current;
@@ -2327,11 +2429,6 @@ _bfd_compute_and_write_armap (bfd *arch,
   size_t amt;
   static bool report_plugin_err = true;
 
-  /* Dunno if this is the best place for this info...  */
-  if (elength != 0)
-    elength += sizeof (struct ar_hdr);
-  elength += elength % 2;
-
   amt = orl_max * sizeof (struct orl);
   map = (struct orl *) bfd_malloc (amt);
   if (map == NULL)
@@ -2453,9 +2550,8 @@ _bfd_compute_and_write_armap (bfd *arch,
 	}
     }
 
-  /* OK, now we have collected all the data, let's write them out.  */
-  ret = BFD_SEND (arch, write_armap,
-		  (arch, elength, map, orl_count, stridx));
+  /* OK, now we have collected all the data, let's push them out.  */
+  ret = push_armap (arch, elength, map, orl_count, stridx);
 
   free (syms);
   free (map);
Index: binutils-gdb/bfd/coff-rs6000.c
===================================================================
--- binutils-gdb.orig/bfd/coff-rs6000.c
+++ binutils-gdb/bfd/coff-rs6000.c
@@ -2498,7 +2498,7 @@ xcoff_write_archive_contents_old (bfd *a
       BFD_ASSERT (nextoff == bfd_tell (abfd));
       sprintf (fhdr->symoff, "%ld", (long) nextoff);
       bfd_ardata (abfd)->tdata = &xtdata;
-      bool ret = _bfd_compute_and_write_armap (abfd, 0);
+      bool ret = _bfd_compute_and_push_armap (abfd, 0, _bfd_write_armap);
       bfd_ardata (abfd)->tdata = NULL;
       if (!ret)
 	return false;
@@ -2766,7 +2766,7 @@ xcoff_write_archive_contents_big (bfd *a
       PRINT20 (fhdr->symoff, nextoff);
 
       bfd_ardata (abfd)->tdata = &xtdata;
-      bool ret = _bfd_compute_and_write_armap (abfd, 0);
+      bool ret = _bfd_compute_and_push_armap (abfd, 0, _bfd_write_armap);
       bfd_ardata (abfd)->tdata = NULL;
       if (!ret)
 	return false;
Index: binutils-gdb/bfd/ecoff.c
===================================================================
--- binutils-gdb.orig/bfd/ecoff.c
+++ binutils-gdb/bfd/ecoff.c
@@ -3596,11 +3596,14 @@ ecoff_link_add_archive_symbols (bfd *abf
 
   if (! bfd_has_map (abfd))
     {
+      bfd *first_one = bfd_openr_next_archived_file (abfd, NULL);
+
       /* An empty archive is a special case.  */
-      if (bfd_openr_next_archived_file (abfd, NULL) == NULL)
+      if (first_one == NULL)
 	return true;
-      bfd_set_error (bfd_error_no_armap);
-      return false;
+
+      if (!_bfd_make_armap (abfd, first_one))
+	return false;
     }
 
   /* If we don't have any raw data for this archive, as can happen on
Index: binutils-gdb/bfd/elflink.c
===================================================================
--- binutils-gdb.orig/bfd/elflink.c
+++ binutils-gdb/bfd/elflink.c
@@ -3691,7 +3691,10 @@ elf_link_is_defined_archive_symbol (bfd
   Elf_Internal_Sym *isymend;
   bool result;
 
-  abfd = _bfd_get_elt_at_filepos (abfd, symdef->u.file_offset, NULL);
+  if (bfd_ardata (abfd)->symdef_use_bfd)
+    abfd = symdef->u.abfd;
+  else
+    abfd = _bfd_get_elt_at_filepos (abfd, symdef->u.file_offset, NULL);
   if (abfd == NULL)
     return false;
 
@@ -6251,11 +6254,14 @@ elf_link_add_archive_symbols (bfd *abfd,
 
   if (! bfd_has_map (abfd))
     {
+      bfd *first_one = bfd_openr_next_archived_file (abfd, NULL);
+
       /* An empty archive is a special case.  */
-      if (bfd_openr_next_archived_file (abfd, NULL) == NULL)
+      if (first_one == NULL)
 	return true;
-      bfd_set_error (bfd_error_no_armap);
-      return false;
+
+      if (!_bfd_make_armap (abfd, first_one))
+	return false;
     }
 
   /* Keep track of all symbols we know to be already defined, and all
@@ -6275,13 +6281,16 @@ elf_link_add_archive_symbols (bfd *abfd,
 
   do
     {
-      file_ptr last;
+      file_ptr_or_bfd last;
       symindex i;
       carsym *symdef;
       carsym *symdefend;
 
       loop = false;
-      last = -1;
+      if (bfd_ardata (abfd)->symdef_use_bfd)
+	last.abfd = NULL;
+      else
+	last.file_offset = -1;
 
       symdef = symdefs;
       symdefend = symdef + c;
@@ -6294,7 +6303,9 @@ elf_link_add_archive_symbols (bfd *abfd,
 
 	  if (included[i])
 	    continue;
-	  if (symdef->u.file_offset == last)
+	  if (bfd_ardata (abfd)->symdef_use_bfd
+	      ? symdef->u.abfd == last.abfd
+	      : symdef->u.file_offset == last.file_offset)
 	    {
 	      included[i] = true;
 	      continue;
@@ -6379,8 +6390,11 @@ elf_link_add_archive_symbols (bfd *abfd,
 	    }
 
 	  /* We need to include this archive member.  */
-	  element = _bfd_get_elt_at_filepos (abfd, symdef->u.file_offset,
-					     info);
+	  if (bfd_ardata (abfd)->symdef_use_bfd)
+	    element = symdef->u.abfd;
+	  else
+	    element = _bfd_get_elt_at_filepos (abfd, symdef->u.file_offset,
+					       info);
 	  if (element == NULL)
 	    goto error_return;
 
@@ -6415,11 +6429,13 @@ elf_link_add_archive_symbols (bfd *abfd,
 		break;
 	      --mark;
 	    }
-	  while (symdefs[mark].u.file_offset == symdef->u.file_offset);
+	  while (bfd_ardata (abfd)->symdef_use_bfd
+		 ? symdefs[mark].u.abfd == symdef->u.abfd
+		 : symdefs[mark].u.file_offset == symdef->u.file_offset);
 
 	  /* We mark subsequent symbols from this object file as we go
 	     on through the loop.  */
-	  last = symdef->u.file_offset;
+	  last = symdef->u;
 	}
     }
   while (loop);
Index: binutils-gdb/bfd/libbfd-in.h
===================================================================
--- binutils-gdb.orig/bfd/libbfd-in.h
+++ binutils-gdb/bfd/libbfd-in.h
@@ -73,6 +73,7 @@ struct artdata
   htab_t cache;
   carsym *symdefs;		/* The symdef entries.  */
   symindex symdef_count;	/* How many there are.  */
+  unsigned int symdef_use_bfd:1; /* Whether entries hold a BFD pointer.  */
   char *extended_names;		/* Clever intel extension.  */
   bfd_size_type extended_names_size; /* Size of extended names.  */
   /* When more compilers are standard C, this can be a time_t.  */
@@ -128,6 +129,8 @@ extern char *_bfd_append_relative_path
   (bfd *, char *) ATTRIBUTE_HIDDEN;
 extern bfd_cleanup bfd_generic_archive_p
   (bfd *) ATTRIBUTE_HIDDEN;
+extern bool _bfd_make_armap
+  (bfd *, bfd *) ATTRIBUTE_HIDDEN;
 extern bool bfd_slurp_armap
   (bfd *) ATTRIBUTE_HIDDEN;
 #define bfd_slurp_bsd_armap bfd_slurp_armap
@@ -160,8 +163,12 @@ extern bool _bfd_construct_extended_name
   (bfd *, bool, char **, bfd_size_type *) ATTRIBUTE_HIDDEN;
 extern bool _bfd_write_archive_contents
   (bfd *) ATTRIBUTE_HIDDEN;
-extern bool _bfd_compute_and_write_armap
-  (bfd *, unsigned int) ATTRIBUTE_HIDDEN;
+extern bool _bfd_write_armap
+  (bfd *, unsigned int, struct orl *, unsigned int, int) ATTRIBUTE_HIDDEN;
+extern bool _bfd_compute_and_push_armap
+  (bfd *, unsigned int,
+   bool (*) (bfd *, unsigned int, struct orl *, unsigned int, int))
+  ATTRIBUTE_HIDDEN;
 extern bfd *_bfd_get_elt_at_filepos
   (bfd *, file_ptr, struct bfd_link_info *) ATTRIBUTE_HIDDEN;
 extern bfd *_bfd_generic_get_elt_at_index
Index: binutils-gdb/bfd/libbfd.h
===================================================================
--- binutils-gdb.orig/bfd/libbfd.h
+++ binutils-gdb/bfd/libbfd.h
@@ -79,6 +79,7 @@ struct artdata
   htab_t cache;
   carsym *symdefs;		/* The symdef entries.  */
   symindex symdef_count;	/* How many there are.  */
+  unsigned int symdef_use_bfd:1; /* Whether entries hold a BFD pointer.  */
   char *extended_names;		/* Clever intel extension.  */
   bfd_size_type extended_names_size; /* Size of extended names.  */
   /* When more compilers are standard C, this can be a time_t.  */
@@ -134,6 +135,8 @@ extern char *_bfd_append_relative_path
   (bfd *, char *) ATTRIBUTE_HIDDEN;
 extern bfd_cleanup bfd_generic_archive_p
   (bfd *) ATTRIBUTE_HIDDEN;
+extern bool _bfd_make_armap
+  (bfd *, bfd *) ATTRIBUTE_HIDDEN;
 extern bool bfd_slurp_armap
   (bfd *) ATTRIBUTE_HIDDEN;
 #define bfd_slurp_bsd_armap bfd_slurp_armap
@@ -166,8 +169,12 @@ extern bool _bfd_construct_extended_name
   (bfd *, bool, char **, bfd_size_type *) ATTRIBUTE_HIDDEN;
 extern bool _bfd_write_archive_contents
   (bfd *) ATTRIBUTE_HIDDEN;
-extern bool _bfd_compute_and_write_armap
-  (bfd *, unsigned int) ATTRIBUTE_HIDDEN;
+extern bool _bfd_write_armap
+  (bfd *, unsigned int, struct orl *, unsigned int, int) ATTRIBUTE_HIDDEN;
+extern bool _bfd_compute_and_push_armap
+  (bfd *, unsigned int,
+   bool (*) (bfd *, unsigned int, struct orl *, unsigned int, int))
+  ATTRIBUTE_HIDDEN;
 extern bfd *_bfd_get_elt_at_filepos
   (bfd *, file_ptr, struct bfd_link_info *) ATTRIBUTE_HIDDEN;
 extern bfd *_bfd_generic_get_elt_at_index
Index: binutils-gdb/bfd/linker.c
===================================================================
--- binutils-gdb.orig/bfd/linker.c
+++ binutils-gdb/bfd/linker.c
@@ -937,11 +937,14 @@ _bfd_generic_link_add_archive_symbols
 
   if (! bfd_has_map (abfd))
     {
+      bfd *first_one = bfd_openr_next_archived_file (abfd, NULL);
+
       /* An empty archive is a special case.  */
-      if (bfd_openr_next_archived_file (abfd, NULL) == NULL)
+      if (first_one == NULL)
 	return true;
-      bfd_set_error (bfd_error_no_armap);
-      return false;
+
+      if (!_bfd_make_armap (abfd, first_one))
+	return false;
     }
 
   amt = bfd_ardata (abfd)->symdef_count;
@@ -958,11 +961,16 @@ _bfd_generic_link_add_archive_symbols
       carsym *arsym_end;
       carsym *arsym;
       unsigned int indx;
-      file_ptr last_ar_offset = -1;
+      file_ptr_or_bfd last;
       bool needed = false;
       bfd *element = NULL;
 
       loop = false;
+      if (bfd_ardata (abfd)->symdef_use_bfd)
+	last.abfd = NULL;
+      else
+	last.file_offset = -1;
+
       arsyms = bfd_ardata (abfd)->symdefs;
       arsym_end = arsyms + bfd_ardata (abfd)->symdef_count;
       for (arsym = arsyms, indx = 0; arsym < arsym_end; arsym++, indx++)
@@ -972,7 +980,10 @@ _bfd_generic_link_add_archive_symbols
 
 	  if (included[indx])
 	    continue;
-	  if (needed && arsym->u.file_offset == last_ar_offset)
+	  if (needed
+	      && (bfd_ardata (abfd)->symdef_use_bfd
+		  ? arsym->u.abfd == last.abfd
+		  : arsym->u.file_offset == last.file_offset))
 	    {
 	      included[indx] = 1;
 	      continue;
@@ -1001,11 +1012,16 @@ _bfd_generic_link_add_archive_symbols
 	      continue;
 	    }
 
-	  if (last_ar_offset != arsym->u.file_offset)
+	  if (bfd_ardata (abfd)->symdef_use_bfd
+	      ? last.abfd != arsym->u.abfd
+	      : last.file_offset != arsym->u.file_offset)
 	    {
-	      last_ar_offset = arsym->u.file_offset;
-	      element = _bfd_get_elt_at_filepos (abfd, last_ar_offset,
-						 info);
+	      last = arsym->u;
+	      if (bfd_ardata (abfd)->symdef_use_bfd)
+		element = last.abfd;
+	      else
+		element = _bfd_get_elt_at_filepos (abfd, last.file_offset,
+						   info);
 	      if (element == NULL
 		  || !bfd_check_format (element, bfd_object))
 		goto error_return;
@@ -1032,7 +1048,9 @@ _bfd_generic_link_add_archive_symbols
 		    break;
 		  --mark;
 		}
-	      while (arsyms[mark].u.file_offset == last_ar_offset);
+	      while (bfd_ardata (abfd)->symdef_use_bfd
+		     ? arsyms[mark].u.abfd == last.abfd
+		     : arsyms[mark].u.file_offset == last.file_offset);
 
 	      if (undefs_tail != info->hash->undefs_tail)
 		loop = true;
Index: binutils-gdb/binutils/doc/binutils.texi
===================================================================
--- binutils-gdb.orig/binutils/doc/binutils.texi
+++ binutils-gdb/binutils/doc/binutils.texi
@@ -205,9 +205,7 @@ subroutines.  Since libraries often will
 object modules in the archive when you specify the modifier @samp{s}.
 Once created, this index is updated in the archive whenever @command{ar}
 makes a change to its contents (save for the @samp{q} update operation).
-An archive with such an index speeds up linking to the library, and
-allows routines in the library to call each other without regard to
-their placement in the archive.
+An archive with such an index speeds up linking to the library.
 
 You may use @samp{nm -s} or @samp{nm --print-armap} to list this index
 table.  If an archive lacks the table, another form of @command{ar} called
@@ -501,10 +499,10 @@ archive is equivalent to running @samp{r
 @item S
 @cindex not writing archive index
 Do not generate an archive symbol table.  This can speed up building a
-large library in several steps.  The resulting archive can not be used
-with the linker.  In order to build a symbol table, you must omit the
-@samp{S} modifier on the last execution of @samp{ar}, or you must run
-@samp{ranlib} on the archive.
+large library in several steps, but will negatively impact performance
+if the resulting archive is used with the linker.  In order to build a
+symbol table, you must omit the @samp{S} modifier on the last execution
+of @samp{ar}, or you must run @samp{ranlib} on the archive.
 
 @item T
 Deprecated alias for @option{--thin}.  @option{T} is not recommended because in
@@ -3149,9 +3147,7 @@ member of an archive that is a relocatab
 
 You may use @samp{nm -s} or @samp{nm --print-armap} to list this index.
 
-An archive with such an index speeds up linking to the library and
-allows routines in the library to call each other without regard to
-their placement in the archive.
+An archive with such an index speeds up linking to the library.
 
 The @sc{gnu} @command{ranlib} program is another form of @sc{gnu} @command{ar}; running
 @command{ranlib} is completely equivalent to executing @samp{ar -s}.
Index: binutils-gdb/ld/testsuite/ld-archive/archive.exp
===================================================================
--- binutils-gdb.orig/ld/testsuite/ld-archive/archive.exp
+++ binutils-gdb/ld/testsuite/ld-archive/archive.exp
@@ -98,26 +98,21 @@ run_ld_link_tests [list \
 	[expr { [istarget "*-*-msdos"] ? {} : {{nm "" abcde.nd}} }] \
 	"abtcdte" \
     ] \
-]
-
-set LDFLAGS $old_ldflags
-
-# XCOFF targets currently accept archives w/o index.
-if { [is_xcoff_format] } {
-    return
-}
-
-run_ld_link_tests [list \
     [list "Regular archive w/o index link" \
 	"-e ff" "tmpdir/abn.a" \
 	"" {abc.s} \
-	{{ld abc.ed}} \
+	[expr { [istarget "*-*-msdos"] ? {} : {{nm "" abc.nd}} }] \
 	"abnc" \
     ] \
+]
+setup_kfail "binutils/33484" "alpha*-*-linux*ecoff*" "alpha*-*-osf*"
+run_ld_link_tests [list \
     [list "Thin archive w/o index link" \
 	"-e ff" "tmpdir/abnt.a" \
 	"" {abc.s} \
-	{{ld abct.ed}} \
-	"abnct" \
+	[expr { [istarget "*-*-msdos"] ? {} : {{nm "" abc.nd}} }] \
+	"abntc" \
     ] \
 ]
+
+set LDFLAGS $old_ldflags


More information about the Binutils mailing list