ebdf2218ccbb44f7eca84baad675364954bc4be5
[deliverable/binutils-gdb.git] / bfd / coff-mips.c
1 /* MIPS Extended-Coff handler for Binary File Diddling.
2 Written by Per Bothner. */
3
4 /* Copyright (C) 1990, 1991 Free Software Foundation, Inc.
5
6 This file is part of BFD, the Binary File Diddler.
7
8 BFD 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 1, or (at your option)
11 any later version.
12
13 BFD 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 BFD; see the file COPYING. If not, write to
20 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
21
22 /* This does not compile on anything but a MIPS yet (and I haven't been
23 able to test it there either since the latest merge!). So it stays
24 out by default. */
25
26 #define MIPS 1
27 #include <stdio.h>
28 #include <string.h>
29
30 #include "bfd.h"
31 #include "libbfd.h"
32 #include "sysdep.h"
33
34 #include "intel-coff.h"
35 #include "libcoff.h" /* to allow easier abstraction-breaking */
36
37 /* initialize a section structure with information
38 * peculiar to this particular implementation of coff
39 */
40
41 static boolean
42 ecoff_new_section_hook(ignore_abfd, ignore)
43 bfd *ignore_abfd;
44 asection *ignore;
45 {
46 return true;
47 }
48
49 /* Take a section header read from a coff file (in HOST byte order),
50 and make a BFD "section" out of it. */
51 static boolean
52 DEFUN(make_a_section_from_file,(abfd, hdr),
53 bfd *abfd AND
54 struct scnhdr *hdr)
55 {
56 asection *return_section;
57
58 {
59 /* Assorted wastage to null-terminate the name, thanks AT&T! */
60 char *name = bfd_alloc(abfd, sizeof (hdr->s_name)+1);
61 if (name == NULL) {
62 bfd_error = no_memory;
63 return false;
64 }
65 strncpy(name, (char *) &hdr->s_name[0], sizeof (hdr->s_name));
66 name[sizeof (hdr->s_name)] = 0;
67
68 return_section = bfd_make_section(abfd, name);
69 }
70
71 /* s_paddr is presumed to be = to s_vaddr */
72 #define assign(to, from) return_section->to = hdr->from
73 assign(vma, s_vaddr);
74 /* assign (vma, s_vaddr); */
75 assign(size, s_size);
76 assign(filepos, s_scnptr);
77 assign(rel_filepos, s_relptr);
78 assign(reloc_count, s_nreloc);
79 assign(line_filepos, s_lnnoptr);
80 /*
81 return_section->linesize = hdr->s_nlnno * sizeof (struct lineno);
82 */
83
84 #undef assign
85 return_section->lineno_count = hdr->s_nlnno;
86 return_section->userdata = NULL;
87 return_section->next = (asection *) NULL;
88 if ((hdr->s_flags & STYP_TEXT) || (hdr->s_flags & STYP_DATA))
89 return_section->flags = (SEC_LOAD | SEC_ALLOC);
90 else if (hdr->s_flags & STYP_BSS)
91 return_section->flags = SEC_ALLOC;
92
93 if (hdr->s_nreloc != 0)
94 return_section->flags |= SEC_RELOC;
95 if (hdr->s_scnptr != 0)
96 return_section->flags |= SEC_HAS_CONTENTS;
97 return true;
98 }
99
100 bfd_target *
101 ecoff_real_object_p (abfd, nscns, opthdr)
102 bfd *abfd;
103 unsigned short nscns, opthdr;
104 {
105 struct icofdata *tdata;
106 char *file_info; /* buffer for all the headers */
107 long readsize; /* length of file_info */
108 struct filehdr* filehdr; /* points into file_info */
109 struct scnhdr *sections; /* points into file_info */
110
111 /* OK, now we know the format, read in the filehdr, soi-disant
112 "optional header", and all the sections.*/
113 readsize = sizeof(struct filehdr) + opthdr + (nscns * sizeof (struct scnhdr));
114 file_info = (char*)bfd_alloc (abfd, readsize);
115 if (file_info == NULL) {
116 bfd_error = no_memory;
117 return 0;
118 }
119 if (bfd_seek (abfd, 0, false) < 0) return 0;
120 if (bfd_read (file_info, 1, readsize, abfd) != readsize) return 0;
121 filehdr = (struct filehdr *) file_info;
122 sections = (struct scnhdr *) (file_info + sizeof (struct filehdr) + opthdr);
123
124 /* Now copy data as required; construct all asections etc */
125 tdata = (struct icofdata *) bfd_zalloc (abfd, sizeof (struct icofdata) +
126 sizeof (AOUTHDR));
127 if (tdata == NULL) {
128 bfd_release (abfd, file_info);
129 bfd_error = no_memory;
130 return 0;
131 }
132
133 if (nscns != 0)
134 {
135 unsigned int i;
136 for (i = 0; i < nscns; i++)
137 {
138 make_a_section_from_file (abfd, sections + i);
139 }
140 }
141
142 abfd->flags |= HAS_RELOC | HAS_LINENO | HAS_LOCALS;
143
144 /* FIXME, the guess should be set by OR-ing info from the sections */
145 if ((filehdr->f_flags & F_RELFLG) != F_RELFLG) abfd->flags &= ~HAS_RELOC;
146 if ((filehdr->f_flags & F_EXEC) == F_EXEC) abfd->flags |= EXEC_P;
147 if ((filehdr->f_flags & F_LNNO) != F_LNNO) abfd->flags &= ~HAS_LINENO;
148 if ((filehdr->f_flags & F_LSYMS) != F_LSYMS) abfd->flags &= ~HAS_LOCALS;
149 set_tdata (abfd, tdata);
150 bfd_get_symcount (abfd) = filehdr->f_nsyms;
151 if (filehdr->f_nsyms) abfd->flags |= HAS_SYMS;
152
153 tdata->sym_filepos = filehdr->f_symptr;
154 /* FIXME, needs byte swapping */
155 tdata->hdr = *(struct aouthdr *)(file_info + sizeof (struct filehdr));
156 tdata->symbols = (coff_symbol_type *)NULL;
157 bfd_get_start_address (abfd) = exec_hdr (abfd).entry;
158 return abfd->xvec;
159 }
160
161 bfd_target *
162 ecoff_object_p (abfd)
163 bfd *abfd;
164 {
165 unsigned char short_bytes[SHORT_SIZE];
166 unsigned short magic, nscns, opthdr;
167
168 bfd_error = no_error;
169
170 /* figure out how much to read */
171 if (bfd_read (short_bytes, 1, SHORT_SIZE, abfd) != SHORT_SIZE)
172 return 0;
173
174 magic = bfd_h_getshort (abfd, short_bytes);
175 if (magic != (abfd->xvec->byteorder_big_p ? 0x160 : 0x162)) {
176 bfd_error = wrong_format;
177 return 0;
178 }
179 if (bfd_read (short_bytes, 1, SHORT_SIZE, abfd) != SHORT_SIZE)
180 return 0;
181 nscns = bfd_h_getshort (abfd, short_bytes);
182
183 if (bfd_seek (abfd,(file_ptr) ((sizeof (long)) * 3), true) < 0)
184 return 0;
185 if (bfd_read (short_bytes, 1, SHORT_SIZE, abfd) != SHORT_SIZE)
186 return 0;
187 opthdr = bfd_h_getshort (abfd, short_bytes);
188
189 return ecoff_real_object_p (abfd, nscns, opthdr);
190 }
191
192 static boolean
193 ecoff_mkobject (abfd)
194 bfd *abfd;
195 {
196 char *rawptr;
197
198
199 bfd_error = no_error;
200
201 /* Use an intermediate variable for clarity */
202 rawptr = (char*)bfd_zalloc (abfd, sizeof (struct icofdata));
203 if (rawptr == NULL) {
204 bfd_error = no_memory;
205 return false;
206 }
207 set_tdata (abfd, rawptr);
208 return true;
209 }
210 \f
211 void
212 ecoff_write_linenumbers(ignore_abfd)
213 bfd *ignore_abfd;
214 {
215 }
216
217
218 static asymbol *
219 ecoff_make_empty_symbol(abfd)
220 bfd *abfd;
221 {
222 coff_symbol_type *new = (coff_symbol_type *) bfd_alloc(abfd, sizeof(coff_symbol_type));
223 if (new == NULL) {
224 bfd_error = no_memory;
225 return (NULL);
226 } /* on error */
227 new->native = 0;
228 new->lineno = (alent *) NULL;
229 new->symbol.the_bfd = abfd;
230 return &new->symbol;
231 }
232
233 /*SUPPRESS 558*/
234 /*SUPPRESS 529*/
235 boolean
236 ecoff_write_object_contents (ignore_abfd)
237 bfd *ignore_abfd;
238 {
239 return false;
240 }
241 \f
242 /* Calculate the file position for each section. */
243 /* ARGSUSED */
244 boolean
245 ecoff_set_section_contents (abfd, section, location, offset, count)
246 bfd *abfd;
247 sec_ptr section;
248 unsigned char *location;
249 file_ptr offset;
250 int count;
251 {
252 return false;
253 }
254
255 /* ARGSUSED */
256 boolean
257 ecoff_set_section_linenos (abfd, section, location, offset, count)
258 bfd *abfd;
259 sec_ptr section;
260 unsigned char *location;
261 file_ptr offset;
262 int count;
263 {
264 return 0;
265 }
266 \f
267
268 /* ARGSUSED */
269 boolean
270 ecoff_close_and_cleanup (abfd)
271 bfd *abfd;
272 {
273 return false;
274 }
275 \f
276 /* ARGSUSED */
277 static boolean
278 ecoff_slurp_symbol_table(abfd)
279 bfd *abfd;
280 {
281 abort();
282 }
283
284 unsigned int
285 ecoff_get_symtab_upper_bound (abfd)
286 bfd *abfd;
287 {
288 if (!ecoff_slurp_symbol_table (abfd)) return 0;
289
290 return (bfd_get_symcount (abfd)+1) * (sizeof (coff_symbol_type *));
291 }
292
293
294 unsigned int
295 ecoff_get_symtab(abfd, alocation)
296 bfd *abfd;
297 asymbol **alocation;
298 {
299 unsigned int counter = 0;
300 coff_symbol_type *symbase;
301 coff_symbol_type **location = (coff_symbol_type **)(alocation);
302
303 if (!ecoff_slurp_symbol_table (abfd)) return 0;
304
305 for (symbase = obj_symbols (abfd); counter++ < bfd_get_symcount (abfd);)
306 *(location++) = symbase++;
307 *location++ =0;
308 return counter;
309 }
310
311 unsigned int
312 ecoff_get_reloc_upper_bound (abfd, asect)
313 bfd *abfd;
314 sec_ptr asect;
315 {
316 if (bfd_get_format (abfd) != bfd_object) {
317 bfd_error = invalid_operation;
318 return 0;
319 }
320
321 return (asect->reloc_count + 1) * sizeof(arelent *);
322 }
323
324
325
326 /* ARGSUSED */
327 boolean
328 ecoff_slurp_reloc_table (abfd, asect)
329 bfd *abfd;
330 sec_ptr asect;
331 {
332 abort();
333 }
334
335
336 /* This is stupid. This function should be a boolean predicate */
337 unsigned int
338 ecoff_canonicalize_reloc (abfd, section, relptr)
339 bfd *abfd;
340 sec_ptr section;
341 arelent **relptr;
342 {
343 return 0;
344 }
345
346 boolean
347 ecoff_get_section_contents (abfd, section, location, offset, count)
348 bfd *abfd;
349 sec_ptr section;
350 PTR location;
351 file_ptr offset;
352 int count;
353 {
354 if (count) {
355 if (offset >= section->size) return false;
356
357 bfd_seek (abfd, section->filepos + offset, SEEK_SET);
358
359 return (bfd_read (location, 1, count, abfd) == count) ? true:false;
360 }
361 else return true;
362 }
363
364 /* ARGSUSED */
365 alent *
366 ecoff_get_lineno(ignore_abfd, ignore_symbol)
367 bfd *ignore_abfd;
368 PTR ignore_symbol;
369 {
370 return (alent *)NULL;
371 }
372
373 #define ecoff_core_file_failing_command _bfd_dummy_core_file_failing_command
374 #define ecoff_core_file_failing_signal _bfd_dummy_core_file_failing_signal
375 #define ecoff_core_file_matches_executable_p _bfd_dummy_core_file_matches_executable_p
376 #define ecoff_slurp_armap bfd_false
377 #define ecoff_slurp_extended_name_table bfd_false
378 #define ecoff_truncate_arname bfd_void
379 #define ecoff_write_armap bfd_false
380 #define ecoff_print_symbol bfd_void
381 #define ecoff_set_arch_mach bfd_false
382 #define ecoff_openr_next_archived_file bfd_generic_openr_next_archived_file
383 #define ecoff_find_nearest_line bfd_false
384 #define ecoff_generic_stat_arch_elt bfd_generic_stat_arch_elt
385 #define ecoff_sizeof_headers bfd_0
386
387 bfd_target ecoff_little_vec =
388 {"ecoff-littlemips", /* name */
389 bfd_target_coff_flavour_enum,
390 false, /* data byte order is little */
391 false, /* header byte order is little */
392
393 (HAS_RELOC | EXEC_P | /* object flags */
394 HAS_LINENO | HAS_DEBUG |
395 HAS_SYMS | HAS_LOCALS | DYNAMIC | WP_TEXT),
396
397 (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
398 '/', /* ar_pad_char */
399 15, /* ar_max_namelen */
400 _do_getllong, _do_putllong, _do_getlshort, _do_putlshort, /* data */
401 _do_getllong, _do_putllong, _do_getlshort, _do_putlshort, /* hdrs */
402
403 {_bfd_dummy_target, ecoff_object_p, /* bfd_check_format */
404 bfd_generic_archive_p, _bfd_dummy_target},
405 {bfd_false, ecoff_mkobject, bfd_false, /* bfd_set_format */
406 bfd_false},
407 JUMP_TABLE (ecoff)
408 };
409
410 bfd_target ecoff_big_vec =
411 {"ecoff-bigmips", /* name */
412 bfd_target_coff_flavour_enum,
413 true, /* data byte order is big */
414 true, /* header byte order is big */
415
416 (HAS_RELOC | EXEC_P | /* object flags */
417 HAS_LINENO | HAS_DEBUG |
418 HAS_SYMS | HAS_LOCALS | DYNAMIC | WP_TEXT),
419
420 (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
421 ' ', /* ar_pad_char */
422 16, /* ar_max_namelen */
423 _do_getblong, _do_putblong, _do_getbshort, _do_putbshort, /* data */
424 _do_getblong, _do_putblong, _do_getbshort, _do_putbshort, /* hdrs */
425
426 {_bfd_dummy_target, ecoff_object_p, /* bfd_check_format */
427 bfd_generic_archive_p, _bfd_dummy_target},
428 {bfd_false, ecoff_mkobject, bfd_false, /* bfd_set_format */
429 bfd_false},
430 JUMP_TABLE(ecoff)
431 };
This page took 0.040662 seconds and 4 git commands to generate.