OSDN Git Service

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