This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Set my_archive for thin archives


LTO plugin support in plugin_maybe_claim wants to close the IR bfd
after replacing it with the recompiled object, but can't do so for
archive elements due to various pointers that access the archive bfd.
Thin archives have the same problem.  They too cannot have their
element bfds closed.

So set my_archive for thin archive elements.  That means some obvious
changes are necessary:  Accessing a thin archive element is not done
by an offset within the archive itself, but by opening another file,
which explains most of the bfd/ changes.  I've also kept the current
practice of using just the element file when reporting errors and
whatnot for thin archives.  Either way would be reasonable, but if we
report both the archive and file we'll get duplication of the
directory path.

I'm not sure what is best for xcoff import path involving thin
archives, so defaulted to what we do currently, just use the element
filename.  I've also ignored vms-lib.c since even the basic thin
archive tests fail on alpha-dec-vms and ia64-vms.

The patch should also fix selection of input via archive:element in
scripts for thin archives.

	PR ld/20241
bfd/
	* archive.c (open_nested_file): Set my_archive.
	* bfd.c (_bfd_default_error_handler <%B>): Exclude archive file name
	for thin archives.
	* bfdio.c (bfd_tell): Don't adjust origin for thin archives.
	(bfd_seek): Likewise.
	* bfdwin.c (bfd_get_file_window): Likewise.
	* cache.c (cache_bmmap): Likewise.
	(bfd_cache_lookup_worker): Don't look in my_archive for thin archives.
	* mach-o.c (bfd_mach_o_follow_dsym): Don't open my_archive for
	thin archives.
	* plugin.c (try_claim): Likewise.
	* xcofflink.c (xcoff_link_add_dynamic_symbols): Use import path of
	file within thin archive, not the archive.
binutils/
	* bucomm.c (bfd_get_archive_filename): Return file name within thin
	archive.
ld/
	* ldmain.c (add_archive_element): Just print file name of file within
	thin archives.
	* ldmisc.c (vfinfo): Likewise.
	* plugin.c (plugin_object_p): Open file within thin archives.
	(plugin_maybe_claim): Expand comment.

diff --git a/bfd/archive.c b/bfd/archive.c
index 6fc5f1d..7f94376 100644
--- a/bfd/archive.c
+++ b/bfd/archive.c
@@ -392,6 +392,7 @@ open_nested_file (const char *filename, bfd *archive)
     {
       n_bfd->lto_output = archive->lto_output;
       n_bfd->no_export = archive->no_export;
+      n_bfd->my_archive = archive;
     }
   return n_bfd;
 }
diff --git a/bfd/bfd.c b/bfd/bfd.c
index 7400c4e..26143f9 100644
--- a/bfd/bfd.c
+++ b/bfd/bfd.c
@@ -703,7 +703,8 @@ _bfd_default_error_handler (const char *fmt, ...)
 		  if (abfd == NULL)
 		    /* Invoking %B with a null bfd pointer is an internal error.  */
 		    abort ();
-		  else if (abfd->my_archive)
+		  else if (abfd->my_archive
+			   && !bfd_is_thin_archive (abfd->my_archive))
 		    snprintf (bufp, avail, "%s(%s)",
 			      abfd->my_archive->filename, abfd->filename);
 		  else
diff --git a/bfd/bfdio.c b/bfd/bfdio.c
index 55deb3b..71991bd 100644
--- a/bfd/bfdio.c
+++ b/bfd/bfdio.c
@@ -234,7 +234,8 @@ bfd_tell (bfd *abfd)
       bfd *parent_bfd = abfd;
       ptr = abfd->iovec->btell (abfd);
 
