1 /* evax-misc.c -- Miscellaneous functions for ALPHA EVAX (openVMS/Alpha) files.
2 Copyright 1996, 1997 Free Software Foundation, Inc.
5 of proGIS Softwareentwicklung, Aachen, Germany
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. */
34 /*-----------------------------------------------------------------------------*/
38 /* debug function for all evax extensions
39 evaluates environment variable EVAX_DEBUG for a
40 numerical value on the first call
41 all error levels below this value are printed
44 1 toplevel bfd calls (functions from the bfd vector)
45 2 functions called by bfd calls
49 level is also identation level. Indentation is performed
55 _bfd_evax_debug (int level, char *format, ...)
57 static int min_level = -1;
58 static FILE *output = NULL;
61 int abslvl = (level > 0)?level:-level;
65 if ((eptr = getenv("EVAX_DEBUG")) != NULL)
67 min_level = atoi(eptr);
75 if (abslvl > min_level)
80 va_start(args, format);
81 vfprintf(output, format, args);
88 #else /* not __STDC__ */
91 _bfd_evax_debug (level, format, a1, a2, a3, a4, a5, a6)
94 long a1; long a2; long a3;
95 long a4; long a5; long a6;
97 static int min_level = -1;
98 static FILE *output = NULL;
103 if ((eptr = getenv("EVAX_DEBUG")) != NULL)
105 min_level = atoi(eptr);
113 if (level > min_level)
117 fprintf(output, " ");
118 fprintf(output, format, a1, a2, a3, a4, a5, a6);
123 #endif /* __STDC__ */
127 hex dump 'size' bytes starting at 'ptr' */
130 _bfd_hexdump (level, ptr, size, offset)
136 unsigned char *lptr = ptr;
143 evax_debug (level, "%08lx:", start);
144 evax_debug (-level, " %02x", *ptr++);
149 while ((count%16) != 0)
151 evax_debug (-level, " ");
157 evax_debug (-level, " ");
160 evax_debug (-level, "%c", (*lptr < 32)?'.':*lptr);
163 evax_debug (-level, "\n");
167 evax_debug (-level, "\n");
176 These are needed when reading an object file. */
178 /* allocate new evax_hash_entry
179 keep the symbol name and a pointer to the bfd symbol in the table */
181 struct bfd_hash_entry *
182 _bfd_evax_hash_newfunc (entry, table, string)
183 struct bfd_hash_entry *entry;
184 struct bfd_hash_table *table;
187 evax_symbol_entry *ret = (evax_symbol_entry *)entry;
190 evax_debug (5, "_bfd_evax_hash_newfunc(%p, %p, %s)\n", entry, table, string);
193 if (ret == (evax_symbol_entry *)NULL)
194 ret = ((evax_symbol_entry *) bfd_hash_allocate (table, sizeof (evax_symbol_entry)));
195 if (ret == (evax_symbol_entry *)NULL)
197 bfd_set_error (bfd_error_no_memory);
198 return (struct bfd_hash_entry *)NULL;
200 ret = (evax_symbol_entry *) bfd_hash_newfunc ((struct bfd_hash_entry *)ret, table, string);
202 ret->symbol = (asymbol *)NULL;
204 return (struct bfd_hash_entry *)ret;
208 /* object file input functions */
210 /* Return type and length from record header (buf) */
213 _bfd_evax_get_header_values (abfd, buf, type, length)
220 *type = bfd_getl16 (buf);
223 *length = bfd_getl16 (buf);
229 /* Get next record from object file to evax_buf
230 set PRIV(buf_size) and return it
232 this is a little tricky since it should be portable.
234 the openVMS/AXP object file has 'variable length' which means that
235 read() returns data in chunks of (hopefully) correct and expected
236 size. The linker (and other tools on vms) depend on that. Unix doesn't
237 know about 'formatted' files, so reading and writing such an object
238 file in a unix environment is not trivial.
240 With the tool 'file' (available on all vms ftp sites), one
241 can view and change the attributes of a file. Changing from
242 'variable length' to 'fixed length, 512 bytes' reveals the
243 record length at the first 2 bytes of every record. The same
244 happens during the transfer of object files from vms to unix,
245 at least with ucx, dec's implementation of tcp/ip.
247 The EVAX format repeats the length at bytes 2 & 3 of every record.
249 On the first call (file_format == FF_UNKNOWN) we check if
250 the first and the third byte pair (!) of the record match.
251 If they do it's an object file in an unix environment or with
252 wrong attributes (FF_FOREIGN), else we should be in a vms
253 environment where read() returns the record size (FF_NATIVE).
255 reading is always done in 2 steps.
256 first just the record header is read and the length extracted
258 then the read buffer is adjusted and the remaining bytes are
261 all file i/o is always done on even file positions */
264 _bfd_evax_get_record (abfd)
267 int test_len, test_start, remaining;
268 unsigned char *evax_buf;
271 evax_debug (8, "_bfd_evax_get_record\n");
274 /* minimum is 6 bytes
275 (2 bytes length, 2 bytes record id, 2 bytes length repeated) */
277 if (PRIV(buf_size) == 0)
279 PRIV(evax_buf) = (unsigned char *) malloc (6);
281 evax_debug (9, "PRIV(evax_buf) %p\n", PRIV(evax_buf));
285 evax_buf = PRIV(evax_buf);
290 evax_debug (9, "can't alloc evax_buf\n");
292 bfd_set_error (bfd_error_no_memory);
296 switch (PRIV(file_format))
300 test_len = 6; /* probe 6 bytes */
301 test_start = 2; /* where the record starts */
310 /* skip odd alignment byte */
312 if (PRIV(file_format) == FF_FOREIGN)
315 if (bfd_tell (abfd) & 1)
318 evax_debug (10, "skip odd\n");
320 if (bfd_read (PRIV(evax_buf), 1, 1, abfd) != 1)
323 evax_debug (9, "skip odd failed\n");
325 bfd_set_error (bfd_error_file_truncated);
332 /* read the record header */
334 if (bfd_read (PRIV(evax_buf), 1, test_len, abfd) != test_len)
337 evax_debug (9, "can't bfd_read test %d bytes\n", test_len);
339 bfd_set_error (bfd_error_file_truncated);
343 /* check file format on first call */
345 if (PRIV(file_format) == FF_UNKNOWN)
346 { /* record length repeats ? */
347 if ( (evax_buf[0] == evax_buf[4])
348 && (evax_buf[1] == evax_buf[5]))
350 PRIV(file_format) = FF_FOREIGN; /* Y: foreign environment */
355 PRIV(file_format) = FF_NATIVE; /* N: native environment */
359 evax_debug (10, "File format is %s\n", (PRIV(file_format) == FF_FOREIGN)?"foreign":"native");
363 /* extract evax record length */
365 _bfd_evax_get_header_values (abfd, evax_buf+test_start, NULL,
368 if (PRIV(rec_length) <= 0)
370 bfd_set_error (bfd_error_file_truncated);
374 /* that's what the linker manual says */
376 if (PRIV(rec_length) > EOBJ_S_C_MAXRECSIZ)
378 bfd_set_error (bfd_error_file_truncated);
382 /* adjust the buffer */
384 if (PRIV(rec_length) > PRIV(buf_size))
386 PRIV(evax_buf) = (unsigned char *) realloc (evax_buf, PRIV(rec_length));
388 evax_debug (3, "adjusted the buffer (%p) from %d to %d\n", PRIV(evax_buf), PRIV(buf_size), PRIV(rec_length));
390 evax_buf = PRIV(evax_buf);
394 evax_debug (9, "can't realloc evax_buf to %d bytes\n", PRIV(rec_length));
396 bfd_set_error (bfd_error_no_memory);
399 PRIV(buf_size) = PRIV(rec_length);
402 /* read the remaining record */
404 remaining = PRIV(rec_length) - test_len + test_start;
406 if (bfd_read (evax_buf + test_len, 1, remaining, abfd) != remaining)
409 evax_debug (9, "can't bfd_read remaining %d bytes\n", remaining);
411 bfd_set_error (bfd_error_file_truncated);
415 PRIV(evax_rec) = evax_buf + test_start;
417 return PRIV(rec_length);
421 /* get next EVAX record from file
422 update evax_rec and rec_length to new (remaining) values */
425 _bfd_evax_next_record (abfd)
429 evax_debug (8, "_bfd_evax_next_record (len %d, size %d)\n",
430 PRIV(rec_length), PRIV(rec_size));
433 if (PRIV(rec_length) > 0)
435 PRIV(evax_rec) += PRIV(rec_size);
439 if (_bfd_evax_get_record (abfd) <= 0)
442 _bfd_evax_get_header_values (abfd, PRIV(evax_rec), &PRIV(rec_type),
444 PRIV(rec_length) -= PRIV(rec_size);
447 evax_debug (8, "_bfd_evax_next_record: rec %p, size %d, length %d, type %d\n",
448 PRIV(evax_rec), PRIV(rec_size), PRIV(rec_length),
452 return PRIV(rec_type);
457 /* Copy sized string (string with fixed length) to new allocated area
458 size is string length (size of record) */
461 _bfd_evax_save_sized_string (str, size)
465 char *newstr = bfd_malloc (size + 1);
469 strncpy (newstr, str, size);
475 /* Copy counted string (string with length at first byte) to new allocated area
476 ptr points to length byte on entry */
479 _bfd_evax_save_counted_string (ptr)
484 return _bfd_evax_save_sized_string (ptr, len);
488 /* stack routines for EVAX ETIR commands */
490 /* Push value and section index */
493 _bfd_evax_push (abfd, val, psect)
498 static int last_psect;
501 evax_debug (4, "<push %016lx(%d) at %d>\n", val, psect, PRIV(stackptr));
507 PRIV(stack[PRIV(stackptr)]).value = val;
508 PRIV(stack[PRIV(stackptr)]).psect = last_psect;
510 if (PRIV(stackptr) >= STACKSIZE)
512 bfd_set_error (bfd_error_bad_value);
519 /* Pop value and section index */
522 _bfd_evax_pop (abfd, psect)
528 if (PRIV(stackptr) == 0)
530 bfd_set_error (bfd_error_bad_value);
534 value = PRIV(stack[PRIV(stackptr)]).value;
535 if ((psect != NULL) && (PRIV(stack[PRIV(stackptr)]).psect >= 0))
536 *psect = PRIV(stack[PRIV(stackptr)]).psect;
539 evax_debug (4, "<pop %016lx(%d)>\n", value, PRIV(stack[PRIV(stackptr)]).psect);
546 /* object file output functions */
548 /* GAS tends to write sections in little chunks (bfd_set_section_contents)
549 which we can't use directly. So we save the little chunks in linked
550 lists (one per section) and write them later. */
552 /* Add a new evax_section structure to evax_section_table
553 - forward chaining - */
555 static evax_section *
556 add_new_contents (abfd, section)
560 evax_section *sptr, *newptr;
562 sptr = PRIV(evax_section_table)[section->index];
566 newptr = (evax_section *) bfd_malloc (sizeof (evax_section));
567 if (newptr == (evax_section *) NULL)
569 newptr->contents = (unsigned char *) bfd_alloc (abfd, (int)section->_raw_size);
570 if (newptr->contents == (unsigned char *)NULL)
573 newptr->size = section->_raw_size;
575 PRIV(evax_section_table)[section->index] = newptr;
580 /* Save section data & offset to an evax_section structure
581 evax_section_table[] holds the evax_section chain */
584 _bfd_save_evax_section (abfd, section, data, offset, count)
593 if (section->index >= EVAX_SECTION_COUNT)
595 bfd_set_error (bfd_error_nonrepresentable_section);
598 if (count == (bfd_size_type)0)
600 sptr = add_new_contents (abfd, section);
603 memcpy (sptr->contents + offset, data, (size_t) count);
609 /* Get evax_section pointer to saved contents for section # index */
612 _bfd_get_evax_section (abfd, index)
616 if (index >= EVAX_SECTION_COUNT)
618 bfd_set_error (bfd_error_nonrepresentable_section);
621 return PRIV(evax_section_table)[index];
625 /* Object output routines */
627 /* Begin new record or record header
628 write 2 bytes rectype
629 write 2 bytes record length (filled in at flush)
630 write 2 bytes header type (ommitted if rechead == -1) */
633 _bfd_evax_output_begin (abfd, rectype, rechead)
639 evax_debug (6, "_bfd_evax_output_begin(type %d, head %d)\n", rectype,
643 _bfd_evax_output_short (abfd,rectype);
645 /* save current output position to fill in lenght later */
647 if (PRIV(push_level) > 0)
648 PRIV(length_pos) = PRIV(output_size);
651 evax_debug (6, "_bfd_evax_output_begin: length_pos = %d\n",
655 _bfd_evax_output_short (abfd,0); /* placeholder for length */
658 _bfd_evax_output_short (abfd,rechead);
664 /* Set record/subrecord alignment */
667 _bfd_evax_output_alignment (abfd, alignto)
672 evax_debug (6, "_bfd_evax_output_alignment(%d)\n", alignto);
675 PRIV(output_alignment) = alignto;
680 /* Prepare for subrecord fields */
683 _bfd_evax_output_push (abfd)
687 evax_debug (6, "evax_output_push(pushed_size = %d)\n", PRIV(output_size));
691 PRIV(pushed_size) = PRIV(output_size);
696 /* End of subrecord fields */
699 _bfd_evax_output_pop (abfd)
703 evax_debug (6, "evax_output_pop(pushed_size = %d)\n", PRIV(pushed_size));
706 _bfd_evax_output_flush (abfd);
707 PRIV(length_pos) = 2;
710 evax_debug (6, "evax_output_pop: length_pos = %d\n", PRIV(length_pos));
713 PRIV(pushed_size) = 0;
719 /* Flush unwritten output, ends current record */
722 _bfd_evax_output_flush (abfd)
725 int real_size = PRIV(output_size);
730 evax_debug (6, "_bfd_evax_output_flush(real_size = %d, pushed_size %d at lenpos %d)\n",
731 real_size, PRIV(pushed_size), PRIV(length_pos));
734 if (PRIV(push_level) > 0)
735 length = real_size - PRIV(pushed_size);
741 aligncount = (PRIV(output_alignment)
742 - (length % PRIV(output_alignment))) % PRIV(output_alignment);
745 evax_debug (6, "align: adding %d bytes\n", aligncount);
748 while(aligncount-- > 0)
750 PRIV(output_buf)[real_size++] = 0;
752 /* this is why I *love* vms: inconsistency :-}
753 alignment is added to the subrecord length
754 but not to the record length */
755 if (PRIV(push_level) > 0)
760 /* put length to buffer */
761 PRIV(output_size) = PRIV(length_pos);
762 _bfd_evax_output_short (abfd, (unsigned int)length);
764 if (PRIV(push_level) == 0)
767 /* write length first, see FF_FOREIGN in the input routines */
768 fwrite (PRIV(output_buf)+2, 2, 1, (FILE *)abfd->iostream);
770 fwrite (PRIV(output_buf), real_size, 1, (FILE *)abfd->iostream);
772 PRIV(output_size) = 0;
776 PRIV(output_size) = real_size;
777 PRIV(pushed_size) = PRIV(output_size);
784 /* End record output */
787 _bfd_evax_output_end (abfd)
791 evax_debug (6, "_bfd_evax_output_end\n");
794 _bfd_evax_output_flush (abfd);
800 /* check remaining buffer size
802 return what's left. */
805 _bfd_evax_output_check (abfd, size)
810 evax_debug (6, "_bfd_evax_output_check(%d)\n", size);
813 return (MAX_OUTREC_SIZE - (PRIV(output_size) + size + MIN_OUTREC_LUFT));
817 /* Output byte (8 bit) value */
820 _bfd_evax_output_byte (abfd, value)
825 evax_debug (6, "_bfd_evax_output_byte(%02x)\n", value);
828 bfd_put_8 (abfd, value & 0xff, PRIV(output_buf) + PRIV(output_size));
829 PRIV(output_size) += 1;
834 /* Output short (16 bit) value */
837 _bfd_evax_output_short (abfd, value)
842 evax_debug (6, "_bfd_evax_output_short (%04x)\n", value);
845 bfd_put_16 (abfd, value & 0xffff, PRIV(output_buf) + PRIV(output_size));
846 PRIV(output_size) += 2;
851 /* Output long (32 bit) value */
854 _bfd_evax_output_long (abfd, value)
859 evax_debug (6, "_bfd_evax_output_long (%08lx)\n", value);
862 bfd_put_32 (abfd, value, PRIV(output_buf) + PRIV(output_size));
863 PRIV(output_size) += 4;
868 /* Output quad (64 bit) value */
871 _bfd_evax_output_quad (abfd, value)
876 evax_debug (6, "_bfd_evax_output_quad(%016lx)\n", value);
879 bfd_put_64(abfd, value, PRIV(output_buf) + PRIV(output_size));
880 PRIV(output_size) += 8;
885 /* Output c-string as counted string */
888 _bfd_evax_output_counted (abfd, value)
895 evax_debug (6, "_bfd_evax_output_counted(%s)\n", value);
898 len = strlen (value);
901 (*_bfd_error_handler) ("_bfd_evax_output_counted called with zero bytes");
906 (*_bfd_error_handler) ("_bfd_evax_output_counted called with too many bytes");
909 _bfd_evax_output_byte (abfd, len & 0xff);
910 _bfd_evax_output_dump (abfd, (unsigned char *)value, len);
914 /* Output character area */
917 _bfd_evax_output_dump (abfd, data, length)
923 evax_debug (6, "_bfd_evax_output_dump(%d)\n", length);
929 memcpy (PRIV(output_buf) + PRIV(output_size), data, length);
930 PRIV(output_size) += length;
936 /* Output count bytes of value */
939 _bfd_evax_output_fill (abfd, value, count)
945 evax_debug (6, "_bfd_evax_output_fill(val %02x times %d)\n", value, count);
950 memset (PRIV(output_buf) + PRIV(output_size), value, count);
951 PRIV(output_size) += count;
956 /* this hash routine borrowed from GNU-EMACS, and strengthened slightly ERY*/
962 register const unsigned char *p = (unsigned char *) ptr;
963 register const unsigned char *end = p + strlen (ptr);
964 register unsigned char c;
965 register int hash = 0;
970 hash = ((hash << 3) + (hash << 15) + (hash >> 28) + c);
975 /* Generate a length-hashed VMS symbol name (limited to 64 chars). */
978 _bfd_evax_length_hash_symbol (abfd, in)
987 const char *old_name;
989 static char outbuf[65];
993 evax_debug(4, "_bfd_evax_length_hash_symbol \"%s\"\n", in);
996 new_name = out; /* save this for later. */
998 /* We may need to truncate the symbol, save the hash for later. */
1000 in_len = strlen (in);
1002 result = (in_len > 64) ? hash_string (in) : 0;
1006 /* Do the length checking. */
1013 strncpy (out, in, i);
1018 && PRIV(flag_hash_long_names))
1019 sprintf (out, "_%08x", result);
1024 evax_debug(4, "--> [%d]\"%s\"\n", strlen (outbuf), outbuf);
1028 && PRIV(flag_hash_long_names)
1029 && PRIV(flag_show_after_trunc))
1030 printf ("Symbol %s replaced by %s\n", old_name, new_name);