Thu Aug 8 12:21:56 1996 Klaus Kaempf <kkaempf@progis.de>
[binutils-gdb.git] / bfd / evax-etir.c
1 /* evax-etir.c -- BFD back-end for ALPHA EVAX (openVMS/AXP) files.
2 Copyright 1996 Free Software Foundation, Inc.
3 ETIR record handling functions
4
5 go and read the openVMS linker manual (esp. appendix B)
6 if you don't know what's going on here :-)
7
8 Written by Klaus Kämpf (kkaempf@progis.de)
9 of proGIS Softwareentwicklung, Aachen, Germany
10
11 This program is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation; either version 2 of the License, or
14 (at your option) any later version.
15
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU General Public License for more details.
20
21 You should have received a copy of the GNU General Public License
22 along with this program; if not, write to the Free Software
23 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
24
25
26 /* The following type abbreviations are used:
27
28 cs counted string (ascii string with length byte)
29 by byte (1 byte)
30 sh short (2 byte, 16 bit)
31 lw longword (4 byte, 32 bit)
32 qw quadword (8 byte, 64 bit)
33 da data stream */
34
35 #include <stdio.h>
36 #include <ctype.h>
37
38 #include "bfd.h"
39 #include "sysdep.h"
40 #include "bfdlink.h"
41 #include "libbfd.h"
42
43 #include "evax.h"
44
45 #if 0
46 static void location_save
47 PARAMS ((bfd *abfd, unsigned long index, unsigned long loc, int section));
48 static unsigned long location_restore
49 PARAMS ((bfd *abfd, unsigned long index, int *section));
50 #endif /* 0 */
51
52 static void image_set_ptr PARAMS ((bfd *abfd, int psect, uquad offset));
53 static void image_inc_ptr PARAMS ((bfd *abfd, uquad offset));
54 static void image_dump PARAMS ((bfd *abfd, unsigned char *ptr, int size, int offset));
55 static void image_write_b PARAMS ((bfd *abfd, unsigned int value));
56 static void image_write_w PARAMS ((bfd *abfd, unsigned int value));
57 static void image_write_l PARAMS ((bfd *abfd, unsigned long value));
58 static void image_write_q PARAMS ((bfd *abfd, uquad value));
59
60 /*-----------------------------------------------------------------------------*/
61
62 #if 0
63
64 /* Save location counter at index */
65
66 static void
67 location_save (abfd, index, loc, section)
68 bfd *abfd;
69 unsigned long index;
70 unsigned long loc;
71 int section;
72 {
73 PRIV(location_stack)[index].value = loc;
74 PRIV(location_stack)[index].psect = section;
75
76 return;
77 }
78
79 /* Restore location counter from index */
80
81 static unsigned long
82 location_restore (abfd, index, section)
83 bfd *abfd;
84 unsigned long index;
85 int *section;
86 {
87 if (section != NULL)
88 *section = PRIV(location_stack)[index].psect;
89 return PRIV(location_stack)[index].value;
90 }
91
92 #endif /* 0 */
93 \f
94 /* routines to fill sections contents during etir read */
95
96 /* Initialize image buffer pointer to be filled */
97
98 static void
99 image_set_ptr (abfd, psect, offset)
100 bfd *abfd;
101 int psect;
102 uquad offset;
103 {
104 #if EVAX_DEBUG
105 evax_debug (4, "image_set_ptr(%d=%s, %d)\n",
106 psect, PRIV(sections)[psect]->name, offset);
107 #endif
108
109 PRIV(image_ptr) = PRIV(sections)[psect]->contents + offset;
110 return;
111 }
112
113
114 /* Increment image buffer pointer by offset */
115
116 static void
117 image_inc_ptr (abfd, offset)
118 bfd *abfd;
119 uquad offset;
120 {
121 #if EVAX_DEBUG
122 evax_debug (4, "image_inc_ptr(%d)\n", offset);
123 #endif
124
125 PRIV(image_ptr) += offset;
126
127 return;
128 }
129
130
131 /* Dump multiple bytes to section image */
132
133 static void
134 image_dump (abfd, ptr, size, offset)
135 bfd *abfd;
136 unsigned char *ptr;
137 int size;
138 int offset;
139 {
140 #if EVAX_DEBUG
141 evax_debug (6, "image_dump from (%p, %d) to (%p)\n", ptr, size, PRIV(image_ptr));
142 _bfd_hexdump (7, ptr, size, offset);
143 #endif
144
145 while (size-- > 0)
146 *PRIV(image_ptr)++ = *ptr++;
147 return;
148 }
149
150
151 /* Write byte to section image */
152
153 static void
154 image_write_b (abfd, value)
155 bfd *abfd;
156 unsigned int value;
157 {
158 #if EVAX_DEBUG
159 evax_debug (6, "image_write_b(%02x)\n", (int)value);
160 #endif
161
162 *PRIV(image_ptr)++ = (value & 0xff);
163 return;
164 }
165
166
167 /* Write 2-byte word to image */
168
169 static void
170 image_write_w (abfd, value)
171 bfd *abfd;
172 unsigned int value;
173 {
174 #if EVAX_DEBUG
175 evax_debug (6, "image_write_w(%04x)\n", (int)value);
176 #endif
177
178 bfd_putl16 (value, PRIV(image_ptr));
179 PRIV(image_ptr) += 2;
180
181 return;
182 }
183
184
185 /* Write 4-byte long to image */
186
187 static void
188 image_write_l (abfd, value)
189 bfd *abfd;
190 unsigned long value;
191 {
192 #if EVAX_DEBUG
193 evax_debug (6, "image_write_l(%08lx)\n", value);
194 #endif
195
196 bfd_putl32 (value, PRIV(image_ptr));
197 PRIV(image_ptr) += 4;
198
199 return;
200 }
201
202
203 /* Write 4-byte long to image */
204
205 static void
206 image_write_q (abfd, value)
207 bfd *abfd;
208 uquad value;
209 {
210 #if EVAX_DEBUG
211 evax_debug (6, "image_write_q(%016lx)\n", value);
212 #endif
213
214 bfd_putl64 (value, PRIV(image_ptr));
215 PRIV(image_ptr) += 8;
216
217 return;
218 }
219 \f
220
221 #define HIGHBIT(op) ((op & 0x80000000L) == 0x80000000L)
222
223 /* etir_sta
224
225 evax stack commands
226
227 handle sta_xxx commands in etir section
228 ptr points to data area in record
229
230 see table B-8 of the openVMS linker manual */
231
232 static boolean
233 etir_sta (abfd, cmd, ptr)
234 bfd *abfd;
235 int cmd;
236 unsigned char *ptr;
237 {
238
239 switch (cmd)
240 {
241 /* stack */
242
243 /* stack global
244 arg: cs symbol name
245
246 stack 32 bit value of symbol (high bits set to 0) */
247
248 case ETIR_S_C_STA_GBL:
249 {
250 char *name;
251 evax_symbol_entry *entry;
252
253 name = _bfd_evax_save_counted_string ((char *)ptr);
254 entry = (evax_symbol_entry *)
255 bfd_hash_lookup (PRIV(evax_symbol_table), name, false, false);
256 if (entry == (evax_symbol_entry *)NULL)
257 {
258 #if EVAX_DEBUG
259 evax_debug (3, "ETIR_S_C_STA_GBL: no symbol \"%s\"\n", name);
260 #endif
261 return false;
262 }
263 else
264 {
265 _bfd_evax_push (abfd, (uquad)(entry->symbol->value), -1);
266 }
267 }
268 break;
269
270 /* stack longword
271 arg: lw value
272
273 stack 32 bit value, sign extend to 64 bit */
274
275 case ETIR_S_C_STA_LW:
276 _bfd_evax_push (abfd, (uquad)bfd_getl32 (ptr), -1);
277 break;
278
279 /* stack global
280 arg: qw value
281
282 stack 64 bit value of symbol */
283
284 case ETIR_S_C_STA_QW:
285 _bfd_evax_push (abfd, (uquad)bfd_getl64(ptr), -1);
286 break;
287
288 /* stack psect base plus quadword offset
289 arg: lw section index
290 qw signed quadword offset (low 32 bits)
291
292 stack qw argument and section index
293 (see ETIR_S_C_STO_OFF, ETIR_S_C_CTL_SETRB) */
294
295 case ETIR_S_C_STA_PQ:
296 {
297 uquad dummy;
298 int psect;
299
300 psect = bfd_getl32 (ptr);
301 if (psect >= PRIV(egsd_sec_count))
302 {
303 (*_bfd_error_handler) ("Bad section index in ETIR_S_C_STA_PQ");
304 bfd_set_error (bfd_error_bad_value);
305 return false;
306 }
307 dummy = bfd_getl64 (ptr+4);
308 _bfd_evax_push (abfd, dummy, psect);
309 }
310 break;
311
312 /* all not supported */
313
314 case ETIR_S_C_STA_LI:
315 case ETIR_S_C_STA_MOD:
316 case ETIR_S_C_STA_CKARG:
317
318 (*_bfd_error_handler) ("Unsupported STA cmd %d", cmd);
319 return false;
320 break;
321
322 default:
323 (*_bfd_error_handler) ("Reserved STA cmd %d", cmd);
324 return false;
325 break;
326 }
327 return true;
328 }
329
330
331 /*
332 etir_sto
333
334 evax store commands
335
336 handle sto_xxx commands in etir section
337 ptr points to data area in record
338
339 see table B-9 of the openVMS linker manual */
340
341 static boolean
342 etir_sto (abfd, cmd, ptr)
343 bfd *abfd;
344 int cmd;
345 unsigned char *ptr;
346 {
347 uquad dummy;
348 int psect;
349
350 switch (cmd)
351 {
352
353 /* store byte: pop stack, write byte
354 arg: - */
355
356 case ETIR_S_C_STO_B:
357 dummy = _bfd_evax_pop (abfd, &psect);
358 #if 0
359 if (is_share) /* FIXME */
360 (*_bfd_error_handler) ("ETIR_S_C_STO_B: byte fixups not supported");
361 #endif
362 image_write_b (abfd, dummy & 0xff); /* FIXME: check top bits */
363 break;
364
365 /* store word: pop stack, write word
366 arg: - */
367
368 case ETIR_S_C_STO_W:
369 dummy = _bfd_evax_pop (abfd, &psect);
370 #if 0
371 if (is_share) /* FIXME */
372 (*_bfd_error_handler) ("ETIR_S_C_STO_B: word fixups not supported");
373 #endif
374 image_write_w (abfd, dummy & 0xffff); /* FIXME: check top bits */
375 break;
376
377 /* store longword: pop stack, write longword
378 arg: - */
379
380 case ETIR_S_C_STO_LW:
381 dummy = _bfd_evax_pop (abfd, &psect);
382 dummy += (PRIV(sections)[psect])->vma;
383 image_write_l (abfd, dummy & 0xffffffff);/* FIXME: check top bits */
384 #if 0 /* FIXME */
385 if (is_rel)
386 evax_debug (3, "ETIR_S_C_STO_LW: Relocation !\n");
387 if (is_share)
388 evax_debug (3, "ETIR_S_C_STO_LW: Fix-up share !\n");
389 #endif
390 break;
391
392 /* store quadword: pop stack, write quadword
393 arg: - */
394
395 case ETIR_S_C_STO_QW:
396 dummy = _bfd_evax_pop (abfd, &psect);
397 dummy += (PRIV(sections)[psect])->vma;
398 image_write_q(abfd, dummy); /* FIXME: check top bits */
399 #if 0 /* FIXME */
400 if (is_rel)
401 evax_debug (3, "ETIR_S_C_STO_LW: Relocation !\n");
402 if (is_share)
403 evax_debug (3, "ETIR_S_C_STO_LW: Fix-up share !\n");
404 #endif
405 break;
406
407 /* store immediate repeated: pop stack for repeat count
408 arg: lw byte count
409 da data */
410
411 case ETIR_S_C_STO_IMMR:
412 {
413 unsigned long size;
414
415 size = bfd_getl32 (ptr);
416 dummy = (unsigned long)_bfd_evax_pop (abfd, NULL);
417 while (dummy-- > 0L)
418 image_dump (abfd, ptr+4, size, 0);
419 }
420 break;
421
422 /* store global: write symbol value
423 arg: cs global symbol name */
424
425 case ETIR_S_C_STO_GBL:
426 {
427 evax_symbol_entry *entry;
428 char *name;
429
430 name = _bfd_evax_save_counted_string ((char *)ptr);
431 entry = (evax_symbol_entry *)bfd_hash_lookup (PRIV(evax_symbol_table), name, false, false);
432 if (entry == (evax_symbol_entry *)NULL)
433 {
434 (*_bfd_error_handler) ("ETIR_S_C_STO_GBL: no symbol \"%s\"",
435 name);
436 return false;
437 }
438 else
439 image_write_q (abfd, (uquad)(entry->symbol->value)); /* FIXME, reloc */
440 }
441 break;
442
443 /* store code address: write address of entry point
444 arg: cs global symbol name (procedure) */
445
446 case ETIR_S_C_STO_CA:
447 {
448 evax_symbol_entry *entry;
449 char *name;
450
451 name = _bfd_evax_save_counted_string ((char *)ptr);
452 entry = (evax_symbol_entry *) bfd_hash_lookup (PRIV(evax_symbol_table), name, false, false);
453 if (entry == (evax_symbol_entry *)NULL)
454 {
455 (*_bfd_error_handler) ("ETIR_S_C_STO_CA: no symbol \"%s\"",
456 name);
457 return false;
458 }
459 else
460 image_write_q (abfd, (uquad)(entry->symbol->value)); /* FIXME, reloc */
461 }
462 break;
463
464 /* not supported */
465
466 case ETIR_S_C_STO_RB:
467 case ETIR_S_C_STO_AB:
468 (*_bfd_error_handler) ("ETIR_S_C_STO_RB/AB: Not supported");
469 break;
470
471 /* store offset to psect: pop stack, add low 32 bits to base of psect
472 arg: - */
473
474 case ETIR_S_C_STO_OFF:
475 {
476 uquad q;
477 int psect;
478
479 q = _bfd_evax_pop (abfd, &psect);
480 q += (PRIV(sections)[psect])->vma;
481 image_write_q (abfd, q);
482 }
483 break;
484
485 /* store immediate
486 arg: lw count of bytes
487 da data */
488
489 case ETIR_S_C_STO_IMM:
490 {
491 int size;
492
493 size = bfd_getl32 (ptr);
494 image_dump (abfd, ptr+4, size, 0);
495 }
496 break;
497
498 /* this code is 'reserved to digital' according to the openVMS linker manual,
499 however it is generated by the DEC C compiler and defined in the include file.
500 FIXME, since the following is just a guess
501 store global longword: store 32bit value of symbol
502 arg: cs symbol name */
503
504 case ETIR_S_C_STO_GBL_LW:
505 {
506 evax_symbol_entry *entry;
507 char *name;
508
509 name = _bfd_evax_save_counted_string ((char *)ptr);
510 entry = (evax_symbol_entry *)bfd_hash_lookup (PRIV(evax_symbol_table), name, false, false);
511 if (entry == (evax_symbol_entry *)NULL)
512 {
513 #if EVAX_DEBUG
514 evax_debug (3, "ETIR_S_C_STO_GBL_LW: no symbol \"%s\"\n", name);
515 #endif
516 return false;
517 }
518 else
519 image_write_l (abfd, (unsigned long)(entry->symbol->value)); /* FIXME, reloc */
520 }
521 break;
522
523 /* not supported */
524
525 case ETIR_S_C_STO_LP_PSB:
526 (*_bfd_error_handler) ("ETIR_S_C_STO_LP_PSB: Not supported");
527 break;
528
529 /* */
530
531 case ETIR_S_C_STO_HINT_GBL:
532 (*_bfd_error_handler) ("ETIR_S_C_STO_HINT_GBL: not implemented");
533 break;
534
535 /* */
536
537 case ETIR_S_C_STO_HINT_PS:
538 (*_bfd_error_handler) ("ETIR_S_C_STO_HINT_PS: not implemented");
539 break;
540
541 default:
542 (*_bfd_error_handler) ("Reserved STO cmd %d", cmd);
543 break;
544 }
545
546 return true;
547 }
548
549 /* stack operator commands
550 all 32 bit signed arithmetic
551 all word just like a stack calculator
552 arguments are popped from stack, results are pushed on stack
553
554 see table B-10 of the openVMS linker manual */
555
556 static boolean
557 etir_opr (abfd, cmd, ptr)
558 bfd *abfd;
559 int cmd;
560 unsigned char *ptr;
561 {
562 long op1, op2;
563
564 switch (cmd)
565 {
566 /* operation */
567
568 /* no-op */
569
570 case ETIR_S_C_OPR_NOP:
571 break;
572
573 /* add */
574
575 case ETIR_S_C_OPR_ADD:
576 op1 = (long)_bfd_evax_pop (abfd, NULL);
577 op2 = (long)_bfd_evax_pop (abfd, NULL);
578 _bfd_evax_push (abfd, (uquad)(op1 + op2), -1);
579 break;
580
581 /* subtract */
582
583 case ETIR_S_C_OPR_SUB:
584 op1 = (long)_bfd_evax_pop (abfd, NULL);
585 op2 = (long)_bfd_evax_pop (abfd, NULL);
586 _bfd_evax_push (abfd, (uquad)(op2 - op1), -1);
587 break;
588
589 /* multiply */
590
591 case ETIR_S_C_OPR_MUL:
592 op1 = (long)_bfd_evax_pop (abfd, NULL);
593 op2 = (long)_bfd_evax_pop (abfd, NULL);
594 _bfd_evax_push (abfd, (uquad)(op1 * op2), -1);
595 break;
596
597 /* divide */
598
599 case ETIR_S_C_OPR_DIV:
600 op1 = (long)_bfd_evax_pop (abfd, NULL);
601 op2 = (long)_bfd_evax_pop (abfd, NULL);
602 if (op2 == 0)
603 _bfd_evax_push (abfd, (uquad)0L, -1);
604 else
605 _bfd_evax_push (abfd, (uquad)(op2 / op1), -1);
606 break;
607
608 /* logical and */
609
610 case ETIR_S_C_OPR_AND:
611 op1 = (long)_bfd_evax_pop (abfd, NULL);
612 op2 = (long)_bfd_evax_pop (abfd, NULL);
613 _bfd_evax_push (abfd, (uquad)(op1 & op2), -1);
614 break;
615
616 /* logical inclusive or */
617
618 case ETIR_S_C_OPR_IOR:
619 op1 = (long)_bfd_evax_pop (abfd, NULL);
620 op2 = (long)_bfd_evax_pop (abfd, NULL);
621 _bfd_evax_push (abfd, (uquad)(op1 | op2), -1);
622 break;
623
624 /* logical exclusive or */
625
626 case ETIR_S_C_OPR_EOR:
627 op1 = (long)_bfd_evax_pop (abfd, NULL);
628 op2 = (long)_bfd_evax_pop (abfd, NULL);
629 _bfd_evax_push (abfd, (uquad)(op1 ^ op2), -1);
630 break;
631
632 /* negate */
633
634 case ETIR_S_C_OPR_NEG:
635 op1 = (long)_bfd_evax_pop (abfd, NULL);
636 _bfd_evax_push (abfd, (uquad)(-op1), -1);
637 break;
638
639 /* complement */
640
641 case ETIR_S_C_OPR_COM:
642 op1 = (long)_bfd_evax_pop (abfd, NULL);
643 _bfd_evax_push (abfd, (uquad)(op1 ^ -1L), -1);
644 break;
645
646 /* insert field */
647
648 case ETIR_S_C_OPR_INSV:
649 (void)_bfd_evax_pop (abfd, NULL);
650 (*_bfd_error_handler) ("ETIR_S_C_OPR_INSV: Not supported");
651 break;
652
653 /* arithmetic shift */
654
655 case ETIR_S_C_OPR_ASH:
656 op1 = (long)_bfd_evax_pop (abfd, NULL);
657 op2 = (long)_bfd_evax_pop (abfd, NULL);
658 if (op2 < 0) /* shift right */
659 op1 >>= -op2;
660 else /* shift left */
661 op1 <<= op2;
662 _bfd_evax_push (abfd, (uquad)op1, -1);
663 break;
664
665 /* unsigned shift */
666
667 case ETIR_S_C_OPR_USH:
668 (*_bfd_error_handler) ("ETIR_S_C_OPR_USH: Not supported");
669 break;
670
671 /* rotate */
672
673 case ETIR_S_C_OPR_ROT:
674 (*_bfd_error_handler) ("ETIR_S_C_OPR_ROT: Not supported");
675 break;
676
677 /* select */
678
679 case ETIR_S_C_OPR_SEL:
680 if ((long)_bfd_evax_pop (abfd, NULL) & 0x01L)
681 (void)_bfd_evax_pop (abfd, NULL);
682 else
683 {
684 op1 = (long)_bfd_evax_pop (abfd, NULL);
685 (void)_bfd_evax_pop (abfd, NULL);
686 _bfd_evax_push (abfd, (uquad)op1, -1);
687 }
688 break;
689
690 /* redefine symbol to current location */
691
692 case ETIR_S_C_OPR_REDEF:
693 (*_bfd_error_handler) ("ETIR_S_C_OPR_REDEF: Not supported");
694 break;
695
696 /* define a literal */
697
698 case ETIR_S_C_OPR_DFLIT:
699 (*_bfd_error_handler) ("ETIR_S_C_OPR_DFLIT: Not supported");
700 break;
701
702 default:
703 (*_bfd_error_handler) ("Reserved OPR cmd %d", cmd);
704 break;
705 }
706
707 return true;
708 }
709
710
711 /* control commands
712
713 see table B-11 of the openVMS linker manual */
714
715 static boolean
716 etir_ctl (abfd, cmd, ptr)
717 bfd *abfd;
718 int cmd;
719 unsigned char *ptr;
720 {
721 uquad dummy;
722 int psect;
723
724 switch (cmd)
725 {
726 /* set relocation base: pop stack, set image location counter
727 arg: - */
728
729 case ETIR_S_C_CTL_SETRB:
730 dummy = _bfd_evax_pop (abfd, &psect);
731 image_set_ptr (abfd, psect, dummy);
732 break;
733
734 /* augment relocation base: increment image location counter by offset
735 arg: lw offset value */
736
737 case ETIR_S_C_CTL_AUGRB:
738 dummy = bfd_getl32 (ptr);
739 image_inc_ptr (abfd, dummy);
740 break;
741
742 /* define location: pop index, save location counter under index
743 arg: - */
744
745 case ETIR_S_C_CTL_DFLOC:
746 dummy = _bfd_evax_pop (abfd, NULL);
747 /* FIXME */
748 break;
749
750 /* set location: pop index, restore location counter from index
751 arg: - */
752
753 case ETIR_S_C_CTL_STLOC:
754 dummy = _bfd_evax_pop (abfd, &psect);
755 /* FIXME */
756 break;
757
758 /* stack defined location: pop index, push location counter from index
759 arg: - */
760
761 case ETIR_S_C_CTL_STKDL:
762 dummy = _bfd_evax_pop (abfd, &psect);
763 /* FIXME */
764 break;
765
766 default:
767 (*_bfd_error_handler) ("Reserved CTL cmd %d", cmd);
768 break;
769 }
770 return true;
771 }
772
773
774 /* store conditional commands
775
776 see table B-12 and B-13 of the openVMS linker manual */
777
778 static boolean
779 etir_stc (abfd, cmd, ptr)
780 bfd *abfd;
781 int cmd;
782 unsigned char *ptr;
783 {
784
785 switch (cmd)
786 {
787 /* 200 Store-conditional Linkage Pair
788 arg: */
789
790 case ETIR_S_C_STC_LP:
791 (*_bfd_error_handler) ("ETIR_S_C_STC_LP: not supported");
792 break;
793
794 /* 201 Store-conditional Linkage Pair with Procedure Signature
795 arg: lw linkage index
796 cs procedure name
797 by signature length
798 da signature */
799
800 case ETIR_S_C_STC_LP_PSB:
801 image_inc_ptr (abfd, 16); /* skip entry,procval */
802 break;
803
804 /* 202 Store-conditional Address at global address
805 arg: lw linkage index
806 cs global name */
807
808 case ETIR_S_C_STC_GBL:
809 (*_bfd_error_handler) ("ETIR_S_C_STC_GBL: not supported");
810 break;
811
812 /* 203 Store-conditional Code Address at global address
813 arg: lw linkage index
814 cs procedure name */
815
816 case ETIR_S_C_STC_GCA:
817 (*_bfd_error_handler) ("ETIR_S_C_STC_GCA: not supported");
818 break;
819
820 /* 204 Store-conditional Address at psect + offset
821 arg: lw linkage index
822 lw psect index
823 qw offset */
824
825 case ETIR_S_C_STC_PS:
826 (*_bfd_error_handler) ("ETIR_S_C_STC_PS: not supported");
827 break;
828
829 /* 205 Store-conditional NOP at address of global
830 arg: */
831
832 case ETIR_S_C_STC_NOP_GBL:
833
834 /* 206 Store-conditional NOP at pect + offset
835 arg: */
836
837 case ETIR_S_C_STC_NOP_PS:
838
839 /* 207 Store-conditional BSR at global address
840 arg: */
841
842 case ETIR_S_C_STC_BSR_GBL:
843
844 /* 208 Store-conditional BSR at pect + offset
845 arg: */
846
847 case ETIR_S_C_STC_BSR_PS:
848
849 /* 209 Store-conditional LDA at global address
850 arg: */
851
852 case ETIR_S_C_STC_LDA_GBL:
853
854 /* 210 Store-conditional LDA at psect + offset
855 arg: */
856
857 case ETIR_S_C_STC_LDA_PS:
858
859 /* 211 Store-conditional BSR or Hint at global address
860 arg: */
861
862 case ETIR_S_C_STC_BOH_GBL:
863
864 /* 212 Store-conditional BSR or Hint at pect + offset
865 arg: */
866
867 case ETIR_S_C_STC_BOH_PS:
868
869 /* 213 Store-conditional NOP,BSR or HINT at global address
870 arg: */
871
872 case ETIR_S_C_STC_NBH_GBL:
873
874 /* 214 Store-conditional NOP,BSR or HINT at psect + offset
875 arg: */
876
877 case ETIR_S_C_STC_NBH_PS:
878 /* FIXME (*_bfd_error_handler) ("ETIR_S_C_STC_xx: (%d) not supported", cmd); */
879 break;
880
881 default:
882 #if EVAX_DEBUG
883 evax_debug (3, "Reserved STC cmd %d", cmd);
884 #endif
885 break;
886 }
887 return true;
888 }
889
890
891 /* handle command from ETIR section */
892
893 static boolean
894 tir_cmd (abfd, cmd, ptr)
895 bfd *abfd;
896 int cmd;
897 unsigned char *ptr;
898 {
899 static struct {
900 int mincod;
901 int maxcod;
902 boolean (*explain) PARAMS((bfd *, int, unsigned char *));
903 } tir_table[] = {
904 { ETIR_S_C_MINSTACOD, ETIR_S_C_MAXSTACOD, etir_sta },
905 { ETIR_S_C_MINSTOCOD, ETIR_S_C_MAXSTOCOD, etir_sto },
906 { ETIR_S_C_MINOPRCOD, ETIR_S_C_MAXOPRCOD, etir_opr },
907 { ETIR_S_C_MINCTLCOD, ETIR_S_C_MAXCTLCOD, etir_ctl },
908 { ETIR_S_C_MINSTCCOD, ETIR_S_C_MAXSTCCOD, etir_stc },
909 { -1, -1, NULL }
910 };
911
912 int i = 0;
913 boolean res = true;
914
915 while (tir_table[i].mincod >= 0)
916 {
917 if ( (tir_table[i].mincod <= cmd)
918 && (cmd <= tir_table[i].maxcod))
919 {
920 res = tir_table[i].explain (abfd, cmd, ptr);
921 break;
922 }
923 i++;
924 }
925
926 return res;
927 }
928
929
930 /* Text Information and Relocation Records (OBJ$C_TIR)
931 handle etir record */
932
933 static boolean
934 analyze_etir (abfd, ptr, length)
935 bfd *abfd;
936 unsigned char *ptr;
937 unsigned int length;
938 {
939 int cmd;
940 unsigned char *maxptr;
941 boolean res = true;
942
943 maxptr = ptr + length;
944
945 while (ptr < maxptr)
946 {
947 cmd = bfd_getl16 (ptr);
948 length = bfd_getl16 (ptr + 2);
949 res = tir_cmd (abfd, cmd, ptr+4);
950 if (!res)
951 break;
952 ptr += length;
953 }
954 return res;
955 }
956
957
958 /* process ETIR record
959
960 return 0 on success, -1 on error */
961
962 int
963 _bfd_evax_slurp_etir (abfd)
964 bfd *abfd;
965 {
966
967 #if EVAX_DEBUG
968 evax_debug (2, "ETIR\n");
969 #endif
970
971 PRIV(evax_rec) += 4; /* skip type, size */
972 PRIV(rec_size) -= 4;
973 if (analyze_etir (abfd, PRIV(evax_rec), PRIV(rec_size)))
974 return 0;
975
976 return -1;
977 }
978
979
980 /* process EDBG record
981 return 0 on success, -1 on error
982
983 not implemented yet */
984
985 int
986 _bfd_evax_slurp_edbg (abfd)
987 bfd *abfd;
988 {
989 #if EVAX_DEBUG
990 evax_debug (2, "EDBG\n");
991 #endif
992
993 abfd->flags |= (HAS_DEBUG | HAS_LINENO);
994 return 0;
995 }
996
997
998 /* process ETBT record
999 return 0 on success, -1 on error
1000
1001 not implemented yet */
1002
1003 int
1004 _bfd_evax_slurp_etbt (abfd)
1005 bfd *abfd;
1006 {
1007 #if EVAX_DEBUG
1008 evax_debug (2, "ETBT\n");
1009 #endif
1010
1011 return 0;
1012 }
1013 \f
1014 /*----------------------------------------------------------------------*/
1015 /* */
1016 /* WRITE ETIR SECTION */
1017 /* */
1018 /* this is still under construction and therefore not documented */
1019 /* */
1020 /*----------------------------------------------------------------------*/
1021
1022 static void start_etir_record PARAMS ((bfd *abfd, int index, uquad offset, boolean justoffset));
1023 static void sto_imm PARAMS ((bfd *abfd, evax_section *sptr, bfd_vma vaddr, int index));
1024 static void end_etir_record PARAMS ((bfd *abfd));
1025
1026 static void
1027 sto_imm (abfd, sptr, vaddr, index)
1028 bfd *abfd;
1029 evax_section *sptr;
1030 bfd_vma vaddr;
1031 int index;
1032 {
1033 int size;
1034 int ssize;
1035 unsigned char *cptr;
1036
1037 #if EVAX_DEBUG
1038 evax_debug (8, "sto_imm %d bytes\n", sptr->size);
1039 _bfd_hexdump (9, sptr->contents, (int)sptr->size, (int)vaddr);
1040 #endif
1041
1042 ssize = sptr->size;
1043 cptr = sptr->contents;
1044
1045 while (ssize > 0)
1046 {
1047
1048 size = ssize; /* try all the rest */
1049
1050 if (_bfd_evax_output_check (abfd, size) < 0)
1051 { /* doesn't fit, split ! */
1052 end_etir_record (abfd);
1053 start_etir_record (abfd, index, vaddr, false);
1054 size = _bfd_evax_output_check (abfd, 0); /* get max size */
1055 if (size > ssize) /* more than what's left ? */
1056 size = ssize;
1057 }
1058
1059 _bfd_evax_output_begin (abfd, ETIR_S_C_STO_IMM, -1);
1060 _bfd_evax_output_long (abfd, (unsigned long)(size));
1061 _bfd_evax_output_dump (abfd, cptr, size);
1062 _bfd_evax_output_flush (abfd);
1063
1064 #if EVAX_DEBUG
1065 evax_debug (10, "dumped %d bytes\n", size);
1066 _bfd_hexdump (10, cptr, (int)size, (int)vaddr);
1067 #endif
1068
1069 vaddr += size;
1070 ssize -= size;
1071 cptr += size;
1072 }
1073
1074 return;
1075 }
1076
1077 /*-------------------------------------------------------------------*/
1078
1079 /* start ETIR record for section #index at virtual addr offset. */
1080
1081 static void
1082 start_etir_record (abfd, index, offset, justoffset)
1083 bfd *abfd;
1084 int index;
1085 uquad offset;
1086 boolean justoffset;
1087 {
1088 if (!justoffset)
1089 {
1090 _bfd_evax_output_begin (abfd, EOBJ_S_C_ETIR, -1); /* one ETIR per section */
1091 _bfd_evax_output_push (abfd);
1092 }
1093
1094 _bfd_evax_output_begin (abfd, ETIR_S_C_STA_PQ, -1); /* push start offset */
1095 _bfd_evax_output_long (abfd, (unsigned long)index);
1096 _bfd_evax_output_quad (abfd, (uquad)offset);
1097 _bfd_evax_output_flush (abfd);
1098
1099 _bfd_evax_output_begin (abfd, ETIR_S_C_CTL_SETRB, -1); /* start = pop() */
1100 _bfd_evax_output_flush (abfd);
1101
1102 return;
1103 }
1104
1105
1106 /* end etir record */
1107 static void
1108 end_etir_record (abfd)
1109 bfd *abfd;
1110 {
1111 _bfd_evax_output_pop (abfd);
1112 _bfd_evax_output_end (abfd);
1113 }
1114
1115 /* write section contents for bfd abfd */
1116
1117 int
1118 _bfd_evax_write_etir (abfd)
1119 bfd *abfd;
1120 {
1121 asection *section;
1122 evax_section *sptr;
1123 int nextoffset;
1124 char uname[200];
1125 char *nptr, *uptr;
1126
1127 #if EVAX_DEBUG
1128 evax_debug (2, "evax_write_etir(%p)\n", abfd);
1129 #endif
1130
1131 _bfd_evax_output_alignment (abfd, 4);
1132
1133 nextoffset = 0;
1134 PRIV(evax_linkage_index) = 1;
1135
1136 /* dump all other sections */
1137
1138 section = abfd->sections;
1139
1140 while (section != NULL)
1141 {
1142
1143 #if EVAX_DEBUG
1144 evax_debug (4, "writing %d. section '%s' (%d bytes)\n", section->index, section->name, (int)(section->_raw_size));
1145 #endif
1146
1147 if (section->flags & SEC_RELOC)
1148 {
1149 int i;
1150
1151 if ((i = section->reloc_count) <= 0)
1152 {
1153 (*_bfd_error_handler) ("SEC_RELOC with no relocs in section %s",
1154 section->name);
1155 }
1156 #if EVAX_DEBUG
1157 else
1158 {
1159 arelent **rptr;
1160 evax_debug (4, "%d relocations:\n", i);
1161 rptr = section->orelocation;
1162 while (i-- > 0)
1163 {
1164 evax_debug (4, "sym %s in sec %s, value %08lx, addr %08lx, off %08lx, len %d: %s\n",
1165 (*(*rptr)->sym_ptr_ptr)->name,
1166 (*(*rptr)->sym_ptr_ptr)->section->name,
1167 (long)(*(*rptr)->sym_ptr_ptr)->value,
1168 (*rptr)->address, (*rptr)->addend,
1169 bfd_get_reloc_size((*rptr)->howto),
1170 (*rptr)->howto->name);
1171 rptr++;
1172 }
1173 }
1174 #endif
1175 }
1176
1177 if (section->flags & SEC_HAS_CONTENTS)
1178 {
1179 bfd_vma vaddr; /* virtual addr in section */
1180
1181 sptr = _bfd_get_evax_section (abfd, section->index);
1182 if (sptr == NULL)
1183 {
1184 bfd_set_error (bfd_error_no_contents);
1185 return -1;
1186 }
1187
1188 vaddr = (bfd_vma)(sptr->offset);
1189
1190 start_etir_record (abfd, section->index, (uquad) sptr->offset,
1191 false);
1192
1193 while (sptr != NULL) /* one STA_PQ, CTL_SETRB per evax_section */
1194 {
1195
1196 if (section->flags & SEC_RELOC) /* check for relocs */
1197 {
1198 arelent **rptr = section->orelocation;
1199 int i = section->reloc_count;
1200 for (;;)
1201 {
1202 bfd_size_type addr = (*rptr)->address;
1203 int len = bfd_get_reloc_size ((*rptr)->howto);
1204 if (sptr->offset < addr) /* sptr starts before reloc */
1205 {
1206 int before = addr - sptr->offset;
1207 if (sptr->size <= before) /* complete before */
1208 {
1209 sto_imm (abfd, sptr, vaddr, section->index);
1210 vaddr += sptr->size;
1211 break;
1212 }
1213 else /* partly before */
1214 {
1215 int after = sptr->size - before;
1216 sptr->size = before;
1217 sto_imm (abfd, sptr, vaddr, section->index);
1218 vaddr += sptr->size;
1219 sptr->contents += before;
1220 sptr->offset += before;
1221 sptr->size = after;
1222 }
1223 }
1224 else if (sptr->offset == addr) /* sptr starts at reloc */
1225 {
1226 asymbol *sym = *(*rptr)->sym_ptr_ptr;
1227 asection *sec = sym->section;
1228
1229 switch ((*rptr)->howto->type)
1230 {
1231 case ALPHA_R_IGNORE:
1232 break;
1233
1234 case ALPHA_R_REFLONG:
1235 {
1236 if (bfd_is_und_section (sym->section))
1237 {
1238 if (_bfd_evax_output_check (abfd,
1239 strlen((char *)sym->name))
1240 < 0)
1241 {
1242 end_etir_record (abfd);
1243 start_etir_record (abfd,
1244 section->index,
1245 vaddr, false);
1246 }
1247 _bfd_evax_output_begin (abfd,
1248 ETIR_S_C_STO_GBL_LW,
1249 -1);
1250 uptr = uname;
1251 nptr = (char *)sym->name;
1252 while (*nptr)
1253 {
1254 if (islower (*nptr))
1255 *uptr = toupper (*nptr);
1256 else
1257 *uptr = *nptr;
1258 nptr++;
1259 uptr++;
1260 }
1261 *uptr = 0;
1262 _bfd_evax_output_counted (abfd, uname);
1263 _bfd_evax_output_flush (abfd);
1264 }
1265 else if (bfd_is_abs_section (sym->section))
1266 {
1267 if (_bfd_evax_output_check (abfd, 16) < 0)
1268 {
1269 end_etir_record (abfd);
1270 start_etir_record (abfd,
1271 section->index,
1272 vaddr, false);
1273 }
1274 _bfd_evax_output_begin (abfd,
1275 ETIR_S_C_STA_LW,
1276 -1);
1277 _bfd_evax_output_quad (abfd,
1278 (uquad)sym->value);
1279 _bfd_evax_output_flush (abfd);
1280 _bfd_evax_output_begin (abfd,
1281 ETIR_S_C_STO_LW,
1282 -1);
1283 _bfd_evax_output_flush (abfd);
1284 }
1285 else
1286 {
1287 if (_bfd_evax_output_check (abfd, 32) < 0)
1288 {
1289 end_etir_record (abfd);
1290 start_etir_record (abfd,
1291 section->index,
1292 vaddr, false);
1293 }
1294 _bfd_evax_output_begin (abfd,
1295 ETIR_S_C_STA_PQ,
1296 -1);
1297 _bfd_evax_output_long (abfd,
1298 (unsigned long)(sec->index));
1299 _bfd_evax_output_quad (abfd,
1300 ((uquad)(*rptr)->addend
1301 + (uquad)sym->value));
1302 _bfd_evax_output_flush (abfd);
1303 _bfd_evax_output_begin (abfd,
1304 ETIR_S_C_STO_LW,
1305 -1);
1306 _bfd_evax_output_flush (abfd);
1307 }
1308 }
1309 break;
1310
1311 case ALPHA_R_REFQUAD:
1312 {
1313 if (bfd_is_und_section (sym->section))
1314 {
1315 if (_bfd_evax_output_check (abfd,
1316 strlen((char *)sym->name))
1317 < 0)
1318 {
1319 end_etir_record (abfd);
1320 start_etir_record (abfd,
1321 section->index,
1322 vaddr, false);
1323 }
1324 _bfd_evax_output_begin (abfd,
1325 ETIR_S_C_STO_GBL,
1326 -1);
1327 uptr = uname;
1328 nptr = (char *)sym->name;
1329 while (*nptr)
1330 {
1331 if (islower (*nptr))
1332 *uptr = toupper (*nptr);
1333 else
1334 *uptr = *nptr;
1335 nptr++;
1336 uptr++;
1337 }
1338 *uptr = 0;
1339 _bfd_evax_output_counted (abfd, uname);
1340 _bfd_evax_output_flush (abfd);
1341 }
1342 else if (bfd_is_abs_section (sym->section))
1343 {
1344 if (_bfd_evax_output_check (abfd, 16) < 0)
1345 {
1346 end_etir_record (abfd);
1347 start_etir_record (abfd,
1348 section->index,
1349 vaddr, false);
1350 }
1351 _bfd_evax_output_begin (abfd,
1352 ETIR_S_C_STA_QW,
1353 -1);
1354 _bfd_evax_output_quad (abfd,
1355 (uquad)sym->value);
1356 _bfd_evax_output_flush (abfd);
1357 _bfd_evax_output_begin (abfd,
1358 ETIR_S_C_STO_QW,
1359 -1);
1360 _bfd_evax_output_flush (abfd);
1361 }
1362 else
1363 {
1364 if (_bfd_evax_output_check (abfd, 32) < 0)
1365 {
1366 end_etir_record (abfd);
1367 start_etir_record (abfd,
1368 section->index,
1369 vaddr, false);
1370 }
1371 _bfd_evax_output_begin (abfd,
1372 ETIR_S_C_STA_PQ,
1373 -1);
1374 _bfd_evax_output_long (abfd,
1375 (unsigned long)(sec->index));
1376 _bfd_evax_output_quad (abfd,
1377 ((uquad)(*rptr)->addend
1378 + (uquad)sym->value));
1379 _bfd_evax_output_flush (abfd);
1380 _bfd_evax_output_begin (abfd,
1381 ETIR_S_C_STO_OFF,
1382 -1);
1383 _bfd_evax_output_flush (abfd);
1384 }
1385 }
1386 break;
1387
1388 case ALPHA_R_HINT:
1389 {
1390 int hint_size;
1391
1392 hint_size = sptr->size;
1393 sptr->size = len;
1394 sto_imm (abfd, sptr, vaddr, section->index);
1395 sptr->size = hint_size;
1396 #if 0
1397 evax_output_begin(abfd, ETIR_S_C_STO_HINT_GBL, -1);
1398 evax_output_long(abfd, (unsigned long)(sec->index));
1399 evax_output_quad(abfd, (uquad)addr);
1400 uptr = uname;
1401 nptr = (char *)(*(*rptr)->sym_ptr_ptr)->name;
1402 while (*nptr)
1403 {
1404 if (islower (*nptr))
1405 *uptr = toupper (*nptr);
1406 else
1407 *uptr = *nptr;
1408 nptr++;
1409 uptr++;
1410 }
1411 *uptr = 0;
1412
1413 evax_output_counted(abfd, uname);
1414 evax_output_flush(abfd);
1415 #endif
1416 }
1417 break;
1418 #if 0
1419 case ALPHA_R_BRADDR:
1420 break;
1421 case ALPHA_R_SREL16:
1422 break;
1423 case ALPHA_R_SREL32:
1424 break;
1425 case ALPHA_R_SREL64:
1426 break;
1427 case ALPHA_R_OP_PUSH:
1428 break;
1429 case ALPHA_R_OP_STORE:
1430 break;
1431 case ALPHA_R_OP_PSUB:
1432 break;
1433 case ALPHA_R_OP_PRSHIFT:
1434 break;
1435 #endif
1436 case ALPHA_R_LINKAGE:
1437 {
1438 if (_bfd_evax_output_check (abfd, 64) < 0)
1439 {
1440 end_etir_record (abfd);
1441 start_etir_record (abfd, section->index,
1442 vaddr, false);
1443 }
1444 _bfd_evax_output_begin (abfd,
1445 ETIR_S_C_STC_LP_PSB,
1446 -1);
1447 _bfd_evax_output_long (abfd,
1448 (unsigned long)PRIV(evax_linkage_index));
1449 PRIV(evax_linkage_index) += 2;
1450 uptr = uname;
1451 nptr = (char *)(*(*rptr)->sym_ptr_ptr)->name;
1452 while (*nptr)
1453 {
1454 if (islower (*nptr))
1455 *uptr = toupper (*nptr);
1456 else
1457 *uptr = *nptr;
1458 nptr++;
1459 uptr++;
1460 }
1461 *uptr = 0;
1462 _bfd_evax_output_counted (abfd, uname);
1463 _bfd_evax_output_byte (abfd, 0);
1464 _bfd_evax_output_flush (abfd);
1465 }
1466 break;
1467
1468 default:
1469 (*_bfd_error_handler) ("Unhandled relocation %s",
1470 (*rptr)->howto->name);
1471 break;
1472 }
1473
1474 vaddr += len;
1475
1476 if (len == sptr->size)
1477 {
1478 break;
1479 }
1480 else
1481 {
1482 sptr->contents += len;
1483 sptr->offset += len;
1484 sptr->size -= len;
1485 i--;
1486 rptr++;
1487 }
1488 }
1489 else /* sptr starts after reloc */
1490 {
1491 i--; /* check next reloc */
1492 rptr++;
1493 }
1494
1495 if (i==0) /* all reloc checked */
1496 {
1497 if (sptr->size > 0)
1498 {
1499 sto_imm (abfd, sptr, vaddr, section->index); /* dump rest */
1500 vaddr += sptr->size;
1501 }
1502 break;
1503 }
1504 } /* for (;;) */
1505 } /* if SEC_RELOC */
1506 else /* no relocs, just dump */
1507 {
1508 sto_imm (abfd, sptr, vaddr, section->index);
1509 vaddr += sptr->size;
1510 }
1511
1512 sptr = sptr->next;
1513
1514 } /* while (sptr != 0) */
1515
1516 end_etir_record (abfd);
1517
1518 } /* has_contents */
1519
1520 section = section->next;
1521 }
1522
1523 _bfd_evax_output_alignment(abfd, 2);
1524 return 0;
1525 }
1526
1527
1528 /* write traceback data for bfd abfd */
1529
1530 int
1531 _bfd_evax_write_etbt (abfd)
1532 bfd *abfd;
1533 {
1534 #if EVAX_DEBUG
1535 evax_debug (2, "evax_write_etbt(%p)\n", abfd);
1536 #endif
1537
1538 return 0;
1539 }
1540
1541
1542 /* write debug info for bfd abfd */
1543
1544 int
1545 _bfd_evax_write_edbg (abfd)
1546 bfd *abfd;
1547 {
1548 #if EVAX_DEBUG
1549 evax_debug (2, "evax_write_edbg(%p)\n", abfd);
1550 #endif
1551
1552 return 0;
1553 }