binutils/SOURCES/binutils-improved-note-merging.patch
2021-09-09 15:04:02 +00:00

2076 lines
66 KiB
Diff
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

diff -rupN binutils.orig/binutils/objcopy.c binutils-2.30/binutils/objcopy.c
--- binutils.orig/binutils/objcopy.c 2019-10-28 17:08:43.352324932 +0000
+++ binutils-2.30/binutils/objcopy.c 2019-10-28 17:20:26.378052081 +0000
@@ -97,8 +97,14 @@ static int deterministic = -1; /* Enabl
static int status = 0; /* Exit status. */
static bfd_boolean merge_notes = FALSE; /* Merge note sections. */
-static bfd_byte * merged_notes = NULL; /* Contents on note section undergoing a merge. */
-static bfd_size_type merged_size = 0; /* New, smaller size of the merged note section. */
+
+typedef struct merged_note_section
+{
+ asection * sec; /* The section that is being merged. */
+ bfd_byte * contents;/* New contents of the section. */
+ bfd_size_type size; /* New size of the section. */
+ struct merged_note_section * next; /* Link to next merged note section. */
+} merged_note_section;
enum strip_action
{
@@ -1259,7 +1265,7 @@ is_update_section (bfd *abfd ATTRIBUTE_U
}
static bfd_boolean
-is_merged_note_section (bfd * abfd, asection * sec)
+is_mergeable_note_section (bfd * abfd, asection * sec)
{
if (merge_notes
&& bfd_get_flavour (abfd) == bfd_target_elf_flavour
@@ -1268,9 +1274,9 @@ is_merged_note_section (bfd * abfd, asec
We should add support for more note types. */
&& ((elf_section_data (sec)->this_hdr.sh_flags & SHF_GNU_BUILD_NOTE) != 0
/* Old versions of GAS (prior to 2.27) could not set the section
- flags to OS-specific values, so we also accept sections with the
- expected name. */
- || (strcmp (sec->name, GNU_BUILD_ATTRS_SECTION_NAME) == 0)))
+ flags to OS-specific values, so we also accept sections that
+ start with the expected name. */
+ || (CONST_STRNEQ (sec->name, GNU_BUILD_ATTRS_SECTION_NAME))))
return TRUE;
return FALSE;
@@ -1893,56 +1899,81 @@ copy_unknown_object (bfd *ibfd, bfd *obf
return TRUE;
}
-/* Returns the number of bytes needed to store VAL. */
-
-static inline unsigned int
-num_bytes (unsigned long val)
-{
- unsigned int count = 0;
-
- /* FIXME: There must be a faster way to do this. */
- while (val)
- {
- count ++;
- val >>= 8;
- }
- return count;
-}
-
typedef struct objcopy_internal_note
{
Elf_Internal_Note note;
+ unsigned long padded_namesz;
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. */
+#define DEBUG_MERGE 0
+
+#if DEBUG_MERGE
+#define merge_debug(format, ...) fprintf (stderr, format, ## __VA_ARGS__)
+#else
+#define merge_debug(format, ...)
+#endif
+
+/* Returns TRUE iff PNOTE1 overlaps or adjoins PNOTE2. */
static bfd_boolean
-gap_exists (objcopy_internal_note * pnote1,
- objcopy_internal_note * pnote2)
+overlaps_or_adjoins (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)
+ if (pnote1->end < pnote2->start)
+ /* 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;
+
+ if (pnote2->end < pnote2->start)
+ return BFD_ALIGN (pnote2->end, 16) < pnote1->start;
+
+ if (pnote1->end < pnote2->end)
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;
+ if (pnote2->end < pnote1->end)
+ return TRUE;
+
+ return FALSE;
+}
+
+/* Returns TRUE iff NEEDLE is fully contained by HAYSTACK. */
+
+static bfd_boolean
+contained_by (objcopy_internal_note * needle,
+ objcopy_internal_note * haystack)
+{
+ return needle->start >= haystack->start && needle->end <= haystack->end;
}
static bfd_boolean
is_open_note (objcopy_internal_note * pnote)
{
- return (pnote->note.type == NT_GNU_BUILD_ATTRIBUTE_OPEN);
+ 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);
+ return pnote->note.type == NT_GNU_BUILD_ATTRIBUTE_FUNC;
+}
+
+static bfd_boolean
+is_deleted_note (objcopy_internal_note * pnote)
+{
+ return pnote->note.type == 0;
+}
+
+static bfd_boolean
+is_version_note (objcopy_internal_note * pnote)
+{
+ return (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);
}
static bfd_boolean
@@ -1955,11 +1986,97 @@ is_64bit (bfd * abfd)
return elf_elfheader (abfd)->e_ident[EI_CLASS] == ELFCLASS64;
}
+/* This sorting function is used to get the notes into an order
+ that makes merging easy. */
+
+static int
+compare_gnu_build_notes (const void * data1, const void * data2)
+{
+ objcopy_internal_note * pnote1 = (objcopy_internal_note *) data1;
+ objcopy_internal_note * pnote2 = (objcopy_internal_note *) data2;
+
+ /* Sort notes based upon the attribute they record. */
+ int cmp = memcmp (pnote1->note.namedata + 3,
+ pnote2->note.namedata + 3,
+ pnote1->note.namesz < pnote2->note.namesz ?
+ pnote1->note.namesz - 3 : pnote2->note.namesz - 3);
+ if (cmp)
+ return cmp;
+
+ if (pnote1->end < pnote2->start)
+ return -1;
+ if (pnote1->start > pnote2->end)
+ return 1;
+
+ /* Overlaps - we should merge the two ranges. */
+ if (pnote1->start < pnote2->start)
+ return -1;
+ if (pnote1->end > pnote2->end)
+ return 1;
+
+ /* Put OPEN notes before function notes. */
+ if (is_open_note (pnote1) && ! is_open_note (pnote2))
+ return -1;
+ if (! is_open_note (pnote1) && is_open_note (pnote2))
+ return 1;
+
+ return 0;
+}
+
+/* This sorting function is used to get the notes into an order
+ that makes eliminating address ranges easier. */
+
+static int
+sort_gnu_build_notes (const void * data1, const void * data2)
+{
+ objcopy_internal_note * pnote1 = (objcopy_internal_note *) data1;
+ objcopy_internal_note * pnote2 = (objcopy_internal_note *) data2;
+
+ if (pnote1->note.type != pnote2->note.type)
+ {
+ /* Move deleted notes to the end. */
+ if (is_deleted_note (pnote1)) /* 1: OFD 2: OFD */
+ return 1;
+
+ /* Move OPEN notes to the start. */
+ if (is_open_note (pnote1)) /* 1: OF 2: OFD */
+ return -1;
+
+ if (is_deleted_note (pnote2)) /* 1: F 2: O D */
+ return 1;
+
+ return 1; /* 1: F 2: O */
+ }
+
+ /* Sort by starting address. */
+ if (pnote1->start < pnote2->start)
+ return -1;
+ if (pnote1->start > pnote2->start)
+ return 1;
+
+ /* Then by end address (bigger range first). */
+ if (pnote1->end > pnote2->end)
+ return -1;
+ if (pnote1->end < pnote2->end)
+ return 1;
+
+ /* Then by attribute type. */
+ if (pnote1->note.namesz > 4
+ && pnote2->note.namesz > 4
+ && pnote1->note.namedata[3] != pnote2->note.namedata[3])
+ return pnote1->note.namedata[3] - pnote2->note.namedata[3];
+
+ return 0;
+}
+
/* Merge the notes on SEC, removing redundant entries.
Returns the new, smaller size of the section upon success. */
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)
{
objcopy_internal_note * pnotes_end;
objcopy_internal_note * pnotes = NULL;
@@ -1968,18 +2085,14 @@ merge_gnu_build_notes (bfd * abfd, asect
unsigned version_1_seen = 0;
unsigned version_2_seen = 0;
unsigned version_3_seen = 0;
- bfd_boolean duplicate_found = FALSE;
const char * err = NULL;
bfd_byte * in = contents;
- int attribute_type_byte;
- 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;
-
relsize = bfd_get_reloc_upper_bound (abfd, sec);
if (relsize > 0)
{
@@ -1992,19 +2105,33 @@ merge_gnu_build_notes (bfd * abfd, asect
relcount = bfd_canonicalize_reloc (abfd, sec, relpp, isympp);
free (relpp);
if (relcount != 0)
- goto done;
+ {
+ if (! is_strip)
+ non_fatal (_("%s[%s]: Cannot merge - there are relocations against this section"),
+ bfd_get_filename (abfd), bfd_section_name (abfd, sec));
+ goto done;
+ }
}
/* Make a copy of the notes and convert to our internal format.
- Minimum size of a note is 12 bytes. */
- pnote = pnotes = (objcopy_internal_note *) xcalloc ((size / 12), sizeof (* pnote));
+ Minimum size of a note is 12 bytes. Also locate the version
+ notes and check them. */
+ pnote = pnotes = (objcopy_internal_note *)
+ xcalloc ((size / 12), sizeof (* pnote));
while (remain >= 12)
{
bfd_vma start, end;
- pnote->note.namesz = (bfd_get_32 (abfd, in ) + 3) & ~3;
- pnote->note.descsz = (bfd_get_32 (abfd, in + 4) + 3) & ~3;
- pnote->note.type = bfd_get_32 (abfd, in + 8);
+ pnote->note.namesz = bfd_get_32 (abfd, in);
+ pnote->note.descsz = bfd_get_32 (abfd, in + 4);
+ pnote->note.type = bfd_get_32 (abfd, in + 8);
+ pnote->padded_namesz = (pnote->note.namesz + 3) & ~3;
+
+ if (((pnote->note.descsz + 3) & ~3) != pnote->note.descsz)
+ {
+ err = _("corrupt GNU build attribute note: description size not a factor of 4");
+ goto done;
+ }
if (pnote->note.type != NT_GNU_BUILD_ATTRIBUTE_OPEN
&& pnote->note.type != NT_GNU_BUILD_ATTRIBUTE_FUNC)
@@ -2013,7 +2140,7 @@ merge_gnu_build_notes (bfd * abfd, asect
goto done;
}
- if (pnote->note.namesz + pnote->note.descsz + 12 > remain)
+ if (pnote->padded_namesz + pnote->note.descsz + 12 > remain)
{
err = _("corrupt GNU build attribute note: note too big");
goto done;
@@ -2026,21 +2153,17 @@ merge_gnu_build_notes (bfd * abfd, asect
}
pnote->note.namedata = (char *)(in + 12);
- pnote->note.descdata = (char *)(in + 12 + pnote->note.namesz);
+ pnote->note.descdata = (char *)(in + 12 + pnote->padded_namesz);
- remain -= 12 + pnote->note.namesz + pnote->note.descsz;
- in += 12 + pnote->note.namesz + pnote->note.descsz;
+ remain -= 12 + pnote->padded_namesz + pnote->note.descsz;
+ in += 12 + pnote->padded_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)
+ else if (is_version_note (pnote))
{
if (pnote->note.namedata[4] == '2')
++ version_2_seen;
@@ -2146,11 +2269,18 @@ merge_gnu_build_notes (bfd * abfd, asect
if (version_1_seen == 0 && version_2_seen == 0 && version_3_seen == 0)
{
+#if 0
err = _("bad GNU build attribute notes: no known versions detected");
goto done;
+#else
+ /* This happens with glibc. No idea why. */
+ non_fatal (_("%s[%s]: Warning: version note missing - assuming version 3"),
+ bfd_get_filename (abfd), bfd_section_name (abfd, sec));
+ version_3_seen = 2;
+#endif
}
- 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))
{
@@ -2158,271 +2288,215 @@ merge_gnu_build_notes (bfd * abfd, asect
goto done;
}
- /* Merging is only needed if there is more than one version note... */
- if (version_1_seen == 1 || version_2_seen == 1 || version_3_seen == 1)
- goto done;
-
- attribute_type_byte = version_1_seen ? 1 : 3;
- val_start = attribute_type_byte + 1;
-
- /* The first note should be the first version note. */
- if (pnotes[0].note.namedata[attribute_type_byte] != GNU_BUILD_ATTRIBUTE_VERSION)
+ /* We are now only supporting the merging v3+ notes
+ - it makes things much simpler. */
+ if (version_3_seen == 0)
{
- err = _("bad GNU build attribute notes: first note not version note");
+ merge_debug ("%s: skipping merge - not using v3 notes", bfd_section_name (sec));
goto done;
}
+ merge_debug ("Merging section %s which contains %ld notes\n",
+ sec->name, pnotes_end - pnotes);
+
+ /* Sort the notes. */
+ qsort (pnotes, pnotes_end - pnotes, sizeof (* pnotes),
+ compare_gnu_build_notes);
+
+#if DEBUG_MERGE
+ merge_debug ("Results of initial sort:\n");
+ for (pnote = pnotes; pnote < pnotes_end; pnote ++)
+ merge_debug ("offset %#08lx range %#08lx..%#08lx type %ld attribute %d namesz %ld\n",
+ (pnote->note.namedata - (char *) contents) - 12,
+ pnote->start, pnote->end,
+ pnote->note.type,
+ pnote->note.namedata[3],
+ pnote->note.namesz
+ );
+#endif
+
/* Now merge the notes. The rules are:
- 1. Preserve the ordering of the notes.
- 2. Preserve any NT_GNU_BUILD_ATTRIBUTE_FUNC notes.
- 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
- of name and whose address ranges coincide.
- IE - if 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
- of type GNU_BUILD_ATTRIBUTE_STACK_SIZE.
- 5. If an NT_GNU_BUILD_ATTRIBUTE_OPEN note is going to be preserved and
- its description field is empty then the nearest preceeding OPEN note
- with a non-empty description field must also be preserved *OR* the
- description field of the note must be changed to contain the starting
- address to which it refers.
- 6. Notes with the same start and end address can be deleted. */
+ 1. If a note has a zero range, it can be eliminated.
+ 2. If two notes have the same namedata then:
+ 2a. If one note's range is fully covered by the other note
+ then it can be deleted.
+ 2b. If one note's range partially overlaps or adjoins the
+ other note then if they are both of the same type (open
+ or func) then they can be merged and one deleted. If
+ they are of different types then they cannot be merged. */
for (pnote = pnotes + 1; pnote < pnotes_end; pnote ++)
{
- int note_type;
- objcopy_internal_note * back;
- objcopy_internal_note * prev_open_with_range = NULL;
+ /* Skip already deleted notes.
+ FIXME: Can this happen ? We are scanning forwards and
+ deleting backwards after all. */
+ if (is_deleted_note (pnote))
+ continue;
- /* Rule 6 - delete 0-range notes. */
+ /* Rule 1 - delete 0-range notes. */
if (pnote->start == pnote->end)
{
- duplicate_found = TRUE;
+ merge_debug ("Delete note at offset %#08lx - empty range\n",
+ (pnote->note.namedata - (char *) contents) - 12);
pnote->note.type = 0;
continue;
}
- /* Rule 2 - preserve function notes. */
- if (! is_open_note (pnote))
- {
- int iter;
-
- /* Check to see if there is an identical previous function note.
- This can happen with overlays for example. */
- for (iter = 0, back = pnote -1; back >= pnotes; back --)
- {
- if (back->start == pnote->start
- && back->end == pnote->end
- && back->note.namesz == pnote->note.namesz
- && memcmp (back->note.namedata, pnote->note.namedata, pnote->note.namesz) == 0)
- {
- duplicate_found = TRUE;
- pnote->note.type = 0;
- break;
- }
-
- /* Don't scan too far back however. */
- if (iter ++ > 16)
- break;
- }
- continue;
- }
-
- note_type = pnote->note.namedata[attribute_type_byte];
-
- /* 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 --)
- {
- int back_type = back->note.namedata[attribute_type_byte];
-
- /* If this is the first open note with an address
- 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;
+ int iter;
+ objcopy_internal_note * back;
- /* If the two notes are different then keep on searching. */
- if (back_type != note_type)
+ /* Rule 2: Check to see if there is an identical previous note. */
+ for (iter = 0, back = pnote - 1; back >= pnotes; back --)
+ {
+ if (is_deleted_note (back))
continue;
- /* Rule 4 - combine stack size notes. */
- if (back_type == GNU_BUILD_ATTRIBUTE_STACK_SIZE)
+ /* Our sorting function should have placed all identically
+ attributed notes together, so if we see a note of a different
+ attribute type stop searching. */
+ if (back->note.namesz != pnote->note.namesz
+ || memcmp (back->note.namedata,
+ pnote->note.namedata, pnote->note.namesz) != 0)
+ break;
+
+ if (back->start == pnote->start
+ && back->end == pnote->end)
{
- 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--;)
- {
- byte = (* name ++) & 0xff;
- note_val |= byte << shift;
- shift += 8;
- }
-
- for (shift = 0, back_val = 0,
- bytes = back->note.namesz - val_start,
- name = (unsigned char *) back->note.namedata + val_start;
- bytes--;)
- {
- byte = (* name ++) & 0xff;
- back_val |= byte << shift;
- shift += 8;
- }
-
- 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;
+ merge_debug ("Delete note at offset %#08lx - duplicate of note at offset %#08lx\n",
+ (pnote->note.namedata - (char *) contents) - 12,
+ (back->note.namedata - (char *) contents) - 12);
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))
+ /* Rule 2a. */
+ if (contained_by (pnote, back))
{
- duplicate_found = TRUE;
+ merge_debug ("Delete note at offset %#08lx - fully contained by note at %#08lx\n",
+ (pnote->note.namedata - (char *) contents) - 12,
+ (back->note.namedata - (char *) contents) - 12);
pnote->note.type = 0;
+ break;
+ }
- if (pnote->end > back->end)
- back->end = pnote->end;
+#if DEBUG_MERGE
+ /* This should not happen as we have sorted the
+ notes with earlier starting addresses first. */
+ if (contained_by (back, pnote))
+ merge_debug ("ERROR: UNEXPECTED CONTAINMENT\n");
+#endif
+
+ /* Rule 2b. */
+ if (overlaps_or_adjoins (back, pnote)
+ && is_func_note (back) == is_func_note (pnote))
+ {
+ merge_debug ("Delete note at offset %#08lx - merge into note at %#08lx\n",
+ (pnote->note.namedata - (char *) contents) - 12,
+ (back->note.namedata - (char *) contents) - 12);
- if (version_3_seen)
- back->modified = TRUE;
+ back->end = back->end > pnote->end ? back->end : pnote->end;
+ back->start = back->start < pnote->start ? back->start : pnote->start;
+ pnote->note.type = 0;
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
+ /* Don't scan too far back however. */
+ if (iter ++ > 16)
{
- 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;
+ /* FIXME: Not sure if this can ever be triggered. */
+ merge_debug ("ITERATION LIMIT REACHED\n");
+ break;
}
-
- /* We have found a similar attribute but the details do not match.
- Stop searching backwards. */
- break;
}
- }
-
- if (duplicate_found)
- {
- bfd_byte * new_contents;
- bfd_byte * old;
- bfd_byte * new;
- bfd_size_type new_size;
- bfd_vma prev_start = 0;
- bfd_vma prev_end = 0;
-
- /* Eliminate the duplicates. */
- new = new_contents = xmalloc (size);
- for (pnote = pnotes, old = contents;
- pnote < pnotes_end;
- pnote ++)
- {
- bfd_size_type note_size = 12 + pnote->note.namesz + pnote->note.descsz;
-
- if (pnote->note.type != 0)
+#if DEBUG_MERGE
+ if (! is_deleted_note (pnote))
+ merge_debug ("Unable to do anything with note at %#08lx\n",
+ (pnote->note.namedata - (char *) contents) - 12);
+#endif
+ }
+
+ /* Resort the notes. */
+ merge_debug ("Final sorting of notes\n");
+ qsort (pnotes, pnotes_end - pnotes, sizeof (* pnotes), sort_gnu_build_notes);
+
+ /* Reconstruct the ELF notes. */
+ bfd_byte * new_contents;
+ bfd_byte * old;
+ bfd_byte * new;
+ bfd_size_type new_size;
+ bfd_vma prev_start = 0;
+ bfd_vma prev_end = 0;
+
+ new = new_contents = xmalloc (size);
+ for (pnote = pnotes, old = contents;
+ pnote < pnotes_end;
+ pnote ++)
+ {
+ bfd_size_type note_size = 12 + pnote->padded_namesz + pnote->note.descsz;
+
+ if (! is_deleted_note (pnote))
+ {
+ /* Create the note, potentially using the
+ address range of the previous note. */
+ if (pnote->start == prev_start && pnote->end == prev_end)
+ {
+ bfd_put_32 (abfd, pnote->note.namesz, new);
+ bfd_put_32 (abfd, 0, new + 4);
+ bfd_put_32 (abfd, pnote->note.type, new + 8);
+ new += 12;
+ memcpy (new, pnote->note.namedata, pnote->note.namesz);
+ if (pnote->note.namesz < pnote->padded_namesz)
+ memset (new + pnote->note.namesz, 0, pnote->padded_namesz - pnote->note.namesz);
+ new += pnote->padded_namesz;
+ }
+ else
{
- if (pnote->modified)
+ 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);
+ if (pnote->note.namesz < pnote->padded_namesz)
+ memset (new + pnote->note.namesz, 0, pnote->padded_namesz - pnote->note.namesz);
+ new += pnote->padded_namesz;
+ if (is_64bit (abfd))
{
- /* If the note has been modified then we must copy it by
- hand, potentially adding in a new description field. */
- if (pnote->start == prev_start && pnote->end == prev_end)
- {
- bfd_put_32 (abfd, pnote->note.namesz, new);
- bfd_put_32 (abfd, 0, 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;
- }
- 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
- {
- bfd_put_32 (abfd, pnote->start, new);
- bfd_put_32 (abfd, pnote->end, new + 4);
- new += 8;
- }
- }
+ bfd_put_64 (abfd, pnote->start, new);
+ bfd_put_64 (abfd, pnote->end, new + 8);
+ new += 16;
}
else
{
- memcpy (new, old, note_size);
- new += note_size;
+ bfd_put_32 (abfd, pnote->start, new);
+ bfd_put_32 (abfd, pnote->end, new + 4);
+ new += 8;
}
+
prev_start = pnote->start;
prev_end = pnote->end;
}
-
- old += note_size;
}
- new_size = new - new_contents;
- memcpy (contents, new_contents, new_size);
- size = new_size;
- free (new_contents);
+ old += note_size;
}
+#if DEBUG_MERGE
+ merge_debug ("Results of merge:\n");
+ for (pnote = pnotes; pnote < pnotes_end; pnote ++)
+ if (! is_deleted_note (pnote))
+ merge_debug ("offset %#08lx range %#08lx..%#08lx type %ld attribute %d namesz %ld\n",
+ (pnote->note.namedata - (char *) contents) - 12,
+ pnote->start, pnote->end,
+ pnote->note.type,
+ pnote->note.namedata[3],
+ pnote->note.namesz
+ );
+#endif
+
+ new_size = new - new_contents;
+ memcpy (contents, new_contents, new_size);
+ size = new_size;
+ free (new_contents);
+
done:
if (err)
{
@@ -2761,52 +2835,61 @@ copy_object (bfd *ibfd, bfd *obfd, const
}
}
+ merged_note_section * merged_note_sections = NULL;
if (merge_notes)
{
/* This palaver is necessary because we must set the output
section size first, before its contents are ready. */
- osec = bfd_get_section_by_name (ibfd, GNU_BUILD_ATTRS_SECTION_NAME);
- if (osec && is_merged_note_section (ibfd, osec))
+ for (osec = ibfd->sections; osec != NULL; osec = osec->next)
{
- bfd_size_type size;
-
- size = bfd_get_section_size (osec);
+ if (! is_mergeable_note_section (ibfd, osec))
+ continue;
+
+ bfd_size_type size = bfd_section_size (obfd, osec);
if (size == 0)
{
- bfd_nonfatal_message (NULL, ibfd, osec, _("warning: note section is empty"));
- merge_notes = FALSE;
+ bfd_nonfatal_message (NULL, ibfd, osec,
+ _("warning: note section is empty"));
+ continue;
}
- else if (! bfd_get_full_section_contents (ibfd, osec, & merged_notes))
+
+ merged_note_section * merged = xmalloc (sizeof * merged);
+ merged->contents = NULL;
+ if (! bfd_get_full_section_contents (ibfd, osec, & merged->contents))
{
- bfd_nonfatal_message (NULL, ibfd, osec, _("warning: could not load note section"));
- free (merged_notes);
- merged_notes = NULL;
- merge_notes = FALSE;
+ bfd_nonfatal_message (NULL, ibfd, osec,
+ _("warning: could not load note section"));
+ free (merged->contents);
+ free (merged);
+ continue;
}
- else
+
+ merged->size = merge_gnu_build_notes (ibfd, osec, size,
+ merged->contents);
+ if (merged->size == size)
+ {
+ /* Merging achieves nothing. */
+ merge_debug ("Merge of section %s achieved nothing - skipping\n",
+ bfd_section_name (obfd, osec));
+ free (merged->contents);
+ free (merged);
+ continue;
+ }
+
+ if (osec->output_section == NULL
+ || !bfd_set_section_size (obfd, osec->output_section, merged->size))
{
- merged_size = merge_gnu_build_notes (ibfd, osec, size, merged_notes);
- if (merged_size == size)
- {
- /* Merging achieves nothing. */
- free (merged_notes);
- merged_notes = NULL;
- merge_notes = FALSE;
- merged_size = 0;
- }
- else
- {
- if (osec->output_section == NULL
- || ! bfd_set_section_size (obfd, osec->output_section, merged_size))
- {
- bfd_nonfatal_message (NULL, obfd, osec, _("warning: failed to set merged notes size"));
- free (merged_notes);
- merged_notes = NULL;
- merge_notes = FALSE;
- merged_size = 0;
- }
- }
+ bfd_nonfatal_message (NULL, obfd, osec,
+ _("warning: failed to set merged notes size"));
+ free (merged->contents);
+ free (merged);
+ continue;
}
+
+ /* Add section to list of merged sections. */
+ merged->sec = osec;
+ merged->next = merged_note_sections;
+ merged_note_sections = merged;
}
}
@@ -3134,25 +3217,72 @@ copy_object (bfd *ibfd, bfd *obfd, const
}
}
- if (merge_notes)
+ if (merged_note_sections != NULL)
{
- osec = bfd_get_section_by_name (obfd, GNU_BUILD_ATTRS_SECTION_NAME);
- if (osec && is_merged_note_section (obfd, osec))
+ merged_note_section * merged = NULL;
+
+ for (osec = obfd->sections; osec != NULL; osec = osec->next)
{
- if (! bfd_set_section_contents (obfd, osec, merged_notes, 0, merged_size))
+ if (! is_mergeable_note_section (obfd, osec))
+ continue;
+
+ if (merged == NULL)
+ merged = merged_note_sections;
+
+ /* It is likely that output sections are in the same order
+ as the input sections, but do not assume that this is
+ the case. */
+ if (strcmp (bfd_section_name (obfd, merged->sec),
+ bfd_section_name (obfd, osec)) != 0)
+ {
+ for (merged = merged_note_sections;
+ merged != NULL;
+ merged = merged->next)
+ if (strcmp (bfd_section_name (obfd, merged->sec),
+ bfd_section_name (obfd, osec)) == 0)
+ break;
+
+ if (merged == NULL)
+ {
+ bfd_nonfatal_message
+ (NULL, obfd, osec,
+ _("error: failed to copy merged notes into output"));
+ continue;
+ }
+ }
+
+ if (! is_mergeable_note_section (obfd, osec))
{
- bfd_nonfatal_message (NULL, obfd, osec, _("error: failed to copy merged notes into output"));
- /* There is a potential resource leak here, but it is not important. */
- /* coverity[leaked_storage: FALSE] */
+ bfd_nonfatal_message
+ (NULL, obfd, osec,
+ _("error: failed to copy merged notes into output"));
+ continue;
+ }
+
+ if (! bfd_set_section_contents (obfd, osec, merged->contents, 0,
+ merged->size))
+ {
+ bfd_nonfatal_message
+ (NULL, obfd, osec,
+ _("error: failed to copy merged notes into output"));
return FALSE;
}
+
+ merged = merged->next;
+ }
+
+ /* Free the memory. */
+ merged_note_section * next;
+ for (merged = merged_note_sections; merged != NULL; merged = next)
+ {
+ next = merged->next;
+ free (merged->contents);
+ free (merged);
}
- else if (! is_strip)
- bfd_nonfatal_message (NULL, obfd, osec, _("could not find any mergeable note sections"));
- free (merged_notes);
- merged_notes = NULL;
- merge_notes = FALSE;
}
+ else if (merge_notes && ! is_strip)
+ non_fatal (_("%s: Could not find any mergeable note sections"),
+ bfd_get_filename (ibfd));
if (gnu_debuglink_filename != NULL)
{
@@ -3915,7 +4045,7 @@ skip_section (bfd *ibfd, sec_ptr isectio
/* When merging a note section we skip the copying of the contents,
but not the copying of the relocs associated with the contents. */
- if (skip_copy && is_merged_note_section (ibfd, isection))
+ if (skip_copy && is_mergeable_note_section (ibfd, isection))
return TRUE;
flags = bfd_get_section_flags (ibfd, isection);
diff -rupN binutils.orig/binutils/testsuite/binutils-all/note-2-32.d binutils-2.30/binutils/testsuite/binutils-all/note-2-32.d
--- binutils.orig/binutils/testsuite/binutils-all/note-2-32.d 2019-10-28 17:08:43.358324887 +0000
+++ binutils-2.30/binutils/testsuite/binutils-all/note-2-32.d 2019-10-28 17:16:57.804615900 +0000
@@ -5,13 +5,12 @@
#source: note-2-32.s
#...
- Owner Data size Description
-[ ]+\$<version>1[ ]+0x00000004[ ]+OPEN[ ]+Applies to region from 0x100 \(note1.s\)
-[ ]+\$<tool>gcc 7.0.1[ ]+0x00000000[ ]+OPEN[ ]+Applies to region from 0x100
-[ ]+\+<stack prot>true[ ]+0x00000000[ ]+OPEN[ ]+Applies to region from 0x100
-[ ]+\*<PIC>static[ ]+0x00000000[ ]+OPEN[ ]+Applies to region from 0x100
-[ ]+\*<ABI>0x0[ ]+0x00000000[ ]+OPEN[ ]+Applies to region from 0x100
-[ ]+\$<version>1[ ]+0x00000004[ ]+OPEN[ ]+Applies to region from 0x104 \(note2.s\)
-[ ]+!<stack prot>false[ ]+0x00000000[ ]+OPEN[ ]+Applies to region from 0x104
-[ ]+\*<PIC>pic[ ]+0x00000004[ ]+func[ ]+Applies to region from 0x104 \(func1\)
+[ ]+Owner[ ]+Data size[ ]+Description
+[ ]+GA\$<version>3p1[ ]+0x00000008[ ]+OPEN[ ]+Applies to region from 0x100 to 0x10b \(note1.s\)
+[ ]+GA\$<tool>gcc 7.0.1[ ]+0x00000000[ ]+OPEN[ ]+Applies to region from 0x100 to 0x10b
+[ ]+GA\*<ABI>0x0[ ]+0x00000008[ ]+OPEN[ ]+Applies to region from 0x100 to 0x108 \(note1.s\)
+[ ]+GA\+<stack prot>true[ ]+0x00000008[ ]+OPEN[ ]+Applies to region from 0x100 to 0x104 \(note1.s\)
+[ ]+GA\*<PIC>static[ ]+0x00000000[ ]+OPEN[ ]+Applies to region from 0x100 to 0x104
+[ ]+GA!<stack prot>false[ ]+0x00000008[ ]+OPEN[ ]+Applies to region from 0x104 to 0x108 \(note2.s\)
+[ ]+GA\*<PIC>pic[ ]+0x00000008[ ]+func[ ]+Applies to region from 0x104 to 0x106 \(func1\)
#...
diff -rupN binutils.orig/binutils/testsuite/binutils-all/note-2-32.s binutils-2.30/binutils/testsuite/binutils-all/note-2-32.s
--- binutils.orig/binutils/testsuite/binutils-all/note-2-32.s 2019-10-28 17:08:43.355324910 +0000
+++ binutils-2.30/binutils/testsuite/binutils-all/note-2-32.s 2019-10-28 17:09:04.609165478 +0000
@@ -6,32 +6,37 @@ note1.s:
.pushsection .gnu.build.attributes, "0x100000", %note
.balign 4
- .dc.l 4
- .dc.l 4
+ .dc.l 8
+ .dc.l 8
.dc.l 0x100
- .asciz "$1"
+ .asciz "GA$3p1"
.dc.l 0x100
+ .dc.l 0x104
- .dc.l 12
+ .dc.l 14
.dc.l 0
.dc.l 0x100
- .asciz "$gcc 7.0.1"
+ .asciz "GA$gcc 7.0.1"
+ .dc.b 0,0
- .dc.l 3
+ .dc.l 5
.dc.l 0
.dc.l 0x100
- .dc.b 0x2b, 0x2, 0
- .dc.b 0
+ .dc.b 0x47, 0x41, 0x2b, 0x2, 0
+ .dc.b 0,0,0
- .dc.l 4
+ .dc.l 6
.dc.l 0
.dc.l 0x100
- .dc.b 0x2a, 0x7, 0, 0
+ .dc.b 0x47, 0x41, 0x2a, 0x7, 0, 0
+ .dc.b 0,0
- .dc.l 4
+ .dc.l 6
.dc.l 0
.dc.l 0x100
- .dc.b 0x2a, 0x6, 0, 0
+ .dc.b 0x47, 0x41, 0x2a, 0x6, 0, 0
+ .dc.b 0,0
+
.popsection
@@ -42,33 +47,38 @@ func1:
.dc.l 0x100
.pushsection .gnu.build.attributes, "0x100000", %note
- .dc.l 4
- .dc.l 4
+ .dc.l 8
+ .dc.l 8
.dc.l 0x100
- .asciz "$1"
+ .asciz "GA$3p1"
.dc.l 0x104
-
- .dc.l 12
+ .dc.l 0x108
+
+ .dc.l 14
.dc.l 0
.dc.l 0x100
- .asciz "$gcc 7.0.1"
+ .asciz "GA$gcc 7.0.1"
+ .dc.b 0,0
- .dc.l 3
+ .dc.l 5
.dc.l 0
.dc.l 0x100
- .dc.b 0x21, 0x2, 0
- .dc.b 0
+ .dc.b 0x47, 0x41, 0x21, 0x2, 0
+ .dc.b 0,0,0
- .dc.l 4
- .dc.l 4
+ .dc.l 6
+ .dc.l 8
.dc.l 0x101
- .dc.b 0x2a, 0x7, 1, 0
- .dc.l 0x104
+ .dc.b 0x47, 0x41, 0x2a, 0x7, 1, 0
+ .dc.b 0,0
+ .dc.l 0x104
+ .dc.l 0x106
- .dc.l 4
+ .dc.l 6
.dc.l 0
.dc.l 0x100
- .dc.b 0x2a, 0x6, 0, 0
+ .dc.b 0x47, 0x41, 0x2a, 0x6, 0, 0
+ .dc.b 0,0
.popsection
@@ -77,16 +87,18 @@ note3.s:
.dc.l 0x100
.pushsection .gnu.build.attributes, "0x100000", %note
- .dc.l 4
- .dc.l 4
+ .dc.l 8
+ .dc.l 8
.dc.l 0x100
- .asciz "$1"
+ .asciz "GA$3p1"
.dc.l 0x108
+ .dc.l 0x10b
- .dc.l 12
+ .dc.l 14
.dc.l 0
.dc.l 0x100
- .asciz "$gcc 7.0.1"
+ .asciz "GA$gcc 7.0.1"
+ .dc.b 0,0
.popsection
diff -rupN binutils.orig/binutils/testsuite/binutils-all/note-2-64.d binutils-2.30/binutils/testsuite/binutils-all/note-2-64.d
--- binutils.orig/binutils/testsuite/binutils-all/note-2-64.d 2019-10-28 17:08:43.356324902 +0000
+++ binutils-2.30/binutils/testsuite/binutils-all/note-2-64.d 2019-10-28 17:17:05.724556490 +0000
@@ -3,19 +3,18 @@
#objcopy: --merge-notes
#name: merge notes section (64-bits)
#source: note-2-64.s
-#not-target: sparc64-*-*
+#not-target: sparc64-*-*
# Internally the Sparc64 backend uses two relocs for every one reloc visible externally.
# Unfortunately the BFD library does not provide a target specific way to delete individual
# relocs, so the note merging feature fails.
#...
- Owner Data size Description
-[ ]+\$<version>1[ ]+0x00000008[ ]+OPEN[ ]+Applies to region from 0x100 \(note1.s\)
-[ ]+\$<tool>gcc 7.0.1[ ]+0x00000000[ ]+OPEN[ ]+Applies to region from 0x100
-[ ]+\+<stack prot>true[ ]+0x00000000[ ]+OPEN[ ]+Applies to region from 0x100
-[ ]+\*<PIC>static[ ]+0x00000000[ ]+OPEN[ ]+Applies to region from 0x100
-[ ]+\*<ABI>0x0[ ]+0x00000000[ ]+OPEN[ ]+Applies to region from 0x100
-[ ]+\$<version>1[ ]+0x00000008[ ]+OPEN[ ]+Applies to region from 0x104 \(note2.s\)
-[ ]+!<stack prot>false[ ]+0x00000000[ ]+OPEN[ ]+Applies to region from 0x104
-[ ]+\*<PIC>pic[ ]+0x00000008[ ]+func[ ]+Applies to region from 0x104 \(func1\)
+[ ]+Owner[ ]+Data size[ ]+Description
+[ ]+GA\$<version>3p1[ ]+0x00000010[ ]+OPEN[ ]+Applies to region from 0x100 to 0x10b \(note1.s\)
+[ ]+GA\$<tool>gcc 7.0.1[ ]+0x00000000[ ]+OPEN[ ]+Applies to region from 0x100 to 0x10b
+[ ]+GA\*<ABI>0x0[ ]+0x00000010[ ]+OPEN[ ]+Applies to region from 0x100 to 0x108 \(note1.s\)
+[ ]+GA\+<stack prot>true[ ]+0x00000010[ ]+OPEN[ ]+Applies to region from 0x100 to 0x104 \(note1.s\)
+[ ]+GA\*<PIC>static[ ]+0x00000000[ ]+OPEN[ ]+Applies to region from 0x100 to 0x104
+[ ]+GA!<stack prot>false[ ]+0x00000010[ ]+OPEN[ ]+Applies to region from 0x104 to 0x108 \(note2.s\)
+[ ]+GA\*<PIC>pic[ ]+0x00000010[ ]+func[ ]+Applies to region from 0x104 to 0x106 \(func1\)
#...
diff -rupN binutils.orig/binutils/testsuite/binutils-all/note-2-64.s binutils-2.30/binutils/testsuite/binutils-all/note-2-64.s
--- binutils.orig/binutils/testsuite/binutils-all/note-2-64.s 2019-10-28 17:08:43.354324917 +0000
+++ binutils-2.30/binutils/testsuite/binutils-all/note-2-64.s 2019-10-28 17:09:04.609165478 +0000
@@ -6,32 +6,43 @@ note1.s:
.pushsection .gnu.build.attributes, "0x100000", %note
.balign 4
- .dc.l 4
.dc.l 8
+ .dc.l 16
.dc.l 0x100
- .asciz "$1"
+ .asciz "GA$3p1"
.8byte 0x100
+ .8byte 0x104
- .dc.l 12
+ .dc.l 14
.dc.l 0
.dc.l 0x100
- .asciz "$gcc 7.0.1"
+ .asciz "GA$gcc 7.0.1"
+ .dc.b 0,0
+
+ .dc.l 5
+ .dc.l 0
+ .dc.l 0x100
+ .dc.b 0x47, 0x41, 0x2b, 0x2, 0
+ .dc.b 0,0,0
- .dc.l 3
+ .dc.l 6
.dc.l 0
.dc.l 0x100
- .dc.b 0x2b, 0x2, 0
- .dc.b 0
+ .dc.b 0x47, 0x41, 0x2a, 0x7, 0, 0
+ .dc.b 0,0
- .dc.l 4
+ .dc.l 6
.dc.l 0
.dc.l 0x100
- .dc.b 0x2a, 0x7, 0, 0
+ .dc.b 0x47, 0x41, 0x2a, 0x6, 0, 0
+ .dc.b 0,0
- .dc.l 4
+ .dc.l 6
.dc.l 0
.dc.l 0x100
- .dc.b 0x2a, 0x6, 0, 0
+ .dc.b 0x47, 0x41, 0x2a, 0x7, 0, 0
+ .dc.b 0,0
+
.popsection
@@ -43,33 +54,38 @@ func1:
.dc.l 0x100
.pushsection .gnu.build.attributes, "0x100000", %note
- .dc.l 4
- .dc.l 8
+ .dc.l 8
+ .dc.l 16
.dc.l 0x100
- .asciz "$1"
+ .asciz "GA$3p1"
.8byte 0x104
+ .8byte 0x108
- .dc.l 12
+ .dc.l 14
.dc.l 0
.dc.l 0x100
- .asciz "$gcc 7.0.1"
-
- .dc.l 3
+ .asciz "GA$gcc 7.0.1"
+ .dc.b 0,0
+
+ .dc.l 5
.dc.l 0
.dc.l 0x100
- .dc.b 0x21, 0x2, 0
- .dc.b 0
+ .dc.b 0x47, 0x41, 0x21, 0x2, 0
+ .dc.b 0,0,7
- .dc.l 4
- .dc.l 8
+ .dc.l 6
+ .dc.l 16
.dc.l 0x101
- .dc.b 0x2a, 0x7, 1, 0
+ .dc.b 0x47, 0x41, 0x2a, 0x7, 1, 0
+ .dc.b 0,0
.8byte 0x104
+ .8byte 0x106
- .dc.l 4
+ .dc.l 6
.dc.l 0
.dc.l 0x100
- .dc.b 0x2a, 0x6, 0, 0
+ .dc.b 0x47, 0x41, 0x2a, 0x6, 0, 0
+ .dc.b 0,0
.popsection
@@ -78,15 +94,17 @@ note3.s:
.dc.l 0x100
.pushsection .gnu.build.attributes, "0x100000", %note
- .dc.l 4
- .dc.l 8
+ .dc.l 8
+ .dc.l 16
.dc.l 0x100
- .asciz "$1"
+ .asciz "GA$3p1"
.8byte 0x108
+ .8byte 0x10b
- .dc.l 12
+ .dc.l 14
.dc.l 0
.dc.l 0x100
- .asciz "$gcc 7.0.1"
+ .asciz "GA$gcc 7.0.1"
+ .dc.b 0,0
.popsection
diff -rupN binutils.orig/binutils/testsuite/binutils-all/note-3-32.d binutils-2.30/binutils/testsuite/binutils-all/note-3-32.d
--- binutils.orig/binutils/testsuite/binutils-all/note-3-32.d 2019-10-28 17:08:43.356324902 +0000
+++ binutils-2.30/binutils/testsuite/binutils-all/note-3-32.d 2019-10-28 17:09:04.609165478 +0000
@@ -7,12 +7,12 @@
#...
Displaying notes found in: .gnu.build.attributes
[ ]+Owner[ ]+Data size[ ]+Description
-[ ]+GA\$<version>2p1[ ]+0x0000000.[ ]+OPEN[ ]+Applies to region from 0x100 to 0x122 \(note_1.s\)
-[ ]+GA\$<tool>gcc 6.3.1 20161221[ ]+0x00000000[ ]+OPEN[ ]+Applies to region from 0x100 to 0x122
-[ ]+GA\*GOW:0x700[ ]+0x00000000[ ]+OPEN[ ]+Applies to region from 0x100 to 0x122
+[ ]+GA\$<version>3p1[ ]+0x0000000.[ ]+OPEN[ ]+Applies to region from 0x100 to 0x122 \(note_1.s\)
[ ]+GA\*<stack prot>off[ ]+0x00000000[ ]+OPEN[ ]+Applies to region from 0x100 to 0x122
-[ ]+GA\*FORTIFY:0xff[ ]+0x00000000[ ]+OPEN[ ]+Applies to region from 0x100 to 0x122
+[ ]+GA\$<tool>gcc 6.3.1 20161221[ ]+0x00000000[ ]+OPEN[ ]+Applies to region from 0x100 to 0x122
+[ ]+GA\*<ABI>0x[0-9a-f]+[ ]+0x00000000[ ]+OPEN[ ]+Applies to region from 0x100 to 0x122
[ ]+GA\*<PIC>PIC[ ]+0x00000000[ ]+OPEN[ ]+Applies to region from 0x100 to 0x122
[ ]+GA\!<short enum>false[ ]+0x00000000[ ]+OPEN[ ]+Applies to region from 0x100 to 0x122
-[ ]+GA\*<ABI>0x[0-9a-f]+[ ]+0x00000000[ ]+OPEN[ ]+Applies to region from 0x100 to 0x122
+[ ]+GA\*FORTIFY:0xff[ ]+0x00000000[ ]+OPEN[ ]+Applies to region from 0x100 to 0x122
+[ ]+GA\*GOW:0x700[ ]+0x00000000[ ]+OPEN[ ]+Applies to region from 0x100 to 0x122
#...
diff -rupN binutils.orig/binutils/testsuite/binutils-all/note-3-32.s binutils-2.30/binutils/testsuite/binutils-all/note-3-32.s
--- binutils.orig/binutils/testsuite/binutils-all/note-3-32.s 2019-10-28 17:08:43.354324917 +0000
+++ binutils-2.30/binutils/testsuite/binutils-all/note-3-32.s 2019-10-28 17:09:04.609165478 +0000
@@ -9,10 +9,11 @@ note_1.s:
.balign 4
.dc.l 8
- .dc.l 4
+ .dc.l 8
.dc.l 0x100
- .asciz "GA$2p1"
- .dc.l note_1.s
+ .asciz "GA$3p1"
+ .dc.l 0x100 /* note_1.s */
+ .dc.l 0x122 /* note_1.s end */
.dc.l 23
.dc.l 0
@@ -55,4 +56,12 @@ note_1.s:
.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 5
+ .dc.l 0
+ .dc.l 0x100
+ .dc.b 0x47, 0x41, 0x21, 0x8, 0
+ .dc.b 0, 0, 0
+
+
.popsection
diff -rupN binutils.orig/binutils/testsuite/binutils-all/note-3-64.d binutils-2.30/binutils/testsuite/binutils-all/note-3-64.d
--- binutils.orig/binutils/testsuite/binutils-all/note-3-64.d 2019-10-28 17:08:43.357324895 +0000
+++ binutils-2.30/binutils/testsuite/binutils-all/note-3-64.d 2019-10-28 17:09:04.609165478 +0000
@@ -7,12 +7,12 @@
#...
Displaying notes found in: .gnu.build.attributes
[ ]+Owner[ ]+Data size[ ]+Description
-[ ]+GA\$<version>2p1[ ]+0x0000000.[ ]+OPEN[ ]+Applies to region from 0x100 to 0x122 \(note_1.s\)
-[ ]+GA\$<tool>gcc 6.3.1 20161221[ ]+0x00000000[ ]+OPEN[ ]+Applies to region from 0x100 to 0x122
-[ ]+GA\*GOW:0x700[ ]+0x00000000[ ]+OPEN[ ]+Applies to region from 0x100 to 0x122
+[ ]+GA\$<version>3p1[ ]+0x00000010[ ]+OPEN[ ]+Applies to region from 0x100 to 0x122 \(note_1.s\)
[ ]+GA\*<stack prot>off[ ]+0x00000000[ ]+OPEN[ ]+Applies to region from 0x100 to 0x122
-[ ]+GA\*FORTIFY:0xff[ ]+0x00000000[ ]+OPEN[ ]+Applies to region from 0x100 to 0x122
+[ ]+GA\$<tool>gcc 6.3.1 20161221[ ]+0x00000000[ ]+OPEN[ ]+Applies to region from 0x100 to 0x122
+[ ]+GA\*<ABI>0x[0-9a-f]+[ ]+0x00000000[ ]+OPEN[ ]+Applies to region from 0x100 to 0x122
[ ]+GA\*<PIC>PIC[ ]+0x00000000[ ]+OPEN[ ]+Applies to region from 0x100 to 0x122
[ ]+GA\!<short enum>false[ ]+0x00000000[ ]+OPEN[ ]+Applies to region from 0x100 to 0x122
-[ ]+GA\*<ABI>0x[0-9a-f]+[ ]+0x00000000[ ]+OPEN[ ]+Applies to region from 0x100 to 0x122
+[ ]+GA\*FORTIFY:0xff[ ]+0x00000000[ ]+OPEN[ ]+Applies to region from 0x100 to 0x122
+[ ]+GA\*GOW:0x700[ ]+0x00000000[ ]+OPEN[ ]+Applies to region from 0x100 to 0x122
#...
diff -rupN binutils.orig/binutils/testsuite/binutils-all/note-3-64.s binutils-2.30/binutils/testsuite/binutils-all/note-3-64.s
--- binutils.orig/binutils/testsuite/binutils-all/note-3-64.s 2019-10-28 17:08:43.357324895 +0000
+++ binutils-2.30/binutils/testsuite/binutils-all/note-3-64.s 2019-10-28 17:09:04.609165478 +0000
@@ -9,10 +9,11 @@ note_1.s:
.balign 4
.dc.l 8
- .dc.l 8
+ .dc.l 16
.dc.l 0x100
- .asciz "GA$2p1"
- .8byte note_1.s
+ .asciz "GA$3p1"
+ .8byte 0x100 /* note_1.s */
+ .8byte 0x122 /* note_1 end */
.dc.l 23
.dc.l 0
@@ -55,4 +56,11 @@ note_1.s:
.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 0
+ .dc.l 0x100
+ .dc.b 0x47, 0x41, 0x2a, 0x7, 0x2, 0
+ .dc.b 0, 0
+
.popsection
diff -rupN binutils.orig/binutils/testsuite/binutils-all/note-4-32.d binutils-2.30/binutils/testsuite/binutils-all/note-4-32.d
--- binutils.orig/binutils/testsuite/binutils-all/note-4-32.d 2019-10-28 17:08:43.357324895 +0000
+++ binutils-2.30/binutils/testsuite/binutils-all/note-4-32.d 2019-10-28 17:17:19.515453041 +0000
@@ -7,13 +7,13 @@
#...
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.*
+[ ]+GA\$<version>3p3[ ]+0x00000008[ ]+OPEN[ ]+Applies to region from 0x10. to 0x110 \(note_4.s\)
+[ ]+GA\*<stack prot>off[ ]+0x00000000[ ]+OPEN[ ]+Applies to region from 0x10. to 0x110
+[ ]+GA\$<tool>gcc 7.2.1 20170915[ ]+0x00000000[ ]+OPEN[ ]+Applies to region from 0x10. to 0x110
+[ ]+GA\*<ABI>0x[0-9a-f]+[ ]+0x00000000[ ]+OPEN[ ]+Applies to region from 0x10. to 0x110
+[ ]+GA\*<PIC>PIC[ ]+0x00000000[ ]+OPEN[ ]+Applies to region from 0x10. to 0x110
+[ ]+GA\!<short enum>false[ ]+0x00000000[ ]+OPEN[ ]+Applies to region from 0x10. to 0x110
+[ ]+GA\*FORTIFY:0xff[ ]+0x00000000[ ]+OPEN[ ]+Applies to region from 0x10. to 0x110
+[ ]+GA\*GOW:0x700[ ]+0x00000000[ ]+OPEN[ ]+Applies to region from 0x10. to 0x110
+[ ]+GA\*<stack prot>strong[ ]+0x00000008[ ]+func[ ]+Applies to region from 0x10. to 0x10c.*
#...
diff -rupN binutils.orig/binutils/testsuite/binutils-all/note-4-32.s binutils-2.30/binutils/testsuite/binutils-all/note-4-32.s
--- binutils.orig/binutils/testsuite/binutils-all/note-4-32.s 2019-10-28 17:08:43.355324910 +0000
+++ binutils-2.30/binutils/testsuite/binutils-all/note-4-32.s 2019-10-28 17:17:23.931419915 +0000
@@ -1,6 +1,6 @@
.text
.org 0x100
-note_4.s:
+ .equiv note_4.s, . + 2
.dc.l 0
.dc.l 0
@@ -18,8 +18,8 @@ note_4.s_end:
.dc.l 8
.dc.l 0x100
.asciz "GA$3p3"
- .dc.l note_4.s
- .dc.l note_4.s_end
+ .dc.l 0x100 /* note_4.s - 2 */
+ .dc.l 0x110 /* note_4.s_end */
.dc.l 23
.dc.l 0
@@ -63,12 +63,18 @@ note_4.s_end:
.dc.b 0x47, 0x41, 0x2a, 0x6, 0xf2, 0x3, 0x38, 0xee, 0xce, 0xfa, 0x5e, 0x3c, 0
.dc.b 0, 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 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
+ .dc.l 0x108 /* bar */
+ .dc.l 0x10c /* bar_end */
.popsection
diff -rupN binutils.orig/binutils/testsuite/binutils-all/note-4-64.d binutils-2.30/binutils/testsuite/binutils-all/note-4-64.d
--- binutils.orig/binutils/testsuite/binutils-all/note-4-64.d 2019-10-28 17:08:43.356324902 +0000
+++ binutils-2.30/binutils/testsuite/binutils-all/note-4-64.d 2019-10-28 17:09:04.609165478 +0000
@@ -8,13 +8,13 @@
#...
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\$<version>3p3[ ]+0x00000010[ ]+OPEN[ ]+Applies to region from 0x100 to 0x120.*
-[ ]+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\$<tool>gcc 7.2.1 20170915[ ]+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\*<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.*
+[ ]+GA\*FORTIFY:0xff[ ]+0x00000000[ ]+OPEN[ ]+Applies to region from 0x100 to 0x120
+[ ]+GA\*GOW:0x700[ ]+0x00000000[ ]+OPEN[ ]+Applies to region from 0x100 to 0x120
+[ ]+GA\*<stack prot>strong[ ]+0x00000010[ ]+func[ ]+Applies to region from 0x110 to 0x120.*
#...
diff -rupN binutils.orig/binutils/testsuite/binutils-all/note-4-64.s binutils-2.30/binutils/testsuite/binutils-all/note-4-64.s
--- binutils.orig/binutils/testsuite/binutils-all/note-4-64.s 2019-10-28 17:08:43.356324902 +0000
+++ binutils-2.30/binutils/testsuite/binutils-all/note-4-64.s 2019-10-28 17:17:29.355379229 +0000
@@ -1,6 +1,6 @@
.text
.org 0x100
-note_4.s:
+ .equiv note_4.s, . + 2
.dc.l 0
.dc.l 0
.dc.l 0
@@ -22,8 +22,8 @@ note_4.s_end:
.dc.l 16
.dc.l 0x100
.asciz "GA$3p3"
- .8byte note_4.s
- .8byte note_4.s_end
+ .8byte 0x100 /* note_4.s - 2 */
+ .8byte 0x120 /* note_4.s_end */
.dc.l 23
.dc.l 0
@@ -68,11 +68,17 @@ note_4.s_end:
.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 6
.dc.l 16
.dc.l 0x101
.dc.b 0x47, 0x41, 0x2a, 0x2, 0x3, 0
.dc.b 0, 0
- .8byte bar
- .8byte bar_end
+ .8byte 0x110 /* bar */
+ .8byte 0x120 /* bar_end */
.popsection
diff -rupN binutils.orig/binutils/testsuite/binutils-all/note-6-32.d binutils-2.30/binutils/testsuite/binutils-all/note-6-32.d
--- binutils.orig/binutils/testsuite/binutils-all/note-6-32.d 1970-01-01 01:00:00.000000000 +0100
+++ binutils-2.30/binutils/testsuite/binutils-all/note-6-32.d 2019-10-28 17:17:38.955307217 +0000
@@ -0,0 +1,20 @@
+#PROG: objcopy
+#readelf: --notes --wide
+#objcopy: --merge-notes
+#name: v3 gnu build attribute note merging (32-bit)
+#source: note-6-32.s
+
+#...
+Displaying notes found in: .gnu.build.attributes
+[ ]+Owner[ ]+Data size[ ]+Description
+[ ]+GA\$<version>3p1[ ]+0x00000008[ ]+OPEN[ ]+Applies to region from 0x100 to 0x106 \(note_test\)
+[ ]+GA\*<stack prot>off[ ]+0x00000000[ ]+OPEN[ ]+Applies to region from 0x100 to 0x106
+[ ]+GA\$<tool>gcc 8.3.1 20190507[ ]+0x00000000[ ]+OPEN[ ]+Applies to region from 0x100 to 0x106
+[ ]+GA\*<ABI>0x[0-9a-f]+[ ]+0x00000000[ ]+OPEN[ ]+Applies to region from 0x100 to 0x106
+[ ]+GA\*<PIC>PIC[ ]+0x00000000[ ]+OPEN[ ]+Applies to region from 0x100 to 0x106
+[ ]+GA\!<short enum>false[ ]+0x00000000[ ]+OPEN[ ]+Applies to region from 0x100 to 0x106
+[ ]+GA\*FORTIFY:0xff[ ]+0x00000000[ ]+OPEN[ ]+Applies to region from 0x100 to 0x106
+[ ]+GA\*GOW:0x700[ ]+0x00000000[ ]+OPEN[ ]+Applies to region from 0x100 to 0x106
+[ ]+GA\$<version>3p1[ ]+0x00000008[ ]+func[ ]+Applies to region from 0x102 to 0x106
+[ ]+GA\$<tool>hello world[ ]+0x00000000[ ]+func[ ]+Applies to region from 0x102 to 0x106
+#...
diff -rupN binutils.orig/binutils/testsuite/binutils-all/note-6-32.s binutils-2.30/binutils/testsuite/binutils-all/note-6-32.s
--- binutils.orig/binutils/testsuite/binutils-all/note-6-32.s 1970-01-01 01:00:00.000000000 +0100
+++ binutils-2.30/binutils/testsuite/binutils-all/note-6-32.s 2019-10-28 17:17:38.955307217 +0000
@@ -0,0 +1,145 @@
+ .text
+ .org 0x100
+ .global note_test
+note_test:
+note_1_start:
+ .word 0
+note_1_end:
+note_2_start:
+ .word 0
+note_2_end:
+note_3_start:
+ .word 0
+note_3_end:
+note_test_end:
+ .size note_test, note_test_end - note_test
+
+ .pushsection .gnu.build.attributes, "", %note
+ .balign 4
+
+ .dc.l 8
+ .dc.l 8
+ .dc.l 0x100
+ .asciz "GA$3p1"
+ .4byte 0x100 /* note_1_start */
+ .4byte 0x102 /* note_1_end */
+
+ .dc.l 23
+ .dc.l 0
+ .dc.l 0x100
+ .asciz "GA$gcc 8.3.1 20190507"
+ .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 8
+ .dc.l 8
+ .dc.l 0x100
+ .asciz "GA$3p1"
+ .4byte 0x102 /* note_2_start */
+ .4byte 0x106 /* note_3_end */
+
+ .dc.l 23
+ .dc.l 0
+ .dc.l 0x100
+ .asciz "GA$gcc 8.3.1 20190507"
+ .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 8
+ .dc.l 8
+ .dc.l 0x101
+ .asciz "GA$3p1"
+ .4byte 0x102 /* note_2_start */
+ .4byte 0x104 /* note_2_end */
+
+ .dc.l 16
+ .dc.l 0
+ .dc.l 0x101
+ .asciz "GA$hello world"
+
+
+ .dc.l 8
+ .dc.l 8
+ .dc.l 0x101
+ .asciz "GA$3p1"
+ .4byte 0x104 /* note_3_start */
+ .4byte 0x106 /* note_3_end */
+
+ .dc.l 16
+ .dc.l 0
+ .dc.l 0x101
+ .asciz "GA$hello world"
+
+ .popsection
diff -rupN binutils.orig/binutils/testsuite/binutils-all/note-6-64.d binutils-2.30/binutils/testsuite/binutils-all/note-6-64.d
--- binutils.orig/binutils/testsuite/binutils-all/note-6-64.d 1970-01-01 01:00:00.000000000 +0100
+++ binutils-2.30/binutils/testsuite/binutils-all/note-6-64.d 2019-10-28 17:17:43.659271931 +0000
@@ -0,0 +1,20 @@
+#PROG: objcopy
+#readelf: --notes --wide
+#objcopy: --merge-notes
+#name: v3 gnu build attribute note merging (64-bit)
+#source: note-6-64.s
+
+#...
+Displaying notes found in: .gnu.build.attributes
+[ ]+Owner[ ]+Data size[ ]+Description
+[ ]+GA\$<version>3p1[ ]+0x00000010[ ]+OPEN[ ]+Applies to region from 0x100 to 0x106 \(note_test\)
+[ ]+GA\*<stack prot>off[ ]+0x00000000[ ]+OPEN[ ]+Applies to region from 0x100 to 0x106
+[ ]+GA\$<tool>gcc 8.3.1 20190507[ ]+0x00000000[ ]+OPEN[ ]+Applies to region from 0x100 to 0x106
+[ ]+GA\*<ABI>0x[0-9a-f]+[ ]+0x00000000[ ]+OPEN[ ]+Applies to region from 0x100 to 0x106
+[ ]+GA\*<PIC>PIC[ ]+0x00000000[ ]+OPEN[ ]+Applies to region from 0x100 to 0x106
+[ ]+GA\!<short enum>false[ ]+0x00000000[ ]+OPEN[ ]+Applies to region from 0x100 to 0x106
+[ ]+GA\*FORTIFY:0xff[ ]+0x00000000[ ]+OPEN[ ]+Applies to region from 0x100 to 0x106
+[ ]+GA\*GOW:0x700[ ]+0x00000000[ ]+OPEN[ ]+Applies to region from 0x100 to 0x106
+[ ]+GA\$<version>3p1[ ]+0x00000010[ ]+func[ ]+Applies to region from 0x102 to 0x106
+[ ]+GA\$<tool>hello world[ ]+0x00000000[ ]+func[ ]+Applies to region from 0x102 to 0x106
+#...
diff -rupN binutils.orig/binutils/testsuite/binutils-all/note-6-64.s binutils-2.30/binutils/testsuite/binutils-all/note-6-64.s
--- binutils.orig/binutils/testsuite/binutils-all/note-6-64.s 1970-01-01 01:00:00.000000000 +0100
+++ binutils-2.30/binutils/testsuite/binutils-all/note-6-64.s 2019-10-28 17:17:43.659271931 +0000
@@ -0,0 +1,145 @@
+ .text
+ .org 0x100
+ .global note_test
+note_test:
+note_1_start:
+ .word 0
+note_1_end:
+note_2_start:
+ .word 0
+note_2_end:
+note_3_start:
+ .word 0
+note_3_end:
+note_test_end:
+ .size note_test, note_test_end - note_test
+
+ .pushsection .gnu.build.attributes, "", %note
+ .balign 4
+
+ .dc.l 8
+ .dc.l 16
+ .dc.l 0x100
+ .asciz "GA$3p1"
+ .8byte 0x100 /* note_1_start */
+ .8byte 0x102 /* note_1_end */
+
+ .dc.l 23
+ .dc.l 0
+ .dc.l 0x100
+ .asciz "GA$gcc 8.3.1 20190507"
+ .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 8
+ .dc.l 16
+ .dc.l 0x100
+ .asciz "GA$3p1"
+ .8byte 0x102 /* note_2_start */
+ .8byte 0x106 /* note_3_end */
+
+ .dc.l 23
+ .dc.l 0
+ .dc.l 0x100
+ .asciz "GA$gcc 8.3.1 20190507"
+ .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 8
+ .dc.l 16
+ .dc.l 0x101
+ .asciz "GA$3p1"
+ .8byte 0x102 /* note_2_start */
+ .8byte 0x104 /* note_2_end */
+
+ .dc.l 16
+ .dc.l 0
+ .dc.l 0x101
+ .asciz "GA$hello world"
+
+
+ .dc.l 8
+ .dc.l 16
+ .dc.l 0x101
+ .asciz "GA$3p1"
+ .8byte 0x104 /* note_3_start */
+ .8byte 0x106 /* note_3_end */
+
+ .dc.l 16
+ .dc.l 0
+ .dc.l 0x101
+ .asciz "GA$hello world"
+
+ .popsection
diff -rupN binutils.orig/binutils/testsuite/binutils-all/objcopy.exp binutils-2.30/binutils/testsuite/binutils-all/objcopy.exp
--- binutils.orig/binutils/testsuite/binutils-all/objcopy.exp 2019-10-28 17:08:43.353324925 +0000
+++ binutils-2.30/binutils/testsuite/binutils-all/objcopy.exp 2019-10-28 17:09:04.610165471 +0000
@@ -1057,10 +1057,12 @@ if [is_elf_format] {
run_dump_test "note-2-64"
run_dump_test "note-3-64"
run_dump_test "note-4-64"
+ run_dump_test "note-6-64"
} else {
run_dump_test "note-2-32"
run_dump_test "note-3-32"
run_dump_test "note-4-32"
+ run_dump_test "note-6-32"
}
run_dump_test "note-5"
}
--- binutils.orig/binutils/objcopy.c 2019-11-06 10:21:47.933091869 +0000
+++ binutils-2.30/binutils/objcopy.c 2019-11-06 15:12:26.964599817 +0000
@@ -2502,7 +2502,7 @@ merge_gnu_build_notes (bfd * ab
{
bfd_set_error (bfd_error_bad_value);
bfd_nonfatal_message (NULL, abfd, sec, err);
- status = 1;
+ /* status = 1; */
}
free (pnotes);
@@ -2859,7 +2859,7 @@ copy_object (bfd *ibfd, bfd *obfd, const
{
bfd_nonfatal_message (NULL, ibfd, osec,
_("warning: could not load note section"));
- free (merged->contents);
+ /* Do NOT free merged->contents - it is cached and might be used elsewhere. */
free (merged);
continue;
}
@@ -2871,7 +2871,7 @@ copy_object (bfd *ibfd, bfd *obfd, const
/* Merging achieves nothing. */
merge_debug ("Merge of section %s achieved nothing - skipping\n",
bfd_section_name (obfd, osec));
- free (merged->contents);
+ /* Do NOT free merged->contents - it is cached and might be used elsewhere. */
free (merged);
continue;
}
@@ -2881,7 +2881,7 @@ copy_object (bfd *ibfd, bfd *obfd, const
{
bfd_nonfatal_message (NULL, obfd, osec,
_("warning: failed to set merged notes size"));
- free (merged->contents);
+ /* Do NOT free merged->contents - it is cached and might be used elsewhere. */
free (merged);
continue;
}
--- binutils.orig/binutils/objcopy.c 2019-11-06 16:37:57.018843494 +0000
+++ binutils-2.30/binutils/objcopy.c 2019-11-06 16:40:52.669564222 +0000
@@ -2845,7 +2845,13 @@ copy_object (bfd *ibfd, bfd *obfd, const
if (! is_mergeable_note_section (ibfd, osec))
continue;
+ /* If the section is going to be completly deleted then
+ do not bother to merge it. */
+ if (osec->output_section == NULL)
+ continue;
+
bfd_size_type size = bfd_section_size (obfd, osec);
+
if (size == 0)
{
bfd_nonfatal_message (NULL, ibfd, osec,
@@ -2859,29 +2865,22 @@ copy_object (bfd *ibfd, bfd *obfd, const
{
bfd_nonfatal_message (NULL, ibfd, osec,
_("warning: could not load note section"));
- /* Do NOT free merged->contents - it is cached and might be used elsewhere. */
free (merged);
continue;
}
merged->size = merge_gnu_build_notes (ibfd, osec, size,
merged->contents);
- if (merged->size == size)
- {
- /* Merging achieves nothing. */
- merge_debug ("Merge of section %s achieved nothing - skipping\n",
- bfd_section_name (obfd, osec));
- /* Do NOT free merged->contents - it is cached and might be used elsewhere. */
- free (merged);
- continue;
- }
+ /* FIXME: Once we have read the contents in, we must write
+ them out again. So even if the mergeing has achieved
+ nothing we still add this entry to the merge list. */
- if (osec->output_section == NULL
- || !bfd_set_section_size (obfd, osec->output_section, merged->size))
+ if (size != merged->size
+ && !bfd_set_section_size (obfd, osec->output_section, merged->size))
{
bfd_nonfatal_message (NULL, obfd, osec,
_("warning: failed to set merged notes size"));
- /* Do NOT free merged->contents - it is cached and might be used elsewhere. */
+ free (merged->contents);
free (merged);
continue;
}
@@ -3246,16 +3245,16 @@ copy_object (bfd *ibfd, bfd *obfd, const
{
bfd_nonfatal_message
(NULL, obfd, osec,
- _("error: failed to copy merged notes into output"));
+ _("error: failed to locate merged notes"));
continue;
}
}
- if (! is_mergeable_note_section (obfd, osec))
+ if (merged->contents == NULL)
{
bfd_nonfatal_message
(NULL, obfd, osec,
- _("error: failed to copy merged notes into output"));
+ _("error: failed to merged notes"));
continue;
}
--- binutils.orig/binutils/objcopy.c 2019-11-20 10:59:20.993888328 +0000
+++ binutils-2.30/binutils/objcopy.c 2019-11-20 16:59:50.714905419 +0000
@@ -2292,7 +2292,7 @@ merge_gnu_build_notes (bfd * ab
- it makes things much simpler. */
if (version_3_seen == 0)
{
- merge_debug ("%s: skipping merge - not using v3 notes", bfd_section_name (sec));
+ merge_debug ("%s: skipping merge - not using v3 notes", bfd_section_name (abfd, sec));
goto done;
}
@@ -2324,7 +2324,7 @@ merge_gnu_build_notes (bfd * ab
other note then if they are both of the same type (open
or func) then they can be merged and one deleted. If
they are of different types then they cannot be merged. */
- for (pnote = pnotes + 1; pnote < pnotes_end; pnote ++)
+ for (pnote = pnotes; pnote < pnotes_end; pnote ++)
{
/* Skip already deleted notes.
FIXME: Can this happen ? We are scanning forwards and
@@ -2426,7 +2426,9 @@ merge_gnu_build_notes (bfd * ab
bfd_vma prev_start = 0;
bfd_vma prev_end = 0;
- new = new_contents = xmalloc (size);
+ /* Not sure how, but the notes might grow in size.
+ (eg see PR 1774507). Allow for this here. */
+ new = new_contents = xmalloc (size * 2);
for (pnote = pnotes, old = contents;
pnote < pnotes_end;
pnote ++)
@@ -2493,8 +2495,11 @@ merge_gnu_build_notes (bfd * ab
#endif
new_size = new - new_contents;
- memcpy (contents, new_contents, new_size);
- size = new_size;
+ if (new_size < size)
+ {
+ memcpy (contents, new_contents, new_size);
+ size = new_size;
+ }
free (new_contents);
done:
@@ -2940,6 +2945,7 @@ copy_object (bfd *ibfd, bfd *obfd, const
pdump->filename,
strerror (errno));
free (contents);
+ fclose (f);
/* There is a potential resource leak here, but it is not important. */
/* coverity[leaked_storage: FALSE] */
return FALSE;