Make all callers of malloc or realloc (including via obstacks)
[deliverable/binutils-gdb.git] / bfd / rs6000-core.c
1 /* IBM RS/6000 "XCOFF" back-end for BFD.
2 Copyright (C) 1990, 1991 Free Software Foundation, Inc.
3 FIXME: Can someone provide a transliteration of this name into ASCII?
4 Using the following chars caused a compiler warning on HIUX (so I replaced
5 them with octal escapes), and isn't useful without an understanding of what
6 character set it is.
7 Written by Metin G. Ozisik, Mimi Ph\373\364ng-Th\345o V\365,
8 and John Gilmore.
9 Archive support from Damon A. Permezel.
10 Contributed by IBM Corporation and Cygnus Support.
11
12 This file is part of BFD, the Binary File Descriptor library.
13
14 This program is free software; you can redistribute it and/or modify
15 it under the terms of the GNU General Public License as published by
16 the Free Software Foundation; either version 2 of the License, or
17 (at your option) any later version.
18
19 This program is distributed in the hope that it will be useful,
20 but WITHOUT ANY WARRANTY; without even the implied warranty of
21 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 GNU General Public License for more details.
23
24 You should have received a copy of the GNU General Public License
25 along with this program; if not, write to the Free Software
26 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
27
28 /* This port currently only handles reading object files, except when
29 compiled on an RS/6000 host. -- no archive support, no core files.
30 In all cases, it does not support writing.
31
32 FIXMEmgo comments are left from Metin Ozisik's original port.
33
34 This is in a separate file from coff-rs6000.c, because it includes
35 system include files that conflict with coff/rs6000.h.
36 */
37
38 /* Internalcoff.h and coffcode.h modify themselves based on this flag. */
39 #define RS6000COFF_C 1
40
41 #include "bfd.h"
42 #include "sysdep.h"
43 #include "libbfd.h"
44
45 #ifdef COREFILES_PLEASE
46
47 /* AOUTHDR is defined by the above. We need another defn of it, from the
48 system include files. Punt the old one and get us a new name for the
49 typedef in the system include files. */
50 #ifdef AOUTHDR
51 #undef AOUTHDR
52 #endif
53 #define AOUTHDR second_AOUTHDR
54
55 #undef SCNHDR
56
57
58 /* ------------------------------------------------------------------------ */
59 /* Support for core file stuff.. */
60 /* ------------------------------------------------------------------------ */
61
62 #include <sys/user.h>
63 #include <sys/ldr.h>
64 #include <sys/core.h>
65
66
67 /* Number of special purpose registers supported by gdb. This value
68 should match `tm.h' in gdb directory. Clean this mess up and use
69 the macros in sys/reg.h. FIXMEmgo. */
70
71 #define NUM_OF_SPEC_REGS 7
72 #define STACK_END_ADDR 0x2ff80000
73
74 #define core_hdr(bfd) (((Rs6kCorData*)(bfd->tdata.any))->hdr)
75 #define core_datasec(bfd) (((Rs6kCorData*)(bfd->tdata.any))->data_section)
76 #define core_stacksec(bfd) (((Rs6kCorData*)(bfd->tdata.any))->stack_section)
77 #define core_regsec(bfd) (((Rs6kCorData*)(bfd->tdata.any))->reg_section)
78 #define core_reg2sec(bfd) (((Rs6kCorData*)(bfd->tdata.any))->reg2_section)
79
80 /* These are stored in the bfd's tdata */
81 typedef struct {
82 struct core *hdr; /* core file header */
83 asection *data_section,
84 *stack_section,
85 *reg_section, /* section for GPRs and special registers. */
86 *reg2_section; /* section for FPRs. */
87
88 /* This tells us where everything is mapped (shared libraries and so on).
89 GDB needs it. */
90 asection *ldinfo_section;
91 #define core_ldinfosec(bfd) (((Rs6kCorData *)(bfd->tdata.any))->ldinfo_section)
92 } Rs6kCorData;
93
94
95 /* Decide if a given bfd represents a `core' file or not. There really is no
96 magic number or anything like, in rs6000coff. */
97
98 bfd_target *
99 rs6000coff_core_p (abfd)
100 bfd *abfd;
101 {
102 int fd;
103 struct core_dump coredata;
104 struct stat statbuf;
105 char *tmpptr;
106
107 /* Use bfd_xxx routines, rather than O/S primitives to read coredata. FIXMEmgo */
108 fd = open (abfd->filename, O_RDONLY);
109 if (fd < 0)
110 {
111 bfd_error = system_call_error;
112 return NULL;
113 }
114
115 if (fstat (fd, &statbuf) < 0)
116 {
117 bfd_error = system_call_error;
118 close (fd);
119 return NULL;
120 }
121 if (read (fd, &coredata, sizeof (struct core_dump))
122 != sizeof (struct core_dump))
123 {
124 bfd_error = wrong_format;
125 close (fd);
126 return NULL;
127 }
128
129 if (close (fd) < 0)
130 {
131 bfd_error = system_call_error;
132 return NULL;
133 }
134
135 /* If the core file ulimit is too small, the system will first
136 omit the data segment, then omit the stack, then decline to
137 dump core altogether (as far as I know UBLOCK_VALID and LE_VALID
138 are always set) (this is based on experimentation on AIX 3.2).
139 Now, the thing is that GDB users will be surprised
140 if segments just silently don't appear (well, maybe they would
141 think to check "info files", I don't know), but we have no way of
142 returning warnings (as opposed to errors).
143
144 For the data segment, we have no choice but to keep going if it's
145 not there, since the default behavior is not to dump it (regardless
146 of the ulimit, it's based on SA_FULLDUMP). But for the stack segment,
147 if it's not there, we refuse to have anything to do with this core
148 file. The usefulness of a core dump without a stack segment is pretty
149 limited anyway. */
150
151 if (!(coredata.c_flag & UBLOCK_VALID)
152 || !(coredata.c_flag & LE_VALID))
153 {
154 bfd_error = wrong_format;
155 return NULL;
156 }
157
158 if ((coredata.c_flag & CORE_TRUNC)
159 || !(coredata.c_flag & USTACK_VALID))
160 {
161 bfd_error = file_truncated;
162 return NULL;
163 }
164
165 if (((bfd_vma)coredata.c_stack + coredata.c_size
166 + ((coredata.c_flag & FULL_CORE) ? coredata.c_u.u_dsize : 0))
167 != statbuf.st_size)
168 {
169 /* If the size is wrong, it means we're misinterpreting something. */
170 bfd_error = wrong_format;
171 return NULL;
172 }
173
174 /* Sanity check on the c_tab field. */
175 if ((u_long) coredata.c_tab < sizeof coredata ||
176 (u_long) coredata.c_tab >= statbuf.st_size ||
177 (long) coredata.c_tab >= (long)coredata.c_stack)
178 {
179 bfd_error = wrong_format;
180 return NULL;
181 }
182
183 /* maybe you should alloc space for the whole core chunk over here!! FIXMEmgo */
184 tmpptr = (char*)bfd_zalloc (abfd, sizeof (Rs6kCorData));
185 if (!tmpptr)
186 {
187 bfd_error = no_memory;
188 return NULL;
189 }
190
191 set_tdata (abfd, tmpptr);
192
193 /* .stack section. */
194 if ((core_stacksec (abfd) = (asection*) bfd_zalloc (abfd, sizeof (asection)))
195 == NULL) {
196 bfd_error = no_memory;
197 /* bfd_release (abfd, ???? ) */
198 return NULL;
199 }
200 core_stacksec (abfd)->name = ".stack";
201 core_stacksec (abfd)->flags = SEC_ALLOC + SEC_LOAD;
202 core_stacksec (abfd)->_raw_size = coredata.c_size;
203 core_stacksec (abfd)->vma = STACK_END_ADDR - coredata.c_size;
204 core_stacksec (abfd)->filepos = (int)coredata.c_stack; /*???? */
205
206 /* .reg section for GPRs and special registers. */
207 if ((core_regsec (abfd) = (asection*) bfd_zalloc (abfd, sizeof (asection)))
208 == NULL) {
209 bfd_error = no_memory;
210 /* bfd_release (abfd, ???? ) */
211 return NULL;
212 }
213 core_regsec (abfd)->name = ".reg";
214 core_regsec (abfd)->flags = SEC_ALLOC;
215 core_regsec (abfd)->_raw_size = (32 + NUM_OF_SPEC_REGS) * 4;
216 core_regsec (abfd)->vma = 0; /* not used?? */
217 core_regsec (abfd)->filepos =
218 (char*)&coredata.c_u.u_save - (char*)&coredata;
219
220 /* .reg2 section for FPRs (floating point registers). */
221 if ((core_reg2sec (abfd) = (asection*) bfd_zalloc (abfd, sizeof (asection)))
222 == NULL) {
223 bfd_error = no_memory;
224 /* bfd_release (abfd, ???? ) */
225 return NULL;
226 }
227 core_reg2sec (abfd)->name = ".reg2";
228 core_reg2sec (abfd)->flags = SEC_ALLOC;
229 core_reg2sec (abfd)->_raw_size = 8 * 32; /* 32 FPRs. */
230 core_reg2sec (abfd)->vma = 0; /* not used?? */
231 core_reg2sec (abfd)->filepos =
232 (char*)&coredata.c_u.u_save.fpr[0] - (char*)&coredata;
233
234 if ((core_ldinfosec (abfd) = (asection*) bfd_zalloc (abfd, sizeof (asection)))
235 == NULL) {
236 bfd_error = no_memory;
237 /* bfd_release (abfd, ???? ) */
238 return NULL;
239 }
240 core_ldinfosec (abfd)->name = ".ldinfo";
241 core_ldinfosec (abfd)->flags = SEC_ALLOC + SEC_LOAD;
242 /* To actually find out how long this section is in this particular
243 core dump would require going down the whole list of struct ld_info's.
244 See if we can just fake it. */
245 core_ldinfosec (abfd)->_raw_size = 0x7fffffff;
246 /* Not relevant for ldinfo section. */
247 core_ldinfosec (abfd)->vma = 0;
248 core_ldinfosec (abfd)->filepos = coredata.c_tab;
249
250 /* set up section chain here. */
251 abfd->section_count = 4;
252 abfd->sections = core_stacksec (abfd);
253 core_stacksec (abfd)->next = core_regsec(abfd);
254 core_regsec (abfd)->next = core_reg2sec (abfd);
255 core_reg2sec (abfd)->next = core_ldinfosec (abfd);
256 core_ldinfosec (abfd)->next = NULL;
257
258 if (coredata.c_flag & FULL_CORE)
259 {
260 asection *sec = (asection *) bfd_zalloc (abfd, sizeof (asection));
261 if (sec == NULL)
262 {
263 bfd_error = no_memory;
264 return NULL;
265 }
266 sec->name = ".data";
267 sec->flags = SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS;
268 sec->_raw_size = coredata.c_u.u_dsize;
269 sec->vma = CDATA_ADDR (coredata.c_u.u_dsize);
270 sec->filepos = (int)coredata.c_stack + coredata.c_size;
271
272 sec->next = abfd->sections;
273 abfd->sections = sec;
274 ++abfd->section_count;
275 }
276
277 return abfd->xvec; /* this is garbage for now. */
278 }
279
280
281
282 /* return `true' if given core is from the given executable.. */
283 boolean
284 rs6000coff_core_file_matches_executable_p (core_bfd, exec_bfd)
285 bfd *core_bfd;
286 bfd *exec_bfd;
287 {
288 FILE *fd;
289 struct core_dump coredata;
290 struct ld_info ldinfo;
291 char pathname [1024];
292 char *str1, *str2;
293
294 /* Use bfd_xxx routines, rather than O/S primitives, do error checking!!
295 FIXMEmgo */
296 /* Actually should be able to use bfd_get_section_contents now that
297 we have a .ldinfo section. */
298 fd = fopen (core_bfd->filename, FOPEN_RB);
299
300 fread (&coredata, sizeof (struct core_dump), 1, fd);
301 fseek (fd, (long)coredata.c_tab, 0);
302 fread (&ldinfo, (char*)&ldinfo.ldinfo_filename[0] - (char*)&ldinfo.ldinfo_next,
303 1, fd);
304 fscanf (fd, "%s", pathname);
305
306 str1 = strrchr (pathname, '/');
307 str2 = strrchr (exec_bfd->filename, '/');
308
309 /* step over character '/' */
310 str1 = str1 ? str1+1 : &pathname[0];
311 str2 = str2 ? str2+1 : exec_bfd->filename;
312
313 fclose (fd);
314 return strcmp (str1, str2) == 0;
315 }
316
317
318 boolean
319 rs6000coff_get_section_contents (abfd, section, location, offset, count)
320 bfd *abfd;
321 sec_ptr section;
322 PTR location;
323 file_ptr offset;
324 int count;
325 {
326 if (count == 0)
327 return true;
328
329 /* Reading a core file's sections will be slightly different. For the
330 rest of them we can use bfd_generic_get_section_contents () I suppose. */
331 /* Make sure this routine works for any bfd and any section. FIXMEmgo. */
332
333 if (abfd->format == bfd_core && strcmp (section->name, ".reg") == 0) {
334
335 struct mstsave mstatus;
336 int regoffset = (char*)&mstatus.gpr[0] - (char*)&mstatus;
337
338 /* Assert that the only way this code will be executed is reading the
339 whole section. */
340 if (offset || count != (sizeof(mstatus.gpr) + (4 * NUM_OF_SPEC_REGS)))
341 fprintf (stderr, "ERROR! in rs6000coff_get_section_contents()\n");
342
343 /* for `.reg' section, `filepos' is a pointer to the `mstsave' structure
344 in the core file. */
345
346 /* read GPR's into the location. */
347 if ( bfd_seek(abfd, section->filepos + regoffset, SEEK_SET) == -1
348 || bfd_read(location, sizeof (mstatus.gpr), 1, abfd) != sizeof (mstatus.gpr))
349 return (false); /* on error */
350
351 /* increment location to the beginning of special registers in the section,
352 reset register offset value to the beginning of first special register
353 in mstsave structure, and read special registers. */
354
355 location = (PTR) ((char*)location + sizeof (mstatus.gpr));
356 regoffset = (char*)&mstatus.iar - (char*)&mstatus;
357
358 if ( bfd_seek(abfd, section->filepos + regoffset, SEEK_SET) == -1
359 || bfd_read(location, 4 * NUM_OF_SPEC_REGS, 1, abfd) !=
360 4 * NUM_OF_SPEC_REGS)
361 return (false); /* on error */
362
363 /* increment location address, and read the special registers.. */
364 /* FIXMEmgo */
365 return (true);
366 }
367
368 /* else, use default bfd section content transfer. */
369 else
370 return bfd_generic_get_section_contents
371 (abfd, section, location, offset, count);
372 }
373
374 #endif /* COREFILES_PLEASE */
This page took 0.038973 seconds and 5 git commands to generate.