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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-old/] [gdb-6.8/] [bfd/] [vms-hdr.c] - Blame information for rev 866

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 24 jeremybenn
/* vms-hdr.c -- BFD back-end for VMS/VAX (openVMS/VAX) and
2
   EVAX (openVMS/Alpha) files.
3
   Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2005, 2006,
4 225 jeremybenn
   2007, 2008, 2009 Free Software Foundation, Inc.
5 24 jeremybenn
 
6
   HDR record handling functions
7
   EMH record handling functions
8 225 jeremybenn
 
9 24 jeremybenn
   EOM record handling functions
10
   EEOM record handling functions
11
 
12 225 jeremybenn
   IHD record handling functions
13
   EIHD record handling functions
14
 
15
   ISD record handling functions
16
   EISD record handling functions
17
 
18
   IHS record handling functions
19
   EIHS record handling functions
20
 
21
   DBG record handling functions
22
   EDBG record handling functions
23
 
24
   TBT record handling functions
25
   ETBT record handling functions
26
 
27
   DST/DMT section handling functions
28
 
29 24 jeremybenn
   Written by Klaus K"ampf (kkaempf@rmi.de)
30
 
31
   This program is free software; you can redistribute it and/or modify
32
   it under the terms of the GNU General Public License as published by
33
   the Free Software Foundation; either version 3 of the License, or
34
   (at your option) any later version.
35
 
36
   This program is distributed in the hope that it will be useful,
37
   but WITHOUT ANY WARRANTY; without even the implied warranty of
38
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
39
   GNU General Public License for more details.
40
 
41
   You should have received a copy of the GNU General Public License
42
   along with this program; if not, write to the Free Software
43
   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
44
   MA 02110-1301, USA.  */
45
 
46
#include "sysdep.h"
47
#include "bfd.h"
48
#include "bfdver.h"
49
#include "bfdlink.h"
50
#include "safe-ctype.h"
51
#include "libbfd.h"
52
 
53
#include "vms.h"
54
 
55 225 jeremybenn
static struct module *new_module (bfd *);
56
static void parse_module
57
  (bfd *, struct module *, unsigned char *, unsigned int);
58
static struct module *build_module_list (bfd *);
59
static bfd_boolean module_find_nearest_line
60
  (bfd *, struct module *, bfd_vma, const char **, const char **,
61
   unsigned int *);
62
static int vms_slurp_debug (bfd *);
63 24 jeremybenn
 
64 225 jeremybenn
#define SET_MODULE_PARSED(m) \
65
  do { if ((m)->name == NULL) (m)->name = ""; } while (0)
66
#define IS_MODULE_PARSED(m) ((m)->name != NULL)
67
 
68
 
69 24 jeremybenn
/* Read & process emh record
70
   return 0 on success, -1 on error.  */
71
 
72
int
73
_bfd_vms_slurp_hdr (bfd *abfd, int objtype)
74
{
75
  unsigned char *ptr;
76
  unsigned char *vms_rec;
77
  int subtype;
78
 
79
  vms_rec = PRIV(vms_rec);
80
 
81
#if VMS_DEBUG
82
  vms_debug(2, "HDR/EMH\n");
83
#endif
84
 
85
  switch (objtype)
86
    {
87
    case OBJ_S_C_HDR:
88
      subtype = vms_rec[1];
89
      break;
90
    case EOBJ_S_C_EMH:
91
      subtype = bfd_getl16 (vms_rec + 4) + EVAX_OFFSET;
92
      break;
93
    default:
94
      subtype = -1;
95
    }
96
 
97
#if VMS_DEBUG
98
  vms_debug(3, "subtype %d\n", subtype);
99
#endif
100
 
101
  switch (subtype)
102
    {
103
    case MHD_S_C_MHD:
104
      /* Module header.  */
105
      PRIV (hdr_data).hdr_b_strlvl = vms_rec[2];
106
      PRIV (hdr_data).hdr_l_recsiz = bfd_getl16 (vms_rec + 3);
107
      PRIV (hdr_data).hdr_t_name = _bfd_vms_save_counted_string (vms_rec + 5);
108
      ptr = vms_rec + 5 + vms_rec[5] + 1;
109
      PRIV (hdr_data).hdr_t_version = _bfd_vms_save_counted_string (ptr);
110
      ptr += *ptr + 1;
111
      PRIV (hdr_data).hdr_t_date = _bfd_vms_save_sized_string (ptr, 17);
112
      break;
113
 
114
    case MHD_S_C_LNM:
115 225 jeremybenn
      PRIV (hdr_data).hdr_c_lnm = _bfd_vms_save_sized_string (vms_rec, PRIV (rec_size - 2));
116 24 jeremybenn
      break;
117
 
118
    case MHD_S_C_SRC:
119 225 jeremybenn
      PRIV (hdr_data).hdr_c_src = _bfd_vms_save_sized_string (vms_rec, PRIV (rec_size - 2));
120 24 jeremybenn
      break;
121
 
122
    case MHD_S_C_TTL:
123 225 jeremybenn
      PRIV (hdr_data).hdr_c_ttl = _bfd_vms_save_sized_string (vms_rec, PRIV (rec_size - 2));
124 24 jeremybenn
      break;
125
 
126
    case EMH_S_C_MHD + EVAX_OFFSET:
127
      /* Module header.  */
128
      PRIV (hdr_data).hdr_b_strlvl = vms_rec[6];
129
      PRIV (hdr_data).hdr_l_arch1  = bfd_getl32 (vms_rec + 8);
130
      PRIV (hdr_data).hdr_l_arch2  = bfd_getl32 (vms_rec + 12);
131
      PRIV (hdr_data).hdr_l_recsiz = bfd_getl32 (vms_rec + 16);
132
      PRIV (hdr_data).hdr_t_name   = _bfd_vms_save_counted_string (vms_rec + 20);
133
      ptr = vms_rec + 20 + vms_rec[20] + 1;
134
      PRIV (hdr_data).hdr_t_version =_bfd_vms_save_counted_string (ptr);
135
      ptr += *ptr + 1;
136
      PRIV (hdr_data).hdr_t_date = _bfd_vms_save_sized_string (ptr, 17);
137
      break;
138
 
139
    case EMH_S_C_LNM + EVAX_OFFSET:
140 225 jeremybenn
      PRIV (hdr_data).hdr_c_lnm = _bfd_vms_save_sized_string (vms_rec, PRIV (rec_size - 6));
141 24 jeremybenn
      break;
142
 
143
    case EMH_S_C_SRC + EVAX_OFFSET:
144 225 jeremybenn
      PRIV (hdr_data).hdr_c_src = _bfd_vms_save_sized_string (vms_rec, PRIV (rec_size - 6));
145 24 jeremybenn
      break;
146
 
147
    case EMH_S_C_TTL + EVAX_OFFSET:
148 225 jeremybenn
      PRIV (hdr_data).hdr_c_ttl = _bfd_vms_save_sized_string (vms_rec, PRIV (rec_size - 6));
149 24 jeremybenn
      break;
150
 
151
    case MHD_S_C_CPR:
152
    case MHD_S_C_MTC:
153
    case MHD_S_C_GTX:
154
    case EMH_S_C_CPR + EVAX_OFFSET:
155
    case EMH_S_C_MTC + EVAX_OFFSET:
156
    case EMH_S_C_GTX + EVAX_OFFSET:
157
      break;
158
 
159
    default:
160
      bfd_set_error (bfd_error_wrong_format);
161
      return -1;
162
    }
163
 
164
  return 0;
165
}
166
 
