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