* ld-elf/note-1.s: Increase .foo size.
[binutils.git] / bfd / vms-misc.c
blob7a3368bc7b04745648e554a12ee93fd6dfe37e22
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, 2003, 2004, 2005
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., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */
22 #if __STDC__
23 #include <stdarg.h>
24 #endif
26 #include "bfd.h"
27 #include "sysdep.h"
28 #include "bfdlink.h"
29 #include "libbfd.h"
31 #include "vms.h"
33 #if VMS_DEBUG
34 /* Debug functions. */
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
41 levels:
42 1 toplevel bfd calls (functions from the bfd vector)
43 2 functions called by bfd calls
44 ...
45 9 almost everything
47 level is also indentation level. Indentation is performed
48 if level > 0. */
50 void
51 _bfd_vms_debug (int level, char *format, ...)
53 static int min_level = -1;
54 static FILE *output = NULL;
55 char *eptr;
56 va_list args;
57 int abslvl = (level > 0) ? level : - level;
59 if (min_level == -1)
61 if ((eptr = getenv ("VMS_DEBUG")) != NULL)
63 min_level = atoi (eptr);
64 output = stderr;
66 else
67 min_level = 0;
69 if (output == NULL)
70 return;
71 if (abslvl > min_level)
72 return;
74 while (--level>0)
75 fprintf (output, " ");
76 va_start (args, format);
77 vfprintf (output, format, args);
78 fflush (output);
79 va_end (args);
82 /* A debug function
83 hex dump 'size' bytes starting at 'ptr'. */
85 void
86 _bfd_hexdump (int level,
87 unsigned char *ptr,
88 int size,
89 int offset)
91 unsigned char *lptr = ptr;
92 int count = 0;
93 long start = offset;
95 while (size-- > 0)
97 if ((count%16) == 0)
98 vms_debug (level, "%08lx:", start);
99 vms_debug (-level, " %02x", *ptr++);
100 count++;
101 start++;
102 if (size == 0)
104 while ((count%16) != 0)
106 vms_debug (-level, " ");
107 count++;
110 if ((count%16) == 0)
112 vms_debug (-level, " ");
113 while (lptr < ptr)
115 vms_debug (-level, "%c", (*lptr < 32)?'.':*lptr);
116 lptr++;
118 vms_debug (-level, "\n");
121 if ((count%16) != 0)
122 vms_debug (-level, "\n");
124 #endif
126 /* Hash functions
128 These are needed when reading an object file. */
130 /* Allocate new vms_hash_entry
131 keep the symbol name and a pointer to the bfd symbol in the table. */
133 struct bfd_hash_entry *
134 _bfd_vms_hash_newfunc (struct bfd_hash_entry *entry,
135 struct bfd_hash_table *table,
136 const char *string)
138 vms_symbol_entry *ret;
140 #if VMS_DEBUG
141 vms_debug (5, "_bfd_vms_hash_newfunc (%p, %p, %s)\n", entry, table, string);
142 #endif
144 if (entry == NULL)
146 ret = (vms_symbol_entry *)
147 bfd_hash_allocate (table, sizeof (vms_symbol_entry));
148 if (ret == NULL)
150 bfd_set_error (bfd_error_no_memory);
151 return NULL;
153 entry = (struct bfd_hash_entry *) ret;
156 /* Call the allocation method of the base class. */
157 ret = (vms_symbol_entry *) bfd_hash_newfunc (entry, table, string);
158 #if VMS_DEBUG
159 vms_debug (6, "_bfd_vms_hash_newfunc ret %p\n", ret);
160 #endif
162 ret->symbol = NULL;
164 return (struct bfd_hash_entry *)ret;
167 /* Object file input functions. */
169 /* Return type and length from record header (buf) on Alpha. */
171 void
172 _bfd_vms_get_header_values (bfd * abfd ATTRIBUTE_UNUSED,
173 unsigned char *buf,
174 int *type,
175 int *length)
177 if (type != 0)
178 *type = bfd_getl16 (buf);
179 buf += 2;
180 if (length != 0)
181 *length = bfd_getl16 (buf);
183 #if VMS_DEBUG
184 vms_debug (10, "_bfd_vms_get_header_values type %x, length %x\n", (type?*type:0), (length?*length:0));
185 #endif
188 /* Get next record from object file to vms_buf.
189 Set PRIV(buf_size) and return it
191 This is a little tricky since it should be portable.
193 The openVMS object file has 'variable length' which means that
194 read() returns data in chunks of (hopefully) correct and expected
195 size. The linker (and other tools on vms) depend on that. Unix doesn't
196 know about 'formatted' files, so reading and writing such an object
197 file in a unix environment is not trivial.
199 With the tool 'file' (available on all vms ftp sites), one
200 can view and change the attributes of a file. Changing from
201 'variable length' to 'fixed length, 512 bytes' reveals the
202 record length at the first 2 bytes of every record. The same
203 happens during the transfer of object files from vms to unix,
204 at least with ucx, dec's implementation of tcp/ip.
206 The vms format repeats the length at bytes 2 & 3 of every record.
208 On the first call (file_format == FF_UNKNOWN) we check if
209 the first and the third byte pair (!) of the record match.
210 If they do it's an object file in an unix environment or with
211 wrong attributes (FF_FOREIGN), else we should be in a vms
212 environment where read() returns the record size (FF_NATIVE).
214 Reading is always done in 2 steps.
215 First just the record header is read and the length extracted
216 by get_header_values,
217 then the read buffer is adjusted and the remaining bytes are
218 read in.
220 All file i/o is always done on even file positions. */
223 _bfd_vms_get_record (bfd * abfd)
225 int test_len, test_start, remaining;
226 unsigned char *vms_buf;
228 #if VMS_DEBUG
229 vms_debug (8, "_bfd_vms_get_record\n");
230 #endif
232 /* Minimum is 6 bytes on Alpha
233 (2 bytes length, 2 bytes record id, 2 bytes length repeated)
235 On the VAX there's no length information in the record
236 so start with OBJ_S_C_MAXRECSIZ. */
238 if (PRIV (buf_size) == 0)
240 bfd_size_type amt;
242 if (PRIV (is_vax))
244 amt = OBJ_S_C_MAXRECSIZ;
245 PRIV (file_format) = FF_VAX;
247 else
248 amt = 6;
249 PRIV (vms_buf) = bfd_malloc (amt);
250 PRIV (buf_size) = amt;
253 vms_buf = PRIV (vms_buf);
255 if (vms_buf == 0)
256 return -1;
258 switch (PRIV (file_format))
260 case FF_UNKNOWN:
261 case FF_FOREIGN:
262 test_len = 6; /* Probe 6 bytes. */
263 test_start = 2; /* Where the record starts. */
264 break;
266 case FF_NATIVE:
267 test_len = 4;
268 test_start = 0;
269 break;
271 default:
272 case FF_VAX:
273 test_len = 0;
274 test_start = 0;
275 break;
278 /* Skip odd alignment byte. */
280 if (bfd_tell (abfd) & 1)
282 if (bfd_bread (PRIV (vms_buf), (bfd_size_type) 1, abfd) != 1)
284 bfd_set_error (bfd_error_file_truncated);
285 return 0;
289 /* Read the record header on Alpha. */
290 if ((test_len != 0)
291 && (bfd_bread (PRIV (vms_buf), (bfd_size_type) test_len, abfd)
292 != (bfd_size_type) test_len))
294 bfd_set_error (bfd_error_file_truncated);
295 return 0;
298 /* Check file format on first call. */
299 if (PRIV (file_format) == FF_UNKNOWN)
300 { /* Record length repeats ? */
301 if (vms_buf[0] == vms_buf[4]
302 && vms_buf[1] == vms_buf[5])
304 PRIV (file_format) = FF_FOREIGN; /* Y: foreign environment. */
305 test_start = 2;
307 else
309 PRIV (file_format) = FF_NATIVE; /* N: native environment. */
310 test_start = 0;
314 if (PRIV (is_vax))
316 PRIV (rec_length) = bfd_bread (vms_buf, (bfd_size_type) PRIV (buf_size),
317 abfd);
318 if (PRIV (rec_length) <= 0)
320 bfd_set_error (bfd_error_file_truncated);
321 return 0;
323 PRIV (vms_rec) = vms_buf;
325 else
327 /* Alpha. */
328 /* Extract vms record length. */
330 _bfd_vms_get_header_values (abfd, vms_buf + test_start, NULL,
331 & PRIV (rec_length));
333 if (PRIV (rec_length) <= 0)
335 bfd_set_error (bfd_error_file_truncated);
336 return 0;
339 /* That's what the linker manual says. */
341 if (PRIV (rec_length) > EOBJ_S_C_MAXRECSIZ)
343 bfd_set_error (bfd_error_file_truncated);
344 return 0;
347 /* Adjust the buffer. */
349 if (PRIV (rec_length) > PRIV (buf_size))
351 PRIV (vms_buf) = bfd_realloc (vms_buf,
352 (bfd_size_type) PRIV (rec_length));
353 vms_buf = PRIV (vms_buf);
354 if (vms_buf == 0)
355 return -1;
356 PRIV (buf_size) = PRIV (rec_length);
359 /* Read the remaining record. */
360 remaining = PRIV (rec_length) - test_len + test_start;
362 #if VMS_DEBUG
363 vms_debug (10, "bfd_bread remaining %d\n", remaining);
364 #endif
365 if (bfd_bread (vms_buf + test_len, (bfd_size_type) remaining, abfd) !=
366 (bfd_size_type) remaining)
368 bfd_set_error (bfd_error_file_truncated);
369 return 0;
371 PRIV (vms_rec) = vms_buf + test_start;
374 #if VMS_DEBUG
375 vms_debug (11, "bfd_bread rec_length %d\n", PRIV (rec_length));
376 #endif
378 return PRIV (rec_length);
381 /* Get next vms record from file
382 update vms_rec and rec_length to new (remaining) values. */
385 _bfd_vms_next_record (bfd * abfd)
387 #if VMS_DEBUG
388 vms_debug (8, "_bfd_vms_next_record (len %d, size %d)\n",
389 PRIV (rec_length), PRIV (rec_size));
390 #endif
392 if (PRIV (rec_length) > 0)
393 PRIV (vms_rec) += PRIV (rec_size);
394 else
396 if (_bfd_vms_get_record (abfd) <= 0)
397 return -1;
400 if (!PRIV (vms_rec) || !PRIV (vms_buf)
401 || PRIV (vms_rec) >= (PRIV (vms_buf) + PRIV (buf_size)))
402 return -1;
404 if (PRIV (is_vax))
406 PRIV (rec_type) = *(PRIV (vms_rec));
407 PRIV (rec_size) = PRIV (rec_length);
409 else
410 _bfd_vms_get_header_values (abfd, PRIV (vms_rec), &PRIV (rec_type),
411 &PRIV (rec_size));
413 PRIV (rec_length) -= PRIV (rec_size);
415 #if VMS_DEBUG
416 vms_debug (8, "_bfd_vms_next_record: rec %p, size %d, length %d, type %d\n",
417 PRIV (vms_rec), PRIV (rec_size), PRIV (rec_length),
418 PRIV (rec_type));
419 #endif
421 return PRIV (rec_type);
424 /* Copy sized string (string with fixed length) to new allocated area
425 size is string length (size of record) */
427 char *
428 _bfd_vms_save_sized_string (unsigned char *str, int size)
430 char *newstr = bfd_malloc ((bfd_size_type) size + 1);
432 if (newstr == NULL)
433 return NULL;
434 strncpy (newstr, (char *) str, (size_t) size);
435 newstr[size] = 0;
437 return newstr;
440 /* Copy counted string (string with length at first byte) to new allocated area
441 ptr points to length byte on entry */
443 char *
444 _bfd_vms_save_counted_string (unsigned char *ptr)
446 int len = *ptr++;
448 return _bfd_vms_save_sized_string (ptr, len);
451 /* Stack routines for vms ETIR commands. */
453 /* Push value and section index. */
455 void
456 _bfd_vms_push (bfd * abfd, uquad val, int psect)
458 static int last_psect;
460 #if VMS_DEBUG
461 vms_debug (4, "<push %016lx (%d) at %d>\n", val, psect, PRIV (stackptr));
462 #endif
464 if (psect >= 0)
465 last_psect = psect;
467 PRIV (stack[PRIV (stackptr)]).value = val;
468 PRIV (stack[PRIV (stackptr)]).psect = last_psect;
469 PRIV (stackptr)++;
470 if (PRIV (stackptr) >= STACKSIZE)
472 bfd_set_error (bfd_error_bad_value);
473 (*_bfd_error_handler) (_("Stack overflow (%d) in _bfd_vms_push"), PRIV (stackptr));
474 exit (1);
478 /* Pop value and section index. */
480 uquad
481 _bfd_vms_pop (bfd * abfd, int *psect)
483 uquad value;
485 if (PRIV (stackptr) == 0)
487 bfd_set_error (bfd_error_bad_value);
488 (*_bfd_error_handler) (_("Stack underflow in _bfd_vms_pop"));
489 exit (1);
491 PRIV (stackptr)--;
492 value = PRIV (stack[PRIV (stackptr)]).value;
493 if ((psect != NULL) && (PRIV (stack[PRIV (stackptr)]).psect >= 0))
494 *psect = PRIV (stack[PRIV (stackptr)]).psect;
496 #if VMS_DEBUG
497 vms_debug (4, "<pop %016lx(%d)>\n", value, PRIV (stack[PRIV (stackptr)]).psect);
498 #endif
500 return value;
503 /* Object file output functions. */
505 /* GAS tends to write sections in little chunks (bfd_set_section_contents)
506 which we can't use directly. So we save the little chunks in linked
507 lists (one per section) and write them later. */
509 /* Add a new vms_section structure to vms_section_table
510 - forward chaining -. */
512 static vms_section *
513 add_new_contents (bfd * abfd, sec_ptr section)
515 vms_section *sptr, *newptr;
517 sptr = PRIV (vms_section_table)[section->index];
518 if (sptr != NULL)
519 return sptr;
521 newptr = bfd_alloc (abfd, (bfd_size_type) sizeof (vms_section));
522 if (newptr == NULL)
523 return NULL;
524 newptr->contents = bfd_alloc (abfd, section->size);
525 if (newptr->contents == NULL)
526 return NULL;
527 newptr->offset = 0;
528 newptr->size = section->size;
529 newptr->next = 0;
530 PRIV (vms_section_table)[section->index] = newptr;
531 return newptr;
534 /* Save section data & offset to a vms_section structure
535 vms_section_table[] holds the vms_section chain. */
537 bfd_boolean
538 _bfd_save_vms_section (bfd * abfd,
539 sec_ptr section,
540 const void * data,
541 file_ptr offset,
542 bfd_size_type count)
544 vms_section *sptr;
546 if (section->index >= VMS_SECTION_COUNT)
548 bfd_set_error (bfd_error_nonrepresentable_section);
549 return FALSE;
551 if (count == (bfd_size_type)0)
552 return TRUE;
553 sptr = add_new_contents (abfd, section);
554 if (sptr == NULL)
555 return FALSE;
556 memcpy (sptr->contents + offset, data, (size_t) count);
558 return TRUE;
561 /* Get vms_section pointer to saved contents for section # index */
563 vms_section *
564 _bfd_get_vms_section (bfd * abfd, int index)
566 if (index >= VMS_SECTION_COUNT)
568 bfd_set_error (bfd_error_nonrepresentable_section);
569 return NULL;
571 return PRIV (vms_section_table)[index];
574 /* Object output routines. */
576 /* Begin new record or record header
577 write 2 bytes rectype
578 write 2 bytes record length (filled in at flush)
579 write 2 bytes header type (ommitted if rechead == -1). */
581 void
582 _bfd_vms_output_begin (bfd * abfd, int rectype, int rechead)
584 #if VMS_DEBUG
585 vms_debug (6, "_bfd_vms_output_begin (type %d, head %d)\n", rectype,
586 rechead);
587 #endif
589 _bfd_vms_output_short (abfd, (unsigned int) rectype);
591 /* Save current output position to fill in length later. */
593 if (PRIV (push_level) > 0)
594 PRIV (length_pos) = PRIV (output_size);
596 #if VMS_DEBUG
597 vms_debug (6, "_bfd_vms_output_begin: length_pos = %d\n",
598 PRIV (length_pos));
599 #endif
601 /* Placeholder for length. */
602 _bfd_vms_output_short (abfd, 0);
604 if (rechead != -1)
605 _bfd_vms_output_short (abfd, (unsigned int) rechead);
608 /* Set record/subrecord alignment. */
610 void
611 _bfd_vms_output_alignment (bfd * abfd, int alignto)
613 #if VMS_DEBUG
614 vms_debug (6, "_bfd_vms_output_alignment (%d)\n", alignto);
615 #endif
617 PRIV (output_alignment) = alignto;
620 /* Prepare for subrecord fields. */
622 void
623 _bfd_vms_output_push (bfd * abfd)
625 #if VMS_DEBUG
626 vms_debug (6, "vms_output_push (pushed_size = %d)\n", PRIV (output_size));
627 #endif
629 PRIV (push_level)++;
630 PRIV (pushed_size) = PRIV (output_size);
633 /* End of subrecord fields. */
635 void
636 _bfd_vms_output_pop (bfd * abfd)
638 #if VMS_DEBUG
639 vms_debug (6, "vms_output_pop (pushed_size = %d)\n", PRIV (pushed_size));
640 #endif
642 _bfd_vms_output_flush (abfd);
643 PRIV (length_pos) = 2;
645 #if VMS_DEBUG
646 vms_debug (6, "vms_output_pop: length_pos = %d\n", PRIV (length_pos));
647 #endif
649 PRIV (pushed_size) = 0;
650 PRIV (push_level)--;
653 /* Flush unwritten output, ends current record. */
655 void
656 _bfd_vms_output_flush (bfd * abfd)
658 int real_size = PRIV (output_size);
659 int aligncount;
660 int length;
662 #if VMS_DEBUG
663 vms_debug (6, "_bfd_vms_output_flush (real_size = %d, pushed_size %d at lenpos %d)\n",
664 real_size, PRIV (pushed_size), PRIV (length_pos));
665 #endif
667 if (PRIV (push_level) > 0)
668 length = real_size - PRIV (pushed_size);
669 else
670 length = real_size;
672 if (length == 0)
673 return;
674 aligncount = (PRIV (output_alignment)
675 - (length % PRIV (output_alignment))) % PRIV (output_alignment);
677 #if VMS_DEBUG
678 vms_debug (6, "align: adding %d bytes\n", aligncount);
679 #endif
681 while (aligncount-- > 0)
683 PRIV (output_buf)[real_size++] = 0;
684 length++;
687 /* Put length to buffer. */
688 PRIV (output_size) = PRIV (length_pos);
689 _bfd_vms_output_short (abfd, (unsigned int) length);
691 if (PRIV (push_level) == 0)
693 #ifndef VMS
694 /* Write length first, see FF_FOREIGN in the input routines. */
695 fwrite (PRIV (output_buf) + 2, 2, 1, (FILE *) abfd->iostream);
696 #endif
697 fwrite (PRIV (output_buf), (size_t) real_size, 1,
698 (FILE *) abfd->iostream);
700 PRIV (output_size) = 0;
702 else
704 PRIV (output_size) = real_size;
705 PRIV (pushed_size) = PRIV (output_size);
709 /* End record output. */
711 void
712 _bfd_vms_output_end (bfd * abfd)
714 #if VMS_DEBUG
715 vms_debug (6, "_bfd_vms_output_end\n");
716 #endif
718 _bfd_vms_output_flush (abfd);
721 /* Check remaining buffer size
723 Return what's left. */
726 _bfd_vms_output_check (bfd * abfd, int size)
728 #if VMS_DEBUG
729 vms_debug (6, "_bfd_vms_output_check (%d)\n", size);
730 #endif
732 return (MAX_OUTREC_SIZE - (PRIV (output_size) + size + MIN_OUTREC_LUFT));
735 /* Output byte (8 bit) value. */
737 void
738 _bfd_vms_output_byte (bfd * abfd, unsigned int value)
740 #if VMS_DEBUG
741 vms_debug (6, "_bfd_vms_output_byte (%02x)\n", value);
742 #endif
744 bfd_put_8 (abfd, value & 0xff, PRIV (output_buf) + PRIV (output_size));
745 PRIV (output_size) += 1;
748 /* Output short (16 bit) value. */
750 void
751 _bfd_vms_output_short (bfd * abfd, unsigned int value)
753 #if VMS_DEBUG
754 vms_debug (6, "_bfd_vms_output_short (%04x)\n", value);
755 #endif
757 bfd_put_16 (abfd, (bfd_vma) value & 0xffff,
758 PRIV (output_buf) + PRIV (output_size));
759 PRIV (output_size) += 2;
762 /* Output long (32 bit) value. */
764 void
765 _bfd_vms_output_long (bfd * abfd, unsigned long value)
767 #if VMS_DEBUG
768 vms_debug (6, "_bfd_vms_output_long (%08lx)\n", value);
769 #endif
771 bfd_put_32 (abfd, (bfd_vma) value, PRIV (output_buf) + PRIV (output_size));
772 PRIV (output_size) += 4;
775 /* Output quad (64 bit) value. */
777 void
778 _bfd_vms_output_quad (bfd * abfd, uquad value)
780 #if VMS_DEBUG
781 vms_debug (6, "_bfd_vms_output_quad (%016lx)\n", value);
782 #endif
784 bfd_put_64(abfd, value, PRIV (output_buf) + PRIV (output_size));
785 PRIV (output_size) += 8;
788 /* Output c-string as counted string. */
790 void
791 _bfd_vms_output_counted (bfd * abfd, char *value)
793 int len;
795 #if VMS_DEBUG
796 vms_debug (6, "_bfd_vms_output_counted (%s)\n", value);
797 #endif
799 len = strlen (value);
800 if (len == 0)
802 (*_bfd_error_handler) (_("_bfd_vms_output_counted called with zero bytes"));
803 return;
805 if (len > 255)
807 (*_bfd_error_handler) (_("_bfd_vms_output_counted called with too many bytes"));
808 return;
810 _bfd_vms_output_byte (abfd, (unsigned int) len & 0xff);
811 _bfd_vms_output_dump (abfd, (unsigned char *) value, len);
814 /* Output character area. */
816 void
817 _bfd_vms_output_dump (bfd * abfd,
818 unsigned char *data,
819 int length)
821 #if VMS_DEBUG
822 vms_debug (6, "_bfd_vms_output_dump (%d)\n", length);
823 #endif
825 if (length == 0)
826 return;
828 memcpy (PRIV (output_buf) + PRIV (output_size), data, (size_t) length);
829 PRIV (output_size) += length;
832 /* Output count bytes of value. */
834 void
835 _bfd_vms_output_fill (bfd * abfd,
836 int value,
837 int count)
839 #if VMS_DEBUG
840 vms_debug (6, "_bfd_vms_output_fill (val %02x times %d)\n", value, count);
841 #endif
843 if (count == 0)
844 return;
845 memset (PRIV (output_buf) + PRIV (output_size), value, (size_t) count);
846 PRIV (output_size) += count;
849 /* This hash routine borrowed from GNU-EMACS, and strengthened slightly. ERY. */
851 static int
852 hash_string (const char *ptr)
854 const unsigned char *p = (unsigned char *) ptr;
855 const unsigned char *end = p + strlen (ptr);
856 unsigned char c;
857 int hash = 0;
859 while (p != end)
861 c = *p++;
862 hash = ((hash << 3) + (hash << 15) + (hash >> 28) + c);
864 return hash;
867 /* Generate a length-hashed VMS symbol name (limited to maxlen chars). */
869 char *
870 _bfd_vms_length_hash_symbol (bfd * abfd, const char *in, int maxlen)
872 long int result;
873 int in_len;
874 char *new_name;
875 const char *old_name;
876 int i;
877 static char outbuf[EOBJ_S_C_SYMSIZ+1];
878 char *out = outbuf;
880 #if VMS_DEBUG
881 vms_debug (4, "_bfd_vms_length_hash_symbol \"%s\"\n", in);
882 #endif
884 if (maxlen > EOBJ_S_C_SYMSIZ)
885 maxlen = EOBJ_S_C_SYMSIZ;
887 /* Save this for later. */
888 new_name = out;
890 /* We may need to truncate the symbol, save the hash for later. */
891 in_len = strlen (in);
893 result = (in_len > maxlen) ? hash_string (in) : 0;
895 old_name = in;
897 /* Do the length checking. */
898 if (in_len <= maxlen)
899 i = in_len;
900 else
902 if (PRIV (flag_hash_long_names))
903 i = maxlen-9;
904 else
905 i = maxlen;
908 strncpy (out, in, (size_t) i);
909 in += i;
910 out += i;
912 if ((in_len > maxlen)
913 && PRIV (flag_hash_long_names))
914 sprintf (out, "_%08lx", result);
915 else
916 *out = 0;
918 #if VMS_DEBUG
919 vms_debug (4, "--> [%d]\"%s\"\n", strlen (outbuf), outbuf);
920 #endif
922 if (in_len > maxlen
923 && PRIV (flag_hash_long_names)
924 && PRIV (flag_show_after_trunc))
925 printf (_("Symbol %s replaced by %s\n"), old_name, new_name);
927 return outbuf;
930 /* Allocate and initialize a new symbol. */
932 static asymbol *
933 new_symbol (bfd * abfd, char *name)
935 asymbol *symbol;
937 #if VMS_DEBUG
938 _bfd_vms_debug (7, "new_symbol %s\n", name);
939 #endif
941 symbol = bfd_make_empty_symbol (abfd);
942 if (symbol == 0)
943 return symbol;
944 symbol->name = name;
945 symbol->section = bfd_make_section (abfd, BFD_UND_SECTION_NAME);
947 return symbol;
950 /* Allocate and enter a new private symbol. */
952 vms_symbol_entry *
953 _bfd_vms_enter_symbol (bfd * abfd, char *name)
955 vms_symbol_entry *entry;
957 #if VMS_DEBUG
958 _bfd_vms_debug (6, "_bfd_vms_enter_symbol %s\n", name);
959 #endif
961 entry = (vms_symbol_entry *)
962 bfd_hash_lookup (PRIV (vms_symbol_table), name, FALSE, FALSE);
963 if (entry == 0)
965 #if VMS_DEBUG
966 _bfd_vms_debug (8, "creating hash entry for %s\n", name);
967 #endif
968 entry = (vms_symbol_entry *) bfd_hash_lookup (PRIV (vms_symbol_table),
969 name, TRUE, FALSE);
970 if (entry != 0)
972 asymbol *symbol;
973 symbol = new_symbol (abfd, name);
974 if (symbol != 0)
976 entry->symbol = symbol;
977 PRIV (gsd_sym_count)++;
978 abfd->symcount++;
980 else
981 entry = 0;
983 else
984 (*_bfd_error_handler) (_("failed to enter %s"), name);
986 else
988 #if VMS_DEBUG
989 _bfd_vms_debug (8, "found hash entry for %s\n", name);
990 #endif
993 #if VMS_DEBUG
994 _bfd_vms_debug (7, "-> entry %p, entry->symbol %p\n", entry, entry->symbol);
995 #endif
996 return entry;