]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blob - bfd/elf32-mcore.c
19990502 sourceware import
[thirdparty/binutils-gdb.git] / bfd / elf32-mcore.c
1 /* Motorolla MCore specific support for 32-bit ELF
2 Copyright 1994, 1995, 1999 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 /* This file is based on a preliminary RCE ELF ABI. The
21 information may not match the final RCE ELF ABI. */
22
23 #include "bfd.h"
24 #include "sysdep.h"
25 #include "bfdlink.h"
26 #include "libbfd.h"
27 #include "elf-bfd.h"
28 #include "elf/mcore.h"
29 #include <assert.h>
30
31 #define USE_RELA /* Only USE_REL is actually significant, but this is
32 here are a reminder... */
33
34 static void mcore_elf_howto_init
35 PARAMS ((void));
36 static reloc_howto_type * mcore_elf_reloc_type_lookup
37 PARAMS ((bfd *, bfd_reloc_code_real_type));
38 static void mcore_elf_info_to_howto
39 PARAMS ((bfd *, arelent *, Elf32_Internal_Rela *));
40 static boolean mcore_elf_set_private_flags
41 PARAMS ((bfd *, flagword));
42 static boolean mcore_elf_copy_private_bfd_data
43 PARAMS ((bfd *, bfd *));
44 static boolean mcore_elf_merge_private_bfd_data
45 PARAMS ((bfd *, bfd *));
46 static bfd_reloc_status_type mcore_elf_unsupported_reloc
47 PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
48 static boolean mcore_elf_relocate_section
49 PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *,
50 Elf_Internal_Rela *, Elf_Internal_Sym *, asection **));
51
52 static reloc_howto_type * mcore_elf_howto_table [(int) R_MCORE_max];
53
54 static reloc_howto_type mcore_elf_howto_raw[] =
55 {
56 /* This reloc does nothing. */
57 HOWTO (R_MCORE_NONE, /* type */
58 0, /* rightshift */
59 2, /* size (0 = byte, 1 = short, 2 = long) */
60 1, /* bitsize */
61 true, /* pc_relative */
62 0, /* bitpos */
63 complain_overflow_bitfield, /* complain_on_overflow */
64 mcore_elf_unsupported_reloc, /* special_function */
65 "R_MCORE_NONE", /* name */
66 false, /* partial_inplace */
67 0, /* src_mask */
68 0, /* dst_mask */
69 true), /* pcrel_offset */
70
71 /* A standard 32 bit relocation. */
72 HOWTO (R_MCORE_ADDR32, /* type */
73 0, /* rightshift */
74 2, /* size (0 = byte, 1 = short, 2 = long) */
75 32, /* bitsize */
76 false, /* pc_relative */
77 0, /* bitpos */
78 complain_overflow_bitfield, /* complain_on_overflow */
79 bfd_elf_generic_reloc, /* special_function */
80 "ADDR32", /* name *//* For compatability with coff/pe port. */
81 false, /* partial_inplace */
82 0x0, /* src_mask */
83 0xffffffff, /* dst_mask */
84 false), /* pcrel_offset */
85
86 /* 8 bits + 2 zero bits; jmpi/jsri/lrw instructions.
87 Should not appear in object files. */
88 HOWTO (R_MCORE_PCRELIMM8BY4, /* type */
89 2, /* rightshift */
90 1, /* size (0 = byte, 1 = short, 2 = long) */
91 8, /* bitsize */
92 true, /* pc_relative */
93 0, /* bitpos */
94 complain_overflow_bitfield, /* complain_on_overflow */
95 mcore_elf_unsupported_reloc, /* special_function */
96 "R_MCORE_PCRELIMM8BY4",/* name */
97 false, /* partial_inplace */
98 0, /* src_mask */
99 0, /* dst_mask */
100 true), /* pcrel_offset */
101
102 /* bsr/bt/bf/br instructions; 11 bits + 1 zero bit
103 Span 2k instructions == 4k bytes.
104 Only useful pieces at the relocated address are the opcode (5 bits) */
105 HOWTO (R_MCORE_PCRELIMM11BY2,/* type */
106 1, /* rightshift */
107 1, /* size (0 = byte, 1 = short, 2 = long) */
108 11, /* bitsize */
109 true, /* pc_relative */
110 0, /* bitpos */
111 complain_overflow_signed, /* complain_on_overflow */
112 bfd_elf_generic_reloc, /* special_function */
113 "R_MCORE_PCRELIMM11BY2",/* name */
114 false, /* partial_inplace */
115 0x0, /* src_mask */
116 0x7ff, /* dst_mask */
117 true), /* pcrel_offset */
118
119 /* 4 bits + 1 zero bit; 'loopt' instruction only; unsupported. */
120 HOWTO (R_MCORE_PCRELIMM4BY2, /* type */
121 1, /* rightshift */
122 1, /* size (0 = byte, 1 = short, 2 = long) */
123 4, /* bitsize */
124 true, /* pc_relative */
125 0, /* bitpos */
126 complain_overflow_bitfield, /* complain_on_overflow */
127 mcore_elf_unsupported_reloc,/* special_function */
128 "R_MCORE_PCRELIMM4BY2",/* name */
129 false, /* partial_inplace */
130 0, /* src_mask */
131 0, /* dst_mask */
132 true), /* pcrel_offset */
133
134 /* 32-bit pc-relative. Eventually this will help support PIC code. */
135 HOWTO (R_MCORE_PCREL32, /* type */
136 0, /* rightshift */
137 2, /* size (0 = byte, 1 = short, 2 = long) */
138 32, /* bitsize */
139 true, /* pc_relative */
140 0, /* bitpos */
141 complain_overflow_bitfield, /* complain_on_overflow */
142 bfd_elf_generic_reloc, /* special_function */
143 "R_MCORE_PCREL32", /* name */
144 false, /* partial_inplace */
145 0x0, /* src_mask */
146 0xffffffff, /* dst_mask */
147 true), /* pcrel_offset */
148
149 /* Like PCRELIMM11BY2, this relocation indicates that there is a
150 'jsri' at the specified address. There is a separate relocation
151 entry for the literal pool entry that it references, but we
152 might be able to change the jsri to a bsr if the target turns out
153 to be close enough [even though we won't reclaim the literal pool
154 entry, we'll get some runtime efficiency back]. Note that this
155 is a relocation that we are allowed to safely ignore. */
156 HOWTO (R_MCORE_PCRELJSR_IMM11BY2,/* type */
157 1, /* rightshift */
158 1, /* size (0 = byte, 1 = short, 2 = long) */
159 11, /* bitsize */
160 true, /* pc_relative */
161 0, /* bitpos */
162 complain_overflow_signed, /* complain_on_overflow */
163 bfd_elf_generic_reloc, /* special_function */
164 "R_MCORE_PCRELJSR_IMM11BY2", /* name */
165 false, /* partial_inplace */
166 0x0, /* src_mask */
167 0x7ff, /* dst_mask */
168 true), /* pcrel_offset */
169
170 /* GNU extension to record C++ vtable hierarchy */
171 HOWTO (R_MCORE_GNU_VTINHERIT, /* type */
172 0, /* rightshift */
173 2, /* size (0 = byte, 1 = short, 2 = long) */
174 0, /* bitsize */
175 false, /* pc_relative */
176 0, /* bitpos */
177 complain_overflow_dont, /* complain_on_overflow */
178 NULL, /* special_function */
179 "R_MCORE_GNU_VTINHERIT", /* name */
180 false, /* partial_inplace */
181 0, /* src_mask */
182 0, /* dst_mask */
183 false), /* pcrel_offset */
184
185 /* GNU extension to record C++ vtable member usage */
186 HOWTO (R_MCORE_GNU_VTENTRY, /* type */
187 0, /* rightshift */
188 2, /* size (0 = byte, 1 = short, 2 = long) */
189 0, /* bitsize */
190 false, /* pc_relative */
191 0, /* bitpos */
192 complain_overflow_dont,/* complain_on_overflow */
193 _bfd_elf_rel_vtable_reloc_fn, /* special_function */
194 "R_MCORE_GNU_VTENTRY", /* name */
195 false, /* partial_inplace */
196 0, /* src_mask */
197 0, /* dst_mask */
198 false), /* pcrel_offset */
199 };
200
201 #ifndef NUM_ELEM
202 #define NUM_ELEM(a) (sizeof (a) / sizeof (a)[0])
203 #endif
204 \f
205 /* Initialize the mcore_elf_howto_table, so that linear accesses can be done. */
206 static void
207 mcore_elf_howto_init ()
208 {
209 unsigned int i;
210
211 for (i = NUM_ELEM (mcore_elf_howto_raw); i--;)
212 {
213 unsigned int type;
214
215 type = mcore_elf_howto_raw[i].type;
216
217 BFD_ASSERT (type < NUM_ELEM (mcore_elf_howto_table));
218
219 mcore_elf_howto_table [type] = & mcore_elf_howto_raw [i];
220 }
221 }
222
223 \f
224 static reloc_howto_type *
225 mcore_elf_reloc_type_lookup (abfd, code)
226 bfd * abfd;
227 bfd_reloc_code_real_type code;
228 {
229 enum elf_mcore_reloc_type mcore_reloc = R_MCORE_NONE;
230
231 switch (code)
232 {
233 case BFD_RELOC_NONE: mcore_reloc = R_MCORE_NONE; break;
234 case BFD_RELOC_32: mcore_reloc = R_MCORE_ADDR32; break;
235 case BFD_RELOC_MCORE_PCREL_IMM8BY4: mcore_reloc = R_MCORE_PCRELIMM8BY4; break;
236 case BFD_RELOC_MCORE_PCREL_IMM11BY2: mcore_reloc = R_MCORE_PCRELIMM11BY2; break;
237 case BFD_RELOC_MCORE_PCREL_IMM4BY2: mcore_reloc = R_MCORE_PCRELIMM4BY2; break;
238 case BFD_RELOC_32_PCREL: mcore_reloc = R_MCORE_PCREL32; break;
239 case BFD_RELOC_MCORE_PCREL_JSR_IMM11BY2: mcore_reloc = R_MCORE_PCRELJSR_IMM11BY2; break;
240 case BFD_RELOC_VTABLE_INHERIT: mcore_reloc = R_MCORE_GNU_VTINHERIT; break;
241 case BFD_RELOC_VTABLE_ENTRY: mcore_reloc = R_MCORE_GNU_VTENTRY; break;
242 default:
243 return (reloc_howto_type *)NULL;
244 }
245
246 if (! mcore_elf_howto_table [R_MCORE_PCRELIMM8BY4]) /* Initialize howto table if needed */
247 mcore_elf_howto_init ();
248
249 return mcore_elf_howto_table [(int) mcore_reloc];
250 };
251
252 /* Set the howto pointer for a RCE ELF reloc. */
253 static void
254 mcore_elf_info_to_howto (abfd, cache_ptr, dst)
255 bfd * abfd;
256 arelent * cache_ptr;
257 Elf32_Internal_Rela * dst;
258 {
259 if (! mcore_elf_howto_table [R_MCORE_PCRELIMM8BY4]) /* Initialize howto table if needed */
260 mcore_elf_howto_init ();
261
262 BFD_ASSERT (ELF32_R_TYPE (dst->r_info) < (unsigned int) R_MCORE_max);
263
264 cache_ptr->howto = mcore_elf_howto_table [ELF32_R_TYPE (dst->r_info)];
265 }
266
267 /* Function to set whether a module needs the -mrelocatable bit set. */
268 static boolean
269 mcore_elf_set_private_flags (abfd, flags)
270 bfd * abfd;
271 flagword flags;
272 {
273 BFD_ASSERT (! elf_flags_init (abfd)
274 || elf_elfheader (abfd)->e_flags == flags);
275
276 elf_elfheader (abfd)->e_flags = flags;
277 elf_flags_init (abfd) = true;
278 return true;
279 }
280
281 /* Copy backend specific data from one object module to another. */
282 static boolean
283 mcore_elf_copy_private_bfd_data (ibfd, obfd)
284 bfd * ibfd;
285 bfd * obfd;
286 {
287 if ( bfd_get_flavour (ibfd) != bfd_target_elf_flavour
288 || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
289 return true;
290
291 BFD_ASSERT (! elf_flags_init (obfd)
292 || elf_elfheader (obfd)->e_flags == elf_elfheader (ibfd)->e_flags);
293
294 elf_elfheader (obfd)->e_flags = elf_elfheader (ibfd)->e_flags;
295 elf_flags_init (obfd) = true;
296 return true;
297 }
298
299 /* Merge backend specific data from an object file to the output
300 object file when linking. */
301 static boolean
302 mcore_elf_merge_private_bfd_data (ibfd, obfd)
303 bfd * ibfd;
304 bfd * obfd;
305 {
306 flagword old_flags;
307 flagword new_flags;
308 boolean error;
309
310 /* Check if we have the same endianess */
311 if ( ibfd->xvec->byteorder != obfd->xvec->byteorder
312 && obfd->xvec->byteorder != BFD_ENDIAN_UNKNOWN)
313 {
314 (*_bfd_error_handler)
315 (_("%s: compiled for a %s endian system and target is %s endian.\n"),
316 bfd_get_filename (ibfd),
317 bfd_big_endian (ibfd) ? "big" : "little",
318 bfd_big_endian (obfd) ? "big" : "little");
319
320 bfd_set_error (bfd_error_wrong_format);
321 return false;
322 }
323
324 if ( bfd_get_flavour (ibfd) != bfd_target_elf_flavour
325 || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
326 return true;
327
328 new_flags = elf_elfheader (ibfd)->e_flags;
329 old_flags = elf_elfheader (obfd)->e_flags;
330
331 if (! elf_flags_init (obfd)) /* First call, no flags set */
332 {
333 elf_flags_init (obfd) = true;
334 elf_elfheader (obfd)->e_flags = new_flags;
335 }
336 else if (new_flags == old_flags) /* Compatible flags are ok */
337 ;
338
339 return true;
340 }
341
342 \f
343 /* Don't pretend we can deal with unsupported relocs. */
344
345 /*ARGSUSED*/
346 static bfd_reloc_status_type
347 mcore_elf_unsupported_reloc (abfd, reloc_entry, symbol, data, input_section,
348 output_bfd, error_message)
349 bfd * abfd;
350 arelent * reloc_entry;
351 asymbol * symbol;
352 PTR data;
353 asection * input_section;
354 bfd * output_bfd;
355 char ** error_message;
356 {
357 BFD_ASSERT (reloc_entry->howto != (reloc_howto_type *)0);
358
359 _bfd_error_handler (_("%s: Relocation %s (%d) is not currently supported.\n"),
360 bfd_get_filename (abfd),
361 reloc_entry->howto->name,
362 reloc_entry->howto->type);
363
364 return bfd_reloc_notsupported;
365 }
366
367 \f
368 /* The RELOCATE_SECTION function is called by the ELF backend linker
369 to handle the relocations for a section.
370
371 The relocs are always passed as Rela structures; if the section
372 actually uses Rel structures, the r_addend field will always be
373 zero.
374
375 This function is responsible for adjust the section contents as
376 necessary, and (if using Rela relocs and generating a
377 relocateable output file) adjusting the reloc addend as
378 necessary.
379
380 This function does not have to worry about setting the reloc
381 address or the reloc symbol index.
382
383 LOCAL_SYMS is a pointer to the swapped in local symbols.
384
385 LOCAL_SECTIONS is an array giving the section in the input file
386 corresponding to the st_shndx field of each local symbol.
387
388 The global hash table entry for the global symbols can be found
389 via elf_sym_hashes (input_bfd).
390
391 When generating relocateable output, this function must handle
392 STB_LOCAL/STT_SECTION symbols specially. The output symbol is
393 going to be the section symbol corresponding to the output
394 section, which means that the addend must be adjusted
395 accordingly. */
396
397 static boolean
398 mcore_elf_relocate_section (output_bfd, info, input_bfd, input_section,
399 contents, relocs, local_syms, local_sections)
400 bfd * output_bfd;
401 struct bfd_link_info * info;
402 bfd * input_bfd;
403 asection * input_section;
404 bfd_byte * contents;
405 Elf_Internal_Rela * relocs;
406 Elf_Internal_Sym * local_syms;
407 asection ** local_sections;
408 {
409 Elf_Internal_Shdr * symtab_hdr = & elf_tdata (input_bfd)->symtab_hdr;
410 struct elf_link_hash_entry ** sym_hashes = elf_sym_hashes (input_bfd);
411 Elf_Internal_Rela * rel = relocs;
412 Elf_Internal_Rela * relend = relocs + input_section->reloc_count;
413 boolean ret = true;
414 long insn;
415
416 #ifdef DEBUG
417 fprintf (stderr,
418 "mcore_elf_relocate_section called for %s section %s, %ld relocations%s\n",
419 bfd_get_filename (input_bfd),
420 bfd_section_name(input_bfd, input_section),
421 (long) input_section->reloc_count,
422 (info->relocateable) ? " (relocatable)" : "");
423 #endif
424
425 if (! mcore_elf_howto_table [R_MCORE_PCRELIMM8BY4]) /* Initialize howto table if needed */
426 mcore_elf_howto_init ();
427
428 for (; rel < relend; rel++)
429 {
430 enum elf_mcore_reloc_type r_type = (enum elf_mcore_reloc_type) ELF32_R_TYPE (rel->r_info);
431 bfd_vma offset = rel->r_offset;
432 bfd_vma addend = rel->r_addend;
433 bfd_reloc_status_type r = bfd_reloc_other;
434 asection * sec = (asection *) 0;
435 reloc_howto_type * howto;
436 bfd_vma relocation;
437 Elf_Internal_Sym * sym = (Elf_Internal_Sym *) 0;
438 unsigned long r_symndx;
439 struct elf_link_hash_entry * h = (struct elf_link_hash_entry *) 0;
440 unsigned short oldinst;
441
442 /* Unknown relocation handling */
443 if ((unsigned) r_type >= (unsigned) R_MCORE_max
444 || ! mcore_elf_howto_table [(int)r_type])
445 {
446 _bfd_error_handler (_("%s: Unknown relocation type %d\n"),
447 bfd_get_filename (input_bfd),
448 (int) r_type);
449
450 bfd_set_error (bfd_error_bad_value);
451 ret = false;
452 continue;
453 }
454
455 howto = mcore_elf_howto_table [(int) r_type];
456 r_symndx = ELF32_R_SYM (rel->r_info);
457
458 if (info->relocateable)
459 {
460 /* This is a relocateable link. We don't have to change
461 anything, unless the reloc is against a section symbol,
462 in which case we have to adjust according to where the
463 section symbol winds up in the output section. */
464 if (r_symndx < symtab_hdr->sh_info)
465 {
466 sym = local_syms + r_symndx;
467
468 if ((unsigned)ELF_ST_TYPE (sym->st_info) == STT_SECTION)
469 {
470 sec = local_sections[r_symndx];
471 addend = rel->r_addend += sec->output_offset + sym->st_value;
472 }
473 }
474
475 #ifdef DEBUG
476 fprintf (stderr, "\ttype = %s (%d), symbol index = %ld, offset = %ld, addend = %ld\n",
477 howto->name, (int) r_type, r_symndx, (long) offset, (long) addend);
478 #endif
479 continue;
480 }
481
482 /* This is a final link. */
483
484 /* Complain about known relocation that are not yet supported */
485 if (howto->special_function == mcore_elf_unsupported_reloc)
486 {
487 _bfd_error_handler (_("%s: Relocation %s (%d) is not currently supported.\n"),
488 bfd_get_filename (input_bfd),
489 howto->name,
490 (int)r_type);
491
492 bfd_set_error (bfd_error_bad_value);
493 ret = false;
494 continue;
495 }
496
497 if (r_symndx < symtab_hdr->sh_info)
498 {
499 sym = local_syms + r_symndx;
500 sec = local_sections [r_symndx];
501 relocation = (sec->output_section->vma
502 + sec->output_offset
503 + sym->st_value);
504 }
505 else
506 {
507 h = sym_hashes [r_symndx - symtab_hdr->sh_info];
508 if ( h->root.type == bfd_link_hash_defined
509 || h->root.type == bfd_link_hash_defweak)
510 {
511 sec = h->root.u.def.section;
512 relocation = (h->root.u.def.value
513 + sec->output_section->vma
514 + sec->output_offset);
515 }
516 else if (h->root.type == bfd_link_hash_undefweak)
517 relocation = 0;
518 else if (info->shared)
519 relocation = 0;
520 else
521 {
522 if (! ((*info->callbacks->undefined_symbol)
523 (info, h->root.root.string, input_bfd,
524 input_section, rel->r_offset)))
525 return false;
526
527 ret = false;
528 continue;
529 }
530 }
531
532 switch (r_type)
533 {
534 default:
535 case R_MCORE_PCRELIMM8BY4:
536 case R_MCORE_PCRELIMM11BY2:
537 case R_MCORE_PCRELIMM4BY2:
538 break;
539
540 case R_MCORE_PCRELJSR_IMM11BY2:
541 oldinst = bfd_get_16 (input_bfd, contents + offset);
542 #define MCORE_INST_BSR 0xF800
543 bfd_put_16 (input_bfd, MCORE_INST_BSR, contents + offset);
544 break;
545 }
546
547
548 #ifdef DEBUG
549 fprintf (stderr, "\ttype = %s (%d), symbol index = %ld, offset = %ld, addend = %ld\n",
550 howto->name, r_type, r_symndx, (long) offset, (long) addend);
551 #endif
552
553 r = _bfd_final_link_relocate
554 (howto, input_bfd, input_section, contents, offset, relocation, addend);
555
556 if (r != bfd_reloc_ok && r_type == R_MCORE_PCRELJSR_IMM11BY2)
557 {
558 /* Wasn't ok, back it out and give up. */
559 bfd_put_16 (input_bfd, oldinst, contents + offset);
560 r = bfd_reloc_ok;
561 }
562
563 if (r != bfd_reloc_ok)
564 {
565 ret = false;
566
567 switch (r)
568 {
569 default:
570 break;
571
572 case bfd_reloc_overflow:
573 {
574 const char * name;
575
576 if (h != NULL)
577 name = h->root.root.string;
578 else
579 {
580 name = bfd_elf_string_from_elf_section
581 (input_bfd, symtab_hdr->sh_link, sym->st_name);
582
583 if (name == NULL)
584 break;
585
586 if (* name == '\0')
587 name = bfd_section_name (input_bfd, sec);
588 }
589
590 (*info->callbacks->reloc_overflow)
591 (info, name, howto->name, (bfd_vma) 0, input_bfd, input_section,
592 offset);
593 }
594 break;
595 }
596 }
597 }
598
599 #ifdef DEBUG
600 fprintf (stderr, "\n");
601 #endif
602
603 return ret;
604 }
605 \f
606 /* Return the section that should be marked against GC for a given
607 relocation. */
608
609 static asection *
610 mcore_elf_gc_mark_hook (abfd, info, rel, h, sym)
611 bfd * abfd;
612 struct bfd_link_info * info;
613 Elf_Internal_Rela * rel;
614 struct elf_link_hash_entry * h;
615 Elf_Internal_Sym * sym;
616 {
617 if (h != NULL)
618 {
619 switch (ELF32_R_TYPE (rel->r_info))
620 {
621 case R_MCORE_GNU_VTINHERIT:
622 case R_MCORE_GNU_VTENTRY:
623 break;
624
625 default:
626 switch (h->root.type)
627 {
628 case bfd_link_hash_defined:
629 case bfd_link_hash_defweak:
630 return h->root.u.def.section;
631
632 case bfd_link_hash_common:
633 return h->root.u.c.p->section;
634 }
635 }
636 }
637 else
638 {
639 if (!(elf_bad_symtab (abfd)
640 && ELF_ST_BIND (sym->st_info) != STB_LOCAL)
641 && ! ((sym->st_shndx <= 0 || sym->st_shndx >= SHN_LORESERVE)
642 && sym->st_shndx != SHN_COMMON))
643 {
644 return bfd_section_from_elf_index (abfd, sym->st_shndx);
645 }
646 }
647
648 return NULL;
649 }
650
651 /* Update the got entry reference counts for the section being removed. */
652
653 static boolean
654 mcore_elf_gc_sweep_hook (abfd, info, sec, relocs)
655 bfd * abfd;
656 struct bfd_link_info * info;
657 asection * sec;
658 const Elf_Internal_Rela * relocs;
659 {
660 return true;
661 }
662
663 /* Look through the relocs for a section during the first phase.
664 Since we don't do .gots or .plts, we just need to consider the
665 virtual table relocs for gc. */
666
667 static boolean
668 mcore_elf_check_relocs (abfd, info, sec, relocs)
669 bfd * abfd;
670 struct bfd_link_info * info;
671 asection * sec;
672 const Elf_Internal_Rela * relocs;
673 {
674 Elf_Internal_Shdr * symtab_hdr;
675 struct elf_link_hash_entry ** sym_hashes;
676 struct elf_link_hash_entry ** sym_hashes_end;
677 const Elf_Internal_Rela * rel;
678 const Elf_Internal_Rela * rel_end;
679
680 if (info->relocateable)
681 return true;
682
683 symtab_hdr = & elf_tdata (abfd)->symtab_hdr;
684 sym_hashes = elf_sym_hashes (abfd);
685 sym_hashes_end = sym_hashes + symtab_hdr->sh_size / sizeof (Elf32_External_Sym);
686 if (!elf_bad_symtab (abfd))
687 sym_hashes_end -= symtab_hdr->sh_info;
688
689 rel_end = relocs + sec->reloc_count;
690
691 for (rel = relocs; rel < rel_end; rel++)
692 {
693 struct elf_link_hash_entry * h;
694 unsigned long r_symndx;
695
696 r_symndx = ELF32_R_SYM (rel->r_info);
697
698 if (r_symndx < symtab_hdr->sh_info)
699 h = NULL;
700 else
701 h = sym_hashes [r_symndx - symtab_hdr->sh_info];
702
703 switch (ELF32_R_TYPE (rel->r_info))
704 {
705 /* This relocation describes the C++ object vtable hierarchy.
706 Reconstruct it for later use during GC. */
707 case R_MCORE_GNU_VTINHERIT:
708 if (!_bfd_elf32_gc_record_vtinherit (abfd, sec, h, rel->r_offset))
709 return false;
710 break;
711
712 /* This relocation describes which C++ vtable entries are actually
713 used. Record for later use during GC. */
714 case R_MCORE_GNU_VTENTRY:
715 if (!_bfd_elf32_gc_record_vtentry (abfd, sec, h, rel->r_addend))
716 return false;
717 break;
718 }
719 }
720
721 return true;
722 }
723
724 #define TARGET_BIG_SYM bfd_elf32_mcore_big_vec
725 #define TARGET_BIG_NAME "elf32-mcore-big"
726 #define TARGET_LITTLE_SYM bfd_elf32_mcore_little_vec
727 #define TARGET_LITTLE_NAME "elf32-mcore-little"
728
729 #define ELF_ARCH bfd_arch_mcore
730 #define ELF_MACHINE_CODE EM_MCORE
731 #define ELF_MAXPAGESIZE 0x1000 /* 4k, if we ever have 'em */
732 #define elf_info_to_howto mcore_elf_info_to_howto
733 #define elf_info_to_howto_rel NULL
734
735
736 #define bfd_elf32_bfd_copy_private_bfd_data mcore_elf_copy_private_bfd_data
737 #define bfd_elf32_bfd_merge_private_bfd_data mcore_elf_merge_private_bfd_data
738 #define bfd_elf32_bfd_set_private_flags mcore_elf_set_private_flags
739 #define bfd_elf32_bfd_reloc_type_lookup mcore_elf_reloc_type_lookup
740 #define elf_backend_relocate_section mcore_elf_relocate_section
741 #define elf_backend_gc_mark_hook mcore_elf_gc_mark_hook
742 #define elf_backend_gc_sweep_hook mcore_elf_gc_sweep_hook
743 #define elf_backend_check_relocs mcore_elf_check_relocs
744
745 #define elf_backend_can_gc_sections 1
746
747 #include "elf32-target.h"