* section.c (SEC_SHORT): Define.
[deliverable/binutils-gdb.git] / bfd / elf32-mcore.c
CommitLineData
252b5132
RH
1/* Motorolla MCore specific support for 32-bit ELF
2 Copyright 1994, 1995, 1999 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/* 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
34static void mcore_elf_howto_init
35 PARAMS ((void));
36static reloc_howto_type * mcore_elf_reloc_type_lookup
37 PARAMS ((bfd *, bfd_reloc_code_real_type));
38static void mcore_elf_info_to_howto
39 PARAMS ((bfd *, arelent *, Elf32_Internal_Rela *));
40static boolean mcore_elf_set_private_flags
41 PARAMS ((bfd *, flagword));
42static boolean mcore_elf_copy_private_bfd_data
43 PARAMS ((bfd *, bfd *));
44static boolean mcore_elf_merge_private_bfd_data
45 PARAMS ((bfd *, bfd *));
46static bfd_reloc_status_type mcore_elf_unsupported_reloc
47 PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
48static 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
52static reloc_howto_type * mcore_elf_howto_table [(int) R_MCORE_max];
53
54static 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 */
36797d47
NC
199
200 HOWTO (R_MCORE_RELATIVE, /* type */
201 0, /* rightshift */
202 2, /* size (0 = byte, 1 = short, 2 = long) */
203 32, /* bitsize */
204 false, /* pc_relative */
205 0, /* bitpos */
206 complain_overflow_signed, /* complain_on_overflow */
207 NULL, /* special_function */
208 "R_MCORE_RELATIVE", /* name */
209 true, /* partial_inplace */
210 0xffffffff, /* src_mask */
211 0xffffffff, /* dst_mask */
212 true) /* pcrel_offset */
252b5132
RH
213};
214
215#ifndef NUM_ELEM
216#define NUM_ELEM(a) (sizeof (a) / sizeof (a)[0])
217#endif
218\f
219/* Initialize the mcore_elf_howto_table, so that linear accesses can be done. */
220static void
221mcore_elf_howto_init ()
222{
223 unsigned int i;
224
225 for (i = NUM_ELEM (mcore_elf_howto_raw); i--;)
226 {
227 unsigned int type;
228
229 type = mcore_elf_howto_raw[i].type;
230
231 BFD_ASSERT (type < NUM_ELEM (mcore_elf_howto_table));
232
233 mcore_elf_howto_table [type] = & mcore_elf_howto_raw [i];
234 }
235}
236
237\f
238static reloc_howto_type *
239mcore_elf_reloc_type_lookup (abfd, code)
240 bfd * abfd;
241 bfd_reloc_code_real_type code;
242{
243 enum elf_mcore_reloc_type mcore_reloc = R_MCORE_NONE;
244
245 switch (code)
246 {
247 case BFD_RELOC_NONE: mcore_reloc = R_MCORE_NONE; break;
248 case BFD_RELOC_32: mcore_reloc = R_MCORE_ADDR32; break;
249 case BFD_RELOC_MCORE_PCREL_IMM8BY4: mcore_reloc = R_MCORE_PCRELIMM8BY4; break;
250 case BFD_RELOC_MCORE_PCREL_IMM11BY2: mcore_reloc = R_MCORE_PCRELIMM11BY2; break;
251 case BFD_RELOC_MCORE_PCREL_IMM4BY2: mcore_reloc = R_MCORE_PCRELIMM4BY2; break;
252 case BFD_RELOC_32_PCREL: mcore_reloc = R_MCORE_PCREL32; break;
253 case BFD_RELOC_MCORE_PCREL_JSR_IMM11BY2: mcore_reloc = R_MCORE_PCRELJSR_IMM11BY2; break;
254 case BFD_RELOC_VTABLE_INHERIT: mcore_reloc = R_MCORE_GNU_VTINHERIT; break;
255 case BFD_RELOC_VTABLE_ENTRY: mcore_reloc = R_MCORE_GNU_VTENTRY; break;
36797d47 256 case BFD_RELOC_RVA: mcore_reloc = R_MCORE_RELATIVE; break;
252b5132
RH
257 default:
258 return (reloc_howto_type *)NULL;
259 }
260
261 if (! mcore_elf_howto_table [R_MCORE_PCRELIMM8BY4]) /* Initialize howto table if needed */
262 mcore_elf_howto_init ();
263
264 return mcore_elf_howto_table [(int) mcore_reloc];
265};
266
267/* Set the howto pointer for a RCE ELF reloc. */
268static void
269mcore_elf_info_to_howto (abfd, cache_ptr, dst)
270 bfd * abfd;
271 arelent * cache_ptr;
272 Elf32_Internal_Rela * dst;
273{
274 if (! mcore_elf_howto_table [R_MCORE_PCRELIMM8BY4]) /* Initialize howto table if needed */
275 mcore_elf_howto_init ();
276
277 BFD_ASSERT (ELF32_R_TYPE (dst->r_info) < (unsigned int) R_MCORE_max);
278
279 cache_ptr->howto = mcore_elf_howto_table [ELF32_R_TYPE (dst->r_info)];
280}
281
282/* Function to set whether a module needs the -mrelocatable bit set. */
283static boolean
284mcore_elf_set_private_flags (abfd, flags)
285 bfd * abfd;
286 flagword flags;
287{
288 BFD_ASSERT (! elf_flags_init (abfd)
289 || elf_elfheader (abfd)->e_flags == flags);
290
291 elf_elfheader (abfd)->e_flags = flags;
292 elf_flags_init (abfd) = true;
293 return true;
294}
295
296/* Copy backend specific data from one object module to another. */
297static boolean
298mcore_elf_copy_private_bfd_data (ibfd, obfd)
299 bfd * ibfd;
300 bfd * obfd;
301{
302 if ( bfd_get_flavour (ibfd) != bfd_target_elf_flavour
303 || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
304 return true;
305
306 BFD_ASSERT (! elf_flags_init (obfd)
307 || elf_elfheader (obfd)->e_flags == elf_elfheader (ibfd)->e_flags);
308
309 elf_elfheader (obfd)->e_flags = elf_elfheader (ibfd)->e_flags;
310 elf_flags_init (obfd) = true;
311 return true;
312}
313
314/* Merge backend specific data from an object file to the output
315 object file when linking. */
316static boolean
317mcore_elf_merge_private_bfd_data (ibfd, obfd)
318 bfd * ibfd;
319 bfd * obfd;
320{
321 flagword old_flags;
322 flagword new_flags;
323 boolean error;
324
325 /* Check if we have the same endianess */
326 if ( ibfd->xvec->byteorder != obfd->xvec->byteorder
327 && obfd->xvec->byteorder != BFD_ENDIAN_UNKNOWN)
328 {
329 (*_bfd_error_handler)
330 (_("%s: compiled for a %s endian system and target is %s endian.\n"),
331 bfd_get_filename (ibfd),
332 bfd_big_endian (ibfd) ? "big" : "little",
333 bfd_big_endian (obfd) ? "big" : "little");
334
335 bfd_set_error (bfd_error_wrong_format);
336 return false;
337 }
338
339 if ( bfd_get_flavour (ibfd) != bfd_target_elf_flavour
340 || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
341 return true;
342
343 new_flags = elf_elfheader (ibfd)->e_flags;
344 old_flags = elf_elfheader (obfd)->e_flags;
345
346 if (! elf_flags_init (obfd)) /* First call, no flags set */
347 {
348 elf_flags_init (obfd) = true;
349 elf_elfheader (obfd)->e_flags = new_flags;
350 }
351 else if (new_flags == old_flags) /* Compatible flags are ok */
352 ;
353
354 return true;
355}
356
357\f
358/* Don't pretend we can deal with unsupported relocs. */
359
360/*ARGSUSED*/
361static bfd_reloc_status_type
362mcore_elf_unsupported_reloc (abfd, reloc_entry, symbol, data, input_section,
363 output_bfd, error_message)
364 bfd * abfd;
365 arelent * reloc_entry;
366 asymbol * symbol;
367 PTR data;
368 asection * input_section;
369 bfd * output_bfd;
370 char ** error_message;
371{
372 BFD_ASSERT (reloc_entry->howto != (reloc_howto_type *)0);
373
374 _bfd_error_handler (_("%s: Relocation %s (%d) is not currently supported.\n"),
375 bfd_get_filename (abfd),
376 reloc_entry->howto->name,
377 reloc_entry->howto->type);
378
379 return bfd_reloc_notsupported;
380}
381
382\f
383/* The RELOCATE_SECTION function is called by the ELF backend linker
384 to handle the relocations for a section.
385
386 The relocs are always passed as Rela structures; if the section
387 actually uses Rel structures, the r_addend field will always be
388 zero.
389
390 This function is responsible for adjust the section contents as
391 necessary, and (if using Rela relocs and generating a
392 relocateable output file) adjusting the reloc addend as
393 necessary.
394
395 This function does not have to worry about setting the reloc
396 address or the reloc symbol index.
397
398 LOCAL_SYMS is a pointer to the swapped in local symbols.
399
400 LOCAL_SECTIONS is an array giving the section in the input file
401 corresponding to the st_shndx field of each local symbol.
402
403 The global hash table entry for the global symbols can be found
404 via elf_sym_hashes (input_bfd).
405
406 When generating relocateable output, this function must handle
407 STB_LOCAL/STT_SECTION symbols specially. The output symbol is
408 going to be the section symbol corresponding to the output
409 section, which means that the addend must be adjusted
410 accordingly. */
411
412static boolean
413mcore_elf_relocate_section (output_bfd, info, input_bfd, input_section,
414 contents, relocs, local_syms, local_sections)
415 bfd * output_bfd;
416 struct bfd_link_info * info;
417 bfd * input_bfd;
418 asection * input_section;
419 bfd_byte * contents;
420 Elf_Internal_Rela * relocs;
421 Elf_Internal_Sym * local_syms;
422 asection ** local_sections;
423{
424 Elf_Internal_Shdr * symtab_hdr = & elf_tdata (input_bfd)->symtab_hdr;
425 struct elf_link_hash_entry ** sym_hashes = elf_sym_hashes (input_bfd);
426 Elf_Internal_Rela * rel = relocs;
427 Elf_Internal_Rela * relend = relocs + input_section->reloc_count;
428 boolean ret = true;
429 long insn;
430
431#ifdef DEBUG
432 fprintf (stderr,
433 "mcore_elf_relocate_section called for %s section %s, %ld relocations%s\n",
434 bfd_get_filename (input_bfd),
435 bfd_section_name(input_bfd, input_section),
436 (long) input_section->reloc_count,
437 (info->relocateable) ? " (relocatable)" : "");
438#endif
439
440 if (! mcore_elf_howto_table [R_MCORE_PCRELIMM8BY4]) /* Initialize howto table if needed */
441 mcore_elf_howto_init ();
442
443 for (; rel < relend; rel++)
444 {
445 enum elf_mcore_reloc_type r_type = (enum elf_mcore_reloc_type) ELF32_R_TYPE (rel->r_info);
446 bfd_vma offset = rel->r_offset;
447 bfd_vma addend = rel->r_addend;
448 bfd_reloc_status_type r = bfd_reloc_other;
449 asection * sec = (asection *) 0;
450 reloc_howto_type * howto;
451 bfd_vma relocation;
452 Elf_Internal_Sym * sym = (Elf_Internal_Sym *) 0;
453 unsigned long r_symndx;
454 struct elf_link_hash_entry * h = (struct elf_link_hash_entry *) 0;
455 unsigned short oldinst;
456
457 /* Unknown relocation handling */
458 if ((unsigned) r_type >= (unsigned) R_MCORE_max
459 || ! mcore_elf_howto_table [(int)r_type])
460 {
461 _bfd_error_handler (_("%s: Unknown relocation type %d\n"),
462 bfd_get_filename (input_bfd),
463 (int) r_type);
464
465 bfd_set_error (bfd_error_bad_value);
466 ret = false;
467 continue;
468 }
469
470 howto = mcore_elf_howto_table [(int) r_type];
471 r_symndx = ELF32_R_SYM (rel->r_info);
472
473 if (info->relocateable)
474 {
475 /* This is a relocateable link. We don't have to change
476 anything, unless the reloc is against a section symbol,
477 in which case we have to adjust according to where the
478 section symbol winds up in the output section. */
479 if (r_symndx < symtab_hdr->sh_info)
480 {
481 sym = local_syms + r_symndx;
482
483 if ((unsigned)ELF_ST_TYPE (sym->st_info) == STT_SECTION)
484 {
485 sec = local_sections[r_symndx];
486 addend = rel->r_addend += sec->output_offset + sym->st_value;
487 }
488 }
489
490#ifdef DEBUG
491 fprintf (stderr, "\ttype = %s (%d), symbol index = %ld, offset = %ld, addend = %ld\n",
492 howto->name, (int) r_type, r_symndx, (long) offset, (long) addend);
493#endif
494 continue;
495 }
496
497 /* This is a final link. */
498
499 /* Complain about known relocation that are not yet supported */
500 if (howto->special_function == mcore_elf_unsupported_reloc)
501 {
502 _bfd_error_handler (_("%s: Relocation %s (%d) is not currently supported.\n"),
503 bfd_get_filename (input_bfd),
504 howto->name,
505 (int)r_type);
506
507 bfd_set_error (bfd_error_bad_value);
508 ret = false;
509 continue;
510 }
511
512 if (r_symndx < symtab_hdr->sh_info)
513 {
514 sym = local_syms + r_symndx;
515 sec = local_sections [r_symndx];
516 relocation = (sec->output_section->vma
517 + sec->output_offset
518 + sym->st_value);
519 }
520 else
521 {
522 h = sym_hashes [r_symndx - symtab_hdr->sh_info];
523 if ( h->root.type == bfd_link_hash_defined
524 || h->root.type == bfd_link_hash_defweak)
525 {
526 sec = h->root.u.def.section;
527 relocation = (h->root.u.def.value
528 + sec->output_section->vma
529 + sec->output_offset);
530 }
531 else if (h->root.type == bfd_link_hash_undefweak)
532 relocation = 0;
533 else if (info->shared)
534 relocation = 0;
535 else
536 {
537 if (! ((*info->callbacks->undefined_symbol)
538 (info, h->root.root.string, input_bfd,
539 input_section, rel->r_offset)))
540 return false;
541
542 ret = false;
543 continue;
544 }
545 }
546
547 switch (r_type)
548 {
549 default:
252b5132
RH
550 break;
551
552 case R_MCORE_PCRELJSR_IMM11BY2:
553 oldinst = bfd_get_16 (input_bfd, contents + offset);
554#define MCORE_INST_BSR 0xF800
555 bfd_put_16 (input_bfd, MCORE_INST_BSR, contents + offset);
556 break;
557 }
558
559
560#ifdef DEBUG
561 fprintf (stderr, "\ttype = %s (%d), symbol index = %ld, offset = %ld, addend = %ld\n",
562 howto->name, r_type, r_symndx, (long) offset, (long) addend);
563#endif
564
565 r = _bfd_final_link_relocate
566 (howto, input_bfd, input_section, contents, offset, relocation, addend);
567
568 if (r != bfd_reloc_ok && r_type == R_MCORE_PCRELJSR_IMM11BY2)
569 {
570 /* Wasn't ok, back it out and give up. */
571 bfd_put_16 (input_bfd, oldinst, contents + offset);
572 r = bfd_reloc_ok;
573 }
574
575 if (r != bfd_reloc_ok)
576 {
577 ret = false;
578
579 switch (r)
580 {
581 default:
582 break;
583
584 case bfd_reloc_overflow:
585 {
586 const char * name;
587
588 if (h != NULL)
589 name = h->root.root.string;
590 else
591 {
592 name = bfd_elf_string_from_elf_section
593 (input_bfd, symtab_hdr->sh_link, sym->st_name);
594
595 if (name == NULL)
596 break;
597
598 if (* name == '\0')
599 name = bfd_section_name (input_bfd, sec);
600 }
601
602 (*info->callbacks->reloc_overflow)
603 (info, name, howto->name, (bfd_vma) 0, input_bfd, input_section,
604 offset);
605 }
606 break;
607 }
608 }
609 }
610
611#ifdef DEBUG
612 fprintf (stderr, "\n");
613#endif
614
615 return ret;
616}
617\f
618/* Return the section that should be marked against GC for a given
619 relocation. */
620
621static asection *
622mcore_elf_gc_mark_hook (abfd, info, rel, h, sym)
623 bfd * abfd;
624 struct bfd_link_info * info;
625 Elf_Internal_Rela * rel;
626 struct elf_link_hash_entry * h;
627 Elf_Internal_Sym * sym;
628{
629 if (h != NULL)
630 {
631 switch (ELF32_R_TYPE (rel->r_info))
632 {
633 case R_MCORE_GNU_VTINHERIT:
634 case R_MCORE_GNU_VTENTRY:
635 break;
636
637 default:
638 switch (h->root.type)
639 {
640 case bfd_link_hash_defined:
641 case bfd_link_hash_defweak:
642 return h->root.u.def.section;
643
644 case bfd_link_hash_common:
645 return h->root.u.c.p->section;
646 }
647 }
648 }
649 else
650 {
651 if (!(elf_bad_symtab (abfd)
652 && ELF_ST_BIND (sym->st_info) != STB_LOCAL)
653 && ! ((sym->st_shndx <= 0 || sym->st_shndx >= SHN_LORESERVE)
654 && sym->st_shndx != SHN_COMMON))
655 {
656 return bfd_section_from_elf_index (abfd, sym->st_shndx);
657 }
658 }
659
660 return NULL;
661}
662
663/* Update the got entry reference counts for the section being removed. */
664
665static boolean
666mcore_elf_gc_sweep_hook (abfd, info, sec, relocs)
667 bfd * abfd;
668 struct bfd_link_info * info;
669 asection * sec;
670 const Elf_Internal_Rela * relocs;
671{
672 return true;
673}
674
675/* Look through the relocs for a section during the first phase.
676 Since we don't do .gots or .plts, we just need to consider the
677 virtual table relocs for gc. */
678
679static boolean
680mcore_elf_check_relocs (abfd, info, sec, relocs)
681 bfd * abfd;
682 struct bfd_link_info * info;
683 asection * sec;
684 const Elf_Internal_Rela * relocs;
685{
686 Elf_Internal_Shdr * symtab_hdr;
687 struct elf_link_hash_entry ** sym_hashes;
688 struct elf_link_hash_entry ** sym_hashes_end;
689 const Elf_Internal_Rela * rel;
690 const Elf_Internal_Rela * rel_end;
691
692 if (info->relocateable)
693 return true;
694
695 symtab_hdr = & elf_tdata (abfd)->symtab_hdr;
696 sym_hashes = elf_sym_hashes (abfd);
697 sym_hashes_end = sym_hashes + symtab_hdr->sh_size / sizeof (Elf32_External_Sym);
698 if (!elf_bad_symtab (abfd))
699 sym_hashes_end -= symtab_hdr->sh_info;
700
701 rel_end = relocs + sec->reloc_count;
702
703 for (rel = relocs; rel < rel_end; rel++)
704 {
705 struct elf_link_hash_entry * h;
706 unsigned long r_symndx;
707
708 r_symndx = ELF32_R_SYM (rel->r_info);
709
710 if (r_symndx < symtab_hdr->sh_info)
711 h = NULL;
712 else
713 h = sym_hashes [r_symndx - symtab_hdr->sh_info];
714
715 switch (ELF32_R_TYPE (rel->r_info))
716 {
717 /* This relocation describes the C++ object vtable hierarchy.
718 Reconstruct it for later use during GC. */
719 case R_MCORE_GNU_VTINHERIT:
720 if (!_bfd_elf32_gc_record_vtinherit (abfd, sec, h, rel->r_offset))
721 return false;
722 break;
723
724 /* This relocation describes which C++ vtable entries are actually
725 used. Record for later use during GC. */
726 case R_MCORE_GNU_VTENTRY:
727 if (!_bfd_elf32_gc_record_vtentry (abfd, sec, h, rel->r_addend))
728 return false;
729 break;
730 }
731 }
732
733 return true;
734}
735
736#define TARGET_BIG_SYM bfd_elf32_mcore_big_vec
737#define TARGET_BIG_NAME "elf32-mcore-big"
738#define TARGET_LITTLE_SYM bfd_elf32_mcore_little_vec
739#define TARGET_LITTLE_NAME "elf32-mcore-little"
740
741#define ELF_ARCH bfd_arch_mcore
742#define ELF_MACHINE_CODE EM_MCORE
743#define ELF_MAXPAGESIZE 0x1000 /* 4k, if we ever have 'em */
744#define elf_info_to_howto mcore_elf_info_to_howto
745#define elf_info_to_howto_rel NULL
746
747
748#define bfd_elf32_bfd_copy_private_bfd_data mcore_elf_copy_private_bfd_data
749#define bfd_elf32_bfd_merge_private_bfd_data mcore_elf_merge_private_bfd_data
750#define bfd_elf32_bfd_set_private_flags mcore_elf_set_private_flags
751#define bfd_elf32_bfd_reloc_type_lookup mcore_elf_reloc_type_lookup
752#define elf_backend_relocate_section mcore_elf_relocate_section
753#define elf_backend_gc_mark_hook mcore_elf_gc_mark_hook
754#define elf_backend_gc_sweep_hook mcore_elf_gc_sweep_hook
755#define elf_backend_check_relocs mcore_elf_check_relocs
756
757#define elf_backend_can_gc_sections 1
758
759#include "elf32-target.h"
This page took 0.076141 seconds and 4 git commands to generate.