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

Subversion Repositories or1k

[/] [or1k/] [tags/] [VER_5_3/] [gdb-5.3/] [bfd/] [coff-alpha.c] - Blame information for rev 1783

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

Line No. Rev Author Line
1 1181 sfurman
/* BFD back-end for ALPHA Extended-Coff files.
2
   Copyright 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002
3
   Free Software Foundation, Inc.
4
   Modified from coff-mips.c by Steve Chamberlain <sac@cygnus.com> and
5
   Ian Lance Taylor <ian@cygnus.com>.
6
 
7
This file is part of BFD, the Binary File Descriptor library.
8
 
9
This program is free software; you can redistribute it and/or modify
10
it under the terms of the GNU General Public License as published by
11
the Free Software Foundation; either version 2 of the License, or
12
(at your option) any later version.
13
 
14
This program is distributed in the hope that it will be useful,
15
but WITHOUT ANY WARRANTY; without even the implied warranty of
16
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17
GNU General Public License for more details.
18
 
19
You should have received a copy of the GNU General Public License
20
along with this program; if not, write to the Free Software
21
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
22
 
23
#include "bfd.h"
24
#include "sysdep.h"
25
#include "bfdlink.h"
26
#include "libbfd.h"
27
#include "coff/internal.h"
28
#include "coff/sym.h"
29
#include "coff/symconst.h"
30
#include "coff/ecoff.h"
31
#include "coff/alpha.h"
32
#include "aout/ar.h"
33
#include "libcoff.h"
34
#include "libecoff.h"
35
 
36
/* Prototypes for static functions.  */
37
 
38
static const bfd_target *alpha_ecoff_object_p PARAMS ((bfd *));
39
static boolean alpha_ecoff_bad_format_hook PARAMS ((bfd *abfd, PTR filehdr));
40
static PTR alpha_ecoff_mkobject_hook PARAMS ((bfd *, PTR filehdr, PTR aouthdr));
41
static void alpha_ecoff_swap_reloc_in PARAMS ((bfd *, PTR,
42
                                              struct internal_reloc *));
43
static void alpha_ecoff_swap_reloc_out PARAMS ((bfd *,
44
                                               const struct internal_reloc *,
45
                                               PTR));
46
static void alpha_adjust_reloc_in PARAMS ((bfd *,
47
                                           const struct internal_reloc *,
48
                                           arelent *));
49
static void alpha_adjust_reloc_out PARAMS ((bfd *, const arelent *,
50
                                            struct internal_reloc *));
51
static reloc_howto_type *alpha_bfd_reloc_type_lookup
52
 PARAMS ((bfd *, bfd_reloc_code_real_type));
53
static bfd_byte *alpha_ecoff_get_relocated_section_contents
54
  PARAMS ((bfd *abfd, struct bfd_link_info *, struct bfd_link_order *,
55
           bfd_byte *data, boolean relocateable, asymbol **symbols));
56
static bfd_vma alpha_convert_external_reloc
57
  PARAMS ((bfd *, struct bfd_link_info *, bfd *, struct external_reloc *,
58
           struct ecoff_link_hash_entry *));
59
static boolean alpha_relocate_section PARAMS ((bfd *, struct bfd_link_info *,
60
                                               bfd *, asection *,
61
                                               bfd_byte *, PTR));
62
static boolean alpha_adjust_headers
63
  PARAMS ((bfd *, struct internal_filehdr *, struct internal_aouthdr *));
64
static PTR alpha_ecoff_read_ar_hdr PARAMS ((bfd *));
65
static bfd *alpha_ecoff_get_elt_at_filepos PARAMS ((bfd *, file_ptr));
66
static bfd *alpha_ecoff_openr_next_archived_file PARAMS ((bfd *, bfd *));
67
static bfd *alpha_ecoff_get_elt_at_index PARAMS ((bfd *, symindex));
68
 
69
/* ECOFF has COFF sections, but the debugging information is stored in
70
   a completely different format.  ECOFF targets use some of the
71
   swapping routines from coffswap.h, and some of the generic COFF
72
   routines in coffgen.c, but, unlike the real COFF targets, do not
73
   use coffcode.h itself.
74
 
75
   Get the generic COFF swapping routines, except for the reloc,
76
   symbol, and lineno ones.  Give them ecoff names.  Define some
77
   accessor macros for the large sizes used for Alpha ECOFF.  */
78
 
79
#define GET_FILEHDR_SYMPTR H_GET_64
80
#define PUT_FILEHDR_SYMPTR H_PUT_64
81
#define GET_AOUTHDR_TSIZE H_GET_64
82
#define PUT_AOUTHDR_TSIZE H_PUT_64
83
#define GET_AOUTHDR_DSIZE H_GET_64
84
#define PUT_AOUTHDR_DSIZE H_PUT_64
85
#define GET_AOUTHDR_BSIZE H_GET_64
86
#define PUT_AOUTHDR_BSIZE H_PUT_64
87
#define GET_AOUTHDR_ENTRY H_GET_64
88
#define PUT_AOUTHDR_ENTRY H_PUT_64
89
#define GET_AOUTHDR_TEXT_START H_GET_64
90
#define PUT_AOUTHDR_TEXT_START H_PUT_64
91
#define GET_AOUTHDR_DATA_START H_GET_64
92
#define PUT_AOUTHDR_DATA_START H_PUT_64
93
#define GET_SCNHDR_PADDR H_GET_64
94
#define PUT_SCNHDR_PADDR H_PUT_64
95
#define GET_SCNHDR_VADDR H_GET_64
96
#define PUT_SCNHDR_VADDR H_PUT_64
97
#define GET_SCNHDR_SIZE H_GET_64
98
#define PUT_SCNHDR_SIZE H_PUT_64
99
#define GET_SCNHDR_SCNPTR H_GET_64
100
#define PUT_SCNHDR_SCNPTR H_PUT_64
101
#define GET_SCNHDR_RELPTR H_GET_64
102
#define PUT_SCNHDR_RELPTR H_PUT_64
103
#define GET_SCNHDR_LNNOPTR H_GET_64
104
#define PUT_SCNHDR_LNNOPTR H_PUT_64
105
 
106
#define ALPHAECOFF
107
 
108
#define NO_COFF_RELOCS
109
#define NO_COFF_SYMBOLS
110
#define NO_COFF_LINENOS
111
#define coff_swap_filehdr_in alpha_ecoff_swap_filehdr_in
112
#define coff_swap_filehdr_out alpha_ecoff_swap_filehdr_out
113
#define coff_swap_aouthdr_in alpha_ecoff_swap_aouthdr_in
114
#define coff_swap_aouthdr_out alpha_ecoff_swap_aouthdr_out
115
#define coff_swap_scnhdr_in alpha_ecoff_swap_scnhdr_in
116
#define coff_swap_scnhdr_out alpha_ecoff_swap_scnhdr_out
117
#include "coffswap.h"
118
 
119
/* Get the ECOFF swapping routines.  */
120
#define ECOFF_64
121
#include "ecoffswap.h"
122
 
123
/* How to process the various reloc types.  */
124
 
125
static bfd_reloc_status_type
126
reloc_nil PARAMS ((bfd *, arelent *, asymbol *, PTR,
127
                   asection *, bfd *, char **));
128
 
129
static bfd_reloc_status_type
130
reloc_nil (abfd, reloc, sym, data, sec, output_bfd, error_message)
131
     bfd *abfd ATTRIBUTE_UNUSED;
132
     arelent *reloc ATTRIBUTE_UNUSED;
133
     asymbol *sym ATTRIBUTE_UNUSED;
134
     PTR data ATTRIBUTE_UNUSED;
135
     asection *sec ATTRIBUTE_UNUSED;
136
     bfd *output_bfd ATTRIBUTE_UNUSED;
137
     char **error_message ATTRIBUTE_UNUSED;
138
{
139
  return bfd_reloc_ok;
140
}
141
 
142
/* In case we're on a 32-bit machine, construct a 64-bit "-1" value
143
   from smaller values.  Start with zero, widen, *then* decrement.  */
144
#define MINUS_ONE       (((bfd_vma)0) - 1)
145
 
