From 183e98bed26941bb85b3170a4620ac32b1f8f686 Mon Sep 17 00:00:00 2001 From: Alan Modra Date: Thu, 1 Feb 2007 05:35:58 +0000 Subject: * elf-bfd.h (struct elf_backend_data): Add elf_backend_write_core_note. * elfxx-target.h (elf_backend_write_core_note): Define and use. * elf.c (elfcore_write_prpsinfo): Call the above. Add support for 32-bit core note on 64-bit target. (elfcore_write_prstatus): Likewise. (elfcore_write_lwpstatus): Make note_name const. (elfcore_write_prfpreg): Likewise. (elfcore_write_pstatus): Add support for 32-bit core note on 64-bit target. * elf32-ppc.c (ppc_elf_write_core_note): New function. (elf_backend_write_core_note): Define. * elf64-ppc.c (ppc64_elf_write_core_note): New function. (elf_backend_write_core_note): Define. --- bfd/ChangeLog | 16 +++++++ bfd/elf-bfd.h | 8 +++- bfd/elf.c | 131 +++++++++++++++++++++++++++++++++++++++++------------ bfd/elf32-ppc.c | 48 ++++++++++++++++++++ bfd/elf64-ppc.c | 49 ++++++++++++++++++++ bfd/elfxx-target.h | 4 ++ 6 files changed, 226 insertions(+), 30 deletions(-) diff --git a/bfd/ChangeLog b/bfd/ChangeLog index bd3d38d..9a76b7b 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,19 @@ +2007-02-01 Alan Modra + + * elf-bfd.h (struct elf_backend_data): Add elf_backend_write_core_note. + * elfxx-target.h (elf_backend_write_core_note): Define and use. + * elf.c (elfcore_write_prpsinfo): Call the above. Add support for + 32-bit core note on 64-bit target. + (elfcore_write_prstatus): Likewise. + (elfcore_write_lwpstatus): Make note_name const. + (elfcore_write_prfpreg): Likewise. + (elfcore_write_pstatus): Add support for 32-bit core note on 64-bit + target. + * elf32-ppc.c (ppc_elf_write_core_note): New function. + (elf_backend_write_core_note): Define. + * elf64-ppc.c (ppc64_elf_write_core_note): New function. + (elf_backend_write_core_note): Define. + 2076-01-31 H.J. Lu * elf32-cris.c (INCLUDED_TARGET_FILE): Removed. diff --git a/bfd/elf-bfd.h b/bfd/elf-bfd.h index 2d0fd35..3798322 100644 --- a/bfd/elf-bfd.h +++ b/bfd/elf-bfd.h @@ -924,15 +924,19 @@ struct elf_backend_data (asection *, Elf_Internal_Rela *); /* This function, if defined, is called when an NT_PRSTATUS note is found - in a core file. */ + in a core file. */ bfd_boolean (*elf_backend_grok_prstatus) (bfd *, Elf_Internal_Note *); /* This function, if defined, is called when an NT_PSINFO or NT_PRPSINFO - note is found in a core file. */ + note is found in a core file. */ bfd_boolean (*elf_backend_grok_psinfo) (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, ...); + /* Functions to print VMAs. Special code to handle 64 bit ELF files. */ void (* elf_backend_sprintf_vma) (bfd *, char *, bfd_vma); diff --git a/bfd/elf.c b/bfd/elf.c index 61e6103..66aa1c7 100644 --- a/bfd/elf.c +++ b/bfd/elf.c @@ -8211,22 +8211,52 @@ elfcore_write_prpsinfo (bfd *abfd, const char *fname, const char *psargs) { - int note_type; - char *note_name = "CORE"; + const char *note_name = "CORE"; + const struct elf_backend_data *bed = get_elf_backend_data (abfd); + + if (bed->elf_backend_write_core_note != NULL) + { + char *ret; + ret = (*bed->elf_backend_write_core_note) (abfd, buf, bufsiz, + NT_PRPSINFO, fname, psargs); + if (ret != NULL) + return ret; + } +#if defined (HAVE_PRPSINFO32_T) || defined (HAVE_PSINFO32_T) + if (bed->s->elfclass == ELFCLASS32) + { +#if defined (HAVE_PSINFO32_T) + psinfo32_t data; + int note_type = NT_PSINFO; +#else + prpsinfo32_t data; + int note_type = NT_PRPSINFO; +#endif + + memset (&data, 0, sizeof (data)); + strncpy (data.pr_fname, fname, sizeof (data.pr_fname)); + strncpy (data.pr_psargs, psargs, sizeof (data.pr_psargs)); + return elfcore_write_note (abfd, buf, bufsiz, + note_name, note_type, &data, sizeof (data)); + } + else +#endif + { #if defined (HAVE_PSINFO_T) - psinfo_t data; - note_type = NT_PSINFO; + psinfo_t data; + int note_type = NT_PSINFO; #else - prpsinfo_t data; - note_type = NT_PRPSINFO; + prpsinfo_t data; + int note_type = NT_PRPSINFO; #endif - memset (&data, 0, sizeof (data)); - strncpy (data.pr_fname, fname, sizeof (data.pr_fname)); - strncpy (data.pr_psargs, psargs, sizeof (data.pr_psargs)); - return elfcore_write_note (abfd, buf, bufsiz, - note_name, note_type, &data, sizeof (data)); + memset (&data, 0, sizeof (data)); + strncpy (data.pr_fname, fname, sizeof (data.pr_fname)); + strncpy (data.pr_psargs, psargs, sizeof (data.pr_psargs)); + return elfcore_write_note (abfd, buf, bufsiz, + note_name, note_type, &data, sizeof (data)); + } } #endif /* PSINFO_T or PRPSINFO_T */ @@ -8239,15 +8269,43 @@ elfcore_write_prstatus (bfd *abfd, int cursig, const void *gregs) { - prstatus_t prstat; - char *note_name = "CORE"; + const char *note_name = "CORE"; + const struct elf_backend_data *bed = get_elf_backend_data (abfd); - memset (&prstat, 0, sizeof (prstat)); - prstat.pr_pid = pid; - prstat.pr_cursig = cursig; - memcpy (&prstat.pr_reg, gregs, sizeof (prstat.pr_reg)); - return elfcore_write_note (abfd, buf, bufsiz, - note_name, NT_PRSTATUS, &prstat, sizeof (prstat)); + if (bed->elf_backend_write_core_note != NULL) + { + char *ret; + ret = (*bed->elf_backend_write_core_note) (abfd, buf, bufsiz, + NT_PRSTATUS, + pid, cursig, gregs); + if (ret != NULL) + return ret; + } + +#if defined (HAVE_PRSTATUS32_T) + if (bed->s->elfclass == ELFCLASS32) + { + prstatus32_t prstat; + + memset (&prstat, 0, sizeof (prstat)); + prstat.pr_pid = pid; + prstat.pr_cursig = cursig; + memcpy (&prstat.pr_reg, gregs, sizeof (prstat.pr_reg)); + return elfcore_write_note (abfd, buf, bufsiz, note_name, + NT_PRSTATUS, &prstat, sizeof (prstat)); + } + else +#endif + { + prstatus_t prstat; + + memset (&prstat, 0, sizeof (prstat)); + prstat.pr_pid = pid; + prstat.pr_cursig = cursig; + memcpy (&prstat.pr_reg, gregs, sizeof (prstat.pr_reg)); + return elfcore_write_note (abfd, buf, bufsiz, note_name, + NT_PRSTATUS, &prstat, sizeof (prstat)); + } } #endif /* HAVE_PRSTATUS_T */ @@ -8261,7 +8319,7 @@ elfcore_write_lwpstatus (bfd *abfd, const void *gregs) { lwpstatus_t lwpstat; - char *note_name = "CORE"; + const char *note_name = "CORE"; memset (&lwpstat, 0, sizeof (lwpstat)); lwpstat.pr_lwpid = pid >> 16; @@ -8291,14 +8349,31 @@ elfcore_write_pstatus (bfd *abfd, int cursig ATTRIBUTE_UNUSED, const void *gregs ATTRIBUTE_UNUSED) { - pstatus_t pstat; - char *note_name = "CORE"; + const char *note_name = "CORE"; +#if defined (HAVE_PSTATUS32_T) + const struct elf_backend_data *bed = get_elf_backend_data (abfd); - memset (&pstat, 0, sizeof (pstat)); - pstat.pr_pid = pid & 0xffff; - buf = elfcore_write_note (abfd, buf, bufsiz, note_name, - NT_PSTATUS, &pstat, sizeof (pstat)); - return buf; + if (bed->s->elfclass == ELFCLASS32) + { + pstatus32_t pstat; + + memset (&pstat, 0, sizeof (pstat)); + pstat.pr_pid = pid & 0xffff; + buf = elfcore_write_note (abfd, buf, bufsiz, note_name, + NT_PSTATUS, &pstat, sizeof (pstat)); + return buf; + } + else +#endif + { + pstatus_t pstat; + + memset (&pstat, 0, sizeof (pstat)); + pstat.pr_pid = pid & 0xffff; + buf = elfcore_write_note (abfd, buf, bufsiz, note_name, + NT_PSTATUS, &pstat, sizeof (pstat)); + return buf; + } } #endif /* HAVE_PSTATUS_T */ @@ -8309,7 +8384,7 @@ elfcore_write_prfpreg (bfd *abfd, const void *fpregs, int size) { - char *note_name = "CORE"; + const char *note_name = "CORE"; return elfcore_write_note (abfd, buf, bufsiz, note_name, NT_FPREGSET, fpregs, size); } diff --git a/bfd/elf32-ppc.c b/bfd/elf32-ppc.c index c81ea1e..f0a780a 100644 --- a/bfd/elf32-ppc.c +++ b/bfd/elf32-ppc.c @@ -25,6 +25,7 @@ suggestions from the in-progress Embedded PowerPC ABI, and that information may also not match. */ +#include #include "bfd.h" #include "sysdep.h" #include "bfdlink.h" @@ -1813,6 +1814,52 @@ ppc_elf_grok_psinfo (bfd *abfd, Elf_Internal_Note *note) return TRUE; } +static char * +ppc_elf_write_core_note (bfd *abfd, char *buf, int *bufsiz, int note_type, ...) +{ + switch (note_type) + { + default: + return NULL; + + case NT_PRPSINFO: + { + char data[128]; + va_list ap; + + va_start (ap, note_type); + memset (data, 0, 32); + strncpy (data + 32, va_arg (ap, const char *), 16); + strncpy (data + 48, va_arg (ap, const char *), 80); + va_end (ap); + return elfcore_write_note (abfd, buf, bufsiz, + "CORE", note_type, data, sizeof (data)); + } + + case NT_PRSTATUS: + { + char data[268]; + va_list ap; + long pid; + int cursig; + const void *greg; + + va_start (ap, note_type); + memset (data, 0, 72); + pid = va_arg (ap, long); + bfd_put_32 (abfd, pid, data + 24); + cursig = va_arg (ap, int); + bfd_put_16 (abfd, cursig, data + 12); + greg = va_arg (ap, const void *); + memcpy (data + 72, greg, 192); + memset (data + 264, 0, 4); + va_end (ap); + return elfcore_write_note (abfd, buf, bufsiz, + "CORE", note_type, data, sizeof (data)); + } + } +} + /* Return address for Ith PLT stub in section PLT, for relocation REL or (bfd_vma) -1 if it should not be included. */ @@ -7476,6 +7523,7 @@ ppc_elf_finish_dynamic_sections (bfd *output_bfd, #define elf_backend_additional_program_headers ppc_elf_additional_program_headers #define elf_backend_grok_prstatus ppc_elf_grok_prstatus #define elf_backend_grok_psinfo ppc_elf_grok_psinfo +#define elf_backend_write_core_note ppc_elf_write_core_note #define elf_backend_reloc_type_class ppc_elf_reloc_type_class #define elf_backend_begin_write_processing ppc_elf_begin_write_processing #define elf_backend_final_write_processing ppc_elf_final_write_processing diff --git a/bfd/elf64-ppc.c b/bfd/elf64-ppc.c index 35f7cdf..a354957 100644 --- a/bfd/elf64-ppc.c +++ b/bfd/elf64-ppc.c @@ -25,6 +25,7 @@ http://www.linuxbase.org/spec/ELF/ppc64/PPC-elf64abi.txt, and http://www.linuxbase.org/spec/ELF/ppc64/spec/book1.html */ +#include #include "bfd.h" #include "sysdep.h" #include "bfdlink.h" @@ -84,6 +85,7 @@ static bfd_vma opd_entry_value #define elf_backend_object_p ppc64_elf_object_p #define elf_backend_grok_prstatus ppc64_elf_grok_prstatus #define elf_backend_grok_psinfo ppc64_elf_grok_psinfo +#define elf_backend_write_core_note ppc64_elf_write_core_note #define elf_backend_create_dynamic_sections ppc64_elf_create_dynamic_sections #define elf_backend_copy_indirect_symbol ppc64_elf_copy_indirect_symbol #define elf_backend_add_symbol_hook ppc64_elf_add_symbol_hook @@ -2484,6 +2486,53 @@ ppc64_elf_grok_psinfo (bfd *abfd, Elf_Internal_Note *note) return TRUE; } +static char * +ppc64_elf_write_core_note (bfd *abfd, char *buf, int *bufsiz, int note_type, + ...) +{ + switch (note_type) + { + default: + return NULL; + + case NT_PRPSINFO: + { + char data[136]; + va_list ap; + + va_start (ap, note_type); + memset (data, 0, 40); + strncpy (data + 40, va_arg (ap, const char *), 16); + strncpy (data + 56, va_arg (ap, const char *), 80); + va_end (ap); + return elfcore_write_note (abfd, buf, bufsiz, + "CORE", note_type, data, sizeof (data)); + } + + case NT_PRSTATUS: + { + char data[504]; + va_list ap; + long pid; + int cursig; + const void *greg; + + va_start (ap, note_type); + memset (data, 0, 112); + pid = va_arg (ap, long); + bfd_put_32 (abfd, pid, data + 32); + cursig = va_arg (ap, int); + bfd_put_16 (abfd, cursig, data + 12); + greg = va_arg (ap, const void *); + memcpy (data + 112, greg, 384); + memset (data + 496, 0, 8); + va_end (ap); + return elfcore_write_note (abfd, buf, bufsiz, + "CORE", note_type, data, sizeof (data)); + } + } +} + /* Merge backend specific data from an object file to the output object file when linking. */ diff --git a/bfd/elfxx-target.h b/bfd/elfxx-target.h index f51617c..a09376b 100644 --- a/bfd/elfxx-target.h +++ b/bfd/elfxx-target.h @@ -460,6 +460,9 @@ #ifndef elf_backend_grok_psinfo #define elf_backend_grok_psinfo NULL #endif +#ifndef elf_backend_write_core_note +#define elf_backend_write_core_note NULL +#endif #ifndef elf_backend_sprintf_vma #define elf_backend_sprintf_vma _bfd_elf_sprintf_vma #endif @@ -635,6 +638,7 @@ static struct elf_backend_data elfNN_bed = elf_backend_count_relocs, elf_backend_grok_prstatus, elf_backend_grok_psinfo, + elf_backend_write_core_note, elf_backend_sprintf_vma, elf_backend_fprintf_vma, elf_backend_reloc_type_class, -- cgit v1.1