*** empty log message ***
[deliverable/binutils-gdb.git] / bfd / vms.c
CommitLineData
252b5132
RH
1/* vms.c -- BFD back-end for VAX (openVMS/VAX) and
2 EVAX (openVMS/Alpha) files.
66eb6687 3 Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
0c376465
TG
4 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
5
6 Main file.
252b5132
RH
7
8 Written by Klaus K"ampf (kkaempf@rmi.de)
9
7920ce38
NC
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
cd123cb7 12 the Free Software Foundation; either version 3 of the License, or
7920ce38 13 (at your option) any later version.
252b5132 14
7920ce38
NC
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
252b5132 19
7920ce38
NC
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
cd123cb7
NC
22 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
23 MA 02110-1301, USA. */
252b5132 24
0c376465
TG
25#ifdef VMS
26#include <rms.h>
11d73275 27#include <unixlib.h>
0c376465
TG
28#include <starlet.h>
29#define RME$C_SETRFM 0x00000001
30#include <unistd.h>
31#endif
32
252b5132 33#include "sysdep.h"
3db64b00 34#include "bfd.h"
252b5132
RH
35#include "bfdlink.h"
36#include "libbfd.h"
37
38#include "vms.h"
39
0c376465
TG
40static bfd_boolean vms_initialize (bfd *);
41static bfd_boolean fill_section_ptr (struct bfd_hash_entry *, PTR);
42static bfd_boolean vms_fixup_sections (bfd *);
43static bfd_boolean copy_symbols (struct bfd_hash_entry *, PTR);
44static bfd_reloc_status_type reloc_nil (bfd *, arelent *, asymbol *, PTR,
45 asection *, bfd *, char **);
46static int vms_slurp_module (bfd *abfd);
47static int vms_slurp_image (bfd *abfd);
48static const struct bfd_target *vms_object_p (bfd *abfd);
0c376465
TG
49static bfd_boolean vms_mkobject (bfd *abfd);
50static bfd_boolean vms_write_object_contents (bfd *abfd);
51static void free_reloc_stream (bfd *abfd, asection *section, void *data);
52static bfd_boolean vms_close_and_cleanup (bfd *abfd);
0c376465
TG
53static bfd_boolean vms_new_section_hook (bfd *abfd, asection *section);
54static bfd_boolean vms_get_section_contents
55 (bfd *abfd, asection *section, PTR x1, file_ptr x2, bfd_size_type x3);
0c376465
TG
56static long vms_get_symtab_upper_bound (bfd *abfd);
57static long vms_canonicalize_symtab (bfd *abfd, asymbol **symbols);
58static void vms_print_symbol (bfd *abfd, PTR file, asymbol *symbol,
59 bfd_print_symbol_type how);
60static void vms_get_symbol_info (bfd *abfd, asymbol *symbol, symbol_info *ret);
61static bfd_boolean vms_bfd_is_local_label_name (bfd *abfd, const char *);
0c376465
TG
62static bfd_boolean vms_find_nearest_line
63 (bfd *abfd, asection *section, asymbol **symbols, bfd_vma offset,
64 const char **file, const char **func, unsigned int *line);
0c376465
TG
65static void alloc_reloc_stream (bfd *abfd, asection *section,
66 void *alloc_error);
67static bfd_boolean vms_slurp_reloc_table (bfd *abfd, asection *section,
68 asymbol **symbols);
69static long vms_get_reloc_upper_bound (bfd *abfd, asection *sect);
70static long vms_canonicalize_reloc (bfd *abfd, asection *srcsec,
71 arelent **location, asymbol **symbols);
72static const struct reloc_howto_struct *vms_bfd_reloc_type_lookup
73 (bfd *abfd, bfd_reloc_code_real_type code);
74static bfd_boolean vms_set_arch_mach
75 (bfd *abfd, enum bfd_architecture arch, unsigned long mach);
76static bfd_boolean vms_set_section_contents
77 (bfd *abfd, asection *section, const PTR location, file_ptr offset,
78 bfd_size_type count);
0c376465 79
3c9458e9 80#define vms_bfd_is_target_special_symbol ((bfd_boolean (*) (bfd *, asymbol *)) bfd_false)
7920ce38
NC
81#define vms_make_empty_symbol _bfd_generic_make_empty_symbol
82#define vms_bfd_link_just_syms _bfd_generic_link_just_syms
1338dd10
PB
83#define vms_bfd_copy_link_hash_symbol_type \
84 _bfd_generic_copy_link_hash_symbol_type
7920ce38
NC
85#define vms_bfd_is_group_section bfd_generic_is_group_section
86#define vms_bfd_discard_group bfd_generic_discard_group
87#define vms_section_already_linked _bfd_generic_section_already_linked
3023e3f6 88#define vms_bfd_define_common_symbol bfd_generic_define_common_symbol
7920ce38
NC
89#define vms_bfd_copy_private_header_data _bfd_generic_bfd_copy_private_header_data
90#define vms_get_synthetic_symtab _bfd_nodynamic_get_synthetic_symtab
252b5132 91
e4d2e665
TG
92#define vms_bfd_copy_private_bfd_data _bfd_generic_bfd_copy_private_bfd_data
93#define vms_bfd_print_private_bfd_data _bfd_generic_bfd_print_private_bfd_data
94#define vms_bfd_free_cached_info _bfd_generic_bfd_free_cached_info
95#define vms_bfd_copy_private_section_data _bfd_generic_bfd_copy_private_section_data
96#define vms_bfd_copy_private_symbol_data _bfd_generic_bfd_copy_private_symbol_data
97#define vms_bfd_set_private_flags _bfd_generic_bfd_set_private_flags
98#define vms_bfd_merge_private_bfd_data _bfd_generic_bfd_merge_private_bfd_data
99#define vms_get_section_contents_in_window _bfd_generic_get_section_contents_in_window
100#define vms_read_minisymbols _bfd_generic_read_minisymbols
101#define vms_minisymbol_to_symbol _bfd_generic_minisymbol_to_symbol
102#define vms_get_lineno _bfd_nosymbols_get_lineno
103#define vms_find_inliner_info _bfd_nosymbols_find_inliner_info
104#define vms_bfd_make_debug_symbol _bfd_nosymbols_bfd_make_debug_symbol
0c376465
TG
105\f
106#ifdef VMS_DEBUG
107/* Cause debug info to be emitted for the structure. */
108struct vms_private_data_struct _vms_private_data_struct_dummy;
109struct vms_section_data_struct _vms_section_data_struct_dummy;
110#endif
111
7920ce38
NC
112extern const bfd_target vms_vax_vec;
113extern const bfd_target vms_alpha_vec;
252b5132 114
0c376465 115/* Initialize private data */
b34976b6 116static bfd_boolean
7920ce38 117vms_initialize (bfd * abfd)
252b5132 118{
dc810e39 119 bfd_size_type amt;
252b5132 120
dc810e39 121 bfd_set_start_address (abfd, (bfd_vma) -1);
252b5132 122
dc810e39 123 amt = sizeof (struct vms_private_data_struct);
0c376465 124 abfd->tdata.any = bfd_zalloc (abfd, amt);
7920ce38 125 if (abfd->tdata.any == NULL)
b34976b6 126 return FALSE;
252b5132 127
0c376465
TG
128 if (bfd_get_flavour (abfd) == bfd_target_ovax_flavour)
129 PRIV (is_vax) = TRUE;
130
8a0c27cd 131 PRIV (file_format) = FF_UNKNOWN;
8a0c27cd 132
dc810e39 133 amt = sizeof (struct stack_struct) * STACKSIZE;
7920ce38
NC
134 PRIV (stack) = bfd_alloc (abfd, amt);
135 if (PRIV (stack) == NULL)
487e54f2 136 goto error_ret1;
252b5132 137
dc810e39 138 amt = sizeof (struct bfd_hash_table);
7920ce38
NC
139 PRIV (vms_symbol_table) = bfd_alloc (abfd, amt);
140 if (PRIV (vms_symbol_table) == NULL)
487e54f2 141 goto error_ret1;
252b5132 142
66eb6687
AM
143 if (!bfd_hash_table_init (PRIV (vms_symbol_table), _bfd_vms_hash_newfunc,
144 sizeof (vms_symbol_entry)))
487e54f2 145 goto error_ret1;
252b5132 146
487e54f2 147 amt = MAX_OUTREC_SIZE;
7920ce38
NC
148 PRIV (output_buf) = bfd_alloc (abfd, amt);
149 if (PRIV (output_buf) == NULL)
487e54f2
AM
150 goto error_ret2;
151
8a0c27cd 152 PRIV (length_pos) = 2;
252b5132 153
b34976b6 154 return TRUE;
487e54f2
AM
155
156 error_ret2:
157 bfd_hash_table_free (PRIV (vms_symbol_table));
158 error_ret1:
159 bfd_release (abfd, abfd->tdata.any);
7920ce38 160 abfd->tdata.any = NULL;
b34976b6 161 return FALSE;
252b5132
RH
162}
163
0c376465
TG
164struct pair
165{
166 unsigned int section_count;
167 asection **sections;
168};
169
170/* Fill symbol->section with section pointer.
171
252b5132 172 symbol->section is filled with the section index for defined symbols
0c376465 173 during reading the GSD/EGSD section. But we need the pointer to the
252b5132
RH
174 bfd section later.
175
0c376465 176 It has the correct value for referenced (undefined section) symbols.
252b5132 177
0c376465 178 Called from bfd_hash_traverse in vms_fixup_sections. */
252b5132 179
b34976b6 180static bfd_boolean
0c376465 181fill_section_ptr (struct bfd_hash_entry *entry, void *sections)
252b5132 182{
0c376465
TG
183 asymbol *sym = ((vms_symbol_entry *)entry)->symbol;
184 struct pair *data = (struct pair *)sections;
185 unsigned long sec = (unsigned long)sym->section;
252b5132 186
e4d2e665 187 vms_debug2 ((6, "fill_section_ptr: sym %p, sec %lu\n", sym, sec));
252b5132 188
0c376465
TG
189 if (sec < data->section_count)
190 {
191 sym->section = data->sections[sec];
252b5132 192
0c376465
TG
193 if (strcmp (sym->name, sym->section->name) == 0)
194 sym->flags |= BSF_SECTION_SYM;
195 }
196 else if (sec == (unsigned long)-1)
197 sym->section = &bfd_und_section;
198
b34976b6 199 return TRUE;
252b5132
RH
200}
201
0c376465 202/* Fixup section pointers in symbols. */
b34976b6 203static bfd_boolean
7920ce38 204vms_fixup_sections (bfd * abfd)
252b5132 205{
0c376465
TG
206 struct pair data;
207
8a0c27cd 208 if (PRIV (fixup_done))
b34976b6 209 return TRUE;
252b5132 210
0c376465
TG
211 data.section_count = PRIV (section_count);
212 data.sections = PRIV (sections);
213 bfd_hash_traverse (PRIV (vms_symbol_table), fill_section_ptr, &data);
252b5132 214
b34976b6 215 PRIV (fixup_done) = TRUE;
b34976b6 216 return TRUE;
252b5132 217}
252b5132 218
0c376465
TG
219/* Slurp an ordered set of VMS object records. */
220int
221_bfd_vms_slurp_object_records (bfd * abfd)
252b5132 222{
0c376465 223 int err, new_type, type = -1;
252b5132
RH
224
225 do
226 {
e4d2e665
TG
227 vms_debug2 ((7, "reading at %08lx\n", bfd_tell (abfd)));
228
0c376465
TG
229 new_type = _bfd_vms_get_object_record (abfd);
230 if (new_type < 0)
252b5132 231 {
e4d2e665 232 vms_debug2 ((2, "next_record failed\n"));
0c376465 233 return -1;
252b5132
RH
234 }
235
0c376465 236 if (type == EOBJ_S_C_EGSD && new_type != EOBJ_S_C_EGSD)
252b5132 237 {
82e51918 238 if (! vms_fixup_sections (abfd))
252b5132 239 {
e4d2e665 240 vms_debug2 ((2, "vms_fixup_sections failed\n"));
0c376465 241 return -1;
252b5132
RH
242 }
243 }
244
0c376465 245 type = new_type;
252b5132 246
0c376465 247 switch (type)
252b5132
RH
248 {
249 case OBJ_S_C_HDR:
250 case EOBJ_S_C_EMH:
0c376465 251 err = _bfd_vms_slurp_hdr (abfd, type);
252b5132
RH
252 break;
253 case OBJ_S_C_EOM:
254 case OBJ_S_C_EOMW:
255 case EOBJ_S_C_EEOM:
0c376465 256 err = _bfd_vms_slurp_eom (abfd, type);
252b5132
RH
257 break;
258 case OBJ_S_C_GSD:
259 case EOBJ_S_C_EGSD:
0c376465 260 err = _bfd_vms_slurp_gsd (abfd, type);
252b5132
RH
261 break;
262 case OBJ_S_C_TIR:
263 case EOBJ_S_C_ETIR:
0c376465 264 err = _bfd_vms_slurp_tir (abfd, type);
252b5132
RH
265 break;
266 case OBJ_S_C_DBG:
267 case EOBJ_S_C_EDBG:
0c376465
TG
268 err = _bfd_vms_slurp_dbg (abfd, type);
269 PRIV (dst_ptr_end) = PRIV (image_ptr);
252b5132
RH
270 break;
271 case OBJ_S_C_TBT:
272 case EOBJ_S_C_ETBT:
0c376465
TG
273 err = _bfd_vms_slurp_tbt (abfd, type);
274 PRIV (dst_ptr_end) = PRIV (image_ptr);
252b5132
RH
275 break;
276 case OBJ_S_C_LNK:
0c376465 277 err = _bfd_vms_slurp_lnk (abfd, type);
252b5132
RH
278 break;
279 default:
280 err = -1;
281 }
282 if (err != 0)
283 {
e4d2e665 284 vms_debug2 ((2, "slurp type %d failed with %d\n", type, err));
0c376465 285 return err;
252b5132
RH
286 }
287 }
0c376465
TG
288 while (type != EOBJ_S_C_EEOM && type != OBJ_S_C_EOM && type != OBJ_S_C_EOMW);
289
290 return 0;
291}
292
293/* Slurp a VMS module and return an error status. */
294
295static int
296vms_slurp_module (bfd *abfd)
297{
298 int type, err;
299
300 if (PRIV (is_vax))
301 type = PRIV (vms_rec)[0];
302 else
303 type = bfd_getl16 (PRIV (vms_rec));
304
305 err = _bfd_vms_slurp_hdr (abfd, type);
306 if (err != 0)
307 {
308 bfd_set_error (bfd_error_wrong_format);
309 return err;
310 }
311
312 return _bfd_vms_slurp_object_records (abfd);
313}
314
315/* Slurp a VMS image and return an error status. */
316
317static int
318vms_slurp_image (bfd *abfd)
319{
320 unsigned int isd_offset, ihs_offset;
321 int err;
322
323 err = _bfd_vms_slurp_ihd (abfd, &isd_offset, &ihs_offset);
324 if (err != 0)
325 {
326 bfd_set_error (bfd_error_wrong_format);
327 return err;
328 }
252b5132 329
0c376465
TG
330 err = _bfd_vms_slurp_isd (abfd, isd_offset);
331 if (err != 0)
332 {
333 bfd_set_error (bfd_error_wrong_format);
334 return err;
335 }
336
337 return _bfd_vms_slurp_ihs (abfd, ihs_offset);
338}
339
340/* Check the format for a file being read.
341 Return a (bfd_target *) if it's an object file or zero if not. */
342
343static const struct bfd_target *
344vms_object_p (bfd *abfd)
345{
346 const struct bfd_target *target_vector;
347 const bfd_arch_info_type *arch;
348 PTR tdata_save = abfd->tdata.any;
349 bfd_vma saddr_save = bfd_get_start_address (abfd);
350 int err = 0;
351
e4d2e665 352 vms_debug2 ((1, "vms_object_p(%p)\n", abfd));
0c376465
TG
353
354 if (!vms_initialize (abfd))
355 goto error_ret;
356
357 if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET))
358 goto err_wrong_format;
359
360 switch (_bfd_vms_get_first_record (abfd))
361 {
362 case FT_UNKNOWN:
363 default:
364 err = -1;
365 break;
366
367 case FT_MODULE:
368 err = vms_slurp_module (abfd);
369 break;
370
371 case FT_IMAGE:
372 err = vms_slurp_image (abfd);
373 break;
374 }
375
376 if (err != 0)
377 goto err_wrong_format;
378
379 if (PRIV (is_vax))
252b5132 380 {
82e51918 381 if (! vms_fixup_sections (abfd))
252b5132 382 {
e4d2e665 383 vms_debug2 ((2, "vms_fixup_sections failed\n"));
487e54f2 384 goto err_wrong_format;
252b5132
RH
385 }
386
0c376465 387 target_vector = &vms_vax_vec;
252b5132 388 arch = bfd_scan_arch ("vax");
0c376465 389
e4d2e665 390 vms_debug2 ((2, "arch is vax\n"));
252b5132 391 }
0c376465 392 else
252b5132 393 {
7920ce38 394 /* Set arch_info to alpha. */
0c376465 395 target_vector = &vms_alpha_vec;
252b5132 396 arch = bfd_scan_arch ("alpha");
e4d2e665 397 vms_debug2 ((2, "arch is alpha\n"));
252b5132
RH
398 }
399
252b5132 400 abfd->arch_info = arch;
252b5132 401 return target_vector;
487e54f2
AM
402
403 err_wrong_format:
404 bfd_set_error (bfd_error_wrong_format);
0c376465 405
487e54f2
AM
406 error_ret:
407 if (abfd->tdata.any != tdata_save && abfd->tdata.any != NULL)
408 bfd_release (abfd, abfd->tdata.any);
409 abfd->tdata.any = tdata_save;
5e9aae3e 410 bfd_set_start_address (abfd, saddr_save);
487e54f2 411 return NULL;
252b5132
RH
412}
413
252b5132
RH
414/* Set the format of a file being written. */
415
b34976b6 416static bfd_boolean
7920ce38 417vms_mkobject (bfd * abfd)
252b5132 418{
0c376465
TG
419 const bfd_arch_info_type *arch;
420
e4d2e665 421 vms_debug2 ((1, "vms_mkobject (%p)\n", abfd));
252b5132
RH
422
423 if (!vms_initialize (abfd))
7920ce38 424 return FALSE;
252b5132 425
0c376465
TG
426 if (PRIV (is_vax))
427 arch = bfd_scan_arch ("vax");
428 else
429 arch = bfd_scan_arch ("alpha");
430
431 if (arch == 0)
432 {
433 bfd_set_error(bfd_error_wrong_format);
434 return FALSE;
435 }
252b5132 436
0c376465 437 abfd->arch_info = arch;
b34976b6 438 return TRUE;
252b5132
RH
439}
440
252b5132
RH
441/* Write cached information into a file being written, at bfd_close. */
442
b34976b6 443static bfd_boolean
7920ce38 444vms_write_object_contents (bfd * abfd)
252b5132 445{
e4d2e665 446 vms_debug2 ((1, "vms_write_object_contents (%p)\n", abfd));
252b5132
RH
447
448 if (abfd->section_count > 0) /* we have sections */
449 {
8a0c27cd 450 if (PRIV (is_vax))
252b5132
RH
451 {
452 if (_bfd_vms_write_hdr (abfd, OBJ_S_C_HDR) != 0)
b34976b6 453 return FALSE;
252b5132 454 if (_bfd_vms_write_gsd (abfd, OBJ_S_C_GSD) != 0)
b34976b6 455 return FALSE;
252b5132 456 if (_bfd_vms_write_tir (abfd, OBJ_S_C_TIR) != 0)
b34976b6 457 return FALSE;
252b5132 458 if (_bfd_vms_write_tbt (abfd, OBJ_S_C_TBT) != 0)
b34976b6 459 return FALSE;
252b5132 460 if (_bfd_vms_write_dbg (abfd, OBJ_S_C_DBG) != 0)
b34976b6 461 return FALSE;
252b5132
RH
462 if (abfd->section_count > 255)
463 {
464 if (_bfd_vms_write_eom (abfd, OBJ_S_C_EOMW) != 0)
b34976b6 465 return FALSE;
252b5132
RH
466 }
467 else
468 {
469 if (_bfd_vms_write_eom (abfd, OBJ_S_C_EOM) != 0)
b34976b6 470 return FALSE;
252b5132
RH
471 }
472 }
473 else
474 {
475 if (_bfd_vms_write_hdr (abfd, EOBJ_S_C_EMH) != 0)
b34976b6 476 return FALSE;
252b5132 477 if (_bfd_vms_write_gsd (abfd, EOBJ_S_C_EGSD) != 0)
b34976b6 478 return FALSE;
252b5132 479 if (_bfd_vms_write_tir (abfd, EOBJ_S_C_ETIR) != 0)
b34976b6 480 return FALSE;
252b5132 481 if (_bfd_vms_write_tbt (abfd, EOBJ_S_C_ETBT) != 0)
b34976b6 482 return FALSE;
252b5132 483 if (_bfd_vms_write_dbg (abfd, EOBJ_S_C_EDBG) != 0)
b34976b6 484 return FALSE;
252b5132 485 if (_bfd_vms_write_eom (abfd, EOBJ_S_C_EEOM) != 0)
b34976b6 486 return FALSE;
252b5132
RH
487 }
488 }
b34976b6 489 return TRUE;
252b5132
RH
490}
491
7920ce38 492/* 4.1, generic. */
252b5132 493
0c376465
TG
494/* Free the reloc buffer for the specified section. */
495
496static void
497free_reloc_stream (bfd *abfd ATTRIBUTE_UNUSED, asection *section,
498 void *data ATTRIBUTE_UNUSED)
499{
500 if (vms_section_data (section)->reloc_stream)
501 free (vms_section_data (section)->reloc_stream);
502}
503
504#ifdef VMS
505/* Convert the file to variable record length format. This is done
506 using undocumented system call sys$modify().
507 Pure VMS version. */
508
509static void
510vms_convert_to_var (char *vms_filename)
511{
512 struct FAB fab = cc$rms_fab;
513
514 fab.fab$l_fna = vms_filename;
515 fab.fab$b_fns = strlen (vms_filename);
516 fab.fab$b_fac = FAB$M_PUT;
517 fab.fab$l_fop = FAB$M_ESC;
518 fab.fab$l_ctx = RME$C_SETRFM;
519
520 sys$open (&fab);
521
522 fab.fab$b_rfm = FAB$C_VAR;
523
524 sys$modify (&fab);
525 sys$close (&fab);
526}
527
528static int
529vms_convert_to_var_1 (char *filename, int type)
530{
531 if (type != DECC$K_FILE)
532 return FALSE;
533 vms_convert_to_var (filename);
534 return TRUE;
535}
536
537/* Convert the file to variable record length format. This is done
538 using undocumented system call sys$modify().
539 Unix filename version. */
540
541static int
542vms_convert_to_var_unix_filename (const char *unix_filename)
543{
544 if (decc$to_vms (unix_filename, &vms_convert_to_var_1, 0, 1) != 1)
545 return FALSE;
546 return TRUE;
547}
548#endif /* VMS */
549
252b5132
RH
550/* Called when the BFD is being closed to do any necessary cleanup. */
551
b34976b6 552static bfd_boolean
7920ce38 553vms_close_and_cleanup (bfd * abfd)
252b5132 554{
e4d2e665
TG
555 vms_debug2 ((1, "vms_close_and_cleanup (%p)\n", abfd));
556
0c376465 557 if (abfd == NULL || abfd->tdata.any == NULL)
b34976b6 558 return TRUE;
252b5132 559
8a0c27cd 560 if (PRIV (vms_buf) != NULL)
487e54f2 561 free (PRIV (vms_buf));
252b5132 562
8a0c27cd 563 if (PRIV (sections) != NULL)
487e54f2 564 free (PRIV (sections));
252b5132 565
8a0c27cd 566 if (PRIV (vms_symbol_table))
487e54f2 567 bfd_hash_table_free (PRIV (vms_symbol_table));
252b5132 568
0c376465
TG
569 bfd_map_over_sections (abfd, free_reloc_stream, NULL);
570
487e54f2 571 bfd_release (abfd, abfd->tdata.any);
252b5132
RH
572 abfd->tdata.any = NULL;
573
0c376465
TG
574#ifdef VMS
575 if (abfd->direction == write_direction)
576 {
577 /* Last step on VMS is to convert the file to variable record length
578 format. */
579 if (bfd_cache_close (abfd) != TRUE)
580 return FALSE;
581 if (vms_convert_to_var_unix_filename (abfd->filename) != TRUE)
582 return FALSE;
583 }
584#endif
585
b34976b6 586 return TRUE;
252b5132
RH
587}
588
252b5132
RH
589/* Called when a new section is created. */
590
b34976b6 591static bfd_boolean
7920ce38 592vms_new_section_hook (bfd * abfd, asection *section)
252b5132 593{
0c376465
TG
594 bfd_size_type amt;
595
4e6bfe8a
AM
596 /* Count hasn't been incremented yet. */
597 unsigned int section_count = abfd->section_count + 1;
598
e4d2e665
TG
599 vms_debug2 ((1, "vms_new_section_hook (%p, [%d]%s), count %d\n",
600 abfd, section->index, section->name, section_count));
0c376465
TG
601
602 bfd_set_section_alignment (abfd, section, 0);
252b5132 603
4e6bfe8a 604 if (section_count > PRIV (section_count))
252b5132 605 {
91d6fa6a 606 amt = section_count;
dc810e39 607 amt *= sizeof (asection *);
515ef31d 608 PRIV (sections) = bfd_realloc_or_free (PRIV (sections), amt);
7920ce38 609 if (PRIV (sections) == NULL)
b34976b6 610 return FALSE;
4e6bfe8a 611 PRIV (section_count) = section_count;
252b5132 612 }
0c376465 613
e4d2e665 614 vms_debug2 ((6, "section_count: %d\n", PRIV (section_count)));
0c376465 615
8a0c27cd 616 PRIV (sections)[section->index] = section;
0c376465 617
e4d2e665 618 vms_debug2 ((7, "%d: %s\n", section->index, section->name));
252b5132 619
0c376465
TG
620 amt = sizeof (struct vms_section_data_struct);
621 section->used_by_bfd = (PTR) bfd_zalloc (abfd, amt);
622 if (section->used_by_bfd == NULL)
623 return FALSE;
624
f592407e 625 return _bfd_generic_new_section_hook (abfd, section);
252b5132
RH
626}
627
252b5132
RH
628/* Read the contents of a section.
629 buf points to a buffer of buf_size bytes to be filled with
630 section data (starting at offset into section) */
631
b34976b6 632static bfd_boolean
7920ce38
NC
633vms_get_section_contents (bfd * abfd ATTRIBUTE_UNUSED,
634 asection *section ATTRIBUTE_UNUSED,
635 void * buf ATTRIBUTE_UNUSED,
636 file_ptr offset ATTRIBUTE_UNUSED,
637 bfd_size_type buf_size ATTRIBUTE_UNUSED)
252b5132 638{
0c376465
TG
639 bfd_size_type size = section->size;
640
e4d2e665
TG
641 vms_debug2 ((1, "vms_get_section_contents (%p, %s, %p, off %ld, size %d)\n",
642 abfd, section->name, buf, offset, (int)buf_size));
252b5132 643
0c376465
TG
644 if (section->contents)
645 abort ();
646
647 section->contents = (unsigned char *) bfd_malloc (size);
648
649 if (section->contents == NULL)
650 {
651 bfd_set_error (bfd_error_no_memory);
652 return FALSE;
653 }
654
655 if (bfd_seek (abfd, section->filepos, SEEK_SET))
656 {
657 bfd_set_error (bfd_error_file_truncated);
658 return FALSE;
659 }
660
661 if (bfd_bread (section->contents, size, abfd) != size)
662 {
663 bfd_set_error (bfd_error_file_truncated);
664 return FALSE;
665 }
666
667 section->flags |= SEC_IN_MEMORY;
668
669 if (buf)
670 memcpy (buf, section->contents + offset, (size_t) buf_size);
671
672 return TRUE;
252b5132
RH
673}
674
7920ce38 675/* Part 4.5, symbols. */
252b5132
RH
676
677/* Return the number of bytes required to store a vector of pointers
678 to asymbols for all the symbols in the BFD abfd, including a
679 terminal NULL pointer. If there are no symbols in the BFD,
680 then return 0. If an error occurs, return -1. */
681
682static long
7920ce38 683vms_get_symtab_upper_bound (bfd * abfd)
252b5132 684{
e4d2e665
TG
685 vms_debug2 ((1, "vms_get_symtab_upper_bound (%p), %d symbols\n",
686 abfd, PRIV (gsd_sym_count)));
687
7920ce38 688 return (PRIV (gsd_sym_count) + 1) * sizeof (asymbol *);
252b5132
RH
689}
690
252b5132
RH
691/* Copy symbols from hash table to symbol vector
692
6cee3f79 693 called from bfd_hash_traverse in vms_canonicalize_symtab
7920ce38 694 init counter to 0 if entry == 0. */
252b5132 695
b34976b6 696static bfd_boolean
7920ce38 697copy_symbols (struct bfd_hash_entry *entry, void * arg)
252b5132 698{
7920ce38 699 bfd * abfd = (bfd *) arg;
252b5132 700
7920ce38 701 if (entry == NULL) /* Init counter. */
8a0c27cd 702 PRIV (symnum) = 0;
7920ce38 703 else /* Fill vector, inc counter. */
8a0c27cd 704 PRIV (symcache)[PRIV (symnum)++] = ((vms_symbol_entry *)entry)->symbol;
252b5132 705
b34976b6 706 return TRUE;
252b5132
RH
707}
708
252b5132
RH
709/* Read the symbols from the BFD abfd, and fills in the vector
710 location with pointers to the symbols and a trailing NULL.
711
7920ce38 712 Return number of symbols read. */
252b5132
RH
713
714static long
7920ce38 715vms_canonicalize_symtab (bfd * abfd, asymbol **symbols)
252b5132 716{
e4d2e665 717 vms_debug2 ((1, "vms_canonicalize_symtab (%p, <ret>)\n", abfd));
252b5132 718
7920ce38
NC
719 /* Init counter. */
720 copy_symbols (NULL, abfd);
252b5132 721
7920ce38 722 /* Traverse table and fill symbols vector. */
8a0c27cd 723 PRIV (symcache) = symbols;
7920ce38 724 bfd_hash_traverse (PRIV (vms_symbol_table), copy_symbols, abfd);
252b5132 725
8a0c27cd 726 symbols[PRIV (gsd_sym_count)] = NULL;
252b5132 727
8a0c27cd 728 return PRIV (gsd_sym_count);
252b5132
RH
729}
730
252b5132
RH
731/* Print symbol to file according to how. how is one of
732 bfd_print_symbol_name just print the name
733 bfd_print_symbol_more print more (???)
7920ce38 734 bfd_print_symbol_all print all we know, which is not much right now :-). */
252b5132
RH
735
736static void
7920ce38
NC
737vms_print_symbol (bfd * abfd,
738 void * file,
739 asymbol *symbol,
740 bfd_print_symbol_type how)
252b5132 741{
e4d2e665
TG
742 vms_debug2 ((1, "vms_print_symbol (%p, %p, %p, %d)\n",
743 abfd, file, symbol, how));
252b5132
RH
744
745 switch (how)
746 {
747 case bfd_print_symbol_name:
748 case bfd_print_symbol_more:
55f2d5ed 749 fprintf ((FILE *)file," %s", symbol->name);
252b5132
RH
750 break;
751
252b5132
RH
752 case bfd_print_symbol_all:
753 {
dc810e39 754 const char *section_name = symbol->section->name;
252b5132 755
7920ce38 756 bfd_print_symbol_vandf (abfd, file, symbol);
252b5132 757
7920ce38 758 fprintf ((FILE *) file," %-8s %s", section_name, symbol->name);
252b5132
RH
759 }
760 break;
761 }
252b5132
RH
762}
763
252b5132
RH
764/* Return information about symbol in ret.
765
766 fill type, value and name
767 type:
768 A absolute
769 B bss segment symbol
770 C common symbol
771 D data segment symbol
772 f filename
773 t a static function symbol
774 T text segment symbol
775 U undefined
7920ce38 776 - debug. */
252b5132
RH
777
778static void
7920ce38
NC
779vms_get_symbol_info (bfd * abfd ATTRIBUTE_UNUSED,
780 asymbol *symbol,
781 symbol_info *ret)
252b5132
RH
782{
783 asection *sec;
784
e4d2e665 785 vms_debug2 ((1, "vms_get_symbol_info (%p, %p, %p)\n", abfd, symbol, ret));
252b5132
RH
786
787 sec = symbol->section;
788
7920ce38 789 if (ret == NULL)
252b5132
RH
790 return;
791
0c376465
TG
792 if (sec == 0)
793 ret->type = 'U';
794 else if (bfd_is_com_section (sec))
252b5132
RH
795 ret->type = 'C';
796 else if (bfd_is_abs_section (sec))
797 ret->type = 'A';
798 else if (bfd_is_und_section (sec))
799 ret->type = 'U';
800 else if (bfd_is_ind_section (sec))
801 ret->type = 'I';
802 else if (bfd_get_section_flags (abfd, sec) & SEC_CODE)
803 ret->type = 'T';
804 else if (bfd_get_section_flags (abfd, sec) & SEC_DATA)
805 ret->type = 'D';
806 else if (bfd_get_section_flags (abfd, sec) & SEC_ALLOC)
807 ret->type = 'B';
808 else
809 ret->type = '-';
810
811 if (ret->type != 'U')
812 ret->value = symbol->value + symbol->section->vma;
813 else
814 ret->value = 0;
815 ret->name = symbol->name;
252b5132
RH
816}
817
b34976b6
AM
818/* Return TRUE if the given symbol sym in the BFD abfd is
819 a compiler generated local label, else return FALSE. */
252b5132 820
b34976b6 821static bfd_boolean
7920ce38
NC
822vms_bfd_is_local_label_name (bfd * abfd ATTRIBUTE_UNUSED,
823 const char *name)
252b5132 824{
e4d2e665 825 vms_debug2 ((1, "vms_bfd_is_local_label_name (%p, %s)\n", abfd, name));
252b5132
RH
826 return name[0] == '$';
827}
828
252b5132
RH
829/* Provided a BFD, a section and an offset into the section, calculate and
830 return the name of the source file and the line nearest to the wanted
831 location. */
832
b34976b6 833static bfd_boolean
7920ce38
NC
834vms_find_nearest_line (bfd * abfd ATTRIBUTE_UNUSED,
835 asection *section ATTRIBUTE_UNUSED,
836 asymbol **symbols ATTRIBUTE_UNUSED,
837 bfd_vma offset ATTRIBUTE_UNUSED,
838 const char **file ATTRIBUTE_UNUSED,
839 const char **func ATTRIBUTE_UNUSED,
840 unsigned int *line ATTRIBUTE_UNUSED)
252b5132 841{
e4d2e665
TG
842 vms_debug2 ((1, "vms_find_nearest_line (%p, %s, %p, %ld, ...)\n",
843 abfd, section->name, symbols, (long int)offset));
0c376465 844 return _bfd_vms_find_nearest_dst_line (abfd, section, symbols, offset, file, func, line);
252b5132
RH
845}
846
7920ce38 847/* Part 4.6, relocations. */
252b5132 848
0c376465 849/* Allocate the reloc buffer for the specified section. */
252b5132 850
0c376465
TG
851static void
852alloc_reloc_stream (bfd *abfd ATTRIBUTE_UNUSED, asection *section,
853 void *alloc_error)
252b5132 854{
0c376465
TG
855 unsigned char *ptr;
856
857 /* If there were no relocations, there is nothing to do. */
858 if (section->reloc_count == 0)
859 return;
860
861 ptr = bfd_malloc (vms_section_data (section)->reloc_size);
862 if (ptr == NULL)
863 {
864 *(bfd_boolean *)alloc_error = TRUE;
865 return;
866 }
867
868 vms_section_data (section)->reloc_stream = ptr;
869}
870
871/* Read in the relocs for the specified section and internalize them.
872
873 The implementation is loosely based on the SOM code and made up
874 of 3 distinct phases:
875
876 1. When the VMS object is opened and parsed, the number and the size
877 of the relocations are computed for all sections. This makes it
878 possible to know upfront both which sections have no relocs and
879 the size of the reloc buffers for the other sections, at virtually
880 no cost for consumers that don't care about relocs at all.
881
882 2. When vms_slurp_reloc_table is invoked for the first time on a section
883 with relocs, the object is traversed and all the reloc information
884 is saved in per-section reloc buffers. It would be very inefficient
885 to scan the whole file on each invocation, so we slurp for all the
886 sections at once.
887
888 3. On subsequent invocations of vms_slurp_reloc_table, the relocs for the
889 specified section are fetched from the buffer, decoded and internalized.
890 The buffer is then freed since the internalized relocs are attached to
891 the section, turning additional invocations of vms_slurp_reloc_table
892 on the same section into no-ops.
893
894 Since VMS objects have very few sections, it could be profitable to merge
895 phase #2 and phase #3, i.e. to decode and internalize the relocs for all
896 the sections at once. The current implementation is more elegant. */
897
898static bfd_boolean
899vms_slurp_reloc_table (bfd *abfd, asection *section, asymbol **symbols)
900{
901 arelent *internal_relocs;
902 bfd_size_type amt;
903 int err;
904
905 /* If there were no relocations, there is nothing to do. */
906 if (section->reloc_count == 0)
907 return TRUE;
908
909 /* Return saved information about the relocations if it is available. */
910 if (section->relocation != NULL)
911 return TRUE;
912
913 /* If the relocation stream has not been slurped, do it now. */
914 if (vms_section_data (section)->reloc_stream == NULL)
915 {
916 bfd_boolean alloc_error = FALSE;
917 int type;
918
919 /* Size the reloc buffer for each section. */
920 bfd_map_over_sections (abfd, alloc_reloc_stream, &alloc_error);
921 if (alloc_error)
922 return FALSE;
923
924 if (bfd_seek (abfd, 0, SEEK_SET) != 0)
925 return FALSE;
926
927 /* Reset section pointer. */
928 PRIV (image_section) = NULL;
929
930 do
931 {
932 type = _bfd_vms_get_object_record (abfd);
933 if (type != EOBJ_S_C_ETIR
934 && type != EOBJ_S_C_EDBG
935 && type != EOBJ_S_C_ETBT)
936 continue;
937 err = _bfd_vms_slurp_relocs (abfd);
938 if (err != 0)
939 {
e4d2e665 940 vms_debug2 ((2, "slurp relocs failed with %d\n", err));
0c376465
TG
941 return FALSE;
942 }
943 }
944 while (type != EOBJ_S_C_EEOM);
945 }
946
947 amt = section->reloc_count * sizeof (arelent);
948 internal_relocs = (arelent *) bfd_zalloc (abfd, amt);
949 if (internal_relocs == NULL)
950 return FALSE;
951
952 /* Decode and internalize the relocations. */
953 err = _bfd_vms_decode_relocs (abfd, internal_relocs, section, symbols);
954 if (err != 0)
955 {
e4d2e665 956 vms_debug2 ((2, "decode relocs failed with %d\n", err));
0c376465
TG
957 return FALSE;
958 }
959
960 /* We're done with the external relocations. Free them. */
961 free (vms_section_data (section)->reloc_stream);
962 vms_section_data (section)->reloc_stream = NULL;
963
964 /* Save our results and return success. */
965 section->relocation = internal_relocs;
966 return TRUE;
252b5132
RH
967}
968
0c376465
TG
969/* Return the number of bytes required to store the relocation
970 information associated with the given section. */
252b5132
RH
971
972static long
0c376465 973vms_get_reloc_upper_bound (bfd *abfd ATTRIBUTE_UNUSED, asection *section)
252b5132 974{
0c376465
TG
975 return (section->reloc_count + 1) * sizeof (arelent *);
976}
977
978/* Convert relocations from VMS (external) form into BFD internal
979 form. Return the number of relocations. */
980
981static long
982vms_canonicalize_reloc (bfd *abfd, asection *section, arelent **relptr,
983 asymbol **symbols)
984{
985 arelent *tblptr;
986 int count;
987
988 if (! vms_slurp_reloc_table (abfd, section, symbols))
989 return -1;
990
991 count = section->reloc_count;
992 tblptr = section->relocation;
993
994 while (count--)
995 *relptr++ = tblptr++;
996
997 *relptr = (arelent *) NULL;
998 return section->reloc_count;
252b5132 999}
7920ce38
NC
1000\f
1001/* This is just copied from ecoff-alpha, needs to be fixed probably. */
252b5132
RH
1002
1003/* How to process the various reloc types. */
1004
1005static bfd_reloc_status_type
7920ce38
NC
1006reloc_nil (bfd * abfd ATTRIBUTE_UNUSED,
1007 arelent *reloc ATTRIBUTE_UNUSED,
1008 asymbol *sym ATTRIBUTE_UNUSED,
1009 void * data ATTRIBUTE_UNUSED,
1010 asection *sec ATTRIBUTE_UNUSED,
1011 bfd *output_bfd ATTRIBUTE_UNUSED,
1012 char **error_message ATTRIBUTE_UNUSED)
252b5132
RH
1013{
1014#if VMS_DEBUG
7920ce38 1015 vms_debug (1, "reloc_nil (abfd %p, output_bfd %p)\n", abfd, output_bfd);
252b5132
RH
1016 vms_debug (2, "In section %s, symbol %s\n",
1017 sec->name, sym->name);
1018 vms_debug (2, "reloc sym %s, addr %08lx, addend %08lx, reloc is a %s\n",
1019 reloc->sym_ptr_ptr[0]->name,
1020 (unsigned long)reloc->address,
1021 (unsigned long)reloc->addend, reloc->howto->name);
1022 vms_debug (2, "data at %p\n", data);
7920ce38 1023 /* _bfd_hexdump (2, data, bfd_get_reloc_size (reloc->howto), 0); */
252b5132
RH
1024#endif
1025
1026 return bfd_reloc_ok;
1027}
1028
1029/* In case we're on a 32-bit machine, construct a 64-bit "-1" value
1030 from smaller values. Start with zero, widen, *then* decrement. */
1031#define MINUS_ONE (((bfd_vma)0) - 1)
1032
1033static reloc_howto_type alpha_howto_table[] =
1034{
7920ce38
NC
1035 HOWTO (ALPHA_R_IGNORE, /* Type. */
1036 0, /* Rightshift. */
1037 0, /* Size (0 = byte, 1 = short, 2 = long). */
1038 8, /* Bitsize. */
1039 TRUE, /* PC relative. */
1040 0, /* Bitpos. */
1041 complain_overflow_dont,/* Complain_on_overflow. */
1042 reloc_nil, /* Special_function. */
1043 "IGNORE", /* Name. */
1044 TRUE, /* Partial_inplace. */
1045 0, /* Source mask */
1046 0, /* Dest mask. */
1047 TRUE), /* PC rel offset. */
252b5132
RH
1048
1049 /* A 64 bit reference to a symbol. */
7920ce38
NC
1050 HOWTO (ALPHA_R_REFQUAD, /* Type. */
1051 0, /* Rightshift. */
1052 4, /* Size (0 = byte, 1 = short, 2 = long). */
1053 64, /* Bitsize. */
1054 FALSE, /* PC relative. */
1055 0, /* Bitpos. */
1056 complain_overflow_bitfield, /* Complain_on_overflow. */
1057 reloc_nil, /* Special_function. */
1058 "REFQUAD", /* Name. */
1059 TRUE, /* Partial_inplace. */
1060 MINUS_ONE, /* Source mask. */
1061 MINUS_ONE, /* Dest mask. */
1062 FALSE), /* PC rel offset. */
252b5132
RH
1063
1064 /* A 21 bit branch. The native assembler generates these for
1065 branches within the text segment, and also fills in the PC
1066 relative offset in the instruction. */
7920ce38
NC
1067 HOWTO (ALPHA_R_BRADDR, /* Type. */
1068 2, /* Rightshift. */
1069 2, /* Size (0 = byte, 1 = short, 2 = long). */
1070 21, /* Bitsize. */
1071 TRUE, /* PC relative. */
1072 0, /* Bitpos. */
1073 complain_overflow_signed, /* Complain_on_overflow. */
1074 reloc_nil, /* Special_function. */
1075 "BRADDR", /* Name. */
1076 TRUE, /* Partial_inplace. */
1077 0x1fffff, /* Source mask. */
1078 0x1fffff, /* Dest mask. */
1079 FALSE), /* PC rel offset. */
252b5132
RH
1080
1081 /* A hint for a jump to a register. */
7920ce38
NC
1082 HOWTO (ALPHA_R_HINT, /* Type. */
1083 2, /* Rightshift. */
1084 1, /* Size (0 = byte, 1 = short, 2 = long). */
1085 14, /* Bitsize. */
1086 TRUE, /* PC relative. */
1087 0, /* Bitpos. */
1088 complain_overflow_dont,/* Complain_on_overflow. */
1089 reloc_nil, /* Special_function. */
1090 "HINT", /* Name. */
1091 TRUE, /* Partial_inplace. */
1092 0x3fff, /* Source mask. */
1093 0x3fff, /* Dest mask. */
1094 FALSE), /* PC rel offset. */
252b5132
RH
1095
1096 /* 16 bit PC relative offset. */
7920ce38
NC
1097 HOWTO (ALPHA_R_SREL16, /* Type. */
1098 0, /* Rightshift. */
1099 1, /* Size (0 = byte, 1 = short, 2 = long). */
1100 16, /* Bitsize. */
1101 TRUE, /* PC relative. */
1102 0, /* Bitpos. */
1103 complain_overflow_signed, /* Complain_on_overflow. */
1104 reloc_nil, /* Special_function. */
1105 "SREL16", /* Name. */
1106 TRUE, /* Partial_inplace. */
1107 0xffff, /* Source mask. */
1108 0xffff, /* Dest mask. */
1109 FALSE), /* PC rel offset. */
252b5132
RH
1110
1111 /* 32 bit PC relative offset. */
7920ce38
NC
1112 HOWTO (ALPHA_R_SREL32, /* Type. */
1113 0, /* Rightshift. */
1114 2, /* Size (0 = byte, 1 = short, 2 = long). */
1115 32, /* Bitsize. */
1116 TRUE, /* PC relative. */
1117 0, /* Bitpos. */
1118 complain_overflow_signed, /* Complain_on_overflow. */
1119 reloc_nil, /* Special_function. */
1120 "SREL32", /* Name. */
1121 TRUE, /* Partial_inplace. */
1122 0xffffffff, /* Source mask. */
1123 0xffffffff, /* Dest mask. */
1124 FALSE), /* PC rel offset. */
252b5132
RH
1125
1126 /* A 64 bit PC relative offset. */
7920ce38
NC
1127 HOWTO (ALPHA_R_SREL64, /* Type. */
1128 0, /* Rightshift. */
1129 4, /* Size (0 = byte, 1 = short, 2 = long). */
1130 64, /* Bitsize. */
1131 TRUE, /* PC relative. */
1132 0, /* Bitpos. */
1133 complain_overflow_signed, /* Complain_on_overflow. */
1134 reloc_nil, /* Special_function. */
1135 "SREL64", /* Name. */
1136 TRUE, /* Partial_inplace. */
1137 MINUS_ONE, /* Source mask. */
1138 MINUS_ONE, /* Dest mask. */
1139 FALSE), /* PC rel offset. */
252b5132
RH
1140
1141 /* Push a value on the reloc evaluation stack. */
7920ce38
NC
1142 HOWTO (ALPHA_R_OP_PUSH, /* Type. */
1143 0, /* Rightshift. */
1144 0, /* Size (0 = byte, 1 = short, 2 = long). */
1145 0, /* Bitsize. */
1146 FALSE, /* PC relative. */
1147 0, /* Bitpos. */
1148 complain_overflow_dont,/* Complain_on_overflow. */
1149 reloc_nil, /* Special_function. */
1150 "OP_PUSH", /* Name. */
1151 FALSE, /* Partial_inplace. */
1152 0, /* Source mask. */
1153 0, /* Dest mask. */
1154 FALSE), /* PC rel offset. */
252b5132
RH
1155
1156 /* Store the value from the stack at the given address. Store it in
1157 a bitfield of size r_size starting at bit position r_offset. */
7920ce38
NC
1158 HOWTO (ALPHA_R_OP_STORE, /* Type. */
1159 0, /* Rightshift. */
1160 4, /* Size (0 = byte, 1 = short, 2 = long). */
1161 64, /* Bitsize. */
1162 FALSE, /* PC relative. */
1163 0, /* Bitpos. */
1164 complain_overflow_dont,/* Complain_on_overflow. */
1165 reloc_nil, /* Special_function. */
1166 "OP_STORE", /* Name. */
1167 FALSE, /* Partial_inplace. */
1168 0, /* Source mask. */
1169 MINUS_ONE, /* Dest mask. */
1170 FALSE), /* PC rel offset. */
252b5132
RH
1171
1172 /* Subtract the reloc address from the value on the top of the
1173 relocation stack. */
7920ce38
NC
1174 HOWTO (ALPHA_R_OP_PSUB, /* Type. */
1175 0, /* Rightshift. */
1176 0, /* Size (0 = byte, 1 = short, 2 = long). */
1177 0, /* Bitsize. */
1178 FALSE, /* PC relative. */
1179 0, /* Bitpos. */
1180 complain_overflow_dont,/* Complain_on_overflow. */
1181 reloc_nil, /* Special_function. */
1182 "OP_PSUB", /* Name. */
1183 FALSE, /* Partial_inplace. */
1184 0, /* Source mask. */
1185 0, /* Dest mask. */
1186 FALSE), /* PC rel offset. */
252b5132
RH
1187
1188 /* Shift the value on the top of the relocation stack right by the
1189 given value. */
7920ce38
NC
1190 HOWTO (ALPHA_R_OP_PRSHIFT, /* Type. */
1191 0, /* Rightshift. */
1192 0, /* Size (0 = byte, 1 = short, 2 = long). */
1193 0, /* Bitsize. */
1194 FALSE, /* PC relative. */
1195 0, /* Bitpos. */
1196 complain_overflow_dont,/* Complain_on_overflow. */
1197 reloc_nil, /* Special_function. */
1198 "OP_PRSHIFT", /* Name. */
1199 FALSE, /* Partial_inplace. */
1200 0, /* Source mask. */
1201 0, /* Dest mask. */
1202 FALSE), /* PC rel offset. */
252b5132
RH
1203
1204 /* Hack. Linkage is done by linker. */
7920ce38
NC
1205 HOWTO (ALPHA_R_LINKAGE, /* Type. */
1206 0, /* Rightshift. */
1207 8, /* Size (0 = byte, 1 = short, 2 = long). */
1208 256, /* Bitsize. */
1209 FALSE, /* PC relative. */
1210 0, /* Bitpos. */
1211 complain_overflow_dont,/* Complain_on_overflow. */
1212 reloc_nil, /* Special_function. */
1213 "LINKAGE", /* Name. */
1214 FALSE, /* Partial_inplace. */
1215 0, /* Source mask. */
1216 0, /* Dest mask. */
1217 FALSE), /* PC rel offset. */
252b5132
RH
1218
1219 /* A 32 bit reference to a symbol. */
7920ce38
NC
1220 HOWTO (ALPHA_R_REFLONG, /* Type. */
1221 0, /* Rightshift. */
1222 2, /* Size (0 = byte, 1 = short, 2 = long). */
1223 32, /* Bitsize. */
1224 FALSE, /* PC relative. */
1225 0, /* Bitpos. */
1226 complain_overflow_bitfield, /* Complain_on_overflow. */
1227 reloc_nil, /* Special_function. */
1228 "REFLONG", /* Name. */
1229 TRUE, /* Partial_inplace. */
1230 0xffffffff, /* Source mask. */
1231 0xffffffff, /* Dest mask. */
1232 FALSE), /* PC rel offset. */
252b5132
RH
1233
1234 /* A 64 bit reference to a procedure, written as 32 bit value. */
7920ce38
NC
1235 HOWTO (ALPHA_R_CODEADDR, /* Type. */
1236 0, /* Rightshift. */
1237 4, /* Size (0 = byte, 1 = short, 2 = long). */
1238 64, /* Bitsize. */
1239 FALSE, /* PC relative. */
1240 0, /* Bitpos. */
1241 complain_overflow_signed,/* Complain_on_overflow. */
1242 reloc_nil, /* Special_function. */
1243 "CODEADDR", /* Name. */
1244 FALSE, /* Partial_inplace. */
1245 0xffffffff, /* Source mask. */
1246 0xffffffff, /* Dest mask. */
1247 FALSE), /* PC rel offset. */
252b5132 1248
0c376465
TG
1249 HOWTO (ALPHA_R_NOP, /* Type. */
1250 0, /* Rightshift. */
1251 3, /* Size (0 = byte, 1 = short, 2 = long). */
1252 0, /* Bitsize. */
1253 /* The following value must match that of ALPHA_R_BSR/ALPHA_R_BOH
1254 because the calculations for the 3 relocations are the same.
1255 See B.4.5.2 of the OpenVMS Linker Utility Manual. */
1256 TRUE, /* PC relative. */
1257 0, /* Bitpos. */
1258 complain_overflow_dont,/* Complain_on_overflow. */
1259 reloc_nil, /* Special_function. */
1260 "NOP", /* Name. */
1261 FALSE, /* Partial_inplace. */
1262 0xffffffff, /* Source mask. */
1263 0xffffffff, /* Dest mask. */
1264 FALSE), /* PC rel offset. */
1265
1266 HOWTO (ALPHA_R_BSR, /* Type. */
1267 0, /* Rightshift. */
1268 3, /* Size (0 = byte, 1 = short, 2 = long). */
1269 0, /* Bitsize. */
1270 TRUE, /* PC relative. */
1271 0, /* Bitpos. */
1272 complain_overflow_dont,/* Complain_on_overflow. */
1273 reloc_nil, /* Special_function. */
1274 "BSR", /* Name. */
1275 FALSE, /* Partial_inplace. */
1276 0xffffffff, /* Source mask. */
1277 0xffffffff, /* Dest mask. */
1278 FALSE), /* PC rel offset. */
1279
1280 HOWTO (ALPHA_R_LDA, /* Type. */
1281 0, /* Rightshift. */
1282 3, /* Size (0 = byte, 1 = short, 2 = long). */
1283 0, /* Bitsize. */
1284 FALSE, /* PC relative. */
1285 0, /* Bitpos. */
1286 complain_overflow_dont,/* Complain_on_overflow. */
1287 reloc_nil, /* Special_function. */
1288 "LDA", /* Name. */
1289 FALSE, /* Partial_inplace. */
1290 0xffffffff, /* Source mask. */
1291 0xffffffff, /* Dest mask. */
1292 FALSE), /* PC rel offset. */
1293
1294 HOWTO (ALPHA_R_BOH, /* Type. */
1295 0, /* Rightshift. */
1296 3, /* Size (0 = byte, 1 = short, 2 = long, 3 = nil). */
1297 0, /* Bitsize. */
1298 TRUE, /* PC relative. */
1299 0, /* Bitpos. */
1300 complain_overflow_dont,/* Complain_on_overflow. */
1301 reloc_nil, /* Special_function. */
1302 "BOH", /* Name. */
1303 FALSE, /* Partial_inplace. */
1304 0xffffffff, /* Source mask. */
1305 0xffffffff, /* Dest mask. */
1306 FALSE), /* PC rel offset. */
252b5132
RH
1307};
1308
1309/* Return a pointer to a howto structure which, when invoked, will perform
1310 the relocation code on data from the architecture noted. */
1311
1312static const struct reloc_howto_struct *
7920ce38
NC
1313vms_bfd_reloc_type_lookup (bfd * abfd ATTRIBUTE_UNUSED,
1314 bfd_reloc_code_real_type code)
252b5132
RH
1315{
1316 int alpha_type;
1317
e4d2e665 1318 vms_debug2 ((1, "vms_bfd_reloc_type_lookup (%p, %d)\t", abfd, code));
252b5132
RH
1319
1320 switch (code)
1321 {
1322 case BFD_RELOC_16: alpha_type = ALPHA_R_SREL16; break;
1323 case BFD_RELOC_32: alpha_type = ALPHA_R_REFLONG; break;
1324 case BFD_RELOC_64: alpha_type = ALPHA_R_REFQUAD; break;
1325 case BFD_RELOC_CTOR: alpha_type = ALPHA_R_REFQUAD; break;
1326 case BFD_RELOC_23_PCREL_S2: alpha_type = ALPHA_R_BRADDR; break;
1327 case BFD_RELOC_ALPHA_HINT: alpha_type = ALPHA_R_HINT; break;
1328 case BFD_RELOC_16_PCREL: alpha_type = ALPHA_R_SREL16; break;
1329 case BFD_RELOC_32_PCREL: alpha_type = ALPHA_R_SREL32; break;
1330 case BFD_RELOC_64_PCREL: alpha_type = ALPHA_R_SREL64; break;
1331 case BFD_RELOC_ALPHA_LINKAGE: alpha_type = ALPHA_R_LINKAGE; break;
1332 case BFD_RELOC_ALPHA_CODEADDR: alpha_type = ALPHA_R_CODEADDR; break;
0c376465
TG
1333 case BFD_RELOC_ALPHA_NOP: alpha_type = ALPHA_R_NOP; break;
1334 case BFD_RELOC_ALPHA_BSR: alpha_type = ALPHA_R_BSR; break;
1335 case BFD_RELOC_ALPHA_LDA: alpha_type = ALPHA_R_LDA; break;
1336 case BFD_RELOC_ALPHA_BOH: alpha_type = ALPHA_R_BOH; break;
252b5132
RH
1337 default:
1338 (*_bfd_error_handler) ("reloc (%d) is *UNKNOWN*", code);
7920ce38 1339 return NULL;
252b5132 1340 }
e4d2e665 1341 vms_debug2 ((2, "reloc is %s\n", alpha_howto_table[alpha_type].name));
7920ce38 1342 return & alpha_howto_table[alpha_type];
252b5132
RH
1343}
1344
157090f7
AM
1345static reloc_howto_type *
1346vms_bfd_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
1347 const char *r_name)
1348{
1349 unsigned int i;
1350
1351 for (i = 0;
1352 i < sizeof (alpha_howto_table) / sizeof (alpha_howto_table[0]);
1353 i++)
1354 if (alpha_howto_table[i].name != NULL
1355 && strcasecmp (alpha_howto_table[i].name, r_name) == 0)
1356 return &alpha_howto_table[i];
1357
1358 return NULL;
1359}
1360
7920ce38 1361/* Part 4.7, writing an object file. */
252b5132
RH
1362
1363/* Set the architecture and machine type in BFD abfd to arch and mach.
1364 Find the correct pointer to a structure and insert it into the arch_info
1365 pointer. */
1366
b34976b6 1367static bfd_boolean
7920ce38
NC
1368vms_set_arch_mach (bfd * abfd,
1369 enum bfd_architecture arch ATTRIBUTE_UNUSED,
1370 unsigned long mach ATTRIBUTE_UNUSED)
252b5132 1371{
e4d2e665 1372 vms_debug2 ((1, "vms_set_arch_mach (%p, %d, %ld)\n", abfd, arch, mach));
252b5132 1373
0c376465
TG
1374 if (arch != bfd_arch_alpha
1375 && arch != bfd_arch_vax
1376 && arch != bfd_arch_unknown)
1377 return FALSE;
1378
1379 return bfd_default_set_arch_mach (abfd, arch, mach);
252b5132
RH
1380}
1381
252b5132 1382/* Sets the contents of the section section in BFD abfd to the data starting
0c376465
TG
1383 in memory at LOCATION. The data is written to the output section starting
1384 at offset offset for count bytes.
252b5132 1385
b34976b6 1386 Normally TRUE is returned, else FALSE. Possible error returns are:
252b5132
RH
1387 o bfd_error_no_contents - The output section does not have the
1388 SEC_HAS_CONTENTS attribute, so nothing can be written to it.
1389 o and some more too */
1390
b34976b6 1391static bfd_boolean
7920ce38
NC
1392vms_set_section_contents (bfd * abfd,
1393 asection *section,
1394 const void * location,
1395 file_ptr offset,
1396 bfd_size_type count)
252b5132
RH
1397{
1398#if VMS_DEBUG
7920ce38
NC
1399 vms_debug (1, "vms_set_section_contents (%p, sec %s, loc %p, off %ld, count %d)\n",
1400 abfd, section->name, location, (long int)offset, (int)count);
eea6121a 1401 vms_debug (2, "size %d\n", (int) section->size);
252b5132 1402#endif
0c376465
TG
1403 if (count == (bfd_size_type)0)
1404 return TRUE;
1405
1406 if (section->contents == NULL)
1407 section->contents = bfd_alloc (abfd, section->size);
1408 if (section->contents == NULL)
1409 return FALSE;
1410
1411 memcpy (section->contents + offset, location, (size_t) count);
1412 return TRUE;
252b5132 1413}
7920ce38
NC
1414\f
1415const bfd_target vms_alpha_vec =
1416{
1417 "vms-alpha", /* Name. */
1418 bfd_target_evax_flavour,
1419 BFD_ENDIAN_LITTLE, /* Data byte order is little. */
1420 BFD_ENDIAN_LITTLE, /* Header byte order is little. */
1421
0c376465 1422 (HAS_RELOC | EXEC_P | HAS_LINENO | HAS_DEBUG | HAS_SYMS | HAS_LOCALS
7920ce38
NC
1423 | WP_TEXT | D_PAGED), /* Object flags. */
1424 (SEC_ALLOC | SEC_LOAD | SEC_RELOC
1425 | SEC_READONLY | SEC_CODE | SEC_DATA
1426 | SEC_HAS_CONTENTS | SEC_IN_MEMORY), /* Sect flags. */
0c376465
TG
1427 0, /* symbol_leading_char. */
1428 ' ', /* ar_pad_char. */
1429 15, /* ar_max_namelen. */
7920ce38
NC
1430 bfd_getl64, bfd_getl_signed_64, bfd_putl64,
1431 bfd_getl32, bfd_getl_signed_32, bfd_putl32,
1432 bfd_getl16, bfd_getl_signed_16, bfd_putl16,
1433 bfd_getl64, bfd_getl_signed_64, bfd_putl64,
1434 bfd_getl32, bfd_getl_signed_32, bfd_putl32,
1435 bfd_getl16, bfd_getl_signed_16, bfd_putl16,
1436
1437 {_bfd_dummy_target, vms_object_p, /* bfd_check_format. */
e4d2e665 1438 _bfd_dummy_target, _bfd_dummy_target},
7920ce38 1439 {bfd_false, vms_mkobject, /* bfd_set_format. */
e4d2e665 1440 bfd_false, bfd_false},
7920ce38 1441 {bfd_false, vms_write_object_contents, /* bfd_write_contents. */
e4d2e665 1442 bfd_false, bfd_false},
7920ce38
NC
1443
1444 BFD_JUMP_TABLE_GENERIC (vms),
1445 BFD_JUMP_TABLE_COPY (vms),
e4d2e665
TG
1446 BFD_JUMP_TABLE_CORE (_bfd_nocore),
1447 BFD_JUMP_TABLE_ARCHIVE (_bfd_noarchive),
7920ce38
NC
1448 BFD_JUMP_TABLE_SYMBOLS (vms),
1449 BFD_JUMP_TABLE_RELOCS (vms),
1450 BFD_JUMP_TABLE_WRITE (vms),
e4d2e665
TG
1451 BFD_JUMP_TABLE_LINK (_bfd_nolink),
1452 BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
7920ce38
NC
1453
1454 NULL,
1455
0c376465 1456 (PTR) 0
7920ce38
NC
1457};
1458
1459const bfd_target vms_vax_vec =
1460{
1461 "vms-vax", /* Name. */
1462 bfd_target_ovax_flavour,
1463 BFD_ENDIAN_LITTLE, /* Data byte order is little. */
1464 BFD_ENDIAN_LITTLE, /* Header byte order is little. */
1465
1466 (HAS_RELOC | HAS_SYMS /* Object flags. */
1467 | WP_TEXT | D_PAGED
1468 | HAS_LINENO | HAS_DEBUG | HAS_LOCALS),
1469
1470 (SEC_ALLOC | SEC_LOAD | SEC_RELOC
1471 | SEC_READONLY | SEC_CODE | SEC_DATA
1472 | SEC_HAS_CONTENTS | SEC_IN_MEMORY), /* Sect flags. */
0c376465
TG
1473 0, /* symbol_leading_char */
1474 ' ', /* ar_pad_char */
1475 15, /* ar_max_namelen */
7920ce38
NC
1476 bfd_getl64, bfd_getl_signed_64, bfd_putl64,
1477 bfd_getl32, bfd_getl_signed_32, bfd_putl32,
1478 bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* Data. */
1479 bfd_getl64, bfd_getl_signed_64, bfd_putl64,
1480 bfd_getl32, bfd_getl_signed_32, bfd_putl32,
0c376465 1481 bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* Hdrs. */
7920ce38
NC
1482
1483 {_bfd_dummy_target, vms_object_p, /* bfd_check_format. */
e4d2e665 1484 _bfd_dummy_target, _bfd_dummy_target},
7920ce38 1485 {bfd_false, vms_mkobject, /* bfd_set_format. */
e4d2e665 1486 bfd_false, bfd_false},
7920ce38 1487 {bfd_false, vms_write_object_contents, /* bfd_write_contents. */
e4d2e665 1488 bfd_false, bfd_false},
7920ce38
NC
1489
1490 BFD_JUMP_TABLE_GENERIC (vms),
1491 BFD_JUMP_TABLE_COPY (vms),
e4d2e665
TG
1492 BFD_JUMP_TABLE_CORE (_bfd_nocore),
1493 BFD_JUMP_TABLE_ARCHIVE (_bfd_noarchive),
7920ce38
NC
1494 BFD_JUMP_TABLE_SYMBOLS (vms),
1495 BFD_JUMP_TABLE_RELOCS (vms),
1496 BFD_JUMP_TABLE_WRITE (vms),
e4d2e665
TG
1497 BFD_JUMP_TABLE_LINK (_bfd_nolink),
1498 BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
7920ce38
NC
1499
1500 NULL,
1501
0c376465 1502 (PTR) 0
7920ce38 1503};
This page took 0.606015 seconds and 4 git commands to generate.