]> Git Repo - binutils.git/blob - bfd/evax-etir.c
Fixed duplicate definition of h_accums field in fmt_53_sadd structure
[binutils.git] / bfd / evax-etir.c
1 /* evax-etir.c -- BFD back-end for ALPHA EVAX (openVMS/Alpha) files.
2    Copyright 1996, 1997 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"ampf ([email protected])
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
1125 #if EVAX_DEBUG
1126   evax_debug (2, "evax_write_etir(%p)\n", abfd);
1127 #endif
1128
1129   _bfd_evax_output_alignment (abfd, 4);
1130
1131   nextoffset = 0;
1132   PRIV(evax_linkage_index) = 1;
1133
1134   /* dump all other sections  */
1135
1136   section = abfd->sections;
1137
1138   while (section != NULL)
1139     {
1140
1141 #if EVAX_DEBUG
1142       evax_debug (4, "writing %d. section '%s' (%d bytes)\n", section->index, section->name, (int)(section->_raw_size));
1143 #endif
1144
1145       if (section->flags & SEC_RELOC)
1146         {
1147           int i;
1148
1149           if ((i = section->reloc_count) <= 0)
1150             {
1151               (*_bfd_error_handler) ("SEC_RELOC with no relocs in section %s",
1152                                      section->name);
1153             }
1154 #if EVAX_DEBUG
1155           else
1156             {
1157               arelent **rptr;
1158               evax_debug (4, "%d relocations:\n", i);
1159               rptr = section->orelocation;
1160               while (i-- > 0)
1161                 {
1162                   evax_debug (4, "sym %s in sec %s, value %08lx, addr %08lx, off %08lx, len %d: %s\n",
1163                               (*(*rptr)->sym_ptr_ptr)->name,
1164                               (*(*rptr)->sym_ptr_ptr)->section->name,
1165                               (long)(*(*rptr)->sym_ptr_ptr)->value,
1166                               (*rptr)->address, (*rptr)->addend,
1167                               bfd_get_reloc_size((*rptr)->howto),
1168                               (*rptr)->howto->name);
1169                   rptr++;
1170                 }
1171             }
1172 #endif
1173         }
1174
1175       if ((section->flags & SEC_HAS_CONTENTS)
1176         && (! bfd_is_com_section (section)))
1177         {
1178           bfd_vma vaddr;                /* virtual addr in section */
1179
1180           sptr = _bfd_get_evax_section (abfd, section->index);
1181           if (sptr == NULL)
1182             {
1183               bfd_set_error (bfd_error_no_contents);
1184               return -1;
1185             }
1186
1187           vaddr = (bfd_vma)(sptr->offset);
1188
1189           start_etir_record (abfd, section->index, (uquad) sptr->offset,
1190                              false);
1191
1192           while (sptr != NULL)                          /* one STA_PQ, CTL_SETRB per evax_section */
1193             {
1194
1195               if (section->flags & SEC_RELOC)                   /* check for relocs */
1196                 {
1197                   arelent **rptr = section->orelocation;
1198                   int i = section->reloc_count;
1199                   for (;;)
1200                     {
1201                       bfd_size_type addr = (*rptr)->address;
1202                       int len = bfd_get_reloc_size ((*rptr)->howto);
1203                       if (sptr->offset < addr)          /* sptr starts before reloc */
1204                         {
1205                           int before = addr - sptr->offset;
1206                           if (sptr->size <= before)             /* complete before */
1207                             {
1208                               sto_imm (abfd, sptr, vaddr, section->index);
1209                               vaddr += sptr->size;
1210                               break;
1211                             }
1212                           else                          /* partly before */
1213                             {
1214                               int after = sptr->size - before;
1215                               sptr->size = before;
1216                               sto_imm (abfd, sptr, vaddr, section->index);
1217                               vaddr += sptr->size;
1218                               sptr->contents += before;
1219                               sptr->offset += before;
1220                               sptr->size = after;
1221                             }
1222                         }
1223                       else if (sptr->offset == addr)    /* sptr starts at reloc */
1224                         {
1225                           asymbol *sym = *(*rptr)->sym_ptr_ptr;
1226                           asection *sec = sym->section;
1227
1228                           switch ((*rptr)->howto->type)
1229                             {
1230                             case ALPHA_R_IGNORE:
1231                               break;
1232
1233                             case ALPHA_R_REFLONG:
1234                               {
1235                                 if (bfd_is_und_section (sym->section))
1236                                   {
1237                                     if (_bfd_evax_output_check (abfd,
1238                                                                 strlen((char *)sym->name))
1239                                         < 0)
1240                                       {
1241                                         end_etir_record (abfd);
1242                                         start_etir_record (abfd,
1243                                                            section->index,
1244                                                            vaddr, false);
1245                                       }
1246                                     _bfd_evax_output_begin (abfd,
1247                                                             ETIR_S_C_STO_GBL_LW,
1248                                                             -1);
1249                                     _bfd_evax_output_counted (abfd,
1250                                                               _bfd_evax_length_hash_symbol (abfd, sym->name, EOBJ_S_C_SYMSIZ));
1251                                     _bfd_evax_output_flush (abfd);
1252                                   }
1253                                 else if (bfd_is_abs_section (sym->section))
1254                                   {
1255                                     if (_bfd_evax_output_check (abfd, 16) < 0)
1256                                       {
1257                                         end_etir_record (abfd);
1258                                         start_etir_record (abfd,
1259                                                            section->index,
1260                                                            vaddr, false);
1261                                       }
1262                                     _bfd_evax_output_begin (abfd,
1263                                                             ETIR_S_C_STA_LW,
1264                                                             -1);
1265                                     _bfd_evax_output_quad (abfd,
1266                                                            (uquad)sym->value);
1267                                     _bfd_evax_output_flush (abfd);
1268                                     _bfd_evax_output_begin (abfd,
1269                                                             ETIR_S_C_STO_LW,
1270                                                             -1);
1271                                     _bfd_evax_output_flush (abfd);
1272                                   }
1273                                 else
1274                                   {
1275                                     if (_bfd_evax_output_check (abfd, 32) < 0)
1276                                       {
1277                                         end_etir_record (abfd);
1278                                         start_etir_record (abfd,
1279                                                            section->index,
1280                                                            vaddr, false);
1281                                       }
1282                                     _bfd_evax_output_begin (abfd,
1283                                                             ETIR_S_C_STA_PQ,
1284                                                             -1);
1285                                     _bfd_evax_output_long (abfd,
1286                                                            (unsigned long)(sec->index));
1287                                     _bfd_evax_output_quad (abfd,
1288                                                            ((uquad)(*rptr)->addend
1289                                                             + (uquad)sym->value));
1290                                     _bfd_evax_output_flush (abfd);
1291                                     _bfd_evax_output_begin (abfd,
1292                                                             ETIR_S_C_STO_LW,
1293                                                             -1);
1294                                     _bfd_evax_output_flush (abfd);
1295                                   }
1296                               }
1297                               break;
1298
1299                             case ALPHA_R_REFQUAD:
1300                               {
1301                                 if (bfd_is_und_section (sym->section))
1302                                   {
1303                                     if (_bfd_evax_output_check (abfd,
1304                                                                 strlen((char *)sym->name))
1305                                         < 0)
1306                                       {
1307                                         end_etir_record (abfd);
1308                                         start_etir_record (abfd,
1309                                                            section->index,
1310                                                            vaddr, false);
1311                                       }
1312                                     _bfd_evax_output_begin (abfd,
1313                                                             ETIR_S_C_STO_GBL,
1314                                                             -1);
1315                                     _bfd_evax_output_counted (abfd,
1316                                                               _bfd_evax_length_hash_symbol (abfd, sym->name, EOBJ_S_C_SYMSIZ));
1317                                     _bfd_evax_output_flush (abfd);
1318                                   }
1319                                 else if (bfd_is_abs_section (sym->section))
1320                                   {
1321                                     if (_bfd_evax_output_check (abfd, 16) < 0)
1322                                       {
1323                                         end_etir_record (abfd);
1324                                         start_etir_record (abfd,
1325                                                            section->index,
1326                                                            vaddr, false);
1327                                       }
1328                                     _bfd_evax_output_begin (abfd,
1329                                                             ETIR_S_C_STA_QW,
1330                                                             -1);
1331                                     _bfd_evax_output_quad (abfd,
1332                                                            (uquad)sym->value);
1333                                     _bfd_evax_output_flush (abfd);
1334                                     _bfd_evax_output_begin (abfd,
1335                                                             ETIR_S_C_STO_QW,
1336                                                             -1);
1337                                     _bfd_evax_output_flush (abfd);
1338                                   }
1339                                 else
1340                                   {
1341                                     if (_bfd_evax_output_check (abfd, 32) < 0)
1342                                       {
1343                                         end_etir_record (abfd);
1344                                         start_etir_record (abfd,
1345                                                            section->index,
1346                                                            vaddr, false);
1347                                       }
1348                                     _bfd_evax_output_begin (abfd,
1349                                                             ETIR_S_C_STA_PQ,
1350                                                             -1);
1351                                     _bfd_evax_output_long (abfd,
1352                                                            (unsigned long)(sec->index));
1353                                     _bfd_evax_output_quad (abfd,
1354                                                            ((uquad)(*rptr)->addend
1355                                                             + (uquad)sym->value));
1356                                     _bfd_evax_output_flush (abfd);
1357                                     _bfd_evax_output_begin (abfd,
1358                                                             ETIR_S_C_STO_OFF,
1359                                                             -1);
1360                                     _bfd_evax_output_flush (abfd);
1361                                   }
1362                               }
1363                               break;
1364
1365                             case ALPHA_R_HINT:
1366                               {
1367                                 int hint_size;
1368
1369                                 hint_size = sptr->size;
1370                                 sptr->size = len;
1371                                 sto_imm (abfd, sptr, vaddr, section->index);
1372                                 sptr->size = hint_size;
1373 #if 0
1374                                 evax_output_begin(abfd, ETIR_S_C_STO_HINT_GBL, -1);
1375                                 evax_output_long(abfd, (unsigned long)(sec->index));
1376                                 evax_output_quad(abfd, (uquad)addr);
1377
1378                                 evax_output_counted(abfd, _bfd_evax_length_hash_symbol (abfd, sym->name, EOBJ_S_C_SYMSIZ));
1379                                 evax_output_flush(abfd);
1380 #endif
1381                               }
1382                               break;
1383                             case ALPHA_R_LINKAGE:
1384                               {
1385                                 if (_bfd_evax_output_check (abfd, 64) < 0)
1386                                   {
1387                                     end_etir_record (abfd);
1388                                     start_etir_record (abfd, section->index,
1389                                                        vaddr, false);
1390                                   }
1391                                 _bfd_evax_output_begin (abfd,
1392                                                         ETIR_S_C_STC_LP_PSB,
1393                                                         -1);
1394                                 _bfd_evax_output_long (abfd,
1395                                                        (unsigned long)PRIV(evax_linkage_index));
1396                                 PRIV(evax_linkage_index) += 2;
1397                                 _bfd_evax_output_counted (abfd,
1398                                                           _bfd_evax_length_hash_symbol (abfd, sym->name, EOBJ_S_C_SYMSIZ));
1399                                 _bfd_evax_output_byte (abfd, 0);
1400                                 _bfd_evax_output_flush (abfd);
1401                               }
1402                               break;
1403
1404                             case ALPHA_R_CODEADDR:
1405                               {
1406                                 if (_bfd_evax_output_check (abfd,
1407                                                             strlen((char *)sym->name))
1408                                     < 0)
1409                                   {
1410                                     end_etir_record (abfd);
1411                                     start_etir_record (abfd,
1412                                                        section->index,
1413                                                        vaddr, false);
1414                                   }
1415                                 _bfd_evax_output_begin (abfd,
1416                                                         ETIR_S_C_STO_CA,
1417                                                         -1);
1418                                 _bfd_evax_output_counted (abfd,
1419                                                           _bfd_evax_length_hash_symbol (abfd, sym->name, EOBJ_S_C_SYMSIZ));
1420                                 _bfd_evax_output_flush (abfd);
1421                               }
1422                               break;
1423
1424                             default:
1425                               (*_bfd_error_handler) ("Unhandled relocation %s",
1426                                                      (*rptr)->howto->name);
1427                               break;
1428                             }
1429
1430                           vaddr += len;
1431
1432                           if (len == sptr->size)
1433                             {
1434                               break;
1435                             }
1436                           else
1437                             {
1438                               sptr->contents += len;
1439                               sptr->offset += len;
1440                               sptr->size -= len;
1441                               i--;
1442                               rptr++;
1443                             }
1444                         }
1445                       else                                      /* sptr starts after reloc */
1446                         {
1447                           i--;                          /* check next reloc */
1448                           rptr++;
1449                         }
1450
1451                       if (i==0)                         /* all reloc checked */
1452                         {
1453                           if (sptr->size > 0)
1454                             {
1455                               sto_imm (abfd, sptr, vaddr, section->index);      /* dump rest */
1456                               vaddr += sptr->size;
1457                             }
1458                           break;
1459                         }
1460                     } /* for (;;) */
1461                 } /* if SEC_RELOC */
1462               else                                              /* no relocs, just dump */
1463                 {
1464                   sto_imm (abfd, sptr, vaddr, section->index);
1465                   vaddr += sptr->size;
1466                 }
1467
1468               sptr = sptr->next;
1469
1470             } /* while (sptr != 0) */
1471
1472           end_etir_record (abfd);
1473
1474         } /* has_contents */
1475
1476       section = section->next;
1477     }
1478
1479   _bfd_evax_output_alignment(abfd, 2);
1480   return 0;
1481 }
1482
1483
1484 /* write traceback data for bfd abfd  */
1485
1486 int
1487 _bfd_evax_write_etbt (abfd)
1488      bfd *abfd;
1489 {
1490 #if EVAX_DEBUG
1491   evax_debug (2, "evax_write_etbt(%p)\n", abfd);
1492 #endif
1493
1494   return 0;
1495 }
1496
1497
1498 /* write debug info for bfd abfd  */
1499
1500 int
1501 _bfd_evax_write_edbg (abfd)
1502      bfd *abfd;
1503 {
1504 #if EVAX_DEBUG
1505   evax_debug (2, "evax_write_edbg(%p)\n", abfd);
1506 #endif
1507
1508   return 0;
1509 }
This page took 0.104774 seconds and 4 git commands to generate.