2007-08-24 Jan Kratochvil <jan.kratochvil@redhat.com>
authorJan Kratochvil <jan.kratochvil@redhat.com>
Fri, 24 Aug 2007 15:11:13 +0000 (15:11 +0000)
committerJan Kratochvil <jan.kratochvil@redhat.com>
Fri, 24 Aug 2007 15:11:13 +0000 (15:11 +0000)
* elf-bfd.h (struct elf_obj_tdata): New BUILD_ID_SIZE, BUILD_ID.
* elf.c (elfcore_read_notes): Split to ...
(elf_read_notes) ... here ...
(elf_parse_notes): ... and here.  Check `bfd_get_format (abfd)' with
the former subfunctions called only for BFD_CORE.
Call ELFOBJ_GROK_GNU_NOTE for BFD_OBJECT files with the owner "GNU".
(_bfd_elf_make_section_from_shdr): Call ELF_PARSE_NOTES for SHT_NOTEs.
(bfd_section_from_phdr): Update the call for renamed ELFCORE_READ_NOTES.
(elfobj_grok_gnu_build_id, elfobj_grok_gnu_note): New functions.
Code advisory: Roland McGrath

bfd/ChangeLog
bfd/elf-bfd.h
bfd/elf.c

index fa0b0af..24a56d9 100644 (file)
@@ -1,3 +1,16 @@
+2007-08-24  Jan Kratochvil  <jan.kratochvil@redhat.com>
+
+       * bfd/elf-bfd.h (struct elf_obj_tdata): New build_id_size, build_id.
+       * bfd/elf.c (elfcore_read_notes): Split to ...
+       (elf_read_notes) ... here ...
+       (elf_parse_notes): ... and here.  Check `bfd_get_format (abfd)' with
+       the former subfunctions called only for BFD_CORE.
+       Call ELFOBJ_GROK_GNU_NOTE for BFD_OBJECT files with the owner "GNU".
+       (_bfd_elf_make_section_from_shdr): Call ELF_PARSE_NOTES for SHT_NOTEs.
+       (bfd_section_from_phdr): Update the call for renamed ELFCORE_READ_NOTES.
+       (elfobj_grok_gnu_build_id, elfobj_grok_gnu_note): New functions.
+       Code advisory: Roland McGrath
+
 2007-08-24  Daniel Jacobowitz  <dan@codesourcery.com>
 
        * elf64-mips.c (elf_backend_sign_extend_vma): Define.
index dffb83b..5dea7f9 100644 (file)
@@ -1472,6 +1472,10 @@ struct elf_obj_tdata
   /* Called at the end of _bfd_elf_write_object_contents if not NULL.  */
   bfd_boolean (*after_write_object_contents) (bfd *);
   void *after_write_object_contents_info;
+
+  /* NT_GNU_BUILD_ID note type.  */
+  bfd_size_type build_id_size;
+  bfd_byte *build_id;
 };
 
 #define elf_tdata(bfd)         ((bfd) -> tdata.elf_obj_data)
index ae3af35..734801e 100644 (file)
--- a/bfd/elf.c
+++ b/bfd/elf.c
@@ -48,7 +48,9 @@ static int elf_sort_sections (const void *, const void *);
 static bfd_boolean assign_file_positions_except_relocs (bfd *, struct bfd_link_info *);
 static bfd_boolean prep_headers (bfd *);
 static bfd_boolean swap_out_syms (bfd *, struct bfd_strtab_hash **, int) ;
-static bfd_boolean elfcore_read_notes (bfd *, file_ptr, bfd_size_type) ;
+static bfd_boolean elf_read_notes (bfd *, file_ptr, bfd_size_type) ;
+static bfd_boolean elf_parse_notes (bfd *abfd, char *buf, size_t size,
+                                   file_ptr offset);
 
 /* Swap version information in and out.  The version information is
    currently size independent.  If that ever changes, this code will
@@ -899,6 +901,28 @@ _bfd_elf_make_section_from_shdr (bfd *abfd,
   if (! bfd_set_section_flags (abfd, newsect, flags))
     return FALSE;
 
+  /* We do not parse the PT_NOTE segments as we are interested even in the
+     separate debug info files which may have the segments offsets corrupted.
+     PT_NOTEs from the core files are currently not parsed using BFD.  */
+  if (hdr->sh_type == SHT_NOTE)
+    {
+      char *contents;
+
+      contents = bfd_malloc (hdr->sh_size);
+      if (!contents)
+       return FALSE;
+
+      if (!bfd_get_section_contents (abfd, hdr->bfd_section, contents, 0,
+                                    hdr->sh_size)
+         || !elf_parse_notes (abfd, contents, hdr->sh_size, -1))
+       {
+         free (contents);
+         return FALSE;
+       }
+      
+      free (contents);
+    }
+
   if ((flags & SEC_ALLOC) != 0)
     {
       Elf_Internal_Phdr *phdr;
@@ -2341,7 +2365,7 @@ bfd_section_from_phdr (bfd *abfd, Elf_Internal_Phdr *hdr, int index)
     case PT_NOTE:
       if (! _bfd_elf_make_section_from_phdr (abfd, hdr, index, "note"))
        return FALSE;
-      if (! elfcore_read_notes (abfd, hdr->p_offset, hdr->p_filesz))
+      if (! elf_read_notes (abfd, hdr->p_offset, hdr->p_filesz))
        return FALSE;
       return TRUE;
 
@@ -7713,6 +7737,32 @@ elfcore_grok_note (bfd *abfd, Elf_Internal_Note *note)
 }
 
 static bfd_boolean