167
/* Output routines.  */
168
 
169
/* Manufacture a VMS like time on a unix based system.
170
   stolen from obj-vms.c.  */
171
 
172
static unsigned char *
173
get_vms_time_string (void)
174
{
175
  static unsigned char tbuf[18];
176
#ifndef VMS
177
#include <time.h>
178
 
179
  char *pnt;
180
  time_t timeb;
181
 
182
  time (& timeb);
183
  pnt = ctime (&timeb);
184
  pnt[3] = 0;
185
  pnt[7] = 0;
186
  pnt[10] = 0;
187
  pnt[16] = 0;
188
  pnt[24] = 0;
189
  sprintf ((char *) tbuf, "%2s-%3s-%s %s",
190
           pnt + 8, pnt + 4, pnt + 20, pnt + 11);
191
#else
192
#include <starlet.h>
193
  struct
194
  {
195
    int Size;
196
    unsigned char *Ptr;
197
  } Descriptor;
198
  Descriptor.Size = 17;
199
  Descriptor.Ptr = tbuf;
200
  SYS$ASCTIM (0, &Descriptor, 0, 0);
201
#endif /* not VMS */
202
 
203
#if VMS_DEBUG
204
  vms_debug (6, "vmstimestring:'%s'\n", tbuf);
205
#endif
206
 
207
  return tbuf;
208
}
209
 
210
/* Write object header for bfd abfd.  */
211
 
212
int
213
_bfd_vms_write_hdr (bfd *abfd, int objtype)
214
{
215
  asymbol *symbol;
216
  unsigned int symnum;
217
  int had_case = 0;
218
  int had_file = 0;
219 225 jeremybenn
  char version [256];
220 24 jeremybenn
 
221
#if VMS_DEBUG
222
  vms_debug (2, "vms_write_hdr (%p)\n", abfd);
223
#endif
224
 
225
  _bfd_vms_output_alignment (abfd, 2);
226
 
227
  /* MHD.  */
228
  if (objtype != OBJ_S_C_HDR)
229
    {
230
      _bfd_vms_output_begin (abfd, EOBJ_S_C_EMH, EMH_S_C_MHD);
231
      _bfd_vms_output_short (abfd, EOBJ_S_C_STRLVL);
232
      _bfd_vms_output_long (abfd, 0);
233
      _bfd_vms_output_long (abfd, 0);
234
      _bfd_vms_output_long (abfd, MAX_OUTREC_SIZE);
235
    }
236
 
237
  if (bfd_get_filename (abfd) != 0)
238
    {
239
      /* Strip path and suffix information.  */
240
      char *fname, *fout, *fptr;
241
 
242
      fptr = bfd_get_filename (abfd);
243 225 jeremybenn
      fname = strdup (fptr);
244
 
245
      /* Strip VMS path.  */
246 24 jeremybenn
      fout = strrchr (fname, ']');
247 225 jeremybenn
      if (fout == NULL)
248 24 jeremybenn
        fout = strchr (fname, ':');
249 225 jeremybenn
      if (fout != NULL)
250 24 jeremybenn
        fout++;
251
      else
252
        fout = fname;
253
 
254 225 jeremybenn
      /* Strip UNIX path.  */
255
      fptr = strrchr (fout, '/');
256
      if (fptr != NULL)
257
        fout = fptr + 1;
258
 
259 24 jeremybenn
      /* Strip .obj suffix.  */
260 225 jeremybenn
      fptr = strrchr (fout, '.');
261
      if (fptr != 0 && strcasecmp (fptr, ".OBJ") == 0)
262 24 jeremybenn
        *fptr = 0;
263
 
264 225 jeremybenn
      /* Convert to upper case and truncate at 31 characters.
265
         (VMS object file format restricts module name length to 31).  */
266 24 jeremybenn
      fptr = fout;
267
      while (*fptr != 0)
268
        {
269
          *fptr = TOUPPER (*fptr);
270
          fptr++;
271 225 jeremybenn
          if (*fptr == ';' || (fptr - fout) >= 31)
272 24 jeremybenn
            *fptr = 0;
273
        }
274
      _bfd_vms_output_counted (abfd, fout);
275 225 jeremybenn
      free (fname);
276 24 jeremybenn
    }
277
  else
278
    _bfd_vms_output_counted (abfd, "NONAME");
279
 
280
  _bfd_vms_output_counted (abfd, BFD_VERSION_STRING);
281 225 jeremybenn
  _bfd_vms_output_dump (abfd, get_vms_time_string (), EMH_DATE_LENGTH);
282
  _bfd_vms_output_fill (abfd, 0, EMH_DATE_LENGTH);
283 24 jeremybenn
  _bfd_vms_output_flush (abfd);
284
 
285
  /* LMN.  */
286
  _bfd_vms_output_begin (abfd, EOBJ_S_C_EMH, EMH_S_C_LNM);
287 225 jeremybenn
  snprintf (version, sizeof (version), "GAS BFD v%s", BFD_VERSION_STRING);
288
  _bfd_vms_output_dump (abfd, (unsigned char *)version, strlen (version));
289 24 jeremybenn
  _bfd_vms_output_flush (abfd);
290
 
291
  /* SRC.  */
292
  _bfd_vms_output_begin (abfd, EOBJ_S_C_EMH, EMH_S_C_SRC);
293
 
294
  for (symnum = 0; symnum < abfd->symcount; symnum++)
295
    {
296
      symbol = abfd->outsymbols[symnum];
297
 
298
      if (symbol->flags & BSF_FILE)
299
        {
300
          if (CONST_STRNEQ ((char *)symbol->name, "<CASE:"))
301
            {
302
              PRIV (flag_hash_long_names) = symbol->name[6] - '0';
303
              PRIV (flag_show_after_trunc) = symbol->name[7] - '0';
304
 
305
              if (had_file)
306
                break;
307
              had_case = 1;
308
              continue;
309
            }
310
 
311
          _bfd_vms_output_dump (abfd, (unsigned char *) symbol->name,
312
                                (int) strlen (symbol->name));
313
          if (had_case)
314
            break;
315
          had_file = 1;
316
        }
317
    }
318
 
319
  if (symnum == abfd->symcount)
320
    _bfd_vms_output_dump (abfd, (unsigned char *) STRING_COMMA_LEN ("noname"));
321
 
322
  _bfd_vms_output_flush (abfd);
323
 
324
  /* TTL.  */
325
  _bfd_vms_output_begin (abfd, EOBJ_S_C_EMH, EMH_S_C_TTL);
326
  _bfd_vms_output_dump (abfd, (unsigned char *) STRING_COMMA_LEN ("TTL"));
327
  _bfd_vms_output_flush (abfd);
328
 
329
  /* CPR.  */
330
  _bfd_vms_output_begin (abfd, EOBJ_S_C_EMH, EMH_S_C_CPR);
331
  _bfd_vms_output_dump (abfd,
332
                         (unsigned char *)"GNU BFD ported by Klaus Kämpf 1994-1996",
333
                         39);
334
  _bfd_vms_output_flush (abfd);
335
 
336
  return 0;
337
}
338
 
339
/* Process EOM/EEOM record
340
   return 0 on success, -1 on error.  */
341
 
