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