* sunos.c: Remove all code that goes in aout.c. Split out
[external/binutils.git] / bfd / sunos.c
1 /* BFD backend for sunos binaries */
2
3 /* Copyright (C) 1990, 1991 Free Software Foundation, Inc.
4
5 This file is part of BFD, the Binary File Diddler.
6
7 BFD is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 1, or (at your option)
10 any later version.
11
12 BFD is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with BFD; see the file COPYING.  If not, write to
19 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
20
21 /* $Id$ */
22
23 #include <ansidecl.h>
24 #include "sysdep.h"
25 #include "bfd.h"
26 #include "libbfd.h"
27
28 #include "a.out.sun4.h"
29 #include "a.out.gnu.h"
30 #include "stab.gnu.h"
31 #include "ar.h"
32 #include "liba.out.h"           /* BFD a.out internal data structures */
33
34 void (*bfd_error_trap)();
35
36 static bfd_target *sunos4_callback ();
37
38 /*SUPPRESS558*/
39 /*SUPPRESS529*/
40
41 bfd_target *
42 sunos4_object_p (abfd)
43      bfd *abfd;
44 {
45   unsigned char magicbuf[4];    /* Raw bytes of magic number from file */
46   unsigned long magic;          /* Swapped magic number */
47
48   bfd_error = system_call_error;
49
50   if (bfd_read ((PTR)magicbuf, 1, sizeof (magicbuf), abfd) !=
51       sizeof (magicbuf))
52     return 0;
53   magic = bfd_h_getlong (abfd, magicbuf);
54
55   if (N_BADMAG (*((struct exec *) &magic))) return 0;
56
57   return some_aout_object_p (abfd, sunos4_callback);
58 }
59
60 /* Set parameters about this a.out file that are machine-dependent.
61    This routine is called from some_aout_object_p just before it returns.  */
62
63 static bfd_target *
64 sunos4_callback (abfd)
65      bfd *abfd;
66 {
67   struct exec *execp = exec_hdr (abfd);
68
69   /* The virtual memory addresses of the sections */
70   obj_datasec (abfd)->vma = N_DATADDR(*execp);
71   obj_bsssec (abfd)->vma = N_BSSADDR(*execp);
72   obj_textsec (abfd)->vma = N_TXTADDR(*execp);
73
74   /* The file offsets of the sections */
75   obj_textsec (abfd)->filepos = N_TXTOFF(*execp);
76   obj_datasec (abfd)->filepos = N_DATOFF(*execp);
77
78   /* The file offsets of the relocation info */
79   obj_textsec (abfd)->rel_filepos = N_TRELOFF(*execp);
80   obj_datasec (abfd)->rel_filepos = N_DRELOFF(*execp);
81
82   /* The file offsets of the string table and symbol table.  */
83   obj_str_filepos (abfd) = N_STROFF (*execp);
84   obj_sym_filepos (abfd) = N_SYMOFF (*execp);
85
86   /* Determine the architecture and machine type of the object file.  */
87   switch (N_MACHTYPE (*exec_hdr (abfd))) {
88
89   case M_UNKNOWN:
90         abfd->obj_arch = bfd_arch_unknown;
91         abfd->obj_machine = 0;
92         break;
93
94   case M_68010:
95         abfd->obj_arch = bfd_arch_m68k;
96         abfd->obj_machine = 68010;
97         break;
98
99   case M_68020:
100         abfd->obj_arch = bfd_arch_m68k;
101         abfd->obj_machine = 68020;
102         break;
103
104   case M_SPARC:
105         abfd->obj_arch = bfd_arch_sparc;
106         abfd->obj_machine = 0;
107         break;
108
109   case M_386:
110         abfd->obj_arch = bfd_arch_i386;
111         abfd->obj_machine = 0;
112         break;
113
114   case M_29K:
115         abfd->obj_arch = bfd_arch_a29k;
116         abfd->obj_machine = 0;
117         break;
118
119   default:
120         abfd->obj_arch = bfd_arch_obscure;
121         abfd->obj_machine = 0;
122         break;
123   }
124
125   /* Determine the size of a relocation entry, based on the architecture */
126   switch (abfd->obj_arch) {
127   case bfd_arch_sparc:
128   case bfd_arch_a29k:
129     obj_reloc_entry_size (abfd) = RELOC_EXT_SIZE;
130   default:
131     obj_reloc_entry_size (abfd) = RELOC_STD_SIZE;
132   }
133   return abfd->xvec;
134 }
135
136
137 boolean
138 sunos4_mkobject (abfd)
139      bfd *abfd;
140 {
141   char *rawptr;
142
143   bfd_error = system_call_error;
144
145   /* Use an intermediate variable for clarity */
146   rawptr = bfd_zalloc (abfd, sizeof (struct aoutdata) + sizeof (struct exec));
147
148   if (rawptr == NULL) {
149     bfd_error = no_memory;
150     return false;
151   }
152
153   set_tdata (abfd, (struct aoutdata *) rawptr);
154   exec_hdr (abfd) = (struct exec *) (rawptr + sizeof (struct aoutdata));
155
156   /* For simplicity's sake we just make all the sections right here. */
157
158   obj_textsec (abfd) = (asection *)NULL;
159   obj_datasec (abfd) = (asection *)NULL;
160   obj_bsssec (abfd) = (asection *)NULL;
161   bfd_make_section (abfd, ".text");
162   bfd_make_section (abfd, ".data");
163   bfd_make_section (abfd, ".bss");
164
165   return true;
166 }
167
168 /* Keep track of machine architecture and machine type for a.out's.
169    Return the machine_type for a particular arch&machine, or M_UNKNOWN
170    if that exact arch&machine can't be represented in a.out format.
171
172    If the architecture is understood, machine type 0 (default) should
173    always be understood.  */
174
175 static enum machine_type
176 aout_machine_type (arch, machine)
177      enum bfd_architecture arch;
178      unsigned long machine;
179 {
180   enum machine_type arch_flags;
181
182   arch_flags = M_UNKNOWN;
183
184   switch (arch) {
185   case bfd_arch_sparc:
186     if (machine == 0)   arch_flags = M_SPARC;
187     break;
188
189   case bfd_arch_m68k:
190     switch (machine) {
191     case 0:             arch_flags = M_68010; break;
192     case 68000:         arch_flags = M_UNKNOWN; break;
193     case 68010:         arch_flags = M_68010; break;
194     case 68020:         arch_flags = M_68020; break;
195     default:            arch_flags = M_UNKNOWN; break;
196     }
197     break;
198
199   case bfd_arch_i386:
200     if (machine == 0)   arch_flags = M_386;
201     break;
202
203   case bfd_arch_a29k:
204     if (machine == 0)   arch_flags = M_29K;
205     break;
206
207   default:
208     arch_flags = M_UNKNOWN;
209     break;
210   }
211   return arch_flags;
212 }
213
214 /* Write an object file in SunOS format.
215    Section contents have already been written.  We write the
216    file header, symbols, and relocation.  */
217
218 boolean
219 sunos4_write_object_contents (abfd)
220      bfd *abfd;
221 {
222   size_t data_pad = 0;
223   unsigned char exec_bytes[EXEC_BYTES_SIZE];
224   struct exec *execp = exec_hdr (abfd);
225
226   execp->a_text = obj_textsec (abfd)->size;
227
228   /* Magic number, maestro, please!  */
229   switch (bfd_get_architecture(abfd)) {
230   case bfd_arch_m68k:
231     switch (bfd_get_machine(abfd)) {
232     case 68010:
233       N_SET_MACHTYPE(*execp, M_68010);
234       break;
235     default:
236     case 68020:
237       N_SET_MACHTYPE(*execp, M_68020);
238       break;
239     }
240     break;
241   case bfd_arch_sparc:
242     N_SET_MACHTYPE(*execp, M_SPARC);
243     break;
244   case bfd_arch_i386:
245     N_SET_MACHTYPE(*execp, M_386);
246     break;
247   case bfd_arch_a29k:
248     N_SET_MACHTYPE(*execp, M_29K);
249     break;
250   default:
251     N_SET_MACHTYPE(*execp, M_UNKNOWN);
252   }
253
254   N_SET_MAGIC (*execp, OMAGIC);
255   if (abfd->flags & D_PAGED) {
256     /* This is not strictly true, but will probably do for the default
257         case.  FIXME.  */
258     execp->a_text = obj_textsec (abfd)->size + sizeof(struct exec);
259     N_SET_MAGIC (*execp, ZMAGIC);
260   } else if (abfd->flags & WP_TEXT) {
261     N_SET_MAGIC (*execp, NMAGIC);
262   }
263   N_SET_FLAGS (*execp, 0x1);    /* copied from ld.c; who the hell knows? */
264
265   if (abfd->flags & D_PAGED) 
266       {
267         data_pad = ((obj_datasec(abfd)->size + PAGE_SIZE -1)
268                     & (- PAGE_SIZE)) - obj_datasec(abfd)->size;
269
270         if (data_pad > obj_bsssec(abfd)->size)
271           execp->a_bss = 0;
272         else 
273           execp->a_bss = obj_bsssec(abfd)->size - data_pad;
274         execp->a_data = obj_datasec(abfd)->size + data_pad;
275
276       }
277   else {
278     execp->a_data = obj_datasec (abfd)->size;
279     execp->a_bss = obj_bsssec (abfd)->size;
280   }
281
282   execp->a_syms = bfd_get_symcount (abfd) * sizeof (struct nlist);
283   execp->a_entry = bfd_get_start_address (abfd);
284
285   execp->a_trsize = ((obj_textsec (abfd)->reloc_count) *
286                      obj_reloc_entry_size (abfd));
287                        
288   execp->a_drsize = ((obj_datasec (abfd)->reloc_count) *
289                      obj_reloc_entry_size (abfd));
290
291   bfd_aout_swap_exec_header_out (abfd, execp, exec_bytes);
292
293   bfd_seek (abfd, 0L, false);
294   bfd_write ((PTR) exec_bytes, 1, EXEC_BYTES_SIZE, abfd);
295
296   /* Now write out reloc info, followed by syms and strings */
297
298   if (bfd_get_symcount (abfd) != 0) 
299     {
300       bfd_seek (abfd,
301                 (long)(N_SYMOFF(*execp)), false);
302
303       aout_write_syms (abfd);
304
305       bfd_seek (abfd,   (long)(N_TRELOFF(*execp)), false);
306
307       if (!aout_squirt_out_relocs (abfd, obj_textsec (abfd))) return false;
308       bfd_seek (abfd, (long)(N_DRELOFF(*execp)), false);
309
310       if (!aout_squirt_out_relocs (abfd, obj_datasec (abfd))) return false;
311     }
312   return true;
313 }
314 \f
315 /* core files */
316
317 #define CORE_MAGIC 0x080456
318 #define CORE_NAMELEN 16
319
320 /* The core structure is taken from the Sun documentation.
321    Unfortunately, they don't document the FPA structure, or at least I
322    can't find it easily.  Fortunately the core header contains its own
323    length.  So this shouldn't cause problems, except for c_ucode, which
324    so far we don't use but is easy to find with a little arithmetic. */
325
326 /* But the reg structure can be gotten from the SPARC processor handbook.
327    This really should be in a GNU include file though so that gdb can use
328    the same info. */
329 struct regs {
330   int r_psr;
331   int r_pc;
332   int r_npc;
333   int r_y;
334   int r_g1;
335   int r_g2;
336   int r_g3;
337   int r_g4;
338   int r_g5;
339   int r_g6;
340   int r_g7;
341   int r_o0;
342   int r_o1;
343   int r_o2;
344   int r_o3;
345   int r_o4;
346   int r_o5;
347   int r_o6;
348   int r_o7;
349 };
350
351 /* Taken from Sun documentation: */
352
353 /* FIXME:  It's worse than we expect.  This struct contains TWO substructs
354    neither of whose size we know, WITH STUFF IN BETWEEN THEM!  We can't
355    even portably access the stuff in between!  */
356
357 struct core {
358   int c_magic;                  /* Corefile magic number */
359   int c_len;                    /* Sizeof (struct core) */
360   struct regs c_regs;           /* General purpose registers -- MACHDEP SIZE */
361   struct exec c_aouthdr;        /* A.out header */
362   int c_signo;                  /* Killing signal, if any */
363   int c_tsize;                  /* Text size (bytes) */
364   int c_dsize;                  /* Data size (bytes) */
365   int c_ssize;                  /* Stack size (bytes) */
366   char c_cmdname[CORE_NAMELEN + 1]; /* Command name */
367   double fp_stuff[1];           /* external FPU state (size unknown by us) */
368                 /* The type "double" is critical here, for alignment.
369                    SunOS declares a struct here, but the struct's alignment
370                    is double since it contains doubles.  */
371   int c_ucode;                  /* Exception no. from u_code */
372                 /* (this member is not accessible by name since we don't
373                     portably know the size of fp_stuff.) */
374 };
375
376 /* Supposedly the user stack grows downward from the bottom of kernel memory.
377    Presuming that this remains true, this definition will work. */
378 #define USRSTACK (-(128*1024*1024))
379
380 PROTO (static void, swapcore, (bfd *abfd, struct core *core));
381
382 /* need this cast b/c ptr is really void * */
383 #define core_hdr(bfd) (((struct suncordata *) (bfd->tdata))->hdr)
384 #define core_datasec(bfd) (((struct suncordata *) ((bfd)->tdata))->data_section)
385 #define core_stacksec(bfd) (((struct suncordata*)((bfd)->tdata))->stack_section)
386 #define core_regsec(bfd) (((struct suncordata *) ((bfd)->tdata))->reg_section)
387 #define core_reg2sec(bfd) (((struct suncordata *) ((bfd)->tdata))->reg2_section)
388
389 /* These are stored in the bfd's tdata */
390 struct suncordata {
391   struct core *hdr;             /* core file header */
392   asection *data_section;
393   asection *stack_section;
394   asection *reg_section;
395   asection *reg2_section;
396 };
397
398 bfd_target *
399 sunos4_core_file_p (abfd)
400      bfd *abfd;
401 {
402   unsigned char longbuf[4];     /* Raw bytes of various header fields */
403   int core_size;
404   int core_mag;
405   struct core *core;
406   char *rawptr;
407
408   bfd_error = system_call_error;
409
410   if (bfd_read ((PTR)longbuf, 1, sizeof (longbuf), abfd) !=
411          sizeof (longbuf))
412     return 0;
413   core_mag = bfd_h_getlong (abfd, longbuf);
414
415   if (core_mag != CORE_MAGIC) return 0;
416
417   /* SunOS core headers can vary in length; second word is size; */
418   if (bfd_read ((PTR)longbuf, 1, sizeof (longbuf), abfd) !=
419          sizeof (longbuf))
420     return 0;
421   core_size = bfd_h_getlong (abfd, longbuf);
422   /* Sanity check */
423   if (core_size > 20000)
424     return 0;
425
426   if (bfd_seek (abfd, 0L, false) < 0) return 0;
427
428   rawptr = bfd_zalloc (abfd, core_size + sizeof (struct suncordata));
429   if (rawptr == NULL) {
430     bfd_error = no_memory;
431     return 0;
432   }
433
434   core = (struct core *) (rawptr + sizeof (struct suncordata));
435
436   if ((bfd_read ((PTR) core, 1, core_size, abfd)) != core_size) {
437     bfd_error = system_call_error;
438     bfd_release (abfd, rawptr);
439     return 0;
440   }
441
442   swapcore (abfd, core);
443   set_tdata (abfd, ((struct suncordata *) rawptr));
444   core_hdr (abfd) = core;
445
446   /* create the sections.  This is raunchy, but bfd_close wants to reclaim
447      them */
448   core_stacksec (abfd) = (asection *) bfd_zalloc (abfd, sizeof (asection));
449   if (core_stacksec (abfd) == NULL) {
450 loser:
451     bfd_error = no_memory;
452     bfd_release (abfd, rawptr);
453     return 0;
454   }
455   core_datasec (abfd) = (asection *) bfd_zalloc (abfd, sizeof (asection));
456   if (core_datasec (abfd) == NULL) {
457 loser1:
458     bfd_release (abfd, core_stacksec (abfd));
459     goto loser;
460   }
461   core_regsec (abfd) = (asection *) bfd_zalloc (abfd, sizeof (asection));
462   if (core_regsec (abfd) == NULL) {
463 loser2:
464     bfd_release (abfd, core_datasec (abfd));
465     goto loser1;
466   }
467   core_reg2sec (abfd) = (asection *) bfd_zalloc (abfd, sizeof (asection));
468   if (core_reg2sec (abfd) == NULL) {
469     bfd_release (abfd, core_regsec (abfd));
470     goto loser2;
471   }
472
473   core_stacksec (abfd)->name = ".stack";
474   core_datasec (abfd)->name = ".data";
475   core_regsec (abfd)->name = ".reg";
476   core_reg2sec (abfd)->name = ".reg2";
477
478   core_stacksec (abfd)->flags = SEC_ALLOC + SEC_LOAD;
479   core_datasec (abfd)->flags = SEC_ALLOC + SEC_LOAD;
480   core_regsec (abfd)->flags = SEC_ALLOC;
481   core_reg2sec (abfd)->flags = SEC_ALLOC;
482
483   core_stacksec (abfd)->size = core->c_ssize;
484   core_datasec (abfd)->size = core->c_dsize;
485   core_regsec (abfd)->size = (sizeof core->c_regs);
486   /* Float regs take up end of struct, except c_ucode.  */
487   core_reg2sec (abfd)->size = core_size - (sizeof core->c_ucode) -
488                               (file_ptr)(((struct core *)0)->fp_stuff);
489
490   core_stacksec (abfd)->vma = (USRSTACK - core->c_ssize);
491   core_datasec (abfd)->vma = N_DATADDR(core->c_aouthdr);
492   core_regsec (abfd)->vma = -1;
493   core_reg2sec (abfd)->vma = -1;
494
495   core_stacksec (abfd)->filepos = core->c_len + core->c_dsize;
496   core_datasec (abfd)->filepos = core->c_len;
497                         /* In file header: */
498   core_regsec (abfd)->filepos = (file_ptr)(&((struct core *)0)->c_regs);
499   core_reg2sec (abfd)->filepos = (file_ptr)(((struct core *)0)->fp_stuff);
500
501   /* Align to word at least */
502   core_stacksec (abfd)->alignment_power = 2;
503   core_datasec (abfd)->alignment_power = 2;
504   core_regsec (abfd)->alignment_power = 2;
505   core_reg2sec (abfd)->alignment_power = 2;
506
507   abfd->sections = core_stacksec (abfd);
508   core_stacksec (abfd)->next = core_datasec (abfd);
509   core_datasec (abfd)->next = core_regsec (abfd);
510   core_regsec (abfd)->next = core_reg2sec (abfd);
511
512   abfd->section_count = 4;
513
514   return abfd->xvec;
515 }
516
517 char *
518 sunos4_core_file_failing_command (abfd)
519      bfd *abfd;
520 {
521   return core_hdr (abfd)->c_cmdname;
522 }
523
524 int
525 sunos4_core_file_failing_signal (abfd)
526      bfd *abfd;
527 {
528   return core_hdr (abfd)->c_signo;
529 }
530
531 boolean
532 sunos4_core_file_matches_executable_p  (core_bfd, exec_bfd)
533      bfd *core_bfd, *exec_bfd;
534 {
535   if (core_bfd->xvec != exec_bfd->xvec) {
536     bfd_error = system_call_error;
537     return false;
538   }
539
540   return (bcmp ((char *)&core_hdr (core_bfd), (char*) &exec_hdr (exec_bfd),
541                 sizeof (struct exec)) == 0) ? true : false;
542 }
543
544 /* byte-swap core structure */
545 /* FIXME, this needs more work to swap IN a core struct from raw bytes */
546 static void
547 swapcore (abfd, core)
548      bfd *abfd;
549      struct core *core;
550 {
551   unsigned char exec_bytes[EXEC_BYTES_SIZE];
552
553   core->c_magic = bfd_h_getlong (abfd, (unsigned char *)&core->c_magic);
554   core->c_len   = bfd_h_getlong (abfd, (unsigned char *)&core->c_len  );
555   /* Leave integer registers in target byte order.  */
556   bcopy ((char *)&(core->c_aouthdr), (char *)exec_bytes, EXEC_BYTES_SIZE);
557   bfd_aout_swap_exec_header_in (abfd, exec_bytes, &core->c_aouthdr);
558   core->c_signo = bfd_h_getlong (abfd, (unsigned char *)&core->c_signo);
559   core->c_tsize = bfd_h_getlong (abfd, (unsigned char *)&core->c_tsize);
560   core->c_dsize = bfd_h_getlong (abfd, (unsigned char *)&core->c_dsize);
561   core->c_ssize = bfd_h_getlong (abfd, (unsigned char *)&core->c_ssize);
562   /* Leave FP registers in target byte order.  */
563   /* Leave "c_ucode" unswapped for now, since we can't find it easily.  */
564 }
565 \f
566 /* We use BFD generic archive files.  */
567 #define aout_openr_next_archived_file   bfd_generic_openr_next_archived_file
568 #define aout_generic_stat_arch_elt      bfd_generic_stat_arch_elt
569 #define aout_slurp_armap                bfd_slurp_bsd_armap
570 #define aout_slurp_extended_name_table  bfd_true
571 #define aout_write_armap                bsd_write_armap
572 #define aout_truncate_arname            bfd_bsd_truncate_arname
573
574 /* We use our own core file format.  */
575 #define aout_core_file_failing_command  sunos4_core_file_failing_command
576 #define aout_core_file_failing_signal   sunos4_core_file_failing_signal
577 #define aout_core_file_matches_executable_p     \
578                                         sunos4_core_file_matches_executable_p
579
580 /* We implement these routines ourselves, rather than using the generic
581    a.out versions.  */
582 #define aout_write_object_contents      sunos4_write_object_contents
583
584 bfd_target sunos_big_vec =
585 {
586   "a.out-sunos-big",            /* name */
587   bfd_target_aout_flavour_enum,
588   true,                         /* target byte order */
589   true,                         /* target headers byte order */
590   (HAS_RELOC | EXEC_P |         /* object flags */
591    HAS_LINENO | HAS_DEBUG |
592    HAS_SYMS | HAS_LOCALS | DYNAMIC | WP_TEXT | D_PAGED),
593   (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
594   ' ',                          /* ar_pad_char */
595   16,                           /* ar_max_namelen */
596   _do_getblong, _do_putblong, _do_getbshort, _do_putbshort, /* data */
597   _do_getblong, _do_putblong, _do_getbshort, _do_putbshort, /* hdrs */
598
599     {_bfd_dummy_target, sunos4_object_p,
600        bfd_generic_archive_p, sunos4_core_file_p},
601     {bfd_false, sunos4_mkobject,
602        _bfd_generic_mkarchive, bfd_false},
603     {bfd_false, sunos4_write_object_contents,   /* bfd_write_contents */
604        _bfd_write_archive_contents, bfd_false},
605
606   JUMP_TABLE(aout)
607 };