Message ID | 3335493.EfdzCE6qkf@ralph.baldwin.cx |
---|---|
State | New |
Headers | show |
On Tuesday, September 19, 2017 09:24:57 PM John Baldwin wrote: > On Wednesday, September 20, 2017 11:31:05 AM Alan Modra wrote: > > On Tue, Sep 19, 2017 at 01:48:12PM -0700, John Baldwin wrote: > > > The first patch to bfd/elf.c might be too hackish. > > > > Yeah, I dislike the inclusion of mips.h in elf.c. > > > > > Not sure if adding a > > > new 'bed' method for 'grok_freebsd_prstatus' is a better approach? > > > > Yes please. > > Ok, how about this: > > From 5a2f8adf9d03f0cb80d9bcc849150936bfd64687 Mon Sep 17 00:00:00 2001 > From: John Baldwin <jhb@FreeBSD.org> > Date: Mon, 18 Sep 2017 11:42:47 -0700 > Subject: [PATCH v2 1/2] Account for padding in FreeBSD/mipsn32 NT_PRSTATUS > notes. > To: gdb-patches@sourceware.org, > binutils@sourceware.org > > Add a new ELF backend method to grok FreeBSD NT_PRSTATUS core dump > notes. Define a method for MIPS N32 to override the default > elfcore_grok_freebsd_prstatus that accounts for additional padding > between pr_pid and pr_reg that is not present in other 32-bit FreeBSD > platforms. > > * elf-bfd.h (struct elf_backend_data): Add > `elf_backend_grok_freebsd_prstatus'. > * elf.c (elfcore_grok_freebsd_note): Call > `elf_backend_grok_freebsd_prstatus' to handle NT_PRSTATUS if > present. > * elfn32-mips.c (elf_n32_mips_grok_freebsd_prstatus): New > function. > (elf_backend_grok_freebsd_prstatus): Define. > * elfxx-target.h (elf_backend_grok_freebsd_prstatus): Define. > (elfNN_bed): Initialize `elf_backend_grok_freebsd_prstatus'. > --- > bfd/ChangeLog | 13 +++++++++++++ > bfd/elf-bfd.h | 5 +++++ > bfd/elf.c | 5 +++++ > bfd/elfn32-mips.c | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ > bfd/elfxx-target.h | 4 ++++ > 5 files changed, 81 insertions(+) > > diff --git a/bfd/ChangeLog b/bfd/ChangeLog > index 4c8c12cd46..033a634f28 100644 > --- a/bfd/ChangeLog > +++ b/bfd/ChangeLog > @@ -1,3 +1,16 @@ > +2017-09-19 John Baldwin <jhb@FreeBSD.org> > + > + * elf-bfd.h (struct elf_backend_data): Add > + `elf_backend_grok_freebsd_prstatus'. > + * elf.c (elfcore_grok_freebsd_note): Call > + `elf_backend_grok_freebsd_prstatus' to handle NT_PRSTATUS if > + present. > + * elfn32-mips.c (elf_n32_mips_grok_freebsd_prstatus): New > + function. > + (elf_backend_grok_freebsd_prstatus): Define. > + * elfxx-target.h (elf_backend_grok_freebsd_prstatus): Define. > + (elfNN_bed): Initialize `elf_backend_grok_freebsd_prstatus'. > + > 2017-09-19 Alan Modra <amodra@gmail.com> > > PR 21441 > diff --git a/bfd/elf-bfd.h b/bfd/elf-bfd.h > index fd08748ae2..399e298a8d 100644 > --- a/bfd/elf-bfd.h > +++ b/bfd/elf-bfd.h > @@ -1270,6 +1270,11 @@ struct elf_backend_data > bfd_boolean (*elf_backend_grok_psinfo) > (bfd *, Elf_Internal_Note *); > > + /* This function, if defined, is called when a "FreeBSD" NT_PRSTATUS > + note is found in a core file. */ > + bfd_boolean (*elf_backend_grok_freebsd_prstatus) > + (bfd *, Elf_Internal_Note *); > + > /* This function, if defined, is called to write a note to a corefile. */ > char *(*elf_backend_write_core_note) > (bfd *abfd, char *buf, int *bufsiz, int note_type, ...); > diff --git a/bfd/elf.c b/bfd/elf.c > index 2aa2337724..428506f862 100644 > --- a/bfd/elf.c > +++ b/bfd/elf.c > @@ -9970,9 +9970,14 @@ elfcore_grok_freebsd_prstatus (bfd *abfd, Elf_Internal_Note *note) > static bfd_boolean > elfcore_grok_freebsd_note (bfd *abfd, Elf_Internal_Note *note) > { > + const struct elf_backend_data *bed = get_elf_backend_data (abfd); > + > switch (note->type) > { > case NT_PRSTATUS: > + if (bed->elf_backend_grok_freebsd_prstatus) > + if ((*bed->elf_backend_grok_freebsd_prstatus) (abfd, note)) > + return TRUE; > return elfcore_grok_freebsd_prstatus (abfd, note); > > case NT_FPREGSET: > diff --git a/bfd/elfn32-mips.c b/bfd/elfn32-mips.c > index dce7ba1c7a..a8ccedaefc 100644 > --- a/bfd/elfn32-mips.c > +++ b/bfd/elfn32-mips.c > @@ -80,6 +80,8 @@ static bfd_boolean elf32_mips_grok_prstatus > (bfd *, Elf_Internal_Note *); > static bfd_boolean elf32_mips_grok_psinfo > (bfd *, Elf_Internal_Note *); > +static bfd_boolean elf_n32_mips_grok_freebsd_prstatus > + (bfd *, Elf_Internal_Note *); > static irix_compat_t elf_n32_mips_irix_compat > (bfd *); > > @@ -3578,6 +3580,56 @@ elf32_mips_grok_psinfo (bfd *abfd, Elf_Internal_Note *note) > > return TRUE; > } > + > +static bfd_boolean > +elf_n32_mips_grok_freebsd_prstatus (bfd *abfd, Elf_Internal_Note *note) > +{ > + size_t offset; > + size_t size; > + size_t min_size; > + > + /* Compute offset of pr_getregsz, skipping over pr_statussz. > + Also compute minimum size of this note. */ > + offset = 4 + 4; > + min_size = offset + (4 * 2) + 4 + 4 + 4; > + > + if (note->descsz < min_size) > + return FALSE; > + > + /* Check for version 1 in pr_version. */ > + if (bfd_h_get_32 (abfd, (bfd_byte *) note->descdata) != 1) > + return FALSE; > + > + /* Extract size of pr_reg from pr_gregsetsz. */ > + /* Skip over pr_gregsetsz and pr_fpregsetsz. */ > + size = bfd_h_get_32 (abfd, (bfd_byte *) note->descdata + offset); > + offset += 4 * 2; > + > + /* Skip over pr_osreldate. */ > + offset += 4; > + > + /* Read signal from pr_cursig. */ > + if (elf_tdata (abfd)->core->signal == 0) > + elf_tdata (abfd)->core->signal > + = bfd_h_get_32 (abfd, (bfd_byte *) note->descdata + offset); > + offset += 4; > + > + /* Read TID from pr_pid. */ > + elf_tdata (abfd)->core->lwpid > + = bfd_h_get_32 (abfd, (bfd_byte *) note->descdata + offset); > + offset += 4; > + > + /* Padding before pr_reg. */ > + offset += 4; > + > + /* Make sure that there is enough data remaining in the note. */ > + if ((note->descsz - offset) < size) > + return FALSE; > + > + /* Make a ".reg/999" section and a ".reg" section. */ > + return _bfd_elfcore_make_pseudosection (abfd, ".reg", > + size, note->descpos + offset); > +} > > /* Depending on the target vector we generate some version of Irix > executables or "normal" MIPS ELF ABI executables. */ > @@ -3684,6 +3736,8 @@ static const struct ecoff_debug_swap mips_elf32_ecoff_debug_swap = { > _bfd_mips_elf_copy_indirect_symbol > #define elf_backend_grok_prstatus elf32_mips_grok_prstatus > #define elf_backend_grok_psinfo elf32_mips_grok_psinfo > +#define elf_backend_grok_freebsd_prstatus \ > + elf_n32_mips_grok_freebsd_prstatus > #define elf_backend_ecoff_debug_swap &mips_elf32_ecoff_debug_swap > > #define elf_backend_got_header_size (4 * MIPS_RESERVED_GOTNO) > diff --git a/bfd/elfxx-target.h b/bfd/elfxx-target.h > index 551883fa09..6efca84e4e 100644 > --- a/bfd/elfxx-target.h > +++ b/bfd/elfxx-target.h > @@ -597,6 +597,9 @@ > #ifndef elf_backend_grok_psinfo > #define elf_backend_grok_psinfo NULL > #endif > +#ifndef elf_backend_grok_freebsd_prstatus > +#define elf_backend_grok_freebsd_prstatus NULL > +#endif > #ifndef elf_backend_write_core_note > #define elf_backend_write_core_note NULL > #endif > @@ -820,6 +823,7 @@ static struct elf_backend_data elfNN_bed = > elf_backend_sort_relocs_p, > elf_backend_grok_prstatus, > elf_backend_grok_psinfo, > + elf_backend_grok_freebsd_prstatus, > elf_backend_write_core_note, > elf_backend_lookup_section_flags_hook, > elf_backend_reloc_type_class, > Ping?
diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 4c8c12cd46..033a634f28 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,16 @@ +2017-09-19 John Baldwin <jhb@FreeBSD.org> + + * elf-bfd.h (struct elf_backend_data): Add + `elf_backend_grok_freebsd_prstatus'. + * elf.c (elfcore_grok_freebsd_note): Call + `elf_backend_grok_freebsd_prstatus' to handle NT_PRSTATUS if + present. + * elfn32-mips.c (elf_n32_mips_grok_freebsd_prstatus): New + function. + (elf_backend_grok_freebsd_prstatus): Define. + * elfxx-target.h (elf_backend_grok_freebsd_prstatus): Define. + (elfNN_bed): Initialize `elf_backend_grok_freebsd_prstatus'. + 2017-09-19 Alan Modra <amodra@gmail.com> PR 21441 diff --git a/bfd/elf-bfd.h b/bfd/elf-bfd.h index fd08748ae2..399e298a8d 100644 --- a/bfd/elf-bfd.h +++ b/bfd/elf-bfd.h @@ -1270,6 +1270,11 @@ struct elf_backend_data bfd_boolean (*elf_backend_grok_psinfo) (bfd *, Elf_Internal_Note *); + /* This function, if defined, is called when a "FreeBSD" NT_PRSTATUS + note is found in a core file. */ + bfd_boolean (*elf_backend_grok_freebsd_prstatus) + (bfd *, Elf_Internal_Note *); + /* This function, if defined, is called to write a note to a corefile. */ char *(*elf_backend_write_core_note) (bfd *abfd, char *buf, int *bufsiz, int note_type, ...); diff --git a/bfd/elf.c b/bfd/elf.c index 2aa2337724..428506f862 100644 --- a/bfd/elf.c +++ b/bfd/elf.c @@ -9970,9 +9970,14 @@ elfcore_grok_freebsd_prstatus (bfd *abfd, Elf_Internal_Note *note) static bfd_boolean elfcore_grok_freebsd_note (bfd *abfd, Elf_Internal_Note *note) { + const struct elf_backend_data *bed = get_elf_backend_data (abfd); + switch (note->type) { case NT_PRSTATUS: + if (bed->elf_backend_grok_freebsd_prstatus) + if ((*bed->elf_backend_grok_freebsd_prstatus) (abfd, note)) + return TRUE; return elfcore_grok_freebsd_prstatus (abfd, note); case NT_FPREGSET: diff --git a/bfd/elfn32-mips.c b/bfd/elfn32-mips.c index dce7ba1c7a..a8ccedaefc 100644 --- a/bfd/elfn32-mips.c +++ b/bfd/elfn32-mips.c @@ -80,6 +80,8 @@ static bfd_boolean elf32_mips_grok_prstatus (bfd *, Elf_Internal_Note *); static bfd_boolean elf32_mips_grok_psinfo (bfd *, Elf_Internal_Note *); +static bfd_boolean elf_n32_mips_grok_freebsd_prstatus + (bfd *, Elf_Internal_Note *); static irix_compat_t elf_n32_mips_irix_compat (bfd *); @@ -3578,6 +3580,56 @@ elf32_mips_grok_psinfo (bfd *abfd, Elf_Internal_Note *note) return TRUE; } + +static bfd_boolean +elf_n32_mips_grok_freebsd_prstatus (bfd *abfd, Elf_Internal_Note *note) +{ + size_t offset; + size_t size; + size_t min_size; + + /* Compute offset of pr_getregsz, skipping over pr_statussz. + Also compute minimum size of this note. */ + offset = 4 + 4; + min_size = offset + (4 * 2) + 4 + 4 + 4; + + if (note->descsz < min_size) + return FALSE; + + /* Check for version 1 in pr_version. */ + if (bfd_h_get_32 (abfd, (bfd_byte *) note->descdata) != 1) + return FALSE; + + /* Extract size of pr_reg from pr_gregsetsz. */ + /* Skip over pr_gregsetsz and pr_fpregsetsz. */ + size = bfd_h_get_32 (abfd, (bfd_byte *) note->descdata + offset); + offset += 4 * 2; + + /* Skip over pr_osreldate. */ + offset += 4; + + /* Read signal from pr_cursig. */ + if (elf_tdata (abfd)->core->signal == 0) + elf_tdata (abfd)->core->signal + = bfd_h_get_32 (abfd, (bfd_byte *) note->descdata + offset); + offset += 4; + + /* Read TID from pr_pid. */ + elf_tdata (abfd)->core->lwpid + = bfd_h_get_32 (abfd, (bfd_byte *) note->descdata + offset); + offset += 4; + + /* Padding before pr_reg. */ + offset += 4; + + /* Make sure that there is enough data remaining in the note. */ + if ((note->descsz - offset) < size) + return FALSE; + + /* Make a ".reg/999" section and a ".reg" section. */ + return _bfd_elfcore_make_pseudosection (abfd, ".reg", + size, note->descpos + offset); +} /* Depending on the target vector we generate some version of Irix executables or "normal" MIPS ELF ABI executables. */ @@ -3684,6 +3736,8 @@ static const struct ecoff_debug_swap mips_elf32_ecoff_debug_swap = { _bfd_mips_elf_copy_indirect_symbol #define elf_backend_grok_prstatus elf32_mips_grok_prstatus #define elf_backend_grok_psinfo elf32_mips_grok_psinfo +#define elf_backend_grok_freebsd_prstatus \ + elf_n32_mips_grok_freebsd_prstatus #define elf_backend_ecoff_debug_swap &mips_elf32_ecoff_debug_swap #define elf_backend_got_header_size (4 * MIPS_RESERVED_GOTNO) diff --git a/bfd/elfxx-target.h b/bfd/elfxx-target.h index 551883fa09..6efca84e4e 100644 --- a/bfd/elfxx-target.h +++ b/bfd/elfxx-target.h @@ -597,6 +597,9 @@ #ifndef elf_backend_grok_psinfo #define elf_backend_grok_psinfo NULL #endif +#ifndef elf_backend_grok_freebsd_prstatus +#define elf_backend_grok_freebsd_prstatus NULL +#endif #ifndef elf_backend_write_core_note #define elf_backend_write_core_note NULL #endif @@ -820,6 +823,7 @@ static struct elf_backend_data elfNN_bed = elf_backend_sort_relocs_p, elf_backend_grok_prstatus, elf_backend_grok_psinfo, + elf_backend_grok_freebsd_prstatus, elf_backend_write_core_note, elf_backend_lookup_section_flags_hook, elf_backend_reloc_type_class,