s/boolean/bfd_boolean/ s/true/TRUE/ s/false/FALSE/. Simplify
[external/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    2002
4    Free Software Foundation, Inc.
5    Written by Cygnus Support.  Based on bout.c.
6
7 This file is part of BFD, the Binary File Descriptor library.
8
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
13
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
22
23 #include "bfd.h"
24 #include "sysdep.h"
25 #include "libbfd.h"
26
27 #include "aout/adobe.h"
28
29 #include "aout/stab_gnu.h"
30 #include "libaout.h"            /* BFD a.out internal data structures.  */
31
32 /* Forward decl.  */
33 extern const bfd_target a_out_adobe_vec;
34
35 static const bfd_target *aout_adobe_callback
36   PARAMS ((bfd *));
37 extern bfd_boolean aout_32_slurp_symbol_table
38   PARAMS ((bfd *abfd));
39 extern bfd_boolean aout_32_write_syms
40   PARAMS ((bfd *));
41 static void aout_adobe_write_section
42   PARAMS ((bfd *abfd, sec_ptr sect));
43 static const bfd_target * aout_adobe_object_p
44   PARAMS ((bfd *));
45 static bfd_boolean aout_adobe_mkobject
46   PARAMS ((bfd *));
47 static bfd_boolean aout_adobe_write_object_contents
48   PARAMS ((bfd *));
49 static bfd_boolean aout_adobe_set_section_contents
50   PARAMS ((bfd *, asection *, PTR, file_ptr, bfd_size_type));
51 static bfd_boolean aout_adobe_set_arch_mach
52   PARAMS ((bfd *, enum bfd_architecture, unsigned long));
53 static int     aout_adobe_sizeof_headers
54   PARAMS ((bfd *, bfd_boolean));
55
56 /* Swaps the information in an executable header taken from a raw byte
57    stream memory image, into the internal exec_header structure.  */
58
59 void aout_adobe_swap_exec_header_in
60   PARAMS ((bfd *, struct external_exec *, struct internal_exec *));
61
62 void
63 aout_adobe_swap_exec_header_in (abfd, raw_bytes, execp)
64      bfd *abfd;
65      struct external_exec *raw_bytes;
66      struct internal_exec *execp;
67 {
68   struct external_exec *bytes = (struct external_exec *) raw_bytes;
69
70   /* Now fill in fields in the execp, from the bytes in the raw data.  */
71   execp->a_info   = H_GET_32 (abfd, bytes->e_info);
72   execp->a_text   = GET_WORD (abfd, bytes->e_text);
73   execp->a_data   = GET_WORD (abfd, bytes->e_data);
74   execp->a_bss    = GET_WORD (abfd, bytes->e_bss);
75   execp->a_syms   = GET_WORD (abfd, bytes->e_syms);
76   execp->a_entry  = GET_WORD (abfd, bytes->e_entry);
77   execp->a_trsize = GET_WORD (abfd, bytes->e_trsize);
78   execp->a_drsize = GET_WORD (abfd, bytes->e_drsize);
79 }
80
81 /* Swaps the information in an internal exec header structure into the
82    supplied buffer ready for writing to disk.  */
83
84 void aout_adobe_swap_exec_header_out
85   PARAMS ((bfd *, struct internal_exec *, struct external_exec *));
86
87 void
88 aout_adobe_swap_exec_header_out (abfd, execp, raw_bytes)
89      bfd *abfd;
90      struct internal_exec *execp;
91      struct external_exec *raw_bytes;
92 {
93   struct external_exec *bytes = (struct external_exec *) raw_bytes;
94
95   /* Now fill in fields in the raw data, from the fields in the exec
96      struct.  */
97   H_PUT_32 (abfd, execp->a_info  , bytes->e_info);
98   PUT_WORD (abfd, execp->a_text  , bytes->e_text);
99   PUT_WORD (abfd, execp->a_data  , bytes->e_data);
100   PUT_WORD (abfd, execp->a_bss   , bytes->e_bss);
101   PUT_WORD (abfd, execp->a_syms  , bytes->e_syms);
102   PUT_WORD (abfd, execp->a_entry , bytes->e_entry);
103   PUT_WORD (abfd, execp->a_trsize, bytes->e_trsize);
104   PUT_WORD (abfd, execp->a_drsize, bytes->e_drsize);
105 }
106
107 static const bfd_target *
108 aout_adobe_object_p (abfd)
109      bfd *abfd;
110 {
111   struct internal_exec anexec;
112   struct external_exec exec_bytes;
113   char *targ;
114   bfd_size_type amt = EXEC_BYTES_SIZE;
115
116   if (bfd_bread ((PTR) &exec_bytes, amt, abfd) != amt)
117     {
118       if (bfd_get_error () != bfd_error_system_call)
119         bfd_set_error (bfd_error_wrong_format);
120       return 0;
121     }
122
123   anexec.a_info = H_GET_32 (abfd, exec_bytes.e_info);
124
125   /* Normally we just compare for the magic number.
126      However, a bunch of Adobe tools aren't fixed up yet; they generate
127      files using ZMAGIC(!).
128      If the environment variable GNUTARGET is set to "a.out.adobe", we will
129      take just about any a.out file as an Adobe a.out file.  FIXME!  */
130
131   if (N_BADMAG (anexec))
132     {
133       targ = getenv ("GNUTARGET");
134       if (targ && !strcmp (targ, a_out_adobe_vec.name))
135         /* Just continue anyway, if specifically set to this format.  */
136         ;
137       else
138         {
139           bfd_set_error (bfd_error_wrong_format);
140           return 0;
141         }
142     }
143
144   aout_adobe_swap_exec_header_in (abfd, &exec_bytes, &anexec);
145   return aout_32_some_aout_object_p (abfd, &anexec, aout_adobe_callback);
146 }
147
148 /* Finish up the opening of a b.out file for reading.  Fill in all the
149    fields that are not handled by common code.  */
150
151 static const bfd_target *
152 aout_adobe_callback (abfd)
153      bfd *abfd;
154 {
155   struct internal_exec *execp = exec_hdr (abfd);
156   asection *sect;
157   struct external_segdesc ext[1];
158   char *section_name;
159   char try_again[30];   /* Name and number.  */
160   char *newname;
161   int trynum;
162   flagword flags;
163
164   /* Architecture and machine type -- unknown in this format.  */
165   bfd_set_arch_mach (abfd, bfd_arch_unknown, 0L);
166
167   /* The positions of the string table and symbol table.  */
168   obj_str_filepos (abfd) = N_STROFF (*execp);
169   obj_sym_filepos (abfd) = N_SYMOFF (*execp);
170
171   /* Suck up the section information from the file, one section at a time.  */
172   for (;;)
173     {
174       bfd_size_type amt = sizeof (*ext);
175       if (bfd_bread ((PTR) ext, amt, abfd) != amt)
176         {
177           if (bfd_get_error () != bfd_error_system_call)
178             bfd_set_error (bfd_error_wrong_format);
179
180           return 0;
181         }
182       switch (ext->e_type[0])
183         {
184         case N_TEXT:
185           section_name = ".text";
186           flags = SEC_CODE | SEC_LOAD | SEC_ALLOC | SEC_HAS_CONTENTS;
187           break;
188
189         case N_DATA:
190           section_name = ".data";
191           flags = SEC_DATA | SEC_LOAD | SEC_ALLOC | SEC_HAS_CONTENTS;
192           break;
193
194         case N_BSS:
195           section_name = ".bss";
196           flags = SEC_DATA | SEC_HAS_CONTENTS;
197           break;
198
199         case 0:
200           goto no_more_sections;
201
202         default:
203           (*_bfd_error_handler)
204             (_("%s: Unknown section type in a.out.adobe file: %x\n"),
205              bfd_archive_filename (abfd), ext->e_type[0]);
206           goto no_more_sections;
207         }
208
209       /* First one is called ".text" or whatever; subsequent ones are
210          ".text1", ".text2", ...  */
211       bfd_set_error (bfd_error_no_error);
212       sect = bfd_make_section (abfd, section_name);
213       trynum = 0;
214
215       while (!sect)
216         {
217           if (bfd_get_error () != bfd_error_no_error)
218             /* Some other error -- slide into the sunset.  */
219             return 0;
220           sprintf (try_again, "%s%d", section_name, ++trynum);
221           sect = bfd_make_section (abfd, try_again);
222         }
223
224       /* Fix the name, if it is a sprintf'd name.  */
225       if (sect->name == try_again)
226         {
227           amt = strlen (sect->name);
228           newname = (char *) bfd_zalloc (abfd, amt);
229           if (newname == NULL)
230             return 0;
231           strcpy (newname, sect->name);
232           sect->name = newname;
233         }
234
235       /* Now set the section's attributes.  */
236       bfd_set_section_flags (abfd, sect, flags);
237       /* Assumed big-endian.  */
238       sect->_raw_size = ((ext->e_size[0] << 8)
239                          | ext->e_size[1] << 8
240                          | ext->e_size[2]);
241       sect->_cooked_size = sect->_raw_size;
242       sect->vma = H_GET_32 (abfd, ext->e_virtbase);
243       sect->filepos = H_GET_32 (abfd, ext->e_filebase);
244       /* FIXME XXX alignment?  */
245
246       /* Set relocation information for first section of each type.  */
247       if (trynum == 0)
248         switch (ext->e_type[0])
249           {
250           case N_TEXT:
251             sect->rel_filepos = N_TRELOFF (*execp);
252             sect->reloc_count = execp->a_trsize;
253             break;
254
255           case N_DATA:
256             sect->rel_filepos = N_DRELOFF (*execp);
257             sect->reloc_count = execp->a_drsize;
258             break;
259
260           default:
261             break;
262           }
263     }
264  no_more_sections:
265
266   adata (abfd).reloc_entry_size = sizeof (struct reloc_std_external);
267   adata (abfd).symbol_entry_size = sizeof (struct external_nlist);
268   adata (abfd).page_size = 1; /* Not applicable.  */
269   adata (abfd).segment_size = 1; /* Not applicable.  */
270   adata (abfd).exec_bytes_size = EXEC_BYTES_SIZE;
271
272   return abfd->xvec;
273 }
274
275 struct bout_data_struct
276   {
277     struct aoutdata a;
278     struct internal_exec e;
279   };
280
281 static bfd_boolean
282 aout_adobe_mkobject (abfd)
283      bfd *abfd;
284 {
285   struct bout_data_struct *rawptr;
286   bfd_size_type amt = sizeof (struct bout_data_struct);
287
288   rawptr = (struct bout_data_struct *) bfd_zalloc (abfd, amt);
289   if (rawptr == NULL)
290     return FALSE;
291
292   abfd->tdata.bout_data = rawptr;
293   exec_hdr (abfd) = &rawptr->e;
294
295   adata (abfd).reloc_entry_size = sizeof (struct reloc_std_external);
296   adata (abfd).symbol_entry_size = sizeof (struct external_nlist);
297   adata (abfd).page_size = 1; /* Not applicable.  */
298   adata (abfd).segment_size = 1; /* Not applicable.  */
299   adata (abfd).exec_bytes_size = EXEC_BYTES_SIZE;
300
301   return TRUE;
302 }
303
304 static bfd_boolean
305 aout_adobe_write_object_contents (abfd)
306      bfd *abfd;
307 {
308   struct external_exec swapped_hdr;
309   static struct external_segdesc sentinel[1];   /* Initialized to zero.  */
310   asection *sect;
311   bfd_size_type amt;
312
313   exec_hdr (abfd)->a_info = ZMAGIC;
314
315   /* Calculate text size as total of text sections, etc.  */
316
317   exec_hdr (abfd)->a_text = 0;
318   exec_hdr (abfd)->a_data = 0;
319   exec_hdr (abfd)->a_bss  = 0;
320   exec_hdr (abfd)->a_trsize = 0;
321   exec_hdr (abfd)->a_drsize = 0;
322
323   for (sect = abfd->sections; sect; sect = sect->next)
324     {
325       if (sect->flags & SEC_CODE)
326         {
327           exec_hdr (abfd)->a_text += sect->_raw_size;
328           exec_hdr (abfd)->a_trsize += sect->reloc_count *
329             sizeof (struct reloc_std_external);
330         }
331       else if (sect->flags & SEC_DATA)
332         {
333           exec_hdr (abfd)->a_data += sect->_raw_size;
334           exec_hdr (abfd)->a_drsize += sect->reloc_count *
335             sizeof (struct reloc_std_external);
336         }
337       else if (sect->flags & SEC_ALLOC && !(sect->flags & SEC_LOAD))
338         {
339           exec_hdr (abfd)->a_bss += sect->_raw_size;
340         }
341     }
342
343   exec_hdr (abfd)->a_syms = bfd_get_symcount (abfd)
344     * sizeof (struct external_nlist);
345   exec_hdr (abfd)->a_entry = bfd_get_start_address (abfd);
346
347   aout_adobe_swap_exec_header_out (abfd, exec_hdr (abfd), &swapped_hdr);
348
349   amt = EXEC_BYTES_SIZE;
350   if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0
351       || bfd_bwrite ((PTR) &swapped_hdr, amt, abfd) != amt)
352     return FALSE;
353
354   /* Now write out the section information.  Text first, data next, rest
355      afterward.  */
356
357   for (sect = abfd->sections; sect; sect = sect->next)
358     if (sect->flags & SEC_CODE)
359       aout_adobe_write_section (abfd, sect);
360
361   for (sect = abfd->sections; sect; sect = sect->next)
362     if (sect->flags & SEC_DATA)
363       aout_adobe_write_section (abfd, sect);
364
365   for (sect = abfd->sections; sect; sect = sect->next)
366     if (!(sect->flags & (SEC_CODE | SEC_DATA)))
367       aout_adobe_write_section (abfd, sect);
368
369   /* Write final `sentinel` section header (with type of 0).  */
370   amt = sizeof (*sentinel);
371   if (bfd_bwrite ((PTR) sentinel, amt, abfd) != amt)
372     return FALSE;
373
374   /* Now write out reloc info, followed by syms and strings.  */
375   if (bfd_get_symcount (abfd) != 0)
376     {
377       if (bfd_seek (abfd, (file_ptr) (N_SYMOFF (*exec_hdr (abfd))), SEEK_SET)
378           != 0)
379         return FALSE;
380
381       if (! aout_32_write_syms (abfd))
382         return FALSE;
383
384       if (bfd_seek (abfd, (file_ptr) (N_TRELOFF (*exec_hdr (abfd))), SEEK_SET)
385           != 0)
386         return FALSE;
387
388       for (sect = abfd->sections; sect; sect = sect->next)
389         if (sect->flags & SEC_CODE)
390           if (!aout_32_squirt_out_relocs (abfd, sect))
391             return FALSE;
392
393       if (bfd_seek (abfd, (file_ptr) (N_DRELOFF (*exec_hdr (abfd))), SEEK_SET)
394           != 0)
395         return FALSE;
396
397       for (sect = abfd->sections; sect; sect = sect->next)
398         if (sect->flags & SEC_DATA)
399           if (!aout_32_squirt_out_relocs (abfd, sect))
400             return FALSE;
401     }
402
403   return TRUE;
404 }
405
406 static void
407 aout_adobe_write_section (abfd, sect)
408      bfd *abfd ATTRIBUTE_UNUSED;
409      sec_ptr sect ATTRIBUTE_UNUSED;
410 {
411   /* FIXME XXX */
412 }
413 \f
414 static bfd_boolean
415 aout_adobe_set_section_contents (abfd, section, location, offset, count)
416      bfd *abfd;
417      asection *section;
418      PTR location;
419      file_ptr offset;
420      bfd_size_type count;
421 {
422   file_ptr section_start;
423   sec_ptr sect;
424
425   /* Set by bfd.c handler.  */
426   if (! abfd->output_has_begun)
427     {
428       /* Assign file offsets to sections.  Text sections are first, and
429          are contiguous.  Then data sections.  Everything else at the end.  */
430       section_start = N_TXTOFF (ignore<-->me);
431
432       for (sect = abfd->sections; sect; sect = sect->next)
433         {
434           if (sect->flags & SEC_CODE)
435             {
436               sect->filepos = section_start;
437               /* FIXME:  Round to alignment.  */
438               section_start += sect->_raw_size;
439             }
440         }
441
442       for (sect = abfd->sections; sect; sect = sect->next)
443         {
444           if (sect->flags & SEC_DATA)
445             {
446               sect->filepos = section_start;
447               /* FIXME:  Round to alignment.  */
448               section_start += sect->_raw_size;
449             }
450         }
451
452       for (sect = abfd->sections; sect; sect = sect->next)
453         {
454           if (sect->flags & SEC_HAS_CONTENTS &&
455               !(sect->flags & (SEC_CODE | SEC_DATA)))
456             {
457               sect->filepos = section_start;
458               /* FIXME:  Round to alignment.  */
459               section_start += sect->_raw_size;
460             }
461         }
462     }
463
464   /* Regardless, once we know what we're doing, we might as well get
465      going.  */
466   if (bfd_seek (abfd, section->filepos + offset, SEEK_SET) != 0)
467     return FALSE;
468
469   if (count == 0)
470     return TRUE;
471
472   return bfd_bwrite ((PTR) location, count, abfd) == count;
473 }
474
475 static bfd_boolean
476 aout_adobe_set_arch_mach (abfd, arch, machine)
477      bfd *abfd;
478      enum bfd_architecture arch;
479      unsigned long machine;
480 {
481   if (! bfd_default_set_arch_mach (abfd, arch, machine))
482     return FALSE;
483
484   if (arch == bfd_arch_unknown
485       || arch == bfd_arch_m68k)
486     return TRUE;
487
488   return FALSE;
489 }
490
491 static int
492 aout_adobe_sizeof_headers (ignore_abfd, ignore)
493      bfd *ignore_abfd ATTRIBUTE_UNUSED;
494      bfd_boolean ignore ATTRIBUTE_UNUSED;
495 {
496   return sizeof (struct internal_exec);
497 }
498
499 /* Build the transfer vector for Adobe A.Out files.  */
500
501 #define aout_32_close_and_cleanup aout_32_bfd_free_cached_info
502
503 #define aout_32_bfd_make_debug_symbol \
504   ((asymbol *(*) PARAMS ((bfd *, void *, unsigned long))) bfd_nullvoidptr)
505
506 #define aout_32_bfd_reloc_type_lookup \
507   ((reloc_howto_type *(*) \
508     PARAMS ((bfd *, bfd_reloc_code_real_type))) bfd_nullvoidptr)
509
510 #define aout_32_set_arch_mach           aout_adobe_set_arch_mach
511 #define aout_32_set_section_contents    aout_adobe_set_section_contents
512
513 #define aout_32_sizeof_headers          aout_adobe_sizeof_headers
514 #define aout_32_bfd_get_relocated_section_contents \
515   bfd_generic_get_relocated_section_contents
516 #define aout_32_get_section_contents_in_window _bfd_generic_get_section_contents_in_window
517 #define aout_32_bfd_relax_section       bfd_generic_relax_section
518 #define aout_32_bfd_gc_sections         bfd_generic_gc_sections
519 #define aout_32_bfd_merge_sections      bfd_generic_merge_sections
520 #define aout_32_bfd_discard_group       bfd_generic_discard_group
521 #define aout_32_bfd_link_hash_table_create \
522   _bfd_generic_link_hash_table_create
523 #define aout_32_bfd_link_hash_table_free \
524   _bfd_generic_link_hash_table_free
525 #define aout_32_bfd_link_add_symbols    _bfd_generic_link_add_symbols
526 #define aout_32_bfd_link_just_syms      _bfd_generic_link_just_syms
527 #define aout_32_bfd_final_link          _bfd_generic_final_link
528 #define aout_32_bfd_link_split_section  _bfd_generic_link_split_section
529
530 const bfd_target a_out_adobe_vec =
531   {
532     "a.out.adobe",              /* name */
533     bfd_target_aout_flavour,
534     BFD_ENDIAN_BIG,             /* data byte order is unknown (big assumed) */
535     BFD_ENDIAN_BIG,             /* hdr byte order is big */
536     (HAS_RELOC | EXEC_P |       /* object flags */
537      HAS_LINENO | HAS_DEBUG |
538      HAS_SYMS | HAS_LOCALS | WP_TEXT ),
539     /* section flags */
540     (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_CODE | SEC_DATA | SEC_RELOC),
541     '_',                                /*  symbol leading char */
542     ' ',                                /* ar_pad_char */
543     16,                                 /* ar_max_namelen */
544
545     bfd_getb64, bfd_getb_signed_64, bfd_putb64,
546     bfd_getb32, bfd_getb_signed_32, bfd_putb32,
547     bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* data */
548     bfd_getb64, bfd_getb_signed_64, bfd_putb64,
549     bfd_getb32, bfd_getb_signed_32, bfd_putb32,
550     bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* hdrs */
551     {_bfd_dummy_target, aout_adobe_object_p,    /* bfd_check_format */
552      bfd_generic_archive_p, _bfd_dummy_target},
553     {bfd_false, aout_adobe_mkobject,            /* bfd_set_format */
554      _bfd_generic_mkarchive, bfd_false},
555     {bfd_false, aout_adobe_write_object_contents,/* bfd_write_contents */
556      _bfd_write_archive_contents, bfd_false},
557
558     BFD_JUMP_TABLE_GENERIC (aout_32),
559     BFD_JUMP_TABLE_COPY (_bfd_generic),
560     BFD_JUMP_TABLE_CORE (_bfd_nocore),
561     BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_bsd),
562     BFD_JUMP_TABLE_SYMBOLS (aout_32),
563     BFD_JUMP_TABLE_RELOCS (aout_32),
564     BFD_JUMP_TABLE_WRITE (aout_32),
565     BFD_JUMP_TABLE_LINK (aout_32),
566     BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
567
568     NULL,
569
570     (PTR) 0
571   };