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