Back to index

cell-binutils  2.17cvs20070401
coff-rs6000.c
Go to the documentation of this file.
00001 /* BFD back-end for IBM RS/6000 "XCOFF" files.
00002    Copyright 1990-1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
00003    Free Software Foundation, Inc.
00004    FIXME: Can someone provide a transliteration of this name into ASCII?
00005    Using the following chars caused a compiler warning on HIUX (so I replaced
00006    them with octal escapes), and isn't useful without an understanding of what
00007    character set it is.
00008    Written by Metin G. Ozisik, Mimi Ph\373\364ng-Th\345o V\365,
00009      and John Gilmore.
00010    Archive support from Damon A. Permezel.
00011    Contributed by IBM Corporation and Cygnus Support.
00012 
00013 This file is part of BFD, the Binary File Descriptor library.
00014 
00015 This program is free software; you can redistribute it and/or modify
00016 it under the terms of the GNU General Public License as published by
00017 the Free Software Foundation; either version 2 of the License, or
00018 (at your option) any later version.
00019 
00020 This program is distributed in the hope that it will be useful,
00021 but WITHOUT ANY WARRANTY; without even the implied warranty of
00022 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00023 GNU General Public License for more details.
00024 
00025 You should have received a copy of the GNU General Public License
00026 along with this program; if not, write to the Free Software
00027 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.  */
00028 
00029 #include "bfd.h"
00030 #include "sysdep.h"
00031 #include "bfdlink.h"
00032 #include "libbfd.h"
00033 #include "coff/internal.h"
00034 #include "coff/xcoff.h"
00035 #include "coff/rs6000.h"
00036 #include "libcoff.h"
00037 #include "libxcoff.h"
00038 
00039 extern bfd_boolean _bfd_xcoff_mkobject
00040   PARAMS ((bfd *));
00041 extern bfd_boolean _bfd_xcoff_copy_private_bfd_data
00042   PARAMS ((bfd *, bfd *));
00043 extern bfd_boolean _bfd_xcoff_is_local_label_name
00044   PARAMS ((bfd *, const char *));
00045 extern reloc_howto_type *_bfd_xcoff_reloc_type_lookup
00046   PARAMS ((bfd *, bfd_reloc_code_real_type));
00047 extern bfd_boolean _bfd_xcoff_slurp_armap
00048   PARAMS ((bfd *));
00049 extern const bfd_target *_bfd_xcoff_archive_p
00050   PARAMS ((bfd *));
00051 extern PTR _bfd_xcoff_read_ar_hdr
00052   PARAMS ((bfd *));
00053 extern bfd *_bfd_xcoff_openr_next_archived_file
00054   PARAMS ((bfd *, bfd *));
00055 extern int _bfd_xcoff_stat_arch_elt
00056   PARAMS ((bfd *, struct stat *));
00057 extern bfd_boolean _bfd_xcoff_write_armap
00058   PARAMS ((bfd *, unsigned int, struct orl *, unsigned int, int));
00059 extern bfd_boolean _bfd_xcoff_write_archive_contents
00060   PARAMS ((bfd *));
00061 extern int _bfd_xcoff_sizeof_headers
00062   PARAMS ((bfd *, struct bfd_link_info *));
00063 extern void _bfd_xcoff_swap_sym_in
00064   PARAMS ((bfd *, PTR, PTR));
00065 extern unsigned int _bfd_xcoff_swap_sym_out
00066   PARAMS ((bfd *, PTR, PTR));
00067 extern void _bfd_xcoff_swap_aux_in
00068   PARAMS ((bfd *, PTR, int, int, int, int, PTR));
00069 extern unsigned int _bfd_xcoff_swap_aux_out
00070   PARAMS ((bfd *, PTR, int, int, int, int, PTR));
00071 static void xcoff_swap_reloc_in
00072   PARAMS ((bfd *, PTR, PTR));
00073 static unsigned int xcoff_swap_reloc_out
00074   PARAMS ((bfd *, PTR, PTR));
00075 
00076 /* Forward declare xcoff_rtype2howto for coffcode.h macro.  */
00077 void xcoff_rtype2howto
00078   PARAMS ((arelent *, struct internal_reloc *));
00079 
00080 /* coffcode.h needs these to be defined.  */
00081 #define RS6000COFF_C 1
00082 
00083 #define SELECT_RELOC(internal, howto)                                 \
00084   {                                                            \
00085     internal.r_type = howto->type;                             \
00086     internal.r_size =                                                 \
00087       ((howto->complain_on_overflow == complain_overflow_signed              \
00088        ? 0x80                                                  \
00089        : 0)                                                    \
00090        | (howto->bitsize - 1));                                       \
00091   }
00092 
00093 #define COFF_DEFAULT_SECTION_ALIGNMENT_POWER (3)
00094 #define COFF_LONG_FILENAMES
00095 #define NO_COFF_SYMBOLS
00096 #define RTYPE2HOWTO(cache_ptr, dst) xcoff_rtype2howto (cache_ptr, dst)
00097 #define coff_mkobject _bfd_xcoff_mkobject
00098 #define coff_bfd_copy_private_bfd_data _bfd_xcoff_copy_private_bfd_data
00099 #define coff_bfd_is_local_label_name _bfd_xcoff_is_local_label_name
00100 #define coff_bfd_reloc_type_lookup _bfd_xcoff_reloc_type_lookup
00101 #define coff_bfd_reloc_name_lookup _bfd_xcoff_reloc_name_lookup
00102 #ifdef AIX_CORE
00103 extern const bfd_target * rs6000coff_core_p
00104   PARAMS ((bfd *abfd));
00105 extern bfd_boolean rs6000coff_core_file_matches_executable_p
00106   PARAMS ((bfd *cbfd, bfd *ebfd));
00107 extern char *rs6000coff_core_file_failing_command
00108   PARAMS ((bfd *abfd));
00109 extern int rs6000coff_core_file_failing_signal
00110   PARAMS ((bfd *abfd));
00111 #define CORE_FILE_P rs6000coff_core_p
00112 #define coff_core_file_failing_command \
00113   rs6000coff_core_file_failing_command
00114 #define coff_core_file_failing_signal \
00115   rs6000coff_core_file_failing_signal
00116 #define coff_core_file_matches_executable_p \
00117   rs6000coff_core_file_matches_executable_p
00118 #else
00119 #define CORE_FILE_P _bfd_dummy_target
00120 #define coff_core_file_failing_command \
00121   _bfd_nocore_core_file_failing_command
00122 #define coff_core_file_failing_signal \
00123   _bfd_nocore_core_file_failing_signal
00124 #define coff_core_file_matches_executable_p \
00125   _bfd_nocore_core_file_matches_executable_p
00126 #endif
00127 #define coff_SWAP_sym_in _bfd_xcoff_swap_sym_in
00128 #define coff_SWAP_sym_out _bfd_xcoff_swap_sym_out
00129 #define coff_SWAP_aux_in _bfd_xcoff_swap_aux_in
00130 #define coff_SWAP_aux_out _bfd_xcoff_swap_aux_out
00131 #define coff_swap_reloc_in xcoff_swap_reloc_in
00132 #define coff_swap_reloc_out xcoff_swap_reloc_out
00133 #define NO_COFF_RELOCS
00134 
00135 #include "coffcode.h"
00136 
00137 /* The main body of code is in coffcode.h.  */
00138 
00139 static const char *normalize_filename
00140   PARAMS ((bfd *));
00141 static bfd_boolean xcoff_write_armap_old
00142   PARAMS ((bfd *, unsigned int, struct orl *, unsigned int, int));
00143 static bfd_boolean xcoff_write_armap_big
00144   PARAMS ((bfd *, unsigned int, struct orl *, unsigned int, int));
00145 static bfd_boolean xcoff_write_archive_contents_old
00146   PARAMS ((bfd *));
00147 static bfd_boolean xcoff_write_archive_contents_big
00148   PARAMS ((bfd *));
00149 static void xcoff_swap_ldhdr_in
00150   PARAMS ((bfd *, const PTR, struct internal_ldhdr *));
00151 static void xcoff_swap_ldhdr_out
00152   PARAMS ((bfd *, const struct internal_ldhdr *, PTR));
00153 static void xcoff_swap_ldsym_in
00154   PARAMS ((bfd *, const PTR, struct internal_ldsym *));
00155 static void xcoff_swap_ldsym_out
00156   PARAMS ((bfd *, const struct internal_ldsym *, PTR));
00157 static void xcoff_swap_ldrel_in
00158   PARAMS ((bfd *, const PTR, struct internal_ldrel *));
00159 static void xcoff_swap_ldrel_out
00160   PARAMS ((bfd *, const struct internal_ldrel *, PTR));
00161 static bfd_boolean xcoff_ppc_relocate_section
00162   PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *,
00163           struct internal_reloc *, struct internal_syment *, asection **));
00164 static bfd_boolean _bfd_xcoff_put_ldsymbol_name
00165   PARAMS ((bfd *, struct xcoff_loader_info *, struct internal_ldsym *,
00166           const char *));
00167 static asection *xcoff_create_csect_from_smclas
00168   PARAMS ((bfd *, union internal_auxent *, const char *));
00169 static bfd_boolean xcoff_is_lineno_count_overflow
00170   PARAMS ((bfd *, bfd_vma));
00171 static bfd_boolean xcoff_is_reloc_count_overflow
00172   PARAMS ((bfd *, bfd_vma));
00173 static bfd_vma xcoff_loader_symbol_offset
00174   PARAMS ((bfd *, struct internal_ldhdr *));
00175 static bfd_vma xcoff_loader_reloc_offset
00176   PARAMS ((bfd *, struct internal_ldhdr *));
00177 static bfd_boolean xcoff_generate_rtinit
00178   PARAMS ((bfd *, const char *, const char *, bfd_boolean));
00179 static bfd_boolean do_pad
00180   PARAMS ((bfd *, unsigned int));
00181 static bfd_boolean do_copy
00182   PARAMS ((bfd *, bfd *));
00183 static bfd_boolean do_shared_object_padding
00184   PARAMS ((bfd *, bfd *, file_ptr *, int));
00185 
00186 /* Relocation functions */
00187 static bfd_boolean xcoff_reloc_type_br
00188   PARAMS ((XCOFF_RELOC_FUNCTION_ARGS));
00189 
00190 static bfd_boolean xcoff_complain_overflow_dont_func
00191   PARAMS ((XCOFF_COMPLAIN_FUNCTION_ARGS));
00192 static bfd_boolean xcoff_complain_overflow_bitfield_func
00193   PARAMS ((XCOFF_COMPLAIN_FUNCTION_ARGS));
00194 static bfd_boolean xcoff_complain_overflow_signed_func
00195   PARAMS ((XCOFF_COMPLAIN_FUNCTION_ARGS));
00196 static bfd_boolean xcoff_complain_overflow_unsigned_func
00197   PARAMS ((XCOFF_COMPLAIN_FUNCTION_ARGS));
00198 
00199 bfd_boolean (*xcoff_calculate_relocation[XCOFF_MAX_CALCULATE_RELOCATION])
00200   PARAMS ((XCOFF_RELOC_FUNCTION_ARGS)) =
00201 {
00202   xcoff_reloc_type_pos,      /* R_POS   (0x00) */
00203   xcoff_reloc_type_neg,      /* R_NEG   (0x01) */
00204   xcoff_reloc_type_rel,      /* R_REL   (0x02) */
00205   xcoff_reloc_type_toc,      /* R_TOC   (0x03) */
00206   xcoff_reloc_type_fail, /* R_RTB   (0x04) */
00207   xcoff_reloc_type_toc,      /* R_GL    (0x05) */
00208   xcoff_reloc_type_toc,      /* R_TCL   (0x06) */
00209   xcoff_reloc_type_fail, /*     (0x07) */
00210   xcoff_reloc_type_ba,       /* R_BA    (0x08) */
00211   xcoff_reloc_type_fail, /*     (0x09) */
00212   xcoff_reloc_type_br,       /* R_BR    (0x0a) */
00213   xcoff_reloc_type_fail, /*     (0x0b) */
00214   xcoff_reloc_type_pos,      /* R_RL    (0x0c) */
00215   xcoff_reloc_type_pos,      /* R_RLA   (0x0d) */
00216   xcoff_reloc_type_fail, /*     (0x0e) */
00217   xcoff_reloc_type_noop, /* R_REF   (0x0f) */
00218   xcoff_reloc_type_fail, /*     (0x10) */
00219   xcoff_reloc_type_fail, /*     (0x11) */
00220   xcoff_reloc_type_toc,      /* R_TRL   (0x12) */
00221   xcoff_reloc_type_toc,      /* R_TRLA  (0x13) */
00222   xcoff_reloc_type_fail, /* R_RRTBI (0x14) */
00223   xcoff_reloc_type_fail, /* R_RRTBA (0x15) */
00224   xcoff_reloc_type_ba,       /* R_CAI   (0x16) */
00225   xcoff_reloc_type_crel, /* R_CREL  (0x17) */
00226   xcoff_reloc_type_ba,       /* R_RBA   (0x18) */
00227   xcoff_reloc_type_ba,       /* R_RBAC  (0x19) */
00228   xcoff_reloc_type_br,       /* R_RBR   (0x1a) */
00229   xcoff_reloc_type_ba,       /* R_RBRC  (0x1b) */
00230 };
00231 
00232 bfd_boolean (*xcoff_complain_overflow[XCOFF_MAX_COMPLAIN_OVERFLOW])
00233   PARAMS ((XCOFF_COMPLAIN_FUNCTION_ARGS)) =
00234 {
00235   xcoff_complain_overflow_dont_func,
00236   xcoff_complain_overflow_bitfield_func,
00237   xcoff_complain_overflow_signed_func,
00238   xcoff_complain_overflow_unsigned_func,
00239 };
00240 
00241 /* We use our own tdata type.  Its first field is the COFF tdata type,
00242    so the COFF routines are compatible.  */
00243 
00244 bfd_boolean
00245 _bfd_xcoff_mkobject (abfd)
00246      bfd *abfd;
00247 {
00248   coff_data_type *coff;
00249   bfd_size_type amt = sizeof (struct xcoff_tdata);
00250 
00251   abfd->tdata.xcoff_obj_data = (struct xcoff_tdata *) bfd_zalloc (abfd, amt);
00252   if (abfd->tdata.xcoff_obj_data == NULL)
00253     return FALSE;
00254   coff = coff_data (abfd);
00255   coff->symbols = (coff_symbol_type *) NULL;
00256   coff->conversion_table = (unsigned int *) NULL;
00257   coff->raw_syments = (struct coff_ptr_struct *) NULL;
00258   coff->relocbase = 0;
00259 
00260   xcoff_data (abfd)->modtype = ('1' << 8) | 'L';
00261 
00262   /* We set cputype to -1 to indicate that it has not been
00263      initialized.  */
00264   xcoff_data (abfd)->cputype = -1;
00265 
00266   xcoff_data (abfd)->csects = NULL;
00267   xcoff_data (abfd)->debug_indices = NULL;
00268 
00269   /* text section alignment is different than the default */
00270   bfd_xcoff_text_align_power (abfd) = 2;
00271 
00272   return TRUE;
00273 }
00274 
00275 /* Copy XCOFF data from one BFD to another.  */
00276 
00277 bfd_boolean
00278 _bfd_xcoff_copy_private_bfd_data (ibfd, obfd)
00279      bfd *ibfd;
00280      bfd *obfd;
00281 {
00282   struct xcoff_tdata *ix, *ox;
00283   asection *sec;
00284 
00285   if (ibfd->xvec != obfd->xvec)
00286     return TRUE;
00287   ix = xcoff_data (ibfd);
00288   ox = xcoff_data (obfd);
00289   ox->full_aouthdr = ix->full_aouthdr;
00290   ox->toc = ix->toc;
00291   if (ix->sntoc == 0)
00292     ox->sntoc = 0;
00293   else
00294     {
00295       sec = coff_section_from_bfd_index (ibfd, ix->sntoc);
00296       if (sec == NULL)
00297        ox->sntoc = 0;
00298       else
00299        ox->sntoc = sec->output_section->target_index;
00300     }
00301   if (ix->snentry == 0)
00302     ox->snentry = 0;
00303   else
00304     {
00305       sec = coff_section_from_bfd_index (ibfd, ix->snentry);
00306       if (sec == NULL)
00307        ox->snentry = 0;
00308       else
00309        ox->snentry = sec->output_section->target_index;
00310     }
00311   bfd_xcoff_text_align_power (obfd) = bfd_xcoff_text_align_power (ibfd);
00312   bfd_xcoff_data_align_power (obfd) = bfd_xcoff_data_align_power (ibfd);
00313   ox->modtype = ix->modtype;
00314   ox->cputype = ix->cputype;
00315   ox->maxdata = ix->maxdata;
00316   ox->maxstack = ix->maxstack;
00317   return TRUE;
00318 }
00319 
00320 /* I don't think XCOFF really has a notion of local labels based on
00321    name.  This will mean that ld -X doesn't actually strip anything.
00322    The AIX native linker does not have a -X option, and it ignores the
00323    -x option.  */
00324 
00325 bfd_boolean
00326 _bfd_xcoff_is_local_label_name (abfd, name)
00327      bfd *abfd ATTRIBUTE_UNUSED;
00328      const char *name ATTRIBUTE_UNUSED;
00329 {
00330   return FALSE;
00331 }
00332 
00333 void
00334 _bfd_xcoff_swap_sym_in (abfd, ext1, in1)
00335      bfd *abfd;
00336      PTR ext1;
00337      PTR in1;
00338 {
00339   SYMENT *ext = (SYMENT *)ext1;
00340   struct internal_syment * in = (struct internal_syment *)in1;
00341 
00342   if (ext->e.e_name[0] != 0)
00343     {
00344       memcpy (in->_n._n_name, ext->e.e_name, SYMNMLEN);
00345     }
00346   else
00347     {
00348       in->_n._n_n._n_zeroes = 0;
00349       in->_n._n_n._n_offset = H_GET_32 (abfd, ext->e.e.e_offset);
00350     }
00351 
00352   in->n_value = H_GET_32 (abfd, ext->e_value);
00353   in->n_scnum = H_GET_16 (abfd, ext->e_scnum);
00354   in->n_type = H_GET_16 (abfd, ext->e_type);
00355   in->n_sclass = H_GET_8 (abfd, ext->e_sclass);
00356   in->n_numaux = H_GET_8 (abfd, ext->e_numaux);
00357 }
00358 
00359 unsigned int
00360 _bfd_xcoff_swap_sym_out (abfd, inp, extp)
00361      bfd *abfd;
00362      PTR inp;
00363      PTR extp;
00364 {
00365   struct internal_syment *in = (struct internal_syment *)inp;
00366   SYMENT *ext =(SYMENT *)extp;
00367 
00368   if (in->_n._n_name[0] != 0)
00369     {
00370       memcpy (ext->e.e_name, in->_n._n_name, SYMNMLEN);
00371     }
00372   else
00373     {
00374       H_PUT_32 (abfd, 0, ext->e.e.e_zeroes);
00375       H_PUT_32 (abfd, in->_n._n_n._n_offset, ext->e.e.e_offset);
00376     }
00377 
00378   H_PUT_32 (abfd, in->n_value, ext->e_value);
00379   H_PUT_16 (abfd, in->n_scnum, ext->e_scnum);
00380   H_PUT_16 (abfd, in->n_type, ext->e_type);
00381   H_PUT_8 (abfd, in->n_sclass, ext->e_sclass);
00382   H_PUT_8 (abfd, in->n_numaux, ext->e_numaux);
00383   return bfd_coff_symesz (abfd);
00384 }
00385 
00386 void
00387 _bfd_xcoff_swap_aux_in (abfd, ext1, type, class, indx, numaux, in1)
00388      bfd *abfd;
00389      PTR ext1;
00390      int type;
00391      int class;
00392      int indx;
00393      int numaux;
00394      PTR in1;
00395 {
00396   AUXENT * ext = (AUXENT *)ext1;
00397   union internal_auxent *in = (union internal_auxent *)in1;
00398 
00399   switch (class)
00400     {
00401     case C_FILE:
00402       if (ext->x_file.x_fname[0] == 0)
00403        {
00404          in->x_file.x_n.x_zeroes = 0;
00405          in->x_file.x_n.x_offset =
00406            H_GET_32 (abfd, ext->x_file.x_n.x_offset);
00407        }
00408       else
00409        {
00410          if (numaux > 1)
00411            {
00412              if (indx == 0)
00413               memcpy (in->x_file.x_fname, ext->x_file.x_fname,
00414                      numaux * sizeof (AUXENT));
00415            }
00416          else
00417            {
00418              memcpy (in->x_file.x_fname, ext->x_file.x_fname, FILNMLEN);
00419            }
00420        }
00421       goto end;
00422 
00423       /* RS/6000 "csect" auxents */
00424     case C_EXT:
00425     case C_HIDEXT:
00426       if (indx + 1 == numaux)
00427        {
00428          in->x_csect.x_scnlen.l = H_GET_32 (abfd, ext->x_csect.x_scnlen);
00429          in->x_csect.x_parmhash = H_GET_32 (abfd, ext->x_csect.x_parmhash);
00430          in->x_csect.x_snhash   = H_GET_16 (abfd, ext->x_csect.x_snhash);
00431          /* We don't have to hack bitfields in x_smtyp because it's
00432             defined by shifts-and-ands, which are equivalent on all
00433             byte orders.  */
00434          in->x_csect.x_smtyp    = H_GET_8 (abfd, ext->x_csect.x_smtyp);
00435          in->x_csect.x_smclas   = H_GET_8 (abfd, ext->x_csect.x_smclas);
00436          in->x_csect.x_stab     = H_GET_32 (abfd, ext->x_csect.x_stab);
00437          in->x_csect.x_snstab   = H_GET_16 (abfd, ext->x_csect.x_snstab);
00438          goto end;
00439        }
00440       break;
00441 
00442     case C_STAT:
00443     case C_LEAFSTAT:
00444     case C_HIDDEN:
00445       if (type == T_NULL)
00446        {
00447          in->x_scn.x_scnlen = H_GET_32 (abfd, ext->x_scn.x_scnlen);
00448          in->x_scn.x_nreloc = H_GET_16 (abfd, ext->x_scn.x_nreloc);
00449          in->x_scn.x_nlinno = H_GET_16 (abfd, ext->x_scn.x_nlinno);
00450          /* PE defines some extra fields; we zero them out for
00451             safety.  */
00452          in->x_scn.x_checksum = 0;
00453          in->x_scn.x_associated = 0;
00454          in->x_scn.x_comdat = 0;
00455 
00456          goto end;
00457        }
00458       break;
00459     }
00460 
00461   in->x_sym.x_tagndx.l = H_GET_32 (abfd, ext->x_sym.x_tagndx);
00462   in->x_sym.x_tvndx = H_GET_16 (abfd, ext->x_sym.x_tvndx);
00463 
00464   if (class == C_BLOCK || class == C_FCN || ISFCN (type) || ISTAG (class))
00465     {
00466       in->x_sym.x_fcnary.x_fcn.x_lnnoptr =
00467        H_GET_32 (abfd, ext->x_sym.x_fcnary.x_fcn.x_lnnoptr);
00468       in->x_sym.x_fcnary.x_fcn.x_endndx.l =
00469        H_GET_32 (abfd, ext->x_sym.x_fcnary.x_fcn.x_endndx);
00470     }
00471   else
00472     {
00473       in->x_sym.x_fcnary.x_ary.x_dimen[0] =
00474        H_GET_16 (abfd, ext->x_sym.x_fcnary.x_ary.x_dimen[0]);
00475       in->x_sym.x_fcnary.x_ary.x_dimen[1] =
00476        H_GET_16 (abfd, ext->x_sym.x_fcnary.x_ary.x_dimen[1]);
00477       in->x_sym.x_fcnary.x_ary.x_dimen[2] =
00478        H_GET_16 (abfd, ext->x_sym.x_fcnary.x_ary.x_dimen[2]);
00479       in->x_sym.x_fcnary.x_ary.x_dimen[3] =
00480        H_GET_16 (abfd, ext->x_sym.x_fcnary.x_ary.x_dimen[3]);
00481     }
00482 
00483   if (ISFCN (type))
00484     {
00485       in->x_sym.x_misc.x_fsize = H_GET_32 (abfd, ext->x_sym.x_misc.x_fsize);
00486     }
00487   else
00488     {
00489       in->x_sym.x_misc.x_lnsz.x_lnno =
00490        H_GET_16 (abfd, ext->x_sym.x_misc.x_lnsz.x_lnno);
00491       in->x_sym.x_misc.x_lnsz.x_size =
00492        H_GET_16 (abfd, ext->x_sym.x_misc.x_lnsz.x_size);
00493     }
00494 
00495  end: ;
00496   /* The semicolon is because MSVC doesn't like labels at
00497      end of block.  */
00498 }
00499 
00500 
00501 unsigned int _bfd_xcoff_swap_aux_out
00502   PARAMS ((bfd *, PTR, int, int, int, int, PTR));
00503 
00504 unsigned int
00505 _bfd_xcoff_swap_aux_out (abfd, inp, type, class, indx, numaux, extp)
00506      bfd * abfd;
00507      PTR   inp;
00508      int   type;
00509      int   class;
00510      int   indx ATTRIBUTE_UNUSED;
00511      int   numaux ATTRIBUTE_UNUSED;
00512      PTR   extp;
00513 {
00514   union internal_auxent *in = (union internal_auxent *)inp;
00515   AUXENT *ext = (AUXENT *)extp;
00516 
00517   memset ((PTR)ext, 0, bfd_coff_auxesz (abfd));
00518   switch (class)
00519     {
00520     case C_FILE:
00521       if (in->x_file.x_fname[0] == 0)
00522        {
00523          H_PUT_32 (abfd, 0, ext->x_file.x_n.x_zeroes);
00524          H_PUT_32 (abfd, in->x_file.x_n.x_offset, ext->x_file.x_n.x_offset);
00525        }
00526       else
00527        {
00528          memcpy (ext->x_file.x_fname, in->x_file.x_fname, FILNMLEN);
00529        }
00530       goto end;
00531 
00532       /* RS/6000 "csect" auxents */
00533     case C_EXT:
00534     case C_HIDEXT:
00535       if (indx + 1 == numaux)
00536        {
00537          H_PUT_32 (abfd, in->x_csect.x_scnlen.l, ext->x_csect.x_scnlen);
00538          H_PUT_32 (abfd, in->x_csect.x_parmhash, ext->x_csect.x_parmhash);
00539          H_PUT_16 (abfd, in->x_csect.x_snhash, ext->x_csect.x_snhash);
00540          /* We don't have to hack bitfields in x_smtyp because it's
00541             defined by shifts-and-ands, which are equivalent on all
00542             byte orders.  */
00543          H_PUT_8 (abfd, in->x_csect.x_smtyp, ext->x_csect.x_smtyp);
00544          H_PUT_8 (abfd, in->x_csect.x_smclas, ext->x_csect.x_smclas);
00545          H_PUT_32 (abfd, in->x_csect.x_stab, ext->x_csect.x_stab);
00546          H_PUT_16 (abfd, in->x_csect.x_snstab, ext->x_csect.x_snstab);
00547          goto end;
00548        }
00549       break;
00550 
00551     case C_STAT:
00552     case C_LEAFSTAT:
00553     case C_HIDDEN:
00554       if (type == T_NULL)
00555        {
00556          H_PUT_32 (abfd, in->x_scn.x_scnlen, ext->x_scn.x_scnlen);
00557          H_PUT_16 (abfd, in->x_scn.x_nreloc, ext->x_scn.x_nreloc);
00558          H_PUT_16 (abfd, in->x_scn.x_nlinno, ext->x_scn.x_nlinno);
00559          goto end;
00560        }
00561       break;
00562     }
00563 
00564   H_PUT_32 (abfd, in->x_sym.x_tagndx.l, ext->x_sym.x_tagndx);
00565   H_PUT_16 (abfd, in->x_sym.x_tvndx, ext->x_sym.x_tvndx);
00566 
00567   if (class == C_BLOCK || class == C_FCN || ISFCN (type) || ISTAG (class))
00568     {
00569       H_PUT_32 (abfd, in->x_sym.x_fcnary.x_fcn.x_lnnoptr,
00570               ext->x_sym.x_fcnary.x_fcn.x_lnnoptr);
00571       H_PUT_32 (abfd, in->x_sym.x_fcnary.x_fcn.x_endndx.l,
00572               ext->x_sym.x_fcnary.x_fcn.x_endndx);
00573     }
00574   else
00575     {
00576       H_PUT_16 (abfd, in->x_sym.x_fcnary.x_ary.x_dimen[0],
00577               ext->x_sym.x_fcnary.x_ary.x_dimen[0]);
00578       H_PUT_16 (abfd, in->x_sym.x_fcnary.x_ary.x_dimen[1],
00579               ext->x_sym.x_fcnary.x_ary.x_dimen[1]);
00580       H_PUT_16 (abfd, in->x_sym.x_fcnary.x_ary.x_dimen[2],
00581               ext->x_sym.x_fcnary.x_ary.x_dimen[2]);
00582       H_PUT_16 (abfd, in->x_sym.x_fcnary.x_ary.x_dimen[3],
00583               ext->x_sym.x_fcnary.x_ary.x_dimen[3]);
00584     }
00585 
00586   if (ISFCN (type))
00587     H_PUT_32 (abfd, in->x_sym.x_misc.x_fsize, ext->x_sym.x_misc.x_fsize);
00588   else
00589     {
00590       H_PUT_16 (abfd, in->x_sym.x_misc.x_lnsz.x_lnno,
00591               ext->x_sym.x_misc.x_lnsz.x_lnno);
00592       H_PUT_16 (abfd, in->x_sym.x_misc.x_lnsz.x_size,
00593               ext->x_sym.x_misc.x_lnsz.x_size);
00594     }
00595 
00596 end:
00597   return bfd_coff_auxesz (abfd);
00598 }
00599 
00600 
00601 
00602 /* The XCOFF reloc table.  Actually, XCOFF relocations specify the
00603    bitsize and whether they are signed or not, along with a
00604    conventional type.  This table is for the types, which are used for
00605    different algorithms for putting in the reloc.  Many of these
00606    relocs need special_function entries, which I have not written.  */
00607 
00608 
00609 reloc_howto_type xcoff_howto_table[] =
00610 {
00611   /* Standard 32 bit relocation.  */
00612   HOWTO (R_POS,                    /* type */
00613         0,                  /* rightshift */
00614         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00615         32,                 /* bitsize */
00616         FALSE,                     /* pc_relative */
00617         0,                  /* bitpos */
00618         complain_overflow_bitfield, /* complain_on_overflow */
00619         0,                  /* special_function */
00620         "R_POS",            /* name */
00621         TRUE,               /* partial_inplace */
00622         0xffffffff,         /* src_mask */
00623         0xffffffff,         /* dst_mask */
00624         FALSE),             /* pcrel_offset */
00625 
00626   /* 32 bit relocation, but store negative value.  */
00627   HOWTO (R_NEG,                    /* type */
00628         0,                  /* rightshift */
00629         -2,                 /* size (0 = byte, 1 = short, 2 = long) */
00630         32,                 /* bitsize */
00631         FALSE,                     /* pc_relative */
00632         0,                  /* bitpos */
00633         complain_overflow_bitfield, /* complain_on_overflow */
00634         0,                  /* special_function */
00635         "R_NEG",            /* name */
00636         TRUE,               /* partial_inplace */
00637         0xffffffff,         /* src_mask */
00638         0xffffffff,         /* dst_mask */
00639         FALSE),             /* pcrel_offset */
00640 
00641   /* 32 bit PC relative relocation.  */
00642   HOWTO (R_REL,                    /* type */
00643         0,                  /* rightshift */
00644         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00645         32,                 /* bitsize */
00646         TRUE,               /* pc_relative */
00647         0,                  /* bitpos */
00648         complain_overflow_signed, /* complain_on_overflow */
00649         0,                  /* special_function */
00650         "R_REL",            /* name */
00651         TRUE,               /* partial_inplace */
00652         0xffffffff,         /* src_mask */
00653         0xffffffff,         /* dst_mask */
00654         FALSE),             /* pcrel_offset */
00655 
00656   /* 16 bit TOC relative relocation.  */
00657   HOWTO (R_TOC,                    /* type */
00658         0,                  /* rightshift */
00659         1,                  /* size (0 = byte, 1 = short, 2 = long) */
00660         16,                 /* bitsize */
00661         FALSE,                     /* pc_relative */
00662         0,                  /* bitpos */
00663         complain_overflow_bitfield, /* complain_on_overflow */
00664         0,                  /* special_function */
00665         "R_TOC",            /* name */
00666         TRUE,               /* partial_inplace */
00667         0xffff,             /* src_mask */
00668         0xffff,             /* dst_mask */
00669         FALSE),             /* pcrel_offset */
00670 
00671   /* I don't really know what this is.  */
00672   HOWTO (R_RTB,                    /* type */
00673         1,                  /* rightshift */
00674         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00675         32,                 /* bitsize */
00676         FALSE,                     /* pc_relative */
00677         0,                  /* bitpos */
00678         complain_overflow_bitfield, /* complain_on_overflow */
00679         0,                  /* special_function */
00680         "R_RTB",            /* name */
00681         TRUE,               /* partial_inplace */
00682         0xffffffff,         /* src_mask */
00683         0xffffffff,         /* dst_mask */
00684         FALSE),             /* pcrel_offset */
00685 
00686   /* External TOC relative symbol.  */
00687   HOWTO (R_GL,                     /* type */
00688         0,                  /* rightshift */
00689         1,                  /* size (0 = byte, 1 = short, 2 = long) */
00690         16,                 /* bitsize */
00691         FALSE,                     /* pc_relative */
00692         0,                  /* bitpos */
00693         complain_overflow_bitfield, /* complain_on_overflow */
00694         0,                  /* special_function */
00695         "R_GL",             /* name */
00696         TRUE,               /* partial_inplace */
00697         0xffff,             /* src_mask */
00698         0xffff,             /* dst_mask */
00699         FALSE),             /* pcrel_offset */
00700 
00701   /* Local TOC relative symbol.     */
00702   HOWTO (R_TCL,                    /* type */
00703         0,                  /* rightshift */
00704         1,                  /* size (0 = byte, 1 = short, 2 = long) */
00705         16,                 /* bitsize */
00706         FALSE,                     /* pc_relative */
00707         0,                  /* bitpos */
00708         complain_overflow_bitfield, /* complain_on_overflow */
00709         0,                  /* special_function */
00710         "R_TCL",            /* name */
00711         TRUE,               /* partial_inplace */
00712         0xffff,             /* src_mask */
00713         0xffff,             /* dst_mask */
00714         FALSE),             /* pcrel_offset */
00715 
00716   EMPTY_HOWTO (7),
00717 
00718   /* Non modifiable absolute branch.  */
00719   HOWTO (R_BA,                     /* type */
00720         0,                  /* rightshift */
00721         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00722         26,                 /* bitsize */
00723         FALSE,                     /* pc_relative */
00724         0,                  /* bitpos */
00725         complain_overflow_bitfield, /* complain_on_overflow */
00726         0,                  /* special_function */
00727         "R_BA_26",          /* name */
00728         TRUE,               /* partial_inplace */
00729         0x03fffffc,         /* src_mask */
00730         0x03fffffc,         /* dst_mask */
00731         FALSE),             /* pcrel_offset */
00732 
00733   EMPTY_HOWTO (9),
00734 
00735   /* Non modifiable relative branch.  */
00736   HOWTO (R_BR,                     /* type */
00737         0,                  /* rightshift */
00738         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00739         26,                 /* bitsize */
00740         TRUE,               /* pc_relative */
00741         0,                  /* bitpos */
00742         complain_overflow_signed, /* complain_on_overflow */
00743         0,                  /* special_function */
00744         "R_BR",             /* name */
00745         TRUE,               /* partial_inplace */
00746         0x03fffffc,         /* src_mask */
00747         0x03fffffc,         /* dst_mask */
00748         FALSE),             /* pcrel_offset */
00749 
00750   EMPTY_HOWTO (0xb),
00751 
00752   /* Indirect load.  */
00753   HOWTO (R_RL,                     /* type */
00754         0,                  /* rightshift */
00755         1,                  /* size (0 = byte, 1 = short, 2 = long) */
00756         16,                 /* bitsize */
00757         FALSE,                     /* pc_relative */
00758         0,                  /* bitpos */
00759         complain_overflow_bitfield, /* complain_on_overflow */
00760         0,                  /* special_function */
00761         "R_RL",             /* name */
00762         TRUE,               /* partial_inplace */
00763         0xffff,             /* src_mask */
00764         0xffff,             /* dst_mask */
00765         FALSE),             /* pcrel_offset */
00766 
00767   /* Load address.  */
00768   HOWTO (R_RLA,                    /* type */
00769         0,                  /* rightshift */
00770         1,                  /* size (0 = byte, 1 = short, 2 = long) */
00771         16,                 /* bitsize */
00772         FALSE,                     /* pc_relative */
00773         0,                  /* bitpos */
00774         complain_overflow_bitfield, /* complain_on_overflow */
00775         0,                  /* special_function */
00776         "R_RLA",            /* name */
00777         TRUE,               /* partial_inplace */
00778         0xffff,             /* src_mask */
00779         0xffff,             /* dst_mask */
00780         FALSE),             /* pcrel_offset */
00781 
00782   EMPTY_HOWTO (0xe),
00783 
00784   /* Non-relocating reference.  */
00785   HOWTO (R_REF,                    /* type */
00786         0,                  /* rightshift */
00787         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00788         32,                 /* bitsize */
00789         FALSE,                     /* pc_relative */
00790         0,                  /* bitpos */
00791         complain_overflow_dont, /* complain_on_overflow */
00792         0,                  /* special_function */
00793         "R_REF",            /* name */
00794         FALSE,                     /* partial_inplace */
00795         0,                  /* src_mask */
00796         0,                  /* dst_mask */
00797         FALSE),             /* pcrel_offset */
00798 
00799   EMPTY_HOWTO (0x10),
00800   EMPTY_HOWTO (0x11),
00801 
00802   /* TOC relative indirect load.  */
00803   HOWTO (R_TRL,                    /* type */
00804         0,                  /* rightshift */
00805         1,                  /* size (0 = byte, 1 = short, 2 = long) */
00806         16,                 /* bitsize */
00807         FALSE,                     /* pc_relative */
00808         0,                  /* bitpos */
00809         complain_overflow_bitfield, /* complain_on_overflow */
00810         0,                  /* special_function */
00811         "R_TRL",            /* name */
00812         TRUE,               /* partial_inplace */
00813         0xffff,             /* src_mask */
00814         0xffff,             /* dst_mask */
00815         FALSE),             /* pcrel_offset */
00816 
00817   /* TOC relative load address.  */
00818   HOWTO (R_TRLA,            /* type */
00819         0,                  /* rightshift */
00820         1,                  /* size (0 = byte, 1 = short, 2 = long) */
00821         16,                 /* bitsize */
00822         FALSE,                     /* pc_relative */
00823         0,                  /* bitpos */
00824         complain_overflow_bitfield, /* complain_on_overflow */
00825         0,                  /* special_function */
00826         "R_TRLA",           /* name */
00827         TRUE,               /* partial_inplace */
00828         0xffff,             /* src_mask */
00829         0xffff,             /* dst_mask */
00830         FALSE),             /* pcrel_offset */
00831 
00832   /* Modifiable relative branch.  */
00833   HOWTO (R_RRTBI,            /* type */
00834         1,                  /* rightshift */
00835         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00836         32,                 /* bitsize */
00837         FALSE,                     /* pc_relative */
00838         0,                  /* bitpos */
00839         complain_overflow_bitfield, /* complain_on_overflow */
00840         0,                  /* special_function */
00841         "R_RRTBI",          /* name */
00842         TRUE,               /* partial_inplace */
00843         0xffffffff,         /* src_mask */
00844         0xffffffff,         /* dst_mask */
00845         FALSE),             /* pcrel_offset */
00846 
00847   /* Modifiable absolute branch.  */
00848   HOWTO (R_RRTBA,            /* type */
00849         1,                  /* rightshift */
00850         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00851         32,                 /* bitsize */
00852         FALSE,                     /* pc_relative */
00853         0,                  /* bitpos */
00854         complain_overflow_bitfield, /* complain_on_overflow */
00855         0,                  /* special_function */
00856         "R_RRTBA",          /* name */
00857         TRUE,               /* partial_inplace */
00858         0xffffffff,         /* src_mask */
00859         0xffffffff,         /* dst_mask */
00860         FALSE),             /* pcrel_offset */
00861 
00862   /* Modifiable call absolute indirect.  */
00863   HOWTO (R_CAI,                    /* type */
00864         0,                  /* rightshift */
00865         1,                  /* size (0 = byte, 1 = short, 2 = long) */
00866         16,                 /* bitsize */
00867         FALSE,                     /* pc_relative */
00868         0,                  /* bitpos */
00869         complain_overflow_bitfield, /* complain_on_overflow */
00870         0,                  /* special_function */
00871         "R_CAI",            /* name */
00872         TRUE,               /* partial_inplace */
00873         0xffff,             /* src_mask */
00874         0xffff,             /* dst_mask */
00875         FALSE),             /* pcrel_offset */
00876 
00877   /* Modifiable call relative.  */
00878   HOWTO (R_CREL,            /* type */
00879         0,                  /* rightshift */
00880         1,                  /* size (0 = byte, 1 = short, 2 = long) */
00881         16,                 /* bitsize */
00882         FALSE,                     /* pc_relative */
00883         0,                  /* bitpos */
00884         complain_overflow_bitfield, /* complain_on_overflow */
00885         0,                  /* special_function */
00886         "R_CREL",           /* name */
00887         TRUE,               /* partial_inplace */
00888         0xffff,             /* src_mask */
00889         0xffff,             /* dst_mask */
00890         FALSE),             /* pcrel_offset */
00891 
00892   /* Modifiable branch absolute.  */
00893   HOWTO (R_RBA,                    /* type */
00894         0,                  /* rightshift */
00895         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00896         26,                 /* bitsize */
00897         FALSE,                     /* pc_relative */
00898         0,                  /* bitpos */
00899         complain_overflow_bitfield, /* complain_on_overflow */
00900         0,                  /* special_function */
00901         "R_RBA",            /* name */
00902         TRUE,               /* partial_inplace */
00903         0x03fffffc,         /* src_mask */
00904         0x03fffffc,         /* dst_mask */
00905         FALSE),             /* pcrel_offset */
00906 
00907   /* Modifiable branch absolute.  */
00908   HOWTO (R_RBAC,            /* type */
00909         0,                  /* rightshift */
00910         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00911         32,                 /* bitsize */
00912         FALSE,                     /* pc_relative */
00913         0,                  /* bitpos */
00914         complain_overflow_bitfield, /* complain_on_overflow */
00915         0,                  /* special_function */
00916         "R_RBAC",           /* name */
00917         TRUE,               /* partial_inplace */
00918         0xffffffff,         /* src_mask */
00919         0xffffffff,         /* dst_mask */
00920         FALSE),             /* pcrel_offset */
00921 
00922   /* Modifiable branch relative.  */
00923   HOWTO (R_RBR,                    /* type */
00924         0,                  /* rightshift */
00925         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00926         26,                 /* bitsize */
00927         FALSE,                     /* pc_relative */
00928         0,                  /* bitpos */
00929         complain_overflow_signed, /* complain_on_overflow */
00930         0,                  /* special_function */
00931         "R_RBR_26",         /* name */
00932         TRUE,               /* partial_inplace */
00933         0x03fffffc,         /* src_mask */
00934         0x03fffffc,         /* dst_mask */
00935         FALSE),             /* pcrel_offset */
00936 
00937   /* Modifiable branch absolute.  */
00938   HOWTO (R_RBRC,            /* type */
00939         0,                  /* rightshift */
00940         1,                  /* size (0 = byte, 1 = short, 2 = long) */
00941         16,                 /* bitsize */
00942         FALSE,                     /* pc_relative */
00943         0,                  /* bitpos */
00944         complain_overflow_bitfield, /* complain_on_overflow */
00945         0,                  /* special_function */
00946         "R_RBRC",           /* name */
00947         TRUE,               /* partial_inplace */
00948         0xffff,             /* src_mask */
00949         0xffff,             /* dst_mask */
00950         FALSE),             /* pcrel_offset */
00951 
00952   /* 16 bit Non modifiable absolute branch.  */
00953   HOWTO (R_BA,                     /* type */
00954         0,                  /* rightshift */
00955         1,                  /* size (0 = byte, 1 = short, 2 = long) */
00956         16,                 /* bitsize */
00957         FALSE,                     /* pc_relative */
00958         0,                  /* bitpos */
00959         complain_overflow_bitfield, /* complain_on_overflow */
00960         0,                  /* special_function */
00961         "R_BA_16",          /* name */
00962         TRUE,               /* partial_inplace */
00963         0xfffc,             /* src_mask */
00964         0xfffc,             /* dst_mask */
00965         FALSE),             /* pcrel_offset */
00966 
00967   /* Modifiable branch relative.  */
00968   HOWTO (R_RBR,                    /* type */
00969         0,                  /* rightshift */
00970         1,                  /* size (0 = byte, 1 = short, 2 = long) */
00971         16,                 /* bitsize */
00972         FALSE,                     /* pc_relative */
00973         0,                  /* bitpos */
00974         complain_overflow_signed, /* complain_on_overflow */
00975         0,                  /* special_function */
00976         "R_RBR_16",         /* name */
00977         TRUE,               /* partial_inplace */
00978         0xffff,             /* src_mask */
00979         0xffff,             /* dst_mask */
00980         FALSE),             /* pcrel_offset */
00981 
00982   /* Modifiable branch relative.  */
00983   HOWTO (R_RBA,                    /* type */
00984         0,                  /* rightshift */
00985         1,                  /* size (0 = byte, 1 = short, 2 = long) */
00986         16,                 /* bitsize */
00987         FALSE,                     /* pc_relative */
00988         0,                  /* bitpos */
00989         complain_overflow_signed, /* complain_on_overflow */
00990         0,                  /* special_function */
00991         "R_RBA_16",         /* name */
00992         TRUE,               /* partial_inplace */
00993         0xffff,             /* src_mask */
00994         0xffff,             /* dst_mask */
00995         FALSE),             /* pcrel_offset */
00996 
00997 };
00998 
00999 void
01000 xcoff_rtype2howto (relent, internal)
01001      arelent *relent;
01002      struct internal_reloc *internal;
01003 {
01004   if (internal->r_type > R_RBRC)
01005     abort ();
01006 
01007   /* Default howto layout works most of the time */
01008   relent->howto = &xcoff_howto_table[internal->r_type];
01009 
01010   /* Special case some 16 bit reloc */
01011   if (15 == (internal->r_size & 0x1f))
01012     {
01013       if (R_BA == internal->r_type)
01014        relent->howto = &xcoff_howto_table[0x1c];
01015       else if (R_RBR == internal->r_type)
01016        relent->howto = &xcoff_howto_table[0x1d];
01017       else if (R_RBA == internal->r_type)
01018        relent->howto = &xcoff_howto_table[0x1e];
01019     }
01020 
01021   /* The r_size field of an XCOFF reloc encodes the bitsize of the
01022      relocation, as well as indicating whether it is signed or not.
01023      Doublecheck that the relocation information gathered from the
01024      type matches this information.  The bitsize is not significant
01025      for R_REF relocs.  */
01026   if (relent->howto->dst_mask != 0
01027       && (relent->howto->bitsize
01028          != ((unsigned int) internal->r_size & 0x1f) + 1))
01029     abort ();
01030 }
01031 
01032 reloc_howto_type *
01033 _bfd_xcoff_reloc_type_lookup (abfd, code)
01034      bfd *abfd ATTRIBUTE_UNUSED;
01035      bfd_reloc_code_real_type code;
01036 {
01037   switch (code)
01038     {
01039     case BFD_RELOC_PPC_B26:
01040       return &xcoff_howto_table[0xa];
01041     case BFD_RELOC_PPC_BA16:
01042       return &xcoff_howto_table[0x1c];
01043     case BFD_RELOC_PPC_BA26:
01044       return &xcoff_howto_table[8];
01045     case BFD_RELOC_PPC_TOC16:
01046       return &xcoff_howto_table[3];
01047     case BFD_RELOC_32:
01048     case BFD_RELOC_CTOR:
01049       return &xcoff_howto_table[0];
01050     default:
01051       return NULL;
01052     }
01053 }
01054 
01055 static reloc_howto_type *
01056 _bfd_xcoff_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
01057                            const char *r_name)
01058 {
01059   unsigned int i;
01060 
01061   for (i = 0;
01062        i < sizeof (xcoff_howto_table) / sizeof (xcoff_howto_table[0]);
01063        i++)
01064     if (xcoff_howto_table[i].name != NULL
01065        && strcasecmp (xcoff_howto_table[i].name, r_name) == 0)
01066       return &xcoff_howto_table[i];
01067 
01068   return NULL;
01069 }
01070 
01071 /* XCOFF archive support.  The original version of this code was by
01072    Damon A. Permezel.  It was enhanced to permit cross support, and
01073    writing archive files, by Ian Lance Taylor, Cygnus Support.
01074 
01075    XCOFF uses its own archive format.  Everything is hooked together
01076    with file offset links, so it is possible to rapidly update an
01077    archive in place.  Of course, we don't do that.  An XCOFF archive
01078    has a real file header, not just an ARMAG string.  The structure of
01079    the file header and of each archive header appear below.
01080 
01081    An XCOFF archive also has a member table, which is a list of
01082    elements in the archive (you can get that by looking through the
01083    linked list, but you have to read a lot more of the file).  The
01084    member table has a normal archive header with an empty name.  It is
01085    normally (and perhaps must be) the second to last entry in the
01086    archive.  The member table data is almost printable ASCII.  It
01087    starts with a 12 character decimal string which is the number of
01088    entries in the table.  For each entry it has a 12 character decimal
01089    string which is the offset in the archive of that member.  These
01090    entries are followed by a series of null terminated strings which
01091    are the member names for each entry.
01092 
01093    Finally, an XCOFF archive has a global symbol table, which is what
01094    we call the armap.  The global symbol table has a normal archive
01095    header with an empty name.  It is normally (and perhaps must be)
01096    the last entry in the archive.  The contents start with a four byte
01097    binary number which is the number of entries.  This is followed by
01098    a that many four byte binary numbers; each is the file offset of an
01099    entry in the archive.  These numbers are followed by a series of
01100    null terminated strings, which are symbol names.
01101 
01102    AIX 4.3 introduced a new archive format which can handle larger
01103    files and also 32- and 64-bit objects in the same archive.  The
01104    things said above remain true except that there is now more than
01105    one global symbol table.  The one is used to index 32-bit objects,
01106    the other for 64-bit objects.
01107 
01108    The new archives (recognizable by the new ARMAG string) has larger
01109    field lengths so that we cannot really share any code.  Also we have
01110    to take care that we are not generating the new form of archives
01111    on AIX 4.2 or earlier systems.  */
01112 
01113 /* XCOFF archives use this as a magic string.  Note that both strings
01114    have the same length.  */
01115 
01116 /* Set the magic for archive.  */
01117 
01118 bfd_boolean
01119 bfd_xcoff_ar_archive_set_magic (abfd, magic)
01120      bfd *abfd ATTRIBUTE_UNUSED;
01121      char *magic ATTRIBUTE_UNUSED;
01122 {
01123   /* Not supported yet.  */
01124   return FALSE;
01125  /* bfd_xcoff_archive_set_magic (abfd, magic); */
01126 }
01127 
01128 /* Read in the armap of an XCOFF archive.  */
01129 
01130 bfd_boolean
01131 _bfd_xcoff_slurp_armap (abfd)
01132      bfd *abfd;
01133 {
01134   file_ptr off;
01135   size_t namlen;
01136   bfd_size_type sz;
01137   bfd_byte *contents, *cend;
01138   bfd_vma c, i;
01139   carsym *arsym;
01140   bfd_byte *p;
01141 
01142   if (xcoff_ardata (abfd) == NULL)
01143     {
01144       bfd_has_map (abfd) = FALSE;
01145       return TRUE;
01146     }
01147 
01148   if (! xcoff_big_format_p (abfd))
01149     {
01150       /* This is for the old format.  */
01151       struct xcoff_ar_hdr hdr;
01152 
01153       off = strtol (xcoff_ardata (abfd)->symoff, (char **) NULL, 10);
01154       if (off == 0)
01155        {
01156          bfd_has_map (abfd) = FALSE;
01157          return TRUE;
01158        }
01159 
01160       if (bfd_seek (abfd, off, SEEK_SET) != 0)
01161        return FALSE;
01162 
01163       /* The symbol table starts with a normal archive header.  */
01164       if (bfd_bread ((PTR) &hdr, (bfd_size_type) SIZEOF_AR_HDR, abfd)
01165          != SIZEOF_AR_HDR)
01166        return FALSE;
01167 
01168       /* Skip the name (normally empty).  */
01169       namlen = strtol (hdr.namlen, (char **) NULL, 10);
01170       off = ((namlen + 1) & ~ (size_t) 1) + SXCOFFARFMAG;
01171       if (bfd_seek (abfd, off, SEEK_CUR) != 0)
01172        return FALSE;
01173 
01174       sz = strtol (hdr.size, (char **) NULL, 10);
01175 
01176       /* Read in the entire symbol table.  */
01177       contents = (bfd_byte *) bfd_alloc (abfd, sz);
01178       if (contents == NULL)
01179        return FALSE;
01180       if (bfd_bread ((PTR) contents, sz, abfd) != sz)
01181        return FALSE;
01182 
01183       /* The symbol table starts with a four byte count.  */
01184       c = H_GET_32 (abfd, contents);
01185 
01186       if (c * 4 >= sz)
01187        {
01188          bfd_set_error (bfd_error_bad_value);
01189          return FALSE;
01190        }
01191 
01192       bfd_ardata (abfd)->symdefs =
01193        ((carsym *) bfd_alloc (abfd, c * sizeof (carsym)));
01194       if (bfd_ardata (abfd)->symdefs == NULL)
01195        return FALSE;
01196 
01197       /* After the count comes a list of four byte file offsets.  */
01198       for (i = 0, arsym = bfd_ardata (abfd)->symdefs, p = contents + 4;
01199           i < c;
01200           ++i, ++arsym, p += 4)
01201        arsym->file_offset = H_GET_32 (abfd, p);
01202     }
01203   else
01204     {
01205       /* This is for the new format.  */
01206       struct xcoff_ar_hdr_big hdr;
01207 
01208       off = strtol (xcoff_ardata_big (abfd)->symoff, (char **) NULL, 10);
01209       if (off == 0)
01210        {
01211          bfd_has_map (abfd) = FALSE;
01212          return TRUE;
01213        }
01214 
01215       if (bfd_seek (abfd, off, SEEK_SET) != 0)
01216        return FALSE;
01217 
01218       /* The symbol table starts with a normal archive header.  */
01219       if (bfd_bread ((PTR) &hdr, (bfd_size_type) SIZEOF_AR_HDR_BIG, abfd)
01220          != SIZEOF_AR_HDR_BIG)
01221        return FALSE;
01222 
01223       /* Skip the name (normally empty).  */
01224       namlen = strtol (hdr.namlen, (char **) NULL, 10);
01225       off = ((namlen + 1) & ~ (size_t) 1) + SXCOFFARFMAG;
01226       if (bfd_seek (abfd, off, SEEK_CUR) != 0)
01227        return FALSE;
01228 
01229       /* XXX This actually has to be a call to strtoll (at least on 32-bit
01230         machines) since the field width is 20 and there numbers with more
01231         than 32 bits can be represented.  */
01232       sz = strtol (hdr.size, (char **) NULL, 10);
01233 
01234       /* Read in the entire symbol table.  */
01235       contents = (bfd_byte *) bfd_alloc (abfd, sz);
01236       if (contents == NULL)
01237        return FALSE;
01238       if (bfd_bread ((PTR) contents, sz, abfd) != sz)
01239        return FALSE;
01240 
01241       /* The symbol table starts with an eight byte count.  */
01242       c = H_GET_64 (abfd, contents);
01243 
01244       if (c * 8 >= sz)
01245        {
01246          bfd_set_error (bfd_error_bad_value);
01247          return FALSE;
01248        }
01249 
01250       bfd_ardata (abfd)->symdefs =
01251        ((carsym *) bfd_alloc (abfd, c * sizeof (carsym)));
01252       if (bfd_ardata (abfd)->symdefs == NULL)
01253        return FALSE;
01254 
01255       /* After the count comes a list of eight byte file offsets.  */
01256       for (i = 0, arsym = bfd_ardata (abfd)->symdefs, p = contents + 8;
01257           i < c;
01258           ++i, ++arsym, p += 8)
01259        arsym->file_offset = H_GET_64 (abfd, p);
01260     }
01261 
01262   /* After the file offsets come null terminated symbol names.  */
01263   cend = contents + sz;
01264   for (i = 0, arsym = bfd_ardata (abfd)->symdefs;
01265        i < c;
01266        ++i, ++arsym, p += strlen ((char *) p) + 1)
01267     {
01268       if (p >= cend)
01269        {
01270          bfd_set_error (bfd_error_bad_value);
01271          return FALSE;
01272        }
01273       arsym->name = (char *) p;
01274     }
01275 
01276   bfd_ardata (abfd)->symdef_count = c;
01277   bfd_has_map (abfd) = TRUE;
01278 
01279   return TRUE;
01280 }
01281 
01282 /* See if this is an XCOFF archive.  */
01283 
01284 const bfd_target *
01285 _bfd_xcoff_archive_p (abfd)
01286      bfd *abfd;
01287 {
01288   struct artdata *tdata_hold;
01289   char magic[SXCOFFARMAG];
01290   bfd_size_type amt = SXCOFFARMAG;
01291 
01292   if (bfd_bread ((PTR) magic, amt, abfd) != amt)
01293     {
01294       if (bfd_get_error () != bfd_error_system_call)
01295        bfd_set_error (bfd_error_wrong_format);
01296       return NULL;
01297     }
01298 
01299   if (strncmp (magic, XCOFFARMAG, SXCOFFARMAG) != 0
01300       && strncmp (magic, XCOFFARMAGBIG, SXCOFFARMAG) != 0)
01301     {
01302       bfd_set_error (bfd_error_wrong_format);
01303       return NULL;
01304     }
01305 
01306   tdata_hold = bfd_ardata (abfd);
01307 
01308   amt = sizeof (struct artdata);
01309   bfd_ardata (abfd) = (struct artdata *) bfd_zalloc (abfd, amt);
01310   if (bfd_ardata (abfd) == (struct artdata *) NULL)
01311     goto error_ret_restore;
01312 
01313   /* Cleared by bfd_zalloc above.
01314      bfd_ardata (abfd)->cache = NULL;
01315      bfd_ardata (abfd)->archive_head = NULL;
01316      bfd_ardata (abfd)->symdefs = NULL;
01317      bfd_ardata (abfd)->extended_names = NULL;
01318      bfd_ardata (abfd)->extended_names_size = 0;  */
01319 
01320   /* Now handle the two formats.  */
01321   if (magic[1] != 'b')
01322     {
01323       /* This is the old format.  */
01324       struct xcoff_ar_file_hdr hdr;
01325 
01326       /* Copy over the magic string.  */
01327       memcpy (hdr.magic, magic, SXCOFFARMAG);
01328 
01329       /* Now read the rest of the file header.  */
01330       amt = SIZEOF_AR_FILE_HDR - SXCOFFARMAG;
01331       if (bfd_bread ((PTR) &hdr.memoff, amt, abfd) != amt)
01332        {
01333          if (bfd_get_error () != bfd_error_system_call)
01334            bfd_set_error (bfd_error_wrong_format);
01335          goto error_ret;
01336        }
01337 
01338       bfd_ardata (abfd)->first_file_filepos = strtol (hdr.firstmemoff,
01339                                                 (char **) NULL, 10);
01340 
01341       amt = SIZEOF_AR_FILE_HDR;
01342       bfd_ardata (abfd)->tdata = bfd_zalloc (abfd, amt);
01343       if (bfd_ardata (abfd)->tdata == NULL)
01344        goto error_ret;
01345 
01346       memcpy (bfd_ardata (abfd)->tdata, &hdr, SIZEOF_AR_FILE_HDR);
01347     }
01348   else
01349     {
01350       /* This is the new format.  */
01351       struct xcoff_ar_file_hdr_big hdr;
01352 
01353       /* Copy over the magic string.  */
01354       memcpy (hdr.magic, magic, SXCOFFARMAG);
01355 
01356       /* Now read the rest of the file header.  */
01357       amt = SIZEOF_AR_FILE_HDR_BIG - SXCOFFARMAG;
01358       if (bfd_bread ((PTR) &hdr.memoff, amt, abfd) != amt)
01359        {
01360          if (bfd_get_error () != bfd_error_system_call)
01361            bfd_set_error (bfd_error_wrong_format);
01362          goto error_ret;
01363        }
01364 
01365       bfd_ardata (abfd)->first_file_filepos = bfd_scan_vma (hdr.firstmemoff,
01366                                                      (const char **) 0,
01367                                                      10);
01368 
01369       amt = SIZEOF_AR_FILE_HDR_BIG;
01370       bfd_ardata (abfd)->tdata = bfd_zalloc (abfd, amt);
01371       if (bfd_ardata (abfd)->tdata == NULL)
01372        goto error_ret;
01373 
01374       memcpy (bfd_ardata (abfd)->tdata, &hdr, SIZEOF_AR_FILE_HDR_BIG);
01375     }
01376 
01377   if (! _bfd_xcoff_slurp_armap (abfd))
01378     {
01379     error_ret:
01380       bfd_release (abfd, bfd_ardata (abfd));
01381     error_ret_restore:
01382       bfd_ardata (abfd) = tdata_hold;
01383       return NULL;
01384     }
01385 
01386   return abfd->xvec;
01387 }
01388 
01389 /* Read the archive header in an XCOFF archive.  */
01390 
01391 PTR
01392 _bfd_xcoff_read_ar_hdr (abfd)
01393      bfd *abfd;
01394 {
01395   bfd_size_type namlen;
01396   struct areltdata *ret;
01397   bfd_size_type amt = sizeof (struct areltdata);
01398 
01399   ret = (struct areltdata *) bfd_alloc (abfd, amt);
01400   if (ret == NULL)
01401     return NULL;
01402 
01403   if (! xcoff_big_format_p (abfd))
01404     {
01405       struct xcoff_ar_hdr hdr;
01406       struct xcoff_ar_hdr *hdrp;
01407 
01408       if (bfd_bread ((PTR) &hdr, (bfd_size_type) SIZEOF_AR_HDR, abfd)
01409          != SIZEOF_AR_HDR)
01410        {
01411          free (ret);
01412          return NULL;
01413        }
01414 
01415       namlen = strtol (hdr.namlen, (char **) NULL, 10);
01416       amt = SIZEOF_AR_HDR + namlen + 1;
01417       hdrp = (struct xcoff_ar_hdr *) bfd_alloc (abfd, amt);
01418       if (hdrp == NULL)
01419        {
01420          free (ret);
01421          return NULL;
01422        }
01423       memcpy (hdrp, &hdr, SIZEOF_AR_HDR);
01424       if (bfd_bread ((char *) hdrp + SIZEOF_AR_HDR, namlen, abfd) != namlen)
01425        {
01426          free (ret);
01427          return NULL;
01428        }
01429       ((char *) hdrp)[SIZEOF_AR_HDR + namlen] = '\0';
01430 
01431       ret->arch_header = (char *) hdrp;
01432       ret->parsed_size = strtol (hdr.size, (char **) NULL, 10);
01433       ret->filename = (char *) hdrp + SIZEOF_AR_HDR;
01434     }
01435   else
01436     {
01437       struct xcoff_ar_hdr_big hdr;
01438       struct xcoff_ar_hdr_big *hdrp;
01439 
01440       if (bfd_bread ((PTR) &hdr, (bfd_size_type) SIZEOF_AR_HDR_BIG, abfd)
01441          != SIZEOF_AR_HDR_BIG)
01442        {
01443          free (ret);
01444          return NULL;
01445        }
01446 
01447       namlen = strtol (hdr.namlen, (char **) NULL, 10);
01448       amt = SIZEOF_AR_HDR_BIG + namlen + 1;
01449       hdrp = (struct xcoff_ar_hdr_big *) bfd_alloc (abfd, amt);
01450       if (hdrp == NULL)
01451        {
01452          free (ret);
01453          return NULL;
01454        }
01455       memcpy (hdrp, &hdr, SIZEOF_AR_HDR_BIG);
01456       if (bfd_bread ((char *) hdrp + SIZEOF_AR_HDR_BIG, namlen, abfd) != namlen)
01457        {
01458          free (ret);
01459          return NULL;
01460        }
01461       ((char *) hdrp)[SIZEOF_AR_HDR_BIG + namlen] = '\0';
01462 
01463       ret->arch_header = (char *) hdrp;
01464       /* XXX This actually has to be a call to strtoll (at least on 32-bit
01465         machines) since the field width is 20 and there numbers with more
01466         than 32 bits can be represented.  */
01467       ret->parsed_size = strtol (hdr.size, (char **) NULL, 10);
01468       ret->filename = (char *) hdrp + SIZEOF_AR_HDR_BIG;
01469     }
01470 
01471   /* Skip over the XCOFFARFMAG at the end of the file name.  */
01472   if (bfd_seek (abfd, (file_ptr) ((namlen & 1) + SXCOFFARFMAG), SEEK_CUR) != 0)
01473     return NULL;
01474 
01475   return (PTR) ret;
01476 }
01477 
01478 /* Open the next element in an XCOFF archive.  */
01479 
01480 bfd *
01481 _bfd_xcoff_openr_next_archived_file (archive, last_file)
01482      bfd *archive;
01483      bfd *last_file;
01484 {
01485   file_ptr filestart;
01486 
01487   if (xcoff_ardata (archive) == NULL)
01488     {
01489       bfd_set_error (bfd_error_invalid_operation);
01490       return NULL;
01491     }
01492 
01493   if (! xcoff_big_format_p (archive))
01494     {
01495       if (last_file == NULL)
01496        filestart = bfd_ardata (archive)->first_file_filepos;
01497       else
01498        filestart = strtol (arch_xhdr (last_file)->nextoff, (char **) NULL,
01499                          10);
01500 
01501       if (filestart == 0
01502          || filestart == strtol (xcoff_ardata (archive)->memoff,
01503                               (char **) NULL, 10)
01504          || filestart == strtol (xcoff_ardata (archive)->symoff,
01505                               (char **) NULL, 10))
01506        {
01507          bfd_set_error (bfd_error_no_more_archived_files);
01508          return NULL;
01509        }
01510     }
01511   else
01512     {
01513       if (last_file == NULL)
01514        filestart = bfd_ardata (archive)->first_file_filepos;
01515       else
01516        /* XXX These actually have to be a calls to strtoll (at least
01517           on 32-bit machines) since the fields's width is 20 and
01518           there numbers with more than 32 bits can be represented.  */
01519        filestart = strtol (arch_xhdr_big (last_file)->nextoff, (char **) NULL,
01520                          10);
01521 
01522       /* XXX These actually have to be calls to strtoll (at least on 32-bit
01523         machines) since the fields's width is 20 and there numbers with more
01524         than 32 bits can be represented.  */
01525       if (filestart == 0
01526          || filestart == strtol (xcoff_ardata_big (archive)->memoff,
01527                               (char **) NULL, 10)
01528          || filestart == strtol (xcoff_ardata_big (archive)->symoff,
01529                               (char **) NULL, 10))
01530        {
01531          bfd_set_error (bfd_error_no_more_archived_files);
01532          return NULL;
01533        }
01534     }
01535 
01536   return _bfd_get_elt_at_filepos (archive, filestart);
01537 }
01538 
01539 /* Stat an element in an XCOFF archive.  */
01540 
01541 int
01542 _bfd_xcoff_stat_arch_elt (abfd, s)
01543      bfd *abfd;
01544      struct stat *s;
01545 {
01546   if (abfd->arelt_data == NULL)
01547     {
01548       bfd_set_error (bfd_error_invalid_operation);
01549       return -1;
01550     }
01551 
01552   if (! xcoff_big_format_p (abfd->my_archive))
01553     {
01554       struct xcoff_ar_hdr *hdrp = arch_xhdr (abfd);
01555 
01556       s->st_mtime = strtol (hdrp->date, (char **) NULL, 10);
01557       s->st_uid = strtol (hdrp->uid, (char **) NULL, 10);
01558       s->st_gid = strtol (hdrp->gid, (char **) NULL, 10);
01559       s->st_mode = strtol (hdrp->mode, (char **) NULL, 8);
01560       s->st_size = arch_eltdata (abfd)->parsed_size;
01561     }
01562   else
01563     {
01564       struct xcoff_ar_hdr_big *hdrp = arch_xhdr_big (abfd);
01565 
01566       s->st_mtime = strtol (hdrp->date, (char **) NULL, 10);
01567       s->st_uid = strtol (hdrp->uid, (char **) NULL, 10);
01568       s->st_gid = strtol (hdrp->gid, (char **) NULL, 10);
01569       s->st_mode = strtol (hdrp->mode, (char **) NULL, 8);
01570       s->st_size = arch_eltdata (abfd)->parsed_size;
01571     }
01572 
01573   return 0;
01574 }
01575 
01576 /* Normalize a file name for inclusion in an archive.  */
01577 
01578 static const char *
01579 normalize_filename (abfd)
01580      bfd *abfd;
01581 {
01582   const char *file;
01583   const char *filename;
01584 
01585   file = bfd_get_filename (abfd);
01586   filename = strrchr (file, '/');
01587   if (filename != NULL)
01588     filename++;
01589   else
01590     filename = file;
01591   return filename;
01592 }
01593 
01594 /* Write out an XCOFF armap.  */
01595 
01596 static bfd_boolean
01597 xcoff_write_armap_old (abfd, elength, map, orl_count, stridx)
01598      bfd *abfd;
01599      unsigned int elength ATTRIBUTE_UNUSED;
01600      struct orl *map;
01601      unsigned int orl_count;
01602      int stridx;
01603 {
01604   struct xcoff_ar_hdr hdr;
01605   char *p;
01606   unsigned char buf[4];
01607   bfd *sub;
01608   file_ptr fileoff;
01609   unsigned int i;
01610 
01611   memset (&hdr, 0, sizeof hdr);
01612   sprintf (hdr.size, "%ld", (long) (4 + orl_count * 4 + stridx));
01613   sprintf (hdr.nextoff, "%d", 0);
01614   memcpy (hdr.prevoff, xcoff_ardata (abfd)->memoff, XCOFFARMAG_ELEMENT_SIZE);
01615   sprintf (hdr.date, "%d", 0);
01616   sprintf (hdr.uid, "%d", 0);
01617   sprintf (hdr.gid, "%d", 0);
01618   sprintf (hdr.mode, "%d", 0);
01619   sprintf (hdr.namlen, "%d", 0);
01620 
01621   /* We need spaces, not null bytes, in the header.  */
01622   for (p = (char *) &hdr; p < (char *) &hdr + SIZEOF_AR_HDR; p++)
01623     if (*p == '\0')
01624       *p = ' ';
01625 
01626   if (bfd_bwrite ((PTR) &hdr, (bfd_size_type) SIZEOF_AR_HDR, abfd)
01627       != SIZEOF_AR_HDR
01628       || (bfd_bwrite (XCOFFARFMAG, (bfd_size_type) SXCOFFARFMAG, abfd)
01629          != SXCOFFARFMAG))
01630     return FALSE;
01631 
01632   H_PUT_32 (abfd, orl_count, buf);
01633   if (bfd_bwrite (buf, (bfd_size_type) 4, abfd) != 4)
01634     return FALSE;
01635 
01636   sub = abfd->archive_head;
01637   fileoff = SIZEOF_AR_FILE_HDR;
01638   i = 0;
01639   while (sub != NULL && i < orl_count)
01640     {
01641       size_t namlen;
01642 
01643       while (map[i].u.abfd == sub)
01644        {
01645          H_PUT_32 (abfd, fileoff, buf);
01646          if (bfd_bwrite (buf, (bfd_size_type) 4, abfd) != 4)
01647            return FALSE;
01648          ++i;
01649        }
01650       namlen = strlen (normalize_filename (sub));
01651       namlen = (namlen + 1) &~ (size_t) 1;
01652       fileoff += (SIZEOF_AR_HDR
01653                 + namlen
01654                 + SXCOFFARFMAG
01655                 + arelt_size (sub));
01656       fileoff = (fileoff + 1) &~ 1;
01657       sub = sub->next;
01658     }
01659 
01660   for (i = 0; i < orl_count; i++)
01661     {
01662       const char *name;
01663       size_t namlen;
01664 
01665       name = *map[i].name;
01666       namlen = strlen (name);
01667       if (bfd_bwrite (name, (bfd_size_type) (namlen + 1), abfd) != namlen + 1)
01668        return FALSE;
01669     }
01670 
01671   if ((stridx & 1) != 0)
01672     {
01673       char b;
01674 
01675       b = '\0';
01676       if (bfd_bwrite (&b, (bfd_size_type) 1, abfd) != 1)
01677        return FALSE;
01678     }
01679 
01680   return TRUE;
01681 }
01682 
01683 static char buff20[XCOFFARMAGBIG_ELEMENT_SIZE + 1];
01684 #define FMT20  "%-20lld"
01685 #define FMT12  "%-12d"
01686 #define FMT12_OCTAL  "%-12o"
01687 #define FMT4  "%-4d"
01688 #define PRINT20(d, v) \
01689   sprintf (buff20, FMT20, (long long)(v)), \
01690   memcpy ((void *) (d), buff20, 20)
01691 
01692 #define PRINT12(d, v) \
01693   sprintf (buff20, FMT12, (int)(v)), \
01694   memcpy ((void *) (d), buff20, 12)
01695 
01696 #define PRINT12_OCTAL(d, v) \
01697   sprintf (buff20, FMT12_OCTAL, (unsigned int)(v)), \
01698   memcpy ((void *) (d), buff20, 12)
01699 
01700 #define PRINT4(d, v) \
01701   sprintf (buff20, FMT4, (int)(v)), \
01702   memcpy ((void *) (d), buff20, 4)
01703 
01704 #define READ20(d, v) \
01705   buff20[20] = 0, \
01706   memcpy (buff20, (d), 20), \
01707   (v) = bfd_scan_vma (buff20, (const char **) NULL, 10)
01708 
01709 static bfd_boolean
01710 do_pad (abfd, number)
01711      bfd *abfd;
01712      unsigned int number;
01713 {
01714   bfd_byte b = 0;
01715 
01716   /* Limit pad to <= 4096.  */
01717   if (number > 4096)
01718     return FALSE;
01719 
01720   while (number--)
01721     if (bfd_bwrite (&b, (bfd_size_type) 1, abfd) != 1)
01722       return FALSE;
01723 
01724   return TRUE;
01725 }
01726 
01727 static bfd_boolean
01728 do_copy (out_bfd, in_bfd)
01729      bfd *out_bfd;
01730      bfd *in_bfd;
01731 {
01732   bfd_size_type remaining;
01733   bfd_byte buffer[DEFAULT_BUFFERSIZE];
01734 
01735   if (bfd_seek (in_bfd, (file_ptr) 0, SEEK_SET) != 0)
01736     return FALSE;
01737 
01738   remaining = arelt_size (in_bfd);
01739 
01740   while (remaining >= DEFAULT_BUFFERSIZE)
01741     {
01742       if (bfd_bread (buffer, DEFAULT_BUFFERSIZE, in_bfd) != DEFAULT_BUFFERSIZE
01743          || bfd_bwrite (buffer, DEFAULT_BUFFERSIZE, out_bfd) != DEFAULT_BUFFERSIZE)
01744        return FALSE;
01745 
01746       remaining -= DEFAULT_BUFFERSIZE;
01747     }
01748 
01749   if (remaining)
01750     {
01751       if (bfd_bread (buffer, remaining, in_bfd) != remaining
01752          || bfd_bwrite (buffer, remaining, out_bfd) != remaining)
01753        return FALSE;
01754     }
01755 
01756   return TRUE;
01757 }
01758 
01759 static bfd_boolean
01760 do_shared_object_padding (out_bfd, in_bfd, offset, ar_header_size)
01761      bfd *out_bfd;
01762      bfd *in_bfd;
01763      file_ptr *offset;
01764      int ar_header_size;
01765 {
01766   if (bfd_check_format (in_bfd, bfd_object)
01767       && bfd_get_flavour (in_bfd) == bfd_target_xcoff_flavour
01768       && (in_bfd->flags & DYNAMIC) != 0)
01769     {
01770       bfd_size_type pad = 0;
01771       int text_align_power;
01772 
01773       text_align_power = bfd_xcoff_text_align_power (in_bfd);
01774 
01775       pad = 1 << text_align_power;
01776       pad -= (*offset + ar_header_size) & (pad - 1);
01777 
01778       if (! do_pad (out_bfd, pad))
01779        return FALSE;
01780 
01781       *offset += pad;
01782     }
01783 
01784   return TRUE;
01785 }
01786 
01787 static bfd_boolean
01788 xcoff_write_armap_big (abfd, elength, map, orl_count, stridx)
01789      bfd *abfd;
01790      unsigned int elength ATTRIBUTE_UNUSED;
01791      struct orl *map;
01792      unsigned int orl_count;
01793      int stridx;
01794 {
01795   struct xcoff_ar_file_hdr_big *fhdr;
01796   bfd_vma i, sym_32, sym_64, str_32, str_64;
01797   const bfd_arch_info_type *arch_info = NULL;
01798   bfd *current_bfd;
01799   size_t string_length;
01800   file_ptr nextoff, prevoff;
01801 
01802   /* First, we look through the symbols and work out which are
01803      from 32-bit objects and which from 64-bit ones.  */
01804   sym_32 = sym_64 = str_32 = str_64 = 0;
01805 
01806   current_bfd = abfd->archive_head;
01807   if (current_bfd != NULL)
01808     arch_info = bfd_get_arch_info (current_bfd);
01809     i = 0;
01810     while (current_bfd != NULL && i < orl_count)
01811     {
01812       while (map[i].u.abfd == current_bfd)
01813        {
01814          string_length = strlen (*map[i].name) + 1;
01815 
01816          if (arch_info->bits_per_address == 64)
01817            {
01818              sym_64++;
01819              str_64 += string_length;
01820            }
01821          else
01822            {
01823              sym_32++;
01824              str_32 += string_length;
01825            }
01826          i++;
01827        }
01828       current_bfd = current_bfd->next;
01829       if (current_bfd != NULL)
01830        arch_info = bfd_get_arch_info (current_bfd);
01831     }
01832 
01833   /* A quick sanity check... */
01834   BFD_ASSERT (sym_64 + sym_32 == orl_count);
01835   /* Explicit cast to int for compiler.  */
01836   BFD_ASSERT ((int)(str_64 + str_32) == stridx);
01837 
01838   fhdr = xcoff_ardata_big (abfd);
01839 
01840   /* xcoff_write_archive_contents_big passes nextoff in symoff. */
01841   READ20 (fhdr->memoff, prevoff);
01842   READ20 (fhdr->symoff, nextoff);
01843 
01844   BFD_ASSERT (nextoff == bfd_tell (abfd));
01845 
01846   /* Write out the symbol table.
01847      Layout :
01848 
01849      standard big archive header
01850      0x0000                ar_size [0x14]
01851      0x0014                ar_nxtmem [0x14]
01852      0x0028                ar_prvmem [0x14]
01853      0x003C                ar_date [0x0C]
01854      0x0048                ar_uid  [0x0C]
01855      0x0054                ar_gid  [0x0C]
01856      0x0060                ar_mod  [0x0C]
01857      0x006C                ar_namelen[0x04]
01858      0x0070                ar_fmag [SXCOFFARFMAG]
01859 
01860      Symbol table
01861      0x0072                num_syms       [0x08], binary
01862      0x0078                offsets [0x08 * num_syms], binary
01863      0x0086 + 0x08 * num_syms names       [??]
01864      ??                           pad to even bytes.
01865   */
01866 
01867   if (sym_32)
01868     {
01869       struct xcoff_ar_hdr_big *hdr;
01870       char *symbol_table;
01871       char *st;
01872       file_ptr fileoff;
01873 
01874       bfd_vma symbol_table_size =
01875        SIZEOF_AR_HDR_BIG
01876        + SXCOFFARFMAG
01877        + 8
01878        + 8 * sym_32
01879        + str_32 + (str_32 & 1);
01880 
01881       symbol_table = bfd_zmalloc (symbol_table_size);
01882       if (symbol_table == NULL)
01883        return FALSE;
01884 
01885       hdr = (struct xcoff_ar_hdr_big *) symbol_table;
01886 
01887       PRINT20 (hdr->size, 8 + 8 * sym_32 + str_32 + (str_32 & 1));
01888 
01889       if (sym_64)
01890        PRINT20 (hdr->nextoff, nextoff + symbol_table_size);
01891       else
01892        PRINT20 (hdr->nextoff, 0);
01893 
01894       PRINT20 (hdr->prevoff, prevoff);
01895       PRINT12 (hdr->date, 0);
01896       PRINT12 (hdr->uid, 0);
01897       PRINT12 (hdr->gid, 0);
01898       PRINT12 (hdr->mode, 0);
01899       PRINT4 (hdr->namlen, 0) ;
01900 
01901       st = symbol_table + SIZEOF_AR_HDR_BIG;
01902       memcpy (st, XCOFFARFMAG, SXCOFFARFMAG);
01903       st += SXCOFFARFMAG;
01904 
01905       bfd_h_put_64 (abfd, sym_32, st);
01906       st += 8;
01907 
01908       /* loop over the 32 bit offsets */
01909       current_bfd = abfd->archive_head;
01910       if (current_bfd != NULL)
01911        arch_info = bfd_get_arch_info (current_bfd);
01912       fileoff = SIZEOF_AR_FILE_HDR_BIG;
01913       i = 0;
01914       while (current_bfd != NULL && i < orl_count)
01915        {
01916          while (map[i].u.abfd == current_bfd)
01917            {
01918              if (arch_info->bits_per_address == 32)
01919               {
01920                 bfd_h_put_64 (abfd, fileoff, st);
01921                 st += 8;
01922               }
01923              i++;
01924            }
01925          string_length = strlen (normalize_filename (current_bfd));
01926          string_length += string_length & 1;
01927          fileoff += (SIZEOF_AR_HDR_BIG
01928                     + string_length
01929                     + SXCOFFARFMAG
01930                     + arelt_size (current_bfd));
01931          fileoff += fileoff & 1;
01932          current_bfd = current_bfd->next;
01933          if (current_bfd != NULL)
01934            arch_info = bfd_get_arch_info (current_bfd);
01935        }
01936 
01937       /* loop over the 32 bit symbol names */
01938       current_bfd = abfd->archive_head;
01939       if (current_bfd != NULL)
01940        arch_info = bfd_get_arch_info (current_bfd);
01941       i = 0;
01942       while (current_bfd != NULL && i < orl_count)
01943        {
01944          while (map[i].u.abfd == current_bfd)
01945            {
01946              if (arch_info->bits_per_address == 32)
01947               {
01948                 string_length = sprintf (st, "%s", *map[i].name);
01949                 st += string_length + 1;
01950               }
01951              i++;
01952            }
01953          current_bfd = current_bfd->next;
01954          if (current_bfd != NULL)
01955            arch_info = bfd_get_arch_info (current_bfd);
01956        }
01957 
01958       bfd_bwrite (symbol_table, symbol_table_size, abfd);
01959 
01960       free (symbol_table);
01961 
01962       prevoff = nextoff;
01963       nextoff = nextoff + symbol_table_size;
01964     }
01965   else
01966     PRINT20 (fhdr->symoff, 0);
01967 
01968   if (sym_64)
01969     {
01970       struct xcoff_ar_hdr_big *hdr;
01971       char *symbol_table;
01972       char *st;
01973       file_ptr fileoff;
01974 
01975       bfd_vma symbol_table_size =
01976        SIZEOF_AR_HDR_BIG
01977        + SXCOFFARFMAG
01978        + 8
01979        + 8 * sym_64
01980        + str_64 + (str_64 & 1);
01981 
01982       symbol_table = bfd_zmalloc (symbol_table_size);
01983       if (symbol_table == NULL)
01984        return FALSE;
01985 
01986       hdr = (struct xcoff_ar_hdr_big *) symbol_table;
01987 
01988       PRINT20 (hdr->size, 8 + 8 * sym_64 + str_64 + (str_64 & 1));
01989       PRINT20 (hdr->nextoff, 0);
01990       PRINT20 (hdr->prevoff, prevoff);
01991       PRINT12 (hdr->date, 0);
01992       PRINT12 (hdr->uid, 0);
01993       PRINT12 (hdr->gid, 0);
01994       PRINT12 (hdr->mode, 0);
01995       PRINT4 (hdr->namlen, 0);
01996 
01997       st = symbol_table + SIZEOF_AR_HDR_BIG;
01998       memcpy (st, XCOFFARFMAG, SXCOFFARFMAG);
01999       st += SXCOFFARFMAG;
02000 
02001       bfd_h_put_64 (abfd, sym_64, st);
02002       st += 8;
02003 
02004       /* loop over the 64 bit offsets */
02005       current_bfd = abfd->archive_head;
02006       if (current_bfd != NULL)
02007        arch_info = bfd_get_arch_info (current_bfd);
02008       fileoff = SIZEOF_AR_FILE_HDR_BIG;
02009       i = 0;
02010       while (current_bfd != NULL && i < orl_count)
02011        {
02012          while (map[i].u.abfd == current_bfd)
02013            {
02014              if (arch_info->bits_per_address == 64)
02015               {
02016                 bfd_h_put_64 (abfd, fileoff, st);
02017                 st += 8;
02018               }
02019              i++;
02020            }
02021          string_length = strlen (normalize_filename (current_bfd));
02022          string_length += string_length & 1;
02023          fileoff += (SIZEOF_AR_HDR_BIG
02024                     + string_length
02025                     + SXCOFFARFMAG
02026                     + arelt_size (current_bfd));
02027          fileoff += fileoff & 1;
02028          current_bfd = current_bfd->next;
02029          if (current_bfd != NULL)
02030            arch_info = bfd_get_arch_info (current_bfd);
02031        }
02032 
02033       /* loop over the 64 bit symbol names */
02034       current_bfd = abfd->archive_head;
02035       if (current_bfd != NULL)
02036        arch_info = bfd_get_arch_info (current_bfd);
02037       i = 0;
02038       while (current_bfd != NULL && i < orl_count)
02039        {
02040          while (map[i].u.abfd == current_bfd)
02041            {
02042              if (arch_info->bits_per_address == 64)
02043               {
02044                 string_length = sprintf (st, "%s", *map[i].name);
02045                 st += string_length + 1;
02046               }
02047              i++;
02048            }
02049          current_bfd = current_bfd->next;
02050          if (current_bfd != NULL)
02051            arch_info = bfd_get_arch_info (current_bfd);
02052        }
02053 
02054       bfd_bwrite (symbol_table, symbol_table_size, abfd);
02055 
02056       free (symbol_table);
02057 
02058       PRINT20 (fhdr->symoff64, nextoff);
02059     }
02060   else
02061     PRINT20 (fhdr->symoff64, 0);
02062 
02063   return TRUE;
02064 }
02065 
02066 bfd_boolean
02067 _bfd_xcoff_write_armap (abfd, elength, map, orl_count, stridx)
02068      bfd *abfd;
02069      unsigned int elength ATTRIBUTE_UNUSED;
02070      struct orl *map;
02071      unsigned int orl_count;
02072      int stridx;
02073 {
02074   if (! xcoff_big_format_p (abfd))
02075     return xcoff_write_armap_old (abfd, elength, map, orl_count, stridx);
02076   else
02077     return xcoff_write_armap_big (abfd, elength, map, orl_count, stridx);
02078 }
02079 
02080 /* Write out an XCOFF archive.  We always write an entire archive,
02081    rather than fussing with the freelist and so forth.  */
02082 
02083 static bfd_boolean
02084 xcoff_write_archive_contents_old (abfd)
02085      bfd *abfd;
02086 {
02087   struct xcoff_ar_file_hdr fhdr;
02088   bfd_size_type count;
02089   bfd_size_type total_namlen;
02090   file_ptr *offsets;
02091   bfd_boolean makemap;
02092   bfd_boolean hasobjects;
02093   file_ptr prevoff, nextoff;
02094   bfd *sub;
02095   size_t i;
02096   struct xcoff_ar_hdr ahdr;
02097   bfd_size_type size;
02098   char *p;
02099   char decbuf[XCOFFARMAG_ELEMENT_SIZE + 1];
02100 
02101   memset (&fhdr, 0, sizeof fhdr);
02102   (void) strncpy (fhdr.magic, XCOFFARMAG, SXCOFFARMAG);
02103   sprintf (fhdr.firstmemoff, "%d", SIZEOF_AR_FILE_HDR);
02104   sprintf (fhdr.freeoff, "%d", 0);
02105 
02106   count = 0;
02107   total_namlen = 0;
02108   for (sub = abfd->archive_head; sub != NULL; sub = sub->next)
02109     {
02110       ++count;
02111       total_namlen += strlen (normalize_filename (sub)) + 1;
02112     }
02113   offsets = (file_ptr *) bfd_alloc (abfd, count * sizeof (file_ptr));
02114   if (offsets == NULL)
02115     return FALSE;
02116 
02117   if (bfd_seek (abfd, (file_ptr) SIZEOF_AR_FILE_HDR, SEEK_SET) != 0)
02118     return FALSE;
02119 
02120   makemap = bfd_has_map (abfd);
02121   hasobjects = FALSE;
02122   prevoff = 0;
02123   nextoff = SIZEOF_AR_FILE_HDR;
02124   for (sub = abfd->archive_head, i = 0; sub != NULL; sub = sub->next, i++)
02125     {
02126       const char *name;
02127       bfd_size_type namlen;
02128       struct xcoff_ar_hdr *ahdrp;
02129       bfd_size_type remaining;
02130 
02131       if (makemap && ! hasobjects)
02132        {
02133          if (bfd_check_format (sub, bfd_object))
02134            hasobjects = TRUE;
02135        }
02136 
02137       name = normalize_filename (sub);
02138       namlen = strlen (name);
02139 
02140       if (sub->arelt_data != NULL)
02141        ahdrp = arch_xhdr (sub);
02142       else
02143        ahdrp = NULL;
02144 
02145       if (ahdrp == NULL)
02146        {
02147          struct stat s;
02148 
02149          memset (&ahdr, 0, sizeof ahdr);
02150          ahdrp = &ahdr;
02151          if (stat (bfd_get_filename (sub), &s) != 0)
02152            {
02153              bfd_set_error (bfd_error_system_call);
02154              return FALSE;
02155            }
02156 
02157          sprintf (ahdrp->size, "%ld", (long) s.st_size);
02158          sprintf (ahdrp->date, "%ld", (long) s.st_mtime);
02159          sprintf (ahdrp->uid, "%ld", (long) s.st_uid);
02160          sprintf (ahdrp->gid, "%ld", (long) s.st_gid);
02161          sprintf (ahdrp->mode, "%o", (unsigned int) s.st_mode);
02162 
02163          if (sub->arelt_data == NULL)
02164            {
02165              size = sizeof (struct areltdata);
02166              sub->arelt_data = bfd_alloc (sub, size);
02167              if (sub->arelt_data == NULL)
02168               return FALSE;
02169            }
02170 
02171          arch_eltdata (sub)->parsed_size = s.st_size;
02172        }
02173 
02174       sprintf (ahdrp->prevoff, "%ld", (long) prevoff);
02175       sprintf (ahdrp->namlen, "%ld", (long) namlen);
02176 
02177       /* If the length of the name is odd, we write out the null byte
02178         after the name as well.  */
02179       namlen = (namlen + 1) &~ (bfd_size_type) 1;
02180 
02181       remaining = arelt_size (sub);
02182       size = (SIZEOF_AR_HDR
02183              + namlen
02184              + SXCOFFARFMAG
02185              + remaining);
02186 
02187       BFD_ASSERT (nextoff == bfd_tell (abfd));
02188 
02189       offsets[i] = nextoff;
02190 
02191       prevoff = nextoff;
02192       nextoff += size + (size & 1);
02193 
02194       sprintf (ahdrp->nextoff, "%ld", (long) nextoff);
02195 
02196       /* We need spaces, not null bytes, in the header.  */
02197       for (p = (char *) ahdrp; p < (char *) ahdrp + SIZEOF_AR_HDR; p++)
02198        if (*p == '\0')
02199          *p = ' ';
02200 
02201       if ((bfd_bwrite ((PTR) ahdrp, (bfd_size_type) SIZEOF_AR_HDR, abfd)
02202           != SIZEOF_AR_HDR)
02203          || bfd_bwrite ((PTR) name, namlen, abfd) != namlen
02204          || bfd_bwrite ((PTR) XCOFFARFMAG, (bfd_size_type) SXCOFFARFMAG,
02205                       abfd) != SXCOFFARFMAG)
02206        return FALSE;
02207 
02208       if (bfd_seek (sub, (file_ptr) 0, SEEK_SET) != 0)
02209        return FALSE;
02210 
02211       if (! do_copy (abfd, sub))
02212        return FALSE;
02213 
02214       if (! do_pad (abfd, size & 1))
02215        return FALSE;
02216     }
02217 
02218   sprintf (fhdr.lastmemoff, "%ld", (long) prevoff);
02219 
02220   /* Write out the member table.  */
02221 
02222   BFD_ASSERT (nextoff == bfd_tell (abfd));
02223   sprintf (fhdr.memoff, "%ld", (long) nextoff);
02224 
02225   memset (&ahdr, 0, sizeof ahdr);
02226   sprintf (ahdr.size, "%ld", (long) (XCOFFARMAG_ELEMENT_SIZE
02227                                  + count * XCOFFARMAG_ELEMENT_SIZE
02228                                  + total_namlen));
02229   sprintf (ahdr.prevoff, "%ld", (long) prevoff);
02230   sprintf (ahdr.date, "%d", 0);
02231   sprintf (ahdr.uid, "%d", 0);
02232   sprintf (ahdr.gid, "%d", 0);
02233   sprintf (ahdr.mode, "%d", 0);
02234   sprintf (ahdr.namlen, "%d", 0);
02235 
02236   size = (SIZEOF_AR_HDR
02237          + XCOFFARMAG_ELEMENT_SIZE
02238          + count * XCOFFARMAG_ELEMENT_SIZE
02239          + total_namlen
02240          + SXCOFFARFMAG);
02241 
02242   prevoff = nextoff;
02243   nextoff += size + (size & 1);
02244 
02245   if (makemap && hasobjects)
02246     sprintf (ahdr.nextoff, "%ld", (long) nextoff);
02247   else
02248     sprintf (ahdr.nextoff, "%d", 0);
02249 
02250   /* We need spaces, not null bytes, in the header.  */
02251   for (p = (char *) &ahdr; p < (char *) &ahdr + SIZEOF_AR_HDR; p++)
02252     if (*p == '\0')
02253       *p = ' ';
02254 
02255   if ((bfd_bwrite ((PTR) &ahdr, (bfd_size_type) SIZEOF_AR_HDR, abfd)
02256        != SIZEOF_AR_HDR)
02257       || (bfd_bwrite ((PTR) XCOFFARFMAG, (bfd_size_type) SXCOFFARFMAG, abfd)
02258          != SXCOFFARFMAG))
02259     return FALSE;
02260 
02261   sprintf (decbuf, "%-12ld", (long) count);
02262   if (bfd_bwrite ((PTR) decbuf, (bfd_size_type) XCOFFARMAG_ELEMENT_SIZE, abfd)
02263       != XCOFFARMAG_ELEMENT_SIZE)
02264     return FALSE;
02265   for (i = 0; i < (size_t) count; i++)
02266     {
02267       sprintf (decbuf, "%-12ld", (long) offsets[i]);
02268       if (bfd_bwrite ((PTR) decbuf, (bfd_size_type) XCOFFARMAG_ELEMENT_SIZE,
02269                     abfd) != XCOFFARMAG_ELEMENT_SIZE)
02270        return FALSE;
02271     }
02272   for (sub = abfd->archive_head; sub != NULL; sub = sub->next)
02273     {
02274       const char *name;
02275       bfd_size_type namlen;
02276 
02277       name = normalize_filename (sub);
02278       namlen = strlen (name);
02279       if (bfd_bwrite ((PTR) name, namlen + 1, abfd) != namlen + 1)
02280        return FALSE;
02281     }
02282 
02283   if (! do_pad (abfd, size & 1))
02284     return FALSE;
02285 
02286   /* Write out the armap, if appropriate.  */
02287   if (! makemap || ! hasobjects)
02288     sprintf (fhdr.symoff, "%d", 0);
02289   else
02290     {
02291       BFD_ASSERT (nextoff == bfd_tell (abfd));
02292       sprintf (fhdr.symoff, "%ld", (long) nextoff);
02293       bfd_ardata (abfd)->tdata = (PTR) &fhdr;
02294       if (! _bfd_compute_and_write_armap (abfd, 0))
02295        return FALSE;
02296     }
02297 
02298   /* Write out the archive file header.  */
02299 
02300   /* We need spaces, not null bytes, in the header.  */
02301   for (p = (char *) &fhdr; p < (char *) &fhdr + SIZEOF_AR_FILE_HDR; p++)
02302     if (*p == '\0')
02303       *p = ' ';
02304 
02305   if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0
02306       || (bfd_bwrite ((PTR) &fhdr, (bfd_size_type) SIZEOF_AR_FILE_HDR, abfd)
02307          != SIZEOF_AR_FILE_HDR))
02308     return FALSE;
02309 
02310   return TRUE;
02311 }
02312 
02313 static bfd_boolean
02314 xcoff_write_archive_contents_big (abfd)
02315      bfd *abfd;
02316 {
02317   struct xcoff_ar_file_hdr_big fhdr;
02318   bfd_size_type count;
02319   bfd_size_type total_namlen;
02320   file_ptr *offsets;
02321   bfd_boolean makemap;
02322   bfd_boolean hasobjects;
02323   file_ptr prevoff, nextoff;
02324   bfd *current_bfd;
02325   size_t i;
02326   struct xcoff_ar_hdr_big *hdr, ahdr;
02327   bfd_size_type size;
02328   char *member_table, *mt;
02329   bfd_vma member_table_size;
02330 
02331   memset (&fhdr, 0, SIZEOF_AR_FILE_HDR_BIG);
02332   memcpy (fhdr.magic, XCOFFARMAGBIG, SXCOFFARMAG);
02333 
02334   if (bfd_seek (abfd, (file_ptr) SIZEOF_AR_FILE_HDR_BIG, SEEK_SET) != 0)
02335     return FALSE;
02336 
02337   /* Calculate count and total_namlen.  */
02338   makemap = bfd_has_map (abfd);
02339   hasobjects = FALSE;
02340   for (current_bfd = abfd->archive_head, count = 0, total_namlen = 0;
02341        current_bfd != NULL;
02342        current_bfd = current_bfd->next, count++)
02343     {
02344       total_namlen += strlen (normalize_filename (current_bfd)) + 1;
02345 
02346       if (makemap
02347          && ! hasobjects
02348          && bfd_check_format (current_bfd, bfd_object))
02349        hasobjects = TRUE;
02350     }
02351 
02352   offsets = NULL;
02353   if (count)
02354     {
02355       offsets = (file_ptr *) bfd_malloc (count * sizeof (file_ptr));
02356       if (offsets == NULL)
02357        return FALSE;
02358     }
02359 
02360   prevoff = 0;
02361   nextoff = SIZEOF_AR_FILE_HDR_BIG;
02362   for (current_bfd = abfd->archive_head, i = 0;
02363        current_bfd != NULL;
02364        current_bfd = current_bfd->next, i++)
02365     {
02366       const char *name;
02367       bfd_size_type namlen;
02368       struct xcoff_ar_hdr_big *ahdrp;
02369       bfd_size_type remaining;
02370 
02371       name = normalize_filename (current_bfd);
02372       namlen = strlen (name);
02373 
02374       if (current_bfd->arelt_data != NULL)
02375        ahdrp = arch_xhdr_big (current_bfd);
02376       else
02377        ahdrp = NULL;
02378 
02379       if (ahdrp == NULL)
02380        {
02381          struct stat s;
02382 
02383          ahdrp = &ahdr;
02384          /* XXX This should actually be a call to stat64 (at least on
02385             32-bit machines).
02386             XXX This call will fail if the original object is not found.  */
02387          if (stat (bfd_get_filename (current_bfd), &s) != 0)
02388            {
02389              bfd_set_error (bfd_error_system_call);
02390              return FALSE;
02391            }
02392 
02393          PRINT20 (ahdrp->size, s.st_size);
02394          PRINT12 (ahdrp->date, s.st_mtime);
02395          PRINT12 (ahdrp->uid,  s.st_uid);
02396          PRINT12 (ahdrp->gid,  s.st_gid);
02397          PRINT12_OCTAL (ahdrp->mode, s.st_mode);
02398 
02399          if (current_bfd->arelt_data == NULL)
02400            {
02401              size = sizeof (struct areltdata);
02402              current_bfd->arelt_data = bfd_alloc (current_bfd, size);
02403              if (current_bfd->arelt_data == NULL)
02404               return FALSE;
02405            }
02406 
02407          arch_eltdata (current_bfd)->parsed_size = s.st_size;
02408        }
02409 
02410       PRINT20 (ahdrp->prevoff, prevoff);
02411       PRINT4 (ahdrp->namlen, namlen);
02412 
02413       /* If the length of the name is odd, we write out the null byte
02414         after the name as well.  */
02415       namlen = (namlen + 1) &~ (bfd_size_type) 1;
02416 
02417       remaining = arelt_size (current_bfd);
02418       size = (SIZEOF_AR_HDR_BIG
02419              + namlen
02420              + SXCOFFARFMAG
02421              + remaining);
02422 
02423       BFD_ASSERT (nextoff == bfd_tell (abfd));
02424 
02425       /* Check for xcoff shared objects.
02426         Their text section needs to be aligned wrt the archive file position.
02427         This requires extra padding before the archive header.  */
02428       if (! do_shared_object_padding (abfd, current_bfd, & nextoff,
02429                                   SIZEOF_AR_HDR_BIG + namlen
02430                                   + SXCOFFARFMAG))
02431        return FALSE;
02432 
02433       offsets[i] = nextoff;
02434 
02435       prevoff = nextoff;
02436       nextoff += size + (size & 1);
02437 
02438       PRINT20 (ahdrp->nextoff, nextoff);
02439 
02440       if ((bfd_bwrite ((PTR) ahdrp, (bfd_size_type) SIZEOF_AR_HDR_BIG, abfd)
02441           != SIZEOF_AR_HDR_BIG)
02442          || bfd_bwrite ((PTR) name, (bfd_size_type) namlen, abfd) != namlen
02443          || (bfd_bwrite ((PTR) XCOFFARFMAG, (bfd_size_type) SXCOFFARFMAG,
02444                        abfd) != SXCOFFARFMAG))
02445        return FALSE;
02446 
02447       if (bfd_seek (current_bfd, (file_ptr) 0, SEEK_SET) != 0)
02448        return FALSE;
02449 
02450       if (! do_copy (abfd, current_bfd))
02451        return FALSE;
02452 
02453       if (! do_pad (abfd, size & 1))
02454        return FALSE;
02455     }
02456 
02457   if (count)
02458     {
02459       PRINT20 (fhdr.firstmemoff, offsets[0]);
02460       PRINT20 (fhdr.lastmemoff, prevoff);
02461     }
02462 
02463   /* Write out the member table.
02464      Layout :
02465 
02466      standard big archive header
02467      0x0000                ar_size [0x14]
02468      0x0014                ar_nxtmem [0x14]
02469      0x0028                ar_prvmem [0x14]
02470      0x003C                ar_date [0x0C]
02471      0x0048                ar_uid  [0x0C]
02472      0x0054                ar_gid  [0x0C]
02473      0x0060                ar_mod  [0x0C]
02474      0x006C                ar_namelen[0x04]
02475      0x0070                ar_fmag [0x02]
02476 
02477      Member table
02478      0x0072                count   [0x14]
02479      0x0086                offsets [0x14 * counts]
02480      0x0086 + 0x14 * counts   names       [??]
02481      ??                           pad to even bytes.
02482    */
02483 
02484   BFD_ASSERT (nextoff == bfd_tell (abfd));
02485 
02486   member_table_size = (SIZEOF_AR_HDR_BIG
02487                      + SXCOFFARFMAG
02488                      + XCOFFARMAGBIG_ELEMENT_SIZE
02489                      + count * XCOFFARMAGBIG_ELEMENT_SIZE
02490                      + total_namlen);
02491 
02492   member_table_size += member_table_size & 1;
02493   member_table = bfd_zmalloc (member_table_size);
02494   if (member_table == NULL)
02495     return FALSE;
02496 
02497   hdr = (struct xcoff_ar_hdr_big *) member_table;
02498 
02499   PRINT20 (hdr->size, (XCOFFARMAGBIG_ELEMENT_SIZE
02500                      + count * XCOFFARMAGBIG_ELEMENT_SIZE
02501                      + total_namlen + (total_namlen & 1)));
02502   if (makemap && hasobjects)
02503     PRINT20 (hdr->nextoff, nextoff + member_table_size);
02504   else
02505     PRINT20 (hdr->nextoff, 0);
02506   PRINT20 (hdr->prevoff, prevoff);
02507   PRINT12 (hdr->date, 0);
02508   PRINT12 (hdr->uid, 0);
02509   PRINT12 (hdr->gid, 0);
02510   PRINT12 (hdr->mode, 0);
02511   PRINT4 (hdr->namlen, 0);
02512 
02513   mt = member_table + SIZEOF_AR_HDR_BIG;
02514   memcpy (mt, XCOFFARFMAG, SXCOFFARFMAG);
02515   mt += SXCOFFARFMAG;
02516 
02517   PRINT20 (mt, count);
02518   mt += XCOFFARMAGBIG_ELEMENT_SIZE;
02519   for (i = 0; i < (size_t) count; i++)
02520     {
02521       PRINT20 (mt, offsets[i]);
02522       mt += XCOFFARMAGBIG_ELEMENT_SIZE;
02523     }
02524 
02525   if (count)
02526     {
02527       free (offsets);
02528       offsets = NULL;
02529     }
02530 
02531   for (current_bfd = abfd->archive_head; current_bfd != NULL;
02532        current_bfd = current_bfd->next)
02533     {
02534       const char *name;
02535       size_t namlen;
02536 
02537       name = normalize_filename (current_bfd);
02538       namlen = sprintf (mt, "%s", name);
02539       mt += namlen + 1;
02540     }
02541 
02542   if (bfd_bwrite (member_table, member_table_size, abfd) != member_table_size)
02543     return FALSE;
02544 
02545   free (member_table);
02546 
02547   PRINT20 (fhdr.memoff, nextoff);
02548 
02549   prevoff = nextoff;
02550   nextoff += member_table_size;
02551 
02552   /* Write out the armap, if appropriate.  */
02553 
02554   if (! makemap || ! hasobjects)
02555     PRINT20 (fhdr.symoff, 0);
02556   else
02557     {
02558       BFD_ASSERT (nextoff == bfd_tell (abfd));
02559 
02560       /* Save nextoff in fhdr.symoff so the armap routine can use it.  */
02561       PRINT20 (fhdr.symoff, nextoff);
02562 
02563       bfd_ardata (abfd)->tdata = (PTR) &fhdr;
02564       if (! _bfd_compute_and_write_armap (abfd, 0))
02565        return FALSE;
02566     }
02567 
02568   /* Write out the archive file header.  */
02569 
02570   if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0
02571       || (bfd_bwrite ((PTR) &fhdr, (bfd_size_type) SIZEOF_AR_FILE_HDR_BIG,
02572                     abfd) != SIZEOF_AR_FILE_HDR_BIG))
02573     return FALSE;
02574 
02575   return TRUE;
02576 }
02577 
02578 bfd_boolean
02579 _bfd_xcoff_write_archive_contents (abfd)
02580      bfd *abfd;
02581 {
02582   if (! xcoff_big_format_p (abfd))
02583     return xcoff_write_archive_contents_old (abfd);
02584   else
02585     return xcoff_write_archive_contents_big (abfd);
02586 }
02587 
02588 /* We can't use the usual coff_sizeof_headers routine, because AIX
02589    always uses an a.out header.  */
02590 
02591 int
02592 _bfd_xcoff_sizeof_headers (bfd *abfd,
02593                         struct bfd_link_info *info ATTRIBUTE_UNUSED)
02594 {
02595   int size;
02596 
02597   size = FILHSZ;
02598   if (xcoff_data (abfd)->full_aouthdr)
02599     size += AOUTSZ;
02600   else
02601     size += SMALL_AOUTSZ;
02602   size += abfd->section_count * SCNHSZ;
02603   return size;
02604 }
02605 
02606 /* Routines to swap information in the XCOFF .loader section.  If we
02607    ever need to write an XCOFF loader, this stuff will need to be
02608    moved to another file shared by the linker (which XCOFF calls the
02609    ``binder'') and the loader.  */
02610 
02611 /* Swap in the ldhdr structure.  */
02612 
02613 static void
02614 xcoff_swap_ldhdr_in (abfd, s, dst)
02615      bfd *abfd;
02616      const PTR s;
02617      struct internal_ldhdr *dst;
02618 {
02619   const struct external_ldhdr *src = (const struct external_ldhdr *) s;
02620 
02621   dst->l_version = bfd_get_32 (abfd, src->l_version);
02622   dst->l_nsyms = bfd_get_32 (abfd, src->l_nsyms);
02623   dst->l_nreloc = bfd_get_32 (abfd, src->l_nreloc);
02624   dst->l_istlen = bfd_get_32 (abfd, src->l_istlen);
02625   dst->l_nimpid = bfd_get_32 (abfd, src->l_nimpid);
02626   dst->l_impoff = bfd_get_32 (abfd, src->l_impoff);
02627   dst->l_stlen = bfd_get_32 (abfd, src->l_stlen);
02628   dst->l_stoff = bfd_get_32 (abfd, src->l_stoff);
02629 }
02630 
02631 /* Swap out the ldhdr structure.  */
02632 
02633 static void
02634 xcoff_swap_ldhdr_out (abfd, src, d)
02635      bfd *abfd;
02636      const struct internal_ldhdr *src;
02637      PTR d;
02638 {
02639   struct external_ldhdr *dst = (struct external_ldhdr *) d;
02640 
02641   bfd_put_32 (abfd, (bfd_vma) src->l_version, dst->l_version);
02642   bfd_put_32 (abfd, src->l_nsyms, dst->l_nsyms);
02643   bfd_put_32 (abfd, src->l_nreloc, dst->l_nreloc);
02644   bfd_put_32 (abfd, src->l_istlen, dst->l_istlen);
02645   bfd_put_32 (abfd, src->l_nimpid, dst->l_nimpid);
02646   bfd_put_32 (abfd, src->l_impoff, dst->l_impoff);
02647   bfd_put_32 (abfd, src->l_stlen, dst->l_stlen);
02648   bfd_put_32 (abfd, src->l_stoff, dst->l_stoff);
02649 }
02650 
02651 /* Swap in the ldsym structure.  */
02652 
02653 static void
02654 xcoff_swap_ldsym_in (abfd, s, dst)
02655      bfd *abfd;
02656      const PTR s;
02657      struct internal_ldsym *dst;
02658 {
02659   const struct external_ldsym *src = (const struct external_ldsym *) s;
02660 
02661   if (bfd_get_32 (abfd, src->_l._l_l._l_zeroes) != 0) {
02662     memcpy (dst->_l._l_name, src->_l._l_name, SYMNMLEN);
02663   } else {
02664     dst->_l._l_l._l_zeroes = 0;
02665     dst->_l._l_l._l_offset = bfd_get_32 (abfd, src->_l._l_l._l_offset);
02666   }
02667   dst->l_value = bfd_get_32 (abfd, src->l_value);
02668   dst->l_scnum = bfd_get_16 (abfd, src->l_scnum);
02669   dst->l_smtype = bfd_get_8 (abfd, src->l_smtype);
02670   dst->l_smclas = bfd_get_8 (abfd, src->l_smclas);
02671   dst->l_ifile = bfd_get_32 (abfd, src->l_ifile);
02672   dst->l_parm = bfd_get_32 (abfd, src->l_parm);
02673 }
02674 
02675 /* Swap out the ldsym structure.  */
02676 
02677 static void
02678 xcoff_swap_ldsym_out (abfd, src, d)
02679      bfd *abfd;
02680      const struct internal_ldsym *src;
02681      PTR d;
02682 {
02683   struct external_ldsym *dst = (struct external_ldsym *) d;
02684 
02685   if (src->_l._l_l._l_zeroes != 0)
02686     memcpy (dst->_l._l_name, src->_l._l_name, SYMNMLEN);
02687   else
02688     {
02689       bfd_put_32 (abfd, (bfd_vma) 0, dst->_l._l_l._l_zeroes);
02690       bfd_put_32 (abfd, (bfd_vma) src->_l._l_l._l_offset,
02691                 dst->_l._l_l._l_offset);
02692     }
02693   bfd_put_32 (abfd, src->l_value, dst->l_value);
02694   bfd_put_16 (abfd, (bfd_vma) src->l_scnum, dst->l_scnum);
02695   bfd_put_8 (abfd, src->l_smtype, dst->l_smtype);
02696   bfd_put_8 (abfd, src->l_smclas, dst->l_smclas);
02697   bfd_put_32 (abfd, src->l_ifile, dst->l_ifile);
02698   bfd_put_32 (abfd, src->l_parm, dst->l_parm);
02699 }
02700 
02701 static void
02702 xcoff_swap_reloc_in (abfd, s, d)
02703      bfd *abfd;
02704      PTR s;
02705      PTR d;
02706 {
02707   struct external_reloc *src = (struct external_reloc *) s;
02708   struct internal_reloc *dst = (struct internal_reloc *) d;
02709 
02710   memset (dst, 0, sizeof (struct internal_reloc));
02711 
02712   dst->r_vaddr = bfd_get_32 (abfd, src->r_vaddr);
02713   dst->r_symndx = bfd_get_32 (abfd, src->r_symndx);
02714   dst->r_size = bfd_get_8 (abfd, src->r_size);
02715   dst->r_type = bfd_get_8 (abfd, src->r_type);
02716 }
02717 
02718 static unsigned int
02719 xcoff_swap_reloc_out (abfd, s, d)
02720      bfd *abfd;
02721      PTR s;
02722      PTR d;
02723 {
02724   struct internal_reloc *src = (struct internal_reloc *) s;
02725   struct external_reloc *dst = (struct external_reloc *) d;
02726 
02727   bfd_put_32 (abfd, src->r_vaddr, dst->r_vaddr);
02728   bfd_put_32 (abfd, src->r_symndx, dst->r_symndx);
02729   bfd_put_8 (abfd, src->r_type, dst->r_type);
02730   bfd_put_8 (abfd, src->r_size, dst->r_size);
02731 
02732   return bfd_coff_relsz (abfd);
02733 }
02734 
02735 /* Swap in the ldrel structure.  */
02736 
02737 static void
02738 xcoff_swap_ldrel_in (abfd, s, dst)
02739      bfd *abfd;
02740      const PTR s;
02741      struct internal_ldrel *dst;
02742 {
02743   const struct external_ldrel *src = (const struct external_ldrel *) s;
02744 
02745   dst->l_vaddr = bfd_get_32 (abfd, src->l_vaddr);
02746   dst->l_symndx = bfd_get_32 (abfd, src->l_symndx);
02747   dst->l_rtype = bfd_get_16 (abfd, src->l_rtype);
02748   dst->l_rsecnm = bfd_get_16 (abfd, src->l_rsecnm);
02749 }
02750 
02751 /* Swap out the ldrel structure.  */
02752 
02753 static void
02754 xcoff_swap_ldrel_out (abfd, src, d)
02755      bfd *abfd;
02756      const struct internal_ldrel *src;
02757      PTR d;
02758 {
02759   struct external_ldrel *dst = (struct external_ldrel *) d;
02760 
02761   bfd_put_32 (abfd, src->l_vaddr, dst->l_vaddr);
02762   bfd_put_32 (abfd, src->l_symndx, dst->l_symndx);
02763   bfd_put_16 (abfd, (bfd_vma) src->l_rtype, dst->l_rtype);
02764   bfd_put_16 (abfd, (bfd_vma) src->l_rsecnm, dst->l_rsecnm);
02765 }
02766 
02767 
02768 bfd_boolean
02769 xcoff_reloc_type_noop (input_bfd, input_section, output_bfd, rel, sym, howto,
02770                      val, addend, relocation, contents)
02771      bfd *input_bfd ATTRIBUTE_UNUSED;
02772      asection *input_section ATTRIBUTE_UNUSED;
02773      bfd *output_bfd ATTRIBUTE_UNUSED;
02774      struct internal_reloc *rel ATTRIBUTE_UNUSED;
02775      struct internal_syment *sym ATTRIBUTE_UNUSED;
02776      struct reloc_howto_struct *howto ATTRIBUTE_UNUSED;
02777      bfd_vma val ATTRIBUTE_UNUSED;
02778      bfd_vma addend ATTRIBUTE_UNUSED;
02779      bfd_vma *relocation ATTRIBUTE_UNUSED;
02780      bfd_byte *contents ATTRIBUTE_UNUSED;
02781 {
02782   return TRUE;
02783 }
02784 
02785 bfd_boolean
02786 xcoff_reloc_type_fail (input_bfd, input_section, output_bfd, rel, sym, howto,
02787                      val, addend, relocation, contents)
02788      bfd *input_bfd;
02789      asection *input_section ATTRIBUTE_UNUSED;
02790      bfd *output_bfd ATTRIBUTE_UNUSED;
02791      struct internal_reloc *rel;
02792      struct internal_syment *sym ATTRIBUTE_UNUSED;
02793      struct reloc_howto_struct *howto ATTRIBUTE_UNUSED;
02794      bfd_vma val ATTRIBUTE_UNUSED;
02795      bfd_vma addend ATTRIBUTE_UNUSED;
02796      bfd_vma *relocation ATTRIBUTE_UNUSED;
02797      bfd_byte *contents ATTRIBUTE_UNUSED;
02798 {
02799   (*_bfd_error_handler)
02800     (_("%s: unsupported relocation type 0x%02x"),
02801      bfd_get_filename (input_bfd), (unsigned int) rel->r_type);
02802   bfd_set_error (bfd_error_bad_value);
02803   return FALSE;
02804 }
02805 
02806 bfd_boolean
02807 xcoff_reloc_type_pos (input_bfd, input_section, output_bfd, rel, sym, howto,
02808                     val, addend, relocation, contents)
02809      bfd *input_bfd ATTRIBUTE_UNUSED;
02810      asection *input_section ATTRIBUTE_UNUSED;
02811      bfd *output_bfd ATTRIBUTE_UNUSED;
02812      struct internal_reloc *rel ATTRIBUTE_UNUSED;
02813      struct internal_syment *sym ATTRIBUTE_UNUSED;
02814      struct reloc_howto_struct *howto ATTRIBUTE_UNUSED;
02815      bfd_vma val;
02816      bfd_vma addend;
02817      bfd_vma *relocation;
02818      bfd_byte *contents ATTRIBUTE_UNUSED;
02819 {
02820   *relocation = val + addend;
02821   return TRUE;
02822 }
02823 
02824 bfd_boolean
02825 xcoff_reloc_type_neg (input_bfd, input_section, output_bfd, rel, sym, howto,
02826                     val, addend, relocation, contents)
02827      bfd *input_bfd ATTRIBUTE_UNUSED;
02828      asection *input_section ATTRIBUTE_UNUSED;
02829      bfd *output_bfd ATTRIBUTE_UNUSED;
02830      struct internal_reloc *rel ATTRIBUTE_UNUSED;
02831      struct internal_syment *sym ATTRIBUTE_UNUSED;
02832      struct reloc_howto_struct *howto ATTRIBUTE_UNUSED;
02833      bfd_vma val;
02834      bfd_vma addend;
02835      bfd_vma *relocation;
02836      bfd_byte *contents ATTRIBUTE_UNUSED;
02837 {
02838   *relocation = addend - val;
02839   return TRUE;
02840 }
02841 
02842 bfd_boolean
02843 xcoff_reloc_type_rel (input_bfd, input_section, output_bfd, rel, sym, howto,
02844                     val, addend, relocation, contents)
02845      bfd *input_bfd ATTRIBUTE_UNUSED;
02846      asection *input_section;
02847      bfd *output_bfd ATTRIBUTE_UNUSED;
02848      struct internal_reloc *rel ATTRIBUTE_UNUSED;
02849      struct internal_syment *sym ATTRIBUTE_UNUSED;
02850      struct reloc_howto_struct *howto;
02851      bfd_vma val;
02852      bfd_vma addend;
02853      bfd_vma *relocation;
02854      bfd_byte *contents ATTRIBUTE_UNUSED;
02855 {
02856   howto->pc_relative = TRUE;
02857 
02858   /* A PC relative reloc includes the section address.  */
02859   addend += input_section->vma;
02860 
02861   *relocation = val + addend;
02862   *relocation -= (input_section->output_section->vma
02863                 + input_section->output_offset);
02864   return TRUE;
02865 }
02866 
02867 bfd_boolean
02868 xcoff_reloc_type_toc (input_bfd, input_section, output_bfd, rel, sym, howto,
02869                     val, addend, relocation, contents)
02870      bfd *input_bfd;
02871      asection *input_section ATTRIBUTE_UNUSED;
02872      bfd *output_bfd;
02873      struct internal_reloc *rel;
02874      struct internal_syment *sym;
02875      struct reloc_howto_struct *howto ATTRIBUTE_UNUSED;
02876      bfd_vma val;
02877      bfd_vma addend ATTRIBUTE_UNUSED;
02878      bfd_vma *relocation;
02879      bfd_byte *contents ATTRIBUTE_UNUSED;
02880 {
02881   struct xcoff_link_hash_entry *h;
02882 
02883   if (0 > rel->r_symndx)
02884     return FALSE;
02885 
02886   h = obj_xcoff_sym_hashes (input_bfd)[rel->r_symndx];
02887 
02888   if (h != NULL && h->smclas != XMC_TD)
02889     {
02890       if (h->toc_section == NULL)
02891        {
02892          (*_bfd_error_handler)
02893            (_("%s: TOC reloc at 0x%x to symbol `%s' with no TOC entry"),
02894             bfd_get_filename (input_bfd), rel->r_vaddr,
02895             h->root.root.string);
02896          bfd_set_error (bfd_error_bad_value);
02897          return FALSE;
02898        }
02899 
02900       BFD_ASSERT ((h->flags & XCOFF_SET_TOC) == 0);
02901       val = (h->toc_section->output_section->vma
02902              + h->toc_section->output_offset);
02903     }
02904 
02905   *relocation = ((val - xcoff_data (output_bfd)->toc)
02906                - (sym->n_value - xcoff_data (input_bfd)->toc));
02907   return TRUE;
02908 }
02909 
02910 bfd_boolean
02911 xcoff_reloc_type_ba (input_bfd, input_section, output_bfd, rel, sym, howto,
02912                    val, addend, relocation, contents)
02913      bfd *input_bfd ATTRIBUTE_UNUSED;
02914      asection *input_section ATTRIBUTE_UNUSED;
02915      bfd *output_bfd ATTRIBUTE_UNUSED;
02916      struct internal_reloc *rel ATTRIBUTE_UNUSED;
02917      struct internal_syment *sym ATTRIBUTE_UNUSED;
02918      struct reloc_howto_struct *howto;
02919      bfd_vma val;
02920      bfd_vma addend;
02921      bfd_vma *relocation;
02922      bfd_byte *contents ATTRIBUTE_UNUSED;
02923 {
02924   howto->src_mask &= ~3;
02925   howto->dst_mask = howto->src_mask;
02926 
02927   *relocation = val + addend;
02928 
02929   return TRUE;
02930 }
02931 
02932 static bfd_boolean
02933 xcoff_reloc_type_br (input_bfd, input_section, output_bfd, rel, sym, howto,
02934                    val, addend, relocation, contents)
02935      bfd *input_bfd;
02936      asection *input_section;
02937      bfd *output_bfd ATTRIBUTE_UNUSED;
02938      struct internal_reloc *rel;
02939      struct internal_syment *sym ATTRIBUTE_UNUSED;
02940      struct reloc_howto_struct *howto;
02941      bfd_vma val;
02942      bfd_vma addend;
02943      bfd_vma *relocation;
02944      bfd_byte *contents;
02945 {
02946   struct xcoff_link_hash_entry *h;
02947 
02948   if (0 > rel->r_symndx)
02949     return FALSE;
02950 
02951   h = obj_xcoff_sym_hashes (input_bfd)[rel->r_symndx];
02952 
02953   /* If we see an R_BR or R_RBR reloc which is jumping to global
02954      linkage code, and it is followed by an appropriate cror nop
02955      instruction, we replace the cror with lwz r2,20(r1).  This
02956      restores the TOC after the glink code.  Contrariwise, if the
02957      call is followed by a lwz r2,20(r1), but the call is not
02958      going to global linkage code, we can replace the load with a
02959      cror.  */
02960   if (NULL != h
02961       && bfd_link_hash_defined == h->root.type
02962       && rel->r_vaddr - input_section->vma + 8 <= input_section->size)
02963     {
02964       bfd_byte *pnext;
02965       unsigned long next;
02966 
02967       pnext = contents + (rel->r_vaddr - input_section->vma) + 4;
02968       next = bfd_get_32 (input_bfd, pnext);
02969 
02970       /* The _ptrgl function is magic.  It is used by the AIX
02971         compiler to call a function through a pointer.  */
02972       if (h->smclas == XMC_GL || strcmp (h->root.root.string, "._ptrgl") == 0)
02973        {
02974          if (next == 0x4def7b82                  /* cror 15,15,15 */
02975              || next == 0x4ffffb82               /* cror 31,31,31 */
02976              || next == 0x60000000)                     /* ori r0,r0,0 */
02977            bfd_put_32 (input_bfd, 0x80410014, pnext);   /* lwz r1,20(r1) */
02978 
02979        }
02980       else
02981        {
02982          if (next == 0x80410014)                 /* lwz r1,20(r1) */
02983            bfd_put_32 (input_bfd, 0x60000000, pnext);   /* ori r0,r0,0 */
02984        }
02985     }
02986   else if (NULL != h && bfd_link_hash_undefined == h->root.type)
02987     {
02988       /* Normally, this relocation is against a defined symbol.  In the
02989         case where this is a partial link and the output section offset
02990         is greater than 2^25, the linker will return an invalid error
02991         message that the relocation has been truncated.  Yes it has been
02992         truncated but no it not important.  For this case, disable the
02993         overflow checking. */
02994 
02995       howto->complain_on_overflow = complain_overflow_dont;
02996     }
02997 
02998   howto->pc_relative = TRUE;
02999   howto->src_mask &= ~3;
03000   howto->dst_mask = howto->src_mask;
03001 
03002   /* A PC relative reloc includes the section address.  */
03003   addend += input_section->vma;
03004 
03005   *relocation = val + addend;
03006   *relocation -= (input_section->output_section->vma
03007                 + input_section->output_offset);
03008   return TRUE;
03009 }
03010 
03011 bfd_boolean
03012 xcoff_reloc_type_crel (input_bfd, input_section, output_bfd, rel, sym, howto,
03013                      val, addend, relocation, contents)
03014      bfd *input_bfd ATTRIBUTE_UNUSED;
03015      asection *input_section;
03016      bfd *output_bfd ATTRIBUTE_UNUSED;
03017      struct internal_reloc *rel ATTRIBUTE_UNUSED;
03018      struct internal_syment *sym ATTRIBUTE_UNUSED;
03019      struct reloc_howto_struct *howto;
03020      bfd_vma val ATTRIBUTE_UNUSED;
03021      bfd_vma addend;
03022      bfd_vma *relocation;
03023      bfd_byte *contents ATTRIBUTE_UNUSED;
03024 {
03025   howto->pc_relative = TRUE;
03026   howto->src_mask &= ~3;
03027   howto->dst_mask = howto->src_mask;
03028 
03029   /* A PC relative reloc includes the section address.  */
03030   addend += input_section->vma;
03031 
03032   *relocation = val + addend;
03033   *relocation -= (input_section->output_section->vma
03034                 + input_section->output_offset);
03035   return TRUE;
03036 }
03037 
03038 static bfd_boolean
03039 xcoff_complain_overflow_dont_func (input_bfd, val, relocation, howto)
03040      bfd *input_bfd ATTRIBUTE_UNUSED;
03041      bfd_vma val ATTRIBUTE_UNUSED;
03042      bfd_vma relocation ATTRIBUTE_UNUSED;
03043      struct reloc_howto_struct *howto ATTRIBUTE_UNUSED;
03044 {
03045   return FALSE;
03046 }
03047 
03048 static bfd_boolean
03049 xcoff_complain_overflow_bitfield_func (input_bfd, val, relocation, howto)
03050      bfd *input_bfd;
03051      bfd_vma val;
03052      bfd_vma relocation;
03053      struct reloc_howto_struct *howto;
03054 {
03055   bfd_vma addrmask, fieldmask, signmask, ss;
03056   bfd_vma a, b, sum;
03057 
03058   /* Get the values to be added together.  For signed and unsigned
03059      relocations, we assume that all values should be truncated to
03060      the size of an address.  For bitfields, all the bits matter.
03061      See also bfd_check_overflow.  */
03062   fieldmask = N_ONES (howto->bitsize);
03063   addrmask = N_ONES (bfd_arch_bits_per_address (input_bfd)) | fieldmask;
03064   a = relocation;
03065   b = val & howto->src_mask;
03066 
03067   /* Much like unsigned, except no trimming with addrmask.  In
03068      addition, the sum overflows if there is a carry out of
03069      the bfd_vma, i.e., the sum is less than either input
03070      operand.  */
03071   a >>= howto->rightshift;
03072   b >>= howto->bitpos;
03073 
03074   /* Bitfields are sometimes used for signed numbers; for
03075      example, a 13-bit field sometimes represents values in
03076      0..8191 and sometimes represents values in -4096..4095.
03077      If the field is signed and a is -4095 (0x1001) and b is
03078      -1 (0x1fff), the sum is -4096 (0x1000), but (0x1001 +
03079      0x1fff is 0x3000).  It's not clear how to handle this
03080      everywhere, since there is not way to know how many bits
03081      are significant in the relocation, but the original code
03082      assumed that it was fully sign extended, and we will keep
03083      that assumption.  */
03084   signmask = (fieldmask >> 1) + 1;
03085 
03086   if ((a & ~ fieldmask) != 0)
03087     {
03088       /* Some bits out of the field are set.  This might not
03089         be a problem: if this is a signed bitfield, it is OK
03090         iff all the high bits are set, including the sign
03091         bit.  We'll try setting all but the most significant
03092         bit in the original relocation value: if this is all
03093         ones, we are OK, assuming a signed bitfield.  */
03094       ss = (signmask << howto->rightshift) - 1;
03095       if ((ss | relocation) != ~ (bfd_vma) 0)
03096        return TRUE;
03097       a &= fieldmask;
03098     }
03099 
03100   /* We just assume (b & ~ fieldmask) == 0.  */
03101 
03102   /* We explicitly permit wrap around if this relocation
03103      covers the high bit of an address.  The Linux kernel
03104      relies on it, and it is the only way to write assembler
03105      code which can run when loaded at a location 0x80000000
03106      away from the location at which it is linked.  */
03107   if (howto->bitsize + howto->rightshift
03108       == bfd_arch_bits_per_address (input_bfd))
03109     return FALSE;
03110 
03111   sum = a + b;
03112   if (sum < a || (sum & ~ fieldmask) != 0)
03113     {
03114       /* There was a carry out, or the field overflow.  Test
03115         for signed operands again.  Here is the overflow test
03116         is as for complain_overflow_signed.  */
03117       if (((~ (a ^ b)) & (a ^ sum)) & signmask)
03118        return TRUE;
03119     }
03120 
03121   return FALSE;
03122 }
03123 
03124 static bfd_boolean
03125 xcoff_complain_overflow_signed_func (input_bfd, val, relocation, howto)
03126      bfd *input_bfd;
03127      bfd_vma val;
03128      bfd_vma relocation;
03129      struct reloc_howto_struct *howto;
03130 {
03131   bfd_vma addrmask, fieldmask, signmask, ss;
03132   bfd_vma a, b, sum;
03133 
03134   /* Get the values to be added together.  For signed and unsigned
03135      relocations, we assume that all values should be truncated to
03136      the size of an address.  For bitfields, all the bits matter.
03137      See also bfd_check_overflow.  */
03138   fieldmask = N_ONES (howto->bitsize);
03139   addrmask = N_ONES (bfd_arch_bits_per_address (input_bfd)) | fieldmask;
03140   a = relocation;
03141   b = val & howto->src_mask;
03142 
03143   a = (a & addrmask) >> howto->rightshift;
03144 
03145   /* If any sign bits are set, all sign bits must be set.
03146      That is, A must be a valid negative address after
03147      shifting.  */
03148   signmask = ~ (fieldmask >> 1);
03149   ss = a & signmask;
03150   if (ss != 0 && ss != ((addrmask >> howto->rightshift) & signmask))
03151     return TRUE;
03152 
03153   /* We only need this next bit of code if the sign bit of B
03154      is below the sign bit of A.  This would only happen if
03155      SRC_MASK had fewer bits than BITSIZE.  Note that if
03156      SRC_MASK has more bits than BITSIZE, we can get into
03157      trouble; we would need to verify that B is in range, as
03158      we do for A above.  */
03159   signmask = ((~ howto->src_mask) >> 1) & howto->src_mask;
03160   if ((b & signmask) != 0)
03161     {
03162       /* Set all the bits above the sign bit.  */
03163       b -= signmask <<= 1;
03164     }
03165 
03166   b = (b & addrmask) >> howto->bitpos;
03167 
03168   /* Now we can do the addition.  */
03169   sum = a + b;
03170 
03171   /* See if the result has the correct sign.  Bits above the
03172      sign bit are junk now; ignore them.  If the sum is
03173      positive, make sure we did not have all negative inputs;
03174      if the sum is negative, make sure we did not have all
03175      positive inputs.  The test below looks only at the sign
03176      bits, and it really just
03177      SIGN (A) == SIGN (B) && SIGN (A) != SIGN (SUM)
03178   */
03179   signmask = (fieldmask >> 1) + 1;
03180   if (((~ (a ^ b)) & (a ^ sum)) & signmask)
03181     return TRUE;
03182 
03183   return FALSE;
03184 }
03185 
03186 static bfd_boolean
03187 xcoff_complain_overflow_unsigned_func (input_bfd, val, relocation, howto)
03188      bfd *input_bfd;
03189      bfd_vma val;
03190      bfd_vma relocation;
03191      struct reloc_howto_struct *howto;
03192 {
03193   bfd_vma addrmask, fieldmask;
03194   bfd_vma a, b, sum;
03195 
03196   /* Get the values to be added together.  For signed and unsigned
03197      relocations, we assume that all values should be truncated to
03198      the size of an address.  For bitfields, all the bits matter.
03199      See also bfd_check_overflow.  */
03200   fieldmask = N_ONES (howto->bitsize);
03201   addrmask = N_ONES (bfd_arch_bits_per_address (input_bfd)) | fieldmask;
03202   a = relocation;
03203   b = val & howto->src_mask;
03204 
03205   /* Checking for an unsigned overflow is relatively easy:
03206      trim the addresses and add, and trim the result as well.
03207      Overflow is normally indicated when the result does not
03208      fit in the field.  However, we also need to consider the
03209      case when, e.g., fieldmask is 0x7fffffff or smaller, an
03210      input is 0x80000000, and bfd_vma is only 32 bits; then we
03211      will get sum == 0, but there is an overflow, since the
03212      inputs did not fit in the field.  Instead of doing a
03213      separate test, we can check for this by or-ing in the
03214      operands when testing for the sum overflowing its final
03215      field.  */
03216   a = (a & addrmask) >> howto->rightshift;
03217   b = (b & addrmask) >> howto->bitpos;
03218   sum = (a + b) & addrmask;
03219   if ((a | b | sum) & ~ fieldmask)
03220     return TRUE;
03221 
03222   return FALSE;
03223 }
03224 
03225 /* This is the relocation function for the RS/6000/POWER/PowerPC.
03226    This is currently the only processor which uses XCOFF; I hope that
03227    will never change.
03228 
03229    I took the relocation type definitions from two documents:
03230    the PowerPC AIX Version 4 Application Binary Interface, First
03231    Edition (April 1992), and the PowerOpen ABI, Big-Endian
03232    32-Bit Hardware Implementation (June 30, 1994).  Differences
03233    between the documents are noted below.
03234 
03235    Unsupported r_type's
03236 
03237    R_RTB:
03238    R_RRTBI:
03239    R_RRTBA:
03240 
03241    These relocs are defined by the PowerPC ABI to be
03242    relative branches which use half of the difference
03243    between the symbol and the program counter.  I can't
03244    quite figure out when this is useful.  These relocs are
03245    not defined by the PowerOpen ABI.
03246 
03247    Supported r_type's
03248 
03249    R_POS:
03250    Simple positive relocation.
03251 
03252    R_NEG:
03253    Simple negative relocation.
03254 
03255    R_REL:
03256    Simple PC relative relocation.
03257 
03258    R_TOC:
03259    TOC relative relocation.  The value in the instruction in
03260    the input file is the offset from the input file TOC to
03261    the desired location.  We want the offset from the final
03262    TOC to the desired location.  We have:
03263    isym = iTOC + in
03264    iinsn = in + o
03265    osym = oTOC + on
03266    oinsn = on + o
03267    so we must change insn by on - in.
03268 
03269    R_GL:
03270    GL linkage relocation.  The value of this relocation
03271    is the address of the entry in the TOC section.
03272 
03273    R_TCL:
03274    Local object TOC address.  I can't figure out the
03275    difference between this and case R_GL.
03276 
03277    R_TRL:
03278    TOC relative relocation.  A TOC relative load instruction
03279    which may be changed to a load address instruction.
03280    FIXME: We don't currently implement this optimization.
03281 
03282    R_TRLA:
03283    TOC relative relocation.  This is a TOC relative load
03284    address instruction which may be changed to a load
03285    instruction.  FIXME: I don't know if this is the correct
03286    implementation.
03287 
03288    R_BA:
03289    Absolute branch.  We don't want to mess with the lower
03290    two bits of the instruction.
03291 
03292    R_CAI:
03293    The PowerPC ABI defines this as an absolute call which
03294    may be modified to become a relative call.  The PowerOpen
03295    ABI does not define this relocation type.
03296 
03297    R_RBA:
03298    Absolute branch which may be modified to become a
03299    relative branch.
03300 
03301    R_RBAC:
03302    The PowerPC ABI defines this as an absolute branch to a
03303    fixed address which may be modified to an absolute branch
03304    to a symbol.  The PowerOpen ABI does not define this
03305    relocation type.
03306 
03307    R_RBRC:
03308    The PowerPC ABI defines this as an absolute branch to a
03309    fixed address which may be modified to a relative branch.
03310    The PowerOpen ABI does not define this relocation type.
03311 
03312    R_BR:
03313    Relative branch.  We don't want to mess with the lower
03314    two bits of the instruction.
03315 
03316    R_CREL:
03317    The PowerPC ABI defines this as a relative call which may
03318    be modified to become an absolute call.  The PowerOpen
03319    ABI does not define this relocation type.
03320 
03321    R_RBR:
03322    A relative branch which may be modified to become an
03323    absolute branch.  FIXME: We don't implement this,
03324    although we should for symbols of storage mapping class
03325    XMC_XO.
03326 
03327    R_RL:
03328    The PowerPC AIX ABI describes this as a load which may be
03329    changed to a load address.  The PowerOpen ABI says this
03330    is the same as case R_POS.
03331 
03332    R_RLA:
03333    The PowerPC AIX ABI describes this as a load address
03334    which may be changed to a load.  The PowerOpen ABI says
03335    this is the same as R_POS.
03336 */
03337 
03338 bfd_boolean
03339 xcoff_ppc_relocate_section (output_bfd, info, input_bfd,
03340                          input_section, contents, relocs, syms,
03341                          sections)
03342      bfd *output_bfd;
03343      struct bfd_link_info *info;
03344      bfd *input_bfd;
03345      asection *input_section;
03346      bfd_byte *contents;
03347      struct internal_reloc *relocs;
03348      struct internal_syment *syms;
03349      asection **sections;
03350 {
03351   struct internal_reloc *rel;
03352   struct internal_reloc *relend;
03353 
03354   rel = relocs;
03355   relend = rel + input_section->reloc_count;
03356   for (; rel < relend; rel++)
03357     {
03358       long symndx;
03359       struct xcoff_link_hash_entry *h;
03360       struct internal_syment *sym;
03361       bfd_vma addend;
03362       bfd_vma val;
03363       struct reloc_howto_struct howto;
03364       bfd_vma relocation;
03365       bfd_vma value_to_relocate;
03366       bfd_vma address;
03367       bfd_byte *location;
03368 
03369       /* Relocation type R_REF is a special relocation type which is
03370         merely used to prevent garbage collection from occurring for
03371         the csect including the symbol which it references.  */
03372       if (rel->r_type == R_REF)
03373        continue;
03374 
03375       /* howto */
03376       howto.type = rel->r_type;
03377       howto.rightshift = 0;
03378       howto.bitsize = (rel->r_size & 0x1f) + 1;
03379       howto.size = howto.bitsize > 16 ? 2 : 1;
03380       howto.pc_relative = FALSE;
03381       howto.bitpos = 0;
03382       howto.complain_on_overflow = (rel->r_size & 0x80
03383                                 ? complain_overflow_signed
03384                                 : complain_overflow_bitfield);
03385       howto.special_function = NULL;
03386       howto.name = "internal";
03387       howto.partial_inplace = TRUE;
03388       howto.src_mask = howto.dst_mask = N_ONES (howto.bitsize);
03389       howto.pcrel_offset = FALSE;
03390 
03391       /* symbol */
03392       val = 0;
03393       addend = 0;
03394       h = NULL;
03395       sym = NULL;
03396       symndx = rel->r_symndx;
03397 
03398       if (-1 != symndx)
03399        {
03400          asection *sec;
03401 
03402          h = obj_xcoff_sym_hashes (input_bfd)[symndx];
03403          sym = syms + symndx;
03404          addend = - sym->n_value;
03405 
03406          if (NULL == h)
03407            {
03408              sec = sections[symndx];
03409              /* Hack to make sure we use the right TOC anchor value
03410                if this reloc is against the TOC anchor.  */
03411              if (sec->name[3] == '0'
03412                 && strcmp (sec->name, ".tc0") == 0)
03413               val = xcoff_data (output_bfd)->toc;
03414              else
03415               val = (sec->output_section->vma
03416                      + sec->output_offset
03417                      + sym->n_value
03418                      - sec->vma);
03419            }
03420          else
03421            {
03422              if (h->root.type == bfd_link_hash_defined
03423                 || h->root.type == bfd_link_hash_defweak)
03424               {
03425                 sec = h->root.u.def.section;
03426                 val = (h->root.u.def.value
03427                       + sec->output_section->vma
03428                       + sec->output_offset);
03429               }
03430              else if (h->root.type == bfd_link_hash_common)
03431               {
03432                 sec = h->root.u.c.p->section;
03433                 val = (sec->output_section->vma
03434                       + sec->output_offset);
03435 
03436               }
03437              else if ((0 == (h->flags & (XCOFF_DEF_DYNAMIC | XCOFF_IMPORT)))
03438                      && ! info->relocatable)
03439               {
03440                 if (! ((*info->callbacks->undefined_symbol)
03441                       (info, h->root.root.string, input_bfd, input_section,
03442                        rel->r_vaddr - input_section->vma, TRUE)))
03443                   return FALSE;
03444 
03445                 /* Don't try to process the reloc.  It can't help, and
03446                    it may generate another error.  */
03447                 continue;
03448               }
03449            }
03450        }
03451 
03452       if (rel->r_type >= XCOFF_MAX_CALCULATE_RELOCATION
03453          || !((*xcoff_calculate_relocation[rel->r_type])
03454               (input_bfd, input_section, output_bfd, rel, sym, &howto, val,
03455               addend, &relocation, contents)))
03456        return FALSE;
03457 
03458       /* address */
03459       address = rel->r_vaddr - input_section->vma;
03460       location = contents + address;
03461 
03462       if (address > input_section->size)
03463        abort ();
03464 
03465       /* Get the value we are going to relocate.  */
03466       if (1 == howto.size)
03467        value_to_relocate = bfd_get_16 (input_bfd, location);
03468       else
03469        value_to_relocate = bfd_get_32 (input_bfd, location);
03470 
03471       /* overflow.
03472 
03473         FIXME: We may drop bits during the addition
03474         which we don't check for.  We must either check at every single
03475         operation, which would be tedious, or we must do the computations
03476         in a type larger than bfd_vma, which would be inefficient.  */
03477 
03478       if ((unsigned int) howto.complain_on_overflow
03479          >= XCOFF_MAX_COMPLAIN_OVERFLOW)
03480        abort ();
03481 
03482       if (((*xcoff_complain_overflow[howto.complain_on_overflow])
03483           (input_bfd, value_to_relocate, relocation, &howto)))
03484        {
03485          const char *name;
03486          char buf[SYMNMLEN + 1];
03487          char reloc_type_name[10];
03488 
03489          if (symndx == -1)
03490            {
03491              name = "*ABS*";
03492            }
03493          else if (h != NULL)
03494            {
03495              name = NULL;
03496            }
03497          else
03498            {
03499              name = _bfd_coff_internal_syment_name (input_bfd, sym, buf);
03500              if (name == NULL)
03501               name = "UNKNOWN";
03502            }
03503          sprintf (reloc_type_name, "0x%02x", rel->r_type);
03504 
03505          if (! ((*info->callbacks->reloc_overflow)
03506                (info, (h ? &h->root : NULL), name, reloc_type_name,
03507                 (bfd_vma) 0, input_bfd, input_section,
03508                 rel->r_vaddr - input_section->vma)))
03509            return FALSE;
03510        }
03511 
03512       /* Add RELOCATION to the right bits of VALUE_TO_RELOCATE.  */
03513       value_to_relocate = ((value_to_relocate & ~howto.dst_mask)
03514                         | (((value_to_relocate & howto.src_mask)
03515                             + relocation) & howto.dst_mask));
03516 
03517       /* Put the value back in the object file.  */
03518       if (1 == howto.size)
03519        bfd_put_16 (input_bfd, value_to_relocate, location);
03520       else
03521        bfd_put_32 (input_bfd, value_to_relocate, location);
03522     }
03523 
03524   return TRUE;
03525 }
03526 
03527 static bfd_boolean
03528 _bfd_xcoff_put_ldsymbol_name (abfd, ldinfo, ldsym, name)
03529      bfd *abfd ATTRIBUTE_UNUSED;
03530         struct xcoff_loader_info *ldinfo;
03531         struct internal_ldsym *ldsym;
03532         const char *name;
03533 {
03534   size_t len;
03535   len = strlen (name);
03536 
03537   if (len <= SYMNMLEN)
03538     strncpy (ldsym->_l._l_name, name, SYMNMLEN);
03539   else
03540     {
03541       if (ldinfo->string_size + len + 3 > ldinfo->string_alc)
03542        {
03543          bfd_size_type newalc;
03544          char *newstrings;
03545 
03546          newalc = ldinfo->string_alc * 2;
03547          if (newalc == 0)
03548            newalc = 32;
03549          while (ldinfo->string_size + len + 3 > newalc)
03550            newalc *= 2;
03551 
03552          newstrings = bfd_realloc (ldinfo->strings, newalc);
03553          if (newstrings == NULL)
03554            {
03555              ldinfo->failed = TRUE;
03556              return FALSE;
03557            }
03558          ldinfo->string_alc = newalc;
03559          ldinfo->strings = newstrings;
03560        }
03561 
03562       bfd_put_16 (ldinfo->output_bfd, (bfd_vma) (len + 1),
03563                 ldinfo->strings + ldinfo->string_size);
03564       strcpy (ldinfo->strings + ldinfo->string_size + 2, name);
03565       ldsym->_l._l_l._l_zeroes = 0;
03566       ldsym->_l._l_l._l_offset = ldinfo->string_size + 2;
03567       ldinfo->string_size += len + 3;
03568     }
03569 
03570   return TRUE;
03571 }
03572 
03573 static bfd_boolean
03574 _bfd_xcoff_put_symbol_name (bfd *abfd, struct bfd_strtab_hash *strtab,
03575                          struct internal_syment *sym,
03576                          const char *name)
03577 {
03578   if (strlen (name) <= SYMNMLEN)
03579     {
03580       strncpy (sym->_n._n_name, name, SYMNMLEN);
03581     }
03582   else
03583     {
03584       bfd_boolean hash;
03585       bfd_size_type indx;
03586 
03587       hash = TRUE;
03588       if ((abfd->flags & BFD_TRADITIONAL_FORMAT) != 0)
03589        hash = FALSE;
03590       indx = _bfd_stringtab_add (strtab, name, hash, FALSE);
03591       if (indx == (bfd_size_type) -1)
03592        return FALSE;
03593       sym->_n._n_n._n_zeroes = 0;
03594       sym->_n._n_n._n_offset = STRING_SIZE_SIZE + indx;
03595     }
03596   return TRUE;
03597 }
03598 
03599 static asection *
03600 xcoff_create_csect_from_smclas (abfd, aux, symbol_name)
03601      bfd *abfd;
03602      union internal_auxent *aux;
03603      const char *symbol_name;
03604 {
03605   asection *return_value = NULL;
03606 
03607   /* .sv64 = x_smclas == 17
03608      This is an invalid csect for 32 bit apps.  */
03609   static const char *names[19] =
03610   {
03611     ".pr", ".ro", ".db", ".tc", ".ua", ".rw", ".gl", ".xo",
03612     ".sv", ".bs", ".ds", ".uc", ".ti", ".tb", NULL, ".tc0",
03613     ".td", NULL, ".sv3264"
03614   };
03615 
03616   if ((19 >= aux->x_csect.x_smclas)
03617       && (NULL != names[aux->x_csect.x_smclas]))
03618     {
03619       return_value = bfd_make_section_anyway
03620        (abfd, names[aux->x_csect.x_smclas]);
03621     }
03622   else
03623     {
03624       (*_bfd_error_handler)
03625        (_("%B: symbol `%s' has unrecognized smclas %d"),
03626         abfd, symbol_name, aux->x_csect.x_smclas);
03627       bfd_set_error (bfd_error_bad_value);
03628     }
03629 
03630   return return_value;
03631 }
03632 
03633 static bfd_boolean
03634 xcoff_is_lineno_count_overflow (abfd, value)
03635     bfd *abfd ATTRIBUTE_UNUSED;
03636        bfd_vma value;
03637 {
03638   if (0xffff <= value)
03639     return TRUE;
03640 
03641   return FALSE;
03642 }
03643 
03644 static bfd_boolean
03645 xcoff_is_reloc_count_overflow (abfd, value)
03646     bfd *abfd ATTRIBUTE_UNUSED;
03647        bfd_vma value;
03648 {
03649   if (0xffff <= value)
03650     return TRUE;
03651 
03652   return FALSE;
03653 }
03654 
03655 static bfd_vma
03656 xcoff_loader_symbol_offset (abfd, ldhdr)
03657     bfd *abfd;
03658     struct internal_ldhdr *ldhdr ATTRIBUTE_UNUSED;
03659 {
03660   return bfd_xcoff_ldhdrsz (abfd);
03661 }
03662 
03663 static bfd_vma
03664 xcoff_loader_reloc_offset (abfd, ldhdr)
03665     bfd *abfd;
03666     struct internal_ldhdr *ldhdr;
03667 {
03668   return bfd_xcoff_ldhdrsz (abfd) + ldhdr->l_nsyms * bfd_xcoff_ldsymsz (abfd);
03669 }
03670 
03671 static bfd_boolean
03672 xcoff_generate_rtinit  (abfd, init, fini, rtld)
03673      bfd *abfd;
03674      const char *init;
03675      const char *fini;
03676      bfd_boolean rtld;
03677 {
03678   bfd_byte filehdr_ext[FILHSZ];
03679   bfd_byte scnhdr_ext[SCNHSZ];
03680   bfd_byte syment_ext[SYMESZ * 10];
03681   bfd_byte reloc_ext[RELSZ * 3];
03682   bfd_byte *data_buffer;
03683   bfd_size_type data_buffer_size;
03684   bfd_byte *string_table = NULL, *st_tmp = NULL;
03685   bfd_size_type string_table_size;
03686   bfd_vma val;
03687   size_t initsz, finisz;
03688   struct internal_filehdr filehdr;
03689   struct internal_scnhdr scnhdr;
03690   struct internal_syment syment;
03691   union internal_auxent auxent;
03692   struct internal_reloc reloc;
03693 
03694   char *data_name = ".data";
03695   char *rtinit_name = "__rtinit";
03696   char *rtld_name = "__rtld";
03697 
03698   if (! bfd_xcoff_rtinit_size (abfd))
03699     return FALSE;
03700 
03701   initsz = (init == NULL ? 0 : 1 + strlen (init));
03702   finisz = (fini == NULL ? 0 : 1 + strlen (fini));
03703 
03704   /* file header */
03705   memset (filehdr_ext, 0, FILHSZ);
03706   memset (&filehdr, 0, sizeof (struct internal_filehdr));
03707   filehdr.f_magic = bfd_xcoff_magic_number (abfd);
03708   filehdr.f_nscns = 1;
03709   filehdr.f_timdat = 0;
03710   filehdr.f_nsyms = 0;  /* at least 6, no more than 10 */
03711   filehdr.f_symptr = 0; /* set below */
03712   filehdr.f_opthdr = 0;
03713   filehdr.f_flags = 0;
03714 
03715   /* section header */
03716   memset (scnhdr_ext, 0, SCNHSZ);
03717   memset (&scnhdr, 0, sizeof (struct internal_scnhdr));
03718   memcpy (scnhdr.s_name, data_name, strlen (data_name));
03719   scnhdr.s_paddr = 0;
03720   scnhdr.s_vaddr = 0;
03721   scnhdr.s_size = 0;    /* set below */
03722   scnhdr.s_scnptr = FILHSZ + SCNHSZ;
03723   scnhdr.s_relptr = 0;  /* set below */
03724   scnhdr.s_lnnoptr = 0;
03725   scnhdr.s_nreloc = 0;  /* either 1 or 2 */
03726   scnhdr.s_nlnno = 0;
03727   scnhdr.s_flags = STYP_DATA;
03728 
03729   /* .data
03730      0x0000         0x00000000 : rtl
03731      0x0004         0x00000010 : offset to init, or 0
03732      0x0008         0x00000028 : offset to fini, or 0
03733      0x000C         0x0000000C : size of descriptor
03734      0x0010         0x00000000 : init, needs a reloc
03735      0x0014         0x00000040 : offset to init name
03736      0x0018         0x00000000 : flags, padded to a word
03737      0x001C         0x00000000 : empty init
03738      0x0020         0x00000000 :
03739      0x0024         0x00000000 :
03740      0x0028         0x00000000 : fini, needs a reloc
03741      0x002C         0x00000??? : offset to fini name
03742      0x0030         0x00000000 : flags, padded to a word
03743      0x0034         0x00000000 : empty fini
03744      0x0038         0x00000000 :
03745      0x003C         0x00000000 :
03746      0x0040         init name
03747      0x0040 + initsz  fini name */
03748 
03749   data_buffer_size = 0x0040 + initsz + finisz;
03750   data_buffer_size = (data_buffer_size + 7) &~ (bfd_size_type) 7;
03751   data_buffer = NULL;
03752   data_buffer = (bfd_byte *) bfd_zmalloc (data_buffer_size);
03753   if (data_buffer == NULL)
03754     return FALSE;
03755 
03756   if (initsz)
03757     {
03758       val = 0x10;
03759       bfd_h_put_32 (abfd, val, &data_buffer[0x04]);
03760       val = 0x40;
03761       bfd_h_put_32 (abfd, val, &data_buffer[0x14]);
03762       memcpy (&data_buffer[val], init, initsz);
03763     }
03764 
03765   if (finisz)
03766     {
03767       val = 0x28;
03768       bfd_h_put_32 (abfd, val, &data_buffer[0x08]);
03769       val = 0x40 + initsz;
03770       bfd_h_put_32 (abfd, val, &data_buffer[0x2C]);
03771       memcpy (&data_buffer[val], fini, finisz);
03772     }
03773 
03774   val = 0x0C;
03775   bfd_h_put_32 (abfd, val, &data_buffer[0x0C]);
03776 
03777   scnhdr.s_size = data_buffer_size;
03778 
03779   /* string table */
03780   string_table_size = 0;
03781   if (initsz > 9)
03782     string_table_size += initsz;
03783   if (finisz > 9)
03784     string_table_size += finisz;
03785   if (string_table_size)
03786     {
03787       string_table_size += 4;
03788       string_table = (bfd_byte *) bfd_zmalloc (string_table_size);
03789       if (string_table == NULL)
03790        return FALSE;
03791 
03792       val = string_table_size;
03793       bfd_h_put_32 (abfd, val, &string_table[0]);
03794       st_tmp = string_table + 4;
03795     }
03796 
03797   /* symbols
03798      0. .data csect
03799      2. __rtinit
03800      4. init function
03801      6. fini function
03802      8. __rtld  */
03803   memset (syment_ext, 0, 10 * SYMESZ);
03804   memset (reloc_ext, 0, 3 * RELSZ);
03805 
03806   /* .data csect */
03807   memset (&syment, 0, sizeof (struct internal_syment));
03808   memset (&auxent, 0, sizeof (union internal_auxent));
03809   memcpy (syment._n._n_name, data_name, strlen (data_name));
03810   syment.n_scnum = 1;
03811   syment.n_sclass = C_HIDEXT;
03812   syment.n_numaux = 1;
03813   auxent.x_csect.x_scnlen.l = data_buffer_size;
03814   auxent.x_csect.x_smtyp = 3 << 3 | XTY_SD;
03815   auxent.x_csect.x_smclas = XMC_RW;
03816   bfd_coff_swap_sym_out (abfd, &syment,
03817                       &syment_ext[filehdr.f_nsyms * SYMESZ]);
03818   bfd_coff_swap_aux_out (abfd, &auxent, syment.n_type, syment.n_sclass, 0,
03819                       syment.n_numaux,
03820                       &syment_ext[(filehdr.f_nsyms + 1) * SYMESZ]);
03821   filehdr.f_nsyms += 2;
03822 
03823   /* __rtinit */
03824   memset (&syment, 0, sizeof (struct internal_syment));
03825   memset (&auxent, 0, sizeof (union internal_auxent));
03826   memcpy (syment._n._n_name, rtinit_name, strlen (rtinit_name));
03827   syment.n_scnum = 1;
03828   syment.n_sclass = C_EXT;
03829   syment.n_numaux = 1;
03830   auxent.x_csect.x_smtyp = XTY_LD;
03831   auxent.x_csect.x_smclas = XMC_RW;
03832   bfd_coff_swap_sym_out (abfd, &syment,
03833                       &syment_ext[filehdr.f_nsyms * SYMESZ]);
03834   bfd_coff_swap_aux_out (abfd, &auxent, syment.n_type, syment.n_sclass, 0,
03835                       syment.n_numaux,
03836                       &syment_ext[(filehdr.f_nsyms + 1) * SYMESZ]);
03837   filehdr.f_nsyms += 2;
03838 
03839   /* init */
03840   if (initsz)
03841     {
03842       memset (&syment, 0, sizeof (struct internal_syment));
03843       memset (&auxent, 0, sizeof (union internal_auxent));
03844 
03845       if (initsz > 9)
03846        {
03847          syment._n._n_n._n_offset = st_tmp - string_table;
03848          memcpy (st_tmp, init, initsz);
03849          st_tmp += initsz;
03850        }
03851       else
03852        memcpy (syment._n._n_name, init, initsz - 1);
03853 
03854       syment.n_sclass = C_EXT;
03855       syment.n_numaux = 1;
03856       bfd_coff_swap_sym_out (abfd, &syment,
03857                           &syment_ext[filehdr.f_nsyms * SYMESZ]);
03858       bfd_coff_swap_aux_out (abfd, &auxent, syment.n_type, syment.n_sclass, 0,
03859                           syment.n_numaux,
03860                           &syment_ext[(filehdr.f_nsyms + 1) * SYMESZ]);
03861 
03862       /* reloc */
03863       memset (&reloc, 0, sizeof (struct internal_reloc));
03864       reloc.r_vaddr = 0x0010;
03865       reloc.r_symndx = filehdr.f_nsyms;
03866       reloc.r_type = R_POS;
03867       reloc.r_size = 31;
03868       bfd_coff_swap_reloc_out (abfd, &reloc, &reloc_ext[0]);
03869 
03870       filehdr.f_nsyms += 2;
03871       scnhdr.s_nreloc += 1;
03872     }
03873 
03874   /* fini */
03875   if (finisz)
03876     {
03877       memset (&syment, 0, sizeof (struct internal_syment));
03878       memset (&auxent, 0, sizeof (union internal_auxent));
03879 
03880       if (finisz > 9)
03881        {
03882          syment._n._n_n._n_offset = st_tmp - string_table;
03883          memcpy (st_tmp, fini, finisz);
03884          st_tmp += finisz;
03885        }
03886       else
03887        memcpy (syment._n._n_name, fini, finisz - 1);
03888 
03889       syment.n_sclass = C_EXT;
03890       syment.n_numaux = 1;
03891       bfd_coff_swap_sym_out (abfd, &syment,
03892                           &syment_ext[filehdr.f_nsyms * SYMESZ]);
03893       bfd_coff_swap_aux_out (abfd, &auxent, syment.n_type, syment.n_sclass, 0,
03894                           syment.n_numaux,
03895                           &syment_ext[(filehdr.f_nsyms + 1) * SYMESZ]);
03896 
03897       /* reloc */
03898       memset (&reloc, 0, sizeof (struct internal_reloc));
03899       reloc.r_vaddr = 0x0028;
03900       reloc.r_symndx = filehdr.f_nsyms;
03901       reloc.r_type = R_POS;
03902       reloc.r_size = 31;
03903       bfd_coff_swap_reloc_out (abfd, &reloc,
03904                             &reloc_ext[scnhdr.s_nreloc * RELSZ]);
03905 
03906       filehdr.f_nsyms += 2;
03907       scnhdr.s_nreloc += 1;
03908     }
03909 
03910   if (rtld)
03911     {
03912       memset (&syment, 0, sizeof (struct internal_syment));
03913       memset (&auxent, 0, sizeof (union internal_auxent));
03914       memcpy (syment._n._n_name, rtld_name, strlen (rtld_name));
03915       syment.n_sclass = C_EXT;
03916       syment.n_numaux = 1;
03917       bfd_coff_swap_sym_out (abfd, &syment,
03918                           &syment_ext[filehdr.f_nsyms * SYMESZ]);
03919       bfd_coff_swap_aux_out (abfd, &auxent, syment.n_type, syment.n_sclass, 0,
03920                           syment.n_numaux,
03921                           &syment_ext[(filehdr.f_nsyms + 1) * SYMESZ]);
03922 
03923       /* reloc */
03924       memset (&reloc, 0, sizeof (struct internal_reloc));
03925       reloc.r_vaddr = 0x0000;
03926       reloc.r_symndx = filehdr.f_nsyms;
03927       reloc.r_type = R_POS;
03928       reloc.r_size = 31;
03929       bfd_coff_swap_reloc_out (abfd, &reloc,
03930                             &reloc_ext[scnhdr.s_nreloc * RELSZ]);
03931 
03932       filehdr.f_nsyms += 2;
03933       scnhdr.s_nreloc += 1;
03934     }
03935 
03936   scnhdr.s_relptr = scnhdr.s_scnptr + data_buffer_size;
03937   filehdr.f_symptr = scnhdr.s_relptr + scnhdr.s_nreloc * RELSZ;
03938 
03939   bfd_coff_swap_filehdr_out (abfd, &filehdr, filehdr_ext);
03940   bfd_bwrite (filehdr_ext, FILHSZ, abfd);
03941   bfd_coff_swap_scnhdr_out (abfd, &scnhdr, scnhdr_ext);
03942   bfd_bwrite (scnhdr_ext, SCNHSZ, abfd);
03943   bfd_bwrite (data_buffer, data_buffer_size, abfd);
03944   bfd_bwrite (reloc_ext, scnhdr.s_nreloc * RELSZ, abfd);
03945   bfd_bwrite (syment_ext, filehdr.f_nsyms * SYMESZ, abfd);
03946   bfd_bwrite (string_table, string_table_size, abfd);
03947 
03948   free (data_buffer);
03949   data_buffer = NULL;
03950 
03951   return TRUE;
03952 }
03953 
03954 
03955 static reloc_howto_type xcoff_dynamic_reloc =
03956 HOWTO (0,                   /* type */
03957        0,                   /* rightshift */
03958        2,                   /* size (0 = byte, 1 = short, 2 = long) */
03959        32,                  /* bitsize */
03960        FALSE,               /* pc_relative */
03961        0,                   /* bitpos */
03962        complain_overflow_bitfield, /* complain_on_overflow */
03963        0,                   /* special_function */
03964        "R_POS",                    /* name */
03965        TRUE,                /* partial_inplace */
03966        0xffffffff,          /* src_mask */
03967        0xffffffff,          /* dst_mask */
03968        FALSE);                     /* pcrel_offset */
03969 
03970 /*  glink
03971 
03972    The first word of global linkage code must be modified by filling in
03973    the correct TOC offset.  */
03974 
03975 static unsigned long xcoff_glink_code[9] =
03976   {
03977     0x81820000,      /* lwz r12,0(r2) */
03978     0x90410014,      /* stw r2,20(r1) */
03979     0x800c0000,      /* lwz r0,0(r12) */
03980     0x804c0004,      /* lwz r2,4(r12) */
03981     0x7c0903a6,      /* mtctr r0 */
03982     0x4e800420,      /* bctr */
03983     0x00000000,      /* start of traceback table */
03984     0x000c8000,      /* traceback table */
03985     0x00000000,      /* traceback table */
03986   };
03987 
03988 
03989 static const struct xcoff_backend_data_rec bfd_xcoff_backend_data =
03990   {
03991     { /* COFF backend, defined in libcoff.h.  */
03992       _bfd_xcoff_swap_aux_in,
03993       _bfd_xcoff_swap_sym_in,
03994       coff_swap_lineno_in,
03995       _bfd_xcoff_swap_aux_out,
03996       _bfd_xcoff_swap_sym_out,
03997       coff_swap_lineno_out,
03998       xcoff_swap_reloc_out,
03999       coff_swap_filehdr_out,
04000       coff_swap_aouthdr_out,
04001       coff_swap_scnhdr_out,
04002       FILHSZ,
04003       AOUTSZ,
04004       SCNHSZ,
04005       SYMESZ,
04006       AUXESZ,
04007       RELSZ,
04008       LINESZ,
04009       FILNMLEN,
04010       TRUE,                 /* _bfd_coff_long_filenames */
04011       FALSE,                /* _bfd_coff_long_section_names */
04012       3,                    /* _bfd_coff_default_section_alignment_power */
04013       FALSE,                /* _bfd_coff_force_symnames_in_strings */
04014       2,                    /* _bfd_coff_debug_string_prefix_length */
04015       coff_swap_filehdr_in,
04016       coff_swap_aouthdr_in,
04017       coff_swap_scnhdr_in,
04018       xcoff_swap_reloc_in,
04019       coff_bad_format_hook,
04020       coff_set_arch_mach_hook,
04021       coff_mkobject_hook,
04022       styp_to_sec_flags,
04023       coff_set_alignment_hook,
04024       coff_slurp_symbol_table,
04025       symname_in_debug_hook,
04026       coff_pointerize_aux_hook,
04027       coff_print_aux,
04028       dummy_reloc16_extra_cases,
04029       dummy_reloc16_estimate,
04030       NULL,                 /* bfd_coff_sym_is_global */
04031       coff_compute_section_file_positions,
04032       NULL,                 /* _bfd_coff_start_final_link */
04033       xcoff_ppc_relocate_section,
04034       coff_rtype_to_howto,
04035       NULL,                 /* _bfd_coff_adjust_symndx */
04036       _bfd_generic_link_add_one_symbol,
04037       coff_link_output_has_begun,
04038       coff_final_link_postscript
04039     },
04040 
04041     0x01DF,                 /* magic number */
04042     bfd_arch_rs6000,
04043     bfd_mach_rs6k,
04044 
04045     /* Function pointers to xcoff specific swap routines.  */
04046     xcoff_swap_ldhdr_in,
04047     xcoff_swap_ldhdr_out,
04048     xcoff_swap_ldsym_in,
04049     xcoff_swap_ldsym_out,
04050     xcoff_swap_ldrel_in,
04051     xcoff_swap_ldrel_out,
04052 
04053     /* Sizes.  */
04054     LDHDRSZ,
04055     LDSYMSZ,
04056     LDRELSZ,
04057     12,                            /* _xcoff_function_descriptor_size */
04058     SMALL_AOUTSZ,
04059 
04060     /* Versions.  */
04061     1,                      /* _xcoff_ldhdr_version */
04062 
04063     _bfd_xcoff_put_symbol_name,
04064     _bfd_xcoff_put_ldsymbol_name,
04065     &xcoff_dynamic_reloc,
04066     xcoff_create_csect_from_smclas,
04067 
04068     /* Lineno and reloc count overflow.  */
04069     xcoff_is_lineno_count_overflow,
04070     xcoff_is_reloc_count_overflow,
04071 
04072     xcoff_loader_symbol_offset,
04073     xcoff_loader_reloc_offset,
04074 
04075     /* glink.  */
04076     &xcoff_glink_code[0],
04077     36,                            /* _xcoff_glink_size */
04078 
04079     /* rtinit */
04080     64,                            /* _xcoff_rtinit_size */
04081     xcoff_generate_rtinit,
04082   };
04083 
04084 /* The transfer vector that leads the outside world to all of the above.  */
04085 const bfd_target rs6000coff_vec =
04086   {
04087     "aixcoff-rs6000",
04088     bfd_target_xcoff_flavour,
04089     BFD_ENDIAN_BIG,         /* data byte order is big */
04090     BFD_ENDIAN_BIG,         /* header byte order is big */
04091 
04092     (HAS_RELOC | EXEC_P | HAS_LINENO | HAS_DEBUG | DYNAMIC
04093      | HAS_SYMS | HAS_LOCALS | WP_TEXT),
04094 
04095     SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_CODE | SEC_DATA,
04096     0,                      /* leading char */
04097     '/',                    /* ar_pad_char */
04098     15,                            /* ar_max_namelen */
04099 
04100     /* data */
04101     bfd_getb64,
04102     bfd_getb_signed_64,
04103     bfd_putb64,
04104     bfd_getb32,
04105     bfd_getb_signed_32,
04106     bfd_putb32,
04107     bfd_getb16,
04108     bfd_getb_signed_16,
04109     bfd_putb16,
04110 
04111     /* hdrs */
04112     bfd_getb64,
04113     bfd_getb_signed_64,
04114     bfd_putb64,
04115     bfd_getb32,
04116     bfd_getb_signed_32,
04117     bfd_putb32,
04118     bfd_getb16,
04119     bfd_getb_signed_16,
04120     bfd_putb16,
04121 
04122     { /* bfd_check_format */
04123       _bfd_dummy_target,
04124       coff_object_p,
04125       _bfd_xcoff_archive_p,
04126       CORE_FILE_P
04127     },
04128 
04129     { /* bfd_set_format */
04130       bfd_false,
04131       coff_mkobject,
04132       _bfd_generic_mkarchive,
04133       bfd_false
04134     },
04135 
04136     {/* bfd_write_contents */
04137       bfd_false,
04138       coff_write_object_contents,
04139       _bfd_xcoff_write_archive_contents,
04140       bfd_false
04141     },
04142 
04143     /* Generic */
04144     bfd_true,
04145     bfd_true,
04146     coff_new_section_hook,
04147     _bfd_generic_get_section_contents,
04148     _bfd_generic_get_section_contents_in_window,
04149 
04150     /* Copy */
04151     _bfd_xcoff_copy_private_bfd_data,
04152     ((bfd_boolean (*) (bfd *, bfd *)) bfd_true),
04153     _bfd_generic_init_private_section_data,
04154     ((bfd_boolean (*) (bfd *, asection *, bfd *, asection *)) bfd_true),
04155     ((bfd_boolean (*) (bfd *, asymbol *, bfd *, asymbol *)) bfd_true),
04156     ((bfd_boolean (*) (bfd *, bfd *)) bfd_true),
04157     ((bfd_boolean (*) (bfd *, flagword)) bfd_true),
04158     ((bfd_boolean (*) (bfd *, void * )) bfd_true),
04159 
04160     /* Core */
04161     coff_core_file_failing_command,
04162     coff_core_file_failing_signal,
04163     coff_core_file_matches_executable_p,
04164 
04165     /* Archive */
04166     _bfd_xcoff_slurp_armap,
04167     bfd_false,
04168     ((bfd_boolean (*) (bfd *, char **, bfd_size_type *, const char **)) bfd_false),
04169     bfd_dont_truncate_arname,
04170     _bfd_xcoff_write_armap,
04171     _bfd_xcoff_read_ar_hdr,
04172     _bfd_xcoff_openr_next_archived_file,
04173     _bfd_generic_get_elt_at_index,
04174     _bfd_xcoff_stat_arch_elt,
04175     bfd_true,
04176 
04177     /* Symbols */
04178     coff_get_symtab_upper_bound,
04179     coff_canonicalize_symtab,
04180     coff_make_empty_symbol,
04181     coff_print_symbol,
04182     coff_get_symbol_info,
04183     _bfd_xcoff_is_local_label_name,
04184     coff_bfd_is_target_special_symbol,
04185     coff_get_lineno,
04186     coff_find_nearest_line,
04187     _bfd_generic_find_line,
04188     coff_find_inliner_info,
04189     coff_bfd_make_debug_symbol,
04190     _bfd_generic_read_minisymbols,
04191     _bfd_generic_minisymbol_to_symbol,
04192 
04193     /* Reloc */
04194     coff_get_reloc_upper_bound,
04195     coff_canonicalize_reloc,
04196     _bfd_xcoff_reloc_type_lookup,
04197     _bfd_xcoff_reloc_name_lookup,
04198 
04199     /* Write */
04200     coff_set_arch_mach,
04201     coff_set_section_contents,
04202 
04203     /* Link */
04204     _bfd_xcoff_sizeof_headers,
04205     bfd_generic_get_relocated_section_contents,
04206     bfd_generic_relax_section,
04207     _bfd_xcoff_bfd_link_hash_table_create,
04208     _bfd_generic_link_hash_table_free,
04209     _bfd_xcoff_bfd_link_add_symbols,
04210     _bfd_generic_link_just_syms,
04211     _bfd_xcoff_bfd_final_link,
04212     _bfd_generic_link_split_section,
04213     bfd_generic_gc_sections,
04214     bfd_generic_merge_sections,
04215     bfd_generic_is_group_section,
04216     bfd_generic_discard_group,
04217     _bfd_generic_section_already_linked,
04218 
04219     /* Dynamic */
04220     _bfd_xcoff_get_dynamic_symtab_upper_bound,
04221     _bfd_xcoff_canonicalize_dynamic_symtab,
04222     _bfd_nodynamic_get_synthetic_symtab,
04223     _bfd_xcoff_get_dynamic_reloc_upper_bound,
04224     _bfd_xcoff_canonicalize_dynamic_reloc,
04225 
04226     /* Opposite endian version, none exists */
04227     NULL,
04228 
04229     (void *) &bfd_xcoff_backend_data,
04230   };
04231 
04232 /* xcoff-powermac target
04233    Old target.
04234    Only difference between this target and the rs6000 target is the
04235    the default architecture and machine type used in coffcode.h
04236 
04237    PowerPC Macs use the same magic numbers as RS/6000
04238    (because that's how they were bootstrapped originally),
04239    but they are always PowerPC architecture.  */
04240 static const struct xcoff_backend_data_rec bfd_pmac_xcoff_backend_data =
04241   {
04242     { /* COFF backend, defined in libcoff.h.  */
04243       _bfd_xcoff_swap_aux_in,
04244       _bfd_xcoff_swap_sym_in,
04245       coff_swap_lineno_in,
04246       _bfd_xcoff_swap_aux_out,
04247       _bfd_xcoff_swap_sym_out,
04248       coff_swap_lineno_out,
04249       xcoff_swap_reloc_out,
04250       coff_swap_filehdr_out,
04251       coff_swap_aouthdr_out,
04252       coff_swap_scnhdr_out,
04253       FILHSZ,
04254       AOUTSZ,
04255       SCNHSZ,
04256       SYMESZ,
04257       AUXESZ,
04258       RELSZ,
04259       LINESZ,
04260       FILNMLEN,
04261       TRUE,                 /* _bfd_coff_long_filenames */
04262       FALSE,                /* _bfd_coff_long_section_names */
04263       3,                    /* _bfd_coff_default_section_alignment_power */
04264       FALSE,                /* _bfd_coff_force_symnames_in_strings */
04265       2,                    /* _bfd_coff_debug_string_prefix_length */
04266       coff_swap_filehdr_in,
04267       coff_swap_aouthdr_in,
04268       coff_swap_scnhdr_in,
04269       xcoff_swap_reloc_in,
04270       coff_bad_format_hook,
04271       coff_set_arch_mach_hook,
04272       coff_mkobject_hook,
04273       styp_to_sec_flags,
04274       coff_set_alignment_hook,
04275       coff_slurp_symbol_table,
04276       symname_in_debug_hook,
04277       coff_pointerize_aux_hook,
04278       coff_print_aux,
04279       dummy_reloc16_extra_cases,
04280       dummy_reloc16_estimate,
04281       NULL,                 /* bfd_coff_sym_is_global */
04282       coff_compute_section_file_positions,
04283       NULL,                 /* _bfd_coff_start_final_link */
04284       xcoff_ppc_relocate_section,
04285       coff_rtype_to_howto,
04286       NULL,                 /* _bfd_coff_adjust_symndx */
04287       _bfd_generic_link_add_one_symbol,
04288       coff_link_output_has_begun,
04289       coff_final_link_postscript
04290     },
04291 
04292     0x01DF,                 /* magic number */
04293     bfd_arch_powerpc,
04294     bfd_mach_ppc,
04295 
04296     /* Function pointers to xcoff specific swap routines.  */
04297     xcoff_swap_ldhdr_in,
04298     xcoff_swap_ldhdr_out,
04299     xcoff_swap_ldsym_in,
04300     xcoff_swap_ldsym_out,
04301     xcoff_swap_ldrel_in,
04302     xcoff_swap_ldrel_out,
04303 
04304     /* Sizes.  */
04305     LDHDRSZ,
04306     LDSYMSZ,
04307     LDRELSZ,
04308     12,                            /* _xcoff_function_descriptor_size */
04309     SMALL_AOUTSZ,
04310 
04311     /* Versions.  */
04312     1,                      /* _xcoff_ldhdr_version */
04313 
04314     _bfd_xcoff_put_symbol_name,
04315     _bfd_xcoff_put_ldsymbol_name,
04316     &xcoff_dynamic_reloc,
04317     xcoff_create_csect_from_smclas,
04318 
04319     /* Lineno and reloc count overflow.  */
04320     xcoff_is_lineno_count_overflow,
04321     xcoff_is_reloc_count_overflow,
04322 
04323     xcoff_loader_symbol_offset,
04324     xcoff_loader_reloc_offset,
04325 
04326     /* glink.  */
04327     &xcoff_glink_code[0],
04328     36,                            /* _xcoff_glink_size */
04329 
04330     /* rtinit */
04331     0,                      /* _xcoff_rtinit_size */
04332     xcoff_generate_rtinit,
04333   };
04334 
04335 /* The transfer vector that leads the outside world to all of the above.  */
04336 const bfd_target pmac_xcoff_vec =
04337   {
04338     "xcoff-powermac",
04339     bfd_target_xcoff_flavour,
04340     BFD_ENDIAN_BIG,         /* data byte order is big */
04341     BFD_ENDIAN_BIG,         /* header byte order is big */
04342 
04343     (HAS_RELOC | EXEC_P | HAS_LINENO | HAS_DEBUG | DYNAMIC
04344      | HAS_SYMS | HAS_LOCALS | WP_TEXT),
04345 
04346     SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_CODE | SEC_DATA,
04347     0,                      /* leading char */
04348     '/',                    /* ar_pad_char */
04349     15,                            /* ar_max_namelen */
04350 
04351     /* data */
04352     bfd_getb64,
04353     bfd_getb_signed_64,
04354     bfd_putb64,
04355     bfd_getb32,
04356     bfd_getb_signed_32,
04357     bfd_putb32,
04358     bfd_getb16,
04359     bfd_getb_signed_16,
04360     bfd_putb16,
04361 
04362     /* hdrs */
04363     bfd_getb64,
04364     bfd_getb_signed_64,
04365     bfd_putb64,
04366     bfd_getb32,
04367     bfd_getb_signed_32,
04368     bfd_putb32,
04369     bfd_getb16,
04370     bfd_getb_signed_16,
04371     bfd_putb16,
04372 
04373     { /* bfd_check_format */
04374       _bfd_dummy_target,
04375       coff_object_p,
04376       _bfd_xcoff_archive_p,
04377       CORE_FILE_P
04378     },
04379 
04380     { /* bfd_set_format */
04381       bfd_false,
04382       coff_mkobject,
04383       _bfd_generic_mkarchive,
04384       bfd_false
04385     },
04386 
04387     {/* bfd_write_contents */
04388       bfd_false,
04389       coff_write_object_contents,
04390       _bfd_xcoff_write_archive_contents,
04391       bfd_false
04392     },
04393 
04394     /* Generic */
04395     bfd_true,
04396     bfd_true,
04397     coff_new_section_hook,
04398     _bfd_generic_get_section_contents,
04399     _bfd_generic_get_section_contents_in_window,
04400 
04401     /* Copy */
04402     _bfd_xcoff_copy_private_bfd_data,
04403     ((bfd_boolean (*) (bfd *, bfd *)) bfd_true),
04404     _bfd_generic_init_private_section_data,
04405     ((bfd_boolean (*) (bfd *, asection *, bfd *, asection *)) bfd_true),
04406     ((bfd_boolean (*) (bfd *, asymbol *, bfd *, asymbol *)) bfd_true),
04407     ((bfd_boolean (*) (bfd *, bfd *)) bfd_true),
04408     ((bfd_boolean (*) (bfd *, flagword)) bfd_true),
04409     ((bfd_boolean (*) (bfd *, void * )) bfd_true),
04410 
04411     /* Core */
04412     coff_core_file_failing_command,
04413     coff_core_file_failing_signal,
04414     coff_core_file_matches_executable_p,
04415 
04416     /* Archive */
04417     _bfd_xcoff_slurp_armap,
04418     bfd_false,
04419     ((bfd_boolean (*) (bfd *, char **, bfd_size_type *, const char **)) bfd_false),
04420     bfd_dont_truncate_arname,
04421     _bfd_xcoff_write_armap,
04422     _bfd_xcoff_read_ar_hdr,
04423     _bfd_xcoff_openr_next_archived_file,
04424     _bfd_generic_get_elt_at_index,
04425     _bfd_xcoff_stat_arch_elt,
04426     bfd_true,
04427 
04428     /* Symbols */
04429     coff_get_symtab_upper_bound,
04430     coff_canonicalize_symtab,
04431     coff_make_empty_symbol,
04432     coff_print_symbol,
04433     coff_get_symbol_info,
04434     _bfd_xcoff_is_local_label_name,
04435     coff_bfd_is_target_special_symbol,
04436     coff_get_lineno,
04437     coff_find_nearest_line,
04438     _bfd_generic_find_line,
04439     coff_find_inliner_info,
04440     coff_bfd_make_debug_symbol,
04441     _bfd_generic_read_minisymbols,
04442     _bfd_generic_minisymbol_to_symbol,
04443 
04444     /* Reloc */
04445     coff_get_reloc_upper_bound,
04446     coff_canonicalize_reloc,
04447     _bfd_xcoff_reloc_type_lookup,
04448     _bfd_xcoff_reloc_name_lookup,
04449 
04450     /* Write */
04451     coff_set_arch_mach,
04452     coff_set_section_contents,
04453 
04454     /* Link */
04455     _bfd_xcoff_sizeof_headers,
04456     bfd_generic_get_relocated_section_contents,
04457     bfd_generic_relax_section,
04458     _bfd_xcoff_bfd_link_hash_table_create,
04459     _bfd_generic_link_hash_table_free,
04460     _bfd_xcoff_bfd_link_add_symbols,
04461     _bfd_generic_link_just_syms,
04462     _bfd_xcoff_bfd_final_link,
04463     _bfd_generic_link_split_section,
04464     bfd_generic_gc_sections,
04465     bfd_generic_merge_sections,
04466     bfd_generic_is_group_section,
04467     bfd_generic_discard_group,
04468     _bfd_generic_section_already_linked,
04469 
04470     /* Dynamic */
04471     _bfd_xcoff_get_dynamic_symtab_upper_bound,
04472     _bfd_xcoff_canonicalize_dynamic_symtab,
04473     _bfd_nodynamic_get_synthetic_symtab,
04474     _bfd_xcoff_get_dynamic_reloc_upper_bound,
04475     _bfd_xcoff_canonicalize_dynamic_reloc,
04476 
04477     /* Opposite endian version, none exists */
04478     NULL,
04479 
04480     (void *) &bfd_pmac_xcoff_backend_data,
04481   };