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