]>
Commit | Line | Data |
---|---|---|
22ddf9bc SC |
1 | |
2 | /* All the swapping routines: | |
3 | */ | |
4 | ||
5 | ||
6 | ||
7 | static void | |
8 | DEFUN(swap_reloc_in,(abfd, reloc_src, reloc_dst), | |
9 | bfd *abfd AND | |
10 | RELOC *reloc_src AND | |
11 | struct internal_reloc *reloc_dst) | |
12 | { | |
13 | reloc_dst->r_vaddr = bfd_h_getlong(abfd, reloc_src->r_vaddr); | |
14 | reloc_dst->r_symndx = bfd_h_getlong(abfd, reloc_src->r_symndx); | |
15 | reloc_dst->r_type = bfd_h_getshort(abfd, reloc_src->r_type); | |
16 | #if M88 | |
17 | reloc_dst->r_offset = bfd_h_getshort(abfd, reloc_src->r_offset); | |
18 | #endif | |
19 | } | |
20 | ||
21 | static void | |
22 | DEFUN(swap_reloc_out,(abfd, reloc_src, reloc_dst), | |
23 | bfd *abfd AND | |
24 | struct internal_reloc *reloc_src AND | |
25 | struct external_reloc *reloc_dst) | |
26 | { | |
27 | bfd_h_putlong(abfd, reloc_src->r_vaddr, reloc_dst->r_vaddr); | |
28 | bfd_h_putlong(abfd, reloc_src->r_symndx, reloc_dst->r_symndx); | |
29 | bfd_h_putshort(abfd, reloc_src->r_type, reloc_dst->r_type); | |
30 | #if M88 | |
31 | bfd_h_putshort(abfd, reloc_src->r_offset, reloc_dst->r_offset); | |
32 | #endif | |
33 | ||
34 | } | |
35 | ||
36 | static void | |
37 | DEFUN(swap_filehdr_in,(abfd, filehdr_src, filehdr_dst), | |
38 | bfd *abfd AND | |
39 | FILHDR *filehdr_src AND | |
40 | struct internal_filehdr *filehdr_dst) | |
41 | { | |
42 | filehdr_dst->f_magic = bfd_h_get_x(abfd, filehdr_src->f_magic); | |
43 | filehdr_dst->f_nscns = bfd_h_get_x(abfd,filehdr_src-> f_nscns); | |
44 | filehdr_dst->f_timdat = bfd_h_get_x(abfd,filehdr_src-> f_timdat); | |
45 | filehdr_dst->f_symptr = bfd_h_get_x(abfd,filehdr_src-> f_symptr); | |
46 | filehdr_dst->f_nsyms = bfd_h_get_x(abfd,filehdr_src-> f_nsyms); | |
47 | filehdr_dst->f_opthdr = bfd_h_get_x(abfd,filehdr_src-> f_opthdr); | |
48 | filehdr_dst->f_flags = bfd_h_get_x(abfd,filehdr_src-> f_flags); | |
49 | } | |
50 | ||
51 | static void | |
52 | DEFUN(swap_filehdr_out,(abfd, filehdr_in, filehdr_out), | |
53 | bfd *abfd AND | |
54 | struct internal_filehdr *filehdr_in AND | |
55 | FILHDR *filehdr_out) | |
56 | { | |
57 | bfd_h_put_x(abfd, filehdr_in->f_magic, filehdr_out->f_magic); | |
58 | bfd_h_put_x(abfd, filehdr_in->f_nscns, filehdr_out->f_nscns); | |
59 | bfd_h_put_x(abfd, filehdr_in->f_timdat, filehdr_out->f_timdat); | |
60 | bfd_h_put_x(abfd, filehdr_in->f_symptr, filehdr_out->f_symptr); | |
61 | bfd_h_put_x(abfd, filehdr_in->f_nsyms, filehdr_out->f_nsyms); | |
62 | bfd_h_put_x(abfd, filehdr_in->f_opthdr, filehdr_out->f_opthdr); | |
63 | bfd_h_put_x(abfd, filehdr_in->f_flags, filehdr_out->f_flags); | |
64 | } | |
65 | ||
66 | ||
67 | static void | |
68 | DEFUN(bfd_coff_swap_sym_in,(abfd, ext, in), | |
69 | bfd *abfd AND | |
70 | SYMENT *ext AND | |
71 | struct internal_syment *in) | |
72 | { | |
73 | if( ext->e.e_name[0] == 0) { | |
74 | in->_n._n_n._n_zeroes = 0; | |
75 | in->_n._n_n._n_offset = bfd_h_getlong(abfd, ext->e.e.e_offset); | |
76 | } | |
77 | else { | |
78 | memcpy(in->_n._n_name, ext->e.e_name, SYMNMLEN); | |
79 | } | |
80 | in->n_value = bfd_h_get_x(abfd, ext->e_value); | |
81 | in->n_scnum = bfd_h_get_x(abfd, ext->e_scnum); | |
82 | in->n_type = bfd_h_get_x(abfd, ext->e_type); | |
83 | in->n_sclass = bfd_h_get_x(abfd, ext->e_sclass); | |
84 | in->n_numaux = bfd_h_get_x(abfd, ext->e_numaux); | |
85 | } | |
86 | ||
87 | static void | |
88 | DEFUN(bfd_coff_swap_sym_out,(abfd,in, ext), | |
89 | bfd *abfd AND | |
90 | struct internal_syment *in AND | |
91 | SYMENT *ext) | |
92 | { | |
93 | if(in->_n._n_name[0] == 0) { | |
94 | bfd_h_putlong(abfd, 0, ext->e.e.e_zeroes); | |
95 | bfd_h_putlong(abfd, in->_n._n_n._n_offset, ext->e.e.e_offset); | |
96 | } | |
97 | else { | |
98 | memcpy(ext->e.e_name, in->_n._n_name, SYMNMLEN); | |
99 | } | |
100 | bfd_h_put_x(abfd, in->n_value , ext->e_value); | |
101 | bfd_h_put_x(abfd, in->n_scnum , ext->e_scnum); | |
102 | bfd_h_put_x(abfd, in->n_type , ext->e_type); | |
103 | bfd_h_put_x(abfd, in->n_sclass , ext->e_sclass); | |
104 | bfd_h_put_x(abfd, in->n_numaux , ext->e_numaux); | |
105 | } | |
106 | ||
107 | static void | |
108 | DEFUN(bfd_coff_swap_aux_in,(abfd, ext, type, class, in), | |
109 | bfd *abfd AND | |
110 | AUXENT *ext AND | |
111 | int type AND | |
112 | int class AND | |
113 | union internal_auxent *in) | |
114 | { | |
115 | switch (class) { | |
116 | case C_FILE: | |
117 | if (ext->x_file.x_fname[0] == 0) { | |
118 | in->x_file.x_n.x_zeroes = 0; | |
119 | in->x_file.x_n.x_offset = bfd_h_getlong(abfd, ext->x_file.x_n.x_offset); | |
120 | } | |
121 | ||
122 | break; | |
123 | case C_STAT: | |
124 | #ifdef C_LEAFSTAT | |
125 | case C_LEAFSTAT: | |
126 | #endif | |
127 | case C_HIDDEN: | |
128 | if (type == T_NULL) { | |
129 | in->x_scn.x_scnlen = bfd_h_get_x(abfd, ext->x_scn.x_scnlen); | |
130 | in->x_scn.x_nreloc = bfd_h_get_x(abfd, ext->x_scn.x_nreloc); | |
131 | in->x_scn.x_nlinno = bfd_h_get_x(abfd, ext->x_scn.x_nlinno); | |
132 | break; | |
133 | } | |
134 | default: | |
135 | in->x_sym.x_tagndx = bfd_h_get_x(abfd, ext->x_sym.x_tagndx); | |
136 | in->x_sym.x_tvndx = bfd_h_get_x(abfd, ext->x_sym.x_tvndx); | |
137 | ||
138 | if (ISARY(type) || class == C_BLOCK) { | |
139 | in->x_sym.x_fcnary.x_ary.x_dimen[0] = bfd_h_get_x(abfd, ext->x_sym.x_fcnary.x_ary.x_dimen[0]); | |
140 | in->x_sym.x_fcnary.x_ary.x_dimen[1] = bfd_h_get_x(abfd, ext->x_sym.x_fcnary.x_ary.x_dimen[1]); | |
141 | in->x_sym.x_fcnary.x_ary.x_dimen[2] = bfd_h_get_x(abfd, ext->x_sym.x_fcnary.x_ary.x_dimen[2]); | |
142 | in->x_sym.x_fcnary.x_ary.x_dimen[3] = bfd_h_get_x(abfd, ext->x_sym.x_fcnary.x_ary.x_dimen[3]); | |
143 | } | |
144 | else { | |
145 | in->x_sym.x_fcnary.x_fcn.x_lnnoptr = bfd_h_get_x(abfd, ext->x_sym.x_fcnary.x_fcn.x_lnnoptr); | |
146 | in->x_sym.x_fcnary.x_fcn.x_endndx = bfd_h_get_x(abfd, ext->x_sym.x_fcnary.x_fcn.x_endndx); | |
147 | } | |
148 | if (ISFCN(type)) { | |
149 | in->x_sym.x_misc.x_fsize = bfd_h_get_x(abfd, ext->x_sym.x_misc.x_fsize); | |
150 | } | |
151 | else { | |
152 | in->x_sym.x_misc.x_lnsz.x_lnno = bfd_h_get_x(abfd, ext->x_sym.x_misc.x_lnsz.x_lnno); | |
153 | in->x_sym.x_misc.x_lnsz.x_size = bfd_h_get_x(abfd, ext->x_sym.x_misc.x_lnsz.x_size); | |
154 | } | |
155 | } | |
156 | } | |
157 | ||
158 | static void | |
159 | DEFUN(bfd_coff_swap_aux_out,(abfd, in, type, class, ext), | |
160 | bfd *abfd AND | |
161 | union internal_auxent *in AND | |
162 | int type AND | |
163 | int class AND | |
164 | AUXENT *ext) | |
165 | { | |
166 | switch (class) { | |
167 | case C_FILE: | |
168 | if (in->x_file.x_fname[0] == 0) { | |
169 | bfd_h_put_x(abfd, 0, ext->x_file.x_n.x_zeroes ); | |
170 | bfd_h_put_x(abfd, in->x_file.x_n.x_offset, ext->x_file.x_n.x_offset); | |
171 | } | |
172 | ||
173 | break; | |
174 | case C_STAT: | |
175 | #ifdef C_LEAFSTAT | |
176 | case C_LEAFSTAT: | |
177 | #endif | |
178 | case C_HIDDEN: | |
179 | if (type == T_NULL) { | |
180 | bfd_h_put_x(abfd, in->x_scn.x_scnlen, ext->x_scn.x_scnlen); | |
181 | bfd_h_put_x(abfd, in->x_scn.x_nreloc, ext->x_scn.x_nreloc); | |
182 | bfd_h_put_x(abfd, in->x_scn.x_nlinno, ext->x_scn.x_nlinno); | |
183 | break; | |
184 | } | |
185 | default: | |
186 | bfd_h_put_x(abfd, in->x_sym.x_tagndx, ext->x_sym.x_tagndx); | |
187 | bfd_h_put_x(abfd, in->x_sym.x_tvndx , ext->x_sym.x_tvndx); | |
188 | ||
189 | if (ISARY(type) || class == C_BLOCK) { | |
190 | bfd_h_put_x(abfd, in->x_sym.x_fcnary.x_ary.x_dimen[0],ext->x_sym.x_fcnary.x_ary.x_dimen[0]); | |
191 | bfd_h_put_x(abfd, in->x_sym.x_fcnary.x_ary.x_dimen[1],ext->x_sym.x_fcnary.x_ary.x_dimen[1]); | |
192 | bfd_h_put_x(abfd, in->x_sym.x_fcnary.x_ary.x_dimen[2],ext->x_sym.x_fcnary.x_ary.x_dimen[2]); | |
193 | bfd_h_put_x(abfd, in->x_sym.x_fcnary.x_ary.x_dimen[3],ext->x_sym.x_fcnary.x_ary.x_dimen[3]); | |
194 | } | |
195 | else { | |
196 | bfd_h_put_x(abfd, in->x_sym.x_fcnary.x_fcn.x_lnnoptr, ext->x_sym.x_fcnary.x_fcn.x_lnnoptr); | |
197 | bfd_h_put_x(abfd, in->x_sym.x_fcnary.x_fcn.x_endndx, ext->x_sym.x_fcnary.x_fcn.x_endndx); | |
198 | } | |
199 | if (ISFCN(type)) { | |
200 | bfd_h_put_x(abfd, in->x_sym.x_misc.x_fsize, ext->x_sym.x_misc.x_fsize); | |
201 | } | |
202 | else { | |
203 | bfd_h_put_x(abfd, in->x_sym.x_misc.x_lnsz.x_lnno, ext->x_sym.x_misc.x_lnsz.x_lnno); | |
204 | bfd_h_put_x(abfd, in->x_sym.x_misc.x_lnsz.x_size, ext->x_sym.x_misc.x_lnsz.x_size); | |
205 | } | |
206 | } | |
207 | } | |
208 | ||
209 | static void | |
210 | DEFUN(bfd_coff_swap_lineno_in,(abfd, ext, in), | |
211 | bfd *abfd AND | |
212 | LINENO *ext AND | |
213 | struct internal_lineno *in) | |
214 | { | |
215 | in->l_addr.l_symndx = bfd_h_get_x(abfd, ext->l_addr.l_symndx); | |
216 | in->l_lnno = bfd_h_get_x(abfd, ext->l_lnno); | |
217 | } | |
218 | ||
219 | static void | |
220 | DEFUN(bfd_coff_swap_lineno_out,(abfd, in, ext), | |
221 | bfd *abfd AND | |
222 | struct internal_lineno *in AND | |
223 | struct external_lineno *ext) | |
224 | { | |
225 | bfd_h_put_x(abfd, in->l_addr.l_symndx, ext->l_addr.l_symndx); | |
226 | bfd_h_put_x(abfd, in->l_lnno, ext->l_lnno); | |
227 | } | |
228 | ||
229 | ||
230 | ||
231 | ||
232 | static void | |
233 | DEFUN(swap_aouthdr_in,(abfd, aouthdr_ext, aouthdr_int), | |
234 | bfd *abfd AND | |
235 | AOUTHDR *aouthdr_ext AND | |
236 | struct internal_aouthdr *aouthdr_int) | |
237 | { | |
238 | aouthdr_int->magic = bfd_h_get_x(abfd, aouthdr_ext->magic); | |
239 | aouthdr_int->vstamp = bfd_h_get_x(abfd, aouthdr_ext->vstamp); | |
240 | aouthdr_int->tsize = bfd_h_get_x(abfd, aouthdr_ext->tsize); | |
241 | aouthdr_int->dsize = bfd_h_get_x(abfd, aouthdr_ext->dsize); | |
242 | aouthdr_int->bsize = bfd_h_get_x(abfd, aouthdr_ext->bsize); | |
243 | aouthdr_int->entry = bfd_h_get_x(abfd, aouthdr_ext->entry); | |
244 | aouthdr_int->text_start = bfd_h_get_x(abfd, aouthdr_ext->text_start); | |
245 | aouthdr_int->data_start = bfd_h_get_x(abfd, aouthdr_ext->data_start); | |
246 | #ifdef I960 | |
247 | aouthdr_int->tagentries = bfd_h_get_x(abfd, aouthdr_ext->tagentries); | |
248 | #endif | |
249 | } | |
250 | ||
251 | static void | |
252 | DEFUN(swap_aouthdr_out,(abfd, aouthdr_in, aouthdr_out), | |
253 | bfd *abfd AND | |
254 | struct internal_aouthdr *aouthdr_in AND | |
255 | AOUTHDR *aouthdr_out) | |
256 | { | |
257 | bfd_h_put_x(abfd, aouthdr_in->magic, aouthdr_out->magic); | |
258 | bfd_h_put_x(abfd, aouthdr_in->vstamp, aouthdr_out->vstamp); | |
259 | bfd_h_put_x(abfd, aouthdr_in->tsize, aouthdr_out->tsize); | |
260 | bfd_h_put_x(abfd, aouthdr_in->dsize, aouthdr_out->dsize); | |
261 | bfd_h_put_x(abfd, aouthdr_in->bsize, aouthdr_out->bsize); | |
262 | bfd_h_put_x(abfd, aouthdr_in->entry, aouthdr_out->entry); | |
263 | bfd_h_put_x(abfd, aouthdr_in->text_start, aouthdr_out->text_start); | |
264 | bfd_h_put_x(abfd, aouthdr_in->data_start, aouthdr_out->data_start); | |
265 | #ifdef I960 | |
266 | bfd_h_put_x(abfd, aouthdr_in->tagentries, aouthdr_out->tagentries); | |
267 | #endif | |
268 | } | |
269 | ||
270 | static void | |
271 | DEFUN(swap_scnhdr_in,(abfd, scnhdr_ext, scnhdr_int), | |
272 | bfd *abfd AND | |
273 | SCNHDR *scnhdr_ext AND | |
274 | struct internal_scnhdr *scnhdr_int) | |
275 | { | |
276 | memcpy(scnhdr_int->s_name, scnhdr_ext->s_name, sizeof(scnhdr_int->s_name)); | |
277 | scnhdr_int->s_vaddr = bfd_h_get_x(abfd, scnhdr_ext->s_vaddr); | |
278 | scnhdr_int->s_paddr = bfd_h_get_x(abfd, scnhdr_ext->s_paddr); | |
279 | scnhdr_int->s_size = bfd_h_get_x(abfd, scnhdr_ext->s_size); | |
280 | scnhdr_int->s_scnptr = bfd_h_get_x(abfd, scnhdr_ext->s_scnptr); | |
281 | scnhdr_int->s_relptr = bfd_h_get_x(abfd, scnhdr_ext->s_relptr); | |
282 | scnhdr_int->s_lnnoptr = bfd_h_get_x(abfd, scnhdr_ext->s_lnnoptr); | |
283 | scnhdr_int->s_nreloc = bfd_h_get_x(abfd, scnhdr_ext->s_nreloc); | |
284 | scnhdr_int->s_nlnno = bfd_h_get_x(abfd, scnhdr_ext->s_nlnno); | |
285 | scnhdr_int->s_flags = bfd_h_get_x(abfd, scnhdr_ext->s_flags); | |
286 | #ifdef I960 | |
287 | scnhdr_int->s_align = bfd_h_get_x(abfd, scnhdr_ext->s_align); | |
288 | #endif | |
289 | } | |
290 | ||
291 | static void | |
292 | DEFUN(swap_scnhdr_out,(abfd, scnhdr_int, scnhdr_ext), | |
293 | bfd *abfd AND | |
294 | struct internal_scnhdr *scnhdr_int AND | |
295 | SCNHDR *scnhdr_ext) | |
296 | { | |
297 | memcpy(scnhdr_ext->s_name, scnhdr_int->s_name, sizeof(scnhdr_int->s_name)); | |
298 | bfd_h_put_x(abfd, scnhdr_int->s_vaddr, scnhdr_ext->s_vaddr); | |
299 | bfd_h_put_x(abfd, scnhdr_int->s_paddr, scnhdr_ext->s_paddr); | |
300 | bfd_h_put_x(abfd, scnhdr_int->s_size, scnhdr_ext->s_size); | |
301 | bfd_h_put_x(abfd, scnhdr_int->s_scnptr, scnhdr_ext->s_scnptr); | |
302 | bfd_h_put_x(abfd, scnhdr_int->s_relptr, scnhdr_ext->s_relptr); | |
303 | bfd_h_put_x(abfd, scnhdr_int->s_lnnoptr, scnhdr_ext->s_lnnoptr); | |
304 | bfd_h_put_x(abfd, scnhdr_int->s_nreloc, scnhdr_ext->s_nreloc); | |
305 | bfd_h_put_x(abfd, scnhdr_int->s_nlnno, scnhdr_ext->s_nlnno); | |
306 | bfd_h_put_x(abfd, scnhdr_int->s_flags, scnhdr_ext->s_flags); | |
307 | #ifdef I960 | |
308 | bfd_h_put_x(abfd, scnhdr_int->s_align, scnhdr_ext->s_align); | |
309 | #endif | |
310 | } | |
311 | ||
312 | /* | |
313 | initialize a section structure with information peculiar to this | |
314 | particular implementation of coff | |
315 | */ | |
316 | ||
317 | static boolean | |
318 | DEFUN(coff_new_section_hook,(abfd_ignore, section_ignore), | |
319 | bfd *abfd_ignore AND | |
320 | asection *section_ignore) | |
321 | { | |
322 | #ifdef MC88MAGIC | |
323 | /* FIXME, shouldn't this ifdef be on something that says we are | |
324 | actually COMPILING FOR an 88K coff file, rather than simply | |
325 | knowing its magic number? */ | |
326 | /* Align to at least 16 bytes */ | |
327 | section_ignore->alignment_power = 4; | |
328 | #endif | |
329 | #if M68 | |
330 | section_ignore->alignment_power = 3; | |
331 | #endif | |
332 | return true; | |
333 | } | |
334 | ||
335 | /* Take a section header read from a coff file (in HOST byte order), | |
336 | and make a BFD "section" out of it. */ | |
337 | static boolean | |
338 | DEFUN(make_a_section_from_file,(abfd, hdr), | |
339 | bfd *abfd AND | |
340 | struct internal_scnhdr *hdr) | |
341 | { | |
342 | asection *return_section; | |
343 | ||
344 | { | |
345 | /* Assorted wastage to null-terminate the name, thanks AT&T! */ | |
346 | char *name = bfd_alloc(abfd, sizeof (hdr->s_name)+1); | |
347 | if (name == NULL) { | |
348 | bfd_error = no_memory; | |
349 | return false; | |
350 | } | |
351 | strncpy(name, (char *) &hdr->s_name[0], sizeof (hdr->s_name)); | |
352 | name[sizeof (hdr->s_name)] = 0; | |
353 | ||
354 | return_section = bfd_make_section(abfd, name); | |
355 | } | |
356 | ||
357 | /* s_paddr is presumed to be = to s_vaddr */ | |
358 | #define assign(to, from) return_section->to = hdr->from | |
359 | assign(vma, s_vaddr); | |
360 | /* assign (vma, s_vaddr); */ | |
361 | assign(size, s_size); | |
362 | assign(filepos, s_scnptr); | |
363 | assign(rel_filepos, s_relptr); | |
364 | assign(reloc_count, s_nreloc); | |
365 | #ifdef I960 | |
366 | { | |
367 | /* FIXME, use a temp var rather than alignment_power */ | |
368 | assign(alignment_power, s_align); | |
369 | { | |
370 | unsigned int i; | |
371 | for (i = 0; i < 32; i++) { | |
372 | if ((1 << i) >= (int) (return_section->alignment_power)) { | |
373 | return_section->alignment_power = i; | |
374 | break; | |
375 | } | |
376 | } | |
377 | } | |
378 | } | |
379 | #endif | |
380 | assign(line_filepos, s_lnnoptr); | |
381 | /* | |
382 | return_section->linesize = hdr->s_nlnno * sizeof (struct lineno); | |
383 | */ | |
384 | ||
385 | #undef assign | |
386 | return_section->lineno_count = hdr->s_nlnno; | |
387 | return_section->userdata = NULL; | |
388 | return_section->next = (asection *) NULL; | |
389 | if ((hdr->s_flags & STYP_TEXT) || (hdr->s_flags & STYP_DATA)) | |
390 | return_section->flags = (SEC_LOAD | SEC_ALLOC); | |
391 | else if (hdr->s_flags & STYP_BSS) | |
392 | return_section->flags = SEC_ALLOC; | |
393 | ||
394 | if (hdr->s_nreloc != 0) | |
395 | return_section->flags |= SEC_RELOC; | |
396 | if (hdr->s_scnptr != 0) | |
397 | return_section->flags |= SEC_HAS_CONTENTS; | |
398 | return true; | |
399 | } | |
400 | static boolean | |
401 | DEFUN(coff_mkobject,(abfd), | |
402 | bfd *abfd) | |
403 | { | |
404 | set_tdata (abfd, bfd_zalloc (abfd,sizeof(coff_data_type))); | |
405 | if (coff_data(abfd) == 0) { | |
406 | bfd_error = no_memory; | |
407 | return false; | |
408 | } | |
409 | coff_data(abfd)->relocbase = 0; | |
410 | return true; | |
411 | } | |
412 | ||
413 | static | |
414 | bfd_target * | |
415 | DEFUN(coff_real_object_p,(abfd, nscns, internal_f, internal_a), | |
416 | bfd *abfd AND | |
417 | unsigned nscns AND | |
418 | struct internal_filehdr *internal_f AND | |
419 | struct internal_aouthdr *internal_a) | |
420 | { | |
421 | coff_data_type *coff; | |
422 | ||
423 | size_t readsize; /* length of file_info */ | |
424 | SCNHDR *external_sections; | |
425 | ||
426 | /* Build a play area */ | |
427 | if (coff_mkobject(abfd) != true) | |
428 | return 0; | |
429 | coff = coff_data(abfd); | |
430 | ||
431 | ||
432 | external_sections = (SCNHDR *)bfd_alloc(abfd, readsize = (nscns * SCNHSZ)); | |
433 | if (bfd_read((PTR)external_sections, 1, readsize, abfd) != readsize) { | |
434 | goto fail; | |
435 | } | |
436 | ||
437 | ||
438 | ||
439 | /* Now copy data as required; construct all asections etc */ | |
440 | coff->symbol_index_slew = 0; | |
441 | coff->relocbase =0; | |
442 | coff->raw_syment_count = 0; | |
443 | coff->raw_linenos = 0; | |
444 | coff->raw_syments = 0; | |
445 | coff->sym_filepos =0; | |
446 | coff->flags = internal_f->f_flags; | |
447 | if (nscns != 0) { | |
448 | unsigned int i; | |
449 | for (i = 0; i < nscns; i++) { | |
450 | struct internal_scnhdr tmp; | |
451 | swap_scnhdr_in(abfd, external_sections + i, &tmp); | |
452 | make_a_section_from_file(abfd,&tmp); | |
453 | } | |
454 | } | |
455 | /* Determine the machine architecture and type. */ | |
456 | abfd->obj_machine = 0; | |
457 | switch (internal_f->f_magic) { | |
458 | #ifdef MIPS | |
459 | #ifdef MIPSEBMAGIC | |
460 | case SMIPSEBMAGIC: | |
461 | case SMIPSELMAGIC: | |
462 | case MIPSEBUMAGIC: | |
463 | case MIPSELUMAGIC: | |
464 | case MIPSEBMAGIC: | |
465 | case MIPSELMAGIC: | |
466 | abfd->obj_arch = bfd_arch_mips; | |
467 | abfd->obj_machine = 0; | |
468 | break; | |
469 | #endif | |
470 | #endif | |
471 | #ifdef MC68MAGIC | |
472 | case MC68MAGIC: | |
473 | case M68MAGIC: | |
474 | abfd->obj_arch = bfd_arch_m68k; | |
475 | abfd->obj_machine = 68020; | |
476 | break; | |
477 | #endif | |
478 | #ifdef MC88MAGIC | |
479 | case MC88MAGIC: | |
480 | case MC88DMAGIC: | |
481 | case MC88OMAGIC: | |
482 | abfd->obj_arch = bfd_arch_m88k; | |
483 | abfd->obj_machine = 88100; | |
484 | break; | |
485 | #endif | |
486 | #ifdef I960 | |
487 | #ifdef I960ROMAGIC | |
488 | case I960ROMAGIC: | |
489 | case I960RWMAGIC: | |
490 | abfd->obj_arch = bfd_arch_i960; | |
491 | switch (F_I960TYPE & internal_f->f_flags) | |
492 | { | |
493 | default: | |
494 | case F_I960CORE: | |
495 | abfd->obj_machine = bfd_mach_i960_core; | |
496 | break; | |
497 | case F_I960KB: | |
498 | abfd->obj_machine = bfd_mach_i960_kb_sb; | |
499 | break; | |
500 | case F_I960MC: | |
501 | abfd->obj_machine = bfd_mach_i960_mc; | |
502 | break; | |
503 | case F_I960XA: | |
504 | abfd->obj_machine = bfd_mach_i960_xa; | |
505 | break; | |
506 | case F_I960CA: | |
507 | abfd->obj_machine = bfd_mach_i960_ca; | |
508 | break; | |
509 | case F_I960KA: | |
510 | abfd->obj_machine = bfd_mach_i960_ka_sa; | |
511 | break; | |
512 | ||
513 | } | |
514 | break; | |
515 | #endif | |
516 | #endif | |
517 | ||
518 | default: /* Unreadable input file type */ | |
519 | abfd->obj_arch = bfd_arch_obscure; | |
520 | break; | |
521 | } | |
522 | ||
523 | if (!(internal_f->f_flags & F_RELFLG)) | |
524 | abfd->flags |= HAS_RELOC; | |
525 | if ((internal_f->f_flags & F_EXEC)) | |
526 | abfd->flags |= EXEC_P; | |
527 | if (!(internal_f->f_flags & F_LNNO)) | |
528 | abfd->flags |= HAS_LINENO; | |
529 | if (!(internal_f->f_flags & F_LSYMS)) | |
530 | abfd->flags |= HAS_LOCALS; | |
531 | ||
532 | ||
533 | bfd_get_symcount(abfd) = internal_f->f_nsyms; | |
534 | if (internal_f->f_nsyms) | |
535 | abfd->flags |= HAS_SYMS; | |
536 | ||
537 | coff->sym_filepos = internal_f->f_symptr; | |
538 | ||
539 | ||
540 | ||
541 | coff->symbols = (coff_symbol_type *) NULL; | |
542 | bfd_get_start_address(abfd) = internal_f->f_opthdr ? internal_a->entry : 0; | |
543 | ||
544 | return abfd->xvec; | |
545 | fail: | |
546 | bfd_release(abfd, coff); | |
547 | return (bfd_target *)NULL; | |
548 | } | |
549 | ||
550 | static bfd_target * | |
551 | DEFUN(coff_object_p,(abfd), | |
552 | bfd *abfd) | |
553 | { | |
554 | int nscns; | |
555 | FILHDR filehdr; | |
556 | AOUTHDR opthdr; | |
557 | struct internal_filehdr internal_f; | |
558 | struct internal_aouthdr internal_a; | |
559 | ||
560 | bfd_error = system_call_error; | |
561 | ||
562 | /* figure out how much to read */ | |
563 | if (bfd_read((PTR) &filehdr, 1, FILHSZ, abfd) != FILHSZ) | |
564 | return 0; | |
565 | ||
566 | swap_filehdr_in(abfd, &filehdr, &internal_f); | |
567 | ||
568 | if (BADMAG(internal_f)) { | |
569 | bfd_error = wrong_format; | |
570 | return 0; | |
571 | } | |
572 | nscns =internal_f.f_nscns; | |
573 | ||
574 | if (internal_f.f_opthdr) { | |
575 | if (bfd_read((PTR) &opthdr, 1,AOUTSZ, abfd) != AOUTSZ) { | |
576 | return 0; | |
577 | } | |
578 | swap_aouthdr_in(abfd, &opthdr, &internal_a); | |
579 | } | |
580 | ||
581 | /* Seek past the opt hdr stuff */ | |
582 | bfd_seek(abfd, internal_f.f_opthdr + FILHSZ, SEEK_SET); | |
583 | ||
584 | /* if the optional header is NULL or not the correct size then | |
585 | quit; the only difference I can see between m88k dgux headers (MC88DMAGIC) | |
586 | and Intel 960 readwrite headers (I960WRMAGIC) is that the | |
587 | optional header is of a different size. | |
588 | ||
589 | But the mips keeps extra stuff in it's opthdr, so dont check | |
590 | when doing that | |
591 | */ | |
592 | ||
593 | #ifndef MIPS | |
594 | if (internal_f.f_opthdr != 0 && AOUTSZ != internal_f.f_opthdr) | |
595 | return (bfd_target *)NULL; | |
596 | #endif | |
597 | ||
598 | return coff_real_object_p(abfd, nscns, &internal_f, &internal_a); | |
599 | } | |
600 | ||
601 |