342
int
343
_bfd_vms_slurp_eom (bfd *abfd, int objtype)
344
{
345
  unsigned char *vms_rec;
346
 
347
#if VMS_DEBUG
348
  vms_debug(2, "EOM/EEOM\n");
349
#endif
350
 
351
  vms_rec = PRIV (vms_rec);
352
 
353
  if ((objtype == OBJ_S_C_EOM)
354
     || (objtype == OBJ_S_C_EOMW))
355
    {
356
    }
357
  else
358
    {
359 225 jeremybenn
      PRIV (eom_data).eom_l_total_lps
360
        = bfd_getl32 (vms_rec + EEOM_S_L_TOTAL_LPS);
361
      PRIV (eom_data).eom_w_comcod = bfd_getl16 (vms_rec + EEOM_S_W_COMCOD);
362
      if (PRIV (eom_data).eom_w_comcod > 1)
363 24 jeremybenn
        {
364
          (*_bfd_error_handler) (_("Object module NOT error-free !\n"));
365
          bfd_set_error (bfd_error_bad_value);
366
          return -1;
367
        }
368
      PRIV (eom_data).eom_has_transfer = FALSE;
369
      if (PRIV (rec_size) > 10)
370
        {
371
           PRIV (eom_data).eom_has_transfer = TRUE;
372 225 jeremybenn
           PRIV (eom_data).eom_b_tfrflg = vms_rec[EEOM_S_B_TFRFLG];
373
           PRIV (eom_data).eom_l_psindx
374
             = bfd_getl32 (vms_rec + EEOM_S_L_PSINDX);
375
           PRIV (eom_data).eom_l_tfradr
376
             = bfd_getl32 (vms_rec + EEOM_S_L_TFRADR);
377 24 jeremybenn
 
378
           abfd->start_address = PRIV (eom_data).eom_l_tfradr;
379
        }
380
    }
381
  return 0;
382
}
383
 
384
/* Write eom record for bfd abfd.  */
385
 
386
int
387
_bfd_vms_write_eom (bfd *abfd, int objtype)
388
{
389
#if VMS_DEBUG
390
  vms_debug (2, "vms_write_eom (%p, %d)\n", abfd, objtype);
391
#endif
392
 
393
  _bfd_vms_output_begin (abfd, objtype, -1);
394
  _bfd_vms_output_long (abfd, (unsigned long) (PRIV (vms_linkage_index) >> 1));
395
  _bfd_vms_output_byte (abfd, 0);        /* Completion code.  */
396
  _bfd_vms_output_byte (abfd, 0);        /* Fill byte.  */
397
 
398
  if (bfd_get_start_address (abfd) != (bfd_vma)-1)
399
    {
400
      asection *section;
401
 
402
      section = bfd_get_section_by_name (abfd, ".link");
403
      if (section == 0)
404
        {
405
          bfd_set_error (bfd_error_nonrepresentable_section);
406
          return -1;
407
        }
408
      _bfd_vms_output_short (abfd, 0);
409
      _bfd_vms_output_long (abfd, (unsigned long) (section->index));
410
      _bfd_vms_output_long (abfd,
411
                             (unsigned long) bfd_get_start_address (abfd));
412
      _bfd_vms_output_long (abfd, 0);
413
    }
414
 
415
  _bfd_vms_output_end (abfd);
416
  return 0;
417
}
418 225 jeremybenn
 
419
/* Read & process IHD/EIHD record.
420
   Return 0 on success, -1 on error  */
421
int
422
_bfd_vms_slurp_ihd (bfd *abfd, unsigned int *isd_offset,
423
                    unsigned int *ihs_offset)
424
{
425
  unsigned int imgtype, size;
426
  bfd_vma symvva;
427
 
428
#if VMS_DEBUG
429
  vms_debug (8, "_bfd_vms_slurp_ihd\n");
430
#endif
431
 
432
  size = bfd_getl32 (PRIV (vms_rec) + EIHD_S_L_SIZE);
433
  imgtype = bfd_getl32 (PRIV (vms_rec) + EIHD_S_L_IMGTYPE);
434
 
435
  if (imgtype == EIHD_S_K_EXE)
436
    abfd->flags |= EXEC_P;
437
 
438
  symvva = bfd_getl64 (PRIV (vms_rec) + EIHD_S_Q_SYMVVA);
439
  if (symvva != 0)
440
    {
441
      PRIV (symvva) = symvva;
442
      abfd->flags |= DYNAMIC;
443
    }
444
 
445
  *isd_offset = bfd_getl32 (PRIV (vms_rec) + EIHD_S_L_ISDOFF);
446
  *ihs_offset = bfd_getl32 (PRIV (vms_rec) + EIHD_S_L_SYMDBGOFF);
447
 
448
#if VMS_DEBUG
449
  vms_debug (4, "EIHD record size %d imgtype %d symvva 0x%llx isd %d ihs %d\n",
450
             size, imgtype, symvva, *isd_offset, *ihs_offset);
451
#endif
452
 
453
  return 0;
454
}
455
 
456
/* Read & process ISD/EISD record
457
   return 0 on success, -1 on error  */
458
 
459
int
460
_bfd_vms_slurp_isd (bfd *abfd, unsigned int offset)
461
{
462
  int section_count = 0;
463
  unsigned char *p;
464
  unsigned int rec_size;
465
 
466
#if VMS_DEBUG
467
  vms_debug (8, "_bfd_vms_slurp_isd\n");
468
#endif
469
 
470
  for (p = PRIV (vms_rec) + offset;
471
       (rec_size = bfd_getl32 (p + EISD_S_L_EISDSIZE)) != 0;
472
       p += rec_size)
473
    {
474
      unsigned long long vaddr = bfd_getl64 (p + EISD_S_Q_VIR_ADDR);
475
      unsigned int size = bfd_getl32 (p + EISD_S_L_SECSIZE);
476
      unsigned int flags = bfd_getl32 (p + EISD_S_L_FLAGS);
477
      unsigned int vbn = bfd_getl32 (p + EISD_S_L_VBN);
478
      char *name = NULL;
479
      asection *section;
480
      flagword bfd_flags;
481
 
482
#if VMS_DEBUG
483
      vms_debug (4, "EISD record at 0x%x size 0x%x addr 0x%x bfd_flags 0x%x block %d\n",
484
                 p - PRIV (vms_rec), size, vaddr, flags, vbn);
485
#endif
486
 
487
      /* VMS combines psects from .obj files into isects in the .exe.  This
488
         process doesn't preserve enough information to reliably determine
489
         what's in each section without examining the data.  This is
490
         especially true of DWARF debug sections.  */
491
      bfd_flags = SEC_ALLOC;
492
 
493
      if (flags & EISD_S_M_EXE)
494
        bfd_flags |= SEC_CODE | SEC_HAS_CONTENTS | SEC_LOAD;
495
 
496
      if (flags & EISD_S_M_NONSHRADR)
497
        bfd_flags |= SEC_DATA | SEC_HAS_CONTENTS | SEC_LOAD;
498
 
499
      if (!(flags & EISD_S_M_WRT))
500
        bfd_flags |= SEC_READONLY;
501
 
502
      if (flags & EISD_S_M_DZRO)
503
        bfd_flags |= SEC_DATA;
504
 
505
      if (flags & EISD_S_M_FIXUPVEC)
506
        bfd_flags |= SEC_DATA | SEC_HAS_CONTENTS | SEC_LOAD;
507
 
508
      if (flags & EISD_S_M_CRF)
509
        bfd_flags |= SEC_HAS_CONTENTS | SEC_LOAD;
510
 
511
      if (flags & EISD_S_M_GBL)
512
        {
513
          name = _bfd_vms_save_counted_string (p + EISD_S_T_GBLNAM);
514
          bfd_flags |= SEC_COFF_SHARED_LIBRARY;
515
          bfd_flags &= ~(SEC_ALLOC | SEC_LOAD);
516
        }
517
      else
518
        {
519
          name = (char*) bfd_alloc (abfd, 32);
520
          sprintf (name, "$LOCAL_%03d$", section_count++);
521
        }
522
 
523
      section = bfd_make_section (abfd, name);
524
 
525
      if (!section)
526
        return -1;
527
 
528
      section->filepos = vbn ? VMS_BLOCK_SIZE * (vbn - 1) : (unsigned int)-1;
529
      section->size = size;
530
      section->vma = vaddr;
531
 
532
      if (!bfd_set_section_flags (abfd, section, bfd_flags))
533
        return -1;
534
    }
535
 
536
  return 0;
537
}
538
 
