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