146
static reloc_howto_type alpha_howto_table[] =
147
{
148
  /* Reloc type 0 is ignored by itself.  However, it appears after a
149
     GPDISP reloc to identify the location where the low order 16 bits
150
     of the gp register are loaded.  */
151
  HOWTO (ALPHA_R_IGNORE,        /* type */
152
         0,                      /* rightshift */
153
         0,                      /* size (0 = byte, 1 = short, 2 = long) */
154
         8,                     /* bitsize */
155
         true,                  /* pc_relative */
156
         0,                      /* bitpos */
157
         complain_overflow_dont, /* complain_on_overflow */
158
         reloc_nil,             /* special_function */
159
         "IGNORE",              /* name */
160
         true,                  /* partial_inplace */
161
         0,                      /* src_mask */
162
         0,                      /* dst_mask */
163
         true),                 /* pcrel_offset */
164
 
165
  /* A 32 bit reference to a symbol.  */
166
  HOWTO (ALPHA_R_REFLONG,       /* type */
167
         0,                      /* rightshift */
168
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
169
         32,                    /* bitsize */
170
         false,                 /* pc_relative */
171
         0,                      /* bitpos */
172
         complain_overflow_bitfield, /* complain_on_overflow */
173
         0,                      /* special_function */
174
         "REFLONG",             /* name */
175
         true,                  /* partial_inplace */
176
         0xffffffff,            /* src_mask */
177
         0xffffffff,            /* dst_mask */
178
         false),                /* pcrel_offset */
179
 
180
  /* A 64 bit reference to a symbol.  */
181
  HOWTO (ALPHA_R_REFQUAD,       /* type */
182
         0,                      /* rightshift */
183
         4,                     /* size (0 = byte, 1 = short, 2 = long) */
184
         64,                    /* bitsize */
185
         false,                 /* pc_relative */
186
         0,                      /* bitpos */
187
         complain_overflow_bitfield, /* complain_on_overflow */
188
         0,                      /* special_function */
189
         "REFQUAD",             /* name */
190
         true,                  /* partial_inplace */
191
         MINUS_ONE,             /* src_mask */
192
         MINUS_ONE,             /* dst_mask */
193
         false),                /* pcrel_offset */
194
 
195
  /* A 32 bit GP relative offset.  This is just like REFLONG except
196
     that when the value is used the value of the gp register will be
197
     added in.  */
198
  HOWTO (ALPHA_R_GPREL32,       /* type */
199
         0,                      /* rightshift */
200
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
201
         32,                    /* bitsize */
202
         false,                 /* pc_relative */
203
         0,                      /* bitpos */
204
         complain_overflow_bitfield, /* complain_on_overflow */
205
         0,                      /* special_function */
206
         "GPREL32",             /* name */
207
         true,                  /* partial_inplace */
208
         0xffffffff,            /* src_mask */
209
         0xffffffff,            /* dst_mask */
210
         false),                /* pcrel_offset */
211
 
212
  /* Used for an instruction that refers to memory off the GP
213
     register.  The offset is 16 bits of the 32 bit instruction.  This
214
     reloc always seems to be against the .lita section.  */
215
  HOWTO (ALPHA_R_LITERAL,       /* type */
216
         0,                      /* rightshift */
217
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
218
         16,                    /* bitsize */
219
         false,                 /* pc_relative */
220
         0,                      /* bitpos */
221
         complain_overflow_signed, /* complain_on_overflow */
222
         0,                      /* special_function */
223
         "LITERAL",             /* name */
224
         true,                  /* partial_inplace */
225
         0xffff,                /* src_mask */
226
         0xffff,                /* dst_mask */
227
         false),                /* pcrel_offset */
228
 
229
  /* This reloc only appears immediately following a LITERAL reloc.
230
     It identifies a use of the literal.  It seems that the linker can
231
     use this to eliminate a portion of the .lita section.  The symbol
232
     index is special: 1 means the literal address is in the base
233
     register of a memory format instruction; 2 means the literal
234
     address is in the byte offset register of a byte-manipulation
235
     instruction; 3 means the literal address is in the target
236
     register of a jsr instruction.  This does not actually do any
237
     relocation.  */
238
  HOWTO (ALPHA_R_LITUSE,        /* type */
239
         0,                      /* rightshift */
240
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
241
         32,                    /* bitsize */
242
         false,                 /* pc_relative */
243
         0,                      /* bitpos */
244
         complain_overflow_dont, /* complain_on_overflow */
245
         reloc_nil,             /* special_function */
246
         "LITUSE",              /* name */
247
         false,                 /* partial_inplace */
248
         0,                      /* src_mask */
249
         0,                      /* dst_mask */
250
         false),                /* pcrel_offset */
251
 
252
  /* Load the gp register.  This is always used for a ldah instruction
253
     which loads the upper 16 bits of the gp register.  The next reloc
254
     will be an IGNORE reloc which identifies the location of the lda
255
     instruction which loads the lower 16 bits.  The symbol index of
256
     the GPDISP instruction appears to actually be the number of bytes
257
     between the ldah and lda instructions.  This gives two different
258
     ways to determine where the lda instruction is; I don't know why
259
     both are used.  The value to use for the relocation is the
260
     difference between the GP value and the current location; the
261
     load will always be done against a register holding the current
262
     address.  */
263
  HOWTO (ALPHA_R_GPDISP,        /* type */
264
         16,                    /* rightshift */
265
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
266
         16,                    /* bitsize */
267
         true,                  /* pc_relative */
268
         0,                      /* bitpos */
269
         complain_overflow_dont, /* complain_on_overflow */
270
         reloc_nil,             /* special_function */
271
         "GPDISP",              /* name */
272
         true,                  /* partial_inplace */
273
         0xffff,                /* src_mask */
274
         0xffff,                /* dst_mask */
275
         true),                 /* pcrel_offset */
276
 
277
  /* A 21 bit branch.  The native assembler generates these for
278
     branches within the text segment, and also fills in the PC
279
     relative offset in the instruction.  */
280
  HOWTO (ALPHA_R_BRADDR,        /* type */
281
         2,                     /* rightshift */
282
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
283
         21,                    /* bitsize */
284
         true,                  /* pc_relative */
285
         0,                      /* bitpos */
286
         complain_overflow_signed, /* complain_on_overflow */
287
         0,                      /* special_function */
288
         "BRADDR",              /* name */
289
         true,                  /* partial_inplace */
290
         0x1fffff,              /* src_mask */
291
         0x1fffff,              /* dst_mask */
292
         false),                /* pcrel_offset */
293
 
294
  /* A hint for a jump to a register.  */
295
  HOWTO (ALPHA_R_HINT,          /* type */
296
         2,                     /* rightshift */
297
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
298
         14,                    /* bitsize */
299
         true,                  /* pc_relative */
300
         0,                      /* bitpos */
301
         complain_overflow_dont, /* complain_on_overflow */
302
         0,                      /* special_function */
303
         "HINT",                /* name */
304
         true,                  /* partial_inplace */
305
         0x3fff,                /* src_mask */
306
         0x3fff,                /* dst_mask */
307
         false),                /* pcrel_offset */
308
 
309
  /* 16 bit PC relative offset.  */
310
  HOWTO (ALPHA_R_SREL16,        /* type */
311
         0,                      /* rightshift */
312
         1,                     /* size (0 = byte, 1 = short, 2 = long) */
313
         16,                    /* bitsize */
314
         true,                  /* pc_relative */
315
         0,                      /* bitpos */
316
         complain_overflow_signed, /* complain_on_overflow */
317
         0,                      /* special_function */
318
         "SREL16",              /* name */
319
         true,                  /* partial_inplace */
320
         0xffff,                /* src_mask */
321
         0xffff,                /* dst_mask */
322
         false),                /* pcrel_offset */
323
 
324
  /* 32 bit PC relative offset.  */
325
  HOWTO (ALPHA_R_SREL32,        /* type */
326
         0,                      /* rightshift */
327
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
328
         32,                    /* bitsize */
329
         true,                  /* pc_relative */
330
         0,                      /* bitpos */
331
         complain_overflow_signed, /* complain_on_overflow */
332
         0,                      /* special_function */
333
         "SREL32",              /* name */
334
         true,                  /* partial_inplace */
335
         0xffffffff,            /* src_mask */
336
         0xffffffff,            /* dst_mask */
337
         false),                /* pcrel_offset */
338
 
339
  /* A 64 bit PC relative offset.  */
340
  HOWTO (ALPHA_R_SREL64,        /* type */
341
         0,                      /* rightshift */
342
         4,                     /* size (0 = byte, 1 = short, 2 = long) */
343
         64,                    /* bitsize */
344
         true,                  /* pc_relative */
345
         0,                      /* bitpos */
346
         complain_overflow_signed, /* complain_on_overflow */
347
         0,                      /* special_function */
348
         "SREL64",              /* name */
349
         true,                  /* partial_inplace */
350
         MINUS_ONE,             /* src_mask */
351
         MINUS_ONE,             /* dst_mask */
352
         false),                /* pcrel_offset */
353
 
354
  /* Push a value on the reloc evaluation stack.  */
355
  HOWTO (ALPHA_R_OP_PUSH,       /* type */
356
         0,                      /* rightshift */
357
         0,                      /* size (0 = byte, 1 = short, 2 = long) */
358
         0,                      /* bitsize */
359
         false,                 /* pc_relative */
360
         0,                      /* bitpos */
361
         complain_overflow_dont, /* complain_on_overflow */
362
         0,                      /* special_function */
363
         "OP_PUSH",             /* name */
364
         false,                 /* partial_inplace */
365
         0,                      /* src_mask */
366
         0,                      /* dst_mask */
367
         false),                /* pcrel_offset */
368
 
369
  /* Store the value from the stack at the given address.  Store it in
370
     a bitfield of size r_size starting at bit position r_offset.  */
371
  HOWTO (ALPHA_R_OP_STORE,      /* type */
372
         0,                      /* rightshift */
373
         4,                     /* size (0 = byte, 1 = short, 2 = long) */
374
         64,                    /* bitsize */
375
         false,                 /* pc_relative */
376
         0,                      /* bitpos */
377
         complain_overflow_dont, /* complain_on_overflow */
378
         0,                      /* special_function */
379
         "OP_STORE",            /* name */
380
         false,                 /* partial_inplace */
381
         0,                      /* src_mask */
382
         MINUS_ONE,             /* dst_mask */
383
         false),                /* pcrel_offset */
384
 
385
  /* Subtract the reloc address from the value on the top of the
386
     relocation stack.  */
387
  HOWTO (ALPHA_R_OP_PSUB,       /* type */
388
         0,                      /* rightshift */
389
         0,                      /* size (0 = byte, 1 = short, 2 = long) */
390
         0,                      /* bitsize */
391
         false,                 /* pc_relative */
392
         0,                      /* bitpos */
393
         complain_overflow_dont, /* complain_on_overflow */
394
         0,                      /* special_function */
395
         "OP_PSUB",             /* name */
396
         false,                 /* partial_inplace */
397
         0,                      /* src_mask */
398
         0,                      /* dst_mask */
399
         false),                /* pcrel_offset */
400
 
401
  /* Shift the value on the top of the relocation stack right by the
402
     given value.  */
403
  HOWTO (ALPHA_R_OP_PRSHIFT,    /* type */
404
         0,                      /* rightshift */
405
         0,                      /* size (0 = byte, 1 = short, 2 = long) */
406
         0,                      /* bitsize */
407
         false,                 /* pc_relative */
408
         0,                      /* bitpos */
409
         complain_overflow_dont, /* complain_on_overflow */
410
         0,                      /* special_function */
411
         "OP_PRSHIFT",          /* name */
412
         false,                 /* partial_inplace */
413
         0,                      /* src_mask */
414
         0,                      /* dst_mask */
415
         false),                /* pcrel_offset */
416
 
417
  /* Adjust the GP value for a new range in the object file.  */
418
  HOWTO (ALPHA_R_GPVALUE,       /* type */
419
         0,                      /* rightshift */
420
         0,                      /* size (0 = byte, 1 = short, 2 = long) */
421
         0,                      /* bitsize */
422
         false,                 /* pc_relative */
423
         0,                      /* bitpos */
424
         complain_overflow_dont, /* complain_on_overflow */
425
         0,                      /* special_function */
426
         "GPVALUE",             /* name */
427
         false,                 /* partial_inplace */
428
         0,                      /* src_mask */
429
         0,                      /* dst_mask */
430
         false)                 /* pcrel_offset */
431
};
432
 
433
/* Recognize an Alpha ECOFF file.  */
434
 
435
static const bfd_target *
436
alpha_ecoff_object_p (abfd)
437
     bfd *abfd;
438
{
439
  static const bfd_target *ret;
440
 
441
  ret = coff_object_p (abfd);
442
 
443
  if (ret != NULL)
444
    {
445
      asection *sec;
446
 
447
      /* Alpha ECOFF has a .pdata section.  The lnnoptr field of the
448
         .pdata section is the number of entries it contains.  Each
449
         entry takes up 8 bytes.  The number of entries is required
450
         since the section is aligned to a 16 byte boundary.  When we
451
         link .pdata sections together, we do not want to include the
452
         alignment bytes.  We handle this on input by faking the size
453
         of the .pdata section to remove the unwanted alignment bytes.
454
         On output we will set the lnnoptr field and force the
455
         alignment.  */
456
      sec = bfd_get_section_by_name (abfd, _PDATA);
457
      if (sec != (asection *) NULL)
458
        {
459
          bfd_size_type size;
460
 
461
          size = sec->line_filepos * 8;
462
          BFD_ASSERT (size == bfd_section_size (abfd, sec)
463
                      || size + 8 == bfd_section_size (abfd, sec));
464
          if (! bfd_set_section_size (abfd, sec, size))
465
            return NULL;
466
        }
467
    }
468
 
469
  return ret;
470
}
471
 
472
/* See whether the magic number matches.  */
473
 
474
static boolean
475
alpha_ecoff_bad_format_hook (abfd, filehdr)
476
     bfd *abfd ATTRIBUTE_UNUSED;
477
     PTR filehdr;
478
{
479
  struct internal_filehdr *internal_f = (struct internal_filehdr *) filehdr;
480
 
481
  if (ALPHA_ECOFF_BADMAG (*internal_f))
482
    return false;
483
 
484
  return true;
485
}
486
 
487
/* This is a hook called by coff_real_object_p to create any backend
488
   specific information.  */
489
 
490
static PTR
491
alpha_ecoff_mkobject_hook (abfd, filehdr, aouthdr)
492
     bfd *abfd;
493
     PTR filehdr;
494
     PTR aouthdr;
495
{
496
  PTR ecoff;
497
 
498
  ecoff = _bfd_ecoff_mkobject_hook (abfd, filehdr, aouthdr);
499
 
500
  if (ecoff != NULL)
501
    {
502
      struct internal_filehdr *internal_f = (struct internal_filehdr *) filehdr;
503
 
504
      /* Set additional BFD flags according to the object type from the
505
         machine specific file header flags.  */
506
      switch (internal_f->f_flags & F_ALPHA_OBJECT_TYPE_MASK)
507
        {
508
        case F_ALPHA_SHARABLE:
509
          abfd->flags |= DYNAMIC;
510
          break;
511
        case F_ALPHA_CALL_SHARED:
512
          /* Always executable if using shared libraries as the run time
513
             loader might resolve undefined references.  */
514
          abfd->flags |= (DYNAMIC | EXEC_P);
515
          break;
516
        }
517
    }
518
  return ecoff;
519
}
520
 
521
/* Reloc handling.  */
522
 
523
/* Swap a reloc in.  */
524
 
525
static void
526
alpha_ecoff_swap_reloc_in (abfd, ext_ptr, intern)
527
     bfd *abfd;
528
     PTR ext_ptr;
529
     struct internal_reloc *intern;
530
{
531
  const RELOC *ext = (RELOC *) ext_ptr;
532
 
533
  intern->r_vaddr = H_GET_64 (abfd, ext->r_vaddr);
534
  intern->r_symndx = H_GET_32 (abfd, ext->r_symndx);
535
 
536
  BFD_ASSERT (bfd_header_little_endian (abfd));
537
 
538
  intern->r_type = ((ext->r_bits[0] & RELOC_BITS0_TYPE_LITTLE)
539
                    >> RELOC_BITS0_TYPE_SH_LITTLE);
540
  intern->r_extern = (ext->r_bits[1] & RELOC_BITS1_EXTERN_LITTLE) != 0;
541
  intern->r_offset = ((ext->r_bits[1] & RELOC_BITS1_OFFSET_LITTLE)
542
                      >> RELOC_BITS1_OFFSET_SH_LITTLE);
543
  /* Ignored the reserved bits.  */
544
  intern->r_size = ((ext->r_bits[3] & RELOC_BITS3_SIZE_LITTLE)
545
                    >> RELOC_BITS3_SIZE_SH_LITTLE);
546
 
547
  if (intern->r_type == ALPHA_R_LITUSE
548
      || intern->r_type == ALPHA_R_GPDISP)
549
    {
550
      /* Handle the LITUSE and GPDISP relocs specially.  Its symndx
551
         value is not actually a symbol index, but is instead a
552
         special code.  We put the code in the r_size field, and
553
         clobber the symndx.  */
554
      if (intern->r_size != 0)
555
        abort ();
556
      intern->r_size = intern->r_symndx;
557
      intern->r_symndx = RELOC_SECTION_NONE;
558
    }
559
  else if (intern->r_type == ALPHA_R_IGNORE)
560
    {
561
      /* The IGNORE reloc generally follows a GPDISP reloc, and is
562
         against the .lita section.  The section is irrelevant.  */
563
      if (! intern->r_extern &&
564
          intern->r_symndx == RELOC_SECTION_ABS)
565
        abort ();
566
      if (! intern->r_extern && intern->r_symndx == RELOC_SECTION_LITA)
567
        intern->r_symndx = RELOC_SECTION_ABS;
568
    }
569
}
570
 
