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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-old/] [binutils-2.18.50/] [bfd/] [vms-gsd.c] - Blame information for rev 853

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

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

powered by: WebSVN 2.1.0

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