2005-12-18 H.J. Lu <hongjiu.lu@intel.com>
[binutils.git] / bfd / elf32-m32c.c
blob35136af820faa7121bbc41c125f2abbab30f2609
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 */
136 HOWTO (R_M32C_8, /* type */
137 0, /* rightshift */
138 0, /* size (0 = byte, 1 = short, 2 = long) */
139 8, /* bitsize */
140 FALSE, /* pc_relative */
141 0, /* bitpos */
142 complain_overflow_unsigned, /* complain_on_overflow */
143 bfd_elf_generic_reloc, /* special_function */
144 "R_M32C_8", /* name */
145 FALSE, /* partial_inplace */
146 0, /* src_mask */
147 0x000000ff, /* dst_mask */
148 FALSE), /* pcrel_offset */
150 HOWTO (R_M32C_LO16, /* type */
151 0, /* rightshift */
152 1, /* size (0 = byte, 1 = short, 2 = long) */
153 16, /* bitsize */
154 FALSE, /* pc_relative */
155 0, /* bitpos */
156 complain_overflow_dont, /* complain_on_overflow */
157 bfd_elf_generic_reloc, /* special_function */
158 "R_M32C_LO16", /* name */
159 FALSE, /* partial_inplace */
160 0, /* src_mask */
161 0x0000ffff, /* dst_mask */
162 FALSE), /* pcrel_offset */
164 HOWTO (R_M32C_HI8, /* type */
165 0, /* rightshift */
166 0, /* size (0 = byte, 1 = short, 2 = long) */
167 8, /* bitsize */
168 FALSE, /* pc_relative */
169 0, /* bitpos */
170 complain_overflow_dont, /* complain_on_overflow */
171 bfd_elf_generic_reloc, /* special_function */
172 "R_M32C_HI8", /* name */
173 FALSE, /* partial_inplace */
174 0, /* src_mask */
175 0x000000ff, /* dst_mask */
176 FALSE), /* pcrel_offset */
178 HOWTO (R_M32C_HI16, /* type */
179 0, /* rightshift */
180 1, /* size (0 = byte, 1 = short, 2 = long) */
181 16, /* bitsize */
182 FALSE, /* pc_relative */
183 0, /* bitpos */
184 complain_overflow_dont, /* complain_on_overflow */
185 bfd_elf_generic_reloc, /* special_function */
186 "R_M32C_HI16", /* name */
187 FALSE, /* partial_inplace */
188 0, /* src_mask */
189 0x0000ffff, /* dst_mask */
190 FALSE), /* pcrel_offset */
193 /* Map BFD reloc types to M32C ELF reloc types. */
195 struct m32c_reloc_map
197 bfd_reloc_code_real_type bfd_reloc_val;
198 unsigned int m32c_reloc_val;
201 static const struct m32c_reloc_map m32c_reloc_map [] =
203 { BFD_RELOC_NONE, R_M32C_NONE },
204 { BFD_RELOC_16, R_M32C_16 },
205 { BFD_RELOC_24, R_M32C_24 },
206 { BFD_RELOC_32, R_M32C_32 },
207 { BFD_RELOC_8_PCREL, R_M32C_8_PCREL },
208 { BFD_RELOC_16_PCREL, R_M32C_16_PCREL },
209 { BFD_RELOC_8, R_M32C_8 },
210 { BFD_RELOC_LO16, R_M32C_LO16 },
211 { BFD_RELOC_HI16, R_M32C_HI16 },
212 { BFD_RELOC_M32C_HI8, R_M32C_HI8 }
215 static reloc_howto_type *
216 m32c_reloc_type_lookup
217 (bfd * abfd ATTRIBUTE_UNUSED,
218 bfd_reloc_code_real_type code)
220 unsigned int i;
222 for (i = ARRAY_SIZE (m32c_reloc_map); --i;)
223 if (m32c_reloc_map [i].bfd_reloc_val == code)
224 return & m32c_elf_howto_table [m32c_reloc_map[i].m32c_reloc_val];
226 return NULL;
229 /* Set the howto pointer for an M32C ELF reloc. */
231 static void
232 m32c_info_to_howto_rela
233 (bfd * abfd ATTRIBUTE_UNUSED,
234 arelent * cache_ptr,
235 Elf_Internal_Rela * dst)
237 unsigned int r_type;
239 r_type = ELF32_R_TYPE (dst->r_info);
240 BFD_ASSERT (r_type < (unsigned int) R_M32C_max);
241 cache_ptr->howto = & m32c_elf_howto_table [r_type];
246 /* Relocate an M32C ELF section.
247 There is some attempt to make this function usable for many architectures,
248 both USE_REL and USE_RELA ['twould be nice if such a critter existed],
249 if only to serve as a learning tool.
251 The RELOCATE_SECTION function is called by the new ELF backend linker
252 to handle the relocations for a section.
254 The relocs are always passed as Rela structures; if the section
255 actually uses Rel structures, the r_addend field will always be
256 zero.
258 This function is responsible for adjusting the section contents as
259 necessary, and (if using Rela relocs and generating a relocatable
260 output file) adjusting the reloc addend as necessary.
262 This function does not have to worry about setting the reloc
263 address or the reloc symbol index.
265 LOCAL_SYMS is a pointer to the swapped in local symbols.
267 LOCAL_SECTIONS is an array giving the section in the input file
268 corresponding to the st_shndx field of each local symbol.
270 The global hash table entry for the global symbols can be found
271 via elf_sym_hashes (input_bfd).
273 When generating relocatable output, this function must handle
274 STB_LOCAL/STT_SECTION symbols specially. The output symbol is
275 going to be the section symbol corresponding to the output
276 section, which means that the addend must be adjusted
277 accordingly. */
279 static bfd_boolean
280 m32c_elf_relocate_section
281 (bfd * output_bfd ATTRIBUTE_UNUSED,
282 struct bfd_link_info * info,
283 bfd * input_bfd,
284 asection * input_section,
285 bfd_byte * contents,
286 Elf_Internal_Rela * relocs,
287 Elf_Internal_Sym * local_syms,
288 asection ** local_sections)
290 Elf_Internal_Shdr * symtab_hdr;
291 struct elf_link_hash_entry ** sym_hashes;
292 Elf_Internal_Rela * rel;
293 Elf_Internal_Rela * relend;
294 bfd *dynobj;
295 asection *splt;
297 symtab_hdr = & elf_tdata (input_bfd)->symtab_hdr;
298 sym_hashes = elf_sym_hashes (input_bfd);
299 relend = relocs + input_section->reloc_count;
301 dynobj = elf_hash_table (info)->dynobj;
302 splt = NULL;
303 if (dynobj != NULL)
304 splt = bfd_get_section_by_name (dynobj, ".plt");
306 for (rel = relocs; rel < relend; rel ++)
308 reloc_howto_type * howto;
309 unsigned long r_symndx;
310 Elf_Internal_Sym * sym;
311 asection * sec;
312 struct elf_link_hash_entry * h;
313 bfd_vma relocation;
314 bfd_reloc_status_type r;
315 const char * name = NULL;
316 int r_type;
318 r_type = ELF32_R_TYPE (rel->r_info);
320 r_symndx = ELF32_R_SYM (rel->r_info);
322 if (info->relocatable)
324 /* This is a relocatable link. We don't have to change
325 anything, unless the reloc is against a section symbol,
326 in which case we have to adjust according to where the
327 section symbol winds up in the output section. */
328 if (r_symndx < symtab_hdr->sh_info)
330 sym = local_syms + r_symndx;
332 if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
334 sec = local_sections [r_symndx];
335 rel->r_addend += sec->output_offset + sym->st_value;
339 continue;
342 /* This is a final link. */
343 howto = m32c_elf_howto_table + ELF32_R_TYPE (rel->r_info);
344 h = NULL;
345 sym = NULL;
346 sec = NULL;
348 if (r_symndx < symtab_hdr->sh_info)
350 sym = local_syms + r_symndx;
351 sec = local_sections [r_symndx];
352 relocation = (sec->output_section->vma
353 + sec->output_offset
354 + sym->st_value);
356 name = bfd_elf_string_from_elf_section
357 (input_bfd, symtab_hdr->sh_link, sym->st_name);
358 name = (name == NULL) ? bfd_section_name (input_bfd, sec) : name;
360 else
362 h = sym_hashes [r_symndx - symtab_hdr->sh_info];
364 while (h->root.type == bfd_link_hash_indirect
365 || h->root.type == bfd_link_hash_warning)
366 h = (struct elf_link_hash_entry *) h->root.u.i.link;
368 name = h->root.root.string;
370 if (h->root.type == bfd_link_hash_defined
371 || h->root.type == bfd_link_hash_defweak)
373 sec = h->root.u.def.section;
374 relocation = (h->root.u.def.value
375 + sec->output_section->vma
376 + sec->output_offset);
378 else if (h->root.type == bfd_link_hash_undefweak)
380 relocation = 0;
382 else
384 if (! ((*info->callbacks->undefined_symbol)
385 (info, h->root.root.string, input_bfd,
386 input_section, rel->r_offset, TRUE)))
387 return FALSE;
388 relocation = 0;
392 switch (ELF32_R_TYPE (rel->r_info))
394 case R_M32C_16:
396 bfd_vma *plt_offset;
398 if (h != NULL)
399 plt_offset = &h->plt.offset;
400 else
401 plt_offset = elf_local_got_offsets (input_bfd) + r_symndx;
403 /* printf("%s: rel %x plt %d\n", h ? h->root.root.string : "(none)",
404 relocation, *plt_offset);*/
405 if (relocation <= 0xffff)
407 /* If the symbol is in range for a 16-bit address, we should
408 have deallocated the plt entry in relax_section. */
409 BFD_ASSERT (*plt_offset == (bfd_vma) -1);
411 else
413 /* If the symbol is out of range for a 16-bit address,
414 we must have allocated a plt entry. */
415 BFD_ASSERT (*plt_offset != (bfd_vma) -1);
417 /* If this is the first time we've processed this symbol,
418 fill in the plt entry with the correct symbol address. */
419 if ((*plt_offset & 1) == 0)
421 unsigned int x;
423 x = 0x000000fc; /* jmpf */
424 x |= (relocation << 8) & 0xffffff00;
425 bfd_put_32 (input_bfd, x, splt->contents + *plt_offset);
426 *plt_offset |= 1;
429 relocation = (splt->output_section->vma
430 + splt->output_offset
431 + (*plt_offset & -2));
434 break;
436 case R_M32C_HI8:
437 case R_M32C_HI16:
438 relocation >>= 16;
439 break;
442 r = _bfd_final_link_relocate (howto, input_bfd, input_section,
443 contents, rel->r_offset, relocation,
444 rel->r_addend);
446 if (r != bfd_reloc_ok)
448 const char * msg = (const char *) NULL;
450 switch (r)
452 case bfd_reloc_overflow:
453 r = info->callbacks->reloc_overflow
454 (info, (h ? &h->root : NULL), name, howto->name, (bfd_vma) 0,
455 input_bfd, input_section, rel->r_offset);
456 break;
458 case bfd_reloc_undefined:
459 r = info->callbacks->undefined_symbol
460 (info, name, input_bfd, input_section, rel->r_offset,
461 TRUE);
462 break;
464 case bfd_reloc_outofrange:
465 msg = _("internal error: out of range error");
466 break;
468 case bfd_reloc_notsupported:
469 msg = _("internal error: unsupported relocation error");
470 break;
472 case bfd_reloc_dangerous:
473 msg = _("internal error: dangerous relocation");
474 break;
476 default:
477 msg = _("internal error: unknown error");
478 break;
481 if (msg)
482 r = info->callbacks->warning
483 (info, msg, name, input_bfd, input_section, rel->r_offset);
485 if (! r)
486 return FALSE;
490 return TRUE;
493 /* Return the section that should be marked against GC for a given
494 relocation. */
496 static asection *
497 m32c_elf_gc_mark_hook
498 (asection * sec,
499 struct bfd_link_info * info ATTRIBUTE_UNUSED,
500 Elf_Internal_Rela * rel,
501 struct elf_link_hash_entry * h,
502 Elf_Internal_Sym * sym)
504 if (h != NULL)
506 switch (ELF32_R_TYPE (rel->r_info))
508 default:
509 switch (h->root.type)
511 case bfd_link_hash_defined:
512 case bfd_link_hash_defweak:
513 return h->root.u.def.section;
515 case bfd_link_hash_common:
516 return h->root.u.c.p->section;
518 default:
519 break;
523 else
525 if (!(elf_bad_symtab (sec->owner)
526 && ELF_ST_BIND (sym->st_info) != STB_LOCAL)
527 && ! ((sym->st_shndx <= 0 || sym->st_shndx >= SHN_LORESERVE)
528 && sym->st_shndx != SHN_COMMON))
530 return bfd_section_from_elf_index (sec->owner, sym->st_shndx);
534 return NULL;
537 /* Update the got entry reference counts for the section being removed. */
539 static bfd_boolean
540 m32c_elf_gc_sweep_hook
541 (bfd * abfd ATTRIBUTE_UNUSED,
542 struct bfd_link_info * info ATTRIBUTE_UNUSED,
543 asection * sec ATTRIBUTE_UNUSED,
544 const Elf_Internal_Rela * relocs ATTRIBUTE_UNUSED)
546 return TRUE;
549 /* We support 16-bit pointers to code above 64k by generating a thunk
550 below 64k containing a JMP instruction to the final address. */
552 static bfd_boolean
553 m32c_elf_check_relocs
554 (bfd * abfd,
555 struct bfd_link_info * info,
556 asection * sec,
557 const Elf_Internal_Rela * relocs)
559 Elf_Internal_Shdr * symtab_hdr;
560 struct elf_link_hash_entry ** sym_hashes;
561 struct elf_link_hash_entry ** sym_hashes_end;
562 const Elf_Internal_Rela * rel;
563 const Elf_Internal_Rela * rel_end;
564 bfd_vma *local_plt_offsets;
565 asection *splt;
566 bfd *dynobj;
568 if (info->relocatable)
569 return TRUE;
571 symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
572 sym_hashes = elf_sym_hashes (abfd);
573 local_plt_offsets = elf_local_got_offsets (abfd);
574 splt = NULL;
575 dynobj = elf_hash_table(info)->dynobj;
577 sym_hashes_end = sym_hashes + symtab_hdr->sh_size/sizeof (Elf32_External_Sym);
578 if (!elf_bad_symtab (abfd))
579 sym_hashes_end -= symtab_hdr->sh_info;
581 rel_end = relocs + sec->reloc_count;
582 for (rel = relocs; rel < rel_end; rel++)
584 struct elf_link_hash_entry *h;
585 unsigned long r_symndx;
586 bfd_vma *offset;
588 r_symndx = ELF32_R_SYM (rel->r_info);
589 if (r_symndx < symtab_hdr->sh_info)
590 h = NULL;
591 else
593 h = sym_hashes[r_symndx - symtab_hdr->sh_info];
594 while (h->root.type == bfd_link_hash_indirect
595 || h->root.type == bfd_link_hash_warning)
596 h = (struct elf_link_hash_entry *) h->root.u.i.link;
599 switch (ELF32_R_TYPE (rel->r_info))
601 /* This relocation describes a 16-bit pointer to a function.
602 We may need to allocate a thunk in low memory; reserve memory
603 for it now. */
604 case R_M32C_16:
605 if (dynobj == NULL)
606 elf_hash_table (info)->dynobj = dynobj = abfd;
607 if (splt == NULL)
609 splt = bfd_get_section_by_name (dynobj, ".plt");
610 if (splt == NULL)
612 splt = bfd_make_section (dynobj, ".plt");
613 if (splt == NULL
614 || ! bfd_set_section_flags (dynobj, splt,
615 (SEC_ALLOC
616 | SEC_LOAD
617 | SEC_HAS_CONTENTS
618 | SEC_IN_MEMORY
619 | SEC_LINKER_CREATED
620 | SEC_READONLY
621 | SEC_CODE))
622 || ! bfd_set_section_alignment (dynobj, splt, 1))
623 return FALSE;
627 if (h != NULL)
628 offset = &h->plt.offset;
629 else
631 if (local_plt_offsets == NULL)
633 size_t size;
634 unsigned int i;
636 size = symtab_hdr->sh_info * sizeof (bfd_vma);
637 local_plt_offsets = (bfd_vma *) bfd_alloc (abfd, size);
638 if (local_plt_offsets == NULL)
639 return FALSE;
640 elf_local_got_offsets (abfd) = local_plt_offsets;
642 for (i = 0; i < symtab_hdr->sh_info; i++)
643 local_plt_offsets[i] = (bfd_vma) -1;
645 offset = &local_plt_offsets[r_symndx];
648 if (*offset == (bfd_vma) -1)
650 *offset = splt->size;
651 splt->size += 4;
653 break;
657 return TRUE;
660 /* This must exist if dynobj is ever set. */
662 static bfd_boolean
663 m32c_elf_finish_dynamic_sections (bfd *abfd ATTRIBUTE_UNUSED,
664 struct bfd_link_info *info)
666 bfd *dynobj;
667 asection *splt;
669 /* As an extra sanity check, verify that all plt entries have
670 been filled in. */
672 if ((dynobj = elf_hash_table (info)->dynobj) != NULL
673 && (splt = bfd_get_section_by_name (dynobj, ".plt")) != NULL)
675 bfd_byte *contents = splt->contents;
676 unsigned int i, size = splt->size;
677 for (i = 0; i < size; i += 4)
679 unsigned int x = bfd_get_32 (dynobj, contents + i);
680 BFD_ASSERT (x != 0);
684 return TRUE;
687 static bfd_boolean
688 m32c_elf_always_size_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
689 struct bfd_link_info *info)
691 bfd *dynobj;
692 asection *splt;
694 if (info->relocatable)
695 return TRUE;
697 dynobj = elf_hash_table (info)->dynobj;
698 if (dynobj == NULL)
699 return TRUE;
701 splt = bfd_get_section_by_name (dynobj, ".plt");
702 BFD_ASSERT (splt != NULL);
704 splt->contents = (bfd_byte *) bfd_zalloc (dynobj, splt->size);
705 if (splt->contents == NULL)
706 return FALSE;
708 return TRUE;
711 /* Function to set the ELF flag bits. */
713 static bfd_boolean
714 m32c_elf_set_private_flags (bfd *abfd, flagword flags)
716 elf_elfheader (abfd)->e_flags = flags;
717 elf_flags_init (abfd) = TRUE;
718 return TRUE;
721 /* Merge backend specific data from an object file to the output
722 object file when linking. */
724 static bfd_boolean
725 m32c_elf_merge_private_bfd_data (bfd *ibfd, bfd *obfd)
727 flagword old_flags, old_partial;
728 flagword new_flags, new_partial;
729 bfd_boolean error = FALSE;
730 char new_opt[80];
731 char old_opt[80];
733 new_opt[0] = old_opt[0] = '\0';
734 new_flags = elf_elfheader (ibfd)->e_flags;
735 old_flags = elf_elfheader (obfd)->e_flags;
737 #ifdef DEBUG
738 (*_bfd_error_handler) ("old_flags = 0x%.8lx, new_flags = 0x%.8lx, init = %s, filename = %s",
739 old_flags, new_flags, elf_flags_init (obfd) ? "yes" : "no",
740 bfd_get_filename (ibfd));
741 #endif
743 if (!elf_flags_init (obfd))
745 /* First call, no flags set. */
746 elf_flags_init (obfd) = TRUE;
747 elf_elfheader (obfd)->e_flags = new_flags;
750 else if (new_flags == old_flags)
751 /* Compatible flags are ok. */
754 else /* Possibly incompatible flags. */
756 /* Warn if different cpu is used (allow a specific cpu to override
757 the generic cpu). */
758 new_partial = (new_flags & EF_M32C_CPU_MASK);
759 old_partial = (old_flags & EF_M32C_CPU_MASK);
760 if (new_partial == old_partial)
763 else
765 switch (new_partial)
767 default: strcat (new_opt, " -m16c"); break;
768 case EF_M32C_CPU_M16C: strcat (new_opt, " -m16c"); break;
769 case EF_M32C_CPU_M32C: strcat (new_opt, " -m32c"); break;
772 switch (old_partial)
774 default: strcat (old_opt, " -m16c"); break;
775 case EF_M32C_CPU_M16C: strcat (old_opt, " -m16c"); break;
776 case EF_M32C_CPU_M32C: strcat (old_opt, " -m32c"); break;
780 /* Print out any mismatches from above. */
781 if (new_opt[0])
783 error = TRUE;
784 (*_bfd_error_handler)
785 (_("%s: compiled with %s and linked with modules compiled with %s"),
786 bfd_get_filename (ibfd), new_opt, old_opt);
789 new_flags &= ~ EF_M32C_ALL_FLAGS;
790 old_flags &= ~ EF_M32C_ALL_FLAGS;
792 /* Warn about any other mismatches. */
793 if (new_flags != old_flags)
795 error = TRUE;
796 (*_bfd_error_handler)
797 (_("%s: uses different e_flags (0x%lx) fields than previous modules (0x%lx)"),
798 bfd_get_filename (ibfd), (long)new_flags, (long)old_flags);
802 if (error)
803 bfd_set_error (bfd_error_bad_value);
805 return !error;
809 static bfd_boolean
810 m32c_elf_print_private_bfd_data (bfd *abfd, PTR ptr)
812 FILE *file = (FILE *) ptr;
813 flagword flags;
815 BFD_ASSERT (abfd != NULL && ptr != NULL);
817 /* Print normal ELF private data. */
818 _bfd_elf_print_private_bfd_data (abfd, ptr);
820 flags = elf_elfheader (abfd)->e_flags;
821 fprintf (file, _("private flags = 0x%lx:"), (long)flags);
823 switch (flags & EF_M32C_CPU_MASK)
825 default: break;
826 case EF_M32C_CPU_M16C: fprintf (file, " -m16c"); break;
827 case EF_M32C_CPU_M32C: fprintf (file, " -m32c"); break;
830 fputc ('\n', file);
831 return TRUE;
834 /* Return the MACH for an e_flags value. */
836 static int
837 elf32_m32c_machine (bfd *abfd)
839 switch (elf_elfheader (abfd)->e_flags & EF_M32C_CPU_MASK)
841 case EF_M32C_CPU_M16C: return bfd_mach_m16c;
842 case EF_M32C_CPU_M32C: return bfd_mach_m32c;
845 return bfd_mach_m16c;
848 static bfd_boolean
849 m32c_elf_object_p (bfd *abfd)
851 bfd_default_set_arch_mach (abfd, bfd_arch_m32c,
852 elf32_m32c_machine (abfd));
853 return TRUE;
857 #ifdef DEBUG
858 static void
859 dump_symtab (bfd * abfd, void *internal_syms, void *external_syms)
861 size_t locsymcount;
862 Elf_Internal_Sym *isymbuf;
863 Elf_Internal_Sym *isymend;
864 Elf_Internal_Sym *isym;
865 Elf_Internal_Shdr *symtab_hdr;
866 bfd_boolean free_internal = 0, free_external = 0;
867 char * st_info_str;
868 char * st_info_stb_str;
869 char * st_other_str;
870 char * st_shndx_str;
872 if (! internal_syms)
874 internal_syms = bfd_malloc (1000);
875 free_internal = 1;
877 if (! external_syms)
879 external_syms = bfd_malloc (1000);
880 free_external = 1;
883 symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
884 locsymcount = symtab_hdr->sh_size / get_elf_backend_data(abfd)->s->sizeof_sym;
885 if (free_internal)
886 isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr,
887 symtab_hdr->sh_info, 0,
888 internal_syms, external_syms, NULL);
889 else
890 isymbuf = internal_syms;
891 isymend = isymbuf + locsymcount;
893 for (isym = isymbuf ; isym < isymend ; isym++)
895 switch (ELF_ST_TYPE (isym->st_info))
897 case STT_FUNC: st_info_str = "STT_FUNC";
898 case STT_SECTION: st_info_str = "STT_SECTION";
899 case STT_SRELC: st_info_str = "STT_SRELC";
900 case STT_FILE: st_info_str = "STT_FILE";
901 case STT_OBJECT: st_info_str = "STT_OBJECT";
902 case STT_TLS: st_info_str = "STT_TLS";
903 default: st_info_str = "";
905 switch (ELF_ST_BIND (isym->st_info))
907 case STB_LOCAL: st_info_stb_str = "STB_LOCAL";
908 case STB_GLOBAL: st_info_stb_str = "STB_GLOBAL";
909 default: st_info_stb_str = "";
911 switch (ELF_ST_VISIBILITY (isym->st_other))
913 case STV_DEFAULT: st_other_str = "STV_DEFAULT";
914 case STV_INTERNAL: st_other_str = "STV_INTERNAL";
915 case STV_PROTECTED: st_other_str = "STV_PROTECTED";
916 default: st_other_str = "";
918 switch (isym->st_shndx)
920 case SHN_ABS: st_shndx_str = "SHN_ABS";
921 case SHN_COMMON: st_shndx_str = "SHN_COMMON";
922 case SHN_UNDEF: st_shndx_str = "SHN_UNDEF";
923 default: st_shndx_str = "";
926 printf ("isym = %p st_value = %lx st_size = %lx st_name = (%lu) %s "
927 "st_info = (%d) %s %s st_other = (%d) %s st_shndx = (%d) %s\n",
928 isym,
929 (unsigned long) isym->st_value,
930 (unsigned long) isym->st_size,
931 isym->st_name,
932 bfd_elf_string_from_elf_section (abfd, symtab_hdr->sh_link,
933 isym->st_name),
934 isym->st_info, st_info_str, st_info_stb_str,
935 isym->st_other, st_other_str,
936 isym->st_shndx, st_shndx_str);
938 if (free_internal)
939 free (internal_syms);
940 if (free_external)
941 free (external_syms);
944 static char *
945 m32c_get_reloc (long reloc)
947 if (0 <= reloc && reloc < R_M32C_max)
948 return m32c_elf_howto_table[reloc].name;
949 else
950 return "";
952 #endif /* DEBUG */
954 /* Handle relaxing. */
956 /* A subroutine of m32c_elf_relax_section. If the global symbol H
957 is within the low 64k, remove any entry for it in the plt. */
959 struct relax_plt_data
961 asection *splt;
962 bfd_boolean *again;
965 static bfd_boolean
966 m32c_relax_plt_check (struct elf_link_hash_entry *h,
967 PTR xdata)
969 struct relax_plt_data *data = (struct relax_plt_data *) xdata;
971 if (h->root.type == bfd_link_hash_warning)
972 h = (struct elf_link_hash_entry *) h->root.u.i.link;
974 if (h->plt.offset != (bfd_vma) -1)
976 bfd_vma address;
978 if (h->root.type == bfd_link_hash_undefined
979 || h->root.type == bfd_link_hash_undefweak)
980 address = 0;
981 else
982 address = (h->root.u.def.section->output_section->vma
983 + h->root.u.def.section->output_offset
984 + h->root.u.def.value);
986 if (address <= 0xffff)
988 h->plt.offset = -1;
989 data->splt->size -= 4;
990 *data->again = TRUE;
994 return TRUE;
997 /* A subroutine of m32c_elf_relax_section. If the global symbol H
998 previously had a plt entry, give it a new entry offset. */
1000 static bfd_boolean
1001 m32c_relax_plt_realloc (struct elf_link_hash_entry *h,
1002 PTR xdata)
1004 bfd_vma *entry = (bfd_vma *) xdata;
1006 if (h->root.type == bfd_link_hash_warning)
1007 h = (struct elf_link_hash_entry *) h->root.u.i.link;
1009 if (h->plt.offset != (bfd_vma) -1)
1011 h->plt.offset = *entry;
1012 *entry += 4;
1015 return TRUE;
1018 static bfd_boolean
1019 m32c_elf_relax_plt_section (bfd *dynobj,
1020 asection *splt,
1021 struct bfd_link_info *info,
1022 bfd_boolean *again)
1024 struct relax_plt_data relax_plt_data;
1025 bfd *ibfd;
1027 /* Assume nothing changes. */
1028 *again = FALSE;
1030 if (info->relocatable)
1031 return TRUE;
1033 /* We only relax the .plt section at the moment. */
1034 if (dynobj != elf_hash_table (info)->dynobj
1035 || strcmp (splt->name, ".plt") != 0)
1036 return TRUE;
1038 /* Quick check for an empty plt. */
1039 if (splt->size == 0)
1040 return TRUE;
1042 /* Map across all global symbols; see which ones happen to
1043 fall in the low 64k. */
1044 relax_plt_data.splt = splt;
1045 relax_plt_data.again = again;
1046 elf_link_hash_traverse (elf_hash_table (info), m32c_relax_plt_check,
1047 &relax_plt_data);
1049 /* Likewise for local symbols, though that's somewhat less convenient
1050 as we have to walk the list of input bfds and swap in symbol data. */
1051 for (ibfd = info->input_bfds; ibfd ; ibfd = ibfd->link_next)
1053 bfd_vma *local_plt_offsets = elf_local_got_offsets (ibfd);
1054 Elf_Internal_Shdr *symtab_hdr;
1055 Elf_Internal_Sym *isymbuf = NULL;
1056 unsigned int idx;
1058 if (! local_plt_offsets)
1059 continue;
1061 symtab_hdr = &elf_tdata (ibfd)->symtab_hdr;
1062 if (symtab_hdr->sh_info != 0)
1064 isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
1065 if (isymbuf == NULL)
1066 isymbuf = bfd_elf_get_elf_syms (ibfd, symtab_hdr,
1067 symtab_hdr->sh_info, 0,
1068 NULL, NULL, NULL);
1069 if (isymbuf == NULL)
1070 return FALSE;
1073 for (idx = 0; idx < symtab_hdr->sh_info; ++idx)
1075 Elf_Internal_Sym *isym;
1076 asection *tsec;
1077 bfd_vma address;
1079 if (local_plt_offsets[idx] == (bfd_vma) -1)
1080 continue;
1082 isym = &isymbuf[idx];
1083 if (isym->st_shndx == SHN_UNDEF)
1084 continue;
1085 else if (isym->st_shndx == SHN_ABS)
1086 tsec = bfd_abs_section_ptr;
1087 else if (isym->st_shndx == SHN_COMMON)
1088 tsec = bfd_com_section_ptr;
1089 else
1090 tsec = bfd_section_from_elf_index (ibfd, isym->st_shndx);
1092 address = (tsec->output_section->vma
1093 + tsec->output_offset
1094 + isym->st_value);
1095 if (address <= 0xffff)
1097 local_plt_offsets[idx] = -1;
1098 splt->size -= 4;
1099 *again = TRUE;
1103 if (isymbuf != NULL
1104 && symtab_hdr->contents != (unsigned char *) isymbuf)
1106 if (! info->keep_memory)
1107 free (isymbuf);
1108 else
1110 /* Cache the symbols for elf_link_input_bfd. */
1111 symtab_hdr->contents = (unsigned char *) isymbuf;
1116 /* If we changed anything, walk the symbols again to reallocate
1117 .plt entry addresses. */
1118 if (*again && splt->size > 0)
1120 bfd_vma entry = 0;
1122 elf_link_hash_traverse (elf_hash_table (info),
1123 m32c_relax_plt_realloc, &entry);
1125 for (ibfd = info->input_bfds; ibfd ; ibfd = ibfd->link_next)
1127 bfd_vma *local_plt_offsets = elf_local_got_offsets (ibfd);
1128 unsigned int nlocals = elf_tdata (ibfd)->symtab_hdr.sh_info;
1129 unsigned int idx;
1131 if (! local_plt_offsets)
1132 continue;
1134 for (idx = 0; idx < nlocals; ++idx)
1135 if (local_plt_offsets[idx] != (bfd_vma) -1)
1137 local_plt_offsets[idx] = entry;
1138 entry += 4;
1143 return TRUE;
1146 struct relax_reloc_s
1148 int machine;
1149 int opcode_mask;
1150 bfd_vma opcode; /* original opcode or insn part */
1151 int relax_backward; /* lbound */
1152 int relax_forward; /* hbound */
1153 int value_shift;
1154 int mask;
1155 int new_opcode; /* new opcode */
1156 int old_reloc; /* old relocation */
1157 int new_reloc; /* new relocation */
1158 int use_pcrel;
1159 int delete_n; /* # bytes differ between original and new */
1161 static struct relax_reloc_s relax_reloc [] =
1163 #if 0
1165 bfd_mach_m16c,
1166 0xff,
1167 0xfc, /* jmp.a */
1168 -32768,
1169 32767,
1171 0xffffff00,
1172 0xf4, /* jmp.w */
1173 R_M32C_8_ELABEL24,
1174 R_M32C_8_PCREL16,
1179 bfd_mach_m32c,
1180 0xff,
1181 0xcc, /* jmp.a */
1182 -32768,
1183 32767,
1185 0xffffff00,
1186 0xce, /* jmp.w */
1187 R_M32C_8_ELABEL24,
1188 R_M32C_8_PCREL16,
1193 bfd_mach_m32c,
1194 0xff,
1195 0xcd, /* jsr.a */
1196 -32768,
1197 32767,
1199 0xffffff00,
1200 0xcf, /* jsr.w */
1201 R_M32C_8_ELABEL24,
1202 R_M32C_8_PCREL16,
1207 bfd_mach_m16c,
1208 0xff,
1209 0xf4, /* jmp.w */
1210 -128,
1211 127,
1213 0xffffff00,
1214 0xfe, /* jmp.b */
1215 R_M32C_8_PCREL16,
1216 R_M32C_8_PCREL8,
1221 bfd_mach_m32c,
1222 0xff,
1223 0xce, /* jmp.w */
1224 -128,
1225 127,
1227 0xffffff00,
1228 0xbb, /* jmp.b */
1229 R_M32C_8_PCREL16,
1230 R_M32C_8_PCREL8,
1235 bfd_mach_m32c,
1236 0xc0f6,
1237 0x8096, /* dest */
1239 0xffff,
1241 0xffff3fff,
1242 0xc000, /* abs16 */
1243 R_M32C_24_ABS24,
1244 R_M32C_24_ABS16,
1249 bfd_mach_m32c,
1250 0xc0f6,
1251 0x80a6, /* dest */
1253 0xffff,
1255 0xffff3fff,
1256 0xc000, /* abs16 */
1257 R_M32C_32_ABS24,
1258 R_M32C_32_ABS16,
1263 bfd_mach_m32c,
1264 0xc0f6,
1265 0x80b6, /* dest */
1267 0xffff,
1269 0xffff3fff,
1270 0xc000, /* abs16 */
1271 R_M32C_40_ABS24,
1272 R_M32C_40_ABS16,
1277 bfd_mach_m32c,
1278 0x30f0,
1279 0x20b0, /* src */
1281 0xffff,
1283 0xffffcfff,
1284 0x3000, /* abs16 */
1285 R_M32C_16_ABS24,
1286 R_M32C_16_ABS16,
1291 bfd_mach_m32c,
1292 0xc086,
1293 0x8086, /* dest */
1295 0xffff,
1297 0xffff3fff,
1298 0xc000, /* abs16 */
1299 R_M32C_16_ABS24,
1300 R_M32C_16_ABS16,
1304 #endif
1306 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1309 static bfd_boolean
1310 m32c_elf_relax_section
1311 (bfd * abfd,
1312 asection * sec,
1313 struct bfd_link_info * link_info,
1314 bfd_boolean * again)
1316 Elf_Internal_Shdr *symtab_hdr;
1317 Elf_Internal_Shdr *shndx_hdr;
1318 Elf_Internal_Rela *internal_relocs;
1319 Elf_Internal_Rela *free_relocs = NULL;
1320 Elf_Internal_Rela *irel, *irelend;
1321 bfd_byte * contents = NULL;
1322 bfd_byte * free_contents = NULL;
1323 Elf32_External_Sym *extsyms = NULL;
1324 Elf32_External_Sym *free_extsyms = NULL;
1325 Elf_External_Sym_Shndx *shndx_buf = NULL;
1326 int machine;
1328 if (abfd == elf_hash_table (link_info)->dynobj
1329 && strcmp (sec->name, ".plt") == 0)
1330 return m32c_elf_relax_plt_section (abfd, sec, link_info, again);
1332 /* Assume nothing changes. */
1333 *again = FALSE;
1335 machine = elf32_m32c_machine (abfd);
1337 /* We don't have to do anything for a relocatable link, if
1338 this section does not have relocs, or if this is not a
1339 code section. */
1340 if (link_info->relocatable
1341 || (sec->flags & SEC_RELOC) == 0
1342 || sec->reloc_count == 0
1343 || (sec->flags & SEC_CODE) == 0)
1344 return TRUE;
1346 /* Relaxing doesn't quite work right yet. */
1347 return TRUE;
1349 symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
1350 shndx_hdr = &elf_tdata (abfd)->symtab_shndx_hdr;
1352 /* Get a copy of the native relocations. */
1353 internal_relocs = (_bfd_elf_link_read_relocs
1354 (abfd, sec, (PTR) NULL, (Elf_Internal_Rela *) NULL,
1355 link_info->keep_memory));
1356 if (internal_relocs == NULL)
1357 goto error_return;
1358 if (! link_info->keep_memory)
1359 free_relocs = internal_relocs;
1361 /* Walk through them looking for relaxing opportunities. */
1362 irelend = internal_relocs + sec->reloc_count;
1364 for (irel = internal_relocs; irel < irelend; irel++)
1366 bfd_vma symval;
1367 bfd_vma insn;
1368 bfd_vma pc;
1369 bfd_signed_vma pcrel_value;
1370 bfd_vma addend;
1371 int to_delete;
1372 int i;
1374 /* Get the section contents. */
1375 if (contents == NULL)
1377 if (elf_section_data (sec)->this_hdr.contents != NULL)
1378 contents = elf_section_data (sec)->this_hdr.contents;
1379 /* Go get them off disk. */
1380 else if (!bfd_malloc_and_get_section (abfd, sec, &contents))
1381 goto error_return;
1384 /* Read this BFD's symbols if we haven't done so already. */
1385 if (extsyms == NULL)
1387 /* Get cached copy if it exists. */
1388 if (symtab_hdr->contents != NULL)
1389 extsyms = (Elf32_External_Sym *) symtab_hdr->contents;
1390 else
1392 bfd_size_type amt = symtab_hdr->sh_size;
1394 /* Go get them off disk. */
1395 extsyms = (Elf32_External_Sym *) bfd_malloc (amt);
1396 if (extsyms == NULL)
1397 goto error_return;
1398 free_extsyms = extsyms;
1399 if (bfd_seek (abfd, symtab_hdr->sh_offset, SEEK_SET) != 0
1400 || bfd_bread (extsyms, amt, abfd) != amt)
1401 goto error_return;
1402 symtab_hdr->contents = (bfd_byte *) extsyms;
1405 if (shndx_hdr->sh_size != 0)
1407 bfd_size_type amt;
1409 amt = symtab_hdr->sh_info;
1410 amt *= sizeof (Elf_External_Sym_Shndx);
1411 shndx_buf = (Elf_External_Sym_Shndx *) bfd_malloc (amt);
1412 if (shndx_buf == NULL)
1413 goto error_return;
1414 if (bfd_seek (abfd, shndx_hdr->sh_offset, SEEK_SET) != 0
1415 || bfd_bread ((PTR) shndx_buf, amt, abfd) != amt)
1416 goto error_return;
1417 shndx_hdr->contents = (bfd_byte *) shndx_buf;
1421 /* Get the value of the symbol referred to by the reloc. */
1422 if (ELF32_R_SYM (irel->r_info) < symtab_hdr->sh_info)
1424 /* A local symbol. */
1425 Elf32_External_Sym *esym;
1426 Elf_External_Sym_Shndx *shndx;
1427 Elf_Internal_Sym isym;
1429 esym = extsyms + ELF32_R_SYM (irel->r_info);
1430 shndx = shndx_buf + (shndx_buf ? ELF32_R_SYM (irel->r_info) : 0);
1431 bfd_elf32_swap_symbol_in (abfd, esym, shndx, &isym);
1433 symval = (isym.st_value
1434 + sec->output_section->vma
1435 + sec->output_offset);
1437 else
1439 unsigned long indx;
1440 struct elf_link_hash_entry *h;
1442 /* An external symbol. */
1443 indx = ELF32_R_SYM (irel->r_info) - symtab_hdr->sh_info;
1444 h = elf_sym_hashes (abfd)[indx];
1445 BFD_ASSERT (h != NULL);
1447 if (h->root.type != bfd_link_hash_defined
1448 && h->root.type != bfd_link_hash_defweak)
1449 /* This appears to be a reference to an undefined
1450 symbol. Just ignore it--it will be caught by the
1451 regular reloc processing. */
1452 continue;
1454 symval = (h->root.u.def.value
1455 + h->root.u.def.section->output_section->vma
1456 + h->root.u.def.section->output_offset);
1459 /* There will always be room for the relaxed insn, since it is smaller
1460 than the one it would replace. */
1461 BFD_ASSERT (irel->r_offset <= sec->size - 2);
1463 insn = bfd_get_16 (abfd, contents + irel->r_offset + 0);
1465 addend = irel->r_addend;
1466 for (i = 0; relax_reloc[i].machine; i++)
1468 #ifdef DEBUG
1469 _bfd_error_handler ("insn %x %d mask %x opcode %x =%x\n",
1470 insn, i, relax_reloc[i].opcode_mask,
1471 relax_reloc[i].opcode,
1472 (insn & relax_reloc[i].opcode_mask) == relax_reloc[i].opcode);
1473 #endif
1474 if (!(machine == relax_reloc[i].machine
1475 && (insn & relax_reloc[i].opcode_mask) == relax_reloc[i].opcode
1476 && (relax_reloc[i].old_reloc
1477 == (int) ELF32_R_TYPE(irel->r_info))))
1478 continue;
1480 /* At this point we've confirmed we have a matching insn. Now
1481 ensure the operand is in range. */
1482 if (relax_reloc[i].use_pcrel)
1484 pc = sec->output_section->vma + sec->output_offset
1485 + irel->r_offset;
1486 pcrel_value = symval - pc;
1487 #ifndef USE_REL /* put in for learning purposes */
1488 pcrel_value += addend;
1489 #else
1490 addend = bfd_get_signed_16 (abfd, contents + irel->r_offset + 2);
1491 pcrel_value += addend;
1492 #endif
1494 else
1495 pcrel_value = symval;
1497 if (pcrel_value >= relax_reloc[i].relax_backward
1498 && pcrel_value < relax_reloc[i].relax_forward + 2)
1500 /* We can relax to a shorter operand. */
1501 insn = (insn & relax_reloc[i].mask) | relax_reloc[i].new_opcode;
1503 to_delete = relax_reloc[i].delete_n;
1505 /* Rewrite the insn. */
1506 bfd_put_16 (abfd, insn, contents + irel->r_offset);
1508 /* Set the new reloc type. */
1509 irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
1510 relax_reloc[i].new_reloc);
1511 irel->r_addend = pcrel_value;
1513 else
1514 continue;
1516 #ifdef DEBUG
1517 _bfd_error_handler ("insn %x pc %x index %d mask %x shift %d delete %d\n"
1518 "old reloc %s new reloc %s",
1519 insn, sec->output_section->vma
1520 + sec->output_offset + irel->r_offset + 2,
1521 i, relax_reloc[i].opcode_mask,
1522 relax_reloc[i].value_shift, to_delete,
1523 m32c_get_reloc (relax_reloc[i].old_reloc),
1524 m32c_get_reloc (relax_reloc[i].new_reloc));
1525 #endif
1527 /* Note that we've changed the relocs, section contents, etc. */
1528 elf_section_data (sec)->relocs = internal_relocs;
1529 free_relocs = NULL;
1531 elf_section_data (sec)->this_hdr.contents = contents;
1532 free_contents = NULL;
1534 symtab_hdr->contents = (bfd_byte *) extsyms;
1535 free_extsyms = NULL;
1537 /* Delete TO_DELETE bytes of data. */
1538 if (! m32c_elf_relax_delete_bytes
1539 (abfd, sec, irel->r_offset + relax_reloc[i].value_shift,
1540 to_delete))
1541 goto error_return;
1542 } /* next relax_reloc */
1543 } /* next relocation */
1545 if (free_relocs != NULL)
1547 free (free_relocs);
1548 free_relocs = NULL;
1551 if (free_contents != NULL)
1553 if (! link_info->keep_memory)
1554 free (free_contents);
1555 /* Cache the section contents for elf_link_input_bfd. */
1556 else
1557 elf_section_data (sec)->this_hdr.contents = contents;
1559 free_contents = NULL;
1562 if (shndx_buf != NULL)
1564 shndx_hdr->contents = NULL;
1565 free (shndx_buf);
1568 if (free_extsyms != NULL)
1570 if (! link_info->keep_memory)
1571 free (free_extsyms);
1572 /* Cache the symbols for elf_link_input_bfd. */
1573 else
1574 symtab_hdr->contents = NULL /* (unsigned char *) extsyms*/;
1576 free_extsyms = NULL;
1578 /* elf_link_input_bfd expects internal syms. */
1579 symtab_hdr->contents = NULL;
1581 return TRUE;
1583 error_return:
1584 if (free_relocs != NULL)
1585 free (free_relocs);
1586 if (free_contents != NULL)
1587 free (free_contents);
1588 if (shndx_buf != NULL)
1590 shndx_hdr->contents = NULL;
1591 free (shndx_buf);
1593 if (free_extsyms != NULL)
1594 free (free_extsyms);
1595 return FALSE;
1598 /* Delete some bytes from a section while relaxing. */
1600 static bfd_boolean
1601 m32c_elf_relax_delete_bytes
1602 (bfd * abfd,
1603 asection * sec,
1604 bfd_vma addr,
1605 int count)
1607 Elf_Internal_Shdr *symtab_hdr;
1608 Elf_Internal_Shdr *shndx_hdr;
1609 int sec_shndx;
1610 bfd_byte *contents;
1611 Elf_Internal_Rela *irel;
1612 Elf_Internal_Rela *irelend;
1613 Elf_Internal_Rela *irelalign;
1614 bfd_vma toaddr;
1615 Elf32_External_Sym *esym;
1616 Elf32_External_Sym *esymend;
1617 Elf32_External_Sym *extsyms;
1618 Elf_External_Sym_Shndx *shndx_buf;
1619 Elf_External_Sym_Shndx *shndx;
1620 struct elf_link_hash_entry ** sym_hashes;
1621 struct elf_link_hash_entry ** end_hashes;
1622 unsigned int symcount;
1624 symtab_hdr = & elf_tdata (abfd)->symtab_hdr;
1625 extsyms = (Elf32_External_Sym *) symtab_hdr->contents;
1626 shndx_hdr = & elf_tdata (abfd)->symtab_shndx_hdr;
1627 shndx_buf = (Elf_External_Sym_Shndx *) shndx_hdr->contents;
1628 sec_shndx = _bfd_elf_section_from_bfd_section (abfd, sec);
1629 contents = elf_section_data (sec)->this_hdr.contents;
1631 /* The deletion must stop at the next ALIGN reloc for an aligment
1632 power larger than the number of bytes we are deleting. */
1633 irelalign = NULL;
1634 toaddr = sec->size;
1636 irel = elf_section_data (sec)->relocs;
1637 irelend = irel + sec->reloc_count;
1639 /* Actually delete the bytes. */
1640 memmove (contents + addr, contents + addr + count, (size_t) (toaddr - addr - count));
1641 sec->size -= count;
1643 /* Adjust all the relocs. */
1644 for (irel = elf_section_data (sec)->relocs; irel < irelend; irel ++)
1646 /* Get the new reloc address. */
1647 if (irel->r_offset > addr && irel->r_offset < toaddr)
1648 irel->r_offset -= count;
1649 if (irel->r_addend > addr && irel->r_addend < toaddr)
1650 irel->r_addend -= count;
1653 /* Adjust the local symbols defined in this section. */
1654 shndx = shndx_buf;
1655 esym = extsyms;
1656 esymend = esym + symtab_hdr->sh_info;
1657 for (; esym < esymend; esym++, shndx = (shndx ? shndx + 1 : NULL))
1659 Elf_Internal_Sym isym;
1660 Elf_External_Sym_Shndx dummy;
1662 bfd_elf32_swap_symbol_in (abfd, esym, shndx, &isym);
1664 if ((int) isym.st_shndx == sec_shndx
1665 && isym.st_value > addr
1666 && isym.st_value < toaddr)
1668 isym.st_value -= count;
1669 bfd_elf32_swap_symbol_out (abfd, &isym, (PTR) esym, (PTR) & dummy);
1673 /* Now adjust the global symbols defined in this section. */
1674 symcount = (symtab_hdr->sh_size / sizeof (Elf32_External_Sym)
1675 - symtab_hdr->sh_info);
1676 sym_hashes = elf_sym_hashes (abfd);
1677 // sym_hashes += symtab_hdr->sh_info;
1678 end_hashes = sym_hashes + symcount;
1680 for (; sym_hashes < end_hashes; sym_hashes ++)
1682 struct elf_link_hash_entry * sym_hash = * sym_hashes;
1684 if (sym_hash &&
1685 ( sym_hash->root.type == bfd_link_hash_defined
1686 || sym_hash->root.type == bfd_link_hash_defweak)
1687 && sym_hash->root.u.def.section == sec
1688 && sym_hash->root.u.def.value > addr
1689 && sym_hash->root.u.def.value < toaddr)
1690 sym_hash->root.u.def.value -= count;
1693 return TRUE;
1697 #define ELF_ARCH bfd_arch_m32c
1698 #define ELF_MACHINE_CODE EM_M32C
1699 #define ELF_MAXPAGESIZE 0x1000
1701 #if 0
1702 #define TARGET_BIG_SYM bfd_elf32_m32c_vec
1703 #define TARGET_BIG_NAME "elf32-m32c"
1704 #else
1705 #define TARGET_LITTLE_SYM bfd_elf32_m32c_vec
1706 #define TARGET_LITTLE_NAME "elf32-m32c"
1707 #endif
1709 #define elf_info_to_howto_rel NULL
1710 #define elf_info_to_howto m32c_info_to_howto_rela
1711 #define elf_backend_object_p m32c_elf_object_p
1712 #define elf_backend_relocate_section m32c_elf_relocate_section
1713 #define elf_backend_gc_mark_hook m32c_elf_gc_mark_hook
1714 #define elf_backend_gc_sweep_hook m32c_elf_gc_sweep_hook
1715 #define elf_backend_check_relocs m32c_elf_check_relocs
1716 #define elf_backend_object_p m32c_elf_object_p
1717 #define elf_symbol_leading_char ('_')
1718 #define elf_backend_always_size_sections \
1719 m32c_elf_always_size_sections
1720 #define elf_backend_finish_dynamic_sections \
1721 m32c_elf_finish_dynamic_sections
1723 #define elf_backend_can_gc_sections 1
1725 #define bfd_elf32_bfd_reloc_type_lookup m32c_reloc_type_lookup
1726 #define bfd_elf32_bfd_relax_section m32c_elf_relax_section
1727 #define bfd_elf32_bfd_set_private_flags m32c_elf_set_private_flags
1728 #define bfd_elf32_bfd_merge_private_bfd_data m32c_elf_merge_private_bfd_data
1729 #define bfd_elf32_bfd_print_private_bfd_data m32c_elf_print_private_bfd_data
1731 #include "elf32-target.h"