1 /* CRIS-specific support for 32-bit ELF.
2 Copyright (C) 2000 Free Software Foundation, Inc.
3 Contributed by Axis Communications AB.
4 Written by Hans-Peter Nilsson, based on elf32-fr30.c
6 This file is part of BFD, the Binary File Descriptor library.
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
28 /* Forward declarations. */
29 static reloc_howto_type
* cris_reloc_type_lookup
30 PARAMS ((bfd
*abfd
, bfd_reloc_code_real_type code
));
32 static void cris_info_to_howto_rela
33 PARAMS ((bfd
*, arelent
*, Elf32_Internal_Rela
*));
35 static boolean cris_elf_relocate_section
36 PARAMS ((bfd
*, struct bfd_link_info
*, bfd
*, asection
*, bfd_byte
*,
37 Elf_Internal_Rela
*, Elf_Internal_Sym
*, asection
**));
39 static bfd_reloc_status_type cris_final_link_relocate
40 PARAMS ((reloc_howto_type
*, bfd
*, asection
*, bfd_byte
*,
41 Elf_Internal_Rela
*, bfd_vma
));
43 static boolean cris_elf_gc_sweep_hook
44 PARAMS ((bfd
*, struct bfd_link_info
*, asection
*,
45 const Elf_Internal_Rela
*));
47 static asection
* cris_elf_gc_mark_hook
48 PARAMS ((bfd
*, struct bfd_link_info
*, Elf_Internal_Rela
*,
49 struct elf_link_hash_entry
*, Elf_Internal_Sym
*));
51 static reloc_howto_type cris_elf_howto_table
[] =
53 /* This reloc does nothing. */
54 HOWTO (R_CRIS_NONE
, /* type */
56 2, /* size (0 = byte, 1 = short, 2 = long) */
58 false, /* pc_relative */
60 complain_overflow_bitfield
, /* complain_on_overflow */
61 bfd_elf_generic_reloc
, /* special_function */
62 "R_CRIS_NONE", /* name */
63 false, /* partial_inplace */
66 false), /* pcrel_offset */
68 /* An 8 bit absolute relocation. */
69 HOWTO (R_CRIS_8
, /* type */
71 0, /* size (0 = byte, 1 = short, 2 = long) */
73 false, /* pc_relative */
75 complain_overflow_bitfield
, /* complain_on_overflow */
76 bfd_elf_generic_reloc
, /* special_function */
77 "R_CRIS_8", /* name */
78 false, /* partial_inplace */
79 0x0000, /* src_mask */
80 0x00ff, /* dst_mask */
81 false), /* pcrel_offset */
83 /* A 16 bit absolute relocation. */
84 HOWTO (R_CRIS_16
, /* type */
86 1, /* size (0 = byte, 1 = short, 2 = long) */
88 false, /* pc_relative */
90 complain_overflow_bitfield
, /* complain_on_overflow */
91 bfd_elf_generic_reloc
, /* special_function */
92 "R_CRIS_16", /* name */
93 false, /* partial_inplace */
94 0x00000000, /* src_mask */
95 0x0000ffff, /* dst_mask */
96 false), /* pcrel_offset */
98 /* A 32 bit absolute relocation. */
99 HOWTO (R_CRIS_32
, /* type */
101 2, /* size (0 = byte, 1 = short, 2 = long) */
103 false, /* pc_relative */
105 complain_overflow_bitfield
, /* complain_on_overflow */
106 bfd_elf_generic_reloc
, /* special_function */
107 "R_CRIS_32", /* name */
108 false, /* partial_inplace */
109 0x00000000, /* src_mask */
110 0xffffffff, /* dst_mask */
111 false), /* pcrel_offset */
113 /* An 8 bit absolute relocation. */
114 HOWTO (R_CRIS_8_PCREL
, /* type */
116 0, /* size (0 = byte, 1 = short, 2 = long) */
118 true, /* pc_relative */
120 complain_overflow_bitfield
, /* complain_on_overflow */
121 bfd_elf_generic_reloc
, /* special_function */
122 "R_CRIS_8_PCREL", /* name */
123 false, /* partial_inplace */
124 0x0000, /* src_mask */
125 0x00ff, /* dst_mask */
126 false), /* pcrel_offset */
128 /* A 16 bit absolute relocation. */
129 HOWTO (R_CRIS_16_PCREL
, /* type */
131 1, /* size (0 = byte, 1 = short, 2 = long) */
133 true, /* pc_relative */
135 complain_overflow_bitfield
, /* complain_on_overflow */
136 bfd_elf_generic_reloc
, /* special_function */
137 "R_CRIS_16", /* name */
138 false, /* partial_inplace */
139 0x00000000, /* src_mask */
140 0x0000ffff, /* dst_mask */
141 false), /* pcrel_offset */
143 /* A 32 bit absolute relocation. */
144 HOWTO (R_CRIS_32_PCREL
, /* type */
146 2, /* size (0 = byte, 1 = short, 2 = long) */
148 true, /* pc_relative */
150 complain_overflow_bitfield
, /* complain_on_overflow */
151 bfd_elf_generic_reloc
, /* special_function */
152 "R_CRIS_32", /* name */
153 false, /* partial_inplace */
154 0x00000000, /* src_mask */
155 0xffffffff, /* dst_mask */
156 false), /* pcrel_offset */
158 /* GNU extension to record C++ vtable hierarchy */
159 HOWTO (R_CRIS_GNU_VTINHERIT
, /* type */
161 2, /* size (0 = byte, 1 = short, 2 = long) */
163 false, /* pc_relative */
165 complain_overflow_dont
, /* complain_on_overflow */
166 NULL
, /* special_function */
167 "R_CRIS_GNU_VTINHERIT", /* name */
168 false, /* partial_inplace */
171 false), /* pcrel_offset */
173 /* GNU extension to record C++ vtable member usage */
174 HOWTO (R_CRIS_GNU_VTENTRY
, /* type */
176 2, /* size (0 = byte, 1 = short, 2 = long) */
178 false, /* pc_relative */
180 complain_overflow_dont
, /* complain_on_overflow */
181 _bfd_elf_rel_vtable_reloc_fn
, /* special_function */
182 "R_CRIS_GNU_VTENTRY", /* name */
183 false, /* partial_inplace */
186 false) /* pcrel_offset */
189 /* Map BFD reloc types to CRIS ELF reloc types. */
191 struct cris_reloc_map
193 bfd_reloc_code_real_type bfd_reloc_val
;
194 unsigned int cris_reloc_val
;
197 static const struct cris_reloc_map cris_reloc_map
[] =
199 { BFD_RELOC_NONE
, R_CRIS_NONE
},
200 { BFD_RELOC_8
, R_CRIS_8
},
201 { BFD_RELOC_16
, R_CRIS_16
},
202 { BFD_RELOC_32
, R_CRIS_32
},
203 { BFD_RELOC_8_PCREL
, R_CRIS_8_PCREL
},
204 { BFD_RELOC_16_PCREL
, R_CRIS_16_PCREL
},
205 { BFD_RELOC_32_PCREL
, R_CRIS_32_PCREL
},
206 { BFD_RELOC_VTABLE_INHERIT
, R_CRIS_GNU_VTINHERIT
},
207 { BFD_RELOC_VTABLE_ENTRY
, R_CRIS_GNU_VTENTRY
}
210 static reloc_howto_type
*
211 cris_reloc_type_lookup (abfd
, code
)
212 bfd
* abfd ATTRIBUTE_UNUSED
;
213 bfd_reloc_code_real_type code
;
217 for (i
= sizeof (cris_reloc_map
) / sizeof (cris_reloc_map
[0]);
219 if (cris_reloc_map
[i
].bfd_reloc_val
== code
)
220 return & cris_elf_howto_table
[cris_reloc_map
[i
].cris_reloc_val
];
225 /* Set the howto pointer for an CRIS ELF reloc. */
228 cris_info_to_howto_rela (abfd
, cache_ptr
, dst
)
229 bfd
* abfd ATTRIBUTE_UNUSED
;
231 Elf32_Internal_Rela
* dst
;
235 r_type
= ELF32_R_TYPE (dst
->r_info
);
236 BFD_ASSERT (r_type
< (unsigned int) R_CRIS_max
);
237 cache_ptr
->howto
= & cris_elf_howto_table
[r_type
];
240 /* Perform a single relocation. By default we use the standard BFD
241 routines, but we might have to do a few relocs ourselves in the future. */
243 static bfd_reloc_status_type
244 cris_final_link_relocate (howto
, input_bfd
, input_section
, contents
, rel
,
246 reloc_howto_type
* howto
;
248 asection
* input_section
;
250 Elf_Internal_Rela
* rel
;
253 bfd_reloc_status_type r
254 = _bfd_final_link_relocate (howto
, input_bfd
, input_section
,
255 contents
, rel
->r_offset
,
256 relocation
, rel
->r_addend
);
260 /* Relocate an CRIS ELF section. See elf32-fr30.c, from where this was
261 copied, for further comments. */
264 cris_elf_relocate_section (output_bfd
, info
, input_bfd
, input_section
,
265 contents
, relocs
, local_syms
, local_sections
)
266 bfd
* output_bfd ATTRIBUTE_UNUSED
;
267 struct bfd_link_info
* info
;
269 asection
* input_section
;
271 Elf_Internal_Rela
* relocs
;
272 Elf_Internal_Sym
* local_syms
;
273 asection
** local_sections
;
275 Elf_Internal_Shdr
* symtab_hdr
;
276 struct elf_link_hash_entry
** sym_hashes
;
277 Elf_Internal_Rela
* rel
;
278 Elf_Internal_Rela
* relend
;
280 symtab_hdr
= & elf_tdata (input_bfd
)->symtab_hdr
;
281 sym_hashes
= elf_sym_hashes (input_bfd
);
282 relend
= relocs
+ input_section
->reloc_count
;
284 /* It seems this can happen with erroneous or unsupported input (mixing
285 a.out and elf in an archive, for example.) */
286 if (sym_hashes
== NULL
)
289 for (rel
= relocs
; rel
< relend
; rel
++)
291 reloc_howto_type
* howto
;
292 unsigned long r_symndx
;
293 Elf_Internal_Sym
* sym
;
295 struct elf_link_hash_entry
* h
;
297 bfd_reloc_status_type r
;
298 const char * name
= NULL
;
301 r_type
= ELF32_R_TYPE (rel
->r_info
);
303 if ( r_type
== R_CRIS_GNU_VTINHERIT
304 || r_type
== R_CRIS_GNU_VTENTRY
)
307 r_symndx
= ELF32_R_SYM (rel
->r_info
);
309 if (info
->relocateable
)
311 /* This is a relocateable link. We don't have to change
312 anything, unless the reloc is against a section symbol,
313 in which case we have to adjust according to where the
314 section symbol winds up in the output section. */
315 if (r_symndx
< symtab_hdr
->sh_info
)
317 sym
= local_syms
+ r_symndx
;
319 if (ELF_ST_TYPE (sym
->st_info
) == STT_SECTION
)
321 sec
= local_sections
[r_symndx
];
322 rel
->r_addend
+= sec
->output_offset
+ sym
->st_value
;
329 /* This is a final link. */
330 howto
= cris_elf_howto_table
+ ELF32_R_TYPE (rel
->r_info
);
335 if (r_symndx
< symtab_hdr
->sh_info
)
337 sym
= local_syms
+ r_symndx
;
338 sec
= local_sections
[r_symndx
];
339 relocation
= (sec
->output_section
->vma
343 name
= bfd_elf_string_from_elf_section
344 (input_bfd
, symtab_hdr
->sh_link
, sym
->st_name
);
345 name
= (name
== NULL
) ? bfd_section_name (input_bfd
, sec
) : name
;
347 fprintf (stderr
, "local: sec: %s, sym: %s (%d), value: %x + %x + %x addend %x\n",
348 sec
->name
, name
, sym
->st_name
,
349 sec
->output_section
->vma
, sec
->output_offset
,
350 sym
->st_value
, rel
->r_addend
);
355 h
= sym_hashes
[r_symndx
- symtab_hdr
->sh_info
];
357 while (h
->root
.type
== bfd_link_hash_indirect
358 || h
->root
.type
== bfd_link_hash_warning
)
359 h
= (struct elf_link_hash_entry
*) h
->root
.u
.i
.link
;
361 name
= h
->root
.root
.string
;
363 if (h
->root
.type
== bfd_link_hash_defined
364 || h
->root
.type
== bfd_link_hash_defweak
)
366 sec
= h
->root
.u
.def
.section
;
367 relocation
= (h
->root
.u
.def
.value
368 + sec
->output_section
->vma
369 + sec
->output_offset
);
372 "defined: sec: %s, name: %s, value: %x + %x + %x gives: %x\n",
373 sec
->name
, name
, h
->root
.u
.def
.value
,
374 sec
->output_section
->vma
, sec
->output_offset
, relocation
);
377 else if (h
->root
.type
== bfd_link_hash_undefweak
)
380 fprintf (stderr
, "undefined: sec: %s, name: %s\n",
385 else if (info
->shared
386 && ELF_ST_VISIBILITY (h
->other
) == STV_DEFAULT
)
390 if (! ((*info
->callbacks
->undefined_symbol
)
391 (info
, h
->root
.root
.string
, input_bfd
,
392 input_section
, rel
->r_offset
, true)))
395 fprintf (stderr
, "unknown: name: %s\n", name
);
401 r
= cris_final_link_relocate (howto
, input_bfd
, input_section
,
402 contents
, rel
, relocation
);
404 if (r
!= bfd_reloc_ok
)
406 const char * msg
= (const char *) NULL
;
410 case bfd_reloc_overflow
:
411 r
= info
->callbacks
->reloc_overflow
412 (info
, name
, howto
->name
, (bfd_vma
) 0,
413 input_bfd
, input_section
, rel
->r_offset
);
416 case bfd_reloc_undefined
:
417 r
= info
->callbacks
->undefined_symbol
418 (info
, name
, input_bfd
, input_section
, rel
->r_offset
,
422 case bfd_reloc_outofrange
:
423 msg
= _("internal error: out of range error");
426 case bfd_reloc_notsupported
:
427 msg
= _("internal error: unsupported relocation error");
430 case bfd_reloc_dangerous
:
431 msg
= _("internal error: dangerous relocation");
435 msg
= _("internal error: unknown error");
440 r
= info
->callbacks
->warning
441 (info
, msg
, name
, input_bfd
, input_section
, rel
->r_offset
);
451 /* Return the section that should be marked against GC for a given
455 cris_elf_gc_mark_hook (abfd
, info
, rel
, h
, sym
)
457 struct bfd_link_info
* info ATTRIBUTE_UNUSED
;
458 Elf_Internal_Rela
* rel
;
459 struct elf_link_hash_entry
* h
;
460 Elf_Internal_Sym
* sym
;
464 switch (ELF32_R_TYPE (rel
->r_info
))
466 case R_CRIS_GNU_VTINHERIT
:
467 case R_CRIS_GNU_VTENTRY
:
471 switch (h
->root
.type
)
473 case bfd_link_hash_defined
:
474 case bfd_link_hash_defweak
:
475 return h
->root
.u
.def
.section
;
477 case bfd_link_hash_common
:
478 return h
->root
.u
.c
.p
->section
;
487 if (!(elf_bad_symtab (abfd
)
488 && ELF_ST_BIND (sym
->st_info
) != STB_LOCAL
)
489 && ! ((sym
->st_shndx
<= 0 || sym
->st_shndx
>= SHN_LORESERVE
)
490 && sym
->st_shndx
!= SHN_COMMON
))
492 return bfd_section_from_elf_index (abfd
, sym
->st_shndx
);
499 /* Update the got entry reference counts for the section being removed. */
502 cris_elf_gc_sweep_hook (abfd
, info
, sec
, relocs
)
503 bfd
* abfd ATTRIBUTE_UNUSED
;
504 struct bfd_link_info
* info ATTRIBUTE_UNUSED
;
505 asection
* sec ATTRIBUTE_UNUSED
;
506 const Elf_Internal_Rela
* relocs ATTRIBUTE_UNUSED
;
511 /* Look through the relocs for a section during the first phase.
512 Since we don't do .gots or .plts, we just need to consider the
513 virtual table relocs for gc. */
516 cris_elf_check_relocs (abfd
, info
, sec
, relocs
)
518 struct bfd_link_info
*info
;
520 const Elf_Internal_Rela
*relocs
;
522 Elf_Internal_Shdr
*symtab_hdr
;
523 struct elf_link_hash_entry
**sym_hashes
, **sym_hashes_end
;
524 const Elf_Internal_Rela
*rel
;
525 const Elf_Internal_Rela
*rel_end
;
527 if (info
->relocateable
)
530 symtab_hdr
= &elf_tdata (abfd
)->symtab_hdr
;
531 sym_hashes
= elf_sym_hashes (abfd
);
532 sym_hashes_end
= sym_hashes
+ symtab_hdr
->sh_size
/sizeof(Elf32_External_Sym
);
533 if (!elf_bad_symtab (abfd
))
534 sym_hashes_end
-= symtab_hdr
->sh_info
;
536 rel_end
= relocs
+ sec
->reloc_count
;
537 for (rel
= relocs
; rel
< rel_end
; rel
++)
539 struct elf_link_hash_entry
*h
;
540 unsigned long r_symndx
;
542 r_symndx
= ELF32_R_SYM (rel
->r_info
);
543 if (r_symndx
< symtab_hdr
->sh_info
)
546 h
= sym_hashes
[r_symndx
- symtab_hdr
->sh_info
];
548 switch (ELF32_R_TYPE (rel
->r_info
))
550 /* This relocation describes the C++ object vtable hierarchy.
551 Reconstruct it for later use during GC. */
552 case R_CRIS_GNU_VTINHERIT
:
553 if (!_bfd_elf32_gc_record_vtinherit (abfd
, sec
, h
, rel
->r_offset
))
557 /* This relocation describes which C++ vtable entries are actually
558 used. Record for later use during GC. */
559 case R_CRIS_GNU_VTENTRY
:
560 if (!_bfd_elf32_gc_record_vtentry (abfd
, sec
, h
, rel
->r_addend
))
569 #define ELF_ARCH bfd_arch_cris
570 #define ELF_MACHINE_CODE EM_CRIS
571 #define ELF_MAXPAGESIZE 0x2000
573 #define TARGET_LITTLE_SYM bfd_elf32_cris_vec
574 #define TARGET_LITTLE_NAME "elf32-cris"
576 /* For the time being, we have a leading underscore. Perhaps change to 0
578 1) a.out isn't as dominating, and we can forget about multiformat links
579 and old assembly code.
580 2) there's an official solution to the symbol vs. register duality
581 problem; perhaps a % register prefix, optionally enforced. */
582 #define elf_symbol_leading_char '_'
584 #define elf_info_to_howto_rel NULL
585 #define elf_info_to_howto cris_info_to_howto_rela
586 #define elf_backend_relocate_section cris_elf_relocate_section
587 #define elf_backend_gc_mark_hook cris_elf_gc_mark_hook
588 #define elf_backend_gc_sweep_hook cris_elf_gc_sweep_hook
589 #define elf_backend_check_relocs cris_elf_check_relocs
591 #define elf_backend_can_gc_sections 1
593 #define bfd_elf32_bfd_reloc_type_lookup cris_reloc_type_lookup
595 /* Later, we my want to optimize RELA entries into REL entries for dynamic
596 linking and libraries (if it's a win of any significance). Until then,
597 take the easy route. */
598 #define elf_backend_may_use_rel_p 0
599 #define elf_backend_may_use_rela_p 1
601 #include "elf32-target.h"