Still a lot of bogus code; just a checkpoint.
[deliverable/binutils-gdb.git] / bfd / rs6000-core.c
CommitLineData
9783e04a 1/* IBM RS/6000 "XCOFF" back-end for BFD.
f366291b 2 Copyright (C) 1990, 91, 92, 93, 94, 95, 1996 Free Software Foundation, Inc.
9783e04a
DM
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
12This file is part of BFD, the Binary File Descriptor library.
13
14This program is free software; you can redistribute it and/or modify
15it under the terms of the GNU General Public License as published by
16the Free Software Foundation; either version 2 of the License, or
17(at your option) any later version.
18
19This program is distributed in the hope that it will be useful,
20but WITHOUT ANY WARRANTY; without even the implied warranty of
21MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22GNU General Public License for more details.
23
24You should have received a copy of the GNU General Public License
25along with this program; if not, write to the Free Software
138b9b81 26Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
9783e04a
DM
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
138b9b81 45#ifdef AIX_CORE
9783e04a
DM
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
9783e04a
DM
72
73#define core_hdr(bfd) (((Rs6kCorData*)(bfd->tdata.any))->hdr)
74#define core_datasec(bfd) (((Rs6kCorData*)(bfd->tdata.any))->data_section)
75#define core_stacksec(bfd) (((Rs6kCorData*)(bfd->tdata.any))->stack_section)
76#define core_regsec(bfd) (((Rs6kCorData*)(bfd->tdata.any))->reg_section)
77#define core_reg2sec(bfd) (((Rs6kCorData*)(bfd->tdata.any))->reg2_section)
78
138b9b81
PS
79/* AIX 4.1 Changed the names and locations of a few items in the core file,
80 this seems to be the quickest easiet way to deal with it.
81
82 Note however that encoding magic addresses (STACK_END_ADDR) is going
83 to be _very_ fragile. But I don't see any easy way to get that info
84 right now. */
f366291b 85#ifdef CORE_VERSION_1
138b9b81
PS
86#define CORE_DATA_SIZE_FIELD c_u.U_dsize
87#define CORE_COMM_FIELD c_u.U_comm
88#define SAVE_FIELD c_mst
89#define STACK_END_ADDR 0x2ff23000
90#else
91#define CORE_DATA_SIZE_FIELD c_u.u_dsize
92#define CORE_COMM_FIELD c_u.u_comm
93#define SAVE_FIELD c_u.u_save
94#define STACK_END_ADDR 0x2ff80000
95#endif
96
9783e04a
DM
97/* These are stored in the bfd's tdata */
98typedef struct {
138b9b81 99 struct core_dump hdr; /* core file header */
9783e04a
DM
100 asection *data_section,
101 *stack_section,
102 *reg_section, /* section for GPRs and special registers. */
103 *reg2_section; /* section for FPRs. */
104
105 /* This tells us where everything is mapped (shared libraries and so on).
106 GDB needs it. */
107 asection *ldinfo_section;
108#define core_ldinfosec(bfd) (((Rs6kCorData *)(bfd->tdata.any))->ldinfo_section)
109} Rs6kCorData;
110
111
112/* Decide if a given bfd represents a `core' file or not. There really is no
113 magic number or anything like, in rs6000coff. */
114
138b9b81 115const bfd_target *
9783e04a
DM
116rs6000coff_core_p (abfd)
117 bfd *abfd;
118{
119 int fd;
120 struct core_dump coredata;
121 struct stat statbuf;
122 char *tmpptr;
123
124 /* Use bfd_xxx routines, rather than O/S primitives to read coredata. FIXMEmgo */
125 fd = open (abfd->filename, O_RDONLY);
126 if (fd < 0)
127 {
138b9b81 128 bfd_set_error (bfd_error_system_call);
9783e04a
DM
129 return NULL;
130 }
131
132 if (fstat (fd, &statbuf) < 0)
133 {
138b9b81 134 bfd_set_error (bfd_error_system_call);
9783e04a
DM
135 close (fd);
136 return NULL;
137 }
138 if (read (fd, &coredata, sizeof (struct core_dump))
139 != sizeof (struct core_dump))
140 {
138b9b81 141 bfd_set_error (bfd_error_wrong_format);
9783e04a
DM
142 close (fd);
143 return NULL;
144 }
145
146 if (close (fd) < 0)
147 {
138b9b81 148 bfd_set_error (bfd_error_system_call);
9783e04a
DM
149 return NULL;
150 }
151
152 /* If the core file ulimit is too small, the system will first
153 omit the data segment, then omit the stack, then decline to
154 dump core altogether (as far as I know UBLOCK_VALID and LE_VALID
155 are always set) (this is based on experimentation on AIX 3.2).
156 Now, the thing is that GDB users will be surprised
157 if segments just silently don't appear (well, maybe they would
f366291b 158 think to check "info files", I don't know).
9783e04a
DM
159
160 For the data segment, we have no choice but to keep going if it's
161 not there, since the default behavior is not to dump it (regardless
162 of the ulimit, it's based on SA_FULLDUMP). But for the stack segment,
163 if it's not there, we refuse to have anything to do with this core
164 file. The usefulness of a core dump without a stack segment is pretty
165 limited anyway. */
166
167 if (!(coredata.c_flag & UBLOCK_VALID)
168 || !(coredata.c_flag & LE_VALID))
169 {
138b9b81 170 bfd_set_error (bfd_error_wrong_format);
9783e04a
DM
171 return NULL;
172 }
173
f366291b 174 if (!(coredata.c_flag & USTACK_VALID))
9783e04a 175 {
138b9b81 176 bfd_set_error (bfd_error_file_truncated);
9783e04a
DM
177 return NULL;
178 }
179
138b9b81
PS
180 /* Don't check the core file size for a full core, AIX 4.1 includes
181 additional shared library sections in a full core. */
f366291b 182 if (!(coredata.c_flag & (FULL_CORE | CORE_TRUNC))
138b9b81 183 && ((bfd_vma)coredata.c_stack + coredata.c_size) != statbuf.st_size)
9783e04a
DM
184 {
185 /* If the size is wrong, it means we're misinterpreting something. */
138b9b81 186 bfd_set_error (bfd_error_wrong_format);
9783e04a
DM
187 return NULL;
188 }
189
190 /* Sanity check on the c_tab field. */
191 if ((u_long) coredata.c_tab < sizeof coredata ||
192 (u_long) coredata.c_tab >= statbuf.st_size ||
193 (long) coredata.c_tab >= (long)coredata.c_stack)
194 {
138b9b81 195 bfd_set_error (bfd_error_wrong_format);
9783e04a
DM
196 return NULL;
197 }
198
f366291b
PS
199 /* Issue warning if the core file was truncated during writing. */
200 if (coredata.c_flag & CORE_TRUNC)
201 (*_bfd_error_handler) ("%s: warning core file truncated",
202 bfd_get_filename (abfd));
203
9783e04a
DM
204 /* maybe you should alloc space for the whole core chunk over here!! FIXMEmgo */
205 tmpptr = (char*)bfd_zalloc (abfd, sizeof (Rs6kCorData));
206 if (!tmpptr)
f366291b 207 return NULL;
9783e04a
DM
208
209 set_tdata (abfd, tmpptr);
210
138b9b81
PS
211 /* Copy core file header. */
212 core_hdr (abfd) = coredata;
213
9783e04a
DM
214 /* .stack section. */
215 if ((core_stacksec (abfd) = (asection*) bfd_zalloc (abfd, sizeof (asection)))
f366291b 216 == NULL)
9783e04a 217 return NULL;
9783e04a 218 core_stacksec (abfd)->name = ".stack";
138b9b81 219 core_stacksec (abfd)->flags = SEC_ALLOC + SEC_LOAD + SEC_HAS_CONTENTS;
9783e04a
DM
220 core_stacksec (abfd)->_raw_size = coredata.c_size;
221 core_stacksec (abfd)->vma = STACK_END_ADDR - coredata.c_size;
222 core_stacksec (abfd)->filepos = (int)coredata.c_stack; /*???? */
223
224 /* .reg section for GPRs and special registers. */
225 if ((core_regsec (abfd) = (asection*) bfd_zalloc (abfd, sizeof (asection)))
f366291b 226 == NULL)
9783e04a 227 return NULL;
9783e04a 228 core_regsec (abfd)->name = ".reg";
138b9b81 229 core_regsec (abfd)->flags = SEC_HAS_CONTENTS;
9783e04a
DM
230 core_regsec (abfd)->_raw_size = (32 + NUM_OF_SPEC_REGS) * 4;
231 core_regsec (abfd)->vma = 0; /* not used?? */
232 core_regsec (abfd)->filepos =
138b9b81 233 (char*)&coredata.SAVE_FIELD - (char*)&coredata;
9783e04a
DM
234
235 /* .reg2 section for FPRs (floating point registers). */
236 if ((core_reg2sec (abfd) = (asection*) bfd_zalloc (abfd, sizeof (asection)))
f366291b 237 == NULL)
9783e04a 238 return NULL;
9783e04a 239 core_reg2sec (abfd)->name = ".reg2";
138b9b81 240 core_reg2sec (abfd)->flags = SEC_HAS_CONTENTS;
9783e04a
DM
241 core_reg2sec (abfd)->_raw_size = 8 * 32; /* 32 FPRs. */
242 core_reg2sec (abfd)->vma = 0; /* not used?? */
243 core_reg2sec (abfd)->filepos =
138b9b81 244 (char*)&coredata.SAVE_FIELD.fpr[0] - (char*)&coredata;
9783e04a
DM
245
246 if ((core_ldinfosec (abfd) = (asection*) bfd_zalloc (abfd, sizeof (asection)))
f366291b 247 == NULL)
9783e04a 248 return NULL;
9783e04a 249 core_ldinfosec (abfd)->name = ".ldinfo";
138b9b81 250 core_ldinfosec (abfd)->flags = SEC_HAS_CONTENTS;
9783e04a
DM
251 /* To actually find out how long this section is in this particular
252 core dump would require going down the whole list of struct ld_info's.
253 See if we can just fake it. */
254 core_ldinfosec (abfd)->_raw_size = 0x7fffffff;
255 /* Not relevant for ldinfo section. */
256 core_ldinfosec (abfd)->vma = 0;
138b9b81 257 core_ldinfosec (abfd)->filepos = (file_ptr) coredata.c_tab;
9783e04a
DM
258
259 /* set up section chain here. */
260 abfd->section_count = 4;
261 abfd->sections = core_stacksec (abfd);
262 core_stacksec (abfd)->next = core_regsec(abfd);
263 core_regsec (abfd)->next = core_reg2sec (abfd);
264 core_reg2sec (abfd)->next = core_ldinfosec (abfd);
265 core_ldinfosec (abfd)->next = NULL;
266
267 if (coredata.c_flag & FULL_CORE)
268 {
269 asection *sec = (asection *) bfd_zalloc (abfd, sizeof (asection));
270 if (sec == NULL)
f366291b 271 return NULL;
9783e04a
DM
272 sec->name = ".data";
273 sec->flags = SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS;
138b9b81
PS
274 sec->_raw_size = coredata.CORE_DATA_SIZE_FIELD;
275 sec->vma = CDATA_ADDR (coredata.CORE_DATA_SIZE_FIELD);
9783e04a
DM
276 sec->filepos = (int)coredata.c_stack + coredata.c_size;
277
278 sec->next = abfd->sections;
279 abfd->sections = sec;
280 ++abfd->section_count;
281 }
282
283 return abfd->xvec; /* this is garbage for now. */
284}
285
286
287
288/* return `true' if given core is from the given executable.. */
289boolean
290rs6000coff_core_file_matches_executable_p (core_bfd, exec_bfd)
291 bfd *core_bfd;
292 bfd *exec_bfd;
293{
9783e04a
DM
294 struct core_dump coredata;
295 struct ld_info ldinfo;
f366291b
PS
296 int size;
297 char *path, *s;
298 size_t alloc;
138b9b81 299 const char *str1, *str2;
f366291b
PS
300 boolean ret;
301
302 if (bfd_seek (core_bfd, 0, SEEK_SET) != 0
303 || bfd_read (&coredata, sizeof coredata, 1, core_bfd) != sizeof coredata)
304 return false;
305
306 if (bfd_seek (core_bfd, (long) coredata.c_tab, SEEK_SET) != 0)
307 return false;
308
309 size = (char *) &ldinfo.ldinfo_filename[0] - (char *) &ldinfo.ldinfo_next;
310 if (bfd_read (&ldinfo, size, 1, core_bfd) != size)
311 return false;
9783e04a 312
f366291b
PS
313 alloc = 100;
314 path = bfd_malloc (alloc);
315 if (path == NULL)
316 return false;
317 s = path;
318
319 while (1)
320 {
321 if (bfd_read (s, 1, 1, core_bfd) != 1)
322 {
323 free (path);
324 return false;
325 }
326 if (*s == '\0')
327 break;
328 ++s;
329 if (s == path + alloc)
330 {
331 char *n;
332
333 alloc *= 2;
334 n = bfd_realloc (path, alloc);
335 if (n == NULL)
336 {
337 free (path);
338 return false;
339 }
340 s = n + (path - s);
341 path = n;
342 }
343 }
9783e04a 344
f366291b 345 str1 = strrchr (path, '/');
9783e04a
DM
346 str2 = strrchr (exec_bfd->filename, '/');
347
348 /* step over character '/' */
f366291b
PS
349 str1 = str1 != NULL ? str1 + 1 : path;
350 str2 = str2 != NULL ? str2 + 1 : exec_bfd->filename;
351
352 if (strcmp (str1, str2) == 0)
353 ret = true;
354 else
355 ret = false;
356
357 free (path);
9783e04a 358
f366291b 359 return ret;
9783e04a
DM
360}
361
138b9b81
PS
362char *
363rs6000coff_core_file_failing_command (abfd)
364 bfd *abfd;
365{
366 char *com = core_hdr (abfd).CORE_COMM_FIELD;
367 if (*com)
368 return com;
369 else
370 return 0;
371}
372
373int
374rs6000coff_core_file_failing_signal (abfd)
375 bfd *abfd;
376{
377 return core_hdr (abfd).c_signo;
378}
379
9783e04a
DM
380
381boolean
382rs6000coff_get_section_contents (abfd, section, location, offset, count)
383 bfd *abfd;
384 sec_ptr section;
385 PTR location;
386 file_ptr offset;
387 int count;
388{
389 if (count == 0)
390 return true;
391
392 /* Reading a core file's sections will be slightly different. For the
393 rest of them we can use bfd_generic_get_section_contents () I suppose. */
394 /* Make sure this routine works for any bfd and any section. FIXMEmgo. */
395
396 if (abfd->format == bfd_core && strcmp (section->name, ".reg") == 0) {
397
398 struct mstsave mstatus;
399 int regoffset = (char*)&mstatus.gpr[0] - (char*)&mstatus;
400
401 /* Assert that the only way this code will be executed is reading the
402 whole section. */
403 if (offset || count != (sizeof(mstatus.gpr) + (4 * NUM_OF_SPEC_REGS)))
f366291b
PS
404 (*_bfd_error_handler)
405 ("ERROR! in rs6000coff_get_section_contents()\n");
9783e04a
DM
406
407 /* for `.reg' section, `filepos' is a pointer to the `mstsave' structure
408 in the core file. */
409
410 /* read GPR's into the location. */
411 if ( bfd_seek(abfd, section->filepos + regoffset, SEEK_SET) == -1
412 || bfd_read(location, sizeof (mstatus.gpr), 1, abfd) != sizeof (mstatus.gpr))
413 return (false); /* on error */
414
415 /* increment location to the beginning of special registers in the section,
416 reset register offset value to the beginning of first special register
417 in mstsave structure, and read special registers. */
418
419 location = (PTR) ((char*)location + sizeof (mstatus.gpr));
420 regoffset = (char*)&mstatus.iar - (char*)&mstatus;
421
422 if ( bfd_seek(abfd, section->filepos + regoffset, SEEK_SET) == -1
423 || bfd_read(location, 4 * NUM_OF_SPEC_REGS, 1, abfd) !=
424 4 * NUM_OF_SPEC_REGS)
425 return (false); /* on error */
426
427 /* increment location address, and read the special registers.. */
428 /* FIXMEmgo */
429 return (true);
430 }
431
432 /* else, use default bfd section content transfer. */
433 else
138b9b81 434 return _bfd_generic_get_section_contents
9783e04a
DM
435 (abfd, section, location, offset, count);
436}
437
138b9b81 438#endif /* AIX_CORE */
This page took 0.456816 seconds and 4 git commands to generate.