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

Subversion Repositories or1k

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

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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