1 /* evax-misc.c -- Miscellaneous functions for ALPHA EVAX (openVMS/AXP) files.
2 Copyright 1996 Free Software Foundation, Inc.
4 of proGIS Softwareentwicklung, Aachen, Germany
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
33 /*-----------------------------------------------------------------------------*/
37 /* debug function for all evax extensions
38 evaluates environment variable EVAX_DEBUG for a
39 numerical value on the first call
40 all error levels below this value are printed
43 1 toplevel bfd calls (functions from the bfd vector)
44 2 functions called by bfd calls
48 level is also identation level. Indentation is performed
54 _bfd_evax_debug (int level, char *format, ...)
56 static int min_level = -1;
57 static FILE *output = NULL;
60 int abslvl = (level > 0)?level:-level;
64 if ((eptr = getenv("EVAX_DEBUG")) != NULL)
66 min_level = atoi(eptr);
74 if (abslvl > min_level)
79 va_start(args, format);
80 vfprintf(output, format, args);
87 #else /* not __STDC__ */
90 _bfd_evax_debug (level, format, a1, a2, a3, a4, a5, a6)
93 long a1; long a2; long a3;
94 long a4; long a5; long a6;
96 static int min_level = -1;
97 static FILE *output = NULL;
102 if ((eptr = getenv("EVAX_DEBUG")) != NULL)
104 min_level = atoi(eptr);
112 if (level > min_level)
116 fprintf(output, " ");
117 fprintf(output, format, a1, a2, a3, a4, a5, a6);
122 #endif /* __STDC__ */
126 hex dump 'size' bytes starting at 'ptr' */
129 _bfd_hexdump (level, ptr, size, offset)
135 unsigned char *lptr = ptr;
142 evax_debug (level, "%08lx:", start);
143 evax_debug (-level, " %02x", *ptr++);
148 while ((count%16) != 0)
150 evax_debug (-level, " ");
156 evax_debug (-level, " ");
159 evax_debug (-level, "%c", (*lptr < 32)?'.':*lptr);
162 evax_debug (-level, "\n");
166 evax_debug (-level, "\n");
175 These are needed when reading an object file. */
177 /* allocate new evax_hash_entry
178 keep the symbol name and a pointer to the bfd symbol in the table */
180 struct bfd_hash_entry *
181 _bfd_evax_hash_newfunc (entry, table, string)
182 struct bfd_hash_entry *entry;
183 struct bfd_hash_table *table;
186 evax_symbol_entry *ret = (evax_symbol_entry *)entry;
189 evax_debug (5, "_bfd_evax_hash_newfunc(%p, %p, %s)\n", entry, table, string);
192 if (ret == (evax_symbol_entry *)NULL)
193 ret = ((evax_symbol_entry *) bfd_hash_allocate (table, sizeof (evax_symbol_entry)));
194 if (ret == (evax_symbol_entry *)NULL)
196 bfd_set_error (bfd_error_no_memory);
197 return (struct bfd_hash_entry *)NULL;
199 ret = (evax_symbol_entry *) bfd_hash_newfunc ((struct bfd_hash_entry *)ret, table, string);
201 ret->symbol = (asymbol *)NULL;
203 return (struct bfd_hash_entry *)ret;
207 /* object file input functions */
209 /* Return type and length from record header (buf) */
212 _bfd_evax_get_header_values (abfd, buf, type, length)
219 *type = bfd_getl16 (buf);
222 *length = bfd_getl16 (buf);
228 /* Get next record from object file to evax_buf
229 set PRIV(buf_size) and return it
231 this is a little tricky since it should be portable.
233 the openVMS/AXP object file has 'variable length' which means that
234 read() returns data in chunks of (hopefully) correct and expected
235 size. The linker (and other tools on vms) depend on that. Unix doesn't
236 know about 'formatted' files, so reading and writing such an object
237 file in a unix environment is not trivial.
239 With the tool 'file' (available on all vms ftp sites), one
240 can view and change the attributes of a file. Changing from
241 'variable length' to 'fixed length, 512 bytes' reveals the
242 record length at the first 2 bytes of every record. The same
243 happens during the transfer of object files from vms to unix,
244 at least with ucx, dec's implementation of tcp/ip.
246 The EVAX format repeats the length at bytes 2 & 3 of every record.
248 On the first call (file_format == FF_UNKNOWN) we check if
249 the first and the third byte pair (!) of the record match.
250 If they do it's an object file in an unix environment or with
251 wrong attributes (FF_FOREIGN), else we should be in a vms
252 environment where read() returns the record size (FF_NATIVE).
254 reading is always done in 2 steps.
255 first just the record header is read and the length extracted
257 then the read buffer is adjusted and the remaining bytes are
260 all file i/o is always done on even file positions */
263 _bfd_evax_get_record (abfd)
266 int test_len, test_start, remaining;
267 unsigned char *evax_buf;
270 evax_debug (8, "_bfd_evax_get_record\n");
273 /* minimum is 6 bytes
274 (2 bytes length, 2 bytes record id, 2 bytes length repeated) */
276 if (PRIV(buf_size) == 0)
278 PRIV(evax_buf) = (unsigned char *) malloc (6);
280 evax_debug (9, "PRIV(evax_buf) %p\n", PRIV(evax_buf));
284 evax_buf = PRIV(evax_buf);
289 evax_debug (9, "can't alloc evax_buf\n");
291 bfd_set_error (bfd_error_no_memory);
295 switch (PRIV(file_format))
299 test_len = 6; /* probe 6 bytes */
300 test_start = 2; /* where the record starts */
309 /* skip odd alignment byte */
311 if (PRIV(file_format) == FF_FOREIGN)
314 if (bfd_tell (abfd) & 1)
317 evax_debug (10, "skip odd\n");
319 if (bfd_read (PRIV(evax_buf), 1, 1, abfd) != 1)
322 evax_debug (9, "skip odd failed\n");
324 bfd_set_error (bfd_error_file_truncated);
331 /* read the record header */
333 if (bfd_read (PRIV(evax_buf), 1, test_len, abfd) != test_len)
336 evax_debug (9, "can't bfd_read test %d bytes\n", test_len);
338 bfd_set_error (bfd_error_file_truncated);
342 /* check file format on first call */
344 if (PRIV(file_format) == FF_UNKNOWN)
345 { /* record length repeats ? */
346 if ( (evax_buf[0] == evax_buf[4])
347 && (evax_buf[1] == evax_buf[5]))
349 PRIV(file_format) = FF_FOREIGN; /* Y: foreign environment */
354 PRIV(file_format) = FF_NATIVE; /* N: native environment */
358 evax_debug (10, "File format is %s\n", (PRIV(file_format) == FF_FOREIGN)?"foreign":"native");
362 /* extract evax record length */
364 _bfd_evax_get_header_values (abfd, evax_buf+test_start, NULL,
367 if (PRIV(rec_length) <= 0)
369 bfd_set_error (bfd_error_file_truncated);
373 /* that's what the linker manual says */
375 if (PRIV(rec_length) > EOBJ_S_C_MAXRECSIZ)
377 bfd_set_error (bfd_error_file_truncated);
381 /* adjust the buffer */
383 if (PRIV(rec_length) > PRIV(buf_size))
385 PRIV(evax_buf) = (unsigned char *) realloc (evax_buf, PRIV(rec_length));
387 evax_debug (3, "adjusted the buffer (%p) from %d to %d\n", PRIV(evax_buf), PRIV(buf_size), PRIV(rec_length));
389 evax_buf = PRIV(evax_buf);
393 evax_debug (9, "can't realloc evax_buf to %d bytes\n", PRIV(rec_length));
395 bfd_set_error (bfd_error_no_memory);
398 PRIV(buf_size) = PRIV(rec_length);
401 /* read the remaining record */
403 remaining = PRIV(rec_length) - test_len + test_start;
405 if (bfd_read (evax_buf + test_len, 1, remaining, abfd) != remaining)
408 evax_debug (9, "can't bfd_read remaining %d bytes\n", remaining);
410 bfd_set_error (bfd_error_file_truncated);
414 PRIV(evax_rec) = evax_buf + test_start;
416 return PRIV(rec_length);
420 /* get next EVAX record from file
421 update evax_rec and rec_length to new (remaining) values */
424 _bfd_evax_next_record (abfd)
428 evax_debug (8, "_bfd_evax_next_record (len %d, size %d)\n",
429 PRIV(rec_length), PRIV(rec_size));
432 if (PRIV(rec_length) > 0)
434 PRIV(evax_rec) += PRIV(rec_size);
438 if (_bfd_evax_get_record (abfd) <= 0)
441 _bfd_evax_get_header_values (abfd, PRIV(evax_rec), &PRIV(rec_type),
443 PRIV(rec_length) -= PRIV(rec_size);
446 evax_debug (8, "_bfd_evax_next_record: rec %p, size %d, length %d, type %d\n",
447 PRIV(evax_rec), PRIV(rec_size), PRIV(rec_length),
451 return PRIV(rec_type);
456 /* Copy sized string (string with fixed length) to new allocated area
457 size is string length (size of record) */
460 _bfd_evax_save_sized_string (str, size)
464 char *newstr = bfd_malloc (size + 1);
468 strncpy (newstr, str, size);
474 /* Copy counted string (string with length at first byte) to new allocated area
475 ptr points to length byte on entry */
478 _bfd_evax_save_counted_string (ptr)
483 return _bfd_evax_save_sized_string (ptr, len);
487 /* stack routines for EVAX ETIR commands */
489 /* Push value and section index */
492 _bfd_evax_push (abfd, val, psect)
497 static int last_psect;
500 evax_debug (4, "<push %016lx(%d) at %d>\n", val, psect, PRIV(stackptr));
506 PRIV(stack[PRIV(stackptr)]).value = val;
507 PRIV(stack[PRIV(stackptr)]).psect = last_psect;
509 if (PRIV(stackptr) >= STACKSIZE)
511 bfd_set_error (bfd_error_bad_value);
518 /* Pop value and section index */
521 _bfd_evax_pop (abfd, psect)
527 if (PRIV(stackptr) == 0)
529 bfd_set_error (bfd_error_bad_value);
533 value = PRIV(stack[PRIV(stackptr)]).value;
534 if ((psect != NULL) && (PRIV(stack[PRIV(stackptr)]).psect >= 0))
535 *psect = PRIV(stack[PRIV(stackptr)]).psect;
538 evax_debug (4, "<pop %016lx(%d)>\n", value, PRIV(stack[PRIV(stackptr)]).psect);
545 /* object file output functions */
547 /* GAS tends to write sections in little chunks (bfd_set_section_contents)
548 which we can't use directly. So we save the little chunks in linked
549 lists (one per section) and write them later. */
551 /* Add a new evax_section structure to evax_section_table
552 - forward chaining - */
554 static evax_section *
555 add_new_contents (abfd, section)
559 evax_section *sptr, *newptr;
561 sptr = PRIV(evax_section_table)[section->index];
565 newptr = (evax_section *) bfd_malloc (sizeof (evax_section));
566 if (newptr == (evax_section *) NULL)
568 newptr->contents = (unsigned char *) bfd_alloc (abfd, (int)section->_raw_size);
569 if (newptr->contents == (unsigned char *)NULL)
572 newptr->size = section->_raw_size;
574 PRIV(evax_section_table)[section->index] = newptr;
579 /* Save section data & offset to an evax_section structure
580 evax_section_table[] holds the evax_section chain */
583 _bfd_save_evax_section (abfd, section, data, offset, count)
592 if (section->index >= EVAX_SECTION_COUNT)
594 bfd_set_error (bfd_error_nonrepresentable_section);
597 if (count == (bfd_size_type)0)
599 sptr = add_new_contents (abfd, section);
602 memcpy (sptr->contents + offset, data, (size_t) count);
608 /* Get evax_section pointer to saved contents for section # index */
611 _bfd_get_evax_section (abfd, index)
615 if (index >= EVAX_SECTION_COUNT)
617 bfd_set_error (bfd_error_nonrepresentable_section);
620 return PRIV(evax_section_table)[index];
624 /* Object output routines */
626 /* Begin new record or record header
627 write 2 bytes rectype
628 write 2 bytes record length (filled in at flush)
629 write 2 bytes header type (ommitted if rechead == -1) */
632 _bfd_evax_output_begin (abfd, rectype, rechead)
638 evax_debug (6, "_bfd_evax_output_begin(type %d, head %d)\n", rectype,
642 _bfd_evax_output_short (abfd,rectype);
644 /* save current output position to fill in lenght later */
646 if (PRIV(push_level) > 0)
647 PRIV(length_pos) = PRIV(output_size);
650 evax_debug (6, "_bfd_evax_output_begin: length_pos = %d\n",
654 _bfd_evax_output_short (abfd,0); /* placeholder for length */
657 _bfd_evax_output_short (abfd,rechead);
663 /* Set record/subrecord alignment */
666 _bfd_evax_output_alignment (abfd, alignto)
671 evax_debug (6, "_bfd_evax_output_alignment(%d)\n", alignto);
674 PRIV(output_alignment) = alignto;
679 /* Prepare for subrecord fields */
682 _bfd_evax_output_push (abfd)
686 evax_debug (6, "evax_output_push(pushed_size = %d)\n", PRIV(output_size));
690 PRIV(pushed_size) = PRIV(output_size);
695 /* End of subrecord fields */
698 _bfd_evax_output_pop (abfd)
702 evax_debug (6, "evax_output_pop(pushed_size = %d)\n", PRIV(pushed_size));
705 _bfd_evax_output_flush (abfd);
706 PRIV(length_pos) = 2;
709 evax_debug (6, "evax_output_pop: length_pos = %d\n", PRIV(length_pos));
712 PRIV(pushed_size) = 0;
718 /* Flush unwritten output, ends current record */
721 _bfd_evax_output_flush (abfd)
724 int real_size = PRIV(output_size);
729 evax_debug (6, "_bfd_evax_output_flush(real_size = %d, pushed_size %d at lenpos %d)\n",
730 real_size, PRIV(pushed_size), PRIV(length_pos));
733 if (PRIV(push_level) > 0)
734 length = real_size - PRIV(pushed_size);
740 aligncount = (PRIV(output_alignment)
741 - (length % PRIV(output_alignment))) % PRIV(output_alignment);
744 evax_debug (6, "align: adding %d bytes\n", aligncount);
747 while(aligncount-- > 0)
749 PRIV(output_buf)[real_size++] = 0;
751 /* this is why I *love* vms: inconsistency :-}
752 alignment is added to the subrecord length
753 but not to the record length */
754 if (PRIV(push_level) > 0)
759 /* put length to buffer */
760 PRIV(output_size) = PRIV(length_pos);
761 _bfd_evax_output_short (abfd, (unsigned int)length);
763 if (PRIV(push_level) == 0)
766 /* write length first, see FF_FOREIGN in the input routines */
767 fwrite (PRIV(output_buf)+2, 2, 1, (FILE *)abfd->iostream);
769 fwrite (PRIV(output_buf), real_size, 1, (FILE *)abfd->iostream);
771 PRIV(output_size) = 0;
775 PRIV(output_size) = real_size;
776 PRIV(pushed_size) = PRIV(output_size);
783 /* End record output */
786 _bfd_evax_output_end (abfd)
790 evax_debug (6, "_bfd_evax_output_end\n");
793 _bfd_evax_output_flush (abfd);
799 /* check remaining buffer size
801 return what's left. */
804 _bfd_evax_output_check (abfd, size)
809 evax_debug (6, "_bfd_evax_output_check(%d)\n", size);
812 return (MAX_OUTREC_SIZE - (PRIV(output_size) + size + MIN_OUTREC_LUFT));
816 /* Output byte (8 bit) value */
819 _bfd_evax_output_byte (abfd, value)
824 evax_debug (6, "_bfd_evax_output_byte(%02x)\n", value);
827 bfd_put_8 (abfd, value & 0xff, PRIV(output_buf) + PRIV(output_size));
828 PRIV(output_size) += 1;
833 /* Output short (16 bit) value */
836 _bfd_evax_output_short (abfd, value)
841 evax_debug (6, "_bfd_evax_output_short (%04x)\n", value);
844 bfd_put_16 (abfd, value & 0xffff, PRIV(output_buf) + PRIV(output_size));
845 PRIV(output_size) += 2;
850 /* Output long (32 bit) value */
853 _bfd_evax_output_long (abfd, value)
858 evax_debug (6, "_bfd_evax_output_long (%08lx)\n", value);
861 bfd_put_32 (abfd, value, PRIV(output_buf) + PRIV(output_size));
862 PRIV(output_size) += 4;
867 /* Output quad (64 bit) value */
870 _bfd_evax_output_quad (abfd, value)
875 evax_debug (6, "_bfd_evax_output_quad(%016lx)\n", value);
878 bfd_put_64(abfd, value, PRIV(output_buf) + PRIV(output_size));
879 PRIV(output_size) += 8;
884 /* Output c-string as counted string */
887 _bfd_evax_output_counted (abfd, value)
894 evax_debug (6, "_bfd_evax_output_counted(%s)\n", value);
897 len = strlen (value);
900 (*_bfd_error_handler) ("_bfd_evax_output_counted called with zero bytes");
905 (*_bfd_error_handler) ("_bfd_evax_output_counted called with too many bytes");
908 _bfd_evax_output_byte (abfd, len & 0xff);
909 _bfd_evax_output_dump (abfd, (unsigned char *)value, len);
913 /* Output character area */
916 _bfd_evax_output_dump (abfd, data, length)
922 evax_debug (6, "_bfd_evax_output_dump(%d)\n", length);
928 memcpy (PRIV(output_buf) + PRIV(output_size), data, length);
929 PRIV(output_size) += length;
935 /* Output count bytes of value */
938 _bfd_evax_output_fill (abfd, value, count)
944 evax_debug (6, "_bfd_evax_output_fill(val %02x times %d)\n", value, count);
949 memset (PRIV(output_buf) + PRIV(output_size), value, count);
950 PRIV(output_size) += count;
955 /* this hash routine borrowed from GNU-EMACS, and strengthened slightly ERY*/
961 register const unsigned char *p = (unsigned char *) ptr;
962 register const unsigned char *end = p + strlen (ptr);
963 register unsigned char c;
964 register int hash = 0;
969 hash = ((hash << 3) + (hash << 15) + (hash >> 28) + c);
974 /* Generate a Case-Hacked VMS symbol name (limited to 64 chars). */
976 _bfd_evax_case_hack_symbol (abfd, in)
984 const char *old_name;
986 int destructor = 0; /*hack to allow for case sens in a destructor*/
988 int case_hack_bits = 0;
990 static char hex_table[16] =
991 {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
993 static char outbuf[65];
997 evax_debug(4, "_bfd_evax_case_hack_symbol \"%s\"\n", in);
1001 /* Kill any leading "_". */ /* Why ? FIXME ! */
1003 if ((in[0] == '_') && ((in[1] > '9') || (in[1] < '0')))
1007 new_name = out; /* save this for later. */
1009 /* We may need to truncate the symbol, save the hash for later. */
1011 result = (strlen (in) > 56) ? hash_string (in) : 0;
1015 /* Do the case conversion. */
1017 i = 56; /* Maximum of 56 chars */
1019 while (*in && (--i >= 0))
1021 case_hack_bits <<= 1;
1024 if ((destructor == 1) && (i == 54))
1026 switch (PRIV(vms_name_mapping))
1029 if (isupper (*in)) {
1031 case_hack_bits |= 1;
1033 *out++ = islower (*in) ? toupper (*in++) : *in++;
1036 case 3: *out++ = *in++;
1039 if (islower (*in)) {
1042 *out++ = isupper (*in) ? tolower (*in++) : *in++;
1048 /* if we saw a dollar sign, we don't do case hacking. */
1050 if (PRIV(flag_no_hash_mixed_case) || saw_dollar)
1053 /* if we have more than 56 characters and everything is lowercase
1054 we can insert the full 64 characters. */
1058 /* We have more than 56 characters
1059 If we must add the case hack, then we have truncated the str. */
1062 if (case_hack_bits == 0)
1064 /* And so far they are all lower case:
1065 Check up to 8 more characters
1066 and ensure that they are lowercase. */
1068 for (i = 0; (in[i] != 0) && (i < 8); i++)
1069 if (isupper (in[i]) && !saw_dollar && !PRIV(flag_no_hash_mixed_case))
1075 if ((i == 8) || (in[i] == 0))
1077 /* They are: Copy up to 64 characters
1078 to the output string. */
1081 while ((--i >= 0) && (*in))
1083 switch (PRIV(vms_name_mapping))
1086 *out++ = islower (*in) ? toupper (*in++) : *in++;
1092 *out++ = isupper (*in) ? tolower (*in++) : *in++;
1100 /* If there were any uppercase characters in the name we
1101 take on the case hacking string. */
1103 /* Old behavior for regular GNU-C compiler */
1105 if (!PRIV(flag_hash_long_names))
1108 if ((case_hack_bits != 0) || (truncate == 1))
1113 for (i = 0; i < 6; i++)
1115 *out++ = hex_table[case_hack_bits & 0xf];
1116 case_hack_bits >>= 4;
1122 out = pnt; /* Cut back to 56 characters maximum */
1124 for (i = 0; i < 7; i++)
1126 init = result & 0x01f;
1127 *out++ = (init < 10) ? ('0' + init) : ('A' + init - 10);
1128 result = result >> 5;
1136 evax_debug(4, "--> [%d]\"%s\"\n", strlen (outbuf), outbuf);
1140 && PRIV(flag_hash_long_names)
1141 && PRIV(flag_show_after_trunc))
1142 printf ("Symbol %s replaced by %s\n", old_name, new_name);