539
/* Read & process IHS/EIHS record
540
   return 0 on success, -1 on error  */
541
int
542
_bfd_vms_slurp_ihs (bfd *abfd, unsigned int offset)
543
{
544
  unsigned char *p = PRIV (vms_rec) + offset;
545
  unsigned int gstvbn = bfd_getl32 (p + EIHS_S_L_GSTVBN);
546
  unsigned int gstsize ATTRIBUTE_UNUSED = bfd_getl32 (p + EIHS_S_L_GSTSIZE);
547
  unsigned int dstvbn = bfd_getl32 (p + EIHS_S_L_DSTVBN);
548
  unsigned int dstsize = bfd_getl32 (p + EIHS_S_L_DSTSIZE);
549
  unsigned int dmtvbn = bfd_getl32 (p + EIHS_S_L_DMTVBN);
550
  unsigned int dmtbytes = bfd_getl32 (p + EIHS_S_L_DMTBYTES);
551
  asection *section;
552
 
553
#if VMS_DEBUG
554
  vms_debug (8, "_bfd_vms_slurp_ihs\n");
555
  vms_debug (4, "EIHS record gstvbn %d gstsize %d dstvbn %d dstsize %d dmtvbn %d dmtbytes %d\n",
556
             gstvbn, gstsize, dstvbn, dstsize, dmtvbn, dmtbytes);
557
#endif
558
 
559
  if (dstvbn)
560
    {
561
      flagword bfd_flags = SEC_HAS_CONTENTS | SEC_DEBUGGING;
562
 
563
      section = bfd_make_section (abfd, "$DST$");
564
      if (!section)
565
        return -1;
566
 
567
      section->size = dstsize;
568
      section->filepos = VMS_BLOCK_SIZE * (dstvbn - 1);
569
 
570
      if (!bfd_set_section_flags (abfd, section, bfd_flags))
571
        return -1;
572
 
573
      PRIV (dst_section) = section;
574
      abfd->flags |= (HAS_DEBUG | HAS_LINENO);
575
    }
576
 
577
  if (dmtvbn)
578
    {
579
      flagword bfd_flags = SEC_HAS_CONTENTS | SEC_DEBUGGING;
580
 
581
      section = bfd_make_section (abfd, "$DMT$");
582
      if (!section)
583
        return -1;
584
 
585
      section->size = dmtbytes;
586
      section->filepos = VMS_BLOCK_SIZE * (dmtvbn - 1);
587
 
588
      if (!bfd_set_section_flags (abfd, section, bfd_flags))
589
        return -1;
590
    }
591
 
592
  if (gstvbn)
593
    {
594
      flagword bfd_flags = SEC_HAS_CONTENTS;
595
 
596
      section = bfd_make_section (abfd, "$GST$");
597
      if (!section)
598
        return -1;
599
 
600
      if (bfd_seek (abfd, VMS_BLOCK_SIZE * (gstvbn - 1), SEEK_SET))
601
        {
602
          bfd_set_error (bfd_error_file_truncated);
603
          return -1;
604
        }
605
 
606
      if (_bfd_vms_slurp_object_records (abfd) != 0)
607
        return -1;
608
 
609
      section->filepos = VMS_BLOCK_SIZE * (gstvbn - 1);
610
      section->size = bfd_tell (abfd) - section->filepos;
611
 
612
      if (!bfd_set_section_flags (abfd, section, bfd_flags))
613
        return -1;
614
 
615
      abfd->flags |= HAS_SYMS;
616
    }
617
 
618
  return 0;
619
}
620
 
621
/* Build a new module for the specified BFD.  */
622
 
623
static struct module *
624
new_module (bfd *abfd)
625
{
626
  struct module *module
627
    = (struct module *) bfd_zalloc (abfd, sizeof (struct module));
628
  module->file_table_count = 16; /* Arbitrary.  */
629
  module->file_table
630
    = bfd_malloc (module->file_table_count * sizeof (struct fileinfo));
631
  return module;
632
}
633
 
634
/* Parse debug info for a module and internalize it.  */
635
 
636
static void
637
parse_module (bfd *abfd, struct module *module, unsigned char *ptr,
638
              unsigned int length)
