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:
Andreas Arnez 2016-08-25 19:13:57 +02:00
parent ceada89664
commit e3e9290d6c
3 changed files with 220 additions and 0 deletions

View file

@ -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.

View file

@ -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

View file

@ -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