OSDN Git Service

PR 10980
[pf3gnuchains/pf3gnuchains3x.git] / bfd / vms-gsd.c
1 /* 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, 2009 Free Software Foundation, Inc.
5
6    GSD record handling functions
7    EGSD record handling functions
8
9    Go and read the openVMS linker manual (esp. appendix B)
10    if you don't know what's going on here :-)
11
12    Written by Klaus K"ampf (kkaempf@rmi.de)
13
14    This program is free software; you can redistribute it and/or modify
15    it under the terms of the GNU General Public License as published by
16    the Free Software Foundation; either version 3 of the License, or
17    (at your option) any later version.
18
19    This program is distributed in the hope that it will be useful,
20    but WITHOUT ANY WARRANTY; without even the implied warranty of
21    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22    GNU General Public License for more details.
23
24    You should have received a copy of the GNU General Public License
25    along with this program; if not, write to the Free Software
26    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
27    MA 02110-1301, USA.  */
28
29 #include "sysdep.h"
30 #include "bfd.h"
31 #include "bfdlink.h"
32 #include "libbfd.h"
33
34 #include "vms.h"
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_LITERALS_NAME      "$LITERALS"
53 #define EVAX_COMMON_NAME        "$COMMON$"
54 #define EVAX_LOCAL_NAME         "$LOCAL$"
55
56 struct sec_flags_struct
57 {
58   char *name;                   /* Name of section.  */
59   int vflags_always;
60   flagword flags_always;        /* Flags we set always.  */
61   int vflags_hassize;
62   flagword flags_hassize;       /* Flags we set if the section has a size > 0.  */
63 };
64
65 /* These flags are deccrtl/vaxcrtl (openVMS 6.2 VAX) compatible.  */
66
67 static struct sec_flags_struct vax_section_flags[] =
68   {
69     { VAX_CODE_NAME,
70       (GPS_S_M_PIC | GPS_S_M_REL | GPS_S_M_SHR | GPS_S_M_EXE | GPS_S_M_RD),
71       (SEC_CODE),
72       (GPS_S_M_PIC | GPS_S_M_REL | GPS_S_M_SHR | GPS_S_M_EXE | GPS_S_M_RD),
73       (SEC_IN_MEMORY | SEC_CODE | SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD) },
74     { VAX_DATA_NAME,
75       (GPS_S_M_PIC | GPS_S_M_REL | GPS_S_M_RD | GPS_S_M_WRT),
76       (SEC_DATA),
77       (GPS_S_M_PIC | GPS_S_M_REL | GPS_S_M_RD | GPS_S_M_WRT),
78       (SEC_IN_MEMORY | SEC_DATA | SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD) },
79     { VAX_ADDRESS_DATA_NAME,
80       (GPS_S_M_PIC | GPS_S_M_REL | GPS_S_M_RD),
81       (SEC_DATA | SEC_READONLY),
82       (GPS_S_M_PIC | GPS_S_M_REL | GPS_S_M_RD),
83       (SEC_IN_MEMORY | SEC_DATA | SEC_HAS_CONTENTS | SEC_ALLOC | SEC_READONLY | SEC_LOAD) },
84     { NULL,
85       (GPS_S_M_PIC | GPS_S_M_OVR | GPS_S_M_REL | GPS_S_M_GBL | GPS_S_M_RD | GPS_S_M_WRT),
86       (SEC_DATA),
87       (GPS_S_M_PIC | GPS_S_M_OVR | GPS_S_M_REL | GPS_S_M_GBL | GPS_S_M_RD | GPS_S_M_WRT),
88       (SEC_IN_MEMORY | SEC_DATA | SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD) }
89   };
90
91 /* These flags are deccrtl/vaxcrtl (openVMS 6.2 Alpha) compatible.  */
92
93 static struct sec_flags_struct evax_section_flags[] =
94   {
95     { EVAX_ABS_NAME,
96       (EGPS_S_V_SHR),
97       (SEC_DATA),
98       (EGPS_S_V_SHR),
99       (SEC_IN_MEMORY | SEC_DATA | SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD) },
100     { EVAX_CODE_NAME,
101       (EGPS_S_V_PIC | EGPS_S_V_REL | EGPS_S_V_SHR | EGPS_S_V_EXE),
102       (SEC_CODE),
103       (EGPS_S_V_PIC | EGPS_S_V_REL | EGPS_S_V_SHR | EGPS_S_V_EXE),
104       (SEC_IN_MEMORY | SEC_CODE | SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD) },
105     { EVAX_LITERAL_NAME,
106       (EGPS_S_V_PIC | EGPS_S_V_REL | EGPS_S_V_SHR | EGPS_S_V_RD | EGPS_S_V_NOMOD),
107       (SEC_DATA | SEC_READONLY),
108       (EGPS_S_V_PIC | EGPS_S_V_REL | EGPS_S_V_SHR | EGPS_S_V_RD),
109       (SEC_IN_MEMORY | SEC_DATA | SEC_HAS_CONTENTS | SEC_ALLOC | SEC_READONLY | SEC_LOAD) },
110     { EVAX_LINK_NAME,
111       (EGPS_S_V_REL | EGPS_S_V_RD),
112       (SEC_DATA | SEC_READONLY),
113       (EGPS_S_V_REL | EGPS_S_V_RD),
114       (SEC_IN_MEMORY | SEC_DATA | SEC_HAS_CONTENTS | SEC_ALLOC | SEC_READONLY | SEC_LOAD) },
115     { EVAX_DATA_NAME,
116       (EGPS_S_V_REL | EGPS_S_V_RD | EGPS_S_V_WRT | EGPS_S_V_NOMOD),
117       (SEC_DATA),
118       (EGPS_S_V_REL | EGPS_S_V_RD | EGPS_S_V_WRT),
119       (SEC_IN_MEMORY | SEC_DATA | SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD) },
120     { EVAX_BSS_NAME,
121       (EGPS_S_V_REL | EGPS_S_V_RD | EGPS_S_V_WRT | EGPS_S_V_NOMOD),
122       (SEC_NO_FLAGS),
123       (EGPS_S_V_REL | EGPS_S_V_RD | EGPS_S_V_WRT | EGPS_S_V_NOMOD),
124       (SEC_IN_MEMORY | SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD) },
125     { EVAX_READONLYADDR_NAME,
126       (EGPS_S_V_PIC | EGPS_S_V_REL | EGPS_S_V_RD),
127       (SEC_DATA | SEC_READONLY),
128       (EGPS_S_V_PIC | EGPS_S_V_REL | EGPS_S_V_RD),
129       (SEC_IN_MEMORY | SEC_DATA | SEC_HAS_CONTENTS | SEC_ALLOC | SEC_READONLY | SEC_LOAD) },
130     { EVAX_READONLY_NAME,
131       (EGPS_S_V_PIC | EGPS_S_V_REL | EGPS_S_V_SHR | EGPS_S_V_RD | EGPS_S_V_NOMOD),
132       (SEC_DATA | SEC_READONLY),
133       (EGPS_S_V_PIC | EGPS_S_V_REL | EGPS_S_V_SHR | EGPS_S_V_RD),
134       (SEC_IN_MEMORY | SEC_DATA | SEC_HAS_CONTENTS | SEC_ALLOC | SEC_READONLY | SEC_LOAD) },
135     { EVAX_LOCAL_NAME,
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     { EVAX_LITERALS_NAME,
141       (EGPS_S_V_PIC | EGPS_S_V_OVR),
142       (SEC_DATA | SEC_READONLY),
143       (EGPS_S_V_PIC | EGPS_S_V_OVR),
144       (SEC_IN_MEMORY | SEC_DATA | SEC_HAS_CONTENTS | SEC_ALLOC | SEC_READONLY | SEC_LOAD) },
145     { NULL,
146       (EGPS_S_V_REL | EGPS_S_V_RD | EGPS_S_V_WRT),
147       (SEC_DATA),
148       (EGPS_S_V_REL | EGPS_S_V_RD | EGPS_S_V_WRT),
149       (SEC_IN_MEMORY | SEC_DATA | SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD) }
150   };
151
152 /* Retrieve bfd section flags by name and size.  */
153
154 static flagword
155 vms_secflag_by_name (bfd *abfd,
156                      struct sec_flags_struct *section_flags,
157                      char *name,
158                      int hassize)
159 {
160   int i = 0;
161
162   while (section_flags[i].name != NULL)
163     {
164       if ((PRIV (is_vax)?
165            strcasecmp (name, section_flags[i].name):
166            strcmp (name, section_flags[i].name)) == 0)
167         {
168           if (hassize)
169             return section_flags[i].flags_hassize;
170           else
171             return section_flags[i].flags_always;
172         }
173       i++;
174     }
175   if (hassize)
176     return section_flags[i].flags_hassize;
177   return section_flags[i].flags_always;
178 }
179
180 /* Retrieve vms section flags by name and size.  */
181
182 static flagword
183 vms_esecflag_by_name (struct sec_flags_struct *section_flags,
184                       char *name,
185                       int hassize)
186 {
187   int i = 0;
188
189   while (section_flags[i].name != NULL)
190     {
191       if (strcmp (name, section_flags[i].name) == 0)
192         {
193           if (hassize)
194             return section_flags[i].vflags_hassize;
195           else
196             return section_flags[i].vflags_always;
197         }
198       i++;
199     }
200   if (hassize)
201     return section_flags[i].vflags_hassize;
202   return section_flags[i].vflags_always;
203 }
204
205 #if VMS_DEBUG
206
207 struct flagdescstruct { char *name; flagword value; };
208
209 static const struct flagdescstruct gpsflagdesc[] =
210 {
211   { "PIC", GPS_S_M_PIC },
212   { "LIB", GPS_S_M_LIB },
213   { "OVR", GPS_S_M_OVR },
214   { "REL", GPS_S_M_REL },
215   { "GBL", GPS_S_M_GBL },
216   { "SHR", GPS_S_M_SHR },
217   { "EXE", GPS_S_M_EXE },
218   { "RD",  GPS_S_M_RD },
219   { "WRT", GPS_S_M_WRT },
220   { "VEC", GPS_S_M_VEC },
221   { "NOMOD", EGPS_S_V_NOMOD },
222   { "COM", EGPS_S_V_COM },
223   { NULL, 0 }
224 };
225
226 static const struct flagdescstruct gsyflagdesc[] =
227 {
228   { "WEAK", GSY_S_M_WEAK },
229   { "DEF",  GSY_S_M_DEF },
230   { "UNI",  GSY_S_M_UNI },
231   { "REL",  GSY_S_M_REL },
232   { "COMM", EGSY_S_V_COMM },
233   { "VECEP", EGSY_S_V_VECEP },
234   { "NORM", EGCY_S_V_NORM },
235   { NULL, 0 }
236 };
237
238 static char *flag2str (struct flagdescstruct *, flagword);
239
240 /* Convert flag to printable string.  */
241
242 static char *
243 flag2str (struct flagdescstruct * flagdesc, flagword flags)
244 {
245   static char res[64];
246   int next = 0;
247
248   res[0] = 0;
249   while (flagdesc->name != NULL)
250     {
251       if ((flags & flagdesc->value) != 0)
252         {
253           if (next)
254             strcat (res, ",");
255           else
256             next = 1;
257           strcat (res, flagdesc->name);
258         }
259       flagdesc++;
260     }
261   return res;
262 }
263 #endif
264
265 /* Input routines.  */
266
267 static int register_universal_symbol (bfd *abfd, asymbol *symbol,
268                                       int vms_flags);
269
270 /* Process GSD/EGSD record
271    return 0 on success, -1 on error.  */
272
273 int
274 _bfd_vms_slurp_gsd (bfd * abfd, int objtype)
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         gsd_type = vms_rec[0];
316       else
317         {
318           _bfd_vms_get_header_values (abfd, vms_rec, &gsd_type, &gsd_size);
319           gsd_type += EVAX_OFFSET;
320         }
321
322 #if VMS_DEBUG
323       vms_debug (3, "gsd_type %d\n", gsd_type);
324 #endif
325
326       switch (gsd_type)
327         {
328         case GSD_S_C_PSC:
329           {
330             /* Program section definition.  */
331             asection *old_section = 0;
332
333 #if VMS_DEBUG
334             vms_debug (4, "GSD_S_C_PSC\n");
335 #endif
336             /* If this section isn't a bfd section.  */
337             if (PRIV (is_vax) && (psect_idx < (abfd->section_count - 1)))
338               {
339                 /* Check for temporary section from TIR record.  */
340                 if (psect_idx < PRIV (section_count))
341                   old_section = PRIV (sections)[psect_idx];
342                 else
343                   old_section = 0;
344               }
345
346             name = _bfd_vms_save_counted_string (vms_rec + 8);
347             section = bfd_make_section (abfd, name);
348             if (!section)
349               {
350                 (*_bfd_error_handler) (_("bfd_make_section (%s) failed"),
351                                        name);
352                 return -1;
353               }
354             old_flags = bfd_getl16 (vms_rec + 2);
355             section->size = bfd_getl32 (vms_rec + 4);  /* allocation */
356             new_flags = vms_secflag_by_name (abfd, vax_section_flags, name,
357                                              section->size > 0);
358             if (old_flags & EGPS_S_V_REL)
359               new_flags |= SEC_RELOC;
360             if (old_flags & GPS_S_M_OVR)
361               new_flags |= SEC_IS_COMMON;
362             if (!bfd_set_section_flags (abfd, section, new_flags))
363               {
364                 (*_bfd_error_handler)
365                   (_("bfd_set_section_flags (%s, %x) failed"),
366                    name, new_flags);
367                 return -1;
368               }
369             section->alignment_power = vms_rec[1];
370             align_addr = (1 << section->alignment_power);
371             if ((base_addr % align_addr) != 0)
372               base_addr += (align_addr - (base_addr % align_addr));
373             section->vma = (bfd_vma)base_addr;
374             base_addr += section->size;
375
376             /* Global section is common symbol.  */
377             if (old_flags & GPS_S_M_GBL)
378               {
379                 entry = _bfd_vms_enter_symbol (abfd, name);
380                 if (entry == NULL)
381                   {
382                     bfd_set_error (bfd_error_no_memory);
383                     return -1;
384                   }
385                 symbol = entry->symbol;
386
387                 symbol->value = 0;
388                 symbol->section = section;
389                 symbol->flags = (BSF_GLOBAL | BSF_SECTION_SYM | BSF_OLD_COMMON);
390               }
391
392             /* Copy saved contents if old_section set.  */
393             if (old_section != 0)
394               {
395                 section->contents = old_section->contents;
396                 if (section->size < old_section->size)
397                   {
398                     (*_bfd_error_handler)
399                       (_("Size mismatch section %s=%lx, %s=%lx"),
400                        old_section->name,
401                        (unsigned long) old_section->size,
402                        section->name,
403                        (unsigned long) section->size);
404                     return -1;
405                   }
406                 else if (section->size > old_section->size)
407                   {
408                     section->contents = bfd_realloc (old_section->contents,
409                                                      section->size);
410                     if (section->contents == NULL)
411                       {
412                         bfd_set_error (bfd_error_no_memory);
413                         return -1;
414                       }
415                   }
416               }
417             else
418               {
419                 section->contents = bfd_zmalloc (section->size);
420                 if (section->contents == NULL)
421                   {
422                     bfd_set_error (bfd_error_no_memory);
423                     return -1;
424                   }
425               }
426 #if VMS_DEBUG
427             vms_debug (4, "gsd psc %d (%s, flags %04x=%s) ",
428                        section->index, name, old_flags, flag2str (gpsflagdesc, old_flags));
429             vms_debug (4, "%d bytes at 0x%08lx (mem %p)\n",
430                        section->size, section->vma, section->contents);
431 #endif
432
433             gsd_size = vms_rec[8] + 9;
434
435             psect_idx++;
436           }
437           break;
438
439         case GSD_S_C_EPM:
440         case GSD_S_C_EPMW:
441 #if VMS_DEBUG
442           vms_debug (4, "gsd epm\n");
443 #endif
444           /* Fall through.  */
445         case GSD_S_C_SYM:
446         case GSD_S_C_SYMW:
447           {
448             int name_offset = 0, value_offset = 0;
449
450             /* Symbol specification (definition or reference).  */
451 #if VMS_DEBUG
452             vms_debug (4, "GSD_S_C_SYM(W)\n");
453 #endif
454             old_flags = bfd_getl16 (vms_rec + 2);
455             new_flags = BSF_NO_FLAGS;
456
457             if (old_flags & GSY_S_M_WEAK)
458               new_flags |= BSF_WEAK;
459
460             switch (gsd_type)
461               {
462               case GSD_S_C_EPM:
463                 name_offset = 11;
464                 value_offset = 5;
465                 new_flags |= BSF_FUNCTION;
466                 break;
467               case GSD_S_C_EPMW:
468                 name_offset = 12;
469                 value_offset = 6;
470                 new_flags |= BSF_FUNCTION;
471                 break;
472               case GSD_S_C_SYM:
473                 if (old_flags & GSY_S_M_DEF)    /* Symbol definition.  */
474                   name_offset = 9;
475                 else
476                   name_offset = 4;
477                 value_offset = 5;
478                 break;
479               case GSD_S_C_SYMW:
480                 if (old_flags & GSY_S_M_DEF)    /* Symbol definition.  */
481                   name_offset = 10;
482                 else
483                   name_offset = 5;
484                 value_offset = 6;
485                 break;
486               }
487
488             /* Save symbol in vms_symbol_table.  */
489             entry = _bfd_vms_enter_symbol
490               (abfd, _bfd_vms_save_counted_string (vms_rec + name_offset));
491             if (entry == NULL)
492               {
493                 bfd_set_error (bfd_error_no_memory);
494                 return -1;
495               }
496             symbol = entry->symbol;
497
498             if (old_flags & GSY_S_M_DEF)
499               {
500                 /* Symbol definition.  */
501                 int psect;
502
503                 symbol->value = bfd_getl32 (vms_rec + value_offset);
504                 if ((gsd_type == GSD_S_C_SYMW)
505                     || (gsd_type == GSD_S_C_EPMW))
506                   psect = bfd_getl16 (vms_rec + value_offset - 2);
507                 else
508                   psect = vms_rec[value_offset-1];
509
510                 symbol->section = (asection *)(unsigned long)psect;
511 #if VMS_DEBUG
512                 vms_debug (4, "gsd sym def #%d (%s, %ld, %04x=%s)\n", abfd->symcount,
513                           symbol->name, (long)symbol->section, old_flags, flag2str(gsyflagdesc, old_flags));
514 #endif
515               }
516             else
517               {
518                 /* Symbol reference.  */
519 #if VMS_DEBUG
520                 vms_debug (4, "gsd sym ref #%d (%s, %04x=%s)\n", abfd->symcount,
521                            symbol->name, old_flags, flag2str (gsyflagdesc, old_flags));
522 #endif
523                 symbol->section = (asection *)(unsigned long)-1;
524               }
525
526             gsd_size = vms_rec[name_offset] + name_offset + 1;
527             symbol->flags = new_flags;
528           }
529
530           break;
531
532         case GSD_S_C_PRO:
533         case GSD_S_C_PROW:
534 #if VMS_DEBUG
535           vms_debug (4, "gsd pro\n");
536 #endif
537           break;
538         case GSD_S_C_IDC:
539 #if VMS_DEBUG
540           vms_debug (4, "gsd idc\n");
541 #endif
542           break;
543         case GSD_S_C_ENV:
544 #if VMS_DEBUG
545           vms_debug (4, "gsd env\n");
546 #endif
547           break;
548         case GSD_S_C_LSY:
549 #if VMS_DEBUG
550           vms_debug (4, "gsd lsy\n");
551 #endif
552           break;
553         case GSD_S_C_LEPM:
554 #if VMS_DEBUG
555           vms_debug (4, "gsd lepm\n");
556 #endif
557           break;
558         case GSD_S_C_LPRO:
559 #if VMS_DEBUG
560           vms_debug (4, "gsd lpro\n");
561 #endif
562           break;
563         case GSD_S_C_SPSC:
564 #if VMS_DEBUG
565           vms_debug (4, "gsd spsc\n");
566 #endif
567           break;
568         case GSD_S_C_SYMV:
569 #if VMS_DEBUG
570           vms_debug (4, "gsd symv\n");
571 #endif
572           break;
573         case GSD_S_C_EPMV:
574 #if VMS_DEBUG
575           vms_debug (4, "gsd epmv\n");
576 #endif
577           break;
578         case GSD_S_C_PROV:
579 #if VMS_DEBUG
580           vms_debug (4, "gsd prov\n");
581 #endif
582           break;
583
584         case EGSD_S_C_PSC + EVAX_OFFSET:
585           {
586             /* Program section definition.  */
587             name = _bfd_vms_save_counted_string (vms_rec + EGPS_S_B_NAMLNG);
588             section = bfd_make_section (abfd, name);
589             if (!section)
590               return -1;
591             old_flags = bfd_getl16 (vms_rec + EGPS_S_W_FLAGS);
592             section->size = bfd_getl32 (vms_rec + EGPS_S_L_ALLOC);
593             new_flags = vms_secflag_by_name (abfd, evax_section_flags, name,
594                                              section->size > 0);
595             if (old_flags & EGPS_S_V_REL)
596               new_flags |= SEC_RELOC;
597             if (!bfd_set_section_flags (abfd, section, new_flags))
598               return -1;
599             section->alignment_power = vms_rec[EGPS_S_B_ALIGN];
600             align_addr = (1 << section->alignment_power);
601             if ((base_addr % align_addr) != 0)
602               base_addr += (align_addr - (base_addr % align_addr));
603             section->vma = (bfd_vma)base_addr;
604             base_addr += section->size;
605             section->contents = bfd_zmalloc (section->size);
606             if (section->contents == NULL)
607               return -1;
608             section->filepos = (unsigned int)-1;
609 #if VMS_DEBUG
610             vms_debug (4, "EGSD P-section %d (%s, flags %04x=%s) ",
611                        section->index, name, old_flags, flag2str(gpsflagdesc, old_flags));
612             vms_debug (4, "%d bytes at 0x%08lx (mem %p)\n",
613                        section->size, section->vma, section->contents);
614 #endif
615           }
616           break;
617
618         case EGSD_S_C_SYM + EVAX_OFFSET:
619           {
620             /* Global symbol specification (definition or reference).  */
621             symbol = bfd_make_empty_symbol (abfd);
622             if (symbol == 0)
623               return -1;
624
625             old_flags = bfd_getl16 (vms_rec + EGSY_S_W_FLAGS);
626             new_flags = BSF_NO_FLAGS;
627
628             if (old_flags & EGSY_S_V_WEAK)
629               new_flags |= BSF_WEAK;
630
631             if (old_flags & EGSY_S_V_DEF)
632               {
633                 /* Symbol definition.  */
634                 if (old_flags & EGSY_S_V_NORM)
635                   new_flags |= BSF_FUNCTION;
636                 symbol->name =
637                   _bfd_vms_save_counted_string (vms_rec + ESDF_S_B_NAMLNG);
638                 symbol->value = bfd_getl64 (vms_rec + ESDF_S_L_VALUE);
639                 symbol->section =
640                   (asection *)(unsigned long) bfd_getl32 (vms_rec + ESDF_S_L_PSINDX);
641 #if VMS_DEBUG
642                 vms_debug (4, "EGSD sym def #%d (%s, %ld, %04x=%s)\n",
643                            abfd->symcount, symbol->name, (long)symbol->section,
644                            old_flags, flag2str (gsyflagdesc, old_flags));
645 #endif
646               }
647             else
648               {
649                 /* Symbol reference.  */
650                 symbol->name =
651                   _bfd_vms_save_counted_string (vms_rec + ESRF_S_B_NAMLNG);
652 #if VMS_DEBUG
653                 vms_debug (4, "EGSD sym ref #%d (%s, %04x=%s)\n",
654                            abfd->symcount, symbol->name, old_flags,
655                            flag2str (gsyflagdesc, old_flags));
656 #endif
657                 symbol->section = (asection *)(unsigned long)-1;
658               }
659
660             symbol->flags = new_flags;
661
662             /* Register symbol in VMS symbol table.  */
663             entry = (vms_symbol_entry *) bfd_hash_lookup
664               (PRIV (vms_symbol_table), symbol->name, TRUE, FALSE);
665
666             if (entry == NULL)
667               {
668                 bfd_set_error (bfd_error_no_memory);
669                 return -1;
670               }
671
672             if (entry->symbol != NULL)
673               {
674                 /* FIXME ?, DEC C generates this.  */
675 #if VMS_DEBUG
676                 vms_debug (4, "EGSD_S_C_SYM: duplicate \"%s\"\n", symbol->name);
677 #endif
678               }
679             else
680               {
681                 entry->symbol = symbol;
682                 PRIV (gsd_sym_count)++;
683                 abfd->symcount++;
684               }
685           }
686           break;
687
688         case EGSD_S_C_SYMG + EVAX_OFFSET:
689           {
690             /* Universal symbol specification (definition).  */
691             symbol = bfd_make_empty_symbol (abfd);
692             if (symbol == 0)
693               return -1;
694
695             old_flags = bfd_getl16 (vms_rec + EGST_S_W_FLAGS);
696             new_flags = BSF_NO_FLAGS;
697
698             if (old_flags & EGSY_S_V_WEAK)
699               new_flags |= BSF_WEAK;
700
701             if (old_flags & EGSY_S_V_DEF) /* symbol definition */
702               {
703                 if (old_flags & EGSY_S_V_NORM)
704                   new_flags |= BSF_FUNCTION;
705
706                 symbol->name =
707                   _bfd_vms_save_counted_string (vms_rec + EGST_S_B_NAMLNG);
708
709                 /* For BSF_FUNCTION symbols, the entry point is in LP_1
710                    and the descriptor in LP_2.  For other symbols, the
711                    unique value is in LP_2.  */
712                 symbol->value = bfd_getl64 (vms_rec + EGST_S_Q_LP_2);
713
714                 /* Adding this offset is necessary in order for GDB to
715                    read the DWARF-2 debug info from shared libraries.  */
716                 if (abfd->flags & DYNAMIC
717                     && strstr (symbol->name, "$DWARF2.DEBUG") != 0)
718                   symbol->value += PRIV (symvva);
719               }
720             else /* symbol reference */
721               (*_bfd_error_handler) ("Invalid EGST reference");
722
723             symbol->flags = new_flags;
724
725             if (register_universal_symbol (abfd, symbol, old_flags) < 0)
726               return -1;
727
728             /* Make a second symbol for the entry point.  */
729             if (symbol->flags & BSF_FUNCTION)
730               {
731                 asymbol *en_sym;
732
733                 name = bfd_alloc (abfd, strlen (symbol->name) + 5);
734
735                 en_sym = bfd_make_empty_symbol (abfd);
736                 if (en_sym == 0)
737                   return -1;
738
739                 strcpy (name, symbol->name);
740                 strcat (name, "..en");
741
742                 en_sym->name = name;
743                 en_sym->value = bfd_getl64 (vms_rec + EGST_S_Q_LP_1);
744
745                 if (register_universal_symbol (abfd, en_sym, old_flags) < 0)
746                   return -1;
747               }
748           }
749           break;
750
751         case EGSD_S_C_IDC + EVAX_OFFSET:
752           break;
753
754         default:
755           (*_bfd_error_handler) (_("Unknown GSD/EGSD subtype %d"), gsd_type);
756           bfd_set_error (bfd_error_bad_value);
757           return -1;
758         }
759
760       PRIV (rec_size) -= gsd_size;
761       PRIV (vms_rec) += gsd_size;
762     }
763
764   if (abfd->symcount > 0)
765     abfd->flags |= HAS_SYMS;
766
767   return 0;
768 }
769
770 /* Register a universal symbol in the VMS symbol table.  */
771
772 static int
773 register_universal_symbol (bfd *abfd, asymbol *symbol, int vms_flags)
774 {
775   bfd_vma sbase = 0;
776   asection *s, *sec = NULL;
777   vms_symbol_entry *entry;
778
779   /* A universal symbol is by definition global...  */
780   symbol->flags |= BSF_GLOBAL;
781
782   /* ...and dynamic in shared libraries.  */
783   if (abfd->flags & DYNAMIC)
784     symbol->flags |= BSF_DYNAMIC;
785
786   /* Find containing section.  */
787   for (s = abfd->sections; s; s = s->next)
788     {
789       if (symbol->value >= s->vma
790           && s->vma > sbase
791           && !(s->flags & SEC_COFF_SHARED_LIBRARY)
792           && (s->size > 0 || !(vms_flags & EGSY_S_V_REL)))
793         {
794           sbase = s->vma;
795           sec = s;
796         }
797     }
798
799   symbol->value -= sbase;
800   symbol->section = sec;
801
802 #if VMS_DEBUG
803   vms_debug (4, "EGST sym def #%d (%s, 0x%llx => 0x%llx, %04x=%s)\n",
804              abfd->symcount, symbol->name, symbol->value + sbase,
805              symbol->value, vms_flags,
806              flag2str(gsyflagdesc, vms_flags));
807 #endif
808
809   entry = (vms_symbol_entry *) bfd_hash_lookup (PRIV (vms_symbol_table),
810                                                 symbol->name,
811                                                 TRUE, FALSE);
812
813   if (entry == NULL)
814     {
815       bfd_set_error (bfd_error_no_memory);
816       return -1;
817     }
818
819   if (entry->symbol) /* FIXME: DEC C generates this */
820     {
821 #if VMS_DEBUG
822       vms_debug (4, "EGSD_S_C_SYMG: duplicate \"%s\"\n", symbol->name);
823 #endif
824     }
825   else
826     {
827       entry->symbol = symbol;
828       PRIV (gsd_sym_count)++;
829       abfd->symcount++;
830     }
831
832   return 0;
833 }
834
835 /* Set section VMS flags.  */
836
837 void
838 bfd_vms_set_section_flags (bfd *abfd ATTRIBUTE_UNUSED,
839                            asection *sec, flagword flags)
840 {
841   vms_section_data (sec)->vflags = flags;
842 }
843
844 /* Write section and symbol directory of bfd abfd.  */
845
846 int
847 _bfd_vms_write_gsd (bfd *abfd, int objtype ATTRIBUTE_UNUSED)
848 {
849   asection *section;
850   asymbol *symbol;
851   unsigned int symnum;
852   int last_index = -1;
853   char dummy_name[10];
854   char *sname;
855   flagword new_flags, old_flags;
856   int abs_section_index = 0;
857
858 #if VMS_DEBUG
859   vms_debug (2, "vms_write_gsd (%p, %d)\n", abfd, objtype);
860 #endif
861
862   /* Output sections.  */
863   section = abfd->sections;
864 #if VMS_DEBUG
865   vms_debug (3, "%d sections found\n", abfd->section_count);
866 #endif
867
868   /* Egsd is quadword aligned.  */
869   _bfd_vms_output_alignment (abfd, 8);
870
871   _bfd_vms_output_begin (abfd, EOBJ_S_C_EGSD, -1);
872   _bfd_vms_output_long (abfd, 0);
873   /* Prepare output for subrecords.  */
874   _bfd_vms_output_push (abfd);
875
876   while (section != 0)
877     {
878 #if VMS_DEBUG
879       vms_debug (3, "Section #%d %s, %d bytes\n", section->index, section->name, (int)section->size);
880 #endif
881
882       /* Don't write out the VMS debug info section since it is in the
883          ETBT and EDBG sections in etir. */
884       if (!strcmp (section->name, ".vmsdebug"))
885         goto done;
886
887       /* 13 bytes egsd, max 31 chars name -> should be 44 bytes.  */
888       if (_bfd_vms_output_check (abfd, 64) < 0)
889         {
890           _bfd_vms_output_pop (abfd);
891           _bfd_vms_output_end (abfd);
892           _bfd_vms_output_begin (abfd, EOBJ_S_C_EGSD, -1);
893           _bfd_vms_output_long (abfd, 0);
894           /* Prepare output for subrecords.  */
895           _bfd_vms_output_push (abfd);
896         }
897
898       /* Create dummy sections to keep consecutive indices.  */
899       while (section->index - last_index > 1)
900         {
901 #if VMS_DEBUG
902           vms_debug (3, "index %d, last %d\n", section->index, last_index);
903 #endif
904           _bfd_vms_output_begin (abfd, EGSD_S_C_PSC, -1);
905           _bfd_vms_output_short (abfd, 0);
906           _bfd_vms_output_short (abfd, 0);
907           _bfd_vms_output_long (abfd, 0);
908           sprintf (dummy_name, ".DUMMY%02d", last_index);
909           _bfd_vms_output_counted (abfd, dummy_name);
910           _bfd_vms_output_flush (abfd);
911           last_index++;
912         }
913
914       /* Don't know if this is necessary for the linker but for now it keeps
915          vms_slurp_gsd happy  */
916       sname = (char *)section->name;
917       if (*sname == '.')
918         {
919           sname++;
920           if ((*sname == 't') && (strcmp (sname, "text") == 0))
921             sname = PRIV (is_vax)?VAX_CODE_NAME:EVAX_CODE_NAME;
922           else if ((*sname == 'd') && (strcmp (sname, "data") == 0))
923             sname = PRIV (is_vax)?VAX_DATA_NAME:EVAX_DATA_NAME;
924           else if ((*sname == 'b') && (strcmp (sname, "bss") == 0))
925             sname = EVAX_BSS_NAME;
926           else if ((*sname == 'l') && (strcmp (sname, "link") == 0))
927             sname = EVAX_LINK_NAME;
928           else if ((*sname == 'r') && (strcmp (sname, "rdata") == 0))
929             sname = EVAX_READONLY_NAME;
930           else if ((*sname == 'l') && (strcmp (sname, "literal") == 0))
931             sname = EVAX_LITERAL_NAME;
932           else if ((*sname == 'l') && (strcmp (sname, "literals") == 0))
933             {
934               sname = EVAX_LITERALS_NAME;
935               abs_section_index = section->index;
936             }
937           else if ((*sname == 'c') && (strcmp (sname, "comm") == 0))
938             sname = EVAX_COMMON_NAME;
939           else if ((*sname == 'l') && (strcmp (sname, "lcomm") == 0))
940             sname = EVAX_LOCAL_NAME;
941         }
942       else
943         sname = _bfd_vms_length_hash_symbol (abfd, sname, EOBJ_S_C_SECSIZ);
944
945       _bfd_vms_output_begin (abfd, EGSD_S_C_PSC, -1);
946       _bfd_vms_output_short (abfd, section->alignment_power & 0xff);
947
948       if (bfd_is_com_section (section))
949         new_flags = (EGPS_S_V_OVR | EGPS_S_V_REL | EGPS_S_V_GBL | EGPS_S_V_RD
950                      | EGPS_S_V_WRT | EGPS_S_V_NOMOD | EGPS_S_V_COM);
951       else
952         new_flags = vms_esecflag_by_name (evax_section_flags, sname,
953                                           section->size > 0);
954
955       /* Modify them as directed.  */
956       if (section->flags & SEC_READONLY)
957         new_flags &= ~EGPS_S_V_WRT;
958
959       new_flags |= vms_section_data (section)->vflags & 0xffff;
960       new_flags &=
961         ~((vms_section_data (section)->vflags >> EGPS_S_V_NO_SHIFT) & 0xffff);
962
963 #if VMS_DEBUG
964       vms_debug (3, "sec flags %x\n", section->flags);
965       vms_debug (3, "new_flags %x, _raw_size %d\n", new_flags, section->size);
966 #endif
967
968       _bfd_vms_output_short (abfd, new_flags);
969       _bfd_vms_output_long (abfd, (unsigned long) section->size);
970       _bfd_vms_output_counted (abfd, sname);
971       _bfd_vms_output_flush (abfd);
972
973       last_index = section->index;
974 done:
975       section = section->next;
976     }
977
978   /* Output symbols.  */
979 #if VMS_DEBUG
980   vms_debug (3, "%d symbols found\n", abfd->symcount);
981 #endif
982
983   bfd_set_start_address (abfd, (bfd_vma) -1);
984
985   for (symnum = 0; symnum < abfd->symcount; symnum++)
986     {
987       char *hash;
988
989       symbol = abfd->outsymbols[symnum];
990       if (*(symbol->name) == '_')
991         {
992           if (strcmp (symbol->name, "__main") == 0)
993             bfd_set_start_address (abfd, (bfd_vma)symbol->value);
994         }
995       old_flags = symbol->flags;
996
997       if (old_flags & BSF_FILE)
998         continue;
999
1000       if ((old_flags & BSF_GLOBAL) == 0            /* Not xdef...  */
1001           && !bfd_is_und_section (symbol->section) /* and not xref... */
1002           && !((old_flags & BSF_SECTION_SYM) != 0  /* and not LIB$INITIALIZE.  */
1003                && strcmp (symbol->section->name, "LIB$INITIALIZE") == 0))
1004         continue;
1005
1006       /* 13 bytes egsd, max 64 chars name -> should be 77 bytes.  */
1007       if (_bfd_vms_output_check (abfd, 80) < 0)
1008         {
1009           _bfd_vms_output_pop (abfd);
1010           _bfd_vms_output_end (abfd);
1011           _bfd_vms_output_begin (abfd, EOBJ_S_C_EGSD, -1);
1012           _bfd_vms_output_long (abfd, 0);
1013           /* Prepare output for subrecords.  */
1014           _bfd_vms_output_push (abfd);
1015         }
1016
1017       _bfd_vms_output_begin (abfd, EGSD_S_C_SYM, -1);
1018
1019       /* Data type, alignment.  */
1020       _bfd_vms_output_short (abfd, 0);
1021
1022       new_flags = 0;
1023
1024       if (old_flags & BSF_WEAK)
1025         new_flags |= EGSY_S_V_WEAK;
1026       if (bfd_is_com_section (symbol->section))         /* .comm  */
1027         new_flags |= (EGSY_S_V_WEAK | EGSY_S_V_COMM);
1028
1029       if (old_flags & BSF_FUNCTION)
1030         {
1031           new_flags |= EGSY_S_V_NORM;
1032           new_flags |= EGSY_S_V_REL;
1033         }
1034       if (old_flags & BSF_GLOBAL)
1035         {
1036           new_flags |= EGSY_S_V_DEF;
1037           if (!bfd_is_abs_section (symbol->section))
1038             new_flags |= EGSY_S_V_REL;
1039         }
1040       _bfd_vms_output_short (abfd, new_flags);
1041
1042       if (old_flags & BSF_GLOBAL)
1043         {
1044           /* Symbol definition.  */
1045           uquad code_address = 0;
1046           unsigned long ca_psindx = 0;
1047           unsigned long psindx;
1048
1049           if ((old_flags & BSF_FUNCTION) && symbol->udata.p != NULL)
1050             {
1051               asymbol *sym;
1052
1053               if (bfd_get_flavour (abfd) == bfd_target_evax_flavour)
1054                 sym = ((struct evax_private_udata_struct *)symbol->udata.p)->enbsym;
1055               else
1056                 sym = (asymbol *)symbol->udata.p;
1057               code_address = sym->value;
1058               ca_psindx = sym->section->index;
1059             }
1060           if (bfd_is_abs_section (symbol->section))
1061             psindx = abs_section_index;
1062           else
1063             psindx = symbol->section->index;
1064
1065           _bfd_vms_output_quad (abfd, symbol->value);
1066           _bfd_vms_output_quad (abfd, code_address);
1067           _bfd_vms_output_long (abfd, ca_psindx);
1068           _bfd_vms_output_long (abfd, psindx);
1069         }
1070       hash = _bfd_vms_length_hash_symbol (abfd, symbol->name, EOBJ_S_C_SYMSIZ);
1071       _bfd_vms_output_counted (abfd, hash);
1072
1073       _bfd_vms_output_flush (abfd);
1074
1075     }
1076
1077   _bfd_vms_output_alignment (abfd, 8);
1078   _bfd_vms_output_pop (abfd);
1079   _bfd_vms_output_end (abfd);
1080
1081   return 0;
1082 }