]>
Commit | Line | Data |
---|---|---|
dae31cf5 ILT |
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 <[email protected]> and | |
4 | Ian Lance Taylor <[email protected]>. | |
5f8f6d56 | 5 | |
5f8f6d56 SC |
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" | |
5f8f6d56 SC |
26 | #include "coff/internal.h" |
27 | #include "coff/sym.h" | |
28 | #include "coff/symconst.h" | |
dae31cf5 ILT |
29 | #include "coff/ecoff.h" |
30 | #include "coff/alpha.h" | |
5f8f6d56 SC |
31 | #include "libcoff.h" |
32 | #include "libecoff.h" | |
5f8f6d56 SC |
33 | \f |
34 | /* Prototypes for static functions. */ | |
35 | ||
dae31cf5 ILT |
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)); | |
5f8f6d56 | 44 | \f |
dae31cf5 ILT |
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, | |
5f8f6d56 | 53 | symbol, and lineno ones. Give them ecoff names. */ |
dae31cf5 | 54 | #define ALPHAECOFF |
5f8f6d56 SC |
55 | #define NO_COFF_RELOCS |
56 | #define NO_COFF_SYMBOLS | |
57 | #define NO_COFF_LINENOS | |
dae31cf5 ILT |
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 | |
5f8f6d56 | 64 | #include "coffswap.h" |
5f8f6d56 | 65 | |
dae31cf5 ILT |
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 | |
5f8f6d56 SC |
123 | /* See whether the magic number matches. */ |
124 | ||
125 | static boolean | |
dae31cf5 | 126 | alpha_ecoff_bad_format_hook (abfd, filehdr) |
5f8f6d56 SC |
127 | bfd *abfd; |
128 | PTR filehdr; | |
129 | { | |
130 | struct internal_filehdr *internal_f = (struct internal_filehdr *) filehdr; | |
131 | ||
dae31cf5 | 132 | if (ALPHA_ECOFF_BADMAG (*internal_f)) |
5f8f6d56 SC |
133 | return false; |
134 | ||
135 | return true; | |
136 | } | |
137 | ||
5f8f6d56 SC |
138 | /* Create an ECOFF object. */ |
139 | ||
140 | static boolean | |
dae31cf5 | 141 | alpha_ecoff_mkobject (abfd) |
5f8f6d56 SC |
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 | ||
dae31cf5 ILT |
152 | ecoff_data (abfd)->backend_data = &alpha_ecoff_backend_data; |
153 | ||
5f8f6d56 SC |
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 | ||
dae31cf5 | 161 | /* Create the MIPS ECOFF backend specific information. */ |
5f8f6d56 SC |
162 | |
163 | static PTR | |
dae31cf5 | 164 | alpha_ecoff_mkobject_hook (abfd, filehdr, aouthdr) |
5f8f6d56 SC |
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 | ||
dae31cf5 | 173 | if (alpha_ecoff_mkobject (abfd) == false) |
5f8f6d56 SC |
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]; | |
dae31cf5 ILT |
190 | if (internal_a->magic == ECOFF_AOUT_ZMAGIC) |
191 | abfd->flags |= D_PAGED; | |
5f8f6d56 SC |
192 | } |
193 | ||
194 | return (PTR) ecoff; | |
195 | } | |
5f8f6d56 | 196 | \f |
dae31cf5 ILT |
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. */ | |
5f8f6d56 | 200 | |
dae31cf5 | 201 | /* Swap a reloc in. */ |
5f8f6d56 SC |
202 | |
203 | static void | |
dae31cf5 | 204 | alpha_ecoff_swap_reloc_in (abfd, ext_ptr, intern) |
5f8f6d56 | 205 | bfd *abfd; |
dae31cf5 ILT |
206 | PTR ext_ptr; |
207 | struct internal_reloc *intern; | |
5f8f6d56 | 208 | { |
dae31cf5 | 209 | const RELOC *ext = (RELOC *) ext_ptr; |
5f8f6d56 | 210 | |
dae31cf5 ILT |
211 | intern->r_vaddr = bfd_h_get_32 (abfd, (bfd_byte *) ext->r_vaddr); |
212 | if (abfd->xvec->header_byteorder_big_p != false) | |
5f8f6d56 | 213 | { |
dae31cf5 ILT |
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; | |
5f8f6d56 | 223 | } |
5f8f6d56 | 224 | else |
5f8f6d56 | 225 | { |
dae31cf5 ILT |
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; | |
5f8f6d56 | 235 | } |
5f8f6d56 SC |
236 | } |
237 | ||
dae31cf5 | 238 | /* Swap a reloc out. */ |
5f8f6d56 | 239 | |
dae31cf5 ILT |
240 | static void |
241 | alpha_ecoff_swap_reloc_out (abfd, intern, dst) | |
5f8f6d56 | 242 | bfd *abfd; |
dae31cf5 ILT |
243 | const struct internal_reloc *intern; |
244 | PTR dst; | |
5f8f6d56 | 245 | { |
dae31cf5 | 246 | RELOC *ext = (RELOC *) dst; |
5f8f6d56 | 247 | |
dae31cf5 ILT |
248 | bfd_h_put_32 (abfd, intern->r_vaddr, (bfd_byte *) ext->r_vaddr); |
249 | if (abfd->xvec->header_byteorder_big_p != false) | |
5f8f6d56 | 250 | { |
dae31cf5 ILT |
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)); | |
5f8f6d56 | 257 | } |
5f8f6d56 SC |
258 | else |
259 | { | |
dae31cf5 ILT |
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)); | |
5f8f6d56 | 266 | } |
5f8f6d56 | 267 | } |
dae31cf5 ILT |
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. */ | |
5f8f6d56 | 278 | |
dae31cf5 ILT |
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 | }; | |
5f8f6d56 | 296 | |
dae31cf5 | 297 | bfd_target ecoffalpha_little_vec = |
5f8f6d56 | 298 | { |
dae31cf5 ILT |
299 | "ecoff-littlealpha", /* name */ |
300 | bfd_target_ecoff_flavour, | |
301 | false, /* data byte order is little */ | |
302 | false, /* header byte order is little */ | |
5f8f6d56 | 303 | |
dae31cf5 ILT |
304 | (HAS_RELOC | EXEC_P | /* object flags */ |
305 | HAS_LINENO | HAS_DEBUG | | |
306 | HAS_SYMS | HAS_LOCALS | DYNAMIC | WP_TEXT | D_PAGED), | |
5f8f6d56 SC |
307 | |
308 | (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* sect | |
309 | flags */ | |
310 | 0, /* leading underscore */ | |
dae31cf5 | 311 | ' ', /* ar_pad_char */ |
5f8f6d56 | 312 | 15, /* ar_max_namelen */ |
dae31cf5 | 313 | 4, /* minimum alignment power */ |
5f8f6d56 SC |
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}, | |
dae31cf5 ILT |
323 | {bfd_false, alpha_ecoff_mkobject, /* bfd_set_format */ |
324 | _bfd_generic_mkarchive, bfd_false}, | |
5f8f6d56 SC |
325 | {bfd_false, ecoff_write_object_contents, /* bfd_write_contents */ |
326 | _bfd_write_archive_contents, bfd_false}, | |
327 | JUMP_TABLE (ecoff), | |
dae31cf5 | 328 | (PTR) &alpha_ecoff_std_swap_table |
5f8f6d56 | 329 | }; |