[prev in list] [next in list] [prev in thread] [next in thread] 

List:       binutils-cvs
Subject:    [binutils-gdb] Support .gnu.lto_.lto section in ELF files (PR 24768).
From:       Martin Liska <marxin () sourceware ! org>
Date:       2019-07-29 8:13:31
Message-ID: 20190729081331.84738.qmail () sourceware ! org
[Download RAW message or body]

https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=cc5277b173701364c10204f316db28198f2c683b

commit cc5277b173701364c10204f316db28198f2c683b
Author: Martin Liska <mliska@suse.cz>
Date:   Thu Jul 4 16:39:08 2019 +0200

    Support .gnu.lto_.lto section in ELF files (PR 24768).
    
    bfd/ChangeLog:
    
    2019-07-22  Martin Liska  <mliska@suse.cz>
    
    	PR 24768
    	* archive.c (_bfd_compute_and_write_armap): Come up with
    	report_plugin_err variable.
    	* bfd-in2.h (struct bfd): Add lto_slim_object flag.
    	* elf.c (struct lto_section): New.
    	(_bfd_elf_make_section_from_shdr): Parse content of
    	.gnu_lto_.lto section.
    	* elflink.c: Report error for a missing LTO plugin.
    	* linker.c (_bfd_generic_link_add_one_symbol): Likewise.
    
    binutils/ChangeLog:
    
    2019-07-22  Martin Liska  <mliska@suse.cz>
    
    	PR 24768
    	* nm.c (filter_symbols): Set report_plugin_err if
    	error is reported.
    	(display_rel_file): Report error for a missing LTO plugin.
    
    gold/ChangeLog:
    
    2019-07-22  Martin Liska  <mliska@suse.cz>
    
    	PR 24768
    	* layout.h (class Layout): Add is_lto_slim_object and
    	set_lto_slim_object.
    	* object.cc (struct lto_section): Add lto_slim_object_.
    	(big_endian>::do_layout): Parse content of
    	.gnu_lto_.lto section.
    	(big_endian>::do_add_symbols): Report error for a missing
    	LTO plugin.

Diff:
---
 bfd/ChangeLog      | 12 ++++++++++++
 bfd/archive.c      | 21 +++++++++++++++++----
 bfd/bfd-in2.h      |  3 +++
 bfd/elf.c          | 23 +++++++++++++++++++++++
 bfd/elflink.c      |  6 ++++++
 bfd/linker.c       | 24 ++++++++++++++++++------
 binutils/ChangeLog |  7 +++++++
 binutils/nm.c      | 23 ++++++++++++++++++++---
 gold/ChangeLog     | 11 +++++++++++
 gold/layout.h      | 10 ++++++++++
 gold/object.cc     | 31 ++++++++++++++++++++++++++++++-
 11 files changed, 157 insertions(+), 14 deletions(-)

diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index 1364904..4258351 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,3 +1,15 @@
+2019-07-29  Martin Liska  <mliska@suse.cz>
+
+	PR 24768
+	* archive.c (_bfd_compute_and_write_armap): Come up with
+	report_plugin_err variable.
+	* bfd-in2.h (struct bfd): Add lto_slim_object flag.
+	* elf.c (struct lto_section): New.
+	(_bfd_elf_make_section_from_shdr): Parse content of
+	.gnu_lto_.lto section.
+	* elflink.c: Report error for a missing LTO plugin.
+	* linker.c (_bfd_generic_link_add_one_symbol): Likewise.
+
 2019-07-28  Alan Modra  <amodra@gmail.com>
 
 	PR 24857
diff --git a/bfd/archive.c b/bfd/archive.c
index 68a92a3..0a7da3a 100644
--- a/bfd/archive.c
+++ b/bfd/archive.c
@@ -2236,6 +2236,7 @@ _bfd_compute_and_write_armap (bfd *arch, unsigned int elength)
   long syms_max = 0;
   bfd_boolean ret;
   bfd_size_type amt;
+  static bfd_boolean report_plugin_err = TRUE;
 
   /* Dunno if this is the best place for this info...  */
   if (elength != 0)
