* sunos.c (m68k_plt_first_entry, sparc_plt_first_entry): Now const.
[platform/upstream/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., 675 Mass Ave, Cambridge, MA 02139, 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 CONST struct reloc_howto_struct *
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 (CONST struct reloc_howto_struct *) 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     {
1258       asection *hsec;
1259       const char *name;
1260
1261       /* This symbol is defined in the output.  Convert the reloc from
1262          being against the symbol to being against the section.  */
1263
1264       /* Clear the r_extern bit.  */
1265       ext_rel->r_bits[1] &=~ RELOC_BITS1_EXTERN_LITTLE;
1266
1267       /* Compute a new r_symndx value.  */
1268       hsec = h->root.u.def.section;
1269       name = bfd_get_section_name (output_bfd, hsec->output_section);
1270
1271       r_symndx = -1;
1272       switch (name[1])
1273         {
1274         case 'A':
1275           if (strcmp (name, "*ABS*") == 0)
1276             r_symndx = RELOC_SECTION_ABS;
1277           break;
1278         case 'b':
1279           if (strcmp (name, ".bss") == 0)
1280             r_symndx = RELOC_SECTION_BSS;
1281           break;
1282         case 'd':
1283           if (strcmp (name, ".data") == 0)
1284             r_symndx = RELOC_SECTION_DATA;
1285           break;
1286         case 'f':
1287           if (strcmp (name, ".fini") == 0)
1288             r_symndx = RELOC_SECTION_FINI;
1289           break;
1290         case 'i':
1291           if (strcmp (name, ".init") == 0)
1292             r_symndx = RELOC_SECTION_INIT;
1293           break;
1294         case 'l':
1295           if (strcmp (name, ".lita") == 0)
1296             r_symndx = RELOC_SECTION_LITA;
1297           else if (strcmp (name, ".lit8") == 0)
1298             r_symndx = RELOC_SECTION_LIT8;
1299           else if (strcmp (name, ".lit4") == 0)
1300             r_symndx = RELOC_SECTION_LIT4;
1301           break;
1302         case 'p':
1303           if (strcmp (name, ".pdata") == 0)
1304             r_symndx = RELOC_SECTION_PDATA;
1305           break;
1306         case 'r':
1307           if (strcmp (name, ".rdata") == 0)
1308             r_symndx = RELOC_SECTION_RDATA;
1309           break;
1310         case 's':
1311           if (strcmp (name, ".sdata") == 0)
1312             r_symndx = RELOC_SECTION_SDATA;
1313           else if (strcmp (name, ".sbss") == 0)
1314             r_symndx = RELOC_SECTION_SBSS;
1315           break;
1316         case 't':
1317           if (strcmp (name, ".text") == 0)
1318             r_symndx = RELOC_SECTION_TEXT;
1319           break;
1320         case 'x':
1321           if (strcmp (name, ".xdata") == 0)
1322             r_symndx = RELOC_SECTION_XDATA;
1323           break;
1324         }
1325                       
1326       if (r_symndx == -1)
1327         abort ();
1328
1329       /* Add the section VMA and the symbol value.  */
1330       relocation = (h->root.u.def.value
1331                     + hsec->output_section->vma
1332                     + hsec->output_offset);
1333     }
1334   else
1335     {
1336       /* Change the symndx value to the right one for
1337          the output BFD.  */
1338       r_symndx = h->indx;
1339       if (r_symndx == -1)
1340         {
1341           /* Caller must give an error.  */
1342           r_symndx = 0;
1343         }
1344       relocation = 0;
1345     }
1346
1347   /* Write out the new r_symndx value.  */
1348   bfd_h_put_32 (input_bfd, (bfd_vma) r_symndx,
1349                 (bfd_byte *) ext_rel->r_symndx);
1350
1351   return relocation;
1352 }
1353
1354 /* Relocate a section while linking an Alpha ECOFF file.  This is
1355    quite similar to get_relocated_section_contents.  Perhaps they
1356    could be combined somehow.  */
1357
1358 static boolean
1359 alpha_relocate_section (output_bfd, info, input_bfd, input_section,
1360                         contents, external_relocs)
1361      bfd *output_bfd;
1362      struct bfd_link_info *info;
1363      bfd *input_bfd;
1364      asection *input_section;
1365      bfd_byte *contents;
1366      PTR external_relocs;
1367 {
1368   asection **symndx_to_section;
1369   struct ecoff_link_hash_entry **sym_hashes;
1370   bfd_vma gp;
1371   boolean gp_undefined;
1372   bfd_vma stack[RELOC_STACKSIZE];
1373   int tos = 0;
1374   struct external_reloc *ext_rel;
1375   struct external_reloc *ext_rel_end;
1376
1377   /* We keep a table mapping the symndx found in an internal reloc to
1378      the appropriate section.  This is faster than looking up the
1379      section by name each time.  */
1380   symndx_to_section = ecoff_data (input_bfd)->symndx_to_section;
1381   if (symndx_to_section == (asection **) NULL)
1382     {
1383       symndx_to_section = ((asection **)
1384                            bfd_alloc (input_bfd,
1385                                       (NUM_RELOC_SECTIONS
1386                                        * sizeof (asection *))));
1387       if (!symndx_to_section)
1388         {
1389           bfd_set_error (bfd_error_no_memory);
1390           return false;
1391         }
1392
1393       symndx_to_section[RELOC_SECTION_NONE] = NULL;
1394       symndx_to_section[RELOC_SECTION_TEXT] =
1395         bfd_get_section_by_name (input_bfd, ".text");
1396       symndx_to_section[RELOC_SECTION_RDATA] =
1397         bfd_get_section_by_name (input_bfd, ".rdata");
1398       symndx_to_section[RELOC_SECTION_DATA] =
1399         bfd_get_section_by_name (input_bfd, ".data");
1400       symndx_to_section[RELOC_SECTION_SDATA] =
1401         bfd_get_section_by_name (input_bfd, ".sdata");
1402       symndx_to_section[RELOC_SECTION_SBSS] =
1403         bfd_get_section_by_name (input_bfd, ".sbss");
1404       symndx_to_section[RELOC_SECTION_BSS] =
1405         bfd_get_section_by_name (input_bfd, ".bss");
1406       symndx_to_section[RELOC_SECTION_INIT] =
1407         bfd_get_section_by_name (input_bfd, ".init");
1408       symndx_to_section[RELOC_SECTION_LIT8] =
1409         bfd_get_section_by_name (input_bfd, ".lit8");
1410       symndx_to_section[RELOC_SECTION_LIT4] =
1411         bfd_get_section_by_name (input_bfd, ".lit4");
1412       symndx_to_section[RELOC_SECTION_XDATA] =
1413         bfd_get_section_by_name (input_bfd, ".xdata");
1414       symndx_to_section[RELOC_SECTION_PDATA] =
1415         bfd_get_section_by_name (input_bfd, ".pdata");
1416       symndx_to_section[RELOC_SECTION_FINI] =
1417         bfd_get_section_by_name (input_bfd, ".fini");
1418       symndx_to_section[RELOC_SECTION_LITA] =
1419         bfd_get_section_by_name (input_bfd, ".lita");
1420       symndx_to_section[RELOC_SECTION_ABS] = bfd_abs_section_ptr;
1421
1422       ecoff_data (input_bfd)->symndx_to_section = symndx_to_section;
1423     }
1424
1425   sym_hashes = ecoff_data (input_bfd)->sym_hashes;
1426
1427   gp = ecoff_data (output_bfd)->gp;
1428   if (gp == 0)
1429     gp_undefined = true;
1430   else
1431     gp_undefined = false;
1432
1433   BFD_ASSERT (output_bfd->xvec->header_byteorder_big_p == false);
1434   BFD_ASSERT (input_bfd->xvec->header_byteorder_big_p == false);
1435
1436   ext_rel = (struct external_reloc *) external_relocs;
1437   ext_rel_end = ext_rel + input_section->reloc_count;
1438   for (; ext_rel < ext_rel_end; ext_rel++)
1439     {
1440       bfd_vma r_vaddr;
1441       unsigned long r_symndx;
1442       int r_type;
1443       int r_extern;
1444       int r_offset;
1445       int r_size;
1446       boolean relocatep;
1447       boolean adjust_addrp;
1448       boolean gp_usedp;
1449       bfd_vma addend;
1450
1451       r_vaddr = bfd_h_get_64 (input_bfd, (bfd_byte *) ext_rel->r_vaddr);
1452       r_symndx = bfd_h_get_32 (input_bfd, (bfd_byte *) ext_rel->r_symndx);
1453
1454       r_type = ((ext_rel->r_bits[0] & RELOC_BITS0_TYPE_LITTLE)
1455                 >> RELOC_BITS0_TYPE_SH_LITTLE);
1456       r_extern = (ext_rel->r_bits[1] & RELOC_BITS1_EXTERN_LITTLE) != 0;
1457       r_offset = ((ext_rel->r_bits[1] & RELOC_BITS1_OFFSET_LITTLE)
1458                   >> RELOC_BITS1_OFFSET_SH_LITTLE);
1459       /* Ignored the reserved bits.  */
1460       r_size = ((ext_rel->r_bits[3] & RELOC_BITS3_SIZE_LITTLE)
1461                 >> RELOC_BITS3_SIZE_SH_LITTLE);
1462
1463       relocatep = false;
1464       adjust_addrp = true;
1465       gp_usedp = false;
1466       addend = 0;
1467
1468       switch (r_type)
1469         {
1470         default:
1471           abort ();
1472
1473         case ALPHA_R_IGNORE:
1474           /* This reloc appears after a GPDISP reloc.  It marks the
1475              position of the second instruction to be altered by the
1476              GPDISP reloc, but is not otherwise used for anything.
1477              For some reason, the address of the relocation does not
1478              appear to include the section VMA, unlike the other
1479              relocation types.  */
1480           if (info->relocateable)
1481             bfd_h_put_64 (input_bfd,
1482                           input_section->output_offset + r_vaddr,
1483                           (bfd_byte *) ext_rel->r_vaddr);
1484           adjust_addrp = false;
1485           break;
1486
1487         case ALPHA_R_REFLONG:
1488         case ALPHA_R_REFQUAD:
1489         case ALPHA_R_BRADDR:
1490         case ALPHA_R_HINT:
1491         case ALPHA_R_SREL16:
1492         case ALPHA_R_SREL32:
1493         case ALPHA_R_SREL64:
1494           relocatep = true;
1495           break;
1496
1497         case ALPHA_R_GPREL32:
1498           /* This relocation is used in a switch table.  It is a 32
1499              bit offset from the current GP value.  We must adjust it
1500              by the different between the original GP value and the
1501              current GP value.  */
1502           relocatep = true;
1503           addend = ecoff_data (input_bfd)->gp - gp;
1504           gp_usedp = true;
1505           break;
1506
1507         case ALPHA_R_LITERAL:
1508           /* This is a reference to a literal value, generally
1509              (always?) in the .lita section.  This is a 16 bit GP
1510              relative relocation.  Sometimes the subsequent reloc is a
1511              LITUSE reloc, which indicates how this reloc is used.
1512              This sometimes permits rewriting the two instructions
1513              referred to by the LITERAL and the LITUSE into different
1514              instructions which do not refer to .lita.  This can save
1515              a memory reference, and permits removing a value from
1516              .lita thus saving GP relative space.
1517
1518              We do not these optimizations.  To do them we would need
1519              to arrange to link the .lita section first, so that by
1520              the time we got here we would know the final values to
1521              use.  This would not be particularly difficult, but it is
1522              not currently implemented.  */
1523
1524           /* I believe that the LITERAL reloc will only apply to a ldq
1525              or ldl instruction, so check my assumption.  */
1526           {
1527             unsigned long insn;
1528
1529             insn = bfd_get_32 (input_bfd,
1530                                contents + r_vaddr - input_section->vma);
1531             BFD_ASSERT (((insn >> 26) & 0x3f) == 0x29
1532                         || ((insn >> 26) & 0x3f) == 0x28);
1533           }
1534
1535           relocatep = true;
1536           addend = ecoff_data (input_bfd)->gp - gp;
1537           gp_usedp = true;
1538           break;
1539
1540         case ALPHA_R_LITUSE:
1541           /* See ALPHA_R_LITERAL above for the uses of this reloc.  It
1542              does not cause anything to happen, itself.  */
1543           break;
1544             
1545         case ALPHA_R_GPDISP:
1546           /* This marks the ldah of an ldah/lda pair which loads the
1547              gp register with the difference of the gp value and the
1548              current location.  The second of the pair is r_symndx
1549              bytes ahead, and is also marked with an ALPHA_R_IGNORE
1550              reloc.  */
1551           {
1552             unsigned long insn1, insn2;
1553
1554             BFD_ASSERT (ext_rel + 1 < ext_rel_end
1555                         && (((ext_rel + 1)->r_bits[0]
1556                              & RELOC_BITS0_TYPE_LITTLE)
1557                             >> RELOC_BITS0_TYPE_SH_LITTLE) == ALPHA_R_IGNORE
1558                         && (bfd_h_get_64 (input_bfd,
1559                                           (bfd_byte *) (ext_rel + 1)->r_vaddr)
1560                             == r_vaddr - input_section->vma + r_symndx));
1561
1562             /* Get the two instructions.  */
1563             insn1 = bfd_get_32 (input_bfd,
1564                                 contents + r_vaddr - input_section->vma);
1565             insn2 = bfd_get_32 (input_bfd,
1566                                 (contents
1567                                  + r_vaddr
1568                                  - input_section->vma
1569                                  + r_symndx));
1570
1571             BFD_ASSERT (((insn1 >> 26) & 0x3f) == 0x09); /* ldah */
1572             BFD_ASSERT (((insn2 >> 26) & 0x3f) == 0x08); /* lda */
1573
1574             /* Get the existing addend.  We must account for the sign
1575                extension done by lda and ldah.  */
1576             addend = ((insn1 & 0xffff) << 16) + (insn2 & 0xffff);
1577             if (insn1 & 0x8000)
1578               {
1579                 /* This is addend -= 0x100000000 without causing an
1580                    integer overflow on a 32 bit host.  */
1581                 addend -= 0x80000000;
1582                 addend -= 0x80000000;
1583               }
1584             if (insn2 & 0x8000)
1585               addend -= 0x10000;
1586
1587             /* The existing addend includes the difference between the
1588                gp of the input BFD and the address in the input BFD.
1589                We want to change this to the difference between the
1590                final GP and the final address.  */
1591             addend += (gp
1592                        - ecoff_data (input_bfd)->gp
1593                        + input_section->vma
1594                        - (input_section->output_section->vma
1595                           + input_section->output_offset));
1596
1597             /* Change the instructions, accounting for the sign
1598                extension, and write them out.  */
1599             if (addend & 0x8000)
1600               addend += 0x10000;
1601             insn1 = (insn1 & 0xffff0000) | ((addend >> 16) & 0xffff);
1602             insn2 = (insn2 & 0xffff0000) | (addend & 0xffff);
1603
1604             bfd_put_32 (input_bfd, (bfd_vma) insn1,
1605                         contents + r_vaddr - input_section->vma);
1606             bfd_put_32 (input_bfd, (bfd_vma) insn2,
1607                         contents + r_vaddr - input_section->vma + r_symndx);
1608
1609             gp_usedp = true;
1610           }
1611           break;
1612           
1613         case ALPHA_R_OP_PUSH:
1614         case ALPHA_R_OP_PSUB:
1615         case ALPHA_R_OP_PRSHIFT:
1616           /* Manipulate values on the reloc evaluation stack.  The
1617              r_vaddr field is not an address in input_section, it is
1618              the current value (including any addend) of the object
1619              being used.  */
1620           if (! r_extern)
1621             {
1622               asection *s;
1623
1624               s = symndx_to_section[r_symndx];
1625               if (s == (asection *) NULL)
1626                 abort ();
1627               addend = s->output_section->vma + s->output_offset - s->vma;
1628             }
1629           else
1630             {
1631               struct ecoff_link_hash_entry *h;
1632
1633               h = sym_hashes[r_symndx];
1634               if (h == (struct ecoff_link_hash_entry *) NULL)
1635                 abort ();
1636
1637               if (! info->relocateable)
1638                 {
1639                   if (h->root.type == bfd_link_hash_defined)
1640                     addend = (h->root.u.def.value
1641                               + h->root.u.def.section->output_section->vma
1642                               + h->root.u.def.section->output_offset);
1643                   else
1644                     {
1645                       /* Note that we pass the address as 0, since we
1646                          do not have a meaningful number for the
1647                          location within the section that is being
1648                          relocated.  */
1649                       if (! ((*info->callbacks->undefined_symbol)
1650                              (info, h->root.root.string, input_bfd,
1651                               input_section, (bfd_vma) 0)))
1652                         return false;
1653                       addend = 0;
1654                     }
1655                 }
1656               else
1657                 {
1658                   if (h->root.type != bfd_link_hash_defined
1659                       && h->indx == -1)
1660                     {
1661                       /* This symbol is not being written out.  Pass
1662                          the address as 0, as with undefined_symbol,
1663                          above.  */
1664                       if (! ((*info->callbacks->unattached_reloc)
1665                              (info, h->root.root.string, input_bfd,
1666                               input_section, (bfd_vma) 0)))
1667                         return false;
1668                     }
1669
1670                   addend = alpha_convert_external_reloc (output_bfd, info,
1671                                                          input_bfd,
1672                                                          ext_rel, h);
1673                 }
1674             }
1675
1676           addend += r_vaddr;
1677
1678           if (info->relocateable)
1679             {
1680               /* Adjust r_vaddr by the addend.  */
1681               bfd_h_put_64 (input_bfd, addend,
1682                             (bfd_byte *) ext_rel->r_vaddr);
1683             }
1684           else
1685             {
1686               switch (r_type)
1687                 {
1688                 case ALPHA_R_OP_PUSH:
1689                   if (tos >= RELOC_STACKSIZE)
1690                     abort ();
1691                   stack[tos++] = addend;
1692                   break;
1693
1694                 case ALPHA_R_OP_PSUB:
1695                   if (tos == 0)
1696                     abort ();
1697                   stack[tos - 1] -= addend;
1698                   break;
1699
1700                 case ALPHA_R_OP_PRSHIFT:
1701                   if (tos == 0)
1702                     abort ();
1703                   stack[tos - 1] >>= addend;
1704                   break;
1705                 }
1706             }
1707
1708           adjust_addrp = false;
1709           break;
1710
1711         case ALPHA_R_OP_STORE:
1712           /* Store a value from the reloc stack into a bitfield.  If
1713              we are generating relocateable output, all we do is
1714              adjust the address of the reloc.  */
1715           if (! info->relocateable)
1716             {
1717               bfd_vma mask;
1718               bfd_vma val;
1719
1720               if (tos == 0)
1721                 abort ();
1722
1723               /* Get the relocation mask.  The separate steps and the
1724                  casts to bfd_vma are attempts to avoid a bug in the
1725                  Alpha OSF 1.3 C compiler.  See reloc.c for more
1726                  details.  */
1727               mask = 1;
1728               mask <<= (bfd_vma) r_size;
1729               mask -= 1;
1730
1731               /* FIXME: I don't know what kind of overflow checking,
1732                  if any, should be done here.  */
1733               val = bfd_get_64 (input_bfd,
1734                                 contents + r_vaddr - input_section->vma);
1735               val &=~ mask << (bfd_vma) r_offset;
1736               val |= (stack[--tos] & mask) << (bfd_vma) r_offset;
1737               bfd_put_64 (input_bfd, val,
1738                           contents + r_vaddr - input_section->vma);
1739             }
1740           break;
1741
1742         case ALPHA_R_GPVALUE:
1743           /* I really don't know if this does the right thing.  */
1744           gp = ecoff_data (input_bfd)->gp + r_symndx;
1745           gp_undefined = false;
1746           break;
1747         }
1748
1749       if (relocatep)
1750         {
1751           reloc_howto_type *howto;
1752           struct ecoff_link_hash_entry *h = NULL;
1753           asection *s = NULL;
1754           bfd_vma relocation;
1755           bfd_reloc_status_type r;
1756
1757           /* Perform a relocation.  */
1758
1759           howto = &alpha_howto_table[r_type];
1760
1761           if (r_extern)
1762             {
1763               h = sym_hashes[r_symndx];
1764               /* If h is NULL, that means that there is a reloc
1765                  against an external symbol which we thought was just
1766                  a debugging symbol.  This should not happen.  */
1767               if (h == (struct ecoff_link_hash_entry *) NULL)
1768                 abort ();
1769             }
1770           else
1771             {
1772               if (r_symndx >= NUM_RELOC_SECTIONS)
1773                 s = NULL;
1774               else
1775                 s = symndx_to_section[r_symndx];
1776
1777               if (s == (asection *) NULL)
1778                 abort ();
1779             }
1780
1781           if (info->relocateable)
1782             {
1783               /* We are generating relocateable output, and must
1784                  convert the existing reloc.  */
1785               if (r_extern)
1786                 {
1787                   if (h->root.type != bfd_link_hash_defined
1788                       && h->indx == -1)
1789                     {
1790                       /* This symbol is not being written out.  */
1791                       if (! ((*info->callbacks->unattached_reloc)
1792                              (info, h->root.root.string, input_bfd,
1793                               input_section, r_vaddr - input_section->vma)))
1794                         return false;
1795                     }
1796
1797                   relocation = alpha_convert_external_reloc (output_bfd,
1798                                                              info,
1799                                                              input_bfd,
1800                                                              ext_rel,
1801                                                              h);
1802                 }
1803               else
1804                 {
1805                   /* This is a relocation against a section.  Adjust
1806                      the value by the amount the section moved.  */
1807                   relocation = (s->output_section->vma
1808                                 + s->output_offset
1809                                 - s->vma);
1810                 }
1811
1812               /* If this is PC relative, the existing object file
1813                  appears to already have the reloc worked out.  We
1814                  must subtract out the old value and add in the new
1815                  one.  */
1816               if (howto->pc_relative)
1817                 relocation -= (input_section->output_section->vma
1818                                + input_section->output_offset
1819                                - input_section->vma);
1820
1821               /* Put in any addend.  */
1822               relocation += addend;
1823
1824               /* Adjust the contents.  */
1825               r = _bfd_relocate_contents (howto, input_bfd, relocation,
1826                                           (contents
1827                                            + r_vaddr
1828                                            - input_section->vma));
1829             }
1830           else
1831             {
1832               /* We are producing a final executable.  */
1833               if (r_extern)
1834                 {
1835                   /* This is a reloc against a symbol.  */
1836                   if (h->root.type == bfd_link_hash_defined)
1837                     {
1838                       asection *hsec;
1839
1840                       hsec = h->root.u.def.section;
1841                       relocation = (h->root.u.def.value
1842                                     + hsec->output_section->vma
1843                                     + hsec->output_offset);
1844                     }
1845                   else
1846                     {
1847                       if (! ((*info->callbacks->undefined_symbol)
1848                              (info, h->root.root.string, input_bfd,
1849                               input_section,
1850                               r_vaddr - input_section->vma)))
1851                         return false;
1852                       relocation = 0;
1853                     }
1854                 }
1855               else
1856                 {
1857                   /* This is a reloc against a section.  */
1858                   relocation = (s->output_section->vma
1859                                 + s->output_offset
1860                                 - s->vma);
1861
1862                   /* Adjust a PC relative relocation by removing the
1863                      reference to the original source section.  */
1864                   if (howto->pc_relative)
1865                     relocation += input_section->vma;
1866                 }
1867
1868               r = _bfd_final_link_relocate (howto,
1869                                             input_bfd,
1870                                             input_section,
1871                                             contents,
1872                                             r_vaddr - input_section->vma,
1873                                             relocation,
1874                                             addend);
1875             }
1876
1877           if (r != bfd_reloc_ok)
1878             {
1879               switch (r)
1880                 {
1881                 default:
1882                 case bfd_reloc_outofrange:
1883                   abort ();
1884                 case bfd_reloc_overflow:
1885                   {
1886                     const char *name;
1887
1888                     if (r_extern)
1889                       name = sym_hashes[r_symndx]->root.root.string;
1890                     else
1891                       name = bfd_section_name (input_bfd,
1892                                                symndx_to_section[r_symndx]);
1893                     if (! ((*info->callbacks->reloc_overflow)
1894                            (info, name, alpha_howto_table[r_type].name,
1895                             (bfd_vma) 0, input_bfd, input_section,
1896                             r_vaddr - input_section->vma)))
1897                       return false;
1898                   }
1899                   break;
1900                 }
1901             }
1902         }
1903
1904       if (info->relocateable && adjust_addrp)
1905         {
1906           /* Change the address of the relocation.  */
1907           bfd_h_put_64 (input_bfd,
1908                         (input_section->output_section->vma
1909                          + input_section->output_offset
1910                          - input_section->vma
1911                          + r_vaddr),
1912                         (bfd_byte *) ext_rel->r_vaddr);
1913         }
1914
1915       if (gp_usedp && gp_undefined)
1916         {
1917           if (! ((*info->callbacks->reloc_dangerous)
1918                  (info, "GP relative relocation when GP not defined",
1919                   input_bfd, input_section, r_vaddr - input_section->vma)))
1920             return false;
1921           /* Only give the error once per link.  */
1922           ecoff_data (output_bfd)->gp = gp = 4;
1923           gp_undefined = false;
1924         }
1925     }
1926
1927   if (tos != 0)
1928     abort ();
1929
1930   return true;
1931 }
1932 \f
1933 /* This is the ECOFF backend structure.  The backend field of the
1934    target vector points to this.  */
1935
1936 static const struct ecoff_backend_data alpha_ecoff_backend_data =
1937 {
1938   /* COFF backend structure.  */
1939   {
1940     (void (*) PARAMS ((bfd *,PTR,int,int,int,int,PTR))) bfd_void, /* aux_in */
1941     (void (*) PARAMS ((bfd *,PTR,PTR))) bfd_void, /* sym_in */
1942     (void (*) PARAMS ((bfd *,PTR,PTR))) bfd_void, /* lineno_in */
1943     (unsigned (*) PARAMS ((bfd *,PTR,int,int,int,int,PTR)))bfd_void,/*aux_out*/
1944     (unsigned (*) PARAMS ((bfd *,PTR,PTR))) bfd_void, /* sym_out */
1945     (unsigned (*) PARAMS ((bfd *,PTR,PTR))) bfd_void, /* lineno_out */
1946     (unsigned (*) PARAMS ((bfd *,PTR,PTR))) bfd_void, /* reloc_out */
1947     alpha_ecoff_swap_filehdr_out, alpha_ecoff_swap_aouthdr_out,
1948     alpha_ecoff_swap_scnhdr_out,
1949     FILHSZ, AOUTSZ, SCNHSZ, 0, 0, 0, 0, true,
1950     alpha_ecoff_swap_filehdr_in, alpha_ecoff_swap_aouthdr_in,
1951     alpha_ecoff_swap_scnhdr_in, NULL,
1952     alpha_ecoff_bad_format_hook, _bfd_ecoff_set_arch_mach_hook,
1953     alpha_ecoff_mkobject_hook, _bfd_ecoff_styp_to_sec_flags,
1954     _bfd_ecoff_make_section_hook, _bfd_ecoff_set_alignment_hook,
1955     _bfd_ecoff_slurp_symbol_table,
1956     NULL, NULL, NULL, NULL, NULL, NULL
1957   },
1958   /* Supported architecture.  */
1959   bfd_arch_alpha,
1960   /* Initial portion of armap string.  */
1961   "________64",
1962   /* The page boundary used to align sections in a demand-paged
1963      executable file.  E.g., 0x1000.  */
1964   0x2000,
1965   /* True if the .rdata section is part of the text segment, as on the
1966      Alpha.  False if .rdata is part of the data segment, as on the
1967      MIPS.  */
1968   true,
1969   /* Bitsize of constructor entries.  */
1970   64,
1971   /* Reloc to use for constructor entries.  */
1972   &alpha_howto_table[ALPHA_R_REFQUAD],
1973   {
1974     /* Symbol table magic number.  */
1975     magicSym2,
1976     /* Alignment of debugging information.  E.g., 4.  */
1977     8,
1978     /* Sizes of external symbolic information.  */
1979     sizeof (struct hdr_ext),
1980     sizeof (struct dnr_ext),
1981     sizeof (struct pdr_ext),
1982     sizeof (struct sym_ext),
1983     sizeof (struct opt_ext),
1984     sizeof (struct fdr_ext),
1985     sizeof (struct rfd_ext),
1986     sizeof (struct ext_ext),
1987     /* Functions to swap in external symbolic data.  */
1988     ecoff_swap_hdr_in,
1989     ecoff_swap_dnr_in,
1990     ecoff_swap_pdr_in,
1991     ecoff_swap_sym_in,
1992     ecoff_swap_opt_in,
1993     ecoff_swap_fdr_in,
1994     ecoff_swap_rfd_in,
1995     ecoff_swap_ext_in,
1996     _bfd_ecoff_swap_tir_in,
1997     _bfd_ecoff_swap_rndx_in,
1998     /* Functions to swap out external symbolic data.  */
1999     ecoff_swap_hdr_out,
2000     ecoff_swap_dnr_out,
2001     ecoff_swap_pdr_out,
2002     ecoff_swap_sym_out,
2003     ecoff_swap_opt_out,
2004     ecoff_swap_fdr_out,
2005     ecoff_swap_rfd_out,
2006     ecoff_swap_ext_out,
2007     _bfd_ecoff_swap_tir_out,
2008     _bfd_ecoff_swap_rndx_out,
2009     /* Function to read in symbolic data.  */
2010     _bfd_ecoff_slurp_symbolic_info
2011   },
2012   /* External reloc size.  */
2013   RELSZ,
2014   /* Reloc swapping functions.  */
2015   alpha_ecoff_swap_reloc_in,
2016   alpha_ecoff_swap_reloc_out,
2017   /* Backend reloc tweaking.  */
2018   alpha_adjust_reloc_in,
2019   alpha_adjust_reloc_out,
2020   /* Relocate section contents while linking.  */
2021   alpha_relocate_section
2022 };
2023
2024 /* Looking up a reloc type is Alpha specific.  */
2025 #define _bfd_ecoff_bfd_reloc_type_lookup alpha_bfd_reloc_type_lookup
2026
2027 /* So is getting relocated section contents.  */
2028 #define _bfd_ecoff_bfd_get_relocated_section_contents \
2029   alpha_ecoff_get_relocated_section_contents
2030
2031 /* Relaxing sections is generic.  */
2032 #define _bfd_ecoff_bfd_relax_section bfd_generic_relax_section
2033
2034 const bfd_target ecoffalpha_little_vec =
2035 {
2036   "ecoff-littlealpha",          /* name */
2037   bfd_target_ecoff_flavour,
2038   false,                        /* data byte order is little */
2039   false,                        /* header byte order is little */
2040
2041   (HAS_RELOC | EXEC_P |         /* object flags */
2042    HAS_LINENO | HAS_DEBUG |
2043    HAS_SYMS | HAS_LOCALS | DYNAMIC | WP_TEXT | D_PAGED),
2044
2045   (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* sect
2046                                                             flags */
2047   0,                            /* leading underscore */
2048   ' ',                          /* ar_pad_char */
2049   15,                           /* ar_max_namelen */
2050   4,                            /* minimum alignment power */
2051   bfd_getl64, bfd_getl_signed_64, bfd_putl64,
2052      bfd_getl32, bfd_getl_signed_32, bfd_putl32,
2053      bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* data */
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, /* hdrs */
2057
2058   {_bfd_dummy_target, alpha_ecoff_object_p, /* bfd_check_format */
2059      _bfd_ecoff_archive_p, _bfd_dummy_target},
2060   {bfd_false, _bfd_ecoff_mkobject,  /* bfd_set_format */
2061      _bfd_generic_mkarchive, bfd_false},
2062   {bfd_false, _bfd_ecoff_write_object_contents, /* bfd_write_contents */
2063      _bfd_write_archive_contents, bfd_false},
2064
2065      BFD_JUMP_TABLE_GENERIC (_bfd_ecoff),
2066      BFD_JUMP_TABLE_COPY (_bfd_ecoff),
2067      BFD_JUMP_TABLE_CORE (_bfd_nocore),
2068      BFD_JUMP_TABLE_ARCHIVE (_bfd_ecoff),
2069      BFD_JUMP_TABLE_SYMBOLS (_bfd_ecoff),
2070      BFD_JUMP_TABLE_RELOCS (_bfd_ecoff),
2071      BFD_JUMP_TABLE_WRITE (_bfd_ecoff),
2072      BFD_JUMP_TABLE_LINK (_bfd_ecoff),
2073      BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
2074
2075   (PTR) &alpha_ecoff_backend_data
2076 };