]>
Commit | Line | Data |
---|---|---|
2b91cc45 SG |
1 | /* BFD back end for Lynx core files |
2 | Copyright 1993 Free Software Foundation, Inc. | |
3 | Written by Stu Grossman of Cygnus Support. | |
4 | ||
5 | This file is part of BFD, the Binary File Descriptor library. | |
6 | ||
7 | This program is free software; you can redistribute it and/or modify | |
8 | it under the terms of the GNU General Public License as published by | |
9 | the Free Software Foundation; either version 2 of the License, or | |
10 | (at your option) any later version. | |
11 | ||
12 | This program is distributed in the hope that it will be useful, | |
13 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
15 | GNU General Public License for more details. | |
16 | ||
17 | You should have received a copy of the GNU General Public License | |
18 | along with this program; if not, write to the Free Software | |
19 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ | |
20 | ||
21 | #include "bfd.h" | |
22 | #include "sysdep.h" | |
23 | #include "libbfd.h" | |
24 | ||
25 | #ifdef HOST_LYNX /* Core files only work locally for now */ | |
26 | ||
27 | /* These are stored in the bfd's tdata */ | |
28 | ||
29 | struct lynx_core_struct | |
30 | { | |
31 | int sig; | |
32 | char cmd[PNMLEN + 1]; | |
33 | }; | |
34 | ||
35 | #define core_hdr(bfd) ((bfd)->tdata.lynx_core_data) | |
36 | #define core_signal(bfd) (core_hdr(bfd)->sig) | |
37 | #define core_command(bfd) (core_hdr(bfd)->cmd) | |
38 | ||
39 | /* Handle Lynx core dump file. */ | |
40 | ||
41 | static asection * | |
42 | make_bfd_asection (abfd, name, flags, _raw_size, vma, filepos) | |
43 | bfd *abfd; | |
44 | CONST char *name; | |
45 | flagword flags; | |
46 | bfd_size_type _raw_size; | |
47 | bfd_vma vma; | |
48 | file_ptr filepos; | |
49 | { | |
50 | asection *asect; | |
51 | char *newname; | |
52 | ||
53 | newname = bfd_alloc (abfd, strlen (name) + 1); | |
54 | if (!newname) | |
55 | return NULL; | |
56 | ||
57 | strcpy (newname, name); | |
58 | ||
59 | asect = bfd_make_section (abfd, newname); | |
60 | if (!asect) | |
61 | return NULL; | |
62 | ||
63 | asect->flags = flags; | |
64 | asect->_raw_size = _raw_size; | |
65 | asect->vma = vma; | |
66 | asect->filepos = filepos; | |
67 | asect->alignment_power = 2; | |
68 | ||
69 | return asect; | |
70 | } | |
71 | ||
72 | /* ARGSUSED */ | |
73 | bfd_target * | |
74 | lynx_core_file_p (abfd) | |
75 | bfd *abfd; | |
76 | { | |
77 | int val; | |
78 | int secnum; | |
79 | struct pssentry pss; | |
80 | size_t tcontext_size; | |
81 | core_st_t *threadp; | |
82 | int pagesize; | |
83 | asection *newsect; | |
84 | ||
85 | pagesize = getpagesize (); /* Serious cross-target issue here... This | |
86 | really needs to come from a system-specific | |
87 | header file. */ | |
88 | ||
89 | /* Get the pss entry from the core file */ | |
90 | ||
91 | bfd_seek (abfd, 0, SEEK_SET); | |
92 | ||
93 | val = bfd_read ((void *)&pss, 1, sizeof pss, abfd); | |
94 | if (val != sizeof pss) | |
95 | { | |
96 | /* Too small to be a core file */ | |
97 | bfd_error = wrong_format; | |
98 | return NULL; | |
99 | } | |
100 | ||
101 | core_hdr (abfd) = (struct lynx_core_struct *) | |
102 | bfd_zalloc (abfd, sizeof (struct lynx_core_struct)); | |
103 | ||
104 | if (!core_hdr (abfd)) | |
105 | { | |
106 | bfd_error = no_memory; | |
107 | return NULL; | |
108 | } | |
109 | ||
110 | strncpy (core_command (abfd), pss.pname, PNMLEN + 1); | |
111 | ||
112 | /* Compute the size of the thread contexts */ | |
113 | ||
114 | tcontext_size = pss.threadcnt * sizeof (core_st_t); | |
115 | ||
116 | /* Allocate space for the thread contexts */ | |
117 | ||
118 | threadp = (core_st_t *)bfd_zalloc (abfd, tcontext_size); | |
119 | if (!threadp) | |
120 | { | |
121 | bfd_error = no_memory; | |
122 | return NULL; | |
123 | } | |
124 | ||
125 | /* Save thread contexts */ | |
126 | ||
127 | bfd_seek (abfd, pagesize, SEEK_SET); | |
128 | ||
129 | val = bfd_read ((void *)threadp, pss.threadcnt, sizeof (core_st_t), abfd); | |
130 | ||
131 | if (val != tcontext_size) | |
132 | { | |
133 | /* Probably too small to be a core file */ | |
134 | bfd_error = wrong_format; | |
135 | return NULL; | |
136 | } | |
137 | ||
138 | core_signal (abfd) = threadp->currsig; | |
139 | ||
140 | newsect = make_bfd_asection (abfd, ".stack", | |
141 | SEC_ALLOC + SEC_LOAD + SEC_HAS_CONTENTS, | |
142 | pss.ssize, | |
143 | pss.slimit, | |
144 | pagesize + tcontext_size); | |
145 | if (!newsect) | |
146 | { | |
147 | bfd_error = no_memory; | |
148 | return NULL; | |
149 | } | |
150 | ||
151 | newsect = make_bfd_asection (abfd, ".data", | |
152 | SEC_ALLOC + SEC_LOAD + SEC_HAS_CONTENTS, | |
153 | pss.data_len + pss.bss_len, | |
154 | pss.data_start, | |
155 | pagesize + tcontext_size + pss.ssize); | |
156 | if (!newsect) | |
157 | { | |
158 | bfd_error = no_memory; | |
159 | return NULL; | |
160 | } | |
161 | ||
162 | for (secnum = 0; secnum < pss.threadcnt; secnum++) | |
163 | { | |
164 | char secname[100]; | |
165 | ||
166 | sprintf (secname, ".reg%d", threadp[secnum].tid); | |
167 | newsect = make_bfd_asection (abfd, secname, | |
168 | SEC_ALLOC + SEC_HAS_CONTENTS, | |
169 | sizeof (core_st_t), | |
170 | 0, | |
171 | pagesize + secnum * sizeof (core_st_t)); | |
172 | if (!newsect) | |
173 | { | |
174 | bfd_error = no_memory; | |
175 | return NULL; | |
176 | } | |
177 | } | |
178 | ||
179 | return abfd->xvec; | |
180 | } | |
181 | ||
182 | char * | |
183 | lynx_core_file_failing_command (abfd) | |
184 | bfd *abfd; | |
185 | { | |
186 | return core_command (abfd); | |
187 | } | |
188 | ||
189 | /* ARGSUSED */ | |
190 | int | |
191 | lynx_core_file_failing_signal (abfd) | |
192 | bfd *abfd; | |
193 | { | |
194 | return core_signal (abfd); | |
195 | } | |
196 | ||
197 | /* ARGSUSED */ | |
198 | boolean | |
199 | lynx_core_file_matches_executable_p (core_bfd, exec_bfd) | |
200 | bfd *core_bfd, *exec_bfd; | |
201 | { | |
202 | return true; /* FIXME, We have no way of telling at this point */ | |
203 | } | |
204 | ||
205 | #endif /* HOST_LYNX */ |