Blame SOURCES/binutils-linkonce-notes.patch

381f6c
--- binutils.orig/gas/write.c	2018-05-14 12:22:27.893671804 +0100
381f6c
+++ binutils-2.30/gas/write.c	2018-05-14 15:39:03.900509629 +0100
381f6c
@@ -1901,6 +1901,7 @@ maybe_generate_build_notes (void)
381f6c
   segT      sec;
381f6c
   char *    note;
381f6c
   offsetT   note_size;
381f6c
+  offsetT   total_size;
381f6c
   offsetT   desc_size;
381f6c
   offsetT   desc2_offset;
381f6c
   int       desc_reloc;
381f6c
@@ -1918,7 +1919,8 @@ maybe_generate_build_notes (void)
381f6c
 			 SEC_READONLY | SEC_HAS_CONTENTS | SEC_DATA);
381f6c
   bfd_set_section_alignment (stdoutput, sec, 2);
381f6c
 
381f6c
-  /* Create a version note.  */
381f6c
+  /* Work out the size of the notes that we will create,
381f6c
+     and the relocation we should use.  */
381f6c
   if (bfd_arch_bits_per_address (stdoutput) <= 32)
381f6c
     {
381f6c
       note_size = 28;
381f6c
@@ -1952,65 +1954,59 @@ maybe_generate_build_notes (void)
381f6c
 	desc_reloc = BFD_RELOC_64;
381f6c
     }
381f6c
   
381f6c
-  frag_now_fix ();
381f6c
-  note = frag_more (note_size);
381f6c
-  memset (note, 0, note_size);
381f6c
+  /* We have to create a note for *each* code section.
381f6c
+     Linker garbage collection might discard some.  */
381f6c
+  total_size = 0;
381f6c
+  note = NULL;
381f6c
 
381f6c
-  if (target_big_endian)
381f6c
-    {
381f6c
-      note[3] = 8; /* strlen (name) + 1.  */
381f6c
-      note[7] = desc_size; /* Two 8-byte offsets.  */
381f6c
-      note[10] = NT_GNU_BUILD_ATTRIBUTE_OPEN >> 8;
381f6c
-      note[11] = NT_GNU_BUILD_ATTRIBUTE_OPEN & 0xff;
381f6c
-    }
381f6c
-  else
381f6c
-    {
381f6c
-      note[0] = 8; /* strlen (name) + 1.  */
381f6c
-      note[4] = desc_size; /* Two 8-byte offsets.  */
381f6c
-      note[8] = NT_GNU_BUILD_ATTRIBUTE_OPEN & 0xff;
381f6c
-      note[9] = NT_GNU_BUILD_ATTRIBUTE_OPEN >> 8;
381f6c
-    }
381f6c
-
381f6c
-  /* The a1 version number indicates that this note was
381f6c
-     generated by the assembler and not the gcc annobin plugin.  */
381f6c
-  memcpy (note + 12, "GA$?3a1", 8);
381f6c
-
381f6c
-  /* Find the first code section symbol.  */
381f6c
   for (sym = symbol_rootP; sym != NULL; sym = sym->sy_next)
381f6c
     if (sym->bsym != NULL
381f6c
 	&& sym->bsym->flags & BSF_SECTION_SYM
381f6c
 	&& sym->bsym->section != NULL
381f6c
-	&& sym->bsym->section->flags & SEC_CODE)
381f6c
+	/* Skip linkonce sections - we cannot these section symbols as they may disappear.  */
381f6c
+	&& (sym->bsym->section->flags & (SEC_CODE | SEC_LINK_ONCE)) == SEC_CODE
381f6c
+	/* Not all linkonce sections are flagged...  */
381f6c
+	&& strncmp (S_GET_NAME (sym), ".gnu.linkonce", sizeof ".gnu.linkonce" - 1) != 0)
381f6c
       {
381f6c
-	/* Found one - now create a relocation against this symbol.  */
381f6c
-	create_note_reloc (sec, sym, 20, desc_reloc, 0, note);
381f6c
-	break;
381f6c
-      }
381f6c
+	/* Create a version note.  */
381f6c
+	frag_now_fix ();
381f6c
+	note = frag_more (note_size);
381f6c
+	memset (note, 0, note_size);
381f6c
 
381f6c
-  /* Find the last code section symbol.  */
381f6c
-  if (sym)
381f6c
-    {
381f6c
-      for (sym = symbol_lastP; sym != NULL; sym = sym->sy_previous)
381f6c
-	if (sym->bsym != NULL
381f6c
-	    && sym->bsym->flags & BSF_SECTION_SYM
381f6c
-	    && sym->bsym->section != NULL
381f6c
-	    && sym->bsym->section->flags & SEC_CODE)
381f6c
+	if (target_big_endian)
381f6c
 	  {
381f6c
-	    /* Create a relocation against the end of this symbol.  */
381f6c
-	    create_note_reloc (sec, sym, desc2_offset, desc_reloc,
381f6c
-			       bfd_get_section_size (sym->bsym->section),
381f6c
-			       note);
381f6c
-	    break;
381f6c
+	    note[3] = 8; /* strlen (name) + 1.  */
381f6c
+	    note[7] = desc_size; /* Two 8-byte offsets.  */
381f6c
+	    note[10] = NT_GNU_BUILD_ATTRIBUTE_OPEN >> 8;
381f6c
+	    note[11] = NT_GNU_BUILD_ATTRIBUTE_OPEN & 0xff;
381f6c
 	  }
381f6c
-    }
381f6c
-  /* else - if we were unable to find any code section symbols then
381f6c
-     probably there is no code in the output.  So leaving the start
381f6c
-     and end values as zero in the note is OK.  */
381f6c
+	else
381f6c
+	  {
381f6c
+	    note[0] = 8; /* strlen (name) + 1.  */
381f6c
+	    note[4] = desc_size; /* Two 8-byte offsets.  */
381f6c
+	    note[8] = NT_GNU_BUILD_ATTRIBUTE_OPEN & 0xff;
381f6c
+	    note[9] = NT_GNU_BUILD_ATTRIBUTE_OPEN >> 8;
381f6c
+	  }
381f6c
+
381f6c
+	/* The a1 version number indicates that this note was
381f6c
+	   generated by the assembler and not the gcc annobin plugin.  */
381f6c
+	memcpy (note + 12, "GA$?3a1", 8);
381f6c
 
381f6c
-  /* FIXME: Maybe add a note recording the assembler command line and version ?  */
381f6c
+	/* Create a relocation to install the start address of the note...  */
381f6c
+	create_note_reloc (sec, sym, 20, desc_reloc, 0, note);
381f6c
+
381f6c
+	/* ...and another one to install the end address.  */
381f6c
+	create_note_reloc (sec, sym, desc2_offset, desc_reloc,
381f6c
+			   bfd_get_section_size (sym->bsym->section),
381f6c
+			   note);
381f6c
+
381f6c
+	total_size += note_size;
381f6c
+	/* FIXME: Maybe add a note recording the assembler command line and version ?  */
381f6c
+      }
381f6c
 
381f6c
   /* Install the note(s) into the section.  */
381f6c
-  bfd_set_section_contents (stdoutput, sec, (bfd_byte *) note, 0, note_size);
381f6c
+  if (total_size)
381f6c
+    bfd_set_section_contents (stdoutput, sec, (bfd_byte *) note, 0, total_size);
381f6c
   subsegs_finish_section (sec);
381f6c
   relax_segment (seg_info (sec)->frchainP->frch_root, sec, 0);
381f6c
   size_seg (stdoutput, sec, NULL);