639
{
640
  unsigned char *maxptr = ptr + length, *src_ptr, *pcl_ptr;
641
  unsigned int prev_linum = 0, curr_linenum = 0;
642
  bfd_vma prev_pc = 0, curr_pc = 0;
643
  struct srecinfo *curr_srec, *srec;
644
  struct lineinfo *curr_line, *line;
645
  struct funcinfo *funcinfo;
646
 
647
  /* Initialize tables with zero element.  */
648
  curr_srec = (struct srecinfo *) bfd_zalloc (abfd, sizeof (struct srecinfo));
649
  module->srec_table = curr_srec;
650
 
651
  curr_line = (struct lineinfo *) bfd_zalloc (abfd, sizeof (struct lineinfo));
652
  module->line_table = curr_line;
653
 
654
  while (ptr < maxptr)
655
    {
656
      /* The first byte is not counted in the recorded length.  */
657
      int rec_length = bfd_getl16 (ptr) + 1;
658
      int rec_type = bfd_getl16 (ptr + 2);
659
 
660
#if VMS_DEBUG
661
      _bfd_vms_debug (2, "DST record: length %d, type %d\n",
662
                      rec_length, rec_type);
663
#endif
664
 
665
      switch (rec_type)
666
        {
667
        case DST_S_C_MODBEG:
668
          module->name
669
            = _bfd_vms_save_counted_string (ptr + DST_S_B_MODBEG_NAME);
670
 
671
          curr_pc = 0;
672
          prev_pc = 0;
673
          curr_linenum = 0;
674
          prev_linum = 0;
675
 
676
#if VMS_DEBUG
677
          _bfd_vms_debug (3, "module: %s\n", module->name);
678
#endif
679
          break;
680
 
681
        case DST_S_C_MODEND:
682
#if VMS_DEBUG
683
          _bfd_vms_debug (3, "end module\n");
684
#endif
685
          break;
686
 
687
        case DST_S_C_RTNBEG:
688
          funcinfo = (struct funcinfo *)
689
            bfd_zalloc (abfd, sizeof (struct funcinfo));
690
          funcinfo->name
691
            = _bfd_vms_save_counted_string (ptr + DST_S_B_RTNBEG_NAME);
692
          funcinfo->low = bfd_getl32 (ptr + DST_S_L_RTNBEG_ADDRESS);
693
          funcinfo->next = module->func_table;
694
          module->func_table = funcinfo;
695
 
696
#if VMS_DEBUG
697
          _bfd_vms_debug (3, "routine: %s at 0x%x\n",
698
                          funcinfo->name, funcinfo->low);
699
#endif
700
          break;
701
 
702
        case DST_S_C_RTNEND:
703
          module->func_table->high = module->func_table->low
704
            + bfd_getl32 (ptr + DST_S_L_RTNEND_SIZE) - 1;
705
 
706
          if (module->func_table->high > module->high)
707
            module->high = module->func_table->high;
708
 
709
#if VMS_DEBUG
710
          _bfd_vms_debug (3, "end routine\n");
711
#endif
712
          break;
713
 
714
        case DST_S_C_PROLOG:
715
#if VMS_DEBUG
716
          _bfd_vms_debug (3, "prologue\n");
717
#endif
718
          break;
719
 
720
        case DST_S_C_EPILOG:
721
#if VMS_DEBUG
722
          _bfd_vms_debug (3, "epilog\n");
723
#endif
724
          break;
725
 
726
        case DST_S_C_BLKBEG:
727
#if VMS_DEBUG
728
          _bfd_vms_debug (3, "block\n");
729
#endif
730
          break;
731
 
732
        case DST_S_C_BLKEND:
733
#if VMS_DEBUG
734
          _bfd_vms_debug (3, "end block\n");
735
#endif
736
          break;
737
 
738
        case DST_S_C_SOURCE:
739
          src_ptr = ptr + DST_S_C_SOURCE_HEADER_SIZE;
740
 
741
#if VMS_DEBUG
742
          _bfd_vms_debug (3, "source info\n");
743
#endif
744
 
745
          while (src_ptr < ptr + rec_length)
746
            {
747
              int cmd = src_ptr[0], cmd_length, data;
748
 
749
              switch (cmd)
750
                {
751
                case DST_S_C_SRC_DECLFILE:
752
                  {
753
                    unsigned int fileid
754
                      = bfd_getl16 (src_ptr + DST_S_W_SRC_DF_FILEID);
755
                    char *filename
756
                      = _bfd_vms_save_counted_string (src_ptr
757
                          + DST_S_B_SRC_DF_FILENAME);
758
 
759
                    while (fileid >= module->file_table_count)
760
                      {
761
                        module->file_table_count *= 2;
762
                        module->file_table
763
                          = bfd_realloc (module->file_table,
764
                                         module->file_table_count
765
                                           * sizeof (struct fileinfo));
766
                      }
767
 
768
                    module->file_table [fileid].name = filename;
769
                    module->file_table [fileid].srec = 1;
770
                    cmd_length = src_ptr[DST_S_B_SRC_DF_LENGTH] + 2;
771
#if VMS_DEBUG
772
                    _bfd_vms_debug (4, "DST_S_C_SRC_DECLFILE: %d, %s\n",
773
                                    fileid,
774
                                    module->file_table [fileid].name);
775
#endif
776
                  }
777
                  break;
778
 
779
                case DST_S_C_SRC_DEFLINES_B:
780
                  /* Perform the association and set the next higher index
781
                     to the limit.  */
782
                  data = src_ptr[DST_S_B_SRC_UNSBYTE];
783
                  srec = (struct srecinfo *)
784
                    bfd_zalloc (abfd, sizeof (struct srecinfo));
785
                  srec->line = curr_srec->line + data;
786
                  srec->srec = curr_srec->srec + data;
787
                  srec->sfile = curr_srec->sfile;
788
                  curr_srec->next = srec;
789
                  curr_srec = srec;
790
                  cmd_length = 2;
791
#if VMS_DEBUG
792
                  _bfd_vms_debug (4, "DST_S_C_SRC_DEFLINES_B: %d\n", data);
793
#endif
794
                  break;
795
 
796
                case DST_S_C_SRC_DEFLINES_W:
797
                  /* Perform the association and set the next higher index
798
                     to the limit.  */
799
                  data = bfd_getl16 (src_ptr + DST_S_W_SRC_UNSWORD);
800
                  srec = (struct srecinfo *)
801
                    bfd_zalloc (abfd, sizeof (struct srecinfo));
802
                  srec->line = curr_srec->line + data;
803
                  srec->srec = curr_srec->srec + data,
804
                  srec->sfile = curr_srec->sfile;
805
                  curr_srec->next = srec;
806
                  curr_srec = srec;
807
                  cmd_length = 3;
808
#if VMS_DEBUG
809
                  _bfd_vms_debug (4, "DST_S_C_SRC_DEFLINES_W: %d\n", data);
810
#endif
811
                  break;
812
 
813
                case DST_S_C_SRC_INCRLNUM_B:
814
                  data = src_ptr[DST_S_B_SRC_UNSBYTE];
815
                  curr_srec->line += data;
816
                  cmd_length = 2;
817
#if VMS_DEBUG
818
                  _bfd_vms_debug (4, "DST_S_C_SRC_INCRLNUM_B: %d\n", data);
819
#endif
820
                  break;
821
 
822
                case DST_S_C_SRC_SETFILE:
823
                  data = bfd_getl16 (src_ptr + DST_S_W_SRC_UNSWORD);
824
                  curr_srec->sfile = data;
825
                  curr_srec->srec = module->file_table[data].srec;
826
                  cmd_length = 3;
827
#if VMS_DEBUG
828
                  _bfd_vms_debug (4, "DST_S_C_SRC_SETFILE: %d\n", data);
829
#endif
830
                  break;
831
 
832
                case DST_S_C_SRC_SETLNUM_L:
833
                  data = bfd_getl32 (src_ptr + DST_S_L_SRC_UNSLONG);
834
                  curr_srec->line = data;
835
                  cmd_length = 5;
836
#if VMS_DEBUG
837
                  _bfd_vms_debug (4, "DST_S_C_SRC_SETLNUM_L: %d\n", data);
838
#endif
839
                  break;
840
 
841
                case DST_S_C_SRC_SETLNUM_W:
842
                  data = bfd_getl16 (src_ptr + DST_S_W_SRC_UNSWORD);
843
                  curr_srec->line = data;
844
                  cmd_length = 3;
845
#if VMS_DEBUG
846
                  _bfd_vms_debug (4, "DST_S_C_SRC_SETLNUM_W: %d\n", data);
847
#endif
848
                  break;
849
 
850
                case DST_S_C_SRC_SETREC_L:
851
                  data = bfd_getl32 (src_ptr + DST_S_L_SRC_UNSLONG);
852
                  curr_srec->srec = data;
853
                  module->file_table[curr_srec->sfile].srec = data;
854
                  cmd_length = 5;
855
#if VMS_DEBUG
856
                  _bfd_vms_debug (4, "DST_S_C_SRC_SETREC_L: %d\n", data);
857
#endif
858
                  break;
859
 
860
                case DST_S_C_SRC_SETREC_W:
861
                  data = bfd_getl16 (src_ptr + DST_S_W_SRC_UNSWORD);
862
                  curr_srec->srec = data;
863
                  module->file_table[curr_srec->sfile].srec = data;
864
                  cmd_length = 3;
865
#if VMS_DEBUG
866
                  _bfd_vms_debug (4, "DST_S_C_SRC_SETREC_W: %d\n", data);
867
#endif
868
                  break;
869
 
870
                case DST_S_C_SRC_FORMFEED:
871
                  cmd_length = 1;
872
#if VMS_DEBUG
873
                  _bfd_vms_debug (4, "DST_S_C_SRC_FORMFEED\n");
874
#endif
875
                  break;
876
 
877
                default:
878
                  (*_bfd_error_handler) (_("unknown source command %d"),
879
                                         cmd);
880
                  cmd_length = 2;
881
                  break;
882
                }
883
 
884
              src_ptr += cmd_length;
885
            }
886
          break;
887
 
888
        case DST_S_C_LINE_NUM:
889
          pcl_ptr = ptr + DST_S_C_LINE_NUM_HEADER_SIZE;
890
 
891
#if VMS_DEBUG
892
          _bfd_vms_debug (3, "line info\n");
893
#endif
894
 
895
          while (pcl_ptr < ptr + rec_length)
896
            {
897
              /* The command byte is signed so we must sign-extend it.  */
898
              int cmd = ((signed char *)pcl_ptr)[0], cmd_length, data;
899
 
900
              switch (cmd)
901
                {
902
                case DST_S_C_DELTA_PC_W:
903
                  data = bfd_getl16 (pcl_ptr + DST_S_W_PCLINE_UNSWORD);
904
                  curr_pc += data;
905
                  curr_linenum += 1;
906
                  cmd_length = 3;
907
#if VMS_DEBUG
908
                  _bfd_vms_debug (4, "DST_S_C_DELTA_PC_W: %d\n", data);
909
#endif
910
                  break;
911
 
912
                case DST_S_C_DELTA_PC_L:
913
                  data = bfd_getl32 (pcl_ptr + DST_S_L_PCLINE_UNSLONG);
914
                  curr_pc += data;
915
                  curr_linenum += 1;
916
                  cmd_length = 5;
917
#if VMS_DEBUG
918
                  _bfd_vms_debug (4, "DST_S_C_DELTA_PC_L: %d\n", data);
919
#endif
920
                  break;
921
 
922
                case DST_S_C_INCR_LINUM:
923
                  data = pcl_ptr[DST_S_B_PCLINE_UNSBYTE];
924
                  curr_linenum += data;
925
                  cmd_length = 2;
926
#if VMS_DEBUG
927
                  _bfd_vms_debug (4, "DST_S_C_INCR_LINUM: %d\n", data);
928
#endif
929
                  break;
930
 
931
                case DST_S_C_INCR_LINUM_W:
932
                  data = bfd_getl16 (pcl_ptr + DST_S_W_PCLINE_UNSWORD);
933
                  curr_linenum += data;
934
                  cmd_length = 3;
935
#if VMS_DEBUG
936
                  _bfd_vms_debug (4, "DST_S_C_INCR_LINUM_W: %d\n", data);
937
#endif
938
                  break;
939
 
940
                case DST_S_C_INCR_LINUM_L:
941
                  data = bfd_getl32 (pcl_ptr + DST_S_L_PCLINE_UNSLONG);
942
                  curr_linenum += data;
943
                  cmd_length = 5;
944
#if VMS_DEBUG
945
                  _bfd_vms_debug (4, "DST_S_C_INCR_LINUM_L: %d\n", data);
946
#endif
947
                  break;
948
 
949
                case DST_S_C_SET_LINUM_INCR:
950
                  (*_bfd_error_handler)
951
                    (_("DST_S_C_SET_LINUM_INCR not implemented"));
952
                  cmd_length = 2;
953
                  break;
954
 
955
                case DST_S_C_SET_LINUM_INCR_W:
956
                  (*_bfd_error_handler)
957
                    (_("DST_S_C_SET_LINUM_INCR_W not implemented"));
958
                  cmd_length = 3;
959
                  break;
960
 
961
                case DST_S_C_RESET_LINUM_INCR:
962
                  (*_bfd_error_handler)
963
                    (_("DST_S_C_RESET_LINUM_INCR not implemented"));
964
                  cmd_length = 1;
965
                  break;
966
 
967
                case DST_S_C_BEG_STMT_MODE:
968
                  (*_bfd_error_handler)
969
                    (_("DST_S_C_BEG_STMT_MODE not implemented"));
970
                  cmd_length = 1;
971
                  break;
972
 
973
                case DST_S_C_END_STMT_MODE:
974
                  (*_bfd_error_handler)
975
                    (_("DST_S_C_END_STMT_MODE not implemented"));
976
                  cmd_length = 1;
977
                  break;
978
 
979
                case DST_S_C_SET_LINUM_B:
980
                  data = pcl_ptr[DST_S_B_PCLINE_UNSBYTE];
981
                  curr_linenum = data;
982
                  cmd_length = 2;
983
#if VMS_DEBUG
984
                  _bfd_vms_debug (4, "DST_S_C_SET_LINUM_B: %d\n", data);
985
#endif
986
                  break;
987
 
988
                case DST_S_C_SET_LINE_NUM:
989
                  data = bfd_getl16 (pcl_ptr + DST_S_W_PCLINE_UNSWORD);
990
                  curr_linenum = data;
991
                  cmd_length = 3;
992
#if VMS_DEBUG
993
                  _bfd_vms_debug (4, "DST_S_C_SET_LINE_NUM: %d\n", data);
994
#endif
995
                  break;
996
 
997
                case DST_S_C_SET_LINUM_L:
998
                  data = bfd_getl32 (pcl_ptr + DST_S_L_PCLINE_UNSLONG);
999
                  curr_linenum = data;
1000
                  cmd_length = 5;
1001
#if VMS_DEBUG
1002
                  _bfd_vms_debug (4, "DST_S_C_SET_LINUM_L: %d\n", data);
1003
#endif
1004
                  break;
1005
 
1006
                case DST_S_C_SET_PC:
1007
                  (*_bfd_error_handler)
1008
                    (_("DST_S_C_SET_PC not implemented"));
1009
                  cmd_length = 2;
1010
                  break;
1011
 
1012
                case DST_S_C_SET_PC_W:
1013
                  (*_bfd_error_handler)
1014
                    (_("DST_S_C_SET_PC_W not implemented"));
1015
                  cmd_length = 3;
1016
                  break;
1017
 
1018
                case DST_S_C_SET_PC_L:
1019
                  (*_bfd_error_handler)
1020
                    (_("DST_S_C_SET_PC_L not implemented"));
1021
                  cmd_length = 5;
1022
                  break;
1023
 
1024
                case DST_S_C_SET_STMTNUM:
1025
                  (*_bfd_error_handler)
1026
                    (_("DST_S_C_SET_STMTNUM not implemented"));
1027
                  cmd_length = 2;
1028
                  break;
1029
 
1030
                case DST_S_C_TERM:
1031
                  data = pcl_ptr[DST_S_B_PCLINE_UNSBYTE];
1032
                  curr_pc += data;
1033
                  cmd_length = 2;
1034
#if VMS_DEBUG
1035
                  _bfd_vms_debug (4, "DST_S_C_TERM: %d\n", data);
1036
#endif
1037
                  break;
1038
 
1039
                case DST_S_C_TERM_W:
1040
                  data = bfd_getl16 (pcl_ptr + DST_S_W_PCLINE_UNSWORD);
1041
                  curr_pc += data;
1042
                  cmd_length = 3;
1043
#if VMS_DEBUG
1044
                  _bfd_vms_debug (4, "DST_S_C_TERM_W: %d\n", data);
1045
#endif
1046
                  break;
1047
 
1048
                case DST_S_C_TERM_L:
1049
                  data = bfd_getl32 (pcl_ptr + DST_S_L_PCLINE_UNSLONG);
1050
                  curr_pc += data;
1051
                  cmd_length = 5;
1052
#if VMS_DEBUG
1053
                  _bfd_vms_debug (4, "DST_S_C_TERM_L: %d\n", data);
1054
#endif
1055
                  break;
1056
 
1057
                case DST_S_C_SET_ABS_PC:
1058
                  data = bfd_getl32 (pcl_ptr + DST_S_L_PCLINE_UNSLONG);
1059
                  curr_pc = data;
1060
                  cmd_length = 5;
1061
#if VMS_DEBUG
1062
                  _bfd_vms_debug (4, "DST_S_C_SET_ABS_PC: 0x%x\n", data);
1063
#endif
1064
                  break;
1065
 
1066
                default:
1067
                  if (cmd <= 0)
1068
                    {
1069
                      curr_pc -= cmd;
1070
                      curr_linenum += 1;
1071
                      cmd_length = 1;
1072
#if VMS_DEBUG
1073
                      _bfd_vms_debug (4, "bump pc to 0x%llx and line to %d\n",
1074
                                      curr_pc, curr_linenum);
1075
#endif
1076
                    }
1077
                  else
1078
                    {
1079
                      (*_bfd_error_handler) (_("unknown line command %d"),
1080
                                             cmd);
1081
                      cmd_length = 2;
1082
                    }
1083
                  break;
1084
                }
1085
 
1086
              if ((curr_linenum != prev_linum && curr_pc != prev_pc)
1087
                  || cmd <= 0
1088
                  || cmd == DST_S_C_DELTA_PC_L
1089
                  || cmd == DST_S_C_DELTA_PC_W)
1090
                {
1091
                  line = (struct lineinfo *)
1092
                    bfd_zalloc (abfd, sizeof (struct lineinfo));
1093
                  line->address = curr_pc;
1094
                  line->line = curr_linenum;
1095
 
1096
                  curr_line->next = line;
1097
                  curr_line = line;
1098
 
1099
                  prev_linum = curr_linenum;
1100
                  prev_pc = curr_pc;
1101
#if VMS_DEBUG
1102
                  _bfd_vms_debug (4, "-> correlate pc 0x%llx with line %d\n",
1103
                                  curr_pc, curr_linenum);
1104
#endif
1105
                }
1106
 
1107
              pcl_ptr += cmd_length;
1108
            }
1109
          break;
1110
 
1111
        case 0x17: /* Undocumented type used by DEC C to declare equates.  */
1112
#if VMS_DEBUG
1113
          _bfd_vms_debug (3, "undocumented type 0x17\n");
1114
#endif
1115
          break;
1116
 
1117
        default:
1118
#if VMS_DEBUG
1119
          _bfd_vms_debug (3, "ignoring record\n");
1120
#endif
1121
          break;
1122
 
1123
        }
1124
 
1125
      ptr += rec_length;
1126
    }
1127
 
1128
  /* Finalize tables with EOL marker.  */
1129
  srec = (struct srecinfo *) bfd_zalloc (abfd, sizeof (struct srecinfo));
1130
  srec->line = (unsigned int) -1;
1131
  srec->srec = (unsigned int) -1;
1132
  curr_srec->next = srec;
1133
 
1134
  line = (struct lineinfo *) bfd_zalloc (abfd, sizeof (struct lineinfo));
1135
  line->line = (unsigned int) -1;
1136
  line->address = (bfd_vma) -1;
1137
  curr_line->next = line;
1138
 
1139
  /* Advertise that this module has been parsed.  This is needed
1140
     because parsing can be either performed at module creation
1141
     or deferred until debug info is consumed.  */
1142
  SET_MODULE_PARSED (module);
1143
}
1144
 
