diff options
author | Steve Chamberlain <steve@cygnus> | 1991-05-21 00:14:16 +0000 |
---|---|---|
committer | Steve Chamberlain <steve@cygnus> | 1991-05-21 00:14:16 +0000 |
commit | 7ed4093abcbe329e94888b6ed1c0ead5bea4e7bf (patch) | |
tree | 52f735fbb18dd4bd2711f0b7b1c8f5b8555e336f /bfd/aoutf1.h | |
parent | fc5d60745615a903d4a149fc5753ea54d3606597 (diff) | |
download | gdb-7ed4093abcbe329e94888b6ed1c0ead5bea4e7bf.zip gdb-7ed4093abcbe329e94888b6ed1c0ead5bea4e7bf.tar.gz gdb-7ed4093abcbe329e94888b6ed1c0ead5bea4e7bf.tar.bz2 |
*** empty log message ***
Diffstat (limited to 'bfd/aoutf1.h')
-rw-r--r-- | bfd/aoutf1.h | 490 |
1 files changed, 490 insertions, 0 deletions
diff --git a/bfd/aoutf1.h b/bfd/aoutf1.h new file mode 100644 index 0000000..197d7c7 --- /dev/null +++ b/bfd/aoutf1.h @@ -0,0 +1,490 @@ +/* BFD backend for generic a.out flavour 1 */ + +/* Copyright (C) 1990, 1991 Free Software Foundation, Inc. + +This file is part of BFD, the Binary File Diddler. + +BFD is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 1, or (at your option) +any later version. + +BFD is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with BFD; see the file COPYING. If not, write to +the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ + +#include <ansidecl.h> +#include <sysdep.h> +struct external_exec; +#include <a.out.sun4.h> +#include "bfd.h" +#include "liba.out.h" +#include "libbfd.h" + + + +#include "aout64.h" +#include "stab.gnu.h" +#include "ar.h" + + + +void (*bfd_error_trap)(); + +static bfd_target *sunos4_callback (); + +/*SUPPRESS558*/ +/*SUPPRESS529*/ + +bfd_target * +DEFUN(NAME(sunos,object_p), (abfd), + bfd *abfd) +{ + unsigned char magicbuf[4]; /* Raw bytes of magic number from file */ + unsigned long magic; /* Swapped magic number */ + + bfd_error = system_call_error; + + if (bfd_read ((PTR)magicbuf, 1 , 4, abfd) != + sizeof (magicbuf)) + return 0; + magic = bfd_h_get_32 (abfd, magicbuf); + + if (N_BADMAG (*((struct internal_exec *) &magic))) return 0; + + return NAME(aout,some_aout_object_p) (abfd, sunos4_callback); +} + + /* Determine the size of a relocation entry, based on the architecture */ +static void +DEFUN(choose_reloc_size,(abfd), +bfd *abfd) + { + switch (abfd->obj_arch) { + case bfd_arch_sparc: + case bfd_arch_a29k: + obj_reloc_entry_size (abfd) = RELOC_EXT_SIZE; + break; + default: + obj_reloc_entry_size (abfd) = RELOC_STD_SIZE; + break; + } + } + +/* Set parameters about this a.out file that are machine-dependent. + This routine is called from some_aout_object_p just before it returns. */ + +static bfd_target * +sunos4_callback (abfd) + bfd *abfd; +{ + struct internal_exec *execp = exec_hdr (abfd); + + WORK_OUT_FILE_POSITIONS(abfd, execp); + /* Determine the architecture and machine type of the object file. */ + switch (N_MACHTYPE (*exec_hdr (abfd))) { + + case M_UNKNOWN: + abfd->obj_arch = bfd_arch_unknown; + abfd->obj_machine = 0; + break; + + case M_68010: + abfd->obj_arch = bfd_arch_m68k; + abfd->obj_machine = 68010; + break; + + case M_68020: + abfd->obj_arch = bfd_arch_m68k; + abfd->obj_machine = 68020; + break; + + case M_SPARC: + abfd->obj_arch = bfd_arch_sparc; + abfd->obj_machine = 0; + break; + + case M_386: + abfd->obj_arch = bfd_arch_i386; + abfd->obj_machine = 0; + break; + + case M_29K: + abfd->obj_arch = bfd_arch_a29k; + abfd->obj_machine = 0; + break; + + default: + abfd->obj_arch = bfd_arch_obscure; + abfd->obj_machine = 0; + break; + } + + choose_reloc_size(abfd); + return abfd->xvec; +} + + +/* Write an object file in SunOS format. +Section contents have already been written. We write the +file header, symbols, and relocation. */ + +boolean +DEFUN(NAME(aout,sunos4_write_object_contents),(abfd), + bfd *abfd) + + { + bfd_size_type data_pad = 0; + struct external_exec exec_bytes; + struct internal_exec *execp = exec_hdr (abfd); + + + + execp->a_text = obj_textsec (abfd)->size; + + /* Magic number, maestro, please! */ + switch (bfd_get_architecture(abfd)) { + case bfd_arch_m68k: + switch (bfd_get_machine(abfd)) { + case 68010: + N_SET_MACHTYPE(*execp, M_68010); + break; + default: + case 68020: + N_SET_MACHTYPE(*execp, M_68020); + break; + } + break; + case bfd_arch_sparc: + N_SET_MACHTYPE(*execp, M_SPARC); + break; + case bfd_arch_i386: + N_SET_MACHTYPE(*execp, M_386); + break; + case bfd_arch_a29k: + N_SET_MACHTYPE(*execp, M_29K); + break; + default: + N_SET_MACHTYPE(*execp, M_UNKNOWN); + } + + choose_reloc_size(abfd); + + /* FIXME */ + N_SET_FLAGS (*execp, 0x81); + + WRITE_HEADERS(abfd, execp); + + return true; +} + +/* core files */ + +#define CORE_MAGIC 0x080456 +#define CORE_NAMELEN 16 + +/* The core structure is taken from the Sun documentation. +Unfortunately, they don't document the FPA structure, or at least I +can't find it easily. Fortunately the core header contains its own +length. So this shouldn't cause problems, except for c_ucode, which +so far we don't use but is easy to find with a little arithmetic. */ + +/* But the reg structure can be gotten from the SPARC processor handbook. +This really should be in a GNU include file though so that gdb can use +the same info. */ +struct regs { + int r_psr; + int r_pc; + int r_npc; + int r_y; + int r_g1; + int r_g2; + int r_g3; + int r_g4; + int r_g5; + int r_g6; + int r_g7; + int r_o0; + int r_o1; + int r_o2; + int r_o3; + int r_o4; + int r_o5; + int r_o6; + int r_o7; +}; + +/* Taken from Sun documentation: */ + +/* FIXME: It's worse than we expect. This struct contains TWO substructs +neither of whose size we know, WITH STUFF IN BETWEEN THEM! We can't +even portably access the stuff in between! */ + +struct core { + int c_magic; /* Corefile magic number */ + int c_len; /* Sizeof (struct core) */ + struct regs c_regs; /* General purpose registers -- MACHDEP SIZE */ + struct internal_exec c_aouthdr; /* A.out header */ + int c_signo; /* Killing signal, if any */ + int c_tsize; /* Text size (bytes) */ + int c_dsize; /* Data size (bytes) */ + int c_ssize; /* Stack size (bytes) */ + char c_cmdname[CORE_NAMELEN + 1]; /* Command name */ + double fp_stuff[1]; /* external FPU state (size unknown by us) */ + /* The type "double" is critical here, for alignment. + SunOS declares a struct here, but the struct's alignment + is double since it contains doubles. */ + int c_ucode; /* Exception no. from u_code */ + /* (this member is not accessible by name since we don't + portably know the size of fp_stuff.) */ +}; + +/* Supposedly the user stack grows downward from the bottom of kernel memory. +Presuming that this remains true, this definition will work. */ +#define USRSTACK (-(128*1024*1024)) + +PROTO (static void, swapcore, (bfd *abfd, struct core *core)); + +/* need this cast b/c ptr is really void * */ +#define core_hdr(bfd) (((struct suncordata *) (bfd->tdata))->hdr) +#define core_datasec(bfd) (((struct suncordata *) ((bfd)->tdata))->data_section) +#define core_stacksec(bfd) (((struct suncordata*)((bfd)->tdata))->stack_section) +#define core_regsec(bfd) (((struct suncordata *) ((bfd)->tdata))->reg_section) +#define core_reg2sec(bfd) (((struct suncordata *) ((bfd)->tdata))->reg2_section) + +/* These are stored in the bfd's tdata */ +struct suncordata { +struct core *hdr; /* core file header */ +asection *data_section; +asection *stack_section; +asection *reg_section; +asection *reg2_section; +}; + +static bfd_target * +DEFUN(sunos4_core_file_p,(abfd), + bfd *abfd) +{ + unsigned char longbuf[4]; /* Raw bytes of various header fields */ + int core_size; + int core_mag; + struct core *core; + char *rawptr; + + bfd_error = system_call_error; + + if (bfd_read ((PTR)longbuf, 1, sizeof (longbuf), abfd) != + sizeof (longbuf)) + return 0; + core_mag = bfd_h_get_32 (abfd, longbuf); + + if (core_mag != CORE_MAGIC) return 0; + + /* SunOS core headers can vary in length; second word is size; */ + if (bfd_read ((PTR)longbuf, 1, sizeof (longbuf), abfd) != + sizeof (longbuf)) + return 0; + core_size = bfd_h_get_32 (abfd, longbuf); + /* Sanity check */ + if (core_size > 20000) + return 0; + + if (bfd_seek (abfd, 0L, false) < 0) return 0; + + rawptr = bfd_zalloc (abfd, core_size + sizeof (struct suncordata)); + if (rawptr == NULL) { + bfd_error = no_memory; + return 0; + } + + core = (struct core *) (rawptr + sizeof (struct suncordata)); + + if ((bfd_read ((PTR) core, 1, core_size, abfd)) != core_size) { + bfd_error = system_call_error; + bfd_release (abfd, rawptr); + return 0; + } + + swapcore (abfd, core); + set_tdata (abfd, ((struct suncordata *) rawptr)); + core_hdr (abfd) = core; + + /* create the sections. This is raunchy, but bfd_close wants to reclaim + them */ + core_stacksec (abfd) = (asection *) bfd_zalloc (abfd, sizeof (asection)); + if (core_stacksec (abfd) == NULL) { + loser: + bfd_error = no_memory; + bfd_release (abfd, rawptr); + return 0; + } + core_datasec (abfd) = (asection *) bfd_zalloc (abfd, sizeof (asection)); + if (core_datasec (abfd) == NULL) { + loser1: + bfd_release (abfd, core_stacksec (abfd)); + goto loser; + } + core_regsec (abfd) = (asection *) bfd_zalloc (abfd, sizeof (asection)); + if (core_regsec (abfd) == NULL) { + loser2: + bfd_release (abfd, core_datasec (abfd)); + goto loser1; + } + core_reg2sec (abfd) = (asection *) bfd_zalloc (abfd, sizeof (asection)); + if (core_reg2sec (abfd) == NULL) { + bfd_release (abfd, core_regsec (abfd)); + goto loser2; + } + + core_stacksec (abfd)->name = ".stack"; + core_datasec (abfd)->name = ".data"; + core_regsec (abfd)->name = ".reg"; + core_reg2sec (abfd)->name = ".reg2"; + + core_stacksec (abfd)->flags = SEC_ALLOC + SEC_LOAD; + core_datasec (abfd)->flags = SEC_ALLOC + SEC_LOAD; + core_regsec (abfd)->flags = SEC_ALLOC; + core_reg2sec (abfd)->flags = SEC_ALLOC; + + core_stacksec (abfd)->size = core->c_ssize; + core_datasec (abfd)->size = core->c_dsize; + core_regsec (abfd)->size = (sizeof core->c_regs); + /* Float regs take up end of struct, except c_ucode. */ + core_reg2sec (abfd)->size = core_size - (sizeof core->c_ucode) - + (file_ptr)(((struct core *)0)->fp_stuff); + + core_stacksec (abfd)->vma = (USRSTACK - core->c_ssize); + core_datasec (abfd)->vma = N_DATADDR(core->c_aouthdr); + core_regsec (abfd)->vma = -1; + core_reg2sec (abfd)->vma = -1; + + core_stacksec (abfd)->filepos = core->c_len + core->c_dsize; + core_datasec (abfd)->filepos = core->c_len; + /* In file header: */ + core_regsec (abfd)->filepos = (file_ptr)(&((struct core *)0)->c_regs); + core_reg2sec (abfd)->filepos = (file_ptr)(((struct core *)0)->fp_stuff); + + /* Align to word at least */ + core_stacksec (abfd)->alignment_power = 2; + core_datasec (abfd)->alignment_power = 2; + core_regsec (abfd)->alignment_power = 2; + core_reg2sec (abfd)->alignment_power = 2; + + abfd->sections = core_stacksec (abfd); + core_stacksec (abfd)->next = core_datasec (abfd); + core_datasec (abfd)->next = core_regsec (abfd); + core_regsec (abfd)->next = core_reg2sec (abfd); + + abfd->section_count = 4; + + return abfd->xvec; +} + +static char *sunos4_core_file_failing_command (abfd) +bfd *abfd; + { + return core_hdr (abfd)->c_cmdname; +} + +static int +DEFUN(sunos4_core_file_failing_signal,(abfd), + bfd *abfd) +{ + return core_hdr (abfd)->c_signo; +} + +static boolean +DEFUN(sunos4_core_file_matches_executable_p, (core_bfd, exec_bfd), + bfd *core_bfd AND + bfd *exec_bfd) +{ + if (core_bfd->xvec != exec_bfd->xvec) { + bfd_error = system_call_error; + return false; + } + + return (bcmp ((char *)&core_hdr (core_bfd), (char*) &exec_hdr (exec_bfd), + sizeof (struct internal_exec)) == 0) ? true : false; +} + +/* byte-swap core structure */ +/* FIXME, this needs more work to swap IN a core struct from raw bytes */ +static void +DEFUN(swapcore,(abfd, core), + bfd *abfd AND + struct core *core) +{ + struct external_exec exec_bytes; + + core->c_magic = bfd_h_get_32 (abfd, (unsigned char *)&core->c_magic); + core->c_len = bfd_h_get_32 (abfd, (unsigned char *)&core->c_len ); + /* Leave integer registers in target byte order. */ + bcopy ((char *)&(core->c_aouthdr), (char *)&exec_bytes, EXEC_BYTES_SIZE); + NAME(aout,swap_exec_header_in)(abfd, &exec_bytes, &core->c_aouthdr); + core->c_signo = bfd_h_get_32 (abfd, (unsigned char *)&core->c_signo); + core->c_tsize = bfd_h_get_32 (abfd, (unsigned char *)&core->c_tsize); + core->c_dsize = bfd_h_get_32 (abfd, (unsigned char *)&core->c_dsize); + core->c_ssize = bfd_h_get_32 (abfd, (unsigned char *)&core->c_ssize); + /* Leave FP registers in target byte order. */ + /* Leave "c_ucode" unswapped for now, since we can't find it easily. */ +} + +/* We use BFD generic archive files. */ +#define aout_32_openr_next_archived_file bfd_generic_openr_next_archived_file +#define aout_32_generic_stat_arch_elt bfd_generic_stat_arch_elt +#define aout_32_slurp_armap bfd_slurp_bsd_armap +#define aout_32_slurp_extended_name_table bfd_true +#define aout_32_write_armap bsd_write_armap +#define aout_32_truncate_arname bfd_bsd_truncate_arname +#define aout_32_machine_type sunos_machine_type + +#define aout_32_core_file_failing_command sunos4_core_file_failing_command +#define aout_32_core_file_failing_signal sunos4_core_file_failing_signal +#define aout_32_core_file_matches_executable_p sunos4_core_file_matches_executable_p + + +#define aout_64_openr_next_archived_file bfd_generic_openr_next_archived_file +#define aout_64_generic_stat_arch_elt bfd_generic_stat_arch_elt +#define aout_64_slurp_armap bfd_slurp_bsd_armap +#define aout_64_slurp_extended_name_table bfd_true +#define aout_64_write_armap bsd_write_armap +#define aout_64_truncate_arname bfd_bsd_truncate_arname +#define aout_64_machine_type sunos_machine_type + +#define aout_64_core_file_failing_command sunos4_core_file_failing_command +#define aout_64_core_file_failing_signal sunos4_core_file_failing_signal +#define aout_64_core_file_matches_executable_p sunos4_core_file_matches_executable_p + +/* We implement these routines ourselves, rather than using the generic +a.out versions. */ +#define aout_write_object_contents sunos4_write_object_contents + +bfd_target VECNAME = + { +TARGETNAME, + bfd_target_aout_flavour_enum, + true, /* target byte order */ + true, /* target headers byte order */ + (HAS_RELOC | EXEC_P | /* object flags */ + HAS_LINENO | HAS_DEBUG | + HAS_SYMS | HAS_LOCALS | DYNAMIC | WP_TEXT | D_PAGED), + (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */ + ' ', /* ar_pad_char */ + 16, /* ar_max_namelen */ + _do_getb64, _do_putb64, _do_getb32, _do_putb32, _do_getb16, _do_putb16, /* data */ + _do_getb64, _do_putb64, _do_getb32, _do_putb32, _do_getb16, _do_putb16, /* hdrs */ + + {_bfd_dummy_target, NAME(sunos,object_p), + bfd_generic_archive_p, sunos4_core_file_p}, + {bfd_false, NAME(aout,mkobject), + _bfd_generic_mkarchive, bfd_false}, + {bfd_false, NAME(aout,sunos4_write_object_contents), /* bfd_write_contents */ + _bfd_write_archive_contents, bfd_false}, + + JUMP_TABLE(JNAME(aout)) +}; |