Add support for v3 binary annotation notes.

I am checking in the attached patch which updates the binutils
  support for version 3 binary annotation notes.  (Version 3 adds
  an end address to the ranges covered by the notes, so that it
  is possible to detect gaps in the coverage).

  This patch also stops the note merging feature of objcopy from
  executing if the notes have relocations against them.  This makes the
  code simpler, and prevents the problems with architectures which have
  unusual relocation management issues.

	* objcopy.c (objcopy_internal_note): New structure.
	(gap_exists): New function.
	(is_open_note): New function.
	(is_func_note): New function.
	(is_64bit): New function.
	(merge_gnu_build_notes): Handle v3 notes.  Do not merge
	if there are relocations against the notes.
	* readelf.c (get_note_type): Use short names for build attribute
	notes.
	(print_symbol_for_build_attribute): Rename to
	get_symbol_for_build_attribute.  Returns the found symbol rather
	than printing it.
	(print_gnu_build_attribute_description): Maintain address ranges
	for function notes as well as global notes.  Handle v3 notes.
	(print_gnu_build_attribute_name): Use more space for printing the
	name in wide mode.
	* testsuite/binutils-all/note-2-32.s: Use .dc.l instead of .word.
	Eliminate symbol references in order to remove the need for
	relocations.
	* testsuite/binutils-all/note-2-64.s: Likewise.
	* testsuite/binutils-all/note-3-32.s: Add a size to the note_1
	symbol.
	* testsuite/binutils-all/note-3-64.s: Likewise.
	* testsuite/binutils-all/mips/mips-note-2r-n32.d: Update expected
	output.
	* testsuite/binutils-all/mips/mips-note-2r-n64.d: Likewise.
	* testsuite/binutils-all/mips/mips-note-2r.d: Likewise.
	* testsuite/binutils-all/note-2-32.d: Likewise.
	* testsuite/binutils-all/note-2-64.d: Likewise.
	* testsuite/binutils-all/note-3-32.d: Likewise.
	* testsuite/binutils-all/note-3-64.d: Likewise.
	* testsuite/binutils-all/note-4-64.s: New test.  Checks v3 notes.
	* testsuite/binutils-all/note-4-32.s: New test.
	* testsuite/binutils-all/note-4-64.d: New test result file.
	* testsuite/binutils-all/note-4-32.d: New test result file.
This commit is contained in:
Nick Clifton 2018-01-03 10:28:33 +00:00
parent 9f757bf7fc
commit 6f156d7a4a
19 changed files with 745 additions and 282 deletions

View file

@ -1,3 +1,41 @@
2018-01-03 Nick Clifton <nickc@redhat.com>
* objcopy.c (objcopy_internal_note): New structure.
(gap_exists): New function.
(is_open_note): New function.
(is_func_note): New function.
(is_64bit): New function.
(merge_gnu_build_notes): Handle v3 notes. Do not merge
if there are relocations against the notes.
* readelf.c (get_note_type): Use short names for build attribute
notes.
(print_symbol_for_build_attribute): Rename to
get_symbol_for_build_attribute. Returns the found symbol rather
than printing it.
(print_gnu_build_attribute_description): Maintain address ranges
for function notes as well as global notes. Handle v3 notes.
(print_gnu_build_attribute_name): Use more space for printing the
name in wide mode.
* testsuite/binutils-all/note-2-32.s: Use .dc.l instead of .word.
Eliminate symbol references in order to remove the need for
relocations.
* testsuite/binutils-all/note-2-64.s: Likewise.
* testsuite/binutils-all/note-3-32.s: Add a size to the note_1
symbol.
* testsuite/binutils-all/note-3-64.s: Likewise.
* testsuite/binutils-all/mips/mips-note-2r-n32.d: Update expected
output.
* testsuite/binutils-all/mips/mips-note-2r-n64.d: Likewise.
* testsuite/binutils-all/mips/mips-note-2r.d: Likewise.
* testsuite/binutils-all/note-2-32.d: Likewise.
* testsuite/binutils-all/note-2-64.d: Likewise.
* testsuite/binutils-all/note-3-32.d: Likewise.
* testsuite/binutils-all/note-3-64.d: Likewise.
* testsuite/binutils-all/note-4-64.s: New test. Checks v3 notes.
* testsuite/binutils-all/note-4-32.s: New test.
* testsuite/binutils-all/note-4-64.d: New test result file.
* testsuite/binutils-all/note-4-32.d: New test result file.
2018-01-03 Alan Modra <amodra@gmail.com> 2018-01-03 Alan Modra <amodra@gmail.com>
Update year range in copyright notice of all files. Update year range in copyright notice of all files.

View file