1145
/* Build the list of modules for the specified BFD.  */
1146
 
1147
static struct module *
1148
build_module_list (bfd *abfd)
1149
{
1150
  struct module *module, *list = NULL;
1151
  asection *dmt;
1152
 
1153
  if ((dmt = bfd_get_section_by_name (abfd, "$DMT$")))
1154
    {
1155
      /* We have a DMT section so this must be an image.  Parse the
1156
         section and build the list of modules.  This is sufficient
1157
         since we can compute the start address and the end address
1158
         of every module from the section contents.  */
1159
      bfd_size_type size = bfd_get_section_size (dmt);
1160
      unsigned char *ptr, *end;
1161
 
1162
      ptr = (unsigned char *) bfd_alloc (abfd, size);
1163
      if (! ptr)
1164
        return NULL;
1165
 
1166
      if (! bfd_get_section_contents (abfd, dmt, ptr, 0, size))
1167
        return NULL;
1168
 
1169
#if VMS_DEBUG
1170
      _bfd_vms_debug (2, "DMT\n");
1171
#endif
1172
 
1173
      end = ptr + size;
1174
 
1175
      while (ptr < end)
1176
        {
1177
          /* Each header declares a module with its start offset and size
1178
             of debug info in the DST section, as well as the count of
1179
             program sections (i.e. address spans) it contains.  */
1180
          int modbeg = bfd_getl32 (ptr + DBG_S_L_DMT_MODBEG);
1181
          int size = bfd_getl32 (ptr + DBG_S_L_DST_SIZE);
1182
          int count = bfd_getl16 (ptr + DBG_S_W_DMT_PSECT_COUNT);
1183
          ptr += DBG_S_C_DMT_HEADER_SIZE;
1184
 
1185
#if VMS_DEBUG
1186
          _bfd_vms_debug (3, "module: modbeg = %d, size = %d, count = %d\n",
1187
                          modbeg, size, count);
1188
#endif
1189
 
1190
          /* We create a 'module' structure for each program section since
1191
             we only support contiguous addresses in a 'module' structure.
1192
             As a consequence, the actual debug info in the DST section is
1193
             shared and can be parsed multiple times; that doesn't seem to
1194
             cause problems in practice.  */
1195
          while (count-- > 0)
1196
            {
1197
              int start = bfd_getl32 (ptr + DBG_S_L_DMT_PSECT_START);
1198
              int length = bfd_getl32 (ptr + DBG_S_L_DMT_PSECT_LENGTH);
1199
              module = new_module (abfd);
1200
              module->modbeg = modbeg;
1201
              module->size = size;
1202
              module->low = start;
1203
              module->high = start + length;
1204
              module->next = list;
1205
              list = module;
1206
              ptr += DBG_S_C_DMT_PSECT_SIZE;
1207
 
1208
#if VMS_DEBUG
1209
              _bfd_vms_debug (4, "section: start = 0x%x, length = %d\n",
1210
                              start, length);
1211
#endif
1212
            }
1213
        }
1214
    }
1215
  else
1216
    {
1217
      /* We don't have a DMT section so this must be an object.  Parse
1218
         the module right now in order to compute its start address and
1219
         end address.  */
1220
      module = new_module (abfd);
1221
      parse_module (abfd, module, PRIV (dst_section)->contents,
1222
                    PRIV (dst_ptr_end) - PRIV (dst_section)->contents);
1223
      list = module;
1224
    }
1225
 
1226
  return list;
1227
}
1228
 
