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