daily update
[deliverable/binutils-gdb.git] / bfd / elf32-dlx.c
1 /* DLX specific support for 32-bit ELF
2 Copyright 2002 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 2 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
19
20 #include "bfd.h"
21 #include "sysdep.h"
22 #include "libbfd.h"
23 #include "elf-bfd.h"
24 #include "elf/dlx.h"
25
26 int set_dlx_skip_hi16_flag PARAMS ((int));
27
28 static boolean elf32_dlx_check_relocs
29 PARAMS ((bfd *, struct bfd_link_info *, asection *, const Elf_Internal_Rela *));
30 static void elf32_dlx_info_to_howto
31 PARAMS ((bfd *, arelent *, Elf32_Internal_Rela *));
32 static void elf32_dlx_info_to_howto_rel
33 PARAMS ((bfd *, arelent *, Elf32_Internal_Rel *));
34 static bfd_reloc_status_type elf32_dlx_relocate16
35 PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
36 static bfd_reloc_status_type elf32_dlx_relocate26
37 PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
38 static reloc_howto_type *elf32_dlx_reloc_type_lookup
39 PARAMS ((bfd *, bfd_reloc_code_real_type));
40 static bfd_reloc_status_type _bfd_dlx_elf_hi16_reloc
41 PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
42 static reloc_howto_type * dlx_rtype_to_howto
43 PARAMS ((unsigned int));
44
45
46 #define USE_REL 1
47
48 #define bfd_elf32_bfd_reloc_type_lookup elf32_dlx_reloc_type_lookup
49 #define elf_info_to_howto elf32_dlx_info_to_howto
50 #define elf_info_to_howto_rel elf32_dlx_info_to_howto_rel
51 #define elf_backend_check_relocs elf32_dlx_check_relocs
52
53 static reloc_howto_type dlx_elf_howto_table[]=
54 {
55 /* No relocation. */
56 HOWTO (R_DLX_NONE, /* type */
57 0, /* rightshift */
58 0, /* size (0 = byte, 1 = short, 2 = long) */
59 0, /* bitsize */
60 false, /* pc_relative */
61 0, /* bitpos */
62 complain_overflow_dont,/* complain_on_overflow */
63 bfd_elf_generic_reloc, /* special_function */
64 "R_DLX_NONE", /* name */
65 false, /* partial_inplace */
66 0, /* src_mask */
67 0, /* dst_mask */
68 false), /* pcrel_offset */
69
70 /* 8 bit relocation. */
71 HOWTO (R_DLX_RELOC_8, /* type */
72 0, /* rightshift */
73 0, /* size (0 = byte, 1 = short, 2 = long) */
74 8, /* bitsize */
75 false, /* pc_relative */
76 0, /* bitpos */
77 complain_overflow_dont,/* complain_on_overflow */
78 bfd_elf_generic_reloc, /* special_function */
79 "R_DLX_RELOC_8", /* name */
80 true, /* partial_inplace */
81 0xff, /* src_mask */
82 0xff, /* dst_mask */
83 false), /* pcrel_offset */
84
85 /* 16 bit relocation. */
86 HOWTO (R_DLX_RELOC_16, /* type */
87 0, /* rightshift */
88 1, /* size (0 = byte, 1 = short, 2 = long) */
89 16, /* bitsize */
90 false, /* pc_relative */
91 0, /* bitpos */
92 complain_overflow_dont,/* complain_on_overflow */
93 bfd_elf_generic_reloc, /* special_function */
94 "R_DLX_RELOC_16", /* name */
95 true, /* partial_inplace */
96 0xffff, /* src_mask */
97 0xffff, /* dst_mask */
98 false), /* pcrel_offset */
99
100 #if 0
101 /* 26 bit jump address. */
102 HOWTO (R_DLX_RELOC_26, /* type */
103 0, /* rightshift */
104 2, /* size (0 = byte, 1 = short, 2 = long) */
105 26, /* bitsize */
106 false, /* pc_relative */
107 0, /* bitpos */
108 complain_overflow_dont,/* complain_on_overflow */
109 /* This needs complex overflow detection, because the upper four
110 bits must match the PC + 4. */
111 bfd_elf_generic_reloc, /* special_function */
112 "R_DLX_RELOC_26", /* name */
113 true, /* partial_inplace */
114 0x3ffffff, /* src_mask */
115 0x3ffffff, /* dst_mask */
116 false), /* pcrel_offset */
117 #endif
118
119 /* 32 bit relocation. */
120 HOWTO (R_DLX_RELOC_32, /* type */
121 0, /* rightshift */
122 2, /* size (0 = byte, 1 = short, 2 = long) */
123 32, /* bitsize */
124 false, /* pc_relative */
125 0, /* bitpos */
126 complain_overflow_dont,/* complain_on_overflow */
127 bfd_elf_generic_reloc, /* special_function */
128 "R_DLX_RELOC_32", /* name */
129 true, /* partial_inplace */
130 0xffffffff, /* src_mask */
131 0xffffffff, /* dst_mask */
132 false), /* pcrel_offset */
133
134 /* GNU extension to record C++ vtable hierarchy */
135 HOWTO (R_DLX_GNU_VTINHERIT, /* type */
136 0, /* rightshift */
137 2, /* size (0 = byte, 1 = short, 2 = long) */
138 0, /* bitsize */
139 false, /* pc_relative */
140 0, /* bitpos */
141 complain_overflow_dont,/* complain_on_overflow */
142 NULL, /* special_function */
143 "R_DLX_GNU_VTINHERIT", /* name */
144 false, /* partial_inplace */
145 0, /* src_mask */
146 0, /* dst_mask */
147 false), /* pcrel_offset */
148
149 /* GNU extension to record C++ vtable member usage */
150 HOWTO (R_DLX_GNU_VTENTRY, /* type */
151 0, /* rightshift */
152 2, /* size (0 = byte, 1 = short, 2 = long) */
153 0, /* bitsize */
154 false, /* pc_relative */
155 0, /* bitpos */
156 complain_overflow_dont,/* complain_on_overflow */
157 _bfd_elf_rel_vtable_reloc_fn,/* special_function */
158 "R_DLX_GNU_VTENTRY", /* name */
159 false, /* partial_inplace */
160 0, /* src_mask */
161 0, /* dst_mask */
162 false) /* pcrel_offset */
163 };
164
165 /* 16 bit offset for pc-relative branches. */
166 static reloc_howto_type elf_dlx_gnu_rel16_s2 =
167 HOWTO (R_DLX_RELOC_16_PCREL, /* type */
168 0, /* rightshift */
169 1, /* size (0 = byte, 1 = short, 2 = long) */
170 16, /* bitsize */
171 true, /* pc_relative */
172 0, /* bitpos */
173 complain_overflow_signed, /* complain_on_overflow */
174 elf32_dlx_relocate16, /* special_function */
175 "R_DLX_RELOC_16_PCREL",/* name */
176 true, /* partial_inplace */
177 0xffff, /* src_mask */
178 0xffff, /* dst_mask */
179 true); /* pcrel_offset */
180
181 /* 26 bit offset for pc-relative branches. */
182 static reloc_howto_type elf_dlx_gnu_rel26_s2 =
183 HOWTO (R_DLX_RELOC_26_PCREL, /* type */
184 0, /* rightshift */
185 2, /* size (0 = byte, 1 = short, 2 = long) */
186 26, /* bitsize */
187 true, /* pc_relative */
188 0, /* bitpos */
189 complain_overflow_dont,/* complain_on_overflow */
190 elf32_dlx_relocate26, /* special_function */
191 "R_DLX_RELOC_26_PCREL",/* name */
192 true, /* partial_inplace */
193 0xffff, /* src_mask */
194 0xffff, /* dst_mask */
195 true); /* pcrel_offset */
196
197 /* High 16 bits of symbol value. */
198 static reloc_howto_type elf_dlx_reloc_16_hi =
199 HOWTO (R_DLX_RELOC_16_HI, /* type */
200 16, /* rightshift */
201 2, /* size (0 = byte, 1 = short, 2 = long) */
202 32, /* bitsize */
203 false, /* pc_relative */
204 0, /* bitpos */
205 complain_overflow_dont, /* complain_on_overflow */
206 _bfd_dlx_elf_hi16_reloc,/* special_function */
207 "R_DLX_RELOC_16_HI", /* name */
208 true, /* partial_inplace */
209 0xFFFF, /* src_mask */
210 0xffff, /* dst_mask */
211 false); /* pcrel_offset */
212
213 /* Low 16 bits of symbol value. */
214 static reloc_howto_type elf_dlx_reloc_16_lo =
215 HOWTO (R_DLX_RELOC_16_LO, /* type */
216 0, /* rightshift */
217 1, /* size (0 = byte, 1 = short, 2 = long) */
218 16, /* bitsize */
219 false, /* pc_relative */
220 0, /* bitpos */
221 complain_overflow_dont,/* complain_on_overflow */
222 bfd_elf_generic_reloc, /* special_function */
223 "R_DLX_RELOC_16_LO", /* name */
224 true, /* partial_inplace */
225 0xffff, /* src_mask */
226 0xffff, /* dst_mask */
227 false); /* pcrel_offset */
228
229
230 /* The gas default beheaver is not to preform the %hi modifier so that the
231 GNU assembler can have the lower 16 bits offset placed in the insn, BUT
232 we do like the gas to indicate it is %hi reloc type so when we in the link
233 loader phase we can have the corrected hi16 vale replace the buggous lo16
234 value that was placed there by gas. */
235
236 static int skip_dlx_elf_hi16_reloc = 0;
237
238 int
239 set_dlx_skip_hi16_flag (flag)
240 int flag;
241 {
242 skip_dlx_elf_hi16_reloc = flag;
243 return flag;
244 }
245
246 static bfd_reloc_status_type
247 _bfd_dlx_elf_hi16_reloc (abfd, reloc_entry, symbol, data,
248 input_section, output_bfd, error_message)
249 bfd *abfd;
250 arelent *reloc_entry;
251 asymbol *symbol;
252 PTR data;
253 asection *input_section;
254 bfd *output_bfd;
255 char **error_message;
256 {
257 bfd_reloc_status_type ret;
258 bfd_vma relocation;
259
260 /* If the skip flag is set then we simply do the generic relocating, this
261 is more of a hack for dlx gas/gld, so we do not need to do the %hi/%lo
262 fixup like mips gld did. */
263 #if 0
264 printf ("DEBUG: skip_dlx_elf_hi16_reloc = 0x%08x\n", skip_dlx_elf_hi16_reloc);
265 #endif
266 if (skip_dlx_elf_hi16_reloc)
267 return bfd_elf_generic_reloc (abfd, reloc_entry, symbol, data,
268 input_section, output_bfd, error_message);
269
270 /* If we're relocating, and this an external symbol, we don't want
271 to change anything. */
272 if (output_bfd != (bfd *) NULL
273 && (symbol->flags & BSF_SECTION_SYM) == 0
274 && reloc_entry->addend == 0)
275 {
276 reloc_entry->address += input_section->output_offset;
277 return bfd_reloc_ok;
278 }
279
280 ret = bfd_reloc_ok;
281
282 if (bfd_is_und_section (symbol->section)
283 && output_bfd == (bfd *) NULL)
284 ret = bfd_reloc_undefined;
285
286 #if 0
287 {
288 unsigned long vallo, val;
289
290 vallo = bfd_get_16 (abfd, (bfd_byte *) data + reloc_entry->address);
291 printf ("DEBUG: The relocation address = 0x%08x\n", reloc_entry->address);
292 printf ("DEBUG: The symbol = 0x%08x\n", vallo);
293 printf ("DEBUG: The symbol name = %s\n", bfd_asymbol_name (symbol));
294 printf ("DEBUG: The symbol->value = 0x%08x\n", symbol->value);
295 printf ("DEBUG: The vma = 0x%08x\n", symbol->section->output_section->vma);
296 printf ("DEBUG: The output_offset = 0x%08x\n", symbol->section->output_offset);
297 printf ("DEBUG: The input_offset = 0x%08x\n", input_section->output_offset);
298 printf ("DEBUG: The input_vma = 0x%08x\n", input_section->vma);
299 printf ("DEBUG: The addend = 0x%08x\n", reloc_entry->addend);
300 }
301 #endif
302
303 relocation = (bfd_is_com_section (symbol->section)) ? 0 : symbol->value;
304 relocation += symbol->section->output_section->vma;
305 relocation += symbol->section->output_offset;
306 relocation += reloc_entry->addend;
307 relocation += bfd_get_16 (abfd, (bfd_byte *)data + reloc_entry->address);
308
309 if (reloc_entry->address > input_section->_cooked_size)
310 return bfd_reloc_outofrange;
311
312 #if 0
313 printf ("DEBUG: The finial relocation value = 0x%08x\n", relocation);
314 #endif
315
316 bfd_put_16 (abfd, (short)((relocation >> 16) & 0xFFFF),
317 (bfd_byte *)data + reloc_entry->address);
318
319 return ret;
320 }
321
322 /* ELF relocs are against symbols. If we are producing relocateable
323 output, and the reloc is against an external symbol, and nothing
324 has given us any additional addend, the resulting reloc will also
325 be against the same symbol. In such a case, we don't want to
326 change anything about the way the reloc is handled, since it will
327 all be done at final link time. Rather than put special case code
328 into bfd_perform_relocation, all the reloc types use this howto
329 function. It just short circuits the reloc if producing
330 relocateable output against an external symbol. */
331
332 static bfd_reloc_status_type
333 elf32_dlx_relocate16 (abfd, reloc_entry, symbol, data,
334 input_section, output_bfd, error_message)
335 bfd *abfd;
336 arelent *reloc_entry;
337 asymbol *symbol;
338 PTR data;
339 asection *input_section;
340 bfd *output_bfd;
341 char **error_message ATTRIBUTE_UNUSED;
342 {
343 unsigned long insn, vallo, allignment;
344 int val;
345
346 /* HACK: I think this first condition is necessary when producing
347 relocatable output. After the end of HACK, the code is identical
348 to bfd_elf_generic_reloc(). I would _guess_ the first change
349 belongs there rather than here. martindo 1998-10-23. */
350
351 if (skip_dlx_elf_hi16_reloc)
352 return bfd_elf_generic_reloc (abfd, reloc_entry, symbol, data,
353 input_section, output_bfd, error_message);
354
355 /* Check undefined section and undefined symbols */
356 if (bfd_is_und_section (symbol->section)
357 && output_bfd == (bfd *) NULL)
358 return bfd_reloc_undefined;
359
360 /* Can not support a long jump to sections other then .text */
361 if (strcmp (input_section->name, symbol->section->output_section->name) != 0)
362 {
363 fprintf (stderr,
364 "BFD Link Error: branch (PC rel16) to section (%s) not supported\n",
365 symbol->section->output_section->name);
366 return bfd_reloc_undefined;
367 }
368
369 insn = bfd_get_32 (abfd, (bfd_byte *)data + reloc_entry->address);
370 allignment = 1 << (input_section->output_section->alignment_power - 1);
371 vallo = insn & 0x0000FFFF;
372
373 if (vallo & 0x8000)
374 vallo = ~(vallo | 0xFFFF0000) + 1;
375
376 /* vallo points to the vma of next instruction. */
377 vallo += (((unsigned long)(input_section->output_section->vma +
378 input_section->output_offset) +
379 allignment) & ~allignment);
380
381 /* val is the displacement (PC relative to next instruction). */
382 val = (symbol->section->output_offset +
383 symbol->section->output_section->vma +
384 symbol->value) - vallo;
385 #if 0
386 printf ("DEBUG elf32_dlx_relocate: We are here\n");
387 printf ("DEBUG: The insn = 0x%08x\n", insn);
388 printf ("DEBUG: The vallo = 0x%08x\n", vallo);
389 printf ("DEBUG: The val = 0x%08x\n", val);
390 printf ("DEBUG: The symbol name = %s\n", bfd_asymbol_name (symbol));
391 printf ("DEBUG: The symbol->value = 0x%08x\n", symbol->value);
392 printf ("DEBUG: The vma = 0x%08x\n", symbol->section->output_section->vma);
393 printf ("DEBUG: The lma = 0x%08x\n", symbol->section->output_section->lma);
394 printf ("DEBUG: The alignment_power = 0x%08x\n", symbol->section->output_section->alignment_power);
395 printf ("DEBUG: The output_offset = 0x%08x\n", symbol->section->output_offset);
396 printf ("DEBUG: The addend = 0x%08x\n", reloc_entry->addend);
397 #endif
398
399 if (abs ((int) val) > 0x00007FFF)
400 return bfd_reloc_outofrange;
401
402 insn = (insn & 0xFFFF0000) | (val & 0x0000FFFF);
403
404 bfd_put_32 (abfd, insn,
405 (bfd_byte *) data + reloc_entry->address);
406
407 return bfd_reloc_ok;
408 }
409
410 static bfd_reloc_status_type
411 elf32_dlx_relocate26 (abfd, reloc_entry, symbol, data,
412 input_section, output_bfd, error_message)
413 bfd *abfd;
414 arelent *reloc_entry;
415 asymbol *symbol;
416 PTR data;
417 asection *input_section;
418 bfd *output_bfd;
419 char **error_message ATTRIBUTE_UNUSED;
420 {
421 unsigned long insn, vallo, allignment;
422 int val;
423
424 /* HACK: I think this first condition is necessary when producing
425 relocatable output. After the end of HACK, the code is identical
426 to bfd_elf_generic_reloc(). I would _guess_ the first change
427 belongs there rather than here. martindo 1998-10-23. */
428
429 if (skip_dlx_elf_hi16_reloc)
430 return bfd_elf_generic_reloc (abfd, reloc_entry, symbol, data,
431 input_section, output_bfd, error_message);
432
433 /* Check undefined section and undefined symbols. */
434 if (bfd_is_und_section (symbol->section)
435 && output_bfd == (bfd *) NULL)
436 return bfd_reloc_undefined;
437
438 /* Can not support a long jump to sections other then .text */
439 if (strcmp (input_section->name, symbol->section->output_section->name) != 0)
440 {
441 fprintf (stderr,
442 "BFD Link Error: jump (PC rel26) to section (%s) not supported\n",
443 symbol->section->output_section->name);
444 return bfd_reloc_undefined;
445 }
446
447 insn = bfd_get_32 (abfd, (bfd_byte *)data + reloc_entry->address);
448 allignment = 1 << (input_section->output_section->alignment_power - 1);
449 vallo = insn & 0x03FFFFFF;
450
451 if (vallo & 0x03000000)
452 vallo = ~(vallo | 0xFC000000) + 1;
453
454 /* vallo is the vma for the next instruction. */
455 vallo += (((unsigned long) (input_section->output_section->vma +
456 input_section->output_offset) +
457 allignment) & ~allignment);
458
459 /* val is the displacement (PC relative to next instruction). */
460 val = (symbol->section->output_offset +
461 symbol->section->output_section->vma + symbol->value)
462 - vallo;
463 #if 0
464 printf ("DEBUG elf32_dlx_relocate26: We are here\n");
465 printf ("DEBUG: The insn = 0x%08x\n", insn);
466 printf ("DEBUG: The vallo = 0x%08x\n", vallo);
467 printf ("DEBUG: The val = 0x%08x\n", val);
468 printf ("DEBUG: The abs(val) = 0x%08x\n", abs (val));
469 printf ("DEBUG: The symbol name = %s\n", bfd_asymbol_name (symbol));
470 printf ("DEBUG: The symbol->value = 0x%08x\n", symbol->value);
471 printf ("DEBUG: The vma = 0x%08x\n", symbol->section->output_section->vma);
472 printf ("DEBUG: The output_offset = 0x%08x\n", symbol->section->output_offset);
473 printf ("DEBUG: The input_vma = 0x%08x\n", input_section->output_section->vma);
474 printf ("DEBUG: The input_offset = 0x%08x\n", input_section->output_offset);
475 printf ("DEBUG: The input_name = %s\n", input_section->name);
476 printf ("DEBUG: The addend = 0x%08x\n", reloc_entry->addend);
477 #endif
478
479 if (abs ((int) val) > 0x01FFFFFF)
480 return bfd_reloc_outofrange;
481
482 insn = (insn & 0xFC000000) | (val & 0x03FFFFFF);
483 bfd_put_32 (abfd, insn,
484 (bfd_byte *) data + reloc_entry->address);
485
486 return bfd_reloc_ok;
487 }
488
489 /* A mapping from BFD reloc types to DLX ELF reloc types.
490 Stolen from elf32-mips.c.
491
492 More about this table - for dlx elf relocation we do not really
493 need this table, if we have a rtype defined in this table will
494 caused tc_gen_relocate confused and die on us, but if we remove
495 this table it will caused more problem, so for now simple soulation
496 is to remove those entries which may cause problem. */
497 struct elf_reloc_map
498 {
499 bfd_reloc_code_real_type bfd_reloc_val;
500 enum elf_dlx_reloc_type elf_reloc_val;
501 };
502
503 static const struct elf_reloc_map dlx_reloc_map[] =
504 {
505 { BFD_RELOC_NONE, R_DLX_NONE },
506 { BFD_RELOC_16, R_DLX_RELOC_16 },
507 #if 0
508 { BFD_RELOC_DLX_JMP26, R_DLX_RELOC_26_PCREL },
509 #endif
510 { BFD_RELOC_32, R_DLX_RELOC_32 },
511 { BFD_RELOC_DLX_HI16_S, R_DLX_RELOC_16_HI },
512 { BFD_RELOC_DLX_LO16, R_DLX_RELOC_16_LO },
513 { BFD_RELOC_VTABLE_INHERIT, R_DLX_GNU_VTINHERIT },
514 { BFD_RELOC_VTABLE_ENTRY, R_DLX_GNU_VTENTRY }
515 };
516
517
518 /* Look through the relocs for a section during the first phase.
519 Since we don't do .gots or .plts, we just need to consider the
520 virtual table relocs for gc. */
521
522 static boolean
523 elf32_dlx_check_relocs (abfd, info, sec, relocs)
524 bfd *abfd;
525 struct bfd_link_info *info;
526 asection *sec;
527 const Elf_Internal_Rela *relocs;
528 {
529 Elf_Internal_Shdr *symtab_hdr;
530 struct elf_link_hash_entry **sym_hashes, **sym_hashes_end;
531 const Elf_Internal_Rela *rel;
532 const Elf_Internal_Rela *rel_end;
533
534 if (info->relocateable)
535 return true;
536
537 symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
538 sym_hashes = elf_sym_hashes (abfd);
539 sym_hashes_end = sym_hashes + symtab_hdr->sh_size / sizeof (Elf32_External_Sym);
540 if (!elf_bad_symtab (abfd))
541 sym_hashes_end -= symtab_hdr->sh_info;
542
543 rel_end = relocs + sec->reloc_count;
544 for (rel = relocs; rel < rel_end; rel++)
545 {
546 struct elf_link_hash_entry *h;
547 unsigned long r_symndx;
548
549 r_symndx = ELF32_R_SYM (rel->r_info);
550 if (r_symndx < symtab_hdr->sh_info)
551 h = NULL;
552 else
553 h = sym_hashes[r_symndx - symtab_hdr->sh_info];
554
555 switch (ELF32_R_TYPE (rel->r_info))
556 {
557 /* This relocation describes the C++ object vtable hierarchy.
558 Reconstruct it for later use during GC. */
559 case R_DLX_GNU_VTINHERIT:
560 if (!_bfd_elf32_gc_record_vtinherit (abfd, sec, h, rel->r_offset))
561 return false;
562 break;
563
564 /* This relocation describes which C++ vtable entries are actually
565 used. Record for later use during GC. */
566 case R_DLX_GNU_VTENTRY:
567 if (!_bfd_elf32_gc_record_vtentry (abfd, sec, h, rel->r_addend))
568 return false;
569 break;
570 }
571 }
572
573 return true;
574 }
575
576 /* Given a BFD reloc type, return a howto structure. */
577
578 static reloc_howto_type *
579 elf32_dlx_reloc_type_lookup (abfd, code)
580 bfd *abfd ATTRIBUTE_UNUSED;
581 bfd_reloc_code_real_type code;
582 {
583 unsigned int i;
584
585 for (i = 0; i < sizeof (dlx_reloc_map) / sizeof (struct elf_reloc_map); i++)
586 if (dlx_reloc_map[i].bfd_reloc_val == code)
587 return &dlx_elf_howto_table[(int) dlx_reloc_map[i].elf_reloc_val];
588
589 switch (code)
590 {
591 default:
592 bfd_set_error (bfd_error_bad_value);
593 return NULL;
594 case BFD_RELOC_16_PCREL_S2:
595 return &elf_dlx_gnu_rel16_s2;
596 case BFD_RELOC_DLX_JMP26:
597 return &elf_dlx_gnu_rel26_s2;
598 case BFD_RELOC_HI16_S:
599 return &elf_dlx_reloc_16_hi;
600 case BFD_RELOC_LO16:
601 return &elf_dlx_reloc_16_lo;
602 }
603 }
604
605 static reloc_howto_type *
606 dlx_rtype_to_howto (r_type)
607 unsigned int r_type;
608 {
609 switch (r_type)
610 {
611 case R_DLX_RELOC_16_PCREL:
612 return & elf_dlx_gnu_rel16_s2;
613 break;
614 case R_DLX_RELOC_26_PCREL:
615 return & elf_dlx_gnu_rel26_s2;
616 break;
617 case R_DLX_RELOC_16_HI:
618 return & elf_dlx_reloc_16_hi;
619 break;
620 case R_DLX_RELOC_16_LO:
621 return & elf_dlx_reloc_16_lo;
622 break;
623
624 default:
625 BFD_ASSERT (r_type < (unsigned int) R_DLX_max);
626 return & dlx_elf_howto_table[r_type];
627 break;
628 }
629 }
630
631 static void
632 elf32_dlx_info_to_howto (abfd, cache_ptr, dst)
633 bfd * abfd ATTRIBUTE_UNUSED;
634 arelent * cache_ptr ATTRIBUTE_UNUSED;
635 Elf32_Internal_Rela * dst ATTRIBUTE_UNUSED;
636 {
637 abort ();
638 }
639
640 static void
641 elf32_dlx_info_to_howto_rel (abfd, cache_ptr, dst)
642 bfd *abfd ATTRIBUTE_UNUSED;
643 arelent *cache_ptr;
644 Elf32_Internal_Rel *dst;
645 {
646 unsigned int r_type;
647
648 r_type = ELF32_R_TYPE (dst->r_info);
649 cache_ptr->howto = dlx_rtype_to_howto (r_type);
650 return;
651 }
652
653 #define TARGET_BIG_SYM bfd_elf32_dlx_big_vec
654 #define TARGET_BIG_NAME "elf32-dlx"
655 #define ELF_ARCH bfd_arch_dlx
656 #define ELF_MACHINE_CODE EM_DLX
657 #define ELF_MAXPAGESIZE 1 /* FIXME: This number is wrong, It should be the page size in bytes. */
658
659 #include "elf32-target.h"
This page took 0.053516 seconds and 4 git commands to generate.