571
/* Swap a reloc out.  */
572
 
573
static void
574
alpha_ecoff_swap_reloc_out (abfd, intern, dst)
575
     bfd *abfd;
576
     const struct internal_reloc *intern;
577
     PTR dst;
578
{
579
  RELOC *ext = (RELOC *) dst;
580
  long symndx;
581
  unsigned char size;
582
 
583
  /* Undo the hackery done in swap_reloc_in.  */
584
  if (intern->r_type == ALPHA_R_LITUSE
585
      || intern->r_type == ALPHA_R_GPDISP)
586
    {
587
      symndx = intern->r_size;
588
      size = 0;
589
    }
590
  else if (intern->r_type == ALPHA_R_IGNORE
591
           && ! intern->r_extern
592
           && intern->r_symndx == RELOC_SECTION_ABS)
593
    {
594
      symndx = RELOC_SECTION_LITA;
595
      size = intern->r_size;
596
    }
597
  else
598
    {
599
      symndx = intern->r_symndx;
600
      size = intern->r_size;
601
    }
602
 
603
  BFD_ASSERT (intern->r_extern
604
              || (intern->r_symndx >= 0 && intern->r_symndx <= 14));
605
 
606
  H_PUT_64 (abfd, intern->r_vaddr, ext->r_vaddr);
607
  H_PUT_32 (abfd, symndx, ext->r_symndx);
608
 
609
  BFD_ASSERT (bfd_header_little_endian (abfd));
610
 
611
  ext->r_bits[0] = ((intern->r_type << RELOC_BITS0_TYPE_SH_LITTLE)
612
                    & RELOC_BITS0_TYPE_LITTLE);
613
  ext->r_bits[1] = ((intern->r_extern ? RELOC_BITS1_EXTERN_LITTLE : 0)
614
                    | ((intern->r_offset << RELOC_BITS1_OFFSET_SH_LITTLE)
615
                       & RELOC_BITS1_OFFSET_LITTLE));
616
  ext->r_bits[2] = 0;
617
  ext->r_bits[3] = ((size << RELOC_BITS3_SIZE_SH_LITTLE)
618
                    & RELOC_BITS3_SIZE_LITTLE);
619
}
620
 
621
/* Finish canonicalizing a reloc.  Part of this is generic to all
622
   ECOFF targets, and that part is in ecoff.c.  The rest is done in
623
   this backend routine.  It must fill in the howto field.  */
624
 
625
static void
626
alpha_adjust_reloc_in (abfd, intern, rptr)
627
     bfd *abfd;
628
     const struct internal_reloc *intern;
629
     arelent *rptr;
630
{
631
  if (intern->r_type > ALPHA_R_GPVALUE)
632
    abort ();
633
 
634
  switch (intern->r_type)
635
    {
636
    case ALPHA_R_BRADDR:
637
    case ALPHA_R_SREL16:
638
    case ALPHA_R_SREL32:
639
    case ALPHA_R_SREL64:
640
      /* This relocs appear to be fully resolved when they are against
641
         internal symbols.  Against external symbols, BRADDR at least
642
         appears to be resolved against the next instruction.  */
643
      if (! intern->r_extern)
644
        rptr->addend = 0;
645
      else
646
        rptr->addend = - (intern->r_vaddr + 4);
647
      break;
648
 
649
    case ALPHA_R_GPREL32:
650
    case ALPHA_R_LITERAL:
651
      /* Copy the gp value for this object file into the addend, to
652
         ensure that we are not confused by the linker.  */
653
      if (! intern->r_extern)
654
        rptr->addend += ecoff_data (abfd)->gp;
655
      break;
656
 
657
    case ALPHA_R_LITUSE:
658
    case ALPHA_R_GPDISP:
659
      /* The LITUSE and GPDISP relocs do not use a symbol, or an
660
         addend, but they do use a special code.  Put this code in the
661
         addend field.  */
662
      rptr->addend = intern->r_size;
663
      break;
664
 
665
    case ALPHA_R_OP_STORE:
666
      /* The STORE reloc needs the size and offset fields.  We store
667
         them in the addend.  */
668
      BFD_ASSERT (intern->r_offset <= 256 && intern->r_size <= 256);
669
      rptr->addend = (intern->r_offset << 8) + intern->r_size;
670
      break;
671
 
672
    case ALPHA_R_OP_PUSH:
673
    case ALPHA_R_OP_PSUB:
674
    case ALPHA_R_OP_PRSHIFT:
675
      /* The PUSH, PSUB and PRSHIFT relocs do not actually use an
676
         address.  I believe that the address supplied is really an
677
         addend.  */
678
      rptr->addend = intern->r_vaddr;
679
      break;
680
 
681
    case ALPHA_R_GPVALUE:
682
      /* Set the addend field to the new GP value.  */
683
      rptr->addend = intern->r_symndx + ecoff_data (abfd)->gp;
684
      break;
685
 
686
    case ALPHA_R_IGNORE:
687
      /* If the type is ALPHA_R_IGNORE, make sure this is a reference
688
         to the absolute section so that the reloc is ignored.  For
689
         some reason the address of this reloc type is not adjusted by
690
         the section vma.  We record the gp value for this object file
691
         here, for convenience when doing the GPDISP relocation.  */
692
      rptr->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
693
      rptr->address = intern->r_vaddr;
694
      rptr->addend = ecoff_data (abfd)->gp;
695
      break;
696
 
697
    default:
698
      break;
699
    }
700
 
701
  rptr->howto = &alpha_howto_table[intern->r_type];
702
}
703
 
704
/* When writing out a reloc we need to pull some values back out of
705
   the addend field into the reloc.  This is roughly the reverse of
706
   alpha_adjust_reloc_in, except that there are several changes we do
707
   not need to undo.  */
708
 
709
static void
710
alpha_adjust_reloc_out (abfd, rel, intern)
711
     bfd *abfd ATTRIBUTE_UNUSED;
712
     const arelent *rel;
713
     struct internal_reloc *intern;
714
{
715
  switch (intern->r_type)
716
    {
717
    case ALPHA_R_LITUSE:
718
    case ALPHA_R_GPDISP:
719
      intern->r_size = rel->addend;
720
      break;
721
 
722
    case ALPHA_R_OP_STORE:
723
      intern->r_size = rel->addend & 0xff;
724
      intern->r_offset = (rel->addend >> 8) & 0xff;
725
      break;
726
 
727
    case ALPHA_R_OP_PUSH:
728
    case ALPHA_R_OP_PSUB:
729
    case ALPHA_R_OP_PRSHIFT:
730
      intern->r_vaddr = rel->addend;
731
      break;
732
 
733
    case ALPHA_R_IGNORE:
734
      intern->r_vaddr = rel->address;
735
      break;
736
 
737
    default:
738
      break;
739
    }
740
}
741
 
742
/* The size of the stack for the relocation evaluator.  */
743
#define RELOC_STACKSIZE (10)
744
 
745
/* Alpha ECOFF relocs have a built in expression evaluator as well as
746
   other interdependencies.  Rather than use a bunch of special
747
   functions and global variables, we use a single routine to do all
748
   the relocation for a section.  I haven't yet worked out how the
749
   assembler is going to handle this.  */
750
 
751
static bfd_byte *
752
alpha_ecoff_get_relocated_section_contents (abfd, link_info, link_order,
753
                                            data, relocateable, symbols)
754
     bfd *abfd;
755
     struct bfd_link_info *link_info;
756
     struct bfd_link_order *link_order;
757
     bfd_byte *data;
758
     boolean relocateable;
759
     asymbol **symbols;
