From aa1ed4a93a2eb0fb90d274c15288f3aad1791f60 Mon Sep 17 00:00:00 2001 From: John Baldwin Date: Sun, 12 Jun 2016 08:56:31 -0700 Subject: [PATCH] Add elfcore_grok_freebsd_note to parse FreeBSD ELF core notes. Move parsing of FreeBSD-specific ELF core notes out of elfcore_grok_note into a new elfcore_grok_freebsd_note function. Add core note grok routines for FreeBSD's psinfo and prstatus notes while here rather than depending on the native handling in elfcore_grok_note. bfd/ChangeLog: * elf.c (elfcore_grok_note): Remove handling of NT_X86_XSTATE for FreeBSD. Remove case for NT_FREEBSD_THRMISC. (elfcore_grok_freebsd_psinfo): New function. (elfcore_grok_freebsd_prstatus): New function. (elfcore_grok_freebsd_note): New function. (elf_parse_notes): Use "elfcore_grok_freebsd_note" for "FreeBSD" notes. --- bfd/ChangeLog | 10 ++++ bfd/elf.c | 138 ++++++++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 139 insertions(+), 9 deletions(-) diff --git a/bfd/ChangeLog b/bfd/ChangeLog index a1d8ea9644c..4822e301246 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,13 @@ +2016-06-24 John Baldwin + + * elf.c (elfcore_grok_note): Remove handling of NT_X86_XSTATE for + FreeBSD. Remove case for NT_FREEBSD_THRMISC. + (elfcore_grok_freebsd_psinfo): New function. + (elfcore_grok_freebsd_prstatus): New function. + (elfcore_grok_freebsd_note): New function. + (elf_parse_notes): Use "elfcore_grok_freebsd_note" for "FreeBSD" + notes. + 2016-06-24 Joel Brobecker * elflink.c: Check the value of BFD_SUPPORTS_PLUGINS rather diff --git a/bfd/elf.c b/bfd/elf.c index aaf2b5351d3..cfcafaad90e 100644 --- a/bfd/elf.c +++ b/bfd/elf.c @@ -9327,9 +9327,6 @@ elfcore_grok_note (bfd *abfd, Elf_Internal_Note *note) if (note->namesz == 6 && strcmp (note->namedata, "LINUX") == 0) return elfcore_grok_xstatereg (abfd, note); - else if (note->namesz == 8 - && strcmp (note->namedata, "FreeBSD") == 0) - return elfcore_grok_xstatereg (abfd, note); else return TRUE; @@ -9485,12 +9482,6 @@ elfcore_grok_note (bfd *abfd, Elf_Internal_Note *note) return elfcore_make_note_pseudosection (abfd, ".note.linuxcore.siginfo", note); - case NT_FREEBSD_THRMISC: - if (note->namesz == 8 - && strcmp (note->namedata, "FreeBSD") == 0) - return elfcore_make_note_pseudosection (abfd, ".thrmisc", note); - else - return TRUE; } } @@ -9555,6 +9546,134 @@ elfobj_grok_stapsdt_note (bfd *abfd, Elf_Internal_Note *note) } } +static bfd_boolean +elfcore_grok_freebsd_psinfo (bfd *abfd, Elf_Internal_Note *note) +{ + size_t offset; + + /* Check for version 1 in pr_version. */ + if (bfd_h_get_32 (abfd, (bfd_byte *) note->descdata) != 1) + return FALSE; + offset = 4; + + /* Skip over pr_psinfosz. */ + switch (abfd->arch_info->bits_per_word) + { + case 32: + offset += 4; + break; + + case 64: + offset += 4; /* Padding before pr_psinfosz. */ + offset += 8; + break; + + default: + return FALSE; + } + + /* pr_fname is PRFNAMESZ (16) + 1 bytes in size. */ + elf_tdata (abfd)->core->program + = _bfd_elfcore_strndup (abfd, note->descdata + offset, 17); + offset += 17; + + /* pr_psargs is PRARGSZ (80) + 1 bytes in size. */ + elf_tdata (abfd)->core->command + = _bfd_elfcore_strndup (abfd, note->descdata + offset, 81); + + return TRUE; +} + +static bfd_boolean +elfcore_grok_freebsd_prstatus (bfd *abfd, Elf_Internal_Note *note) +{ + size_t offset; + size_t size; + + /* Check for version 1 in pr_version. */ + if (bfd_h_get_32 (abfd, (bfd_byte *) note->descdata) != 1) + return FALSE; + offset = 4; + + /* Skip over pr_statussz. */ + switch (abfd->arch_info->bits_per_word) + { + case 32: + offset += 4; + break; + + case 64: + offset += 4; /* Padding before pr_statussz. */ + offset += 8; + break; + + default: + return FALSE; + } + + /* Extract size of pr_reg from pr_gregsetsz. */ + if (abfd->arch_info->bits_per_word == 32) + size = bfd_h_get_32 (abfd, (bfd_byte *) note->descdata + offset); + else + size = bfd_h_get_64 (abfd, (bfd_byte *) note->descdata + offset); + + /* Skip over pr_gregsetsz and pr_fpregsetsz. */ + offset += (abfd->arch_info->bits_per_word / 8) * 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. */ + if (abfd->arch_info->bits_per_word == 64) + offset += 4; + + /* Make a ".reg/999" section and a ".reg" section. */ + return _bfd_elfcore_make_pseudosection (abfd, ".reg", + size, note->descpos + offset); +} + +static bfd_boolean +elfcore_grok_freebsd_note (bfd *abfd, Elf_Internal_Note *note) +{ + switch (note->type) + { + case NT_PRSTATUS: + return elfcore_grok_freebsd_prstatus (abfd, note); + + case NT_FPREGSET: + return elfcore_grok_prfpreg (abfd, note); + + case NT_PRPSINFO: + return elfcore_grok_freebsd_psinfo (abfd, note); + + case NT_FREEBSD_THRMISC: + if (note->namesz == 8) + return elfcore_make_note_pseudosection (abfd, ".thrmisc", note); + else + return TRUE; + + case NT_X86_XSTATE: + if (note->namesz == 8) + return elfcore_grok_xstatereg (abfd, note); + else + return TRUE; + + default: + return TRUE; + } +} + static bfd_boolean elfcore_netbsd_get_lwpid (Elf_Internal_Note *note, int *lwpidp) { @@ -10467,6 +10586,7 @@ elf_parse_notes (bfd *abfd, char *buf, size_t size, file_ptr offset) grokers[] = { GROKER_ELEMENT ("", elfcore_grok_note), + GROKER_ELEMENT ("FreeBSD", elfcore_grok_freebsd_note), GROKER_ELEMENT ("NetBSD-CORE", elfcore_grok_netbsd_note), GROKER_ELEMENT ( "OpenBSD", elfcore_grok_openbsd_note), GROKER_ELEMENT ("QNX", elfcore_grok_nto_note), -- 2.30.2