Home | History | Annotate | Download | only in bfd
      1 /* D30V-specific support for 32-bit ELF
      2    Copyright (C) 1997-2016 Free Software Foundation, Inc.
      3    Contributed by Martin Hunt (hunt (at) cygnus.com).
      4 
      5    This file is part of BFD, the Binary File Descriptor library.
      6 
      7    This program is free software; you can redistribute it and/or modify
      8    it under the terms of the GNU General Public License as published by
      9    the Free Software Foundation; either version 3 of the License, or
     10    (at your option) any later version.
     11 
     12    This program is distributed in the hope that it will be useful,
     13    but WITHOUT ANY WARRANTY; without even the implied warranty of
     14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     15    GNU General Public License for more details.
     16 
     17    You should have received a copy of the GNU General Public License
     18    along with this program; if not, write to the Free Software
     19    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
     20    MA 02110-1301, USA.  */
     21 
     22 #include "sysdep.h"
     23 #include "bfd.h"
     24 #include "libbfd.h"
     25 #include "elf-bfd.h"
     26 #include "elf/d30v.h"
     27 
     28 #define MAX32 ((bfd_signed_vma) 0x7fffffff)
     29 #define MIN32 (- MAX32 - 1)
     30 
     31 static bfd_reloc_status_type
     32 bfd_elf_d30v_reloc (bfd *abfd,
     33 		    arelent *reloc_entry,
     34 		    asymbol *symbol,
     35 		    void * data,
     36 		    asection *input_section,
     37 		    bfd *output_bfd,
     38 		    char **error_message)
     39 {
     40   bfd_signed_vma relocation;
     41   bfd_vma in1, in2, num;
     42   bfd_vma tmp_addr = 0;
     43   bfd_reloc_status_type r;
     44   asection *reloc_target_output_section;
     45   bfd_size_type addr = reloc_entry->address;
     46   bfd_reloc_status_type flag = bfd_reloc_ok;
     47   bfd_vma output_base = 0;
     48   reloc_howto_type *howto = reloc_entry->howto;
     49   int make_absolute = 0;
     50 
     51   if (output_bfd != NULL)
     52     {
     53       /* Partial linking -- do nothing.  */
     54       reloc_entry->address += input_section->output_offset;
     55       return bfd_reloc_ok;
     56     }
     57 
     58   r = bfd_elf_generic_reloc (abfd, reloc_entry, symbol, data,
     59                              input_section, output_bfd, error_message);
     60   if (r != bfd_reloc_continue)
     61     return r;
     62 
     63   /* A hacked-up version of bfd_perform_reloc() follows.  */
     64  if (bfd_is_und_section (symbol->section)
     65       && (symbol->flags & BSF_WEAK) == 0
     66       && output_bfd == NULL)
     67     flag = bfd_reloc_undefined;
     68 
     69   /* Is the address of the relocation really within the section?  */
     70   if (reloc_entry->address > bfd_get_section_limit (abfd, input_section))
     71     return bfd_reloc_outofrange;
     72 
     73   /* Work out which section the relocation is targeted at and the
     74      initial relocation command value.  */
     75 
     76   /* Get symbol value.  (Common symbols are special.)  */
     77   if (bfd_is_com_section (symbol->section))
     78     relocation = 0;
     79   else
     80     relocation = symbol->value;
     81 
     82   reloc_target_output_section = symbol->section->output_section;
     83 
     84   /* Convert input-section-relative symbol value to absolute.  */
     85   output_base = reloc_target_output_section->vma;
     86   relocation += output_base + symbol->section->output_offset;
     87 
     88   /* Add in supplied addend.  */
     89   relocation += reloc_entry->addend;
     90 
     91   /* Here the variable relocation holds the final address of the
     92      symbol we are relocating against, plus any addend.  */
     93   if (howto->pc_relative)
     94     {
     95       tmp_addr = input_section->output_section->vma
     96 	+ input_section->output_offset
     97 	+ reloc_entry->address;
     98       relocation -= tmp_addr;
     99     }
    100 
    101   in1 = bfd_get_32 (abfd, (bfd_byte *) data + addr);
    102   in2 = bfd_get_32 (abfd, (bfd_byte *) data + addr + 4);
    103 
    104   /* Extract the addend.  */
    105   num = ((in2 & 0x3FFFF)
    106 	 | ((in2 & 0xFF00000) >> 2)
    107 	 | ((in1 & 0x3F) << 26));
    108   in1 &= 0xFFFFFFC0;
    109   in2 = 0x80000000;
    110 
    111   relocation += num;
    112 
    113   if (howto->pc_relative && howto->bitsize == 32)
    114     {
    115       /* The D30V has a PC that doesn't wrap and PC-relative jumps are
    116 	 signed, so a PC-relative jump can't be more than +/- 2^31 bytes.
    117 	 If one exceeds this, change it to an absolute jump.  */
    118       if (relocation > MAX32 || relocation < MIN32)
    119 	{
    120 	  relocation = (relocation + tmp_addr) & 0xffffffff;
    121 	  make_absolute = 1;
    122 	}
    123     }
    124 
    125   in1 |= (relocation >> 26) & 0x3F;		/* Top 6 bits.  */
    126   in2 |= ((relocation & 0x03FC0000) << 2);  	/* Next 8 bits.  */
    127   in2 |= relocation & 0x0003FFFF;		/* Bottom 18 bits.  */
    128 
    129   /* Change a PC-relative instruction to its
    130      absolute equivalent with this simple hack.  */
    131   if (make_absolute)
    132     in1 |= 0x00100000;
    133 
    134   bfd_put_32 (abfd, in1, (bfd_byte *) data + addr);
    135   bfd_put_32 (abfd, in2, (bfd_byte *) data + addr + 4);
    136 
    137   return flag;
    138 }
    139 
    140 static bfd_reloc_status_type
    141 bfd_elf_d30v_reloc_21 (bfd *abfd,
    142 		       arelent *reloc_entry,
    143 		       asymbol *symbol,
    144 		       void * data,
    145 		       asection *input_section,
    146 		       bfd *output_bfd,
    147 		       char **error_message)
    148 {
    149   bfd_vma relocation;
    150   bfd_vma in1, num;
    151   bfd_reloc_status_type r;
    152   asection *reloc_target_output_section;
    153   bfd_size_type addr = reloc_entry->address;
    154   bfd_reloc_status_type flag = bfd_reloc_ok;
    155   bfd_vma output_base = 0;
    156   reloc_howto_type *howto = reloc_entry->howto;
    157   int mask, max;
    158 
    159   if (output_bfd != NULL)
    160     {
    161       /* Partial linking -- do nothing.  */
    162       reloc_entry->address += input_section->output_offset;
    163       return bfd_reloc_ok;
    164     }
    165 
    166   r = bfd_elf_generic_reloc (abfd, reloc_entry, symbol, data,
    167                              input_section, output_bfd, error_message);
    168   if (r != bfd_reloc_continue)
    169     return r;
    170 
    171   /* A hacked-up version of bfd_perform_reloc() follows.  */
    172   if (bfd_is_und_section (symbol->section)
    173       && (symbol->flags & BSF_WEAK) == 0
    174       && output_bfd == NULL)
    175     flag = bfd_reloc_undefined;
    176 
    177   /* Is the address of the relocation really within the section?  */
    178   if (reloc_entry->address > bfd_get_section_limit (abfd, input_section))
    179     return bfd_reloc_outofrange;
    180 
    181   /* Work out which section the relocation is targeted at and the
    182      initial relocation command value.  */
    183 
    184   /* Get symbol value.  (Common symbols are special.)  */
    185   if (bfd_is_com_section (symbol->section))
    186     relocation = 0;
    187   else
    188     relocation = symbol->value;
    189 
    190   reloc_target_output_section = symbol->section->output_section;
    191 
    192   /* Convert input-section-relative symbol value to absolute.  */
    193   output_base = reloc_target_output_section->vma;
    194   relocation += output_base + symbol->section->output_offset;
    195 
    196   /* Add in supplied addend.  */
    197   relocation += reloc_entry->addend;
    198 
    199   /* Here the variable relocation holds the final address of the
    200      symbol we are relocating against, plus any addend.  */
    201 
    202   if (howto->pc_relative)
    203     {
    204       relocation -= (input_section->output_section->vma
    205 		     + input_section->output_offset);
    206       if (howto->pcrel_offset)
    207 	relocation -= reloc_entry->address;
    208     }
    209 
    210   in1 = bfd_get_32 (abfd, (bfd_byte *) data + addr);
    211 
    212   mask =  (1 << howto->bitsize) - 1;
    213   if (howto->bitsize == 6)
    214     mask <<= 12;
    215   max = (1 << (howto->bitsize + 2)) - 1;
    216 
    217   /* Extract the addend.  */
    218   num = in1 & mask;  /* 18 bits.  */
    219   if (howto->bitsize == 6)
    220     num >>= 12;
    221   num <<= 3; /* shift left 3.  */
    222   in1 &= ~mask;  /* Mask out addend.  */
    223 
    224   relocation += num;
    225   if (howto->type == R_D30V_21_PCREL_R
    226       || howto->type == R_D30V_15_PCREL_R
    227       || howto->type == R_D30V_9_PCREL_R)
    228     relocation += 4;
    229 
    230   if ((int) relocation < 0)
    231     {
    232       if (~ (int) relocation > max)
    233 	flag = bfd_reloc_overflow;
    234     }
    235   else
    236     {
    237       if ((int) relocation > max)
    238 	flag = bfd_reloc_overflow;
    239     }
    240 
    241   relocation >>= 3;
    242   if (howto->bitsize == 6)
    243     in1 |= ((relocation & (mask >> 12)) << 12);
    244   else
    245     in1 |= relocation & mask;
    246 
    247   bfd_put_32 (abfd, in1, (bfd_byte *) data + addr);
    248 
    249   return flag;
    250 }
    251 
    252 static reloc_howto_type elf_d30v_howto_table[] =
    253 {
    254   /* This reloc does nothing.  */
    255   HOWTO (R_D30V_NONE,		/* Type.  */
    256 	 0,			/* Rightshift.  */
    257 	 3,			/* Size (0 = byte, 1 = short, 2 = long).  */
    258 	 0,			/* Bitsize.  */
    259 	 FALSE,			/* PC_relative.  */
    260 	 0,			/* Bitpos.  */
    261 	 complain_overflow_dont, /* Complain_on_overflow.  */
    262 	 bfd_elf_generic_reloc,	/* Special_function.  */
    263 	 "R_D30V_NONE",		/* Name.  */
    264 	 FALSE,			/* Partial_inplace.  */
    265 	 0,			/* Src_mask.  */
    266 	 0,			/* Dst_mask.  */
    267 	 FALSE),		/* PCrel_offset.  */
    268 
    269   /* A 6 bit absolute relocation.  */
    270   HOWTO (R_D30V_6,		/* Type.  */
    271 	 0,			/* Rightshift.  */
    272 	 2,			/* Size (0 = byte, 1 = short, 2 = long).  */
    273 	 6,			/* Bitsize.  */
    274 	 FALSE,			/* PC_relative.  */
    275 	 0,			/* Bitpos.  */
    276 	 complain_overflow_bitfield, /* Complain_on_overflow.  */
    277 	 bfd_elf_generic_reloc,	/* Special_function.  */
    278 	 "R_D30V_6",		/* Name.  */
    279 	 FALSE,			/* Partial_inplace.  */
    280 	 0x3f,			/* Src_mask.  */
    281 	 0x3f,			/* Dst_mask.  */
    282 	 FALSE),		/* PCrel_offset.  */
    283 
    284   /* A relative 9 bit relocation, right shifted by 3.  */
    285   HOWTO (R_D30V_9_PCREL,	/* Type.  */
    286 	 3,			/* Rightshift.  */
    287 	 2,			/* Size (0 = byte, 1 = short, 2 = long).  */
    288 	 6,			/* Bitsize.  */
    289 	 TRUE,			/* PC_relative.  */
    290 	 0,			/* Bitpos.  */
    291 	 complain_overflow_signed, /* Complain_on_overflow.  */
    292 	 bfd_elf_d30v_reloc_21,	/* Special_function.  */
    293 	 "R_D30V_9_PCREL",	/* Name.  */
    294 	 FALSE,			/* Partial_inplace.  */
    295 	 0x3f,			/* Src_mask.  */
    296 	 0x3f,			/* Dst_mask.  */
    297 	 TRUE),			/* PCrel_offset.  */
    298 
    299   /* A relative 9 bit relocation, right shifted by 3.  */
    300   HOWTO (R_D30V_9_PCREL_R,	/* Type.  */
    301 	 3,			/* Rightshift.  */
    302 	 2,			/* Size (0 = byte, 1 = short, 2 = long).  */
    303 	 6,			/* Bitsize.  */
    304 	 TRUE,			/* PC_relative.  */
    305 	 0,			/* Bitpos.  */
    306 	 complain_overflow_signed, /* Complain_on_overflow.  */
    307 	 bfd_elf_d30v_reloc_21,	/* Special_function.  */
    308 	 "R_D30V_9_PCREL_R",	/* Name.  */
    309 	 FALSE,			/* Partial_inplace.  */
    310 	 0x3f,			/* Src_mask.  */
    311 	 0x3f,			/* Dst_mask.  */
    312 	 TRUE),			/* PCrel_offset.  */
    313 
    314   /* An absolute 15 bit relocation, right shifted by 3.  */
    315   HOWTO (R_D30V_15,		/* Type.  */
    316 	 3,			/* Rightshift.  */
    317 	 2,			/* Size (0 = byte, 1 = short, 2 = long).  */
    318 	 12,			/* Bitsize.  */
    319 	 FALSE,			/* PC_relative.  */
    320 	 0,			/* Bitpos.  */
    321 	 complain_overflow_signed, /* Complain_on_overflow.  */
    322 	 bfd_elf_generic_reloc,	/* Special_function.  */
    323 	 "R_D30V_15",		/* Name.  */
    324 	 FALSE,			/* Partial_inplace.  */
    325 	 0xfff,			/* Src_mask.  */
    326 	 0xfff,			/* Dst_mask.  */
    327 	 FALSE),		/* PCrel_offset.  */
    328 
    329   /* A relative 15 bit relocation, right shifted by 3.  */
    330   HOWTO (R_D30V_15_PCREL,	/* Type.  */
    331 	 3,			/* Rightshift.  */
    332 	 2,			/* Size (0 = byte, 1 = short, 2 = long).  */
    333 	 12,			/* Bitsize.  */
    334 	 TRUE,			/* PC_relative.  */
    335 	 0,			/* Bitpos.  */
    336 	 complain_overflow_signed, /* Complain_on_overflow.  */
    337 	 bfd_elf_d30v_reloc_21,	/* Special_function.  */
    338 	 "R_D30V_15_PCREL",	/* Name.  */
    339 	 FALSE,			/* Partial_inplace.  */
    340 	 0xfff,			/* Src_mask.  */
    341 	 0xfff,			/* Dst_mask.  */
    342 	 TRUE),			/* PCrel_offset.  */
    343 
    344   /* A relative 15 bit relocation, right shifted by 3.  */
    345   HOWTO (R_D30V_15_PCREL_R,	/* Type.  */
    346 	 3,			/* Rightshift.  */
    347 	 2,			/* Size (0 = byte, 1 = short, 2 = long).  */
    348 	 12,			/* Bitsize.  */
    349 	 TRUE,			/* PC_relative.  */
    350 	 0,			/* Bitpos.  */
    351 	 complain_overflow_signed, /* Complain_on_overflow.  */
    352 	 bfd_elf_d30v_reloc_21,	/* Special_function.  */
    353 	 "R_D30V_15_PCREL_R",	/* Name.  */
    354 	 FALSE,			/* Partial_inplace.  */
    355 	 0xfff,			/* Src_mask.  */
    356 	 0xfff,			/* Dst_mask.  */
    357 	 TRUE),			/* PCrel_offset.  */
    358 
    359   /* An absolute 21 bit relocation, right shifted by 3.  */
    360   HOWTO (R_D30V_21,		/* Type.  */
    361 	 3,			/* Rightshift.  */
    362 	 2,			/* Size (0 = byte, 1 = short, 2 = long).  */
    363 	 18,			/* Bitsize.  */
    364 	 FALSE,			/* PC_relative.  */
    365 	 0,			/* Bitpos.  */
    366 	 complain_overflow_signed, /* Complain_on_overflow.  */
    367 	 bfd_elf_generic_reloc,	/* Special_function.  */
    368 	 "R_D30V_21",		/* Name.  */
    369 	 FALSE,			/* Partial_inplace.  */
    370 	 0x3ffff,		/* Src_mask.  */
    371 	 0x3ffff,		/* Dst_mask.  */
    372 	 FALSE),		/* PCrel_offset.  */
    373 
    374   /* A relative 21 bit relocation, right shifted by 3.  */
    375   HOWTO (R_D30V_21_PCREL,	/* Type.  */
    376 	 3,			/* Rightshift.  */
    377 	 2,			/* Size (0 = byte, 1 = short, 2 = long).  */
    378 	 18,			/* Bitsize.  */
    379 	 TRUE,			/* PC_relative.  */
    380 	 0,			/* Bitpos.  */
    381 	 complain_overflow_signed, /* Complain_on_overflow.  */
    382 	 bfd_elf_d30v_reloc_21,	/* Special_function.  */
    383 	 "R_D30V_21_PCREL",	/* Name.  */
    384 	 FALSE,			/* Partial_inplace.  */
    385 	 0x3ffff,		/* Src_mask.  */
    386 	 0x3ffff,		/* Dst_mask.  */
    387 	 TRUE),			/* PCrel_offset.  */
    388 
    389   /* A relative 21 bit relocation, right shifted by 3, in the Right container.  */
    390   HOWTO (R_D30V_21_PCREL_R,	/* Type.  */
    391 	 3,			/* Rightshift.  */
    392 	 2,			/* Size (0 = byte, 1 = short, 2 = long).  */
    393 	 18,			/* Bitsize.  */
    394 	 TRUE,			/* PC_relative.  */
    395 	 0,			/* Bitpos.  */
    396 	 complain_overflow_signed, /* Complain_on_overflow.  */
    397 	 bfd_elf_d30v_reloc_21,	/* Special_function.  */
    398 	 "R_D30V_21_PCREL_R",	/* Name.  */
    399 	 FALSE,			/* Partial_inplace.  */
    400 	 0x3ffff,		/* Src_mask.  */
    401 	 0x3ffff,		/* Dst_mask.  */
    402 	 TRUE),			/* PCrel_offset.  */
    403 
    404   /* A D30V 32 bit absolute relocation.  */
    405   HOWTO (R_D30V_32,		/* Type.  */
    406 	 0,			/* Rightshift.  */
    407 	 4,			/* Size (0 = byte, 1 = short, 2 = long).  */
    408 	 32,			/* Bitsize.  */
    409 	 FALSE,			/* PC_relative.  */
    410 	 0,			/* Bitpos.  */
    411 	 complain_overflow_bitfield, /* Complain_on_overflow.  */
    412 	 bfd_elf_d30v_reloc,	/* Special_function.  */
    413 	 "R_D30V_32",		/* Name.  */
    414 	 FALSE,			/* Partial_inplace.  */
    415 	 0xffffffff,		/* Src_mask.  */
    416 	 0xffffffff,		/* Dst_mask.  */
    417 	 FALSE),		/* PCrel_offset.  */
    418 
    419   /* A relative 32 bit relocation.  */
    420   HOWTO (R_D30V_32_PCREL,	/* Type.  */
    421 	 0,			/* Rightshift.  */
    422 	 4,			/* Size (0 = byte, 1 = short, 2 = long).  */
    423 	 32,			/* Bitsize.  */
    424 	 TRUE,			/* PC_relative.  */
    425 	 0,			/* Bitpos.  */
    426 	 complain_overflow_signed, /* Complain_on_overflow.  */
    427 	 bfd_elf_d30v_reloc,	/* Special_function.  */
    428 	 "R_D30V_32_PCREL",	/* Name.  */
    429 	 FALSE,			/* Partial_inplace.  */
    430 	 0xffffffff,		/* Src_mask.  */
    431 	 0xffffffff,		/* Dst_mask.  */
    432 	 TRUE),			/* PCrel_offset.  */
    433 
    434   /* A regular 32 bit absolute relocation.  */
    435   HOWTO (R_D30V_32_NORMAL,	/* Type.  */
    436 	 0,			/* Rightshift.  */
    437 	 2,			/* Size (0 = byte, 1 = short, 2 = long).  */
    438 	 32,			/* Bitsize.  */
    439 	 FALSE,			/* PC_relative.  */
    440 	 0,			/* Bitpos.  */
    441 	 complain_overflow_bitfield, /* Complain_on_overflow.  */
    442 	 bfd_elf_generic_reloc,	/* Special_function.  */
    443 	 "R_D30V_32_NORMAL",	/* Name.  */
    444 	 FALSE,			/* Partial_inplace.  */
    445 	 0xffffffff,		/* Src_mask.  */
    446 	 0xffffffff,		/* Dst_mask.  */
    447 	 FALSE),		/* PCrel_offset.  */
    448 
    449 };
    450 
    451 /* Map BFD reloc types to D30V ELF reloc types.  */
    452 
    453 struct d30v_reloc_map
    454 {
    455   bfd_reloc_code_real_type bfd_reloc_val;
    456   unsigned char elf_reloc_val;
    457 };
    458 
    459 static const struct d30v_reloc_map d30v_reloc_map[] =
    460 {
    461   { BFD_RELOC_NONE, R_D30V_NONE, },
    462   { BFD_RELOC_D30V_6, R_D30V_6 },
    463   { BFD_RELOC_D30V_9_PCREL, R_D30V_9_PCREL },
    464   { BFD_RELOC_D30V_9_PCREL_R, R_D30V_9_PCREL_R },
    465   { BFD_RELOC_D30V_15, R_D30V_15 },
    466   { BFD_RELOC_D30V_15_PCREL, R_D30V_15_PCREL },
    467   { BFD_RELOC_D30V_15_PCREL_R, R_D30V_15_PCREL_R },
    468   { BFD_RELOC_D30V_21, R_D30V_21 },
    469   { BFD_RELOC_D30V_21_PCREL, R_D30V_21_PCREL },
    470   { BFD_RELOC_D30V_21_PCREL_R, R_D30V_21_PCREL_R },
    471   { BFD_RELOC_D30V_32, R_D30V_32 },
    472   { BFD_RELOC_D30V_32_PCREL, R_D30V_32_PCREL },
    473   { BFD_RELOC_32, R_D30V_32_NORMAL },
    474 };
    475 
    476 static reloc_howto_type *
    477 bfd_elf32_bfd_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
    478 				 bfd_reloc_code_real_type code)
    479 {
    480   unsigned int i;
    481 
    482   for (i = 0;
    483        i < sizeof (d30v_reloc_map) / sizeof (struct d30v_reloc_map);
    484        i++)
    485     {
    486       if (d30v_reloc_map[i].bfd_reloc_val == code)
    487 	return &elf_d30v_howto_table[d30v_reloc_map[i].elf_reloc_val];
    488     }
    489 
    490   return NULL;
    491 }
    492 
    493 static reloc_howto_type *
    494 bfd_elf32_bfd_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
    495 				 const char *r_name)
    496 {
    497   unsigned int i;
    498 
    499   for (i = 0;
    500        i < sizeof (elf_d30v_howto_table) / sizeof (elf_d30v_howto_table[0]);
    501        i++)
    502     if (elf_d30v_howto_table[i].name != NULL
    503 	&& strcasecmp (elf_d30v_howto_table[i].name, r_name) == 0)
    504       return &elf_d30v_howto_table[i];
    505 
    506   return NULL;
    507 }
    508 
    509 /* Set the howto pointer for an D30V ELF reloc (type REL).  */
    510 
    511 static void
    512 d30v_info_to_howto_rel (bfd *abfd ATTRIBUTE_UNUSED,
    513 			arelent *cache_ptr,
    514 			Elf_Internal_Rela *dst)
    515 {
    516   unsigned int r_type;
    517 
    518   r_type = ELF32_R_TYPE (dst->r_info);
    519   if (r_type >= (unsigned int) R_D30V_max)
    520     {
    521       _bfd_error_handler (_("%B: invalid D30V reloc number: %d"), abfd, r_type);
    522       r_type = 0;
    523     }
    524   cache_ptr->howto = &elf_d30v_howto_table[r_type];
    525 }
    526 
    527 /* Set the howto pointer for an D30V ELF reloc (type RELA).  */
    528 
    529 static void
    530 d30v_info_to_howto_rela (bfd *abfd ATTRIBUTE_UNUSED,
    531 			 arelent *cache_ptr,
    532 			 Elf_Internal_Rela *dst)
    533 {
    534   unsigned int r_type;
    535 
    536   r_type = ELF32_R_TYPE (dst->r_info);
    537   if (r_type >= (unsigned int) R_D30V_max)
    538     {
    539       _bfd_error_handler (_("%B: invalid D30V reloc number: %d"), abfd, r_type);
    540       r_type = 0;
    541     }
    542   cache_ptr->howto = &elf_d30v_howto_table[r_type];
    543 }
    544 
    545 #define ELF_ARCH		bfd_arch_d30v
    546 #define ELF_MACHINE_CODE	EM_D30V
    547 #define ELF_MACHINE_ALT1	EM_CYGNUS_D30V
    548 #define ELF_MAXPAGESIZE		0x1000
    549 
    550 #define TARGET_BIG_SYM          d30v_elf32_vec
    551 #define TARGET_BIG_NAME		"elf32-d30v"
    552 
    553 #define elf_info_to_howto	d30v_info_to_howto_rela
    554 #define elf_info_to_howto_rel	d30v_info_to_howto_rel
    555 #define elf_backend_object_p	0
    556 #define elf_backend_final_write_processing	0
    557 
    558 #include "elf32-target.h"
    559