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