@@ -2270,6 +2271,14 @@ _bfd_compute_and_write_armap (bfd *arch, unsigned int elength)
 	  long symcount;
 	  long src_count;
 
+	  if (current->lto_slim_object && report_plugin_err)
+	    {
+	      report_plugin_err = FALSE;
+	      _bfd_error_handler
+		(_("%pB: plugin needed to handle lto object"),
+		 current);
+	    }
+
 	  storage = bfd_get_symtab_upper_bound (current);
 	  if (storage < 0)
 	    goto error_return;
@@ -2322,10 +2331,14 @@ _bfd_compute_and_write_armap (bfd *arch, unsigned int elength)
 			  && syms[src_count]->name[1] == '_'
 			  && strcmp (syms[src_count]->name
 				     + (syms[src_count]->name[2] == '_'),
-				     "__gnu_lto_slim") == 0)
-			_bfd_error_handler
-			  (_("%pB: plugin needed to handle lto object"),
-			   current);
+				     "__gnu_lto_slim") == 0
+			  && report_plugin_err)
+			{
+			  report_plugin_err = FALSE;
+			  _bfd_error_handler
+			    (_("%pB: plugin needed to handle lto object"),
+			     current);
+			}
 		      namelen = strlen (syms[src_count]->name);
 		      amt = sizeof (char *);
 		      map[orl_count].name = (char **) bfd_alloc (arch, amt);
diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h
index 8374390..7e6dad7 100644
--- a/bfd/bfd-in2.h
+++ b/bfd/bfd-in2.h
@@ -7196,6 +7196,9 @@ struct bfd
   /* Set if this is a plugin output file.  */
   unsigned int lto_output : 1;
 
+  /* Set if this is a slim LTO object not loaded with a compiler plugin.  */
+  unsigned int lto_slim_object: 1;
+
   /* Set to dummy BFD created when claimed by a compiler plug-in
      library.  */
   bfd *plugin_dummy_bfd;
diff --git a/bfd/elf.c b/bfd/elf.c
index f47e88b..6b5d12c 100644
--- a/bfd/elf.c
+++ b/bfd/elf.c
@@ -999,6 +999,18 @@ convert_zdebug_to_debug (bfd *abfd, const char *name)
   return new_name;
 }
 
+/* This a copy of lto_section defined in GCC (lto-streamer.h).  */
+
+struct lto_section
+{
+  int16_t major_version;
+  int16_t minor_version;
+  unsigned char slim_object;
+
+  /* Flags is a private field that is not defined publicly.  */
+  uint16_t flags;
+};
+
 /* Make a BFD section from an ELF section.  We store a pointer to the
    BFD section in the bfd_section field of the header.  */
 
@@ -1275,6 +1287,17 @@ _bfd_elf_make_section_from_shdr (bfd *abfd,
 	newsect->flags |= SEC_ELF_RENAME;
     }
 
+  /* GCC uses .gnu.lto_.lto.<some_hash> as a LTO bytecode information
+     section.  */
+  const char *lto_section_name = ".gnu.lto_.lto.";
+  if (strncmp (name, lto_section_name, strlen (lto_section_name)) == 0)
+    {
+      struct lto_section lsection;
+      if (bfd_get_section_contents (abfd, newsect, &lsection, 0,
+				    sizeof (struct lto_section)))
+	abfd->lto_slim_object = lsection.slim_object;
+    }
+
   return TRUE;
 }
 
diff --git a/bfd/elflink.c b/bfd/elflink.c
index ad146d4..5971845 100644
--- a/bfd/elflink.c
+++ b/bfd/elflink.c
@@ -4401,6 +4401,12 @@ error_free_dyn:
       goto error_free_vers;
     }
 
+  if (abfd->lto_slim_object)
+    {
+      _bfd_error_handler
+	(_("%pB: plugin needed to handle lto object"), abfd);
+    }
+
   for (isym = isymbuf, isymend = isymbuf + extsymcount;
        isym < isymend;
        isym++, sym_hash++, ever = (ever != NULL ? ever + 1 : NULL))
