OSDN Git Service

* elf-m10200.c (mn10200_elf_relax_section): Cast assignment to
[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
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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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
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 *));
36
37 /*-----------------------------------------------------------------------------*/
38 #if VMS_DEBUG
39 /* debug functions */
40
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
45
46    levels:
47    1    toplevel bfd calls (functions from the bfd vector)
48    2    functions called by bfd calls
49    ...
50    9    almost everything
51
52    level is also identation level. Indentation is performed
53    if level > 0
54         */
55
56 #if __STDC__
57 void
58 _bfd_vms_debug (int level, char *format, ...)
59 {
60   static int min_level = -1;
61   static FILE *output = NULL;
62   char *eptr;
63   va_list args;
64   int abslvl = (level > 0)?level:-level;
65
66   if (min_level == -1)
67     {
68       if ((eptr = getenv("VMS_DEBUG")) != NULL)
69         {
70           min_level = atoi(eptr);
71           output = stderr;
72         }
73       else
74         min_level = 0;
75     }
76   if (output == NULL)
77     return;
78   if (abslvl > min_level)
79     return;
80
81   while (--level>0)
82     fprintf (output, " ");
83   va_start(args, format);
84   vfprintf (output, format, args);
85   fflush(output);
86   va_end(args);
87
88   return;
89 }
90
91 #else /* not __STDC__ */
92
93 void
94 _bfd_vms_debug (level, format, a1, a2, a3, a4, a5, a6)
95      int level;
96      char *format;
97      long a1; long a2; long a3;
98      long a4; long a5; long a6;
99 {
100   static int min_level = -1;
101   static FILE *output = NULL;
102   char *eptr;
103
104   if (min_level == -1)
105     {
106       if ((eptr = getenv("VMS_DEBUG")) != NULL)
107         {
108           min_level = atoi(eptr);
109           output = stderr;
110         }
111       else
112         min_level = 0;
113     }
114   if (output == NULL)
115     return;
116   if (level > min_level)
117     return;
118
119   while (--level>0)
120     fprintf (output, " ");
121   fprintf (output, format, a1, a2, a3, a4, a5, a6);
122   fflush(output);
123
124   return;
125 }
126 #endif /* __STDC__ */
127
128 /* a debug function
129    hex dump 'size' bytes starting at 'ptr'  */
130
131 void
132 _bfd_hexdump (level, ptr, size, offset)
133      int level;
134      unsigned char *ptr;
135      int size;
136      int offset;
137 {
138   unsigned char *lptr = ptr;
139   int count = 0;
140   long start = offset;
141
142   while (size-- > 0)
143     {
144       if ((count%16) == 0)
145         vms_debug (level, "%08lx:", start);
146       vms_debug (-level, " %02x", *ptr++);
147       count++;
148       start++;
149       if (size == 0)
150         {
151           while ((count%16) != 0)
152             {
153               vms_debug (-level, "   ");
154               count++;
155             }
156         }
157       if ((count%16) == 0)
158         {
159           vms_debug (-level, " ");
160           while (lptr < ptr)
161             {
162               vms_debug (-level, "%c", (*lptr < 32)?'.':*lptr);
163               lptr++;
164             }
165           vms_debug (-level, "\n");
166         }
167     }
168   if ((count%16) != 0)
169     vms_debug (-level, "\n");
170
171   return;
172 }
173 #endif
174 \f
175 /* hash functions
176
177    These are needed when reading an object file.  */
178
179 /* allocate new vms_hash_entry
180    keep the symbol name and a pointer to the bfd symbol in the table  */
181
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;
186      const char *string;
187 {
188   vms_symbol_entry *ret;
189
190 #if VMS_DEBUG
191   vms_debug (5, "_bfd_vms_hash_newfunc(%p, %p, %s)\n", entry, table, string);
192 #endif
193
194   if (entry == (struct bfd_hash_entry *)NULL)
195     {
196       ret = (vms_symbol_entry *)
197               bfd_hash_allocate (table, sizeof (vms_symbol_entry));
198       if (ret == (vms_symbol_entry *) NULL)
199         {
200           bfd_set_error (bfd_error_no_memory);
201           return (struct bfd_hash_entry *)NULL;
202         }
203       entry = (struct bfd_hash_entry *) ret;
204     }
205
206   /* Call the allocation method of the base class.  */
207
208   ret = (vms_symbol_entry *) bfd_hash_newfunc (entry, table, string);
209 #if VMS_DEBUG
210   vms_debug (6, "_bfd_vms_hash_newfunc ret %p\n", ret);
211 #endif
212
213   ret->symbol = (asymbol *)NULL;
214
215   return (struct bfd_hash_entry *)ret;
216 }
217 \f
218 /* object file input functions */
219
220 /* Return type and length from record header (buf) on Alpha.  */
221
222 void
223 _bfd_vms_get_header_values (abfd, buf, type, length)
224      bfd *abfd ATTRIBUTE_UNUSED;
225      unsigned char *buf;
226      int *type;
227      int *length;
228 {
229   if (type != 0)
230     *type = bfd_getl16 (buf);
231   buf += 2;
232   if (length != 0)
233     *length = bfd_getl16 (buf);
234
235 #if VMS_DEBUG
236   vms_debug (10, "_bfd_vms_get_header_values type %x, length %x\n", (type?*type:0), (length?*length:0));
237 #endif
238
239   return;
240 }
241
242 /* Get next record from object file to vms_buf
243    set PRIV(buf_size) and return it
244
245    this is a little tricky since it should be portable.
246
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.
252
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.
259
260    The vms format repeats the length at bytes 2 & 3 of every record.
261
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).
267
268    reading is always done in 2 steps.
269    first just the record header is read and the length extracted
270    by get_header_values
271    then the read buffer is adjusted and the remaining bytes are
272    read in.
273
274    all file i/o is always done on even file positions  */
275
276 int
277 _bfd_vms_get_record (abfd)
278      bfd *abfd;
279 {
280   int test_len, test_start, remaining;
281   unsigned char *vms_buf;
282
283 #if VMS_DEBUG
284   vms_debug (8, "_bfd_vms_get_record\n");
285 #endif
286
287   /* minimum is 6 bytes on Alpha
288      (2 bytes length, 2 bytes record id, 2 bytes length repeated)
289
290      on VAX there's no length information in the record
291      so start with OBJ_S_C_MAXRECSIZ  */
292
293   if (PRIV (buf_size) == 0)
294     {
295       if (PRIV (is_vax))
296         {
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;
300         }
301       else
302         PRIV (vms_buf) = (unsigned char *) malloc (6);
303     }
304
305   vms_buf = PRIV (vms_buf);
306
307   if (vms_buf == 0)
308     {
309       bfd_set_error (bfd_error_no_memory);
310       return -1;
311     }
312
313   switch (PRIV (file_format))
314     {
315     case FF_UNKNOWN:
316     case FF_FOREIGN:
317       test_len = 6;                     /* probe 6 bytes */
318       test_start = 2;                   /* where the record starts */
319       break;
320
321     case FF_NATIVE:
322       test_len = 4;
323       test_start = 0;
324       break;
325
326     default:
327     case FF_VAX:
328       test_len = 0;
329       test_start = 0;
330       break;
331     }
332
333   /* skip odd alignment byte  */
334
335   if (bfd_tell (abfd) & 1)
336     {
337       if (bfd_bread (PRIV (vms_buf), (bfd_size_type) 1, abfd) != 1)
338         {
339           bfd_set_error (bfd_error_file_truncated);
340           return 0;
341         }
342     }
343
344   /* read the record header on Alpha.  */
345
346   if ((test_len != 0)
347       && (bfd_bread (PRIV (vms_buf), (bfd_size_type) test_len, abfd)
348           != (bfd_size_type) test_len))
349     {
350       bfd_set_error (bfd_error_file_truncated);
351       return 0;
352     }
353
354   /* check file format on first call  */
355
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]))
360         {
361           PRIV (file_format) = FF_FOREIGN;      /* Y: foreign environment */
362           test_start = 2;
363         }
364       else
365         {
366           PRIV (file_format) = FF_NATIVE;       /* N: native environment */
367           test_start = 0;
368         }
369     }
370
371   if (PRIV (is_vax))
372     {
373       PRIV (rec_length) = bfd_bread (vms_buf, (bfd_size_type) PRIV (buf_size),
374                                     abfd);
375       if (PRIV (rec_length) <= 0)
376         {
377           bfd_set_error (bfd_error_file_truncated);
378           return 0;
379         }
380       PRIV (vms_rec) = vms_buf;
381     }
382   else          /* Alpha  */
383     {
384       /* extract vms record length  */
385
386       _bfd_vms_get_header_values (abfd, vms_buf+test_start, NULL,
387                                   &PRIV (rec_length));
388
389       if (PRIV (rec_length) <= 0)
390         {
391           bfd_set_error (bfd_error_file_truncated);
392           return 0;
393         }
394
395       /* that's what the linker manual says  */
396
397       if (PRIV (rec_length) > EOBJ_S_C_MAXRECSIZ)
398         {
399           bfd_set_error (bfd_error_file_truncated);
400           return 0;
401         }
402
403       /* adjust the buffer  */
404
405       if (PRIV (rec_length) > PRIV (buf_size))
406         {
407           PRIV (vms_buf) = ((unsigned char *)
408                             realloc (vms_buf, (size_t) PRIV (rec_length)));
409           vms_buf = PRIV (vms_buf);
410           if (vms_buf == 0)
411             {
412               bfd_set_error (bfd_error_no_memory);
413               return -1;
414             }
415           PRIV (buf_size) = PRIV (rec_length);
416         }
417
418       /* read the remaining record  */
419
420       remaining = PRIV (rec_length) - test_len + test_start;
421
422 #if VMS_DEBUG
423       vms_debug (10, "bfd_bread remaining %d\n", remaining);
424 #endif
425       if (bfd_bread (vms_buf + test_len, (bfd_size_type) remaining, abfd) !=
426           (bfd_size_type) remaining)
427         {
428           bfd_set_error (bfd_error_file_truncated);
429           return 0;
430         }
431       PRIV (vms_rec) = vms_buf + test_start;
432     }
433
434 #if VMS_DEBUG
435   vms_debug (11, "bfd_bread rec_length %d\n", PRIV (rec_length));
436 #endif
437
438   return PRIV (rec_length);
439 }
440
441 /* get next vms record from file
442    update vms_rec and rec_length to new (remaining) values  */
443
444 int
445 _bfd_vms_next_record (abfd)
446      bfd *abfd;
447 {
448 #if VMS_DEBUG
449   vms_debug (8, "_bfd_vms_next_record (len %d, size %d)\n",
450               PRIV (rec_length), PRIV (rec_size));
451 #endif
452
453   if (PRIV (rec_length) > 0)
454     {
455       PRIV (vms_rec) += PRIV (rec_size);
456     }
457   else
458     {
459       if (_bfd_vms_get_record (abfd) <= 0)
460         return -1;
461     }
462
463   if (!PRIV (vms_rec) || !PRIV (vms_buf)
464       || PRIV (vms_rec) >= (PRIV (vms_buf) + PRIV (buf_size)))
465     return -1;
466
467   if (PRIV (is_vax))
468     {
469       PRIV (rec_type) = *(PRIV (vms_rec));
470       PRIV (rec_size) = PRIV (rec_length);
471     }
472   else
473     {
474       _bfd_vms_get_header_values (abfd, PRIV (vms_rec), &PRIV (rec_type),
475                                   &PRIV (rec_size));
476     }
477   PRIV (rec_length) -= PRIV (rec_size);
478
479 #if VMS_DEBUG
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),
482               PRIV (rec_type));
483 #endif
484
485   return PRIV (rec_type);
486 }
487 \f
488 /* Copy sized string (string with fixed length) to new allocated area
489    size is string length (size of record)  */
490
491 char *
492 _bfd_vms_save_sized_string (str, size)
493      unsigned char *str;
494      int size;
495 {
496   char *newstr = bfd_malloc ((bfd_size_type) size + 1);
497
498   if (newstr == NULL)
499     return 0;
500   strncpy (newstr, (char *) str, (size_t) size);
501   newstr[size] = 0;
502
503   return newstr;
504 }
505
506 /* Copy counted string (string with length at first byte) to new allocated area
507    ptr points to length byte on entry  */
508
509 char *
510 _bfd_vms_save_counted_string (ptr)
511      unsigned char *ptr;
512 {
513   int len = *ptr++;
514
515   return _bfd_vms_save_sized_string (ptr, len);
516 }
517 \f
518 /* stack routines for vms ETIR commands */
519
520 /* Push value and section index  */
521
522 void
523 _bfd_vms_push (abfd, val, psect)
524      bfd *abfd;
525      uquad val;
526      int psect;
527 {
528   static int last_psect;
529
530 #if VMS_DEBUG
531   vms_debug (4, "<push %016lx(%d) at %d>\n", val, psect, PRIV (stackptr));
532 #endif
533
534   if (psect >= 0)
535     last_psect = psect;
536
537   PRIV (stack[PRIV (stackptr)]).value = val;
538   PRIV (stack[PRIV (stackptr)]).psect = last_psect;
539   PRIV (stackptr)++;
540   if (PRIV (stackptr) >= STACKSIZE)
541     {
542       bfd_set_error (bfd_error_bad_value);
543       (*_bfd_error_handler) (_("Stack overflow (%d) in _bfd_vms_push"), PRIV (stackptr));
544       exit (1);
545     }
546   return;
547 }
548
549 /* Pop value and section index  */
550
551 uquad
552 _bfd_vms_pop (abfd, psect)
553      bfd *abfd;
554      int *psect;
555 {
556   uquad value;
557
558   if (PRIV (stackptr) == 0)
559     {
560       bfd_set_error (bfd_error_bad_value);
561       (*_bfd_error_handler) (_("Stack underflow in _bfd_vms_pop"));
562       exit (1);
563     }
564   PRIV (stackptr)--;
565   value = PRIV (stack[PRIV (stackptr)]).value;
566   if ((psect != NULL) && (PRIV (stack[PRIV (stackptr)]).psect >= 0))
567     *psect = PRIV (stack[PRIV (stackptr)]).psect;
568
569 #if VMS_DEBUG
570   vms_debug (4, "<pop %016lx(%d)>\n", value, PRIV (stack[PRIV (stackptr)]).psect);
571 #endif
572
573   return value;
574 }
575 \f
576 /* object file output functions */
577
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.  */
581
582 /* Add a new vms_section structure to vms_section_table
583    - forward chaining -  */
584
585 static vms_section *
586 add_new_contents (abfd, section)
587      bfd *abfd;
588      sec_ptr section;
589 {
590   vms_section *sptr, *newptr;
591
592   sptr = PRIV (vms_section_table)[section->index];
593   if (sptr != NULL)
594     return sptr;
595
596   newptr = (vms_section *) bfd_malloc ((bfd_size_type) sizeof (vms_section));
597   if (newptr == (vms_section *) NULL)
598     return NULL;
599   newptr->contents = (unsigned char *) bfd_alloc (abfd, section->_raw_size);
600   if (newptr->contents == (unsigned char *) NULL)
601     return NULL;
602   newptr->offset = 0;
603   newptr->size = section->_raw_size;
604   newptr->next = 0;
605   PRIV (vms_section_table)[section->index] = newptr;
606   return newptr;
607 }
608
609 /* Save section data & offset to an vms_section structure
610    vms_section_table[] holds the vms_section chain  */
611
612 boolean
613 _bfd_save_vms_section (abfd, section, data, offset, count)
614      bfd *abfd;
615      sec_ptr section;
616      PTR data;
617      file_ptr offset;
618      bfd_size_type count;
619 {
620   vms_section *sptr;
621
622   if (section->index >= VMS_SECTION_COUNT)
623     {
624       bfd_set_error (bfd_error_nonrepresentable_section);
625       return false;
626     }
627   if (count == (bfd_size_type)0)
628     return true;
629   sptr = add_new_contents (abfd, section);
630   if (sptr == NULL)
631     return false;
632   memcpy (sptr->contents + offset, data, (size_t) count);
633
634   return true;
635 }
636
637 /* Get vms_section pointer to saved contents for section # index  */
638
639 vms_section *
640 _bfd_get_vms_section (abfd, index)
641      bfd *abfd;
642      int index;
643 {
644   if (index >=  VMS_SECTION_COUNT)
645     {
646       bfd_set_error (bfd_error_nonrepresentable_section);
647       return NULL;
648     }
649   return PRIV (vms_section_table)[index];
650 }
651 \f
652 /* Object output routines  */
653
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)  */
658
659 void
660 _bfd_vms_output_begin (abfd, rectype, rechead)
661      bfd *abfd;
662      int rectype;
663      int rechead;
664 {
665 #if VMS_DEBUG
666   vms_debug (6, "_bfd_vms_output_begin(type %d, head %d)\n", rectype,
667               rechead);
668 #endif
669
670   _bfd_vms_output_short (abfd, (unsigned int) rectype);
671
672   /* save current output position to fill in lenght later  */
673
674   if (PRIV (push_level) > 0)
675     PRIV (length_pos) = PRIV (output_size);
676
677 #if VMS_DEBUG
678   vms_debug (6, "_bfd_vms_output_begin: length_pos = %d\n",
679               PRIV (length_pos));
680 #endif
681
682   _bfd_vms_output_short (abfd, 0);              /* placeholder for length */
683
684   if (rechead != -1)
685     _bfd_vms_output_short (abfd, (unsigned int) rechead);
686
687   return;
688 }
689
690 /* Set record/subrecord alignment  */
691
692 void
693 _bfd_vms_output_alignment (abfd, alignto)
694      bfd *abfd;
695      int alignto;
696 {
697 #if VMS_DEBUG
698   vms_debug (6, "_bfd_vms_output_alignment(%d)\n", alignto);
699 #endif
700
701   PRIV (output_alignment) = alignto;
702   return;
703 }
704
705 /* Prepare for subrecord fields  */
706
707 void
708 _bfd_vms_output_push (abfd)
709      bfd *abfd;
710 {
711 #if VMS_DEBUG
712   vms_debug (6, "vms_output_push(pushed_size = %d)\n", PRIV (output_size));
713 #endif
714
715   PRIV (push_level)++;
716   PRIV (pushed_size) = PRIV (output_size);
717   return;
718 }
719
720 /* End of subrecord fields  */
721
722 void
723 _bfd_vms_output_pop (abfd)
724      bfd *abfd;
725 {
726 #if VMS_DEBUG
727   vms_debug (6, "vms_output_pop(pushed_size = %d)\n", PRIV (pushed_size));
728 #endif
729
730   _bfd_vms_output_flush (abfd);
731   PRIV (length_pos) = 2;
732
733 #if VMS_DEBUG
734   vms_debug (6, "vms_output_pop: length_pos = %d\n", PRIV (length_pos));
735 #endif
736
737   PRIV (pushed_size) = 0;
738   PRIV (push_level)--;
739   return;
740 }
741
742 /* Flush unwritten output, ends current record  */
743
744 void
745 _bfd_vms_output_flush (abfd)
746      bfd *abfd;
747 {
748   int real_size = PRIV (output_size);
749   int aligncount;
750   int length;
751
752 #if VMS_DEBUG
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));
755 #endif
756
757   if (PRIV (push_level) > 0)
758     length = real_size - PRIV (pushed_size);
759   else
760     length = real_size;
761
762   if (length == 0)
763     return;
764   aligncount = (PRIV (output_alignment)
765                 - (length % PRIV (output_alignment))) % PRIV (output_alignment);
766
767 #if VMS_DEBUG
768   vms_debug (6, "align: adding %d bytes\n", aligncount);
769 #endif
770
771   while (aligncount-- > 0)
772     {
773       PRIV (output_buf)[real_size++] = 0;
774 #if 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)
779 #endif
780         length++;
781     }
782
783   /* put length to buffer  */
784   PRIV (output_size) = PRIV (length_pos);
785   _bfd_vms_output_short (abfd, (unsigned int) length);
786
787   if (PRIV (push_level) == 0)
788     {
789 #ifndef VMS
790         /* write length first, see FF_FOREIGN in the input routines */
791       fwrite (PRIV (output_buf) + 2, 2, 1, (FILE *) abfd->iostream);
792 #endif
793       fwrite (PRIV (output_buf), (size_t) real_size, 1,
794               (FILE *) abfd->iostream);
795
796       PRIV (output_size) = 0;
797     }
798   else
799     {
800       PRIV (output_size) = real_size;
801       PRIV (pushed_size) = PRIV (output_size);
802     }
803
804   return;
805 }
806
807 /* End record output  */
808
809 void
810 _bfd_vms_output_end (abfd)
811      bfd *abfd;
812 {
813 #if VMS_DEBUG
814   vms_debug (6, "_bfd_vms_output_end\n");
815 #endif
816
817   _bfd_vms_output_flush (abfd);
818
819   return;
820 }
821
822 /* check remaining buffer size
823
824    return what's left.  */
825
826 int
827 _bfd_vms_output_check (abfd, size)
828     bfd *abfd;
829     int size;
830 {
831 #if VMS_DEBUG
832   vms_debug (6, "_bfd_vms_output_check(%d)\n", size);
833 #endif
834
835   return (MAX_OUTREC_SIZE - (PRIV (output_size) + size + MIN_OUTREC_LUFT));
836 }
837
838 /* Output byte (8 bit) value  */
839
840 void
841 _bfd_vms_output_byte (abfd, value)
842      bfd *abfd;
843      unsigned int value;
844 {
845 #if VMS_DEBUG
846   vms_debug (6, "_bfd_vms_output_byte(%02x)\n", value);
847 #endif
848
849   bfd_put_8 (abfd, value & 0xff, PRIV (output_buf) + PRIV (output_size));
850   PRIV (output_size) += 1;
851   return;
852 }
853
854 /* Output short (16 bit) value  */
855
856 void
857 _bfd_vms_output_short (abfd, value)
858      bfd *abfd;
859      unsigned int value;
860 {
861 #if VMS_DEBUG
862   vms_debug (6, "_bfd_vms_output_short (%04x)\n", value);
863 #endif
864
865   bfd_put_16 (abfd, (bfd_vma) value & 0xffff,
866               PRIV (output_buf) + PRIV (output_size));
867   PRIV (output_size) += 2;
868   return;
869 }
870
871 /* Output long (32 bit) value  */
872
873 void
874 _bfd_vms_output_long (abfd, value)
875      bfd *abfd;
876      unsigned long value;
877 {
878 #if VMS_DEBUG
879   vms_debug (6, "_bfd_vms_output_long (%08lx)\n", value);
880 #endif
881
882   bfd_put_32 (abfd, (bfd_vma) value, PRIV (output_buf) + PRIV (output_size));
883   PRIV (output_size) += 4;
884   return;
885 }
886
887 /* Output quad (64 bit) value  */
888
889 void
890 _bfd_vms_output_quad (abfd, value)
891      bfd *abfd;
892      uquad value;
893 {
894 #if VMS_DEBUG
895   vms_debug (6, "_bfd_vms_output_quad(%016lx)\n", value);
896 #endif
897
898   bfd_put_64(abfd, value, PRIV (output_buf) + PRIV (output_size));
899   PRIV (output_size) += 8;
900   return;
901 }
902
903 /* Output c-string as counted string  */
904
905 void
906 _bfd_vms_output_counted (abfd, value)
907      bfd *abfd;
908      char *value;
909 {
910 int len;
911
912 #if VMS_DEBUG
913   vms_debug (6, "_bfd_vms_output_counted(%s)\n", value);
914 #endif
915
916   len = strlen (value);
917   if (len == 0)
918     {
919       (*_bfd_error_handler) (_("_bfd_vms_output_counted called with zero bytes"));
920       return;
921     }
922   if (len > 255)
923     {
924       (*_bfd_error_handler) (_("_bfd_vms_output_counted called with too many bytes"));
925       return;
926     }
927   _bfd_vms_output_byte (abfd, (unsigned int) len & 0xff);
928   _bfd_vms_output_dump (abfd, (unsigned char *)value, len);
929 }
930
931 /* Output character area  */
932
933 void
934 _bfd_vms_output_dump (abfd, data, length)
935      bfd *abfd;
936      unsigned char *data;
937      int length;
938 {
939 #if VMS_DEBUG
940   vms_debug (6, "_bfd_vms_output_dump(%d)\n", length);
941 #endif
942
943   if (length == 0)
944     return;
945
946   memcpy (PRIV (output_buf) + PRIV (output_size), data, (size_t) length);
947   PRIV (output_size) += length;
948
949   return;
950 }
951
952 /* Output count bytes of value  */
953
954 void
955 _bfd_vms_output_fill (abfd, value, count)
956      bfd *abfd;
957      int value;
958      int count;
959 {
960 #if VMS_DEBUG
961   vms_debug (6, "_bfd_vms_output_fill(val %02x times %d)\n", value, count);
962 #endif
963
964   if (count == 0)
965     return;
966   memset (PRIV (output_buf) + PRIV (output_size), value, (size_t) count);
967   PRIV (output_size) += count;
968
969   return;
970 }
971
972 /* this hash routine borrowed from GNU-EMACS, and strengthened slightly  ERY*/
973
974 static int
975 hash_string (ptr)
976      const char *ptr;
977 {
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;
982
983   while (p != end)
984     {
985       c = *p++;
986       hash = ((hash << 3) + (hash << 15) + (hash >> 28) + c);
987     }
988   return hash;
989 }
990
991 /* Generate a length-hashed VMS symbol name (limited to maxlen chars).  */
992
993 char *
994 _bfd_vms_length_hash_symbol (abfd, in, maxlen)
995      bfd *abfd;
996      const char *in;
997      int maxlen;
998 {
999   long int result;
1000   int in_len;
1001   char *new_name;
1002   const char *old_name;
1003   int i;
1004   static char outbuf[EOBJ_S_C_SYMSIZ+1];
1005   char *out = outbuf;
1006
1007 #if VMS_DEBUG
1008   vms_debug(4, "_bfd_vms_length_hash_symbol \"%s\"\n", in);
1009 #endif
1010
1011   if (maxlen > EOBJ_S_C_SYMSIZ)
1012     maxlen = EOBJ_S_C_SYMSIZ;
1013
1014   new_name = out;               /* save this for later.  */
1015
1016   /* We may need to truncate the symbol, save the hash for later.  */
1017
1018   in_len = strlen (in);
1019
1020   result = (in_len > maxlen) ? hash_string (in) : 0;
1021
1022   old_name = in;
1023
1024   /* Do the length checking.  */
1025
1026   if (in_len <= maxlen)
1027     {
1028       i = in_len;
1029     }
1030   else
1031     {
1032       if (PRIV (flag_hash_long_names))
1033         i = maxlen-9;
1034       else
1035         i = maxlen;
1036     }
1037
1038   strncpy (out, in, (size_t) i);
1039   in += i;
1040   out += i;
1041
1042   if ((in_len > maxlen)
1043       && PRIV (flag_hash_long_names))
1044     sprintf (out, "_%08lx", result);
1045   else
1046     *out = 0;
1047
1048 #if VMS_DEBUG
1049   vms_debug(4, "--> [%d]\"%s\"\n", strlen (outbuf), outbuf);
1050 #endif
1051
1052   if (in_len > maxlen
1053         && PRIV (flag_hash_long_names)
1054         && PRIV (flag_show_after_trunc))
1055     printf (_("Symbol %s replaced by %s\n"), old_name, new_name);
1056
1057   return outbuf;
1058 }
1059
1060 /* Allocate and initialize a new symbol.  */
1061
1062 static asymbol *
1063 new_symbol (abfd, name)
1064      bfd *abfd;
1065      char *name;
1066 {
1067   asymbol *symbol;
1068
1069 #if VMS_DEBUG
1070   _bfd_vms_debug (7,  "new_symbol %s\n", name);
1071 #endif
1072
1073   symbol = _bfd_vms_make_empty_symbol (abfd);
1074   if (symbol == 0)
1075     return symbol;
1076   symbol->name = name;
1077   symbol->section = bfd_make_section (abfd, BFD_UND_SECTION_NAME);
1078
1079   return symbol;
1080 }
1081
1082 /* Allocate and enter a new private symbol.  */
1083
1084 vms_symbol_entry *
1085 _bfd_vms_enter_symbol (abfd, name)
1086      bfd *abfd;
1087      char *name;
1088 {
1089   vms_symbol_entry *entry;
1090
1091 #if VMS_DEBUG
1092   _bfd_vms_debug (6,  "_bfd_vms_enter_symbol %s\n", name);
1093 #endif
1094
1095   entry = (vms_symbol_entry *)
1096           bfd_hash_lookup (PRIV (vms_symbol_table), name, false, false);
1097   if (entry == 0)
1098     {
1099 #if VMS_DEBUG
1100       _bfd_vms_debug (8,  "creating hash entry for %s\n", name);
1101 #endif
1102       entry = (vms_symbol_entry *)bfd_hash_lookup (PRIV (vms_symbol_table), name, true, false);
1103       if (entry != 0)
1104         {
1105           asymbol *symbol;
1106           symbol = new_symbol (abfd, name);
1107           if (symbol != 0)
1108             {
1109               entry->symbol = symbol;
1110               PRIV (gsd_sym_count)++;
1111               abfd->symcount++;
1112             }
1113           else
1114             entry = 0;
1115         }
1116       else
1117         (*_bfd_error_handler) (_("failed to enter %s"), name);
1118     }
1119   else
1120     {
1121 #if VMS_DEBUG
1122       _bfd_vms_debug (8,  "found hash entry for %s\n", name);
1123 #endif
1124     }
1125
1126 #if VMS_DEBUG
1127   _bfd_vms_debug (7, "-> entry %p, entry->symbol %p\n", entry, entry->symbol);
1128 #endif
1129   return entry;
1130 }