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