bfd/
[deliverable/binutils-gdb.git] / bfd / elf32-mcore.c
CommitLineData
59d23ada 1/* Motorola MCore specific support for 32-bit ELF
ab96bf03
AM
2 Copyright 1994, 1995, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
3 2007 Free Software Foundation, Inc.
252b5132 4
47b0e7ad 5 This file is part of BFD, the Binary File Descriptor library.
252b5132 6
47b0e7ad
NC
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
cd123cb7 9 the Free Software Foundation; either version 3 of the License, or
47b0e7ad 10 (at your option) any later version.
252b5132 11
47b0e7ad
NC
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
252b5132 16
47b0e7ad
NC
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
cd123cb7
NC
19 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
20 MA 02110-1301, USA. */
21
252b5132
RH
22
23/* This file is based on a preliminary RCE ELF ABI. The
24 information may not match the final RCE ELF ABI. */
25
252b5132 26#include "sysdep.h"
3db64b00 27#include "bfd.h"
252b5132
RH
28#include "bfdlink.h"
29#include "libbfd.h"
30#include "elf-bfd.h"
31#include "elf/mcore.h"
32#include <assert.h>
33
f0fe0e16 34/* RELA relocs are used here... */
252b5132 35
47b0e7ad
NC
36/* Function to set whether a module needs the -mrelocatable bit set. */
37
38static bfd_boolean
39mcore_elf_set_private_flags (bfd * abfd, flagword flags)
40{
41 BFD_ASSERT (! elf_flags_init (abfd)
42 || elf_elfheader (abfd)->e_flags == flags);
43
44 elf_elfheader (abfd)->e_flags = flags;
45 elf_flags_init (abfd) = TRUE;
46 return TRUE;
47}
48
49/* Merge backend specific data from an object file to the output
50 object file when linking. */
51
52static bfd_boolean
53mcore_elf_merge_private_bfd_data (bfd * ibfd, bfd * obfd)
54{
55 flagword old_flags;
56 flagword new_flags;
57
58 /* Check if we have the same endianess. */
59 if (! _bfd_generic_verify_endian_match (ibfd, obfd))
60 return FALSE;
61
62 if ( bfd_get_flavour (ibfd) != bfd_target_elf_flavour
63 || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
64 return TRUE;
65
66 new_flags = elf_elfheader (ibfd)->e_flags;
67 old_flags = elf_elfheader (obfd)->e_flags;
68
69 if (! elf_flags_init (obfd))
70 {
71 /* First call, no flags set. */
72 elf_flags_init (obfd) = TRUE;
73 elf_elfheader (obfd)->e_flags = new_flags;
74 }
75 else if (new_flags == old_flags)
76 /* Compatible flags are OK. */
77 ;
78 else
79 {
80 /* FIXME */
81 }
82
83 return TRUE;
84}
85\f
86/* Don't pretend we can deal with unsupported relocs. */
87
88static bfd_reloc_status_type
89mcore_elf_unsupported_reloc (bfd * abfd,
90 arelent * reloc_entry,
91 asymbol * symbol ATTRIBUTE_UNUSED,
92 PTR data ATTRIBUTE_UNUSED,
93 asection * input_section ATTRIBUTE_UNUSED,
94 bfd * output_bfd ATTRIBUTE_UNUSED,
95 char ** error_message ATTRIBUTE_UNUSED)
96{
97 BFD_ASSERT (reloc_entry->howto != (reloc_howto_type *)0);
98
99 _bfd_error_handler (_("%B: Relocation %s (%d) is not currently supported.\n"),
100 abfd,
101 reloc_entry->howto->name,
102 reloc_entry->howto->type);
103
104 return bfd_reloc_notsupported;
105}
252b5132
RH
106
107static reloc_howto_type * mcore_elf_howto_table [(int) R_MCORE_max];
108
109static reloc_howto_type mcore_elf_howto_raw[] =
110{
111 /* This reloc does nothing. */
112 HOWTO (R_MCORE_NONE, /* type */
113 0, /* rightshift */
114 2, /* size (0 = byte, 1 = short, 2 = long) */
59d23ada 115 32, /* bitsize */
b34976b6 116 FALSE, /* pc_relative */
252b5132
RH
117 0, /* bitpos */
118 complain_overflow_bitfield, /* complain_on_overflow */
59d23ada 119 NULL, /* special_function */
252b5132 120 "R_MCORE_NONE", /* name */
b34976b6 121 FALSE, /* partial_inplace */
252b5132
RH
122 0, /* src_mask */
123 0, /* dst_mask */
b34976b6 124 FALSE), /* pcrel_offset */
252b5132
RH
125
126 /* A standard 32 bit relocation. */
127 HOWTO (R_MCORE_ADDR32, /* type */
128 0, /* rightshift */
129 2, /* size (0 = byte, 1 = short, 2 = long) */
130 32, /* bitsize */
b34976b6 131 FALSE, /* pc_relative */
252b5132
RH
132 0, /* bitpos */
133 complain_overflow_bitfield, /* complain_on_overflow */
134 bfd_elf_generic_reloc, /* special_function */
4cc11e76 135 "ADDR32", /* name *//* For compatibility with coff/pe port. */
b34976b6 136 FALSE, /* partial_inplace */
252b5132
RH
137 0x0, /* src_mask */
138 0xffffffff, /* dst_mask */
b34976b6 139 FALSE), /* pcrel_offset */
252b5132
RH
140
141 /* 8 bits + 2 zero bits; jmpi/jsri/lrw instructions.
c3668558 142 Should not appear in object files. */
252b5132
RH
143 HOWTO (R_MCORE_PCRELIMM8BY4, /* type */
144 2, /* rightshift */
145 1, /* size (0 = byte, 1 = short, 2 = long) */
146 8, /* bitsize */
b34976b6 147 TRUE, /* pc_relative */
252b5132
RH
148 0, /* bitpos */
149 complain_overflow_bitfield, /* complain_on_overflow */
150 mcore_elf_unsupported_reloc, /* special_function */
151 "R_MCORE_PCRELIMM8BY4",/* name */
b34976b6 152 FALSE, /* partial_inplace */
252b5132
RH
153 0, /* src_mask */
154 0, /* dst_mask */
b34976b6 155 TRUE), /* pcrel_offset */
252b5132 156
c3668558 157 /* bsr/bt/bf/br instructions; 11 bits + 1 zero bit
252b5132
RH
158 Span 2k instructions == 4k bytes.
159 Only useful pieces at the relocated address are the opcode (5 bits) */
160 HOWTO (R_MCORE_PCRELIMM11BY2,/* type */
161 1, /* rightshift */
162 1, /* size (0 = byte, 1 = short, 2 = long) */
163 11, /* bitsize */
b34976b6 164 TRUE, /* pc_relative */
252b5132
RH
165 0, /* bitpos */
166 complain_overflow_signed, /* complain_on_overflow */
167 bfd_elf_generic_reloc, /* special_function */
168 "R_MCORE_PCRELIMM11BY2",/* name */
b34976b6 169 FALSE, /* partial_inplace */
252b5132
RH
170 0x0, /* src_mask */
171 0x7ff, /* dst_mask */
b34976b6 172 TRUE), /* pcrel_offset */
252b5132 173
c3668558 174 /* 4 bits + 1 zero bit; 'loopt' instruction only; unsupported. */
252b5132
RH
175 HOWTO (R_MCORE_PCRELIMM4BY2, /* type */
176 1, /* rightshift */
177 1, /* size (0 = byte, 1 = short, 2 = long) */
178 4, /* bitsize */
b34976b6 179 TRUE, /* pc_relative */
252b5132
RH
180 0, /* bitpos */
181 complain_overflow_bitfield, /* complain_on_overflow */
182 mcore_elf_unsupported_reloc,/* special_function */
183 "R_MCORE_PCRELIMM4BY2",/* name */
b34976b6 184 FALSE, /* partial_inplace */
252b5132
RH
185 0, /* src_mask */
186 0, /* dst_mask */
b34976b6 187 TRUE), /* pcrel_offset */
252b5132 188
c3668558 189 /* 32-bit pc-relative. Eventually this will help support PIC code. */
252b5132
RH
190 HOWTO (R_MCORE_PCREL32, /* type */
191 0, /* rightshift */
192 2, /* size (0 = byte, 1 = short, 2 = long) */
193 32, /* bitsize */
b34976b6 194 TRUE, /* pc_relative */
252b5132
RH
195 0, /* bitpos */
196 complain_overflow_bitfield, /* complain_on_overflow */
197 bfd_elf_generic_reloc, /* special_function */
198 "R_MCORE_PCREL32", /* name */
b34976b6 199 FALSE, /* partial_inplace */
252b5132
RH
200 0x0, /* src_mask */
201 0xffffffff, /* dst_mask */
b34976b6 202 TRUE), /* pcrel_offset */
252b5132
RH
203
204 /* Like PCRELIMM11BY2, this relocation indicates that there is a
205 'jsri' at the specified address. There is a separate relocation
c3668558 206 entry for the literal pool entry that it references, but we
252b5132
RH
207 might be able to change the jsri to a bsr if the target turns out
208 to be close enough [even though we won't reclaim the literal pool
209 entry, we'll get some runtime efficiency back]. Note that this
c3668558 210 is a relocation that we are allowed to safely ignore. */
252b5132
RH
211 HOWTO (R_MCORE_PCRELJSR_IMM11BY2,/* type */
212 1, /* rightshift */
213 1, /* size (0 = byte, 1 = short, 2 = long) */
214 11, /* bitsize */
b34976b6 215 TRUE, /* pc_relative */
252b5132
RH
216 0, /* bitpos */
217 complain_overflow_signed, /* complain_on_overflow */
218 bfd_elf_generic_reloc, /* special_function */
219 "R_MCORE_PCRELJSR_IMM11BY2", /* name */
b34976b6 220 FALSE, /* partial_inplace */
252b5132
RH
221 0x0, /* src_mask */
222 0x7ff, /* dst_mask */
b34976b6 223 TRUE), /* pcrel_offset */
c3668558 224
47b0e7ad 225 /* GNU extension to record C++ vtable hierarchy. */
252b5132
RH
226 HOWTO (R_MCORE_GNU_VTINHERIT, /* type */
227 0, /* rightshift */
228 2, /* size (0 = byte, 1 = short, 2 = long) */
229 0, /* bitsize */
b34976b6 230 FALSE, /* pc_relative */
252b5132
RH
231 0, /* bitpos */
232 complain_overflow_dont, /* complain_on_overflow */
233 NULL, /* special_function */
234 "R_MCORE_GNU_VTINHERIT", /* name */
b34976b6 235 FALSE, /* partial_inplace */
252b5132
RH
236 0, /* src_mask */
237 0, /* dst_mask */
b34976b6 238 FALSE), /* pcrel_offset */
252b5132 239
47b0e7ad 240 /* GNU extension to record C++ vtable member usage. */
252b5132
RH
241 HOWTO (R_MCORE_GNU_VTENTRY, /* type */
242 0, /* rightshift */
243 2, /* size (0 = byte, 1 = short, 2 = long) */
244 0, /* bitsize */
b34976b6 245 FALSE, /* pc_relative */
252b5132
RH
246 0, /* bitpos */
247 complain_overflow_dont,/* complain_on_overflow */
248 _bfd_elf_rel_vtable_reloc_fn, /* special_function */
249 "R_MCORE_GNU_VTENTRY", /* name */
b34976b6 250 FALSE, /* partial_inplace */
252b5132
RH
251 0, /* src_mask */
252 0, /* dst_mask */
b34976b6 253 FALSE), /* pcrel_offset */
c3668558 254
36797d47
NC
255 HOWTO (R_MCORE_RELATIVE, /* type */
256 0, /* rightshift */
257 2, /* size (0 = byte, 1 = short, 2 = long) */
258 32, /* bitsize */
b34976b6 259 FALSE, /* pc_relative */
36797d47
NC
260 0, /* bitpos */
261 complain_overflow_signed, /* complain_on_overflow */
262 NULL, /* special_function */
263 "R_MCORE_RELATIVE", /* name */
b34976b6 264 TRUE, /* partial_inplace */
36797d47
NC
265 0xffffffff, /* src_mask */
266 0xffffffff, /* dst_mask */
b34976b6 267 FALSE) /* pcrel_offset */
252b5132
RH
268};
269
270#ifndef NUM_ELEM
271#define NUM_ELEM(a) (sizeof (a) / sizeof (a)[0])
272#endif
273\f
274/* Initialize the mcore_elf_howto_table, so that linear accesses can be done. */
275static void
47b0e7ad 276mcore_elf_howto_init (void)
252b5132
RH
277{
278 unsigned int i;
279
280 for (i = NUM_ELEM (mcore_elf_howto_raw); i--;)
281 {
282 unsigned int type;
c3668558 283
252b5132 284 type = mcore_elf_howto_raw[i].type;
c3668558 285
252b5132 286 BFD_ASSERT (type < NUM_ELEM (mcore_elf_howto_table));
c3668558 287
252b5132
RH
288 mcore_elf_howto_table [type] = & mcore_elf_howto_raw [i];
289 }
290}
252b5132
RH
291\f
292static reloc_howto_type *
47b0e7ad
NC
293mcore_elf_reloc_type_lookup (bfd * abfd ATTRIBUTE_UNUSED,
294 bfd_reloc_code_real_type code)
252b5132
RH
295{
296 enum elf_mcore_reloc_type mcore_reloc = R_MCORE_NONE;
297
298 switch (code)
299 {
300 case BFD_RELOC_NONE: mcore_reloc = R_MCORE_NONE; break;
301 case BFD_RELOC_32: mcore_reloc = R_MCORE_ADDR32; break;
302 case BFD_RELOC_MCORE_PCREL_IMM8BY4: mcore_reloc = R_MCORE_PCRELIMM8BY4; break;
303 case BFD_RELOC_MCORE_PCREL_IMM11BY2: mcore_reloc = R_MCORE_PCRELIMM11BY2; break;
304 case BFD_RELOC_MCORE_PCREL_IMM4BY2: mcore_reloc = R_MCORE_PCRELIMM4BY2; break;
305 case BFD_RELOC_32_PCREL: mcore_reloc = R_MCORE_PCREL32; break;
306 case BFD_RELOC_MCORE_PCREL_JSR_IMM11BY2: mcore_reloc = R_MCORE_PCRELJSR_IMM11BY2; break;
307 case BFD_RELOC_VTABLE_INHERIT: mcore_reloc = R_MCORE_GNU_VTINHERIT; break;
308 case BFD_RELOC_VTABLE_ENTRY: mcore_reloc = R_MCORE_GNU_VTENTRY; break;
36797d47 309 case BFD_RELOC_RVA: mcore_reloc = R_MCORE_RELATIVE; break;
252b5132 310 default:
47b0e7ad 311 return NULL;
252b5132
RH
312 }
313
47b0e7ad
NC
314 if (! mcore_elf_howto_table [R_MCORE_PCRELIMM8BY4])
315 /* Initialize howto table if needed. */
252b5132
RH
316 mcore_elf_howto_init ();
317
318 return mcore_elf_howto_table [(int) mcore_reloc];
319};
320
157090f7
AM
321static reloc_howto_type *
322mcore_elf_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
323 const char *r_name)
324{
325 unsigned int i;
326
327 for (i = 0;
328 i < sizeof (mcore_elf_howto_raw) / sizeof (mcore_elf_howto_raw[0]);
329 i++)
330 if (mcore_elf_howto_raw[i].name != NULL
331 && strcasecmp (mcore_elf_howto_raw[i].name, r_name) == 0)
332 return &mcore_elf_howto_raw[i];
333
334 return NULL;
335}
336
252b5132 337/* Set the howto pointer for a RCE ELF reloc. */
47b0e7ad 338
252b5132 339static void
47b0e7ad
NC
340mcore_elf_info_to_howto (bfd * abfd ATTRIBUTE_UNUSED,
341 arelent * cache_ptr,
342 Elf_Internal_Rela * dst)
252b5132 343{
47b0e7ad
NC
344 if (! mcore_elf_howto_table [R_MCORE_PCRELIMM8BY4])
345 /* Initialize howto table if needed. */
252b5132
RH
346 mcore_elf_howto_init ();
347
348 BFD_ASSERT (ELF32_R_TYPE (dst->r_info) < (unsigned int) R_MCORE_max);
c3668558 349
252b5132
RH
350 cache_ptr->howto = mcore_elf_howto_table [ELF32_R_TYPE (dst->r_info)];
351}
252b5132
RH
352\f
353/* The RELOCATE_SECTION function is called by the ELF backend linker
354 to handle the relocations for a section.
355
356 The relocs are always passed as Rela structures; if the section
357 actually uses Rel structures, the r_addend field will always be
358 zero.
359
360 This function is responsible for adjust the section contents as
361 necessary, and (if using Rela relocs and generating a
1049f94e 362 relocatable output file) adjusting the reloc addend as
252b5132
RH
363 necessary.
364
365 This function does not have to worry about setting the reloc
366 address or the reloc symbol index.
367
368 LOCAL_SYMS is a pointer to the swapped in local symbols.
369
370 LOCAL_SECTIONS is an array giving the section in the input file
371 corresponding to the st_shndx field of each local symbol.
372
373 The global hash table entry for the global symbols can be found
374 via elf_sym_hashes (input_bfd).
375
1049f94e 376 When generating relocatable output, this function must handle
252b5132
RH
377 STB_LOCAL/STT_SECTION symbols specially. The output symbol is
378 going to be the section symbol corresponding to the output
379 section, which means that the addend must be adjusted
380 accordingly. */
381
b34976b6 382static bfd_boolean
47b0e7ad
NC
383mcore_elf_relocate_section (bfd * output_bfd,
384 struct bfd_link_info * info,
385 bfd * input_bfd,
386 asection * input_section,
387 bfd_byte * contents,
388 Elf_Internal_Rela * relocs,
389 Elf_Internal_Sym * local_syms,
390 asection ** local_sections)
252b5132 391{
b34976b6 392 Elf_Internal_Shdr * symtab_hdr = & elf_tdata (input_bfd)->symtab_hdr;
252b5132 393 struct elf_link_hash_entry ** sym_hashes = elf_sym_hashes (input_bfd);
b34976b6
AM
394 Elf_Internal_Rela * rel = relocs;
395 Elf_Internal_Rela * relend = relocs + input_section->reloc_count;
396 bfd_boolean ret = TRUE;
252b5132
RH
397
398#ifdef DEBUG
d003868e
AM
399 _bfd_error_handler
400 ("mcore_elf_relocate_section called for %B section %A, %ld relocations%s",
401 input_bfd,
402 input_section,
403 (long) input_section->reloc_count,
404 (info->relocatable) ? " (relocatable)" : "");
252b5132
RH
405#endif
406
407 if (! mcore_elf_howto_table [R_MCORE_PCRELIMM8BY4]) /* Initialize howto table if needed */
408 mcore_elf_howto_init ();
409
410 for (; rel < relend; rel++)
411 {
412 enum elf_mcore_reloc_type r_type = (enum elf_mcore_reloc_type) ELF32_R_TYPE (rel->r_info);
413 bfd_vma offset = rel->r_offset;
414 bfd_vma addend = rel->r_addend;
415 bfd_reloc_status_type r = bfd_reloc_other;
47b0e7ad 416 asection * sec = NULL;
252b5132
RH
417 reloc_howto_type * howto;
418 bfd_vma relocation;
47b0e7ad 419 Elf_Internal_Sym * sym = NULL;
252b5132 420 unsigned long r_symndx;
47b0e7ad 421 struct elf_link_hash_entry * h = NULL;
86033394 422 unsigned short oldinst = 0;
c3668558 423
47b0e7ad 424 /* Unknown relocation handling. */
252b5132
RH
425 if ((unsigned) r_type >= (unsigned) R_MCORE_max
426 || ! mcore_elf_howto_table [(int)r_type])
427 {
d003868e
AM
428 _bfd_error_handler (_("%B: Unknown relocation type %d\n"),
429 input_bfd, (int) r_type);
252b5132
RH
430
431 bfd_set_error (bfd_error_bad_value);
b34976b6 432 ret = FALSE;
252b5132
RH
433 continue;
434 }
c3668558 435
252b5132
RH
436 howto = mcore_elf_howto_table [(int) r_type];
437 r_symndx = ELF32_R_SYM (rel->r_info);
c3668558 438
a022216b 439 /* Complain about known relocation that are not yet supported. */
252b5132
RH
440 if (howto->special_function == mcore_elf_unsupported_reloc)
441 {
d003868e
AM
442 _bfd_error_handler (_("%B: Relocation %s (%d) is not currently supported.\n"),
443 input_bfd,
252b5132
RH
444 howto->name,
445 (int)r_type);
446
447 bfd_set_error (bfd_error_bad_value);
b34976b6 448 ret = FALSE;
252b5132
RH
449 continue;
450 }
451
452 if (r_symndx < symtab_hdr->sh_info)
453 {
454 sym = local_syms + r_symndx;
455 sec = local_sections [r_symndx];
8517fae7 456 relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel);
f8df10f4 457 addend = rel->r_addend;
252b5132
RH
458 }
459 else
460 {
59c2e50f
L
461 bfd_boolean unresolved_reloc, warned;
462
b2a8e766
AM
463 RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
464 r_symndx, symtab_hdr, sym_hashes,
465 h, sec, relocation,
466 unresolved_reloc, warned);
252b5132
RH
467 }
468
ab96bf03
AM
469 if (sec != NULL && elf_discarded_section (sec))
470 {
471 /* For relocs against symbols from removed linkonce sections,
472 or sections discarded by a linker script, we just want the
473 section contents zeroed. Avoid any special processing. */
474 _bfd_clear_contents (howto, input_bfd, contents + rel->r_offset);
475 rel->r_info = 0;
476 rel->r_addend = 0;
477 continue;
478 }
479
480 if (info->relocatable)
481 continue;
482
252b5132
RH
483 switch (r_type)
484 {
485 default:
252b5132
RH
486 break;
487
488 case R_MCORE_PCRELJSR_IMM11BY2:
489 oldinst = bfd_get_16 (input_bfd, contents + offset);
490#define MCORE_INST_BSR 0xF800
dc810e39 491 bfd_put_16 (input_bfd, (bfd_vma) MCORE_INST_BSR, contents + offset);
252b5132
RH
492 break;
493 }
494
252b5132
RH
495#ifdef DEBUG
496 fprintf (stderr, "\ttype = %s (%d), symbol index = %ld, offset = %ld, addend = %ld\n",
497 howto->name, r_type, r_symndx, (long) offset, (long) addend);
498#endif
499
500 r = _bfd_final_link_relocate
501 (howto, input_bfd, input_section, contents, offset, relocation, addend);
502
503 if (r != bfd_reloc_ok && r_type == R_MCORE_PCRELJSR_IMM11BY2)
504 {
505 /* Wasn't ok, back it out and give up. */
dc810e39 506 bfd_put_16 (input_bfd, (bfd_vma) oldinst, contents + offset);
252b5132
RH
507 r = bfd_reloc_ok;
508 }
c3668558 509
252b5132
RH
510 if (r != bfd_reloc_ok)
511 {
b34976b6 512 ret = FALSE;
c3668558 513
252b5132
RH
514 switch (r)
515 {
516 default:
517 break;
518
519 case bfd_reloc_overflow:
520 {
521 const char * name;
522
523 if (h != NULL)
dfeffb9f 524 name = NULL;
252b5132
RH
525 else
526 {
527 name = bfd_elf_string_from_elf_section
528 (input_bfd, symtab_hdr->sh_link, sym->st_name);
c3668558 529
252b5132
RH
530 if (name == NULL)
531 break;
532
533 if (* name == '\0')
534 name = bfd_section_name (input_bfd, sec);
535 }
536
537 (*info->callbacks->reloc_overflow)
dfeffb9f
L
538 (info, (h ? &h->root : NULL), name, howto->name,
539 (bfd_vma) 0, input_bfd, input_section, offset);
252b5132
RH
540 }
541 break;
542 }
543 }
544 }
545
546#ifdef DEBUG
547 fprintf (stderr, "\n");
548#endif
549
550 return ret;
551}
552\f
553/* Return the section that should be marked against GC for a given
554 relocation. */
555
556static asection *
07adf181
AM
557mcore_elf_gc_mark_hook (asection *sec,
558 struct bfd_link_info *info,
559 Elf_Internal_Rela *rel,
560 struct elf_link_hash_entry *h,
561 Elf_Internal_Sym *sym)
252b5132 562{
07adf181
AM
563 if (h != NULL)
564 switch (ELF32_R_TYPE (rel->r_info))
565 {
566 case R_MCORE_GNU_VTINHERIT:
567 case R_MCORE_GNU_VTENTRY:
568 return NULL;
569 }
570
571 return _bfd_elf_gc_mark_hook (sec, info, rel, h, sym);
252b5132
RH
572}
573
574/* Update the got entry reference counts for the section being removed. */
575
b34976b6 576static bfd_boolean
47b0e7ad
NC
577mcore_elf_gc_sweep_hook (bfd * abfd ATTRIBUTE_UNUSED,
578 struct bfd_link_info * info ATTRIBUTE_UNUSED,
579 asection * sec ATTRIBUTE_UNUSED,
580 const Elf_Internal_Rela * relocs ATTRIBUTE_UNUSED)
252b5132 581{
b34976b6 582 return TRUE;
252b5132
RH
583}
584
585/* Look through the relocs for a section during the first phase.
586 Since we don't do .gots or .plts, we just need to consider the
587 virtual table relocs for gc. */
c3668558 588
b34976b6 589static bfd_boolean
47b0e7ad
NC
590mcore_elf_check_relocs (bfd * abfd,
591 struct bfd_link_info * info,
592 asection * sec,
593 const Elf_Internal_Rela * relocs)
252b5132 594{
b34976b6 595 Elf_Internal_Shdr * symtab_hdr;
252b5132 596 struct elf_link_hash_entry ** sym_hashes;
b34976b6
AM
597 const Elf_Internal_Rela * rel;
598 const Elf_Internal_Rela * rel_end;
c3668558 599
1049f94e 600 if (info->relocatable)
b34976b6 601 return TRUE;
c3668558 602
252b5132
RH
603 symtab_hdr = & elf_tdata (abfd)->symtab_hdr;
604 sym_hashes = elf_sym_hashes (abfd);
c3668558 605
252b5132 606 rel_end = relocs + sec->reloc_count;
c3668558 607
252b5132
RH
608 for (rel = relocs; rel < rel_end; rel++)
609 {
610 struct elf_link_hash_entry * h;
611 unsigned long r_symndx;
c3668558 612
252b5132 613 r_symndx = ELF32_R_SYM (rel->r_info);
c3668558 614
252b5132
RH
615 if (r_symndx < symtab_hdr->sh_info)
616 h = NULL;
617 else
973a3492
L
618 {
619 h = sym_hashes [r_symndx - symtab_hdr->sh_info];
620 while (h->root.type == bfd_link_hash_indirect
621 || h->root.type == bfd_link_hash_warning)
622 h = (struct elf_link_hash_entry *) h->root.u.i.link;
623 }
c3668558 624
252b5132
RH
625 switch (ELF32_R_TYPE (rel->r_info))
626 {
627 /* This relocation describes the C++ object vtable hierarchy.
628 Reconstruct it for later use during GC. */
629 case R_MCORE_GNU_VTINHERIT:
c152c796 630 if (!bfd_elf_gc_record_vtinherit (abfd, sec, h, rel->r_offset))
b34976b6 631 return FALSE;
252b5132 632 break;
c3668558 633
252b5132
RH
634 /* This relocation describes which C++ vtable entries are actually
635 used. Record for later use during GC. */
636 case R_MCORE_GNU_VTENTRY:
d17e0c6e
JB
637 BFD_ASSERT (h != NULL);
638 if (h != NULL
639 && !bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend))
b34976b6 640 return FALSE;
252b5132
RH
641 break;
642 }
643 }
c3668558 644
b34976b6 645 return TRUE;
252b5132
RH
646}
647
b35d266b 648static const struct bfd_elf_special_section mcore_elf_special_sections[]=
2f89ff8d 649{
0112cd26
NC
650 { STRING_COMMA_LEN (".ctors"), -2, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE },
651 { STRING_COMMA_LEN (".dtors"), -2, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE },
652 { NULL, 0, 0, 0, 0 }
2f89ff8d
L
653};
654
252b5132
RH
655#define TARGET_BIG_SYM bfd_elf32_mcore_big_vec
656#define TARGET_BIG_NAME "elf32-mcore-big"
657#define TARGET_LITTLE_SYM bfd_elf32_mcore_little_vec
658#define TARGET_LITTLE_NAME "elf32-mcore-little"
659
660#define ELF_ARCH bfd_arch_mcore
661#define ELF_MACHINE_CODE EM_MCORE
662#define ELF_MAXPAGESIZE 0x1000 /* 4k, if we ever have 'em */
663#define elf_info_to_howto mcore_elf_info_to_howto
664#define elf_info_to_howto_rel NULL
665
252b5132
RH
666#define bfd_elf32_bfd_merge_private_bfd_data mcore_elf_merge_private_bfd_data
667#define bfd_elf32_bfd_set_private_flags mcore_elf_set_private_flags
668#define bfd_elf32_bfd_reloc_type_lookup mcore_elf_reloc_type_lookup
157090f7 669#define bfd_elf32_bfd_reloc_name_lookup mcore_elf_reloc_name_lookup
252b5132
RH
670#define elf_backend_relocate_section mcore_elf_relocate_section
671#define elf_backend_gc_mark_hook mcore_elf_gc_mark_hook
672#define elf_backend_gc_sweep_hook mcore_elf_gc_sweep_hook
673#define elf_backend_check_relocs mcore_elf_check_relocs
29ef7005 674#define elf_backend_special_sections mcore_elf_special_sections
252b5132
RH
675
676#define elf_backend_can_gc_sections 1
b491616a 677#define elf_backend_rela_normal 1
252b5132
RH
678
679#include "elf32-target.h"
This page took 0.885589 seconds and 4 git commands to generate.