* archures.c (bfd_mach_mn10300): Define.
[deliverable/binutils-gdb.git] / bfd / evax-misc.c
CommitLineData
8696b2db 1/* evax-misc.c -- Miscellaneous functions for ALPHA EVAX (openVMS/Alpha) files.
980381af 2 Copyright 1996, 1997, 1998 Free Software Foundation, Inc.
8696b2db
ILT
3
4 Written by Klaus K"ampf (kkaempf@progis.de)
c3d8e071
ILT
5 of proGIS Softwareentwicklung, Aachen, Germany
6
7This program is free software; you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published by
9the Free Software Foundation; either version 2 of the License, or
10(at your option) any later version.
11
12This program is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15GNU General Public License for more details.
16
17You should have received a copy of the GNU General Public License
18along with this program; if not, write to the Free Software
19Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
20
21
22#if __STDC__
23#include <stdarg.h>
24#endif
c3d8e071
ILT
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__
53void
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
89void
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
128void
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
180struct 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
211void
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
262int
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
423int
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
459char *
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
477char *
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
491void
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
520uquad
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
554static evax_section *
555add_new_contents (abfd, section)
556 bfd *abfd;
557 sec_ptr section;
558{
559 evax_section *sptr, *newptr;
560
c3d8e071 561 sptr = PRIV(evax_section_table)[section->index];
8612a388
ILT
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;
bf53bd9f 568 newptr->contents = (unsigned char *) bfd_alloc (abfd, (int)section->_raw_size);
8612a388
ILT
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;
c3d8e071
ILT
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
582boolean
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;
8612a388 602 memcpy (sptr->contents + offset, data, (size_t) count);
c3d8e071
ILT
603
604 return true;
605}
606
607
608/* Get evax_section pointer to saved contents for section # index */
609
610evax_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
631void
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
665void
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
681void
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
697void
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
720void
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
785void
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
803int
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
818void
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
835void
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
852void
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
869void
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
886void
887_bfd_evax_output_counted (abfd, value)
888 bfd *abfd;
889 char *value;
890{
891int 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 {
53d3ce37 900 (*_bfd_error_handler) (_("_bfd_evax_output_counted called with zero bytes"));
c3d8e071
ILT
901 return;
902 }
903 if (len > 255)
904 {
53d3ce37 905 (*_bfd_error_handler) (_("_bfd_evax_output_counted called with too many bytes"));
c3d8e071
ILT
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
915void
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
937void
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
bf53bd9f 955/* this hash routine borrowed from GNU-EMACS, and strengthened slightly ERY*/
c3d8e071 956
bf53bd9f
ILT
957static int
958hash_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;
c3d8e071 965
bf53bd9f
ILT
966 while (p != end)
967 {
968 c = *p++;
969 hash = ((hash << 3) + (hash << 15) + (hash >> 28) + c);
970 }
971 return hash;
972}
973
412222d9 974/* Generate a length-hashed VMS symbol name (limited to maxlen chars). */
8696b2db 975
c3d8e071 976char *
412222d9 977_bfd_evax_length_hash_symbol (abfd, in, maxlen)
bf53bd9f
ILT
978 bfd *abfd;
979 const char *in;
412222d9 980 int maxlen;
c3d8e071 981{
bf53bd9f
ILT
982 long int init;
983 long int result;
8696b2db 984 int in_len;
bf53bd9f
ILT
985 char *pnt = 0;
986 char *new_name;
987 const char *old_name;
988 int i;
412222d9 989 static char outbuf[EOBJ_S_C_SYMSIZ+1];
bf53bd9f 990 char *out = outbuf;
c3d8e071
ILT
991
992#if EVAX_DEBUG
8696b2db 993 evax_debug(4, "_bfd_evax_length_hash_symbol \"%s\"\n", in);
bf53bd9f
ILT
994#endif
995
412222d9
ILT
996 if (maxlen > EOBJ_S_C_SYMSIZ)
997 maxlen = EOBJ_S_C_SYMSIZ;
998
bf53bd9f
ILT
999 new_name = out; /* save this for later. */
1000
1001 /* We may need to truncate the symbol, save the hash for later. */
1002
8696b2db 1003 in_len = strlen (in);
bf53bd9f 1004
412222d9 1005 result = (in_len > maxlen) ? hash_string (in) : 0;
bf53bd9f 1006
8696b2db 1007 old_name = in;
c3d8e071 1008
8696b2db 1009 /* Do the length checking. */
bf53bd9f 1010
412222d9
ILT
1011 if (in_len <= maxlen)
1012 {
1013 i = in_len;
1014 }
1015 else
1016 {
1017 if (PRIV(flag_hash_long_names))
1018 i = maxlen-9;
bf53bd9f 1019 else
412222d9
ILT
1020 i = maxlen;
1021 }
bf53bd9f 1022
8696b2db
ILT
1023 strncpy (out, in, i);
1024 in += i;
1025 out += i;
1026
412222d9 1027 if ((in_len > maxlen)
8696b2db
ILT
1028 && PRIV(flag_hash_long_names))
1029 sprintf (out, "_%08x", result);
1030 else
412222d9 1031 *out = 0;
c3d8e071
ILT
1032
1033#if EVAX_DEBUG
bf53bd9f 1034 evax_debug(4, "--> [%d]\"%s\"\n", strlen (outbuf), outbuf);
c3d8e071
ILT
1035#endif
1036
412222d9 1037 if (in_len > maxlen
bf53bd9f
ILT
1038 && PRIV(flag_hash_long_names)
1039 && PRIV(flag_show_after_trunc))
53d3ce37 1040 printf (_("Symbol %s replaced by %s\n"), old_name, new_name);
bf53bd9f
ILT
1041
1042 return outbuf;
c3d8e071 1043}
bf53bd9f 1044
This page took 0.146708 seconds and 4 git commands to generate.