@ -1905,84 +1905,229 @@ num_bytes (unsigned long val)
return count; return count;
} }
typedef struct objcopy_internal_note
{
Elf_Internal_Note note;
bfd_vma start;
bfd_vma end;
bfd_boolean modified;
} objcopy_internal_note;
/* Returns TRUE if a gap does, or could, exist between the address range
covered by PNOTE1 and PNOTE2. */
static bfd_boolean
gap_exists (objcopy_internal_note * pnote1,
objcopy_internal_note * pnote2)
{
/* Without range end notes, we assume that a gap might exist. */
if (pnote1->end == 0 || pnote2->end == 0)
return TRUE;
/* FIXME: Alignment of 16 bytes taken from x86_64 binaries.
Really we should extract the alignment of the section covered by the notes. */
return BFD_ALIGN (pnote1->end, 16) < pnote2->start;
}
static bfd_boolean
is_open_note (objcopy_internal_note * pnote)
{
return (pnote->note.type == NT_GNU_BUILD_ATTRIBUTE_OPEN);
}
static bfd_boolean
is_func_note (objcopy_internal_note * pnote)
{
return (pnote->note.type == NT_GNU_BUILD_ATTRIBUTE_FUNC);
}
static bfd_boolean
is_64bit (bfd * abfd)
{
/* Should never happen, but let's be paranoid. */
if (bfd_get_flavour (abfd) != bfd_target_elf_flavour)
return FALSE;
return elf_elfheader (abfd)->e_ident[EI_CLASS] == ELFCLASS64;
}
/* Merge the notes on SEC, removing redundant entries. /* Merge the notes on SEC, removing redundant entries.
Returns the new, smaller size of the section upon success. */ Returns the new, smaller size of the section upon success. */
static bfd_size_type static bfd_size_type
merge_gnu_build_notes (bfd * abfd, asection * sec, bfd_size_type size, bfd_byte * contents) merge_gnu_build_notes (bfd * abfd, asection * sec, bfd_size_type size, bfd_byte * contents)
{ {
Elf_Internal_Note * pnotes_end; objcopy_internal_note * pnotes_end;
Elf_Internal_Note * pnotes; objcopy_internal_note * pnotes = NULL;
Elf_Internal_Note * pnote; objcopy_internal_note * pnote;
bfd_size_type remain = size; bfd_size_type remain = size;
unsigned version_1_seen = 0; unsigned version_1_seen = 0;
unsigned version_2_seen = 0; unsigned version_2_seen = 0;
unsigned version_3_seen = 0;
bfd_boolean duplicate_found = FALSE; bfd_boolean duplicate_found = FALSE;
const char * err = NULL; const char * err = NULL;
bfd_byte * in = contents; bfd_byte * in = contents;
int attribute_type_byte; int attribute_type_byte;
int val_start; int val_start;
unsigned long previous_func_start = 0;
unsigned long previous_open_start = 0;
unsigned long previous_func_end = 0;
unsigned long previous_open_end = 0;
long relsize;
/* Make a copy of the notes.
relsize = bfd_get_reloc_upper_bound (abfd, sec);
if (relsize > 0)
{
arelent ** relpp;
long relcount;
/* If there are relocs associated with this section then we
cannot safely merge it. */
relpp = (arelent **) xmalloc (relsize);
relcount = bfd_canonicalize_reloc (abfd, sec, relpp, isympp);
free (relpp);
if (relcount != 0)
goto done;
}
/* Make a copy of the notes and convert to our internal format.
Minimum size of a note is 12 bytes. */ Minimum size of a note is 12 bytes. */
pnote = pnotes = (Elf_Internal_Note *) xcalloc ((size / 12), sizeof (Elf_Internal_Note)); pnote = pnotes = (objcopy_internal_note *) xcalloc ((size / 12), sizeof (* pnote));
while (remain >= 12) while (remain >= 12)
{ {
pnote->namesz = (bfd_get_32 (abfd, in ) + 3) & ~3; bfd_vma start, end;
pnote->descsz = (bfd_get_32 (abfd, in + 4) + 3) & ~3;
pnote->type = bfd_get_32 (abfd, in + 8);
if (pnote->type != NT_GNU_BUILD_ATTRIBUTE_OPEN pnote->note.namesz = (bfd_get_32 (abfd, in ) + 3) & ~3;
&& pnote->type != NT_GNU_BUILD_ATTRIBUTE_FUNC) pnote->note.descsz = (bfd_get_32 (abfd, in + 4) + 3) & ~3;
pnote->note.type = bfd_get_32 (abfd, in + 8);
if (pnote->note.type != NT_GNU_BUILD_ATTRIBUTE_OPEN
&& pnote->note.type != NT_GNU_BUILD_ATTRIBUTE_FUNC)
{ {
err = _("corrupt GNU build attribute note: wrong note type"); err = _("corrupt GNU build attribute note: wrong note type");
goto done; goto done;
} }
if (pnote->namesz + pnote->descsz + 12 > remain) if (pnote->note.namesz + pnote->note.descsz + 12 > remain)
{ {
err = _("corrupt GNU build attribute note: note too big"); err = _("corrupt GNU build attribute note: note too big");
goto done; goto done;
} }
if (pnote->namesz < 2) if (pnote->note.namesz < 2)
{ {
err = _("corrupt GNU build attribute note: name too small"); err = _("corrupt GNU build attribute note: name too small");
goto done; goto done;
} }
if (pnote->descsz != 0 pnote->note.namedata = (char *)(in + 12);
&& pnote->descsz != 4 pnote->note.descdata = (char *)(in + 12 + pnote->note.namesz);
&& pnote->descsz != 8)
remain -= 12 + pnote->note.namesz + pnote->note.descsz;
in += 12 + pnote->note.namesz + pnote->note.descsz;
if (pnote->note.namesz > 2
&& pnote->note.namedata[0] == '$'
&& pnote->note.namedata[1] == GNU_BUILD_ATTRIBUTE_VERSION
&& pnote->note.namedata[2] == '1')
++ version_1_seen;
else if (pnote->note.namesz > 4
&& pnote->note.namedata[0] == 'G'
&& pnote->note.namedata[1] == 'A'
&& pnote->note.namedata[2] == '$'
&& pnote->note.namedata[3] == GNU_BUILD_ATTRIBUTE_VERSION)
{ {
if (pnote->note.namedata[4] == '2')
++ version_2_seen;
else if (pnote->note.namedata[4] == '3')
++ version_3_seen;
else
{
err = _("corrupt GNU build attribute note: unsupported version");
goto done;
}
}
switch (pnote->note.descsz)
{
case 0:
start = end = 0;
break;
case 4:
start = bfd_get_32 (abfd, pnote->note.descdata);
/* FIXME: For version 1 and 2 notes we should try to
calculate the end address by finding a symbol whose
value is START, and then adding in its size.
For now though, since v1 and v2 was not intended to
handle gaps, we chose an artificially large end
address. */
end = 0x7ffffffffffffffUL;
break;
case 8:
if (! is_64bit (abfd))
{
start = bfd_get_32 (abfd, pnote->note.descdata);
end = bfd_get_32 (abfd, pnote->note.descdata + 4);
}
else
{
start = bfd_get_64 (abfd, pnote->note.descdata);
/* FIXME: For version 1 and 2 notes we should try to
calculate the end address by finding a symbol whose
value is START, and then adding in its size.
For now though, since v1 and v2 was not intended to
handle gaps, we chose an artificially large end
address. */
end = 0x7ffffffffffffffUL;
}
break;
case 16:
start = bfd_get_64 (abfd, pnote->note.descdata);
end = bfd_get_64 (abfd, pnote->note.descdata + 8);
break;
default:
err = _("corrupt GNU build attribute note: bad description size"); err = _("corrupt GNU build attribute note: bad description size");
goto done; goto done;
} }
pnote->namedata = (char *)(in + 12); if (is_open_note (pnote))
pnote->descdata = (char *)(in + 12 + pnote->namesz); {
if (start)
previous_open_start = start;
remain -= 12 + pnote->namesz + pnote->descsz; pnote->start = previous_open_start;
in += 12 + pnote->namesz + pnote->descsz;
if (pnote->namedata[pnote->namesz - 1] != 0) if (end)
previous_open_end = end;
pnote->end = previous_open_end;
}
else
{
if (start)
previous_func_start = start;
pnote->start = previous_func_start;
if (end)
previous_func_end = end;
pnote->end = previous_func_end;
}
if (pnote->note.namedata[pnote->note.namesz - 1] != 0)
{ {
err = _("corrupt GNU build attribute note: name not NUL terminated"); err = _("corrupt GNU build attribute note: name not NUL terminated");
goto done; goto done;
} }
if (pnote->namesz > 2
&& pnote->namedata[0] == '$'
&& pnote->namedata[1] == GNU_BUILD_ATTRIBUTE_VERSION
&& pnote->namedata[2] == '1')
++ version_1_seen;
else if (pnote->namesz > 4
&& pnote->namedata[0] == 'G'
&& pnote->namedata[1] == 'A'
&& pnote->namedata[2] == '$'
&& pnote->namedata[3] == GNU_BUILD_ATTRIBUTE_VERSION
&& pnote->namedata[4] == '2')
++ version_2_seen;
pnote ++; pnote ++;
} }
@ -1995,27 +2140,29 @@ merge_gnu_build_notes (bfd * abfd, asection * sec, bfd_size_type size, bfd_byte
goto done; goto done;
} }
if (version_1_seen == 0 && version_2_seen == 0) if (version_1_seen == 0 && version_2_seen == 0 && version_3_seen == 0)
{ {
err = _("bad GNU build attribute notes: no known versions detected"); err = _("bad GNU build attribute notes: no known versions detected");
goto done; goto done;
} }
if (version_1_seen > 0 && version_2_seen > 0) if ((version_1_seen > 0 && version_2_seen > 0)
|| (version_1_seen > 0 && version_3_seen > 0)
|| (version_2_seen > 0 && version_3_seen > 0))
{ {
err = _("bad GNU build attribute notes: multiple different versions"); err = _("bad GNU build attribute notes: multiple different versions");
goto done; goto done;
} }
/* Merging is only needed if there is more than one version note... */ /* Merging is only needed if there is more than one version note... */
if (version_1_seen == 1 || version_2_seen == 1) if (version_1_seen == 1 || version_2_seen == 1 || version_3_seen == 1)
goto done; goto done;
attribute_type_byte = version_1_seen ? 1 : 3; attribute_type_byte = version_1_seen ? 1 : 3;
val_start = attribute_type_byte + 1; val_start = attribute_type_byte + 1;
/* The first note should be the first version note. */ /* The first note should be the first version note. */
if (pnotes[0].namedata[attribute_type_byte] != GNU_BUILD_ATTRIBUTE_VERSION) if (pnotes[0].note.namedata[attribute_type_byte] != GNU_BUILD_ATTRIBUTE_VERSION)
{ {
err = _("bad GNU build attribute notes: first note not version note"); err = _("bad GNU build attribute notes: first note not version note");
goto done; goto done;
@ -2026,7 +2173,9 @@ merge_gnu_build_notes (bfd * abfd, asection * sec, bfd_size_type size, bfd_byte
2. Preserve any NT_GNU_BUILD_ATTRIBUTE_FUNC notes. 2. Preserve any NT_GNU_BUILD_ATTRIBUTE_FUNC notes.
3. Eliminate any NT_GNU_BUILD_ATTRIBUTE_OPEN notes that have the same 3. Eliminate any NT_GNU_BUILD_ATTRIBUTE_OPEN notes that have the same
full name field as the immediately preceeding note with the same type full name field as the immediately preceeding note with the same type
of name. of name and whose address ranges coincide.
IE - it there are gaps in the coverage of the notes, then these gaps
must be preserved.
4. Combine the numeric value of any NT_GNU_BUILD_ATTRIBUTE_OPEN notes 4. Combine the numeric value of any NT_GNU_BUILD_ATTRIBUTE_OPEN notes
of type GNU_BUILD_ATTRIBUTE_STACK_SIZE. of type GNU_BUILD_ATTRIBUTE_STACK_SIZE.
5. If an NT_GNU_BUILD_ATTRIBUTE_OPEN note is going to be preserved and 5. If an NT_GNU_BUILD_ATTRIBUTE_OPEN note is going to be preserved and
@ -2036,103 +2185,134 @@ merge_gnu_build_notes (bfd * abfd, asection * sec, bfd_size_type size, bfd_byte
address to which it refers. */ address to which it refers. */
for (pnote = pnotes + 1; pnote < pnotes_end; pnote ++) for (pnote = pnotes + 1; pnote < pnotes_end; pnote ++)
{ {
Elf_Internal_Note * back; int note_type;
Elf_Internal_Note * prev_open = NULL; objcopy_internal_note * back;
objcopy_internal_note * prev_open_with_range = NULL;
if (pnote->type == NT_GNU_BUILD_ATTRIBUTE_FUNC) /* Rule 2 - preserve function notes. */
if (! is_open_note (pnote))
continue; continue;
/* Scan for duplicates. Clear the type field of any found - but do not note_type = pnote->note.namedata[attribute_type_byte];
delete them just yet. */
/* Scan backwards from pnote, looking for duplicates.
Clear the type field of any found - but do not delete them just yet. */
for (back = pnote - 1; back >= pnotes; back --) for (back = pnote - 1; back >= pnotes; back --)
{ {
if (back->descsz > 0 int back_type = back->note.namedata[attribute_type_byte];
&& back->type != NT_GNU_BUILD_ATTRIBUTE_FUNC
&& prev_open == NULL)
prev_open = back;
if (back->type == pnote->type /* If this is the first open note with an address
&& back->namedata[attribute_type_byte] == pnote->namedata[attribute_type_byte]) range that we have encountered then record it. */
if (prev_open_with_range == NULL
&& back->note.descsz > 0
&& ! is_func_note (back))
prev_open_with_range = back;
if (! is_open_note (back))
continue;
/* If the two notes are different then keep on searching. */
if (back_type != note_type)
continue;
/* Rule 4 - combine stack size notes. */
if (back_type == GNU_BUILD_ATTRIBUTE_STACK_SIZE)
{ {
if (back->namedata[attribute_type_byte] == GNU_BUILD_ATTRIBUTE_STACK_SIZE) unsigned char * name;
unsigned long note_val;
unsigned long back_val;
unsigned int shift;
unsigned int bytes;
unsigned long byte;
for (shift = 0, note_val = 0,
bytes = pnote->note.namesz - val_start,
name = (unsigned char *) pnote->note.namedata + val_start;
bytes--;)
{ {
unsigned char * name; byte = (* name ++) & 0xff;
unsigned long note_val; note_val |= byte << shift;
unsigned long back_val; shift += 8;
unsigned int shift;
unsigned int bytes;
unsigned long byte;
for (shift = 0, note_val = 0,
bytes = pnote->namesz - val_start,
name = (unsigned char *) pnote->namedata + val_start;
bytes--;)
{
byte = (* name ++) & 0xff;
note_val |= byte << shift;
shift += 8;
}
for (shift = 0, back_val = 0,
bytes = back->namesz - val_start,
name = (unsigned char *) back->namedata + val_start;
bytes--;)
{
byte = (* name ++) & 0xff;
back_val |= byte << shift;
shift += 8;
}
back_val += note_val;
if (num_bytes (back_val) >= back->namesz - val_start)
{
/* We have a problem - the new value requires more bytes of
storage in the name field than are available. Currently
we have no way of fixing this, so we just preserve both
notes. */
continue;
}
/* Write the new val into back. */
name = (unsigned char *) back->namedata + val_start;
while (name < (unsigned char *) back->namedata + back->namesz)
{
byte = back_val & 0xff;
* name ++ = byte;
if (back_val == 0)
break;
back_val >>= 8;
}
duplicate_found = TRUE;
pnote->type = 0;
break;
}
if (back->namesz == pnote->namesz
&& memcmp (back->namedata, pnote->namedata, back->namesz) == 0)
{
duplicate_found = TRUE;
pnote->type = 0;
break;
} }
/* If we have found an attribute match then stop searching backwards. */ for (shift = 0, back_val = 0,
if (! ISPRINT (back->namedata[attribute_type_byte]) bytes = back->note.namesz - val_start,
/* Names are NUL terminated, so this is safe. */ name = (unsigned char *) back->note.namedata + val_start;
|| strcmp (back->namedata + val_start, pnote->namedata + val_start) == 0) bytes--;)
{ {
/* Since we are keeping this note we must check to see if its byte = (* name ++) & 0xff;
description refers back to an earlier OPEN version note. If so back_val |= byte << shift;
then we must make sure that version note is also preserved. */ shift += 8;
if (pnote->descsz == 0
&& prev_open != NULL
&& prev_open->type == 0)
prev_open->type = NT_GNU_BUILD_ATTRIBUTE_FUNC;
break;
} }
back_val += note_val;
if (num_bytes (back_val) >= back->note.namesz - val_start)
{
/* We have a problem - the new value requires more bytes of
storage in the name field than are available. Currently
we have no way of fixing this, so we just preserve both
notes. */
continue;
}
/* Write the new val into back. */
name = (unsigned char *) back->note.namedata + val_start;
while (name < (unsigned char *) back->note.namedata
+ back->note.namesz)
{
byte = back_val & 0xff;
* name ++ = byte;
if (back_val == 0)
break;
back_val >>= 8;
}
duplicate_found = TRUE;
pnote->note.type = 0;
break;
} }
/* Rule 3 - combine identical open notes. */
if (back->note.namesz == pnote->note.namesz
&& memcmp (back->note.namedata,
pnote->note.namedata, back->note.namesz) == 0
&& ! gap_exists (back, pnote))
{
duplicate_found = TRUE;
pnote->note.type = 0;
if (pnote->end > back->end)
back->end = pnote->end;
if (version_3_seen)
back->modified = TRUE;
break;
}
/* Rule 5 - Since we are keeping this note we must check to see
if its description refers back to an earlier OPEN version
note that has been scheduled for deletion. If so then we
must make sure that version note is also preserved. */
if (version_3_seen)
{
/* As of version 3 we can just
move the range into the note. */
pnote->modified = TRUE;
pnote->note.type = NT_GNU_BUILD_ATTRIBUTE_FUNC;
back->modified = TRUE;
back->note.type = NT_GNU_BUILD_ATTRIBUTE_FUNC;
}
else
{
if (pnote->note.descsz == 0
&& prev_open_with_range != NULL
&& prev_open_with_range->note.type == 0)
prev_open_with_range->note.type = NT_GNU_BUILD_ATTRIBUTE_OPEN;
}
/* We have found a similar attribute but the details do not match.
Stop searching backwards. */
break;
} }
} }
@ -2142,22 +2322,8 @@ merge_gnu_build_notes (bfd * abfd, asection * sec, bfd_size_type size, bfd_byte
bfd_byte * old; bfd_byte * old;
bfd_byte * new; bfd_byte * new;
bfd_size_type new_size; bfd_size_type new_size;
arelent ** relpp = NULL; bfd_vma prev_start = 0;
long relsize; bfd_vma prev_end = 0;
long relcount = 0;
relsize = bfd_get_reloc_upper_bound (abfd, sec);
if (relsize > 0)
{
/* If there are relocs associated with this section then we may
have to adjust them as well, as we remove notes. */
relpp = (arelent **) xmalloc (relsize);
relcount = bfd_canonicalize_reloc (abfd, sec, relpp, isympp);
if (relcount < 0)
/* Do not bother complaining here - copy_relocations_in_section
will do that for us. */
relcount = 0;
}
/* Eliminate the duplicates. */ /* Eliminate the duplicates. */
new = new_contents = xmalloc (size); new = new_contents = xmalloc (size);
@ -2165,36 +2331,52 @@ merge_gnu_build_notes (bfd * abfd, asection * sec, bfd_size_type size, bfd_byte
pnote < pnotes_end; pnote < pnotes_end;
pnote ++) pnote ++)
{ {
bfd_size_type note_size = 12 + pnote->namesz + pnote->descsz; bfd_size_type note_size = 12 + pnote->note.namesz + pnote->note.descsz;
if (pnote->type == 0) if (pnote->note.type != 0)
{ {
if (relcount > 0) if (pnote->modified)
{ {
arelent ** rel; /* If the note has been modified then we must copy it by
hand, potentially adding in a new description field. */
/* If there is a reloc at the current offset, delete it. if (pnote->start == prev_start && pnote->end == prev_end)
Adjust the location of any relocs above the current
location downwards by the size of the note being deleted.
FIXME: We could optimize this loop by retaining a pointer to
the last reloc below the current note. */
for (rel = relpp; rel < relpp + relcount; rel ++)
{ {
if ((* rel)->howto == NULL) bfd_put_32 (abfd, pnote->note.namesz, new);
continue; bfd_put_32 (abfd, 0, new + 4);
if ((* rel)->address < (bfd_vma) (new - new_contents)) bfd_put_32 (abfd, pnote->note.type, new + 8);
continue; new += 12;
if ((* rel)->address >= (bfd_vma) ((new + note_size) - new_contents)) memcpy (new, pnote->note.namedata, pnote->note.namesz);
(* rel)->address -= note_size; new += pnote->note.namesz;
}
else
{
bfd_put_32 (abfd, pnote->note.namesz, new);
bfd_put_32 (abfd, is_64bit (abfd) ? 16 : 8, new + 4);
bfd_put_32 (abfd, pnote->note.type, new + 8);
new += 12;
memcpy (new, pnote->note.namedata, pnote->note.namesz);
new += pnote->note.namesz;
if (is_64bit (abfd))
{
bfd_put_64 (abfd, pnote->start, new);
bfd_put_64 (abfd, pnote->end, new + 8);
new += 16;
}
else else
(* rel)->howto = NULL; {
bfd_put_32 (abfd, pnote->start, new);
bfd_put_32 (abfd, pnote->end, new + 4);
new += 8;
}
} }
} }
} else
else {
{ memcpy (new, old, note_size);
memcpy (new, old, note_size); new += note_size;
new += note_size; }
prev_start = pnote->start;
prev_end = pnote->end;
} }
old += note_size; old += note_size;
@ -2204,24 +2386,6 @@ merge_gnu_build_notes (bfd * abfd, asection * sec, bfd_size_type size, bfd_byte
memcpy (contents, new_contents, new_size); memcpy (contents, new_contents, new_size);
size = new_size; size = new_size;
free (new_contents); free (new_contents);
if (relcount > 0)
{
arelent **rel = relpp;
while (rel < relpp + relcount)
if ((*rel)->howto != NULL)
rel++;
else
{
/* Delete eliminated relocs.
FIXME: There are better ways to do this. */
memmove (rel, rel + 1,
((relcount - (rel - relpp)) - 1) * sizeof (*rel));
relcount--;
}
bfd_set_reloc (abfd, sec, relpp, relcount);
}
} }
done: done:

View file

@ -16594,9 +16594,9 @@ get_note_type (Filedata * filedata, unsigned e_type)
case NT_ARCH: case NT_ARCH:
return _("NT_ARCH (architecture)"); return _("NT_ARCH (architecture)");
case NT_GNU_BUILD_ATTRIBUTE_OPEN: case NT_GNU_BUILD_ATTRIBUTE_OPEN:
return _("NT_GNU_BUILD_ATTRIBUTE_OPEN"); return _("OPEN");
case NT_GNU_BUILD_ATTRIBUTE_FUNC: case NT_GNU_BUILD_ATTRIBUTE_FUNC:
return _("NT_GNU_BUILD_ATTRIBUTE_FUNC"); return _("func");
default: default:
break; break;
} }
@ -17416,13 +17416,16 @@ print_ia64_vms_note (Elf_Internal_Note * pnote)
return TRUE; return TRUE;
} }
/* Print the name of the symbol associated with a build attribute /* Find the symbol associated with a build attribute that is attached
that is attached to address OFFSET. */ to address OFFSET. If PNAME is non-NULL then store the name of
the symbol (if found) in the provided pointer, Returns NULL if a
symbol could not be found. */
static bfd_boolean static Elf_Internal_Sym *
print_symbol_for_build_attribute (Filedata * filedata, get_symbol_for_build_attribute (Filedata * filedata,
unsigned long offset, unsigned long offset,
bfd_boolean is_open_attr) bfd_boolean is_open_attr,
const char ** pname)
{ {
static Filedata * saved_filedata = NULL; static Filedata * saved_filedata = NULL;
static char * strtab; static char * strtab;
@ -17461,10 +17464,7 @@ print_symbol_for_build_attribute (Filedata * filedata,
} }
if (symtab == NULL || strtab == NULL) if (symtab == NULL || strtab == NULL)
{ return NULL;
printf ("\n");
return FALSE;
}
/* Find a symbol whose value matches offset. */ /* Find a symbol whose value matches offset. */
for (sym = symtab; sym < symtab + nsyms; sym ++) for (sym = symtab; sym < symtab + nsyms; sym ++)
@ -17484,14 +17484,15 @@ print_symbol_for_build_attribute (Filedata * filedata,
FUNC symbols entirely. */ FUNC symbols entirely. */
switch (ELF_ST_TYPE (sym->st_info)) switch (ELF_ST_TYPE (sym->st_info))
{ {
case STT_OBJECT:
case STT_FILE: case STT_FILE:
saved_sym = sym; saved_sym = sym;
/* We can stop searching now. */ if (sym->st_size)
sym = symtab + nsyms; {
continue; /* If the symbol has a size associated
with it then we can stop searching. */
case STT_OBJECT: sym = symtab + nsyms;
saved_sym = sym; }
continue; continue;
case STT_FUNC: case STT_FUNC:
@ -17529,55 +17530,118 @@ print_symbol_for_build_attribute (Filedata * filedata,
} }
} }
printf (" (%s: %s)\n", if (saved_sym && pname)
is_open_attr ? _("file") : _("func"), * pname = strtab + saved_sym->st_name;
saved_sym ? strtab + saved_sym->st_name : _("<no symbol found>)"));
return TRUE; return saved_sym;
} }
static bfd_boolean static bfd_boolean
print_gnu_build_attribute_description (Elf_Internal_Note * pnote, print_gnu_build_attribute_description (Elf_Internal_Note * pnote,
Filedata * filedata) Filedata * filedata)
{ {
static unsigned long global_offset = 0; static unsigned long global_offset = 0;
unsigned long offset; static unsigned long global_end = 0;
unsigned int desc_size = is_32bit_elf ? 4 : 8; static unsigned long func_offset = 0;
bfd_boolean is_open_attr = pnote->type == NT_GNU_BUILD_ATTRIBUTE_OPEN; static unsigned long func_end = 0;
if (pnote->descsz == 0) Elf_Internal_Sym * sym;
const char * name;
unsigned long start;
unsigned long end;
bfd_boolean is_open_attr = pnote->type == NT_GNU_BUILD_ATTRIBUTE_OPEN;
switch (pnote->descsz)
{ {
case 0:
/* A zero-length description means that the range of
the previous note of the same type should be used. */
if (is_open_attr) if (is_open_attr)
{ {
printf (_(" Applies from offset %#lx\n"), global_offset); if (global_end > global_offset)
return TRUE; printf (_(" Applies to region from %#lx to %#lx\n"),
global_offset, global_end);
else
printf (_(" Applies to region from %#lx\n"), global_offset);
} }
else else
{ {
printf (_(" Applies to func at %#lx"), global_offset); if (func_end > func_offset)
return print_symbol_for_build_attribute (filedata, global_offset, is_open_attr); printf (_(" Applies to region from %#lx to %#lx\n"), func_offset, func_end);
else
printf (_(" Applies to region from %#lx\n"), func_offset);
} }
} return TRUE;
if (pnote->descsz != desc_size) case 4:
{ start = byte_get ((unsigned char *) pnote->descdata, 4);
end = 0;
break;
case 8:
if (is_32bit_elf)
{
/* FIXME: We should check that version 3+ notes are being used here... */
start = byte_get ((unsigned char *) pnote->descdata, 4);
end = byte_get ((unsigned char *) pnote->descdata + 4, 4);
}
else
{
start = byte_get ((unsigned char *) pnote->descdata, 8);
end = 0;
}
break;
case 16:
start = byte_get ((unsigned char *) pnote->descdata, 8);
end = byte_get ((unsigned char *) pnote->descdata + 8, 8);
break;
default:
error (_(" <invalid description size: %lx>\n"), pnote->descsz); error (_(" <invalid description size: %lx>\n"), pnote->descsz);
printf (_(" <invalid descsz>")); printf (_(" <invalid descsz>"));
return FALSE; return FALSE;
} }
offset = byte_get ((unsigned char *) pnote->descdata, desc_size); name = NULL;
sym = get_symbol_for_build_attribute (filedata, start, is_open_attr, & name);
if (end == 0 && sym != NULL && sym->st_size > 0)
end = start + sym->st_size;
if (is_open_attr) if (is_open_attr)
{ {
printf (_(" Applies from offset %#lx"), offset); /* FIXME: Need to properly allow for section alignment. 16 is just the alignment used on x86_64. */
global_offset = offset; if (global_end > 0 && start > BFD_ALIGN (global_end, 16))
warn (_("Gap in build notes detected from %#lx to %#lx\n"),
global_end + 1, start - 1);
printf (_(" Applies to region from %#lx"), start);
global_offset = start;
if (end)
{
printf (_(" to %#lx"), end);
global_end = end;
}
} }
else else
{ {
printf (_(" Applies to func at %#lx"), offset); printf (_(" Applies to region from %#lx"), start);
func_offset = start;
if (end)
{
printf (_(" to %#lx"), end);
func_end = end;
}
} }
return print_symbol_for_build_attribute (filedata, offset, is_open_attr); if (sym && name)
printf (_(" (%s)"), name);
printf ("\n");
return TRUE;
} }
static bfd_boolean static bfd_boolean
@ -17600,11 +17664,21 @@ print_gnu_build_attribute_name (Elf_Internal_Note * pnote)
return FALSE; return FALSE;
} }
left = 20; if (do_wide)
left = 28;
else
left = 20;
/* Version 2 of the spec adds a "GA" prefix to the name field. */ /* Version 2 of the spec adds a "GA" prefix to the name field. */
if (name[0] == 'G' && name[1] == 'A') if (name[0] == 'G' && name[1] == 'A')
{ {
if (pnote->namesz < 4)
{
error (_("corrupt name field in GNU build attribute note: size = %ld\n"), pnote->namesz);
print_symbol (-20, _(" <corrupt name>"));
return FALSE;
}
printf ("GA"); printf ("GA");
name += 2; name += 2;
left -= 2; left -= 2;

View file

@ -5,7 +5,5 @@
#as: -n32 -mips3 #as: -n32 -mips3
#source: ../note-2-32.s #source: ../note-2-32.s
Relocation section '\.rela\.gnu\.build\.attributes' at offset .* contains 2 entries: There are no relocations in this file.
Offset Info Type Sym\.Value Sym\. Name \+ Addend #...
00000010 ......02 R_MIPS_32 00000100 note1\.s \+ 0
0000006c ......02 R_MIPS_32 00000104 note2\.s \+ 0

View file

@ -5,11 +5,5 @@
#as: -64 -mips3 #as: -64 -mips3
#source: ../note-2-64.s #source: ../note-2-64.s
Relocation section '\.rela\.gnu\.build\.attributes' at offset .* contains 2 entries: There are no relocations in this file.
Offset Info Type Sym\. Value Sym\. Name \+ Addend #...
000000000010 ....00000012 R_MIPS_64 0000000000000100 note1\.s \+ 0
Type2: R_MIPS_NONE
Type3: R_MIPS_NONE
000000000070 ....00000012 R_MIPS_64 0000000000000104 note2\.s \+ 0
Type2: R_MIPS_NONE
Type3: R_MIPS_NONE

View file

@ -5,7 +5,5 @@
#as: -32 #as: -32
#source: ../note-2-32.s #source: ../note-2-32.s
Relocation section '\.rel\.gnu\.build\.attributes' at offset .* contains 2 entries: There are no relocations in this file.
Offset Info Type Sym\.Value Sym\. Name #...
00000010 ......02 R_MIPS_32 00000100 note1\.s
0000006c ......02 R_MIPS_32 00000104 note2\.s

View file

@ -6,12 +6,12 @@
#... #...
Owner Data size Description Owner Data size Description
[ ]+\$<version>1[ ]+0x00000004[ ]+NT_GNU_BUILD_ATTRIBUTE_OPEN[ ]+Applies from offset 0x100 \(file: note1.s\) [ ]+\$<version>1[ ]+0x00000004[ ]+OPEN[ ]+Applies to region from 0x100 \(note1.s\)
[ ]+\$<tool>gcc 7.0.1[ ]+0x00000000[ ]+NT_GNU_BUILD_ATTRIBUTE_OPEN[ ]+Applies from offset 0x100 [ ]+\$<tool>gcc 7.0.1[ ]+0x00000000[ ]+OPEN[ ]+Applies to region from 0x100
[ ]+\+<stack prot>true[ ]+0x00000000[ ]+NT_GNU_BUILD_ATTRIBUTE_OPEN[ ]+Applies from offset 0x100 [ ]+\+<stack prot>true[ ]+0x00000000[ ]+OPEN[ ]+Applies to region from 0x100
[ ]+\*<PIC>static[ ]+0x00000000[ ]+NT_GNU_BUILD_ATTRIBUTE_OPEN[ ]+Applies from offset 0x100 [ ]+\*<PIC>static[ ]+0x00000000[ ]+OPEN[ ]+Applies to region from 0x100
[ ]+\*<ABI>0x0[ ]+0x00000000[ ]+NT_GNU_BUILD_ATTRIBUTE_OPEN[ ]+Applies from offset 0x100 [ ]+\*<ABI>0x0[ ]+0x00000000[ ]+OPEN[ ]+Applies to region from 0x100
[ ]+\$<version>1[ ]+0x00000004[ ]+NT_GNU_BUILD_ATTRIBUTE_OPEN[ ]+Applies from offset 0x10. \(file: note2.s\) [ ]+\$<version>1[ ]+0x00000004[ ]+OPEN[ ]+Applies to region from 0x104 \(note2.s\)
[ ]+!<stack prot>false[ ]+0x00000000[ ]+NT_GNU_BUILD_ATTRIBUTE_OPEN[ ]+Applies from offset 0x10. [ ]+!<stack prot>false[ ]+0x00000000[ ]+OPEN[ ]+Applies to region from 0x104
[ ]+\*<PIC>pic[ ]+0x00000000[ ]+NT_GNU_BUILD_ATTRIBUTE_FUNC[ ]+Applies to func at 0x10. \(func: func1\) [ ]+\*<PIC>pic[ ]+0x00000004[ ]+func[ ]+Applies to region from 0x104 \(func1\)
#... #...

View file

@ -2,7 +2,7 @@
.org 0x100 .org 0x100
.global note1.s .global note1.s
note1.s: note1.s:
.word 0 .dc.l 0
.pushsection .gnu.build.attributes, "0x100000", %note .pushsection .gnu.build.attributes, "0x100000", %note
.balign 4 .balign 4
@ -10,7 +10,7 @@ note1.s:
.dc.l 4 .dc.l 4
.dc.l 0x100 .dc.l 0x100
.asciz "$1" .asciz "$1"
.dc.l note1.s .dc.l 0x100
.dc.l 12 .dc.l 12
.dc.l 0 .dc.l 0
@ -39,14 +39,14 @@ note1.s:
note2.s: note2.s:
.type func1, STT_FUNC .type func1, STT_FUNC
func1: func1:
.word 0x100 .dc.l 0x100
.pushsection .gnu.build.attributes, "0x100000", %note .pushsection .gnu.build.attributes, "0x100000", %note
.dc.l 4 .dc.l 4
.dc.l 4 .dc.l 4
.dc.l 0x100 .dc.l 0x100
.asciz "$1" .asciz "$1"
.dc.l note2.s .dc.l 0x104
.dc.l 12 .dc.l 12
.dc.l 0 .dc.l 0
@ -60,26 +60,28 @@ func1:
.dc.b 0 .dc.b 0
.dc.l 4 .dc.l 4
.dc.l 0 .dc.l 4
.dc.l 0x101 .dc.l 0x101
.dc.b 0x2a, 0x7, 1, 0 .dc.b 0x2a, 0x7, 1, 0
.dc.l 0x104
.dc.l 4 .dc.l 4
.dc.l 0 .dc.l 0
.dc.l 0x100 .dc.l 0x100
.dc.b 0x2a, 0x6, 0, 0 .dc.b 0x2a, 0x6, 0, 0
.popsection .popsection
.global note3.s .global note3.s
note3.s: note3.s:
.word 0x100 .dc.l 0x100
.pushsection .gnu.build.attributes, "0x100000", %note .pushsection .gnu.build.attributes, "0x100000", %note
.dc.l 4 .dc.l 4
.dc.l 4 .dc.l 4
.dc.l 0x100 .dc.l 0x100
.asciz "$1" .asciz "$1"
.dc.l note3.s .dc.l 0x108
.dc.l 12 .dc.l 12
.dc.l 0 .dc.l 0

View file

@ -10,12 +10,12 @@
#... #...
Owner Data size Description Owner Data size Description
[ ]+\$<version>1[ ]+0x00000008[ ]+NT_GNU_BUILD_ATTRIBUTE_OPEN[ ]+Applies from offset 0x100 \(file: note1.s\) [ ]+\$<version>1[ ]+0x00000008[ ]+OPEN[ ]+Applies to region from 0x100 \(note1.s\)
[ ]+\$<tool>gcc 7.0.1[ ]+0x00000000[ ]+NT_GNU_BUILD_ATTRIBUTE_OPEN[ ]+Applies from offset 0x100 [ ]+\$<tool>gcc 7.0.1[ ]+0x00000000[ ]+OPEN[ ]+Applies to region from 0x100
[ ]+\+<stack prot>true[ ]+0x00000000[ ]+NT_GNU_BUILD_ATTRIBUTE_OPEN[ ]+Applies from offset 0x100 [ ]+\+<stack prot>true[ ]+0x00000000[ ]+OPEN[ ]+Applies to region from 0x100
[ ]+\*<PIC>static[ ]+0x00000000[ ]+NT_GNU_BUILD_ATTRIBUTE_OPEN[ ]+Applies from offset 0x100 [ ]+\*<PIC>static[ ]+0x00000000[ ]+OPEN[ ]+Applies to region from 0x100
[ ]+\*<ABI>0x0[ ]+0x00000000[ ]+NT_GNU_BUILD_ATTRIBUTE_OPEN[ ]+Applies from offset 0x100 [ ]+\*<ABI>0x0[ ]+0x00000000[ ]+OPEN[ ]+Applies to region from 0x100
[ ]+\$<version>1[ ]+0x00000008[ ]+NT_GNU_BUILD_ATTRIBUTE_OPEN[ ]+Applies from offset 0x10. \(file: note2.s\) [ ]+\$<version>1[ ]+0x00000008[ ]+OPEN[ ]+Applies to region from 0x104 \(note2.s\)
[ ]+!<stack prot>false[ ]+0x00000000[ ]+NT_GNU_BUILD_ATTRIBUTE_OPEN[ ]+Applies from offset 0x10. [ ]+!<stack prot>false[ ]+0x00000000[ ]+OPEN[ ]+Applies to region from 0x104
[ ]+\*<PIC>pic[ ]+0x00000000[ ]+NT_GNU_BUILD_ATTRIBUTE_FUNC[ ]+Applies to func at 0x10. \(func: func1\) [ ]+\*<PIC>pic[ ]+0x00000008[ ]+func[ ]+Applies to region from 0x104 \(func1\)
#... #...

View file

@ -2,7 +2,7 @@
.org 0x100 .org 0x100
.global note1.s .global note1.s
note1.s: note1.s:
.word 0 .dc.l 0
.pushsection .gnu.build.attributes, "0x100000", %note .pushsection .gnu.build.attributes, "0x100000", %note
.balign 4 .balign 4
@ -10,7 +10,7 @@ note1.s:
.dc.l 8 .dc.l 8
.dc.l 0x100 .dc.l 0x100
.asciz "$1" .asciz "$1"
.8byte note1.s .8byte 0x100
.dc.l 12 .dc.l 12
.dc.l 0 .dc.l 0
@ -40,14 +40,14 @@ note2.s:
.global func1 .global func1
.type func1, STT_FUNC .type func1, STT_FUNC
func1: func1:
.word 0x100 .dc.l 0x100
.pushsection .gnu.build.attributes, "0x100000", %note .pushsection .gnu.build.attributes, "0x100000", %note
.dc.l 4 .dc.l 4
.dc.l 8 .dc.l 8
.dc.l 0x100 .dc.l 0x100
.asciz "$1" .asciz "$1"
.8byte note2.s .8byte 0x104
.dc.l 12 .dc.l 12
.dc.l 0 .dc.l 0
@ -61,9 +61,10 @@ func1:
.dc.b 0 .dc.b 0
.dc.l 4 .dc.l 4
.dc.l 0 .dc.l 8
.dc.l 0x101 .dc.l 0x101
.dc.b 0x2a, 0x7, 1, 0 .dc.b 0x2a, 0x7, 1, 0
.8byte 0x104
.dc.l 4 .dc.l 4
.dc.l 0 .dc.l 0
@ -74,14 +75,14 @@ func1:
.global note3.s .global note3.s
note3.s: note3.s:
.word 0x100 .dc.l 0x100
.pushsection .gnu.build.attributes, "0x100000", %note .pushsection .gnu.build.attributes, "0x100000", %note
.dc.l 4 .dc.l 4
.dc.l 8 .dc.l 8
.dc.l 0x100 .dc.l 0x100
.asciz "$1" .asciz "$1"
.8byte note3.s .8byte 0x108
.dc.l 12 .dc.l 12
.dc.l 0 .dc.l 0

View file

@ -7,12 +7,12 @@
#... #...
Displaying notes found in: .gnu.build.attributes Displaying notes found in: .gnu.build.attributes
[ ]+Owner[ ]+Data size[ ]+Description [ ]+Owner[ ]+Data size[ ]+Description
[ ]+GA\$<version>2p1[ ]+0x0000000.[ ]+NT_GNU_BUILD_ATTRIBUTE_OPEN[ ]+Applies from offset 0x100 \(file: note_1.s\) [ ]+GA\$<version>2p1[ ]+0x0000000.[ ]+OPEN[ ]+Applies to region from 0x100 to 0x122 \(note_1.s\)
[ ]+GA\$<tool>gcc 6.3.1 20161221[ ]+0x00000000[ ]+NT_GNU_BUILD_ATTRIBUTE_OPEN[ ]+Applies from offset 0x100 [ ]+GA\$<tool>gcc 6.3.1 20161221[ ]+0x00000000[ ]+OPEN[ ]+Applies to region from 0x100 to 0x122
[ ]+GA\*GOW:0x700[ ]+0x00000000[ ]+NT_GNU_BUILD_ATTRIBUTE_OPEN[ ]+Applies from offset 0x100 [ ]+GA\*GOW:0x700[ ]+0x00000000[ ]+OPEN[ ]+Applies to region from 0x100 to 0x122
[ ]+GA\*<stack prot>off[ ]+0x00000000[ ]+NT_GNU_BUILD_ATTRIBUTE_OPEN[ ]+Applies from offset 0x100 [ ]+GA\*<stack prot>off[ ]+0x00000000[ ]+OPEN[ ]+Applies to region from 0x100 to 0x122
[ ]+GA\*FORTIFY:0xff[ ]+0x00000000[ ]+NT_GNU_BUILD_ATTRIBUTE_OPEN[ ]+Applies from offset 0x100 [ ]+GA\*FORTIFY:0xff[ ]+0x00000000[ ]+OPEN[ ]+Applies to region from 0x100 to 0x122
[ ]+GA\*<PIC>PIC[ ]+0x00000000[ ]+NT_GNU_BUILD_ATTRIBUTE_OPEN[ ]+Applies from offset 0x100 [ ]+GA\*<PIC>PIC[ ]+0x00000000[ ]+OPEN[ ]+Applies to region from 0x100 to 0x122
[ ]+GA\!<short enum>false[ ]+0x00000000[ ]+NT_GNU_BUILD_ATTRIBUTE_OPEN[ ]+Applies from offset 0x100 [ ]+GA\!<short enum>false[ ]+0x00000000[ ]+OPEN[ ]+Applies to region from 0x100 to 0x122
[ ]+GA\*<ABI>0x[0-9a-f]+[ ]+0x00000000[ ]+NT_GNU_BUILD_ATTRIBUTE_OPEN[ ]+Applies from offset 0x100 [ ]+GA\*<ABI>0x[0-9a-f]+[ ]+0x00000000[ ]+OPEN[ ]+Applies to region from 0x100 to 0x122
#... #...

View file

@ -1,6 +1,7 @@
.text .text
.org 0x100 .org 0x100
.global note_1.s .global note_1.s
.size note_1.s, 0x22
note_1.s: note_1.s:
.word 0 .word 0

View file

@ -7,12 +7,12 @@
#... #...
Displaying notes found in: .gnu.build.attributes Displaying notes found in: .gnu.build.attributes
[ ]+Owner[ ]+Data size[ ]+Description [ ]+Owner[ ]+Data size[ ]+Description
[ ]+GA\$<version>2p1[ ]+0x0000000.[ ]+NT_GNU_BUILD_ATTRIBUTE_OPEN[ ]+Applies from offset 0x100 \(file: note_1.s\) [ ]+GA\$<version>2p1[ ]+0x0000000.[ ]+OPEN[ ]+Applies to region from 0x100 to 0x122 \(note_1.s\)
[ ]+GA\$<tool>gcc 6.3.1 20161221[ ]+0x00000000[ ]+NT_GNU_BUILD_ATTRIBUTE_OPEN[ ]+Applies from offset 0x100 [ ]+GA\$<tool>gcc 6.3.1 20161221[ ]+0x00000000[ ]+OPEN[ ]+Applies to region from 0x100 to 0x122
[ ]+GA\*GOW:0x700[ ]+0x00000000[ ]+NT_GNU_BUILD_ATTRIBUTE_OPEN[ ]+Applies from offset 0x100 [ ]+GA\*GOW:0x700[ ]+0x00000000[ ]+OPEN[ ]+Applies to region from 0x100 to 0x122
[ ]+GA\*<stack prot>off[ ]+0x00000000[ ]+NT_GNU_BUILD_ATTRIBUTE_OPEN[ ]+Applies from offset 0x100 [ ]+GA\*<stack prot>off[ ]+0x00000000[ ]+OPEN[ ]+Applies to region from 0x100 to 0x122
[ ]+GA\*FORTIFY:0xff[ ]+0x00000000[ ]+NT_GNU_BUILD_ATTRIBUTE_OPEN[ ]+Applies from offset 0x100 [ ]+GA\*FORTIFY:0xff[ ]+0x00000000[ ]+OPEN[ ]+Applies to region from 0x100 to 0x122
[ ]+GA\*<PIC>PIC[ ]+0x00000000[ ]+NT_GNU_BUILD_ATTRIBUTE_OPEN[ ]+Applies from offset 0x100 [ ]+GA\*<PIC>PIC[ ]+0x00000000[ ]+OPEN[ ]+Applies to region from 0x100 to 0x122
[ ]+GA\!<short enum>false[ ]+0x00000000[ ]+NT_GNU_BUILD_ATTRIBUTE_OPEN[ ]+Applies from offset 0x100 [ ]+GA\!<short enum>false[ ]+0x00000000[ ]+OPEN[ ]+Applies to region from 0x100 to 0x122
[ ]+GA\*<ABI>0x[0-9a-f]+[ ]+0x00000000[ ]+NT_GNU_BUILD_ATTRIBUTE_OPEN[ ]+Applies from offset 0x100 [ ]+GA\*<ABI>0x[0-9a-f]+[ ]+0x00000000[ ]+OPEN[ ]+Applies to region from 0x100 to 0x122
#... #...

View file

@ -1,6 +1,7 @@
.text .text
.org 0x100 .org 0x100
.global note_1.s .global note_1.s
.size note_1.s, 0x22
note_1.s: note_1.s:
.word 0 .word 0

View file

@ -0,0 +1,19 @@
#PROG: objcopy
#readelf: --notes --wide
#objcopy: --merge-notes
#name: v3 gnu build attribute notes (32-bit)
#source: note-4-32.s
#...
Displaying notes found in: .gnu.build.attributes
[ ]+Owner[ ]+Data size[ ]+Description
[ ]+GA\$<version>3p3[ ]+0x00000008[ ]+OPEN[ ]+Applies to region from 0x100 to 0x110 \(note_4.s\)
[ ]+GA\$<tool>gcc 7.2.1 20170915[ ]+0x00000000[ ]+OPEN[ ]+Applies to region from 0x100 to 0x110
[ ]+GA\*GOW:0x700[ ]+0x00000000[ ]+OPEN[ ]+Applies to region from 0x100 to 0x110
[ ]+GA\*<stack prot>off[ ]+0x00000000[ ]+OPEN[ ]+Applies to region from 0x100 to 0x110
[ ]+GA\*FORTIFY:0xff[ ]+0x00000000[ ]+OPEN[ ]+Applies to region from 0x100 to 0x110
[ ]+GA\*<PIC>PIC[ ]+0x00000000[ ]+OPEN[ ]+Applies to region from 0x100 to 0x110
[ ]+GA\!<short enum>false[ ]+0x00000000[ ]+OPEN[ ]+Applies to region from 0x100 to 0x110
[ ]+GA\*<ABI>0x[0-9a-f]+[ ]+0x00000000[ ]+OPEN[ ]+Applies to region from 0x100 to 0x110
[ ]+GA\*<stack prot>strong[ ]+0x00000008[ ]+func[ ]+Applies to region from 0x108 to 0x10c.*
#...

View file

@ -0,0 +1,74 @@
.text
.org 0x100
note_4.s:
.dc.l 0
.dc.l 0
.type bar, STT_FUNC
bar:
.dc.l 0
bar_end:
.dc.l 0
note_4.s_end:
.pushsection .gnu.build.attributes, "", %note
.balign 4
.dc.l 8
.dc.l 8
.dc.l 0x100
.asciz "GA$3p3"
.dc.l note_4.s
.dc.l note_4.s_end
.dc.l 23
.dc.l 0
.dc.l 0x100
.asciz "GA$gcc 7.2.1 20170915"
.dc.b 0
.dc.l 10
.dc.l 0
.dc.l 0x100
.dc.b 0x47, 0x41, 0x2a, 0x47, 0x4f, 0x57, 0, 0, 0x7, 0
.dc.b 0, 0
.dc.l 6
.dc.l 0
.dc.l 0x100
.dc.b 0x47, 0x41, 0x2a, 0x2, 0, 0
.dc.b 0, 0
.dc.l 13
.dc.l 0
.dc.l 0x100
.dc.b 0x47, 0x41, 0x2a, 0x46, 0x4f, 0x52, 0x54, 0x49, 0x46, 0x59, 0, 0xff, 0
.dc.b 0, 0, 0
.dc.l 6
.dc.l 0
.dc.l 0x100
.dc.b 0x47, 0x41, 0x2a, 0x7, 0x2, 0
.dc.b 0, 0
.dc.l 5
.dc.l 0
.dc.l 0x100
.dc.b 0x47, 0x41, 0x21, 0x8, 0
.dc.b 0, 0, 0
.dc.l 13
.dc.l 0
.dc.l 0x100
.dc.b 0x47, 0x41, 0x2a, 0x6, 0xf2, 0x3, 0x38, 0xee, 0xce, 0xfa, 0x5e, 0x3c, 0
.dc.b 0, 0, 0
.dc.l 6
.dc.l 8
.dc.l 0x101
.dc.b 0x47, 0x41, 0x2a, 0x2, 0x3, 0
.dc.b 0, 0
.dc.l bar
.dc.l bar_end
.popsection

View file

@ -0,0 +1,19 @@
#PROG: objcopy
#readelf: --notes --wide
#objcopy: --merge-notes
#name: v3 gnu build attribute notes (64-bit)
#source: note-4-64.s
#...
Displaying notes found in: .gnu.build.attributes
[ ]+Owner[ ]+Data size[ ]+Description
[ ]+GA\$<version>3p3[ ]+0x00000010[ ]+OPEN[ ]+Applies to region from 0x100 to 0x120 \(note_4.s\)
[ ]+GA\$<tool>gcc 7.2.1 20170915[ ]+0x00000000[ ]+OPEN[ ]+Applies to region from 0x100 to 0x120
[ ]+GA\*GOW:0x700[ ]+0x00000000[ ]+OPEN[ ]+Applies to region from 0x100 to 0x120
[ ]+GA\*<stack prot>off[ ]+0x00000000[ ]+OPEN[ ]+Applies to region from 0x100 to 0x120
[ ]+GA\*FORTIFY:0xff[ ]+0x00000000[ ]+OPEN[ ]+Applies to region from 0x100 to 0x120
[ ]+GA\*<PIC>PIC[ ]+0x00000000[ ]+OPEN[ ]+Applies to region from 0x100 to 0x120
[ ]+GA\!<short enum>false[ ]+0x00000000[ ]+OPEN[ ]+Applies to region from 0x100 to 0x120
[ ]+GA\*<ABI>0x[0-9a-f]+[ ]+0x00000000[ ]+OPEN[ ]+Applies to region from 0x100 to 0x120
[ ]+GA\*<stack prot>strong[ ]+0x00000010[ ]+func[ ]+Applies to region from 0x110 to 0x11c.*
#...

View file

@ -0,0 +1,78 @@
.text
.org 0x100
note_4.s:
.dc.l 0
.dc.l 0
.dc.l 0
.dc.l 0
.type bar, @function
bar:
.dc.l 0
.dc.l 0
.dc.l 0
bar_end:
.dc.l 0
note_4.s_end:
.pushsection .gnu.build.attributes, "", %note
.balign 4
.dc.l 8
.dc.l 16
.dc.l 0x100
.asciz "GA$3p3"
.8byte note_4.s
.8byte note_4.s_end
.dc.l 23
.dc.l 0
.dc.l 0x100
.asciz "GA$gcc 7.2.1 20170915"
.dc.b 0
.dc.l 10
.dc.l 0
.dc.l 0x100
.dc.b 0x47, 0x41, 0x2a, 0x47, 0x4f, 0x57, 0, 0, 0x7, 0
.dc.b 0, 0
.dc.l 6
.dc.l 0
.dc.l 0x100
.dc.b 0x47, 0x41, 0x2a, 0x2, 0, 0
.dc.b 0, 0
.dc.l 13
.dc.l 0
.dc.l 0x100
.dc.b 0x47, 0x41, 0x2a, 0x46, 0x4f, 0x52, 0x54, 0x49, 0x46, 0x59, 0, 0xff, 0
.dc.b 0, 0, 0
.dc.l 6
.dc.l 0
.dc.l 0x100
.dc.b 0x47, 0x41, 0x2a, 0x7, 0x2, 0
.dc.b 0, 0
.dc.l 5
.dc.l 0
.dc.l 0x100
.dc.b 0x47, 0x41, 0x21, 0x8, 0
.dc.b 0, 0, 0
.dc.l 13
.dc.l 0
.dc.l 0x100
.dc.b 0x47, 0x41, 0x2a, 0x6, 0xf2, 0x3, 0x38, 0xee, 0xce, 0xfa, 0x5e, 0x3c, 0
.dc.b 0, 0, 0
.dc.l 6
.dc.l 16
.dc.l 0x101
.dc.b 0x47, 0x41, 0x2a, 0x2, 0x3, 0
.dc.b 0, 0
.8byte bar
.8byte bar_end
.popsection

View file

@ -1056,9 +1056,11 @@ if [is_elf_format] {
if [is_elf64 tmpdir/bintest.o] { if [is_elf64 tmpdir/bintest.o] {
run_dump_test "note-2-64" run_dump_test "note-2-64"
run_dump_test "note-3-64" run_dump_test "note-3-64"
run_dump_test "note-4-64"
} else { } else {
run_dump_test "note-2-32" run_dump_test "note-2-32"
run_dump_test "note-3-32" run_dump_test "note-3-32"
run_dump_test "note-4-32"
} }
} }