added coff-sparc.c to CFILES, rebuilt dependencies
[deliverable/binutils-gdb.git] / bfd / coff-alpha.c
1 /* BFD back-end for ALPHA Extended-Coff files.
2 Copyright 1993 Free Software Foundation, Inc.
3 Modified from coff-mips.c by Steve Chamberlain <sac@cygnus.com> and
4 Ian Lance Taylor <ian@cygnus.com>.
5
6 This file is part of BFD, the Binary File Descriptor library.
7
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
12
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
21
22 #include "bfd.h"
23 #include "sysdep.h"
24 #include "libbfd.h"
25 #include "seclet.h"
26 #include "coff/internal.h"
27 #include "coff/sym.h"
28 #include "coff/symconst.h"
29 #include "coff/ecoff.h"
30 #include "coff/alpha.h"
31 #include "libcoff.h"
32 #include "libecoff.h"
33 \f
34 /* Prototypes for static functions. */
35
36 static boolean alpha_ecoff_bad_format_hook PARAMS ((bfd *abfd, PTR filehdr));
37 static PTR alpha_ecoff_mkobject_hook PARAMS ((bfd *abfd, PTR filehdr,
38 PTR aouthdr));
39 static void alpha_ecoff_swap_reloc_in PARAMS ((bfd *, PTR,
40 struct internal_reloc *));
41 static void alpha_ecoff_swap_reloc_out PARAMS ((bfd *,
42 const struct internal_reloc *,
43 PTR));
44 \f
45
46 /* ECOFF has COFF sections, but the debugging information is stored in
47 a completely different format. ECOFF targets use some of the
48 swapping routines from coffswap.h, and some of the generic COFF
49 routines in coffgen.c, but, unlike the real COFF targets, do not
50 use coffcode.h itself.
51
52 Get the generic COFF swapping routines, except for the reloc,
53 symbol, and lineno ones. Give them ecoff names. */
54 #define ALPHAECOFF
55 #define NO_COFF_RELOCS
56 #define NO_COFF_SYMBOLS
57 #define NO_COFF_LINENOS
58 #define coff_swap_filehdr_in alpha_ecoff_swap_filehdr_in
59 #define coff_swap_filehdr_out alpha_ecoff_swap_filehdr_out
60 #define coff_swap_aouthdr_in alpha_ecoff_swap_aouthdr_in
61 #define coff_swap_aouthdr_out alpha_ecoff_swap_aouthdr_out
62 #define coff_swap_scnhdr_in alpha_ecoff_swap_scnhdr_in
63 #define coff_swap_scnhdr_out alpha_ecoff_swap_scnhdr_out
64 #include "coffswap.h"
65
66 /* Get the ECOFF swapping routines. */
67 #define ECOFF_64
68 #include "ecoffswap.h"
69 \f
70 /* This is the ECOFF backend structure. The backend_data field of the
71 ecoff_tdata structure is set to this when an ECOFF BFD is
72 initialized. This is used by the generic ECOFF routines. */
73
74 static const struct ecoff_backend_data alpha_ecoff_backend_data =
75 {
76 /* Supported architecture. */
77 bfd_arch_alpha,
78 /* Big endian magic number. */
79 0,
80 /* Little endian magic number. */
81 ALPHA_MAGIC,
82 /* Alignment of debugging information. E.g., 4. */
83 8,
84 /* The page boundary used to align sections in a demand-paged
85 executable file. E.g., 0x1000. */
86 0x10000,
87 /* Bitsize of constructor entries. */
88 64,
89 /* Sizes of external symbolic information. */
90 sizeof (struct hdr_ext),
91 sizeof (struct dnr_ext),
92 sizeof (struct pdr_ext),
93 sizeof (struct sym_ext),
94 sizeof (struct opt_ext),
95 sizeof (struct fdr_ext),
96 sizeof (struct rfd_ext),
97 sizeof (struct ext_ext),
98 /* Functions to swap in external symbolic data. */
99 ecoff_swap_hdr_in,
100 ecoff_swap_dnr_in,
101 ecoff_swap_pdr_in,
102 ecoff_swap_sym_in,
103 ecoff_swap_opt_in,
104 ecoff_swap_fdr_in,
105 ecoff_swap_rfd_in,
106 ecoff_swap_ext_in,
107 /* Functions to swap out external symbolic data. */
108 ecoff_swap_hdr_out,
109 ecoff_swap_dnr_out,
110 ecoff_swap_pdr_out,
111 ecoff_swap_sym_out,
112 ecoff_swap_opt_out,
113 ecoff_swap_fdr_out,
114 ecoff_swap_rfd_out,
115 ecoff_swap_ext_out,
116 /* External reloc size. */
117 RELSZ,
118 /* Reloc swapping functions. */
119 alpha_ecoff_swap_reloc_in,
120 alpha_ecoff_swap_reloc_out
121 };
122 \f
123 /* See whether the magic number matches. */
124
125 static boolean
126 alpha_ecoff_bad_format_hook (abfd, filehdr)
127 bfd *abfd;
128 PTR filehdr;
129 {
130 struct internal_filehdr *internal_f = (struct internal_filehdr *) filehdr;
131
132 if (ALPHA_ECOFF_BADMAG (*internal_f))
133 return false;
134
135 return true;
136 }
137
138 /* Create an ECOFF object. */
139
140 static boolean
141 alpha_ecoff_mkobject (abfd)
142 bfd *abfd;
143 {
144 abfd->tdata.ecoff_obj_data = ((struct ecoff_tdata *)
145 bfd_zalloc (abfd, sizeof (ecoff_data_type)));
146 if (abfd->tdata.ecoff_obj_data == NULL)
147 {
148 bfd_error = no_memory;
149 return false;
150 }
151
152 ecoff_data (abfd)->backend_data = &alpha_ecoff_backend_data;
153
154 /* Always create a .scommon section for every BFD. This is a hack so
155 that the linker has something to attach scSCommon symbols to. */
156 bfd_make_section (abfd, SCOMMON);
157
158 return true;
159 }
160
161 /* Create the MIPS ECOFF backend specific information. */
162
163 static PTR
164 alpha_ecoff_mkobject_hook (abfd, filehdr, aouthdr)
165 bfd *abfd;
166 PTR filehdr;
167 PTR aouthdr;
168 {
169 struct internal_filehdr *internal_f = (struct internal_filehdr *) filehdr;
170 struct internal_aouthdr *internal_a = (struct internal_aouthdr *) aouthdr;
171 ecoff_data_type *ecoff;
172
173 if (alpha_ecoff_mkobject (abfd) == false)
174 return NULL;
175
176 ecoff = ecoff_data (abfd);
177 ecoff->gp_size = 8;
178 ecoff->sym_filepos = internal_f->f_symptr;
179
180 if (internal_a != (struct internal_aouthdr *) NULL)
181 {
182 int i;
183
184 ecoff->text_start = internal_a->text_start;
185 ecoff->text_end = internal_a->text_start + internal_a->tsize;
186 ecoff->gp = internal_a->gp_value;
187 ecoff->gprmask = internal_a->gprmask;
188 for (i = 0; i < 4; i++)
189 ecoff->cprmask[i] = internal_a->cprmask[i];
190 if (internal_a->magic == ECOFF_AOUT_ZMAGIC)
191 abfd->flags |= D_PAGED;
192 }
193
194 return (PTR) ecoff;
195 }
196 \f
197 /* Reloc handling. MIPS ECOFF relocs are packed into 8 bytes in
198 external form. They use a bit which indicates whether the symbol
199 is external. */
200
201 /* Swap a reloc in. */
202
203 static void
204 alpha_ecoff_swap_reloc_in (abfd, ext_ptr, intern)
205 bfd *abfd;
206 PTR ext_ptr;
207 struct internal_reloc *intern;
208 {
209 const RELOC *ext = (RELOC *) ext_ptr;
210
211 intern->r_vaddr = bfd_h_get_32 (abfd, (bfd_byte *) ext->r_vaddr);
212 if (abfd->xvec->header_byteorder_big_p != false)
213 {
214 intern->r_symndx = (((int) ext->r_bits[0]
215 << RELOC_BITS0_SYMNDX_SH_LEFT_BIG)
216 | ((int) ext->r_bits[1]
217 << RELOC_BITS1_SYMNDX_SH_LEFT_BIG)
218 | ((int) ext->r_bits[2]
219 << RELOC_BITS2_SYMNDX_SH_LEFT_BIG));
220 intern->r_type = ((ext->r_bits[3] & RELOC_BITS3_TYPE_BIG)
221 >> RELOC_BITS3_TYPE_SH_BIG);
222 intern->r_extern = (ext->r_bits[3] & RELOC_BITS3_EXTERN_BIG) != 0;
223 }
224 else
225 {
226 intern->r_symndx = (((int) ext->r_bits[0]
227 << RELOC_BITS0_SYMNDX_SH_LEFT_LITTLE)
228 | ((int) ext->r_bits[1]
229 << RELOC_BITS1_SYMNDX_SH_LEFT_LITTLE)
230 | ((int) ext->r_bits[2]
231 << RELOC_BITS2_SYMNDX_SH_LEFT_LITTLE));
232 intern->r_type = ((ext->r_bits[3] & RELOC_BITS3_TYPE_LITTLE)
233 >> RELOC_BITS3_TYPE_SH_LITTLE);
234 intern->r_extern = (ext->r_bits[3] & RELOC_BITS3_EXTERN_LITTLE) != 0;
235 }
236 }
237
238 /* Swap a reloc out. */
239
240 static void
241 alpha_ecoff_swap_reloc_out (abfd, intern, dst)
242 bfd *abfd;
243 const struct internal_reloc *intern;
244 PTR dst;
245 {
246 RELOC *ext = (RELOC *) dst;
247
248 bfd_h_put_32 (abfd, intern->r_vaddr, (bfd_byte *) ext->r_vaddr);
249 if (abfd->xvec->header_byteorder_big_p != false)
250 {
251 ext->r_bits[0] = intern->r_symndx >> RELOC_BITS0_SYMNDX_SH_LEFT_BIG;
252 ext->r_bits[1] = intern->r_symndx >> RELOC_BITS1_SYMNDX_SH_LEFT_BIG;
253 ext->r_bits[2] = intern->r_symndx >> RELOC_BITS2_SYMNDX_SH_LEFT_BIG;
254 ext->r_bits[3] = (((intern->r_type << RELOC_BITS3_TYPE_SH_BIG)
255 & RELOC_BITS3_TYPE_BIG)
256 | (intern->r_extern ? RELOC_BITS3_EXTERN_BIG : 0));
257 }
258 else
259 {
260 ext->r_bits[0] = intern->r_symndx >> RELOC_BITS0_SYMNDX_SH_LEFT_LITTLE;
261 ext->r_bits[1] = intern->r_symndx >> RELOC_BITS1_SYMNDX_SH_LEFT_LITTLE;
262 ext->r_bits[2] = intern->r_symndx >> RELOC_BITS2_SYMNDX_SH_LEFT_LITTLE;
263 ext->r_bits[3] = (((intern->r_type << RELOC_BITS3_TYPE_SH_LITTLE)
264 & RELOC_BITS3_TYPE_LITTLE)
265 | (intern->r_extern ? RELOC_BITS3_EXTERN_LITTLE : 0));
266 }
267 }
268 \f
269 #define ecoff_core_file_p _bfd_dummy_target
270 #define ecoff_core_file_failing_command _bfd_dummy_core_file_failing_command
271 #define ecoff_core_file_failing_signal _bfd_dummy_core_file_failing_signal
272 #define ecoff_core_file_matches_executable_p \
273 _bfd_dummy_core_file_matches_executable_p
274 \f
275 /* This is the COFF backend structure. The backend_data field of the
276 bfd_target structure is set to this. The section reading code in
277 coffgen.c uses this structure. */
278
279 static CONST bfd_coff_backend_data alpha_ecoff_std_swap_table = {
280 (void (*) PARAMS ((bfd *,PTR,int,int,PTR))) bfd_void, /* aux_in */
281 (void (*) PARAMS ((bfd *,PTR,PTR))) bfd_void, /* sym_in */
282 (void (*) PARAMS ((bfd *,PTR,PTR))) bfd_void, /* lineno_in */
283 (unsigned (*) PARAMS ((bfd *,PTR,int,int,PTR))) bfd_void, /* aux_out */
284 (unsigned (*) PARAMS ((bfd *,PTR,PTR))) bfd_void, /* sym_out */
285 (unsigned (*) PARAMS ((bfd *,PTR,PTR))) bfd_void, /* lineno_out */
286 (unsigned (*) PARAMS ((bfd *,PTR,PTR))) bfd_void, /* reloc_out */
287 alpha_ecoff_swap_filehdr_out, alpha_ecoff_swap_aouthdr_out,
288 alpha_ecoff_swap_scnhdr_out,
289 FILHSZ, AOUTSZ, SCNHSZ, 0, 0, 0, true,
290 alpha_ecoff_swap_filehdr_in, alpha_ecoff_swap_aouthdr_in,
291 alpha_ecoff_swap_scnhdr_in, alpha_ecoff_bad_format_hook,
292 ecoff_set_arch_mach_hook, alpha_ecoff_mkobject_hook,
293 ecoff_styp_to_sec_flags, ecoff_make_section_hook, ecoff_set_alignment_hook,
294 ecoff_slurp_symbol_table
295 };
296
297 bfd_target ecoffalpha_little_vec =
298 {
299 "ecoff-littlealpha", /* name */
300 bfd_target_ecoff_flavour,
301 false, /* data byte order is little */
302 false, /* header byte order is little */
303
304 (HAS_RELOC | EXEC_P | /* object flags */
305 HAS_LINENO | HAS_DEBUG |
306 HAS_SYMS | HAS_LOCALS | DYNAMIC | WP_TEXT | D_PAGED),
307
308 (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* sect
309 flags */
310 0, /* leading underscore */
311 ' ', /* ar_pad_char */
312 15, /* ar_max_namelen */
313 4, /* minimum alignment power */
314 _do_getl64, _do_getl_signed_64, _do_putl64,
315 _do_getl32, _do_getl_signed_32, _do_putl32,
316 _do_getl16, _do_getl_signed_16, _do_putl16, /* data */
317 _do_getl64, _do_getl_signed_64, _do_putl64,
318 _do_getl32, _do_getl_signed_32, _do_putl32,
319 _do_getl16, _do_getl_signed_16, _do_putl16, /* hdrs */
320
321 {_bfd_dummy_target, coff_object_p, /* bfd_check_format */
322 ecoff_archive_p, _bfd_dummy_target},
323 {bfd_false, alpha_ecoff_mkobject, /* bfd_set_format */
324 _bfd_generic_mkarchive, bfd_false},
325 {bfd_false, ecoff_write_object_contents, /* bfd_write_contents */
326 _bfd_write_archive_contents, bfd_false},
327 JUMP_TABLE (ecoff),
328 (PTR) &alpha_ecoff_std_swap_table
329 };
This page took 0.03653 seconds and 4 git commands to generate.