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
43 PARAMS ((bfd
*, asection
*, PTR
, file_ptr
, bfd_size_type
));
44 static boolean aout_adobe_set_arch_mach
45 PARAMS ((bfd
*, enum bfd_architecture
, unsigned long));
46 static int aout_adobe_sizeof_headers
PARAMS ((bfd
*, boolean
));
48 /* Swaps the information in an executable header taken from a raw byte
49 stream memory image, into the internal exec_header structure. */
51 void aout_adobe_swap_exec_header_in
52 PARAMS ((bfd
*, struct external_exec
*, struct internal_exec
*));
55 aout_adobe_swap_exec_header_in (abfd
, raw_bytes
, execp
)
57 struct external_exec
*raw_bytes
;
58 struct internal_exec
*execp
;
60 struct external_exec
*bytes
= (struct external_exec
*) raw_bytes
;
62 /* Now fill in fields in the execp, from the bytes in the raw data. */
63 execp
->a_info
= H_GET_32 (abfd
, bytes
->e_info
);
64 execp
->a_text
= GET_WORD (abfd
, bytes
->e_text
);
65 execp
->a_data
= GET_WORD (abfd
, bytes
->e_data
);
66 execp
->a_bss
= GET_WORD (abfd
, bytes
->e_bss
);
67 execp
->a_syms
= GET_WORD (abfd
, bytes
->e_syms
);
68 execp
->a_entry
= GET_WORD (abfd
, bytes
->e_entry
);
69 execp
->a_trsize
= GET_WORD (abfd
, bytes
->e_trsize
);
70 execp
->a_drsize
= GET_WORD (abfd
, bytes
->e_drsize
);
73 /* Swaps the information in an internal exec header structure into the
74 supplied buffer ready for writing to disk. */
76 void aout_adobe_swap_exec_header_out
77 PARAMS ((bfd
*, struct internal_exec
*, struct external_exec
*));
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 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
;
106 bfd_size_type amt
= EXEC_BYTES_SIZE
;
108 if (bfd_bread ((PTR
) &exec_bytes
, amt
, abfd
) != amt
)
110 if (bfd_get_error () != bfd_error_system_call
)
111 bfd_set_error (bfd_error_wrong_format
);
115 anexec
.a_info
= 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
, 0L);
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 bfd_size_type amt
= sizeof (*ext
);
167 if (bfd_bread ((PTR
) ext
, amt
, abfd
) != amt
)
169 if (bfd_get_error () != bfd_error_system_call
)
170 bfd_set_error (bfd_error_wrong_format
);
174 switch (ext
->e_type
[0])
177 section_name
= ".text";
178 flags
= SEC_CODE
| SEC_LOAD
| SEC_ALLOC
| SEC_HAS_CONTENTS
;
182 section_name
= ".data";
183 flags
= SEC_DATA
| SEC_LOAD
| SEC_ALLOC
| SEC_HAS_CONTENTS
;
187 section_name
= ".bss";
188 flags
= SEC_DATA
| SEC_HAS_CONTENTS
;
192 goto no_more_sections
;
195 (*_bfd_error_handler
)
196 (_("%s: Unknown section type in a.out.adobe file: %x\n"),
197 bfd_archive_filename (abfd
), ext
->e_type
[0]);
198 goto no_more_sections
;
201 /* First one is called ".text" or whatever; subsequent ones are
202 ".text1", ".text2", ... */
203 bfd_set_error (bfd_error_no_error
);
204 sect
= bfd_make_section (abfd
, section_name
);
209 if (bfd_get_error () != bfd_error_no_error
)
210 /* Some other error -- slide into the sunset. */
212 sprintf (try_again
, "%s%d", section_name
, ++trynum
);
213 sect
= bfd_make_section (abfd
, try_again
);
216 /* Fix the name, if it is a sprintf'd name. */
217 if (sect
->name
== try_again
)
219 amt
= strlen (sect
->name
);
220 newname
= (char *) bfd_zalloc (abfd
, amt
);
223 strcpy (newname
, sect
->name
);
224 sect
->name
= newname
;
227 /* Now set the section's attributes. */
228 bfd_set_section_flags (abfd
, sect
, flags
);
229 /* Assumed big-endian. */
230 sect
->_raw_size
= ((ext
->e_size
[0] << 8)
231 | ext
->e_size
[1] << 8
233 sect
->_cooked_size
= sect
->_raw_size
;
234 sect
->vma
= H_GET_32 (abfd
, ext
->e_virtbase
);
235 sect
->filepos
= H_GET_32 (abfd
, ext
->e_filebase
);
236 /* FIXME XXX alignment? */
238 /* Set relocation information for first section of each type. */
240 switch (ext
->e_type
[0])
243 sect
->rel_filepos
= N_TRELOFF (*execp
);
244 sect
->reloc_count
= execp
->a_trsize
;
248 sect
->rel_filepos
= N_DRELOFF (*execp
);
249 sect
->reloc_count
= execp
->a_drsize
;
258 adata (abfd
).reloc_entry_size
= sizeof (struct reloc_std_external
);
259 adata (abfd
).symbol_entry_size
= sizeof (struct external_nlist
);
260 adata (abfd
).page_size
= 1; /* Not applicable. */
261 adata (abfd
).segment_size
= 1; /* Not applicable. */
262 adata (abfd
).exec_bytes_size
= EXEC_BYTES_SIZE
;
267 struct bout_data_struct
270 struct internal_exec e
;
274 aout_adobe_mkobject (abfd
)
277 struct bout_data_struct
*rawptr
;
278 bfd_size_type amt
= sizeof (struct bout_data_struct
);
280 rawptr
= (struct bout_data_struct
*) bfd_zalloc (abfd
, amt
);
284 abfd
->tdata
.bout_data
= rawptr
;
285 exec_hdr (abfd
) = &rawptr
->e
;
287 adata (abfd
).reloc_entry_size
= sizeof (struct reloc_std_external
);
288 adata (abfd
).symbol_entry_size
= sizeof (struct external_nlist
);
289 adata (abfd
).page_size
= 1; /* Not applicable. */
290 adata (abfd
).segment_size
= 1; /* Not applicable. */
291 adata (abfd
).exec_bytes_size
= EXEC_BYTES_SIZE
;
297 aout_adobe_write_object_contents (abfd
)
300 struct external_exec swapped_hdr
;
301 static struct external_segdesc sentinel
[1]; /* Initialized to zero. */
305 exec_hdr (abfd
)->a_info
= ZMAGIC
;
307 /* Calculate text size as total of text sections, etc. */
309 exec_hdr (abfd
)->a_text
= 0;
310 exec_hdr (abfd
)->a_data
= 0;
311 exec_hdr (abfd
)->a_bss
= 0;
312 exec_hdr (abfd
)->a_trsize
= 0;
313 exec_hdr (abfd
)->a_drsize
= 0;
315 for (sect
= abfd
->sections
; sect
; sect
= sect
->next
)
317 if (sect
->flags
& SEC_CODE
)
319 exec_hdr (abfd
)->a_text
+= sect
->_raw_size
;
320 exec_hdr (abfd
)->a_trsize
+= sect
->reloc_count
*
321 sizeof (struct reloc_std_external
);
323 else if (sect
->flags
& SEC_DATA
)
325 exec_hdr (abfd
)->a_data
+= sect
->_raw_size
;
326 exec_hdr (abfd
)->a_drsize
+= sect
->reloc_count
*
327 sizeof (struct reloc_std_external
);
329 else if (sect
->flags
& SEC_ALLOC
&& !(sect
->flags
& SEC_LOAD
))
331 exec_hdr (abfd
)->a_bss
+= sect
->_raw_size
;
335 exec_hdr (abfd
)->a_syms
= bfd_get_symcount (abfd
)
336 * sizeof (struct external_nlist
);
337 exec_hdr (abfd
)->a_entry
= bfd_get_start_address (abfd
);
339 aout_adobe_swap_exec_header_out (abfd
, exec_hdr (abfd
), &swapped_hdr
);
341 amt
= EXEC_BYTES_SIZE
;
342 if (bfd_seek (abfd
, (file_ptr
) 0, SEEK_SET
) != 0
343 || bfd_bwrite ((PTR
) &swapped_hdr
, amt
, abfd
) != amt
)
346 /* Now write out the section information. Text first, data next, rest
349 for (sect
= abfd
->sections
; sect
; sect
= sect
->next
)
350 if (sect
->flags
& SEC_CODE
)
351 aout_adobe_write_section (abfd
, sect
);
353 for (sect
= abfd
->sections
; sect
; sect
= sect
->next
)
354 if (sect
->flags
& SEC_DATA
)
355 aout_adobe_write_section (abfd
, sect
);
357 for (sect
= abfd
->sections
; sect
; sect
= sect
->next
)
358 if (!(sect
->flags
& (SEC_CODE
| SEC_DATA
)))
359 aout_adobe_write_section (abfd
, sect
);
361 /* Write final `sentinel` section header (with type of 0). */
362 amt
= sizeof (*sentinel
);
363 if (bfd_bwrite ((PTR
) sentinel
, amt
, abfd
) != amt
)
366 /* Now write out reloc info, followed by syms and strings. */
367 if (bfd_get_symcount (abfd
) != 0)
369 if (bfd_seek (abfd
, (file_ptr
) (N_SYMOFF (*exec_hdr (abfd
))), SEEK_SET
)
373 if (! aout_32_write_syms (abfd
))
376 if (bfd_seek (abfd
, (file_ptr
) (N_TRELOFF (*exec_hdr (abfd
))), SEEK_SET
)
380 for (sect
= abfd
->sections
; sect
; sect
= sect
->next
)
381 if (sect
->flags
& SEC_CODE
)
382 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
)
390 if (sect
->flags
& SEC_DATA
)
391 if (!aout_32_squirt_out_relocs (abfd
, sect
))
399 aout_adobe_write_section (abfd
, sect
)
400 bfd
*abfd ATTRIBUTE_UNUSED
;
401 sec_ptr sect ATTRIBUTE_UNUSED
;
407 aout_adobe_set_section_contents (abfd
, section
, location
, offset
, count
)
414 file_ptr section_start
;
417 /* Set by bfd.c handler. */
418 if (abfd
->output_has_begun
== false)
420 /* Assign file offsets to sections. Text sections are first, and
421 are contiguous. Then data sections. Everything else at the end. */
422 section_start
= N_TXTOFF (ignore
<-->me
);
424 for (sect
= abfd
->sections
; sect
; sect
= sect
->next
)
426 if (sect
->flags
& SEC_CODE
)
428 sect
->filepos
= section_start
;
429 /* FIXME: Round to alignment. */
430 section_start
+= sect
->_raw_size
;
434 for (sect
= abfd
->sections
; sect
; sect
= sect
->next
)
436 if (sect
->flags
& SEC_DATA
)
438 sect
->filepos
= section_start
;
439 /* FIXME: Round to alignment. */
440 section_start
+= sect
->_raw_size
;
444 for (sect
= abfd
->sections
; sect
; sect
= sect
->next
)
446 if (sect
->flags
& SEC_HAS_CONTENTS
&&
447 !(sect
->flags
& (SEC_CODE
| SEC_DATA
)))
449 sect
->filepos
= section_start
;
450 /* FIXME: Round to alignment. */
451 section_start
+= sect
->_raw_size
;
456 /* Regardless, once we know what we're doing, we might as well get
458 if (bfd_seek (abfd
, section
->filepos
+ offset
, SEEK_SET
) != 0)
464 return bfd_bwrite ((PTR
) location
, count
, abfd
) == count
;
468 aout_adobe_set_arch_mach (abfd
, arch
, machine
)
470 enum bfd_architecture arch
;
471 unsigned long machine
;
473 if (! bfd_default_set_arch_mach (abfd
, arch
, machine
))
476 if (arch
== bfd_arch_unknown
477 || arch
== bfd_arch_m68k
)
484 aout_adobe_sizeof_headers (ignore_abfd
, ignore
)
485 bfd
*ignore_abfd ATTRIBUTE_UNUSED
;
486 boolean ignore ATTRIBUTE_UNUSED
;
488 return sizeof (struct internal_exec
);
491 /* Build the transfer vector for Adobe A.Out files. */
493 #define aout_32_close_and_cleanup aout_32_bfd_free_cached_info
495 #define aout_32_bfd_make_debug_symbol \
496 ((asymbol *(*) PARAMS ((bfd *, void *, unsigned long))) bfd_nullvoidptr)
498 #define aout_32_bfd_reloc_type_lookup \
499 ((reloc_howto_type *(*) \
500 PARAMS ((bfd *, bfd_reloc_code_real_type))) bfd_nullvoidptr)
502 #define aout_32_set_arch_mach aout_adobe_set_arch_mach
503 #define aout_32_set_section_contents aout_adobe_set_section_contents
505 #define aout_32_sizeof_headers aout_adobe_sizeof_headers
506 #define aout_32_bfd_get_relocated_section_contents \
507 bfd_generic_get_relocated_section_contents
508 #define aout_32_get_section_contents_in_window _bfd_generic_get_section_contents_in_window
509 #define aout_32_bfd_relax_section bfd_generic_relax_section
510 #define aout_32_bfd_gc_sections bfd_generic_gc_sections
511 #define aout_32_bfd_merge_sections bfd_generic_merge_sections
512 #define aout_32_bfd_link_hash_table_create \
513 _bfd_generic_link_hash_table_create
514 #define aout_32_bfd_link_add_symbols _bfd_generic_link_add_symbols
515 #define aout_32_bfd_final_link _bfd_generic_final_link
516 #define aout_32_bfd_link_split_section _bfd_generic_link_split_section
518 const bfd_target a_out_adobe_vec
=
520 "a.out.adobe", /* name */
521 bfd_target_aout_flavour
,
522 BFD_ENDIAN_BIG
, /* data byte order is unknown (big assumed) */
523 BFD_ENDIAN_BIG
, /* hdr byte order is big */
524 (HAS_RELOC
| EXEC_P
| /* object flags */
525 HAS_LINENO
| HAS_DEBUG
|
526 HAS_SYMS
| HAS_LOCALS
| WP_TEXT
),
528 (SEC_HAS_CONTENTS
| SEC_ALLOC
| SEC_LOAD
| SEC_CODE
| SEC_DATA
| SEC_RELOC
),
529 '_', /* symbol leading char */
530 ' ', /* ar_pad_char */
531 16, /* ar_max_namelen */
533 bfd_getb64
, bfd_getb_signed_64
, bfd_putb64
,
534 bfd_getb32
, bfd_getb_signed_32
, bfd_putb32
,
535 bfd_getb16
, bfd_getb_signed_16
, bfd_putb16
, /* data */
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
, /* hdrs */
539 {_bfd_dummy_target
, aout_adobe_object_p
, /* bfd_check_format */
540 bfd_generic_archive_p
, _bfd_dummy_target
},
541 {bfd_false
, aout_adobe_mkobject
, /* bfd_set_format */
542 _bfd_generic_mkarchive
, bfd_false
},
543 {bfd_false
, aout_adobe_write_object_contents
,/* bfd_write_contents */
544 _bfd_write_archive_contents
, bfd_false
},
546 BFD_JUMP_TABLE_GENERIC (aout_32
),
547 BFD_JUMP_TABLE_COPY (_bfd_generic
),
548 BFD_JUMP_TABLE_CORE (_bfd_nocore
),
549 BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_bsd
),
550 BFD_JUMP_TABLE_SYMBOLS (aout_32
),
551 BFD_JUMP_TABLE_RELOCS (aout_32
),
552 BFD_JUMP_TABLE_WRITE (aout_32
),
553 BFD_JUMP_TABLE_LINK (aout_32
),
554 BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic
),