-      while (parent_bfd->my_archive != NULL)
+      while (parent_bfd->my_archive != NULL
+	     && !bfd_is_thin_archive (parent_bfd->my_archive))
 	{
 	  ptr -= parent_bfd->origin;
 	  parent_bfd = parent_bfd->my_archive;
@@ -289,7 +290,7 @@ bfd_seek (bfd *abfd, file_ptr position, int direction)
   if (direction == SEEK_CUR && position == 0)
     return 0;
 
-  if (abfd->format != bfd_archive && abfd->my_archive == 0)
+  if (abfd->my_archive == NULL || bfd_is_thin_archive (abfd->my_archive))
     {
       if (direction == SEEK_SET && (bfd_vma) position == abfd->where)
 	return 0;
@@ -314,7 +315,8 @@ bfd_seek (bfd *abfd, file_ptr position, int direction)
     {
       bfd *parent_bfd = abfd;
 
-      while (parent_bfd->my_archive != NULL)
+      while (parent_bfd->my_archive != NULL
+	     && !bfd_is_thin_archive (parent_bfd->my_archive))
         {
           file_position += parent_bfd->origin;
           parent_bfd = parent_bfd->my_archive;
diff --git a/bfd/bfdwin.c b/bfd/bfdwin.c
index 1aaee2c..f3faba4 100644
--- a/bfd/bfdwin.c
+++ b/bfd/bfdwin.c
@@ -144,7 +144,8 @@ bfd_get_file_window (bfd *abfd,
       int fd;
 
       /* Find the real file and the real offset into it.  */
-      while (abfd->my_archive != NULL)
+      while (abfd->my_archive != NULL
+	     && !bfd_is_thin_archive (abfd->my_archive))
 	{
 	  offset += abfd->origin;
 	  abfd = abfd->my_archive;
diff --git a/bfd/cache.c b/bfd/cache.c
index 995cf1f..8efbcb9 100644
--- a/bfd/cache.c
+++ b/bfd/cache.c
@@ -241,7 +241,8 @@ bfd_cache_lookup_worker (bfd *abfd, enum cache_flag flag)
   if ((abfd->flags & BFD_IN_MEMORY) != 0)
     abort ();
 
-  while (abfd->my_archive)
+  while (abfd->my_archive != NULL
+	 && !bfd_is_thin_archive (abfd->my_archive))
     abfd = abfd->my_archive;
 
   if (abfd->iostream != NULL)
@@ -466,7 +467,8 @@ cache_bmmap (struct bfd *abfd ATTRIBUTE_UNUSED,
         pagesize_m1 = getpagesize () - 1;
 
       /* Handle archive members.  */
-      if (abfd->my_archive != NULL)
+      if (abfd->my_archive != NULL
+	  && !bfd_is_thin_archive (abfd->my_archive))
         offset += abfd->origin;
 
       /* Align.  */
diff --git a/bfd/mach-o.c b/bfd/mach-o.c
index 85ce857..1609980 100644
--- a/bfd/mach-o.c
+++ b/bfd/mach-o.c
@@ -5708,7 +5708,7 @@ bfd_mach_o_follow_dsym (bfd *abfd)
   if (abfd == NULL || bfd_get_flavour (abfd) != bfd_target_mach_o_flavour)
     return NULL;
 
-  if (abfd->my_archive)
+  if (abfd->my_archive && !bfd_is_thin_archive (abfd->my_archive))
     base_bfd = abfd->my_archive;
   /* BFD may have been opened from a stream. */
   if (base_bfd->filename == NULL)
diff --git a/bfd/plugin.c b/bfd/plugin.c
index c81a267..559fcd4 100644
--- a/bfd/plugin.c
+++ b/bfd/plugin.c
@@ -167,7 +167,7 @@ try_claim (bfd *abfd)
 
   file.name = abfd->filename;
 
-  if (abfd->my_archive)
+  if (abfd->my_archive && !bfd_is_thin_archive (abfd->my_archive))
     {
       iobfd = abfd->my_archive;
       file.offset = abfd->origin;
@@ -185,7 +185,7 @@ try_claim (bfd *abfd)
 
   file.fd = fileno ((FILE *) iobfd->iostream);
 
-  if (!abfd->my_archive)
+  if (!abfd->my_archive || bfd_is_thin_archive (abfd->my_archive))
     {
       struct stat stat_buf;
       if (fstat (file.fd, &stat_buf))
diff --git a/bfd/xcofflink.c b/bfd/xcofflink.c
index de7a992..d3653e3 100644
--- a/bfd/xcofflink.c
+++ b/bfd/xcofflink.c
@@ -997,7 +997,7 @@ xcoff_link_add_dynamic_symbols (bfd *abfd, struct bfd_link_info *info)
     return FALSE;
   n->next = NULL;
 
-  if (abfd->my_archive == NULL)
+  if (abfd->my_archive == NULL || bfd_is_thin_archive (abfd->my_archive))
     {
       if (!bfd_xcoff_split_import_path (abfd, abfd->filename,
 					&n->path, &n->file))
diff --git a/binutils/bucomm.c b/binutils/bucomm.c
index da7cfad..8ecd7f2 100644
--- a/binutils/bucomm.c
+++ b/binutils/bucomm.c
@@ -605,7 +605,8 @@ bfd_get_archive_filename (const bfd *abfd)
 
   assert (abfd != NULL);
 
-  if (!abfd->my_archive)
+  if (abfd->my_archive == NULL
+      || bfd_is_thin_archive (abfd->my_archive))
     return bfd_get_filename (abfd);
 
   needed = (strlen (bfd_get_filename (abfd->my_archive))
diff --git a/ld/ldmain.c b/ld/ldmain.c
index f16e33b..3c5065f 100644
--- a/ld/ldmain.c
+++ b/ld/ldmain.c
@@ -865,7 +865,8 @@ add_archive_element (struct bfd_link_info *info,
 	  header_printed = TRUE;
 	}
 
-      if (bfd_my_archive (abfd) == NULL)
+      if (bfd_my_archive (abfd) == NULL
+	  || bfd_is_thin_archive (bfd_my_archive (abfd)))
 	{
 	  minfo ("%s", bfd_get_filename (abfd));
 	  len = strlen (bfd_get_filename (abfd));
diff --git a/ld/ldmisc.c b/ld/ldmisc.c
index 70e12ea..321db9a 100644
--- a/ld/ldmisc.c
+++ b/ld/ldmisc.c
@@ -201,7 +201,8 @@ vfinfo (FILE *fp, const char *fmt, va_list arg, bfd_boolean is_warning)
 
 		if (abfd == NULL)
 		  fprintf (fp, "%s generated", program_name);
-		else if (abfd->my_archive)
+		else if (abfd->my_archive != NULL
+			 && !bfd_is_thin_archive (abfd->my_archive))
 		  fprintf (fp, "%s(%s)", abfd->my_archive->filename,
 			   abfd->filename);
 		else
@@ -230,11 +231,13 @@ vfinfo (FILE *fp, const char *fmt, va_list arg, bfd_boolean is_warning)
 		lang_input_statement_type *i;
 
 		i = va_arg (arg, lang_input_statement_type *);
-		if (bfd_my_archive (i->the_bfd) != NULL)
+		if (bfd_my_archive (i->the_bfd) != NULL
+		    && !bfd_is_thin_archive (bfd_my_archive (i->the_bfd)))
 		  fprintf (fp, "(%s)",
 			   bfd_get_filename (bfd_my_archive (i->the_bfd)));
 		fprintf (fp, "%s", i->local_sym_name);
-		if (bfd_my_archive (i->the_bfd) == NULL
+		if ((bfd_my_archive (i->the_bfd) == NULL
+		     || bfd_is_thin_archive (bfd_my_archive (i->the_bfd)))
 		    && filename_cmp (i->local_sym_name, i->filename) != 0)
 		  fprintf (fp, " (%s)", i->filename);
 	      }
diff --git a/ld/plugin.c b/ld/plugin.c
index c951995..c347cfa 100644
--- a/ld/plugin.c
+++ b/ld/plugin.c
@@ -1089,7 +1089,8 @@ plugin_object_p (bfd *ibfd)
 	return NULL;
     }
 
-  inarchive = bfd_my_archive (ibfd) != NULL;
+  inarchive = (bfd_my_archive (ibfd) != NULL
+	       && !bfd_is_thin_archive (bfd_my_archive (ibfd)));
   name = inarchive ? bfd_my_archive (ibfd)->filename : ibfd->filename;
   fd = open (name, O_RDONLY | O_BINARY);
 
@@ -1201,8 +1202,10 @@ plugin_maybe_claim (lang_input_statement_type *entry)
 
       /* Discard the real file's BFD and substitute the dummy one.  */
 
-      /* BFD archive handling caches elements so we can't call
-	 bfd_close for archives.  */
+      /* We can't call bfd_close on archives.  BFD archive handling
+	 caches elements, and add_archive_element keeps pointers to
+	 the_bfd and the_bfd->filename in a lang_input_statement_type
+	 linker script statement.  */
       if (entry->the_bfd->my_archive == NULL)
 	bfd_close (entry->the_bfd);
       entry->the_bfd = abfd;

-- 
Alan Modra
Australia Development Lab, IBM


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]