Touches most files in bfd/, so likely will be blamed for everything..
[deliverable/binutils-gdb.git] / bfd / aout-adobe.c
CommitLineData
252b5132 1/* BFD back-end for a.out.adobe binaries.
1725a96e 2 Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001
5f771d47 3 Free Software Foundation, Inc.
252b5132
RH
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"
1725a96e 29#include "libaout.h" /* BFD a.out internal data structures. */
252b5132 30
336eced2
KH
31/* Forward decl. */
32extern const bfd_target a_out_adobe_vec;
252b5132
RH
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 *));
1725a96e
NC
38static void aout_adobe_write_section PARAMS ((bfd *abfd, sec_ptr sect));
39static const bfd_target * aout_adobe_object_p PARAMS ((bfd *));
40static boolean aout_adobe_mkobject PARAMS ((bfd *));
41static boolean aout_adobe_write_object_contents PARAMS ((bfd *));
dc810e39
AM
42static boolean aout_adobe_set_section_contents
43 PARAMS ((bfd *, asection *, PTR, file_ptr, bfd_size_type));
44static boolean aout_adobe_set_arch_mach
45 PARAMS ((bfd *, enum bfd_architecture, unsigned long));
1725a96e 46static int aout_adobe_sizeof_headers PARAMS ((bfd *, boolean));
252b5132
RH
47
48/* Swaps the information in an executable header taken from a raw byte
49 stream memory image, into the internal exec_header structure. */
50
51void aout_adobe_swap_exec_header_in
dc810e39 52 PARAMS ((bfd *, struct external_exec *, struct internal_exec *));
c4dfa77f 53
252b5132
RH
54void
55aout_adobe_swap_exec_header_in (abfd, raw_bytes, execp)
56 bfd *abfd;
57 struct external_exec *raw_bytes;
58 struct internal_exec *execp;
59{
336eced2 60 struct external_exec *bytes = (struct external_exec *) raw_bytes;
252b5132
RH
61
62 /* Now fill in fields in the execp, from the bytes in the raw data. */
dc810e39 63 execp->a_info = H_GET_32 (abfd, bytes->e_info);
252b5132
RH
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);
71}
72
73/* Swaps the information in an internal exec header structure into the
74 supplied buffer ready for writing to disk. */
75
dc810e39
AM
76void aout_adobe_swap_exec_header_out
77 PARAMS ((bfd *, struct internal_exec *, struct external_exec *));
78
252b5132
RH
79void
80aout_adobe_swap_exec_header_out (abfd, execp, raw_bytes)
81 bfd *abfd;
82 struct internal_exec *execp;
83 struct external_exec *raw_bytes;
84{
336eced2 85 struct external_exec *bytes = (struct external_exec *) raw_bytes;
252b5132 86
336eced2
KH
87 /* Now fill in fields in the raw data, from the fields in the exec
88 struct. */
dc810e39 89 H_PUT_32 (abfd, execp->a_info , bytes->e_info);
252b5132
RH
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);
97}
98
252b5132
RH
99static const bfd_target *
100aout_adobe_object_p (abfd)
101 bfd *abfd;
102{
103 struct internal_exec anexec;
104 struct external_exec exec_bytes;
105 char *targ;
dc810e39 106 bfd_size_type amt = EXEC_BYTES_SIZE;
252b5132 107
dc810e39 108 if (bfd_bread ((PTR) &exec_bytes, amt, abfd) != amt)
336eced2
KH
109 {
110 if (bfd_get_error () != bfd_error_system_call)
111 bfd_set_error (bfd_error_wrong_format);
112 return 0;
113 }
252b5132 114
dc810e39 115 anexec.a_info = H_GET_32 (abfd, exec_bytes.e_info);
252b5132
RH
116
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! */
122
336eced2
KH
123 if (N_BADMAG (anexec))
124 {
125 targ = getenv ("GNUTARGET");
126 if (targ && !strcmp (targ, a_out_adobe_vec.name))
127 /* Just continue anyway, if specifically set to this format. */
128 ;
129 else
130 {
131 bfd_set_error (bfd_error_wrong_format);
132 return 0;
133 }
134 }
252b5132
RH
135
136 aout_adobe_swap_exec_header_in (abfd, &exec_bytes, &anexec);
137 return aout_32_some_aout_object_p (abfd, &anexec, aout_adobe_callback);
138}
139
252b5132
RH
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. */
142
143static const bfd_target *
144aout_adobe_callback (abfd)
145 bfd *abfd;
146{
147 struct internal_exec *execp = exec_hdr (abfd);
148 asection *sect;
149 struct external_segdesc ext[1];
150 char *section_name;
1725a96e 151 char try_again[30]; /* Name and number. */
252b5132
RH
152 char *newname;
153 int trynum;
154 flagword flags;
155
156 /* Architecture and machine type -- unknown in this format. */
dc810e39 157 bfd_set_arch_mach (abfd, bfd_arch_unknown, 0L);
252b5132
RH
158
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);
162
163 /* Suck up the section information from the file, one section at a time. */
336eced2
KH
164 for (;;)
165 {
dc810e39
AM
166 bfd_size_type amt = sizeof (*ext);
167 if (bfd_bread ((PTR) ext, amt, abfd) != amt)
336eced2
KH
168 {
169 if (bfd_get_error () != bfd_error_system_call)
170 bfd_set_error (bfd_error_wrong_format);
1725a96e 171
336eced2
KH
172 return 0;
173 }
174 switch (ext->e_type[0])
175 {
176 case N_TEXT:
177 section_name = ".text";
178 flags = SEC_CODE | SEC_LOAD | SEC_ALLOC | SEC_HAS_CONTENTS;
179 break;
180
181 case N_DATA:
182 section_name = ".data";
183 flags = SEC_DATA | SEC_LOAD | SEC_ALLOC | SEC_HAS_CONTENTS;
184 break;
185
186 case N_BSS:
187 section_name = ".bss";
188 flags = SEC_DATA | SEC_HAS_CONTENTS;
189 break;
190
191 case 0:
192 goto no_more_sections;
193
194 default:
195 (*_bfd_error_handler)
196 (_("%s: Unknown section type in a.out.adobe file: %x\n"),
197 bfd_get_filename (abfd), ext->e_type[0]);
198 goto no_more_sections;
199 }
200
201 /* First one is called ".text" or whatever; subsequent ones are
202 ".text1", ".text2", ... */
336eced2
KH
203 bfd_set_error (bfd_error_no_error);
204 sect = bfd_make_section (abfd, section_name);
205 trynum = 0;
1725a96e 206
336eced2
KH
207 while (!sect)
208 {
209 if (bfd_get_error () != bfd_error_no_error)
210 /* Some other error -- slide into the sunset. */
211 return 0;
212 sprintf (try_again, "%s%d", section_name, ++trynum);
213 sect = bfd_make_section (abfd, try_again);
214 }
215
216 /* Fix the name, if it is a sprintf'd name. */
217 if (sect->name == try_again)
218 {
dc810e39
AM
219 amt = strlen (sect->name);
220 newname = (char *) bfd_zalloc (abfd, amt);
336eced2
KH
221 if (newname == NULL)
222 return 0;
223 strcpy (newname, sect->name);
224 sect->name = newname;
225 }
226
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)
dc810e39
AM
231 | ext->e_size[1] << 8
232 | ext->e_size[2]);
336eced2 233 sect->_cooked_size = sect->_raw_size;
dc810e39
AM
234 sect->vma = H_GET_32 (abfd, ext->e_virtbase);
235 sect->filepos = H_GET_32 (abfd, ext->e_filebase);
336eced2
KH
236 /* FIXME XXX alignment? */
237
238 /* Set relocation information for first section of each type. */
239 if (trynum == 0)
240 switch (ext->e_type[0])
241 {
242 case N_TEXT:
243 sect->rel_filepos = N_TRELOFF (*execp);
244 sect->reloc_count = execp->a_trsize;
245 break;
246
247 case N_DATA:
248 sect->rel_filepos = N_DRELOFF (*execp);
249 sect->reloc_count = execp->a_drsize;
250 break;
1725a96e
NC
251
252 default:
253 break;
336eced2 254 }
252b5132 255 }
336eced2 256 no_more_sections:
252b5132 257
336eced2
KH
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;
252b5132
RH
263
264 return abfd->xvec;
265}
266
1725a96e
NC
267struct bout_data_struct
268 {
269 struct aoutdata a;
270 struct internal_exec e;
271 };
252b5132
RH
272
273static boolean
274aout_adobe_mkobject (abfd)
275 bfd *abfd;
276{
277 struct bout_data_struct *rawptr;
dc810e39 278 bfd_size_type amt = sizeof (struct bout_data_struct);
252b5132 279
dc810e39 280 rawptr = (struct bout_data_struct *) bfd_zalloc (abfd, amt);
252b5132 281 if (rawptr == NULL)
336eced2 282 return false;
252b5132
RH
283
284 abfd->tdata.bout_data = rawptr;
285 exec_hdr (abfd) = &rawptr->e;
286
336eced2
KH
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;
252b5132
RH
292
293 return true;
294}
295
252b5132
RH
296static boolean
297aout_adobe_write_object_contents (abfd)
298 bfd *abfd;
299{
300 struct external_exec swapped_hdr;
336eced2 301 static struct external_segdesc sentinel[1]; /* Initialized to zero. */
252b5132 302 asection *sect;
dc810e39 303 bfd_size_type amt;
252b5132
RH
304
305 exec_hdr (abfd)->a_info = ZMAGIC;
306
c4dfa77f 307 /* Calculate text size as total of text sections, etc. */
252b5132
RH
308
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;
314
336eced2
KH
315 for (sect = abfd->sections; sect; sect = sect->next)
316 {
317 if (sect->flags & SEC_CODE)
318 {
319 exec_hdr (abfd)->a_text += sect->_raw_size;
320 exec_hdr (abfd)->a_trsize += sect->reloc_count *
321 sizeof (struct reloc_std_external);
322 }
323 else if (sect->flags & SEC_DATA)
324 {
325 exec_hdr (abfd)->a_data += sect->_raw_size;
326 exec_hdr (abfd)->a_drsize += sect->reloc_count *
327 sizeof (struct reloc_std_external);
328 }
329 else if (sect->flags & SEC_ALLOC && !(sect->flags & SEC_LOAD))
330 {
331 exec_hdr (abfd)->a_bss += sect->_raw_size;
332 }
252b5132 333 }
252b5132
RH
334
335 exec_hdr (abfd)->a_syms = bfd_get_symcount (abfd)
336eced2 336 * sizeof (struct external_nlist);
252b5132
RH
337 exec_hdr (abfd)->a_entry = bfd_get_start_address (abfd);
338
339 aout_adobe_swap_exec_header_out (abfd, exec_hdr (abfd), &swapped_hdr);
340
dc810e39 341 amt = EXEC_BYTES_SIZE;
252b5132 342 if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0
dc810e39 343 || bfd_bwrite ((PTR) &swapped_hdr, amt, abfd) != amt)
252b5132
RH
344 return false;
345
346 /* Now write out the section information. Text first, data next, rest
347 afterward. */
348
336eced2 349 for (sect = abfd->sections; sect; sect = sect->next)
1725a96e
NC
350 if (sect->flags & SEC_CODE)
351 aout_adobe_write_section (abfd, sect);
352
336eced2 353 for (sect = abfd->sections; sect; sect = sect->next)
1725a96e
NC
354 if (sect->flags & SEC_DATA)
355 aout_adobe_write_section (abfd, sect);
356
336eced2 357 for (sect = abfd->sections; sect; sect = sect->next)
1725a96e
NC
358 if (!(sect->flags & (SEC_CODE | SEC_DATA)))
359 aout_adobe_write_section (abfd, sect);
252b5132
RH
360
361 /* Write final `sentinel` section header (with type of 0). */
dc810e39
AM
362 amt = sizeof (*sentinel);
363 if (bfd_bwrite ((PTR) sentinel, amt, abfd) != amt)
252b5132
RH
364 return false;
365
336eced2 366 /* Now write out reloc info, followed by syms and strings. */
c4dfa77f 367 if (bfd_get_symcount (abfd) != 0)
252b5132 368 {
336eced2 369 if (bfd_seek (abfd, (file_ptr) (N_SYMOFF (*exec_hdr (abfd))), SEEK_SET)
252b5132
RH
370 != 0)
371 return false;
372
373 if (! aout_32_write_syms (abfd))
374 return false;
375
336eced2 376 if (bfd_seek (abfd, (file_ptr) (N_TRELOFF (*exec_hdr (abfd))), SEEK_SET)
252b5132
RH
377 != 0)
378 return false;
379
336eced2 380 for (sect = abfd->sections; sect; sect = sect->next)
1725a96e
NC
381 if (sect->flags & SEC_CODE)
382 if (!aout_32_squirt_out_relocs (abfd, sect))
383 return false;
252b5132 384
336eced2 385 if (bfd_seek (abfd, (file_ptr) (N_DRELOFF (*exec_hdr (abfd))), SEEK_SET)
252b5132
RH
386 != 0)
387 return false;
388
336eced2 389 for (sect = abfd->sections; sect; sect = sect->next)
1725a96e
NC
390 if (sect->flags & SEC_DATA)
391 if (!aout_32_squirt_out_relocs (abfd, sect))
392 return false;
252b5132 393 }
1725a96e 394
252b5132
RH
395 return true;
396}
397
398static void
399aout_adobe_write_section (abfd, sect)
5f771d47
ILT
400 bfd *abfd ATTRIBUTE_UNUSED;
401 sec_ptr sect ATTRIBUTE_UNUSED;
252b5132
RH
402{
403 /* FIXME XXX */
404}
405\f
406static boolean
407aout_adobe_set_section_contents (abfd, section, location, offset, count)
408 bfd *abfd;
409 asection *section;
410 PTR location;
411 file_ptr offset;
412 bfd_size_type count;
413{
414 file_ptr section_start;
415 sec_ptr sect;
416
336eced2
KH
417 /* Set by bfd.c handler. */
418 if (abfd->output_has_begun == false)
419 {
420 /* Assign file offsets to sections. Text sections are first, and
421 are contiguous. Then data sections. Everything else at the end. */
336eced2
KH
422 section_start = N_TXTOFF (ignore<-->me);
423
424 for (sect = abfd->sections; sect; sect = sect->next)
425 {
426 if (sect->flags & SEC_CODE)
427 {
428 sect->filepos = section_start;
429 /* FIXME: Round to alignment. */
430 section_start += sect->_raw_size;
431 }
432 }
433
434 for (sect = abfd->sections; sect; sect = sect->next)
435 {
436 if (sect->flags & SEC_DATA)
437 {
438 sect->filepos = section_start;
439 /* FIXME: Round to alignment. */
440 section_start += sect->_raw_size;
441 }
442 }
443
444 for (sect = abfd->sections; sect; sect = sect->next)
445 {
446 if (sect->flags & SEC_HAS_CONTENTS &&
447 !(sect->flags & (SEC_CODE | SEC_DATA)))
448 {
449 sect->filepos = section_start;
450 /* FIXME: Round to alignment. */
451 section_start += sect->_raw_size;
452 }
453 }
252b5132 454 }
252b5132 455
336eced2
KH
456 /* Regardless, once we know what we're doing, we might as well get
457 going. */
252b5132
RH
458 if (bfd_seek (abfd, section->filepos + offset, SEEK_SET) != 0)
459 return false;
460
dc810e39
AM
461 if (count == 0)
462 return true;
1725a96e 463
dc810e39 464 return bfd_bwrite ((PTR) location, count, abfd) == count;
252b5132
RH
465}
466
467static boolean
468aout_adobe_set_arch_mach (abfd, arch, machine)
469 bfd *abfd;
470 enum bfd_architecture arch;
471 unsigned long machine;
472{
473 if (! bfd_default_set_arch_mach (abfd, arch, machine))
474 return false;
475
476 if (arch == bfd_arch_unknown
477 || arch == bfd_arch_m68k)
478 return true;
479
480 return false;
481}
482
c4dfa77f 483static int
252b5132 484aout_adobe_sizeof_headers (ignore_abfd, ignore)
5f771d47
ILT
485 bfd *ignore_abfd ATTRIBUTE_UNUSED;
486 boolean ignore ATTRIBUTE_UNUSED;
252b5132 487{
beb0d161 488 return sizeof (struct internal_exec);
252b5132
RH
489}
490
252b5132
RH
491/* Build the transfer vector for Adobe A.Out files. */
492
493#define aout_32_close_and_cleanup aout_32_bfd_free_cached_info
494
495#define aout_32_bfd_make_debug_symbol \
496 ((asymbol *(*) PARAMS ((bfd *, void *, unsigned long))) bfd_nullvoidptr)
497
498#define aout_32_bfd_reloc_type_lookup \
499 ((reloc_howto_type *(*) \
500 PARAMS ((bfd *, bfd_reloc_code_real_type))) bfd_nullvoidptr)
501
502#define aout_32_set_arch_mach aout_adobe_set_arch_mach
503#define aout_32_set_section_contents aout_adobe_set_section_contents
504
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
8550eb6e 511#define aout_32_bfd_merge_sections bfd_generic_merge_sections
252b5132
RH
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
517
1725a96e
NC
518const bfd_target a_out_adobe_vec =
519 {
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 ),
527 /* section flags */
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 */
532
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},
545
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),
555
556 NULL,
557
558 (PTR) 0
559 };
This page took 0.152454 seconds and 4 git commands to generate.