From cc5277b173701364c10204f316db28198f2c683b Mon Sep 17 00:00:00 2001
From: Martin Liska <mliska@suse.cz>
Date: Thu, 4 Jul 2019 16:39:08 +0200
Subject: 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.
---
 gold/ChangeLog | 11 +++++++++++
 gold/layout.h  | 10 ++++++++++
 gold/object.cc | 31 ++++++++++++++++++++++++++++++-
 3 files changed, 51 insertions(+), 1 deletion(-)

(limited to 'gold')

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,
-- 
cgit v1.1