13d8817e4Smiod /* BFD back-end for IBM RS/6000 "XCOFF" files.
23d8817e4Smiod Copyright 1990-1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006
33d8817e4Smiod Free Software Foundation, Inc.
43d8817e4Smiod FIXME: Can someone provide a transliteration of this name into ASCII?
53d8817e4Smiod Using the following chars caused a compiler warning on HIUX (so I replaced
63d8817e4Smiod them with octal escapes), and isn't useful without an understanding of what
73d8817e4Smiod character set it is.
83d8817e4Smiod Written by Metin G. Ozisik, Mimi Ph\373\364ng-Th\345o V\365,
93d8817e4Smiod and John Gilmore.
103d8817e4Smiod Archive support from Damon A. Permezel.
113d8817e4Smiod Contributed by IBM Corporation and Cygnus Support.
123d8817e4Smiod
133d8817e4Smiod This file is part of BFD, the Binary File Descriptor library.
143d8817e4Smiod
153d8817e4Smiod This program is free software; you can redistribute it and/or modify
163d8817e4Smiod it under the terms of the GNU General Public License as published by
173d8817e4Smiod the Free Software Foundation; either version 2 of the License, or
183d8817e4Smiod (at your option) any later version.
193d8817e4Smiod
203d8817e4Smiod This program is distributed in the hope that it will be useful,
213d8817e4Smiod but WITHOUT ANY WARRANTY; without even the implied warranty of
223d8817e4Smiod MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
233d8817e4Smiod GNU General Public License for more details.
243d8817e4Smiod
253d8817e4Smiod You should have received a copy of the GNU General Public License
263d8817e4Smiod along with this program; if not, write to the Free Software
273d8817e4Smiod Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */
283d8817e4Smiod
293d8817e4Smiod #include "bfd.h"
303d8817e4Smiod #include "sysdep.h"
313d8817e4Smiod #include "bfdlink.h"
323d8817e4Smiod #include "libbfd.h"
333d8817e4Smiod #include "coff/internal.h"
343d8817e4Smiod #include "coff/xcoff.h"
353d8817e4Smiod #include "coff/rs6000.h"
363d8817e4Smiod #include "libcoff.h"
373d8817e4Smiod #include "libxcoff.h"
383d8817e4Smiod
393d8817e4Smiod extern bfd_boolean _bfd_xcoff_mkobject
403d8817e4Smiod PARAMS ((bfd *));
413d8817e4Smiod extern bfd_boolean _bfd_xcoff_copy_private_bfd_data
423d8817e4Smiod PARAMS ((bfd *, bfd *));
433d8817e4Smiod extern bfd_boolean _bfd_xcoff_is_local_label_name
443d8817e4Smiod PARAMS ((bfd *, const char *));
453d8817e4Smiod extern reloc_howto_type *_bfd_xcoff_reloc_type_lookup
463d8817e4Smiod PARAMS ((bfd *, bfd_reloc_code_real_type));
473d8817e4Smiod extern bfd_boolean _bfd_xcoff_slurp_armap
483d8817e4Smiod PARAMS ((bfd *));
493d8817e4Smiod extern const bfd_target *_bfd_xcoff_archive_p
503d8817e4Smiod PARAMS ((bfd *));
513d8817e4Smiod extern PTR _bfd_xcoff_read_ar_hdr
523d8817e4Smiod PARAMS ((bfd *));
533d8817e4Smiod extern bfd *_bfd_xcoff_openr_next_archived_file
543d8817e4Smiod PARAMS ((bfd *, bfd *));
553d8817e4Smiod extern int _bfd_xcoff_stat_arch_elt
563d8817e4Smiod PARAMS ((bfd *, struct stat *));
573d8817e4Smiod extern bfd_boolean _bfd_xcoff_write_armap
583d8817e4Smiod PARAMS ((bfd *, unsigned int, struct orl *, unsigned int, int));
593d8817e4Smiod extern bfd_boolean _bfd_xcoff_write_archive_contents
603d8817e4Smiod PARAMS ((bfd *));
613d8817e4Smiod extern int _bfd_xcoff_sizeof_headers
623d8817e4Smiod PARAMS ((bfd *, bfd_boolean));
633d8817e4Smiod extern void _bfd_xcoff_swap_sym_in
643d8817e4Smiod PARAMS ((bfd *, PTR, PTR));
653d8817e4Smiod extern unsigned int _bfd_xcoff_swap_sym_out
663d8817e4Smiod PARAMS ((bfd *, PTR, PTR));
673d8817e4Smiod extern void _bfd_xcoff_swap_aux_in
683d8817e4Smiod PARAMS ((bfd *, PTR, int, int, int, int, PTR));
693d8817e4Smiod extern unsigned int _bfd_xcoff_swap_aux_out
703d8817e4Smiod PARAMS ((bfd *, PTR, int, int, int, int, PTR));
713d8817e4Smiod static void xcoff_swap_reloc_in
723d8817e4Smiod PARAMS ((bfd *, PTR, PTR));
733d8817e4Smiod static unsigned int xcoff_swap_reloc_out
743d8817e4Smiod PARAMS ((bfd *, PTR, PTR));
753d8817e4Smiod
763d8817e4Smiod /* Forward declare xcoff_rtype2howto for coffcode.h macro. */
773d8817e4Smiod void xcoff_rtype2howto
783d8817e4Smiod PARAMS ((arelent *, struct internal_reloc *));
793d8817e4Smiod
803d8817e4Smiod /* coffcode.h needs these to be defined. */
813d8817e4Smiod #define RS6000COFF_C 1
823d8817e4Smiod
833d8817e4Smiod #define SELECT_RELOC(internal, howto) \
843d8817e4Smiod { \
853d8817e4Smiod internal.r_type = howto->type; \
863d8817e4Smiod internal.r_size = \
873d8817e4Smiod ((howto->complain_on_overflow == complain_overflow_signed \
883d8817e4Smiod ? 0x80 \
893d8817e4Smiod : 0) \
903d8817e4Smiod | (howto->bitsize - 1)); \
913d8817e4Smiod }
923d8817e4Smiod
933d8817e4Smiod #define COFF_DEFAULT_SECTION_ALIGNMENT_POWER (3)
943d8817e4Smiod #define COFF_LONG_FILENAMES
953d8817e4Smiod #define NO_COFF_SYMBOLS
963d8817e4Smiod #define RTYPE2HOWTO(cache_ptr, dst) xcoff_rtype2howto (cache_ptr, dst)
973d8817e4Smiod #define coff_mkobject _bfd_xcoff_mkobject
983d8817e4Smiod #define coff_bfd_copy_private_bfd_data _bfd_xcoff_copy_private_bfd_data
993d8817e4Smiod #define coff_bfd_is_local_label_name _bfd_xcoff_is_local_label_name
1003d8817e4Smiod #define coff_bfd_reloc_type_lookup _bfd_xcoff_reloc_type_lookup
1013d8817e4Smiod #ifdef AIX_CORE
1023d8817e4Smiod extern const bfd_target * rs6000coff_core_p
1033d8817e4Smiod PARAMS ((bfd *abfd));
1043d8817e4Smiod extern bfd_boolean rs6000coff_core_file_matches_executable_p
1053d8817e4Smiod PARAMS ((bfd *cbfd, bfd *ebfd));
1063d8817e4Smiod extern char *rs6000coff_core_file_failing_command
1073d8817e4Smiod PARAMS ((bfd *abfd));
1083d8817e4Smiod extern int rs6000coff_core_file_failing_signal
1093d8817e4Smiod PARAMS ((bfd *abfd));
1103d8817e4Smiod #define CORE_FILE_P rs6000coff_core_p
1113d8817e4Smiod #define coff_core_file_failing_command \
1123d8817e4Smiod rs6000coff_core_file_failing_command
1133d8817e4Smiod #define coff_core_file_failing_signal \
1143d8817e4Smiod rs6000coff_core_file_failing_signal
1153d8817e4Smiod #define coff_core_file_matches_executable_p \
1163d8817e4Smiod rs6000coff_core_file_matches_executable_p
1173d8817e4Smiod #else
1183d8817e4Smiod #define CORE_FILE_P _bfd_dummy_target
1193d8817e4Smiod #define coff_core_file_failing_command \
1203d8817e4Smiod _bfd_nocore_core_file_failing_command
1213d8817e4Smiod #define coff_core_file_failing_signal \
1223d8817e4Smiod _bfd_nocore_core_file_failing_signal
1233d8817e4Smiod #define coff_core_file_matches_executable_p \
1243d8817e4Smiod _bfd_nocore_core_file_matches_executable_p
1253d8817e4Smiod #endif
1263d8817e4Smiod #define coff_SWAP_sym_in _bfd_xcoff_swap_sym_in
1273d8817e4Smiod #define coff_SWAP_sym_out _bfd_xcoff_swap_sym_out
1283d8817e4Smiod #define coff_SWAP_aux_in _bfd_xcoff_swap_aux_in
1293d8817e4Smiod #define coff_SWAP_aux_out _bfd_xcoff_swap_aux_out
1303d8817e4Smiod #define coff_swap_reloc_in xcoff_swap_reloc_in
1313d8817e4Smiod #define coff_swap_reloc_out xcoff_swap_reloc_out
1323d8817e4Smiod #define NO_COFF_RELOCS
1333d8817e4Smiod
1343d8817e4Smiod #include "coffcode.h"
1353d8817e4Smiod
1363d8817e4Smiod /* The main body of code is in coffcode.h. */
1373d8817e4Smiod
1383d8817e4Smiod static const char *normalize_filename
1393d8817e4Smiod PARAMS ((bfd *));
1403d8817e4Smiod static bfd_boolean xcoff_write_armap_old
1413d8817e4Smiod PARAMS ((bfd *, unsigned int, struct orl *, unsigned int, int));
1423d8817e4Smiod static bfd_boolean xcoff_write_armap_big
1433d8817e4Smiod PARAMS ((bfd *, unsigned int, struct orl *, unsigned int, int));
1443d8817e4Smiod static bfd_boolean xcoff_write_archive_contents_old
1453d8817e4Smiod PARAMS ((bfd *));
1463d8817e4Smiod static bfd_boolean xcoff_write_archive_contents_big
1473d8817e4Smiod PARAMS ((bfd *));
1483d8817e4Smiod static void xcoff_swap_ldhdr_in
1493d8817e4Smiod PARAMS ((bfd *, const PTR, struct internal_ldhdr *));
1503d8817e4Smiod static void xcoff_swap_ldhdr_out
1513d8817e4Smiod PARAMS ((bfd *, const struct internal_ldhdr *, PTR));
1523d8817e4Smiod static void xcoff_swap_ldsym_in
1533d8817e4Smiod PARAMS ((bfd *, const PTR, struct internal_ldsym *));
1543d8817e4Smiod static void xcoff_swap_ldsym_out
1553d8817e4Smiod PARAMS ((bfd *, const struct internal_ldsym *, PTR));
1563d8817e4Smiod static void xcoff_swap_ldrel_in
1573d8817e4Smiod PARAMS ((bfd *, const PTR, struct internal_ldrel *));
1583d8817e4Smiod static void xcoff_swap_ldrel_out
1593d8817e4Smiod PARAMS ((bfd *, const struct internal_ldrel *, PTR));
1603d8817e4Smiod static bfd_boolean xcoff_ppc_relocate_section
1613d8817e4Smiod PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *,
1623d8817e4Smiod struct internal_reloc *, struct internal_syment *, asection **));
1633d8817e4Smiod static bfd_boolean _bfd_xcoff_put_ldsymbol_name
1643d8817e4Smiod PARAMS ((bfd *, struct xcoff_loader_info *, struct internal_ldsym *,
1653d8817e4Smiod const char *));
1663d8817e4Smiod static asection *xcoff_create_csect_from_smclas
1673d8817e4Smiod PARAMS ((bfd *, union internal_auxent *, const char *));
1683d8817e4Smiod static bfd_boolean xcoff_is_lineno_count_overflow
1693d8817e4Smiod PARAMS ((bfd *, bfd_vma));
1703d8817e4Smiod static bfd_boolean xcoff_is_reloc_count_overflow
1713d8817e4Smiod PARAMS ((bfd *, bfd_vma));
1723d8817e4Smiod static bfd_vma xcoff_loader_symbol_offset
1733d8817e4Smiod PARAMS ((bfd *, struct internal_ldhdr *));
1743d8817e4Smiod static bfd_vma xcoff_loader_reloc_offset
1753d8817e4Smiod PARAMS ((bfd *, struct internal_ldhdr *));
1763d8817e4Smiod static bfd_boolean xcoff_generate_rtinit
1773d8817e4Smiod PARAMS ((bfd *, const char *, const char *, bfd_boolean));
1783d8817e4Smiod static bfd_boolean do_pad
1793d8817e4Smiod PARAMS ((bfd *, unsigned int));
1803d8817e4Smiod static bfd_boolean do_copy
1813d8817e4Smiod PARAMS ((bfd *, bfd *));
1823d8817e4Smiod static bfd_boolean do_shared_object_padding
1833d8817e4Smiod PARAMS ((bfd *, bfd *, file_ptr *, int));
1843d8817e4Smiod
1853d8817e4Smiod /* Relocation functions */
1863d8817e4Smiod static bfd_boolean xcoff_reloc_type_br
1873d8817e4Smiod PARAMS ((XCOFF_RELOC_FUNCTION_ARGS));
1883d8817e4Smiod
1893d8817e4Smiod static bfd_boolean xcoff_complain_overflow_dont_func
1903d8817e4Smiod PARAMS ((XCOFF_COMPLAIN_FUNCTION_ARGS));
1913d8817e4Smiod static bfd_boolean xcoff_complain_overflow_bitfield_func
1923d8817e4Smiod PARAMS ((XCOFF_COMPLAIN_FUNCTION_ARGS));
1933d8817e4Smiod static bfd_boolean xcoff_complain_overflow_signed_func
1943d8817e4Smiod PARAMS ((XCOFF_COMPLAIN_FUNCTION_ARGS));
1953d8817e4Smiod static bfd_boolean xcoff_complain_overflow_unsigned_func
1963d8817e4Smiod PARAMS ((XCOFF_COMPLAIN_FUNCTION_ARGS));
1973d8817e4Smiod
1983d8817e4Smiod bfd_boolean (*xcoff_calculate_relocation[XCOFF_MAX_CALCULATE_RELOCATION])
1993d8817e4Smiod PARAMS ((XCOFF_RELOC_FUNCTION_ARGS)) =
2003d8817e4Smiod {
2013d8817e4Smiod xcoff_reloc_type_pos, /* R_POS (0x00) */
2023d8817e4Smiod xcoff_reloc_type_neg, /* R_NEG (0x01) */
2033d8817e4Smiod xcoff_reloc_type_rel, /* R_REL (0x02) */
2043d8817e4Smiod xcoff_reloc_type_toc, /* R_TOC (0x03) */
2053d8817e4Smiod xcoff_reloc_type_fail, /* R_RTB (0x04) */
2063d8817e4Smiod xcoff_reloc_type_toc, /* R_GL (0x05) */
2073d8817e4Smiod xcoff_reloc_type_toc, /* R_TCL (0x06) */
2083d8817e4Smiod xcoff_reloc_type_fail, /* (0x07) */
2093d8817e4Smiod xcoff_reloc_type_ba, /* R_BA (0x08) */
2103d8817e4Smiod xcoff_reloc_type_fail, /* (0x09) */
2113d8817e4Smiod xcoff_reloc_type_br, /* R_BR (0x0a) */
2123d8817e4Smiod xcoff_reloc_type_fail, /* (0x0b) */
2133d8817e4Smiod xcoff_reloc_type_pos, /* R_RL (0x0c) */
2143d8817e4Smiod xcoff_reloc_type_pos, /* R_RLA (0x0d) */
2153d8817e4Smiod xcoff_reloc_type_fail, /* (0x0e) */
2163d8817e4Smiod xcoff_reloc_type_noop, /* R_REF (0x0f) */
2173d8817e4Smiod xcoff_reloc_type_fail, /* (0x10) */
2183d8817e4Smiod xcoff_reloc_type_fail, /* (0x11) */
2193d8817e4Smiod xcoff_reloc_type_toc, /* R_TRL (0x12) */
2203d8817e4Smiod xcoff_reloc_type_toc, /* R_TRLA (0x13) */
2213d8817e4Smiod xcoff_reloc_type_fail, /* R_RRTBI (0x14) */
2223d8817e4Smiod xcoff_reloc_type_fail, /* R_RRTBA (0x15) */
2233d8817e4Smiod xcoff_reloc_type_ba, /* R_CAI (0x16) */
2243d8817e4Smiod xcoff_reloc_type_crel, /* R_CREL (0x17) */
2253d8817e4Smiod xcoff_reloc_type_ba, /* R_RBA (0x18) */
2263d8817e4Smiod xcoff_reloc_type_ba, /* R_RBAC (0x19) */
2273d8817e4Smiod xcoff_reloc_type_br, /* R_RBR (0x1a) */
2283d8817e4Smiod xcoff_reloc_type_ba, /* R_RBRC (0x1b) */
2293d8817e4Smiod };
2303d8817e4Smiod
2313d8817e4Smiod bfd_boolean (*xcoff_complain_overflow[XCOFF_MAX_COMPLAIN_OVERFLOW])
2323d8817e4Smiod PARAMS ((XCOFF_COMPLAIN_FUNCTION_ARGS)) =
2333d8817e4Smiod {
2343d8817e4Smiod xcoff_complain_overflow_dont_func,
2353d8817e4Smiod xcoff_complain_overflow_bitfield_func,
2363d8817e4Smiod xcoff_complain_overflow_signed_func,
2373d8817e4Smiod xcoff_complain_overflow_unsigned_func,
2383d8817e4Smiod };
2393d8817e4Smiod
2403d8817e4Smiod /* We use our own tdata type. Its first field is the COFF tdata type,
2413d8817e4Smiod so the COFF routines are compatible. */
2423d8817e4Smiod
2433d8817e4Smiod bfd_boolean
_bfd_xcoff_mkobject(abfd)2443d8817e4Smiod _bfd_xcoff_mkobject (abfd)
2453d8817e4Smiod bfd *abfd;
2463d8817e4Smiod {
2473d8817e4Smiod coff_data_type *coff;
2483d8817e4Smiod bfd_size_type amt = sizeof (struct xcoff_tdata);
2493d8817e4Smiod
2503d8817e4Smiod abfd->tdata.xcoff_obj_data = (struct xcoff_tdata *) bfd_zalloc (abfd, amt);
2513d8817e4Smiod if (abfd->tdata.xcoff_obj_data == NULL)
2523d8817e4Smiod return FALSE;
2533d8817e4Smiod coff = coff_data (abfd);
2543d8817e4Smiod coff->symbols = (coff_symbol_type *) NULL;
2553d8817e4Smiod coff->conversion_table = (unsigned int *) NULL;
2563d8817e4Smiod coff->raw_syments = (struct coff_ptr_struct *) NULL;
2573d8817e4Smiod coff->relocbase = 0;
2583d8817e4Smiod
2593d8817e4Smiod xcoff_data (abfd)->modtype = ('1' << 8) | 'L';
2603d8817e4Smiod
2613d8817e4Smiod /* We set cputype to -1 to indicate that it has not been
2623d8817e4Smiod initialized. */
2633d8817e4Smiod xcoff_data (abfd)->cputype = -1;
2643d8817e4Smiod
2653d8817e4Smiod xcoff_data (abfd)->csects = NULL;
2663d8817e4Smiod xcoff_data (abfd)->debug_indices = NULL;
2673d8817e4Smiod
2683d8817e4Smiod /* text section alignment is different than the default */
2693d8817e4Smiod bfd_xcoff_text_align_power (abfd) = 2;
2703d8817e4Smiod
2713d8817e4Smiod return TRUE;
2723d8817e4Smiod }
2733d8817e4Smiod
2743d8817e4Smiod /* Copy XCOFF data from one BFD to another. */
2753d8817e4Smiod
2763d8817e4Smiod bfd_boolean
_bfd_xcoff_copy_private_bfd_data(ibfd,obfd)2773d8817e4Smiod _bfd_xcoff_copy_private_bfd_data (ibfd, obfd)
2783d8817e4Smiod bfd *ibfd;
2793d8817e4Smiod bfd *obfd;
2803d8817e4Smiod {
2813d8817e4Smiod struct xcoff_tdata *ix, *ox;
2823d8817e4Smiod asection *sec;
2833d8817e4Smiod
2843d8817e4Smiod if (ibfd->xvec != obfd->xvec)
2853d8817e4Smiod return TRUE;
2863d8817e4Smiod ix = xcoff_data (ibfd);
2873d8817e4Smiod ox = xcoff_data (obfd);
2883d8817e4Smiod ox->full_aouthdr = ix->full_aouthdr;
2893d8817e4Smiod ox->toc = ix->toc;
2903d8817e4Smiod if (ix->sntoc == 0)
2913d8817e4Smiod ox->sntoc = 0;
2923d8817e4Smiod else
2933d8817e4Smiod {
2943d8817e4Smiod sec = coff_section_from_bfd_index (ibfd, ix->sntoc);
2953d8817e4Smiod if (sec == NULL)
2963d8817e4Smiod ox->sntoc = 0;
2973d8817e4Smiod else
2983d8817e4Smiod ox->sntoc = sec->output_section->target_index;
2993d8817e4Smiod }
3003d8817e4Smiod if (ix->snentry == 0)
3013d8817e4Smiod ox->snentry = 0;
3023d8817e4Smiod else
3033d8817e4Smiod {
3043d8817e4Smiod sec = coff_section_from_bfd_index (ibfd, ix->snentry);
3053d8817e4Smiod if (sec == NULL)
3063d8817e4Smiod ox->snentry = 0;
3073d8817e4Smiod else
3083d8817e4Smiod ox->snentry = sec->output_section->target_index;
3093d8817e4Smiod }
3103d8817e4Smiod bfd_xcoff_text_align_power (obfd) = bfd_xcoff_text_align_power (ibfd);
3113d8817e4Smiod bfd_xcoff_data_align_power (obfd) = bfd_xcoff_data_align_power (ibfd);
3123d8817e4Smiod ox->modtype = ix->modtype;
3133d8817e4Smiod ox->cputype = ix->cputype;
3143d8817e4Smiod ox->maxdata = ix->maxdata;
3153d8817e4Smiod ox->maxstack = ix->maxstack;
3163d8817e4Smiod return TRUE;
3173d8817e4Smiod }
3183d8817e4Smiod
3193d8817e4Smiod /* I don't think XCOFF really has a notion of local labels based on
3203d8817e4Smiod name. This will mean that ld -X doesn't actually strip anything.
3213d8817e4Smiod The AIX native linker does not have a -X option, and it ignores the
3223d8817e4Smiod -x option. */
3233d8817e4Smiod
3243d8817e4Smiod bfd_boolean
_bfd_xcoff_is_local_label_name(abfd,name)3253d8817e4Smiod _bfd_xcoff_is_local_label_name (abfd, name)
3263d8817e4Smiod bfd *abfd ATTRIBUTE_UNUSED;
3273d8817e4Smiod const char *name ATTRIBUTE_UNUSED;
3283d8817e4Smiod {
3293d8817e4Smiod return FALSE;
3303d8817e4Smiod }
3313d8817e4Smiod
3323d8817e4Smiod void
_bfd_xcoff_swap_sym_in(abfd,ext1,in1)3333d8817e4Smiod _bfd_xcoff_swap_sym_in (abfd, ext1, in1)
3343d8817e4Smiod bfd *abfd;
3353d8817e4Smiod PTR ext1;
3363d8817e4Smiod PTR in1;
3373d8817e4Smiod {
3383d8817e4Smiod SYMENT *ext = (SYMENT *)ext1;
3393d8817e4Smiod struct internal_syment * in = (struct internal_syment *)in1;
3403d8817e4Smiod
3413d8817e4Smiod if (ext->e.e_name[0] != 0)
3423d8817e4Smiod {
3433d8817e4Smiod memcpy (in->_n._n_name, ext->e.e_name, SYMNMLEN);
3443d8817e4Smiod }
3453d8817e4Smiod else
3463d8817e4Smiod {
3473d8817e4Smiod in->_n._n_n._n_zeroes = 0;
3483d8817e4Smiod in->_n._n_n._n_offset = H_GET_32 (abfd, ext->e.e.e_offset);
3493d8817e4Smiod }
3503d8817e4Smiod
3513d8817e4Smiod in->n_value = H_GET_32 (abfd, ext->e_value);
3523d8817e4Smiod in->n_scnum = H_GET_16 (abfd, ext->e_scnum);
3533d8817e4Smiod in->n_type = H_GET_16 (abfd, ext->e_type);
3543d8817e4Smiod in->n_sclass = H_GET_8 (abfd, ext->e_sclass);
3553d8817e4Smiod in->n_numaux = H_GET_8 (abfd, ext->e_numaux);
3563d8817e4Smiod }
3573d8817e4Smiod
3583d8817e4Smiod unsigned int
_bfd_xcoff_swap_sym_out(abfd,inp,extp)3593d8817e4Smiod _bfd_xcoff_swap_sym_out (abfd, inp, extp)
3603d8817e4Smiod bfd *abfd;
3613d8817e4Smiod PTR inp;
3623d8817e4Smiod PTR extp;
3633d8817e4Smiod {
3643d8817e4Smiod struct internal_syment *in = (struct internal_syment *)inp;
3653d8817e4Smiod SYMENT *ext =(SYMENT *)extp;
3663d8817e4Smiod
3673d8817e4Smiod if (in->_n._n_name[0] != 0)
3683d8817e4Smiod {
3693d8817e4Smiod memcpy (ext->e.e_name, in->_n._n_name, SYMNMLEN);
3703d8817e4Smiod }
3713d8817e4Smiod else
3723d8817e4Smiod {
3733d8817e4Smiod H_PUT_32 (abfd, 0, ext->e.e.e_zeroes);
3743d8817e4Smiod H_PUT_32 (abfd, in->_n._n_n._n_offset, ext->e.e.e_offset);
3753d8817e4Smiod }
3763d8817e4Smiod
3773d8817e4Smiod H_PUT_32 (abfd, in->n_value, ext->e_value);
3783d8817e4Smiod H_PUT_16 (abfd, in->n_scnum, ext->e_scnum);
3793d8817e4Smiod H_PUT_16 (abfd, in->n_type, ext->e_type);
3803d8817e4Smiod H_PUT_8 (abfd, in->n_sclass, ext->e_sclass);
3813d8817e4Smiod H_PUT_8 (abfd, in->n_numaux, ext->e_numaux);
3823d8817e4Smiod return bfd_coff_symesz (abfd);
3833d8817e4Smiod }
3843d8817e4Smiod
3853d8817e4Smiod void
_bfd_xcoff_swap_aux_in(abfd,ext1,type,class,indx,numaux,in1)3863d8817e4Smiod _bfd_xcoff_swap_aux_in (abfd, ext1, type, class, indx, numaux, in1)
3873d8817e4Smiod bfd *abfd;
3883d8817e4Smiod PTR ext1;
3893d8817e4Smiod int type;
3903d8817e4Smiod int class;
3913d8817e4Smiod int indx;
3923d8817e4Smiod int numaux;
3933d8817e4Smiod PTR in1;
3943d8817e4Smiod {
3953d8817e4Smiod AUXENT * ext = (AUXENT *)ext1;
3963d8817e4Smiod union internal_auxent *in = (union internal_auxent *)in1;
3973d8817e4Smiod
3983d8817e4Smiod switch (class)
3993d8817e4Smiod {
4003d8817e4Smiod case C_FILE:
4013d8817e4Smiod if (ext->x_file.x_fname[0] == 0)
4023d8817e4Smiod {
4033d8817e4Smiod in->x_file.x_n.x_zeroes = 0;
4043d8817e4Smiod in->x_file.x_n.x_offset =
4053d8817e4Smiod H_GET_32 (abfd, ext->x_file.x_n.x_offset);
4063d8817e4Smiod }
4073d8817e4Smiod else
4083d8817e4Smiod {
4093d8817e4Smiod if (numaux > 1)
4103d8817e4Smiod {
4113d8817e4Smiod if (indx == 0)
4123d8817e4Smiod memcpy (in->x_file.x_fname, ext->x_file.x_fname,
4133d8817e4Smiod numaux * sizeof (AUXENT));
4143d8817e4Smiod }
4153d8817e4Smiod else
4163d8817e4Smiod {
4173d8817e4Smiod memcpy (in->x_file.x_fname, ext->x_file.x_fname, FILNMLEN);
4183d8817e4Smiod }
4193d8817e4Smiod }
4203d8817e4Smiod goto end;
4213d8817e4Smiod
4223d8817e4Smiod /* RS/6000 "csect" auxents */
4233d8817e4Smiod case C_EXT:
4243d8817e4Smiod case C_HIDEXT:
4253d8817e4Smiod if (indx + 1 == numaux)
4263d8817e4Smiod {
4273d8817e4Smiod in->x_csect.x_scnlen.l = H_GET_32 (abfd, ext->x_csect.x_scnlen);
4283d8817e4Smiod in->x_csect.x_parmhash = H_GET_32 (abfd, ext->x_csect.x_parmhash);
4293d8817e4Smiod in->x_csect.x_snhash = H_GET_16 (abfd, ext->x_csect.x_snhash);
4303d8817e4Smiod /* We don't have to hack bitfields in x_smtyp because it's
4313d8817e4Smiod defined by shifts-and-ands, which are equivalent on all
4323d8817e4Smiod byte orders. */
4333d8817e4Smiod in->x_csect.x_smtyp = H_GET_8 (abfd, ext->x_csect.x_smtyp);
4343d8817e4Smiod in->x_csect.x_smclas = H_GET_8 (abfd, ext->x_csect.x_smclas);
4353d8817e4Smiod in->x_csect.x_stab = H_GET_32 (abfd, ext->x_csect.x_stab);
4363d8817e4Smiod in->x_csect.x_snstab = H_GET_16 (abfd, ext->x_csect.x_snstab);
4373d8817e4Smiod goto end;
4383d8817e4Smiod }
4393d8817e4Smiod break;
4403d8817e4Smiod
4413d8817e4Smiod case C_STAT:
4423d8817e4Smiod case C_LEAFSTAT:
4433d8817e4Smiod case C_HIDDEN:
4443d8817e4Smiod if (type == T_NULL)
4453d8817e4Smiod {
4463d8817e4Smiod in->x_scn.x_scnlen = H_GET_32 (abfd, ext->x_scn.x_scnlen);
4473d8817e4Smiod in->x_scn.x_nreloc = H_GET_16 (abfd, ext->x_scn.x_nreloc);
4483d8817e4Smiod in->x_scn.x_nlinno = H_GET_16 (abfd, ext->x_scn.x_nlinno);
4493d8817e4Smiod /* PE defines some extra fields; we zero them out for
4503d8817e4Smiod safety. */
4513d8817e4Smiod in->x_scn.x_checksum = 0;
4523d8817e4Smiod in->x_scn.x_associated = 0;
4533d8817e4Smiod in->x_scn.x_comdat = 0;
4543d8817e4Smiod
4553d8817e4Smiod goto end;
4563d8817e4Smiod }
4573d8817e4Smiod break;
4583d8817e4Smiod }
4593d8817e4Smiod
4603d8817e4Smiod in->x_sym.x_tagndx.l = H_GET_32 (abfd, ext->x_sym.x_tagndx);
4613d8817e4Smiod in->x_sym.x_tvndx = H_GET_16 (abfd, ext->x_sym.x_tvndx);
4623d8817e4Smiod
4633d8817e4Smiod if (class == C_BLOCK || class == C_FCN || ISFCN (type) || ISTAG (class))
4643d8817e4Smiod {
4653d8817e4Smiod in->x_sym.x_fcnary.x_fcn.x_lnnoptr =
4663d8817e4Smiod H_GET_32 (abfd, ext->x_sym.x_fcnary.x_fcn.x_lnnoptr);
4673d8817e4Smiod in->x_sym.x_fcnary.x_fcn.x_endndx.l =
4683d8817e4Smiod H_GET_32 (abfd, ext->x_sym.x_fcnary.x_fcn.x_endndx);
4693d8817e4Smiod }
4703d8817e4Smiod else
4713d8817e4Smiod {
4723d8817e4Smiod in->x_sym.x_fcnary.x_ary.x_dimen[0] =
4733d8817e4Smiod H_GET_16 (abfd, ext->x_sym.x_fcnary.x_ary.x_dimen[0]);
4743d8817e4Smiod in->x_sym.x_fcnary.x_ary.x_dimen[1] =
4753d8817e4Smiod H_GET_16 (abfd, ext->x_sym.x_fcnary.x_ary.x_dimen[1]);
4763d8817e4Smiod in->x_sym.x_fcnary.x_ary.x_dimen[2] =
4773d8817e4Smiod H_GET_16 (abfd, ext->x_sym.x_fcnary.x_ary.x_dimen[2]);
4783d8817e4Smiod in->x_sym.x_fcnary.x_ary.x_dimen[3] =
4793d8817e4Smiod H_GET_16 (abfd, ext->x_sym.x_fcnary.x_ary.x_dimen[3]);
4803d8817e4Smiod }
4813d8817e4Smiod
4823d8817e4Smiod if (ISFCN (type))
4833d8817e4Smiod {
4843d8817e4Smiod in->x_sym.x_misc.x_fsize = H_GET_32 (abfd, ext->x_sym.x_misc.x_fsize);
4853d8817e4Smiod }
4863d8817e4Smiod else
4873d8817e4Smiod {
4883d8817e4Smiod in->x_sym.x_misc.x_lnsz.x_lnno =
4893d8817e4Smiod H_GET_16 (abfd, ext->x_sym.x_misc.x_lnsz.x_lnno);
4903d8817e4Smiod in->x_sym.x_misc.x_lnsz.x_size =
4913d8817e4Smiod H_GET_16 (abfd, ext->x_sym.x_misc.x_lnsz.x_size);
4923d8817e4Smiod }
4933d8817e4Smiod
4943d8817e4Smiod end: ;
4953d8817e4Smiod /* The semicolon is because MSVC doesn't like labels at
4963d8817e4Smiod end of block. */
4973d8817e4Smiod }
4983d8817e4Smiod
4993d8817e4Smiod
5003d8817e4Smiod unsigned int _bfd_xcoff_swap_aux_out
5013d8817e4Smiod PARAMS ((bfd *, PTR, int, int, int, int, PTR));
5023d8817e4Smiod
5033d8817e4Smiod unsigned int
_bfd_xcoff_swap_aux_out(abfd,inp,type,class,indx,numaux,extp)5043d8817e4Smiod _bfd_xcoff_swap_aux_out (abfd, inp, type, class, indx, numaux, extp)
5053d8817e4Smiod bfd * abfd;
5063d8817e4Smiod PTR inp;
5073d8817e4Smiod int type;
5083d8817e4Smiod int class;
5093d8817e4Smiod int indx ATTRIBUTE_UNUSED;
5103d8817e4Smiod int numaux ATTRIBUTE_UNUSED;
5113d8817e4Smiod PTR extp;
5123d8817e4Smiod {
5133d8817e4Smiod union internal_auxent *in = (union internal_auxent *)inp;
5143d8817e4Smiod AUXENT *ext = (AUXENT *)extp;
5153d8817e4Smiod
5163d8817e4Smiod memset ((PTR)ext, 0, bfd_coff_auxesz (abfd));
5173d8817e4Smiod switch (class)
5183d8817e4Smiod {
5193d8817e4Smiod case C_FILE:
5203d8817e4Smiod if (in->x_file.x_fname[0] == 0)
5213d8817e4Smiod {
5223d8817e4Smiod H_PUT_32 (abfd, 0, ext->x_file.x_n.x_zeroes);
5233d8817e4Smiod H_PUT_32 (abfd, in->x_file.x_n.x_offset, ext->x_file.x_n.x_offset);
5243d8817e4Smiod }
5253d8817e4Smiod else
5263d8817e4Smiod {
5273d8817e4Smiod memcpy (ext->x_file.x_fname, in->x_file.x_fname, FILNMLEN);
5283d8817e4Smiod }
5293d8817e4Smiod goto end;
5303d8817e4Smiod
5313d8817e4Smiod /* RS/6000 "csect" auxents */
5323d8817e4Smiod case C_EXT:
5333d8817e4Smiod case C_HIDEXT:
5343d8817e4Smiod if (indx + 1 == numaux)
5353d8817e4Smiod {
5363d8817e4Smiod H_PUT_32 (abfd, in->x_csect.x_scnlen.l, ext->x_csect.x_scnlen);
5373d8817e4Smiod H_PUT_32 (abfd, in->x_csect.x_parmhash, ext->x_csect.x_parmhash);
5383d8817e4Smiod H_PUT_16 (abfd, in->x_csect.x_snhash, ext->x_csect.x_snhash);
5393d8817e4Smiod /* We don't have to hack bitfields in x_smtyp because it's
5403d8817e4Smiod defined by shifts-and-ands, which are equivalent on all
5413d8817e4Smiod byte orders. */
5423d8817e4Smiod H_PUT_8 (abfd, in->x_csect.x_smtyp, ext->x_csect.x_smtyp);
5433d8817e4Smiod H_PUT_8 (abfd, in->x_csect.x_smclas, ext->x_csect.x_smclas);
5443d8817e4Smiod H_PUT_32 (abfd, in->x_csect.x_stab, ext->x_csect.x_stab);
5453d8817e4Smiod H_PUT_16 (abfd, in->x_csect.x_snstab, ext->x_csect.x_snstab);
5463d8817e4Smiod goto end;
5473d8817e4Smiod }
5483d8817e4Smiod break;
5493d8817e4Smiod
5503d8817e4Smiod case C_STAT:
5513d8817e4Smiod case C_LEAFSTAT:
5523d8817e4Smiod case C_HIDDEN:
5533d8817e4Smiod if (type == T_NULL)
5543d8817e4Smiod {
5553d8817e4Smiod H_PUT_32 (abfd, in->x_scn.x_scnlen, ext->x_scn.x_scnlen);
5563d8817e4Smiod H_PUT_16 (abfd, in->x_scn.x_nreloc, ext->x_scn.x_nreloc);
5573d8817e4Smiod H_PUT_16 (abfd, in->x_scn.x_nlinno, ext->x_scn.x_nlinno);
5583d8817e4Smiod goto end;
5593d8817e4Smiod }
5603d8817e4Smiod break;
5613d8817e4Smiod }
5623d8817e4Smiod
5633d8817e4Smiod H_PUT_32 (abfd, in->x_sym.x_tagndx.l, ext->x_sym.x_tagndx);
5643d8817e4Smiod H_PUT_16 (abfd, in->x_sym.x_tvndx, ext->x_sym.x_tvndx);
5653d8817e4Smiod
5663d8817e4Smiod if (class == C_BLOCK || class == C_FCN || ISFCN (type) || ISTAG (class))
5673d8817e4Smiod {
5683d8817e4Smiod H_PUT_32 (abfd, in->x_sym.x_fcnary.x_fcn.x_lnnoptr,
5693d8817e4Smiod ext->x_sym.x_fcnary.x_fcn.x_lnnoptr);
5703d8817e4Smiod H_PUT_32 (abfd, in->x_sym.x_fcnary.x_fcn.x_endndx.l,
5713d8817e4Smiod ext->x_sym.x_fcnary.x_fcn.x_endndx);
5723d8817e4Smiod }
5733d8817e4Smiod else
5743d8817e4Smiod {
5753d8817e4Smiod H_PUT_16 (abfd, in->x_sym.x_fcnary.x_ary.x_dimen[0],
5763d8817e4Smiod ext->x_sym.x_fcnary.x_ary.x_dimen[0]);
5773d8817e4Smiod H_PUT_16 (abfd, in->x_sym.x_fcnary.x_ary.x_dimen[1],
5783d8817e4Smiod ext->x_sym.x_fcnary.x_ary.x_dimen[1]);
5793d8817e4Smiod H_PUT_16 (abfd, in->x_sym.x_fcnary.x_ary.x_dimen[2],
5803d8817e4Smiod ext->x_sym.x_fcnary.x_ary.x_dimen[2]);
5813d8817e4Smiod H_PUT_16 (abfd, in->x_sym.x_fcnary.x_ary.x_dimen[3],
5823d8817e4Smiod ext->x_sym.x_fcnary.x_ary.x_dimen[3]);
5833d8817e4Smiod }
5843d8817e4Smiod
5853d8817e4Smiod if (ISFCN (type))
5863d8817e4Smiod H_PUT_32 (abfd, in->x_sym.x_misc.x_fsize, ext->x_sym.x_misc.x_fsize);
5873d8817e4Smiod else
5883d8817e4Smiod {
5893d8817e4Smiod H_PUT_16 (abfd, in->x_sym.x_misc.x_lnsz.x_lnno,
5903d8817e4Smiod ext->x_sym.x_misc.x_lnsz.x_lnno);
5913d8817e4Smiod H_PUT_16 (abfd, in->x_sym.x_misc.x_lnsz.x_size,
5923d8817e4Smiod ext->x_sym.x_misc.x_lnsz.x_size);
5933d8817e4Smiod }
5943d8817e4Smiod
5953d8817e4Smiod end:
5963d8817e4Smiod return bfd_coff_auxesz (abfd);
5973d8817e4Smiod }
5983d8817e4Smiod
5993d8817e4Smiod
6003d8817e4Smiod
6013d8817e4Smiod /* The XCOFF reloc table. Actually, XCOFF relocations specify the
6023d8817e4Smiod bitsize and whether they are signed or not, along with a
6033d8817e4Smiod conventional type. This table is for the types, which are used for
6043d8817e4Smiod different algorithms for putting in the reloc. Many of these
6053d8817e4Smiod relocs need special_function entries, which I have not written. */
6063d8817e4Smiod
6073d8817e4Smiod
6083d8817e4Smiod reloc_howto_type xcoff_howto_table[] =
6093d8817e4Smiod {
6103d8817e4Smiod /* Standard 32 bit relocation. */
6113d8817e4Smiod HOWTO (R_POS, /* type */
6123d8817e4Smiod 0, /* rightshift */
6133d8817e4Smiod 2, /* size (0 = byte, 1 = short, 2 = long) */
6143d8817e4Smiod 32, /* bitsize */
6153d8817e4Smiod FALSE, /* pc_relative */
6163d8817e4Smiod 0, /* bitpos */
6173d8817e4Smiod complain_overflow_bitfield, /* complain_on_overflow */
6183d8817e4Smiod 0, /* special_function */
6193d8817e4Smiod "R_POS", /* name */
6203d8817e4Smiod TRUE, /* partial_inplace */
6213d8817e4Smiod 0xffffffff, /* src_mask */
6223d8817e4Smiod 0xffffffff, /* dst_mask */
6233d8817e4Smiod FALSE), /* pcrel_offset */
6243d8817e4Smiod
6253d8817e4Smiod /* 32 bit relocation, but store negative value. */
6263d8817e4Smiod HOWTO (R_NEG, /* type */
6273d8817e4Smiod 0, /* rightshift */
6283d8817e4Smiod -2, /* size (0 = byte, 1 = short, 2 = long) */
6293d8817e4Smiod 32, /* bitsize */
6303d8817e4Smiod FALSE, /* pc_relative */
6313d8817e4Smiod 0, /* bitpos */
6323d8817e4Smiod complain_overflow_bitfield, /* complain_on_overflow */
6333d8817e4Smiod 0, /* special_function */
6343d8817e4Smiod "R_NEG", /* name */
6353d8817e4Smiod TRUE, /* partial_inplace */
6363d8817e4Smiod 0xffffffff, /* src_mask */
6373d8817e4Smiod 0xffffffff, /* dst_mask */
6383d8817e4Smiod FALSE), /* pcrel_offset */
6393d8817e4Smiod
6403d8817e4Smiod /* 32 bit PC relative relocation. */
6413d8817e4Smiod HOWTO (R_REL, /* type */
6423d8817e4Smiod 0, /* rightshift */
6433d8817e4Smiod 2, /* size (0 = byte, 1 = short, 2 = long) */
6443d8817e4Smiod 32, /* bitsize */
6453d8817e4Smiod TRUE, /* pc_relative */
6463d8817e4Smiod 0, /* bitpos */
6473d8817e4Smiod complain_overflow_signed, /* complain_on_overflow */
6483d8817e4Smiod 0, /* special_function */
6493d8817e4Smiod "R_REL", /* name */
6503d8817e4Smiod TRUE, /* partial_inplace */
6513d8817e4Smiod 0xffffffff, /* src_mask */
6523d8817e4Smiod 0xffffffff, /* dst_mask */
6533d8817e4Smiod FALSE), /* pcrel_offset */
6543d8817e4Smiod
6553d8817e4Smiod /* 16 bit TOC relative relocation. */
6563d8817e4Smiod HOWTO (R_TOC, /* type */
6573d8817e4Smiod 0, /* rightshift */
6583d8817e4Smiod 1, /* size (0 = byte, 1 = short, 2 = long) */
6593d8817e4Smiod 16, /* bitsize */
6603d8817e4Smiod FALSE, /* pc_relative */
6613d8817e4Smiod 0, /* bitpos */
6623d8817e4Smiod complain_overflow_bitfield, /* complain_on_overflow */
6633d8817e4Smiod 0, /* special_function */
6643d8817e4Smiod "R_TOC", /* name */
6653d8817e4Smiod TRUE, /* partial_inplace */
6663d8817e4Smiod 0xffff, /* src_mask */
6673d8817e4Smiod 0xffff, /* dst_mask */
6683d8817e4Smiod FALSE), /* pcrel_offset */
6693d8817e4Smiod
6703d8817e4Smiod /* I don't really know what this is. */
6713d8817e4Smiod HOWTO (R_RTB, /* type */
6723d8817e4Smiod 1, /* rightshift */
6733d8817e4Smiod 2, /* size (0 = byte, 1 = short, 2 = long) */
6743d8817e4Smiod 32, /* bitsize */
6753d8817e4Smiod FALSE, /* pc_relative */
6763d8817e4Smiod 0, /* bitpos */
6773d8817e4Smiod complain_overflow_bitfield, /* complain_on_overflow */
6783d8817e4Smiod 0, /* special_function */
6793d8817e4Smiod "R_RTB", /* name */
6803d8817e4Smiod TRUE, /* partial_inplace */
6813d8817e4Smiod 0xffffffff, /* src_mask */
6823d8817e4Smiod 0xffffffff, /* dst_mask */
6833d8817e4Smiod FALSE), /* pcrel_offset */
6843d8817e4Smiod
6853d8817e4Smiod /* External TOC relative symbol. */
6863d8817e4Smiod HOWTO (R_GL, /* type */
6873d8817e4Smiod 0, /* rightshift */
6883d8817e4Smiod 1, /* size (0 = byte, 1 = short, 2 = long) */
6893d8817e4Smiod 16, /* bitsize */
6903d8817e4Smiod FALSE, /* pc_relative */
6913d8817e4Smiod 0, /* bitpos */
6923d8817e4Smiod complain_overflow_bitfield, /* complain_on_overflow */
6933d8817e4Smiod 0, /* special_function */
6943d8817e4Smiod "R_GL", /* name */
6953d8817e4Smiod TRUE, /* partial_inplace */
6963d8817e4Smiod 0xffff, /* src_mask */
6973d8817e4Smiod 0xffff, /* dst_mask */
6983d8817e4Smiod FALSE), /* pcrel_offset */
6993d8817e4Smiod
7003d8817e4Smiod /* Local TOC relative symbol. */
7013d8817e4Smiod HOWTO (R_TCL, /* type */
7023d8817e4Smiod 0, /* rightshift */
7033d8817e4Smiod 1, /* size (0 = byte, 1 = short, 2 = long) */
7043d8817e4Smiod 16, /* bitsize */
7053d8817e4Smiod FALSE, /* pc_relative */
7063d8817e4Smiod 0, /* bitpos */
7073d8817e4Smiod complain_overflow_bitfield, /* complain_on_overflow */
7083d8817e4Smiod 0, /* special_function */
7093d8817e4Smiod "R_TCL", /* name */
7103d8817e4Smiod TRUE, /* partial_inplace */
7113d8817e4Smiod 0xffff, /* src_mask */
7123d8817e4Smiod 0xffff, /* dst_mask */
7133d8817e4Smiod FALSE), /* pcrel_offset */
7143d8817e4Smiod
7153d8817e4Smiod EMPTY_HOWTO (7),
7163d8817e4Smiod
7173d8817e4Smiod /* Non modifiable absolute branch. */
7183d8817e4Smiod HOWTO (R_BA, /* type */
7193d8817e4Smiod 0, /* rightshift */
7203d8817e4Smiod 2, /* size (0 = byte, 1 = short, 2 = long) */
7213d8817e4Smiod 26, /* bitsize */
7223d8817e4Smiod FALSE, /* pc_relative */
7233d8817e4Smiod 0, /* bitpos */
7243d8817e4Smiod complain_overflow_bitfield, /* complain_on_overflow */
7253d8817e4Smiod 0, /* special_function */
7263d8817e4Smiod "R_BA_26", /* name */
7273d8817e4Smiod TRUE, /* partial_inplace */
7283d8817e4Smiod 0x03fffffc, /* src_mask */
7293d8817e4Smiod 0x03fffffc, /* dst_mask */
7303d8817e4Smiod FALSE), /* pcrel_offset */
7313d8817e4Smiod
7323d8817e4Smiod EMPTY_HOWTO (9),
7333d8817e4Smiod
7343d8817e4Smiod /* Non modifiable relative branch. */
7353d8817e4Smiod HOWTO (R_BR, /* type */
7363d8817e4Smiod 0, /* rightshift */
7373d8817e4Smiod 2, /* size (0 = byte, 1 = short, 2 = long) */
7383d8817e4Smiod 26, /* bitsize */
7393d8817e4Smiod TRUE, /* pc_relative */
7403d8817e4Smiod 0, /* bitpos */
7413d8817e4Smiod complain_overflow_signed, /* complain_on_overflow */
7423d8817e4Smiod 0, /* special_function */
7433d8817e4Smiod "R_BR", /* name */
7443d8817e4Smiod TRUE, /* partial_inplace */
7453d8817e4Smiod 0x03fffffc, /* src_mask */
7463d8817e4Smiod 0x03fffffc, /* dst_mask */
7473d8817e4Smiod FALSE), /* pcrel_offset */
7483d8817e4Smiod
7493d8817e4Smiod EMPTY_HOWTO (0xb),
7503d8817e4Smiod
7513d8817e4Smiod /* Indirect load. */
7523d8817e4Smiod HOWTO (R_RL, /* type */
7533d8817e4Smiod 0, /* rightshift */
7543d8817e4Smiod 1, /* size (0 = byte, 1 = short, 2 = long) */
7553d8817e4Smiod 16, /* bitsize */
7563d8817e4Smiod FALSE, /* pc_relative */
7573d8817e4Smiod 0, /* bitpos */
7583d8817e4Smiod complain_overflow_bitfield, /* complain_on_overflow */
7593d8817e4Smiod 0, /* special_function */
7603d8817e4Smiod "R_RL", /* name */
7613d8817e4Smiod TRUE, /* partial_inplace */
7623d8817e4Smiod 0xffff, /* src_mask */
7633d8817e4Smiod 0xffff, /* dst_mask */
7643d8817e4Smiod FALSE), /* pcrel_offset */
7653d8817e4Smiod
7663d8817e4Smiod /* Load address. */
7673d8817e4Smiod HOWTO (R_RLA, /* type */
7683d8817e4Smiod 0, /* rightshift */
7693d8817e4Smiod 1, /* size (0 = byte, 1 = short, 2 = long) */
7703d8817e4Smiod 16, /* bitsize */
7713d8817e4Smiod FALSE, /* pc_relative */
7723d8817e4Smiod 0, /* bitpos */
7733d8817e4Smiod complain_overflow_bitfield, /* complain_on_overflow */
7743d8817e4Smiod 0, /* special_function */
7753d8817e4Smiod "R_RLA", /* name */
7763d8817e4Smiod TRUE, /* partial_inplace */
7773d8817e4Smiod 0xffff, /* src_mask */
7783d8817e4Smiod 0xffff, /* dst_mask */
7793d8817e4Smiod FALSE), /* pcrel_offset */
7803d8817e4Smiod
7813d8817e4Smiod EMPTY_HOWTO (0xe),
7823d8817e4Smiod
7833d8817e4Smiod /* Non-relocating reference. */
7843d8817e4Smiod HOWTO (R_REF, /* type */
7853d8817e4Smiod 0, /* rightshift */
7863d8817e4Smiod 2, /* size (0 = byte, 1 = short, 2 = long) */
7873d8817e4Smiod 32, /* bitsize */
7883d8817e4Smiod FALSE, /* pc_relative */
7893d8817e4Smiod 0, /* bitpos */
7903d8817e4Smiod complain_overflow_dont, /* complain_on_overflow */
7913d8817e4Smiod 0, /* special_function */
7923d8817e4Smiod "R_REF", /* name */
7933d8817e4Smiod FALSE, /* partial_inplace */
7943d8817e4Smiod 0, /* src_mask */
7953d8817e4Smiod 0, /* dst_mask */
7963d8817e4Smiod FALSE), /* pcrel_offset */
7973d8817e4Smiod
7983d8817e4Smiod EMPTY_HOWTO (0x10),
7993d8817e4Smiod EMPTY_HOWTO (0x11),
8003d8817e4Smiod
8013d8817e4Smiod /* TOC relative indirect load. */
8023d8817e4Smiod HOWTO (R_TRL, /* type */
8033d8817e4Smiod 0, /* rightshift */
8043d8817e4Smiod 1, /* size (0 = byte, 1 = short, 2 = long) */
8053d8817e4Smiod 16, /* bitsize */
8063d8817e4Smiod FALSE, /* pc_relative */
8073d8817e4Smiod 0, /* bitpos */
8083d8817e4Smiod complain_overflow_bitfield, /* complain_on_overflow */
8093d8817e4Smiod 0, /* special_function */
8103d8817e4Smiod "R_TRL", /* name */
8113d8817e4Smiod TRUE, /* partial_inplace */
8123d8817e4Smiod 0xffff, /* src_mask */
8133d8817e4Smiod 0xffff, /* dst_mask */
8143d8817e4Smiod FALSE), /* pcrel_offset */
8153d8817e4Smiod
8163d8817e4Smiod /* TOC relative load address. */
8173d8817e4Smiod HOWTO (R_TRLA, /* type */
8183d8817e4Smiod 0, /* rightshift */
8193d8817e4Smiod 1, /* size (0 = byte, 1 = short, 2 = long) */
8203d8817e4Smiod 16, /* bitsize */
8213d8817e4Smiod FALSE, /* pc_relative */
8223d8817e4Smiod 0, /* bitpos */
8233d8817e4Smiod complain_overflow_bitfield, /* complain_on_overflow */
8243d8817e4Smiod 0, /* special_function */
8253d8817e4Smiod "R_TRLA", /* name */
8263d8817e4Smiod TRUE, /* partial_inplace */
8273d8817e4Smiod 0xffff, /* src_mask */
8283d8817e4Smiod 0xffff, /* dst_mask */
8293d8817e4Smiod FALSE), /* pcrel_offset */
8303d8817e4Smiod
8313d8817e4Smiod /* Modifiable relative branch. */
8323d8817e4Smiod HOWTO (R_RRTBI, /* type */
8333d8817e4Smiod 1, /* rightshift */
8343d8817e4Smiod 2, /* size (0 = byte, 1 = short, 2 = long) */
8353d8817e4Smiod 32, /* bitsize */
8363d8817e4Smiod FALSE, /* pc_relative */
8373d8817e4Smiod 0, /* bitpos */
8383d8817e4Smiod complain_overflow_bitfield, /* complain_on_overflow */
8393d8817e4Smiod 0, /* special_function */
8403d8817e4Smiod "R_RRTBI", /* name */
8413d8817e4Smiod TRUE, /* partial_inplace */
8423d8817e4Smiod 0xffffffff, /* src_mask */
8433d8817e4Smiod 0xffffffff, /* dst_mask */
8443d8817e4Smiod FALSE), /* pcrel_offset */
8453d8817e4Smiod
8463d8817e4Smiod /* Modifiable absolute branch. */
8473d8817e4Smiod HOWTO (R_RRTBA, /* type */
8483d8817e4Smiod 1, /* rightshift */
8493d8817e4Smiod 2, /* size (0 = byte, 1 = short, 2 = long) */
8503d8817e4Smiod 32, /* bitsize */
8513d8817e4Smiod FALSE, /* pc_relative */
8523d8817e4Smiod 0, /* bitpos */
8533d8817e4Smiod complain_overflow_bitfield, /* complain_on_overflow */
8543d8817e4Smiod 0, /* special_function */
8553d8817e4Smiod "R_RRTBA", /* name */
8563d8817e4Smiod TRUE, /* partial_inplace */
8573d8817e4Smiod 0xffffffff, /* src_mask */
8583d8817e4Smiod 0xffffffff, /* dst_mask */
8593d8817e4Smiod FALSE), /* pcrel_offset */
8603d8817e4Smiod
8613d8817e4Smiod /* Modifiable call absolute indirect. */
8623d8817e4Smiod HOWTO (R_CAI, /* type */
8633d8817e4Smiod 0, /* rightshift */
8643d8817e4Smiod 1, /* size (0 = byte, 1 = short, 2 = long) */
8653d8817e4Smiod 16, /* bitsize */
8663d8817e4Smiod FALSE, /* pc_relative */
8673d8817e4Smiod 0, /* bitpos */
8683d8817e4Smiod complain_overflow_bitfield, /* complain_on_overflow */
8693d8817e4Smiod 0, /* special_function */
8703d8817e4Smiod "R_CAI", /* name */
8713d8817e4Smiod TRUE, /* partial_inplace */
8723d8817e4Smiod 0xffff, /* src_mask */
8733d8817e4Smiod 0xffff, /* dst_mask */
8743d8817e4Smiod FALSE), /* pcrel_offset */
8753d8817e4Smiod
8763d8817e4Smiod /* Modifiable call relative. */
8773d8817e4Smiod HOWTO (R_CREL, /* type */
8783d8817e4Smiod 0, /* rightshift */
8793d8817e4Smiod 1, /* size (0 = byte, 1 = short, 2 = long) */
8803d8817e4Smiod 16, /* bitsize */
8813d8817e4Smiod FALSE, /* pc_relative */
8823d8817e4Smiod 0, /* bitpos */
8833d8817e4Smiod complain_overflow_bitfield, /* complain_on_overflow */
8843d8817e4Smiod 0, /* special_function */
8853d8817e4Smiod "R_CREL", /* name */
8863d8817e4Smiod TRUE, /* partial_inplace */
8873d8817e4Smiod 0xffff, /* src_mask */
8883d8817e4Smiod 0xffff, /* dst_mask */
8893d8817e4Smiod FALSE), /* pcrel_offset */
8903d8817e4Smiod
8913d8817e4Smiod /* Modifiable branch absolute. */
8923d8817e4Smiod HOWTO (R_RBA, /* type */
8933d8817e4Smiod 0, /* rightshift */
8943d8817e4Smiod 2, /* size (0 = byte, 1 = short, 2 = long) */
8953d8817e4Smiod 26, /* bitsize */
8963d8817e4Smiod FALSE, /* pc_relative */
8973d8817e4Smiod 0, /* bitpos */
8983d8817e4Smiod complain_overflow_bitfield, /* complain_on_overflow */
8993d8817e4Smiod 0, /* special_function */
9003d8817e4Smiod "R_RBA", /* name */
9013d8817e4Smiod TRUE, /* partial_inplace */
9023d8817e4Smiod 0x03fffffc, /* src_mask */
9033d8817e4Smiod 0x03fffffc, /* dst_mask */
9043d8817e4Smiod FALSE), /* pcrel_offset */
9053d8817e4Smiod
9063d8817e4Smiod /* Modifiable branch absolute. */
9073d8817e4Smiod HOWTO (R_RBAC, /* type */
9083d8817e4Smiod 0, /* rightshift */
9093d8817e4Smiod 2, /* size (0 = byte, 1 = short, 2 = long) */
9103d8817e4Smiod 32, /* bitsize */
9113d8817e4Smiod FALSE, /* pc_relative */
9123d8817e4Smiod 0, /* bitpos */
9133d8817e4Smiod complain_overflow_bitfield, /* complain_on_overflow */
9143d8817e4Smiod 0, /* special_function */
9153d8817e4Smiod "R_RBAC", /* name */
9163d8817e4Smiod TRUE, /* partial_inplace */
9173d8817e4Smiod 0xffffffff, /* src_mask */
9183d8817e4Smiod 0xffffffff, /* dst_mask */
9193d8817e4Smiod FALSE), /* pcrel_offset */
9203d8817e4Smiod
9213d8817e4Smiod /* Modifiable branch relative. */
9223d8817e4Smiod HOWTO (R_RBR, /* type */
9233d8817e4Smiod 0, /* rightshift */
9243d8817e4Smiod 2, /* size (0 = byte, 1 = short, 2 = long) */
9253d8817e4Smiod 26, /* bitsize */
9263d8817e4Smiod FALSE, /* pc_relative */
9273d8817e4Smiod 0, /* bitpos */
9283d8817e4Smiod complain_overflow_signed, /* complain_on_overflow */
9293d8817e4Smiod 0, /* special_function */
9303d8817e4Smiod "R_RBR_26", /* name */
9313d8817e4Smiod TRUE, /* partial_inplace */
9323d8817e4Smiod 0x03fffffc, /* src_mask */
9333d8817e4Smiod 0x03fffffc, /* dst_mask */
9343d8817e4Smiod FALSE), /* pcrel_offset */
9353d8817e4Smiod
9363d8817e4Smiod /* Modifiable branch absolute. */
9373d8817e4Smiod HOWTO (R_RBRC, /* type */
9383d8817e4Smiod 0, /* rightshift */
9393d8817e4Smiod 1, /* size (0 = byte, 1 = short, 2 = long) */
9403d8817e4Smiod 16, /* bitsize */
9413d8817e4Smiod FALSE, /* pc_relative */
9423d8817e4Smiod 0, /* bitpos */
9433d8817e4Smiod complain_overflow_bitfield, /* complain_on_overflow */
9443d8817e4Smiod 0, /* special_function */
9453d8817e4Smiod "R_RBRC", /* name */
9463d8817e4Smiod TRUE, /* partial_inplace */
9473d8817e4Smiod 0xffff, /* src_mask */
9483d8817e4Smiod 0xffff, /* dst_mask */
9493d8817e4Smiod FALSE), /* pcrel_offset */
9503d8817e4Smiod
9513d8817e4Smiod /* 16 bit Non modifiable absolute branch. */
9523d8817e4Smiod HOWTO (R_BA, /* type */
9533d8817e4Smiod 0, /* rightshift */
9543d8817e4Smiod 1, /* size (0 = byte, 1 = short, 2 = long) */
9553d8817e4Smiod 16, /* bitsize */
9563d8817e4Smiod FALSE, /* pc_relative */
9573d8817e4Smiod 0, /* bitpos */
9583d8817e4Smiod complain_overflow_bitfield, /* complain_on_overflow */
9593d8817e4Smiod 0, /* special_function */
9603d8817e4Smiod "R_BA_16", /* name */
9613d8817e4Smiod TRUE, /* partial_inplace */
9623d8817e4Smiod 0xfffc, /* src_mask */
9633d8817e4Smiod 0xfffc, /* dst_mask */
9643d8817e4Smiod FALSE), /* pcrel_offset */
9653d8817e4Smiod
9663d8817e4Smiod /* Modifiable branch relative. */
9673d8817e4Smiod HOWTO (R_RBR, /* type */
9683d8817e4Smiod 0, /* rightshift */
9693d8817e4Smiod 1, /* size (0 = byte, 1 = short, 2 = long) */
9703d8817e4Smiod 16, /* bitsize */
9713d8817e4Smiod FALSE, /* pc_relative */
9723d8817e4Smiod 0, /* bitpos */
9733d8817e4Smiod complain_overflow_signed, /* complain_on_overflow */
9743d8817e4Smiod 0, /* special_function */
9753d8817e4Smiod "R_RBR_16", /* name */
9763d8817e4Smiod TRUE, /* partial_inplace */
9773d8817e4Smiod 0xffff, /* src_mask */
9783d8817e4Smiod 0xffff, /* dst_mask */
9793d8817e4Smiod FALSE), /* pcrel_offset */
9803d8817e4Smiod
9813d8817e4Smiod /* Modifiable branch relative. */
9823d8817e4Smiod HOWTO (R_RBA, /* type */
9833d8817e4Smiod 0, /* rightshift */
9843d8817e4Smiod 1, /* size (0 = byte, 1 = short, 2 = long) */
9853d8817e4Smiod 16, /* bitsize */
9863d8817e4Smiod FALSE, /* pc_relative */
9873d8817e4Smiod 0, /* bitpos */
9883d8817e4Smiod complain_overflow_signed, /* complain_on_overflow */
9893d8817e4Smiod 0, /* special_function */
9903d8817e4Smiod "R_RBA_16", /* name */
9913d8817e4Smiod TRUE, /* partial_inplace */
9923d8817e4Smiod 0xffff, /* src_mask */
9933d8817e4Smiod 0xffff, /* dst_mask */
9943d8817e4Smiod FALSE), /* pcrel_offset */
9953d8817e4Smiod
9963d8817e4Smiod };
9973d8817e4Smiod
9983d8817e4Smiod void
xcoff_rtype2howto(relent,internal)9993d8817e4Smiod xcoff_rtype2howto (relent, internal)
10003d8817e4Smiod arelent *relent;
10013d8817e4Smiod struct internal_reloc *internal;
10023d8817e4Smiod {
10033d8817e4Smiod if (internal->r_type > R_RBRC)
10043d8817e4Smiod abort ();
10053d8817e4Smiod
10063d8817e4Smiod /* Default howto layout works most of the time */
10073d8817e4Smiod relent->howto = &xcoff_howto_table[internal->r_type];
10083d8817e4Smiod
10093d8817e4Smiod /* Special case some 16 bit reloc */
10103d8817e4Smiod if (15 == (internal->r_size & 0x1f))
10113d8817e4Smiod {
10123d8817e4Smiod if (R_BA == internal->r_type)
10133d8817e4Smiod relent->howto = &xcoff_howto_table[0x1c];
10143d8817e4Smiod else if (R_RBR == internal->r_type)
10153d8817e4Smiod relent->howto = &xcoff_howto_table[0x1d];
10163d8817e4Smiod else if (R_RBA == internal->r_type)
10173d8817e4Smiod relent->howto = &xcoff_howto_table[0x1e];
10183d8817e4Smiod }
10193d8817e4Smiod
10203d8817e4Smiod /* The r_size field of an XCOFF reloc encodes the bitsize of the
10213d8817e4Smiod relocation, as well as indicating whether it is signed or not.
10223d8817e4Smiod Doublecheck that the relocation information gathered from the
10233d8817e4Smiod type matches this information. The bitsize is not significant
10243d8817e4Smiod for R_REF relocs. */
10253d8817e4Smiod if (relent->howto->dst_mask != 0
10263d8817e4Smiod && (relent->howto->bitsize
10273d8817e4Smiod != ((unsigned int) internal->r_size & 0x1f) + 1))
10283d8817e4Smiod abort ();
10293d8817e4Smiod }
10303d8817e4Smiod
10313d8817e4Smiod reloc_howto_type *
_bfd_xcoff_reloc_type_lookup(abfd,code)10323d8817e4Smiod _bfd_xcoff_reloc_type_lookup (abfd, code)
10333d8817e4Smiod bfd *abfd ATTRIBUTE_UNUSED;
10343d8817e4Smiod bfd_reloc_code_real_type code;
10353d8817e4Smiod {
10363d8817e4Smiod switch (code)
10373d8817e4Smiod {
10383d8817e4Smiod case BFD_RELOC_PPC_B26:
10393d8817e4Smiod return &xcoff_howto_table[0xa];
10403d8817e4Smiod case BFD_RELOC_PPC_BA16:
10413d8817e4Smiod return &xcoff_howto_table[0x1c];
10423d8817e4Smiod case BFD_RELOC_PPC_BA26:
10433d8817e4Smiod return &xcoff_howto_table[8];
10443d8817e4Smiod case BFD_RELOC_PPC_TOC16:
10453d8817e4Smiod return &xcoff_howto_table[3];
10463d8817e4Smiod case BFD_RELOC_32:
10473d8817e4Smiod case BFD_RELOC_CTOR:
10483d8817e4Smiod return &xcoff_howto_table[0];
10493d8817e4Smiod default:
10503d8817e4Smiod return NULL;
10513d8817e4Smiod }
10523d8817e4Smiod }
10533d8817e4Smiod
10543d8817e4Smiod
10553d8817e4Smiod /* XCOFF archive support. The original version of this code was by
10563d8817e4Smiod Damon A. Permezel. It was enhanced to permit cross support, and
10573d8817e4Smiod writing archive files, by Ian Lance Taylor, Cygnus Support.
10583d8817e4Smiod
10593d8817e4Smiod XCOFF uses its own archive format. Everything is hooked together
10603d8817e4Smiod with file offset links, so it is possible to rapidly update an
10613d8817e4Smiod archive in place. Of course, we don't do that. An XCOFF archive
10623d8817e4Smiod has a real file header, not just an ARMAG string. The structure of
10633d8817e4Smiod the file header and of each archive header appear below.
10643d8817e4Smiod
10653d8817e4Smiod An XCOFF archive also has a member table, which is a list of
10663d8817e4Smiod elements in the archive (you can get that by looking through the
10673d8817e4Smiod linked list, but you have to read a lot more of the file). The
10683d8817e4Smiod member table has a normal archive header with an empty name. It is
10693d8817e4Smiod normally (and perhaps must be) the second to last entry in the
10703d8817e4Smiod archive. The member table data is almost printable ASCII. It
10713d8817e4Smiod starts with a 12 character decimal string which is the number of
10723d8817e4Smiod entries in the table. For each entry it has a 12 character decimal
10733d8817e4Smiod string which is the offset in the archive of that member. These
10743d8817e4Smiod entries are followed by a series of null terminated strings which
10753d8817e4Smiod are the member names for each entry.
10763d8817e4Smiod
10773d8817e4Smiod Finally, an XCOFF archive has a global symbol table, which is what
10783d8817e4Smiod we call the armap. The global symbol table has a normal archive
10793d8817e4Smiod header with an empty name. It is normally (and perhaps must be)
10803d8817e4Smiod the last entry in the archive. The contents start with a four byte
10813d8817e4Smiod binary number which is the number of entries. This is followed by
10823d8817e4Smiod a that many four byte binary numbers; each is the file offset of an
10833d8817e4Smiod entry in the archive. These numbers are followed by a series of
10843d8817e4Smiod null terminated strings, which are symbol names.
10853d8817e4Smiod
10863d8817e4Smiod AIX 4.3 introduced a new archive format which can handle larger
10873d8817e4Smiod files and also 32- and 64-bit objects in the same archive. The
10883d8817e4Smiod things said above remain true except that there is now more than
10893d8817e4Smiod one global symbol table. The one is used to index 32-bit objects,
10903d8817e4Smiod the other for 64-bit objects.
10913d8817e4Smiod
10923d8817e4Smiod The new archives (recognizable by the new ARMAG string) has larger
10933d8817e4Smiod field lengths so that we cannot really share any code. Also we have
10943d8817e4Smiod to take care that we are not generating the new form of archives
10953d8817e4Smiod on AIX 4.2 or earlier systems. */
10963d8817e4Smiod
10973d8817e4Smiod /* XCOFF archives use this as a magic string. Note that both strings
10983d8817e4Smiod have the same length. */
10993d8817e4Smiod
11003d8817e4Smiod /* Set the magic for archive. */
11013d8817e4Smiod
11023d8817e4Smiod bfd_boolean
bfd_xcoff_ar_archive_set_magic(abfd,magic)11033d8817e4Smiod bfd_xcoff_ar_archive_set_magic (abfd, magic)
11043d8817e4Smiod bfd *abfd ATTRIBUTE_UNUSED;
11053d8817e4Smiod char *magic ATTRIBUTE_UNUSED;
11063d8817e4Smiod {
11073d8817e4Smiod /* Not supported yet. */
11083d8817e4Smiod return FALSE;
11093d8817e4Smiod /* bfd_xcoff_archive_set_magic (abfd, magic); */
11103d8817e4Smiod }
11113d8817e4Smiod
11123d8817e4Smiod /* Read in the armap of an XCOFF archive. */
11133d8817e4Smiod
11143d8817e4Smiod bfd_boolean
_bfd_xcoff_slurp_armap(abfd)11153d8817e4Smiod _bfd_xcoff_slurp_armap (abfd)
11163d8817e4Smiod bfd *abfd;
11173d8817e4Smiod {
11183d8817e4Smiod file_ptr off;
11193d8817e4Smiod size_t namlen;
11203d8817e4Smiod bfd_size_type sz;
11213d8817e4Smiod bfd_byte *contents, *cend;
11223d8817e4Smiod bfd_vma c, i;
11233d8817e4Smiod carsym *arsym;
11243d8817e4Smiod bfd_byte *p;
11253d8817e4Smiod
11263d8817e4Smiod if (xcoff_ardata (abfd) == NULL)
11273d8817e4Smiod {
11283d8817e4Smiod bfd_has_map (abfd) = FALSE;
11293d8817e4Smiod return TRUE;
11303d8817e4Smiod }
11313d8817e4Smiod
11323d8817e4Smiod if (! xcoff_big_format_p (abfd))
11333d8817e4Smiod {
11343d8817e4Smiod /* This is for the old format. */
11353d8817e4Smiod struct xcoff_ar_hdr hdr;
11363d8817e4Smiod
11373d8817e4Smiod off = strtol (xcoff_ardata (abfd)->symoff, (char **) NULL, 10);
11383d8817e4Smiod if (off == 0)
11393d8817e4Smiod {
11403d8817e4Smiod bfd_has_map (abfd) = FALSE;
11413d8817e4Smiod return TRUE;
11423d8817e4Smiod }
11433d8817e4Smiod
11443d8817e4Smiod if (bfd_seek (abfd, off, SEEK_SET) != 0)
11453d8817e4Smiod return FALSE;
11463d8817e4Smiod
11473d8817e4Smiod /* The symbol table starts with a normal archive header. */
11483d8817e4Smiod if (bfd_bread ((PTR) &hdr, (bfd_size_type) SIZEOF_AR_HDR, abfd)
11493d8817e4Smiod != SIZEOF_AR_HDR)
11503d8817e4Smiod return FALSE;
11513d8817e4Smiod
11523d8817e4Smiod /* Skip the name (normally empty). */
11533d8817e4Smiod namlen = strtol (hdr.namlen, (char **) NULL, 10);
11543d8817e4Smiod off = ((namlen + 1) & ~ (size_t) 1) + SXCOFFARFMAG;
11553d8817e4Smiod if (bfd_seek (abfd, off, SEEK_CUR) != 0)
11563d8817e4Smiod return FALSE;
11573d8817e4Smiod
11583d8817e4Smiod sz = strtol (hdr.size, (char **) NULL, 10);
11593d8817e4Smiod
11603d8817e4Smiod /* Read in the entire symbol table. */
11613d8817e4Smiod contents = (bfd_byte *) bfd_alloc (abfd, sz);
11623d8817e4Smiod if (contents == NULL)
11633d8817e4Smiod return FALSE;
11643d8817e4Smiod if (bfd_bread ((PTR) contents, sz, abfd) != sz)
11653d8817e4Smiod return FALSE;
11663d8817e4Smiod
11673d8817e4Smiod /* The symbol table starts with a four byte count. */
11683d8817e4Smiod c = H_GET_32 (abfd, contents);
11693d8817e4Smiod
11703d8817e4Smiod if (c * 4 >= sz)
11713d8817e4Smiod {
11723d8817e4Smiod bfd_set_error (bfd_error_bad_value);
11733d8817e4Smiod return FALSE;
11743d8817e4Smiod }
11753d8817e4Smiod
11763d8817e4Smiod bfd_ardata (abfd)->symdefs =
11773d8817e4Smiod ((carsym *) bfd_alloc (abfd, c * sizeof (carsym)));
11783d8817e4Smiod if (bfd_ardata (abfd)->symdefs == NULL)
11793d8817e4Smiod return FALSE;
11803d8817e4Smiod
11813d8817e4Smiod /* After the count comes a list of four byte file offsets. */
11823d8817e4Smiod for (i = 0, arsym = bfd_ardata (abfd)->symdefs, p = contents + 4;
11833d8817e4Smiod i < c;
11843d8817e4Smiod ++i, ++arsym, p += 4)
11853d8817e4Smiod arsym->file_offset = H_GET_32 (abfd, p);
11863d8817e4Smiod }
11873d8817e4Smiod else
11883d8817e4Smiod {
11893d8817e4Smiod /* This is for the new format. */
11903d8817e4Smiod struct xcoff_ar_hdr_big hdr;
11913d8817e4Smiod
11923d8817e4Smiod off = strtol (xcoff_ardata_big (abfd)->symoff, (char **) NULL, 10);
11933d8817e4Smiod if (off == 0)
11943d8817e4Smiod {
11953d8817e4Smiod bfd_has_map (abfd) = FALSE;
11963d8817e4Smiod return TRUE;
11973d8817e4Smiod }
11983d8817e4Smiod
11993d8817e4Smiod if (bfd_seek (abfd, off, SEEK_SET) != 0)
12003d8817e4Smiod return FALSE;
12013d8817e4Smiod
12023d8817e4Smiod /* The symbol table starts with a normal archive header. */
12033d8817e4Smiod if (bfd_bread ((PTR) &hdr, (bfd_size_type) SIZEOF_AR_HDR_BIG, abfd)
12043d8817e4Smiod != SIZEOF_AR_HDR_BIG)
12053d8817e4Smiod return FALSE;
12063d8817e4Smiod
12073d8817e4Smiod /* Skip the name (normally empty). */
12083d8817e4Smiod namlen = strtol (hdr.namlen, (char **) NULL, 10);
12093d8817e4Smiod off = ((namlen + 1) & ~ (size_t) 1) + SXCOFFARFMAG;
12103d8817e4Smiod if (bfd_seek (abfd, off, SEEK_CUR) != 0)
12113d8817e4Smiod return FALSE;
12123d8817e4Smiod
12133d8817e4Smiod /* XXX This actually has to be a call to strtoll (at least on 32-bit
12143d8817e4Smiod machines) since the field width is 20 and there numbers with more
12153d8817e4Smiod than 32 bits can be represented. */
12163d8817e4Smiod sz = strtol (hdr.size, (char **) NULL, 10);
12173d8817e4Smiod
12183d8817e4Smiod /* Read in the entire symbol table. */
12193d8817e4Smiod contents = (bfd_byte *) bfd_alloc (abfd, sz);
12203d8817e4Smiod if (contents == NULL)
12213d8817e4Smiod return FALSE;
12223d8817e4Smiod if (bfd_bread ((PTR) contents, sz, abfd) != sz)
12233d8817e4Smiod return FALSE;
12243d8817e4Smiod
12253d8817e4Smiod /* The symbol table starts with an eight byte count. */
12263d8817e4Smiod c = H_GET_64 (abfd, contents);
12273d8817e4Smiod
12283d8817e4Smiod if (c * 8 >= sz)
12293d8817e4Smiod {
12303d8817e4Smiod bfd_set_error (bfd_error_bad_value);
12313d8817e4Smiod return FALSE;
12323d8817e4Smiod }
12333d8817e4Smiod
12343d8817e4Smiod bfd_ardata (abfd)->symdefs =
12353d8817e4Smiod ((carsym *) bfd_alloc (abfd, c * sizeof (carsym)));
12363d8817e4Smiod if (bfd_ardata (abfd)->symdefs == NULL)
12373d8817e4Smiod return FALSE;
12383d8817e4Smiod
12393d8817e4Smiod /* After the count comes a list of eight byte file offsets. */
12403d8817e4Smiod for (i = 0, arsym = bfd_ardata (abfd)->symdefs, p = contents + 8;
12413d8817e4Smiod i < c;
12423d8817e4Smiod ++i, ++arsym, p += 8)
12433d8817e4Smiod arsym->file_offset = H_GET_64 (abfd, p);
12443d8817e4Smiod }
12453d8817e4Smiod
12463d8817e4Smiod /* After the file offsets come null terminated symbol names. */
12473d8817e4Smiod cend = contents + sz;
12483d8817e4Smiod for (i = 0, arsym = bfd_ardata (abfd)->symdefs;
12493d8817e4Smiod i < c;
12503d8817e4Smiod ++i, ++arsym, p += strlen ((char *) p) + 1)
12513d8817e4Smiod {
12523d8817e4Smiod if (p >= cend)
12533d8817e4Smiod {
12543d8817e4Smiod bfd_set_error (bfd_error_bad_value);
12553d8817e4Smiod return FALSE;
12563d8817e4Smiod }
12573d8817e4Smiod arsym->name = (char *) p;
12583d8817e4Smiod }
12593d8817e4Smiod
12603d8817e4Smiod bfd_ardata (abfd)->symdef_count = c;
12613d8817e4Smiod bfd_has_map (abfd) = TRUE;
12623d8817e4Smiod
12633d8817e4Smiod return TRUE;
12643d8817e4Smiod }
12653d8817e4Smiod
12663d8817e4Smiod /* See if this is an XCOFF archive. */
12673d8817e4Smiod
12683d8817e4Smiod const bfd_target *
_bfd_xcoff_archive_p(abfd)12693d8817e4Smiod _bfd_xcoff_archive_p (abfd)
12703d8817e4Smiod bfd *abfd;
12713d8817e4Smiod {
12723d8817e4Smiod struct artdata *tdata_hold;
12733d8817e4Smiod char magic[SXCOFFARMAG];
12743d8817e4Smiod bfd_size_type amt = SXCOFFARMAG;
12753d8817e4Smiod
12763d8817e4Smiod if (bfd_bread ((PTR) magic, amt, abfd) != amt)
12773d8817e4Smiod {
12783d8817e4Smiod if (bfd_get_error () != bfd_error_system_call)
12793d8817e4Smiod bfd_set_error (bfd_error_wrong_format);
12803d8817e4Smiod return NULL;
12813d8817e4Smiod }
12823d8817e4Smiod
12833d8817e4Smiod if (strncmp (magic, XCOFFARMAG, SXCOFFARMAG) != 0
12843d8817e4Smiod && strncmp (magic, XCOFFARMAGBIG, SXCOFFARMAG) != 0)
12853d8817e4Smiod {
12863d8817e4Smiod bfd_set_error (bfd_error_wrong_format);
12873d8817e4Smiod return NULL;
12883d8817e4Smiod }
12893d8817e4Smiod
12903d8817e4Smiod tdata_hold = bfd_ardata (abfd);
12913d8817e4Smiod
12923d8817e4Smiod amt = sizeof (struct artdata);
12933d8817e4Smiod bfd_ardata (abfd) = (struct artdata *) bfd_zalloc (abfd, amt);
12943d8817e4Smiod if (bfd_ardata (abfd) == (struct artdata *) NULL)
12953d8817e4Smiod goto error_ret_restore;
12963d8817e4Smiod
12973d8817e4Smiod /* Cleared by bfd_zalloc above.
12983d8817e4Smiod bfd_ardata (abfd)->cache = NULL;
12993d8817e4Smiod bfd_ardata (abfd)->archive_head = NULL;
13003d8817e4Smiod bfd_ardata (abfd)->symdefs = NULL;
13013d8817e4Smiod bfd_ardata (abfd)->extended_names = NULL;
13023d8817e4Smiod bfd_ardata (abfd)->extended_names_size = 0; */
13033d8817e4Smiod
13043d8817e4Smiod /* Now handle the two formats. */
13053d8817e4Smiod if (magic[1] != 'b')
13063d8817e4Smiod {
13073d8817e4Smiod /* This is the old format. */
13083d8817e4Smiod struct xcoff_ar_file_hdr hdr;
13093d8817e4Smiod
13103d8817e4Smiod /* Copy over the magic string. */
13113d8817e4Smiod memcpy (hdr.magic, magic, SXCOFFARMAG);
13123d8817e4Smiod
13133d8817e4Smiod /* Now read the rest of the file header. */
13143d8817e4Smiod amt = SIZEOF_AR_FILE_HDR - SXCOFFARMAG;
13153d8817e4Smiod if (bfd_bread ((PTR) &hdr.memoff, amt, abfd) != amt)
13163d8817e4Smiod {
13173d8817e4Smiod if (bfd_get_error () != bfd_error_system_call)
13183d8817e4Smiod bfd_set_error (bfd_error_wrong_format);
13193d8817e4Smiod goto error_ret;
13203d8817e4Smiod }
13213d8817e4Smiod
13223d8817e4Smiod bfd_ardata (abfd)->first_file_filepos = strtol (hdr.firstmemoff,
13233d8817e4Smiod (char **) NULL, 10);
13243d8817e4Smiod
13253d8817e4Smiod amt = SIZEOF_AR_FILE_HDR;
13263d8817e4Smiod bfd_ardata (abfd)->tdata = bfd_zalloc (abfd, amt);
13273d8817e4Smiod if (bfd_ardata (abfd)->tdata == NULL)
13283d8817e4Smiod goto error_ret;
13293d8817e4Smiod
13303d8817e4Smiod memcpy (bfd_ardata (abfd)->tdata, &hdr, SIZEOF_AR_FILE_HDR);
13313d8817e4Smiod }
13323d8817e4Smiod else
13333d8817e4Smiod {
13343d8817e4Smiod /* This is the new format. */
13353d8817e4Smiod struct xcoff_ar_file_hdr_big hdr;
13363d8817e4Smiod
13373d8817e4Smiod /* Copy over the magic string. */
13383d8817e4Smiod memcpy (hdr.magic, magic, SXCOFFARMAG);
13393d8817e4Smiod
13403d8817e4Smiod /* Now read the rest of the file header. */
13413d8817e4Smiod amt = SIZEOF_AR_FILE_HDR_BIG - SXCOFFARMAG;
13423d8817e4Smiod if (bfd_bread ((PTR) &hdr.memoff, amt, abfd) != amt)
13433d8817e4Smiod {
13443d8817e4Smiod if (bfd_get_error () != bfd_error_system_call)
13453d8817e4Smiod bfd_set_error (bfd_error_wrong_format);
13463d8817e4Smiod goto error_ret;
13473d8817e4Smiod }
13483d8817e4Smiod
13493d8817e4Smiod bfd_ardata (abfd)->first_file_filepos = bfd_scan_vma (hdr.firstmemoff,
13503d8817e4Smiod (const char **) 0,
13513d8817e4Smiod 10);
13523d8817e4Smiod
13533d8817e4Smiod amt = SIZEOF_AR_FILE_HDR_BIG;
13543d8817e4Smiod bfd_ardata (abfd)->tdata = bfd_zalloc (abfd, amt);
13553d8817e4Smiod if (bfd_ardata (abfd)->tdata == NULL)
13563d8817e4Smiod goto error_ret;
13573d8817e4Smiod
13583d8817e4Smiod memcpy (bfd_ardata (abfd)->tdata, &hdr, SIZEOF_AR_FILE_HDR_BIG);
13593d8817e4Smiod }
13603d8817e4Smiod
13613d8817e4Smiod if (! _bfd_xcoff_slurp_armap (abfd))
13623d8817e4Smiod {
13633d8817e4Smiod error_ret:
13643d8817e4Smiod bfd_release (abfd, bfd_ardata (abfd));
13653d8817e4Smiod error_ret_restore:
13663d8817e4Smiod bfd_ardata (abfd) = tdata_hold;
13673d8817e4Smiod return NULL;
13683d8817e4Smiod }
13693d8817e4Smiod
13703d8817e4Smiod return abfd->xvec;
13713d8817e4Smiod }
13723d8817e4Smiod
13733d8817e4Smiod /* Read the archive header in an XCOFF archive. */
13743d8817e4Smiod
13753d8817e4Smiod PTR
_bfd_xcoff_read_ar_hdr(abfd)13763d8817e4Smiod _bfd_xcoff_read_ar_hdr (abfd)
13773d8817e4Smiod bfd *abfd;
13783d8817e4Smiod {
13793d8817e4Smiod bfd_size_type namlen;
13803d8817e4Smiod struct areltdata *ret;
13813d8817e4Smiod bfd_size_type amt = sizeof (struct areltdata);
13823d8817e4Smiod
13833d8817e4Smiod ret = (struct areltdata *) bfd_alloc (abfd, amt);
13843d8817e4Smiod if (ret == NULL)
13853d8817e4Smiod return NULL;
13863d8817e4Smiod
13873d8817e4Smiod if (! xcoff_big_format_p (abfd))
13883d8817e4Smiod {
13893d8817e4Smiod struct xcoff_ar_hdr hdr;
13903d8817e4Smiod struct xcoff_ar_hdr *hdrp;
13913d8817e4Smiod
13923d8817e4Smiod if (bfd_bread ((PTR) &hdr, (bfd_size_type) SIZEOF_AR_HDR, abfd)
13933d8817e4Smiod != SIZEOF_AR_HDR)
13943d8817e4Smiod {
13953d8817e4Smiod free (ret);
13963d8817e4Smiod return NULL;
13973d8817e4Smiod }
13983d8817e4Smiod
13993d8817e4Smiod namlen = strtol (hdr.namlen, (char **) NULL, 10);
14003d8817e4Smiod amt = SIZEOF_AR_HDR + namlen + 1;
14013d8817e4Smiod hdrp = (struct xcoff_ar_hdr *) bfd_alloc (abfd, amt);
14023d8817e4Smiod if (hdrp == NULL)
14033d8817e4Smiod {
14043d8817e4Smiod free (ret);
14053d8817e4Smiod return NULL;
14063d8817e4Smiod }
14073d8817e4Smiod memcpy (hdrp, &hdr, SIZEOF_AR_HDR);
14083d8817e4Smiod if (bfd_bread ((char *) hdrp + SIZEOF_AR_HDR, namlen, abfd) != namlen)
14093d8817e4Smiod {
14103d8817e4Smiod free (ret);
14113d8817e4Smiod return NULL;
14123d8817e4Smiod }
14133d8817e4Smiod ((char *) hdrp)[SIZEOF_AR_HDR + namlen] = '\0';
14143d8817e4Smiod
14153d8817e4Smiod ret->arch_header = (char *) hdrp;
14163d8817e4Smiod ret->parsed_size = strtol (hdr.size, (char **) NULL, 10);
14173d8817e4Smiod ret->filename = (char *) hdrp + SIZEOF_AR_HDR;
14183d8817e4Smiod }
14193d8817e4Smiod else
14203d8817e4Smiod {
14213d8817e4Smiod struct xcoff_ar_hdr_big hdr;
14223d8817e4Smiod struct xcoff_ar_hdr_big *hdrp;
14233d8817e4Smiod
14243d8817e4Smiod if (bfd_bread ((PTR) &hdr, (bfd_size_type) SIZEOF_AR_HDR_BIG, abfd)
14253d8817e4Smiod != SIZEOF_AR_HDR_BIG)
14263d8817e4Smiod {
14273d8817e4Smiod free (ret);
14283d8817e4Smiod return NULL;
14293d8817e4Smiod }
14303d8817e4Smiod
14313d8817e4Smiod namlen = strtol (hdr.namlen, (char **) NULL, 10);
14323d8817e4Smiod amt = SIZEOF_AR_HDR_BIG + namlen + 1;
14333d8817e4Smiod hdrp = (struct xcoff_ar_hdr_big *) bfd_alloc (abfd, amt);
14343d8817e4Smiod if (hdrp == NULL)
14353d8817e4Smiod {
14363d8817e4Smiod free (ret);
14373d8817e4Smiod return NULL;
14383d8817e4Smiod }
14393d8817e4Smiod memcpy (hdrp, &hdr, SIZEOF_AR_HDR_BIG);
14403d8817e4Smiod if (bfd_bread ((char *) hdrp + SIZEOF_AR_HDR_BIG, namlen, abfd) != namlen)
14413d8817e4Smiod {
14423d8817e4Smiod free (ret);
14433d8817e4Smiod return NULL;
14443d8817e4Smiod }
14453d8817e4Smiod ((char *) hdrp)[SIZEOF_AR_HDR_BIG + namlen] = '\0';
14463d8817e4Smiod
14473d8817e4Smiod ret->arch_header = (char *) hdrp;
14483d8817e4Smiod /* XXX This actually has to be a call to strtoll (at least on 32-bit
14493d8817e4Smiod machines) since the field width is 20 and there numbers with more
14503d8817e4Smiod than 32 bits can be represented. */
14513d8817e4Smiod ret->parsed_size = strtol (hdr.size, (char **) NULL, 10);
14523d8817e4Smiod ret->filename = (char *) hdrp + SIZEOF_AR_HDR_BIG;
14533d8817e4Smiod }
14543d8817e4Smiod
14553d8817e4Smiod /* Skip over the XCOFFARFMAG at the end of the file name. */
14563d8817e4Smiod if (bfd_seek (abfd, (file_ptr) ((namlen & 1) + SXCOFFARFMAG), SEEK_CUR) != 0)
14573d8817e4Smiod return NULL;
14583d8817e4Smiod
14593d8817e4Smiod return (PTR) ret;
14603d8817e4Smiod }
14613d8817e4Smiod
14623d8817e4Smiod /* Open the next element in an XCOFF archive. */
14633d8817e4Smiod
14643d8817e4Smiod bfd *
_bfd_xcoff_openr_next_archived_file(archive,last_file)14653d8817e4Smiod _bfd_xcoff_openr_next_archived_file (archive, last_file)
14663d8817e4Smiod bfd *archive;
14673d8817e4Smiod bfd *last_file;
14683d8817e4Smiod {
14693d8817e4Smiod file_ptr filestart;
14703d8817e4Smiod
14713d8817e4Smiod if (xcoff_ardata (archive) == NULL)
14723d8817e4Smiod {
14733d8817e4Smiod bfd_set_error (bfd_error_invalid_operation);
14743d8817e4Smiod return NULL;
14753d8817e4Smiod }
14763d8817e4Smiod
14773d8817e4Smiod if (! xcoff_big_format_p (archive))
14783d8817e4Smiod {
14793d8817e4Smiod if (last_file == NULL)
14803d8817e4Smiod filestart = bfd_ardata (archive)->first_file_filepos;
14813d8817e4Smiod else
14823d8817e4Smiod filestart = strtol (arch_xhdr (last_file)->nextoff, (char **) NULL,
14833d8817e4Smiod 10);
14843d8817e4Smiod
14853d8817e4Smiod if (filestart == 0
14863d8817e4Smiod || filestart == strtol (xcoff_ardata (archive)->memoff,
14873d8817e4Smiod (char **) NULL, 10)
14883d8817e4Smiod || filestart == strtol (xcoff_ardata (archive)->symoff,
14893d8817e4Smiod (char **) NULL, 10))
14903d8817e4Smiod {
14913d8817e4Smiod bfd_set_error (bfd_error_no_more_archived_files);
14923d8817e4Smiod return NULL;
14933d8817e4Smiod }
14943d8817e4Smiod }
14953d8817e4Smiod else
14963d8817e4Smiod {
14973d8817e4Smiod if (last_file == NULL)
14983d8817e4Smiod filestart = bfd_ardata (archive)->first_file_filepos;
14993d8817e4Smiod else
15003d8817e4Smiod /* XXX These actually have to be a calls to strtoll (at least
15013d8817e4Smiod on 32-bit machines) since the fields's width is 20 and
15023d8817e4Smiod there numbers with more than 32 bits can be represented. */
15033d8817e4Smiod filestart = strtol (arch_xhdr_big (last_file)->nextoff, (char **) NULL,
15043d8817e4Smiod 10);
15053d8817e4Smiod
15063d8817e4Smiod /* XXX These actually have to be calls to strtoll (at least on 32-bit
15073d8817e4Smiod machines) since the fields's width is 20 and there numbers with more
15083d8817e4Smiod than 32 bits can be represented. */
15093d8817e4Smiod if (filestart == 0
15103d8817e4Smiod || filestart == strtol (xcoff_ardata_big (archive)->memoff,
15113d8817e4Smiod (char **) NULL, 10)
15123d8817e4Smiod || filestart == strtol (xcoff_ardata_big (archive)->symoff,
15133d8817e4Smiod (char **) NULL, 10))
15143d8817e4Smiod {
15153d8817e4Smiod bfd_set_error (bfd_error_no_more_archived_files);
15163d8817e4Smiod return NULL;
15173d8817e4Smiod }
15183d8817e4Smiod }
15193d8817e4Smiod
15203d8817e4Smiod return _bfd_get_elt_at_filepos (archive, filestart);
15213d8817e4Smiod }
15223d8817e4Smiod
15233d8817e4Smiod /* Stat an element in an XCOFF archive. */
15243d8817e4Smiod
15253d8817e4Smiod int
_bfd_xcoff_stat_arch_elt(abfd,s)15263d8817e4Smiod _bfd_xcoff_stat_arch_elt (abfd, s)
15273d8817e4Smiod bfd *abfd;
15283d8817e4Smiod struct stat *s;
15293d8817e4Smiod {
15303d8817e4Smiod if (abfd->arelt_data == NULL)
15313d8817e4Smiod {
15323d8817e4Smiod bfd_set_error (bfd_error_invalid_operation);
15333d8817e4Smiod return -1;
15343d8817e4Smiod }
15353d8817e4Smiod
15363d8817e4Smiod if (! xcoff_big_format_p (abfd->my_archive))
15373d8817e4Smiod {
15383d8817e4Smiod struct xcoff_ar_hdr *hdrp = arch_xhdr (abfd);
15393d8817e4Smiod
1540*d04417c8Smiod s->st_mtime = strtoll (hdrp->date, (char **) NULL, 10);
15413d8817e4Smiod s->st_uid = strtol (hdrp->uid, (char **) NULL, 10);
15423d8817e4Smiod s->st_gid = strtol (hdrp->gid, (char **) NULL, 10);
15433d8817e4Smiod s->st_mode = strtol (hdrp->mode, (char **) NULL, 8);
15443d8817e4Smiod s->st_size = arch_eltdata (abfd)->parsed_size;
15453d8817e4Smiod }
15463d8817e4Smiod else
15473d8817e4Smiod {
15483d8817e4Smiod struct xcoff_ar_hdr_big *hdrp = arch_xhdr_big (abfd);
15493d8817e4Smiod
1550*d04417c8Smiod s->st_mtime = strtoll (hdrp->date, (char **) NULL, 10);
15513d8817e4Smiod s->st_uid = strtol (hdrp->uid, (char **) NULL, 10);
15523d8817e4Smiod s->st_gid = strtol (hdrp->gid, (char **) NULL, 10);
15533d8817e4Smiod s->st_mode = strtol (hdrp->mode, (char **) NULL, 8);
15543d8817e4Smiod s->st_size = arch_eltdata (abfd)->parsed_size;
15553d8817e4Smiod }
15563d8817e4Smiod
15573d8817e4Smiod return 0;
15583d8817e4Smiod }
15593d8817e4Smiod
15603d8817e4Smiod /* Normalize a file name for inclusion in an archive. */
15613d8817e4Smiod
15623d8817e4Smiod static const char *
normalize_filename(abfd)15633d8817e4Smiod normalize_filename (abfd)
15643d8817e4Smiod bfd *abfd;
15653d8817e4Smiod {
15663d8817e4Smiod const char *file;
15673d8817e4Smiod const char *filename;
15683d8817e4Smiod
15693d8817e4Smiod file = bfd_get_filename (abfd);
15703d8817e4Smiod filename = strrchr (file, '/');
15713d8817e4Smiod if (filename != NULL)
15723d8817e4Smiod filename++;
15733d8817e4Smiod else
15743d8817e4Smiod filename = file;
15753d8817e4Smiod return filename;
15763d8817e4Smiod }
15773d8817e4Smiod
15783d8817e4Smiod /* Write out an XCOFF armap. */
15793d8817e4Smiod
15803d8817e4Smiod static bfd_boolean
xcoff_write_armap_old(abfd,elength,map,orl_count,stridx)15813d8817e4Smiod xcoff_write_armap_old (abfd, elength, map, orl_count, stridx)
15823d8817e4Smiod bfd *abfd;
15833d8817e4Smiod unsigned int elength ATTRIBUTE_UNUSED;
15843d8817e4Smiod struct orl *map;
15853d8817e4Smiod unsigned int orl_count;
15863d8817e4Smiod int stridx;
15873d8817e4Smiod {
15883d8817e4Smiod struct xcoff_ar_hdr hdr;
15893d8817e4Smiod char *p;
15903d8817e4Smiod unsigned char buf[4];
15913d8817e4Smiod bfd *sub;
15923d8817e4Smiod file_ptr fileoff;
15933d8817e4Smiod unsigned int i;
15943d8817e4Smiod
15953d8817e4Smiod memset (&hdr, 0, sizeof hdr);
15963d8817e4Smiod sprintf (hdr.size, "%ld", (long) (4 + orl_count * 4 + stridx));
15973d8817e4Smiod sprintf (hdr.nextoff, "%d", 0);
15983d8817e4Smiod memcpy (hdr.prevoff, xcoff_ardata (abfd)->memoff, XCOFFARMAG_ELEMENT_SIZE);
15993d8817e4Smiod sprintf (hdr.date, "%d", 0);
16003d8817e4Smiod sprintf (hdr.uid, "%d", 0);
16013d8817e4Smiod sprintf (hdr.gid, "%d", 0);
16023d8817e4Smiod sprintf (hdr.mode, "%d", 0);
16033d8817e4Smiod sprintf (hdr.namlen, "%d", 0);
16043d8817e4Smiod
16053d8817e4Smiod /* We need spaces, not null bytes, in the header. */
16063d8817e4Smiod for (p = (char *) &hdr; p < (char *) &hdr + SIZEOF_AR_HDR; p++)
16073d8817e4Smiod if (*p == '\0')
16083d8817e4Smiod *p = ' ';
16093d8817e4Smiod
16103d8817e4Smiod if (bfd_bwrite ((PTR) &hdr, (bfd_size_type) SIZEOF_AR_HDR, abfd)
16113d8817e4Smiod != SIZEOF_AR_HDR
16123d8817e4Smiod || (bfd_bwrite (XCOFFARFMAG, (bfd_size_type) SXCOFFARFMAG, abfd)
16133d8817e4Smiod != SXCOFFARFMAG))
16143d8817e4Smiod return FALSE;
16153d8817e4Smiod
16163d8817e4Smiod H_PUT_32 (abfd, orl_count, buf);
16173d8817e4Smiod if (bfd_bwrite (buf, (bfd_size_type) 4, abfd) != 4)
16183d8817e4Smiod return FALSE;
16193d8817e4Smiod
16203d8817e4Smiod sub = abfd->archive_head;
16213d8817e4Smiod fileoff = SIZEOF_AR_FILE_HDR;
16223d8817e4Smiod i = 0;
16233d8817e4Smiod while (sub != NULL && i < orl_count)
16243d8817e4Smiod {
16253d8817e4Smiod size_t namlen;
16263d8817e4Smiod
16273d8817e4Smiod while (map[i].u.abfd == sub)
16283d8817e4Smiod {
16293d8817e4Smiod H_PUT_32 (abfd, fileoff, buf);
16303d8817e4Smiod if (bfd_bwrite (buf, (bfd_size_type) 4, abfd) != 4)
16313d8817e4Smiod return FALSE;
16323d8817e4Smiod ++i;
16333d8817e4Smiod }
16343d8817e4Smiod namlen = strlen (normalize_filename (sub));
16353d8817e4Smiod namlen = (namlen + 1) &~ (size_t) 1;
16363d8817e4Smiod fileoff += (SIZEOF_AR_HDR
16373d8817e4Smiod + namlen
16383d8817e4Smiod + SXCOFFARFMAG
16393d8817e4Smiod + arelt_size (sub));
16403d8817e4Smiod fileoff = (fileoff + 1) &~ 1;
16413d8817e4Smiod sub = sub->next;
16423d8817e4Smiod }
16433d8817e4Smiod
16443d8817e4Smiod for (i = 0; i < orl_count; i++)
16453d8817e4Smiod {
16463d8817e4Smiod const char *name;
16473d8817e4Smiod size_t namlen;
16483d8817e4Smiod
16493d8817e4Smiod name = *map[i].name;
16503d8817e4Smiod namlen = strlen (name);
16513d8817e4Smiod if (bfd_bwrite (name, (bfd_size_type) (namlen + 1), abfd) != namlen + 1)
16523d8817e4Smiod return FALSE;
16533d8817e4Smiod }
16543d8817e4Smiod
16553d8817e4Smiod if ((stridx & 1) != 0)
16563d8817e4Smiod {
16573d8817e4Smiod char b;
16583d8817e4Smiod
16593d8817e4Smiod b = '\0';
16603d8817e4Smiod if (bfd_bwrite (&b, (bfd_size_type) 1, abfd) != 1)
16613d8817e4Smiod return FALSE;
16623d8817e4Smiod }
16633d8817e4Smiod
16643d8817e4Smiod return TRUE;
16653d8817e4Smiod }
16663d8817e4Smiod
16673d8817e4Smiod static char buff20[XCOFFARMAGBIG_ELEMENT_SIZE + 1];
16683d8817e4Smiod #define FMT20 "%-20lld"
16693d8817e4Smiod #define FMT12 "%-12d"
1670*d04417c8Smiod #define FMT12_LL "%-12lld"
16713d8817e4Smiod #define FMT12_OCTAL "%-12o"
16723d8817e4Smiod #define FMT4 "%-4d"
16733d8817e4Smiod #define PRINT20(d, v) \
16743d8817e4Smiod sprintf (buff20, FMT20, (long long)(v)), \
16753d8817e4Smiod memcpy ((void *) (d), buff20, 20)
16763d8817e4Smiod
16773d8817e4Smiod #define PRINT12(d, v) \
16783d8817e4Smiod sprintf (buff20, FMT12, (int)(v)), \
16793d8817e4Smiod memcpy ((void *) (d), buff20, 12)
16803d8817e4Smiod
1681*d04417c8Smiod #define PRINT12_LL(d, v) \
1682*d04417c8Smiod sprintf (buff20, FMT12_LL, (long long)(v)), \
1683*d04417c8Smiod memcpy ((void *) (d), buff20, 12)
1684*d04417c8Smiod
16853d8817e4Smiod #define PRINT12_OCTAL(d, v) \
16863d8817e4Smiod sprintf (buff20, FMT12_OCTAL, (unsigned int)(v)), \
16873d8817e4Smiod memcpy ((void *) (d), buff20, 12)
16883d8817e4Smiod
16893d8817e4Smiod #define PRINT4(d, v) \
16903d8817e4Smiod sprintf (buff20, FMT4, (int)(v)), \
16913d8817e4Smiod memcpy ((void *) (d), buff20, 4)
16923d8817e4Smiod
16933d8817e4Smiod #define READ20(d, v) \
16943d8817e4Smiod buff20[20] = 0, \
16953d8817e4Smiod memcpy (buff20, (d), 20), \
16963d8817e4Smiod (v) = bfd_scan_vma (buff20, (const char **) NULL, 10)
16973d8817e4Smiod
16983d8817e4Smiod static bfd_boolean
do_pad(abfd,number)16993d8817e4Smiod do_pad (abfd, number)
17003d8817e4Smiod bfd *abfd;
17013d8817e4Smiod unsigned int number;
17023d8817e4Smiod {
17033d8817e4Smiod bfd_byte b = 0;
17043d8817e4Smiod
17053d8817e4Smiod /* Limit pad to <= 4096. */
17063d8817e4Smiod if (number > 4096)
17073d8817e4Smiod return FALSE;
17083d8817e4Smiod
17093d8817e4Smiod while (number--)
17103d8817e4Smiod if (bfd_bwrite (&b, (bfd_size_type) 1, abfd) != 1)
17113d8817e4Smiod return FALSE;
17123d8817e4Smiod
17133d8817e4Smiod return TRUE;
17143d8817e4Smiod }
17153d8817e4Smiod
17163d8817e4Smiod static bfd_boolean
do_copy(out_bfd,in_bfd)17173d8817e4Smiod do_copy (out_bfd, in_bfd)
17183d8817e4Smiod bfd *out_bfd;
17193d8817e4Smiod bfd *in_bfd;
17203d8817e4Smiod {
17213d8817e4Smiod bfd_size_type remaining;
17223d8817e4Smiod bfd_byte buffer[DEFAULT_BUFFERSIZE];
17233d8817e4Smiod
17243d8817e4Smiod if (bfd_seek (in_bfd, (file_ptr) 0, SEEK_SET) != 0)
17253d8817e4Smiod return FALSE;
17263d8817e4Smiod
17273d8817e4Smiod remaining = arelt_size (in_bfd);
17283d8817e4Smiod
17293d8817e4Smiod while (remaining >= DEFAULT_BUFFERSIZE)
17303d8817e4Smiod {
17313d8817e4Smiod if (bfd_bread (buffer, DEFAULT_BUFFERSIZE, in_bfd) != DEFAULT_BUFFERSIZE
17323d8817e4Smiod || bfd_bwrite (buffer, DEFAULT_BUFFERSIZE, out_bfd) != DEFAULT_BUFFERSIZE)
17333d8817e4Smiod return FALSE;
17343d8817e4Smiod
17353d8817e4Smiod remaining -= DEFAULT_BUFFERSIZE;
17363d8817e4Smiod }
17373d8817e4Smiod
17383d8817e4Smiod if (remaining)
17393d8817e4Smiod {
17403d8817e4Smiod if (bfd_bread (buffer, remaining, in_bfd) != remaining
17413d8817e4Smiod || bfd_bwrite (buffer, remaining, out_bfd) != remaining)
17423d8817e4Smiod return FALSE;
17433d8817e4Smiod }
17443d8817e4Smiod
17453d8817e4Smiod return TRUE;
17463d8817e4Smiod }
17473d8817e4Smiod
17483d8817e4Smiod static bfd_boolean
do_shared_object_padding(out_bfd,in_bfd,offset,ar_header_size)17493d8817e4Smiod do_shared_object_padding (out_bfd, in_bfd, offset, ar_header_size)
17503d8817e4Smiod bfd *out_bfd;
17513d8817e4Smiod bfd *in_bfd;
17523d8817e4Smiod file_ptr *offset;
17533d8817e4Smiod int ar_header_size;
17543d8817e4Smiod {
17553d8817e4Smiod if (bfd_check_format (in_bfd, bfd_object)
17563d8817e4Smiod && bfd_get_flavour (in_bfd) == bfd_target_xcoff_flavour
17573d8817e4Smiod && (in_bfd->flags & DYNAMIC) != 0)
17583d8817e4Smiod {
17593d8817e4Smiod bfd_size_type pad = 0;
17603d8817e4Smiod int text_align_power;
17613d8817e4Smiod
17623d8817e4Smiod text_align_power = bfd_xcoff_text_align_power (in_bfd);
17633d8817e4Smiod
17643d8817e4Smiod pad = 1 << text_align_power;
17653d8817e4Smiod pad -= (*offset + ar_header_size) & (pad - 1);
17663d8817e4Smiod
17673d8817e4Smiod if (! do_pad (out_bfd, pad))
17683d8817e4Smiod return FALSE;
17693d8817e4Smiod
17703d8817e4Smiod *offset += pad;
17713d8817e4Smiod }
17723d8817e4Smiod
17733d8817e4Smiod return TRUE;
17743d8817e4Smiod }
17753d8817e4Smiod
17763d8817e4Smiod static bfd_boolean
xcoff_write_armap_big(abfd,elength,map,orl_count,stridx)17773d8817e4Smiod xcoff_write_armap_big (abfd, elength, map, orl_count, stridx)
17783d8817e4Smiod bfd *abfd;
17793d8817e4Smiod unsigned int elength ATTRIBUTE_UNUSED;
17803d8817e4Smiod struct orl *map;
17813d8817e4Smiod unsigned int orl_count;
17823d8817e4Smiod int stridx;
17833d8817e4Smiod {
17843d8817e4Smiod struct xcoff_ar_file_hdr_big *fhdr;
17853d8817e4Smiod bfd_vma i, sym_32, sym_64, str_32, str_64;
17863d8817e4Smiod const bfd_arch_info_type *arch_info = NULL;
17873d8817e4Smiod bfd *current_bfd;
17883d8817e4Smiod size_t string_length;
17893d8817e4Smiod file_ptr nextoff, prevoff;
17903d8817e4Smiod
17913d8817e4Smiod /* First, we look through the symbols and work out which are
17923d8817e4Smiod from 32-bit objects and which from 64-bit ones. */
17933d8817e4Smiod sym_32 = sym_64 = str_32 = str_64 = 0;
17943d8817e4Smiod
17953d8817e4Smiod current_bfd = abfd->archive_head;
17963d8817e4Smiod if (current_bfd != NULL)
17973d8817e4Smiod arch_info = bfd_get_arch_info (current_bfd);
17983d8817e4Smiod i = 0;
17993d8817e4Smiod while (current_bfd != NULL && i < orl_count)
18003d8817e4Smiod {
18013d8817e4Smiod while (map[i].u.abfd == current_bfd)
18023d8817e4Smiod {
18033d8817e4Smiod string_length = strlen (*map[i].name) + 1;
18043d8817e4Smiod
18053d8817e4Smiod if (arch_info->bits_per_address == 64)
18063d8817e4Smiod {
18073d8817e4Smiod sym_64++;
18083d8817e4Smiod str_64 += string_length;
18093d8817e4Smiod }
18103d8817e4Smiod else
18113d8817e4Smiod {
18123d8817e4Smiod sym_32++;
18133d8817e4Smiod str_32 += string_length;
18143d8817e4Smiod }
18153d8817e4Smiod i++;
18163d8817e4Smiod }
18173d8817e4Smiod current_bfd = current_bfd->next;
18183d8817e4Smiod if (current_bfd != NULL)
18193d8817e4Smiod arch_info = bfd_get_arch_info (current_bfd);
18203d8817e4Smiod }
18213d8817e4Smiod
18223d8817e4Smiod /* A quick sanity check... */
18233d8817e4Smiod BFD_ASSERT (sym_64 + sym_32 == orl_count);
18243d8817e4Smiod /* Explicit cast to int for compiler. */
18253d8817e4Smiod BFD_ASSERT ((int)(str_64 + str_32) == stridx);
18263d8817e4Smiod
18273d8817e4Smiod fhdr = xcoff_ardata_big (abfd);
18283d8817e4Smiod
18293d8817e4Smiod /* xcoff_write_archive_contents_big passes nextoff in symoff. */
18303d8817e4Smiod READ20 (fhdr->memoff, prevoff);
18313d8817e4Smiod READ20 (fhdr->symoff, nextoff);
18323d8817e4Smiod
18333d8817e4Smiod BFD_ASSERT (nextoff == bfd_tell (abfd));
18343d8817e4Smiod
18353d8817e4Smiod /* Write out the symbol table.
18363d8817e4Smiod Layout :
18373d8817e4Smiod
18383d8817e4Smiod standard big archive header
18393d8817e4Smiod 0x0000 ar_size [0x14]
18403d8817e4Smiod 0x0014 ar_nxtmem [0x14]
18413d8817e4Smiod 0x0028 ar_prvmem [0x14]
18423d8817e4Smiod 0x003C ar_date [0x0C]
18433d8817e4Smiod 0x0048 ar_uid [0x0C]
18443d8817e4Smiod 0x0054 ar_gid [0x0C]
18453d8817e4Smiod 0x0060 ar_mod [0x0C]
18463d8817e4Smiod 0x006C ar_namelen[0x04]
18473d8817e4Smiod 0x0070 ar_fmag [SXCOFFARFMAG]
18483d8817e4Smiod
18493d8817e4Smiod Symbol table
18503d8817e4Smiod 0x0072 num_syms [0x08], binary
18513d8817e4Smiod 0x0078 offsets [0x08 * num_syms], binary
18523d8817e4Smiod 0x0086 + 0x08 * num_syms names [??]
18533d8817e4Smiod ?? pad to even bytes.
18543d8817e4Smiod */
18553d8817e4Smiod
18563d8817e4Smiod if (sym_32)
18573d8817e4Smiod {
18583d8817e4Smiod struct xcoff_ar_hdr_big *hdr;
18593d8817e4Smiod char *symbol_table;
18603d8817e4Smiod char *st;
18613d8817e4Smiod file_ptr fileoff;
18623d8817e4Smiod
18633d8817e4Smiod bfd_vma symbol_table_size =
18643d8817e4Smiod SIZEOF_AR_HDR_BIG
18653d8817e4Smiod + SXCOFFARFMAG
18663d8817e4Smiod + 8
18673d8817e4Smiod + 8 * sym_32
18683d8817e4Smiod + str_32 + (str_32 & 1);
18693d8817e4Smiod
18703d8817e4Smiod symbol_table = bfd_zmalloc (symbol_table_size);
18713d8817e4Smiod if (symbol_table == NULL)
18723d8817e4Smiod return FALSE;
18733d8817e4Smiod
18743d8817e4Smiod hdr = (struct xcoff_ar_hdr_big *) symbol_table;
18753d8817e4Smiod
18763d8817e4Smiod PRINT20 (hdr->size, 8 + 8 * sym_32 + str_32 + (str_32 & 1));
18773d8817e4Smiod
18783d8817e4Smiod if (sym_64)
18793d8817e4Smiod PRINT20 (hdr->nextoff, nextoff + symbol_table_size);
18803d8817e4Smiod else
18813d8817e4Smiod PRINT20 (hdr->nextoff, 0);
18823d8817e4Smiod
18833d8817e4Smiod PRINT20 (hdr->prevoff, prevoff);
18843d8817e4Smiod PRINT12 (hdr->date, 0);
18853d8817e4Smiod PRINT12 (hdr->uid, 0);
18863d8817e4Smiod PRINT12 (hdr->gid, 0);
18873d8817e4Smiod PRINT12 (hdr->mode, 0);
18883d8817e4Smiod PRINT4 (hdr->namlen, 0) ;
18893d8817e4Smiod
18903d8817e4Smiod st = symbol_table + SIZEOF_AR_HDR_BIG;
18913d8817e4Smiod memcpy (st, XCOFFARFMAG, SXCOFFARFMAG);
18923d8817e4Smiod st += SXCOFFARFMAG;
18933d8817e4Smiod
18943d8817e4Smiod bfd_h_put_64 (abfd, sym_32, st);
18953d8817e4Smiod st += 8;
18963d8817e4Smiod
18973d8817e4Smiod /* loop over the 32 bit offsets */
18983d8817e4Smiod current_bfd = abfd->archive_head;
18993d8817e4Smiod if (current_bfd != NULL)
19003d8817e4Smiod arch_info = bfd_get_arch_info (current_bfd);
19013d8817e4Smiod fileoff = SIZEOF_AR_FILE_HDR_BIG;
19023d8817e4Smiod i = 0;
19033d8817e4Smiod while (current_bfd != NULL && i < orl_count)
19043d8817e4Smiod {
19053d8817e4Smiod while (map[i].u.abfd == current_bfd)
19063d8817e4Smiod {
19073d8817e4Smiod if (arch_info->bits_per_address == 32)
19083d8817e4Smiod {
19093d8817e4Smiod bfd_h_put_64 (abfd, fileoff, st);
19103d8817e4Smiod st += 8;
19113d8817e4Smiod }
19123d8817e4Smiod i++;
19133d8817e4Smiod }
19143d8817e4Smiod string_length = strlen (normalize_filename (current_bfd));
19153d8817e4Smiod string_length += string_length & 1;
19163d8817e4Smiod fileoff += (SIZEOF_AR_HDR_BIG
19173d8817e4Smiod + string_length
19183d8817e4Smiod + SXCOFFARFMAG
19193d8817e4Smiod + arelt_size (current_bfd));
19203d8817e4Smiod fileoff += fileoff & 1;
19213d8817e4Smiod current_bfd = current_bfd->next;
19223d8817e4Smiod if (current_bfd != NULL)
19233d8817e4Smiod arch_info = bfd_get_arch_info (current_bfd);
19243d8817e4Smiod }
19253d8817e4Smiod
19263d8817e4Smiod /* loop over the 32 bit symbol names */
19273d8817e4Smiod current_bfd = abfd->archive_head;
19283d8817e4Smiod if (current_bfd != NULL)
19293d8817e4Smiod arch_info = bfd_get_arch_info (current_bfd);
19303d8817e4Smiod i = 0;
19313d8817e4Smiod while (current_bfd != NULL && i < orl_count)
19323d8817e4Smiod {
19333d8817e4Smiod while (map[i].u.abfd == current_bfd)
19343d8817e4Smiod {
19353d8817e4Smiod if (arch_info->bits_per_address == 32)
19363d8817e4Smiod {
19373d8817e4Smiod string_length = sprintf (st, "%s", *map[i].name);
19383d8817e4Smiod st += string_length + 1;
19393d8817e4Smiod }
19403d8817e4Smiod i++;
19413d8817e4Smiod }
19423d8817e4Smiod current_bfd = current_bfd->next;
19433d8817e4Smiod if (current_bfd != NULL)
19443d8817e4Smiod arch_info = bfd_get_arch_info (current_bfd);
19453d8817e4Smiod }
19463d8817e4Smiod
19473d8817e4Smiod bfd_bwrite (symbol_table, symbol_table_size, abfd);
19483d8817e4Smiod
19493d8817e4Smiod free (symbol_table);
19503d8817e4Smiod
19513d8817e4Smiod prevoff = nextoff;
19523d8817e4Smiod nextoff = nextoff + symbol_table_size;
19533d8817e4Smiod }
19543d8817e4Smiod else
19553d8817e4Smiod PRINT20 (fhdr->symoff, 0);
19563d8817e4Smiod
19573d8817e4Smiod if (sym_64)
19583d8817e4Smiod {
19593d8817e4Smiod struct xcoff_ar_hdr_big *hdr;
19603d8817e4Smiod char *symbol_table;
19613d8817e4Smiod char *st;
19623d8817e4Smiod file_ptr fileoff;
19633d8817e4Smiod
19643d8817e4Smiod bfd_vma symbol_table_size =
19653d8817e4Smiod SIZEOF_AR_HDR_BIG
19663d8817e4Smiod + SXCOFFARFMAG
19673d8817e4Smiod + 8
19683d8817e4Smiod + 8 * sym_64
19693d8817e4Smiod + str_64 + (str_64 & 1);
19703d8817e4Smiod
19713d8817e4Smiod symbol_table = bfd_zmalloc (symbol_table_size);
19723d8817e4Smiod if (symbol_table == NULL)
19733d8817e4Smiod return FALSE;
19743d8817e4Smiod
19753d8817e4Smiod hdr = (struct xcoff_ar_hdr_big *) symbol_table;
19763d8817e4Smiod
19773d8817e4Smiod PRINT20 (hdr->size, 8 + 8 * sym_64 + str_64 + (str_64 & 1));
19783d8817e4Smiod PRINT20 (hdr->nextoff, 0);
19793d8817e4Smiod PRINT20 (hdr->prevoff, prevoff);
19803d8817e4Smiod PRINT12 (hdr->date, 0);
19813d8817e4Smiod PRINT12 (hdr->uid, 0);
19823d8817e4Smiod PRINT12 (hdr->gid, 0);
19833d8817e4Smiod PRINT12 (hdr->mode, 0);
19843d8817e4Smiod PRINT4 (hdr->namlen, 0);
19853d8817e4Smiod
19863d8817e4Smiod st = symbol_table + SIZEOF_AR_HDR_BIG;
19873d8817e4Smiod memcpy (st, XCOFFARFMAG, SXCOFFARFMAG);
19883d8817e4Smiod st += SXCOFFARFMAG;
19893d8817e4Smiod
19903d8817e4Smiod bfd_h_put_64 (abfd, sym_64, st);
19913d8817e4Smiod st += 8;
19923d8817e4Smiod
19933d8817e4Smiod /* loop over the 64 bit offsets */
19943d8817e4Smiod current_bfd = abfd->archive_head;
19953d8817e4Smiod if (current_bfd != NULL)
19963d8817e4Smiod arch_info = bfd_get_arch_info (current_bfd);
19973d8817e4Smiod fileoff = SIZEOF_AR_FILE_HDR_BIG;
19983d8817e4Smiod i = 0;
19993d8817e4Smiod while (current_bfd != NULL && i < orl_count)
20003d8817e4Smiod {
20013d8817e4Smiod while (map[i].u.abfd == current_bfd)
20023d8817e4Smiod {
20033d8817e4Smiod if (arch_info->bits_per_address == 64)
20043d8817e4Smiod {
20053d8817e4Smiod bfd_h_put_64 (abfd, fileoff, st);
20063d8817e4Smiod st += 8;
20073d8817e4Smiod }
20083d8817e4Smiod i++;
20093d8817e4Smiod }
20103d8817e4Smiod string_length = strlen (normalize_filename (current_bfd));
20113d8817e4Smiod string_length += string_length & 1;
20123d8817e4Smiod fileoff += (SIZEOF_AR_HDR_BIG
20133d8817e4Smiod + string_length
20143d8817e4Smiod + SXCOFFARFMAG
20153d8817e4Smiod + arelt_size (current_bfd));
20163d8817e4Smiod fileoff += fileoff & 1;
20173d8817e4Smiod current_bfd = current_bfd->next;
20183d8817e4Smiod if (current_bfd != NULL)
20193d8817e4Smiod arch_info = bfd_get_arch_info (current_bfd);
20203d8817e4Smiod }
20213d8817e4Smiod
20223d8817e4Smiod /* loop over the 64 bit symbol names */
20233d8817e4Smiod current_bfd = abfd->archive_head;
20243d8817e4Smiod if (current_bfd != NULL)
20253d8817e4Smiod arch_info = bfd_get_arch_info (current_bfd);
20263d8817e4Smiod i = 0;
20273d8817e4Smiod while (current_bfd != NULL && i < orl_count)
20283d8817e4Smiod {
20293d8817e4Smiod while (map[i].u.abfd == current_bfd)
20303d8817e4Smiod {
20313d8817e4Smiod if (arch_info->bits_per_address == 64)
20323d8817e4Smiod {
20333d8817e4Smiod string_length = sprintf (st, "%s", *map[i].name);
20343d8817e4Smiod st += string_length + 1;
20353d8817e4Smiod }
20363d8817e4Smiod i++;
20373d8817e4Smiod }
20383d8817e4Smiod current_bfd = current_bfd->next;
20393d8817e4Smiod if (current_bfd != NULL)
20403d8817e4Smiod arch_info = bfd_get_arch_info (current_bfd);
20413d8817e4Smiod }
20423d8817e4Smiod
20433d8817e4Smiod bfd_bwrite (symbol_table, symbol_table_size, abfd);
20443d8817e4Smiod
20453d8817e4Smiod free (symbol_table);
20463d8817e4Smiod
20473d8817e4Smiod PRINT20 (fhdr->symoff64, nextoff);
20483d8817e4Smiod }
20493d8817e4Smiod else
20503d8817e4Smiod PRINT20 (fhdr->symoff64, 0);
20513d8817e4Smiod
20523d8817e4Smiod return TRUE;
20533d8817e4Smiod }
20543d8817e4Smiod
20553d8817e4Smiod bfd_boolean
_bfd_xcoff_write_armap(abfd,elength,map,orl_count,stridx)20563d8817e4Smiod _bfd_xcoff_write_armap (abfd, elength, map, orl_count, stridx)
20573d8817e4Smiod bfd *abfd;
20583d8817e4Smiod unsigned int elength ATTRIBUTE_UNUSED;
20593d8817e4Smiod struct orl *map;
20603d8817e4Smiod unsigned int orl_count;
20613d8817e4Smiod int stridx;
20623d8817e4Smiod {
20633d8817e4Smiod if (! xcoff_big_format_p (abfd))
20643d8817e4Smiod return xcoff_write_armap_old (abfd, elength, map, orl_count, stridx);
20653d8817e4Smiod else
20663d8817e4Smiod return xcoff_write_armap_big (abfd, elength, map, orl_count, stridx);
20673d8817e4Smiod }
20683d8817e4Smiod
20693d8817e4Smiod /* Write out an XCOFF archive. We always write an entire archive,
20703d8817e4Smiod rather than fussing with the freelist and so forth. */
20713d8817e4Smiod
20723d8817e4Smiod static bfd_boolean
xcoff_write_archive_contents_old(abfd)20733d8817e4Smiod xcoff_write_archive_contents_old (abfd)
20743d8817e4Smiod bfd *abfd;
20753d8817e4Smiod {
20763d8817e4Smiod struct xcoff_ar_file_hdr fhdr;
20773d8817e4Smiod bfd_size_type count;
20783d8817e4Smiod bfd_size_type total_namlen;
20793d8817e4Smiod file_ptr *offsets;
20803d8817e4Smiod bfd_boolean makemap;
20813d8817e4Smiod bfd_boolean hasobjects;
20823d8817e4Smiod file_ptr prevoff, nextoff;
20833d8817e4Smiod bfd *sub;
20843d8817e4Smiod size_t i;
20853d8817e4Smiod struct xcoff_ar_hdr ahdr;
20863d8817e4Smiod bfd_size_type size;
20873d8817e4Smiod char *p;
20883d8817e4Smiod char decbuf[XCOFFARMAG_ELEMENT_SIZE + 1];
20893d8817e4Smiod
20903d8817e4Smiod memset (&fhdr, 0, sizeof fhdr);
20913d8817e4Smiod (void) strncpy (fhdr.magic, XCOFFARMAG, SXCOFFARMAG);
20923d8817e4Smiod sprintf (fhdr.firstmemoff, "%d", SIZEOF_AR_FILE_HDR);
20933d8817e4Smiod sprintf (fhdr.freeoff, "%d", 0);
20943d8817e4Smiod
20953d8817e4Smiod count = 0;
20963d8817e4Smiod total_namlen = 0;
20973d8817e4Smiod for (sub = abfd->archive_head; sub != NULL; sub = sub->next)
20983d8817e4Smiod {
20993d8817e4Smiod ++count;
21003d8817e4Smiod total_namlen += strlen (normalize_filename (sub)) + 1;
21013d8817e4Smiod }
21023d8817e4Smiod offsets = (file_ptr *) bfd_alloc (abfd, count * sizeof (file_ptr));
21033d8817e4Smiod if (offsets == NULL)
21043d8817e4Smiod return FALSE;
21053d8817e4Smiod
21063d8817e4Smiod if (bfd_seek (abfd, (file_ptr) SIZEOF_AR_FILE_HDR, SEEK_SET) != 0)
21073d8817e4Smiod return FALSE;
21083d8817e4Smiod
21093d8817e4Smiod makemap = bfd_has_map (abfd);
21103d8817e4Smiod hasobjects = FALSE;
21113d8817e4Smiod prevoff = 0;
21123d8817e4Smiod nextoff = SIZEOF_AR_FILE_HDR;
21133d8817e4Smiod for (sub = abfd->archive_head, i = 0; sub != NULL; sub = sub->next, i++)
21143d8817e4Smiod {
21153d8817e4Smiod const char *name;
21163d8817e4Smiod bfd_size_type namlen;
21173d8817e4Smiod struct xcoff_ar_hdr *ahdrp;
21183d8817e4Smiod bfd_size_type remaining;
21193d8817e4Smiod
21203d8817e4Smiod if (makemap && ! hasobjects)
21213d8817e4Smiod {
21223d8817e4Smiod if (bfd_check_format (sub, bfd_object))
21233d8817e4Smiod hasobjects = TRUE;
21243d8817e4Smiod }
21253d8817e4Smiod
21263d8817e4Smiod name = normalize_filename (sub);
21273d8817e4Smiod namlen = strlen (name);
21283d8817e4Smiod
21293d8817e4Smiod if (sub->arelt_data != NULL)
21303d8817e4Smiod ahdrp = arch_xhdr (sub);
21313d8817e4Smiod else
21323d8817e4Smiod ahdrp = NULL;
21333d8817e4Smiod
21343d8817e4Smiod if (ahdrp == NULL)
21353d8817e4Smiod {
21363d8817e4Smiod struct stat s;
21373d8817e4Smiod
21383d8817e4Smiod memset (&ahdr, 0, sizeof ahdr);
21393d8817e4Smiod ahdrp = &ahdr;
21403d8817e4Smiod if (stat (bfd_get_filename (sub), &s) != 0)
21413d8817e4Smiod {
21423d8817e4Smiod bfd_set_error (bfd_error_system_call);
21433d8817e4Smiod return FALSE;
21443d8817e4Smiod }
21453d8817e4Smiod
21463d8817e4Smiod sprintf (ahdrp->size, "%ld", (long) s.st_size);
2147*d04417c8Smiod sprintf (ahdrp->date, "%lld", (long long) s.st_mtime);
21483d8817e4Smiod sprintf (ahdrp->uid, "%ld", (long) s.st_uid);
21493d8817e4Smiod sprintf (ahdrp->gid, "%ld", (long) s.st_gid);
21503d8817e4Smiod sprintf (ahdrp->mode, "%o", (unsigned int) s.st_mode);
21513d8817e4Smiod
21523d8817e4Smiod if (sub->arelt_data == NULL)
21533d8817e4Smiod {
21543d8817e4Smiod size = sizeof (struct areltdata);
21553d8817e4Smiod sub->arelt_data = bfd_alloc (sub, size);
21563d8817e4Smiod if (sub->arelt_data == NULL)
21573d8817e4Smiod return FALSE;
21583d8817e4Smiod }
21593d8817e4Smiod
21603d8817e4Smiod arch_eltdata (sub)->parsed_size = s.st_size;
21613d8817e4Smiod }
21623d8817e4Smiod
21633d8817e4Smiod sprintf (ahdrp->prevoff, "%ld", (long) prevoff);
21643d8817e4Smiod sprintf (ahdrp->namlen, "%ld", (long) namlen);
21653d8817e4Smiod
21663d8817e4Smiod /* If the length of the name is odd, we write out the null byte
21673d8817e4Smiod after the name as well. */
21683d8817e4Smiod namlen = (namlen + 1) &~ (bfd_size_type) 1;
21693d8817e4Smiod
21703d8817e4Smiod remaining = arelt_size (sub);
21713d8817e4Smiod size = (SIZEOF_AR_HDR
21723d8817e4Smiod + namlen
21733d8817e4Smiod + SXCOFFARFMAG
21743d8817e4Smiod + remaining);
21753d8817e4Smiod
21763d8817e4Smiod BFD_ASSERT (nextoff == bfd_tell (abfd));
21773d8817e4Smiod
21783d8817e4Smiod offsets[i] = nextoff;
21793d8817e4Smiod
21803d8817e4Smiod prevoff = nextoff;
21813d8817e4Smiod nextoff += size + (size & 1);
21823d8817e4Smiod
21833d8817e4Smiod sprintf (ahdrp->nextoff, "%ld", (long) nextoff);
21843d8817e4Smiod
21853d8817e4Smiod /* We need spaces, not null bytes, in the header. */
21863d8817e4Smiod for (p = (char *) ahdrp; p < (char *) ahdrp + SIZEOF_AR_HDR; p++)
21873d8817e4Smiod if (*p == '\0')
21883d8817e4Smiod *p = ' ';
21893d8817e4Smiod
21903d8817e4Smiod if ((bfd_bwrite ((PTR) ahdrp, (bfd_size_type) SIZEOF_AR_HDR, abfd)
21913d8817e4Smiod != SIZEOF_AR_HDR)
21923d8817e4Smiod || bfd_bwrite ((PTR) name, namlen, abfd) != namlen
21933d8817e4Smiod || bfd_bwrite ((PTR) XCOFFARFMAG, (bfd_size_type) SXCOFFARFMAG,
21943d8817e4Smiod abfd) != SXCOFFARFMAG)
21953d8817e4Smiod return FALSE;
21963d8817e4Smiod
21973d8817e4Smiod if (bfd_seek (sub, (file_ptr) 0, SEEK_SET) != 0)
21983d8817e4Smiod return FALSE;
21993d8817e4Smiod
22003d8817e4Smiod if (! do_copy (abfd, sub))
22013d8817e4Smiod return FALSE;
22023d8817e4Smiod
22033d8817e4Smiod if (! do_pad (abfd, size & 1))
22043d8817e4Smiod return FALSE;
22053d8817e4Smiod }
22063d8817e4Smiod
22073d8817e4Smiod sprintf (fhdr.lastmemoff, "%ld", (long) prevoff);
22083d8817e4Smiod
22093d8817e4Smiod /* Write out the member table. */
22103d8817e4Smiod
22113d8817e4Smiod BFD_ASSERT (nextoff == bfd_tell (abfd));
22123d8817e4Smiod sprintf (fhdr.memoff, "%ld", (long) nextoff);
22133d8817e4Smiod
22143d8817e4Smiod memset (&ahdr, 0, sizeof ahdr);
22153d8817e4Smiod sprintf (ahdr.size, "%ld", (long) (XCOFFARMAG_ELEMENT_SIZE
22163d8817e4Smiod + count * XCOFFARMAG_ELEMENT_SIZE
22173d8817e4Smiod + total_namlen));
22183d8817e4Smiod sprintf (ahdr.prevoff, "%ld", (long) prevoff);
22193d8817e4Smiod sprintf (ahdr.date, "%d", 0);
22203d8817e4Smiod sprintf (ahdr.uid, "%d", 0);
22213d8817e4Smiod sprintf (ahdr.gid, "%d", 0);
22223d8817e4Smiod sprintf (ahdr.mode, "%d", 0);
22233d8817e4Smiod sprintf (ahdr.namlen, "%d", 0);
22243d8817e4Smiod
22253d8817e4Smiod size = (SIZEOF_AR_HDR
22263d8817e4Smiod + XCOFFARMAG_ELEMENT_SIZE
22273d8817e4Smiod + count * XCOFFARMAG_ELEMENT_SIZE
22283d8817e4Smiod + total_namlen
22293d8817e4Smiod + SXCOFFARFMAG);
22303d8817e4Smiod
22313d8817e4Smiod prevoff = nextoff;
22323d8817e4Smiod nextoff += size + (size & 1);
22333d8817e4Smiod
22343d8817e4Smiod if (makemap && hasobjects)
22353d8817e4Smiod sprintf (ahdr.nextoff, "%ld", (long) nextoff);
22363d8817e4Smiod else
22373d8817e4Smiod sprintf (ahdr.nextoff, "%d", 0);
22383d8817e4Smiod
22393d8817e4Smiod /* We need spaces, not null bytes, in the header. */
22403d8817e4Smiod for (p = (char *) &ahdr; p < (char *) &ahdr + SIZEOF_AR_HDR; p++)
22413d8817e4Smiod if (*p == '\0')
22423d8817e4Smiod *p = ' ';
22433d8817e4Smiod
22443d8817e4Smiod if ((bfd_bwrite ((PTR) &ahdr, (bfd_size_type) SIZEOF_AR_HDR, abfd)
22453d8817e4Smiod != SIZEOF_AR_HDR)
22463d8817e4Smiod || (bfd_bwrite ((PTR) XCOFFARFMAG, (bfd_size_type) SXCOFFARFMAG, abfd)
22473d8817e4Smiod != SXCOFFARFMAG))
22483d8817e4Smiod return FALSE;
22493d8817e4Smiod
22503d8817e4Smiod sprintf (decbuf, "%-12ld", (long) count);
22513d8817e4Smiod if (bfd_bwrite ((PTR) decbuf, (bfd_size_type) XCOFFARMAG_ELEMENT_SIZE, abfd)
22523d8817e4Smiod != XCOFFARMAG_ELEMENT_SIZE)
22533d8817e4Smiod return FALSE;
22543d8817e4Smiod for (i = 0; i < (size_t) count; i++)
22553d8817e4Smiod {
22563d8817e4Smiod sprintf (decbuf, "%-12ld", (long) offsets[i]);
22573d8817e4Smiod if (bfd_bwrite ((PTR) decbuf, (bfd_size_type) XCOFFARMAG_ELEMENT_SIZE,
22583d8817e4Smiod abfd) != XCOFFARMAG_ELEMENT_SIZE)
22593d8817e4Smiod return FALSE;
22603d8817e4Smiod }
22613d8817e4Smiod for (sub = abfd->archive_head; sub != NULL; sub = sub->next)
22623d8817e4Smiod {
22633d8817e4Smiod const char *name;
22643d8817e4Smiod bfd_size_type namlen;
22653d8817e4Smiod
22663d8817e4Smiod name = normalize_filename (sub);
22673d8817e4Smiod namlen = strlen (name);
22683d8817e4Smiod if (bfd_bwrite ((PTR) name, namlen + 1, abfd) != namlen + 1)
22693d8817e4Smiod return FALSE;
22703d8817e4Smiod }
22713d8817e4Smiod
22723d8817e4Smiod if (! do_pad (abfd, size & 1))
22733d8817e4Smiod return FALSE;
22743d8817e4Smiod
22753d8817e4Smiod /* Write out the armap, if appropriate. */
22763d8817e4Smiod if (! makemap || ! hasobjects)
22773d8817e4Smiod sprintf (fhdr.symoff, "%d", 0);
22783d8817e4Smiod else
22793d8817e4Smiod {
22803d8817e4Smiod BFD_ASSERT (nextoff == bfd_tell (abfd));
22813d8817e4Smiod sprintf (fhdr.symoff, "%ld", (long) nextoff);
22823d8817e4Smiod bfd_ardata (abfd)->tdata = (PTR) &fhdr;
22833d8817e4Smiod if (! _bfd_compute_and_write_armap (abfd, 0))
22843d8817e4Smiod return FALSE;
22853d8817e4Smiod }
22863d8817e4Smiod
22873d8817e4Smiod /* Write out the archive file header. */
22883d8817e4Smiod
22893d8817e4Smiod /* We need spaces, not null bytes, in the header. */
22903d8817e4Smiod for (p = (char *) &fhdr; p < (char *) &fhdr + SIZEOF_AR_FILE_HDR; p++)
22913d8817e4Smiod if (*p == '\0')
22923d8817e4Smiod *p = ' ';
22933d8817e4Smiod
22943d8817e4Smiod if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0
22953d8817e4Smiod || (bfd_bwrite ((PTR) &fhdr, (bfd_size_type) SIZEOF_AR_FILE_HDR, abfd)
22963d8817e4Smiod != SIZEOF_AR_FILE_HDR))
22973d8817e4Smiod return FALSE;
22983d8817e4Smiod
22993d8817e4Smiod return TRUE;
23003d8817e4Smiod }
23013d8817e4Smiod
23023d8817e4Smiod static bfd_boolean
xcoff_write_archive_contents_big(abfd)23033d8817e4Smiod xcoff_write_archive_contents_big (abfd)
23043d8817e4Smiod bfd *abfd;
23053d8817e4Smiod {
23063d8817e4Smiod struct xcoff_ar_file_hdr_big fhdr;
23073d8817e4Smiod bfd_size_type count;
23083d8817e4Smiod bfd_size_type total_namlen;
23093d8817e4Smiod file_ptr *offsets;
23103d8817e4Smiod bfd_boolean makemap;
23113d8817e4Smiod bfd_boolean hasobjects;
23123d8817e4Smiod file_ptr prevoff, nextoff;
23133d8817e4Smiod bfd *current_bfd;
23143d8817e4Smiod size_t i;
23153d8817e4Smiod struct xcoff_ar_hdr_big *hdr, ahdr;
23163d8817e4Smiod bfd_size_type size;
23173d8817e4Smiod char *member_table, *mt;
23183d8817e4Smiod bfd_vma member_table_size;
23193d8817e4Smiod
23203d8817e4Smiod memset (&fhdr, 0, SIZEOF_AR_FILE_HDR_BIG);
23213d8817e4Smiod memcpy (fhdr.magic, XCOFFARMAGBIG, SXCOFFARMAG);
23223d8817e4Smiod
23233d8817e4Smiod if (bfd_seek (abfd, (file_ptr) SIZEOF_AR_FILE_HDR_BIG, SEEK_SET) != 0)
23243d8817e4Smiod return FALSE;
23253d8817e4Smiod
23263d8817e4Smiod /* Calculate count and total_namlen. */
23273d8817e4Smiod makemap = bfd_has_map (abfd);
23283d8817e4Smiod hasobjects = FALSE;
23293d8817e4Smiod for (current_bfd = abfd->archive_head, count = 0, total_namlen = 0;
23303d8817e4Smiod current_bfd != NULL;
23313d8817e4Smiod current_bfd = current_bfd->next, count++)
23323d8817e4Smiod {
23333d8817e4Smiod total_namlen += strlen (normalize_filename (current_bfd)) + 1;
23343d8817e4Smiod
23353d8817e4Smiod if (makemap
23363d8817e4Smiod && ! hasobjects
23373d8817e4Smiod && bfd_check_format (current_bfd, bfd_object))
23383d8817e4Smiod hasobjects = TRUE;
23393d8817e4Smiod }
23403d8817e4Smiod
23413d8817e4Smiod offsets = NULL;
23423d8817e4Smiod if (count)
23433d8817e4Smiod {
23443d8817e4Smiod offsets = (file_ptr *) bfd_malloc (count * sizeof (file_ptr));
23453d8817e4Smiod if (offsets == NULL)
23463d8817e4Smiod return FALSE;
23473d8817e4Smiod }
23483d8817e4Smiod
23493d8817e4Smiod prevoff = 0;
23503d8817e4Smiod nextoff = SIZEOF_AR_FILE_HDR_BIG;
23513d8817e4Smiod for (current_bfd = abfd->archive_head, i = 0;
23523d8817e4Smiod current_bfd != NULL;
23533d8817e4Smiod current_bfd = current_bfd->next, i++)
23543d8817e4Smiod {
23553d8817e4Smiod const char *name;
23563d8817e4Smiod bfd_size_type namlen;
23573d8817e4Smiod struct xcoff_ar_hdr_big *ahdrp;
23583d8817e4Smiod bfd_size_type remaining;
23593d8817e4Smiod
23603d8817e4Smiod name = normalize_filename (current_bfd);
23613d8817e4Smiod namlen = strlen (name);
23623d8817e4Smiod
23633d8817e4Smiod if (current_bfd->arelt_data != NULL)
23643d8817e4Smiod ahdrp = arch_xhdr_big (current_bfd);
23653d8817e4Smiod else
23663d8817e4Smiod ahdrp = NULL;
23673d8817e4Smiod
23683d8817e4Smiod if (ahdrp == NULL)
23693d8817e4Smiod {
23703d8817e4Smiod struct stat s;
23713d8817e4Smiod
23723d8817e4Smiod ahdrp = &ahdr;
23733d8817e4Smiod /* XXX This should actually be a call to stat64 (at least on
23743d8817e4Smiod 32-bit machines).
23753d8817e4Smiod XXX This call will fail if the original object is not found. */
23763d8817e4Smiod if (stat (bfd_get_filename (current_bfd), &s) != 0)
23773d8817e4Smiod {
23783d8817e4Smiod bfd_set_error (bfd_error_system_call);
23793d8817e4Smiod return FALSE;
23803d8817e4Smiod }
23813d8817e4Smiod
23823d8817e4Smiod PRINT20 (ahdrp->size, s.st_size);
2383*d04417c8Smiod PRINT12_LL (ahdrp->date, s.st_mtime);
23843d8817e4Smiod PRINT12 (ahdrp->uid, s.st_uid);
23853d8817e4Smiod PRINT12 (ahdrp->gid, s.st_gid);
23863d8817e4Smiod PRINT12_OCTAL (ahdrp->mode, s.st_mode);
23873d8817e4Smiod
23883d8817e4Smiod if (current_bfd->arelt_data == NULL)
23893d8817e4Smiod {
23903d8817e4Smiod size = sizeof (struct areltdata);
23913d8817e4Smiod current_bfd->arelt_data = bfd_alloc (current_bfd, size);
23923d8817e4Smiod if (current_bfd->arelt_data == NULL)
23933d8817e4Smiod return FALSE;
23943d8817e4Smiod }
23953d8817e4Smiod
23963d8817e4Smiod arch_eltdata (current_bfd)->parsed_size = s.st_size;
23973d8817e4Smiod }
23983d8817e4Smiod
23993d8817e4Smiod PRINT20 (ahdrp->prevoff, prevoff);
24003d8817e4Smiod PRINT4 (ahdrp->namlen, namlen);
24013d8817e4Smiod
24023d8817e4Smiod /* If the length of the name is odd, we write out the null byte
24033d8817e4Smiod after the name as well. */
24043d8817e4Smiod namlen = (namlen + 1) &~ (bfd_size_type) 1;
24053d8817e4Smiod
24063d8817e4Smiod remaining = arelt_size (current_bfd);
24073d8817e4Smiod size = (SIZEOF_AR_HDR_BIG
24083d8817e4Smiod + namlen
24093d8817e4Smiod + SXCOFFARFMAG
24103d8817e4Smiod + remaining);
24113d8817e4Smiod
24123d8817e4Smiod BFD_ASSERT (nextoff == bfd_tell (abfd));
24133d8817e4Smiod
24143d8817e4Smiod /* Check for xcoff shared objects.
24153d8817e4Smiod Their text section needs to be aligned wrt the archive file position.
24163d8817e4Smiod This requires extra padding before the archive header. */
24173d8817e4Smiod if (! do_shared_object_padding (abfd, current_bfd, & nextoff,
24183d8817e4Smiod SIZEOF_AR_HDR_BIG + namlen
24193d8817e4Smiod + SXCOFFARFMAG))
24203d8817e4Smiod return FALSE;
24213d8817e4Smiod
24223d8817e4Smiod offsets[i] = nextoff;
24233d8817e4Smiod
24243d8817e4Smiod prevoff = nextoff;
24253d8817e4Smiod nextoff += size + (size & 1);
24263d8817e4Smiod
24273d8817e4Smiod PRINT20 (ahdrp->nextoff, nextoff);
24283d8817e4Smiod
24293d8817e4Smiod if ((bfd_bwrite ((PTR) ahdrp, (bfd_size_type) SIZEOF_AR_HDR_BIG, abfd)
24303d8817e4Smiod != SIZEOF_AR_HDR_BIG)
24313d8817e4Smiod || bfd_bwrite ((PTR) name, (bfd_size_type) namlen, abfd) != namlen
24323d8817e4Smiod || (bfd_bwrite ((PTR) XCOFFARFMAG, (bfd_size_type) SXCOFFARFMAG,
24333d8817e4Smiod abfd) != SXCOFFARFMAG))
24343d8817e4Smiod return FALSE;
24353d8817e4Smiod
24363d8817e4Smiod if (bfd_seek (current_bfd, (file_ptr) 0, SEEK_SET) != 0)
24373d8817e4Smiod return FALSE;
24383d8817e4Smiod
24393d8817e4Smiod if (! do_copy (abfd, current_bfd))
24403d8817e4Smiod return FALSE;
24413d8817e4Smiod
24423d8817e4Smiod if (! do_pad (abfd, size & 1))
24433d8817e4Smiod return FALSE;
24443d8817e4Smiod }
24453d8817e4Smiod
24463d8817e4Smiod if (count)
24473d8817e4Smiod {
24483d8817e4Smiod PRINT20 (fhdr.firstmemoff, offsets[0]);
24493d8817e4Smiod PRINT20 (fhdr.lastmemoff, prevoff);
24503d8817e4Smiod }
24513d8817e4Smiod
24523d8817e4Smiod /* Write out the member table.
24533d8817e4Smiod Layout :
24543d8817e4Smiod
24553d8817e4Smiod standard big archive header
24563d8817e4Smiod 0x0000 ar_size [0x14]
24573d8817e4Smiod 0x0014 ar_nxtmem [0x14]
24583d8817e4Smiod 0x0028 ar_prvmem [0x14]
24593d8817e4Smiod 0x003C ar_date [0x0C]
24603d8817e4Smiod 0x0048 ar_uid [0x0C]
24613d8817e4Smiod 0x0054 ar_gid [0x0C]
24623d8817e4Smiod 0x0060 ar_mod [0x0C]
24633d8817e4Smiod 0x006C ar_namelen[0x04]
24643d8817e4Smiod 0x0070 ar_fmag [0x02]
24653d8817e4Smiod
24663d8817e4Smiod Member table
24673d8817e4Smiod 0x0072 count [0x14]
24683d8817e4Smiod 0x0086 offsets [0x14 * counts]
24693d8817e4Smiod 0x0086 + 0x14 * counts names [??]
24703d8817e4Smiod ?? pad to even bytes.
24713d8817e4Smiod */
24723d8817e4Smiod
24733d8817e4Smiod BFD_ASSERT (nextoff == bfd_tell (abfd));
24743d8817e4Smiod
24753d8817e4Smiod member_table_size = (SIZEOF_AR_HDR_BIG
24763d8817e4Smiod + SXCOFFARFMAG
24773d8817e4Smiod + XCOFFARMAGBIG_ELEMENT_SIZE
24783d8817e4Smiod + count * XCOFFARMAGBIG_ELEMENT_SIZE
24793d8817e4Smiod + total_namlen);
24803d8817e4Smiod
24813d8817e4Smiod member_table_size += member_table_size & 1;
24823d8817e4Smiod member_table = bfd_zmalloc (member_table_size);
24833d8817e4Smiod if (member_table == NULL)
24843d8817e4Smiod return FALSE;
24853d8817e4Smiod
24863d8817e4Smiod hdr = (struct xcoff_ar_hdr_big *) member_table;
24873d8817e4Smiod
24883d8817e4Smiod PRINT20 (hdr->size, (XCOFFARMAGBIG_ELEMENT_SIZE
24893d8817e4Smiod + count * XCOFFARMAGBIG_ELEMENT_SIZE
24903d8817e4Smiod + total_namlen + (total_namlen & 1)));
24913d8817e4Smiod if (makemap && hasobjects)
24923d8817e4Smiod PRINT20 (hdr->nextoff, nextoff + member_table_size);
24933d8817e4Smiod else
24943d8817e4Smiod PRINT20 (hdr->nextoff, 0);
24953d8817e4Smiod PRINT20 (hdr->prevoff, prevoff);
24963d8817e4Smiod PRINT12 (hdr->date, 0);
24973d8817e4Smiod PRINT12 (hdr->uid, 0);
24983d8817e4Smiod PRINT12 (hdr->gid, 0);
24993d8817e4Smiod PRINT12 (hdr->mode, 0);
25003d8817e4Smiod PRINT4 (hdr->namlen, 0);
25013d8817e4Smiod
25023d8817e4Smiod mt = member_table + SIZEOF_AR_HDR_BIG;
25033d8817e4Smiod memcpy (mt, XCOFFARFMAG, SXCOFFARFMAG);
25043d8817e4Smiod mt += SXCOFFARFMAG;
25053d8817e4Smiod
25063d8817e4Smiod PRINT20 (mt, count);
25073d8817e4Smiod mt += XCOFFARMAGBIG_ELEMENT_SIZE;
25083d8817e4Smiod for (i = 0; i < (size_t) count; i++)
25093d8817e4Smiod {
25103d8817e4Smiod PRINT20 (mt, offsets[i]);
25113d8817e4Smiod mt += XCOFFARMAGBIG_ELEMENT_SIZE;
25123d8817e4Smiod }
25133d8817e4Smiod
25143d8817e4Smiod if (count)
25153d8817e4Smiod {
25163d8817e4Smiod free (offsets);
25173d8817e4Smiod offsets = NULL;
25183d8817e4Smiod }
25193d8817e4Smiod
25203d8817e4Smiod for (current_bfd = abfd->archive_head; current_bfd != NULL;
25213d8817e4Smiod current_bfd = current_bfd->next)
25223d8817e4Smiod {
25233d8817e4Smiod const char *name;
25243d8817e4Smiod size_t namlen;
25253d8817e4Smiod
25263d8817e4Smiod name = normalize_filename (current_bfd);
25273d8817e4Smiod namlen = sprintf (mt, "%s", name);
25283d8817e4Smiod mt += namlen + 1;
25293d8817e4Smiod }
25303d8817e4Smiod
25313d8817e4Smiod if (bfd_bwrite (member_table, member_table_size, abfd) != member_table_size)
25323d8817e4Smiod return FALSE;
25333d8817e4Smiod
25343d8817e4Smiod free (member_table);
25353d8817e4Smiod
25363d8817e4Smiod PRINT20 (fhdr.memoff, nextoff);
25373d8817e4Smiod
25383d8817e4Smiod prevoff = nextoff;
25393d8817e4Smiod nextoff += member_table_size;
25403d8817e4Smiod
25413d8817e4Smiod /* Write out the armap, if appropriate. */
25423d8817e4Smiod
25433d8817e4Smiod if (! makemap || ! hasobjects)
25443d8817e4Smiod PRINT20 (fhdr.symoff, 0);
25453d8817e4Smiod else
25463d8817e4Smiod {
25473d8817e4Smiod BFD_ASSERT (nextoff == bfd_tell (abfd));
25483d8817e4Smiod
25493d8817e4Smiod /* Save nextoff in fhdr.symoff so the armap routine can use it. */
25503d8817e4Smiod PRINT20 (fhdr.symoff, nextoff);
25513d8817e4Smiod
25523d8817e4Smiod bfd_ardata (abfd)->tdata = (PTR) &fhdr;
25533d8817e4Smiod if (! _bfd_compute_and_write_armap (abfd, 0))
25543d8817e4Smiod return FALSE;
25553d8817e4Smiod }
25563d8817e4Smiod
25573d8817e4Smiod /* Write out the archive file header. */
25583d8817e4Smiod
25593d8817e4Smiod if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0
25603d8817e4Smiod || (bfd_bwrite ((PTR) &fhdr, (bfd_size_type) SIZEOF_AR_FILE_HDR_BIG,
25613d8817e4Smiod abfd) != SIZEOF_AR_FILE_HDR_BIG))
25623d8817e4Smiod return FALSE;
25633d8817e4Smiod
25643d8817e4Smiod return TRUE;
25653d8817e4Smiod }
25663d8817e4Smiod
25673d8817e4Smiod bfd_boolean
_bfd_xcoff_write_archive_contents(abfd)25683d8817e4Smiod _bfd_xcoff_write_archive_contents (abfd)
25693d8817e4Smiod bfd *abfd;
25703d8817e4Smiod {
25713d8817e4Smiod if (! xcoff_big_format_p (abfd))
25723d8817e4Smiod return xcoff_write_archive_contents_old (abfd);
25733d8817e4Smiod else
25743d8817e4Smiod return xcoff_write_archive_contents_big (abfd);
25753d8817e4Smiod }
25763d8817e4Smiod
25773d8817e4Smiod /* We can't use the usual coff_sizeof_headers routine, because AIX
25783d8817e4Smiod always uses an a.out header. */
25793d8817e4Smiod
25803d8817e4Smiod int
_bfd_xcoff_sizeof_headers(abfd,reloc)25813d8817e4Smiod _bfd_xcoff_sizeof_headers (abfd, reloc)
25823d8817e4Smiod bfd *abfd;
25833d8817e4Smiod bfd_boolean reloc ATTRIBUTE_UNUSED;
25843d8817e4Smiod {
25853d8817e4Smiod int size;
25863d8817e4Smiod
25873d8817e4Smiod size = FILHSZ;
25883d8817e4Smiod if (xcoff_data (abfd)->full_aouthdr)
25893d8817e4Smiod size += AOUTSZ;
25903d8817e4Smiod else
25913d8817e4Smiod size += SMALL_AOUTSZ;
25923d8817e4Smiod size += abfd->section_count * SCNHSZ;
25933d8817e4Smiod return size;
25943d8817e4Smiod }
25953d8817e4Smiod
25963d8817e4Smiod /* Routines to swap information in the XCOFF .loader section. If we
25973d8817e4Smiod ever need to write an XCOFF loader, this stuff will need to be
25983d8817e4Smiod moved to another file shared by the linker (which XCOFF calls the
25993d8817e4Smiod ``binder'') and the loader. */
26003d8817e4Smiod
26013d8817e4Smiod /* Swap in the ldhdr structure. */
26023d8817e4Smiod
26033d8817e4Smiod static void
xcoff_swap_ldhdr_in(abfd,s,dst)26043d8817e4Smiod xcoff_swap_ldhdr_in (abfd, s, dst)
26053d8817e4Smiod bfd *abfd;
26063d8817e4Smiod const PTR s;
26073d8817e4Smiod struct internal_ldhdr *dst;
26083d8817e4Smiod {
26093d8817e4Smiod const struct external_ldhdr *src = (const struct external_ldhdr *) s;
26103d8817e4Smiod
26113d8817e4Smiod dst->l_version = bfd_get_32 (abfd, src->l_version);
26123d8817e4Smiod dst->l_nsyms = bfd_get_32 (abfd, src->l_nsyms);
26133d8817e4Smiod dst->l_nreloc = bfd_get_32 (abfd, src->l_nreloc);
26143d8817e4Smiod dst->l_istlen = bfd_get_32 (abfd, src->l_istlen);
26153d8817e4Smiod dst->l_nimpid = bfd_get_32 (abfd, src->l_nimpid);
26163d8817e4Smiod dst->l_impoff = bfd_get_32 (abfd, src->l_impoff);
26173d8817e4Smiod dst->l_stlen = bfd_get_32 (abfd, src->l_stlen);
26183d8817e4Smiod dst->l_stoff = bfd_get_32 (abfd, src->l_stoff);
26193d8817e4Smiod }
26203d8817e4Smiod
26213d8817e4Smiod /* Swap out the ldhdr structure. */
26223d8817e4Smiod
26233d8817e4Smiod static void
xcoff_swap_ldhdr_out(abfd,src,d)26243d8817e4Smiod xcoff_swap_ldhdr_out (abfd, src, d)
26253d8817e4Smiod bfd *abfd;
26263d8817e4Smiod const struct internal_ldhdr *src;
26273d8817e4Smiod PTR d;
26283d8817e4Smiod {
26293d8817e4Smiod struct external_ldhdr *dst = (struct external_ldhdr *) d;
26303d8817e4Smiod
26313d8817e4Smiod bfd_put_32 (abfd, (bfd_vma) src->l_version, dst->l_version);
26323d8817e4Smiod bfd_put_32 (abfd, src->l_nsyms, dst->l_nsyms);
26333d8817e4Smiod bfd_put_32 (abfd, src->l_nreloc, dst->l_nreloc);
26343d8817e4Smiod bfd_put_32 (abfd, src->l_istlen, dst->l_istlen);
26353d8817e4Smiod bfd_put_32 (abfd, src->l_nimpid, dst->l_nimpid);
26363d8817e4Smiod bfd_put_32 (abfd, src->l_impoff, dst->l_impoff);
26373d8817e4Smiod bfd_put_32 (abfd, src->l_stlen, dst->l_stlen);
26383d8817e4Smiod bfd_put_32 (abfd, src->l_stoff, dst->l_stoff);
26393d8817e4Smiod }
26403d8817e4Smiod
26413d8817e4Smiod /* Swap in the ldsym structure. */
26423d8817e4Smiod
26433d8817e4Smiod static void
xcoff_swap_ldsym_in(abfd,s,dst)26443d8817e4Smiod xcoff_swap_ldsym_in (abfd, s, dst)
26453d8817e4Smiod bfd *abfd;
26463d8817e4Smiod const PTR s;
26473d8817e4Smiod struct internal_ldsym *dst;
26483d8817e4Smiod {
26493d8817e4Smiod const struct external_ldsym *src = (const struct external_ldsym *) s;
26503d8817e4Smiod
26513d8817e4Smiod if (bfd_get_32 (abfd, src->_l._l_l._l_zeroes) != 0) {
26523d8817e4Smiod memcpy (dst->_l._l_name, src->_l._l_name, SYMNMLEN);
26533d8817e4Smiod } else {
26543d8817e4Smiod dst->_l._l_l._l_zeroes = 0;
26553d8817e4Smiod dst->_l._l_l._l_offset = bfd_get_32 (abfd, src->_l._l_l._l_offset);
26563d8817e4Smiod }
26573d8817e4Smiod dst->l_value = bfd_get_32 (abfd, src->l_value);
26583d8817e4Smiod dst->l_scnum = bfd_get_16 (abfd, src->l_scnum);
26593d8817e4Smiod dst->l_smtype = bfd_get_8 (abfd, src->l_smtype);
26603d8817e4Smiod dst->l_smclas = bfd_get_8 (abfd, src->l_smclas);
26613d8817e4Smiod dst->l_ifile = bfd_get_32 (abfd, src->l_ifile);
26623d8817e4Smiod dst->l_parm = bfd_get_32 (abfd, src->l_parm);
26633d8817e4Smiod }
26643d8817e4Smiod
26653d8817e4Smiod /* Swap out the ldsym structure. */
26663d8817e4Smiod
26673d8817e4Smiod static void
xcoff_swap_ldsym_out(abfd,src,d)26683d8817e4Smiod xcoff_swap_ldsym_out (abfd, src, d)
26693d8817e4Smiod bfd *abfd;
26703d8817e4Smiod const struct internal_ldsym *src;
26713d8817e4Smiod PTR d;
26723d8817e4Smiod {
26733d8817e4Smiod struct external_ldsym *dst = (struct external_ldsym *) d;
26743d8817e4Smiod
26753d8817e4Smiod if (src->_l._l_l._l_zeroes != 0)
26763d8817e4Smiod memcpy (dst->_l._l_name, src->_l._l_name, SYMNMLEN);
26773d8817e4Smiod else
26783d8817e4Smiod {
26793d8817e4Smiod bfd_put_32 (abfd, (bfd_vma) 0, dst->_l._l_l._l_zeroes);
26803d8817e4Smiod bfd_put_32 (abfd, (bfd_vma) src->_l._l_l._l_offset,
26813d8817e4Smiod dst->_l._l_l._l_offset);
26823d8817e4Smiod }
26833d8817e4Smiod bfd_put_32 (abfd, src->l_value, dst->l_value);
26843d8817e4Smiod bfd_put_16 (abfd, (bfd_vma) src->l_scnum, dst->l_scnum);
26853d8817e4Smiod bfd_put_8 (abfd, src->l_smtype, dst->l_smtype);
26863d8817e4Smiod bfd_put_8 (abfd, src->l_smclas, dst->l_smclas);
26873d8817e4Smiod bfd_put_32 (abfd, src->l_ifile, dst->l_ifile);
26883d8817e4Smiod bfd_put_32 (abfd, src->l_parm, dst->l_parm);
26893d8817e4Smiod }
26903d8817e4Smiod
26913d8817e4Smiod static void
xcoff_swap_reloc_in(abfd,s,d)26923d8817e4Smiod xcoff_swap_reloc_in (abfd, s, d)
26933d8817e4Smiod bfd *abfd;
26943d8817e4Smiod PTR s;
26953d8817e4Smiod PTR d;
26963d8817e4Smiod {
26973d8817e4Smiod struct external_reloc *src = (struct external_reloc *) s;
26983d8817e4Smiod struct internal_reloc *dst = (struct internal_reloc *) d;
26993d8817e4Smiod
27003d8817e4Smiod memset (dst, 0, sizeof (struct internal_reloc));
27013d8817e4Smiod
27023d8817e4Smiod dst->r_vaddr = bfd_get_32 (abfd, src->r_vaddr);
27033d8817e4Smiod dst->r_symndx = bfd_get_32 (abfd, src->r_symndx);
27043d8817e4Smiod dst->r_size = bfd_get_8 (abfd, src->r_size);
27053d8817e4Smiod dst->r_type = bfd_get_8 (abfd, src->r_type);
27063d8817e4Smiod }
27073d8817e4Smiod
27083d8817e4Smiod static unsigned int
xcoff_swap_reloc_out(abfd,s,d)27093d8817e4Smiod xcoff_swap_reloc_out (abfd, s, d)
27103d8817e4Smiod bfd *abfd;
27113d8817e4Smiod PTR s;
27123d8817e4Smiod PTR d;
27133d8817e4Smiod {
27143d8817e4Smiod struct internal_reloc *src = (struct internal_reloc *) s;
27153d8817e4Smiod struct external_reloc *dst = (struct external_reloc *) d;
27163d8817e4Smiod
27173d8817e4Smiod bfd_put_32 (abfd, src->r_vaddr, dst->r_vaddr);
27183d8817e4Smiod bfd_put_32 (abfd, src->r_symndx, dst->r_symndx);
27193d8817e4Smiod bfd_put_8 (abfd, src->r_type, dst->r_type);
27203d8817e4Smiod bfd_put_8 (abfd, src->r_size, dst->r_size);
27213d8817e4Smiod
27223d8817e4Smiod return bfd_coff_relsz (abfd);
27233d8817e4Smiod }
27243d8817e4Smiod
27253d8817e4Smiod /* Swap in the ldrel structure. */
27263d8817e4Smiod
27273d8817e4Smiod static void
xcoff_swap_ldrel_in(abfd,s,dst)27283d8817e4Smiod xcoff_swap_ldrel_in (abfd, s, dst)
27293d8817e4Smiod bfd *abfd;
27303d8817e4Smiod const PTR s;
27313d8817e4Smiod struct internal_ldrel *dst;
27323d8817e4Smiod {
27333d8817e4Smiod const struct external_ldrel *src = (const struct external_ldrel *) s;
27343d8817e4Smiod
27353d8817e4Smiod dst->l_vaddr = bfd_get_32 (abfd, src->l_vaddr);
27363d8817e4Smiod dst->l_symndx = bfd_get_32 (abfd, src->l_symndx);
27373d8817e4Smiod dst->l_rtype = bfd_get_16 (abfd, src->l_rtype);
27383d8817e4Smiod dst->l_rsecnm = bfd_get_16 (abfd, src->l_rsecnm);
27393d8817e4Smiod }
27403d8817e4Smiod
27413d8817e4Smiod /* Swap out the ldrel structure. */
27423d8817e4Smiod
27433d8817e4Smiod static void
xcoff_swap_ldrel_out(abfd,src,d)27443d8817e4Smiod xcoff_swap_ldrel_out (abfd, src, d)
27453d8817e4Smiod bfd *abfd;
27463d8817e4Smiod const struct internal_ldrel *src;
27473d8817e4Smiod PTR d;
27483d8817e4Smiod {
27493d8817e4Smiod struct external_ldrel *dst = (struct external_ldrel *) d;
27503d8817e4Smiod
27513d8817e4Smiod bfd_put_32 (abfd, src->l_vaddr, dst->l_vaddr);
27523d8817e4Smiod bfd_put_32 (abfd, src->l_symndx, dst->l_symndx);
27533d8817e4Smiod bfd_put_16 (abfd, (bfd_vma) src->l_rtype, dst->l_rtype);
27543d8817e4Smiod bfd_put_16 (abfd, (bfd_vma) src->l_rsecnm, dst->l_rsecnm);
27553d8817e4Smiod }
27563d8817e4Smiod
27573d8817e4Smiod
27583d8817e4Smiod bfd_boolean
xcoff_reloc_type_noop(input_bfd,input_section,output_bfd,rel,sym,howto,val,addend,relocation,contents)27593d8817e4Smiod xcoff_reloc_type_noop (input_bfd, input_section, output_bfd, rel, sym, howto,
27603d8817e4Smiod val, addend, relocation, contents)
27613d8817e4Smiod bfd *input_bfd ATTRIBUTE_UNUSED;
27623d8817e4Smiod asection *input_section ATTRIBUTE_UNUSED;
27633d8817e4Smiod bfd *output_bfd ATTRIBUTE_UNUSED;
27643d8817e4Smiod struct internal_reloc *rel ATTRIBUTE_UNUSED;
27653d8817e4Smiod struct internal_syment *sym ATTRIBUTE_UNUSED;
27663d8817e4Smiod struct reloc_howto_struct *howto ATTRIBUTE_UNUSED;
27673d8817e4Smiod bfd_vma val ATTRIBUTE_UNUSED;
27683d8817e4Smiod bfd_vma addend ATTRIBUTE_UNUSED;
27693d8817e4Smiod bfd_vma *relocation ATTRIBUTE_UNUSED;
27703d8817e4Smiod bfd_byte *contents ATTRIBUTE_UNUSED;
27713d8817e4Smiod {
27723d8817e4Smiod return TRUE;
27733d8817e4Smiod }
27743d8817e4Smiod
27753d8817e4Smiod bfd_boolean
xcoff_reloc_type_fail(input_bfd,input_section,output_bfd,rel,sym,howto,val,addend,relocation,contents)27763d8817e4Smiod xcoff_reloc_type_fail (input_bfd, input_section, output_bfd, rel, sym, howto,
27773d8817e4Smiod val, addend, relocation, contents)
27783d8817e4Smiod bfd *input_bfd;
27793d8817e4Smiod asection *input_section ATTRIBUTE_UNUSED;
27803d8817e4Smiod bfd *output_bfd ATTRIBUTE_UNUSED;
27813d8817e4Smiod struct internal_reloc *rel;
27823d8817e4Smiod struct internal_syment *sym ATTRIBUTE_UNUSED;
27833d8817e4Smiod struct reloc_howto_struct *howto ATTRIBUTE_UNUSED;
27843d8817e4Smiod bfd_vma val ATTRIBUTE_UNUSED;
27853d8817e4Smiod bfd_vma addend ATTRIBUTE_UNUSED;
27863d8817e4Smiod bfd_vma *relocation ATTRIBUTE_UNUSED;
27873d8817e4Smiod bfd_byte *contents ATTRIBUTE_UNUSED;
27883d8817e4Smiod {
27893d8817e4Smiod (*_bfd_error_handler)
27903d8817e4Smiod (_("%s: unsupported relocation type 0x%02x"),
27913d8817e4Smiod bfd_get_filename (input_bfd), (unsigned int) rel->r_type);
27923d8817e4Smiod bfd_set_error (bfd_error_bad_value);
27933d8817e4Smiod return FALSE;
27943d8817e4Smiod }
27953d8817e4Smiod
27963d8817e4Smiod bfd_boolean
xcoff_reloc_type_pos(input_bfd,input_section,output_bfd,rel,sym,howto,val,addend,relocation,contents)27973d8817e4Smiod xcoff_reloc_type_pos (input_bfd, input_section, output_bfd, rel, sym, howto,
27983d8817e4Smiod val, addend, relocation, contents)
27993d8817e4Smiod bfd *input_bfd ATTRIBUTE_UNUSED;
28003d8817e4Smiod asection *input_section ATTRIBUTE_UNUSED;
28013d8817e4Smiod bfd *output_bfd ATTRIBUTE_UNUSED;
28023d8817e4Smiod struct internal_reloc *rel ATTRIBUTE_UNUSED;
28033d8817e4Smiod struct internal_syment *sym ATTRIBUTE_UNUSED;
28043d8817e4Smiod struct reloc_howto_struct *howto ATTRIBUTE_UNUSED;
28053d8817e4Smiod bfd_vma val;
28063d8817e4Smiod bfd_vma addend;
28073d8817e4Smiod bfd_vma *relocation;
28083d8817e4Smiod bfd_byte *contents ATTRIBUTE_UNUSED;
28093d8817e4Smiod {
28103d8817e4Smiod *relocation = val + addend;
28113d8817e4Smiod return TRUE;
28123d8817e4Smiod }
28133d8817e4Smiod
28143d8817e4Smiod bfd_boolean
xcoff_reloc_type_neg(input_bfd,input_section,output_bfd,rel,sym,howto,val,addend,relocation,contents)28153d8817e4Smiod xcoff_reloc_type_neg (input_bfd, input_section, output_bfd, rel, sym, howto,
28163d8817e4Smiod val, addend, relocation, contents)
28173d8817e4Smiod bfd *input_bfd ATTRIBUTE_UNUSED;
28183d8817e4Smiod asection *input_section ATTRIBUTE_UNUSED;
28193d8817e4Smiod bfd *output_bfd ATTRIBUTE_UNUSED;
28203d8817e4Smiod struct internal_reloc *rel ATTRIBUTE_UNUSED;
28213d8817e4Smiod struct internal_syment *sym ATTRIBUTE_UNUSED;
28223d8817e4Smiod struct reloc_howto_struct *howto ATTRIBUTE_UNUSED;
28233d8817e4Smiod bfd_vma val;
28243d8817e4Smiod bfd_vma addend;
28253d8817e4Smiod bfd_vma *relocation;
28263d8817e4Smiod bfd_byte *contents ATTRIBUTE_UNUSED;
28273d8817e4Smiod {
28283d8817e4Smiod *relocation = addend - val;
28293d8817e4Smiod return TRUE;
28303d8817e4Smiod }
28313d8817e4Smiod
28323d8817e4Smiod bfd_boolean
xcoff_reloc_type_rel(input_bfd,input_section,output_bfd,rel,sym,howto,val,addend,relocation,contents)28333d8817e4Smiod xcoff_reloc_type_rel (input_bfd, input_section, output_bfd, rel, sym, howto,
28343d8817e4Smiod val, addend, relocation, contents)
28353d8817e4Smiod bfd *input_bfd ATTRIBUTE_UNUSED;
28363d8817e4Smiod asection *input_section;
28373d8817e4Smiod bfd *output_bfd ATTRIBUTE_UNUSED;
28383d8817e4Smiod struct internal_reloc *rel ATTRIBUTE_UNUSED;
28393d8817e4Smiod struct internal_syment *sym ATTRIBUTE_UNUSED;
28403d8817e4Smiod struct reloc_howto_struct *howto;
28413d8817e4Smiod bfd_vma val;
28423d8817e4Smiod bfd_vma addend;
28433d8817e4Smiod bfd_vma *relocation;
28443d8817e4Smiod bfd_byte *contents ATTRIBUTE_UNUSED;
28453d8817e4Smiod {
28463d8817e4Smiod howto->pc_relative = TRUE;
28473d8817e4Smiod
28483d8817e4Smiod /* A PC relative reloc includes the section address. */
28493d8817e4Smiod addend += input_section->vma;
28503d8817e4Smiod
28513d8817e4Smiod *relocation = val + addend;
28523d8817e4Smiod *relocation -= (input_section->output_section->vma
28533d8817e4Smiod + input_section->output_offset);
28543d8817e4Smiod return TRUE;
28553d8817e4Smiod }
28563d8817e4Smiod
28573d8817e4Smiod bfd_boolean
xcoff_reloc_type_toc(input_bfd,input_section,output_bfd,rel,sym,howto,val,addend,relocation,contents)28583d8817e4Smiod xcoff_reloc_type_toc (input_bfd, input_section, output_bfd, rel, sym, howto,
28593d8817e4Smiod val, addend, relocation, contents)
28603d8817e4Smiod bfd *input_bfd;
28613d8817e4Smiod asection *input_section ATTRIBUTE_UNUSED;
28623d8817e4Smiod bfd *output_bfd;
28633d8817e4Smiod struct internal_reloc *rel;
28643d8817e4Smiod struct internal_syment *sym;
28653d8817e4Smiod struct reloc_howto_struct *howto ATTRIBUTE_UNUSED;
28663d8817e4Smiod bfd_vma val;
28673d8817e4Smiod bfd_vma addend ATTRIBUTE_UNUSED;
28683d8817e4Smiod bfd_vma *relocation;
28693d8817e4Smiod bfd_byte *contents ATTRIBUTE_UNUSED;
28703d8817e4Smiod {
28713d8817e4Smiod struct xcoff_link_hash_entry *h;
28723d8817e4Smiod
28733d8817e4Smiod if (0 > rel->r_symndx)
28743d8817e4Smiod return FALSE;
28753d8817e4Smiod
28763d8817e4Smiod h = obj_xcoff_sym_hashes (input_bfd)[rel->r_symndx];
28773d8817e4Smiod
28783d8817e4Smiod if (h != NULL && h->smclas != XMC_TD)
28793d8817e4Smiod {
28803d8817e4Smiod if (h->toc_section == NULL)
28813d8817e4Smiod {
28823d8817e4Smiod (*_bfd_error_handler)
28833d8817e4Smiod (_("%s: TOC reloc at 0x%x to symbol `%s' with no TOC entry"),
28843d8817e4Smiod bfd_get_filename (input_bfd), rel->r_vaddr,
28853d8817e4Smiod h->root.root.string);
28863d8817e4Smiod bfd_set_error (bfd_error_bad_value);
28873d8817e4Smiod return FALSE;
28883d8817e4Smiod }
28893d8817e4Smiod
28903d8817e4Smiod BFD_ASSERT ((h->flags & XCOFF_SET_TOC) == 0);
28913d8817e4Smiod val = (h->toc_section->output_section->vma
28923d8817e4Smiod + h->toc_section->output_offset);
28933d8817e4Smiod }
28943d8817e4Smiod
28953d8817e4Smiod *relocation = ((val - xcoff_data (output_bfd)->toc)
28963d8817e4Smiod - (sym->n_value - xcoff_data (input_bfd)->toc));
28973d8817e4Smiod return TRUE;
28983d8817e4Smiod }
28993d8817e4Smiod
29003d8817e4Smiod bfd_boolean
xcoff_reloc_type_ba(input_bfd,input_section,output_bfd,rel,sym,howto,val,addend,relocation,contents)29013d8817e4Smiod xcoff_reloc_type_ba (input_bfd, input_section, output_bfd, rel, sym, howto,
29023d8817e4Smiod val, addend, relocation, contents)
29033d8817e4Smiod bfd *input_bfd ATTRIBUTE_UNUSED;
29043d8817e4Smiod asection *input_section ATTRIBUTE_UNUSED;
29053d8817e4Smiod bfd *output_bfd ATTRIBUTE_UNUSED;
29063d8817e4Smiod struct internal_reloc *rel ATTRIBUTE_UNUSED;
29073d8817e4Smiod struct internal_syment *sym ATTRIBUTE_UNUSED;
29083d8817e4Smiod struct reloc_howto_struct *howto;
29093d8817e4Smiod bfd_vma val;
29103d8817e4Smiod bfd_vma addend;
29113d8817e4Smiod bfd_vma *relocation;
29123d8817e4Smiod bfd_byte *contents ATTRIBUTE_UNUSED;
29133d8817e4Smiod {
29143d8817e4Smiod howto->src_mask &= ~3;
29153d8817e4Smiod howto->dst_mask = howto->src_mask;
29163d8817e4Smiod
29173d8817e4Smiod *relocation = val + addend;
29183d8817e4Smiod
29193d8817e4Smiod return TRUE;
29203d8817e4Smiod }
29213d8817e4Smiod
29223d8817e4Smiod static bfd_boolean
xcoff_reloc_type_br(input_bfd,input_section,output_bfd,rel,sym,howto,val,addend,relocation,contents)29233d8817e4Smiod xcoff_reloc_type_br (input_bfd, input_section, output_bfd, rel, sym, howto,
29243d8817e4Smiod val, addend, relocation, contents)
29253d8817e4Smiod bfd *input_bfd;
29263d8817e4Smiod asection *input_section;
29273d8817e4Smiod bfd *output_bfd ATTRIBUTE_UNUSED;
29283d8817e4Smiod struct internal_reloc *rel;
29293d8817e4Smiod struct internal_syment *sym ATTRIBUTE_UNUSED;
29303d8817e4Smiod struct reloc_howto_struct *howto;
29313d8817e4Smiod bfd_vma val;
29323d8817e4Smiod bfd_vma addend;
29333d8817e4Smiod bfd_vma *relocation;
29343d8817e4Smiod bfd_byte *contents;
29353d8817e4Smiod {
29363d8817e4Smiod struct xcoff_link_hash_entry *h;
29373d8817e4Smiod
29383d8817e4Smiod if (0 > rel->r_symndx)
29393d8817e4Smiod return FALSE;
29403d8817e4Smiod
29413d8817e4Smiod h = obj_xcoff_sym_hashes (input_bfd)[rel->r_symndx];
29423d8817e4Smiod
29433d8817e4Smiod /* If we see an R_BR or R_RBR reloc which is jumping to global
29443d8817e4Smiod linkage code, and it is followed by an appropriate cror nop
29453d8817e4Smiod instruction, we replace the cror with lwz r2,20(r1). This
29463d8817e4Smiod restores the TOC after the glink code. Contrariwise, if the
29473d8817e4Smiod call is followed by a lwz r2,20(r1), but the call is not
29483d8817e4Smiod going to global linkage code, we can replace the load with a
29493d8817e4Smiod cror. */
29503d8817e4Smiod if (NULL != h
29513d8817e4Smiod && bfd_link_hash_defined == h->root.type
29523d8817e4Smiod && rel->r_vaddr - input_section->vma + 8 <= input_section->size)
29533d8817e4Smiod {
29543d8817e4Smiod bfd_byte *pnext;
29553d8817e4Smiod unsigned long next;
29563d8817e4Smiod
29573d8817e4Smiod pnext = contents + (rel->r_vaddr - input_section->vma) + 4;
29583d8817e4Smiod next = bfd_get_32 (input_bfd, pnext);
29593d8817e4Smiod
29603d8817e4Smiod /* The _ptrgl function is magic. It is used by the AIX
29613d8817e4Smiod compiler to call a function through a pointer. */
29623d8817e4Smiod if (h->smclas == XMC_GL || strcmp (h->root.root.string, "._ptrgl") == 0)
29633d8817e4Smiod {
29643d8817e4Smiod if (next == 0x4def7b82 /* cror 15,15,15 */
29653d8817e4Smiod || next == 0x4ffffb82 /* cror 31,31,31 */
29663d8817e4Smiod || next == 0x60000000) /* ori r0,r0,0 */
29673d8817e4Smiod bfd_put_32 (input_bfd, 0x80410014, pnext); /* lwz r1,20(r1) */
29683d8817e4Smiod
29693d8817e4Smiod }
29703d8817e4Smiod else
29713d8817e4Smiod {
29723d8817e4Smiod if (next == 0x80410014) /* lwz r1,20(r1) */
29733d8817e4Smiod bfd_put_32 (input_bfd, 0x60000000, pnext); /* ori r0,r0,0 */
29743d8817e4Smiod }
29753d8817e4Smiod }
29763d8817e4Smiod else if (NULL != h && bfd_link_hash_undefined == h->root.type)
29773d8817e4Smiod {
29783d8817e4Smiod /* Normally, this relocation is against a defined symbol. In the
29793d8817e4Smiod case where this is a partial link and the output section offset
29803d8817e4Smiod is greater than 2^25, the linker will return an invalid error
29813d8817e4Smiod message that the relocation has been truncated. Yes it has been
29823d8817e4Smiod truncated but no it not important. For this case, disable the
29833d8817e4Smiod overflow checking. */
29843d8817e4Smiod
29853d8817e4Smiod howto->complain_on_overflow = complain_overflow_dont;
29863d8817e4Smiod }
29873d8817e4Smiod
29883d8817e4Smiod howto->pc_relative = TRUE;
29893d8817e4Smiod howto->src_mask &= ~3;
29903d8817e4Smiod howto->dst_mask = howto->src_mask;
29913d8817e4Smiod
29923d8817e4Smiod /* A PC relative reloc includes the section address. */
29933d8817e4Smiod addend += input_section->vma;
29943d8817e4Smiod
29953d8817e4Smiod *relocation = val + addend;
29963d8817e4Smiod *relocation -= (input_section->output_section->vma
29973d8817e4Smiod + input_section->output_offset);
29983d8817e4Smiod return TRUE;
29993d8817e4Smiod }
30003d8817e4Smiod
30013d8817e4Smiod bfd_boolean
xcoff_reloc_type_crel(input_bfd,input_section,output_bfd,rel,sym,howto,val,addend,relocation,contents)30023d8817e4Smiod xcoff_reloc_type_crel (input_bfd, input_section, output_bfd, rel, sym, howto,
30033d8817e4Smiod val, addend, relocation, contents)
30043d8817e4Smiod bfd *input_bfd ATTRIBUTE_UNUSED;
30053d8817e4Smiod asection *input_section;
30063d8817e4Smiod bfd *output_bfd ATTRIBUTE_UNUSED;
30073d8817e4Smiod struct internal_reloc *rel ATTRIBUTE_UNUSED;
30083d8817e4Smiod struct internal_syment *sym ATTRIBUTE_UNUSED;
30093d8817e4Smiod struct reloc_howto_struct *howto;
30103d8817e4Smiod bfd_vma val ATTRIBUTE_UNUSED;
30113d8817e4Smiod bfd_vma addend;
30123d8817e4Smiod bfd_vma *relocation;
30133d8817e4Smiod bfd_byte *contents ATTRIBUTE_UNUSED;
30143d8817e4Smiod {
30153d8817e4Smiod howto->pc_relative = TRUE;
30163d8817e4Smiod howto->src_mask &= ~3;
30173d8817e4Smiod howto->dst_mask = howto->src_mask;
30183d8817e4Smiod
30193d8817e4Smiod /* A PC relative reloc includes the section address. */
30203d8817e4Smiod addend += input_section->vma;
30213d8817e4Smiod
30223d8817e4Smiod *relocation = val + addend;
30233d8817e4Smiod *relocation -= (input_section->output_section->vma
30243d8817e4Smiod + input_section->output_offset);
30253d8817e4Smiod return TRUE;
30263d8817e4Smiod }
30273d8817e4Smiod
30283d8817e4Smiod static bfd_boolean
xcoff_complain_overflow_dont_func(input_bfd,val,relocation,howto)30293d8817e4Smiod xcoff_complain_overflow_dont_func (input_bfd, val, relocation, howto)
30303d8817e4Smiod bfd *input_bfd ATTRIBUTE_UNUSED;
30313d8817e4Smiod bfd_vma val ATTRIBUTE_UNUSED;
30323d8817e4Smiod bfd_vma relocation ATTRIBUTE_UNUSED;
30333d8817e4Smiod struct reloc_howto_struct *howto ATTRIBUTE_UNUSED;
30343d8817e4Smiod {
30353d8817e4Smiod return FALSE;
30363d8817e4Smiod }
30373d8817e4Smiod
30383d8817e4Smiod static bfd_boolean
xcoff_complain_overflow_bitfield_func(input_bfd,val,relocation,howto)30393d8817e4Smiod xcoff_complain_overflow_bitfield_func (input_bfd, val, relocation, howto)
30403d8817e4Smiod bfd *input_bfd;
30413d8817e4Smiod bfd_vma val;
30423d8817e4Smiod bfd_vma relocation;
30433d8817e4Smiod struct reloc_howto_struct *howto;
30443d8817e4Smiod {
30453d8817e4Smiod bfd_vma addrmask, fieldmask, signmask, ss;
30463d8817e4Smiod bfd_vma a, b, sum;
30473d8817e4Smiod
30483d8817e4Smiod /* Get the values to be added together. For signed and unsigned
30493d8817e4Smiod relocations, we assume that all values should be truncated to
30503d8817e4Smiod the size of an address. For bitfields, all the bits matter.
30513d8817e4Smiod See also bfd_check_overflow. */
30523d8817e4Smiod fieldmask = N_ONES (howto->bitsize);
30533d8817e4Smiod addrmask = N_ONES (bfd_arch_bits_per_address (input_bfd)) | fieldmask;
30543d8817e4Smiod a = relocation;
30553d8817e4Smiod b = val & howto->src_mask;
30563d8817e4Smiod
30573d8817e4Smiod /* Much like unsigned, except no trimming with addrmask. In
30583d8817e4Smiod addition, the sum overflows if there is a carry out of
30593d8817e4Smiod the bfd_vma, i.e., the sum is less than either input
30603d8817e4Smiod operand. */
30613d8817e4Smiod a >>= howto->rightshift;
30623d8817e4Smiod b >>= howto->bitpos;
30633d8817e4Smiod
30643d8817e4Smiod /* Bitfields are sometimes used for signed numbers; for
30653d8817e4Smiod example, a 13-bit field sometimes represents values in
30663d8817e4Smiod 0..8191 and sometimes represents values in -4096..4095.
30673d8817e4Smiod If the field is signed and a is -4095 (0x1001) and b is
30683d8817e4Smiod -1 (0x1fff), the sum is -4096 (0x1000), but (0x1001 +
30693d8817e4Smiod 0x1fff is 0x3000). It's not clear how to handle this
30703d8817e4Smiod everywhere, since there is not way to know how many bits
30713d8817e4Smiod are significant in the relocation, but the original code
30723d8817e4Smiod assumed that it was fully sign extended, and we will keep
30733d8817e4Smiod that assumption. */
30743d8817e4Smiod signmask = (fieldmask >> 1) + 1;
30753d8817e4Smiod
30763d8817e4Smiod if ((a & ~ fieldmask) != 0)
30773d8817e4Smiod {
30783d8817e4Smiod /* Some bits out of the field are set. This might not
30793d8817e4Smiod be a problem: if this is a signed bitfield, it is OK
30803d8817e4Smiod iff all the high bits are set, including the sign
30813d8817e4Smiod bit. We'll try setting all but the most significant
30823d8817e4Smiod bit in the original relocation value: if this is all
30833d8817e4Smiod ones, we are OK, assuming a signed bitfield. */
30843d8817e4Smiod ss = (signmask << howto->rightshift) - 1;
30853d8817e4Smiod if ((ss | relocation) != ~ (bfd_vma) 0)
30863d8817e4Smiod return TRUE;
30873d8817e4Smiod a &= fieldmask;
30883d8817e4Smiod }
30893d8817e4Smiod
30903d8817e4Smiod /* We just assume (b & ~ fieldmask) == 0. */
30913d8817e4Smiod
30923d8817e4Smiod /* We explicitly permit wrap around if this relocation
30933d8817e4Smiod covers the high bit of an address. The Linux kernel
30943d8817e4Smiod relies on it, and it is the only way to write assembler
30953d8817e4Smiod code which can run when loaded at a location 0x80000000
30963d8817e4Smiod away from the location at which it is linked. */
30973d8817e4Smiod if (howto->bitsize + howto->rightshift
30983d8817e4Smiod == bfd_arch_bits_per_address (input_bfd))
30993d8817e4Smiod return FALSE;
31003d8817e4Smiod
31013d8817e4Smiod sum = a + b;
31023d8817e4Smiod if (sum < a || (sum & ~ fieldmask) != 0)
31033d8817e4Smiod {
31043d8817e4Smiod /* There was a carry out, or the field overflow. Test
31053d8817e4Smiod for signed operands again. Here is the overflow test
31063d8817e4Smiod is as for complain_overflow_signed. */
31073d8817e4Smiod if (((~ (a ^ b)) & (a ^ sum)) & signmask)
31083d8817e4Smiod return TRUE;
31093d8817e4Smiod }
31103d8817e4Smiod
31113d8817e4Smiod return FALSE;
31123d8817e4Smiod }
31133d8817e4Smiod
31143d8817e4Smiod static bfd_boolean
xcoff_complain_overflow_signed_func(input_bfd,val,relocation,howto)31153d8817e4Smiod xcoff_complain_overflow_signed_func (input_bfd, val, relocation, howto)
31163d8817e4Smiod bfd *input_bfd;
31173d8817e4Smiod bfd_vma val;
31183d8817e4Smiod bfd_vma relocation;
31193d8817e4Smiod struct reloc_howto_struct *howto;
31203d8817e4Smiod {
31213d8817e4Smiod bfd_vma addrmask, fieldmask, signmask, ss;
31223d8817e4Smiod bfd_vma a, b, sum;
31233d8817e4Smiod
31243d8817e4Smiod /* Get the values to be added together. For signed and unsigned
31253d8817e4Smiod relocations, we assume that all values should be truncated to
31263d8817e4Smiod the size of an address. For bitfields, all the bits matter.
31273d8817e4Smiod See also bfd_check_overflow. */
31283d8817e4Smiod fieldmask = N_ONES (howto->bitsize);
31293d8817e4Smiod addrmask = N_ONES (bfd_arch_bits_per_address (input_bfd)) | fieldmask;
31303d8817e4Smiod a = relocation;
31313d8817e4Smiod b = val & howto->src_mask;
31323d8817e4Smiod
31333d8817e4Smiod a = (a & addrmask) >> howto->rightshift;
31343d8817e4Smiod
31353d8817e4Smiod /* If any sign bits are set, all sign bits must be set.
31363d8817e4Smiod That is, A must be a valid negative address after
31373d8817e4Smiod shifting. */
31383d8817e4Smiod signmask = ~ (fieldmask >> 1);
31393d8817e4Smiod ss = a & signmask;
31403d8817e4Smiod if (ss != 0 && ss != ((addrmask >> howto->rightshift) & signmask))
31413d8817e4Smiod return TRUE;
31423d8817e4Smiod
31433d8817e4Smiod /* We only need this next bit of code if the sign bit of B
31443d8817e4Smiod is below the sign bit of A. This would only happen if
31453d8817e4Smiod SRC_MASK had fewer bits than BITSIZE. Note that if
31463d8817e4Smiod SRC_MASK has more bits than BITSIZE, we can get into
31473d8817e4Smiod trouble; we would need to verify that B is in range, as
31483d8817e4Smiod we do for A above. */
31493d8817e4Smiod signmask = ((~ howto->src_mask) >> 1) & howto->src_mask;
31503d8817e4Smiod if ((b & signmask) != 0)
31513d8817e4Smiod {
31523d8817e4Smiod /* Set all the bits above the sign bit. */
31533d8817e4Smiod b -= signmask <<= 1;
31543d8817e4Smiod }
31553d8817e4Smiod
31563d8817e4Smiod b = (b & addrmask) >> howto->bitpos;
31573d8817e4Smiod
31583d8817e4Smiod /* Now we can do the addition. */
31593d8817e4Smiod sum = a + b;
31603d8817e4Smiod
31613d8817e4Smiod /* See if the result has the correct sign. Bits above the
31623d8817e4Smiod sign bit are junk now; ignore them. If the sum is
31633d8817e4Smiod positive, make sure we did not have all negative inputs;
31643d8817e4Smiod if the sum is negative, make sure we did not have all
31653d8817e4Smiod positive inputs. The test below looks only at the sign
31663d8817e4Smiod bits, and it really just
31673d8817e4Smiod SIGN (A) == SIGN (B) && SIGN (A) != SIGN (SUM)
31683d8817e4Smiod */
31693d8817e4Smiod signmask = (fieldmask >> 1) + 1;
31703d8817e4Smiod if (((~ (a ^ b)) & (a ^ sum)) & signmask)
31713d8817e4Smiod return TRUE;
31723d8817e4Smiod
31733d8817e4Smiod return FALSE;
31743d8817e4Smiod }
31753d8817e4Smiod
31763d8817e4Smiod static bfd_boolean
xcoff_complain_overflow_unsigned_func(input_bfd,val,relocation,howto)31773d8817e4Smiod xcoff_complain_overflow_unsigned_func (input_bfd, val, relocation, howto)
31783d8817e4Smiod bfd *input_bfd;
31793d8817e4Smiod bfd_vma val;
31803d8817e4Smiod bfd_vma relocation;
31813d8817e4Smiod struct reloc_howto_struct *howto;
31823d8817e4Smiod {
31833d8817e4Smiod bfd_vma addrmask, fieldmask;
31843d8817e4Smiod bfd_vma a, b, sum;
31853d8817e4Smiod
31863d8817e4Smiod /* Get the values to be added together. For signed and unsigned
31873d8817e4Smiod relocations, we assume that all values should be truncated to
31883d8817e4Smiod the size of an address. For bitfields, all the bits matter.
31893d8817e4Smiod See also bfd_check_overflow. */
31903d8817e4Smiod fieldmask = N_ONES (howto->bitsize);
31913d8817e4Smiod addrmask = N_ONES (bfd_arch_bits_per_address (input_bfd)) | fieldmask;
31923d8817e4Smiod a = relocation;
31933d8817e4Smiod b = val & howto->src_mask;
31943d8817e4Smiod
31953d8817e4Smiod /* Checking for an unsigned overflow is relatively easy:
31963d8817e4Smiod trim the addresses and add, and trim the result as well.
31973d8817e4Smiod Overflow is normally indicated when the result does not
31983d8817e4Smiod fit in the field. However, we also need to consider the
31993d8817e4Smiod case when, e.g., fieldmask is 0x7fffffff or smaller, an
32003d8817e4Smiod input is 0x80000000, and bfd_vma is only 32 bits; then we
32013d8817e4Smiod will get sum == 0, but there is an overflow, since the
32023d8817e4Smiod inputs did not fit in the field. Instead of doing a
32033d8817e4Smiod separate test, we can check for this by or-ing in the
32043d8817e4Smiod operands when testing for the sum overflowing its final
32053d8817e4Smiod field. */
32063d8817e4Smiod a = (a & addrmask) >> howto->rightshift;
32073d8817e4Smiod b = (b & addrmask) >> howto->bitpos;
32083d8817e4Smiod sum = (a + b) & addrmask;
32093d8817e4Smiod if ((a | b | sum) & ~ fieldmask)
32103d8817e4Smiod return TRUE;
32113d8817e4Smiod
32123d8817e4Smiod return FALSE;
32133d8817e4Smiod }
32143d8817e4Smiod
32153d8817e4Smiod /* This is the relocation function for the RS/6000/POWER/PowerPC.
32163d8817e4Smiod This is currently the only processor which uses XCOFF; I hope that
32173d8817e4Smiod will never change.
32183d8817e4Smiod
32193d8817e4Smiod I took the relocation type definitions from two documents:
32203d8817e4Smiod the PowerPC AIX Version 4 Application Binary Interface, First
32213d8817e4Smiod Edition (April 1992), and the PowerOpen ABI, Big-Endian
32223d8817e4Smiod 32-Bit Hardware Implementation (June 30, 1994). Differences
32233d8817e4Smiod between the documents are noted below.
32243d8817e4Smiod
32253d8817e4Smiod Unsupported r_type's
32263d8817e4Smiod
32273d8817e4Smiod R_RTB:
32283d8817e4Smiod R_RRTBI:
32293d8817e4Smiod R_RRTBA:
32303d8817e4Smiod
32313d8817e4Smiod These relocs are defined by the PowerPC ABI to be
32323d8817e4Smiod relative branches which use half of the difference
32333d8817e4Smiod between the symbol and the program counter. I can't
32343d8817e4Smiod quite figure out when this is useful. These relocs are
32353d8817e4Smiod not defined by the PowerOpen ABI.
32363d8817e4Smiod
32373d8817e4Smiod Supported r_type's
32383d8817e4Smiod
32393d8817e4Smiod R_POS:
32403d8817e4Smiod Simple positive relocation.
32413d8817e4Smiod
32423d8817e4Smiod R_NEG:
32433d8817e4Smiod Simple negative relocation.
32443d8817e4Smiod
32453d8817e4Smiod R_REL:
32463d8817e4Smiod Simple PC relative relocation.
32473d8817e4Smiod
32483d8817e4Smiod R_TOC:
32493d8817e4Smiod TOC relative relocation. The value in the instruction in
32503d8817e4Smiod the input file is the offset from the input file TOC to
32513d8817e4Smiod the desired location. We want the offset from the final
32523d8817e4Smiod TOC to the desired location. We have:
32533d8817e4Smiod isym = iTOC + in
32543d8817e4Smiod iinsn = in + o
32553d8817e4Smiod osym = oTOC + on
32563d8817e4Smiod oinsn = on + o
32573d8817e4Smiod so we must change insn by on - in.
32583d8817e4Smiod
32593d8817e4Smiod R_GL:
32603d8817e4Smiod GL linkage relocation. The value of this relocation
32613d8817e4Smiod is the address of the entry in the TOC section.
32623d8817e4Smiod
32633d8817e4Smiod R_TCL:
32643d8817e4Smiod Local object TOC address. I can't figure out the
32653d8817e4Smiod difference between this and case R_GL.
32663d8817e4Smiod
32673d8817e4Smiod R_TRL:
32683d8817e4Smiod TOC relative relocation. A TOC relative load instruction
32693d8817e4Smiod which may be changed to a load address instruction.
32703d8817e4Smiod FIXME: We don't currently implement this optimization.
32713d8817e4Smiod
32723d8817e4Smiod R_TRLA:
32733d8817e4Smiod TOC relative relocation. This is a TOC relative load
32743d8817e4Smiod address instruction which may be changed to a load
32753d8817e4Smiod instruction. FIXME: I don't know if this is the correct
32763d8817e4Smiod implementation.
32773d8817e4Smiod
32783d8817e4Smiod R_BA:
32793d8817e4Smiod Absolute branch. We don't want to mess with the lower
32803d8817e4Smiod two bits of the instruction.
32813d8817e4Smiod
32823d8817e4Smiod R_CAI:
32833d8817e4Smiod The PowerPC ABI defines this as an absolute call which
32843d8817e4Smiod may be modified to become a relative call. The PowerOpen
32853d8817e4Smiod ABI does not define this relocation type.
32863d8817e4Smiod
32873d8817e4Smiod R_RBA:
32883d8817e4Smiod Absolute branch which may be modified to become a
32893d8817e4Smiod relative branch.
32903d8817e4Smiod
32913d8817e4Smiod R_RBAC:
32923d8817e4Smiod The PowerPC ABI defines this as an absolute branch to a
32933d8817e4Smiod fixed address which may be modified to an absolute branch
32943d8817e4Smiod to a symbol. The PowerOpen ABI does not define this
32953d8817e4Smiod relocation type.
32963d8817e4Smiod
32973d8817e4Smiod R_RBRC:
32983d8817e4Smiod The PowerPC ABI defines this as an absolute branch to a
32993d8817e4Smiod fixed address which may be modified to a relative branch.
33003d8817e4Smiod The PowerOpen ABI does not define this relocation type.
33013d8817e4Smiod
33023d8817e4Smiod R_BR:
33033d8817e4Smiod Relative branch. We don't want to mess with the lower
33043d8817e4Smiod two bits of the instruction.
33053d8817e4Smiod
33063d8817e4Smiod R_CREL:
33073d8817e4Smiod The PowerPC ABI defines this as a relative call which may
33083d8817e4Smiod be modified to become an absolute call. The PowerOpen
33093d8817e4Smiod ABI does not define this relocation type.
33103d8817e4Smiod
33113d8817e4Smiod R_RBR:
33123d8817e4Smiod A relative branch which may be modified to become an
33133d8817e4Smiod absolute branch. FIXME: We don't implement this,
33143d8817e4Smiod although we should for symbols of storage mapping class
33153d8817e4Smiod XMC_XO.
33163d8817e4Smiod
33173d8817e4Smiod R_RL:
33183d8817e4Smiod The PowerPC AIX ABI describes this as a load which may be
33193d8817e4Smiod changed to a load address. The PowerOpen ABI says this
33203d8817e4Smiod is the same as case R_POS.
33213d8817e4Smiod
33223d8817e4Smiod R_RLA:
33233d8817e4Smiod The PowerPC AIX ABI describes this as a load address
33243d8817e4Smiod which may be changed to a load. The PowerOpen ABI says
33253d8817e4Smiod this is the same as R_POS.
33263d8817e4Smiod */
33273d8817e4Smiod
33283d8817e4Smiod bfd_boolean
xcoff_ppc_relocate_section(output_bfd,info,input_bfd,input_section,contents,relocs,syms,sections)33293d8817e4Smiod xcoff_ppc_relocate_section (output_bfd, info, input_bfd,
33303d8817e4Smiod input_section, contents, relocs, syms,
33313d8817e4Smiod sections)
33323d8817e4Smiod bfd *output_bfd;
33333d8817e4Smiod struct bfd_link_info *info;
33343d8817e4Smiod bfd *input_bfd;
33353d8817e4Smiod asection *input_section;
33363d8817e4Smiod bfd_byte *contents;
33373d8817e4Smiod struct internal_reloc *relocs;
33383d8817e4Smiod struct internal_syment *syms;
33393d8817e4Smiod asection **sections;
33403d8817e4Smiod {
33413d8817e4Smiod struct internal_reloc *rel;
33423d8817e4Smiod struct internal_reloc *relend;
33433d8817e4Smiod
33443d8817e4Smiod rel = relocs;
33453d8817e4Smiod relend = rel + input_section->reloc_count;
33463d8817e4Smiod for (; rel < relend; rel++)
33473d8817e4Smiod {
33483d8817e4Smiod long symndx;
33493d8817e4Smiod struct xcoff_link_hash_entry *h;
33503d8817e4Smiod struct internal_syment *sym;
33513d8817e4Smiod bfd_vma addend;
33523d8817e4Smiod bfd_vma val;
33533d8817e4Smiod struct reloc_howto_struct howto;
33543d8817e4Smiod bfd_vma relocation;
33553d8817e4Smiod bfd_vma value_to_relocate;
33563d8817e4Smiod bfd_vma address;
33573d8817e4Smiod bfd_byte *location;
33583d8817e4Smiod
33593d8817e4Smiod /* Relocation type R_REF is a special relocation type which is
33603d8817e4Smiod merely used to prevent garbage collection from occurring for
33613d8817e4Smiod the csect including the symbol which it references. */
33623d8817e4Smiod if (rel->r_type == R_REF)
33633d8817e4Smiod continue;
33643d8817e4Smiod
33653d8817e4Smiod /* howto */
33663d8817e4Smiod howto.type = rel->r_type;
33673d8817e4Smiod howto.rightshift = 0;
33683d8817e4Smiod howto.bitsize = (rel->r_size & 0x1f) + 1;
33693d8817e4Smiod howto.size = howto.bitsize > 16 ? 2 : 1;
33703d8817e4Smiod howto.pc_relative = FALSE;
33713d8817e4Smiod howto.bitpos = 0;
33723d8817e4Smiod howto.complain_on_overflow = (rel->r_size & 0x80
33733d8817e4Smiod ? complain_overflow_signed
33743d8817e4Smiod : complain_overflow_bitfield);
33753d8817e4Smiod howto.special_function = NULL;
33763d8817e4Smiod howto.name = "internal";
33773d8817e4Smiod howto.partial_inplace = TRUE;
33783d8817e4Smiod howto.src_mask = howto.dst_mask = N_ONES (howto.bitsize);
33793d8817e4Smiod howto.pcrel_offset = FALSE;
33803d8817e4Smiod
33813d8817e4Smiod /* symbol */
33823d8817e4Smiod val = 0;
33833d8817e4Smiod addend = 0;
33843d8817e4Smiod h = NULL;
33853d8817e4Smiod sym = NULL;
33863d8817e4Smiod symndx = rel->r_symndx;
33873d8817e4Smiod
33883d8817e4Smiod if (-1 != symndx)
33893d8817e4Smiod {
33903d8817e4Smiod asection *sec;
33913d8817e4Smiod
33923d8817e4Smiod h = obj_xcoff_sym_hashes (input_bfd)[symndx];
33933d8817e4Smiod sym = syms + symndx;
33943d8817e4Smiod addend = - sym->n_value;
33953d8817e4Smiod
33963d8817e4Smiod if (NULL == h)
33973d8817e4Smiod {
33983d8817e4Smiod sec = sections[symndx];
33993d8817e4Smiod /* Hack to make sure we use the right TOC anchor value
34003d8817e4Smiod if this reloc is against the TOC anchor. */
34013d8817e4Smiod if (sec->name[3] == '0'
34023d8817e4Smiod && strcmp (sec->name, ".tc0") == 0)
34033d8817e4Smiod val = xcoff_data (output_bfd)->toc;
34043d8817e4Smiod else
34053d8817e4Smiod val = (sec->output_section->vma
34063d8817e4Smiod + sec->output_offset
34073d8817e4Smiod + sym->n_value
34083d8817e4Smiod - sec->vma);
34093d8817e4Smiod }
34103d8817e4Smiod else
34113d8817e4Smiod {
34123d8817e4Smiod if (h->root.type == bfd_link_hash_defined
34133d8817e4Smiod || h->root.type == bfd_link_hash_defweak)
34143d8817e4Smiod {
34153d8817e4Smiod sec = h->root.u.def.section;
34163d8817e4Smiod val = (h->root.u.def.value
34173d8817e4Smiod + sec->output_section->vma
34183d8817e4Smiod + sec->output_offset);
34193d8817e4Smiod }
34203d8817e4Smiod else if (h->root.type == bfd_link_hash_common)
34213d8817e4Smiod {
34223d8817e4Smiod sec = h->root.u.c.p->section;
34233d8817e4Smiod val = (sec->output_section->vma
34243d8817e4Smiod + sec->output_offset);
34253d8817e4Smiod
34263d8817e4Smiod }
34273d8817e4Smiod else if ((0 == (h->flags & (XCOFF_DEF_DYNAMIC | XCOFF_IMPORT)))
34283d8817e4Smiod && ! info->relocatable)
34293d8817e4Smiod {
34303d8817e4Smiod if (! ((*info->callbacks->undefined_symbol)
34313d8817e4Smiod (info, h->root.root.string, input_bfd, input_section,
34323d8817e4Smiod rel->r_vaddr - input_section->vma, TRUE)))
34333d8817e4Smiod return FALSE;
34343d8817e4Smiod
34353d8817e4Smiod /* Don't try to process the reloc. It can't help, and
34363d8817e4Smiod it may generate another error. */
34373d8817e4Smiod continue;
34383d8817e4Smiod }
34393d8817e4Smiod }
34403d8817e4Smiod }
34413d8817e4Smiod
34423d8817e4Smiod if (rel->r_type >= XCOFF_MAX_CALCULATE_RELOCATION
34433d8817e4Smiod || !((*xcoff_calculate_relocation[rel->r_type])
34443d8817e4Smiod (input_bfd, input_section, output_bfd, rel, sym, &howto, val,
34453d8817e4Smiod addend, &relocation, contents)))
34463d8817e4Smiod return FALSE;
34473d8817e4Smiod
34483d8817e4Smiod /* address */
34493d8817e4Smiod address = rel->r_vaddr - input_section->vma;
34503d8817e4Smiod location = contents + address;
34513d8817e4Smiod
34523d8817e4Smiod if (address > input_section->size)
34533d8817e4Smiod abort ();
34543d8817e4Smiod
34553d8817e4Smiod /* Get the value we are going to relocate. */
34563d8817e4Smiod if (1 == howto.size)
34573d8817e4Smiod value_to_relocate = bfd_get_16 (input_bfd, location);
34583d8817e4Smiod else
34593d8817e4Smiod value_to_relocate = bfd_get_32 (input_bfd, location);
34603d8817e4Smiod
34613d8817e4Smiod /* overflow.
34623d8817e4Smiod
34633d8817e4Smiod FIXME: We may drop bits during the addition
34643d8817e4Smiod which we don't check for. We must either check at every single
34653d8817e4Smiod operation, which would be tedious, or we must do the computations
34663d8817e4Smiod in a type larger than bfd_vma, which would be inefficient. */
34673d8817e4Smiod
34683d8817e4Smiod if ((unsigned int) howto.complain_on_overflow
34693d8817e4Smiod >= XCOFF_MAX_COMPLAIN_OVERFLOW)
34703d8817e4Smiod abort ();
34713d8817e4Smiod
34723d8817e4Smiod if (((*xcoff_complain_overflow[howto.complain_on_overflow])
34733d8817e4Smiod (input_bfd, value_to_relocate, relocation, &howto)))
34743d8817e4Smiod {
34753d8817e4Smiod const char *name;
34763d8817e4Smiod char buf[SYMNMLEN + 1];
34773d8817e4Smiod char reloc_type_name[10];
34783d8817e4Smiod
34793d8817e4Smiod if (symndx == -1)
34803d8817e4Smiod {
34813d8817e4Smiod name = "*ABS*";
34823d8817e4Smiod }
34833d8817e4Smiod else if (h != NULL)
34843d8817e4Smiod {
34853d8817e4Smiod name = NULL;
34863d8817e4Smiod }
34873d8817e4Smiod else
34883d8817e4Smiod {
34893d8817e4Smiod name = _bfd_coff_internal_syment_name (input_bfd, sym, buf);
34903d8817e4Smiod if (name == NULL)
34913d8817e4Smiod name = "UNKNOWN";
34923d8817e4Smiod }
34933d8817e4Smiod sprintf (reloc_type_name, "0x%02x", rel->r_type);
34943d8817e4Smiod
34953d8817e4Smiod if (! ((*info->callbacks->reloc_overflow)
34963d8817e4Smiod (info, (h ? &h->root : NULL), name, reloc_type_name,
34973d8817e4Smiod (bfd_vma) 0, input_bfd, input_section,
34983d8817e4Smiod rel->r_vaddr - input_section->vma)))
34993d8817e4Smiod return FALSE;
35003d8817e4Smiod }
35013d8817e4Smiod
35023d8817e4Smiod /* Add RELOCATION to the right bits of VALUE_TO_RELOCATE. */
35033d8817e4Smiod value_to_relocate = ((value_to_relocate & ~howto.dst_mask)
35043d8817e4Smiod | (((value_to_relocate & howto.src_mask)
35053d8817e4Smiod + relocation) & howto.dst_mask));
35063d8817e4Smiod
35073d8817e4Smiod /* Put the value back in the object file. */
35083d8817e4Smiod if (1 == howto.size)
35093d8817e4Smiod bfd_put_16 (input_bfd, value_to_relocate, location);
35103d8817e4Smiod else
35113d8817e4Smiod bfd_put_32 (input_bfd, value_to_relocate, location);
35123d8817e4Smiod }
35133d8817e4Smiod
35143d8817e4Smiod return TRUE;
35153d8817e4Smiod }
35163d8817e4Smiod
35173d8817e4Smiod static bfd_boolean
_bfd_xcoff_put_ldsymbol_name(abfd,ldinfo,ldsym,name)35183d8817e4Smiod _bfd_xcoff_put_ldsymbol_name (abfd, ldinfo, ldsym, name)
35193d8817e4Smiod bfd *abfd ATTRIBUTE_UNUSED;
35203d8817e4Smiod struct xcoff_loader_info *ldinfo;
35213d8817e4Smiod struct internal_ldsym *ldsym;
35223d8817e4Smiod const char *name;
35233d8817e4Smiod {
35243d8817e4Smiod size_t len;
35253d8817e4Smiod len = strlen (name);
35263d8817e4Smiod
35273d8817e4Smiod if (len <= SYMNMLEN)
35283d8817e4Smiod strncpy (ldsym->_l._l_name, name, SYMNMLEN);
35293d8817e4Smiod else
35303d8817e4Smiod {
35313d8817e4Smiod if (ldinfo->string_size + len + 3 > ldinfo->string_alc)
35323d8817e4Smiod {
35333d8817e4Smiod bfd_size_type newalc;
35343d8817e4Smiod char *newstrings;
35353d8817e4Smiod
35363d8817e4Smiod newalc = ldinfo->string_alc * 2;
35373d8817e4Smiod if (newalc == 0)
35383d8817e4Smiod newalc = 32;
35393d8817e4Smiod while (ldinfo->string_size + len + 3 > newalc)
35403d8817e4Smiod newalc *= 2;
35413d8817e4Smiod
35423d8817e4Smiod newstrings = bfd_realloc (ldinfo->strings, newalc);
35433d8817e4Smiod if (newstrings == NULL)
35443d8817e4Smiod {
35453d8817e4Smiod ldinfo->failed = TRUE;
35463d8817e4Smiod return FALSE;
35473d8817e4Smiod }
35483d8817e4Smiod ldinfo->string_alc = newalc;
35493d8817e4Smiod ldinfo->strings = newstrings;
35503d8817e4Smiod }
35513d8817e4Smiod
35523d8817e4Smiod bfd_put_16 (ldinfo->output_bfd, (bfd_vma) (len + 1),
35533d8817e4Smiod ldinfo->strings + ldinfo->string_size);
35543d8817e4Smiod strcpy (ldinfo->strings + ldinfo->string_size + 2, name);
35553d8817e4Smiod ldsym->_l._l_l._l_zeroes = 0;
35563d8817e4Smiod ldsym->_l._l_l._l_offset = ldinfo->string_size + 2;
35573d8817e4Smiod ldinfo->string_size += len + 3;
35583d8817e4Smiod }
35593d8817e4Smiod
35603d8817e4Smiod return TRUE;
35613d8817e4Smiod }
35623d8817e4Smiod
35633d8817e4Smiod static bfd_boolean
_bfd_xcoff_put_symbol_name(bfd * abfd,struct bfd_strtab_hash * strtab,struct internal_syment * sym,const char * name)35643d8817e4Smiod _bfd_xcoff_put_symbol_name (bfd *abfd, struct bfd_strtab_hash *strtab,
35653d8817e4Smiod struct internal_syment *sym,
35663d8817e4Smiod const char *name)
35673d8817e4Smiod {
35683d8817e4Smiod if (strlen (name) <= SYMNMLEN)
35693d8817e4Smiod {
35703d8817e4Smiod strncpy (sym->_n._n_name, name, SYMNMLEN);
35713d8817e4Smiod }
35723d8817e4Smiod else
35733d8817e4Smiod {
35743d8817e4Smiod bfd_boolean hash;
35753d8817e4Smiod bfd_size_type indx;
35763d8817e4Smiod
35773d8817e4Smiod hash = TRUE;
35783d8817e4Smiod if ((abfd->flags & BFD_TRADITIONAL_FORMAT) != 0)
35793d8817e4Smiod hash = FALSE;
35803d8817e4Smiod indx = _bfd_stringtab_add (strtab, name, hash, FALSE);
35813d8817e4Smiod if (indx == (bfd_size_type) -1)
35823d8817e4Smiod return FALSE;
35833d8817e4Smiod sym->_n._n_n._n_zeroes = 0;
35843d8817e4Smiod sym->_n._n_n._n_offset = STRING_SIZE_SIZE + indx;
35853d8817e4Smiod }
35863d8817e4Smiod return TRUE;
35873d8817e4Smiod }
35883d8817e4Smiod
35893d8817e4Smiod static asection *
xcoff_create_csect_from_smclas(abfd,aux,symbol_name)35903d8817e4Smiod xcoff_create_csect_from_smclas (abfd, aux, symbol_name)
35913d8817e4Smiod bfd *abfd;
35923d8817e4Smiod union internal_auxent *aux;
35933d8817e4Smiod const char *symbol_name;
35943d8817e4Smiod {
35953d8817e4Smiod asection *return_value = NULL;
35963d8817e4Smiod
35973d8817e4Smiod /* .sv64 = x_smclas == 17
35983d8817e4Smiod This is an invalid csect for 32 bit apps. */
35993d8817e4Smiod static const char *names[19] =
36003d8817e4Smiod {
36013d8817e4Smiod ".pr", ".ro", ".db", ".tc", ".ua", ".rw", ".gl", ".xo",
36023d8817e4Smiod ".sv", ".bs", ".ds", ".uc", ".ti", ".tb", NULL, ".tc0",
36033d8817e4Smiod ".td", NULL, ".sv3264"
36043d8817e4Smiod };
36053d8817e4Smiod
36063d8817e4Smiod if ((19 >= aux->x_csect.x_smclas)
36073d8817e4Smiod && (NULL != names[aux->x_csect.x_smclas]))
36083d8817e4Smiod {
36093d8817e4Smiod return_value = bfd_make_section_anyway
36103d8817e4Smiod (abfd, names[aux->x_csect.x_smclas]);
36113d8817e4Smiod }
36123d8817e4Smiod else
36133d8817e4Smiod {
36143d8817e4Smiod (*_bfd_error_handler)
36153d8817e4Smiod (_("%B: symbol `%s' has unrecognized smclas %d"),
36163d8817e4Smiod abfd, symbol_name, aux->x_csect.x_smclas);
36173d8817e4Smiod bfd_set_error (bfd_error_bad_value);
36183d8817e4Smiod }
36193d8817e4Smiod
36203d8817e4Smiod return return_value;
36213d8817e4Smiod }
36223d8817e4Smiod
36233d8817e4Smiod static bfd_boolean
xcoff_is_lineno_count_overflow(abfd,value)36243d8817e4Smiod xcoff_is_lineno_count_overflow (abfd, value)
36253d8817e4Smiod bfd *abfd ATTRIBUTE_UNUSED;
36263d8817e4Smiod bfd_vma value;
36273d8817e4Smiod {
36283d8817e4Smiod if (0xffff <= value)
36293d8817e4Smiod return TRUE;
36303d8817e4Smiod
36313d8817e4Smiod return FALSE;
36323d8817e4Smiod }
36333d8817e4Smiod
36343d8817e4Smiod static bfd_boolean
xcoff_is_reloc_count_overflow(abfd,value)36353d8817e4Smiod xcoff_is_reloc_count_overflow (abfd, value)
36363d8817e4Smiod bfd *abfd ATTRIBUTE_UNUSED;
36373d8817e4Smiod bfd_vma value;
36383d8817e4Smiod {
36393d8817e4Smiod if (0xffff <= value)
36403d8817e4Smiod return TRUE;
36413d8817e4Smiod
36423d8817e4Smiod return FALSE;
36433d8817e4Smiod }
36443d8817e4Smiod
36453d8817e4Smiod static bfd_vma
xcoff_loader_symbol_offset(abfd,ldhdr)36463d8817e4Smiod xcoff_loader_symbol_offset (abfd, ldhdr)
36473d8817e4Smiod bfd *abfd;
36483d8817e4Smiod struct internal_ldhdr *ldhdr ATTRIBUTE_UNUSED;
36493d8817e4Smiod {
36503d8817e4Smiod return bfd_xcoff_ldhdrsz (abfd);
36513d8817e4Smiod }
36523d8817e4Smiod
36533d8817e4Smiod static bfd_vma
xcoff_loader_reloc_offset(abfd,ldhdr)36543d8817e4Smiod xcoff_loader_reloc_offset (abfd, ldhdr)
36553d8817e4Smiod bfd *abfd;
36563d8817e4Smiod struct internal_ldhdr *ldhdr;
36573d8817e4Smiod {
36583d8817e4Smiod return bfd_xcoff_ldhdrsz (abfd) + ldhdr->l_nsyms * bfd_xcoff_ldsymsz (abfd);
36593d8817e4Smiod }
36603d8817e4Smiod
36613d8817e4Smiod static bfd_boolean
xcoff_generate_rtinit(abfd,init,fini,rtld)36623d8817e4Smiod xcoff_generate_rtinit (abfd, init, fini, rtld)
36633d8817e4Smiod bfd *abfd;
36643d8817e4Smiod const char *init;
36653d8817e4Smiod const char *fini;
36663d8817e4Smiod bfd_boolean rtld;
36673d8817e4Smiod {
36683d8817e4Smiod bfd_byte filehdr_ext[FILHSZ];
36693d8817e4Smiod bfd_byte scnhdr_ext[SCNHSZ];
36703d8817e4Smiod bfd_byte syment_ext[SYMESZ * 10];
36713d8817e4Smiod bfd_byte reloc_ext[RELSZ * 3];
36723d8817e4Smiod bfd_byte *data_buffer;
36733d8817e4Smiod bfd_size_type data_buffer_size;
36743d8817e4Smiod bfd_byte *string_table = NULL, *st_tmp = NULL;
36753d8817e4Smiod bfd_size_type string_table_size;
36763d8817e4Smiod bfd_vma val;
36773d8817e4Smiod size_t initsz, finisz;
36783d8817e4Smiod struct internal_filehdr filehdr;
36793d8817e4Smiod struct internal_scnhdr scnhdr;
36803d8817e4Smiod struct internal_syment syment;
36813d8817e4Smiod union internal_auxent auxent;
36823d8817e4Smiod struct internal_reloc reloc;
36833d8817e4Smiod
36843d8817e4Smiod char *data_name = ".data";
36853d8817e4Smiod char *rtinit_name = "__rtinit";
36863d8817e4Smiod char *rtld_name = "__rtld";
36873d8817e4Smiod
36883d8817e4Smiod if (! bfd_xcoff_rtinit_size (abfd))
36893d8817e4Smiod return FALSE;
36903d8817e4Smiod
36913d8817e4Smiod initsz = (init == NULL ? 0 : 1 + strlen (init));
36923d8817e4Smiod finisz = (fini == NULL ? 0 : 1 + strlen (fini));
36933d8817e4Smiod
36943d8817e4Smiod /* file header */
36953d8817e4Smiod memset (filehdr_ext, 0, FILHSZ);
36963d8817e4Smiod memset (&filehdr, 0, sizeof (struct internal_filehdr));
36973d8817e4Smiod filehdr.f_magic = bfd_xcoff_magic_number (abfd);
36983d8817e4Smiod filehdr.f_nscns = 1;
36993d8817e4Smiod filehdr.f_timdat = 0;
37003d8817e4Smiod filehdr.f_nsyms = 0; /* at least 6, no more than 10 */
37013d8817e4Smiod filehdr.f_symptr = 0; /* set below */
37023d8817e4Smiod filehdr.f_opthdr = 0;
37033d8817e4Smiod filehdr.f_flags = 0;
37043d8817e4Smiod
37053d8817e4Smiod /* section header */
37063d8817e4Smiod memset (scnhdr_ext, 0, SCNHSZ);
37073d8817e4Smiod memset (&scnhdr, 0, sizeof (struct internal_scnhdr));
37083d8817e4Smiod memcpy (scnhdr.s_name, data_name, strlen (data_name));
37093d8817e4Smiod scnhdr.s_paddr = 0;
37103d8817e4Smiod scnhdr.s_vaddr = 0;
37113d8817e4Smiod scnhdr.s_size = 0; /* set below */
37123d8817e4Smiod scnhdr.s_scnptr = FILHSZ + SCNHSZ;
37133d8817e4Smiod scnhdr.s_relptr = 0; /* set below */
37143d8817e4Smiod scnhdr.s_lnnoptr = 0;
37153d8817e4Smiod scnhdr.s_nreloc = 0; /* either 1 or 2 */
37163d8817e4Smiod scnhdr.s_nlnno = 0;
37173d8817e4Smiod scnhdr.s_flags = STYP_DATA;
37183d8817e4Smiod
37193d8817e4Smiod /* .data
37203d8817e4Smiod 0x0000 0x00000000 : rtl
37213d8817e4Smiod 0x0004 0x00000010 : offset to init, or 0
37223d8817e4Smiod 0x0008 0x00000028 : offset to fini, or 0
37233d8817e4Smiod 0x000C 0x0000000C : size of descriptor
37243d8817e4Smiod 0x0010 0x00000000 : init, needs a reloc
37253d8817e4Smiod 0x0014 0x00000040 : offset to init name
37263d8817e4Smiod 0x0018 0x00000000 : flags, padded to a word
37273d8817e4Smiod 0x001C 0x00000000 : empty init
37283d8817e4Smiod 0x0020 0x00000000 :
37293d8817e4Smiod 0x0024 0x00000000 :
37303d8817e4Smiod 0x0028 0x00000000 : fini, needs a reloc
37313d8817e4Smiod 0x002C 0x00000??? : offset to fini name
37323d8817e4Smiod 0x0030 0x00000000 : flags, padded to a word
37333d8817e4Smiod 0x0034 0x00000000 : empty fini
37343d8817e4Smiod 0x0038 0x00000000 :
37353d8817e4Smiod 0x003C 0x00000000 :
37363d8817e4Smiod 0x0040 init name
37373d8817e4Smiod 0x0040 + initsz fini name */
37383d8817e4Smiod
37393d8817e4Smiod data_buffer_size = 0x0040 + initsz + finisz;
37403d8817e4Smiod data_buffer_size = (data_buffer_size + 7) &~ (bfd_size_type) 7;
37413d8817e4Smiod data_buffer = NULL;
37423d8817e4Smiod data_buffer = (bfd_byte *) bfd_zmalloc (data_buffer_size);
37433d8817e4Smiod if (data_buffer == NULL)
37443d8817e4Smiod return FALSE;
37453d8817e4Smiod
37463d8817e4Smiod if (initsz)
37473d8817e4Smiod {
37483d8817e4Smiod val = 0x10;
37493d8817e4Smiod bfd_h_put_32 (abfd, val, &data_buffer[0x04]);
37503d8817e4Smiod val = 0x40;
37513d8817e4Smiod bfd_h_put_32 (abfd, val, &data_buffer[0x14]);
37523d8817e4Smiod memcpy (&data_buffer[val], init, initsz);
37533d8817e4Smiod }
37543d8817e4Smiod
37553d8817e4Smiod if (finisz)
37563d8817e4Smiod {
37573d8817e4Smiod val = 0x28;
37583d8817e4Smiod bfd_h_put_32 (abfd, val, &data_buffer[0x08]);
37593d8817e4Smiod val = 0x40 + initsz;
37603d8817e4Smiod bfd_h_put_32 (abfd, val, &data_buffer[0x2C]);
37613d8817e4Smiod memcpy (&data_buffer[val], fini, finisz);
37623d8817e4Smiod }
37633d8817e4Smiod
37643d8817e4Smiod val = 0x0C;
37653d8817e4Smiod bfd_h_put_32 (abfd, val, &data_buffer[0x0C]);
37663d8817e4Smiod
37673d8817e4Smiod scnhdr.s_size = data_buffer_size;
37683d8817e4Smiod
37693d8817e4Smiod /* string table */
37703d8817e4Smiod string_table_size = 0;
37713d8817e4Smiod if (initsz > 9)
37723d8817e4Smiod string_table_size += initsz;
37733d8817e4Smiod if (finisz > 9)
37743d8817e4Smiod string_table_size += finisz;
37753d8817e4Smiod if (string_table_size)
37763d8817e4Smiod {
37773d8817e4Smiod string_table_size += 4;
37783d8817e4Smiod string_table = (bfd_byte *) bfd_zmalloc (string_table_size);
37793d8817e4Smiod if (string_table == NULL)
37803d8817e4Smiod return FALSE;
37813d8817e4Smiod
37823d8817e4Smiod val = string_table_size;
37833d8817e4Smiod bfd_h_put_32 (abfd, val, &string_table[0]);
37843d8817e4Smiod st_tmp = string_table + 4;
37853d8817e4Smiod }
37863d8817e4Smiod
37873d8817e4Smiod /* symbols
37883d8817e4Smiod 0. .data csect
37893d8817e4Smiod 2. __rtinit
37903d8817e4Smiod 4. init function
37913d8817e4Smiod 6. fini function
37923d8817e4Smiod 8. __rtld */
37933d8817e4Smiod memset (syment_ext, 0, 10 * SYMESZ);
37943d8817e4Smiod memset (reloc_ext, 0, 3 * RELSZ);
37953d8817e4Smiod
37963d8817e4Smiod /* .data csect */
37973d8817e4Smiod memset (&syment, 0, sizeof (struct internal_syment));
37983d8817e4Smiod memset (&auxent, 0, sizeof (union internal_auxent));
37993d8817e4Smiod memcpy (syment._n._n_name, data_name, strlen (data_name));
38003d8817e4Smiod syment.n_scnum = 1;
38013d8817e4Smiod syment.n_sclass = C_HIDEXT;
38023d8817e4Smiod syment.n_numaux = 1;
38033d8817e4Smiod auxent.x_csect.x_scnlen.l = data_buffer_size;
38043d8817e4Smiod auxent.x_csect.x_smtyp = 3 << 3 | XTY_SD;
38053d8817e4Smiod auxent.x_csect.x_smclas = XMC_RW;
38063d8817e4Smiod bfd_coff_swap_sym_out (abfd, &syment,
38073d8817e4Smiod &syment_ext[filehdr.f_nsyms * SYMESZ]);
38083d8817e4Smiod bfd_coff_swap_aux_out (abfd, &auxent, syment.n_type, syment.n_sclass, 0,
38093d8817e4Smiod syment.n_numaux,
38103d8817e4Smiod &syment_ext[(filehdr.f_nsyms + 1) * SYMESZ]);
38113d8817e4Smiod filehdr.f_nsyms += 2;
38123d8817e4Smiod
38133d8817e4Smiod /* __rtinit */
38143d8817e4Smiod memset (&syment, 0, sizeof (struct internal_syment));
38153d8817e4Smiod memset (&auxent, 0, sizeof (union internal_auxent));
38163d8817e4Smiod memcpy (syment._n._n_name, rtinit_name, strlen (rtinit_name));
38173d8817e4Smiod syment.n_scnum = 1;
38183d8817e4Smiod syment.n_sclass = C_EXT;
38193d8817e4Smiod syment.n_numaux = 1;
38203d8817e4Smiod auxent.x_csect.x_smtyp = XTY_LD;
38213d8817e4Smiod auxent.x_csect.x_smclas = XMC_RW;
38223d8817e4Smiod bfd_coff_swap_sym_out (abfd, &syment,
38233d8817e4Smiod &syment_ext[filehdr.f_nsyms * SYMESZ]);
38243d8817e4Smiod bfd_coff_swap_aux_out (abfd, &auxent, syment.n_type, syment.n_sclass, 0,
38253d8817e4Smiod syment.n_numaux,
38263d8817e4Smiod &syment_ext[(filehdr.f_nsyms + 1) * SYMESZ]);
38273d8817e4Smiod filehdr.f_nsyms += 2;
38283d8817e4Smiod
38293d8817e4Smiod /* init */
38303d8817e4Smiod if (initsz)
38313d8817e4Smiod {
38323d8817e4Smiod memset (&syment, 0, sizeof (struct internal_syment));
38333d8817e4Smiod memset (&auxent, 0, sizeof (union internal_auxent));
38343d8817e4Smiod
38353d8817e4Smiod if (initsz > 9)
38363d8817e4Smiod {
38373d8817e4Smiod syment._n._n_n._n_offset = st_tmp - string_table;
38383d8817e4Smiod memcpy (st_tmp, init, initsz);
38393d8817e4Smiod st_tmp += initsz;
38403d8817e4Smiod }
38413d8817e4Smiod else
38423d8817e4Smiod memcpy (syment._n._n_name, init, initsz - 1);
38433d8817e4Smiod
38443d8817e4Smiod syment.n_sclass = C_EXT;
38453d8817e4Smiod syment.n_numaux = 1;
38463d8817e4Smiod bfd_coff_swap_sym_out (abfd, &syment,
38473d8817e4Smiod &syment_ext[filehdr.f_nsyms * SYMESZ]);
38483d8817e4Smiod bfd_coff_swap_aux_out (abfd, &auxent, syment.n_type, syment.n_sclass, 0,
38493d8817e4Smiod syment.n_numaux,
38503d8817e4Smiod &syment_ext[(filehdr.f_nsyms + 1) * SYMESZ]);
38513d8817e4Smiod
38523d8817e4Smiod /* reloc */
38533d8817e4Smiod memset (&reloc, 0, sizeof (struct internal_reloc));
38543d8817e4Smiod reloc.r_vaddr = 0x0010;
38553d8817e4Smiod reloc.r_symndx = filehdr.f_nsyms;
38563d8817e4Smiod reloc.r_type = R_POS;
38573d8817e4Smiod reloc.r_size = 31;
38583d8817e4Smiod bfd_coff_swap_reloc_out (abfd, &reloc, &reloc_ext[0]);
38593d8817e4Smiod
38603d8817e4Smiod filehdr.f_nsyms += 2;
38613d8817e4Smiod scnhdr.s_nreloc += 1;
38623d8817e4Smiod }
38633d8817e4Smiod
38643d8817e4Smiod /* fini */
38653d8817e4Smiod if (finisz)
38663d8817e4Smiod {
38673d8817e4Smiod memset (&syment, 0, sizeof (struct internal_syment));
38683d8817e4Smiod memset (&auxent, 0, sizeof (union internal_auxent));
38693d8817e4Smiod
38703d8817e4Smiod if (finisz > 9)
38713d8817e4Smiod {
38723d8817e4Smiod syment._n._n_n._n_offset = st_tmp - string_table;
38733d8817e4Smiod memcpy (st_tmp, fini, finisz);
38743d8817e4Smiod st_tmp += finisz;
38753d8817e4Smiod }
38763d8817e4Smiod else
38773d8817e4Smiod memcpy (syment._n._n_name, fini, finisz - 1);
38783d8817e4Smiod
38793d8817e4Smiod syment.n_sclass = C_EXT;
38803d8817e4Smiod syment.n_numaux = 1;
38813d8817e4Smiod bfd_coff_swap_sym_out (abfd, &syment,
38823d8817e4Smiod &syment_ext[filehdr.f_nsyms * SYMESZ]);
38833d8817e4Smiod bfd_coff_swap_aux_out (abfd, &auxent, syment.n_type, syment.n_sclass, 0,
38843d8817e4Smiod syment.n_numaux,
38853d8817e4Smiod &syment_ext[(filehdr.f_nsyms + 1) * SYMESZ]);
38863d8817e4Smiod
38873d8817e4Smiod /* reloc */
38883d8817e4Smiod memset (&reloc, 0, sizeof (struct internal_reloc));
38893d8817e4Smiod reloc.r_vaddr = 0x0028;
38903d8817e4Smiod reloc.r_symndx = filehdr.f_nsyms;
38913d8817e4Smiod reloc.r_type = R_POS;
38923d8817e4Smiod reloc.r_size = 31;
38933d8817e4Smiod bfd_coff_swap_reloc_out (abfd, &reloc,
38943d8817e4Smiod &reloc_ext[scnhdr.s_nreloc * RELSZ]);
38953d8817e4Smiod
38963d8817e4Smiod filehdr.f_nsyms += 2;
38973d8817e4Smiod scnhdr.s_nreloc += 1;
38983d8817e4Smiod }
38993d8817e4Smiod
39003d8817e4Smiod if (rtld)
39013d8817e4Smiod {
39023d8817e4Smiod memset (&syment, 0, sizeof (struct internal_syment));
39033d8817e4Smiod memset (&auxent, 0, sizeof (union internal_auxent));
39043d8817e4Smiod memcpy (syment._n._n_name, rtld_name, strlen (rtld_name));
39053d8817e4Smiod syment.n_sclass = C_EXT;
39063d8817e4Smiod syment.n_numaux = 1;
39073d8817e4Smiod bfd_coff_swap_sym_out (abfd, &syment,
39083d8817e4Smiod &syment_ext[filehdr.f_nsyms * SYMESZ]);
39093d8817e4Smiod bfd_coff_swap_aux_out (abfd, &auxent, syment.n_type, syment.n_sclass, 0,
39103d8817e4Smiod syment.n_numaux,
39113d8817e4Smiod &syment_ext[(filehdr.f_nsyms + 1) * SYMESZ]);
39123d8817e4Smiod
39133d8817e4Smiod /* reloc */
39143d8817e4Smiod memset (&reloc, 0, sizeof (struct internal_reloc));
39153d8817e4Smiod reloc.r_vaddr = 0x0000;
39163d8817e4Smiod reloc.r_symndx = filehdr.f_nsyms;
39173d8817e4Smiod reloc.r_type = R_POS;
39183d8817e4Smiod reloc.r_size = 31;
39193d8817e4Smiod bfd_coff_swap_reloc_out (abfd, &reloc,
39203d8817e4Smiod &reloc_ext[scnhdr.s_nreloc * RELSZ]);
39213d8817e4Smiod
39223d8817e4Smiod filehdr.f_nsyms += 2;
39233d8817e4Smiod scnhdr.s_nreloc += 1;
39243d8817e4Smiod }
39253d8817e4Smiod
39263d8817e4Smiod scnhdr.s_relptr = scnhdr.s_scnptr + data_buffer_size;
39273d8817e4Smiod filehdr.f_symptr = scnhdr.s_relptr + scnhdr.s_nreloc * RELSZ;
39283d8817e4Smiod
39293d8817e4Smiod bfd_coff_swap_filehdr_out (abfd, &filehdr, filehdr_ext);
39303d8817e4Smiod bfd_bwrite (filehdr_ext, FILHSZ, abfd);
39313d8817e4Smiod bfd_coff_swap_scnhdr_out (abfd, &scnhdr, scnhdr_ext);
39323d8817e4Smiod bfd_bwrite (scnhdr_ext, SCNHSZ, abfd);
39333d8817e4Smiod bfd_bwrite (data_buffer, data_buffer_size, abfd);
39343d8817e4Smiod bfd_bwrite (reloc_ext, scnhdr.s_nreloc * RELSZ, abfd);
39353d8817e4Smiod bfd_bwrite (syment_ext, filehdr.f_nsyms * SYMESZ, abfd);
39363d8817e4Smiod bfd_bwrite (string_table, string_table_size, abfd);
39373d8817e4Smiod
39383d8817e4Smiod free (data_buffer);
39393d8817e4Smiod data_buffer = NULL;
39403d8817e4Smiod
39413d8817e4Smiod return TRUE;
39423d8817e4Smiod }
39433d8817e4Smiod
39443d8817e4Smiod
39453d8817e4Smiod static reloc_howto_type xcoff_dynamic_reloc =
39463d8817e4Smiod HOWTO (0, /* type */
39473d8817e4Smiod 0, /* rightshift */
39483d8817e4Smiod 2, /* size (0 = byte, 1 = short, 2 = long) */
39493d8817e4Smiod 32, /* bitsize */
39503d8817e4Smiod FALSE, /* pc_relative */
39513d8817e4Smiod 0, /* bitpos */
39523d8817e4Smiod complain_overflow_bitfield, /* complain_on_overflow */
39533d8817e4Smiod 0, /* special_function */
39543d8817e4Smiod "R_POS", /* name */
39553d8817e4Smiod TRUE, /* partial_inplace */
39563d8817e4Smiod 0xffffffff, /* src_mask */
39573d8817e4Smiod 0xffffffff, /* dst_mask */
39583d8817e4Smiod FALSE); /* pcrel_offset */
39593d8817e4Smiod
39603d8817e4Smiod /* glink
39613d8817e4Smiod
39623d8817e4Smiod The first word of global linkage code must be modified by filling in
39633d8817e4Smiod the correct TOC offset. */
39643d8817e4Smiod
39653d8817e4Smiod static unsigned long xcoff_glink_code[9] =
39663d8817e4Smiod {
39673d8817e4Smiod 0x81820000, /* lwz r12,0(r2) */
39683d8817e4Smiod 0x90410014, /* stw r2,20(r1) */
39693d8817e4Smiod 0x800c0000, /* lwz r0,0(r12) */
39703d8817e4Smiod 0x804c0004, /* lwz r2,4(r12) */
39713d8817e4Smiod 0x7c0903a6, /* mtctr r0 */
39723d8817e4Smiod 0x4e800420, /* bctr */
39733d8817e4Smiod 0x00000000, /* start of traceback table */
39743d8817e4Smiod 0x000c8000, /* traceback table */
39753d8817e4Smiod 0x00000000, /* traceback table */
39763d8817e4Smiod };
39773d8817e4Smiod
39783d8817e4Smiod
39793d8817e4Smiod static const struct xcoff_backend_data_rec bfd_xcoff_backend_data =
39803d8817e4Smiod {
39813d8817e4Smiod { /* COFF backend, defined in libcoff.h. */
39823d8817e4Smiod _bfd_xcoff_swap_aux_in,
39833d8817e4Smiod _bfd_xcoff_swap_sym_in,
39843d8817e4Smiod coff_swap_lineno_in,
39853d8817e4Smiod _bfd_xcoff_swap_aux_out,
39863d8817e4Smiod _bfd_xcoff_swap_sym_out,
39873d8817e4Smiod coff_swap_lineno_out,
39883d8817e4Smiod xcoff_swap_reloc_out,
39893d8817e4Smiod coff_swap_filehdr_out,
39903d8817e4Smiod coff_swap_aouthdr_out,
39913d8817e4Smiod coff_swap_scnhdr_out,
39923d8817e4Smiod FILHSZ,
39933d8817e4Smiod AOUTSZ,
39943d8817e4Smiod SCNHSZ,
39953d8817e4Smiod SYMESZ,
39963d8817e4Smiod AUXESZ,
39973d8817e4Smiod RELSZ,
39983d8817e4Smiod LINESZ,
39993d8817e4Smiod FILNMLEN,
40003d8817e4Smiod TRUE, /* _bfd_coff_long_filenames */
40013d8817e4Smiod FALSE, /* _bfd_coff_long_section_names */
40023d8817e4Smiod 3, /* _bfd_coff_default_section_alignment_power */
40033d8817e4Smiod FALSE, /* _bfd_coff_force_symnames_in_strings */
40043d8817e4Smiod 2, /* _bfd_coff_debug_string_prefix_length */
40053d8817e4Smiod coff_swap_filehdr_in,
40063d8817e4Smiod coff_swap_aouthdr_in,
40073d8817e4Smiod coff_swap_scnhdr_in,
40083d8817e4Smiod xcoff_swap_reloc_in,
40093d8817e4Smiod coff_bad_format_hook,
40103d8817e4Smiod coff_set_arch_mach_hook,
40113d8817e4Smiod coff_mkobject_hook,
40123d8817e4Smiod styp_to_sec_flags,
40133d8817e4Smiod coff_set_alignment_hook,
40143d8817e4Smiod coff_slurp_symbol_table,
40153d8817e4Smiod symname_in_debug_hook,
40163d8817e4Smiod coff_pointerize_aux_hook,
40173d8817e4Smiod coff_print_aux,
40183d8817e4Smiod dummy_reloc16_extra_cases,
40193d8817e4Smiod dummy_reloc16_estimate,
40203d8817e4Smiod NULL, /* bfd_coff_sym_is_global */
40213d8817e4Smiod coff_compute_section_file_positions,
40223d8817e4Smiod NULL, /* _bfd_coff_start_final_link */
40233d8817e4Smiod xcoff_ppc_relocate_section,
40243d8817e4Smiod coff_rtype_to_howto,
40253d8817e4Smiod NULL, /* _bfd_coff_adjust_symndx */
40263d8817e4Smiod _bfd_generic_link_add_one_symbol,
40273d8817e4Smiod coff_link_output_has_begun,
40283d8817e4Smiod coff_final_link_postscript
40293d8817e4Smiod },
40303d8817e4Smiod
40313d8817e4Smiod 0x01DF, /* magic number */
40323d8817e4Smiod bfd_arch_rs6000,
40333d8817e4Smiod bfd_mach_rs6k,
40343d8817e4Smiod
40353d8817e4Smiod /* Function pointers to xcoff specific swap routines. */
40363d8817e4Smiod xcoff_swap_ldhdr_in,
40373d8817e4Smiod xcoff_swap_ldhdr_out,
40383d8817e4Smiod xcoff_swap_ldsym_in,
40393d8817e4Smiod xcoff_swap_ldsym_out,
40403d8817e4Smiod xcoff_swap_ldrel_in,
40413d8817e4Smiod xcoff_swap_ldrel_out,
40423d8817e4Smiod
40433d8817e4Smiod /* Sizes. */
40443d8817e4Smiod LDHDRSZ,
40453d8817e4Smiod LDSYMSZ,
40463d8817e4Smiod LDRELSZ,
40473d8817e4Smiod 12, /* _xcoff_function_descriptor_size */
40483d8817e4Smiod SMALL_AOUTSZ,
40493d8817e4Smiod
40503d8817e4Smiod /* Versions. */
40513d8817e4Smiod 1, /* _xcoff_ldhdr_version */
40523d8817e4Smiod
40533d8817e4Smiod _bfd_xcoff_put_symbol_name,
40543d8817e4Smiod _bfd_xcoff_put_ldsymbol_name,
40553d8817e4Smiod &xcoff_dynamic_reloc,
40563d8817e4Smiod xcoff_create_csect_from_smclas,
40573d8817e4Smiod
40583d8817e4Smiod /* Lineno and reloc count overflow. */
40593d8817e4Smiod xcoff_is_lineno_count_overflow,
40603d8817e4Smiod xcoff_is_reloc_count_overflow,
40613d8817e4Smiod
40623d8817e4Smiod xcoff_loader_symbol_offset,
40633d8817e4Smiod xcoff_loader_reloc_offset,
40643d8817e4Smiod
40653d8817e4Smiod /* glink. */
40663d8817e4Smiod &xcoff_glink_code[0],
40673d8817e4Smiod 36, /* _xcoff_glink_size */
40683d8817e4Smiod
40693d8817e4Smiod /* rtinit */
40703d8817e4Smiod 64, /* _xcoff_rtinit_size */
40713d8817e4Smiod xcoff_generate_rtinit,
40723d8817e4Smiod };
40733d8817e4Smiod
40743d8817e4Smiod /* The transfer vector that leads the outside world to all of the above. */
40753d8817e4Smiod const bfd_target rs6000coff_vec =
40763d8817e4Smiod {
40773d8817e4Smiod "aixcoff-rs6000",
40783d8817e4Smiod bfd_target_xcoff_flavour,
40793d8817e4Smiod BFD_ENDIAN_BIG, /* data byte order is big */
40803d8817e4Smiod BFD_ENDIAN_BIG, /* header byte order is big */
40813d8817e4Smiod
40823d8817e4Smiod (HAS_RELOC | EXEC_P | HAS_LINENO | HAS_DEBUG | DYNAMIC
40833d8817e4Smiod | HAS_SYMS | HAS_LOCALS | WP_TEXT),
40843d8817e4Smiod
40853d8817e4Smiod SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_CODE | SEC_DATA,
40863d8817e4Smiod 0, /* leading char */
40873d8817e4Smiod '/', /* ar_pad_char */
40883d8817e4Smiod 15, /* ar_max_namelen */
40893d8817e4Smiod
40903d8817e4Smiod /* data */
40913d8817e4Smiod bfd_getb64,
40923d8817e4Smiod bfd_getb_signed_64,
40933d8817e4Smiod bfd_putb64,
40943d8817e4Smiod bfd_getb32,
40953d8817e4Smiod bfd_getb_signed_32,
40963d8817e4Smiod bfd_putb32,
40973d8817e4Smiod bfd_getb16,
40983d8817e4Smiod bfd_getb_signed_16,
40993d8817e4Smiod bfd_putb16,
41003d8817e4Smiod
41013d8817e4Smiod /* hdrs */
41023d8817e4Smiod bfd_getb64,
41033d8817e4Smiod bfd_getb_signed_64,
41043d8817e4Smiod bfd_putb64,
41053d8817e4Smiod bfd_getb32,
41063d8817e4Smiod bfd_getb_signed_32,
41073d8817e4Smiod bfd_putb32,
41083d8817e4Smiod bfd_getb16,
41093d8817e4Smiod bfd_getb_signed_16,
41103d8817e4Smiod bfd_putb16,
41113d8817e4Smiod
41123d8817e4Smiod { /* bfd_check_format */
41133d8817e4Smiod _bfd_dummy_target,
41143d8817e4Smiod coff_object_p,
41153d8817e4Smiod _bfd_xcoff_archive_p,
41163d8817e4Smiod CORE_FILE_P
41173d8817e4Smiod },
41183d8817e4Smiod
41193d8817e4Smiod { /* bfd_set_format */
41203d8817e4Smiod bfd_false,
41213d8817e4Smiod coff_mkobject,
41223d8817e4Smiod _bfd_generic_mkarchive,
41233d8817e4Smiod bfd_false
41243d8817e4Smiod },
41253d8817e4Smiod
41263d8817e4Smiod {/* bfd_write_contents */
41273d8817e4Smiod bfd_false,
41283d8817e4Smiod coff_write_object_contents,
41293d8817e4Smiod _bfd_xcoff_write_archive_contents,
41303d8817e4Smiod bfd_false
41313d8817e4Smiod },
41323d8817e4Smiod
41333d8817e4Smiod /* Generic */
41343d8817e4Smiod bfd_true,
41353d8817e4Smiod bfd_true,
41363d8817e4Smiod coff_new_section_hook,
41373d8817e4Smiod _bfd_generic_get_section_contents,
41383d8817e4Smiod _bfd_generic_get_section_contents_in_window,
41393d8817e4Smiod
41403d8817e4Smiod /* Copy */
41413d8817e4Smiod _bfd_xcoff_copy_private_bfd_data,
41423d8817e4Smiod ((bfd_boolean (*) (bfd *, bfd *)) bfd_true),
41433d8817e4Smiod _bfd_generic_init_private_section_data,
41443d8817e4Smiod ((bfd_boolean (*) (bfd *, asection *, bfd *, asection *)) bfd_true),
41453d8817e4Smiod ((bfd_boolean (*) (bfd *, asymbol *, bfd *, asymbol *)) bfd_true),
41463d8817e4Smiod ((bfd_boolean (*) (bfd *, bfd *)) bfd_true),
41473d8817e4Smiod ((bfd_boolean (*) (bfd *, flagword)) bfd_true),
41483d8817e4Smiod ((bfd_boolean (*) (bfd *, void * )) bfd_true),
41493d8817e4Smiod
41503d8817e4Smiod /* Core */
41513d8817e4Smiod coff_core_file_failing_command,
41523d8817e4Smiod coff_core_file_failing_signal,
41533d8817e4Smiod coff_core_file_matches_executable_p,
41543d8817e4Smiod
41553d8817e4Smiod /* Archive */
41563d8817e4Smiod _bfd_xcoff_slurp_armap,
41573d8817e4Smiod bfd_false,
41583d8817e4Smiod ((bfd_boolean (*) (bfd *, char **, bfd_size_type *, const char **)) bfd_false),
41593d8817e4Smiod bfd_dont_truncate_arname,
41603d8817e4Smiod _bfd_xcoff_write_armap,
41613d8817e4Smiod _bfd_xcoff_read_ar_hdr,
41623d8817e4Smiod _bfd_xcoff_openr_next_archived_file,
41633d8817e4Smiod _bfd_generic_get_elt_at_index,
41643d8817e4Smiod _bfd_xcoff_stat_arch_elt,
41653d8817e4Smiod bfd_true,
41663d8817e4Smiod
41673d8817e4Smiod /* Symbols */
41683d8817e4Smiod coff_get_symtab_upper_bound,
41693d8817e4Smiod coff_canonicalize_symtab,
41703d8817e4Smiod coff_make_empty_symbol,
41713d8817e4Smiod coff_print_symbol,
41723d8817e4Smiod coff_get_symbol_info,
41733d8817e4Smiod _bfd_xcoff_is_local_label_name,
41743d8817e4Smiod coff_bfd_is_target_special_symbol,
41753d8817e4Smiod coff_get_lineno,
41763d8817e4Smiod coff_find_nearest_line,
41773d8817e4Smiod _bfd_generic_find_line,
41783d8817e4Smiod coff_find_inliner_info,
41793d8817e4Smiod coff_bfd_make_debug_symbol,
41803d8817e4Smiod _bfd_generic_read_minisymbols,
41813d8817e4Smiod _bfd_generic_minisymbol_to_symbol,
41823d8817e4Smiod
41833d8817e4Smiod /* Reloc */
41843d8817e4Smiod coff_get_reloc_upper_bound,
41853d8817e4Smiod coff_canonicalize_reloc,
41863d8817e4Smiod _bfd_xcoff_reloc_type_lookup,
41873d8817e4Smiod
41883d8817e4Smiod /* Write */
41893d8817e4Smiod coff_set_arch_mach,
41903d8817e4Smiod coff_set_section_contents,
41913d8817e4Smiod
41923d8817e4Smiod /* Link */
41933d8817e4Smiod _bfd_xcoff_sizeof_headers,
41943d8817e4Smiod bfd_generic_get_relocated_section_contents,
41953d8817e4Smiod bfd_generic_relax_section,
41963d8817e4Smiod _bfd_xcoff_bfd_link_hash_table_create,
41973d8817e4Smiod _bfd_generic_link_hash_table_free,
41983d8817e4Smiod _bfd_xcoff_bfd_link_add_symbols,
41993d8817e4Smiod _bfd_generic_link_just_syms,
42003d8817e4Smiod _bfd_xcoff_bfd_final_link,
42013d8817e4Smiod _bfd_generic_link_split_section,
42023d8817e4Smiod bfd_generic_gc_sections,
42033d8817e4Smiod bfd_generic_merge_sections,
42043d8817e4Smiod bfd_generic_is_group_section,
42053d8817e4Smiod bfd_generic_discard_group,
42063d8817e4Smiod _bfd_generic_section_already_linked,
42073d8817e4Smiod
42083d8817e4Smiod /* Dynamic */
42093d8817e4Smiod _bfd_xcoff_get_dynamic_symtab_upper_bound,
42103d8817e4Smiod _bfd_xcoff_canonicalize_dynamic_symtab,
42113d8817e4Smiod _bfd_nodynamic_get_synthetic_symtab,
42123d8817e4Smiod _bfd_xcoff_get_dynamic_reloc_upper_bound,
42133d8817e4Smiod _bfd_xcoff_canonicalize_dynamic_reloc,
42143d8817e4Smiod
42153d8817e4Smiod /* Opposite endian version, none exists */
42163d8817e4Smiod NULL,
42173d8817e4Smiod
42183d8817e4Smiod (void *) &bfd_xcoff_backend_data,
42193d8817e4Smiod };
42203d8817e4Smiod
42213d8817e4Smiod /* xcoff-powermac target
42223d8817e4Smiod Old target.
42233d8817e4Smiod Only difference between this target and the rs6000 target is the
42243d8817e4Smiod the default architecture and machine type used in coffcode.h
42253d8817e4Smiod
42263d8817e4Smiod PowerPC Macs use the same magic numbers as RS/6000
42273d8817e4Smiod (because that's how they were bootstrapped originally),
42283d8817e4Smiod but they are always PowerPC architecture. */
42293d8817e4Smiod static const struct xcoff_backend_data_rec bfd_pmac_xcoff_backend_data =
42303d8817e4Smiod {
42313d8817e4Smiod { /* COFF backend, defined in libcoff.h. */
42323d8817e4Smiod _bfd_xcoff_swap_aux_in,
42333d8817e4Smiod _bfd_xcoff_swap_sym_in,
42343d8817e4Smiod coff_swap_lineno_in,
42353d8817e4Smiod _bfd_xcoff_swap_aux_out,
42363d8817e4Smiod _bfd_xcoff_swap_sym_out,
42373d8817e4Smiod coff_swap_lineno_out,
42383d8817e4Smiod xcoff_swap_reloc_out,
42393d8817e4Smiod coff_swap_filehdr_out,
42403d8817e4Smiod coff_swap_aouthdr_out,
42413d8817e4Smiod coff_swap_scnhdr_out,
42423d8817e4Smiod FILHSZ,
42433d8817e4Smiod AOUTSZ,
42443d8817e4Smiod SCNHSZ,
42453d8817e4Smiod SYMESZ,
42463d8817e4Smiod AUXESZ,
42473d8817e4Smiod RELSZ,
42483d8817e4Smiod LINESZ,
42493d8817e4Smiod FILNMLEN,
42503d8817e4Smiod TRUE, /* _bfd_coff_long_filenames */
42513d8817e4Smiod FALSE, /* _bfd_coff_long_section_names */
42523d8817e4Smiod 3, /* _bfd_coff_default_section_alignment_power */
42533d8817e4Smiod FALSE, /* _bfd_coff_force_symnames_in_strings */
42543d8817e4Smiod 2, /* _bfd_coff_debug_string_prefix_length */
42553d8817e4Smiod coff_swap_filehdr_in,
42563d8817e4Smiod coff_swap_aouthdr_in,
42573d8817e4Smiod coff_swap_scnhdr_in,
42583d8817e4Smiod xcoff_swap_reloc_in,
42593d8817e4Smiod coff_bad_format_hook,
42603d8817e4Smiod coff_set_arch_mach_hook,
42613d8817e4Smiod coff_mkobject_hook,
42623d8817e4Smiod styp_to_sec_flags,
42633d8817e4Smiod coff_set_alignment_hook,
42643d8817e4Smiod coff_slurp_symbol_table,
42653d8817e4Smiod symname_in_debug_hook,
42663d8817e4Smiod coff_pointerize_aux_hook,
42673d8817e4Smiod coff_print_aux,
42683d8817e4Smiod dummy_reloc16_extra_cases,
42693d8817e4Smiod dummy_reloc16_estimate,
42703d8817e4Smiod NULL, /* bfd_coff_sym_is_global */
42713d8817e4Smiod coff_compute_section_file_positions,
42723d8817e4Smiod NULL, /* _bfd_coff_start_final_link */
42733d8817e4Smiod xcoff_ppc_relocate_section,
42743d8817e4Smiod coff_rtype_to_howto,
42753d8817e4Smiod NULL, /* _bfd_coff_adjust_symndx */
42763d8817e4Smiod _bfd_generic_link_add_one_symbol,
42773d8817e4Smiod coff_link_output_has_begun,
42783d8817e4Smiod coff_final_link_postscript
42793d8817e4Smiod },
42803d8817e4Smiod
42813d8817e4Smiod 0x01DF, /* magic number */
42823d8817e4Smiod bfd_arch_powerpc,
42833d8817e4Smiod bfd_mach_ppc,
42843d8817e4Smiod
42853d8817e4Smiod /* Function pointers to xcoff specific swap routines. */
42863d8817e4Smiod xcoff_swap_ldhdr_in,
42873d8817e4Smiod xcoff_swap_ldhdr_out,
42883d8817e4Smiod xcoff_swap_ldsym_in,
42893d8817e4Smiod xcoff_swap_ldsym_out,
42903d8817e4Smiod xcoff_swap_ldrel_in,
42913d8817e4Smiod xcoff_swap_ldrel_out,
42923d8817e4Smiod
42933d8817e4Smiod /* Sizes. */
42943d8817e4Smiod LDHDRSZ,
42953d8817e4Smiod LDSYMSZ,
42963d8817e4Smiod LDRELSZ,
42973d8817e4Smiod 12, /* _xcoff_function_descriptor_size */
42983d8817e4Smiod SMALL_AOUTSZ,
42993d8817e4Smiod
43003d8817e4Smiod /* Versions. */
43013d8817e4Smiod 1, /* _xcoff_ldhdr_version */
43023d8817e4Smiod
43033d8817e4Smiod _bfd_xcoff_put_symbol_name,
43043d8817e4Smiod _bfd_xcoff_put_ldsymbol_name,
43053d8817e4Smiod &xcoff_dynamic_reloc,
43063d8817e4Smiod xcoff_create_csect_from_smclas,
43073d8817e4Smiod
43083d8817e4Smiod /* Lineno and reloc count overflow. */
43093d8817e4Smiod xcoff_is_lineno_count_overflow,
43103d8817e4Smiod xcoff_is_reloc_count_overflow,
43113d8817e4Smiod
43123d8817e4Smiod xcoff_loader_symbol_offset,
43133d8817e4Smiod xcoff_loader_reloc_offset,
43143d8817e4Smiod
43153d8817e4Smiod /* glink. */
43163d8817e4Smiod &xcoff_glink_code[0],
43173d8817e4Smiod 36, /* _xcoff_glink_size */
43183d8817e4Smiod
43193d8817e4Smiod /* rtinit */
43203d8817e4Smiod 0, /* _xcoff_rtinit_size */
43213d8817e4Smiod xcoff_generate_rtinit,
43223d8817e4Smiod };
43233d8817e4Smiod
43243d8817e4Smiod /* The transfer vector that leads the outside world to all of the above. */
43253d8817e4Smiod const bfd_target pmac_xcoff_vec =
43263d8817e4Smiod {
43273d8817e4Smiod "xcoff-powermac",
43283d8817e4Smiod bfd_target_xcoff_flavour,
43293d8817e4Smiod BFD_ENDIAN_BIG, /* data byte order is big */
43303d8817e4Smiod BFD_ENDIAN_BIG, /* header byte order is big */
43313d8817e4Smiod
43323d8817e4Smiod (HAS_RELOC | EXEC_P | HAS_LINENO | HAS_DEBUG | DYNAMIC
43333d8817e4Smiod | HAS_SYMS | HAS_LOCALS | WP_TEXT),
43343d8817e4Smiod
43353d8817e4Smiod SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_CODE | SEC_DATA,
43363d8817e4Smiod 0, /* leading char */
43373d8817e4Smiod '/', /* ar_pad_char */
43383d8817e4Smiod 15, /* ar_max_namelen */
43393d8817e4Smiod
43403d8817e4Smiod /* data */
43413d8817e4Smiod bfd_getb64,
43423d8817e4Smiod bfd_getb_signed_64,
43433d8817e4Smiod bfd_putb64,
43443d8817e4Smiod bfd_getb32,
43453d8817e4Smiod bfd_getb_signed_32,
43463d8817e4Smiod bfd_putb32,
43473d8817e4Smiod bfd_getb16,
43483d8817e4Smiod bfd_getb_signed_16,
43493d8817e4Smiod bfd_putb16,
43503d8817e4Smiod
43513d8817e4Smiod /* hdrs */
43523d8817e4Smiod bfd_getb64,
43533d8817e4Smiod bfd_getb_signed_64,
43543d8817e4Smiod bfd_putb64,
43553d8817e4Smiod bfd_getb32,
43563d8817e4Smiod bfd_getb_signed_32,
43573d8817e4Smiod bfd_putb32,
43583d8817e4Smiod bfd_getb16,
43593d8817e4Smiod bfd_getb_signed_16,
43603d8817e4Smiod bfd_putb16,
43613d8817e4Smiod
43623d8817e4Smiod { /* bfd_check_format */
43633d8817e4Smiod _bfd_dummy_target,
43643d8817e4Smiod coff_object_p,
43653d8817e4Smiod _bfd_xcoff_archive_p,
43663d8817e4Smiod CORE_FILE_P
43673d8817e4Smiod },
43683d8817e4Smiod
43693d8817e4Smiod { /* bfd_set_format */
43703d8817e4Smiod bfd_false,
43713d8817e4Smiod coff_mkobject,
43723d8817e4Smiod _bfd_generic_mkarchive,
43733d8817e4Smiod bfd_false
43743d8817e4Smiod },
43753d8817e4Smiod
43763d8817e4Smiod {/* bfd_write_contents */
43773d8817e4Smiod bfd_false,
43783d8817e4Smiod coff_write_object_contents,
43793d8817e4Smiod _bfd_xcoff_write_archive_contents,
43803d8817e4Smiod bfd_false
43813d8817e4Smiod },
43823d8817e4Smiod
43833d8817e4Smiod /* Generic */
43843d8817e4Smiod bfd_true,
43853d8817e4Smiod bfd_true,
43863d8817e4Smiod coff_new_section_hook,
43873d8817e4Smiod _bfd_generic_get_section_contents,
43883d8817e4Smiod _bfd_generic_get_section_contents_in_window,
43893d8817e4Smiod
43903d8817e4Smiod /* Copy */
43913d8817e4Smiod _bfd_xcoff_copy_private_bfd_data,
43923d8817e4Smiod ((bfd_boolean (*) (bfd *, bfd *)) bfd_true),
43933d8817e4Smiod _bfd_generic_init_private_section_data,
43943d8817e4Smiod ((bfd_boolean (*) (bfd *, asection *, bfd *, asection *)) bfd_true),
43953d8817e4Smiod ((bfd_boolean (*) (bfd *, asymbol *, bfd *, asymbol *)) bfd_true),
43963d8817e4Smiod ((bfd_boolean (*) (bfd *, bfd *)) bfd_true),
43973d8817e4Smiod ((bfd_boolean (*) (bfd *, flagword)) bfd_true),
43983d8817e4Smiod ((bfd_boolean (*) (bfd *, void * )) bfd_true),
43993d8817e4Smiod
44003d8817e4Smiod /* Core */
44013d8817e4Smiod coff_core_file_failing_command,
44023d8817e4Smiod coff_core_file_failing_signal,
44033d8817e4Smiod coff_core_file_matches_executable_p,
44043d8817e4Smiod
44053d8817e4Smiod /* Archive */
44063d8817e4Smiod _bfd_xcoff_slurp_armap,
44073d8817e4Smiod bfd_false,
44083d8817e4Smiod ((bfd_boolean (*) (bfd *, char **, bfd_size_type *, const char **)) bfd_false),
44093d8817e4Smiod bfd_dont_truncate_arname,
44103d8817e4Smiod _bfd_xcoff_write_armap,
44113d8817e4Smiod _bfd_xcoff_read_ar_hdr,
44123d8817e4Smiod _bfd_xcoff_openr_next_archived_file,
44133d8817e4Smiod _bfd_generic_get_elt_at_index,
44143d8817e4Smiod _bfd_xcoff_stat_arch_elt,
44153d8817e4Smiod bfd_true,
44163d8817e4Smiod
44173d8817e4Smiod /* Symbols */
44183d8817e4Smiod coff_get_symtab_upper_bound,
44193d8817e4Smiod coff_canonicalize_symtab,
44203d8817e4Smiod coff_make_empty_symbol,
44213d8817e4Smiod coff_print_symbol,
44223d8817e4Smiod coff_get_symbol_info,
44233d8817e4Smiod _bfd_xcoff_is_local_label_name,
44243d8817e4Smiod coff_bfd_is_target_special_symbol,
44253d8817e4Smiod coff_get_lineno,
44263d8817e4Smiod coff_find_nearest_line,
44273d8817e4Smiod _bfd_generic_find_line,
44283d8817e4Smiod coff_find_inliner_info,
44293d8817e4Smiod coff_bfd_make_debug_symbol,
44303d8817e4Smiod _bfd_generic_read_minisymbols,
44313d8817e4Smiod _bfd_generic_minisymbol_to_symbol,
44323d8817e4Smiod
44333d8817e4Smiod /* Reloc */
44343d8817e4Smiod coff_get_reloc_upper_bound,
44353d8817e4Smiod coff_canonicalize_reloc,
44363d8817e4Smiod _bfd_xcoff_reloc_type_lookup,
44373d8817e4Smiod
44383d8817e4Smiod /* Write */
44393d8817e4Smiod coff_set_arch_mach,
44403d8817e4Smiod coff_set_section_contents,
44413d8817e4Smiod
44423d8817e4Smiod /* Link */
44433d8817e4Smiod _bfd_xcoff_sizeof_headers,
44443d8817e4Smiod bfd_generic_get_relocated_section_contents,
44453d8817e4Smiod bfd_generic_relax_section,
44463d8817e4Smiod _bfd_xcoff_bfd_link_hash_table_create,
44473d8817e4Smiod _bfd_generic_link_hash_table_free,
44483d8817e4Smiod _bfd_xcoff_bfd_link_add_symbols,
44493d8817e4Smiod _bfd_generic_link_just_syms,
44503d8817e4Smiod _bfd_xcoff_bfd_final_link,
44513d8817e4Smiod _bfd_generic_link_split_section,
44523d8817e4Smiod bfd_generic_gc_sections,
44533d8817e4Smiod bfd_generic_merge_sections,
44543d8817e4Smiod bfd_generic_is_group_section,
44553d8817e4Smiod bfd_generic_discard_group,
44563d8817e4Smiod _bfd_generic_section_already_linked,
44573d8817e4Smiod
44583d8817e4Smiod /* Dynamic */
44593d8817e4Smiod _bfd_xcoff_get_dynamic_symtab_upper_bound,
44603d8817e4Smiod _bfd_xcoff_canonicalize_dynamic_symtab,
44613d8817e4Smiod _bfd_nodynamic_get_synthetic_symtab,
44623d8817e4Smiod _bfd_xcoff_get_dynamic_reloc_upper_bound,
44633d8817e4Smiod _bfd_xcoff_canonicalize_dynamic_reloc,
44643d8817e4Smiod
44653d8817e4Smiod /* Opposite endian version, none exists */
44663d8817e4Smiod NULL,
44673d8817e4Smiod
44683d8817e4Smiod (void *) &bfd_pmac_xcoff_backend_data,
44693d8817e4Smiod };
4470