Home | History | Annotate | Line # | Download | only in bfd
      1       1.1     skrll /* D10V-specific support for 32-bit ELF
      2  1.1.1.12  christos    Copyright (C) 1996-2026 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.9  christos 	 0,			/* Size.  */
     37   1.1.1.4  christos 	 0,			/* Bitsize.  */
     38   1.1.1.9  christos 	 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.1.9  christos 	 false,			/* Partial_inplace.  */
     44       1.1     skrll 	 0,			/* Src_mask.  */
     45       1.1     skrll 	 0,			/* Dst_mask.  */
     46   1.1.1.9  christos 	 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.1.6  christos 	 2,			/* Rightshift.  */
     51   1.1.1.9  christos 	 4,			/* Size.  */
     52   1.1.1.6  christos 	 8,			/* Bitsize.  */
     53   1.1.1.9  christos 	 true,			/* PC_relative.  */
     54   1.1.1.6  christos 	 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.1.9  christos 	 false,			/* Partial_inplace.  */
     59       1.1     skrll 	 0xff,			/* Src_mask.  */
     60   1.1.1.6  christos 	 0xff,			/* Dst_mask.  */
     61   1.1.1.9  christos 	 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.1.6  christos 	 2,			/* Rightshift.  */
     66   1.1.1.9  christos 	 4,			/* Size.  */
     67   1.1.1.6  christos 	 8,			/* Bitsize.  */
     68   1.1.1.9  christos 	 true,			/* PC_relative.  */
     69   1.1.1.6  christos 	 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.1.9  christos 	 false,			/* Partial_inplace.  */
     74       1.1     skrll 	 0x07f8000,		/* Src_mask.  */
     75   1.1.1.6  christos 	 0x07f8000,		/* Dst_mask.  */
     76   1.1.1.9  christos 	 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.1.9  christos 	 2,			/* Size.  */
     82       1.1     skrll 	 16,			/* Bitsize.  */
     83   1.1.1.9  christos 	 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.1.9  christos 	 false,			/* Partial_inplace.  */
     89       1.1     skrll 	 0xffff,		/* Src_mask.  */
     90       1.1     skrll 	 0xffff,		/* Dst_mask.  */
     91   1.1.1.9  christos 	 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.1.9  christos 	 2,			/* Size.  */
     97       1.1     skrll 	 16,			/* Bitsize.  */
     98   1.1.1.9  christos 	 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.1.9  christos 	 false,			/* Partial_inplace.  */
    104       1.1     skrll 	 0xffff,		/* Src_mask.  */
    105       1.1     skrll 	 0xffff,		/* Dst_mask.  */
    106   1.1.1.9  christos 	 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.1.9  christos 	 4,			/* Size.  */
    112       1.1     skrll 	 16,			/* Bitsize.  */
    113   1.1.1.9  christos 	 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.1.9  christos 	 false,			/* Partial_inplace.  */
    119       1.1     skrll 	 0xffff,		/* Src_mask.  */
    120       1.1     skrll 	 0xffff,		/* Dst_mask.  */
    121   1.1.1.9  christos 	 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.1.9  christos 	 4,			/* Size.  */
    127       1.1     skrll 	 32,			/* Bitsize.  */
    128   1.1.1.9  christos 	 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.1.9  christos 	 false,			/* Partial_inplace.  */
    134       1.1     skrll 	 0xffffffff,		/* Src_mask.  */
    135       1.1     skrll 	 0xffffffff,		/* Dst_mask.  */
    136   1.1.1.9  christos 	 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.1.6  christos 	 0,			/* Rightshift.  */
    141   1.1.1.9  christos 	 4,			/* Size.  */
    142   1.1.1.6  christos 	 0,			/* Bitsize.  */
    143   1.1.1.9  christos 	 false,			/* PC_relative.  */
    144   1.1.1.6  christos 	 0,			/* Bitpos.  */
    145       1.1     skrll 	 complain_overflow_dont,/* Complain_on_overflow.  */
    146   1.1.1.6  christos 	 NULL,			/* Special_function.  */
    147       1.1     skrll 	 "R_D10V_GNU_VTINHERIT",/* Name.  */
    148   1.1.1.9  christos 	 false,			/* Partial_inplace.  */
    149   1.1.1.6  christos 	 0,			/* Src_mask.  */
    150   1.1.1.6  christos 	 0,			/* Dst_mask.  */
    151   1.1.1.9  christos 	 false),		/* PCrel_offset.  */
    152       1.1     skrll 
    153       1.1     skrll   /* GNU extension to record C++ vtable member usage.  */
    154   1.1.1.6  christos   HOWTO (R_D10V_GNU_VTENTRY,	/* Type.  */
    155   1.1.1.6  christos 	 0,			/* Rightshift.  */
    156   1.1.1.9  christos 	 4,			/* Size.  */
    157   1.1.1.6  christos 	 0,			/* Bitsize.  */
    158   1.1.1.9  christos 	 false,			/* PC_relative.  */
    159   1.1.1.6  christos 	 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.1.6  christos 	 "R_D10V_GNU_VTENTRY",	/* Name.  */
    163   1.1.1.9  christos 	 false,			/* Partial_inplace.  */
    164   1.1.1.6  christos 	 0,			/* Src_mask.  */
    165   1.1.1.6  christos 	 0,			/* Dst_mask.  */
    166   1.1.1.9  christos 	 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.1.9  christos static bool
    224   1.1.1.7  christos d10v_info_to_howto_rel (bfd *abfd,
    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.6  christos       /* xgettext:c-format */
    234   1.1.1.7  christos       _bfd_error_handler (_("%pB: unsupported relocation type %#x"),
    235   1.1.1.7  christos 			  abfd, r_type);
    236   1.1.1.7  christos       bfd_set_error (bfd_error_bad_value);
    237   1.1.1.9  christos       return false;
    238   1.1.1.4  christos     }
    239       1.1     skrll   cache_ptr->howto = &elf_d10v_howto_table[r_type];
    240   1.1.1.9  christos   return true;
    241       1.1     skrll }
    242       1.1     skrll 
    243       1.1     skrll static asection *
    244       1.1     skrll elf32_d10v_gc_mark_hook (asection *sec,
    245       1.1     skrll 			 struct bfd_link_info *info,
    246  1.1.1.12  christos 			 struct elf_reloc_cookie *cookie,
    247       1.1     skrll 			 struct elf_link_hash_entry *h,
    248  1.1.1.12  christos 			 unsigned int symndx)
    249       1.1     skrll {
    250       1.1     skrll   if (h != NULL)
    251  1.1.1.12  christos     switch (ELF32_R_TYPE (cookie->rel->r_info))
    252       1.1     skrll       {
    253       1.1     skrll       case R_D10V_GNU_VTINHERIT:
    254       1.1     skrll       case R_D10V_GNU_VTENTRY:
    255       1.1     skrll 	return NULL;
    256       1.1     skrll       }
    257       1.1     skrll 
    258  1.1.1.12  christos   return _bfd_elf_gc_mark_hook (sec, info, cookie, h, symndx);
    259       1.1     skrll }
    260       1.1     skrll 
    261       1.1     skrll /* Look through the relocs for a section during the first phase.
    262       1.1     skrll    Since we don't do .gots or .plts, we just need to consider the
    263       1.1     skrll    virtual table relocs for gc.  */
    264       1.1     skrll 
    265   1.1.1.9  christos static bool
    266       1.1     skrll elf32_d10v_check_relocs (bfd *abfd,
    267       1.1     skrll 			 struct bfd_link_info *info,
    268       1.1     skrll 			 asection *sec,
    269       1.1     skrll 			 const Elf_Internal_Rela *relocs)
    270       1.1     skrll {
    271       1.1     skrll   Elf_Internal_Shdr *symtab_hdr;
    272       1.1     skrll   struct elf_link_hash_entry **sym_hashes;
    273       1.1     skrll   const Elf_Internal_Rela *rel;
    274       1.1     skrll   const Elf_Internal_Rela *rel_end;
    275       1.1     skrll 
    276   1.1.1.4  christos   if (bfd_link_relocatable (info))
    277   1.1.1.9  christos     return true;
    278       1.1     skrll 
    279       1.1     skrll   symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
    280       1.1     skrll   sym_hashes = elf_sym_hashes (abfd);
    281       1.1     skrll 
    282       1.1     skrll   rel_end = relocs + sec->reloc_count;
    283       1.1     skrll   for (rel = relocs; rel < rel_end; rel++)
    284       1.1     skrll     {
    285       1.1     skrll       struct elf_link_hash_entry *h;
    286       1.1     skrll       unsigned long r_symndx;
    287       1.1     skrll 
    288       1.1     skrll       r_symndx = ELF32_R_SYM (rel->r_info);
    289       1.1     skrll       if (r_symndx < symtab_hdr->sh_info)
    290   1.1.1.6  christos 	h = NULL;
    291       1.1     skrll       else
    292       1.1     skrll 	{
    293       1.1     skrll 	  h = sym_hashes[r_symndx - symtab_hdr->sh_info];
    294       1.1     skrll 	  while (h->root.type == bfd_link_hash_indirect
    295       1.1     skrll 		 || h->root.type == bfd_link_hash_warning)
    296       1.1     skrll 	    h = (struct elf_link_hash_entry *) h->root.u.i.link;
    297       1.1     skrll 	}
    298       1.1     skrll 
    299       1.1     skrll       switch (ELF32_R_TYPE (rel->r_info))
    300   1.1.1.6  christos 	{
    301   1.1.1.6  christos 	/* This relocation describes the C++ object vtable hierarchy.
    302   1.1.1.6  christos 	   Reconstruct it for later use during GC.  */
    303   1.1.1.6  christos 	case R_D10V_GNU_VTINHERIT:
    304   1.1.1.6  christos 	  if (!bfd_elf_gc_record_vtinherit (abfd, sec, h, rel->r_offset))
    305   1.1.1.9  christos 	    return false;
    306   1.1.1.6  christos 	  break;
    307   1.1.1.6  christos 
    308   1.1.1.6  christos 	/* This relocation describes which C++ vtable entries are actually
    309   1.1.1.6  christos 	   used.  Record for later use during GC.  */
    310   1.1.1.6  christos 	case R_D10V_GNU_VTENTRY:
    311   1.1.1.8  christos 	  if (!bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_offset))
    312   1.1.1.9  christos 	    return false;
    313   1.1.1.6  christos 	  break;
    314   1.1.1.6  christos 	}
    315       1.1     skrll     }
    316       1.1     skrll 
    317   1.1.1.9  christos   return true;
    318       1.1     skrll }
    319       1.1     skrll 
    320       1.1     skrll static bfd_vma
    321       1.1     skrll extract_rel_addend (bfd *abfd,
    322       1.1     skrll 		    bfd_byte *where,
    323       1.1     skrll 		    reloc_howto_type *howto)
    324       1.1     skrll {
    325       1.1     skrll   bfd_vma insn, val;
    326       1.1     skrll 
    327   1.1.1.9  christos   switch (bfd_get_reloc_size (howto))
    328       1.1     skrll     {
    329   1.1.1.9  christos     case 1:
    330       1.1     skrll       insn = bfd_get_8 (abfd, where);
    331       1.1     skrll       break;
    332   1.1.1.9  christos     case 2:
    333       1.1     skrll       insn = bfd_get_16 (abfd, where);
    334       1.1     skrll       break;
    335   1.1.1.9  christos     case 4:
    336       1.1     skrll       insn = bfd_get_32 (abfd, where);
    337       1.1     skrll       break;
    338       1.1     skrll     default:
    339       1.1     skrll       abort ();
    340       1.1     skrll     }
    341       1.1     skrll 
    342       1.1     skrll   val = (insn & howto->dst_mask) >> howto->bitpos << howto->rightshift;
    343       1.1     skrll   /* We should really be testing for signed addends here, but we don't
    344       1.1     skrll      have that info directly in the howto.  */
    345       1.1     skrll   if (howto->pc_relative)
    346       1.1     skrll     {
    347       1.1     skrll       bfd_vma sign;
    348       1.1     skrll       sign = howto->dst_mask & (~howto->dst_mask >> 1 | ~(-(bfd_vma) 1 >> 1));
    349       1.1     skrll       sign = sign >> howto->bitpos << howto->rightshift;
    350       1.1     skrll       val = (val ^ sign) - sign;
    351       1.1     skrll     }
    352       1.1     skrll   return val;
    353       1.1     skrll }
    354       1.1     skrll 
    355       1.1     skrll static void
    356       1.1     skrll insert_rel_addend (bfd *abfd,
    357       1.1     skrll 		   bfd_byte *where,
    358       1.1     skrll 		   reloc_howto_type *howto,
    359       1.1     skrll 		   bfd_vma addend)
    360       1.1     skrll {
    361       1.1     skrll   bfd_vma insn;
    362       1.1     skrll 
    363       1.1     skrll   addend = (addend >> howto->rightshift << howto->bitpos) & howto->dst_mask;
    364       1.1     skrll   insn = ~howto->dst_mask;
    365   1.1.1.9  christos   switch (bfd_get_reloc_size (howto))
    366       1.1     skrll     {
    367   1.1.1.9  christos     case 1:
    368       1.1     skrll       insn &= bfd_get_8 (abfd, where);
    369       1.1     skrll       insn |= addend;
    370       1.1     skrll       bfd_put_8 (abfd, insn, where);
    371       1.1     skrll       break;
    372   1.1.1.9  christos     case 2:
    373       1.1     skrll       insn &= bfd_get_16 (abfd, where);
    374       1.1     skrll       insn |= addend;
    375       1.1     skrll       bfd_put_16 (abfd, insn, where);
    376       1.1     skrll       break;
    377   1.1.1.9  christos     case 4:
    378       1.1     skrll       insn &= bfd_get_32 (abfd, where);
    379       1.1     skrll       insn |= addend;
    380       1.1     skrll       bfd_put_32 (abfd, insn, where);
    381       1.1     skrll       break;
    382       1.1     skrll     default:
    383       1.1     skrll       abort ();
    384       1.1     skrll     }
    385       1.1     skrll }
    386       1.1     skrll 
    387       1.1     skrll /* Relocate a D10V ELF section.  */
    388       1.1     skrll 
    389   1.1.1.9  christos static int
    390       1.1     skrll elf32_d10v_relocate_section (bfd *output_bfd,
    391       1.1     skrll 			     struct bfd_link_info *info,
    392       1.1     skrll 			     bfd *input_bfd,
    393       1.1     skrll 			     asection *input_section,
    394       1.1     skrll 			     bfd_byte *contents,
    395       1.1     skrll 			     Elf_Internal_Rela *relocs,
    396       1.1     skrll 			     Elf_Internal_Sym *local_syms,
    397       1.1     skrll 			     asection **local_sections)
    398       1.1     skrll {
    399       1.1     skrll   Elf_Internal_Shdr *symtab_hdr;
    400       1.1     skrll   struct elf_link_hash_entry **sym_hashes;
    401       1.1     skrll   Elf_Internal_Rela *rel, *relend;
    402       1.1     skrll   const char *name;
    403       1.1     skrll 
    404       1.1     skrll   symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
    405       1.1     skrll   sym_hashes = elf_sym_hashes (input_bfd);
    406       1.1     skrll 
    407       1.1     skrll   rel = relocs;
    408       1.1     skrll   relend = relocs + input_section->reloc_count;
    409       1.1     skrll   for (; rel < relend; rel++)
    410       1.1     skrll     {
    411       1.1     skrll       int r_type;
    412       1.1     skrll       reloc_howto_type *howto;
    413       1.1     skrll       unsigned long r_symndx;
    414       1.1     skrll       Elf_Internal_Sym *sym;
    415       1.1     skrll       asection *sec;
    416       1.1     skrll       struct elf_link_hash_entry *h;
    417       1.1     skrll       bfd_vma relocation;
    418       1.1     skrll       bfd_reloc_status_type r;
    419       1.1     skrll 
    420       1.1     skrll       r_symndx = ELF32_R_SYM (rel->r_info);
    421       1.1     skrll       r_type = ELF32_R_TYPE (rel->r_info);
    422       1.1     skrll 
    423       1.1     skrll       if (r_type == R_D10V_GNU_VTENTRY
    424   1.1.1.6  christos 	  || r_type == R_D10V_GNU_VTINHERIT)
    425   1.1.1.6  christos 	continue;
    426       1.1     skrll 
    427       1.1     skrll       howto = elf_d10v_howto_table + r_type;
    428       1.1     skrll       h = NULL;
    429       1.1     skrll       sym = NULL;
    430       1.1     skrll       sec = NULL;
    431       1.1     skrll       if (r_symndx < symtab_hdr->sh_info)
    432       1.1     skrll 	{
    433       1.1     skrll 	  sym = local_syms + r_symndx;
    434       1.1     skrll 	  sec = local_sections[r_symndx];
    435       1.1     skrll 	  relocation = (sec->output_section->vma
    436       1.1     skrll 			+ sec->output_offset
    437       1.1     skrll 			+ sym->st_value);
    438       1.1     skrll 	  if (ELF_ST_TYPE (sym->st_info) == STT_SECTION
    439       1.1     skrll 	      && ((sec->flags & SEC_MERGE) != 0
    440   1.1.1.4  christos 		  || (bfd_link_relocatable (info)
    441       1.1     skrll 		      && sec->output_offset != 0)))
    442       1.1     skrll 	    {
    443       1.1     skrll 	      bfd_vma addend;
    444       1.1     skrll 	      bfd_byte *where = contents + rel->r_offset;
    445       1.1     skrll 
    446       1.1     skrll 	      addend = extract_rel_addend (input_bfd, where, howto);
    447       1.1     skrll 
    448   1.1.1.4  christos 	      if (bfd_link_relocatable (info))
    449       1.1     skrll 		addend += sec->output_offset;
    450       1.1     skrll 	      else
    451       1.1     skrll 		{
    452       1.1     skrll 		  asection *msec = sec;
    453       1.1     skrll 		  addend = _bfd_elf_rel_local_sym (output_bfd, sym, &msec,
    454       1.1     skrll 						   addend);
    455       1.1     skrll 		  addend -= relocation;
    456       1.1     skrll 		  addend += msec->output_section->vma + msec->output_offset;
    457       1.1     skrll 		}
    458       1.1     skrll 	      insert_rel_addend (input_bfd, where, howto, addend);
    459       1.1     skrll 	    }
    460       1.1     skrll 	}
    461       1.1     skrll       else
    462       1.1     skrll 	{
    463   1.1.1.9  christos 	  bool unresolved_reloc, warned, ignored;
    464       1.1     skrll 
    465       1.1     skrll 	  RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
    466       1.1     skrll 				   r_symndx, symtab_hdr, sym_hashes,
    467       1.1     skrll 				   h, sec, relocation,
    468   1.1.1.4  christos 				   unresolved_reloc, warned, ignored);
    469       1.1     skrll 	}
    470       1.1     skrll 
    471   1.1.1.3  christos       if (sec != NULL && discarded_section (sec))
    472   1.1.1.2  christos 	RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
    473  1.1.1.12  christos 					 rel, 1, relend, R_D10V_NONE,
    474  1.1.1.12  christos 					 howto, 0, contents);
    475       1.1     skrll 
    476   1.1.1.4  christos       if (bfd_link_relocatable (info))
    477       1.1     skrll 	continue;
    478       1.1     skrll 
    479       1.1     skrll       if (h != NULL)
    480       1.1     skrll 	name = h->root.root.string;
    481       1.1     skrll       else
    482       1.1     skrll 	{
    483       1.1     skrll 	  name = (bfd_elf_string_from_elf_section
    484       1.1     skrll 		  (input_bfd, symtab_hdr->sh_link, sym->st_name));
    485       1.1     skrll 	  if (name == NULL || *name == '\0')
    486   1.1.1.8  christos 	    name = bfd_section_name (sec);
    487       1.1     skrll 	}
    488       1.1     skrll 
    489       1.1     skrll       r = _bfd_final_link_relocate (howto, input_bfd, input_section,
    490   1.1.1.6  christos 				    contents, rel->r_offset,
    491   1.1.1.6  christos 				    relocation, (bfd_vma) 0);
    492       1.1     skrll 
    493       1.1     skrll       if (r != bfd_reloc_ok)
    494       1.1     skrll 	{
    495       1.1     skrll 	  const char * msg = (const char *) 0;
    496       1.1     skrll 
    497       1.1     skrll 	  switch (r)
    498       1.1     skrll 	    {
    499       1.1     skrll 	    case bfd_reloc_overflow:
    500   1.1.1.5  christos 	      (*info->callbacks->reloc_overflow)
    501   1.1.1.5  christos 		(info, (h ? &h->root : NULL), name, howto->name,
    502   1.1.1.5  christos 		 (bfd_vma) 0, input_bfd, input_section, rel->r_offset);
    503       1.1     skrll 	      break;
    504       1.1     skrll 
    505       1.1     skrll 	    case bfd_reloc_undefined:
    506   1.1.1.5  christos 	      (*info->callbacks->undefined_symbol)
    507   1.1.1.9  christos 		(info, name, input_bfd, input_section, rel->r_offset, true);
    508       1.1     skrll 	      break;
    509       1.1     skrll 
    510       1.1     skrll 	    case bfd_reloc_outofrange:
    511       1.1     skrll 	      msg = _("internal error: out of range error");
    512       1.1     skrll 	      goto common_error;
    513       1.1     skrll 
    514       1.1     skrll 	    case bfd_reloc_notsupported:
    515       1.1     skrll 	      msg = _("internal error: unsupported relocation error");
    516       1.1     skrll 	      goto common_error;
    517       1.1     skrll 
    518       1.1     skrll 	    case bfd_reloc_dangerous:
    519       1.1     skrll 	      msg = _("internal error: dangerous error");
    520       1.1     skrll 	      goto common_error;
    521       1.1     skrll 
    522       1.1     skrll 	    default:
    523       1.1     skrll 	      msg = _("internal error: unknown error");
    524       1.1     skrll 	      /* fall through */
    525       1.1     skrll 
    526       1.1     skrll 	    common_error:
    527   1.1.1.5  christos 	      (*info->callbacks->warning) (info, msg, name, input_bfd,
    528   1.1.1.5  christos 					   input_section, rel->r_offset);
    529       1.1     skrll 	      break;
    530       1.1     skrll 	    }
    531       1.1     skrll 	}
    532       1.1     skrll     }
    533       1.1     skrll 
    534   1.1.1.9  christos   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.1.6  christos #define TARGET_BIG_SYM		d10v_elf32_vec
    542       1.1     skrll #define TARGET_BIG_NAME		"elf32-d10v"
    543       1.1     skrll 
    544   1.1.1.7  christos #define elf_info_to_howto		     NULL
    545   1.1.1.6  christos #define elf_info_to_howto_rel		     d10v_info_to_howto_rel
    546   1.1.1.6  christos #define elf_backend_object_p		     0
    547   1.1.1.6  christos #define elf_backend_gc_mark_hook	     elf32_d10v_gc_mark_hook
    548   1.1.1.6  christos #define elf_backend_check_relocs	     elf32_d10v_check_relocs
    549   1.1.1.6  christos #define elf_backend_relocate_section	     elf32_d10v_relocate_section
    550   1.1.1.6  christos #define elf_backend_can_gc_sections	     1
    551       1.1     skrll 
    552       1.1     skrll #include "elf32-target.h"
    553