Home | History | Annotate | Download | only in bfd
      1 /* DLX specific support for 32-bit ELF
      2    Copyright (C) 2002-2014 Free Software Foundation, Inc.
      3 
      4    This file is part of BFD, the Binary File Descriptor library.
      5 
      6    This program is free software; you can redistribute it and/or modify
      7    it under the terms of the GNU General Public License as published by
      8    the Free Software Foundation; either version 3 of the License, or
      9    (at your option) any later version.
     10 
     11    This program is distributed in the hope that it will be useful,
     12    but WITHOUT ANY WARRANTY; without even the implied warranty of
     13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     14    GNU General Public License for more details.
     15 
     16    You should have received a copy of the GNU General Public License
     17    along with this program; if not, write to the Free Software
     18    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
     19    MA 02110-1301, USA.  */
     20 
     21 #include "sysdep.h"
     22 #include "bfd.h"
     23 #include "libbfd.h"
     24 #include "elf-bfd.h"
     25 #include "elf/dlx.h"
     26 
     27 #define USE_REL 1
     28 
     29 #define bfd_elf32_bfd_reloc_type_lookup elf32_dlx_reloc_type_lookup
     30 #define bfd_elf32_bfd_reloc_name_lookup elf32_dlx_reloc_name_lookup
     31 #define elf_info_to_howto               elf32_dlx_info_to_howto
     32 #define elf_info_to_howto_rel           elf32_dlx_info_to_howto_rel
     33 #define elf_backend_check_relocs        elf32_dlx_check_relocs
     34 
     35 /* The gas default behavior is not to preform the %hi modifier so that the
     36    GNU assembler can have the lower 16 bits offset placed in the insn, BUT
     37    we do like the gas to indicate it is %hi reloc type so when we in the link
     38    loader phase we can have the corrected hi16 vale replace the buggous lo16
     39    value that was placed there by gas.  */
     40 
     41 static int skip_dlx_elf_hi16_reloc = 0;
     42 
     43 extern int set_dlx_skip_hi16_flag (int);
     44 
     45 int
     46 set_dlx_skip_hi16_flag (int flag)
     47 {
     48   skip_dlx_elf_hi16_reloc = flag;
     49   return flag;
     50 }
     51 
     52 static bfd_reloc_status_type
     53 _bfd_dlx_elf_hi16_reloc (bfd *abfd,
     54 			 arelent *reloc_entry,
     55 			 asymbol *symbol,
     56 			 void * data,
     57 			 asection *input_section,
     58 			 bfd *output_bfd,
     59 			 char **error_message)
     60 {
     61   bfd_reloc_status_type ret;
     62   bfd_vma relocation;
     63 
     64   /* If the skip flag is set then we simply do the generic relocating, this
     65      is more of a hack for dlx gas/gld, so we do not need to do the %hi/%lo
     66      fixup like mips gld did.   */
     67   if (skip_dlx_elf_hi16_reloc)
     68     return bfd_elf_generic_reloc (abfd, reloc_entry, symbol, data,
     69                           input_section, output_bfd, error_message);
     70 
     71   /* If we're relocating, and this an external symbol, we don't want
     72      to change anything.  */
     73   if (output_bfd != (bfd *) NULL
     74       && (symbol->flags & BSF_SECTION_SYM) == 0
     75       && reloc_entry->addend == 0)
     76     {
     77       reloc_entry->address += input_section->output_offset;
     78       return bfd_reloc_ok;
     79     }
     80 
     81   ret = bfd_reloc_ok;
     82 
     83   if (bfd_is_und_section (symbol->section)
     84       && output_bfd == (bfd *) NULL)
     85     ret = bfd_reloc_undefined;
     86 
     87   relocation = (bfd_is_com_section (symbol->section)) ? 0 : symbol->value;
     88   relocation += symbol->section->output_section->vma;
     89   relocation += symbol->section->output_offset;
     90   relocation += reloc_entry->addend;
     91   relocation += bfd_get_16 (abfd, (bfd_byte *)data + reloc_entry->address);
     92 
     93   if (reloc_entry->address > bfd_get_section_limit (abfd, input_section))
     94     return bfd_reloc_outofrange;
     95 
     96   bfd_put_16 (abfd, (short)((relocation >> 16) & 0xFFFF),
     97               (bfd_byte *)data + reloc_entry->address);
     98 
     99   return ret;
    100 }
    101 
    102 /* ELF relocs are against symbols.  If we are producing relocatable
    103    output, and the reloc is against an external symbol, and nothing
    104    has given us any additional addend, the resulting reloc will also
    105    be against the same symbol.  In such a case, we don't want to
    106    change anything about the way the reloc is handled, since it will
    107    all be done at final link time.  Rather than put special case code
    108    into bfd_perform_relocation, all the reloc types use this howto
    109    function.  It just short circuits the reloc if producing
    110    relocatable output against an external symbol.  */
    111 
    112 static bfd_reloc_status_type
    113 elf32_dlx_relocate16 (bfd *abfd,
    114 		      arelent *reloc_entry,
    115 		      asymbol *symbol,
    116 		      void * data,
    117 		      asection *input_section,
    118 		      bfd *output_bfd,
    119 		      char **error_message ATTRIBUTE_UNUSED)
    120 {
    121   unsigned long insn, vallo, allignment;
    122   int           val;
    123 
    124   /* HACK: I think this first condition is necessary when producing
    125      relocatable output.  After the end of HACK, the code is identical
    126      to bfd_elf_generic_reloc().  I would _guess_ the first change
    127      belongs there rather than here.  martindo 1998-10-23.  */
    128 
    129   if (skip_dlx_elf_hi16_reloc)
    130     return bfd_elf_generic_reloc (abfd, reloc_entry, symbol, data,
    131                                  input_section, output_bfd, error_message);
    132 
    133   /* Check undefined section and undefined symbols.  */
    134   if (bfd_is_und_section (symbol->section)
    135       && output_bfd == (bfd *) NULL)
    136     return bfd_reloc_undefined;
    137 
    138   /* Can not support a long jump to sections other then .text.  */
    139   if (strcmp (input_section->name, symbol->section->output_section->name) != 0)
    140     {
    141       (*_bfd_error_handler) (_("BFD Link Error: branch (PC rel16) to section (%s) not supported"),
    142 			     symbol->section->output_section->name);
    143       return bfd_reloc_undefined;
    144     }
    145 
    146   insn  = bfd_get_32 (abfd, (bfd_byte *)data + reloc_entry->address);
    147   allignment = 1 << (input_section->output_section->alignment_power - 1);
    148   vallo = insn & 0x0000FFFF;
    149 
    150   if (vallo & 0x8000)
    151     vallo = ~(vallo | 0xFFFF0000) + 1;
    152 
    153   /* vallo points to the vma of next instruction.  */
    154   vallo += (((unsigned long)(input_section->output_section->vma +
    155                            input_section->output_offset) +
    156             allignment) & ~allignment);
    157 
    158   /* val is the displacement (PC relative to next instruction).  */
    159   val =  (symbol->section->output_offset +
    160 	  symbol->section->output_section->vma +
    161 	  symbol->value) - vallo;
    162 
    163   if (abs ((int) val) > 0x00007FFF)
    164     return bfd_reloc_outofrange;
    165 
    166   insn  = (insn & 0xFFFF0000) | (val & 0x0000FFFF);
    167 
    168   bfd_put_32 (abfd, insn,
    169               (bfd_byte *) data + reloc_entry->address);
    170 
    171   return bfd_reloc_ok;
    172 }
    173 
    174 static bfd_reloc_status_type
    175 elf32_dlx_relocate26 (bfd *abfd,
    176 		      arelent *reloc_entry,
    177 		      asymbol *symbol,
    178 		      void * data,
    179 		      asection *input_section,
    180 		      bfd *output_bfd,
    181 		      char **error_message ATTRIBUTE_UNUSED)
    182 {
    183   unsigned long insn, vallo, allignment;
    184   int           val;
    185 
    186   /* HACK: I think this first condition is necessary when producing
    187      relocatable output.  After the end of HACK, the code is identical
    188      to bfd_elf_generic_reloc().  I would _guess_ the first change
    189      belongs there rather than here.  martindo 1998-10-23.  */
    190 
    191   if (skip_dlx_elf_hi16_reloc)
    192     return bfd_elf_generic_reloc (abfd, reloc_entry, symbol, data,
    193                                  input_section, output_bfd, error_message);
    194 
    195   /* Check undefined section and undefined symbols.  */
    196   if (bfd_is_und_section (symbol->section)
    197       && output_bfd == (bfd *) NULL)
    198     return bfd_reloc_undefined;
    199 
    200   /* Can not support a long jump to sections other then .text   */
    201   if (strcmp (input_section->name, symbol->section->output_section->name) != 0)
    202     {
    203       (*_bfd_error_handler) (_("BFD Link Error: jump (PC rel26) to section (%s) not supported"),
    204 			     symbol->section->output_section->name);
    205       return bfd_reloc_undefined;
    206     }
    207 
    208   insn  = bfd_get_32 (abfd, (bfd_byte *)data + reloc_entry->address);
    209   allignment = 1 << (input_section->output_section->alignment_power - 1);
    210   vallo = insn & 0x03FFFFFF;
    211 
    212   if (vallo & 0x03000000)
    213     vallo = ~(vallo | 0xFC000000) + 1;
    214 
    215   /* vallo is the vma for the next instruction.  */
    216   vallo += (((unsigned long) (input_section->output_section->vma +
    217 			      input_section->output_offset) +
    218 	     allignment) & ~allignment);
    219 
    220   /* val is the displacement (PC relative to next instruction).  */
    221   val = (symbol->section->output_offset +
    222 	 symbol->section->output_section->vma + symbol->value)
    223     - vallo;
    224 
    225   if (abs ((int) val) > 0x01FFFFFF)
    226     return bfd_reloc_outofrange;
    227 
    228   insn  = (insn & 0xFC000000) | (val & 0x03FFFFFF);
    229   bfd_put_32 (abfd, insn,
    230               (bfd_byte *) data + reloc_entry->address);
    231 
    232   return bfd_reloc_ok;
    233 }
    234 
    235 static reloc_howto_type dlx_elf_howto_table[]=
    236 {
    237   /* No relocation.  */
    238   HOWTO (R_DLX_NONE,            /* Type. */
    239 	 0,                     /* Rightshift.  */
    240 	 0,                     /* size (0 = byte, 1 = short, 2 = long).  */
    241 	 0,                     /* Bitsize.  */
    242 	 FALSE,                 /* PC_relative.  */
    243 	 0,                     /* Bitpos.  */
    244 	 complain_overflow_dont,/* Complain_on_overflow.  */
    245 	 bfd_elf_generic_reloc, /* Special_function.  */
    246 	 "R_DLX_NONE",          /* Name.  */
    247 	 FALSE,                 /* Partial_inplace.  */
    248 	 0,                     /* Src_mask.  */
    249 	 0,                     /* Dst_mask.  */
    250 	 FALSE),                /* PCrel_offset.  */
    251 
    252   /* 8 bit relocation.  */
    253   HOWTO (R_DLX_RELOC_8,         /* Type. */
    254 	 0,                     /* Rightshift.  */
    255 	 0,                     /* Size (0 = byte, 1 = short, 2 = long).  */
    256 	 8,                     /* Bitsize.  */
    257 	 FALSE,                 /* PC_relative.  */
    258 	 0,                     /* Bitpos.  */
    259 	 complain_overflow_dont,/* Complain_on_overflow.  */
    260 	 bfd_elf_generic_reloc, /* Special_function.  */
    261 	 "R_DLX_RELOC_8",       /* Name.  */
    262 	 TRUE,                  /* Partial_inplace.  */
    263 	 0xff,                  /* Src_mask.  */
    264 	 0xff,                  /* Dst_mask.  */
    265 	 FALSE),                /* PCrel_offset.  */
    266 
    267   /* 16 bit relocation.  */
    268   HOWTO (R_DLX_RELOC_16,        /* Type. */
    269 	 0,                     /* Rightshift.  */
    270 	 1,                     /* Size (0 = byte, 1 = short, 2 = long).  */
    271 	 16,                    /* Bitsize.  */
    272 	 FALSE,                 /* PC_relative.  */
    273 	 0,                     /* Bitpos.  */
    274 	 complain_overflow_dont,/* Complain_on_overflow.  */
    275 	 bfd_elf_generic_reloc, /* Special_function.  */
    276 	 "R_DLX_RELOC_16",      /* Name.  */
    277 	 TRUE,                  /* Partial_inplace.  */
    278 	 0xffff,                /* Src_mask.  */
    279 	 0xffff,                /* Dst_mask.  */
    280 	 FALSE),                /* PCrel_offset.  */
    281 
    282   /* 32 bit relocation.  */
    283   HOWTO (R_DLX_RELOC_32,        /* Type. */
    284 	 0,                     /* Rightshift.  */
    285 	 2,                     /* Size (0 = byte, 1 = short, 2 = long).  */
    286 	 32,                    /* Bitsize.  */
    287 	 FALSE,                 /* PC_relative.  */
    288 	 0,                     /* Bitpos.  */
    289 	 complain_overflow_dont,/* Complain_on_overflow.  */
    290 	 bfd_elf_generic_reloc, /* Special_function.  */
    291 	 "R_DLX_RELOC_32",      /* Name.  */
    292 	 TRUE,                  /* Partial_inplace.  */
    293 	 0xffffffff,            /* Src_mask.  */
    294 	 0xffffffff,            /* Dst_mask.  */
    295 	 FALSE),                /* PCrel_offset.  */
    296 
    297   /* GNU extension to record C++ vtable hierarchy.  */
    298   HOWTO (R_DLX_GNU_VTINHERIT,   /* Type. */
    299 	 0,			/* Rightshift.  */
    300 	 2,			/* Size (0 = byte, 1 = short, 2 = long).  */
    301 	 0,			/* Bitsize.  */
    302 	 FALSE,			/* PC_relative.  */
    303 	 0,			/* Bitpos.  */
    304 	 complain_overflow_dont,/* Complain_on_overflow.  */
    305 	 NULL,			/* Special_function.  */
    306 	 "R_DLX_GNU_VTINHERIT", /* Name.  */
    307 	 FALSE,			/* Partial_inplace.  */
    308 	 0,			/* Src_mask.  */
    309 	 0,			/* Dst_mask.  */
    310 	 FALSE),		/* PCrel_offset.  */
    311 
    312   /* GNU extension to record C++ vtable member usage.  */
    313   HOWTO (R_DLX_GNU_VTENTRY,     /* Type. */
    314 	 0,			/* Rightshift.  */
    315 	 2,			/* Size (0 = byte, 1 = short, 2 = long).  */
    316 	 0,			/* Bitsize.  */
    317 	 FALSE,			/* PC_relative.  */
    318 	 0,			/* Bitpos.  */
    319 	 complain_overflow_dont,/* Complain_on_overflow.  */
    320 	 _bfd_elf_rel_vtable_reloc_fn,/* Special_function.  */
    321 	 "R_DLX_GNU_VTENTRY",	/* Name.  */
    322 	 FALSE,		  	/* Partial_inplace.  */
    323 	 0,			/* Src_mask.  */
    324 	 0,			/* Dst_mask.  */
    325 	 FALSE)		  	/* PCrel_offset.  */
    326 };
    327 
    328 /* 16 bit offset for pc-relative branches.  */
    329 static reloc_howto_type elf_dlx_gnu_rel16_s2 =
    330   HOWTO (R_DLX_RELOC_16_PCREL,  /* Type. */
    331 	 0,                     /* Rightshift.  */
    332 	 1,                     /* Size (0 = byte, 1 = short, 2 = long).  */
    333 	 16,                    /* Bitsize.  */
    334 	 TRUE,                  /* PC_relative.  */
    335 	 0,                     /* Bitpos.  */
    336 	 complain_overflow_signed, /* Complain_on_overflow.  */
    337 	 elf32_dlx_relocate16,  /* Special_function.  */
    338 	 "R_DLX_RELOC_16_PCREL",/* Name.  */
    339 	 TRUE,                  /* Partial_inplace.  */
    340 	 0xffff,                /* Src_mask.  */
    341 	 0xffff,                /* Dst_mask.  */
    342 	 TRUE);                 /* PCrel_offset.  */
    343 
    344 /* 26 bit offset for pc-relative branches.  */
    345 static reloc_howto_type elf_dlx_gnu_rel26_s2 =
    346   HOWTO (R_DLX_RELOC_26_PCREL,  /* Type. */
    347 	 0,                     /* Rightshift.  */
    348 	 2,                     /* Size (0 = byte, 1 = short, 2 = long).  */
    349 	 26,                    /* Bitsize.  */
    350 	 TRUE,                  /* PC_relative.  */
    351 	 0,                     /* Bitpos.  */
    352 	 complain_overflow_dont,/* Complain_on_overflow.  */
    353 	 elf32_dlx_relocate26,  /* Special_function.  */
    354 	 "R_DLX_RELOC_26_PCREL",/* Name.  */
    355 	 TRUE,                  /* Partial_inplace.  */
    356 	 0xffff,                /* Src_mask.  */
    357 	 0xffff,                /* Dst_mask.  */
    358 	 TRUE);                 /* PCrel_offset.  */
    359 
    360 /* High 16 bits of symbol value.  */
    361 static reloc_howto_type elf_dlx_reloc_16_hi =
    362   HOWTO (R_DLX_RELOC_16_HI,     /* Type. */
    363 	 16,                    /* Rightshift.  */
    364 	 2,                     /* Size (0 = byte, 1 = short, 2 = long).  */
    365 	 32,                    /* Bitsize.  */
    366 	 FALSE,                 /* PC_relative.  */
    367 	 0,                     /* Bitpos.  */
    368 	 complain_overflow_dont,/* Complain_on_overflow.  */
    369 	 _bfd_dlx_elf_hi16_reloc,/* Special_function.  */
    370 	 "R_DLX_RELOC_16_HI",   /* Name.  */
    371 	 TRUE,                  /* Partial_inplace.  */
    372 	 0xFFFF,                /* Src_mask.  */
    373 	 0xffff,                /* Dst_mask.  */
    374 	 FALSE);                /* PCrel_offset.  */
    375 
    376   /* Low 16 bits of symbol value.  */
    377 static reloc_howto_type elf_dlx_reloc_16_lo =
    378   HOWTO (R_DLX_RELOC_16_LO,     /* Type. */
    379 	 0,                     /* Rightshift.  */
    380 	 1,                     /* Size (0 = byte, 1 = short, 2 = long).  */
    381 	 16,                    /* Bitsize.  */
    382 	 FALSE,                 /* PC_relative.  */
    383 	 0,                     /* Bitpos.  */
    384 	 complain_overflow_dont,/* Complain_on_overflow.  */
    385 	 bfd_elf_generic_reloc, /* Special_function.  */
    386 	 "R_DLX_RELOC_16_LO",   /* Name.  */
    387 	 TRUE,                  /* Partial_inplace.  */
    388 	 0xffff,                /* Src_mask.  */
    389 	 0xffff,                /* Dst_mask.  */
    390 	 FALSE);                /* PCrel_offset.  */
    391 
    392 /* A mapping from BFD reloc types to DLX ELF reloc types.
    393    Stolen from elf32-mips.c.
    394 
    395    More about this table - for dlx elf relocation we do not really
    396    need this table, if we have a rtype defined in this table will
    397    caused tc_gen_relocate confused and die on us, but if we remove
    398    this table it will caused more problem, so for now simple solution
    399    is to remove those entries which may cause problem.  */
    400 struct elf_reloc_map
    401 {
    402   bfd_reloc_code_real_type bfd_reloc_val;
    403   enum elf_dlx_reloc_type elf_reloc_val;
    404 };
    405 
    406 static const struct elf_reloc_map dlx_reloc_map[] =
    407 {
    408   { BFD_RELOC_NONE,           R_DLX_NONE },
    409   { BFD_RELOC_16,             R_DLX_RELOC_16 },
    410   { BFD_RELOC_32,             R_DLX_RELOC_32 },
    411   { BFD_RELOC_DLX_HI16_S,     R_DLX_RELOC_16_HI },
    412   { BFD_RELOC_DLX_LO16,       R_DLX_RELOC_16_LO },
    413   { BFD_RELOC_VTABLE_INHERIT,	R_DLX_GNU_VTINHERIT },
    414   { BFD_RELOC_VTABLE_ENTRY,	R_DLX_GNU_VTENTRY }
    415 };
    416 
    417 /* Look through the relocs for a section during the first phase.
    418    Since we don't do .gots or .plts, we just need to consider the
    419    virtual table relocs for gc.  */
    420 
    421 static bfd_boolean
    422 elf32_dlx_check_relocs (bfd *abfd,
    423 			struct bfd_link_info *info,
    424 			asection *sec,
    425 			const Elf_Internal_Rela *relocs)
    426 {
    427   Elf_Internal_Shdr *symtab_hdr;
    428   struct elf_link_hash_entry **sym_hashes;
    429   const Elf_Internal_Rela *rel;
    430   const Elf_Internal_Rela *rel_end;
    431 
    432   if (info->relocatable)
    433     return TRUE;
    434 
    435   symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
    436   sym_hashes = elf_sym_hashes (abfd);
    437 
    438   rel_end = relocs + sec->reloc_count;
    439   for (rel = relocs; rel < rel_end; rel++)
    440     {
    441       struct elf_link_hash_entry *h;
    442       unsigned long r_symndx;
    443 
    444       r_symndx = ELF32_R_SYM (rel->r_info);
    445       if (r_symndx < symtab_hdr->sh_info)
    446         h = NULL;
    447       else
    448 	{
    449 	  h = sym_hashes[r_symndx - symtab_hdr->sh_info];
    450 	  while (h->root.type == bfd_link_hash_indirect
    451 		 || h->root.type == bfd_link_hash_warning)
    452 	    h = (struct elf_link_hash_entry *) h->root.u.i.link;
    453 
    454 	  /* PR15323, ref flags aren't set for references in the same
    455 	     object.  */
    456 	  h->root.non_ir_ref = 1;
    457 	}
    458 
    459       switch (ELF32_R_TYPE (rel->r_info))
    460         {
    461         /* This relocation describes the C++ object vtable hierarchy.
    462            Reconstruct it for later use during GC.  */
    463         case R_DLX_GNU_VTINHERIT:
    464           if (!bfd_elf_gc_record_vtinherit (abfd, sec, h, rel->r_offset))
    465             return FALSE;
    466           break;
    467 
    468         /* This relocation describes which C++ vtable entries are actually
    469            used.  Record for later use during GC.  */
    470         case R_DLX_GNU_VTENTRY:
    471           BFD_ASSERT (h != NULL);
    472           if (h != NULL
    473               && !bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend))
    474             return FALSE;
    475           break;
    476         }
    477     }
    478 
    479   return TRUE;
    480 }
    481 
    482 /* Given a BFD reloc type, return a howto structure.  */
    483 
    484 static reloc_howto_type *
    485 elf32_dlx_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
    486 			     bfd_reloc_code_real_type code)
    487 {
    488   unsigned int i;
    489 
    490   for (i = 0; i < sizeof (dlx_reloc_map) / sizeof (struct elf_reloc_map); i++)
    491     if (dlx_reloc_map[i].bfd_reloc_val == code)
    492       return &dlx_elf_howto_table[(int) dlx_reloc_map[i].elf_reloc_val];
    493 
    494   switch (code)
    495     {
    496     default:
    497       bfd_set_error (bfd_error_bad_value);
    498       return NULL;
    499     case BFD_RELOC_16_PCREL_S2:
    500       return &elf_dlx_gnu_rel16_s2;
    501     case BFD_RELOC_DLX_JMP26:
    502       return &elf_dlx_gnu_rel26_s2;
    503     case BFD_RELOC_HI16_S:
    504       return &elf_dlx_reloc_16_hi;
    505     case BFD_RELOC_LO16:
    506       return &elf_dlx_reloc_16_lo;
    507     }
    508 }
    509 
    510 static reloc_howto_type *
    511 elf32_dlx_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
    512 			     const char *r_name)
    513 {
    514   unsigned int i;
    515 
    516   for (i = 0;
    517        i < sizeof (dlx_elf_howto_table) / sizeof (dlx_elf_howto_table[0]);
    518        i++)
    519     if (dlx_elf_howto_table[i].name != NULL
    520 	&& strcasecmp (dlx_elf_howto_table[i].name, r_name) == 0)
    521       return &dlx_elf_howto_table[i];
    522 
    523   if (strcasecmp (elf_dlx_gnu_rel16_s2.name, r_name) == 0)
    524     return &elf_dlx_gnu_rel16_s2;
    525   if (strcasecmp (elf_dlx_gnu_rel26_s2.name, r_name) == 0)
    526     return &elf_dlx_gnu_rel26_s2;
    527   if (strcasecmp (elf_dlx_reloc_16_hi.name, r_name) == 0)
    528     return &elf_dlx_reloc_16_hi;
    529   if (strcasecmp (elf_dlx_reloc_16_lo.name, r_name) == 0)
    530     return &elf_dlx_reloc_16_lo;
    531 
    532   return NULL;
    533 }
    534 
    535 static reloc_howto_type *
    536 dlx_rtype_to_howto (unsigned int r_type)
    537 {
    538   switch (r_type)
    539     {
    540     case R_DLX_RELOC_16_PCREL:
    541       return & elf_dlx_gnu_rel16_s2;
    542     case R_DLX_RELOC_26_PCREL:
    543       return & elf_dlx_gnu_rel26_s2;
    544     case R_DLX_RELOC_16_HI:
    545       return & elf_dlx_reloc_16_hi;
    546     case R_DLX_RELOC_16_LO:
    547       return & elf_dlx_reloc_16_lo;
    548     default:
    549       BFD_ASSERT (r_type < (unsigned int) R_DLX_max);
    550       return & dlx_elf_howto_table[r_type];
    551     }
    552 }
    553 
    554 static void
    555 elf32_dlx_info_to_howto (bfd * abfd ATTRIBUTE_UNUSED,
    556 			 arelent * cache_ptr ATTRIBUTE_UNUSED,
    557 			 Elf_Internal_Rela * dst ATTRIBUTE_UNUSED)
    558 {
    559   abort ();
    560 }
    561 
    562 static void
    563 elf32_dlx_info_to_howto_rel (bfd *abfd ATTRIBUTE_UNUSED,
    564 			     arelent *cache_ptr,
    565 			     Elf_Internal_Rela *dst)
    566 {
    567   unsigned int r_type;
    568 
    569   r_type = ELF32_R_TYPE (dst->r_info);
    570   cache_ptr->howto = dlx_rtype_to_howto (r_type);
    571   return;
    572 }
    573 
    574 #define TARGET_BIG_SYM          dlx_elf32_be_vec
    575 #define TARGET_BIG_NAME         "elf32-dlx"
    576 #define ELF_ARCH                bfd_arch_dlx
    577 #define ELF_MACHINE_CODE        EM_DLX
    578 #define ELF_MAXPAGESIZE         1 /* FIXME: This number is wrong,  It should be the page size in bytes.  */
    579 
    580 #include "elf32-target.h"
    581