1229
/* Calculate and return the name of the source file and the line nearest
1230
   to the wanted location in the specified module.  */
1231
 
1232
static bfd_boolean
1233
module_find_nearest_line (bfd *abfd, struct module *module, bfd_vma addr,
1234
                          const char **file, const char **func,
1235
                          unsigned int *line)
1236
{
1237
  struct funcinfo *funcinfo;
1238
  struct lineinfo *lineinfo;
1239
  struct srecinfo *srecinfo;
1240
  bfd_boolean ret = FALSE;
1241
 
1242
  /* Parse this module if that was not done at module creation.  */
1243
  if (! IS_MODULE_PARSED (module))
1244
    {
1245
      unsigned int size = module->size;
1246
      unsigned int modbeg = PRIV (dst_section)->filepos + module->modbeg;
1247
      unsigned char *buffer = (unsigned char *) bfd_malloc (module->size);
1248
 
1249
      if (bfd_seek (abfd, modbeg, SEEK_SET) != 0
1250
          || bfd_bread (buffer, size, abfd) != size)
1251
        {
1252
          bfd_set_error (bfd_error_no_debug_section);
1253
          return FALSE;
1254
        }
1255
 
1256
      parse_module (abfd, module, buffer, size);
1257
      free (buffer);
1258
    }
1259
 
1260
  /* Find out the function (if any) that contains the address.  */
1261
  for (funcinfo = module->func_table; funcinfo; funcinfo = funcinfo->next)
1262
    if (addr >= funcinfo->low && addr <= funcinfo->high)
1263
      {
1264
        *func = funcinfo->name;
1265
        ret = TRUE;
1266
        break;
1267
      }
1268
 
1269
  /* Find out the source file and the line nearest to the address.  */
1270
  for (lineinfo = module->line_table; lineinfo; lineinfo = lineinfo->next)
1271
    if (lineinfo->next && addr < lineinfo->next->address)
1272
      {
1273
        for (srecinfo = module->srec_table; srecinfo; srecinfo = srecinfo->next)
1274
          if (srecinfo->next && lineinfo->line < srecinfo->next->line)
1275
            {
1276
              if (srecinfo->sfile > 0)
1277
                {
1278
                  *file = module->file_table[srecinfo->sfile].name;
1279
                  *line = srecinfo->srec + lineinfo->line - srecinfo->line;
1280
                }
1281
              else
1282
                {
1283
                  *file = module->name;
1284
                  *line = lineinfo->line;
1285
                }
1286
              return TRUE;
1287
            }
1288
 
1289
        break;
1290
      }
1291
 
1292
  return ret;
1293
}
1294
 