760
{
761
  bfd *input_bfd = link_order->u.indirect.section->owner;
762
  asection *input_section = link_order->u.indirect.section;
763
  long reloc_size = bfd_get_reloc_upper_bound (input_bfd, input_section);
764
  arelent **reloc_vector = NULL;
765
  long reloc_count;
766
  bfd *output_bfd = relocateable ? abfd : (bfd *) NULL;
767
  bfd_vma gp;
768
  boolean gp_undefined;
769
  bfd_vma stack[RELOC_STACKSIZE];
770
  int tos = 0;
771
 
772
  if (reloc_size < 0)
773
    goto error_return;
774
  reloc_vector = (arelent **) bfd_malloc ((bfd_size_type) reloc_size);
775
  if (reloc_vector == NULL && reloc_size != 0)
776
    goto error_return;
777
 
778
  if (! bfd_get_section_contents (input_bfd, input_section, data,
779
                                  (file_ptr) 0, input_section->_raw_size))
780
    goto error_return;
781
 
782
  /* The section size is not going to change.  */
783
  input_section->_cooked_size = input_section->_raw_size;
784
  input_section->reloc_done = true;
785
 
786
  reloc_count = bfd_canonicalize_reloc (input_bfd, input_section,
787
                                        reloc_vector, symbols);
788
  if (reloc_count < 0)
789
    goto error_return;
790
  if (reloc_count == 0)
791
    goto successful_return;
792
 
793
  /* Get the GP value for the output BFD.  */
794
  gp_undefined = false;
795
  gp = _bfd_get_gp_value (abfd);
796
  if (gp == 0)
797
    {
798
      if (relocateable)
799
        {
800
          asection *sec;
801
          bfd_vma lo;
802
 
803
          /* Make up a value.  */
804
          lo = (bfd_vma) -1;
805
          for (sec = abfd->sections; sec != NULL; sec = sec->next)
806
            {
807
              if (sec->vma < lo
808
                  && (strcmp (sec->name, ".sbss") == 0
809
                      || strcmp (sec->name, ".sdata") == 0
810
                      || strcmp (sec->name, ".lit4") == 0
811
                      || strcmp (sec->name, ".lit8") == 0
812
                      || strcmp (sec->name, ".lita") == 0))
813
                lo = sec->vma;
814
            }
815
          gp = lo + 0x8000;
816
          _bfd_set_gp_value (abfd, gp);
817
        }
818
      else
819
        {
820
          struct bfd_link_hash_entry *h;
821
 
822
          h = bfd_link_hash_lookup (link_info->hash, "_gp", false, false,
823
                                    true);
824
          if (h == (struct bfd_link_hash_entry *) NULL
825
              || h->type != bfd_link_hash_defined)
826
            gp_undefined = true;
827
          else
828
            {
829
              gp = (h->u.def.value
830
                    + h->u.def.section->output_section->vma
831
                    + h->u.def.section->output_offset);
832
              _bfd_set_gp_value (abfd, gp);
833
            }
834
        }
835
    }
836
 
837
  for (; *reloc_vector != (arelent *) NULL; reloc_vector++)
838
    {
839
      arelent *rel;
840
      bfd_reloc_status_type r;
841
      char *err;
842
 
843
      rel = *reloc_vector;
844
      r = bfd_reloc_ok;
845
      switch (rel->howto->type)
846
        {
847
        case ALPHA_R_IGNORE:
848
          rel->address += input_section->output_offset;
849
          break;
850
 
851
        case ALPHA_R_REFLONG:
852
        case ALPHA_R_REFQUAD:
853
        case ALPHA_R_BRADDR:
854
        case ALPHA_R_HINT:
855
        case ALPHA_R_SREL16:
856
        case ALPHA_R_SREL32:
857
        case ALPHA_R_SREL64:
858
          if (relocateable
859
              && ((*rel->sym_ptr_ptr)->flags & BSF_SECTION_SYM) == 0)
860
            {
861
              rel->address += input_section->output_offset;
862
              break;
863
            }
864
          r = bfd_perform_relocation (input_bfd, rel, data, input_section,
865
                                      output_bfd, &err);
866
          break;
867
 
868
        case ALPHA_R_GPREL32:
869
          /* This relocation is used in a switch table.  It is a 32
870
             bit offset from the current GP value.  We must adjust it
871
             by the different between the original GP value and the
872
             current GP value.  The original GP value is stored in the
873
             addend.  We adjust the addend and let
874
             bfd_perform_relocation finish the job.  */
875
          rel->addend -= gp;
876
          r = bfd_perform_relocation (input_bfd, rel, data, input_section,
877
                                      output_bfd, &err);
878
          if (r == bfd_reloc_ok && gp_undefined)
879
            {
880
              r = bfd_reloc_dangerous;
881
              err = (char *) _("GP relative relocation used when GP not defined");
882
            }
883
          break;
884
 
885
        case ALPHA_R_LITERAL:
886
          /* This is a reference to a literal value, generally
887
             (always?) in the .lita section.  This is a 16 bit GP
888
             relative relocation.  Sometimes the subsequent reloc is a
889
             LITUSE reloc, which indicates how this reloc is used.
890
             This sometimes permits rewriting the two instructions
891
             referred to by the LITERAL and the LITUSE into different
892
             instructions which do not refer to .lita.  This can save
893
             a memory reference, and permits removing a value from
894
             .lita thus saving GP relative space.
895
 
896
             We do not these optimizations.  To do them we would need
897
             to arrange to link the .lita section first, so that by
898
             the time we got here we would know the final values to
899
             use.  This would not be particularly difficult, but it is
900
             not currently implemented.  */
901
 
902
          {
903
            unsigned long insn;
904
 
905
            /* I believe that the LITERAL reloc will only apply to a
906
               ldq or ldl instruction, so check my assumption.  */
907
            insn = bfd_get_32 (input_bfd, data + rel->address);
908
            BFD_ASSERT (((insn >> 26) & 0x3f) == 0x29
909
                        || ((insn >> 26) & 0x3f) == 0x28);
910
 
911
            rel->addend -= gp;
912
            r = bfd_perform_relocation (input_bfd, rel, data, input_section,
913
                                        output_bfd, &err);
914
            if (r == bfd_reloc_ok && gp_undefined)
915
              {
916
                r = bfd_reloc_dangerous;
917
                err =
918
                  (char *) _("GP relative relocation used when GP not defined");
919
              }
920
          }
921
          break;
922
 
923
        case ALPHA_R_LITUSE:
924
          /* See ALPHA_R_LITERAL above for the uses of this reloc.  It
925
             does not cause anything to happen, itself.  */
926
          rel->address += input_section->output_offset;
927
          break;
928
 
929
        case ALPHA_R_GPDISP:
930
          /* This marks the ldah of an ldah/lda pair which loads the
931
             gp register with the difference of the gp value and the
932
             current location.  The second of the pair is r_size bytes
933
             ahead; it used to be marked with an ALPHA_R_IGNORE reloc,
934
             but that no longer happens in OSF/1 3.2.  */
935
          {
936
            unsigned long insn1, insn2;
937
            bfd_vma addend;
938
 
939
            /* Get the two instructions.  */
940
            insn1 = bfd_get_32 (input_bfd, data + rel->address);
941
            insn2 = bfd_get_32 (input_bfd, data + rel->address + rel->addend);
942
 
943
            BFD_ASSERT (((insn1 >> 26) & 0x3f) == 0x09); /* ldah */
944
            BFD_ASSERT (((insn2 >> 26) & 0x3f) == 0x08); /* lda */
945
 
946
            /* Get the existing addend.  We must account for the sign
947
               extension done by lda and ldah.  */
948
            addend = ((insn1 & 0xffff) << 16) + (insn2 & 0xffff);
949
            if (insn1 & 0x8000)
950
              {
951
                addend -= 0x80000000;
952
                addend -= 0x80000000;
953
              }
954
            if (insn2 & 0x8000)
955
              addend -= 0x10000;
956
 
957
            /* The existing addend includes the different between the
958
               gp of the input BFD and the address in the input BFD.
959
               Subtract this out.  */
960
            addend -= (ecoff_data (input_bfd)->gp
961
                       - (input_section->vma + rel->address));
962
 
963
            /* Now add in the final gp value, and subtract out the
964
               final address.  */
965
            addend += (gp
966
                       - (input_section->output_section->vma
967
                          + input_section->output_offset
968
                          + rel->address));
969
 
970
            /* Change the instructions, accounting for the sign
971
               extension, and write them out.  */
972
            if (addend & 0x8000)
973
              addend += 0x10000;
974
            insn1 = (insn1 & 0xffff0000) | ((addend >> 16) & 0xffff);
975
            insn2 = (insn2 & 0xffff0000) | (addend & 0xffff);
976
 
977
            bfd_put_32 (input_bfd, (bfd_vma) insn1, data + rel->address);
978
            bfd_put_32 (input_bfd, (bfd_vma) insn2,
979
                        data + rel->address + rel->addend);
980
 
981
            rel->address += input_section->output_offset;
982
          }
983
          break;
984
 
985
        case ALPHA_R_OP_PUSH:
986
          /* Push a value on the reloc evaluation stack.  */
987
          {
988
            asymbol *symbol;
989
            bfd_vma relocation;
990
 
991
            if (relocateable)
992
              {
993
                rel->address += input_section->output_offset;
994
                break;
995
              }
996
 
997
            /* Figure out the relocation of this symbol.  */
998
            symbol = *rel->sym_ptr_ptr;
999
 
1000
            if (bfd_is_und_section (symbol->section))
1001
              r = bfd_reloc_undefined;
1002
 
1003
            if (bfd_is_com_section (symbol->section))
1004
              relocation = 0;
1005
            else
1006
              relocation = symbol->value;
1007
            relocation += symbol->section->output_section->vma;
1008
            relocation += symbol->section->output_offset;
1009
            relocation += rel->addend;
1010
 
1011
            if (tos >= RELOC_STACKSIZE)
1012
              abort ();
1013
 
1014
            stack[tos++] = relocation;
1015
          }
1016
          break;
1017
 
1018
        case ALPHA_R_OP_STORE:
1019
          /* Store a value from the reloc stack into a bitfield.  */
1020
          {
1021
            bfd_vma val;
1022
            int offset, size;
1023
 
1024
            if (relocateable)
1025
              {
1026
                rel->address += input_section->output_offset;
1027
                break;
1028
              }
1029
 
1030
            if (tos == 0)
1031
              abort ();
1032
 
1033
            /* The offset and size for this reloc are encoded into the
1034
               addend field by alpha_adjust_reloc_in.  */
1035
            offset = (rel->addend >> 8) & 0xff;
1036
            size = rel->addend & 0xff;
1037
 
1038
            val = bfd_get_64 (abfd, data + rel->address);
1039
            val &=~ (((1 << size) - 1) << offset);
1040
            val |= (stack[--tos] & ((1 << size) - 1)) << offset;
1041
            bfd_put_64 (abfd, val, data + rel->address);
1042
          }
1043
          break;
1044
 
1045
        case ALPHA_R_OP_PSUB:
1046
          /* Subtract a value from the top of the stack.  */
1047
          {
1048
            asymbol *symbol;
1049
            bfd_vma relocation;
1050
 
1051
            if (relocateable)
1052
              {
1053
                rel->address += input_section->output_offset;
1054
                break;
1055
              }
1056
 
1057
            /* Figure out the relocation of this symbol.  */
1058
            symbol = *rel->sym_ptr_ptr;
1059
 
1060
            if (bfd_is_und_section (symbol->section))
1061
              r = bfd_reloc_undefined;
1062
 
1063
            if (bfd_is_com_section (symbol->section))
1064
              relocation = 0;
1065
            else
1066
              relocation = symbol->value;
1067
            relocation += symbol->section->output_section->vma;
1068
            relocation += symbol->section->output_offset;
1069
            relocation += rel->addend;
1070
 
1071
            if (tos == 0)
1072
              abort ();
1073
 
1074
            stack[tos - 1] -= relocation;
1075
          }
1076
          break;
1077
 
1078
        case ALPHA_R_OP_PRSHIFT:
1079
          /* Shift the value on the top of the stack.  */
1080
          {
1081
            asymbol *symbol;
1082
            bfd_vma relocation;
1083
 
1084
            if (relocateable)
1085
              {
1086
                rel->address += input_section->output_offset;
1087
                break;
1088
              }
1089
 
1090
            /* Figure out the relocation of this symbol.  */
1091
            symbol = *rel->sym_ptr_ptr;
1092
 
1093
            if (bfd_is_und_section (symbol->section))
1094
              r = bfd_reloc_undefined;
1095
 
1096
            if (bfd_is_com_section (symbol->section))
1097
              relocation = 0;
1098
            else
1099
              relocation = symbol->value;
1100
            relocation += symbol->section->output_section->vma;
1101
            relocation += symbol->section->output_offset;
1102
            relocation += rel->addend;
1103
 
1104
            if (tos == 0)
1105
              abort ();
1106
 
1107
            stack[tos - 1] >>= relocation;
1108
          }
1109
          break;
1110
 
1111
        case ALPHA_R_GPVALUE:
1112
          /* I really don't know if this does the right thing.  */
1113
          gp = rel->addend;
1114
          gp_undefined = false;
1115
          break;
1116
 
1117
        default:
1118
          abort ();
1119
        }
1120
 
1121
      if (relocateable)
1122
        {
1123
          asection *os = input_section->output_section;
1124
 
1125
          /* A partial link, so keep the relocs.  */
1126
          os->orelocation[os->reloc_count] = rel;
1127
          os->reloc_count++;
1128
        }
1129
 
1130
      if (r != bfd_reloc_ok)
1131
        {
1132
          switch (r)
1133
            {
1134
            case bfd_reloc_undefined:
1135
              if (! ((*link_info->callbacks->undefined_symbol)
1136
                     (link_info, bfd_asymbol_name (*rel->sym_ptr_ptr),
1137
                      input_bfd, input_section, rel->address, true)))
1138
                goto error_return;
1139
              break;
1140
            case bfd_reloc_dangerous:
1141
              if (! ((*link_info->callbacks->reloc_dangerous)
1142
                     (link_info, err, input_bfd, input_section,
1143
                      rel->address)))
1144
                goto error_return;
1145
              break;
1146
            case bfd_reloc_overflow:
1147
              if (! ((*link_info->callbacks->reloc_overflow)
1148
                     (link_info, bfd_asymbol_name (*rel->sym_ptr_ptr),
1149
                      rel->howto->name, rel->addend, input_bfd,
1150
                      input_section, rel->address)))
1151
                goto error_return;
1152
              break;
1153
            case bfd_reloc_outofrange:
1154
            default:
1155
              abort ();
1156
              break;
1157
            }
1158
        }
1159
    }
1160
 
1161
  if (tos != 0)
1162
    abort ();
1163
 
1164
 successful_return:
1165
  if (reloc_vector != NULL)
1166
    free (reloc_vector);
1167
  return data;
1168
 
1169
 error_return:
1170
  if (reloc_vector != NULL)
1171
    free (reloc_vector);
1172
  return NULL;
1173
}
1174
 
1175
/* Get the howto structure for a generic reloc type.  */
1176
 
1177
static reloc_howto_type *
1178
alpha_bfd_reloc_type_lookup (abfd, code)
1179
     bfd *abfd ATTRIBUTE_UNUSED;
1180
     bfd_reloc_code_real_type code;
1181
{
1182
  int alpha_type;
1183
 
1184
  switch (code)
1185
    {
1186
    case BFD_RELOC_32:
1187
      alpha_type = ALPHA_R_REFLONG;
1188
      break;
1189
    case BFD_RELOC_64:
1190
    case BFD_RELOC_CTOR:
1191
      alpha_type = ALPHA_R_REFQUAD;
1192
      break;
1193
    case BFD_RELOC_GPREL32:
1194
      alpha_type = ALPHA_R_GPREL32;
1195
      break;
1196
    case BFD_RELOC_ALPHA_LITERAL:
1197
      alpha_type = ALPHA_R_LITERAL;
1198
      break;
1199
    case BFD_RELOC_ALPHA_LITUSE:
1200
      alpha_type = ALPHA_R_LITUSE;
1201
      break;
1202
    case BFD_RELOC_ALPHA_GPDISP_HI16:
1203
      alpha_type = ALPHA_R_GPDISP;
1204
      break;
1205
    case BFD_RELOC_ALPHA_GPDISP_LO16:
1206
      alpha_type = ALPHA_R_IGNORE;
1207
      break;
1208
    case BFD_RELOC_23_PCREL_S2:
1209
      alpha_type = ALPHA_R_BRADDR;
1210
      break;
1211
    case BFD_RELOC_ALPHA_HINT:
1212
      alpha_type = ALPHA_R_HINT;
1213
      break;
1214
    case BFD_RELOC_16_PCREL:
1215
      alpha_type = ALPHA_R_SREL16;
1216
      break;
1217
    case BFD_RELOC_32_PCREL:
1218
      alpha_type = ALPHA_R_SREL32;
1219
      break;
1220
    case BFD_RELOC_64_PCREL:
1221
      alpha_type = ALPHA_R_SREL64;
1222
      break;
1223
#if 0
1224
    case ???:
1225
      alpha_type = ALPHA_R_OP_PUSH;
1226
      break;
1227
    case ???:
1228
      alpha_type = ALPHA_R_OP_STORE;
1229
      break;
1230
    case ???:
1231
      alpha_type = ALPHA_R_OP_PSUB;
1232
      break;
1233
    case ???:
1234
      alpha_type = ALPHA_R_OP_PRSHIFT;
1235
      break;
1236
    case ???:
1237
      alpha_type = ALPHA_R_GPVALUE;
1238
      break;
1239
#endif
1240
    default:
1241
      return (reloc_howto_type *) NULL;
1242
    }
1243
 
1244
  return &alpha_howto_table[alpha_type];
1245
}
1246
 
