aboutsummaryrefslogtreecommitdiff
path: root/bfd
diff options
context:
space:
mode:
Diffstat (limited to 'bfd')
-rw-r--r--bfd/ChangeLog5
-rw-r--r--bfd/elfcore.h85
2 files changed, 81 insertions, 9 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index ad92c2c..d894d24 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,3 +1,8 @@
+Tue Apr 16 16:36:38 1996 Stu Grossman (grossman@lisa.cygnus.com)
+
+ * elfcore.h: Add support for core files with multiple threads.
+ (Primarily for Solaris.)
+
Tue Apr 16 13:44:08 1996 Ian Lance Taylor <ian@cygnus.com>
* aoutx.h (NAME(aout,squirt_out_relocs)): Don't do anything if
diff --git a/bfd/elfcore.h b/bfd/elfcore.h
index e22faf7..ab8b79f 100644
--- a/bfd/elfcore.h
+++ b/bfd/elfcore.h
@@ -1,5 +1,5 @@
/* ELF core file support for BFD.
- Copyright 1995 Free Software Foundation, Inc.
+ Copyright (C) 1995, 1996 Free Software Foundation, Inc.
This file is part of BFD, the Binary File Descriptor library.
@@ -21,27 +21,51 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#ifdef HAVE_SYS_PROCFS_H /* Some core file support requires host /proc files */
#include <signal.h>
#include <sys/procfs.h>
+
+/* Solaris includes the field pr_who that indicates the thread number within
+ the process. */
+
+#ifdef PIOCOPENLWP
+#define get_thread(STATUS) ((((prstatus_t *)(STATUS))->pr_who << 16) \
+ | ((prstatus_t *)(STATUS))->pr_pid)
+#else
+#define get_thread(STATUS) (((prstatus_t *)(STATUS))->pr_pid)
+#endif
#else
#define bfd_prstatus(abfd, descdata, descsz, filepos) true
#define bfd_fpregset(abfd, descdata, descsz, filepos) true
#define bfd_prpsinfo(abfd, descdata, descsz, filepos) true
+#define get_thread(STATUS) (1)
#endif
#ifdef HAVE_SYS_PROCFS_H
+static int did_reg;
+static int did_reg2;
+
static boolean
-bfd_prstatus (abfd, descdata, descsz, filepos)
+bfd_prstatus (abfd, descdata, descsz, filepos, thread)
bfd *abfd;
char *descdata;
int descsz;
long filepos;
+ int thread;
{
asection *newsect;
prstatus_t *status = (prstatus_t *) 0;
if (descsz == sizeof (prstatus_t))
{
- newsect = bfd_make_section (abfd, ".reg");
+ char secname[100];
+ char *p;
+
+ sprintf (secname, ".reg/%d", thread);
+ p = bfd_alloc (abfd, strlen (secname) + 1);
+ if (!p)
+ return false;
+ strcpy (p, secname);
+
+ newsect = bfd_make_section (abfd, p);
if (newsect == NULL)
return false;
newsect->_raw_size = sizeof (status->pr_reg);
@@ -52,6 +76,19 @@ bfd_prstatus (abfd, descdata, descsz, filepos)
{
memcpy (core_prstatus (abfd), descdata, descsz);
}
+
+ if (!did_reg++)
+ {
+ asection *regsect;
+
+ regsect = bfd_make_section (abfd, ".reg");
+ if (regsect == NULL)
+ return false;
+ regsect->_raw_size = newsect->_raw_size;
+ regsect->filepos = newsect->filepos;
+ regsect->flags = newsect->flags;
+ regsect->alignment_power = newsect->alignment_power;
+ }
}
return true;
}
@@ -75,21 +112,44 @@ bfd_prpsinfo (abfd, descdata, descsz, filepos)
}
static boolean
-bfd_fpregset (abfd, descdata, descsz, filepos)
+bfd_fpregset (abfd, descdata, descsz, filepos, thread)
bfd *abfd;
char *descdata;
int descsz;
long filepos;
+ int thread;
{
asection *newsect;
+ char secname[100];
+ char *p;
- newsect = bfd_make_section (abfd, ".reg2");
+ sprintf (secname, ".reg2/%d", thread);
+ p = bfd_alloc (abfd, strlen (secname) + 1);
+ if (!p)
+ return false;
+ strcpy (p, secname);
+
+ newsect = bfd_make_section (abfd, p);
if (newsect == NULL)
return false;
newsect->_raw_size = descsz;
newsect->filepos = filepos;
newsect->flags = SEC_HAS_CONTENTS;
newsect->alignment_power = 2;
+
+ if (!did_reg2++)
+ {
+ asection *regsect;
+
+ regsect = bfd_make_section (abfd, ".reg2");
+ if (regsect == NULL)
+ return false;
+ regsect->_raw_size = newsect->_raw_size;
+ regsect->filepos = newsect->filepos;
+ regsect->flags = newsect->flags;
+ regsect->alignment_power = newsect->alignment_power;
+ }
+
return true;
}
@@ -237,6 +297,10 @@ elf_corefile_note (abfd, hdr)
char *sectname; /* Name to use for new section */
long filepos; /* File offset to descriptor data */
asection *newsect;
+ int thread = 1; /* Current thread number */
+
+ did_reg = 0; /* Non-zero if we made .reg section */
+ did_reg2 = 0; /* Ditto for .reg2 */
if (hdr->p_filesz > 0
&& (buf = (char *) bfd_malloc ((size_t) hdr->p_filesz)) != NULL
@@ -256,15 +320,18 @@ elf_corefile_note (abfd, hdr)
{
case NT_PRSTATUS:
/* process descdata as prstatus info */
- if (! bfd_prstatus (abfd, descdata, i_note.descsz, filepos))
+ thread = get_thread (descdata);
+ if (! bfd_prstatus (abfd, descdata, i_note.descsz, filepos,
+ thread))
return false;
- sectname = ".prstatus";
+ sectname = NULL;
break;
case NT_FPREGSET:
/* process descdata as fpregset info */
- if (! bfd_fpregset (abfd, descdata, i_note.descsz, filepos))
+ if (! bfd_fpregset (abfd, descdata, i_note.descsz, filepos,
+ thread))
return false;
- sectname = ".fpregset";
+ sectname = NULL;
break;
case NT_PRPSINFO:
/* process descdata as prpsinfo */