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