* config.bfd (arm-*-netbsdelf*): Add target.
[deliverable/binutils-gdb.git] / bfd / elf.c
index cf13ad60afe57894b5f4c0e7f160a5f5a573103e..92b60071dc5987406b32255a30a8ebb56e216415 100644 (file)
--- a/bfd/elf.c
+++ b/bfd/elf.c
@@ -71,6 +71,11 @@ static boolean elfcore_grok_prfpreg PARAMS ((bfd *, Elf_Internal_Note *));
 static boolean elfcore_grok_prxfpreg PARAMS ((bfd *, Elf_Internal_Note *));
 static boolean elfcore_grok_note PARAMS ((bfd *, Elf_Internal_Note *));
 
+static boolean elfcore_netbsd_get_lwpid PARAMS ((Elf_Internal_Note *, int *));
+static boolean elfcore_grok_netbsd_procinfo PARAMS ((bfd *,
+                                                    Elf_Internal_Note *));
+static boolean elfcore_grok_netbsd_note PARAMS ((bfd *, Elf_Internal_Note *));
+
 /* Swap version information in and out.  The version information is
    currently size independent.  If that ever changes, this code will
    need to move into elfcode.h.  */
@@ -779,6 +784,28 @@ _bfd_elf_merge_sections (abfd, info)
   return true;
 }
 \f
+/* Copy the program header and other data from one object module to
+   another.  */
+
+boolean
+_bfd_elf_copy_private_bfd_data (ibfd, obfd)
+     bfd *ibfd;
+     bfd *obfd;
+{
+  if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
+      || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
+    return true;
+
+  BFD_ASSERT (!elf_flags_init (obfd)
+             || (elf_elfheader (obfd)->e_flags
+                 == elf_elfheader (ibfd)->e_flags));
+
+  elf_gp (obfd) = elf_gp (ibfd);
+  elf_elfheader (obfd)->e_flags = elf_elfheader (ibfd)->e_flags;
+  elf_flags_init (obfd) = true;
+  return true;
+}
+
 /* Print out the program headers.  */
 
 boolean
@@ -3272,8 +3299,13 @@ assign_file_positions_for_segments (abfd)
       asection **secpp;
 
       /* If elf_segment_map is not from map_sections_to_segments, the
-         sections may not be correctly ordered.  */
-      if (m->count > 0)
+         sections may not be correctly ordered.  NOTE: sorting should 
+        not be done to the PT_NOTE section of a corefile, which may
+        contain several pseudo-sections artificially created by bfd.
+        Sorting these pseudo-sections breaks things badly.  */
+      if (m->count > 1 
+         && !(elf_elfheader (abfd)->e_type == ET_CORE 
+              && m->p_type == PT_NOTE))
        qsort (m->sections, (size_t) m->count, sizeof (asection *),
               elf_sort_sections);
 
@@ -6352,6 +6384,109 @@ elfcore_grok_note (abfd, note)
     }
 }
 
+static boolean
+elfcore_netbsd_get_lwpid (note, lwpidp)
+     Elf_Internal_Note *note;
+     int *lwpidp;
+{
+  char *cp;
+
+  cp = strchr (note->namedata, '@');
+  if (cp != NULL)
+    {
+      *lwpidp = atoi(cp);
+      return true;
+    }
+  return false;
+}
+
+static boolean
+elfcore_grok_netbsd_procinfo (abfd, note)
+     bfd *abfd;
+     Elf_Internal_Note *note;
+{
+
+  /* Signal number at offset 0x08. */
+  elf_tdata (abfd)->core_signal
+    = bfd_h_get_32 (abfd, (bfd_byte *) note->descdata + 0x08);
+
+  /* Process ID at offset 0x50. */
+  elf_tdata (abfd)->core_pid
+    = bfd_h_get_32 (abfd, (bfd_byte *) note->descdata + 0x50);
+
+  /* Command name at 0x7c (max 32 bytes, including nul). */
+  elf_tdata (abfd)->core_command
+    = _bfd_elfcore_strndup (abfd, note->descdata + 0x7c, 31);
+
+  return true;
+}
+
+static boolean
+elfcore_grok_netbsd_note (abfd, note)
+     bfd *abfd;
+     Elf_Internal_Note *note;
+{
+  int lwp;
+
+  if (elfcore_netbsd_get_lwpid (note, &lwp))
+    elf_tdata (abfd)->core_lwpid = lwp;
+
+  if (note->type == 1)
+    {
+      /* NetBSD-specific core "procinfo".  Note that we expect to
+         find this note before any of the others, which is fine,
+         since the kernel writes this note out first when it
+         creates a core file.  */
+      
+      return elfcore_grok_netbsd_procinfo (abfd, note);
+    }
+
+  /* There are not currently any other machine-independent notes defined
+     for NetBSD ELF core files.  If the note type is less than the start
+     of the machine-dependent note types, we don't understand it.  */
+  
+  if (note->type < 32)
+    return true;
+
+
+  switch (bfd_get_arch (abfd))
+    {
+    /* On the Alpha, SPARC (32-bit and 64-bit), PT_GETREGS == mach+0 and
+       PT_GETFPREGS == mach+2.  */
+
+    case bfd_arch_alpha:
+    case bfd_arch_sparc:
+      switch (note->type)
+        {
+        case 32+0:
+          return elfcore_make_note_pseudosection (abfd, ".reg", note);
+
+        case 32+2:
+          return elfcore_make_note_pseudosection (abfd, ".reg2", note);
+
+        default:
+          return true;
+        }
+
+    /* On all other arch's, PT_GETREGS == mach+1 and
+       PT_GETFPREGS == mach+3.  */
+
+    default:
+      switch (note->type)
+        {
+        case 32+1:
+          return elfcore_make_note_pseudosection (abfd, ".reg", note);
+
+        case 32+3:
+          return elfcore_make_note_pseudosection (abfd, ".reg2", note);
+
+        default:
+          return true;
+        }
+    }
+    /* NOTREACHED */
+}
+
 static boolean
 elfcore_read_notes (abfd, offset, size)
      bfd *abfd;
@@ -6394,8 +6529,16 @@ elfcore_read_notes (abfd, offset, size)
       in.descdata = in.namedata + BFD_ALIGN (in.namesz, 4);
       in.descpos = offset + (in.descdata - buf);
 
-      if (! elfcore_grok_note (abfd, &in))
-       goto error;
+      if (strncmp (in.namedata, "NetBSD-CORE", 11) == 0)
+        {
+          if (! elfcore_grok_netbsd_note (abfd, &in))
+            goto error;
+        }
+      else
+        {
+          if (! elfcore_grok_note (abfd, &in))
+            goto error;
+        }
 
       p = in.descdata + BFD_ALIGN (in.descsz, 4);
     }
This page took 0.026641 seconds and 4 git commands to generate.