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