Remove special case handling for rtems targets that are sufficiently handled by
[binutils.git] / bfd / elf32-m32c.c
blob3f9bb4e06cec1c055dd577e9f78874dbb1e6d3da
1 /* M16C/M32C specific support for 32-bit ELF.
2 Copyright (C) 2005
3 Free Software Foundation, Inc.
5 This file is part of BFD, the Binary File Descriptor library.
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
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
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.
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
19 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
21 #include "bfd.h"
22 #include "sysdep.h"
23 #include "libbfd.h"
24 #include "elf-bfd.h"
25 #include "elf/m32c.h"
26 #include "libiberty.h"
28 /* Forward declarations. */
29 static reloc_howto_type * m32c_reloc_type_lookup
30 (bfd *, bfd_reloc_code_real_type);
31 static void m32c_info_to_howto_rela
32 (bfd *, arelent *, Elf_Internal_Rela *);
33 static bfd_boolean m32c_elf_relocate_section
34 (bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *, Elf_Internal_Rela *, Elf_Internal_Sym *, asection **);
35 static bfd_boolean m32c_elf_gc_sweep_hook
36 (bfd *, struct bfd_link_info *, asection *, const Elf_Internal_Rela *);
37 static asection * m32c_elf_gc_mark_hook
38 (asection *, struct bfd_link_info *, Elf_Internal_Rela *, struct elf_link_hash_entry *, Elf_Internal_Sym *);
39 static bfd_boolean m32c_elf_check_relocs
40 (bfd *, struct bfd_link_info *, asection *, const Elf_Internal_Rela *);
41 static bfd_boolean m32c_elf_relax_delete_bytes (bfd *, asection *, bfd_vma, int);
42 #ifdef DEBUG
43 static char * m32c_get_reloc (long reloc);
44 #endif
45 static bfd_boolean m32c_elf_relax_section
46 (bfd *abfd, asection *sec, struct bfd_link_info *link_info, bfd_boolean *again);
49 static reloc_howto_type m32c_elf_howto_table [] =
51 /* This reloc does nothing. */
52 HOWTO (R_M32C_NONE, /* type */
53 0, /* rightshift */
54 0, /* size (0 = byte, 1 = short, 2 = long) */
55 32, /* bitsize */
56 FALSE, /* pc_relative */
57 0, /* bitpos */
58 complain_overflow_bitfield, /* complain_on_overflow */
59 bfd_elf_generic_reloc, /* special_function */
60 "R_M32C_NONE", /* name */
61 FALSE, /* partial_inplace */
62 0, /* src_mask */
63 0, /* dst_mask */
64 FALSE), /* pcrel_offset */
66 HOWTO (R_M32C_16, /* type */
67 0, /* rightshift */
68 1, /* size (0 = byte, 1 = short, 2 = long) */
69 16, /* bitsize */
70 FALSE, /* pc_relative */
71 0, /* bitpos */
72 complain_overflow_bitfield, /* complain_on_overflow */
73 bfd_elf_generic_reloc, /* special_function */
74 "R_M32C_16", /* name */
75 FALSE, /* partial_inplace */
76 0, /* src_mask */
77 0x0000ffff, /* dst_mask */
78 FALSE), /* pcrel_offset */
80 HOWTO (R_M32C_24, /* type */
81 0, /* rightshift */
82 2, /* size (0 = byte, 1 = short, 2 = long) */
83 24, /* bitsize */
84 FALSE, /* pc_relative */
85 0, /* bitpos */
86 complain_overflow_bitfield, /* complain_on_overflow */
87 bfd_elf_generic_reloc, /* special_function */
88 "R_M32C_24", /* name */
89 FALSE, /* partial_inplace */
90 0, /* src_mask */
91 0x00ffffff, /* dst_mask */
92 FALSE), /* pcrel_offset */
94 HOWTO (R_M32C_32, /* type */
95 0, /* rightshift */
96 2, /* size (0 = byte, 1 = short, 2 = long) */
97 32, /* bitsize */
98 FALSE, /* pc_relative */
99 0, /* bitpos */
100 complain_overflow_bitfield, /* complain_on_overflow */
101 bfd_elf_generic_reloc, /* special_function */
102 "R_M32C_32", /* name */
103 FALSE, /* partial_inplace */
104 0, /* src_mask */
105 0xffffffff, /* dst_mask */
106 FALSE), /* pcrel_offset */
108 HOWTO (R_M32C_8_PCREL, /* type */
109 0, /* rightshift */
110 0, /* size (0 = byte, 1 = short, 2 = long) */
111 8, /* bitsize */
112 TRUE, /* pc_relative */
113 0, /* bitpos */
114 complain_overflow_signed, /* complain_on_overflow */
115 bfd_elf_generic_reloc, /* special_function */
116 "R_M32C_8_PCREL", /* name */
117 FALSE, /* partial_inplace */
118 0, /* src_mask */
119 0x000000ff, /* dst_mask */
120 TRUE), /* pcrel_offset */
122 HOWTO (R_M32C_16_PCREL, /* type */
123 0, /* rightshift */
124 1, /* size (0 = byte, 1 = short, 2 = long) */
125 16, /* bitsize */
126 TRUE, /* pc_relative */
127 0, /* bitpos */
128 complain_overflow_signed, /* complain_on_overflow */
129 bfd_elf_generic_reloc, /* special_function */
130 "R_M32C_16_PCREL", /* name */
131 FALSE, /* partial_inplace */
132 0, /* src_mask */
133 0, /* dst_mask */
134 TRUE), /* pcrel_offset */
137 /* Map BFD reloc types to M32C ELF reloc types. */
139 struct m32c_reloc_map
141 bfd_reloc_code_real_type bfd_reloc_val;
142 unsigned int m32c_reloc_val;
145 static const struct m32c_reloc_map m32c_reloc_map [] =
147 { BFD_RELOC_NONE, R_M32C_NONE },
148 { BFD_RELOC_16, R_M32C_16 },
149 { BFD_RELOC_24, R_M32C_24 },
150 { BFD_RELOC_32, R_M32C_32 },
151 { BFD_RELOC_8_PCREL, R_M32C_8_PCREL },
152 { BFD_RELOC_16_PCREL, R_M32C_16_PCREL }
155 static reloc_howto_type *
156 m32c_reloc_type_lookup
157 (bfd * abfd ATTRIBUTE_UNUSED,
158 bfd_reloc_code_real_type code)
160 unsigned int i;
162 for (i = ARRAY_SIZE (m32c_reloc_map); --i;)
163 if (m32c_reloc_map [i].bfd_reloc_val == code)
164 return & m32c_elf_howto_table [m32c_reloc_map[i].m32c_reloc_val];
166 return NULL;
169 /* Set the howto pointer for an M32C ELF reloc. */
171 static void
172 m32c_info_to_howto_rela
173 (bfd * abfd ATTRIBUTE_UNUSED,
174 arelent * cache_ptr,
175 Elf_Internal_Rela * dst)
177 unsigned int r_type;
179 r_type = ELF32_R_TYPE (dst->r_info);
180 BFD_ASSERT (r_type < (unsigned int) R_M32C_max);
181 cache_ptr->howto = & m32c_elf_howto_table [r_type];
186 /* Relocate an M32C ELF section.
187 There is some attempt to make this function usable for many architectures,
188 both USE_REL and USE_RELA ['twould be nice if such a critter existed],
189 if only to serve as a learning tool.
191 The RELOCATE_SECTION function is called by the new ELF backend linker
192 to handle the relocations for a section.
194 The relocs are always passed as Rela structures; if the section
195 actually uses Rel structures, the r_addend field will always be
196 zero.
198 This function is responsible for adjusting the section contents as
199 necessary, and (if using Rela relocs and generating a relocatable
200 output file) adjusting the reloc addend as necessary.
202 This function does not have to worry about setting the reloc
203 address or the reloc symbol index.
205 LOCAL_SYMS is a pointer to the swapped in local symbols.
207 LOCAL_SECTIONS is an array giving the section in the input file
208 corresponding to the st_shndx field of each local symbol.
210 The global hash table entry for the global symbols can be found
211 via elf_sym_hashes (input_bfd).
213 When generating relocatable output, this function must handle
214 STB_LOCAL/STT_SECTION symbols specially. The output symbol is
215 going to be the section symbol corresponding to the output
216 section, which means that the addend must be adjusted
217 accordingly. */
219 static bfd_boolean
220 m32c_elf_relocate_section
221 (bfd * output_bfd ATTRIBUTE_UNUSED,
222 struct bfd_link_info * info,
223 bfd * input_bfd,
224 asection * input_section,
225 bfd_byte * contents,
226 Elf_Internal_Rela * relocs,
227 Elf_Internal_Sym * local_syms,
228 asection ** local_sections)
230 Elf_Internal_Shdr * symtab_hdr;
231 struct elf_link_hash_entry ** sym_hashes;
232 Elf_Internal_Rela * rel;
233 Elf_Internal_Rela * relend;
234 bfd *dynobj;
235 asection *splt;
237 symtab_hdr = & elf_tdata (input_bfd)->symtab_hdr;
238 sym_hashes = elf_sym_hashes (input_bfd);
239 relend = relocs + input_section->reloc_count;
241 dynobj = elf_hash_table (info)->dynobj;
242 splt = NULL;
243 if (dynobj != NULL)
244 splt = bfd_get_section_by_name (dynobj, ".plt");
246 for (rel = relocs; rel < relend; rel ++)
248 reloc_howto_type * howto;
249 unsigned long r_symndx;
250 Elf_Internal_Sym * sym;
251 asection * sec;
252 struct elf_link_hash_entry * h;
253 bfd_vma relocation;
254 bfd_reloc_status_type r;
255 const char * name = NULL;
256 int r_type;
258 r_type = ELF32_R_TYPE (rel->r_info);
260 r_symndx = ELF32_R_SYM (rel->r_info);
262 if (info->relocatable)
264 /* This is a relocatable link. We don't have to change
265 anything, unless the reloc is against a section symbol,
266 in which case we have to adjust according to where the
267 section symbol winds up in the output section. */
268 if (r_symndx < symtab_hdr->sh_info)
270 sym = local_syms + r_symndx;
272 if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
274 sec = local_sections [r_symndx];
275 rel->r_addend += sec->output_offset + sym->st_value;
279 continue;
282 /* This is a final link. */
283 howto = m32c_elf_howto_table + ELF32_R_TYPE (rel->r_info);
284 h = NULL;
285 sym = NULL;
286 sec = NULL;
288 if (r_symndx < symtab_hdr->sh_info)
290 sym = local_syms + r_symndx;
291 sec = local_sections [r_symndx];
292 relocation = (sec->output_section->vma
293 + sec->output_offset
294 + sym->st_value);
296 name = bfd_elf_string_from_elf_section
297 (input_bfd, symtab_hdr->sh_link, sym->st_name);
298 name = (name == NULL) ? bfd_section_name (input_bfd, sec) : name;
300 else
302 h = sym_hashes [r_symndx - symtab_hdr->sh_info];
304 while (h->root.type == bfd_link_hash_indirect
305 || h->root.type == bfd_link_hash_warning)
306 h = (struct elf_link_hash_entry *) h->root.u.i.link;
308 name = h->root.root.string;
310 if (h->root.type == bfd_link_hash_defined
311 || h->root.type == bfd_link_hash_defweak)
313 sec = h->root.u.def.section;
314 relocation = (h->root.u.def.value
315 + sec->output_section->vma
316 + sec->output_offset);
318 else if (h->root.type == bfd_link_hash_undefweak)
320 relocation = 0;
322 else
324 if (! ((*info->callbacks->undefined_symbol)
325 (info, h->root.root.string, input_bfd,
326 input_section, rel->r_offset, TRUE)))
327 return FALSE;
328 relocation = 0;
332 switch (ELF32_R_TYPE (rel->r_info))
334 case R_M32C_16:
336 bfd_vma *plt_offset;
338 if (h != NULL)
339 plt_offset = &h->plt.offset;
340 else
341 plt_offset = elf_local_got_offsets (input_bfd) + r_symndx;
343 /* printf("%s: rel %x plt %d\n", h ? h->root.root.string : "(none)",
344 relocation, *plt_offset);*/
345 if (relocation <= 0xffff)
347 /* If the symbol is in range for a 16-bit address, we should
348 have deallocated the plt entry in relax_section. */
349 BFD_ASSERT (*plt_offset == (bfd_vma) -1);
351 else
353 /* If the symbol is out of range for a 16-bit address,
354 we must have allocated a plt entry. */
355 BFD_ASSERT (*plt_offset != (bfd_vma) -1);
357 /* If this is the first time we've processed this symbol,
358 fill in the plt entry with the correct symbol address. */
359 if ((*plt_offset & 1) == 0)
361 unsigned int x;
363 x = 0x000000fc; /* jmpf */
364 x |= (relocation << 8) & 0xffffff00;
365 bfd_put_32 (input_bfd, x, splt->contents + *plt_offset);
366 *plt_offset |= 1;
369 relocation = (splt->output_section->vma
370 + splt->output_offset
371 + (*plt_offset & -2));
374 break;
377 r = _bfd_final_link_relocate (howto, input_bfd, input_section,
378 contents, rel->r_offset, relocation,
379 rel->r_addend);
381 if (r != bfd_reloc_ok)
383 const char * msg = (const char *) NULL;
385 switch (r)
387 case bfd_reloc_overflow:
388 r = info->callbacks->reloc_overflow
389 (info, (h ? &h->root : NULL), name, howto->name, (bfd_vma) 0,
390 input_bfd, input_section, rel->r_offset);
391 break;
393 case bfd_reloc_undefined:
394 r = info->callbacks->undefined_symbol
395 (info, name, input_bfd, input_section, rel->r_offset,
396 TRUE);
397 break;
399 case bfd_reloc_outofrange:
400 msg = _("internal error: out of range error");
401 break;
403 case bfd_reloc_notsupported:
404 msg = _("internal error: unsupported relocation error");
405 break;
407 case bfd_reloc_dangerous:
408 msg = _("internal error: dangerous relocation");
409 break;
411 default:
412 msg = _("internal error: unknown error");
413 break;
416 if (msg)
417 r = info->callbacks->warning
418 (info, msg, name, input_bfd, input_section, rel->r_offset);
420 if (! r)
421 return FALSE;
425 return TRUE;
428 /* Return the section that should be marked against GC for a given
429 relocation. */
431 static asection *
432 m32c_elf_gc_mark_hook
433 (asection * sec,
434 struct bfd_link_info * info ATTRIBUTE_UNUSED,
435 Elf_Internal_Rela * rel,
436 struct elf_link_hash_entry * h,
437 Elf_Internal_Sym * sym)
439 if (h != NULL)
441 switch (ELF32_R_TYPE (rel->r_info))
443 default:
444 switch (h->root.type)
446 case bfd_link_hash_defined:
447 case bfd_link_hash_defweak:
448 return h->root.u.def.section;
450 case bfd_link_hash_common:
451 return h->root.u.c.p->section;
453 default:
454 break;
458 else
460 if (!(elf_bad_symtab (sec->owner)
461 && ELF_ST_BIND (sym->st_info) != STB_LOCAL)
462 && ! ((sym->st_shndx <= 0 || sym->st_shndx >= SHN_LORESERVE)
463 && sym->st_shndx != SHN_COMMON))
465 return bfd_section_from_elf_index (sec->owner, sym->st_shndx);
469 return NULL;
472 /* Update the got entry reference counts for the section being removed. */
474 static bfd_boolean
475 m32c_elf_gc_sweep_hook
476 (bfd * abfd ATTRIBUTE_UNUSED,
477 struct bfd_link_info * info ATTRIBUTE_UNUSED,
478 asection * sec ATTRIBUTE_UNUSED,
479 const Elf_Internal_Rela * relocs ATTRIBUTE_UNUSED)
481 return TRUE;
484 /* We support 16-bit pointers to code above 64k by generating a thunk
485 below 64k containing a JMP instruction to the final address. */
487 static bfd_boolean
488 m32c_elf_check_relocs
489 (bfd * abfd,
490 struct bfd_link_info * info,
491 asection * sec,
492 const Elf_Internal_Rela * relocs)
494 Elf_Internal_Shdr * symtab_hdr;
495 struct elf_link_hash_entry ** sym_hashes;
496 struct elf_link_hash_entry ** sym_hashes_end;
497 const Elf_Internal_Rela * rel;
498 const Elf_Internal_Rela * rel_end;
499 bfd_vma *local_plt_offsets;
500 asection *splt;
501 bfd *dynobj;
503 if (info->relocatable)
504 return TRUE;
506 symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
507 sym_hashes = elf_sym_hashes (abfd);
508 local_plt_offsets = elf_local_got_offsets (abfd);
509 splt = NULL;
510 dynobj = elf_hash_table(info)->dynobj;
512 sym_hashes_end = sym_hashes + symtab_hdr->sh_size/sizeof (Elf32_External_Sym);
513 if (!elf_bad_symtab (abfd))
514 sym_hashes_end -= symtab_hdr->sh_info;
516 rel_end = relocs + sec->reloc_count;
517 for (rel = relocs; rel < rel_end; rel++)
519 struct elf_link_hash_entry *h;
520 unsigned long r_symndx;
521 bfd_vma *offset;
523 r_symndx = ELF32_R_SYM (rel->r_info);
524 if (r_symndx < symtab_hdr->sh_info)
525 h = NULL;
526 else
528 h = sym_hashes[r_symndx - symtab_hdr->sh_info];
529 while (h->root.type == bfd_link_hash_indirect
530 || h->root.type == bfd_link_hash_warning)
531 h = (struct elf_link_hash_entry *) h->root.u.i.link;
534 switch (ELF32_R_TYPE (rel->r_info))
536 /* This relocation describes a 16-bit pointer to a function.
537 We may need to allocate a thunk in low memory; reserve memory
538 for it now. */
539 case R_M32C_16:
540 if (dynobj == NULL)
541 elf_hash_table (info)->dynobj = dynobj = abfd;
542 if (splt == NULL)
544 splt = bfd_get_section_by_name (dynobj, ".plt");
545 if (splt == NULL)
547 splt = bfd_make_section (dynobj, ".plt");
548 if (splt == NULL
549 || ! bfd_set_section_flags (dynobj, splt,
550 (SEC_ALLOC
551 | SEC_LOAD
552 | SEC_HAS_CONTENTS
553 | SEC_IN_MEMORY
554 | SEC_LINKER_CREATED
555 | SEC_READONLY
556 | SEC_CODE))
557 || ! bfd_set_section_alignment (dynobj, splt, 1))
558 return FALSE;
562 if (h != NULL)
563 offset = &h->plt.offset;
564 else
566 if (local_plt_offsets == NULL)
568 size_t size;
569 unsigned int i;
571 size = symtab_hdr->sh_info * sizeof (bfd_vma);
572 local_plt_offsets = (bfd_vma *) bfd_alloc (abfd, size);
573 if (local_plt_offsets == NULL)
574 return FALSE;
575 elf_local_got_offsets (abfd) = local_plt_offsets;
577 for (i = 0; i < symtab_hdr->sh_info; i++)
578 local_plt_offsets[i] = (bfd_vma) -1;
580 offset = &local_plt_offsets[r_symndx];
583 if (*offset == (bfd_vma) -1)
585 *offset = splt->size;
586 splt->size += 4;
588 break;
592 return TRUE;
595 /* This must exist if dynobj is ever set. */
597 static bfd_boolean
598 m32c_elf_finish_dynamic_sections (bfd *abfd ATTRIBUTE_UNUSED,
599 struct bfd_link_info *info)
601 bfd *dynobj;
602 asection *splt;
604 /* As an extra sanity check, verify that all plt entries have
605 been filled in. */
607 if ((dynobj = elf_hash_table (info)->dynobj) != NULL
608 && (splt = bfd_get_section_by_name (dynobj, ".plt")) != NULL)
610 bfd_byte *contents = splt->contents;
611 unsigned int i, size = splt->size;
612 for (i = 0; i < size; i += 4)
614 unsigned int x = bfd_get_32 (dynobj, contents + i);
615 BFD_ASSERT (x != 0);
619 return TRUE;
622 static bfd_boolean
623 m32c_elf_always_size_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
624 struct bfd_link_info *info)
626 bfd *dynobj;
627 asection *splt;
629 if (info->relocatable)
630 return TRUE;
632 dynobj = elf_hash_table (info)->dynobj;
633 if (dynobj == NULL)
634 return TRUE;
636 splt = bfd_get_section_by_name (dynobj, ".plt");
637 BFD_ASSERT (splt != NULL);
639 splt->contents = (bfd_byte *) bfd_zalloc (dynobj, splt->size);
640 if (splt->contents == NULL)
641 return FALSE;
643 return TRUE;
646 /* Function to set the ELF flag bits. */
648 static bfd_boolean
649 m32c_elf_set_private_flags (bfd *abfd, flagword flags)
651 elf_elfheader (abfd)->e_flags = flags;
652 elf_flags_init (abfd) = TRUE;
653 return TRUE;
656 /* Merge backend specific data from an object file to the output
657 object file when linking. */
659 static bfd_boolean
660 m32c_elf_merge_private_bfd_data (bfd *ibfd, bfd *obfd)
662 flagword old_flags, old_partial;
663 flagword new_flags, new_partial;
664 bfd_boolean error = FALSE;
665 char new_opt[80];
666 char old_opt[80];
668 new_opt[0] = old_opt[0] = '\0';
669 new_flags = elf_elfheader (ibfd)->e_flags;
670 old_flags = elf_elfheader (obfd)->e_flags;
672 #ifdef DEBUG
673 (*_bfd_error_handler) ("old_flags = 0x%.8lx, new_flags = 0x%.8lx, init = %s, filename = %s",
674 old_flags, new_flags, elf_flags_init (obfd) ? "yes" : "no",
675 bfd_get_filename (ibfd));
676 #endif
678 if (!elf_flags_init (obfd))
680 /* First call, no flags set. */
681 elf_flags_init (obfd) = TRUE;
682 elf_elfheader (obfd)->e_flags = new_flags;
685 else if (new_flags == old_flags)
686 /* Compatible flags are ok. */
689 else /* Possibly incompatible flags. */
691 /* Warn if different cpu is used (allow a specific cpu to override
692 the generic cpu). */
693 new_partial = (new_flags & EF_M32C_CPU_MASK);
694 old_partial = (old_flags & EF_M32C_CPU_MASK);
695 if (new_partial == old_partial)
698 else
700 switch (new_partial)
702 default: strcat (new_opt, " -m16c"); break;
703 case EF_M32C_CPU_M16C: strcat (new_opt, " -m16c"); break;
704 case EF_M32C_CPU_M32C: strcat (new_opt, " -m32c"); break;
707 switch (old_partial)
709 default: strcat (old_opt, " -m16c"); break;
710 case EF_M32C_CPU_M16C: strcat (old_opt, " -m16c"); break;
711 case EF_M32C_CPU_M32C: strcat (old_opt, " -m32c"); break;
715 /* Print out any mismatches from above. */
716 if (new_opt[0])
718 error = TRUE;
719 (*_bfd_error_handler)
720 (_("%s: compiled with %s and linked with modules compiled with %s"),
721 bfd_get_filename (ibfd), new_opt, old_opt);
724 new_flags &= ~ EF_M32C_ALL_FLAGS;
725 old_flags &= ~ EF_M32C_ALL_FLAGS;
727 /* Warn about any other mismatches. */
728 if (new_flags != old_flags)
730 error = TRUE;
731 (*_bfd_error_handler)
732 (_("%s: uses different e_flags (0x%lx) fields than previous modules (0x%lx)"),
733 bfd_get_filename (ibfd), (long)new_flags, (long)old_flags);
737 if (error)
738 bfd_set_error (bfd_error_bad_value);
740 return !error;
744 static bfd_boolean
745 m32c_elf_print_private_bfd_data (bfd *abfd, PTR ptr)
747 FILE *file = (FILE *) ptr;
748 flagword flags;
750 BFD_ASSERT (abfd != NULL && ptr != NULL);
752 /* Print normal ELF private data. */
753 _bfd_elf_print_private_bfd_data (abfd, ptr);
755 flags = elf_elfheader (abfd)->e_flags;
756 fprintf (file, _("private flags = 0x%lx:"), (long)flags);
758 switch (flags & EF_M32C_CPU_MASK)
760 default: break;
761 case EF_M32C_CPU_M16C: fprintf (file, " -m16c"); break;
762 case EF_M32C_CPU_M32C: fprintf (file, " -m32c"); break;
765 fputc ('\n', file);
766 return TRUE;
769 /* Return the MACH for an e_flags value. */
771 static int
772 elf32_m32c_machine (bfd *abfd)
774 switch (elf_elfheader (abfd)->e_flags & EF_M32C_CPU_MASK)
776 case EF_M32C_CPU_M16C: return bfd_mach_m16c;
777 case EF_M32C_CPU_M32C: return bfd_mach_m32c;
780 return bfd_mach_m16c;
783 static bfd_boolean
784 m32c_elf_object_p (bfd *abfd)
786 bfd_default_set_arch_mach (abfd, bfd_arch_m32c,
787 elf32_m32c_machine (abfd));
788 return TRUE;
792 #ifdef DEBUG
793 static void
794 dump_symtab (bfd * abfd, void *internal_syms, void *external_syms)
796 size_t locsymcount;
797 Elf_Internal_Sym *isymbuf;
798 Elf_Internal_Sym *isymend;
799 Elf_Internal_Sym *isym;
800 Elf_Internal_Shdr *symtab_hdr;
801 bfd_boolean free_internal = 0, free_external = 0;
802 char * st_info_str;
803 char * st_info_stb_str;
804 char * st_other_str;
805 char * st_shndx_str;
807 if (! internal_syms)
809 internal_syms = bfd_malloc (1000);
810 free_internal = 1;
812 if (! external_syms)
814 external_syms = bfd_malloc (1000);
815 free_external = 1;
818 symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
819 locsymcount = symtab_hdr->sh_size / get_elf_backend_data(abfd)->s->sizeof_sym;
820 if (free_internal)
821 isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr,
822 symtab_hdr->sh_info, 0,
823 internal_syms, external_syms, NULL);
824 else
825 isymbuf = internal_syms;
826 isymend = isymbuf + locsymcount;
828 for (isym = isymbuf ; isym < isymend ; isym++)
830 switch (ELF_ST_TYPE (isym->st_info))
832 case STT_FUNC: st_info_str = "STT_FUNC";
833 case STT_SECTION: st_info_str = "STT_SECTION";
834 case STT_SRELC: st_info_str = "STT_SRELC";
835 case STT_FILE: st_info_str = "STT_FILE";
836 case STT_OBJECT: st_info_str = "STT_OBJECT";
837 case STT_TLS: st_info_str = "STT_TLS";
838 default: st_info_str = "";
840 switch (ELF_ST_BIND (isym->st_info))
842 case STB_LOCAL: st_info_stb_str = "STB_LOCAL";
843 case STB_GLOBAL: st_info_stb_str = "STB_GLOBAL";
844 default: st_info_stb_str = "";
846 switch (ELF_ST_VISIBILITY (isym->st_other))
848 case STV_DEFAULT: st_other_str = "STV_DEFAULT";
849 case STV_INTERNAL: st_other_str = "STV_INTERNAL";
850 case STV_PROTECTED: st_other_str = "STV_PROTECTED";
851 default: st_other_str = "";
853 switch (isym->st_shndx)
855 case SHN_ABS: st_shndx_str = "SHN_ABS";
856 case SHN_COMMON: st_shndx_str = "SHN_COMMON";
857 case SHN_UNDEF: st_shndx_str = "SHN_UNDEF";
858 default: st_shndx_str = "";
861 printf ("isym = %p st_value = %lx st_size = %lx st_name = (%lu) %s "
862 "st_info = (%d) %s %s st_other = (%d) %s st_shndx = (%d) %s\n",
863 isym,
864 (unsigned long) isym->st_value,
865 (unsigned long) isym->st_size,
866 isym->st_name,
867 bfd_elf_string_from_elf_section (abfd, symtab_hdr->sh_link,
868 isym->st_name),
869 isym->st_info, st_info_str, st_info_stb_str,
870 isym->st_other, st_other_str,
871 isym->st_shndx, st_shndx_str);
873 if (free_internal)
874 free (internal_syms);
875 if (free_external)
876 free (external_syms);
879 static char *
880 m32c_get_reloc (long reloc)
882 if (0 <= reloc && reloc < R_M32C_max)
883 return m32c_elf_howto_table[reloc].name;
884 else
885 return "";
887 #endif /* DEBUG */
889 /* Handle relaxing. */
891 /* A subroutine of m32c_elf_relax_section. If the global symbol H
892 is within the low 64k, remove any entry for it in the plt. */
894 struct relax_plt_data
896 asection *splt;
897 bfd_boolean *again;
900 static bfd_boolean
901 m32c_relax_plt_check (struct elf_link_hash_entry *h,
902 PTR xdata)
904 struct relax_plt_data *data = (struct relax_plt_data *) xdata;
906 if (h->root.type == bfd_link_hash_warning)
907 h = (struct elf_link_hash_entry *) h->root.u.i.link;
909 if (h->plt.offset != (bfd_vma) -1)
911 bfd_vma address;
913 if (h->root.type == bfd_link_hash_undefined
914 || h->root.type == bfd_link_hash_undefweak)
915 address = 0;
916 else
917 address = (h->root.u.def.section->output_section->vma
918 + h->root.u.def.section->output_offset
919 + h->root.u.def.value);
921 if (address <= 0xffff)
923 h->plt.offset = -1;
924 data->splt->size -= 4;
925 *data->again = TRUE;
929 return TRUE;
932 /* A subroutine of m32c_elf_relax_section. If the global symbol H
933 previously had a plt entry, give it a new entry offset. */
935 static bfd_boolean
936 m32c_relax_plt_realloc (struct elf_link_hash_entry *h,
937 PTR xdata)
939 bfd_vma *entry = (bfd_vma *) xdata;
941 if (h->root.type == bfd_link_hash_warning)
942 h = (struct elf_link_hash_entry *) h->root.u.i.link;
944 if (h->plt.offset != (bfd_vma) -1)
946 h->plt.offset = *entry;
947 *entry += 4;
950 return TRUE;
953 static bfd_boolean
954 m32c_elf_relax_plt_section (bfd *dynobj,
955 asection *splt,
956 struct bfd_link_info *info,
957 bfd_boolean *again)
959 struct relax_plt_data relax_plt_data;
960 bfd *ibfd;
962 /* Assume nothing changes. */
963 *again = FALSE;
965 if (info->relocatable)
966 return TRUE;
968 /* We only relax the .plt section at the moment. */
969 if (dynobj != elf_hash_table (info)->dynobj
970 || strcmp (splt->name, ".plt") != 0)
971 return TRUE;
973 /* Quick check for an empty plt. */
974 if (splt->size == 0)
975 return TRUE;
977 /* Map across all global symbols; see which ones happen to
978 fall in the low 64k. */
979 relax_plt_data.splt = splt;
980 relax_plt_data.again = again;
981 elf_link_hash_traverse (elf_hash_table (info), m32c_relax_plt_check,
982 &relax_plt_data);
984 /* Likewise for local symbols, though that's somewhat less convenient
985 as we have to walk the list of input bfds and swap in symbol data. */
986 for (ibfd = info->input_bfds; ibfd ; ibfd = ibfd->link_next)
988 bfd_vma *local_plt_offsets = elf_local_got_offsets (ibfd);
989 Elf_Internal_Shdr *symtab_hdr;
990 Elf_Internal_Sym *isymbuf = NULL;
991 unsigned int idx;
993 if (! local_plt_offsets)
994 continue;
996 symtab_hdr = &elf_tdata (ibfd)->symtab_hdr;
997 if (symtab_hdr->sh_info != 0)
999 isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
1000 if (isymbuf == NULL)
1001 isymbuf = bfd_elf_get_elf_syms (ibfd, symtab_hdr,
1002 symtab_hdr->sh_info, 0,
1003 NULL, NULL, NULL);
1004 if (isymbuf == NULL)
1005 return FALSE;
1008 for (idx = 0; idx < symtab_hdr->sh_info; ++idx)
1010 Elf_Internal_Sym *isym;
1011 asection *tsec;
1012 bfd_vma address;
1014 if (local_plt_offsets[idx] == (bfd_vma) -1)
1015 continue;
1017 isym = &isymbuf[idx];
1018 if (isym->st_shndx == SHN_UNDEF)
1019 continue;
1020 else if (isym->st_shndx == SHN_ABS)
1021 tsec = bfd_abs_section_ptr;
1022 else if (isym->st_shndx == SHN_COMMON)
1023 tsec = bfd_com_section_ptr;
1024 else
1025 tsec = bfd_section_from_elf_index (ibfd, isym->st_shndx);
1027 address = (tsec->output_section->vma
1028 + tsec->output_offset
1029 + isym->st_value);
1030 if (address <= 0xffff)
1032 local_plt_offsets[idx] = -1;
1033 splt->size -= 4;
1034 *again = TRUE;
1038 if (isymbuf != NULL
1039 && symtab_hdr->contents != (unsigned char *) isymbuf)
1041 if (! info->keep_memory)
1042 free (isymbuf);
1043 else
1045 /* Cache the symbols for elf_link_input_bfd. */
1046 symtab_hdr->contents = (unsigned char *) isymbuf;
1051 /* If we changed anything, walk the symbols again to reallocate
1052 .plt entry addresses. */
1053 if (*again && splt->size > 0)
1055 bfd_vma entry = 0;
1057 elf_link_hash_traverse (elf_hash_table (info),
1058 m32c_relax_plt_realloc, &entry);
1060 for (ibfd = info->input_bfds; ibfd ; ibfd = ibfd->link_next)
1062 bfd_vma *local_plt_offsets = elf_local_got_offsets (ibfd);
1063 unsigned int nlocals = elf_tdata (ibfd)->symtab_hdr.sh_info;
1064 unsigned int idx;
1066 if (! local_plt_offsets)
1067 continue;
1069 for (idx = 0; idx < nlocals; ++idx)
1070 if (local_plt_offsets[idx] != (bfd_vma) -1)
1072 local_plt_offsets[idx] = entry;
1073 entry += 4;
1078 return TRUE;
1081 struct relax_reloc_s
1083 int machine;
1084 int opcode_mask;
1085 bfd_vma opcode; /* original opcode or insn part */
1086 int relax_backward; /* lbound */
1087 int relax_forward; /* hbound */
1088 int value_shift;
1089 int mask;
1090 int new_opcode; /* new opcode */
1091 int old_reloc; /* old relocation */
1092 int new_reloc; /* new relocation */
1093 int use_pcrel;
1094 int delete_n; /* # bytes differ between original and new */
1096 static struct relax_reloc_s relax_reloc [] =
1098 #if 0
1100 bfd_mach_m16c,
1101 0xff,
1102 0xfc, /* jmp.a */
1103 -32768,
1104 32767,
1106 0xffffff00,
1107 0xf4, /* jmp.w */
1108 R_M32C_8_ELABEL24,
1109 R_M32C_8_PCREL16,
1114 bfd_mach_m32c,
1115 0xff,
1116 0xcc, /* jmp.a */
1117 -32768,
1118 32767,
1120 0xffffff00,
1121 0xce, /* jmp.w */
1122 R_M32C_8_ELABEL24,
1123 R_M32C_8_PCREL16,
1128 bfd_mach_m32c,
1129 0xff,
1130 0xcd, /* jsr.a */
1131 -32768,
1132 32767,
1134 0xffffff00,
1135 0xcf, /* jsr.w */
1136 R_M32C_8_ELABEL24,
1137 R_M32C_8_PCREL16,
1142 bfd_mach_m16c,
1143 0xff,
1144 0xf4, /* jmp.w */
1145 -128,
1146 127,
1148 0xffffff00,
1149 0xfe, /* jmp.b */
1150 R_M32C_8_PCREL16,
1151 R_M32C_8_PCREL8,
1156 bfd_mach_m32c,
1157 0xff,
1158 0xce, /* jmp.w */
1159 -128,
1160 127,
1162 0xffffff00,
1163 0xbb, /* jmp.b */
1164 R_M32C_8_PCREL16,
1165 R_M32C_8_PCREL8,
1170 bfd_mach_m32c,
1171 0xc0f6,
1172 0x8096, /* dest */
1174 0xffff,
1176 0xffff3fff,
1177 0xc000, /* abs16 */
1178 R_M32C_24_ABS24,
1179 R_M32C_24_ABS16,
1184 bfd_mach_m32c,
1185 0xc0f6,
1186 0x80a6, /* dest */
1188 0xffff,
1190 0xffff3fff,
1191 0xc000, /* abs16 */
1192 R_M32C_32_ABS24,
1193 R_M32C_32_ABS16,
1198 bfd_mach_m32c,
1199 0xc0f6,
1200 0x80b6, /* dest */
1202 0xffff,
1204 0xffff3fff,
1205 0xc000, /* abs16 */
1206 R_M32C_40_ABS24,
1207 R_M32C_40_ABS16,
1212 bfd_mach_m32c,
1213 0x30f0,
1214 0x20b0, /* src */
1216 0xffff,
1218 0xffffcfff,
1219 0x3000, /* abs16 */
1220 R_M32C_16_ABS24,
1221 R_M32C_16_ABS16,
1226 bfd_mach_m32c,
1227 0xc086,
1228 0x8086, /* dest */
1230 0xffff,
1232 0xffff3fff,
1233 0xc000, /* abs16 */
1234 R_M32C_16_ABS24,
1235 R_M32C_16_ABS16,
1239 #endif
1241 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1244 static bfd_boolean
1245 m32c_elf_relax_section
1246 (bfd * abfd,
1247 asection * sec,
1248 struct bfd_link_info * link_info,
1249 bfd_boolean * again)
1251 Elf_Internal_Shdr *symtab_hdr;
1252 Elf_Internal_Shdr *shndx_hdr;
1253 Elf_Internal_Rela *internal_relocs;
1254 Elf_Internal_Rela *free_relocs = NULL;
1255 Elf_Internal_Rela *irel, *irelend;
1256 bfd_byte * contents = NULL;
1257 bfd_byte * free_contents = NULL;
1258 Elf32_External_Sym *extsyms = NULL;
1259 Elf32_External_Sym *free_extsyms = NULL;
1260 Elf_External_Sym_Shndx *shndx_buf = NULL;
1261 int machine;
1263 if (abfd == elf_hash_table (link_info)->dynobj
1264 && strcmp (sec->name, ".plt") == 0)
1265 return m32c_elf_relax_plt_section (abfd, sec, link_info, again);
1267 /* Assume nothing changes. */
1268 *again = FALSE;
1270 machine = elf32_m32c_machine (abfd);
1272 /* We don't have to do anything for a relocatable link, if
1273 this section does not have relocs, or if this is not a
1274 code section. */
1275 if (link_info->relocatable
1276 || (sec->flags & SEC_RELOC) == 0
1277 || sec->reloc_count == 0
1278 || (sec->flags & SEC_CODE) == 0)
1279 return TRUE;
1281 /* Relaxing doesn't quite work right yet. */
1282 return TRUE;
1284 symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
1285 shndx_hdr = &elf_tdata (abfd)->symtab_shndx_hdr;
1287 /* Get a copy of the native relocations. */
1288 internal_relocs = (_bfd_elf_link_read_relocs
1289 (abfd, sec, (PTR) NULL, (Elf_Internal_Rela *) NULL,
1290 link_info->keep_memory));
1291 if (internal_relocs == NULL)
1292 goto error_return;
1293 if (! link_info->keep_memory)
1294 free_relocs = internal_relocs;
1296 /* Walk through them looking for relaxing opportunities. */
1297 irelend = internal_relocs + sec->reloc_count;
1299 for (irel = internal_relocs; irel < irelend; irel++)
1301 bfd_vma symval;
1302 bfd_vma insn;
1303 bfd_vma pc;
1304 bfd_signed_vma pcrel_value;
1305 bfd_vma addend;
1306 int to_delete;
1307 int i;
1309 /* Get the section contents. */
1310 if (contents == NULL)
1312 if (elf_section_data (sec)->this_hdr.contents != NULL)
1313 contents = elf_section_data (sec)->this_hdr.contents;
1314 /* Go get them off disk. */
1315 else if (!bfd_malloc_and_get_section (abfd, sec, &contents))
1316 goto error_return;
1319 /* Read this BFD's symbols if we haven't done so already. */
1320 if (extsyms == NULL)
1322 /* Get cached copy if it exists. */
1323 if (symtab_hdr->contents != NULL)
1324 extsyms = (Elf32_External_Sym *) symtab_hdr->contents;
1325 else
1327 bfd_size_type amt = symtab_hdr->sh_size;
1329 /* Go get them off disk. */
1330 extsyms = (Elf32_External_Sym *) bfd_malloc (amt);
1331 if (extsyms == NULL)
1332 goto error_return;
1333 free_extsyms = extsyms;
1334 if (bfd_seek (abfd, symtab_hdr->sh_offset, SEEK_SET) != 0
1335 || bfd_bread (extsyms, amt, abfd) != amt)
1336 goto error_return;
1337 symtab_hdr->contents = (bfd_byte *) extsyms;
1340 if (shndx_hdr->sh_size != 0)
1342 bfd_size_type amt;
1344 amt = symtab_hdr->sh_info;
1345 amt *= sizeof (Elf_External_Sym_Shndx);
1346 shndx_buf = (Elf_External_Sym_Shndx *) bfd_malloc (amt);
1347 if (shndx_buf == NULL)
1348 goto error_return;
1349 if (bfd_seek (abfd, shndx_hdr->sh_offset, SEEK_SET) != 0
1350 || bfd_bread ((PTR) shndx_buf, amt, abfd) != amt)
1351 goto error_return;
1352 shndx_hdr->contents = (bfd_byte *) shndx_buf;
1356 /* Get the value of the symbol referred to by the reloc. */
1357 if (ELF32_R_SYM (irel->r_info) < symtab_hdr->sh_info)
1359 /* A local symbol. */
1360 Elf32_External_Sym *esym;
1361 Elf_External_Sym_Shndx *shndx;
1362 Elf_Internal_Sym isym;
1364 esym = extsyms + ELF32_R_SYM (irel->r_info);
1365 shndx = shndx_buf + (shndx_buf ? ELF32_R_SYM (irel->r_info) : 0);
1366 bfd_elf32_swap_symbol_in (abfd, esym, shndx, &isym);
1368 symval = (isym.st_value
1369 + sec->output_section->vma
1370 + sec->output_offset);
1372 else
1374 unsigned long indx;
1375 struct elf_link_hash_entry *h;
1377 /* An external symbol. */
1378 indx = ELF32_R_SYM (irel->r_info) - symtab_hdr->sh_info;
1379 h = elf_sym_hashes (abfd)[indx];
1380 BFD_ASSERT (h != NULL);
1382 if (h->root.type != bfd_link_hash_defined
1383 && h->root.type != bfd_link_hash_defweak)
1384 /* This appears to be a reference to an undefined
1385 symbol. Just ignore it--it will be caught by the
1386 regular reloc processing. */
1387 continue;
1389 symval = (h->root.u.def.value
1390 + h->root.u.def.section->output_section->vma
1391 + h->root.u.def.section->output_offset);
1394 /* There will always be room for the relaxed insn, since it is smaller
1395 than the one it would replace. */
1396 BFD_ASSERT (irel->r_offset <= sec->size - 2);
1398 insn = bfd_get_16 (abfd, contents + irel->r_offset + 0);
1400 addend = irel->r_addend;
1401 for (i = 0; relax_reloc[i].machine; i++)
1403 #ifdef DEBUG
1404 _bfd_error_handler ("insn %x %d mask %x opcode %x =%x\n",
1405 insn, i, relax_reloc[i].opcode_mask,
1406 relax_reloc[i].opcode,
1407 (insn & relax_reloc[i].opcode_mask) == relax_reloc[i].opcode);
1408 #endif
1409 if (!(machine == relax_reloc[i].machine
1410 && (insn & relax_reloc[i].opcode_mask) == relax_reloc[i].opcode
1411 && (relax_reloc[i].old_reloc
1412 == (int) ELF32_R_TYPE(irel->r_info))))
1413 continue;
1415 /* At this point we've confirmed we have a matching insn. Now
1416 ensure the operand is in range. */
1417 if (relax_reloc[i].use_pcrel)
1419 pc = sec->output_section->vma + sec->output_offset
1420 + irel->r_offset;
1421 pcrel_value = symval - pc;
1422 #ifndef USE_REL /* put in for learning purposes */
1423 pcrel_value += addend;
1424 #else
1425 addend = bfd_get_signed_16 (abfd, contents + irel->r_offset + 2);
1426 pcrel_value += addend;
1427 #endif
1429 else
1430 pcrel_value = symval;
1432 if (pcrel_value >= relax_reloc[i].relax_backward
1433 && pcrel_value < relax_reloc[i].relax_forward + 2)
1435 /* We can relax to a shorter operand. */
1436 insn = (insn & relax_reloc[i].mask) | relax_reloc[i].new_opcode;
1438 to_delete = relax_reloc[i].delete_n;
1440 /* Rewrite the insn. */
1441 bfd_put_16 (abfd, insn, contents + irel->r_offset);
1443 /* Set the new reloc type. */
1444 irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
1445 relax_reloc[i].new_reloc);
1446 irel->r_addend = pcrel_value;
1448 else
1449 continue;
1451 #ifdef DEBUG
1452 _bfd_error_handler ("insn %x pc %x index %d mask %x shift %d delete %d\n"
1453 "old reloc %s new reloc %s",
1454 insn, sec->output_section->vma
1455 + sec->output_offset + irel->r_offset + 2,
1456 i, relax_reloc[i].opcode_mask,
1457 relax_reloc[i].value_shift, to_delete,
1458 m32c_get_reloc (relax_reloc[i].old_reloc),
1459 m32c_get_reloc (relax_reloc[i].new_reloc));
1460 #endif
1462 /* Note that we've changed the relocs, section contents, etc. */
1463 elf_section_data (sec)->relocs = internal_relocs;
1464 free_relocs = NULL;
1466 elf_section_data (sec)->this_hdr.contents = contents;
1467 free_contents = NULL;
1469 symtab_hdr->contents = (bfd_byte *) extsyms;
1470 free_extsyms = NULL;
1472 /* Delete TO_DELETE bytes of data. */
1473 if (! m32c_elf_relax_delete_bytes
1474 (abfd, sec, irel->r_offset + relax_reloc[i].value_shift,
1475 to_delete))
1476 goto error_return;
1477 } /* next relax_reloc */
1478 } /* next relocation */
1480 if (free_relocs != NULL)
1482 free (free_relocs);
1483 free_relocs = NULL;
1486 if (free_contents != NULL)
1488 if (! link_info->keep_memory)
1489 free (free_contents);
1490 /* Cache the section contents for elf_link_input_bfd. */
1491 else
1492 elf_section_data (sec)->this_hdr.contents = contents;
1494 free_contents = NULL;
1497 if (shndx_buf != NULL)
1499 shndx_hdr->contents = NULL;
1500 free (shndx_buf);
1503 if (free_extsyms != NULL)
1505 if (! link_info->keep_memory)
1506 free (free_extsyms);
1507 /* Cache the symbols for elf_link_input_bfd. */
1508 else
1509 symtab_hdr->contents = NULL /* (unsigned char *) extsyms*/;
1511 free_extsyms = NULL;
1513 /* elf_link_input_bfd expects internal syms. */
1514 symtab_hdr->contents = NULL;
1516 return TRUE;
1518 error_return:
1519 if (free_relocs != NULL)
1520 free (free_relocs);
1521 if (free_contents != NULL)
1522 free (free_contents);
1523 if (shndx_buf != NULL)
1525 shndx_hdr->contents = NULL;
1526 free (shndx_buf);
1528 if (free_extsyms != NULL)
1529 free (free_extsyms);
1530 return FALSE;
1533 /* Delete some bytes from a section while relaxing. */
1535 static bfd_boolean
1536 m32c_elf_relax_delete_bytes
1537 (bfd * abfd,
1538 asection * sec,
1539 bfd_vma addr,
1540 int count)
1542 Elf_Internal_Shdr *symtab_hdr;
1543 Elf_Internal_Shdr *shndx_hdr;
1544 int sec_shndx;
1545 bfd_byte *contents;
1546 Elf_Internal_Rela *irel;
1547 Elf_Internal_Rela *irelend;
1548 Elf_Internal_Rela *irelalign;
1549 bfd_vma toaddr;
1550 Elf32_External_Sym *esym;
1551 Elf32_External_Sym *esymend;
1552 Elf32_External_Sym *extsyms;
1553 Elf_External_Sym_Shndx *shndx_buf;
1554 Elf_External_Sym_Shndx *shndx;
1555 struct elf_link_hash_entry ** sym_hashes;
1556 struct elf_link_hash_entry ** end_hashes;
1557 unsigned int symcount;
1559 symtab_hdr = & elf_tdata (abfd)->symtab_hdr;
1560 extsyms = (Elf32_External_Sym *) symtab_hdr->contents;
1561 shndx_hdr = & elf_tdata (abfd)->symtab_shndx_hdr;
1562 shndx_buf = (Elf_External_Sym_Shndx *) shndx_hdr->contents;
1563 sec_shndx = _bfd_elf_section_from_bfd_section (abfd, sec);
1564 contents = elf_section_data (sec)->this_hdr.contents;
1566 /* The deletion must stop at the next ALIGN reloc for an aligment
1567 power larger than the number of bytes we are deleting. */
1568 irelalign = NULL;
1569 toaddr = sec->size;
1571 irel = elf_section_data (sec)->relocs;
1572 irelend = irel + sec->reloc_count;
1574 /* Actually delete the bytes. */
1575 memmove (contents + addr, contents + addr + count, (size_t) (toaddr - addr - count));
1576 sec->size -= count;
1578 /* Adjust all the relocs. */
1579 for (irel = elf_section_data (sec)->relocs; irel < irelend; irel ++)
1581 /* Get the new reloc address. */
1582 if (irel->r_offset > addr && irel->r_offset < toaddr)
1583 irel->r_offset -= count;
1584 if (irel->r_addend > addr && irel->r_addend < toaddr)
1585 irel->r_addend -= count;
1588 /* Adjust the local symbols defined in this section. */
1589 shndx = shndx_buf;
1590 esym = extsyms;
1591 esymend = esym + symtab_hdr->sh_info;
1592 for (; esym < esymend; esym++, shndx = (shndx ? shndx + 1 : NULL))
1594 Elf_Internal_Sym isym;
1595 Elf_External_Sym_Shndx dummy;
1597 bfd_elf32_swap_symbol_in (abfd, esym, shndx, &isym);
1599 if ((int) isym.st_shndx == sec_shndx
1600 && isym.st_value > addr
1601 && isym.st_value < toaddr)
1603 isym.st_value -= count;
1604 bfd_elf32_swap_symbol_out (abfd, &isym, (PTR) esym, (PTR) & dummy);
1608 /* Now adjust the global symbols defined in this section. */
1609 symcount = (symtab_hdr->sh_size / sizeof (Elf32_External_Sym)
1610 - symtab_hdr->sh_info);
1611 sym_hashes = elf_sym_hashes (abfd);
1612 // sym_hashes += symtab_hdr->sh_info;
1613 end_hashes = sym_hashes + symcount;
1615 for (; sym_hashes < end_hashes; sym_hashes ++)
1617 struct elf_link_hash_entry * sym_hash = * sym_hashes;
1619 if (sym_hash &&
1620 ( sym_hash->root.type == bfd_link_hash_defined
1621 || sym_hash->root.type == bfd_link_hash_defweak)
1622 && sym_hash->root.u.def.section == sec
1623 && sym_hash->root.u.def.value > addr
1624 && sym_hash->root.u.def.value < toaddr)
1625 sym_hash->root.u.def.value -= count;
1628 return TRUE;
1632 #define ELF_ARCH bfd_arch_m32c
1633 #define ELF_MACHINE_CODE EM_M32C
1634 #define ELF_MAXPAGESIZE 0x1000
1636 #if 0
1637 #define TARGET_BIG_SYM bfd_elf32_m32c_vec
1638 #define TARGET_BIG_NAME "elf32-m32c"
1639 #else
1640 #define TARGET_LITTLE_SYM bfd_elf32_m32c_vec
1641 #define TARGET_LITTLE_NAME "elf32-m32c"
1642 #endif
1644 #define elf_info_to_howto_rel NULL
1645 #define elf_info_to_howto m32c_info_to_howto_rela
1646 #define elf_backend_object_p m32c_elf_object_p
1647 #define elf_backend_relocate_section m32c_elf_relocate_section
1648 #define elf_backend_gc_mark_hook m32c_elf_gc_mark_hook
1649 #define elf_backend_gc_sweep_hook m32c_elf_gc_sweep_hook
1650 #define elf_backend_check_relocs m32c_elf_check_relocs
1651 #define elf_backend_object_p m32c_elf_object_p
1652 #define elf_symbol_leading_char ('_')
1653 #define elf_backend_always_size_sections \
1654 m32c_elf_always_size_sections
1655 #define elf_backend_finish_dynamic_sections \
1656 m32c_elf_finish_dynamic_sections
1658 #define elf_backend_can_gc_sections 1
1660 #define bfd_elf32_bfd_reloc_type_lookup m32c_reloc_type_lookup
1661 #define bfd_elf32_bfd_relax_section m32c_elf_relax_section
1662 #define bfd_elf32_bfd_set_private_flags m32c_elf_set_private_flags
1663 #define bfd_elf32_bfd_merge_private_bfd_data m32c_elf_merge_private_bfd_data
1664 #define bfd_elf32_bfd_print_private_bfd_data m32c_elf_print_private_bfd_data
1666 #include "elf32-target.h"