+elfobj_grok_gnu_build_id (bfd *abfd, Elf_Internal_Note *note)
+{
+  elf_tdata (abfd)->build_id_size = note->descsz;
+  elf_tdata (abfd)->build_id = bfd_alloc (abfd, note->descsz);
+  if (elf_tdata (abfd)->build_id == NULL)
+    return FALSE;
+
+  memcpy (elf_tdata (abfd)->build_id, note->descdata, note->descsz);
+
+  return TRUE;
+}
+
+static bfd_boolean
+elfobj_grok_gnu_note (bfd *abfd, Elf_Internal_Note *note)
+{
+  switch (note->type)
+    {
+    default:
+      return TRUE;
+
+    case NT_GNU_BUILD_ID:
+      return elfobj_grok_gnu_build_id (abfd, note);
+    }
+}
+
+static bfd_boolean
 elfcore_netbsd_get_lwpid (Elf_Internal_Note *note, int *lwpidp)
 {
   char *cp;
@@ -8186,28 +8236,10 @@ elfcore_write_prxfpreg (bfd *abfd,
 }
 
 static bfd_boolean
-elfcore_read_notes (bfd *abfd, file_ptr offset, bfd_size_type size)
+elf_parse_notes (bfd *abfd, char *buf, size_t size, file_ptr offset)
 {
-  char *buf;
   char *p;
 
-  if (size <= 0)
-    return TRUE;
-
-  if (bfd_seek (abfd, offset, SEEK_SET) != 0)
-    return FALSE;
-
-  buf = bfd_malloc (size);
-  if (buf == NULL)
-    return FALSE;
-
-  if (bfd_bread (buf, size, abfd) != size)
-    {
-    error:
-      free (buf);
-      return FALSE;
-    }
-
   p = buf;
   while (p < buf + size)
     {
@@ -8224,25 +8256,66 @@ elfcore_read_notes (bfd *abfd, file_ptr offset, bfd_size_type size)
       in.descdata = in.namedata + BFD_ALIGN (in.namesz, 4);
       in.descpos = offset + (in.descdata - buf);
 
-      if (CONST_STRNEQ (in.namedata, "NetBSD-CORE"))
-       {
-         if (! elfcore_grok_netbsd_note (abfd, &in))
-           goto error;
-       }
-      else if (CONST_STRNEQ (in.namedata, "QNX"))
-       {
-         if (! elfcore_grok_nto_note (abfd, &in))
-           goto error;
-       }
-      else
-       {
-         if (! elfcore_grok_note (abfd, &in))
-           goto error;
+      switch (bfd_get_format (abfd))
+        {
+       default:
+         return TRUE;
+
+       case bfd_core:
+         if (CONST_STRNEQ (in.namedata, "NetBSD-CORE"))
+           {
+             if (! elfcore_grok_netbsd_note (abfd, &in))
+               return FALSE;
+           }
+         else if (CONST_STRNEQ (in.namedata, "QNX"))
+           {
+             if (! elfcore_grok_nto_note (abfd, &in))
+               return FALSE;
+           }
+         else
+           {
+             if (! elfcore_grok_note (abfd, &in))
+               return FALSE;
+           }
+         break;
+
+       case bfd_object:
+         if (in.namesz == sizeof "GNU" && strcmp (in.namedata, "GNU") == 0)
+           {
+             if (! elfobj_grok_gnu_note (abfd, &in))
+               return FALSE;
+           }
+         break;
        }
 
       p = in.descdata + BFD_ALIGN (in.descsz, 4);
     }
 
+  return TRUE;
+}
+
+static bfd_boolean
+elf_read_notes (bfd *abfd, file_ptr offset, bfd_size_type size)
+{
+  char *buf;
+
+  if (size <= 0)
+    return TRUE;
+
+  if (bfd_seek (abfd, offset, SEEK_SET) != 0)
+    return FALSE;
+
+  buf = bfd_malloc (size);
+  if (buf == NULL)
+    return FALSE;
+
+  if (bfd_bread (buf, size, abfd) != size
+      || !elf_parse_notes (abfd, buf, size, offset))
+    {
+      free (buf);
+      return FALSE;
+    }
+
   free (buf);
   return TRUE;
 }