* elf64-sparc.c (sparc64_elf_relocate_section): Ignore overflows
[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,
3    2001, 2002, 2003, 2004
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 *, const 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             (_("%B: Unknown section type in a.out.adobe file: %x\n"),
205              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->size = ((ext->e_size[0] << 8)
239                     | ext->e_size[1] << 8
240                     | ext->e_size[2]);
241       sect->vma = H_GET_32 (abfd, ext->e_virtbase);
242       sect->filepos = H_GET_32 (abfd, ext->e_filebase);
243       /* FIXME XXX alignment?  */
244
245       /* Set relocation information for first section of each type.  */
246       if (trynum == 0)
247         switch (ext->e_type[0])
248           {
249           case N_TEXT:
250             sect->rel_filepos = N_TRELOFF (*execp);
251             sect->reloc_count = execp->a_trsize;
252             break;
253
254           case N_DATA:
255             sect->rel_filepos = N_DRELOFF (*execp);
256             sect->reloc_count = execp->a_drsize;
257             break;
258
259           default:
260             break;
261           }
262     }
263  no_more_sections:
264
265   adata (abfd).reloc_entry_size = sizeof (struct reloc_std_external);
266   adata (abfd).symbol_entry_size = sizeof (struct external_nlist);
267   adata (abfd).page_size = 1; /* Not applicable.  */
268   adata (abfd).segment_size = 1; /* Not applicable.  */
269   adata (abfd).exec_bytes_size = EXEC_BYTES_SIZE;
270
271   return abfd->xvec;
272 }
273
274 struct bout_data_struct
275   {
276     struct aoutdata a;
277     struct internal_exec e;
278   };
279
280 static bfd_boolean
281 aout_adobe_mkobject (abfd)
282      bfd *abfd;
283 {
284   struct bout_data_struct *rawptr;
285   bfd_size_type amt = sizeof (struct bout_data_struct);
286
287   rawptr = (struct bout_data_struct *) bfd_zalloc (abfd, amt);
288   if (rawptr == NULL)
289     return FALSE;
290
291   abfd->tdata.bout_data = rawptr;
292   exec_hdr (abfd) = &rawptr->e;
293
294   adata (abfd).reloc_entry_size = sizeof (struct reloc_std_external);
295   adata (abfd).symbol_entry_size = sizeof (struct external_nlist);
296   adata (abfd).page_size = 1; /* Not applicable.  */
297   adata (abfd).segment_size = 1; /* Not applicable.  */
298   adata (abfd).exec_bytes_size = EXEC_BYTES_SIZE;
299
300   return TRUE;
301 }
302
303 static bfd_boolean
304 aout_adobe_write_object_contents (abfd)
305      bfd *abfd;
306 {
307   struct external_exec swapped_hdr;
308   static struct external_segdesc sentinel[1];   /* Initialized to zero.  */
309   asection *sect;
310   bfd_size_type amt;
311
312   exec_hdr (abfd)->a_info = ZMAGIC;
313
314   /* Calculate text size as total of text sections, etc.  */
315
316   exec_hdr (abfd)->a_text = 0;
317   exec_hdr (abfd)->a_data = 0;
318   exec_hdr (abfd)->a_bss  = 0;
319   exec_hdr (abfd)->a_trsize = 0;
320   exec_hdr (abfd)->a_drsize = 0;
321
322   for (sect = abfd->sections; sect; sect = sect->next)
323     {
324       if (sect->flags & SEC_CODE)
325         {
326           exec_hdr (abfd)->a_text += sect->size;
327           exec_hdr (abfd)->a_trsize += sect->reloc_count *
328             sizeof (struct reloc_std_external);
329         }
330       else if (sect->flags & SEC_DATA)
331         {
332           exec_hdr (abfd)->a_data += sect->size;
333           exec_hdr (abfd)->a_drsize += sect->reloc_count *
334             sizeof (struct reloc_std_external);
335         }
336       else if (sect->flags & SEC_ALLOC && !(sect->flags & SEC_LOAD))
337         {
338           exec_hdr (abfd)->a_bss += sect->size;
339         }
340     }
341
342   exec_hdr (abfd)->a_syms = bfd_get_symcount (abfd)
343     * sizeof (struct external_nlist);
344   exec_hdr (abfd)->a_entry = bfd_get_start_address (abfd);
345
346   aout_adobe_swap_exec_header_out (abfd, exec_hdr (abfd), &swapped_hdr);
347
348   amt = EXEC_BYTES_SIZE;
349   if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0
350       || bfd_bwrite ((PTR) &swapped_hdr, amt, abfd) != amt)
351     return FALSE;
352
353   /* Now write out the section information.  Text first, data next, rest
354      afterward.  */
355
356   for (sect = abfd->sections; sect; sect = sect->next)
357     if (sect->flags & SEC_CODE)
358       aout_adobe_write_section (abfd, sect);
359
360   for (sect = abfd->sections; sect; sect = sect->next)
361     if (sect->flags & SEC_DATA)
362       aout_adobe_write_section (abfd, sect);
363
364   for (sect = abfd->sections; sect; sect = sect->next)
365     if (!(sect->flags & (SEC_CODE | SEC_DATA)))
366       aout_adobe_write_section (abfd, sect);
367
368   /* Write final `sentinel` section header (with type of 0).  */
369   amt = sizeof (*sentinel);
370   if (bfd_bwrite ((PTR) sentinel, amt, abfd) != amt)
371     return FALSE;
372
373   /* Now write out reloc info, followed by syms and strings.  */
374   if (bfd_get_symcount (abfd) != 0)
375     {
376       if (bfd_seek (abfd, (file_ptr) (N_SYMOFF (*exec_hdr (abfd))), SEEK_SET)
377           != 0)
378         return FALSE;
379
380       if (! aout_32_write_syms (abfd))
381         return FALSE;
382
383       if (bfd_seek (abfd, (file_ptr) (N_TRELOFF (*exec_hdr (abfd))), SEEK_SET)
384           != 0)
385         return FALSE;
386
387       for (sect = abfd->sections; sect; sect = sect->next)
388         if (sect->flags & SEC_CODE)
389           if (!aout_32_squirt_out_relocs (abfd, sect))
390             return FALSE;
391
392       if (bfd_seek (abfd, (file_ptr) (N_DRELOFF (*exec_hdr (abfd))), SEEK_SET)
393           != 0)
394         return FALSE;
395
396       for (sect = abfd->sections; sect; sect = sect->next)
397         if (sect->flags & SEC_DATA)
398           if (!aout_32_squirt_out_relocs (abfd, sect))
399             return FALSE;
400     }
401
402   return TRUE;
403 }
404
405 static void
406 aout_adobe_write_section (abfd, sect)
407      bfd *abfd ATTRIBUTE_UNUSED;
408      sec_ptr sect ATTRIBUTE_UNUSED;
409 {
410   /* FIXME XXX */
411 }
412 \f
413 static bfd_boolean
414 aout_adobe_set_section_contents (abfd, section, location, offset, count)
415      bfd *abfd;
416      asection *section;
417      const PTR location;
418      file_ptr offset;
419      bfd_size_type count;
420 {
421   file_ptr section_start;
422   sec_ptr sect;
423
424   /* Set by bfd.c handler.  */
425   if (! abfd->output_has_begun)
426     {
427       /* Assign file offsets to sections.  Text sections are first, and
428          are contiguous.  Then data sections.  Everything else at the end.  */
429       section_start = N_TXTOFF (ignore<-->me);
430
431       for (sect = abfd->sections; sect; sect = sect->next)
432         {
433           if (sect->flags & SEC_CODE)
434             {
435               sect->filepos = section_start;
436               /* FIXME:  Round to alignment.  */
437               section_start += sect->size;
438             }
439         }
440
441       for (sect = abfd->sections; sect; sect = sect->next)
442         {
443           if (sect->flags & SEC_DATA)
444             {
445               sect->filepos = section_start;
446               /* FIXME:  Round to alignment.  */
447               section_start += sect->size;
448             }
449         }
450
451       for (sect = abfd->sections; sect; sect = sect->next)
452         {
453           if (sect->flags & SEC_HAS_CONTENTS &&
454               !(sect->flags & (SEC_CODE | SEC_DATA)))
455             {
456               sect->filepos = section_start;
457               /* FIXME:  Round to alignment.  */
458               section_start += sect->size;
459             }
460         }
461     }
462
463   /* Regardless, once we know what we're doing, we might as well get
464      going.  */
465   if (bfd_seek (abfd, section->filepos + offset, SEEK_SET) != 0)
466     return FALSE;
467
468   if (count == 0)
469     return TRUE;
470
471   return bfd_bwrite ((PTR) location, count, abfd) == count;
472 }
473
474 static bfd_boolean
475 aout_adobe_set_arch_mach (abfd, arch, machine)
476      bfd *abfd;
477      enum bfd_architecture arch;
478      unsigned long machine;
479 {
480   if (! bfd_default_set_arch_mach (abfd, arch, machine))
481     return FALSE;
482
483   if (arch == bfd_arch_unknown
484       || arch == bfd_arch_m68k)
485     return TRUE;
486
487   return FALSE;
488 }
489
490 static int
491 aout_adobe_sizeof_headers (ignore_abfd, ignore)
492      bfd *ignore_abfd ATTRIBUTE_UNUSED;
493      bfd_boolean ignore ATTRIBUTE_UNUSED;
494 {
495   return sizeof (struct internal_exec);
496 }
497
498 /* Build the transfer vector for Adobe A.Out files.  */
499
500 #define aout_32_close_and_cleanup aout_32_bfd_free_cached_info
501
502 #define aout_32_bfd_make_debug_symbol \
503   ((asymbol *(*) PARAMS ((bfd *, void *, unsigned long))) bfd_nullvoidptr)
504
505 #define aout_32_bfd_reloc_type_lookup \
506   ((reloc_howto_type *(*) \
507     PARAMS ((bfd *, bfd_reloc_code_real_type))) bfd_nullvoidptr)
508
509 #define aout_32_set_arch_mach           aout_adobe_set_arch_mach
510 #define aout_32_set_section_contents    aout_adobe_set_section_contents
511
512 #define aout_32_sizeof_headers          aout_adobe_sizeof_headers
513 #define aout_32_bfd_get_relocated_section_contents \
514   bfd_generic_get_relocated_section_contents
515 #define aout_32_get_section_contents_in_window _bfd_generic_get_section_contents_in_window
516 #define aout_32_bfd_relax_section       bfd_generic_relax_section
517 #define aout_32_bfd_gc_sections         bfd_generic_gc_sections
518 #define aout_32_bfd_merge_sections      bfd_generic_merge_sections
519 #define aout_32_bfd_is_group_section    bfd_generic_is_group_section
520 #define aout_32_bfd_discard_group       bfd_generic_discard_group
521 #define aout_32_section_already_linked \
522   _bfd_generic_section_already_linked
523 #define aout_32_bfd_link_hash_table_create \
524   _bfd_generic_link_hash_table_create
525 #define aout_32_bfd_link_hash_table_free \
526   _bfd_generic_link_hash_table_free
527 #define aout_32_bfd_link_add_symbols    _bfd_generic_link_add_symbols
528 #define aout_32_bfd_link_just_syms      _bfd_generic_link_just_syms
529 #define aout_32_bfd_final_link          _bfd_generic_final_link
530 #define aout_32_bfd_link_split_section  _bfd_generic_link_split_section
531
532 const bfd_target a_out_adobe_vec =
533   {
534     "a.out.adobe",              /* name */
535     bfd_target_aout_flavour,
536     BFD_ENDIAN_BIG,             /* data byte order is unknown (big assumed) */
537     BFD_ENDIAN_BIG,             /* hdr byte order is big */
538     (HAS_RELOC | EXEC_P |       /* object flags */
539      HAS_LINENO | HAS_DEBUG |
540      HAS_SYMS | HAS_LOCALS | WP_TEXT ),
541     /* section flags */
542     (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_CODE | SEC_DATA | SEC_RELOC),
543     '_',                                /*  symbol leading char */
544     ' ',                                /* ar_pad_char */
545     16,                                 /* ar_max_namelen */
546
547     bfd_getb64, bfd_getb_signed_64, bfd_putb64,
548     bfd_getb32, bfd_getb_signed_32, bfd_putb32,
549     bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* data */
550     bfd_getb64, bfd_getb_signed_64, bfd_putb64,
551     bfd_getb32, bfd_getb_signed_32, bfd_putb32,
552     bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* hdrs */
553     {_bfd_dummy_target, aout_adobe_object_p,    /* bfd_check_format */
554      bfd_generic_archive_p, _bfd_dummy_target},
555     {bfd_false, aout_adobe_mkobject,            /* bfd_set_format */
556      _bfd_generic_mkarchive, bfd_false},
557     {bfd_false, aout_adobe_write_object_contents,/* bfd_write_contents */
558      _bfd_write_archive_contents, bfd_false},
559
560     BFD_JUMP_TABLE_GENERIC (aout_32),
561     BFD_JUMP_TABLE_COPY (_bfd_generic),
562     BFD_JUMP_TABLE_CORE (_bfd_nocore),
563     BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_bsd),
564     BFD_JUMP_TABLE_SYMBOLS (aout_32),
565     BFD_JUMP_TABLE_RELOCS (aout_32),
566     BFD_JUMP_TABLE_WRITE (aout_32),
567     BFD_JUMP_TABLE_LINK (aout_32),
568     BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
569
570     NULL,
571
572     (PTR) 0
573   };