Add support for v3 binary annotation notes.
authorNick Clifton <nickc@redhat.com>
Wed, 3 Jan 2018 10:28:33 +0000 (10:28 +0000)
committerNick Clifton <nickc@redhat.com>
Wed, 3 Jan 2018 10:30:07 +0000 (10:30 +0000)
  I am checking in the attached patch which updates the binutils
  support for version 3 binary annotation notes.  (Version 3 adds
  an end address to the ranges covered by the notes, so that it
  is possible to detect gaps in the coverage).

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

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

19 files changed:
binutils/ChangeLog
binutils/objcopy.c
binutils/readelf.c
binutils/testsuite/binutils-all/mips/mips-note-2r-n32.d
binutils/testsuite/binutils-all/mips/mips-note-2r-n64.d
binutils/testsuite/binutils-all/mips/mips-note-2r.d
binutils/testsuite/binutils-all/note-2-32.d
binutils/testsuite/binutils-all/note-2-32.s
binutils/testsuite/binutils-all/note-2-64.d
binutils/testsuite/binutils-all/note-2-64.s
binutils/testsuite/binutils-all/note-3-32.d
binutils/testsuite/binutils-all/note-3-32.s
binutils/testsuite/binutils-all/note-3-64.d
binutils/testsuite/binutils-all/note-3-64.s
binutils/testsuite/binutils-all/note-4-32.d [new file with mode: 0644]
binutils/testsuite/binutils-all/note-4-32.s [new file with mode: 0644]
binutils/testsuite/binutils-all/note-4-64.d [new file with mode: 0644]
binutils/testsuite/binutils-all/note-4-64.s [new file with mode: 0644]
binutils/testsuite/binutils-all/objcopy.exp

index 2b8e7c575c22a7f15fb91faa33efe069db5bd745..8771aeca99fc1507f0d1b54be09a0559e9c4cfa5 100644 (file)
@@ -1,3 +1,41 @@
+2018-01-03  Nick Clifton  <nickc@redhat.com>
+
+       * objcopy.c (objcopy_internal_note): New structure.
+       (gap_exists): New function.
+       (is_open_note): New function.
+       (is_func_note): New function.
+       (is_64bit): New function.
+       (merge_gnu_build_notes): Handle v3 notes.  Do not merge
+       if there are relocations against the notes.
+       * readelf.c (get_note_type): Use short names for build attribute
+       notes.
+       (print_symbol_for_build_attribute): Rename to
+       get_symbol_for_build_attribute.  Returns the found symbol rather
+       than printing it.
+       (print_gnu_build_attribute_description): Maintain address ranges
+       for function notes as well as global notes.  Handle v3 notes.
+       (print_gnu_build_attribute_name): Use more space for printing the
+       name in wide mode.
+       * testsuite/binutils-all/note-2-32.s: Use .dc.l instead of .word.
+       Eliminate symbol references in order to remove the need for
+       relocations.
+       * testsuite/binutils-all/note-2-64.s: Likewise.
+       * testsuite/binutils-all/note-3-32.s: Add a size to the note_1
+       symbol.
+       * testsuite/binutils-all/note-3-64.s: Likewise.
+       * testsuite/binutils-all/mips/mips-note-2r-n32.d: Update expected
+       output.
+       * testsuite/binutils-all/mips/mips-note-2r-n64.d: Likewise.
+       * testsuite/binutils-all/mips/mips-note-2r.d: Likewise.
+       * testsuite/binutils-all/note-2-32.d: Likewise.
+       * testsuite/binutils-all/note-2-64.d: Likewise.
+       * testsuite/binutils-all/note-3-32.d: Likewise.
+       * testsuite/binutils-all/note-3-64.d: Likewise.
+       * testsuite/binutils-all/note-4-64.s: New test.  Checks v3 notes.
+       * testsuite/binutils-all/note-4-32.s: New test.
+       * testsuite/binutils-all/note-4-64.d: New test result file.
+       * testsuite/binutils-all/note-4-32.d: New test result file.
+
 2018-01-03  Alan Modra  <amodra@gmail.com>
 
        Update year range in copyright notice of all files.
