OSDN Git Service

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