aoutf1.h revision 60484
133965Sjdp/* A.out "format 1" file handling code for BFD. 238889Sjdp Copyright 1990, 91, 92, 93, 94, 95, 96, 97, 1998 338889Sjdp Free Software Foundation, Inc. 433965Sjdp Written by Cygnus Support. 533965Sjdp 633965SjdpThis file is part of BFD, the Binary File Descriptor library. 733965Sjdp 833965SjdpThis program is free software; you can redistribute it and/or modify 933965Sjdpit under the terms of the GNU General Public License as published by 1033965Sjdpthe Free Software Foundation; either version 2 of the License, or 1133965Sjdp(at your option) any later version. 1233965Sjdp 1333965SjdpThis program is distributed in the hope that it will be useful, 1433965Sjdpbut WITHOUT ANY WARRANTY; without even the implied warranty of 1533965SjdpMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1633965SjdpGNU General Public License for more details. 1733965Sjdp 1833965SjdpYou should have received a copy of the GNU General Public License 1933965Sjdpalong with this program; if not, write to the Free Software 2033965SjdpFoundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ 2133965Sjdp 2233965Sjdp#include "bfd.h" 2333965Sjdp#include "sysdep.h" 2433965Sjdp#include "libbfd.h" 2533965Sjdp 2633965Sjdp#include "aout/sun4.h" 2733965Sjdp#include "libaout.h" /* BFD a.out internal data structures */ 2833965Sjdp 2933965Sjdp#include "aout/aout64.h" 3033965Sjdp#include "aout/stab_gnu.h" 3133965Sjdp#include "aout/ar.h" 3233965Sjdp 3333965Sjdp/* This is needed to reject a NewsOS file, e.g. in 3433965Sjdp gdb/testsuite/gdb.t10/crossload.exp. <kingdon@cygnus.com> 3533965Sjdp I needed to add M_UNKNOWN to recognize a 68000 object, so this will 3633965Sjdp probably no longer reject a NewsOS object. <ian@cygnus.com>. */ 3733965Sjdp#ifndef MACHTYPE_OK 3833965Sjdp#define MACHTYPE_OK(mtype) \ 3933965Sjdp (((mtype) == M_SPARC && bfd_lookup_arch (bfd_arch_sparc, 0) != NULL) \ 4033965Sjdp || (((mtype) == M_UNKNOWN || (mtype) == M_68010 || (mtype) == M_68020) \ 4133965Sjdp && bfd_lookup_arch (bfd_arch_m68k, 0) != NULL)) 4233965Sjdp#endif 4333965Sjdp 4433965Sjdp/* 4533965SjdpThe file @code{aoutf1.h} contains the code for BFD's 4633965Sjdpa.out back end. Control over the generated back end is given by these 4733965Sjdptwo preprocessor names: 4833965Sjdp@table @code 4933965Sjdp@item ARCH_SIZE 5033965SjdpThis value should be either 32 or 64, depending upon the size of an 5133965Sjdpint in the target format. It changes the sizes of the structs which 5233965Sjdpperform the memory/disk mapping of structures. 5333965Sjdp 5433965SjdpThe 64 bit backend may only be used if the host compiler supports 64 5533965Sjdpints (eg long long with gcc), by defining the name @code{BFD_HOST_64_BIT} in @code{bfd.h}. 5633965SjdpWith this name defined, @emph{all} bfd operations are performed with 64bit 5733965Sjdparithmetic, not just those to a 64bit target. 5833965Sjdp 5933965Sjdp@item TARGETNAME 6033965SjdpThe name put into the target vector. 6133965Sjdp@item 6233965Sjdp@end table 6333965Sjdp 6433965Sjdp*/ 6533965Sjdp 6633965Sjdp/*SUPPRESS558*/ 6733965Sjdp/*SUPPRESS529*/ 6833965Sjdp 6933965Sjdp#if ARCH_SIZE == 64 7033965Sjdp#define sunos_set_arch_mach sunos_64_set_arch_mach 7133965Sjdp#define sunos_write_object_contents aout_64_sunos4_write_object_contents 7233965Sjdp#else 7333965Sjdp#define sunos_set_arch_mach sunos_32_set_arch_mach 7433965Sjdp#define sunos_write_object_contents aout_32_sunos4_write_object_contents 7533965Sjdp#endif 7633965Sjdp 7733965Sjdpstatic boolean sunos_merge_private_bfd_data PARAMS ((bfd *, bfd *)); 7833965Sjdpstatic void sunos_set_arch_mach PARAMS ((bfd *, int)); 7933965Sjdpstatic void choose_reloc_size PARAMS ((bfd *)); 8033965Sjdpstatic boolean sunos_write_object_contents PARAMS ((bfd *)); 8133965Sjdpstatic const bfd_target *sunos4_core_file_p PARAMS ((bfd *)); 8233965Sjdpstatic char *sunos4_core_file_failing_command PARAMS ((bfd *)); 8333965Sjdpstatic int sunos4_core_file_failing_signal PARAMS ((bfd *)); 8433965Sjdpstatic boolean sunos4_core_file_matches_executable_p PARAMS ((bfd *, bfd *)); 8533965Sjdpstatic boolean sunos4_set_sizes PARAMS ((bfd *)); 8633965Sjdp 8733965Sjdp/* Merge backend data into the output file. 8833965Sjdp This is necessary on sparclet-aout where we want the resultant machine 8933965Sjdp number to be M_SPARCLET if any input file is M_SPARCLET. */ 9033965Sjdp 9133965Sjdp#define MY_bfd_merge_private_bfd_data sunos_merge_private_bfd_data 9233965Sjdp 9333965Sjdpstatic boolean 9433965Sjdpsunos_merge_private_bfd_data (ibfd, obfd) 9533965Sjdp bfd *ibfd, *obfd; 9633965Sjdp{ 9733965Sjdp if (bfd_get_flavour (ibfd) != bfd_target_aout_flavour 9833965Sjdp || bfd_get_flavour (obfd) != bfd_target_aout_flavour) 9933965Sjdp return true; 10033965Sjdp 10133965Sjdp if (bfd_get_arch (obfd) == bfd_arch_sparc) 10233965Sjdp { 10333965Sjdp if (bfd_get_mach (obfd) < bfd_get_mach (ibfd)) 10433965Sjdp bfd_set_arch_mach (obfd, bfd_arch_sparc, bfd_get_mach (ibfd)); 10533965Sjdp } 10633965Sjdp 10733965Sjdp return true; 10833965Sjdp} 10933965Sjdp 11033965Sjdp/* This is either sunos_32_set_arch_mach or sunos_64_set_arch_mach, 11133965Sjdp depending upon ARCH_SIZE. */ 11233965Sjdp 11333965Sjdpstatic void 11433965Sjdpsunos_set_arch_mach (abfd, machtype) 11533965Sjdp bfd *abfd; 11633965Sjdp int machtype; 11733965Sjdp{ 11833965Sjdp /* Determine the architecture and machine type of the object file. */ 11933965Sjdp enum bfd_architecture arch; 12033965Sjdp long machine; 12133965Sjdp switch (machtype) 12233965Sjdp { 12333965Sjdp 12433965Sjdp case M_UNKNOWN: 12533965Sjdp /* Some Sun3s make magic numbers without cpu types in them, so 12633965Sjdp we'll default to the 68000. */ 12733965Sjdp arch = bfd_arch_m68k; 12838889Sjdp machine = bfd_mach_m68000; 12933965Sjdp break; 13033965Sjdp 13133965Sjdp case M_68010: 13233965Sjdp case M_HP200: 13333965Sjdp arch = bfd_arch_m68k; 13438889Sjdp machine = bfd_mach_m68010; 13533965Sjdp break; 13633965Sjdp 13733965Sjdp case M_68020: 13833965Sjdp case M_HP300: 13933965Sjdp arch = bfd_arch_m68k; 14038889Sjdp machine = bfd_mach_m68020; 14133965Sjdp break; 14233965Sjdp 14333965Sjdp case M_SPARC: 14433965Sjdp arch = bfd_arch_sparc; 14533965Sjdp machine = 0; 14633965Sjdp break; 14733965Sjdp 14833965Sjdp case M_SPARCLET: 14933965Sjdp arch = bfd_arch_sparc; 15033965Sjdp machine = bfd_mach_sparc_sparclet; 15133965Sjdp break; 15233965Sjdp 15360484Sobrien case M_SPARCLITE_LE: 15460484Sobrien arch = bfd_arch_sparc; 15560484Sobrien machine = bfd_mach_sparc_sparclite_le; 15660484Sobrien break; 15760484Sobrien 15833965Sjdp case M_386: 15933965Sjdp case M_386_DYNIX: 16033965Sjdp arch = bfd_arch_i386; 16133965Sjdp machine = 0; 16233965Sjdp break; 16333965Sjdp 16433965Sjdp case M_29K: 16533965Sjdp arch = bfd_arch_a29k; 16633965Sjdp machine = 0; 16733965Sjdp break; 16833965Sjdp 16933965Sjdp case M_HPUX: 17033965Sjdp arch = bfd_arch_m68k; 17133965Sjdp machine = 0; 17233965Sjdp break; 17333965Sjdp 17433965Sjdp default: 17533965Sjdp arch = bfd_arch_obscure; 17633965Sjdp machine = 0; 17733965Sjdp break; 17833965Sjdp } 17933965Sjdp bfd_set_arch_mach (abfd, arch, machine); 18033965Sjdp} 18133965Sjdp 18233965Sjdp#define SET_ARCH_MACH(ABFD, EXEC) \ 18333965Sjdp NAME(sunos,set_arch_mach)(ABFD, N_MACHTYPE (EXEC)); \ 18433965Sjdp choose_reloc_size(ABFD); 18533965Sjdp 18633965Sjdp/* Determine the size of a relocation entry, based on the architecture */ 18733965Sjdpstatic void 18833965Sjdpchoose_reloc_size (abfd) 18933965Sjdp bfd *abfd; 19033965Sjdp{ 19133965Sjdp switch (bfd_get_arch (abfd)) 19233965Sjdp { 19333965Sjdp case bfd_arch_sparc: 19433965Sjdp case bfd_arch_a29k: 19533965Sjdp obj_reloc_entry_size (abfd) = RELOC_EXT_SIZE; 19633965Sjdp break; 19733965Sjdp default: 19833965Sjdp obj_reloc_entry_size (abfd) = RELOC_STD_SIZE; 19933965Sjdp break; 20033965Sjdp } 20133965Sjdp} 20233965Sjdp 20333965Sjdp/* Write an object file in SunOS format. Section contents have 20433965Sjdp already been written. We write the file header, symbols, and 20533965Sjdp relocation. The real name of this function is either 20633965Sjdp aout_64_sunos4_write_object_contents or 20733965Sjdp aout_32_sunos4_write_object_contents, depending upon ARCH_SIZE. */ 20833965Sjdp 20933965Sjdpstatic boolean 21033965Sjdpsunos_write_object_contents (abfd) 21133965Sjdp bfd *abfd; 21233965Sjdp{ 21333965Sjdp struct external_exec exec_bytes; 21433965Sjdp struct internal_exec *execp = exec_hdr (abfd); 21533965Sjdp 21633965Sjdp /* Magic number, maestro, please! */ 21733965Sjdp switch (bfd_get_arch (abfd)) 21833965Sjdp { 21933965Sjdp case bfd_arch_m68k: 22033965Sjdp switch (bfd_get_mach (abfd)) 22133965Sjdp { 22238889Sjdp case bfd_mach_m68000: 22333965Sjdp N_SET_MACHTYPE (*execp, M_UNKNOWN); 22433965Sjdp break; 22538889Sjdp case bfd_mach_m68010: 22633965Sjdp N_SET_MACHTYPE (*execp, M_68010); 22733965Sjdp break; 22833965Sjdp default: 22938889Sjdp case bfd_mach_m68020: 23033965Sjdp N_SET_MACHTYPE (*execp, M_68020); 23133965Sjdp break; 23233965Sjdp } 23333965Sjdp break; 23433965Sjdp case bfd_arch_sparc: 23533965Sjdp switch (bfd_get_mach (abfd)) 23633965Sjdp { 23733965Sjdp case bfd_mach_sparc_sparclet: 23833965Sjdp N_SET_MACHTYPE (*execp, M_SPARCLET); 23933965Sjdp break; 24060484Sobrien case bfd_mach_sparc_sparclite_le: 24160484Sobrien N_SET_MACHTYPE (*execp, M_SPARCLITE_LE); 24260484Sobrien break; 24333965Sjdp default: 24433965Sjdp N_SET_MACHTYPE (*execp, M_SPARC); 24533965Sjdp break; 24633965Sjdp } 24733965Sjdp break; 24833965Sjdp case bfd_arch_i386: 24933965Sjdp N_SET_MACHTYPE (*execp, M_386); 25033965Sjdp break; 25133965Sjdp case bfd_arch_a29k: 25233965Sjdp N_SET_MACHTYPE (*execp, M_29K); 25333965Sjdp break; 25433965Sjdp default: 25533965Sjdp N_SET_MACHTYPE (*execp, M_UNKNOWN); 25633965Sjdp } 25733965Sjdp 25833965Sjdp choose_reloc_size (abfd); 25933965Sjdp 26033965Sjdp N_SET_FLAGS (*execp, aout_backend_info (abfd)->exec_hdr_flags); 26133965Sjdp 26233965Sjdp N_SET_DYNAMIC (*execp, bfd_get_file_flags (abfd) & DYNAMIC); 26333965Sjdp 26433965Sjdp WRITE_HEADERS (abfd, execp); 26533965Sjdp 26633965Sjdp return true; 26733965Sjdp} 26833965Sjdp 26933965Sjdp/* core files */ 27033965Sjdp 27133965Sjdp#define CORE_MAGIC 0x080456 27233965Sjdp#define CORE_NAMELEN 16 27333965Sjdp 27433965Sjdp/* The core structure is taken from the Sun documentation. 27533965Sjdp Unfortunately, they don't document the FPA structure, or at least I 27633965Sjdp can't find it easily. Fortunately the core header contains its own 27733965Sjdp length. So this shouldn't cause problems, except for c_ucode, which 27833965Sjdp so far we don't use but is easy to find with a little arithmetic. */ 27933965Sjdp 28033965Sjdp/* But the reg structure can be gotten from the SPARC processor handbook. 28133965Sjdp This really should be in a GNU include file though so that gdb can use 28233965Sjdp the same info. */ 28333965Sjdpstruct regs 28433965Sjdp{ 28533965Sjdp int r_psr; 28633965Sjdp int r_pc; 28733965Sjdp int r_npc; 28833965Sjdp int r_y; 28933965Sjdp int r_g1; 29033965Sjdp int r_g2; 29133965Sjdp int r_g3; 29233965Sjdp int r_g4; 29333965Sjdp int r_g5; 29433965Sjdp int r_g6; 29533965Sjdp int r_g7; 29633965Sjdp int r_o0; 29733965Sjdp int r_o1; 29833965Sjdp int r_o2; 29933965Sjdp int r_o3; 30033965Sjdp int r_o4; 30133965Sjdp int r_o5; 30233965Sjdp int r_o6; 30333965Sjdp int r_o7; 30433965Sjdp}; 30533965Sjdp 30633965Sjdp/* Taken from Sun documentation: */ 30733965Sjdp 30833965Sjdp/* FIXME: It's worse than we expect. This struct contains TWO substructs 30933965Sjdp neither of whose size we know, WITH STUFF IN BETWEEN THEM! We can't 31033965Sjdp even portably access the stuff in between! */ 31133965Sjdp 31233965Sjdpstruct external_sparc_core 31333965Sjdp { 31433965Sjdp int c_magic; /* Corefile magic number */ 31533965Sjdp int c_len; /* Sizeof (struct core) */ 31633965Sjdp#define SPARC_CORE_LEN 432 31733965Sjdp int c_regs[19]; /* General purpose registers -- MACHDEP SIZE */ 31833965Sjdp struct external_exec c_aouthdr; /* A.out header */ 31933965Sjdp int c_signo; /* Killing signal, if any */ 32033965Sjdp int c_tsize; /* Text size (bytes) */ 32133965Sjdp int c_dsize; /* Data size (bytes) */ 32233965Sjdp int c_ssize; /* Stack size (bytes) */ 32333965Sjdp char c_cmdname[CORE_NAMELEN + 1]; /* Command name */ 32433965Sjdp double fp_stuff[1]; /* external FPU state (size unknown by us) */ 32533965Sjdp /* The type "double" is critical here, for alignment. 32633965Sjdp SunOS declares a struct here, but the struct's alignment 32733965Sjdp is double since it contains doubles. */ 32833965Sjdp int c_ucode; /* Exception no. from u_code */ 32933965Sjdp /* (this member is not accessible by name since we don't 33033965Sjdp portably know the size of fp_stuff.) */ 33133965Sjdp }; 33233965Sjdp 33333965Sjdp/* Core files generated by the BCP (the part of Solaris which allows 33433965Sjdp it to run SunOS4 a.out files). */ 33533965Sjdpstruct external_solaris_bcp_core 33633965Sjdp { 33733965Sjdp int c_magic; /* Corefile magic number */ 33833965Sjdp int c_len; /* Sizeof (struct core) */ 33933965Sjdp#define SOLARIS_BCP_CORE_LEN 456 34033965Sjdp int c_regs[19]; /* General purpose registers -- MACHDEP SIZE */ 34133965Sjdp int c_exdata_vp; /* exdata structure */ 34233965Sjdp int c_exdata_tsize; 34333965Sjdp int c_exdata_dsize; 34433965Sjdp int c_exdata_bsize; 34533965Sjdp int c_exdata_lsize; 34633965Sjdp int c_exdata_nshlibs; 34733965Sjdp short c_exdata_mach; 34833965Sjdp short c_exdata_mag; 34933965Sjdp int c_exdata_toffset; 35033965Sjdp int c_exdata_doffset; 35133965Sjdp int c_exdata_loffset; 35233965Sjdp int c_exdata_txtorg; 35333965Sjdp int c_exdata_datorg; 35433965Sjdp int c_exdata_entloc; 35533965Sjdp int c_signo; /* Killing signal, if any */ 35633965Sjdp int c_tsize; /* Text size (bytes) */ 35733965Sjdp int c_dsize; /* Data size (bytes) */ 35833965Sjdp int c_ssize; /* Stack size (bytes) */ 35933965Sjdp char c_cmdname[CORE_NAMELEN + 1]; /* Command name */ 36033965Sjdp double fp_stuff[1]; /* external FPU state (size unknown by us) */ 36133965Sjdp /* The type "double" is critical here, for alignment. 36233965Sjdp SunOS declares a struct here, but the struct's alignment 36333965Sjdp is double since it contains doubles. */ 36433965Sjdp int c_ucode; /* Exception no. from u_code */ 36533965Sjdp /* (this member is not accessible by name since we don't 36633965Sjdp portably know the size of fp_stuff.) */ 36733965Sjdp }; 36833965Sjdp 36933965Sjdpstruct external_sun3_core 37033965Sjdp { 37133965Sjdp int c_magic; /* Corefile magic number */ 37233965Sjdp int c_len; /* Sizeof (struct core) */ 37333965Sjdp#define SUN3_CORE_LEN 826 /* As of SunOS 4.1.1 */ 37433965Sjdp int c_regs[18]; /* General purpose registers -- MACHDEP SIZE */ 37533965Sjdp struct external_exec c_aouthdr; /* A.out header */ 37633965Sjdp int c_signo; /* Killing signal, if any */ 37733965Sjdp int c_tsize; /* Text size (bytes) */ 37833965Sjdp int c_dsize; /* Data size (bytes) */ 37933965Sjdp int c_ssize; /* Stack size (bytes) */ 38033965Sjdp char c_cmdname[CORE_NAMELEN + 1]; /* Command name */ 38133965Sjdp double fp_stuff[1]; /* external FPU state (size unknown by us) */ 38233965Sjdp /* The type "double" is critical here, for alignment. 38333965Sjdp SunOS declares a struct here, but the struct's alignment 38433965Sjdp is double since it contains doubles. */ 38533965Sjdp int c_ucode; /* Exception no. from u_code */ 38633965Sjdp /* (this member is not accessible by name since we don't 38733965Sjdp portably know the size of fp_stuff.) */ 38833965Sjdp }; 38933965Sjdp 39033965Sjdpstruct internal_sunos_core 39133965Sjdp { 39233965Sjdp int c_magic; /* Corefile magic number */ 39333965Sjdp int c_len; /* Sizeof (struct core) */ 39433965Sjdp long c_regs_pos; /* file offset of General purpose registers */ 39533965Sjdp int c_regs_size; /* size of General purpose registers */ 39633965Sjdp struct internal_exec c_aouthdr; /* A.out header */ 39733965Sjdp int c_signo; /* Killing signal, if any */ 39833965Sjdp int c_tsize; /* Text size (bytes) */ 39933965Sjdp int c_dsize; /* Data size (bytes) */ 40033965Sjdp bfd_vma c_data_addr; /* Data start (address) */ 40133965Sjdp int c_ssize; /* Stack size (bytes) */ 40233965Sjdp bfd_vma c_stacktop; /* Stack top (address) */ 40333965Sjdp char c_cmdname[CORE_NAMELEN + 1]; /* Command name */ 40433965Sjdp long fp_stuff_pos; /* file offset of external FPU state (regs) */ 40533965Sjdp int fp_stuff_size; /* Size of it */ 40633965Sjdp int c_ucode; /* Exception no. from u_code */ 40733965Sjdp }; 40833965Sjdp 40933965Sjdpstatic void swapcore_sun3 41033965Sjdp PARAMS ((bfd *, char *, struct internal_sunos_core *)); 41133965Sjdpstatic void swapcore_sparc 41233965Sjdp PARAMS ((bfd *, char *, struct internal_sunos_core *)); 41333965Sjdpstatic void swapcore_solaris_bcp 41433965Sjdp PARAMS ((bfd *, char *, struct internal_sunos_core *)); 41533965Sjdp 41633965Sjdp/* byte-swap in the Sun-3 core structure */ 41733965Sjdpstatic void 41833965Sjdpswapcore_sun3 (abfd, ext, intcore) 41933965Sjdp bfd *abfd; 42033965Sjdp char *ext; 42133965Sjdp struct internal_sunos_core *intcore; 42233965Sjdp{ 42333965Sjdp struct external_sun3_core *extcore = (struct external_sun3_core *) ext; 42433965Sjdp 42533965Sjdp intcore->c_magic = bfd_h_get_32 (abfd, (unsigned char *) &extcore->c_magic); 42633965Sjdp intcore->c_len = bfd_h_get_32 (abfd, (unsigned char *) &extcore->c_len); 42733965Sjdp intcore->c_regs_pos = (long) (((struct external_sun3_core *) 0)->c_regs); 42833965Sjdp intcore->c_regs_size = sizeof (extcore->c_regs); 42933965Sjdp#if ARCH_SIZE == 64 43033965Sjdp aout_64_swap_exec_header_in 43133965Sjdp#else 43233965Sjdp aout_32_swap_exec_header_in 43333965Sjdp#endif 43433965Sjdp (abfd, &extcore->c_aouthdr, &intcore->c_aouthdr); 43533965Sjdp intcore->c_signo = bfd_h_get_32 (abfd, (unsigned char *) &extcore->c_signo); 43633965Sjdp intcore->c_tsize = bfd_h_get_32 (abfd, (unsigned char *) &extcore->c_tsize); 43733965Sjdp intcore->c_dsize = bfd_h_get_32 (abfd, (unsigned char *) &extcore->c_dsize); 43833965Sjdp intcore->c_data_addr = N_DATADDR (intcore->c_aouthdr); 43933965Sjdp intcore->c_ssize = bfd_h_get_32 (abfd, (unsigned char *) &extcore->c_ssize); 44033965Sjdp memcpy (intcore->c_cmdname, extcore->c_cmdname, sizeof (intcore->c_cmdname)); 44133965Sjdp intcore->fp_stuff_pos = (long) (((struct external_sun3_core *) 0)->fp_stuff); 44233965Sjdp /* FP stuff takes up whole rest of struct, except c_ucode. */ 44333965Sjdp intcore->fp_stuff_size = intcore->c_len - (sizeof extcore->c_ucode) - 44433965Sjdp (file_ptr) (((struct external_sun3_core *) 0)->fp_stuff); 44533965Sjdp /* Ucode is the last thing in the struct -- just before the end */ 44633965Sjdp intcore->c_ucode = 44733965Sjdp bfd_h_get_32 (abfd, 44833965Sjdp intcore->c_len - sizeof (extcore->c_ucode) + (unsigned char *) extcore); 44933965Sjdp intcore->c_stacktop = 0x0E000000; /* By experimentation */ 45033965Sjdp} 45133965Sjdp 45233965Sjdp 45333965Sjdp/* byte-swap in the Sparc core structure */ 45433965Sjdpstatic void 45533965Sjdpswapcore_sparc (abfd, ext, intcore) 45633965Sjdp bfd *abfd; 45733965Sjdp char *ext; 45833965Sjdp struct internal_sunos_core *intcore; 45933965Sjdp{ 46033965Sjdp struct external_sparc_core *extcore = (struct external_sparc_core *) ext; 46133965Sjdp 46233965Sjdp intcore->c_magic = bfd_h_get_32 (abfd, (unsigned char *) &extcore->c_magic); 46333965Sjdp intcore->c_len = bfd_h_get_32 (abfd, (unsigned char *) &extcore->c_len); 46433965Sjdp intcore->c_regs_pos = (long) (((struct external_sparc_core *) 0)->c_regs); 46533965Sjdp intcore->c_regs_size = sizeof (extcore->c_regs); 46633965Sjdp#if ARCH_SIZE == 64 46733965Sjdp aout_64_swap_exec_header_in 46833965Sjdp#else 46933965Sjdp aout_32_swap_exec_header_in 47033965Sjdp#endif 47133965Sjdp (abfd, &extcore->c_aouthdr, &intcore->c_aouthdr); 47233965Sjdp intcore->c_signo = bfd_h_get_32 (abfd, (unsigned char *) &extcore->c_signo); 47333965Sjdp intcore->c_tsize = bfd_h_get_32 (abfd, (unsigned char *) &extcore->c_tsize); 47433965Sjdp intcore->c_dsize = bfd_h_get_32 (abfd, (unsigned char *) &extcore->c_dsize); 47533965Sjdp intcore->c_data_addr = N_DATADDR (intcore->c_aouthdr); 47633965Sjdp intcore->c_ssize = bfd_h_get_32 (abfd, (unsigned char *) &extcore->c_ssize); 47733965Sjdp memcpy (intcore->c_cmdname, extcore->c_cmdname, sizeof (intcore->c_cmdname)); 47833965Sjdp intcore->fp_stuff_pos = (long) (((struct external_sparc_core *) 0)->fp_stuff); 47933965Sjdp /* FP stuff takes up whole rest of struct, except c_ucode. */ 48033965Sjdp intcore->fp_stuff_size = intcore->c_len - (sizeof extcore->c_ucode) - 48133965Sjdp (file_ptr) (((struct external_sparc_core *) 0)->fp_stuff); 48233965Sjdp /* Ucode is the last thing in the struct -- just before the end */ 48333965Sjdp intcore->c_ucode = 48433965Sjdp bfd_h_get_32 (abfd, 48533965Sjdp intcore->c_len - sizeof (extcore->c_ucode) + (unsigned char *) extcore); 48633965Sjdp 48733965Sjdp /* Supposedly the user stack grows downward from the bottom of kernel memory. 48833965Sjdp Presuming that this remains true, this definition will work. */ 48933965Sjdp /* Now sun has provided us with another challenge. The value is different 49033965Sjdp for sparc2 and sparc10 (both running SunOS 4.1.3). We pick one or 49133965Sjdp the other based on the current value of the stack pointer. This 49233965Sjdp loses (a) if the stack pointer has been clobbered, or (b) if the stack 49333965Sjdp is larger than 128 megabytes. 49433965Sjdp 49533965Sjdp It's times like these you're glad they're switching to ELF. 49633965Sjdp 49733965Sjdp Note that using include files or nlist on /vmunix would be wrong, 49833965Sjdp because we want the value for this core file, no matter what kind of 49933965Sjdp machine we were compiled on or are running on. */ 50033965Sjdp#define SPARC_USRSTACK_SPARC2 ((bfd_vma)0xf8000000) 50133965Sjdp#define SPARC_USRSTACK_SPARC10 ((bfd_vma)0xf0000000) 50233965Sjdp { 50333965Sjdp bfd_vma sp = bfd_h_get_32 50433965Sjdp (abfd, (unsigned char *) &((struct regs *) &extcore->c_regs[0])->r_o6); 50533965Sjdp if (sp < SPARC_USRSTACK_SPARC10) 50633965Sjdp intcore->c_stacktop = SPARC_USRSTACK_SPARC10; 50733965Sjdp else 50833965Sjdp intcore->c_stacktop = SPARC_USRSTACK_SPARC2; 50933965Sjdp } 51033965Sjdp} 51133965Sjdp 51233965Sjdp/* byte-swap in the Solaris BCP core structure */ 51333965Sjdpstatic void 51433965Sjdpswapcore_solaris_bcp (abfd, ext, intcore) 51533965Sjdp bfd *abfd; 51633965Sjdp char *ext; 51733965Sjdp struct internal_sunos_core *intcore; 51833965Sjdp{ 51933965Sjdp struct external_solaris_bcp_core *extcore = 52033965Sjdp (struct external_solaris_bcp_core *) ext; 52133965Sjdp 52233965Sjdp intcore->c_magic = bfd_h_get_32 (abfd, (unsigned char *) &extcore->c_magic); 52333965Sjdp intcore->c_len = bfd_h_get_32 (abfd, (unsigned char *) &extcore->c_len); 52433965Sjdp intcore->c_regs_pos = (long) (((struct external_solaris_bcp_core *) 0)->c_regs); 52533965Sjdp intcore->c_regs_size = sizeof (extcore->c_regs); 52633965Sjdp 52733965Sjdp /* The Solaris BCP exdata structure does not contain an a_syms field, 52833965Sjdp so we are unable to synthesize an internal exec header. 52933965Sjdp Luckily we are able to figure out the start address of the data section, 53033965Sjdp which is the only thing needed from the internal exec header, 53133965Sjdp from the exdata structure. 53233965Sjdp 53333965Sjdp As of Solaris 2.3, BCP core files for statically linked executables 53433965Sjdp are buggy. The exdata structure is not properly filled in, and 53533965Sjdp the data section is written from address zero instead of the data 53633965Sjdp start address. */ 53733965Sjdp memset ((PTR) &intcore->c_aouthdr, 0, sizeof (struct internal_exec)); 53833965Sjdp intcore->c_data_addr = 53933965Sjdp bfd_h_get_32 (abfd, (unsigned char *) &extcore->c_exdata_datorg); 54033965Sjdp intcore->c_signo = bfd_h_get_32 (abfd, (unsigned char *) &extcore->c_signo); 54133965Sjdp intcore->c_tsize = bfd_h_get_32 (abfd, (unsigned char *) &extcore->c_tsize); 54233965Sjdp intcore->c_dsize = bfd_h_get_32 (abfd, (unsigned char *) &extcore->c_dsize); 54333965Sjdp intcore->c_ssize = bfd_h_get_32 (abfd, (unsigned char *) &extcore->c_ssize); 54433965Sjdp memcpy (intcore->c_cmdname, extcore->c_cmdname, sizeof (intcore->c_cmdname)); 54533965Sjdp intcore->fp_stuff_pos = 54633965Sjdp (long) (((struct external_solaris_bcp_core *) 0)->fp_stuff); 54733965Sjdp /* FP stuff takes up whole rest of struct, except c_ucode. */ 54833965Sjdp intcore->fp_stuff_size = intcore->c_len - (sizeof extcore->c_ucode) - 54933965Sjdp (file_ptr) (((struct external_solaris_bcp_core *) 0)->fp_stuff); 55033965Sjdp /* Ucode is the last thing in the struct -- just before the end */ 55133965Sjdp intcore->c_ucode = 55233965Sjdp bfd_h_get_32 (abfd, 55333965Sjdp intcore->c_len - sizeof (extcore->c_ucode) + (unsigned char *) extcore); 55433965Sjdp 55533965Sjdp /* Supposedly the user stack grows downward from the bottom of kernel memory. 55633965Sjdp Presuming that this remains true, this definition will work. */ 55733965Sjdp /* Now sun has provided us with another challenge. The value is different 55833965Sjdp for sparc2 and sparc10 (both running SunOS 4.1.3). We pick one or 55933965Sjdp the other based on the current value of the stack pointer. This 56033965Sjdp loses (a) if the stack pointer has been clobbered, or (b) if the stack 56133965Sjdp is larger than 128 megabytes. 56233965Sjdp 56333965Sjdp It's times like these you're glad they're switching to ELF. 56433965Sjdp 56533965Sjdp Note that using include files or nlist on /vmunix would be wrong, 56633965Sjdp because we want the value for this core file, no matter what kind of 56733965Sjdp machine we were compiled on or are running on. */ 56833965Sjdp#define SPARC_USRSTACK_SPARC2 ((bfd_vma)0xf8000000) 56933965Sjdp#define SPARC_USRSTACK_SPARC10 ((bfd_vma)0xf0000000) 57033965Sjdp { 57133965Sjdp bfd_vma sp = bfd_h_get_32 57233965Sjdp (abfd, (unsigned char *) &((struct regs *) &extcore->c_regs[0])->r_o6); 57333965Sjdp if (sp < SPARC_USRSTACK_SPARC10) 57433965Sjdp intcore->c_stacktop = SPARC_USRSTACK_SPARC10; 57533965Sjdp else 57633965Sjdp intcore->c_stacktop = SPARC_USRSTACK_SPARC2; 57733965Sjdp } 57833965Sjdp} 57933965Sjdp 58033965Sjdp/* need this cast because ptr is really void * */ 58133965Sjdp#define core_hdr(bfd) ((bfd)->tdata.sun_core_data) 58233965Sjdp#define core_datasec(bfd) (core_hdr(bfd)->data_section) 58333965Sjdp#define core_stacksec(bfd) (core_hdr(bfd)->stack_section) 58433965Sjdp#define core_regsec(bfd) (core_hdr(bfd)->reg_section) 58533965Sjdp#define core_reg2sec(bfd) (core_hdr(bfd)->reg2_section) 58633965Sjdp 58733965Sjdp/* These are stored in the bfd's tdata */ 58833965Sjdpstruct sun_core_struct 58933965Sjdp{ 59033965Sjdp struct internal_sunos_core *hdr; /* core file header */ 59133965Sjdp asection *data_section; 59233965Sjdp asection *stack_section; 59333965Sjdp asection *reg_section; 59433965Sjdp asection *reg2_section; 59533965Sjdp}; 59633965Sjdp 59733965Sjdpstatic const bfd_target * 59833965Sjdpsunos4_core_file_p (abfd) 59933965Sjdp bfd *abfd; 60033965Sjdp{ 60133965Sjdp unsigned char longbuf[4]; /* Raw bytes of various header fields */ 60233965Sjdp bfd_size_type core_size; 60333965Sjdp unsigned long core_mag; 60433965Sjdp struct internal_sunos_core *core; 60533965Sjdp char *extcore; 60633965Sjdp struct mergem 60733965Sjdp { 60833965Sjdp struct sun_core_struct suncoredata; 60933965Sjdp struct internal_sunos_core internal_sunos_core; 61033965Sjdp char external_core[1]; 61133965Sjdp } 61233965Sjdp *mergem; 61333965Sjdp 61433965Sjdp if (bfd_read ((PTR) longbuf, 1, sizeof (longbuf), abfd) != 61533965Sjdp sizeof (longbuf)) 61633965Sjdp return 0; 61733965Sjdp core_mag = bfd_h_get_32 (abfd, longbuf); 61833965Sjdp 61933965Sjdp if (core_mag != CORE_MAGIC) 62033965Sjdp return 0; 62133965Sjdp 62233965Sjdp /* SunOS core headers can vary in length; second word is size; */ 62333965Sjdp if (bfd_read ((PTR) longbuf, 1, sizeof (longbuf), abfd) != 62433965Sjdp sizeof (longbuf)) 62533965Sjdp return 0; 62633965Sjdp core_size = bfd_h_get_32 (abfd, longbuf); 62733965Sjdp /* Sanity check */ 62833965Sjdp if (core_size > 20000) 62933965Sjdp return 0; 63033965Sjdp 63133965Sjdp if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) < 0) 63233965Sjdp return 0; 63333965Sjdp 63433965Sjdp mergem = (struct mergem *) bfd_zalloc (abfd, core_size + sizeof (struct mergem)); 63533965Sjdp if (mergem == NULL) 63633965Sjdp return 0; 63733965Sjdp 63833965Sjdp extcore = mergem->external_core; 63933965Sjdp 64033965Sjdp if ((bfd_read ((PTR) extcore, 1, core_size, abfd)) != core_size) 64133965Sjdp { 64233965Sjdp bfd_release (abfd, (char *) mergem); 64333965Sjdp return 0; 64433965Sjdp } 64533965Sjdp 64633965Sjdp /* Validate that it's a core file we know how to handle, due to sun 64733965Sjdp botching the positioning of registers and other fields in a machine 64833965Sjdp dependent way. */ 64933965Sjdp core = &mergem->internal_sunos_core; 65033965Sjdp switch (core_size) 65133965Sjdp { 65233965Sjdp case SPARC_CORE_LEN: 65333965Sjdp swapcore_sparc (abfd, extcore, core); 65433965Sjdp break; 65533965Sjdp case SUN3_CORE_LEN: 65633965Sjdp swapcore_sun3 (abfd, extcore, core); 65733965Sjdp break; 65833965Sjdp case SOLARIS_BCP_CORE_LEN: 65933965Sjdp swapcore_solaris_bcp (abfd, extcore, core); 66033965Sjdp break; 66133965Sjdp default: 66233965Sjdp bfd_set_error (bfd_error_system_call); /* FIXME */ 66333965Sjdp bfd_release (abfd, (char *) mergem); 66433965Sjdp return 0; 66533965Sjdp } 66633965Sjdp 66733965Sjdp abfd->tdata.sun_core_data = &mergem->suncoredata; 66833965Sjdp abfd->tdata.sun_core_data->hdr = core; 66933965Sjdp 67033965Sjdp /* create the sections. This is raunchy, but bfd_close wants to reclaim 67133965Sjdp them */ 67233965Sjdp core_stacksec (abfd) = (asection *) bfd_zalloc (abfd, sizeof (asection)); 67333965Sjdp if (core_stacksec (abfd) == NULL) 67433965Sjdp { 67533965Sjdp loser: 67633965Sjdp bfd_release (abfd, (char *) mergem); 67733965Sjdp return 0; 67833965Sjdp } 67933965Sjdp core_datasec (abfd) = (asection *) bfd_zalloc (abfd, sizeof (asection)); 68033965Sjdp if (core_datasec (abfd) == NULL) 68133965Sjdp { 68233965Sjdp loser1: 68333965Sjdp bfd_release (abfd, core_stacksec (abfd)); 68433965Sjdp goto loser; 68533965Sjdp } 68633965Sjdp core_regsec (abfd) = (asection *) bfd_zalloc (abfd, sizeof (asection)); 68733965Sjdp if (core_regsec (abfd) == NULL) 68833965Sjdp { 68933965Sjdp loser2: 69033965Sjdp bfd_release (abfd, core_datasec (abfd)); 69133965Sjdp goto loser1; 69233965Sjdp } 69333965Sjdp core_reg2sec (abfd) = (asection *) bfd_zalloc (abfd, sizeof (asection)); 69433965Sjdp if (core_reg2sec (abfd) == NULL) 69533965Sjdp { 69633965Sjdp bfd_release (abfd, core_regsec (abfd)); 69733965Sjdp goto loser2; 69833965Sjdp } 69933965Sjdp 70033965Sjdp core_stacksec (abfd)->name = ".stack"; 70133965Sjdp core_datasec (abfd)->name = ".data"; 70233965Sjdp core_regsec (abfd)->name = ".reg"; 70333965Sjdp core_reg2sec (abfd)->name = ".reg2"; 70433965Sjdp 70533965Sjdp core_stacksec (abfd)->flags = SEC_ALLOC + SEC_LOAD + SEC_HAS_CONTENTS; 70633965Sjdp core_datasec (abfd)->flags = SEC_ALLOC + SEC_LOAD + SEC_HAS_CONTENTS; 70733965Sjdp core_regsec (abfd)->flags = SEC_HAS_CONTENTS; 70833965Sjdp core_reg2sec (abfd)->flags = SEC_HAS_CONTENTS; 70933965Sjdp 71033965Sjdp core_stacksec (abfd)->_raw_size = core->c_ssize; 71133965Sjdp core_datasec (abfd)->_raw_size = core->c_dsize; 71233965Sjdp core_regsec (abfd)->_raw_size = core->c_regs_size; 71333965Sjdp core_reg2sec (abfd)->_raw_size = core->fp_stuff_size; 71433965Sjdp 71533965Sjdp core_stacksec (abfd)->vma = (core->c_stacktop - core->c_ssize); 71633965Sjdp core_datasec (abfd)->vma = core->c_data_addr; 71733965Sjdp core_regsec (abfd)->vma = 0; 71833965Sjdp core_reg2sec (abfd)->vma = 0; 71933965Sjdp 72033965Sjdp core_stacksec (abfd)->filepos = core->c_len + core->c_dsize; 72133965Sjdp core_datasec (abfd)->filepos = core->c_len; 72233965Sjdp /* We'll access the regs afresh in the core file, like any section: */ 72333965Sjdp core_regsec (abfd)->filepos = (file_ptr) core->c_regs_pos; 72433965Sjdp core_reg2sec (abfd)->filepos = (file_ptr) core->fp_stuff_pos; 72533965Sjdp 72633965Sjdp /* Align to word at least */ 72733965Sjdp core_stacksec (abfd)->alignment_power = 2; 72833965Sjdp core_datasec (abfd)->alignment_power = 2; 72933965Sjdp core_regsec (abfd)->alignment_power = 2; 73033965Sjdp core_reg2sec (abfd)->alignment_power = 2; 73133965Sjdp 73233965Sjdp abfd->sections = core_stacksec (abfd); 73333965Sjdp core_stacksec (abfd)->next = core_datasec (abfd); 73433965Sjdp core_datasec (abfd)->next = core_regsec (abfd); 73533965Sjdp core_regsec (abfd)->next = core_reg2sec (abfd); 73633965Sjdp 73733965Sjdp abfd->section_count = 4; 73833965Sjdp 73933965Sjdp return abfd->xvec; 74033965Sjdp} 74133965Sjdp 74233965Sjdpstatic char * 74333965Sjdpsunos4_core_file_failing_command (abfd) 74433965Sjdp bfd *abfd; 74533965Sjdp{ 74633965Sjdp return core_hdr (abfd)->hdr->c_cmdname; 74733965Sjdp} 74833965Sjdp 74933965Sjdpstatic int 75033965Sjdpsunos4_core_file_failing_signal (abfd) 75133965Sjdp bfd *abfd; 75233965Sjdp{ 75333965Sjdp return core_hdr (abfd)->hdr->c_signo; 75433965Sjdp} 75533965Sjdp 75633965Sjdpstatic boolean 75733965Sjdpsunos4_core_file_matches_executable_p (core_bfd, exec_bfd) 75833965Sjdp bfd *core_bfd; 75933965Sjdp bfd *exec_bfd; 76033965Sjdp{ 76133965Sjdp if (core_bfd->xvec != exec_bfd->xvec) 76233965Sjdp { 76333965Sjdp bfd_set_error (bfd_error_system_call); 76433965Sjdp return false; 76533965Sjdp } 76633965Sjdp 76733965Sjdp /* Solaris core files do not include an aouthdr. */ 76833965Sjdp if ((core_hdr (core_bfd)->hdr)->c_len == SOLARIS_BCP_CORE_LEN) 76933965Sjdp return true; 77033965Sjdp 77133965Sjdp return (memcmp ((char *) &((core_hdr (core_bfd)->hdr)->c_aouthdr), 77233965Sjdp (char *) exec_hdr (exec_bfd), 77333965Sjdp sizeof (struct internal_exec)) == 0) ? true : false; 77433965Sjdp} 77533965Sjdp 77633965Sjdp#define MY_set_sizes sunos4_set_sizes 77733965Sjdpstatic boolean 77833965Sjdpsunos4_set_sizes (abfd) 77933965Sjdp bfd *abfd; 78033965Sjdp{ 78133965Sjdp switch (bfd_get_arch (abfd)) 78233965Sjdp { 78333965Sjdp default: 78433965Sjdp return false; 78533965Sjdp case bfd_arch_sparc: 78633965Sjdp adata (abfd).page_size = 0x2000; 78733965Sjdp adata (abfd).segment_size = 0x2000; 78833965Sjdp adata (abfd).exec_bytes_size = EXEC_BYTES_SIZE; 78933965Sjdp return true; 79033965Sjdp case bfd_arch_m68k: 79133965Sjdp adata (abfd).page_size = 0x2000; 79233965Sjdp adata (abfd).segment_size = 0x20000; 79333965Sjdp adata (abfd).exec_bytes_size = EXEC_BYTES_SIZE; 79433965Sjdp return true; 79533965Sjdp } 79633965Sjdp} 79733965Sjdp 79833965Sjdp/* We default to setting the toolversion field to 1, as is required by 79933965Sjdp SunOS. */ 80033965Sjdp#ifndef MY_exec_hdr_flags 80133965Sjdp#define MY_exec_hdr_flags 1 80233965Sjdp#endif 80333965Sjdp 80433965Sjdp#ifndef MY_entry_is_text_address 80533965Sjdp#define MY_entry_is_text_address 0 80633965Sjdp#endif 80733965Sjdp#ifndef MY_add_dynamic_symbols 80833965Sjdp#define MY_add_dynamic_symbols 0 80933965Sjdp#endif 81033965Sjdp#ifndef MY_add_one_symbol 81133965Sjdp#define MY_add_one_symbol 0 81233965Sjdp#endif 81333965Sjdp#ifndef MY_link_dynamic_object 81433965Sjdp#define MY_link_dynamic_object 0 81533965Sjdp#endif 81633965Sjdp#ifndef MY_write_dynamic_symbol 81733965Sjdp#define MY_write_dynamic_symbol 0 81833965Sjdp#endif 81933965Sjdp#ifndef MY_check_dynamic_reloc 82033965Sjdp#define MY_check_dynamic_reloc 0 82133965Sjdp#endif 82233965Sjdp#ifndef MY_finish_dynamic_link 82333965Sjdp#define MY_finish_dynamic_link 0 82433965Sjdp#endif 82533965Sjdp 82633965Sjdpstatic CONST struct aout_backend_data sunos4_aout_backend = 82733965Sjdp{ 82833965Sjdp 0, /* zmagic files are not contiguous */ 82933965Sjdp 1, /* text includes header */ 83033965Sjdp MY_entry_is_text_address, 83133965Sjdp MY_exec_hdr_flags, 83233965Sjdp 0, /* default text vma */ 83333965Sjdp sunos4_set_sizes, 83433965Sjdp 0, /* header is counted in zmagic text */ 83533965Sjdp MY_add_dynamic_symbols, 83633965Sjdp MY_add_one_symbol, 83733965Sjdp MY_link_dynamic_object, 83833965Sjdp MY_write_dynamic_symbol, 83933965Sjdp MY_check_dynamic_reloc, 84033965Sjdp MY_finish_dynamic_link 84133965Sjdp}; 84233965Sjdp 84333965Sjdp#define MY_core_file_failing_command sunos4_core_file_failing_command 84433965Sjdp#define MY_core_file_failing_signal sunos4_core_file_failing_signal 84533965Sjdp#define MY_core_file_matches_executable_p sunos4_core_file_matches_executable_p 84633965Sjdp 84733965Sjdp#define MY_bfd_debug_info_start bfd_void 84833965Sjdp#define MY_bfd_debug_info_end bfd_void 84933965Sjdp#define MY_bfd_debug_info_accumulate \ 85033965Sjdp (void (*) PARAMS ((bfd *, struct sec *))) bfd_void 85133965Sjdp#define MY_core_file_p sunos4_core_file_p 85233965Sjdp#define MY_write_object_contents NAME(aout,sunos4_write_object_contents) 85333965Sjdp#define MY_backend_data &sunos4_aout_backend 85433965Sjdp 85533965Sjdp#ifndef TARGET_IS_LITTLE_ENDIAN_P 85633965Sjdp#define TARGET_IS_BIG_ENDIAN_P 85733965Sjdp#endif 85833965Sjdp 85933965Sjdp#include "aout-target.h" 860