Add missing protypes
[platform/upstream/binutils.git] / bfd / aout-adobe.c
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.
5
6 This file is part of BFD, the Binary File Descriptor library.
7
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.
12
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.
17
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.  */
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.  */
32 extern const bfd_target a_out_adobe_vec;
33
34 static const bfd_target *aout_adobe_callback PARAMS ((bfd *));
35
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));
45
46 /* Swaps the information in an executable header taken from a raw byte
47    stream memory image, into the internal exec_header structure.  */
48
49 void aout_adobe_swap_exec_header_in
50   PARAMS ((bfd *abfd, struct external_exec *raw_bytes,
51            struct internal_exec *execp));
52
53 void
54 aout_adobe_swap_exec_header_in (abfd, raw_bytes, execp)
55      bfd *abfd;
56      struct external_exec *raw_bytes;
57      struct internal_exec *execp;
58 {
59   struct external_exec *bytes = (struct external_exec *) raw_bytes;
60
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);
70 }
71
72 /* Swaps the information in an internal exec header structure into the
73    supplied buffer ready for writing to disk.  */
74
75 PROTO(void, aout_adobe_swap_exec_header_out,
76           (bfd *abfd,
77            struct internal_exec *execp,
78            struct external_exec *raw_bytes));
79 void
80 aout_adobe_swap_exec_header_out (abfd, execp, raw_bytes)
81      bfd *abfd;
82      struct internal_exec *execp;
83      struct external_exec *raw_bytes;
84 {
85   struct external_exec *bytes = (struct external_exec *) raw_bytes;
86
87   /* Now fill in fields in the raw data, from the fields in the exec
88      struct.  */
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);
97 }
98
99 static const bfd_target *
100 aout_adobe_object_p (abfd)
101      bfd *abfd;
102 {
103   struct internal_exec anexec;
104   struct external_exec exec_bytes;
105   char *targ;
106
107   if (bfd_read ((PTR) &exec_bytes, 1, EXEC_BYTES_SIZE, abfd)
108       != EXEC_BYTES_SIZE)
109     {
110       if (bfd_get_error () != bfd_error_system_call)
111         bfd_set_error (bfd_error_wrong_format);
112       return 0;
113     }
114
115   anexec.a_info = bfd_h_get_32 (abfd, exec_bytes.e_info);
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
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     }
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
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
143 static const bfd_target *
144 aout_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;
151   char try_again[30];   /* Name and number.  */
152   char *newname;
153   int trynum;
154   flagword flags;
155
156   /* Architecture and machine type -- unknown in this format.  */
157   bfd_set_arch_mach (abfd, bfd_arch_unknown, 0);
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.  */
164   for (;;)
165     {
166       if (bfd_read ((PTR) ext, 1, sizeof (*ext), abfd) != sizeof (*ext))
167         {
168           if (bfd_get_error () != bfd_error_system_call)
169             bfd_set_error (bfd_error_wrong_format);
170
171           return 0;
172         }
173       switch (ext->e_type[0])
174         {
175         case N_TEXT:
176           section_name = ".text";
177           flags = SEC_CODE | SEC_LOAD | SEC_ALLOC | SEC_HAS_CONTENTS;
178           break;
179
180         case N_DATA:
181           section_name = ".data";
182           flags = SEC_DATA | SEC_LOAD | SEC_ALLOC | SEC_HAS_CONTENTS;
183           break;
184
185         case N_BSS:
186           section_name = ".bss";
187           flags = SEC_DATA | SEC_HAS_CONTENTS;
188           break;
189
190         case 0:
191           goto no_more_sections;
192
193         default:
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;
198         }
199
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);
204       trynum = 0;
205
206       while (!sect)
207         {
208           if (bfd_get_error () != bfd_error_no_error)
209             /* Some other error -- slide into the sunset.  */
210             return 0;
211           sprintf (try_again, "%s%d", section_name, ++trynum);
212           sect = bfd_make_section (abfd, try_again);
213         }
214
215       /* Fix the name, if it is a sprintf'd name.  */
216       if (sect->name == try_again)
217         {
218           newname = (char *) bfd_zalloc (abfd, strlen (sect->name));
219           if (newname == NULL)
220             return 0;
221           strcpy (newname, sect->name);
222           sect->name = newname;
223         }
224
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)
230         | ext->e_size[2];
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?  */
235
236       /* Set relocation information for first section of each type.  */
237       if (trynum == 0)
238         switch (ext->e_type[0])
239           {
240           case N_TEXT:
241             sect->rel_filepos = N_TRELOFF (*execp);
242             sect->reloc_count = execp->a_trsize;
243             break;
244
245           case N_DATA:
246             sect->rel_filepos = N_DRELOFF (*execp);
247             sect->reloc_count = execp->a_drsize;
248             break;
249
250           default:
251             break;
252           }
253     }
254  no_more_sections:
255
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;
261
262   return abfd->xvec;
263 }
264
265 struct bout_data_struct
266   {
267     struct aoutdata a;
268     struct internal_exec e;
269   };
270
271 static boolean
272 aout_adobe_mkobject (abfd)
273      bfd *abfd;
274 {
275   struct bout_data_struct *rawptr;
276
277   rawptr = (struct bout_data_struct *) bfd_zalloc (abfd, sizeof (struct bout_data_struct));
278   if (rawptr == NULL)
279     return false;
280
281   abfd->tdata.bout_data = rawptr;
282   exec_hdr (abfd) = &rawptr->e;
283
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;
289
290   return true;
291 }
292
293 static boolean
294 aout_adobe_write_object_contents (abfd)
295      bfd *abfd;
296 {
297   struct external_exec swapped_hdr;
298   static struct external_segdesc sentinel[1];   /* Initialized to zero.  */
299   asection *sect;
300
301   exec_hdr (abfd)->a_info = ZMAGIC;
302
303   /* Calculate text size as total of text sections, etc.  */
304
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;
310
311   for (sect = abfd->sections; sect; sect = sect->next)
312     {
313       if (sect->flags & SEC_CODE)
314         {
315           exec_hdr (abfd)->a_text += sect->_raw_size;
316           exec_hdr (abfd)->a_trsize += sect->reloc_count *
317             sizeof (struct reloc_std_external);
318         }
319       else if (sect->flags & SEC_DATA)
320         {
321           exec_hdr (abfd)->a_data += sect->_raw_size;
322           exec_hdr (abfd)->a_drsize += sect->reloc_count *
323             sizeof (struct reloc_std_external);
324         }
325       else if (sect->flags & SEC_ALLOC && !(sect->flags & SEC_LOAD))
326         {
327           exec_hdr (abfd)->a_bss += sect->_raw_size;
328         }
329     }
330
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);
334
335   aout_adobe_swap_exec_header_out (abfd, exec_hdr (abfd), &swapped_hdr);
336
337   if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0
338       || (bfd_write ((PTR) &swapped_hdr, 1, EXEC_BYTES_SIZE, abfd)
339           != EXEC_BYTES_SIZE))
340     return false;
341
342   /* Now write out the section information.  Text first, data next, rest
343      afterward.  */
344
345   for (sect = abfd->sections; sect; sect = sect->next)
346     if (sect->flags & SEC_CODE)
347       aout_adobe_write_section (abfd, sect);
348
349   for (sect = abfd->sections; sect; sect = sect->next)
350     if (sect->flags & SEC_DATA)
351       aout_adobe_write_section (abfd, sect);
352
353   for (sect = abfd->sections; sect; sect = sect->next)
354     if (!(sect->flags & (SEC_CODE | SEC_DATA)))
355       aout_adobe_write_section (abfd, sect);
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         if (sect->flags & SEC_CODE)
378           if (!aout_32_squirt_out_relocs (abfd, sect))
379             return false;
380
381       if (bfd_seek (abfd, (file_ptr) (N_DRELOFF (*exec_hdr (abfd))), SEEK_SET)
382           != 0)
383         return false;
384
385       for (sect = abfd->sections; sect; sect = sect->next)
386         if (sect->flags & SEC_DATA)
387           if (!aout_32_squirt_out_relocs (abfd, sect))
388             return false;
389     }
390
391   return true;
392 }
393
394 static void
395 aout_adobe_write_section (abfd, sect)
396      bfd *abfd ATTRIBUTE_UNUSED;
397      sec_ptr sect ATTRIBUTE_UNUSED;
398 {
399   /* FIXME XXX */
400 }
401 \f
402 static boolean
403 aout_adobe_set_section_contents (abfd, section, location, offset, count)
404      bfd *abfd;
405      asection *section;
406      PTR location;
407      file_ptr offset;
408      bfd_size_type count;
409 {
410   file_ptr section_start;
411   sec_ptr sect;
412
413   /* Set by bfd.c handler.  */
414   if (abfd->output_has_begun == false)
415     {
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);
419
420       for (sect = abfd->sections; sect; sect = sect->next)
421         {
422           if (sect->flags & SEC_CODE)
423             {
424               sect->filepos = section_start;
425               /* FIXME:  Round to alignment.  */
426               section_start += sect->_raw_size;
427             }
428         }
429
430       for (sect = abfd->sections; sect; sect = sect->next)
431         {
432           if (sect->flags & SEC_DATA)
433             {
434               sect->filepos = section_start;
435               /* FIXME:  Round to alignment.  */
436               section_start += sect->_raw_size;
437             }
438         }
439
440       for (sect = abfd->sections; sect; sect = sect->next)
441         {
442           if (sect->flags & SEC_HAS_CONTENTS &&
443               !(sect->flags & (SEC_CODE | SEC_DATA)))
444             {
445               sect->filepos = section_start;
446               /* FIXME:  Round to alignment.  */
447               section_start += sect->_raw_size;
448             }
449         }
450     }
451
452   /* Regardless, once we know what we're doing, we might as well get
453      going.  */
454   if (bfd_seek (abfd, section->filepos + offset, SEEK_SET) != 0)
455     return false;
456
457   if (count != 0)
458     return (bfd_write ((PTR) location, 1, count, abfd) == count) ? true : false;
459
460   return true;
461 }
462
463 static boolean
464 aout_adobe_set_arch_mach (abfd, arch, machine)
465      bfd *abfd;
466      enum bfd_architecture arch;
467      unsigned long machine;
468 {
469   if (! bfd_default_set_arch_mach (abfd, arch, machine))
470     return false;
471
472   if (arch == bfd_arch_unknown
473       || arch == bfd_arch_m68k)
474     return true;
475
476   return false;
477 }
478
479 static int
480 aout_adobe_sizeof_headers (ignore_abfd, ignore)
481      bfd *ignore_abfd ATTRIBUTE_UNUSED;
482      boolean ignore ATTRIBUTE_UNUSED;
483 {
484   return sizeof (struct internal_exec);
485 }
486
487 /* Build the transfer vector for Adobe A.Out files.  */
488
489 #define aout_32_close_and_cleanup aout_32_bfd_free_cached_info
490
491 #define aout_32_bfd_make_debug_symbol \
492   ((asymbol *(*) PARAMS ((bfd *, void *, unsigned long))) bfd_nullvoidptr)
493
494 #define aout_32_bfd_reloc_type_lookup \
495   ((reloc_howto_type *(*) \
496     PARAMS ((bfd *, bfd_reloc_code_real_type))) bfd_nullvoidptr)
497
498 #define aout_32_set_arch_mach           aout_adobe_set_arch_mach
499 #define aout_32_set_section_contents    aout_adobe_set_section_contents
500
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
513
514 const bfd_target a_out_adobe_vec =
515   {
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 ),
523     /* section flags */
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 */
528
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},
541
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),
551
552     NULL,
553
554     (PTR) 0
555   };