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
274 /* Also the size has already had the sizeof the header taken into
275 account. It may be wrong for the application to have to do this
276 (though this is what sizeof_headers is for), but it's the way
277 it is, so that's the way it will stay for the moment.*/
278 execp->a_text = obj_textsec (abfd)->size ; /*+ sizeof(struct exec);*/
279 N_SET_MAGIC (*execp, ZMAGIC);
280 } else if (abfd->flags & WP_TEXT) {
281 N_SET_MAGIC (*execp, NMAGIC);
283 N_SET_FLAGS (*execp, 0x1); /* copied from ld.c; who the hell knows? */
285 if (abfd->flags & D_PAGED)
287 data_pad = ((obj_datasec(abfd)->size + PAGE_SIZE -1)
288 & (- PAGE_SIZE)) - obj_datasec(abfd)->size;
290 if (data_pad > obj_bsssec(abfd)->size)
293 execp->a_bss = obj_bsssec(abfd)->size - data_pad;
294 execp->a_data = obj_datasec(abfd)->size + data_pad;
298 execp->a_data = obj_datasec (abfd)->size;
299 execp->a_bss = obj_bsssec (abfd)->size;
302 execp->a_syms = bfd_get_symcount (abfd) * sizeof (struct nlist);
303 execp->a_entry = bfd_get_start_address (abfd);
308 execp->a_trsize = ((obj_textsec (abfd)->reloc_count) *
309 obj_reloc_entry_size (abfd));
311 execp->a_drsize = ((obj_datasec (abfd)->reloc_count) *
312 obj_reloc_entry_size (abfd));
314 bfd_aout_swap_exec_header_out (abfd, execp, exec_bytes);
316 bfd_seek (abfd, 0L, false);
317 bfd_write ((PTR) exec_bytes, 1, EXEC_BYTES_SIZE, abfd);
319 /* Now write out reloc info, followed by syms and strings */
321 if (bfd_get_symcount (abfd) != 0)
324 (long)(N_SYMOFF(*execp)), false);
326 aout_write_syms (abfd);
328 bfd_seek (abfd, (long)(N_TRELOFF(*execp)), false);
330 if (!aout_squirt_out_relocs (abfd, obj_textsec (abfd))) return false;
331 bfd_seek (abfd, (long)(N_DRELOFF(*execp)), false);
333 if (!aout_squirt_out_relocs (abfd, obj_datasec (abfd))) return false;
340 #define CORE_MAGIC 0x080456
341 #define CORE_NAMELEN 16
343 /* The core structure is taken from the Sun documentation.
344 Unfortunately, they don't document the FPA structure, or at least I
345 can't find it easily. Fortunately the core header contains its own
346 length. So this shouldn't cause problems, except for c_ucode, which
347 so far we don't use but is easy to find with a little arithmetic. */
349 /* But the reg structure can be gotten from the SPARC processor handbook.
350 This really should be in a GNU include file though so that gdb can use
374 /* Taken from Sun documentation: */
376 /* FIXME: It's worse than we expect. This struct contains TWO substructs
377 neither of whose size we know, WITH STUFF IN BETWEEN THEM! We can't
378 even portably access the stuff in between! */
381 int c_magic; /* Corefile magic number */
382 int c_len; /* Sizeof (struct core) */
383 struct regs c_regs; /* General purpose registers -- MACHDEP SIZE */
384 struct exec c_aouthdr; /* A.out header */
385 int c_signo; /* Killing signal, if any */
386 int c_tsize; /* Text size (bytes) */
387 int c_dsize; /* Data size (bytes) */
388 int c_ssize; /* Stack size (bytes) */
389 char c_cmdname[CORE_NAMELEN + 1]; /* Command name */
390 double fp_stuff[1]; /* external FPU state (size unknown by us) */
391 /* The type "double" is critical here, for alignment.
392 SunOS declares a struct here, but the struct's alignment
393 is double since it contains doubles. */
394 int c_ucode; /* Exception no. from u_code */
395 /* (this member is not accessible by name since we don't
396 portably know the size of fp_stuff.) */
399 /* Supposedly the user stack grows downward from the bottom of kernel memory.
400 Presuming that this remains true, this definition will work. */
401 #define USRSTACK (-(128*1024*1024))
403 PROTO (static void, swapcore, (bfd *abfd, struct core *core));
405 /* need this cast b/c ptr is really void * */
406 #define core_hdr(bfd) (((struct suncordata *) (bfd->tdata))->hdr)
407 #define core_datasec(bfd) (((struct suncordata *) ((bfd)->tdata))->data_section)
408 #define core_stacksec(bfd) (((struct suncordata*)((bfd)->tdata))->stack_section)
409 #define core_regsec(bfd) (((struct suncordata *) ((bfd)->tdata))->reg_section)
410 #define core_reg2sec(bfd) (((struct suncordata *) ((bfd)->tdata))->reg2_section)
412 /* These are stored in the bfd's tdata */
414 struct core *hdr; /* core file header */
415 asection *data_section;
416 asection *stack_section;
417 asection *reg_section;
418 asection *reg2_section;
422 sunos4_core_file_p (abfd)
425 unsigned char longbuf[4]; /* Raw bytes of various header fields */
431 bfd_error = system_call_error;
433 if (bfd_read ((PTR)longbuf, 1, sizeof (longbuf), abfd) !=
436 core_mag = bfd_h_getlong (abfd, longbuf);
438 if (core_mag != CORE_MAGIC) return 0;
440 /* SunOS core headers can vary in length; second word is size; */
441 if (bfd_read ((PTR)longbuf, 1, sizeof (longbuf), abfd) !=
444 core_size = bfd_h_getlong (abfd, longbuf);
446 if (core_size > 20000)
449 if (bfd_seek (abfd, 0L, false) < 0) return 0;
451 rawptr = bfd_zalloc (abfd, core_size + sizeof (struct suncordata));
452 if (rawptr == NULL) {
453 bfd_error = no_memory;
457 core = (struct core *) (rawptr + sizeof (struct suncordata));
459 if ((bfd_read ((PTR) core, 1, core_size, abfd)) != core_size) {
460 bfd_error = system_call_error;
461 bfd_release (abfd, rawptr);
465 swapcore (abfd, core);
466 set_tdata (abfd, ((struct suncordata *) rawptr));
467 core_hdr (abfd) = core;
469 /* create the sections. This is raunchy, but bfd_close wants to reclaim
471 core_stacksec (abfd) = (asection *) bfd_zalloc (abfd, sizeof (asection));
472 if (core_stacksec (abfd) == NULL) {
474 bfd_error = no_memory;
475 bfd_release (abfd, rawptr);
478 core_datasec (abfd) = (asection *) bfd_zalloc (abfd, sizeof (asection));
479 if (core_datasec (abfd) == NULL) {
481 bfd_release (abfd, core_stacksec (abfd));
484 core_regsec (abfd) = (asection *) bfd_zalloc (abfd, sizeof (asection));
485 if (core_regsec (abfd) == NULL) {
487 bfd_release (abfd, core_datasec (abfd));
490 core_reg2sec (abfd) = (asection *) bfd_zalloc (abfd, sizeof (asection));
491 if (core_reg2sec (abfd) == NULL) {
492 bfd_release (abfd, core_regsec (abfd));
496 core_stacksec (abfd)->name = ".stack";
497 core_datasec (abfd)->name = ".data";
498 core_regsec (abfd)->name = ".reg";
499 core_reg2sec (abfd)->name = ".reg2";
501 core_stacksec (abfd)->flags = SEC_ALLOC + SEC_LOAD;
502 core_datasec (abfd)->flags = SEC_ALLOC + SEC_LOAD;
503 core_regsec (abfd)->flags = SEC_ALLOC;
504 core_reg2sec (abfd)->flags = SEC_ALLOC;
506 core_stacksec (abfd)->size = core->c_ssize;
507 core_datasec (abfd)->size = core->c_dsize;
508 core_regsec (abfd)->size = (sizeof core->c_regs);
509 /* Float regs take up end of struct, except c_ucode. */
510 core_reg2sec (abfd)->size = core_size - (sizeof core->c_ucode) -
511 (file_ptr)(((struct core *)0)->fp_stuff);
513 core_stacksec (abfd)->vma = (USRSTACK - core->c_ssize);
514 core_datasec (abfd)->vma = N_DATADDR(core->c_aouthdr);
515 core_regsec (abfd)->vma = -1;
516 core_reg2sec (abfd)->vma = -1;
518 core_stacksec (abfd)->filepos = core->c_len + core->c_dsize;
519 core_datasec (abfd)->filepos = core->c_len;
520 /* In file header: */
521 core_regsec (abfd)->filepos = (file_ptr)(&((struct core *)0)->c_regs);
522 core_reg2sec (abfd)->filepos = (file_ptr)(((struct core *)0)->fp_stuff);
524 /* Align to word at least */
525 core_stacksec (abfd)->alignment_power = 2;
526 core_datasec (abfd)->alignment_power = 2;
527 core_regsec (abfd)->alignment_power = 2;
528 core_reg2sec (abfd)->alignment_power = 2;
530 abfd->sections = core_stacksec (abfd);
531 core_stacksec (abfd)->next = core_datasec (abfd);
532 core_datasec (abfd)->next = core_regsec (abfd);
533 core_regsec (abfd)->next = core_reg2sec (abfd);
535 abfd->section_count = 4;
541 sunos4_core_file_failing_command (abfd)
544 return core_hdr (abfd)->c_cmdname;
548 sunos4_core_file_failing_signal (abfd)
551 return core_hdr (abfd)->c_signo;
555 sunos4_core_file_matches_executable_p (core_bfd, exec_bfd)
556 bfd *core_bfd, *exec_bfd;
558 if (core_bfd->xvec != exec_bfd->xvec) {
559 bfd_error = system_call_error;
563 return (bcmp ((char *)&core_hdr (core_bfd), (char*) &exec_hdr (exec_bfd),
564 sizeof (struct exec)) == 0) ? true : false;
567 /* byte-swap core structure */
568 /* FIXME, this needs more work to swap IN a core struct from raw bytes */
570 swapcore (abfd, core)
574 unsigned char exec_bytes[EXEC_BYTES_SIZE];
576 core->c_magic = bfd_h_getlong (abfd, (unsigned char *)&core->c_magic);
577 core->c_len = bfd_h_getlong (abfd, (unsigned char *)&core->c_len );
578 /* Leave integer registers in target byte order. */
579 bcopy ((char *)&(core->c_aouthdr), (char *)exec_bytes, EXEC_BYTES_SIZE);
580 bfd_aout_swap_exec_header_in (abfd, exec_bytes, &core->c_aouthdr);
581 core->c_signo = bfd_h_getlong (abfd, (unsigned char *)&core->c_signo);
582 core->c_tsize = bfd_h_getlong (abfd, (unsigned char *)&core->c_tsize);
583 core->c_dsize = bfd_h_getlong (abfd, (unsigned char *)&core->c_dsize);
584 core->c_ssize = bfd_h_getlong (abfd, (unsigned char *)&core->c_ssize);
585 /* Leave FP registers in target byte order. */
586 /* Leave "c_ucode" unswapped for now, since we can't find it easily. */
589 /* We use BFD generic archive files. */
590 #define aout_openr_next_archived_file bfd_generic_openr_next_archived_file
591 #define aout_generic_stat_arch_elt bfd_generic_stat_arch_elt
592 #define aout_slurp_armap bfd_slurp_bsd_armap
593 #define aout_slurp_extended_name_table bfd_true
594 #define aout_write_armap bsd_write_armap
595 #define aout_truncate_arname bfd_bsd_truncate_arname
597 /* We use our own core file format. */
598 #define aout_core_file_failing_command sunos4_core_file_failing_command
599 #define aout_core_file_failing_signal sunos4_core_file_failing_signal
600 #define aout_core_file_matches_executable_p \
601 sunos4_core_file_matches_executable_p
603 /* We implement these routines ourselves, rather than using the generic
605 #define aout_write_object_contents sunos4_write_object_contents
607 bfd_target sunos_big_vec =
609 "a.out-sunos-big", /* name */
610 bfd_target_aout_flavour_enum,
611 true, /* target byte order */
612 true, /* target headers byte order */
613 (HAS_RELOC | EXEC_P | /* object flags */
614 HAS_LINENO | HAS_DEBUG |
615 HAS_SYMS | HAS_LOCALS | DYNAMIC | WP_TEXT | D_PAGED),
616 (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
617 ' ', /* ar_pad_char */
618 16, /* ar_max_namelen */
619 _do_getblong, _do_putblong, _do_getbshort, _do_putbshort, /* data */
620 _do_getblong, _do_putblong, _do_getbshort, _do_putbshort, /* hdrs */
622 {_bfd_dummy_target, sunos4_object_p,
623 bfd_generic_archive_p, sunos4_core_file_p},
624 {bfd_false, sunos4_mkobject,
625 _bfd_generic_mkarchive, bfd_false},
626 {bfd_false, sunos4_write_object_contents, /* bfd_write_contents */
627 _bfd_write_archive_contents, bfd_false},