Back to index

cell-binutils  2.17cvs20070401
coff-alpha.c
Go to the documentation of this file.
00001 /* BFD back-end for ALPHA Extended-Coff files.
00002    Copyright 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
00003    2003, 2004, 2005, 2007 Free Software Foundation, Inc.
00004    Modified from coff-mips.c by Steve Chamberlain <sac@cygnus.com> and
00005    Ian Lance Taylor <ian@cygnus.com>.
00006 
00007 This file is part of BFD, the Binary File Descriptor library.
00008 
00009 This program is free software; you can redistribute it and/or modify
00010 it under the terms of the GNU General Public License as published by
00011 the Free Software Foundation; either version 2 of the License, or
00012 (at your option) any later version.
00013 
00014 This program is distributed in the hope that it will be useful,
00015 but WITHOUT ANY WARRANTY; without even the implied warranty of
00016 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00017 GNU General Public License for more details.
00018 
00019 You should have received a copy of the GNU General Public License
00020 along with this program; if not, write to the Free Software
00021 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.  */
00022 
00023 #include "bfd.h"
00024 #include "sysdep.h"
00025 #include "bfdlink.h"
00026 #include "libbfd.h"
00027 #include "coff/internal.h"
00028 #include "coff/sym.h"
00029 #include "coff/symconst.h"
00030 #include "coff/ecoff.h"
00031 #include "coff/alpha.h"
00032 #include "aout/ar.h"
00033 #include "libcoff.h"
00034 #include "libecoff.h"
00035 
00036 /* Prototypes for static functions.  */
00037 
00038 static const bfd_target *alpha_ecoff_object_p
00039   PARAMS ((bfd *));
00040 static bfd_boolean alpha_ecoff_bad_format_hook
00041   PARAMS ((bfd *abfd, PTR filehdr));
00042 static PTR alpha_ecoff_mkobject_hook
00043   PARAMS ((bfd *, PTR filehdr, PTR aouthdr));
00044 static void alpha_ecoff_swap_reloc_in
00045   PARAMS ((bfd *, PTR, struct internal_reloc *));
00046 static void alpha_ecoff_swap_reloc_out
00047   PARAMS ((bfd *, const struct internal_reloc *, PTR));
00048 static void alpha_adjust_reloc_in
00049   PARAMS ((bfd *, const struct internal_reloc *, arelent *));
00050 static void alpha_adjust_reloc_out
00051   PARAMS ((bfd *, const arelent *, struct internal_reloc *));
00052 static reloc_howto_type *alpha_bfd_reloc_type_lookup
00053   PARAMS ((bfd *, bfd_reloc_code_real_type));
00054 static bfd_byte *alpha_ecoff_get_relocated_section_contents
00055   PARAMS ((bfd *abfd, struct bfd_link_info *, struct bfd_link_order *,
00056           bfd_byte *data, bfd_boolean relocatable, asymbol **symbols));
00057 static bfd_vma alpha_convert_external_reloc
00058   PARAMS ((bfd *, struct bfd_link_info *, bfd *, struct external_reloc *,
00059           struct ecoff_link_hash_entry *));
00060 static bfd_boolean alpha_relocate_section
00061   PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *, PTR));
00062 static bfd_boolean alpha_adjust_headers
00063   PARAMS ((bfd *, struct internal_filehdr *, struct internal_aouthdr *));
00064 static PTR alpha_ecoff_read_ar_hdr
00065   PARAMS ((bfd *));
00066 static bfd *alpha_ecoff_get_elt_at_filepos
00067   PARAMS ((bfd *, file_ptr));
00068 static bfd *alpha_ecoff_openr_next_archived_file
00069   PARAMS ((bfd *, bfd *));
00070 static bfd *alpha_ecoff_get_elt_at_index
00071   PARAMS ((bfd *, symindex));
00072 
00073 /* ECOFF has COFF sections, but the debugging information is stored in
00074    a completely different format.  ECOFF targets use some of the
00075    swapping routines from coffswap.h, and some of the generic COFF
00076    routines in coffgen.c, but, unlike the real COFF targets, do not
00077    use coffcode.h itself.
00078 
00079    Get the generic COFF swapping routines, except for the reloc,
00080    symbol, and lineno ones.  Give them ecoff names.  Define some
00081    accessor macros for the large sizes used for Alpha ECOFF.  */
00082 
00083 #define GET_FILEHDR_SYMPTR H_GET_64
00084 #define PUT_FILEHDR_SYMPTR H_PUT_64
00085 #define GET_AOUTHDR_TSIZE H_GET_64
00086 #define PUT_AOUTHDR_TSIZE H_PUT_64
00087 #define GET_AOUTHDR_DSIZE H_GET_64
00088 #define PUT_AOUTHDR_DSIZE H_PUT_64
00089 #define GET_AOUTHDR_BSIZE H_GET_64
00090 #define PUT_AOUTHDR_BSIZE H_PUT_64
00091 #define GET_AOUTHDR_ENTRY H_GET_64
00092 #define PUT_AOUTHDR_ENTRY H_PUT_64
00093 #define GET_AOUTHDR_TEXT_START H_GET_64
00094 #define PUT_AOUTHDR_TEXT_START H_PUT_64
00095 #define GET_AOUTHDR_DATA_START H_GET_64
00096 #define PUT_AOUTHDR_DATA_START H_PUT_64
00097 #define GET_SCNHDR_PADDR H_GET_64
00098 #define PUT_SCNHDR_PADDR H_PUT_64
00099 #define GET_SCNHDR_VADDR H_GET_64
00100 #define PUT_SCNHDR_VADDR H_PUT_64
00101 #define GET_SCNHDR_SIZE H_GET_64
00102 #define PUT_SCNHDR_SIZE H_PUT_64
00103 #define GET_SCNHDR_SCNPTR H_GET_64
00104 #define PUT_SCNHDR_SCNPTR H_PUT_64
00105 #define GET_SCNHDR_RELPTR H_GET_64
00106 #define PUT_SCNHDR_RELPTR H_PUT_64
00107 #define GET_SCNHDR_LNNOPTR H_GET_64
00108 #define PUT_SCNHDR_LNNOPTR H_PUT_64
00109 
00110 #define ALPHAECOFF
00111 
00112 #define NO_COFF_RELOCS
00113 #define NO_COFF_SYMBOLS
00114 #define NO_COFF_LINENOS
00115 #define coff_swap_filehdr_in alpha_ecoff_swap_filehdr_in
00116 #define coff_swap_filehdr_out alpha_ecoff_swap_filehdr_out
00117 #define coff_swap_aouthdr_in alpha_ecoff_swap_aouthdr_in
00118 #define coff_swap_aouthdr_out alpha_ecoff_swap_aouthdr_out
00119 #define coff_swap_scnhdr_in alpha_ecoff_swap_scnhdr_in
00120 #define coff_swap_scnhdr_out alpha_ecoff_swap_scnhdr_out
00121 #include "coffswap.h"
00122 
00123 /* Get the ECOFF swapping routines.  */
00124 #define ECOFF_64
00125 #include "ecoffswap.h"
00126 
00127 /* How to process the various reloc types.  */
00128 
00129 static bfd_reloc_status_type reloc_nil
00130   PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
00131 
00132 static bfd_reloc_status_type
00133 reloc_nil (abfd, reloc, sym, data, sec, output_bfd, error_message)
00134      bfd *abfd ATTRIBUTE_UNUSED;
00135      arelent *reloc ATTRIBUTE_UNUSED;
00136      asymbol *sym ATTRIBUTE_UNUSED;
00137      PTR data ATTRIBUTE_UNUSED;
00138      asection *sec ATTRIBUTE_UNUSED;
00139      bfd *output_bfd ATTRIBUTE_UNUSED;
00140      char **error_message ATTRIBUTE_UNUSED;
00141 {
00142   return bfd_reloc_ok;
00143 }
00144 
00145 /* In case we're on a 32-bit machine, construct a 64-bit "-1" value
00146    from smaller values.  Start with zero, widen, *then* decrement.  */
00147 #define MINUS_ONE    (((bfd_vma)0) - 1)
00148 
00149 static reloc_howto_type alpha_howto_table[] =
00150 {
00151   /* Reloc type 0 is ignored by itself.  However, it appears after a
00152      GPDISP reloc to identify the location where the low order 16 bits
00153      of the gp register are loaded.  */
00154   HOWTO (ALPHA_R_IGNORE,    /* type */
00155         0,                  /* rightshift */
00156         0,                  /* size (0 = byte, 1 = short, 2 = long) */
00157         8,                  /* bitsize */
00158         TRUE,               /* pc_relative */
00159         0,                  /* bitpos */
00160         complain_overflow_dont, /* complain_on_overflow */
00161         reloc_nil,          /* special_function */
00162         "IGNORE",           /* name */
00163         TRUE,               /* partial_inplace */
00164         0,                  /* src_mask */
00165         0,                  /* dst_mask */
00166         TRUE),                     /* pcrel_offset */
00167 
00168   /* A 32 bit reference to a symbol.  */
00169   HOWTO (ALPHA_R_REFLONG,   /* type */
00170         0,                  /* rightshift */
00171         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00172         32,                 /* bitsize */
00173         FALSE,                     /* pc_relative */
00174         0,                  /* bitpos */
00175         complain_overflow_bitfield, /* complain_on_overflow */
00176         0,                  /* special_function */
00177         "REFLONG",          /* name */
00178         TRUE,               /* partial_inplace */
00179         0xffffffff,         /* src_mask */
00180         0xffffffff,         /* dst_mask */
00181         FALSE),             /* pcrel_offset */
00182 
00183   /* A 64 bit reference to a symbol.  */
00184   HOWTO (ALPHA_R_REFQUAD,   /* type */
00185         0,                  /* rightshift */
00186         4,                  /* size (0 = byte, 1 = short, 2 = long) */
00187         64,                 /* bitsize */
00188         FALSE,                     /* pc_relative */
00189         0,                  /* bitpos */
00190         complain_overflow_bitfield, /* complain_on_overflow */
00191         0,                  /* special_function */
00192         "REFQUAD",          /* name */
00193         TRUE,               /* partial_inplace */
00194         MINUS_ONE,          /* src_mask */
00195         MINUS_ONE,          /* dst_mask */
00196         FALSE),             /* pcrel_offset */
00197 
00198   /* A 32 bit GP relative offset.  This is just like REFLONG except
00199      that when the value is used the value of the gp register will be
00200      added in.  */
00201   HOWTO (ALPHA_R_GPREL32,   /* type */
00202         0,                  /* rightshift */
00203         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00204         32,                 /* bitsize */
00205         FALSE,                     /* pc_relative */
00206         0,                  /* bitpos */
00207         complain_overflow_bitfield, /* complain_on_overflow */
00208         0,                  /* special_function */
00209         "GPREL32",          /* name */
00210         TRUE,               /* partial_inplace */
00211         0xffffffff,         /* src_mask */
00212         0xffffffff,         /* dst_mask */
00213         FALSE),             /* pcrel_offset */
00214 
00215   /* Used for an instruction that refers to memory off the GP
00216      register.  The offset is 16 bits of the 32 bit instruction.  This
00217      reloc always seems to be against the .lita section.  */
00218   HOWTO (ALPHA_R_LITERAL,   /* type */
00219         0,                  /* rightshift */
00220         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00221         16,                 /* bitsize */
00222         FALSE,                     /* pc_relative */
00223         0,                  /* bitpos */
00224         complain_overflow_signed, /* complain_on_overflow */
00225         0,                  /* special_function */
00226         "LITERAL",          /* name */
00227         TRUE,               /* partial_inplace */
00228         0xffff,             /* src_mask */
00229         0xffff,             /* dst_mask */
00230         FALSE),             /* pcrel_offset */
00231 
00232   /* This reloc only appears immediately following a LITERAL reloc.
00233      It identifies a use of the literal.  It seems that the linker can
00234      use this to eliminate a portion of the .lita section.  The symbol
00235      index is special: 1 means the literal address is in the base
00236      register of a memory format instruction; 2 means the literal
00237      address is in the byte offset register of a byte-manipulation
00238      instruction; 3 means the literal address is in the target
00239      register of a jsr instruction.  This does not actually do any
00240      relocation.  */
00241   HOWTO (ALPHA_R_LITUSE,    /* type */
00242         0,                  /* rightshift */
00243         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00244         32,                 /* bitsize */
00245         FALSE,                     /* pc_relative */
00246         0,                  /* bitpos */
00247         complain_overflow_dont, /* complain_on_overflow */
00248         reloc_nil,          /* special_function */
00249         "LITUSE",           /* name */
00250         FALSE,                     /* partial_inplace */
00251         0,                  /* src_mask */
00252         0,                  /* dst_mask */
00253         FALSE),             /* pcrel_offset */
00254 
00255   /* Load the gp register.  This is always used for a ldah instruction
00256      which loads the upper 16 bits of the gp register.  The next reloc
00257      will be an IGNORE reloc which identifies the location of the lda
00258      instruction which loads the lower 16 bits.  The symbol index of
00259      the GPDISP instruction appears to actually be the number of bytes
00260      between the ldah and lda instructions.  This gives two different
00261      ways to determine where the lda instruction is; I don't know why
00262      both are used.  The value to use for the relocation is the
00263      difference between the GP value and the current location; the
00264      load will always be done against a register holding the current
00265      address.  */
00266   HOWTO (ALPHA_R_GPDISP,    /* type */
00267         16,                 /* rightshift */
00268         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00269         16,                 /* bitsize */
00270         TRUE,               /* pc_relative */
00271         0,                  /* bitpos */
00272         complain_overflow_dont, /* complain_on_overflow */
00273         reloc_nil,          /* special_function */
00274         "GPDISP",           /* name */
00275         TRUE,               /* partial_inplace */
00276         0xffff,             /* src_mask */
00277         0xffff,             /* dst_mask */
00278         TRUE),                     /* pcrel_offset */
00279 
00280   /* A 21 bit branch.  The native assembler generates these for
00281      branches within the text segment, and also fills in the PC
00282      relative offset in the instruction.  */
00283   HOWTO (ALPHA_R_BRADDR,    /* type */
00284         2,                  /* rightshift */
00285         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00286         21,                 /* bitsize */
00287         TRUE,               /* pc_relative */
00288         0,                  /* bitpos */
00289         complain_overflow_signed, /* complain_on_overflow */
00290         0,                  /* special_function */
00291         "BRADDR",           /* name */
00292         TRUE,               /* partial_inplace */
00293         0x1fffff,           /* src_mask */
00294         0x1fffff,           /* dst_mask */
00295         FALSE),             /* pcrel_offset */
00296 
00297   /* A hint for a jump to a register.  */
00298   HOWTO (ALPHA_R_HINT,             /* type */
00299         2,                  /* rightshift */
00300         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00301         14,                 /* bitsize */
00302         TRUE,               /* pc_relative */
00303         0,                  /* bitpos */
00304         complain_overflow_dont, /* complain_on_overflow */
00305         0,                  /* special_function */
00306         "HINT",             /* name */
00307         TRUE,               /* partial_inplace */
00308         0x3fff,             /* src_mask */
00309         0x3fff,             /* dst_mask */
00310         FALSE),             /* pcrel_offset */
00311 
00312   /* 16 bit PC relative offset.  */
00313   HOWTO (ALPHA_R_SREL16,    /* type */
00314         0,                  /* rightshift */
00315         1,                  /* size (0 = byte, 1 = short, 2 = long) */
00316         16,                 /* bitsize */
00317         TRUE,               /* pc_relative */
00318         0,                  /* bitpos */
00319         complain_overflow_signed, /* complain_on_overflow */
00320         0,                  /* special_function */
00321         "SREL16",           /* name */
00322         TRUE,               /* partial_inplace */
00323         0xffff,             /* src_mask */
00324         0xffff,             /* dst_mask */
00325         FALSE),             /* pcrel_offset */
00326 
00327   /* 32 bit PC relative offset.  */
00328   HOWTO (ALPHA_R_SREL32,    /* type */
00329         0,                  /* rightshift */
00330         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00331         32,                 /* bitsize */
00332         TRUE,               /* pc_relative */
00333         0,                  /* bitpos */
00334         complain_overflow_signed, /* complain_on_overflow */
00335         0,                  /* special_function */
00336         "SREL32",           /* name */
00337         TRUE,               /* partial_inplace */
00338         0xffffffff,         /* src_mask */
00339         0xffffffff,         /* dst_mask */
00340         FALSE),             /* pcrel_offset */
00341 
00342   /* A 64 bit PC relative offset.  */
00343   HOWTO (ALPHA_R_SREL64,    /* type */
00344         0,                  /* rightshift */
00345         4,                  /* size (0 = byte, 1 = short, 2 = long) */
00346         64,                 /* bitsize */
00347         TRUE,               /* pc_relative */
00348         0,                  /* bitpos */
00349         complain_overflow_signed, /* complain_on_overflow */
00350         0,                  /* special_function */
00351         "SREL64",           /* name */
00352         TRUE,               /* partial_inplace */
00353         MINUS_ONE,          /* src_mask */
00354         MINUS_ONE,          /* dst_mask */
00355         FALSE),             /* pcrel_offset */
00356 
00357   /* Push a value on the reloc evaluation stack.  */
00358   HOWTO (ALPHA_R_OP_PUSH,   /* type */
00359         0,                  /* rightshift */
00360         0,                  /* size (0 = byte, 1 = short, 2 = long) */
00361         0,                  /* bitsize */
00362         FALSE,                     /* pc_relative */
00363         0,                  /* bitpos */
00364         complain_overflow_dont, /* complain_on_overflow */
00365         0,                  /* special_function */
00366         "OP_PUSH",          /* name */
00367         FALSE,                     /* partial_inplace */
00368         0,                  /* src_mask */
00369         0,                  /* dst_mask */
00370         FALSE),             /* pcrel_offset */
00371 
00372   /* Store the value from the stack at the given address.  Store it in
00373      a bitfield of size r_size starting at bit position r_offset.  */
00374   HOWTO (ALPHA_R_OP_STORE,  /* type */
00375         0,                  /* rightshift */
00376         4,                  /* size (0 = byte, 1 = short, 2 = long) */
00377         64,                 /* bitsize */
00378         FALSE,                     /* pc_relative */
00379         0,                  /* bitpos */
00380         complain_overflow_dont, /* complain_on_overflow */
00381         0,                  /* special_function */
00382         "OP_STORE",         /* name */
00383         FALSE,                     /* partial_inplace */
00384         0,                  /* src_mask */
00385         MINUS_ONE,          /* dst_mask */
00386         FALSE),             /* pcrel_offset */
00387 
00388   /* Subtract the reloc address from the value on the top of the
00389      relocation stack.  */
00390   HOWTO (ALPHA_R_OP_PSUB,   /* type */
00391         0,                  /* rightshift */
00392         0,                  /* size (0 = byte, 1 = short, 2 = long) */
00393         0,                  /* bitsize */
00394         FALSE,                     /* pc_relative */
00395         0,                  /* bitpos */
00396         complain_overflow_dont, /* complain_on_overflow */
00397         0,                  /* special_function */
00398         "OP_PSUB",          /* name */
00399         FALSE,                     /* partial_inplace */
00400         0,                  /* src_mask */
00401         0,                  /* dst_mask */
00402         FALSE),             /* pcrel_offset */
00403 
00404   /* Shift the value on the top of the relocation stack right by the
00405      given value.  */
00406   HOWTO (ALPHA_R_OP_PRSHIFT,       /* type */
00407         0,                  /* rightshift */
00408         0,                  /* size (0 = byte, 1 = short, 2 = long) */
00409         0,                  /* bitsize */
00410         FALSE,                     /* pc_relative */
00411         0,                  /* bitpos */
00412         complain_overflow_dont, /* complain_on_overflow */
00413         0,                  /* special_function */
00414         "OP_PRSHIFT",              /* name */
00415         FALSE,                     /* partial_inplace */
00416         0,                  /* src_mask */
00417         0,                  /* dst_mask */
00418         FALSE),             /* pcrel_offset */
00419 
00420   /* Adjust the GP value for a new range in the object file.  */
00421   HOWTO (ALPHA_R_GPVALUE,   /* type */
00422         0,                  /* rightshift */
00423         0,                  /* size (0 = byte, 1 = short, 2 = long) */
00424         0,                  /* bitsize */
00425         FALSE,                     /* pc_relative */
00426         0,                  /* bitpos */
00427         complain_overflow_dont, /* complain_on_overflow */
00428         0,                  /* special_function */
00429         "GPVALUE",          /* name */
00430         FALSE,                     /* partial_inplace */
00431         0,                  /* src_mask */
00432         0,                  /* dst_mask */
00433         FALSE)                     /* pcrel_offset */
00434 };
00435 
00436 /* Recognize an Alpha ECOFF file.  */
00437 
00438 static const bfd_target *
00439 alpha_ecoff_object_p (abfd)
00440      bfd *abfd;
00441 {
00442   static const bfd_target *ret;
00443 
00444   ret = coff_object_p (abfd);
00445 
00446   if (ret != NULL)
00447     {
00448       asection *sec;
00449 
00450       /* Alpha ECOFF has a .pdata section.  The lnnoptr field of the
00451         .pdata section is the number of entries it contains.  Each
00452         entry takes up 8 bytes.  The number of entries is required
00453         since the section is aligned to a 16 byte boundary.  When we
00454         link .pdata sections together, we do not want to include the
00455         alignment bytes.  We handle this on input by faking the size
00456         of the .pdata section to remove the unwanted alignment bytes.
00457         On output we will set the lnnoptr field and force the
00458         alignment.  */
00459       sec = bfd_get_section_by_name (abfd, _PDATA);
00460       if (sec != (asection *) NULL)
00461        {
00462          bfd_size_type size;
00463 
00464          size = sec->line_filepos * 8;
00465          BFD_ASSERT (size == sec->size
00466                     || size + 8 == sec->size);
00467          if (! bfd_set_section_size (abfd, sec, size))
00468            return NULL;
00469        }
00470     }
00471 
00472   return ret;
00473 }
00474 
00475 /* See whether the magic number matches.  */
00476 
00477 static bfd_boolean
00478 alpha_ecoff_bad_format_hook (abfd, filehdr)
00479      bfd *abfd ATTRIBUTE_UNUSED;
00480      PTR filehdr;
00481 {
00482   struct internal_filehdr *internal_f = (struct internal_filehdr *) filehdr;
00483 
00484   if (! ALPHA_ECOFF_BADMAG (*internal_f))
00485     return TRUE;
00486 
00487   if (ALPHA_ECOFF_COMPRESSEDMAG (*internal_f))
00488     (*_bfd_error_handler)
00489       (_("%B: Cannot handle compressed Alpha binaries.\n"
00490         "   Use compiler flags, or objZ, to generate uncompressed binaries."),
00491        abfd);
00492 
00493   return FALSE;
00494 }
00495 
00496 /* This is a hook called by coff_real_object_p to create any backend
00497    specific information.  */
00498 
00499 static PTR
00500 alpha_ecoff_mkobject_hook (abfd, filehdr, aouthdr)
00501      bfd *abfd;
00502      PTR filehdr;
00503      PTR aouthdr;
00504 {
00505   PTR ecoff;
00506 
00507   ecoff = _bfd_ecoff_mkobject_hook (abfd, filehdr, aouthdr);
00508 
00509   if (ecoff != NULL)
00510     {
00511       struct internal_filehdr *internal_f = (struct internal_filehdr *) filehdr;
00512 
00513       /* Set additional BFD flags according to the object type from the
00514         machine specific file header flags.  */
00515       switch (internal_f->f_flags & F_ALPHA_OBJECT_TYPE_MASK)
00516        {
00517        case F_ALPHA_SHARABLE:
00518          abfd->flags |= DYNAMIC;
00519          break;
00520        case F_ALPHA_CALL_SHARED:
00521          /* Always executable if using shared libraries as the run time
00522             loader might resolve undefined references.  */
00523          abfd->flags |= (DYNAMIC | EXEC_P);
00524          break;
00525        }
00526     }
00527   return ecoff;
00528 }
00529 
00530 /* Reloc handling.  */
00531 
00532 /* Swap a reloc in.  */
00533 
00534 static void
00535 alpha_ecoff_swap_reloc_in (abfd, ext_ptr, intern)
00536      bfd *abfd;
00537      PTR ext_ptr;
00538      struct internal_reloc *intern;
00539 {
00540   const RELOC *ext = (RELOC *) ext_ptr;
00541 
00542   intern->r_vaddr = H_GET_64 (abfd, ext->r_vaddr);
00543   intern->r_symndx = H_GET_32 (abfd, ext->r_symndx);
00544 
00545   BFD_ASSERT (bfd_header_little_endian (abfd));
00546 
00547   intern->r_type = ((ext->r_bits[0] & RELOC_BITS0_TYPE_LITTLE)
00548                   >> RELOC_BITS0_TYPE_SH_LITTLE);
00549   intern->r_extern = (ext->r_bits[1] & RELOC_BITS1_EXTERN_LITTLE) != 0;
00550   intern->r_offset = ((ext->r_bits[1] & RELOC_BITS1_OFFSET_LITTLE)
00551                     >> RELOC_BITS1_OFFSET_SH_LITTLE);
00552   /* Ignored the reserved bits.  */
00553   intern->r_size = ((ext->r_bits[3] & RELOC_BITS3_SIZE_LITTLE)
00554                   >> RELOC_BITS3_SIZE_SH_LITTLE);
00555 
00556   if (intern->r_type == ALPHA_R_LITUSE
00557       || intern->r_type == ALPHA_R_GPDISP)
00558     {
00559       /* Handle the LITUSE and GPDISP relocs specially.  Its symndx
00560         value is not actually a symbol index, but is instead a
00561         special code.  We put the code in the r_size field, and
00562         clobber the symndx.  */
00563       if (intern->r_size != 0)
00564        abort ();
00565       intern->r_size = intern->r_symndx;
00566       intern->r_symndx = RELOC_SECTION_NONE;
00567     }
00568   else if (intern->r_type == ALPHA_R_IGNORE)
00569     {
00570       /* The IGNORE reloc generally follows a GPDISP reloc, and is
00571         against the .lita section.  The section is irrelevant.  */
00572       if (! intern->r_extern &&
00573          intern->r_symndx == RELOC_SECTION_ABS)
00574        abort ();
00575       if (! intern->r_extern && intern->r_symndx == RELOC_SECTION_LITA)
00576        intern->r_symndx = RELOC_SECTION_ABS;
00577     }
00578 }
00579 
00580 /* Swap a reloc out.  */
00581 
00582 static void
00583 alpha_ecoff_swap_reloc_out (abfd, intern, dst)
00584      bfd *abfd;
00585      const struct internal_reloc *intern;
00586      PTR dst;
00587 {
00588   RELOC *ext = (RELOC *) dst;
00589   long symndx;
00590   unsigned char size;
00591 
00592   /* Undo the hackery done in swap_reloc_in.  */
00593   if (intern->r_type == ALPHA_R_LITUSE
00594       || intern->r_type == ALPHA_R_GPDISP)
00595     {
00596       symndx = intern->r_size;
00597       size = 0;
00598     }
00599   else if (intern->r_type == ALPHA_R_IGNORE
00600           && ! intern->r_extern
00601           && intern->r_symndx == RELOC_SECTION_ABS)
00602     {
00603       symndx = RELOC_SECTION_LITA;
00604       size = intern->r_size;
00605     }
00606   else
00607     {
00608       symndx = intern->r_symndx;
00609       size = intern->r_size;
00610     }
00611 
00612   /* XXX FIXME:  The maximum symndx value used to be 14 but this
00613      fails with object files produced by DEC's C++ compiler.
00614      Where does the value 14 (or 15) come from anyway ?  */
00615   BFD_ASSERT (intern->r_extern
00616              || (intern->r_symndx >= 0 && intern->r_symndx <= 15));
00617 
00618   H_PUT_64 (abfd, intern->r_vaddr, ext->r_vaddr);
00619   H_PUT_32 (abfd, symndx, ext->r_symndx);
00620 
00621   BFD_ASSERT (bfd_header_little_endian (abfd));
00622 
00623   ext->r_bits[0] = ((intern->r_type << RELOC_BITS0_TYPE_SH_LITTLE)
00624                   & RELOC_BITS0_TYPE_LITTLE);
00625   ext->r_bits[1] = ((intern->r_extern ? RELOC_BITS1_EXTERN_LITTLE : 0)
00626                   | ((intern->r_offset << RELOC_BITS1_OFFSET_SH_LITTLE)
00627                      & RELOC_BITS1_OFFSET_LITTLE));
00628   ext->r_bits[2] = 0;
00629   ext->r_bits[3] = ((size << RELOC_BITS3_SIZE_SH_LITTLE)
00630                   & RELOC_BITS3_SIZE_LITTLE);
00631 }
00632 
00633 /* Finish canonicalizing a reloc.  Part of this is generic to all
00634    ECOFF targets, and that part is in ecoff.c.  The rest is done in
00635    this backend routine.  It must fill in the howto field.  */
00636 
00637 static void
00638 alpha_adjust_reloc_in (abfd, intern, rptr)
00639      bfd *abfd;
00640      const struct internal_reloc *intern;
00641      arelent *rptr;
00642 {
00643   if (intern->r_type > ALPHA_R_GPVALUE)
00644     {
00645       (*_bfd_error_handler)
00646        (_("%B: unknown/unsupported relocation type %d"),
00647         abfd, intern->r_type);
00648       bfd_set_error (bfd_error_bad_value);
00649       rptr->addend = 0;
00650       rptr->howto  = NULL;
00651       return;
00652     }
00653 
00654   switch (intern->r_type)
00655     {
00656     case ALPHA_R_BRADDR:
00657     case ALPHA_R_SREL16:
00658     case ALPHA_R_SREL32:
00659     case ALPHA_R_SREL64:
00660       /* This relocs appear to be fully resolved when they are against
00661          internal symbols.  Against external symbols, BRADDR at least
00662          appears to be resolved against the next instruction.  */
00663       if (! intern->r_extern)
00664        rptr->addend = 0;
00665       else
00666        rptr->addend = - (intern->r_vaddr + 4);
00667       break;
00668 
00669     case ALPHA_R_GPREL32:
00670     case ALPHA_R_LITERAL:
00671       /* Copy the gp value for this object file into the addend, to
00672         ensure that we are not confused by the linker.  */
00673       if (! intern->r_extern)
00674        rptr->addend += ecoff_data (abfd)->gp;
00675       break;
00676 
00677     case ALPHA_R_LITUSE:
00678     case ALPHA_R_GPDISP:
00679       /* The LITUSE and GPDISP relocs do not use a symbol, or an
00680         addend, but they do use a special code.  Put this code in the
00681         addend field.  */
00682       rptr->addend = intern->r_size;
00683       break;
00684 
00685     case ALPHA_R_OP_STORE:
00686       /* The STORE reloc needs the size and offset fields.  We store
00687         them in the addend.  */
00688       BFD_ASSERT (intern->r_offset <= 256);
00689       rptr->addend = (intern->r_offset << 8) + intern->r_size;
00690       break;
00691 
00692     case ALPHA_R_OP_PUSH:
00693     case ALPHA_R_OP_PSUB:
00694     case ALPHA_R_OP_PRSHIFT:
00695       /* The PUSH, PSUB and PRSHIFT relocs do not actually use an
00696         address.  I believe that the address supplied is really an
00697         addend.  */
00698       rptr->addend = intern->r_vaddr;
00699       break;
00700 
00701     case ALPHA_R_GPVALUE:
00702       /* Set the addend field to the new GP value.  */
00703       rptr->addend = intern->r_symndx + ecoff_data (abfd)->gp;
00704       break;
00705 
00706     case ALPHA_R_IGNORE:
00707       /* If the type is ALPHA_R_IGNORE, make sure this is a reference
00708         to the absolute section so that the reloc is ignored.  For
00709         some reason the address of this reloc type is not adjusted by
00710         the section vma.  We record the gp value for this object file
00711         here, for convenience when doing the GPDISP relocation.  */
00712       rptr->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
00713       rptr->address = intern->r_vaddr;
00714       rptr->addend = ecoff_data (abfd)->gp;
00715       break;
00716 
00717     default:
00718       break;
00719     }
00720 
00721   rptr->howto = &alpha_howto_table[intern->r_type];
00722 }
00723 
00724 /* When writing out a reloc we need to pull some values back out of
00725    the addend field into the reloc.  This is roughly the reverse of
00726    alpha_adjust_reloc_in, except that there are several changes we do
00727    not need to undo.  */
00728 
00729 static void
00730 alpha_adjust_reloc_out (abfd, rel, intern)
00731      bfd *abfd ATTRIBUTE_UNUSED;
00732      const arelent *rel;
00733      struct internal_reloc *intern;
00734 {
00735   switch (intern->r_type)
00736     {
00737     case ALPHA_R_LITUSE:
00738     case ALPHA_R_GPDISP:
00739       intern->r_size = rel->addend;
00740       break;
00741 
00742     case ALPHA_R_OP_STORE:
00743       intern->r_size = rel->addend & 0xff;
00744       intern->r_offset = (rel->addend >> 8) & 0xff;
00745       break;
00746 
00747     case ALPHA_R_OP_PUSH:
00748     case ALPHA_R_OP_PSUB:
00749     case ALPHA_R_OP_PRSHIFT:
00750       intern->r_vaddr = rel->addend;
00751       break;
00752 
00753     case ALPHA_R_IGNORE:
00754       intern->r_vaddr = rel->address;
00755       break;
00756 
00757     default:
00758       break;
00759     }
00760 }
00761 
00762 /* The size of the stack for the relocation evaluator.  */
00763 #define RELOC_STACKSIZE (10)
00764 
00765 /* Alpha ECOFF relocs have a built in expression evaluator as well as
00766    other interdependencies.  Rather than use a bunch of special
00767    functions and global variables, we use a single routine to do all
00768    the relocation for a section.  I haven't yet worked out how the
00769    assembler is going to handle this.  */
00770 
00771 static bfd_byte *
00772 alpha_ecoff_get_relocated_section_contents (abfd, link_info, link_order,
00773                                        data, relocatable, symbols)
00774      bfd *abfd;
00775      struct bfd_link_info *link_info;
00776      struct bfd_link_order *link_order;
00777      bfd_byte *data;
00778      bfd_boolean relocatable;
00779      asymbol **symbols;
00780 {
00781   bfd *input_bfd = link_order->u.indirect.section->owner;
00782   asection *input_section = link_order->u.indirect.section;
00783   long reloc_size = bfd_get_reloc_upper_bound (input_bfd, input_section);
00784   arelent **reloc_vector = NULL;
00785   long reloc_count;
00786   bfd *output_bfd = relocatable ? abfd : (bfd *) NULL;
00787   bfd_vma gp;
00788   bfd_size_type sz;
00789   bfd_boolean gp_undefined;
00790   bfd_vma stack[RELOC_STACKSIZE];
00791   int tos = 0;
00792 
00793   if (reloc_size < 0)
00794     goto error_return;
00795   reloc_vector = (arelent **) bfd_malloc ((bfd_size_type) reloc_size);
00796   if (reloc_vector == NULL && reloc_size != 0)
00797     goto error_return;
00798 
00799   sz = input_section->rawsize ? input_section->rawsize : input_section->size;
00800   if (! bfd_get_section_contents (input_bfd, input_section, data, 0, sz))
00801     goto error_return;
00802 
00803   reloc_count = bfd_canonicalize_reloc (input_bfd, input_section,
00804                                    reloc_vector, symbols);
00805   if (reloc_count < 0)
00806     goto error_return;
00807   if (reloc_count == 0)
00808     goto successful_return;
00809 
00810   /* Get the GP value for the output BFD.  */
00811   gp_undefined = FALSE;
00812   gp = _bfd_get_gp_value (abfd);
00813   if (gp == 0)
00814     {
00815       if (relocatable)
00816        {
00817          asection *sec;
00818          bfd_vma lo;
00819 
00820          /* Make up a value.  */
00821          lo = (bfd_vma) -1;
00822          for (sec = abfd->sections; sec != NULL; sec = sec->next)
00823            {
00824              if (sec->vma < lo
00825                 && (strcmp (sec->name, ".sbss") == 0
00826                     || strcmp (sec->name, ".sdata") == 0
00827                     || strcmp (sec->name, ".lit4") == 0
00828                     || strcmp (sec->name, ".lit8") == 0
00829                     || strcmp (sec->name, ".lita") == 0))
00830               lo = sec->vma;
00831            }
00832          gp = lo + 0x8000;
00833          _bfd_set_gp_value (abfd, gp);
00834        }
00835       else
00836        {
00837          struct bfd_link_hash_entry *h;
00838 
00839          h = bfd_link_hash_lookup (link_info->hash, "_gp", FALSE, FALSE,
00840                                 TRUE);
00841          if (h == (struct bfd_link_hash_entry *) NULL
00842              || h->type != bfd_link_hash_defined)
00843            gp_undefined = TRUE;
00844          else
00845            {
00846              gp = (h->u.def.value
00847                   + h->u.def.section->output_section->vma
00848                   + h->u.def.section->output_offset);
00849              _bfd_set_gp_value (abfd, gp);
00850            }
00851        }
00852     }
00853 
00854   for (; *reloc_vector != (arelent *) NULL; reloc_vector++)
00855     {
00856       arelent *rel;
00857       bfd_reloc_status_type r;
00858       char *err;
00859 
00860       rel = *reloc_vector;
00861       r = bfd_reloc_ok;
00862       switch (rel->howto->type)
00863        {
00864        case ALPHA_R_IGNORE:
00865          rel->address += input_section->output_offset;
00866          break;
00867 
00868        case ALPHA_R_REFLONG:
00869        case ALPHA_R_REFQUAD:
00870        case ALPHA_R_BRADDR:
00871        case ALPHA_R_HINT:
00872        case ALPHA_R_SREL16:
00873        case ALPHA_R_SREL32:
00874        case ALPHA_R_SREL64:
00875          if (relocatable
00876              && ((*rel->sym_ptr_ptr)->flags & BSF_SECTION_SYM) == 0)
00877            {
00878              rel->address += input_section->output_offset;
00879              break;
00880            }
00881          r = bfd_perform_relocation (input_bfd, rel, data, input_section,
00882                                   output_bfd, &err);
00883          break;
00884 
00885        case ALPHA_R_GPREL32:
00886          /* This relocation is used in a switch table.  It is a 32
00887             bit offset from the current GP value.  We must adjust it
00888             by the different between the original GP value and the
00889             current GP value.  The original GP value is stored in the
00890             addend.  We adjust the addend and let
00891             bfd_perform_relocation finish the job.  */
00892          rel->addend -= gp;
00893          r = bfd_perform_relocation (input_bfd, rel, data, input_section,
00894                                   output_bfd, &err);
00895          if (r == bfd_reloc_ok && gp_undefined)
00896            {
00897              r = bfd_reloc_dangerous;
00898              err = (char *) _("GP relative relocation used when GP not defined");
00899            }
00900          break;
00901 
00902        case ALPHA_R_LITERAL:
00903          /* This is a reference to a literal value, generally
00904             (always?) in the .lita section.  This is a 16 bit GP
00905             relative relocation.  Sometimes the subsequent reloc is a
00906             LITUSE reloc, which indicates how this reloc is used.
00907             This sometimes permits rewriting the two instructions
00908             referred to by the LITERAL and the LITUSE into different
00909             instructions which do not refer to .lita.  This can save
00910             a memory reference, and permits removing a value from
00911             .lita thus saving GP relative space.
00912 
00913             We do not these optimizations.  To do them we would need
00914             to arrange to link the .lita section first, so that by
00915             the time we got here we would know the final values to
00916             use.  This would not be particularly difficult, but it is
00917             not currently implemented.  */
00918 
00919          {
00920            unsigned long insn;
00921 
00922            /* I believe that the LITERAL reloc will only apply to a
00923               ldq or ldl instruction, so check my assumption.  */
00924            insn = bfd_get_32 (input_bfd, data + rel->address);
00925            BFD_ASSERT (((insn >> 26) & 0x3f) == 0x29
00926                      || ((insn >> 26) & 0x3f) == 0x28);
00927 
00928            rel->addend -= gp;
00929            r = bfd_perform_relocation (input_bfd, rel, data, input_section,
00930                                    output_bfd, &err);
00931            if (r == bfd_reloc_ok && gp_undefined)
00932              {
00933               r = bfd_reloc_dangerous;
00934               err =
00935                 (char *) _("GP relative relocation used when GP not defined");
00936              }
00937          }
00938          break;
00939 
00940        case ALPHA_R_LITUSE:
00941          /* See ALPHA_R_LITERAL above for the uses of this reloc.  It
00942             does not cause anything to happen, itself.  */
00943          rel->address += input_section->output_offset;
00944          break;
00945 
00946        case ALPHA_R_GPDISP:
00947          /* This marks the ldah of an ldah/lda pair which loads the
00948             gp register with the difference of the gp value and the
00949             current location.  The second of the pair is r_size bytes
00950             ahead; it used to be marked with an ALPHA_R_IGNORE reloc,
00951             but that no longer happens in OSF/1 3.2.  */
00952          {
00953            unsigned long insn1, insn2;
00954            bfd_vma addend;
00955 
00956            /* Get the two instructions.  */
00957            insn1 = bfd_get_32 (input_bfd, data + rel->address);
00958            insn2 = bfd_get_32 (input_bfd, data + rel->address + rel->addend);
00959 
00960            BFD_ASSERT (((insn1 >> 26) & 0x3f) == 0x09); /* ldah */
00961            BFD_ASSERT (((insn2 >> 26) & 0x3f) == 0x08); /* lda */
00962 
00963            /* Get the existing addend.  We must account for the sign
00964               extension done by lda and ldah.  */
00965            addend = ((insn1 & 0xffff) << 16) + (insn2 & 0xffff);
00966            if (insn1 & 0x8000)
00967              {
00968               addend -= 0x80000000;
00969               addend -= 0x80000000;
00970              }
00971            if (insn2 & 0x8000)
00972              addend -= 0x10000;
00973 
00974            /* The existing addend includes the different between the
00975               gp of the input BFD and the address in the input BFD.
00976               Subtract this out.  */
00977            addend -= (ecoff_data (input_bfd)->gp
00978                      - (input_section->vma + rel->address));
00979 
00980            /* Now add in the final gp value, and subtract out the
00981               final address.  */
00982            addend += (gp
00983                      - (input_section->output_section->vma
00984                        + input_section->output_offset
00985                        + rel->address));
00986 
00987            /* Change the instructions, accounting for the sign
00988               extension, and write them out.  */
00989            if (addend & 0x8000)
00990              addend += 0x10000;
00991            insn1 = (insn1 & 0xffff0000) | ((addend >> 16) & 0xffff);
00992            insn2 = (insn2 & 0xffff0000) | (addend & 0xffff);
00993 
00994            bfd_put_32 (input_bfd, (bfd_vma) insn1, data + rel->address);
00995            bfd_put_32 (input_bfd, (bfd_vma) insn2,
00996                      data + rel->address + rel->addend);
00997 
00998            rel->address += input_section->output_offset;
00999          }
01000          break;
01001 
01002        case ALPHA_R_OP_PUSH:
01003          /* Push a value on the reloc evaluation stack.  */
01004          {
01005            asymbol *symbol;
01006            bfd_vma relocation;
01007 
01008            if (relocatable)
01009              {
01010               rel->address += input_section->output_offset;
01011               break;
01012              }
01013 
01014            /* Figure out the relocation of this symbol.  */
01015            symbol = *rel->sym_ptr_ptr;
01016 
01017            if (bfd_is_und_section (symbol->section))
01018              r = bfd_reloc_undefined;
01019 
01020            if (bfd_is_com_section (symbol->section))
01021              relocation = 0;
01022            else
01023              relocation = symbol->value;
01024            relocation += symbol->section->output_section->vma;
01025            relocation += symbol->section->output_offset;
01026            relocation += rel->addend;
01027 
01028            if (tos >= RELOC_STACKSIZE)
01029              abort ();
01030 
01031            stack[tos++] = relocation;
01032          }
01033          break;
01034 
01035        case ALPHA_R_OP_STORE:
01036          /* Store a value from the reloc stack into a bitfield.  */
01037          {
01038            bfd_vma val;
01039            int offset, size;
01040 
01041            if (relocatable)
01042              {
01043               rel->address += input_section->output_offset;
01044               break;
01045              }
01046 
01047            if (tos == 0)
01048              abort ();
01049 
01050            /* The offset and size for this reloc are encoded into the
01051               addend field by alpha_adjust_reloc_in.  */
01052            offset = (rel->addend >> 8) & 0xff;
01053            size = rel->addend & 0xff;
01054 
01055            val = bfd_get_64 (abfd, data + rel->address);
01056            val &=~ (((1 << size) - 1) << offset);
01057            val |= (stack[--tos] & ((1 << size) - 1)) << offset;
01058            bfd_put_64 (abfd, val, data + rel->address);
01059          }
01060          break;
01061 
01062        case ALPHA_R_OP_PSUB:
01063          /* Subtract a value from the top of the stack.  */
01064          {
01065            asymbol *symbol;
01066            bfd_vma relocation;
01067 
01068            if (relocatable)
01069              {
01070               rel->address += input_section->output_offset;
01071               break;
01072              }
01073 
01074            /* Figure out the relocation of this symbol.  */
01075            symbol = *rel->sym_ptr_ptr;
01076 
01077            if (bfd_is_und_section (symbol->section))
01078              r = bfd_reloc_undefined;
01079 
01080            if (bfd_is_com_section (symbol->section))
01081              relocation = 0;
01082            else
01083              relocation = symbol->value;
01084            relocation += symbol->section->output_section->vma;
01085            relocation += symbol->section->output_offset;
01086            relocation += rel->addend;
01087 
01088            if (tos == 0)
01089              abort ();
01090 
01091            stack[tos - 1] -= relocation;
01092          }
01093          break;
01094 
01095        case ALPHA_R_OP_PRSHIFT:
01096          /* Shift the value on the top of the stack.  */
01097          {
01098            asymbol *symbol;
01099            bfd_vma relocation;
01100 
01101            if (relocatable)
01102              {
01103               rel->address += input_section->output_offset;
01104               break;
01105              }
01106 
01107            /* Figure out the relocation of this symbol.  */
01108            symbol = *rel->sym_ptr_ptr;
01109 
01110            if (bfd_is_und_section (symbol->section))
01111              r = bfd_reloc_undefined;
01112 
01113            if (bfd_is_com_section (symbol->section))
01114              relocation = 0;
01115            else
01116              relocation = symbol->value;
01117            relocation += symbol->section->output_section->vma;
01118            relocation += symbol->section->output_offset;
01119            relocation += rel->addend;
01120 
01121            if (tos == 0)
01122              abort ();
01123 
01124            stack[tos - 1] >>= relocation;
01125          }
01126          break;
01127 
01128        case ALPHA_R_GPVALUE:
01129          /* I really don't know if this does the right thing.  */
01130          gp = rel->addend;
01131          gp_undefined = FALSE;
01132          break;
01133 
01134        default:
01135          abort ();
01136        }
01137 
01138       if (relocatable)
01139        {
01140          asection *os = input_section->output_section;
01141 
01142          /* A partial link, so keep the relocs.  */
01143          os->orelocation[os->reloc_count] = rel;
01144          os->reloc_count++;
01145        }
01146 
01147       if (r != bfd_reloc_ok)
01148        {
01149          switch (r)
01150            {
01151            case bfd_reloc_undefined:
01152              if (! ((*link_info->callbacks->undefined_symbol)
01153                    (link_info, bfd_asymbol_name (*rel->sym_ptr_ptr),
01154                     input_bfd, input_section, rel->address, TRUE)))
01155               goto error_return;
01156              break;
01157            case bfd_reloc_dangerous:
01158              if (! ((*link_info->callbacks->reloc_dangerous)
01159                    (link_info, err, input_bfd, input_section,
01160                     rel->address)))
01161               goto error_return;
01162              break;
01163            case bfd_reloc_overflow:
01164              if (! ((*link_info->callbacks->reloc_overflow)
01165                    (link_info, NULL,
01166                     bfd_asymbol_name (*rel->sym_ptr_ptr),
01167                     rel->howto->name, rel->addend, input_bfd,
01168                     input_section, rel->address)))
01169               goto error_return;
01170              break;
01171            case bfd_reloc_outofrange:
01172            default:
01173              abort ();
01174              break;
01175            }
01176        }
01177     }
01178 
01179   if (tos != 0)
01180     abort ();
01181 
01182  successful_return:
01183   if (reloc_vector != NULL)
01184     free (reloc_vector);
01185   return data;
01186 
01187  error_return:
01188   if (reloc_vector != NULL)
01189     free (reloc_vector);
01190   return NULL;
01191 }
01192 
01193 /* Get the howto structure for a generic reloc type.  */
01194 
01195 static reloc_howto_type *
01196 alpha_bfd_reloc_type_lookup (abfd, code)
01197      bfd *abfd ATTRIBUTE_UNUSED;
01198      bfd_reloc_code_real_type code;
01199 {
01200   int alpha_type;
01201 
01202   switch (code)
01203     {
01204     case BFD_RELOC_32:
01205       alpha_type = ALPHA_R_REFLONG;
01206       break;
01207     case BFD_RELOC_64:
01208     case BFD_RELOC_CTOR:
01209       alpha_type = ALPHA_R_REFQUAD;
01210       break;
01211     case BFD_RELOC_GPREL32:
01212       alpha_type = ALPHA_R_GPREL32;
01213       break;
01214     case BFD_RELOC_ALPHA_LITERAL:
01215       alpha_type = ALPHA_R_LITERAL;
01216       break;
01217     case BFD_RELOC_ALPHA_LITUSE:
01218       alpha_type = ALPHA_R_LITUSE;
01219       break;
01220     case BFD_RELOC_ALPHA_GPDISP_HI16:
01221       alpha_type = ALPHA_R_GPDISP;
01222       break;
01223     case BFD_RELOC_ALPHA_GPDISP_LO16:
01224       alpha_type = ALPHA_R_IGNORE;
01225       break;
01226     case BFD_RELOC_23_PCREL_S2:
01227       alpha_type = ALPHA_R_BRADDR;
01228       break;
01229     case BFD_RELOC_ALPHA_HINT:
01230       alpha_type = ALPHA_R_HINT;
01231       break;
01232     case BFD_RELOC_16_PCREL:
01233       alpha_type = ALPHA_R_SREL16;
01234       break;
01235     case BFD_RELOC_32_PCREL:
01236       alpha_type = ALPHA_R_SREL32;
01237       break;
01238     case BFD_RELOC_64_PCREL:
01239       alpha_type = ALPHA_R_SREL64;
01240       break;
01241     default:
01242       return (reloc_howto_type *) NULL;
01243     }
01244 
01245   return &alpha_howto_table[alpha_type];
01246 }
01247 
01248 static reloc_howto_type *
01249 alpha_bfd_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
01250                           const char *r_name)
01251 {
01252   unsigned int i;
01253 
01254   for (i = 0;
01255        i < sizeof (alpha_howto_table) / sizeof (alpha_howto_table[0]);
01256        i++)
01257     if (alpha_howto_table[i].name != NULL
01258        && strcasecmp (alpha_howto_table[i].name, r_name) == 0)
01259       return &alpha_howto_table[i];
01260 
01261   return NULL;
01262 }
01263 
01264 /* A helper routine for alpha_relocate_section which converts an
01265    external reloc when generating relocatable output.  Returns the
01266    relocation amount.  */
01267 
01268 static bfd_vma
01269 alpha_convert_external_reloc (output_bfd, info, input_bfd, ext_rel, h)
01270      bfd *output_bfd ATTRIBUTE_UNUSED;
01271      struct bfd_link_info *info;
01272      bfd *input_bfd;
01273      struct external_reloc *ext_rel;
01274      struct ecoff_link_hash_entry *h;
01275 {
01276   unsigned long r_symndx;
01277   bfd_vma relocation;
01278 
01279   BFD_ASSERT (info->relocatable);
01280 
01281   if (h->root.type == bfd_link_hash_defined
01282       || h->root.type == bfd_link_hash_defweak)
01283     {
01284       asection *hsec;
01285       const char *name;
01286 
01287       /* This symbol is defined in the output.  Convert the reloc from
01288         being against the symbol to being against the section.  */
01289 
01290       /* Clear the r_extern bit.  */
01291       ext_rel->r_bits[1] &=~ RELOC_BITS1_EXTERN_LITTLE;
01292 
01293       /* Compute a new r_symndx value.  */
01294       hsec = h->root.u.def.section;
01295       name = bfd_get_section_name (output_bfd, hsec->output_section);
01296 
01297       r_symndx = (unsigned long) -1;
01298       switch (name[1])
01299        {
01300        case 'A':
01301          if (strcmp (name, "*ABS*") == 0)
01302            r_symndx = RELOC_SECTION_ABS;
01303          break;
01304        case 'b':
01305          if (strcmp (name, ".bss") == 0)
01306            r_symndx = RELOC_SECTION_BSS;
01307          break;
01308        case 'd':
01309          if (strcmp (name, ".data") == 0)
01310            r_symndx = RELOC_SECTION_DATA;
01311          break;
01312        case 'f':
01313          if (strcmp (name, ".fini") == 0)
01314            r_symndx = RELOC_SECTION_FINI;
01315          break;
01316        case 'i':
01317          if (strcmp (name, ".init") == 0)
01318            r_symndx = RELOC_SECTION_INIT;
01319          break;
01320        case 'l':
01321          if (strcmp (name, ".lita") == 0)
01322            r_symndx = RELOC_SECTION_LITA;
01323          else if (strcmp (name, ".lit8") == 0)
01324            r_symndx = RELOC_SECTION_LIT8;
01325          else if (strcmp (name, ".lit4") == 0)
01326            r_symndx = RELOC_SECTION_LIT4;
01327          break;
01328        case 'p':
01329          if (strcmp (name, ".pdata") == 0)
01330            r_symndx = RELOC_SECTION_PDATA;
01331          break;
01332        case 'r':
01333          if (strcmp (name, ".rdata") == 0)
01334            r_symndx = RELOC_SECTION_RDATA;
01335          else if (strcmp (name, ".rconst") == 0)
01336            r_symndx = RELOC_SECTION_RCONST;
01337          break;
01338        case 's':
01339          if (strcmp (name, ".sdata") == 0)
01340            r_symndx = RELOC_SECTION_SDATA;
01341          else if (strcmp (name, ".sbss") == 0)
01342            r_symndx = RELOC_SECTION_SBSS;
01343          break;
01344        case 't':
01345          if (strcmp (name, ".text") == 0)
01346            r_symndx = RELOC_SECTION_TEXT;
01347          break;
01348        case 'x':
01349          if (strcmp (name, ".xdata") == 0)
01350            r_symndx = RELOC_SECTION_XDATA;
01351          break;
01352        }
01353 
01354       if (r_symndx == (unsigned long) -1)
01355        abort ();
01356 
01357       /* Add the section VMA and the symbol value.  */
01358       relocation = (h->root.u.def.value
01359                   + hsec->output_section->vma
01360                   + hsec->output_offset);
01361     }
01362   else
01363     {
01364       /* Change the symndx value to the right one for
01365         the output BFD.  */
01366       r_symndx = h->indx;
01367       if (r_symndx == (unsigned long) -1)
01368        {
01369          /* Caller must give an error.  */
01370          r_symndx = 0;
01371        }
01372       relocation = 0;
01373     }
01374 
01375   /* Write out the new r_symndx value.  */
01376   H_PUT_32 (input_bfd, r_symndx, ext_rel->r_symndx);
01377 
01378   return relocation;
01379 }
01380 
01381 /* Relocate a section while linking an Alpha ECOFF file.  This is
01382    quite similar to get_relocated_section_contents.  Perhaps they
01383    could be combined somehow.  */
01384 
01385 static bfd_boolean
01386 alpha_relocate_section (output_bfd, info, input_bfd, input_section,
01387                      contents, external_relocs)
01388      bfd *output_bfd;
01389      struct bfd_link_info *info;
01390      bfd *input_bfd;
01391      asection *input_section;
01392      bfd_byte *contents;
01393      PTR external_relocs;
01394 {
01395   asection **symndx_to_section, *lita_sec;
01396   struct ecoff_link_hash_entry **sym_hashes;
01397   bfd_vma gp;
01398   bfd_boolean gp_undefined;
01399   bfd_vma stack[RELOC_STACKSIZE];
01400   int tos = 0;
01401   struct external_reloc *ext_rel;
01402   struct external_reloc *ext_rel_end;
01403   bfd_size_type amt;
01404 
01405   /* We keep a table mapping the symndx found in an internal reloc to
01406      the appropriate section.  This is faster than looking up the
01407      section by name each time.  */
01408   symndx_to_section = ecoff_data (input_bfd)->symndx_to_section;
01409   if (symndx_to_section == (asection **) NULL)
01410     {
01411       amt = NUM_RELOC_SECTIONS * sizeof (asection *);
01412       symndx_to_section = (asection **) bfd_alloc (input_bfd, amt);
01413       if (!symndx_to_section)
01414        return FALSE;
01415 
01416       symndx_to_section[RELOC_SECTION_NONE] = NULL;
01417       symndx_to_section[RELOC_SECTION_TEXT] =
01418        bfd_get_section_by_name (input_bfd, ".text");
01419       symndx_to_section[RELOC_SECTION_RDATA] =
01420        bfd_get_section_by_name (input_bfd, ".rdata");
01421       symndx_to_section[RELOC_SECTION_DATA] =
01422        bfd_get_section_by_name (input_bfd, ".data");
01423       symndx_to_section[RELOC_SECTION_SDATA] =
01424        bfd_get_section_by_name (input_bfd, ".sdata");
01425       symndx_to_section[RELOC_SECTION_SBSS] =
01426        bfd_get_section_by_name (input_bfd, ".sbss");
01427       symndx_to_section[RELOC_SECTION_BSS] =
01428        bfd_get_section_by_name (input_bfd, ".bss");
01429       symndx_to_section[RELOC_SECTION_INIT] =
01430        bfd_get_section_by_name (input_bfd, ".init");
01431       symndx_to_section[RELOC_SECTION_LIT8] =
01432        bfd_get_section_by_name (input_bfd, ".lit8");
01433       symndx_to_section[RELOC_SECTION_LIT4] =
01434        bfd_get_section_by_name (input_bfd, ".lit4");
01435       symndx_to_section[RELOC_SECTION_XDATA] =
01436        bfd_get_section_by_name (input_bfd, ".xdata");
01437       symndx_to_section[RELOC_SECTION_PDATA] =
01438        bfd_get_section_by_name (input_bfd, ".pdata");
01439       symndx_to_section[RELOC_SECTION_FINI] =
01440        bfd_get_section_by_name (input_bfd, ".fini");
01441       symndx_to_section[RELOC_SECTION_LITA] =
01442        bfd_get_section_by_name (input_bfd, ".lita");
01443       symndx_to_section[RELOC_SECTION_ABS] = bfd_abs_section_ptr;
01444       symndx_to_section[RELOC_SECTION_RCONST] =
01445        bfd_get_section_by_name (input_bfd, ".rconst");
01446 
01447       ecoff_data (input_bfd)->symndx_to_section = symndx_to_section;
01448     }
01449 
01450   sym_hashes = ecoff_data (input_bfd)->sym_hashes;
01451 
01452   /* On the Alpha, the .lita section must be addressable by the global
01453      pointer.  To support large programs, we need to allow multiple
01454      global pointers.  This works as long as each input .lita section
01455      is <64KB big.  This implies that when producing relocatable
01456      output, the .lita section is limited to 64KB. .  */
01457 
01458   lita_sec = symndx_to_section[RELOC_SECTION_LITA];
01459   gp = _bfd_get_gp_value (output_bfd);
01460   if (! info->relocatable && lita_sec != NULL)
01461     {
01462       struct ecoff_section_tdata *lita_sec_data;
01463 
01464       /* Make sure we have a section data structure to which we can
01465         hang on to the gp value we pick for the section.  */
01466       lita_sec_data = ecoff_section_data (input_bfd, lita_sec);
01467       if (lita_sec_data == NULL)
01468        {
01469          amt = sizeof (struct ecoff_section_tdata);
01470          lita_sec_data = ((struct ecoff_section_tdata *)
01471                         bfd_zalloc (input_bfd, amt));
01472          lita_sec->used_by_bfd = lita_sec_data;
01473        }
01474 
01475       if (lita_sec_data->gp != 0)
01476        {
01477          /* If we already assigned a gp to this section, we better
01478             stick with that value.  */
01479          gp = lita_sec_data->gp;
01480        }
01481       else
01482        {
01483          bfd_vma lita_vma;
01484          bfd_size_type lita_size;
01485 
01486          lita_vma = lita_sec->output_offset + lita_sec->output_section->vma;
01487          lita_size = lita_sec->size;
01488 
01489          if (gp == 0
01490              || lita_vma <  gp - 0x8000
01491              || lita_vma + lita_size >= gp + 0x8000)
01492            {
01493              /* Either gp hasn't been set at all or the current gp
01494                cannot address this .lita section.  In both cases we
01495                reset the gp to point into the "middle" of the
01496                current input .lita section.  */
01497              if (gp && !ecoff_data (output_bfd)->issued_multiple_gp_warning)
01498               {
01499                 (*info->callbacks->warning) (info,
01500                                           _("using multiple gp values"),
01501                                           (char *) NULL, output_bfd,
01502                                           (asection *) NULL, (bfd_vma) 0);
01503                 ecoff_data (output_bfd)->issued_multiple_gp_warning = TRUE;
01504               }
01505              if (lita_vma < gp - 0x8000)
01506               gp = lita_vma + lita_size - 0x8000;
01507              else
01508               gp = lita_vma + 0x8000;
01509 
01510            }
01511 
01512          lita_sec_data->gp = gp;
01513        }
01514 
01515       _bfd_set_gp_value (output_bfd, gp);
01516     }
01517 
01518   gp_undefined = (gp == 0);
01519 
01520   BFD_ASSERT (bfd_header_little_endian (output_bfd));
01521   BFD_ASSERT (bfd_header_little_endian (input_bfd));
01522 
01523   ext_rel = (struct external_reloc *) external_relocs;
01524   ext_rel_end = ext_rel + input_section->reloc_count;
01525   for (; ext_rel < ext_rel_end; ext_rel++)
01526     {
01527       bfd_vma r_vaddr;
01528       unsigned long r_symndx;
01529       int r_type;
01530       int r_extern;
01531       int r_offset;
01532       int r_size;
01533       bfd_boolean relocatep;
01534       bfd_boolean adjust_addrp;
01535       bfd_boolean gp_usedp;
01536       bfd_vma addend;
01537 
01538       r_vaddr = H_GET_64 (input_bfd, ext_rel->r_vaddr);
01539       r_symndx = H_GET_32 (input_bfd, ext_rel->r_symndx);
01540 
01541       r_type = ((ext_rel->r_bits[0] & RELOC_BITS0_TYPE_LITTLE)
01542               >> RELOC_BITS0_TYPE_SH_LITTLE);
01543       r_extern = (ext_rel->r_bits[1] & RELOC_BITS1_EXTERN_LITTLE) != 0;
01544       r_offset = ((ext_rel->r_bits[1] & RELOC_BITS1_OFFSET_LITTLE)
01545                 >> RELOC_BITS1_OFFSET_SH_LITTLE);
01546       /* Ignored the reserved bits.  */
01547       r_size = ((ext_rel->r_bits[3] & RELOC_BITS3_SIZE_LITTLE)
01548               >> RELOC_BITS3_SIZE_SH_LITTLE);
01549 
01550       relocatep = FALSE;
01551       adjust_addrp = TRUE;
01552       gp_usedp = FALSE;
01553       addend = 0;
01554 
01555       switch (r_type)
01556        {
01557        case ALPHA_R_GPRELHIGH:
01558          (*_bfd_error_handler)
01559            (_("%B: unsupported relocation: ALPHA_R_GPRELHIGH"),
01560             input_bfd);
01561          bfd_set_error (bfd_error_bad_value);
01562          continue;
01563          
01564        case ALPHA_R_GPRELLOW:
01565          (*_bfd_error_handler)
01566            (_("%B: unsupported relocation: ALPHA_R_GPRELLOW"),
01567             input_bfd);
01568          bfd_set_error (bfd_error_bad_value);
01569          continue;
01570          
01571        default:
01572          (*_bfd_error_handler)
01573            (_("%B: unknown relocation type %d"),
01574             input_bfd, (int) r_type);
01575          bfd_set_error (bfd_error_bad_value);
01576          continue;
01577 
01578        case ALPHA_R_IGNORE:
01579          /* This reloc appears after a GPDISP reloc.  On earlier
01580             versions of OSF/1, It marked the position of the second
01581             instruction to be altered by the GPDISP reloc, but it is
01582             not otherwise used for anything.  For some reason, the
01583             address of the relocation does not appear to include the
01584             section VMA, unlike the other relocation types.  */
01585          if (info->relocatable)
01586            H_PUT_64 (input_bfd, input_section->output_offset + r_vaddr,
01587                     ext_rel->r_vaddr);
01588          adjust_addrp = FALSE;
01589          break;
01590 
01591        case ALPHA_R_REFLONG:
01592        case ALPHA_R_REFQUAD:
01593        case ALPHA_R_HINT:
01594          relocatep = TRUE;
01595          break;
01596 
01597        case ALPHA_R_BRADDR:
01598        case ALPHA_R_SREL16:
01599        case ALPHA_R_SREL32:
01600        case ALPHA_R_SREL64:
01601          if (r_extern)
01602            addend += - (r_vaddr + 4);
01603          relocatep = TRUE;
01604          break;
01605 
01606        case ALPHA_R_GPREL32:
01607          /* This relocation is used in a switch table.  It is a 32
01608             bit offset from the current GP value.  We must adjust it
01609             by the different between the original GP value and the
01610             current GP value.  */
01611          relocatep = TRUE;
01612          addend = ecoff_data (input_bfd)->gp - gp;
01613          gp_usedp = TRUE;
01614          break;
01615 
01616        case ALPHA_R_LITERAL:
01617          /* This is a reference to a literal value, generally
01618             (always?) in the .lita section.  This is a 16 bit GP
01619             relative relocation.  Sometimes the subsequent reloc is a
01620             LITUSE reloc, which indicates how this reloc is used.
01621             This sometimes permits rewriting the two instructions
01622             referred to by the LITERAL and the LITUSE into different
01623             instructions which do not refer to .lita.  This can save
01624             a memory reference, and permits removing a value from
01625             .lita thus saving GP relative space.
01626 
01627             We do not these optimizations.  To do them we would need
01628             to arrange to link the .lita section first, so that by
01629             the time we got here we would know the final values to
01630             use.  This would not be particularly difficult, but it is
01631             not currently implemented.  */
01632 
01633          /* I believe that the LITERAL reloc will only apply to a ldq
01634             or ldl instruction, so check my assumption.  */
01635          {
01636            unsigned long insn;
01637 
01638            insn = bfd_get_32 (input_bfd,
01639                             contents + r_vaddr - input_section->vma);
01640            BFD_ASSERT (((insn >> 26) & 0x3f) == 0x29
01641                      || ((insn >> 26) & 0x3f) == 0x28);
01642          }
01643 
01644          relocatep = TRUE;
01645          addend = ecoff_data (input_bfd)->gp - gp;
01646          gp_usedp = TRUE;
01647          break;
01648 
01649        case ALPHA_R_LITUSE:
01650          /* See ALPHA_R_LITERAL above for the uses of this reloc.  It
01651             does not cause anything to happen, itself.  */
01652          break;
01653 
01654        case ALPHA_R_GPDISP:
01655          /* This marks the ldah of an ldah/lda pair which loads the
01656             gp register with the difference of the gp value and the
01657             current location.  The second of the pair is r_symndx
01658             bytes ahead.  It used to be marked with an ALPHA_R_IGNORE
01659             reloc, but OSF/1 3.2 no longer does that.  */
01660          {
01661            unsigned long insn1, insn2;
01662 
01663            /* Get the two instructions.  */
01664            insn1 = bfd_get_32 (input_bfd,
01665                             contents + r_vaddr - input_section->vma);
01666            insn2 = bfd_get_32 (input_bfd,
01667                             (contents
01668                              + r_vaddr
01669                              - input_section->vma
01670                              + r_symndx));
01671 
01672            BFD_ASSERT (((insn1 >> 26) & 0x3f) == 0x09); /* ldah */
01673            BFD_ASSERT (((insn2 >> 26) & 0x3f) == 0x08); /* lda */
01674 
01675            /* Get the existing addend.  We must account for the sign
01676               extension done by lda and ldah.  */
01677            addend = ((insn1 & 0xffff) << 16) + (insn2 & 0xffff);
01678            if (insn1 & 0x8000)
01679              {
01680               /* This is addend -= 0x100000000 without causing an
01681                  integer overflow on a 32 bit host.  */
01682               addend -= 0x80000000;
01683               addend -= 0x80000000;
01684              }
01685            if (insn2 & 0x8000)
01686              addend -= 0x10000;
01687 
01688            /* The existing addend includes the difference between the
01689               gp of the input BFD and the address in the input BFD.
01690               We want to change this to the difference between the
01691               final GP and the final address.  */
01692            addend += (gp
01693                      - ecoff_data (input_bfd)->gp
01694                      + input_section->vma
01695                      - (input_section->output_section->vma
01696                        + input_section->output_offset));
01697 
01698            /* Change the instructions, accounting for the sign
01699               extension, and write them out.  */
01700            if (addend & 0x8000)
01701              addend += 0x10000;
01702            insn1 = (insn1 & 0xffff0000) | ((addend >> 16) & 0xffff);
01703            insn2 = (insn2 & 0xffff0000) | (addend & 0xffff);
01704 
01705            bfd_put_32 (input_bfd, (bfd_vma) insn1,
01706                      contents + r_vaddr - input_section->vma);
01707            bfd_put_32 (input_bfd, (bfd_vma) insn2,
01708                      contents + r_vaddr - input_section->vma + r_symndx);
01709 
01710            gp_usedp = TRUE;
01711          }
01712          break;
01713 
01714        case ALPHA_R_OP_PUSH:
01715        case ALPHA_R_OP_PSUB:
01716        case ALPHA_R_OP_PRSHIFT:
01717          /* Manipulate values on the reloc evaluation stack.  The
01718             r_vaddr field is not an address in input_section, it is
01719             the current value (including any addend) of the object
01720             being used.  */
01721          if (! r_extern)
01722            {
01723              asection *s;
01724 
01725              s = symndx_to_section[r_symndx];
01726              if (s == (asection *) NULL)
01727               abort ();
01728              addend = s->output_section->vma + s->output_offset - s->vma;
01729            }
01730          else
01731            {
01732              struct ecoff_link_hash_entry *h;
01733 
01734              h = sym_hashes[r_symndx];
01735              if (h == (struct ecoff_link_hash_entry *) NULL)
01736               abort ();
01737 
01738              if (! info->relocatable)
01739               {
01740                 if (h->root.type == bfd_link_hash_defined
01741                     || h->root.type == bfd_link_hash_defweak)
01742                   addend = (h->root.u.def.value
01743                            + h->root.u.def.section->output_section->vma
01744                            + h->root.u.def.section->output_offset);
01745                 else
01746                   {
01747                     /* Note that we pass the address as 0, since we
01748                       do not have a meaningful number for the
01749                       location within the section that is being
01750                       relocated.  */
01751                     if (! ((*info->callbacks->undefined_symbol)
01752                           (info, h->root.root.string, input_bfd,
01753                            input_section, (bfd_vma) 0, TRUE)))
01754                      return FALSE;
01755                     addend = 0;
01756                   }
01757               }
01758              else
01759               {
01760                 if (h->root.type != bfd_link_hash_defined
01761                     && h->root.type != bfd_link_hash_defweak
01762                     && h->indx == -1)
01763                   {
01764                     /* This symbol is not being written out.  Pass
01765                       the address as 0, as with undefined_symbol,
01766                       above.  */
01767                     if (! ((*info->callbacks->unattached_reloc)
01768                           (info, h->root.root.string, input_bfd,
01769                            input_section, (bfd_vma) 0)))
01770                      return FALSE;
01771                   }
01772 
01773                 addend = alpha_convert_external_reloc (output_bfd, info,
01774                                                   input_bfd,
01775                                                   ext_rel, h);
01776               }
01777            }
01778 
01779          addend += r_vaddr;
01780 
01781          if (info->relocatable)
01782            {
01783              /* Adjust r_vaddr by the addend.  */
01784              H_PUT_64 (input_bfd, addend, ext_rel->r_vaddr);
01785            }
01786          else
01787            {
01788              switch (r_type)
01789               {
01790               case ALPHA_R_OP_PUSH:
01791                 if (tos >= RELOC_STACKSIZE)
01792                   abort ();
01793                 stack[tos++] = addend;
01794                 break;
01795 
01796               case ALPHA_R_OP_PSUB:
01797                 if (tos == 0)
01798                   abort ();
01799                 stack[tos - 1] -= addend;
01800                 break;
01801 
01802               case ALPHA_R_OP_PRSHIFT:
01803                 if (tos == 0)
01804                   abort ();
01805                 stack[tos - 1] >>= addend;
01806                 break;
01807               }
01808            }
01809 
01810          adjust_addrp = FALSE;
01811          break;
01812 
01813        case ALPHA_R_OP_STORE:
01814          /* Store a value from the reloc stack into a bitfield.  If
01815             we are generating relocatable output, all we do is
01816             adjust the address of the reloc.  */
01817          if (! info->relocatable)
01818            {
01819              bfd_vma mask;
01820              bfd_vma val;
01821 
01822              if (tos == 0)
01823               abort ();
01824 
01825              /* Get the relocation mask.  The separate steps and the
01826                casts to bfd_vma are attempts to avoid a bug in the
01827                Alpha OSF 1.3 C compiler.  See reloc.c for more
01828                details.  */
01829              mask = 1;
01830              mask <<= (bfd_vma) r_size;
01831              mask -= 1;
01832 
01833              /* FIXME: I don't know what kind of overflow checking,
01834                if any, should be done here.  */
01835              val = bfd_get_64 (input_bfd,
01836                             contents + r_vaddr - input_section->vma);
01837              val &=~ mask << (bfd_vma) r_offset;
01838              val |= (stack[--tos] & mask) << (bfd_vma) r_offset;
01839              bfd_put_64 (input_bfd, val,
01840                        contents + r_vaddr - input_section->vma);
01841            }
01842          break;
01843 
01844        case ALPHA_R_GPVALUE:
01845          /* I really don't know if this does the right thing.  */
01846          gp = ecoff_data (input_bfd)->gp + r_symndx;
01847          gp_undefined = FALSE;
01848          break;
01849        }
01850 
01851       if (relocatep)
01852        {
01853          reloc_howto_type *howto;
01854          struct ecoff_link_hash_entry *h = NULL;
01855          asection *s = NULL;
01856          bfd_vma relocation;
01857          bfd_reloc_status_type r;
01858 
01859          /* Perform a relocation.  */
01860 
01861          howto = &alpha_howto_table[r_type];
01862 
01863          if (r_extern)
01864            {
01865              h = sym_hashes[r_symndx];
01866              /* If h is NULL, that means that there is a reloc
01867                against an external symbol which we thought was just
01868                a debugging symbol.  This should not happen.  */
01869              if (h == (struct ecoff_link_hash_entry *) NULL)
01870               abort ();
01871            }
01872          else
01873            {
01874              if (r_symndx >= NUM_RELOC_SECTIONS)
01875               s = NULL;
01876              else
01877               s = symndx_to_section[r_symndx];
01878 
01879              if (s == (asection *) NULL)
01880               abort ();
01881            }
01882 
01883          if (info->relocatable)
01884            {
01885              /* We are generating relocatable output, and must
01886                convert the existing reloc.  */
01887              if (r_extern)
01888               {
01889                 if (h->root.type != bfd_link_hash_defined
01890                     && h->root.type != bfd_link_hash_defweak
01891                     && h->indx == -1)
01892                   {
01893                     /* This symbol is not being written out.  */
01894                     if (! ((*info->callbacks->unattached_reloc)
01895                           (info, h->root.root.string, input_bfd,
01896                            input_section, r_vaddr - input_section->vma)))
01897                      return FALSE;
01898                   }
01899 
01900                 relocation = alpha_convert_external_reloc (output_bfd,
01901                                                       info,
01902                                                       input_bfd,
01903                                                       ext_rel,
01904                                                       h);
01905               }
01906              else
01907               {
01908                 /* This is a relocation against a section.  Adjust
01909                    the value by the amount the section moved.  */
01910                 relocation = (s->output_section->vma
01911                             + s->output_offset
01912                             - s->vma);
01913               }
01914 
01915              /* If this is PC relative, the existing object file
01916                appears to already have the reloc worked out.  We
01917                must subtract out the old value and add in the new
01918                one.  */
01919              if (howto->pc_relative)
01920               relocation -= (input_section->output_section->vma
01921                             + input_section->output_offset
01922                             - input_section->vma);
01923 
01924              /* Put in any addend.  */
01925              relocation += addend;
01926 
01927              /* Adjust the contents.  */
01928              r = _bfd_relocate_contents (howto, input_bfd, relocation,
01929                                      (contents
01930                                       + r_vaddr
01931                                       - input_section->vma));
01932            }
01933          else
01934            {
01935              /* We are producing a final executable.  */
01936              if (r_extern)
01937               {
01938                 /* This is a reloc against a symbol.  */
01939                 if (h->root.type == bfd_link_hash_defined
01940                     || h->root.type == bfd_link_hash_defweak)
01941                   {
01942                     asection *hsec;
01943 
01944                     hsec = h->root.u.def.section;
01945                     relocation = (h->root.u.def.value
01946                                 + hsec->output_section->vma
01947                                 + hsec->output_offset);
01948                   }
01949                 else
01950                   {
01951                     if (! ((*info->callbacks->undefined_symbol)
01952                           (info, h->root.root.string, input_bfd,
01953                            input_section,
01954                            r_vaddr - input_section->vma, TRUE)))
01955                      return FALSE;
01956                     relocation = 0;
01957                   }
01958               }
01959              else
01960               {
01961                 /* This is a reloc against a section.  */
01962                 relocation = (s->output_section->vma
01963                             + s->output_offset
01964                             - s->vma);
01965 
01966                 /* Adjust a PC relative relocation by removing the
01967                    reference to the original source section.  */
01968                 if (howto->pc_relative)
01969                   relocation += input_section->vma;
01970               }
01971 
01972              r = _bfd_final_link_relocate (howto,
01973                                        input_bfd,
01974                                        input_section,
01975                                        contents,
01976                                        r_vaddr - input_section->vma,
01977                                        relocation,
01978                                        addend);
01979            }
01980 
01981          if (r != bfd_reloc_ok)
01982            {
01983              switch (r)
01984               {
01985               default:
01986               case bfd_reloc_outofrange:
01987                 abort ();
01988               case bfd_reloc_overflow:
01989                 {
01990                   const char *name;
01991 
01992                   if (r_extern)
01993                     name = sym_hashes[r_symndx]->root.root.string;
01994                   else
01995                     name = bfd_section_name (input_bfd,
01996                                           symndx_to_section[r_symndx]);
01997                   if (! ((*info->callbacks->reloc_overflow)
01998                         (info, NULL, name,
01999                          alpha_howto_table[r_type].name,
02000                          (bfd_vma) 0, input_bfd, input_section,
02001                          r_vaddr - input_section->vma)))
02002                     return FALSE;
02003                 }
02004                 break;
02005               }
02006            }
02007        }
02008 
02009       if (info->relocatable && adjust_addrp)
02010        {
02011          /* Change the address of the relocation.  */
02012          H_PUT_64 (input_bfd,
02013                   (input_section->output_section->vma
02014                    + input_section->output_offset
02015                    - input_section->vma
02016                    + r_vaddr),
02017                   ext_rel->r_vaddr);
02018        }
02019 
02020       if (gp_usedp && gp_undefined)
02021        {
02022          if (! ((*info->callbacks->reloc_dangerous)
02023                (info, _("GP relative relocation used when GP not defined"),
02024                 input_bfd, input_section, r_vaddr - input_section->vma)))
02025            return FALSE;
02026          /* Only give the error once per link.  */
02027          gp = 4;
02028          _bfd_set_gp_value (output_bfd, gp);
02029          gp_undefined = FALSE;
02030        }
02031     }
02032 
02033   if (tos != 0)
02034     abort ();
02035 
02036   return TRUE;
02037 }
02038 
02039 /* Do final adjustments to the filehdr and the aouthdr.  This routine
02040    sets the dynamic bits in the file header.  */
02041 
02042 static bfd_boolean
02043 alpha_adjust_headers (abfd, fhdr, ahdr)
02044      bfd *abfd;
02045      struct internal_filehdr *fhdr;
02046      struct internal_aouthdr *ahdr ATTRIBUTE_UNUSED;
02047 {
02048   if ((abfd->flags & (DYNAMIC | EXEC_P)) == (DYNAMIC | EXEC_P))
02049     fhdr->f_flags |= F_ALPHA_CALL_SHARED;
02050   else if ((abfd->flags & DYNAMIC) != 0)
02051     fhdr->f_flags |= F_ALPHA_SHARABLE;
02052   return TRUE;
02053 }
02054 
02055 /* Archive handling.  In OSF/1 (or Digital Unix) v3.2, Digital
02056    introduced archive packing, in which the elements in an archive are
02057    optionally compressed using a simple dictionary scheme.  We know
02058    how to read such archives, but we don't write them.  */
02059 
02060 #define alpha_ecoff_slurp_armap _bfd_ecoff_slurp_armap
02061 #define alpha_ecoff_slurp_extended_name_table \
02062   _bfd_ecoff_slurp_extended_name_table
02063 #define alpha_ecoff_construct_extended_name_table \
02064   _bfd_ecoff_construct_extended_name_table
02065 #define alpha_ecoff_truncate_arname _bfd_ecoff_truncate_arname
02066 #define alpha_ecoff_write_armap _bfd_ecoff_write_armap
02067 #define alpha_ecoff_generic_stat_arch_elt _bfd_ecoff_generic_stat_arch_elt
02068 #define alpha_ecoff_update_armap_timestamp _bfd_ecoff_update_armap_timestamp
02069 
02070 /* A compressed file uses this instead of ARFMAG.  */
02071 
02072 #define ARFZMAG "Z\012"
02073 
02074 /* Read an archive header.  This is like the standard routine, but it
02075    also accepts ARFZMAG.  */
02076 
02077 static PTR
02078 alpha_ecoff_read_ar_hdr (abfd)
02079      bfd *abfd;
02080 {
02081   struct areltdata *ret;
02082   struct ar_hdr *h;
02083 
02084   ret = (struct areltdata *) _bfd_generic_read_ar_hdr_mag (abfd, ARFZMAG);
02085   if (ret == NULL)
02086     return NULL;
02087 
02088   h = (struct ar_hdr *) ret->arch_header;
02089   if (strncmp (h->ar_fmag, ARFZMAG, 2) == 0)
02090     {
02091       bfd_byte ab[8];
02092 
02093       /* This is a compressed file.  We must set the size correctly.
02094          The size is the eight bytes after the dummy file header.  */
02095       if (bfd_seek (abfd, (file_ptr) FILHSZ, SEEK_CUR) != 0
02096          || bfd_bread (ab, (bfd_size_type) 8, abfd) != 8
02097          || bfd_seek (abfd, (file_ptr) (- (FILHSZ + 8)), SEEK_CUR) != 0)
02098        return NULL;
02099 
02100       ret->parsed_size = H_GET_64 (abfd, ab);
02101     }
02102 
02103   return (PTR) ret;
02104 }
02105 
02106 /* Get an archive element at a specified file position.  This is where
02107    we uncompress the archive element if necessary.  */
02108 
02109 static bfd *
02110 alpha_ecoff_get_elt_at_filepos (archive, filepos)
02111      bfd *archive;
02112      file_ptr filepos;
02113 {
02114   bfd *nbfd = NULL;
02115   struct areltdata *tdata;
02116   struct ar_hdr *hdr;
02117   bfd_byte ab[8];
02118   bfd_size_type size;
02119   bfd_byte *buf, *p;
02120   struct bfd_in_memory *bim;
02121 
02122   nbfd = _bfd_get_elt_at_filepos (archive, filepos);
02123   if (nbfd == NULL)
02124     goto error_return;
02125 
02126   if ((nbfd->flags & BFD_IN_MEMORY) != 0)
02127     {
02128       /* We have already expanded this BFD.  */
02129       return nbfd;
02130     }
02131 
02132   tdata = (struct areltdata *) nbfd->arelt_data;
02133   hdr = (struct ar_hdr *) tdata->arch_header;
02134   if (strncmp (hdr->ar_fmag, ARFZMAG, 2) != 0)
02135     return nbfd;
02136 
02137   /* We must uncompress this element.  We do this by copying it into a
02138      memory buffer, and making bfd_bread and bfd_seek use that buffer.
02139      This can use a lot of memory, but it's simpler than getting a
02140      temporary file, making that work with the file descriptor caching
02141      code, and making sure that it is deleted at all appropriate
02142      times.  It can be changed if it ever becomes important.  */
02143 
02144   /* The compressed file starts with a dummy ECOFF file header.  */
02145   if (bfd_seek (nbfd, (file_ptr) FILHSZ, SEEK_SET) != 0)
02146     goto error_return;
02147 
02148   /* The next eight bytes are the real file size.  */
02149   if (bfd_bread (ab, (bfd_size_type) 8, nbfd) != 8)
02150     goto error_return;
02151   size = H_GET_64 (nbfd, ab);
02152 
02153   if (size == 0)
02154     buf = NULL;
02155   else
02156     {
02157       bfd_size_type left;
02158       bfd_byte dict[4096];
02159       unsigned int h;
02160       bfd_byte b;
02161 
02162       buf = (bfd_byte *) bfd_alloc (nbfd, size);
02163       if (buf == NULL)
02164        goto error_return;
02165       p = buf;
02166 
02167       left = size;
02168 
02169       /* I don't know what the next eight bytes are for.  */
02170       if (bfd_bread (ab, (bfd_size_type) 8, nbfd) != 8)
02171        goto error_return;
02172 
02173       /* This is the uncompression algorithm.  It's a simple
02174         dictionary based scheme in which each character is predicted
02175         by a hash of the previous three characters.  A control byte
02176         indicates whether the character is predicted or whether it
02177         appears in the input stream; each control byte manages the
02178         next eight bytes in the output stream.  */
02179       memset (dict, 0, sizeof dict);
02180       h = 0;
02181       while (bfd_bread (&b, (bfd_size_type) 1, nbfd) == 1)
02182        {
02183          unsigned int i;
02184 
02185          for (i = 0; i < 8; i++, b >>= 1)
02186            {
02187              bfd_byte n;
02188 
02189              if ((b & 1) == 0)
02190               n = dict[h];
02191              else
02192               {
02193                 if (! bfd_bread (&n, (bfd_size_type) 1, nbfd))
02194                   goto error_return;
02195                 dict[h] = n;
02196               }
02197 
02198              *p++ = n;
02199 
02200              --left;
02201              if (left == 0)
02202               break;
02203 
02204              h <<= 4;
02205              h ^= n;
02206              h &= sizeof dict - 1;
02207            }
02208 
02209          if (left == 0)
02210            break;
02211        }
02212     }
02213 
02214   /* Now the uncompressed file contents are in buf.  */
02215   bim = ((struct bfd_in_memory *)
02216         bfd_alloc (nbfd, (bfd_size_type) sizeof (struct bfd_in_memory)));
02217   if (bim == NULL)
02218     goto error_return;
02219   bim->size = size;
02220   bim->buffer = buf;
02221 
02222   nbfd->mtime_set = TRUE;
02223   nbfd->mtime = strtol (hdr->ar_date, (char **) NULL, 10);
02224 
02225   nbfd->flags |= BFD_IN_MEMORY;
02226   nbfd->iostream = (PTR) bim;
02227   BFD_ASSERT (! nbfd->cacheable);
02228 
02229   return nbfd;
02230 
02231  error_return:
02232   if (nbfd != NULL)
02233     bfd_close (nbfd);
02234   return NULL;
02235 }
02236 
02237 /* Open the next archived file.  */
02238 
02239 static bfd *
02240 alpha_ecoff_openr_next_archived_file (archive, last_file)
02241      bfd *archive;
02242      bfd *last_file;
02243 {
02244   file_ptr filestart;
02245 
02246   if (last_file == NULL)
02247     filestart = bfd_ardata (archive)->first_file_filepos;
02248   else
02249     {
02250       struct areltdata *t;
02251       struct ar_hdr *h;
02252       bfd_size_type size;
02253 
02254       /* We can't use arelt_size here, because that uses parsed_size,
02255          which is the uncompressed size.  We need the compressed size.  */
02256       t = (struct areltdata *) last_file->arelt_data;
02257       h = (struct ar_hdr *) t->arch_header;
02258       size = strtol (h->ar_size, (char **) NULL, 10);
02259 
02260       /* Pad to an even boundary...
02261         Note that last_file->origin can be odd in the case of
02262         BSD-4.4-style element with a long odd size.  */
02263       filestart = last_file->origin + size;
02264       filestart += filestart % 2;
02265     }
02266 
02267   return alpha_ecoff_get_elt_at_filepos (archive, filestart);
02268 }
02269 
02270 /* Open the archive file given an index into the armap.  */
02271 
02272 static bfd *
02273 alpha_ecoff_get_elt_at_index (abfd, index)
02274      bfd *abfd;
02275      symindex index;
02276 {
02277   carsym *entry;
02278 
02279   entry = bfd_ardata (abfd)->symdefs + index;
02280   return alpha_ecoff_get_elt_at_filepos (abfd, entry->file_offset);
02281 }
02282 
02283 /* This is the ECOFF backend structure.  The backend field of the
02284    target vector points to this.  */
02285 
02286 static const struct ecoff_backend_data alpha_ecoff_backend_data =
02287 {
02288   /* COFF backend structure.  */
02289   {
02290     (void (*) PARAMS ((bfd *,PTR,int,int,int,int,PTR))) bfd_void, /* aux_in */
02291     (void (*) PARAMS ((bfd *,PTR,PTR))) bfd_void, /* sym_in */
02292     (void (*) PARAMS ((bfd *,PTR,PTR))) bfd_void, /* lineno_in */
02293     (unsigned (*) PARAMS ((bfd *,PTR,int,int,int,int,PTR)))bfd_void,/*aux_out*/
02294     (unsigned (*) PARAMS ((bfd *,PTR,PTR))) bfd_void, /* sym_out */
02295     (unsigned (*) PARAMS ((bfd *,PTR,PTR))) bfd_void, /* lineno_out */
02296     (unsigned (*) PARAMS ((bfd *,PTR,PTR))) bfd_void, /* reloc_out */
02297     alpha_ecoff_swap_filehdr_out, alpha_ecoff_swap_aouthdr_out,
02298     alpha_ecoff_swap_scnhdr_out,
02299     FILHSZ, AOUTSZ, SCNHSZ, 0, 0, 0, 0, FILNMLEN, TRUE, FALSE, 4, FALSE, 2,
02300     alpha_ecoff_swap_filehdr_in, alpha_ecoff_swap_aouthdr_in,
02301     alpha_ecoff_swap_scnhdr_in, NULL,
02302     alpha_ecoff_bad_format_hook, _bfd_ecoff_set_arch_mach_hook,
02303     alpha_ecoff_mkobject_hook, _bfd_ecoff_styp_to_sec_flags,
02304     _bfd_ecoff_set_alignment_hook, _bfd_ecoff_slurp_symbol_table,
02305     NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
02306     NULL, NULL, NULL
02307   },
02308   /* Supported architecture.  */
02309   bfd_arch_alpha,
02310   /* Initial portion of armap string.  */
02311   "________64",
02312   /* The page boundary used to align sections in a demand-paged
02313      executable file.  E.g., 0x1000.  */
02314   0x2000,
02315   /* TRUE if the .rdata section is part of the text segment, as on the
02316      Alpha.  FALSE if .rdata is part of the data segment, as on the
02317      MIPS.  */
02318   TRUE,
02319   /* Bitsize of constructor entries.  */
02320   64,
02321   /* Reloc to use for constructor entries.  */
02322   &alpha_howto_table[ALPHA_R_REFQUAD],
02323   {
02324     /* Symbol table magic number.  */
02325     magicSym2,
02326     /* Alignment of debugging information.  E.g., 4.  */
02327     8,
02328     /* Sizes of external symbolic information.  */
02329     sizeof (struct hdr_ext),
02330     sizeof (struct dnr_ext),
02331     sizeof (struct pdr_ext),
02332     sizeof (struct sym_ext),
02333     sizeof (struct opt_ext),
02334     sizeof (struct fdr_ext),
02335     sizeof (struct rfd_ext),
02336     sizeof (struct ext_ext),
02337     /* Functions to swap in external symbolic data.  */
02338     ecoff_swap_hdr_in,
02339     ecoff_swap_dnr_in,
02340     ecoff_swap_pdr_in,
02341     ecoff_swap_sym_in,
02342     ecoff_swap_opt_in,
02343     ecoff_swap_fdr_in,
02344     ecoff_swap_rfd_in,
02345     ecoff_swap_ext_in,
02346     _bfd_ecoff_swap_tir_in,
02347     _bfd_ecoff_swap_rndx_in,
02348     /* Functions to swap out external symbolic data.  */
02349     ecoff_swap_hdr_out,
02350     ecoff_swap_dnr_out,
02351     ecoff_swap_pdr_out,
02352     ecoff_swap_sym_out,
02353     ecoff_swap_opt_out,
02354     ecoff_swap_fdr_out,
02355     ecoff_swap_rfd_out,
02356     ecoff_swap_ext_out,
02357     _bfd_ecoff_swap_tir_out,
02358     _bfd_ecoff_swap_rndx_out,
02359     /* Function to read in symbolic data.  */
02360     _bfd_ecoff_slurp_symbolic_info
02361   },
02362   /* External reloc size.  */
02363   RELSZ,
02364   /* Reloc swapping functions.  */
02365   alpha_ecoff_swap_reloc_in,
02366   alpha_ecoff_swap_reloc_out,
02367   /* Backend reloc tweaking.  */
02368   alpha_adjust_reloc_in,
02369   alpha_adjust_reloc_out,
02370   /* Relocate section contents while linking.  */
02371   alpha_relocate_section,
02372   /* Do final adjustments to filehdr and aouthdr.  */
02373   alpha_adjust_headers,
02374   /* Read an element from an archive at a given file position.  */
02375   alpha_ecoff_get_elt_at_filepos
02376 };
02377 
02378 /* Looking up a reloc type is Alpha specific.  */
02379 #define _bfd_ecoff_bfd_reloc_type_lookup alpha_bfd_reloc_type_lookup
02380 #define _bfd_ecoff_bfd_reloc_name_lookup \
02381   alpha_bfd_reloc_name_lookup
02382 
02383 /* So is getting relocated section contents.  */
02384 #define _bfd_ecoff_bfd_get_relocated_section_contents \
02385   alpha_ecoff_get_relocated_section_contents
02386 
02387 /* Handling file windows is generic.  */
02388 #define _bfd_ecoff_get_section_contents_in_window \
02389   _bfd_generic_get_section_contents_in_window
02390 
02391 /* Relaxing sections is generic.  */
02392 #define _bfd_ecoff_bfd_relax_section bfd_generic_relax_section
02393 #define _bfd_ecoff_bfd_gc_sections bfd_generic_gc_sections
02394 #define _bfd_ecoff_bfd_merge_sections bfd_generic_merge_sections
02395 #define _bfd_ecoff_bfd_is_group_section bfd_generic_is_group_section
02396 #define _bfd_ecoff_bfd_discard_group bfd_generic_discard_group
02397 #define _bfd_ecoff_section_already_linked \
02398   _bfd_generic_section_already_linked
02399 
02400 const bfd_target ecoffalpha_little_vec =
02401 {
02402   "ecoff-littlealpha",             /* name */
02403   bfd_target_ecoff_flavour,
02404   BFD_ENDIAN_LITTLE,        /* data byte order is little */
02405   BFD_ENDIAN_LITTLE,        /* header byte order is little */
02406 
02407   (HAS_RELOC | EXEC_P |            /* object flags */
02408    HAS_LINENO | HAS_DEBUG |
02409    HAS_SYMS | HAS_LOCALS | DYNAMIC | WP_TEXT | D_PAGED),
02410 
02411   (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_CODE | SEC_DATA),
02412   0,                        /* leading underscore */
02413   ' ',                      /* ar_pad_char */
02414   15,                       /* ar_max_namelen */
02415   bfd_getl64, bfd_getl_signed_64, bfd_putl64,
02416      bfd_getl32, bfd_getl_signed_32, bfd_putl32,
02417      bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* data */
02418   bfd_getl64, bfd_getl_signed_64, bfd_putl64,
02419      bfd_getl32, bfd_getl_signed_32, bfd_putl32,
02420      bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* hdrs */
02421 
02422   {_bfd_dummy_target, alpha_ecoff_object_p, /* bfd_check_format */
02423      _bfd_ecoff_archive_p, _bfd_dummy_target},
02424   {bfd_false, _bfd_ecoff_mkobject,  /* bfd_set_format */
02425      _bfd_generic_mkarchive, bfd_false},
02426   {bfd_false, _bfd_ecoff_write_object_contents, /* bfd_write_contents */
02427      _bfd_write_archive_contents, bfd_false},
02428 
02429      BFD_JUMP_TABLE_GENERIC (_bfd_ecoff),
02430      BFD_JUMP_TABLE_COPY (_bfd_ecoff),
02431      BFD_JUMP_TABLE_CORE (_bfd_nocore),
02432      BFD_JUMP_TABLE_ARCHIVE (alpha_ecoff),
02433      BFD_JUMP_TABLE_SYMBOLS (_bfd_ecoff),
02434      BFD_JUMP_TABLE_RELOCS (_bfd_ecoff),
02435      BFD_JUMP_TABLE_WRITE (_bfd_ecoff),
02436      BFD_JUMP_TABLE_LINK (_bfd_ecoff),
02437      BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
02438 
02439   NULL,
02440 
02441   (PTR) &alpha_ecoff_backend_data
02442 };