1 /* vms-misc.c -- Miscellaneous functions for VAX (openVMS/VAX) and
2 EVAX (openVMS/Alpha) files.
3 Copyright 1996, 1997, 1998, 1999 Free Software Foundation, Inc.
5 Written by Klaus K"ampf (kkaempf@rmi.de)
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
32 /*-----------------------------------------------------------------------------*/
36 /* debug function for all vms extensions
37 evaluates environment variable VMS_DEBUG for a
38 numerical value on the first call
39 all error levels below this value are printed
42 1 toplevel bfd calls (functions from the bfd vector)
43 2 functions called by bfd calls
47 level is also identation level. Indentation is performed
53 _bfd_vms_debug (int level
, char *format
, ...)
55 static int min_level
= -1;
56 static FILE *output
= NULL
;
59 int abslvl
= (level
> 0)?level
:-level
;
63 if ((eptr
= getenv("VMS_DEBUG")) != NULL
)
65 min_level
= atoi(eptr
);
73 if (abslvl
> min_level
)
77 fprintf (output
, " ");
78 va_start(args
, format
);
79 vfprintf (output
, format
, args
);
86 #else /* not __STDC__ */
89 _bfd_vms_debug (level
, format
, a1
, a2
, a3
, a4
, a5
, a6
)
92 long a1
; long a2
; long a3
;
93 long a4
; long a5
; long a6
;
95 static int min_level
= -1;
96 static FILE *output
= NULL
;
101 if ((eptr
= getenv("VMS_DEBUG")) != NULL
)
103 min_level
= atoi(eptr
);
111 if (level
> min_level
)
115 fprintf (output
, " ");
116 fprintf (output
, format
, a1
, a2
, a3
, a4
, a5
, a6
);
121 #endif /* __STDC__ */
124 hex dump 'size' bytes starting at 'ptr' */
127 _bfd_hexdump (level
, ptr
, size
, offset
)
133 unsigned char *lptr
= ptr
;
140 vms_debug (level
, "%08lx:", start
);
141 vms_debug (-level
, " %02x", *ptr
++);
146 while ((count
%16) != 0)
148 vms_debug (-level
, " ");
154 vms_debug (-level
, " ");
157 vms_debug (-level
, "%c", (*lptr
< 32)?'.':*lptr
);
160 vms_debug (-level
, "\n");
164 vms_debug (-level
, "\n");
173 These are needed when reading an object file. */
175 /* allocate new vms_hash_entry
176 keep the symbol name and a pointer to the bfd symbol in the table */
178 struct bfd_hash_entry
*
179 _bfd_vms_hash_newfunc (entry
, table
, string
)
180 struct bfd_hash_entry
*entry
;
181 struct bfd_hash_table
*table
;
184 vms_symbol_entry
*ret
;
187 vms_debug (5, "_bfd_vms_hash_newfunc(%p, %p, %s)\n", entry
, table
, string
);
190 if (entry
== (struct bfd_hash_entry
*)NULL
)
192 ret
= (vms_symbol_entry
*)
193 bfd_hash_allocate (table
, sizeof (vms_symbol_entry
));
194 if (ret
== (vms_symbol_entry
*) NULL
)
196 bfd_set_error (bfd_error_no_memory
);
197 return (struct bfd_hash_entry
*)NULL
;
199 entry
= (struct bfd_hash_entry
*) ret
;
202 /* Call the allocation method of the base class. */
204 ret
= (vms_symbol_entry
*) bfd_hash_newfunc (entry
, table
, string
);
206 vms_debug (6, "_bfd_vms_hash_newfunc ret %p\n", ret
);
209 ret
->symbol
= (asymbol
*)NULL
;
211 return (struct bfd_hash_entry
*)ret
;
215 /* object file input functions */
217 /* Return type and length from record header (buf) on Alpha. */
220 _bfd_vms_get_header_values (abfd
, buf
, type
, length
)
221 bfd
*abfd ATTRIBUTE_UNUSED
;
227 *type
= bfd_getl16 (buf
);
230 *length
= bfd_getl16 (buf
);
233 vms_debug (10, "_bfd_vms_get_header_values type %x, length %x\n", (type
?*type
:0), (length
?*length
:0));
239 /* Get next record from object file to vms_buf
240 set PRIV(buf_size) and return it
242 this is a little tricky since it should be portable.
244 the openVMS object file has 'variable length' which means that
245 read() returns data in chunks of (hopefully) correct and expected
246 size. The linker (and other tools on vms) depend on that. Unix doesn't
247 know about 'formatted' files, so reading and writing such an object
248 file in a unix environment is not trivial.
250 With the tool 'file' (available on all vms ftp sites), one
251 can view and change the attributes of a file. Changing from
252 'variable length' to 'fixed length, 512 bytes' reveals the
253 record length at the first 2 bytes of every record. The same
254 happens during the transfer of object files from vms to unix,
255 at least with ucx, dec's implementation of tcp/ip.
257 The vms format repeats the length at bytes 2 & 3 of every record.
259 On the first call (file_format == FF_UNKNOWN) we check if
260 the first and the third byte pair (!) of the record match.
261 If they do it's an object file in an unix environment or with
262 wrong attributes (FF_FOREIGN), else we should be in a vms
263 environment where read() returns the record size (FF_NATIVE).
265 reading is always done in 2 steps.
266 first just the record header is read and the length extracted
268 then the read buffer is adjusted and the remaining bytes are
271 all file i/o is always done on even file positions */
274 _bfd_vms_get_record (abfd
)
277 int test_len
, test_start
, remaining
;
278 unsigned char *vms_buf
;
281 vms_debug (8, "_bfd_vms_get_record\n");
284 /* minimum is 6 bytes on Alpha
285 (2 bytes length, 2 bytes record id, 2 bytes length repeated)
287 on VAX there's no length information in the record
288 so start with OBJ_S_C_MAXRECSIZ */
290 if (PRIV(buf_size
) == 0)
294 PRIV(vms_buf
) = (unsigned char *) malloc (OBJ_S_C_MAXRECSIZ
);
295 PRIV(buf_size
) = OBJ_S_C_MAXRECSIZ
;
296 PRIV(file_format
) = FF_VAX
;
299 PRIV(vms_buf
) = (unsigned char *) malloc (6);
302 vms_buf
= PRIV(vms_buf
);
306 bfd_set_error (bfd_error_no_memory
);
310 switch (PRIV(file_format
))
314 test_len
= 6; /* probe 6 bytes */
315 test_start
= 2; /* where the record starts */
330 /* skip odd alignment byte */
332 if (bfd_tell (abfd
) & 1)
334 if (bfd_read (PRIV(vms_buf
), 1, 1, abfd
) != 1)
336 bfd_set_error (bfd_error_file_truncated
);
341 /* read the record header on Alpha. */
344 && (bfd_read (PRIV(vms_buf
), 1, test_len
, abfd
)
345 != (bfd_size_type
) test_len
))
347 bfd_set_error (bfd_error_file_truncated
);
351 /* check file format on first call */
353 if (PRIV(file_format
) == FF_UNKNOWN
)
354 { /* record length repeats ? */
355 if ( (vms_buf
[0] == vms_buf
[4])
356 && (vms_buf
[1] == vms_buf
[5]))
358 PRIV(file_format
) = FF_FOREIGN
; /* Y: foreign environment */
363 PRIV(file_format
) = FF_NATIVE
; /* N: native environment */
370 PRIV(rec_length
) = bfd_read (vms_buf
, 1, PRIV(buf_size
), abfd
);
371 if (PRIV(rec_length
) <= 0)
373 bfd_set_error (bfd_error_file_truncated
);
376 PRIV(vms_rec
) = vms_buf
;
380 /* extract vms record length */
382 _bfd_vms_get_header_values (abfd
, vms_buf
+test_start
, NULL
,
385 if (PRIV(rec_length
) <= 0)
387 bfd_set_error (bfd_error_file_truncated
);
391 /* that's what the linker manual says */
393 if (PRIV(rec_length
) > EOBJ_S_C_MAXRECSIZ
)
395 bfd_set_error (bfd_error_file_truncated
);
399 /* adjust the buffer */
401 if (PRIV(rec_length
) > PRIV(buf_size
))
403 PRIV(vms_buf
) = (unsigned char *) realloc (vms_buf
, PRIV(rec_length
));
404 vms_buf
= PRIV(vms_buf
);
407 bfd_set_error (bfd_error_no_memory
);
410 PRIV(buf_size
) = PRIV(rec_length
);
413 /* read the remaining record */
415 remaining
= PRIV(rec_length
) - test_len
+ test_start
;
418 vms_debug (10, "bfd_read remaining %d\n", remaining
);
420 if (bfd_read (vms_buf
+ test_len
, 1, remaining
, abfd
) !=
421 (bfd_size_type
) remaining
)
423 bfd_set_error (bfd_error_file_truncated
);
426 PRIV(vms_rec
) = vms_buf
+ test_start
;
430 vms_debug (11, "bfd_read rec_length %d\n", PRIV(rec_length
));
433 return PRIV(rec_length
);
436 /* get next vms record from file
437 update vms_rec and rec_length to new (remaining) values */
440 _bfd_vms_next_record (abfd
)
444 vms_debug (8, "_bfd_vms_next_record (len %d, size %d)\n",
445 PRIV(rec_length
), PRIV(rec_size
));
448 if (PRIV(rec_length
) > 0)
450 PRIV(vms_rec
) += PRIV(rec_size
);
454 if (_bfd_vms_get_record (abfd
) <= 0)
458 if (!PRIV(vms_rec
) || !PRIV(vms_buf
)
459 || PRIV(vms_rec
) >= (PRIV(vms_buf
) + PRIV(buf_size
)))
464 PRIV(rec_type
) = *(PRIV(vms_rec
));
465 PRIV(rec_size
) = PRIV(rec_length
);
469 _bfd_vms_get_header_values (abfd
, PRIV(vms_rec
), &PRIV(rec_type
),
472 PRIV(rec_length
) -= PRIV(rec_size
);
475 vms_debug (8, "_bfd_vms_next_record: rec %p, size %d, length %d, type %d\n",
476 PRIV(vms_rec
), PRIV(rec_size
), PRIV(rec_length
),
480 return PRIV(rec_type
);
484 /* Copy sized string (string with fixed length) to new allocated area
485 size is string length (size of record) */
488 _bfd_vms_save_sized_string (str
, size
)
492 char *newstr
= bfd_malloc (size
+ 1);
496 strncpy (newstr
, (char *)str
, size
);
502 /* Copy counted string (string with length at first byte) to new allocated area
503 ptr points to length byte on entry */
506 _bfd_vms_save_counted_string (ptr
)
511 return _bfd_vms_save_sized_string (ptr
, len
);
515 /* stack routines for vms ETIR commands */
517 /* Push value and section index */
520 _bfd_vms_push (abfd
, val
, psect
)
525 static int last_psect
;
528 vms_debug (4, "<push %016lx(%d) at %d>\n", val
, psect
, PRIV(stackptr
));
534 PRIV(stack
[PRIV(stackptr
)]).value
= val
;
535 PRIV(stack
[PRIV(stackptr
)]).psect
= last_psect
;
537 if (PRIV(stackptr
) >= STACKSIZE
)
539 bfd_set_error (bfd_error_bad_value
);
540 (*_bfd_error_handler
) (_("Stack overflow (%d) in _bfd_vms_push"), PRIV(stackptr
));
546 /* Pop value and section index */
549 _bfd_vms_pop (abfd
, psect
)
555 if (PRIV(stackptr
) == 0)
557 bfd_set_error (bfd_error_bad_value
);
558 (*_bfd_error_handler
) (_("Stack underflow in _bfd_vms_pop"));
562 value
= PRIV(stack
[PRIV(stackptr
)]).value
;
563 if ((psect
!= NULL
) && (PRIV(stack
[PRIV(stackptr
)]).psect
>= 0))
564 *psect
= PRIV(stack
[PRIV(stackptr
)]).psect
;
567 vms_debug (4, "<pop %016lx(%d)>\n", value
, PRIV(stack
[PRIV(stackptr
)]).psect
);
574 /* object file output functions */
576 /* GAS tends to write sections in little chunks (bfd_set_section_contents)
577 which we can't use directly. So we save the little chunks in linked
578 lists (one per section) and write them later. */
580 /* Add a new vms_section structure to vms_section_table
581 - forward chaining - */
584 add_new_contents (abfd
, section
)
588 vms_section
*sptr
, *newptr
;
590 sptr
= PRIV(vms_section_table
)[section
->index
];
594 newptr
= (vms_section
*) bfd_malloc (sizeof (vms_section
));
595 if (newptr
== (vms_section
*) NULL
)
597 newptr
->contents
= (unsigned char *) bfd_alloc (abfd
, (int)section
->_raw_size
);
598 if (newptr
->contents
== (unsigned char *)NULL
)
601 newptr
->size
= section
->_raw_size
;
603 PRIV(vms_section_table
)[section
->index
] = newptr
;
607 /* Save section data & offset to an vms_section structure
608 vms_section_table[] holds the vms_section chain */
611 _bfd_save_vms_section (abfd
, section
, data
, offset
, count
)
620 if (section
->index
>= VMS_SECTION_COUNT
)
622 bfd_set_error (bfd_error_nonrepresentable_section
);
625 if (count
== (bfd_size_type
)0)
627 sptr
= add_new_contents (abfd
, section
);
630 memcpy (sptr
->contents
+ offset
, data
, (size_t) count
);
635 /* Get vms_section pointer to saved contents for section # index */
638 _bfd_get_vms_section (abfd
, index
)
642 if (index
>= VMS_SECTION_COUNT
)
644 bfd_set_error (bfd_error_nonrepresentable_section
);
647 return PRIV(vms_section_table
)[index
];
651 /* Object output routines */
653 /* Begin new record or record header
654 write 2 bytes rectype
655 write 2 bytes record length (filled in at flush)
656 write 2 bytes header type (ommitted if rechead == -1) */
659 _bfd_vms_output_begin (abfd
, rectype
, rechead
)
665 vms_debug (6, "_bfd_vms_output_begin(type %d, head %d)\n", rectype
,
669 _bfd_vms_output_short (abfd
,rectype
);
671 /* save current output position to fill in lenght later */
673 if (PRIV(push_level
) > 0)
674 PRIV(length_pos
) = PRIV(output_size
);
677 vms_debug (6, "_bfd_vms_output_begin: length_pos = %d\n",
681 _bfd_vms_output_short (abfd
,0); /* placeholder for length */
684 _bfd_vms_output_short (abfd
,rechead
);
689 /* Set record/subrecord alignment */
692 _bfd_vms_output_alignment (abfd
, alignto
)
697 vms_debug (6, "_bfd_vms_output_alignment(%d)\n", alignto
);
700 PRIV(output_alignment
) = alignto
;
704 /* Prepare for subrecord fields */
707 _bfd_vms_output_push (abfd
)
711 vms_debug (6, "vms_output_push(pushed_size = %d)\n", PRIV(output_size
));
715 PRIV(pushed_size
) = PRIV(output_size
);
719 /* End of subrecord fields */
722 _bfd_vms_output_pop (abfd
)
726 vms_debug (6, "vms_output_pop(pushed_size = %d)\n", PRIV(pushed_size
));
729 _bfd_vms_output_flush (abfd
);
730 PRIV(length_pos
) = 2;
733 vms_debug (6, "vms_output_pop: length_pos = %d\n", PRIV(length_pos
));
736 PRIV(pushed_size
) = 0;
741 /* Flush unwritten output, ends current record */
744 _bfd_vms_output_flush (abfd
)
747 int real_size
= PRIV(output_size
);
752 vms_debug (6, "_bfd_vms_output_flush(real_size = %d, pushed_size %d at lenpos %d)\n",
753 real_size
, PRIV(pushed_size
), PRIV(length_pos
));
756 if (PRIV(push_level
) > 0)
757 length
= real_size
- PRIV(pushed_size
);
763 aligncount
= (PRIV(output_alignment
)
764 - (length
% PRIV(output_alignment
))) % PRIV(output_alignment
);
767 vms_debug (6, "align: adding %d bytes\n", aligncount
);
770 while (aligncount
-- > 0)
772 PRIV(output_buf
)[real_size
++] = 0;
774 /* this is why I *love* vms: inconsistency :-}
775 alignment is added to the subrecord length
776 but not to the record length */
777 if (PRIV(push_level
) > 0)
782 /* put length to buffer */
783 PRIV(output_size
) = PRIV(length_pos
);
784 _bfd_vms_output_short (abfd
, (unsigned int)length
);
786 if (PRIV(push_level
) == 0)
789 /* write length first, see FF_FOREIGN in the input routines */
790 fwrite (PRIV(output_buf
)+2, 2, 1, (FILE *)abfd
->iostream
);
792 fwrite (PRIV(output_buf
), real_size
, 1, (FILE *)abfd
->iostream
);
794 PRIV(output_size
) = 0;
798 PRIV(output_size
) = real_size
;
799 PRIV(pushed_size
) = PRIV(output_size
);
805 /* End record output */
808 _bfd_vms_output_end (abfd
)
812 vms_debug (6, "_bfd_vms_output_end\n");
815 _bfd_vms_output_flush (abfd
);
820 /* check remaining buffer size
822 return what's left. */
825 _bfd_vms_output_check (abfd
, size
)
830 vms_debug (6, "_bfd_vms_output_check(%d)\n", size
);
833 return (MAX_OUTREC_SIZE
- (PRIV(output_size
) + size
+ MIN_OUTREC_LUFT
));
836 /* Output byte (8 bit) value */
839 _bfd_vms_output_byte (abfd
, value
)
844 vms_debug (6, "_bfd_vms_output_byte(%02x)\n", value
);
847 bfd_put_8 (abfd
, value
& 0xff, PRIV(output_buf
) + PRIV(output_size
));
848 PRIV(output_size
) += 1;
852 /* Output short (16 bit) value */
855 _bfd_vms_output_short (abfd
, value
)
860 vms_debug (6, "_bfd_vms_output_short (%04x)\n", value
);
863 bfd_put_16 (abfd
, value
& 0xffff, PRIV(output_buf
) + PRIV(output_size
));
864 PRIV(output_size
) += 2;
868 /* Output long (32 bit) value */
871 _bfd_vms_output_long (abfd
, value
)
876 vms_debug (6, "_bfd_vms_output_long (%08lx)\n", value
);
879 bfd_put_32 (abfd
, value
, PRIV(output_buf
) + PRIV(output_size
));
880 PRIV(output_size
) += 4;
884 /* Output quad (64 bit) value */
887 _bfd_vms_output_quad (abfd
, value
)
892 vms_debug (6, "_bfd_vms_output_quad(%016lx)\n", value
);
895 bfd_put_64(abfd
, value
, PRIV(output_buf
) + PRIV(output_size
));
896 PRIV(output_size
) += 8;
900 /* Output c-string as counted string */
903 _bfd_vms_output_counted (abfd
, value
)
910 vms_debug (6, "_bfd_vms_output_counted(%s)\n", value
);
913 len
= strlen (value
);
916 (*_bfd_error_handler
) (_("_bfd_vms_output_counted called with zero bytes"));
921 (*_bfd_error_handler
) (_("_bfd_vms_output_counted called with too many bytes"));
924 _bfd_vms_output_byte (abfd
, len
& 0xff);
925 _bfd_vms_output_dump (abfd
, (unsigned char *)value
, len
);
928 /* Output character area */
931 _bfd_vms_output_dump (abfd
, data
, length
)
937 vms_debug (6, "_bfd_vms_output_dump(%d)\n", length
);
943 memcpy (PRIV(output_buf
) + PRIV(output_size
), data
, length
);
944 PRIV(output_size
) += length
;
949 /* Output count bytes of value */
952 _bfd_vms_output_fill (abfd
, value
, count
)
958 vms_debug (6, "_bfd_vms_output_fill(val %02x times %d)\n", value
, count
);
963 memset (PRIV(output_buf
) + PRIV(output_size
), value
, count
);
964 PRIV(output_size
) += count
;
969 /* this hash routine borrowed from GNU-EMACS, and strengthened slightly ERY*/
975 register const unsigned char *p
= (unsigned char *) ptr
;
976 register const unsigned char *end
= p
+ strlen (ptr
);
977 register unsigned char c
;
978 register int hash
= 0;
983 hash
= ((hash
<< 3) + (hash
<< 15) + (hash
>> 28) + c
);
988 /* Generate a length-hashed VMS symbol name (limited to maxlen chars). */
991 _bfd_vms_length_hash_symbol (abfd
, in
, maxlen
)
999 const char *old_name
;
1001 static char outbuf
[EOBJ_S_C_SYMSIZ
+1];
1005 vms_debug(4, "_bfd_vms_length_hash_symbol \"%s\"\n", in
);
1008 if (maxlen
> EOBJ_S_C_SYMSIZ
)
1009 maxlen
= EOBJ_S_C_SYMSIZ
;
1011 new_name
= out
; /* save this for later. */
1013 /* We may need to truncate the symbol, save the hash for later. */
1015 in_len
= strlen (in
);
1017 result
= (in_len
> maxlen
) ? hash_string (in
) : 0;
1021 /* Do the length checking. */
1023 if (in_len
<= maxlen
)
1029 if (PRIV(flag_hash_long_names
))
1035 strncpy (out
, in
, i
);
1039 if ((in_len
> maxlen
)
1040 && PRIV(flag_hash_long_names
))
1041 sprintf (out
, "_%08lx", result
);
1046 vms_debug(4, "--> [%d]\"%s\"\n", strlen (outbuf
), outbuf
);
1050 && PRIV(flag_hash_long_names
)
1051 && PRIV(flag_show_after_trunc
))
1052 printf (_("Symbol %s replaced by %s\n"), old_name
, new_name
);
1057 /* Allocate and initialize a new symbol. */
1060 new_symbol (abfd
, name
)
1067 _bfd_vms_debug (7, "new_symbol %s\n", name
);
1070 symbol
= _bfd_vms_make_empty_symbol (abfd
);
1073 symbol
->name
= name
;
1074 symbol
->section
= bfd_make_section (abfd
, BFD_UND_SECTION_NAME
);
1079 /* Allocate and enter a new private symbol. */
1082 _bfd_vms_enter_symbol (abfd
, name
)
1086 vms_symbol_entry
*entry
;
1089 _bfd_vms_debug (6, "_bfd_vms_enter_symbol %s\n", name
);
1092 entry
= (vms_symbol_entry
*)
1093 bfd_hash_lookup (PRIV(vms_symbol_table
), name
, false, false);
1097 _bfd_vms_debug (8, "creating hash entry for %s\n", name
);
1099 entry
= (vms_symbol_entry
*)bfd_hash_lookup (PRIV(vms_symbol_table
), name
, true, false);
1103 symbol
= new_symbol (abfd
, name
);
1106 entry
->symbol
= symbol
;
1107 PRIV(gsd_sym_count
)++;
1114 (*_bfd_error_handler
) (_("failed to enter %s"), name
);
1119 _bfd_vms_debug (8, "found hash entry for %s\n", name
);
1124 _bfd_vms_debug (7, "-> entry %p, entry->symbol %p\n", entry
, entry
->symbol
);