This is the mail archive of the binutils@sources.redhat.com mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Re: [RFC] Cross core support


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,




Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]