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