1247
/* A helper routine for alpha_relocate_section which converts an
1248
   external reloc when generating relocateable output.  Returns the
1249
   relocation amount.  */
1250
 
1251
static bfd_vma
1252
alpha_convert_external_reloc (output_bfd, info, input_bfd, ext_rel, h)
1253
     bfd *output_bfd ATTRIBUTE_UNUSED;
1254
     struct bfd_link_info *info;
1255
     bfd *input_bfd;
1256
     struct external_reloc *ext_rel;
1257
     struct ecoff_link_hash_entry *h;
1258
{
1259
  unsigned long r_symndx;
1260
  bfd_vma relocation;
1261
 
1262
  BFD_ASSERT (info->relocateable);
1263
 
1264
  if (h->root.type == bfd_link_hash_defined
1265
      || h->root.type == bfd_link_hash_defweak)
1266
    {
1267
      asection *hsec;
1268
      const char *name;
1269
 
1270
      /* This symbol is defined in the output.  Convert the reloc from
1271
         being against the symbol to being against the section.  */
1272
 
1273
      /* Clear the r_extern bit.  */
1274
      ext_rel->r_bits[1] &=~ RELOC_BITS1_EXTERN_LITTLE;
1275
 
1276
      /* Compute a new r_symndx value.  */
1277
      hsec = h->root.u.def.section;
1278
      name = bfd_get_section_name (output_bfd, hsec->output_section);
1279
 
1280
      r_symndx = (unsigned long) -1;
1281
      switch (name[1])
1282
        {
1283
        case 'A':
1284
          if (strcmp (name, "*ABS*") == 0)
1285
            r_symndx = RELOC_SECTION_ABS;
1286
          break;
1287
        case 'b':
1288
          if (strcmp (name, ".bss") == 0)
1289
            r_symndx = RELOC_SECTION_BSS;
1290
          break;
1291
        case 'd':
1292
          if (strcmp (name, ".data") == 0)
1293
            r_symndx = RELOC_SECTION_DATA;
1294
          break;
1295
        case 'f':
1296
          if (strcmp (name, ".fini") == 0)
1297
            r_symndx = RELOC_SECTION_FINI;
1298
          break;
1299
        case 'i':
1300
          if (strcmp (name, ".init") == 0)
1301
            r_symndx = RELOC_SECTION_INIT;
1302
          break;
1303
        case 'l':
1304
          if (strcmp (name, ".lita") == 0)
1305
            r_symndx = RELOC_SECTION_LITA;
1306
          else if (strcmp (name, ".lit8") == 0)
1307
            r_symndx = RELOC_SECTION_LIT8;
1308
          else if (strcmp (name, ".lit4") == 0)
1309
            r_symndx = RELOC_SECTION_LIT4;
1310
          break;
1311
        case 'p':
1312
          if (strcmp (name, ".pdata") == 0)
1313
            r_symndx = RELOC_SECTION_PDATA;
1314
          break;
1315
        case 'r':
1316
          if (strcmp (name, ".rdata") == 0)
1317
            r_symndx = RELOC_SECTION_RDATA;
1318
          else if (strcmp (name, ".rconst") == 0)
1319
            r_symndx = RELOC_SECTION_RCONST;
1320
          break;
1321
        case 's':
1322
          if (strcmp (name, ".sdata") == 0)
1323
            r_symndx = RELOC_SECTION_SDATA;
1324
          else if (strcmp (name, ".sbss") == 0)
1325
            r_symndx = RELOC_SECTION_SBSS;
1326
          break;
1327
        case 't':
1328
          if (strcmp (name, ".text") == 0)
1329
            r_symndx = RELOC_SECTION_TEXT;
1330
          break;
1331
        case 'x':
1332
          if (strcmp (name, ".xdata") == 0)
1333
            r_symndx = RELOC_SECTION_XDATA;
1334
          break;
1335
        }
1336
 
1337
      if (r_symndx == (unsigned long) -1)
1338
        abort ();
1339
 
1340
      /* Add the section VMA and the symbol value.  */
1341
      relocation = (h->root.u.def.value
1342
                    + hsec->output_section->vma
1343
                    + hsec->output_offset);
1344
    }
1345
  else
1346
    {
1347
      /* Change the symndx value to the right one for
1348
         the output BFD.  */
1349
      r_symndx = h->indx;
1350
      if (r_symndx == (unsigned long) -1)
1351
        {
1352
          /* Caller must give an error.  */
1353
          r_symndx = 0;
1354
        }
1355
      relocation = 0;
1356
    }
1357
 
1358
  /* Write out the new r_symndx value.  */
1359
  H_PUT_32 (input_bfd, r_symndx, ext_rel->r_symndx);
1360
 
1361
  return relocation;
1362
}
1363
 
1364
/* Relocate a section while linking an Alpha ECOFF file.  This is
1365
   quite similar to get_relocated_section_contents.  Perhaps they
1366
   could be combined somehow.  */
1367
 
1368
static boolean
1369
alpha_relocate_section (output_bfd, info, input_bfd, input_section,
1370
                        contents, external_relocs)
1371
     bfd *output_bfd;
1372
     struct bfd_link_info *info;
1373
     bfd *input_bfd;
1374
     asection *input_section;
1375
     bfd_byte *contents;
1376
     PTR external_relocs;
