diff options
author | Andreas Arnez <arnez@linux.vnet.ibm.com> | 2016-08-25 19:13:57 +0200 |
---|---|---|
committer | Andreas Arnez <arnez@linux.vnet.ibm.com> | 2016-08-25 19:13:57 +0200 |
commit | e3e9290d6c7bc276ac6a15a9d5793a49dde92c41 (patch) | |
tree | bdf42a9d34fd098dee36b7430f06273c32d2f87e | |
parent | ceada89664de30158de12d3d8f7bd7880ff6af29 (diff) | |
download | gdb-e3e9290d6c7bc276ac6a15a9d5793a49dde92c41.zip gdb-e3e9290d6c7bc276ac6a15a9d5793a49dde92c41.tar.gz gdb-e3e9290d6c7bc276ac6a15a9d5793a49dde92c41.tar.bz2 |
S390: Add support for core dump NOTE sections
This enhances the 32-bit and 64-bit s390 ELF backends with support for
reading and writing the core dump note sections NT_PRSTATUS and
NT_PRPSINFO. Byte swapping is done as appropriate, such that core files
can now be processed correctly on non-s390 platforms.
bfd/ChangeLog:
* elf32-s390.c (stdarg.h): New include.
(elf_s390_grok_psinfo): New function.
(elf_s390_write_core_note): New function.
(elf_backend_grok_psinfo): Declare backend hook.
(elf_backend_write_core_note): Likewise.
* elf64-s390.c (stdarg.h): New include.
(elf_s390_grok_prstatus): New function.
(elf_s390_grok_psinfo): New function.
(elf_s390_write_core_note): New function.
(elf_backend_grok_prstatus): Declare backend hook.
(elf_backend_grok_psinfo): Likewise.
(elf_backend_write_core_note): Likewise.
-rw-r--r-- | bfd/ChangeLog | 15 | ||||
-rw-r--r-- | bfd/elf32-s390.c | 88 | ||||
-rw-r--r-- | bfd/elf64-s390.c | 117 |
3 files changed, 220 insertions, 0 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 6f65e90..c2c49d1 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,5 +1,20 @@ 2016-08-25 Andreas Arnez <arnez@linux.vnet.ibm.com> + * elf32-s390.c (stdarg.h): New include. + (elf_s390_grok_psinfo): New function. + (elf_s390_write_core_note): New function. + (elf_backend_grok_psinfo): Declare backend hook. + (elf_backend_write_core_note): Likewise. + * elf64-s390.c (stdarg.h): New include. + (elf_s390_grok_prstatus): New function. + (elf_s390_grok_psinfo): New function. + (elf_s390_write_core_note): New function. + (elf_backend_grok_prstatus): Declare backend hook. + (elf_backend_grok_psinfo): Likewise. + (elf_backend_write_core_note): Likewise. + +2016-08-25 Andreas Arnez <arnez@linux.vnet.ibm.com> + * elf32-s390.c (allocate_dynrelocs): Fix indentation. (elf_s390_finish_ifunc_symbol): Likewise. (elf_s390_finish_dynamic_symbol): Likewise. diff --git a/bfd/elf32-s390.c b/bfd/elf32-s390.c index 170a450..b1627c9 100644 --- a/bfd/elf32-s390.c +++ b/bfd/elf32-s390.c @@ -25,6 +25,7 @@ #include "libbfd.h" #include "elf-bfd.h" #include "elf/s390.h" +#include <stdarg.h> static bfd_reloc_status_type s390_tls_reloc (bfd *, arelent *, asymbol *, void *, @@ -4039,6 +4040,8 @@ elf_s390_finish_dynamic_sections (bfd *output_bfd, } return TRUE; } + +/* Support for core dump NOTE sections. */ static bfd_boolean elf_s390_grok_prstatus (bfd * abfd, Elf_Internal_Note * note) @@ -4069,6 +4072,89 @@ elf_s390_grok_prstatus (bfd * abfd, Elf_Internal_Note * note) size, note->descpos + offset); } +static bfd_boolean +elf_s390_grok_psinfo (bfd *abfd, Elf_Internal_Note *note) +{ + switch (note->descsz) + { + default: + return FALSE; + + case 124: /* sizeof(struct elf_prpsinfo) on s390 */ + elf_tdata (abfd)->core->pid + = bfd_get_32 (abfd, note->descdata + 12); + elf_tdata (abfd)->core->program + = _bfd_elfcore_strndup (abfd, note->descdata + 28, 16); + elf_tdata (abfd)->core->command + = _bfd_elfcore_strndup (abfd, note->descdata + 44, 80); + break; + } + + /* Note that for some reason, a spurious space is tacked + onto the end of the args in some (at least one anyway) + implementations, so strip it off if it exists. */ + + { + char *command = elf_tdata (abfd)->core->command; + int n = strlen (command); + + if (0 < n && command[n - 1] == ' ') + command[n - 1] = '\0'; + } + + return TRUE; +} + +static char * +elf_s390_write_core_note (bfd *abfd, char *buf, int *bufsiz, + int note_type, ...) +{ + va_list ap; + + switch (note_type) + { + default: + return NULL; + + case NT_PRPSINFO: + { + char data[124] = { 0 }; + const char *fname, *psargs; + + va_start (ap, note_type); + fname = va_arg (ap, const char *); + psargs = va_arg (ap, const char *); + va_end (ap); + + strncpy (data + 28, fname, 16); + strncpy (data + 44, psargs, 80); + return elfcore_write_note (abfd, buf, bufsiz, "CORE", note_type, + &data, sizeof (data)); + } + + case NT_PRSTATUS: + { + char data[224] = { 0 }; + long pid; + int cursig; + const void *gregs; + + va_start (ap, note_type); + pid = va_arg (ap, long); + cursig = va_arg (ap, int); + gregs = va_arg (ap, const void *); + va_end (ap); + + bfd_put_16 (abfd, cursig, data + 12); + bfd_put_32 (abfd, pid, data + 24); + memcpy (data + 72, gregs, 144); + return elfcore_write_note (abfd, buf, bufsiz, "CORE", note_type, + &data, sizeof (data)); + } + } + /* NOTREACHED */ +} + /* Return address for Ith PLT stub in section PLT, for relocation REL or (bfd_vma) -1 if it should not be included. */ @@ -4134,6 +4220,8 @@ elf32_s390_merge_private_bfd_data (bfd *ibfd, bfd *obfd) #define elf_backend_size_dynamic_sections elf_s390_size_dynamic_sections #define elf_backend_init_index_section _bfd_elf_init_1_index_section #define elf_backend_grok_prstatus elf_s390_grok_prstatus +#define elf_backend_grok_psinfo elf_s390_grok_psinfo +#define elf_backend_write_core_note elf_s390_write_core_note #define elf_backend_plt_sym_val elf_s390_plt_sym_val #define elf_backend_add_symbol_hook elf_s390_add_symbol_hook #define elf_backend_sort_relocs_p elf_s390_elf_sort_relocs_p diff --git a/bfd/elf64-s390.c b/bfd/elf64-s390.c index 53f2d0e..fc7a337 100644 --- a/bfd/elf64-s390.c +++ b/bfd/elf64-s390.c @@ -25,6 +25,7 @@ #include "libbfd.h" #include "elf-bfd.h" #include "elf/s390.h" +#include <stdarg.h> /* In case we're on a 32-bit machine, construct a 64-bit "-1" value from smaller values. Start with zero, widen, *then* decrement. */ @@ -3843,7 +3844,120 @@ elf_s390_finish_dynamic_sections (bfd *output_bfd, return TRUE; } + +/* Support for core dump NOTE sections. */ +static bfd_boolean +elf_s390_grok_prstatus (bfd *abfd, Elf_Internal_Note *note) +{ + int offset; + size_t size; + + switch (note->descsz) + { + default: + return FALSE; + + case 336: /* sizeof(struct elf_prstatus) on s390x */ + /* pr_cursig */ + elf_tdata (abfd)->core->signal = bfd_get_16 (abfd, note->descdata + 12); + + /* pr_pid */ + elf_tdata (abfd)->core->lwpid = bfd_get_32 (abfd, note->descdata + 32); + + /* pr_reg */ + offset = 112; + size = 216; + break; + } + + /* Make a ".reg/999" section. */ + return _bfd_elfcore_make_pseudosection (abfd, ".reg", + size, note->descpos + offset); +} + +static bfd_boolean +elf_s390_grok_psinfo (bfd *abfd, Elf_Internal_Note *note) +{ + switch (note->descsz) + { + default: + return FALSE; + + case 136: /* sizeof(struct elf_prpsinfo) on s390x */ + elf_tdata (abfd)->core->pid + = bfd_get_32 (abfd, note->descdata + 24); + elf_tdata (abfd)->core->program + = _bfd_elfcore_strndup (abfd, note->descdata + 40, 16); + elf_tdata (abfd)->core->command + = _bfd_elfcore_strndup (abfd, note->descdata + 56, 80); + } + + /* Note that for some reason, a spurious space is tacked + onto the end of the args in some (at least one anyway) + implementations, so strip it off if it exists. */ + + { + char *command = elf_tdata (abfd)->core->command; + int n = strlen (command); + + if (0 < n && command[n - 1] == ' ') + command[n - 1] = '\0'; + } + + return TRUE; +} + +static char * +elf_s390_write_core_note (bfd *abfd, char *buf, int *bufsiz, + int note_type, ...) +{ + va_list ap; + + switch (note_type) + { + default: + return NULL; + + case NT_PRPSINFO: + { + char data[136] = { 0 }; + const char *fname, *psargs; + + va_start (ap, note_type); + fname = va_arg (ap, const char *); + psargs = va_arg (ap, const char *); + va_end (ap); + + strncpy (data + 40, fname, 16); + strncpy (data + 56, psargs, 80); + return elfcore_write_note (abfd, buf, bufsiz, "CORE", note_type, + &data, sizeof (data)); + } + + case NT_PRSTATUS: + { + char data[336] = { 0 }; + long pid; + int cursig; + const void *gregs; + + va_start (ap, note_type); + pid = va_arg (ap, long); + cursig = va_arg (ap, int); + gregs = va_arg (ap, const void *); + va_end (ap); + + bfd_put_16 (abfd, cursig, data + 12); + bfd_put_32 (abfd, pid, data + 32); + memcpy (data + 112, gregs, 216); + return elfcore_write_note (abfd, buf, bufsiz, "CORE", note_type, + &data, sizeof (data)); + } + } + /* NOTREACHED */ +} + /* Return address for Ith PLT stub in section PLT, for relocation REL or (bfd_vma) -1 if it should not be included. */ @@ -3942,6 +4056,9 @@ const struct elf_size_info s390_elf64_size_info = #define elf_backend_relocate_section elf_s390_relocate_section #define elf_backend_size_dynamic_sections elf_s390_size_dynamic_sections #define elf_backend_init_index_section _bfd_elf_init_1_index_section +#define elf_backend_grok_prstatus elf_s390_grok_prstatus +#define elf_backend_grok_psinfo elf_s390_grok_psinfo +#define elf_backend_write_core_note elf_s390_write_core_note #define elf_backend_plt_sym_val elf_s390_plt_sym_val #define elf_backend_add_symbol_hook elf_s390_add_symbol_hook #define elf_backend_sort_relocs_p elf_s390_elf_sort_relocs_p |