1 /* BFD backend for sunos binaries */
3 /* Copyright (C) 1990, 1991 Free Software Foundation, Inc.
5 This file is part of BFD, the Binary File Diddler.
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)
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.
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. */
28 #include "a.out.sun4.h"
29 #include "a.out.gnu.h"
32 #include "liba.out.h" /* BFD a.out internal data structures */
34 void (*bfd_error_trap)();
36 static bfd_target *sunos4_callback ();
42 sunos4_object_p (abfd)
45 unsigned char magicbuf[4]; /* Raw bytes of magic number from file */
46 unsigned long magic; /* Swapped magic number */
48 bfd_error = system_call_error;
50 if (bfd_read ((PTR)magicbuf, 1, sizeof (magicbuf), abfd) !=
53 magic = bfd_h_getlong (abfd, magicbuf);
55 if (N_BADMAG (*((struct exec *) &magic))) return 0;
57 return some_aout_object_p (abfd, sunos4_callback);
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. */
64 sunos4_callback (abfd)
67 struct exec *execp = exec_hdr (abfd);
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);
74 /* The file offsets of the sections */
75 obj_textsec (abfd)->filepos = N_TXTOFF(*execp);
76 obj_datasec (abfd)->filepos = N_DATOFF(*execp);
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);
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);
86 /* Determine the architecture and machine type of the object file. */
87 switch (N_MACHTYPE (*exec_hdr (abfd))) {
90 abfd->obj_arch = bfd_arch_unknown;
91 abfd->obj_machine = 0;
95 abfd->obj_arch = bfd_arch_m68k;
96 abfd->obj_machine = 68010;
100 abfd->obj_arch = bfd_arch_m68k;
101 abfd->obj_machine = 68020;
105 abfd->obj_arch = bfd_arch_sparc;
106 abfd->obj_machine = 0;
110 abfd->obj_arch = bfd_arch_i386;
111 abfd->obj_machine = 0;
115 abfd->obj_arch = bfd_arch_a29k;
116 abfd->obj_machine = 0;
120 abfd->obj_arch = bfd_arch_obscure;
121 abfd->obj_machine = 0;
125 /* Determine the size of a relocation entry, based on the architecture */
126 switch (abfd->obj_arch) {
129 obj_reloc_entry_size (abfd) = RELOC_EXT_SIZE;
131 obj_reloc_entry_size (abfd) = RELOC_STD_SIZE;
138 sunos4_mkobject (abfd)
143 bfd_error = system_call_error;
145 /* Use an intermediate variable for clarity */
146 rawptr = bfd_zalloc (abfd, sizeof (struct aoutdata) + sizeof (struct exec));
148 if (rawptr == NULL) {
149 bfd_error = no_memory;
153 set_tdata (abfd, (struct aoutdata *) rawptr);
154 exec_hdr (abfd) = (struct exec *) (rawptr + sizeof (struct aoutdata));
156 /* For simplicity's sake we just make all the sections right here. */
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");
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.
172 If the architecture is understood, machine type 0 (default) should
173 always be understood. */
175 static enum machine_type
176 aout_machine_type (arch, machine)
177 enum bfd_architecture arch;
178 unsigned long machine;
180 enum machine_type arch_flags;
182 arch_flags = M_UNKNOWN;
186 if (machine == 0) arch_flags = M_SPARC;
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;
200 if (machine == 0) arch_flags = M_386;
204 if (machine == 0) arch_flags = M_29K;
208 arch_flags = M_UNKNOWN;
214 /* Write an object file in SunOS format.
215 Section contents have already been written. We write the
216 file header, symbols, and relocation. */
219 sunos4_write_object_contents (abfd)
223 unsigned char exec_bytes[EXEC_BYTES_SIZE];
224 struct exec *execp = exec_hdr (abfd);
226 execp->a_text = obj_textsec (abfd)->size;
228 /* Magic number, maestro, please! */
229 switch (bfd_get_architecture(abfd)) {
231 switch (bfd_get_machine(abfd)) {
233 N_SET_MACHTYPE(*execp, M_68010);
237 N_SET_MACHTYPE(*execp, M_68020);
242 N_SET_MACHTYPE(*execp, M_SPARC);
245 N_SET_MACHTYPE(*execp, M_386);
248 N_SET_MACHTYPE(*execp, M_29K);
251 N_SET_MACHTYPE(*execp, M_UNKNOWN);
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
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);
263 N_SET_FLAGS (*execp, 0x1); /* copied from ld.c; who the hell knows? */
265 if (abfd->flags & D_PAGED)
267 data_pad = ((obj_datasec(abfd)->size + PAGE_SIZE -1)
268 & (- PAGE_SIZE)) - obj_datasec(abfd)->size;
270 if (data_pad > obj_bsssec(abfd)->size)
273 execp->a_bss = obj_bsssec(abfd)->size - data_pad;
274 execp->a_data = obj_datasec(abfd)->size + data_pad;
278 execp->a_data = obj_datasec (abfd)->size;
279 execp->a_bss = obj_bsssec (abfd)->size;
282 execp->a_syms = bfd_get_symcount (abfd) * sizeof (struct nlist);
283 execp->a_entry = bfd_get_start_address (abfd);
285 execp->a_trsize = ((obj_textsec (abfd)->reloc_count) *
286 obj_reloc_entry_size (abfd));
288 execp->a_drsize = ((obj_datasec (abfd)->reloc_count) *
289 obj_reloc_entry_size (abfd));
291 bfd_aout_swap_exec_header_out (abfd, execp, exec_bytes);
293 bfd_seek (abfd, 0L, false);
294 bfd_write ((PTR) exec_bytes, 1, EXEC_BYTES_SIZE, abfd);
296 /* Now write out reloc info, followed by syms and strings */
298 if (bfd_get_symcount (abfd) != 0)
301 (long)(N_SYMOFF(*execp)), false);
303 aout_write_syms (abfd);
305 bfd_seek (abfd, (long)(N_TRELOFF(*execp)), false);
307 if (!aout_squirt_out_relocs (abfd, obj_textsec (abfd))) return false;
308 bfd_seek (abfd, (long)(N_DRELOFF(*execp)), false);
310 if (!aout_squirt_out_relocs (abfd, obj_datasec (abfd))) return false;
317 #define CORE_MAGIC 0x080456
318 #define CORE_NAMELEN 16
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. */
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
351 /* Taken from Sun documentation: */
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! */
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.) */
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))
380 PROTO (static void, swapcore, (bfd *abfd, struct core *core));
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)
389 /* These are stored in the bfd's tdata */
391 struct core *hdr; /* core file header */
392 asection *data_section;
393 asection *stack_section;
394 asection *reg_section;
395 asection *reg2_section;
399 sunos4_core_file_p (abfd)
402 unsigned char longbuf[4]; /* Raw bytes of various header fields */
408 bfd_error = system_call_error;
410 if (bfd_read ((PTR)longbuf, 1, sizeof (longbuf), abfd) !=
413 core_mag = bfd_h_getlong (abfd, longbuf);
415 if (core_mag != CORE_MAGIC) return 0;
417 /* SunOS core headers can vary in length; second word is size; */
418 if (bfd_read ((PTR)longbuf, 1, sizeof (longbuf), abfd) !=
421 core_size = bfd_h_getlong (abfd, longbuf);
423 if (core_size > 20000)
426 if (bfd_seek (abfd, 0L, false) < 0) return 0;
428 rawptr = bfd_zalloc (abfd, core_size + sizeof (struct suncordata));
429 if (rawptr == NULL) {
430 bfd_error = no_memory;
434 core = (struct core *) (rawptr + sizeof (struct suncordata));
436 if ((bfd_read ((PTR) core, 1, core_size, abfd)) != core_size) {
437 bfd_error = system_call_error;
438 bfd_release (abfd, rawptr);
442 swapcore (abfd, core);
443 set_tdata (abfd, ((struct suncordata *) rawptr));
444 core_hdr (abfd) = core;
446 /* create the sections. This is raunchy, but bfd_close wants to reclaim
448 core_stacksec (abfd) = (asection *) bfd_zalloc (abfd, sizeof (asection));
449 if (core_stacksec (abfd) == NULL) {
451 bfd_error = no_memory;
452 bfd_release (abfd, rawptr);
455 core_datasec (abfd) = (asection *) bfd_zalloc (abfd, sizeof (asection));
456 if (core_datasec (abfd) == NULL) {
458 bfd_release (abfd, core_stacksec (abfd));
461 core_regsec (abfd) = (asection *) bfd_zalloc (abfd, sizeof (asection));
462 if (core_regsec (abfd) == NULL) {
464 bfd_release (abfd, core_datasec (abfd));
467 core_reg2sec (abfd) = (asection *) bfd_zalloc (abfd, sizeof (asection));
468 if (core_reg2sec (abfd) == NULL) {
469 bfd_release (abfd, core_regsec (abfd));
473 core_stacksec (abfd)->name = ".stack";
474 core_datasec (abfd)->name = ".data";
475 core_regsec (abfd)->name = ".reg";
476 core_reg2sec (abfd)->name = ".reg2";
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;
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);
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;
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);
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;
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);
512 abfd->section_count = 4;
518 sunos4_core_file_failing_command (abfd)
521 return core_hdr (abfd)->c_cmdname;
525 sunos4_core_file_failing_signal (abfd)
528 return core_hdr (abfd)->c_signo;
532 sunos4_core_file_matches_executable_p (core_bfd, exec_bfd)
533 bfd *core_bfd, *exec_bfd;
535 if (core_bfd->xvec != exec_bfd->xvec) {
536 bfd_error = system_call_error;
540 return (bcmp ((char *)&core_hdr (core_bfd), (char*) &exec_hdr (exec_bfd),
541 sizeof (struct exec)) == 0) ? true : false;
544 /* byte-swap core structure */
545 /* FIXME, this needs more work to swap IN a core struct from raw bytes */
547 swapcore (abfd, core)
551 unsigned char exec_bytes[EXEC_BYTES_SIZE];
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. */
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
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
580 /* We implement these routines ourselves, rather than using the generic
582 #define aout_write_object_contents sunos4_write_object_contents
584 bfd_target sunos_big_vec =
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 */
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},