Enable dosrel for special dos installation (appending of .exe to
[deliverable/binutils-gdb.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 (kkaempf@progis.de)
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 newptr = (evax_section *) bfd_zalloc (abfd, sizeof (evax_section));
562 if (newptr == (evax_section *)NULL)
563 {
564 bfd_set_error (bfd_error_no_memory);
565 return NULL;
566 }
567 sptr = PRIV(evax_section_table)[section->index];
568 if (sptr == NULL)
569 {
570 PRIV(evax_section_table)[section->index] = (evax_section *)newptr;
571 }
572 else
573 {
574 while (sptr->next != NULL)
575 sptr = sptr->next;
576 sptr->next = newptr;
577 }
578 return newptr;
579 }
580
581
582 /* Save section data & offset to an evax_section structure
583 evax_section_table[] holds the evax_section chain */
584
585 boolean
586 _bfd_save_evax_section (abfd, section, data, offset, count)
587 bfd *abfd;
588 sec_ptr section;
589 PTR data;
590 file_ptr offset;
591 bfd_size_type count;
592 {
593 evax_section *sptr;
594
595 if (section->index >= EVAX_SECTION_COUNT)
596 {
597 bfd_set_error (bfd_error_nonrepresentable_section);
598 return false;
599 }
600 if (count == (bfd_size_type)0)
601 return true;
602 sptr = add_new_contents (abfd, section);
603 if (sptr == NULL)
604 return false;
605 sptr->contents = (unsigned char *) bfd_alloc (abfd, (int)count);
606 if (sptr->contents == (unsigned char *)NULL)
607 {
608 bfd_set_error (bfd_error_no_memory);
609 return false;
610 }
611 memcpy (sptr->contents, data, (int)count);
612 sptr->offset = (bfd_vma)offset;
613 sptr->size = count;
614
615 #if EVAX_DEBUG
616 evax_debug (6, "_bfd_save_evax_section sptr = %08lx\n", sptr);
617 _bfd_hexdump (6, data, count, (int)offset);
618 #endif
619
620 return true;
621 }
622
623
624 /* Get evax_section pointer to saved contents for section # index */
625
626 evax_section *
627 _bfd_get_evax_section (abfd, index)
628 bfd *abfd;
629 int index;
630 {
631 if (index >= EVAX_SECTION_COUNT)
632 {
633 bfd_set_error (bfd_error_nonrepresentable_section);
634 return NULL;
635 }
636 return PRIV(evax_section_table)[index];
637 }
638
639 \f
640 /* Object output routines */
641
642 /* Begin new record or record header
643 write 2 bytes rectype
644 write 2 bytes record length (filled in at flush)
645 write 2 bytes header type (ommitted if rechead == -1) */
646
647 void
648 _bfd_evax_output_begin (abfd, rectype, rechead)
649 bfd *abfd;
650 int rectype;
651 int rechead;
652 {
653 #if EVAX_DEBUG
654 evax_debug (6, "_bfd_evax_output_begin(type %d, head %d)\n", rectype,
655 rechead);
656 #endif
657
658 _bfd_evax_output_short (abfd,rectype);
659
660 /* save current output position to fill in lenght later */
661
662 if (PRIV(push_level) > 0)
663 PRIV(length_pos) = PRIV(output_size);
664
665 #if EVAX_DEBUG
666 evax_debug (6, "_bfd_evax_output_begin: length_pos = %d\n",
667 PRIV(length_pos));
668 #endif
669
670 _bfd_evax_output_short (abfd,0); /* placeholder for length */
671
672 if (rechead != -1)
673 _bfd_evax_output_short (abfd,rechead);
674
675 return;
676 }
677
678
679 /* Set record/subrecord alignment */
680
681 void
682 _bfd_evax_output_alignment (abfd, alignto)
683 bfd *abfd;
684 int alignto;
685 {
686 #if EVAX_DEBUG
687 evax_debug (6, "_bfd_evax_output_alignment(%d)\n", alignto);
688 #endif
689
690 PRIV(output_alignment) = alignto;
691 return;
692 }
693
694
695 /* Prepare for subrecord fields */
696
697 void
698 _bfd_evax_output_push (abfd)
699 bfd *abfd;
700 {
701 #if EVAX_DEBUG
702 evax_debug (6, "evax_output_push(pushed_size = %d)\n", PRIV(output_size));
703 #endif
704
705 PRIV(push_level)++;
706 PRIV(pushed_size) = PRIV(output_size);
707 return;
708 }
709
710
711 /* End of subrecord fields */
712
713 void
714 _bfd_evax_output_pop (abfd)
715 bfd *abfd;
716 {
717 #if EVAX_DEBUG
718 evax_debug (6, "evax_output_pop(pushed_size = %d)\n", PRIV(pushed_size));
719 #endif
720
721 _bfd_evax_output_flush (abfd);
722 PRIV(length_pos) = 2;
723
724 #if EVAX_DEBUG
725 evax_debug (6, "evax_output_pop: length_pos = %d\n", PRIV(length_pos));
726 #endif
727
728 PRIV(pushed_size) = 0;
729 PRIV(push_level)--;
730 return;
731 }
732
733
734 /* Flush unwritten output, ends current record */
735
736 void
737 _bfd_evax_output_flush (abfd)
738 bfd *abfd;
739 {
740 int real_size = PRIV(output_size);
741 int aligncount;
742 int length;
743
744 #if EVAX_DEBUG
745 evax_debug (6, "_bfd_evax_output_flush(real_size = %d, pushed_size %d at lenpos %d)\n",
746 real_size, PRIV(pushed_size), PRIV(length_pos));
747 #endif
748
749 if (PRIV(push_level) > 0)
750 length = real_size - PRIV(pushed_size);
751 else
752 length = real_size;
753
754 if (length == 0)
755 return;
756 aligncount = (PRIV(output_alignment)
757 - (length % PRIV(output_alignment))) % PRIV(output_alignment);
758
759 #if EVAX_DEBUG
760 evax_debug (6, "align: adding %d bytes\n", aligncount);
761 #endif
762
763 while(aligncount-- > 0)
764 {
765 PRIV(output_buf)[real_size++] = 0;
766 #if 0
767 /* this is why I *love* vms: inconsistency :-}
768 alignment is added to the subrecord length
769 but not to the record length */
770 if (PRIV(push_level) > 0)
771 #endif
772 length++;
773 }
774
775 /* put length to buffer */
776 PRIV(output_size) = PRIV(length_pos);
777 _bfd_evax_output_short (abfd, (unsigned int)length);
778
779 if (PRIV(push_level) == 0)
780 {
781 #ifndef VMS
782 /* write length first, see FF_FOREIGN in the input routines */
783 fwrite (PRIV(output_buf)+2, 2, 1, (FILE *)abfd->iostream);
784 #endif
785 fwrite (PRIV(output_buf), real_size, 1, (FILE *)abfd->iostream);
786
787 PRIV(output_size) = 0;
788 }
789 else
790 {
791 PRIV(output_size) = real_size;
792 PRIV(pushed_size) = PRIV(output_size);
793 }
794
795 return;
796 }
797
798
799 /* End record output */
800
801 void
802 _bfd_evax_output_end (abfd)
803 bfd *abfd;
804 {
805 #if EVAX_DEBUG
806 evax_debug (6, "_bfd_evax_output_end\n");
807 #endif
808
809 _bfd_evax_output_flush (abfd);
810
811 return;
812 }
813
814
815 /* check remaining buffer size
816
817 return what's left. */
818
819 int
820 _bfd_evax_output_check (abfd, size)
821 bfd *abfd;
822 int size;
823 {
824 #if EVAX_DEBUG
825 evax_debug (6, "_bfd_evax_output_check(%d)\n", size);
826 #endif
827
828 return (MAX_OUTREC_SIZE - (PRIV(output_size) + size + MIN_OUTREC_LUFT));
829 }
830
831
832 /* Output byte (8 bit) value */
833
834 void
835 _bfd_evax_output_byte (abfd, value)
836 bfd *abfd;
837 unsigned int value;
838 {
839 #if EVAX_DEBUG
840 evax_debug (6, "_bfd_evax_output_byte(%02x)\n", value);
841 #endif
842
843 bfd_put_8 (abfd, value & 0xff, PRIV(output_buf) + PRIV(output_size));
844 PRIV(output_size) += 1;
845 return;
846 }
847
848
849 /* Output short (16 bit) value */
850
851 void
852 _bfd_evax_output_short (abfd, value)
853 bfd *abfd;
854 unsigned int value;
855 {
856 #if EVAX_DEBUG
857 evax_debug (6, "_bfd_evax_output_short (%04x)\n", value);
858 #endif
859
860 bfd_put_16 (abfd, value & 0xffff, PRIV(output_buf) + PRIV(output_size));
861 PRIV(output_size) += 2;
862 return;
863 }
864
865
866 /* Output long (32 bit) value */
867
868 void
869 _bfd_evax_output_long (abfd, value)
870 bfd *abfd;
871 unsigned long value;
872 {
873 #if EVAX_DEBUG
874 evax_debug (6, "_bfd_evax_output_long (%08lx)\n", value);
875 #endif
876
877 bfd_put_32 (abfd, value, PRIV(output_buf) + PRIV(output_size));
878 PRIV(output_size) += 4;
879 return;
880 }
881
882
883 /* Output quad (64 bit) value */
884
885 void
886 _bfd_evax_output_quad (abfd, value)
887 bfd *abfd;
888 uquad value;
889 {
890 #if EVAX_DEBUG
891 evax_debug (6, "_bfd_evax_output_quad(%016lx)\n", value);
892 #endif
893
894 bfd_put_64(abfd, value, PRIV(output_buf) + PRIV(output_size));
895 PRIV(output_size) += 8;
896 return;
897 }
898
899
900 /* Output c-string as counted string */
901
902 void
903 _bfd_evax_output_counted (abfd, value)
904 bfd *abfd;
905 char *value;
906 {
907 int len;
908
909 #if EVAX_DEBUG
910 evax_debug (6, "_bfd_evax_output_counted(%s)\n", value);
911 #endif
912
913 len = strlen (value);
914 if (len == 0)
915 {
916 (*_bfd_error_handler) ("_bfd_evax_output_counted called with zero bytes");
917 return;
918 }
919 if (len > 255)
920 {
921 (*_bfd_error_handler) ("_bfd_evax_output_counted called with too many bytes");
922 return;
923 }
924 _bfd_evax_output_byte (abfd, len & 0xff);
925 _bfd_evax_output_dump (abfd, (unsigned char *)value, len);
926 }
927
928
929 /* Output character area */
930
931 void
932 _bfd_evax_output_dump (abfd, data, length)
933 bfd *abfd;
934 unsigned char *data;
935 int length;
936 {
937 #if EVAX_DEBUG
938 evax_debug (6, "_bfd_evax_output_dump(%d)\n", length);
939 #endif
940
941 if (length == 0)
942 return;
943
944 memcpy (PRIV(output_buf) + PRIV(output_size), data, length);
945 PRIV(output_size) += length;
946
947 return;
948 }
949
950
951 /* Output count bytes of value */
952
953 void
954 _bfd_evax_output_fill (abfd, value, count)
955 bfd *abfd;
956 int value;
957 int count;
958 {
959 #if EVAX_DEBUG
960 evax_debug (6, "_bfd_evax_output_fill(val %02x times %d)\n", value, count);
961 #endif
962
963 if (count == 0)
964 return;
965 memset (PRIV(output_buf) + PRIV(output_size), value, count);
966 PRIV(output_size) += count;
967
968 return;
969 }
970
971 /*-----------------------------------------------------------------------------*/
972
973 /* Return basename (stripped of directory information) of filename */
974
975 char *
976 _bfd_evax_basename (name)
977 char *name;
978 {
979 char *ptr;
980
981 #if EVAX_DEBUG
982 evax_debug (6, "_bfd_evax_basename %s -> ", name);
983 #endif
984
985 #ifndef VMS
986 /* assume unix host */
987 ptr = strrchr (name, '.');
988 if (ptr)
989 *ptr = 0;
990 ptr = strrchr (name, '/');
991 if (ptr)
992 *ptr++ = 0;
993 else
994 ptr = name;
995 #else
996 /* assume vms host */
997 ptr = strrchr (name, '.');
998 if (ptr)
999 {
1000 *ptr = 0;
1001 ptr = name;
1002 }
1003 else
1004 {
1005 ptr = strrchr (name, ']');
1006 if (ptr)
1007 *ptr++ = 0;
1008 else
1009 {
1010 ptr = strrchr (name, ':');
1011 if (ptr)
1012 *ptr++ = 0;
1013 else
1014 ptr = name;
1015 }
1016 }
1017 #endif
1018
1019 #if EVAX_DEBUG
1020 evax_debug (6, "%s\n", ptr);
1021 #endif
1022
1023 return ptr;
1024 }
1025
1026
1027 /* Manufacure a VMS like time on a unix based system.
1028 stolen from obj-vms.c */
1029
1030 char *
1031 _bfd_get_vms_time_string ()
1032 {
1033 static char tbuf[18];
1034 #ifndef VMS
1035 #include <sys/types.h>
1036 #include <time.h>
1037
1038 char *pnt;
1039 time_t timeb;
1040 time (&timeb);
1041 pnt = ctime (&timeb);
1042 pnt[3] = 0;
1043 pnt[7] = 0;
1044 pnt[10] = 0;
1045 pnt[16] = 0;
1046 pnt[24] = 0;
1047 sprintf (tbuf, "%2s-%3s-%s %s", pnt + 8, pnt + 4, pnt + 20, pnt + 11);
1048 #else
1049 #include <starlet.h>
1050 struct
1051 {
1052 int Size;
1053 char *Ptr;
1054 } Descriptor;
1055 Descriptor.Size = 17;
1056 Descriptor.Ptr = tbuf;
1057 sys$asctim (0, &Descriptor, 0, 0);
1058 #endif /* not VMS */
1059
1060 #if EVAX_DEBUG
1061 evax_debug (6, "vmstimestring:'%s'\n", tbuf);
1062 #endif
1063
1064 return tbuf;
1065 }
This page took 0.050604 seconds and 4 git commands to generate.