Check in correct version of previous patch.
[deliverable/binutils-gdb.git] / bfd / elf32-m32c.c
CommitLineData
49f58d10
JB
1/* M16C/M32C specific support for 32-bit ELF.
2 Copyright (C) 2005
3 Free Software Foundation, Inc.
4
5 This file is part of BFD, the Binary File Descriptor library.
6
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.
11
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.
16
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. */
20
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"
27
28/* Forward declarations. */
29static reloc_howto_type * m32c_reloc_type_lookup
30 (bfd *, bfd_reloc_code_real_type);
31static void m32c_info_to_howto_rela
32 (bfd *, arelent *, Elf_Internal_Rela *);
33static bfd_boolean m32c_elf_relocate_section
34 (bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *, Elf_Internal_Rela *, Elf_Internal_Sym *, asection **);
35static bfd_boolean m32c_elf_gc_sweep_hook
36 (bfd *, struct bfd_link_info *, asection *, const Elf_Internal_Rela *);
37static asection * m32c_elf_gc_mark_hook
38 (asection *, struct bfd_link_info *, Elf_Internal_Rela *, struct elf_link_hash_entry *, Elf_Internal_Sym *);
39static bfd_boolean m32c_elf_check_relocs
40 (bfd *, struct bfd_link_info *, asection *, const Elf_Internal_Rela *);
41static bfd_boolean m32c_elf_relax_delete_bytes (bfd *, asection *, bfd_vma, int);
42#ifdef DEBUG
43static char * m32c_get_reloc (long reloc);
44#endif
45static bfd_boolean m32c_elf_relax_section
46(bfd *abfd, asection *sec, struct bfd_link_info *link_info, bfd_boolean *again);
47
48
49static reloc_howto_type m32c_elf_howto_table [] =
50{
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 */
65
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 */
79
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 */
93
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 */
107
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 */
121
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 */
fd54057a
DD
135
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 */
149
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 */
163
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 */
177
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 */
49f58d10
JB
191};
192\f
193/* Map BFD reloc types to M32C ELF reloc types. */
194
195struct m32c_reloc_map
196{
197 bfd_reloc_code_real_type bfd_reloc_val;
198 unsigned int m32c_reloc_val;
199};
200
201static const struct m32c_reloc_map m32c_reloc_map [] =
202{
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 },
fd54057a
DD
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 }
49f58d10
JB
213};
214
215static reloc_howto_type *
216m32c_reloc_type_lookup
217 (bfd * abfd ATTRIBUTE_UNUSED,
218 bfd_reloc_code_real_type code)
219{
220 unsigned int i;
221
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];
225
226 return NULL;
227}
228
229/* Set the howto pointer for an M32C ELF reloc. */
230
231static void
232m32c_info_to_howto_rela
233 (bfd * abfd ATTRIBUTE_UNUSED,
234 arelent * cache_ptr,
235 Elf_Internal_Rela * dst)
236{
237 unsigned int r_type;
238
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];
242}
243
244\f
245
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.
250
251 The RELOCATE_SECTION function is called by the new ELF backend linker
252 to handle the relocations for a section.
253
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.
257
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.
261
262 This function does not have to worry about setting the reloc
263 address or the reloc symbol index.
264
265 LOCAL_SYMS is a pointer to the swapped in local symbols.
266
267 LOCAL_SECTIONS is an array giving the section in the input file
268 corresponding to the st_shndx field of each local symbol.
269
270 The global hash table entry for the global symbols can be found
271 via elf_sym_hashes (input_bfd).
272
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. */
278
279static bfd_boolean
280m32c_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)
289{
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;
296
297 symtab_hdr = & elf_tdata (input_bfd)->symtab_hdr;
298 sym_hashes = elf_sym_hashes (input_bfd);
299 relend = relocs + input_section->reloc_count;
300
301 dynobj = elf_hash_table (info)->dynobj;
302 splt = NULL;
303 if (dynobj != NULL)
304 splt = bfd_get_section_by_name (dynobj, ".plt");
305
306 for (rel = relocs; rel < relend; rel ++)
307 {
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;
317
318 r_type = ELF32_R_TYPE (rel->r_info);
319
320 r_symndx = ELF32_R_SYM (rel->r_info);
321
322 if (info->relocatable)
323 {
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)
329 {
330 sym = local_syms + r_symndx;
331
332 if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
333 {
334 sec = local_sections [r_symndx];
335 rel->r_addend += sec->output_offset + sym->st_value;
336 }
337 }
338
339 continue;
340 }
341
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;
347
348 if (r_symndx < symtab_hdr->sh_info)
349 {
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);
355
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;
359 }
360 else
361 {
362 h = sym_hashes [r_symndx - symtab_hdr->sh_info];
363
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;
367
368 name = h->root.root.string;
369
370 if (h->root.type == bfd_link_hash_defined
371 || h->root.type == bfd_link_hash_defweak)
372 {
373 sec = h->root.u.def.section;
374 relocation = (h->root.u.def.value
375 + sec->output_section->vma
376 + sec->output_offset);
377 }
378 else if (h->root.type == bfd_link_hash_undefweak)
379 {
380 relocation = 0;
381 }
382 else
383 {
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;
389 }
390 }
391
392 switch (ELF32_R_TYPE (rel->r_info))
393 {
394 case R_M32C_16:
395 {
396 bfd_vma *plt_offset;
397
398 if (h != NULL)
399 plt_offset = &h->plt.offset;
400 else
401 plt_offset = elf_local_got_offsets (input_bfd) + r_symndx;
402
403 /* printf("%s: rel %x plt %d\n", h ? h->root.root.string : "(none)",
404 relocation, *plt_offset);*/
405 if (relocation <= 0xffff)
406 {
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);
410 }
411 else
412 {
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);
416
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)
420 {
421 unsigned int x;
422
423 x = 0x000000fc; /* jmpf */
424 x |= (relocation << 8) & 0xffffff00;
425 bfd_put_32 (input_bfd, x, splt->contents + *plt_offset);
426 *plt_offset |= 1;
427 }
428
429 relocation = (splt->output_section->vma
430 + splt->output_offset
431 + (*plt_offset & -2));
432 }
433 }
434 break;
fd54057a
DD
435
436 case R_M32C_HI8:
437 case R_M32C_HI16:
438 relocation >>= 16;
439 break;
49f58d10
JB
440 }
441
442 r = _bfd_final_link_relocate (howto, input_bfd, input_section,
443 contents, rel->r_offset, relocation,
444 rel->r_addend);
445
446 if (r != bfd_reloc_ok)
447 {
448 const char * msg = (const char *) NULL;
449
450 switch (r)
451 {
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;
457
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;
463
464 case bfd_reloc_outofrange:
465 msg = _("internal error: out of range error");
466 break;
467
468 case bfd_reloc_notsupported:
469 msg = _("internal error: unsupported relocation error");
470 break;
471
472 case bfd_reloc_dangerous:
473 msg = _("internal error: dangerous relocation");
474 break;
475
476 default:
477 msg = _("internal error: unknown error");
478 break;
479 }
480
481 if (msg)
482 r = info->callbacks->warning
483 (info, msg, name, input_bfd, input_section, rel->r_offset);
484
485 if (! r)
486 return FALSE;
487 }
488 }
489
490 return TRUE;
491}
492\f
493/* Return the section that should be marked against GC for a given
494 relocation. */
495
496static asection *
497m32c_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)
503{
504 if (h != NULL)
505 {
506 switch (ELF32_R_TYPE (rel->r_info))
507 {
508 default:
509 switch (h->root.type)
510 {
511 case bfd_link_hash_defined:
512 case bfd_link_hash_defweak:
513 return h->root.u.def.section;
514
515 case bfd_link_hash_common:
516 return h->root.u.c.p->section;
517
518 default:
519 break;
520 }
521 }
522 }
523 else
524 {
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))
529 {
530 return bfd_section_from_elf_index (sec->owner, sym->st_shndx);
531 }
532 }
533
534 return NULL;
535}
536
537/* Update the got entry reference counts for the section being removed. */
538
539static bfd_boolean
540m32c_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)
545{
546 return TRUE;
547}
548
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. */
551
552static bfd_boolean
553m32c_elf_check_relocs
554 (bfd * abfd,
555 struct bfd_link_info * info,
556 asection * sec,
557 const Elf_Internal_Rela * relocs)
558{
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;
567
568 if (info->relocatable)
569 return TRUE;
570
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;
576
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;
580
581 rel_end = relocs + sec->reloc_count;
582 for (rel = relocs; rel < rel_end; rel++)
583 {
584 struct elf_link_hash_entry *h;
585 unsigned long r_symndx;
586 bfd_vma *offset;
587
588 r_symndx = ELF32_R_SYM (rel->r_info);
589 if (r_symndx < symtab_hdr->sh_info)
590 h = NULL;
591 else
592 {
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;
597 }
598
599 switch (ELF32_R_TYPE (rel->r_info))
600 {
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)
608 {
609 splt = bfd_get_section_by_name (dynobj, ".plt");
610 if (splt == NULL)
611 {
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;
624 }
625 }
626
627 if (h != NULL)
628 offset = &h->plt.offset;
629 else
630 {
631 if (local_plt_offsets == NULL)
632 {
633 size_t size;
634 unsigned int i;
635
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;
641
642 for (i = 0; i < symtab_hdr->sh_info; i++)
643 local_plt_offsets[i] = (bfd_vma) -1;
644 }
645 offset = &local_plt_offsets[r_symndx];
646 }
647
648 if (*offset == (bfd_vma) -1)
649 {
650 *offset = splt->size;
651 splt->size += 4;
652 }
653 break;
654 }
655 }
656
657 return TRUE;
658}
659
660/* This must exist if dynobj is ever set. */
661
662static bfd_boolean
663m32c_elf_finish_dynamic_sections (bfd *abfd ATTRIBUTE_UNUSED,
664 struct bfd_link_info *info)
665{
666 bfd *dynobj;
667 asection *splt;
668
669 /* As an extra sanity check, verify that all plt entries have
670 been filled in. */
671
672 if ((dynobj = elf_hash_table (info)->dynobj) != NULL
673 && (splt = bfd_get_section_by_name (dynobj, ".plt")) != NULL)
674 {
675 bfd_byte *contents = splt->contents;
676 unsigned int i, size = splt->size;
677 for (i = 0; i < size; i += 4)
678 {
679 unsigned int x = bfd_get_32 (dynobj, contents + i);
680 BFD_ASSERT (x != 0);
681 }
682 }
683
684 return TRUE;
685}
686
687static bfd_boolean
688m32c_elf_always_size_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
689 struct bfd_link_info *info)
690{
691 bfd *dynobj;
692 asection *splt;
693
694 if (info->relocatable)
695 return TRUE;
696
697 dynobj = elf_hash_table (info)->dynobj;
698 if (dynobj == NULL)
699 return TRUE;
700
701 splt = bfd_get_section_by_name (dynobj, ".plt");
702 BFD_ASSERT (splt != NULL);
703
704 splt->contents = (bfd_byte *) bfd_zalloc (dynobj, splt->size);
705 if (splt->contents == NULL)
706 return FALSE;
707
708 return TRUE;
709}
710\f
711/* Function to set the ELF flag bits. */
712
713static bfd_boolean
714m32c_elf_set_private_flags (bfd *abfd, flagword flags)
715{
716 elf_elfheader (abfd)->e_flags = flags;
717 elf_flags_init (abfd) = TRUE;
718 return TRUE;
719}
720
721/* Merge backend specific data from an object file to the output
722 object file when linking. */
723
724static bfd_boolean
725m32c_elf_merge_private_bfd_data (bfd *ibfd, bfd *obfd)
726{
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];
732
733 new_opt[0] = old_opt[0] = '\0';
734 new_flags = elf_elfheader (ibfd)->e_flags;
735 old_flags = elf_elfheader (obfd)->e_flags;
736
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
742
743 if (!elf_flags_init (obfd))
744 {
745 /* First call, no flags set. */
746 elf_flags_init (obfd) = TRUE;
747 elf_elfheader (obfd)->e_flags = new_flags;
748 }
749
750 else if (new_flags == old_flags)
751 /* Compatible flags are ok. */
752 ;
753
754 else /* Possibly incompatible flags. */
755 {
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)
761 ;
762
763 else
764 {
765 switch (new_partial)
766 {
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;
770 }
771
772 switch (old_partial)
773 {
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;
777 }
778 }
779
780 /* Print out any mismatches from above. */
781 if (new_opt[0])
782 {
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);
787 }
788
789 new_flags &= ~ EF_M32C_ALL_FLAGS;
790 old_flags &= ~ EF_M32C_ALL_FLAGS;
791
792 /* Warn about any other mismatches. */
793 if (new_flags != old_flags)
794 {
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);
799 }
800 }
801
802 if (error)
803 bfd_set_error (bfd_error_bad_value);
804
805 return !error;
806}
807
808\f
809static bfd_boolean
810m32c_elf_print_private_bfd_data (bfd *abfd, PTR ptr)
811{
812 FILE *file = (FILE *) ptr;
813 flagword flags;
814
815 BFD_ASSERT (abfd != NULL && ptr != NULL);
816
817 /* Print normal ELF private data. */
818 _bfd_elf_print_private_bfd_data (abfd, ptr);
819
820 flags = elf_elfheader (abfd)->e_flags;
821 fprintf (file, _("private flags = 0x%lx:"), (long)flags);
822
823 switch (flags & EF_M32C_CPU_MASK)
824 {
825 default: break;
826 case EF_M32C_CPU_M16C: fprintf (file, " -m16c"); break;
827 case EF_M32C_CPU_M32C: fprintf (file, " -m32c"); break;
828 }
829
830 fputc ('\n', file);
831 return TRUE;
832}
833
834/* Return the MACH for an e_flags value. */
835
836static int
837elf32_m32c_machine (bfd *abfd)
838{
839 switch (elf_elfheader (abfd)->e_flags & EF_M32C_CPU_MASK)
840 {
841 case EF_M32C_CPU_M16C: return bfd_mach_m16c;
842 case EF_M32C_CPU_M32C: return bfd_mach_m32c;
843 }
844
845 return bfd_mach_m16c;
846}
847
848static bfd_boolean
849m32c_elf_object_p (bfd *abfd)
850{
851 bfd_default_set_arch_mach (abfd, bfd_arch_m32c,
852 elf32_m32c_machine (abfd));
853 return TRUE;
854}
855 \f
856
857#ifdef DEBUG
858static void
859dump_symtab (bfd * abfd, void *internal_syms, void *external_syms)
860{
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;
871
872 if (! internal_syms)
873 {
874 internal_syms = bfd_malloc (1000);
875 free_internal = 1;
876 }
877 if (! external_syms)
878 {
879 external_syms = bfd_malloc (1000);
880 free_external = 1;
881 }
882
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;
892
893 for (isym = isymbuf ; isym < isymend ; isym++)
894 {
895 switch (ELF_ST_TYPE (isym->st_info))
896 {
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 = "";
904 }
905 switch (ELF_ST_BIND (isym->st_info))
906 {
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 = "";
910 }
911 switch (ELF_ST_VISIBILITY (isym->st_other))
912 {
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 = "";
917 }
918 switch (isym->st_shndx)
919 {
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 = "";
924 }
925
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);
937 }
938 if (free_internal)
939 free (internal_syms);
940 if (free_external)
941 free (external_syms);
942}
943
944static char *
945m32c_get_reloc (long reloc)
946{
947 if (0 <= reloc && reloc < R_M32C_max)
948 return m32c_elf_howto_table[reloc].name;
949 else
950 return "";
951}
952#endif /* DEBUG */
953
954/* Handle relaxing. */
955
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. */
958
959struct relax_plt_data
960{
961 asection *splt;
962 bfd_boolean *again;
963};
964
965static bfd_boolean
966m32c_relax_plt_check (struct elf_link_hash_entry *h,
967 PTR xdata)
968{
969 struct relax_plt_data *data = (struct relax_plt_data *) xdata;
970
971 if (h->root.type == bfd_link_hash_warning)
972 h = (struct elf_link_hash_entry *) h->root.u.i.link;
973
974 if (h->plt.offset != (bfd_vma) -1)
975 {
976 bfd_vma address;
977
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);
985
986 if (address <= 0xffff)
987 {
988 h->plt.offset = -1;
989 data->splt->size -= 4;
990 *data->again = TRUE;
991 }
992 }
993
994 return TRUE;
995}
996
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. */
999
1000static bfd_boolean
1001m32c_relax_plt_realloc (struct elf_link_hash_entry *h,
1002 PTR xdata)
1003{
1004 bfd_vma *entry = (bfd_vma *) xdata;
1005
1006 if (h->root.type == bfd_link_hash_warning)
1007 h = (struct elf_link_hash_entry *) h->root.u.i.link;
1008
1009 if (h->plt.offset != (bfd_vma) -1)
1010 {
1011 h->plt.offset = *entry;
1012 *entry += 4;
1013 }
1014
1015 return TRUE;
1016}
1017
1018static bfd_boolean
1019m32c_elf_relax_plt_section (bfd *dynobj,
1020 asection *splt,
1021 struct bfd_link_info *info,
1022 bfd_boolean *again)
1023{
1024 struct relax_plt_data relax_plt_data;
1025 bfd *ibfd;
1026
1027 /* Assume nothing changes. */
1028 *again = FALSE;
1029
1030 if (info->relocatable)
1031 return TRUE;
1032
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;
1037
1038 /* Quick check for an empty plt. */
1039 if (splt->size == 0)
1040 return TRUE;
1041
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);
1048
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)
1052 {
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;
1057
1058 if (! local_plt_offsets)
1059 continue;
1060
1061 symtab_hdr = &elf_tdata (ibfd)->symtab_hdr;
1062 if (symtab_hdr->sh_info != 0)
1063 {
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;
1071 }
1072
1073 for (idx = 0; idx < symtab_hdr->sh_info; ++idx)
1074 {
1075 Elf_Internal_Sym *isym;
1076 asection *tsec;
1077 bfd_vma address;
1078
1079 if (local_plt_offsets[idx] == (bfd_vma) -1)
1080 continue;
1081
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);
1091
1092 address = (tsec->output_section->vma
1093 + tsec->output_offset
1094 + isym->st_value);
1095 if (address <= 0xffff)
1096 {
1097 local_plt_offsets[idx] = -1;
1098 splt->size -= 4;
1099 *again = TRUE;
1100 }
1101 }
1102
1103 if (isymbuf != NULL
1104 && symtab_hdr->contents != (unsigned char *) isymbuf)
1105 {
1106 if (! info->keep_memory)
1107 free (isymbuf);
1108 else
1109 {
1110 /* Cache the symbols for elf_link_input_bfd. */
1111 symtab_hdr->contents = (unsigned char *) isymbuf;
1112 }
1113 }
1114 }
1115
1116 /* If we changed anything, walk the symbols again to reallocate
1117 .plt entry addresses. */
1118 if (*again && splt->size > 0)
1119 {
1120 bfd_vma entry = 0;
1121
1122 elf_link_hash_traverse (elf_hash_table (info),
1123 m32c_relax_plt_realloc, &entry);
1124
1125 for (ibfd = info->input_bfds; ibfd ; ibfd = ibfd->link_next)
1126 {
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;
1130
1131 if (! local_plt_offsets)
1132 continue;
1133
1134 for (idx = 0; idx < nlocals; ++idx)
1135 if (local_plt_offsets[idx] != (bfd_vma) -1)
1136 {
1137 local_plt_offsets[idx] = entry;
1138 entry += 4;
1139 }
1140 }
1141 }
1142
1143 return TRUE;
1144}
1145
1146struct relax_reloc_s
1147{
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 */
1160};
1161static struct relax_reloc_s relax_reloc [] =
1162 {
1163#if 0
1164 {
1165 bfd_mach_m16c,
1166 0xff,
1167 0xfc, /* jmp.a */
1168 -32768,
1169 32767,
1170 2,
1171 0xffffff00,
1172 0xf4, /* jmp.w */
1173 R_M32C_8_ELABEL24,
1174 R_M32C_8_PCREL16,
1175 1,
1176 1,
1177 },
1178 {
1179 bfd_mach_m32c,
1180 0xff,
1181 0xcc, /* jmp.a */
1182 -32768,
1183 32767,
1184 2,
1185 0xffffff00,
1186 0xce, /* jmp.w */
1187 R_M32C_8_ELABEL24,
1188 R_M32C_8_PCREL16,
1189 1,
1190 1,
1191 },
1192 {
1193 bfd_mach_m32c,
1194 0xff,
1195 0xcd, /* jsr.a */
1196 -32768,
1197 32767,
1198 2,
1199 0xffffff00,
1200 0xcf, /* jsr.w */
1201 R_M32C_8_ELABEL24,
1202 R_M32C_8_PCREL16,
1203 1,
1204 1,
1205 },
1206 {
1207 bfd_mach_m16c,
1208 0xff,
1209 0xf4, /* jmp.w */
1210 -128,
1211 127,
1212 2,
1213 0xffffff00,
1214 0xfe, /* jmp.b */
1215 R_M32C_8_PCREL16,
1216 R_M32C_8_PCREL8,
1217 1,
1218 1,
1219 },
1220 {
1221 bfd_mach_m32c,
1222 0xff,
1223 0xce, /* jmp.w */
1224 -128,
1225 127,
1226 2,
1227 0xffffff00,
1228 0xbb, /* jmp.b */
1229 R_M32C_8_PCREL16,
1230 R_M32C_8_PCREL8,
1231 1,
1232 1,
1233 },
1234 {
1235 bfd_mach_m32c,
1236 0xc0f6,
1237 0x8096, /* dest */
1238 0,
1239 0xffff,
1240 3,
1241 0xffff3fff,
1242 0xc000, /* abs16 */
1243 R_M32C_24_ABS24,
1244 R_M32C_24_ABS16,
1245 0,
1246 1,
1247 },
1248 {
1249 bfd_mach_m32c,
1250 0xc0f6,
1251 0x80a6, /* dest */
1252 0,
1253 0xffff,
1254 4,
1255 0xffff3fff,
1256 0xc000, /* abs16 */
1257 R_M32C_32_ABS24,
1258 R_M32C_32_ABS16,
1259 0,
1260 1,
1261 },
1262 {
1263 bfd_mach_m32c,
1264 0xc0f6,
1265 0x80b6, /* dest */
1266 0,
1267 0xffff,
1268 5,
1269 0xffff3fff,
1270 0xc000, /* abs16 */
1271 R_M32C_40_ABS24,
1272 R_M32C_40_ABS16,
1273 0,
1274 1,
1275 },
1276 {
1277 bfd_mach_m32c,
1278 0x30f0,
1279 0x20b0, /* src */
1280 0,
1281 0xffff,
1282 2,
1283 0xffffcfff,
1284 0x3000, /* abs16 */
1285 R_M32C_16_ABS24,
1286 R_M32C_16_ABS16,
1287 0,
1288 1,
1289 },
1290 {
1291 bfd_mach_m32c,
1292 0xc086,
1293 0x8086, /* dest */
1294 0,
1295 0xffff,
1296 2,
1297 0xffff3fff,
1298 0xc000, /* abs16 */
1299 R_M32C_16_ABS24,
1300 R_M32C_16_ABS16,
1301 0,
1302 1,
1303 },
1304#endif
1305 {
1306 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1307 }
1308 };
1309static bfd_boolean
1310m32c_elf_relax_section
1311 (bfd * abfd,
1312 asection * sec,
1313 struct bfd_link_info * link_info,
1314 bfd_boolean * again)
1315{
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;
1327
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);
1331
1332 /* Assume nothing changes. */
1333 *again = FALSE;
1334
1335 machine = elf32_m32c_machine (abfd);
1336
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;
1345
1346 /* Relaxing doesn't quite work right yet. */
1347 return TRUE;
1348
1349 symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
1350 shndx_hdr = &elf_tdata (abfd)->symtab_shndx_hdr;
1351
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;
1360
1361 /* Walk through them looking for relaxing opportunities. */
1362 irelend = internal_relocs + sec->reloc_count;
1363
1364 for (irel = internal_relocs; irel < irelend; irel++)
1365 {
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;
1373
1374 /* Get the section contents. */
1375 if (contents == NULL)
1376 {
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;
1382 }
1383
1384 /* Read this BFD's symbols if we haven't done so already. */
1385 if (extsyms == NULL)
1386 {
1387 /* Get cached copy if it exists. */
1388 if (symtab_hdr->contents != NULL)
1389 extsyms = (Elf32_External_Sym *) symtab_hdr->contents;
1390 else
1391 {
1392 bfd_size_type amt = symtab_hdr->sh_size;
1393
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;
1403 }
1404
1405 if (shndx_hdr->sh_size != 0)
1406 {
1407 bfd_size_type amt;
1408
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;
1418 }
1419 }
1420
1421 /* Get the value of the symbol referred to by the reloc. */
1422 if (ELF32_R_SYM (irel->r_info) < symtab_hdr->sh_info)
1423 {
1424 /* A local symbol. */
1425 Elf32_External_Sym *esym;
1426 Elf_External_Sym_Shndx *shndx;
1427 Elf_Internal_Sym isym;
1428
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);
1432
1433 symval = (isym.st_value
1434 + sec->output_section->vma
1435 + sec->output_offset);
1436 }
1437 else
1438 {
1439 unsigned long indx;
1440 struct elf_link_hash_entry *h;
1441
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);
1446
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;
1453
1454 symval = (h->root.u.def.value
1455 + h->root.u.def.section->output_section->vma
1456 + h->root.u.def.section->output_offset);
1457 }
1458
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);
1462
1463 insn = bfd_get_16 (abfd, contents + irel->r_offset + 0);
1464
1465 addend = irel->r_addend;
1466 for (i = 0; relax_reloc[i].machine; i++)
1467 {
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;
1479
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)
1483 {
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
1493 }
1494 else
1495 pcrel_value = symval;
1496
1497 if (pcrel_value >= relax_reloc[i].relax_backward
1498 && pcrel_value < relax_reloc[i].relax_forward + 2)
1499 {
1500 /* We can relax to a shorter operand. */
1501 insn = (insn & relax_reloc[i].mask) | relax_reloc[i].new_opcode;
1502
1503 to_delete = relax_reloc[i].delete_n;
1504
1505 /* Rewrite the insn. */
1506 bfd_put_16 (abfd, insn, contents + irel->r_offset);
1507
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;
1512 }
1513 else
1514 continue;
1515
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
1526
1527 /* Note that we've changed the relocs, section contents, etc. */
1528 elf_section_data (sec)->relocs = internal_relocs;
1529 free_relocs = NULL;
1530
1531 elf_section_data (sec)->this_hdr.contents = contents;
1532 free_contents = NULL;
1533
1534 symtab_hdr->contents = (bfd_byte *) extsyms;
1535 free_extsyms = NULL;
1536
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 */
1544
1545 if (free_relocs != NULL)
1546 {
1547 free (free_relocs);
1548 free_relocs = NULL;
1549 }
1550
1551 if (free_contents != NULL)
1552 {
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;
1558
1559 free_contents = NULL;
1560 }
1561
1562 if (shndx_buf != NULL)
1563 {
1564 shndx_hdr->contents = NULL;
1565 free (shndx_buf);
1566 }
1567
1568 if (free_extsyms != NULL)
1569 {
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*/;
1575
1576 free_extsyms = NULL;
1577 }
1578 /* elf_link_input_bfd expects internal syms. */
1579 symtab_hdr->contents = NULL;
1580
1581 return TRUE;
1582
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)
1589 {
1590 shndx_hdr->contents = NULL;
1591 free (shndx_buf);
1592 }
1593 if (free_extsyms != NULL)
1594 free (free_extsyms);
1595 return FALSE;
1596}
1597
1598/* Delete some bytes from a section while relaxing. */
1599
1600static bfd_boolean
1601m32c_elf_relax_delete_bytes
1602 (bfd * abfd,
1603 asection * sec,
1604 bfd_vma addr,
1605 int count)
1606{
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;
1623
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;
1630
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;
1635
1636 irel = elf_section_data (sec)->relocs;
1637 irelend = irel + sec->reloc_count;
1638
1639 /* Actually delete the bytes. */
1640 memmove (contents + addr, contents + addr + count, (size_t) (toaddr - addr - count));
1641 sec->size -= count;
1642
1643 /* Adjust all the relocs. */
1644 for (irel = elf_section_data (sec)->relocs; irel < irelend; irel ++)
1645 {
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;
1651 }
1652
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))
1658 {
1659 Elf_Internal_Sym isym;
1660 Elf_External_Sym_Shndx dummy;
1661
1662 bfd_elf32_swap_symbol_in (abfd, esym, shndx, &isym);
1663
1664 if ((int) isym.st_shndx == sec_shndx
1665 && isym.st_value > addr
1666 && isym.st_value < toaddr)
1667 {
1668 isym.st_value -= count;
1669 bfd_elf32_swap_symbol_out (abfd, &isym, (PTR) esym, (PTR) & dummy);
1670 }
1671 }
1672
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;
1679
1680 for (; sym_hashes < end_hashes; sym_hashes ++)
1681 {
1682 struct elf_link_hash_entry * sym_hash = * sym_hashes;
1683
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;
1691 }
1692
1693 return TRUE;
1694}
1695\f
1696
1697#define ELF_ARCH bfd_arch_m32c
1698#define ELF_MACHINE_CODE EM_M32C
1699#define ELF_MAXPAGESIZE 0x1000
1700
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
1708
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
1722
1723#define elf_backend_can_gc_sections 1
1724
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
1730
1731#include "elf32-target.h"
This page took 0.154989 seconds and 4 git commands to generate.