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