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