]> Git Repo - binutils.git/blob - bfd/evax-etir.c
Fix PHDRS test in linker testsuite by also dumping program header output
[binutils.git] / bfd / evax-etir.c
1 /* evax-etir.c -- BFD back-end for ALPHA EVAX (openVMS/Alpha) files.
2    Copyright 1996, 1997, 1998 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 <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
45 static void location_save
46   PARAMS ((bfd *abfd, unsigned long index, unsigned long loc, int section));
47 static unsigned long location_restore
48   PARAMS ((bfd *abfd, unsigned long index, int *section));
49 #endif /* 0 */
50
51 static void image_set_ptr PARAMS ((bfd *abfd, int psect, uquad offset));
52 static void image_inc_ptr PARAMS ((bfd *abfd, uquad offset));
53 static void image_dump PARAMS ((bfd *abfd, unsigned char *ptr, int size, int offset));
54 static void image_write_b PARAMS ((bfd *abfd, unsigned int value));
55 static void image_write_w PARAMS ((bfd *abfd, unsigned int value));
56 static void image_write_l PARAMS ((bfd *abfd, unsigned long value));
57 static void image_write_q PARAMS ((bfd *abfd, uquad value));
58
59 /*-----------------------------------------------------------------------------*/
60
61 #if 0
62
63 /* Save location counter at index  */
64
65 static void
66 location_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
80 static unsigned long
81 location_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
97 static void
98 image_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
115 static void
116 image_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
132 static void
133 image_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
152 static void
153 image_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
168 static void
169 image_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
186 static void
187 image_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
204 static void
205 image_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
231 static boolean
232 etir_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             {
302               (*_bfd_error_handler) (_("Bad section index in ETIR_S_C_STA_PQ"));
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
317         (*_bfd_error_handler) (_("Unsupported STA cmd %d"), cmd);
318         return false;
319       break;
320
321       default:
322         (*_bfd_error_handler) (_("Reserved STA cmd %d"), cmd);
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
340 static boolean
341 etir_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           {
433             (*_bfd_error_handler) (_("ETIR_S_C_STO_GBL: no symbol \"%s\""),
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           {
454             (*_bfd_error_handler) (_("ETIR_S_C_STO_CA: no symbol \"%s\""),
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:
467       (*_bfd_error_handler) (_("ETIR_S_C_STO_RB/AB: Not supported"));
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:
525       (*_bfd_error_handler) (_("ETIR_S_C_STO_LP_PSB: Not supported"));
526       break;
527
528     /* */
529
530     case ETIR_S_C_STO_HINT_GBL:
531       (*_bfd_error_handler) (_("ETIR_S_C_STO_HINT_GBL: not implemented"));
532       break;
533
534     /* */
535
536     case ETIR_S_C_STO_HINT_PS:
537       (*_bfd_error_handler) (_("ETIR_S_C_STO_HINT_PS: not implemented"));
538       break;
539
540     default:
541       (*_bfd_error_handler) (_("Reserved STO cmd %d"), cmd);
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
555 static boolean
556 etir_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);
649       (*_bfd_error_handler) (_("ETIR_S_C_OPR_INSV: Not supported"));
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:
667       (*_bfd_error_handler) (_("ETIR_S_C_OPR_USH: Not supported"));
668       break;
669
670       /* rotate  */
671
672     case ETIR_S_C_OPR_ROT:
673       (*_bfd_error_handler) (_("ETIR_S_C_OPR_ROT: Not supported"));
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:
692       (*_bfd_error_handler) (_("ETIR_S_C_OPR_REDEF: Not supported"));
693       break;
694
695       /* define a literal  */
696
697     case ETIR_S_C_OPR_DFLIT:
698       (*_bfd_error_handler) (_("ETIR_S_C_OPR_DFLIT: Not supported"));
699       break;
700
701     default:
702       (*_bfd_error_handler) (_("Reserved OPR cmd %d"), cmd);
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
714 static boolean
715 etir_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:
766       (*_bfd_error_handler) (_("Reserved CTL cmd %d"), cmd);
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
777 static boolean
778 etir_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:
790       (*_bfd_error_handler) (_("ETIR_S_C_STC_LP: not supported"));
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:
808       (*_bfd_error_handler) (_("ETIR_S_C_STC_GBL: not supported"));
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:
816       (*_bfd_error_handler) (_("ETIR_S_C_STC_GCA: not supported"));
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:
825       (*_bfd_error_handler) (_("ETIR_S_C_STC_PS: not supported"));
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:
877 /* FIXME     (*_bfd_error_handler) ("ETIR_S_C_STC_xx: (%d) not supported", cmd); */
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
892 static boolean
893 tir_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
932 static boolean
933 analyze_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
961 int
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
984 int
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
1002 int
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
1021 static void start_etir_record PARAMS ((bfd *abfd, int index, uquad offset, boolean justoffset));
1022 static void sto_imm PARAMS ((bfd *abfd, evax_section *sptr, bfd_vma vaddr, int index));
1023 static void end_etir_record PARAMS ((bfd *abfd));
1024
1025 static void
1026 sto_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
1080 static void
1081 start_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  */
1106 static void
1107 end_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
1116 int
1117 _bfd_evax_write_etir (abfd)
1118      bfd *abfd;
1119 {
1120   asection *section;
1121   evax_section *sptr;
1122   int nextoffset;
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             {
1150               (*_bfd_error_handler) (_("SEC_RELOC with no relocs in section %s"),
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
1174       if ((section->flags & SEC_HAS_CONTENTS)
1175         && (! bfd_is_com_section (section)))
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);
1248                                     _bfd_evax_output_counted (abfd,
1249                                                               _bfd_evax_length_hash_symbol (abfd, sym->name, EOBJ_S_C_SYMSIZ));
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);
1314                                     _bfd_evax_output_counted (abfd,
1315                                                               _bfd_evax_length_hash_symbol (abfd, sym->name, EOBJ_S_C_SYMSIZ));
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);
1376
1377                                 evax_output_counted(abfd, _bfd_evax_length_hash_symbol (abfd, sym->name, EOBJ_S_C_SYMSIZ));
1378                                 evax_output_flush(abfd);
1379 #endif
1380                               }
1381                               break;
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;
1396                                 _bfd_evax_output_counted (abfd,
1397                                                           _bfd_evax_length_hash_symbol (abfd, sym->name, EOBJ_S_C_SYMSIZ));
1398                                 _bfd_evax_output_byte (abfd, 0);
1399                                 _bfd_evax_output_flush (abfd);
1400                               }
1401                               break;
1402
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,
1418                                                           _bfd_evax_length_hash_symbol (abfd, sym->name, EOBJ_S_C_SYMSIZ));
1419                                 _bfd_evax_output_flush (abfd);
1420                               }
1421                               break;
1422
1423                             default:
1424                               (*_bfd_error_handler) (_("Unhandled relocation %s"),
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
1485 int
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
1499 int
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 }
This page took 0.110798 seconds and 4 git commands to generate.