Stop generating GNU build notes for linkonce sections.

gas	* write.c (maybe_generate_build_notes): Generate notes on a
	per-code-section basis.  Skip linkonce sections.

ld	* testsuite/ld-elf/notes.exp: New file: Run new test.
	* testsuite/ld-elf/note1_1.s: New file: Source file for test.
	* testsuite/ld-elf/note1_2.s: New file: Source file for test.
	* testsuite/ld-elf/note1.r: New file: Expected readelf output.
This commit is contained in:
Nick Clifton 2018-05-14 15:32:43 +01:00
parent c3533c4c7c
commit 864bb26cb3
7 changed files with 141 additions and 50 deletions

View File

@ -1,3 +1,8 @@
2018-05-14 Nick Clifton <nickc@redhat.com>
* write.c (maybe_generate_build_notes): Generate notes on a
per-code-section basis. Skip linkonce sections.
2018-05-14 Nick Clifton <nickc@redhat.com>
PR 23153

View File

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

View File

@ -1,3 +1,10 @@
2018-05-14 Nick Clifton <nickc@redhat.com>
* testsuite/ld-elf/notes.exp: New file: Run new test.
* testsuite/ld-elf/note1_1.s: New file: Source file for test.
* testsuite/ld-elf/note1_2.s: New file: Source file for test.
* testsuite/ld-elf/note1.r: New file: Expected readelf output.
2018-05-14 H.J. Lu <hongjiu.lu@intel.com>
PR ld/23169

View File

@ -0,0 +1,6 @@
#...
Displaying notes found in: .gnu.build.attributes
[ ]+Owner[ ]+Data size[ ]+Description
[ ]+GA\$<version>3a1[ ]+0x000000(08|10)[ ]+OPEN[ ]+Applies to region from 0.*
[ ]+GA\$<version>3a1[ ]+0x000000(08|10)[ ]+OPEN[ ]+Applies to region from 0.*
#pass

View File

@ -0,0 +1,17 @@
.section .gnu.linkonce.t.thunk.ax,"ax",%progbits
.globl thunk.ax
.hidden thunk.ax
.p2align 4
.type thunk.ax,%function
thunk.ax:
.dc.l 0
.size thunk.ax, . - thunk.ax
.p2align 4
.globl foo
.type foo,%function
foo:
.dc.a thunk.ax
.dc.l 0
.size foo, . - foo

View File

@ -0,0 +1,17 @@
.section .gnu.linkonce.t.thunk.ax,"ax",%progbits
.globl thunk.ax
.hidden thunk.ax
.p2align 4
.type thunk.ax,%function
thunk.ax:
.dc.l 0
.size thunk.ax, . - thunk.ax
.p2align 4
.globl bar
.type bar,%function
bar:
.dc.a thunk.ax
.dc.l 0
.size bar, . - bar

View File

@ -0,0 +1,43 @@
# Expect script for various ELF based Note tests.
# Copyright (C) 2018 Free Software Foundation, Inc.
#
# This file is part of the GNU Binutils.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
# MA 02110-1301, USA.
#
# Exclude non-ELF targets.
if ![is_elf_format] {
return
}
set old_ldflags $LDFLAGS
if { [istarget spu*-*-*] } {
set LDFLAGS "$LDFLAGS --local-store 0:0"
}
if { [is_remote host] } then {
remote_download host merge.ld
}
run_ld_link_tests [list \
[list "Linkonce sections with assembler generated notes" \
"-r" "" "--generate-missing-build-notes=yes" \
{note1_1.s note1_2.s} \
{{readelf {--wide --notes} note1.r}} \
"note1.so" ] \
]