Back to index

cell-binutils  2.17cvs20070401
coff64-rs6000.c
Go to the documentation of this file.
00001 /* BFD back-end for IBM RS/6000 "XCOFF64" files.
00002    Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
00003    Free Software Foundation, Inc.
00004    Written Clinton Popetz.
00005    Contributed by Cygnus Support.
00006 
00007    This file is part of BFD, the Binary File Descriptor library.
00008 
00009    This program is free software; you can redistribute it and/or modify
00010    it under the terms of the GNU General Public License as published by
00011    the Free Software Foundation; either version 2 of the License, or
00012    (at your option) any later version.
00013 
00014    This program is distributed in the hope that it will be useful,
00015    but WITHOUT ANY WARRANTY; without even the implied warranty of
00016    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00017    GNU General Public License for more details.
00018 
00019    You should have received a copy of the GNU General Public License
00020    along with this program; if not, write to the Free Software
00021    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.  */
00022 
00023 #include "bfd.h"
00024 #include "sysdep.h"
00025 #include "bfdlink.h"
00026 #include "libbfd.h"
00027 #include "coff/internal.h"
00028 #include "coff/xcoff.h"
00029 #include "coff/rs6k64.h"
00030 #include "libcoff.h"
00031 #include "libxcoff.h"
00032 
00033 #define GET_FILEHDR_SYMPTR H_GET_64
00034 #define PUT_FILEHDR_SYMPTR H_PUT_64
00035 #define GET_AOUTHDR_DATA_START H_GET_64
00036 #define PUT_AOUTHDR_DATA_START H_PUT_64
00037 #define GET_AOUTHDR_TEXT_START H_GET_64
00038 #define PUT_AOUTHDR_TEXT_START H_PUT_64
00039 #define GET_AOUTHDR_TSIZE H_GET_64
00040 #define PUT_AOUTHDR_TSIZE H_PUT_64
00041 #define GET_AOUTHDR_DSIZE H_GET_64
00042 #define PUT_AOUTHDR_DSIZE H_PUT_64
00043 #define GET_AOUTHDR_BSIZE H_GET_64
00044 #define PUT_AOUTHDR_BSIZE H_PUT_64
00045 #define GET_AOUTHDR_ENTRY H_GET_64
00046 #define PUT_AOUTHDR_ENTRY H_PUT_64
00047 #define GET_SCNHDR_PADDR H_GET_64
00048 #define PUT_SCNHDR_PADDR H_PUT_64
00049 #define GET_SCNHDR_VADDR H_GET_64
00050 #define PUT_SCNHDR_VADDR H_PUT_64
00051 #define GET_SCNHDR_SIZE H_GET_64
00052 #define PUT_SCNHDR_SIZE H_PUT_64
00053 #define GET_SCNHDR_SCNPTR H_GET_64
00054 #define PUT_SCNHDR_SCNPTR H_PUT_64
00055 #define GET_SCNHDR_RELPTR H_GET_64
00056 #define PUT_SCNHDR_RELPTR H_PUT_64
00057 #define GET_SCNHDR_LNNOPTR H_GET_64
00058 #define PUT_SCNHDR_LNNOPTR H_PUT_64
00059 #define GET_SCNHDR_NRELOC H_GET_32
00060 #define MAX_SCNHDR_NRELOC 0xffffffff
00061 #define PUT_SCNHDR_NRELOC H_PUT_32
00062 #define GET_SCNHDR_NLNNO H_GET_32
00063 #define MAX_SCNHDR_NLNNO 0xffffffff
00064 #define PUT_SCNHDR_NLNNO H_PUT_32
00065 #define GET_RELOC_VADDR H_GET_64
00066 #define PUT_RELOC_VADDR H_PUT_64
00067 
00068 #define COFF_FORCE_SYMBOLS_IN_STRINGS
00069 #define COFF_DEBUG_STRING_WIDE_PREFIX
00070 
00071 
00072 #define COFF_ADJUST_SCNHDR_OUT_POST(ABFD, INT, EXT)                   \
00073   do                                                           \
00074     {                                                          \
00075       memset (((SCNHDR *) EXT)->s_pad, 0,                      \
00076              sizeof (((SCNHDR *) EXT)->s_pad));                \
00077     }                                                          \
00078   while (0)
00079 
00080 #define NO_COFF_LINENOS
00081 
00082 #define coff_SWAP_lineno_in _bfd_xcoff64_swap_lineno_in
00083 #define coff_SWAP_lineno_out _bfd_xcoff64_swap_lineno_out
00084 
00085 static void _bfd_xcoff64_swap_lineno_in
00086   PARAMS ((bfd *, PTR, PTR));
00087 static unsigned int _bfd_xcoff64_swap_lineno_out
00088   PARAMS ((bfd *, PTR, PTR));
00089 static bfd_boolean _bfd_xcoff64_put_symbol_name
00090   PARAMS ((bfd *, struct bfd_strtab_hash *, struct internal_syment *,
00091           const char *));
00092 static bfd_boolean _bfd_xcoff64_put_ldsymbol_name
00093   PARAMS ((bfd *, struct xcoff_loader_info *, struct internal_ldsym *,
00094           const char *));
00095 static void _bfd_xcoff64_swap_sym_in
00096   PARAMS ((bfd *, PTR, PTR));
00097 static unsigned int _bfd_xcoff64_swap_sym_out
00098   PARAMS ((bfd *, PTR, PTR));
00099 static void _bfd_xcoff64_swap_aux_in
00100   PARAMS ((bfd *, PTR, int, int, int, int, PTR));
00101 static unsigned int _bfd_xcoff64_swap_aux_out
00102   PARAMS ((bfd *, PTR, int, int, int, int, PTR));
00103 static void xcoff64_swap_reloc_in
00104   PARAMS ((bfd *, PTR, PTR));
00105 static unsigned int xcoff64_swap_reloc_out
00106   PARAMS ((bfd *, PTR, PTR));
00107 extern bfd_boolean _bfd_xcoff_mkobject
00108   PARAMS ((bfd *));
00109 extern bfd_boolean _bfd_xcoff_copy_private_bfd_data
00110   PARAMS ((bfd *, bfd *));
00111 extern bfd_boolean _bfd_xcoff_is_local_label_name
00112   PARAMS ((bfd *, const char *));
00113 extern void xcoff64_rtype2howto
00114   PARAMS ((arelent *, struct internal_reloc *));
00115 extern reloc_howto_type * xcoff64_reloc_type_lookup
00116   PARAMS ((bfd *, bfd_reloc_code_real_type));
00117 extern bfd_boolean _bfd_xcoff_slurp_armap
00118   PARAMS ((bfd *));
00119 extern PTR _bfd_xcoff_read_ar_hdr
00120   PARAMS ((bfd *));
00121 extern bfd *_bfd_xcoff_openr_next_archived_file
00122   PARAMS ((bfd *, bfd *));
00123 extern int _bfd_xcoff_stat_arch_elt
00124   PARAMS ((bfd *, struct stat *));
00125 extern bfd_boolean _bfd_xcoff_write_armap
00126   PARAMS ((bfd *, unsigned int, struct orl *, unsigned int, int));
00127 extern bfd_boolean _bfd_xcoff_write_archive_contents
00128   PARAMS ((bfd *));
00129 extern int _bfd_xcoff_sizeof_headers
00130   PARAMS ((bfd *, struct bfd_link_info *));
00131 extern void _bfd_xcoff_swap_sym_in
00132   PARAMS ((bfd *, PTR, PTR));
00133 extern unsigned int _bfd_xcoff_swap_sym_out
00134   PARAMS ((bfd *, PTR, PTR));
00135 extern void _bfd_xcoff_swap_aux_in
00136   PARAMS ((bfd *, PTR, int, int, int, int, PTR));
00137 extern unsigned int _bfd_xcoff_swap_aux_out
00138   PARAMS ((bfd *, PTR, int, int, int, int, PTR));
00139 static void xcoff64_swap_ldhdr_in
00140   PARAMS ((bfd *, const PTR, struct internal_ldhdr *));
00141 static void xcoff64_swap_ldhdr_out
00142   PARAMS ((bfd *, const struct internal_ldhdr *, PTR d));
00143 static void xcoff64_swap_ldsym_in
00144   PARAMS ((bfd *, const PTR, struct internal_ldsym *));
00145 static void xcoff64_swap_ldsym_out
00146   PARAMS ((bfd *, const struct internal_ldsym *, PTR d));
00147 static void xcoff64_swap_ldrel_in
00148   PARAMS ((bfd *, const PTR, struct internal_ldrel *));
00149 static void xcoff64_swap_ldrel_out
00150   PARAMS ((bfd *, const struct internal_ldrel *, PTR d));
00151 static bfd_boolean xcoff64_write_object_contents
00152   PARAMS ((bfd *));
00153 static bfd_boolean xcoff64_ppc_relocate_section
00154   PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *,
00155           struct internal_reloc *, struct internal_syment *,
00156           asection **));
00157 static bfd_boolean xcoff64_slurp_armap
00158   PARAMS ((bfd *));
00159 static const bfd_target *xcoff64_archive_p
00160   PARAMS ((bfd *));
00161 static bfd *xcoff64_openr_next_archived_file
00162   PARAMS ((bfd *, bfd *));
00163 static int xcoff64_sizeof_headers
00164   PARAMS ((bfd *, struct bfd_link_info *));
00165 static asection *xcoff64_create_csect_from_smclas
00166   PARAMS ((bfd *, union internal_auxent *, const char *));
00167 static bfd_boolean xcoff64_is_lineno_count_overflow
00168   PARAMS ((bfd *, bfd_vma));
00169 static bfd_boolean xcoff64_is_reloc_count_overflow
00170   PARAMS ((bfd *, bfd_vma));
00171 static bfd_vma xcoff64_loader_symbol_offset
00172   PARAMS ((bfd *, struct internal_ldhdr *));
00173 static bfd_vma xcoff64_loader_reloc_offset
00174   PARAMS ((bfd *, struct internal_ldhdr *));
00175 static bfd_boolean xcoff64_generate_rtinit
00176   PARAMS ((bfd *, const char *, const char *, bfd_boolean));
00177 static bfd_boolean xcoff64_bad_format_hook
00178   PARAMS ((bfd *, PTR ));
00179 
00180 /* Relocation functions */
00181 static bfd_boolean xcoff64_reloc_type_br
00182   PARAMS ((XCOFF_RELOC_FUNCTION_ARGS));
00183 
00184 bfd_boolean (*xcoff64_calculate_relocation[XCOFF_MAX_CALCULATE_RELOCATION])
00185   PARAMS ((XCOFF_RELOC_FUNCTION_ARGS)) =
00186 {
00187   xcoff_reloc_type_pos,      /* R_POS   (0x00) */
00188   xcoff_reloc_type_neg,      /* R_NEG   (0x01) */
00189   xcoff_reloc_type_rel,      /* R_REL   (0x02) */
00190   xcoff_reloc_type_toc,      /* R_TOC   (0x03) */
00191   xcoff_reloc_type_fail, /* R_RTB   (0x04) */
00192   xcoff_reloc_type_toc,      /* R_GL    (0x05) */
00193   xcoff_reloc_type_toc,      /* R_TCL   (0x06) */
00194   xcoff_reloc_type_fail, /*     (0x07) */
00195   xcoff_reloc_type_ba,       /* R_BA    (0x08) */
00196   xcoff_reloc_type_fail, /*     (0x09) */
00197   xcoff64_reloc_type_br, /* R_BR    (0x0a) */
00198   xcoff_reloc_type_fail, /*     (0x0b) */
00199   xcoff_reloc_type_pos,      /* R_RL    (0x0c) */
00200   xcoff_reloc_type_pos,      /* R_RLA   (0x0d) */
00201   xcoff_reloc_type_fail, /*     (0x0e) */
00202   xcoff_reloc_type_noop, /* R_REF   (0x0f) */
00203   xcoff_reloc_type_fail, /*     (0x10) */
00204   xcoff_reloc_type_fail, /*     (0x11) */
00205   xcoff_reloc_type_toc,      /* R_TRL   (0x12) */
00206   xcoff_reloc_type_toc,      /* R_TRLA  (0x13) */
00207   xcoff_reloc_type_fail, /* R_RRTBI (0x14) */
00208   xcoff_reloc_type_fail, /* R_RRTBA (0x15) */
00209   xcoff_reloc_type_ba,       /* R_CAI   (0x16) */
00210   xcoff_reloc_type_crel, /* R_CREL  (0x17) */
00211   xcoff_reloc_type_ba,       /* R_RBA   (0x18) */
00212   xcoff_reloc_type_ba,       /* R_RBAC  (0x19) */
00213   xcoff64_reloc_type_br, /* R_RBR   (0x1a) */
00214   xcoff_reloc_type_ba,       /* R_RBRC  (0x1b) */
00215 };
00216 
00217 /* coffcode.h needs these to be defined.  */
00218 /* Internalcoff.h and coffcode.h modify themselves based on these flags.  */
00219 #define XCOFF64
00220 #define RS6000COFF_C 1
00221 
00222 #define SELECT_RELOC(internal, howto)                                 \
00223   {                                                            \
00224     internal.r_type = howto->type;                             \
00225     internal.r_size =                                                 \
00226       ((howto->complain_on_overflow == complain_overflow_signed              \
00227        ? 0x80                                                  \
00228        : 0)                                                    \
00229        | (howto->bitsize - 1));                                       \
00230   }
00231 
00232 #define COFF_DEFAULT_SECTION_ALIGNMENT_POWER (3)
00233 #define COFF_LONG_FILENAMES
00234 #define NO_COFF_SYMBOLS
00235 #define RTYPE2HOWTO(cache_ptr, dst) xcoff64_rtype2howto (cache_ptr, dst)
00236 #define coff_mkobject _bfd_xcoff_mkobject
00237 #define coff_bfd_copy_private_bfd_data _bfd_xcoff_copy_private_bfd_data
00238 #define coff_bfd_is_local_label_name _bfd_xcoff_is_local_label_name
00239 #define coff_bfd_reloc_type_lookup xcoff64_reloc_type_lookup
00240 #define coff_bfd_reloc_name_lookup xcoff64_reloc_name_lookup
00241 #ifdef AIX_CORE
00242 extern const bfd_target * rs6000coff_core_p
00243   PARAMS ((bfd *abfd));
00244 extern bfd_boolean rs6000coff_core_file_matches_executable_p
00245   PARAMS ((bfd *cbfd, bfd *ebfd));
00246 extern char *rs6000coff_core_file_failing_command
00247   PARAMS ((bfd *abfd));
00248 extern int rs6000coff_core_file_failing_signal
00249   PARAMS ((bfd *abfd));
00250 #define CORE_FILE_P rs6000coff_core_p
00251 #define coff_core_file_failing_command \
00252   rs6000coff_core_file_failing_command
00253 #define coff_core_file_failing_signal \
00254   rs6000coff_core_file_failing_signal
00255 #define coff_core_file_matches_executable_p \
00256   rs6000coff_core_file_matches_executable_p
00257 #else
00258 #define CORE_FILE_P _bfd_dummy_target
00259 #define coff_core_file_failing_command \
00260   _bfd_nocore_core_file_failing_command
00261 #define coff_core_file_failing_signal \
00262   _bfd_nocore_core_file_failing_signal
00263 #define coff_core_file_matches_executable_p \
00264   _bfd_nocore_core_file_matches_executable_p
00265 #endif
00266 #define coff_SWAP_sym_in _bfd_xcoff64_swap_sym_in
00267 #define coff_SWAP_sym_out _bfd_xcoff64_swap_sym_out
00268 #define coff_SWAP_aux_in _bfd_xcoff64_swap_aux_in
00269 #define coff_SWAP_aux_out _bfd_xcoff64_swap_aux_out
00270 #define coff_swap_reloc_in xcoff64_swap_reloc_in
00271 #define coff_swap_reloc_out xcoff64_swap_reloc_out
00272 #define NO_COFF_RELOCS
00273 
00274 #include "coffcode.h"
00275 
00276 /* For XCOFF64, the effective width of symndx changes depending on
00277    whether we are the first entry.  Sigh.  */
00278 static void
00279 _bfd_xcoff64_swap_lineno_in (abfd, ext1, in1)
00280      bfd *abfd;
00281      PTR ext1;
00282      PTR in1;
00283 {
00284   LINENO *ext = (LINENO *) ext1;
00285   struct internal_lineno *in = (struct internal_lineno *) in1;
00286 
00287   in->l_lnno = H_GET_32 (abfd, (ext->l_lnno));
00288   if (in->l_lnno == 0)
00289     in->l_addr.l_symndx = H_GET_32 (abfd, ext->l_addr.l_symndx);
00290   else
00291     in->l_addr.l_paddr = H_GET_64 (abfd, ext->l_addr.l_paddr);
00292 }
00293 
00294 static unsigned int
00295 _bfd_xcoff64_swap_lineno_out (abfd, inp, outp)
00296      bfd *abfd;
00297      PTR inp;
00298      PTR outp;
00299 {
00300   struct internal_lineno *in = (struct internal_lineno *) inp;
00301   struct external_lineno *ext = (struct external_lineno *) outp;
00302 
00303   H_PUT_32 (abfd, in->l_addr.l_symndx, ext->l_addr.l_symndx);
00304   H_PUT_32 (abfd, in->l_lnno, (ext->l_lnno));
00305 
00306   if (in->l_lnno == 0)
00307     H_PUT_32 (abfd, in->l_addr.l_symndx, ext->l_addr.l_symndx);
00308   else
00309     H_PUT_64 (abfd, in->l_addr.l_paddr, ext->l_addr.l_paddr);
00310 
00311   return bfd_coff_linesz (abfd);
00312 }
00313 
00314 static void
00315 _bfd_xcoff64_swap_sym_in (abfd, ext1, in1)
00316      bfd *abfd;
00317      PTR ext1;
00318      PTR in1;
00319 {
00320   struct external_syment *ext = (struct external_syment *) ext1;
00321   struct internal_syment *in = (struct internal_syment *) in1;
00322 
00323   in->_n._n_n._n_zeroes = 0;
00324   in->_n._n_n._n_offset = H_GET_32 (abfd, ext->e_offset);
00325   in->n_value = H_GET_64 (abfd, ext->e_value);
00326   in->n_scnum = H_GET_16 (abfd, ext->e_scnum);
00327   in->n_type = H_GET_16 (abfd, ext->e_type);
00328   in->n_sclass = H_GET_8 (abfd, ext->e_sclass);
00329   in->n_numaux = H_GET_8 (abfd, ext->e_numaux);
00330 }
00331 
00332 static unsigned int
00333 _bfd_xcoff64_swap_sym_out (abfd, inp, extp)
00334      bfd *abfd;
00335      PTR inp;
00336      PTR extp;
00337 {
00338   struct internal_syment *in = (struct internal_syment *) inp;
00339   struct external_syment *ext = (struct external_syment *) extp;
00340 
00341   H_PUT_32 (abfd, in->_n._n_n._n_offset, ext->e_offset);
00342   H_PUT_64 (abfd, in->n_value, ext->e_value);
00343   H_PUT_16 (abfd, in->n_scnum, ext->e_scnum);
00344   H_PUT_16 (abfd, in->n_type, ext->e_type);
00345   H_PUT_8 (abfd, in->n_sclass, ext->e_sclass);
00346   H_PUT_8 (abfd, in->n_numaux, ext->e_numaux);
00347   return bfd_coff_symesz (abfd);
00348 }
00349 
00350 static void
00351 _bfd_xcoff64_swap_aux_in (abfd, ext1, type, class, indx, numaux, in1)
00352      bfd *abfd;
00353      PTR ext1;
00354      int type;
00355      int class;
00356      int indx;
00357      int numaux;
00358      PTR in1;
00359 {
00360   union external_auxent *ext = (union external_auxent *) ext1;
00361   union internal_auxent *in = (union internal_auxent *) in1;
00362 
00363   switch (class)
00364     {
00365     case C_FILE:
00366       if (ext->x_file.x_n.x_zeroes[0] == 0)
00367        {
00368          in->x_file.x_n.x_zeroes = 0;
00369          in->x_file.x_n.x_offset = H_GET_32 (abfd, ext->x_file.x_n.x_offset);
00370        }
00371       else
00372        {
00373          memcpy (in->x_file.x_fname, ext->x_file.x_fname, FILNMLEN);
00374        }
00375       goto end;
00376 
00377       /* RS/6000 "csect" auxents */
00378     case C_EXT:
00379     case C_HIDEXT:
00380       if (indx + 1 == numaux)
00381        {
00382          bfd_signed_vma h = 0;
00383          bfd_vma l = 0;
00384 
00385          h = H_GET_S32 (abfd, ext->x_csect.x_scnlen_hi);
00386          l = H_GET_32 (abfd, ext->x_csect.x_scnlen_lo);
00387 
00388          in->x_csect.x_scnlen.l = h << 32 | (l & 0xffffffff);
00389 
00390          in->x_csect.x_parmhash = H_GET_32 (abfd, ext->x_csect.x_parmhash);
00391          in->x_csect.x_snhash = H_GET_16 (abfd, ext->x_csect.x_snhash);
00392          /* We don't have to hack bitfields in x_smtyp because it's
00393             defined by shifts-and-ands, which are equivalent on all
00394             byte orders.  */
00395          in->x_csect.x_smtyp = H_GET_8 (abfd, ext->x_csect.x_smtyp);
00396          in->x_csect.x_smclas = H_GET_8 (abfd, ext->x_csect.x_smclas);
00397          goto end;
00398        }
00399       break;
00400 
00401     case C_STAT:
00402     case C_LEAFSTAT:
00403     case C_HIDDEN:
00404       if (type == T_NULL)
00405        {
00406          /* PE defines some extra fields; we zero them out for
00407             safety.  */
00408          in->x_scn.x_checksum = 0;
00409          in->x_scn.x_associated = 0;
00410          in->x_scn.x_comdat = 0;
00411 
00412          goto end;
00413        }
00414       break;
00415     }
00416 
00417   if (class == C_BLOCK || class == C_FCN || ISFCN (type) || ISTAG (class))
00418     {
00419       in->x_sym.x_fcnary.x_fcn.x_lnnoptr
00420        = H_GET_64 (abfd, ext->x_sym.x_fcnary.x_fcn.x_lnnoptr);
00421       in->x_sym.x_fcnary.x_fcn.x_endndx.l
00422        = H_GET_32 (abfd, ext->x_sym.x_fcnary.x_fcn.x_endndx);
00423     }
00424   if (ISFCN (type))
00425     {
00426       in->x_sym.x_misc.x_fsize
00427        = H_GET_32 (abfd, ext->x_sym.x_fcnary.x_fcn.x_fsize);
00428     }
00429   else
00430     {
00431       in->x_sym.x_misc.x_lnsz.x_lnno
00432        = H_GET_32 (abfd, ext->x_sym.x_fcnary.x_lnsz.x_lnno);
00433       in->x_sym.x_misc.x_lnsz.x_size
00434        = H_GET_16 (abfd, ext->x_sym.x_fcnary.x_lnsz.x_size);
00435     }
00436 
00437  end: ;
00438 }
00439 
00440 static unsigned int
00441 _bfd_xcoff64_swap_aux_out (abfd, inp, type, class, indx, numaux, extp)
00442      bfd *abfd;
00443      PTR inp;
00444      int type;
00445      int class;
00446      int indx ATTRIBUTE_UNUSED;
00447      int numaux ATTRIBUTE_UNUSED;
00448      PTR extp;
00449 {
00450   union internal_auxent *in = (union internal_auxent *) inp;
00451   union external_auxent *ext = (union external_auxent *) extp;
00452 
00453   memset ((PTR) ext, 0, bfd_coff_auxesz (abfd));
00454   switch (class)
00455     {
00456     case C_FILE:
00457       if (in->x_file.x_n.x_zeroes == 0)
00458        {
00459          H_PUT_32 (abfd, 0, ext->x_file.x_n.x_zeroes);
00460          H_PUT_32 (abfd, in->x_file.x_n.x_offset, ext->x_file.x_n.x_offset);
00461        }
00462       else
00463        {
00464          memcpy (ext->x_file.x_fname, in->x_file.x_fname, FILNMLEN);
00465        }
00466       H_PUT_8 (abfd, _AUX_FILE, ext->x_auxtype.x_auxtype);
00467       goto end;
00468 
00469       /* RS/6000 "csect" auxents */
00470     case C_EXT:
00471     case C_HIDEXT:
00472       if (indx + 1 == numaux)
00473        {
00474          bfd_vma temp;
00475 
00476          temp = in->x_csect.x_scnlen.l & 0xffffffff;
00477          H_PUT_32 (abfd, temp, ext->x_csect.x_scnlen_lo);
00478          temp = in->x_csect.x_scnlen.l >> 32;
00479          H_PUT_32 (abfd, temp, ext->x_csect.x_scnlen_hi);
00480          H_PUT_32 (abfd, in->x_csect.x_parmhash, ext->x_csect.x_parmhash);
00481          H_PUT_16 (abfd, in->x_csect.x_snhash, ext->x_csect.x_snhash);
00482          /* We don't have to hack bitfields in x_smtyp because it's
00483             defined by shifts-and-ands, which are equivalent on all
00484             byte orders.  */
00485          H_PUT_8 (abfd, in->x_csect.x_smtyp, ext->x_csect.x_smtyp);
00486          H_PUT_8 (abfd, in->x_csect.x_smclas, ext->x_csect.x_smclas);
00487          H_PUT_8 (abfd, _AUX_CSECT, ext->x_auxtype.x_auxtype);
00488          goto end;
00489        }
00490       break;
00491 
00492     case C_STAT:
00493     case C_LEAFSTAT:
00494     case C_HIDDEN:
00495       if (type == T_NULL)
00496        {
00497          goto end;
00498        }
00499       break;
00500     }
00501 
00502   if (class == C_BLOCK || class == C_FCN || ISFCN (type) || ISTAG (class))
00503     {
00504       H_PUT_64 (abfd, in->x_sym.x_fcnary.x_fcn.x_lnnoptr,
00505               ext->x_sym.x_fcnary.x_fcn.x_lnnoptr);
00506       H_PUT_8 (abfd, _AUX_FCN,
00507               ext->x_auxtype.x_auxtype);
00508       H_PUT_32 (abfd, in->x_sym.x_fcnary.x_fcn.x_endndx.l,
00509               ext->x_sym.x_fcnary.x_fcn.x_endndx);
00510     }
00511   if (ISFCN (type))
00512     {
00513       H_PUT_32 (abfd, in->x_sym.x_misc.x_fsize,
00514               ext->x_sym.x_fcnary.x_fcn.x_fsize);
00515     }
00516   else
00517     {
00518       H_PUT_32 (abfd, in->x_sym.x_misc.x_lnsz.x_lnno,
00519               ext->x_sym.x_fcnary.x_lnsz.x_lnno);
00520       H_PUT_16 (abfd, in->x_sym.x_misc.x_lnsz.x_size,
00521               ext->x_sym.x_fcnary.x_lnsz.x_size);
00522     }
00523 
00524  end:
00525 
00526   return bfd_coff_auxesz (abfd);
00527 }
00528 
00529 static bfd_boolean
00530 _bfd_xcoff64_put_symbol_name (abfd, strtab, sym, name)
00531      bfd *abfd;
00532      struct bfd_strtab_hash *strtab;
00533      struct internal_syment *sym;
00534      const char *name;
00535 {
00536   bfd_boolean hash;
00537   bfd_size_type indx;
00538 
00539   hash = TRUE;
00540 
00541   if ((abfd->flags & BFD_TRADITIONAL_FORMAT) != 0)
00542     hash = FALSE;
00543 
00544   indx = _bfd_stringtab_add (strtab, name, hash, FALSE);
00545 
00546   if (indx == (bfd_size_type) -1)
00547     return FALSE;
00548 
00549   sym->_n._n_n._n_zeroes = 0;
00550   sym->_n._n_n._n_offset = STRING_SIZE_SIZE + indx;
00551 
00552   return TRUE;
00553 }
00554 
00555 static bfd_boolean
00556 _bfd_xcoff64_put_ldsymbol_name (abfd, ldinfo, ldsym, name)
00557      bfd *abfd ATTRIBUTE_UNUSED;
00558      struct xcoff_loader_info *ldinfo;
00559      struct internal_ldsym *ldsym;
00560      const char *name;
00561 {
00562   size_t len;
00563   len = strlen (name);
00564 
00565   if (ldinfo->string_size + len + 3 > ldinfo->string_alc)
00566     {
00567       bfd_size_type newalc;
00568       char *newstrings;
00569 
00570       newalc = ldinfo->string_alc * 2;
00571       if (newalc == 0)
00572        newalc = 32;
00573       while (ldinfo->string_size + len + 3 > newalc)
00574        newalc *= 2;
00575 
00576       newstrings = bfd_realloc (ldinfo->strings, newalc);
00577       if (newstrings == NULL)
00578        {
00579          ldinfo->failed = TRUE;
00580          return FALSE;
00581        }
00582       ldinfo->string_alc = newalc;
00583       ldinfo->strings = newstrings;
00584     }
00585 
00586   bfd_put_16 (ldinfo->output_bfd, (bfd_vma) (len + 1),
00587              ldinfo->strings + ldinfo->string_size);
00588   strcpy (ldinfo->strings + ldinfo->string_size + 2, name);
00589   ldsym->_l._l_l._l_zeroes = 0;
00590   ldsym->_l._l_l._l_offset = ldinfo->string_size + 2;
00591   ldinfo->string_size += len + 3;
00592 
00593   return TRUE;
00594 }
00595 
00596 /* Routines to swap information in the XCOFF .loader section.  If we
00597    ever need to write an XCOFF loader, this stuff will need to be
00598    moved to another file shared by the linker (which XCOFF calls the
00599    ``binder'') and the loader.  */
00600 
00601 /* Swap in the ldhdr structure.  */
00602 
00603 static void
00604 xcoff64_swap_ldhdr_in (abfd, s, dst)
00605      bfd *abfd;
00606      const PTR s;
00607      struct internal_ldhdr *dst;
00608 {
00609   const struct external_ldhdr *src = (const struct external_ldhdr *) s;
00610 
00611   dst->l_version = bfd_get_32 (abfd, src->l_version);
00612   dst->l_nsyms = bfd_get_32 (abfd, src->l_nsyms);
00613   dst->l_nreloc = bfd_get_32 (abfd, src->l_nreloc);
00614   dst->l_istlen = bfd_get_32 (abfd, src->l_istlen);
00615   dst->l_nimpid = bfd_get_32 (abfd, src->l_nimpid);
00616   dst->l_stlen = bfd_get_32 (abfd, src->l_stlen);
00617   dst->l_impoff = bfd_get_64 (abfd, src->l_impoff);
00618   dst->l_stoff = bfd_get_64 (abfd, src->l_stoff);
00619   dst->l_symoff = bfd_get_64 (abfd, src->l_symoff);
00620   dst->l_rldoff = bfd_get_64 (abfd, src->l_rldoff);
00621 }
00622 
00623 /* Swap out the ldhdr structure.  */
00624 
00625 static void
00626 xcoff64_swap_ldhdr_out (abfd, src, d)
00627      bfd *abfd;
00628      const struct internal_ldhdr *src;
00629      PTR d;
00630 {
00631   struct external_ldhdr *dst = (struct external_ldhdr *) d;
00632 
00633   bfd_put_32 (abfd, (bfd_vma) src->l_version, dst->l_version);
00634   bfd_put_32 (abfd, src->l_nsyms, dst->l_nsyms);
00635   bfd_put_32 (abfd, src->l_nreloc, dst->l_nreloc);
00636   bfd_put_32 (abfd, src->l_istlen, dst->l_istlen);
00637   bfd_put_32 (abfd, src->l_nimpid, dst->l_nimpid);
00638   bfd_put_32 (abfd, src->l_stlen, dst->l_stlen);
00639   bfd_put_64 (abfd, src->l_impoff, dst->l_impoff);
00640   bfd_put_64 (abfd, src->l_stoff, dst->l_stoff);
00641   bfd_put_64 (abfd, src->l_symoff, dst->l_symoff);
00642   bfd_put_64 (abfd, src->l_rldoff, dst->l_rldoff);
00643 }
00644 
00645 /* Swap in the ldsym structure.  */
00646 
00647 static void
00648 xcoff64_swap_ldsym_in (abfd, s, dst)
00649      bfd *abfd;
00650      const PTR s;
00651      struct internal_ldsym *dst;
00652 {
00653   const struct external_ldsym *src = (const struct external_ldsym *) s;
00654   /* XCOFF64 does not use l_zeroes like XCOFF32
00655      Set the internal l_zeroes to 0 so the common 32/64 code uses l_value
00656      as an offset into the loader symbol table.  */
00657   dst->_l._l_l._l_zeroes = 0;
00658   dst->_l._l_l._l_offset = bfd_get_32 (abfd, src->l_offset);
00659   dst->l_value = bfd_get_64 (abfd, src->l_value);
00660   dst->l_scnum = bfd_get_16 (abfd, src->l_scnum);
00661   dst->l_smtype = bfd_get_8 (abfd, src->l_smtype);
00662   dst->l_smclas = bfd_get_8 (abfd, src->l_smclas);
00663   dst->l_ifile = bfd_get_32 (abfd, src->l_ifile);
00664   dst->l_parm = bfd_get_32 (abfd, src->l_parm);
00665 }
00666 
00667 /* Swap out the ldsym structure.  */
00668 
00669 static void
00670 xcoff64_swap_ldsym_out (abfd, src, d)
00671      bfd *abfd;
00672      const struct internal_ldsym *src;
00673      PTR d;
00674 {
00675   struct external_ldsym *dst = (struct external_ldsym *) d;
00676 
00677   bfd_put_64 (abfd, src->l_value, dst->l_value);
00678   bfd_put_32 (abfd, (bfd_vma) src->_l._l_l._l_offset, dst->l_offset);
00679   bfd_put_16 (abfd, (bfd_vma) src->l_scnum, dst->l_scnum);
00680   bfd_put_8 (abfd, src->l_smtype, dst->l_smtype);
00681   bfd_put_8 (abfd, src->l_smclas, dst->l_smclas);
00682   bfd_put_32 (abfd, src->l_ifile, dst->l_ifile);
00683   bfd_put_32 (abfd, src->l_parm, dst->l_parm);
00684 }
00685 
00686 static void
00687 xcoff64_swap_reloc_in (abfd, s, d)
00688      bfd *abfd;
00689      PTR s;
00690      PTR d;
00691 {
00692   struct external_reloc *src = (struct external_reloc *) s;
00693   struct internal_reloc *dst = (struct internal_reloc *) d;
00694 
00695   memset (dst, 0, sizeof (struct internal_reloc));
00696 
00697   dst->r_vaddr = bfd_get_64 (abfd, src->r_vaddr);
00698   dst->r_symndx = bfd_get_32 (abfd, src->r_symndx);
00699   dst->r_size = bfd_get_8 (abfd, src->r_size);
00700   dst->r_type = bfd_get_8 (abfd, src->r_type);
00701 }
00702 
00703 static unsigned int
00704 xcoff64_swap_reloc_out (abfd, s, d)
00705      bfd *abfd;
00706      PTR s;
00707      PTR d;
00708 {
00709   struct internal_reloc *src = (struct internal_reloc *) s;
00710   struct external_reloc *dst = (struct external_reloc *) d;
00711 
00712   bfd_put_64 (abfd, src->r_vaddr, dst->r_vaddr);
00713   bfd_put_32 (abfd, src->r_symndx, dst->r_symndx);
00714   bfd_put_8 (abfd, src->r_type, dst->r_type);
00715   bfd_put_8 (abfd, src->r_size, dst->r_size);
00716 
00717   return bfd_coff_relsz (abfd);
00718 }
00719 
00720 /* Swap in the ldrel structure.  */
00721 
00722 static void
00723 xcoff64_swap_ldrel_in (abfd, s, dst)
00724      bfd *abfd;
00725      const PTR s;
00726      struct internal_ldrel *dst;
00727 {
00728   const struct external_ldrel *src = (const struct external_ldrel *) s;
00729 
00730   dst->l_vaddr = bfd_get_64 (abfd, src->l_vaddr);
00731   dst->l_symndx = bfd_get_32 (abfd, src->l_symndx);
00732   dst->l_rtype = bfd_get_16 (abfd, src->l_rtype);
00733   dst->l_rsecnm = bfd_get_16 (abfd, src->l_rsecnm);
00734 }
00735 
00736 /* Swap out the ldrel structure.  */
00737 
00738 static void
00739 xcoff64_swap_ldrel_out (abfd, src, d)
00740      bfd *abfd;
00741      const struct internal_ldrel *src;
00742      PTR d;
00743 {
00744   struct external_ldrel *dst = (struct external_ldrel *) d;
00745 
00746   bfd_put_64 (abfd, src->l_vaddr, dst->l_vaddr);
00747   bfd_put_16 (abfd, (bfd_vma) src->l_rtype, dst->l_rtype);
00748   bfd_put_16 (abfd, (bfd_vma) src->l_rsecnm, dst->l_rsecnm);
00749   bfd_put_32 (abfd, src->l_symndx, dst->l_symndx);
00750 }
00751 
00752 static bfd_boolean
00753 xcoff64_write_object_contents (abfd)
00754      bfd *abfd;
00755 {
00756   asection *current;
00757   bfd_boolean hasrelocs = FALSE;
00758   bfd_boolean haslinno = FALSE;
00759   file_ptr scn_base;
00760   file_ptr reloc_base;
00761   file_ptr lineno_base;
00762   file_ptr sym_base;
00763   unsigned long reloc_size = 0;
00764   unsigned long lnno_size = 0;
00765   bfd_boolean long_section_names;
00766   asection *text_sec = ((void *) 0);
00767   asection *data_sec = ((void *) 0);
00768   asection *bss_sec = ((void *) 0);
00769   struct internal_filehdr internal_f;
00770   struct internal_aouthdr internal_a;
00771 
00772   bfd_set_error (bfd_error_system_call);
00773 
00774   if (! abfd->output_has_begun)
00775     {
00776       if (! bfd_coff_compute_section_file_positions (abfd))
00777        return FALSE;
00778     }
00779 
00780   /* Work out the size of the reloc and linno areas.  */
00781   reloc_base = obj_relocbase (abfd);
00782 
00783   for (current = abfd->sections; current != NULL; current = current->next)
00784     reloc_size += current->reloc_count * bfd_coff_relsz (abfd);
00785 
00786   lineno_base = reloc_base + reloc_size;
00787 
00788   /* Make a pass through the symbol table to count line number entries and
00789      put them into the correct asections.  */
00790   lnno_size = coff_count_linenumbers (abfd) * bfd_coff_linesz (abfd);
00791 
00792   sym_base = lineno_base + lnno_size;
00793 
00794   /* Indicate in each section->line_filepos its actual file address.  */
00795   for (current = abfd->sections; current != NULL; current =  current->next)
00796     {
00797       if (current->lineno_count)
00798        {
00799          current->line_filepos = lineno_base;
00800          current->moving_line_filepos = lineno_base;
00801          lineno_base += current->lineno_count * bfd_coff_linesz (abfd);
00802        }
00803       else
00804        {
00805          current->line_filepos = 0;
00806        }
00807 
00808       if (current->reloc_count)
00809        {
00810          current->rel_filepos = reloc_base;
00811          reloc_base += current->reloc_count * bfd_coff_relsz (abfd);
00812        }
00813       else
00814        {
00815          current->rel_filepos = 0;
00816        }
00817     }
00818 
00819   if ((abfd->flags & EXEC_P) != 0)
00820     {
00821       scn_base = bfd_coff_filhsz (abfd) + bfd_coff_aoutsz (abfd);
00822       internal_f.f_opthdr = bfd_coff_aoutsz (abfd);
00823     }
00824   else
00825     {
00826       scn_base = bfd_coff_filhsz (abfd);
00827       internal_f.f_opthdr = 0;
00828     }
00829 
00830   internal_f.f_nscns = 0;
00831 
00832   if (bfd_seek (abfd, scn_base, SEEK_SET) != 0)
00833     return FALSE;
00834 
00835   long_section_names = FALSE;
00836   for (current = abfd->sections; current != NULL; current = current->next)
00837     {
00838       struct internal_scnhdr section;
00839       struct external_scnhdr buff;
00840       bfd_size_type amount;
00841 
00842       internal_f.f_nscns++;
00843 
00844       strncpy (section.s_name, current->name, SCNNMLEN);
00845 
00846       section.s_vaddr = current->vma;
00847       section.s_paddr = current->lma;
00848       section.s_size =  current->size;
00849 
00850       /* If this section has no size or is unloadable then the scnptr
00851         will be 0 too.  */
00852       if (current->size == 0
00853          || (current->flags & (SEC_LOAD | SEC_HAS_CONTENTS)) == 0)
00854        {
00855          section.s_scnptr = 0;
00856        }
00857       else
00858        {
00859          section.s_scnptr = current->filepos;
00860        }
00861 
00862       section.s_relptr = current->rel_filepos;
00863       section.s_lnnoptr = current->line_filepos;
00864       section.s_nreloc = current->reloc_count;
00865 
00866       section.s_nlnno = current->lineno_count;
00867       if (current->reloc_count != 0)
00868        hasrelocs = TRUE;
00869       if (current->lineno_count != 0)
00870        haslinno = TRUE;
00871 
00872       section.s_flags = sec_to_styp_flags (current->name, current->flags);
00873 
00874       if (!strcmp (current->name, _TEXT))
00875        {
00876          text_sec = current;
00877        }
00878       else if (!strcmp (current->name, _DATA))
00879        {
00880          data_sec = current;
00881        }
00882       else if (!strcmp (current->name, _BSS))
00883        {
00884          bss_sec = current;
00885        }
00886 
00887       amount = bfd_coff_scnhsz (abfd);
00888       if (bfd_coff_swap_scnhdr_out (abfd, &section, &buff) == 0
00889          || bfd_bwrite ((PTR) (&buff), amount, abfd) != amount)
00890        return FALSE;
00891     }
00892 
00893   internal_f.f_timdat = 0;
00894 
00895   internal_f.f_flags = 0;
00896 
00897   if (!hasrelocs)
00898     internal_f.f_flags |= F_RELFLG;
00899   if (!haslinno)
00900     internal_f.f_flags |= F_LNNO;
00901   if (abfd->flags & EXEC_P)
00902     internal_f.f_flags |= F_EXEC;
00903 
00904   /* FIXME: this is wrong for PPC_PE!  */
00905   if (bfd_little_endian (abfd))
00906     internal_f.f_flags |= F_AR32WR;
00907   else
00908     internal_f.f_flags |= F_AR32W;
00909 
00910   if ((abfd->flags & DYNAMIC) != 0)
00911     internal_f.f_flags |= F_SHROBJ;
00912   if (bfd_get_section_by_name (abfd, _LOADER) != NULL)
00913     internal_f.f_flags |= F_DYNLOAD;
00914 
00915   memset (&internal_a, 0, sizeof internal_a);
00916 
00917   internal_f.f_magic = bfd_xcoff_magic_number (abfd);
00918   internal_a.magic = (abfd->flags & D_PAGED
00919                     ? RS6K_AOUTHDR_ZMAGIC
00920                     : (abfd->flags & WP_TEXT
00921                       ? RS6K_AOUTHDR_NMAGIC
00922                       : RS6K_AOUTHDR_OMAGIC));
00923 
00924   /* FIXME: Does anybody ever set this to another value?  */
00925   internal_a.vstamp = 0;
00926 
00927   /* Now should write relocs, strings, syms.  */
00928   obj_sym_filepos (abfd) = sym_base;
00929 
00930   internal_f.f_symptr = 0;
00931   internal_f.f_nsyms = 0;
00932 
00933   /* If bfd_get_symcount (abfd) != 0, then we are not using the COFF
00934      backend linker, and obj_raw_syment_count is not valid until after
00935      coff_write_symbols is called.  */
00936   if (bfd_get_symcount (abfd) != 0)
00937     {
00938       int firstundef;
00939 
00940       if (!coff_renumber_symbols (abfd, &firstundef))
00941        return FALSE;
00942       coff_mangle_symbols (abfd);
00943       if (! coff_write_symbols (abfd))
00944        return FALSE;
00945       if (! coff_write_linenumbers (abfd))
00946        return FALSE;
00947       if (! coff_write_relocs (abfd, firstundef))
00948        return FALSE;
00949 
00950       internal_f.f_symptr = sym_base;
00951       internal_f.f_nsyms = bfd_get_symcount (abfd);
00952     }
00953   else if (obj_raw_syment_count (abfd) != 0)
00954     {
00955       internal_f.f_symptr = sym_base;
00956 
00957       /* AIX appears to require that F_RELFLG not be set if there are
00958         local symbols but no relocations.  */
00959       internal_f.f_flags &=~ F_RELFLG;
00960     }
00961   else
00962     {
00963       internal_f.f_flags |= F_LSYMS;
00964     }
00965 
00966   if (text_sec)
00967     {
00968       internal_a.tsize = text_sec->size;
00969       internal_a.text_start = internal_a.tsize ? text_sec->vma : 0;
00970     }
00971 
00972   if (data_sec)
00973     {
00974       internal_a.dsize = data_sec->size;
00975       internal_a.data_start = internal_a.dsize ? data_sec->vma : 0;
00976     }
00977 
00978   if (bss_sec)
00979     {
00980       internal_a.bsize = bss_sec->size;
00981       if (internal_a.bsize && bss_sec->vma < internal_a.data_start)
00982        internal_a.data_start = bss_sec->vma;
00983     }
00984 
00985   internal_a.entry = bfd_get_start_address (abfd);
00986   internal_f.f_nsyms = obj_raw_syment_count (abfd);
00987 
00988   if (xcoff_data (abfd)->full_aouthdr)
00989     {
00990       bfd_vma toc;
00991       asection *loader_sec;
00992 
00993       internal_a.vstamp = 1;
00994 
00995       internal_a.o_snentry = xcoff_data (abfd)->snentry;
00996       if (internal_a.o_snentry == 0)
00997        internal_a.entry = (bfd_vma) -1;
00998 
00999       if (text_sec != NULL)
01000        {
01001          internal_a.o_sntext = text_sec->target_index;
01002          internal_a.o_algntext = bfd_get_section_alignment (abfd, text_sec);
01003        }
01004       else
01005        {
01006          internal_a.o_sntext = 0;
01007          internal_a.o_algntext = 0;
01008        }
01009 
01010       if (data_sec != NULL)
01011        {
01012          internal_a.o_sndata = data_sec->target_index;
01013          internal_a.o_algndata = bfd_get_section_alignment (abfd, data_sec);
01014        }
01015       else
01016        {
01017          internal_a.o_sndata = 0;
01018          internal_a.o_algndata = 0;
01019        }
01020 
01021       loader_sec = bfd_get_section_by_name (abfd, ".loader");
01022       if (loader_sec != NULL)
01023        internal_a.o_snloader = loader_sec->target_index;
01024       else
01025        internal_a.o_snloader = 0;
01026       if (bss_sec != NULL)
01027        internal_a.o_snbss = bss_sec->target_index;
01028       else
01029        internal_a.o_snbss = 0;
01030 
01031       toc = xcoff_data (abfd)->toc;
01032       internal_a.o_toc = toc;
01033       internal_a.o_sntoc = xcoff_data (abfd)->sntoc;
01034 
01035       internal_a.o_modtype = xcoff_data (abfd)->modtype;
01036       if (xcoff_data (abfd)->cputype != -1)
01037        internal_a.o_cputype = xcoff_data (abfd)->cputype;
01038       else
01039        {
01040          switch (bfd_get_arch (abfd))
01041            {
01042            case bfd_arch_rs6000:
01043              internal_a.o_cputype = 4;
01044              break;
01045            case bfd_arch_powerpc:
01046              if (bfd_get_mach (abfd) == bfd_mach_ppc)
01047               internal_a.o_cputype = 3;
01048              else
01049               internal_a.o_cputype = 1;
01050              break;
01051            default:
01052              abort ();
01053            }
01054        }
01055       internal_a.o_maxstack = xcoff_data (abfd)->maxstack;
01056       internal_a.o_maxdata = xcoff_data (abfd)->maxdata;
01057     }
01058 
01059   if (bfd_seek (abfd, (file_ptr) 0, 0) != 0)
01060     return FALSE;
01061 
01062   {
01063     char * buff;
01064     bfd_size_type amount = bfd_coff_filhsz (abfd);
01065 
01066     buff = bfd_malloc (amount);
01067     if (buff == NULL)
01068       return FALSE;
01069 
01070     bfd_coff_swap_filehdr_out (abfd, (PTR) &internal_f, (PTR) buff);
01071     amount = bfd_bwrite ((PTR) buff, amount, abfd);
01072 
01073     free (buff);
01074 
01075     if (amount != bfd_coff_filhsz (abfd))
01076       return FALSE;
01077   }
01078 
01079   if (abfd->flags & EXEC_P)
01080     {
01081       char * buff;
01082       bfd_size_type amount = bfd_coff_aoutsz (abfd);
01083 
01084       buff = bfd_malloc (amount);
01085       if (buff == NULL)
01086        return FALSE;
01087 
01088       bfd_coff_swap_aouthdr_out (abfd, (PTR) &internal_a, (PTR) buff);
01089       amount = bfd_bwrite ((PTR) buff, amount, abfd);
01090 
01091       free (buff);
01092 
01093       if (amount != bfd_coff_aoutsz (abfd))
01094        return FALSE;
01095     }
01096 
01097   return TRUE;
01098 }
01099 
01100 static bfd_boolean
01101 xcoff64_reloc_type_br (input_bfd, input_section, output_bfd, rel, sym, howto,
01102                      val, addend, relocation, contents)
01103      bfd *input_bfd;
01104      asection *input_section;
01105      bfd *output_bfd ATTRIBUTE_UNUSED;
01106      struct internal_reloc *rel;
01107      struct internal_syment *sym ATTRIBUTE_UNUSED;
01108      struct reloc_howto_struct *howto;
01109      bfd_vma val;
01110      bfd_vma addend;
01111      bfd_vma *relocation;
01112      bfd_byte *contents;
01113 {
01114   struct xcoff_link_hash_entry *h;
01115 
01116   if (0 > rel->r_symndx)
01117     return FALSE;
01118 
01119   h = obj_xcoff_sym_hashes (input_bfd)[rel->r_symndx];
01120 
01121   /* If we see an R_BR or R_RBR reloc which is jumping to global
01122      linkage code, and it is followed by an appropriate cror nop
01123      instruction, we replace the cror with ld r2,40(r1).  This
01124      restores the TOC after the glink code.  Contrariwise, if the
01125      call is followed by a ld r2,40(r1), but the call is not
01126      going to global linkage code, we can replace the load with a
01127      cror.  */
01128   if (NULL != h
01129       && bfd_link_hash_defined == h->root.type
01130       && rel->r_vaddr - input_section->vma + 8 <= input_section->size)
01131     {
01132       bfd_byte *pnext;
01133       unsigned long next;
01134 
01135       pnext = contents + (rel->r_vaddr - input_section->vma) + 4;
01136       next = bfd_get_32 (input_bfd, pnext);
01137 
01138       /* The _ptrgl function is magic.  It is used by the AIX compiler to call
01139         a function through a pointer.  */
01140       if (h->smclas == XMC_GL || strcmp (h->root.root.string, "._ptrgl") == 0)
01141        {
01142          if (next == 0x4def7b82                  /* cror 15,15,15  */
01143              || next == 0x4ffffb82               /* cror 31,31,31  */
01144              || next == 0x60000000)                     /* ori r0,r0,0         */
01145            bfd_put_32 (input_bfd, 0xe8410028, pnext);   /* ld  r2,40(r1) */
01146        }
01147       else
01148        {
01149          if (next == 0xe8410028)                 /* ld r2,40(r1)        */
01150            bfd_put_32 (input_bfd, 0x60000000, pnext);   /* ori r0,r0,0         */
01151        }
01152     }
01153   else if (NULL != h && bfd_link_hash_undefined == h->root.type)
01154     {
01155       /* Normally, this relocation is against a defined symbol.  In the
01156         case where this is a partial link and the output section offset
01157         is greater than 2^25, the linker will return an invalid error
01158         message that the relocation has been truncated.  Yes it has been
01159         truncated but no it not important.  For this case, disable the
01160         overflow checking. */
01161       howto->complain_on_overflow = complain_overflow_dont;
01162     }
01163 
01164   howto->pc_relative = TRUE;
01165   howto->src_mask &= ~3;
01166   howto->dst_mask = howto->src_mask;
01167 
01168   /* A PC relative reloc includes the section address.  */
01169   addend += input_section->vma;
01170 
01171   *relocation = val + addend;
01172   *relocation -= (input_section->output_section->vma
01173                 + input_section->output_offset);
01174   return TRUE;
01175 }
01176 
01177 /* This is the relocation function for the PowerPC64.
01178    See xcoff_ppc_relocation_section for more information. */
01179 
01180 bfd_boolean
01181 xcoff64_ppc_relocate_section (output_bfd, info, input_bfd,
01182                            input_section, contents, relocs, syms,
01183                            sections)
01184      bfd *output_bfd;
01185      struct bfd_link_info *info;
01186      bfd *input_bfd;
01187      asection *input_section;
01188      bfd_byte *contents;
01189      struct internal_reloc *relocs;
01190      struct internal_syment *syms;
01191      asection **sections;
01192 {
01193   struct internal_reloc *rel;
01194   struct internal_reloc *relend;
01195 
01196   rel = relocs;
01197   relend = rel + input_section->reloc_count;
01198   for (; rel < relend; rel++)
01199     {
01200       long symndx;
01201       struct xcoff_link_hash_entry *h;
01202       struct internal_syment *sym;
01203       bfd_vma addend;
01204       bfd_vma val;
01205       struct reloc_howto_struct howto;
01206       bfd_vma relocation;
01207       bfd_vma value_to_relocate;
01208       bfd_vma address;
01209       bfd_byte *location;
01210 
01211       /* Relocation type R_REF is a special relocation type which is
01212         merely used to prevent garbage collection from occurring for
01213         the csect including the symbol which it references.  */
01214       if (rel->r_type == R_REF)
01215        continue;
01216 
01217       /* howto */
01218       howto.type = rel->r_type;
01219       howto.rightshift = 0;
01220       howto.bitsize = (rel->r_size & 0x3f) + 1;
01221       howto.size = howto.bitsize > 16 ? (howto.bitsize > 32 ? 4 : 2) : 1;
01222       howto.pc_relative = FALSE;
01223       howto.bitpos = 0;
01224       howto.complain_on_overflow = (rel->r_size & 0x80
01225                                 ? complain_overflow_signed
01226                                 : complain_overflow_bitfield);
01227       howto.special_function = NULL;
01228       howto.name = "internal";
01229       howto.partial_inplace = TRUE;
01230       howto.src_mask = howto.dst_mask = N_ONES (howto.bitsize);
01231       howto.pcrel_offset = FALSE;
01232 
01233       /* symbol */
01234       val = 0;
01235       addend = 0;
01236       h = NULL;
01237       sym = NULL;
01238       symndx = rel->r_symndx;
01239 
01240       if (-1 != symndx)
01241        {
01242          asection *sec;
01243 
01244          h = obj_xcoff_sym_hashes (input_bfd)[symndx];
01245          sym = syms + symndx;
01246          addend = - sym->n_value;
01247 
01248          if (NULL == h)
01249            {
01250              sec = sections[symndx];
01251              /* Hack to make sure we use the right TOC anchor value
01252                if this reloc is against the TOC anchor.  */
01253              if (sec->name[3] == '0'
01254                 && strcmp (sec->name, ".tc0") == 0)
01255               val = xcoff_data (output_bfd)->toc;
01256              else
01257               val = (sec->output_section->vma
01258                      + sec->output_offset
01259                      + sym->n_value
01260                      - sec->vma);
01261            }
01262          else
01263            {
01264              if (h->root.type == bfd_link_hash_defined
01265                 || h->root.type == bfd_link_hash_defweak)
01266               {
01267                 sec = h->root.u.def.section;
01268                 val = (h->root.u.def.value
01269                       + sec->output_section->vma
01270                       + sec->output_offset);
01271               }
01272              else if (h->root.type == bfd_link_hash_common)
01273               {
01274                 sec = h->root.u.c.p->section;
01275                 val = (sec->output_section->vma
01276                       + sec->output_offset);
01277               }
01278              else if ((0 == (h->flags & (XCOFF_DEF_DYNAMIC | XCOFF_IMPORT)))
01279                      && ! info->relocatable)
01280               {
01281                 if (! ((*info->callbacks->undefined_symbol)
01282                       (info, h->root.root.string, input_bfd, input_section,
01283                        rel->r_vaddr - input_section->vma, TRUE)))
01284                   return FALSE;
01285 
01286                 /* Don't try to process the reloc.  It can't help, and
01287                    it may generate another error.  */
01288                 continue;
01289               }
01290            }
01291        }
01292 
01293       if (rel->r_type >= XCOFF_MAX_CALCULATE_RELOCATION
01294          || !((*xcoff64_calculate_relocation[rel->r_type])
01295              (input_bfd, input_section, output_bfd, rel, sym, &howto, val,
01296               addend, &relocation, contents)))
01297        return FALSE;
01298 
01299       /* address */
01300       address = rel->r_vaddr - input_section->vma;
01301       location = contents + address;
01302 
01303       if (address > input_section->size)
01304        abort ();
01305 
01306       /* Get the value we are going to relocate.  */
01307       if (1 == howto.size)
01308        value_to_relocate = bfd_get_16 (input_bfd, location);
01309       else if (2 == howto.size)
01310        value_to_relocate = bfd_get_32 (input_bfd, location);
01311       else
01312        value_to_relocate = bfd_get_64 (input_bfd, location);
01313 
01314       /* overflow.
01315 
01316         FIXME: We may drop bits during the addition
01317         which we don't check for.  We must either check at every single
01318         operation, which would be tedious, or we must do the computations
01319         in a type larger than bfd_vma, which would be inefficient.  */
01320 
01321       if ((unsigned int) howto.complain_on_overflow
01322          >= XCOFF_MAX_COMPLAIN_OVERFLOW)
01323        abort ();
01324 
01325       if (((*xcoff_complain_overflow[howto.complain_on_overflow])
01326           (input_bfd, value_to_relocate, relocation, &howto)))
01327        {
01328          const char *name;
01329          char buf[SYMNMLEN + 1];
01330          char reloc_type_name[10];
01331 
01332          if (symndx == -1)
01333            {
01334              name = "*ABS*";
01335            }
01336          else if (h != NULL)
01337            {
01338              name = NULL;
01339            }
01340          else
01341            {
01342              name = _bfd_coff_internal_syment_name (input_bfd, sym, buf);
01343              if (name == NULL)
01344               name = "UNKNOWN";
01345            }
01346          sprintf (reloc_type_name, "0x%02x", rel->r_type);
01347 
01348          if (! ((*info->callbacks->reloc_overflow)
01349                (info, (h ? &h->root : NULL), name, reloc_type_name,
01350                 (bfd_vma) 0, input_bfd, input_section,
01351                 rel->r_vaddr - input_section->vma)))
01352            return FALSE;
01353        }
01354 
01355       /* Add RELOCATION to the right bits of VALUE_TO_RELOCATE.  */
01356       value_to_relocate = ((value_to_relocate & ~howto.dst_mask)
01357                         | (((value_to_relocate & howto.src_mask)
01358                             + relocation) & howto.dst_mask));
01359 
01360       /* Put the value back in the object file.  */
01361       if (1 == howto.size)
01362        bfd_put_16 (input_bfd, value_to_relocate, location);
01363       else if (2 == howto.size)
01364        bfd_put_32 (input_bfd, value_to_relocate, location);
01365       else
01366        bfd_put_64 (input_bfd, value_to_relocate, location);
01367 
01368     }
01369   return TRUE;
01370 }
01371 
01372 
01373 /* The XCOFF reloc table.  Actually, XCOFF relocations specify the
01374    bitsize and whether they are signed or not, along with a
01375    conventional type.  This table is for the types, which are used for
01376    different algorithms for putting in the reloc.  Many of these
01377    relocs need special_function entries, which I have not written.  */
01378 
01379 reloc_howto_type xcoff64_howto_table[] =
01380 {
01381   /* Standard 64 bit relocation.  */
01382   HOWTO (R_POS,                    /* type */
01383         0,                  /* rightshift */
01384         4,                  /* size (0 = byte, 1 = short, 2 = long) */
01385         64,                 /* bitsize */
01386         FALSE,                     /* pc_relative */
01387         0,                  /* bitpos */
01388         complain_overflow_bitfield, /* complain_on_overflow */
01389         0,                  /* special_function */
01390         "R_POS_64",         /* name */
01391         TRUE,               /* partial_inplace */
01392         MINUS_ONE,          /* src_mask */
01393         MINUS_ONE,          /* dst_mask */
01394         FALSE),             /* pcrel_offset */
01395 
01396   /* 64 bit relocation, but store negative value.  */
01397   HOWTO (R_NEG,                    /* type */
01398         0,                  /* rightshift */
01399         -4,                 /* size (0 = byte, 1 = short, 2 = long) */
01400         64,                 /* bitsize */
01401         FALSE,                     /* pc_relative */
01402         0,                  /* bitpos */
01403         complain_overflow_bitfield, /* complain_on_overflow */
01404         0,                  /* special_function */
01405         "R_NEG",            /* name */
01406         TRUE,               /* partial_inplace */
01407         MINUS_ONE,          /* src_mask */
01408         MINUS_ONE,          /* dst_mask */
01409         FALSE),             /* pcrel_offset */
01410 
01411   /* 32 bit PC relative relocation.  */
01412   HOWTO (R_REL,                    /* type */
01413         0,                  /* rightshift */
01414         2,                  /* size (0 = byte, 1 = short, 2 = long) */
01415         32,                 /* bitsize */
01416         TRUE,               /* pc_relative */
01417         0,                  /* bitpos */
01418         complain_overflow_signed, /* complain_on_overflow */
01419         0,                  /* special_function */
01420         "R_REL",            /* name */
01421         TRUE,               /* partial_inplace */
01422         0xffffffff,         /* src_mask */
01423         0xffffffff,         /* dst_mask */
01424         FALSE),             /* pcrel_offset */
01425 
01426   /* 16 bit TOC relative relocation.  */
01427   HOWTO (R_TOC,                    /* type */
01428         0,                  /* rightshift */
01429         1,                  /* size (0 = byte, 1 = short, 2 = long) */
01430         16,                 /* bitsize */
01431         FALSE,                     /* pc_relative */
01432         0,                  /* bitpos */
01433         complain_overflow_bitfield, /* complain_on_overflow */
01434         0,                  /* special_function */
01435         "R_TOC",            /* name */
01436         TRUE,               /* partial_inplace */
01437         0xffff,             /* src_mask */
01438         0xffff,             /* dst_mask */
01439         FALSE),             /* pcrel_offset */
01440 
01441   /* I don't really know what this is.    */
01442   HOWTO (R_RTB,                    /* type */
01443         1,                  /* rightshift */
01444         2,                  /* size (0 = byte, 1 = short, 2 = long) */
01445         32,                 /* bitsize */
01446         FALSE,                     /* pc_relative */
01447         0,                  /* bitpos */
01448         complain_overflow_bitfield, /* complain_on_overflow */
01449         0,                  /* special_function */
01450         "R_RTB",            /* name */
01451         TRUE,               /* partial_inplace */
01452         0xffffffff,         /* src_mask */
01453         0xffffffff,         /* dst_mask */
01454         FALSE),             /* pcrel_offset */
01455 
01456   /* External TOC relative symbol.  */
01457   HOWTO (R_GL,                     /* type */
01458         0,                  /* rightshift */
01459         1,                  /* size (0 = byte, 1 = short, 2 = long) */
01460         16,                 /* bitsize */
01461         FALSE,                     /* pc_relative */
01462         0,                  /* bitpos */
01463         complain_overflow_bitfield, /* complain_on_overflow */
01464         0,                  /* special_function */
01465         "R_GL",             /* name */
01466         TRUE,               /* partial_inplace */
01467         0xffff,             /* src_mask */
01468         0xffff,             /* dst_mask */
01469         FALSE),             /* pcrel_offset */
01470 
01471   /* Local TOC relative symbol.     */
01472   HOWTO (R_TCL,                    /* type */
01473         0,                  /* rightshift */
01474         1,                  /* size (0 = byte, 1 = short, 2 = long) */
01475         16,                 /* bitsize */
01476         FALSE,                     /* pc_relative */
01477         0,                  /* bitpos */
01478         complain_overflow_bitfield, /* complain_on_overflow */
01479         0,                  /* special_function */
01480         "R_TCL",            /* name */
01481         TRUE,               /* partial_inplace */
01482         0xffff,             /* src_mask */
01483         0xffff,             /* dst_mask */
01484         FALSE),             /* pcrel_offset */
01485 
01486   EMPTY_HOWTO (7),
01487 
01488   /* Non modifiable absolute branch.  */
01489   HOWTO (R_BA,                     /* type */
01490         0,                  /* rightshift */
01491         2,                  /* size (0 = byte, 1 = short, 2 = long) */
01492         26,                 /* bitsize */
01493         FALSE,                     /* pc_relative */
01494         0,                  /* bitpos */
01495         complain_overflow_bitfield, /* complain_on_overflow */
01496         0,                  /* special_function */
01497         "R_BA_26",          /* name */
01498         TRUE,               /* partial_inplace */
01499         0x03fffffc,         /* src_mask */
01500         0x03fffffc,         /* dst_mask */
01501         FALSE),             /* pcrel_offset */
01502 
01503   EMPTY_HOWTO (9),
01504 
01505   /* Non modifiable relative branch.  */
01506   HOWTO (R_BR,                     /* type */
01507         0,                  /* rightshift */
01508         2,                  /* size (0 = byte, 1 = short, 2 = long) */
01509         26,                 /* bitsize */
01510         TRUE,               /* pc_relative */
01511         0,                  /* bitpos */
01512         complain_overflow_signed, /* complain_on_overflow */
01513         0,                  /* special_function */
01514         "R_BR",             /* name */
01515         TRUE,               /* partial_inplace */
01516         0x03fffffc,         /* src_mask */
01517         0x03fffffc,         /* dst_mask */
01518         FALSE),             /* pcrel_offset */
01519 
01520   EMPTY_HOWTO (0xb),
01521 
01522   /* Indirect load.  */
01523   HOWTO (R_RL,                     /* type */
01524         0,                  /* rightshift */
01525         1,                  /* size (0 = byte, 1 = short, 2 = long) */
01526         16,                 /* bitsize */
01527         FALSE,                     /* pc_relative */
01528         0,                  /* bitpos */
01529         complain_overflow_bitfield, /* complain_on_overflow */
01530         0,                  /* special_function */
01531         "R_RL",             /* name */
01532         TRUE,               /* partial_inplace */
01533         0xffff,             /* src_mask */
01534         0xffff,             /* dst_mask */
01535         FALSE),             /* pcrel_offset */
01536 
01537   /* Load address.  */
01538   HOWTO (R_RLA,                    /* type */
01539         0,                  /* rightshift */
01540         1,                  /* size (0 = byte, 1 = short, 2 = long) */
01541         16,                 /* bitsize */
01542         FALSE,                     /* pc_relative */
01543         0,                  /* bitpos */
01544         complain_overflow_bitfield, /* complain_on_overflow */
01545         0,                  /* special_function */
01546         "R_RLA",            /* name */
01547         TRUE,               /* partial_inplace */
01548         0xffff,             /* src_mask */
01549         0xffff,             /* dst_mask */
01550         FALSE),             /* pcrel_offset */
01551 
01552   EMPTY_HOWTO (0xe),
01553 
01554   /* Non-relocating reference.     */
01555   HOWTO (R_REF,                    /* type */
01556         0,                  /* rightshift */
01557         2,                  /* size (0 = byte, 1 = short, 2 = long) */
01558         32,                 /* bitsize */
01559         FALSE,                     /* pc_relative */
01560         0,                  /* bitpos */
01561         complain_overflow_dont, /* complain_on_overflow */
01562         0,                  /* special_function */
01563         "R_REF",            /* name */
01564         FALSE,                     /* partial_inplace */
01565         0,                  /* src_mask */
01566         0,                  /* dst_mask */
01567         FALSE),             /* pcrel_offset */
01568 
01569   EMPTY_HOWTO (0x10),
01570   EMPTY_HOWTO (0x11),
01571 
01572   /* TOC relative indirect load.  */
01573   HOWTO (R_TRL,                    /* type */
01574         0,                  /* rightshift */
01575         1,                  /* size (0 = byte, 1 = short, 2 = long) */
01576         16,                 /* bitsize */
01577         FALSE,                     /* pc_relative */
01578         0,                  /* bitpos */
01579         complain_overflow_bitfield, /* complain_on_overflow */
01580         0,                  /* special_function */
01581         "R_TRL",            /* name */
01582         TRUE,               /* partial_inplace */
01583         0xffff,             /* src_mask */
01584         0xffff,             /* dst_mask */
01585         FALSE),             /* pcrel_offset */
01586 
01587   /* TOC relative load address.     */
01588   HOWTO (R_TRLA,            /* type */
01589         0,                  /* rightshift */
01590         1,                  /* size (0 = byte, 1 = short, 2 = long) */
01591         16,                 /* bitsize */
01592         FALSE,                     /* pc_relative */
01593         0,                  /* bitpos */
01594         complain_overflow_bitfield, /* complain_on_overflow */
01595         0,                  /* special_function */
01596         "R_TRLA",           /* name */
01597         TRUE,               /* partial_inplace */
01598         0xffff,             /* src_mask */
01599         0xffff,             /* dst_mask */
01600         FALSE),             /* pcrel_offset */
01601 
01602   /* Modifiable relative branch.  */
01603   HOWTO (R_RRTBI,           /* type */
01604         1,                  /* rightshift */
01605         2,                  /* size (0 = byte, 1 = short, 2 = long) */
01606         32,                 /* bitsize */
01607         FALSE,                     /* pc_relative */
01608         0,                  /* bitpos */
01609         complain_overflow_bitfield, /* complain_on_overflow */
01610         0,                  /* special_function */
01611         "R_RRTBI",          /* name */
01612         TRUE,               /* partial_inplace */
01613         0xffffffff,         /* src_mask */
01614         0xffffffff,         /* dst_mask */
01615         FALSE),             /* pcrel_offset */
01616 
01617   /* Modifiable absolute branch.  */
01618   HOWTO (R_RRTBA,           /* type */
01619         1,                  /* rightshift */
01620         2,                  /* size (0 = byte, 1 = short, 2 = long) */
01621         32,                 /* bitsize */
01622         FALSE,                     /* pc_relative */
01623         0,                  /* bitpos */
01624         complain_overflow_bitfield, /* complain_on_overflow */
01625         0,                  /* special_function */
01626         "R_RRTBA",          /* name */
01627         TRUE,               /* partial_inplace */
01628         0xffffffff,         /* src_mask */
01629         0xffffffff,         /* dst_mask */
01630         FALSE),             /* pcrel_offset */
01631 
01632   /* Modifiable call absolute indirect.    */
01633   HOWTO (R_CAI,                    /* type */
01634         0,                  /* rightshift */
01635         1,                  /* size (0 = byte, 1 = short, 2 = long) */
01636         16,                 /* bitsize */
01637         FALSE,                     /* pc_relative */
01638         0,                  /* bitpos */
01639         complain_overflow_bitfield, /* complain_on_overflow */
01640         0,                  /* special_function */
01641         "R_CAI",            /* name */
01642         TRUE,               /* partial_inplace */
01643         0xffff,             /* src_mask */
01644         0xffff,             /* dst_mask */
01645         FALSE),             /* pcrel_offset */
01646 
01647   /* Modifiable call relative.     */
01648   HOWTO (R_CREL,            /* type */
01649         0,                  /* rightshift */
01650         1,                  /* size (0 = byte, 1 = short, 2 = long) */
01651         16,                 /* bitsize */
01652         FALSE,                     /* pc_relative */
01653         0,                  /* bitpos */
01654         complain_overflow_bitfield, /* complain_on_overflow */
01655         0,                  /* special_function */
01656         "R_CREL",           /* name */
01657         TRUE,               /* partial_inplace */
01658         0xffff,             /* src_mask */
01659         0xffff,             /* dst_mask */
01660         FALSE),             /* pcrel_offset */
01661 
01662   /* Modifiable branch absolute.  */
01663   HOWTO (R_RBA,                    /* type */
01664         0,                  /* rightshift */
01665         2,                  /* size (0 = byte, 1 = short, 2 = long) */
01666         26,                 /* bitsize */
01667         FALSE,                     /* pc_relative */
01668         0,                  /* bitpos */
01669         complain_overflow_bitfield, /* complain_on_overflow */
01670         0,                  /* special_function */
01671         "R_RBA",            /* name */
01672         TRUE,               /* partial_inplace */
01673         0x03fffffc,         /* src_mask */
01674         0x03fffffc,         /* dst_mask */
01675         FALSE),             /* pcrel_offset */
01676 
01677   /* Modifiable branch absolute.  */
01678   HOWTO (R_RBAC,            /* type */
01679         0,                  /* rightshift */
01680         2,                  /* size (0 = byte, 1 = short, 2 = long) */
01681         32,                 /* bitsize */
01682         FALSE,                     /* pc_relative */
01683         0,                  /* bitpos */
01684         complain_overflow_bitfield, /* complain_on_overflow */
01685         0,                  /* special_function */
01686         "R_RBAC",           /* name */
01687         TRUE,               /* partial_inplace */
01688         0xffffffff,         /* src_mask */
01689         0xffffffff,         /* dst_mask */
01690         FALSE),             /* pcrel_offset */
01691 
01692   /* Modifiable branch relative.  */
01693   HOWTO (R_RBR,                    /* type */
01694         0,                  /* rightshift */
01695         2,                  /* size (0 = byte, 1 = short, 2 = long) */
01696         26,                 /* bitsize */
01697         FALSE,                     /* pc_relative */
01698         0,                  /* bitpos */
01699         complain_overflow_signed, /* complain_on_overflow */
01700         0,                  /* special_function */
01701         "R_RBR_26",         /* name */
01702         TRUE,               /* partial_inplace */
01703         0x03fffffc,         /* src_mask */
01704         0x03fffffc,         /* dst_mask */
01705         FALSE),             /* pcrel_offset */
01706 
01707   /* Modifiable branch absolute.  */
01708   HOWTO (R_RBRC,            /* type */
01709         0,                  /* rightshift */
01710         1,                  /* size (0 = byte, 1 = short, 2 = long) */
01711         16,                 /* bitsize */
01712         FALSE,                     /* pc_relative */
01713         0,                  /* bitpos */
01714         complain_overflow_bitfield, /* complain_on_overflow */
01715         0,                  /* special_function */
01716         "R_RBRC",           /* name */
01717         TRUE,               /* partial_inplace */
01718         0xffff,             /* src_mask */
01719         0xffff,             /* dst_mask */
01720         FALSE),             /* pcrel_offset */
01721 
01722   HOWTO (R_POS,                    /* type */
01723         0,                  /* rightshift */
01724         2,                  /* size (0 = byte, 1 = short, 2 = long) */
01725         32,                 /* bitsize */
01726         FALSE,                     /* pc_relative */
01727         0,                  /* bitpos */
01728         complain_overflow_bitfield, /* complain_on_overflow */
01729         0,                  /* special_function */
01730         "R_POS_32",         /* name */
01731         TRUE,               /* partial_inplace */
01732         0xffffffff,         /* src_mask */
01733         0xffffffff,         /* dst_mask */
01734         FALSE),             /* pcrel_offset */
01735 
01736   /* 16 bit Non modifiable absolute branch.  */
01737   HOWTO (R_BA,                     /* type */
01738         0,                  /* rightshift */
01739         1,                  /* size (0 = byte, 1 = short, 2 = long) */
01740         16,                 /* bitsize */
01741         FALSE,                     /* pc_relative */
01742         0,                  /* bitpos */
01743         complain_overflow_bitfield, /* complain_on_overflow */
01744         0,                  /* special_function */
01745         "R_BA_16",          /* name */
01746         TRUE,               /* partial_inplace */
01747         0xfffc,             /* src_mask */
01748         0xfffc,             /* dst_mask */
01749         FALSE),             /* pcrel_offset */
01750 
01751   /* Modifiable branch relative.  */
01752   HOWTO (R_RBR,                    /* type */
01753         0,                  /* rightshift */
01754         1,                  /* size (0 = byte, 1 = short, 2 = long) */
01755         16,                 /* bitsize */
01756         FALSE,                     /* pc_relative */
01757         0,                  /* bitpos */
01758         complain_overflow_signed, /* complain_on_overflow */
01759         0,                  /* special_function */
01760         "R_RBR_16",         /* name */
01761         TRUE,               /* partial_inplace */
01762         0xffff,             /* src_mask */
01763         0xffff,             /* dst_mask */
01764         FALSE),             /* pcrel_offset */
01765 
01766   /* Modifiable branch absolute.  */
01767   HOWTO (R_RBA,                    /* type */
01768         0,                  /* rightshift */
01769         1,                  /* size (0 = byte, 1 = short, 2 = long) */
01770         16,                 /* bitsize */
01771         FALSE,                     /* pc_relative */
01772         0,                  /* bitpos */
01773         complain_overflow_bitfield, /* complain_on_overflow */
01774         0,                  /* special_function */
01775         "R_RBA_16",         /* name */
01776         TRUE,               /* partial_inplace */
01777         0xffff,             /* src_mask */
01778         0xffff,             /* dst_mask */
01779         FALSE),             /* pcrel_offset */
01780 
01781 };
01782 
01783 void
01784 xcoff64_rtype2howto (relent, internal)
01785      arelent *relent;
01786      struct internal_reloc *internal;
01787 {
01788   if (internal->r_type > R_RBRC)
01789     abort ();
01790 
01791   /* Default howto layout works most of the time */
01792   relent->howto = &xcoff64_howto_table[internal->r_type];
01793 
01794   /* Special case some 16 bit reloc */
01795   if (15 == (internal->r_size & 0x3f))
01796     {
01797       if (R_BA == internal->r_type)
01798        relent->howto = &xcoff64_howto_table[0x1d];
01799       else if (R_RBR == internal->r_type)
01800        relent->howto = &xcoff64_howto_table[0x1e];
01801       else if (R_RBA == internal->r_type)
01802        relent->howto = &xcoff64_howto_table[0x1f];
01803     }
01804   /* Special case 32 bit */
01805   else if (31 == (internal->r_size & 0x3f))
01806     {
01807       if (R_POS == internal->r_type)
01808        relent->howto = &xcoff64_howto_table[0x1c];
01809     }
01810 
01811   /* The r_size field of an XCOFF reloc encodes the bitsize of the
01812      relocation, as well as indicating whether it is signed or not.
01813      Doublecheck that the relocation information gathered from the
01814      type matches this information.  The bitsize is not significant
01815      for R_REF relocs.  */
01816   if (relent->howto->dst_mask != 0
01817       && (relent->howto->bitsize
01818          != ((unsigned int) internal->r_size & 0x3f) + 1))
01819     abort ();
01820 }
01821 
01822 reloc_howto_type *
01823 xcoff64_reloc_type_lookup (abfd, code)
01824      bfd *abfd ATTRIBUTE_UNUSED;
01825      bfd_reloc_code_real_type code;
01826 {
01827   switch (code)
01828     {
01829     case BFD_RELOC_PPC_B26:
01830       return &xcoff64_howto_table[0xa];
01831     case BFD_RELOC_PPC_BA16:
01832       return &xcoff64_howto_table[0x1d];
01833     case BFD_RELOC_PPC_BA26:
01834       return &xcoff64_howto_table[8];
01835     case BFD_RELOC_PPC_TOC16:
01836       return &xcoff64_howto_table[3];
01837     case BFD_RELOC_32:
01838     case BFD_RELOC_CTOR:
01839       return &xcoff64_howto_table[0x1c];
01840     case BFD_RELOC_64:
01841       return &xcoff64_howto_table[0];
01842     default:
01843       return NULL;
01844     }
01845 }
01846 
01847 static reloc_howto_type *
01848 xcoff64_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
01849                         const char *r_name)
01850 {
01851   unsigned int i;
01852 
01853   for (i = 0;
01854        i < sizeof (xcoff64_howto_table) / sizeof (xcoff64_howto_table[0]);
01855        i++)
01856     if (xcoff64_howto_table[i].name != NULL
01857        && strcasecmp (xcoff64_howto_table[i].name, r_name) == 0)
01858       return &xcoff64_howto_table[i];
01859 
01860   return NULL;
01861 }
01862 
01863 /* Read in the armap of an XCOFF archive.  */
01864 
01865 static bfd_boolean
01866 xcoff64_slurp_armap (abfd)
01867      bfd *abfd;
01868 {
01869   file_ptr off;
01870   size_t namlen;
01871   bfd_size_type sz, amt;
01872   bfd_byte *contents, *cend;
01873   bfd_vma c, i;
01874   carsym *arsym;
01875   bfd_byte *p;
01876   file_ptr pos;
01877 
01878   /* This is for the new format.  */
01879   struct xcoff_ar_hdr_big hdr;
01880 
01881   if (xcoff_ardata (abfd) == NULL)
01882     {
01883       bfd_has_map (abfd) = FALSE;
01884       return TRUE;
01885     }
01886 
01887   off = bfd_scan_vma (xcoff_ardata_big (abfd)->symoff64,
01888                     (const char **) NULL, 10);
01889   if (off == 0)
01890     {
01891       bfd_has_map (abfd) = FALSE;
01892       return TRUE;
01893     }
01894 
01895   if (bfd_seek (abfd, off, SEEK_SET) != 0)
01896     return FALSE;
01897 
01898   /* The symbol table starts with a normal archive header.  */
01899   if (bfd_bread ((PTR) &hdr, (bfd_size_type) SIZEOF_AR_HDR_BIG, abfd)
01900       != SIZEOF_AR_HDR_BIG)
01901     return FALSE;
01902 
01903   /* Skip the name (normally empty).  */
01904   namlen = strtol (hdr.namlen, (char **) NULL, 10);
01905   pos = ((namlen + 1) & ~(size_t) 1) + SXCOFFARFMAG;
01906   if (bfd_seek (abfd, pos, SEEK_CUR) != 0)
01907     return FALSE;
01908 
01909   sz = bfd_scan_vma (hdr.size, (const char **) NULL, 10);
01910 
01911   /* Read in the entire symbol table.  */
01912   contents = (bfd_byte *) bfd_alloc (abfd, sz);
01913   if (contents == NULL)
01914     return FALSE;
01915   if (bfd_bread ((PTR) contents, sz, abfd) != sz)
01916     return FALSE;
01917 
01918   /* The symbol table starts with an eight byte count.  */
01919   c = H_GET_64 (abfd, contents);
01920 
01921   if (c * 8 >= sz)
01922     {
01923       bfd_set_error (bfd_error_bad_value);
01924       return FALSE;
01925     }
01926   amt = c;
01927   amt *= sizeof (carsym);
01928   bfd_ardata (abfd)->symdefs = (carsym *) bfd_alloc (abfd, amt);
01929   if (bfd_ardata (abfd)->symdefs == NULL)
01930     return FALSE;
01931 
01932   /* After the count comes a list of eight byte file offsets.  */
01933   for (i = 0, arsym = bfd_ardata (abfd)->symdefs, p = contents + 8;
01934        i < c;
01935        ++i, ++arsym, p += 8)
01936     arsym->file_offset = H_GET_64 (abfd, p);
01937 
01938   /* After the file offsets come null terminated symbol names.  */
01939   cend = contents + sz;
01940   for (i = 0, arsym = bfd_ardata (abfd)->symdefs;
01941        i < c;
01942        ++i, ++arsym, p += strlen ((char *) p) + 1)
01943     {
01944       if (p >= cend)
01945        {
01946          bfd_set_error (bfd_error_bad_value);
01947          return FALSE;
01948        }
01949       arsym->name = (char *) p;
01950     }
01951 
01952   bfd_ardata (abfd)->symdef_count = c;
01953   bfd_has_map (abfd) = TRUE;
01954 
01955   return TRUE;
01956 }
01957 
01958 
01959 /* See if this is an NEW XCOFF archive.  */
01960 
01961 static const bfd_target *
01962 xcoff64_archive_p (abfd)
01963      bfd *abfd;
01964 {
01965   struct artdata *tdata_hold;
01966   char magic[SXCOFFARMAG];
01967   /* This is the new format.  */
01968   struct xcoff_ar_file_hdr_big hdr;
01969   bfd_size_type amt = SXCOFFARMAG;
01970 
01971   if (bfd_bread ((PTR) magic, amt, abfd) != amt)
01972     {
01973       if (bfd_get_error () != bfd_error_system_call)
01974        bfd_set_error (bfd_error_wrong_format);
01975       return NULL;
01976     }
01977 
01978   if (strncmp (magic, XCOFFARMAGBIG, SXCOFFARMAG) != 0)
01979     {
01980       bfd_set_error (bfd_error_wrong_format);
01981       return NULL;
01982     }
01983 
01984   /* Copy over the magic string.  */
01985   memcpy (hdr.magic, magic, SXCOFFARMAG);
01986 
01987   /* Now read the rest of the file header.  */
01988   amt = SIZEOF_AR_FILE_HDR_BIG - SXCOFFARMAG;
01989   if (bfd_bread ((PTR) &hdr.memoff, amt, abfd) != amt)
01990     {
01991       if (bfd_get_error () != bfd_error_system_call)
01992        bfd_set_error (bfd_error_wrong_format);
01993       return NULL;
01994     }
01995 
01996   tdata_hold = bfd_ardata (abfd);
01997 
01998   amt = sizeof (struct artdata);
01999   bfd_ardata (abfd) = (struct artdata *) bfd_zalloc (abfd, amt);
02000   if (bfd_ardata (abfd) == (struct artdata *) NULL)
02001     goto error_ret_restore;
02002 
02003   /* Already cleared by bfd_zalloc above.
02004      bfd_ardata (abfd)->cache = NULL;
02005      bfd_ardata (abfd)->archive_head = NULL;
02006      bfd_ardata (abfd)->symdefs = NULL;
02007      bfd_ardata (abfd)->extended_names = NULL;
02008      bfd_ardata (abfd)->extended_names_size = 0;  */
02009   bfd_ardata (abfd)->first_file_filepos = bfd_scan_vma (hdr.firstmemoff,
02010                                                  (const char **) NULL,
02011                                                  10);
02012 
02013   amt = SIZEOF_AR_FILE_HDR_BIG;
02014   bfd_ardata (abfd)->tdata = bfd_zalloc (abfd, amt);
02015   if (bfd_ardata (abfd)->tdata == NULL)
02016     goto error_ret;
02017 
02018   memcpy (bfd_ardata (abfd)->tdata, &hdr, SIZEOF_AR_FILE_HDR_BIG);
02019 
02020   if (! xcoff64_slurp_armap (abfd))
02021     {
02022     error_ret:
02023       bfd_release (abfd, bfd_ardata (abfd));
02024     error_ret_restore:
02025       bfd_ardata (abfd) = tdata_hold;
02026       return NULL;
02027     }
02028 
02029   return abfd->xvec;
02030 }
02031 
02032 
02033 /* Open the next element in an XCOFF archive.  */
02034 
02035 static bfd *
02036 xcoff64_openr_next_archived_file (archive, last_file)
02037      bfd *archive;
02038      bfd *last_file;
02039 {
02040   bfd_vma filestart;
02041 
02042   if ((xcoff_ardata (archive) == NULL)
02043       || ! xcoff_big_format_p (archive))
02044     {
02045       bfd_set_error (bfd_error_invalid_operation);
02046       return NULL;
02047     }
02048 
02049   if (last_file == NULL)
02050     {
02051       filestart = bfd_ardata (archive)->first_file_filepos;
02052     }
02053   else
02054     {
02055       filestart = bfd_scan_vma (arch_xhdr_big (last_file)->nextoff,
02056                             (const char **) NULL, 10);
02057     }
02058 
02059   if (filestart == 0
02060       || filestart == bfd_scan_vma (xcoff_ardata_big (archive)->memoff,
02061                                 (const char **) NULL, 10)
02062       || filestart == bfd_scan_vma (xcoff_ardata_big (archive)->symoff,
02063                                 (const char **) NULL, 10))
02064     {
02065       bfd_set_error (bfd_error_no_more_archived_files);
02066       return NULL;
02067     }
02068 
02069   return _bfd_get_elt_at_filepos (archive, (file_ptr) filestart);
02070 }
02071 
02072 /* We can't use the usual coff_sizeof_headers routine, because AIX
02073    always uses an a.out header.  */
02074 
02075 static int
02076 xcoff64_sizeof_headers (bfd *abfd,
02077                      struct bfd_link_info *info ATTRIBUTE_UNUSED)
02078 {
02079   int size;
02080 
02081   size = bfd_coff_filhsz (abfd);
02082 
02083   /* Don't think the small aout header can be used since some of the
02084      old elements have been reordered past the end of the old coff
02085      small aout size.  */
02086 
02087   if (xcoff_data (abfd)->full_aouthdr)
02088     size += bfd_coff_aoutsz (abfd);
02089 
02090   size += abfd->section_count * bfd_coff_scnhsz (abfd);
02091   return size;
02092 }
02093 
02094 
02095 
02096 static asection *
02097 xcoff64_create_csect_from_smclas (abfd, aux, symbol_name)
02098      bfd *abfd;
02099      union internal_auxent *aux;
02100      const char *symbol_name;
02101 {
02102   asection *return_value = NULL;
02103 
02104   /* Changes from 32 :
02105      .sv == 8, is only for 32 bit programs
02106      .ti == 12 and .tb == 13 are now reserved.  */
02107   static const char *names[19] =
02108   {
02109     ".pr", ".ro", ".db", ".tc", ".ua", ".rw", ".gl", ".xo",
02110     NULL, ".bs", ".ds", ".uc", NULL,  NULL,  NULL,  ".tc0",
02111     ".td", ".sv64", ".sv3264"
02112   };
02113 
02114   if ((19 >= aux->x_csect.x_smclas)
02115       && (NULL != names[aux->x_csect.x_smclas]))
02116     {
02117 
02118       return_value = bfd_make_section_anyway
02119        (abfd, names[aux->x_csect.x_smclas]);
02120 
02121     }
02122   else
02123     {
02124       (*_bfd_error_handler)
02125        (_("%B: symbol `%s' has unrecognized smclas %d"),
02126         abfd, symbol_name, aux->x_csect.x_smclas);
02127       bfd_set_error (bfd_error_bad_value);
02128     }
02129 
02130   return return_value;
02131 }
02132 
02133 static bfd_boolean
02134 xcoff64_is_lineno_count_overflow (abfd, value)
02135      bfd *abfd ATTRIBUTE_UNUSED;
02136      bfd_vma value ATTRIBUTE_UNUSED;
02137 {
02138   return FALSE;
02139 }
02140 
02141 static bfd_boolean
02142 xcoff64_is_reloc_count_overflow (abfd, value)
02143      bfd *abfd ATTRIBUTE_UNUSED;
02144      bfd_vma value ATTRIBUTE_UNUSED;
02145 {
02146   return FALSE;
02147 }
02148 
02149 static bfd_vma
02150 xcoff64_loader_symbol_offset (abfd, ldhdr)
02151      bfd *abfd ATTRIBUTE_UNUSED;
02152      struct internal_ldhdr *ldhdr;
02153 {
02154   return (ldhdr->l_symoff);
02155 }
02156 
02157 static bfd_vma
02158 xcoff64_loader_reloc_offset (abfd, ldhdr)
02159      bfd *abfd ATTRIBUTE_UNUSED;
02160      struct internal_ldhdr *ldhdr;
02161 {
02162   return (ldhdr->l_rldoff);
02163 }
02164 
02165 static bfd_boolean
02166 xcoff64_bad_format_hook (abfd, filehdr)
02167      bfd * abfd;
02168      PTR filehdr;
02169 {
02170   struct internal_filehdr *internal_f = (struct internal_filehdr *) filehdr;
02171 
02172   /* Check flavor first.  */
02173   if (bfd_get_flavour (abfd) != bfd_target_xcoff_flavour)
02174     return FALSE;
02175 
02176   if (bfd_xcoff_magic_number (abfd) != internal_f->f_magic)
02177     return FALSE;
02178 
02179   return TRUE;
02180 }
02181 
02182 static bfd_boolean
02183 xcoff64_generate_rtinit (abfd, init, fini, rtld)
02184      bfd *abfd;
02185      const char *init;
02186      const char *fini;
02187      bfd_boolean rtld;
02188 {
02189   bfd_byte filehdr_ext[FILHSZ];
02190   bfd_byte scnhdr_ext[SCNHSZ * 3];
02191   bfd_byte syment_ext[SYMESZ * 10];
02192   bfd_byte reloc_ext[RELSZ * 3];
02193   bfd_byte *data_buffer;
02194   bfd_size_type data_buffer_size;
02195   bfd_byte *string_table, *st_tmp;
02196   bfd_size_type string_table_size;
02197   bfd_vma val;
02198   size_t initsz, finisz;
02199   struct internal_filehdr filehdr;
02200   struct internal_scnhdr text_scnhdr;
02201   struct internal_scnhdr data_scnhdr;
02202   struct internal_scnhdr bss_scnhdr;
02203   struct internal_syment syment;
02204   union internal_auxent auxent;
02205   struct internal_reloc reloc;
02206 
02207   char *text_name = ".text";
02208   char *data_name = ".data";
02209   char *bss_name = ".bss";
02210   char *rtinit_name = "__rtinit";
02211   char *rtld_name = "__rtld";
02212 
02213   if (! bfd_xcoff_rtinit_size (abfd))
02214     return FALSE;
02215 
02216   initsz = (init == NULL ? 0 : 1 + strlen (init));
02217   finisz = (fini == NULL ? 0 : 1 + strlen (fini));
02218 
02219   /* File header.  */
02220   memset (filehdr_ext, 0, FILHSZ);
02221   memset (&filehdr, 0, sizeof (struct internal_filehdr));
02222   filehdr.f_magic = bfd_xcoff_magic_number (abfd);
02223   filehdr.f_nscns = 3;
02224   filehdr.f_timdat = 0;
02225   filehdr.f_nsyms = 0;  /* at least 6, no more than 8 */
02226   filehdr.f_symptr = 0; /* set below */
02227   filehdr.f_opthdr = 0;
02228   filehdr.f_flags = 0;
02229 
02230   /* Section headers.  */
02231   memset (scnhdr_ext, 0, 3 * SCNHSZ);
02232 
02233   /* Text.  */
02234   memset (&text_scnhdr, 0, sizeof (struct internal_scnhdr));
02235   memcpy (text_scnhdr.s_name, text_name, strlen (text_name));
02236   text_scnhdr.s_paddr = 0;
02237   text_scnhdr.s_vaddr = 0;
02238   text_scnhdr.s_size = 0;
02239   text_scnhdr.s_scnptr = 0;
02240   text_scnhdr.s_relptr = 0;
02241   text_scnhdr.s_lnnoptr = 0;
02242   text_scnhdr.s_nreloc = 0;
02243   text_scnhdr.s_nlnno = 0;
02244   text_scnhdr.s_flags = STYP_TEXT;
02245 
02246   /* Data.  */
02247   memset (&data_scnhdr, 0, sizeof (struct internal_scnhdr));
02248   memcpy (data_scnhdr.s_name, data_name, strlen (data_name));
02249   data_scnhdr.s_paddr = 0;
02250   data_scnhdr.s_vaddr = 0;
02251   data_scnhdr.s_size = 0;    /* set below */
02252   data_scnhdr.s_scnptr = FILHSZ + 3 * SCNHSZ;
02253   data_scnhdr.s_relptr = 0;  /* set below */
02254   data_scnhdr.s_lnnoptr = 0;
02255   data_scnhdr.s_nreloc = 0;  /* either 1 or 2 */
02256   data_scnhdr.s_nlnno = 0;
02257   data_scnhdr.s_flags = STYP_DATA;
02258 
02259   /* Bss.  */
02260   memset (&bss_scnhdr, 0, sizeof (struct internal_scnhdr));
02261   memcpy (bss_scnhdr.s_name, bss_name, strlen (bss_name));
02262   bss_scnhdr.s_paddr = 0; /* set below */
02263   bss_scnhdr.s_vaddr = 0; /* set below */
02264   bss_scnhdr.s_size = 0;  /* set below */
02265   bss_scnhdr.s_scnptr = 0;
02266   bss_scnhdr.s_relptr = 0;
02267   bss_scnhdr.s_lnnoptr = 0;
02268   bss_scnhdr.s_nreloc = 0;
02269   bss_scnhdr.s_nlnno = 0;
02270   bss_scnhdr.s_flags = STYP_BSS;
02271 
02272   /* .data
02273      0x0000         0x00000000 : rtl
02274      0x0004         0x00000000 :
02275      0x0008         0x00000018 : offset to init, or 0
02276      0x000C         0x00000038 : offset to fini, or 0
02277      0x0010         0x00000010 : size of descriptor
02278      0x0014         0x00000000 : pad
02279      0x0018         0x00000000 : init, needs a reloc
02280      0x001C         0x00000000 :
02281      0x0020         0x00000058 : offset to init name
02282      0x0024         0x00000000 : flags, padded to a word
02283      0x0028         0x00000000 : empty init
02284      0x002C         0x00000000 :
02285      0x0030         0x00000000 :
02286      0x0034         0x00000000 :
02287      0x0038         0x00000000 : fini, needs a reloc
02288      0x003C         0x00000000 :
02289      0x0040         0x00000??? : offset to fini name
02290      0x0044         0x00000000 : flags, padded to a word
02291      0x0048         0x00000000 : empty fini
02292      0x004C         0x00000000 :
02293      0x0050         0x00000000 :
02294      0x0054         0x00000000 :
02295      0x0058         init name
02296      0x0058 + initsz  fini name */
02297 
02298   data_buffer_size = 0x0058 + initsz + finisz;
02299   data_buffer_size = (data_buffer_size + 7) &~ (bfd_size_type) 7;
02300   data_buffer = NULL;
02301   data_buffer = (bfd_byte *) bfd_zmalloc (data_buffer_size);
02302   if (data_buffer == NULL)
02303     return FALSE;
02304 
02305   if (initsz)
02306     {
02307       val = 0x18;
02308       bfd_put_32 (abfd, val, &data_buffer[0x08]);
02309       val = 0x58;
02310       bfd_put_32 (abfd, val, &data_buffer[0x20]);
02311       memcpy (&data_buffer[val], init, initsz);
02312     }
02313 
02314   if (finisz)
02315     {
02316       val = 0x38;
02317       bfd_put_32 (abfd, val, &data_buffer[0x0C]);
02318       val = 0x58 + initsz;
02319       bfd_put_32 (abfd, val, &data_buffer[0x40]);
02320       memcpy (&data_buffer[val], fini, finisz);
02321     }
02322 
02323   val = 0x10;
02324   bfd_put_32 (abfd, val, &data_buffer[0x10]);
02325   data_scnhdr.s_size = data_buffer_size;
02326   bss_scnhdr.s_paddr = bss_scnhdr.s_vaddr = data_scnhdr.s_size;
02327 
02328   /* String table.  */
02329   string_table_size = 4;
02330   string_table_size += strlen (data_name) + 1;
02331   string_table_size += strlen (rtinit_name) + 1;
02332   string_table_size += initsz;
02333   string_table_size += finisz;
02334   if (rtld)
02335     string_table_size += strlen (rtld_name) + 1;
02336 
02337   string_table = (bfd_byte *) bfd_zmalloc (string_table_size);
02338   if (string_table == NULL)
02339     return FALSE;
02340 
02341   val = string_table_size;
02342   bfd_put_32 (abfd, val, &string_table[0]);
02343   st_tmp = string_table + 4;
02344 
02345   /* symbols
02346      0. .data csect
02347      2. __rtinit
02348      4. init function
02349      6. fini function
02350      8. __rtld  */
02351   memset (syment_ext, 0, 10 * SYMESZ);
02352   memset (reloc_ext, 0, 3 * RELSZ);
02353 
02354   /* .data csect */
02355   memset (&syment, 0, sizeof (struct internal_syment));
02356   memset (&auxent, 0, sizeof (union internal_auxent));
02357 
02358   syment._n._n_n._n_offset = st_tmp - string_table;
02359   memcpy (st_tmp, data_name, strlen (data_name));
02360   st_tmp += strlen (data_name) + 1;
02361 
02362   syment.n_scnum = 2;
02363   syment.n_sclass = C_HIDEXT;
02364   syment.n_numaux = 1;
02365   auxent.x_csect.x_scnlen.l = data_buffer_size;
02366   auxent.x_csect.x_smtyp = 3 << 3 | XTY_SD;
02367   auxent.x_csect.x_smclas = XMC_RW;
02368   bfd_coff_swap_sym_out (abfd, &syment,
02369                       &syment_ext[filehdr.f_nsyms * SYMESZ]);
02370   bfd_coff_swap_aux_out (abfd, &auxent, syment.n_type, syment.n_sclass, 0,
02371                       syment.n_numaux,
02372                       &syment_ext[(filehdr.f_nsyms + 1) * SYMESZ]);
02373   filehdr.f_nsyms += 2;
02374 
02375   /* __rtinit */
02376   memset (&syment, 0, sizeof (struct internal_syment));
02377   memset (&auxent, 0, sizeof (union internal_auxent));
02378   syment._n._n_n._n_offset = st_tmp - string_table;
02379   memcpy (st_tmp, rtinit_name, strlen (rtinit_name));
02380   st_tmp += strlen (rtinit_name) + 1;
02381 
02382   syment.n_scnum = 2;
02383   syment.n_sclass = C_EXT;
02384   syment.n_numaux = 1;
02385   auxent.x_csect.x_smtyp = XTY_LD;
02386   auxent.x_csect.x_smclas = XMC_RW;
02387   bfd_coff_swap_sym_out (abfd, &syment,
02388                       &syment_ext[filehdr.f_nsyms * SYMESZ]);
02389   bfd_coff_swap_aux_out (abfd, &auxent, syment.n_type, syment.n_sclass, 0,
02390                       syment.n_numaux,
02391                       &syment_ext[(filehdr.f_nsyms + 1) * SYMESZ]);
02392   filehdr.f_nsyms += 2;
02393 
02394   /* Init.  */
02395   if (initsz)
02396     {
02397       memset (&syment, 0, sizeof (struct internal_syment));
02398       memset (&auxent, 0, sizeof (union internal_auxent));
02399 
02400       syment._n._n_n._n_offset = st_tmp - string_table;
02401       memcpy (st_tmp, init, initsz);
02402       st_tmp += initsz;
02403 
02404       syment.n_sclass = C_EXT;
02405       syment.n_numaux = 1;
02406       bfd_coff_swap_sym_out (abfd, &syment,
02407                           &syment_ext[filehdr.f_nsyms * SYMESZ]);
02408       bfd_coff_swap_aux_out (abfd, &auxent, syment.n_type, syment.n_sclass, 0,
02409                           syment.n_numaux,
02410                           &syment_ext[(filehdr.f_nsyms + 1) * SYMESZ]);
02411       /* Reloc.  */
02412       memset (&reloc, 0, sizeof (struct internal_reloc));
02413       reloc.r_vaddr = 0x0018;
02414       reloc.r_symndx = filehdr.f_nsyms;
02415       reloc.r_type = R_POS;
02416       reloc.r_size = 63;
02417       bfd_coff_swap_reloc_out (abfd, &reloc, &reloc_ext[0]);
02418 
02419       filehdr.f_nsyms += 2;
02420       data_scnhdr.s_nreloc += 1;
02421     }
02422 
02423   /* Finit.  */
02424   if (finisz)
02425     {
02426       memset (&syment, 0, sizeof (struct internal_syment));
02427       memset (&auxent, 0, sizeof (union internal_auxent));
02428 
02429       syment._n._n_n._n_offset = st_tmp - string_table;
02430       memcpy (st_tmp, fini, finisz);
02431       st_tmp += finisz;
02432 
02433       syment.n_sclass = C_EXT;
02434       syment.n_numaux = 1;
02435       bfd_coff_swap_sym_out (abfd, &syment,
02436                           &syment_ext[filehdr.f_nsyms * SYMESZ]);
02437       bfd_coff_swap_aux_out (abfd, &auxent, syment.n_type, syment.n_sclass, 0,
02438                           syment.n_numaux,
02439                           &syment_ext[(filehdr.f_nsyms + 1) * SYMESZ]);
02440 
02441       /* Reloc.  */
02442       memset (&reloc, 0, sizeof (struct internal_reloc));
02443       reloc.r_vaddr = 0x0038;
02444       reloc.r_symndx = filehdr.f_nsyms;
02445       reloc.r_type = R_POS;
02446       reloc.r_size = 63;
02447       bfd_coff_swap_reloc_out (abfd, &reloc,
02448                             &reloc_ext[data_scnhdr.s_nreloc * RELSZ]);
02449 
02450       filehdr.f_nsyms += 2;
02451       data_scnhdr.s_nreloc += 1;
02452     }
02453 
02454   if (rtld)
02455     {
02456       memset (&syment, 0, sizeof (struct internal_syment));
02457       memset (&auxent, 0, sizeof (union internal_auxent));
02458 
02459       syment._n._n_n._n_offset = st_tmp - string_table;
02460       memcpy (st_tmp, rtld_name, strlen (rtld_name));
02461       st_tmp += strlen (rtld_name) + 1;
02462 
02463       syment.n_sclass = C_EXT;
02464       syment.n_numaux = 1;
02465       bfd_coff_swap_sym_out (abfd, &syment,
02466                           &syment_ext[filehdr.f_nsyms * SYMESZ]);
02467       bfd_coff_swap_aux_out (abfd, &auxent, syment.n_type, syment.n_sclass, 0,
02468                           syment.n_numaux,
02469                           &syment_ext[(filehdr.f_nsyms + 1) * SYMESZ]);
02470 
02471       /* Reloc.  */
02472       memset (&reloc, 0, sizeof (struct internal_reloc));
02473       reloc.r_vaddr = 0x0000;
02474       reloc.r_symndx = filehdr.f_nsyms;
02475       reloc.r_type = R_POS;
02476       reloc.r_size = 63;
02477       bfd_coff_swap_reloc_out (abfd, &reloc,
02478                             &reloc_ext[data_scnhdr.s_nreloc * RELSZ]);
02479 
02480       filehdr.f_nsyms += 2;
02481       data_scnhdr.s_nreloc += 1;
02482 
02483       bss_scnhdr.s_size = 0;
02484     }
02485 
02486   data_scnhdr.s_relptr = data_scnhdr.s_scnptr + data_buffer_size;
02487   filehdr.f_symptr = data_scnhdr.s_relptr + data_scnhdr.s_nreloc * RELSZ;
02488 
02489   bfd_coff_swap_filehdr_out (abfd, &filehdr, filehdr_ext);
02490   bfd_bwrite (filehdr_ext, FILHSZ, abfd);
02491   bfd_coff_swap_scnhdr_out (abfd, &text_scnhdr, &scnhdr_ext[SCNHSZ * 0]);
02492   bfd_coff_swap_scnhdr_out (abfd, &data_scnhdr, &scnhdr_ext[SCNHSZ * 1]);
02493   bfd_coff_swap_scnhdr_out (abfd, &bss_scnhdr, &scnhdr_ext[SCNHSZ * 2]);
02494   bfd_bwrite (scnhdr_ext, 3 * SCNHSZ, abfd);
02495   bfd_bwrite (data_buffer, data_buffer_size, abfd);
02496   bfd_bwrite (reloc_ext, data_scnhdr.s_nreloc * RELSZ, abfd);
02497   bfd_bwrite (syment_ext, filehdr.f_nsyms * SYMESZ, abfd);
02498   bfd_bwrite (string_table, string_table_size, abfd);
02499 
02500   free (data_buffer);
02501   data_buffer = NULL;
02502 
02503   return TRUE;
02504 }
02505 
02506 /* The typical dynamic reloc.  */
02507 
02508 static reloc_howto_type xcoff64_dynamic_reloc =
02509 HOWTO (0,                   /* type */
02510        0,                   /* rightshift */
02511        4,                   /* size (0 = byte, 1 = short, 2 = long) */
02512        64,                  /* bitsize */
02513        FALSE,               /* pc_relative */
02514        0,                   /* bitpos */
02515        complain_overflow_bitfield, /* complain_on_overflow */
02516        0,                   /* special_function */
02517        "R_POS",                    /* name */
02518        TRUE,                /* partial_inplace */
02519        MINUS_ONE,           /* src_mask */
02520        MINUS_ONE,           /* dst_mask */
02521        FALSE);                     /* pcrel_offset */
02522 
02523 static unsigned long xcoff64_glink_code[10] =
02524 {
02525   0xe9820000, /* ld r12,0(r2) */
02526   0xf8410028, /* std r2,40(r1) */
02527   0xe80c0000, /* ld r0,0(r12) */
02528   0xe84c0008, /* ld r0,8(r12) */
02529   0x7c0903a6, /* mtctr r0 */
02530   0x4e800420, /* bctr */
02531   0x00000000, /* start of traceback table */
02532   0x000ca000, /* traceback table */
02533   0x00000000, /* traceback table */
02534   0x00000018, /* ??? */
02535 };
02536 
02537 static const struct xcoff_backend_data_rec bfd_xcoff_backend_data =
02538   {
02539     { /* COFF backend, defined in libcoff.h.  */
02540       _bfd_xcoff64_swap_aux_in,
02541       _bfd_xcoff64_swap_sym_in,
02542       _bfd_xcoff64_swap_lineno_in,
02543       _bfd_xcoff64_swap_aux_out,
02544       _bfd_xcoff64_swap_sym_out,
02545       _bfd_xcoff64_swap_lineno_out,
02546       xcoff64_swap_reloc_out,
02547       coff_swap_filehdr_out,
02548       coff_swap_aouthdr_out,
02549       coff_swap_scnhdr_out,
02550       FILHSZ,
02551       AOUTSZ,
02552       SCNHSZ,
02553       SYMESZ,
02554       AUXESZ,
02555       RELSZ,
02556       LINESZ,
02557       FILNMLEN,
02558       TRUE,                 /* _bfd_coff_long_filenames */
02559       FALSE,                /* _bfd_coff_long_section_names */
02560       3,                    /* _bfd_coff_default_section_alignment_power */
02561       TRUE,                 /* _bfd_coff_force_symnames_in_strings */
02562       4,                    /* _bfd_coff_debug_string_prefix_length */
02563       coff_swap_filehdr_in,
02564       coff_swap_aouthdr_in,
02565       coff_swap_scnhdr_in,
02566       xcoff64_swap_reloc_in,
02567       xcoff64_bad_format_hook,
02568       coff_set_arch_mach_hook,
02569       coff_mkobject_hook,
02570       styp_to_sec_flags,
02571       coff_set_alignment_hook,
02572       coff_slurp_symbol_table,
02573       symname_in_debug_hook,
02574       coff_pointerize_aux_hook,
02575       coff_print_aux,
02576       dummy_reloc16_extra_cases,
02577       dummy_reloc16_estimate,
02578       NULL,                 /* bfd_coff_sym_is_global */
02579       coff_compute_section_file_positions,
02580       NULL,                 /* _bfd_coff_start_final_link */
02581       xcoff64_ppc_relocate_section,
02582       coff_rtype_to_howto,
02583       NULL,                 /* _bfd_coff_adjust_symndx */
02584       _bfd_generic_link_add_one_symbol,
02585       coff_link_output_has_begun,
02586       coff_final_link_postscript
02587     },
02588 
02589     0x01EF,                 /* magic number */
02590     bfd_arch_powerpc,
02591     bfd_mach_ppc_620,
02592 
02593     /* Function pointers to xcoff specific swap routines.  */
02594     xcoff64_swap_ldhdr_in,
02595     xcoff64_swap_ldhdr_out,
02596     xcoff64_swap_ldsym_in,
02597     xcoff64_swap_ldsym_out,
02598     xcoff64_swap_ldrel_in,
02599     xcoff64_swap_ldrel_out,
02600 
02601     /* Sizes.  */
02602     LDHDRSZ,
02603     LDSYMSZ,
02604     LDRELSZ,
02605     24,                            /* _xcoff_function_descriptor_size */
02606     0,                      /* _xcoff_small_aout_header_size */
02607 
02608     /* Versions.  */
02609     2,                      /* _xcoff_ldhdr_version */
02610 
02611     _bfd_xcoff64_put_symbol_name,
02612     _bfd_xcoff64_put_ldsymbol_name,
02613     &xcoff64_dynamic_reloc,
02614     xcoff64_create_csect_from_smclas,
02615 
02616     /* Lineno and reloc count overflow.  */
02617     xcoff64_is_lineno_count_overflow,
02618     xcoff64_is_reloc_count_overflow,
02619 
02620     xcoff64_loader_symbol_offset,
02621     xcoff64_loader_reloc_offset,
02622 
02623     /* glink.  */
02624     &xcoff64_glink_code[0],
02625     40,                            /* _xcoff_glink_size */
02626 
02627     /* rtinit.  */
02628     88,                            /* _xcoff_rtinit_size */
02629     xcoff64_generate_rtinit,
02630   };
02631 
02632 /* The transfer vector that leads the outside world to all of the above.  */
02633 const bfd_target rs6000coff64_vec =
02634   {
02635     "aixcoff64-rs6000",
02636     bfd_target_xcoff_flavour,
02637     BFD_ENDIAN_BIG,         /* data byte order is big */
02638     BFD_ENDIAN_BIG,         /* header byte order is big */
02639 
02640     (HAS_RELOC | EXEC_P | HAS_LINENO | HAS_DEBUG | DYNAMIC
02641      | HAS_SYMS | HAS_LOCALS | WP_TEXT),
02642 
02643     SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_CODE | SEC_DATA,
02644     0,                      /* leading char */
02645     '/',                    /* ar_pad_char */
02646     15,                            /* ar_max_namelen */
02647 
02648     /* data */
02649     bfd_getb64,
02650     bfd_getb_signed_64,
02651     bfd_putb64,
02652     bfd_getb32,
02653     bfd_getb_signed_32,
02654     bfd_putb32,
02655     bfd_getb16,
02656     bfd_getb_signed_16,
02657     bfd_putb16,
02658 
02659     /* hdrs */
02660     bfd_getb64,
02661     bfd_getb_signed_64,
02662     bfd_putb64,
02663     bfd_getb32,
02664     bfd_getb_signed_32,
02665     bfd_putb32,
02666     bfd_getb16,
02667     bfd_getb_signed_16,
02668     bfd_putb16,
02669 
02670     { /* bfd_check_format */
02671       _bfd_dummy_target,
02672       coff_object_p,
02673       xcoff64_archive_p,
02674       CORE_FILE_P
02675     },
02676 
02677     { /* bfd_set_format */
02678       bfd_false,
02679       coff_mkobject,
02680       _bfd_generic_mkarchive,
02681       bfd_false
02682     },
02683 
02684     {/* bfd_write_contents */
02685       bfd_false,
02686       xcoff64_write_object_contents,
02687       _bfd_xcoff_write_archive_contents,
02688       bfd_false
02689     },
02690 
02691     /* Generic */
02692     bfd_true,
02693     bfd_true,
02694     coff_new_section_hook,
02695     _bfd_generic_get_section_contents,
02696     _bfd_generic_get_section_contents_in_window,
02697 
02698     /* Copy */
02699     _bfd_xcoff_copy_private_bfd_data,
02700     ((bfd_boolean (*) (bfd *, bfd *)) bfd_true),
02701     _bfd_generic_init_private_section_data,
02702     ((bfd_boolean (*) (bfd *, asection *, bfd *, asection *)) bfd_true),
02703     ((bfd_boolean (*) (bfd *, asymbol *, bfd *, asymbol *)) bfd_true),
02704     ((bfd_boolean (*) (bfd *, bfd *)) bfd_true),
02705     ((bfd_boolean (*) (bfd *, flagword)) bfd_true),
02706     ((bfd_boolean (*) (bfd *, void * )) bfd_true),
02707 
02708     /* Core */
02709     coff_core_file_failing_command,
02710     coff_core_file_failing_signal,
02711     coff_core_file_matches_executable_p,
02712 
02713     /* Archive */
02714     xcoff64_slurp_armap,
02715     bfd_false,
02716     ((bfd_boolean (*) (bfd *, char **, bfd_size_type *, const char **)) bfd_false),
02717     bfd_dont_truncate_arname,
02718     _bfd_xcoff_write_armap,
02719     _bfd_xcoff_read_ar_hdr,
02720     xcoff64_openr_next_archived_file,
02721     _bfd_generic_get_elt_at_index,
02722     _bfd_xcoff_stat_arch_elt,
02723     bfd_true,
02724 
02725     /* Symbols */
02726     coff_get_symtab_upper_bound,
02727     coff_canonicalize_symtab,
02728     coff_make_empty_symbol,
02729     coff_print_symbol,
02730     coff_get_symbol_info,
02731     _bfd_xcoff_is_local_label_name,
02732     coff_bfd_is_target_special_symbol,
02733     coff_get_lineno,
02734     coff_find_nearest_line,
02735     _bfd_generic_find_line,
02736     coff_find_inliner_info,
02737     coff_bfd_make_debug_symbol,
02738     _bfd_generic_read_minisymbols,
02739     _bfd_generic_minisymbol_to_symbol,
02740 
02741     /* Reloc */
02742     coff_get_reloc_upper_bound,
02743     coff_canonicalize_reloc,
02744     xcoff64_reloc_type_lookup,
02745     xcoff64_reloc_name_lookup,
02746 
02747     /* Write */
02748     coff_set_arch_mach,
02749     coff_set_section_contents,
02750 
02751     /* Link */
02752     xcoff64_sizeof_headers,
02753     bfd_generic_get_relocated_section_contents,
02754     bfd_generic_relax_section,
02755     _bfd_xcoff_bfd_link_hash_table_create,
02756     _bfd_generic_link_hash_table_free,
02757     _bfd_xcoff_bfd_link_add_symbols,
02758     _bfd_generic_link_just_syms,
02759     _bfd_xcoff_bfd_final_link,
02760     _bfd_generic_link_split_section,
02761     bfd_generic_gc_sections,
02762     bfd_generic_merge_sections,
02763     bfd_generic_is_group_section,
02764     bfd_generic_discard_group,
02765     _bfd_generic_section_already_linked,
02766 
02767     /* Dynamic */
02768     _bfd_xcoff_get_dynamic_symtab_upper_bound,
02769     _bfd_xcoff_canonicalize_dynamic_symtab,
02770     _bfd_nodynamic_get_synthetic_symtab,
02771     _bfd_xcoff_get_dynamic_reloc_upper_bound,
02772     _bfd_xcoff_canonicalize_dynamic_reloc,
02773 
02774     /* Opposite endian version, none exists */
02775     NULL,
02776 
02777     (void *) &bfd_xcoff_backend_data,
02778   };
02779 
02780 extern const bfd_target *xcoff64_core_p
02781   PARAMS ((bfd *));
02782 extern bfd_boolean xcoff64_core_file_matches_executable_p
02783   PARAMS ((bfd *, bfd *));
02784 extern char *xcoff64_core_file_failing_command
02785   PARAMS ((bfd *));
02786 extern int xcoff64_core_file_failing_signal
02787   PARAMS ((bfd *));
02788 
02789 /* AIX 5 */
02790 static const struct xcoff_backend_data_rec bfd_xcoff_aix5_backend_data =
02791   {
02792     { /* COFF backend, defined in libcoff.h.  */
02793       _bfd_xcoff64_swap_aux_in,
02794       _bfd_xcoff64_swap_sym_in,
02795       _bfd_xcoff64_swap_lineno_in,
02796       _bfd_xcoff64_swap_aux_out,
02797       _bfd_xcoff64_swap_sym_out,
02798       _bfd_xcoff64_swap_lineno_out,
02799       xcoff64_swap_reloc_out,
02800       coff_swap_filehdr_out,
02801       coff_swap_aouthdr_out,
02802       coff_swap_scnhdr_out,
02803       FILHSZ,
02804       AOUTSZ,
02805       SCNHSZ,
02806       SYMESZ,
02807       AUXESZ,
02808       RELSZ,
02809       LINESZ,
02810       FILNMLEN,
02811       TRUE,                 /* _bfd_coff_long_filenames */
02812       FALSE,                /* _bfd_coff_long_section_names */
02813       3,                    /* _bfd_coff_default_section_alignment_power */
02814       TRUE,                 /* _bfd_coff_force_symnames_in_strings */
02815       4,                    /* _bfd_coff_debug_string_prefix_length */
02816       coff_swap_filehdr_in,
02817       coff_swap_aouthdr_in,
02818       coff_swap_scnhdr_in,
02819       xcoff64_swap_reloc_in,
02820       xcoff64_bad_format_hook,
02821       coff_set_arch_mach_hook,
02822       coff_mkobject_hook,
02823       styp_to_sec_flags,
02824       coff_set_alignment_hook,
02825       coff_slurp_symbol_table,
02826       symname_in_debug_hook,
02827       coff_pointerize_aux_hook,
02828       coff_print_aux,
02829       dummy_reloc16_extra_cases,
02830       dummy_reloc16_estimate,
02831       NULL,                 /* bfd_coff_sym_is_global */
02832       coff_compute_section_file_positions,
02833       NULL,                 /* _bfd_coff_start_final_link */
02834       xcoff64_ppc_relocate_section,
02835       coff_rtype_to_howto,
02836       NULL,                 /* _bfd_coff_adjust_symndx */
02837       _bfd_generic_link_add_one_symbol,
02838       coff_link_output_has_begun,
02839       coff_final_link_postscript
02840     },
02841 
02842     U64_TOCMAGIC,           /* magic number */
02843     bfd_arch_powerpc,
02844     bfd_mach_ppc_620,
02845 
02846     /* Function pointers to xcoff specific swap routines.  */
02847     xcoff64_swap_ldhdr_in,
02848     xcoff64_swap_ldhdr_out,
02849     xcoff64_swap_ldsym_in,
02850     xcoff64_swap_ldsym_out,
02851     xcoff64_swap_ldrel_in,
02852     xcoff64_swap_ldrel_out,
02853 
02854     /* Sizes.  */
02855     LDHDRSZ,
02856     LDSYMSZ,
02857     LDRELSZ,
02858     24,                            /* _xcoff_function_descriptor_size */
02859     0,                      /* _xcoff_small_aout_header_size */
02860     /* Versions.  */
02861     2,                      /* _xcoff_ldhdr_version */
02862 
02863     _bfd_xcoff64_put_symbol_name,
02864     _bfd_xcoff64_put_ldsymbol_name,
02865     &xcoff64_dynamic_reloc,
02866     xcoff64_create_csect_from_smclas,
02867 
02868     /* Lineno and reloc count overflow.  */
02869     xcoff64_is_lineno_count_overflow,
02870     xcoff64_is_reloc_count_overflow,
02871 
02872     xcoff64_loader_symbol_offset,
02873     xcoff64_loader_reloc_offset,
02874 
02875     /* glink.  */
02876     &xcoff64_glink_code[0],
02877     40,                            /* _xcoff_glink_size */
02878 
02879     /* rtinit.  */
02880     88,                            /* _xcoff_rtinit_size */
02881     xcoff64_generate_rtinit,
02882   };
02883 
02884 /* The transfer vector that leads the outside world to all of the above.  */
02885 const bfd_target aix5coff64_vec =
02886   {
02887     "aix5coff64-rs6000",
02888     bfd_target_xcoff_flavour,
02889     BFD_ENDIAN_BIG,         /* data byte order is big */
02890     BFD_ENDIAN_BIG,         /* header byte order is big */
02891 
02892     (HAS_RELOC | EXEC_P | HAS_LINENO | HAS_DEBUG | DYNAMIC
02893      | HAS_SYMS | HAS_LOCALS | WP_TEXT),
02894 
02895     SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_CODE | SEC_DATA,
02896     0,                      /* leading char */
02897     '/',                    /* ar_pad_char */
02898     15,                            /* ar_max_namelen */
02899 
02900     /* data */
02901     bfd_getb64,
02902     bfd_getb_signed_64,
02903     bfd_putb64,
02904     bfd_getb32,
02905     bfd_getb_signed_32,
02906     bfd_putb32,
02907     bfd_getb16,
02908     bfd_getb_signed_16,
02909     bfd_putb16,
02910 
02911     /* hdrs */
02912     bfd_getb64,
02913     bfd_getb_signed_64,
02914     bfd_putb64,
02915     bfd_getb32,
02916     bfd_getb_signed_32,
02917     bfd_putb32,
02918     bfd_getb16,
02919     bfd_getb_signed_16,
02920     bfd_putb16,
02921 
02922     { /* bfd_check_format */
02923       _bfd_dummy_target,
02924       coff_object_p,
02925       xcoff64_archive_p,
02926       xcoff64_core_p
02927     },
02928 
02929     { /* bfd_set_format */
02930       bfd_false,
02931       coff_mkobject,
02932       _bfd_generic_mkarchive,
02933       bfd_false
02934     },
02935 
02936     {/* bfd_write_contents */
02937       bfd_false,
02938       xcoff64_write_object_contents,
02939       _bfd_xcoff_write_archive_contents,
02940       bfd_false
02941     },
02942 
02943     /* Generic */
02944     bfd_true,
02945     bfd_true,
02946     coff_new_section_hook,
02947     _bfd_generic_get_section_contents,
02948     _bfd_generic_get_section_contents_in_window,
02949 
02950     /* Copy */
02951     _bfd_xcoff_copy_private_bfd_data,
02952     ((bfd_boolean (*) (bfd *, bfd *)) bfd_true),
02953     _bfd_generic_init_private_section_data,
02954     ((bfd_boolean (*) (bfd *, asection *, bfd *, asection *)) bfd_true),
02955     ((bfd_boolean (*) (bfd *, asymbol *, bfd *, asymbol *)) bfd_true),
02956     ((bfd_boolean (*) (bfd *, bfd *)) bfd_true),
02957     ((bfd_boolean (*) (bfd *, flagword)) bfd_true),
02958     ((bfd_boolean (*) (bfd *, void * )) bfd_true),
02959 
02960     /* Core */
02961     xcoff64_core_file_failing_command,
02962     xcoff64_core_file_failing_signal,
02963     xcoff64_core_file_matches_executable_p,
02964 
02965     /* Archive */
02966     xcoff64_slurp_armap,
02967     bfd_false,
02968     ((bfd_boolean (*) (bfd *, char **, bfd_size_type *, const char **)) bfd_false),
02969     bfd_dont_truncate_arname,
02970     _bfd_xcoff_write_armap,
02971     _bfd_xcoff_read_ar_hdr,
02972     xcoff64_openr_next_archived_file,
02973     _bfd_generic_get_elt_at_index,
02974     _bfd_xcoff_stat_arch_elt,
02975     bfd_true,
02976 
02977     /* Symbols */
02978     coff_get_symtab_upper_bound,
02979     coff_canonicalize_symtab,
02980     coff_make_empty_symbol,
02981     coff_print_symbol,
02982     coff_get_symbol_info,
02983     _bfd_xcoff_is_local_label_name,
02984     coff_bfd_is_target_special_symbol,
02985     coff_get_lineno,
02986     coff_find_nearest_line,
02987     _bfd_generic_find_line,
02988     coff_find_inliner_info,
02989     coff_bfd_make_debug_symbol,
02990     _bfd_generic_read_minisymbols,
02991     _bfd_generic_minisymbol_to_symbol,
02992 
02993     /* Reloc */
02994     coff_get_reloc_upper_bound,
02995     coff_canonicalize_reloc,
02996     xcoff64_reloc_type_lookup,
02997     xcoff64_reloc_name_lookup,
02998 
02999     /* Write */
03000     coff_set_arch_mach,
03001     coff_set_section_contents,
03002 
03003     /* Link */
03004     xcoff64_sizeof_headers,
03005     bfd_generic_get_relocated_section_contents,
03006     bfd_generic_relax_section,
03007     _bfd_xcoff_bfd_link_hash_table_create,
03008     _bfd_generic_link_hash_table_free,
03009     _bfd_xcoff_bfd_link_add_symbols,
03010     _bfd_generic_link_just_syms,
03011     _bfd_xcoff_bfd_final_link,
03012     _bfd_generic_link_split_section,
03013     bfd_generic_gc_sections,
03014     bfd_generic_merge_sections,
03015     bfd_generic_is_group_section,
03016     bfd_generic_discard_group,
03017     _bfd_generic_section_already_linked,
03018 
03019     /* Dynamic */
03020     _bfd_xcoff_get_dynamic_symtab_upper_bound,
03021     _bfd_xcoff_canonicalize_dynamic_symtab,
03022     _bfd_nodynamic_get_synthetic_symtab,
03023     _bfd_xcoff_get_dynamic_reloc_upper_bound,
03024     _bfd_xcoff_canonicalize_dynamic_reloc,
03025 
03026     /* Opposite endian version, none exists.  */
03027     NULL,
03028 
03029     (void *) & bfd_xcoff_aix5_backend_data,
03030   };