diff --git a/bfd/linker.c b/bfd/linker.c
index 1b71fcf..edbd0a7 100644
--- a/bfd/linker.c
+++ b/bfd/linker.c
@@ -1421,12 +1421,24 @@ _bfd_generic_link_add_one_symbol (struct bfd_link_info *info,
   else if (bfd_is_com_section (section))
     {
       row = COMMON_ROW;
-      if (!bfd_link_relocatable (info)
-	  && name[0] == '_'
-	  && name[1] == '_'
-	  && strcmp (name + (name[2] == '_'), "__gnu_lto_slim") == 0)
-	_bfd_error_handler
-	  (_("%pB: plugin needed to handle lto object"), abfd);
+      static bfd_boolean report_plugin_err = TRUE;
+      if (!bfd_link_relocatable (info) && report_plugin_err)
+	{
+	  if (abfd->lto_slim_object)
+	    {
+	      report_plugin_err = FALSE;
+	      _bfd_error_handler
+		(_("%pB: plugin needed to handle lto object"), abfd);
+	    }
+	  else if (name[0] == '_'
+		   && name[1] == '_'
+		   && strcmp (name + (name[2] == '_'), "__gnu_lto_slim") == 0)
+	    {
+	      report_plugin_err = FALSE;
+	      _bfd_error_handler
+		(_("%pB: plugin needed to handle lto object"), abfd);
+	    }
+	}
     }
   else
     row = DEF_ROW;
diff --git a/binutils/ChangeLog b/binutils/ChangeLog
index 9195540..f3be264 100644
--- a/binutils/ChangeLog
+++ b/binutils/ChangeLog
@@ -1,3 +1,10 @@
+2019-07-29  Martin Liska  <mliska@suse.cz>
+
+	PR 24768
+	* nm.c (filter_symbols): Set report_plugin_err if
+	error is reported.
+	(display_rel_file): Report error for a missing LTO plugin.
+
 2019-07-26  Alan Modra  <amodra@gmail.com>
 
 	PR 24798
diff --git a/binutils/nm.c b/binutils/nm.c
index fd3f731..5d3d647 100644
--- a/binutils/nm.c
+++ b/binutils/nm.c
@@ -438,6 +438,10 @@ print_symdef_entry (bfd *abfd)
     }
 }
 
+
+/* True when we can report missing plugin error.  */
+bfd_boolean report_plugin_err = TRUE;
+
 /* Choose which symbol entries to print;
    compact them downward to get rid of the rest.
    Return the number of symbols to be printed.  */
@@ -470,9 +474,13 @@ filter_symbols (bfd *abfd, bfd_boolean is_dynamic, void *minisyms,
 
       if (sym->name[0] == '_'
 	  && sym->name[1] == '_'
-	  && strcmp (sym->name + (sym->name[2] == '_'), "__gnu_lto_slim") == 0)
-	non_fatal (_("%s: plugin needed to handle lto object"),
-		   bfd_get_filename (abfd));
+	  && strcmp (sym->name + (sym->name[2] == '_'), "__gnu_lto_slim") == 0
+	  && report_plugin_err)
+	{
+	  report_plugin_err = FALSE;
+	  non_fatal (_("%s: plugin needed to handle lto object"),
+		     bfd_get_filename (abfd));
+	}
 
       if (undefined_only)
 	keep = bfd_is_und_section (sym->section);
@@ -1164,6 +1172,15 @@ display_rel_file (bfd *abfd, bfd *archive_bfd)
 	}
     }
 
+  /* lto_slim_object is set to false when a bfd is loaded with a compiler
+     LTO plugin.  */
+  if (abfd->lto_slim_object)
+    {
+      report_plugin_err = FALSE;
+      non_fatal (_("%s: plugin needed to handle lto object"),
+		 bfd_get_filename (abfd));
+    }
+
   /* Discard the symbols we don't want to print.
      It's OK to do this in place; we'll free the storage anyway
      (after printing).  */
