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