*** empty log message ***
[external/binutils.git] / bfd / aoutf1.h
1 /* BFD backend for generic a.out flavour 1 */
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 #include <ansidecl.h>
22 #include <sysdep.h>
23 struct external_exec;
24 #include <a.out.sun4.h>
25 #include "bfd.h"
26 #include "liba.out.h"           
27 #include "libbfd.h"
28
29
30
31 #include "aout64.h"
32 #include "stab.gnu.h"
33 #include "ar.h"
34
35
36
37 void (*bfd_error_trap)();
38
39 static bfd_target *sunos4_callback ();
40
41 /*SUPPRESS558*/
42 /*SUPPRESS529*/
43
44 bfd_target *
45 DEFUN(NAME(sunos,object_p), (abfd),
46      bfd *abfd)
47 {
48   unsigned char magicbuf[4];    /* Raw bytes of magic number from file */
49   unsigned long magic;          /* Swapped magic number */
50
51   bfd_error = system_call_error;
52
53   if (bfd_read ((PTR)magicbuf, 1 , 4, abfd) !=
54       sizeof (magicbuf))
55     return 0;
56   magic = bfd_h_get_32 (abfd, magicbuf);
57
58   if (N_BADMAG (*((struct internal_exec *) &magic))) return 0;
59
60   return NAME(aout,some_aout_object_p) (abfd, sunos4_callback);
61 }
62
63   /* Determine the size of a relocation entry, based on the architecture */
64 static void
65 DEFUN(choose_reloc_size,(abfd),
66 bfd *abfd)
67   {
68     switch (abfd->obj_arch) {
69     case bfd_arch_sparc:
70     case bfd_arch_a29k:
71       obj_reloc_entry_size (abfd) = RELOC_EXT_SIZE;
72       break;
73     default:
74       obj_reloc_entry_size (abfd) = RELOC_STD_SIZE;
75       break;
76     }
77   }
78
79 /* Set parameters about this a.out file that are machine-dependent.
80    This routine is called from some_aout_object_p just before it returns.  */
81
82 static bfd_target *
83 sunos4_callback (abfd)
84      bfd *abfd;
85 {
86   struct internal_exec *execp = exec_hdr (abfd);
87
88   WORK_OUT_FILE_POSITIONS(abfd, execp);  
89   /* Determine the architecture and machine type of the object file.  */
90   switch (N_MACHTYPE (*exec_hdr (abfd))) {
91     
92   case M_UNKNOWN:
93     abfd->obj_arch = bfd_arch_unknown;
94     abfd->obj_machine = 0;
95     break;
96     
97   case M_68010:
98     abfd->obj_arch = bfd_arch_m68k;
99     abfd->obj_machine = 68010;
100     break;
101     
102   case M_68020:
103     abfd->obj_arch = bfd_arch_m68k;
104     abfd->obj_machine = 68020;
105     break;
106     
107   case M_SPARC:
108     abfd->obj_arch = bfd_arch_sparc;
109     abfd->obj_machine = 0;
110     break;
111     
112   case M_386:
113     abfd->obj_arch = bfd_arch_i386;
114     abfd->obj_machine = 0;
115     break;
116     
117   case M_29K:
118     abfd->obj_arch = bfd_arch_a29k;
119     abfd->obj_machine = 0;
120     break;
121     
122   default:
123     abfd->obj_arch = bfd_arch_obscure;
124     abfd->obj_machine = 0;
125     break;
126   }
127   
128   choose_reloc_size(abfd);
129   return abfd->xvec;
130 }
131
132
133 /* Write an object file in SunOS format.
134 Section contents have already been written.  We write the
135 file header, symbols, and relocation.  */
136
137 boolean
138 DEFUN(NAME(aout,sunos4_write_object_contents),(abfd),
139       bfd *abfd)
140
141   {
142     bfd_size_type data_pad = 0;
143     struct external_exec exec_bytes;
144     struct internal_exec *execp = exec_hdr (abfd);
145     
146     
147     
148     execp->a_text = obj_textsec (abfd)->size;
149     
150     /* Magic number, maestro, please!  */
151     switch (bfd_get_architecture(abfd)) {
152     case bfd_arch_m68k:
153       switch (bfd_get_machine(abfd)) {
154       case 68010:
155         N_SET_MACHTYPE(*execp, M_68010);
156         break;
157       default:
158       case 68020:
159         N_SET_MACHTYPE(*execp, M_68020);
160         break;
161       }
162       break;
163     case bfd_arch_sparc:
164       N_SET_MACHTYPE(*execp, M_SPARC);
165       break;
166     case bfd_arch_i386:
167       N_SET_MACHTYPE(*execp, M_386);
168       break;
169     case bfd_arch_a29k:
170       N_SET_MACHTYPE(*execp, M_29K);
171       break;
172     default:
173       N_SET_MACHTYPE(*execp, M_UNKNOWN);
174     }
175     
176     choose_reloc_size(abfd);
177
178     /* FIXME */
179     N_SET_FLAGS (*execp, 0x81);
180     
181     WRITE_HEADERS(abfd, execp);
182
183   return true;
184 }
185 \f
186 /* core files */
187
188 #define CORE_MAGIC 0x080456
189 #define CORE_NAMELEN 16
190
191 /* The core structure is taken from the Sun documentation.
192 Unfortunately, they don't document the FPA structure, or at least I
193 can't find it easily.  Fortunately the core header contains its own
194 length.  So this shouldn't cause problems, except for c_ucode, which
195 so far we don't use but is easy to find with a little arithmetic. */
196
197 /* But the reg structure can be gotten from the SPARC processor handbook.
198 This really should be in a GNU include file though so that gdb can use
199 the same info. */
200 struct regs {
201   int r_psr;
202   int r_pc;
203   int r_npc;
204   int r_y;
205   int r_g1;
206   int r_g2;
207   int r_g3;
208   int r_g4;
209   int r_g5;
210   int r_g6;
211   int r_g7;
212   int r_o0;
213   int r_o1;
214   int r_o2;
215   int r_o3;
216   int r_o4;
217   int r_o5;
218   int r_o6;
219   int r_o7;
220 };
221
222 /* Taken from Sun documentation: */
223
224 /* FIXME:  It's worse than we expect.  This struct contains TWO substructs
225 neither of whose size we know, WITH STUFF IN BETWEEN THEM!  We can't
226 even portably access the stuff in between!  */
227
228 struct core {
229   int c_magic;                  /* Corefile magic number */
230   int c_len;                    /* Sizeof (struct core) */
231   struct regs c_regs;           /* General purpose registers -- MACHDEP SIZE */
232   struct internal_exec c_aouthdr;       /* A.out header */
233   int c_signo;                  /* Killing signal, if any */
234   int c_tsize;                  /* Text size (bytes) */
235   int c_dsize;                  /* Data size (bytes) */
236   int c_ssize;                  /* Stack size (bytes) */
237   char c_cmdname[CORE_NAMELEN + 1]; /* Command name */
238   double fp_stuff[1];               /* external FPU state (size unknown by us) */
239   /* The type "double" is critical here, for alignment.
240     SunOS declares a struct here, but the struct's alignment
241       is double since it contains doubles.  */
242   int c_ucode;                  /* Exception no. from u_code */
243   /* (this member is not accessible by name since we don't
244     portably know the size of fp_stuff.) */
245 };
246
247 /* Supposedly the user stack grows downward from the bottom of kernel memory.
248 Presuming that this remains true, this definition will work. */
249 #define USRSTACK (-(128*1024*1024))
250
251 PROTO (static void, swapcore, (bfd *abfd, struct core *core));
252
253 /* need this cast b/c ptr is really void * */
254 #define core_hdr(bfd) (((struct suncordata *) (bfd->tdata))->hdr)
255 #define core_datasec(bfd) (((struct suncordata *) ((bfd)->tdata))->data_section)
256 #define core_stacksec(bfd) (((struct suncordata*)((bfd)->tdata))->stack_section)
257 #define core_regsec(bfd) (((struct suncordata *) ((bfd)->tdata))->reg_section)
258 #define core_reg2sec(bfd) (((struct suncordata *) ((bfd)->tdata))->reg2_section)
259
260 /* These are stored in the bfd's tdata */
261 struct suncordata {
262 struct core *hdr;             /* core file header */
263 asection *data_section;
264 asection *stack_section;
265 asection *reg_section;
266 asection *reg2_section;
267 };
268
269 static bfd_target *
270 DEFUN(sunos4_core_file_p,(abfd),
271       bfd *abfd)
272 {
273   unsigned char longbuf[4];     /* Raw bytes of various header fields */
274   int core_size;
275   int core_mag;
276   struct core *core;
277   char *rawptr;
278   
279   bfd_error = system_call_error;
280   
281   if (bfd_read ((PTR)longbuf, 1, sizeof (longbuf), abfd) !=
282       sizeof (longbuf))
283     return 0;
284   core_mag = bfd_h_get_32 (abfd, longbuf);
285
286   if (core_mag != CORE_MAGIC) return 0;
287
288   /* SunOS core headers can vary in length; second word is size; */
289   if (bfd_read ((PTR)longbuf, 1, sizeof (longbuf), abfd) !=
290       sizeof (longbuf))
291     return 0;
292   core_size = bfd_h_get_32 (abfd, longbuf);
293   /* Sanity check */
294   if (core_size > 20000)
295     return 0;
296
297   if (bfd_seek (abfd, 0L, false) < 0) return 0;
298
299   rawptr = bfd_zalloc (abfd, core_size + sizeof (struct suncordata));
300   if (rawptr == NULL) {
301     bfd_error = no_memory;
302     return 0;
303   }
304
305   core = (struct core *) (rawptr + sizeof (struct suncordata));
306
307   if ((bfd_read ((PTR) core, 1, core_size, abfd)) != core_size) {
308     bfd_error = system_call_error;
309     bfd_release (abfd, rawptr);
310     return 0;
311   }
312
313   swapcore (abfd, core);
314   set_tdata (abfd, ((struct suncordata *) rawptr));
315   core_hdr (abfd) = core;
316
317   /* create the sections.  This is raunchy, but bfd_close wants to reclaim
318      them */
319   core_stacksec (abfd) = (asection *) bfd_zalloc (abfd, sizeof (asection));
320   if (core_stacksec (abfd) == NULL) {
321   loser:
322     bfd_error = no_memory;
323     bfd_release (abfd, rawptr);
324     return 0;
325   }
326   core_datasec (abfd) = (asection *) bfd_zalloc (abfd, sizeof (asection));
327   if (core_datasec (abfd) == NULL) {
328   loser1:
329     bfd_release (abfd, core_stacksec (abfd));
330     goto loser;
331   }
332   core_regsec (abfd) = (asection *) bfd_zalloc (abfd, sizeof (asection));
333   if (core_regsec (abfd) == NULL) {
334   loser2:
335     bfd_release (abfd, core_datasec (abfd));
336     goto loser1;
337   }
338   core_reg2sec (abfd) = (asection *) bfd_zalloc (abfd, sizeof (asection));
339   if (core_reg2sec (abfd) == NULL) {
340     bfd_release (abfd, core_regsec (abfd));
341     goto loser2;
342   }
343
344   core_stacksec (abfd)->name = ".stack";
345   core_datasec (abfd)->name = ".data";
346   core_regsec (abfd)->name = ".reg";
347   core_reg2sec (abfd)->name = ".reg2";
348
349   core_stacksec (abfd)->flags = SEC_ALLOC + SEC_LOAD;
350   core_datasec (abfd)->flags = SEC_ALLOC + SEC_LOAD;
351   core_regsec (abfd)->flags = SEC_ALLOC;
352   core_reg2sec (abfd)->flags = SEC_ALLOC;
353
354   core_stacksec (abfd)->size = core->c_ssize;
355   core_datasec (abfd)->size = core->c_dsize;
356   core_regsec (abfd)->size = (sizeof core->c_regs);
357   /* Float regs take up end of struct, except c_ucode.  */
358   core_reg2sec (abfd)->size = core_size - (sizeof core->c_ucode) -
359     (file_ptr)(((struct core *)0)->fp_stuff);
360
361   core_stacksec (abfd)->vma = (USRSTACK - core->c_ssize);
362   core_datasec (abfd)->vma = N_DATADDR(core->c_aouthdr);
363   core_regsec (abfd)->vma = -1;
364   core_reg2sec (abfd)->vma = -1;
365
366   core_stacksec (abfd)->filepos = core->c_len + core->c_dsize;
367   core_datasec (abfd)->filepos = core->c_len;
368   /* In file header: */
369   core_regsec (abfd)->filepos = (file_ptr)(&((struct core *)0)->c_regs);
370   core_reg2sec (abfd)->filepos = (file_ptr)(((struct core *)0)->fp_stuff);
371
372   /* Align to word at least */
373   core_stacksec (abfd)->alignment_power = 2;
374   core_datasec (abfd)->alignment_power = 2;
375   core_regsec (abfd)->alignment_power = 2;
376   core_reg2sec (abfd)->alignment_power = 2;
377
378   abfd->sections = core_stacksec (abfd);
379   core_stacksec (abfd)->next = core_datasec (abfd);
380   core_datasec (abfd)->next = core_regsec (abfd);
381   core_regsec (abfd)->next = core_reg2sec (abfd);
382
383   abfd->section_count = 4;
384
385   return abfd->xvec;
386 }
387
388 static char *sunos4_core_file_failing_command (abfd)
389 bfd *abfd;
390   {
391   return core_hdr (abfd)->c_cmdname;
392 }
393
394 static int
395 DEFUN(sunos4_core_file_failing_signal,(abfd),
396       bfd *abfd)
397 {
398   return core_hdr (abfd)->c_signo;
399 }
400
401 static boolean
402 DEFUN(sunos4_core_file_matches_executable_p, (core_bfd, exec_bfd),
403       bfd *core_bfd AND
404       bfd *exec_bfd)
405 {
406   if (core_bfd->xvec != exec_bfd->xvec) {
407     bfd_error = system_call_error;
408     return false;
409   }
410
411   return (bcmp ((char *)&core_hdr (core_bfd), (char*) &exec_hdr (exec_bfd),
412                 sizeof (struct internal_exec)) == 0) ? true : false;
413 }
414
415 /* byte-swap core structure */
416 /* FIXME, this needs more work to swap IN a core struct from raw bytes */
417 static void
418 DEFUN(swapcore,(abfd, core),
419       bfd *abfd AND
420       struct core *core)
421 {
422   struct external_exec exec_bytes;
423   
424   core->c_magic = bfd_h_get_32 (abfd, (unsigned char *)&core->c_magic);
425   core->c_len   = bfd_h_get_32 (abfd, (unsigned char *)&core->c_len  );
426   /* Leave integer registers in target byte order.  */
427   bcopy ((char *)&(core->c_aouthdr), (char *)&exec_bytes, EXEC_BYTES_SIZE);
428   NAME(aout,swap_exec_header_in)(abfd, &exec_bytes, &core->c_aouthdr);
429   core->c_signo = bfd_h_get_32 (abfd, (unsigned char *)&core->c_signo);
430   core->c_tsize = bfd_h_get_32 (abfd, (unsigned char *)&core->c_tsize);
431   core->c_dsize = bfd_h_get_32 (abfd, (unsigned char *)&core->c_dsize);
432   core->c_ssize = bfd_h_get_32 (abfd, (unsigned char *)&core->c_ssize);
433   /* Leave FP registers in target byte order.  */
434   /* Leave "c_ucode" unswapped for now, since we can't find it easily.  */
435 }
436 \f
437 /* We use BFD generic archive files.  */
438 #define aout_32_openr_next_archived_file        bfd_generic_openr_next_archived_file
439 #define aout_32_generic_stat_arch_elt           bfd_generic_stat_arch_elt
440 #define aout_32_slurp_armap                     bfd_slurp_bsd_armap
441 #define aout_32_slurp_extended_name_table       bfd_true
442 #define aout_32_write_armap                     bsd_write_armap
443 #define aout_32_truncate_arname                 bfd_bsd_truncate_arname
444 #define aout_32_machine_type                    sunos_machine_type
445
446 #define aout_32_core_file_failing_command       sunos4_core_file_failing_command
447 #define aout_32_core_file_failing_signal        sunos4_core_file_failing_signal
448 #define aout_32_core_file_matches_executable_p  sunos4_core_file_matches_executable_p
449
450
451 #define aout_64_openr_next_archived_file        bfd_generic_openr_next_archived_file
452 #define aout_64_generic_stat_arch_elt           bfd_generic_stat_arch_elt
453 #define aout_64_slurp_armap                     bfd_slurp_bsd_armap
454 #define aout_64_slurp_extended_name_table       bfd_true
455 #define aout_64_write_armap                     bsd_write_armap
456 #define aout_64_truncate_arname                 bfd_bsd_truncate_arname
457 #define aout_64_machine_type                    sunos_machine_type
458
459 #define aout_64_core_file_failing_command       sunos4_core_file_failing_command
460 #define aout_64_core_file_failing_signal        sunos4_core_file_failing_signal
461 #define aout_64_core_file_matches_executable_p  sunos4_core_file_matches_executable_p
462
463 /* We implement these routines ourselves, rather than using the generic
464 a.out versions.  */
465 #define aout_write_object_contents      sunos4_write_object_contents
466
467 bfd_target VECNAME =
468   {
469 TARGETNAME,
470   bfd_target_aout_flavour_enum,
471   true,                         /* target byte order */
472   true,                         /* target headers byte order */
473   (HAS_RELOC | EXEC_P |         /* object flags */
474    HAS_LINENO | HAS_DEBUG |
475    HAS_SYMS | HAS_LOCALS | DYNAMIC | WP_TEXT | D_PAGED),
476    (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
477    ' ',                                                   /* ar_pad_char */
478    16,                                                    /* ar_max_namelen */
479    _do_getb64, _do_putb64, _do_getb32, _do_putb32, _do_getb16, _do_putb16, /* data */
480    _do_getb64, _do_putb64, _do_getb32, _do_putb32, _do_getb16, _do_putb16,  /* hdrs */
481    
482   {_bfd_dummy_target, NAME(sunos,object_p),
483    bfd_generic_archive_p, sunos4_core_file_p},
484   {bfd_false, NAME(aout,mkobject),
485    _bfd_generic_mkarchive, bfd_false},
486   {bfd_false, NAME(aout,sunos4_write_object_contents), /* bfd_write_contents */
487    _bfd_write_archive_contents, bfd_false},
488    
489    JUMP_TABLE(JNAME(aout))
490 };