1131722Sobrien/* BFD XCOFF object file private structure.
2218822Sdim   Copyright 2001, 2002, 2005 Free Software Foundation, Inc.
3131722Sobrien   Written by Tom Rix, Redhat.
4131722Sobrien
5131722Sobrien   This file is part of BFD, the Binary File Descriptor library.
6131722Sobrien
7131722Sobrien   This program is free software; you can redistribute it and/or modify
8131722Sobrien   it under the terms of the GNU General Public License as published by
9131722Sobrien   the Free Software Foundation; either version 2 of the License, or
10131722Sobrien   (at your option) any later version.
11131722Sobrien
12131722Sobrien   This program is distributed in the hope that it will be useful,
13131722Sobrien   but WITHOUT ANY WARRANTY; without even the implied warranty of
14131722Sobrien   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15131722Sobrien   GNU General Public License for more details.
16131722Sobrien
17131722Sobrien   You should have received a copy of the GNU General Public License
18131722Sobrien   along with this program; if not, write to the Free Software
19218822Sdim   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.  */
20131722Sobrien
21131722Sobrien#ifndef LIBXCOFF_H
22131722Sobrien#define LIBXCOFF_H
23131722Sobrien
24131722Sobrien/* This is the backend information kept for XCOFF files.  This
25131722Sobrien   structure is constant for a particular backend.  The first element
26131722Sobrien   is the COFF backend data structure, so that XCOFF targets can use
27131722Sobrien   the generic COFF code.  */
28131722Sobrien
29131722Sobrienstruct xcoff_backend_data_rec
30131722Sobrien{
31131722Sobrien  /* COFF backend information.  */
32131722Sobrien  bfd_coff_backend_data coff;
33131722Sobrien
34131722Sobrien  /* Magic number.  */
35131722Sobrien  unsigned short _xcoff_magic_number;
36131722Sobrien
37131722Sobrien  /* Architecture and machine for coff_set_arch_mach_hook.  */
38131722Sobrien  enum bfd_architecture _xcoff_architecture;
39131722Sobrien  long _xcoff_machine;
40131722Sobrien
41131722Sobrien  /* Function pointers to xcoff specific swap routines.  */
42218822Sdim  void (* _xcoff_swap_ldhdr_in) (bfd *, const void *, struct internal_ldhdr *);
43218822Sdim  void (* _xcoff_swap_ldhdr_out)(bfd *, const struct internal_ldhdr *, void *);
44218822Sdim  void (* _xcoff_swap_ldsym_in) (bfd *, const void *, struct internal_ldsym *);
45218822Sdim  void (* _xcoff_swap_ldsym_out)(bfd *, const struct internal_ldsym *, void *);
46218822Sdim  void (* _xcoff_swap_ldrel_in) (bfd *, const void *, struct internal_ldrel *);
47218822Sdim  void (* _xcoff_swap_ldrel_out)(bfd *, const struct internal_ldrel *, void *);
48131722Sobrien
49131722Sobrien  /* Size of the external struct.  */
50131722Sobrien  unsigned int _xcoff_ldhdrsz;
51131722Sobrien  unsigned int _xcoff_ldsymsz;
52131722Sobrien  unsigned int _xcoff_ldrelsz;
53131722Sobrien
54131722Sobrien  /* Size an entry in a descriptor section.  */
55131722Sobrien  unsigned int _xcoff_function_descriptor_size;
56131722Sobrien
57131722Sobrien  /* Size of the small aout file header.  */
58131722Sobrien  unsigned int _xcoff_small_aout_header_size;
59131722Sobrien
60131722Sobrien  /* Loader version
61131722Sobrien     1 : XCOFF32
62131722Sobrien     2 : XCOFF64.  */
63131722Sobrien  unsigned long _xcoff_ldhdr_version;
64131722Sobrien
65131722Sobrien  bfd_boolean (* _xcoff_put_symbol_name)
66218822Sdim    (bfd *, struct bfd_strtab_hash *, struct internal_syment *,
67218822Sdim     const char *);
68131722Sobrien
69131722Sobrien  bfd_boolean (* _xcoff_put_ldsymbol_name)
70218822Sdim    (bfd *, struct xcoff_loader_info *, struct internal_ldsym *,
71218822Sdim     const char *);
72131722Sobrien
73131722Sobrien  reloc_howto_type *_xcoff_dynamic_reloc;
74131722Sobrien
75131722Sobrien  asection * (* _xcoff_create_csect_from_smclas)
76218822Sdim    (bfd *, union internal_auxent *, const char *);
77131722Sobrien
78131722Sobrien  /* Line number and relocation overflow.
79131722Sobrien     XCOFF32 overflows to another section when the line number or the
80131722Sobrien     relocation count exceeds 0xffff.  XCOFF64 does not overflow.  */
81218822Sdim  bfd_boolean (*_xcoff_is_lineno_count_overflow) (bfd *, bfd_vma);
82218822Sdim  bfd_boolean (*_xcoff_is_reloc_count_overflow)  (bfd *, bfd_vma);
83131722Sobrien
84131722Sobrien  /* Loader section symbol and relocation table offset
85131722Sobrien     XCOFF32 is after the .loader header
86131722Sobrien     XCOFF64 is offset in .loader header.  */
87218822Sdim  bfd_vma (*_xcoff_loader_symbol_offset) (bfd *, struct internal_ldhdr *);
88218822Sdim  bfd_vma (*_xcoff_loader_reloc_offset)  (bfd *, struct internal_ldhdr *);
89131722Sobrien
90131722Sobrien  /* Global linkage.  The first word of global linkage code must be be
91131722Sobrien     modified by filling in the correct TOC offset.  */
92131722Sobrien  unsigned long *_xcoff_glink_code;
93131722Sobrien
94131722Sobrien  /* Size of the global link code in bytes of the xcoff_glink_code table.  */
95131722Sobrien  unsigned long _xcoff_glink_size;
96131722Sobrien
97131722Sobrien  /* rtinit.  */
98131722Sobrien  unsigned int _xcoff_rtinit_size;
99131722Sobrien  bfd_boolean (*_xcoff_generate_rtinit)
100218822Sdim    (bfd *, const char *, const char *, bfd_boolean);
101131722Sobrien};
102131722Sobrien
103131722Sobrien/* Look up an entry in an XCOFF link hash table.  */
104131722Sobrien#define xcoff_link_hash_lookup(table, string, create, copy, follow) \
105131722Sobrien  ((struct xcoff_link_hash_entry *) \
106131722Sobrien   bfd_link_hash_lookup (&(table)->root, (string), (create), (copy),\
107131722Sobrien			 (follow)))
108131722Sobrien
109131722Sobrien/* Traverse an XCOFF link hash table.  */
110131722Sobrien#define xcoff_link_hash_traverse(table, func, info)			\
111131722Sobrien  (bfd_link_hash_traverse						\
112131722Sobrien   (&(table)->root,							\
113218822Sdim    (bfd_boolean (*) (struct bfd_link_hash_entry *, void *)) (func),	\
114131722Sobrien    (info)))
115131722Sobrien
116131722Sobrien/* Get the XCOFF link hash table from the info structure.  This is
117131722Sobrien   just a cast.  */
118131722Sobrien#define xcoff_hash_table(p) ((struct xcoff_link_hash_table *) ((p)->hash))
119131722Sobrien
120131722Sobrien
121131722Sobrien#define xcoff_backend(abfd) \
122131722Sobrien  ((struct xcoff_backend_data_rec *) (abfd)->xvec->backend_data)
123131722Sobrien
124218822Sdim#define bfd_xcoff_magic_number(a) ((xcoff_backend (a)->_xcoff_magic_number))
125218822Sdim#define bfd_xcoff_architecture(a) ((xcoff_backend (a)->_xcoff_architecture))
126218822Sdim#define bfd_xcoff_machine(a)      ((xcoff_backend (a)->_xcoff_machine))
127131722Sobrien
128131722Sobrien#define bfd_xcoff_swap_ldhdr_in(a, b, c) \
129218822Sdim  ((xcoff_backend (a)->_xcoff_swap_ldhdr_in) ((a), (b), (c)))
130131722Sobrien
131131722Sobrien#define bfd_xcoff_swap_ldhdr_out(a, b, c) \
132218822Sdim  ((xcoff_backend (a)->_xcoff_swap_ldhdr_out) ((a), (b), (c)))
133131722Sobrien
134131722Sobrien#define bfd_xcoff_swap_ldsym_in(a, b, c) \
135218822Sdim  ((xcoff_backend (a)->_xcoff_swap_ldsym_in) ((a), (b), (c)))
136131722Sobrien
137131722Sobrien#define bfd_xcoff_swap_ldsym_out(a, b, c) \
138218822Sdim  ((xcoff_backend (a)->_xcoff_swap_ldsym_out) ((a), (b), (c)))
139131722Sobrien
140131722Sobrien#define bfd_xcoff_swap_ldrel_in(a, b, c) \
141218822Sdim  ((xcoff_backend (a)->_xcoff_swap_ldrel_in) ((a), (b), (c)))
142131722Sobrien
143131722Sobrien#define bfd_xcoff_swap_ldrel_out(a, b, c) \
144218822Sdim  ((xcoff_backend (a)->_xcoff_swap_ldrel_out) ((a), (b), (c)))
145131722Sobrien
146218822Sdim#define bfd_xcoff_ldhdrsz(a) ((xcoff_backend (a)->_xcoff_ldhdrsz))
147218822Sdim#define bfd_xcoff_ldsymsz(a) ((xcoff_backend (a)->_xcoff_ldsymsz))
148218822Sdim#define bfd_xcoff_ldrelsz(a) ((xcoff_backend (a)->_xcoff_ldrelsz))
149131722Sobrien#define bfd_xcoff_function_descriptor_size(a) \
150218822Sdim  ((xcoff_backend (a)->_xcoff_function_descriptor_size))
151131722Sobrien#define bfd_xcoff_small_aout_header_size(a) \
152218822Sdim  ((xcoff_backend (a)->_xcoff_small_aout_header_size))
153131722Sobrien
154218822Sdim#define bfd_xcoff_ldhdr_version(a) ((xcoff_backend (a)->_xcoff_ldhdr_version))
155131722Sobrien
156131722Sobrien#define bfd_xcoff_put_symbol_name(a, b, c, d) \
157218822Sdim  ((xcoff_backend (a)->_xcoff_put_symbol_name) ((a), (b), (c), (d)))
158131722Sobrien
159131722Sobrien#define bfd_xcoff_put_ldsymbol_name(a, b, c, d) \
160218822Sdim  ((xcoff_backend (a)->_xcoff_put_ldsymbol_name) ((a), (b), (c), (d)))
161131722Sobrien
162131722Sobrien/* Get the XCOFF hash table entries for a BFD.  */
163131722Sobrien#define obj_xcoff_sym_hashes(bfd) \
164131722Sobrien  ((struct xcoff_link_hash_entry **) obj_coff_sym_hashes (bfd))
165131722Sobrien
166131722Sobrien#define bfd_xcoff_dynamic_reloc_howto(a) \
167218822Sdim   ((xcoff_backend (a)->_xcoff_dynamic_reloc))
168131722Sobrien
169131722Sobrien#define bfd_xcoff_create_csect_from_smclas(a, b, c) \
170218822Sdim   ((xcoff_backend (a)->_xcoff_create_csect_from_smclas((a), (b), (c))))
171131722Sobrien
172131722Sobrien#define bfd_xcoff_is_lineno_count_overflow(a, b) \
173218822Sdim   ((xcoff_backend (a)->_xcoff_is_lineno_count_overflow((a), (b))))
174131722Sobrien
175131722Sobrien#define bfd_xcoff_is_reloc_count_overflow(a, b) \
176218822Sdim   ((xcoff_backend (a)->_xcoff_is_reloc_count_overflow((a), (b))))
177131722Sobrien
178131722Sobrien#define bfd_xcoff_loader_symbol_offset(a, b) \
179218822Sdim ((xcoff_backend (a)->_xcoff_loader_symbol_offset((a), (b))))
180131722Sobrien
181131722Sobrien#define bfd_xcoff_loader_reloc_offset(a, b) \
182218822Sdim ((xcoff_backend (a)->_xcoff_loader_reloc_offset((a), (b))))
183131722Sobrien
184218822Sdim#define bfd_xcoff_glink_code(a, b)   ((xcoff_backend (a)->_xcoff_glink_code[(b)]))
185218822Sdim#define bfd_xcoff_glink_code_size(a) ((xcoff_backend (a)->_xcoff_glink_size))
186131722Sobrien
187131722Sobrien/* Check for the magic number U803XTOCMAGIC or U64_TOCMAGIC for 64 bit
188131722Sobrien   targets.  */
189131722Sobrien#define bfd_xcoff_is_xcoff64(a) \
190218822Sdim  (   (0x01EF == (bfd_xcoff_magic_number (a))) \
191218822Sdim   || (0x01F7 == (bfd_xcoff_magic_number (a))))
192131722Sobrien
193131722Sobrien/* Check for the magic number U802TOMAGIC for 32 bit targets.  */
194218822Sdim#define bfd_xcoff_is_xcoff32(a) (0x01DF == (bfd_xcoff_magic_number (a)))
195131722Sobrien
196218822Sdim#define bfd_xcoff_rtinit_size(a)              ((xcoff_backend (a)->_xcoff_rtinit_size))
197218822Sdim#define bfd_xcoff_generate_rtinit(a, b, c, d) ((xcoff_backend (a)->_xcoff_generate_rtinit ((a), (b), (c), (d))))
198131722Sobrien
199131722Sobrien/* Accessor macros for tdata.  */
200131722Sobrien#define bfd_xcoff_text_align_power(a) ((xcoff_data (a)->text_align_power))
201131722Sobrien#define bfd_xcoff_data_align_power(a) ((xcoff_data (a)->data_align_power))
202131722Sobrien
203131722Sobrien/* xcoff*_ppc_relocate_section macros  */
204131722Sobrien#define XCOFF_MAX_CALCULATE_RELOCATION (0x1c)
205131722Sobrien#define XCOFF_MAX_COMPLAIN_OVERFLOW (4)
206131722Sobrien/* N_ONES produces N one bits, without overflowing machine arithmetic.  */
207131722Sobrien#ifdef N_ONES
208131722Sobrien#undef N_ONES
209131722Sobrien#endif
210131722Sobrien#define N_ONES(n) (((((bfd_vma) 1 << ((n) - 1)) - 1) << 1) | 1)
211131722Sobrien
212131722Sobrien#define XCOFF_RELOC_FUNCTION_ARGS \
213131722Sobrien  bfd *, asection *, bfd *, struct internal_reloc *, \
214131722Sobrien  struct internal_syment *, struct reloc_howto_struct *, bfd_vma, bfd_vma, \
215131722Sobrien  bfd_vma *relocation, bfd_byte *contents
216131722Sobrien
217131722Sobrien#define XCOFF_COMPLAIN_FUNCTION_ARGS \
218131722Sobrien  bfd *, bfd_vma, bfd_vma, struct reloc_howto_struct *howto
219131722Sobrien
220131722Sobrienextern bfd_boolean (*xcoff_calculate_relocation[XCOFF_MAX_CALCULATE_RELOCATION])
221218822Sdim  (XCOFF_RELOC_FUNCTION_ARGS);
222131722Sobrienextern bfd_boolean (*xcoff_complain_overflow[XCOFF_MAX_COMPLAIN_OVERFLOW])
223218822Sdim  (XCOFF_COMPLAIN_FUNCTION_ARGS);
224131722Sobrien
225131722Sobrien/* Relocation functions */
226218822Sdimbfd_boolean xcoff_reloc_type_noop (XCOFF_RELOC_FUNCTION_ARGS);
227218822Sdimbfd_boolean xcoff_reloc_type_fail (XCOFF_RELOC_FUNCTION_ARGS);
228218822Sdimbfd_boolean xcoff_reloc_type_pos  (XCOFF_RELOC_FUNCTION_ARGS);
229218822Sdimbfd_boolean xcoff_reloc_type_neg  (XCOFF_RELOC_FUNCTION_ARGS);
230218822Sdimbfd_boolean xcoff_reloc_type_rel  (XCOFF_RELOC_FUNCTION_ARGS);
231218822Sdimbfd_boolean xcoff_reloc_type_toc  (XCOFF_RELOC_FUNCTION_ARGS);
232218822Sdimbfd_boolean xcoff_reloc_type_ba   (XCOFF_RELOC_FUNCTION_ARGS);
233218822Sdimbfd_boolean xcoff_reloc_type_crel (XCOFF_RELOC_FUNCTION_ARGS);
234131722Sobrien
235131722Sobrien#endif /* LIBXCOFF_H */
236