]> Git Repo - binutils.git/blob - bfd/evax-misc.c
* app.c (do_scrub_chars): At the end of a C comment, pass space to
[binutils.git] / bfd / evax-misc.c
1 /* evax-misc.c -- Miscellaneous functions for ALPHA EVAX (openVMS/AXP) files.
2    Copyright 1996 Free Software Foundation, Inc.
3    Written by Klaus Kämpf ([email protected])
4    of proGIS Softwareentwicklung, Aachen, Germany
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
19
20
21 #if __STDC__
22 #include <stdarg.h>
23 #endif
24 #include <stdio.h>
25
26 #include "bfd.h"
27 #include "sysdep.h"
28 #include "bfdlink.h"
29 #include "libbfd.h"
30
31 #include "evax.h"
32
33 /*-----------------------------------------------------------------------------*/
34 #if EVAX_DEBUG
35 /* debug functions */
36
37 /* debug function for all evax extensions
38    evaluates environment variable EVAX_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_evax_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("EVAX_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_evax_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("EVAX_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         evax_debug (level, "%08lx:", start);
143       evax_debug (-level, " %02x", *ptr++);
144       count++;
145       start++;
146       if (size == 0)
147         {
148           while ((count%16) != 0)
149             {
150               evax_debug (-level, "   ");
151               count++;
152             }
153         }
154       if ((count%16) == 0)
155         {
156           evax_debug (-level, " ");
157           while (lptr < ptr)
158             {
159               evax_debug (-level, "%c", (*lptr < 32)?'.':*lptr);
160               lptr++;
161             }
162           evax_debug (-level, "\n");
163         }
164     }
165   if ((count%16) != 0)
166     evax_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 evax_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_evax_hash_newfunc (entry, table, string)
182      struct bfd_hash_entry *entry;
183      struct bfd_hash_table *table;
184      const char *string;
185 {
186   evax_symbol_entry *ret = (evax_symbol_entry *)entry;
187
188 #if EVAX_DEBUG
189   evax_debug (5, "_bfd_evax_hash_newfunc(%p, %p, %s)\n", entry, table, string);
190 #endif
191
192   if (ret == (evax_symbol_entry *)NULL)
193     ret = ((evax_symbol_entry *) bfd_hash_allocate (table, sizeof (evax_symbol_entry)));
194   if (ret == (evax_symbol_entry *)NULL)
195     {
196       bfd_set_error (bfd_error_no_memory);
197       return (struct bfd_hash_entry *)NULL;
198     }
199   ret = (evax_symbol_entry *) bfd_hash_newfunc ((struct bfd_hash_entry *)ret, table, string);
200
201   ret->symbol = (asymbol *)NULL;
202
203   return (struct bfd_hash_entry *)ret;
204 }
205
206 \f
207 /* object file input functions */
208
209 /* Return type and length from record header (buf)  */
210
211 void
212 _bfd_evax_get_header_values (abfd, buf, type, length)
213      bfd *abfd;
214      unsigned char *buf;
215      int *type;
216      int *length;
217 {
218   if (type != 0)
219     *type = bfd_getl16 (buf);
220   buf += 2;
221   if (length != 0)
222     *length = bfd_getl16 (buf);
223
224   return;
225 }
226
227
228 /* Get next record from object file to evax_buf
229    set PRIV(buf_size) and return it
230   
231    this is a little tricky since it should be portable.
232   
233    the openVMS/AXP object file has 'variable length' which means that
234    read() returns data in chunks of (hopefully) correct and expected
235    size. The linker (and other tools on vms) depend on that. Unix doesn't
236    know about 'formatted' files, so reading and writing such an object
237    file in a unix environment is not trivial.
238   
239    With the tool 'file' (available on all vms ftp sites), one
240    can view and change the attributes of a file. Changing from
241    'variable length' to 'fixed length, 512 bytes' reveals the
242    record length at the first 2 bytes of every record. The same
243    happens during the transfer of object files from vms to unix,
244    at least with ucx, dec's implementation of tcp/ip.
245   
246    The EVAX format repeats the length at bytes 2 & 3 of every record.
247   
248    On the first call (file_format == FF_UNKNOWN) we check if
249    the first and the third byte pair (!) of the record match.
250    If they do it's an object file in an unix environment or with
251    wrong attributes (FF_FOREIGN), else we should be in a vms
252    environment where read() returns the record size (FF_NATIVE).
253   
254    reading is always done in 2 steps.
255    first just the record header is read and the length extracted
256    by get_header_values
257    then the read buffer is adjusted and the remaining bytes are
258    read in.
259   
260    all file i/o is always done on even file positions  */
261
262 int
263 _bfd_evax_get_record (abfd)
264      bfd *abfd;
265 {
266   int test_len, test_start, remaining;
267   unsigned char *evax_buf;
268
269 #if EVAX_DEBUG
270   evax_debug (8, "_bfd_evax_get_record\n");
271 #endif
272
273   /* minimum is 6 bytes
274      (2 bytes length, 2 bytes record id, 2 bytes length repeated)  */
275
276   if (PRIV(buf_size) == 0)
277     {
278       PRIV(evax_buf) = (unsigned char *) malloc (6);
279 #if EVAX_DEBUG
280       evax_debug (9, "PRIV(evax_buf) %p\n", PRIV(evax_buf));
281 #endif
282     }
283
284   evax_buf = PRIV(evax_buf);
285
286   if (evax_buf == 0)
287     {
288 #if EVAX_DEBUG
289       evax_debug (9, "can't alloc evax_buf\n");
290 #endif
291       bfd_set_error (bfd_error_no_memory);
292       return -1;
293     }
294
295   switch (PRIV(file_format))
296     {
297       case FF_UNKNOWN:
298       case FF_FOREIGN:
299         test_len = 6;                           /* probe 6 bytes */
300         test_start = 2;                         /* where the record starts */
301       break;
302
303       case FF_NATIVE:
304         test_len = 4;
305         test_start = 0;
306       break;
307   }
308
309   /* skip odd alignment byte  */
310 #if 0
311   if (PRIV(file_format) == FF_FOREIGN)
312     {
313 #endif
314       if (bfd_tell (abfd) & 1)
315         {
316 #if EVAX_DEBUG
317           evax_debug (10, "skip odd\n");
318 #endif
319           if (bfd_read (PRIV(evax_buf), 1, 1, abfd) != 1)
320             {
321 #if EVAX_DEBUG
322               evax_debug (9, "skip odd failed\n");
323 #endif
324               bfd_set_error (bfd_error_file_truncated);
325               return 0;
326             }
327         }
328 #if 0
329     }
330 #endif
331   /* read the record header  */
332
333   if (bfd_read (PRIV(evax_buf), 1, test_len, abfd) != test_len)
334     {
335 #if EVAX_DEBUG
336       evax_debug (9, "can't bfd_read test %d bytes\n", test_len);
337 #endif
338       bfd_set_error (bfd_error_file_truncated);
339       return 0;
340     }
341
342   /* check file format on first call  */
343
344   if (PRIV(file_format) == FF_UNKNOWN)
345     {                                           /* record length repeats ? */
346       if ( (evax_buf[0] == evax_buf[4])
347         && (evax_buf[1] == evax_buf[5]))
348         {
349           PRIV(file_format) = FF_FOREIGN;       /* Y: foreign environment */
350           test_start = 2;
351         }
352       else
353         {
354           PRIV(file_format) = FF_NATIVE;        /* N: native environment */
355           test_start = 0;
356         }
357 #if EVAX_DEBUG
358       evax_debug (10, "File format is %s\n", (PRIV(file_format) == FF_FOREIGN)?"foreign":"native");
359 #endif
360     }
361
362   /* extract evax record length  */
363
364   _bfd_evax_get_header_values (abfd, evax_buf+test_start, NULL,
365                                &PRIV(rec_length));
366
367   if (PRIV(rec_length) <= 0)
368     {
369       bfd_set_error (bfd_error_file_truncated);
370       return 0;
371     }
372
373   /* that's what the linker manual says  */
374
375   if (PRIV(rec_length) > EOBJ_S_C_MAXRECSIZ)
376     {
377       bfd_set_error (bfd_error_file_truncated);
378       return 0;
379     }
380
381   /* adjust the buffer  */
382
383   if (PRIV(rec_length) > PRIV(buf_size))
384     {
385       PRIV(evax_buf) = (unsigned char *) realloc (evax_buf, PRIV(rec_length));
386 #if EVAX_DEBUG
387       evax_debug (3, "adjusted the buffer (%p) from %d to %d\n", PRIV(evax_buf), PRIV(buf_size), PRIV(rec_length));
388 #endif
389       evax_buf = PRIV(evax_buf);
390       if (evax_buf == 0)
391         {
392 #if EVAX_DEBUG
393           evax_debug (9, "can't realloc evax_buf to %d bytes\n", PRIV(rec_length));
394 #endif
395           bfd_set_error (bfd_error_no_memory);
396           return -1;
397         }
398       PRIV(buf_size) = PRIV(rec_length);
399     }
400
401   /* read the remaining record  */
402
403   remaining = PRIV(rec_length) - test_len + test_start;
404
405   if (bfd_read (evax_buf + test_len, 1, remaining, abfd) != remaining)
406     {
407 #if EVAX_DEBUG
408       evax_debug (9, "can't bfd_read remaining %d bytes\n", remaining);
409 #endif
410       bfd_set_error (bfd_error_file_truncated);
411       return 0;
412     }
413
414   PRIV(evax_rec) = evax_buf + test_start;
415
416   return PRIV(rec_length);
417 }
418
419
420 /* get next EVAX record from file
421    update evax_rec and rec_length to new (remaining) values  */
422
423 int
424 _bfd_evax_next_record (abfd)
425      bfd *abfd;
426 {
427 #if EVAX_DEBUG
428   evax_debug (8, "_bfd_evax_next_record (len %d, size %d)\n",
429               PRIV(rec_length), PRIV(rec_size));
430 #endif
431
432   if (PRIV(rec_length) > 0)
433     {
434       PRIV(evax_rec) += PRIV(rec_size);
435     }
436   else
437     {
438       if (_bfd_evax_get_record (abfd) <= 0)
439         return -1;
440     }
441   _bfd_evax_get_header_values (abfd, PRIV(evax_rec), &PRIV(rec_type),
442                                &PRIV(rec_size));
443   PRIV(rec_length) -= PRIV(rec_size);
444
445 #if EVAX_DEBUG
446   evax_debug (8, "_bfd_evax_next_record: rec %p, size %d, length %d, type %d\n",
447               PRIV(evax_rec), PRIV(rec_size),   PRIV(rec_length),
448               PRIV(rec_type));
449 #endif
450
451   return PRIV(rec_type);
452 }
453
454
455 \f
456 /* Copy sized string (string with fixed length) to new allocated area
457    size is string length (size of record)  */
458
459 char *
460 _bfd_evax_save_sized_string (str, size)
461      char *str;
462      int size;
463 {
464   char *newstr = bfd_malloc (size + 1);
465
466   if (newstr == NULL)
467     return 0;
468   strncpy (newstr, str, size);
469   newstr[size] = 0;
470
471   return newstr;
472 }
473
474 /* Copy counted string (string with length at first byte) to new allocated area
475    ptr points to length byte on entry  */
476
477 char *
478 _bfd_evax_save_counted_string (ptr)
479      char *ptr;
480 {
481   int len = *ptr++;
482
483   return _bfd_evax_save_sized_string (ptr, len);
484 }
485
486 \f
487 /* stack routines for EVAX ETIR commands */
488
489 /* Push value and section index  */
490
491 void
492 _bfd_evax_push (abfd, val, psect)
493      bfd *abfd;
494      uquad val;
495      int psect;
496 {
497   static int last_psect;
498
499 #if EVAX_DEBUG
500   evax_debug (4, "<push %016lx(%d) at %d>\n", val, psect, PRIV(stackptr));
501 #endif
502
503   if (psect >= 0)
504     last_psect = psect;
505
506   PRIV(stack[PRIV(stackptr)]).value = val;
507   PRIV(stack[PRIV(stackptr)]).psect = last_psect;
508   PRIV(stackptr)++;
509   if (PRIV(stackptr) >= STACKSIZE)
510     {
511       bfd_set_error (bfd_error_bad_value);
512       exit(1);
513     }
514   return;
515 }
516
517
518 /* Pop value and section index  */
519
520 uquad
521 _bfd_evax_pop (abfd, psect)
522      bfd *abfd;
523      int *psect;
524 {
525   uquad value;
526
527   if (PRIV(stackptr) == 0)
528     {
529       bfd_set_error (bfd_error_bad_value);
530       exit(1);
531     }
532   PRIV(stackptr)--;
533   value = PRIV(stack[PRIV(stackptr)]).value;
534   if ((psect != NULL) && (PRIV(stack[PRIV(stackptr)]).psect >= 0))
535     *psect = PRIV(stack[PRIV(stackptr)]).psect;
536
537 #if EVAX_DEBUG
538   evax_debug (4, "<pop %016lx(%d)>\n", value, PRIV(stack[PRIV(stackptr)]).psect);
539 #endif
540
541   return value;
542 }
543
544 \f
545 /* object file output functions */
546
547 /* GAS tends to write sections in little chunks (bfd_set_section_contents)
548    which we can't use directly. So we save the little chunks in linked
549    lists (one per section) and write them later.  */
550
551 /* Add a new evax_section structure to evax_section_table
552    - forward chaining -  */
553
554 static evax_section *
555 add_new_contents (abfd, section)
556      bfd *abfd;
557      sec_ptr section;
558 {
559   evax_section *sptr, *newptr;
560
561   sptr = PRIV(evax_section_table)[section->index];
562   if (sptr != NULL)
563     return sptr;
564
565   newptr = (evax_section *) bfd_malloc (sizeof (evax_section));
566   if (newptr == (evax_section *) NULL)
567     return NULL;
568   newptr->contents = (unsigned char *) bfd_alloc (abfd, (int)section->_raw_size);
569   if (newptr->contents == (unsigned char *)NULL)
570     return NULL;
571   newptr->offset = 0;
572   newptr->size = section->_raw_size;
573   newptr->next = 0;
574   PRIV(evax_section_table)[section->index] = newptr;
575   return newptr;
576 }
577
578
579 /* Save section data & offset to an evax_section structure
580    evax_section_table[] holds the evax_section chain  */
581
582 boolean
583 _bfd_save_evax_section (abfd, section, data, offset, count)
584      bfd *abfd;
585      sec_ptr section;
586      PTR data;
587      file_ptr offset;
588      bfd_size_type count;
589 {
590   evax_section *sptr;
591
592   if (section->index >= EVAX_SECTION_COUNT)
593     {
594       bfd_set_error (bfd_error_nonrepresentable_section);
595       return false;
596     }
597   if (count == (bfd_size_type)0)
598     return true;
599   sptr = add_new_contents (abfd, section);
600   if (sptr == NULL)
601     return false;
602   memcpy (sptr->contents + offset, data, (size_t) count);
603
604   return true;
605 }
606
607
608 /* Get evax_section pointer to saved contents for section # index  */
609
610 evax_section *
611 _bfd_get_evax_section (abfd, index)
612      bfd *abfd;
613      int index;
614 {
615   if (index >=  EVAX_SECTION_COUNT)
616     {
617       bfd_set_error (bfd_error_nonrepresentable_section);
618       return NULL;
619     }
620   return PRIV(evax_section_table)[index];
621 }
622
623 \f
624 /* Object output routines  */
625
626 /* Begin new record or record header
627    write 2 bytes rectype
628    write 2 bytes record length (filled in at flush)
629    write 2 bytes header type (ommitted if rechead == -1)  */
630
631 void
632 _bfd_evax_output_begin (abfd, rectype, rechead)
633      bfd *abfd;
634      int rectype;
635      int rechead;
636 {
637 #if EVAX_DEBUG
638   evax_debug (6, "_bfd_evax_output_begin(type %d, head %d)\n", rectype,
639               rechead);
640 #endif
641
642   _bfd_evax_output_short (abfd,rectype);
643
644   /* save current output position to fill in lenght later  */
645
646   if (PRIV(push_level) > 0)
647     PRIV(length_pos) = PRIV(output_size);
648
649 #if EVAX_DEBUG
650   evax_debug (6, "_bfd_evax_output_begin: length_pos = %d\n",
651               PRIV(length_pos));
652 #endif
653
654   _bfd_evax_output_short (abfd,0);              /* placeholder for length */
655
656   if (rechead != -1)
657     _bfd_evax_output_short (abfd,rechead);
658
659   return;
660 }
661
662
663 /* Set record/subrecord alignment  */
664
665 void
666 _bfd_evax_output_alignment (abfd, alignto)
667      bfd *abfd;
668      int alignto;
669 {
670 #if EVAX_DEBUG
671   evax_debug (6, "_bfd_evax_output_alignment(%d)\n", alignto);
672 #endif
673
674   PRIV(output_alignment) = alignto;
675   return;
676 }
677
678
679 /* Prepare for subrecord fields  */
680
681 void
682 _bfd_evax_output_push (abfd)
683      bfd *abfd;
684 {
685 #if EVAX_DEBUG
686   evax_debug (6, "evax_output_push(pushed_size = %d)\n", PRIV(output_size));
687 #endif
688
689   PRIV(push_level)++;
690   PRIV(pushed_size) = PRIV(output_size);
691   return;
692 }
693
694
695 /* End of subrecord fields  */
696
697 void
698 _bfd_evax_output_pop (abfd)
699      bfd *abfd;
700 {
701 #if EVAX_DEBUG
702   evax_debug (6, "evax_output_pop(pushed_size = %d)\n", PRIV(pushed_size));
703 #endif
704
705   _bfd_evax_output_flush (abfd);
706   PRIV(length_pos) = 2;
707
708 #if EVAX_DEBUG
709   evax_debug (6, "evax_output_pop: length_pos = %d\n", PRIV(length_pos));
710 #endif
711
712   PRIV(pushed_size) = 0;
713   PRIV(push_level)--;
714   return;
715 }
716
717
718 /* Flush unwritten output, ends current record  */
719
720 void
721 _bfd_evax_output_flush (abfd)
722      bfd *abfd;
723 {
724   int real_size = PRIV(output_size);
725   int aligncount;
726   int length;
727
728 #if EVAX_DEBUG
729   evax_debug (6, "_bfd_evax_output_flush(real_size = %d, pushed_size %d at lenpos %d)\n",
730               real_size, PRIV(pushed_size), PRIV(length_pos));
731 #endif
732
733   if (PRIV(push_level) > 0)
734     length = real_size - PRIV(pushed_size);
735   else
736     length = real_size;
737
738   if (length == 0)
739     return;
740   aligncount = (PRIV(output_alignment)
741                 - (length % PRIV(output_alignment))) % PRIV(output_alignment);
742
743 #if EVAX_DEBUG
744   evax_debug (6, "align: adding %d bytes\n", aligncount);
745 #endif
746
747   while(aligncount-- > 0)
748     {
749       PRIV(output_buf)[real_size++] = 0;
750 #if 0
751       /* this is why I *love* vms: inconsistency :-}
752          alignment is added to the subrecord length
753          but not to the record length  */
754       if (PRIV(push_level) > 0)
755 #endif
756         length++;
757     }
758
759   /* put length to buffer  */
760   PRIV(output_size) = PRIV(length_pos);
761   _bfd_evax_output_short (abfd, (unsigned int)length);
762
763   if (PRIV(push_level) == 0)
764     {
765 #ifndef VMS
766         /* write length first, see FF_FOREIGN in the input routines */
767       fwrite (PRIV(output_buf)+2, 2, 1, (FILE *)abfd->iostream);
768 #endif
769       fwrite (PRIV(output_buf), real_size, 1, (FILE *)abfd->iostream);
770
771       PRIV(output_size) = 0;
772     }
773   else
774     {
775       PRIV(output_size) = real_size;
776       PRIV(pushed_size) = PRIV(output_size);
777     }
778
779   return;
780 }
781
782
783 /* End record output  */
784
785 void
786 _bfd_evax_output_end (abfd)
787      bfd *abfd;
788 {
789 #if EVAX_DEBUG
790   evax_debug (6, "_bfd_evax_output_end\n");
791 #endif
792
793   _bfd_evax_output_flush (abfd);
794
795   return;
796 }
797
798
799 /* check remaining buffer size
800
801    return what's left.  */
802
803 int
804 _bfd_evax_output_check (abfd, size)
805     bfd *abfd;
806     int size;
807 {
808 #if EVAX_DEBUG
809   evax_debug (6, "_bfd_evax_output_check(%d)\n", size);
810 #endif
811
812   return (MAX_OUTREC_SIZE - (PRIV(output_size) + size + MIN_OUTREC_LUFT));
813 }
814
815
816 /* Output byte (8 bit) value  */
817
818 void
819 _bfd_evax_output_byte (abfd, value)
820      bfd *abfd;
821      unsigned int value;
822 {
823 #if EVAX_DEBUG
824   evax_debug (6, "_bfd_evax_output_byte(%02x)\n", value);
825 #endif
826
827   bfd_put_8 (abfd, value & 0xff, PRIV(output_buf) + PRIV(output_size));
828   PRIV(output_size) += 1;
829   return;
830 }
831
832
833 /* Output short (16 bit) value  */
834
835 void
836 _bfd_evax_output_short (abfd, value)
837      bfd *abfd;
838      unsigned int value;
839 {
840 #if EVAX_DEBUG
841   evax_debug (6, "_bfd_evax_output_short (%04x)\n", value);
842 #endif
843
844   bfd_put_16 (abfd, value & 0xffff, PRIV(output_buf) + PRIV(output_size));
845   PRIV(output_size) += 2;
846   return;
847 }
848
849
850 /* Output long (32 bit) value  */
851
852 void
853 _bfd_evax_output_long (abfd, value)
854      bfd *abfd;
855      unsigned long value;
856 {
857 #if EVAX_DEBUG
858   evax_debug (6, "_bfd_evax_output_long (%08lx)\n", value);
859 #endif
860
861   bfd_put_32 (abfd, value, PRIV(output_buf) + PRIV(output_size));
862   PRIV(output_size) += 4;
863   return;
864 }
865
866
867 /* Output quad (64 bit) value  */
868
869 void
870 _bfd_evax_output_quad (abfd, value)
871      bfd *abfd;
872      uquad value;
873 {
874 #if EVAX_DEBUG
875   evax_debug (6, "_bfd_evax_output_quad(%016lx)\n", value);
876 #endif
877
878   bfd_put_64(abfd, value, PRIV(output_buf) + PRIV(output_size));
879   PRIV(output_size) += 8;
880   return;
881 }
882
883
884 /* Output c-string as counted string  */
885
886 void
887 _bfd_evax_output_counted (abfd, value)
888      bfd *abfd;
889      char *value;
890 {
891 int len;
892
893 #if EVAX_DEBUG
894   evax_debug (6, "_bfd_evax_output_counted(%s)\n", value);
895 #endif
896
897   len = strlen (value);
898   if (len == 0)
899     {
900       (*_bfd_error_handler) ("_bfd_evax_output_counted called with zero bytes");
901       return;
902     }
903   if (len > 255)
904     {
905       (*_bfd_error_handler) ("_bfd_evax_output_counted called with too many bytes");
906       return;
907     }
908   _bfd_evax_output_byte (abfd, len & 0xff);
909   _bfd_evax_output_dump (abfd, (unsigned char *)value, len);
910 }
911
912
913 /* Output character area  */
914
915 void
916 _bfd_evax_output_dump (abfd, data, length)
917      bfd *abfd;
918      unsigned char *data;
919      int length;
920 {
921 #if EVAX_DEBUG
922   evax_debug (6, "_bfd_evax_output_dump(%d)\n", length);
923 #endif
924
925   if (length == 0)
926     return;
927
928   memcpy (PRIV(output_buf) + PRIV(output_size), data, length);
929   PRIV(output_size) += length;
930
931   return;
932 }
933
934
935 /* Output count bytes of value  */
936
937 void
938 _bfd_evax_output_fill (abfd, value, count)
939      bfd *abfd;
940      int value;
941      int count;
942 {
943 #if EVAX_DEBUG
944   evax_debug (6, "_bfd_evax_output_fill(val %02x times %d)\n", value, count);
945 #endif
946
947   if (count == 0)
948     return;
949   memset (PRIV(output_buf) + PRIV(output_size), value, count);
950   PRIV(output_size) += count;
951
952   return;
953 }
954
955 /* this hash routine borrowed from GNU-EMACS, and strengthened slightly  ERY*/
956
957 static int
958 hash_string (ptr)
959      const char *ptr;
960 {
961   register const unsigned char *p = (unsigned char *) ptr;
962   register const unsigned char *end = p + strlen (ptr);
963   register unsigned char c;
964   register int hash = 0;
965
966   while (p != end)
967     {
968       c = *p++;
969       hash = ((hash << 3) + (hash << 15) + (hash >> 28) + c);
970     }
971   return hash;
972 }
973
974 /* Generate a Case-Hacked VMS symbol name (limited to 64 chars).  */
975 char *
976 _bfd_evax_case_hack_symbol (abfd, in)
977      bfd *abfd;
978      const char *in;
979 {
980   long int init;
981   long int result;
982   char *pnt = 0;
983   char *new_name;
984   const char *old_name;
985   int i;
986   int destructor = 0;           /*hack to allow for case sens in a destructor*/
987   int truncate = 0;
988   int case_hack_bits = 0;
989   int saw_dollar = 0;
990   static char hex_table[16] =
991   {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
992
993   static char outbuf[65];
994   char *out = outbuf;
995
996 #if EVAX_DEBUG
997   evax_debug(4, "_bfd_evax_case_hack_symbol \"%s\"\n", in);
998 #endif
999
1000 #if 0
1001   /* Kill any leading "_".  */  /* Why ? FIXME ! */
1002
1003   if ((in[0] == '_') && ((in[1] > '9') || (in[1] < '0')))
1004     in++;
1005 #endif
1006
1007   new_name = out;               /* save this for later.  */
1008
1009   /* We may need to truncate the symbol, save the hash for later.  */
1010
1011   result = (strlen (in) > 56) ? hash_string (in) : 0;
1012
1013   old_name = in;
1014
1015   /* Do the case conversion.  */
1016
1017   i = 56;                       /* Maximum of 56 chars */
1018
1019   while (*in && (--i >= 0))
1020     {
1021       case_hack_bits <<= 1;
1022       if (*in == '$')
1023         saw_dollar = 1;
1024       if ((destructor == 1) && (i == 54))
1025         saw_dollar = 0;
1026       switch (PRIV(vms_name_mapping))
1027         {
1028         case 0:
1029           if (isupper (*in)) {
1030             *out++ = *in++;
1031             case_hack_bits |= 1;
1032           } else {
1033             *out++ = islower (*in) ? toupper (*in++) : *in++;
1034           }
1035           break;
1036         case 3: *out++ = *in++;
1037           break;
1038         case 2:
1039           if (islower (*in)) {
1040             *out++ = *in++;
1041           } else {
1042             *out++ = isupper (*in) ? tolower (*in++) : *in++;
1043           }
1044           break;
1045         }
1046     }
1047
1048   /* if we saw a dollar sign, we don't do case hacking.  */
1049
1050   if (PRIV(flag_no_hash_mixed_case) || saw_dollar)
1051     case_hack_bits = 0;
1052
1053   /* if we have more than 56 characters and everything is lowercase
1054      we can insert the full 64 characters.  */
1055
1056   if (*in)
1057     {
1058       /* We have more than 56 characters
1059          If we must add the case hack, then we have truncated the str.  */
1060       pnt = out;
1061       truncate = 1;
1062       if (case_hack_bits == 0)
1063         {
1064           /* And so far they are all lower case:
1065                Check up to 8 more characters
1066                and ensure that they are lowercase.  */
1067
1068           for (i = 0; (in[i] != 0) && (i < 8); i++)
1069             if (isupper (in[i]) && !saw_dollar && !PRIV(flag_no_hash_mixed_case))
1070               break;
1071
1072           if (in[i] == 0)
1073             truncate = 0;
1074
1075           if ((i == 8) || (in[i] == 0))
1076             {
1077               /* They are:  Copy up to 64 characters
1078                             to the output string.  */
1079
1080               i = 8;
1081               while ((--i >= 0) && (*in))
1082                 {
1083                   switch (PRIV(vms_name_mapping))
1084                     {
1085                       case 0:
1086                         *out++ = islower (*in) ? toupper (*in++) : *in++;
1087                         break;
1088                       case 3:
1089                         *out++ = *in++;
1090                         break;
1091                       case 2:
1092                         *out++ = isupper (*in) ? tolower (*in++) : *in++;
1093                         break;
1094                     }
1095                 }
1096             }
1097         }
1098 }
1099
1100   /* If there were any uppercase characters in the name we
1101      take on the case hacking string.  */
1102
1103   /* Old behavior for regular GNU-C compiler */
1104
1105   if (!PRIV(flag_hash_long_names))
1106     truncate = 0;
1107
1108   if ((case_hack_bits != 0) || (truncate == 1))
1109     {
1110       if (truncate == 0)
1111         {
1112           *out++ = '_';
1113           for (i = 0; i < 6; i++)
1114             {
1115               *out++ = hex_table[case_hack_bits & 0xf];
1116               case_hack_bits >>= 4;
1117             }
1118           *out++ = 'X';
1119         }
1120       else
1121         {
1122           out = pnt;            /* Cut back to 56 characters maximum */
1123           *out++ = '_';
1124           for (i = 0; i < 7; i++)
1125             {
1126               init = result & 0x01f;
1127               *out++ = (init < 10) ? ('0' + init) : ('A' + init - 10);
1128               result = result >> 5;
1129             }
1130         }
1131     }
1132
1133   *out = 0;
1134
1135 #if EVAX_DEBUG
1136   evax_debug(4, "--> [%d]\"%s\"\n", strlen (outbuf), outbuf);
1137 #endif
1138
1139   if (truncate == 1
1140         && PRIV(flag_hash_long_names)
1141         && PRIV(flag_show_after_trunc))
1142     printf ("Symbol %s replaced by %s\n", old_name, new_name);
1143
1144   return outbuf;
1145 }
1146
This page took 0.083176 seconds and 4 git commands to generate.