1 /* vms-misc.c -- Miscellaneous functions for VAX (openVMS/VAX) and
2 EVAX (openVMS/Alpha) files.
3 Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002
4 Free Software Foundation, Inc.
6 Written by Klaus K"ampf (kkaempf@rmi.de)
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
33 static vms_section
*add_new_contents
PARAMS ((bfd
*, sec_ptr
));
34 static int hash_string
PARAMS ((const char *));
35 static asymbol
*new_symbol
PARAMS ((bfd
*, char *));
37 /*-----------------------------------------------------------------------------*/
41 /* debug function for all vms extensions
42 evaluates environment variable VMS_DEBUG for a
43 numerical value on the first call
44 all error levels below this value are printed
47 1 toplevel bfd calls (functions from the bfd vector)
48 2 functions called by bfd calls
52 level is also identation level. Indentation is performed
58 _bfd_vms_debug (int level
, char *format
, ...)
60 static int min_level
= -1;
61 static FILE *output
= NULL
;
64 int abslvl
= (level
> 0)?level
:-level
;
68 if ((eptr
= getenv("VMS_DEBUG")) != NULL
)
70 min_level
= atoi(eptr
);
78 if (abslvl
> min_level
)
82 fprintf (output
, " ");
83 va_start(args
, format
);
84 vfprintf (output
, format
, args
);
91 #else /* not __STDC__ */
94 _bfd_vms_debug (level
, format
, a1
, a2
, a3
, a4
, a5
, a6
)
97 long a1
; long a2
; long a3
;
98 long a4
; long a5
; long a6
;
100 static int min_level
= -1;
101 static FILE *output
= NULL
;
106 if ((eptr
= getenv("VMS_DEBUG")) != NULL
)
108 min_level
= atoi(eptr
);
116 if (level
> min_level
)
120 fprintf (output
, " ");
121 fprintf (output
, format
, a1
, a2
, a3
, a4
, a5
, a6
);
126 #endif /* __STDC__ */
129 hex dump 'size' bytes starting at 'ptr' */
132 _bfd_hexdump (level
, ptr
, size
, offset
)
138 unsigned char *lptr
= ptr
;
145 vms_debug (level
, "%08lx:", start
);
146 vms_debug (-level
, " %02x", *ptr
++);
151 while ((count
%16) != 0)
153 vms_debug (-level
, " ");
159 vms_debug (-level
, " ");
162 vms_debug (-level
, "%c", (*lptr
< 32)?'.':*lptr
);
165 vms_debug (-level
, "\n");
169 vms_debug (-level
, "\n");
177 These are needed when reading an object file. */
179 /* allocate new vms_hash_entry
180 keep the symbol name and a pointer to the bfd symbol in the table */
182 struct bfd_hash_entry
*
183 _bfd_vms_hash_newfunc (entry
, table
, string
)
184 struct bfd_hash_entry
*entry
;
185 struct bfd_hash_table
*table
;
188 vms_symbol_entry
*ret
;
191 vms_debug (5, "_bfd_vms_hash_newfunc(%p, %p, %s)\n", entry
, table
, string
);
194 if (entry
== (struct bfd_hash_entry
*)NULL
)
196 ret
= (vms_symbol_entry
*)
197 bfd_hash_allocate (table
, sizeof (vms_symbol_entry
));
198 if (ret
== (vms_symbol_entry
*) NULL
)
200 bfd_set_error (bfd_error_no_memory
);
201 return (struct bfd_hash_entry
*)NULL
;
203 entry
= (struct bfd_hash_entry
*) ret
;
206 /* Call the allocation method of the base class. */
208 ret
= (vms_symbol_entry
*) bfd_hash_newfunc (entry
, table
, string
);
210 vms_debug (6, "_bfd_vms_hash_newfunc ret %p\n", ret
);
213 ret
->symbol
= (asymbol
*)NULL
;
215 return (struct bfd_hash_entry
*)ret
;
218 /* object file input functions */
220 /* Return type and length from record header (buf) on Alpha. */
223 _bfd_vms_get_header_values (abfd
, buf
, type
, length
)
224 bfd
*abfd ATTRIBUTE_UNUSED
;
230 *type
= bfd_getl16 (buf
);
233 *length
= bfd_getl16 (buf
);
236 vms_debug (10, "_bfd_vms_get_header_values type %x, length %x\n", (type
?*type
:0), (length
?*length
:0));
242 /* Get next record from object file to vms_buf
243 set PRIV(buf_size) and return it
245 this is a little tricky since it should be portable.
247 the openVMS object file has 'variable length' which means that
248 read() returns data in chunks of (hopefully) correct and expected
249 size. The linker (and other tools on vms) depend on that. Unix doesn't
250 know about 'formatted' files, so reading and writing such an object
251 file in a unix environment is not trivial.
253 With the tool 'file' (available on all vms ftp sites), one
254 can view and change the attributes of a file. Changing from
255 'variable length' to 'fixed length, 512 bytes' reveals the
256 record length at the first 2 bytes of every record. The same
257 happens during the transfer of object files from vms to unix,
258 at least with ucx, dec's implementation of tcp/ip.
260 The vms format repeats the length at bytes 2 & 3 of every record.
262 On the first call (file_format == FF_UNKNOWN) we check if
263 the first and the third byte pair (!) of the record match.
264 If they do it's an object file in an unix environment or with
265 wrong attributes (FF_FOREIGN), else we should be in a vms
266 environment where read() returns the record size (FF_NATIVE).
268 reading is always done in 2 steps.
269 first just the record header is read and the length extracted
271 then the read buffer is adjusted and the remaining bytes are
274 all file i/o is always done on even file positions */
277 _bfd_vms_get_record (abfd
)
280 int test_len
, test_start
, remaining
;
281 unsigned char *vms_buf
;
284 vms_debug (8, "_bfd_vms_get_record\n");
287 /* minimum is 6 bytes on Alpha
288 (2 bytes length, 2 bytes record id, 2 bytes length repeated)
290 on VAX there's no length information in the record
291 so start with OBJ_S_C_MAXRECSIZ */
293 if (PRIV (buf_size
) == 0)
297 PRIV (vms_buf
) = (unsigned char *) malloc (OBJ_S_C_MAXRECSIZ
);
298 PRIV (buf_size
) = OBJ_S_C_MAXRECSIZ
;
299 PRIV (file_format
) = FF_VAX
;
302 PRIV (vms_buf
) = (unsigned char *) malloc (6);
305 vms_buf
= PRIV (vms_buf
);
309 bfd_set_error (bfd_error_no_memory
);
313 switch (PRIV (file_format
))
317 test_len
= 6; /* probe 6 bytes */
318 test_start
= 2; /* where the record starts */
333 /* skip odd alignment byte */
335 if (bfd_tell (abfd
) & 1)
337 if (bfd_bread (PRIV (vms_buf
), (bfd_size_type
) 1, abfd
) != 1)
339 bfd_set_error (bfd_error_file_truncated
);
344 /* read the record header on Alpha. */
347 && (bfd_bread (PRIV (vms_buf
), (bfd_size_type
) test_len
, abfd
)
348 != (bfd_size_type
) test_len
))
350 bfd_set_error (bfd_error_file_truncated
);
354 /* check file format on first call */
356 if (PRIV (file_format
) == FF_UNKNOWN
)
357 { /* record length repeats ? */
358 if ( (vms_buf
[0] == vms_buf
[4])
359 && (vms_buf
[1] == vms_buf
[5]))
361 PRIV (file_format
) = FF_FOREIGN
; /* Y: foreign environment */
366 PRIV (file_format
) = FF_NATIVE
; /* N: native environment */
373 PRIV (rec_length
) = bfd_bread (vms_buf
, (bfd_size_type
) PRIV (buf_size
),
375 if (PRIV (rec_length
) <= 0)
377 bfd_set_error (bfd_error_file_truncated
);
380 PRIV (vms_rec
) = vms_buf
;
384 /* extract vms record length */
386 _bfd_vms_get_header_values (abfd
, vms_buf
+test_start
, NULL
,
389 if (PRIV (rec_length
) <= 0)
391 bfd_set_error (bfd_error_file_truncated
);
395 /* that's what the linker manual says */
397 if (PRIV (rec_length
) > EOBJ_S_C_MAXRECSIZ
)
399 bfd_set_error (bfd_error_file_truncated
);
403 /* adjust the buffer */
405 if (PRIV (rec_length
) > PRIV (buf_size
))
407 PRIV (vms_buf
) = ((unsigned char *)
408 realloc (vms_buf
, (size_t) PRIV (rec_length
)));
409 vms_buf
= PRIV (vms_buf
);
412 bfd_set_error (bfd_error_no_memory
);
415 PRIV (buf_size
) = PRIV (rec_length
);
418 /* read the remaining record */
420 remaining
= PRIV (rec_length
) - test_len
+ test_start
;
423 vms_debug (10, "bfd_bread remaining %d\n", remaining
);
425 if (bfd_bread (vms_buf
+ test_len
, (bfd_size_type
) remaining
, abfd
) !=
426 (bfd_size_type
) remaining
)
428 bfd_set_error (bfd_error_file_truncated
);
431 PRIV (vms_rec
) = vms_buf
+ test_start
;
435 vms_debug (11, "bfd_bread rec_length %d\n", PRIV (rec_length
));
438 return PRIV (rec_length
);
441 /* get next vms record from file
442 update vms_rec and rec_length to new (remaining) values */
445 _bfd_vms_next_record (abfd
)
449 vms_debug (8, "_bfd_vms_next_record (len %d, size %d)\n",
450 PRIV (rec_length
), PRIV (rec_size
));
453 if (PRIV (rec_length
) > 0)
455 PRIV (vms_rec
) += PRIV (rec_size
);
459 if (_bfd_vms_get_record (abfd
) <= 0)
463 if (!PRIV (vms_rec
) || !PRIV (vms_buf
)
464 || PRIV (vms_rec
) >= (PRIV (vms_buf
) + PRIV (buf_size
)))
469 PRIV (rec_type
) = *(PRIV (vms_rec
));
470 PRIV (rec_size
) = PRIV (rec_length
);
474 _bfd_vms_get_header_values (abfd
, PRIV (vms_rec
), &PRIV (rec_type
),
477 PRIV (rec_length
) -= PRIV (rec_size
);
480 vms_debug (8, "_bfd_vms_next_record: rec %p, size %d, length %d, type %d\n",
481 PRIV (vms_rec
), PRIV (rec_size
), PRIV (rec_length
),
485 return PRIV (rec_type
);
488 /* Copy sized string (string with fixed length) to new allocated area
489 size is string length (size of record) */
492 _bfd_vms_save_sized_string (str
, size
)
496 char *newstr
= bfd_malloc ((bfd_size_type
) size
+ 1);
500 strncpy (newstr
, (char *) str
, (size_t) size
);
506 /* Copy counted string (string with length at first byte) to new allocated area
507 ptr points to length byte on entry */
510 _bfd_vms_save_counted_string (ptr
)
515 return _bfd_vms_save_sized_string (ptr
, len
);
518 /* stack routines for vms ETIR commands */
520 /* Push value and section index */
523 _bfd_vms_push (abfd
, val
, psect
)
528 static int last_psect
;
531 vms_debug (4, "<push %016lx(%d) at %d>\n", val
, psect
, PRIV (stackptr
));
537 PRIV (stack
[PRIV (stackptr
)]).value
= val
;
538 PRIV (stack
[PRIV (stackptr
)]).psect
= last_psect
;
540 if (PRIV (stackptr
) >= STACKSIZE
)
542 bfd_set_error (bfd_error_bad_value
);
543 (*_bfd_error_handler
) (_("Stack overflow (%d) in _bfd_vms_push"), PRIV (stackptr
));
549 /* Pop value and section index */
552 _bfd_vms_pop (abfd
, psect
)
558 if (PRIV (stackptr
) == 0)
560 bfd_set_error (bfd_error_bad_value
);
561 (*_bfd_error_handler
) (_("Stack underflow in _bfd_vms_pop"));
565 value
= PRIV (stack
[PRIV (stackptr
)]).value
;
566 if ((psect
!= NULL
) && (PRIV (stack
[PRIV (stackptr
)]).psect
>= 0))
567 *psect
= PRIV (stack
[PRIV (stackptr
)]).psect
;
570 vms_debug (4, "<pop %016lx(%d)>\n", value
, PRIV (stack
[PRIV (stackptr
)]).psect
);
576 /* object file output functions */
578 /* GAS tends to write sections in little chunks (bfd_set_section_contents)
579 which we can't use directly. So we save the little chunks in linked
580 lists (one per section) and write them later. */
582 /* Add a new vms_section structure to vms_section_table
583 - forward chaining - */
586 add_new_contents (abfd
, section
)
590 vms_section
*sptr
, *newptr
;
592 sptr
= PRIV (vms_section_table
)[section
->index
];
596 newptr
= (vms_section
*) bfd_malloc ((bfd_size_type
) sizeof (vms_section
));
597 if (newptr
== (vms_section
*) NULL
)
599 newptr
->contents
= (unsigned char *) bfd_alloc (abfd
, section
->_raw_size
);
600 if (newptr
->contents
== (unsigned char *) NULL
)
603 newptr
->size
= section
->_raw_size
;
605 PRIV (vms_section_table
)[section
->index
] = newptr
;
609 /* Save section data & offset to an vms_section structure
610 vms_section_table[] holds the vms_section chain */
613 _bfd_save_vms_section (abfd
, section
, data
, offset
, count
)
622 if (section
->index
>= VMS_SECTION_COUNT
)
624 bfd_set_error (bfd_error_nonrepresentable_section
);
627 if (count
== (bfd_size_type
)0)
629 sptr
= add_new_contents (abfd
, section
);
632 memcpy (sptr
->contents
+ offset
, data
, (size_t) count
);
637 /* Get vms_section pointer to saved contents for section # index */
640 _bfd_get_vms_section (abfd
, index
)
644 if (index
>= VMS_SECTION_COUNT
)
646 bfd_set_error (bfd_error_nonrepresentable_section
);
649 return PRIV (vms_section_table
)[index
];
652 /* Object output routines */
654 /* Begin new record or record header
655 write 2 bytes rectype
656 write 2 bytes record length (filled in at flush)
657 write 2 bytes header type (ommitted if rechead == -1) */
660 _bfd_vms_output_begin (abfd
, rectype
, rechead
)
666 vms_debug (6, "_bfd_vms_output_begin(type %d, head %d)\n", rectype
,
670 _bfd_vms_output_short (abfd
, (unsigned int) rectype
);
672 /* save current output position to fill in lenght later */
674 if (PRIV (push_level
) > 0)
675 PRIV (length_pos
) = PRIV (output_size
);
678 vms_debug (6, "_bfd_vms_output_begin: length_pos = %d\n",
682 _bfd_vms_output_short (abfd
, 0); /* placeholder for length */
685 _bfd_vms_output_short (abfd
, (unsigned int) rechead
);
690 /* Set record/subrecord alignment */
693 _bfd_vms_output_alignment (abfd
, alignto
)
698 vms_debug (6, "_bfd_vms_output_alignment(%d)\n", alignto
);
701 PRIV (output_alignment
) = alignto
;
705 /* Prepare for subrecord fields */
708 _bfd_vms_output_push (abfd
)
712 vms_debug (6, "vms_output_push(pushed_size = %d)\n", PRIV (output_size
));
716 PRIV (pushed_size
) = PRIV (output_size
);
720 /* End of subrecord fields */
723 _bfd_vms_output_pop (abfd
)
727 vms_debug (6, "vms_output_pop(pushed_size = %d)\n", PRIV (pushed_size
));
730 _bfd_vms_output_flush (abfd
);
731 PRIV (length_pos
) = 2;
734 vms_debug (6, "vms_output_pop: length_pos = %d\n", PRIV (length_pos
));
737 PRIV (pushed_size
) = 0;
742 /* Flush unwritten output, ends current record */
745 _bfd_vms_output_flush (abfd
)
748 int real_size
= PRIV (output_size
);
753 vms_debug (6, "_bfd_vms_output_flush(real_size = %d, pushed_size %d at lenpos %d)\n",
754 real_size
, PRIV (pushed_size
), PRIV (length_pos
));
757 if (PRIV (push_level
) > 0)
758 length
= real_size
- PRIV (pushed_size
);
764 aligncount
= (PRIV (output_alignment
)
765 - (length
% PRIV (output_alignment
))) % PRIV (output_alignment
);
768 vms_debug (6, "align: adding %d bytes\n", aligncount
);
771 while (aligncount
-- > 0)
773 PRIV (output_buf
)[real_size
++] = 0;
775 /* this is why I *love* vms: inconsistency :-}
776 alignment is added to the subrecord length
777 but not to the record length */
778 if (PRIV (push_level
) > 0)
783 /* put length to buffer */
784 PRIV (output_size
) = PRIV (length_pos
);
785 _bfd_vms_output_short (abfd
, (unsigned int) length
);
787 if (PRIV (push_level
) == 0)
790 /* write length first, see FF_FOREIGN in the input routines */
791 fwrite (PRIV (output_buf
) + 2, 2, 1, (FILE *) abfd
->iostream
);
793 fwrite (PRIV (output_buf
), (size_t) real_size
, 1,
794 (FILE *) abfd
->iostream
);
796 PRIV (output_size
) = 0;
800 PRIV (output_size
) = real_size
;
801 PRIV (pushed_size
) = PRIV (output_size
);
807 /* End record output */
810 _bfd_vms_output_end (abfd
)
814 vms_debug (6, "_bfd_vms_output_end\n");
817 _bfd_vms_output_flush (abfd
);
822 /* check remaining buffer size
824 return what's left. */
827 _bfd_vms_output_check (abfd
, size
)
832 vms_debug (6, "_bfd_vms_output_check(%d)\n", size
);
835 return (MAX_OUTREC_SIZE
- (PRIV (output_size
) + size
+ MIN_OUTREC_LUFT
));
838 /* Output byte (8 bit) value */
841 _bfd_vms_output_byte (abfd
, value
)
846 vms_debug (6, "_bfd_vms_output_byte(%02x)\n", value
);
849 bfd_put_8 (abfd
, value
& 0xff, PRIV (output_buf
) + PRIV (output_size
));
850 PRIV (output_size
) += 1;
854 /* Output short (16 bit) value */
857 _bfd_vms_output_short (abfd
, value
)
862 vms_debug (6, "_bfd_vms_output_short (%04x)\n", value
);
865 bfd_put_16 (abfd
, (bfd_vma
) value
& 0xffff,
866 PRIV (output_buf
) + PRIV (output_size
));
867 PRIV (output_size
) += 2;
871 /* Output long (32 bit) value */
874 _bfd_vms_output_long (abfd
, value
)
879 vms_debug (6, "_bfd_vms_output_long (%08lx)\n", value
);
882 bfd_put_32 (abfd
, (bfd_vma
) value
, PRIV (output_buf
) + PRIV (output_size
));
883 PRIV (output_size
) += 4;
887 /* Output quad (64 bit) value */
890 _bfd_vms_output_quad (abfd
, value
)
895 vms_debug (6, "_bfd_vms_output_quad(%016lx)\n", value
);
898 bfd_put_64(abfd
, value
, PRIV (output_buf
) + PRIV (output_size
));
899 PRIV (output_size
) += 8;
903 /* Output c-string as counted string */
906 _bfd_vms_output_counted (abfd
, value
)
913 vms_debug (6, "_bfd_vms_output_counted(%s)\n", value
);
916 len
= strlen (value
);
919 (*_bfd_error_handler
) (_("_bfd_vms_output_counted called with zero bytes"));
924 (*_bfd_error_handler
) (_("_bfd_vms_output_counted called with too many bytes"));
927 _bfd_vms_output_byte (abfd
, (unsigned int) len
& 0xff);
928 _bfd_vms_output_dump (abfd
, (unsigned char *)value
, len
);
931 /* Output character area */
934 _bfd_vms_output_dump (abfd
, data
, length
)
940 vms_debug (6, "_bfd_vms_output_dump(%d)\n", length
);
946 memcpy (PRIV (output_buf
) + PRIV (output_size
), data
, (size_t) length
);
947 PRIV (output_size
) += length
;
952 /* Output count bytes of value */
955 _bfd_vms_output_fill (abfd
, value
, count
)
961 vms_debug (6, "_bfd_vms_output_fill(val %02x times %d)\n", value
, count
);
966 memset (PRIV (output_buf
) + PRIV (output_size
), value
, (size_t) count
);
967 PRIV (output_size
) += count
;
972 /* this hash routine borrowed from GNU-EMACS, and strengthened slightly ERY*/
978 register const unsigned char *p
= (unsigned char *) ptr
;
979 register const unsigned char *end
= p
+ strlen (ptr
);
980 register unsigned char c
;
981 register int hash
= 0;
986 hash
= ((hash
<< 3) + (hash
<< 15) + (hash
>> 28) + c
);
991 /* Generate a length-hashed VMS symbol name (limited to maxlen chars). */
994 _bfd_vms_length_hash_symbol (abfd
, in
, maxlen
)
1002 const char *old_name
;
1004 static char outbuf
[EOBJ_S_C_SYMSIZ
+1];
1008 vms_debug(4, "_bfd_vms_length_hash_symbol \"%s\"\n", in
);
1011 if (maxlen
> EOBJ_S_C_SYMSIZ
)
1012 maxlen
= EOBJ_S_C_SYMSIZ
;
1014 new_name
= out
; /* save this for later. */
1016 /* We may need to truncate the symbol, save the hash for later. */
1018 in_len
= strlen (in
);
1020 result
= (in_len
> maxlen
) ? hash_string (in
) : 0;
1024 /* Do the length checking. */
1026 if (in_len
<= maxlen
)
1032 if (PRIV (flag_hash_long_names
))
1038 strncpy (out
, in
, (size_t) i
);
1042 if ((in_len
> maxlen
)
1043 && PRIV (flag_hash_long_names
))
1044 sprintf (out
, "_%08lx", result
);
1049 vms_debug(4, "--> [%d]\"%s\"\n", strlen (outbuf
), outbuf
);
1053 && PRIV (flag_hash_long_names
)
1054 && PRIV (flag_show_after_trunc
))
1055 printf (_("Symbol %s replaced by %s\n"), old_name
, new_name
);
1060 /* Allocate and initialize a new symbol. */
1063 new_symbol (abfd
, name
)
1070 _bfd_vms_debug (7, "new_symbol %s\n", name
);
1073 symbol
= bfd_make_empty_symbol (abfd
);
1076 symbol
->name
= name
;
1077 symbol
->section
= bfd_make_section (abfd
, BFD_UND_SECTION_NAME
);
1082 /* Allocate and enter a new private symbol. */
1085 _bfd_vms_enter_symbol (abfd
, name
)
1089 vms_symbol_entry
*entry
;
1092 _bfd_vms_debug (6, "_bfd_vms_enter_symbol %s\n", name
);
1095 entry
= (vms_symbol_entry
*)
1096 bfd_hash_lookup (PRIV (vms_symbol_table
), name
, false, false);
1100 _bfd_vms_debug (8, "creating hash entry for %s\n", name
);
1102 entry
= (vms_symbol_entry
*)bfd_hash_lookup (PRIV (vms_symbol_table
), name
, true, false);
1106 symbol
= new_symbol (abfd
, name
);
1109 entry
->symbol
= symbol
;
1110 PRIV (gsd_sym_count
)++;
1117 (*_bfd_error_handler
) (_("failed to enter %s"), name
);
1122 _bfd_vms_debug (8, "found hash entry for %s\n", name
);
1127 _bfd_vms_debug (7, "-> entry %p, entry->symbol %p\n", entry
, entry
->symbol
);