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