1 /* BFD back-end for a.out.adobe binaries.
2 Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001
3 Free Software Foundation, Inc.
4 Written by Cygnus Support. Based on bout.c.
6 This file is part of BFD, the Binary File Descriptor library.
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.
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.
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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
26 #include "aout/adobe.h"
28 #include "aout/stab_gnu.h"
29 #include "libaout.h" /* BFD a.out internal data structures. */
32 extern const bfd_target a_out_adobe_vec;
34 static const bfd_target *aout_adobe_callback PARAMS ((bfd *));
36 extern boolean aout_32_slurp_symbol_table PARAMS ((bfd *abfd));
37 extern boolean aout_32_write_syms PARAMS ((bfd *));
38 static void aout_adobe_write_section PARAMS ((bfd *abfd, sec_ptr sect));
39 static const bfd_target * aout_adobe_object_p PARAMS ((bfd *));
40 static boolean aout_adobe_mkobject PARAMS ((bfd *));
41 static boolean aout_adobe_write_object_contents PARAMS ((bfd *));
42 static boolean aout_adobe_set_section_contents PARAMS ((bfd *, asection *, PTR, file_ptr, bfd_size_type));
43 static boolean aout_adobe_set_arch_mach PARAMS ((bfd *, enum bfd_architecture, unsigned long));
44 static int aout_adobe_sizeof_headers PARAMS ((bfd *, boolean));
46 /* Swaps the information in an executable header taken from a raw byte
47 stream memory image, into the internal exec_header structure. */
49 void aout_adobe_swap_exec_header_in
50 PARAMS ((bfd *abfd, struct external_exec *raw_bytes,
51 struct internal_exec *execp));
54 aout_adobe_swap_exec_header_in (abfd, raw_bytes, execp)
56 struct external_exec *raw_bytes;
57 struct internal_exec *execp;
59 struct external_exec *bytes = (struct external_exec *) raw_bytes;
61 /* Now fill in fields in the execp, from the bytes in the raw data. */
62 execp->a_info = bfd_h_get_32 (abfd, bytes->e_info);
63 execp->a_text = GET_WORD (abfd, bytes->e_text);
64 execp->a_data = GET_WORD (abfd, bytes->e_data);
65 execp->a_bss = GET_WORD (abfd, bytes->e_bss);
66 execp->a_syms = GET_WORD (abfd, bytes->e_syms);
67 execp->a_entry = GET_WORD (abfd, bytes->e_entry);
68 execp->a_trsize = GET_WORD (abfd, bytes->e_trsize);
69 execp->a_drsize = GET_WORD (abfd, bytes->e_drsize);
72 /* Swaps the information in an internal exec header structure into the
73 supplied buffer ready for writing to disk. */
75 PROTO(void, aout_adobe_swap_exec_header_out,
77 struct internal_exec *execp,
78 struct external_exec *raw_bytes));
80 aout_adobe_swap_exec_header_out (abfd, execp, raw_bytes)
82 struct internal_exec *execp;
83 struct external_exec *raw_bytes;
85 struct external_exec *bytes = (struct external_exec *) raw_bytes;
87 /* Now fill in fields in the raw data, from the fields in the exec
89 bfd_h_put_32 (abfd, execp->a_info , bytes->e_info);
90 PUT_WORD (abfd, execp->a_text , bytes->e_text);
91 PUT_WORD (abfd, execp->a_data , bytes->e_data);
92 PUT_WORD (abfd, execp->a_bss , bytes->e_bss);
93 PUT_WORD (abfd, execp->a_syms , bytes->e_syms);
94 PUT_WORD (abfd, execp->a_entry , bytes->e_entry);
95 PUT_WORD (abfd, execp->a_trsize, bytes->e_trsize);
96 PUT_WORD (abfd, execp->a_drsize, bytes->e_drsize);
99 static const bfd_target *
100 aout_adobe_object_p (abfd)
103 struct internal_exec anexec;
104 struct external_exec exec_bytes;
107 if (bfd_read ((PTR) &exec_bytes, 1, EXEC_BYTES_SIZE, abfd)
110 if (bfd_get_error () != bfd_error_system_call)
111 bfd_set_error (bfd_error_wrong_format);
115 anexec.a_info = bfd_h_get_32 (abfd, exec_bytes.e_info);
117 /* Normally we just compare for the magic number.
118 However, a bunch of Adobe tools aren't fixed up yet; they generate
119 files using ZMAGIC(!).
120 If the environment variable GNUTARGET is set to "a.out.adobe", we will
121 take just about any a.out file as an Adobe a.out file. FIXME! */
123 if (N_BADMAG (anexec))
125 targ = getenv ("GNUTARGET");
126 if (targ && !strcmp (targ, a_out_adobe_vec.name))
127 /* Just continue anyway, if specifically set to this format. */
131 bfd_set_error (bfd_error_wrong_format);
136 aout_adobe_swap_exec_header_in (abfd, &exec_bytes, &anexec);
137 return aout_32_some_aout_object_p (abfd, &anexec, aout_adobe_callback);
140 /* Finish up the opening of a b.out file for reading. Fill in all the
141 fields that are not handled by common code. */
143 static const bfd_target *
144 aout_adobe_callback (abfd)
147 struct internal_exec *execp = exec_hdr (abfd);
149 struct external_segdesc ext[1];
151 char try_again[30]; /* Name and number. */
156 /* Architecture and machine type -- unknown in this format. */
157 bfd_set_arch_mach (abfd, bfd_arch_unknown, 0);
159 /* The positions of the string table and symbol table. */
160 obj_str_filepos (abfd) = N_STROFF (*execp);
161 obj_sym_filepos (abfd) = N_SYMOFF (*execp);
163 /* Suck up the section information from the file, one section at a time. */
166 if (bfd_read ((PTR) ext, 1, sizeof (*ext), abfd) != sizeof (*ext))
168 if (bfd_get_error () != bfd_error_system_call)
169 bfd_set_error (bfd_error_wrong_format);
173 switch (ext->e_type[0])
176 section_name = ".text";
177 flags = SEC_CODE | SEC_LOAD | SEC_ALLOC | SEC_HAS_CONTENTS;
181 section_name = ".data";
182 flags = SEC_DATA | SEC_LOAD | SEC_ALLOC | SEC_HAS_CONTENTS;
186 section_name = ".bss";
187 flags = SEC_DATA | SEC_HAS_CONTENTS;
191 goto no_more_sections;
194 (*_bfd_error_handler)
195 (_("%s: Unknown section type in a.out.adobe file: %x\n"),
196 bfd_get_filename (abfd), ext->e_type[0]);
197 goto no_more_sections;
200 /* First one is called ".text" or whatever; subsequent ones are
201 ".text1", ".text2", ... */
202 bfd_set_error (bfd_error_no_error);
203 sect = bfd_make_section (abfd, section_name);
208 if (bfd_get_error () != bfd_error_no_error)
209 /* Some other error -- slide into the sunset. */
211 sprintf (try_again, "%s%d", section_name, ++trynum);
212 sect = bfd_make_section (abfd, try_again);
215 /* Fix the name, if it is a sprintf'd name. */
216 if (sect->name == try_again)
218 newname = (char *) bfd_zalloc (abfd, strlen (sect->name));
221 strcpy (newname, sect->name);
222 sect->name = newname;
225 /* Now set the section's attributes. */
226 bfd_set_section_flags (abfd, sect, flags);
227 /* Assumed big-endian. */
228 sect->_raw_size = ((ext->e_size[0] << 8)
229 | ext->e_size[1] << 8)
231 sect->_cooked_size = sect->_raw_size;
232 sect->vma = bfd_h_get_32 (abfd, ext->e_virtbase);
233 sect->filepos = bfd_h_get_32 (abfd, ext->e_filebase);
234 /* FIXME XXX alignment? */
236 /* Set relocation information for first section of each type. */
238 switch (ext->e_type[0])
241 sect->rel_filepos = N_TRELOFF (*execp);
242 sect->reloc_count = execp->a_trsize;
246 sect->rel_filepos = N_DRELOFF (*execp);
247 sect->reloc_count = execp->a_drsize;
256 adata (abfd).reloc_entry_size = sizeof (struct reloc_std_external);
257 adata (abfd).symbol_entry_size = sizeof (struct external_nlist);
258 adata (abfd).page_size = 1; /* Not applicable. */
259 adata (abfd).segment_size = 1; /* Not applicable. */
260 adata (abfd).exec_bytes_size = EXEC_BYTES_SIZE;
265 struct bout_data_struct
268 struct internal_exec e;
272 aout_adobe_mkobject (abfd)
275 struct bout_data_struct *rawptr;
277 rawptr = (struct bout_data_struct *) bfd_zalloc (abfd, sizeof (struct bout_data_struct));
281 abfd->tdata.bout_data = rawptr;
282 exec_hdr (abfd) = &rawptr->e;
284 adata (abfd).reloc_entry_size = sizeof (struct reloc_std_external);
285 adata (abfd).symbol_entry_size = sizeof (struct external_nlist);
286 adata (abfd).page_size = 1; /* Not applicable. */
287 adata (abfd).segment_size = 1; /* Not applicable. */
288 adata (abfd).exec_bytes_size = EXEC_BYTES_SIZE;
294 aout_adobe_write_object_contents (abfd)
297 struct external_exec swapped_hdr;
298 static struct external_segdesc sentinel[1]; /* Initialized to zero. */
301 exec_hdr (abfd)->a_info = ZMAGIC;
303 /* Calculate text size as total of text sections, etc. */
305 exec_hdr (abfd)->a_text = 0;
306 exec_hdr (abfd)->a_data = 0;
307 exec_hdr (abfd)->a_bss = 0;
308 exec_hdr (abfd)->a_trsize = 0;
309 exec_hdr (abfd)->a_drsize = 0;
311 for (sect = abfd->sections; sect; sect = sect->next)
313 if (sect->flags & SEC_CODE)
315 exec_hdr (abfd)->a_text += sect->_raw_size;
316 exec_hdr (abfd)->a_trsize += sect->reloc_count *
317 sizeof (struct reloc_std_external);
319 else if (sect->flags & SEC_DATA)
321 exec_hdr (abfd)->a_data += sect->_raw_size;
322 exec_hdr (abfd)->a_drsize += sect->reloc_count *
323 sizeof (struct reloc_std_external);
325 else if (sect->flags & SEC_ALLOC && !(sect->flags & SEC_LOAD))
327 exec_hdr (abfd)->a_bss += sect->_raw_size;
331 exec_hdr (abfd)->a_syms = bfd_get_symcount (abfd)
332 * sizeof (struct external_nlist);
333 exec_hdr (abfd)->a_entry = bfd_get_start_address (abfd);
335 aout_adobe_swap_exec_header_out (abfd, exec_hdr (abfd), &swapped_hdr);
337 if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0
338 || (bfd_write ((PTR) &swapped_hdr, 1, EXEC_BYTES_SIZE, abfd)
342 /* Now write out the section information. Text first, data next, rest
345 for (sect = abfd->sections; sect; sect = sect->next)
346 if (sect->flags & SEC_CODE)
347 aout_adobe_write_section (abfd, sect);
349 for (sect = abfd->sections; sect; sect = sect->next)
350 if (sect->flags & SEC_DATA)
351 aout_adobe_write_section (abfd, sect);
353 for (sect = abfd->sections; sect; sect = sect->next)
354 if (!(sect->flags & (SEC_CODE | SEC_DATA)))
355 aout_adobe_write_section (abfd, sect);
357 /* Write final `sentinel` section header (with type of 0). */
358 if (bfd_write ((PTR) sentinel, 1, sizeof (*sentinel), abfd)
359 != sizeof (*sentinel))
362 /* Now write out reloc info, followed by syms and strings. */
363 if (bfd_get_symcount (abfd) != 0)
365 if (bfd_seek (abfd, (file_ptr) (N_SYMOFF (*exec_hdr (abfd))), SEEK_SET)
369 if (! aout_32_write_syms (abfd))
372 if (bfd_seek (abfd, (file_ptr) (N_TRELOFF (*exec_hdr (abfd))), SEEK_SET)
376 for (sect = abfd->sections; sect; sect = sect->next)
377 if (sect->flags & SEC_CODE)
378 if (!aout_32_squirt_out_relocs (abfd, sect))
381 if (bfd_seek (abfd, (file_ptr) (N_DRELOFF (*exec_hdr (abfd))), SEEK_SET)
385 for (sect = abfd->sections; sect; sect = sect->next)
386 if (sect->flags & SEC_DATA)
387 if (!aout_32_squirt_out_relocs (abfd, sect))
395 aout_adobe_write_section (abfd, sect)
396 bfd *abfd ATTRIBUTE_UNUSED;
397 sec_ptr sect ATTRIBUTE_UNUSED;
403 aout_adobe_set_section_contents (abfd, section, location, offset, count)
410 file_ptr section_start;
413 /* Set by bfd.c handler. */
414 if (abfd->output_has_begun == false)
416 /* Assign file offsets to sections. Text sections are first, and
417 are contiguous. Then data sections. Everything else at the end. */
418 section_start = N_TXTOFF (ignore<-->me);
420 for (sect = abfd->sections; sect; sect = sect->next)
422 if (sect->flags & SEC_CODE)
424 sect->filepos = section_start;
425 /* FIXME: Round to alignment. */
426 section_start += sect->_raw_size;
430 for (sect = abfd->sections; sect; sect = sect->next)
432 if (sect->flags & SEC_DATA)
434 sect->filepos = section_start;
435 /* FIXME: Round to alignment. */
436 section_start += sect->_raw_size;
440 for (sect = abfd->sections; sect; sect = sect->next)
442 if (sect->flags & SEC_HAS_CONTENTS &&
443 !(sect->flags & (SEC_CODE | SEC_DATA)))
445 sect->filepos = section_start;
446 /* FIXME: Round to alignment. */
447 section_start += sect->_raw_size;
452 /* Regardless, once we know what we're doing, we might as well get
454 if (bfd_seek (abfd, section->filepos + offset, SEEK_SET) != 0)
458 return (bfd_write ((PTR) location, 1, count, abfd) == count) ? true : false;
464 aout_adobe_set_arch_mach (abfd, arch, machine)
466 enum bfd_architecture arch;
467 unsigned long machine;
469 if (! bfd_default_set_arch_mach (abfd, arch, machine))
472 if (arch == bfd_arch_unknown
473 || arch == bfd_arch_m68k)
480 aout_adobe_sizeof_headers (ignore_abfd, ignore)
481 bfd *ignore_abfd ATTRIBUTE_UNUSED;
482 boolean ignore ATTRIBUTE_UNUSED;
484 return sizeof (struct internal_exec);
487 /* Build the transfer vector for Adobe A.Out files. */
489 #define aout_32_close_and_cleanup aout_32_bfd_free_cached_info
491 #define aout_32_bfd_make_debug_symbol \
492 ((asymbol *(*) PARAMS ((bfd *, void *, unsigned long))) bfd_nullvoidptr)
494 #define aout_32_bfd_reloc_type_lookup \
495 ((reloc_howto_type *(*) \
496 PARAMS ((bfd *, bfd_reloc_code_real_type))) bfd_nullvoidptr)
498 #define aout_32_set_arch_mach aout_adobe_set_arch_mach
499 #define aout_32_set_section_contents aout_adobe_set_section_contents
501 #define aout_32_sizeof_headers aout_adobe_sizeof_headers
502 #define aout_32_bfd_get_relocated_section_contents \
503 bfd_generic_get_relocated_section_contents
504 #define aout_32_get_section_contents_in_window _bfd_generic_get_section_contents_in_window
505 #define aout_32_bfd_relax_section bfd_generic_relax_section
506 #define aout_32_bfd_gc_sections bfd_generic_gc_sections
507 #define aout_32_bfd_merge_sections bfd_generic_merge_sections
508 #define aout_32_bfd_link_hash_table_create \
509 _bfd_generic_link_hash_table_create
510 #define aout_32_bfd_link_add_symbols _bfd_generic_link_add_symbols
511 #define aout_32_bfd_final_link _bfd_generic_final_link
512 #define aout_32_bfd_link_split_section _bfd_generic_link_split_section
514 const bfd_target a_out_adobe_vec =
516 "a.out.adobe", /* name */
517 bfd_target_aout_flavour,
518 BFD_ENDIAN_BIG, /* data byte order is unknown (big assumed) */
519 BFD_ENDIAN_BIG, /* hdr byte order is big */
520 (HAS_RELOC | EXEC_P | /* object flags */
521 HAS_LINENO | HAS_DEBUG |
522 HAS_SYMS | HAS_LOCALS | WP_TEXT ),
524 (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_CODE | SEC_DATA | SEC_RELOC),
525 '_', /* symbol leading char */
526 ' ', /* ar_pad_char */
527 16, /* ar_max_namelen */
529 bfd_getb64, bfd_getb_signed_64, bfd_putb64,
530 bfd_getb32, bfd_getb_signed_32, bfd_putb32,
531 bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* data */
532 bfd_getb64, bfd_getb_signed_64, bfd_putb64,
533 bfd_getb32, bfd_getb_signed_32, bfd_putb32,
534 bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* hdrs */
535 {_bfd_dummy_target, aout_adobe_object_p, /* bfd_check_format */
536 bfd_generic_archive_p, _bfd_dummy_target},
537 {bfd_false, aout_adobe_mkobject, /* bfd_set_format */
538 _bfd_generic_mkarchive, bfd_false},
539 {bfd_false, aout_adobe_write_object_contents,/* bfd_write_contents */
540 _bfd_write_archive_contents, bfd_false},
542 BFD_JUMP_TABLE_GENERIC (aout_32),
543 BFD_JUMP_TABLE_COPY (_bfd_generic),
544 BFD_JUMP_TABLE_CORE (_bfd_nocore),
545 BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_bsd),
546 BFD_JUMP_TABLE_SYMBOLS (aout_32),
547 BFD_JUMP_TABLE_RELOCS (aout_32),
548 BFD_JUMP_TABLE_WRITE (aout_32),
549 BFD_JUMP_TABLE_LINK (aout_32),
550 BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),