Home | History | Annotate | Line # | Download | only in bfd
elf32-d10v.c revision 1.1.1.2.2.1
      1          1.1     skrll /* D10V-specific support for 32-bit ELF
      2          1.1     skrll    Copyright 1996, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
      3  1.1.1.2.2.1      yamt    2007, 2010, 2012 Free Software Foundation, Inc.
      4          1.1     skrll    Contributed by Martin Hunt (hunt (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/d10v.h"
     28          1.1     skrll 
     29          1.1     skrll /* Use REL instead of RELA to save space.  */
     30          1.1     skrll #define USE_REL	1
     31          1.1     skrll 
     32          1.1     skrll static reloc_howto_type elf_d10v_howto_table[] =
     33          1.1     skrll {
     34          1.1     skrll   /* This reloc does nothing.  */
     35          1.1     skrll   HOWTO (R_D10V_NONE,		/* Type.  */
     36          1.1     skrll 	 0,			/* Rightshift.  */
     37          1.1     skrll 	 2,			/* Size (0 = byte, 1 = short, 2 = long).  */
     38          1.1     skrll 	 32,			/* Bitsize.  */
     39          1.1     skrll 	 FALSE,			/* PC_relative.  */
     40          1.1     skrll 	 0,			/* Bitpos.  */
     41          1.1     skrll 	 complain_overflow_dont,/* Complain_on_overflow.  */
     42          1.1     skrll 	 bfd_elf_generic_reloc, /* Special_function.  */
     43          1.1     skrll 	 "R_D10V_NONE",		/* Name.  */
     44          1.1     skrll 	 FALSE,			/* Partial_inplace.  */
     45          1.1     skrll 	 0,			/* Src_mask.  */
     46          1.1     skrll 	 0,			/* Dst_mask.  */
     47          1.1     skrll 	 FALSE),		/* PCrel_offset.  */
     48          1.1     skrll 
     49          1.1     skrll   /* An PC Relative 10-bit relocation, shifted by 2, right container.  */
     50          1.1     skrll   HOWTO (R_D10V_10_PCREL_R,	/* Type.  */
     51          1.1     skrll 	 2,	                /* Rightshift.  */
     52          1.1     skrll 	 2,	                /* Size (0 = byte, 1 = short, 2 = long).  */
     53          1.1     skrll 	 8,	                /* Bitsize.  */
     54          1.1     skrll 	 TRUE,	        	/* PC_relative.  */
     55          1.1     skrll 	 0,	                /* Bitpos.  */
     56          1.1     skrll 	 complain_overflow_signed, /* Complain_on_overflow.  */
     57          1.1     skrll 	 bfd_elf_generic_reloc, /* Special_function.  */
     58          1.1     skrll 	 "R_D10V_10_PCREL_R",	/* Name.  */
     59          1.1     skrll 	 FALSE,	        	/* Partial_inplace.  */
     60          1.1     skrll 	 0xff,			/* Src_mask.  */
     61          1.1     skrll 	 0xff,   		/* Dst_mask.  */
     62          1.1     skrll 	 TRUE),			/* PCrel_offset.  */
     63          1.1     skrll 
     64          1.1     skrll   /* An PC Relative 10-bit relocation, shifted by 2, left container.  */
     65          1.1     skrll   HOWTO (R_D10V_10_PCREL_L,	/* Type.  */
     66          1.1     skrll 	 2,	                /* Rightshift.  */
     67          1.1     skrll 	 2,	                /* Size (0 = byte, 1 = short, 2 = long).  */
     68          1.1     skrll 	 8,	                /* Bitsize.  */
     69          1.1     skrll 	 TRUE,	        	/* PC_relative.  */
     70          1.1     skrll 	 15,	                /* Bitpos.  */
     71          1.1     skrll 	 complain_overflow_signed, /* Complain_on_overflow.  */
     72          1.1     skrll 	 bfd_elf_generic_reloc, /* Special_function.  */
     73          1.1     skrll 	 "R_D10V_10_PCREL_L",	/* Name.  */
     74          1.1     skrll 	 FALSE,	        	/* Partial_inplace.  */
     75          1.1     skrll 	 0x07f8000,		/* Src_mask.  */
     76          1.1     skrll 	 0x07f8000,   		/* Dst_mask.  */
     77          1.1     skrll 	 TRUE),			/* PCrel_offset.  */
     78          1.1     skrll 
     79          1.1     skrll   /* A 16 bit absolute relocation.  */
     80          1.1     skrll   HOWTO (R_D10V_16,		/* Type.  */
     81          1.1     skrll 	 0,			/* Rightshift.  */
     82          1.1     skrll 	 1,			/* Size (0 = byte, 1 = short, 2 = long).  */
     83          1.1     skrll 	 16,			/* Bitsize.  */
     84          1.1     skrll 	 FALSE,			/* PC_relative.  */
     85          1.1     skrll 	 0,			/* Bitpos.  */
     86          1.1     skrll 	 complain_overflow_dont,/* Complain_on_overflow.  */
     87          1.1     skrll 	 bfd_elf_generic_reloc, /* Special_function.  */
     88          1.1     skrll 	 "R_D10V_16",		/* Name.  */
     89          1.1     skrll 	 FALSE,			/* Partial_inplace.  */
     90          1.1     skrll 	 0xffff,		/* Src_mask.  */
     91          1.1     skrll 	 0xffff,		/* Dst_mask.  */
     92          1.1     skrll 	 FALSE),		/* PCrel_offset.  */
     93          1.1     skrll 
     94          1.1     skrll   /* An 18 bit absolute relocation, right shifted 2.  */
     95          1.1     skrll   HOWTO (R_D10V_18,		/* Type.  */
     96          1.1     skrll 	 2,			/* Rightshift.  */
     97          1.1     skrll 	 1,			/* Size (0 = byte, 1 = short, 2 = long).  */
     98          1.1     skrll 	 16,			/* Bitsize.  */
     99          1.1     skrll 	 FALSE,			/* PC_relative.  */
    100          1.1     skrll 	 0,			/* Bitpos.  */
    101          1.1     skrll 	 complain_overflow_dont, /* Complain_on_overflow.  */
    102          1.1     skrll 	 bfd_elf_generic_reloc, /* Special_function.  */
    103          1.1     skrll 	 "R_D10V_18",		/* Name.  */
    104          1.1     skrll 	 FALSE,			/* Partial_inplace.  */
    105          1.1     skrll 	 0xffff,		/* Src_mask.  */
    106          1.1     skrll 	 0xffff,		/* Dst_mask.  */
    107          1.1     skrll 	 FALSE),		/* PCrel_offset.  */
    108          1.1     skrll 
    109          1.1     skrll   /* A relative 18 bit relocation, right shifted by 2.  */
    110          1.1     skrll   HOWTO (R_D10V_18_PCREL,	/* Type.  */
    111          1.1     skrll 	 2,			/* Rightshift.  */
    112          1.1     skrll 	 2,			/* Size (0 = byte, 1 = short, 2 = long).  */
    113          1.1     skrll 	 16,			/* Bitsize.  */
    114          1.1     skrll 	 TRUE,			/* PC_relative.  */
    115          1.1     skrll 	 0,			/* Bitpos.  */
    116          1.1     skrll 	 complain_overflow_signed, /* Complain_on_overflow.  */
    117          1.1     skrll 	 bfd_elf_generic_reloc, /* Special_function.  */
    118          1.1     skrll 	 "R_D10V_18_PCREL",	/* Name.  */
    119          1.1     skrll 	 FALSE,			/* Partial_inplace.  */
    120          1.1     skrll 	 0xffff,		/* Src_mask.  */
    121          1.1     skrll 	 0xffff,		/* Dst_mask.  */
    122          1.1     skrll 	 TRUE),			/* PCrel_offset.  */
    123          1.1     skrll 
    124          1.1     skrll   /* A 32 bit absolute relocation.  */
    125          1.1     skrll   HOWTO (R_D10V_32,		/* Type.  */
    126          1.1     skrll 	 0,			/* Rightshift.  */
    127          1.1     skrll 	 2,			/* Size (0 = byte, 1 = short, 2 = long).  */
    128          1.1     skrll 	 32,			/* Bitsize.  */
    129          1.1     skrll 	 FALSE,			/* PC_relative.  */
    130          1.1     skrll 	 0,			/* Bitpos.  */
    131          1.1     skrll 	 complain_overflow_dont,/* Complain_on_overflow.  */
    132          1.1     skrll 	 bfd_elf_generic_reloc, /* Special_function.  */
    133          1.1     skrll 	 "R_D10V_32",		/* Name.  */
    134          1.1     skrll 	 FALSE,			/* Partial_inplace.  */
    135          1.1     skrll 	 0xffffffff,		/* Src_mask.  */
    136          1.1     skrll 	 0xffffffff,		/* Dst_mask.  */
    137          1.1     skrll 	 FALSE),		/* PCrel_offset.  */
    138          1.1     skrll 
    139          1.1     skrll   /* GNU extension to record C++ vtable hierarchy.  */
    140          1.1     skrll   HOWTO (R_D10V_GNU_VTINHERIT,	/* Type.  */
    141          1.1     skrll 	 0,                     /* Rightshift.  */
    142          1.1     skrll 	 2,                     /* Size (0 = byte, 1 = short, 2 = long).  */
    143          1.1     skrll 	 0,                     /* Bitsize.  */
    144          1.1     skrll 	 FALSE,                 /* PC_relative.  */
    145          1.1     skrll 	 0,                     /* Bitpos.  */
    146          1.1     skrll 	 complain_overflow_dont,/* Complain_on_overflow.  */
    147          1.1     skrll 	 NULL,                  /* Special_function.  */
    148          1.1     skrll 	 "R_D10V_GNU_VTINHERIT",/* Name.  */
    149          1.1     skrll 	 FALSE,                 /* Partial_inplace.  */
    150          1.1     skrll 	 0,                     /* Src_mask.  */
    151          1.1     skrll 	 0,                     /* Dst_mask.  */
    152          1.1     skrll 	 FALSE),                /* PCrel_offset.  */
    153          1.1     skrll 
    154          1.1     skrll   /* GNU extension to record C++ vtable member usage.  */
    155          1.1     skrll   HOWTO (R_D10V_GNU_VTENTRY,    /* Type.  */
    156          1.1     skrll 	 0,                     /* Rightshift.  */
    157          1.1     skrll 	 2,                     /* Size (0 = byte, 1 = short, 2 = long).  */
    158          1.1     skrll 	 0,                     /* Bitsize.  */
    159          1.1     skrll 	 FALSE,                 /* PC_relative.  */
    160          1.1     skrll 	 0,                     /* Bitpos.  */
    161          1.1     skrll 	 complain_overflow_dont,/* Complain_on_overflow.  */
    162          1.1     skrll 	 _bfd_elf_rel_vtable_reloc_fn,  /* Special_function.  */
    163          1.1     skrll 	 "R_D10V_GNU_VTENTRY",  /* Name.  */
    164          1.1     skrll 	 FALSE,                 /* Partial_inplace.  */
    165          1.1     skrll 	 0,                     /* Src_mask.  */
    166          1.1     skrll 	 0,                     /* Dst_mask.  */
    167          1.1     skrll 	 FALSE),                /* PCrel_offset.  */
    168          1.1     skrll };
    169          1.1     skrll 
    170          1.1     skrll /* Map BFD reloc types to D10V ELF reloc types.  */
    171          1.1     skrll 
    172          1.1     skrll struct d10v_reloc_map
    173          1.1     skrll {
    174          1.1     skrll   bfd_reloc_code_real_type bfd_reloc_val;
    175          1.1     skrll   unsigned char elf_reloc_val;
    176          1.1     skrll };
    177          1.1     skrll 
    178          1.1     skrll static const struct d10v_reloc_map d10v_reloc_map[] =
    179          1.1     skrll {
    180          1.1     skrll   { BFD_RELOC_NONE, R_D10V_NONE, },
    181          1.1     skrll   { BFD_RELOC_D10V_10_PCREL_R, R_D10V_10_PCREL_R },
    182          1.1     skrll   { BFD_RELOC_D10V_10_PCREL_L, R_D10V_10_PCREL_L },
    183          1.1     skrll   { BFD_RELOC_16, R_D10V_16 },
    184          1.1     skrll   { BFD_RELOC_D10V_18, R_D10V_18 },
    185          1.1     skrll   { BFD_RELOC_D10V_18_PCREL, R_D10V_18_PCREL },
    186          1.1     skrll   { BFD_RELOC_32, R_D10V_32 },
    187          1.1     skrll   { BFD_RELOC_VTABLE_INHERIT, R_D10V_GNU_VTINHERIT },
    188          1.1     skrll   { BFD_RELOC_VTABLE_ENTRY, R_D10V_GNU_VTENTRY },
    189          1.1     skrll };
    190          1.1     skrll 
    191          1.1     skrll static reloc_howto_type *
    192          1.1     skrll bfd_elf32_bfd_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
    193          1.1     skrll 				 bfd_reloc_code_real_type code)
    194          1.1     skrll {
    195          1.1     skrll   unsigned int i;
    196          1.1     skrll 
    197          1.1     skrll   for (i = 0;
    198          1.1     skrll        i < sizeof (d10v_reloc_map) / sizeof (struct d10v_reloc_map);
    199          1.1     skrll        i++)
    200          1.1     skrll     if (d10v_reloc_map[i].bfd_reloc_val == code)
    201          1.1     skrll       return &elf_d10v_howto_table[d10v_reloc_map[i].elf_reloc_val];
    202          1.1     skrll 
    203          1.1     skrll   return NULL;
    204          1.1     skrll }
    205          1.1     skrll 
    206          1.1     skrll static reloc_howto_type *
    207          1.1     skrll bfd_elf32_bfd_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
    208          1.1     skrll 				 const char *r_name)
    209          1.1     skrll {
    210          1.1     skrll   unsigned int i;
    211          1.1     skrll 
    212          1.1     skrll   for (i = 0;
    213          1.1     skrll        i < sizeof (elf_d10v_howto_table) / sizeof (elf_d10v_howto_table[0]);
    214          1.1     skrll        i++)
    215          1.1     skrll     if (elf_d10v_howto_table[i].name != NULL
    216          1.1     skrll 	&& strcasecmp (elf_d10v_howto_table[i].name, r_name) == 0)
    217          1.1     skrll       return &elf_d10v_howto_table[i];
    218          1.1     skrll 
    219          1.1     skrll   return NULL;
    220          1.1     skrll }
    221          1.1     skrll 
    222          1.1     skrll /* Set the howto pointer for an D10V ELF reloc.  */
    223          1.1     skrll 
    224          1.1     skrll static void
    225          1.1     skrll d10v_info_to_howto_rel (bfd *abfd ATTRIBUTE_UNUSED,
    226          1.1     skrll 			arelent *cache_ptr,
    227          1.1     skrll 			Elf_Internal_Rela *dst)
    228          1.1     skrll {
    229          1.1     skrll   unsigned int r_type;
    230          1.1     skrll 
    231          1.1     skrll   r_type = ELF32_R_TYPE (dst->r_info);
    232          1.1     skrll   BFD_ASSERT (r_type < (unsigned int) R_D10V_max);
    233          1.1     skrll   cache_ptr->howto = &elf_d10v_howto_table[r_type];
    234          1.1     skrll }
    235          1.1     skrll 
    236          1.1     skrll static asection *
    237          1.1     skrll elf32_d10v_gc_mark_hook (asection *sec,
    238          1.1     skrll 			 struct bfd_link_info *info,
    239          1.1     skrll 			 Elf_Internal_Rela *rel,
    240          1.1     skrll 			 struct elf_link_hash_entry *h,
    241          1.1     skrll 			 Elf_Internal_Sym *sym)
    242          1.1     skrll {
    243          1.1     skrll   if (h != NULL)
    244          1.1     skrll     switch (ELF32_R_TYPE (rel->r_info))
    245          1.1     skrll       {
    246          1.1     skrll       case R_D10V_GNU_VTINHERIT:
    247          1.1     skrll       case R_D10V_GNU_VTENTRY:
    248          1.1     skrll 	return NULL;
    249          1.1     skrll       }
    250          1.1     skrll 
    251          1.1     skrll   return _bfd_elf_gc_mark_hook (sec, info, rel, h, sym);
    252          1.1     skrll }
    253          1.1     skrll 
    254          1.1     skrll /* Look through the relocs for a section during the first phase.
    255          1.1     skrll    Since we don't do .gots or .plts, we just need to consider the
    256          1.1     skrll    virtual table relocs for gc.  */
    257          1.1     skrll 
    258          1.1     skrll static bfd_boolean
    259          1.1     skrll elf32_d10v_check_relocs (bfd *abfd,
    260          1.1     skrll 			 struct bfd_link_info *info,
    261          1.1     skrll 			 asection *sec,
    262          1.1     skrll 			 const Elf_Internal_Rela *relocs)
    263          1.1     skrll {
    264          1.1     skrll   Elf_Internal_Shdr *symtab_hdr;
    265          1.1     skrll   struct elf_link_hash_entry **sym_hashes;
    266          1.1     skrll   const Elf_Internal_Rela *rel;
    267          1.1     skrll   const Elf_Internal_Rela *rel_end;
    268          1.1     skrll 
    269          1.1     skrll   if (info->relocatable)
    270          1.1     skrll     return TRUE;
    271          1.1     skrll 
    272          1.1     skrll   symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
    273          1.1     skrll   sym_hashes = elf_sym_hashes (abfd);
    274          1.1     skrll 
    275          1.1     skrll   rel_end = relocs + sec->reloc_count;
    276          1.1     skrll   for (rel = relocs; rel < rel_end; rel++)
    277          1.1     skrll     {
    278          1.1     skrll       struct elf_link_hash_entry *h;
    279          1.1     skrll       unsigned long r_symndx;
    280          1.1     skrll 
    281          1.1     skrll       r_symndx = ELF32_R_SYM (rel->r_info);
    282          1.1     skrll       if (r_symndx < symtab_hdr->sh_info)
    283          1.1     skrll         h = NULL;
    284          1.1     skrll       else
    285          1.1     skrll 	{
    286          1.1     skrll 	  h = sym_hashes[r_symndx - symtab_hdr->sh_info];
    287          1.1     skrll 	  while (h->root.type == bfd_link_hash_indirect
    288          1.1     skrll 		 || h->root.type == bfd_link_hash_warning)
    289          1.1     skrll 	    h = (struct elf_link_hash_entry *) h->root.u.i.link;
    290          1.1     skrll 	}
    291          1.1     skrll 
    292          1.1     skrll       switch (ELF32_R_TYPE (rel->r_info))
    293          1.1     skrll         {
    294          1.1     skrll         /* This relocation describes the C++ object vtable hierarchy.
    295          1.1     skrll            Reconstruct it for later use during GC.  */
    296          1.1     skrll         case R_D10V_GNU_VTINHERIT:
    297          1.1     skrll           if (!bfd_elf_gc_record_vtinherit (abfd, sec, h, rel->r_offset))
    298          1.1     skrll             return FALSE;
    299          1.1     skrll           break;
    300          1.1     skrll 
    301          1.1     skrll         /* This relocation describes which C++ vtable entries are actually
    302          1.1     skrll            used.  Record for later use during GC.  */
    303          1.1     skrll         case R_D10V_GNU_VTENTRY:
    304          1.1     skrll           BFD_ASSERT (h != NULL);
    305          1.1     skrll           if (h != NULL
    306          1.1     skrll               && !bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_offset))
    307          1.1     skrll             return FALSE;
    308          1.1     skrll           break;
    309          1.1     skrll         }
    310          1.1     skrll     }
    311          1.1     skrll 
    312          1.1     skrll   return TRUE;
    313          1.1     skrll }
    314          1.1     skrll 
    315          1.1     skrll static bfd_vma
    316          1.1     skrll extract_rel_addend (bfd *abfd,
    317          1.1     skrll 		    bfd_byte *where,
    318          1.1     skrll 		    reloc_howto_type *howto)
    319          1.1     skrll {
    320          1.1     skrll   bfd_vma insn, val;
    321          1.1     skrll 
    322          1.1     skrll   switch (howto->size)
    323          1.1     skrll     {
    324          1.1     skrll     case 0:
    325          1.1     skrll       insn = bfd_get_8 (abfd, where);
    326          1.1     skrll       break;
    327          1.1     skrll     case 1:
    328          1.1     skrll       insn = bfd_get_16 (abfd, where);
    329          1.1     skrll       break;
    330          1.1     skrll     case 2:
    331          1.1     skrll       insn = bfd_get_32 (abfd, where);
    332          1.1     skrll       break;
    333          1.1     skrll     default:
    334          1.1     skrll       abort ();
    335          1.1     skrll     }
    336          1.1     skrll 
    337          1.1     skrll   val = (insn & howto->dst_mask) >> howto->bitpos << howto->rightshift;
    338          1.1     skrll   /* We should really be testing for signed addends here, but we don't
    339          1.1     skrll      have that info directly in the howto.  */
    340          1.1     skrll   if (howto->pc_relative)
    341          1.1     skrll     {
    342          1.1     skrll       bfd_vma sign;
    343          1.1     skrll       sign = howto->dst_mask & (~howto->dst_mask >> 1 | ~(-(bfd_vma) 1 >> 1));
    344          1.1     skrll       sign = sign >> howto->bitpos << howto->rightshift;
    345          1.1     skrll       val = (val ^ sign) - sign;
    346          1.1     skrll     }
    347          1.1     skrll   return val;
    348          1.1     skrll }
    349          1.1     skrll 
    350          1.1     skrll static void
    351          1.1     skrll insert_rel_addend (bfd *abfd,
    352          1.1     skrll 		   bfd_byte *where,
    353          1.1     skrll 		   reloc_howto_type *howto,
    354          1.1     skrll 		   bfd_vma addend)
    355          1.1     skrll {
    356          1.1     skrll   bfd_vma insn;
    357          1.1     skrll 
    358          1.1     skrll   addend = (addend >> howto->rightshift << howto->bitpos) & howto->dst_mask;
    359          1.1     skrll   insn = ~howto->dst_mask;
    360          1.1     skrll   switch (howto->size)
    361          1.1     skrll     {
    362          1.1     skrll     case 0:
    363          1.1     skrll       insn &= bfd_get_8 (abfd, where);
    364          1.1     skrll       insn |= addend;
    365          1.1     skrll       bfd_put_8 (abfd, insn, where);
    366          1.1     skrll       break;
    367          1.1     skrll     case 1:
    368          1.1     skrll       insn &= bfd_get_16 (abfd, where);
    369          1.1     skrll       insn |= addend;
    370          1.1     skrll       bfd_put_16 (abfd, insn, where);
    371          1.1     skrll       break;
    372          1.1     skrll     case 2:
    373          1.1     skrll       insn &= bfd_get_32 (abfd, where);
    374          1.1     skrll       insn |= addend;
    375          1.1     skrll       bfd_put_32 (abfd, insn, where);
    376          1.1     skrll       break;
    377          1.1     skrll     default:
    378          1.1     skrll       abort ();
    379          1.1     skrll     }
    380          1.1     skrll }
    381          1.1     skrll 
    382          1.1     skrll /* Relocate a D10V ELF section.  */
    383          1.1     skrll 
    384          1.1     skrll static bfd_boolean
    385          1.1     skrll elf32_d10v_relocate_section (bfd *output_bfd,
    386          1.1     skrll 			     struct bfd_link_info *info,
    387          1.1     skrll 			     bfd *input_bfd,
    388          1.1     skrll 			     asection *input_section,
    389          1.1     skrll 			     bfd_byte *contents,
    390          1.1     skrll 			     Elf_Internal_Rela *relocs,
    391          1.1     skrll 			     Elf_Internal_Sym *local_syms,
    392          1.1     skrll 			     asection **local_sections)
    393          1.1     skrll {
    394          1.1     skrll   Elf_Internal_Shdr *symtab_hdr;
    395          1.1     skrll   struct elf_link_hash_entry **sym_hashes;
    396          1.1     skrll   Elf_Internal_Rela *rel, *relend;
    397          1.1     skrll   const char *name;
    398          1.1     skrll 
    399          1.1     skrll   symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
    400          1.1     skrll   sym_hashes = elf_sym_hashes (input_bfd);
    401          1.1     skrll 
    402          1.1     skrll   rel = relocs;
    403          1.1     skrll   relend = relocs + input_section->reloc_count;
    404          1.1     skrll   for (; rel < relend; rel++)
    405          1.1     skrll     {
    406          1.1     skrll       int r_type;
    407          1.1     skrll       reloc_howto_type *howto;
    408          1.1     skrll       unsigned long r_symndx;
    409          1.1     skrll       Elf_Internal_Sym *sym;
    410          1.1     skrll       asection *sec;
    411          1.1     skrll       struct elf_link_hash_entry *h;
    412          1.1     skrll       bfd_vma relocation;
    413          1.1     skrll       bfd_reloc_status_type r;
    414          1.1     skrll 
    415          1.1     skrll       r_symndx = ELF32_R_SYM (rel->r_info);
    416          1.1     skrll       r_type = ELF32_R_TYPE (rel->r_info);
    417          1.1     skrll 
    418          1.1     skrll       if (r_type == R_D10V_GNU_VTENTRY
    419          1.1     skrll           || r_type == R_D10V_GNU_VTINHERIT)
    420          1.1     skrll         continue;
    421          1.1     skrll 
    422          1.1     skrll       howto = elf_d10v_howto_table + r_type;
    423          1.1     skrll       h = NULL;
    424          1.1     skrll       sym = NULL;
    425          1.1     skrll       sec = NULL;
    426          1.1     skrll       if (r_symndx < symtab_hdr->sh_info)
    427          1.1     skrll 	{
    428          1.1     skrll 	  sym = local_syms + r_symndx;
    429          1.1     skrll 	  sec = local_sections[r_symndx];
    430          1.1     skrll 	  relocation = (sec->output_section->vma
    431          1.1     skrll 			+ sec->output_offset
    432          1.1     skrll 			+ sym->st_value);
    433          1.1     skrll 	  if (ELF_ST_TYPE (sym->st_info) == STT_SECTION
    434          1.1     skrll 	      && ((sec->flags & SEC_MERGE) != 0
    435          1.1     skrll 		  || (info->relocatable
    436          1.1     skrll 		      && sec->output_offset != 0)))
    437          1.1     skrll 	    {
    438          1.1     skrll 	      bfd_vma addend;
    439          1.1     skrll 	      bfd_byte *where = contents + rel->r_offset;
    440          1.1     skrll 
    441          1.1     skrll 	      addend = extract_rel_addend (input_bfd, where, howto);
    442          1.1     skrll 
    443          1.1     skrll 	      if (info->relocatable)
    444          1.1     skrll 		addend += sec->output_offset;
    445          1.1     skrll 	      else
    446          1.1     skrll 		{
    447          1.1     skrll 		  asection *msec = sec;
    448          1.1     skrll 		  addend = _bfd_elf_rel_local_sym (output_bfd, sym, &msec,
    449          1.1     skrll 						   addend);
    450          1.1     skrll 		  addend -= relocation;
    451          1.1     skrll 		  addend += msec->output_section->vma + msec->output_offset;
    452          1.1     skrll 		}
    453          1.1     skrll 	      insert_rel_addend (input_bfd, where, howto, addend);
    454          1.1     skrll 	    }
    455          1.1     skrll 	}
    456          1.1     skrll       else
    457          1.1     skrll 	{
    458          1.1     skrll 	  bfd_boolean unresolved_reloc, warned;
    459          1.1     skrll 
    460          1.1     skrll 	  RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
    461          1.1     skrll 				   r_symndx, symtab_hdr, sym_hashes,
    462          1.1     skrll 				   h, sec, relocation,
    463          1.1     skrll 				   unresolved_reloc, warned);
    464          1.1     skrll 	}
    465          1.1     skrll 
    466  1.1.1.2.2.1      yamt       if (sec != NULL && discarded_section (sec))
    467      1.1.1.2  christos 	RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
    468  1.1.1.2.2.1      yamt 					 rel, 1, relend, howto, 0, contents);
    469          1.1     skrll 
    470          1.1     skrll       if (info->relocatable)
    471          1.1     skrll 	continue;
    472          1.1     skrll 
    473          1.1     skrll       if (h != NULL)
    474          1.1     skrll 	name = h->root.root.string;
    475          1.1     skrll       else
    476          1.1     skrll 	{
    477          1.1     skrll 	  name = (bfd_elf_string_from_elf_section
    478          1.1     skrll 		  (input_bfd, symtab_hdr->sh_link, sym->st_name));
    479          1.1     skrll 	  if (name == NULL || *name == '\0')
    480          1.1     skrll 	    name = bfd_section_name (input_bfd, sec);
    481          1.1     skrll 	}
    482          1.1     skrll 
    483          1.1     skrll       r = _bfd_final_link_relocate (howto, input_bfd, input_section,
    484          1.1     skrll                                     contents, rel->r_offset,
    485          1.1     skrll                                     relocation, (bfd_vma) 0);
    486          1.1     skrll 
    487          1.1     skrll       if (r != bfd_reloc_ok)
    488          1.1     skrll 	{
    489          1.1     skrll 	  const char * msg = (const char *) 0;
    490          1.1     skrll 
    491          1.1     skrll 	  switch (r)
    492          1.1     skrll 	    {
    493          1.1     skrll 	    case bfd_reloc_overflow:
    494          1.1     skrll 	      if (!((*info->callbacks->reloc_overflow)
    495          1.1     skrll 		    (info, (h ? &h->root : NULL), name, howto->name,
    496          1.1     skrll 		     (bfd_vma) 0, input_bfd, input_section,
    497          1.1     skrll 		     rel->r_offset)))
    498          1.1     skrll 		return FALSE;
    499          1.1     skrll 	      break;
    500          1.1     skrll 
    501          1.1     skrll 	    case bfd_reloc_undefined:
    502          1.1     skrll 	      if (!((*info->callbacks->undefined_symbol)
    503          1.1     skrll 		    (info, name, input_bfd, input_section,
    504          1.1     skrll 		     rel->r_offset, TRUE)))
    505          1.1     skrll 		return FALSE;
    506          1.1     skrll 	      break;
    507          1.1     skrll 
    508          1.1     skrll 	    case bfd_reloc_outofrange:
    509          1.1     skrll 	      msg = _("internal error: out of range error");
    510          1.1     skrll 	      goto common_error;
    511          1.1     skrll 
    512          1.1     skrll 	    case bfd_reloc_notsupported:
    513          1.1     skrll 	      msg = _("internal error: unsupported relocation error");
    514          1.1     skrll 	      goto common_error;
    515          1.1     skrll 
    516          1.1     skrll 	    case bfd_reloc_dangerous:
    517          1.1     skrll 	      msg = _("internal error: dangerous error");
    518          1.1     skrll 	      goto common_error;
    519          1.1     skrll 
    520          1.1     skrll 	    default:
    521          1.1     skrll 	      msg = _("internal error: unknown error");
    522          1.1     skrll 	      /* fall through */
    523          1.1     skrll 
    524          1.1     skrll 	    common_error:
    525          1.1     skrll 	      if (!((*info->callbacks->warning)
    526          1.1     skrll 		    (info, msg, name, input_bfd, input_section,
    527          1.1     skrll 		     rel->r_offset)))
    528          1.1     skrll 		return FALSE;
    529          1.1     skrll 	      break;
    530          1.1     skrll 	    }
    531          1.1     skrll 	}
    532          1.1     skrll     }
    533          1.1     skrll 
    534          1.1     skrll   return TRUE;
    535          1.1     skrll }
    536          1.1     skrll #define ELF_ARCH		bfd_arch_d10v
    537          1.1     skrll #define ELF_MACHINE_CODE	EM_D10V
    538          1.1     skrll #define ELF_MACHINE_ALT1	EM_CYGNUS_D10V
    539          1.1     skrll #define ELF_MAXPAGESIZE		0x1000
    540          1.1     skrll 
    541          1.1     skrll #define TARGET_BIG_SYM          bfd_elf32_d10v_vec
    542          1.1     skrll #define TARGET_BIG_NAME		"elf32-d10v"
    543          1.1     skrll 
    544          1.1     skrll #define elf_info_to_howto	             0
    545          1.1     skrll #define elf_info_to_howto_rel	             d10v_info_to_howto_rel
    546          1.1     skrll #define elf_backend_object_p	             0
    547          1.1     skrll #define elf_backend_final_write_processing   0
    548          1.1     skrll #define elf_backend_gc_mark_hook             elf32_d10v_gc_mark_hook
    549          1.1     skrll #define elf_backend_check_relocs             elf32_d10v_check_relocs
    550          1.1     skrll #define elf_backend_relocate_section         elf32_d10v_relocate_section
    551          1.1     skrll #define elf_backend_can_gc_sections          1
    552          1.1     skrll 
    553          1.1     skrll #include "elf32-target.h"
    554