source: branches/libc-0.6/src/binutils/bfd/vms-gsd.c

Last change on this file was 610, checked in by bird, 22 years ago

This commit was generated by cvs2svn to compensate for changes in r609,
which included commits to RCS files with non-trunk default branches.

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