source: trunk/src/binutils/bfd/elf32-iq2000.c@ 607

Last change on this file since 607 was 607, checked in by bird, 22 years ago

Initial revision

  • Property cvs2svn:cvs-rev set to 1.1
  • Property svn:eol-style set to native
  • Property svn:executable set to *
File size: 29.4 KB
Line 
1/* IQ2000-specific support for 32-bit ELF.
2 Copyright (C) 2003 Free Software Foundation, Inc.
3
4This file is part of BFD, the Binary File Descriptor library.
5
6This program is free software; you can redistribute it and/or modify
7it under the terms of the GNU General Public License as published by
8the Free Software Foundation; either version 2 of the License, or
9(at your option) any later version.
10
11This program is distributed in the hope that it will be useful,
12but WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14GNU General Public License for more details.
15
16You should have received a copy of the GNU General Public License
17along with this program; if not, write to the Free Software
18Foundation, 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/iq2000.h"
25
26/* Forward declarations. */
27
28/* Private relocation functions. */
29static bfd_reloc_status_type iq2000_elf_relocate_hi16 PARAMS ((bfd *, Elf_Internal_Rela *, bfd_byte *, bfd_vma));
30static reloc_howto_type * iq2000_reloc_type_lookup PARAMS ((bfd *, bfd_reloc_code_real_type));
31static void iq2000_info_to_howto_rela PARAMS ((bfd *, arelent *, Elf_Internal_Rela *));
32static bfd_boolean iq2000_elf_relocate_section PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *, Elf_Internal_Rela *, Elf_Internal_Sym *, asection **));
33static bfd_reloc_status_type iq2000_final_link_relocate PARAMS ((reloc_howto_type *, bfd *, asection *, bfd_byte *, Elf_Internal_Rela *, bfd_vma));
34static bfd_boolean iq2000_elf_gc_sweep_hook PARAMS ((bfd *, struct bfd_link_info *, asection *, const Elf_Internal_Rela *));
35static asection * iq2000_elf_gc_mark_hook PARAMS ((asection *sec, struct bfd_link_info *, Elf_Internal_Rela *, struct elf_link_hash_entry *, Elf_Internal_Sym *));
36static reloc_howto_type * iq2000_reloc_type_lookup PARAMS ((bfd *, bfd_reloc_code_real_type));
37static int elf32_iq2000_machine PARAMS ((bfd *));
38static bfd_boolean iq2000_elf_object_p PARAMS ((bfd *));
39static bfd_boolean iq2000_elf_set_private_flags PARAMS ((bfd *, flagword));
40static bfd_boolean iq2000_elf_copy_private_bfd_data PARAMS ((bfd *, bfd *));
41static bfd_boolean iq2000_elf_merge_private_bfd_data PARAMS ((bfd *, bfd *));
42static bfd_boolean iq2000_elf_print_private_bfd_data PARAMS ((bfd *, PTR));
43static bfd_boolean iq2000_elf_check_relocs PARAMS ((bfd *, struct bfd_link_info *, asection *, const Elf_Internal_Rela *));
44static bfd_reloc_status_type iq2000_elf_howto_hi16_reloc PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
45
46
47
48static reloc_howto_type iq2000_elf_howto_table [] =
49{
50 /* This reloc does nothing. */
51
52 HOWTO (R_IQ2000_NONE, /* type */
53 0, /* rightshift */
54 2, /* size (0 = byte, 1 = short, 2 = long) */
55 32, /* bitsize */
56 FALSE, /* pc_relative */
57 0, /* bitpos */
58 complain_overflow_bitfield, /* complain_on_overflow */
59 bfd_elf_generic_reloc, /* special_function */
60 "R_IQ2000_NONE", /* name */
61 FALSE, /* partial_inplace */
62 0, /* src_mask */
63 0, /* dst_mask */
64 FALSE), /* pcrel_offset */
65
66 /* A 16 bit absolute relocation. */
67 HOWTO (R_IQ2000_16, /* type */
68 0, /* rightshift */
69 1, /* size (0 = byte, 1 = short, 2 = long) */
70 16, /* bitsize */
71 FALSE, /* pc_relative */
72 0, /* bitpos */
73 complain_overflow_bitfield, /* complain_on_overflow */
74 bfd_elf_generic_reloc, /* special_function */
75 "R_IQ2000_16", /* name */
76 FALSE, /* partial_inplace */
77 0x0000, /* src_mask */
78 0xffff, /* dst_mask */
79 FALSE), /* pcrel_offset */
80
81 /* A 32 bit absolute relocation. */
82 HOWTO (R_IQ2000_32, /* type */
83 0, /* rightshift */
84 2, /* size (0 = byte, 1 = short, 2 = long) */
85 31, /* bitsize */
86 FALSE, /* pc_relative */
87 0, /* bitpos */
88 complain_overflow_bitfield, /* complain_on_overflow */
89 bfd_elf_generic_reloc, /* special_function */
90 "R_IQ2000_32", /* name */
91 FALSE, /* partial_inplace */
92 0x00000000, /* src_mask */
93 0x7fffffff, /* dst_mask */
94 FALSE), /* pcrel_offset */
95
96 /* 26 bit branch address. */
97 HOWTO (R_IQ2000_26, /* type */
98 2, /* rightshift */
99 2, /* size (0 = byte, 1 = short, 2 = long) */
100 26, /* bitsize */
101 FALSE, /* pc_relative */
102 0, /* bitpos */
103 complain_overflow_dont, /* complain_on_overflow */
104 /* This needs complex overflow
105 detection, because the upper four
106 bits must match the PC. */
107 bfd_elf_generic_reloc, /* special_function */
108 "R_IQ2000_26", /* name */
109 FALSE, /* partial_inplace */
110 0x00000000, /* src_mask */
111 0x03ffffff, /* dst_mask */
112 FALSE), /* pcrel_offset */
113
114 /* 16 bit PC relative reference. */
115 HOWTO (R_IQ2000_PC16, /* type */
116 2, /* rightshift */
117 2, /* size (0 = byte, 1 = short, 2 = long) */
118 16, /* bitsize */
119 TRUE, /* pc_relative */
120 0, /* bitpos */
121 complain_overflow_signed, /* complain_on_overflow */
122 bfd_elf_generic_reloc, /* special_function */
123 "R_IQ2000_PC16", /* name */
124 FALSE, /* partial_inplace */
125 0x0000, /* src_mask */
126 0xffff, /* dst_mask */
127 TRUE), /* pcrel_offset */
128
129 /* high 16 bits of symbol value. */
130 HOWTO (R_IQ2000_HI16, /* type */
131 16, /* rightshift */
132 2, /* size (0 = byte, 1 = short, 2 = long) */
133 15, /* bitsize */
134 FALSE, /* pc_relative */
135 0, /* bitpos */
136 complain_overflow_dont, /* complain_on_overflow */
137 iq2000_elf_howto_hi16_reloc, /* special_function */
138 "R_IQ2000_HI16", /* name */
139 FALSE, /* partial_inplace */
140 0x0000, /* src_mask */
141 0x7fff, /* dst_mask */
142 FALSE), /* pcrel_offset */
143
144 /* Low 16 bits of symbol value. */
145 HOWTO (R_IQ2000_LO16, /* type */
146 0, /* rightshift */
147 2, /* size (0 = byte, 1 = short, 2 = long) */
148 16, /* bitsize */
149 FALSE, /* pc_relative */
150 0, /* bitpos */
151 complain_overflow_dont, /* complain_on_overflow */
152 bfd_elf_generic_reloc, /* special_function */
153 "R_IQ2000_LO16", /* name */
154 FALSE, /* partial_inplace */
155 0x0000, /* src_mask */
156 0xffff, /* dst_mask */
157 FALSE), /* pcrel_offset */
158
159 /* 16-bit jump offset. */
160 HOWTO (R_IQ2000_OFFSET_16, /* type */
161 2, /* rightshift */
162 2, /* size (0 = byte, 1 = short, 2 = long) */
163 16, /* bitsize */
164 FALSE, /* pc_relative */
165 0, /* bitpos */
166 complain_overflow_dont, /* complain_on_overflow */
167 bfd_elf_generic_reloc, /* special_function */
168 "R_IQ2000_OFFSET_16", /* name */
169 FALSE, /* partial_inplace */
170 0x0000, /* src_mask */
171 0xffff, /* dst_mask */
172 FALSE), /* pcrel_offset */
173
174 /* 21-bit jump offset. */
175 HOWTO (R_IQ2000_OFFSET_21, /* type */
176 2, /* rightshift */
177 2, /* size (0 = byte, 1 = short, 2 = long) */
178 21, /* bitsize */
179 FALSE, /* pc_relative */
180 0, /* bitpos */
181 complain_overflow_dont, /* complain_on_overflow */
182 bfd_elf_generic_reloc, /* special_function */
183 "R_IQ2000_OFFSET_21", /* name */
184 FALSE, /* partial_inplace */
185 0x000000, /* src_mask */
186 0x1fffff, /* dst_mask */
187 FALSE), /* pcrel_offset */
188
189 /* unsigned high 16 bits of value. */
190 HOWTO (R_IQ2000_OFFSET_21, /* type */
191 16, /* rightshift */
192 2, /* size (0 = byte, 1 = short, 2 = long) */
193 16, /* bitsize */
194 FALSE, /* pc_relative */
195 0, /* bitpos */
196 complain_overflow_dont, /* complain_on_overflow */
197 bfd_elf_generic_reloc, /* special_function */
198 "R_IQ2000_UHI16", /* name */
199 FALSE, /* partial_inplace */
200 0x0000, /* src_mask */
201 0x7fff, /* dst_mask */
202 FALSE), /* pcrel_offset */
203
204 /* A 32 bit absolute debug relocation. */
205 HOWTO (R_IQ2000_32_DEBUG, /* type */
206 0, /* rightshift */
207 2, /* size (0 = byte, 1 = short, 2 = long) */
208 32, /* bitsize */
209 FALSE, /* pc_relative */
210 0, /* bitpos */
211 complain_overflow_bitfield, /* complain_on_overflow */
212 bfd_elf_generic_reloc, /* special_function */
213 "R_IQ2000_32", /* name */
214 FALSE, /* partial_inplace */
215 0x00000000, /* src_mask */
216 0xffffffff, /* dst_mask */
217 FALSE), /* pcrel_offset */
218
219};
220
221/* GNU extension to record C++ vtable hierarchy. */
222static reloc_howto_type iq2000_elf_vtinherit_howto =
223 HOWTO (R_IQ2000_GNU_VTINHERIT, /* type */
224 0, /* rightshift */
225 2, /* size (0 = byte, 1 = short, 2 = long) */
226 0, /* bitsize */
227 FALSE, /* pc_relative */
228 0, /* bitpos */
229 complain_overflow_dont, /* complain_on_overflow */
230 NULL, /* special_function */
231 "R_IQ2000_GNU_VTINHERIT", /* name */
232 FALSE, /* partial_inplace */
233 0, /* src_mask */
234 0, /* dst_mask */
235 FALSE); /* pcrel_offset */
236
237/* GNU extension to record C++ vtable member usage. */
238static reloc_howto_type iq2000_elf_vtentry_howto =
239 HOWTO (R_IQ2000_GNU_VTENTRY, /* type */
240 0, /* rightshift */
241 2, /* size (0 = byte, 1 = short, 2 = long) */
242 0, /* bitsize */
243 FALSE, /* pc_relative */
244 0, /* bitpos */
245 complain_overflow_dont, /* complain_on_overflow */
246 NULL, /* special_function */
247 "R_IQ2000_GNU_VTENTRY", /* name */
248 FALSE, /* partial_inplace */
249 0, /* src_mask */
250 0, /* dst_mask */
251 FALSE); /* pcrel_offset */
252
253
254
255/* Map BFD reloc types to IQ2000 ELF reloc types. */
256
257struct iq2000_reloc_map
258{
259 bfd_reloc_code_real_type bfd_reloc_val;
260 unsigned int iq2000_reloc_val;
261};
262
263static const struct iq2000_reloc_map iq2000_reloc_map [] =
264{
265 { BFD_RELOC_NONE, R_IQ2000_NONE },
266 { BFD_RELOC_16, R_IQ2000_16 },
267 { BFD_RELOC_32, R_IQ2000_32 },
268 { BFD_RELOC_MIPS_JMP, R_IQ2000_26 },
269 { BFD_RELOC_16_PCREL_S2, R_IQ2000_PC16 },
270 { BFD_RELOC_HI16, R_IQ2000_HI16 },
271 { BFD_RELOC_LO16, R_IQ2000_LO16 },
272 { BFD_RELOC_IQ2000_OFFSET_16,R_IQ2000_OFFSET_16 },
273 { BFD_RELOC_IQ2000_OFFSET_21,R_IQ2000_OFFSET_21 },
274 { BFD_RELOC_IQ2000_UHI16, R_IQ2000_UHI16 },
275 { BFD_RELOC_VTABLE_INHERIT, R_IQ2000_GNU_VTINHERIT },
276 { BFD_RELOC_VTABLE_ENTRY, R_IQ2000_GNU_VTENTRY },
277};
278
279static bfd_reloc_status_type
280iq2000_elf_howto_hi16_reloc (abfd,
281 reloc_entry,
282 symbol,
283 data,
284 input_section,
285 output_bfd,
286 error_message)
287 bfd *abfd ATTRIBUTE_UNUSED;
288 arelent *reloc_entry;
289 asymbol *symbol;
290 PTR data;
291 asection *input_section;
292 bfd *output_bfd;
293 char **error_message ATTRIBUTE_UNUSED;
294{
295 bfd_reloc_status_type ret;
296 bfd_vma relocation;
297
298 /* If we're relocating, and this an external symbol, we don't want
299 to change anything. */
300 if (output_bfd != (bfd *) NULL
301 && (symbol->flags & BSF_SECTION_SYM) == 0
302 && reloc_entry->addend == 0)
303 {
304 reloc_entry->address += input_section->output_offset;
305 return bfd_reloc_ok;
306 }
307
308 if (bfd_is_com_section (symbol->section))
309 relocation = 0;
310 else
311 relocation = symbol->value;
312
313 relocation += symbol->section->output_section->vma;
314 relocation += symbol->section->output_offset;
315 relocation += reloc_entry->addend;
316
317 /* if %lo will have sign-extension, compensate by add 0x10000 to hi portion */
318 if (relocation & 0x8000)
319 reloc_entry->addend += 0x10000;
320
321 /* Now do the reloc in the usual way. */
322 ret = bfd_elf_generic_reloc (abfd, reloc_entry, symbol, data,
323 input_section, output_bfd, error_message);
324
325 /* put it back the way it was */
326 if (relocation & 0x8000)
327 reloc_entry->addend -= 0x10000;
328
329 return ret;
330}
331
332static bfd_reloc_status_type
333iq2000_elf_relocate_hi16 (input_bfd, relhi, contents, value)
334 bfd *input_bfd;
335 Elf_Internal_Rela *relhi;
336 bfd_byte *contents;
337 bfd_vma value;
338{
339 bfd_vma insn;
340
341 insn = bfd_get_32 (input_bfd, contents + relhi->r_offset);
342
343 value += relhi->r_addend;
344 value &= 0x7fffffff; /* mask off top-bit which is Harvard mask bit */
345
346 /* if top-bit of %lo value is on, this means that %lo will
347 sign-propagate and so we compensate by adding 1 to %hi value */
348 if (value & 0x8000)
349 value += 0x10000;
350
351 value >>= 16;
352 insn = ((insn & ~0xFFFF) | value);
353
354 bfd_put_32 (input_bfd, insn, contents + relhi->r_offset);
355 return bfd_reloc_ok;
356}
357
358static reloc_howto_type *
359iq2000_reloc_type_lookup (abfd, code)
360 bfd * abfd ATTRIBUTE_UNUSED;
361 bfd_reloc_code_real_type code;
362{
363 /* Note that the iq2000_elf_howto_table is indxed by the R_
364 constants. Thus, the order that the howto records appear in the
365 table *must* match the order of the relocation types defined in
366 include/elf/iq2000.h. */
367
368 switch (code)
369 {
370 case BFD_RELOC_NONE:
371 return &iq2000_elf_howto_table[ (int) R_IQ2000_NONE];
372 case BFD_RELOC_16:
373 return &iq2000_elf_howto_table[ (int) R_IQ2000_16];
374 case BFD_RELOC_32:
375 return &iq2000_elf_howto_table[ (int) R_IQ2000_32];
376 case BFD_RELOC_MIPS_JMP:
377 return &iq2000_elf_howto_table[ (int) R_IQ2000_26];
378 case BFD_RELOC_IQ2000_OFFSET_16:
379 return &iq2000_elf_howto_table[ (int) R_IQ2000_OFFSET_16];
380 case BFD_RELOC_IQ2000_OFFSET_21:
381 return &iq2000_elf_howto_table[ (int) R_IQ2000_OFFSET_21];
382 case BFD_RELOC_16_PCREL_S2:
383 return &iq2000_elf_howto_table[ (int) R_IQ2000_PC16];
384 case BFD_RELOC_HI16:
385 return &iq2000_elf_howto_table[ (int) R_IQ2000_HI16];
386 case BFD_RELOC_IQ2000_UHI16:
387 return &iq2000_elf_howto_table[ (int) R_IQ2000_UHI16];
388 case BFD_RELOC_LO16:
389 return &iq2000_elf_howto_table[ (int) R_IQ2000_LO16];
390 case BFD_RELOC_VTABLE_INHERIT:
391 return &iq2000_elf_vtinherit_howto;
392 case BFD_RELOC_VTABLE_ENTRY:
393 return &iq2000_elf_vtentry_howto;
394 default:
395 /* Pacify gcc -Wall. */
396 return NULL;
397 }
398 return NULL;
399}
400
401
402
403/* Perform a single relocation. By default we use the standard BFD
404 routines. */
405
406static bfd_reloc_status_type
407iq2000_final_link_relocate (howto, input_bfd, input_section, contents, rel, relocation)
408 reloc_howto_type * howto;
409 bfd * input_bfd;
410 asection * input_section;
411 bfd_byte * contents;
412 Elf_Internal_Rela * rel;
413 bfd_vma relocation;
414{
415 return _bfd_final_link_relocate (howto, input_bfd, input_section,
416 contents, rel->r_offset,
417 relocation, rel->r_addend);
418}
419
420
421/* Set the howto pointer for a IQ2000 ELF reloc. */
422
423static void
424iq2000_info_to_howto_rela (abfd, cache_ptr, dst)
425 bfd * abfd ATTRIBUTE_UNUSED;
426 arelent * cache_ptr;
427 Elf_Internal_Rela * dst;
428{
429 unsigned int r_type;
430
431 r_type = ELF32_R_TYPE (dst->r_info);
432 switch (r_type)
433 {
434 case R_IQ2000_GNU_VTINHERIT:
435 cache_ptr->howto = & iq2000_elf_vtinherit_howto;
436 break;
437
438 case R_IQ2000_GNU_VTENTRY:
439 cache_ptr->howto = & iq2000_elf_vtentry_howto;
440 break;
441
442 default:
443 cache_ptr->howto = & iq2000_elf_howto_table [r_type];
444 break;
445 }
446}
447
448/* Look through the relocs for a section during the first phase.
449 Since we don't do .gots or .plts, we just need to consider the
450 virtual table relocs for gc. */
451
452static bfd_boolean
453iq2000_elf_check_relocs (abfd, info, sec, relocs)
454 bfd *abfd;
455 struct bfd_link_info *info;
456 asection *sec;
457 const Elf_Internal_Rela *relocs;
458{
459 Elf_Internal_Shdr *symtab_hdr;
460 struct elf_link_hash_entry **sym_hashes, **sym_hashes_end;
461 const Elf_Internal_Rela *rel;
462 const Elf_Internal_Rela *rel_end;
463 bfd_boolean changed = FALSE;
464
465 if (info->relocateable)
466 return TRUE;
467
468 symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
469 sym_hashes = elf_sym_hashes (abfd);
470 sym_hashes_end = sym_hashes + symtab_hdr->sh_size/sizeof(Elf32_External_Sym);
471 if (!elf_bad_symtab (abfd))
472 sym_hashes_end -= symtab_hdr->sh_info;
473
474 rel_end = relocs + sec->reloc_count;
475 for (rel = relocs; rel < rel_end; rel++)
476 {
477 struct elf_link_hash_entry *h;
478 unsigned long r_symndx;
479
480 r_symndx = ELF32_R_SYM (rel->r_info);
481 if (r_symndx < symtab_hdr->sh_info)
482 h = NULL;
483 else
484 h = sym_hashes[r_symndx - symtab_hdr->sh_info];
485
486 switch (ELF32_R_TYPE (rel->r_info))
487 {
488 /* This relocation describes the C++ object vtable hierarchy.
489 Reconstruct it for later use during GC. */
490 case R_IQ2000_GNU_VTINHERIT:
491 if (!_bfd_elf32_gc_record_vtinherit (abfd, sec, h, rel->r_offset))
492 return FALSE;
493 break;
494
495 /* This relocation describes which C++ vtable entries are actually
496 used. Record for later use during GC. */
497 case R_IQ2000_GNU_VTENTRY:
498 if (!_bfd_elf32_gc_record_vtentry (abfd, sec, h, rel->r_addend))
499 return FALSE;
500 break;
501
502 case R_IQ2000_32:
503 /* For debug section, change to special harvard-aware relocations */
504 if (memcmp (sec->name, ".debug", 6) == 0
505 || memcmp (sec->name, ".stab", 5) == 0
506 || memcmp (sec->name, ".eh_frame", 9) == 0)
507 {
508 ((Elf_Internal_Rela *) rel)->r_info
509 = ELF32_R_INFO (ELF32_R_SYM (rel->r_info), R_IQ2000_32_DEBUG);
510 changed = TRUE;
511 }
512 break;
513 }
514 }
515
516 if (changed)
517 /* Note that we've changed relocs, otherwise if !info->keep_memory
518 we'll free the relocs and lose our changes. */
519 (const Elf_Internal_Rela *) (elf_section_data (sec)->relocs) = relocs;
520
521 return TRUE;
522}
523
524
525
526/* Relocate a IQ2000 ELF section.
527 There is some attempt to make this function usable for many architectures,
528 both USE_REL and USE_RELA ['twould be nice if such a critter existed],
529 if only to serve as a learning tool.
530
531 The RELOCATE_SECTION function is called by the new ELF backend linker
532 to handle the relocations for a section.
533
534 The relocs are always passed as Rela structures; if the section
535 actually uses Rel structures, the r_addend field will always be
536 zero.
537
538 This function is responsible for adjusting the section contents as
539 necessary, and (if using Rela relocs and generating a relocateable
540 output file) adjusting the reloc addend as necessary.
541
542 This function does not have to worry about setting the reloc
543 address or the reloc symbol index.
544
545 LOCAL_SYMS is a pointer to the swapped in local symbols.
546
547 LOCAL_SECTIONS is an array giving the section in the input file
548 corresponding to the st_shndx field of each local symbol.
549
550 The global hash table entry for the global symbols can be found
551 via elf_sym_hashes (input_bfd).
552
553 When generating relocateable output, this function must handle
554 STB_LOCAL/STT_SECTION symbols specially. The output symbol is
555 going to be the section symbol corresponding to the output
556 section, which means that the addend must be adjusted
557 accordingly. */
558
559static bfd_boolean
560iq2000_elf_relocate_section (output_bfd, info, input_bfd, input_section,
561 contents, relocs, local_syms, local_sections)
562 bfd * output_bfd ATTRIBUTE_UNUSED;
563 struct bfd_link_info * info;
564 bfd * input_bfd;
565 asection * input_section;
566 bfd_byte * contents;
567 Elf_Internal_Rela * relocs;
568 Elf_Internal_Sym * local_syms;
569 asection ** local_sections;
570{
571 Elf_Internal_Shdr * symtab_hdr;
572 struct elf_link_hash_entry ** sym_hashes;
573 Elf_Internal_Rela * rel;
574 Elf_Internal_Rela * relend;
575
576 symtab_hdr = & elf_tdata (input_bfd)->symtab_hdr;
577 sym_hashes = elf_sym_hashes (input_bfd);
578 relend = relocs + input_section->reloc_count;
579
580 for (rel = relocs; rel < relend; rel ++)
581 {
582 reloc_howto_type * howto;
583 unsigned long r_symndx;
584 Elf_Internal_Sym * sym;
585 asection * sec;
586 struct elf_link_hash_entry * h;
587 bfd_vma relocation;
588 bfd_reloc_status_type r;
589 const char * name = NULL;
590 int r_type;
591
592 r_type = ELF32_R_TYPE (rel->r_info);
593
594 if ( r_type == R_IQ2000_GNU_VTINHERIT
595 || r_type == R_IQ2000_GNU_VTENTRY)
596 continue;
597
598 r_symndx = ELF32_R_SYM (rel->r_info);
599
600 /* This is a final link. */
601 howto = iq2000_elf_howto_table + ELF32_R_TYPE (rel->r_info);
602 h = NULL;
603 sym = NULL;
604 sec = NULL;
605
606 if (r_symndx < symtab_hdr->sh_info)
607 {
608 sym = local_syms + r_symndx;
609 sec = local_sections [r_symndx];
610 relocation = (sec->output_section->vma
611 + sec->output_offset
612 + sym->st_value);
613
614 name = bfd_elf_string_from_elf_section
615 (input_bfd, symtab_hdr->sh_link, sym->st_name);
616 name = (name == NULL) ? bfd_section_name (input_bfd, sec) : name;
617#ifdef DEBUG
618 fprintf (stderr, "local: sec: %s, sym: %s (%d), value: %x + %x + %x addend %x\n",
619 sec->name, name, sym->st_name,
620 sec->output_section->vma, sec->output_offset,
621 sym->st_value, rel->r_addend);
622#endif
623 }
624 else
625 {
626 h = sym_hashes [r_symndx];
627
628 while (h->root.type == bfd_link_hash_indirect
629 || h->root.type == bfd_link_hash_warning)
630 h = (struct elf_link_hash_entry *) h->root.u.i.link;
631
632 name = h->root.root.string;
633
634 if (h->root.type == bfd_link_hash_defined
635 || h->root.type == bfd_link_hash_defweak)
636 {
637 sec = h->root.u.def.section;
638 relocation = (h->root.u.def.value
639 + sec->output_section->vma
640 + sec->output_offset);
641#ifdef DEBUG
642 fprintf (stderr,
643 "defined: sec: %s, name: %s, value: %x + %x + %x gives: %x\n",
644 sec->name, name, h->root.u.def.value,
645 sec->output_section->vma, sec->output_offset, relocation);
646#endif
647 }
648 else if (h->root.type == bfd_link_hash_undefweak)
649 {
650#ifdef DEBUG
651 fprintf (stderr, "undefined: sec: %s, name: %s\n",
652 sec->name, name);
653#endif
654 relocation = 0;
655 }
656 else
657 {
658 if (! ((*info->callbacks->undefined_symbol)
659 (info, h->root.root.string, input_bfd,
660 input_section, rel->r_offset,
661 (!info->shared || info->no_undefined))))
662 return FALSE;
663#ifdef DEBUG
664 fprintf (stderr, "unknown: name: %s\n", name);
665#endif
666 relocation = 0;
667 }
668 }
669
670 switch (r_type)
671 {
672 case R_IQ2000_HI16:
673 r = iq2000_elf_relocate_hi16 (input_bfd, rel, contents, relocation);
674 break;
675
676 case R_IQ2000_PC16:
677 rel->r_addend -= 4;
678 /* Fall through. */
679
680 default:
681 r = iq2000_final_link_relocate (howto, input_bfd, input_section,
682 contents, rel, relocation);
683 break;
684 }
685
686 if (r != bfd_reloc_ok)
687 {
688 const char * msg = (const char *) NULL;
689
690 switch (r)
691 {
692 case bfd_reloc_overflow:
693 r = info->callbacks->reloc_overflow
694 (info, name, howto->name, (bfd_vma) 0,
695 input_bfd, input_section, rel->r_offset);
696 break;
697
698 case bfd_reloc_undefined:
699 r = info->callbacks->undefined_symbol
700 (info, name, input_bfd, input_section, rel->r_offset, TRUE);
701 break;
702
703 case bfd_reloc_outofrange:
704 msg = _("internal error: out of range error");
705 break;
706
707 case bfd_reloc_notsupported:
708 msg = _("internal error: unsupported relocation error");
709 break;
710
711 case bfd_reloc_dangerous:
712 msg = _("internal error: dangerous relocation");
713 break;
714
715 default:
716 msg = _("internal error: unknown error");
717 break;
718 }
719
720 if (msg)
721 r = info->callbacks->warning
722 (info, msg, name, input_bfd, input_section, rel->r_offset);
723
724 if (! r)
725 return FALSE;
726 }
727 }
728
729 return TRUE;
730}
731
732
733
734/* Update the got entry reference counts for the section being
735 removed. */
736
737static bfd_boolean
738iq2000_elf_gc_sweep_hook (abfd, info, sec, relocs)
739 bfd * abfd ATTRIBUTE_UNUSED;
740 struct bfd_link_info * info ATTRIBUTE_UNUSED;
741 asection * sec ATTRIBUTE_UNUSED;
742 const Elf_Internal_Rela * relocs ATTRIBUTE_UNUSED;
743{
744 return TRUE;
745}
746
747/* Return the section that should be marked against GC for a given
748 relocation. */
749
750static asection *
751iq2000_elf_gc_mark_hook (sec, info, rel, h, sym)
752 asection * sec;
753 struct bfd_link_info * info ATTRIBUTE_UNUSED;
754 Elf_Internal_Rela * rel;
755 struct elf_link_hash_entry * h;
756 Elf_Internal_Sym * sym;
757{
758 if (h != NULL)
759 {
760 switch (ELF32_R_TYPE (rel->r_info))
761 {
762 case R_IQ2000_GNU_VTINHERIT:
763 case R_IQ2000_GNU_VTENTRY:
764 break;
765
766 default:
767 switch (h->root.type)
768 {
769 case bfd_link_hash_defined:
770 case bfd_link_hash_defweak:
771 return h->root.u.def.section;
772
773 case bfd_link_hash_common:
774 return h->root.u.c.p->section;
775
776 default:
777 break;
778 }
779 }
780 }
781 else
782 return bfd_section_from_elf_index (sec->owner, sym->st_shndx);
783
784 return NULL;
785}
786
787
788
789/* Return the MACH for an e_flags value. */
790
791static int
792elf32_iq2000_machine (abfd)
793 bfd *abfd;
794{
795 switch (elf_elfheader (abfd)->e_flags & EF_IQ2000_CPU_MASK)
796 {
797 case EF_IQ2000_CPU_IQ2000: return bfd_mach_iq2000;
798 case EF_IQ2000_CPU_IQ10: return bfd_mach_iq10;
799 }
800
801 return bfd_mach_iq2000;
802}
803
804
805
806/* Function to set the ELF flag bits. */
807
808static bfd_boolean
809iq2000_elf_set_private_flags (abfd, flags)
810 bfd *abfd;
811 flagword flags;
812{
813 elf_elfheader (abfd)->e_flags = flags;
814 elf_flags_init (abfd) = TRUE;
815 return TRUE;
816}
817
818/* Copy backend specific data from one object module to another. */
819
820static bfd_boolean
821iq2000_elf_copy_private_bfd_data (ibfd, obfd)
822 bfd *ibfd;
823 bfd *obfd;
824{
825 if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
826 || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
827 return TRUE;
828
829 BFD_ASSERT (!elf_flags_init (obfd)
830 || elf_elfheader (obfd)->e_flags == elf_elfheader (ibfd)->e_flags);
831
832 elf_elfheader (obfd)->e_flags = elf_elfheader (ibfd)->e_flags;
833 elf_flags_init (obfd) = TRUE;
834 return TRUE;
835}
836
837/* Merge backend specific data from an object file to the output
838 object file when linking. */
839
840static bfd_boolean
841iq2000_elf_merge_private_bfd_data (ibfd, obfd)
842 bfd *ibfd;
843 bfd *obfd;
844{
845 flagword old_flags, old_partial;
846 flagword new_flags, new_partial;
847 bfd_boolean error = FALSE;
848 char new_opt[80];
849 char old_opt[80];
850
851 new_opt[0] = old_opt[0] = '\0';
852 new_flags = elf_elfheader (ibfd)->e_flags;
853 old_flags = elf_elfheader (obfd)->e_flags;
854
855#ifdef DEBUG
856 (*_bfd_error_handler) ("old_flags = 0x%.8lx, new_flags = 0x%.8lx, init = %s, filename = %s",
857 old_flags, new_flags, elf_flags_init (obfd) ? "yes" : "no",
858 bfd_get_filename (ibfd));
859#endif
860
861 if (!elf_flags_init (obfd))
862 {
863 /* First call, no flags set. */
864 elf_flags_init (obfd) = TRUE;
865 elf_elfheader (obfd)->e_flags = new_flags;
866 }
867
868 else if (new_flags == old_flags)
869 /* Compatible flags are ok. */
870 ;
871
872 else /* Possibly incompatible flags. */
873 {
874 /* Warn if different cpu is used (allow a specific cpu to override
875 the generic cpu). */
876 new_partial = (new_flags & EF_IQ2000_CPU_MASK);
877 old_partial = (old_flags & EF_IQ2000_CPU_MASK);
878 if (new_partial == old_partial)
879 ;
880
881 else
882 {
883 switch (new_partial)
884 {
885 default: strcat (new_opt, " -m2000"); break;
886 case EF_IQ2000_CPU_IQ2000: strcat (new_opt, " -m2000"); break;
887 case EF_IQ2000_CPU_IQ10: strcat (new_opt, " -m10"); break;
888 }
889
890 switch (old_partial)
891 {
892 default: strcat (old_opt, " -m2000"); break;
893 case EF_IQ2000_CPU_IQ2000: strcat (old_opt, " -m2000"); break;
894 case EF_IQ2000_CPU_IQ10: strcat (old_opt, " -m10"); break;
895 }
896 }
897
898 /* Print out any mismatches from above. */
899 if (new_opt[0])
900 {
901 error = TRUE;
902 (*_bfd_error_handler)
903 (_("%s: compiled with %s and linked with modules compiled with %s"),
904 bfd_get_filename (ibfd), new_opt, old_opt);
905 }
906
907 new_flags &= ~ EF_IQ2000_ALL_FLAGS;
908 old_flags &= ~ EF_IQ2000_ALL_FLAGS;
909
910 /* Warn about any other mismatches. */
911 if (new_flags != old_flags)
912 {
913 error = TRUE;
914 (*_bfd_error_handler)
915 (_("%s: uses different e_flags (0x%lx) fields than previous modules (0x%lx)"),
916 bfd_get_filename (ibfd), (long)new_flags, (long)old_flags);
917 }
918 }
919
920 if (error)
921 bfd_set_error (bfd_error_bad_value);
922
923 return !error;
924}
925
926
927
928static bfd_boolean
929iq2000_elf_print_private_bfd_data (abfd, ptr)
930 bfd *abfd;
931 PTR ptr;
932{
933 FILE *file = (FILE *) ptr;
934 flagword flags;
935
936 BFD_ASSERT (abfd != NULL && ptr != NULL);
937
938 /* Print normal ELF private data. */
939 _bfd_elf_print_private_bfd_data (abfd, ptr);
940
941 flags = elf_elfheader (abfd)->e_flags;
942 fprintf (file, _("private flags = 0x%lx:"), (long)flags);
943
944 switch (flags & EF_IQ2000_CPU_MASK)
945 {
946 default: break;
947 case EF_IQ2000_CPU_IQ2000: fprintf (file, " -m2000"); break;
948 case EF_IQ2000_CPU_IQ10: fprintf (file, " -m10"); break;
949 }
950
951 fputc ('\n', file);
952 return TRUE;
953}
954
955static
956bfd_boolean
957iq2000_elf_object_p (abfd)
958 bfd *abfd;
959{
960 /* Irix 5 and 6 is broken. Object file symbol tables are not always
961 sorted correctly such that local symbols precede global symbols,
962 and the sh_info field in the symbol table is not always right. */
963 elf_bad_symtab (abfd) = TRUE;
964
965 bfd_default_set_arch_mach (abfd, bfd_arch_iq2000,
966 elf32_iq2000_machine (abfd));
967 return TRUE;
968}
969
970
971
972#define ELF_ARCH bfd_arch_iq2000
973#define ELF_MACHINE_CODE EM_IQ2000
974#define ELF_MAXPAGESIZE 0x1000
975
976#define TARGET_BIG_SYM bfd_elf32_iq2000_vec
977#define TARGET_BIG_NAME "elf32-iq2000"
978
979#define elf_info_to_howto_rel NULL
980#define elf_info_to_howto iq2000_info_to_howto_rela
981#define elf_backend_relocate_section iq2000_elf_relocate_section
982#define elf_backend_gc_mark_hook iq2000_elf_gc_mark_hook
983#define elf_backend_gc_sweep_hook iq2000_elf_gc_sweep_hook
984#define elf_backend_check_relocs iq2000_elf_check_relocs
985#define elf_backend_object_p iq2000_elf_object_p
986#define elf_backend_rela_normal 1
987
988#define elf_backend_can_gc_sections 1
989
990#define bfd_elf32_bfd_reloc_type_lookup iq2000_reloc_type_lookup
991#define bfd_elf32_bfd_set_private_flags iq2000_elf_set_private_flags
992#define bfd_elf32_bfd_copy_private_bfd_data iq2000_elf_copy_private_bfd_data
993#define bfd_elf32_bfd_merge_private_bfd_data iq2000_elf_merge_private_bfd_data
994#define bfd_elf32_bfd_print_private_bfd_data iq2000_elf_print_private_bfd_data
995
996#include "elf32-target.h"
Note: See TracBrowser for help on using the repository browser.