]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - bfd/vms-alpha.c
Update year range in copyright notice of binutils files
[thirdparty/binutils-gdb.git] / bfd / vms-alpha.c
CommitLineData
95e34ef7 1/* vms.c -- BFD back-end for EVAX (openVMS/Alpha) files.
a2c58332 2 Copyright (C) 1996-2022 Free Software Foundation, Inc.
95e34ef7
TG
3
4 Initial version written by Klaus Kaempf (kkaempf@rmi.de)
5 Major rewrite by Adacore.
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
20 MA 02110-1301, USA. */
21
22/* TODO:
f9eeb9c9 23 o overlayed sections
95e34ef7
TG
24 o PIC
25 o Generation of shared image
95e34ef7
TG
26 o Relocation optimizations
27 o EISD for the stack
28 o Vectors isect
29 o 64 bits sections
30 o Entry point
f9eeb9c9
TG
31 o LIB$INITIALIZE
32 o protected sections (for messages)
95e34ef7
TG
33 ...
34*/
35
36#include "sysdep.h"
f8b1e5f6 37#include <limits.h>
95e34ef7
TG
38#include "bfd.h"
39#include "bfdlink.h"
40#include "libbfd.h"
41#include "bfdver.h"
42
43#include "vms.h"
44#include "vms/eihd.h"
45#include "vms/eiha.h"
46#include "vms/eihi.h"
47#include "vms/eihs.h"
48#include "vms/eisd.h"
49#include "vms/dmt.h"
50#include "vms/dst.h"
51#include "vms/eihvn.h"
52#include "vms/eobjrec.h"
53#include "vms/egsd.h"
54#include "vms/egps.h"
9a1b4480 55#include "vms/esgps.h"
95e34ef7
TG
56#include "vms/eeom.h"
57#include "vms/emh.h"
58#include "vms/eiaf.h"
59#include "vms/shl.h"
60#include "vms/eicp.h"
61#include "vms/etir.h"
62#include "vms/egsy.h"
63#include "vms/esdf.h"
64#include "vms/esdfm.h"
65#include "vms/esdfv.h"
66#include "vms/esrf.h"
67#include "vms/egst.h"
9a1b4480 68#include "vms/eidc.h"
95e34ef7
TG
69#include "vms/dsc.h"
70#include "vms/prt.h"
71#include "vms/internal.h"
72\f
73
74#define MIN(a,b) ((a) < (b) ? (a) : (b))
f8b1e5f6
AM
75#ifndef CHAR_BIT
76#define CHAR_BIT 8
77#endif
95e34ef7
TG
78
79/* The r_type field in a reloc is one of the following values. */
80#define ALPHA_R_IGNORE 0
81#define ALPHA_R_REFQUAD 1
82#define ALPHA_R_BRADDR 2
83#define ALPHA_R_HINT 3
84#define ALPHA_R_SREL16 4
85#define ALPHA_R_SREL32 5
86#define ALPHA_R_SREL64 6
87#define ALPHA_R_OP_PUSH 7
88#define ALPHA_R_OP_STORE 8
89#define ALPHA_R_OP_PSUB 9
90#define ALPHA_R_OP_PRSHIFT 10
91#define ALPHA_R_LINKAGE 11
92#define ALPHA_R_REFLONG 12
93#define ALPHA_R_CODEADDR 13
94#define ALPHA_R_NOP 14
95#define ALPHA_R_BSR 15
96#define ALPHA_R_LDA 16
97#define ALPHA_R_BOH 17
44273c5b 98
95e34ef7
TG
99/* These are used with DST_S_C_LINE_NUM. */
100#define DST_S_C_LINE_NUM_HEADER_SIZE 4
101
102/* These are used with DST_S_C_SOURCE */
103
104#define DST_S_B_PCLINE_UNSBYTE 1
105#define DST_S_W_PCLINE_UNSWORD 1
106#define DST_S_L_PCLINE_UNSLONG 1
107
108#define DST_S_B_MODBEG_NAME 14
109#define DST_S_L_RTNBEG_ADDRESS 5
110#define DST_S_B_RTNBEG_NAME 13
111#define DST_S_L_RTNEND_SIZE 5
112
113/* These are used with DST_S_C_SOURCE. */
114#define DST_S_C_SOURCE_HEADER_SIZE 4
115
116#define DST_S_B_SRC_DF_LENGTH 1
117#define DST_S_W_SRC_DF_FILEID 3
118#define DST_S_B_SRC_DF_FILENAME 20
119#define DST_S_B_SRC_UNSBYTE 1
120#define DST_S_W_SRC_UNSWORD 1
121#define DST_S_L_SRC_UNSLONG 1
122
123/* Debugger symbol definitions. */
124
07d6d2b8
AM
125#define DBG_S_L_DMT_MODBEG 0
126#define DBG_S_L_DST_SIZE 4
127#define DBG_S_W_DMT_PSECT_COUNT 8
95e34ef7
TG
128#define DBG_S_C_DMT_HEADER_SIZE 12
129
07d6d2b8 130#define DBG_S_L_DMT_PSECT_START 0
95e34ef7 131#define DBG_S_L_DMT_PSECT_LENGTH 4
07d6d2b8 132#define DBG_S_C_DMT_PSECT_SIZE 8
95e34ef7
TG
133
134/* VMS module header. */
135
136struct hdr_struct
137{
138 char hdr_b_strlvl;
139 int hdr_l_arch1;
140 int hdr_l_arch2;
141 int hdr_l_recsiz;
142 char *hdr_t_name;
143 char *hdr_t_version;
144 char *hdr_t_date;
145 char *hdr_c_lnm;
146 char *hdr_c_src;
147 char *hdr_c_ttl;
148};
149
150#define EMH_DATE_LENGTH 17
151
152/* VMS End-Of-Module records (EOM/EEOM). */
153
154struct eom_struct
155{
156 unsigned int eom_l_total_lps;
157 unsigned short eom_w_comcod;
0a1b45a2 158 bool eom_has_transfer;
95e34ef7
TG
159 unsigned char eom_b_tfrflg;
160 unsigned int eom_l_psindx;
161 unsigned int eom_l_tfradr;
162};
163
164struct vms_symbol_entry
165{
166 bfd *owner;
167
168 /* Common fields. */
169 unsigned char typ;
170 unsigned char data_type;
171 unsigned short flags;
172
173 /* Section and offset/value of the symbol. */
95e34ef7 174 unsigned int value;
a928f1d7 175 asection *section;
95e34ef7
TG
176
177 /* Section and offset/value for the entry point (only for subprg). */
a928f1d7 178 asection *code_section;
95e34ef7
TG
179 unsigned int code_value;
180
181 /* Symbol vector offset. */
182 unsigned int symbol_vector;
183
184 /* Length of the name. */
185 unsigned char namelen;
186
187 char name[1];
188};
189
190/* Stack value for push/pop commands. */
191
192struct stack_struct
193{
194 bfd_vma value;
195 unsigned int reloc;
196};
197
198#define STACKSIZE 128
199
200/* A minimal decoding of DST compilation units. We only decode
201 what's needed to get to the line number information. */
202
203struct fileinfo
204{
205 char *name;
206 unsigned int srec;
207};
208
209struct srecinfo
210{
211 struct srecinfo *next;
212 unsigned int line;
213 unsigned int sfile;
214 unsigned int srec;
215};
216
217struct lineinfo
218{
219 struct lineinfo *next;
220 bfd_vma address;
221 unsigned int line;
222};
223
224struct funcinfo
225{
226 struct funcinfo *next;
227 char *name;
228 bfd_vma low;
229 bfd_vma high;
230};
231
232struct module
233{
234 /* Chain the previously read compilation unit. */
235 struct module *next;
236
237 /* The module name. */
238 char *name;
239
240 /* The start offset and size of debug info in the DST section. */
241 unsigned int modbeg;
242 unsigned int size;
243
244 /* The lowest and highest addresses contained in this compilation
245 unit as specified in the compilation unit header. */
246 bfd_vma low;
247 bfd_vma high;
248
249 /* The listing line table. */
250 struct lineinfo *line_table;
251
252 /* The source record table. */
253 struct srecinfo *srec_table;
254
255 /* A list of the functions found in this module. */
256 struct funcinfo *func_table;
257
258 /* Current allocation of file_table. */
259 unsigned int file_table_count;
260
261 /* An array of the files making up this module. */
262 struct fileinfo *file_table;
263};
264
265/* BFD private data for alpha-vms. */
266
267struct vms_private_data_struct
268{
269 /* If true, relocs have been read. */
0a1b45a2 270 bool reloc_done;
95e34ef7
TG
271
272 /* Record input buffer. */
273 struct vms_rec_rd recrd;
274 struct vms_rec_wr recwr;
275
276 struct hdr_struct hdr_data; /* data from HDR/EMH record */
277 struct eom_struct eom_data; /* data from EOM/EEOM record */
c734eb83 278
46d00b8a
TG
279 /* Transfer addresses (entry points). */
280 bfd_vma transfer_address[4];
281
c734eb83 282 /* Array of GSD sections to get the correspond BFD one. */
07d6d2b8 283 unsigned int section_max; /* Size of the sections array. */
c734eb83
TG
284 unsigned int section_count; /* Number of GSD sections. */
285 asection **sections;
95e34ef7
TG
286
287 /* Array of raw symbols. */
288 struct vms_symbol_entry **syms;
289
290 /* Canonicalized symbols. */
291 asymbol **csymbols;
292
293 /* Number of symbols. */
294 unsigned int gsd_sym_count;
295 /* Size of the syms array. */
296 unsigned int max_sym_count;
297 /* Number of procedure symbols. */
298 unsigned int norm_sym_count;
299
300 /* Stack used to evaluate TIR/ETIR commands. */
301 struct stack_struct *stack;
302 int stackptr;
303
304 /* Content reading. */
305 asection *image_section; /* section for image_ptr */
306 file_ptr image_offset; /* Offset for image_ptr. */
95e34ef7
TG
307
308 struct module *modules; /* list of all compilation units */
309
8185f55c 310 /* The DST section. */
95e34ef7
TG
311 asection *dst_section;
312
313 unsigned int dst_ptr_offsets_count; /* # of offsets in following array */
314 unsigned int *dst_ptr_offsets; /* array of saved image_ptr offsets */
315
316 /* Shared library support */
317 bfd_vma symvva; /* relative virtual address of symbol vector */
318 unsigned int ident;
319 unsigned char matchctl;
320
321 /* Shared library index. This is used for input bfd while linking. */
322 unsigned int shr_index;
323
324 /* Used to place structures in the file. */
325 file_ptr file_pos;
326
327 /* Simply linked list of eisd. */
328 struct vms_internal_eisd_map *eisd_head;
329 struct vms_internal_eisd_map *eisd_tail;
330
331 /* Simply linked list of eisd for shared libraries. */
332 struct vms_internal_eisd_map *gbl_eisd_head;
333 struct vms_internal_eisd_map *gbl_eisd_tail;
334
335 /* linkage index counter used by conditional store commands */
25d41743 336 unsigned int vms_linkage_index;
95e34ef7
TG
337};
338
339#define PRIV2(abfd, name) \
340 (((struct vms_private_data_struct *)(abfd)->tdata.any)->name)
341#define PRIV(name) PRIV2(abfd,name)
342
343
344/* Used to keep extra VMS specific information for a given section.
345
346 reloc_size holds the size of the relocation stream, note this
347 is very different from the number of relocations as VMS relocations
348 are variable length.
349
350 reloc_stream is the actual stream of relocation entries. */
351
352struct vms_section_data_struct
353{
354 /* Maximnum number of entries in sec->relocation. */
355 unsigned reloc_max;
356
357 /* Corresponding eisd. Used only while generating executables. */
358 struct vms_internal_eisd_map *eisd;
359
360 /* PSC flags to be clear. */
361 flagword no_flags;
362
363 /* PSC flags to be set. */
364 flagword flags;
365};
366
367#define vms_section_data(sec) \
368 ((struct vms_section_data_struct *)sec->used_by_bfd)
369
370/* To be called from the debugger. */
0a9d414a 371struct vms_private_data_struct *bfd_vms_get_data (bfd *);
95e34ef7 372
0a9d414a 373static int vms_get_remaining_object_record (bfd *, unsigned int);
0a1b45a2
AM
374static bool _bfd_vms_slurp_object_records (bfd * abfd);
375static bool alpha_vms_add_fixup_lp (struct bfd_link_info *, bfd *, bfd *);
376static bool alpha_vms_add_fixup_ca (struct bfd_link_info *, bfd *, bfd *);
377static bool alpha_vms_add_fixup_qr (struct bfd_link_info *, bfd *, bfd *,
378 bfd_vma);
379static bool alpha_vms_add_fixup_lr (struct bfd_link_info *, unsigned int,
380 bfd_vma);
381static bool alpha_vms_add_lw_reloc (struct bfd_link_info *);
382static bool alpha_vms_add_qw_reloc (struct bfd_link_info *);
95e34ef7
TG
383
384struct vector_type
385{
386 unsigned int max_el;
387 unsigned int nbr_el;
388 void *els;
389};
390
391/* Number of elements in VEC. */
392
393#define VEC_COUNT(VEC) ((VEC).nbr_el)
394
395/* Get the address of the Nth element. */
396
397#define VEC_EL(VEC, TYPE, N) (((TYPE *)((VEC).els))[N])
398
07d6d2b8
AM
399#define VEC_INIT(VEC) \
400 do { \
401 (VEC).max_el = 0; \
402 (VEC).nbr_el = 0; \
403 (VEC).els = NULL; \
95e34ef7
TG
404 } while (0)
405
406/* Be sure there is room for a new element. */
407
96d3b80f 408static void *vector_grow1 (struct vector_type *vec, size_t elsz);
95e34ef7
TG
409
410/* Allocate room for a new element and return its address. */
411
07d6d2b8 412#define VEC_APPEND(VEC, TYPE) \
96d3b80f 413 ((TYPE *) vector_grow1 (&VEC, sizeof (TYPE)))
95e34ef7
TG
414
415struct alpha_vms_vma_ref
416{
417 bfd_vma vma; /* Vma in the output. */
418 bfd_vma ref; /* Reference in the input. */
419};
420
421struct alpha_vms_shlib_el
422{
423 bfd *abfd;
0a1b45a2 424 bool has_fixups;
95e34ef7
TG
425
426 struct vector_type lp; /* Vector of bfd_vma. */
427 struct vector_type ca; /* Vector of bfd_vma. */
428 struct vector_type qr; /* Vector of struct alpha_vms_vma_ref. */
429};
430
431/* Alpha VMS linker hash table. */
432
433struct alpha_vms_link_hash_table
434{
435 struct bfd_link_hash_table root;
436
cc643b88 437 /* Vector of shared libraries. */
95e34ef7
TG
438 struct vector_type shrlibs;
439
440 /* Fixup section. */
441 asection *fixup;
442
443 /* Base address. Used by fixups. */
444 bfd_vma base_addr;
445};
446
447#define alpha_vms_link_hash(INFO) \
448 ((struct alpha_vms_link_hash_table *)(INFO->hash))
449
450/* Alpha VMS linker hash table entry. */
451
452struct alpha_vms_link_hash_entry
453{
454 struct bfd_link_hash_entry root;
455
456 /* Pointer to the original vms symbol. */
457 struct vms_symbol_entry *sym;
458};
459\f
460/* Image reading. */
461
462/* Read & process EIHD record.
463 Return TRUE on success, FALSE on error. */
464
0a1b45a2 465static bool
95e34ef7 466_bfd_vms_slurp_eihd (bfd *abfd, unsigned int *eisd_offset,
07d6d2b8 467 unsigned int *eihs_offset)
95e34ef7
TG
468{
469 unsigned int imgtype, size;
470 bfd_vma symvva;
471 struct vms_eihd *eihd = (struct vms_eihd *)PRIV (recrd.rec);
472
473 vms_debug2 ((8, "_bfd_vms_slurp_eihd\n"));
474
ca4cf9b9
NC
475 /* PR 21813: Check for an undersized record. */
476 if (PRIV (recrd.buf_size) < sizeof (* eihd))
477 {
38f14ab8 478 _bfd_error_handler (_("corrupt EIHD record - size is too small"));
ca4cf9b9 479 bfd_set_error (bfd_error_bad_value);
0a1b45a2 480 return false;
ca4cf9b9
NC
481 }
482
95e34ef7
TG
483 size = bfd_getl32 (eihd->size);
484 imgtype = bfd_getl32 (eihd->imgtype);
485
486 if (imgtype == EIHD__K_EXE || imgtype == EIHD__K_LIM)
487 abfd->flags |= EXEC_P;
488
489 symvva = bfd_getl64 (eihd->symvva);
490 if (symvva != 0)
491 {
492 PRIV (symvva) = symvva;
493 abfd->flags |= DYNAMIC;
494 }
495
496 PRIV (ident) = bfd_getl32 (eihd->ident);
497 PRIV (matchctl) = eihd->matchctl;
498
499 *eisd_offset = bfd_getl32 (eihd->isdoff);
500 *eihs_offset = bfd_getl32 (eihd->symdbgoff);
501
502 vms_debug2 ((4, "EIHD size %d imgtype %d symvva 0x%lx eisd %d eihs %d\n",
07d6d2b8
AM
503 size, imgtype, (unsigned long)symvva,
504 *eisd_offset, *eihs_offset));
8ab484c2 505 (void) size;
95e34ef7 506
0a1b45a2 507 return true;
95e34ef7
TG
508}
509
510/* Read & process EISD record.
511 Return TRUE on success, FALSE on error. */
512
0a1b45a2 513static bool
95e34ef7
TG
514_bfd_vms_slurp_eisd (bfd *abfd, unsigned int offset)
515{
516 int section_count = 0;
517
518 vms_debug2 ((8, "_bfd_vms_slurp_eisd\n"));
519
520 while (1)
521 {
522 struct vms_eisd *eisd;
523 unsigned int rec_size;
524 unsigned int size;
ce9116fd 525 bfd_uint64_t vaddr;
95e34ef7
TG
526 unsigned int flags;
527 unsigned int vbn;
528 char *name = NULL;
529 asection *section;
530 flagword bfd_flags;
531
bf31e604
AM
532 /* PR 17512: file: 3d9e9fe9. */
533 if (offset > PRIV (recrd.rec_size)
534 || (PRIV (recrd.rec_size) - offset
535 < offsetof (struct vms_eisd, eisdsize) + 4))
0a1b45a2 536 return false;
bf31e604 537 eisd = (struct vms_eisd *) (PRIV (recrd.rec) + offset);
95e34ef7 538 rec_size = bfd_getl32 (eisd->eisdsize);
95e34ef7 539 if (rec_size == 0)
07d6d2b8 540 break;
95e34ef7
TG
541
542 /* Skip to next block if pad. */
543 if (rec_size == 0xffffffff)
07d6d2b8
AM
544 {
545 offset = (offset + VMS_BLOCK_SIZE) & ~(VMS_BLOCK_SIZE - 1);
546 continue;
547 }
7adc0a81
NC
548
549 /* Make sure that there is enough data present in the record. */
bf31e604 550 if (rec_size < offsetof (struct vms_eisd, type) + 1)
0a1b45a2 551 return false;
7adc0a81 552 /* Make sure that the record is not too big either. */
bf31e604 553 if (rec_size > PRIV (recrd.rec_size) - offset)
0a1b45a2 554 return false;
7adc0a81
NC
555
556 offset += rec_size;
95e34ef7
TG
557
558 size = bfd_getl32 (eisd->secsize);
559 vaddr = bfd_getl64 (eisd->virt_addr);
560 flags = bfd_getl32 (eisd->flags);
561 vbn = bfd_getl32 (eisd->vbn);
562
563 vms_debug2 ((4, "EISD at 0x%x size 0x%x addr 0x%lx flags 0x%x blk %d\n",
07d6d2b8 564 offset, size, (unsigned long)vaddr, flags, vbn));
95e34ef7
TG
565
566 /* VMS combines psects from .obj files into isects in the .exe. This
567 process doesn't preserve enough information to reliably determine
568 what's in each section without examining the data. This is
569 especially true of DWARF debug sections. */
570 bfd_flags = SEC_ALLOC;
c068d5be 571 if (vbn != 0)
07d6d2b8 572 bfd_flags |= SEC_HAS_CONTENTS | SEC_LOAD;
95e34ef7
TG
573
574 if (flags & EISD__M_EXE)
c068d5be 575 bfd_flags |= SEC_CODE;
95e34ef7
TG
576
577 if (flags & EISD__M_NONSHRADR)
c068d5be 578 bfd_flags |= SEC_DATA;
95e34ef7
TG
579
580 if (!(flags & EISD__M_WRT))
581 bfd_flags |= SEC_READONLY;
582
583 if (flags & EISD__M_DZRO)
584 bfd_flags |= SEC_DATA;
585
586 if (flags & EISD__M_FIXUPVEC)
c068d5be 587 bfd_flags |= SEC_DATA;
95e34ef7
TG
588
589 if (flags & EISD__M_CRF)
c068d5be 590 bfd_flags |= SEC_DATA;
95e34ef7
TG
591
592 if (flags & EISD__M_GBL)
593 {
bf31e604 594 if (rec_size <= offsetof (struct vms_eisd, gblnam))
0a1b45a2 595 return false;
7adc0a81 596 else if (rec_size < sizeof (struct vms_eisd))
37d2e9c7 597 name = _bfd_vms_save_counted_string (abfd, eisd->gblnam,
7adc0a81
NC
598 rec_size - offsetof (struct vms_eisd, gblnam));
599 else
37d2e9c7
AM
600 name = _bfd_vms_save_counted_string (abfd, eisd->gblnam,
601 EISD__K_GBLNAMLEN);
bf31e604 602 if (name == NULL || name[0] == 0)
0a1b45a2 603 return false;
95e34ef7
TG
604 bfd_flags |= SEC_COFF_SHARED_LIBRARY;
605 bfd_flags &= ~(SEC_ALLOC | SEC_LOAD);
606 }
607 else if (flags & EISD__M_FIXUPVEC)
07d6d2b8 608 name = "$FIXUPVEC$";
95e34ef7 609 else if (eisd->type == EISD__K_USRSTACK)
07d6d2b8 610 name = "$STACK$";
95e34ef7
TG
611 else
612 {
07d6d2b8 613 const char *pfx;
95e34ef7 614
37d2e9c7
AM
615 name = (char *) bfd_alloc (abfd, 32);
616 if (name == NULL)
0a1b45a2 617 return false;
07d6d2b8
AM
618 if (flags & EISD__M_DZRO)
619 pfx = "BSS";
620 else if (flags & EISD__M_EXE)
621 pfx = "CODE";
622 else if (!(flags & EISD__M_WRT))
623 pfx = "RO";
624 else
625 pfx = "LOCAL";
626 BFD_ASSERT (section_count < 999);
95e34ef7
TG
627 sprintf (name, "$%s_%03d$", pfx, section_count++);
628 }
629
630 section = bfd_make_section (abfd, name);
631
632 if (!section)
0a1b45a2 633 return false;
95e34ef7
TG
634
635 section->filepos = vbn ? VMS_BLOCK_SIZE * (vbn - 1) : 0;
636 section->size = size;
637 section->vma = vaddr;
638
fd361982 639 if (!bfd_set_section_flags (section, bfd_flags))
0a1b45a2 640 return false;
95e34ef7
TG
641 }
642
0a1b45a2 643 return true;
95e34ef7
TG
644}
645
646/* Read & process EIHS record.
647 Return TRUE on success, FALSE on error. */
648
0a1b45a2 649static bool
95e34ef7
TG
650_bfd_vms_slurp_eihs (bfd *abfd, unsigned int offset)
651{
652 unsigned char *p = PRIV (recrd.rec) + offset;
80053e46
NC
653 unsigned int gstvbn;
654 unsigned int gstsize ATTRIBUTE_UNUSED;
655 unsigned int dstvbn;
656 unsigned int dstsize;
657 unsigned int dmtvbn;
658 unsigned int dmtbytes;
95e34ef7
TG
659 asection *section;
660
80053e46
NC
661 /* PR 21611: Check that offset is valid. */
662 if (offset > PRIV (recrd.rec_size) - (EIHS__L_DMTBYTES + 4))
663 {
38f14ab8
AM
664 _bfd_error_handler (_("unable to read EIHS record at offset %#x"),
665 offset);
80053e46 666 bfd_set_error (bfd_error_file_truncated);
0a1b45a2 667 return false;
80053e46
NC
668 }
669
670 gstvbn = bfd_getl32 (p + EIHS__L_GSTVBN);
671 gstsize = bfd_getl32 (p + EIHS__L_GSTSIZE);
672 dstvbn = bfd_getl32 (p + EIHS__L_DSTVBN);
673 dstsize = bfd_getl32 (p + EIHS__L_DSTSIZE);
674 dmtvbn = bfd_getl32 (p + EIHS__L_DMTVBN);
675 dmtbytes = bfd_getl32 (p + EIHS__L_DMTBYTES);
676
95e34ef7
TG
677#if VMS_DEBUG
678 vms_debug (8, "_bfd_vms_slurp_ihs\n");
679 vms_debug (4, "EIHS record gstvbn %d gstsize %d dstvbn %d dstsize %d dmtvbn %d dmtbytes %d\n",
680 gstvbn, gstsize, dstvbn, dstsize, dmtvbn, dmtbytes);
681#endif
682
683 if (dstvbn)
684 {
685 flagword bfd_flags = SEC_HAS_CONTENTS | SEC_DEBUGGING;
686
687 section = bfd_make_section (abfd, "$DST$");
688 if (!section)
0a1b45a2 689 return false;
95e34ef7
TG
690
691 section->size = dstsize;
692 section->filepos = VMS_BLOCK_SIZE * (dstvbn - 1);
693
fd361982 694 if (!bfd_set_section_flags (section, bfd_flags))
0a1b45a2 695 return false;
95e34ef7
TG
696
697 PRIV (dst_section) = section;
698 abfd->flags |= (HAS_DEBUG | HAS_LINENO);
699 }
700
701 if (dmtvbn)
702 {
703 flagword bfd_flags = SEC_HAS_CONTENTS | SEC_DEBUGGING;
704
705 section = bfd_make_section (abfd, "$DMT$");
706 if (!section)
0a1b45a2 707 return false;
95e34ef7
TG
708
709 section->size = dmtbytes;
710 section->filepos = VMS_BLOCK_SIZE * (dmtvbn - 1);
711
fd361982 712 if (!bfd_set_section_flags (section, bfd_flags))
0a1b45a2 713 return false;
95e34ef7
TG
714 }
715
716 if (gstvbn)
717 {
95e34ef7
TG
718 if (bfd_seek (abfd, VMS_BLOCK_SIZE * (gstvbn - 1), SEEK_SET))
719 {
720 bfd_set_error (bfd_error_file_truncated);
0a1b45a2 721 return false;
95e34ef7
TG
722 }
723
535b785f 724 if (!_bfd_vms_slurp_object_records (abfd))
0a1b45a2 725 return false;
95e34ef7 726
95e34ef7
TG
727 abfd->flags |= HAS_SYMS;
728 }
729
0a1b45a2 730 return true;
95e34ef7
TG
731}
732\f
733/* Object file reading. */
734
735/* Object file input functions. */
736
737/* Get next record from object file to vms_buf.
738 Set PRIV(buf_size) and return it
739
740 This is a little tricky since it should be portable.
741
742 The openVMS object file has 'variable length' which means that
743 read() returns data in chunks of (hopefully) correct and expected
744 size. The linker (and other tools on VMS) depend on that. Unix
745 doesn't know about 'formatted' files, so reading and writing such
746 an object file in a Unix environment is not trivial.
747
748 With the tool 'file' (available on all VMS FTP sites), one
749 can view and change the attributes of a file. Changing from
750 'variable length' to 'fixed length, 512 bytes' reveals the
751 record size at the first 2 bytes of every record. The same
752 may happen during the transfer of object files from VMS to Unix,
753 at least with UCX, the DEC implementation of TCP/IP.
754
755 The VMS format repeats the size at bytes 2 & 3 of every record.
756
757 On the first call (file_format == FF_UNKNOWN) we check if
758 the first and the third byte pair (!) of the record match.
759 If they do it's an object file in an Unix environment or with
760 wrong attributes (FF_FOREIGN), else we should be in a VMS
761 environment where read() returns the record size (FF_NATIVE).
762
763 Reading is always done in 2 steps:
764 1. first just the record header is read and the size extracted,
765 2. then the read buffer is adjusted and the remaining bytes are
766 read in.
767
768 All file I/O is done on even file positions. */
769
770#define VMS_OBJECT_ADJUSTMENT 2
771
772static void
773maybe_adjust_record_pointer_for_object (bfd *abfd)
774{
775 /* Set the file format once for all on the first invocation. */
776 if (PRIV (recrd.file_format) == FF_UNKNOWN)
777 {
778 if (PRIV (recrd.rec)[0] == PRIV (recrd.rec)[4]
779 && PRIV (recrd.rec)[1] == PRIV (recrd.rec)[5])
780 PRIV (recrd.file_format) = FF_FOREIGN;
781 else
782 PRIV (recrd.file_format) = FF_NATIVE;
783 }
784
785 /* The adjustment is needed only in an Unix environment. */
786 if (PRIV (recrd.file_format) == FF_FOREIGN)
787 PRIV (recrd.rec) += VMS_OBJECT_ADJUSTMENT;
788}
789
790/* Implement step #1 of the object record reading procedure.
791 Return the record type or -1 on failure. */
792
793static int
794_bfd_vms_get_object_record (bfd *abfd)
795{
ddfb684a 796 unsigned int test_len = 6;
95e34ef7 797 int type;
95e34ef7
TG
798
799 vms_debug2 ((8, "_bfd_vms_get_obj_record\n"));
800
ddfb684a 801 /* Skip alignment byte if the current position is odd. */
af47dcbf 802 if (PRIV (recrd.file_format) == FF_FOREIGN && (bfd_tell (abfd) & 1))
95e34ef7
TG
803 {
804 if (bfd_bread (PRIV (recrd.buf), 1, abfd) != 1)
07d6d2b8
AM
805 {
806 bfd_set_error (bfd_error_file_truncated);
807 return -1;
808 }
95e34ef7
TG
809 }
810
811 /* Read the record header */
ddfb684a 812 if (bfd_bread (PRIV (recrd.buf), test_len, abfd) != test_len)
95e34ef7
TG
813 {
814 bfd_set_error (bfd_error_file_truncated);
815 return -1;
816 }
817
818 /* Reset the record pointer. */
819 PRIV (recrd.rec) = PRIV (recrd.buf);
820 maybe_adjust_record_pointer_for_object (abfd);
821
822 if (vms_get_remaining_object_record (abfd, test_len) <= 0)
823 return -1;
824
825 type = bfd_getl16 (PRIV (recrd.rec));
826
827 vms_debug2 ((8, "_bfd_vms_get_obj_record: rec %p, size %d, type %d\n",
07d6d2b8 828 PRIV (recrd.rec), PRIV (recrd.rec_size), type));
95e34ef7
TG
829
830 return type;
831}
832
833/* Implement step #2 of the object record reading procedure.
834 Return the size of the record or 0 on failure. */
835
836static int
0a9d414a 837vms_get_remaining_object_record (bfd *abfd, unsigned int read_so_far)
95e34ef7
TG
838{
839 unsigned int to_read;
840
841 vms_debug2 ((8, "vms_get_remaining_obj_record\n"));
842
843 /* Extract record size. */
844 PRIV (recrd.rec_size) = bfd_getl16 (PRIV (recrd.rec) + 2);
845
083faca9 846 if (PRIV (recrd.rec_size) == 0)
95e34ef7
TG
847 {
848 bfd_set_error (bfd_error_file_truncated);
849 return 0;
850 }
851
852 /* That's what the linker manual says. */
853 if (PRIV (recrd.rec_size) > EOBJ__C_MAXRECSIZ)
854 {
855 bfd_set_error (bfd_error_file_truncated);
856 return 0;
857 }
858
859 /* Take into account object adjustment. */
860 to_read = PRIV (recrd.rec_size);
861 if (PRIV (recrd.file_format) == FF_FOREIGN)
862 to_read += VMS_OBJECT_ADJUSTMENT;
863
864 /* Adjust the buffer. */
865 if (to_read > PRIV (recrd.buf_size))
866 {
867 PRIV (recrd.buf)
9cb56943 868 = (unsigned char *) bfd_realloc_or_free (PRIV (recrd.buf), to_read);
95e34ef7 869 if (PRIV (recrd.buf) == NULL)
07d6d2b8 870 return 0;
95e34ef7
TG
871 PRIV (recrd.buf_size) = to_read;
872 }
0a9d414a
NC
873 /* PR 17512: file: 025-1974-0.004. */
874 else if (to_read <= read_so_far)
875 return 0;
1b786873 876
95e34ef7
TG
877 /* Read the remaining record. */
878 to_read -= read_so_far;
879
880 vms_debug2 ((8, "vms_get_remaining_obj_record: to_read %d\n", to_read));
881
882 if (bfd_bread (PRIV (recrd.buf) + read_so_far, to_read, abfd) != to_read)
883 {
884 bfd_set_error (bfd_error_file_truncated);
885 return 0;
886 }
887
888 /* Reset the record pointer. */
889 PRIV (recrd.rec) = PRIV (recrd.buf);
890 maybe_adjust_record_pointer_for_object (abfd);
891
892 vms_debug2 ((8, "vms_get_remaining_obj_record: size %d\n",
07d6d2b8 893 PRIV (recrd.rec_size)));
95e34ef7
TG
894
895 return PRIV (recrd.rec_size);
896}
897
898/* Read and process emh record.
899 Return TRUE on success, FALSE on error. */
900
0a1b45a2 901static bool
95e34ef7
TG
902_bfd_vms_slurp_ehdr (bfd *abfd)
903{
904 unsigned char *ptr;
905 unsigned char *vms_rec;
4e5cb37e 906 unsigned char *end;
95e34ef7
TG
907 int subtype;
908
909 vms_rec = PRIV (recrd.rec);
4e5cb37e 910 /* PR 17512: file: 62736583. */
8bdf0be1 911 end = PRIV (recrd.buf) + PRIV (recrd.buf_size);
95e34ef7
TG
912
913 vms_debug2 ((2, "HDR/EMH\n"));
914
915 subtype = bfd_getl16 (vms_rec + 4);
916
917 vms_debug2 ((3, "subtype %d\n", subtype));
918
919 switch (subtype)
920 {
921 case EMH__C_MHD:
922 /* Module header. */
4e5cb37e
NC
923 if (vms_rec + 21 >= end)
924 goto fail;
95e34ef7
TG
925 PRIV (hdr_data).hdr_b_strlvl = vms_rec[6];
926 PRIV (hdr_data).hdr_l_arch1 = bfd_getl32 (vms_rec + 8);
927 PRIV (hdr_data).hdr_l_arch2 = bfd_getl32 (vms_rec + 12);
928 PRIV (hdr_data).hdr_l_recsiz = bfd_getl32 (vms_rec + 16);
4e5cb37e
NC
929 if ((vms_rec + 20 + vms_rec[20] + 1) >= end)
930 goto fail;
37d2e9c7
AM
931 PRIV (hdr_data).hdr_t_name
932 = _bfd_vms_save_counted_string (abfd, vms_rec + 20, vms_rec[20]);
95e34ef7 933 ptr = vms_rec + 20 + vms_rec[20] + 1;
4e5cb37e
NC
934 if ((ptr + *ptr + 1) >= end)
935 goto fail;
37d2e9c7
AM
936 PRIV (hdr_data).hdr_t_version
937 = _bfd_vms_save_counted_string (abfd, ptr, *ptr);
95e34ef7 938 ptr += *ptr + 1;
4e5cb37e
NC
939 if (ptr + 17 >= end)
940 goto fail;
37d2e9c7
AM
941 PRIV (hdr_data).hdr_t_date
942 = _bfd_vms_save_sized_string (abfd, ptr, 17);
95e34ef7
TG
943 break;
944
945 case EMH__C_LNM:
4e5cb37e
NC
946 if (vms_rec + PRIV (recrd.rec_size - 6) > end)
947 goto fail;
37d2e9c7
AM
948 PRIV (hdr_data).hdr_c_lnm
949 = _bfd_vms_save_sized_string (abfd, vms_rec, PRIV (recrd.rec_size - 6));
95e34ef7
TG
950 break;
951
952 case EMH__C_SRC:
4e5cb37e
NC
953 if (vms_rec + PRIV (recrd.rec_size - 6) > end)
954 goto fail;
37d2e9c7
AM
955 PRIV (hdr_data).hdr_c_src
956 = _bfd_vms_save_sized_string (abfd, vms_rec, PRIV (recrd.rec_size - 6));
95e34ef7
TG
957 break;
958
959 case EMH__C_TTL:
4e5cb37e
NC
960 if (vms_rec + PRIV (recrd.rec_size - 6) > end)
961 goto fail;
37d2e9c7
AM
962 PRIV (hdr_data).hdr_c_ttl
963 = _bfd_vms_save_sized_string (abfd, vms_rec, PRIV (recrd.rec_size - 6));
95e34ef7
TG
964 break;
965
966 case EMH__C_CPR:
967 case EMH__C_MTC:
968 case EMH__C_GTX:
969 break;
970
971 default:
4e5cb37e 972 fail:
95e34ef7 973 bfd_set_error (bfd_error_wrong_format);
0a1b45a2 974 return false;
95e34ef7
TG
975 }
976
0a1b45a2 977 return true;
95e34ef7
TG
978}
979
980/* Typical sections for evax object files. */
981
982#define EVAX_ABS_NAME "$ABS$"
983#define EVAX_CODE_NAME "$CODE$"
984#define EVAX_LINK_NAME "$LINK$"
985#define EVAX_DATA_NAME "$DATA$"
986#define EVAX_BSS_NAME "$BSS$"
987#define EVAX_READONLYADDR_NAME "$READONLY_ADDR$"
988#define EVAX_READONLY_NAME "$READONLY$"
989#define EVAX_LITERAL_NAME "$LITERAL$"
990#define EVAX_LITERALS_NAME "$LITERALS"
991#define EVAX_COMMON_NAME "$COMMON$"
992#define EVAX_LOCAL_NAME "$LOCAL$"
993
994struct sec_flags_struct
995{
996 const char *name; /* Name of section. */
997 int vflags_always;
998 flagword flags_always; /* Flags we set always. */
999 int vflags_hassize;
1000 flagword flags_hassize; /* Flags we set if the section has a size > 0. */
1001};
1002
1003/* These flags are deccrtl/vaxcrtl (openVMS 6.2 Alpha) compatible. */
1004
81bb31c0 1005static const struct sec_flags_struct evax_section_flags[] =
95e34ef7
TG
1006 {
1007 { EVAX_ABS_NAME,
d833fa0d
TG
1008 EGPS__V_SHR,
1009 0,
1010 EGPS__V_SHR,
1011 0 },
95e34ef7 1012 { EVAX_CODE_NAME,
d833fa0d 1013 EGPS__V_PIC | EGPS__V_REL | EGPS__V_SHR | EGPS__V_EXE,
cf6b8767 1014 SEC_CODE | SEC_READONLY,
d833fa0d 1015 EGPS__V_PIC | EGPS__V_REL | EGPS__V_SHR | EGPS__V_EXE,
cf6b8767 1016 SEC_CODE | SEC_READONLY | SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD },
95e34ef7 1017 { EVAX_LITERAL_NAME,
d833fa0d
TG
1018 EGPS__V_PIC | EGPS__V_REL | EGPS__V_SHR | EGPS__V_RD | EGPS__V_NOMOD,
1019 SEC_DATA | SEC_READONLY,
1020 EGPS__V_PIC | EGPS__V_REL | EGPS__V_SHR | EGPS__V_RD,
cf6b8767 1021 SEC_DATA | SEC_READONLY | SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD },
95e34ef7 1022 { EVAX_LINK_NAME,
d833fa0d
TG
1023 EGPS__V_REL | EGPS__V_RD,
1024 SEC_DATA | SEC_READONLY,
1025 EGPS__V_REL | EGPS__V_RD,
cf6b8767 1026 SEC_DATA | SEC_READONLY | SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD },
95e34ef7 1027 { EVAX_DATA_NAME,
d833fa0d
TG
1028 EGPS__V_REL | EGPS__V_RD | EGPS__V_WRT | EGPS__V_NOMOD,
1029 SEC_DATA,
1030 EGPS__V_REL | EGPS__V_RD | EGPS__V_WRT,
1031 SEC_DATA | SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD },
95e34ef7 1032 { EVAX_BSS_NAME,
d833fa0d
TG
1033 EGPS__V_REL | EGPS__V_RD | EGPS__V_WRT | EGPS__V_NOMOD,
1034 SEC_NO_FLAGS,
1035 EGPS__V_REL | EGPS__V_RD | EGPS__V_WRT | EGPS__V_NOMOD,
1036 SEC_ALLOC },
95e34ef7 1037 { EVAX_READONLYADDR_NAME,
d833fa0d
TG
1038 EGPS__V_PIC | EGPS__V_REL | EGPS__V_RD,
1039 SEC_DATA | SEC_READONLY,
1040 EGPS__V_PIC | EGPS__V_REL | EGPS__V_RD,
cf6b8767 1041 SEC_DATA | SEC_READONLY | SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD },
95e34ef7 1042 { EVAX_READONLY_NAME,
d833fa0d
TG
1043 EGPS__V_PIC | EGPS__V_REL | EGPS__V_SHR | EGPS__V_RD | EGPS__V_NOMOD,
1044 SEC_DATA | SEC_READONLY,
1045 EGPS__V_PIC | EGPS__V_REL | EGPS__V_SHR | EGPS__V_RD,
cf6b8767 1046 SEC_DATA | SEC_READONLY | SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD },
95e34ef7 1047 { EVAX_LOCAL_NAME,
d833fa0d
TG
1048 EGPS__V_REL | EGPS__V_RD | EGPS__V_WRT,
1049 SEC_DATA,
1050 EGPS__V_REL | EGPS__V_RD | EGPS__V_WRT,
1051 SEC_DATA | SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD },
95e34ef7 1052 { EVAX_LITERALS_NAME,
d833fa0d
TG
1053 EGPS__V_PIC | EGPS__V_OVR,
1054 SEC_DATA | SEC_READONLY,
1055 EGPS__V_PIC | EGPS__V_OVR,
cf6b8767 1056 SEC_DATA | SEC_READONLY | SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD },
95e34ef7 1057 { NULL,
d833fa0d
TG
1058 EGPS__V_REL | EGPS__V_RD | EGPS__V_WRT,
1059 SEC_DATA,
1060 EGPS__V_REL | EGPS__V_RD | EGPS__V_WRT,
8185f55c 1061 SEC_DATA | SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD }
95e34ef7
TG
1062 };
1063
81bb31c0 1064/* Retrieve BFD section flags by name and size. */
95e34ef7
TG
1065
1066static flagword
81bb31c0
TG
1067vms_secflag_by_name (const struct sec_flags_struct *section_flags,
1068 const char *name,
95e34ef7
TG
1069 int hassize)
1070{
1071 int i = 0;
1072
1073 while (section_flags[i].name != NULL)
1074 {
1075 if (strcmp (name, section_flags[i].name) == 0)
07d6d2b8 1076 {
95e34ef7
TG
1077 if (hassize)
1078 return section_flags[i].flags_hassize;
1079 else
1080 return section_flags[i].flags_always;
1081 }
1082 i++;
1083 }
1084 if (hassize)
1085 return section_flags[i].flags_hassize;
1086 return section_flags[i].flags_always;
1087}
1088
81bb31c0 1089/* Retrieve VMS section flags by name and size. */
95e34ef7
TG
1090
1091static flagword
81bb31c0
TG
1092vms_esecflag_by_name (const struct sec_flags_struct *section_flags,
1093 const char *name,
07d6d2b8 1094 int hassize)
95e34ef7
TG
1095{
1096 int i = 0;
1097
1098 while (section_flags[i].name != NULL)
1099 {
1100 if (strcmp (name, section_flags[i].name) == 0)
1101 {
1102 if (hassize)
1103 return section_flags[i].vflags_hassize;
1104 else
1105 return section_flags[i].vflags_always;
1106 }
1107 i++;
1108 }
1109 if (hassize)
1110 return section_flags[i].vflags_hassize;
1111 return section_flags[i].vflags_always;
1112}
1113
ce76e55c
TG
1114/* Add SYM to the symbol table of ABFD.
1115 Return FALSE in case of error. */
95e34ef7 1116
0a1b45a2 1117static bool
ce76e55c 1118add_symbol_entry (bfd *abfd, struct vms_symbol_entry *sym)
95e34ef7 1119{
95e34ef7
TG
1120 if (PRIV (gsd_sym_count) >= PRIV (max_sym_count))
1121 {
1122 if (PRIV (max_sym_count) == 0)
07d6d2b8
AM
1123 {
1124 PRIV (max_sym_count) = 128;
1125 PRIV (syms) = bfd_malloc
1126 (PRIV (max_sym_count) * sizeof (struct vms_symbol_entry *));
1127 }
95e34ef7 1128 else
07d6d2b8
AM
1129 {
1130 PRIV (max_sym_count) *= 2;
9cb56943 1131 PRIV (syms) = bfd_realloc_or_free
07d6d2b8
AM
1132 (PRIV (syms),
1133 (PRIV (max_sym_count) * sizeof (struct vms_symbol_entry *)));
1134 }
95e34ef7 1135 if (PRIV (syms) == NULL)
0a1b45a2 1136 return false;
95e34ef7
TG
1137 }
1138
ce76e55c 1139 PRIV (syms)[PRIV (gsd_sym_count)++] = sym;
0a1b45a2 1140 return true;
ce76e55c
TG
1141}
1142
1143/* Create a symbol whose name is ASCIC and add it to ABFD.
1144 Return NULL in case of error. */
1145
1146static struct vms_symbol_entry *
2c0e48e5 1147add_symbol (bfd *abfd, const unsigned char *ascic, unsigned int max)
ce76e55c
TG
1148{
1149 struct vms_symbol_entry *entry;
2c0e48e5 1150 unsigned int len;
ce76e55c
TG
1151
1152 len = *ascic++;
2c0e48e5
AM
1153 max -= 1;
1154 if (len > max)
1155 {
1156 _bfd_error_handler (_("record is too small for symbol name length"));
1157 bfd_set_error (bfd_error_bad_value);
1158 return NULL;
1159 }
1160
ce76e55c
TG
1161 entry = (struct vms_symbol_entry *)bfd_zalloc (abfd, sizeof (*entry) + len);
1162 if (entry == NULL)
1163 return NULL;
1164 entry->namelen = len;
1165 memcpy (entry->name, ascic, len);
1166 entry->name[len] = 0;
1167 entry->owner = abfd;
1168
1169 if (!add_symbol_entry (abfd, entry))
1170 return NULL;
95e34ef7
TG
1171 return entry;
1172}
1173
1174/* Read and process EGSD. Return FALSE on failure. */
1175
0a1b45a2 1176static bool
5fe88cfb 1177_bfd_vms_slurp_egsd (bfd *abfd)
95e34ef7 1178{
72e84f96
NC
1179 int gsd_type;
1180 unsigned int gsd_size;
95e34ef7 1181 unsigned char *vms_rec;
401e101e 1182 bfd_vma base_addr;
bf31e604 1183 long psindx;
95e34ef7
TG
1184
1185 vms_debug2 ((2, "EGSD\n"));
1186
3de58d95
NC
1187 if (PRIV (recrd.rec_size) < 8)
1188 {
38f14ab8 1189 _bfd_error_handler (_("corrupt EGSD record: its size (%#x) is too small"),
3de58d95
NC
1190 PRIV (recrd.rec_size));
1191 bfd_set_error (bfd_error_bad_value);
0a1b45a2 1192 return false;
3de58d95 1193 }
07d6d2b8 1194
95e34ef7
TG
1195 PRIV (recrd.rec) += 8; /* Skip type, size, align pad. */
1196 PRIV (recrd.rec_size) -= 8;
1197
1198 /* Calculate base address for each section. */
401e101e 1199 base_addr = 0;
95e34ef7 1200
72e84f96 1201 while (PRIV (recrd.rec_size) > 4)
95e34ef7
TG
1202 {
1203 vms_rec = PRIV (recrd.rec);
1204
1205 gsd_type = bfd_getl16 (vms_rec);
1206 gsd_size = bfd_getl16 (vms_rec + 2);
1207
1208 vms_debug2 ((3, "egsd_type %d\n", gsd_type));
1209
72e84f96
NC
1210 /* PR 21615: Check for size overflow. */
1211 if (PRIV (recrd.rec_size) < gsd_size)
1212 {
bf31e604
AM
1213 _bfd_error_handler (_("corrupt EGSD record type %d: size (%#x) "
1214 "is larger than remaining space (%#x)"),
1215 gsd_type, gsd_size, PRIV (recrd.rec_size));
7adc0a81 1216 bfd_set_error (bfd_error_bad_value);
0a1b45a2 1217 return false;
7adc0a81
NC
1218 }
1219
b50ef514
AM
1220 if (gsd_size < 4)
1221 {
1222 too_small:
1223 _bfd_error_handler (_("corrupt EGSD record type %d: size (%#x) "
1224 "is too small"),
1225 gsd_type, gsd_size);
1226 bfd_set_error (bfd_error_bad_value);
0a1b45a2 1227 return false;
b50ef514
AM
1228 }
1229
95e34ef7
TG
1230 switch (gsd_type)
1231 {
1232 case EGSD__C_PSC:
07d6d2b8 1233 /* Program section definition. */
95e34ef7 1234 {
bf31e604 1235 struct vms_egps *egps = (struct vms_egps *) vms_rec;
07d6d2b8
AM
1236 flagword new_flags, vms_flags;
1237 asection *section;
5fe88cfb 1238
bf31e604 1239 if (offsetof (struct vms_egps, flags) + 2 > gsd_size)
b50ef514 1240 goto too_small;
8185f55c 1241 vms_flags = bfd_getl16 (egps->flags);
21e003e8 1242
07d6d2b8
AM
1243 if ((vms_flags & EGPS__V_REL) == 0)
1244 {
1245 /* Use the global absolute section for all
1246 absolute sections. */
1247 section = bfd_abs_section_ptr;
1248 }
1249 else
1250 {
1251 char *name;
401e101e 1252 bfd_vma align_addr;
bf31e604 1253 size_t left;
21e003e8 1254
bf31e604
AM
1255 if (offsetof (struct vms_egps, namlng) >= gsd_size)
1256 goto too_small;
1257 left = gsd_size - offsetof (struct vms_egps, namlng);
1258 name = _bfd_vms_save_counted_string (abfd, &egps->namlng, left);
1259 if (name == NULL || name[0] == 0)
0a1b45a2 1260 return false;
21e003e8 1261
07d6d2b8
AM
1262 section = bfd_make_section (abfd, name);
1263 if (!section)
0a1b45a2 1264 return false;
07d6d2b8
AM
1265
1266 section->filepos = 0;
1267 section->size = bfd_getl32 (egps->alloc);
401e101e 1268 section->alignment_power = egps->align & 31;
07d6d2b8
AM
1269
1270 vms_section_data (section)->flags = vms_flags;
1271 vms_section_data (section)->no_flags = 0;
1272
37d2e9c7
AM
1273 new_flags = vms_secflag_by_name (evax_section_flags,
1274 section->name,
07d6d2b8
AM
1275 section->size > 0);
1276 if (section->size > 0)
1277 new_flags |= SEC_LOAD;
1278 if (!(vms_flags & EGPS__V_NOMOD) && section->size > 0)
1279 {
1280 /* Set RELOC and HAS_CONTENTS if the section is not
1281 demand-zero and not empty. */
1282 new_flags |= SEC_HAS_CONTENTS;
1283 if (vms_flags & EGPS__V_REL)
1284 new_flags |= SEC_RELOC;
1285 }
1286 if (vms_flags & EGPS__V_EXE)
1287 {
1288 /* Set CODE if section is executable. */
1289 new_flags |= SEC_CODE;
1290 new_flags &= ~SEC_DATA;
1291 }
fd361982 1292 if (!bfd_set_section_flags (section, new_flags))
0a1b45a2 1293 return false;
07d6d2b8
AM
1294
1295 /* Give a non-overlapping vma to non absolute sections. */
401e101e
AM
1296 align_addr = (bfd_vma) 1 << section->alignment_power;
1297 base_addr = (base_addr + align_addr - 1) & -align_addr;
1298 section->vma = base_addr;
07d6d2b8
AM
1299 base_addr += section->size;
1300 }
1301
1302 /* Append it to the section array. */
1303 if (PRIV (section_count) >= PRIV (section_max))
1304 {
1305 if (PRIV (section_max) == 0)
1306 PRIV (section_max) = 16;
1307 else
1308 PRIV (section_max) *= 2;
1309 PRIV (sections) = bfd_realloc_or_free
1310 (PRIV (sections), PRIV (section_max) * sizeof (asection *));
1311 if (PRIV (sections) == NULL)
0a1b45a2 1312 return false;
07d6d2b8
AM
1313 }
1314
1315 PRIV (sections)[PRIV (section_count)] = section;
1316 PRIV (section_count)++;
95e34ef7
TG
1317 }
1318 break;
1319
1320 case EGSD__C_SYM:
1321 {
2c0e48e5 1322 unsigned int nameoff;
07d6d2b8
AM
1323 struct vms_symbol_entry *entry;
1324 struct vms_egsy *egsy = (struct vms_egsy *) vms_rec;
1325 flagword old_flags;
95e34ef7 1326
bf31e604
AM
1327 if (offsetof (struct vms_egsy, flags) + 2 > gsd_size)
1328 goto too_small;
95e34ef7
TG
1329 old_flags = bfd_getl16 (egsy->flags);
1330 if (old_flags & EGSY__V_DEF)
07d6d2b8
AM
1331 nameoff = ESDF__B_NAMLNG;
1332 else
1333 nameoff = ESRF__B_NAMLNG;
95e34ef7 1334
2c0e48e5 1335 if (nameoff >= gsd_size)
bf31e604 1336 goto too_small;
2c0e48e5 1337 entry = add_symbol (abfd, vms_rec + nameoff, gsd_size - nameoff);
07d6d2b8 1338 if (entry == NULL)
0a1b45a2 1339 return false;
95e34ef7 1340
07d6d2b8
AM
1341 /* Allow only duplicate reference. */
1342 if ((entry->flags & EGSY__V_DEF) && (old_flags & EGSY__V_DEF))
1343 abort ();
95e34ef7 1344
07d6d2b8
AM
1345 if (entry->typ == 0)
1346 {
1347 entry->typ = gsd_type;
1348 entry->data_type = egsy->datyp;
1349 entry->flags = old_flags;
1350 }
95e34ef7
TG
1351
1352 if (old_flags & EGSY__V_DEF)
07d6d2b8 1353 {
bf31e604 1354 struct vms_esdf *esdf = (struct vms_esdf *) vms_rec;
95e34ef7
TG
1355
1356 entry->value = bfd_getl64 (esdf->value);
cb06d03a 1357 if (PRIV (sections) == NULL)
0a1b45a2 1358 return false;
ca4cf9b9
NC
1359
1360 psindx = bfd_getl32 (esdf->psindx);
1361 /* PR 21813: Check for an out of range index. */
1362 if (psindx < 0 || psindx >= (int) PRIV (section_count))
1363 {
bf31e604
AM
1364 bad_psindx:
1365 _bfd_error_handler (_("corrupt EGSD record: its psindx "
1366 "field is too big (%#lx)"),
ca4cf9b9
NC
1367 psindx);
1368 bfd_set_error (bfd_error_bad_value);
0a1b45a2 1369 return false;
ca4cf9b9
NC
1370 }
1371 entry->section = PRIV (sections)[psindx];
95e34ef7 1372
07d6d2b8
AM
1373 if (old_flags & EGSY__V_NORM)
1374 {
1375 PRIV (norm_sym_count)++;
95e34ef7 1376
07d6d2b8 1377 entry->code_value = bfd_getl64 (esdf->code_address);
ca4cf9b9 1378 psindx = bfd_getl32 (esdf->ca_psindx);
bf31e604 1379 /* PR 21813: Check for an out of range index. */
ca4cf9b9 1380 if (psindx < 0 || psindx >= (int) PRIV (section_count))
bf31e604 1381 goto bad_psindx;
07d6d2b8
AM
1382 entry->code_section = PRIV (sections)[psindx];
1383 }
1384 }
95e34ef7
TG
1385 }
1386 break;
1387
1388 case EGSD__C_SYMG:
1389 {
07d6d2b8
AM
1390 struct vms_symbol_entry *entry;
1391 struct vms_egst *egst = (struct vms_egst *)vms_rec;
1392 flagword old_flags;
2c0e48e5 1393 unsigned int nameoff = offsetof (struct vms_egst, namlng);
95e34ef7 1394
2c0e48e5 1395 if (nameoff >= gsd_size)
bf31e604 1396 goto too_small;
2c0e48e5 1397 entry = add_symbol (abfd, &egst->namlng, gsd_size - nameoff);
07d6d2b8 1398 if (entry == NULL)
0a1b45a2 1399 return false;
95e34ef7 1400
de6a7ee4 1401 old_flags = bfd_getl16 (egst->header.flags);
07d6d2b8
AM
1402 entry->typ = gsd_type;
1403 entry->data_type = egst->header.datyp;
1404 entry->flags = old_flags;
95e34ef7 1405
07d6d2b8 1406 entry->symbol_vector = bfd_getl32 (egst->value);
95e34ef7 1407
07d6d2b8 1408 if (old_flags & EGSY__V_REL)
cb06d03a
NC
1409 {
1410 if (PRIV (sections) == NULL)
0a1b45a2 1411 return false;
ca4cf9b9
NC
1412 psindx = bfd_getl32 (egst->psindx);
1413 /* PR 21813: Check for an out of range index. */
1414 if (psindx < 0 || psindx >= (int) PRIV (section_count))
bf31e604 1415 goto bad_psindx;
ca4cf9b9 1416 entry->section = PRIV (sections)[psindx];
cb06d03a 1417 }
07d6d2b8
AM
1418 else
1419 entry->section = bfd_abs_section_ptr;
a928f1d7 1420
07d6d2b8 1421 entry->value = bfd_getl64 (egst->lp_2);
95e34ef7 1422
07d6d2b8
AM
1423 if (old_flags & EGSY__V_NORM)
1424 {
1425 PRIV (norm_sym_count)++;
95e34ef7 1426
07d6d2b8
AM
1427 entry->code_value = bfd_getl64 (egst->lp_1);
1428 entry->code_section = bfd_abs_section_ptr;
1429 }
1430 }
95e34ef7
TG
1431 break;
1432
07d6d2b8
AM
1433 case EGSD__C_SPSC:
1434 case EGSD__C_IDC:
1435 /* Currently ignored. */
1436 break;
95e34ef7
TG
1437 case EGSD__C_SYMM:
1438 case EGSD__C_SYMV:
1439 default:
38f14ab8 1440 _bfd_error_handler (_("unknown EGSD subtype %d"), gsd_type);
95e34ef7 1441 bfd_set_error (bfd_error_bad_value);
0a1b45a2 1442 return false;
95e34ef7
TG
1443 }
1444
1445 PRIV (recrd.rec_size) -= gsd_size;
1446 PRIV (recrd.rec) += gsd_size;
1447 }
1448
3de58d95
NC
1449 /* FIXME: Should we complain if PRIV (recrd.rec_size) is not zero ? */
1450
95e34ef7
TG
1451 if (PRIV (gsd_sym_count) > 0)
1452 abfd->flags |= HAS_SYMS;
1453
0a1b45a2 1454 return true;
95e34ef7
TG
1455}
1456
1457/* Stack routines for vms ETIR commands. */
1458
1459/* Push value and section index. */
1460
0a1b45a2 1461static bool
95e34ef7
TG
1462_bfd_vms_push (bfd *abfd, bfd_vma val, unsigned int reloc)
1463{
1464 vms_debug2 ((4, "<push %08lx (0x%08x) at %d>\n",
07d6d2b8 1465 (unsigned long)val, reloc, PRIV (stackptr)));
95e34ef7
TG
1466
1467 PRIV (stack[PRIV (stackptr)]).value = val;
1468 PRIV (stack[PRIV (stackptr)]).reloc = reloc;
1469 PRIV (stackptr)++;
1470 if (PRIV (stackptr) >= STACKSIZE)
1471 {
1472 bfd_set_error (bfd_error_bad_value);
38f14ab8 1473 _bfd_error_handler (_("stack overflow (%d) in _bfd_vms_push"), PRIV (stackptr));
0a1b45a2 1474 return false;
95e34ef7 1475 }
0a1b45a2 1476 return true;
95e34ef7
TG
1477}
1478
1479/* Pop value and section index. */
1480
0a1b45a2 1481static bool
95e34ef7
TG
1482_bfd_vms_pop (bfd *abfd, bfd_vma *val, unsigned int *rel)
1483{
1484 if (PRIV (stackptr) == 0)
1485 {
1486 bfd_set_error (bfd_error_bad_value);
38f14ab8 1487 _bfd_error_handler (_("stack underflow in _bfd_vms_pop"));
0a1b45a2 1488 return false;
95e34ef7
TG
1489 }
1490 PRIV (stackptr)--;
1491 *val = PRIV (stack[PRIV (stackptr)]).value;
1492 *rel = PRIV (stack[PRIV (stackptr)]).reloc;
1493
1494 vms_debug2 ((4, "<pop %08lx (0x%08x)>\n", (unsigned long)*val, *rel));
0a1b45a2 1495 return true;
95e34ef7
TG
1496}
1497
1498/* Routines to fill sections contents during tir/etir read. */
1499
1500/* Initialize image buffer pointer to be filled. */
1501
1502static void
1503image_set_ptr (bfd *abfd, bfd_vma vma, int sect, struct bfd_link_info *info)
1504{
1505 asection *sec;
1506
1507 vms_debug2 ((4, "image_set_ptr (0x%08x, sect=%d)\n", (unsigned)vma, sect));
1508
cb06d03a
NC
1509 if (PRIV (sections) == NULL)
1510 return;
ca4cf9b9
NC
1511 if (sect < 0 || sect >= (int) PRIV (section_count))
1512 return;
1513
95e34ef7
TG
1514 sec = PRIV (sections)[sect];
1515
1516 if (info)
1517 {
1518 /* Reading contents to an output bfd. */
1519
1520 if (sec->output_section == NULL)
07d6d2b8
AM
1521 {
1522 /* Section discarded. */
1523 vms_debug2 ((5, " section %s discarded\n", sec->name));
1524
1525 /* This is not used. */
1526 PRIV (image_section) = NULL;
1527 PRIV (image_offset) = 0;
1528 return;
1529 }
95e34ef7
TG
1530 PRIV (image_offset) = sec->output_offset + vma;
1531 PRIV (image_section) = sec->output_section;
1532 }
1533 else
1534 {
1535 PRIV (image_offset) = vma;
1536 PRIV (image_section) = sec;
1537 }
1538}
1539
1540/* Increment image buffer pointer by offset. */
1541
1542static void
1543image_inc_ptr (bfd *abfd, bfd_vma offset)
1544{
1545 vms_debug2 ((4, "image_inc_ptr (%u)\n", (unsigned)offset));
1546
1547 PRIV (image_offset) += offset;
1548}
1549
1550/* Save current DST location counter under specified index. */
1551
0a1b45a2 1552static bool
95e34ef7
TG
1553dst_define_location (bfd *abfd, unsigned int loc)
1554{
1555 vms_debug2 ((4, "dst_define_location (%d)\n", (int)loc));
1556
f75fbe8a
AM
1557 if (loc > 1 << 24)
1558 {
1559 /* 16M entries ought to be plenty. */
1560 bfd_set_error (bfd_error_bad_value);
1561 _bfd_error_handler (_("dst_define_location %u too large"), loc);
0a1b45a2 1562 return false;
f75fbe8a
AM
1563 }
1564
95e34ef7
TG
1565 /* Grow the ptr offset table if necessary. */
1566 if (loc + 1 > PRIV (dst_ptr_offsets_count))
1567 {
9cb56943
AM
1568 PRIV (dst_ptr_offsets)
1569 = bfd_realloc_or_free (PRIV (dst_ptr_offsets),
1570 (loc + 1) * sizeof (unsigned int));
1571 if (PRIV (dst_ptr_offsets) == NULL)
0a1b45a2 1572 return false;
95e34ef7
TG
1573 PRIV (dst_ptr_offsets_count) = loc + 1;
1574 }
1575
1576 PRIV (dst_ptr_offsets)[loc] = PRIV (image_offset);
0a1b45a2 1577 return true;
95e34ef7
TG
1578}
1579
1580/* Restore saved DST location counter from specified index. */
1581
0a1b45a2 1582static bool
95e34ef7
TG
1583dst_restore_location (bfd *abfd, unsigned int loc)
1584{
1585 vms_debug2 ((4, "dst_restore_location (%d)\n", (int)loc));
1586
7bac4137
AM
1587 if (loc < PRIV (dst_ptr_offsets_count))
1588 {
1589 PRIV (image_offset) = PRIV (dst_ptr_offsets)[loc];
0a1b45a2 1590 return true;
7bac4137 1591 }
0a1b45a2 1592 return false;
95e34ef7
TG
1593}
1594
1595/* Retrieve saved DST location counter from specified index. */
1596
0a1b45a2 1597static bool
7bac4137 1598dst_retrieve_location (bfd *abfd, bfd_vma *loc)
95e34ef7 1599{
7bac4137 1600 vms_debug2 ((4, "dst_retrieve_location (%d)\n", (int) *loc));
95e34ef7 1601
7bac4137
AM
1602 if (*loc < PRIV (dst_ptr_offsets_count))
1603 {
1604 *loc = PRIV (dst_ptr_offsets)[*loc];
0a1b45a2 1605 return true;
7bac4137 1606 }
0a1b45a2 1607 return false;
95e34ef7
TG
1608}
1609
95e34ef7
TG
1610/* Write multiple bytes to section image. */
1611
0a1b45a2 1612static bool
c53d2e6d 1613image_write (bfd *abfd, unsigned char *ptr, unsigned int size)
95e34ef7 1614{
81699544
AM
1615 asection *sec = PRIV (image_section);
1616 size_t off = PRIV (image_offset);
1617
1618 /* Check bounds. */
1619 if (off > sec->size
1620 || size > sec->size - off)
1621 {
1622 bfd_set_error (bfd_error_bad_value);
0a1b45a2 1623 return false;
81699544
AM
1624 }
1625
95e34ef7
TG
1626#if VMS_DEBUG
1627 _bfd_vms_debug (8, "image_write from (%p, %d) to (%ld)\n", ptr, size,
81699544 1628 (long) off));
95e34ef7
TG
1629#endif
1630
95e34ef7 1631 if (PRIV (image_section)->contents != NULL)
81699544
AM
1632 memcpy (sec->contents + off, ptr, size);
1633 else
95e34ef7 1634 {
81699544
AM
1635 unsigned int i;
1636 for (i = 0; i < size; i++)
1637 if (ptr[i] != 0)
1638 {
1639 bfd_set_error (bfd_error_bad_value);
0a1b45a2 1640 return false;
81699544 1641 }
95e34ef7 1642 }
81699544 1643
8ab484c2
AM
1644#if VMS_DEBUG
1645 _bfd_hexdump (9, ptr, size, 0);
1646#endif
95e34ef7
TG
1647
1648 PRIV (image_offset) += size;
0a1b45a2 1649 return true;
95e34ef7
TG
1650}
1651
1652/* Write byte to section image. */
1653
0a1b45a2 1654static bool
95e34ef7
TG
1655image_write_b (bfd * abfd, unsigned int value)
1656{
1657 unsigned char data[1];
1658
1659 vms_debug2 ((6, "image_write_b (%02x)\n", (int) value));
1660
1661 *data = value;
1662
1663 return image_write (abfd, data, sizeof (data));
1664}
1665
1666/* Write 2-byte word to image. */
1667
0a1b45a2 1668static bool
95e34ef7
TG
1669image_write_w (bfd * abfd, unsigned int value)
1670{
1671 unsigned char data[2];
1672
1673 vms_debug2 ((6, "image_write_w (%04x)\n", (int) value));
1674
1675 bfd_putl16 (value, data);
1676 return image_write (abfd, data, sizeof (data));
1677}
1678
1679/* Write 4-byte long to image. */
1680
0a1b45a2 1681static bool
95e34ef7
TG
1682image_write_l (bfd * abfd, unsigned long value)
1683{
1684 unsigned char data[4];
1685
1686 vms_debug2 ((6, "image_write_l (%08lx)\n", value));
1687
1688 bfd_putl32 (value, data);
1689 return image_write (abfd, data, sizeof (data));
1690}
1691
1692/* Write 8-byte quad to image. */
1693
0a1b45a2 1694static bool
95e34ef7
TG
1695image_write_q (bfd * abfd, bfd_vma value)
1696{
1697 unsigned char data[8];
1698
1699 vms_debug2 ((6, "image_write_q (%08lx)\n", (unsigned long)value));
1700
1701 bfd_putl64 (value, data);
1702 return image_write (abfd, data, sizeof (data));
1703}
1704\f
1705static const char *
1706_bfd_vms_etir_name (int cmd)
1707{
1708 switch (cmd)
1709 {
1710 case ETIR__C_STA_GBL: return "ETIR__C_STA_GBL";
1711 case ETIR__C_STA_LW: return "ETIR__C_STA_LW";
1712 case ETIR__C_STA_QW: return "ETIR__C_STA_QW";
1713 case ETIR__C_STA_PQ: return "ETIR__C_STA_PQ";
1714 case ETIR__C_STA_LI: return "ETIR__C_STA_LI";
1715 case ETIR__C_STA_MOD: return "ETIR__C_STA_MOD";
1716 case ETIR__C_STA_CKARG: return "ETIR__C_STA_CKARG";
1717 case ETIR__C_STO_B: return "ETIR__C_STO_B";
1718 case ETIR__C_STO_W: return "ETIR__C_STO_W";
1719 case ETIR__C_STO_GBL: return "ETIR__C_STO_GBL";
1720 case ETIR__C_STO_CA: return "ETIR__C_STO_CA";
1721 case ETIR__C_STO_RB: return "ETIR__C_STO_RB";
1722 case ETIR__C_STO_AB: return "ETIR__C_STO_AB";
1723 case ETIR__C_STO_OFF: return "ETIR__C_STO_OFF";
1724 case ETIR__C_STO_IMM: return "ETIR__C_STO_IMM";
1725 case ETIR__C_STO_IMMR: return "ETIR__C_STO_IMMR";
1726 case ETIR__C_STO_LW: return "ETIR__C_STO_LW";
1727 case ETIR__C_STO_QW: return "ETIR__C_STO_QW";
1728 case ETIR__C_STO_GBL_LW: return "ETIR__C_STO_GBL_LW";
1729 case ETIR__C_STO_LP_PSB: return "ETIR__C_STO_LP_PSB";
1730 case ETIR__C_STO_HINT_GBL: return "ETIR__C_STO_HINT_GBL";
1731 case ETIR__C_STO_HINT_PS: return "ETIR__C_STO_HINT_PS";
1732 case ETIR__C_OPR_ADD: return "ETIR__C_OPR_ADD";
1733 case ETIR__C_OPR_SUB: return "ETIR__C_OPR_SUB";
1734 case ETIR__C_OPR_INSV: return "ETIR__C_OPR_INSV";
1735 case ETIR__C_OPR_USH: return "ETIR__C_OPR_USH";
1736 case ETIR__C_OPR_ROT: return "ETIR__C_OPR_ROT";
1737 case ETIR__C_OPR_REDEF: return "ETIR__C_OPR_REDEF";
1738 case ETIR__C_OPR_DFLIT: return "ETIR__C_OPR_DFLIT";
1739 case ETIR__C_STC_LP: return "ETIR__C_STC_LP";
1740 case ETIR__C_STC_GBL: return "ETIR__C_STC_GBL";
1741 case ETIR__C_STC_GCA: return "ETIR__C_STC_GCA";
1742 case ETIR__C_STC_PS: return "ETIR__C_STC_PS";
1743 case ETIR__C_STC_NBH_PS: return "ETIR__C_STC_NBH_PS";
1744 case ETIR__C_STC_NOP_GBL: return "ETIR__C_STC_NOP_GBL";
1745 case ETIR__C_STC_NOP_PS: return "ETIR__C_STC_NOP_PS";
1746 case ETIR__C_STC_BSR_GBL: return "ETIR__C_STC_BSR_GBL";
1747 case ETIR__C_STC_BSR_PS: return "ETIR__C_STC_BSR_PS";
1748 case ETIR__C_STC_LDA_GBL: return "ETIR__C_STC_LDA_GBL";
1749 case ETIR__C_STC_LDA_PS: return "ETIR__C_STC_LDA_PS";
1750 case ETIR__C_STC_BOH_GBL: return "ETIR__C_STC_BOH_GBL";
1751 case ETIR__C_STC_BOH_PS: return "ETIR__C_STC_BOH_PS";
1752 case ETIR__C_STC_NBH_GBL: return "ETIR__C_STC_NBH_GBL";
1753 case ETIR__C_STC_LP_PSB: return "ETIR__C_STC_LP_PSB";
1754 case ETIR__C_CTL_SETRB: return "ETIR__C_CTL_SETRB";
1755 case ETIR__C_CTL_AUGRB: return "ETIR__C_CTL_AUGRB";
1756 case ETIR__C_CTL_DFLOC: return "ETIR__C_CTL_DFLOC";
1757 case ETIR__C_CTL_STLOC: return "ETIR__C_CTL_STLOC";
1758 case ETIR__C_CTL_STKDL: return "ETIR__C_CTL_STKDL";
1759
1760 default:
1761 /* These names have not yet been added to this switch statement. */
4eca0228 1762 _bfd_error_handler (_("unknown ETIR command %d"), cmd);
95e34ef7
TG
1763 }
1764
1765 return NULL;
1766}
1767#define HIGHBIT(op) ((op & 0x80000000L) == 0x80000000L)
1768
1769static void
c53d2e6d
NC
1770_bfd_vms_get_value (bfd *abfd,
1771 const unsigned char *ascic,
1772 const unsigned char *max_ascic,
07d6d2b8
AM
1773 struct bfd_link_info *info,
1774 bfd_vma *vma,
1775 struct alpha_vms_link_hash_entry **hp)
95e34ef7
TG
1776{
1777 char name[257];
c53d2e6d
NC
1778 unsigned int len;
1779 unsigned int i;
95e34ef7
TG
1780 struct alpha_vms_link_hash_entry *h;
1781
1782 /* Not linking. Do not try to resolve the symbol. */
1783 if (info == NULL)
1784 {
1785 *vma = 0;
1786 *hp = NULL;
1787 return;
1788 }
1789
1790 len = *ascic;
c53d2e6d
NC
1791 if (ascic + len >= max_ascic)
1792 {
38f14ab8 1793 _bfd_error_handler (_("corrupt vms value"));
c53d2e6d
NC
1794 *vma = 0;
1795 *hp = NULL;
1796 return;
1797 }
1798
95e34ef7
TG
1799 for (i = 0; i < len; i++)
1800 name[i] = ascic[i + 1];
1801 name[i] = 0;
1802
1803 h = (struct alpha_vms_link_hash_entry *)
0a1b45a2 1804 bfd_link_hash_lookup (info->hash, name, false, false, true);
95e34ef7
TG
1805
1806 *hp = h;
1807
1808 if (h != NULL
1809 && (h->root.type == bfd_link_hash_defined
07d6d2b8 1810 || h->root.type == bfd_link_hash_defweak))
95e34ef7
TG
1811 *vma = h->root.u.def.value
1812 + h->root.u.def.section->output_offset
1813 + h->root.u.def.section->output_section->vma;
1814 else if (h && h->root.type == bfd_link_hash_undefweak)
1815 *vma = 0;
1816 else
1817 {
1a72702b 1818 (*info->callbacks->undefined_symbol)
0a1b45a2 1819 (info, name, abfd, PRIV (image_section), PRIV (image_offset), true);
95e34ef7
TG
1820 *vma = 0;
1821 }
1822}
1823
1824#define RELC_NONE 0
1825#define RELC_REL 1
1826#define RELC_SHR_BASE 0x10000
1827#define RELC_SEC_BASE 0x20000
1828#define RELC_MASK 0x0ffff
1829
1830static unsigned int
1831alpha_vms_sym_to_ctxt (struct alpha_vms_link_hash_entry *h)
1832{
1833 /* Handle undefined symbols. */
1834 if (h == NULL || h->sym == NULL)
1835 return RELC_NONE;
1836
1837 if (h->sym->typ == EGSD__C_SYMG)
1838 {
1839 if (h->sym->flags & EGSY__V_REL)
07d6d2b8 1840 return RELC_SHR_BASE + PRIV2 (h->sym->owner, shr_index);
95e34ef7 1841 else
07d6d2b8
AM
1842 {
1843 /* Can this happen (non-relocatable symg) ? I'd like to see
1844 an example. */
1845 abort ();
1846 }
95e34ef7
TG
1847 }
1848 if (h->sym->typ == EGSD__C_SYM)
1849 {
1850 if (h->sym->flags & EGSY__V_REL)
07d6d2b8 1851 return RELC_REL;
95e34ef7 1852 else
07d6d2b8 1853 return RELC_NONE;
95e34ef7
TG
1854 }
1855 abort ();
1856}
1857
1858static bfd_vma
a928f1d7 1859alpha_vms_get_sym_value (asection *sect, bfd_vma addr)
95e34ef7 1860{
a928f1d7 1861 return sect->output_section->vma + sect->output_offset + addr;
95e34ef7
TG
1862}
1863
1864static bfd_vma
1865alpha_vms_fix_sec_rel (bfd *abfd, struct bfd_link_info *info,
07d6d2b8 1866 unsigned int rel, bfd_vma vma)
95e34ef7 1867{
cb06d03a
NC
1868 asection *sec;
1869
1870 if (PRIV (sections) == NULL)
1871 return 0;
1872
1873 sec = PRIV (sections)[rel & RELC_MASK];
95e34ef7
TG
1874
1875 if (info)
1876 {
1877 if (sec->output_section == NULL)
07d6d2b8 1878 abort ();
95e34ef7
TG
1879 return vma + sec->output_section->vma + sec->output_offset;
1880 }
1881 else
1882 return vma + sec->vma;
1883}
1884
44273c5b
TG
1885/* Read an ETIR record from ABFD. If INFO is not null, put the content into
1886 the output section (used during linking).
1887 Return FALSE in case of error. */
1888
0a1b45a2 1889static bool
95e34ef7
TG
1890_bfd_vms_slurp_etir (bfd *abfd, struct bfd_link_info *info)
1891{
1892 unsigned char *ptr;
1893 unsigned int length;
1894 unsigned char *maxptr;
8ab484c2
AM
1895 bfd_vma op1 = 0;
1896 bfd_vma op2 = 0;
1897 unsigned int rel1 = RELC_NONE;
1898 unsigned int rel2 = RELC_NONE;
95e34ef7
TG
1899 struct alpha_vms_link_hash_entry *h;
1900
1901 PRIV (recrd.rec) += ETIR__C_HEADER_SIZE;
1902 PRIV (recrd.rec_size) -= ETIR__C_HEADER_SIZE;
1903
1904 ptr = PRIV (recrd.rec);
1905 length = PRIV (recrd.rec_size);
1906 maxptr = ptr + length;
1907
1908 vms_debug2 ((2, "ETIR: %d bytes\n", length));
1909
1910 while (ptr < maxptr)
1911 {
2c0e48e5 1912 int cmd, cmd_length;
95e34ef7 1913
2c0e48e5
AM
1914 if (ptr + 4 > maxptr)
1915 goto corrupt_etir;
1916
1917 cmd = bfd_getl16 (ptr);
1918 cmd_length = bfd_getl16 (ptr + 2);
95e34ef7 1919
76800cba 1920 /* PR 21589 and 21579: Check for a corrupt ETIR record. */
2c0e48e5 1921 if (cmd_length < 4 || ptr + cmd_length > maxptr)
c53d2e6d
NC
1922 {
1923 corrupt_etir:
38f14ab8 1924 _bfd_error_handler (_("corrupt ETIR record encountered"));
c53d2e6d 1925 bfd_set_error (bfd_error_bad_value);
0a1b45a2 1926 return false;
c53d2e6d 1927 }
2c0e48e5 1928 ptr += 4;
2fdb65f2 1929 cmd_length -= 4;
c53d2e6d 1930
76800cba
NC
1931#if VMS_DEBUG
1932 _bfd_vms_debug (4, "etir: %s(%d)\n",
07d6d2b8 1933 _bfd_vms_etir_name (cmd), cmd);
2fdb65f2 1934 _bfd_hexdump (8, ptr, cmd_length, 0);
76800cba
NC
1935#endif
1936
95e34ef7 1937 switch (cmd)
07d6d2b8
AM
1938 {
1939 /* Stack global
1940 arg: cs symbol name
95e34ef7 1941
07d6d2b8
AM
1942 stack 32 bit value of symbol (high bits set to 0). */
1943 case ETIR__C_STA_GBL:
2fdb65f2 1944 _bfd_vms_get_value (abfd, ptr, ptr + cmd_length, info, &op1, &h);
ab356be7 1945 if (!_bfd_vms_push (abfd, op1, alpha_vms_sym_to_ctxt (h)))
0a1b45a2 1946 return false;
07d6d2b8 1947 break;
95e34ef7 1948
07d6d2b8
AM
1949 /* Stack longword
1950 arg: lw value
95e34ef7 1951
07d6d2b8
AM
1952 stack 32 bit value, sign extend to 64 bit. */
1953 case ETIR__C_STA_LW:
2fdb65f2 1954 if (cmd_length < 4)
c53d2e6d 1955 goto corrupt_etir;
ab356be7 1956 if (!_bfd_vms_push (abfd, bfd_getl32 (ptr), RELC_NONE))
0a1b45a2 1957 return false;
07d6d2b8 1958 break;
95e34ef7 1959
07d6d2b8
AM
1960 /* Stack quadword
1961 arg: qw value
95e34ef7 1962
07d6d2b8
AM
1963 stack 64 bit value of symbol. */
1964 case ETIR__C_STA_QW:
2fdb65f2 1965 if (cmd_length < 8)
c53d2e6d 1966 goto corrupt_etir;
ab356be7 1967 if (!_bfd_vms_push (abfd, bfd_getl64 (ptr), RELC_NONE))
0a1b45a2 1968 return false;
07d6d2b8 1969 break;
95e34ef7 1970
07d6d2b8
AM
1971 /* Stack psect base plus quadword offset
1972 arg: lw section index
1973 qw signed quadword offset (low 32 bits)
95e34ef7 1974
07d6d2b8
AM
1975 Stack qw argument and section index
1976 (see ETIR__C_STO_OFF, ETIR__C_CTL_SETRB). */
1977 case ETIR__C_STA_PQ:
1978 {
1979 int psect;
95e34ef7 1980
2fdb65f2 1981 if (cmd_length < 12)
c53d2e6d 1982 goto corrupt_etir;
07d6d2b8
AM
1983 psect = bfd_getl32 (ptr);
1984 if ((unsigned int) psect >= PRIV (section_count))
1985 {
4eca0228
AM
1986 _bfd_error_handler (_("bad section index in %s"),
1987 _bfd_vms_etir_name (cmd));
07d6d2b8 1988 bfd_set_error (bfd_error_bad_value);
0a1b45a2 1989 return false;
07d6d2b8
AM
1990 }
1991 op1 = bfd_getl64 (ptr + 4);
ab356be7 1992 if (!_bfd_vms_push (abfd, op1, psect | RELC_SEC_BASE))
0a1b45a2 1993 return false;
07d6d2b8
AM
1994 }
1995 break;
1996
1997 case ETIR__C_STA_LI:
1998 case ETIR__C_STA_MOD:
1999 case ETIR__C_STA_CKARG:
4eca0228
AM
2000 _bfd_error_handler (_("unsupported STA cmd %s"),
2001 _bfd_vms_etir_name (cmd));
0a1b45a2 2002 return false;
07d6d2b8
AM
2003 break;
2004
2005 /* Store byte: pop stack, write byte
2006 arg: -. */
2007 case ETIR__C_STO_B:
ab356be7 2008 if (!_bfd_vms_pop (abfd, &op1, &rel1))
0a1b45a2 2009 return false;
07d6d2b8
AM
2010 if (rel1 != RELC_NONE)
2011 goto bad_context;
81699544 2012 if (!image_write_b (abfd, (unsigned int) op1 & 0xff))
0a1b45a2 2013 return false;
07d6d2b8
AM
2014 break;
2015
2016 /* Store word: pop stack, write word
2017 arg: -. */
2018 case ETIR__C_STO_W:
ab356be7 2019 if (!_bfd_vms_pop (abfd, &op1, &rel1))
0a1b45a2 2020 return false;
07d6d2b8
AM
2021 if (rel1 != RELC_NONE)
2022 goto bad_context;
81699544 2023 if (!image_write_w (abfd, (unsigned int) op1 & 0xffff))
0a1b45a2 2024 return false;
07d6d2b8
AM
2025 break;
2026
2027 /* Store longword: pop stack, write longword
2028 arg: -. */
2029 case ETIR__C_STO_LW:
ab356be7 2030 if (!_bfd_vms_pop (abfd, &op1, &rel1))
0a1b45a2 2031 return false;
07d6d2b8
AM
2032 if (rel1 & RELC_SEC_BASE)
2033 {
2034 op1 = alpha_vms_fix_sec_rel (abfd, info, rel1, op1);
2035 rel1 = RELC_REL;
2036 }
2037 else if (rel1 & RELC_SHR_BASE)
2038 {
96d3b80f 2039 if (!alpha_vms_add_fixup_lr (info, rel1 & RELC_MASK, op1))
0a1b45a2 2040 return false;
07d6d2b8
AM
2041 rel1 = RELC_NONE;
2042 }
2043 if (rel1 != RELC_NONE)
2044 {
2045 if (rel1 != RELC_REL)
2046 abort ();
96d3b80f 2047 if (!alpha_vms_add_lw_reloc (info))
0a1b45a2 2048 return false;
07d6d2b8 2049 }
81699544 2050 if (!image_write_l (abfd, op1))
0a1b45a2 2051 return false;
07d6d2b8
AM
2052 break;
2053
2054 /* Store quadword: pop stack, write quadword
2055 arg: -. */
2056 case ETIR__C_STO_QW:
ab356be7 2057 if (!_bfd_vms_pop (abfd, &op1, &rel1))
0a1b45a2 2058 return false;
07d6d2b8
AM
2059 if (rel1 & RELC_SEC_BASE)
2060 {
2061 op1 = alpha_vms_fix_sec_rel (abfd, info, rel1, op1);
2062 rel1 = RELC_REL;
2063 }
2064 else if (rel1 & RELC_SHR_BASE)
2065 abort ();
2066 if (rel1 != RELC_NONE)
2067 {
2068 if (rel1 != RELC_REL)
2069 abort ();
96d3b80f 2070 if (!alpha_vms_add_qw_reloc (info))
0a1b45a2 2071 return false;
07d6d2b8 2072 }
81699544 2073 if (!image_write_q (abfd, op1))
0a1b45a2 2074 return false;
07d6d2b8
AM
2075 break;
2076
2077 /* Store immediate repeated: pop stack for repeat count
2078 arg: lw byte count
2079 da data. */
2080 case ETIR__C_STO_IMMR:
2081 {
2082 int size;
95e34ef7 2083
2fdb65f2 2084 if (cmd_length < 4)
c53d2e6d 2085 goto corrupt_etir;
07d6d2b8 2086 size = bfd_getl32 (ptr);
2fdb65f2
AM
2087 if (size > cmd_length - 4)
2088 goto corrupt_etir;
ab356be7 2089 if (!_bfd_vms_pop (abfd, &op1, &rel1))
0a1b45a2 2090 return false;
07d6d2b8
AM
2091 if (rel1 != RELC_NONE)
2092 goto bad_context;
2fdb65f2
AM
2093 if (size == 0)
2094 break;
2095 op1 &= 0xffffffff;
07d6d2b8 2096 while (op1-- > 0)
81699544 2097 if (!image_write (abfd, ptr + 4, size))
0a1b45a2 2098 return false;
07d6d2b8
AM
2099 }
2100 break;
2101
2102 /* Store global: write symbol value
2103 arg: cs global symbol name. */
2104 case ETIR__C_STO_GBL:
2fdb65f2 2105 _bfd_vms_get_value (abfd, ptr, ptr + cmd_length, info, &op1, &h);
07d6d2b8
AM
2106 if (h && h->sym)
2107 {
2108 if (h->sym->typ == EGSD__C_SYMG)
2109 {
96d3b80f
AM
2110 if (!alpha_vms_add_fixup_qr (info, abfd, h->sym->owner,
2111 h->sym->symbol_vector))
0a1b45a2 2112 return false;
07d6d2b8
AM
2113 op1 = 0;
2114 }
2115 else
2116 {
2117 op1 = alpha_vms_get_sym_value (h->sym->section,
2118 h->sym->value);
96d3b80f 2119 if (!alpha_vms_add_qw_reloc (info))
0a1b45a2 2120 return false;
07d6d2b8
AM
2121 }
2122 }
81699544 2123 if (!image_write_q (abfd, op1))
0a1b45a2 2124 return false;
07d6d2b8
AM
2125 break;
2126
2127 /* Store code address: write address of entry point
2128 arg: cs global symbol name (procedure). */
2129 case ETIR__C_STO_CA:
2fdb65f2 2130 _bfd_vms_get_value (abfd, ptr, ptr + cmd_length, info, &op1, &h);
07d6d2b8
AM
2131 if (h && h->sym)
2132 {
2133 if (h->sym->flags & EGSY__V_NORM)
2134 {
2135 /* That's really a procedure. */
2136 if (h->sym->typ == EGSD__C_SYMG)
2137 {
96d3b80f 2138 if (!alpha_vms_add_fixup_ca (info, abfd, h->sym->owner))
0a1b45a2 2139 return false;
07d6d2b8
AM
2140 op1 = h->sym->symbol_vector;
2141 }
2142 else
2143 {
2144 op1 = alpha_vms_get_sym_value (h->sym->code_section,
2145 h->sym->code_value);
96d3b80f 2146 if (!alpha_vms_add_qw_reloc (info))
0a1b45a2 2147 return false;
07d6d2b8
AM
2148 }
2149 }
2150 else
2151 {
2152 /* Symbol is not a procedure. */
2153 abort ();
2154 }
2155 }
81699544 2156 if (!image_write_q (abfd, op1))
0a1b45a2 2157 return false;
07d6d2b8
AM
2158 break;
2159
2160 /* Store offset to psect: pop stack, add low 32 bits to base of psect
2161 arg: none. */
2162 case ETIR__C_STO_OFF:
ab356be7 2163 if (!_bfd_vms_pop (abfd, &op1, &rel1))
0a1b45a2 2164 return false;
07d6d2b8
AM
2165
2166 if (!(rel1 & RELC_SEC_BASE))
2167 abort ();
2168
2169 op1 = alpha_vms_fix_sec_rel (abfd, info, rel1, op1);
2170 rel1 = RELC_REL;
81699544 2171 if (!image_write_q (abfd, op1))
0a1b45a2 2172 return false;
07d6d2b8
AM
2173 break;
2174
2175 /* Store immediate
2176 arg: lw count of bytes
2177 da data. */
2178 case ETIR__C_STO_IMM:
2179 {
2180 unsigned int size;
95e34ef7 2181
2fdb65f2 2182 if (cmd_length < 4)
c53d2e6d 2183 goto corrupt_etir;
07d6d2b8 2184 size = bfd_getl32 (ptr);
81699544 2185 if (!image_write (abfd, ptr + 4, size))
0a1b45a2 2186 return false;
07d6d2b8
AM
2187 }
2188 break;
2189
2190 /* This code is 'reserved to digital' according to the openVMS
2191 linker manual, however it is generated by the DEC C compiler
2192 and defined in the include file.
2193 FIXME, since the following is just a guess
2194 store global longword: store 32bit value of symbol
2195 arg: cs symbol name. */
2196 case ETIR__C_STO_GBL_LW:
2fdb65f2 2197 _bfd_vms_get_value (abfd, ptr, ptr + cmd_length, info, &op1, &h);
95e34ef7 2198#if 0
07d6d2b8 2199 abort ();
95e34ef7 2200#endif
81699544 2201 if (!image_write_l (abfd, op1))
0a1b45a2 2202 return false;
07d6d2b8 2203 break;
95e34ef7 2204
07d6d2b8
AM
2205 case ETIR__C_STO_RB:
2206 case ETIR__C_STO_AB:
2207 case ETIR__C_STO_LP_PSB:
4eca0228
AM
2208 _bfd_error_handler (_("%s: not supported"),
2209 _bfd_vms_etir_name (cmd));
0a1b45a2 2210 return false;
07d6d2b8
AM
2211 break;
2212 case ETIR__C_STO_HINT_GBL:
2213 case ETIR__C_STO_HINT_PS:
4eca0228
AM
2214 _bfd_error_handler (_("%s: not implemented"),
2215 _bfd_vms_etir_name (cmd));
0a1b45a2 2216 return false;
07d6d2b8 2217 break;
95e34ef7 2218
07d6d2b8
AM
2219 /* 200 Store-conditional Linkage Pair
2220 arg: none. */
2221 case ETIR__C_STC_LP:
95e34ef7 2222
07d6d2b8
AM
2223 /* 202 Store-conditional Address at global address
2224 lw linkage index
2225 cs global name. */
95e34ef7 2226
07d6d2b8 2227 case ETIR__C_STC_GBL:
95e34ef7 2228
07d6d2b8
AM
2229 /* 203 Store-conditional Code Address at global address
2230 lw linkage index
2231 cs procedure name. */
2232 case ETIR__C_STC_GCA:
95e34ef7 2233
07d6d2b8
AM
2234 /* 204 Store-conditional Address at psect + offset
2235 lw linkage index
2236 lw psect index
2237 qw offset. */
2238 case ETIR__C_STC_PS:
4eca0228
AM
2239 _bfd_error_handler (_("%s: not supported"),
2240 _bfd_vms_etir_name (cmd));
0a1b45a2 2241 return false;
07d6d2b8
AM
2242 break;
2243
2244 /* 201 Store-conditional Linkage Pair with Procedure Signature
2245 lw linkage index
2246 cs procedure name
2247 by signature length
2248 da signature. */
2249
2250 case ETIR__C_STC_LP_PSB:
2fdb65f2
AM
2251 if (cmd_length < 4)
2252 goto corrupt_etir;
2253 _bfd_vms_get_value (abfd, ptr + 4, ptr + cmd_length, info, &op1, &h);
07d6d2b8
AM
2254 if (h && h->sym)
2255 {
2256 if (h->sym->typ == EGSD__C_SYMG)
2257 {
96d3b80f 2258 if (!alpha_vms_add_fixup_lp (info, abfd, h->sym->owner))
0a1b45a2 2259 return false;
07d6d2b8
AM
2260 op1 = h->sym->symbol_vector;
2261 op2 = 0;
2262 }
2263 else
2264 {
2265 op1 = alpha_vms_get_sym_value (h->sym->code_section,
2266 h->sym->code_value);
2267 op2 = alpha_vms_get_sym_value (h->sym->section,
2268 h->sym->value);
2269 }
2270 }
2271 else
2272 {
2273 /* Undefined symbol. */
2274 op1 = 0;
2275 op2 = 0;
2276 }
81699544
AM
2277 if (!image_write_q (abfd, op1)
2278 || !image_write_q (abfd, op2))
0a1b45a2 2279 return false;
07d6d2b8
AM
2280 break;
2281
2282 /* 205 Store-conditional NOP at address of global
2283 arg: none. */
2284 case ETIR__C_STC_NOP_GBL:
2285 /* ALPHA_R_NOP */
2286
2287 /* 207 Store-conditional BSR at global address
2288 arg: none. */
2289
2290 case ETIR__C_STC_BSR_GBL:
2291 /* ALPHA_R_BSR */
2292
2293 /* 209 Store-conditional LDA at global address
2294 arg: none. */
2295
2296 case ETIR__C_STC_LDA_GBL:
2297 /* ALPHA_R_LDA */
2298
2299 /* 211 Store-conditional BSR or Hint at global address
2300 arg: none. */
2301
2302 case ETIR__C_STC_BOH_GBL:
2303 /* Currentl ignored. */
2304 break;
2305
2306 /* 213 Store-conditional NOP,BSR or HINT at global address
2307 arg: none. */
2308
2309 case ETIR__C_STC_NBH_GBL:
2310
2311 /* 206 Store-conditional NOP at pect + offset
2312 arg: none. */
2313
2314 case ETIR__C_STC_NOP_PS:
2315
2316 /* 208 Store-conditional BSR at pect + offset
2317 arg: none. */
2318
2319 case ETIR__C_STC_BSR_PS:
2320
2321 /* 210 Store-conditional LDA at psect + offset
2322 arg: none. */
2323
2324 case ETIR__C_STC_LDA_PS:
2325
2326 /* 212 Store-conditional BSR or Hint at pect + offset
2327 arg: none. */
2328
2329 case ETIR__C_STC_BOH_PS:
2330
2331 /* 214 Store-conditional NOP, BSR or HINT at psect + offset
2332 arg: none. */
2333 case ETIR__C_STC_NBH_PS:
695344c0 2334 _bfd_error_handler (_("%s: not supported"),
4eca0228 2335 _bfd_vms_etir_name (cmd));
0a1b45a2 2336 return false;
07d6d2b8
AM
2337 break;
2338
2339 /* Det relocation base: pop stack, set image location counter
2340 arg: none. */
2341 case ETIR__C_CTL_SETRB:
ab356be7 2342 if (!_bfd_vms_pop (abfd, &op1, &rel1))
0a1b45a2 2343 return false;
07d6d2b8
AM
2344 if (!(rel1 & RELC_SEC_BASE))
2345 abort ();
2346 image_set_ptr (abfd, op1, rel1 & RELC_MASK, info);
2347 break;
2348
2349 /* Augment relocation base: increment image location counter by offset
2350 arg: lw offset value. */
2351 case ETIR__C_CTL_AUGRB:
2fdb65f2 2352 if (cmd_length < 4)
c53d2e6d 2353 goto corrupt_etir;
07d6d2b8
AM
2354 op1 = bfd_getl32 (ptr);
2355 image_inc_ptr (abfd, op1);
2356 break;
2357
2358 /* Define location: pop index, save location counter under index
2359 arg: none. */
2360 case ETIR__C_CTL_DFLOC:
ab356be7 2361 if (!_bfd_vms_pop (abfd, &op1, &rel1))
0a1b45a2 2362 return false;
07d6d2b8
AM
2363 if (rel1 != RELC_NONE)
2364 goto bad_context;
9cb56943 2365 if (!dst_define_location (abfd, op1))
0a1b45a2 2366 return false;
07d6d2b8
AM
2367 break;
2368
2369 /* Set location: pop index, restore location counter from index
2370 arg: none. */
2371 case ETIR__C_CTL_STLOC:
ab356be7 2372 if (!_bfd_vms_pop (abfd, &op1, &rel1))
0a1b45a2 2373 return false;
07d6d2b8
AM
2374 if (rel1 != RELC_NONE)
2375 goto bad_context;
7bac4137
AM
2376 if (!dst_restore_location (abfd, op1))
2377 {
2378 bfd_set_error (bfd_error_bad_value);
2379 _bfd_error_handler (_("invalid %s"), "ETIR__C_CTL_STLOC");
0a1b45a2 2380 return false;
7bac4137 2381 }
07d6d2b8
AM
2382 break;
2383
2384 /* Stack defined location: pop index, push location counter from index
2385 arg: none. */
2386 case ETIR__C_CTL_STKDL:
ab356be7 2387 if (!_bfd_vms_pop (abfd, &op1, &rel1))
0a1b45a2 2388 return false;
07d6d2b8
AM
2389 if (rel1 != RELC_NONE)
2390 goto bad_context;
7bac4137
AM
2391 if (!dst_retrieve_location (abfd, &op1))
2392 {
2393 bfd_set_error (bfd_error_bad_value);
2394 _bfd_error_handler (_("invalid %s"), "ETIR__C_CTL_STKDL");
0a1b45a2 2395 return false;
7bac4137
AM
2396 }
2397 if (!_bfd_vms_push (abfd, op1, RELC_NONE))
0a1b45a2 2398 return false;
07d6d2b8
AM
2399 break;
2400
2401 case ETIR__C_OPR_NOP: /* No-op. */
2402 break;
2403
2404 case ETIR__C_OPR_ADD: /* Add. */
ab356be7
AM
2405 if (!_bfd_vms_pop (abfd, &op1, &rel1)
2406 || !_bfd_vms_pop (abfd, &op2, &rel2))
0a1b45a2 2407 return false;
07d6d2b8
AM
2408 if (rel1 == RELC_NONE && rel2 != RELC_NONE)
2409 rel1 = rel2;
2410 else if (rel1 != RELC_NONE && rel2 != RELC_NONE)
2411 goto bad_context;
ab356be7 2412 if (!_bfd_vms_push (abfd, op1 + op2, rel1))
0a1b45a2 2413 return false;
07d6d2b8
AM
2414 break;
2415
2416 case ETIR__C_OPR_SUB: /* Subtract. */
ab356be7
AM
2417 if (!_bfd_vms_pop (abfd, &op1, &rel1)
2418 || !_bfd_vms_pop (abfd, &op2, &rel2))
0a1b45a2 2419 return false;
07d6d2b8
AM
2420 if (rel1 == RELC_NONE && rel2 != RELC_NONE)
2421 rel1 = rel2;
2422 else if ((rel1 & RELC_SEC_BASE) && (rel2 & RELC_SEC_BASE))
2423 {
2424 op1 = alpha_vms_fix_sec_rel (abfd, info, rel1, op1);
2425 op2 = alpha_vms_fix_sec_rel (abfd, info, rel2, op2);
2426 rel1 = RELC_NONE;
2427 }
2428 else if (rel1 != RELC_NONE && rel2 != RELC_NONE)
2429 goto bad_context;
ab356be7 2430 if (!_bfd_vms_push (abfd, op2 - op1, rel1))
0a1b45a2 2431 return false;
07d6d2b8
AM
2432 break;
2433
2434 case ETIR__C_OPR_MUL: /* Multiply. */
ab356be7
AM
2435 if (!_bfd_vms_pop (abfd, &op1, &rel1)
2436 || !_bfd_vms_pop (abfd, &op2, &rel2))
0a1b45a2 2437 return false;
07d6d2b8
AM
2438 if (rel1 != RELC_NONE || rel2 != RELC_NONE)
2439 goto bad_context;
ab356be7 2440 if (!_bfd_vms_push (abfd, op1 * op2, RELC_NONE))
0a1b45a2 2441 return false;
07d6d2b8
AM
2442 break;
2443
2444 case ETIR__C_OPR_DIV: /* Divide. */
ab356be7
AM
2445 if (!_bfd_vms_pop (abfd, &op1, &rel1)
2446 || !_bfd_vms_pop (abfd, &op2, &rel2))
0a1b45a2 2447 return false;
07d6d2b8
AM
2448 if (rel1 != RELC_NONE || rel2 != RELC_NONE)
2449 goto bad_context;
48e5bada 2450 if (op1 == 0)
ab356be7 2451 {
48e5bada
AM
2452 /* Divide by zero is supposed to give a result of zero,
2453 and a non-fatal warning message. */
2454 _bfd_error_handler (_("%s divide by zero"), "ETIR__C_OPR_DIV");
ab356be7 2455 if (!_bfd_vms_push (abfd, 0, RELC_NONE))
0a1b45a2 2456 return false;
ab356be7 2457 }
07d6d2b8 2458 else
ab356be7
AM
2459 {
2460 if (!_bfd_vms_push (abfd, op2 / op1, RELC_NONE))
0a1b45a2 2461 return false;
ab356be7 2462 }
07d6d2b8
AM
2463 break;
2464
2465 case ETIR__C_OPR_AND: /* Logical AND. */
ab356be7
AM
2466 if (!_bfd_vms_pop (abfd, &op1, &rel1)
2467 || !_bfd_vms_pop (abfd, &op2, &rel2))
0a1b45a2 2468 return false;
07d6d2b8
AM
2469 if (rel1 != RELC_NONE || rel2 != RELC_NONE)
2470 goto bad_context;
ab356be7 2471 if (!_bfd_vms_push (abfd, op1 & op2, RELC_NONE))
0a1b45a2 2472 return false;
07d6d2b8
AM
2473 break;
2474
2475 case ETIR__C_OPR_IOR: /* Logical inclusive OR. */
ab356be7
AM
2476 if (!_bfd_vms_pop (abfd, &op1, &rel1)
2477 || !_bfd_vms_pop (abfd, &op2, &rel2))
0a1b45a2 2478 return false;
07d6d2b8
AM
2479 if (rel1 != RELC_NONE || rel2 != RELC_NONE)
2480 goto bad_context;
ab356be7 2481 if (!_bfd_vms_push (abfd, op1 | op2, RELC_NONE))
0a1b45a2 2482 return false;
07d6d2b8
AM
2483 break;
2484
2485 case ETIR__C_OPR_EOR: /* Logical exclusive OR. */
ab356be7
AM
2486 if (!_bfd_vms_pop (abfd, &op1, &rel1)
2487 || !_bfd_vms_pop (abfd, &op2, &rel2))
0a1b45a2 2488 return false;
07d6d2b8
AM
2489 if (rel1 != RELC_NONE || rel2 != RELC_NONE)
2490 goto bad_context;
ab356be7 2491 if (!_bfd_vms_push (abfd, op1 ^ op2, RELC_NONE))
0a1b45a2 2492 return false;
07d6d2b8
AM
2493 break;
2494
2495 case ETIR__C_OPR_NEG: /* Negate. */
ab356be7 2496 if (!_bfd_vms_pop (abfd, &op1, &rel1))
0a1b45a2 2497 return false;
07d6d2b8
AM
2498 if (rel1 != RELC_NONE)
2499 goto bad_context;
ab356be7 2500 if (!_bfd_vms_push (abfd, -op1, RELC_NONE))
0a1b45a2 2501 return false;
07d6d2b8
AM
2502 break;
2503
2504 case ETIR__C_OPR_COM: /* Complement. */
ab356be7 2505 if (!_bfd_vms_pop (abfd, &op1, &rel1))
0a1b45a2 2506 return false;
07d6d2b8
AM
2507 if (rel1 != RELC_NONE)
2508 goto bad_context;
ab356be7 2509 if (!_bfd_vms_push (abfd, ~op1, RELC_NONE))
0a1b45a2 2510 return false;
07d6d2b8
AM
2511 break;
2512
2513 case ETIR__C_OPR_ASH: /* Arithmetic shift. */
ab356be7
AM
2514 if (!_bfd_vms_pop (abfd, &op1, &rel1)
2515 || !_bfd_vms_pop (abfd, &op2, &rel2))
0a1b45a2 2516 return false;
07d6d2b8
AM
2517 if (rel1 != RELC_NONE || rel2 != RELC_NONE)
2518 {
2519 bad_context:
4eca0228
AM
2520 _bfd_error_handler (_("invalid use of %s with contexts"),
2521 _bfd_vms_etir_name (cmd));
0a1b45a2 2522 return false;
07d6d2b8 2523 }
f8b1e5f6
AM
2524 if ((bfd_signed_vma) op2 < 0)
2525 {
2526 /* Shift right. */
2527 bfd_vma sign;
2528 op2 = -op2;
2529 if (op2 >= CHAR_BIT * sizeof (op1))
2530 op2 = CHAR_BIT * sizeof (op1) - 1;
2531 /* op1 = (bfd_signed_vma) op1 >> op2; */
2532 sign = op1 & ((bfd_vma) 1 << (CHAR_BIT * sizeof (op1) - 1));
2533 op1 >>= op2;
2534 sign >>= op2;
2535 op1 = (op1 ^ sign) - sign;
2536 }
2537 else
2538 {
2539 /* Shift left. */
2540 if (op2 >= CHAR_BIT * sizeof (op1))
2541 op1 = 0;
2542 else
2543 op1 <<= op2;
2544 }
ab356be7 2545 if (!_bfd_vms_push (abfd, op1, RELC_NONE)) /* FIXME: sym. */
0a1b45a2 2546 return false;
07d6d2b8
AM
2547 break;
2548
2549 case ETIR__C_OPR_INSV: /* Insert field. */
2550 case ETIR__C_OPR_USH: /* Unsigned shift. */
2551 case ETIR__C_OPR_ROT: /* Rotate. */
2552 case ETIR__C_OPR_REDEF: /* Redefine symbol to current location. */
2553 case ETIR__C_OPR_DFLIT: /* Define a literal. */
4eca0228
AM
2554 _bfd_error_handler (_("%s: not supported"),
2555 _bfd_vms_etir_name (cmd));
0a1b45a2 2556 return false;
07d6d2b8
AM
2557 break;
2558
2559 case ETIR__C_OPR_SEL: /* Select. */
ab356be7 2560 if (!_bfd_vms_pop (abfd, &op1, &rel1))
0a1b45a2 2561 return false;
07d6d2b8 2562 if (op1 & 0x01L)
ab356be7
AM
2563 {
2564 if (!_bfd_vms_pop (abfd, &op1, &rel1))
0a1b45a2 2565 return false;
ab356be7 2566 }
07d6d2b8
AM
2567 else
2568 {
ab356be7
AM
2569 if (!_bfd_vms_pop (abfd, &op1, &rel1)
2570 || !_bfd_vms_pop (abfd, &op2, &rel2))
0a1b45a2 2571 return false;
ab356be7 2572 if (!_bfd_vms_push (abfd, op1, rel1))
0a1b45a2 2573 return false;
07d6d2b8
AM
2574 }
2575 break;
2576
2577 default:
4eca0228 2578 _bfd_error_handler (_("reserved cmd %d"), cmd);
0a1b45a2 2579 return false;
07d6d2b8
AM
2580 break;
2581 }
95e34ef7 2582
2fdb65f2 2583 ptr += cmd_length;
95e34ef7
TG
2584 }
2585
0a1b45a2 2586 return true;
95e34ef7
TG
2587}
2588
2589/* Process EDBG/ETBT record.
2590 Return TRUE on success, FALSE on error */
2591
0a1b45a2 2592static bool
95e34ef7
TG
2593vms_slurp_debug (bfd *abfd)
2594{
2595 asection *section = PRIV (dst_section);
2596
2597 if (section == NULL)
2598 {
2599 /* We have no way to find out beforehand how much debug info there
2600 is in an object file, so pick an initial amount and grow it as
2601 needed later. */
2602 flagword flags = SEC_HAS_CONTENTS | SEC_DEBUGGING | SEC_RELOC
07d6d2b8 2603 | SEC_IN_MEMORY;
95e34ef7
TG
2604
2605 section = bfd_make_section (abfd, "$DST$");
2606 if (!section)
0a1b45a2 2607 return false;
fd361982 2608 if (!bfd_set_section_flags (section, flags))
0a1b45a2 2609 return false;
95e34ef7
TG
2610 PRIV (dst_section) = section;
2611 }
2612
2613 PRIV (image_section) = section;
2614 PRIV (image_offset) = section->size;
95e34ef7
TG
2615
2616 if (!_bfd_vms_slurp_etir (abfd, NULL))
0a1b45a2 2617 return false;
95e34ef7 2618
44273c5b 2619 section->size = PRIV (image_offset);
0a1b45a2 2620 return true;
95e34ef7
TG
2621}
2622
2623/* Process EDBG record.
2624 Return TRUE on success, FALSE on error. */
2625
0a1b45a2 2626static bool
95e34ef7
TG
2627_bfd_vms_slurp_edbg (bfd *abfd)
2628{
2629 vms_debug2 ((2, "EDBG\n"));
2630
44273c5b 2631 abfd->flags |= HAS_DEBUG | HAS_LINENO;
95e34ef7
TG
2632
2633 return vms_slurp_debug (abfd);
2634}
2635
2636/* Process ETBT record.
2637 Return TRUE on success, FALSE on error. */
2638
0a1b45a2 2639static bool
95e34ef7
TG
2640_bfd_vms_slurp_etbt (bfd *abfd)
2641{
2642 vms_debug2 ((2, "ETBT\n"));
2643
2644 abfd->flags |= HAS_LINENO;
2645
2646 return vms_slurp_debug (abfd);
2647}
2648
2649/* Process EEOM record.
2650 Return TRUE on success, FALSE on error. */
2651
0a1b45a2 2652static bool
95e34ef7
TG
2653_bfd_vms_slurp_eeom (bfd *abfd)
2654{
2655 struct vms_eeom *eeom = (struct vms_eeom *) PRIV (recrd.rec);
2656
2657 vms_debug2 ((2, "EEOM\n"));
2658
ca4cf9b9
NC
2659 /* PR 21813: Check for an undersized record. */
2660 if (PRIV (recrd.buf_size) < sizeof (* eeom))
2661 {
38f14ab8 2662 _bfd_error_handler (_("corrupt EEOM record - size is too small"));
ca4cf9b9 2663 bfd_set_error (bfd_error_bad_value);
0a1b45a2 2664 return false;
ca4cf9b9
NC
2665 }
2666
95e34ef7
TG
2667 PRIV (eom_data).eom_l_total_lps = bfd_getl32 (eeom->total_lps);
2668 PRIV (eom_data).eom_w_comcod = bfd_getl16 (eeom->comcod);
2669 if (PRIV (eom_data).eom_w_comcod > 1)
2670 {
38f14ab8 2671 _bfd_error_handler (_("object module not error-free !"));
95e34ef7 2672 bfd_set_error (bfd_error_bad_value);
0a1b45a2 2673 return false;
95e34ef7
TG
2674 }
2675
0a1b45a2 2676 PRIV (eom_data).eom_has_transfer = false;
95e34ef7
TG
2677 if (PRIV (recrd.rec_size) > 10)
2678 {
0a1b45a2 2679 PRIV (eom_data).eom_has_transfer = true;
95e34ef7
TG
2680 PRIV (eom_data).eom_b_tfrflg = eeom->tfrflg;
2681 PRIV (eom_data).eom_l_psindx = bfd_getl32 (eeom->psindx);
2682 PRIV (eom_data).eom_l_tfradr = bfd_getl32 (eeom->tfradr);
2683
2684 abfd->start_address = PRIV (eom_data).eom_l_tfradr;
2685 }
0a1b45a2 2686 return true;
95e34ef7
TG
2687}
2688
2689/* Slurp an ordered set of VMS object records. Return FALSE on error. */
2690
0a1b45a2 2691static bool
95e34ef7
TG
2692_bfd_vms_slurp_object_records (bfd * abfd)
2693{
0a1b45a2 2694 bool ok;
44273c5b 2695 int type;
95e34ef7
TG
2696
2697 do
2698 {
2699 vms_debug2 ((7, "reading at %08lx\n", (unsigned long)bfd_tell (abfd)));
2700
44273c5b
TG
2701 type = _bfd_vms_get_object_record (abfd);
2702 if (type < 0)
95e34ef7
TG
2703 {
2704 vms_debug2 ((2, "next_record failed\n"));
0a1b45a2 2705 return false;
95e34ef7
TG
2706 }
2707
95e34ef7
TG
2708 switch (type)
2709 {
07d6d2b8 2710 case EOBJ__C_EMH:
f75fbe8a 2711 ok = _bfd_vms_slurp_ehdr (abfd);
07d6d2b8
AM
2712 break;
2713 case EOBJ__C_EEOM:
f75fbe8a 2714 ok = _bfd_vms_slurp_eeom (abfd);
07d6d2b8
AM
2715 break;
2716 case EOBJ__C_EGSD:
f75fbe8a 2717 ok = _bfd_vms_slurp_egsd (abfd);
07d6d2b8
AM
2718 break;
2719 case EOBJ__C_ETIR:
0a1b45a2 2720 ok = true; /* _bfd_vms_slurp_etir (abfd); */
07d6d2b8
AM
2721 break;
2722 case EOBJ__C_EDBG:
f75fbe8a 2723 ok = _bfd_vms_slurp_edbg (abfd);
07d6d2b8
AM
2724 break;
2725 case EOBJ__C_ETBT:
f75fbe8a 2726 ok = _bfd_vms_slurp_etbt (abfd);
07d6d2b8
AM
2727 break;
2728 default:
0a1b45a2 2729 ok = false;
95e34ef7 2730 }
f75fbe8a 2731 if (!ok)
95e34ef7
TG
2732 {
2733 vms_debug2 ((2, "slurp type %d failed\n", type));
0a1b45a2 2734 return false;
95e34ef7
TG
2735 }
2736 }
2737 while (type != EOBJ__C_EEOM);
2738
0a1b45a2 2739 return true;
95e34ef7
TG
2740}
2741
2742/* Initialize private data */
0a1b45a2 2743static bool
95e34ef7
TG
2744vms_initialize (bfd * abfd)
2745{
986f0783 2746 size_t amt;
95e34ef7
TG
2747
2748 amt = sizeof (struct vms_private_data_struct);
2749 abfd->tdata.any = bfd_zalloc (abfd, amt);
2750 if (abfd->tdata.any == NULL)
0a1b45a2 2751 return false;
95e34ef7
TG
2752
2753 PRIV (recrd.file_format) = FF_UNKNOWN;
2754
2755 amt = sizeof (struct stack_struct) * STACKSIZE;
2756 PRIV (stack) = bfd_alloc (abfd, amt);
2757 if (PRIV (stack) == NULL)
2758 goto error_ret1;
2759
0a1b45a2 2760 return true;
95e34ef7
TG
2761
2762 error_ret1:
2763 bfd_release (abfd, abfd->tdata.any);
2764 abfd->tdata.any = NULL;
0a1b45a2 2765 return false;
95e34ef7
TG
2766}
2767
a7ac9aa5
AM
2768/* Free malloc'd memory. */
2769
2770static void
2771alpha_vms_free_private (bfd *abfd)
2772{
2773 struct module *module;
2774
2775 free (PRIV (recrd.buf));
2776 free (PRIV (sections));
2777 free (PRIV (syms));
2778 free (PRIV (dst_ptr_offsets));
2779
2780 for (module = PRIV (modules); module; module = module->next)
2781 free (module->file_table);
2782}
2783
95e34ef7
TG
2784/* Check the format for a file being read.
2785 Return a (bfd_target *) if it's an object file or zero if not. */
2786
cb001c0d 2787static bfd_cleanup
95e34ef7
TG
2788alpha_vms_object_p (bfd *abfd)
2789{
8185f55c 2790 void *tdata_save = abfd->tdata.any;
95e34ef7
TG
2791 unsigned int test_len;
2792 unsigned char *buf;
2793
2794 vms_debug2 ((1, "vms_object_p(%p)\n", abfd));
2795
2796 /* Allocate alpha-vms specific data. */
2797 if (!vms_initialize (abfd))
a7ac9aa5
AM
2798 {
2799 abfd->tdata.any = tdata_save;
2800 return NULL;
2801 }
95e34ef7
TG
2802
2803 if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET))
1b088c82 2804 goto error_ret;
95e34ef7
TG
2805
2806 /* The first challenge with VMS is to discover the kind of the file.
2807
2808 Image files (executable or shared images) are stored as a raw
2809 stream of bytes (like on UNIX), but there is no magic number.
2810
2811 Object files are written with RMS (record management service), ie
2812 each records are preceeded by its length (on a word - 2 bytes), and
2813 padded for word-alignment. That would be simple but when files
2814 are transfered to a UNIX filesystem (using ftp), records are lost.
2815 Only the raw content of the records are transfered. Fortunately,
2816 the Alpha Object file format also store the length of the record
2817 in the records. Is that clear ? */
2818
2819 /* Minimum is 6 bytes for objects (2 bytes size, 2 bytes record id,
2820 2 bytes size repeated) and 12 bytes for images (4 bytes major id,
2821 4 bytes minor id, 4 bytes length). */
2822 test_len = 12;
1b088c82 2823 buf = _bfd_malloc_and_read (abfd, test_len, test_len);
95e34ef7
TG
2824 if (buf == NULL)
2825 goto error_ret;
2826 PRIV (recrd.buf) = buf;
2827 PRIV (recrd.buf_size) = test_len;
95e34ef7
TG
2828 PRIV (recrd.rec) = buf;
2829
95e34ef7
TG
2830 /* Is it an image? */
2831 if ((bfd_getl32 (buf) == EIHD__K_MAJORID)
2832 && (bfd_getl32 (buf + 4) == EIHD__K_MINORID))
2833 {
95e34ef7
TG
2834 unsigned int eisd_offset, eihs_offset;
2835
2836 /* Extract the header size. */
2837 PRIV (recrd.rec_size) = bfd_getl32 (buf + EIHD__L_SIZE);
2838
af47dcbf
TG
2839 /* The header size is 0 for DSF files. */
2840 if (PRIV (recrd.rec_size) == 0)
07d6d2b8 2841 PRIV (recrd.rec_size) = sizeof (struct vms_eihd);
af47dcbf 2842
8a2df5e2 2843 /* PR 21813: Check for a truncated record. */
1b088c82
AM
2844 /* PR 17512: file: 7d7c57c2. */
2845 if (PRIV (recrd.rec_size) < sizeof (struct vms_eihd))
2846 goto err_wrong_format;
95e34ef7 2847
1b088c82
AM
2848 if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET))
2849 goto error_ret;
95e34ef7 2850
1b088c82
AM
2851 free (PRIV (recrd.buf));
2852 PRIV (recrd.buf) = NULL;
2853 buf = _bfd_malloc_and_read (abfd, PRIV (recrd.rec_size),
2854 PRIV (recrd.rec_size));
2855 if (buf == NULL)
2856 goto error_ret;
95e34ef7 2857
1b088c82
AM
2858 PRIV (recrd.buf) = buf;
2859 PRIV (recrd.buf_size) = PRIV (recrd.rec_size);
95e34ef7
TG
2860 PRIV (recrd.rec) = buf;
2861
2862 vms_debug2 ((2, "file type is image\n"));
2863
535b785f 2864 if (!_bfd_vms_slurp_eihd (abfd, &eisd_offset, &eihs_offset))
07d6d2b8 2865 goto err_wrong_format;
95e34ef7 2866
535b785f 2867 if (!_bfd_vms_slurp_eisd (abfd, eisd_offset))
07d6d2b8 2868 goto err_wrong_format;
95e34ef7
TG
2869
2870 /* EIHS is optional. */
535b785f 2871 if (eihs_offset != 0 && !_bfd_vms_slurp_eihs (abfd, eihs_offset))
07d6d2b8 2872 goto err_wrong_format;
95e34ef7
TG
2873 }
2874 else
2875 {
2876 int type;
2877
2878 /* Assume it's a module and adjust record pointer if necessary. */
2879 maybe_adjust_record_pointer_for_object (abfd);
2880
2881 /* But is it really a module? */
2882 if (bfd_getl16 (PRIV (recrd.rec)) <= EOBJ__C_MAXRECTYP
07d6d2b8
AM
2883 && bfd_getl16 (PRIV (recrd.rec) + 2) <= EOBJ__C_MAXRECSIZ)
2884 {
2885 if (vms_get_remaining_object_record (abfd, test_len) <= 0)
2886 goto err_wrong_format;
95e34ef7 2887
07d6d2b8 2888 vms_debug2 ((2, "file type is module\n"));
95e34ef7 2889
07d6d2b8
AM
2890 type = bfd_getl16 (PRIV (recrd.rec));
2891 if (type != EOBJ__C_EMH || !_bfd_vms_slurp_ehdr (abfd))
2892 goto err_wrong_format;
95e34ef7 2893
07d6d2b8
AM
2894 if (!_bfd_vms_slurp_object_records (abfd))
2895 goto err_wrong_format;
2896 }
95e34ef7 2897 else
07d6d2b8 2898 goto err_wrong_format;
95e34ef7
TG
2899 }
2900
2901 /* Set arch_info to alpha. */
2902
2903 if (! bfd_default_set_arch_mach (abfd, bfd_arch_alpha, 0))
2904 goto err_wrong_format;
2905
cb001c0d 2906 return alpha_vms_free_private;
95e34ef7
TG
2907
2908 err_wrong_format:
2909 bfd_set_error (bfd_error_wrong_format);
2910
2911 error_ret:
a7ac9aa5 2912 alpha_vms_free_private (abfd);
95e34ef7
TG
2913 if (abfd->tdata.any != tdata_save && abfd->tdata.any != NULL)
2914 bfd_release (abfd, abfd->tdata.any);
2915 abfd->tdata.any = tdata_save;
2916 return NULL;
2917}
2918\f
2919/* Image write. */
2920
bd7b51b4
TG
2921/* Write an EMH/MHD record. */
2922
2923static void
2924_bfd_vms_write_emh (bfd *abfd)
2925{
2926 struct vms_rec_wr *recwr = &PRIV (recwr);
7fbd5f4e 2927 unsigned char tbuf[18];
bd7b51b4
TG
2928
2929 _bfd_vms_output_alignment (recwr, 2);
2930
2931 /* EMH. */
2932 _bfd_vms_output_begin (recwr, EOBJ__C_EMH);
2933 _bfd_vms_output_short (recwr, EMH__C_MHD);
2934 _bfd_vms_output_short (recwr, EOBJ__C_STRLVL);
2935 _bfd_vms_output_long (recwr, 0);
2936 _bfd_vms_output_long (recwr, 0);
2937 _bfd_vms_output_long (recwr, MAX_OUTREC_SIZE);
2938
2939 /* Create module name from filename. */
2940 if (bfd_get_filename (abfd) != 0)
2941 {
0a1b45a2 2942 char *module = vms_get_module_name (bfd_get_filename (abfd), true);
bd7b51b4
TG
2943 _bfd_vms_output_counted (recwr, module);
2944 free (module);
2945 }
2946 else
2947 _bfd_vms_output_counted (recwr, "NONAME");
2948
2949 _bfd_vms_output_counted (recwr, BFD_VERSION_STRING);
7fbd5f4e 2950 _bfd_vms_output_dump (recwr, get_vms_time_string (tbuf), EMH_DATE_LENGTH);
bd7b51b4
TG
2951 _bfd_vms_output_fill (recwr, 0, EMH_DATE_LENGTH);
2952 _bfd_vms_output_end (abfd, recwr);
2953}
2954
2955/* Write an EMH/LMN record. */
2956
2957static void
2958_bfd_vms_write_lmn (bfd *abfd, const char *name)
2959{
2960 char version [64];
2961 struct vms_rec_wr *recwr = &PRIV (recwr);
2962 unsigned int ver = BFD_VERSION / 10000;
2963
2964 /* LMN. */
2965 _bfd_vms_output_begin (recwr, EOBJ__C_EMH);
2966 _bfd_vms_output_short (recwr, EMH__C_LNM);
2967 snprintf (version, sizeof (version), "%s %d.%d.%d", name,
07d6d2b8 2968 ver / 10000, (ver / 100) % 100, ver % 100);
bd7b51b4
TG
2969 _bfd_vms_output_dump (recwr, (unsigned char *)version, strlen (version));
2970 _bfd_vms_output_end (abfd, recwr);
2971}
2972
2973
2974/* Write eom record for bfd abfd. Return FALSE on error. */
2975
0a1b45a2 2976static bool
bd7b51b4
TG
2977_bfd_vms_write_eeom (bfd *abfd)
2978{
2979 struct vms_rec_wr *recwr = &PRIV (recwr);
2980
2981 vms_debug2 ((2, "vms_write_eeom\n"));
2982
2983 _bfd_vms_output_alignment (recwr, 2);
2984
2985 _bfd_vms_output_begin (recwr, EOBJ__C_EEOM);
f1bb0388 2986 _bfd_vms_output_long (recwr, PRIV (vms_linkage_index + 1) >> 1);
bd7b51b4
TG
2987 _bfd_vms_output_byte (recwr, 0); /* Completion code. */
2988 _bfd_vms_output_byte (recwr, 0); /* Fill byte. */
2989
2990 if ((abfd->flags & EXEC_P) == 0
2991 && bfd_get_start_address (abfd) != (bfd_vma)-1)
2992 {
2993 asection *section;
2994
2995 section = bfd_get_section_by_name (abfd, ".link");
2996 if (section == 0)
2997 {
2998 bfd_set_error (bfd_error_nonrepresentable_section);
0a1b45a2 2999 return false;
bd7b51b4
TG
3000 }
3001 _bfd_vms_output_short (recwr, 0);
1b3d1dbf 3002 _bfd_vms_output_long (recwr, (unsigned long) section->target_index);
bd7b51b4
TG
3003 _bfd_vms_output_long (recwr,
3004 (unsigned long) bfd_get_start_address (abfd));
3005 _bfd_vms_output_long (recwr, 0);
3006 }
3007
3008 _bfd_vms_output_end (abfd, recwr);
0a1b45a2 3009 return true;
bd7b51b4
TG
3010}
3011
96d3b80f 3012static void *
95e34ef7
TG
3013vector_grow1 (struct vector_type *vec, size_t elsz)
3014{
96d3b80f 3015 if (vec->nbr_el >= vec->max_el)
95e34ef7 3016 {
96d3b80f
AM
3017 if (vec->max_el == 0)
3018 {
3019 vec->max_el = 16;
1f4361a7 3020 vec->els = bfd_malloc (vec->max_el * elsz);
96d3b80f
AM
3021 }
3022 else
3023 {
1f4361a7 3024 size_t amt;
96d3b80f
AM
3025 if (vec->max_el > -1u / 2)
3026 {
3027 bfd_set_error (bfd_error_file_too_big);
3028 return NULL;
3029 }
3030 vec->max_el *= 2;
1f4361a7
AM
3031 if (_bfd_mul_overflow (vec->max_el, elsz, &amt))
3032 {
3033 bfd_set_error (bfd_error_file_too_big);
3034 return NULL;
3035 }
9cb56943 3036 vec->els = bfd_realloc_or_free (vec->els, amt);
96d3b80f 3037 }
95e34ef7 3038 }
96d3b80f
AM
3039 if (vec->els == NULL)
3040 return NULL;
3041 return (char *) vec->els + elsz * vec->nbr_el++;
95e34ef7
TG
3042}
3043
3044/* Bump ABFD file position to next block. */
3045
3046static void
3047alpha_vms_file_position_block (bfd *abfd)
3048{
3049 /* Next block. */
3050 PRIV (file_pos) += VMS_BLOCK_SIZE - 1;
3051 PRIV (file_pos) -= (PRIV (file_pos) % VMS_BLOCK_SIZE);
3052}
3053
44273c5b
TG
3054/* Convert from internal structure SRC to external structure DST. */
3055
95e34ef7
TG
3056static void
3057alpha_vms_swap_eisd_out (struct vms_internal_eisd_map *src,
07d6d2b8 3058 struct vms_eisd *dst)
95e34ef7
TG
3059{
3060 bfd_putl32 (src->u.eisd.majorid, dst->majorid);
3061 bfd_putl32 (src->u.eisd.minorid, dst->minorid);
3062 bfd_putl32 (src->u.eisd.eisdsize, dst->eisdsize);
3063 if (src->u.eisd.eisdsize <= EISD__K_LENEND)
3064 return;
3065 bfd_putl32 (src->u.eisd.secsize, dst->secsize);
3066 bfd_putl64 (src->u.eisd.virt_addr, dst->virt_addr);
3067 bfd_putl32 (src->u.eisd.flags, dst->flags);
3068 bfd_putl32 (src->u.eisd.vbn, dst->vbn);
3069 dst->pfc = src->u.eisd.pfc;
3070 dst->matchctl = src->u.eisd.matchctl;
3071 dst->type = src->u.eisd.type;
3072 dst->fill_1 = 0;
3073 if (src->u.eisd.flags & EISD__M_GBL)
3074 {
3075 bfd_putl32 (src->u.gbl_eisd.ident, dst->ident);
3076 memcpy (dst->gblnam, src->u.gbl_eisd.gblnam,
07d6d2b8 3077 src->u.gbl_eisd.gblnam[0] + 1);
95e34ef7
TG
3078 }
3079}
3080
3081/* Append EISD to the list of extra eisd for ABFD. */
3082
3083static void
3084alpha_vms_append_extra_eisd (bfd *abfd, struct vms_internal_eisd_map *eisd)
3085{
3086 eisd->next = NULL;
3087 if (PRIV (gbl_eisd_head) == NULL)
3088 PRIV (gbl_eisd_head) = eisd;
3089 else
3090 PRIV (gbl_eisd_tail)->next = eisd;
3091 PRIV (gbl_eisd_tail) = eisd;
3092}
3093
44273c5b
TG
3094/* Create an EISD for shared image SHRIMG.
3095 Return FALSE in case of error. */
3096
0a1b45a2 3097static bool
95e34ef7
TG
3098alpha_vms_create_eisd_for_shared (bfd *abfd, bfd *shrimg)
3099{
3100 struct vms_internal_eisd_map *eisd;
3101 int namlen;
3102
3103 namlen = strlen (PRIV2 (shrimg, hdr_data.hdr_t_name));
3104 if (namlen + 5 > EISD__K_GBLNAMLEN)
3105 {
3106 /* Won't fit. */
0a1b45a2 3107 return false;
95e34ef7
TG
3108 }
3109
3110 eisd = bfd_alloc (abfd, sizeof (*eisd));
3111 if (eisd == NULL)
0a1b45a2 3112 return false;
95e34ef7
TG
3113
3114 /* Fill the fields. */
3115 eisd->u.gbl_eisd.common.majorid = EISD__K_MAJORID;
3116 eisd->u.gbl_eisd.common.minorid = EISD__K_MINORID;
3117 eisd->u.gbl_eisd.common.eisdsize = (EISD__K_LEN + 4 + namlen + 5 + 3) & ~3;
3118 eisd->u.gbl_eisd.common.secsize = VMS_BLOCK_SIZE; /* Must not be 0. */
3119 eisd->u.gbl_eisd.common.virt_addr = 0;
3120 eisd->u.gbl_eisd.common.flags = EISD__M_GBL;
3121 eisd->u.gbl_eisd.common.vbn = 0;
3122 eisd->u.gbl_eisd.common.pfc = 0;
3123 eisd->u.gbl_eisd.common.matchctl = PRIV2 (shrimg, matchctl);
3124 eisd->u.gbl_eisd.common.type = EISD__K_SHRPIC;
3125
3126 eisd->u.gbl_eisd.ident = PRIV2 (shrimg, ident);
3127 eisd->u.gbl_eisd.gblnam[0] = namlen + 4;
3128 memcpy (eisd->u.gbl_eisd.gblnam + 1, PRIV2 (shrimg, hdr_data.hdr_t_name),
07d6d2b8 3129 namlen);
95e34ef7
TG
3130 memcpy (eisd->u.gbl_eisd.gblnam + 1 + namlen, "_001", 4);
3131
3132 /* Append it to the list. */
3133 alpha_vms_append_extra_eisd (abfd, eisd);
3134
0a1b45a2 3135 return true;
95e34ef7
TG
3136}
3137
44273c5b
TG
3138/* Create an EISD for section SEC.
3139 Return FALSE in case of failure. */
3140
0a1b45a2 3141static bool
95e34ef7
TG
3142alpha_vms_create_eisd_for_section (bfd *abfd, asection *sec)
3143{
3144 struct vms_internal_eisd_map *eisd;
3145
3146 /* Only for allocating section. */
3147 if (!(sec->flags & SEC_ALLOC))
0a1b45a2 3148 return true;
95e34ef7
TG
3149
3150 BFD_ASSERT (vms_section_data (sec)->eisd == NULL);
3151 eisd = bfd_alloc (abfd, sizeof (*eisd));
3152 if (eisd == NULL)
0a1b45a2 3153 return false;
95e34ef7
TG
3154 vms_section_data (sec)->eisd = eisd;
3155
3156 /* Fill the fields. */
3157 eisd->u.eisd.majorid = EISD__K_MAJORID;
3158 eisd->u.eisd.minorid = EISD__K_MINORID;
3159 eisd->u.eisd.eisdsize = EISD__K_LEN;
3160 eisd->u.eisd.secsize =
3161 (sec->size + VMS_BLOCK_SIZE - 1) & ~(VMS_BLOCK_SIZE - 1);
3162 eisd->u.eisd.virt_addr = sec->vma;
3163 eisd->u.eisd.flags = 0;
3164 eisd->u.eisd.vbn = 0; /* To be later defined. */
3165 eisd->u.eisd.pfc = 0; /* Default. */
3166 eisd->u.eisd.matchctl = EISD__K_MATALL;
3167 eisd->u.eisd.type = EISD__K_NORMAL;
3168
3169 if (sec->flags & SEC_CODE)
3170 eisd->u.eisd.flags |= EISD__M_EXE;
cf6b8767 3171 if (!(sec->flags & SEC_READONLY))
95e34ef7
TG
3172 eisd->u.eisd.flags |= EISD__M_WRT | EISD__M_CRF;
3173
5f101a3d
TG
3174 /* If relocations or fixup will be applied, make this isect writeable. */
3175 if (sec->flags & SEC_RELOC)
3176 eisd->u.eisd.flags |= EISD__M_WRT | EISD__M_CRF;
3177
8185f55c 3178 if (!(sec->flags & SEC_HAS_CONTENTS))
95e34ef7
TG
3179 {
3180 eisd->u.eisd.flags |= EISD__M_DZRO;
3181 eisd->u.eisd.flags &= ~EISD__M_CRF;
3182 }
3183 if (sec->flags & SEC_LINKER_CREATED)
3184 {
3185 if (strcmp (sec->name, "$FIXUP$") == 0)
07d6d2b8 3186 eisd->u.eisd.flags |= EISD__M_FIXUPVEC;
95e34ef7
TG
3187 }
3188
3189 /* Append it to the list. */
3190 eisd->next = NULL;
3191 if (PRIV (eisd_head) == NULL)
3192 PRIV (eisd_head) = eisd;
3193 else
3194 PRIV (eisd_tail)->next = eisd;
3195 PRIV (eisd_tail) = eisd;
3196
0a1b45a2 3197 return true;
95e34ef7
TG
3198}
3199
44273c5b
TG
3200/* Layout executable ABFD and write it to the disk.
3201 Return FALSE in case of failure. */
3202
0a1b45a2 3203static bool
95e34ef7
TG
3204alpha_vms_write_exec (bfd *abfd)
3205{
3206 struct vms_eihd eihd;
3207 struct vms_eiha *eiha;
3208 struct vms_eihi *eihi;
3209 struct vms_eihs *eihs = NULL;
3210 asection *sec;
3211 struct vms_internal_eisd_map *first_eisd;
3212 struct vms_internal_eisd_map *eisd;
3213 asection *dst;
44273c5b 3214 asection *dmt;
f9eeb9c9
TG
3215 file_ptr gst_filepos = 0;
3216 unsigned int lnkflags = 0;
95e34ef7 3217
44273c5b 3218 /* Build the EIHD. */
95e34ef7
TG
3219 PRIV (file_pos) = EIHD__C_LENGTH;
3220
3221 memset (&eihd, 0, sizeof (eihd));
3222 memset (eihd.fill_2, 0xff, sizeof (eihd.fill_2));
3223
3224 bfd_putl32 (EIHD__K_MAJORID, eihd.majorid);
3225 bfd_putl32 (EIHD__K_MINORID, eihd.minorid);
3226
3227 bfd_putl32 (sizeof (eihd), eihd.size);
3228 bfd_putl32 (0, eihd.isdoff);
3229 bfd_putl32 (0, eihd.activoff);
3230 bfd_putl32 (0, eihd.symdbgoff);
3231 bfd_putl32 (0, eihd.imgidoff);
3232 bfd_putl32 (0, eihd.patchoff);
3233 bfd_putl64 (0, eihd.iafva);
3234 bfd_putl32 (0, eihd.version_array_off);
3235
3236 bfd_putl32 (EIHD__K_EXE, eihd.imgtype);
3237 bfd_putl32 (0, eihd.subtype);
3238
3239 bfd_putl32 (0, eihd.imgiocnt);
3240 bfd_putl32 (-1, eihd.privreqs);
3241 bfd_putl32 (-1, eihd.privreqs + 4);
3242
3243 bfd_putl32 ((sizeof (eihd) + VMS_BLOCK_SIZE - 1) / VMS_BLOCK_SIZE,
07d6d2b8 3244 eihd.hdrblkcnt);
95e34ef7
TG
3245 bfd_putl32 (0, eihd.ident);
3246 bfd_putl32 (0, eihd.sysver);
3247
3248 eihd.matchctl = 0;
3249 bfd_putl32 (0, eihd.symvect_size);
3250 bfd_putl32 (16, eihd.virt_mem_block_size);
3251 bfd_putl32 (0, eihd.ext_fixup_off);
3252 bfd_putl32 (0, eihd.noopt_psect_off);
5cbc0eb0 3253 bfd_putl16 (-1, eihd.alias);
95e34ef7
TG
3254
3255 /* Alloc EIHA. */
3256 eiha = (struct vms_eiha *)((char *) &eihd + PRIV (file_pos));
3257 bfd_putl32 (PRIV (file_pos), eihd.activoff);
3258 PRIV (file_pos) += sizeof (struct vms_eiha);
3259
3260 bfd_putl32 (sizeof (struct vms_eiha), eiha->size);
3261 bfd_putl32 (0, eiha->spare);
46d00b8a
TG
3262 bfd_putl64 (PRIV (transfer_address[0]), eiha->tfradr1);
3263 bfd_putl64 (PRIV (transfer_address[1]), eiha->tfradr2);
3264 bfd_putl64 (PRIV (transfer_address[2]), eiha->tfradr3);
3265 bfd_putl64 (PRIV (transfer_address[3]), eiha->tfradr4);
95e34ef7
TG
3266 bfd_putl64 (0, eiha->inishr);
3267
3268 /* Alloc EIHI. */
3269 eihi = (struct vms_eihi *)((char *) &eihd + PRIV (file_pos));
3270 bfd_putl32 (PRIV (file_pos), eihd.imgidoff);
3271 PRIV (file_pos) += sizeof (struct vms_eihi);
3272
3273 bfd_putl32 (EIHI__K_MAJORID, eihi->majorid);
3274 bfd_putl32 (EIHI__K_MINORID, eihi->minorid);
3275 {
3276 char *module;
3277 unsigned int len;
3278
9714ee48 3279 /* Set module name. */
0a1b45a2 3280 module = vms_get_module_name (bfd_get_filename (abfd), true);
95e34ef7
TG
3281 len = strlen (module);
3282 if (len > sizeof (eihi->imgnam) - 1)
3283 len = sizeof (eihi->imgnam) - 1;
3284 eihi->imgnam[0] = len;
3285 memcpy (eihi->imgnam + 1, module, len);
3286 free (module);
3287 }
9714ee48
TG
3288 {
3289 unsigned int lo;
3290 unsigned int hi;
3291
3292 /* Set time. */
3293 vms_get_time (&hi, &lo);
3294 bfd_putl32 (lo, eihi->linktime + 0);
3295 bfd_putl32 (hi, eihi->linktime + 4);
3296 }
95e34ef7
TG
3297 eihi->imgid[0] = 0;
3298 eihi->linkid[0] = 0;
3299 eihi->imgbid[0] = 0;
3300
3301 /* Alloc EIHS. */
44273c5b
TG
3302 dst = PRIV (dst_section);
3303 dmt = bfd_get_section_by_name (abfd, "$DMT$");
95e34ef7
TG
3304 if (dst != NULL && dst->size != 0)
3305 {
3306 eihs = (struct vms_eihs *)((char *) &eihd + PRIV (file_pos));
3307 bfd_putl32 (PRIV (file_pos), eihd.symdbgoff);
3308 PRIV (file_pos) += sizeof (struct vms_eihs);
3309
3310 bfd_putl32 (EIHS__K_MAJORID, eihs->majorid);
3311 bfd_putl32 (EIHS__K_MINORID, eihs->minorid);
3312 bfd_putl32 (0, eihs->dstvbn);
3313 bfd_putl32 (0, eihs->dstsize);
3314 bfd_putl32 (0, eihs->gstvbn);
3315 bfd_putl32 (0, eihs->gstsize);
3316 bfd_putl32 (0, eihs->dmtvbn);
3317 bfd_putl32 (0, eihs->dmtsize);
3318 }
3319
44273c5b 3320 /* One EISD per section. */
95e34ef7
TG
3321 for (sec = abfd->sections; sec; sec = sec->next)
3322 {
3323 if (!alpha_vms_create_eisd_for_section (abfd, sec))
0a1b45a2 3324 return false;
95e34ef7
TG
3325 }
3326
3327 /* Merge section EIDS which extra ones. */
3328 if (PRIV (eisd_tail))
3329 PRIV (eisd_tail)->next = PRIV (gbl_eisd_head);
3330 else
3331 PRIV (eisd_head) = PRIV (gbl_eisd_head);
3332 if (PRIV (gbl_eisd_tail))
3333 PRIV (eisd_tail) = PRIV (gbl_eisd_tail);
3334
3335 first_eisd = PRIV (eisd_head);
3336
3337 /* Add end of eisd. */
3338 if (first_eisd)
3339 {
3340 eisd = bfd_zalloc (abfd, sizeof (*eisd));
3341 if (eisd == NULL)
0a1b45a2 3342 return false;
95e34ef7
TG
3343 eisd->u.eisd.majorid = 0;
3344 eisd->u.eisd.minorid = 0;
3345 eisd->u.eisd.eisdsize = 0;
3346 alpha_vms_append_extra_eisd (abfd, eisd);
3347 }
3348
3349 /* Place EISD in the file. */
3350 for (eisd = first_eisd; eisd; eisd = eisd->next)
3351 {
3352 file_ptr room = VMS_BLOCK_SIZE - (PRIV (file_pos) % VMS_BLOCK_SIZE);
3353
3354 /* First block is a little bit special: there is a word at the end. */
3355 if (PRIV (file_pos) < VMS_BLOCK_SIZE && room > 2)
07d6d2b8 3356 room -= 2;
95e34ef7 3357 if (room < eisd->u.eisd.eisdsize + EISD__K_LENEND)
07d6d2b8 3358 alpha_vms_file_position_block (abfd);
95e34ef7
TG
3359
3360 eisd->file_pos = PRIV (file_pos);
3361 PRIV (file_pos) += eisd->u.eisd.eisdsize;
3362
3363 if (eisd->u.eisd.flags & EISD__M_FIXUPVEC)
07d6d2b8 3364 bfd_putl64 (eisd->u.eisd.virt_addr, eihd.iafva);
95e34ef7
TG
3365 }
3366
3367 if (first_eisd != NULL)
3368 {
3369 bfd_putl32 (first_eisd->file_pos, eihd.isdoff);
3370 /* Real size of end of eisd marker. */
3371 PRIV (file_pos) += EISD__K_LENEND;
3372 }
3373
3374 bfd_putl32 (PRIV (file_pos), eihd.size);
3375 bfd_putl32 ((PRIV (file_pos) + VMS_BLOCK_SIZE - 1) / VMS_BLOCK_SIZE,
07d6d2b8 3376 eihd.hdrblkcnt);
95e34ef7
TG
3377
3378 /* Place sections. */
3379 for (sec = abfd->sections; sec; sec = sec->next)
3380 {
3381 if (!(sec->flags & SEC_HAS_CONTENTS))
07d6d2b8 3382 continue;
95e34ef7
TG
3383
3384 eisd = vms_section_data (sec)->eisd;
3385
3386 /* Align on a block. */
3387 alpha_vms_file_position_block (abfd);
3388 sec->filepos = PRIV (file_pos);
3389
3390 if (eisd != NULL)
07d6d2b8 3391 eisd->u.eisd.vbn = (sec->filepos / VMS_BLOCK_SIZE) + 1;
95e34ef7
TG
3392
3393 PRIV (file_pos) += sec->size;
3394 }
3395
5fe88cfb 3396 /* Update EIHS. */
95e34ef7
TG
3397 if (eihs != NULL && dst != NULL)
3398 {
3399 bfd_putl32 ((dst->filepos / VMS_BLOCK_SIZE) + 1, eihs->dstvbn);
3400 bfd_putl32 (dst->size, eihs->dstsize);
44273c5b
TG
3401
3402 if (dmt != NULL)
07d6d2b8
AM
3403 {
3404 lnkflags |= EIHD__M_DBGDMT;
3405 bfd_putl32 ((dmt->filepos / VMS_BLOCK_SIZE) + 1, eihs->dmtvbn);
3406 bfd_putl32 (dmt->size, eihs->dmtsize);
3407 }
f9eeb9c9 3408 if (PRIV (gsd_sym_count) != 0)
07d6d2b8
AM
3409 {
3410 alpha_vms_file_position_block (abfd);
3411 gst_filepos = PRIV (file_pos);
3412 bfd_putl32 ((gst_filepos / VMS_BLOCK_SIZE) + 1, eihs->gstvbn);
3413 bfd_putl32 ((PRIV (gsd_sym_count) + 4) / 5 + 4, eihs->gstsize);
3414 }
95e34ef7
TG
3415 }
3416
3417 /* Write EISD in hdr. */
3418 for (eisd = first_eisd; eisd && eisd->file_pos < VMS_BLOCK_SIZE;
3419 eisd = eisd->next)
3420 alpha_vms_swap_eisd_out
3421 (eisd, (struct vms_eisd *)((char *)&eihd + eisd->file_pos));
3422
3423 /* Write first block. */
f9eeb9c9 3424 bfd_putl32 (lnkflags, eihd.lnkflags);
95e34ef7 3425 if (bfd_bwrite (&eihd, sizeof (eihd), abfd) != sizeof (eihd))
0a1b45a2 3426 return false;
95e34ef7
TG
3427
3428 /* Write remaining eisd. */
3429 if (eisd != NULL)
3430 {
3431 unsigned char blk[VMS_BLOCK_SIZE];
3432 struct vms_internal_eisd_map *next_eisd;
3433
3434 memset (blk, 0xff, sizeof (blk));
3435 while (eisd != NULL)
07d6d2b8
AM
3436 {
3437 alpha_vms_swap_eisd_out
3438 (eisd,
3439 (struct vms_eisd *)(blk + (eisd->file_pos % VMS_BLOCK_SIZE)));
3440
3441 next_eisd = eisd->next;
3442 if (next_eisd == NULL
3443 || (next_eisd->file_pos / VMS_BLOCK_SIZE
3444 != eisd->file_pos / VMS_BLOCK_SIZE))
3445 {
3446 if (bfd_bwrite (blk, sizeof (blk), abfd) != sizeof (blk))
0a1b45a2 3447 return false;
95e34ef7 3448
07d6d2b8
AM
3449 memset (blk, 0xff, sizeof (blk));
3450 }
3451 eisd = next_eisd;
3452 }
95e34ef7
TG
3453 }
3454
3455 /* Write sections. */
3456 for (sec = abfd->sections; sec; sec = sec->next)
3457 {
3458 unsigned char blk[VMS_BLOCK_SIZE];
3459 bfd_size_type len;
3460
3461 if (sec->size == 0 || !(sec->flags & SEC_HAS_CONTENTS))
07d6d2b8 3462 continue;
95e34ef7 3463 if (bfd_bwrite (sec->contents, sec->size, abfd) != sec->size)
0a1b45a2 3464 return false;
95e34ef7
TG
3465
3466 /* Pad. */
3467 len = VMS_BLOCK_SIZE - sec->size % VMS_BLOCK_SIZE;
3468 if (len != VMS_BLOCK_SIZE)
07d6d2b8
AM
3469 {
3470 memset (blk, 0, len);
3471 if (bfd_bwrite (blk, len, abfd) != len)
0a1b45a2 3472 return false;
07d6d2b8 3473 }
95e34ef7
TG
3474 }
3475
f9eeb9c9
TG
3476 /* Write GST. */
3477 if (gst_filepos != 0)
3478 {
3479 struct vms_rec_wr *recwr = &PRIV (recwr);
3480 unsigned int i;
3481
3482 _bfd_vms_write_emh (abfd);
3483 _bfd_vms_write_lmn (abfd, "GNU LD");
3484
3485 /* PSC for the absolute section. */
3486 _bfd_vms_output_begin (recwr, EOBJ__C_EGSD);
3487 _bfd_vms_output_long (recwr, 0);
3488 _bfd_vms_output_begin_subrec (recwr, EGSD__C_PSC);
3489 _bfd_vms_output_short (recwr, 0);
3490 _bfd_vms_output_short (recwr, EGPS__V_PIC | EGPS__V_LIB | EGPS__V_RD);
3491 _bfd_vms_output_long (recwr, 0);
3492 _bfd_vms_output_counted (recwr, ".$$ABS$$.");
3493 _bfd_vms_output_end_subrec (recwr);
3494 _bfd_vms_output_end (abfd, recwr);
3495
3496 for (i = 0; i < PRIV (gsd_sym_count); i++)
07d6d2b8
AM
3497 {
3498 struct vms_symbol_entry *sym = PRIV (syms)[i];
3499 bfd_vma val;
3500 bfd_vma ep;
3501
3502 if ((i % 5) == 0)
3503 {
3504 _bfd_vms_output_alignment (recwr, 8);
3505 _bfd_vms_output_begin (recwr, EOBJ__C_EGSD);
3506 _bfd_vms_output_long (recwr, 0);
3507 }
3508 _bfd_vms_output_begin_subrec (recwr, EGSD__C_SYMG);
3509 _bfd_vms_output_short (recwr, 0); /* Data type, alignment. */
3510 _bfd_vms_output_short (recwr, sym->flags);
3511
3512 if (sym->code_section)
3513 ep = alpha_vms_get_sym_value (sym->code_section, sym->code_value);
3514 else
3515 {
3516 BFD_ASSERT (sym->code_value == 0);
3517 ep = 0;
3518 }
3519 val = alpha_vms_get_sym_value (sym->section, sym->value);
3520 _bfd_vms_output_quad
3521 (recwr, sym->typ == EGSD__C_SYMG ? sym->symbol_vector : val);
3522 _bfd_vms_output_quad (recwr, ep);
3523 _bfd_vms_output_quad (recwr, val);
3524 _bfd_vms_output_long (recwr, 0);
3525 _bfd_vms_output_counted (recwr, sym->name);
3526 _bfd_vms_output_end_subrec (recwr);
3527 if ((i % 5) == 4)
3528 _bfd_vms_output_end (abfd, recwr);
3529 }
f9eeb9c9 3530 if ((i % 5) != 0)
07d6d2b8 3531 _bfd_vms_output_end (abfd, recwr);
f9eeb9c9
TG
3532
3533 if (!_bfd_vms_write_eeom (abfd))
0a1b45a2 3534 return false;
f9eeb9c9 3535 }
0a1b45a2 3536 return true;
95e34ef7
TG
3537}
3538\f
3539/* Object write. */
3540
95e34ef7
TG
3541/* Write section and symbol directory of bfd abfd. Return FALSE on error. */
3542
0a1b45a2 3543static bool
95e34ef7
TG
3544_bfd_vms_write_egsd (bfd *abfd)
3545{
3546 asection *section;
3547 asymbol *symbol;
3548 unsigned int symnum;
dddb0e80 3549 const char *sname;
95e34ef7 3550 flagword new_flags, old_flags;
4ba2ab9f 3551 int abs_section_index = -1;
1b3d1dbf 3552 unsigned int target_index = 0;
95e34ef7
TG
3553 struct vms_rec_wr *recwr = &PRIV (recwr);
3554
1b3d1dbf 3555 vms_debug2 ((2, "vms_write_egsd\n"));
95e34ef7
TG
3556
3557 /* Egsd is quadword aligned. */
3558 _bfd_vms_output_alignment (recwr, 8);
3559
3560 _bfd_vms_output_begin (recwr, EOBJ__C_EGSD);
3561 _bfd_vms_output_long (recwr, 0);
3562
1b3d1dbf
TG
3563 /* Number sections. */
3564 for (section = abfd->sections; section != NULL; section = section->next)
3565 {
3566 if (section->flags & SEC_DEBUGGING)
07d6d2b8 3567 continue;
1b3d1dbf 3568 if (!strcmp (section->name, ".vmsdebug"))
07d6d2b8
AM
3569 {
3570 section->flags |= SEC_DEBUGGING;
3571 continue;
3572 }
1b3d1dbf
TG
3573 section->target_index = target_index++;
3574 }
3575
3576 for (section = abfd->sections; section != NULL; section = section->next)
95e34ef7
TG
3577 {
3578 vms_debug2 ((3, "Section #%d %s, %d bytes\n",
07d6d2b8 3579 section->target_index, section->name, (int)section->size));
95e34ef7
TG
3580
3581 /* Don't write out the VMS debug info section since it is in the
07d6d2b8 3582 ETBT and EDBG sections in etir. */
1b3d1dbf 3583 if (section->flags & SEC_DEBUGGING)
07d6d2b8 3584 continue;
95e34ef7
TG
3585
3586 /* 13 bytes egsd, max 31 chars name -> should be 44 bytes. */
3587 if (_bfd_vms_output_check (recwr, 64) < 0)
3588 {
3589 _bfd_vms_output_end (abfd, recwr);
3590 _bfd_vms_output_begin (recwr, EOBJ__C_EGSD);
3591 _bfd_vms_output_long (recwr, 0);
3592 }
3593
95e34ef7 3594 /* Don't know if this is necessary for the linker but for now it keeps
5fe88cfb 3595 vms_slurp_gsd happy. */
81bb31c0 3596 sname = section->name;
95e34ef7
TG
3597 if (*sname == '.')
3598 {
07d6d2b8 3599 /* Remove leading dot. */
95e34ef7
TG
3600 sname++;
3601 if ((*sname == 't') && (strcmp (sname, "text") == 0))
3602 sname = EVAX_CODE_NAME;
3603 else if ((*sname == 'd') && (strcmp (sname, "data") == 0))
3604 sname = EVAX_DATA_NAME;
3605 else if ((*sname == 'b') && (strcmp (sname, "bss") == 0))
3606 sname = EVAX_BSS_NAME;
3607 else if ((*sname == 'l') && (strcmp (sname, "link") == 0))
3608 sname = EVAX_LINK_NAME;
3609 else if ((*sname == 'r') && (strcmp (sname, "rdata") == 0))
3610 sname = EVAX_READONLY_NAME;
3611 else if ((*sname == 'l') && (strcmp (sname, "literal") == 0))
3612 sname = EVAX_LITERAL_NAME;
3613 else if ((*sname == 'l') && (strcmp (sname, "literals") == 0))
07d6d2b8 3614 sname = EVAX_LITERALS_NAME;
95e34ef7
TG
3615 else if ((*sname == 'c') && (strcmp (sname, "comm") == 0))
3616 sname = EVAX_COMMON_NAME;
3617 else if ((*sname == 'l') && (strcmp (sname, "lcomm") == 0))
3618 sname = EVAX_LOCAL_NAME;
3619 }
95e34ef7 3620
95e34ef7
TG
3621 if (bfd_is_com_section (section))
3622 new_flags = (EGPS__V_OVR | EGPS__V_REL | EGPS__V_GBL | EGPS__V_RD
3623 | EGPS__V_WRT | EGPS__V_NOMOD | EGPS__V_COM);
3624 else
3625 new_flags = vms_esecflag_by_name (evax_section_flags, sname,
3626 section->size > 0);
3627
3628 /* Modify them as directed. */
3629 if (section->flags & SEC_READONLY)
3630 new_flags &= ~EGPS__V_WRT;
3631
3632 new_flags &= ~vms_section_data (section)->no_flags;
3633 new_flags |= vms_section_data (section)->flags;
3634
3635 vms_debug2 ((3, "sec flags %x\n", section->flags));
3636 vms_debug2 ((3, "new_flags %x, _raw_size %lu\n",
07d6d2b8 3637 new_flags, (unsigned long)section->size));
95e34ef7 3638
4ba2ab9f
TG
3639 _bfd_vms_output_begin_subrec (recwr, EGSD__C_PSC);
3640 _bfd_vms_output_short (recwr, section->alignment_power & 0xff);
95e34ef7
TG
3641 _bfd_vms_output_short (recwr, new_flags);
3642 _bfd_vms_output_long (recwr, (unsigned long) section->size);
3643 _bfd_vms_output_counted (recwr, sname);
3644 _bfd_vms_output_end_subrec (recwr);
4ba2ab9f
TG
3645
3646 /* If the section is an obsolute one, remind its index as it will be
07d6d2b8 3647 used later for absolute symbols. */
4ba2ab9f 3648 if ((new_flags & EGPS__V_REL) == 0 && abs_section_index < 0)
07d6d2b8 3649 abs_section_index = section->target_index;
95e34ef7
TG
3650 }
3651
3652 /* Output symbols. */
3653 vms_debug2 ((3, "%d symbols found\n", abfd->symcount));
3654
3655 bfd_set_start_address (abfd, (bfd_vma) -1);
3656
3657 for (symnum = 0; symnum < abfd->symcount; symnum++)
3658 {
95e34ef7 3659 symbol = abfd->outsymbols[symnum];
46d00b8a
TG
3660 old_flags = symbol->flags;
3661
4ba2ab9f 3662 /* Work-around a missing feature: consider __main as the main entry
07d6d2b8 3663 point. */
53452371
TG
3664 if (symbol->name[0] == '_' && strcmp (symbol->name, "__main") == 0)
3665 bfd_set_start_address (abfd, (bfd_vma)symbol->value);
95e34ef7 3666
46d00b8a 3667 /* Only put in the GSD the global and the undefined symbols. */
95e34ef7
TG
3668 if (old_flags & BSF_FILE)
3669 continue;
3670
46d00b8a 3671 if ((old_flags & BSF_GLOBAL) == 0 && !bfd_is_und_section (symbol->section))
07d6d2b8
AM
3672 {
3673 /* If the LIB$INITIIALIZE section is present, add a reference to
3674 LIB$INITIALIZE symbol. FIXME: this should be done explicitely
3675 in the assembly file. */
3676 if (!((old_flags & BSF_SECTION_SYM) != 0
3677 && strcmp (symbol->section->name, "LIB$INITIALIZE") == 0))
3678 continue;
3679 }
95e34ef7 3680
4ba2ab9f 3681 /* 13 bytes egsd, max 64 chars name -> should be 77 bytes. Add 16 more
07d6d2b8 3682 bytes for a possible ABS section. */
4ba2ab9f 3683 if (_bfd_vms_output_check (recwr, 80 + 16) < 0)
95e34ef7
TG
3684 {
3685 _bfd_vms_output_end (abfd, recwr);
3686 _bfd_vms_output_begin (recwr, EOBJ__C_EGSD);
3687 _bfd_vms_output_long (recwr, 0);
3688 }
3689
4ba2ab9f 3690 if ((old_flags & BSF_GLOBAL) != 0
07d6d2b8
AM
3691 && bfd_is_abs_section (symbol->section)
3692 && abs_section_index <= 0)
3693 {
3694 /* Create an absolute section if none was defined. It is highly
3695 unlikely that the name $ABS$ clashes with a user defined
3696 non-absolute section name. */
3697 _bfd_vms_output_begin_subrec (recwr, EGSD__C_PSC);
3698 _bfd_vms_output_short (recwr, 4);
3699 _bfd_vms_output_short (recwr, EGPS__V_SHR);
3700 _bfd_vms_output_long (recwr, 0);
3701 _bfd_vms_output_counted (recwr, "$ABS$");
3702 _bfd_vms_output_end_subrec (recwr);
3703
3704 abs_section_index = target_index++;
3705 }
4ba2ab9f 3706
95e34ef7
TG
3707 _bfd_vms_output_begin_subrec (recwr, EGSD__C_SYM);
3708
3709 /* Data type, alignment. */
3710 _bfd_vms_output_short (recwr, 0);
3711
3712 new_flags = 0;
3713
3714 if (old_flags & BSF_WEAK)
3715 new_flags |= EGSY__V_WEAK;
3716 if (bfd_is_com_section (symbol->section)) /* .comm */
3717 new_flags |= (EGSY__V_WEAK | EGSY__V_COMM);
3718
3719 if (old_flags & BSF_FUNCTION)
3720 {
3721 new_flags |= EGSY__V_NORM;
3722 new_flags |= EGSY__V_REL;
3723 }
3724 if (old_flags & BSF_GLOBAL)
3725 {
3726 new_flags |= EGSY__V_DEF;
3727 if (!bfd_is_abs_section (symbol->section))
3728 new_flags |= EGSY__V_REL;
3729 }
3730 _bfd_vms_output_short (recwr, new_flags);
3731
3732 if (old_flags & BSF_GLOBAL)
3733 {
3734 /* Symbol definition. */
3735 bfd_vma code_address = 0;
3736 unsigned long ca_psindx = 0;
3737 unsigned long psindx;
3738
3739 if ((old_flags & BSF_FUNCTION) && symbol->udata.p != NULL)
3740 {
3741 asymbol *sym;
3742
07d6d2b8
AM
3743 sym =
3744 ((struct evax_private_udata_struct *)symbol->udata.p)->enbsym;
95e34ef7 3745 code_address = sym->value;
1b3d1dbf 3746 ca_psindx = sym->section->target_index;
95e34ef7
TG
3747 }
3748 if (bfd_is_abs_section (symbol->section))
3749 psindx = abs_section_index;
3750 else
1b3d1dbf 3751 psindx = symbol->section->target_index;
95e34ef7
TG
3752
3753 _bfd_vms_output_quad (recwr, symbol->value);
3754 _bfd_vms_output_quad (recwr, code_address);
3755 _bfd_vms_output_long (recwr, ca_psindx);
3756 _bfd_vms_output_long (recwr, psindx);
3757 }
53452371 3758 _bfd_vms_output_counted (recwr, symbol->name);
95e34ef7
TG
3759
3760 _bfd_vms_output_end_subrec (recwr);
95e34ef7
TG
3761 }
3762
3763 _bfd_vms_output_alignment (recwr, 8);
3764 _bfd_vms_output_end (abfd, recwr);
3765
0a1b45a2 3766 return true;
95e34ef7
TG
3767}
3768
3769/* Write object header for bfd abfd. Return FALSE on error. */
3770
0a1b45a2 3771static bool
95e34ef7
TG
3772_bfd_vms_write_ehdr (bfd *abfd)
3773{
3774 asymbol *symbol;
3775 unsigned int symnum;
95e34ef7
TG
3776 struct vms_rec_wr *recwr = &PRIV (recwr);
3777
3778 vms_debug2 ((2, "vms_write_ehdr (%p)\n", abfd));
3779
3780 _bfd_vms_output_alignment (recwr, 2);
3781
bd7b51b4
TG
3782 _bfd_vms_write_emh (abfd);
3783 _bfd_vms_write_lmn (abfd, "GNU AS");
95e34ef7
TG
3784
3785 /* SRC. */
3786 _bfd_vms_output_begin (recwr, EOBJ__C_EMH);
3787 _bfd_vms_output_short (recwr, EMH__C_SRC);
3788
3789 for (symnum = 0; symnum < abfd->symcount; symnum++)
3790 {
3791 symbol = abfd->outsymbols[symnum];
3792
3793 if (symbol->flags & BSF_FILE)
3794 {
95e34ef7
TG
3795 _bfd_vms_output_dump (recwr, (unsigned char *) symbol->name,
3796 (int) strlen (symbol->name));
53452371 3797 break;
95e34ef7
TG
3798 }
3799 }
3800
3801 if (symnum == abfd->symcount)
3802 _bfd_vms_output_dump (recwr, (unsigned char *) STRING_COMMA_LEN ("noname"));
3803
3804 _bfd_vms_output_end (abfd, recwr);
3805
3806 /* TTL. */
3807 _bfd_vms_output_begin (recwr, EOBJ__C_EMH);
3808 _bfd_vms_output_short (recwr, EMH__C_TTL);
3809 _bfd_vms_output_dump (recwr, (unsigned char *) STRING_COMMA_LEN ("TTL"));
3810 _bfd_vms_output_end (abfd, recwr);
3811
3812 /* CPR. */
3813 _bfd_vms_output_begin (recwr, EOBJ__C_EMH);
3814 _bfd_vms_output_short (recwr, EMH__C_CPR);
3815 _bfd_vms_output_dump (recwr,
07d6d2b8 3816 (unsigned char *)"GNU BFD ported by Klaus Kämpf 1994-1996",
95e34ef7
TG
3817 39);
3818 _bfd_vms_output_end (abfd, recwr);
3819
0a1b45a2 3820 return true;
95e34ef7
TG
3821}
3822
3823/* Part 4.6, relocations. */
3824
3825\f
3826/* WRITE ETIR SECTION
3827
3828 This is still under construction and therefore not documented. */
3829
3830/* Close the etir/etbt record. */
3831
3832static void
3833end_etir_record (bfd * abfd)
3834{
3835 struct vms_rec_wr *recwr = &PRIV (recwr);
3836
3837 _bfd_vms_output_end (abfd, recwr);
3838}
3839
3840static void
3841start_etir_or_etbt_record (bfd *abfd, asection *section, bfd_vma offset)
3842{
3843 struct vms_rec_wr *recwr = &PRIV (recwr);
3844
1b3d1dbf 3845 if (section->flags & SEC_DEBUGGING)
95e34ef7
TG
3846 {
3847 _bfd_vms_output_begin (recwr, EOBJ__C_ETBT);
3848
3849 if (offset == 0)
07d6d2b8
AM
3850 {
3851 /* Push start offset. */
3852 _bfd_vms_output_begin_subrec (recwr, ETIR__C_STA_LW);
3853 _bfd_vms_output_long (recwr, (unsigned long) 0);
3854 _bfd_vms_output_end_subrec (recwr);
3855
3856 /* Set location. */
3857 _bfd_vms_output_begin_subrec (recwr, ETIR__C_CTL_DFLOC);
3858 _bfd_vms_output_end_subrec (recwr);
3859 }
95e34ef7
TG
3860 }
3861 else
3862 {
3863 _bfd_vms_output_begin (recwr, EOBJ__C_ETIR);
3864
3865 if (offset == 0)
07d6d2b8
AM
3866 {
3867 /* Push start offset. */
3868 _bfd_vms_output_begin_subrec (recwr, ETIR__C_STA_PQ);
3869 _bfd_vms_output_long (recwr, (unsigned long) section->target_index);
3870 _bfd_vms_output_quad (recwr, offset);
3871 _bfd_vms_output_end_subrec (recwr);
3872
3873 /* Start = pop (). */
3874 _bfd_vms_output_begin_subrec (recwr, ETIR__C_CTL_SETRB);
3875 _bfd_vms_output_end_subrec (recwr);
3876 }
95e34ef7
TG
3877 }
3878}
3879
3880/* Output a STO_IMM command for SSIZE bytes of data from CPR at virtual
3881 address VADDR in section specified by SEC_INDEX and NAME. */
3882
3883static void
3884sto_imm (bfd *abfd, asection *section,
07d6d2b8 3885 bfd_size_type ssize, unsigned char *cptr, bfd_vma vaddr)
95e34ef7
TG
3886{
3887 bfd_size_type size;
3888 struct vms_rec_wr *recwr = &PRIV (recwr);
3889
3890#if VMS_DEBUG
3891 _bfd_vms_debug (8, "sto_imm %d bytes\n", (int) ssize);
3892 _bfd_hexdump (9, cptr, (int) ssize, (int) vaddr);
3893#endif
3894
3895 while (ssize > 0)
3896 {
3897 /* Try all the rest. */
3898 size = ssize;
3899
3900 if (_bfd_vms_output_check (recwr, size) < 0)
3901 {
3902 /* Doesn't fit, split ! */
3903 end_etir_record (abfd);
3904
07d6d2b8 3905 start_etir_or_etbt_record (abfd, section, vaddr);
95e34ef7
TG
3906
3907 size = _bfd_vms_output_check (recwr, 0); /* get max size */
3908 if (size > ssize) /* more than what's left ? */
3909 size = ssize;
3910 }
3911
3912 _bfd_vms_output_begin_subrec (recwr, ETIR__C_STO_IMM);
3913 _bfd_vms_output_long (recwr, (unsigned long) (size));
3914 _bfd_vms_output_dump (recwr, cptr, size);
3915 _bfd_vms_output_end_subrec (recwr);
3916
3917#if VMS_DEBUG
3918 _bfd_vms_debug (10, "dumped %d bytes\n", (int) size);
3919 _bfd_hexdump (10, cptr, (int) size, (int) vaddr);
3920#endif
3921
3922 vaddr += size;
3923 cptr += size;
3924 ssize -= size;
3925 }
3926}
3927
3928static void
3929etir_output_check (bfd *abfd, asection *section, bfd_vma vaddr, int checklen)
3930{
3931 if (_bfd_vms_output_check (&PRIV (recwr), checklen) < 0)
3932 {
3933 /* Not enough room in this record. Close it and open a new one. */
3934 end_etir_record (abfd);
3935 start_etir_or_etbt_record (abfd, section, vaddr);
3936 }
3937}
3938
3939/* Return whether RELOC must be deferred till the end. */
3940
0a1b45a2 3941static bool
95e34ef7
TG
3942defer_reloc_p (arelent *reloc)
3943{
3944 switch (reloc->howto->type)
3945 {
3946 case ALPHA_R_NOP:
3947 case ALPHA_R_LDA:
3948 case ALPHA_R_BSR:
3949 case ALPHA_R_BOH:
0a1b45a2 3950 return true;
95e34ef7
TG
3951
3952 default:
0a1b45a2 3953 return false;
95e34ef7
TG
3954 }
3955}
3956
3957/* Write section contents for bfd abfd. Return FALSE on error. */
3958
0a1b45a2 3959static bool
95e34ef7
TG
3960_bfd_vms_write_etir (bfd * abfd, int objtype ATTRIBUTE_UNUSED)
3961{
3962 asection *section;
3963 struct vms_rec_wr *recwr = &PRIV (recwr);
3964
3965 vms_debug2 ((2, "vms_write_tir (%p, %d)\n", abfd, objtype));
3966
3967 _bfd_vms_output_alignment (recwr, 4);
3968
f1bb0388 3969 PRIV (vms_linkage_index) = 0;
95e34ef7
TG
3970
3971 for (section = abfd->sections; section; section = section->next)
3972 {
3973 vms_debug2 ((4, "writing %d. section '%s' (%d bytes)\n",
07d6d2b8 3974 section->target_index, section->name, (int) (section->size)));
95e34ef7
TG
3975
3976 if (!(section->flags & SEC_HAS_CONTENTS)
3977 || bfd_is_com_section (section))
3978 continue;
3979
3980 if (!section->contents)
3981 {
3982 bfd_set_error (bfd_error_no_contents);
0a1b45a2 3983 return false;
95e34ef7
TG
3984 }
3985
3986 start_etir_or_etbt_record (abfd, section, 0);
3987
3988 if (section->flags & SEC_RELOC)
3989 {
3990 bfd_vma curr_addr = 0;
3991 unsigned char *curr_data = section->contents;
3992 bfd_size_type size;
3993 int pass2_needed = 0;
3994 int pass2_in_progress = 0;
3995 unsigned int irel;
3996
083faca9 3997 if (section->reloc_count == 0)
4eca0228 3998 _bfd_error_handler
871b3ab2 3999 (_("SEC_RELOC with no relocs in section %pA"), section);
95e34ef7
TG
4000
4001#if VMS_DEBUG
4002 else
4003 {
4004 int i = section->reloc_count;
4005 arelent **rptr = section->orelocation;
4006 _bfd_vms_debug (4, "%d relocations:\n", i);
4007 while (i-- > 0)
4008 {
4009 _bfd_vms_debug (4, "sym %s in sec %s, value %08lx, "
4010 "addr %08lx, off %08lx, len %d: %s\n",
4011 (*(*rptr)->sym_ptr_ptr)->name,
4012 (*(*rptr)->sym_ptr_ptr)->section->name,
4013 (long) (*(*rptr)->sym_ptr_ptr)->value,
4014 (unsigned long)(*rptr)->address,
07d6d2b8 4015 (unsigned long)(*rptr)->addend,
95e34ef7 4016 bfd_get_reloc_size ((*rptr)->howto),
07d6d2b8 4017 ( *rptr)->howto->name);
95e34ef7
TG
4018 rptr++;
4019 }
4020 }
4021#endif
4022
4023 new_pass:
4024 for (irel = 0; irel < section->reloc_count; irel++)
4025 {
4026 struct evax_private_udata_struct *udata;
4027 arelent *rptr = section->orelocation [irel];
4028 bfd_vma addr = rptr->address;
4029 asymbol *sym = *rptr->sym_ptr_ptr;
4030 asection *sec = sym->section;
0a1b45a2 4031 bool defer = defer_reloc_p (rptr);
95e34ef7 4032 unsigned int slen;
95e34ef7
TG
4033
4034 if (pass2_in_progress)
4035 {
4036 /* Non-deferred relocs have already been output. */
4037 if (!defer)
4038 continue;
4039 }
4040 else
4041 {
4042 /* Deferred relocs must be output at the very end. */
4043 if (defer)
4044 {
4045 pass2_needed = 1;
4046 continue;
4047 }
4048
4049 /* Regular relocs are intertwined with binary data. */
07d6d2b8 4050 if (curr_addr > addr)
38f14ab8 4051 _bfd_error_handler (_("size error in section %pA"),
dae82561 4052 section);
95e34ef7
TG
4053 size = addr - curr_addr;
4054 sto_imm (abfd, section, size, curr_data, curr_addr);
4055 curr_data += size;
4056 curr_addr += size;
4057 }
4058
4059 size = bfd_get_reloc_size (rptr->howto);
4060
4061 switch (rptr->howto->type)
07d6d2b8 4062 {
95e34ef7
TG
4063 case ALPHA_R_IGNORE:
4064 break;
4065
4066 case ALPHA_R_REFLONG:
4067 if (bfd_is_und_section (sym->section))
4068 {
4069 bfd_vma addend = rptr->addend;
4070 slen = strlen ((char *) sym->name);
95e34ef7
TG
4071 etir_output_check (abfd, section, curr_addr, slen);
4072 if (addend)
4073 {
4074 _bfd_vms_output_begin_subrec (recwr, ETIR__C_STA_GBL);
53452371 4075 _bfd_vms_output_counted (recwr, sym->name);
95e34ef7
TG
4076 _bfd_vms_output_end_subrec (recwr);
4077 _bfd_vms_output_begin_subrec (recwr, ETIR__C_STA_LW);
4078 _bfd_vms_output_long (recwr, (unsigned long) addend);
4079 _bfd_vms_output_end_subrec (recwr);
4080 _bfd_vms_output_begin_subrec (recwr, ETIR__C_OPR_ADD);
4081 _bfd_vms_output_end_subrec (recwr);
4082 _bfd_vms_output_begin_subrec (recwr, ETIR__C_STO_LW);
4083 _bfd_vms_output_end_subrec (recwr);
4084 }
4085 else
4086 {
4087 _bfd_vms_output_begin_subrec
07d6d2b8 4088 (recwr, ETIR__C_STO_GBL_LW);
53452371 4089 _bfd_vms_output_counted (recwr, sym->name);
95e34ef7
TG
4090 _bfd_vms_output_end_subrec (recwr);
4091 }
4092 }
4093 else if (bfd_is_abs_section (sym->section))
4094 {
4095 etir_output_check (abfd, section, curr_addr, 16);
4096 _bfd_vms_output_begin_subrec (recwr, ETIR__C_STA_LW);
4097 _bfd_vms_output_long (recwr, (unsigned long) sym->value);
4098 _bfd_vms_output_end_subrec (recwr);
4099 _bfd_vms_output_begin_subrec (recwr, ETIR__C_STO_LW);
4100 _bfd_vms_output_end_subrec (recwr);
4101 }
4102 else
4103 {
4104 etir_output_check (abfd, section, curr_addr, 32);
4105 _bfd_vms_output_begin_subrec (recwr, ETIR__C_STA_PQ);
1b3d1dbf 4106 _bfd_vms_output_long (recwr,
07d6d2b8 4107 (unsigned long) sec->target_index);
95e34ef7
TG
4108 _bfd_vms_output_quad (recwr, rptr->addend + sym->value);
4109 _bfd_vms_output_end_subrec (recwr);
4110 /* ??? Table B-8 of the OpenVMS Linker Utilily Manual
4111 says that we should have a ETIR__C_STO_OFF here.
4112 But the relocation would not be BFD_RELOC_32 then.
4113 This case is very likely unreachable. */
4114 _bfd_vms_output_begin_subrec (recwr, ETIR__C_STO_LW);
4115 _bfd_vms_output_end_subrec (recwr);
4116 }
4117 break;
4118
4119 case ALPHA_R_REFQUAD:
4120 if (bfd_is_und_section (sym->section))
4121 {
4122 bfd_vma addend = rptr->addend;
4123 slen = strlen ((char *) sym->name);
95e34ef7
TG
4124 etir_output_check (abfd, section, curr_addr, slen);
4125 if (addend)
4126 {
4127 _bfd_vms_output_begin_subrec (recwr, ETIR__C_STA_GBL);
53452371 4128 _bfd_vms_output_counted (recwr, sym->name);
95e34ef7
TG
4129 _bfd_vms_output_end_subrec (recwr);
4130 _bfd_vms_output_begin_subrec (recwr, ETIR__C_STA_QW);
4131 _bfd_vms_output_quad (recwr, addend);
4132 _bfd_vms_output_end_subrec (recwr);
4133 _bfd_vms_output_begin_subrec (recwr, ETIR__C_OPR_ADD);
4134 _bfd_vms_output_end_subrec (recwr);
4135 _bfd_vms_output_begin_subrec (recwr, ETIR__C_STO_QW);
4136 _bfd_vms_output_end_subrec (recwr);
4137 }
4138 else
4139 {
4140 _bfd_vms_output_begin_subrec (recwr, ETIR__C_STO_GBL);
53452371 4141 _bfd_vms_output_counted (recwr, sym->name);
95e34ef7
TG
4142 _bfd_vms_output_end_subrec (recwr);
4143 }
4144 }
4145 else if (bfd_is_abs_section (sym->section))
4146 {
4147 etir_output_check (abfd, section, curr_addr, 16);
4148 _bfd_vms_output_begin_subrec (recwr, ETIR__C_STA_QW);
4149 _bfd_vms_output_quad (recwr, sym->value);
4150 _bfd_vms_output_end_subrec (recwr);
4151 _bfd_vms_output_begin_subrec (recwr, ETIR__C_STO_QW);
4152 _bfd_vms_output_end_subrec (recwr);
4153 }
4154 else
4155 {
4156 etir_output_check (abfd, section, curr_addr, 32);
4157 _bfd_vms_output_begin_subrec (recwr, ETIR__C_STA_PQ);
1b3d1dbf 4158 _bfd_vms_output_long (recwr,
07d6d2b8 4159 (unsigned long) sec->target_index);
95e34ef7
TG
4160 _bfd_vms_output_quad (recwr, rptr->addend + sym->value);
4161 _bfd_vms_output_end_subrec (recwr);
4162 _bfd_vms_output_begin_subrec (recwr, ETIR__C_STO_OFF);
4163 _bfd_vms_output_end_subrec (recwr);
4164 }
4165 break;
4166
4167 case ALPHA_R_HINT:
4168 sto_imm (abfd, section, size, curr_data, curr_addr);
4169 break;
4170
4171 case ALPHA_R_LINKAGE:
706704c8 4172 size = 16;
95e34ef7
TG
4173 etir_output_check (abfd, section, curr_addr, 64);
4174 _bfd_vms_output_begin_subrec (recwr, ETIR__C_STC_LP_PSB);
4175 _bfd_vms_output_long
25d41743 4176 (recwr, (unsigned long) rptr->addend);
07d6d2b8
AM
4177 if (rptr->addend > PRIV (vms_linkage_index))
4178 PRIV (vms_linkage_index) = rptr->addend;
53452371 4179 _bfd_vms_output_counted (recwr, sym->name);
95e34ef7
TG
4180 _bfd_vms_output_byte (recwr, 0);
4181 _bfd_vms_output_end_subrec (recwr);
4182 break;
4183
4184 case ALPHA_R_CODEADDR:
4185 slen = strlen ((char *) sym->name);
95e34ef7
TG
4186 etir_output_check (abfd, section, curr_addr, slen);
4187 _bfd_vms_output_begin_subrec (recwr, ETIR__C_STO_CA);
53452371 4188 _bfd_vms_output_counted (recwr, sym->name);
95e34ef7
TG
4189 _bfd_vms_output_end_subrec (recwr);
4190 break;
4191
4192 case ALPHA_R_NOP:
4193 udata
4194 = (struct evax_private_udata_struct *) rptr->sym_ptr_ptr;
4195 etir_output_check (abfd, section, curr_addr,
4196 32 + 1 + strlen (udata->origname));
4197 _bfd_vms_output_begin_subrec (recwr, ETIR__C_STC_NOP_GBL);
4198 _bfd_vms_output_long (recwr, (unsigned long) udata->lkindex);
4199 _bfd_vms_output_long
a8efca92 4200 (recwr, (unsigned long) section->target_index);
95e34ef7
TG
4201 _bfd_vms_output_quad (recwr, rptr->address);
4202 _bfd_vms_output_long (recwr, (unsigned long) 0x47ff041f);
4203 _bfd_vms_output_long
a8efca92 4204 (recwr, (unsigned long) section->target_index);
95e34ef7 4205 _bfd_vms_output_quad (recwr, rptr->addend);
53452371 4206 _bfd_vms_output_counted (recwr, udata->origname);
95e34ef7
TG
4207 _bfd_vms_output_end_subrec (recwr);
4208 break;
4209
4210 case ALPHA_R_BSR:
38f14ab8 4211 _bfd_error_handler (_("spurious ALPHA_R_BSR reloc"));
95e34ef7
TG
4212 break;
4213
4214 case ALPHA_R_LDA:
4215 udata
4216 = (struct evax_private_udata_struct *) rptr->sym_ptr_ptr;
4217 etir_output_check (abfd, section, curr_addr,
4218 32 + 1 + strlen (udata->origname));
4219 _bfd_vms_output_begin_subrec (recwr, ETIR__C_STC_LDA_GBL);
4220 _bfd_vms_output_long
4221 (recwr, (unsigned long) udata->lkindex + 1);
4222 _bfd_vms_output_long
a8efca92 4223 (recwr, (unsigned long) section->target_index);
95e34ef7
TG
4224 _bfd_vms_output_quad (recwr, rptr->address);
4225 _bfd_vms_output_long (recwr, (unsigned long) 0x237B0000);
4226 _bfd_vms_output_long
1b3d1dbf 4227 (recwr, (unsigned long) udata->bsym->section->target_index);
95e34ef7 4228 _bfd_vms_output_quad (recwr, rptr->addend);
53452371 4229 _bfd_vms_output_counted (recwr, udata->origname);
95e34ef7
TG
4230 _bfd_vms_output_end_subrec (recwr);
4231 break;
4232
4233 case ALPHA_R_BOH:
4234 udata
4235 = (struct evax_private_udata_struct *) rptr->sym_ptr_ptr;
4236 etir_output_check (abfd, section, curr_addr,
4237 32 + 1 + strlen (udata->origname));
4238 _bfd_vms_output_begin_subrec (recwr, ETIR__C_STC_BOH_GBL);
4239 _bfd_vms_output_long (recwr, (unsigned long) udata->lkindex);
4240 _bfd_vms_output_long
a8efca92 4241 (recwr, (unsigned long) section->target_index);
95e34ef7
TG
4242 _bfd_vms_output_quad (recwr, rptr->address);
4243 _bfd_vms_output_long (recwr, (unsigned long) 0xD3400000);
4244 _bfd_vms_output_long
a8efca92 4245 (recwr, (unsigned long) section->target_index);
95e34ef7 4246 _bfd_vms_output_quad (recwr, rptr->addend);
53452371 4247 _bfd_vms_output_counted (recwr, udata->origname);
95e34ef7
TG
4248 _bfd_vms_output_end_subrec (recwr);
4249 break;
4250
4251 default:
38f14ab8 4252 _bfd_error_handler (_("unhandled relocation %s"),
4eca0228 4253 rptr->howto->name);
95e34ef7
TG
4254 break;
4255 }
4256
4257 curr_data += size;
4258 curr_addr += size;
4259 } /* End of relocs loop. */
4260
4261 if (!pass2_in_progress)
4262 {
4263 /* Output rest of section. */
4264 if (curr_addr > section->size)
9ec2f606
AM
4265 {
4266 _bfd_error_handler (_("size error in section %pA"), section);
0a1b45a2 4267 return false;
9ec2f606 4268 }
95e34ef7
TG
4269 size = section->size - curr_addr;
4270 sto_imm (abfd, section, size, curr_data, curr_addr);
4271 curr_data += size;
4272 curr_addr += size;
4273
4274 if (pass2_needed)
4275 {
4276 pass2_in_progress = 1;
4277 goto new_pass;
4278 }
4279 }
4280 }
4281
4282 else /* (section->flags & SEC_RELOC) */
4283 sto_imm (abfd, section, section->size, section->contents, 0);
4284
4285 end_etir_record (abfd);
4286 }
4287
4288 _bfd_vms_output_alignment (recwr, 2);
0a1b45a2 4289 return true;
95e34ef7
TG
4290}
4291
95e34ef7
TG
4292/* Write cached information into a file being written, at bfd_close. */
4293
0a1b45a2 4294static bool
95e34ef7
TG
4295alpha_vms_write_object_contents (bfd *abfd)
4296{
4297 vms_debug2 ((1, "vms_write_object_contents (%p)\n", abfd));
4298
4299 if (abfd->flags & (EXEC_P | DYNAMIC))
4300 {
4301 return alpha_vms_write_exec (abfd);
4302 }
4303 else
4304 {
4305 if (abfd->section_count > 0) /* we have sections */
07d6d2b8
AM
4306 {
4307 if (!_bfd_vms_write_ehdr (abfd))
0a1b45a2 4308 return false;
07d6d2b8 4309 if (!_bfd_vms_write_egsd (abfd))
0a1b45a2 4310 return false;
07d6d2b8 4311 if (!_bfd_vms_write_etir (abfd, EOBJ__C_ETIR))
0a1b45a2 4312 return false;
07d6d2b8 4313 if (!_bfd_vms_write_eeom (abfd))
0a1b45a2 4314 return false;
07d6d2b8 4315 }
95e34ef7 4316 }
0a1b45a2 4317 return true;
95e34ef7
TG
4318}
4319\f
4320/* Debug stuff: nearest line. */
4321
4322#define SET_MODULE_PARSED(m) \
4323 do { if ((m)->name == NULL) (m)->name = ""; } while (0)
4324#define IS_MODULE_PARSED(m) ((m)->name != NULL)
4325
4326/* Build a new module for the specified BFD. */
4327
4328static struct module *
4329new_module (bfd *abfd)
4330{
4331 struct module *module
4332 = (struct module *) bfd_zalloc (abfd, sizeof (struct module));
4333 module->file_table_count = 16; /* Arbitrary. */
4334 module->file_table
4335 = bfd_malloc (module->file_table_count * sizeof (struct fileinfo));
4336 return module;
4337}
4338
4339/* Parse debug info for a module and internalize it. */
4340
0a1b45a2 4341static bool
95e34ef7
TG
4342parse_module (bfd *abfd, struct module *module, unsigned char *ptr,
4343 int length)
4344{
4345 unsigned char *maxptr = ptr + length;
4346 unsigned char *src_ptr, *pcl_ptr;
4347 unsigned int prev_linum = 0, curr_linenum = 0;
4348 bfd_vma prev_pc = 0, curr_pc = 0;
4349 struct srecinfo *curr_srec, *srec;
4350 struct lineinfo *curr_line, *line;
4351 struct funcinfo *funcinfo;
4352
4353 /* Initialize tables with zero element. */
4354 curr_srec = (struct srecinfo *) bfd_zalloc (abfd, sizeof (struct srecinfo));
4355 module->srec_table = curr_srec;
4356
4357 curr_line = (struct lineinfo *) bfd_zalloc (abfd, sizeof (struct lineinfo));
4358 module->line_table = curr_line;
4359
4360 while (length == -1 || ptr < maxptr)
4361 {
4362 /* The first byte is not counted in the recorded length. */
4363 int rec_length = bfd_getl16 (ptr) + 1;
4364 int rec_type = bfd_getl16 (ptr + 2);
4365
4366 vms_debug2 ((2, "DST record: leng %d, type %d\n", rec_length, rec_type));
4367
4368 if (length == -1 && rec_type == DST__K_MODEND)
07d6d2b8 4369 break;
95e34ef7
TG
4370
4371 switch (rec_type)
4372 {
4373 case DST__K_MODBEG:
4374 module->name
37d2e9c7 4375 = _bfd_vms_save_counted_string (abfd, ptr + DST_S_B_MODBEG_NAME,
7adc0a81 4376 maxptr - (ptr + DST_S_B_MODBEG_NAME));
95e34ef7
TG
4377
4378 curr_pc = 0;
4379 prev_pc = 0;
4380 curr_linenum = 0;
4381 prev_linum = 0;
4382
07d6d2b8 4383 vms_debug2 ((3, "module: %s\n", module->name));
95e34ef7
TG
4384 break;
4385
4386 case DST__K_MODEND:
4387 break;
4388
4389 case DST__K_RTNBEG:
4390 funcinfo = (struct funcinfo *)
4391 bfd_zalloc (abfd, sizeof (struct funcinfo));
07d6d2b8 4392 funcinfo->name
37d2e9c7 4393 = _bfd_vms_save_counted_string (abfd, ptr + DST_S_B_RTNBEG_NAME,
7adc0a81 4394 maxptr - (ptr + DST_S_B_RTNBEG_NAME));
95e34ef7
TG
4395 funcinfo->low = bfd_getl32 (ptr + DST_S_L_RTNBEG_ADDRESS);
4396 funcinfo->next = module->func_table;
4397 module->func_table = funcinfo;
4398
07d6d2b8
AM
4399 vms_debug2 ((3, "routine: %s at 0x%lx\n",
4400 funcinfo->name, (unsigned long) funcinfo->low));
95e34ef7
TG
4401 break;
4402
4403 case DST__K_RTNEND:
4404 module->func_table->high = module->func_table->low
4405 + bfd_getl32 (ptr + DST_S_L_RTNEND_SIZE) - 1;
4406
4407 if (module->func_table->high > module->high)
4408 module->high = module->func_table->high;
4409
07d6d2b8 4410 vms_debug2 ((3, "end routine\n"));
95e34ef7
TG
4411 break;
4412
4413 case DST__K_PROLOG:
07d6d2b8 4414 vms_debug2 ((3, "prologue\n"));
95e34ef7
TG
4415 break;
4416
4417 case DST__K_EPILOG:
07d6d2b8 4418 vms_debug2 ((3, "epilog\n"));
95e34ef7
TG
4419 break;
4420
4421 case DST__K_BLKBEG:
07d6d2b8 4422 vms_debug2 ((3, "block\n"));
95e34ef7
TG
4423 break;
4424
4425 case DST__K_BLKEND:
07d6d2b8 4426 vms_debug2 ((3, "end block\n"));
95e34ef7
TG
4427 break;
4428
4429 case DST__K_SOURCE:
4430 src_ptr = ptr + DST_S_C_SOURCE_HEADER_SIZE;
4431
4432 vms_debug2 ((3, "source info\n"));
4433
4434 while (src_ptr < ptr + rec_length)
4435 {
4436 int cmd = src_ptr[0], cmd_length, data;
4437
4438 switch (cmd)
4439 {
4440 case DST__K_SRC_DECLFILE:
4441 {
4442 unsigned int fileid
4443 = bfd_getl16 (src_ptr + DST_S_W_SRC_DF_FILEID);
37d2e9c7
AM
4444 char *filename = _bfd_vms_save_counted_string
4445 (abfd,
4446 src_ptr + DST_S_B_SRC_DF_FILENAME,
4447 ptr + rec_length - (src_ptr + DST_S_B_SRC_DF_FILENAME));
95e34ef7
TG
4448
4449 while (fileid >= module->file_table_count)
4450 {
4451 module->file_table_count *= 2;
4452 module->file_table
9cb56943
AM
4453 = bfd_realloc_or_free (module->file_table,
4454 module->file_table_count
4455 * sizeof (struct fileinfo));
4456 if (module->file_table == NULL)
0a1b45a2 4457 return false;
95e34ef7
TG
4458 }
4459
4460 module->file_table [fileid].name = filename;
4461 module->file_table [fileid].srec = 1;
4462 cmd_length = src_ptr[DST_S_B_SRC_DF_LENGTH] + 2;
4463 vms_debug2 ((4, "DST_S_C_SRC_DECLFILE: %d, %s\n",
07d6d2b8 4464 fileid, module->file_table [fileid].name));
95e34ef7
TG
4465 }
4466 break;
4467
4468 case DST__K_SRC_DEFLINES_B:
4469 /* Perform the association and set the next higher index
4470 to the limit. */
4471 data = src_ptr[DST_S_B_SRC_UNSBYTE];
4472 srec = (struct srecinfo *)
4473 bfd_zalloc (abfd, sizeof (struct srecinfo));
4474 srec->line = curr_srec->line + data;
4475 srec->srec = curr_srec->srec + data;
4476 srec->sfile = curr_srec->sfile;
4477 curr_srec->next = srec;
4478 curr_srec = srec;
4479 cmd_length = 2;
4480 vms_debug2 ((4, "DST_S_C_SRC_DEFLINES_B: %d\n", data));
4481 break;
4482
4483 case DST__K_SRC_DEFLINES_W:
4484 /* Perform the association and set the next higher index
4485 to the limit. */
4486 data = bfd_getl16 (src_ptr + DST_S_W_SRC_UNSWORD);
4487 srec = (struct srecinfo *)
4488 bfd_zalloc (abfd, sizeof (struct srecinfo));
4489 srec->line = curr_srec->line + data;
4490 srec->srec = curr_srec->srec + data,
4491 srec->sfile = curr_srec->sfile;
4492 curr_srec->next = srec;
4493 curr_srec = srec;
4494 cmd_length = 3;
4495 vms_debug2 ((4, "DST_S_C_SRC_DEFLINES_W: %d\n", data));
4496 break;
4497
4498 case DST__K_SRC_INCRLNUM_B:
4499 data = src_ptr[DST_S_B_SRC_UNSBYTE];
4500 curr_srec->line += data;
4501 cmd_length = 2;
4502 vms_debug2 ((4, "DST_S_C_SRC_INCRLNUM_B: %d\n", data));
4503 break;
4504
4505 case DST__K_SRC_SETFILE:
4506 data = bfd_getl16 (src_ptr + DST_S_W_SRC_UNSWORD);
4507 curr_srec->sfile = data;
4508 curr_srec->srec = module->file_table[data].srec;
4509 cmd_length = 3;
4510 vms_debug2 ((4, "DST_S_C_SRC_SETFILE: %d\n", data));
4511 break;
4512
4513 case DST__K_SRC_SETLNUM_L:
4514 data = bfd_getl32 (src_ptr + DST_S_L_SRC_UNSLONG);
4515 curr_srec->line = data;
4516 cmd_length = 5;
4517 vms_debug2 ((4, "DST_S_C_SRC_SETLNUM_L: %d\n", data));
4518 break;
4519
4520 case DST__K_SRC_SETLNUM_W:
4521 data = bfd_getl16 (src_ptr + DST_S_W_SRC_UNSWORD);
4522 curr_srec->line = data;
4523 cmd_length = 3;
4524 vms_debug2 ((4, "DST_S_C_SRC_SETLNUM_W: %d\n", data));
4525 break;
4526
4527 case DST__K_SRC_SETREC_L:
4528 data = bfd_getl32 (src_ptr + DST_S_L_SRC_UNSLONG);
4529 curr_srec->srec = data;
4530 module->file_table[curr_srec->sfile].srec = data;
4531 cmd_length = 5;
4532 vms_debug2 ((4, "DST_S_C_SRC_SETREC_L: %d\n", data));
4533 break;
4534
4535 case DST__K_SRC_SETREC_W:
4536 data = bfd_getl16 (src_ptr + DST_S_W_SRC_UNSWORD);
4537 curr_srec->srec = data;
4538 module->file_table[curr_srec->sfile].srec = data;
4539 cmd_length = 3;
4540 vms_debug2 ((4, "DST_S_C_SRC_SETREC_W: %d\n", data));
4541 break;
4542
4543 case DST__K_SRC_FORMFEED:
4544 cmd_length = 1;
4545 vms_debug2 ((4, "DST_S_C_SRC_FORMFEED\n"));
4546 break;
4547
4548 default:
4eca0228
AM
4549 _bfd_error_handler (_("unknown source command %d"),
4550 cmd);
95e34ef7
TG
4551 cmd_length = 2;
4552 break;
4553 }
4554
4555 src_ptr += cmd_length;
4556 }
4557 break;
4558
4559 case DST__K_LINE_NUM:
4560 pcl_ptr = ptr + DST_S_C_LINE_NUM_HEADER_SIZE;
4561
4562 vms_debug2 ((3, "line info\n"));
4563
4564 while (pcl_ptr < ptr + rec_length)
4565 {
4566 /* The command byte is signed so we must sign-extend it. */
4567 int cmd = ((signed char *)pcl_ptr)[0], cmd_length, data;
4568
4569 switch (cmd)
4570 {
4571 case DST__K_DELTA_PC_W:
4572 data = bfd_getl16 (pcl_ptr + DST_S_W_PCLINE_UNSWORD);
4573 curr_pc += data;
4574 curr_linenum += 1;
4575 cmd_length = 3;
4576 vms_debug2 ((4, "DST__K_DELTA_PC_W: %d\n", data));
4577 break;
4578
4579 case DST__K_DELTA_PC_L:
4580 data = bfd_getl32 (pcl_ptr + DST_S_L_PCLINE_UNSLONG);
4581 curr_pc += data;
4582 curr_linenum += 1;
4583 cmd_length = 5;
4584 vms_debug2 ((4, "DST__K_DELTA_PC_L: %d\n", data));
4585 break;
4586
4587 case DST__K_INCR_LINUM:
4588 data = pcl_ptr[DST_S_B_PCLINE_UNSBYTE];
4589 curr_linenum += data;
4590 cmd_length = 2;
4591 vms_debug2 ((4, "DST__K_INCR_LINUM: %d\n", data));
4592 break;
4593
4594 case DST__K_INCR_LINUM_W:
4595 data = bfd_getl16 (pcl_ptr + DST_S_W_PCLINE_UNSWORD);
4596 curr_linenum += data;
4597 cmd_length = 3;
4598 vms_debug2 ((4, "DST__K_INCR_LINUM_W: %d\n", data));
4599 break;
4600
4601 case DST__K_INCR_LINUM_L:
4602 data = bfd_getl32 (pcl_ptr + DST_S_L_PCLINE_UNSLONG);
4603 curr_linenum += data;
4604 cmd_length = 5;
4605 vms_debug2 ((4, "DST__K_INCR_LINUM_L: %d\n", data));
4606 break;
4607
4608 case DST__K_SET_LINUM_INCR:
4eca0228 4609 _bfd_error_handler
38f14ab8 4610 (_("%s not implemented"), "DST__K_SET_LINUM_INCR");
95e34ef7
TG
4611 cmd_length = 2;
4612 break;
4613
4614 case DST__K_SET_LINUM_INCR_W:
4eca0228 4615 _bfd_error_handler
38f14ab8 4616 (_("%s not implemented"), "DST__K_SET_LINUM_INCR_W");
95e34ef7
TG
4617 cmd_length = 3;
4618 break;
4619
4620 case DST__K_RESET_LINUM_INCR:
4eca0228 4621 _bfd_error_handler
38f14ab8 4622 (_("%s not implemented"), "DST__K_RESET_LINUM_INCR");
95e34ef7
TG
4623 cmd_length = 1;
4624 break;
4625
4626 case DST__K_BEG_STMT_MODE:
4eca0228 4627 _bfd_error_handler
38f14ab8 4628 (_("%s not implemented"), "DST__K_BEG_STMT_MODE");
95e34ef7
TG
4629 cmd_length = 1;
4630 break;
4631
4632 case DST__K_END_STMT_MODE:
4eca0228 4633 _bfd_error_handler
38f14ab8 4634 (_("%s not implemented"), "DST__K_END_STMT_MODE");
95e34ef7
TG
4635 cmd_length = 1;
4636 break;
4637
4638 case DST__K_SET_LINUM_B:
4639 data = pcl_ptr[DST_S_B_PCLINE_UNSBYTE];
4640 curr_linenum = data;
4641 cmd_length = 2;
4642 vms_debug2 ((4, "DST__K_SET_LINUM_B: %d\n", data));
4643 break;
4644
4645 case DST__K_SET_LINUM:
4646 data = bfd_getl16 (pcl_ptr + DST_S_W_PCLINE_UNSWORD);
4647 curr_linenum = data;
4648 cmd_length = 3;
4649 vms_debug2 ((4, "DST__K_SET_LINE_NUM: %d\n", data));
4650 break;
4651
4652 case DST__K_SET_LINUM_L:
4653 data = bfd_getl32 (pcl_ptr + DST_S_L_PCLINE_UNSLONG);
4654 curr_linenum = data;
4655 cmd_length = 5;
4656 vms_debug2 ((4, "DST__K_SET_LINUM_L: %d\n", data));
4657 break;
4658
4659 case DST__K_SET_PC:
4eca0228 4660 _bfd_error_handler
38f14ab8 4661 (_("%s not implemented"), "DST__K_SET_PC");
95e34ef7
TG
4662 cmd_length = 2;
4663 break;
4664
4665 case DST__K_SET_PC_W:
4eca0228 4666 _bfd_error_handler
38f14ab8 4667 (_("%s not implemented"), "DST__K_SET_PC_W");
95e34ef7
TG
4668 cmd_length = 3;
4669 break;
4670
4671 case DST__K_SET_PC_L:
4eca0228 4672 _bfd_error_handler
38f14ab8 4673 (_("%s not implemented"), "DST__K_SET_PC_L");
95e34ef7
TG
4674 cmd_length = 5;
4675 break;
4676
4677 case DST__K_SET_STMTNUM:
4eca0228 4678 _bfd_error_handler
38f14ab8 4679 (_("%s not implemented"), "DST__K_SET_STMTNUM");
95e34ef7
TG
4680 cmd_length = 2;
4681 break;
4682
4683 case DST__K_TERM:
4684 data = pcl_ptr[DST_S_B_PCLINE_UNSBYTE];
4685 curr_pc += data;
4686 cmd_length = 2;
4687 vms_debug2 ((4, "DST__K_TERM: %d\n", data));
4688 break;
4689
4690 case DST__K_TERM_W:
4691 data = bfd_getl16 (pcl_ptr + DST_S_W_PCLINE_UNSWORD);
4692 curr_pc += data;
4693 cmd_length = 3;
4694 vms_debug2 ((4, "DST__K_TERM_W: %d\n", data));
4695 break;
4696
4697 case DST__K_TERM_L:
4698 data = bfd_getl32 (pcl_ptr + DST_S_L_PCLINE_UNSLONG);
4699 curr_pc += data;
4700 cmd_length = 5;
4701 vms_debug2 ((4, "DST__K_TERM_L: %d\n", data));
4702 break;
4703
4704 case DST__K_SET_ABS_PC:
4705 data = bfd_getl32 (pcl_ptr + DST_S_L_PCLINE_UNSLONG);
4706 curr_pc = data;
4707 cmd_length = 5;
4708 vms_debug2 ((4, "DST__K_SET_ABS_PC: 0x%x\n", data));
4709 break;
4710
4711 default:
4712 if (cmd <= 0)
4713 {
4714 curr_pc -= cmd;
4715 curr_linenum += 1;
4716 cmd_length = 1;
4717 vms_debug2 ((4, "bump pc to 0x%lx and line to %d\n",
07d6d2b8 4718 (unsigned long)curr_pc, curr_linenum));
95e34ef7
TG
4719 }
4720 else
4721 {
4eca0228 4722 _bfd_error_handler (_("unknown line command %d"), cmd);
95e34ef7
TG
4723 cmd_length = 2;
4724 }
4725 break;
4726 }
4727
4728 if ((curr_linenum != prev_linum && curr_pc != prev_pc)
4729 || cmd <= 0
4730 || cmd == DST__K_DELTA_PC_L
4731 || cmd == DST__K_DELTA_PC_W)
4732 {
4733 line = (struct lineinfo *)
4734 bfd_zalloc (abfd, sizeof (struct lineinfo));
4735 line->address = curr_pc;
4736 line->line = curr_linenum;
4737
4738 curr_line->next = line;
4739 curr_line = line;
4740
4741 prev_linum = curr_linenum;
4742 prev_pc = curr_pc;
4743 vms_debug2 ((4, "-> correlate pc 0x%lx with line %d\n",
07d6d2b8 4744 (unsigned long)curr_pc, curr_linenum));
95e34ef7
TG
4745 }
4746
4747 pcl_ptr += cmd_length;
4748 }
4749 break;
4750
4751 case 0x17: /* Undocumented type used by DEC C to declare equates. */
4752 vms_debug2 ((3, "undocumented type 0x17\n"));
4753 break;
4754
4755 default:
4756 vms_debug2 ((3, "ignoring record\n"));
4757 break;
4758
4759 }
4760
4761 ptr += rec_length;
4762 }
4763
4764 /* Finalize tables with EOL marker. */
4765 srec = (struct srecinfo *) bfd_zalloc (abfd, sizeof (struct srecinfo));
4766 srec->line = (unsigned int) -1;
4767 srec->srec = (unsigned int) -1;
4768 curr_srec->next = srec;
4769
4770 line = (struct lineinfo *) bfd_zalloc (abfd, sizeof (struct lineinfo));
4771 line->line = (unsigned int) -1;
4772 line->address = (bfd_vma) -1;
4773 curr_line->next = line;
4774
4775 /* Advertise that this module has been parsed. This is needed
4776 because parsing can be either performed at module creation
4777 or deferred until debug info is consumed. */
4778 SET_MODULE_PARSED (module);
0a1b45a2 4779 return true;
95e34ef7
TG
4780}
4781
4782/* Build the list of modules for the specified BFD. */
4783
4784static struct module *
4785build_module_list (bfd *abfd)
4786{
4787 struct module *module, *list = NULL;
4788 asection *dmt;
4789
4790 if ((dmt = bfd_get_section_by_name (abfd, "$DMT$")))
4791 {
4792 /* We have a DMT section so this must be an image. Parse the
4793 section and build the list of modules. This is sufficient
4794 since we can compute the start address and the end address
4795 of every module from the section contents. */
fd361982 4796 bfd_size_type size = bfd_section_size (dmt);
3c8ed65a 4797 unsigned char *buf, *ptr, *end;
95e34ef7 4798
3c8ed65a 4799 if (! bfd_malloc_and_get_section (abfd, dmt, &buf))
95e34ef7
TG
4800 return NULL;
4801
4802 vms_debug2 ((2, "DMT\n"));
4803
3c8ed65a 4804 ptr = buf;
95e34ef7 4805 end = ptr + size;
ddbe6976 4806 while (end - ptr >= DBG_S_C_DMT_HEADER_SIZE)
95e34ef7
TG
4807 {
4808 /* Each header declares a module with its start offset and size
4809 of debug info in the DST section, as well as the count of
4810 program sections (i.e. address spans) it contains. */
3c8ed65a
AM
4811 unsigned int modbeg = bfd_getl32 (ptr + DBG_S_L_DMT_MODBEG);
4812 unsigned int msize = bfd_getl32 (ptr + DBG_S_L_DST_SIZE);
95e34ef7
TG
4813 int count = bfd_getl16 (ptr + DBG_S_W_DMT_PSECT_COUNT);
4814 ptr += DBG_S_C_DMT_HEADER_SIZE;
4815
3c8ed65a 4816 vms_debug2 ((3, "module: modbeg = %u, size = %u, count = %d\n",
07d6d2b8 4817 modbeg, msize, count));
95e34ef7
TG
4818
4819 /* We create a 'module' structure for each program section since
4820 we only support contiguous addresses in a 'module' structure.
4821 As a consequence, the actual debug info in the DST section is
4822 shared and can be parsed multiple times; that doesn't seem to
4823 cause problems in practice. */
ddbe6976 4824 while (count-- > 0 && end - ptr >= DBG_S_C_DMT_PSECT_SIZE)
95e34ef7 4825 {
3c8ed65a
AM
4826 unsigned int start = bfd_getl32 (ptr + DBG_S_L_DMT_PSECT_START);
4827 unsigned int length = bfd_getl32 (ptr + DBG_S_L_DMT_PSECT_LENGTH);
95e34ef7
TG
4828 module = new_module (abfd);
4829 module->modbeg = modbeg;
4830 module->size = msize;
4831 module->low = start;
4832 module->high = start + length;
4833 module->next = list;
4834 list = module;
4835 ptr += DBG_S_C_DMT_PSECT_SIZE;
4836
3c8ed65a 4837 vms_debug2 ((4, "section: start = 0x%x, length = %u\n",
07d6d2b8 4838 start, length));
95e34ef7
TG
4839 }
4840 }
3c8ed65a 4841 free (buf);
95e34ef7
TG
4842 }
4843 else
4844 {
4845 /* We don't have a DMT section so this must be an object. Parse
4846 the module right now in order to compute its start address and
4847 end address. */
8185f55c
TG
4848 void *dst = PRIV (dst_section)->contents;
4849
4850 if (dst == NULL)
07d6d2b8 4851 return NULL;
8185f55c 4852
95e34ef7 4853 module = new_module (abfd);
9cb56943
AM
4854 if (!parse_module (abfd, module, PRIV (dst_section)->contents, -1))
4855 return NULL;
95e34ef7
TG
4856 list = module;
4857 }
4858
4859 return list;
4860}
4861
4862/* Calculate and return the name of the source file and the line nearest
4863 to the wanted location in the specified module. */
4864
0a1b45a2 4865static bool
95e34ef7
TG
4866module_find_nearest_line (bfd *abfd, struct module *module, bfd_vma addr,
4867 const char **file, const char **func,
4868 unsigned int *line)
4869{
4870 struct funcinfo *funcinfo;
4871 struct lineinfo *lineinfo;
4872 struct srecinfo *srecinfo;
0a1b45a2 4873 bool ret = false;
95e34ef7
TG
4874
4875 /* Parse this module if that was not done at module creation. */
4876 if (! IS_MODULE_PARSED (module))
4877 {
4878 unsigned int size = module->size;
4879 unsigned int modbeg = PRIV (dst_section)->filepos + module->modbeg;
2bb3687b 4880 unsigned char *buffer;
95e34ef7
TG
4881
4882 if (bfd_seek (abfd, modbeg, SEEK_SET) != 0
2bb3687b 4883 || (buffer = _bfd_malloc_and_read (abfd, size, size)) == NULL)
95e34ef7
TG
4884 {
4885 bfd_set_error (bfd_error_no_debug_section);
0a1b45a2 4886 return false;
95e34ef7
TG
4887 }
4888
9cb56943 4889 ret = parse_module (abfd, module, buffer, size);
95e34ef7 4890 free (buffer);
9cb56943
AM
4891 if (!ret)
4892 return ret;
95e34ef7
TG
4893 }
4894
4895 /* Find out the function (if any) that contains the address. */
4896 for (funcinfo = module->func_table; funcinfo; funcinfo = funcinfo->next)
4897 if (addr >= funcinfo->low && addr <= funcinfo->high)
4898 {
07d6d2b8 4899 *func = funcinfo->name;
0a1b45a2 4900 ret = true;
95e34ef7
TG
4901 break;
4902 }
4903
4904 /* Find out the source file and the line nearest to the address. */
4905 for (lineinfo = module->line_table; lineinfo; lineinfo = lineinfo->next)
4906 if (lineinfo->next && addr < lineinfo->next->address)
4907 {
4908 for (srecinfo = module->srec_table; srecinfo; srecinfo = srecinfo->next)
4909 if (srecinfo->next && lineinfo->line < srecinfo->next->line)
4910 {
4911 if (srecinfo->sfile > 0)
4912 {
4913 *file = module->file_table[srecinfo->sfile].name;
4914 *line = srecinfo->srec + lineinfo->line - srecinfo->line;
4915 }
4916 else
4917 {
4918 *file = module->name;
4919 *line = lineinfo->line;
4920 }
0a1b45a2 4921 return true;
95e34ef7
TG
4922 }
4923
4924 break;
4925 }
4926
4927 return ret;
4928}
4929
4930/* Provided a BFD, a section and an offset into the section, calculate and
4931 return the name of the source file and the line nearest to the wanted
4932 location. */
4933
0a1b45a2 4934static bool
fb167eb2
AM
4935_bfd_vms_find_nearest_line (bfd *abfd,
4936 asymbol **symbols ATTRIBUTE_UNUSED,
4937 asection *section,
4938 bfd_vma offset,
4939 const char **file,
4940 const char **func,
4941 unsigned int *line,
4942 unsigned int *discriminator)
95e34ef7
TG
4943{
4944 struct module *module;
4945
4946 /* What address are we looking for? */
4947 bfd_vma addr = section->vma + offset;
4948
4949 *file = NULL;
4950 *func = NULL;
4951 *line = 0;
fb167eb2
AM
4952 if (discriminator)
4953 *discriminator = 0;
95e34ef7 4954
8185f55c 4955 /* We can't do anything if there is no DST (debug symbol table). */
a283ff93 4956 if (PRIV (dst_section) == NULL)
0a1b45a2 4957 return false;
95e34ef7 4958
8185f55c 4959 /* Create the module list - if not already done. */
95e34ef7
TG
4960 if (PRIV (modules) == NULL)
4961 {
4962 PRIV (modules) = build_module_list (abfd);
4963 if (PRIV (modules) == NULL)
0a1b45a2 4964 return false;
95e34ef7
TG
4965 }
4966
4967 for (module = PRIV (modules); module; module = module->next)
4968 if (addr >= module->low && addr <= module->high)
4969 return module_find_nearest_line (abfd, module, addr, file, func, line);
4970
0a1b45a2 4971 return false;
95e34ef7
TG
4972}
4973\f
4974/* Canonicalizations. */
4975/* Set name, value, section and flags of SYM from E. */
4976
0a1b45a2 4977static bool
95e34ef7
TG
4978alpha_vms_convert_symbol (bfd *abfd, struct vms_symbol_entry *e, asymbol *sym)
4979{
4980 flagword flags;
4981 symvalue value;
4982 asection *sec;
4983 const char *name;
4984
4985 name = e->name;
4986 value = 0;
4987 flags = BSF_NO_FLAGS;
4988 sec = NULL;
4989
4990 switch (e->typ)
4991 {
4992 case EGSD__C_SYM:
4993 if (e->flags & EGSY__V_WEAK)
07d6d2b8 4994 flags |= BSF_WEAK;
95e34ef7
TG
4995
4996 if (e->flags & EGSY__V_DEF)
07d6d2b8
AM
4997 {
4998 /* Symbol definition. */
4999 flags |= BSF_GLOBAL;
5000 if (e->flags & EGSY__V_NORM)
5001 flags |= BSF_FUNCTION;
5002 value = e->value;
5003 sec = e->section;
5004 }
95e34ef7 5005 else
07d6d2b8
AM
5006 {
5007 /* Symbol reference. */
5008 sec = bfd_und_section_ptr;
5009 }
95e34ef7
TG
5010 break;
5011
5012 case EGSD__C_SYMG:
5013 /* A universal symbol is by definition global... */
5014 flags |= BSF_GLOBAL;
5015
5016 /* ...and dynamic in shared libraries. */
5017 if (abfd->flags & DYNAMIC)
07d6d2b8 5018 flags |= BSF_DYNAMIC;
95e34ef7
TG
5019
5020 if (e->flags & EGSY__V_WEAK)
07d6d2b8 5021 flags |= BSF_WEAK;
95e34ef7
TG
5022
5023 if (!(e->flags & EGSY__V_DEF))
07d6d2b8 5024 abort ();
95e34ef7
TG
5025
5026 if (e->flags & EGSY__V_NORM)
07d6d2b8 5027 flags |= BSF_FUNCTION;
95e34ef7 5028
a928f1d7
TG
5029 value = e->value;
5030 /* sec = e->section; */
95e34ef7 5031 sec = bfd_abs_section_ptr;
95e34ef7
TG
5032 break;
5033
5034 default:
0a1b45a2 5035 return false;
95e34ef7
TG
5036 }
5037
5038 sym->name = name;
5039 sym->section = sec;
5040 sym->flags = flags;
5041 sym->value = value;
0a1b45a2 5042 return true;
95e34ef7
TG
5043}
5044
5045
5046/* Return the number of bytes required to store a vector of pointers
5047 to asymbols for all the symbols in the BFD abfd, including a
5048 terminal NULL pointer. If there are no symbols in the BFD,
5049 then return 0. If an error occurs, return -1. */
5050
5051static long
5052alpha_vms_get_symtab_upper_bound (bfd *abfd)
5053{
5054 vms_debug2 ((1, "alpha_vms_get_symtab_upper_bound (%p), %d symbols\n",
07d6d2b8 5055 abfd, PRIV (gsd_sym_count)));
95e34ef7
TG
5056
5057 return (PRIV (gsd_sym_count) + 1) * sizeof (asymbol *);
5058}
5059
5060/* Read the symbols from the BFD abfd, and fills in the vector
5061 location with pointers to the symbols and a trailing NULL.
5062
5063 Return number of symbols read. */
5064
5065static long
5066alpha_vms_canonicalize_symtab (bfd *abfd, asymbol **symbols)
5067{
5068 unsigned int i;
5069
5070 vms_debug2 ((1, "alpha_vms_canonicalize_symtab (%p, <ret>)\n", abfd));
5071
5072 if (PRIV (csymbols) == NULL)
5073 {
5074 PRIV (csymbols) = (asymbol **) bfd_alloc
07d6d2b8 5075 (abfd, PRIV (gsd_sym_count) * sizeof (asymbol *));
95e34ef7
TG
5076
5077 /* Traverse table and fill symbols vector. */
5078 for (i = 0; i < PRIV (gsd_sym_count); i++)
07d6d2b8
AM
5079 {
5080 struct vms_symbol_entry *e = PRIV (syms)[i];
5081 asymbol *sym;
95e34ef7 5082
07d6d2b8
AM
5083 sym = bfd_make_empty_symbol (abfd);
5084 if (sym == NULL || !alpha_vms_convert_symbol (abfd, e, sym))
5085 {
5086 bfd_release (abfd, PRIV (csymbols));
5087 PRIV (csymbols) = NULL;
5088 return -1;
5089 }
95e34ef7 5090
07d6d2b8
AM
5091 PRIV (csymbols)[i] = sym;
5092 }
95e34ef7
TG
5093 }
5094
5095 if (symbols != NULL)
5096 {
5097 for (i = 0; i < PRIV (gsd_sym_count); i++)
07d6d2b8 5098 symbols[i] = PRIV (csymbols)[i];
95e34ef7
TG
5099 symbols[i] = NULL;
5100 }
5101
5102 return PRIV (gsd_sym_count);
5103}
5104
5105/* Read and convert relocations from ETIR. We do it once for all sections. */
5106
0a1b45a2 5107static bool
95e34ef7
TG
5108alpha_vms_slurp_relocs (bfd *abfd)
5109{
5110 int cur_psect = -1;
5111
5112 vms_debug2 ((3, "alpha_vms_slurp_relocs\n"));
5113
5114 /* We slurp relocs only once, for all sections. */
5115 if (PRIV (reloc_done))
0a1b45a2
AM
5116 return true;
5117 PRIV (reloc_done) = true;
95e34ef7
TG
5118
5119 if (alpha_vms_canonicalize_symtab (abfd, NULL) < 0)
0a1b45a2 5120 return false;
95e34ef7
TG
5121
5122 if (bfd_seek (abfd, 0, SEEK_SET) != 0)
0a1b45a2 5123 return false;
95e34ef7
TG
5124
5125 while (1)
5126 {
5127 unsigned char *begin;
5128 unsigned char *end;
5129 unsigned char *ptr;
5130 bfd_reloc_code_real_type reloc_code;
5131 int type;
5132 bfd_vma vaddr = 0;
5133
5134 int length;
5135
5136 bfd_vma cur_address;
5137 int cur_psidx = -1;
5138 unsigned char *cur_sym = NULL;
5139 int prev_cmd = -1;
5140 bfd_vma cur_addend = 0;
5141
5142 /* Skip non-ETIR records. */
5143 type = _bfd_vms_get_object_record (abfd);
5144 if (type == EOBJ__C_EEOM)
07d6d2b8 5145 break;
95e34ef7 5146 if (type != EOBJ__C_ETIR)
07d6d2b8 5147 continue;
95e34ef7
TG
5148
5149 begin = PRIV (recrd.rec) + 4;
5150 end = PRIV (recrd.rec) + PRIV (recrd.rec_size);
5151
5152 for (ptr = begin; ptr < end; ptr += length)
07d6d2b8
AM
5153 {
5154 int cmd;
5155
5156 cmd = bfd_getl16 (ptr);
5157 length = bfd_getl16 (ptr + 2);
5158
5159 cur_address = vaddr;
5160
5161 vms_debug2 ((4, "alpha_vms_slurp_relocs: etir %s\n",
5162 _bfd_vms_etir_name (cmd)));
5163
5164 switch (cmd)
5165 {
5166 case ETIR__C_STA_GBL: /* ALPHA_R_REFLONG und_section, step 1 */
5167 /* ALPHA_R_REFQUAD und_section, step 1 */
5168 cur_sym = ptr + 4;
5169 prev_cmd = cmd;
5170 continue;
5171
5172 case ETIR__C_STA_PQ: /* ALPHA_R_REF{LONG|QUAD}, others part 1 */
5173 cur_psidx = bfd_getl32 (ptr + 4);
5174 cur_addend = bfd_getl64 (ptr + 8);
5175 prev_cmd = cmd;
5176 continue;
5177
5178 case ETIR__C_CTL_SETRB:
5179 if (prev_cmd != ETIR__C_STA_PQ)
5180 {
4eca0228 5181 _bfd_error_handler
695344c0 5182 /* xgettext:c-format */
38f14ab8 5183 (_("unknown reloc %s + %s"), _bfd_vms_etir_name (prev_cmd),
07d6d2b8 5184 _bfd_vms_etir_name (cmd));
0a1b45a2 5185 return false;
07d6d2b8
AM
5186 }
5187 cur_psect = cur_psidx;
5188 vaddr = cur_addend;
5189 cur_psidx = -1;
5190 cur_addend = 0;
5191 continue;
5192
5193 case ETIR__C_STA_LW: /* ALPHA_R_REFLONG abs_section, step 1 */
5194 /* ALPHA_R_REFLONG und_section, step 2 */
5195 if (prev_cmd != -1)
5196 {
5197 if (prev_cmd != ETIR__C_STA_GBL)
5198 {
4eca0228 5199 _bfd_error_handler
695344c0 5200 /* xgettext:c-format */
38f14ab8 5201 (_("unknown reloc %s + %s"), _bfd_vms_etir_name (cmd),
07d6d2b8 5202 _bfd_vms_etir_name (ETIR__C_STA_LW));
0a1b45a2 5203 return false;
07d6d2b8
AM
5204 }
5205 }
5206 cur_addend = bfd_getl32 (ptr + 4);
5207 prev_cmd = cmd;
5208 continue;
5209
5210 case ETIR__C_STA_QW: /* ALPHA_R_REFQUAD abs_section, step 1 */
5211 /* ALPHA_R_REFQUAD und_section, step 2 */
5212 if (prev_cmd != -1 && prev_cmd != ETIR__C_STA_GBL)
5213 {
4eca0228 5214 _bfd_error_handler
695344c0 5215 /* xgettext:c-format */
38f14ab8 5216 (_("unknown reloc %s + %s"), _bfd_vms_etir_name (cmd),
07d6d2b8 5217 _bfd_vms_etir_name (ETIR__C_STA_QW));
0a1b45a2 5218 return false;
07d6d2b8
AM
5219 }
5220 cur_addend = bfd_getl64 (ptr + 4);
5221 prev_cmd = cmd;
5222 continue;
5223
5224 case ETIR__C_STO_LW: /* ALPHA_R_REFLONG und_section, step 4 */
5225 /* ALPHA_R_REFLONG abs_section, step 2 */
5226 /* ALPHA_R_REFLONG others, step 2 */
5227 if (prev_cmd != ETIR__C_OPR_ADD
5228 && prev_cmd != ETIR__C_STA_LW
5229 && prev_cmd != ETIR__C_STA_PQ)
5230 {
695344c0 5231 /* xgettext:c-format */
38f14ab8 5232 _bfd_error_handler (_("unknown reloc %s + %s"),
4eca0228
AM
5233 _bfd_vms_etir_name (prev_cmd),
5234 _bfd_vms_etir_name (ETIR__C_STO_LW));
0a1b45a2 5235 return false;
07d6d2b8
AM
5236 }
5237 reloc_code = BFD_RELOC_32;
5238 break;
5239
5240 case ETIR__C_STO_QW: /* ALPHA_R_REFQUAD und_section, step 4 */
5241 /* ALPHA_R_REFQUAD abs_section, step 2 */
5242 if (prev_cmd != ETIR__C_OPR_ADD && prev_cmd != ETIR__C_STA_QW)
5243 {
695344c0 5244 /* xgettext:c-format */
38f14ab8 5245 _bfd_error_handler (_("unknown reloc %s + %s"),
4eca0228
AM
5246 _bfd_vms_etir_name (prev_cmd),
5247 _bfd_vms_etir_name (ETIR__C_STO_QW));
0a1b45a2 5248 return false;
07d6d2b8
AM
5249 }
5250 reloc_code = BFD_RELOC_64;
5251 break;
5252
5253 case ETIR__C_STO_OFF: /* ALPHA_R_REFQUAD others, step 2 */
5254 if (prev_cmd != ETIR__C_STA_PQ)
5255 {
695344c0 5256 /* xgettext:c-format */
38f14ab8 5257 _bfd_error_handler (_("unknown reloc %s + %s"),
4eca0228
AM
5258 _bfd_vms_etir_name (prev_cmd),
5259 _bfd_vms_etir_name (ETIR__C_STO_OFF));
0a1b45a2 5260 return false;
07d6d2b8
AM
5261 }
5262 reloc_code = BFD_RELOC_64;
5263 break;
5264
5265 case ETIR__C_OPR_ADD: /* ALPHA_R_REFLONG und_section, step 3 */
5266 /* ALPHA_R_REFQUAD und_section, step 3 */
5267 if (prev_cmd != ETIR__C_STA_LW && prev_cmd != ETIR__C_STA_QW)
5268 {
695344c0 5269 /* xgettext:c-format */
38f14ab8 5270 _bfd_error_handler (_("unknown reloc %s + %s"),
4eca0228
AM
5271 _bfd_vms_etir_name (prev_cmd),
5272 _bfd_vms_etir_name (ETIR__C_OPR_ADD));
0a1b45a2 5273 return false;
07d6d2b8
AM
5274 }
5275 prev_cmd = ETIR__C_OPR_ADD;
5276 continue;
5277
5278 case ETIR__C_STO_CA: /* ALPHA_R_CODEADDR */
5279 reloc_code = BFD_RELOC_ALPHA_CODEADDR;
5280 cur_sym = ptr + 4;
5281 break;
5282
5283 case ETIR__C_STO_GBL: /* ALPHA_R_REFQUAD und_section */
5284 reloc_code = BFD_RELOC_64;
5285 cur_sym = ptr + 4;
5286 break;
5287
5288 case ETIR__C_STO_GBL_LW: /* ALPHA_R_REFLONG und_section */
5289 reloc_code = BFD_RELOC_32;
5290 cur_sym = ptr + 4;
5291 break;
5292
5293 case ETIR__C_STC_LP_PSB: /* ALPHA_R_LINKAGE */
5294 reloc_code = BFD_RELOC_ALPHA_LINKAGE;
5295 cur_sym = ptr + 8;
5296 break;
5297
5298 case ETIR__C_STC_NOP_GBL: /* ALPHA_R_NOP */
5299 reloc_code = BFD_RELOC_ALPHA_NOP;
5300 goto call_reloc;
5301
5302 case ETIR__C_STC_BSR_GBL: /* ALPHA_R_BSR */
5303 reloc_code = BFD_RELOC_ALPHA_BSR;
5304 goto call_reloc;
5305
5306 case ETIR__C_STC_LDA_GBL: /* ALPHA_R_LDA */
5307 reloc_code = BFD_RELOC_ALPHA_LDA;
5308 goto call_reloc;
5309
5310 case ETIR__C_STC_BOH_GBL: /* ALPHA_R_BOH */
5311 reloc_code = BFD_RELOC_ALPHA_BOH;
5312 goto call_reloc;
5313
5314 call_reloc:
5315 cur_sym = ptr + 4 + 32;
5316 cur_address = bfd_getl64 (ptr + 4 + 8);
5317 cur_addend = bfd_getl64 (ptr + 4 + 24);
5318 break;
5319
5320 case ETIR__C_STO_IMM:
5321 vaddr += bfd_getl32 (ptr + 4);
5322 continue;
5323
5324 default:
38f14ab8 5325 _bfd_error_handler (_("unknown reloc %s"),
4eca0228 5326 _bfd_vms_etir_name (cmd));
0a1b45a2 5327 return false;
07d6d2b8 5328 }
95e34ef7 5329
07d6d2b8
AM
5330 {
5331 asection *sec;
5332 struct vms_section_data_struct *vms_sec;
5333 arelent *reloc;
706704c8 5334 bfd_size_type size;
95e34ef7 5335
07d6d2b8
AM
5336 /* Get section to which the relocation applies. */
5337 if (cur_psect < 0 || cur_psect > (int)PRIV (section_count))
5338 {
38f14ab8 5339 _bfd_error_handler (_("invalid section index in ETIR"));
0a1b45a2 5340 return false;
07d6d2b8 5341 }
d120eec2 5342
cb06d03a 5343 if (PRIV (sections) == NULL)
0a1b45a2 5344 return false;
07d6d2b8
AM
5345 sec = PRIV (sections)[cur_psect];
5346 if (sec == bfd_abs_section_ptr)
5347 {
38f14ab8 5348 _bfd_error_handler (_("relocation for non-REL psect"));
0a1b45a2 5349 return false;
07d6d2b8
AM
5350 }
5351
5352 vms_sec = vms_section_data (sec);
5353
5354 /* Allocate a reloc entry. */
5355 if (sec->reloc_count >= vms_sec->reloc_max)
5356 {
5357 if (vms_sec->reloc_max == 0)
5358 {
5359 vms_sec->reloc_max = 64;
5360 sec->relocation = bfd_zmalloc
5361 (vms_sec->reloc_max * sizeof (arelent));
5362 }
5363 else
5364 {
5365 vms_sec->reloc_max *= 2;
9cb56943 5366 sec->relocation = bfd_realloc_or_free
07d6d2b8 5367 (sec->relocation, vms_sec->reloc_max * sizeof (arelent));
9cb56943 5368 if (sec->relocation == NULL)
0a1b45a2 5369 return false;
07d6d2b8
AM
5370 }
5371 }
5372 reloc = &sec->relocation[sec->reloc_count];
5373 sec->reloc_count++;
5374
5375 reloc->howto = bfd_reloc_type_lookup (abfd, reloc_code);
5376
5377 if (cur_sym != NULL)
5378 {
5379 unsigned int j;
5380 unsigned int symlen = *cur_sym;
5381 asymbol **sym;
5382
5383 /* Linear search. */
5384 symlen = *cur_sym;
5385 cur_sym++;
5386 sym = NULL;
5387
5388 for (j = 0; j < PRIV (gsd_sym_count); j++)
5389 if (PRIV (syms)[j]->namelen == symlen
5390 && memcmp (PRIV (syms)[j]->name, cur_sym, symlen) == 0)
5391 {
5392 sym = &PRIV (csymbols)[j];
5393 break;
5394 }
5395 if (sym == NULL)
5396 {
38f14ab8 5397 _bfd_error_handler (_("unknown symbol in command %s"),
4eca0228 5398 _bfd_vms_etir_name (cmd));
07d6d2b8
AM
5399 reloc->sym_ptr_ptr = NULL;
5400 }
5401 else
5402 reloc->sym_ptr_ptr = sym;
5403 }
5404 else if (cur_psidx >= 0)
cb06d03a 5405 {
ca4cf9b9 5406 if (PRIV (sections) == NULL || cur_psidx >= (int) PRIV (section_count))
0a1b45a2 5407 return false;
cb06d03a
NC
5408 reloc->sym_ptr_ptr =
5409 PRIV (sections)[cur_psidx]->symbol_ptr_ptr;
5410 }
07d6d2b8
AM
5411 else
5412 reloc->sym_ptr_ptr = NULL;
95e34ef7 5413
07d6d2b8
AM
5414 reloc->address = cur_address;
5415 reloc->addend = cur_addend;
95e34ef7 5416
706704c8
AM
5417 if (reloc_code == ALPHA_R_LINKAGE)
5418 size = 16;
5419 else
5420 size = bfd_get_reloc_size (reloc->howto);
5421 vaddr += size;
07d6d2b8 5422 }
95e34ef7 5423
07d6d2b8
AM
5424 cur_addend = 0;
5425 prev_cmd = -1;
5426 cur_sym = NULL;
5427 cur_psidx = -1;
5428 }
95e34ef7 5429 }
0a1b45a2 5430 vms_debug2 ((3, "alpha_vms_slurp_relocs: result = true\n"));
95e34ef7 5431
0a1b45a2 5432 return true;
95e34ef7
TG
5433}
5434
5435/* Return the number of bytes required to store the relocation
5436 information associated with the given section. */
5437
5438static long
5439alpha_vms_get_reloc_upper_bound (bfd *abfd ATTRIBUTE_UNUSED, asection *section)
5440{
5441 alpha_vms_slurp_relocs (abfd);
5442
5cfe19e5 5443 return (section->reloc_count + 1L) * sizeof (arelent *);
95e34ef7
TG
5444}
5445
5446/* Convert relocations from VMS (external) form into BFD internal
5447 form. Return the number of relocations. */
5448
5449static long
5450alpha_vms_canonicalize_reloc (bfd *abfd, asection *section, arelent **relptr,
07d6d2b8 5451 asymbol **symbols ATTRIBUTE_UNUSED)
95e34ef7
TG
5452{
5453 arelent *tblptr;
5454 int count;
5455
5456 if (!alpha_vms_slurp_relocs (abfd))
5457 return -1;
5458
5459 count = section->reloc_count;
5460 tblptr = section->relocation;
5461
5462 while (count--)
5463 *relptr++ = tblptr++;
5464
5465 *relptr = (arelent *) NULL;
5466 return section->reloc_count;
5467}
23186865
JM
5468
5469/* Install a new set of internal relocs. */
5470
5471#define alpha_vms_set_reloc _bfd_generic_set_reloc
5472
95e34ef7
TG
5473\f
5474/* This is just copied from ecoff-alpha, needs to be fixed probably. */
5475
5476/* How to process the various reloc types. */
5477
5478static bfd_reloc_status_type
5479reloc_nil (bfd * abfd ATTRIBUTE_UNUSED,
5480 arelent *reloc ATTRIBUTE_UNUSED,
5481 asymbol *sym ATTRIBUTE_UNUSED,
5482 void * data ATTRIBUTE_UNUSED,
5483 asection *sec ATTRIBUTE_UNUSED,
5484 bfd *output_bfd ATTRIBUTE_UNUSED,
5485 char **error_message ATTRIBUTE_UNUSED)
5486{
5487#if VMS_DEBUG
5488 vms_debug (1, "reloc_nil (abfd %p, output_bfd %p)\n", abfd, output_bfd);
5489 vms_debug (2, "In section %s, symbol %s\n",
5490 sec->name, sym->name);
5491 vms_debug (2, "reloc sym %s, addr %08lx, addend %08lx, reloc is a %s\n",
5492 reloc->sym_ptr_ptr[0]->name,
5493 (unsigned long)reloc->address,
5494 (unsigned long)reloc->addend, reloc->howto->name);
5495 vms_debug (2, "data at %p\n", data);
5496 /* _bfd_hexdump (2, data, bfd_get_reloc_size (reloc->howto), 0); */
5497#endif
5498
5499 return bfd_reloc_ok;
5500}
5501
5502/* In case we're on a 32-bit machine, construct a 64-bit "-1" value
5503 from smaller values. Start with zero, widen, *then* decrement. */
5504#define MINUS_ONE (((bfd_vma)0) - 1)
5505
5506static reloc_howto_type alpha_howto_table[] =
5507{
5508 HOWTO (ALPHA_R_IGNORE, /* Type. */
5509 0, /* Rightshift. */
5510 0, /* Size (0 = byte, 1 = short, 2 = long). */
5511 8, /* Bitsize. */
0a1b45a2 5512 true, /* PC relative. */
95e34ef7
TG
5513 0, /* Bitpos. */
5514 complain_overflow_dont,/* Complain_on_overflow. */
5515 reloc_nil, /* Special_function. */
5516 "IGNORE", /* Name. */
0a1b45a2 5517 true, /* Partial_inplace. */
95e34ef7
TG
5518 0, /* Source mask */
5519 0, /* Dest mask. */
0a1b45a2 5520 true), /* PC rel offset. */
95e34ef7
TG
5521
5522 /* A 64 bit reference to a symbol. */
5523 HOWTO (ALPHA_R_REFQUAD, /* Type. */
5524 0, /* Rightshift. */
5525 4, /* Size (0 = byte, 1 = short, 2 = long). */
5526 64, /* Bitsize. */
0a1b45a2 5527 false, /* PC relative. */
95e34ef7
TG
5528 0, /* Bitpos. */
5529 complain_overflow_bitfield, /* Complain_on_overflow. */
5530 reloc_nil, /* Special_function. */
5531 "REFQUAD", /* Name. */
0a1b45a2 5532 true, /* Partial_inplace. */
95e34ef7
TG
5533 MINUS_ONE, /* Source mask. */
5534 MINUS_ONE, /* Dest mask. */
0a1b45a2 5535 false), /* PC rel offset. */
95e34ef7
TG
5536
5537 /* A 21 bit branch. The native assembler generates these for
5538 branches within the text segment, and also fills in the PC
5539 relative offset in the instruction. */
5540 HOWTO (ALPHA_R_BRADDR, /* Type. */
5541 2, /* Rightshift. */
5542 2, /* Size (0 = byte, 1 = short, 2 = long). */
5543 21, /* Bitsize. */
0a1b45a2 5544 true, /* PC relative. */
95e34ef7
TG
5545 0, /* Bitpos. */
5546 complain_overflow_signed, /* Complain_on_overflow. */
5547 reloc_nil, /* Special_function. */
5548 "BRADDR", /* Name. */
0a1b45a2 5549 true, /* Partial_inplace. */
95e34ef7
TG
5550 0x1fffff, /* Source mask. */
5551 0x1fffff, /* Dest mask. */
0a1b45a2 5552 false), /* PC rel offset. */
95e34ef7
TG
5553
5554 /* A hint for a jump to a register. */
5555 HOWTO (ALPHA_R_HINT, /* Type. */
5556 2, /* Rightshift. */
5557 1, /* Size (0 = byte, 1 = short, 2 = long). */
5558 14, /* Bitsize. */
0a1b45a2 5559 true, /* PC relative. */
95e34ef7
TG
5560 0, /* Bitpos. */
5561 complain_overflow_dont,/* Complain_on_overflow. */
5562 reloc_nil, /* Special_function. */
5563 "HINT", /* Name. */
0a1b45a2 5564 true, /* Partial_inplace. */
95e34ef7
TG
5565 0x3fff, /* Source mask. */
5566 0x3fff, /* Dest mask. */
0a1b45a2 5567 false), /* PC rel offset. */
95e34ef7
TG
5568
5569 /* 16 bit PC relative offset. */
5570 HOWTO (ALPHA_R_SREL16, /* Type. */
5571 0, /* Rightshift. */
5572 1, /* Size (0 = byte, 1 = short, 2 = long). */
5573 16, /* Bitsize. */
0a1b45a2 5574 true, /* PC relative. */
95e34ef7
TG
5575 0, /* Bitpos. */
5576 complain_overflow_signed, /* Complain_on_overflow. */
5577 reloc_nil, /* Special_function. */
5578 "SREL16", /* Name. */
0a1b45a2 5579 true, /* Partial_inplace. */
95e34ef7
TG
5580 0xffff, /* Source mask. */
5581 0xffff, /* Dest mask. */
0a1b45a2 5582 false), /* PC rel offset. */
95e34ef7
TG
5583
5584 /* 32 bit PC relative offset. */
5585 HOWTO (ALPHA_R_SREL32, /* Type. */
5586 0, /* Rightshift. */
5587 2, /* Size (0 = byte, 1 = short, 2 = long). */
5588 32, /* Bitsize. */
0a1b45a2 5589 true, /* PC relative. */
95e34ef7
TG
5590 0, /* Bitpos. */
5591 complain_overflow_signed, /* Complain_on_overflow. */
5592 reloc_nil, /* Special_function. */
5593 "SREL32", /* Name. */
0a1b45a2 5594 true, /* Partial_inplace. */
95e34ef7
TG
5595 0xffffffff, /* Source mask. */
5596 0xffffffff, /* Dest mask. */
0a1b45a2 5597 false), /* PC rel offset. */
95e34ef7
TG
5598
5599 /* A 64 bit PC relative offset. */
5600 HOWTO (ALPHA_R_SREL64, /* Type. */
5601 0, /* Rightshift. */
5602 4, /* Size (0 = byte, 1 = short, 2 = long). */
5603 64, /* Bitsize. */
0a1b45a2 5604 true, /* PC relative. */
95e34ef7
TG
5605 0, /* Bitpos. */
5606 complain_overflow_signed, /* Complain_on_overflow. */
5607 reloc_nil, /* Special_function. */
5608 "SREL64", /* Name. */
0a1b45a2 5609 true, /* Partial_inplace. */
95e34ef7
TG
5610 MINUS_ONE, /* Source mask. */
5611 MINUS_ONE, /* Dest mask. */
0a1b45a2 5612 false), /* PC rel offset. */
95e34ef7
TG
5613
5614 /* Push a value on the reloc evaluation stack. */
5615 HOWTO (ALPHA_R_OP_PUSH, /* Type. */
5616 0, /* Rightshift. */
5617 0, /* Size (0 = byte, 1 = short, 2 = long). */
5618 0, /* Bitsize. */
0a1b45a2 5619 false, /* PC relative. */
95e34ef7
TG
5620 0, /* Bitpos. */
5621 complain_overflow_dont,/* Complain_on_overflow. */
5622 reloc_nil, /* Special_function. */
5623 "OP_PUSH", /* Name. */
0a1b45a2 5624 false, /* Partial_inplace. */
95e34ef7
TG
5625 0, /* Source mask. */
5626 0, /* Dest mask. */
0a1b45a2 5627 false), /* PC rel offset. */
95e34ef7
TG
5628
5629 /* Store the value from the stack at the given address. Store it in
5630 a bitfield of size r_size starting at bit position r_offset. */
5631 HOWTO (ALPHA_R_OP_STORE, /* Type. */
5632 0, /* Rightshift. */
5633 4, /* Size (0 = byte, 1 = short, 2 = long). */
5634 64, /* Bitsize. */
0a1b45a2 5635 false, /* PC relative. */
95e34ef7
TG
5636 0, /* Bitpos. */
5637 complain_overflow_dont,/* Complain_on_overflow. */
5638 reloc_nil, /* Special_function. */
5639 "OP_STORE", /* Name. */
0a1b45a2 5640 false, /* Partial_inplace. */
95e34ef7
TG
5641 0, /* Source mask. */
5642 MINUS_ONE, /* Dest mask. */
0a1b45a2 5643 false), /* PC rel offset. */
95e34ef7
TG
5644
5645 /* Subtract the reloc address from the value on the top of the
5646 relocation stack. */
5647 HOWTO (ALPHA_R_OP_PSUB, /* Type. */
5648 0, /* Rightshift. */
5649 0, /* Size (0 = byte, 1 = short, 2 = long). */
5650 0, /* Bitsize. */
0a1b45a2 5651 false, /* PC relative. */
95e34ef7
TG
5652 0, /* Bitpos. */
5653 complain_overflow_dont,/* Complain_on_overflow. */
5654 reloc_nil, /* Special_function. */
5655 "OP_PSUB", /* Name. */
0a1b45a2 5656 false, /* Partial_inplace. */
95e34ef7
TG
5657 0, /* Source mask. */
5658 0, /* Dest mask. */
0a1b45a2 5659 false), /* PC rel offset. */
95e34ef7
TG
5660
5661 /* Shift the value on the top of the relocation stack right by the
5662 given value. */
5663 HOWTO (ALPHA_R_OP_PRSHIFT, /* Type. */
5664 0, /* Rightshift. */
5665 0, /* Size (0 = byte, 1 = short, 2 = long). */
5666 0, /* Bitsize. */
0a1b45a2 5667 false, /* PC relative. */
95e34ef7
TG
5668 0, /* Bitpos. */
5669 complain_overflow_dont,/* Complain_on_overflow. */
5670 reloc_nil, /* Special_function. */
5671 "OP_PRSHIFT", /* Name. */
0a1b45a2 5672 false, /* Partial_inplace. */
95e34ef7
TG
5673 0, /* Source mask. */
5674 0, /* Dest mask. */
0a1b45a2 5675 false), /* PC rel offset. */
95e34ef7
TG
5676
5677 /* Hack. Linkage is done by linker. */
5678 HOWTO (ALPHA_R_LINKAGE, /* Type. */
5679 0, /* Rightshift. */
706704c8
AM
5680 0, /* Size (0 = byte, 1 = short, 2 = long). */
5681 0, /* Bitsize. */
0a1b45a2 5682 false, /* PC relative. */
95e34ef7
TG
5683 0, /* Bitpos. */
5684 complain_overflow_dont,/* Complain_on_overflow. */
5685 reloc_nil, /* Special_function. */
5686 "LINKAGE", /* Name. */
0a1b45a2 5687 false, /* Partial_inplace. */
95e34ef7
TG
5688 0, /* Source mask. */
5689 0, /* Dest mask. */
0a1b45a2 5690 false), /* PC rel offset. */
95e34ef7
TG
5691
5692 /* A 32 bit reference to a symbol. */
5693 HOWTO (ALPHA_R_REFLONG, /* Type. */
5694 0, /* Rightshift. */
5695 2, /* Size (0 = byte, 1 = short, 2 = long). */
5696 32, /* Bitsize. */
0a1b45a2 5697 false, /* PC relative. */
95e34ef7
TG
5698 0, /* Bitpos. */
5699 complain_overflow_bitfield, /* Complain_on_overflow. */
5700 reloc_nil, /* Special_function. */
5701 "REFLONG", /* Name. */
0a1b45a2 5702 true, /* Partial_inplace. */
95e34ef7
TG
5703 0xffffffff, /* Source mask. */
5704 0xffffffff, /* Dest mask. */
0a1b45a2 5705 false), /* PC rel offset. */
95e34ef7
TG
5706
5707 /* A 64 bit reference to a procedure, written as 32 bit value. */
5708 HOWTO (ALPHA_R_CODEADDR, /* Type. */
5709 0, /* Rightshift. */
5710 4, /* Size (0 = byte, 1 = short, 2 = long). */
5711 64, /* Bitsize. */
0a1b45a2 5712 false, /* PC relative. */
95e34ef7
TG
5713 0, /* Bitpos. */
5714 complain_overflow_signed,/* Complain_on_overflow. */
5715 reloc_nil, /* Special_function. */
5716 "CODEADDR", /* Name. */
0a1b45a2 5717 false, /* Partial_inplace. */
95e34ef7
TG
5718 0xffffffff, /* Source mask. */
5719 0xffffffff, /* Dest mask. */
0a1b45a2 5720 false), /* PC rel offset. */
95e34ef7
TG
5721
5722 HOWTO (ALPHA_R_NOP, /* Type. */
5723 0, /* Rightshift. */
5724 3, /* Size (0 = byte, 1 = short, 2 = long). */
5725 0, /* Bitsize. */
5726 /* The following value must match that of ALPHA_R_BSR/ALPHA_R_BOH
5727 because the calculations for the 3 relocations are the same.
5728 See B.4.5.2 of the OpenVMS Linker Utility Manual. */
0a1b45a2 5729 true, /* PC relative. */
95e34ef7
TG
5730 0, /* Bitpos. */
5731 complain_overflow_dont,/* Complain_on_overflow. */
5732 reloc_nil, /* Special_function. */
5733 "NOP", /* Name. */
0a1b45a2 5734 false, /* Partial_inplace. */
95e34ef7
TG
5735 0xffffffff, /* Source mask. */
5736 0xffffffff, /* Dest mask. */
0a1b45a2 5737 false), /* PC rel offset. */
95e34ef7
TG
5738
5739 HOWTO (ALPHA_R_BSR, /* Type. */
5740 0, /* Rightshift. */
5741 3, /* Size (0 = byte, 1 = short, 2 = long). */
5742 0, /* Bitsize. */
0a1b45a2 5743 true, /* PC relative. */
95e34ef7
TG
5744 0, /* Bitpos. */
5745 complain_overflow_dont,/* Complain_on_overflow. */
5746 reloc_nil, /* Special_function. */
5747 "BSR", /* Name. */
0a1b45a2 5748 false, /* Partial_inplace. */
95e34ef7
TG
5749 0xffffffff, /* Source mask. */
5750 0xffffffff, /* Dest mask. */
0a1b45a2 5751 false), /* PC rel offset. */
95e34ef7
TG
5752
5753 HOWTO (ALPHA_R_LDA, /* Type. */
5754 0, /* Rightshift. */
5755 3, /* Size (0 = byte, 1 = short, 2 = long). */
5756 0, /* Bitsize. */
0a1b45a2 5757 false, /* PC relative. */
95e34ef7
TG
5758 0, /* Bitpos. */
5759 complain_overflow_dont,/* Complain_on_overflow. */
5760 reloc_nil, /* Special_function. */
5761 "LDA", /* Name. */
0a1b45a2 5762 false, /* Partial_inplace. */
95e34ef7
TG
5763 0xffffffff, /* Source mask. */
5764 0xffffffff, /* Dest mask. */
0a1b45a2 5765 false), /* PC rel offset. */
95e34ef7
TG
5766
5767 HOWTO (ALPHA_R_BOH, /* Type. */
5768 0, /* Rightshift. */
5769 3, /* Size (0 = byte, 1 = short, 2 = long, 3 = nil). */
5770 0, /* Bitsize. */
0a1b45a2 5771 true, /* PC relative. */
95e34ef7
TG
5772 0, /* Bitpos. */
5773 complain_overflow_dont,/* Complain_on_overflow. */
5774 reloc_nil, /* Special_function. */
5775 "BOH", /* Name. */
0a1b45a2 5776 false, /* Partial_inplace. */
95e34ef7
TG
5777 0xffffffff, /* Source mask. */
5778 0xffffffff, /* Dest mask. */
0a1b45a2 5779 false), /* PC rel offset. */
95e34ef7
TG
5780};
5781
5782/* Return a pointer to a howto structure which, when invoked, will perform
5783 the relocation code on data from the architecture noted. */
5784
487096bf 5785static reloc_howto_type *
95e34ef7 5786alpha_vms_bfd_reloc_type_lookup (bfd * abfd ATTRIBUTE_UNUSED,
07d6d2b8 5787 bfd_reloc_code_real_type code)
95e34ef7
TG
5788{
5789 int alpha_type;
5790
5791 vms_debug2 ((1, "vms_bfd_reloc_type_lookup (%p, %d)\t", abfd, code));
5792
5793 switch (code)
5794 {
5795 case BFD_RELOC_16: alpha_type = ALPHA_R_SREL16; break;
5796 case BFD_RELOC_32: alpha_type = ALPHA_R_REFLONG; break;
5797 case BFD_RELOC_64: alpha_type = ALPHA_R_REFQUAD; break;
5798 case BFD_RELOC_CTOR: alpha_type = ALPHA_R_REFQUAD; break;
5799 case BFD_RELOC_23_PCREL_S2: alpha_type = ALPHA_R_BRADDR; break;
5800 case BFD_RELOC_ALPHA_HINT: alpha_type = ALPHA_R_HINT; break;
5801 case BFD_RELOC_16_PCREL: alpha_type = ALPHA_R_SREL16; break;
5802 case BFD_RELOC_32_PCREL: alpha_type = ALPHA_R_SREL32; break;
5803 case BFD_RELOC_64_PCREL: alpha_type = ALPHA_R_SREL64; break;
5804 case BFD_RELOC_ALPHA_LINKAGE: alpha_type = ALPHA_R_LINKAGE; break;
5805 case BFD_RELOC_ALPHA_CODEADDR: alpha_type = ALPHA_R_CODEADDR; break;
5806 case BFD_RELOC_ALPHA_NOP: alpha_type = ALPHA_R_NOP; break;
5807 case BFD_RELOC_ALPHA_BSR: alpha_type = ALPHA_R_BSR; break;
5808 case BFD_RELOC_ALPHA_LDA: alpha_type = ALPHA_R_LDA; break;
5809 case BFD_RELOC_ALPHA_BOH: alpha_type = ALPHA_R_BOH; break;
5810 default:
695344c0 5811 _bfd_error_handler (_("reloc (%d) is *UNKNOWN*"), code);
95e34ef7
TG
5812 return NULL;
5813 }
5814 vms_debug2 ((2, "reloc is %s\n", alpha_howto_table[alpha_type].name));
5815 return & alpha_howto_table[alpha_type];
5816}
5817
5818static reloc_howto_type *
5819alpha_vms_bfd_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
07d6d2b8 5820 const char *r_name)
95e34ef7
TG
5821{
5822 unsigned int i;
5823
5824 for (i = 0;
5825 i < sizeof (alpha_howto_table) / sizeof (alpha_howto_table[0]);
5826 i++)
5827 if (alpha_howto_table[i].name != NULL
5828 && strcasecmp (alpha_howto_table[i].name, r_name) == 0)
5829 return &alpha_howto_table[i];
5830
5831 return NULL;
5832}
5833\f
5834static long
5835alpha_vms_get_synthetic_symtab (bfd *abfd,
07d6d2b8
AM
5836 long symcount ATTRIBUTE_UNUSED,
5837 asymbol **usyms ATTRIBUTE_UNUSED,
5838 long dynsymcount ATTRIBUTE_UNUSED,
5839 asymbol **dynsyms ATTRIBUTE_UNUSED,
5840 asymbol **ret)
95e34ef7
TG
5841{
5842 asymbol *syms;
5843 unsigned int i;
5844 unsigned int n = 0;
5845
5846 syms = (asymbol *) bfd_malloc (PRIV (norm_sym_count) * sizeof (asymbol));
5847 *ret = syms;
5848 if (syms == NULL)
5849 return -1;
5850
5851 for (i = 0; i < PRIV (gsd_sym_count); i++)
5852 {
5853 struct vms_symbol_entry *e = PRIV (syms)[i];
5854 asymbol *sym;
5855 flagword flags;
5856 symvalue value;
5857 asection *sec;
5858 const char *name;
5859 char *sname;
5860 int l;
5861
5862 name = e->name;
5863 value = 0;
5864 flags = BSF_LOCAL | BSF_SYNTHETIC;
5865 sec = NULL;
5866
5867 switch (e->typ)
07d6d2b8
AM
5868 {
5869 case EGSD__C_SYM:
5870 case EGSD__C_SYMG:
5871 if ((e->flags & EGSY__V_DEF) && (e->flags & EGSY__V_NORM))
5872 {
5873 value = e->code_value;
5874 sec = e->code_section;
5875 }
5876 else
5877 continue;
5878 break;
5879
5880 default:
5881 continue;
5882 }
95e34ef7
TG
5883
5884 l = strlen (name);
5885 sname = bfd_alloc (abfd, l + 5);
5886 if (sname == NULL)
0a1b45a2 5887 return false;
95e34ef7
TG
5888 memcpy (sname, name, l);
5889 memcpy (sname + l, "..en", 5);
5890
5891 sym = &syms[n++];
5892 sym->name = sname;
5893 sym->section = sec;
5894 sym->flags = flags;
5895 sym->value = value;
5896 sym->udata.p = NULL;
5897 }
5898
5899 return n;
5900}
5901\f
5902/* Private dump. */
5903
5904static const char *
5905vms_time_to_str (unsigned char *buf)
5906{
5907 time_t t = vms_rawtime_to_time_t (buf);
5908 char *res = ctime (&t);
5909
5910 if (!res)
5911 res = "*invalid time*";
5912 else
5913 res[24] = 0;
5914 return res;
5915}
5916
5917static void
5918evax_bfd_print_emh (FILE *file, unsigned char *rec, unsigned int rec_len)
5919{
5920 struct vms_emh_common *emh = (struct vms_emh_common *)rec;
5921 unsigned int subtype;
8bdf0be1 5922 int extra;
95e34ef7 5923
8bdf0be1 5924 subtype = (unsigned) bfd_getl16 (emh->subtyp);
95e34ef7 5925
695344c0 5926 /* xgettext:c-format */
95e34ef7
TG
5927 fprintf (file, _(" EMH %u (len=%u): "), subtype, rec_len);
5928
bc21b167
NC
5929 /* PR 21618: Check for invalid lengths. */
5930 if (rec_len < sizeof (* emh))
5931 {
5932 fprintf (file, _(" Error: The length is less than the length of an EMH record\n"));
5933 return;
5934 }
8bdf0be1
NC
5935 extra = rec_len - sizeof (struct vms_emh_common);
5936
95e34ef7
TG
5937 switch (subtype)
5938 {
5939 case EMH__C_MHD:
5940 {
07d6d2b8
AM
5941 struct vms_emh_mhd *mhd = (struct vms_emh_mhd *) rec;
5942 const char * name;
8bdf0be1
NC
5943 const char * nextname;
5944 const char * maxname;
95e34ef7 5945
8bdf0be1
NC
5946 /* PR 21840: Check for invalid lengths. */
5947 if (rec_len < sizeof (* mhd))
5948 {
5949 fprintf (file, _(" Error: The record length is less than the size of an EMH_MHD record\n"));
5950 return;
5951 }
07d6d2b8
AM
5952 fprintf (file, _("Module header\n"));
5953 fprintf (file, _(" structure level: %u\n"), mhd->strlvl);
5954 fprintf (file, _(" max record size: %u\n"),
5955 (unsigned) bfd_getl32 (mhd->recsiz));
5956 name = (char *)(mhd + 1);
8bdf0be1
NC
5957 maxname = (char *) rec + rec_len;
5958 if (name > maxname - 2)
5959 {
5960 fprintf (file, _(" Error: The module name is missing\n"));
5961 return;
5962 }
5963 nextname = name + name[0] + 1;
5964 if (nextname >= maxname)
5965 {
5966 fprintf (file, _(" Error: The module name is too long\n"));
5967 return;
5968 }
07d6d2b8
AM
5969 fprintf (file, _(" module name : %.*s\n"), name[0], name + 1);
5970 name = nextname;
8bdf0be1
NC
5971 if (name > maxname - 2)
5972 {
5973 fprintf (file, _(" Error: The module version is missing\n"));
5974 return;
5975 }
5976 nextname = name + name[0] + 1;
5977 if (nextname >= maxname)
5978 {
5979 fprintf (file, _(" Error: The module version is too long\n"));
5980 return;
5981 }
07d6d2b8
AM
5982 fprintf (file, _(" module version : %.*s\n"), name[0], name + 1);
5983 name = nextname;
8bdf0be1
NC
5984 if ((maxname - name) < 17 && maxname[-1] != 0)
5985 fprintf (file, _(" Error: The compile date is truncated\n"));
5986 else
5987 fprintf (file, _(" compile date : %.17s\n"), name);
95e34ef7
TG
5988 }
5989 break;
8bdf0be1 5990
95e34ef7 5991 case EMH__C_LNM:
8bdf0be1
NC
5992 fprintf (file, _("Language Processor Name\n"));
5993 fprintf (file, _(" language name: %.*s\n"), extra, (char *)(emh + 1));
95e34ef7 5994 break;
8bdf0be1 5995
95e34ef7 5996 case EMH__C_SRC:
8bdf0be1
NC
5997 fprintf (file, _("Source Files Header\n"));
5998 fprintf (file, _(" file: %.*s\n"), extra, (char *)(emh + 1));
95e34ef7 5999 break;
8bdf0be1 6000
95e34ef7 6001 case EMH__C_TTL:
8bdf0be1
NC
6002 fprintf (file, _("Title Text Header\n"));
6003 fprintf (file, _(" title: %.*s\n"), extra, (char *)(emh + 1));
95e34ef7 6004 break;
8bdf0be1 6005
95e34ef7 6006 case EMH__C_CPR:
8bdf0be1
NC
6007 fprintf (file, _("Copyright Header\n"));
6008 fprintf (file, _(" copyright: %.*s\n"), extra, (char *)(emh + 1));
95e34ef7 6009 break;
8bdf0be1 6010
95e34ef7
TG
6011 default:
6012 fprintf (file, _("unhandled emh subtype %u\n"), subtype);
6013 break;
6014 }
6015}
6016
6017static void
6018evax_bfd_print_eeom (FILE *file, unsigned char *rec, unsigned int rec_len)
6019{
6020 struct vms_eeom *eeom = (struct vms_eeom *)rec;
6021
6022 fprintf (file, _(" EEOM (len=%u):\n"), rec_len);
bc21b167
NC
6023
6024 /* PR 21618: Check for invalid lengths. */
6025 if (rec_len < sizeof (* eeom))
6026 {
6027 fprintf (file, _(" Error: The length is less than the length of an EEOM record\n"));
6028 return;
6029 }
07d6d2b8 6030
95e34ef7 6031 fprintf (file, _(" number of cond linkage pairs: %u\n"),
07d6d2b8 6032 (unsigned)bfd_getl32 (eeom->total_lps));
95e34ef7 6033 fprintf (file, _(" completion code: %u\n"),
07d6d2b8 6034 (unsigned)bfd_getl16 (eeom->comcod));
95e34ef7
TG
6035 if (rec_len > 10)
6036 {
6037 fprintf (file, _(" transfer addr flags: 0x%02x\n"), eeom->tfrflg);
6038 fprintf (file, _(" transfer addr psect: %u\n"),
07d6d2b8 6039 (unsigned)bfd_getl32 (eeom->psindx));
95e34ef7 6040 fprintf (file, _(" transfer address : 0x%08x\n"),
07d6d2b8 6041 (unsigned)bfd_getl32 (eeom->tfradr));
95e34ef7
TG
6042 }
6043}
6044
6045static void
6046exav_bfd_print_egsy_flags (unsigned int flags, FILE *file)
6047{
6048 if (flags & EGSY__V_WEAK)
6049 fputs (_(" WEAK"), file);
6050 if (flags & EGSY__V_DEF)
6051 fputs (_(" DEF"), file);
6052 if (flags & EGSY__V_UNI)
6053 fputs (_(" UNI"), file);
6054 if (flags & EGSY__V_REL)
6055 fputs (_(" REL"), file);
6056 if (flags & EGSY__V_COMM)
6057 fputs (_(" COMM"), file);
6058 if (flags & EGSY__V_VECEP)
6059 fputs (_(" VECEP"), file);
6060 if (flags & EGSY__V_NORM)
6061 fputs (_(" NORM"), file);
6062 if (flags & EGSY__V_QUAD_VAL)
6063 fputs (_(" QVAL"), file);
6064}
6065
9a1b4480
TG
6066static void
6067evax_bfd_print_egsd_flags (FILE *file, unsigned int flags)
6068{
6069 if (flags & EGPS__V_PIC)
6070 fputs (_(" PIC"), file);
6071 if (flags & EGPS__V_LIB)
6072 fputs (_(" LIB"), file);
6073 if (flags & EGPS__V_OVR)
6074 fputs (_(" OVR"), file);
6075 if (flags & EGPS__V_REL)
6076 fputs (_(" REL"), file);
6077 if (flags & EGPS__V_GBL)
6078 fputs (_(" GBL"), file);
6079 if (flags & EGPS__V_SHR)
6080 fputs (_(" SHR"), file);
6081 if (flags & EGPS__V_EXE)
6082 fputs (_(" EXE"), file);
6083 if (flags & EGPS__V_RD)
6084 fputs (_(" RD"), file);
6085 if (flags & EGPS__V_WRT)
6086 fputs (_(" WRT"), file);
6087 if (flags & EGPS__V_VEC)
6088 fputs (_(" VEC"), file);
6089 if (flags & EGPS__V_NOMOD)
6090 fputs (_(" NOMOD"), file);
6091 if (flags & EGPS__V_COM)
6092 fputs (_(" COM"), file);
6093 if (flags & EGPS__V_ALLOC_64BIT)
6094 fputs (_(" 64B"), file);
6095}
6096
95e34ef7
TG
6097static void
6098evax_bfd_print_egsd (FILE *file, unsigned char *rec, unsigned int rec_len)
6099{
6100 unsigned int off = sizeof (struct vms_egsd);
94852430 6101 unsigned int n = 0;
95e34ef7
TG
6102
6103 fprintf (file, _(" EGSD (len=%u):\n"), rec_len);
94852430
AM
6104 if (rec_len < sizeof (struct vms_egsd) + sizeof (struct vms_egsd_entry))
6105 return;
95e34ef7 6106
94852430 6107 while (off <= rec_len - sizeof (struct vms_egsd_entry))
95e34ef7
TG
6108 {
6109 struct vms_egsd_entry *e = (struct vms_egsd_entry *)(rec + off);
6110 unsigned int type;
6111 unsigned int len;
94852430 6112 unsigned int rest;
95e34ef7
TG
6113
6114 type = (unsigned)bfd_getl16 (e->gsdtyp);
6115 len = (unsigned)bfd_getl16 (e->gsdsiz);
6116
695344c0 6117 /* xgettext:c-format */
95e34ef7 6118 fprintf (file, _(" EGSD entry %2u (type: %u, len: %u): "),
07d6d2b8 6119 n, type, len);
95e34ef7
TG
6120 n++;
6121
94852430 6122 if (len < sizeof (struct vms_egsd_entry) || len > rec_len - off)
bc21b167 6123 {
94852430 6124 fprintf (file, _(" Erroneous length\n"));
bc21b167
NC
6125 return;
6126 }
6127
95e34ef7 6128 switch (type)
07d6d2b8
AM
6129 {
6130 case EGSD__C_PSC:
94852430
AM
6131 if (len >= offsetof (struct vms_egps, name))
6132 {
6133 struct vms_egps *egps = (struct vms_egps *) e;
6134 unsigned int flags = bfd_getl16 (egps->flags);
6135 unsigned int l;
6136
6137 fprintf (file, _("PSC - Program section definition\n"));
6138 fprintf (file, _(" alignment : 2**%u\n"), egps->align);
6139 fprintf (file, _(" flags : 0x%04x"), flags);
6140 evax_bfd_print_egsd_flags (file, flags);
6141 fputc ('\n', file);
6142 l = bfd_getl32 (egps->alloc);
6143 fprintf (file, _(" alloc (len): %u (0x%08x)\n"), l, l);
6144 rest = len - offsetof (struct vms_egps, name);
6145 fprintf (file, _(" name : %.*s\n"),
6146 egps->namlng > rest ? rest : egps->namlng,
6147 egps->name);
6148 }
07d6d2b8
AM
6149 break;
6150 case EGSD__C_SPSC:
94852430
AM
6151 if (len >= offsetof (struct vms_esgps, name))
6152 {
6153 struct vms_esgps *esgps = (struct vms_esgps *) e;
6154 unsigned int flags = bfd_getl16 (esgps->flags);
6155 unsigned int l;
6156
6157 fprintf (file, _("SPSC - Shared Image Program section def\n"));
6158 fprintf (file, _(" alignment : 2**%u\n"), esgps->align);
6159 fprintf (file, _(" flags : 0x%04x"), flags);
6160 evax_bfd_print_egsd_flags (file, flags);
6161 fputc ('\n', file);
6162 l = bfd_getl32 (esgps->alloc);
6163 fprintf (file, _(" alloc (len) : %u (0x%08x)\n"), l, l);
6164 fprintf (file, _(" image offset : 0x%08x\n"),
6165 (unsigned int) bfd_getl32 (esgps->base));
6166 fprintf (file, _(" symvec offset : 0x%08x\n"),
6167 (unsigned int) bfd_getl32 (esgps->value));
6168 rest = len - offsetof (struct vms_esgps, name);
6169 fprintf (file, _(" name : %.*s\n"),
6170 esgps->namlng > rest ? rest : esgps->namlng,
6171 esgps->name);
6172 }
07d6d2b8
AM
6173 break;
6174 case EGSD__C_SYM:
94852430
AM
6175 if (len >= sizeof (struct vms_egsy))
6176 {
6177 struct vms_egsy *egsy = (struct vms_egsy *) e;
6178 unsigned int flags = bfd_getl16 (egsy->flags);
07d6d2b8 6179
94852430
AM
6180 if ((flags & EGSY__V_DEF) != 0
6181 && len >= offsetof (struct vms_esdf, name))
6182 {
6183 struct vms_esdf *esdf = (struct vms_esdf *) e;
6184
6185 fprintf (file, _("SYM - Global symbol definition\n"));
6186 fprintf (file, _(" flags: 0x%04x"), flags);
6187 exav_bfd_print_egsy_flags (flags, file);
6188 fputc ('\n', file);
6189 fprintf (file, _(" psect offset: 0x%08x\n"),
6190 (unsigned) bfd_getl32 (esdf->value));
6191 if (flags & EGSY__V_NORM)
6192 {
6193 fprintf (file, _(" code address: 0x%08x\n"),
6194 (unsigned) bfd_getl32 (esdf->code_address));
6195 fprintf (file, _(" psect index for entry point : %u\n"),
6196 (unsigned) bfd_getl32 (esdf->ca_psindx));
6197 }
6198 fprintf (file, _(" psect index : %u\n"),
6199 (unsigned) bfd_getl32 (esdf->psindx));
6200 rest = len - offsetof (struct vms_esdf, name);
6201 fprintf (file, _(" name : %.*s\n"),
6202 esdf->namlng > rest ? rest : esdf->namlng,
6203 esdf->name);
6204 }
6205 else if (len >= offsetof (struct vms_esrf, name))
6206 {
6207 struct vms_esrf *esrf = (struct vms_esrf *)e;
07d6d2b8 6208
94852430
AM
6209 fprintf (file, _("SYM - Global symbol reference\n"));
6210 rest = len - offsetof (struct vms_esrf, name);
6211 fprintf (file, _(" name : %.*s\n"),
6212 esrf->namlng > rest ? rest : esrf->namlng,
6213 esrf->name);
6214 }
6215 }
07d6d2b8
AM
6216 break;
6217 case EGSD__C_IDC:
94852430
AM
6218 if (len >= sizeof (struct vms_eidc))
6219 {
6220 struct vms_eidc *eidc = (struct vms_eidc *) e;
6221 unsigned int flags = bfd_getl32 (eidc->flags);
6222 unsigned char *p;
6223
6224 fprintf (file, _("IDC - Ident Consistency check\n"));
6225 fprintf (file, _(" flags : 0x%08x"), flags);
6226 if (flags & EIDC__V_BINIDENT)
6227 fputs (" BINDENT", file);
6228 fputc ('\n', file);
6229 fprintf (file, _(" id match : %x\n"),
6230 (flags >> EIDC__V_IDMATCH_SH) & EIDC__V_IDMATCH_MASK);
6231 fprintf (file, _(" error severity: %x\n"),
6232 (flags >> EIDC__V_ERRSEV_SH) & EIDC__V_ERRSEV_MASK);
6233 p = eidc->name;
6234 rest = len - (p - (unsigned char *) e);
6235 fprintf (file, _(" entity name : %.*s\n"),
6236 p[0] > rest - 1 ? rest - 1 : p[0], p + 1);
6237 if (rest > 1u + p[0])
6238 {
6239 rest -= 1 + p[0];
6240 p += 1 + p[0];
6241 fprintf (file, _(" object name : %.*s\n"),
6242 p[0] > rest - 1 ? rest - 1 : p[0], p + 1);
6243 if (rest > 1u + p[0])
6244 {
6245 rest -= 1 + p[0];
6246 p += 1 + p[0];
6247 if (flags & EIDC__V_BINIDENT)
6248 {
6249 if (rest >= 4)
6250 fprintf (file, _(" binary ident : 0x%08x\n"),
6251 (unsigned) bfd_getl32 (p));
6252 }
6253 else
6254 fprintf (file, _(" ascii ident : %.*s\n"),
6255 p[0] > rest - 1 ? rest - 1 : p[0], p + 1);
6256 }
6257 }
6258 }
07d6d2b8
AM
6259 break;
6260 case EGSD__C_SYMG:
94852430
AM
6261 if (len >= offsetof (struct vms_egst, name))
6262 {
6263 struct vms_egst *egst = (struct vms_egst *) e;
6264 unsigned int flags = bfd_getl16 (egst->header.flags);
6265
6266 fprintf (file, _("SYMG - Universal symbol definition\n"));
6267 fprintf (file, _(" flags: 0x%04x"), flags);
6268 exav_bfd_print_egsy_flags (flags, file);
6269 fputc ('\n', file);
6270 fprintf (file, _(" symbol vector offset: 0x%08x\n"),
6271 (unsigned) bfd_getl32 (egst->value));
6272 fprintf (file, _(" entry point: 0x%08x\n"),
6273 (unsigned) bfd_getl32 (egst->lp_1));
6274 fprintf (file, _(" proc descr : 0x%08x\n"),
6275 (unsigned) bfd_getl32 (egst->lp_2));
6276 fprintf (file, _(" psect index: %u\n"),
6277 (unsigned) bfd_getl32 (egst->psindx));
6278 rest = len - offsetof (struct vms_egst, name);
6279 fprintf (file, _(" name : %.*s\n"),
6280 egst->namlng > rest ? rest : egst->namlng,
6281 egst->name);
6282 }
07d6d2b8
AM
6283 break;
6284 case EGSD__C_SYMV:
94852430
AM
6285 if (len >= offsetof (struct vms_esdfv, name))
6286 {
6287 struct vms_esdfv *esdfv = (struct vms_esdfv *) e;
6288 unsigned int flags = bfd_getl16 (esdfv->flags);
6289
6290 fprintf (file, _("SYMV - Vectored symbol definition\n"));
6291 fprintf (file, _(" flags: 0x%04x"), flags);
6292 exav_bfd_print_egsy_flags (flags, file);
6293 fputc ('\n', file);
6294 fprintf (file, _(" vector : 0x%08x\n"),
6295 (unsigned) bfd_getl32 (esdfv->vector));
6296 fprintf (file, _(" psect offset: %u\n"),
6297 (unsigned) bfd_getl32 (esdfv->value));
6298 fprintf (file, _(" psect index : %u\n"),
6299 (unsigned) bfd_getl32 (esdfv->psindx));
6300 rest = len - offsetof (struct vms_esdfv, name);
6301 fprintf (file, _(" name : %.*s\n"),
6302 esdfv->namlng > rest ? rest : esdfv->namlng,
6303 esdfv->name);
6304 }
07d6d2b8
AM
6305 break;
6306 case EGSD__C_SYMM:
94852430
AM
6307 if (len >= offsetof (struct vms_esdfm, name))
6308 {
6309 struct vms_esdfm *esdfm = (struct vms_esdfm *) e;
6310 unsigned int flags = bfd_getl16 (esdfm->flags);
6311
6312 fprintf (file,
6313 _("SYMM - Global symbol definition with version\n"));
6314 fprintf (file, _(" flags: 0x%04x"), flags);
6315 exav_bfd_print_egsy_flags (flags, file);
6316 fputc ('\n', file);
6317 fprintf (file, _(" version mask: 0x%08x\n"),
6318 (unsigned)bfd_getl32 (esdfm->version_mask));
6319 fprintf (file, _(" psect offset: %u\n"),
6320 (unsigned)bfd_getl32 (esdfm->value));
6321 fprintf (file, _(" psect index : %u\n"),
6322 (unsigned)bfd_getl32 (esdfm->psindx));
6323 rest = len - offsetof (struct vms_esdfm, name);
6324 fprintf (file, _(" name : %.*s\n"),
6325 esdfm->namlng > rest ? rest : esdfm->namlng,
6326 esdfm->name);
6327 }
07d6d2b8
AM
6328 break;
6329 default:
6330 fprintf (file, _("unhandled egsd entry type %u\n"), type);
6331 break;
6332 }
95e34ef7
TG
6333 off += len;
6334 }
6335}
6336
6337static void
6338evax_bfd_print_hex (FILE *file, const char *pfx,
07d6d2b8 6339 const unsigned char *buf, unsigned int len)
95e34ef7
TG
6340{
6341 unsigned int i;
6342 unsigned int n;
6343
6344 n = 0;
6345 for (i = 0; i < len; i++)
6346 {
6347 if (n == 0)
07d6d2b8 6348 fputs (pfx, file);
95e34ef7
TG
6349 fprintf (file, " %02x", buf[i]);
6350 n++;
6351 if (n == 16)
07d6d2b8
AM
6352 {
6353 n = 0;
6354 fputc ('\n', file);
6355 }
95e34ef7
TG
6356 }
6357 if (n != 0)
6358 fputc ('\n', file);
6359}
6360
6361static void
94852430
AM
6362evax_bfd_print_etir_stc_ir (FILE *file, const unsigned char *buf,
6363 unsigned int len, int is_ps)
95e34ef7 6364{
94852430
AM
6365 if (is_ps ? len < 44 : len < 33)
6366 return;
6367
695344c0 6368 /* xgettext:c-format */
95e34ef7 6369 fprintf (file, _(" linkage index: %u, replacement insn: 0x%08x\n"),
07d6d2b8
AM
6370 (unsigned)bfd_getl32 (buf),
6371 (unsigned)bfd_getl32 (buf + 16));
695344c0 6372 /* xgettext:c-format */
95e34ef7 6373 fprintf (file, _(" psect idx 1: %u, offset 1: 0x%08x %08x\n"),
07d6d2b8
AM
6374 (unsigned)bfd_getl32 (buf + 4),
6375 (unsigned)bfd_getl32 (buf + 12),
6376 (unsigned)bfd_getl32 (buf + 8));
695344c0 6377 /* xgettext:c-format */
95e34ef7 6378 fprintf (file, _(" psect idx 2: %u, offset 2: 0x%08x %08x\n"),
07d6d2b8
AM
6379 (unsigned)bfd_getl32 (buf + 20),
6380 (unsigned)bfd_getl32 (buf + 28),
6381 (unsigned)bfd_getl32 (buf + 24));
95e34ef7 6382 if (is_ps)
695344c0 6383 /* xgettext:c-format */
95e34ef7 6384 fprintf (file, _(" psect idx 3: %u, offset 3: 0x%08x %08x\n"),
07d6d2b8
AM
6385 (unsigned)bfd_getl32 (buf + 32),
6386 (unsigned)bfd_getl32 (buf + 40),
6387 (unsigned)bfd_getl32 (buf + 36));
95e34ef7 6388 else
94852430
AM
6389 fprintf (file, _(" global name: %.*s\n"),
6390 buf[32] > len - 33 ? len - 33 : buf[32],
6391 buf + 33);
95e34ef7
TG
6392}
6393
6394static void
6395evax_bfd_print_etir (FILE *file, const char *name,
07d6d2b8 6396 unsigned char *rec, unsigned int rec_len)
95e34ef7 6397{
94852430 6398 unsigned int off = sizeof (struct vms_eobjrec);
95e34ef7 6399
695344c0 6400 /* xgettext:c-format */
94852430
AM
6401 fprintf (file, _(" %s (len=%u):\n"), name, (unsigned) rec_len);
6402 if (rec_len < sizeof (struct vms_eobjrec) + sizeof (struct vms_etir))
6403 return;
95e34ef7 6404
94852430 6405 while (off <= rec_len - sizeof (struct vms_etir))
95e34ef7
TG
6406 {
6407 struct vms_etir *etir = (struct vms_etir *)(rec + off);
6408 unsigned char *buf;
6409 unsigned int type;
6410 unsigned int size;
94852430 6411 unsigned int rest;
95e34ef7
TG
6412
6413 type = bfd_getl16 (etir->rectyp);
6414 size = bfd_getl16 (etir->size);
6415 buf = rec + off + sizeof (struct vms_etir);
6416
94852430 6417 if (size < sizeof (struct vms_etir) || size > rec_len - off)
bc21b167 6418 {
94852430 6419 fprintf (file, _(" Erroneous length\n"));
bc21b167
NC
6420 return;
6421 }
6422
695344c0 6423 /* xgettext:c-format */
94852430
AM
6424 fprintf (file, _(" (type: %3u, size: %3u): "), type, size);
6425 rest = size - sizeof (struct vms_etir);
95e34ef7 6426 switch (type)
07d6d2b8
AM
6427 {
6428 case ETIR__C_STA_GBL:
94852430
AM
6429 if (rest >= 1)
6430 fprintf (file, _("STA_GBL (stack global) %.*s\n"),
6431 buf[0] > rest - 1 ? rest - 1 : buf[0], buf + 1);
07d6d2b8
AM
6432 break;
6433 case ETIR__C_STA_LW:
94852430
AM
6434 fprintf (file, _("STA_LW (stack longword)"));
6435 if (rest >= 4)
6436 fprintf (file, " 0x%08x\n",
6437 (unsigned) bfd_getl32 (buf));
07d6d2b8
AM
6438 break;
6439 case ETIR__C_STA_QW:
94852430
AM
6440 fprintf (file, _("STA_QW (stack quadword)"));
6441 if (rest >= 8)
6442 fprintf (file, " 0x%08x %08x\n",
6443 (unsigned) bfd_getl32 (buf + 4),
6444 (unsigned) bfd_getl32 (buf + 0));
07d6d2b8
AM
6445 break;
6446 case ETIR__C_STA_PQ:
6447 fprintf (file, _("STA_PQ (stack psect base + offset)\n"));
94852430
AM
6448 if (rest >= 12)
6449 /* xgettext:c-format */
6450 fprintf (file, _(" psect: %u, offset: 0x%08x %08x\n"),
6451 (unsigned) bfd_getl32 (buf + 0),
6452 (unsigned) bfd_getl32 (buf + 8),
6453 (unsigned) bfd_getl32 (buf + 4));
07d6d2b8
AM
6454 break;
6455 case ETIR__C_STA_LI:
6456 fprintf (file, _("STA_LI (stack literal)\n"));
6457 break;
6458 case ETIR__C_STA_MOD:
6459 fprintf (file, _("STA_MOD (stack module)\n"));
6460 break;
6461 case ETIR__C_STA_CKARG:
6462 fprintf (file, _("STA_CKARG (compare procedure argument)\n"));
6463 break;
6464
6465 case ETIR__C_STO_B:
6466 fprintf (file, _("STO_B (store byte)\n"));
6467 break;
6468 case ETIR__C_STO_W:
6469 fprintf (file, _("STO_W (store word)\n"));
6470 break;
6471 case ETIR__C_STO_LW:
6472 fprintf (file, _("STO_LW (store longword)\n"));
6473 break;
6474 case ETIR__C_STO_QW:
6475 fprintf (file, _("STO_QW (store quadword)\n"));
6476 break;
6477 case ETIR__C_STO_IMMR:
94852430
AM
6478 if (rest >= 4)
6479 {
6480 unsigned int rpt = bfd_getl32 (buf);
6481 fprintf (file,
6482 _("STO_IMMR (store immediate repeat) %u bytes\n"),
6483 rpt);
6484 if (rpt > rest - 4)
6485 rpt = rest - 4;
6486 evax_bfd_print_hex (file, " ", buf + 4, rpt);
6487 }
07d6d2b8
AM
6488 break;
6489 case ETIR__C_STO_GBL:
94852430
AM
6490 if (rest >= 1)
6491 fprintf (file, _("STO_GBL (store global) %.*s\n"),
6492 buf[0] > rest - 1 ? rest - 1 : buf[0], buf + 1);
07d6d2b8
AM
6493 break;
6494 case ETIR__C_STO_CA:
94852430
AM
6495 if (rest >= 1)
6496 fprintf (file, _("STO_CA (store code address) %.*s\n"),
6497 buf[0] > rest - 1 ? rest - 1 : buf[0], buf + 1);
07d6d2b8
AM
6498 break;
6499 case ETIR__C_STO_RB:
6500 fprintf (file, _("STO_RB (store relative branch)\n"));
6501 break;
6502 case ETIR__C_STO_AB:
6503 fprintf (file, _("STO_AB (store absolute branch)\n"));
6504 break;
6505 case ETIR__C_STO_OFF:
6506 fprintf (file, _("STO_OFF (store offset to psect)\n"));
6507 break;
6508 case ETIR__C_STO_IMM:
94852430
AM
6509 if (rest >= 4)
6510 {
6511 unsigned int rpt = bfd_getl32 (buf);
6512 fprintf (file,
6513 _("STO_IMM (store immediate) %u bytes\n"),
6514 rpt);
6515 if (rpt > rest - 4)
6516 rpt = rest - 4;
6517 evax_bfd_print_hex (file, " ", buf + 4, rpt);
6518 }
07d6d2b8
AM
6519 break;
6520 case ETIR__C_STO_GBL_LW:
94852430
AM
6521 if (rest >= 1)
6522 fprintf (file, _("STO_GBL_LW (store global longword) %.*s\n"),
6523 buf[0] > rest - 1 ? rest - 1 : buf[0], buf + 1);
07d6d2b8
AM
6524 break;
6525 case ETIR__C_STO_LP_PSB:
6526 fprintf (file, _("STO_OFF (store LP with procedure signature)\n"));
6527 break;
6528 case ETIR__C_STO_HINT_GBL:
6529 fprintf (file, _("STO_BR_GBL (store branch global) *todo*\n"));
6530 break;
6531 case ETIR__C_STO_HINT_PS:
6532 fprintf (file, _("STO_BR_PS (store branch psect + offset) *todo*\n"));
6533 break;
6534
6535 case ETIR__C_OPR_NOP:
6536 fprintf (file, _("OPR_NOP (no-operation)\n"));
6537 break;
6538 case ETIR__C_OPR_ADD:
6539 fprintf (file, _("OPR_ADD (add)\n"));
6540 break;
6541 case ETIR__C_OPR_SUB:
6542 fprintf (file, _("OPR_SUB (subtract)\n"));
6543 break;
6544 case ETIR__C_OPR_MUL:
6545 fprintf (file, _("OPR_MUL (multiply)\n"));
6546 break;
6547 case ETIR__C_OPR_DIV:
6548 fprintf (file, _("OPR_DIV (divide)\n"));
6549 break;
6550 case ETIR__C_OPR_AND:
6551 fprintf (file, _("OPR_AND (logical and)\n"));
6552 break;
6553 case ETIR__C_OPR_IOR:
6554 fprintf (file, _("OPR_IOR (logical inclusive or)\n"));
6555 break;
6556 case ETIR__C_OPR_EOR:
6557 fprintf (file, _("OPR_EOR (logical exclusive or)\n"));
6558 break;
6559 case ETIR__C_OPR_NEG:
6560 fprintf (file, _("OPR_NEG (negate)\n"));
6561 break;
6562 case ETIR__C_OPR_COM:
6563 fprintf (file, _("OPR_COM (complement)\n"));
6564 break;
6565 case ETIR__C_OPR_INSV:
6566 fprintf (file, _("OPR_INSV (insert field)\n"));
6567 break;
6568 case ETIR__C_OPR_ASH:
6569 fprintf (file, _("OPR_ASH (arithmetic shift)\n"));
6570 break;
6571 case ETIR__C_OPR_USH:
6572 fprintf (file, _("OPR_USH (unsigned shift)\n"));
6573 break;
6574 case ETIR__C_OPR_ROT:
6575 fprintf (file, _("OPR_ROT (rotate)\n"));
6576 break;
6577 case ETIR__C_OPR_SEL:
6578 fprintf (file, _("OPR_SEL (select)\n"));
6579 break;
6580 case ETIR__C_OPR_REDEF:
6581 fprintf (file, _("OPR_REDEF (redefine symbol to curr location)\n"));
6582 break;
6583 case ETIR__C_OPR_DFLIT:
6584 fprintf (file, _("OPR_REDEF (define a literal)\n"));
6585 break;
6586
6587 case ETIR__C_STC_LP:
6588 fprintf (file, _("STC_LP (store cond linkage pair)\n"));
6589 break;
6590 case ETIR__C_STC_LP_PSB:
6591 fprintf (file,
6592 _("STC_LP_PSB (store cond linkage pair + signature)\n"));
94852430
AM
6593 if (rest >= 5)
6594 {
6595 /* xgettext:c-format */
6596 fprintf (file, _(" linkage index: %u, procedure: %.*s\n"),
6597 (unsigned) bfd_getl32 (buf),
6598 buf[4] > rest - 5 ? rest - 5 : buf[4], buf + 5);
6599 if (rest > 4 + 1u + buf[4])
6600 {
6601 rest -= 4 + 1 + buf[4];
6602 buf += 4 + 1 + buf[4];
6603 fprintf (file, _(" signature: %.*s\n"),
6604 buf[0] > rest - 1 ? rest - 1: buf[0], buf + 1);
6605 }
6606 }
07d6d2b8
AM
6607 break;
6608 case ETIR__C_STC_GBL:
6609 fprintf (file, _("STC_GBL (store cond global)\n"));
94852430
AM
6610 if (rest >= 5)
6611 /* xgettext:c-format */
6612 fprintf (file, _(" linkage index: %u, global: %.*s\n"),
6613 (unsigned) bfd_getl32 (buf),
6614 buf[4] > rest - 5 ? rest - 5 : buf[4], buf + 5);
07d6d2b8
AM
6615 break;
6616 case ETIR__C_STC_GCA:
6617 fprintf (file, _("STC_GCA (store cond code address)\n"));
94852430
AM
6618 if (rest >= 5)
6619 /* xgettext:c-format */
6620 fprintf (file, _(" linkage index: %u, procedure name: %.*s\n"),
6621 (unsigned) bfd_getl32 (buf),
6622 buf[4] > rest - 5 ? rest - 5 : buf[4], buf + 5);
07d6d2b8
AM
6623 break;
6624 case ETIR__C_STC_PS:
6625 fprintf (file, _("STC_PS (store cond psect + offset)\n"));
94852430
AM
6626 if (rest >= 16)
6627 fprintf (file,
6628 /* xgettext:c-format */
6629 _(" linkage index: %u, psect: %u, offset: 0x%08x %08x\n"),
6630 (unsigned)bfd_getl32 (buf),
6631 (unsigned)bfd_getl32 (buf + 4),
6632 (unsigned)bfd_getl32 (buf + 12),
6633 (unsigned)bfd_getl32 (buf + 8));
07d6d2b8
AM
6634 break;
6635 case ETIR__C_STC_NOP_GBL:
6636 fprintf (file, _("STC_NOP_GBL (store cond NOP at global addr)\n"));
94852430 6637 evax_bfd_print_etir_stc_ir (file, buf, rest, 0);
07d6d2b8
AM
6638 break;
6639 case ETIR__C_STC_NOP_PS:
6640 fprintf (file, _("STC_NOP_PS (store cond NOP at psect + offset)\n"));
94852430 6641 evax_bfd_print_etir_stc_ir (file, buf, rest, 1);
07d6d2b8
AM
6642 break;
6643 case ETIR__C_STC_BSR_GBL:
6644 fprintf (file, _("STC_BSR_GBL (store cond BSR at global addr)\n"));
94852430 6645 evax_bfd_print_etir_stc_ir (file, buf, rest, 0);
07d6d2b8
AM
6646 break;
6647 case ETIR__C_STC_BSR_PS:
6648 fprintf (file, _("STC_BSR_PS (store cond BSR at psect + offset)\n"));
94852430 6649 evax_bfd_print_etir_stc_ir (file, buf, rest, 1);
07d6d2b8
AM
6650 break;
6651 case ETIR__C_STC_LDA_GBL:
6652 fprintf (file, _("STC_LDA_GBL (store cond LDA at global addr)\n"));
94852430 6653 evax_bfd_print_etir_stc_ir (file, buf, rest, 0);
07d6d2b8
AM
6654 break;
6655 case ETIR__C_STC_LDA_PS:
6656 fprintf (file, _("STC_LDA_PS (store cond LDA at psect + offset)\n"));
94852430 6657 evax_bfd_print_etir_stc_ir (file, buf, rest, 1);
07d6d2b8
AM
6658 break;
6659 case ETIR__C_STC_BOH_GBL:
6660 fprintf (file, _("STC_BOH_GBL (store cond BOH at global addr)\n"));
94852430 6661 evax_bfd_print_etir_stc_ir (file, buf, rest, 0);
07d6d2b8
AM
6662 break;
6663 case ETIR__C_STC_BOH_PS:
6664 fprintf (file, _("STC_BOH_PS (store cond BOH at psect + offset)\n"));
94852430 6665 evax_bfd_print_etir_stc_ir (file, buf, rest, 1);
07d6d2b8
AM
6666 break;
6667 case ETIR__C_STC_NBH_GBL:
6668 fprintf (file,
6669 _("STC_NBH_GBL (store cond or hint at global addr)\n"));
6670 break;
6671 case ETIR__C_STC_NBH_PS:
6672 fprintf (file,
6673 _("STC_NBH_PS (store cond or hint at psect + offset)\n"));
6674 break;
6675
6676 case ETIR__C_CTL_SETRB:
6677 fprintf (file, _("CTL_SETRB (set relocation base)\n"));
07d6d2b8
AM
6678 break;
6679 case ETIR__C_CTL_AUGRB:
94852430
AM
6680 if (rest >= 4)
6681 {
6682 unsigned int val = bfd_getl32 (buf);
6683 fprintf (file, _("CTL_AUGRB (augment relocation base) %u\n"),
6684 val);
6685 }
07d6d2b8
AM
6686 break;
6687 case ETIR__C_CTL_DFLOC:
6688 fprintf (file, _("CTL_DFLOC (define location)\n"));
6689 break;
6690 case ETIR__C_CTL_STLOC:
6691 fprintf (file, _("CTL_STLOC (set location)\n"));
6692 break;
6693 case ETIR__C_CTL_STKDL:
6694 fprintf (file, _("CTL_STKDL (stack defined location)\n"));
6695 break;
6696 default:
6697 fprintf (file, _("*unhandled*\n"));
6698 break;
6699 }
95e34ef7
TG
6700 off += size;
6701 }
6702}
6703
6704static void
6705evax_bfd_print_eobj (struct bfd *abfd, FILE *file)
6706{
0a1b45a2
AM
6707 bool is_first = true;
6708 bool has_records = false;
95e34ef7
TG
6709
6710 while (1)
6711 {
6712 unsigned int rec_len;
6713 unsigned int pad_len;
6714 unsigned char *rec;
6715 unsigned int hdr_size;
6716 unsigned int type;
6717
6718 if (is_first)
07d6d2b8
AM
6719 {
6720 unsigned char buf[6];
6721
0a1b45a2 6722 is_first = false;
07d6d2b8
AM
6723
6724 /* Read 6 bytes. */
6725 if (bfd_bread (buf, sizeof (buf), abfd) != sizeof (buf))
6726 {
6727 fprintf (file, _("cannot read GST record length\n"));
6728 return;
6729 }
6730 rec_len = bfd_getl16 (buf + 0);
6731 if (rec_len == bfd_getl16 (buf + 4)
6732 && bfd_getl16 (buf + 2) == EOBJ__C_EMH)
6733 {
6734 /* The format is raw: record-size, type, record-size. */
0a1b45a2 6735 has_records = true;
07d6d2b8
AM
6736 pad_len = (rec_len + 1) & ~1U;
6737 hdr_size = 4;
6738 }
6739 else if (rec_len == EOBJ__C_EMH)
6740 {
0a1b45a2 6741 has_records = false;
07d6d2b8
AM
6742 pad_len = bfd_getl16 (buf + 2);
6743 hdr_size = 6;
6744 }
6745 else
6746 {
6747 /* Ill-formed. */
6748 fprintf (file, _("cannot find EMH in first GST record\n"));
6749 return;
6750 }
6751 rec = bfd_malloc (pad_len);
6752 memcpy (rec, buf + sizeof (buf) - hdr_size, hdr_size);
6753 }
6754 else
6755 {
6756 unsigned int rec_len2 = 0;
6757 unsigned char hdr[4];
6758
6759 if (has_records)
6760 {
6761 unsigned char buf_len[2];
6762
6763 if (bfd_bread (buf_len, sizeof (buf_len), abfd)
6764 != sizeof (buf_len))
6765 {
6766 fprintf (file, _("cannot read GST record length\n"));
6767 return;
6768 }
6769 rec_len2 = (unsigned)bfd_getl16 (buf_len);
6770 }
6771
6772 if (bfd_bread (hdr, sizeof (hdr), abfd) != sizeof (hdr))
6773 {
6774 fprintf (file, _("cannot read GST record header\n"));
6775 return;
6776 }
6777 rec_len = (unsigned)bfd_getl16 (hdr + 2);
6778 if (has_records)
6779 pad_len = (rec_len + 1) & ~1U;
6780 else
6781 pad_len = rec_len;
6782 rec = bfd_malloc (pad_len);
6783 memcpy (rec, hdr, sizeof (hdr));
6784 hdr_size = sizeof (hdr);
6785 if (has_records && rec_len2 != rec_len)
6786 {
6787 fprintf (file, _(" corrupted GST\n"));
6788 break;
6789 }
6790 }
95e34ef7
TG
6791
6792 if (bfd_bread (rec + hdr_size, pad_len - hdr_size, abfd)
07d6d2b8
AM
6793 != pad_len - hdr_size)
6794 {
6795 fprintf (file, _("cannot read GST record\n"));
6796 return;
6797 }
95e34ef7
TG
6798
6799 type = (unsigned)bfd_getl16 (rec);
6800
6801 switch (type)
07d6d2b8
AM
6802 {
6803 case EOBJ__C_EMH:
6804 evax_bfd_print_emh (file, rec, rec_len);
6805 break;
6806 case EOBJ__C_EGSD:
6807 evax_bfd_print_egsd (file, rec, rec_len);
6808 break;
6809 case EOBJ__C_EEOM:
6810 evax_bfd_print_eeom (file, rec, rec_len);
6811 free (rec);
6812 return;
6813 break;
6814 case EOBJ__C_ETIR:
6815 evax_bfd_print_etir (file, "ETIR", rec, rec_len);
6816 break;
6817 case EOBJ__C_EDBG:
6818 evax_bfd_print_etir (file, "EDBG", rec, rec_len);
6819 break;
6820 case EOBJ__C_ETBT:
6821 evax_bfd_print_etir (file, "ETBT", rec, rec_len);
6822 break;
6823 default:
6824 fprintf (file, _(" unhandled EOBJ record type %u\n"), type);
6825 break;
6826 }
95e34ef7
TG
6827 free (rec);
6828 }
6829}
6830
6831static void
b920bc37
AM
6832evax_bfd_print_relocation_records (FILE *file, const unsigned char *buf,
6833 size_t buf_size, size_t off,
07d6d2b8 6834 unsigned int stride)
95e34ef7 6835{
b920bc37 6836 while (off <= buf_size - 8)
95e34ef7
TG
6837 {
6838 unsigned int base;
6839 unsigned int count;
6840 unsigned int j;
6841
b920bc37 6842 count = bfd_getl32 (buf + off + 0);
95e34ef7
TG
6843
6844 if (count == 0)
07d6d2b8 6845 break;
b920bc37 6846 base = bfd_getl32 (buf + off + 4);
95e34ef7 6847
695344c0 6848 /* xgettext:c-format */
95e34ef7 6849 fprintf (file, _(" bitcount: %u, base addr: 0x%08x\n"),
07d6d2b8 6850 count, base);
95e34ef7 6851
b920bc37
AM
6852 off += 8;
6853 for (j = 0; count > 0 && off <= buf_size - 4; j += 4, count -= 32)
07d6d2b8
AM
6854 {
6855 unsigned int k;
6856 unsigned int n = 0;
6857 unsigned int val;
95e34ef7 6858
b920bc37
AM
6859 val = bfd_getl32 (buf + off);
6860 off += 4;
95e34ef7 6861
695344c0 6862 /* xgettext:c-format */
07d6d2b8
AM
6863 fprintf (file, _(" bitmap: 0x%08x (count: %u):\n"), val, count);
6864
6865 for (k = 0; k < 32; k++)
401e101e 6866 if (val & (1u << k))
07d6d2b8
AM
6867 {
6868 if (n == 0)
6869 fputs (" ", file);
6870 fprintf (file, _(" %08x"), base + (j * 8 + k) * stride);
6871 n++;
6872 if (n == 8)
6873 {
6874 fputs ("\n", file);
6875 n = 0;
6876 }
6877 }
6878 if (n)
6879 fputs ("\n", file);
6880 }
95e34ef7
TG
6881 }
6882}
6883
6884static void
b920bc37
AM
6885evax_bfd_print_address_fixups (FILE *file, const unsigned char *buf,
6886 size_t buf_size, size_t off)
95e34ef7 6887{
b920bc37 6888 while (off <= buf_size - 8)
95e34ef7
TG
6889 {
6890 unsigned int j;
6891 unsigned int count;
6892
b920bc37 6893 count = bfd_getl32 (buf + off + 0);
95e34ef7 6894 if (count == 0)
07d6d2b8 6895 return;
695344c0 6896 /* xgettext:c-format */
95e34ef7 6897 fprintf (file, _(" image %u (%u entries)\n"),
b920bc37
AM
6898 (unsigned) bfd_getl32 (buf + off + 4), count);
6899 off += 8;
6900 for (j = 0; j < count && off <= buf_size - 8; j++)
07d6d2b8 6901 {
695344c0 6902 /* xgettext:c-format */
07d6d2b8 6903 fprintf (file, _(" offset: 0x%08x, val: 0x%08x\n"),
b920bc37
AM
6904 (unsigned) bfd_getl32 (buf + off + 0),
6905 (unsigned) bfd_getl32 (buf + off + 4));
6906 off += 8;
07d6d2b8 6907 }
95e34ef7
TG
6908 }
6909}
6910
6911static void
b920bc37
AM
6912evax_bfd_print_reference_fixups (FILE *file, const unsigned char *buf,
6913 size_t buf_size, size_t off)
95e34ef7
TG
6914{
6915 unsigned int count;
6916
b920bc37 6917 while (off <= buf_size - 8)
95e34ef7
TG
6918 {
6919 unsigned int j;
6920 unsigned int n = 0;
6921
b920bc37 6922 count = bfd_getl32 (buf + off + 0);
95e34ef7 6923 if (count == 0)
07d6d2b8 6924 break;
695344c0 6925 /* xgettext:c-format */
95e34ef7 6926 fprintf (file, _(" image %u (%u entries), offsets:\n"),
b920bc37
AM
6927 (unsigned) bfd_getl32 (buf + off + 4), count);
6928 off += 8;
6929 for (j = 0; j < count && off <= buf_size - 4; j++)
07d6d2b8
AM
6930 {
6931 if (n == 0)
6932 fputs (" ", file);
b920bc37 6933 fprintf (file, _(" 0x%08x"), (unsigned) bfd_getl32 (buf + off));
07d6d2b8
AM
6934 n++;
6935 if (n == 7)
6936 {
6937 fputs ("\n", file);
6938 n = 0;
6939 }
b920bc37 6940 off += 4;
07d6d2b8 6941 }
95e34ef7 6942 if (n)
07d6d2b8 6943 fputs ("\n", file);
95e34ef7
TG
6944 }
6945}
6946
6947static void
6948evax_bfd_print_indent (int indent, FILE *file)
6949{
6950 for (; indent; indent--)
6951 fputc (' ', file);
6952}
6953
6954static const char *
6955evax_bfd_get_dsc_name (unsigned int v)
6956{
6957 switch (v)
6958 {
6959 case DSC__K_DTYPE_Z:
6960 return "Z (Unspecified)";
6961 case DSC__K_DTYPE_V:
6962 return "V (Bit)";
6963 case DSC__K_DTYPE_BU:
6964 return "BU (Byte logical)";
6965 case DSC__K_DTYPE_WU:
6966 return "WU (Word logical)";
6967 case DSC__K_DTYPE_LU:
6968 return "LU (Longword logical)";
6969 case DSC__K_DTYPE_QU:
6970 return "QU (Quadword logical)";
6971 case DSC__K_DTYPE_B:
6972 return "B (Byte integer)";
6973 case DSC__K_DTYPE_W:
6974 return "W (Word integer)";
6975 case DSC__K_DTYPE_L:
6976 return "L (Longword integer)";
6977 case DSC__K_DTYPE_Q:
6978 return "Q (Quadword integer)";
6979 case DSC__K_DTYPE_F:
6980 return "F (Single-precision floating)";
6981 case DSC__K_DTYPE_D:
6982 return "D (Double-precision floating)";
6983 case DSC__K_DTYPE_FC:
6984 return "FC (Complex)";
6985 case DSC__K_DTYPE_DC:
6986 return "DC (Double-precision Complex)";
6987 case DSC__K_DTYPE_T:
6988 return "T (ASCII text string)";
6989 case DSC__K_DTYPE_NU:
6990 return "NU (Numeric string, unsigned)";
6991 case DSC__K_DTYPE_NL:
6992 return "NL (Numeric string, left separate sign)";
6993 case DSC__K_DTYPE_NLO:
6994 return "NLO (Numeric string, left overpunched sign)";
6995 case DSC__K_DTYPE_NR:
6996 return "NR (Numeric string, right separate sign)";
6997 case DSC__K_DTYPE_NRO:
6998 return "NRO (Numeric string, right overpunched sig)";
6999 case DSC__K_DTYPE_NZ:
7000 return "NZ (Numeric string, zoned sign)";
7001 case DSC__K_DTYPE_P:
7002 return "P (Packed decimal string)";
7003 case DSC__K_DTYPE_ZI:
7004 return "ZI (Sequence of instructions)";
7005 case DSC__K_DTYPE_ZEM:
7006 return "ZEM (Procedure entry mask)";
7007 case DSC__K_DTYPE_DSC:
7008 return "DSC (Descriptor, used for arrays of dyn strings)";
7009 case DSC__K_DTYPE_OU:
7010 return "OU (Octaword logical)";
7011 case DSC__K_DTYPE_O:
7012 return "O (Octaword integer)";
7013 case DSC__K_DTYPE_G:
7014 return "G (Double precision G floating, 64 bit)";
7015 case DSC__K_DTYPE_H:
7016 return "H (Quadruple precision floating, 128 bit)";
7017 case DSC__K_DTYPE_GC:
7018 return "GC (Double precision complex, G floating)";
7019 case DSC__K_DTYPE_HC:
7020 return "HC (Quadruple precision complex, H floating)";
7021 case DSC__K_DTYPE_CIT:
7022 return "CIT (COBOL intermediate temporary)";
7023 case DSC__K_DTYPE_BPV:
7024 return "BPV (Bound Procedure Value)";
7025 case DSC__K_DTYPE_BLV:
7026 return "BLV (Bound Label Value)";
7027 case DSC__K_DTYPE_VU:
7028 return "VU (Bit Unaligned)";
7029 case DSC__K_DTYPE_ADT:
7030 return "ADT (Absolute Date-Time)";
7031 case DSC__K_DTYPE_VT:
7032 return "VT (Varying Text)";
7033 case DSC__K_DTYPE_T2:
7034 return "T2 (16-bit char)";
7035 case DSC__K_DTYPE_VT2:
7036 return "VT2 (16-bit varying char)";
7037 default:
7038 return "?? (unknown)";
7039 }
7040}
7041
7042static void
a3c0896d
AM
7043evax_bfd_print_desc (const unsigned char *buf, unsigned int bufsize,
7044 int indent, FILE *file)
95e34ef7 7045{
a3c0896d
AM
7046 if (bufsize < 8)
7047 return;
7048
95e34ef7
TG
7049 unsigned char bclass = buf[3];
7050 unsigned char dtype = buf[2];
7051 unsigned int len = (unsigned)bfd_getl16 (buf);
7052 unsigned int pointer = (unsigned)bfd_getl32 (buf + 4);
7053
7054 evax_bfd_print_indent (indent, file);
7055
7056 if (len == 1 && pointer == 0xffffffffUL)
7057 {
7058 /* 64 bits. */
7059 fprintf (file, _("64 bits *unhandled*\n"));
7060 }
7061 else
7062 {
695344c0 7063 /* xgettext:c-format */
95e34ef7 7064 fprintf (file, _("class: %u, dtype: %u, length: %u, pointer: 0x%08x\n"),
07d6d2b8 7065 bclass, dtype, len, pointer);
95e34ef7 7066 switch (bclass)
07d6d2b8
AM
7067 {
7068 case DSC__K_CLASS_NCA:
7069 {
7070 const struct vms_dsc_nca *dsc = (const void *)buf;
7071 unsigned int i;
7072 const unsigned char *b;
7073
7074 evax_bfd_print_indent (indent, file);
7075 fprintf (file, _("non-contiguous array of %s\n"),
7076 evax_bfd_get_dsc_name (dsc->dtype));
a3c0896d 7077 if (bufsize >= sizeof (*dsc))
07d6d2b8 7078 {
a3c0896d
AM
7079 evax_bfd_print_indent (indent + 1, file);
7080 fprintf (file,
7081 /* xgettext:c-format */
7082 _("dimct: %u, aflags: 0x%02x, digits: %u, scale: %u\n"),
7083 dsc->dimct, dsc->aflags, dsc->digits, dsc->scale);
7084 evax_bfd_print_indent (indent + 1, file);
7085 fprintf (file,
7086 /* xgettext:c-format */
7087 _("arsize: %u, a0: 0x%08x\n"),
7088 (unsigned) bfd_getl32 (dsc->arsize),
7089 (unsigned) bfd_getl32 (dsc->a0));
7090 evax_bfd_print_indent (indent + 1, file);
7091 fprintf (file, _("Strides:\n"));
7092 b = buf + sizeof (*dsc);
7093 bufsize -= sizeof (*dsc);
7094 for (i = 0; i < dsc->dimct; i++)
7095 {
7096 if (bufsize < 4)
7097 break;
7098 evax_bfd_print_indent (indent + 2, file);
7099 fprintf (file, "[%u]: %u\n", i + 1,
7100 (unsigned) bfd_getl32 (b));
7101 b += 4;
7102 bufsize -= 4;
7103 }
7104 evax_bfd_print_indent (indent + 1, file);
7105 fprintf (file, _("Bounds:\n"));
7106 for (i = 0; i < dsc->dimct; i++)
7107 {
7108 if (bufsize < 8)
7109 break;
7110 evax_bfd_print_indent (indent + 2, file);
7111 /* xgettext:c-format */
7112 fprintf (file, _("[%u]: Lower: %u, upper: %u\n"), i + 1,
7113 (unsigned) bfd_getl32 (b + 0),
7114 (unsigned) bfd_getl32 (b + 4));
7115 b += 8;
7116 bufsize -= 8;
7117 }
07d6d2b8
AM
7118 }
7119 }
7120 break;
7121 case DSC__K_CLASS_UBS:
7122 {
7123 const struct vms_dsc_ubs *ubs = (const void *)buf;
7124
7125 evax_bfd_print_indent (indent, file);
7126 fprintf (file, _("unaligned bit-string of %s\n"),
7127 evax_bfd_get_dsc_name (ubs->dtype));
a3c0896d
AM
7128 if (bufsize >= sizeof (*ubs))
7129 {
7130 evax_bfd_print_indent (indent + 1, file);
7131 fprintf (file,
7132 /* xgettext:c-format */
7133 _("base: %u, pos: %u\n"),
7134 (unsigned) bfd_getl32 (ubs->base),
7135 (unsigned) bfd_getl32 (ubs->pos));
7136 }
07d6d2b8
AM
7137 }
7138 break;
7139 default:
7140 fprintf (file, _("*unhandled*\n"));
7141 break;
7142 }
95e34ef7
TG
7143 }
7144}
7145
7146static unsigned int
a3c0896d
AM
7147evax_bfd_print_valspec (const unsigned char *buf, unsigned int bufsize,
7148 int indent, FILE *file)
95e34ef7 7149{
a3c0896d
AM
7150 if (bufsize < 5)
7151 return bufsize;
7152
95e34ef7 7153 unsigned int vflags = buf[0];
a3c0896d 7154 unsigned int value = (unsigned) bfd_getl32 (buf + 1);
95e34ef7
TG
7155 unsigned int len = 5;
7156
7157 evax_bfd_print_indent (indent, file);
695344c0 7158 /* xgettext:c-format */
95e34ef7
TG
7159 fprintf (file, _("vflags: 0x%02x, value: 0x%08x "), vflags, value);
7160 buf += 5;
a3c0896d 7161 bufsize -= 5;
95e34ef7
TG
7162
7163 switch (vflags)
7164 {
7165 case DST__K_VFLAGS_NOVAL:
7166 fprintf (file, _("(no value)\n"));
7167 break;
7168 case DST__K_VFLAGS_NOTACTIVE:
7169 fprintf (file, _("(not active)\n"));
7170 break;
7171 case DST__K_VFLAGS_UNALLOC:
7172 fprintf (file, _("(not allocated)\n"));
7173 break;
7174 case DST__K_VFLAGS_DSC:
7175 fprintf (file, _("(descriptor)\n"));
a3c0896d
AM
7176 if (value <= bufsize)
7177 evax_bfd_print_desc (buf + value, bufsize - value, indent + 1, file);
95e34ef7
TG
7178 break;
7179 case DST__K_VFLAGS_TVS:
7180 fprintf (file, _("(trailing value)\n"));
7181 break;
7182 case DST__K_VS_FOLLOWS:
7183 fprintf (file, _("(value spec follows)\n"));
7184 break;
7185 case DST__K_VFLAGS_BITOFFS:
7186 fprintf (file, _("(at bit offset %u)\n"), value);
7187 break;
7188 default:
695344c0 7189 /* xgettext:c-format */
95e34ef7 7190 fprintf (file, _("(reg: %u, disp: %u, indir: %u, kind: "),
07d6d2b8
AM
7191 (vflags & DST__K_REGNUM_MASK) >> DST__K_REGNUM_SHIFT,
7192 vflags & DST__K_DISP ? 1 : 0,
7193 vflags & DST__K_INDIR ? 1 : 0);
95e34ef7 7194 switch (vflags & DST__K_VALKIND_MASK)
07d6d2b8
AM
7195 {
7196 case DST__K_VALKIND_LITERAL:
7197 fputs (_("literal"), file);
7198 break;
7199 case DST__K_VALKIND_ADDR:
7200 fputs (_("address"), file);
7201 break;
7202 case DST__K_VALKIND_DESC:
7203 fputs (_("desc"), file);
7204 break;
7205 case DST__K_VALKIND_REG:
7206 fputs (_("reg"), file);
7207 break;
7208 }
95e34ef7
TG
7209 fputs (")\n", file);
7210 break;
7211 }
7212 return len;
7213}
7214
7215static void
a3c0896d
AM
7216evax_bfd_print_typspec (const unsigned char *buf, unsigned int bufsize,
7217 int indent, FILE *file)
95e34ef7 7218{
a3c0896d
AM
7219 if (bufsize < 3)
7220 return;
7221
95e34ef7 7222 unsigned char kind = buf[2];
a3c0896d 7223 unsigned int len = (unsigned) bfd_getl16 (buf);
95e34ef7
TG
7224
7225 evax_bfd_print_indent (indent, file);
695344c0
NC
7226 /* xgettext:c-format */
7227 fprintf (file, _("len: %2u, kind: %2u "), len, kind);
95e34ef7 7228 buf += 3;
a3c0896d 7229 bufsize -= 3;
95e34ef7
TG
7230 switch (kind)
7231 {
7232 case DST__K_TS_ATOM:
695344c0 7233 /* xgettext:c-format */
a3c0896d
AM
7234 if (bufsize >= 1)
7235 fprintf (file, _("atomic, type=0x%02x %s\n"),
7236 buf[0], evax_bfd_get_dsc_name (buf[0]));
95e34ef7
TG
7237 break;
7238 case DST__K_TS_IND:
a3c0896d
AM
7239 if (bufsize >= 4)
7240 fprintf (file, _("indirect, defined at 0x%08x\n"),
7241 (unsigned) bfd_getl32 (buf));
95e34ef7
TG
7242 break;
7243 case DST__K_TS_TPTR:
695344c0 7244 fprintf (file, _("typed pointer\n"));
a3c0896d 7245 evax_bfd_print_typspec (buf, bufsize, indent + 1, file);
95e34ef7
TG
7246 break;
7247 case DST__K_TS_PTR:
695344c0 7248 fprintf (file, _("pointer\n"));
95e34ef7
TG
7249 break;
7250 case DST__K_TS_ARRAY:
7251 {
07d6d2b8 7252 const unsigned char *vs;
a3c0896d 7253 unsigned int vs_len;
07d6d2b8
AM
7254 unsigned int vec_len;
7255 unsigned int i;
7256
a3c0896d
AM
7257 if (bufsize == 0)
7258 return;
07d6d2b8 7259 fprintf (file, _("array, dim: %u, bitmap: "), buf[0]);
a3c0896d 7260 --bufsize;
07d6d2b8
AM
7261 vec_len = (buf[0] + 1 + 7) / 8;
7262 for (i = 0; i < vec_len; i++)
a3c0896d
AM
7263 {
7264 if (bufsize == 0)
7265 break;
7266 fprintf (file, " %02x", buf[i + 1]);
7267 --bufsize;
7268 }
07d6d2b8 7269 fputc ('\n', file);
a3c0896d
AM
7270 if (bufsize == 0)
7271 return;
07d6d2b8
AM
7272 vs = buf + 1 + vec_len;
7273 evax_bfd_print_indent (indent, file);
7274 fprintf (file, _("array descriptor:\n"));
a3c0896d
AM
7275 vs_len = evax_bfd_print_valspec (vs, bufsize, indent + 1, file);
7276 vs += vs_len;
7277 if (bufsize > vs_len)
7278 {
7279 bufsize -= vs_len;
7280 for (i = 0; i < buf[0] + 1U; i++)
7281 if (buf[1 + i / 8] & (1 << (i % 8)))
7282 {
7283 evax_bfd_print_indent (indent, file);
7284 if (i == 0)
7285 fprintf (file, _("type spec for element:\n"));
7286 else
7287 fprintf (file, _("type spec for subscript %u:\n"), i);
7288 evax_bfd_print_typspec (vs, bufsize, indent + 1, file);
7289 if (bufsize < 2)
7290 break;
7291 vs_len = bfd_getl16 (vs);
7292 if (bufsize <= vs_len)
7293 break;
7294 vs += vs_len;
7295 bufsize -= vs_len;
7296 }
7297 }
95e34ef7
TG
7298 }
7299 break;
7300 default:
695344c0 7301 fprintf (file, _("*unhandled*\n"));
95e34ef7
TG
7302 }
7303}
7304
7305static void
7306evax_bfd_print_dst (struct bfd *abfd, unsigned int dst_size, FILE *file)
7307{
7308 unsigned int off = 0;
7309 unsigned int pc = 0;
7310 unsigned int line = 0;
7311
7312 fprintf (file, _("Debug symbol table:\n"));
7313
7314 while (dst_size > 0)
7315 {
7316 struct vms_dst_header dsth;
7317 unsigned int len;
7318 unsigned int type;
7319 unsigned char *buf;
7320
7321 if (bfd_bread (&dsth, sizeof (dsth), abfd) != sizeof (dsth))
07d6d2b8
AM
7322 {
7323 fprintf (file, _("cannot read DST header\n"));
7324 return;
7325 }
95e34ef7
TG
7326 len = bfd_getl16 (dsth.length);
7327 type = bfd_getl16 (dsth.type);
695344c0 7328 /* xgettext:c-format */
95e34ef7 7329 fprintf (file, _(" type: %3u, len: %3u (at 0x%08x): "),
07d6d2b8 7330 type, len, off);
a3c0896d 7331 if (len < sizeof (dsth))
07d6d2b8
AM
7332 {
7333 fputc ('\n', file);
7334 break;
7335 }
95e34ef7
TG
7336 dst_size -= len;
7337 off += len;
7338 len -= sizeof (dsth);
a3c0896d
AM
7339 if (len == 0)
7340 buf = NULL;
7341 else
07d6d2b8 7342 {
a3c0896d
AM
7343 buf = _bfd_malloc_and_read (abfd, len, len);
7344 if (buf == NULL)
7345 {
7346 fprintf (file, _("cannot read DST symbol\n"));
7347 return;
7348 }
07d6d2b8 7349 }
95e34ef7 7350 switch (type)
07d6d2b8
AM
7351 {
7352 case DSC__K_DTYPE_V:
7353 case DSC__K_DTYPE_BU:
7354 case DSC__K_DTYPE_WU:
7355 case DSC__K_DTYPE_LU:
7356 case DSC__K_DTYPE_QU:
7357 case DSC__K_DTYPE_B:
7358 case DSC__K_DTYPE_W:
7359 case DSC__K_DTYPE_L:
7360 case DSC__K_DTYPE_Q:
7361 case DSC__K_DTYPE_F:
7362 case DSC__K_DTYPE_D:
7363 case DSC__K_DTYPE_FC:
7364 case DSC__K_DTYPE_DC:
7365 case DSC__K_DTYPE_T:
7366 case DSC__K_DTYPE_NU:
7367 case DSC__K_DTYPE_NL:
7368 case DSC__K_DTYPE_NLO:
7369 case DSC__K_DTYPE_NR:
7370 case DSC__K_DTYPE_NRO:
7371 case DSC__K_DTYPE_NZ:
7372 case DSC__K_DTYPE_P:
7373 case DSC__K_DTYPE_ZI:
7374 case DSC__K_DTYPE_ZEM:
7375 case DSC__K_DTYPE_DSC:
7376 case DSC__K_DTYPE_OU:
7377 case DSC__K_DTYPE_O:
7378 case DSC__K_DTYPE_G:
7379 case DSC__K_DTYPE_H:
7380 case DSC__K_DTYPE_GC:
7381 case DSC__K_DTYPE_HC:
7382 case DSC__K_DTYPE_CIT:
7383 case DSC__K_DTYPE_BPV:
7384 case DSC__K_DTYPE_BLV:
7385 case DSC__K_DTYPE_VU:
7386 case DSC__K_DTYPE_ADT:
7387 case DSC__K_DTYPE_VT:
7388 case DSC__K_DTYPE_T2:
7389 case DSC__K_DTYPE_VT2:
7390 fprintf (file, _("standard data: %s\n"),
7391 evax_bfd_get_dsc_name (type));
a3c0896d 7392 evax_bfd_print_valspec (buf, len, 4, file);
07d6d2b8
AM
7393 fprintf (file, _(" name: %.*s\n"), buf[5], buf + 6);
7394 break;
7395 case DST__K_MODBEG:
7396 {
7397 struct vms_dst_modbeg *dst = (void *)buf;
7398 const char *name = (const char *)buf + sizeof (*dst);
7399
7400 fprintf (file, _("modbeg\n"));
a3c0896d
AM
7401 if (len < sizeof (*dst))
7402 break;
695344c0 7403 /* xgettext:c-format */
07d6d2b8
AM
7404 fprintf (file, _(" flags: %d, language: %u, "
7405 "major: %u, minor: %u\n"),
7406 dst->flags,
7407 (unsigned)bfd_getl32 (dst->language),
7408 (unsigned)bfd_getl16 (dst->major),
7409 (unsigned)bfd_getl16 (dst->minor));
a3c0896d
AM
7410 len -= sizeof (*dst);
7411 if (len > 0)
7412 {
7413 int nlen = len - 1;
7414 fprintf (file, _(" module name: %.*s\n"),
7415 name[0] > nlen ? nlen : name[0], name + 1);
7416 if (name[0] < nlen)
7417 {
7418 len -= name[0] + 1;
7419 name += name[0] + 1;
7420 nlen = len - 1;
7421 fprintf (file, _(" compiler : %.*s\n"),
7422 name[0] > nlen ? nlen: name[0], name + 1);
7423 }
7424 }
07d6d2b8
AM
7425 }
7426 break;
7427 case DST__K_MODEND:
7428 fprintf (file, _("modend\n"));
7429 break;
7430 case DST__K_RTNBEG:
7431 {
7432 struct vms_dst_rtnbeg *dst = (void *)buf;
7433 const char *name = (const char *)buf + sizeof (*dst);
7434
7435 fputs (_("rtnbeg\n"), file);
a3c0896d
AM
7436 if (len >= sizeof (*dst))
7437 {
7438 /* xgettext:c-format */
7439 fprintf (file, _(" flags: %u, address: 0x%08x, "
7440 "pd-address: 0x%08x\n"),
7441 dst->flags,
7442 (unsigned) bfd_getl32 (dst->address),
7443 (unsigned) bfd_getl32 (dst->pd_address));
7444 len -= sizeof (*dst);
7445 if (len > 0)
7446 {
7447 int nlen = len - 1;
7448 fprintf (file, _(" routine name: %.*s\n"),
7449 name[0] > nlen ? nlen : name[0], name + 1);
7450 }
7451 }
07d6d2b8
AM
7452 }
7453 break;
7454 case DST__K_RTNEND:
7455 {
7456 struct vms_dst_rtnend *dst = (void *)buf;
7457
a3c0896d
AM
7458 if (len >= sizeof (*dst))
7459 fprintf (file, _("rtnend: size 0x%08x\n"),
7460 (unsigned) bfd_getl32 (dst->size));
07d6d2b8
AM
7461 }
7462 break;
7463 case DST__K_PROLOG:
7464 {
7465 struct vms_dst_prolog *dst = (void *)buf;
7466
a3c0896d
AM
7467 if (len >= sizeof (*dst))
7468 /* xgettext:c-format */
7469 fprintf (file, _("prolog: bkpt address 0x%08x\n"),
7470 (unsigned) bfd_getl32 (dst->bkpt_addr));
07d6d2b8
AM
7471 }
7472 break;
7473 case DST__K_EPILOG:
7474 {
7475 struct vms_dst_epilog *dst = (void *)buf;
95e34ef7 7476
a3c0896d
AM
7477 if (len >= sizeof (*dst))
7478 /* xgettext:c-format */
7479 fprintf (file, _("epilog: flags: %u, count: %u\n"),
7480 dst->flags, (unsigned) bfd_getl32 (dst->count));
07d6d2b8
AM
7481 }
7482 break;
7483 case DST__K_BLKBEG:
7484 {
7485 struct vms_dst_blkbeg *dst = (void *)buf;
7486 const char *name = (const char *)buf + sizeof (*dst);
95e34ef7 7487
a3c0896d
AM
7488 if (len > sizeof (*dst))
7489 {
7490 int nlen;
7491 len -= sizeof (*dst);
7492 nlen = len - 1;
7493 /* xgettext:c-format */
7494 fprintf (file, _("blkbeg: address: 0x%08x, name: %.*s\n"),
7495 (unsigned) bfd_getl32 (dst->address),
7496 name[0] > nlen ? nlen : name[0], name + 1);
7497 }
07d6d2b8
AM
7498 }
7499 break;
7500 case DST__K_BLKEND:
7501 {
7502 struct vms_dst_blkend *dst = (void *)buf;
7503
a3c0896d
AM
7504 if (len >= sizeof (*dst))
7505 /* xgettext:c-format */
7506 fprintf (file, _("blkend: size: 0x%08x\n"),
7507 (unsigned) bfd_getl32 (dst->size));
07d6d2b8
AM
7508 }
7509 break;
7510 case DST__K_TYPSPEC:
7511 {
7512 fprintf (file, _("typspec (len: %u)\n"), len);
a3c0896d
AM
7513 if (len >= 1)
7514 {
7515 int nlen = len - 1;
7516 fprintf (file, _(" name: %.*s\n"),
7517 buf[0] > nlen ? nlen : buf[0], buf + 1);
7518 if (nlen > buf[0])
7519 evax_bfd_print_typspec (buf + 1 + buf[0], len - (1 + buf[0]),
7520 5, file);
7521 }
07d6d2b8
AM
7522 }
7523 break;
7524 case DST__K_SEPTYP:
7525 {
a3c0896d
AM
7526 if (len >= 6)
7527 {
7528 fprintf (file, _("septyp, name: %.*s\n"),
7529 buf[5] > len - 6 ? len - 6 : buf[5], buf + 6);
7530 evax_bfd_print_valspec (buf, len, 4, file);
7531 }
07d6d2b8
AM
7532 }
7533 break;
7534 case DST__K_RECBEG:
7535 {
7536 struct vms_dst_recbeg *recbeg = (void *)buf;
7537 const char *name = (const char *)buf + sizeof (*recbeg);
7538
a3c0896d
AM
7539 if (len > sizeof (*recbeg))
7540 {
7541 int nlen = len - sizeof (*recbeg) - 1;
7542 if (name[0] < nlen)
7543 nlen = name[0];
7544 fprintf (file, _("recbeg: name: %.*s\n"), nlen, name + 1);
7545 evax_bfd_print_valspec (buf, len, 4, file);
7546 len -= 1 + nlen;
7547 if (len >= 4)
7548 fprintf (file, _(" len: %u bits\n"),
7549 (unsigned) bfd_getl32 (name + 1 + nlen));
7550 }
07d6d2b8
AM
7551 }
7552 break;
7553 case DST__K_RECEND:
7554 fprintf (file, _("recend\n"));
7555 break;
7556 case DST__K_ENUMBEG:
a3c0896d
AM
7557 if (len >= 2)
7558 /* xgettext:c-format */
7559 fprintf (file, _("enumbeg, len: %u, name: %.*s\n"),
7560 buf[0], buf[1] > len - 2 ? len - 2 : buf[1], buf + 2);
07d6d2b8
AM
7561 break;
7562 case DST__K_ENUMELT:
a3c0896d
AM
7563 if (len >= 6)
7564 {
7565 fprintf (file, _("enumelt, name: %.*s\n"),
7566 buf[5] > len - 6 ? len - 6 : buf[5], buf + 6);
7567 evax_bfd_print_valspec (buf, len, 4, file);
7568 }
07d6d2b8
AM
7569 break;
7570 case DST__K_ENUMEND:
7571 fprintf (file, _("enumend\n"));
7572 break;
7573 case DST__K_LABEL:
7574 {
7575 struct vms_dst_label *lab = (void *)buf;
a3c0896d
AM
7576 if (len >= sizeof (*lab))
7577 {
7578 fprintf (file, _("label, name: %.*s\n"),
7579 lab->name[0] > len - 1 ? len - 1 : lab->name[0],
7580 lab->name + 1);
7581 fprintf (file, _(" address: 0x%08x\n"),
7582 (unsigned) bfd_getl32 (lab->value));
7583 }
07d6d2b8
AM
7584 }
7585 break;
7586 case DST__K_DIS_RANGE:
a3c0896d
AM
7587 if (len >= 4)
7588 {
7589 unsigned int cnt = bfd_getl32 (buf);
7590 unsigned char *rng = buf + 4;
7591 unsigned int i;
07d6d2b8 7592
a3c0896d
AM
7593 fprintf (file, _("discontiguous range (nbr: %u)\n"), cnt);
7594 len -= 4;
7595 for (i = 0; i < cnt; i++, rng += 8)
7596 {
7597 if (len < 8)
7598 break;
7599 /* xgettext:c-format */
7600 fprintf (file, _(" address: 0x%08x, size: %u\n"),
7601 (unsigned) bfd_getl32 (rng),
7602 (unsigned) bfd_getl32 (rng + 4));
7603 len -= 8;
7604 }
7605 }
07d6d2b8
AM
7606 break;
7607 case DST__K_LINE_NUM:
7608 {
7609 unsigned char *buf_orig = buf;
7610
7611 fprintf (file, _("line num (len: %u)\n"), len);
7612
7613 while (len > 0)
7614 {
a3c0896d 7615 int cmd;
07d6d2b8 7616 unsigned int val;
a3c0896d 7617 int cmdlen = -1;
07d6d2b8 7618
a3c0896d
AM
7619 cmd = *buf++;
7620 len--;
07d6d2b8
AM
7621
7622 fputs (" ", file);
7623
7624 switch (cmd)
7625 {
7626 case DST__K_DELTA_PC_W:
a3c0896d
AM
7627 if (len < 2)
7628 break;
7629 val = bfd_getl16 (buf);
07d6d2b8
AM
7630 fprintf (file, _("delta_pc_w %u\n"), val);
7631 pc += val;
7632 line++;
a3c0896d 7633 cmdlen = 2;
07d6d2b8
AM
7634 break;
7635 case DST__K_INCR_LINUM:
a3c0896d
AM
7636 if (len < 1)
7637 break;
7638 val = *buf;
07d6d2b8
AM
7639 fprintf (file, _("incr_linum(b): +%u\n"), val);
7640 line += val;
a3c0896d 7641 cmdlen = 1;
07d6d2b8
AM
7642 break;
7643 case DST__K_INCR_LINUM_W:
a3c0896d
AM
7644 if (len < 2)
7645 break;
7646 val = bfd_getl16 (buf);
07d6d2b8
AM
7647 fprintf (file, _("incr_linum_w: +%u\n"), val);
7648 line += val;
a3c0896d 7649 cmdlen = 2;
07d6d2b8
AM
7650 break;
7651 case DST__K_INCR_LINUM_L:
a3c0896d
AM
7652 if (len < 4)
7653 break;
7654 val = bfd_getl32 (buf);
07d6d2b8
AM
7655 fprintf (file, _("incr_linum_l: +%u\n"), val);
7656 line += val;
a3c0896d 7657 cmdlen = 4;
07d6d2b8
AM
7658 break;
7659 case DST__K_SET_LINUM:
a3c0896d
AM
7660 if (len < 2)
7661 break;
7662 line = bfd_getl16 (buf);
07d6d2b8 7663 fprintf (file, _("set_line_num(w) %u\n"), line);
a3c0896d 7664 cmdlen = 2;
07d6d2b8
AM
7665 break;
7666 case DST__K_SET_LINUM_B:
a3c0896d
AM
7667 if (len < 1)
7668 break;
7669 line = *buf;
07d6d2b8 7670 fprintf (file, _("set_line_num_b %u\n"), line);
a3c0896d 7671 cmdlen = 1;
07d6d2b8
AM
7672 break;
7673 case DST__K_SET_LINUM_L:
a3c0896d
AM
7674 if (len < 4)
7675 break;
7676 line = bfd_getl32 (buf);
07d6d2b8 7677 fprintf (file, _("set_line_num_l %u\n"), line);
a3c0896d 7678 cmdlen = 4;
07d6d2b8
AM
7679 break;
7680 case DST__K_SET_ABS_PC:
a3c0896d
AM
7681 if (len < 4)
7682 break;
7683 pc = bfd_getl32 (buf);
07d6d2b8 7684 fprintf (file, _("set_abs_pc: 0x%08x\n"), pc);
a3c0896d 7685 cmdlen = 4;
07d6d2b8
AM
7686 break;
7687 case DST__K_DELTA_PC_L:
a3c0896d
AM
7688 if (len < 4)
7689 break;
07d6d2b8 7690 fprintf (file, _("delta_pc_l: +0x%08x\n"),
a3c0896d
AM
7691 (unsigned) bfd_getl32 (buf));
7692 cmdlen = 4;
07d6d2b8
AM
7693 break;
7694 case DST__K_TERM:
a3c0896d
AM
7695 if (len < 1)
7696 break;
7697 fprintf (file, _("term(b): 0x%02x"), *buf);
7698 pc += *buf;
07d6d2b8 7699 fprintf (file, _(" pc: 0x%08x\n"), pc);
a3c0896d 7700 cmdlen = 1;
07d6d2b8
AM
7701 break;
7702 case DST__K_TERM_W:
a3c0896d
AM
7703 if (len < 2)
7704 break;
7705 val = bfd_getl16 (buf);
07d6d2b8
AM
7706 fprintf (file, _("term_w: 0x%04x"), val);
7707 pc += val;
7708 fprintf (file, _(" pc: 0x%08x\n"), pc);
a3c0896d 7709 cmdlen = 2;
07d6d2b8
AM
7710 break;
7711 default:
7712 if (cmd <= 0)
7713 {
7714 fprintf (file, _("delta pc +%-4d"), -cmd);
7715 line++; /* FIXME: curr increment. */
7716 pc += -cmd;
695344c0 7717 /* xgettext:c-format */
07d6d2b8
AM
7718 fprintf (file, _(" pc: 0x%08x line: %5u\n"),
7719 pc, line);
a3c0896d 7720 cmdlen = 0;
07d6d2b8
AM
7721 }
7722 else
7723 fprintf (file, _(" *unhandled* cmd %u\n"), cmd);
7724 break;
7725 }
a3c0896d 7726 if (cmdlen < 0)
07d6d2b8
AM
7727 break;
7728 len -= cmdlen;
7729 buf += cmdlen;
7730 }
7731 buf = buf_orig;
7732 }
7733 break;
7734 case DST__K_SOURCE:
7735 {
7736 unsigned char *buf_orig = buf;
7737
7738 fprintf (file, _("source (len: %u)\n"), len);
7739
7740 while (len > 0)
7741 {
a3c0896d
AM
7742 int cmd = *buf++;
7743 int cmdlen = -1;
07d6d2b8 7744
a3c0896d 7745 len--;
07d6d2b8
AM
7746 switch (cmd)
7747 {
7748 case DST__K_SRC_DECLFILE:
7749 {
a3c0896d 7750 struct vms_dst_src_decl_src *src = (void *) buf;
07d6d2b8 7751 const char *name;
a3c0896d 7752 int nlen;
95e34ef7 7753
a3c0896d
AM
7754 if (len < sizeof (*src))
7755 break;
695344c0 7756 /* xgettext:c-format */
07d6d2b8
AM
7757 fprintf (file, _(" declfile: len: %u, flags: %u, "
7758 "fileid: %u\n"),
7759 src->length, src->flags,
7760 (unsigned)bfd_getl16 (src->fileid));
695344c0 7761 /* xgettext:c-format */
07d6d2b8
AM
7762 fprintf (file, _(" rms: cdt: 0x%08x %08x, "
7763 "ebk: 0x%08x, ffb: 0x%04x, "
7764 "rfo: %u\n"),
7765 (unsigned)bfd_getl32 (src->rms_cdt + 4),
7766 (unsigned)bfd_getl32 (src->rms_cdt + 0),
7767 (unsigned)bfd_getl32 (src->rms_ebk),
7768 (unsigned)bfd_getl16 (src->rms_ffb),
7769 src->rms_rfo);
a3c0896d
AM
7770 if (src->length > len || src->length <= sizeof (*src))
7771 break;
7772 nlen = src->length - sizeof (*src) - 1;
7773 name = (const char *) buf + sizeof (*src);
07d6d2b8 7774 fprintf (file, _(" filename : %.*s\n"),
a3c0896d
AM
7775 name[0] > nlen ? nlen : name[0], name + 1);
7776 if (name[0] >= nlen)
7777 break;
7778 nlen -= name[0] + 1;
07d6d2b8
AM
7779 name += name[0] + 1;
7780 fprintf (file, _(" module name: %.*s\n"),
a3c0896d
AM
7781 name[0] > nlen ? nlen : name[0], name + 1);
7782 if (name[0] > nlen)
7783 break;
7784 cmdlen = src->length;
07d6d2b8
AM
7785 }
7786 break;
7787 case DST__K_SRC_SETFILE:
a3c0896d
AM
7788 if (len < 2)
7789 break;
07d6d2b8 7790 fprintf (file, _(" setfile %u\n"),
a3c0896d
AM
7791 (unsigned) bfd_getl16 (buf));
7792 cmdlen = 2;
07d6d2b8
AM
7793 break;
7794 case DST__K_SRC_SETREC_W:
a3c0896d
AM
7795 if (len < 2)
7796 break;
07d6d2b8 7797 fprintf (file, _(" setrec %u\n"),
a3c0896d
AM
7798 (unsigned) bfd_getl16 (buf));
7799 cmdlen = 2;
07d6d2b8
AM
7800 break;
7801 case DST__K_SRC_SETREC_L:
a3c0896d
AM
7802 if (len < 4)
7803 break;
07d6d2b8 7804 fprintf (file, _(" setrec %u\n"),
a3c0896d
AM
7805 (unsigned) bfd_getl32 (buf));
7806 cmdlen = 4;
07d6d2b8
AM
7807 break;
7808 case DST__K_SRC_SETLNUM_W:
a3c0896d
AM
7809 if (len < 2)
7810 break;
07d6d2b8 7811 fprintf (file, _(" setlnum %u\n"),
a3c0896d
AM
7812 (unsigned) bfd_getl16 (buf));
7813 cmdlen = 2;
07d6d2b8
AM
7814 break;
7815 case DST__K_SRC_SETLNUM_L:
a3c0896d
AM
7816 if (len < 4)
7817 break;
07d6d2b8 7818 fprintf (file, _(" setlnum %u\n"),
a3c0896d
AM
7819 (unsigned) bfd_getl32 (buf));
7820 cmdlen = 4;
07d6d2b8
AM
7821 break;
7822 case DST__K_SRC_DEFLINES_W:
a3c0896d
AM
7823 if (len < 2)
7824 break;
07d6d2b8 7825 fprintf (file, _(" deflines %u\n"),
a3c0896d
AM
7826 (unsigned) bfd_getl16 (buf));
7827 cmdlen = 2;
07d6d2b8
AM
7828 break;
7829 case DST__K_SRC_DEFLINES_B:
a3c0896d
AM
7830 if (len < 1)
7831 break;
7832 fprintf (file, _(" deflines %u\n"), *buf);
7833 cmdlen = 1;
07d6d2b8
AM
7834 break;
7835 case DST__K_SRC_FORMFEED:
7836 fprintf (file, _(" formfeed\n"));
a3c0896d 7837 cmdlen = 0;
07d6d2b8
AM
7838 break;
7839 default:
7840 fprintf (file, _(" *unhandled* cmd %u\n"), cmd);
7841 break;
7842 }
a3c0896d 7843 if (cmdlen < 0)
07d6d2b8
AM
7844 break;
7845 len -= cmdlen;
7846 buf += cmdlen;
7847 }
7848 buf = buf_orig;
7849 }
7850 break;
7851 default:
7852 fprintf (file, _("*unhandled* dst type %u\n"), type);
7853 break;
7854 }
95e34ef7
TG
7855 free (buf);
7856 }
7857}
7858
7859static void
7860evax_bfd_print_image (bfd *abfd, FILE *file)
7861{
7862 struct vms_eihd eihd;
7863 const char *name;
7864 unsigned int val;
7865 unsigned int eiha_off;
7866 unsigned int eihi_off;
7867 unsigned int eihs_off;
7868 unsigned int eisd_off;
7869 unsigned int eihef_off = 0;
7870 unsigned int eihnp_off = 0;
7871 unsigned int dmt_vbn = 0;
7872 unsigned int dmt_size = 0;
7873 unsigned int dst_vbn = 0;
7874 unsigned int dst_size = 0;
7875 unsigned int gst_vbn = 0;
7876 unsigned int gst_size = 0;
7877 unsigned int eiaf_vbn = 0;
7878 unsigned int eiaf_size = 0;
7879 unsigned int eihvn_off;
7880
7881 if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET)
7882 || bfd_bread (&eihd, sizeof (eihd), abfd) != sizeof (eihd))
7883 {
7884 fprintf (file, _("cannot read EIHD\n"));
7885 return;
7886 }
695344c0 7887 /* xgettext:c-format */
95e34ef7 7888 fprintf (file, _("EIHD: (size: %u, nbr blocks: %u)\n"),
07d6d2b8
AM
7889 (unsigned)bfd_getl32 (eihd.size),
7890 (unsigned)bfd_getl32 (eihd.hdrblkcnt));
695344c0 7891 /* xgettext:c-format */
95e34ef7 7892 fprintf (file, _(" majorid: %u, minorid: %u\n"),
07d6d2b8
AM
7893 (unsigned)bfd_getl32 (eihd.majorid),
7894 (unsigned)bfd_getl32 (eihd.minorid));
95e34ef7
TG
7895
7896 val = (unsigned)bfd_getl32 (eihd.imgtype);
7897 switch (val)
7898 {
7899 case EIHD__K_EXE:
7900 name = _("executable");
7901 break;
7902 case EIHD__K_LIM:
7903 name = _("linkable image");
7904 break;
7905 default:
7906 name = _("unknown");
7907 break;
7908 }
695344c0 7909 /* xgettext:c-format */
95e34ef7
TG
7910 fprintf (file, _(" image type: %u (%s)"), val, name);
7911
7912 val = (unsigned)bfd_getl32 (eihd.subtype);
7913 switch (val)
7914 {
7915 case EIHD__C_NATIVE:
7916 name = _("native");
7917 break;
7918 case EIHD__C_CLI:
7919 name = _("CLI");
7920 break;
7921 default:
7922 name = _("unknown");
7923 break;
7924 }
695344c0 7925 /* xgettext:c-format */
95e34ef7
TG
7926 fprintf (file, _(", subtype: %u (%s)\n"), val, name);
7927
7928 eisd_off = bfd_getl32 (eihd.isdoff);
7929 eiha_off = bfd_getl32 (eihd.activoff);
7930 eihi_off = bfd_getl32 (eihd.imgidoff);
7931 eihs_off = bfd_getl32 (eihd.symdbgoff);
695344c0 7932 /* xgettext:c-format */
95e34ef7 7933 fprintf (file, _(" offsets: isd: %u, activ: %u, symdbg: %u, "
07d6d2b8
AM
7934 "imgid: %u, patch: %u\n"),
7935 eisd_off, eiha_off, eihs_off, eihi_off,
7936 (unsigned)bfd_getl32 (eihd.patchoff));
95e34ef7
TG
7937 fprintf (file, _(" fixup info rva: "));
7938 bfd_fprintf_vma (abfd, file, bfd_getl64 (eihd.iafva));
7939 fprintf (file, _(", symbol vector rva: "));
7940 bfd_fprintf_vma (abfd, file, bfd_getl64 (eihd.symvva));
7941 eihvn_off = bfd_getl32 (eihd.version_array_off);
7942 fprintf (file, _("\n"
07d6d2b8
AM
7943 " version array off: %u\n"),
7944 eihvn_off);
95e34ef7 7945 fprintf (file,
695344c0 7946 /* xgettext:c-format */
07d6d2b8
AM
7947 _(" img I/O count: %u, nbr channels: %u, req pri: %08x%08x\n"),
7948 (unsigned)bfd_getl32 (eihd.imgiocnt),
7949 (unsigned)bfd_getl32 (eihd.iochancnt),
7950 (unsigned)bfd_getl32 (eihd.privreqs + 4),
7951 (unsigned)bfd_getl32 (eihd.privreqs + 0));
95e34ef7
TG
7952 val = (unsigned)bfd_getl32 (eihd.lnkflags);
7953 fprintf (file, _(" linker flags: %08x:"), val);
7954 if (val & EIHD__M_LNKDEBUG)
7955 fprintf (file, " LNKDEBUG");
7956 if (val & EIHD__M_LNKNOTFR)
7957 fprintf (file, " LNKNOTFR");
7958 if (val & EIHD__M_NOP0BUFS)
7959 fprintf (file, " NOP0BUFS");
7960 if (val & EIHD__M_PICIMG)
7961 fprintf (file, " PICIMG");
7962 if (val & EIHD__M_P0IMAGE)
7963 fprintf (file, " P0IMAGE");
7964 if (val & EIHD__M_DBGDMT)
7965 fprintf (file, " DBGDMT");
7966 if (val & EIHD__M_INISHR)
7967 fprintf (file, " INISHR");
7968 if (val & EIHD__M_XLATED)
7969 fprintf (file, " XLATED");
7970 if (val & EIHD__M_BIND_CODE_SEC)
7971 fprintf (file, " BIND_CODE_SEC");
7972 if (val & EIHD__M_BIND_DATA_SEC)
7973 fprintf (file, " BIND_DATA_SEC");
7974 if (val & EIHD__M_MKTHREADS)
7975 fprintf (file, " MKTHREADS");
7976 if (val & EIHD__M_UPCALLS)
7977 fprintf (file, " UPCALLS");
7978 if (val & EIHD__M_OMV_READY)
7979 fprintf (file, " OMV_READY");
7980 if (val & EIHD__M_EXT_BIND_SECT)
7981 fprintf (file, " EXT_BIND_SECT");
7982 fprintf (file, "\n");
695344c0 7983 /* xgettext:c-format */
95e34ef7 7984 fprintf (file, _(" ident: 0x%08x, sysver: 0x%08x, "
07d6d2b8
AM
7985 "match ctrl: %u, symvect_size: %u\n"),
7986 (unsigned)bfd_getl32 (eihd.ident),
7987 (unsigned)bfd_getl32 (eihd.sysver),
7988 eihd.matchctl,
7989 (unsigned)bfd_getl32 (eihd.symvect_size));
95e34ef7 7990 fprintf (file, _(" BPAGE: %u"),
07d6d2b8 7991 (unsigned)bfd_getl32 (eihd.virt_mem_block_size));
95e34ef7
TG
7992 if (val & (EIHD__M_OMV_READY | EIHD__M_EXT_BIND_SECT))
7993 {
7994 eihef_off = bfd_getl32 (eihd.ext_fixup_off);
7995 eihnp_off = bfd_getl32 (eihd.noopt_psect_off);
695344c0 7996 /* xgettext:c-format */
95e34ef7 7997 fprintf (file, _(", ext fixup offset: %u, no_opt psect off: %u"),
07d6d2b8 7998 eihef_off, eihnp_off);
95e34ef7
TG
7999 }
8000 fprintf (file, _(", alias: %u\n"), (unsigned)bfd_getl16 (eihd.alias));
8001
8002 if (eihvn_off != 0)
8003 {
8004 struct vms_eihvn eihvn;
8005 unsigned int mask;
8006 unsigned int j;
8007
8008 fprintf (file, _("system version array information:\n"));
8009 if (bfd_seek (abfd, (file_ptr) eihvn_off, SEEK_SET)
07d6d2b8
AM
8010 || bfd_bread (&eihvn, sizeof (eihvn), abfd) != sizeof (eihvn))
8011 {
8012 fprintf (file, _("cannot read EIHVN header\n"));
8013 return;
8014 }
95e34ef7
TG
8015 mask = bfd_getl32 (eihvn.subsystem_mask);
8016 for (j = 0; j < 32; j++)
9216910e 8017 if (mask & (1u << j))
07d6d2b8
AM
8018 {
8019 struct vms_eihvn_subversion ver;
8020 if (bfd_bread (&ver, sizeof (ver), abfd) != sizeof (ver))
8021 {
8022 fprintf (file, _("cannot read EIHVN version\n"));
8023 return;
8024 }
8025 fprintf (file, _(" %02u "), j);
8026 switch (j)
8027 {
8028 case EIHVN__BASE_IMAGE_BIT:
95e34ef7 8029 fputs (_("BASE_IMAGE "), file);
07d6d2b8
AM
8030 break;
8031 case EIHVN__MEMORY_MANAGEMENT_BIT:
8032 fputs (_("MEMORY_MANAGEMENT"), file);
8033 break;
8034 case EIHVN__IO_BIT:
8035 fputs (_("IO "), file);
8036 break;
8037 case EIHVN__FILES_VOLUMES_BIT:
8038 fputs (_("FILES_VOLUMES "), file);
8039 break;
8040 case EIHVN__PROCESS_SCHED_BIT:
8041 fputs (_("PROCESS_SCHED "), file);
8042 break;
8043 case EIHVN__SYSGEN_BIT:
95e34ef7 8044 fputs (_("SYSGEN "), file);
07d6d2b8
AM
8045 break;
8046 case EIHVN__CLUSTERS_LOCKMGR_BIT:
8047 fputs (_("CLUSTERS_LOCKMGR "), file);
8048 break;
8049 case EIHVN__LOGICAL_NAMES_BIT:
8050 fputs (_("LOGICAL_NAMES "), file);
8051 break;
8052 case EIHVN__SECURITY_BIT:
95e34ef7 8053 fputs (_("SECURITY "), file);
07d6d2b8
AM
8054 break;
8055 case EIHVN__IMAGE_ACTIVATOR_BIT:
8056 fputs (_("IMAGE_ACTIVATOR "), file);
8057 break;
8058 case EIHVN__NETWORKS_BIT:
95e34ef7 8059 fputs (_("NETWORKS "), file);
07d6d2b8
AM
8060 break;
8061 case EIHVN__COUNTERS_BIT:
95e34ef7 8062 fputs (_("COUNTERS "), file);
07d6d2b8
AM
8063 break;
8064 case EIHVN__STABLE_BIT:
95e34ef7 8065 fputs (_("STABLE "), file);
07d6d2b8
AM
8066 break;
8067 case EIHVN__MISC_BIT:
8068 fputs (_("MISC "), file);
8069 break;
8070 case EIHVN__CPU_BIT:
8071 fputs (_("CPU "), file);
8072 break;
8073 case EIHVN__VOLATILE_BIT:
95e34ef7 8074 fputs (_("VOLATILE "), file);
07d6d2b8
AM
8075 break;
8076 case EIHVN__SHELL_BIT:
95e34ef7 8077 fputs (_("SHELL "), file);
07d6d2b8
AM
8078 break;
8079 case EIHVN__POSIX_BIT:
95e34ef7 8080 fputs (_("POSIX "), file);
07d6d2b8
AM
8081 break;
8082 case EIHVN__MULTI_PROCESSING_BIT:
8083 fputs (_("MULTI_PROCESSING "), file);
8084 break;
8085 case EIHVN__GALAXY_BIT:
95e34ef7 8086 fputs (_("GALAXY "), file);
07d6d2b8
AM
8087 break;
8088 default:
8089 fputs (_("*unknown* "), file);
8090 break;
8091 }
8092 fprintf (file, ": %u.%u\n",
8093 (unsigned)bfd_getl16 (ver.major),
8094 (unsigned)bfd_getl16 (ver.minor));
8095 }
95e34ef7
TG
8096 }
8097
8098 if (eiha_off != 0)
8099 {
8100 struct vms_eiha eiha;
8101
8102 if (bfd_seek (abfd, (file_ptr) eiha_off, SEEK_SET)
07d6d2b8
AM
8103 || bfd_bread (&eiha, sizeof (eiha), abfd) != sizeof (eiha))
8104 {
8105 fprintf (file, _("cannot read EIHA\n"));
8106 return;
8107 }
95e34ef7 8108 fprintf (file, _("Image activation: (size=%u)\n"),
07d6d2b8 8109 (unsigned)bfd_getl32 (eiha.size));
695344c0 8110 /* xgettext:c-format */
95e34ef7 8111 fprintf (file, _(" First address : 0x%08x 0x%08x\n"),
07d6d2b8
AM
8112 (unsigned)bfd_getl32 (eiha.tfradr1_h),
8113 (unsigned)bfd_getl32 (eiha.tfradr1));
695344c0 8114 /* xgettext:c-format */
95e34ef7 8115 fprintf (file, _(" Second address: 0x%08x 0x%08x\n"),
07d6d2b8
AM
8116 (unsigned)bfd_getl32 (eiha.tfradr2_h),
8117 (unsigned)bfd_getl32 (eiha.tfradr2));
695344c0 8118 /* xgettext:c-format */
95e34ef7 8119 fprintf (file, _(" Third address : 0x%08x 0x%08x\n"),
07d6d2b8
AM
8120 (unsigned)bfd_getl32 (eiha.tfradr3_h),
8121 (unsigned)bfd_getl32 (eiha.tfradr3));
695344c0 8122 /* xgettext:c-format */
95e34ef7 8123 fprintf (file, _(" Fourth address: 0x%08x 0x%08x\n"),
07d6d2b8
AM
8124 (unsigned)bfd_getl32 (eiha.tfradr4_h),
8125 (unsigned)bfd_getl32 (eiha.tfradr4));
695344c0 8126 /* xgettext:c-format */
95e34ef7 8127 fprintf (file, _(" Shared image : 0x%08x 0x%08x\n"),
07d6d2b8
AM
8128 (unsigned)bfd_getl32 (eiha.inishr_h),
8129 (unsigned)bfd_getl32 (eiha.inishr));
95e34ef7
TG
8130 }
8131 if (eihi_off != 0)
8132 {
8133 struct vms_eihi eihi;
8134
8135 if (bfd_seek (abfd, (file_ptr) eihi_off, SEEK_SET)
07d6d2b8
AM
8136 || bfd_bread (&eihi, sizeof (eihi), abfd) != sizeof (eihi))
8137 {
8138 fprintf (file, _("cannot read EIHI\n"));
8139 return;
8140 }
695344c0 8141 /* xgettext:c-format */
95e34ef7 8142 fprintf (file, _("Image identification: (major: %u, minor: %u)\n"),
07d6d2b8
AM
8143 (unsigned)bfd_getl32 (eihi.majorid),
8144 (unsigned)bfd_getl32 (eihi.minorid));
95e34ef7 8145 fprintf (file, _(" image name : %.*s\n"),
07d6d2b8 8146 eihi.imgnam[0], eihi.imgnam + 1);
95e34ef7 8147 fprintf (file, _(" link time : %s\n"),
07d6d2b8 8148 vms_time_to_str (eihi.linktime));
95e34ef7 8149 fprintf (file, _(" image ident : %.*s\n"),
07d6d2b8 8150 eihi.imgid[0], eihi.imgid + 1);
95e34ef7 8151 fprintf (file, _(" linker ident : %.*s\n"),
07d6d2b8 8152 eihi.linkid[0], eihi.linkid + 1);
95e34ef7 8153 fprintf (file, _(" image build ident: %.*s\n"),
07d6d2b8 8154 eihi.imgbid[0], eihi.imgbid + 1);
95e34ef7
TG
8155 }
8156 if (eihs_off != 0)
8157 {
8158 struct vms_eihs eihs;
8159
8160 if (bfd_seek (abfd, (file_ptr) eihs_off, SEEK_SET)
07d6d2b8
AM
8161 || bfd_bread (&eihs, sizeof (eihs), abfd) != sizeof (eihs))
8162 {
8163 fprintf (file, _("cannot read EIHS\n"));
8164 return;
8165 }
695344c0 8166 /* xgettext:c-format */
95e34ef7 8167 fprintf (file, _("Image symbol & debug table: (major: %u, minor: %u)\n"),
07d6d2b8
AM
8168 (unsigned)bfd_getl32 (eihs.majorid),
8169 (unsigned)bfd_getl32 (eihs.minorid));
95e34ef7
TG
8170 dst_vbn = bfd_getl32 (eihs.dstvbn);
8171 dst_size = bfd_getl32 (eihs.dstsize);
695344c0 8172 /* xgettext:c-format */
44273c5b 8173 fprintf (file, _(" debug symbol table : vbn: %u, size: %u (0x%x)\n"),
07d6d2b8 8174 dst_vbn, dst_size, dst_size);
95e34ef7
TG
8175 gst_vbn = bfd_getl32 (eihs.gstvbn);
8176 gst_size = bfd_getl32 (eihs.gstsize);
695344c0 8177 /* xgettext:c-format */
95e34ef7 8178 fprintf (file, _(" global symbol table: vbn: %u, records: %u\n"),
07d6d2b8 8179 gst_vbn, gst_size);
95e34ef7
TG
8180 dmt_vbn = bfd_getl32 (eihs.dmtvbn);
8181 dmt_size = bfd_getl32 (eihs.dmtsize);
695344c0 8182 /* xgettext:c-format */
95e34ef7 8183 fprintf (file, _(" debug module table : vbn: %u, size: %u\n"),
07d6d2b8 8184 dmt_vbn, dmt_size);
95e34ef7
TG
8185 }
8186 while (eisd_off != 0)
8187 {
8188 struct vms_eisd eisd;
8189 unsigned int len;
8190
8191 while (1)
07d6d2b8
AM
8192 {
8193 if (bfd_seek (abfd, (file_ptr) eisd_off, SEEK_SET)
8194 || bfd_bread (&eisd, sizeof (eisd), abfd) != sizeof (eisd))
8195 {
8196 fprintf (file, _("cannot read EISD\n"));
8197 return;
8198 }
8199 len = (unsigned)bfd_getl32 (eisd.eisdsize);
8200 if (len != (unsigned)-1)
8201 break;
8202
8203 /* Next block. */
8204 eisd_off = (eisd_off + VMS_BLOCK_SIZE) & ~(VMS_BLOCK_SIZE - 1);
8205 }
695344c0 8206 /* xgettext:c-format */
95e34ef7 8207 fprintf (file, _("Image section descriptor: (major: %u, minor: %u, "
07d6d2b8
AM
8208 "size: %u, offset: %u)\n"),
8209 (unsigned)bfd_getl32 (eisd.majorid),
8210 (unsigned)bfd_getl32 (eisd.minorid),
8211 len, eisd_off);
95e34ef7 8212 if (len == 0)
07d6d2b8 8213 break;
695344c0 8214 /* xgettext:c-format */
95e34ef7 8215 fprintf (file, _(" section: base: 0x%08x%08x size: 0x%08x\n"),
07d6d2b8
AM
8216 (unsigned)bfd_getl32 (eisd.virt_addr + 4),
8217 (unsigned)bfd_getl32 (eisd.virt_addr + 0),
8218 (unsigned)bfd_getl32 (eisd.secsize));
95e34ef7
TG
8219 val = (unsigned)bfd_getl32 (eisd.flags);
8220 fprintf (file, _(" flags: 0x%04x"), val);
8221 if (val & EISD__M_GBL)
07d6d2b8 8222 fprintf (file, " GBL");
95e34ef7 8223 if (val & EISD__M_CRF)
07d6d2b8 8224 fprintf (file, " CRF");
95e34ef7 8225 if (val & EISD__M_DZRO)
07d6d2b8 8226 fprintf (file, " DZRO");
95e34ef7 8227 if (val & EISD__M_WRT)
07d6d2b8 8228 fprintf (file, " WRT");
95e34ef7
TG
8229 if (val & EISD__M_INITALCODE)
8230 fprintf (file, " INITALCODE");
8231 if (val & EISD__M_BASED)
07d6d2b8 8232 fprintf (file, " BASED");
95e34ef7
TG
8233 if (val & EISD__M_FIXUPVEC)
8234 fprintf (file, " FIXUPVEC");
8235 if (val & EISD__M_RESIDENT)
8236 fprintf (file, " RESIDENT");
8237 if (val & EISD__M_VECTOR)
07d6d2b8 8238 fprintf (file, " VECTOR");
95e34ef7
TG
8239 if (val & EISD__M_PROTECT)
8240 fprintf (file, " PROTECT");
8241 if (val & EISD__M_LASTCLU)
8242 fprintf (file, " LASTCLU");
8243 if (val & EISD__M_EXE)
07d6d2b8 8244 fprintf (file, " EXE");
95e34ef7
TG
8245 if (val & EISD__M_NONSHRADR)
8246 fprintf (file, " NONSHRADR");
8247 if (val & EISD__M_QUAD_LENGTH)
8248 fprintf (file, " QUAD_LENGTH");
8249 if (val & EISD__M_ALLOC_64BIT)
8250 fprintf (file, " ALLOC_64BIT");
8251 fprintf (file, "\n");
8252 if (val & EISD__M_FIXUPVEC)
07d6d2b8
AM
8253 {
8254 eiaf_vbn = bfd_getl32 (eisd.vbn);
8255 eiaf_size = bfd_getl32 (eisd.secsize);
8256 }
695344c0 8257 /* xgettext:c-format */
95e34ef7 8258 fprintf (file, _(" vbn: %u, pfc: %u, matchctl: %u type: %u ("),
07d6d2b8
AM
8259 (unsigned)bfd_getl32 (eisd.vbn),
8260 eisd.pfc, eisd.matchctl, eisd.type);
95e34ef7 8261 switch (eisd.type)
07d6d2b8
AM
8262 {
8263 case EISD__K_NORMAL:
8264 fputs (_("NORMAL"), file);
8265 break;
8266 case EISD__K_SHRFXD:
8267 fputs (_("SHRFXD"), file);
8268 break;
8269 case EISD__K_PRVFXD:
8270 fputs (_("PRVFXD"), file);
8271 break;
8272 case EISD__K_SHRPIC:
8273 fputs (_("SHRPIC"), file);
8274 break;
8275 case EISD__K_PRVPIC:
8276 fputs (_("PRVPIC"), file);
8277 break;
8278 case EISD__K_USRSTACK:
8279 fputs (_("USRSTACK"), file);
8280 break;
8281 default:
8282 fputs (_("*unknown*"), file);
8283 break;
8284 }
95e34ef7
TG
8285 fputs (_(")\n"), file);
8286 if (val & EISD__M_GBL)
695344c0 8287 /* xgettext:c-format */
07d6d2b8
AM
8288 fprintf (file, _(" ident: 0x%08x, name: %.*s\n"),
8289 (unsigned)bfd_getl32 (eisd.ident),
8290 eisd.gblnam[0], eisd.gblnam + 1);
95e34ef7
TG
8291 eisd_off += len;
8292 }
8293
8294 if (dmt_vbn != 0)
8295 {
8296 if (bfd_seek (abfd, (file_ptr) (dmt_vbn - 1) * VMS_BLOCK_SIZE, SEEK_SET))
07d6d2b8
AM
8297 {
8298 fprintf (file, _("cannot read DMT\n"));
8299 return;
8300 }
95e34ef7
TG
8301
8302 fprintf (file, _("Debug module table:\n"));
8303
8304 while (dmt_size > 0)
07d6d2b8
AM
8305 {
8306 struct vms_dmt_header dmth;
8307 unsigned int count;
8308
8309 if (bfd_bread (&dmth, sizeof (dmth), abfd) != sizeof (dmth))
8310 {
8311 fprintf (file, _("cannot read DMT header\n"));
8312 return;
8313 }
8314 count = bfd_getl16 (dmth.psect_count);
8315 fprintf (file,
695344c0 8316 /* xgettext:c-format */
07d6d2b8
AM
8317 _(" module offset: 0x%08x, size: 0x%08x, (%u psects)\n"),
8318 (unsigned)bfd_getl32 (dmth.modbeg),
8319 (unsigned)bfd_getl32 (dmth.size), count);
8320 dmt_size -= sizeof (dmth);
8321 while (count > 0)
8322 {
8323 struct vms_dmt_psect dmtp;
8324
8325 if (bfd_bread (&dmtp, sizeof (dmtp), abfd) != sizeof (dmtp))
8326 {
8327 fprintf (file, _("cannot read DMT psect\n"));
8328 return;
8329 }
695344c0 8330 /* xgettext:c-format */
07d6d2b8
AM
8331 fprintf (file, _(" psect start: 0x%08x, length: %u\n"),
8332 (unsigned)bfd_getl32 (dmtp.start),
8333 (unsigned)bfd_getl32 (dmtp.length));
8334 count--;
8335 dmt_size -= sizeof (dmtp);
8336 }
8337 }
95e34ef7
TG
8338 }
8339
8340 if (dst_vbn != 0)
8341 {
8342 if (bfd_seek (abfd, (file_ptr) (dst_vbn - 1) * VMS_BLOCK_SIZE, SEEK_SET))
07d6d2b8
AM
8343 {
8344 fprintf (file, _("cannot read DST\n"));
8345 return;
8346 }
95e34ef7
TG
8347
8348 evax_bfd_print_dst (abfd, dst_size, file);
8349 }
8350 if (gst_vbn != 0)
8351 {
8352 if (bfd_seek (abfd, (file_ptr) (gst_vbn - 1) * VMS_BLOCK_SIZE, SEEK_SET))
07d6d2b8
AM
8353 {
8354 fprintf (file, _("cannot read GST\n"));
8355 return;
8356 }
95e34ef7
TG
8357
8358 fprintf (file, _("Global symbol table:\n"));
8359 evax_bfd_print_eobj (abfd, file);
8360 }
b920bc37 8361 if (eiaf_vbn != 0 && eiaf_size >= sizeof (struct vms_eiaf))
95e34ef7
TG
8362 {
8363 unsigned char *buf;
8364 struct vms_eiaf *eiaf;
8365 unsigned int qrelfixoff;
8366 unsigned int lrelfixoff;
8367 unsigned int qdotadroff;
8368 unsigned int ldotadroff;
8369 unsigned int shrimgcnt;
8370 unsigned int shlstoff;
8371 unsigned int codeadroff;
8372 unsigned int lpfixoff;
8373 unsigned int chgprtoff;
2bb3687b 8374 file_ptr f_off = (file_ptr) (eiaf_vbn - 1) * VMS_BLOCK_SIZE;
95e34ef7 8375
2bb3687b
AM
8376 if (bfd_seek (abfd, f_off, SEEK_SET) != 0
8377 || (buf = _bfd_malloc_and_read (abfd, eiaf_size, eiaf_size)) == NULL)
07d6d2b8
AM
8378 {
8379 fprintf (file, _("cannot read EIHA\n"));
07d6d2b8
AM
8380 return;
8381 }
95e34ef7
TG
8382 eiaf = (struct vms_eiaf *)buf;
8383 fprintf (file,
695344c0 8384 /* xgettext:c-format */
07d6d2b8
AM
8385 _("Image activator fixup: (major: %u, minor: %u)\n"),
8386 (unsigned)bfd_getl32 (eiaf->majorid),
8387 (unsigned)bfd_getl32 (eiaf->minorid));
695344c0 8388 /* xgettext:c-format */
95e34ef7 8389 fprintf (file, _(" iaflink : 0x%08x %08x\n"),
07d6d2b8
AM
8390 (unsigned)bfd_getl32 (eiaf->iaflink + 0),
8391 (unsigned)bfd_getl32 (eiaf->iaflink + 4));
695344c0 8392 /* xgettext:c-format */
95e34ef7 8393 fprintf (file, _(" fixuplnk: 0x%08x %08x\n"),
07d6d2b8
AM
8394 (unsigned)bfd_getl32 (eiaf->fixuplnk + 0),
8395 (unsigned)bfd_getl32 (eiaf->fixuplnk + 4));
95e34ef7 8396 fprintf (file, _(" size : %u\n"),
07d6d2b8 8397 (unsigned)bfd_getl32 (eiaf->size));
95e34ef7 8398 fprintf (file, _(" flags: 0x%08x\n"),
07d6d2b8 8399 (unsigned)bfd_getl32 (eiaf->flags));
95e34ef7
TG
8400 qrelfixoff = bfd_getl32 (eiaf->qrelfixoff);
8401 lrelfixoff = bfd_getl32 (eiaf->lrelfixoff);
695344c0 8402 /* xgettext:c-format */
95e34ef7 8403 fprintf (file, _(" qrelfixoff: %5u, lrelfixoff: %5u\n"),
07d6d2b8 8404 qrelfixoff, lrelfixoff);
95e34ef7
TG
8405 qdotadroff = bfd_getl32 (eiaf->qdotadroff);
8406 ldotadroff = bfd_getl32 (eiaf->ldotadroff);
695344c0 8407 /* xgettext:c-format */
95e34ef7 8408 fprintf (file, _(" qdotadroff: %5u, ldotadroff: %5u\n"),
07d6d2b8 8409 qdotadroff, ldotadroff);
95e34ef7
TG
8410 codeadroff = bfd_getl32 (eiaf->codeadroff);
8411 lpfixoff = bfd_getl32 (eiaf->lpfixoff);
695344c0 8412 /* xgettext:c-format */
95e34ef7 8413 fprintf (file, _(" codeadroff: %5u, lpfixoff : %5u\n"),
07d6d2b8 8414 codeadroff, lpfixoff);
95e34ef7
TG
8415 chgprtoff = bfd_getl32 (eiaf->chgprtoff);
8416 fprintf (file, _(" chgprtoff : %5u\n"), chgprtoff);
8417 shrimgcnt = bfd_getl32 (eiaf->shrimgcnt);
8418 shlstoff = bfd_getl32 (eiaf->shlstoff);
695344c0 8419 /* xgettext:c-format */
95e34ef7 8420 fprintf (file, _(" shlstoff : %5u, shrimgcnt : %5u\n"),
07d6d2b8 8421 shlstoff, shrimgcnt);
695344c0 8422 /* xgettext:c-format */
95e34ef7 8423 fprintf (file, _(" shlextra : %5u, permctx : %5u\n"),
07d6d2b8
AM
8424 (unsigned)bfd_getl32 (eiaf->shlextra),
8425 (unsigned)bfd_getl32 (eiaf->permctx));
95e34ef7 8426 fprintf (file, _(" base_va : 0x%08x\n"),
07d6d2b8 8427 (unsigned)bfd_getl32 (eiaf->base_va));
95e34ef7 8428 fprintf (file, _(" lppsbfixoff: %5u\n"),
07d6d2b8 8429 (unsigned)bfd_getl32 (eiaf->lppsbfixoff));
95e34ef7
TG
8430
8431 if (shlstoff)
07d6d2b8 8432 {
07d6d2b8
AM
8433 unsigned int j;
8434
8435 fprintf (file, _(" Shareable images:\n"));
b920bc37
AM
8436 for (j = 0;
8437 j < shrimgcnt && shlstoff <= eiaf_size - sizeof (struct vms_shl);
8438 j++, shlstoff += sizeof (struct vms_shl))
07d6d2b8 8439 {
b920bc37 8440 struct vms_shl *shl = (struct vms_shl *) (buf + shlstoff);
07d6d2b8 8441 fprintf (file,
695344c0 8442 /* xgettext:c-format */
07d6d2b8
AM
8443 _(" %u: size: %u, flags: 0x%02x, name: %.*s\n"),
8444 j, shl->size, shl->flags,
8445 shl->imgnam[0], shl->imgnam + 1);
8446 }
8447 }
95e34ef7 8448 if (qrelfixoff != 0)
07d6d2b8
AM
8449 {
8450 fprintf (file, _(" quad-word relocation fixups:\n"));
b920bc37
AM
8451 evax_bfd_print_relocation_records (file, buf, eiaf_size,
8452 qrelfixoff, 8);
07d6d2b8 8453 }
95e34ef7 8454 if (lrelfixoff != 0)
07d6d2b8
AM
8455 {
8456 fprintf (file, _(" long-word relocation fixups:\n"));
b920bc37
AM
8457 evax_bfd_print_relocation_records (file, buf, eiaf_size,
8458 lrelfixoff, 4);
07d6d2b8 8459 }
95e34ef7 8460 if (qdotadroff != 0)
07d6d2b8
AM
8461 {
8462 fprintf (file, _(" quad-word .address reference fixups:\n"));
b920bc37 8463 evax_bfd_print_address_fixups (file, buf, eiaf_size, qdotadroff);
07d6d2b8 8464 }
95e34ef7 8465 if (ldotadroff != 0)
07d6d2b8
AM
8466 {
8467 fprintf (file, _(" long-word .address reference fixups:\n"));
b920bc37 8468 evax_bfd_print_address_fixups (file, buf, eiaf_size, ldotadroff);
07d6d2b8 8469 }
95e34ef7 8470 if (codeadroff != 0)
07d6d2b8
AM
8471 {
8472 fprintf (file, _(" Code Address Reference Fixups:\n"));
b920bc37 8473 evax_bfd_print_reference_fixups (file, buf, eiaf_size, codeadroff);
07d6d2b8 8474 }
95e34ef7 8475 if (lpfixoff != 0)
07d6d2b8
AM
8476 {
8477 fprintf (file, _(" Linkage Pairs Reference Fixups:\n"));
b920bc37 8478 evax_bfd_print_reference_fixups (file, buf, eiaf_size, lpfixoff);
07d6d2b8 8479 }
b920bc37 8480 if (chgprtoff && chgprtoff <= eiaf_size - 4)
07d6d2b8 8481 {
b920bc37 8482 unsigned int count = (unsigned) bfd_getl32 (buf + chgprtoff);
07d6d2b8
AM
8483 unsigned int j;
8484
8485 fprintf (file, _(" Change Protection (%u entries):\n"), count);
b920bc37
AM
8486 for (j = 0, chgprtoff += 4;
8487 j < count && chgprtoff <= eiaf_size - sizeof (struct vms_eicp);
8488 j++, chgprtoff += sizeof (struct vms_eicp))
07d6d2b8 8489 {
b920bc37 8490 struct vms_eicp *eicp = (struct vms_eicp *) (buf + chgprtoff);
07d6d2b8
AM
8491 unsigned int prot = bfd_getl32 (eicp->newprt);
8492 fprintf (file,
695344c0 8493 /* xgettext:c-format */
07d6d2b8 8494 _(" base: 0x%08x %08x, size: 0x%08x, prot: 0x%08x "),
b920bc37
AM
8495 (unsigned) bfd_getl32 (eicp->baseva + 4),
8496 (unsigned) bfd_getl32 (eicp->baseva + 0),
8497 (unsigned) bfd_getl32 (eicp->size),
8498 (unsigned) bfd_getl32 (eicp->newprt));
07d6d2b8
AM
8499 switch (prot)
8500 {
8501 case PRT__C_NA:
8502 fprintf (file, "NA");
8503 break;
8504 case PRT__C_RESERVED:
8505 fprintf (file, "RES");
8506 break;
8507 case PRT__C_KW:
8508 fprintf (file, "KW");
8509 break;
8510 case PRT__C_KR:
8511 fprintf (file, "KR");
8512 break;
8513 case PRT__C_UW:
8514 fprintf (file, "UW");
8515 break;
8516 case PRT__C_EW:
8517 fprintf (file, "EW");
8518 break;
8519 case PRT__C_ERKW:
8520 fprintf (file, "ERKW");
8521 break;
8522 case PRT__C_ER:
8523 fprintf (file, "ER");
8524 break;
8525 case PRT__C_SW:
8526 fprintf (file, "SW");
8527 break;
8528 case PRT__C_SREW:
8529 fprintf (file, "SREW");
8530 break;
8531 case PRT__C_SRKW:
8532 fprintf (file, "SRKW");
8533 break;
8534 case PRT__C_SR:
8535 fprintf (file, "SR");
8536 break;
8537 case PRT__C_URSW:
8538 fprintf (file, "URSW");
8539 break;
8540 case PRT__C_UREW:
8541 fprintf (file, "UREW");
8542 break;
8543 case PRT__C_URKW:
8544 fprintf (file, "URKW");
8545 break;
8546 case PRT__C_UR:
8547 fprintf (file, "UR");
8548 break;
8549 default:
8550 fputs ("??", file);
8551 break;
8552 }
8553 fputc ('\n', file);
8554 }
8555 }
95e34ef7
TG
8556 free (buf);
8557 }
8558}
8559
0a1b45a2 8560static bool
95e34ef7
TG
8561vms_bfd_print_private_bfd_data (bfd *abfd, void *ptr)
8562{
8563 FILE *file = (FILE *)ptr;
8564
8565 if (bfd_get_file_flags (abfd) & (EXEC_P | DYNAMIC))
8566 evax_bfd_print_image (abfd, file);
8567 else
8568 {
8569 if (bfd_seek (abfd, 0, SEEK_SET))
0a1b45a2 8570 return false;
95e34ef7
TG
8571 evax_bfd_print_eobj (abfd, file);
8572 }
0a1b45a2 8573 return true;
95e34ef7
TG
8574}
8575\f
8576/* Linking. */
8577
44273c5b 8578/* Slurp ETIR/EDBG/ETBT VMS object records. */
95e34ef7 8579
0a1b45a2 8580static bool
95e34ef7
TG
8581alpha_vms_read_sections_content (bfd *abfd, struct bfd_link_info *info)
8582{
8583 asection *cur_section;
8584 file_ptr cur_offset;
8585 asection *dst_section;
8586 file_ptr dst_offset;
8587
8588 if (bfd_seek (abfd, 0, SEEK_SET) != 0)
0a1b45a2 8589 return false;
95e34ef7 8590
95e34ef7
TG
8591 cur_section = NULL;
8592 cur_offset = 0;
8593
8594 dst_section = PRIV (dst_section);
8595 dst_offset = 0;
8596 if (info)
8597 {
8598 if (info->strip == strip_all || info->strip == strip_debugger)
07d6d2b8
AM
8599 {
8600 /* Discard the DST section. */
8601 dst_offset = 0;
8602 dst_section = NULL;
8603 }
95e34ef7 8604 else if (dst_section)
07d6d2b8
AM
8605 {
8606 dst_offset = dst_section->output_offset;
8607 dst_section = dst_section->output_section;
8608 }
95e34ef7
TG
8609 }
8610
8611 while (1)
8612 {
8613 int type;
0a1b45a2 8614 bool res;
95e34ef7
TG
8615
8616 type = _bfd_vms_get_object_record (abfd);
8617 if (type < 0)
8618 {
8619 vms_debug2 ((2, "next_record failed\n"));
0a1b45a2 8620 return false;
95e34ef7
TG
8621 }
8622 switch (type)
07d6d2b8
AM
8623 {
8624 case EOBJ__C_ETIR:
8625 PRIV (image_section) = cur_section;
8626 PRIV (image_offset) = cur_offset;
8627 res = _bfd_vms_slurp_etir (abfd, info);
8628 cur_section = PRIV (image_section);
8629 cur_offset = PRIV (image_offset);
8630 break;
8631 case EOBJ__C_EDBG:
8632 case EOBJ__C_ETBT:
8633 if (dst_section == NULL)
8634 continue;
8635 PRIV (image_section) = dst_section;
8636 PRIV (image_offset) = dst_offset;
8637 res = _bfd_vms_slurp_etir (abfd, info);
8638 dst_offset = PRIV (image_offset);
8639 break;
8640 case EOBJ__C_EEOM:
0a1b45a2 8641 return true;
07d6d2b8
AM
8642 default:
8643 continue;
8644 }
95e34ef7 8645 if (!res)
07d6d2b8
AM
8646 {
8647 vms_debug2 ((2, "slurp eobj type %d failed\n", type));
0a1b45a2 8648 return false;
07d6d2b8 8649 }
95e34ef7
TG
8650 }
8651}
8652
8653static int
8654alpha_vms_sizeof_headers (bfd *abfd ATTRIBUTE_UNUSED,
07d6d2b8 8655 struct bfd_link_info *info ATTRIBUTE_UNUSED)
95e34ef7
TG
8656{
8657 return 0;
8658}
8659
8660/* Add a linkage pair fixup at address SECT + OFFSET to SHLIB. */
8661
0a1b45a2 8662static bool
95e34ef7
TG
8663alpha_vms_add_fixup_lp (struct bfd_link_info *info, bfd *src, bfd *shlib)
8664{
8665 struct alpha_vms_shlib_el *sl;
8666 asection *sect = PRIV2 (src, image_section);
8667 file_ptr offset = PRIV2 (src, image_offset);
96d3b80f 8668 bfd_vma *p;
95e34ef7
TG
8669
8670 sl = &VEC_EL (alpha_vms_link_hash (info)->shrlibs,
07d6d2b8 8671 struct alpha_vms_shlib_el, PRIV2 (shlib, shr_index));
0a1b45a2 8672 sl->has_fixups = true;
96d3b80f
AM
8673 p = VEC_APPEND (sl->lp, bfd_vma);
8674 if (p == NULL)
0a1b45a2 8675 return false;
96d3b80f 8676 *p = sect->output_section->vma + sect->output_offset + offset;
5f101a3d 8677 sect->output_section->flags |= SEC_RELOC;
0a1b45a2 8678 return true;
95e34ef7
TG
8679}
8680
5f101a3d
TG
8681/* Add a code address fixup at address SECT + OFFSET to SHLIB. */
8682
0a1b45a2 8683static bool
95e34ef7
TG
8684alpha_vms_add_fixup_ca (struct bfd_link_info *info, bfd *src, bfd *shlib)
8685{
8686 struct alpha_vms_shlib_el *sl;
8687 asection *sect = PRIV2 (src, image_section);
8688 file_ptr offset = PRIV2 (src, image_offset);
96d3b80f 8689 bfd_vma *p;
95e34ef7
TG
8690
8691 sl = &VEC_EL (alpha_vms_link_hash (info)->shrlibs,
07d6d2b8 8692 struct alpha_vms_shlib_el, PRIV2 (shlib, shr_index));
0a1b45a2 8693 sl->has_fixups = true;
96d3b80f
AM
8694 p = VEC_APPEND (sl->ca, bfd_vma);
8695 if (p == NULL)
0a1b45a2 8696 return false;
96d3b80f 8697 *p = sect->output_section->vma + sect->output_offset + offset;
5f101a3d 8698 sect->output_section->flags |= SEC_RELOC;
0a1b45a2 8699 return true;
95e34ef7
TG
8700}
8701
5f101a3d
TG
8702/* Add a quad word relocation fixup at address SECT + OFFSET to SHLIB. */
8703
0a1b45a2 8704static bool
95e34ef7 8705alpha_vms_add_fixup_qr (struct bfd_link_info *info, bfd *src,
07d6d2b8 8706 bfd *shlib, bfd_vma vec)
95e34ef7
TG
8707{
8708 struct alpha_vms_shlib_el *sl;
8709 struct alpha_vms_vma_ref *r;
8710 asection *sect = PRIV2 (src, image_section);
8711 file_ptr offset = PRIV2 (src, image_offset);
8712
8713 sl = &VEC_EL (alpha_vms_link_hash (info)->shrlibs,
07d6d2b8 8714 struct alpha_vms_shlib_el, PRIV2 (shlib, shr_index));
0a1b45a2 8715 sl->has_fixups = true;
95e34ef7 8716 r = VEC_APPEND (sl->qr, struct alpha_vms_vma_ref);
96d3b80f 8717 if (r == NULL)
0a1b45a2 8718 return false;
95e34ef7
TG
8719 r->vma = sect->output_section->vma + sect->output_offset + offset;
8720 r->ref = vec;
5f101a3d 8721 sect->output_section->flags |= SEC_RELOC;
0a1b45a2 8722 return true;
95e34ef7
TG
8723}
8724
0a1b45a2 8725static bool
5369db0a 8726alpha_vms_add_fixup_lr (struct bfd_link_info *info ATTRIBUTE_UNUSED,
07d6d2b8
AM
8727 unsigned int shr ATTRIBUTE_UNUSED,
8728 bfd_vma vec ATTRIBUTE_UNUSED)
95e34ef7 8729{
5f101a3d 8730 /* Not yet supported. */
0a1b45a2 8731 return false;
95e34ef7
TG
8732}
8733
5369db0a 8734/* Add relocation. FIXME: Not yet emitted. */
95e34ef7 8735
0a1b45a2 8736static bool
95e34ef7
TG
8737alpha_vms_add_lw_reloc (struct bfd_link_info *info ATTRIBUTE_UNUSED)
8738{
0a1b45a2 8739 return false;
95e34ef7
TG
8740}
8741
0a1b45a2 8742static bool
95e34ef7
TG
8743alpha_vms_add_qw_reloc (struct bfd_link_info *info ATTRIBUTE_UNUSED)
8744{
0a1b45a2 8745 return false;
95e34ef7
TG
8746}
8747
8748static struct bfd_hash_entry *
8749alpha_vms_link_hash_newfunc (struct bfd_hash_entry *entry,
07d6d2b8
AM
8750 struct bfd_hash_table *table,
8751 const char *string)
95e34ef7
TG
8752{
8753 struct alpha_vms_link_hash_entry *ret =
8754 (struct alpha_vms_link_hash_entry *) entry;
8755
8756 /* Allocate the structure if it has not already been allocated by a
8757 subclass. */
8758 if (ret == NULL)
8759 ret = ((struct alpha_vms_link_hash_entry *)
8760 bfd_hash_allocate (table,
07d6d2b8 8761 sizeof (struct alpha_vms_link_hash_entry)));
95e34ef7
TG
8762 if (ret == NULL)
8763 return NULL;
8764
8765 /* Call the allocation method of the superclass. */
8766 ret = ((struct alpha_vms_link_hash_entry *)
8767 _bfd_link_hash_newfunc ((struct bfd_hash_entry *) ret,
8768 table, string));
8769
8770 ret->sym = NULL;
8771
8772 return (struct bfd_hash_entry *) ret;
8773}
8774
37d2e9c7
AM
8775static void
8776alpha_vms_bfd_link_hash_table_free (bfd *abfd)
8777{
8778 struct alpha_vms_link_hash_table *t;
8779 unsigned i;
8780
8781 t = (struct alpha_vms_link_hash_table *) abfd->link.hash;
8782 for (i = 0; i < VEC_COUNT (t->shrlibs); i++)
8783 {
8784 struct alpha_vms_shlib_el *shlib;
8785
8786 shlib = &VEC_EL (t->shrlibs, struct alpha_vms_shlib_el, i);
8787 free (&VEC_EL (shlib->ca, bfd_vma, 0));
8788 free (&VEC_EL (shlib->lp, bfd_vma, 0));
8789 free (&VEC_EL (shlib->qr, struct alpha_vms_vma_ref, 0));
8790 }
8791 free (&VEC_EL (t->shrlibs, struct alpha_vms_shlib_el, 0));
8792
8793 _bfd_generic_link_hash_table_free (abfd);
8794}
8795
95e34ef7
TG
8796/* Create an Alpha/VMS link hash table. */
8797
8798static struct bfd_link_hash_table *
8799alpha_vms_bfd_link_hash_table_create (bfd *abfd)
8800{
8801 struct alpha_vms_link_hash_table *ret;
986f0783 8802 size_t amt = sizeof (struct alpha_vms_link_hash_table);
95e34ef7
TG
8803
8804 ret = (struct alpha_vms_link_hash_table *) bfd_malloc (amt);
8805 if (ret == NULL)
8806 return NULL;
8807 if (!_bfd_link_hash_table_init (&ret->root, abfd,
8808 alpha_vms_link_hash_newfunc,
8809 sizeof (struct alpha_vms_link_hash_entry)))
8810 {
8811 free (ret);
8812 return NULL;
8813 }
8814
8815 VEC_INIT (ret->shrlibs);
8816 ret->fixup = NULL;
37d2e9c7 8817 ret->root.hash_table_free = alpha_vms_bfd_link_hash_table_free;
95e34ef7
TG
8818
8819 return &ret->root;
8820}
8821
0a1b45a2 8822static bool
95e34ef7
TG
8823alpha_vms_link_add_object_symbols (bfd *abfd, struct bfd_link_info *info)
8824{
8825 unsigned int i;
8826
8827 for (i = 0; i < PRIV (gsd_sym_count); i++)
8828 {
8829 struct vms_symbol_entry *e = PRIV (syms)[i];
8830 struct alpha_vms_link_hash_entry *h;
11afaeda 8831 struct bfd_link_hash_entry *h_root;
95e34ef7
TG
8832 asymbol sym;
8833
8834 if (!alpha_vms_convert_symbol (abfd, e, &sym))
0a1b45a2 8835 return false;
95e34ef7
TG
8836
8837 if ((e->flags & EGSY__V_DEF) && abfd->selective_search)
07d6d2b8
AM
8838 {
8839 /* In selective_search mode, only add definition that are
8840 required. */
8841 h = (struct alpha_vms_link_hash_entry *)bfd_link_hash_lookup
0a1b45a2 8842 (info->hash, sym.name, false, false, false);
07d6d2b8
AM
8843 if (h == NULL || h->root.type != bfd_link_hash_undefined)
8844 continue;
8845 }
95e34ef7 8846 else
07d6d2b8 8847 h = NULL;
95e34ef7 8848
11afaeda 8849 h_root = (struct bfd_link_hash_entry *) h;
535b785f
AM
8850 if (!_bfd_generic_link_add_one_symbol (info, abfd, sym.name, sym.flags,
8851 sym.section, sym.value, NULL,
0a1b45a2
AM
8852 false, false, &h_root))
8853 return false;
11afaeda 8854 h = (struct alpha_vms_link_hash_entry *) h_root;
95e34ef7
TG
8855
8856 if ((e->flags & EGSY__V_DEF)
07d6d2b8
AM
8857 && h->sym == NULL
8858 && abfd->xvec == info->output_bfd->xvec)
8859 h->sym = e;
95e34ef7
TG
8860 }
8861
8862 if (abfd->flags & DYNAMIC)
8863 {
8864 struct alpha_vms_shlib_el *shlib;
8865
8866 /* We do not want to include any of the sections in a dynamic
07d6d2b8 8867 object in the output file. See comment in elflink.c. */
95e34ef7
TG
8868 bfd_section_list_clear (abfd);
8869
8870 shlib = VEC_APPEND (alpha_vms_link_hash (info)->shrlibs,
07d6d2b8 8871 struct alpha_vms_shlib_el);
96d3b80f 8872 if (shlib == NULL)
0a1b45a2 8873 return false;
95e34ef7
TG
8874 shlib->abfd = abfd;
8875 VEC_INIT (shlib->ca);
8876 VEC_INIT (shlib->lp);
8877 VEC_INIT (shlib->qr);
8878 PRIV (shr_index) = VEC_COUNT (alpha_vms_link_hash (info)->shrlibs) - 1;
8879 }
8880
0a1b45a2 8881 return true;
95e34ef7
TG
8882}
8883
0a1b45a2 8884static bool
95e34ef7
TG
8885alpha_vms_link_add_archive_symbols (bfd *abfd, struct bfd_link_info *info)
8886{
8887 int pass;
8888 struct bfd_link_hash_entry **pundef;
8889 struct bfd_link_hash_entry **next_pundef;
8890
8891 /* We only accept VMS libraries. */
8892 if (info->output_bfd->xvec != abfd->xvec)
8893 {
8894 bfd_set_error (bfd_error_wrong_format);
0a1b45a2 8895 return false;
95e34ef7
TG
8896 }
8897
8898 /* The archive_pass field in the archive itself is used to
8899 initialize PASS, since we may search the same archive multiple
8900 times. */
8901 pass = ++abfd->archive_pass;
8902
8903 /* Look through the list of undefined symbols. */
8904 for (pundef = &info->hash->undefs; *pundef != NULL; pundef = next_pundef)
8905 {
8906 struct bfd_link_hash_entry *h;
8e57e1d1 8907 symindex symidx;
95e34ef7
TG
8908 bfd *element;
8909 bfd *orig_element;
8910
8911 h = *pundef;
8912 next_pundef = &(*pundef)->u.undef.next;
8913
8914 /* When a symbol is defined, it is not necessarily removed from
8915 the list. */
8916 if (h->type != bfd_link_hash_undefined
8917 && h->type != bfd_link_hash_common)
8918 {
8919 /* Remove this entry from the list, for general cleanliness
8920 and because we are going to look through the list again
8921 if we search any more libraries. We can't remove the
8922 entry if it is the tail, because that would lose any
8923 entries we add to the list later on. */
8924 if (*pundef != info->hash->undefs_tail)
07d6d2b8
AM
8925 {
8926 *pundef = *next_pundef;
8927 next_pundef = pundef;
8928 }
95e34ef7
TG
8929 continue;
8930 }
8931
8932 /* Look for this symbol in the archive hash table. */
8e57e1d1
TG
8933 symidx = _bfd_vms_lib_find_symbol (abfd, h->root.string);
8934 if (symidx == BFD_NO_MORE_SYMBOLS)
95e34ef7
TG
8935 {
8936 /* Nothing in this slot. */
8937 continue;
8938 }
8939
8e57e1d1 8940 element = bfd_get_elt_at_index (abfd, symidx);
95e34ef7 8941 if (element == NULL)
0a1b45a2 8942 return false;
95e34ef7
TG
8943
8944 if (element->archive_pass == -1 || element->archive_pass == pass)
07d6d2b8
AM
8945 {
8946 /* Next symbol if this archive is wrong or already handled. */
8947 continue;
8948 }
95e34ef7
TG
8949
8950 if (! bfd_check_format (element, bfd_object))
07d6d2b8
AM
8951 {
8952 element->archive_pass = -1;
0a1b45a2 8953 return false;
07d6d2b8 8954 }
95e34ef7
TG
8955
8956 orig_element = element;
8957 if (bfd_is_thin_archive (abfd))
07d6d2b8
AM
8958 {
8959 element = _bfd_vms_lib_get_imagelib_file (element);
8960 if (element == NULL || !bfd_check_format (element, bfd_object))
8961 {
8962 orig_element->archive_pass = -1;
0a1b45a2 8963 return false;
07d6d2b8
AM
8964 }
8965 }
95e34ef7
TG
8966
8967 /* Unlike the generic linker, we know that this element provides
8968 a definition for an undefined symbol and we know that we want
8969 to include it. We don't need to check anything. */
0e144ba7
AM
8970 if (!(*info->callbacks
8971 ->add_archive_element) (info, element, h->root.string, &element))
b95a0a31 8972 continue;
0e144ba7 8973 if (!alpha_vms_link_add_object_symbols (element, info))
0a1b45a2 8974 return false;
95e34ef7
TG
8975
8976 orig_element->archive_pass = pass;
8977 }
8978
0a1b45a2 8979 return true;
95e34ef7
TG
8980}
8981
0a1b45a2 8982static bool
95e34ef7
TG
8983alpha_vms_bfd_link_add_symbols (bfd *abfd, struct bfd_link_info *info)
8984{
8985 switch (bfd_get_format (abfd))
8986 {
8987 case bfd_object:
8988 vms_debug2 ((2, "vms_link_add_symbols for object %s\n",
07d6d2b8 8989 abfd->filename));
95e34ef7
TG
8990 return alpha_vms_link_add_object_symbols (abfd, info);
8991 break;
8992 case bfd_archive:
8993 vms_debug2 ((2, "vms_link_add_symbols for archive %s\n",
07d6d2b8 8994 abfd->filename));
95e34ef7
TG
8995 return alpha_vms_link_add_archive_symbols (abfd, info);
8996 break;
8997 default:
8998 bfd_set_error (bfd_error_wrong_format);
0a1b45a2 8999 return false;
95e34ef7
TG
9000 }
9001}
9002
0a1b45a2 9003static bool
95e34ef7
TG
9004alpha_vms_build_fixups (struct bfd_link_info *info)
9005{
9006 struct alpha_vms_link_hash_table *t = alpha_vms_link_hash (info);
9007 unsigned char *content;
9008 unsigned int i;
9009 unsigned int sz = 0;
9010 unsigned int lp_sz = 0;
9011 unsigned int ca_sz = 0;
9012 unsigned int qr_sz = 0;
9013 unsigned int shrimg_cnt = 0;
79326a5a
TG
9014 unsigned int chgprt_num = 0;
9015 unsigned int chgprt_sz = 0;
95e34ef7
TG
9016 struct vms_eiaf *eiaf;
9017 unsigned int off;
9018 asection *sec;
9019
9020 /* Shared libraries. */
9021 for (i = 0; i < VEC_COUNT (t->shrlibs); i++)
9022 {
9023 struct alpha_vms_shlib_el *shlib;
9024
9025 shlib = &VEC_EL (t->shrlibs, struct alpha_vms_shlib_el, i);
9026
9027 if (!shlib->has_fixups)
07d6d2b8 9028 continue;
95e34ef7
TG
9029
9030 shrimg_cnt++;
9031
9032 if (VEC_COUNT (shlib->ca) > 0)
07d6d2b8
AM
9033 {
9034 /* Header + entries. */
9035 ca_sz += 8;
9036 ca_sz += VEC_COUNT (shlib->ca) * 4;
9037 }
95e34ef7 9038 if (VEC_COUNT (shlib->lp) > 0)
07d6d2b8
AM
9039 {
9040 /* Header + entries. */
9041 lp_sz += 8;
9042 lp_sz += VEC_COUNT (shlib->lp) * 4;
9043 }
95e34ef7 9044 if (VEC_COUNT (shlib->qr) > 0)
07d6d2b8
AM
9045 {
9046 /* Header + entries. */
9047 qr_sz += 8;
9048 qr_sz += VEC_COUNT (shlib->qr) * 8;
9049 }
95e34ef7
TG
9050 }
9051 /* Add markers. */
9052 if (ca_sz > 0)
9053 ca_sz += 8;
9054 if (lp_sz > 0)
9055 lp_sz += 8;
9056 if (qr_sz > 0)
9057 qr_sz += 8;
9058
9059 /* Finish now if there is no content. */
9060 if (ca_sz + lp_sz + qr_sz == 0)
0a1b45a2 9061 return true;
95e34ef7 9062
79326a5a
TG
9063 /* Add an eicp entry for the fixup itself. */
9064 chgprt_num = 1;
9065 for (sec = info->output_bfd->sections; sec != NULL; sec = sec->next)
9066 {
9067 /* This isect could be made RO or EXE after relocations are applied. */
9068 if ((sec->flags & SEC_RELOC) != 0
07d6d2b8
AM
9069 && (sec->flags & (SEC_CODE | SEC_READONLY)) != 0)
9070 chgprt_num++;
79326a5a
TG
9071 }
9072 chgprt_sz = 4 + chgprt_num * sizeof (struct vms_eicp);
9073
95e34ef7
TG
9074 /* Allocate section content (round-up size) */
9075 sz = sizeof (struct vms_eiaf) + shrimg_cnt * sizeof (struct vms_shl)
79326a5a 9076 + ca_sz + lp_sz + qr_sz + chgprt_sz;
95e34ef7
TG
9077 sz = (sz + VMS_BLOCK_SIZE - 1) & ~(VMS_BLOCK_SIZE - 1);
9078 content = bfd_zalloc (info->output_bfd, sz);
9079 if (content == NULL)
0a1b45a2 9080 return false;
95e34ef7
TG
9081
9082 sec = alpha_vms_link_hash (info)->fixup;
9083 sec->contents = content;
9084 sec->size = sz;
9085
9086 eiaf = (struct vms_eiaf *)content;
9087 off = sizeof (struct vms_eiaf);
9088 bfd_putl32 (0, eiaf->majorid);
9089 bfd_putl32 (0, eiaf->minorid);
9090 bfd_putl32 (0, eiaf->iaflink);
9091 bfd_putl32 (0, eiaf->fixuplnk);
9092 bfd_putl32 (sizeof (struct vms_eiaf), eiaf->size);
9093 bfd_putl32 (0, eiaf->flags);
9094 bfd_putl32 (0, eiaf->qrelfixoff);
9095 bfd_putl32 (0, eiaf->lrelfixoff);
9096 bfd_putl32 (0, eiaf->qdotadroff);
9097 bfd_putl32 (0, eiaf->ldotadroff);
9098 bfd_putl32 (0, eiaf->codeadroff);
9099 bfd_putl32 (0, eiaf->lpfixoff);
9100 bfd_putl32 (0, eiaf->chgprtoff);
9101 bfd_putl32 (shrimg_cnt ? off : 0, eiaf->shlstoff);
9102 bfd_putl32 (shrimg_cnt, eiaf->shrimgcnt);
9103 bfd_putl32 (0, eiaf->shlextra);
9104 bfd_putl32 (0, eiaf->permctx);
9105 bfd_putl32 (0, eiaf->base_va);
9106 bfd_putl32 (0, eiaf->lppsbfixoff);
9107
9108 if (shrimg_cnt)
9109 {
9110 shrimg_cnt = 0;
9111
9112 /* Write shl. */
9113 for (i = 0; i < VEC_COUNT (t->shrlibs); i++)
07d6d2b8
AM
9114 {
9115 struct alpha_vms_shlib_el *shlib;
9116 struct vms_shl *shl;
9117
9118 shlib = &VEC_EL (t->shrlibs, struct alpha_vms_shlib_el, i);
9119
9120 if (!shlib->has_fixups)
9121 continue;
9122
9123 /* Renumber shared images. */
9124 PRIV2 (shlib->abfd, shr_index) = shrimg_cnt++;
9125
9126 shl = (struct vms_shl *)(content + off);
9127 bfd_putl32 (0, shl->baseva);
9128 bfd_putl32 (0, shl->shlptr);
9129 bfd_putl32 (0, shl->ident);
9130 bfd_putl32 (0, shl->permctx);
9131 shl->size = sizeof (struct vms_shl);
9132 bfd_putl16 (0, shl->fill_1);
9133 shl->flags = 0;
9134 bfd_putl32 (0, shl->icb);
9135 shl->imgnam[0] = strlen (PRIV2 (shlib->abfd, hdr_data.hdr_t_name));
9136 memcpy (shl->imgnam + 1, PRIV2 (shlib->abfd, hdr_data.hdr_t_name),
9137 shl->imgnam[0]);
9138
9139 off += sizeof (struct vms_shl);
9140 }
95e34ef7
TG
9141
9142 /* CA fixups. */
9143 if (ca_sz != 0)
07d6d2b8
AM
9144 {
9145 bfd_putl32 (off, eiaf->codeadroff);
95e34ef7 9146
07d6d2b8
AM
9147 for (i = 0; i < VEC_COUNT (t->shrlibs); i++)
9148 {
9149 struct alpha_vms_shlib_el *shlib;
9150 unsigned int j;
95e34ef7 9151
07d6d2b8 9152 shlib = &VEC_EL (t->shrlibs, struct alpha_vms_shlib_el, i);
95e34ef7 9153
07d6d2b8
AM
9154 if (VEC_COUNT (shlib->ca) == 0)
9155 continue;
95e34ef7 9156
07d6d2b8
AM
9157 bfd_putl32 (VEC_COUNT (shlib->ca), content + off);
9158 bfd_putl32 (PRIV2 (shlib->abfd, shr_index), content + off + 4);
9159 off += 8;
95e34ef7 9160
07d6d2b8
AM
9161 for (j = 0; j < VEC_COUNT (shlib->ca); j++)
9162 {
9163 bfd_putl32 (VEC_EL (shlib->ca, bfd_vma, j) - t->base_addr,
9164 content + off);
9165 off += 4;
9166 }
9167 }
95e34ef7 9168
07d6d2b8
AM
9169 bfd_putl32 (0, content + off);
9170 bfd_putl32 (0, content + off + 4);
9171 off += 8;
9172 }
95e34ef7
TG
9173
9174 /* LP fixups. */
9175 if (lp_sz != 0)
07d6d2b8
AM
9176 {
9177 bfd_putl32 (off, eiaf->lpfixoff);
95e34ef7 9178
07d6d2b8
AM
9179 for (i = 0; i < VEC_COUNT (t->shrlibs); i++)
9180 {
9181 struct alpha_vms_shlib_el *shlib;
9182 unsigned int j;
95e34ef7 9183
07d6d2b8 9184 shlib = &VEC_EL (t->shrlibs, struct alpha_vms_shlib_el, i);
95e34ef7 9185
07d6d2b8
AM
9186 if (VEC_COUNT (shlib->lp) == 0)
9187 continue;
95e34ef7 9188
07d6d2b8
AM
9189 bfd_putl32 (VEC_COUNT (shlib->lp), content + off);
9190 bfd_putl32 (PRIV2 (shlib->abfd, shr_index), content + off + 4);
9191 off += 8;
95e34ef7 9192
07d6d2b8
AM
9193 for (j = 0; j < VEC_COUNT (shlib->lp); j++)
9194 {
9195 bfd_putl32 (VEC_EL (shlib->lp, bfd_vma, j) - t->base_addr,
9196 content + off);
9197 off += 4;
9198 }
9199 }
95e34ef7 9200
07d6d2b8
AM
9201 bfd_putl32 (0, content + off);
9202 bfd_putl32 (0, content + off + 4);
9203 off += 8;
9204 }
95e34ef7
TG
9205
9206 /* QR fixups. */
9207 if (qr_sz != 0)
07d6d2b8
AM
9208 {
9209 bfd_putl32 (off, eiaf->qdotadroff);
95e34ef7 9210
07d6d2b8
AM
9211 for (i = 0; i < VEC_COUNT (t->shrlibs); i++)
9212 {
9213 struct alpha_vms_shlib_el *shlib;
9214 unsigned int j;
95e34ef7 9215
07d6d2b8 9216 shlib = &VEC_EL (t->shrlibs, struct alpha_vms_shlib_el, i);
95e34ef7 9217
07d6d2b8
AM
9218 if (VEC_COUNT (shlib->qr) == 0)
9219 continue;
95e34ef7 9220
07d6d2b8
AM
9221 bfd_putl32 (VEC_COUNT (shlib->qr), content + off);
9222 bfd_putl32 (PRIV2 (shlib->abfd, shr_index), content + off + 4);
9223 off += 8;
95e34ef7 9224
07d6d2b8
AM
9225 for (j = 0; j < VEC_COUNT (shlib->qr); j++)
9226 {
9227 struct alpha_vms_vma_ref *r;
9228 r = &VEC_EL (shlib->qr, struct alpha_vms_vma_ref, j);
9229 bfd_putl32 (r->vma - t->base_addr, content + off);
9230 bfd_putl32 (r->ref, content + off + 4);
9231 off += 8;
9232 }
9233 }
95e34ef7 9234
07d6d2b8
AM
9235 bfd_putl32 (0, content + off);
9236 bfd_putl32 (0, content + off + 4);
9237 off += 8;
9238 }
95e34ef7
TG
9239 }
9240
79326a5a
TG
9241 /* Write the change protection table. */
9242 bfd_putl32 (off, eiaf->chgprtoff);
9243 bfd_putl32 (chgprt_num, content + off);
9244 off += 4;
9245
9246 for (sec = info->output_bfd->sections; sec != NULL; sec = sec->next)
9247 {
9248 struct vms_eicp *eicp;
9249 unsigned int prot;
9250
9251 if ((sec->flags & SEC_LINKER_CREATED) != 0 &&
07d6d2b8
AM
9252 strcmp (sec->name, "$FIXUP$") == 0)
9253 prot = PRT__C_UREW;
79326a5a 9254 else if ((sec->flags & SEC_RELOC) != 0
07d6d2b8
AM
9255 && (sec->flags & (SEC_CODE | SEC_READONLY)) != 0)
9256 prot = PRT__C_UR;
79326a5a 9257 else
07d6d2b8 9258 continue;
79326a5a
TG
9259
9260 eicp = (struct vms_eicp *)(content + off);
9261 bfd_putl64 (sec->vma - t->base_addr, eicp->baseva);
9262 bfd_putl32 ((sec->size + VMS_BLOCK_SIZE - 1) & ~(VMS_BLOCK_SIZE - 1),
07d6d2b8 9263 eicp->size);
79326a5a
TG
9264 bfd_putl32 (prot, eicp->newprt);
9265 off += sizeof (struct vms_eicp);
9266 }
9267
0a1b45a2 9268 return true;
95e34ef7
TG
9269}
9270
7686d77d 9271/* Called by bfd_hash_traverse to fill the symbol table.
f9eeb9c9
TG
9272 Return FALSE in case of failure. */
9273
0a1b45a2 9274static bool
7686d77d 9275alpha_vms_link_output_symbol (struct bfd_hash_entry *bh, void *infov)
f9eeb9c9 9276{
7686d77d 9277 struct bfd_link_hash_entry *hc = (struct bfd_link_hash_entry *) bh;
f9eeb9c9 9278 struct bfd_link_info *info = (struct bfd_link_info *)infov;
7686d77d 9279 struct alpha_vms_link_hash_entry *h;
f9eeb9c9
TG
9280 struct vms_symbol_entry *sym;
9281
7686d77d
AM
9282 if (hc->type == bfd_link_hash_warning)
9283 {
9284 hc = hc->u.i.link;
9285 if (hc->type == bfd_link_hash_new)
0a1b45a2 9286 return true;
7686d77d
AM
9287 }
9288 h = (struct alpha_vms_link_hash_entry *) hc;
9289
f9eeb9c9
TG
9290 switch (h->root.type)
9291 {
f9eeb9c9 9292 case bfd_link_hash_undefined:
0a1b45a2 9293 return true;
8185f55c 9294 case bfd_link_hash_new:
7686d77d 9295 case bfd_link_hash_warning:
f9eeb9c9
TG
9296 abort ();
9297 case bfd_link_hash_undefweak:
0a1b45a2 9298 return true;
f9eeb9c9
TG
9299 case bfd_link_hash_defined:
9300 case bfd_link_hash_defweak:
9301 {
07d6d2b8 9302 asection *sec = h->root.u.def.section;
f9eeb9c9 9303
07d6d2b8
AM
9304 /* FIXME: this is certainly a symbol from a dynamic library. */
9305 if (bfd_is_abs_section (sec))
0a1b45a2 9306 return true;
f9eeb9c9 9307
07d6d2b8 9308 if (sec->owner->flags & DYNAMIC)
0a1b45a2 9309 return true;
f9eeb9c9
TG
9310 }
9311 break;
9312 case bfd_link_hash_common:
9313 break;
9314 case bfd_link_hash_indirect:
0a1b45a2 9315 return true;
f9eeb9c9
TG
9316 }
9317
9318 /* Do not write not kept symbols. */
9319 if (info->strip == strip_some
9320 && bfd_hash_lookup (info->keep_hash, h->root.root.string,
0a1b45a2
AM
9321 false, false) != NULL)
9322 return true;
f9eeb9c9
TG
9323
9324 if (h->sym == NULL)
9325 {
9326 /* This symbol doesn't come from a VMS object. So we suppose it is
07d6d2b8 9327 a data. */
f9eeb9c9
TG
9328 int len = strlen (h->root.root.string);
9329
9330 sym = (struct vms_symbol_entry *)bfd_zalloc (info->output_bfd,
07d6d2b8 9331 sizeof (*sym) + len);
f9eeb9c9 9332 if (sym == NULL)
07d6d2b8 9333 abort ();
f9eeb9c9
TG
9334 sym->namelen = len;
9335 memcpy (sym->name, h->root.root.string, len);
9336 sym->name[len] = 0;
9337 sym->owner = info->output_bfd;
9338
9339 sym->typ = EGSD__C_SYMG;
9340 sym->data_type = 0;
9341 sym->flags = EGSY__V_DEF | EGSY__V_REL;
9342 sym->symbol_vector = h->root.u.def.value;
9343 sym->section = h->root.u.def.section;
9344 sym->value = h->root.u.def.value;
9345 }
9346 else
9347 sym = h->sym;
9348
9349 if (!add_symbol_entry (info->output_bfd, sym))
0a1b45a2 9350 return false;
f9eeb9c9 9351
0a1b45a2 9352 return true;
f9eeb9c9
TG
9353}
9354
0a1b45a2 9355static bool
95e34ef7
TG
9356alpha_vms_bfd_final_link (bfd *abfd, struct bfd_link_info *info)
9357{
9358 asection *o;
9359 struct bfd_link_order *p;
9360 bfd *sub;
9361 asection *fixupsec;
9362 bfd_vma base_addr;
9363 bfd_vma last_addr;
44273c5b 9364 asection *dst;
fa23f0f4 9365 asection *dmt;
95e34ef7 9366
0e1862bb 9367 if (bfd_link_relocatable (info))
79326a5a
TG
9368 {
9369 /* FIXME: we do not yet support relocatable link. It is not obvious
07d6d2b8 9370 how to do it for debug infos. */
79326a5a 9371 (*info->callbacks->einfo)(_("%P: relocatable link is not supported\n"));
0a1b45a2 9372 return false;
79326a5a
TG
9373 }
9374
ed48ec2e
AM
9375 abfd->outsymbols = NULL;
9376 abfd->symcount = 0;
95e34ef7
TG
9377
9378 /* Mark all sections which will be included in the output file. */
9379 for (o = abfd->sections; o != NULL; o = o->next)
9380 for (p = o->map_head.link_order; p != NULL; p = p->next)
9381 if (p->type == bfd_indirect_link_order)
0a1b45a2 9382 p->u.indirect.section->linker_mark = true;
95e34ef7
TG
9383
9384#if 0
9385 /* Handle all the link order information for the sections. */
9386 for (o = abfd->sections; o != NULL; o = o->next)
9387 {
9388 printf ("For section %s (at 0x%08x, flags=0x%08x):\n",
07d6d2b8 9389 o->name, (unsigned)o->vma, (unsigned)o->flags);
95e34ef7
TG
9390
9391 for (p = o->map_head.link_order; p != NULL; p = p->next)
9392 {
07d6d2b8
AM
9393 printf (" at 0x%08x - 0x%08x: ",
9394 (unsigned)p->offset, (unsigned)(p->offset + p->size - 1));
95e34ef7
TG
9395 switch (p->type)
9396 {
9397 case bfd_section_reloc_link_order:
9398 case bfd_symbol_reloc_link_order:
07d6d2b8 9399 printf (" section/symbol reloc\n");
95e34ef7
TG
9400 break;
9401 case bfd_indirect_link_order:
07d6d2b8
AM
9402 printf (" section %s of %s\n",
9403 p->u.indirect.section->name,
9404 p->u.indirect.section->owner->filename);
9405 break;
9406 case bfd_data_link_order:
9407 printf (" explicit data\n");
95e34ef7 9408 break;
95e34ef7 9409 default:
07d6d2b8 9410 printf (" *unknown* type %u\n", p->type);
95e34ef7
TG
9411 break;
9412 }
9413 }
9414 }
9415#endif
9416
f9eeb9c9
TG
9417 /* Generate the symbol table. */
9418 BFD_ASSERT (PRIV (syms) == NULL);
9419 if (info->strip != strip_all)
7686d77d 9420 bfd_hash_traverse (&info->hash->table, alpha_vms_link_output_symbol, info);
f9eeb9c9 9421
44273c5b 9422 /* Find the entry point. */
95e34ef7
TG
9423 if (bfd_get_start_address (abfd) == 0)
9424 {
9425 bfd *startbfd = NULL;
9426
c72f2fb2 9427 for (sub = info->input_bfds; sub != NULL; sub = sub->link.next)
07d6d2b8
AM
9428 {
9429 /* Consider only VMS object files. */
9430 if (sub->xvec != abfd->xvec)
9431 continue;
9432
9433 if (!PRIV2 (sub, eom_data).eom_has_transfer)
9434 continue;
9435 if ((PRIV2 (sub, eom_data).eom_b_tfrflg & EEOM__M_WKTFR) && startbfd)
9436 continue;
9437 if (startbfd != NULL
9438 && !(PRIV2 (sub, eom_data).eom_b_tfrflg & EEOM__M_WKTFR))
9439 {
9440 (*info->callbacks->einfo)
695344c0 9441 /* xgettext:c-format */
871b3ab2 9442 (_("%P: multiple entry points: in modules %pB and %pB\n"),
07d6d2b8
AM
9443 startbfd, sub);
9444 continue;
9445 }
9446 startbfd = sub;
9447 }
95e34ef7
TG
9448
9449 if (startbfd)
07d6d2b8
AM
9450 {
9451 unsigned int ps_idx = PRIV2 (startbfd, eom_data).eom_l_psindx;
9452 bfd_vma tfradr = PRIV2 (startbfd, eom_data).eom_l_tfradr;
9453 asection *sec;
95e34ef7 9454
07d6d2b8 9455 sec = PRIV2 (startbfd, sections)[ps_idx];
95e34ef7 9456
07d6d2b8
AM
9457 bfd_set_start_address
9458 (abfd, sec->output_section->vma + sec->output_offset + tfradr);
9459 }
95e34ef7
TG
9460 }
9461
46d00b8a
TG
9462 /* Set transfer addresses. */
9463 {
9464 int i;
9465 struct bfd_link_hash_entry *h;
9466
9467 i = 0;
d0ef7741 9468 PRIV (transfer_address[i++]) = 0xffffffff00000340ULL; /* SYS$IMGACT */
0a1b45a2 9469 h = bfd_link_hash_lookup (info->hash, "LIB$INITIALIZE", false, false, true);
46d00b8a
TG
9470 if (h != NULL && h->type == bfd_link_hash_defined)
9471 PRIV (transfer_address[i++]) =
07d6d2b8 9472 alpha_vms_get_sym_value (h->u.def.section, h->u.def.value);
46d00b8a
TG
9473 PRIV (transfer_address[i++]) = bfd_get_start_address (abfd);
9474 while (i < 4)
9475 PRIV (transfer_address[i++]) = 0;
9476 }
9477
79326a5a
TG
9478 /* Allocate contents.
9479 Also compute the virtual base address. */
95e34ef7
TG
9480 base_addr = (bfd_vma)-1;
9481 last_addr = 0;
9482 for (o = abfd->sections; o != NULL; o = o->next)
9483 {
9484 if (o->flags & SEC_HAS_CONTENTS)
07d6d2b8
AM
9485 {
9486 o->contents = bfd_alloc (abfd, o->size);
9487 if (o->contents == NULL)
0a1b45a2 9488 return false;
07d6d2b8 9489 }
95e34ef7 9490 if (o->flags & SEC_LOAD)
07d6d2b8
AM
9491 {
9492 if (o->vma < base_addr)
9493 base_addr = o->vma;
9494 if (o->vma + o->size > last_addr)
9495 last_addr = o->vma + o->size;
9496 }
79326a5a 9497 /* Clear the RELOC flags. Currently we don't support incremental
07d6d2b8 9498 linking. We use the RELOC flag for computing the eicp entries. */
79326a5a 9499 o->flags &= ~SEC_RELOC;
95e34ef7
TG
9500 }
9501
44273c5b 9502 /* Create the fixup section. */
95e34ef7
TG
9503 fixupsec = bfd_make_section_anyway_with_flags
9504 (info->output_bfd, "$FIXUP$",
9505 SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_LINKER_CREATED);
9506 if (fixupsec == NULL)
0a1b45a2 9507 return false;
95e34ef7
TG
9508 last_addr = (last_addr + 0xffff) & ~0xffff;
9509 fixupsec->vma = last_addr;
9510
9511 alpha_vms_link_hash (info)->fixup = fixupsec;
9512 alpha_vms_link_hash (info)->base_addr = base_addr;
9513
fa23f0f4 9514 /* Create the DMT section, if necessary. */
f9eeb9c9
TG
9515 BFD_ASSERT (PRIV (dst_section) == NULL);
9516 dst = bfd_get_section_by_name (abfd, "$DST$");
fa23f0f4
TG
9517 if (dst != NULL && dst->size == 0)
9518 dst = NULL;
9519 if (dst != NULL)
9520 {
f9eeb9c9 9521 PRIV (dst_section) = dst;
fa23f0f4 9522 dmt = bfd_make_section_anyway_with_flags
07d6d2b8
AM
9523 (info->output_bfd, "$DMT$",
9524 SEC_DEBUGGING | SEC_HAS_CONTENTS | SEC_LINKER_CREATED);
fa23f0f4 9525 if (dmt == NULL)
0a1b45a2 9526 return false;
fa23f0f4
TG
9527 }
9528 else
9529 dmt = NULL;
9530
95e34ef7 9531 /* Read all sections from the inputs. */
c72f2fb2 9532 for (sub = info->input_bfds; sub != NULL; sub = sub->link.next)
95e34ef7
TG
9533 {
9534 if (sub->flags & DYNAMIC)
07d6d2b8
AM
9535 {
9536 alpha_vms_create_eisd_for_shared (abfd, sub);
9537 continue;
9538 }
95e34ef7
TG
9539
9540 if (!alpha_vms_read_sections_content (sub, info))
0a1b45a2 9541 return false;
95e34ef7
TG
9542 }
9543
fa23f0f4
TG
9544 /* Handle all the link order information for the sections.
9545 Note: past this point, it is not possible to create new sections. */
95e34ef7
TG
9546 for (o = abfd->sections; o != NULL; o = o->next)
9547 {
9548 for (p = o->map_head.link_order; p != NULL; p = p->next)
9549 {
9550 switch (p->type)
9551 {
9552 case bfd_section_reloc_link_order:
9553 case bfd_symbol_reloc_link_order:
07d6d2b8 9554 abort ();
0a1b45a2 9555 return false;
95e34ef7 9556 case bfd_indirect_link_order:
07d6d2b8 9557 /* Already done. */
95e34ef7
TG
9558 break;
9559 default:
9560 if (! _bfd_default_link_order (abfd, info, o, p))
0a1b45a2 9561 return false;
95e34ef7
TG
9562 break;
9563 }
9564 }
9565 }
9566
9567 /* Compute fixups. */
9568 if (!alpha_vms_build_fixups (info))
0a1b45a2 9569 return false;
95e34ef7 9570
44273c5b 9571 /* Compute the DMT. */
fa23f0f4 9572 if (dmt != NULL)
44273c5b 9573 {
44273c5b
TG
9574 int pass;
9575 unsigned char *contents = NULL;
9576
44273c5b
TG
9577 /* In pass 1, compute the size. In pass 2, write the DMT contents. */
9578 for (pass = 0; pass < 2; pass++)
07d6d2b8
AM
9579 {
9580 unsigned int off = 0;
9581
9582 /* For each object file (ie for each module). */
9583 for (sub = info->input_bfds; sub != NULL; sub = sub->link.next)
9584 {
9585 asection *sub_dst;
9586 struct vms_dmt_header *dmth = NULL;
9587 unsigned int psect_count;
9588
9589 /* Skip this module if it has no DST. */
9590 sub_dst = PRIV2 (sub, dst_section);
9591 if (sub_dst == NULL || sub_dst->size == 0)
9592 continue;
9593
9594 if (pass == 1)
9595 {
9596 /* Write the header. */
9597 dmth = (struct vms_dmt_header *)(contents + off);
9598 bfd_putl32 (sub_dst->output_offset, dmth->modbeg);
9599 bfd_putl32 (sub_dst->size, dmth->size);
9600 }
9601
9602 off += sizeof (struct vms_dmt_header);
9603 psect_count = 0;
9604
9605 /* For each section (ie for each psect). */
9606 for (o = sub->sections; o != NULL; o = o->next)
9607 {
9608 /* Only consider interesting sections. */
9609 if (!(o->flags & SEC_ALLOC))
9610 continue;
9611 if (o->flags & SEC_LINKER_CREATED)
9612 continue;
9613
9614 if (pass == 1)
9615 {
9616 /* Write an entry. */
9617 struct vms_dmt_psect *dmtp;
9618
9619 dmtp = (struct vms_dmt_psect *)(contents + off);
9620 bfd_putl32 (o->output_offset + o->output_section->vma,
9621 dmtp->start);
9622 bfd_putl32 (o->size, dmtp->length);
9623 psect_count++;
9624 }
9625 off += sizeof (struct vms_dmt_psect);
9626 }
9627 if (pass == 1)
9628 bfd_putl32 (psect_count, dmth->psect_count);
9629 }
9630
9631 if (pass == 0)
9632 {
9633 contents = bfd_zalloc (info->output_bfd, off);
9634 if (contents == NULL)
0a1b45a2 9635 return false;
07d6d2b8
AM
9636 dmt->contents = contents;
9637 dmt->size = off;
9638 }
9639 else
9640 {
9641 BFD_ASSERT (off == dmt->size);
9642 }
9643 }
44273c5b
TG
9644 }
9645
0a1b45a2 9646 return true;
95e34ef7
TG
9647}
9648
9649/* Read the contents of a section.
9650 buf points to a buffer of buf_size bytes to be filled with
9651 section data (starting at offset into section) */
9652
0a1b45a2 9653static bool
95e34ef7 9654alpha_vms_get_section_contents (bfd *abfd, asection *section,
07d6d2b8
AM
9655 void *buf, file_ptr offset,
9656 bfd_size_type count)
95e34ef7
TG
9657{
9658 asection *sec;
9659
9660 /* Image are easy. */
9661 if (bfd_get_file_flags (abfd) & (EXEC_P | DYNAMIC))
9662 return _bfd_generic_get_section_contents (abfd, section,
07d6d2b8 9663 buf, offset, count);
95e34ef7
TG
9664
9665 /* Safety check. */
9666 if (offset + count < count
9667 || offset + count > section->size)
9668 {
9669 bfd_set_error (bfd_error_invalid_operation);
0a1b45a2 9670 return false;
95e34ef7
TG
9671 }
9672
8185f55c
TG
9673 /* If the section is already in memory, just copy it. */
9674 if (section->flags & SEC_IN_MEMORY)
9675 {
9676 BFD_ASSERT (section->contents != NULL);
9677 memcpy (buf, section->contents + offset, count);
0a1b45a2 9678 return true;
8185f55c
TG
9679 }
9680 if (section->size == 0)
0a1b45a2 9681 return true;
95e34ef7 9682
8185f55c 9683 /* Alloc in memory and read ETIRs. */
95e34ef7
TG
9684 for (sec = abfd->sections; sec; sec = sec->next)
9685 {
9686 BFD_ASSERT (sec->contents == NULL);
9687
9688 if (sec->size != 0 && (sec->flags & SEC_HAS_CONTENTS))
07d6d2b8
AM
9689 {
9690 sec->contents = bfd_alloc (abfd, sec->size);
9691 if (sec->contents == NULL)
0a1b45a2 9692 return false;
07d6d2b8 9693 }
95e34ef7
TG
9694 }
9695 if (!alpha_vms_read_sections_content (abfd, NULL))
0a1b45a2 9696 return false;
95e34ef7 9697 for (sec = abfd->sections; sec; sec = sec->next)
8185f55c
TG
9698 if (sec->contents)
9699 sec->flags |= SEC_IN_MEMORY;
95e34ef7 9700 memcpy (buf, section->contents + offset, count);
0a1b45a2 9701 return true;
95e34ef7
TG
9702}
9703
9704
9705/* Set the format of a file being written. */
9706
0a1b45a2 9707static bool
95e34ef7
TG
9708alpha_vms_mkobject (bfd * abfd)
9709{
9710 const bfd_arch_info_type *arch;
9711
9712 vms_debug2 ((1, "alpha_vms_mkobject (%p)\n", abfd));
9713
9714 if (!vms_initialize (abfd))
0a1b45a2 9715 return false;
95e34ef7
TG
9716
9717 PRIV (recwr.buf) = bfd_alloc (abfd, MAX_OUTREC_SIZE);
9718 if (PRIV (recwr.buf) == NULL)
0a1b45a2 9719 return false;
95e34ef7
TG
9720
9721 arch = bfd_scan_arch ("alpha");
9722
9723 if (arch == 0)
9724 {
9725 bfd_set_error (bfd_error_wrong_format);
0a1b45a2 9726 return false;
95e34ef7
TG
9727 }
9728
9729 abfd->arch_info = arch;
0a1b45a2 9730 return true;
95e34ef7
TG
9731}
9732
9733
9734/* 4.1, generic. */
9735
9736/* Called when the BFD is being closed to do any necessary cleanup. */
9737
0a1b45a2 9738static bool
95e34ef7
TG
9739vms_close_and_cleanup (bfd * abfd)
9740{
9741 vms_debug2 ((1, "vms_close_and_cleanup (%p)\n", abfd));
9742
9743 if (abfd == NULL || abfd->tdata.any == NULL)
0a1b45a2 9744 return true;
95e34ef7 9745
37d2e9c7 9746 if (abfd->format == bfd_object)
95e34ef7 9747 {
a7ac9aa5 9748 alpha_vms_free_private (abfd);
95e34ef7
TG
9749
9750#ifdef VMS
37d2e9c7
AM
9751 if (abfd->direction == write_direction)
9752 {
9753 /* Last step on VMS is to convert the file to variable record length
9754 format. */
9755 if (!bfd_cache_close (abfd))
0a1b45a2 9756 return false;
37d2e9c7 9757 if (!_bfd_vms_convert_to_var_unix_filename (abfd->filename))
0a1b45a2 9758 return false;
37d2e9c7 9759 }
95e34ef7 9760#endif
37d2e9c7 9761 }
95e34ef7 9762
37d2e9c7 9763 return _bfd_generic_close_and_cleanup (abfd);
95e34ef7
TG
9764}
9765
9766/* Called when a new section is created. */
9767
0a1b45a2 9768static bool
95e34ef7
TG
9769vms_new_section_hook (bfd * abfd, asection *section)
9770{
986f0783 9771 size_t amt;
95e34ef7 9772
d3435ae8 9773 vms_debug2 ((1, "vms_new_section_hook (%p, [%u]%s)\n",
07d6d2b8 9774 abfd, section->index, section->name));
95e34ef7 9775
fd361982 9776 if (!bfd_set_section_alignment (section, 0))
0a1b45a2 9777 return false;
95e34ef7 9778
d3435ae8 9779 vms_debug2 ((7, "%u: %s\n", section->index, section->name));
95e34ef7
TG
9780
9781 amt = sizeof (struct vms_section_data_struct);
8185f55c 9782 section->used_by_bfd = bfd_zalloc (abfd, amt);
95e34ef7 9783 if (section->used_by_bfd == NULL)
0a1b45a2 9784 return false;
95e34ef7 9785
95e34ef7
TG
9786 /* Create the section symbol. */
9787 return _bfd_generic_new_section_hook (abfd, section);
9788}
9789
9790/* Part 4.5, symbols. */
9791
9792/* Print symbol to file according to how. how is one of
9793 bfd_print_symbol_name just print the name
9794 bfd_print_symbol_more print more (???)
9795 bfd_print_symbol_all print all we know, which is not much right now :-). */
9796
9797static void
9798vms_print_symbol (bfd * abfd,
9799 void * file,
9800 asymbol *symbol,
9801 bfd_print_symbol_type how)
9802{
9803 vms_debug2 ((1, "vms_print_symbol (%p, %p, %p, %d)\n",
07d6d2b8 9804 abfd, file, symbol, how));
95e34ef7
TG
9805
9806 switch (how)
9807 {
9808 case bfd_print_symbol_name:
9809 case bfd_print_symbol_more:
9810 fprintf ((FILE *)file," %s", symbol->name);
9811 break;
9812
9813 case bfd_print_symbol_all:
9814 {
9815 const char *section_name = symbol->section->name;
9816
9817 bfd_print_symbol_vandf (abfd, file, symbol);
9818
9819 fprintf ((FILE *) file," %-8s %s", section_name, symbol->name);
07d6d2b8 9820 }
95e34ef7
TG
9821 break;
9822 }
9823}
9824
9825/* Return information about symbol in ret.
9826
9827 fill type, value and name
9828 type:
9829 A absolute
9830 B bss segment symbol
9831 C common symbol
9832 D data segment symbol
9833 f filename
9834 t a static function symbol
9835 T text segment symbol
9836 U undefined
9837 - debug. */
9838
9839static void
9840vms_get_symbol_info (bfd * abfd ATTRIBUTE_UNUSED,
9841 asymbol *symbol,
9842 symbol_info *ret)
9843{
9844 asection *sec;
9845
9846 vms_debug2 ((1, "vms_get_symbol_info (%p, %p, %p)\n", abfd, symbol, ret));
9847
9848 sec = symbol->section;
9849
9850 if (ret == NULL)
9851 return;
9852
a928f1d7 9853 if (sec == NULL)
95e34ef7
TG
9854 ret->type = 'U';
9855 else if (bfd_is_com_section (sec))
9856 ret->type = 'C';
9857 else if (bfd_is_abs_section (sec))
9858 ret->type = 'A';
9859 else if (bfd_is_und_section (sec))
9860 ret->type = 'U';
9861 else if (bfd_is_ind_section (sec))
9862 ret->type = 'I';
c068d5be 9863 else if ((symbol->flags & BSF_FUNCTION)
fd361982 9864 || (bfd_section_flags (sec) & SEC_CODE))
95e34ef7 9865 ret->type = 'T';
fd361982 9866 else if (bfd_section_flags (sec) & SEC_DATA)
95e34ef7 9867 ret->type = 'D';
fd361982 9868 else if (bfd_section_flags (sec) & SEC_ALLOC)
95e34ef7
TG
9869 ret->type = 'B';
9870 else
5369db0a 9871 ret->type = '?';
95e34ef7
TG
9872
9873 if (ret->type != 'U')
9874 ret->value = symbol->value + symbol->section->vma;
9875 else
9876 ret->value = 0;
9877 ret->name = symbol->name;
9878}
9879
9880/* Return TRUE if the given symbol sym in the BFD abfd is
9881 a compiler generated local label, else return FALSE. */
9882
0a1b45a2 9883static bool
95e34ef7
TG
9884vms_bfd_is_local_label_name (bfd * abfd ATTRIBUTE_UNUSED,
9885 const char *name)
9886{
95e34ef7
TG
9887 return name[0] == '$';
9888}
9889\f
9890/* Part 4.7, writing an object file. */
9891
9892/* Sets the contents of the section section in BFD abfd to the data starting
9893 in memory at LOCATION. The data is written to the output section starting
9894 at offset offset for count bytes.
9895
9896 Normally TRUE is returned, else FALSE. Possible error returns are:
9897 o bfd_error_no_contents - The output section does not have the
9898 SEC_HAS_CONTENTS attribute, so nothing can be written to it.
9899 o and some more too */
9900
0a1b45a2 9901static bool
95e34ef7 9902_bfd_vms_set_section_contents (bfd * abfd,
07d6d2b8
AM
9903 asection *section,
9904 const void * location,
9905 file_ptr offset,
9906 bfd_size_type count)
95e34ef7
TG
9907{
9908 if (section->contents == NULL)
9909 {
9910 section->contents = bfd_alloc (abfd, section->size);
9911 if (section->contents == NULL)
0a1b45a2 9912 return false;
95e34ef7
TG
9913
9914 memcpy (section->contents + offset, location, (size_t) count);
9915 }
9916
0a1b45a2 9917 return true;
95e34ef7
TG
9918}
9919
9920/* Set the architecture and machine type in BFD abfd to arch and mach.
9921 Find the correct pointer to a structure and insert it into the arch_info
9922 pointer. */
9923
0a1b45a2 9924static bool
95e34ef7 9925alpha_vms_set_arch_mach (bfd *abfd,
07d6d2b8 9926 enum bfd_architecture arch, unsigned long mach)
95e34ef7
TG
9927{
9928 if (arch != bfd_arch_alpha
9929 && arch != bfd_arch_unknown)
0a1b45a2 9930 return false;
95e34ef7
TG
9931
9932 return bfd_default_set_arch_mach (abfd, arch, mach);
9933}
9934
9935/* Set section VMS flags. Clear NO_FLAGS and set FLAGS. */
9936
9937void
9938bfd_vms_set_section_flags (bfd *abfd ATTRIBUTE_UNUSED,
9939 asection *sec, flagword no_flags, flagword flags)
9940{
9941 vms_section_data (sec)->no_flags = no_flags;
9942 vms_section_data (sec)->flags = flags;
9943}
9944
9945struct vms_private_data_struct *
9946bfd_vms_get_data (bfd *abfd)
9947{
9948 return (struct vms_private_data_struct *)abfd->tdata.any;
9949}
9950
d00dd7dc 9951#define vms_bfd_is_target_special_symbol _bfd_bool_bfd_asymbol_false
07d6d2b8 9952#define vms_bfd_link_just_syms _bfd_generic_link_just_syms
95e34ef7
TG
9953#define vms_bfd_copy_link_hash_symbol_type \
9954 _bfd_generic_copy_link_hash_symbol_type
07d6d2b8 9955#define vms_bfd_is_group_section bfd_generic_is_group_section
cb7f4b29 9956#define vms_bfd_group_name bfd_generic_group_name
07d6d2b8
AM
9957#define vms_bfd_discard_group bfd_generic_discard_group
9958#define vms_section_already_linked _bfd_generic_section_already_linked
9959#define vms_bfd_define_common_symbol bfd_generic_define_common_symbol
34a87bb0 9960#define vms_bfd_link_hide_symbol _bfd_generic_link_hide_symbol
68d20676 9961#define vms_bfd_define_start_stop bfd_generic_define_start_stop
95e34ef7
TG
9962#define vms_bfd_copy_private_header_data _bfd_generic_bfd_copy_private_header_data
9963
9964#define vms_bfd_copy_private_bfd_data _bfd_generic_bfd_copy_private_bfd_data
9965#define vms_bfd_free_cached_info _bfd_generic_bfd_free_cached_info
9966#define vms_bfd_copy_private_section_data _bfd_generic_bfd_copy_private_section_data
9967#define vms_bfd_copy_private_symbol_data _bfd_generic_bfd_copy_private_symbol_data
07d6d2b8
AM
9968#define vms_bfd_set_private_flags _bfd_generic_bfd_set_private_flags
9969#define vms_bfd_merge_private_bfd_data _bfd_generic_bfd_merge_private_bfd_data
95e34ef7
TG
9970
9971/* Symbols table. */
07d6d2b8 9972#define alpha_vms_make_empty_symbol _bfd_generic_make_empty_symbol
d00dd7dc 9973#define alpha_vms_bfd_is_target_special_symbol _bfd_bool_bfd_asymbol_false
07d6d2b8
AM
9974#define alpha_vms_print_symbol vms_print_symbol
9975#define alpha_vms_get_symbol_info vms_get_symbol_info
60bb06bc
L
9976#define alpha_vms_get_symbol_version_string \
9977 _bfd_nosymbols_get_symbol_version_string
9978
07d6d2b8
AM
9979#define alpha_vms_read_minisymbols _bfd_generic_read_minisymbols
9980#define alpha_vms_minisymbol_to_symbol _bfd_generic_minisymbol_to_symbol
9981#define alpha_vms_get_lineno _bfd_nosymbols_get_lineno
9982#define alpha_vms_find_inliner_info _bfd_nosymbols_find_inliner_info
9983#define alpha_vms_bfd_make_debug_symbol _bfd_nosymbols_bfd_make_debug_symbol
9984#define alpha_vms_find_nearest_line _bfd_vms_find_nearest_line
9985#define alpha_vms_find_line _bfd_nosymbols_find_line
95e34ef7
TG
9986#define alpha_vms_bfd_is_local_label_name vms_bfd_is_local_label_name
9987
9988/* Generic table. */
9989#define alpha_vms_close_and_cleanup vms_close_and_cleanup
9990#define alpha_vms_bfd_free_cached_info vms_bfd_free_cached_info
9991#define alpha_vms_new_section_hook vms_new_section_hook
9992#define alpha_vms_set_section_contents _bfd_vms_set_section_contents
9993#define alpha_vms_get_section_contents_in_window _bfd_generic_get_section_contents_in_window
9994
9995#define alpha_vms_bfd_get_relocated_section_contents \
9996 bfd_generic_get_relocated_section_contents
9997
9998#define alpha_vms_bfd_relax_section bfd_generic_relax_section
9999#define alpha_vms_bfd_gc_sections bfd_generic_gc_sections
ae17ab41 10000#define alpha_vms_bfd_lookup_section_flags bfd_generic_lookup_section_flags
95e34ef7
TG
10001#define alpha_vms_bfd_merge_sections bfd_generic_merge_sections
10002#define alpha_vms_bfd_is_group_section bfd_generic_is_group_section
cb7f4b29 10003#define alpha_vms_bfd_group_name bfd_generic_group_name
95e34ef7
TG
10004#define alpha_vms_bfd_discard_group bfd_generic_discard_group
10005#define alpha_vms_section_already_linked \
10006 _bfd_generic_section_already_linked
10007
10008#define alpha_vms_bfd_define_common_symbol bfd_generic_define_common_symbol
34a87bb0 10009#define alpha_vms_bfd_link_hide_symbol _bfd_generic_link_hide_symbol
7dba9362 10010#define alpha_vms_bfd_define_start_stop bfd_generic_define_start_stop
95e34ef7
TG
10011#define alpha_vms_bfd_link_just_syms _bfd_generic_link_just_syms
10012#define alpha_vms_bfd_copy_link_hash_symbol_type \
10013 _bfd_generic_copy_link_hash_symbol_type
10014
10015#define alpha_vms_bfd_link_split_section _bfd_generic_link_split_section
10016
10017#define alpha_vms_get_dynamic_symtab_upper_bound \
10018 _bfd_nodynamic_get_dynamic_symtab_upper_bound
10019#define alpha_vms_canonicalize_dynamic_symtab \
10020 _bfd_nodynamic_canonicalize_dynamic_symtab
10021#define alpha_vms_get_dynamic_reloc_upper_bound \
10022 _bfd_nodynamic_get_dynamic_reloc_upper_bound
10023#define alpha_vms_canonicalize_dynamic_reloc \
10024 _bfd_nodynamic_canonicalize_dynamic_reloc
07d6d2b8 10025#define alpha_vms_bfd_link_check_relocs _bfd_generic_link_check_relocs
95e34ef7 10026
6d00b590 10027const bfd_target alpha_vms_vec =
95e34ef7
TG
10028{
10029 "vms-alpha", /* Name. */
10030 bfd_target_evax_flavour,
10031 BFD_ENDIAN_LITTLE, /* Data byte order is little. */
10032 BFD_ENDIAN_LITTLE, /* Header byte order is little. */
10033
10034 (HAS_RELOC | EXEC_P | HAS_LINENO | HAS_DEBUG | HAS_SYMS | HAS_LOCALS
10035 | WP_TEXT | D_PAGED), /* Object flags. */
10036 (SEC_ALLOC | SEC_LOAD | SEC_RELOC
10037 | SEC_READONLY | SEC_CODE | SEC_DATA
10038 | SEC_HAS_CONTENTS | SEC_IN_MEMORY), /* Sect flags. */
10039 0, /* symbol_leading_char. */
10040 ' ', /* ar_pad_char. */
10041 15, /* ar_max_namelen. */
0aabe54e 10042 0, /* match priority. */
d1bcae83 10043 TARGET_KEEP_UNUSED_SECTION_SYMBOLS, /* keep unused section symbols. */
95e34ef7
TG
10044 bfd_getl64, bfd_getl_signed_64, bfd_putl64,
10045 bfd_getl32, bfd_getl_signed_32, bfd_putl32,
10046 bfd_getl16, bfd_getl_signed_16, bfd_putl16,
10047 bfd_getl64, bfd_getl_signed_64, bfd_putl64,
10048 bfd_getl32, bfd_getl_signed_32, bfd_putl32,
10049 bfd_getl16, bfd_getl_signed_16, bfd_putl16,
10050
d00dd7dc
AM
10051 { /* bfd_check_format. */
10052 _bfd_dummy_target,
10053 alpha_vms_object_p,
10054 _bfd_vms_lib_alpha_archive_p,
10055 _bfd_dummy_target
10056 },
10057 { /* bfd_set_format. */
10058 _bfd_bool_bfd_false_error,
10059 alpha_vms_mkobject,
10060 _bfd_vms_lib_alpha_mkarchive,
10061 _bfd_bool_bfd_false_error
10062 },
10063 { /* bfd_write_contents. */
10064 _bfd_bool_bfd_false_error,
10065 alpha_vms_write_object_contents,
10066 _bfd_vms_lib_write_archive_contents,
10067 _bfd_bool_bfd_false_error
10068 },
95e34ef7
TG
10069
10070 BFD_JUMP_TABLE_GENERIC (alpha_vms),
10071 BFD_JUMP_TABLE_COPY (vms),
10072 BFD_JUMP_TABLE_CORE (_bfd_nocore),
10073 BFD_JUMP_TABLE_ARCHIVE (_bfd_vms_lib),
10074 BFD_JUMP_TABLE_SYMBOLS (alpha_vms),
10075 BFD_JUMP_TABLE_RELOCS (alpha_vms),
10076 BFD_JUMP_TABLE_WRITE (alpha_vms),
10077 BFD_JUMP_TABLE_LINK (alpha_vms),
10078 BFD_JUMP_TABLE_DYNAMIC (alpha_vms),
10079
10080 NULL,
10081
8185f55c 10082 NULL
95e34ef7 10083};