Back to index

cell-binutils  2.17cvs20070401
elf32-i960.c
Go to the documentation of this file.
00001 /* Intel 960 specific support for 32-bit ELF
00002    Copyright 1999, 2000, 2001, 2002, 2003, 2005, 2007
00003    Free Software Foundation, Inc.
00004 
00005    This file is part of BFD, the Binary File Descriptor library.
00006 
00007    This program is free software; you can redistribute it and/or modify
00008    it under the terms of the GNU General Public License as published by
00009    the Free Software Foundation; either version 2 of the License, or
00010    (at your option) any later version.
00011 
00012    This program is distributed in the hope that it will be useful,
00013    but WITHOUT ANY WARRANTY; without even the implied warranty of
00014    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015    GNU General Public License for more details.
00016 
00017    You should have received a copy of the GNU General Public License
00018    along with this program; if not, write to the Free Software
00019    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
00020    MA 02110-1301, USA.  */
00021 
00022 #include "bfd.h"
00023 #include "sysdep.h"
00024 #include "libbfd.h"
00025 #include "elf-bfd.h"
00026 #include "elf/i960.h"
00027 
00028 #define USE_REL 1
00029 
00030 #define bfd_elf32_bfd_reloc_type_lookup   elf32_i960_reloc_type_lookup
00031 #define bfd_elf32_bfd_reloc_name_lookup \
00032   elf32_i960_reloc_name_lookup
00033 #define elf_info_to_howto          elf32_i960_info_to_howto
00034 #define elf_info_to_howto_rel             elf32_i960_info_to_howto_rel
00035 
00036 /* ELF relocs are against symbols.  If we are producing relocatable
00037    output, and the reloc is against an external symbol, and nothing
00038    has given us any additional addend, the resulting reloc will also
00039    be against the same symbol.  In such a case, we don't want to
00040    change anything about the way the reloc is handled, since it will
00041    all be done at final link time.  Rather than put special case code
00042    into bfd_perform_relocation, all the reloc types use this howto
00043    function.  It just short circuits the reloc if producing
00044    relocatable output against an external symbol.  */
00045 
00046 static bfd_reloc_status_type
00047 elf32_i960_relocate (bfd *abfd ATTRIBUTE_UNUSED,
00048                    arelent *reloc_entry,
00049                    asymbol *symbol,
00050                    PTR data ATTRIBUTE_UNUSED,
00051                    asection *input_section,
00052                    bfd *output_bfd,
00053                    char **error_message ATTRIBUTE_UNUSED)
00054 {
00055   /* HACK: I think this first condition is necessary when producing
00056      relocatable output.  After the end of HACK, the code is identical
00057      to bfd_elf_generic_reloc().  I would _guess_ the first change
00058      belongs there rather than here.  martindo 1998-10-23.  */
00059   if (output_bfd != (bfd *) NULL
00060       && reloc_entry->howto->pc_relative
00061       && !reloc_entry->howto->pcrel_offset)
00062     reloc_entry->addend -= symbol->value;
00063 
00064   /* This is more dubious.  */
00065   else if (output_bfd != (bfd *) NULL
00066           && (symbol->flags & BSF_SECTION_SYM) != 0)
00067     reloc_entry->addend -= symbol->section->output_section->vma;
00068 
00069   else
00070     {
00071       /* ...end of HACK.  */
00072       if (output_bfd != (bfd *) NULL
00073          && (symbol->flags & BSF_SECTION_SYM) == 0
00074          && (! reloc_entry->howto->partial_inplace
00075              || reloc_entry->addend == 0))
00076        {
00077          reloc_entry->address += input_section->output_offset;
00078          return bfd_reloc_ok;
00079        }
00080     }
00081 
00082   return bfd_reloc_continue;
00083 }
00084 
00085 static reloc_howto_type elf_howto_table[]=
00086 {
00087   HOWTO (R_960_NONE, 0, 0, 0, FALSE, 0, complain_overflow_bitfield,
00088         elf32_i960_relocate, "R_960_NONE", TRUE,
00089         0x00000000, 0x00000000, FALSE),
00090   EMPTY_HOWTO (1),
00091   HOWTO (R_960_32, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,
00092         elf32_i960_relocate, "R_960_32", TRUE,
00093         0xffffffff, 0xffffffff, FALSE),
00094   HOWTO (R_960_IP24, 0, 2, 24, TRUE, 0, complain_overflow_signed,
00095         elf32_i960_relocate, "R_960_IP24 ", TRUE,
00096         0x00ffffff, 0x00ffffff, FALSE),
00097   EMPTY_HOWTO (4),
00098   EMPTY_HOWTO (5),
00099   EMPTY_HOWTO (6),
00100   EMPTY_HOWTO (7)
00101 };
00102 
00103 static enum elf_i960_reloc_type
00104 elf32_i960_bfd_to_reloc_type (bfd_reloc_code_real_type code)
00105 {
00106   switch (code)
00107     {
00108     default:
00109       return R_960_NONE;
00110     case BFD_RELOC_I960_CALLJ:
00111       return R_960_OPTCALL;
00112     case BFD_RELOC_32:
00113     case BFD_RELOC_CTOR:
00114       return R_960_32;
00115     case BFD_RELOC_24_PCREL:
00116       return R_960_IP24;
00117     }
00118 }
00119 
00120 static void
00121 elf32_i960_info_to_howto (bfd *               abfd ATTRIBUTE_UNUSED,
00122                        arelent *           cache_ptr ATTRIBUTE_UNUSED,
00123                        Elf_Internal_Rela * dst ATTRIBUTE_UNUSED)
00124 {
00125   abort ();
00126 }
00127 
00128 static void
00129 elf32_i960_info_to_howto_rel (bfd *abfd ATTRIBUTE_UNUSED,
00130                            arelent *cache_ptr,
00131                            Elf_Internal_Rela *dst)
00132 {
00133   enum elf_i960_reloc_type type;
00134 
00135   type = (enum elf_i960_reloc_type) ELF32_R_TYPE (dst->r_info);
00136   BFD_ASSERT (type < R_960_max);
00137 
00138   cache_ptr->howto = &elf_howto_table[(int) type];
00139 }
00140 
00141 static reloc_howto_type *
00142 elf32_i960_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
00143                            bfd_reloc_code_real_type code)
00144 {
00145   return elf_howto_table + elf32_i960_bfd_to_reloc_type (code);
00146 }
00147 
00148 static reloc_howto_type *
00149 elf32_i960_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
00150                            const char *r_name)
00151 {
00152   unsigned int i;
00153 
00154   for (i = 0; i < sizeof (elf_howto_table) / sizeof (elf_howto_table[0]); i++)
00155     if (elf_howto_table[i].name != NULL
00156        && strcasecmp (elf_howto_table[i].name, r_name) == 0)
00157       return &elf_howto_table[i];
00158 
00159   return NULL;
00160 }
00161 
00162 #define TARGET_LITTLE_SYM   bfd_elf32_i960_vec
00163 #define TARGET_LITTLE_NAME  "elf32-i960"
00164 #define ELF_ARCH            bfd_arch_i960
00165 #define ELF_MACHINE_CODE    EM_960
00166 #define ELF_MAXPAGESIZE     1 /* FIXME: This number is wrong,  It should be the page size in bytes.  */
00167 
00168 #include "elf32-target.h"