index 17b91bf090eecf290d6abfb680e1af39eb6b1166..77193b155e376cfb17e1bc072a8d6cf8f00f7b71 100644 (file)
@@ -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;
+
+      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->type    != NT_GNU_BUILD_ATTRIBUTE_OPEN
-         && pnote->type != NT_GNU_BUILD_ATTRIBUTE_FUNC)
+      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;
+
+         if (end)
+           previous_open_end = end;
 
-      remain -= 12 + pnote->namesz + pnote->descsz;
-      in     += 12 + pnote->namesz + pnote->descsz;
+         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->namedata[pnote->namesz - 1] != 0)
+      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, asection * sec, bfd_size_type size, bfd_byte
       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, asection * sec, bfd_size_type size, bfd_byte
      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, asection * sec, bfd_size_type size, bfd_byte
        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 (back->type == pnote->type
-             && back->namedata[attribute_type_byte] == pnote->namedata[attribute_type_byte])
-           {
-             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->namesz - val_start,
-                        name = (unsigned char *) pnote->namedata + val_start;
-                      bytes--;)
-                   {
-                     byte = (* name ++) & 0xff;
-                     note_val |= byte << shift;
-                     shift += 8;
-                   }
+         /* 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;
 
-                 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;
-                   }
+         if (! is_open_note (back))
+           continue;
 
-                 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;
-                   }
+         /* If the two notes are different then keep on searching.  */
+         if (back_type != note_type)
+           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;
+         /* Rule 4 - combine stack size notes.  */
+         if (back_type == 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--;)
+               {
+                 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, asection * sec, bfd_size_type size, bfd_byte
       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, asection * sec, bfd_size_type size, bfd_byte
           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)
