]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blob - bfd/vms-misc.c
* syms.c (_bfd_generic_make_empty_symbol): New function.
[thirdparty/binutils-gdb.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
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_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 }