From 54f1b3cf509cd889905287cb8ce6c5ae33911a21 Mon Sep 17 00:00:00 2001 From: Andrew Hsieh Date: Fri, 13 Jun 2014 12:38:00 -0700 Subject: Add upstream binutils-2.25 snapshot 4/4 2014 For MIPS -mmsa support Change-Id: I08c4f002fa7b33dec85ed75956e6ab551bb03c96 --- binutils-2.25/bfd/lynx-core.c | 227 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 227 insertions(+) create mode 100644 binutils-2.25/bfd/lynx-core.c (limited to 'binutils-2.25/bfd/lynx-core.c') diff --git a/binutils-2.25/bfd/lynx-core.c b/binutils-2.25/bfd/lynx-core.c new file mode 100644 index 00000000..0b4af043 --- /dev/null +++ b/binutils-2.25/bfd/lynx-core.c @@ -0,0 +1,227 @@ +/* BFD back end for Lynx core files + Copyright 1993, 1994, 1995, 2001, 2002, 2004, 2005, 2006, 2007 + Free Software Foundation, Inc. + Written by Stu Grossman of Cygnus Support. + + This file is part of BFD, the Binary File Descriptor library. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + 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., 51 Franklin Street - Fifth Floor, Boston, + MA 02110-1301, USA. */ + +#include "sysdep.h" +#include "bfd.h" +#include "libbfd.h" + +#ifdef LYNX_CORE + +#include +#include +/* sys/kernel.h should define this, but doesn't always, sigh. */ +#ifndef __LYNXOS +#define __LYNXOS +#endif +#include +#include +#include +#include +#include +#include +#include + +/* These are stored in the bfd's tdata */ + +struct lynx_core_struct +{ + int sig; + char cmd[PNMLEN + 1]; +}; + +#define core_hdr(bfd) ((bfd)->tdata.lynx_core_data) +#define core_signal(bfd) (core_hdr(bfd)->sig) +#define core_command(bfd) (core_hdr(bfd)->cmd) + +#define lynx_core_file_matches_executable_p generic_core_file_matches_executable_p +#define lynx_core_file_pid _bfd_nocore_core_file_pid + +/* Handle Lynx core dump file. */ + +static asection * +make_bfd_asection (bfd *abfd, + const char *name, + flagword flags, + bfd_size_type size, + bfd_vma vma, + file_ptr filepos) +{ + asection *asect; + char *newname; + + newname = bfd_alloc (abfd, (bfd_size_type) strlen (name) + 1); + if (!newname) + return NULL; + + strcpy (newname, name); + + asect = bfd_make_section_with_flags (abfd, newname, flags); + if (!asect) + return NULL; + + asect->size = size; + asect->vma = vma; + asect->filepos = filepos; + asect->alignment_power = 2; + + return asect; +} + +const bfd_target * +lynx_core_file_p (bfd *abfd) +{ + int secnum; + struct pssentry pss; + bfd_size_type tcontext_size; + core_st_t *threadp; + int pagesize; + asection *newsect; + bfd_size_type amt; + + pagesize = getpagesize (); /* Serious cross-target issue here... This + really needs to come from a system-specific + header file. */ + + /* Get the pss entry from the core file */ + + if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0) + return NULL; + + amt = sizeof pss; + if (bfd_bread ((void *) &pss, amt, abfd) != amt) + { + /* Too small to be a core file */ + if (bfd_get_error () != bfd_error_system_call) + bfd_set_error (bfd_error_wrong_format); + return NULL; + } + + amt = sizeof (struct lynx_core_struct); + core_hdr (abfd) = (struct lynx_core_struct *) bfd_zalloc (abfd, amt); + + if (!core_hdr (abfd)) + return NULL; + + strncpy (core_command (abfd), pss.pname, PNMLEN + 1); + + /* Compute the size of the thread contexts */ + + tcontext_size = pss.threadcnt * sizeof (core_st_t); + + /* Allocate space for the thread contexts */ + + threadp = (core_st_t *) bfd_alloc (abfd, tcontext_size); + if (!threadp) + goto fail; + + /* Save thread contexts */ + + if (bfd_seek (abfd, (file_ptr) pagesize, SEEK_SET) != 0) + goto fail; + + if (bfd_bread ((void *) threadp, tcontext_size, abfd) != tcontext_size) + { + /* Probably too small to be a core file */ + if (bfd_get_error () != bfd_error_system_call) + bfd_set_error (bfd_error_wrong_format); + goto fail; + } + + core_signal (abfd) = threadp->currsig; + + newsect = make_bfd_asection (abfd, ".stack", + SEC_ALLOC + SEC_LOAD + SEC_HAS_CONTENTS, + pss.ssize, + pss.slimit, + pagesize + tcontext_size); + if (!newsect) + goto fail; + + newsect = make_bfd_asection (abfd, ".data", + SEC_ALLOC + SEC_LOAD + SEC_HAS_CONTENTS, + pss.data_len + pss.bss_len, + pss.data_start, + pagesize + tcontext_size + pss.ssize +#if defined (SPARC) || defined (__SPARC__) + /* SPARC Lynx seems to start dumping + the .data section at a page + boundary. It's OK to check a + #define like SPARC here because this + file can only be compiled on a Lynx + host. */ + + pss.data_start % pagesize +#endif + ); + if (!newsect) + goto fail; + +/* And, now for the .reg/XXX pseudo sections. Each thread has it's own + .reg/XXX section, where XXX is the thread id (without leading zeros). The + currently running thread (at the time of the core dump) also has an alias + called `.reg' (just to keep GDB happy). Note that we use `.reg/XXX' as + opposed to `.regXXX' because GDB expects that .reg2 will be the floating- + point registers. */ + + newsect = make_bfd_asection (abfd, ".reg", + SEC_HAS_CONTENTS, + sizeof (core_st_t), + 0, + pagesize); + if (!newsect) + goto fail; + + for (secnum = 0; secnum < pss.threadcnt; secnum++) + { + char secname[100]; + + sprintf (secname, ".reg/%d", BUILDPID (0, threadp[secnum].tid)); + newsect = make_bfd_asection (abfd, secname, + SEC_HAS_CONTENTS, + sizeof (core_st_t), + 0, + pagesize + secnum * sizeof (core_st_t)); + if (!newsect) + goto fail; + } + + return abfd->xvec; + + fail: + bfd_release (abfd, core_hdr (abfd)); + core_hdr (abfd) = NULL; + bfd_section_list_clear (abfd); + return NULL; +} + +char * +lynx_core_file_failing_command (bfd *abfd) +{ + return core_command (abfd); +} + +int +lynx_core_file_failing_signal (bfd *abfd) +{ + return core_signal (abfd); +} + +#endif /* LYNX_CORE */ -- cgit v1.2.3