X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=bfd%2Faoutf1.h;h=993a637060758bc3a03ab6933b180b023233e09d;hb=651dbc76f217e10b4b03933f86fe9e5b39d382be;hp=d78de7f6cca4186dcda654417fea9d26855c5ba2;hpb=9ae74960a87e149d8deaa40ce0cfed81486ae160;p=deliverable%2Fbinutils-gdb.git diff --git a/bfd/aoutf1.h b/bfd/aoutf1.h index d78de7f6cc..993a637060 100644 --- a/bfd/aoutf1.h +++ b/bfd/aoutf1.h @@ -1,29 +1,32 @@ /* A.out "format 1" file handling code for BFD. - Copyright 1990, 1991, 1992, 1993 Free Software Foundation, Inc. + Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 2000, + 2001, 2002, 2003, 2004, 2005, 2006, 2007 + Free Software Foundation, Inc. Written by Cygnus Support. -This file is part of BFD, the Binary File Descriptor library. + This file is part of BFD, the Binary File Descriptor library. -This program 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 2 of the License, or -(at your option) any later version. + This program 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 3 of the License, or + (at your option) any later version. -This program 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. + This program 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 this program; if not, write to the Free Software -Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, + MA 02110-1301, USA. */ -#include "bfd.h" #include "sysdep.h" +#include "bfd.h" #include "libbfd.h" #include "aout/sun4.h" -#include "libaout.h" /* BFD a.out internal data structures */ +#include "libaout.h" /* BFD a.out internal data structures. */ #include "aout/aout64.h" #include "aout/stab_gnu.h" @@ -32,70 +35,92 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* This is needed to reject a NewsOS file, e.g. in gdb/testsuite/gdb.t10/crossload.exp. I needed to add M_UNKNOWN to recognize a 68000 object, so this will - probably no longer reject a NewsOS object. . */ -#define MACHTYPE_OK(mtype) ((mtype) == M_UNKNOWN \ - || (mtype) == M_68010 \ - || (mtype) == M_68020 \ - || (mtype) == M_SPARC) - -/* -The file @code{aoutf1.h} contains the code for BFD's -a.out back end. Control over the generated back end is given by these -two preprocessor names: -@table @code -@item ARCH_SIZE -This value should be either 32 or 64, depending upon the size of an -int in the target format. It changes the sizes of the structs which -perform the memory/disk mapping of structures. - -The 64 bit backend may only be used if the host compiler supports 64 -ints (eg long long with gcc), by defining the name @code{BFD_HOST_64_BIT} in @code{bfd.h}. -With this name defined, @emph{all} bfd operations are performed with 64bit -arithmetic, not just those to a 64bit target. - -@item TARGETNAME -The name put into the target vector. -@item -@end table - -*/ - -/*SUPPRESS558*/ -/*SUPPRESS529*/ + probably no longer reject a NewsOS object. . */ +#ifndef MACHTYPE_OK +#define MACHTYPE_OK(mtype) \ + (((mtype) == M_SPARC && bfd_lookup_arch (bfd_arch_sparc, 0) != NULL) \ + || (((mtype) == M_UNKNOWN || (mtype) == M_68010 || (mtype) == M_68020) \ + && bfd_lookup_arch (bfd_arch_m68k, 0) != NULL)) +#endif + +/* The file @code{aoutf1.h} contains the code for BFD's + a.out back end. Control over the generated back end is given by these + two preprocessor names: + @table @code + @item ARCH_SIZE + This value should be either 32 or 64, depending upon the size of an + int in the target format. It changes the sizes of the structs which + perform the memory/disk mapping of structures. + + The 64 bit backend may only be used if the host compiler supports 64 + ints (eg long long with gcc), by defining the name @code{BFD_HOST_64_BIT} in @code{bfd.h}. + With this name defined, @emph{all} bfd operations are performed with 64bit + arithmetic, not just those to a 64bit target. + + @item TARGETNAME + The name put into the target vector. + @item + @end table. */ -static void #if ARCH_SIZE == 64 -sunos_64_set_arch_mach +#define sunos_set_arch_mach sunos_64_set_arch_mach +#define sunos_write_object_contents aout_64_sunos4_write_object_contents #else -sunos_32_set_arch_mach +#define sunos_set_arch_mach sunos_32_set_arch_mach +#define sunos_write_object_contents aout_32_sunos4_write_object_contents #endif - (abfd, machtype) - bfd *abfd; - int machtype; + +/* Merge backend data into the output file. + This is necessary on sparclet-aout where we want the resultant machine + number to be M_SPARCLET if any input file is M_SPARCLET. */ + +#define MY_bfd_merge_private_bfd_data sunos_merge_private_bfd_data + +static bfd_boolean +sunos_merge_private_bfd_data (bfd *ibfd, bfd *obfd) +{ + if (bfd_get_flavour (ibfd) != bfd_target_aout_flavour + || bfd_get_flavour (obfd) != bfd_target_aout_flavour) + return TRUE; + + if (bfd_get_arch (obfd) == bfd_arch_sparc) + { + if (bfd_get_mach (obfd) < bfd_get_mach (ibfd)) + bfd_set_arch_mach (obfd, bfd_arch_sparc, bfd_get_mach (ibfd)); + } + + return TRUE; +} + +/* This is either sunos_32_set_arch_mach or sunos_64_set_arch_mach, + depending upon ARCH_SIZE. */ + +static void +sunos_set_arch_mach (bfd *abfd, enum machine_type machtype) { /* Determine the architecture and machine type of the object file. */ enum bfd_architecture arch; - long machine; + unsigned long machine; + switch (machtype) { - case M_UNKNOWN: /* Some Sun3s make magic numbers without cpu types in them, so - we'll default to the 68000. */ + we'll default to the 68000. */ arch = bfd_arch_m68k; - machine = 68000; + machine = bfd_mach_m68000; break; case M_68010: case M_HP200: arch = bfd_arch_m68k; - machine = 68010; + machine = bfd_mach_m68010; break; case M_68020: case M_HP300: arch = bfd_arch_m68k; - machine = 68020; + machine = bfd_mach_m68020; break; case M_SPARC: @@ -103,17 +128,22 @@ sunos_32_set_arch_mach machine = 0; break; + case M_SPARCLET: + arch = bfd_arch_sparc; + machine = bfd_mach_sparc_sparclet; + break; + + case M_SPARCLITE_LE: + arch = bfd_arch_sparc; + machine = bfd_mach_sparc_sparclite_le; + break; + case M_386: case M_386_DYNIX: arch = bfd_arch_i386; machine = 0; break; - case M_29K: - arch = bfd_arch_a29k; - machine = 0; - break; - case M_HPUX: arch = bfd_arch_m68k; machine = 0; @@ -128,18 +158,17 @@ sunos_32_set_arch_mach } #define SET_ARCH_MACH(ABFD, EXEC) \ - NAME(sunos,set_arch_mach)(ABFD, N_MACHTYPE (EXEC)); \ + NAME(sunos,set_arch_mach) (ABFD, N_MACHTYPE (EXEC)); \ choose_reloc_size(ABFD); -/* Determine the size of a relocation entry, based on the architecture */ +/* Determine the size of a relocation entry, based on the architecture. */ + static void -choose_reloc_size (abfd) - bfd *abfd; +choose_reloc_size (bfd *abfd) { switch (bfd_get_arch (abfd)) { case bfd_arch_sparc: - case bfd_arch_a29k: obj_reloc_entry_size (abfd) = RELOC_EXT_SIZE; break; default: @@ -148,18 +177,14 @@ choose_reloc_size (abfd) } } -/* Write an object file in SunOS format. - Section contents have already been written. We write the - file header, symbols, and relocation. */ +/* Write an object file in SunOS format. Section contents have + already been written. We write the file header, symbols, and + relocation. The real name of this function is either + aout_64_sunos4_write_object_contents or + aout_32_sunos4_write_object_contents, depending upon ARCH_SIZE. */ -static boolean -#if ARCH_SIZE == 64 -aout_64_sunos4_write_object_contents -#else -aout_32_sunos4_write_object_contents -#endif - (abfd) - bfd *abfd; +static bfd_boolean +sunos_write_object_contents (bfd *abfd) { struct external_exec exec_bytes; struct internal_exec *execp = exec_hdr (abfd); @@ -170,27 +195,35 @@ aout_32_sunos4_write_object_contents case bfd_arch_m68k: switch (bfd_get_mach (abfd)) { - case 68000: + case bfd_mach_m68000: N_SET_MACHTYPE (*execp, M_UNKNOWN); break; - case 68010: + case bfd_mach_m68010: N_SET_MACHTYPE (*execp, M_68010); break; default: - case 68020: + case bfd_mach_m68020: N_SET_MACHTYPE (*execp, M_68020); break; } break; case bfd_arch_sparc: - N_SET_MACHTYPE (*execp, M_SPARC); + switch (bfd_get_mach (abfd)) + { + case bfd_mach_sparc_sparclet: + N_SET_MACHTYPE (*execp, M_SPARCLET); + break; + case bfd_mach_sparc_sparclite_le: + N_SET_MACHTYPE (*execp, M_SPARCLITE_LE); + break; + default: + N_SET_MACHTYPE (*execp, M_SPARC); + break; + } 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); } @@ -199,27 +232,27 @@ aout_32_sunos4_write_object_contents N_SET_FLAGS (*execp, aout_backend_info (abfd)->exec_hdr_flags); - N_SET_DYNAMIC (*execp, bfd_get_file_flags (abfd) & DYNAMIC); + N_SET_DYNAMIC (*execp, (long)(bfd_get_file_flags (abfd) & DYNAMIC)); WRITE_HEADERS (abfd, execp); - return true; + return TRUE; } -/* core files */ +/* Core files. */ -#define CORE_MAGIC 0x080456 +#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. */ + 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. */ + the same info. */ struct regs { int r_psr; @@ -250,77 +283,112 @@ struct regs even portably access the stuff in between! */ struct external_sparc_core - { - int c_magic; /* Corefile magic number */ - int c_len; /* Sizeof (struct core) */ +{ + int c_magic; /* Corefile magic number. */ + int c_len; /* Sizeof (struct core). */ #define SPARC_CORE_LEN 432 - int c_regs[19]; /* General purpose registers -- MACHDEP SIZE */ - struct external_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.) */ - }; + struct regs c_regs; /* General purpose registers -- MACHDEP SIZE. */ + struct external_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. */ +}; + +/* Core files generated by the BCP (the part of Solaris which allows + it to run SunOS4 a.out files). */ +struct external_solaris_bcp_core +{ + int c_magic; /* Corefile magic number. */ + int c_len; /* Sizeof (struct core). */ +#define SOLARIS_BCP_CORE_LEN 456 + struct regs c_regs; /* General purpose registers -- MACHDEP SIZE. */ + int c_exdata_vp; /* Exdata structure. */ + int c_exdata_tsize; + int c_exdata_dsize; + int c_exdata_bsize; + int c_exdata_lsize; + int c_exdata_nshlibs; + short c_exdata_mach; + short c_exdata_mag; + int c_exdata_toffset; + int c_exdata_doffset; + int c_exdata_loffset; + int c_exdata_txtorg; + int c_exdata_datorg; + int c_exdata_entloc; + 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. */ +}; struct external_sun3_core - { - int c_magic; /* Corefile magic number */ - int c_len; /* Sizeof (struct core) */ -#define SUN3_CORE_LEN 826 /* As of SunOS 4.1.1 */ - int c_regs[18]; /* General purpose registers -- MACHDEP SIZE */ - struct external_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.) */ - }; +{ + int c_magic; /* Corefile magic number. */ + int c_len; /* Sizeof (struct core). */ +#define SUN3_CORE_LEN 826 /* As of SunOS 4.1.1. */ + int c_regs[18]; /* General purpose registers -- MACHDEP SIZE. */ + struct external_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. */ +}; struct internal_sunos_core - { - int c_magic; /* Corefile magic number */ - int c_len; /* Sizeof (struct core) */ - long c_regs_pos; /* file offset of General purpose registers */ - int c_regs_size; /* size of General purpose registers */ - 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) */ - bfd_vma c_stacktop; /* Stack top (address) */ - char c_cmdname[CORE_NAMELEN + 1]; /* Command name */ - long fp_stuff_pos; /* file offset of external FPU state (regs) */ - int fp_stuff_size; /* Size of it */ - int c_ucode; /* Exception no. from u_code */ - }; - -/* byte-swap in the Sun-3 core structure */ +{ + int c_magic; /* Corefile magic number. */ + int c_len; /* Sizeof (struct core). */ + long c_regs_pos; /* File offset of General purpose registers. */ + int c_regs_size; /* Size of General purpose registers. */ + 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). */ + bfd_vma c_data_addr; /* Data start (address). */ + int c_ssize; /* Stack size (bytes). */ + bfd_vma c_stacktop; /* Stack top (address). */ + char c_cmdname[CORE_NAMELEN + 1]; /* Command name. */ + long fp_stuff_pos; /* File offset of external FPU state (regs). */ + int fp_stuff_size; /* Size of it. */ + int c_ucode; /* Exception no. from u_code. */ +}; + +/* Byte-swap in the Sun-3 core structure. */ + static void -swapcore_sun3 (abfd, ext, intcore) - bfd *abfd; - char *ext; - struct internal_sunos_core *intcore; +swapcore_sun3 (bfd *abfd, char *ext, struct internal_sunos_core *intcore) { struct external_sun3_core *extcore = (struct external_sun3_core *) ext; - intcore->c_magic = bfd_h_get_32 (abfd, (unsigned char *) &extcore->c_magic); - intcore->c_len = bfd_h_get_32 (abfd, (unsigned char *) &extcore->c_len); - intcore->c_regs_pos = (long) (((struct external_sun3_core *) 0)->c_regs); + intcore->c_magic = H_GET_32 (abfd, &extcore->c_magic); + intcore->c_len = H_GET_32 (abfd, &extcore->c_len); + intcore->c_regs_pos = offsetof (struct external_sun3_core, c_regs); intcore->c_regs_size = sizeof (extcore->c_regs); #if ARCH_SIZE == 64 aout_64_swap_exec_header_in @@ -328,35 +396,34 @@ swapcore_sun3 (abfd, ext, intcore) aout_32_swap_exec_header_in #endif (abfd, &extcore->c_aouthdr, &intcore->c_aouthdr); - intcore->c_signo = bfd_h_get_32 (abfd, (unsigned char *) &extcore->c_signo); - intcore->c_tsize = bfd_h_get_32 (abfd, (unsigned char *) &extcore->c_tsize); - intcore->c_dsize = bfd_h_get_32 (abfd, (unsigned char *) &extcore->c_dsize); - intcore->c_ssize = bfd_h_get_32 (abfd, (unsigned char *) &extcore->c_ssize); + intcore->c_signo = H_GET_32 (abfd, &extcore->c_signo); + intcore->c_tsize = H_GET_32 (abfd, &extcore->c_tsize); + intcore->c_dsize = H_GET_32 (abfd, &extcore->c_dsize); + intcore->c_data_addr = N_DATADDR (intcore->c_aouthdr); + intcore->c_ssize = H_GET_32 (abfd, &extcore->c_ssize); memcpy (intcore->c_cmdname, extcore->c_cmdname, sizeof (intcore->c_cmdname)); - intcore->fp_stuff_pos = (long) (((struct external_sun3_core *) 0)->fp_stuff); - /* FP stuff takes up whole rest of struct, except c_ucode. */ + intcore->fp_stuff_pos = offsetof (struct external_sun3_core, fp_stuff); + /* FP stuff takes up whole rest of struct, except c_ucode. */ intcore->fp_stuff_size = intcore->c_len - (sizeof extcore->c_ucode) - - (file_ptr) (((struct external_sun3_core *) 0)->fp_stuff); - /* Ucode is the last thing in the struct -- just before the end */ - intcore->c_ucode = - bfd_h_get_32 (abfd, - intcore->c_len - sizeof (extcore->c_ucode) + (unsigned char *) extcore); - intcore->c_stacktop = 0x0E000000; /* By experimentation */ + offsetof (struct external_sun3_core, fp_stuff); + /* Ucode is the last thing in the struct -- just before the end. */ + intcore->c_ucode = H_GET_32 (abfd, + (intcore->c_len + - sizeof (extcore->c_ucode) + + (unsigned char *) extcore)); + intcore->c_stacktop = 0x0E000000; /* By experimentation. */ } +/* Byte-swap in the Sparc core structure. */ -/* byte-swap in the Sparc core structure */ static void -swapcore_sparc (abfd, ext, intcore) - bfd *abfd; - char *ext; - struct internal_sunos_core *intcore; +swapcore_sparc (bfd *abfd, char *ext, struct internal_sunos_core *intcore) { struct external_sparc_core *extcore = (struct external_sparc_core *) ext; - intcore->c_magic = bfd_h_get_32 (abfd, (unsigned char *) &extcore->c_magic); - intcore->c_len = bfd_h_get_32 (abfd, (unsigned char *) &extcore->c_len); - intcore->c_regs_pos = (long) (((struct external_sparc_core *) 0)->c_regs); + intcore->c_magic = H_GET_32 (abfd, &extcore->c_magic); + intcore->c_len = H_GET_32 (abfd, &extcore->c_len); + intcore->c_regs_pos = offsetof (struct external_sparc_core, c_regs); intcore->c_regs_size = sizeof (extcore->c_regs); #if ARCH_SIZE == 64 aout_64_swap_exec_header_in @@ -364,19 +431,86 @@ swapcore_sparc (abfd, ext, intcore) aout_32_swap_exec_header_in #endif (abfd, &extcore->c_aouthdr, &intcore->c_aouthdr); - intcore->c_signo = bfd_h_get_32 (abfd, (unsigned char *) &extcore->c_signo); - intcore->c_tsize = bfd_h_get_32 (abfd, (unsigned char *) &extcore->c_tsize); - intcore->c_dsize = bfd_h_get_32 (abfd, (unsigned char *) &extcore->c_dsize); - intcore->c_ssize = bfd_h_get_32 (abfd, (unsigned char *) &extcore->c_ssize); + intcore->c_signo = H_GET_32 (abfd, &extcore->c_signo); + intcore->c_tsize = H_GET_32 (abfd, &extcore->c_tsize); + intcore->c_dsize = H_GET_32 (abfd, &extcore->c_dsize); + intcore->c_data_addr = N_DATADDR (intcore->c_aouthdr); + intcore->c_ssize = H_GET_32 (abfd, &extcore->c_ssize); + memcpy (intcore->c_cmdname, extcore->c_cmdname, sizeof (intcore->c_cmdname)); + intcore->fp_stuff_pos = offsetof (struct external_sparc_core, fp_stuff); + /* FP stuff takes up whole rest of struct, except c_ucode. */ + intcore->fp_stuff_size = intcore->c_len - (sizeof extcore->c_ucode) - + offsetof (struct external_sparc_core, fp_stuff); + /* Ucode is the last thing in the struct -- just before the end. */ + intcore->c_ucode = H_GET_32 (abfd, + (intcore->c_len + - sizeof (extcore->c_ucode) + + (unsigned char *) extcore)); + + /* Supposedly the user stack grows downward from the bottom of kernel memory. + Presuming that this remains true, this definition will work. */ + /* Now sun has provided us with another challenge. The value is different + for sparc2 and sparc10 (both running SunOS 4.1.3). We pick one or + the other based on the current value of the stack pointer. This + loses (a) if the stack pointer has been clobbered, or (b) if the stack + is larger than 128 megabytes. + + It's times like these you're glad they're switching to ELF. + + Note that using include files or nlist on /vmunix would be wrong, + because we want the value for this core file, no matter what kind of + machine we were compiled on or are running on. */ +#define SPARC_USRSTACK_SPARC2 ((bfd_vma)0xf8000000) +#define SPARC_USRSTACK_SPARC10 ((bfd_vma)0xf0000000) + { + bfd_vma sp = H_GET_32 (abfd, &extcore->c_regs.r_o6); + if (sp < SPARC_USRSTACK_SPARC10) + intcore->c_stacktop = SPARC_USRSTACK_SPARC10; + else + intcore->c_stacktop = SPARC_USRSTACK_SPARC2; + } +} + +/* Byte-swap in the Solaris BCP core structure. */ + +static void +swapcore_solaris_bcp (bfd *abfd, char *ext, struct internal_sunos_core *intcore) +{ + struct external_solaris_bcp_core *extcore = + (struct external_solaris_bcp_core *) ext; + + intcore->c_magic = H_GET_32 (abfd, &extcore->c_magic); + intcore->c_len = H_GET_32 (abfd, &extcore->c_len); + intcore->c_regs_pos = offsetof (struct external_solaris_bcp_core, c_regs); + intcore->c_regs_size = sizeof (extcore->c_regs); + + /* The Solaris BCP exdata structure does not contain an a_syms field, + so we are unable to synthesize an internal exec header. + Luckily we are able to figure out the start address of the data section, + which is the only thing needed from the internal exec header, + from the exdata structure. + + As of Solaris 2.3, BCP core files for statically linked executables + are buggy. The exdata structure is not properly filled in, and + the data section is written from address zero instead of the data + start address. */ + memset ((void *) &intcore->c_aouthdr, 0, sizeof (struct internal_exec)); + intcore->c_data_addr = H_GET_32 (abfd, &extcore->c_exdata_datorg); + intcore->c_signo = H_GET_32 (abfd, &extcore->c_signo); + intcore->c_tsize = H_GET_32 (abfd, &extcore->c_tsize); + intcore->c_dsize = H_GET_32 (abfd, &extcore->c_dsize); + intcore->c_ssize = H_GET_32 (abfd, &extcore->c_ssize); memcpy (intcore->c_cmdname, extcore->c_cmdname, sizeof (intcore->c_cmdname)); - intcore->fp_stuff_pos = (long) (((struct external_sparc_core *) 0)->fp_stuff); - /* FP stuff takes up whole rest of struct, except c_ucode. */ + intcore->fp_stuff_pos = + offsetof (struct external_solaris_bcp_core, fp_stuff); + /* FP stuff takes up whole rest of struct, except c_ucode. */ intcore->fp_stuff_size = intcore->c_len - (sizeof extcore->c_ucode) - - (file_ptr) (((struct external_sparc_core *) 0)->fp_stuff); + offsetof (struct external_solaris_bcp_core, fp_stuff); /* Ucode is the last thing in the struct -- just before the end */ - intcore->c_ucode = - bfd_h_get_32 (abfd, - intcore->c_len - sizeof (extcore->c_ucode) + (unsigned char *) extcore); + intcore->c_ucode = H_GET_32 (abfd, + (intcore->c_len + - sizeof (extcore->c_ucode) + + (unsigned char *) extcore)); /* Supposedly the user stack grows downward from the bottom of kernel memory. Presuming that this remains true, this definition will work. */ @@ -394,8 +528,7 @@ swapcore_sparc (abfd, ext, intcore) #define SPARC_USRSTACK_SPARC2 ((bfd_vma)0xf8000000) #define SPARC_USRSTACK_SPARC10 ((bfd_vma)0xf0000000) { - bfd_vma sp = bfd_h_get_32 - (abfd, (unsigned char *) &((struct regs *) &extcore->c_regs[0])->r_o6); + bfd_vma sp = H_GET_32 (abfd, &extcore->c_regs.r_o6); if (sp < SPARC_USRSTACK_SPARC10) intcore->c_stacktop = SPARC_USRSTACK_SPARC10; else @@ -403,30 +536,29 @@ swapcore_sparc (abfd, ext, intcore) } } -/* need this cast because ptr is really void * */ -#define core_hdr(bfd) ((bfd)->tdata.sun_core_data) -#define core_datasec(bfd) (core_hdr(bfd)->data_section) -#define core_stacksec(bfd) (core_hdr(bfd)->stack_section) -#define core_regsec(bfd) (core_hdr(bfd)->reg_section) -#define core_reg2sec(bfd) (core_hdr(bfd)->reg2_section) +/* Need this cast because ptr is really void *. */ +#define core_hdr(bfd) ((bfd)->tdata.sun_core_data) +#define core_datasec(bfd) (core_hdr (bfd)->data_section) +#define core_stacksec(bfd) (core_hdr (bfd)->stack_section) +#define core_regsec(bfd) (core_hdr (bfd)->reg_section) +#define core_reg2sec(bfd) (core_hdr (bfd)->reg2_section) -/* These are stored in the bfd's tdata */ +/* These are stored in the bfd's tdata. */ struct sun_core_struct { - struct internal_sunos_core *hdr; /* core file header */ + struct internal_sunos_core *hdr; /* Core file header. */ asection *data_section; asection *stack_section; asection *reg_section; asection *reg2_section; }; -static bfd_target * -sunos4_core_file_p (abfd) - bfd *abfd; +static const bfd_target * +sunos4_core_file_p (bfd *abfd) { - unsigned char longbuf[4]; /* Raw bytes of various header fields */ - int core_size; - int core_mag; + unsigned char longbuf[4]; /* Raw bytes of various header fields. */ + bfd_size_type core_size, amt; + unsigned long core_mag; struct internal_sunos_core *core; char *extcore; struct mergem @@ -434,42 +566,43 @@ sunos4_core_file_p (abfd) struct sun_core_struct suncoredata; struct internal_sunos_core internal_sunos_core; char external_core[1]; - } - *mergem; + } *mergem; + flagword flags; - if (bfd_read ((PTR) longbuf, 1, sizeof (longbuf), abfd) != - sizeof (longbuf)) - return 0; - core_mag = bfd_h_get_32 (abfd, longbuf); + if (bfd_bread ((void *) longbuf, (bfd_size_type) sizeof (longbuf), abfd) + != sizeof (longbuf)) + return NULL; + core_mag = H_GET_32 (abfd, longbuf); if (core_mag != CORE_MAGIC) - return 0; + return NULL; /* 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 (bfd_bread ((void *) longbuf, (bfd_size_type) sizeof (longbuf), abfd) + != sizeof (longbuf)) + return NULL; + core_size = H_GET_32 (abfd, longbuf); + /* Sanity check. */ if (core_size > 20000) - return 0; + return NULL; - if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) < 0) - return 0; + if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0) + return NULL; - mergem = (struct mergem *) bfd_zalloc (abfd, core_size + sizeof (struct mergem)); + amt = core_size + sizeof (struct mergem); + mergem = bfd_zalloc (abfd, amt); if (mergem == NULL) - { - bfd_set_error (bfd_error_no_memory); - return 0; - } + return NULL; extcore = mergem->external_core; - if ((bfd_read ((PTR) extcore, 1, core_size, abfd)) != core_size) + if ((bfd_bread ((void *) extcore, core_size, abfd)) != core_size) { + loser: bfd_release (abfd, (char *) mergem); - return 0; + abfd->tdata.any = NULL; + bfd_section_list_clear (abfd); + return NULL; } /* Validate that it's a core file we know how to handle, due to sun @@ -484,137 +617,117 @@ sunos4_core_file_p (abfd) case SUN3_CORE_LEN: swapcore_sun3 (abfd, extcore, core); break; + case SOLARIS_BCP_CORE_LEN: + swapcore_solaris_bcp (abfd, extcore, core); + break; default: - bfd_set_error (bfd_error_system_call); /* FIXME */ - bfd_release (abfd, (char *) mergem); - return 0; + bfd_set_error (bfd_error_system_call); /* FIXME. */ + goto loser; } abfd->tdata.sun_core_data = &mergem->suncoredata; abfd->tdata.sun_core_data->hdr = core; - /* create the sections. This is raunchy, but bfd_close wants to reclaim - them */ - core_stacksec (abfd) = (asection *) bfd_zalloc (abfd, sizeof (asection)); + /* Create the sections. */ + flags = SEC_ALLOC + SEC_LOAD + SEC_HAS_CONTENTS; + core_stacksec (abfd) = bfd_make_section_anyway_with_flags (abfd, ".stack", + flags); if (core_stacksec (abfd) == NULL) - { - loser: - bfd_set_error (bfd_error_no_memory); - bfd_release (abfd, (char *) mergem); - return 0; - } - core_datasec (abfd) = (asection *) bfd_zalloc (abfd, sizeof (asection)); + /* bfd_release frees everything allocated after it's arg. */ + goto loser; + + flags = SEC_ALLOC + SEC_LOAD + SEC_HAS_CONTENTS; + core_datasec (abfd) = bfd_make_section_anyway_with_flags (abfd, ".data", + flags); 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; - } + goto loser; - core_stacksec (abfd)->name = ".stack"; - core_datasec (abfd)->name = ".data"; - core_regsec (abfd)->name = ".reg"; - core_reg2sec (abfd)->name = ".reg2"; + flags = SEC_HAS_CONTENTS; + core_regsec (abfd) = bfd_make_section_anyway_with_flags (abfd, ".reg", + flags); + if (core_regsec (abfd) == NULL) + goto loser; - core_stacksec (abfd)->flags = SEC_ALLOC + SEC_LOAD + SEC_HAS_CONTENTS; - core_datasec (abfd)->flags = SEC_ALLOC + SEC_LOAD + SEC_HAS_CONTENTS; - core_regsec (abfd)->flags = SEC_ALLOC + SEC_HAS_CONTENTS; - core_reg2sec (abfd)->flags = SEC_ALLOC + SEC_HAS_CONTENTS; + flags = SEC_HAS_CONTENTS; + core_reg2sec (abfd) = bfd_make_section_anyway_with_flags (abfd, ".reg2", + flags); + if (core_reg2sec (abfd) == NULL) + goto loser; - core_stacksec (abfd)->_raw_size = core->c_ssize; - core_datasec (abfd)->_raw_size = core->c_dsize; - core_regsec (abfd)->_raw_size = core->c_regs_size; - core_reg2sec (abfd)->_raw_size = core->fp_stuff_size; + core_stacksec (abfd)->size = core->c_ssize; + core_datasec (abfd)->size = core->c_dsize; + core_regsec (abfd)->size = core->c_regs_size; + core_reg2sec (abfd)->size = core->fp_stuff_size; core_stacksec (abfd)->vma = (core->c_stacktop - core->c_ssize); - core_datasec (abfd)->vma = N_DATADDR (core->c_aouthdr); + core_datasec (abfd)->vma = core->c_data_addr; core_regsec (abfd)->vma = 0; core_reg2sec (abfd)->vma = 0; core_stacksec (abfd)->filepos = core->c_len + core->c_dsize; core_datasec (abfd)->filepos = core->c_len; - /* We'll access the regs afresh in the core file, like any section: */ + /* We'll access the regs afresh in the core file, like any section: */ core_regsec (abfd)->filepos = (file_ptr) core->c_regs_pos; core_reg2sec (abfd)->filepos = (file_ptr) core->fp_stuff_pos; - /* Align to word at least */ + /* 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; +sunos4_core_file_failing_command (bfd *abfd) { return core_hdr (abfd)->hdr->c_cmdname; } static int -sunos4_core_file_failing_signal (abfd) - bfd *abfd; +sunos4_core_file_failing_signal (bfd *abfd) { return core_hdr (abfd)->hdr->c_signo; } -static boolean -sunos4_core_file_matches_executable_p (core_bfd, exec_bfd) - bfd *core_bfd; - bfd *exec_bfd; +static bfd_boolean +sunos4_core_file_matches_executable_p (bfd *core_bfd, bfd *exec_bfd) { if (core_bfd->xvec != exec_bfd->xvec) { bfd_set_error (bfd_error_system_call); - return false; + return FALSE; } - return (memcmp ((char *) &((core_hdr (core_bfd)->hdr)->c_aouthdr), - (char *) exec_hdr (exec_bfd), - sizeof (struct internal_exec)) == 0) ? true : false; + /* Solaris core files do not include an aouthdr. */ + if ((core_hdr (core_bfd)->hdr)->c_len == SOLARIS_BCP_CORE_LEN) + return TRUE; + + return memcmp ((char *) &((core_hdr (core_bfd)->hdr)->c_aouthdr), + (char *) exec_hdr (exec_bfd), + sizeof (struct internal_exec)) == 0; } #define MY_set_sizes sunos4_set_sizes -static boolean -sunos4_set_sizes (abfd) - bfd *abfd; + +static bfd_boolean +sunos4_set_sizes (bfd *abfd) { switch (bfd_get_arch (abfd)) { default: - return false; + return FALSE; case bfd_arch_sparc: adata (abfd).page_size = 0x2000; adata (abfd).segment_size = 0x2000; adata (abfd).exec_bytes_size = EXEC_BYTES_SIZE; - return true; + return TRUE; case bfd_arch_m68k: adata (abfd).page_size = 0x2000; adata (abfd).segment_size = 0x20000; adata (abfd).exec_bytes_size = EXEC_BYTES_SIZE; - return true; + return TRUE; } } @@ -624,6 +737,9 @@ sunos4_set_sizes (abfd) #define MY_exec_hdr_flags 1 #endif +#ifndef MY_entry_is_text_address +#define MY_entry_is_text_address 0 +#endif #ifndef MY_add_dynamic_symbols #define MY_add_dynamic_symbols 0 #endif @@ -643,14 +759,15 @@ sunos4_set_sizes (abfd) #define MY_finish_dynamic_link 0 #endif -static CONST struct aout_backend_data sunos4_aout_backend = +static const struct aout_backend_data sunos4_aout_backend = { - 0, /* zmagic files are not contiguous */ - 1, /* text includes header */ + 0, /* Zmagic files are not contiguous. */ + 1, /* Text includes header. */ + MY_entry_is_text_address, MY_exec_hdr_flags, - 0, /* default text vma */ + 0, /* Default text vma. */ sunos4_set_sizes, - 0, /* header is counted in zmagic text */ + 0, /* Header is counted in zmagic text. */ MY_add_dynamic_symbols, MY_add_one_symbol, MY_link_dynamic_object, @@ -665,12 +782,13 @@ static CONST struct aout_backend_data sunos4_aout_backend = #define MY_bfd_debug_info_start bfd_void #define MY_bfd_debug_info_end bfd_void -#define MY_bfd_debug_info_accumulate \ - (void (*) PARAMS ((bfd *, struct sec *))) bfd_void +#define MY_bfd_debug_info_accumulate (void (*) (bfd *, struct bfd_section *)) bfd_void #define MY_core_file_p sunos4_core_file_p -#define MY_write_object_contents NAME(aout,sunos4_write_object_contents) -#define MY_backend_data &sunos4_aout_backend +#define MY_write_object_contents NAME(aout, sunos4_write_object_contents) +#define MY_backend_data & sunos4_aout_backend +#ifndef TARGET_IS_LITTLE_ENDIAN_P #define TARGET_IS_BIG_ENDIAN_P +#endif #include "aout-target.h"