1377
{
1378
  asection **symndx_to_section, *lita_sec;
1379
  struct ecoff_link_hash_entry **sym_hashes;
1380
  bfd_vma gp;
1381
  boolean gp_undefined;
1382
  bfd_vma stack[RELOC_STACKSIZE];
1383
  int tos = 0;
1384
  struct external_reloc *ext_rel;
1385
  struct external_reloc *ext_rel_end;
1386
  bfd_size_type amt;
1387
 
1388
  /* We keep a table mapping the symndx found in an internal reloc to
1389
     the appropriate section.  This is faster than looking up the
1390
     section by name each time.  */
1391
  symndx_to_section = ecoff_data (input_bfd)->symndx_to_section;
1392
  if (symndx_to_section == (asection **) NULL)
1393
    {
1394
      amt = NUM_RELOC_SECTIONS * sizeof (asection *);
1395
      symndx_to_section = (asection **) bfd_alloc (input_bfd, amt);
1396
      if (!symndx_to_section)
1397
        return false;
1398
 
1399
      symndx_to_section[RELOC_SECTION_NONE] = NULL;
1400
      symndx_to_section[RELOC_SECTION_TEXT] =
1401
        bfd_get_section_by_name (input_bfd, ".text");
1402
      symndx_to_section[RELOC_SECTION_RDATA] =
1403
        bfd_get_section_by_name (input_bfd, ".rdata");
1404
      symndx_to_section[RELOC_SECTION_DATA] =
1405
        bfd_get_section_by_name (input_bfd, ".data");
1406
      symndx_to_section[RELOC_SECTION_SDATA] =
1407
        bfd_get_section_by_name (input_bfd, ".sdata");
1408
      symndx_to_section[RELOC_SECTION_SBSS] =
1409
        bfd_get_section_by_name (input_bfd, ".sbss");
1410
      symndx_to_section[RELOC_SECTION_BSS] =
1411
        bfd_get_section_by_name (input_bfd, ".bss");
1412
      symndx_to_section[RELOC_SECTION_INIT] =
1413
        bfd_get_section_by_name (input_bfd, ".init");
1414
      symndx_to_section[RELOC_SECTION_LIT8] =
1415
        bfd_get_section_by_name (input_bfd, ".lit8");
1416
      symndx_to_section[RELOC_SECTION_LIT4] =
1417
        bfd_get_section_by_name (input_bfd, ".lit4");
1418
      symndx_to_section[RELOC_SECTION_XDATA] =
1419
        bfd_get_section_by_name (input_bfd, ".xdata");
1420
      symndx_to_section[RELOC_SECTION_PDATA] =
1421
        bfd_get_section_by_name (input_bfd, ".pdata");
1422
      symndx_to_section[RELOC_SECTION_FINI] =
1423
        bfd_get_section_by_name (input_bfd, ".fini");
1424
      symndx_to_section[RELOC_SECTION_LITA] =
1425
        bfd_get_section_by_name (input_bfd, ".lita");
1426
      symndx_to_section[RELOC_SECTION_ABS] = bfd_abs_section_ptr;
1427
      symndx_to_section[RELOC_SECTION_RCONST] =
1428
        bfd_get_section_by_name (input_bfd, ".rconst");
1429
 
1430
      ecoff_data (input_bfd)->symndx_to_section = symndx_to_section;
1431
    }
1432
 
1433
  sym_hashes = ecoff_data (input_bfd)->sym_hashes;
1434
 
1435
  /* On the Alpha, the .lita section must be addressable by the global
1436
     pointer.  To support large programs, we need to allow multiple
1437
     global pointers.  This works as long as each input .lita section
1438
     is <64KB big.  This implies that when producing relocatable
1439
     output, the .lita section is limited to 64KB. .  */
1440
 
1441
  lita_sec = symndx_to_section[RELOC_SECTION_LITA];
1442
  gp = _bfd_get_gp_value (output_bfd);
1443
  if (! info->relocateable && lita_sec != NULL)
1444
    {
1445
      struct ecoff_section_tdata *lita_sec_data;
1446
 
1447
      /* Make sure we have a section data structure to which we can
1448
         hang on to the gp value we pick for the section.  */
1449
      lita_sec_data = ecoff_section_data (input_bfd, lita_sec);
1450
      if (lita_sec_data == NULL)
1451
        {
1452
          amt = sizeof (struct ecoff_section_tdata);
1453
          lita_sec_data = ((struct ecoff_section_tdata *)
1454
                           bfd_zalloc (input_bfd, amt));
1455
          ecoff_section_data (input_bfd, lita_sec) = lita_sec_data;
1456
        }
1457
 
1458
      if (lita_sec_data->gp != 0)
1459
        {
1460
          /* If we already assigned a gp to this section, we better
1461
             stick with that value.  */
1462
          gp = lita_sec_data->gp;
1463
        }
1464
      else
1465
        {
1466
          bfd_vma lita_vma;
1467
          bfd_size_type lita_size;
1468
 
1469
          lita_vma = lita_sec->output_offset + lita_sec->output_section->vma;
1470
          lita_size = lita_sec->_cooked_size;
1471
          if (lita_size == 0)
1472
            lita_size = lita_sec->_raw_size;
1473
 
1474
          if (gp == 0
1475
              || lita_vma <  gp - 0x8000
1476
              || lita_vma + lita_size >= gp + 0x8000)
1477
            {
1478
              /* Either gp hasn't been set at all or the current gp
1479
                 cannot address this .lita section.  In both cases we
1480
                 reset the gp to point into the "middle" of the
1481
                 current input .lita section.  */
1482
              if (gp && !ecoff_data (output_bfd)->issued_multiple_gp_warning)
1483
                {
1484
                  (*info->callbacks->warning) (info,
1485
                                               _("using multiple gp values"),
1486
                                               (char *) NULL, output_bfd,
1487
                                               (asection *) NULL, (bfd_vma) 0);
1488
                  ecoff_data (output_bfd)->issued_multiple_gp_warning = true;
1489
                }
1490
              if (lita_vma < gp - 0x8000)
1491
                gp = lita_vma + lita_size - 0x8000;
1492
              else
1493
                gp = lita_vma + 0x8000;
1494
 
1495
            }
1496
 
1497
          lita_sec_data->gp = gp;
1498
        }
1499
 
1500
      _bfd_set_gp_value (output_bfd, gp);
1501
    }
1502
 
1503
  gp_undefined = (gp == 0);
1504
 
1505
  BFD_ASSERT (bfd_header_little_endian (output_bfd));
1506
  BFD_ASSERT (bfd_header_little_endian (input_bfd));
1507
 
1508
  ext_rel = (struct external_reloc *) external_relocs;
1509
  ext_rel_end = ext_rel + input_section->reloc_count;
1510
  for (; ext_rel < ext_rel_end; ext_rel++)
1511
    {
1512
      bfd_vma r_vaddr;
1513
      unsigned long r_symndx;
1514
      int r_type;
1515
      int r_extern;
1516
      int r_offset;
1517
      int r_size;
1518
      boolean relocatep;
1519
      boolean adjust_addrp;
1520
      boolean gp_usedp;
1521
      bfd_vma addend;
1522
 
1523
      r_vaddr = H_GET_64 (input_bfd, ext_rel->r_vaddr);
1524
      r_symndx = H_GET_32 (input_bfd, ext_rel->r_symndx);
1525
 
1526
      r_type = ((ext_rel->r_bits[0] & RELOC_BITS0_TYPE_LITTLE)
1527
                >> RELOC_BITS0_TYPE_SH_LITTLE);
1528
      r_extern = (ext_rel->r_bits[1] & RELOC_BITS1_EXTERN_LITTLE) != 0;
1529
      r_offset = ((ext_rel->r_bits[1] & RELOC_BITS1_OFFSET_LITTLE)
1530
                  >> RELOC_BITS1_OFFSET_SH_LITTLE);
1531
      /* Ignored the reserved bits.  */
1532
      r_size = ((ext_rel->r_bits[3] & RELOC_BITS3_SIZE_LITTLE)
1533
                >> RELOC_BITS3_SIZE_SH_LITTLE);
1534
 
1535
      relocatep = false;
1536
      adjust_addrp = true;
1537
      gp_usedp = false;
1538
      addend = 0;
1539
 
1540
      switch (r_type)
1541
        {
1542
        default:
1543
          abort ();
1544
 
1545
        case ALPHA_R_IGNORE:
1546
          /* This reloc appears after a GPDISP reloc.  On earlier
1547
             versions of OSF/1, It marked the position of the second
1548
             instruction to be altered by the GPDISP reloc, but it is
1549
             not otherwise used for anything.  For some reason, the
1550
             address of the relocation does not appear to include the
1551
             section VMA, unlike the other relocation types.  */
1552
          if (info->relocateable)
1553
            H_PUT_64 (input_bfd, input_section->output_offset + r_vaddr,
1554
                      ext_rel->r_vaddr);
1555
          adjust_addrp = false;
1556
          break;
1557
 
1558
        case ALPHA_R_REFLONG:
1559
        case ALPHA_R_REFQUAD:
1560
        case ALPHA_R_HINT:
1561
          relocatep = true;
1562
          break;
1563
 
1564
        case ALPHA_R_BRADDR:
1565
        case ALPHA_R_SREL16:
1566
        case ALPHA_R_SREL32:
1567
        case ALPHA_R_SREL64:
1568
          if (r_extern)
1569
            addend += - (r_vaddr + 4);
1570
          relocatep = true;
1571
          break;
1572
 
1573
        case ALPHA_R_GPREL32:
1574
          /* This relocation is used in a switch table.  It is a 32
1575
             bit offset from the current GP value.  We must adjust it
1576
             by the different between the original GP value and the
1577
             current GP value.  */
1578
          relocatep = true;
1579
          addend = ecoff_data (input_bfd)->gp - gp;
1580
          gp_usedp = true;
1581
          break;
1582
 
1583
        case ALPHA_R_LITERAL:
1584
          /* This is a reference to a literal value, generally
1585
             (always?) in the .lita section.  This is a 16 bit GP
1586
             relative relocation.  Sometimes the subsequent reloc is a
1587
             LITUSE reloc, which indicates how this reloc is used.
1588
             This sometimes permits rewriting the two instructions
1589
             referred to by the LITERAL and the LITUSE into different
1590
             instructions which do not refer to .lita.  This can save
1591
             a memory reference, and permits removing a value from
1592
             .lita thus saving GP relative space.
1593
 
1594
             We do not these optimizations.  To do them we would need
1595
             to arrange to link the .lita section first, so that by
1596
             the time we got here we would know the final values to
1597
             use.  This would not be particularly difficult, but it is
1598
             not currently implemented.  */
1599
 
1600
          /* I believe that the LITERAL reloc will only apply to a ldq
1601
             or ldl instruction, so check my assumption.  */
1602
          {
1603
            unsigned long insn;
1604
 
1605
            insn = bfd_get_32 (input_bfd,
1606
                               contents + r_vaddr - input_section->vma);
1607
            BFD_ASSERT (((insn >> 26) & 0x3f) == 0x29
1608
                        || ((insn >> 26) & 0x3f) == 0x28);
1609
          }
1610
 
1611
          relocatep = true;
1612
          addend = ecoff_data (input_bfd)->gp - gp;
1613
          gp_usedp = true;
1614
          break;
1615
 
1616
        case ALPHA_R_LITUSE:
1617
          /* See ALPHA_R_LITERAL above for the uses of this reloc.  It
1618
             does not cause anything to happen, itself.  */
1619
          break;
1620
 
1621
        case ALPHA_R_GPDISP:
1622
          /* This marks the ldah of an ldah/lda pair which loads the
1623
             gp register with the difference of the gp value and the
1624
             current location.  The second of the pair is r_symndx
1625
             bytes ahead.  It used to be marked with an ALPHA_R_IGNORE
1626
             reloc, but OSF/1 3.2 no longer does that.  */
1627
          {
1628
            unsigned long insn1, insn2;
1629
 
1630
            /* Get the two instructions.  */
1631
            insn1 = bfd_get_32 (input_bfd,
1632
                                contents + r_vaddr - input_section->vma);
1633
            insn2 = bfd_get_32 (input_bfd,
1634
                                (contents
1635
                                 + r_vaddr
1636
                                 - input_section->vma
1637
                                 + r_symndx));
1638
 
1639
            BFD_ASSERT (((insn1 >> 26) & 0x3f) == 0x09); /* ldah */
1640
            BFD_ASSERT (((insn2 >> 26) & 0x3f) == 0x08); /* lda */
1641
 
1642
            /* Get the existing addend.  We must account for the sign
1643
               extension done by lda and ldah.  */
1644
            addend = ((insn1 & 0xffff) << 16) + (insn2 & 0xffff);
1645
            if (insn1 & 0x8000)
1646
              {
1647
                /* This is addend -= 0x100000000 without causing an
1648
                   integer overflow on a 32 bit host.  */
1649
                addend -= 0x80000000;
1650
                addend -= 0x80000000;
1651
              }
1652
            if (insn2 & 0x8000)
1653
              addend -= 0x10000;
1654
 
1655
            /* The existing addend includes the difference between the
1656
               gp of the input BFD and the address in the input BFD.
1657
               We want to change this to the difference between the
1658
               final GP and the final address.  */
1659
            addend += (gp
1660
                       - ecoff_data (input_bfd)->gp
1661
                       + input_section->vma
1662
                       - (input_section->output_section->vma
1663
                          + input_section->output_offset));
1664
 
1665
            /* Change the instructions, accounting for the sign
1666
               extension, and write them out.  */
1667
            if (addend & 0x8000)
1668
              addend += 0x10000;
1669
            insn1 = (insn1 & 0xffff0000) | ((addend >> 16) & 0xffff);
1670
            insn2 = (insn2 & 0xffff0000) | (addend & 0xffff);
1671
 
1672
            bfd_put_32 (input_bfd, (bfd_vma) insn1,
1673
                        contents + r_vaddr - input_section->vma);
1674
            bfd_put_32 (input_bfd, (bfd_vma) insn2,
1675
                        contents + r_vaddr - input_section->vma + r_symndx);
1676
 
1677
            gp_usedp = true;
1678
          }
1679
          break;
1680
 
1681
        case ALPHA_R_OP_PUSH:
1682
        case ALPHA_R_OP_PSUB:
1683
        case ALPHA_R_OP_PRSHIFT:
1684
          /* Manipulate values on the reloc evaluation stack.  The
1685
             r_vaddr field is not an address in input_section, it is
1686
             the current value (including any addend) of the object
1687
             being used.  */
1688
          if (! r_extern)
1689
            {
1690
              asection *s;
1691
 
1692
              s = symndx_to_section[r_symndx];
1693
              if (s == (asection *) NULL)
1694
                abort ();
1695
              addend = s->output_section->vma + s->output_offset - s->vma;
1696
            }
1697
          else
1698
            {
1699
              struct ecoff_link_hash_entry *h;
1700
 
1701
              h = sym_hashes[r_symndx];
1702
              if (h == (struct ecoff_link_hash_entry *) NULL)
1703
                abort ();
1704
 
1705
              if (! info->relocateable)
1706
                {
1707
                  if (h->root.type == bfd_link_hash_defined
1708
                      || h->root.type == bfd_link_hash_defweak)
1709
                    addend = (h->root.u.def.value
1710
                              + h->root.u.def.section->output_section->vma
1711
                              + h->root.u.def.section->output_offset);
1712
                  else
1713
                    {
1714
                      /* Note that we pass the address as 0, since we
1715
                         do not have a meaningful number for the
1716
                         location within the section that is being
1717
                         relocated.  */
1718
                      if (! ((*info->callbacks->undefined_symbol)
1719
                             (info, h->root.root.string, input_bfd,
1720
                              input_section, (bfd_vma) 0, true)))
1721
                        return false;
1722
                      addend = 0;
1723
                    }
1724
                }
1725
              else
1726
                {
1727
                  if (h->root.type != bfd_link_hash_defined
1728
                      && h->root.type != bfd_link_hash_defweak
1729
                      && h->indx == -1)
1730
                    {
1731
                      /* This symbol is not being written out.  Pass
1732
                         the address as 0, as with undefined_symbol,
1733
                         above.  */
1734
                      if (! ((*info->callbacks->unattached_reloc)
1735
                             (info, h->root.root.string, input_bfd,
1736
                              input_section, (bfd_vma) 0)))
1737
                        return false;
1738
                    }
1739
 
1740
                  addend = alpha_convert_external_reloc (output_bfd, info,
1741
                                                         input_bfd,
1742
                                                         ext_rel, h);
1743
                }
1744
            }
1745
 
1746
          addend += r_vaddr;
1747
 
1748
          if (info->relocateable)
1749
            {
1750
              /* Adjust r_vaddr by the addend.  */
1751
              H_PUT_64 (input_bfd, addend, ext_rel->r_vaddr);
1752
            }
1753
          else
1754
            {
1755
              switch (r_type)
1756
                {
1757
                case ALPHA_R_OP_PUSH:
1758
                  if (tos >= RELOC_STACKSIZE)
1759
                    abort ();
1760
                  stack[tos++] = addend;
1761
                  break;
1762
 
1763
                case ALPHA_R_OP_PSUB:
1764
                  if (tos == 0)
1765
                    abort ();
1766
                  stack[tos - 1] -= addend;
1767
                  break;
1768
 
1769
                case ALPHA_R_OP_PRSHIFT:
1770
                  if (tos == 0)
1771
                    abort ();
1772
                  stack[tos - 1] >>= addend;
1773
                  break;
1774
                }
1775
            }
1776
 
1777
          adjust_addrp = false;
1778
          break;
1779
 
1780
        case ALPHA_R_OP_STORE:
1781
          /* Store a value from the reloc stack into a bitfield.  If
1782
             we are generating relocateable output, all we do is
1783
             adjust the address of the reloc.  */
1784
          if (! info->relocateable)
1785
            {
1786
              bfd_vma mask;
1787
              bfd_vma val;
1788
 
1789
              if (tos == 0)
1790
                abort ();
1791
 
1792
              /* Get the relocation mask.  The separate steps and the
1793
                 casts to bfd_vma are attempts to avoid a bug in the
1794
                 Alpha OSF 1.3 C compiler.  See reloc.c for more
1795
                 details.  */
1796
              mask = 1;
1797
              mask <<= (bfd_vma) r_size;
1798
              mask -= 1;
1799
 
1800
              /* FIXME: I don't know what kind of overflow checking,
1801
                 if any, should be done here.  */
1802
              val = bfd_get_64 (input_bfd,
1803
                                contents + r_vaddr - input_section->vma);
1804
              val &=~ mask << (bfd_vma) r_offset;
1805
              val |= (stack[--tos] & mask) << (bfd_vma) r_offset;
1806
              bfd_put_64 (input_bfd, val,
1807
                          contents + r_vaddr - input_section->vma);
1808
            }
1809
          break;
1810
 
1811
        case ALPHA_R_GPVALUE:
1812
          /* I really don't know if this does the right thing.  */
1813
          gp = ecoff_data (input_bfd)->gp + r_symndx;
1814
          gp_undefined = false;
1815
          break;
1816
        }
1817
 
1818
      if (relocatep)
1819
        {
1820
          reloc_howto_type *howto;
1821
          struct ecoff_link_hash_entry *h = NULL;
1822
          asection *s = NULL;
1823
          bfd_vma relocation;
1824
          bfd_reloc_status_type r;
1825
 
1826
          /* Perform a relocation.  */
1827
 
1828
          howto = &alpha_howto_table[r_type];
1829
 
1830
          if (r_extern)
1831
            {
1832
              h = sym_hashes[r_symndx];
1833
              /* If h is NULL, that means that there is a reloc
1834
                 against an external symbol which we thought was just
1835
                 a debugging symbol.  This should not happen.  */
1836
              if (h == (struct ecoff_link_hash_entry *) NULL)
1837
                abort ();
1838
            }
1839
          else
1840
            {
1841
              if (r_symndx >= NUM_RELOC_SECTIONS)
1842
                s = NULL;
1843
              else
1844
                s = symndx_to_section[r_symndx];
1845
 
1846
              if (s == (asection *) NULL)
1847
                abort ();
1848
            }
1849
 
1850
          if (info->relocateable)
1851
            {
1852
              /* We are generating relocateable output, and must
1853
                 convert the existing reloc.  */
1854
              if (r_extern)
1855
                {
1856
                  if (h->root.type != bfd_link_hash_defined
1857
                      && h->root.type != bfd_link_hash_defweak
1858
                      && h->indx == -1)
1859
                    {
1860
                      /* This symbol is not being written out.  */
1861
                      if (! ((*info->callbacks->unattached_reloc)
1862
                             (info, h->root.root.string, input_bfd,
1863
                              input_section, r_vaddr - input_section->vma)))
1864
                        return false;
1865
                    }
1866
 
1867
                  relocation = alpha_convert_external_reloc (output_bfd,
1868
                                                             info,
1869
                                                             input_bfd,
1870
                                                             ext_rel,
1871
                                                             h);
1872
                }
1873
              else
1874
                {
1875
                  /* This is a relocation against a section.  Adjust
1876
                     the value by the amount the section moved.  */
1877
                  relocation = (s->output_section->vma
1878
                                + s->output_offset
1879
                                - s->vma);
1880
                }
1881
 
1882
              /* If this is PC relative, the existing object file
1883
                 appears to already have the reloc worked out.  We
1884
                 must subtract out the old value and add in the new
1885
                 one.  */
1886
              if (howto->pc_relative)
1887
                relocation -= (input_section->output_section->vma
1888
                               + input_section->output_offset
1889
                               - input_section->vma);
1890
 
1891
              /* Put in any addend.  */
1892
              relocation += addend;
1893
 
1894
              /* Adjust the contents.  */
1895
              r = _bfd_relocate_contents (howto, input_bfd, relocation,
1896
                                          (contents
1897
                                           + r_vaddr
1898
                                           - input_section->vma));
1899
            }
1900
          else
1901
            {
1902
              /* We are producing a final executable.  */
1903
              if (r_extern)
1904
                {
1905
                  /* This is a reloc against a symbol.  */
1906
                  if (h->root.type == bfd_link_hash_defined
1907
                      || h->root.type == bfd_link_hash_defweak)
1908
                    {
1909
                      asection *hsec;
1910
 
1911
                      hsec = h->root.u.def.section;
1912
                      relocation = (h->root.u.def.value
1913
                                    + hsec->output_section->vma
1914
                                    + hsec->output_offset);
1915
                    }
1916
                  else
1917
                    {
1918
                      if (! ((*info->callbacks->undefined_symbol)
1919
                             (info, h->root.root.string, input_bfd,
1920
                              input_section,
1921
                              r_vaddr - input_section->vma, true)))
1922
                        return false;
1923
                      relocation = 0;
1924
                    }
1925
                }
1926
              else
1927
                {
1928
                  /* This is a reloc against a section.  */
1929
                  relocation = (s->output_section->vma
1930
                                + s->output_offset
1931
                                - s->vma);
1932
 
1933
                  /* Adjust a PC relative relocation by removing the
1934
                     reference to the original source section.  */
1935
                  if (howto->pc_relative)
1936
                    relocation += input_section->vma;
1937
                }
1938
 
1939
              r = _bfd_final_link_relocate (howto,
1940
                                            input_bfd,
1941
                                            input_section,
1942
                                            contents,
1943
                                            r_vaddr - input_section->vma,
1944
                                            relocation,
1945
                                            addend);
1946
            }
1947
 
1948
          if (r != bfd_reloc_ok)
1949
            {
1950
              switch (r)
1951
                {
1952
                default:
1953
                case bfd_reloc_outofrange:
1954
                  abort ();
1955
                case bfd_reloc_overflow:
1956
                  {
1957
                    const char *name;
1958
 
1959
                    if (r_extern)
1960
                      name = sym_hashes[r_symndx]->root.root.string;
1961
                    else
1962
                      name = bfd_section_name (input_bfd,
1963
                                               symndx_to_section[r_symndx]);
1964
                    if (! ((*info->callbacks->reloc_overflow)
1965
                           (info, name, alpha_howto_table[r_type].name,
1966
                            (bfd_vma) 0, input_bfd, input_section,
1967
                            r_vaddr - input_section->vma)))
1968
                      return false;
1969
                  }
1970
                  break;
1971
                }
1972
            }
1973
        }
1974
 
1975
      if (info->relocateable && adjust_addrp)
1976
        {
1977
          /* Change the address of the relocation.  */
1978
          H_PUT_64 (input_bfd,
1979
                    (input_section->output_section->vma
1980
                     + input_section->output_offset
1981
                     - input_section->vma
1982
                     + r_vaddr),
1983
                    ext_rel->r_vaddr);
1984
        }
1985
 
1986
      if (gp_usedp && gp_undefined)
1987
        {
1988
          if (! ((*info->callbacks->reloc_dangerous)
1989
                 (info, _("GP relative relocation used when GP not defined"),
1990
                  input_bfd, input_section, r_vaddr - input_section->vma)))
1991
            return false;
1992
          /* Only give the error once per link.  */
1993
          gp = 4;
1994
          _bfd_set_gp_value (output_bfd, gp);
1995
          gp_undefined = false;
1996
        }
1997
    }
1998
 
1999
  if (tos != 0)
2000
    abort ();
2001
 
2002
  return true;
2003
}
2004
 
