• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
set_dlx_skip_hi16_flag(int flag)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
_bfd_dlx_elf_hi16_reloc(bfd * abfd,arelent * reloc_entry,asymbol * symbol,void * data,asection * input_section,bfd * output_bfd,char ** error_message)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
elf32_dlx_relocate16(bfd * abfd,arelent * reloc_entry,asymbol * symbol,void * data,asection * input_section,bfd * output_bfd,char ** error_message ATTRIBUTE_UNUSED)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
elf32_dlx_relocate26(bfd * abfd,arelent * reloc_entry,asymbol * symbol,void * data,asection * input_section,bfd * output_bfd,char ** error_message ATTRIBUTE_UNUSED)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
elf32_dlx_check_relocs(bfd * abfd,struct bfd_link_info * info,asection * sec,const Elf_Internal_Rela * relocs)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 *
elf32_dlx_reloc_type_lookup(bfd * abfd ATTRIBUTE_UNUSED,bfd_reloc_code_real_type code)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 *
elf32_dlx_reloc_name_lookup(bfd * abfd ATTRIBUTE_UNUSED,const char * r_name)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 *
dlx_rtype_to_howto(unsigned int r_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
elf32_dlx_info_to_howto(bfd * abfd ATTRIBUTE_UNUSED,arelent * cache_ptr ATTRIBUTE_UNUSED,Elf_Internal_Rela * dst ATTRIBUTE_UNUSED)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
elf32_dlx_info_to_howto_rel(bfd * abfd ATTRIBUTE_UNUSED,arelent * cache_ptr,Elf_Internal_Rela * dst)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