+                   {
+                     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
                    {
-                     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, 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, asection * sec, bfd_size_type size, bfd_byte
       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:
index f221cce32a948b489977cc3199f5da1a66413fb3..ae1cda9a7bd54b85f085d1bb48f8b2c4bf5f0d46 100644 (file)
@@ -16594,9 +16594,9 @@ get_note_type (Filedata * filedata, 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;
       }
@@ -17416,13 +17416,16 @@ print_ia64_vms_note (Elf_Internal_Note * pnote)
   return TRUE;
 }
 
-/* Print the name of the symbol associated with a build attribute
-   that is attached to address OFFSET.  */
+/* 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 bfd_boolean
-print_symbol_for_build_attribute (Filedata *     filedata,
-                                 unsigned long  offset,
-                                 bfd_boolean    is_open_attr)
+static Elf_Internal_Sym *
+get_symbol_for_build_attribute (Filedata *       filedata,
+                               unsigned long    offset,
+                               bfd_boolean      is_open_attr,
+                               const char **    pname)
 {
   static Filedata *         saved_filedata = NULL;
   static char *             strtab;
@@ -17461,10 +17464,7 @@ print_symbol_for_build_attribute (Filedata *     filedata,
     }
 
   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 ++)
@@ -17484,14 +17484,15 @@ print_symbol_for_build_attribute (Filedata *     filedata,
               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:
@@ -17529,55 +17530,118 @@ print_symbol_for_build_attribute (Filedata *     filedata,
          }
       }
 
-  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,
                                       Filedata *           filedata)
 {
-  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;
+  static unsigned long  global_offset = 0;
+  static unsigned long  global_end = 0;
+  static unsigned long  func_offset = 0;
+  static unsigned long  func_end = 0;
 
-  if (pnote->descsz == 0)
+  Elf_Internal_Sym *    sym;
+  const char *          name;
+  unsigned long         start;
+  unsigned long         end;
+  bfd_boolean           is_open_attr = pnote->type == NT_GNU_BUILD_ATTRIBUTE_OPEN;
+
+  switch (pnote->descsz)
     {
+    case 0:
+      /* A zero-length description means that the range of
+        the previous note of the same type should be used.  */
       if (is_open_attr)
        {
-         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 (filedata, 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 (filedata, 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 (filedata, offset, is_open_attr);
+  if (sym && name)
+    printf (_(" (%s)"), name);
+
+  printf ("\n");
+  return TRUE;
 }
 
 static bfd_boolean
@@ -17600,11 +17664,21 @@ print_gnu_build_attribute_name (Elf_Internal_Note * pnote)
       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;
index caf99722a176038dcaa9f69d12a8f779ca0bdcc7..e76466eb9450044060d45aa421dbef7017758b7c 100644 (file)
@@ -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.
+#...
index 0fbcc390a87961491c5370a78088b3eb8a6e1485..033dd9b5b07a8e26074494cc271f45db6d43ad08 100644 (file)
@@ -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.
+#...
index c025727cf60ebb64ec6d752ac8644664a8044d45..c1305289363d0b1134d153b82f5581d989687aa8 100644 (file)
@@ -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.
+#...
index 8deb7f6c93da3e7d6cfdae40bb0b3870be6d6bdc..a6840322e07a6f176becde3437c9d8d75f63437c 100644 (file)
@@ -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\)
 #...
index 9aed3df346c245e5836d2cd03097779d05ec69b4..7b025ae8de1fcf632ff85aa6d40b2fef160a6369 100644 (file)
@@ -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 "$\ 11"
-       .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 "$\ 11"    
-       .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 "$\ 11"    
-       .dc.l note3.s
+       .dc.l 0x108
 
        .dc.l 12        
        .dc.l 0         
index f9be89756aee329b690cabfef8c1372d974fb5ec..17917d59c6a2d446eb4970309e72992603d7d44c 100644 (file)
 
 #...
   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\)
 #...
index 885e9477607bcc9e625fe400de3140175de376af..02b84e43710940f864f3098720bd486b2ebac56b 100644 (file)
@@ -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 "$\ 11"
-       .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 "$\ 11"    
-       .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 "$\ 11"    
-       .8byte note3.s
+       .8byte 0x108
 
        .dc.l 12        
        .dc.l 0         
index fa571b0a38863a305749dd54c07e24f83fb8dea3..e35e9cc2705b994d9ed08e7aa4cf28eed696b043 100644 (file)
@@ -7,12 +7,12 @@
 #...
 Displaying notes found in: .gnu.build.attributes
 [      ]+Owner[        ]+Data size[    ]+Description
-[      ]+GA\$<version>2p1[     ]+0x0000000.[   ]+NT_GNU_BUILD_ATTRIBUTE_OPEN[  ]+Applies from offset 0x100 \(file: note_1.s\)
-[      ]+GA\$<tool>gcc 6.3.1 20161221[         ]+0x00000000[   ]+NT_GNU_BUILD_ATTRIBUTE_OPEN[  ]+Applies from offset 0x100
-[      ]+GA\*GOW:0x700[        ]+0x00000000[   ]+NT_GNU_BUILD_ATTRIBUTE_OPEN[  ]+Applies from offset 0x100
-[      ]+GA\*<stack prot>off[  ]+0x00000000[   ]+NT_GNU_BUILD_ATTRIBUTE_OPEN[  ]+Applies from offset 0x100
-[      ]+GA\*FORTIFY:0xff[     ]+0x00000000[   ]+NT_GNU_BUILD_ATTRIBUTE_OPEN[  ]+Applies from offset 0x100
-[      ]+GA\*<PIC>PIC[         ]+0x00000000[   ]+NT_GNU_BUILD_ATTRIBUTE_OPEN[  ]+Applies from offset 0x100
-[      ]+GA\!<short enum>false[        ]+0x00000000[   ]+NT_GNU_BUILD_ATTRIBUTE_OPEN[  ]+Applies from offset 0x100
-[      ]+GA\*<ABI>0x[0-9a-f]+[         ]+0x00000000[   ]+NT_GNU_BUILD_ATTRIBUTE_OPEN[  ]+Applies from offset 0x100
+[      ]+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\*<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\*<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
 #...
index 4dbbebea2bb1647f50b69a162e00020fc5703944..e2e06f9c7966010c0a858de300f637190e38c910 100644 (file)
@@ -1,6 +1,7 @@
        .text
        .org 0x100
        .global note_1.s
+       .size   note_1.s, 0x22
 note_1.s:
        .word 0
        
index f048e8b86f02fc69b8a7699b614786bc92f45e2a..9899ea16097b7c7389a6c0624c847400ecd80029 100644 (file)
@@ -7,12 +7,12 @@
 #...
 Displaying notes found in: .gnu.build.attributes
 [      ]+Owner[        ]+Data size[    ]+Description
-[      ]+GA\$<version>2p1[     ]+0x0000000.[   ]+NT_GNU_BUILD_ATTRIBUTE_OPEN[  ]+Applies from offset 0x100 \(file: note_1.s\)
-[      ]+GA\$<tool>gcc 6.3.1 20161221[         ]+0x00000000[   ]+NT_GNU_BUILD_ATTRIBUTE_OPEN[  ]+Applies from offset 0x100
-[      ]+GA\*GOW:0x700[        ]+0x00000000[   ]+NT_GNU_BUILD_ATTRIBUTE_OPEN[  ]+Applies from offset 0x100
-[      ]+GA\*<stack prot>off[  ]+0x00000000[   ]+NT_GNU_BUILD_ATTRIBUTE_OPEN[  ]+Applies from offset 0x100
-[      ]+GA\*FORTIFY:0xff[     ]+0x00000000[   ]+NT_GNU_BUILD_ATTRIBUTE_OPEN[  ]+Applies from offset 0x100
-[      ]+GA\*<PIC>PIC[         ]+0x00000000[   ]+NT_GNU_BUILD_ATTRIBUTE_OPEN[  ]+Applies from offset 0x100
-[      ]+GA\!<short enum>false[        ]+0x00000000[   ]+NT_GNU_BUILD_ATTRIBUTE_OPEN[  ]+Applies from offset 0x100
-[      ]+GA\*<ABI>0x[0-9a-f]+[         ]+0x00000000[   ]+NT_GNU_BUILD_ATTRIBUTE_OPEN[  ]+Applies from offset 0x100
+[      ]+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\*<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\*<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
 #...
index 42f3e48422df2b79b30d3e2ae169e6184645ea71..e7d27d28ded3dfe44999c5660b265d430641209b 100644 (file)
@@ -1,6 +1,7 @@
        .text
        .org 0x100
        .global note_1.s
+       .size   note_1.s, 0x22
 note_1.s:
        .word 0
        
diff --git a/binutils/testsuite/binutils-all/note-4-32.d b/binutils/testsuite/binutils-all/note-4-32.d
new file mode 100644 (file)
index 0000000..567af90
--- /dev/null
@@ -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.*
+#...
diff --git a/binutils/testsuite/binutils-all/note-4-32.s b/binutils/testsuite/binutils-all/note-4-32.s
new file mode 100644 (file)
index 0000000..09c5652
--- /dev/null
@@ -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$\ 13p3"
+       .dc.l note_4.s
+       .dc.l note_4.s_end
+
+       .dc.l 23
+       .dc.l 0
+       .dc.l 0x100
+       .asciz "GA$\ 5gcc 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
diff --git a/binutils/testsuite/binutils-all/note-4-64.d b/binutils/testsuite/binutils-all/note-4-64.d
new file mode 100644 (file)
index 0000000..f81c9c4
--- /dev/null
@@ -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.*
+#...
diff --git a/binutils/testsuite/binutils-all/note-4-64.s b/binutils/testsuite/binutils-all/note-4-64.s
new file mode 100644 (file)
index 0000000..4f53298
--- /dev/null
@@ -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$\ 13p3"
+       .8byte note_4.s
+       .8byte note_4.s_end
+
+       .dc.l 23
+       .dc.l 0
+       .dc.l 0x100
+       .asciz "GA$\ 5gcc 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
index 8308adcb03dfe0d92209654f38adc0b67930b29d..377f88c0e16de365e543d40791306c5fdfab2a39 100644 (file)
@@ -1056,9 +1056,11 @@ if [is_elf_format] {
     if [is_elf64 tmpdir/bintest.o] {
        run_dump_test "note-2-64"
        run_dump_test "note-3-64"
+       run_dump_test "note-4-64"
     } else {
        run_dump_test "note-2-32"
        run_dump_test "note-3-32"
+       run_dump_test "note-4-32"
     }
 }