2005
/* Do final adjustments to the filehdr and the aouthdr.  This routine
2006
   sets the dynamic bits in the file header.  */
2007
 
2008
static boolean
2009
alpha_adjust_headers (abfd, fhdr, ahdr)
2010
     bfd *abfd;
2011
     struct internal_filehdr *fhdr;
2012
     struct internal_aouthdr *ahdr ATTRIBUTE_UNUSED;
2013
{
2014
  if ((abfd->flags & (DYNAMIC | EXEC_P)) == (DYNAMIC | EXEC_P))
2015
    fhdr->f_flags |= F_ALPHA_CALL_SHARED;
2016
  else if ((abfd->flags & DYNAMIC) != 0)
2017
    fhdr->f_flags |= F_ALPHA_SHARABLE;
2018
  return true;
2019
}
2020
 
2021
/* Archive handling.  In OSF/1 (or Digital Unix) v3.2, Digital
2022
   introduced archive packing, in which the elements in an archive are
2023
   optionally compressed using a simple dictionary scheme.  We know
2024
   how to read such archives, but we don't write them.  */
2025
 
2026
#define alpha_ecoff_slurp_armap _bfd_ecoff_slurp_armap
2027
#define alpha_ecoff_slurp_extended_name_table \
2028
  _bfd_ecoff_slurp_extended_name_table
2029
#define alpha_ecoff_construct_extended_name_table \
2030
  _bfd_ecoff_construct_extended_name_table
2031
#define alpha_ecoff_truncate_arname _bfd_ecoff_truncate_arname
2032
#define alpha_ecoff_write_armap _bfd_ecoff_write_armap
2033
#define alpha_ecoff_generic_stat_arch_elt _bfd_ecoff_generic_stat_arch_elt
2034
#define alpha_ecoff_update_armap_timestamp _bfd_ecoff_update_armap_timestamp
2035
 
2036
/* A compressed file uses this instead of ARFMAG.  */
2037
 
2038
#define ARFZMAG "Z\012"
2039
 
2040
/* Read an archive header.  This is like the standard routine, but it
2041
   also accepts ARFZMAG.  */
2042
 
2043
static PTR
2044
alpha_ecoff_read_ar_hdr (abfd)
2045
     bfd *abfd;
2046
{
2047
  struct areltdata *ret;
2048
  struct ar_hdr *h;
2049
 
2050
  ret = (struct areltdata *) _bfd_generic_read_ar_hdr_mag (abfd, ARFZMAG);
2051
  if (ret == NULL)
2052
    return NULL;
2053
 
2054
  h = (struct ar_hdr *) ret->arch_header;
2055
  if (strncmp (h->ar_fmag, ARFZMAG, 2) == 0)
2056
    {
2057
      bfd_byte ab[8];
2058
 
2059
      /* This is a compressed file.  We must set the size correctly.
2060
         The size is the eight bytes after the dummy file header.  */
2061
      if (bfd_seek (abfd, (file_ptr) FILHSZ, SEEK_CUR) != 0
2062
          || bfd_bread (ab, (bfd_size_type) 8, abfd) != 8
2063
          || bfd_seek (abfd, (file_ptr) (- (FILHSZ + 8)), SEEK_CUR) != 0)
2064
        return NULL;
2065
 
2066
      ret->parsed_size = H_GET_64 (abfd, ab);
2067
    }
2068
 
2069
  return (PTR) ret;
2070
}
2071
 
2072
/* Get an archive element at a specified file position.  This is where
2073
   we uncompress the archive element if necessary.  */
2074
 
2075
static bfd *
2076
alpha_ecoff_get_elt_at_filepos (archive, filepos)
2077
     bfd *archive;
2078
     file_ptr filepos;
2079
{
2080
  bfd *nbfd = NULL;
2081
  struct areltdata *tdata;
2082
  struct ar_hdr *hdr;
2083
  bfd_byte ab[8];
2084
  bfd_size_type size;
2085
  bfd_byte *buf, *p;
2086
  struct bfd_in_memory *bim;
2087
 
2088
  nbfd = _bfd_get_elt_at_filepos (archive, filepos);
2089
  if (nbfd == NULL)
2090
    goto error_return;
2091
 
2092
  if ((nbfd->flags & BFD_IN_MEMORY) != 0)
2093
    {
2094
      /* We have already expanded this BFD.  */
2095
      return nbfd;
2096
    }
2097
 
2098
  tdata = (struct areltdata *) nbfd->arelt_data;
2099
  hdr = (struct ar_hdr *) tdata->arch_header;
2100
  if (strncmp (hdr->ar_fmag, ARFZMAG, 2) != 0)
2101
    return nbfd;
2102
 
2103
  /* We must uncompress this element.  We do this by copying it into a
2104
     memory buffer, and making bfd_bread and bfd_seek use that buffer.
2105
     This can use a lot of memory, but it's simpler than getting a
2106
     temporary file, making that work with the file descriptor caching
2107
     code, and making sure that it is deleted at all appropriate
2108
     times.  It can be changed if it ever becomes important.  */
2109
 
2110
  /* The compressed file starts with a dummy ECOFF file header.  */
2111
  if (bfd_seek (nbfd, (file_ptr) FILHSZ, SEEK_SET) != 0)
2112
    goto error_return;
2113
 
2114
  /* The next eight bytes are the real file size.  */
2115
  if (bfd_bread (ab, (bfd_size_type) 8, nbfd) != 8)
2116
    goto error_return;
2117
  size = H_GET_64 (nbfd, ab);
2118
 
2119
  if (size == 0)
2120
    buf = NULL;
2121
  else
2122
    {
2123
      bfd_size_type left;
2124
      bfd_byte dict[4096];
2125
      unsigned int h;
2126
      bfd_byte b;
2127
 
2128
      buf = (bfd_byte *) bfd_alloc (nbfd, size);
2129
      if (buf == NULL)
2130
        goto error_return;
2131
      p = buf;
2132
 
2133
      left = size;
2134
 
2135
      /* I don't know what the next eight bytes are for.  */
2136
      if (bfd_bread (ab, (bfd_size_type) 8, nbfd) != 8)
2137
        goto error_return;
2138
 
2139
      /* This is the uncompression algorithm.  It's a simple
2140
         dictionary based scheme in which each character is predicted
2141
         by a hash of the previous three characters.  A control byte
2142
         indicates whether the character is predicted or whether it
2143
         appears in the input stream; each control byte manages the
2144
         next eight bytes in the output stream.  */
2145
      memset (dict, 0, sizeof dict);
2146
      h = 0;
2147
      while (bfd_bread (&b, (bfd_size_type) 1, nbfd) == 1)
2148
        {
2149
          unsigned int i;
2150
 
2151
          for (i = 0; i < 8; i++, b >>= 1)
2152
            {
2153
              bfd_byte n;
2154
 
2155
              if ((b & 1) == 0)
2156
                n = dict[h];
2157
              else
2158
                {
2159
                  if (! bfd_bread (&n, (bfd_size_type) 1, nbfd))
2160
                    goto error_return;
2161
                  dict[h] = n;
2162
                }
2163
 
2164
              *p++ = n;
2165
 
2166
              --left;
2167
              if (left == 0)
2168
                break;
2169
 
2170
              h <<= 4;
2171
              h ^= n;
2172
              h &= sizeof dict - 1;
2173
            }
2174
 
2175
          if (left == 0)
2176
            break;
2177
        }
2178
    }
2179
 
2180
  /* Now the uncompressed file contents are in buf.  */
2181
  bim = ((struct bfd_in_memory *)
2182
         bfd_alloc (nbfd, (bfd_size_type) sizeof (struct bfd_in_memory)));
2183
  if (bim == NULL)
2184
    goto error_return;
2185
  bim->size = size;
2186
  bim->buffer = buf;
2187
 
2188
  nbfd->mtime_set = true;
2189
  nbfd->mtime = strtol (hdr->ar_date, (char **) NULL, 10);
2190
 
2191
  nbfd->flags |= BFD_IN_MEMORY;
2192
  nbfd->iostream = (PTR) bim;
2193
  BFD_ASSERT (! nbfd->cacheable);
2194
 
2195
  return nbfd;
2196
 
2197
 error_return:
2198
  if (nbfd != NULL)
2199
    bfd_close (nbfd);
2200
  return NULL;
2201
}
2202
 
