OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [tags/] [start/] [gdb-5.0/] [bfd/] [rs6000-core.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 104 markom
/* IBM RS/6000 "XCOFF" back-end for BFD.
2
   Copyright 1990, 91, 92, 93, 94, 95, 96, 97, 98, 2000
3
   Free Software Foundation, Inc.
4
   FIXME: Can someone provide a transliteration of this name into ASCII?
5
   Using the following chars caused a compiler warning on HIUX (so I replaced
6
   them with octal escapes), and isn't useful without an understanding of what
7
   character set it is.
8
   Written by Metin G. Ozisik, Mimi Ph\373\364ng-Th\345o V\365,
9
     and John Gilmore.
10
   Archive support from Damon A. Permezel.
11
   Contributed by IBM Corporation and Cygnus Support.
12
 
13
This file is part of BFD, the Binary File Descriptor library.
14
 
15
This program is free software; you can redistribute it and/or modify
16
it under the terms of the GNU General Public License as published by
17
the Free Software Foundation; either version 2 of the License, or
18
(at your option) any later version.
19
 
20
This program is distributed in the hope that it will be useful,
21
but WITHOUT ANY WARRANTY; without even the implied warranty of
22
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
23
GNU General Public License for more details.
24
 
25
You should have received a copy of the GNU General Public License
26
along with this program; if not, write to the Free Software
27
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
28
 
29
/* This port currently only handles reading object files, except when
30
   compiled on an RS/6000 host.  -- no archive support, no core files.
31
   In all cases, it does not support writing.
32
 
33
   FIXMEmgo comments are left from Metin Ozisik's original port.
34
 
35
   This is in a separate file from coff-rs6000.c, because it includes
36
   system include files that conflict with coff/rs6000.h.
37
  */
38
 
39
/* Internalcoff.h and coffcode.h modify themselves based on this flag.  */
40
#define RS6000COFF_C 1
41
 
42
/* The AIX 4.1 kernel is obviously compiled with -D_LONG_LONG, so
43
   we have to define _LONG_LONG for older versions of gcc to get the
44
   proper alignments in the user structure.  */
45
#if defined(_AIX41) && !defined(_LONG_LONG)
46
#define _LONG_LONG
47
#endif
48
 
49
#include "bfd.h"
50
#include "sysdep.h"
51
#include "libbfd.h"
52
 
53
#ifdef AIX_CORE
54
 
55
/* AOUTHDR is defined by the above.  We need another defn of it, from the
56
   system include files.  Punt the old one and get us a new name for the
57
   typedef in the system include files.  */
58
#ifdef AOUTHDR
59
#undef AOUTHDR
60
#endif
61
#define AOUTHDR second_AOUTHDR
62
 
63
#undef  SCNHDR
64
 
65
 
66
/* ------------------------------------------------------------------------ */
67
/*      Support for core file stuff..                                       */
68
/* ------------------------------------------------------------------------ */
69
 
70
#include <sys/user.h>
71
#include <sys/ldr.h>
72
#include <sys/core.h>
73
 
74
 
75
/* Number of special purpose registers supported by gdb.  This value
76
   should match `tm.h' in gdb directory.  Clean this mess up and use
77
   the macros in sys/reg.h.  FIXMEmgo. */
78
 
79
#define NUM_OF_SPEC_REGS  7
80
 
81
#define core_hdr(bfd)           (((Rs6kCorData*)(bfd->tdata.any))->hdr)
82
 
83
/* AIX 4.1 Changed the names and locations of a few items in the core file,
84
   this seems to be the quickest/easiest way to deal with it.
85
 
86
   Note however that encoding magic addresses (STACK_END_ADDR) is going
87
   to be _very_ fragile.  But I don't see any easy way to get that info
88
   right now.
89
 
90
   AIX 4.3 defines an entirely new structure (core_dumpx).  Yet the
91
   basic logic stays the same and we can still use our macro
92
   redefinition mechanism to effect the necessary changes.  */
93
 
94
#ifdef AIX_CORE_DUMPX_CORE
95
#define CORE_DATA_SIZE_FIELD c_dataorg
96
#define CORE_COMM_FIELD c_u.U_proc.pi_comm
97
#define SAVE_FIELD c_flt.hctx.r32
98
#define STACK_END_ADDR coredata.c_stackorg + coredata.c_size
99
#define LOADER_OFFSET_FIELD c_loader
100
#define LOADER_REGION_SIZE coredata.c_lsize
101
#define CORE_DUMP core_dumpx
102
#else
103
#ifdef CORE_VERSION_1
104
#define CORE_DATA_SIZE_FIELD c_u.U_dsize
105
#define CORE_COMM_FIELD c_u.U_comm
106
#define SAVE_FIELD c_mst
107
#define STACK_END_ADDR 0x2ff23000
108
#define LOADER_OFFSET_FIELD c_tab
109
#define LOADER_REGION_SIZE 0x7ffffff
110
#define CORE_DUMP core_dump
111
#else
112
#define CORE_DATA_SIZE_FIELD c_u.u_dsize
113
#define CORE_COMM_FIELD c_u.u_comm
114
#define SAVE_FIELD c_u.u_save
115
#define STACK_END_ADDR 0x2ff80000
116
#define LOADER_OFFSET_FIELD c_tab
117
#define LOADER_REGION_SIZE 0x7ffffff
118
#define CORE_DUMP core_dump
119
#endif
120
#endif
121
 
122
/* These are stored in the bfd's tdata */
123
typedef struct {
124
  struct CORE_DUMP hdr;         /* core file header */
125
} Rs6kCorData;
126
 
127
static asection *make_bfd_asection PARAMS ((bfd *, CONST char *, flagword,
128
                                            bfd_size_type, bfd_vma, file_ptr));
129
 
130
static asection *
131
make_bfd_asection (abfd, name, flags, _raw_size, vma, filepos)
132
     bfd *abfd;
133
     CONST char *name;
134
     flagword flags;
135
     bfd_size_type _raw_size;
136
     bfd_vma vma;
137
     file_ptr filepos;
138
{
139
  asection *asect;
140
 
141
  asect = bfd_make_section_anyway (abfd, name);
142
  if (!asect)
143
    return NULL;
144
 
145
  asect->flags = flags;
146
  asect->_raw_size = _raw_size;
147
  asect->vma = vma;
148
  asect->filepos = filepos;
149
  asect->alignment_power = 8;
150
 
151
  return asect;
152
}
153
 
154
/* Decide if a given bfd represents a `core' file or not. There really is no
155
   magic number or anything like, in rs6000coff. */
156
 
157
const bfd_target *
158
rs6000coff_core_p (abfd)
159
     bfd *abfd;
160
{
161
  struct CORE_DUMP coredata;
162
  struct stat statbuf;
163
  bfd_size_type nread;
164
  char *tmpptr;
165
 
166
  if (bfd_seek (abfd, 0, SEEK_SET) != 0)
167
    return NULL;
168
 
169
  nread = bfd_read (&coredata, 1, sizeof (struct CORE_DUMP), abfd);
170
  if (nread != sizeof (struct CORE_DUMP))
171
    {
172
      if (bfd_get_error () != bfd_error_system_call)
173
        bfd_set_error (bfd_error_wrong_format);
174
      return NULL;
175
    }
176
 
177
  if (bfd_stat (abfd, &statbuf) < 0)
178
    {
179
      bfd_set_error (bfd_error_system_call);
180
      return NULL;
181
    }
182
 
183
  /* If the core file ulimit is too small, the system will first
184
     omit the data segment, then omit the stack, then decline to
185
     dump core altogether (as far as I know UBLOCK_VALID and LE_VALID
186
     are always set) (this is based on experimentation on AIX 3.2).
187
     Now, the thing is that GDB users will be surprised
188
     if segments just silently don't appear (well, maybe they would
189
     think to check "info files", I don't know).
190
 
191
     For the data segment, we have no choice but to keep going if it's
192
     not there, since the default behavior is not to dump it (regardless
193
     of the ulimit, it's based on SA_FULLDUMP).  But for the stack segment,
194
     if it's not there, we refuse to have anything to do with this core
195
     file.  The usefulness of a core dump without a stack segment is pretty
196
     limited anyway.  */
197
 
198
  if (!(coredata.c_flag & UBLOCK_VALID)
199
      || !(coredata.c_flag & LE_VALID))
200
    {
201
      bfd_set_error (bfd_error_wrong_format);
202
      return NULL;
203
    }
204
 
205
  if (!(coredata.c_flag & USTACK_VALID))
206
    {
207
      bfd_set_error (bfd_error_file_truncated);
208
      return NULL;
209
    }
210
 
211
  /* Don't check the core file size for a full core, AIX 4.1 includes
212
     additional shared library sections in a full core.  */
213
  if (!(coredata.c_flag & (FULL_CORE | CORE_TRUNC))
214
      && ((bfd_vma)coredata.c_stack + coredata.c_size) != statbuf.st_size)
215
    {
216
      /* If the size is wrong, it means we're misinterpreting something.  */
217
      bfd_set_error (bfd_error_wrong_format);
218
      return NULL;
219
    }
220
 
221
#ifdef AIX_CORE_DUMPX_CORE
222
  /* For the core_dumpx format, make sure c_entries == 0  If it does
223
     not, the core file uses the old format */
224
  if (coredata.c_entries != 0)
225
    {
226
      bfd_set_error (bfd_error_wrong_format);
227
      return NULL;
228
    }
229
#else
230
  /* Sanity check on the c_tab field.  */
231
  if ((u_long) coredata.c_tab < sizeof coredata ||
232
      (u_long) coredata.c_tab >= statbuf.st_size ||
233
      (long) coredata.c_tab >= (long)coredata.c_stack)
234
    {
235
      bfd_set_error (bfd_error_wrong_format);
236
      return NULL;
237
    }
238
#endif
239
 
240
  /* Issue warning if the core file was truncated during writing.  */
241
  if (coredata.c_flag & CORE_TRUNC)
242
    (*_bfd_error_handler) (_("%s: warning core file truncated"),
243
                           bfd_get_filename (abfd));
244
 
245
  /* Allocate core file header.  */
246
  tmpptr = (char*) bfd_zalloc (abfd, sizeof (Rs6kCorData));
247
  if (!tmpptr)
248
    return NULL;
249
 
250
  set_tdata (abfd, tmpptr);
251
 
252
  /* Copy core file header.  */
253
  core_hdr (abfd) = coredata;
254
 
255
  /* .stack section. */
256
  if (!make_bfd_asection (abfd, ".stack",
257
                          SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS,
258
                          (bfd_size_type) coredata.c_size,
259
                          (bfd_vma) (STACK_END_ADDR - coredata.c_size),
260
                          (file_ptr) coredata.c_stack))
261
    return NULL;
262
 
263
  /* .reg section for GPRs and special registers. */
264
  if (!make_bfd_asection (abfd, ".reg",
265
                          SEC_HAS_CONTENTS,
266
                          (bfd_size_type) ((32 + NUM_OF_SPEC_REGS) * 4),
267
                          (bfd_vma) 0,
268
                          (file_ptr) ((char *) &coredata.SAVE_FIELD
269
                                      - (char *) &coredata)))
270
    return NULL;
271
 
272
  /* .reg2 section for FPRs (floating point registers). */
273
  if (!make_bfd_asection (abfd, ".reg2",
274
                          SEC_HAS_CONTENTS,
275
                          (bfd_size_type) 8 * 32,       /* 32 FPRs. */
276
                          (bfd_vma) 0,
277
                          (file_ptr) ((char *) &coredata.SAVE_FIELD.fpr[0]
278
                                      - (char *) &coredata)))
279
    return NULL;
280
 
281
  /* .ldinfo section.
282
     To actually find out how long this section is in this particular
283
     core dump would require going down the whole list of struct ld_info's.
284
     See if we can just fake it.  */
285
  if (!make_bfd_asection (abfd, ".ldinfo",
286
                          SEC_HAS_CONTENTS,
287
                          (bfd_size_type) LOADER_REGION_SIZE,
288
                          (bfd_vma) 0,
289
                          (file_ptr) coredata.LOADER_OFFSET_FIELD))
290
    return NULL;
291
 
292
#ifndef CORE_VERSION_1
293
  /* .data section if present.
294
     AIX 3 dumps the complete data section and sets FULL_CORE if the
295
     ulimit is large enough, otherwise the data section is omitted.
296
     AIX 4 sets FULL_CORE even if the core file is truncated, we have
297
     to examine coredata.c_datasize below to find out the actual size of
298
     the .data section.  */
299
  if (coredata.c_flag & FULL_CORE)
300
    {
301
      if (!make_bfd_asection (abfd, ".data",
302
                              SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS,
303
                              (bfd_size_type) coredata.CORE_DATA_SIZE_FIELD,
304
                              (bfd_vma)
305
                                CDATA_ADDR (coredata.CORE_DATA_SIZE_FIELD),
306
                              (file_ptr) coredata.c_stack + coredata.c_size))
307
        return NULL;
308
    }
309
#endif
310
 
311
#ifdef CORE_VERSION_1
312
  /* AIX 4 adds data sections from loaded objects to the core file,
313
     which can be found by examining ldinfo, and anonymously mmapped
314
     regions.  */
315
  {
316
    struct ld_info ldinfo;
317
    bfd_size_type ldinfo_size;
318
    file_ptr ldinfo_offset = (file_ptr) coredata.LOADER_OFFSET_FIELD;
319
 
320
    /* .data section from executable.  */
321
    if (coredata.c_datasize)
322
      {
323
        if (!make_bfd_asection (abfd, ".data",
324
                                SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS,
325
                                (bfd_size_type) coredata.c_datasize,
326
                                (bfd_vma)
327
                                  CDATA_ADDR (coredata.CORE_DATA_SIZE_FIELD),
328
                                (file_ptr) coredata.c_data))
329
          return NULL;
330
      }
331
 
332
    /* .data sections from loaded objects.  */
333
    ldinfo_size = (char *) &ldinfo.ldinfo_filename[0]
334
                  - (char *) &ldinfo.ldinfo_next;
335
    while (1)
336
      {
337
        if (bfd_seek (abfd, ldinfo_offset, SEEK_SET) != 0)
338
          return NULL;
339
        if (bfd_read (&ldinfo, ldinfo_size, 1, abfd) != ldinfo_size)
340
          return NULL;
341
        if (ldinfo.ldinfo_core)
342
          {
343
            if (!make_bfd_asection (abfd, ".data",
344
                                    SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS,
345
                                    (bfd_size_type) ldinfo.ldinfo_datasize,
346
                                    (bfd_vma) ldinfo.ldinfo_dataorg,
347
                                    (file_ptr) ldinfo.ldinfo_core))
348
              return NULL;
349
          }
350
        if (ldinfo.ldinfo_next == 0)
351
          break;
352
        ldinfo_offset += ldinfo.ldinfo_next;
353
      }
354
 
355
    /* .vmdata sections from anonymously mmapped regions.  */
356
    if (coredata.c_vmregions)
357
      {
358
        int i;
359
 
360
        if (bfd_seek (abfd, (file_ptr) coredata.c_vmm, SEEK_SET) != 0)
361
          return NULL;
362
 
363
        for (i = 0; i < coredata.c_vmregions; i++)
364
          {
365
            struct vm_info vminfo;
366
 
367
            if (bfd_read (&vminfo, sizeof (vminfo), 1, abfd) != sizeof (vminfo))
368
              return NULL;
369
            if (vminfo.vminfo_offset)
370
              {
371
                if (!make_bfd_asection (abfd, ".vmdata",
372
                                        SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS,
373
                                        (bfd_size_type) vminfo.vminfo_size,
374
                                        (bfd_vma) vminfo.vminfo_addr,
375
                                        (file_ptr) vminfo.vminfo_offset))
376
                  return NULL;
377
              }
378
          }
379
      }
380
  }
381
#endif
382
 
383
  return abfd->xvec;                            /* this is garbage for now. */
384
}
385
 
386
 
387
 
388
/* return `true' if given core is from the given executable.. */
389
boolean
390
rs6000coff_core_file_matches_executable_p (core_bfd, exec_bfd)
391
     bfd *core_bfd;
392
     bfd *exec_bfd;
393
{
394
  struct CORE_DUMP coredata;
395
  struct ld_info ldinfo;
396
  bfd_size_type size;
397
  char *path, *s;
398
  size_t alloc;
399
  const char *str1, *str2;
400
  boolean ret;
401
 
402
  if (bfd_seek (core_bfd, 0, SEEK_SET) != 0
403
      || bfd_read (&coredata, sizeof coredata, 1, core_bfd) != sizeof coredata)
404
    return false;
405
 
406
  if (bfd_seek (core_bfd, (long) coredata.LOADER_OFFSET_FIELD, SEEK_SET) != 0)
407
    return false;
408
 
409
  size = (char *) &ldinfo.ldinfo_filename[0] - (char *) &ldinfo.ldinfo_next;
410
  if (bfd_read (&ldinfo, size, 1, core_bfd) != size)
411
    return false;
412
 
413
  alloc = 100;
414
  path = bfd_malloc (alloc);
415
  if (path == NULL)
416
    return false;
417
  s = path;
418
 
419
  while (1)
420
    {
421
      if (bfd_read (s, 1, 1, core_bfd) != 1)
422
        {
423
          free (path);
424
          return false;
425
        }
426
      if (*s == '\0')
427
        break;
428
      ++s;
429
      if (s == path + alloc)
430
        {
431
          char *n;
432
 
433
          alloc *= 2;
434
          n = bfd_realloc (path, alloc);
435
          if (n == NULL)
436
            {
437
              free (path);
438
              return false;
439
            }
440
          s = n + (path - s);
441
          path = n;
442
        }
443
    }
444
 
445
  str1 = strrchr (path, '/');
446
  str2 = strrchr (exec_bfd->filename, '/');
447
 
448
  /* step over character '/' */
449
  str1 = str1 != NULL ? str1 + 1 : path;
450
  str2 = str2 != NULL ? str2 + 1 : exec_bfd->filename;
451
 
452
  if (strcmp (str1, str2) == 0)
453
    ret = true;
454
  else
455
    ret = false;
456
 
457
  free (path);
458
 
459
  return ret;
460
}
461
 
462
char *
463
rs6000coff_core_file_failing_command (abfd)
464
     bfd *abfd;
465
{
466
  char *com = core_hdr (abfd).CORE_COMM_FIELD;
467
  if (*com)
468
    return com;
469
  else
470
    return 0;
471
}
472
 
473
int
474
rs6000coff_core_file_failing_signal (abfd)
475
     bfd *abfd;
476
{
477
  return core_hdr (abfd).c_signo;
478
}
479
 
480
 
481
boolean
482
rs6000coff_get_section_contents (abfd, section, location, offset, count)
483
     bfd *abfd;
484
     sec_ptr section;
485
     PTR location;
486
     file_ptr offset;
487
     bfd_size_type count;
488
{
489
    if (count == 0)
490
        return true;
491
 
492
    /* Reading a core file's sections will be slightly different. For the
493
       rest of them we can use bfd_generic_get_section_contents () I suppose. */
494
    /* Make sure this routine works for any bfd and any section. FIXMEmgo. */
495
 
496
    if (abfd->format == bfd_core && strcmp (section->name, ".reg") == 0) {
497
 
498
      struct mstsave mstatus;
499
      int    regoffset = (char*)&mstatus.gpr[0] - (char*)&mstatus;
500
 
501
      /* Assert that the only way this code will be executed is reading the
502
         whole section. */
503
      if (offset || count != (sizeof(mstatus.gpr) + (4 * NUM_OF_SPEC_REGS)))
504
        (*_bfd_error_handler)
505
          (_("ERROR! in rs6000coff_get_section_contents()\n"));
506
 
507
      /* for `.reg' section, `filepos' is a pointer to the `mstsave' structure
508
         in the core file. */
509
 
510
      /* read GPR's into the location. */
511
      if ( bfd_seek(abfd, section->filepos + regoffset, SEEK_SET) == -1
512
        || bfd_read(location, sizeof (mstatus.gpr), 1, abfd) != sizeof (mstatus.gpr))
513
        return (false); /* on error */
514
 
515
      /* increment location to the beginning of special registers in the section,
516
         reset register offset value to the beginning of first special register
517
         in mstsave structure, and read special registers. */
518
 
519
      location = (PTR) ((char*)location + sizeof (mstatus.gpr));
520
      regoffset = (char*)&mstatus.iar - (char*)&mstatus;
521
 
522
      if ( bfd_seek(abfd, section->filepos + regoffset, SEEK_SET) == -1
523
        || bfd_read(location, 4 * NUM_OF_SPEC_REGS, 1, abfd) !=
524
                                                        4 * NUM_OF_SPEC_REGS)
525
        return (false); /* on error */
526
 
527
      /* increment location address, and read the special registers.. */
528
      /* FIXMEmgo */
529
      return (true);
530
    }
531
 
532
    /* else, use default bfd section content transfer. */
533
    else
534
      return _bfd_generic_get_section_contents
535
                        (abfd, section, location, offset, count);
536
}
537
 
538
#endif /* AIX_CORE */

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.