1295
/* Provided a BFD, a section and an offset into the section, calculate and
1296
   return the name of the source file and the line nearest to the wanted
1297
   location.  */
1298
 
1299
bfd_boolean
1300
_bfd_vms_find_nearest_dst_line (bfd *abfd, asection *section,
1301
                                asymbol **symbols ATTRIBUTE_UNUSED,
1302
                                bfd_vma offset, const char **file,
1303
                                const char **func, unsigned int *line)
1304
{
1305
  struct module *module;
1306
 
1307
  /* What address are we looking for?  */
1308
  bfd_vma addr = section->vma + offset;
1309
 
1310
  *file = NULL;
1311
  *func = NULL;
1312
  *line = 0;
1313
 
1314
  if (PRIV (dst_section) == NULL)
1315
    return FALSE;
1316
 
1317
  if (PRIV (modules) == NULL)
1318
    {
1319
      PRIV (modules) = build_module_list (abfd);
1320
      if (PRIV (modules) == NULL)
1321
        return FALSE;
1322
    }
1323
 
1324
  for (module = PRIV (modules); module; module = module->next)
1325
    if (addr >= module->low && addr <= module->high)
1326
      return module_find_nearest_line (abfd, module, addr, file, func, line);
1327
 
1328
  return FALSE;
1329
}
1330
 
1331
/* Process EDBG/ETBT record.
1332
   Return 0 on success, -1 on error  */
1333
 
1334
static int
1335
vms_slurp_debug (bfd *abfd)
1336
{
1337
  if (PRIV (dst_section) == NULL)
1338
    {
1339
      /* We have no way to find out beforehand how much debug info there
1340
         is in an object file, so pick an initial amount and grow it as
1341
         needed later.  */
1342
      flagword flags = SEC_HAS_CONTENTS | SEC_DEBUGGING | SEC_RELOC;
1343
      asection *section = bfd_make_section (abfd, "$DST$");
1344
      if (!section)
1345
        return -1;
1346
      section->size = 1024;
1347
      if (!bfd_set_section_flags (abfd, section, flags))
1348
        return -1;
1349
      section->contents = ((unsigned char *)
1350
                           bfd_zmalloc (section->size));
1351
      if (section->contents == NULL)
1352
        return -1;
1353
      section->filepos = (unsigned int)-1;
1354
      PRIV (dst_section) = section;
1355
    }
1356
 
1357
  PRIV (image_section) = PRIV (dst_section);
1358
  PRIV (image_ptr) = PRIV (dst_section)->contents;
1359
 
1360
  return _bfd_vms_slurp_tir (abfd, EOBJ_S_C_ETIR);
1361
}
1362
 
1363
/* Process DBG/EDBG record.
1364
   Return 0 on success, -1 on error.  */
1365
 
1366
int
1367
_bfd_vms_slurp_dbg (bfd *abfd, int objtype ATTRIBUTE_UNUSED)
1368
{
1369
#if VMS_DEBUG
1370
  _bfd_vms_debug (2, "DBG/EDBG\n");
1371
#endif
1372
 
1373
  abfd->flags |= (HAS_DEBUG | HAS_LINENO);
1374
 
1375
  return vms_slurp_debug (abfd);
1376
}
1377
 
1378
/* Process TBT/ETBT record.
1379
   Return 0 on success, -1 on error.  */
1380
 
1381
int
1382
_bfd_vms_slurp_tbt (bfd *abfd, int objtype ATTRIBUTE_UNUSED)
1383
{
1384
#if VMS_DEBUG
1385
  _bfd_vms_debug (2, "TBT/ETBT\n");
1386
#endif
1387
 
1388
  abfd->flags |= HAS_LINENO;
1389
 
1390
  return vms_slurp_debug (abfd);
1391
}
1392
 
1393
/* Write DBG/EDBG record.  */
1394
 
1395
int
1396
_bfd_vms_write_dbg (bfd *abfd ATTRIBUTE_UNUSED, int objtype ATTRIBUTE_UNUSED)
1397
{
1398
#if VMS_DEBUG
1399
  _bfd_vms_debug (2, "vms_write_dbg (%p, objtype)\n", abfd, objtype);
1400
#endif
1401
 
1402
  return 0;
1403
}
1404
 
1405
/* Write TBT/ETBT record.  */
1406
 
1407
int
1408
_bfd_vms_write_tbt (bfd *abfd ATTRIBUTE_UNUSED, int objtype ATTRIBUTE_UNUSED)
1409
{
1410
#if VMS_DEBUG
1411
  _bfd_vms_debug (2, "vms_write_tbt (%p, %d)\n", abfd, objtype);
1412
#endif
1413
 
1414
  return 0;
1415
}

powered by: WebSVN 2.1.0

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