2203
/* Open the next archived file.  */
2204
 
2205
static bfd *
2206
alpha_ecoff_openr_next_archived_file (archive, last_file)
2207
     bfd *archive;
2208
     bfd *last_file;
2209
{
2210
  file_ptr filestart;
2211
 
2212
  if (last_file == NULL)
2213
    filestart = bfd_ardata (archive)->first_file_filepos;
2214
  else
2215
    {
2216
      struct areltdata *t;
2217
      struct ar_hdr *h;
2218
      bfd_size_type size;
2219
 
2220
      /* We can't use arelt_size here, because that uses parsed_size,
2221
         which is the uncompressed size.  We need the compressed size.  */
2222
      t = (struct areltdata *) last_file->arelt_data;
2223
      h = (struct ar_hdr *) t->arch_header;
2224
      size = strtol (h->ar_size, (char **) NULL, 10);
2225
 
2226
      /* Pad to an even boundary...
2227
         Note that last_file->origin can be odd in the case of
2228
         BSD-4.4-style element with a long odd size.  */
2229
      filestart = last_file->origin + size;
2230
      filestart += filestart % 2;
2231
    }
2232
 
2233
  return alpha_ecoff_get_elt_at_filepos (archive, filestart);
2234
}
2235
 
2236
/* Open the archive file given an index into the armap.  */
2237
 
2238
static bfd *
2239
alpha_ecoff_get_elt_at_index (abfd, index)
2240
     bfd *abfd;
2241
     symindex index;
2242
{
2243
  carsym *entry;
2244
 
2245
  entry = bfd_ardata (abfd)->symdefs + index;
2246
  return alpha_ecoff_get_elt_at_filepos (abfd, entry->file_offset);
2247
}
2248
 
2249
/* This is the ECOFF backend structure.  The backend field of the
2250
   target vector points to this.  */
2251
 
2252
static const struct ecoff_backend_data alpha_ecoff_backend_data =
2253
{
2254
  /* COFF backend structure.  */
2255
  {
2256
    (void (*) PARAMS ((bfd *,PTR,int,int,int,int,PTR))) bfd_void, /* aux_in */
2257
    (void (*) PARAMS ((bfd *,PTR,PTR))) bfd_void, /* sym_in */
2258
    (void (*) PARAMS ((bfd *,PTR,PTR))) bfd_void, /* lineno_in */
2259
    (unsigned (*) PARAMS ((bfd *,PTR,int,int,int,int,PTR)))bfd_void,/*aux_out*/
2260
    (unsigned (*) PARAMS ((bfd *,PTR,PTR))) bfd_void, /* sym_out */
2261
    (unsigned (*) PARAMS ((bfd *,PTR,PTR))) bfd_void, /* lineno_out */
2262
    (unsigned (*) PARAMS ((bfd *,PTR,PTR))) bfd_void, /* reloc_out */
2263
    alpha_ecoff_swap_filehdr_out, alpha_ecoff_swap_aouthdr_out,
2264
    alpha_ecoff_swap_scnhdr_out,
2265
    FILHSZ, AOUTSZ, SCNHSZ, 0, 0, 0, 0, FILNMLEN, true, false, 4, false, 2,
2266
    alpha_ecoff_swap_filehdr_in, alpha_ecoff_swap_aouthdr_in,
2267
    alpha_ecoff_swap_scnhdr_in, NULL,
2268
    alpha_ecoff_bad_format_hook, _bfd_ecoff_set_arch_mach_hook,
2269
    alpha_ecoff_mkobject_hook, _bfd_ecoff_styp_to_sec_flags,
2270
    _bfd_ecoff_set_alignment_hook, _bfd_ecoff_slurp_symbol_table,
2271
    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
2272
    NULL, NULL, NULL
2273
  },
2274
  /* Supported architecture.  */
2275
  bfd_arch_alpha,
2276
  /* Initial portion of armap string.  */
2277
  "________64",
2278
  /* The page boundary used to align sections in a demand-paged
2279
     executable file.  E.g., 0x1000.  */
2280
  0x2000,
2281
  /* True if the .rdata section is part of the text segment, as on the
2282
     Alpha.  False if .rdata is part of the data segment, as on the
2283
     MIPS.  */
2284
  true,
2285
  /* Bitsize of constructor entries.  */
2286
  64,
2287
  /* Reloc to use for constructor entries.  */
2288
  &alpha_howto_table[ALPHA_R_REFQUAD],
2289
  {
2290
    /* Symbol table magic number.  */
2291
    magicSym2,
2292
    /* Alignment of debugging information.  E.g., 4.  */
2293
    8,
2294
    /* Sizes of external symbolic information.  */
2295
    sizeof (struct hdr_ext),
2296
    sizeof (struct dnr_ext),
2297
    sizeof (struct pdr_ext),
2298
    sizeof (struct sym_ext),
2299
    sizeof (struct opt_ext),
2300
    sizeof (struct fdr_ext),
2301
    sizeof (struct rfd_ext),
2302
    sizeof (struct ext_ext),
2303
    /* Functions to swap in external symbolic data.  */
2304
    ecoff_swap_hdr_in,
2305
    ecoff_swap_dnr_in,
2306
    ecoff_swap_pdr_in,
2307
    ecoff_swap_sym_in,
2308
    ecoff_swap_opt_in,
2309
    ecoff_swap_fdr_in,
2310
    ecoff_swap_rfd_in,
2311
    ecoff_swap_ext_in,
2312
    _bfd_ecoff_swap_tir_in,
2313
    _bfd_ecoff_swap_rndx_in,
2314
    /* Functions to swap out external symbolic data.  */
2315
    ecoff_swap_hdr_out,
2316
    ecoff_swap_dnr_out,
2317
    ecoff_swap_pdr_out,
2318
    ecoff_swap_sym_out,
2319
    ecoff_swap_opt_out,
2320
    ecoff_swap_fdr_out,
2321
    ecoff_swap_rfd_out,
2322
    ecoff_swap_ext_out,
2323
    _bfd_ecoff_swap_tir_out,
2324
    _bfd_ecoff_swap_rndx_out,
2325
    /* Function to read in symbolic data.  */
2326
    _bfd_ecoff_slurp_symbolic_info
2327
  },
2328
  /* External reloc size.  */
2329
  RELSZ,
2330
  /* Reloc swapping functions.  */
2331
  alpha_ecoff_swap_reloc_in,
2332
  alpha_ecoff_swap_reloc_out,
2333
  /* Backend reloc tweaking.  */
2334
  alpha_adjust_reloc_in,
2335
  alpha_adjust_reloc_out,
2336
  /* Relocate section contents while linking.  */
2337
  alpha_relocate_section,
2338
  /* Do final adjustments to filehdr and aouthdr.  */
2339
  alpha_adjust_headers,
2340
  /* Read an element from an archive at a given file position.  */
2341
  alpha_ecoff_get_elt_at_filepos
2342
};
2343
 
2344
/* Looking up a reloc type is Alpha specific.  */
2345
#define _bfd_ecoff_bfd_reloc_type_lookup alpha_bfd_reloc_type_lookup
2346
 
2347
/* So is getting relocated section contents.  */
2348
#define _bfd_ecoff_bfd_get_relocated_section_contents \
2349
  alpha_ecoff_get_relocated_section_contents
2350
 
2351
/* Handling file windows is generic.  */
2352
#define _bfd_ecoff_get_section_contents_in_window \
2353
  _bfd_generic_get_section_contents_in_window
2354
 
2355
/* Relaxing sections is generic.  */
2356
#define _bfd_ecoff_bfd_relax_section bfd_generic_relax_section
2357
#define _bfd_ecoff_bfd_gc_sections bfd_generic_gc_sections
2358
#define _bfd_ecoff_bfd_merge_sections bfd_generic_merge_sections
2359
#define _bfd_ecoff_bfd_discard_group bfd_generic_discard_group
2360
 
2361
const bfd_target ecoffalpha_little_vec =
2362
{
2363
  "ecoff-littlealpha",          /* name */
2364
  bfd_target_ecoff_flavour,
2365
  BFD_ENDIAN_LITTLE,            /* data byte order is little */
2366
  BFD_ENDIAN_LITTLE,            /* header byte order is little */
2367
 
2368
  (HAS_RELOC | EXEC_P |         /* object flags */
2369
   HAS_LINENO | HAS_DEBUG |
2370
   HAS_SYMS | HAS_LOCALS | DYNAMIC | WP_TEXT | D_PAGED),
2371
 
2372
  (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_CODE | SEC_DATA),
2373
  0,                             /* leading underscore */
2374
  ' ',                          /* ar_pad_char */
2375
  15,                           /* ar_max_namelen */
2376
  bfd_getl64, bfd_getl_signed_64, bfd_putl64,
2377
     bfd_getl32, bfd_getl_signed_32, bfd_putl32,
2378
     bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* data */
2379
  bfd_getl64, bfd_getl_signed_64, bfd_putl64,
2380
     bfd_getl32, bfd_getl_signed_32, bfd_putl32,
2381
     bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* hdrs */
2382
 
2383
  {_bfd_dummy_target, alpha_ecoff_object_p, /* bfd_check_format */
2384
     _bfd_ecoff_archive_p, _bfd_dummy_target},
2385
  {bfd_false, _bfd_ecoff_mkobject,  /* bfd_set_format */
2386
     _bfd_generic_mkarchive, bfd_false},
2387
  {bfd_false, _bfd_ecoff_write_object_contents, /* bfd_write_contents */
2388
     _bfd_write_archive_contents, bfd_false},
2389
 
2390
     BFD_JUMP_TABLE_GENERIC (_bfd_ecoff),
2391
     BFD_JUMP_TABLE_COPY (_bfd_ecoff),
2392
     BFD_JUMP_TABLE_CORE (_bfd_nocore),
2393
     BFD_JUMP_TABLE_ARCHIVE (alpha_ecoff),
2394
     BFD_JUMP_TABLE_SYMBOLS (_bfd_ecoff),
2395
     BFD_JUMP_TABLE_RELOCS (_bfd_ecoff),
2396
     BFD_JUMP_TABLE_WRITE (_bfd_ecoff),
2397
     BFD_JUMP_TABLE_LINK (_bfd_ecoff),
2398
     BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
2399
 
2400
  NULL,
2401
 
2402
  (PTR) &alpha_ecoff_backend_data
2403
};

powered by: WebSVN 2.1.0

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