[RFC] Cross core support
Daniel Jacobowitz
dmj+@andrew.cmu.edu
Fri Jun 29 11:01:00 GMT 2001
On Thu, Jun 28, 2001 at 09:13:56PM +0100, Nick Clifton wrote:
> > That's true, I am only looking at ELF here. My ignorance of BFD is
> > showing. So I could add what I am interested in to elf_backend_data,
> > and replace things in elf.c like:
> >
> > #if defined (HAVE_PRSTATUS_T)
> > case NT_PRSTATUS:
> > return elfcore_grok_prstatus (abfd, note);
> > #endif
> >
> > with something along the lines of:
> > if (bed->elf_backend_grok_prstatus)
> > return (*bed->elf_backend_grok_prstatus) (abfd, note);
> >
> > I'd still need to do something relatively hokey, I expect, since there
> > could be multiple ia32 ELF targets with differently formatted cores
> > (say, Linux/x86 and Solaris/x86). However, we could then special-case
> > those appropriately if there was a backend function for it.
> >
> > Does this sound reasonable?
>
> Yes.
>
> > If so, I'll try to work out a way to do
> > this with minimal code duplication for parsing all the different note
> > types, and send a patch later today or tomorrow.
>
> Wow, so fast!
OK, a little later than I expected :) I got sidetracked by some gdb
problems.
This only converts elf32-mips.c; if it's OK as is, I'll do the other
ports I have numbers for. It leaves all the existing logic intact, so
the only possible way for it to cause a problem is if there are two
OS's using elf32-mips.c with same-sized notes with different layouts.
I'm not terribly worried.
I ended up not doing it table-based; while this will cause a little
code duplication, I think it's more useful, in case we need to
distinguish between different OS's in some more complicated way in the
future. I also only converted the prstatus and psinfo handling, since
they were the only two I could test.
--
Daniel Jacobowitz Carnegie Mellon University
MontaVista Software Debian GNU/Linux Developer
2001-06-29 Daniel Jacobowitz <drow@mvista.com>
* elf-bfd.h: Add prototypes for _bfd_elfcore_make_pseudosection
and _bfd_elfcore_strndup.
(struct elf_backend_data): Add elf_backend_grok_prstatus
and elf_backend_grok_psinfo.
* elf.c (_bfd_elfcore_make_pseudosection): New function.
(elfcore_grok_prstatus): Use it.
(elfcore_make_note_pseudosection): Likewise.
(elfcore_strndup): Rename to...
(_bfd_elfcore_strndup): Here, and make global.
(elfcore_grok_psinfo): Use _bfd_elfcore_strndup.
(elfcore_grok_note): Call elf_backend_grok_prstatus
and elf_backend_grok_psinfo if available.
* elf32-mips.c (_bfd_elf32_mips_grok_prstatus): New function.
(_bfd_elf32_mips_grok_psinfo): New function.
(elf_backend_grok_prstatus): Define.
(elf_backend_grok_psinfo): Define.
* elfxx-target.h (elf_backend_grok_prstatus): Default to NULL.
(elf_backend_grok_psinfo): Likewise.
(elfNN_bed): Include elf_backend_grok_prstatus and
elf_backend_grok_psinfo.
Index: elf-bfd.h
===================================================================
RCS file: /cvs/src/src/bfd/elf-bfd.h,v
retrieving revision 1.35
diff -u -p -r1.35 elf-bfd.h
--- elf-bfd.h 2001/06/20 20:34:10 1.35
+++ elf-bfd.h 2001/06/29 17:39:05
@@ -628,6 +628,14 @@ struct elf_backend_data
unsigned int (*elf_backend_count_relocs)
PARAMS ((asection *, Elf_Internal_Rela *));
+ /* This function, if defined, is called when an NT_PRSTATUS note is found
+ in a core file. */
+ boolean (*elf_backend_grok_prstatus) PARAMS ((bfd *, Elf_Internal_Note *));
+
+ /* This function, if defined, is called when an NT_PSINFO or NT_PRPSINFO
+ note is found in a core file. */
+ boolean (*elf_backend_grok_psinfo) PARAMS ((bfd *, Elf_Internal_Note *));
+
/* The swapping table to use when dealing with ECOFF information.
Used for the MIPS ELF .mdebug section. */
const struct ecoff_debug_swap *elf_backend_ecoff_debug_swap;
@@ -1097,6 +1105,9 @@ boolean _bfd_elf_create_got_section PARA
struct bfd_link_info *));
unsigned long _bfd_elf_link_renumber_dynsyms PARAMS ((bfd *,
struct bfd_link_info *));
+
+boolean _bfd_elfcore_make_pseudosection PARAMS ((bfd *, char *, int, int));
+char *_bfd_elfcore_strndup PARAMS ((bfd *, char *, int));
elf_linker_section_t *_bfd_elf_create_linker_section
PARAMS ((bfd *abfd,
Index: elf.c
===================================================================
RCS file: /cvs/src/src/bfd/elf.c,v
retrieving revision 1.72
diff -u -p -r1.72 elf.c
--- elf.c 2001/06/10 05:20:59 1.72
+++ elf.c 2001/06/29 17:39:09
@@ -5376,6 +5376,46 @@ elfcore_maybe_make_sect (abfd, name, sec
return true;
}
+/* Create a pseudosection containing SIZE bytes at FILEPOS. This
+ actually creates up to two pseudosections:
+ - For the single-threaded case, a section named NAME, unless
+ such a section already exists.
+ - For the multi-threaded case, a section named "NAME/PID", where
+ PID is elfcore_make_pid (abfd).
+ Both pseudosections have identical contents. */
+boolean
+_bfd_elfcore_make_pseudosection (abfd, name, size, filepos)
+ bfd *abfd;
+ char *name;
+ int size;
+ int filepos;
+{
+ char buf[100];
+ char *threaded_name;
+ asection *sect;
+
+ /* Build the section name. */
+
+ sprintf (buf, "%s/%d", name, elfcore_make_pid (abfd));
+ threaded_name = bfd_alloc (abfd, strlen (buf) + 1);
+ if (threaded_name == NULL)
+ return false;
+ strcpy (threaded_name, buf);
+
+ sect = bfd_make_section (abfd, threaded_name);
+ if (sect == NULL)
+ return false;
+ sect->_raw_size = size;
+ sect->filepos = filepos;
+ sect->flags = SEC_HAS_CONTENTS;
+ sect->alignment_power = 2;
+
+ if (! elfcore_maybe_make_sect (abfd, name, sect))
+ return false;
+
+ return true;
+}
+
/* prstatus_t exists on:
solaris 2.5+
linux 2.[01] + glibc
@@ -5388,9 +5428,6 @@ elfcore_grok_prstatus (abfd, note)
bfd *abfd;
Elf_Internal_Note *note;
{
- char buf[100];
- char *name;
- asection *sect;
int raw_size;
int offset;
@@ -5445,70 +5482,24 @@ elfcore_grok_prstatus (abfd, note)
note size (ie. data object type). */
return true;
}
-
- /* Make a ".reg/999" section. */
-
- sprintf (buf, ".reg/%d", elfcore_make_pid (abfd));
- name = bfd_alloc (abfd, strlen (buf) + 1);
- if (name == NULL)
- return false;
- strcpy (name, buf);
-
- sect = bfd_make_section (abfd, name);
- if (sect == NULL)
- return false;
-
- sect->_raw_size = raw_size;
- sect->filepos = note->descpos + offset;
-
- sect->flags = SEC_HAS_CONTENTS;
- sect->alignment_power = 2;
- if (! elfcore_maybe_make_sect (abfd, ".reg", sect))
+ /* Make a ".reg/999" section and a ".reg" section. */
+ if (! _bfd_elfcore_make_pseudosection (abfd, ".reg",
+ raw_size, note->descpos + offset));
return false;
return true;
}
#endif /* defined (HAVE_PRSTATUS_T) */
-/* Create a pseudosection containing the exact contents of NOTE. This
- actually creates up to two pseudosections:
- - For the single-threaded case, a section named NAME, unless
- such a section already exists.
- - For the multi-threaded case, a section named "NAME/PID", where
- PID is elfcore_make_pid (abfd).
- Both pseudosections have identical contents: the contents of NOTE. */
-
+/* Create a pseudosection containing the exact contents of NOTE. */
static boolean
elfcore_make_note_pseudosection (abfd, name, note)
bfd *abfd;
char *name;
Elf_Internal_Note *note;
{
- char buf[100];
- char *threaded_name;
- asection *sect;
-
- /* Build the section name. */
-
- sprintf (buf, "%s/%d", name, elfcore_make_pid (abfd));
- threaded_name = bfd_alloc (abfd, strlen (buf) + 1);
- if (threaded_name == NULL)
- return false;
- strcpy (threaded_name, buf);
-
- sect = bfd_make_section (abfd, threaded_name);
- if (sect == NULL)
- return false;
- sect->_raw_size = note->descsz;
- sect->filepos = note->descpos;
- sect->flags = SEC_HAS_CONTENTS;
- sect->alignment_power = 2;
-
- if (! elfcore_maybe_make_sect (abfd, name, sect))
- return false;
-
- return true;
+ return _bfd_elfcore_make_pseudosection (abfd, name, note->descsz, note->descpos);
}
/* There isn't a consistent prfpregset_t across platforms,
@@ -5548,15 +5539,13 @@ typedef psinfo_t elfcore_psinfo_t;
typedef psinfo32_t elfcore_psinfo32_t;
#endif
#endif
-
-#if defined (HAVE_PRPSINFO_T) || defined (HAVE_PSINFO_T)
/* return a malloc'ed copy of a string at START which is at
most MAX bytes long, possibly without a terminating '\0'.
the copy will always have a terminating '\0'. */
-static char*
-elfcore_strndup (abfd, start, max)
+char*
+_bfd_elfcore_strndup (abfd, start, max)
bfd *abfd;
char *start;
int max;
@@ -5580,6 +5565,8 @@ elfcore_strndup (abfd, start, max)
return dup;
}
+#if defined (HAVE_PRPSINFO_T) || defined (HAVE_PSINFO_T)
+
static boolean
elfcore_grok_psinfo (abfd, note)
bfd *abfd;
@@ -5592,10 +5583,10 @@ elfcore_grok_psinfo (abfd, note)
memcpy (&psinfo, note->descdata, sizeof (psinfo));
elf_tdata (abfd)->core_program
- = elfcore_strndup (abfd, psinfo.pr_fname, sizeof (psinfo.pr_fname));
+ = _bfd_elfcore_strndup (abfd, psinfo.pr_fname, sizeof (psinfo.pr_fname));
elf_tdata (abfd)->core_command
- = elfcore_strndup (abfd, psinfo.pr_psargs, sizeof (psinfo.pr_psargs));
+ = _bfd_elfcore_strndup (abfd, psinfo.pr_psargs, sizeof (psinfo.pr_psargs));
}
#if defined (HAVE_PRPSINFO32_T) || defined (HAVE_PSINFO32_T)
else if (note->descsz == sizeof (elfcore_psinfo32_t))
@@ -5606,10 +5597,10 @@ elfcore_grok_psinfo (abfd, note)
memcpy (&psinfo, note->descdata, sizeof (psinfo));
elf_tdata (abfd)->core_program
- = elfcore_strndup (abfd, psinfo.pr_fname, sizeof (psinfo.pr_fname));
+ = _bfd_elfcore_strndup (abfd, psinfo.pr_fname, sizeof (psinfo.pr_fname));
elf_tdata (abfd)->core_command
- = elfcore_strndup (abfd, psinfo.pr_psargs, sizeof (psinfo.pr_psargs));
+ = _bfd_elfcore_strndup (abfd, psinfo.pr_psargs, sizeof (psinfo.pr_psargs));
}
#endif
@@ -5841,14 +5832,21 @@ elfcore_grok_note (abfd, note)
bfd *abfd;
Elf_Internal_Note *note;
{
+ struct elf_backend_data *bed = get_elf_backend_data (abfd);
+
switch (note->type)
{
default:
return true;
-#if defined (HAVE_PRSTATUS_T)
case NT_PRSTATUS:
+ if (bed->elf_backend_grok_prstatus)
+ if ((*bed->elf_backend_grok_prstatus) (abfd, note))
+ return true;
+#if defined (HAVE_PRSTATUS_T)
return elfcore_grok_prstatus (abfd, note);
+#else
+ return true;
#endif
#if defined (HAVE_PSTATUS_T)
@@ -5876,10 +5874,15 @@ elfcore_grok_note (abfd, note)
else
return true;
-#if defined (HAVE_PRPSINFO_T) || defined (HAVE_PSINFO_T)
case NT_PRPSINFO:
case NT_PSINFO:
+ if (bed->elf_backend_grok_psinfo)
+ if ((*bed->elf_backend_grok_psinfo) (abfd, note))
+ return true;
+#if defined (HAVE_PRPSINFO_T) || defined (HAVE_PSINFO_T)
return elfcore_grok_psinfo (abfd, note);
+#else
+ return true;
#endif
}
}
Index: elf32-mips.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-mips.c,v
retrieving revision 1.100
diff -u -p -r1.100 elf32-mips.c
--- elf32-mips.c 2001/06/17 16:14:42 1.100
+++ elf32-mips.c 2001/06/29 17:39:12
@@ -9134,6 +9134,73 @@ _bfd_mips_elf_finish_dynamic_sections (o
return true;
}
+/* Support for core dump NOTE sections */
+static boolean
+_bfd_elf32_mips_grok_prstatus (abfd, note)
+ bfd *abfd;
+ Elf_Internal_Note *note;
+{
+ int offset;
+ int raw_size;
+
+ switch (note->descsz)
+ {
+ default:
+ return false;
+
+ case 256: /* Linux/MIPS */
+ /* pr_cursig */
+ elf_tdata (abfd)->core_signal = bfd_get_16 (abfd, note->descdata + 12);
+
+ /* pr_pid */
+ elf_tdata (abfd)->core_pid = bfd_get_32 (abfd, note->descdata + 24);
+
+ /* pr_reg */
+ offset = 72;
+ raw_size = 180;
+
+ break;
+ }
+
+ /* Make a ".reg/999" section. */
+ if (! _bfd_elfcore_make_pseudosection (abfd, ".reg",
+ raw_size, note->descpos + offset))
+ return false;
+
+ return true;
+}
+
+static boolean _bfd_elf32_mips_grok_psinfo (abfd, note)
+ bfd *abfd;
+ Elf_Internal_Note *note;
+{
+ switch (note->descsz)
+ {
+ default:
+ return false;
+
+ case 128: /* Linux/MIPS elf_prpsinfo */
+ elf_tdata (abfd)->core_program
+ = _bfd_elfcore_strndup (abfd, note->descdata + 32, 16);
+ elf_tdata (abfd)->core_command
+ = _bfd_elfcore_strndup (abfd, note->descdata + 48, 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;
+}
+
/* This is almost identical to bfd_generic_get_... except that some
MIPS relocations need to be handled specially. Sigh. */
@@ -9421,6 +9488,8 @@ static const struct ecoff_debug_swap mip
_bfd_mips_elf_copy_indirect_symbol
#define elf_backend_hide_symbol _bfd_mips_elf_hide_symbol
+#define elf_backend_grok_prstatus _bfd_elf32_mips_grok_prstatus
+#define elf_backend_grok_psinfo _bfd_elf32_mips_grok_psinfo
#define bfd_elf32_bfd_is_local_label_name \
mips_elf_is_local_label_name
Index: elfxx-target.h
===================================================================
RCS file: /cvs/src/src/bfd/elfxx-target.h,v
retrieving revision 1.22
diff -u -p -r1.22 elfxx-target.h
--- elfxx-target.h 2001/06/20 20:34:10 1.22
+++ elfxx-target.h 2001/06/29 17:39:12
@@ -329,6 +329,12 @@ Foundation, Inc., 59 Temple Place - Suit
#ifndef elf_backend_count_relocs
#define elf_backend_count_relocs NULL
#endif
+#ifndef elf_backend_grok_prstatus
+#define elf_backend_grok_prstatus NULL
+#endif
+#ifndef elf_backend_grok_psinfo
+#define elf_backend_grok_psinfo NULL
+#endif
/* Previously, backends could only use SHT_REL or SHT_RELA relocation
sections, but not both. They defined USE_REL to indicate SHT_REL
@@ -412,6 +418,8 @@ static CONST struct elf_backend_data elf
elf_backend_hide_symbol,
elf_backend_emit_relocs,
elf_backend_count_relocs,
+ elf_backend_grok_prstatus,
+ elf_backend_grok_psinfo,
elf_backend_ecoff_debug_swap,
ELF_MACHINE_ALT1,
ELF_MACHINE_ALT2,
More information about the Binutils
mailing list