source: trunk/src/binutils/bfd/aout-adobe.c@ 524

Last change on this file since 524 was 10, checked in by bird, 22 years ago

Initial revision

  • Property cvs2svn:cvs-rev set to 1.1
  • Property svn:eol-style set to native
  • Property svn:executable set to *
File size: 16.1 KB
Line 
1/* BFD back-end for a.out.adobe binaries.
2 Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000
3 Free Software Foundation, Inc.
4 Written by Cygnus Support. Based on bout.c.
5
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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
21
22#include "bfd.h"
23#include "sysdep.h"
24#include "libbfd.h"
25
26#include "aout/adobe.h"
27
28#include "aout/stab_gnu.h"
29#include "libaout.h" /* BFD a.out internal data structures */
30
31/* Forward decl. */
32extern const bfd_target a_out_adobe_vec;
33
34static const bfd_target *aout_adobe_callback PARAMS ((bfd *));
35
36extern boolean aout_32_slurp_symbol_table PARAMS ((bfd *abfd));
37extern boolean aout_32_write_syms PARAMS ((bfd *));
38static void aout_adobe_write_section PARAMS ((bfd *abfd, sec_ptr sect));
39
40/* Swaps the information in an executable header taken from a raw byte
41 stream memory image, into the internal exec_header structure. */
42
43void aout_adobe_swap_exec_header_in
44 PARAMS ((bfd *abfd, struct external_exec *raw_bytes,
45 struct internal_exec *execp));
46
47void
48aout_adobe_swap_exec_header_in (abfd, raw_bytes, execp)
49 bfd *abfd;
50 struct external_exec *raw_bytes;
51 struct internal_exec *execp;
52{
53 struct external_exec *bytes = (struct external_exec *) raw_bytes;
54
55 /* Now fill in fields in the execp, from the bytes in the raw data. */
56 execp->a_info = bfd_h_get_32 (abfd, bytes->e_info);
57 execp->a_text = GET_WORD (abfd, bytes->e_text);
58 execp->a_data = GET_WORD (abfd, bytes->e_data);
59 execp->a_bss = GET_WORD (abfd, bytes->e_bss);
60 execp->a_syms = GET_WORD (abfd, bytes->e_syms);
61 execp->a_entry = GET_WORD (abfd, bytes->e_entry);
62 execp->a_trsize = GET_WORD (abfd, bytes->e_trsize);
63 execp->a_drsize = GET_WORD (abfd, bytes->e_drsize);
64}
65
66/* Swaps the information in an internal exec header structure into the
67 supplied buffer ready for writing to disk. */
68
69PROTO(void, aout_adobe_swap_exec_header_out,
70 (bfd *abfd,
71 struct internal_exec *execp,
72 struct external_exec *raw_bytes));
73void
74aout_adobe_swap_exec_header_out (abfd, execp, raw_bytes)
75 bfd *abfd;
76 struct internal_exec *execp;
77 struct external_exec *raw_bytes;
78{
79 struct external_exec *bytes = (struct external_exec *) raw_bytes;
80
81 /* Now fill in fields in the raw data, from the fields in the exec
82 struct. */
83 bfd_h_put_32 (abfd, execp->a_info , bytes->e_info);
84 PUT_WORD (abfd, execp->a_text , bytes->e_text);
85 PUT_WORD (abfd, execp->a_data , bytes->e_data);
86 PUT_WORD (abfd, execp->a_bss , bytes->e_bss);
87 PUT_WORD (abfd, execp->a_syms , bytes->e_syms);
88 PUT_WORD (abfd, execp->a_entry , bytes->e_entry);
89 PUT_WORD (abfd, execp->a_trsize, bytes->e_trsize);
90 PUT_WORD (abfd, execp->a_drsize, bytes->e_drsize);
91}
92
93static const bfd_target *
94aout_adobe_object_p (abfd)
95 bfd *abfd;
96{
97 struct internal_exec anexec;
98 struct external_exec exec_bytes;
99 char *targ;
100
101 if (bfd_read ((PTR) &exec_bytes, 1, EXEC_BYTES_SIZE, abfd)
102 != EXEC_BYTES_SIZE)
103 {
104 if (bfd_get_error () != bfd_error_system_call)
105 bfd_set_error (bfd_error_wrong_format);
106 return 0;
107 }
108
109 anexec.a_info = bfd_h_get_32 (abfd, exec_bytes.e_info);
110
111 /* Normally we just compare for the magic number.
112 However, a bunch of Adobe tools aren't fixed up yet; they generate
113 files using ZMAGIC(!).
114 If the environment variable GNUTARGET is set to "a.out.adobe", we will
115 take just about any a.out file as an Adobe a.out file. FIXME! */
116
117 if (N_BADMAG (anexec))
118 {
119 targ = getenv ("GNUTARGET");
120 if (targ && !strcmp (targ, a_out_adobe_vec.name))
121 /* Just continue anyway, if specifically set to this format. */
122 ;
123 else
124 {
125 bfd_set_error (bfd_error_wrong_format);
126 return 0;
127 }
128 }
129
130 aout_adobe_swap_exec_header_in (abfd, &exec_bytes, &anexec);
131 return aout_32_some_aout_object_p (abfd, &anexec, aout_adobe_callback);
132}
133
134/* Finish up the opening of a b.out file for reading. Fill in all the
135 fields that are not handled by common code. */
136
137static const bfd_target *
138aout_adobe_callback (abfd)
139 bfd *abfd;
140{
141 struct internal_exec *execp = exec_hdr (abfd);
142 asection *sect;
143 struct external_segdesc ext[1];
144 char *section_name;
145 char try_again[30]; /* name and number */
146 char *newname;
147 int trynum;
148 flagword flags;
149
150 /* Architecture and machine type -- unknown in this format. */
151 bfd_set_arch_mach (abfd, bfd_arch_unknown, 0);
152
153 /* The positions of the string table and symbol table. */
154 obj_str_filepos (abfd) = N_STROFF (*execp);
155 obj_sym_filepos (abfd) = N_SYMOFF (*execp);
156
157 /* Suck up the section information from the file, one section at a time. */
158
159 for (;;)
160 {
161 if (bfd_read ((PTR) ext, 1, sizeof (*ext), abfd) != sizeof (*ext))
162 {
163 if (bfd_get_error () != bfd_error_system_call)
164 bfd_set_error (bfd_error_wrong_format);
165 return 0;
166 }
167 switch (ext->e_type[0])
168 {
169 case N_TEXT:
170 section_name = ".text";
171 flags = SEC_CODE | SEC_LOAD | SEC_ALLOC | SEC_HAS_CONTENTS;
172 break;
173
174 case N_DATA:
175 section_name = ".data";
176 flags = SEC_DATA | SEC_LOAD | SEC_ALLOC | SEC_HAS_CONTENTS;
177 break;
178
179 case N_BSS:
180 section_name = ".bss";
181 flags = SEC_DATA | SEC_HAS_CONTENTS;
182 break;
183
184 case 0:
185 goto no_more_sections;
186
187 default:
188 (*_bfd_error_handler)
189 (_("%s: Unknown section type in a.out.adobe file: %x\n"),
190 bfd_get_filename (abfd), ext->e_type[0]);
191 goto no_more_sections;
192 }
193
194 /* First one is called ".text" or whatever; subsequent ones are
195 ".text1", ".text2", ... */
196
197 bfd_set_error (bfd_error_no_error);
198 sect = bfd_make_section (abfd, section_name);
199 trynum = 0;
200 while (!sect)
201 {
202 if (bfd_get_error () != bfd_error_no_error)
203 /* Some other error -- slide into the sunset. */
204 return 0;
205 sprintf (try_again, "%s%d", section_name, ++trynum);
206 sect = bfd_make_section (abfd, try_again);
207 }
208
209 /* Fix the name, if it is a sprintf'd name. */
210 if (sect->name == try_again)
211 {
212 newname = (char *) bfd_zalloc (abfd, strlen (sect->name));
213 if (newname == NULL)
214 return 0;
215 strcpy (newname, sect->name);
216 sect->name = newname;
217 }
218
219 /* Now set the section's attributes. */
220 bfd_set_section_flags (abfd, sect, flags);
221 /* Assumed big-endian. */
222 sect->_raw_size = ((ext->e_size[0] << 8)
223 | ext->e_size[1] << 8)
224 | ext->e_size[2];
225 sect->_cooked_size = sect->_raw_size;
226 sect->vma = bfd_h_get_32 (abfd, ext->e_virtbase);
227 sect->filepos = bfd_h_get_32 (abfd, ext->e_filebase);
228 /* FIXME XXX alignment? */
229
230 /* Set relocation information for first section of each type. */
231 if (trynum == 0)
232 switch (ext->e_type[0])
233 {
234 case N_TEXT:
235 sect->rel_filepos = N_TRELOFF (*execp);
236 sect->reloc_count = execp->a_trsize;
237 break;
238
239 case N_DATA:
240 sect->rel_filepos = N_DRELOFF (*execp);
241 sect->reloc_count = execp->a_drsize;
242 break;
243 }
244 }
245 no_more_sections:
246
247 adata (abfd).reloc_entry_size = sizeof (struct reloc_std_external);
248 adata (abfd).symbol_entry_size = sizeof (struct external_nlist);
249 adata (abfd).page_size = 1; /* Not applicable. */
250 adata (abfd).segment_size = 1; /* Not applicable. */
251 adata (abfd).exec_bytes_size = EXEC_BYTES_SIZE;
252
253 return abfd->xvec;
254}
255
256struct bout_data_struct {
257 struct aoutdata a;
258 struct internal_exec e;
259};
260
261static boolean
262aout_adobe_mkobject (abfd)
263 bfd *abfd;
264{
265 struct bout_data_struct *rawptr;
266
267 rawptr = (struct bout_data_struct *) bfd_zalloc (abfd, sizeof (struct bout_data_struct));
268 if (rawptr == NULL)
269 return false;
270
271 abfd->tdata.bout_data = rawptr;
272 exec_hdr (abfd) = &rawptr->e;
273
274 adata (abfd).reloc_entry_size = sizeof (struct reloc_std_external);
275 adata (abfd).symbol_entry_size = sizeof (struct external_nlist);
276 adata (abfd).page_size = 1; /* Not applicable. */
277 adata (abfd).segment_size = 1; /* Not applicable. */
278 adata (abfd).exec_bytes_size = EXEC_BYTES_SIZE;
279
280 return true;
281}
282
283static boolean
284aout_adobe_write_object_contents (abfd)
285 bfd *abfd;
286{
287 struct external_exec swapped_hdr;
288 static struct external_segdesc sentinel[1]; /* Initialized to zero. */
289 asection *sect;
290
291 exec_hdr (abfd)->a_info = ZMAGIC;
292
293 /* Calculate text size as total of text sections, etc. */
294
295 exec_hdr (abfd)->a_text = 0;
296 exec_hdr (abfd)->a_data = 0;
297 exec_hdr (abfd)->a_bss = 0;
298 exec_hdr (abfd)->a_trsize = 0;
299 exec_hdr (abfd)->a_drsize = 0;
300
301 for (sect = abfd->sections; sect; sect = sect->next)
302 {
303 if (sect->flags & SEC_CODE)
304 {
305 exec_hdr (abfd)->a_text += sect->_raw_size;
306 exec_hdr (abfd)->a_trsize += sect->reloc_count *
307 sizeof (struct reloc_std_external);
308 }
309 else if (sect->flags & SEC_DATA)
310 {
311 exec_hdr (abfd)->a_data += sect->_raw_size;
312 exec_hdr (abfd)->a_drsize += sect->reloc_count *
313 sizeof (struct reloc_std_external);
314 }
315 else if (sect->flags & SEC_ALLOC && !(sect->flags & SEC_LOAD))
316 {
317 exec_hdr (abfd)->a_bss += sect->_raw_size;
318 }
319 }
320
321 exec_hdr (abfd)->a_syms = bfd_get_symcount (abfd)
322 * sizeof (struct external_nlist);
323 exec_hdr (abfd)->a_entry = bfd_get_start_address (abfd);
324
325 aout_adobe_swap_exec_header_out (abfd, exec_hdr (abfd), &swapped_hdr);
326
327 if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0
328 || (bfd_write ((PTR) &swapped_hdr, 1, EXEC_BYTES_SIZE, abfd)
329 != EXEC_BYTES_SIZE))
330 return false;
331
332 /* Now write out the section information. Text first, data next, rest
333 afterward. */
334
335 for (sect = abfd->sections; sect; sect = sect->next)
336 {
337 if (sect->flags & SEC_CODE)
338 {
339 aout_adobe_write_section (abfd, sect);
340 }
341 }
342 for (sect = abfd->sections; sect; sect = sect->next)
343 {
344 if (sect->flags & SEC_DATA)
345 {
346 aout_adobe_write_section (abfd, sect);
347 }
348 }
349 for (sect = abfd->sections; sect; sect = sect->next)
350 {
351 if (!(sect->flags & (SEC_CODE | SEC_DATA)))
352 {
353 aout_adobe_write_section (abfd, sect);
354 }
355 }
356
357 /* Write final `sentinel` section header (with type of 0). */
358 if (bfd_write ((PTR) sentinel, 1, sizeof (*sentinel), abfd)
359 != sizeof (*sentinel))
360 return false;
361
362 /* Now write out reloc info, followed by syms and strings. */
363 if (bfd_get_symcount (abfd) != 0)
364 {
365 if (bfd_seek (abfd, (file_ptr) (N_SYMOFF (*exec_hdr (abfd))), SEEK_SET)
366 != 0)
367 return false;
368
369 if (! aout_32_write_syms (abfd))
370 return false;
371
372 if (bfd_seek (abfd, (file_ptr) (N_TRELOFF (*exec_hdr (abfd))), SEEK_SET)
373 != 0)
374 return false;
375
376 for (sect = abfd->sections; sect; sect = sect->next)
377 {
378 if (sect->flags & SEC_CODE)
379 {
380 if (!aout_32_squirt_out_relocs (abfd, sect))
381 return false;
382 }
383 }
384
385 if (bfd_seek (abfd, (file_ptr) (N_DRELOFF (*exec_hdr (abfd))), SEEK_SET)
386 != 0)
387 return false;
388
389 for (sect = abfd->sections; sect; sect = sect->next)
390 {
391 if (sect->flags & SEC_DATA)
392 {
393 if (!aout_32_squirt_out_relocs (abfd, sect))
394 return false;
395 }
396 }
397 }
398 return true;
399}
400
401static void
402aout_adobe_write_section (abfd, sect)
403 bfd *abfd ATTRIBUTE_UNUSED;
404 sec_ptr sect ATTRIBUTE_UNUSED;
405{
406 /* FIXME XXX */
407}
408
409
410static boolean
411aout_adobe_set_section_contents (abfd, section, location, offset, count)
412 bfd *abfd;
413 asection *section;
414 PTR location;
415 file_ptr offset;
416 bfd_size_type count;
417{
418 file_ptr section_start;
419 sec_ptr sect;
420
421 /* Set by bfd.c handler. */
422 if (abfd->output_has_begun == false)
423 {
424 /* Assign file offsets to sections. Text sections are first, and
425 are contiguous. Then data sections. Everything else at the end. */
426
427 section_start = N_TXTOFF (ignore<-->me);
428
429 for (sect = abfd->sections; sect; sect = sect->next)
430 {
431 if (sect->flags & SEC_CODE)
432 {
433 sect->filepos = section_start;
434 /* FIXME: Round to alignment. */
435 section_start += sect->_raw_size;
436 }
437 }
438
439 for (sect = abfd->sections; sect; sect = sect->next)
440 {
441 if (sect->flags & SEC_DATA)
442 {
443 sect->filepos = section_start;
444 /* FIXME: Round to alignment. */
445 section_start += sect->_raw_size;
446 }
447 }
448
449 for (sect = abfd->sections; sect; sect = sect->next)
450 {
451 if (sect->flags & SEC_HAS_CONTENTS &&
452 !(sect->flags & (SEC_CODE | SEC_DATA)))
453 {
454 sect->filepos = section_start;
455 /* FIXME: Round to alignment. */
456 section_start += sect->_raw_size;
457 }
458 }
459 }
460
461 /* Regardless, once we know what we're doing, we might as well get
462 going. */
463 if (bfd_seek (abfd, section->filepos + offset, SEEK_SET) != 0)
464 return false;
465
466 if (count != 0)
467 {
468 return (bfd_write ((PTR) location, 1, count, abfd) == count) ? true : false;
469 }
470 return true;
471}
472
473static boolean
474aout_adobe_set_arch_mach (abfd, arch, machine)
475 bfd *abfd;
476 enum bfd_architecture arch;
477 unsigned long machine;
478{
479 if (! bfd_default_set_arch_mach (abfd, arch, machine))
480 return false;
481
482 if (arch == bfd_arch_unknown
483 || arch == bfd_arch_m68k)
484 return true;
485
486 return false;
487}
488
489static int
490aout_adobe_sizeof_headers (ignore_abfd, ignore)
491 bfd *ignore_abfd ATTRIBUTE_UNUSED;
492 boolean ignore ATTRIBUTE_UNUSED;
493{
494 return sizeof (struct internal_exec);
495}
496
497/* Build the transfer vector for Adobe A.Out files. */
498
499#define aout_32_close_and_cleanup aout_32_bfd_free_cached_info
500
501#define aout_32_bfd_make_debug_symbol \
502 ((asymbol *(*) PARAMS ((bfd *, void *, unsigned long))) bfd_nullvoidptr)
503
504#define aout_32_bfd_reloc_type_lookup \
505 ((reloc_howto_type *(*) \
506 PARAMS ((bfd *, bfd_reloc_code_real_type))) bfd_nullvoidptr)
507
508#define aout_32_set_arch_mach aout_adobe_set_arch_mach
509#define aout_32_set_section_contents aout_adobe_set_section_contents
510
511#define aout_32_sizeof_headers aout_adobe_sizeof_headers
512#define aout_32_bfd_get_relocated_section_contents \
513 bfd_generic_get_relocated_section_contents
514#define aout_32_get_section_contents_in_window _bfd_generic_get_section_contents_in_window
515#define aout_32_bfd_relax_section bfd_generic_relax_section
516#define aout_32_bfd_gc_sections bfd_generic_gc_sections
517#define aout_32_bfd_link_hash_table_create \
518 _bfd_generic_link_hash_table_create
519#define aout_32_bfd_link_add_symbols _bfd_generic_link_add_symbols
520#define aout_32_bfd_final_link _bfd_generic_final_link
521#define aout_32_bfd_link_split_section _bfd_generic_link_split_section
522
523const bfd_target a_out_adobe_vec = {
524 "a.out.adobe", /* name */
525 bfd_target_aout_flavour,
526 BFD_ENDIAN_BIG, /* data byte order is unknown (big assumed) */
527 BFD_ENDIAN_BIG, /* hdr byte order is big */
528 (HAS_RELOC | EXEC_P | /* object flags */
529 HAS_LINENO | HAS_DEBUG |
530 HAS_SYMS | HAS_LOCALS | WP_TEXT ),
531 /* section flags */
532 (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_CODE | SEC_DATA | SEC_RELOC),
533 '_', /* symbol leading char */
534 ' ', /* ar_pad_char */
535 16, /* ar_max_namelen */
536
537 bfd_getb64, bfd_getb_signed_64, bfd_putb64,
538 bfd_getb32, bfd_getb_signed_32, bfd_putb32,
539 bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* data */
540 bfd_getb64, bfd_getb_signed_64, bfd_putb64,
541 bfd_getb32, bfd_getb_signed_32, bfd_putb32,
542 bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* hdrs */
543 {_bfd_dummy_target, aout_adobe_object_p, /* bfd_check_format */
544 bfd_generic_archive_p, _bfd_dummy_target},
545 {bfd_false, aout_adobe_mkobject, /* bfd_set_format */
546 _bfd_generic_mkarchive, bfd_false},
547 {bfd_false, aout_adobe_write_object_contents, /* bfd_write_contents */
548 _bfd_write_archive_contents, bfd_false},
549
550 BFD_JUMP_TABLE_GENERIC (aout_32),
551 BFD_JUMP_TABLE_COPY (_bfd_generic),
552 BFD_JUMP_TABLE_CORE (_bfd_nocore),
553 BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_bsd),
554 BFD_JUMP_TABLE_SYMBOLS (aout_32),
555 BFD_JUMP_TABLE_RELOCS (aout_32),
556 BFD_JUMP_TABLE_WRITE (aout_32),
557 BFD_JUMP_TABLE_LINK (aout_32),
558 BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
559
560 NULL,
561
562 (PTR) 0
563};
Note: See TracBrowser for help on using the repository browser.