Home | History | Annotate | Line # | Download | only in bfd
elf32-arc.c revision 1.1
      1  1.1  skrll /* ARC-specific support for 32-bit ELF
      2  1.1  skrll    Copyright 1994, 1995, 1997, 1999, 2001, 2002, 2005, 2007
      3  1.1  skrll    Free Software Foundation, Inc.
      4  1.1  skrll    Contributed by Doug Evans (dje (at) cygnus.com).
      5  1.1  skrll 
      6  1.1  skrll    This file is part of BFD, the Binary File Descriptor library.
      7  1.1  skrll 
      8  1.1  skrll    This program is free software; you can redistribute it and/or modify
      9  1.1  skrll    it under the terms of the GNU General Public License as published by
     10  1.1  skrll    the Free Software Foundation; either version 3 of the License, or
     11  1.1  skrll    (at your option) any later version.
     12  1.1  skrll 
     13  1.1  skrll    This program is distributed in the hope that it will be useful,
     14  1.1  skrll    but WITHOUT ANY WARRANTY; without even the implied warranty of
     15  1.1  skrll    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     16  1.1  skrll    GNU General Public License for more details.
     17  1.1  skrll 
     18  1.1  skrll    You should have received a copy of the GNU General Public License
     19  1.1  skrll    along with this program; if not, write to the Free Software
     20  1.1  skrll    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
     21  1.1  skrll    MA 02110-1301, USA.  */
     22  1.1  skrll 
     23  1.1  skrll #include "sysdep.h"
     24  1.1  skrll #include "bfd.h"
     25  1.1  skrll #include "libbfd.h"
     26  1.1  skrll #include "elf-bfd.h"
     27  1.1  skrll #include "elf/arc.h"
     28  1.1  skrll #include "libiberty.h"
     29  1.1  skrll 
     30  1.1  skrll /* Try to minimize the amount of space occupied by relocation tables
     31  1.1  skrll    on the ROM (not that the ROM won't be swamped by other ELF overhead).  */
     32  1.1  skrll 
     33  1.1  skrll #define USE_REL	1
     34  1.1  skrll 
     35  1.1  skrll static bfd_reloc_status_type
     36  1.1  skrll arc_elf_b22_pcrel (bfd * abfd,
     37  1.1  skrll 		   arelent * reloc_entry,
     38  1.1  skrll 		   asymbol * symbol,
     39  1.1  skrll 		   void * data,
     40  1.1  skrll 		   asection * input_section,
     41  1.1  skrll 		   bfd * output_bfd,
     42  1.1  skrll 		   char ** error_message)
     43  1.1  skrll {
     44  1.1  skrll   /* If linking, back up the final symbol address by the address of the
     45  1.1  skrll      reloc.  This cannot be accomplished by setting the pcrel_offset
     46  1.1  skrll      field to TRUE, as bfd_install_relocation will detect this and refuse
     47  1.1  skrll      to install the offset in the first place, but bfd_perform_relocation
     48  1.1  skrll      will still insist on removing it.  */
     49  1.1  skrll   if (output_bfd == NULL)
     50  1.1  skrll     reloc_entry->addend -= reloc_entry->address;
     51  1.1  skrll 
     52  1.1  skrll   /* Fall through to the default elf reloc handler.  */
     53  1.1  skrll   return bfd_elf_generic_reloc (abfd, reloc_entry, symbol, data,
     54  1.1  skrll 				input_section, output_bfd, error_message);
     55  1.1  skrll }
     56  1.1  skrll 
     57  1.1  skrll static reloc_howto_type elf_arc_howto_table[] =
     58  1.1  skrll {
     59  1.1  skrll   /* This reloc does nothing.  */
     60  1.1  skrll   HOWTO (R_ARC_NONE,		/* Type.  */
     61  1.1  skrll 	 0,			/* Rightshift.  */
     62  1.1  skrll 	 2,			/* Size (0 = byte, 1 = short, 2 = long).  */
     63  1.1  skrll 	 32,			/* Bitsize.  */
     64  1.1  skrll 	 FALSE,			/* PC_relative.  */
     65  1.1  skrll 	 0,			/* Bitpos.  */
     66  1.1  skrll 	 complain_overflow_bitfield, /* Complain_on_overflow.  */
     67  1.1  skrll 	 bfd_elf_generic_reloc,	/* Special_function.  */
     68  1.1  skrll 	 "R_ARC_NONE",		/* Name.  */
     69  1.1  skrll 	 TRUE,			/* Partial_inplace.  */
     70  1.1  skrll 	 0,			/* Src_mask.  */
     71  1.1  skrll 	 0,			/* Dst_mask.  */
     72  1.1  skrll 	 FALSE),		/* PCrel_offset.  */
     73  1.1  skrll 
     74  1.1  skrll   /* A standard 32 bit relocation.  */
     75  1.1  skrll   HOWTO (R_ARC_32,		/* Type.  */
     76  1.1  skrll 	 0,			/* Rightshift.  */
     77  1.1  skrll 	 2,			/* Size (0 = byte, 1 = short, 2 = long).  */
     78  1.1  skrll 	 32,			/* Bitsize.  */
     79  1.1  skrll 	 FALSE,			/* PC_relative.  */
     80  1.1  skrll 	 0,			/* Bitpos.  */
     81  1.1  skrll 	 complain_overflow_bitfield, /* Complain_on_overflow.  */
     82  1.1  skrll 	 bfd_elf_generic_reloc,	/* Special_function.  */
     83  1.1  skrll 	 "R_ARC_32",		/* Name.  */
     84  1.1  skrll 	 TRUE,			/* Partial_inplace.  */
     85  1.1  skrll 	 0xffffffff,		/* Src_mask.  */
     86  1.1  skrll 	 0xffffffff,		/* Dst_mask.  */
     87  1.1  skrll 	 FALSE),		/* PCrel_offset.  */
     88  1.1  skrll 
     89  1.1  skrll   /* A 26 bit absolute branch, right shifted by 2.  */
     90  1.1  skrll   HOWTO (R_ARC_B26,		/* Type.  */
     91  1.1  skrll 	 2,			/* Rightshift.  */
     92  1.1  skrll 	 2,			/* Size (0 = byte, 1 = short, 2 = long).  */
     93  1.1  skrll 	 26,			/* Bitsize.  */
     94  1.1  skrll 	 FALSE,			/* PC_relative.  */
     95  1.1  skrll 	 0,			/* Bitpos.  */
     96  1.1  skrll 	 complain_overflow_bitfield, /* Complain_on_overflow.  */
     97  1.1  skrll 	 bfd_elf_generic_reloc,	/* Special_function.  */
     98  1.1  skrll 	 "R_ARC_B26",		/* Name.  */
     99  1.1  skrll 	 TRUE,			/* Partial_inplace.  */
    100  1.1  skrll 	 0x00ffffff,		/* Src_mask.  */
    101  1.1  skrll 	 0x00ffffff,		/* Dst_mask.  */
    102  1.1  skrll 	 FALSE),		/* PCrel_offset.  */
    103  1.1  skrll 
    104  1.1  skrll   /* A relative 22 bit branch; bits 21-2 are stored in bits 26-7.  */
    105  1.1  skrll   HOWTO (R_ARC_B22_PCREL,	/* Type.  */
    106  1.1  skrll 	 2,			/* Rightshift.  */
    107  1.1  skrll 	 2,			/* Size (0 = byte, 1 = short, 2 = long).  */
    108  1.1  skrll 	 22,			/* Bitsize.  */
    109  1.1  skrll 	 TRUE,			/* PC_relative.  */
    110  1.1  skrll 	 7,			/* Bitpos.  */
    111  1.1  skrll 	 complain_overflow_signed, /* Complain_on_overflow.  */
    112  1.1  skrll 	 arc_elf_b22_pcrel,	/* Special_function.  */
    113  1.1  skrll 	 "R_ARC_B22_PCREL",	/* Name.  */
    114  1.1  skrll 	 TRUE,			/* Partial_inplace.  */
    115  1.1  skrll 	 0x07ffff80,		/* Src_mask.  */
    116  1.1  skrll 	 0x07ffff80,		/* Dst_mask.  */
    117  1.1  skrll 	 FALSE),		/* PCrel_offset.  */
    118  1.1  skrll };
    119  1.1  skrll 
    120  1.1  skrll /* Map BFD reloc types to ARC ELF reloc types.  */
    121  1.1  skrll 
    122  1.1  skrll struct arc_reloc_map
    123  1.1  skrll {
    124  1.1  skrll   bfd_reloc_code_real_type bfd_reloc_val;
    125  1.1  skrll   unsigned char elf_reloc_val;
    126  1.1  skrll };
    127  1.1  skrll 
    128  1.1  skrll static const struct arc_reloc_map arc_reloc_map[] =
    129  1.1  skrll {
    130  1.1  skrll   { BFD_RELOC_NONE, R_ARC_NONE, },
    131  1.1  skrll   { BFD_RELOC_32, R_ARC_32 },
    132  1.1  skrll   { BFD_RELOC_CTOR, R_ARC_32 },
    133  1.1  skrll   { BFD_RELOC_ARC_B26, R_ARC_B26 },
    134  1.1  skrll   { BFD_RELOC_ARC_B22_PCREL, R_ARC_B22_PCREL },
    135  1.1  skrll };
    136  1.1  skrll 
    137  1.1  skrll static reloc_howto_type *
    138  1.1  skrll bfd_elf32_bfd_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
    139  1.1  skrll 				 bfd_reloc_code_real_type code)
    140  1.1  skrll {
    141  1.1  skrll   unsigned int i;
    142  1.1  skrll 
    143  1.1  skrll   for (i = ARRAY_SIZE (arc_reloc_map); i--;)
    144  1.1  skrll     if (arc_reloc_map[i].bfd_reloc_val == code)
    145  1.1  skrll       return elf_arc_howto_table + arc_reloc_map[i].elf_reloc_val;
    146  1.1  skrll 
    147  1.1  skrll   return NULL;
    148  1.1  skrll }
    149  1.1  skrll 
    150  1.1  skrll static reloc_howto_type *
    151  1.1  skrll bfd_elf32_bfd_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
    152  1.1  skrll 				 const char *r_name)
    153  1.1  skrll {
    154  1.1  skrll   unsigned int i;
    155  1.1  skrll 
    156  1.1  skrll   for (i = 0;
    157  1.1  skrll        i < sizeof (elf_arc_howto_table) / sizeof (elf_arc_howto_table[0]);
    158  1.1  skrll        i++)
    159  1.1  skrll     if (elf_arc_howto_table[i].name != NULL
    160  1.1  skrll 	&& strcasecmp (elf_arc_howto_table[i].name, r_name) == 0)
    161  1.1  skrll       return &elf_arc_howto_table[i];
    162  1.1  skrll 
    163  1.1  skrll   return NULL;
    164  1.1  skrll }
    165  1.1  skrll 
    166  1.1  skrll /* Set the howto pointer for an ARC ELF reloc.  */
    167  1.1  skrll 
    168  1.1  skrll static void
    169  1.1  skrll arc_info_to_howto_rel (bfd *abfd ATTRIBUTE_UNUSED,
    170  1.1  skrll 		       arelent *cache_ptr,
    171  1.1  skrll 		       Elf_Internal_Rela *dst)
    172  1.1  skrll {
    173  1.1  skrll   unsigned int r_type;
    174  1.1  skrll 
    175  1.1  skrll   r_type = ELF32_R_TYPE (dst->r_info);
    176  1.1  skrll   BFD_ASSERT (r_type < (unsigned int) R_ARC_max);
    177  1.1  skrll   cache_ptr->howto = &elf_arc_howto_table[r_type];
    178  1.1  skrll }
    179  1.1  skrll 
    180  1.1  skrll /* Set the right machine number for an ARC ELF file.  */
    181  1.1  skrll 
    182  1.1  skrll static bfd_boolean
    183  1.1  skrll arc_elf_object_p (bfd *abfd)
    184  1.1  skrll {
    185  1.1  skrll   unsigned int mach = bfd_mach_arc_6;
    186  1.1  skrll 
    187  1.1  skrll   if (elf_elfheader(abfd)->e_machine == EM_ARC)
    188  1.1  skrll     {
    189  1.1  skrll       unsigned long arch = elf_elfheader (abfd)->e_flags & EF_ARC_MACH;
    190  1.1  skrll 
    191  1.1  skrll       switch (arch)
    192  1.1  skrll 	{
    193  1.1  skrll 	case E_ARC_MACH_ARC5:
    194  1.1  skrll 	  mach = bfd_mach_arc_5;
    195  1.1  skrll 	  break;
    196  1.1  skrll 	default:
    197  1.1  skrll 	case E_ARC_MACH_ARC6:
    198  1.1  skrll 	  mach = bfd_mach_arc_6;
    199  1.1  skrll 	  break;
    200  1.1  skrll 	case E_ARC_MACH_ARC7:
    201  1.1  skrll 	  mach = bfd_mach_arc_7;
    202  1.1  skrll 	  break;
    203  1.1  skrll 	case E_ARC_MACH_ARC8:
    204  1.1  skrll 	  mach = bfd_mach_arc_8;
    205  1.1  skrll 	  break;
    206  1.1  skrll 	}
    207  1.1  skrll     }
    208  1.1  skrll   return bfd_default_set_arch_mach (abfd, bfd_arch_arc, mach);
    209  1.1  skrll }
    210  1.1  skrll 
    211  1.1  skrll /* The final processing done just before writing out an ARC ELF object file.
    212  1.1  skrll    This gets the ARC architecture right based on the machine number.  */
    213  1.1  skrll 
    214  1.1  skrll static void
    215  1.1  skrll arc_elf_final_write_processing (bfd *abfd,
    216  1.1  skrll 				bfd_boolean linker ATTRIBUTE_UNUSED)
    217  1.1  skrll {
    218  1.1  skrll   unsigned long val;
    219  1.1  skrll 
    220  1.1  skrll   switch (bfd_get_mach (abfd))
    221  1.1  skrll     {
    222  1.1  skrll     case bfd_mach_arc_5:
    223  1.1  skrll       val = E_ARC_MACH_ARC5;
    224  1.1  skrll       break;
    225  1.1  skrll     default:
    226  1.1  skrll     case bfd_mach_arc_6:
    227  1.1  skrll       val = E_ARC_MACH_ARC6;
    228  1.1  skrll       break;
    229  1.1  skrll     case bfd_mach_arc_7:
    230  1.1  skrll       val = E_ARC_MACH_ARC7;
    231  1.1  skrll       break;
    232  1.1  skrll     case bfd_mach_arc_8:
    233  1.1  skrll       val = E_ARC_MACH_ARC8;
    234  1.1  skrll       break;
    235  1.1  skrll     }
    236  1.1  skrll   elf_elfheader (abfd)->e_flags &=~ EF_ARC_MACH;
    237  1.1  skrll   elf_elfheader (abfd)->e_flags |= val;
    238  1.1  skrll }
    239  1.1  skrll 
    240  1.1  skrll #define TARGET_LITTLE_SYM   bfd_elf32_littlearc_vec
    241  1.1  skrll #define TARGET_LITTLE_NAME  "elf32-littlearc"
    242  1.1  skrll #define TARGET_BIG_SYM      bfd_elf32_bigarc_vec
    243  1.1  skrll #define TARGET_BIG_NAME	    "elf32-bigarc"
    244  1.1  skrll #define ELF_ARCH            bfd_arch_arc
    245  1.1  skrll #define ELF_MACHINE_CODE    EM_ARC
    246  1.1  skrll #define ELF_MAXPAGESIZE     0x1000
    247  1.1  skrll 
    248  1.1  skrll #define elf_info_to_howto                   0
    249  1.1  skrll #define elf_info_to_howto_rel               arc_info_to_howto_rel
    250  1.1  skrll #define elf_backend_object_p                arc_elf_object_p
    251  1.1  skrll #define elf_backend_final_write_processing  arc_elf_final_write_processing
    252  1.1  skrll 
    253  1.1  skrll #include "elf32-target.h"
    254