OSDN Git Service

Update the address and phone number of the FSF organization in the GPL notices
[pf3gnuchains/pf3gnuchains4x.git] / bfd / vms-misc.c
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.
5
6    Written by Klaus K"ampf (kkaempf@rmi.de)
7
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.
12
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.
17
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.  */
21
22 #if __STDC__
23 #include <stdarg.h>
24 #endif
25
26 #include "bfd.h"
27 #include "sysdep.h"
28 #include "bfdlink.h"
29 #include "libbfd.h"
30
31 #include "vms.h"
32 \f
33 #if VMS_DEBUG
34 /* Debug functions.  */
35
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
40
41    levels:
42    1    toplevel bfd calls (functions from the bfd vector)
43    2    functions called by bfd calls
44    ...
45    9    almost everything
46
47    level is also indentation level. Indentation is performed
48    if level > 0.  */
49
50 void
51 _bfd_vms_debug (int level, char *format, ...)
52 {
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;
58
59   if (min_level == -1)
60     {
61       if ((eptr = getenv ("VMS_DEBUG")) != NULL)
62         {
63           min_level = atoi (eptr);
64           output = stderr;
65         }
66       else
67         min_level = 0;
68     }
69   if (output == NULL)
70     return;
71   if (abslvl > min_level)
72     return;
73
74   while (--level>0)
75     fprintf (output, " ");
76   va_start (args, format);
77   vfprintf (output, format, args);
78   fflush (output);
79   va_end (args);
80 }
81
82 /* A debug function
83    hex dump 'size' bytes starting at 'ptr'.  */
84
85 void
86 _bfd_hexdump (int level,
87               unsigned char *ptr,
88               int size,
89               int offset)
90 {
91   unsigned char *lptr = ptr;
92   int count = 0;
93   long start = offset;
94
95   while (size-- > 0)
96     {
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)
103         {
104           while ((count%16) != 0)
105             {
106               vms_debug (-level, "   ");
107               count++;
108             }
109         }
110       if ((count%16) == 0)
111         {
112           vms_debug (-level, " ");
113           while (lptr < ptr)
114             {
115               vms_debug (-level, "%c", (*lptr < 32)?'.':*lptr);
116               lptr++;
117             }
118           vms_debug (-level, "\n");
119         }
120     }
121   if ((count%16) != 0)
122     vms_debug (-level, "\n");
123 }
124 #endif
125 \f
126 /* Hash functions
127
128    These are needed when reading an object file.  */
129
130 /* Allocate new vms_hash_entry
131    keep the symbol name and a pointer to the bfd symbol in the table.  */
132
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)
137 {
138   vms_symbol_entry *ret;
139
140 #if VMS_DEBUG
141   vms_debug (5, "_bfd_vms_hash_newfunc (%p, %p, %s)\n", entry, table, string);
142 #endif
143
144   if (entry == NULL)
145     {
146       ret = (vms_symbol_entry *)
147               bfd_hash_allocate (table, sizeof (vms_symbol_entry));
148       if (ret ==  NULL)
149         {
150           bfd_set_error (bfd_error_no_memory);
151           return NULL;
152         }
153       entry = (struct bfd_hash_entry *) ret;
154     }
155
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
161
162   ret->symbol = NULL;
163
164   return (struct bfd_hash_entry *)ret;
165 }
166 \f
167 /* Object file input functions.  */
168
169 /* Return type and length from record header (buf) on Alpha.  */
170
171 void
172 _bfd_vms_get_header_values (bfd * abfd ATTRIBUTE_UNUSED,
173                             unsigned char *buf,
174                             int *type,
175                             int *length)
176 {
177   if (type != 0)
178     *type = bfd_getl16 (buf);
179   buf += 2;
180   if (length != 0)
181     *length = bfd_getl16 (buf);
182
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
186 }
187
188 /* Get next record from object file to vms_buf.
189    Set PRIV(buf_size) and return it
190
191    This is a little tricky since it should be portable.
192
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.
198
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.
205
206    The vms format repeats the length at bytes 2 & 3 of every record.
207
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).
213
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.
219
220    All file i/o is always done on even file positions.  */
221
222 int
223 _bfd_vms_get_record (bfd * abfd)
224 {
225   int test_len, test_start, remaining;
226   unsigned char *vms_buf;
227
228 #if VMS_DEBUG
229   vms_debug (8, "_bfd_vms_get_record\n");
230 #endif
231
232   /* Minimum is 6 bytes on Alpha
233      (2 bytes length, 2 bytes record id, 2 bytes length repeated)
234
235      On the VAX there's no length information in the record
236      so start with OBJ_S_C_MAXRECSIZ.   */
237
238   if (PRIV (buf_size) == 0)
239     {
240       bfd_size_type amt;
241
242       if (PRIV (is_vax))
243         {
244           amt = OBJ_S_C_MAXRECSIZ;
245           PRIV (file_format) = FF_VAX;
246         }
247       else
248         amt = 6;
249       PRIV (vms_buf) = bfd_malloc (amt);
250       PRIV (buf_size) = amt;
251     }
252
253   vms_buf = PRIV (vms_buf);
254
255   if (vms_buf == 0)
256     return -1;
257
258   switch (PRIV (file_format))
259     {
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;
265
266     case FF_NATIVE:
267       test_len = 4;
268       test_start = 0;
269       break;
270
271     default:
272     case FF_VAX:
273       test_len = 0;
274       test_start = 0;
275       break;
276     }
277
278   /* Skip odd alignment byte.  */
279
280   if (bfd_tell (abfd) & 1)
281     {
282       if (bfd_bread (PRIV (vms_buf), (bfd_size_type) 1, abfd) != 1)
283         {
284           bfd_set_error (bfd_error_file_truncated);
285           return 0;
286         }
287     }
288
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))
293     {
294       bfd_set_error (bfd_error_file_truncated);
295       return 0;
296     }
297
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])
303         {
304           PRIV (file_format) = FF_FOREIGN;      /* Y: foreign environment.  */
305           test_start = 2;
306         }
307       else
308         {
309           PRIV (file_format) = FF_NATIVE;       /* N: native environment.  */
310           test_start = 0;
311         }
312     }
313
314   if (PRIV (is_vax))
315     {
316       PRIV (rec_length) = bfd_bread (vms_buf, (bfd_size_type) PRIV (buf_size),
317                                      abfd);
318       if (PRIV (rec_length) <= 0)
319         {
320           bfd_set_error (bfd_error_file_truncated);
321           return 0;
322         }
323       PRIV (vms_rec) = vms_buf;
324     }
325   else
326     {
327       /* Alpha.   */
328       /* Extract vms record length.  */
329
330       _bfd_vms_get_header_values (abfd, vms_buf + test_start, NULL,
331                                   & PRIV (rec_length));
332
333       if (PRIV (rec_length) <= 0)
334         {
335           bfd_set_error (bfd_error_file_truncated);
336           return 0;
337         }
338
339       /* That's what the linker manual says.  */
340
341       if (PRIV (rec_length) > EOBJ_S_C_MAXRECSIZ)
342         {
343           bfd_set_error (bfd_error_file_truncated);
344           return 0;
345         }
346
347       /* Adjust the buffer.  */
348
349       if (PRIV (rec_length) > PRIV (buf_size))
350         {
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);
357         }
358
359       /* Read the remaining record.  */
360       remaining = PRIV (rec_length) - test_len + test_start;
361
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)
367         {
368           bfd_set_error (bfd_error_file_truncated);
369           return 0;
370         }
371       PRIV (vms_rec) = vms_buf + test_start;
372     }
373
374 #if VMS_DEBUG
375   vms_debug (11, "bfd_bread rec_length %d\n", PRIV (rec_length));
376 #endif
377
378   return PRIV (rec_length);
379 }
380
381 /* Get next vms record from file
382    update vms_rec and rec_length to new (remaining) values.  */
383
384 int
385 _bfd_vms_next_record (bfd * abfd)
386 {
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
391
392   if (PRIV (rec_length) > 0)
393     PRIV (vms_rec) += PRIV (rec_size);
394   else
395     {
396       if (_bfd_vms_get_record (abfd) <= 0)
397         return -1;
398     }
399
400   if (!PRIV (vms_rec) || !PRIV (vms_buf)
401       || PRIV (vms_rec) >= (PRIV (vms_buf) + PRIV (buf_size)))
402     return -1;
403
404   if (PRIV (is_vax))
405     {
406       PRIV (rec_type) = *(PRIV (vms_rec));
407       PRIV (rec_size) = PRIV (rec_length);
408     }
409   else
410     _bfd_vms_get_header_values (abfd, PRIV (vms_rec), &PRIV (rec_type),
411                                 &PRIV (rec_size));
412
413   PRIV (rec_length) -= PRIV (rec_size);
414
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
420
421   return PRIV (rec_type);
422 }
423 \f
424 /* Copy sized string (string with fixed length) to new allocated area
425    size is string length (size of record)  */
426
427 char *
428 _bfd_vms_save_sized_string (unsigned char *str, int size)
429 {
430   char *newstr = bfd_malloc ((bfd_size_type) size + 1);
431
432   if (newstr == NULL)
433     return NULL;
434   strncpy (newstr, (char *) str, (size_t) size);
435   newstr[size] = 0;
436
437   return newstr;
438 }
439
440 /* Copy counted string (string with length at first byte) to new allocated area
441    ptr points to length byte on entry  */
442
443 char *
444 _bfd_vms_save_counted_string (unsigned char *ptr)
445 {
446   int len = *ptr++;
447
448   return _bfd_vms_save_sized_string (ptr, len);
449 }
450 \f
451 /* Stack routines for vms ETIR commands.  */
452
453 /* Push value and section index.  */
454
455 void
456 _bfd_vms_push (bfd * abfd, uquad val, int psect)
457 {
458   static int last_psect;
459
460 #if VMS_DEBUG
461   vms_debug (4, "<push %016lx (%d) at %d>\n", val, psect, PRIV (stackptr));
462 #endif
463
464   if (psect >= 0)
465     last_psect = psect;
466
467   PRIV (stack[PRIV (stackptr)]).value = val;
468   PRIV (stack[PRIV (stackptr)]).psect = last_psect;
469   PRIV (stackptr)++;
470   if (PRIV (stackptr) >= STACKSIZE)
471     {
472       bfd_set_error (bfd_error_bad_value);
473       (*_bfd_error_handler) (_("Stack overflow (%d) in _bfd_vms_push"), PRIV (stackptr));
474       exit (1);
475     }
476 }
477
478 /* Pop value and section index.  */
479
480 uquad
481 _bfd_vms_pop (bfd * abfd, int *psect)
482 {
483   uquad value;
484
485   if (PRIV (stackptr) == 0)
486     {
487       bfd_set_error (bfd_error_bad_value);
488       (*_bfd_error_handler) (_("Stack underflow in _bfd_vms_pop"));
489       exit (1);
490     }
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;
495
496 #if VMS_DEBUG
497   vms_debug (4, "<pop %016lx(%d)>\n", value, PRIV (stack[PRIV (stackptr)]).psect);
498 #endif
499
500   return value;
501 }
502 \f
503 /* Object file output functions.  */
504
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.  */
508
509 /* Add a new vms_section structure to vms_section_table
510    - forward chaining -.  */
511
512 static vms_section *
513 add_new_contents (bfd * abfd, sec_ptr section)
514 {
515   vms_section *sptr, *newptr;
516
517   sptr = PRIV (vms_section_table)[section->index];
518   if (sptr != NULL)
519     return sptr;
520
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;
532 }
533
534 /* Save section data & offset to a vms_section structure
535    vms_section_table[] holds the vms_section chain.  */
536
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)
543 {
544   vms_section *sptr;
545
546   if (section->index >= VMS_SECTION_COUNT)
547     {
548       bfd_set_error (bfd_error_nonrepresentable_section);
549       return FALSE;
550     }
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);
557
558   return TRUE;
559 }
560
561 /* Get vms_section pointer to saved contents for section # index  */
562
563 vms_section *
564 _bfd_get_vms_section (bfd * abfd, int index)
565 {
566   if (index >=  VMS_SECTION_COUNT)
567     {
568       bfd_set_error (bfd_error_nonrepresentable_section);
569       return NULL;
570     }
571   return PRIV (vms_section_table)[index];
572 }
573 \f
574 /* Object output routines.   */
575
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).   */
580
581 void
582 _bfd_vms_output_begin (bfd * abfd, int rectype, int rechead)
583 {
584 #if VMS_DEBUG
585   vms_debug (6, "_bfd_vms_output_begin (type %d, head %d)\n", rectype,
586               rechead);
587 #endif
588
589   _bfd_vms_output_short (abfd, (unsigned int) rectype);
590
591   /* Save current output position to fill in length later.   */
592
593   if (PRIV (push_level) > 0)
594     PRIV (length_pos) = PRIV (output_size);
595
596 #if VMS_DEBUG
597   vms_debug (6, "_bfd_vms_output_begin: length_pos = %d\n",
598               PRIV (length_pos));
599 #endif
600
601   /* Placeholder for length.  */
602   _bfd_vms_output_short (abfd, 0);
603
604   if (rechead != -1)
605     _bfd_vms_output_short (abfd, (unsigned int) rechead);
606 }
607
608 /* Set record/subrecord alignment.   */
609
610 void
611 _bfd_vms_output_alignment (bfd * abfd, int alignto)
612 {
613 #if VMS_DEBUG
614   vms_debug (6, "_bfd_vms_output_alignment (%d)\n", alignto);
615 #endif
616
617   PRIV (output_alignment) = alignto;
618 }
619
620 /* Prepare for subrecord fields.  */
621
622 void
623 _bfd_vms_output_push (bfd * abfd)
624 {
625 #if VMS_DEBUG
626   vms_debug (6, "vms_output_push (pushed_size = %d)\n", PRIV (output_size));
627 #endif
628
629   PRIV (push_level)++;
630   PRIV (pushed_size) = PRIV (output_size);
631 }
632
633 /* End of subrecord fields.   */
634
635 void
636 _bfd_vms_output_pop (bfd * abfd)
637 {
638 #if VMS_DEBUG
639   vms_debug (6, "vms_output_pop (pushed_size = %d)\n", PRIV (pushed_size));
640 #endif
641
642   _bfd_vms_output_flush (abfd);
643   PRIV (length_pos) = 2;
644
645 #if VMS_DEBUG
646   vms_debug (6, "vms_output_pop: length_pos = %d\n", PRIV (length_pos));
647 #endif
648
649   PRIV (pushed_size) = 0;
650   PRIV (push_level)--;
651 }
652
653 /* Flush unwritten output, ends current record.  */
654
655 void
656 _bfd_vms_output_flush (bfd * abfd)
657 {
658   int real_size = PRIV (output_size);
659   int aligncount;
660   int length;
661
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
666
667   if (PRIV (push_level) > 0)
668     length = real_size - PRIV (pushed_size);
669   else
670     length = real_size;
671
672   if (length == 0)
673     return;
674   aligncount = (PRIV (output_alignment)
675                 - (length % PRIV (output_alignment))) % PRIV (output_alignment);
676
677 #if VMS_DEBUG
678   vms_debug (6, "align: adding %d bytes\n", aligncount);
679 #endif
680
681   while (aligncount-- > 0)
682     {
683       PRIV (output_buf)[real_size++] = 0;
684       length++;
685     }
686
687   /* Put length to buffer.  */
688   PRIV (output_size) = PRIV (length_pos);
689   _bfd_vms_output_short (abfd, (unsigned int) length);
690
691   if (PRIV (push_level) == 0)
692     {
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);
699
700       PRIV (output_size) = 0;
701     }
702   else
703     {
704       PRIV (output_size) = real_size;
705       PRIV (pushed_size) = PRIV (output_size);
706     }
707 }
708
709 /* End record output.   */
710
711 void
712 _bfd_vms_output_end (bfd * abfd)
713 {
714 #if VMS_DEBUG
715   vms_debug (6, "_bfd_vms_output_end\n");
716 #endif
717
718   _bfd_vms_output_flush (abfd);
719 }
720
721 /* Check remaining buffer size
722
723    Return what's left.  */
724
725 int
726 _bfd_vms_output_check (bfd * abfd, int size)
727 {
728 #if VMS_DEBUG
729   vms_debug (6, "_bfd_vms_output_check (%d)\n", size);
730 #endif
731
732   return (MAX_OUTREC_SIZE - (PRIV (output_size) + size + MIN_OUTREC_LUFT));
733 }
734
735 /* Output byte (8 bit) value.  */
736
737 void
738 _bfd_vms_output_byte (bfd * abfd, unsigned int value)
739 {
740 #if VMS_DEBUG
741   vms_debug (6, "_bfd_vms_output_byte (%02x)\n", value);
742 #endif
743
744   bfd_put_8 (abfd, value & 0xff, PRIV (output_buf) + PRIV (output_size));
745   PRIV (output_size) += 1;
746 }
747
748 /* Output short (16 bit) value.  */
749
750 void
751 _bfd_vms_output_short (bfd * abfd, unsigned int value)
752 {
753 #if VMS_DEBUG
754   vms_debug (6, "_bfd_vms_output_short (%04x)\n", value);
755 #endif
756
757   bfd_put_16 (abfd, (bfd_vma) value & 0xffff,
758               PRIV (output_buf) + PRIV (output_size));
759   PRIV (output_size) += 2;
760 }
761
762 /* Output long (32 bit) value.  */
763
764 void
765 _bfd_vms_output_long (bfd * abfd, unsigned long value)
766 {
767 #if VMS_DEBUG
768   vms_debug (6, "_bfd_vms_output_long (%08lx)\n", value);
769 #endif
770
771   bfd_put_32 (abfd, (bfd_vma) value, PRIV (output_buf) + PRIV (output_size));
772   PRIV (output_size) += 4;
773 }
774
775 /* Output quad (64 bit) value.  */
776
777 void
778 _bfd_vms_output_quad (bfd * abfd, uquad value)
779 {
780 #if VMS_DEBUG
781   vms_debug (6, "_bfd_vms_output_quad (%016lx)\n", value);
782 #endif
783
784   bfd_put_64(abfd, value, PRIV (output_buf) + PRIV (output_size));
785   PRIV (output_size) += 8;
786 }
787
788 /* Output c-string as counted string.  */
789
790 void
791 _bfd_vms_output_counted (bfd * abfd, char *value)
792 {
793   int len;
794
795 #if VMS_DEBUG
796   vms_debug (6, "_bfd_vms_output_counted (%s)\n", value);
797 #endif
798
799   len = strlen (value);
800   if (len == 0)
801     {
802       (*_bfd_error_handler) (_("_bfd_vms_output_counted called with zero bytes"));
803       return;
804     }
805   if (len > 255)
806     {
807       (*_bfd_error_handler) (_("_bfd_vms_output_counted called with too many bytes"));
808       return;
809     }
810   _bfd_vms_output_byte (abfd, (unsigned int) len & 0xff);
811   _bfd_vms_output_dump (abfd, (unsigned char *) value, len);
812 }
813
814 /* Output character area.  */
815
816 void
817 _bfd_vms_output_dump (bfd * abfd,
818                       unsigned char *data,
819                       int length)
820 {
821 #if VMS_DEBUG
822   vms_debug (6, "_bfd_vms_output_dump (%d)\n", length);
823 #endif
824
825   if (length == 0)
826     return;
827
828   memcpy (PRIV (output_buf) + PRIV (output_size), data, (size_t) length);
829   PRIV (output_size) += length;
830 }
831
832 /* Output count bytes of value.  */
833
834 void
835 _bfd_vms_output_fill (bfd * abfd,
836                       int value,
837                       int count)
838 {
839 #if VMS_DEBUG
840   vms_debug (6, "_bfd_vms_output_fill (val %02x times %d)\n", value, count);
841 #endif
842
843   if (count == 0)
844     return;
845   memset (PRIV (output_buf) + PRIV (output_size), value, (size_t) count);
846   PRIV (output_size) += count;
847 }
848
849 /* This hash routine borrowed from GNU-EMACS, and strengthened slightly.  ERY.  */
850
851 static int
852 hash_string (const char *ptr)
853 {
854   const unsigned char *p = (unsigned char *) ptr;
855   const unsigned char *end = p + strlen (ptr);
856   unsigned char c;
857   int hash = 0;
858
859   while (p != end)
860     {
861       c = *p++;
862       hash = ((hash << 3) + (hash << 15) + (hash >> 28) + c);
863     }
864   return hash;
865 }
866
867 /* Generate a length-hashed VMS symbol name (limited to maxlen chars).  */
868
869 char *
870 _bfd_vms_length_hash_symbol (bfd * abfd, const char *in, int maxlen)
871 {
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;
879
880 #if VMS_DEBUG
881   vms_debug (4, "_bfd_vms_length_hash_symbol \"%s\"\n", in);
882 #endif
883
884   if (maxlen > EOBJ_S_C_SYMSIZ)
885     maxlen = EOBJ_S_C_SYMSIZ;
886
887   /* Save this for later.  */
888   new_name = out;
889
890   /* We may need to truncate the symbol, save the hash for later.  */
891   in_len = strlen (in);
892
893   result = (in_len > maxlen) ? hash_string (in) : 0;
894
895   old_name = in;
896
897   /* Do the length checking.  */
898   if (in_len <= maxlen)
899     i = in_len;
900   else
901     {
902       if (PRIV (flag_hash_long_names))
903         i = maxlen-9;
904       else
905         i = maxlen;
906     }
907
908   strncpy (out, in, (size_t) i);
909   in += i;
910   out += i;
911
912   if ((in_len > maxlen)
913       && PRIV (flag_hash_long_names))
914     sprintf (out, "_%08lx", result);
915   else
916     *out = 0;
917
918 #if VMS_DEBUG
919   vms_debug (4, "--> [%d]\"%s\"\n", strlen (outbuf), outbuf);
920 #endif
921
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);
926
927   return outbuf;
928 }
929
930 /* Allocate and initialize a new symbol.  */
931
932 static asymbol *
933 new_symbol (bfd * abfd, char *name)
934 {
935   asymbol *symbol;
936
937 #if VMS_DEBUG
938   _bfd_vms_debug (7,  "new_symbol %s\n", name);
939 #endif
940
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);
946
947   return symbol;
948 }
949
950 /* Allocate and enter a new private symbol.  */
951
952 vms_symbol_entry *
953 _bfd_vms_enter_symbol (bfd * abfd, char *name)
954 {
955   vms_symbol_entry *entry;
956
957 #if VMS_DEBUG
958   _bfd_vms_debug (6,  "_bfd_vms_enter_symbol %s\n", name);
959 #endif
960
961   entry = (vms_symbol_entry *)
962           bfd_hash_lookup (PRIV (vms_symbol_table), name, FALSE, FALSE);
963   if (entry == 0)
964     {
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)
971         {
972           asymbol *symbol;
973           symbol = new_symbol (abfd, name);
974           if (symbol != 0)
975             {
976               entry->symbol = symbol;
977               PRIV (gsd_sym_count)++;
978               abfd->symcount++;
979             }
980           else
981             entry = 0;
982         }
983       else
984         (*_bfd_error_handler) (_("failed to enter %s"), name);
985     }
986   else
987     {
988 #if VMS_DEBUG
989       _bfd_vms_debug (8,  "found hash entry for %s\n", name);
990 #endif
991     }
992
993 #if VMS_DEBUG
994   _bfd_vms_debug (7, "-> entry %p, entry->symbol %p\n", entry, entry->symbol);
995 #endif
996   return entry;
997 }