133965Sjdp/* A.out "format 1" file handling code for BFD. 289857Sobrien Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 2000, 3218822Sdim 2001, 2002, 2003, 2004, 2005, 2006, 2007 438889Sjdp Free Software Foundation, Inc. 533965Sjdp Written by Cygnus Support. 633965Sjdp 7218822Sdim This file is part of BFD, the Binary File Descriptor library. 833965Sjdp 9218822Sdim This program is free software; you can redistribute it and/or modify 10218822Sdim it under the terms of the GNU General Public License as published by 11218822Sdim the Free Software Foundation; either version 2 of the License, or 12218822Sdim (at your option) any later version. 1333965Sjdp 14218822Sdim This program is distributed in the hope that it will be useful, 15218822Sdim but WITHOUT ANY WARRANTY; without even the implied warranty of 16218822Sdim MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17218822Sdim GNU General Public License for more details. 1833965Sjdp 19218822Sdim You should have received a copy of the GNU General Public License 20218822Sdim along with this program; if not, write to the Free Software 21218822Sdim Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ 2233965Sjdp 23218822Sdim#include "sysdep.h" 2433965Sjdp#include "bfd.h" 2533965Sjdp#include "libbfd.h" 2633965Sjdp 2733965Sjdp#include "aout/sun4.h" 28218822Sdim#include "libaout.h" /* BFD a.out internal data structures. */ 2933965Sjdp 3033965Sjdp#include "aout/aout64.h" 3133965Sjdp#include "aout/stab_gnu.h" 3233965Sjdp#include "aout/ar.h" 3333965Sjdp 3433965Sjdp/* This is needed to reject a NewsOS file, e.g. in 3533965Sjdp gdb/testsuite/gdb.t10/crossload.exp. <kingdon@cygnus.com> 3633965Sjdp I needed to add M_UNKNOWN to recognize a 68000 object, so this will 3777298Sobrien probably no longer reject a NewsOS object. <ian@cygnus.com>. */ 3833965Sjdp#ifndef MACHTYPE_OK 3933965Sjdp#define MACHTYPE_OK(mtype) \ 4033965Sjdp (((mtype) == M_SPARC && bfd_lookup_arch (bfd_arch_sparc, 0) != NULL) \ 4133965Sjdp || (((mtype) == M_UNKNOWN || (mtype) == M_68010 || (mtype) == M_68020) \ 4233965Sjdp && bfd_lookup_arch (bfd_arch_m68k, 0) != NULL)) 4333965Sjdp#endif 4433965Sjdp 45218822Sdim/* The file @code{aoutf1.h} contains the code for BFD's 46218822Sdim a.out back end. Control over the generated back end is given by these 47218822Sdim two preprocessor names: 48218822Sdim @table @code 49218822Sdim @item ARCH_SIZE 50218822Sdim This value should be either 32 or 64, depending upon the size of an 51218822Sdim int in the target format. It changes the sizes of the structs which 52218822Sdim perform the memory/disk mapping of structures. 5333965Sjdp 54218822Sdim The 64 bit backend may only be used if the host compiler supports 64 55218822Sdim ints (eg long long with gcc), by defining the name @code{BFD_HOST_64_BIT} in @code{bfd.h}. 56218822Sdim With this name defined, @emph{all} bfd operations are performed with 64bit 57218822Sdim arithmetic, not just those to a 64bit target. 5833965Sjdp 59218822Sdim @item TARGETNAME 60218822Sdim The name put into the target vector. 61218822Sdim @item 62218822Sdim @end table. */ 6333965Sjdp 6433965Sjdp#if ARCH_SIZE == 64 6533965Sjdp#define sunos_set_arch_mach sunos_64_set_arch_mach 6633965Sjdp#define sunos_write_object_contents aout_64_sunos4_write_object_contents 6733965Sjdp#else 6833965Sjdp#define sunos_set_arch_mach sunos_32_set_arch_mach 6933965Sjdp#define sunos_write_object_contents aout_32_sunos4_write_object_contents 7033965Sjdp#endif 7133965Sjdp 7233965Sjdp/* Merge backend data into the output file. 7333965Sjdp This is necessary on sparclet-aout where we want the resultant machine 7433965Sjdp number to be M_SPARCLET if any input file is M_SPARCLET. */ 7533965Sjdp 7633965Sjdp#define MY_bfd_merge_private_bfd_data sunos_merge_private_bfd_data 7733965Sjdp 78130561Sobrienstatic bfd_boolean 79218822Sdimsunos_merge_private_bfd_data (bfd *ibfd, bfd *obfd) 8033965Sjdp{ 8133965Sjdp if (bfd_get_flavour (ibfd) != bfd_target_aout_flavour 8233965Sjdp || bfd_get_flavour (obfd) != bfd_target_aout_flavour) 83130561Sobrien return TRUE; 8433965Sjdp 8533965Sjdp if (bfd_get_arch (obfd) == bfd_arch_sparc) 8633965Sjdp { 8733965Sjdp if (bfd_get_mach (obfd) < bfd_get_mach (ibfd)) 8833965Sjdp bfd_set_arch_mach (obfd, bfd_arch_sparc, bfd_get_mach (ibfd)); 8933965Sjdp } 9033965Sjdp 91130561Sobrien return TRUE; 9233965Sjdp} 9333965Sjdp 9433965Sjdp/* This is either sunos_32_set_arch_mach or sunos_64_set_arch_mach, 9533965Sjdp depending upon ARCH_SIZE. */ 9633965Sjdp 9733965Sjdpstatic void 98218822Sdimsunos_set_arch_mach (bfd *abfd, enum machine_type machtype) 9933965Sjdp{ 10033965Sjdp /* Determine the architecture and machine type of the object file. */ 10133965Sjdp enum bfd_architecture arch; 10289857Sobrien unsigned long machine; 103218822Sdim 10433965Sjdp switch (machtype) 10533965Sjdp { 10633965Sjdp case M_UNKNOWN: 10733965Sjdp /* Some Sun3s make magic numbers without cpu types in them, so 10877298Sobrien we'll default to the 68000. */ 10933965Sjdp arch = bfd_arch_m68k; 11038889Sjdp machine = bfd_mach_m68000; 11133965Sjdp break; 11233965Sjdp 11333965Sjdp case M_68010: 11433965Sjdp case M_HP200: 11533965Sjdp arch = bfd_arch_m68k; 11638889Sjdp machine = bfd_mach_m68010; 11733965Sjdp break; 11833965Sjdp 11933965Sjdp case M_68020: 12033965Sjdp case M_HP300: 12133965Sjdp arch = bfd_arch_m68k; 12238889Sjdp machine = bfd_mach_m68020; 12333965Sjdp break; 12433965Sjdp 12533965Sjdp case M_SPARC: 12633965Sjdp arch = bfd_arch_sparc; 12733965Sjdp machine = 0; 12833965Sjdp break; 12933965Sjdp 13033965Sjdp case M_SPARCLET: 13133965Sjdp arch = bfd_arch_sparc; 13233965Sjdp machine = bfd_mach_sparc_sparclet; 13333965Sjdp break; 13433965Sjdp 13560484Sobrien case M_SPARCLITE_LE: 13660484Sobrien arch = bfd_arch_sparc; 13760484Sobrien machine = bfd_mach_sparc_sparclite_le; 13860484Sobrien break; 13960484Sobrien 14033965Sjdp case M_386: 14133965Sjdp case M_386_DYNIX: 14233965Sjdp arch = bfd_arch_i386; 14333965Sjdp machine = 0; 14433965Sjdp break; 14533965Sjdp 14633965Sjdp case M_HPUX: 14733965Sjdp arch = bfd_arch_m68k; 14833965Sjdp machine = 0; 14933965Sjdp break; 15033965Sjdp 15133965Sjdp default: 15233965Sjdp arch = bfd_arch_obscure; 15333965Sjdp machine = 0; 15433965Sjdp break; 15533965Sjdp } 15633965Sjdp bfd_set_arch_mach (abfd, arch, machine); 15733965Sjdp} 15833965Sjdp 15933965Sjdp#define SET_ARCH_MACH(ABFD, EXEC) \ 16077298Sobrien NAME(sunos,set_arch_mach) (ABFD, N_MACHTYPE (EXEC)); \ 16133965Sjdp choose_reloc_size(ABFD); 16233965Sjdp 163218822Sdim/* Determine the size of a relocation entry, based on the architecture. */ 164218822Sdim 16533965Sjdpstatic void 166218822Sdimchoose_reloc_size (bfd *abfd) 16733965Sjdp{ 16833965Sjdp switch (bfd_get_arch (abfd)) 16933965Sjdp { 17033965Sjdp case bfd_arch_sparc: 17133965Sjdp obj_reloc_entry_size (abfd) = RELOC_EXT_SIZE; 17233965Sjdp break; 17333965Sjdp default: 17433965Sjdp obj_reloc_entry_size (abfd) = RELOC_STD_SIZE; 17533965Sjdp break; 17633965Sjdp } 17733965Sjdp} 17833965Sjdp 17933965Sjdp/* Write an object file in SunOS format. Section contents have 18033965Sjdp already been written. We write the file header, symbols, and 18133965Sjdp relocation. The real name of this function is either 18233965Sjdp aout_64_sunos4_write_object_contents or 18333965Sjdp aout_32_sunos4_write_object_contents, depending upon ARCH_SIZE. */ 18433965Sjdp 185130561Sobrienstatic bfd_boolean 186218822Sdimsunos_write_object_contents (bfd *abfd) 18733965Sjdp{ 18833965Sjdp struct external_exec exec_bytes; 18933965Sjdp struct internal_exec *execp = exec_hdr (abfd); 19033965Sjdp 19133965Sjdp /* Magic number, maestro, please! */ 19233965Sjdp switch (bfd_get_arch (abfd)) 19333965Sjdp { 19433965Sjdp case bfd_arch_m68k: 19533965Sjdp switch (bfd_get_mach (abfd)) 19633965Sjdp { 19738889Sjdp case bfd_mach_m68000: 19833965Sjdp N_SET_MACHTYPE (*execp, M_UNKNOWN); 19933965Sjdp break; 20038889Sjdp case bfd_mach_m68010: 20133965Sjdp N_SET_MACHTYPE (*execp, M_68010); 20233965Sjdp break; 20333965Sjdp default: 20438889Sjdp case bfd_mach_m68020: 20533965Sjdp N_SET_MACHTYPE (*execp, M_68020); 20633965Sjdp break; 20733965Sjdp } 20833965Sjdp break; 20933965Sjdp case bfd_arch_sparc: 21033965Sjdp switch (bfd_get_mach (abfd)) 21133965Sjdp { 21233965Sjdp case bfd_mach_sparc_sparclet: 21333965Sjdp N_SET_MACHTYPE (*execp, M_SPARCLET); 21433965Sjdp break; 21560484Sobrien case bfd_mach_sparc_sparclite_le: 21660484Sobrien N_SET_MACHTYPE (*execp, M_SPARCLITE_LE); 21760484Sobrien break; 21833965Sjdp default: 21933965Sjdp N_SET_MACHTYPE (*execp, M_SPARC); 22033965Sjdp break; 22133965Sjdp } 22233965Sjdp break; 22333965Sjdp case bfd_arch_i386: 22433965Sjdp N_SET_MACHTYPE (*execp, M_386); 22533965Sjdp break; 22633965Sjdp default: 22733965Sjdp N_SET_MACHTYPE (*execp, M_UNKNOWN); 22833965Sjdp } 22933965Sjdp 23033965Sjdp choose_reloc_size (abfd); 23133965Sjdp 23233965Sjdp N_SET_FLAGS (*execp, aout_backend_info (abfd)->exec_hdr_flags); 23333965Sjdp 23489857Sobrien N_SET_DYNAMIC (*execp, (long)(bfd_get_file_flags (abfd) & DYNAMIC)); 23533965Sjdp 23633965Sjdp WRITE_HEADERS (abfd, execp); 23733965Sjdp 238130561Sobrien return TRUE; 23933965Sjdp} 24033965Sjdp 241218822Sdim/* Core files. */ 24233965Sjdp 243218822Sdim#define CORE_MAGIC 0x080456 24433965Sjdp#define CORE_NAMELEN 16 24533965Sjdp 24633965Sjdp/* The core structure is taken from the Sun documentation. 24733965Sjdp Unfortunately, they don't document the FPA structure, or at least I 24833965Sjdp can't find it easily. Fortunately the core header contains its own 24933965Sjdp length. So this shouldn't cause problems, except for c_ucode, which 25077298Sobrien so far we don't use but is easy to find with a little arithmetic. */ 25133965Sjdp 25233965Sjdp/* But the reg structure can be gotten from the SPARC processor handbook. 25333965Sjdp This really should be in a GNU include file though so that gdb can use 25477298Sobrien the same info. */ 25533965Sjdpstruct regs 25633965Sjdp{ 25733965Sjdp int r_psr; 25833965Sjdp int r_pc; 25933965Sjdp int r_npc; 26033965Sjdp int r_y; 26133965Sjdp int r_g1; 26233965Sjdp int r_g2; 26333965Sjdp int r_g3; 26433965Sjdp int r_g4; 26533965Sjdp int r_g5; 26633965Sjdp int r_g6; 26733965Sjdp int r_g7; 26833965Sjdp int r_o0; 26933965Sjdp int r_o1; 27033965Sjdp int r_o2; 27133965Sjdp int r_o3; 27233965Sjdp int r_o4; 27333965Sjdp int r_o5; 27433965Sjdp int r_o6; 27533965Sjdp int r_o7; 27633965Sjdp}; 27733965Sjdp 27833965Sjdp/* Taken from Sun documentation: */ 27933965Sjdp 28033965Sjdp/* FIXME: It's worse than we expect. This struct contains TWO substructs 28133965Sjdp neither of whose size we know, WITH STUFF IN BETWEEN THEM! We can't 28233965Sjdp even portably access the stuff in between! */ 28333965Sjdp 28433965Sjdpstruct external_sparc_core 285218822Sdim{ 286218822Sdim int c_magic; /* Corefile magic number. */ 287218822Sdim int c_len; /* Sizeof (struct core). */ 28833965Sjdp#define SPARC_CORE_LEN 432 289218822Sdim struct regs c_regs; /* General purpose registers -- MACHDEP SIZE. */ 290218822Sdim struct external_exec c_aouthdr; /* A.out header. */ 291218822Sdim int c_signo; /* Killing signal, if any. */ 292218822Sdim int c_tsize; /* Text size (bytes). */ 293218822Sdim int c_dsize; /* Data size (bytes). */ 294218822Sdim int c_ssize; /* Stack size (bytes). */ 295218822Sdim char c_cmdname[CORE_NAMELEN + 1]; /* Command name. */ 296218822Sdim double fp_stuff[1]; /* External FPU state (size unknown by us). */ 297218822Sdim /* The type "double" is critical here, for alignment. 298218822Sdim SunOS declares a struct here, but the struct's 299218822Sdim alignment is double since it contains doubles. */ 300218822Sdim int c_ucode; /* Exception no. from u_code. */ 301218822Sdim /* This member is not accessible by name since 302218822Sdim we don't portably know the size of fp_stuff. */ 303218822Sdim}; 30433965Sjdp 30533965Sjdp/* Core files generated by the BCP (the part of Solaris which allows 30633965Sjdp it to run SunOS4 a.out files). */ 30733965Sjdpstruct external_solaris_bcp_core 308218822Sdim{ 309218822Sdim int c_magic; /* Corefile magic number. */ 310218822Sdim int c_len; /* Sizeof (struct core). */ 31133965Sjdp#define SOLARIS_BCP_CORE_LEN 456 312218822Sdim struct regs c_regs; /* General purpose registers -- MACHDEP SIZE. */ 313218822Sdim int c_exdata_vp; /* Exdata structure. */ 314218822Sdim int c_exdata_tsize; 315218822Sdim int c_exdata_dsize; 316218822Sdim int c_exdata_bsize; 317218822Sdim int c_exdata_lsize; 318218822Sdim int c_exdata_nshlibs; 319218822Sdim short c_exdata_mach; 320218822Sdim short c_exdata_mag; 321218822Sdim int c_exdata_toffset; 322218822Sdim int c_exdata_doffset; 323218822Sdim int c_exdata_loffset; 324218822Sdim int c_exdata_txtorg; 325218822Sdim int c_exdata_datorg; 326218822Sdim int c_exdata_entloc; 327218822Sdim int c_signo; /* Killing signal, if any. */ 328218822Sdim int c_tsize; /* Text size (bytes). */ 329218822Sdim int c_dsize; /* Data size (bytes). */ 330218822Sdim int c_ssize; /* Stack size (bytes). */ 331218822Sdim char c_cmdname[CORE_NAMELEN + 1]; /* Command name. */ 332218822Sdim double fp_stuff[1]; /* External FPU state (size unknown by us). */ 333218822Sdim /* The type "double" is critical here, for alignment. 334218822Sdim SunOS declares a struct here, but the struct's 335218822Sdim alignment is double since it contains doubles. */ 336218822Sdim int c_ucode; /* Exception no. from u_code. */ 337218822Sdim /* This member is not accessible by name since 338218822Sdim we don't portably know the size of fp_stuff. */ 339218822Sdim}; 34033965Sjdp 34133965Sjdpstruct external_sun3_core 342218822Sdim{ 343218822Sdim int c_magic; /* Corefile magic number. */ 344218822Sdim int c_len; /* Sizeof (struct core). */ 345218822Sdim#define SUN3_CORE_LEN 826 /* As of SunOS 4.1.1. */ 346218822Sdim int c_regs[18]; /* General purpose registers -- MACHDEP SIZE. */ 347218822Sdim struct external_exec c_aouthdr; /* A.out header. */ 348218822Sdim int c_signo; /* Killing signal, if any. */ 349218822Sdim int c_tsize; /* Text size (bytes). */ 350218822Sdim int c_dsize; /* Data size (bytes). */ 351218822Sdim int c_ssize; /* Stack size (bytes). */ 352218822Sdim char c_cmdname[CORE_NAMELEN + 1]; /* Command name. */ 353218822Sdim double fp_stuff[1]; /* External FPU state (size unknown by us). */ 354218822Sdim /* The type "double" is critical here, for alignment. 355218822Sdim SunOS declares a struct here, but the struct's 356218822Sdim alignment is double since it contains doubles. */ 357218822Sdim int c_ucode; /* Exception no. from u_code. */ 358218822Sdim /* This member is not accessible by name since 359218822Sdim we don't portably know the size of fp_stuff. */ 360218822Sdim}; 36133965Sjdp 36233965Sjdpstruct internal_sunos_core 363218822Sdim{ 364218822Sdim int c_magic; /* Corefile magic number. */ 365218822Sdim int c_len; /* Sizeof (struct core). */ 366218822Sdim long c_regs_pos; /* File offset of General purpose registers. */ 367218822Sdim int c_regs_size; /* Size of General purpose registers. */ 368218822Sdim struct internal_exec c_aouthdr; /* A.out header. */ 369218822Sdim int c_signo; /* Killing signal, if any. */ 370218822Sdim int c_tsize; /* Text size (bytes). */ 371218822Sdim int c_dsize; /* Data size (bytes). */ 372218822Sdim bfd_vma c_data_addr; /* Data start (address). */ 373218822Sdim int c_ssize; /* Stack size (bytes). */ 374218822Sdim bfd_vma c_stacktop; /* Stack top (address). */ 375218822Sdim char c_cmdname[CORE_NAMELEN + 1]; /* Command name. */ 376218822Sdim long fp_stuff_pos; /* File offset of external FPU state (regs). */ 377218822Sdim int fp_stuff_size; /* Size of it. */ 378218822Sdim int c_ucode; /* Exception no. from u_code. */ 379218822Sdim}; 38033965Sjdp 381218822Sdim/* Byte-swap in the Sun-3 core structure. */ 38233965Sjdp 38333965Sjdpstatic void 384218822Sdimswapcore_sun3 (bfd *abfd, char *ext, struct internal_sunos_core *intcore) 38533965Sjdp{ 38633965Sjdp struct external_sun3_core *extcore = (struct external_sun3_core *) ext; 38733965Sjdp 38889857Sobrien intcore->c_magic = H_GET_32 (abfd, &extcore->c_magic); 38989857Sobrien intcore->c_len = H_GET_32 (abfd, &extcore->c_len); 390218822Sdim intcore->c_regs_pos = offsetof (struct external_sun3_core, c_regs); 39133965Sjdp intcore->c_regs_size = sizeof (extcore->c_regs); 39233965Sjdp#if ARCH_SIZE == 64 39333965Sjdp aout_64_swap_exec_header_in 39433965Sjdp#else 39533965Sjdp aout_32_swap_exec_header_in 39633965Sjdp#endif 39733965Sjdp (abfd, &extcore->c_aouthdr, &intcore->c_aouthdr); 39889857Sobrien intcore->c_signo = H_GET_32 (abfd, &extcore->c_signo); 39989857Sobrien intcore->c_tsize = H_GET_32 (abfd, &extcore->c_tsize); 40089857Sobrien intcore->c_dsize = H_GET_32 (abfd, &extcore->c_dsize); 40133965Sjdp intcore->c_data_addr = N_DATADDR (intcore->c_aouthdr); 40289857Sobrien intcore->c_ssize = H_GET_32 (abfd, &extcore->c_ssize); 40333965Sjdp memcpy (intcore->c_cmdname, extcore->c_cmdname, sizeof (intcore->c_cmdname)); 404218822Sdim intcore->fp_stuff_pos = offsetof (struct external_sun3_core, fp_stuff); 40577298Sobrien /* FP stuff takes up whole rest of struct, except c_ucode. */ 40633965Sjdp intcore->fp_stuff_size = intcore->c_len - (sizeof extcore->c_ucode) - 407218822Sdim offsetof (struct external_sun3_core, fp_stuff); 408218822Sdim /* Ucode is the last thing in the struct -- just before the end. */ 40989857Sobrien intcore->c_ucode = H_GET_32 (abfd, 41089857Sobrien (intcore->c_len 41189857Sobrien - sizeof (extcore->c_ucode) 41289857Sobrien + (unsigned char *) extcore)); 413218822Sdim intcore->c_stacktop = 0x0E000000; /* By experimentation. */ 41433965Sjdp} 41533965Sjdp 416218822Sdim/* Byte-swap in the Sparc core structure. */ 417218822Sdim 41833965Sjdpstatic void 419218822Sdimswapcore_sparc (bfd *abfd, char *ext, struct internal_sunos_core *intcore) 42033965Sjdp{ 42133965Sjdp struct external_sparc_core *extcore = (struct external_sparc_core *) ext; 42233965Sjdp 42389857Sobrien intcore->c_magic = H_GET_32 (abfd, &extcore->c_magic); 42489857Sobrien intcore->c_len = H_GET_32 (abfd, &extcore->c_len); 425218822Sdim intcore->c_regs_pos = offsetof (struct external_sparc_core, c_regs); 42633965Sjdp intcore->c_regs_size = sizeof (extcore->c_regs); 42733965Sjdp#if ARCH_SIZE == 64 42833965Sjdp aout_64_swap_exec_header_in 42933965Sjdp#else 43033965Sjdp aout_32_swap_exec_header_in 43133965Sjdp#endif 43233965Sjdp (abfd, &extcore->c_aouthdr, &intcore->c_aouthdr); 43389857Sobrien intcore->c_signo = H_GET_32 (abfd, &extcore->c_signo); 43489857Sobrien intcore->c_tsize = H_GET_32 (abfd, &extcore->c_tsize); 43589857Sobrien intcore->c_dsize = H_GET_32 (abfd, &extcore->c_dsize); 43633965Sjdp intcore->c_data_addr = N_DATADDR (intcore->c_aouthdr); 43789857Sobrien intcore->c_ssize = H_GET_32 (abfd, &extcore->c_ssize); 43833965Sjdp memcpy (intcore->c_cmdname, extcore->c_cmdname, sizeof (intcore->c_cmdname)); 439218822Sdim intcore->fp_stuff_pos = offsetof (struct external_sparc_core, fp_stuff); 44077298Sobrien /* FP stuff takes up whole rest of struct, except c_ucode. */ 44133965Sjdp intcore->fp_stuff_size = intcore->c_len - (sizeof extcore->c_ucode) - 442218822Sdim offsetof (struct external_sparc_core, fp_stuff); 443218822Sdim /* Ucode is the last thing in the struct -- just before the end. */ 44489857Sobrien intcore->c_ucode = H_GET_32 (abfd, 44589857Sobrien (intcore->c_len 44689857Sobrien - sizeof (extcore->c_ucode) 44789857Sobrien + (unsigned char *) extcore)); 44833965Sjdp 44933965Sjdp /* Supposedly the user stack grows downward from the bottom of kernel memory. 45033965Sjdp Presuming that this remains true, this definition will work. */ 45133965Sjdp /* Now sun has provided us with another challenge. The value is different 45233965Sjdp for sparc2 and sparc10 (both running SunOS 4.1.3). We pick one or 45333965Sjdp the other based on the current value of the stack pointer. This 45433965Sjdp loses (a) if the stack pointer has been clobbered, or (b) if the stack 45533965Sjdp is larger than 128 megabytes. 45633965Sjdp 45733965Sjdp It's times like these you're glad they're switching to ELF. 45833965Sjdp 45933965Sjdp Note that using include files or nlist on /vmunix would be wrong, 46033965Sjdp because we want the value for this core file, no matter what kind of 46133965Sjdp machine we were compiled on or are running on. */ 46233965Sjdp#define SPARC_USRSTACK_SPARC2 ((bfd_vma)0xf8000000) 46333965Sjdp#define SPARC_USRSTACK_SPARC10 ((bfd_vma)0xf0000000) 46433965Sjdp { 465218822Sdim bfd_vma sp = H_GET_32 (abfd, &extcore->c_regs.r_o6); 46633965Sjdp if (sp < SPARC_USRSTACK_SPARC10) 46733965Sjdp intcore->c_stacktop = SPARC_USRSTACK_SPARC10; 46833965Sjdp else 46933965Sjdp intcore->c_stacktop = SPARC_USRSTACK_SPARC2; 47033965Sjdp } 47133965Sjdp} 47233965Sjdp 473218822Sdim/* Byte-swap in the Solaris BCP core structure. */ 474218822Sdim 47533965Sjdpstatic void 476218822Sdimswapcore_solaris_bcp (bfd *abfd, char *ext, struct internal_sunos_core *intcore) 47733965Sjdp{ 47833965Sjdp struct external_solaris_bcp_core *extcore = 47933965Sjdp (struct external_solaris_bcp_core *) ext; 48033965Sjdp 48189857Sobrien intcore->c_magic = H_GET_32 (abfd, &extcore->c_magic); 48289857Sobrien intcore->c_len = H_GET_32 (abfd, &extcore->c_len); 483218822Sdim intcore->c_regs_pos = offsetof (struct external_solaris_bcp_core, c_regs); 48433965Sjdp intcore->c_regs_size = sizeof (extcore->c_regs); 48533965Sjdp 48633965Sjdp /* The Solaris BCP exdata structure does not contain an a_syms field, 48733965Sjdp so we are unable to synthesize an internal exec header. 48833965Sjdp Luckily we are able to figure out the start address of the data section, 48933965Sjdp which is the only thing needed from the internal exec header, 49033965Sjdp from the exdata structure. 49133965Sjdp 49233965Sjdp As of Solaris 2.3, BCP core files for statically linked executables 49333965Sjdp are buggy. The exdata structure is not properly filled in, and 49433965Sjdp the data section is written from address zero instead of the data 49533965Sjdp start address. */ 496218822Sdim memset ((void *) &intcore->c_aouthdr, 0, sizeof (struct internal_exec)); 49789857Sobrien intcore->c_data_addr = H_GET_32 (abfd, &extcore->c_exdata_datorg); 49889857Sobrien intcore->c_signo = H_GET_32 (abfd, &extcore->c_signo); 49989857Sobrien intcore->c_tsize = H_GET_32 (abfd, &extcore->c_tsize); 50089857Sobrien intcore->c_dsize = H_GET_32 (abfd, &extcore->c_dsize); 50189857Sobrien intcore->c_ssize = H_GET_32 (abfd, &extcore->c_ssize); 50233965Sjdp memcpy (intcore->c_cmdname, extcore->c_cmdname, sizeof (intcore->c_cmdname)); 50333965Sjdp intcore->fp_stuff_pos = 504218822Sdim offsetof (struct external_solaris_bcp_core, fp_stuff); 50577298Sobrien /* FP stuff takes up whole rest of struct, except c_ucode. */ 50633965Sjdp intcore->fp_stuff_size = intcore->c_len - (sizeof extcore->c_ucode) - 507218822Sdim offsetof (struct external_solaris_bcp_core, fp_stuff); 50833965Sjdp /* Ucode is the last thing in the struct -- just before the end */ 50989857Sobrien intcore->c_ucode = H_GET_32 (abfd, 51089857Sobrien (intcore->c_len 51189857Sobrien - sizeof (extcore->c_ucode) 51289857Sobrien + (unsigned char *) extcore)); 51333965Sjdp 51433965Sjdp /* Supposedly the user stack grows downward from the bottom of kernel memory. 51533965Sjdp Presuming that this remains true, this definition will work. */ 51633965Sjdp /* Now sun has provided us with another challenge. The value is different 51733965Sjdp for sparc2 and sparc10 (both running SunOS 4.1.3). We pick one or 51833965Sjdp the other based on the current value of the stack pointer. This 51933965Sjdp loses (a) if the stack pointer has been clobbered, or (b) if the stack 52033965Sjdp is larger than 128 megabytes. 52133965Sjdp 52233965Sjdp It's times like these you're glad they're switching to ELF. 52333965Sjdp 52433965Sjdp Note that using include files or nlist on /vmunix would be wrong, 52533965Sjdp because we want the value for this core file, no matter what kind of 52633965Sjdp machine we were compiled on or are running on. */ 52733965Sjdp#define SPARC_USRSTACK_SPARC2 ((bfd_vma)0xf8000000) 52833965Sjdp#define SPARC_USRSTACK_SPARC10 ((bfd_vma)0xf0000000) 52933965Sjdp { 530218822Sdim bfd_vma sp = H_GET_32 (abfd, &extcore->c_regs.r_o6); 53133965Sjdp if (sp < SPARC_USRSTACK_SPARC10) 53233965Sjdp intcore->c_stacktop = SPARC_USRSTACK_SPARC10; 53333965Sjdp else 53433965Sjdp intcore->c_stacktop = SPARC_USRSTACK_SPARC2; 53533965Sjdp } 53633965Sjdp} 53733965Sjdp 538218822Sdim/* Need this cast because ptr is really void *. */ 539218822Sdim#define core_hdr(bfd) ((bfd)->tdata.sun_core_data) 540218822Sdim#define core_datasec(bfd) (core_hdr (bfd)->data_section) 541218822Sdim#define core_stacksec(bfd) (core_hdr (bfd)->stack_section) 542218822Sdim#define core_regsec(bfd) (core_hdr (bfd)->reg_section) 543218822Sdim#define core_reg2sec(bfd) (core_hdr (bfd)->reg2_section) 54433965Sjdp 545218822Sdim/* These are stored in the bfd's tdata. */ 54633965Sjdpstruct sun_core_struct 54733965Sjdp{ 548218822Sdim struct internal_sunos_core *hdr; /* Core file header. */ 54933965Sjdp asection *data_section; 55033965Sjdp asection *stack_section; 55133965Sjdp asection *reg_section; 55233965Sjdp asection *reg2_section; 55333965Sjdp}; 55433965Sjdp 55533965Sjdpstatic const bfd_target * 556218822Sdimsunos4_core_file_p (bfd *abfd) 55733965Sjdp{ 558218822Sdim unsigned char longbuf[4]; /* Raw bytes of various header fields. */ 55989857Sobrien bfd_size_type core_size, amt; 56033965Sjdp unsigned long core_mag; 56133965Sjdp struct internal_sunos_core *core; 56233965Sjdp char *extcore; 56333965Sjdp struct mergem 56433965Sjdp { 56533965Sjdp struct sun_core_struct suncoredata; 56633965Sjdp struct internal_sunos_core internal_sunos_core; 56733965Sjdp char external_core[1]; 56889857Sobrien } *mergem; 569218822Sdim flagword flags; 57033965Sjdp 571218822Sdim if (bfd_bread ((void *) longbuf, (bfd_size_type) sizeof (longbuf), abfd) 57289857Sobrien != sizeof (longbuf)) 573218822Sdim return NULL; 57489857Sobrien core_mag = H_GET_32 (abfd, longbuf); 57533965Sjdp 57633965Sjdp if (core_mag != CORE_MAGIC) 577218822Sdim return NULL; 57833965Sjdp 57933965Sjdp /* SunOS core headers can vary in length; second word is size; */ 580218822Sdim if (bfd_bread ((void *) longbuf, (bfd_size_type) sizeof (longbuf), abfd) 58189857Sobrien != sizeof (longbuf)) 582218822Sdim return NULL; 58389857Sobrien core_size = H_GET_32 (abfd, longbuf); 584218822Sdim /* Sanity check. */ 58533965Sjdp if (core_size > 20000) 586218822Sdim return NULL; 58733965Sjdp 58889857Sobrien if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0) 589218822Sdim return NULL; 59033965Sjdp 59189857Sobrien amt = core_size + sizeof (struct mergem); 592218822Sdim mergem = bfd_zalloc (abfd, amt); 59333965Sjdp if (mergem == NULL) 594218822Sdim return NULL; 59533965Sjdp 59633965Sjdp extcore = mergem->external_core; 59733965Sjdp 598218822Sdim if ((bfd_bread ((void *) extcore, core_size, abfd)) != core_size) 59933965Sjdp { 60089857Sobrien loser: 60133965Sjdp bfd_release (abfd, (char *) mergem); 60289857Sobrien abfd->tdata.any = NULL; 60389857Sobrien bfd_section_list_clear (abfd); 604218822Sdim return NULL; 60533965Sjdp } 60633965Sjdp 60733965Sjdp /* Validate that it's a core file we know how to handle, due to sun 60833965Sjdp botching the positioning of registers and other fields in a machine 60933965Sjdp dependent way. */ 61033965Sjdp core = &mergem->internal_sunos_core; 61133965Sjdp switch (core_size) 61233965Sjdp { 61333965Sjdp case SPARC_CORE_LEN: 61433965Sjdp swapcore_sparc (abfd, extcore, core); 61533965Sjdp break; 61633965Sjdp case SUN3_CORE_LEN: 61733965Sjdp swapcore_sun3 (abfd, extcore, core); 61833965Sjdp break; 61933965Sjdp case SOLARIS_BCP_CORE_LEN: 62033965Sjdp swapcore_solaris_bcp (abfd, extcore, core); 62133965Sjdp break; 62233965Sjdp default: 623218822Sdim bfd_set_error (bfd_error_system_call); /* FIXME. */ 62489857Sobrien goto loser; 62533965Sjdp } 62633965Sjdp 62733965Sjdp abfd->tdata.sun_core_data = &mergem->suncoredata; 62833965Sjdp abfd->tdata.sun_core_data->hdr = core; 62933965Sjdp 63089857Sobrien /* Create the sections. */ 631218822Sdim flags = SEC_ALLOC + SEC_LOAD + SEC_HAS_CONTENTS; 632218822Sdim core_stacksec (abfd) = bfd_make_section_anyway_with_flags (abfd, ".stack", 633218822Sdim flags); 63433965Sjdp if (core_stacksec (abfd) == NULL) 63589857Sobrien /* bfd_release frees everything allocated after it's arg. */ 63689857Sobrien goto loser; 63789857Sobrien 638218822Sdim flags = SEC_ALLOC + SEC_LOAD + SEC_HAS_CONTENTS; 639218822Sdim core_datasec (abfd) = bfd_make_section_anyway_with_flags (abfd, ".data", 640218822Sdim flags); 64133965Sjdp if (core_datasec (abfd) == NULL) 64289857Sobrien goto loser; 64389857Sobrien 644218822Sdim flags = SEC_HAS_CONTENTS; 645218822Sdim core_regsec (abfd) = bfd_make_section_anyway_with_flags (abfd, ".reg", 646218822Sdim flags); 64733965Sjdp if (core_regsec (abfd) == NULL) 64889857Sobrien goto loser; 64989857Sobrien 650218822Sdim flags = SEC_HAS_CONTENTS; 651218822Sdim core_reg2sec (abfd) = bfd_make_section_anyway_with_flags (abfd, ".reg2", 652218822Sdim flags); 65333965Sjdp if (core_reg2sec (abfd) == NULL) 65489857Sobrien goto loser; 65533965Sjdp 656218822Sdim core_stacksec (abfd)->size = core->c_ssize; 657218822Sdim core_datasec (abfd)->size = core->c_dsize; 658218822Sdim core_regsec (abfd)->size = core->c_regs_size; 659218822Sdim core_reg2sec (abfd)->size = core->fp_stuff_size; 66033965Sjdp 66133965Sjdp core_stacksec (abfd)->vma = (core->c_stacktop - core->c_ssize); 66233965Sjdp core_datasec (abfd)->vma = core->c_data_addr; 66333965Sjdp core_regsec (abfd)->vma = 0; 66433965Sjdp core_reg2sec (abfd)->vma = 0; 66533965Sjdp 66633965Sjdp core_stacksec (abfd)->filepos = core->c_len + core->c_dsize; 66733965Sjdp core_datasec (abfd)->filepos = core->c_len; 668218822Sdim /* We'll access the regs afresh in the core file, like any section: */ 66933965Sjdp core_regsec (abfd)->filepos = (file_ptr) core->c_regs_pos; 67033965Sjdp core_reg2sec (abfd)->filepos = (file_ptr) core->fp_stuff_pos; 67133965Sjdp 672218822Sdim /* Align to word at least. */ 67333965Sjdp core_stacksec (abfd)->alignment_power = 2; 67433965Sjdp core_datasec (abfd)->alignment_power = 2; 67533965Sjdp core_regsec (abfd)->alignment_power = 2; 67633965Sjdp core_reg2sec (abfd)->alignment_power = 2; 67733965Sjdp 67833965Sjdp return abfd->xvec; 67933965Sjdp} 68033965Sjdp 68133965Sjdpstatic char * 682218822Sdimsunos4_core_file_failing_command (bfd *abfd) 68333965Sjdp{ 68433965Sjdp return core_hdr (abfd)->hdr->c_cmdname; 68533965Sjdp} 68633965Sjdp 68733965Sjdpstatic int 688218822Sdimsunos4_core_file_failing_signal (bfd *abfd) 68933965Sjdp{ 69033965Sjdp return core_hdr (abfd)->hdr->c_signo; 69133965Sjdp} 69233965Sjdp 693130561Sobrienstatic bfd_boolean 694218822Sdimsunos4_core_file_matches_executable_p (bfd *core_bfd, bfd *exec_bfd) 69533965Sjdp{ 69633965Sjdp if (core_bfd->xvec != exec_bfd->xvec) 69733965Sjdp { 69833965Sjdp bfd_set_error (bfd_error_system_call); 699130561Sobrien return FALSE; 70033965Sjdp } 70133965Sjdp 70277298Sobrien /* Solaris core files do not include an aouthdr. */ 70333965Sjdp if ((core_hdr (core_bfd)->hdr)->c_len == SOLARIS_BCP_CORE_LEN) 704130561Sobrien return TRUE; 70533965Sjdp 706218822Sdim return memcmp ((char *) &((core_hdr (core_bfd)->hdr)->c_aouthdr), 707218822Sdim (char *) exec_hdr (exec_bfd), 708218822Sdim sizeof (struct internal_exec)) == 0; 70933965Sjdp} 71033965Sjdp 71133965Sjdp#define MY_set_sizes sunos4_set_sizes 712218822Sdim 713130561Sobrienstatic bfd_boolean 714218822Sdimsunos4_set_sizes (bfd *abfd) 71533965Sjdp{ 71633965Sjdp switch (bfd_get_arch (abfd)) 71733965Sjdp { 71833965Sjdp default: 719130561Sobrien return FALSE; 72033965Sjdp case bfd_arch_sparc: 72133965Sjdp adata (abfd).page_size = 0x2000; 72233965Sjdp adata (abfd).segment_size = 0x2000; 72333965Sjdp adata (abfd).exec_bytes_size = EXEC_BYTES_SIZE; 724130561Sobrien return TRUE; 72533965Sjdp case bfd_arch_m68k: 72633965Sjdp adata (abfd).page_size = 0x2000; 72733965Sjdp adata (abfd).segment_size = 0x20000; 72833965Sjdp adata (abfd).exec_bytes_size = EXEC_BYTES_SIZE; 729130561Sobrien return TRUE; 73033965Sjdp } 73133965Sjdp} 73233965Sjdp 73333965Sjdp/* We default to setting the toolversion field to 1, as is required by 73433965Sjdp SunOS. */ 73533965Sjdp#ifndef MY_exec_hdr_flags 73633965Sjdp#define MY_exec_hdr_flags 1 73733965Sjdp#endif 73833965Sjdp 73933965Sjdp#ifndef MY_entry_is_text_address 74033965Sjdp#define MY_entry_is_text_address 0 74133965Sjdp#endif 74233965Sjdp#ifndef MY_add_dynamic_symbols 74333965Sjdp#define MY_add_dynamic_symbols 0 74433965Sjdp#endif 74533965Sjdp#ifndef MY_add_one_symbol 74633965Sjdp#define MY_add_one_symbol 0 74733965Sjdp#endif 74833965Sjdp#ifndef MY_link_dynamic_object 74933965Sjdp#define MY_link_dynamic_object 0 75033965Sjdp#endif 75133965Sjdp#ifndef MY_write_dynamic_symbol 75233965Sjdp#define MY_write_dynamic_symbol 0 75333965Sjdp#endif 75433965Sjdp#ifndef MY_check_dynamic_reloc 75533965Sjdp#define MY_check_dynamic_reloc 0 75633965Sjdp#endif 75733965Sjdp#ifndef MY_finish_dynamic_link 75833965Sjdp#define MY_finish_dynamic_link 0 75933965Sjdp#endif 76033965Sjdp 76189857Sobrienstatic const struct aout_backend_data sunos4_aout_backend = 76233965Sjdp{ 763218822Sdim 0, /* Zmagic files are not contiguous. */ 764218822Sdim 1, /* Text includes header. */ 76533965Sjdp MY_entry_is_text_address, 76633965Sjdp MY_exec_hdr_flags, 767218822Sdim 0, /* Default text vma. */ 76833965Sjdp sunos4_set_sizes, 769218822Sdim 0, /* Header is counted in zmagic text. */ 77033965Sjdp MY_add_dynamic_symbols, 77133965Sjdp MY_add_one_symbol, 77233965Sjdp MY_link_dynamic_object, 77333965Sjdp MY_write_dynamic_symbol, 77433965Sjdp MY_check_dynamic_reloc, 77533965Sjdp MY_finish_dynamic_link 77633965Sjdp}; 77733965Sjdp 77833965Sjdp#define MY_core_file_failing_command sunos4_core_file_failing_command 77933965Sjdp#define MY_core_file_failing_signal sunos4_core_file_failing_signal 78033965Sjdp#define MY_core_file_matches_executable_p sunos4_core_file_matches_executable_p 78133965Sjdp 78233965Sjdp#define MY_bfd_debug_info_start bfd_void 78333965Sjdp#define MY_bfd_debug_info_end bfd_void 784218822Sdim#define MY_bfd_debug_info_accumulate (void (*) (bfd *, struct bfd_section *)) bfd_void 78533965Sjdp#define MY_core_file_p sunos4_core_file_p 786218822Sdim#define MY_write_object_contents NAME(aout, sunos4_write_object_contents) 787218822Sdim#define MY_backend_data & sunos4_aout_backend 78833965Sjdp 78933965Sjdp#ifndef TARGET_IS_LITTLE_ENDIAN_P 79033965Sjdp#define TARGET_IS_BIG_ENDIAN_P 79133965Sjdp#endif 79233965Sjdp 79333965Sjdp#include "aout-target.h" 794