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