* cris.h (EF_CRIS_UNDERSCORE): New.
[deliverable/binutils-gdb.git] / bfd / elf32-cris.c
CommitLineData
06c15ad7
HPN
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
5
6This file is part of BFD, the Binary File Descriptor library.
7
8This program is free software; you can redistribute it and/or modify
9it under the terms of the GNU General Public License as published by
10the Free Software Foundation; either version 2 of the License, or
11(at your option) any later version.
12
13This program is distributed in the hope that it will be useful,
14but WITHOUT ANY WARRANTY; without even the implied warranty of
15MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16GNU General Public License for more details.
17
18You should have received a copy of the GNU General Public License
19along with this program; if not, write to the Free Software
20Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
21
22#include "bfd.h"
23#include "sysdep.h"
24#include "libbfd.h"
25#include "elf-bfd.h"
26#include "elf/cris.h"
27
28/* Forward declarations. */
29static reloc_howto_type * cris_reloc_type_lookup
30 PARAMS ((bfd *abfd, bfd_reloc_code_real_type code));
31
32static void cris_info_to_howto_rela
33 PARAMS ((bfd *, arelent *, Elf32_Internal_Rela *));
34
35static boolean cris_elf_relocate_section
36 PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *,
37 Elf_Internal_Rela *, Elf_Internal_Sym *, asection **));
38
39static bfd_reloc_status_type cris_final_link_relocate
40 PARAMS ((reloc_howto_type *, bfd *, asection *, bfd_byte *,
41 Elf_Internal_Rela *, bfd_vma));
42
43static boolean cris_elf_gc_sweep_hook
44 PARAMS ((bfd *, struct bfd_link_info *, asection *,
45 const Elf_Internal_Rela *));
46
47static 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 *));
50
51static reloc_howto_type cris_elf_howto_table [] =
52{
53 /* This reloc does nothing. */
54 HOWTO (R_CRIS_NONE, /* type */
55 0, /* rightshift */
56 2, /* size (0 = byte, 1 = short, 2 = long) */
57 32, /* bitsize */
58 false, /* pc_relative */
59 0, /* bitpos */
60 complain_overflow_bitfield, /* complain_on_overflow */
61 bfd_elf_generic_reloc, /* special_function */
62 "R_CRIS_NONE", /* name */
63 false, /* partial_inplace */
64 0, /* src_mask */
65 0, /* dst_mask */
66 false), /* pcrel_offset */
67
68 /* An 8 bit absolute relocation. */
69 HOWTO (R_CRIS_8, /* type */
70 0, /* rightshift */
71 0, /* size (0 = byte, 1 = short, 2 = long) */
72 8, /* bitsize */
73 false, /* pc_relative */
74 0, /* bitpos */
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 */
82
83 /* A 16 bit absolute relocation. */
84 HOWTO (R_CRIS_16, /* type */
85 0, /* rightshift */
86 1, /* size (0 = byte, 1 = short, 2 = long) */
87 16, /* bitsize */
88 false, /* pc_relative */
89 0, /* bitpos */
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 */
97
98 /* A 32 bit absolute relocation. */
99 HOWTO (R_CRIS_32, /* type */
100 0, /* rightshift */
101 2, /* size (0 = byte, 1 = short, 2 = long) */
102 32, /* bitsize */
103 false, /* pc_relative */
104 0, /* bitpos */
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 */
112
113 /* An 8 bit absolute relocation. */
114 HOWTO (R_CRIS_8_PCREL, /* type */
115 0, /* rightshift */
116 0, /* size (0 = byte, 1 = short, 2 = long) */
117 8, /* bitsize */
118 true, /* pc_relative */
119 0, /* bitpos */
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 */
127
128 /* A 16 bit absolute relocation. */
129 HOWTO (R_CRIS_16_PCREL, /* type */
130 0, /* rightshift */
131 1, /* size (0 = byte, 1 = short, 2 = long) */
132 16, /* bitsize */
133 true, /* pc_relative */
134 0, /* bitpos */
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 */
142
143 /* A 32 bit absolute relocation. */
144 HOWTO (R_CRIS_32_PCREL, /* type */
145 0, /* rightshift */
146 2, /* size (0 = byte, 1 = short, 2 = long) */
147 32, /* bitsize */
148 true, /* pc_relative */
149 0, /* bitpos */
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 */
157
158 /* GNU extension to record C++ vtable hierarchy */
159 HOWTO (R_CRIS_GNU_VTINHERIT, /* type */
160 0, /* rightshift */
161 2, /* size (0 = byte, 1 = short, 2 = long) */
162 0, /* bitsize */
163 false, /* pc_relative */
164 0, /* bitpos */
165 complain_overflow_dont, /* complain_on_overflow */
166 NULL, /* special_function */
167 "R_CRIS_GNU_VTINHERIT", /* name */
168 false, /* partial_inplace */
169 0, /* src_mask */
170 0, /* dst_mask */
171 false), /* pcrel_offset */
172
173 /* GNU extension to record C++ vtable member usage */
174 HOWTO (R_CRIS_GNU_VTENTRY, /* type */
175 0, /* rightshift */
176 2, /* size (0 = byte, 1 = short, 2 = long) */
177 0, /* bitsize */
178 false, /* pc_relative */
179 0, /* bitpos */
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 */
184 0, /* src_mask */
185 0, /* dst_mask */
186 false) /* pcrel_offset */
187};
188\f
189/* Map BFD reloc types to CRIS ELF reloc types. */
190
191struct cris_reloc_map
192{
193 bfd_reloc_code_real_type bfd_reloc_val;
194 unsigned int cris_reloc_val;
195};
196
197static const struct cris_reloc_map cris_reloc_map [] =
198{
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 }
208};
209
210static reloc_howto_type *
211cris_reloc_type_lookup (abfd, code)
212 bfd * abfd ATTRIBUTE_UNUSED;
213 bfd_reloc_code_real_type code;
214{
215 unsigned int i;
216
217 for (i = sizeof (cris_reloc_map) / sizeof (cris_reloc_map[0]);
218 --i;)
219 if (cris_reloc_map [i].bfd_reloc_val == code)
220 return & cris_elf_howto_table [cris_reloc_map[i].cris_reloc_val];
221
222 return NULL;
223}
224
225/* Set the howto pointer for an CRIS ELF reloc. */
226
227static void
228cris_info_to_howto_rela (abfd, cache_ptr, dst)
229 bfd * abfd ATTRIBUTE_UNUSED;
230 arelent * cache_ptr;
231 Elf32_Internal_Rela * dst;
232{
233 unsigned int r_type;
234
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];
238}
239\f
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. */
242
243static bfd_reloc_status_type
244cris_final_link_relocate (howto, input_bfd, input_section, contents, rel,
245 relocation)
246 reloc_howto_type * howto;
247 bfd * input_bfd;
248 asection * input_section;
249 bfd_byte * contents;
250 Elf_Internal_Rela * rel;
251 bfd_vma relocation;
252{
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);
257 return r;
258}
259\f
260/* Relocate an CRIS ELF section. See elf32-fr30.c, from where this was
261 copied, for further comments. */
262
263static boolean
264cris_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;
268 bfd * input_bfd;
269 asection * input_section;
270 bfd_byte * contents;
271 Elf_Internal_Rela * relocs;
272 Elf_Internal_Sym * local_syms;
273 asection ** local_sections;
274{
275 Elf_Internal_Shdr * symtab_hdr;
276 struct elf_link_hash_entry ** sym_hashes;
277 Elf_Internal_Rela * rel;
278 Elf_Internal_Rela * relend;
279
280 symtab_hdr = & elf_tdata (input_bfd)->symtab_hdr;
281 sym_hashes = elf_sym_hashes (input_bfd);
282 relend = relocs + input_section->reloc_count;
283
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)
287 return false;
288
289 for (rel = relocs; rel < relend; rel ++)
290 {
291 reloc_howto_type * howto;
292 unsigned long r_symndx;
293 Elf_Internal_Sym * sym;
294 asection * sec;
295 struct elf_link_hash_entry * h;
296 bfd_vma relocation;
297 bfd_reloc_status_type r;
298 const char * name = NULL;
299 int r_type;
300
301 r_type = ELF32_R_TYPE (rel->r_info);
302
303 if ( r_type == R_CRIS_GNU_VTINHERIT
304 || r_type == R_CRIS_GNU_VTENTRY)
305 continue;
306
307 r_symndx = ELF32_R_SYM (rel->r_info);
308
309 if (info->relocateable)
310 {
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)
316 {
317 sym = local_syms + r_symndx;
318
319 if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
320 {
321 sec = local_sections [r_symndx];
322 rel->r_addend += sec->output_offset + sym->st_value;
323 }
324 }
325
326 continue;
327 }
328
329 /* This is a final link. */
330 howto = cris_elf_howto_table + ELF32_R_TYPE (rel->r_info);
331 h = NULL;
332 sym = NULL;
333 sec = NULL;
334
335 if (r_symndx < symtab_hdr->sh_info)
336 {
337 sym = local_syms + r_symndx;
338 sec = local_sections [r_symndx];
339 relocation = (sec->output_section->vma
340 + sec->output_offset
341 + sym->st_value);
342
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;
346#if 0
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);
351#endif
352 }
353 else
354 {
355 h = sym_hashes [r_symndx - symtab_hdr->sh_info];
356
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;
360
361 name = h->root.root.string;
362
363 if (h->root.type == bfd_link_hash_defined
364 || h->root.type == bfd_link_hash_defweak)
365 {
366 sec = h->root.u.def.section;
367 relocation = (h->root.u.def.value
368 + sec->output_section->vma
369 + sec->output_offset);
370#if 0
371 fprintf (stderr,
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);
375#endif
376 }
377 else if (h->root.type == bfd_link_hash_undefweak)
378 {
379#if 0
380 fprintf (stderr, "undefined: sec: %s, name: %s\n",
381 sec->name, name);
382#endif
383 relocation = 0;
384 }
385 else if (info->shared
386 && ELF_ST_VISIBILITY (h->other) == STV_DEFAULT)
387 relocation = 0;
388 else
389 {
390 if (! ((*info->callbacks->undefined_symbol)
391 (info, h->root.root.string, input_bfd,
392 input_section, rel->r_offset, true)))
393 return false;
394#if 0
395 fprintf (stderr, "unknown: name: %s\n", name);
396#endif
397 relocation = 0;
398 }
399 }
400
401 r = cris_final_link_relocate (howto, input_bfd, input_section,
402 contents, rel, relocation);
403
404 if (r != bfd_reloc_ok)
405 {
406 const char * msg = (const char *) NULL;
407
408 switch (r)
409 {
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);
414 break;
415
416 case bfd_reloc_undefined:
417 r = info->callbacks->undefined_symbol
418 (info, name, input_bfd, input_section, rel->r_offset,
419 true);
420 break;
421
422 case bfd_reloc_outofrange:
423 msg = _("internal error: out of range error");
424 break;
425
426 case bfd_reloc_notsupported:
427 msg = _("internal error: unsupported relocation error");
428 break;
429
430 case bfd_reloc_dangerous:
431 msg = _("internal error: dangerous relocation");
432 break;
433
434 default:
435 msg = _("internal error: unknown error");
436 break;
437 }
438
439 if (msg)
440 r = info->callbacks->warning
441 (info, msg, name, input_bfd, input_section, rel->r_offset);
442
443 if (! r)
444 return false;
445 }
446 }
447
448 return true;
449}
450\f
451/* Return the section that should be marked against GC for a given
452 relocation. */
453
454static asection *
455cris_elf_gc_mark_hook (abfd, info, rel, h, sym)
456 bfd * abfd;
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;
461{
462 if (h != NULL)
463 {
464 switch (ELF32_R_TYPE (rel->r_info))
465 {
466 case R_CRIS_GNU_VTINHERIT:
467 case R_CRIS_GNU_VTENTRY:
468 break;
469
470 default:
471 switch (h->root.type)
472 {
473 case bfd_link_hash_defined:
474 case bfd_link_hash_defweak:
475 return h->root.u.def.section;
476
477 case bfd_link_hash_common:
478 return h->root.u.c.p->section;
479
480 default:
481 break;
482 }
483 }
484 }
485 else
486 {
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))
491 {
492 return bfd_section_from_elf_index (abfd, sym->st_shndx);
493 }
494 }
495
496 return NULL;
497}
498
499/* Update the got entry reference counts for the section being removed. */
500
501static boolean
502cris_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;
507{
508 return true;
509}
510
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. */
514
515static boolean
516cris_elf_check_relocs (abfd, info, sec, relocs)
517 bfd *abfd;
518 struct bfd_link_info *info;
519 asection *sec;
520 const Elf_Internal_Rela *relocs;
521{
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;
526
527 if (info->relocateable)
528 return true;
529
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;
535
536 rel_end = relocs + sec->reloc_count;
537 for (rel = relocs; rel < rel_end; rel++)
538 {
539 struct elf_link_hash_entry *h;
540 unsigned long r_symndx;
541
542 r_symndx = ELF32_R_SYM (rel->r_info);
543 if (r_symndx < symtab_hdr->sh_info)
544 h = NULL;
545 else
546 h = sym_hashes[r_symndx - symtab_hdr->sh_info];
547
548 switch (ELF32_R_TYPE (rel->r_info))
549 {
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))
554 return false;
555 break;
556
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))
561 return false;
562 break;
563 }
564 }
565
566 return true;
567}
568\f
569#define ELF_ARCH bfd_arch_cris
570#define ELF_MACHINE_CODE EM_CRIS
571#define ELF_MAXPAGESIZE 0x2000
572
573#define TARGET_LITTLE_SYM bfd_elf32_cris_vec
574#define TARGET_LITTLE_NAME "elf32-cris"
575
576/* For the time being, we have a leading underscore. Perhaps change to 0
577 later, when
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 '_'
583
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
590
591#define elf_backend_can_gc_sections 1
592
593#define bfd_elf32_bfd_reloc_type_lookup cris_reloc_type_lookup
594
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
600
601#include "elf32-target.h"
This page took 0.053877 seconds and 4 git commands to generate.