+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 + 1);
+ 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 == NT_NETBSDCORE_PROCINFO)
+ {
+ /* 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);
+ }
+
+ /* As of Jan 2002 there are no other machine-independent notes
+ defined for NetBSD 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 < NT_NETBSDCORE_FIRSTMACH)
+ 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 NT_NETBSDCORE_FIRSTMACH+0:
+ return elfcore_make_note_pseudosection (abfd, ".reg", note);
+
+ case NT_NETBSDCORE_FIRSTMACH+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 NT_NETBSDCORE_FIRSTMACH+1:
+ return elfcore_make_note_pseudosection (abfd, ".reg", note);
+
+ case NT_NETBSDCORE_FIRSTMACH+3:
+ return elfcore_make_note_pseudosection (abfd, ".reg2", note);
+
+ default:
+ return true;
+ }
+ }
+ /* NOTREACHED */
+}
+
+/* Function: elfcore_write_note
+
+ Inputs:
+ buffer to hold note
+ name of note
+ type of note
+ data for note
+ size of data for note
+
+ Return:
+ End of buffer containing note. */
+
+char *
+elfcore_write_note (abfd, buf, bufsiz, name, type, input, size)
+ bfd *abfd;
+ char *buf;
+ int *bufsiz;
+ char *name;
+ int type;
+ void *input;
+ int size;
+{
+ Elf_External_Note *xnp;
+ int namesz = strlen (name);
+ int newspace = BFD_ALIGN (sizeof (Elf_External_Note) + size + namesz - 1, 4);
+ char *p, *dest;
+
+ p = realloc (buf, *bufsiz + newspace);
+ dest = p + *bufsiz;
+ *bufsiz += newspace;
+ xnp = (Elf_External_Note *) dest;
+ H_PUT_32 (abfd, namesz, xnp->namesz);
+ H_PUT_32 (abfd, size, xnp->descsz);
+ H_PUT_32 (abfd, type, xnp->type);
+ strcpy (xnp->name, name);
+ memcpy (xnp->name + BFD_ALIGN (namesz, 4), input, size);
+ return p;
+}
+
+#if defined (HAVE_PRPSINFO_T) || defined (HAVE_PSINFO_T)
+char *
+elfcore_write_prpsinfo (abfd, buf, bufsiz, fname, psargs)
+ bfd *abfd;
+ char *buf;
+ int *bufsiz;
+ char *fname;
+ char *psargs;
+{
+ int note_type;
+ char *note_name = "CORE";
+
+#if defined (HAVE_PSINFO_T)
+ psinfo_t data;
+ note_type = NT_PSINFO;
+#else
+ prpsinfo_t data;
+ note_type = NT_PRPSINFO;
+#endif
+
+ memset (&data, 0, sizeof (data));
+ strncpy (data.pr_fname, fname, sizeof (data.pr_fname));
+ strncpy (data.pr_psargs, psargs, sizeof (data.pr_psargs));
+ return elfcore_write_note (abfd, buf, bufsiz,
+ note_name, note_type, &data, sizeof (data));
+}
+#endif /* PSINFO_T or PRPSINFO_T */
+
+#if defined (HAVE_PRSTATUS_T)
+char *
+elfcore_write_prstatus (abfd, buf, bufsiz, pid, cursig, gregs)
+ bfd *abfd;
+ char *buf;
+ int *bufsiz;
+ long pid;
+ int cursig;
+ void *gregs;
+{
+ prstatus_t prstat;
+ char *note_name = "CORE";
+
+ memset (&prstat, 0, sizeof (prstat));
+ prstat.pr_pid = pid;
+ prstat.pr_cursig = cursig;
+ memcpy (&prstat.pr_reg, gregs, sizeof (prstat.pr_reg));
+ return elfcore_write_note (abfd, buf, bufsiz,
+ note_name, NT_PRSTATUS, &prstat, sizeof (prstat));
+}
+#endif /* HAVE_PRSTATUS_T */
+
+#if defined (HAVE_LWPSTATUS_T)
+char *
+elfcore_write_lwpstatus (abfd, buf, bufsiz, pid, cursig, gregs)
+ bfd *abfd;
+ char *buf;
+ int *bufsiz;
+ long pid;
+ int cursig;
+ void *gregs;
+{
+ lwpstatus_t lwpstat;
+ char *note_name = "CORE";
+
+ memset (&lwpstat, 0, sizeof (lwpstat));
+ lwpstat.pr_lwpid = pid >> 16;
+ lwpstat.pr_cursig = cursig;
+#if defined (HAVE_LWPSTATUS_T_PR_REG)
+ memcpy (lwpstat.pr_reg, gregs, sizeof (lwpstat.pr_reg));
+#elif defined (HAVE_LWPSTATUS_T_PR_CONTEXT)
+#if !defined(gregs)
+ memcpy (lwpstat.pr_context.uc_mcontext.gregs,
+ gregs, sizeof (lwpstat.pr_context.uc_mcontext.gregs));
+#else
+ memcpy (lwpstat.pr_context.uc_mcontext.__gregs,
+ gregs, sizeof (lwpstat.pr_context.uc_mcontext.__gregs));
+#endif
+#endif
+ return elfcore_write_note (abfd, buf, bufsiz, note_name,
+ NT_LWPSTATUS, &lwpstat, sizeof (lwpstat));
+}
+#endif /* HAVE_LWPSTATUS_T */
+
+#if defined (HAVE_PSTATUS_T)
+char *
+elfcore_write_pstatus (abfd, buf, bufsiz, pid, cursig, gregs)
+ bfd *abfd;
+ char *buf;
+ int *bufsiz;
+ long pid;
+ int cursig;
+ void *gregs;
+{
+ pstatus_t pstat;
+ char *note_name = "CORE";
+
+ memset (&pstat, 0, sizeof (pstat));
+ pstat.pr_pid = pid & 0xffff;
+ buf = elfcore_write_note (abfd, buf, bufsiz, note_name,
+ NT_PSTATUS, &pstat, sizeof (pstat));
+ return buf;
+}
+#endif /* HAVE_PSTATUS_T */
+
+char *
+elfcore_write_prfpreg (abfd, buf, bufsiz, fpregs, size)
+ bfd *abfd;
+ char *buf;
+ int *bufsiz;
+ void *fpregs;
+ int size;
+{
+ char *note_name = "CORE";
+ return elfcore_write_note (abfd, buf, bufsiz,
+ note_name, NT_FPREGSET, fpregs, size);
+}
+
+char *
+elfcore_write_prxfpreg (abfd, buf, bufsiz, xfpregs, size)
+ bfd *abfd;
+ char *buf;
+ int *bufsiz;
+ void *xfpregs;
+ int size;
+{
+ char *note_name = "LINUX";
+ return elfcore_write_note (abfd, buf, bufsiz,
+ note_name, NT_PRXFPREG, xfpregs, size);
+}
+