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