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