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 /* Determine the size of a relocation entry, based on the architecture */
62 DEFUN(choose_reloc_size,(abfd),
65 switch (abfd->obj_arch) {
68 obj_reloc_entry_size (abfd) = RELOC_EXT_SIZE;
71 obj_reloc_entry_size (abfd) = RELOC_STD_SIZE;
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. */
80 sunos4_callback (abfd)
83 struct exec *execp = exec_hdr (abfd);
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);
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);
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);
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);
104 /* Determine the architecture and machine type of the object file. */
105 switch (N_MACHTYPE (*exec_hdr (abfd))) {
108 abfd->obj_arch = bfd_arch_unknown;
109 abfd->obj_machine = 0;
113 abfd->obj_arch = bfd_arch_m68k;
114 abfd->obj_machine = 68010;
118 abfd->obj_arch = bfd_arch_m68k;
119 abfd->obj_machine = 68020;
123 abfd->obj_arch = bfd_arch_sparc;
124 abfd->obj_machine = 0;
128 abfd->obj_arch = bfd_arch_i386;
129 abfd->obj_machine = 0;
133 abfd->obj_arch = bfd_arch_a29k;
134 abfd->obj_machine = 0;
138 abfd->obj_arch = bfd_arch_obscure;
139 abfd->obj_machine = 0;
143 choose_reloc_size(abfd);
149 sunos4_mkobject (abfd)
154 bfd_error = system_call_error;
156 /* Use an intermediate variable for clarity */
157 rawptr = bfd_zalloc (abfd, sizeof (struct aoutdata) + sizeof (struct exec));
159 if (rawptr == NULL) {
160 bfd_error = no_memory;
164 set_tdata (abfd, (struct aoutdata *) rawptr);
165 exec_hdr (abfd) = (struct exec *) (rawptr + sizeof (struct aoutdata));
167 /* For simplicity's sake we just make all the sections right here. */
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");
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.
183 If the architecture is understood, machine type 0 (default) should
184 always be understood. */
186 static enum machine_type
187 aout_machine_type (arch, machine)
188 enum bfd_architecture arch;
189 unsigned long machine;
191 enum machine_type arch_flags;
193 arch_flags = M_UNKNOWN;
197 if (machine == 0) arch_flags = M_SPARC;
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;
211 if (machine == 0) arch_flags = M_386;
215 if (machine == 0) arch_flags = M_29K;
219 arch_flags = M_UNKNOWN;
225 /* Write an object file in SunOS format.
226 Section contents have already been written. We write the
227 file header, symbols, and relocation. */
230 sunos4_write_object_contents (abfd)
234 unsigned char exec_bytes[EXEC_BYTES_SIZE];
235 struct exec *execp = exec_hdr (abfd);
239 execp->a_text = obj_textsec (abfd)->size;
241 /* Magic number, maestro, please! */
242 switch (bfd_get_architecture(abfd)) {
244 switch (bfd_get_machine(abfd)) {
246 N_SET_MACHTYPE(*execp, M_68010);
250 N_SET_MACHTYPE(*execp, M_68020);
255 N_SET_MACHTYPE(*execp, M_SPARC);
258 N_SET_MACHTYPE(*execp, M_386);
261 N_SET_MACHTYPE(*execp, M_29K);
264 N_SET_MACHTYPE(*execp, M_UNKNOWN);
267 choose_reloc_size(abfd);
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
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);
280 N_SET_FLAGS (*execp, 0x1); /* copied from ld.c; who the hell knows? */
282 if (abfd->flags & D_PAGED)
284 data_pad = ((obj_datasec(abfd)->size + PAGE_SIZE -1)
285 & (- PAGE_SIZE)) - obj_datasec(abfd)->size;
287 if (data_pad > obj_bsssec(abfd)->size)
290 execp->a_bss = obj_bsssec(abfd)->size - data_pad;
291 execp->a_data = obj_datasec(abfd)->size + data_pad;
295 execp->a_data = obj_datasec (abfd)->size;
296 execp->a_bss = obj_bsssec (abfd)->size;
299 execp->a_syms = bfd_get_symcount (abfd) * sizeof (struct nlist);
300 execp->a_entry = bfd_get_start_address (abfd);
305 execp->a_trsize = ((obj_textsec (abfd)->reloc_count) *
306 obj_reloc_entry_size (abfd));
308 execp->a_drsize = ((obj_datasec (abfd)->reloc_count) *
309 obj_reloc_entry_size (abfd));
311 bfd_aout_swap_exec_header_out (abfd, execp, exec_bytes);
313 bfd_seek (abfd, 0L, false);
314 bfd_write ((PTR) exec_bytes, 1, EXEC_BYTES_SIZE, abfd);
316 /* Now write out reloc info, followed by syms and strings */
318 if (bfd_get_symcount (abfd) != 0)
321 (long)(N_SYMOFF(*execp)), false);
323 aout_write_syms (abfd);
325 bfd_seek (abfd, (long)(N_TRELOFF(*execp)), false);
327 if (!aout_squirt_out_relocs (abfd, obj_textsec (abfd))) return false;
328 bfd_seek (abfd, (long)(N_DRELOFF(*execp)), false);
330 if (!aout_squirt_out_relocs (abfd, obj_datasec (abfd))) return false;
337 #define CORE_MAGIC 0x080456
338 #define CORE_NAMELEN 16
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. */
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
371 /* Taken from Sun documentation: */
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! */
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.) */
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))
400 PROTO (static void, swapcore, (bfd *abfd, struct core *core));
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)
409 /* These are stored in the bfd's tdata */
411 struct core *hdr; /* core file header */
412 asection *data_section;
413 asection *stack_section;
414 asection *reg_section;
415 asection *reg2_section;
419 sunos4_core_file_p (abfd)
422 unsigned char longbuf[4]; /* Raw bytes of various header fields */
428 bfd_error = system_call_error;
430 if (bfd_read ((PTR)longbuf, 1, sizeof (longbuf), abfd) !=
433 core_mag = bfd_h_getlong (abfd, longbuf);
435 if (core_mag != CORE_MAGIC) return 0;
437 /* SunOS core headers can vary in length; second word is size; */
438 if (bfd_read ((PTR)longbuf, 1, sizeof (longbuf), abfd) !=
441 core_size = bfd_h_getlong (abfd, longbuf);
443 if (core_size > 20000)
446 if (bfd_seek (abfd, 0L, false) < 0) return 0;
448 rawptr = bfd_zalloc (abfd, core_size + sizeof (struct suncordata));
449 if (rawptr == NULL) {
450 bfd_error = no_memory;
454 core = (struct core *) (rawptr + sizeof (struct suncordata));
456 if ((bfd_read ((PTR) core, 1, core_size, abfd)) != core_size) {
457 bfd_error = system_call_error;
458 bfd_release (abfd, rawptr);
462 swapcore (abfd, core);
463 set_tdata (abfd, ((struct suncordata *) rawptr));
464 core_hdr (abfd) = core;
466 /* create the sections. This is raunchy, but bfd_close wants to reclaim
468 core_stacksec (abfd) = (asection *) bfd_zalloc (abfd, sizeof (asection));
469 if (core_stacksec (abfd) == NULL) {
471 bfd_error = no_memory;
472 bfd_release (abfd, rawptr);
475 core_datasec (abfd) = (asection *) bfd_zalloc (abfd, sizeof (asection));
476 if (core_datasec (abfd) == NULL) {
478 bfd_release (abfd, core_stacksec (abfd));
481 core_regsec (abfd) = (asection *) bfd_zalloc (abfd, sizeof (asection));
482 if (core_regsec (abfd) == NULL) {
484 bfd_release (abfd, core_datasec (abfd));
487 core_reg2sec (abfd) = (asection *) bfd_zalloc (abfd, sizeof (asection));
488 if (core_reg2sec (abfd) == NULL) {
489 bfd_release (abfd, core_regsec (abfd));
493 core_stacksec (abfd)->name = ".stack";
494 core_datasec (abfd)->name = ".data";
495 core_regsec (abfd)->name = ".reg";
496 core_reg2sec (abfd)->name = ".reg2";
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;
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);
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;
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);
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;
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);
532 abfd->section_count = 4;
538 sunos4_core_file_failing_command (abfd)
541 return core_hdr (abfd)->c_cmdname;
545 sunos4_core_file_failing_signal (abfd)
548 return core_hdr (abfd)->c_signo;
552 sunos4_core_file_matches_executable_p (core_bfd, exec_bfd)
553 bfd *core_bfd, *exec_bfd;
555 if (core_bfd->xvec != exec_bfd->xvec) {
556 bfd_error = system_call_error;
560 return (bcmp ((char *)&core_hdr (core_bfd), (char*) &exec_hdr (exec_bfd),
561 sizeof (struct exec)) == 0) ? true : false;
564 /* byte-swap core structure */
565 /* FIXME, this needs more work to swap IN a core struct from raw bytes */
567 swapcore (abfd, core)
571 unsigned char exec_bytes[EXEC_BYTES_SIZE];
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. */
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
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
600 /* We implement these routines ourselves, rather than using the generic
602 #define aout_write_object_contents sunos4_write_object_contents
604 bfd_target sunos_big_vec =
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 */
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},