diff --git a/gold/ChangeLog b/gold/ChangeLog
index 67f9088..754d0e3 100644
--- a/gold/ChangeLog
+++ b/gold/ChangeLog
@@ -1,3 +1,14 @@
+2019-07-29  Martin Liska  <mliska@suse.cz>
+
+	PR 24768
+	* layout.h (class Layout): Add is_lto_slim_object and
+	set_lto_slim_object.
+	* object.cc (struct lto_section): Add lto_slim_object_.
+	(big_endian>::do_layout): Parse content of
+	.gnu_lto_.lto section.
+	(big_endian>::do_add_symbols): Report error for a missing
+	LTO plugin.
+
 2019-07-13  Alan Modra  <amodra@gmail.com>
 
 	* powerpc.cc (xlate_pcrel_opt): New function.
diff --git a/gold/layout.h b/gold/layout.h
index bfd44e1..b9b7581 100644
--- a/gold/layout.h
+++ b/gold/layout.h
@@ -593,6 +593,14 @@ class Layout
   set_unique_segment_for_sections_specified()
   { this->unique_segment_for_sections_specified_ = true; }
 
+  bool
+  is_lto_slim_object () const
+  { return this->lto_slim_object_; }
+
+  void
+  set_lto_slim_object ()
+  { this->lto_slim_object_ = true; }
+
   // For incremental updates, allocate a block of memory from the
   // free list.  Find a block starting at or after MINOFF.
   off_t
@@ -1480,6 +1488,8 @@ class Layout
   Incremental_inputs* incremental_inputs_;
   // Whether we record output section data created in script
   bool record_output_section_data_from_script_;
+  // Set if this is a slim LTO object not loaded with a compiler plugin
+  bool lto_slim_object_;
   // List of output data that needs to be removed at relaxation clean up.
   Output_section_data_list script_output_section_data_list_;
   // Structure to save segment states before entering the relaxation loop.
diff --git a/gold/object.cc b/gold/object.cc
index 689448f..86c519a 100644
--- a/gold/object.cc
+++ b/gold/object.cc
@@ -1380,6 +1380,18 @@ Sized_relobj_file<size, big_endian>::layout_gnu_property_section(
     }
 }
 
+// This a copy of lto_section defined in GCC (lto-streamer.h)
+
+struct lto_section
+{
+  int16_t major_version;
+  int16_t minor_version;
+  unsigned char slim_object;
+
+  /* Flags is a private field that is not defined publicly.  */
+  uint16_t flags;
+};
+
 // Lay out the input sections.  We walk through the sections and check
 // whether they should be included in the link.  If they should, we
 // pass them to the Layout object, which will return an output section
@@ -1865,6 +1877,19 @@ Sized_relobj_file<size, big_endian>::do_layout(Symbol_table* symtab,
 		debug_types_sections.push_back(i);
 	    }
 	}
+
+      /* GCC uses .gnu.lto_.lto.<some_hash> as a LTO bytecode information
+	 section.  */
+      const char *lto_section_name = ".gnu.lto_.lto.";
+      if (strncmp (name, lto_section_name, strlen (lto_section_name)) == 0)
+	{
+	  section_size_type contents_len;
+	  const unsigned char* pcontents = this->section_contents(i, &contents_len, false);
+	  struct lto_section lsection = *(const lto_section*)pcontents;
+	  if (lsection.slim_object)
+	    gold_info(_("%s: plugin needed to handle lto object"),
+		      this->name().c_str());
+	}
     }
 
   if (!is_pass_two)
@@ -2083,7 +2108,7 @@ template<int size, bool big_endian>
 void
 Sized_relobj_file<size, big_endian>::do_add_symbols(Symbol_table* symtab,
 						    Read_symbols_data* sd,
-						    Layout*)
+						    Layout* layout)
 {
   if (sd->symbols == NULL)
     {
@@ -2102,6 +2127,10 @@ Sized_relobj_file<size, big_endian>::do_add_symbols(Symbol_table* symtab,
 
   this->symbols_.resize(symcount);
 
+  if (layout->is_lto_slim_object ())
+    gold_info(_("%s: plugin needed to handle lto object"),
+	      this->name().c_str());
+
   const char* sym_names =
     reinterpret_cast<const char*>(sd->symbol_names->data());
   symtab->add_from_relobj(this,
[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic