/* 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.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
-Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
/* Core file support */
-#ifdef HAVE_PROCFS /* Some core file support requires host /proc files */
+#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_PROCFS
+#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);
{
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;
}
if (descsz == sizeof (prpsinfo_t))
{
if ((core_prpsinfo (abfd) = bfd_alloc (abfd, descsz)) == NULL)
- {
- bfd_set_error (bfd_error_no_memory);
- return false;
- }
+ return false;
memcpy (core_prpsinfo (abfd), descdata, descsz);
}
return true;
}
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;
+
+ sprintf (secname, ".reg2/%d", thread);
+ p = bfd_alloc (abfd, strlen (secname) + 1);
+ if (!p)
+ return false;
+ strcpy (p, secname);
- newsect = bfd_make_section (abfd, ".reg2");
+ 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;
}
-#endif /* HAVE_PROCFS */
+#endif /* HAVE_SYS_PROCFS_H */
/* Return a pointer to the args (including the command name) that were
seen by the program that generated the core dump. Note that for
elf_core_file_failing_command (abfd)
bfd *abfd;
{
-#ifdef HAVE_PROCFS
+#ifdef HAVE_SYS_PROCFS_H
if (core_prpsinfo (abfd))
{
prpsinfo_t *p = core_prpsinfo (abfd);
elf_core_file_failing_signal (abfd)
bfd *abfd;
{
-#ifdef HAVE_PROCFS
+#ifdef HAVE_SYS_PROCFS_H
if (core_prstatus (abfd))
{
return ((prstatus_t *) (core_prstatus (abfd)))->pr_cursig;
bfd *core_bfd;
bfd *exec_bfd;
{
-#ifdef HAVE_PROCFS
+#ifdef HAVE_SYS_PROCFS_H
char *corename;
char *execname;
#endif
return false;
}
-#ifdef HAVE_PROCFS
+#ifdef HAVE_SYS_PROCFS_H
/* If no prpsinfo, just return true. Otherwise, grab the last component
of the exec'd pathname from the prpsinfo. */
return true;
-#endif /* HAVE_PROCFS */
+#endif /* HAVE_SYS_PROCFS_H */
}
/* ELF core files contain a segment of type PT_NOTE, that holds much of
the bfd client will have to interpret the structures itself. Even with
/proc support, it might want these full structures for it's own reasons.
- In the second level of support, where HAVE_PROCFS is defined, bfd will
- pick apart the structures to gather some additional information that
- clients may want, such as the general register set, the name of the
- exec'ed file and its arguments, the signal (if any) that caused the
- core dump, etc.
+ In the second level of support, where HAVE_SYS_PROCFS_H is defined,
+ bfd will pick apart the structures to gather some additional
+ information that clients may want, such as the general register
+ set, the name of the exec'ed file and its arguments, the signal (if
+ any) that caused the core dump, etc.
*/
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 *) malloc (hdr->p_filesz)) != NULL
+ && (buf = (char *) bfd_malloc ((size_t) hdr->p_filesz)) != NULL
&& bfd_seek (abfd, hdr->p_offset, SEEK_SET) != -1
&& bfd_read ((PTR) buf, hdr->p_filesz, 1, abfd) == hdr->p_filesz)
{
{
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 */
}
else if (hdr->p_filesz > 0)
{
- bfd_set_error (bfd_error_no_memory);
return false;
}
return true;
switch (x_ehdr.e_ident[EI_DATA])
{
case ELFDATA2MSB: /* Big-endian */
- if (abfd->xvec->byteorder_big_p == false)
+ if (! bfd_big_endian (abfd))
goto wrong;
break;
case ELFDATA2LSB: /* Little-endian */
- if (abfd->xvec->byteorder_big_p == true)
+ if (! bfd_little_endian (abfd))
goto wrong;
break;
case ELFDATANONE: /* No data encoding specified */
elf_tdata (abfd) =
(struct elf_obj_tdata *) bfd_zalloc (abfd, sizeof (struct elf_obj_tdata));
if (elf_tdata (abfd) == NULL)
- {
- bfd_set_error (bfd_error_no_memory);
- return NULL;
- }
+ return NULL;
/* FIXME, `wrong' returns from this point onward, leak memory. */
i_phdrp = (Elf_Internal_Phdr *)
bfd_alloc (abfd, sizeof (*i_phdrp) * i_ehdrp->e_phnum);
if (!i_phdrp)
- {
- bfd_set_error (bfd_error_no_memory);
- return NULL;
- }
+ return NULL;
if (bfd_seek (abfd, i_ehdrp->e_phoff, SEEK_SET) == -1)
return NULL;
for (phindex = 0; phindex < i_ehdrp->e_phnum; phindex++)