* ecoff.c: New file for generic ECOFF functions.
[deliverable/binutils-gdb.git] / bfd / coff-alpha.c
CommitLineData
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 <sac@cygnus.com> and
4 Ian Lance Taylor <ian@cygnus.com>.
5f8f6d56 5
5f8f6d56
SC
6This file is part of BFD, the Binary File Descriptor library.
7
8This program is free software; you can redistribute it and/or modify
9it under the terms of the GNU General Public License as published by
10the Free Software Foundation; either version 2 of the License, or
11(at your option) any later version.
12
13This program is distributed in the hope that it will be useful,
14but WITHOUT ANY WARRANTY; without even the implied warranty of
15MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16GNU General Public License for more details.
17
18You should have received a copy of the GNU General Public License
19along with this program; if not, write to the Free Software
20Foundation, 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
36static boolean alpha_ecoff_bad_format_hook PARAMS ((bfd *abfd, PTR filehdr));
37static PTR alpha_ecoff_mkobject_hook PARAMS ((bfd *abfd, PTR filehdr,
38 PTR aouthdr));
39static void alpha_ecoff_swap_reloc_in PARAMS ((bfd *, PTR,
40 struct internal_reloc *));
41static 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
74static 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
125static boolean
dae31cf5 126alpha_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
140static boolean
dae31cf5 141alpha_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
163static PTR
dae31cf5 164alpha_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
203static void
dae31cf5 204alpha_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
240static void
241alpha_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
279static 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 297bfd_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};
This page took 0.048361 seconds and 4 git commands to generate.