1338 lines
41 KiB
Diff
1338 lines
41 KiB
Diff
diff -rup binutils.orig/binutils/objcopy.c binutils-2.29.1/binutils/objcopy.c
|
||
--- binutils.orig/binutils/objcopy.c 2018-01-03 16:06:45.005657092 +0000
|
||
+++ binutils-2.29.1/binutils/objcopy.c 2018-01-03 16:06:57.927502748 +0000
|
||
@@ -1905,84 +1905,229 @@ num_bytes (unsigned long val)
|
||
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.
|
||
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)
|
||
{
|
||
- Elf_Internal_Note * pnotes_end;
|
||
- Elf_Internal_Note * pnotes;
|
||
- Elf_Internal_Note * pnote;
|
||
+ objcopy_internal_note * pnotes_end;
|
||
+ objcopy_internal_note * pnotes = NULL;
|
||
+ objcopy_internal_note * pnote;
|
||
bfd_size_type remain = size;
|
||
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;
|
||
+
|
||
|
||
- /* 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. */
|
||
- 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)
|
||
{
|
||
- pnote->namesz = (bfd_get_32 (abfd, in ) + 3) & ~3;
|
||
- pnote->descsz = (bfd_get_32 (abfd, in + 4) + 3) & ~3;
|
||
- pnote->type = bfd_get_32 (abfd, in + 8);
|
||
+ bfd_vma start, end;
|
||
|
||
- if (pnote->type != NT_GNU_BUILD_ATTRIBUTE_OPEN
|
||
- && pnote->type != NT_GNU_BUILD_ATTRIBUTE_FUNC)
|
||
+ 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);
|
||
+
|
||
+ 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");
|
||
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");
|
||
goto done;
|
||
}
|
||
|
||
- if (pnote->namesz < 2)
|
||
+ if (pnote->note.namesz < 2)
|
||
{
|
||
err = _("corrupt GNU build attribute note: name too small");
|
||
goto done;
|
||
}
|
||
|
||
- if (pnote->descsz != 0
|
||
- && pnote->descsz != 4
|
||
- && pnote->descsz != 8)
|
||
+ pnote->note.namedata = (char *)(in + 12);
|
||
+ pnote->note.descdata = (char *)(in + 12 + pnote->note.namesz);
|
||
+
|
||
+ 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");
|
||
goto done;
|
||
}
|
||
|
||
- pnote->namedata = (char *)(in + 12);
|
||
- pnote->descdata = (char *)(in + 12 + pnote->namesz);
|
||
+ if (is_open_note (pnote))
|
||
+ {
|
||
+ if (start)
|
||
+ previous_open_start = start;
|
||
+
|
||
+ pnote->start = previous_open_start;
|
||
|
||
- remain -= 12 + pnote->namesz + pnote->descsz;
|
||
- in += 12 + pnote->namesz + pnote->descsz;
|
||
+ if (end)
|
||
+ previous_open_end = end;
|
||
|
||
- if (pnote->namedata[pnote->namesz - 1] != 0)
|
||
+ 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");
|
||
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 ++;
|
||
}
|
||
|
||
@@ -1995,27 +2140,29 @@ merge_gnu_build_notes (bfd * abfd, asect
|
||
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");
|
||
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");
|
||
goto done;
|
||
}
|
||
|
||
/* 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;
|
||
|
||
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].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");
|
||
goto done;
|
||
@@ -2026,7 +2173,9 @@ merge_gnu_build_notes (bfd * abfd, asect
|
||
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.
|
||
+ 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
|
||
of type GNU_BUILD_ATTRIBUTE_STACK_SIZE.
|
||
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, asect
|
||
address to which it refers. */
|
||
for (pnote = pnotes + 1; pnote < pnotes_end; pnote ++)
|
||
{
|
||
- Elf_Internal_Note * back;
|
||
- Elf_Internal_Note * prev_open = NULL;
|
||
+ int note_type;
|
||
+ 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;
|
||
|
||
- /* Scan for duplicates. Clear the type field of any found - but do not
|
||
- delete them just yet. */
|
||
+ 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 --)
|
||
{
|
||
- if (back->descsz > 0
|
||
- && back->type != NT_GNU_BUILD_ATTRIBUTE_FUNC
|
||
- && prev_open == NULL)
|
||
- prev_open = 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;
|
||
+
|
||
+ /* If the two notes are different then keep on searching. */
|
||
+ if (back_type != note_type)
|
||
+ continue;
|
||
|
||
- if (back->type == pnote->type
|
||
- && back->namedata[attribute_type_byte] == pnote->namedata[attribute_type_byte])
|
||
+ /* 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;
|
||
- 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->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;
|
||
+ byte = (* name ++) & 0xff;
|
||
+ note_val |= byte << shift;
|
||
+ shift += 8;
|
||
}
|
||
-
|
||
- if (back->namesz == pnote->namesz
|
||
- && memcmp (back->namedata, pnote->namedata, back->namesz) == 0)
|
||
+
|
||
+ for (shift = 0, back_val = 0,
|
||
+ bytes = back->note.namesz - val_start,
|
||
+ name = (unsigned char *) back->note.namedata + val_start;
|
||
+ bytes--;)
|
||
{
|
||
- duplicate_found = TRUE;
|
||
- pnote->type = 0;
|
||
- break;
|
||
+ byte = (* name ++) & 0xff;
|
||
+ back_val |= byte << shift;
|
||
+ shift += 8;
|
||
}
|
||
|
||
- /* If we have found an attribute match then stop searching backwards. */
|
||
- if (! ISPRINT (back->namedata[attribute_type_byte])
|
||
- /* Names are NUL terminated, so this is safe. */
|
||
- || strcmp (back->namedata + val_start, pnote->namedata + val_start) == 0)
|
||
+ back_val += note_val;
|
||
+ if (num_bytes (back_val) >= back->note.namesz - val_start)
|
||
{
|
||
- /* Since we are keeping this note we must check to see if its
|
||
- description refers back to an earlier OPEN version note. If so
|
||
- then we must make sure that version note is also preserved. */
|
||
- if (pnote->descsz == 0
|
||
- && prev_open != NULL
|
||
- && prev_open->type == 0)
|
||
- prev_open->type = NT_GNU_BUILD_ATTRIBUTE_FUNC;
|
||
+ /* 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;
|
||
+ }
|
||
|
||
- break;
|
||
+ /* 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, asect
|
||
bfd_byte * old;
|
||
bfd_byte * new;
|
||
bfd_size_type new_size;
|
||
- arelent ** relpp = NULL;
|
||
- long relsize;
|
||
- 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;
|
||
- }
|
||
+ bfd_vma prev_start = 0;
|
||
+ bfd_vma prev_end = 0;
|
||
|
||
/* Eliminate the duplicates. */
|
||
new = new_contents = xmalloc (size);
|
||
@@ -2165,36 +2331,52 @@ merge_gnu_build_notes (bfd * abfd, asect
|
||
pnote < pnotes_end;
|
||
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 there is a reloc at the current offset, delete it.
|
||
- 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 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)
|
||
{
|
||
- if ((* rel)->howto == NULL)
|
||
- continue;
|
||
- if ((* rel)->address < (bfd_vma) (new - new_contents))
|
||
- continue;
|
||
- if ((* rel)->address >= (bfd_vma) ((new + note_size) - new_contents))
|
||
- (* rel)->address -= note_size;
|
||
+ 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
|
||
- (* rel)->howto = NULL;
|
||
+ {
|
||
+ bfd_put_32 (abfd, pnote->start, new);
|
||
+ bfd_put_32 (abfd, pnote->end, new + 4);
|
||
+ new += 8;
|
||
+ }
|
||
}
|
||
}
|
||
- }
|
||
- else
|
||
- {
|
||
- memcpy (new, old, note_size);
|
||
- new += note_size;
|
||
+ else
|
||
+ {
|
||
+ memcpy (new, old, note_size);
|
||
+ new += note_size;
|
||
+ }
|
||
+ prev_start = pnote->start;
|
||
+ prev_end = pnote->end;
|
||
}
|
||
|
||
old += note_size;
|
||
@@ -2204,24 +2386,6 @@ merge_gnu_build_notes (bfd * abfd, asect
|
||
memcpy (contents, new_contents, new_size);
|
||
size = new_size;
|
||
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:
|
||
diff -rup binutils.orig/binutils/readelf.c binutils-2.29.1/binutils/readelf.c
|
||
--- binutils.orig/binutils/readelf.c 2018-01-03 16:06:45.005657092 +0000
|
||
+++ binutils-2.29.1/binutils/readelf.c 2018-01-03 16:28:24.417115970 +0000
|
||
@@ -16247,9 +16247,9 @@ get_note_type (unsigned e_type)
|
||
case NT_ARCH:
|
||
return _("NT_ARCH (architecture)");
|
||
case NT_GNU_BUILD_ATTRIBUTE_OPEN:
|
||
- return _("NT_GNU_BUILD_ATTRIBUTE_OPEN");
|
||
+ return _("OPEN");
|
||
case NT_GNU_BUILD_ATTRIBUTE_FUNC:
|
||
- return _("NT_GNU_BUILD_ATTRIBUTE_FUNC");
|
||
+ return _("func");
|
||
default:
|
||
break;
|
||
}
|
||
@@ -17064,13 +17064,16 @@ print_ia64_vms_note (Elf_Internal_Note *
|
||
return TRUE;
|
||
}
|
||
|
||
-/* Print the name of the symbol associated with a build attribute
|
||
- that is attached to address OFFSET. */
|
||
-
|
||
-static bfd_boolean
|
||
-print_symbol_for_build_attribute (FILE * file,
|
||
- unsigned long offset,
|
||
- bfd_boolean is_open_attr)
|
||
+/* Find the symbol associated with a build attribute that is attached
|
||
+ 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 Elf_Internal_Sym *
|
||
+get_symbol_for_build_attribute (FILE * file,
|
||
+ unsigned long offset,
|
||
+ bfd_boolean is_open_attr,
|
||
+ const char ** pname)
|
||
{
|
||
static FILE * saved_file = NULL;
|
||
static char * strtab;
|
||
@@ -17109,10 +17112,7 @@ print_symbol_for_build_attribute (FILE *
|
||
}
|
||
|
||
if (symtab == NULL || strtab == NULL)
|
||
- {
|
||
- printf ("\n");
|
||
- return FALSE;
|
||
- }
|
||
+ return NULL;
|
||
|
||
/* Find a symbol whose value matches offset. */
|
||
for (sym = symtab; sym < symtab + nsyms; sym ++)
|
||
@@ -17132,14 +17132,15 @@ print_symbol_for_build_attribute (FILE *
|
||
FUNC symbols entirely. */
|
||
switch (ELF_ST_TYPE (sym->st_info))
|
||
{
|
||
- case STT_FILE:
|
||
- saved_sym = sym;
|
||
- /* We can stop searching now. */
|
||
- sym = symtab + nsyms;
|
||
- continue;
|
||
-
|
||
case STT_OBJECT:
|
||
+ case STT_FILE:
|
||
saved_sym = sym;
|
||
+ if (sym->st_size)
|
||
+ {
|
||
+ /* If the symbol has a size associated
|
||
+ with it then we can stop searching. */
|
||
+ sym = symtab + nsyms;
|
||
+ }
|
||
continue;
|
||
|
||
case STT_FUNC:
|
||
@@ -17177,55 +17178,118 @@ print_symbol_for_build_attribute (FILE *
|
||
}
|
||
}
|
||
|
||
- printf (" (%s: %s)\n",
|
||
- is_open_attr ? _("file") : _("func"),
|
||
- saved_sym ? strtab + saved_sym->st_name : _("<no symbol found>)"));
|
||
- return TRUE;
|
||
+ if (saved_sym && pname)
|
||
+ * pname = strtab + saved_sym->st_name;
|
||
+
|
||
+ return saved_sym;
|
||
}
|
||
|
||
static bfd_boolean
|
||
print_gnu_build_attribute_description (Elf_Internal_Note * pnote,
|
||
FILE * file)
|
||
{
|
||
- static unsigned long global_offset = 0;
|
||
- unsigned long offset;
|
||
- unsigned int desc_size = is_32bit_elf ? 4 : 8;
|
||
- bfd_boolean is_open_attr = pnote->type == NT_GNU_BUILD_ATTRIBUTE_OPEN;
|
||
-
|
||
- if (pnote->descsz == 0)
|
||
- {
|
||
+ static unsigned long global_offset = 0;
|
||
+ static unsigned long global_end = 0;
|
||
+ static unsigned long func_offset = 0;
|
||
+ static unsigned long func_end = 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)
|
||
{
|
||
- printf (_(" Applies from offset %#lx\n"), global_offset);
|
||
- return TRUE;
|
||
+ if (global_end > global_offset)
|
||
+ printf (_(" Applies to region from %#lx to %#lx\n"),
|
||
+ global_offset, global_end);
|
||
+ else
|
||
+ printf (_(" Applies to region from %#lx\n"), global_offset);
|
||
}
|
||
else
|
||
{
|
||
- printf (_(" Applies to func at %#lx"), global_offset);
|
||
- return print_symbol_for_build_attribute (file, global_offset, is_open_attr);
|
||
+ if (func_end > func_offset)
|
||
+ 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);
|
||
printf (_(" <invalid descsz>"));
|
||
return FALSE;
|
||
}
|
||
|
||
- offset = byte_get ((unsigned char *) pnote->descdata, desc_size);
|
||
+ name = NULL;
|
||
+ sym = get_symbol_for_build_attribute (file, start, is_open_attr, & name);
|
||
+
|
||
+ if (end == 0 && sym != NULL && sym->st_size > 0)
|
||
+ end = start + sym->st_size;
|
||
|
||
if (is_open_attr)
|
||
{
|
||
- printf (_(" Applies from offset %#lx"), offset);
|
||
- global_offset = offset;
|
||
+ /* FIXME: Need to properly allow for section alignment. 16 is just the alignment used on x86_64. */
|
||
+ 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
|
||
{
|
||
- 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 (file, offset, is_open_attr);
|
||
+ if (sym && name)
|
||
+ printf (_(" (%s)"), name);
|
||
+
|
||
+ printf ("\n");
|
||
+ return TRUE;
|
||
}
|
||
|
||
static bfd_boolean
|
||
@@ -17248,11 +17312,21 @@ print_gnu_build_attribute_name (Elf_Inte
|
||
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. */
|
||
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");
|
||
name += 2;
|
||
left -= 2;
|
||
diff -rup binutils.orig/binutils/testsuite/binutils-all/mips/mips-note-2r.d binutils-2.29.1/binutils/testsuite/binutils-all/mips/mips-note-2r.d
|
||
--- binutils.orig/binutils/testsuite/binutils-all/mips/mips-note-2r.d 2018-01-03 16:06:45.013656996 +0000
|
||
+++ binutils-2.29.1/binutils/testsuite/binutils-all/mips/mips-note-2r.d 2018-01-03 16:06:57.927502748 +0000
|
||
@@ -5,7 +5,5 @@
|
||
#as: -32
|
||
#source: ../note-2-32.s
|
||
|
||
-Relocation section '\.rel\.gnu\.build\.attributes' at offset .* contains 2 entries:
|
||
- Offset Info Type Sym\.Value Sym\. Name
|
||
-00000010 ......02 R_MIPS_32 00000100 note1\.s
|
||
-0000006c ......02 R_MIPS_32 00000104 note2\.s
|
||
+There are no relocations in this file.
|
||
+#...
|
||
diff -rup binutils.orig/binutils/testsuite/binutils-all/mips/mips-note-2r-n32.d binutils-2.29.1/binutils/testsuite/binutils-all/mips/mips-note-2r-n32.d
|
||
--- binutils.orig/binutils/testsuite/binutils-all/mips/mips-note-2r-n32.d 2018-01-03 16:06:45.014656984 +0000
|
||
+++ binutils-2.29.1/binutils/testsuite/binutils-all/mips/mips-note-2r-n32.d 2018-01-03 16:06:57.927502748 +0000
|
||
@@ -5,7 +5,5 @@
|
||
#as: -n32 -mips3
|
||
#source: ../note-2-32.s
|
||
|
||
-Relocation section '\.rela\.gnu\.build\.attributes' at offset .* contains 2 entries:
|
||
- 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
|
||
+There are no relocations in this file.
|
||
+#...
|
||
diff -rup binutils.orig/binutils/testsuite/binutils-all/mips/mips-note-2r-n64.d binutils-2.29.1/binutils/testsuite/binutils-all/mips/mips-note-2r-n64.d
|
||
--- binutils.orig/binutils/testsuite/binutils-all/mips/mips-note-2r-n64.d 2018-01-03 16:06:45.014656984 +0000
|
||
+++ binutils-2.29.1/binutils/testsuite/binutils-all/mips/mips-note-2r-n64.d 2018-01-03 16:06:57.927502748 +0000
|
||
@@ -5,11 +5,5 @@
|
||
#as: -64 -mips3
|
||
#source: ../note-2-64.s
|
||
|
||
-Relocation section '\.rela\.gnu\.build\.attributes' at offset .* contains 2 entries:
|
||
- 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
|
||
+There are no relocations in this file.
|
||
+#...
|
||
diff -rup binutils.orig/binutils/testsuite/binutils-all/note-2-32.d binutils-2.29.1/binutils/testsuite/binutils-all/note-2-32.d
|
||
--- binutils.orig/binutils/testsuite/binutils-all/note-2-32.d 2018-01-03 16:06:45.013656996 +0000
|
||
+++ binutils-2.29.1/binutils/testsuite/binutils-all/note-2-32.d 2018-01-03 16:06:57.927502748 +0000
|
||
@@ -6,12 +6,12 @@
|
||
|
||
#...
|
||
Owner Data size Description
|
||
-[ ]+\$<version>1[ ]+0x00000004[ ]+NT_GNU_BUILD_ATTRIBUTE_OPEN[ ]+Applies from offset 0x100 \(file: note1.s\)
|
||
-[ ]+\$<tool>gcc 7.0.1[ ]+0x00000000[ ]+NT_GNU_BUILD_ATTRIBUTE_OPEN[ ]+Applies from offset 0x100
|
||
-[ ]+\+<stack prot>true[ ]+0x00000000[ ]+NT_GNU_BUILD_ATTRIBUTE_OPEN[ ]+Applies from offset 0x100
|
||
-[ ]+\*<PIC>static[ ]+0x00000000[ ]+NT_GNU_BUILD_ATTRIBUTE_OPEN[ ]+Applies from offset 0x100
|
||
-[ ]+\*<ABI>0x0[ ]+0x00000000[ ]+NT_GNU_BUILD_ATTRIBUTE_OPEN[ ]+Applies from offset 0x100
|
||
-[ ]+\$<version>1[ ]+0x00000004[ ]+NT_GNU_BUILD_ATTRIBUTE_OPEN[ ]+Applies from offset 0x10. \(file: note2.s\)
|
||
-[ ]+!<stack prot>false[ ]+0x00000000[ ]+NT_GNU_BUILD_ATTRIBUTE_OPEN[ ]+Applies from offset 0x10.
|
||
-[ ]+\*<PIC>pic[ ]+0x00000000[ ]+NT_GNU_BUILD_ATTRIBUTE_FUNC[ ]+Applies to func at 0x10. \(func: func1\)
|
||
+[ ]+\$<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\)
|
||
#...
|
||
diff -rup binutils.orig/binutils/testsuite/binutils-all/note-2-32.s binutils-2.29.1/binutils/testsuite/binutils-all/note-2-32.s
|
||
--- binutils.orig/binutils/testsuite/binutils-all/note-2-32.s 2018-01-03 16:06:45.010657032 +0000
|
||
+++ binutils-2.29.1/binutils/testsuite/binutils-all/note-2-32.s 2018-01-03 16:06:57.927502748 +0000
|
||
@@ -2,7 +2,7 @@
|
||
.org 0x100
|
||
.global note1.s
|
||
note1.s:
|
||
- .word 0
|
||
+ .dc.l 0
|
||
|
||
.pushsection .gnu.build.attributes, "0x100000", %note
|
||
.balign 4
|
||
@@ -10,7 +10,7 @@ note1.s:
|
||
.dc.l 4
|
||
.dc.l 0x100
|
||
.asciz "$1"
|
||
- .dc.l note1.s
|
||
+ .dc.l 0x100
|
||
|
||
.dc.l 12
|
||
.dc.l 0
|
||
@@ -39,14 +39,14 @@ note1.s:
|
||
note2.s:
|
||
.type func1, STT_FUNC
|
||
func1:
|
||
- .word 0x100
|
||
+ .dc.l 0x100
|
||
|
||
.pushsection .gnu.build.attributes, "0x100000", %note
|
||
.dc.l 4
|
||
.dc.l 4
|
||
.dc.l 0x100
|
||
.asciz "$1"
|
||
- .dc.l note2.s
|
||
+ .dc.l 0x104
|
||
|
||
.dc.l 12
|
||
.dc.l 0
|
||
@@ -60,26 +60,28 @@ func1:
|
||
.dc.b 0
|
||
|
||
.dc.l 4
|
||
- .dc.l 0
|
||
+ .dc.l 4
|
||
.dc.l 0x101
|
||
.dc.b 0x2a, 0x7, 1, 0
|
||
-
|
||
+ .dc.l 0x104
|
||
+
|
||
.dc.l 4
|
||
.dc.l 0
|
||
.dc.l 0x100
|
||
.dc.b 0x2a, 0x6, 0, 0
|
||
.popsection
|
||
|
||
+
|
||
.global note3.s
|
||
note3.s:
|
||
- .word 0x100
|
||
+ .dc.l 0x100
|
||
|
||
.pushsection .gnu.build.attributes, "0x100000", %note
|
||
.dc.l 4
|
||
.dc.l 4
|
||
.dc.l 0x100
|
||
.asciz "$1"
|
||
- .dc.l note3.s
|
||
+ .dc.l 0x108
|
||
|
||
.dc.l 12
|
||
.dc.l 0
|
||
diff -rup binutils.orig/binutils/testsuite/binutils-all/note-2-64.d binutils-2.29.1/binutils/testsuite/binutils-all/note-2-64.d
|
||
--- binutils.orig/binutils/testsuite/binutils-all/note-2-64.d 2018-01-03 16:06:45.010657032 +0000
|
||
+++ binutils-2.29.1/binutils/testsuite/binutils-all/note-2-64.d 2018-01-03 16:06:57.927502748 +0000
|
||
@@ -6,12 +6,12 @@
|
||
|
||
#...
|
||
Owner Data size Description
|
||
-[ ]+\$<version>1[ ]+0x00000008[ ]+NT_GNU_BUILD_ATTRIBUTE_OPEN[ ]+Applies from offset 0x100 \(file: note1.s\)
|
||
-[ ]+\$<tool>gcc 7.0.1[ ]+0x00000000[ ]+NT_GNU_BUILD_ATTRIBUTE_OPEN[ ]+Applies from offset 0x100
|
||
-[ ]+\+<stack prot>true[ ]+0x00000000[ ]+NT_GNU_BUILD_ATTRIBUTE_OPEN[ ]+Applies from offset 0x100
|
||
-[ ]+\*<PIC>static[ ]+0x00000000[ ]+NT_GNU_BUILD_ATTRIBUTE_OPEN[ ]+Applies from offset 0x100
|
||
-[ ]+\*<ABI>0x0[ ]+0x00000000[ ]+NT_GNU_BUILD_ATTRIBUTE_OPEN[ ]+Applies from offset 0x100
|
||
-[ ]+\$<version>1[ ]+0x00000008[ ]+NT_GNU_BUILD_ATTRIBUTE_OPEN[ ]+Applies from offset 0x10. \(file: note2.s\)
|
||
-[ ]+!<stack prot>false[ ]+0x00000000[ ]+NT_GNU_BUILD_ATTRIBUTE_OPEN[ ]+Applies from offset 0x10.
|
||
-[ ]+\*<PIC>pic[ ]+0x00000000[ ]+NT_GNU_BUILD_ATTRIBUTE_FUNC[ ]+Applies to func at 0x10. \(func: func1\)
|
||
+[ ]+\$<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\)
|
||
#...
|
||
diff -rup binutils.orig/binutils/testsuite/binutils-all/note-2-64.s binutils-2.29.1/binutils/testsuite/binutils-all/note-2-64.s
|
||
--- binutils.orig/binutils/testsuite/binutils-all/note-2-64.s 2018-01-03 16:06:45.014656984 +0000
|
||
+++ binutils-2.29.1/binutils/testsuite/binutils-all/note-2-64.s 2018-01-03 16:06:57.927502748 +0000
|
||
@@ -2,7 +2,7 @@
|
||
.org 0x100
|
||
.global note1.s
|
||
note1.s:
|
||
- .word 0
|
||
+ .dc.l 0
|
||
|
||
.pushsection .gnu.build.attributes, "0x100000", %note
|
||
.balign 4
|
||
@@ -10,7 +10,7 @@ note1.s:
|
||
.dc.l 8
|
||
.dc.l 0x100
|
||
.asciz "$1"
|
||
- .8byte note1.s
|
||
+ .8byte 0x100
|
||
|
||
.dc.l 12
|
||
.dc.l 0
|
||
@@ -40,14 +40,14 @@ note2.s:
|
||
.global func1
|
||
.type func1, STT_FUNC
|
||
func1:
|
||
- .word 0x100
|
||
+ .dc.l 0x100
|
||
|
||
.pushsection .gnu.build.attributes, "0x100000", %note
|
||
.dc.l 4
|
||
.dc.l 8
|
||
.dc.l 0x100
|
||
.asciz "$1"
|
||
- .8byte note2.s
|
||
+ .8byte 0x104
|
||
|
||
.dc.l 12
|
||
.dc.l 0
|
||
@@ -61,9 +61,10 @@ func1:
|
||
.dc.b 0
|
||
|
||
.dc.l 4
|
||
- .dc.l 0
|
||
+ .dc.l 8
|
||
.dc.l 0x101
|
||
.dc.b 0x2a, 0x7, 1, 0
|
||
+ .8byte 0x104
|
||
|
||
.dc.l 4
|
||
.dc.l 0
|
||
@@ -74,14 +75,14 @@ func1:
|
||
|
||
.global note3.s
|
||
note3.s:
|
||
- .word 0x100
|
||
+ .dc.l 0x100
|
||
|
||
.pushsection .gnu.build.attributes, "0x100000", %note
|
||
.dc.l 4
|
||
.dc.l 8
|
||
.dc.l 0x100
|
||
.asciz "$1"
|
||
- .8byte note3.s
|
||
+ .8byte 0x108
|
||
|
||
.dc.l 12
|
||
.dc.l 0
|
||
diff -rup binutils.orig/binutils/testsuite/binutils-all/objcopy.exp binutils-2.29.1/binutils/testsuite/binutils-all/objcopy.exp
|
||
--- binutils.orig/binutils/testsuite/binutils-all/objcopy.exp 2018-01-03 16:06:45.013656996 +0000
|
||
+++ binutils-2.29.1/binutils/testsuite/binutils-all/objcopy.exp 2018-01-03 16:21:05.682365371 +0000
|
||
@@ -1056,8 +1056,10 @@ if [is_elf_format] {
|
||
run_dump_test "note-1"
|
||
if [is_elf64 tmpdir/bintest.o] {
|
||
run_dump_test "note-2-64"
|
||
+ run_dump_test "note-4-64"
|
||
} else {
|
||
run_dump_test "note-2-32"
|
||
+ run_dump_test "note-4-32"
|
||
}
|
||
}
|
||
|
||
|
||
--- /dev/null 2018-01-03 08:45:19.457895336 +0000
|
||
+++ binutils-2.29.1/binutils/testsuite/binutils-all/note-4-32.s 2018-01-03 16:36:13.314505682 +0000
|
||
@@ -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
|
||
--- /dev/null 2018-01-03 08:45:19.457895336 +0000
|
||
+++ binutils-2.29.1/binutils/testsuite/binutils-all/note-4-32.d 2018-01-03 16:36:13.313505694 +0000
|
||
@@ -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.*
|
||
+#...
|
||
--- /dev/null 2018-01-03 08:45:19.457895336 +0000
|
||
+++ binutils-2.29.1/binutils/testsuite/binutils-all/note-4-64.s 2018-01-03 16:36:07.041580738 +0000
|
||
@@ -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
|
||
--- /dev/null 2018-01-03 08:45:19.457895336 +0000
|
||
+++ binutils-2.29.1/binutils/testsuite/binutils-all/note-4-64.d 2018-01-03 16:36:07.041580738 +0000
|
||
@@ -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.*
|
||
+#...
|