]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - bfd/vms-tir.c
Switch sources over to use the GPL version 3
[thirdparty/binutils-gdb.git] / bfd / vms-tir.c
CommitLineData
252b5132
RH
1/* vms-tir.c -- BFD back-end for VAX (openVMS/VAX) and
2 EVAX (openVMS/Alpha) files.
3db64b00 3 Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2004, 2005, 2007
ca09e32b 4 Free Software Foundation, Inc.
252b5132
RH
5
6 TIR record handling functions
7 ETIR record handling functions
8
9 go and read the openVMS linker manual (esp. appendix B)
10 if you don't know what's going on here :-)
11
12 Written by Klaus K"ampf (kkaempf@rmi.de)
13
ca09e32b
NC
14 This program is free software; you can redistribute it and/or modify
15 it under the terms of the GNU General Public License as published by
cd123cb7 16 the Free Software Foundation; either version 3 of the License, or
ca09e32b 17 (at your option) any later version.
252b5132 18
ca09e32b
NC
19 This program is distributed in the hope that it will be useful,
20 but WITHOUT ANY WARRANTY; without even the implied warranty of
21 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 GNU General Public License for more details.
252b5132 23
ca09e32b
NC
24 You should have received a copy of the GNU General Public License
25 along with this program; if not, write to the Free Software
cd123cb7
NC
26 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
27 MA 02110-1301, USA. */
28
252b5132 29
252b5132
RH
30/* The following type abbreviations are used:
31
32 cs counted string (ascii string with length byte)
33 by byte (1 byte)
34 sh short (2 byte, 16 bit)
35 lw longword (4 byte, 32 bit)
36 qw quadword (8 byte, 64 bit)
37 da data stream */
38
252b5132 39#include "sysdep.h"
3db64b00 40#include "bfd.h"
252b5132
RH
41#include "bfdlink.h"
42#include "libbfd.h"
252b5132 43#include "vms.h"
ca09e32b 44\f
252b5132 45static int
7920ce38 46check_section (bfd * abfd, int size)
252b5132 47{
dc810e39 48 bfd_size_type offset;
252b5132 49
dc810e39 50 offset = PRIV (image_ptr) - PRIV (image_section)->contents;
eea6121a 51 if (offset + size > PRIV (image_section)->size)
252b5132 52 {
dc810e39
AM
53 PRIV (image_section)->contents
54 = bfd_realloc (PRIV (image_section)->contents, offset + size);
55 if (PRIV (image_section)->contents == 0)
252b5132
RH
56 {
57 (*_bfd_error_handler) (_("No Mem !"));
58 return -1;
59 }
eea6121a 60 PRIV (image_section)->size = offset + size;
dc810e39 61 PRIV (image_ptr) = PRIV (image_section)->contents + offset;
252b5132
RH
62 }
63
64 return 0;
65}
66
ca09e32b 67/* Routines to fill sections contents during tir/etir read. */
252b5132 68
ca09e32b 69/* Initialize image buffer pointer to be filled. */
252b5132
RH
70
71static void
7920ce38 72image_set_ptr (bfd * abfd, int psect, uquad offset)
252b5132
RH
73{
74#if VMS_DEBUG
75 _bfd_vms_debug (4, "image_set_ptr (%d=%s, %d)\n",
dc810e39 76 psect, PRIV (sections)[psect]->name, offset);
252b5132
RH
77#endif
78
dc810e39
AM
79 PRIV (image_ptr) = PRIV (sections)[psect]->contents + offset;
80 PRIV (image_section) = PRIV (sections)[psect];
252b5132
RH
81}
82
ca09e32b 83/* Increment image buffer pointer by offset. */
252b5132
RH
84
85static void
7920ce38 86image_inc_ptr (bfd * abfd, uquad offset)
252b5132
RH
87{
88#if VMS_DEBUG
89 _bfd_vms_debug (4, "image_inc_ptr (%d)\n", offset);
90#endif
91
dc810e39 92 PRIV (image_ptr) += offset;
252b5132
RH
93}
94
ca09e32b 95/* Dump multiple bytes to section image. */
252b5132
RH
96
97static void
7920ce38
NC
98image_dump (bfd * abfd,
99 unsigned char *ptr,
100 int size,
101 int offset ATTRIBUTE_UNUSED)
252b5132
RH
102{
103#if VMS_DEBUG
dc810e39
AM
104 _bfd_vms_debug (8, "image_dump from (%p, %d) to (%p)\n", ptr, size,
105 PRIV (image_ptr));
252b5132
RH
106 _bfd_hexdump (9, ptr, size, offset);
107#endif
108
dc810e39 109 if (PRIV (is_vax) && check_section (abfd, size))
252b5132
RH
110 return;
111
112 while (size-- > 0)
dc810e39 113 *PRIV (image_ptr)++ = *ptr++;
252b5132
RH
114}
115
ca09e32b 116/* Write byte to section image. */
252b5132
RH
117
118static void
7920ce38 119image_write_b (bfd * abfd, unsigned int value)
252b5132
RH
120{
121#if VMS_DEBUG
7920ce38 122 _bfd_vms_debug (6, "image_write_b (%02x)\n", (int) value);
252b5132
RH
123#endif
124
dc810e39 125 if (PRIV (is_vax) && check_section (abfd, 1))
252b5132
RH
126 return;
127
dc810e39 128 *PRIV (image_ptr)++ = (value & 0xff);
252b5132
RH
129}
130
ca09e32b 131/* Write 2-byte word to image. */
252b5132
RH
132
133static void
7920ce38 134image_write_w (bfd * abfd, unsigned int value)
252b5132
RH
135{
136#if VMS_DEBUG
7920ce38 137 _bfd_vms_debug (6, "image_write_w (%04x)\n", (int) value);
252b5132
RH
138#endif
139
dc810e39 140 if (PRIV (is_vax) && check_section (abfd, 2))
252b5132
RH
141 return;
142
dc810e39
AM
143 bfd_putl16 ((bfd_vma) value, PRIV (image_ptr));
144 PRIV (image_ptr) += 2;
252b5132
RH
145}
146
ca09e32b 147/* Write 4-byte long to image. */
252b5132
RH
148
149static void
7920ce38 150image_write_l (bfd * abfd, unsigned long value)
252b5132
RH
151{
152#if VMS_DEBUG
153 _bfd_vms_debug (6, "image_write_l (%08lx)\n", value);
154#endif
155
dc810e39 156 if (PRIV (is_vax) && check_section (abfd, 4))
252b5132
RH
157 return;
158
dc810e39
AM
159 bfd_putl32 ((bfd_vma) value, PRIV (image_ptr));
160 PRIV (image_ptr) += 4;
252b5132
RH
161}
162
ca09e32b 163/* Write 8-byte quad to image. */
252b5132
RH
164
165static void
7920ce38 166image_write_q (bfd * abfd, uquad value)
252b5132
RH
167{
168#if VMS_DEBUG
169 _bfd_vms_debug (6, "image_write_q (%016lx)\n", value);
170#endif
171
dc810e39 172 if (PRIV (is_vax) && check_section (abfd, 8))
252b5132
RH
173 return;
174
dc810e39
AM
175 bfd_putl64 (value, PRIV (image_ptr));
176 PRIV (image_ptr) += 8;
252b5132
RH
177}
178\f
ca09e32b 179static const char *
7920ce38 180cmd_name (int cmd)
ca09e32b
NC
181{
182 switch (cmd)
183 {
184 case ETIR_S_C_STA_GBL: return "ETIR_S_C_STA_GBL";
185 case ETIR_S_C_STA_PQ: return "ETIR_S_C_STA_PQ";
186 case ETIR_S_C_STA_LI: return "ETIR_S_C_STA_LI";
187 case ETIR_S_C_STA_MOD: return "ETIR_S_C_STA_MOD";
188 case ETIR_S_C_STA_CKARG: return "ETIR_S_C_STA_CKARG";
189 case ETIR_S_C_STO_B: return "ETIR_S_C_STO_B";
190 case ETIR_S_C_STO_W: return "ETIR_S_C_STO_W";
191 case ETIR_S_C_STO_GBL: return "ETIR_S_C_STO_GBL";
192 case ETIR_S_C_STO_CA: return "ETIR_S_C_STO_CA";
193 case ETIR_S_C_STO_RB: return "ETIR_S_C_STO_RB";
194 case ETIR_S_C_STO_AB: return "ETIR_S_C_STO_AB";
195 case ETIR_S_C_STO_GBL_LW: return "ETIR_S_C_STO_GBL_LW";
196 case ETIR_S_C_STO_LP_PSB: return "ETIR_S_C_STO_LP_PSB";
197 case ETIR_S_C_STO_HINT_GBL: return "ETIR_S_C_STO_HINT_GBL";
198 case ETIR_S_C_STO_HINT_PS: return "ETIR_S_C_STO_HINT_PS";
199 case ETIR_S_C_OPR_INSV: return "ETIR_S_C_OPR_INSV";
200 case ETIR_S_C_OPR_USH: return "ETIR_S_C_OPR_USH";
201 case ETIR_S_C_OPR_ROT: return "ETIR_S_C_OPR_ROT";
202 case ETIR_S_C_OPR_REDEF: return "ETIR_S_C_OPR_REDEF";
203 case ETIR_S_C_OPR_DFLIT: return "ETIR_S_C_OPR_DFLIT";
204 case ETIR_S_C_STC_LP: return "ETIR_S_C_STC_LP";
205 case ETIR_S_C_STC_GBL: return "ETIR_S_C_STC_GBL";
206 case ETIR_S_C_STC_GCA: return "ETIR_S_C_STC_GCA";
207 case ETIR_S_C_STC_PS: return "ETIR_S_C_STC_PS";
208 case ETIR_S_C_STC_NBH_PS: return "ETIR_S_C_STC_NBH_PS";
209 case ETIR_S_C_STC_NOP_GBL: return "ETIR_S_C_STC_NOP_GBL";
210 case ETIR_S_C_STC_NOP_PS: return "ETIR_S_C_STC_NOP_PS";
211 case ETIR_S_C_STC_BSR_GBL: return "ETIR_S_C_STC_BSR_GBL";
212 case ETIR_S_C_STC_BSR_PS: return "ETIR_S_C_STC_BSR_PS";
213 case ETIR_S_C_STC_LDA_GBL: return "ETIR_S_C_STC_LDA_GBL";
214 case ETIR_S_C_STC_LDA_PS: return "ETIR_S_C_STC_LDA_PS";
215 case ETIR_S_C_STC_BOH_GBL: return "ETIR_S_C_STC_BOH_GBL";
216 case ETIR_S_C_STC_BOH_PS: return "ETIR_S_C_STC_BOH_PS";
217 case ETIR_S_C_STC_NBH_GBL: return "ETIR_S_C_STC_NBH_GBL";
252b5132 218
ca09e32b
NC
219 default:
220 /* These names have not yet been added to this switch statement. */
221 abort ();
222 }
223}
252b5132
RH
224#define HIGHBIT(op) ((op & 0x80000000L) == 0x80000000L)
225
226/* etir_sta
672579e9 227
252b5132 228 vms stack commands
672579e9 229
252b5132
RH
230 handle sta_xxx commands in etir section
231 ptr points to data area in record
672579e9 232
ca09e32b 233 see table B-8 of the openVMS linker manual. */
252b5132 234
b34976b6 235static bfd_boolean
7920ce38 236etir_sta (bfd * abfd, int cmd, unsigned char *ptr)
252b5132 237{
252b5132
RH
238#if VMS_DEBUG
239 _bfd_vms_debug (5, "etir_sta %d/%x\n", cmd, cmd);
dc810e39 240 _bfd_hexdump (8, ptr, 16, (int) ptr);
252b5132
RH
241#endif
242
243 switch (cmd)
244 {
252b5132 245 /* stack global
dc810e39 246 arg: cs symbol name
252b5132 247
7920ce38 248 stack 32 bit value of symbol (high bits set to 0). */
dc810e39
AM
249 case ETIR_S_C_STA_GBL:
250 {
251 char *name;
252 vms_symbol_entry *entry;
252b5132 253
dc810e39
AM
254 name = _bfd_vms_save_counted_string (ptr);
255 entry = (vms_symbol_entry *)
b34976b6 256 bfd_hash_lookup (PRIV (vms_symbol_table), name, FALSE, FALSE);
7920ce38 257 if (entry == NULL)
dc810e39 258 {
252b5132 259#if VMS_DEBUG
ca09e32b
NC
260 _bfd_vms_debug (3, "%s: no symbol \"%s\"\n",
261 cmd_name (cmd), name);
252b5132 262#endif
dc810e39
AM
263 _bfd_vms_push (abfd, (uquad) 0, -1);
264 }
265 else
7920ce38 266 _bfd_vms_push (abfd, (uquad) (entry->symbol->value), -1);
dc810e39 267 }
252b5132
RH
268 break;
269
dc810e39
AM
270 /* stack longword
271 arg: lw value
252b5132 272
7920ce38 273 stack 32 bit value, sign extend to 64 bit. */
dc810e39
AM
274 case ETIR_S_C_STA_LW:
275 _bfd_vms_push (abfd, (uquad) bfd_getl32 (ptr), -1);
252b5132
RH
276 break;
277
dc810e39
AM
278 /* stack global
279 arg: qw value
252b5132 280
7920ce38 281 stack 64 bit value of symbol. */
dc810e39
AM
282 case ETIR_S_C_STA_QW:
283 _bfd_vms_push (abfd, (uquad) bfd_getl64 (ptr), -1);
252b5132
RH
284 break;
285
dc810e39
AM
286 /* stack psect base plus quadword offset
287 arg: lw section index
288 qw signed quadword offset (low 32 bits)
252b5132 289
dc810e39 290 stack qw argument and section index
7920ce38 291 (see ETIR_S_C_STO_OFF, ETIR_S_C_CTL_SETRB). */
dc810e39
AM
292 case ETIR_S_C_STA_PQ:
293 {
294 uquad dummy;
295 unsigned int psect;
252b5132 296
dc810e39
AM
297 psect = bfd_getl32 (ptr);
298 if (psect >= PRIV (section_count))
299 {
ca09e32b
NC
300 (*_bfd_error_handler) (_("bad section index in %s"),
301 cmd_name (cmd));
dc810e39 302 bfd_set_error (bfd_error_bad_value);
b34976b6 303 return FALSE;
dc810e39 304 }
7920ce38 305 dummy = bfd_getl64 (ptr + 4);
dc810e39
AM
306 _bfd_vms_push (abfd, dummy, (int) psect);
307 }
252b5132
RH
308 break;
309
dc810e39
AM
310 case ETIR_S_C_STA_LI:
311 case ETIR_S_C_STA_MOD:
312 case ETIR_S_C_STA_CKARG:
ca09e32b 313 (*_bfd_error_handler) (_("unsupported STA cmd %s"), cmd_name (cmd));
b34976b6 314 return FALSE;
252b5132
RH
315 break;
316
dc810e39 317 default:
ca09e32b 318 (*_bfd_error_handler) (_("reserved STA cmd %d"), cmd);
b34976b6 319 return FALSE;
252b5132
RH
320 break;
321 }
322#if VMS_DEBUG
323 _bfd_vms_debug (5, "etir_sta true\n");
324#endif
b34976b6 325 return TRUE;
252b5132
RH
326}
327
7920ce38 328/* etir_sto
672579e9 329
252b5132 330 vms store commands
672579e9 331
252b5132
RH
332 handle sto_xxx commands in etir section
333 ptr points to data area in record
672579e9 334
ca09e32b 335 see table B-9 of the openVMS linker manual. */
252b5132 336
b34976b6 337static bfd_boolean
7920ce38 338etir_sto (bfd * abfd, int cmd, unsigned char *ptr)
252b5132
RH
339{
340 uquad dummy;
341 int psect;
342
343#if VMS_DEBUG
344 _bfd_vms_debug (5, "etir_sto %d/%x\n", cmd, cmd);
dc810e39 345 _bfd_hexdump (8, ptr, 16, (int) ptr);
252b5132
RH
346#endif
347
348 switch (cmd)
349 {
7920ce38
NC
350 /* Store byte: pop stack, write byte
351 arg: -. */
252b5132
RH
352 case ETIR_S_C_STO_B:
353 dummy = _bfd_vms_pop (abfd, &psect);
7920ce38 354 /* FIXME: check top bits. */
dc810e39 355 image_write_b (abfd, (unsigned int) dummy & 0xff);
252b5132
RH
356 break;
357
7920ce38
NC
358 /* Store word: pop stack, write word
359 arg: -. */
252b5132
RH
360 case ETIR_S_C_STO_W:
361 dummy = _bfd_vms_pop (abfd, &psect);
dc810e39
AM
362 /* FIXME: check top bits */
363 image_write_w (abfd, (unsigned int) dummy & 0xffff);
252b5132
RH
364 break;
365
7920ce38
NC
366 /* Store longword: pop stack, write longword
367 arg: -. */
252b5132
RH
368 case ETIR_S_C_STO_LW:
369 dummy = _bfd_vms_pop (abfd, &psect);
dc810e39 370 dummy += (PRIV (sections)[psect])->vma;
ca09e32b 371 /* FIXME: check top bits. */
dc810e39 372 image_write_l (abfd, (unsigned int) dummy & 0xffffffff);
252b5132
RH
373 break;
374
7920ce38
NC
375 /* Store quadword: pop stack, write quadword
376 arg: -. */
252b5132
RH
377 case ETIR_S_C_STO_QW:
378 dummy = _bfd_vms_pop (abfd, &psect);
dc810e39 379 dummy += (PRIV (sections)[psect])->vma;
7920ce38
NC
380 /* FIXME: check top bits. */
381 image_write_q (abfd, dummy);
252b5132
RH
382 break;
383
7920ce38 384 /* Store immediate repeated: pop stack for repeat count
252b5132 385 arg: lw byte count
7920ce38 386 da data. */
252b5132
RH
387 case ETIR_S_C_STO_IMMR:
388 {
dc810e39 389 int size;
252b5132
RH
390
391 size = bfd_getl32 (ptr);
dc810e39
AM
392 dummy = (unsigned long) _bfd_vms_pop (abfd, NULL);
393 while (dummy-- > 0)
252b5132
RH
394 image_dump (abfd, ptr+4, size, 0);
395 }
396 break;
397
7920ce38 398 /* Store global: write symbol value
ca09e32b 399 arg: cs global symbol name. */
252b5132
RH
400 case ETIR_S_C_STO_GBL:
401 {
402 vms_symbol_entry *entry;
403 char *name;
404
405 name = _bfd_vms_save_counted_string (ptr);
dc810e39 406 entry = (vms_symbol_entry *) bfd_hash_lookup (PRIV (vms_symbol_table),
b34976b6 407 name, FALSE, FALSE);
7920ce38 408 if (entry == NULL)
252b5132 409 {
ca09e32b
NC
410 (*_bfd_error_handler) (_("%s: no symbol \"%s\""),
411 cmd_name (cmd), name);
b34976b6 412 return FALSE;
252b5132
RH
413 }
414 else
ca09e32b
NC
415 /* FIXME, reloc. */
416 image_write_q (abfd, (uquad) (entry->symbol->value));
252b5132
RH
417 }
418 break;
419
7920ce38 420 /* Store code address: write address of entry point
ca09e32b 421 arg: cs global symbol name (procedure). */
252b5132
RH
422 case ETIR_S_C_STO_CA:
423 {
424 vms_symbol_entry *entry;
425 char *name;
426
427 name = _bfd_vms_save_counted_string (ptr);
dc810e39 428 entry = (vms_symbol_entry *) bfd_hash_lookup (PRIV (vms_symbol_table),
b34976b6 429 name, FALSE, FALSE);
7920ce38 430 if (entry == NULL)
252b5132 431 {
ca09e32b
NC
432 (*_bfd_error_handler) (_("%s: no symbol \"%s\""),
433 cmd_name (cmd), name);
b34976b6 434 return FALSE;
252b5132
RH
435 }
436 else
7920ce38
NC
437 /* FIXME, reloc. */
438 image_write_q (abfd, (uquad) (entry->symbol->value));
252b5132
RH
439 }
440 break;
441
ca09e32b
NC
442 /* Store offset to psect: pop stack, add low 32 bits to base of psect
443 arg: none. */
252b5132
RH
444 case ETIR_S_C_STO_OFF:
445 {
446 uquad q;
dc810e39 447 int psect1;
252b5132 448
7920ce38 449 q = _bfd_vms_pop (abfd, & psect1);
dc810e39 450 q += (PRIV (sections)[psect1])->vma;
252b5132
RH
451 image_write_q (abfd, q);
452 }
453 break;
454
ca09e32b 455 /* Store immediate
252b5132 456 arg: lw count of bytes
ca09e32b 457 da data. */
252b5132
RH
458 case ETIR_S_C_STO_IMM:
459 {
460 int size;
461
462 size = bfd_getl32 (ptr);
463 image_dump (abfd, ptr+4, size, 0);
464 }
465 break;
466
ca09e32b 467 /* This code is 'reserved to digital' according to the openVMS
dc810e39
AM
468 linker manual, however it is generated by the DEC C compiler
469 and defined in the include file.
252b5132
RH
470 FIXME, since the following is just a guess
471 store global longword: store 32bit value of symbol
ca09e32b 472 arg: cs symbol name. */
252b5132
RH
473 case ETIR_S_C_STO_GBL_LW:
474 {
475 vms_symbol_entry *entry;
476 char *name;
477
478 name = _bfd_vms_save_counted_string (ptr);
dc810e39 479 entry = (vms_symbol_entry *) bfd_hash_lookup (PRIV (vms_symbol_table),
b34976b6 480 name, FALSE, FALSE);
7920ce38 481 if (entry == NULL)
252b5132
RH
482 {
483#if VMS_DEBUG
ca09e32b 484 _bfd_vms_debug (3, "%s: no symbol \"%s\"\n", cmd_name (cmd), name);
252b5132 485#endif
dc810e39 486 image_write_l (abfd, (unsigned long) 0); /* FIXME, reloc */
252b5132
RH
487 }
488 else
ca09e32b
NC
489 /* FIXME, reloc. */
490 image_write_l (abfd, (unsigned long) (entry->symbol->value));
252b5132
RH
491 }
492 break;
493
ca09e32b
NC
494 case ETIR_S_C_STO_RB:
495 case ETIR_S_C_STO_AB:
252b5132 496 case ETIR_S_C_STO_LP_PSB:
ca09e32b 497 (*_bfd_error_handler) (_("%s: not supported"), cmd_name (cmd));
252b5132
RH
498 break;
499
252b5132 500 case ETIR_S_C_STO_HINT_GBL:
252b5132 501 case ETIR_S_C_STO_HINT_PS:
ca09e32b 502 (*_bfd_error_handler) (_("%s: not implemented"), cmd_name (cmd));
252b5132
RH
503 break;
504
505 default:
ca09e32b 506 (*_bfd_error_handler) (_("reserved STO cmd %d"), cmd);
252b5132
RH
507 break;
508 }
509
b34976b6 510 return TRUE;
252b5132
RH
511}
512
ca09e32b 513/* Stack operator commands
252b5132
RH
514 all 32 bit signed arithmetic
515 all word just like a stack calculator
516 arguments are popped from stack, results are pushed on stack
672579e9 517
ca09e32b 518 see table B-10 of the openVMS linker manual. */
252b5132 519
b34976b6 520static bfd_boolean
7920ce38 521etir_opr (bfd * abfd, int cmd, unsigned char *ptr ATTRIBUTE_UNUSED)
252b5132
RH
522{
523 long op1, op2;
524
525#if VMS_DEBUG
526 _bfd_vms_debug (5, "etir_opr %d/%x\n", cmd, cmd);
dc810e39 527 _bfd_hexdump (8, ptr, 16, (int) ptr);
252b5132
RH
528#endif
529
530 switch (cmd)
531 {
7920ce38 532 case ETIR_S_C_OPR_NOP: /* No-op. */
252b5132
RH
533 break;
534
7920ce38 535 case ETIR_S_C_OPR_ADD: /* Add. */
dc810e39
AM
536 op1 = (long) _bfd_vms_pop (abfd, NULL);
537 op2 = (long) _bfd_vms_pop (abfd, NULL);
672579e9 538 _bfd_vms_push (abfd, (uquad) (op1 + op2), -1);
252b5132
RH
539 break;
540
7920ce38 541 case ETIR_S_C_OPR_SUB: /* Subtract. */
dc810e39
AM
542 op1 = (long) _bfd_vms_pop (abfd, NULL);
543 op2 = (long) _bfd_vms_pop (abfd, NULL);
672579e9 544 _bfd_vms_push (abfd, (uquad) (op2 - op1), -1);
252b5132
RH
545 break;
546
7920ce38 547 case ETIR_S_C_OPR_MUL: /* Multiply. */
dc810e39
AM
548 op1 = (long) _bfd_vms_pop (abfd, NULL);
549 op2 = (long) _bfd_vms_pop (abfd, NULL);
672579e9 550 _bfd_vms_push (abfd, (uquad) (op1 * op2), -1);
252b5132
RH
551 break;
552
7920ce38 553 case ETIR_S_C_OPR_DIV: /* Divide. */
dc810e39
AM
554 op1 = (long) _bfd_vms_pop (abfd, NULL);
555 op2 = (long) _bfd_vms_pop (abfd, NULL);
252b5132 556 if (op2 == 0)
dc810e39 557 _bfd_vms_push (abfd, (uquad) 0, -1);
252b5132 558 else
672579e9 559 _bfd_vms_push (abfd, (uquad) (op2 / op1), -1);
252b5132
RH
560 break;
561
7920ce38 562 case ETIR_S_C_OPR_AND: /* Logical AND. */
dc810e39
AM
563 op1 = (long) _bfd_vms_pop (abfd, NULL);
564 op2 = (long) _bfd_vms_pop (abfd, NULL);
672579e9 565 _bfd_vms_push (abfd, (uquad) (op1 & op2), -1);
252b5132
RH
566 break;
567
7920ce38 568 case ETIR_S_C_OPR_IOR: /* Logical inclusive OR. */
dc810e39
AM
569 op1 = (long) _bfd_vms_pop (abfd, NULL);
570 op2 = (long) _bfd_vms_pop (abfd, NULL);
672579e9 571 _bfd_vms_push (abfd, (uquad) (op1 | op2), -1);
252b5132
RH
572 break;
573
7920ce38 574 case ETIR_S_C_OPR_EOR: /* Logical exclusive OR. */
dc810e39
AM
575 op1 = (long) _bfd_vms_pop (abfd, NULL);
576 op2 = (long) _bfd_vms_pop (abfd, NULL);
672579e9 577 _bfd_vms_push (abfd, (uquad) (op1 ^ op2), -1);
252b5132
RH
578 break;
579
7920ce38 580 case ETIR_S_C_OPR_NEG: /* Negate. */
dc810e39 581 op1 = (long) _bfd_vms_pop (abfd, NULL);
672579e9 582 _bfd_vms_push (abfd, (uquad) (-op1), -1);
252b5132
RH
583 break;
584
7920ce38 585 case ETIR_S_C_OPR_COM: /* Complement. */
dc810e39 586 op1 = (long) _bfd_vms_pop (abfd, NULL);
672579e9 587 _bfd_vms_push (abfd, (uquad) (op1 ^ -1L), -1);
252b5132
RH
588 break;
589
7920ce38 590 case ETIR_S_C_OPR_ASH: /* Arithmetic shift. */
dc810e39
AM
591 op1 = (long) _bfd_vms_pop (abfd, NULL);
592 op2 = (long) _bfd_vms_pop (abfd, NULL);
7920ce38 593 if (op2 < 0) /* Shift right. */
252b5132 594 op1 >>= -op2;
7920ce38 595 else /* Shift left. */
252b5132 596 op1 <<= op2;
dc810e39 597 _bfd_vms_push (abfd, (uquad) op1, -1);
252b5132
RH
598 break;
599
7920ce38 600 case ETIR_S_C_OPR_INSV: /* Insert field. */
ca09e32b 601 (void) _bfd_vms_pop (abfd, NULL);
7920ce38
NC
602 case ETIR_S_C_OPR_USH: /* Unsigned shift. */
603 case ETIR_S_C_OPR_ROT: /* Rotate. */
ca09e32b
NC
604 case ETIR_S_C_OPR_REDEF: /* Redefine symbol to current location. */
605 case ETIR_S_C_OPR_DFLIT: /* Define a literal. */
606 (*_bfd_error_handler) (_("%s: not supported"), cmd_name (cmd));
252b5132
RH
607 break;
608
7920ce38 609 case ETIR_S_C_OPR_SEL: /* Select. */
dc810e39
AM
610 if ((long) _bfd_vms_pop (abfd, NULL) & 0x01L)
611 (void) _bfd_vms_pop (abfd, NULL);
252b5132
RH
612 else
613 {
dc810e39
AM
614 op1 = (long) _bfd_vms_pop (abfd, NULL);
615 (void) _bfd_vms_pop (abfd, NULL);
616 _bfd_vms_push (abfd, (uquad) op1, -1);
252b5132
RH
617 }
618 break;
619
252b5132 620 default:
ca09e32b 621 (*_bfd_error_handler) (_("reserved OPR cmd %d"), cmd);
252b5132
RH
622 break;
623 }
624
b34976b6 625 return TRUE;
252b5132
RH
626}
627
ca09e32b 628/* Control commands.
672579e9 629
ca09e32b 630 See table B-11 of the openVMS linker manual. */
252b5132 631
b34976b6 632static bfd_boolean
7920ce38 633etir_ctl (bfd * abfd, int cmd, unsigned char *ptr)
252b5132
RH
634{
635 uquad dummy;
636 int psect;
637
638#if VMS_DEBUG
639 _bfd_vms_debug (5, "etir_ctl %d/%x\n", cmd, cmd);
dc810e39 640 _bfd_hexdump (8, ptr, 16, (int) ptr);
252b5132
RH
641#endif
642
643 switch (cmd)
644 {
7920ce38 645 /* Det relocation base: pop stack, set image location counter
ca09e32b 646 arg: none. */
252b5132
RH
647 case ETIR_S_C_CTL_SETRB:
648 dummy = _bfd_vms_pop (abfd, &psect);
649 image_set_ptr (abfd, psect, dummy);
650 break;
651
7920ce38
NC
652 /* Augment relocation base: increment image location counter by offset
653 arg: lw offset value. */
252b5132
RH
654 case ETIR_S_C_CTL_AUGRB:
655 dummy = bfd_getl32 (ptr);
656 image_inc_ptr (abfd, dummy);
657 break;
658
7920ce38 659 /* Define location: pop index, save location counter under index
ca09e32b 660 arg: none. */
252b5132
RH
661 case ETIR_S_C_CTL_DFLOC:
662 dummy = _bfd_vms_pop (abfd, NULL);
663 /* FIXME */
664 break;
665
7920ce38 666 /* Set location: pop index, restore location counter from index
ca09e32b 667 arg: none. */
252b5132
RH
668 case ETIR_S_C_CTL_STLOC:
669 dummy = _bfd_vms_pop (abfd, &psect);
670 /* FIXME */
671 break;
672
7920ce38 673 /* Stack defined location: pop index, push location counter from index
ca09e32b 674 arg: none. */
252b5132
RH
675 case ETIR_S_C_CTL_STKDL:
676 dummy = _bfd_vms_pop (abfd, &psect);
7920ce38 677 /* FIXME. */
252b5132
RH
678 break;
679
680 default:
ca09e32b 681 (*_bfd_error_handler) (_("reserved CTL cmd %d"), cmd);
252b5132
RH
682 break;
683 }
b34976b6 684 return TRUE;
252b5132
RH
685}
686
7920ce38 687/* Store conditional commands
672579e9 688
ca09e32b 689 See table B-12 and B-13 of the openVMS linker manual. */
252b5132 690
b34976b6 691static bfd_boolean
7920ce38 692etir_stc (bfd * abfd, int cmd, unsigned char *ptr ATTRIBUTE_UNUSED)
252b5132 693{
252b5132
RH
694#if VMS_DEBUG
695 _bfd_vms_debug (5, "etir_stc %d/%x\n", cmd, cmd);
dc810e39 696 _bfd_hexdump (8, ptr, 16, (int) ptr);
252b5132
RH
697#endif
698
699 switch (cmd)
700 {
701 /* 200 Store-conditional Linkage Pair
ca09e32b 702 arg: none. */
252b5132 703 case ETIR_S_C_STC_LP:
ca09e32b 704 (*_bfd_error_handler) (_("%s: not supported"), cmd_name (cmd));
252b5132
RH
705 break;
706
707 /* 201 Store-conditional Linkage Pair with Procedure Signature
708 arg: lw linkage index
b34976b6
AM
709 cs procedure name
710 by signature length
711 da signature. */
252b5132 712 case ETIR_S_C_STC_LP_PSB:
dc810e39 713 image_inc_ptr (abfd, (uquad) 16); /* skip entry,procval */
252b5132
RH
714 break;
715
716 /* 202 Store-conditional Address at global address
717 arg: lw linkage index
b34976b6 718 cs global name. */
252b5132
RH
719
720 case ETIR_S_C_STC_GBL:
ca09e32b 721 (*_bfd_error_handler) (_("%s: not supported"), cmd_name (cmd));
252b5132
RH
722 break;
723
724 /* 203 Store-conditional Code Address at global address
725 arg: lw linkage index
b34976b6 726 cs procedure name. */
252b5132 727 case ETIR_S_C_STC_GCA:
ca09e32b 728 (*_bfd_error_handler) (_("%s: not supported"), cmd_name (cmd));
252b5132
RH
729 break;
730
731 /* 204 Store-conditional Address at psect + offset
732 arg: lw linkage index
b34976b6
AM
733 lw psect index
734 qw offset. */
252b5132 735 case ETIR_S_C_STC_PS:
ca09e32b 736 (*_bfd_error_handler) (_("%s: not supported"), cmd_name (cmd));
252b5132
RH
737 break;
738
739 /* 205 Store-conditional NOP at address of global
ca09e32b 740 arg: none. */
252b5132
RH
741 case ETIR_S_C_STC_NOP_GBL:
742
743 /* 206 Store-conditional NOP at pect + offset
ca09e32b 744 arg: none. */
252b5132
RH
745 case ETIR_S_C_STC_NOP_PS:
746
747 /* 207 Store-conditional BSR at global address
ca09e32b 748 arg: none. */
252b5132
RH
749 case ETIR_S_C_STC_BSR_GBL:
750
751 /* 208 Store-conditional BSR at pect + offset
ca09e32b 752 arg: none. */
252b5132
RH
753 case ETIR_S_C_STC_BSR_PS:
754
755 /* 209 Store-conditional LDA at global address
ca09e32b 756 arg: none. */
252b5132
RH
757 case ETIR_S_C_STC_LDA_GBL:
758
759 /* 210 Store-conditional LDA at psect + offset
ca09e32b 760 arg: none. */
252b5132
RH
761 case ETIR_S_C_STC_LDA_PS:
762
763 /* 211 Store-conditional BSR or Hint at global address
ca09e32b 764 arg: none. */
252b5132
RH
765 case ETIR_S_C_STC_BOH_GBL:
766
767 /* 212 Store-conditional BSR or Hint at pect + offset
ca09e32b 768 arg: none. */
252b5132
RH
769 case ETIR_S_C_STC_BOH_PS:
770
771 /* 213 Store-conditional NOP,BSR or HINT at global address
ca09e32b 772 arg: none. */
252b5132
RH
773 case ETIR_S_C_STC_NBH_GBL:
774
775 /* 214 Store-conditional NOP,BSR or HINT at psect + offset
ca09e32b 776 arg: none. */
252b5132 777 case ETIR_S_C_STC_NBH_PS:
dc810e39 778 /* FIXME */
252b5132
RH
779 break;
780
781 default:
782#if VMS_DEBUG
ca09e32b 783 _bfd_vms_debug (3, "reserved STC cmd %d", cmd);
252b5132
RH
784#endif
785 break;
786 }
b34976b6 787 return TRUE;
252b5132
RH
788}
789
252b5132 790static asection *
7920ce38 791new_section (bfd * abfd ATTRIBUTE_UNUSED, int idx)
252b5132
RH
792{
793 asection *section;
794 char sname[16];
795 char *name;
796
797#if VMS_DEBUG
ca09e32b 798 _bfd_vms_debug (5, "new_section %d\n", idx);
252b5132
RH
799#endif
800 sprintf (sname, SECTION_NAME_TEMPLATE, idx);
801
dc810e39 802 name = bfd_malloc ((bfd_size_type) strlen (sname) + 1);
252b5132 803 if (name == 0)
7920ce38 804 return NULL;
252b5132
RH
805 strcpy (name, sname);
806
dc810e39 807 section = bfd_malloc ((bfd_size_type) sizeof (asection));
252b5132
RH
808 if (section == 0)
809 {
810#if VMS_DEBUG
811 _bfd_vms_debug (6, "bfd_make_section (%s) failed", name);
812#endif
7920ce38 813 return NULL;
252b5132
RH
814 }
815
eea6121a 816 section->size = 0;
252b5132
RH
817 section->vma = 0;
818 section->contents = 0;
252b5132
RH
819 section->name = name;
820 section->index = idx;
821
822 return section;
823}
824
252b5132 825static int
7920ce38 826alloc_section (bfd * abfd, unsigned int idx)
252b5132 827{
dc810e39
AM
828 bfd_size_type amt;
829
252b5132 830#if VMS_DEBUG
ca09e32b 831 _bfd_vms_debug (4, "alloc_section %d\n", idx);
252b5132
RH
832#endif
833
dc810e39
AM
834 amt = idx + 1;
835 amt *= sizeof (asection *);
7920ce38 836 PRIV (sections) = bfd_realloc (PRIV (sections), amt);
dc810e39 837 if (PRIV (sections) == 0)
252b5132
RH
838 return -1;
839
dc810e39 840 while (PRIV (section_count) <= idx)
252b5132 841 {
dc810e39
AM
842 PRIV (sections)[PRIV (section_count)]
843 = new_section (abfd, (int) PRIV (section_count));
844 if (PRIV (sections)[PRIV (section_count)] == 0)
252b5132 845 return -1;
dc810e39 846 PRIV (section_count)++;
252b5132
RH
847 }
848
849 return 0;
850}
851
ca09e32b 852/* tir_sta
b34976b6 853
ca09e32b 854 vax stack commands
b34976b6 855
ca09e32b
NC
856 Handle sta_xxx commands in tir section
857 ptr points to data area in record
b34976b6 858
ca09e32b 859 See table 7-3 of the VAX/VMS linker manual. */
252b5132
RH
860
861static unsigned char *
7920ce38 862tir_sta (bfd * abfd, unsigned char *ptr)
252b5132
RH
863{
864 int cmd = *ptr++;
865
866#if VMS_DEBUG
867 _bfd_vms_debug (5, "tir_sta %d\n", cmd);
868#endif
869
870 switch (cmd)
871 {
dc810e39
AM
872 /* stack */
873 case TIR_S_C_STA_GBL:
ca09e32b 874 /* stack global
b34976b6
AM
875 arg: cs symbol name
876
877 stack 32 bit value of symbol (high bits set to 0). */
dc810e39
AM
878 {
879 char *name;
880 vms_symbol_entry *entry;
252b5132 881
dc810e39 882 name = _bfd_vms_save_counted_string (ptr);
252b5132 883
dc810e39 884 entry = _bfd_vms_enter_symbol (abfd, name);
7920ce38
NC
885 if (entry == NULL)
886 return NULL;
252b5132 887
dc810e39
AM
888 _bfd_vms_push (abfd, (uquad) (entry->symbol->value), -1);
889 ptr += *ptr + 1;
890 }
252b5132
RH
891 break;
892
dc810e39 893 case TIR_S_C_STA_SB:
ca09e32b 894 /* stack signed byte
b34976b6
AM
895 arg: by value
896
897 stack byte value, sign extend to 32 bit. */
dc810e39
AM
898 _bfd_vms_push (abfd, (uquad) *ptr++, -1);
899 break;
900
901 case TIR_S_C_STA_SW:
ca09e32b 902 /* stack signed short word
b34976b6
AM
903 arg: sh value
904
905 stack 16 bit value, sign extend to 32 bit. */
dc810e39
AM
906 _bfd_vms_push (abfd, (uquad) bfd_getl16 (ptr), -1);
907 ptr += 2;
908 break;
909
910 case TIR_S_C_STA_LW:
ca09e32b 911 /* stack signed longword
b34976b6
AM
912 arg: lw value
913
914 stack 32 bit value. */
dc810e39
AM
915 _bfd_vms_push (abfd, (uquad) bfd_getl32 (ptr), -1);
916 ptr += 4;
917 break;
918
919 case TIR_S_C_STA_PB:
920 case TIR_S_C_STA_WPB:
ca09e32b 921 /* stack psect base plus byte offset (word index)
b34976b6
AM
922 arg: by section index
923 (sh section index)
924 by signed byte offset. */
dc810e39
AM
925 {
926 unsigned long dummy;
927 unsigned int psect;
928
929 if (cmd == TIR_S_C_STA_PB)
930 psect = *ptr++;
931 else
932 {
933 psect = bfd_getl16 (ptr);
934 ptr += 2;
935 }
936
937 if (psect >= PRIV (section_count))
ca09e32b 938 alloc_section (abfd, psect);
dc810e39
AM
939
940 dummy = (long) *ptr++;
941 dummy += (PRIV (sections)[psect])->vma;
942 _bfd_vms_push (abfd, (uquad) dummy, (int) psect);
943 }
252b5132
RH
944 break;
945
dc810e39
AM
946 case TIR_S_C_STA_PW:
947 case TIR_S_C_STA_WPW:
ca09e32b 948 /* stack psect base plus word offset (word index)
b34976b6
AM
949 arg: by section index
950 (sh section index)
951 sh signed short offset. */
dc810e39
AM
952 {
953 unsigned long dummy;
954 unsigned int psect;
252b5132 955
dc810e39
AM
956 if (cmd == TIR_S_C_STA_PW)
957 psect = *ptr++;
958 else
959 {
960 psect = bfd_getl16 (ptr);
961 ptr += 2;
962 }
252b5132 963
dc810e39 964 if (psect >= PRIV (section_count))
ca09e32b 965 alloc_section (abfd, psect);
252b5132 966
dc810e39
AM
967 dummy = bfd_getl16 (ptr); ptr+=2;
968 dummy += (PRIV (sections)[psect])->vma;
969 _bfd_vms_push (abfd, (uquad) dummy, (int) psect);
970 }
971 break;
252b5132 972
dc810e39
AM
973 case TIR_S_C_STA_PL:
974 case TIR_S_C_STA_WPL:
ca09e32b 975 /* stack psect base plus long offset (word index)
b34976b6
AM
976 arg: by section index
977 (sh section index)
978 lw signed longword offset. */
dc810e39
AM
979 {
980 unsigned long dummy;
981 unsigned int psect;
252b5132 982
dc810e39
AM
983 if (cmd == TIR_S_C_STA_PL)
984 psect = *ptr++;
985 else
986 {
987 psect = bfd_getl16 (ptr);
988 ptr += 2;
989 }
252b5132 990
dc810e39 991 if (psect >= PRIV (section_count))
ca09e32b 992 alloc_section (abfd, psect);
dc810e39
AM
993
994 dummy = bfd_getl32 (ptr); ptr += 4;
995 dummy += (PRIV (sections)[psect])->vma;
996 _bfd_vms_push (abfd, (uquad) dummy, (int) psect);
997 }
252b5132
RH
998 break;
999
dc810e39 1000 case TIR_S_C_STA_UB:
ca09e32b 1001 /* stack unsigned byte
b34976b6
AM
1002 arg: by value
1003
1004 stack byte value. */
dc810e39
AM
1005 _bfd_vms_push (abfd, (uquad) *ptr++, -1);
1006 break;
1007
1008 case TIR_S_C_STA_UW:
ca09e32b 1009 /* stack unsigned short word
b34976b6
AM
1010 arg: sh value
1011
1012 stack 16 bit value. */
dc810e39
AM
1013 _bfd_vms_push (abfd, (uquad) bfd_getl16 (ptr), -1);
1014 ptr += 2;
1015 break;
1016
1017 case TIR_S_C_STA_BFI:
ca09e32b 1018 /* stack byte from image
b34976b6 1019 arg: none. */
ca09e32b 1020 /* FALLTHRU */
dc810e39 1021 case TIR_S_C_STA_WFI:
ca09e32b 1022 /* stack byte from image
b34976b6 1023 arg: none. */
ca09e32b 1024 /* FALLTHRU */
dc810e39 1025 case TIR_S_C_STA_LFI:
ca09e32b 1026 /* stack byte from image
b34976b6 1027 arg: none. */
ca09e32b 1028 (*_bfd_error_handler) (_("stack-from-image not implemented"));
dc810e39
AM
1029 return NULL;
1030
1031 case TIR_S_C_STA_EPM:
ca09e32b 1032 /* stack entry point mask
b34976b6
AM
1033 arg: cs symbol name
1034
1035 stack (unsigned) entry point mask of symbol
1036 err if symbol is no entry point. */
dc810e39
AM
1037 {
1038 char *name;
1039 vms_symbol_entry *entry;
252b5132 1040
dc810e39
AM
1041 name = _bfd_vms_save_counted_string (ptr);
1042 entry = _bfd_vms_enter_symbol (abfd, name);
7920ce38
NC
1043 if (entry == NULL)
1044 return NULL;
252b5132 1045
ca09e32b 1046 (*_bfd_error_handler) (_("stack-entry-mask not fully implemented"));
dc810e39
AM
1047 _bfd_vms_push (abfd, (uquad) 0, -1);
1048 ptr += *ptr + 1;
1049 }
252b5132
RH
1050 break;
1051
dc810e39 1052 case TIR_S_C_STA_CKARG:
ca09e32b 1053 /* compare procedure argument
b34976b6
AM
1054 arg: cs symbol name
1055 by argument index
1056 da argument descriptor
1057
1058 compare argument descriptor with symbol argument (ARG$V_PASSMECH)
1059 and stack TRUE (args match) or FALSE (args dont match) value. */
dc810e39
AM
1060 (*_bfd_error_handler) (_("PASSMECH not fully implemented"));
1061 _bfd_vms_push (abfd, (uquad) 1, -1);
1062 break;
1063
1064 case TIR_S_C_STA_LSY:
ca09e32b 1065 /* stack local symbol value
b34976b6
AM
1066 arg: sh environment index
1067 cs symbol name. */
dc810e39
AM
1068 {
1069 int envidx;
1070 char *name;
1071 vms_symbol_entry *entry;
252b5132 1072
dc810e39
AM
1073 envidx = bfd_getl16 (ptr);
1074 ptr += 2;
1075 name = _bfd_vms_save_counted_string (ptr);
1076 entry = _bfd_vms_enter_symbol (abfd, name);
7920ce38
NC
1077 if (entry == NULL)
1078 return NULL;
ca09e32b 1079 (*_bfd_error_handler) (_("stack-local-symbol not fully implemented"));
dc810e39
AM
1080 _bfd_vms_push (abfd, (uquad) 0, -1);
1081 ptr += *ptr + 1;
1082 }
252b5132
RH
1083 break;
1084
dc810e39 1085 case TIR_S_C_STA_LIT:
ca09e32b 1086 /* stack literal
b34976b6
AM
1087 arg: by literal index
1088
1089 stack literal. */
dc810e39
AM
1090 ptr++;
1091 _bfd_vms_push (abfd, (uquad) 0, -1);
ca09e32b 1092 (*_bfd_error_handler) (_("stack-literal not fully implemented"));
dc810e39
AM
1093 break;
1094
1095 case TIR_S_C_STA_LEPM:
ca09e32b 1096 /* stack local symbol entry point mask
b34976b6
AM
1097 arg: sh environment index
1098 cs symbol name
1099
1100 stack (unsigned) entry point mask of symbol
1101 err if symbol is no entry point. */
dc810e39
AM
1102 {
1103 int envidx;
1104 char *name;
1105 vms_symbol_entry *entry;
252b5132 1106
dc810e39
AM
1107 envidx = bfd_getl16 (ptr);
1108 ptr += 2;
1109 name = _bfd_vms_save_counted_string (ptr);
1110 entry = _bfd_vms_enter_symbol (abfd, name);
7920ce38
NC
1111 if (entry == NULL)
1112 return NULL;
ca09e32b 1113 (*_bfd_error_handler) (_("stack-local-symbol-entry-point-mask not fully implemented"));
dc810e39
AM
1114 _bfd_vms_push (abfd, (uquad) 0, -1);
1115 ptr += *ptr + 1;
1116 }
252b5132
RH
1117 break;
1118
dc810e39 1119 default:
ca09e32b 1120 (*_bfd_error_handler) (_("reserved STA cmd %d"), ptr[-1]);
dc810e39 1121 return NULL;
252b5132 1122 break;
dc810e39 1123 }
252b5132
RH
1124
1125 return ptr;
1126}
1127
ca09e32b 1128static const char *
7920ce38 1129tir_cmd_name (int cmd)
ca09e32b
NC
1130{
1131 switch (cmd)
1132 {
1133 case TIR_S_C_STO_RSB: return "TIR_S_C_STO_RSB";
1134 case TIR_S_C_STO_RSW: return "TIR_S_C_STO_RSW";
1135 case TIR_S_C_STO_RL: return "TIR_S_C_STO_RL";
1136 case TIR_S_C_STO_VPS: return "TIR_S_C_STO_VPS";
1137 case TIR_S_C_STO_USB: return "TIR_S_C_STO_USB";
1138 case TIR_S_C_STO_USW: return "TIR_S_C_STO_USW";
1139 case TIR_S_C_STO_RUB: return "TIR_S_C_STO_RUB";
1140 case TIR_S_C_STO_RUW: return "TIR_S_C_STO_RUW";
1141 case TIR_S_C_STO_PIRR: return "TIR_S_C_STO_PIRR";
1142 case TIR_S_C_OPR_INSV: return "TIR_S_C_OPR_INSV";
1143 case TIR_S_C_OPR_DFLIT: return "TIR_S_C_OPR_DFLIT";
1144 case TIR_S_C_OPR_REDEF: return "TIR_S_C_OPR_REDEF";
1145 case TIR_S_C_OPR_ROT: return "TIR_S_C_OPR_ROT";
1146 case TIR_S_C_OPR_USH: return "TIR_S_C_OPR_USH";
1147 case TIR_S_C_OPR_ASH: return "TIR_S_C_OPR_ASH";
1148 case TIR_S_C_CTL_DFLOC: return "TIR_S_C_CTL_DFLOC";
1149 case TIR_S_C_CTL_STLOC: return "TIR_S_C_CTL_STLOC";
1150 case TIR_S_C_CTL_STKDL: return "TIR_S_C_CTL_STKDL";
1151
1152 default:
1153 /* These strings have not been added yet. */
1154 abort ();
1155 }
1156}
1157
1158/* tir_sto
b34976b6 1159
ca09e32b 1160 vax store commands
b34976b6 1161
ca09e32b
NC
1162 handle sto_xxx commands in tir section
1163 ptr points to data area in record
b34976b6 1164
ca09e32b 1165 See table 7-4 of the VAX/VMS linker manual. */
252b5132
RH
1166
1167static unsigned char *
7920ce38 1168tir_sto (bfd * abfd, unsigned char *ptr)
252b5132
RH
1169{
1170 unsigned long dummy;
1171 int size;
1172 int psect;
1173
1174#if VMS_DEBUG
1175 _bfd_vms_debug (5, "tir_sto %d\n", *ptr);
1176#endif
1177
1178 switch (*ptr++)
1179 {
dc810e39 1180 case TIR_S_C_STO_SB:
7920ce38 1181 /* Store signed byte: pop stack, write byte
b34976b6 1182 arg: none. */
dc810e39
AM
1183 dummy = _bfd_vms_pop (abfd, &psect);
1184 image_write_b (abfd, dummy & 0xff); /* FIXME: check top bits */
1185 break;
1186
1187 case TIR_S_C_STO_SW:
7920ce38 1188 /* Store signed word: pop stack, write word
b34976b6 1189 arg: none. */
dc810e39
AM
1190 dummy = _bfd_vms_pop (abfd, &psect);
1191 image_write_w (abfd, dummy & 0xffff); /* FIXME: check top bits */
1192 break;
1193
1194 case TIR_S_C_STO_LW:
7920ce38 1195 /* Store longword: pop stack, write longword
b34976b6 1196 arg: none. */
dc810e39
AM
1197 dummy = _bfd_vms_pop (abfd, &psect);
1198 image_write_l (abfd, dummy & 0xffffffff); /* FIXME: check top bits */
1199 break;
1200
1201 case TIR_S_C_STO_BD:
7920ce38 1202 /* Store byte displaced: pop stack, sub lc+1, write byte
b34976b6 1203 arg: none. */
dc810e39
AM
1204 dummy = _bfd_vms_pop (abfd, &psect);
1205 dummy -= ((PRIV (sections)[psect])->vma + 1);
1206 image_write_b (abfd, dummy & 0xff);/* FIXME: check top bits */
1207 break;
1208
1209 case TIR_S_C_STO_WD:
7920ce38 1210 /* Store word displaced: pop stack, sub lc+2, write word
b34976b6 1211 arg: none. */
dc810e39
AM
1212 dummy = _bfd_vms_pop (abfd, &psect);
1213 dummy -= ((PRIV (sections)[psect])->vma + 2);
1214 image_write_w (abfd, dummy & 0xffff);/* FIXME: check top bits */
1215 break;
ca09e32b 1216
dc810e39 1217 case TIR_S_C_STO_LD:
7920ce38 1218 /* Store long displaced: pop stack, sub lc+4, write long
b34976b6 1219 arg: none. */
dc810e39
AM
1220 dummy = _bfd_vms_pop (abfd, &psect);
1221 dummy -= ((PRIV (sections)[psect])->vma + 4);
1222 image_write_l (abfd, dummy & 0xffffffff);/* FIXME: check top bits */
1223 break;
ca09e32b 1224
dc810e39 1225 case TIR_S_C_STO_LI:
7920ce38 1226 /* Store short literal: pop stack, write byte
b34976b6 1227 arg: none. */
dc810e39
AM
1228 dummy = _bfd_vms_pop (abfd, &psect);
1229 image_write_b (abfd, dummy & 0xff);/* FIXME: check top bits */
1230 break;
ca09e32b 1231
dc810e39 1232 case TIR_S_C_STO_PIDR:
7920ce38 1233 /* Store position independent data reference: pop stack, write longword
b34976b6 1234 arg: none.
ca09e32b 1235 FIXME: incomplete ! */
dc810e39
AM
1236 dummy = _bfd_vms_pop (abfd, &psect);
1237 image_write_l (abfd, dummy & 0xffffffff);
1238 break;
ca09e32b 1239
dc810e39 1240 case TIR_S_C_STO_PICR:
7920ce38 1241 /* Store position independent code reference: pop stack, write longword
b34976b6
AM
1242 arg: none.
1243 FIXME: incomplete ! */
dc810e39
AM
1244 dummy = _bfd_vms_pop (abfd, &psect);
1245 image_write_b (abfd, 0x9f);
1246 image_write_l (abfd, dummy & 0xffffffff);
1247 break;
ca09e32b 1248
dc810e39 1249 case TIR_S_C_STO_RIVB:
7920ce38 1250 /* Store repeated immediate variable bytes
b34976b6
AM
1251 1-byte count n field followed by n bytes of data
1252 pop stack, write n bytes <stack> times. */
dc810e39
AM
1253 size = *ptr++;
1254 dummy = (unsigned long) _bfd_vms_pop (abfd, NULL);
1255 while (dummy-- > 0L)
1256 image_dump (abfd, ptr, size, 0);
1257 ptr += size;
1258 break;
ca09e32b 1259
dc810e39 1260 case TIR_S_C_STO_B:
7920ce38 1261 /* Store byte from top longword. */
dc810e39
AM
1262 dummy = (unsigned long) _bfd_vms_pop (abfd, NULL);
1263 image_write_b (abfd, dummy & 0xff);
1264 break;
ca09e32b 1265
dc810e39 1266 case TIR_S_C_STO_W:
7920ce38 1267 /* Store word from top longword. */
dc810e39
AM
1268 dummy = (unsigned long) _bfd_vms_pop (abfd, NULL);
1269 image_write_w (abfd, dummy & 0xffff);
1270 break;
ca09e32b 1271
dc810e39 1272 case TIR_S_C_STO_RB:
7920ce38 1273 /* Store repeated byte from top longword. */
dc810e39
AM
1274 size = (unsigned long) _bfd_vms_pop (abfd, NULL);
1275 dummy = (unsigned long) _bfd_vms_pop (abfd, NULL);
1276 while (size-- > 0)
252b5132 1277 image_write_b (abfd, dummy & 0xff);
dc810e39 1278 break;
ca09e32b 1279
dc810e39 1280 case TIR_S_C_STO_RW:
7920ce38 1281 /* Store repeated word from top longword. */
dc810e39
AM
1282 size = (unsigned long) _bfd_vms_pop (abfd, NULL);
1283 dummy = (unsigned long) _bfd_vms_pop (abfd, NULL);
1284 while (size-- > 0)
252b5132 1285 image_write_w (abfd, dummy & 0xffff);
dc810e39 1286 break;
252b5132 1287
dc810e39
AM
1288 case TIR_S_C_STO_RSB:
1289 case TIR_S_C_STO_RSW:
1290 case TIR_S_C_STO_RL:
1291 case TIR_S_C_STO_VPS:
1292 case TIR_S_C_STO_USB:
1293 case TIR_S_C_STO_USW:
1294 case TIR_S_C_STO_RUB:
1295 case TIR_S_C_STO_RUW:
1296 case TIR_S_C_STO_PIRR:
ca09e32b 1297 (*_bfd_error_handler) (_("%s: not implemented"), tir_cmd_name (ptr[-1]));
252b5132
RH
1298 break;
1299
dc810e39 1300 default:
ca09e32b 1301 (*_bfd_error_handler) (_("reserved STO cmd %d"), ptr[-1]);
252b5132 1302 break;
dc810e39 1303 }
252b5132
RH
1304
1305 return ptr;
1306}
1307
7920ce38
NC
1308/* Stack operator commands
1309 All 32 bit signed arithmetic
1310 All word just like a stack calculator
1311 Arguments are popped from stack, results are pushed on stack
b34976b6 1312
ca09e32b 1313 See table 7-5 of the VAX/VMS linker manual. */
252b5132
RH
1314
1315static unsigned char *
7920ce38 1316tir_opr (bfd * abfd, unsigned char *ptr)
252b5132
RH
1317{
1318 long op1, op2;
1319
1320#if VMS_DEBUG
1321 _bfd_vms_debug (5, "tir_opr %d\n", *ptr);
1322#endif
1323
7920ce38 1324 /* Operation. */
252b5132
RH
1325 switch (*ptr++)
1326 {
7920ce38 1327 case TIR_S_C_OPR_NOP: /* No-op. */
dc810e39
AM
1328 break;
1329
7920ce38 1330 case TIR_S_C_OPR_ADD: /* Add. */
dc810e39
AM
1331 op1 = (long) _bfd_vms_pop (abfd, NULL);
1332 op2 = (long) _bfd_vms_pop (abfd, NULL);
1333 _bfd_vms_push (abfd, (uquad) (op1 + op2), -1);
1334 break;
1335
7920ce38 1336 case TIR_S_C_OPR_SUB: /* Subtract. */
dc810e39
AM
1337 op1 = (long) _bfd_vms_pop (abfd, NULL);
1338 op2 = (long) _bfd_vms_pop (abfd, NULL);
1339 _bfd_vms_push (abfd, (uquad) (op2 - op1), -1);
1340 break;
1341
7920ce38 1342 case TIR_S_C_OPR_MUL: /* Multiply. */
dc810e39
AM
1343 op1 = (long) _bfd_vms_pop (abfd, NULL);
1344 op2 = (long) _bfd_vms_pop (abfd, NULL);
1345 _bfd_vms_push (abfd, (uquad) (op1 * op2), -1);
1346 break;
1347
7920ce38 1348 case TIR_S_C_OPR_DIV: /* Divide. */
dc810e39
AM
1349 op1 = (long) _bfd_vms_pop (abfd, NULL);
1350 op2 = (long) _bfd_vms_pop (abfd, NULL);
1351 if (op2 == 0)
1352 _bfd_vms_push (abfd, (uquad) 0, -1);
1353 else
1354 _bfd_vms_push (abfd, (uquad) (op2 / op1), -1);
1355 break;
1356
7920ce38 1357 case TIR_S_C_OPR_AND: /* Logical AND. */
dc810e39
AM
1358 op1 = (long) _bfd_vms_pop (abfd, NULL);
1359 op2 = (long) _bfd_vms_pop (abfd, NULL);
1360 _bfd_vms_push (abfd, (uquad) (op1 & op2), -1);
1361 break;
1362
7920ce38 1363 case TIR_S_C_OPR_IOR: /* Logical inclusive OR. */
dc810e39 1364 op1 = (long) _bfd_vms_pop (abfd, NULL);
dc810e39
AM
1365 op2 = (long) _bfd_vms_pop (abfd, NULL);
1366 _bfd_vms_push (abfd, (uquad) (op1 | op2), -1);
1367 break;
1368
7920ce38 1369 case TIR_S_C_OPR_EOR: /* Logical exclusive OR. */
dc810e39
AM
1370 op1 = (long) _bfd_vms_pop (abfd, NULL);
1371 op2 = (long) _bfd_vms_pop (abfd, NULL);
1372 _bfd_vms_push (abfd, (uquad) (op1 ^ op2), -1);
1373 break;
1374
7920ce38 1375 case TIR_S_C_OPR_NEG: /* Negate. */
dc810e39
AM
1376 op1 = (long) _bfd_vms_pop (abfd, NULL);
1377 _bfd_vms_push (abfd, (uquad) (-op1), -1);
1378 break;
1379
7920ce38 1380 case TIR_S_C_OPR_COM: /* Complement. */
dc810e39
AM
1381 op1 = (long) _bfd_vms_pop (abfd, NULL);
1382 _bfd_vms_push (abfd, (uquad) (op1 ^ -1L), -1);
252b5132
RH
1383 break;
1384
7920ce38 1385 case TIR_S_C_OPR_INSV: /* Insert field. */
dc810e39 1386 (void) _bfd_vms_pop (abfd, NULL);
ca09e32b
NC
1387 (*_bfd_error_handler) (_("%s: not fully implemented"),
1388 tir_cmd_name (ptr[-1]));
252b5132
RH
1389 break;
1390
7920ce38 1391 case TIR_S_C_OPR_ASH: /* Arithmetic shift. */
dc810e39
AM
1392 op1 = (long) _bfd_vms_pop (abfd, NULL);
1393 op2 = (long) _bfd_vms_pop (abfd, NULL);
7920ce38 1394 if (HIGHBIT (op1)) /* Shift right. */
dc810e39 1395 op2 >>= op1;
7920ce38 1396 else /* Shift left. */
dc810e39
AM
1397 op2 <<= op1;
1398 _bfd_vms_push (abfd, (uquad) op2, -1);
ca09e32b
NC
1399 (*_bfd_error_handler) (_("%s: not fully implemented"),
1400 tir_cmd_name (ptr[-1]));
dc810e39
AM
1401 break;
1402
7920ce38 1403 case TIR_S_C_OPR_USH: /* Unsigned shift. */
dc810e39
AM
1404 op1 = (long) _bfd_vms_pop (abfd, NULL);
1405 op2 = (long) _bfd_vms_pop (abfd, NULL);
7920ce38 1406 if (HIGHBIT (op1)) /* Shift right. */
dc810e39 1407 op2 >>= op1;
7920ce38 1408 else /* Shift left. */
dc810e39
AM
1409 op2 <<= op1;
1410 _bfd_vms_push (abfd, (uquad) op2, -1);
ca09e32b
NC
1411 (*_bfd_error_handler) (_("%s: not fully implemented"),
1412 tir_cmd_name (ptr[-1]));
dc810e39
AM
1413 break;
1414
7920ce38 1415 case TIR_S_C_OPR_ROT: /* Rotate. */
dc810e39
AM
1416 op1 = (long) _bfd_vms_pop (abfd, NULL);
1417 op2 = (long) _bfd_vms_pop (abfd, NULL);
7920ce38 1418 if (HIGHBIT (0)) /* Shift right. */
dc810e39 1419 op2 >>= op1;
7920ce38 1420 else /* Shift left. */
dc810e39
AM
1421 op2 <<= op1;
1422 _bfd_vms_push (abfd, (uquad) op2, -1);
ca09e32b
NC
1423 (*_bfd_error_handler) (_("%s: not fully implemented"),
1424 tir_cmd_name (ptr[-1]));
dc810e39
AM
1425 break;
1426
7920ce38 1427 case TIR_S_C_OPR_SEL: /* Select. */
dc810e39
AM
1428 if ((long) _bfd_vms_pop (abfd, NULL) & 0x01L)
1429 (void) _bfd_vms_pop (abfd, NULL);
1430 else
1431 {
1432 op1 = (long) _bfd_vms_pop (abfd, NULL);
1433 (void) _bfd_vms_pop (abfd, NULL);
1434 _bfd_vms_push (abfd, (uquad) op1, -1);
1435 }
1436 break;
1437
ca09e32b
NC
1438 case TIR_S_C_OPR_REDEF: /* Redefine symbol to current location. */
1439 case TIR_S_C_OPR_DFLIT: /* Define a literal. */
1440 (*_bfd_error_handler) (_("%s: not supported"),
1441 tir_cmd_name (ptr[-1]));
dc810e39
AM
1442 break;
1443
1444 default:
ca09e32b 1445 (*_bfd_error_handler) (_("reserved OPR cmd %d"), ptr[-1]);
252b5132
RH
1446 break;
1447 }
1448
1449 return ptr;
1450}
1451
7920ce38 1452/* Control commands
b34976b6 1453
ca09e32b
NC
1454 See table 7-6 of the VAX/VMS linker manual. */
1455
252b5132 1456static unsigned char *
7920ce38 1457tir_ctl (bfd * abfd, unsigned char *ptr)
252b5132
RH
1458{
1459 unsigned long dummy;
5f771d47 1460 unsigned int psect;
252b5132
RH
1461
1462#if VMS_DEBUG
1463 _bfd_vms_debug (5, "tir_ctl %d\n", *ptr);
1464#endif
1465
1466 switch (*ptr++)
1467 {
dc810e39 1468 case TIR_S_C_CTL_SETRB:
ca09e32b 1469 /* Set relocation base: pop stack, set image location counter
b34976b6 1470 arg: none. */
f075ee0c 1471 dummy = _bfd_vms_pop (abfd, (int *) &psect);
dc810e39 1472 if (psect >= PRIV (section_count))
ca09e32b 1473 alloc_section (abfd, psect);
dc810e39
AM
1474 image_set_ptr (abfd, (int) psect, (uquad) dummy);
1475 break;
ca09e32b 1476
dc810e39 1477 case TIR_S_C_CTL_AUGRB:
ca09e32b 1478 /* Augment relocation base: increment image location counter by offset
b34976b6 1479 arg: lw offset value. */
dc810e39
AM
1480 dummy = bfd_getl32 (ptr);
1481 image_inc_ptr (abfd, (uquad) dummy);
1482 break;
ca09e32b 1483
dc810e39 1484 case TIR_S_C_CTL_DFLOC:
ca09e32b 1485 /* Define location: pop index, save location counter under index
b34976b6 1486 arg: none. */
dc810e39 1487 dummy = _bfd_vms_pop (abfd, NULL);
ca09e32b
NC
1488 (*_bfd_error_handler) (_("%s: not fully implemented"),
1489 tir_cmd_name (ptr[-1]));
dc810e39 1490 break;
ca09e32b 1491
dc810e39 1492 case TIR_S_C_CTL_STLOC:
ca09e32b 1493 /* Set location: pop index, restore location counter from index
b34976b6 1494 arg: none. */
f075ee0c 1495 dummy = _bfd_vms_pop (abfd, (int *) &psect);
ca09e32b
NC
1496 (*_bfd_error_handler) (_("%s: not fully implemented"),
1497 tir_cmd_name (ptr[-1]));
252b5132 1498 break;
ca09e32b 1499
252b5132 1500 case TIR_S_C_CTL_STKDL:
ca09e32b 1501 /* Stack defined location: pop index, push location counter from index
b34976b6 1502 arg: none. */
f075ee0c 1503 dummy = _bfd_vms_pop (abfd, (int *) &psect);
ca09e32b
NC
1504 (*_bfd_error_handler) (_("%s: not fully implemented"),
1505 tir_cmd_name (ptr[-1]));
252b5132 1506 break;
ca09e32b 1507
252b5132 1508 default:
ca09e32b 1509 (*_bfd_error_handler) (_("reserved CTL cmd %d"), ptr[-1]);
dc810e39
AM
1510 break;
1511 }
252b5132
RH
1512 return ptr;
1513}
1514
ca09e32b 1515/* Handle command from TIR section. */
252b5132
RH
1516
1517static unsigned char *
7920ce38 1518tir_cmd (bfd * abfd, unsigned char *ptr)
252b5132 1519{
dc810e39
AM
1520 struct
1521 {
252b5132
RH
1522 int mincod;
1523 int maxcod;
672579e9 1524 unsigned char * (*explain) (bfd *, unsigned char *);
dc810e39
AM
1525 }
1526 tir_table[] =
1527 {
b34976b6 1528 { 0, TIR_S_C_MAXSTACOD, tir_sta },
dc810e39
AM
1529 { TIR_S_C_MINSTOCOD, TIR_S_C_MAXSTOCOD, tir_sto },
1530 { TIR_S_C_MINOPRCOD, TIR_S_C_MAXOPRCOD, tir_opr },
1531 { TIR_S_C_MINCTLCOD, TIR_S_C_MAXCTLCOD, tir_ctl },
1532 { -1, -1, NULL }
252b5132
RH
1533 };
1534 int i = 0;
1535
1536#if VMS_DEBUG
1537 _bfd_vms_debug (4, "tir_cmd %d/%x\n", *ptr, *ptr);
dc810e39 1538 _bfd_hexdump (8, ptr, 16, (int) ptr);
252b5132
RH
1539#endif
1540
7920ce38 1541 if (*ptr & 0x80)
252b5132 1542 {
7920ce38 1543 /* Store immediate. */
252b5132
RH
1544 i = 128 - (*ptr++ & 0x7f);
1545 image_dump (abfd, ptr, i, 0);
1546 ptr += i;
1547 }
1548 else
1549 {
1550 while (tir_table[i].mincod >= 0)
1551 {
672579e9 1552 if ( (tir_table[i].mincod <= *ptr)
dc810e39 1553 && (*ptr <= tir_table[i].maxcod))
252b5132
RH
1554 {
1555 ptr = tir_table[i].explain (abfd, ptr);
1556 break;
1557 }
1558 i++;
1559 }
1560 if (tir_table[i].mincod < 0)
1561 {
ca09e32b 1562 (*_bfd_error_handler) (_("obj code %d not found"), *ptr);
252b5132
RH
1563 ptr = 0;
1564 }
1565 }
1566
1567 return ptr;
1568}
1569
ca09e32b 1570/* Handle command from ETIR section. */
252b5132
RH
1571
1572static int
7920ce38 1573etir_cmd (bfd * abfd, int cmd, unsigned char *ptr)
252b5132 1574{
dc810e39
AM
1575 static struct
1576 {
252b5132
RH
1577 int mincod;
1578 int maxcod;
7920ce38 1579 bfd_boolean (*explain) (bfd *, int, unsigned char *);
dc810e39
AM
1580 }
1581 etir_table[] =
1582 {
252b5132
RH
1583 { ETIR_S_C_MINSTACOD, ETIR_S_C_MAXSTACOD, etir_sta },
1584 { ETIR_S_C_MINSTOCOD, ETIR_S_C_MAXSTOCOD, etir_sto },
1585 { ETIR_S_C_MINOPRCOD, ETIR_S_C_MAXOPRCOD, etir_opr },
1586 { ETIR_S_C_MINCTLCOD, ETIR_S_C_MAXCTLCOD, etir_ctl },
1587 { ETIR_S_C_MINSTCCOD, ETIR_S_C_MAXSTCCOD, etir_stc },
1588 { -1, -1, NULL }
1589 };
1590
1591 int i = 0;
1592
1593#if VMS_DEBUG
1594 _bfd_vms_debug (4, "etir_cmd %d/%x\n", cmd, cmd);
dc810e39 1595 _bfd_hexdump (8, ptr, 16, (int) ptr);
252b5132
RH
1596#endif
1597
1598 while (etir_table[i].mincod >= 0)
1599 {
672579e9 1600 if ( (etir_table[i].mincod <= cmd)
dc810e39 1601 && (cmd <= etir_table[i].maxcod))
252b5132
RH
1602 {
1603 if (!etir_table[i].explain (abfd, cmd, ptr))
1604 return -1;
1605 break;
1606 }
1607 i++;
1608 }
1609
1610#if VMS_DEBUG
1611 _bfd_vms_debug (4, "etir_cmd: = 0\n");
1612#endif
1613 return 0;
1614}
1615
252b5132 1616/* Text Information and Relocation Records (OBJ$C_TIR)
ca09e32b 1617 handle tir record. */
252b5132
RH
1618
1619static int
7920ce38 1620analyze_tir (bfd * abfd, unsigned char *ptr, unsigned int length)
252b5132
RH
1621{
1622 unsigned char *maxptr;
1623
1624#if VMS_DEBUG
1625 _bfd_vms_debug (3, "analyze_tir: %d bytes\n", length);
1626#endif
1627
1628 maxptr = ptr + length;
1629
1630 while (ptr < maxptr)
1631 {
1632 ptr = tir_cmd (abfd, ptr);
1633 if (ptr == 0)
1634 return -1;
1635 }
1636
1637 return 0;
1638}
1639
252b5132 1640/* Text Information and Relocation Records (EOBJ$C_ETIR)
ca09e32b 1641 handle etir record. */
252b5132
RH
1642
1643static int
7920ce38 1644analyze_etir (bfd * abfd, unsigned char *ptr, unsigned int length)
252b5132
RH
1645{
1646 int cmd;
1647 unsigned char *maxptr;
1648 int result = 0;
1649
1650#if VMS_DEBUG
1651 _bfd_vms_debug (3, "analyze_etir: %d bytes\n", length);
1652#endif
1653
1654 maxptr = ptr + length;
1655
1656 while (ptr < maxptr)
1657 {
1658 cmd = bfd_getl16 (ptr);
1659 length = bfd_getl16 (ptr + 2);
1660 result = etir_cmd (abfd, cmd, ptr+4);
1661 if (result != 0)
1662 break;
1663 ptr += length;
1664 }
1665
1666#if VMS_DEBUG
1667 _bfd_vms_debug (3, "analyze_etir: = %d\n", result);
1668#endif
1669
1670 return result;
1671}
1672
ca09e32b
NC
1673/* Process ETIR record
1674 Return 0 on success, -1 on error. */
252b5132
RH
1675
1676int
7920ce38 1677_bfd_vms_slurp_tir (bfd * abfd, int objtype)
252b5132
RH
1678{
1679 int result;
1680
1681#if VMS_DEBUG
1682 _bfd_vms_debug (2, "TIR/ETIR\n");
1683#endif
1684
1685 switch (objtype)
1686 {
dc810e39 1687 case EOBJ_S_C_ETIR:
7920ce38 1688 PRIV (vms_rec) += 4; /* Skip type, size. */
dc810e39
AM
1689 PRIV (rec_size) -= 4;
1690 result = analyze_etir (abfd, PRIV (vms_rec), (unsigned) PRIV (rec_size));
1691 break;
1692 case OBJ_S_C_TIR:
7920ce38 1693 PRIV (vms_rec) += 1; /* Skip type. */
dc810e39
AM
1694 PRIV (rec_size) -= 1;
1695 result = analyze_tir (abfd, PRIV (vms_rec), (unsigned) PRIV (rec_size));
1696 break;
1697 default:
1698 result = -1;
1699 break;
252b5132
RH
1700 }
1701
1702 return result;
1703}
1704
ca09e32b
NC
1705/* Process EDBG record
1706 Return 0 on success, -1 on error
672579e9 1707
ca09e32b 1708 Not implemented yet. */
252b5132
RH
1709
1710int
7920ce38 1711_bfd_vms_slurp_dbg (bfd * abfd, int objtype ATTRIBUTE_UNUSED)
252b5132
RH
1712{
1713#if VMS_DEBUG
1714 _bfd_vms_debug (2, "DBG/EDBG\n");
1715#endif
1716
1717 abfd->flags |= (HAS_DEBUG | HAS_LINENO);
1718 return 0;
1719}
1720
ca09e32b
NC
1721/* Process ETBT record
1722 Return 0 on success, -1 on error
672579e9 1723
ca09e32b 1724 Not implemented yet. */
252b5132
RH
1725
1726int
7920ce38
NC
1727_bfd_vms_slurp_tbt (bfd * abfd ATTRIBUTE_UNUSED,
1728 int objtype ATTRIBUTE_UNUSED)
252b5132
RH
1729{
1730#if VMS_DEBUG
1731 _bfd_vms_debug (2, "TBT/ETBT\n");
1732#endif
1733
1734 return 0;
1735}
1736
ca09e32b
NC
1737/* Process LNK record
1738 Return 0 on success, -1 on error
672579e9 1739
ca09e32b 1740 Not implemented yet. */
252b5132
RH
1741
1742int
7920ce38
NC
1743_bfd_vms_slurp_lnk (bfd * abfd ATTRIBUTE_UNUSED,
1744 int objtype ATTRIBUTE_UNUSED)
252b5132
RH
1745{
1746#if VMS_DEBUG
1747 _bfd_vms_debug (2, "LNK\n");
1748#endif
1749
1750 return 0;
1751}
1752\f
7920ce38
NC
1753/* Start ETIR record for section #index at virtual addr offset. */
1754
1755static void
1756start_etir_record (bfd * abfd, int index, uquad offset, bfd_boolean justoffset)
1757{
1758 if (!justoffset)
1759 {
1760 /* One ETIR per section. */
1761 _bfd_vms_output_begin (abfd, EOBJ_S_C_ETIR, -1);
1762 _bfd_vms_output_push (abfd);
1763 }
1764
1765 /* Push start offset. */
1766 _bfd_vms_output_begin (abfd, ETIR_S_C_STA_PQ, -1);
1767 _bfd_vms_output_long (abfd, (unsigned long) index);
1768 _bfd_vms_output_quad (abfd, (uquad) offset);
1769 _bfd_vms_output_flush (abfd);
1770
1771 /* Start = pop (). */
1772 _bfd_vms_output_begin (abfd, ETIR_S_C_CTL_SETRB, -1);
1773 _bfd_vms_output_flush (abfd);
1774}
1775
1776static void
1777end_etir_record (bfd * abfd)
1778{
1779 _bfd_vms_output_pop (abfd);
1780 _bfd_vms_output_end (abfd);
1781}
1782
ca09e32b
NC
1783/* WRITE ETIR SECTION
1784
1785 This is still under construction and therefore not documented. */
252b5132 1786
252b5132 1787static void
7920ce38 1788sto_imm (bfd * abfd, vms_section *sptr, bfd_vma vaddr, int index)
252b5132
RH
1789{
1790 int size;
1791 int ssize;
1792 unsigned char *cptr;
1793
1794#if VMS_DEBUG
1795 _bfd_vms_debug (8, "sto_imm %d bytes\n", sptr->size);
dc810e39 1796 _bfd_hexdump (9, sptr->contents, (int) sptr->size, (int) vaddr);
252b5132
RH
1797#endif
1798
1799 ssize = sptr->size;
1800 cptr = sptr->contents;
1801
1802 while (ssize > 0)
1803 {
7920ce38
NC
1804 /* Try all the rest. */
1805 size = ssize;
252b5132
RH
1806
1807 if (_bfd_vms_output_check (abfd, size) < 0)
7920ce38
NC
1808 {
1809 /* Doesn't fit, split ! */
252b5132 1810 end_etir_record (abfd);
b34976b6 1811 start_etir_record (abfd, index, vaddr, FALSE);
7920ce38
NC
1812 /* Get max size. */
1813 size = _bfd_vms_output_check (abfd, 0);
1814 /* More than what's left ? */
1815 if (size > ssize)
252b5132
RH
1816 size = ssize;
1817 }
1818
1819 _bfd_vms_output_begin (abfd, ETIR_S_C_STO_IMM, -1);
672579e9 1820 _bfd_vms_output_long (abfd, (unsigned long) (size));
252b5132
RH
1821 _bfd_vms_output_dump (abfd, cptr, size);
1822 _bfd_vms_output_flush (abfd);
1823
1824#if VMS_DEBUG
1825 _bfd_vms_debug (10, "dumped %d bytes\n", size);
dc810e39 1826 _bfd_hexdump (10, cptr, (int) size, (int) vaddr);
252b5132
RH
1827#endif
1828
1829 vaddr += size;
1830 ssize -= size;
1831 cptr += size;
1832 }
252b5132
RH
1833}
1834
ca09e32b 1835/* Write section contents for bfd abfd. */
252b5132
RH
1836
1837int
7920ce38 1838_bfd_vms_write_tir (bfd * abfd, int objtype ATTRIBUTE_UNUSED)
252b5132
RH
1839{
1840 asection *section;
1841 vms_section *sptr;
1842 int nextoffset;
1843
1844#if VMS_DEBUG
1845 _bfd_vms_debug (2, "vms_write_tir (%p, %d)\n", abfd, objtype);
1846#endif
1847
1848 _bfd_vms_output_alignment (abfd, 4);
1849
1850 nextoffset = 0;
dc810e39 1851 PRIV (vms_linkage_index) = 1;
252b5132 1852
ca09e32b 1853 /* Dump all other sections. */
252b5132
RH
1854 section = abfd->sections;
1855
1856 while (section != NULL)
1857 {
1858
1859#if VMS_DEBUG
dc810e39
AM
1860 _bfd_vms_debug (4, "writing %d. section '%s' (%d bytes)\n",
1861 section->index, section->name,
eea6121a 1862 (int) (section->size));
252b5132
RH
1863#endif
1864
1865 if (section->flags & SEC_RELOC)
1866 {
1867 int i;
1868
1869 if ((i = section->reloc_count) <= 0)
7920ce38
NC
1870 (*_bfd_error_handler) (_("SEC_RELOC with no relocs in section %s"),
1871 section->name);
252b5132
RH
1872#if VMS_DEBUG
1873 else
1874 {
1875 arelent **rptr;
1876 _bfd_vms_debug (4, "%d relocations:\n", i);
1877 rptr = section->orelocation;
1878 while (i-- > 0)
1879 {
1880 _bfd_vms_debug (4, "sym %s in sec %s, value %08lx, addr %08lx, off %08lx, len %d: %s\n",
dc810e39
AM
1881 (*(*rptr)->sym_ptr_ptr)->name,
1882 (*(*rptr)->sym_ptr_ptr)->section->name,
1883 (long) (*(*rptr)->sym_ptr_ptr)->value,
1884 (*rptr)->address, (*rptr)->addend,
1885 bfd_get_reloc_size ((*rptr)->howto),
1886 (*rptr)->howto->name);
252b5132
RH
1887 rptr++;
1888 }
1889 }
1890#endif
1891 }
1892
1893 if ((section->flags & SEC_HAS_CONTENTS)
dc810e39 1894 && (! bfd_is_com_section (section)))
252b5132 1895 {
7920ce38
NC
1896 /* Virtual addr in section. */
1897 bfd_vma vaddr;
252b5132
RH
1898
1899 sptr = _bfd_get_vms_section (abfd, section->index);
1900 if (sptr == NULL)
1901 {
1902 bfd_set_error (bfd_error_no_contents);
1903 return -1;
1904 }
1905
672579e9 1906 vaddr = (bfd_vma) (sptr->offset);
252b5132
RH
1907
1908 start_etir_record (abfd, section->index, (uquad) sptr->offset,
b34976b6 1909 FALSE);
252b5132 1910
7920ce38 1911 while (sptr != NULL)
252b5132 1912 {
7920ce38
NC
1913 /* One STA_PQ, CTL_SETRB per vms_section. */
1914 if (section->flags & SEC_RELOC)
252b5132 1915 {
7920ce38 1916 /* Check for relocs. */
252b5132
RH
1917 arelent **rptr = section->orelocation;
1918 int i = section->reloc_count;
ca09e32b 1919
252b5132
RH
1920 for (;;)
1921 {
1922 bfd_size_type addr = (*rptr)->address;
5f771d47 1923 bfd_size_type len = bfd_get_reloc_size ((*rptr)->howto);
7920ce38 1924 if (sptr->offset < addr)
252b5132 1925 {
7920ce38 1926 /* Sptr starts before reloc. */
5f771d47 1927 bfd_size_type before = addr - sptr->offset;
7920ce38 1928 if (sptr->size <= before)
252b5132 1929 {
7920ce38 1930 /* Complete before. */
252b5132
RH
1931 sto_imm (abfd, sptr, vaddr, section->index);
1932 vaddr += sptr->size;
1933 break;
1934 }
7920ce38 1935 else
252b5132 1936 {
7920ce38 1937 /* Partly before. */
252b5132 1938 int after = sptr->size - before;
7920ce38 1939
252b5132
RH
1940 sptr->size = before;
1941 sto_imm (abfd, sptr, vaddr, section->index);
1942 vaddr += sptr->size;
1943 sptr->contents += before;
1944 sptr->offset += before;
1945 sptr->size = after;
1946 }
1947 }
7920ce38 1948 else if (sptr->offset == addr)
252b5132 1949 {
7920ce38 1950 /* Sptr starts at reloc. */
252b5132
RH
1951 asymbol *sym = *(*rptr)->sym_ptr_ptr;
1952 asection *sec = sym->section;
1953
1954 switch ((*rptr)->howto->type)
1955 {
1956 case ALPHA_R_IGNORE:
1957 break;
1958
1959 case ALPHA_R_REFLONG:
1960 {
1961 if (bfd_is_und_section (sym->section))
1962 {
dc810e39
AM
1963 int slen = strlen ((char *) sym->name);
1964 char *hash;
1965
1966 if (_bfd_vms_output_check (abfd, slen) < 0)
252b5132
RH
1967 {
1968 end_etir_record (abfd);
1969 start_etir_record (abfd,
1970 section->index,
b34976b6 1971 vaddr, FALSE);
252b5132
RH
1972 }
1973 _bfd_vms_output_begin (abfd,
dc810e39
AM
1974 ETIR_S_C_STO_GBL_LW,
1975 -1);
1976 hash = (_bfd_vms_length_hash_symbol
1977 (abfd, sym->name, EOBJ_S_C_SYMSIZ));
1978 _bfd_vms_output_counted (abfd, hash);
252b5132
RH
1979 _bfd_vms_output_flush (abfd);
1980 }
1981 else if (bfd_is_abs_section (sym->section))
1982 {
1983 if (_bfd_vms_output_check (abfd, 16) < 0)
1984 {
1985 end_etir_record (abfd);
1986 start_etir_record (abfd,
1987 section->index,
b34976b6 1988 vaddr, FALSE);
252b5132
RH
1989 }
1990 _bfd_vms_output_begin (abfd,
dc810e39
AM
1991 ETIR_S_C_STA_LW,
1992 -1);
252b5132 1993 _bfd_vms_output_quad (abfd,
dc810e39 1994 (uquad) sym->value);
252b5132
RH
1995 _bfd_vms_output_flush (abfd);
1996 _bfd_vms_output_begin (abfd,
dc810e39
AM
1997 ETIR_S_C_STO_LW,
1998 -1);
252b5132
RH
1999 _bfd_vms_output_flush (abfd);
2000 }
2001 else
2002 {
2003 if (_bfd_vms_output_check (abfd, 32) < 0)
2004 {
2005 end_etir_record (abfd);
2006 start_etir_record (abfd,
2007 section->index,
b34976b6 2008 vaddr, FALSE);
252b5132
RH
2009 }
2010 _bfd_vms_output_begin (abfd,
dc810e39
AM
2011 ETIR_S_C_STA_PQ,
2012 -1);
252b5132 2013 _bfd_vms_output_long (abfd,
dc810e39 2014 (unsigned long) (sec->index));
252b5132 2015 _bfd_vms_output_quad (abfd,
dc810e39
AM
2016 ((uquad) (*rptr)->addend
2017 + (uquad) sym->value));
252b5132
RH
2018 _bfd_vms_output_flush (abfd);
2019 _bfd_vms_output_begin (abfd,
dc810e39
AM
2020 ETIR_S_C_STO_LW,
2021 -1);
252b5132
RH
2022 _bfd_vms_output_flush (abfd);
2023 }
2024 }
2025 break;
2026
2027 case ALPHA_R_REFQUAD:
2028 {
2029 if (bfd_is_und_section (sym->section))
2030 {
dc810e39
AM
2031 int slen = strlen ((char *) sym->name);
2032 char *hash;
7920ce38 2033
dc810e39 2034 if (_bfd_vms_output_check (abfd, slen) < 0)
252b5132
RH
2035 {
2036 end_etir_record (abfd);
2037 start_etir_record (abfd,
2038 section->index,
b34976b6 2039 vaddr, FALSE);
252b5132
RH
2040 }
2041 _bfd_vms_output_begin (abfd,
dc810e39
AM
2042 ETIR_S_C_STO_GBL,
2043 -1);
2044 hash = (_bfd_vms_length_hash_symbol
2045 (abfd, sym->name, EOBJ_S_C_SYMSIZ));
2046 _bfd_vms_output_counted (abfd, hash);
252b5132
RH
2047 _bfd_vms_output_flush (abfd);
2048 }
2049 else if (bfd_is_abs_section (sym->section))
2050 {
2051 if (_bfd_vms_output_check (abfd, 16) < 0)
2052 {
2053 end_etir_record (abfd);
2054 start_etir_record (abfd,
2055 section->index,
b34976b6 2056 vaddr, FALSE);
252b5132
RH
2057 }
2058 _bfd_vms_output_begin (abfd,
dc810e39
AM
2059 ETIR_S_C_STA_QW,
2060 -1);
252b5132 2061 _bfd_vms_output_quad (abfd,
dc810e39 2062 (uquad) sym->value);
252b5132
RH
2063 _bfd_vms_output_flush (abfd);
2064 _bfd_vms_output_begin (abfd,
dc810e39
AM
2065 ETIR_S_C_STO_QW,
2066 -1);
252b5132
RH
2067 _bfd_vms_output_flush (abfd);
2068 }
2069 else
2070 {
2071 if (_bfd_vms_output_check (abfd, 32) < 0)
2072 {
2073 end_etir_record (abfd);
2074 start_etir_record (abfd,
2075 section->index,
b34976b6 2076 vaddr, FALSE);
252b5132
RH
2077 }
2078 _bfd_vms_output_begin (abfd,
dc810e39
AM
2079 ETIR_S_C_STA_PQ,
2080 -1);
252b5132 2081 _bfd_vms_output_long (abfd,
dc810e39 2082 (unsigned long) (sec->index));
252b5132 2083 _bfd_vms_output_quad (abfd,
dc810e39
AM
2084 ((uquad) (*rptr)->addend
2085 + (uquad) sym->value));
252b5132
RH
2086 _bfd_vms_output_flush (abfd);
2087 _bfd_vms_output_begin (abfd,
dc810e39
AM
2088 ETIR_S_C_STO_OFF,
2089 -1);
252b5132
RH
2090 _bfd_vms_output_flush (abfd);
2091 }
2092 }
2093 break;
2094
2095 case ALPHA_R_HINT:
2096 {
2097 int hint_size;
dc810e39 2098 char *hash ATTRIBUTE_UNUSED;
252b5132
RH
2099
2100 hint_size = sptr->size;
2101 sptr->size = len;
2102 sto_imm (abfd, sptr, vaddr, section->index);
2103 sptr->size = hint_size;
252b5132
RH
2104 }
2105 break;
2106 case ALPHA_R_LINKAGE:
2107 {
dc810e39
AM
2108 char *hash;
2109
252b5132
RH
2110 if (_bfd_vms_output_check (abfd, 64) < 0)
2111 {
2112 end_etir_record (abfd);
2113 start_etir_record (abfd, section->index,
b34976b6 2114 vaddr, FALSE);
252b5132
RH
2115 }
2116 _bfd_vms_output_begin (abfd,
dc810e39
AM
2117 ETIR_S_C_STC_LP_PSB,
2118 -1);
252b5132 2119 _bfd_vms_output_long (abfd,
dc810e39
AM
2120 (unsigned long) PRIV (vms_linkage_index));
2121 PRIV (vms_linkage_index) += 2;
2122 hash = (_bfd_vms_length_hash_symbol
2123 (abfd, sym->name, EOBJ_S_C_SYMSIZ));
2124 _bfd_vms_output_counted (abfd, hash);
252b5132
RH
2125 _bfd_vms_output_byte (abfd, 0);
2126 _bfd_vms_output_flush (abfd);
2127 }
2128 break;
2129
2130 case ALPHA_R_CODEADDR:
2131 {
dc810e39
AM
2132 int slen = strlen ((char *) sym->name);
2133 char *hash;
2134 if (_bfd_vms_output_check (abfd, slen) < 0)
252b5132
RH
2135 {
2136 end_etir_record (abfd);
2137 start_etir_record (abfd,
2138 section->index,
b34976b6 2139 vaddr, FALSE);
252b5132
RH
2140 }
2141 _bfd_vms_output_begin (abfd,
dc810e39
AM
2142 ETIR_S_C_STO_CA,
2143 -1);
2144 hash = (_bfd_vms_length_hash_symbol
2145 (abfd, sym->name, EOBJ_S_C_SYMSIZ));
2146 _bfd_vms_output_counted (abfd, hash);
252b5132
RH
2147 _bfd_vms_output_flush (abfd);
2148 }
2149 break;
2150
2151 default:
2152 (*_bfd_error_handler) (_("Unhandled relocation %s"),
2153 (*rptr)->howto->name);
2154 break;
2155 }
2156
2157 vaddr += len;
2158
2159 if (len == sptr->size)
2160 {
2161 break;
2162 }
2163 else
2164 {
2165 sptr->contents += len;
2166 sptr->offset += len;
2167 sptr->size -= len;
2168 i--;
2169 rptr++;
2170 }
2171 }
7920ce38 2172 else
252b5132 2173 {
7920ce38
NC
2174 /* Sptr starts after reloc. */
2175 i--;
2176 /* Check next reloc. */
252b5132
RH
2177 rptr++;
2178 }
2179
7920ce38 2180 if (i == 0)
252b5132 2181 {
7920ce38 2182 /* All reloc checked. */
252b5132
RH
2183 if (sptr->size > 0)
2184 {
7920ce38 2185 /* Dump rest. */
dc810e39 2186 sto_imm (abfd, sptr, vaddr, section->index);
252b5132
RH
2187 vaddr += sptr->size;
2188 }
2189 break;
2190 }
7920ce38
NC
2191 }
2192 }
2193 else
252b5132 2194 {
7920ce38 2195 /* No relocs, just dump. */
252b5132
RH
2196 sto_imm (abfd, sptr, vaddr, section->index);
2197 vaddr += sptr->size;
2198 }
2199
2200 sptr = sptr->next;
7920ce38 2201 }
252b5132
RH
2202
2203 end_etir_record (abfd);
7920ce38 2204 }
252b5132
RH
2205
2206 section = section->next;
2207 }
2208
dc810e39 2209 _bfd_vms_output_alignment (abfd, 2);
252b5132
RH
2210 return 0;
2211}
2212
ca09e32b 2213/* Write traceback data for bfd abfd. */
252b5132
RH
2214
2215int
7920ce38
NC
2216_bfd_vms_write_tbt (bfd * abfd ATTRIBUTE_UNUSED,
2217 int objtype ATTRIBUTE_UNUSED)
252b5132
RH
2218{
2219#if VMS_DEBUG
2220 _bfd_vms_debug (2, "vms_write_tbt (%p, %d)\n", abfd, objtype);
2221#endif
2222
2223 return 0;
2224}
2225
ca09e32b 2226/* Write debug info for bfd abfd. */
252b5132
RH
2227
2228int
7920ce38
NC
2229_bfd_vms_write_dbg (bfd * abfd ATTRIBUTE_UNUSED,
2230 int objtype ATTRIBUTE_UNUSED)
252b5132
RH
2231{
2232#if VMS_DEBUG
2233 _bfd_vms_debug (2, "vms_write_dbg (%p, objtype)\n", abfd, objtype);
2234#endif
2235
2236 return 0;
2237}