Back to index

cell-binutils  2.17cvs20070401
coff-sparc.c
Go to the documentation of this file.
00001 /* BFD back-end for Sparc COFF files.
00002    Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1999, 2000, 2001,
00003    2002, 2003, 2005, 2007 Free Software Foundation, Inc.
00004    Written by Cygnus Support.
00005 
00006 This file is part of BFD, the Binary File Descriptor library.
00007 
00008 This program is free software; you can redistribute it and/or modify
00009 it under the terms of the GNU General Public License as published by
00010 the Free Software Foundation; either version 2 of the License, or
00011 (at your option) any later version.
00012 
00013 This program is distributed in the hope that it will be useful,
00014 but WITHOUT ANY WARRANTY; without even the implied warranty of
00015 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00016 GNU General Public License for more details.
00017 
00018 You should have received a copy of the GNU General Public License
00019 along with this program; if not, write to the Free Software
00020 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.  */
00021 
00022 #include "bfd.h"
00023 #include "sysdep.h"
00024 #include "libbfd.h"
00025 #include "coff/sparc.h"
00026 #include "coff/internal.h"
00027 #include "libcoff.h"
00028 
00029 #define COFF_DEFAULT_SECTION_ALIGNMENT_POWER (3)
00030 
00031 #define BADMAG(x) ((x).f_magic != SPARCMAGIC && (x).f_magic != LYNXCOFFMAGIC)
00032 
00033 /* The page size is a guess based on ELF.  */
00034 #define COFF_PAGE_SIZE 0x10000
00035 
00036 
00037 static reloc_howto_type *coff_sparc_reloc_type_lookup
00038   PARAMS ((bfd *, bfd_reloc_code_real_type));
00039 static void rtype2howto PARAMS ((arelent *, struct internal_reloc *));
00040 
00041 enum reloc_type
00042   {
00043     R_SPARC_NONE = 0,
00044     R_SPARC_8,              R_SPARC_16,          R_SPARC_32,
00045     R_SPARC_DISP8,   R_SPARC_DISP16,             R_SPARC_DISP32,
00046     R_SPARC_WDISP30, R_SPARC_WDISP22,
00047     R_SPARC_HI22,    R_SPARC_22,
00048     R_SPARC_13,             R_SPARC_LO10,
00049     R_SPARC_GOT10,   R_SPARC_GOT13,              R_SPARC_GOT22,
00050     R_SPARC_PC10,    R_SPARC_PC22,
00051     R_SPARC_WPLT30,
00052     R_SPARC_COPY,
00053     R_SPARC_GLOB_DAT,       R_SPARC_JMP_SLOT,
00054     R_SPARC_RELATIVE,
00055     R_SPARC_UA32,
00056     R_SPARC_max
00057   };
00058 
00059 /* This is stolen pretty directly from elf.c.  */
00060 static bfd_reloc_status_type
00061 bfd_coff_generic_reloc PARAMS ((bfd *, arelent *, asymbol *, PTR,
00062                             asection *, bfd *, char **));
00063 
00064 static bfd_reloc_status_type
00065 bfd_coff_generic_reloc (abfd, reloc_entry, symbol, data, input_section,
00066                      output_bfd, error_message)
00067      bfd *abfd ATTRIBUTE_UNUSED;
00068      arelent *reloc_entry;
00069      asymbol *symbol;
00070      PTR data ATTRIBUTE_UNUSED;
00071      asection *input_section;
00072      bfd *output_bfd;
00073      char **error_message ATTRIBUTE_UNUSED;
00074 {
00075   if (output_bfd != (bfd *) NULL
00076       && (symbol->flags & BSF_SECTION_SYM) == 0)
00077     {
00078       reloc_entry->address += input_section->output_offset;
00079       return bfd_reloc_ok;
00080     }
00081 
00082   return bfd_reloc_continue;
00083 }
00084 
00085 static reloc_howto_type coff_sparc_howto_table[] =
00086 {
00087   HOWTO(R_SPARC_NONE,    0,0, 0,FALSE,0,complain_overflow_dont,    bfd_coff_generic_reloc,"R_SPARC_NONE",    FALSE,0,0x00000000,TRUE),
00088   HOWTO(R_SPARC_8,       0,0, 8,FALSE,0,complain_overflow_bitfield,bfd_coff_generic_reloc,"R_SPARC_8",       FALSE,0,0x000000ff,TRUE),
00089   HOWTO(R_SPARC_16,      0,1,16,FALSE,0,complain_overflow_bitfield,bfd_coff_generic_reloc,"R_SPARC_16",      FALSE,0,0x0000ffff,TRUE),
00090   HOWTO(R_SPARC_32,      0,2,32,FALSE,0,complain_overflow_bitfield,bfd_coff_generic_reloc,"R_SPARC_32",      FALSE,0,0xffffffff,TRUE),
00091   HOWTO(R_SPARC_DISP8,   0,0, 8,TRUE, 0,complain_overflow_signed,  bfd_coff_generic_reloc,"R_SPARC_DISP8",   FALSE,0,0x000000ff,TRUE),
00092   HOWTO(R_SPARC_DISP16,  0,1,16,TRUE, 0,complain_overflow_signed,  bfd_coff_generic_reloc,"R_SPARC_DISP16",  FALSE,0,0x0000ffff,TRUE),
00093   HOWTO(R_SPARC_DISP32,  0,2,32,TRUE, 0,complain_overflow_signed,  bfd_coff_generic_reloc,"R_SPARC_DISP32",  FALSE,0,0x00ffffff,TRUE),
00094   HOWTO(R_SPARC_WDISP30, 2,2,30,TRUE, 0,complain_overflow_signed,  bfd_coff_generic_reloc,"R_SPARC_WDISP30", FALSE,0,0x3fffffff,TRUE),
00095   HOWTO(R_SPARC_WDISP22, 2,2,22,TRUE, 0,complain_overflow_signed,  bfd_coff_generic_reloc,"R_SPARC_WDISP22", FALSE,0,0x003fffff,TRUE),
00096   HOWTO(R_SPARC_HI22,   10,2,22,FALSE,0,complain_overflow_dont,    bfd_coff_generic_reloc,"R_SPARC_HI22",    FALSE,0,0x003fffff,TRUE),
00097   HOWTO(R_SPARC_22,      0,2,22,FALSE,0,complain_overflow_bitfield,bfd_coff_generic_reloc,"R_SPARC_22",      FALSE,0,0x003fffff,TRUE),
00098   HOWTO(R_SPARC_13,      0,2,13,FALSE,0,complain_overflow_bitfield,bfd_coff_generic_reloc,"R_SPARC_13",      FALSE,0,0x00001fff,TRUE),
00099   HOWTO(R_SPARC_LO10,    0,2,10,FALSE,0,complain_overflow_dont,    bfd_coff_generic_reloc,"R_SPARC_LO10",    FALSE,0,0x000003ff,TRUE),
00100   HOWTO(R_SPARC_GOT10,   0,2,10,FALSE,0,complain_overflow_bitfield,bfd_coff_generic_reloc,"R_SPARC_GOT10",   FALSE,0,0x000003ff,TRUE),
00101   HOWTO(R_SPARC_GOT13,   0,2,13,FALSE,0,complain_overflow_bitfield,bfd_coff_generic_reloc,"R_SPARC_GOT13",   FALSE,0,0x00001fff,TRUE),
00102   HOWTO(R_SPARC_GOT22,  10,2,22,FALSE,0,complain_overflow_bitfield,bfd_coff_generic_reloc,"R_SPARC_GOT22",   FALSE,0,0x003fffff,TRUE),
00103   HOWTO(R_SPARC_PC10,    0,2,10,FALSE,0,complain_overflow_bitfield,bfd_coff_generic_reloc,"R_SPARC_PC10",    FALSE,0,0x000003ff,TRUE),
00104   HOWTO(R_SPARC_PC22,    0,2,22,FALSE,0,complain_overflow_bitfield,bfd_coff_generic_reloc,"R_SPARC_PC22",    FALSE,0,0x003fffff,TRUE),
00105   HOWTO(R_SPARC_WPLT30,  0,0,00,FALSE,0,complain_overflow_dont,    bfd_coff_generic_reloc,"R_SPARC_WPLT30",  FALSE,0,0x00000000,TRUE),
00106   HOWTO(R_SPARC_COPY,    0,0,00,FALSE,0,complain_overflow_dont,    bfd_coff_generic_reloc,"R_SPARC_COPY",    FALSE,0,0x00000000,TRUE),
00107   HOWTO(R_SPARC_GLOB_DAT,0,0,00,FALSE,0,complain_overflow_dont,    bfd_coff_generic_reloc,"R_SPARC_GLOB_DAT",FALSE,0,0x00000000,TRUE),
00108   HOWTO(R_SPARC_JMP_SLOT,0,0,00,FALSE,0,complain_overflow_dont,    bfd_coff_generic_reloc,"R_SPARC_JMP_SLOT",FALSE,0,0x00000000,TRUE),
00109   HOWTO(R_SPARC_RELATIVE,0,0,00,FALSE,0,complain_overflow_dont,    bfd_coff_generic_reloc,"R_SPARC_RELATIVE",FALSE,0,0x00000000,TRUE),
00110   HOWTO(R_SPARC_UA32,    0,0,00,FALSE,0,complain_overflow_dont,    bfd_coff_generic_reloc,"R_SPARC_UA32",    FALSE,0,0x00000000,TRUE),
00111 };
00112 
00113 struct coff_reloc_map {
00114   bfd_reloc_code_real_type bfd_reloc_val;
00115   unsigned char coff_reloc_val;
00116 };
00117 
00118 static const struct coff_reloc_map sparc_reloc_map[] =
00119 {
00120   { BFD_RELOC_NONE, R_SPARC_NONE, },
00121   { BFD_RELOC_16, R_SPARC_16, },
00122   { BFD_RELOC_8, R_SPARC_8 },
00123   { BFD_RELOC_8_PCREL, R_SPARC_DISP8 },
00124   { BFD_RELOC_CTOR, R_SPARC_32 }, /* @@ Assumes 32 bits.  */
00125   { BFD_RELOC_32, R_SPARC_32 },
00126   { BFD_RELOC_32_PCREL, R_SPARC_DISP32 },
00127   { BFD_RELOC_HI22, R_SPARC_HI22 },
00128   { BFD_RELOC_LO10, R_SPARC_LO10, },
00129   { BFD_RELOC_32_PCREL_S2, R_SPARC_WDISP30 },
00130   { BFD_RELOC_SPARC22, R_SPARC_22 },
00131   { BFD_RELOC_SPARC13, R_SPARC_13 },
00132   { BFD_RELOC_SPARC_GOT10, R_SPARC_GOT10 },
00133   { BFD_RELOC_SPARC_GOT13, R_SPARC_GOT13 },
00134   { BFD_RELOC_SPARC_GOT22, R_SPARC_GOT22 },
00135   { BFD_RELOC_SPARC_PC10, R_SPARC_PC10 },
00136   { BFD_RELOC_SPARC_PC22, R_SPARC_PC22 },
00137   { BFD_RELOC_SPARC_WPLT30, R_SPARC_WPLT30 },
00138   { BFD_RELOC_SPARC_COPY, R_SPARC_COPY },
00139   { BFD_RELOC_SPARC_GLOB_DAT, R_SPARC_GLOB_DAT },
00140   { BFD_RELOC_SPARC_JMP_SLOT, R_SPARC_JMP_SLOT },
00141   { BFD_RELOC_SPARC_RELATIVE, R_SPARC_RELATIVE },
00142   { BFD_RELOC_SPARC_WDISP22, R_SPARC_WDISP22 },
00143   /*  { BFD_RELOC_SPARC_UA32, R_SPARC_UA32 }, not used?? */
00144 };
00145 
00146 static reloc_howto_type *
00147 coff_sparc_reloc_type_lookup (abfd, code)
00148      bfd *abfd ATTRIBUTE_UNUSED;
00149      bfd_reloc_code_real_type code;
00150 {
00151   unsigned int i;
00152   for (i = 0; i < sizeof (sparc_reloc_map) / sizeof (struct coff_reloc_map); i++)
00153     {
00154       if (sparc_reloc_map[i].bfd_reloc_val == code)
00155        return &coff_sparc_howto_table[(int) sparc_reloc_map[i].coff_reloc_val];
00156     }
00157   return 0;
00158 }
00159 #define coff_bfd_reloc_type_lookup coff_sparc_reloc_type_lookup
00160 
00161 static reloc_howto_type *
00162 coff_sparc_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
00163                            const char *r_name)
00164 {
00165   unsigned int i;
00166 
00167   for (i = 0;
00168        i < (sizeof (coff_sparc_howto_table)
00169            / sizeof (coff_sparc_howto_table[0]));
00170        i++)
00171     if (coff_sparc_howto_table[i].name != NULL
00172        && strcasecmp (coff_sparc_howto_table[i].name, r_name) == 0)
00173       return &coff_sparc_howto_table[i];
00174 
00175   return NULL;
00176 }
00177 #define coff_bfd_reloc_name_lookup coff_sparc_reloc_name_lookup
00178 
00179 static void
00180 rtype2howto (cache_ptr, dst)
00181      arelent *cache_ptr;
00182      struct internal_reloc *dst;
00183 {
00184   BFD_ASSERT (dst->r_type < (unsigned int) R_SPARC_max);
00185   cache_ptr->howto = &coff_sparc_howto_table[dst->r_type];
00186 }
00187 
00188 #define RTYPE2HOWTO(internal, relocentry) rtype2howto(internal,relocentry)
00189 
00190 #define SWAP_IN_RELOC_OFFSET       H_GET_32
00191 #define SWAP_OUT_RELOC_OFFSET      H_PUT_32
00192 #define CALC_ADDEND(abfd, ptr, reloc, cache_ptr) \
00193   cache_ptr->addend = reloc.r_offset;
00194 
00195 /* Clear the r_spare field in relocs.  */
00196 #define SWAP_OUT_RELOC_EXTRA(abfd,src,dst) \
00197   do { \
00198        dst->r_spare[0] = 0; \
00199        dst->r_spare[1] = 0; \
00200      } while (0)
00201 
00202 #define __A_MAGIC_SET__
00203 
00204 /* Enable Sparc-specific hacks in coffcode.h.  */
00205 
00206 #define COFF_SPARC
00207 
00208 #include "coffcode.h"
00209 
00210 #ifndef TARGET_SYM
00211 #define TARGET_SYM sparccoff_vec
00212 #endif
00213 
00214 #ifndef TARGET_NAME
00215 #define TARGET_NAME "coff-sparc"
00216 #endif
00217 
00218 CREATE_BIG_COFF_TARGET_VEC (TARGET_SYM, TARGET_NAME, D_PAGED, 0, '_', NULL, COFF_SWAP_TABLE)