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