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