OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-old/] [gdb-7.1/] [bfd/] [vms.c] - Blame information for rev 853

Go to most recent revision | Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.