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.
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
));
40 /* Swaps the information in an executable header taken from a raw byte
41 stream memory image, into the internal exec_header structure. */
43 void aout_adobe_swap_exec_header_in
44 PARAMS ((bfd
*abfd
, struct external_exec
*raw_bytes
,
45 struct internal_exec
*execp
));
48 aout_adobe_swap_exec_header_in (abfd
, raw_bytes
, execp
)
50 struct external_exec
*raw_bytes
;
51 struct internal_exec
*execp
;
53 struct external_exec
*bytes
= (struct external_exec
*) raw_bytes
;
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
);
66 /* Swaps the information in an internal exec header structure into the
67 supplied buffer ready for writing to disk. */
69 PROTO(void, aout_adobe_swap_exec_header_out
,
71 struct internal_exec
*execp
,
72 struct external_exec
*raw_bytes
));
74 aout_adobe_swap_exec_header_out (abfd
, execp
, raw_bytes
)
76 struct internal_exec
*execp
;
77 struct external_exec
*raw_bytes
;
79 struct external_exec
*bytes
= (struct external_exec
*) raw_bytes
;
81 /* Now fill in fields in the raw data, from the fields in the exec
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
);
93 static const bfd_target
*
94 aout_adobe_object_p (abfd
)
97 struct internal_exec anexec
;
98 struct external_exec exec_bytes
;
101 if (bfd_read ((PTR
) &exec_bytes
, 1, EXEC_BYTES_SIZE
, abfd
)
104 if (bfd_get_error () != bfd_error_system_call
)
105 bfd_set_error (bfd_error_wrong_format
);
109 anexec
.a_info
= bfd_h_get_32 (abfd
, exec_bytes
.e_info
);
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! */
117 if (N_BADMAG (anexec
))
119 targ
= getenv ("GNUTARGET");
120 if (targ
&& !strcmp (targ
, a_out_adobe_vec
.name
))
121 /* Just continue anyway, if specifically set to this format. */
125 bfd_set_error (bfd_error_wrong_format
);
130 aout_adobe_swap_exec_header_in (abfd
, &exec_bytes
, &anexec
);
131 return aout_32_some_aout_object_p (abfd
, &anexec
, aout_adobe_callback
);
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. */
137 static const bfd_target
*
138 aout_adobe_callback (abfd
)
141 struct internal_exec
*execp
= exec_hdr (abfd
);
143 struct external_segdesc ext
[1];
145 char try_again
[30]; /* name and number */
150 /* Architecture and machine type -- unknown in this format. */
151 bfd_set_arch_mach (abfd
, bfd_arch_unknown
, 0);
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
);
157 /* Suck up the section information from the file, one section at a time. */
161 if (bfd_read ((PTR
) ext
, 1, sizeof (*ext
), abfd
) != sizeof (*ext
))
163 if (bfd_get_error () != bfd_error_system_call
)
164 bfd_set_error (bfd_error_wrong_format
);
167 switch (ext
->e_type
[0])
170 section_name
= ".text";
171 flags
= SEC_CODE
| SEC_LOAD
| SEC_ALLOC
| SEC_HAS_CONTENTS
;
175 section_name
= ".data";
176 flags
= SEC_DATA
| SEC_LOAD
| SEC_ALLOC
| SEC_HAS_CONTENTS
;
180 section_name
= ".bss";
181 flags
= SEC_DATA
| SEC_HAS_CONTENTS
;
185 goto no_more_sections
;
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
;
194 /* First one is called ".text" or whatever; subsequent ones are
195 ".text1", ".text2", ... */
197 bfd_set_error (bfd_error_no_error
);
198 sect
= bfd_make_section (abfd
, section_name
);
202 if (bfd_get_error () != bfd_error_no_error
)
203 /* Some other error -- slide into the sunset. */
205 sprintf (try_again
, "%s%d", section_name
, ++trynum
);
206 sect
= bfd_make_section (abfd
, try_again
);
209 /* Fix the name, if it is a sprintf'd name. */
210 if (sect
->name
== try_again
)
212 newname
= (char *) bfd_zalloc (abfd
, strlen (sect
->name
));
215 strcpy (newname
, sect
->name
);
216 sect
->name
= newname
;
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)
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? */
230 /* Set relocation information for first section of each type. */
232 switch (ext
->e_type
[0])
235 sect
->rel_filepos
= N_TRELOFF (*execp
);
236 sect
->reloc_count
= execp
->a_trsize
;
240 sect
->rel_filepos
= N_DRELOFF (*execp
);
241 sect
->reloc_count
= execp
->a_drsize
;
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
;
256 struct bout_data_struct
{
258 struct internal_exec e
;
262 aout_adobe_mkobject (abfd
)
265 struct bout_data_struct
*rawptr
;
267 rawptr
= (struct bout_data_struct
*) bfd_zalloc (abfd
, sizeof (struct bout_data_struct
));
271 abfd
->tdata
.bout_data
= rawptr
;
272 exec_hdr (abfd
) = &rawptr
->e
;
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
;
284 aout_adobe_write_object_contents (abfd
)
287 struct external_exec swapped_hdr
;
288 static struct external_segdesc sentinel
[1]; /* Initialized to zero. */
291 exec_hdr (abfd
)->a_info
= ZMAGIC
;
293 /* Calculate text size as total of text sections, etc. */
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;
301 for (sect
= abfd
->sections
; sect
; sect
= sect
->next
)
303 if (sect
->flags
& SEC_CODE
)
305 exec_hdr (abfd
)->a_text
+= sect
->_raw_size
;
306 exec_hdr (abfd
)->a_trsize
+= sect
->reloc_count
*
307 sizeof (struct reloc_std_external
);
309 else if (sect
->flags
& SEC_DATA
)
311 exec_hdr (abfd
)->a_data
+= sect
->_raw_size
;
312 exec_hdr (abfd
)->a_drsize
+= sect
->reloc_count
*
313 sizeof (struct reloc_std_external
);
315 else if (sect
->flags
& SEC_ALLOC
&& !(sect
->flags
& SEC_LOAD
))
317 exec_hdr (abfd
)->a_bss
+= sect
->_raw_size
;
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
);
325 aout_adobe_swap_exec_header_out (abfd
, exec_hdr (abfd
), &swapped_hdr
);
327 if (bfd_seek (abfd
, (file_ptr
) 0, SEEK_SET
) != 0
328 || (bfd_write ((PTR
) &swapped_hdr
, 1, EXEC_BYTES_SIZE
, abfd
)
332 /* Now write out the section information. Text first, data next, rest
335 for (sect
= abfd
->sections
; sect
; sect
= sect
->next
)
337 if (sect
->flags
& SEC_CODE
)
339 aout_adobe_write_section (abfd
, sect
);
342 for (sect
= abfd
->sections
; sect
; sect
= sect
->next
)
344 if (sect
->flags
& SEC_DATA
)
346 aout_adobe_write_section (abfd
, sect
);
349 for (sect
= abfd
->sections
; sect
; sect
= sect
->next
)
351 if (!(sect
->flags
& (SEC_CODE
| SEC_DATA
)))
353 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
)
378 if (sect
->flags
& SEC_CODE
)
380 if (!aout_32_squirt_out_relocs (abfd
, sect
))
385 if (bfd_seek (abfd
, (file_ptr
) (N_DRELOFF (*exec_hdr (abfd
))), SEEK_SET
)
389 for (sect
= abfd
->sections
; sect
; sect
= sect
->next
)
391 if (sect
->flags
& SEC_DATA
)
393 if (!aout_32_squirt_out_relocs (abfd
, sect
))
402 aout_adobe_write_section (abfd
, sect
)
403 bfd
*abfd ATTRIBUTE_UNUSED
;
404 sec_ptr sect ATTRIBUTE_UNUSED
;
410 aout_adobe_set_section_contents (abfd
, section
, location
, offset
, count
)
417 file_ptr section_start
;
420 /* Set by bfd.c handler. */
421 if (abfd
->output_has_begun
== false)
423 /* Assign file offsets to sections. Text sections are first, and
424 are contiguous. Then data sections. Everything else at the end. */
426 section_start
= N_TXTOFF (ignore
<-->me
);
428 for (sect
= abfd
->sections
; sect
; sect
= sect
->next
)
430 if (sect
->flags
& SEC_CODE
)
432 sect
->filepos
= section_start
;
433 /* FIXME: Round to alignment. */
434 section_start
+= sect
->_raw_size
;
438 for (sect
= abfd
->sections
; sect
; sect
= sect
->next
)
440 if (sect
->flags
& SEC_DATA
)
442 sect
->filepos
= section_start
;
443 /* FIXME: Round to alignment. */
444 section_start
+= sect
->_raw_size
;
448 for (sect
= abfd
->sections
; sect
; sect
= sect
->next
)
450 if (sect
->flags
& SEC_HAS_CONTENTS
&&
451 !(sect
->flags
& (SEC_CODE
| SEC_DATA
)))
453 sect
->filepos
= section_start
;
454 /* FIXME: Round to alignment. */
455 section_start
+= sect
->_raw_size
;
460 /* Regardless, once we know what we're doing, we might as well get
462 if (bfd_seek (abfd
, section
->filepos
+ offset
, SEEK_SET
) != 0)
467 return (bfd_write ((PTR
) location
, 1, count
, abfd
) == count
) ? true : false;
473 aout_adobe_set_arch_mach (abfd
, arch
, machine
)
475 enum bfd_architecture arch
;
476 unsigned long machine
;
478 if (! bfd_default_set_arch_mach (abfd
, arch
, machine
))
481 if (arch
== bfd_arch_unknown
482 || arch
== bfd_arch_m68k
)
489 aout_adobe_sizeof_headers (ignore_abfd
, ignore
)
490 bfd
*ignore_abfd ATTRIBUTE_UNUSED
;
491 boolean ignore ATTRIBUTE_UNUSED
;
493 return sizeof (struct internal_exec
);
496 /* Build the transfer vector for Adobe A.Out files. */
498 #define aout_32_close_and_cleanup aout_32_bfd_free_cached_info
500 #define aout_32_bfd_make_debug_symbol \
501 ((asymbol *(*) PARAMS ((bfd *, void *, unsigned long))) bfd_nullvoidptr)
503 #define aout_32_bfd_reloc_type_lookup \
504 ((reloc_howto_type *(*) \
505 PARAMS ((bfd *, bfd_reloc_code_real_type))) bfd_nullvoidptr)
507 #define aout_32_set_arch_mach aout_adobe_set_arch_mach
508 #define aout_32_set_section_contents aout_adobe_set_section_contents
510 #define aout_32_sizeof_headers aout_adobe_sizeof_headers
511 #define aout_32_bfd_get_relocated_section_contents \
512 bfd_generic_get_relocated_section_contents
513 #define aout_32_get_section_contents_in_window _bfd_generic_get_section_contents_in_window
514 #define aout_32_bfd_relax_section bfd_generic_relax_section
515 #define aout_32_bfd_gc_sections bfd_generic_gc_sections
516 #define aout_32_bfd_link_hash_table_create \
517 _bfd_generic_link_hash_table_create
518 #define aout_32_bfd_link_add_symbols _bfd_generic_link_add_symbols
519 #define aout_32_bfd_final_link _bfd_generic_final_link
520 #define aout_32_bfd_link_split_section _bfd_generic_link_split_section
522 const bfd_target a_out_adobe_vec
= {
523 "a.out.adobe", /* name */
524 bfd_target_aout_flavour
,
525 BFD_ENDIAN_BIG
, /* data byte order is unknown (big assumed) */
526 BFD_ENDIAN_BIG
, /* hdr byte order is big */
527 (HAS_RELOC
| EXEC_P
| /* object flags */
528 HAS_LINENO
| HAS_DEBUG
|
529 HAS_SYMS
| HAS_LOCALS
| WP_TEXT
),
531 (SEC_HAS_CONTENTS
| SEC_ALLOC
| SEC_LOAD
| SEC_CODE
| SEC_DATA
| SEC_RELOC
),
532 '_', /* symbol leading char */
533 ' ', /* ar_pad_char */
534 16, /* ar_max_namelen */
536 bfd_getb64
, bfd_getb_signed_64
, bfd_putb64
,
537 bfd_getb32
, bfd_getb_signed_32
, bfd_putb32
,
538 bfd_getb16
, bfd_getb_signed_16
, bfd_putb16
, /* data */
539 bfd_getb64
, bfd_getb_signed_64
, bfd_putb64
,
540 bfd_getb32
, bfd_getb_signed_32
, bfd_putb32
,
541 bfd_getb16
, bfd_getb_signed_16
, bfd_putb16
, /* hdrs */
542 {_bfd_dummy_target
, aout_adobe_object_p
, /* bfd_check_format */
543 bfd_generic_archive_p
, _bfd_dummy_target
},
544 {bfd_false
, aout_adobe_mkobject
, /* bfd_set_format */
545 _bfd_generic_mkarchive
, bfd_false
},
546 {bfd_false
, aout_adobe_write_object_contents
, /* bfd_write_contents */
547 _bfd_write_archive_contents
, bfd_false
},
549 BFD_JUMP_TABLE_GENERIC (aout_32
),
550 BFD_JUMP_TABLE_COPY (_bfd_generic
),
551 BFD_JUMP_TABLE_CORE (_bfd_nocore
),
552 BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_bsd
),
553 BFD_JUMP_TABLE_SYMBOLS (aout_32
),
554 BFD_JUMP_TABLE_RELOCS (aout_32
),
555 BFD_JUMP_TABLE_WRITE (aout_32
),
556 BFD_JUMP_TABLE_LINK (aout_32
),
557 BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic
),