OSDN Git Service

2009-11-19 Tristan Gingold <gingold@adacore.com>
[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                 char *name = bfd_alloc (abfd, strlen (symbol->name) + 5);
733
734                 en_sym = bfd_make_empty_symbol (abfd);
735                 if (en_sym == 0)
736                   return -1;
737
738                 strcpy (name, symbol->name);
739                 strcat (name, "..en");
740
741                 en_sym->name = name;
742                 en_sym->value = bfd_getl64 (vms_rec + EGST_S_Q_LP_1);
743
744                 if (register_universal_symbol (abfd, en_sym, old_flags) < 0)
745                   return -1;
746               }
747           }
748           break;
749
750         case EGSD_S_C_IDC + EVAX_OFFSET:
751           break;
752
753         default:
754           (*_bfd_error_handler) (_("Unknown GSD/EGSD subtype %d"), gsd_type);
755           bfd_set_error (bfd_error_bad_value);
756           return -1;
757         }
758
759       PRIV (rec_size) -= gsd_size;
760       PRIV (vms_rec) += gsd_size;
761     }
762
763   if (abfd->symcount > 0)
764     abfd->flags |= HAS_SYMS;
765
766   return 0;
767 }
768
769 /* Register a universal symbol in the VMS symbol table.  */
770
771 static int
772 register_universal_symbol (bfd *abfd, asymbol *symbol, int vms_flags)
773 {
774   bfd_vma sbase = 0;
775   asection *s, *sec = NULL;
776   vms_symbol_entry *entry;
777
778   /* A universal symbol is by definition global...  */
779   symbol->flags |= BSF_GLOBAL;
780
781   /* ...and dynamic in shared libraries.  */
782   if (abfd->flags & DYNAMIC)
783     symbol->flags |= BSF_DYNAMIC;
784
785   /* Find containing section.  */
786   for (s = abfd->sections; s; s = s->next)
787     {
788       if (symbol->value >= s->vma
789           && s->vma > sbase
790           && !(s->flags & SEC_COFF_SHARED_LIBRARY)
791           && (s->size > 0 || !(vms_flags & EGSY_S_V_REL)))
792         {
793           sbase = s->vma;
794           sec = s;
795         }
796     }
797
798   symbol->value -= sbase;
799   symbol->section = sec;
800
801 #if VMS_DEBUG
802   vms_debug (4, "EGST sym def #%d (%s, 0x%llx => 0x%llx, %04x=%s)\n",
803              abfd->symcount, symbol->name, symbol->value + sbase,
804              symbol->value, vms_flags,
805              flag2str(gsyflagdesc, vms_flags));
806 #endif
807
808   entry = (vms_symbol_entry *) bfd_hash_lookup (PRIV (vms_symbol_table),
809                                                 symbol->name,
810                                                 TRUE, FALSE);
811
812   if (entry == NULL)
813     {
814       bfd_set_error (bfd_error_no_memory);
815       return -1;
816     }
817
818   if (entry->symbol) /* FIXME: DEC C generates this */
819     {
820 #if VMS_DEBUG
821       vms_debug (4, "EGSD_S_C_SYMG: duplicate \"%s\"\n", symbol->name);
822 #endif
823     }
824   else
825     {
826       entry->symbol = symbol;
827       PRIV (gsd_sym_count)++;
828       abfd->symcount++;
829     }
830
831   return 0;
832 }
833
834 /* Set section VMS flags.  */
835
836 void
837 bfd_vms_set_section_flags (bfd *abfd ATTRIBUTE_UNUSED,
838                            asection *sec, flagword flags)
839 {
840   vms_section_data (sec)->vflags = flags;
841 }
842
843 /* Write section and symbol directory of bfd abfd.  */
844
845 int
846 _bfd_vms_write_gsd (bfd *abfd, int objtype ATTRIBUTE_UNUSED)
847 {
848   asection *section;
849   asymbol *symbol;
850   unsigned int symnum;
851   int last_index = -1;
852   char dummy_name[10];
853   char *sname;
854   flagword new_flags, old_flags;
855   int abs_section_index = 0;
856
857 #if VMS_DEBUG
858   vms_debug (2, "vms_write_gsd (%p, %d)\n", abfd, objtype);
859 #endif
860
861   /* Output sections.  */
862   section = abfd->sections;
863 #if VMS_DEBUG
864   vms_debug (3, "%d sections found\n", abfd->section_count);
865 #endif
866
867   /* Egsd is quadword aligned.  */
868   _bfd_vms_output_alignment (abfd, 8);
869
870   _bfd_vms_output_begin (abfd, EOBJ_S_C_EGSD, -1);
871   _bfd_vms_output_long (abfd, 0);
872   /* Prepare output for subrecords.  */
873   _bfd_vms_output_push (abfd);
874
875   while (section != 0)
876     {
877 #if VMS_DEBUG
878       vms_debug (3, "Section #%d %s, %d bytes\n", section->index, section->name, (int)section->size);
879 #endif
880
881       /* Don't write out the VMS debug info section since it is in the
882          ETBT and EDBG sections in etir. */
883       if (!strcmp (section->name, ".vmsdebug"))
884         goto done;
885
886       /* 13 bytes egsd, max 31 chars name -> should be 44 bytes.  */
887       if (_bfd_vms_output_check (abfd, 64) < 0)
888         {
889           _bfd_vms_output_pop (abfd);
890           _bfd_vms_output_end (abfd);
891           _bfd_vms_output_begin (abfd, EOBJ_S_C_EGSD, -1);
892           _bfd_vms_output_long (abfd, 0);
893           /* Prepare output for subrecords.  */
894           _bfd_vms_output_push (abfd);
895         }
896
897       /* Create dummy sections to keep consecutive indices.  */
898       while (section->index - last_index > 1)
899         {
900 #if VMS_DEBUG
901           vms_debug (3, "index %d, last %d\n", section->index, last_index);
902 #endif
903           _bfd_vms_output_begin (abfd, EGSD_S_C_PSC, -1);
904           _bfd_vms_output_short (abfd, 0);
905           _bfd_vms_output_short (abfd, 0);
906           _bfd_vms_output_long (abfd, 0);
907           sprintf (dummy_name, ".DUMMY%02d", last_index);
908           _bfd_vms_output_counted (abfd, dummy_name);
909           _bfd_vms_output_flush (abfd);
910           last_index++;
911         }
912
913       /* Don't know if this is necessary for the linker but for now it keeps
914          vms_slurp_gsd happy  */
915       sname = (char *)section->name;
916       if (*sname == '.')
917         {
918           sname++;
919           if ((*sname == 't') && (strcmp (sname, "text") == 0))
920             sname = PRIV (is_vax)?VAX_CODE_NAME:EVAX_CODE_NAME;
921           else if ((*sname == 'd') && (strcmp (sname, "data") == 0))
922             sname = PRIV (is_vax)?VAX_DATA_NAME:EVAX_DATA_NAME;
923           else if ((*sname == 'b') && (strcmp (sname, "bss") == 0))
924             sname = EVAX_BSS_NAME;
925           else if ((*sname == 'l') && (strcmp (sname, "link") == 0))
926             sname = EVAX_LINK_NAME;
927           else if ((*sname == 'r') && (strcmp (sname, "rdata") == 0))
928             sname = EVAX_READONLY_NAME;
929           else if ((*sname == 'l') && (strcmp (sname, "literal") == 0))
930             sname = EVAX_LITERAL_NAME;
931           else if ((*sname == 'l') && (strcmp (sname, "literals") == 0))
932             {
933               sname = EVAX_LITERALS_NAME;
934               abs_section_index = section->index;
935             }
936           else if ((*sname == 'c') && (strcmp (sname, "comm") == 0))
937             sname = EVAX_COMMON_NAME;
938           else if ((*sname == 'l') && (strcmp (sname, "lcomm") == 0))
939             sname = EVAX_LOCAL_NAME;
940         }
941       else
942         sname = _bfd_vms_length_hash_symbol (abfd, sname, EOBJ_S_C_SECSIZ);
943
944       _bfd_vms_output_begin (abfd, EGSD_S_C_PSC, -1);
945       _bfd_vms_output_short (abfd, section->alignment_power & 0xff);
946
947       if (bfd_is_com_section (section))
948         new_flags = (EGPS_S_V_OVR | EGPS_S_V_REL | EGPS_S_V_GBL | EGPS_S_V_RD
949                      | EGPS_S_V_WRT | EGPS_S_V_NOMOD | EGPS_S_V_COM);
950       else
951         new_flags = vms_esecflag_by_name (evax_section_flags, sname,
952                                           section->size > 0);
953
954       /* Modify them as directed.  */
955       if (section->flags & SEC_READONLY)
956         new_flags &= ~EGPS_S_V_WRT;
957
958       new_flags |= vms_section_data (section)->vflags & 0xffff;
959       new_flags &=
960         ~((vms_section_data (section)->vflags >> EGPS_S_V_NO_SHIFT) & 0xffff);
961
962 #if VMS_DEBUG
963       vms_debug (3, "sec flags %x\n", section->flags);
964       vms_debug (3, "new_flags %x, _raw_size %d\n", new_flags, section->size);
965 #endif
966
967       _bfd_vms_output_short (abfd, new_flags);
968       _bfd_vms_output_long (abfd, (unsigned long) section->size);
969       _bfd_vms_output_counted (abfd, sname);
970       _bfd_vms_output_flush (abfd);
971
972       last_index = section->index;
973 done:
974       section = section->next;
975     }
976
977   /* Output symbols.  */
978 #if VMS_DEBUG
979   vms_debug (3, "%d symbols found\n", abfd->symcount);
980 #endif
981
982   bfd_set_start_address (abfd, (bfd_vma) -1);
983
984   for (symnum = 0; symnum < abfd->symcount; symnum++)
985     {
986       char *hash;
987
988       symbol = abfd->outsymbols[symnum];
989       if (*(symbol->name) == '_')
990         {
991           if (strcmp (symbol->name, "__main") == 0)
992             bfd_set_start_address (abfd, (bfd_vma)symbol->value);
993         }
994       old_flags = symbol->flags;
995
996       if (old_flags & BSF_FILE)
997         continue;
998
999       if ((old_flags & BSF_GLOBAL) == 0            /* Not xdef...  */
1000           && !bfd_is_und_section (symbol->section) /* and not xref... */
1001           && !((old_flags & BSF_SECTION_SYM) != 0  /* and not LIB$INITIALIZE.  */
1002                && strcmp (symbol->section->name, "LIB$INITIALIZE") == 0))
1003         continue;
1004
1005       /* 13 bytes egsd, max 64 chars name -> should be 77 bytes.  */
1006       if (_bfd_vms_output_check (abfd, 80) < 0)
1007         {
1008           _bfd_vms_output_pop (abfd);
1009           _bfd_vms_output_end (abfd);
1010           _bfd_vms_output_begin (abfd, EOBJ_S_C_EGSD, -1);
1011           _bfd_vms_output_long (abfd, 0);
1012           /* Prepare output for subrecords.  */
1013           _bfd_vms_output_push (abfd);
1014         }
1015
1016       _bfd_vms_output_begin (abfd, EGSD_S_C_SYM, -1);
1017
1018       /* Data type, alignment.  */
1019       _bfd_vms_output_short (abfd, 0);
1020
1021       new_flags = 0;
1022
1023       if (old_flags & BSF_WEAK)
1024         new_flags |= EGSY_S_V_WEAK;
1025       if (bfd_is_com_section (symbol->section))         /* .comm  */
1026         new_flags |= (EGSY_S_V_WEAK | EGSY_S_V_COMM);
1027
1028       if (old_flags & BSF_FUNCTION)
1029         {
1030           new_flags |= EGSY_S_V_NORM;
1031           new_flags |= EGSY_S_V_REL;
1032         }
1033       if (old_flags & BSF_GLOBAL)
1034         {
1035           new_flags |= EGSY_S_V_DEF;
1036           if (!bfd_is_abs_section (symbol->section))
1037             new_flags |= EGSY_S_V_REL;
1038         }
1039       _bfd_vms_output_short (abfd, new_flags);
1040
1041       if (old_flags & BSF_GLOBAL)
1042         {
1043           /* Symbol definition.  */
1044           uquad code_address = 0;
1045           unsigned long ca_psindx = 0;
1046           unsigned long psindx;
1047
1048           if ((old_flags & BSF_FUNCTION) && symbol->udata.p != NULL)
1049             {
1050               asymbol *sym;
1051
1052               if (bfd_get_flavour (abfd) == bfd_target_evax_flavour)
1053                 sym = ((struct evax_private_udata_struct *)symbol->udata.p)->enbsym;
1054               else
1055                 sym = (asymbol *)symbol->udata.p;
1056               code_address = sym->value;
1057               ca_psindx = sym->section->index;
1058             }
1059           if (bfd_is_abs_section (symbol->section))
1060             psindx = abs_section_index;
1061           else
1062             psindx = symbol->section->index;
1063
1064           _bfd_vms_output_quad (abfd, symbol->value);
1065           _bfd_vms_output_quad (abfd, code_address);
1066           _bfd_vms_output_long (abfd, ca_psindx);
1067           _bfd_vms_output_long (abfd, psindx);
1068         }
1069       hash = _bfd_vms_length_hash_symbol (abfd, symbol->name, EOBJ_S_C_SYMSIZ);
1070       _bfd_vms_output_counted (abfd, hash);
1071
1072       _bfd_vms_output_flush (abfd);
1073
1074     }
1075
1076   _bfd_vms_output_alignment (abfd, 8);
1077   _bfd_vms_output_pop (abfd);
1078   _bfd_vms_output_end (abfd);
1079
1080   return 0;
1081 }