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);