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