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.
This commit is contained in:
parent
ceada89664
commit
e3e9290d6c
3 changed files with 220 additions and 0 deletions
|
@ -1,3 +1,18 @@
|
|||
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.
|
||||
|
|
|
@ -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
|
||||
|
|
117
bfd/elf64-s390.c
117
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
|
||||
|
|
Loading…
Reference in a new issue