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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [gdb-5.0/] [bfd/] [vms-gsd.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 104 markom
/* vms-gsd.c -- BFD back-end for VAX (openVMS/VAX) and
2
   EVAX (openVMS/Alpha) files.
3
   Copyright 1996, 1997, 1998, 1999 Free Software Foundation Inc.
4
 
5
   go and read the openVMS linker manual (esp. appendix B)
6
   if you don't know what's going on here :-)
7
 
8
   Written by Klaus K"ampf (kkaempf@rmi.de)
9
 
10
This program is free software; you can redistribute it and/or modify
11
it under the terms of the GNU General Public License as published by
12
the Free Software Foundation; either version 2 of the License, or
13
(at your option) any later version.
14
 
15
This program is distributed in the hope that it will be useful,
16
but WITHOUT ANY WARRANTY; without even the implied warranty of
17
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18
GNU General Public License for more details.
19
 
20
You should have received a copy of the GNU General Public License
21
along with this program; if not, write to the Free Software
22
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
23
 
24
 
25
#include <ctype.h>
26
 
27
#include "bfd.h"
28
#include "sysdep.h"
29
#include "bfdlink.h"
30
#include "libbfd.h"
31
 
32
#include "vms.h"
33
 
34
/*-----------------------------------------------------------------------------*/
35
 
36
/* typical sections for vax object files  */
37
 
38
#define VAX_CODE_NAME           "$CODE"
39
#define VAX_DATA_NAME           "$DATA"
40
#define VAX_ADDRESS_DATA_NAME   "$ADDRESS_DATA"
41
 
42
/* typical sections for evax object files  */
43
 
44
#define EVAX_ABS_NAME           "$ABS$"
45
#define EVAX_CODE_NAME          "$CODE$"
46
#define EVAX_LINK_NAME          "$LINK$"
47
#define EVAX_DATA_NAME          "$DATA$"
48
#define EVAX_BSS_NAME           "$BSS$"
49
#define EVAX_READONLYADDR_NAME  "$READONLY_ADDR$"
50
#define EVAX_READONLY_NAME      "$READONLY$"
51
#define EVAX_LITERAL_NAME       "$LITERAL$"
52
#define EVAX_COMMON_NAME        "$COMMON$"
53
#define EVAX_LOCAL_NAME         "$LOCAL$"
54
 
55
struct sec_flags_struct {
56
  char *name;                   /* name of section */
57
  int vflags_always;
58
  flagword flags_always;        /* flags we set always */
59
  int vflags_hassize;
60
  flagword flags_hassize;       /* flags we set if the section has a size > 0 */
61
};
62
 
63
/* These flags are deccrtl/vaxcrtl (openVMS 6.2 VAX) compatible  */
64
 
65
static struct sec_flags_struct vax_section_flags[] = {
66
  { VAX_CODE_NAME,
67
        (GPS_S_M_PIC|GPS_S_M_REL|GPS_S_M_SHR|GPS_S_M_EXE|GPS_S_M_RD),
68
        (SEC_CODE),
69
        (GPS_S_M_PIC|GPS_S_M_REL|GPS_S_M_SHR|GPS_S_M_EXE|GPS_S_M_RD),
70
        (SEC_IN_MEMORY|SEC_CODE|SEC_HAS_CONTENTS|SEC_ALLOC|SEC_LOAD) },
71
  { VAX_DATA_NAME,
72
        (GPS_S_M_PIC|GPS_S_M_REL|GPS_S_M_RD|GPS_S_M_WRT),
73
        (SEC_DATA),
74
        (GPS_S_M_PIC|GPS_S_M_REL|GPS_S_M_RD|GPS_S_M_WRT),
75
        (SEC_IN_MEMORY|SEC_DATA|SEC_HAS_CONTENTS|SEC_ALLOC|SEC_LOAD) },
76
  { VAX_ADDRESS_DATA_NAME,
77
        (GPS_S_M_PIC|GPS_S_M_REL|GPS_S_M_RD),
78
        (SEC_DATA|SEC_READONLY),
79
        (GPS_S_M_PIC|GPS_S_M_REL|GPS_S_M_RD),
80
        (SEC_IN_MEMORY|SEC_DATA|SEC_HAS_CONTENTS|SEC_ALLOC|SEC_READONLY|SEC_LOAD) },
81
  { NULL,
82
        (GPS_S_M_PIC|GPS_S_M_OVR|GPS_S_M_REL|GPS_S_M_GBL|GPS_S_M_RD|GPS_S_M_WRT),
83
        (SEC_DATA),
84
        (GPS_S_M_PIC|GPS_S_M_OVR|GPS_S_M_REL|GPS_S_M_GBL|GPS_S_M_RD|GPS_S_M_WRT),
85
        (SEC_IN_MEMORY|SEC_DATA|SEC_HAS_CONTENTS|SEC_ALLOC|SEC_LOAD) }
86
};
87
 
88
 
89
/* These flags are deccrtl/vaxcrtl (openVMS 6.2 Alpha) compatible  */
90
 
91
static struct sec_flags_struct evax_section_flags[] = {
92
  { EVAX_ABS_NAME,
93
        (EGPS_S_V_SHR),
94
        (SEC_DATA),
95
        (EGPS_S_V_SHR),
96
        (SEC_IN_MEMORY|SEC_DATA|SEC_HAS_CONTENTS|SEC_ALLOC|SEC_LOAD) },
97
  { EVAX_CODE_NAME,
98
        (EGPS_S_V_PIC|EGPS_S_V_REL|EGPS_S_V_SHR|EGPS_S_V_EXE),
99
        (SEC_CODE),
100
        (EGPS_S_V_PIC|EGPS_S_V_REL|EGPS_S_V_SHR|EGPS_S_V_EXE),
101
        (SEC_IN_MEMORY|SEC_CODE|SEC_HAS_CONTENTS|SEC_ALLOC|SEC_LOAD) },
102
  { EVAX_LITERAL_NAME,
103
        (EGPS_S_V_PIC|EGPS_S_V_REL|EGPS_S_V_SHR|EGPS_S_V_RD|EGPS_S_V_NOMOD),
104
        (SEC_DATA|SEC_READONLY),
105
        (EGPS_S_V_PIC|EGPS_S_V_REL|EGPS_S_V_SHR|EGPS_S_V_RD),
106
        (SEC_IN_MEMORY|SEC_DATA|SEC_HAS_CONTENTS|SEC_ALLOC|SEC_READONLY|SEC_LOAD) },
107
  { EVAX_LINK_NAME,
108
        (EGPS_S_V_REL|EGPS_S_V_RD),
109
        (SEC_DATA|SEC_READONLY),
110
        (EGPS_S_V_REL|EGPS_S_V_RD),
111
        (SEC_IN_MEMORY|SEC_DATA|SEC_HAS_CONTENTS|SEC_ALLOC|SEC_READONLY|SEC_LOAD) },
112
  { EVAX_DATA_NAME,
113
        (EGPS_S_V_REL|EGPS_S_V_RD|EGPS_S_V_WRT|EGPS_S_V_NOMOD),
114
        (SEC_DATA),
115
        (EGPS_S_V_REL|EGPS_S_V_RD|EGPS_S_V_WRT),
116
        (SEC_IN_MEMORY|SEC_DATA|SEC_HAS_CONTENTS|SEC_ALLOC|SEC_LOAD) },
117
  { EVAX_BSS_NAME,
118
        (EGPS_S_V_REL|EGPS_S_V_RD|EGPS_S_V_WRT|EGPS_S_V_NOMOD),
119
        (SEC_NO_FLAGS),
120
        (EGPS_S_V_REL|EGPS_S_V_RD|EGPS_S_V_WRT|EGPS_S_V_NOMOD),
121
        (SEC_IN_MEMORY|SEC_HAS_CONTENTS|SEC_ALLOC|SEC_LOAD) },
122
  { EVAX_READONLYADDR_NAME,
123
        (EGPS_S_V_PIC|EGPS_S_V_REL|EGPS_S_V_RD),
124
        (SEC_DATA|SEC_READONLY),
125
        (EGPS_S_V_PIC|EGPS_S_V_REL|EGPS_S_V_RD),
126
        (SEC_IN_MEMORY|SEC_DATA|SEC_HAS_CONTENTS|SEC_ALLOC|SEC_READONLY|SEC_LOAD) },
127
  { EVAX_READONLY_NAME,
128
        (EGPS_S_V_PIC|EGPS_S_V_REL|EGPS_S_V_SHR|EGPS_S_V_RD|EGPS_S_V_NOMOD),
129
        (SEC_DATA|SEC_READONLY),
130
        (EGPS_S_V_PIC|EGPS_S_V_REL|EGPS_S_V_SHR|EGPS_S_V_RD),
131
        (SEC_IN_MEMORY|SEC_DATA|SEC_HAS_CONTENTS|SEC_ALLOC|SEC_READONLY|SEC_LOAD) },
132
  { EVAX_LOCAL_NAME,
133
        (EGPS_S_V_REL|EGPS_S_V_RD|EGPS_S_V_WRT),
134
        (SEC_DATA),
135
        (EGPS_S_V_REL|EGPS_S_V_RD|EGPS_S_V_WRT),
136
        (SEC_IN_MEMORY|SEC_DATA|SEC_HAS_CONTENTS|SEC_ALLOC|SEC_LOAD) },
137
  { NULL,
138
        (EGPS_S_V_REL|EGPS_S_V_RD|EGPS_S_V_WRT),
139
        (SEC_DATA),
140
        (EGPS_S_V_REL|EGPS_S_V_RD|EGPS_S_V_WRT),
141
        (SEC_IN_MEMORY|SEC_DATA|SEC_HAS_CONTENTS|SEC_ALLOC|SEC_LOAD) }
142
};
143
 
144
/* Retrieve bfd section flags by name and size  */
145
 
146
static flagword
147
vms_secflag_by_name (abfd, section_flags, name, size)
148
     bfd *abfd;
149
     struct sec_flags_struct *section_flags;
150
     char *name;
151
     int size;
152
{
153
  int i = 0;
154
 
155
  while (section_flags[i].name != NULL)
156
    {
157
      if ((PRIV(is_vax)?
158
            strcasecmp (name, section_flags[i].name):
159
            strcmp (name, section_flags[i].name)) == 0)
160
        {
161
          if (size > 0)
162
            return section_flags[i].flags_hassize;
163
          else
164
            return section_flags[i].flags_always;
165
        }
166
      i++;
167
    }
168
  if (size > 0)
169
    return section_flags[i].flags_hassize;
170
  return section_flags[i].flags_always;
171
}
172
 
173
 
174
/* Retrieve vms section flags by name and size  */
175
 
176
static flagword
177
vms_esecflag_by_name (section_flags, name, size)
178
     struct sec_flags_struct *section_flags;
179
     char *name;
180
     int size;
181
{
182
  int i = 0;
183
 
184
  while (section_flags[i].name != NULL)
185
    {
186
      if (strcmp (name, section_flags[i].name) == 0)
187
        {
188
          if (size > 0)
189
            return section_flags[i].vflags_hassize;
190
          else
191
            return section_flags[i].vflags_always;
192
        }
193
      i++;
194
    }
195
  if (size > 0)
196
    return section_flags[i].vflags_hassize;
197
  return section_flags[i].vflags_always;
198
}
199
 
200
/*-----------------------------------------------------------------------------*/
201
#if VMS_DEBUG
202
/* debug */
203
 
204
struct flagdescstruct { char *name; flagword value; };
205
 
206
/* Convert flag to printable string  */
207
 
208
static char *
209
flag2str(flagdesc, flags)
210
     struct flagdescstruct *flagdesc;
211
     flagword flags;
212
{
213
 
214
  static char res[64];
215
  int next = 0;
216
 
217
  res[0] = 0;
218
  while (flagdesc->name != NULL)
219
    {
220
      if ((flags & flagdesc->value) != 0)
221
        {
222
          if (next)
223
            strcat(res, ",");
224
          else
225
            next = 1;
226
          strcat (res, flagdesc->name);
227
        }
228
      flagdesc++;
229
    }
230
  return res;
231
}
232
#endif
233
 
234
/*-----------------------------------------------------------------------------*/
235
/* input routines */
236
 
237
/* Process GSD/EGSD record
238
   return 0 on success, -1 on error  */
239
 
240
int
241
_bfd_vms_slurp_gsd (abfd, objtype)
242
     bfd *abfd;
243
     int objtype;
244
{
245
#if VMS_DEBUG
246
  static struct flagdescstruct gpsflagdesc[] =
247
  {
248
    { "PIC", 0x0001 },
249
    { "LIB", 0x0002 },
250
    { "OVR", 0x0004 },
251
    { "REL", 0x0008 },
252
    { "GBL", 0x0010 },
253
    { "SHR", 0x0020 },
254
    { "EXE", 0x0040 },
255
    { "RD",  0x0080 },
256
    { "WRT", 0x0100 },
257
    { "VEC", 0x0200 },
258
    { "NOMOD", 0x0400 },
259
    { "COM", 0x0800 },
260
    { NULL, 0 }
261
  };
262
 
263
  static struct flagdescstruct gsyflagdesc[] =
264
  {
265
    { "WEAK", 0x0001 },
266
    { "DEF",  0x0002 },
267
    { "UNI",  0x0004 },
268
    { "REL",  0x0008 },
269
    { "COMM", 0x0010 },
270
    { "VECEP", 0x0020 },
271
    { "NORM", 0x0040 },
272
    { NULL, 0 }
273
  };
274
#endif
275
 
276
  int gsd_type, gsd_size;
277
  asection *section;
278
  unsigned char *vms_rec;
279
  flagword new_flags, old_flags;
280
  char *name;
281
  asymbol *symbol;
282
  vms_symbol_entry *entry;
283
  unsigned long base_addr;
284
  unsigned long align_addr;
285
  static unsigned int psect_idx = 0;
286
 
287
#if VMS_DEBUG
288
  vms_debug (2, "GSD/EGSD (%d/%x)\n", objtype, objtype);
289
#endif
290
 
291
  switch (objtype)
292
    {
293
      case EOBJ_S_C_EGSD:
294
        PRIV(vms_rec) += 8;     /* skip type, size, l_temp */
295
        PRIV(rec_size) -= 8;
296
        break;
297
      case OBJ_S_C_GSD:
298
        PRIV(vms_rec) += 1;
299
        PRIV(rec_size) -= 1;
300
        break;
301
      default:
302
        return -1;
303
    }
304
 
305
  /* calculate base address for each section  */
306
  base_addr = 0L;
307
 
308
  abfd->symcount = 0;
309
 
310
  while (PRIV(rec_size) > 0)
311
    {
312
      vms_rec = PRIV(vms_rec);
313
 
314
      if (objtype == OBJ_S_C_GSD)
315
        {
316
          gsd_type = *vms_rec;
317
        }
318
      else
319
        {
320
          _bfd_vms_get_header_values (abfd, vms_rec, &gsd_type, &gsd_size);
321
          gsd_type += EVAX_OFFSET;
322
        }
323
 
324
#if VMS_DEBUG
325
  vms_debug (3, "gsd_type %d\n", gsd_type);
326
#endif
327
 
328
      switch (gsd_type)
329
        {
330
          case GSD_S_C_PSC:
331
            {
332
              /*
333
               * program section definition
334
               */
335
 
336
              asection *old_section = 0;
337
 
338
#if VMS_DEBUG
339
  vms_debug (4, "GSD_S_C_PSC\n");
340
#endif
341
              /* If this section isn't a bfd section.  */
342
 
343
              if (PRIV(is_vax) && (psect_idx < (abfd->section_count-1)))
344
                {
345
                  /* check for temporary section from TIR record.  */
346
 
347
                  if (psect_idx < PRIV(section_count))
348
                    old_section = PRIV(sections)[psect_idx];
349
                  else
350
                    old_section = 0;
351
                }
352
 
353
              name = _bfd_vms_save_counted_string (vms_rec + 8);
354
              section = bfd_make_section (abfd, name);
355
              if (!section)
356
                {
357
                  (*_bfd_error_handler) (_("bfd_make_section (%s) failed"),
358
                                         name);
359
                  return -1;
360
                }
361
              old_flags = bfd_getl16 (vms_rec + 2);
362
              section->_raw_size = bfd_getl32(vms_rec + 4);     /* allocation */
363
              new_flags = vms_secflag_by_name (abfd, vax_section_flags, name, section->_raw_size);
364
              if (old_flags & EGPS_S_V_REL)
365
                new_flags |= SEC_RELOC;
366
              if (old_flags & GPS_S_M_OVR)
367
                new_flags |= SEC_IS_COMMON;
368
              if (!bfd_set_section_flags (abfd, section, new_flags))
369
                {
370
                  (*_bfd_error_handler)
371
                    (_("bfd_set_section_flags (%s, %x) failed"),
372
                     name, new_flags);
373
                  return -1;
374
                }
375
              section->alignment_power = vms_rec[1];
376
              align_addr = (1 << section->alignment_power);
377
              if ((base_addr % align_addr) != 0)
378
                base_addr += (align_addr - (base_addr % align_addr));
379
              section->vma = (bfd_vma)base_addr;
380
              base_addr += section->_raw_size;
381
 
382
              /* global section is common symbol  */
383
 
384
              if (old_flags & GPS_S_M_GBL)
385
                {
386
                  entry = _bfd_vms_enter_symbol (abfd, name);
387
                  if (entry == (vms_symbol_entry *)NULL)
388
                    {
389
                      bfd_set_error (bfd_error_no_memory);
390
                      return -1;
391
                    }
392
                  symbol = entry->symbol;
393
 
394
                  symbol->value = 0;
395
                  symbol->section = section;
396
                  symbol->flags = (BSF_GLOBAL|BSF_SECTION_SYM|BSF_OLD_COMMON);
397
                }
398
 
399
              /* copy saved contents if old_section set  */
400
 
401
              if (old_section != 0)
402
                {
403
                  section->contents = old_section->contents;
404
                  if (section->_raw_size < old_section->_raw_size)
405
                    {
406
                      (*_bfd_error_handler)
407
                        (_("Size mismatch section %s=%lx, %s=%lx"),
408
                         old_section->name,
409
                         (unsigned long) old_section->_raw_size,
410
                         section->name,
411
                         (unsigned long) section->_raw_size);
412
                      return -1;
413
                    }
414
                  else if (section->_raw_size > old_section->_raw_size)
415
                    {
416
                      section->contents = ((unsigned char *)
417
                                    bfd_realloc (old_section->contents, section->_raw_size));
418
                      if (section->contents == NULL)
419
                        {
420
                          bfd_set_error (bfd_error_no_memory);
421
                          return -1;
422
                        }
423
                    }
424
                }
425
              else
426
                {
427
                  section->contents = ((unsigned char *)
428
                                        bfd_malloc (section->_raw_size));
429
                  if (section->contents == NULL)
430
                    {
431
                      bfd_set_error (bfd_error_no_memory);
432
                      return -1;
433
                    }
434
                  memset (section->contents, 0, (size_t)section->_raw_size);
435
                }
436
              section->_cooked_size = section->_raw_size;
437
#if VMS_DEBUG
438
              vms_debug (4, "gsd psc %d (%s, flags %04x=%s) ",
439
                         section->index, name, old_flags, flag2str (gpsflagdesc, old_flags));
440
              vms_debug (4, "%d bytes at 0x%08lx (mem %p)\n",
441
                         section->_raw_size, section->vma, section->contents);
442
#endif
443
 
444
              gsd_size = vms_rec[8] + 9;
445
 
446
              psect_idx++;
447
            }
448
          break;
449
 
450
          case GSD_S_C_EPM:
451
          case GSD_S_C_EPMW:
452
#if VMS_DEBUG
453
                vms_debug(4, "gsd epm\n");
454
#endif
455
          /*FALLTHRU*/
456
          case GSD_S_C_SYM:
457
          case GSD_S_C_SYMW:
458
            {
459
              int name_offset, value_offset;
460
 
461
              /*
462
               * symbol specification (definition or reference)
463
               */
464
 
465
#if VMS_DEBUG
466
  vms_debug (4, "GSD_S_C_SYM(W)\n");
467
#endif
468
              old_flags = bfd_getl16 (vms_rec + 2);
469
              new_flags = BSF_NO_FLAGS;
470
 
471
              if (old_flags & GSY_S_M_WEAK)
472
                new_flags |= BSF_WEAK;
473
 
474
              switch (gsd_type)
475
                {
476
                  case GSD_S_C_EPM:
477
                    name_offset = 11;
478
                    value_offset = 5;
479
                    new_flags |= BSF_FUNCTION;
480
                    break;
481
                  case GSD_S_C_EPMW:
482
                    name_offset = 12;
483
                    value_offset = 6;
484
                    new_flags |= BSF_FUNCTION;
485
                    break;
486
                  case GSD_S_C_SYM:
487
                    if (old_flags & GSY_S_M_DEF)        /* symbol definition */
488
                      name_offset = 9;
489
                    else
490
                      name_offset = 4;
491
                    value_offset = 5;
492
                    break;
493
                  case GSD_S_C_SYMW:
494
                    if (old_flags & GSY_S_M_DEF)        /* symbol definition */
495
                      name_offset = 10;
496
                    else
497
                      name_offset = 5;
498
                    value_offset = 6;
499
                    break;
500
                }
501
 
502
              /* save symbol in vms_symbol_table */
503
 
504
              entry = _bfd_vms_enter_symbol (abfd,
505
                        _bfd_vms_save_counted_string (vms_rec + name_offset));
506
              if (entry == (vms_symbol_entry *)NULL)
507
                {
508
                  bfd_set_error (bfd_error_no_memory);
509
                  return -1;
510
                }
511
              symbol = entry->symbol;
512
 
513
              if (old_flags & GSY_S_M_DEF)      /* symbol definition */
514
                {
515
                  int psect;
516
 
517
                  symbol->value = bfd_getl32 (vms_rec+value_offset);
518
                  if ((gsd_type == GSD_S_C_SYMW)
519
                      || (gsd_type == GSD_S_C_EPMW))
520
                    psect = bfd_getl16 (vms_rec + value_offset - 2);
521
                  else
522
                    psect = vms_rec[value_offset-1];
523
 
524
                  symbol->section = (asection *)psect;
525
#if VMS_DEBUG
526
                  vms_debug(4, "gsd sym def #%d (%s, %d [%p], %04x=%s)\n", abfd->symcount,
527
                                symbol->name, (int)symbol->section, symbol->section, old_flags, flag2str(gsyflagdesc, old_flags));
528
#endif
529
                }
530
              else      /* symbol reference */
531
                {
532
                  symbol->section = bfd_make_section (abfd, BFD_UND_SECTION_NAME);
533
#if VMS_DEBUG
534
                  vms_debug (4, "gsd sym ref #%d (%s, %s [%p], %04x=%s)\n", abfd->symcount,
535
                                symbol->name, symbol->section->name, symbol->section, old_flags, flag2str (gsyflagdesc, old_flags));
536
#endif
537
                }
538
 
539
              gsd_size = vms_rec[name_offset] + name_offset + 1;
540
              symbol->flags = new_flags;
541
            }
542
 
543
          break;
544
 
545
          case GSD_S_C_PRO:
546
          case GSD_S_C_PROW:
547
#if VMS_DEBUG
548
                vms_debug(4, "gsd pro\n");
549
#endif
550
          break;
551
          case GSD_S_C_IDC:
552
#if VMS_DEBUG
553
                vms_debug(4, "gsd idc\n");
554
#endif
555
          break;
556
          case GSD_S_C_ENV:
557
#if VMS_DEBUG
558
                vms_debug(4, "gsd env\n");
559
#endif
560
          break;
561
          case GSD_S_C_LSY:
562
#if VMS_DEBUG
563
                vms_debug(4, "gsd lsy\n");
564
#endif
565
          break;
566
          case GSD_S_C_LEPM:
567
#if VMS_DEBUG
568
                vms_debug(4, "gsd lepm\n");
569
#endif
570
          break;
571
          case GSD_S_C_LPRO:
572
#if VMS_DEBUG
573
                vms_debug(4, "gsd lpro\n");
574
#endif
575
          break;
576
          case GSD_S_C_SPSC:
577
#if VMS_DEBUG
578
                vms_debug(4, "gsd spsc\n");
579
#endif
580
          break;
581
          case GSD_S_C_SYMV:
582
#if VMS_DEBUG
583
                vms_debug(4, "gsd symv\n");
584
#endif
585
          break;
586
          case GSD_S_C_EPMV:
587
#if VMS_DEBUG
588
                vms_debug(4, "gsd epmv\n");
589
#endif
590
          break;
591
          case GSD_S_C_PROV:
592
#if VMS_DEBUG
593
                vms_debug(4, "gsd prov\n");
594
#endif
595
          break;
596
 
597
        case EGSD_S_C_PSC + EVAX_OFFSET:
598
          {
599
            /* program section definition  */
600
 
601
            name = _bfd_vms_save_counted_string (vms_rec+12);
602
            section = bfd_make_section (abfd, name);
603
            if (!section)
604
              return -1;
605
            old_flags = bfd_getl16 (vms_rec + 6);
606
            section->_raw_size = bfd_getl32 (vms_rec + 8);      /* allocation */
607
            new_flags = vms_secflag_by_name (abfd, evax_section_flags, name, (int) section->_raw_size);
608
            if (old_flags & EGPS_S_V_REL)
609
              new_flags |= SEC_RELOC;
610
            if (!bfd_set_section_flags (abfd, section, new_flags))
611
              return -1;
612
            section->alignment_power = vms_rec[4];
613
            align_addr = (1 << section->alignment_power);
614
            if ((base_addr % align_addr) != 0)
615
              base_addr += (align_addr - (base_addr % align_addr));
616
            section->vma = (bfd_vma)base_addr;
617
            base_addr += section->_raw_size;
618
            section->contents = ((unsigned char *)
619
                                 bfd_malloc (section->_raw_size));
620
            if (section->contents == NULL)
621
              return -1;
622
            memset (section->contents, 0, (size_t) section->_raw_size);
623
            section->_cooked_size = section->_raw_size;
624
#if VMS_DEBUG
625
            vms_debug(4, "egsd psc %d (%s, flags %04x=%s) ",
626
                       section->index, name, old_flags, flag2str(gpsflagdesc, old_flags));
627
            vms_debug(4, "%d bytes at 0x%08lx (mem %p)\n",
628
                       section->_raw_size, section->vma, section->contents);
629
#endif
630
          }
631
          break;
632
 
633
        case EGSD_S_C_SYM + EVAX_OFFSET:
634
          {
635
            /* symbol specification (definition or reference)  */
636
 
637
            symbol = _bfd_vms_make_empty_symbol (abfd);
638
            if (symbol == 0)
639
              return -1;
640
 
641
            old_flags = bfd_getl16 (vms_rec + 6);
642
            new_flags = BSF_NO_FLAGS;
643
 
644
            if (old_flags & EGSY_S_V_WEAK)
645
              new_flags |= BSF_WEAK;
646
 
647
            if (vms_rec[6] & EGSY_S_V_DEF)      /* symbol definition */
648
              {
649
                symbol->name =
650
                  _bfd_vms_save_counted_string (vms_rec+32);
651
                if (old_flags & EGSY_S_V_NORM)
652
                  {         /* proc def */
653
                    new_flags |= BSF_FUNCTION;
654
                  }
655
                symbol->value = bfd_getl64 (vms_rec+8);
656
                symbol->section = (asection *)((unsigned long) bfd_getl32 (vms_rec+28));
657
#if VMS_DEBUG
658
                vms_debug(4, "egsd sym def #%d (%s, %d, %04x=%s)\n", abfd->symcount,
659
                           symbol->name, (int)symbol->section, old_flags, flag2str(gsyflagdesc, old_flags));
660
#endif
661
              }
662
            else        /* symbol reference */
663
              {
664
                symbol->name =
665
                  _bfd_vms_save_counted_string (vms_rec+8);
666
#if VMS_DEBUG
667
                vms_debug(4, "egsd sym ref #%d (%s, %04x=%s)\n", abfd->symcount,
668
                           symbol->name, old_flags, flag2str(gsyflagdesc, old_flags));
669
#endif
670
                symbol->section = bfd_make_section (abfd, BFD_UND_SECTION_NAME);
671
              }
672
 
673
            symbol->flags = new_flags;
674
 
675
            /* save symbol in vms_symbol_table  */
676
 
677
            entry = (vms_symbol_entry *) bfd_hash_lookup (PRIV(vms_symbol_table), symbol->name, true, false);
678
            if (entry == (vms_symbol_entry *)NULL)
679
              {
680
                bfd_set_error (bfd_error_no_memory);
681
                return -1;
682
              }
683
            if (entry->symbol != (asymbol *)NULL)
684
              {                                 /* FIXME ?, DEC C generates this */
685
#if VMS_DEBUG
686
                vms_debug(4, "EGSD_S_C_SYM: duplicate \"%s\"\n", symbol->name);
687
#endif
688
              }
689
            else
690
              {
691
                entry->symbol = symbol;
692
                PRIV(gsd_sym_count)++;
693
                abfd->symcount++;
694
              }
695
          }
696
          break;
697
 
698
        case EGSD_S_C_IDC + EVAX_OFFSET:
699
          break;
700
 
701
        default:
702
          (*_bfd_error_handler) (_("unknown gsd/egsd subtype %d"), gsd_type);
703
          bfd_set_error (bfd_error_bad_value);
704
          return -1;
705
 
706
        } /* switch */
707
 
708
      PRIV(rec_size) -= gsd_size;
709
      PRIV(vms_rec) += gsd_size;
710
 
711
    } /* while (recsize > 0) */
712
 
713
  if (abfd->symcount > 0)
714
    abfd->flags |= HAS_SYMS;
715
 
716
  return 0;
717
}
718
 
719
/*-----------------------------------------------------------------------------*/
720
/* output routines */
721
 
722
/* Write section and symbol directory of bfd abfd  */
723
 
724
int
725
_bfd_vms_write_gsd (abfd, objtype)
726
     bfd *abfd;
727
     int objtype ATTRIBUTE_UNUSED;
728
{
729
  asection *section;
730
  asymbol *symbol;
731
  unsigned int symnum;
732
  int last_index = -1;
733
  char dummy_name[10];
734
  char *sname;
735
  flagword new_flags, old_flags;
736
 
737
#if VMS_DEBUG
738
  vms_debug (2, "vms_write_gsd (%p, %d)\n", abfd, objtype);
739
#endif
740
 
741
  /* output sections  */
742
 
743
  section = abfd->sections;
744
#if VMS_DEBUG
745
  vms_debug (3, "%d sections found\n", abfd->section_count);
746
#endif
747
 
748
  /* egsd is quadword aligned  */
749
 
750
  _bfd_vms_output_alignment (abfd, 8);
751
 
752
  _bfd_vms_output_begin (abfd, EOBJ_S_C_EGSD, -1);
753
  _bfd_vms_output_long (abfd, 0);
754
  _bfd_vms_output_push (abfd);          /* prepare output for subrecords */
755
 
756
  while (section != 0)
757
    {
758
#if VMS_DEBUG
759
  vms_debug (3, "Section #%d %s, %d bytes\n", section->index, section->name, (int)section->_raw_size);
760
#endif
761
 
762
        /* 13 bytes egsd, max 31 chars name -> should be 44 bytes */
763
      if (_bfd_vms_output_check (abfd, 64) < 0)
764
        {
765
          _bfd_vms_output_pop (abfd);
766
          _bfd_vms_output_end (abfd);
767
          _bfd_vms_output_begin (abfd, EOBJ_S_C_EGSD, -1);
768
          _bfd_vms_output_long (abfd, 0);
769
          _bfd_vms_output_push (abfd);          /* prepare output for subrecords */
770
        }
771
 
772
        /* Create dummy sections to keep consecutive indices */
773
 
774
      while (section->index - last_index > 1)
775
        {
776
#if VMS_DEBUG
777
          vms_debug (3, "index %d, last %d\n", section->index, last_index);
778
#endif
779
          _bfd_vms_output_begin (abfd, EGSD_S_C_PSC, -1);
780
          _bfd_vms_output_short (abfd, 0);
781
          _bfd_vms_output_short (abfd, 0);
782
          _bfd_vms_output_long (abfd, 0);
783
          sprintf (dummy_name, ".DUMMY%02d", last_index);
784
          _bfd_vms_output_counted (abfd, dummy_name);
785
          _bfd_vms_output_flush (abfd);
786
          last_index++;
787
        }
788
 
789
      /* Don't know if this is neccesary for the linker but for now it keeps
790
         vms_slurp_gsd happy  */
791
 
792
      sname = (char *)section->name;
793
      if (*sname == '.')
794
        {
795
          sname++;
796
          if ((*sname == 't') && (strcmp (sname, "text") == 0))
797
            sname = PRIV(is_vax)?VAX_CODE_NAME:EVAX_CODE_NAME;
798
          else if ((*sname == 'd') && (strcmp (sname, "data") == 0))
799
            sname = PRIV(is_vax)?VAX_DATA_NAME:EVAX_DATA_NAME;
800
          else if ((*sname == 'b') && (strcmp (sname, "bss") == 0))
801
            sname = EVAX_BSS_NAME;
802
          else if ((*sname == 'l') && (strcmp (sname, "link") == 0))
803
            sname = EVAX_LINK_NAME;
804
          else if ((*sname == 'r') && (strcmp (sname, "rdata") == 0))
805
            sname = EVAX_READONLY_NAME;
806
          else if ((*sname == 'l') && (strcmp (sname, "literal") == 0))
807
            sname = EVAX_LITERAL_NAME;
808
          else if ((*sname == 'c') && (strcmp (sname, "comm") == 0))
809
            sname = EVAX_COMMON_NAME;
810
          else if ((*sname == 'l') && (strcmp (sname, "lcomm") == 0))
811
            sname = EVAX_LOCAL_NAME;
812
        }
813
      else
814
        sname = _bfd_vms_length_hash_symbol (abfd, sname, EOBJ_S_C_SECSIZ);
815
 
816
      _bfd_vms_output_begin (abfd, EGSD_S_C_PSC, -1);
817
      _bfd_vms_output_short (abfd, section->alignment_power & 0xff);
818
      if (bfd_is_com_section (section))
819
        {
820
          new_flags = (EGPS_S_V_OVR|EGPS_S_V_REL|EGPS_S_V_GBL|EGPS_S_V_RD|EGPS_S_V_WRT|EGPS_S_V_NOMOD|EGPS_S_V_COM);
821
        }
822
      else
823
        {
824
          new_flags = vms_esecflag_by_name (evax_section_flags, sname, section->_raw_size);
825
        }
826
      _bfd_vms_output_short (abfd, new_flags);
827
      _bfd_vms_output_long (abfd, section->_raw_size);
828
      _bfd_vms_output_counted (abfd, sname);
829
      _bfd_vms_output_flush (abfd);
830
 
831
      last_index = section->index;
832
      section = section->next;
833
    }
834
 
835
  /* output symbols  */
836
 
837
#if VMS_DEBUG
838
  vms_debug (3, "%d symbols found\n", abfd->symcount);
839
#endif
840
 
841
  bfd_set_start_address (abfd, (bfd_vma)-1);
842
 
843
  for (symnum = 0; symnum < abfd->symcount; symnum++)
844
    {
845
 
846
      symbol = abfd->outsymbols[symnum];
847
      if (*(symbol->name) == '_')
848
        {
849
          if (strcmp (symbol->name, "__main") == 0)
850
            bfd_set_start_address (abfd, (bfd_vma)symbol->value);
851
        }
852
      old_flags = symbol->flags;
853
 
854
      if (old_flags & BSF_FILE)
855
        continue;
856
 
857
      if (((old_flags & (BSF_GLOBAL|BSF_WEAK)) == 0)     /* not xdef */
858
          && (!bfd_is_und_section (symbol->section)))   /* and not xref */
859
        continue;                                       /* dont output */
860
 
861
      /* 13 bytes egsd, max 64 chars name -> should be 77 bytes  */
862
 
863
      if (_bfd_vms_output_check (abfd, 80) < 0)
864
        {
865
          _bfd_vms_output_pop (abfd);
866
          _bfd_vms_output_end (abfd);
867
          _bfd_vms_output_begin (abfd, EOBJ_S_C_EGSD, -1);
868
          _bfd_vms_output_long (abfd, 0);
869
          _bfd_vms_output_push (abfd);          /* prepare output for subrecords */
870
        }
871
 
872
      _bfd_vms_output_begin (abfd, EGSD_S_C_SYM, -1);
873
 
874
      _bfd_vms_output_short (abfd, 0);                   /* data type, alignment */
875
 
876
      new_flags = 0;
877
 
878
      if (old_flags & BSF_WEAK)
879
        new_flags |= EGSY_S_V_WEAK;
880
      if (bfd_is_com_section (symbol->section))         /* .comm  */
881
        new_flags |= (EGSY_S_V_WEAK|EGSY_S_V_COMM);
882
 
883
      if (old_flags & BSF_FUNCTION)
884
        {
885
          new_flags |= EGSY_S_V_NORM;
886
          new_flags |= EGSY_S_V_REL;
887
        }
888
      if (old_flags & (BSF_GLOBAL|BSF_WEAK))
889
        {
890
          new_flags |= EGSY_S_V_DEF;
891
          if (!bfd_is_abs_section (symbol->section))
892
            new_flags |= EGSY_S_V_REL;
893
        }
894
      _bfd_vms_output_short (abfd, new_flags);
895
 
896
      if (old_flags & (BSF_GLOBAL|BSF_WEAK))            /* symbol definition */
897
        {
898
          if (old_flags & BSF_FUNCTION)
899
            {
900
              _bfd_vms_output_quad (abfd, symbol->value);
901
              _bfd_vms_output_quad (abfd,
902
                                     ((asymbol *)(symbol->udata.p))->value);
903
              _bfd_vms_output_long (abfd,
904
                                     (((asymbol *)(symbol->udata.p))
905
                                      ->section->index));
906
              _bfd_vms_output_long (abfd, symbol->section->index);
907
            }
908
          else
909
            {
910
              _bfd_vms_output_quad (abfd, symbol->value);       /* L_VALUE */
911
              _bfd_vms_output_quad (abfd, 0);                    /* L_CODE_ADDRESS */
912
              _bfd_vms_output_long (abfd, 0);                    /* L_CA_PSINDX */
913
              _bfd_vms_output_long (abfd, symbol->section->index);/* L_PSINDX */
914
            }
915
        }
916
      _bfd_vms_output_counted (abfd, _bfd_vms_length_hash_symbol (abfd, symbol->name, EOBJ_S_C_SYMSIZ));
917
 
918
      _bfd_vms_output_flush (abfd);
919
 
920
    }
921
 
922
  _bfd_vms_output_alignment (abfd, 8);
923
  _bfd_vms_output_pop (abfd);
924
  _bfd_vms_output_end (abfd);
925
 
926
  return 0;
927
}

powered by: WebSVN 2.1.0

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