*** empty log message ***
[deliverable/binutils-gdb.git] / bfd / lynx-core.c
CommitLineData
252b5132 1/* BFD back end for Lynx core files
aa820537 2 Copyright 1993, 1994, 1995, 2001, 2002, 2004, 2005, 2006, 2007
eea6121a 3 Free Software Foundation, Inc.
252b5132
RH
4 Written by Stu Grossman of Cygnus Support.
5
cd123cb7 6 This file is part of BFD, the Binary File Descriptor library.
252b5132 7
cd123cb7
NC
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3 of the License, or
11 (at your option) any later version.
252b5132 12
cd123cb7
NC
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
252b5132 17
cd123cb7
NC
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
21 MA 02110-1301, USA. */
252b5132 22
252b5132 23#include "sysdep.h"
3db64b00 24#include "bfd.h"
252b5132
RH
25#include "libbfd.h"
26
27#ifdef LYNX_CORE
28
29#include <sys/conf.h>
30#include <sys/kernel.h>
509945ae 31/* sys/kernel.h should define this, but doesn't always, sigh. */
252b5132
RH
32#ifndef __LYNXOS
33#define __LYNXOS
34#endif
35#include <sys/mem.h>
36#include <sys/signal.h>
37#include <sys/time.h>
38#include <sys/resource.h>
39#include <sys/itimer.h>
40#include <sys/file.h>
41#include <sys/proc.h>
42
43/* These are stored in the bfd's tdata */
44
509945ae 45struct lynx_core_struct
252b5132
RH
46{
47 int sig;
48 char cmd[PNMLEN + 1];
49};
50
51#define core_hdr(bfd) ((bfd)->tdata.lynx_core_data)
52#define core_signal(bfd) (core_hdr(bfd)->sig)
53#define core_command(bfd) (core_hdr(bfd)->cmd)
54
69d246d9 55#define lynx_core_file_matches_executable_p generic_core_file_matches_executable_p
261b8d08 56#define lynx_core_file_pid _bfd_nocore_core_file_pid
69d246d9 57
252b5132
RH
58/* Handle Lynx core dump file. */
59
60static asection *
2c3fc389
NC
61make_bfd_asection (bfd *abfd,
62 const char *name,
63 flagword flags,
64 bfd_size_type size,
65 bfd_vma vma,
66 file_ptr filepos)
252b5132
RH
67{
68 asection *asect;
69 char *newname;
70
dc810e39 71 newname = bfd_alloc (abfd, (bfd_size_type) strlen (name) + 1);
252b5132
RH
72 if (!newname)
73 return NULL;
74
75 strcpy (newname, name);
76
117ed4f8 77 asect = bfd_make_section_with_flags (abfd, newname, flags);
252b5132
RH
78 if (!asect)
79 return NULL;
80
eea6121a 81 asect->size = size;
252b5132
RH
82 asect->vma = vma;
83 asect->filepos = filepos;
84 asect->alignment_power = 2;
85
86 return asect;
87}
88
252b5132 89const bfd_target *
2c3fc389 90lynx_core_file_p (bfd *abfd)
252b5132 91{
252b5132
RH
92 int secnum;
93 struct pssentry pss;
dc810e39 94 bfd_size_type tcontext_size;
252b5132
RH
95 core_st_t *threadp;
96 int pagesize;
97 asection *newsect;
dc810e39 98 bfd_size_type amt;
252b5132
RH
99
100 pagesize = getpagesize (); /* Serious cross-target issue here... This
101 really needs to come from a system-specific
102 header file. */
103
104 /* Get the pss entry from the core file */
105
dc810e39 106 if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0)
252b5132
RH
107 return NULL;
108
dc810e39
AM
109 amt = sizeof pss;
110 if (bfd_bread ((void *) &pss, amt, abfd) != amt)
252b5132
RH
111 {
112 /* Too small to be a core file */
113 if (bfd_get_error () != bfd_error_system_call)
114 bfd_set_error (bfd_error_wrong_format);
115 return NULL;
116 }
117
dc810e39
AM
118 amt = sizeof (struct lynx_core_struct);
119 core_hdr (abfd) = (struct lynx_core_struct *) bfd_zalloc (abfd, amt);
252b5132
RH
120
121 if (!core_hdr (abfd))
122 return NULL;
123
124 strncpy (core_command (abfd), pss.pname, PNMLEN + 1);
125
126 /* Compute the size of the thread contexts */
127
128 tcontext_size = pss.threadcnt * sizeof (core_st_t);
129
130 /* Allocate space for the thread contexts */
131
dc810e39 132 threadp = (core_st_t *) bfd_alloc (abfd, tcontext_size);
252b5132 133 if (!threadp)
9e7b37b3 134 goto fail;
252b5132
RH
135
136 /* Save thread contexts */
137
dc810e39 138 if (bfd_seek (abfd, (file_ptr) pagesize, SEEK_SET) != 0)
9e7b37b3 139 goto fail;
252b5132 140
dc810e39 141 if (bfd_bread ((void *) threadp, tcontext_size, abfd) != tcontext_size)
252b5132
RH
142 {
143 /* Probably too small to be a core file */
144 if (bfd_get_error () != bfd_error_system_call)
145 bfd_set_error (bfd_error_wrong_format);
9e7b37b3 146 goto fail;
252b5132 147 }
509945ae 148
252b5132
RH
149 core_signal (abfd) = threadp->currsig;
150
151 newsect = make_bfd_asection (abfd, ".stack",
152 SEC_ALLOC + SEC_LOAD + SEC_HAS_CONTENTS,
153 pss.ssize,
154 pss.slimit,
155 pagesize + tcontext_size);
156 if (!newsect)
9e7b37b3 157 goto fail;
252b5132
RH
158
159 newsect = make_bfd_asection (abfd, ".data",
160 SEC_ALLOC + SEC_LOAD + SEC_HAS_CONTENTS,
161 pss.data_len + pss.bss_len,
162 pss.data_start,
163 pagesize + tcontext_size + pss.ssize
164#if defined (SPARC) || defined (__SPARC__)
165 /* SPARC Lynx seems to start dumping
166 the .data section at a page
167 boundary. It's OK to check a
168 #define like SPARC here because this
169 file can only be compiled on a Lynx
170 host. */
171 + pss.data_start % pagesize
172#endif
173 );
174 if (!newsect)
9e7b37b3 175 goto fail;
252b5132
RH
176
177/* And, now for the .reg/XXX pseudo sections. Each thread has it's own
178 .reg/XXX section, where XXX is the thread id (without leading zeros). The
179 currently running thread (at the time of the core dump) also has an alias
180 called `.reg' (just to keep GDB happy). Note that we use `.reg/XXX' as
181 opposed to `.regXXX' because GDB expects that .reg2 will be the floating-
182 point registers. */
183
184 newsect = make_bfd_asection (abfd, ".reg",
185 SEC_HAS_CONTENTS,
186 sizeof (core_st_t),
187 0,
188 pagesize);
189 if (!newsect)
9e7b37b3 190 goto fail;
252b5132
RH
191
192 for (secnum = 0; secnum < pss.threadcnt; secnum++)
193 {
194 char secname[100];
195
196 sprintf (secname, ".reg/%d", BUILDPID (0, threadp[secnum].tid));
197 newsect = make_bfd_asection (abfd, secname,
198 SEC_HAS_CONTENTS,
199 sizeof (core_st_t),
200 0,
201 pagesize + secnum * sizeof (core_st_t));
202 if (!newsect)
9e7b37b3 203 goto fail;
252b5132
RH
204 }
205
206 return abfd->xvec;
9e7b37b3
AM
207
208 fail:
209 bfd_release (abfd, core_hdr (abfd));
210 core_hdr (abfd) = NULL;
211 bfd_section_list_clear (abfd);
212 return NULL;
252b5132
RH
213}
214
215char *
2c3fc389 216lynx_core_file_failing_command (bfd *abfd)
252b5132
RH
217{
218 return core_command (abfd);
219}
220
252b5132 221int
2c3fc389 222lynx_core_file_failing_signal (bfd *abfd)
252b5132
RH
223{
224 return core_signal (abfd);
225}
226
252b5132 227#endif /* LYNX_CORE */
This page took 0.652304 seconds and 4 git commands to generate.