source: trunk/src/binutils/bfd/elf32-h8300.c@ 2013

Last change on this file since 2013 was 607, checked in by bird, 22 years ago

Initial revision

  • Property cvs2svn:cvs-rev set to 1.1
  • Property svn:eol-style set to native
  • Property svn:executable set to *
File size: 42.8 KB
Line 
1/* BFD back-end for Renesas H8/300 ELF binaries.
2 Copyright 1993, 1995, 1998, 1999, 2001, 2002, 2003
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/h8.h"
26
27static reloc_howto_type *elf32_h8_reloc_type_lookup
28 PARAMS ((bfd *abfd, bfd_reloc_code_real_type code));
29static void elf32_h8_info_to_howto
30 PARAMS ((bfd *, arelent *, Elf_Internal_Rela *));
31static void elf32_h8_info_to_howto_rel
32 PARAMS ((bfd *, arelent *, Elf_Internal_Rela *));
33static unsigned long elf32_h8_mach
34 PARAMS ((flagword));
35static void elf32_h8_final_write_processing
36 PARAMS ((bfd *, bfd_boolean));
37static bfd_boolean elf32_h8_object_p
38 PARAMS ((bfd *));
39static bfd_boolean elf32_h8_merge_private_bfd_data
40 PARAMS ((bfd *, bfd *));
41static bfd_boolean elf32_h8_relax_section
42 PARAMS ((bfd *, asection *, struct bfd_link_info *, bfd_boolean *));
43static bfd_boolean elf32_h8_relax_delete_bytes
44 PARAMS ((bfd *, asection *, bfd_vma, int));
45static bfd_boolean elf32_h8_symbol_address_p
46 PARAMS ((bfd *, asection *, bfd_vma));
47static bfd_byte *elf32_h8_get_relocated_section_contents
48 PARAMS ((bfd *, struct bfd_link_info *, struct bfd_link_order *,
49 bfd_byte *, bfd_boolean, asymbol **));
50static bfd_reloc_status_type elf32_h8_final_link_relocate
51 PARAMS ((unsigned long, bfd *, bfd *, asection *,
52 bfd_byte *, bfd_vma, bfd_vma, bfd_vma,
53 struct bfd_link_info *, asection *, int));
54static bfd_boolean elf32_h8_relocate_section
55 PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *,
56 bfd_byte *, Elf_Internal_Rela *,
57 Elf_Internal_Sym *, asection **));
58static bfd_reloc_status_type special
59 PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
60
61/* This does not include any relocation information, but should be
62 good enough for GDB or objdump to read the file. */
63
64static reloc_howto_type h8_elf_howto_table[] = {
65#define R_H8_NONE_X 0
66 HOWTO (R_H8_NONE, /* type */
67 0, /* rightshift */
68 0, /* size (0 = byte, 1 = short, 2 = long) */
69 0, /* bitsize */
70 FALSE, /* pc_relative */
71 0, /* bitpos */
72 complain_overflow_dont, /* complain_on_overflow */
73 special, /* special_function */
74 "R_H8_NONE", /* name */
75 FALSE, /* partial_inplace */
76 0, /* src_mask */
77 0, /* dst_mask */
78 FALSE), /* pcrel_offset */
79#define R_H8_DIR32_X (R_H8_NONE_X + 1)
80 HOWTO (R_H8_DIR32, /* type */
81 0, /* rightshift */
82 2, /* size (0 = byte, 1 = short, 2 = long) */
83 32, /* bitsize */
84 FALSE, /* pc_relative */
85 0, /* bitpos */
86 complain_overflow_dont, /* complain_on_overflow */
87 special, /* special_function */
88 "R_H8_DIR32", /* name */
89 FALSE, /* partial_inplace */
90 0, /* src_mask */
91 0xffffffff, /* dst_mask */
92 FALSE), /* pcrel_offset */
93#define R_H8_DIR16_X (R_H8_DIR32_X + 1)
94 HOWTO (R_H8_DIR16, /* type */
95 0, /* rightshift */
96 1, /* size (0 = byte, 1 = short, 2 = long) */
97 16, /* bitsize */
98 FALSE, /* pc_relative */
99 0, /* bitpos */
100 complain_overflow_dont, /* complain_on_overflow */
101 special, /* special_function */
102 "R_H8_DIR16", /* name */
103 FALSE, /* partial_inplace */
104 0, /* src_mask */
105 0x0000ffff, /* dst_mask */
106 FALSE), /* pcrel_offset */
107#define R_H8_DIR8_X (R_H8_DIR16_X + 1)
108 HOWTO (R_H8_DIR8, /* type */
109 0, /* rightshift */
110 0, /* size (0 = byte, 1 = short, 2 = long) */
111 8, /* bitsize */
112 FALSE, /* pc_relative */
113 0, /* bitpos */
114 complain_overflow_dont, /* complain_on_overflow */
115 special, /* special_function */
116 "R_H8_DIR16", /* name */
117 FALSE, /* partial_inplace */
118 0, /* src_mask */
119 0x000000ff, /* dst_mask */
120 FALSE), /* pcrel_offset */
121#define R_H8_DIR16A8_X (R_H8_DIR8_X + 1)
122 HOWTO (R_H8_DIR16A8, /* type */
123 0, /* rightshift */
124 1, /* size (0 = byte, 1 = short, 2 = long) */
125 16, /* bitsize */
126 FALSE, /* pc_relative */
127 0, /* bitpos */
128 complain_overflow_bitfield, /* complain_on_overflow */
129 special, /* special_function */
130 "R_H8_DIR16A8", /* name */
131 FALSE, /* partial_inplace */
132 0, /* src_mask */
133 0x0000ffff, /* dst_mask */
134 FALSE), /* pcrel_offset */
135#define R_H8_DIR16R8_X (R_H8_DIR16A8_X + 1)
136 HOWTO (R_H8_DIR16R8, /* type */
137 0, /* rightshift */
138 1, /* size (0 = byte, 1 = short, 2 = long) */
139 16, /* bitsize */
140 FALSE, /* pc_relative */
141 0, /* bitpos */
142 complain_overflow_bitfield, /* complain_on_overflow */
143 special, /* special_function */
144 "R_H8_DIR16R8", /* name */
145 FALSE, /* partial_inplace */
146 0, /* src_mask */
147 0x0000ffff, /* dst_mask */
148 FALSE), /* pcrel_offset */
149#define R_H8_DIR24A8_X (R_H8_DIR16R8_X + 1)
150 HOWTO (R_H8_DIR24A8, /* type */
151 0, /* rightshift */
152 2, /* size (0 = byte, 1 = short, 2 = long) */
153 24, /* bitsize */
154 FALSE, /* pc_relative */
155 0, /* bitpos */
156 complain_overflow_bitfield, /* complain_on_overflow */
157 special, /* special_function */
158 "R_H8_DIR24A8", /* name */
159 TRUE, /* partial_inplace */
160 0xff000000, /* src_mask */
161 0x00ffffff, /* dst_mask */
162 FALSE), /* pcrel_offset */
163#define R_H8_DIR24R8_X (R_H8_DIR24A8_X + 1)
164 HOWTO (R_H8_DIR24R8, /* type */
165 0, /* rightshift */
166 2, /* size (0 = byte, 1 = short, 2 = long) */
167 24, /* bitsize */
168 FALSE, /* pc_relative */
169 0, /* bitpos */
170 complain_overflow_bitfield, /* complain_on_overflow */
171 special, /* special_function */
172 "R_H8_DIR24R8", /* name */
173 TRUE, /* partial_inplace */
174 0xff000000, /* src_mask */
175 0x00ffffff, /* dst_mask */
176 FALSE), /* pcrel_offset */
177#define R_H8_DIR32A16_X (R_H8_DIR24R8_X + 1)
178 HOWTO (R_H8_DIR32A16, /* type */
179 0, /* rightshift */
180 2, /* size (0 = byte, 1 = short, 2 = long) */
181 32, /* bitsize */
182 FALSE, /* pc_relative */
183 0, /* bitpos */
184 complain_overflow_dont, /* complain_on_overflow */
185 special, /* special_function */
186 "R_H8_DIR32", /* name */
187 FALSE, /* partial_inplace */
188 0, /* src_mask */
189 0xffffffff, /* dst_mask */
190 FALSE), /* pcrel_offset */
191#define R_H8_PCREL16_X (R_H8_DIR32A16_X + 1)
192 HOWTO (R_H8_PCREL16, /* type */
193 0, /* rightshift */
194 1, /* size (0 = byte, 1 = short, 2 = long) */
195 16, /* bitsize */
196 TRUE, /* pc_relative */
197 0, /* bitpos */
198 complain_overflow_signed, /* complain_on_overflow */
199 special, /* special_function */
200 "R_H8_PCREL16", /* name */
201 FALSE, /* partial_inplace */
202 0xffff, /* src_mask */
203 0xffff, /* dst_mask */
204 TRUE), /* pcrel_offset */
205#define R_H8_PCREL8_X (R_H8_PCREL16_X + 1)
206 HOWTO (R_H8_PCREL8, /* type */
207 0, /* rightshift */
208 0, /* size (0 = byte, 1 = short, 2 = long) */
209 8, /* bitsize */
210 TRUE, /* pc_relative */
211 0, /* bitpos */
212 complain_overflow_signed, /* complain_on_overflow */
213 special, /* special_function */
214 "R_H8_PCREL8", /* name */
215 FALSE, /* partial_inplace */
216 0xff, /* src_mask */
217 0xff, /* dst_mask */
218 TRUE), /* pcrel_offset */
219};
220
221/* This structure is used to map BFD reloc codes to H8 ELF relocs. */
222
223struct elf_reloc_map {
224 bfd_reloc_code_real_type bfd_reloc_val;
225 unsigned char howto_index;
226};
227
228/* An array mapping BFD reloc codes to SH ELF relocs. */
229
230static const struct elf_reloc_map h8_reloc_map[] = {
231 { BFD_RELOC_NONE, R_H8_NONE_X },
232 { BFD_RELOC_32, R_H8_DIR32_X },
233 { BFD_RELOC_16, R_H8_DIR16_X },
234 { BFD_RELOC_8, R_H8_DIR8_X },
235 { BFD_RELOC_H8_DIR16A8, R_H8_DIR16A8_X },
236 { BFD_RELOC_H8_DIR16R8, R_H8_DIR16R8_X },
237 { BFD_RELOC_H8_DIR24A8, R_H8_DIR24A8_X },
238 { BFD_RELOC_H8_DIR24R8, R_H8_DIR24R8_X },
239 { BFD_RELOC_H8_DIR32A16, R_H8_DIR32A16_X },
240 { BFD_RELOC_16_PCREL, R_H8_PCREL16_X },
241 { BFD_RELOC_8_PCREL, R_H8_PCREL8_X },
242};
243
244
245static reloc_howto_type *
246elf32_h8_reloc_type_lookup (abfd, code)
247 bfd *abfd ATTRIBUTE_UNUSED;
248 bfd_reloc_code_real_type code;
249{
250 unsigned int i;
251
252 for (i = 0; i < sizeof (h8_reloc_map) / sizeof (struct elf_reloc_map); i++)
253 {
254 if (h8_reloc_map[i].bfd_reloc_val == code)
255 return &h8_elf_howto_table[(int) h8_reloc_map[i].howto_index];
256 }
257 return NULL;
258}
259
260static void
261elf32_h8_info_to_howto (abfd, bfd_reloc, elf_reloc)
262 bfd *abfd ATTRIBUTE_UNUSED;
263 arelent *bfd_reloc;
264 Elf_Internal_Rela *elf_reloc;
265{
266 unsigned int r;
267 unsigned int i;
268
269 r = ELF32_R_TYPE (elf_reloc->r_info);
270 for (i = 0; i < sizeof (h8_elf_howto_table) / sizeof (reloc_howto_type); i++)
271 if (h8_elf_howto_table[i].type == r)
272 {
273 bfd_reloc->howto = &h8_elf_howto_table[i];
274 return;
275 }
276 abort ();
277}
278
279static void
280elf32_h8_info_to_howto_rel (abfd, bfd_reloc, elf_reloc)
281 bfd *abfd ATTRIBUTE_UNUSED;
282 arelent *bfd_reloc;
283 Elf_Internal_Rela *elf_reloc ATTRIBUTE_UNUSED;
284{
285 unsigned int r;
286
287 abort ();
288 r = ELF32_R_TYPE (elf_reloc->r_info);
289 bfd_reloc->howto = &h8_elf_howto_table[r];
290}
291
292/* Special handling for H8/300 relocs.
293 We only come here for pcrel stuff and return normally if not an -r link.
294 When doing -r, we can't do any arithmetic for the pcrel stuff, because
295 we support relaxing on the H8/300 series chips. */
296static bfd_reloc_status_type
297special (abfd, reloc_entry, symbol, data, input_section, output_bfd,
298 error_message)
299 bfd *abfd ATTRIBUTE_UNUSED;
300 arelent *reloc_entry ATTRIBUTE_UNUSED;
301 asymbol *symbol ATTRIBUTE_UNUSED;
302 PTR data ATTRIBUTE_UNUSED;
303 asection *input_section ATTRIBUTE_UNUSED;
304 bfd *output_bfd;
305 char **error_message ATTRIBUTE_UNUSED;
306{
307 if (output_bfd == (bfd *) NULL)
308 return bfd_reloc_continue;
309
310 /* Adjust the reloc address to that in the output section. */
311 reloc_entry->address += input_section->output_offset;
312 return bfd_reloc_ok;
313}
314
315/* Perform a relocation as part of a final link. */
316static bfd_reloc_status_type
317elf32_h8_final_link_relocate (r_type, input_bfd, output_bfd,
318 input_section, contents, offset, value,
319 addend, info, sym_sec, is_local)
320 unsigned long r_type;
321 bfd *input_bfd;
322 bfd *output_bfd ATTRIBUTE_UNUSED;
323 asection *input_section ATTRIBUTE_UNUSED;
324 bfd_byte *contents;
325 bfd_vma offset;
326 bfd_vma value;
327 bfd_vma addend;
328 struct bfd_link_info *info ATTRIBUTE_UNUSED;
329 asection *sym_sec ATTRIBUTE_UNUSED;
330 int is_local ATTRIBUTE_UNUSED;
331{
332 bfd_byte *hit_data = contents + offset;
333
334 switch (r_type)
335 {
336
337 case R_H8_NONE:
338 return bfd_reloc_ok;
339
340 case R_H8_DIR32:
341 case R_H8_DIR32A16:
342 case R_H8_DIR24A8:
343 value += addend;
344 bfd_put_32 (input_bfd, value, hit_data);
345 return bfd_reloc_ok;
346
347 case R_H8_DIR16:
348 case R_H8_DIR16A8:
349 case R_H8_DIR16R8:
350 value += addend;
351 bfd_put_16 (input_bfd, value, hit_data);
352 return bfd_reloc_ok;
353
354 /* AKA R_RELBYTE */
355 case R_H8_DIR8:
356 value += addend;
357
358 bfd_put_8 (input_bfd, value, hit_data);
359 return bfd_reloc_ok;
360
361 case R_H8_DIR24R8:
362 value += addend;
363
364 /* HIT_DATA is the address for the first byte for the relocated
365 value. Subtract 1 so that we can manipulate the data in 32bit
366 hunks. */
367 hit_data--;
368
369 /* Clear out the top byte in value. */
370 value &= 0xffffff;
371
372 /* Retrieve the type byte for value from the section contents. */
373 value |= (bfd_get_32 (input_bfd, hit_data) & 0xff000000);
374
375 /* Now scribble it out in one 32bit hunk. */
376 bfd_put_32 (input_bfd, value, hit_data);
377 return bfd_reloc_ok;
378
379 case R_H8_PCREL16:
380 value -= (input_section->output_section->vma
381 + input_section->output_offset);
382 value -= offset;
383 value += addend;
384
385 /* The value is relative to the start of the instruction,
386 not the relocation offset. Subtract 2 to account for
387 this minor issue. */
388 value -= 2;
389
390 bfd_put_16 (input_bfd, value, hit_data);
391 return bfd_reloc_ok;
392
393 case R_H8_PCREL8:
394 value -= (input_section->output_section->vma
395 + input_section->output_offset);
396 value -= offset;
397 value += addend;
398
399 /* The value is relative to the start of the instruction,
400 not the relocation offset. Subtract 1 to account for
401 this minor issue. */
402 value -= 1;
403
404 bfd_put_8 (input_bfd, value, hit_data);
405 return bfd_reloc_ok;
406
407 default:
408 return bfd_reloc_notsupported;
409 }
410}
411
412
413/* Relocate an H8 ELF section. */
414static bfd_boolean
415elf32_h8_relocate_section (output_bfd, info, input_bfd, input_section,
416 contents, relocs, local_syms, local_sections)
417 bfd *output_bfd;
418 struct bfd_link_info *info;
419 bfd *input_bfd;
420 asection *input_section;
421 bfd_byte *contents;
422 Elf_Internal_Rela *relocs;
423 Elf_Internal_Sym *local_syms;
424 asection **local_sections;
425{
426 Elf_Internal_Shdr *symtab_hdr;
427 struct elf_link_hash_entry **sym_hashes;
428 Elf_Internal_Rela *rel, *relend;
429
430 if (info->relocateable)
431 return TRUE;
432
433 symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
434 sym_hashes = elf_sym_hashes (input_bfd);
435
436 rel = relocs;
437 relend = relocs + input_section->reloc_count;
438 for (; rel < relend; rel++)
439 {
440 unsigned int r_type;
441 unsigned long r_symndx;
442 Elf_Internal_Sym *sym;
443 asection *sec;
444 struct elf_link_hash_entry *h;
445 bfd_vma relocation;
446 bfd_reloc_status_type r;
447
448 /* This is a final link. */
449 r_symndx = ELF32_R_SYM (rel->r_info);
450 r_type = ELF32_R_TYPE (rel->r_info);
451 h = NULL;
452 sym = NULL;
453 sec = NULL;
454 if (r_symndx < symtab_hdr->sh_info)
455 {
456 sym = local_syms + r_symndx;
457 sec = local_sections[r_symndx];
458 relocation = _bfd_elf_rela_local_sym (output_bfd, sym, sec, rel);
459 }
460 else
461 {
462 h = sym_hashes[r_symndx - symtab_hdr->sh_info];
463 while (h->root.type == bfd_link_hash_indirect
464 || h->root.type == bfd_link_hash_warning)
465 h = (struct elf_link_hash_entry *) h->root.u.i.link;
466 if (h->root.type == bfd_link_hash_defined
467 || h->root.type == bfd_link_hash_defweak)
468 {
469 sec = h->root.u.def.section;
470 relocation = (h->root.u.def.value
471 + sec->output_section->vma
472 + sec->output_offset);
473 }
474 else if (h->root.type == bfd_link_hash_undefweak)
475 relocation = 0;
476 else
477 {
478 if (! ((*info->callbacks->undefined_symbol)
479 (info, h->root.root.string, input_bfd,
480 input_section, rel->r_offset, TRUE)))
481 return FALSE;
482 relocation = 0;
483 }
484 }
485
486 r = elf32_h8_final_link_relocate (r_type, input_bfd, output_bfd,
487 input_section,
488 contents, rel->r_offset,
489 relocation, rel->r_addend,
490 info, sec, h == NULL);
491
492 if (r != bfd_reloc_ok)
493 {
494 const char *name;
495 const char *msg = (const char *) 0;
496 arelent bfd_reloc;
497 reloc_howto_type *howto;
498
499 elf32_h8_info_to_howto (input_bfd, &bfd_reloc, rel);
500 howto = bfd_reloc.howto;
501
502 if (h != NULL)
503 name = h->root.root.string;
504 else
505 {
506 name = (bfd_elf_string_from_elf_section
507 (input_bfd, symtab_hdr->sh_link, sym->st_name));
508 if (name == NULL || *name == '\0')
509 name = bfd_section_name (input_bfd, sec);
510 }
511
512 switch (r)
513 {
514 case bfd_reloc_overflow:
515 if (! ((*info->callbacks->reloc_overflow)
516 (info, name, howto->name, (bfd_vma) 0,
517 input_bfd, input_section, rel->r_offset)))
518 return FALSE;
519 break;
520
521 case bfd_reloc_undefined:
522 if (! ((*info->callbacks->undefined_symbol)
523 (info, name, input_bfd, input_section,
524 rel->r_offset, TRUE)))
525 return FALSE;
526 break;
527
528 case bfd_reloc_outofrange:
529 msg = _("internal error: out of range error");
530 goto common_error;
531
532 case bfd_reloc_notsupported:
533 msg = _("internal error: unsupported relocation error");
534 goto common_error;
535
536 case bfd_reloc_dangerous:
537 msg = _("internal error: dangerous error");
538 goto common_error;
539
540 default:
541 msg = _("internal error: unknown error");
542 /* fall through */
543
544 common_error:
545 if (!((*info->callbacks->warning)
546 (info, msg, name, input_bfd, input_section,
547 rel->r_offset)))
548 return FALSE;
549 break;
550 }
551 }
552 }
553
554 return TRUE;
555}
556
557/* Object files encode the specific H8 model they were compiled
558 for in the ELF flags field.
559
560 Examine that field and return the proper BFD machine type for
561 the object file. */
562static unsigned long
563elf32_h8_mach (flags)
564 flagword flags;
565{
566 switch (flags & EF_H8_MACH)
567 {
568 case E_H8_MACH_H8300:
569 default:
570 return bfd_mach_h8300;
571
572 case E_H8_MACH_H8300H:
573 return bfd_mach_h8300h;
574
575 case E_H8_MACH_H8300S:
576 return bfd_mach_h8300s;
577
578 case E_H8_MACH_H8300HN:
579 return bfd_mach_h8300hn;
580
581 case E_H8_MACH_H8300SN:
582 return bfd_mach_h8300sn;
583 }
584}
585
586/* The final processing done just before writing out a H8 ELF object
587 file. We use this opportunity to encode the BFD machine type
588 into the flags field in the object file. */
589
590static void
591elf32_h8_final_write_processing (abfd, linker)
592 bfd *abfd;
593 bfd_boolean linker ATTRIBUTE_UNUSED;
594{
595 unsigned long val;
596
597 switch (bfd_get_mach (abfd))
598 {
599 default:
600 case bfd_mach_h8300:
601 val = E_H8_MACH_H8300;
602 break;
603
604 case bfd_mach_h8300h:
605 val = E_H8_MACH_H8300H;
606 break;
607
608 case bfd_mach_h8300s:
609 val = E_H8_MACH_H8300S;
610 break;
611
612 case bfd_mach_h8300hn:
613 val = E_H8_MACH_H8300HN;
614 break;
615
616 case bfd_mach_h8300sn:
617 val = E_H8_MACH_H8300SN;
618 break;
619 }
620
621 elf_elfheader (abfd)->e_flags &= ~ (EF_H8_MACH);
622 elf_elfheader (abfd)->e_flags |= val;
623}
624
625/* Return nonzero if ABFD represents a valid H8 ELF object file; also
626 record the encoded machine type found in the ELF flags. */
627
628static bfd_boolean
629elf32_h8_object_p (abfd)
630 bfd *abfd;
631{
632 bfd_default_set_arch_mach (abfd, bfd_arch_h8300,
633 elf32_h8_mach (elf_elfheader (abfd)->e_flags));
634 return TRUE;
635}
636
637/* Merge backend specific data from an object file to the output
638 object file when linking. The only data we need to copy at this
639 time is the architecture/machine information. */
640
641static bfd_boolean
642elf32_h8_merge_private_bfd_data (ibfd, obfd)
643 bfd *ibfd;
644 bfd *obfd;
645{
646 if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
647 || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
648 return TRUE;
649
650 if (bfd_get_arch (obfd) == bfd_get_arch (ibfd)
651 && bfd_get_mach (obfd) < bfd_get_mach (ibfd))
652 {
653 if (! bfd_set_arch_mach (obfd, bfd_get_arch (ibfd),
654 bfd_get_mach (ibfd)))
655 return FALSE;
656 }
657
658 return TRUE;
659}
660
661/* This function handles relaxing for the H8..
662
663 There's a few relaxing opportunites available on the H8:
664
665 jmp/jsr:24 -> bra/bsr:8 2 bytes
666 The jmp may be completely eliminated if the previous insn is a
667 conditional branch to the insn after the jump. In that case
668 we invert the branch and delete the jump and save 4 bytes.
669
670 bCC:16 -> bCC:8 2 bytes
671 bsr:16 -> bsr:8 2 bytes
672
673 mov.b:16 -> mov.b:8 2 bytes
674 mov.b:24/32 -> mov.b:8 4 bytes
675
676 mov.[bwl]:24/32 -> mov.[bwl]:16 2 bytes */
677
678static bfd_boolean
679elf32_h8_relax_section (abfd, sec, link_info, again)
680 bfd *abfd;
681 asection *sec;
682 struct bfd_link_info *link_info;
683 bfd_boolean *again;
684{
685 Elf_Internal_Shdr *symtab_hdr;
686 Elf_Internal_Rela *internal_relocs;
687 Elf_Internal_Rela *irel, *irelend;
688 bfd_byte *contents = NULL;
689 Elf_Internal_Sym *isymbuf = NULL;
690 static asection *last_input_section = NULL;
691 static Elf_Internal_Rela *last_reloc = NULL;
692
693 /* Assume nothing changes. */
694 *again = FALSE;
695
696 /* We don't have to do anything for a relocateable link, if
697 this section does not have relocs, or if this is not a
698 code section. */
699 if (link_info->relocateable
700 || (sec->flags & SEC_RELOC) == 0
701 || sec->reloc_count == 0
702 || (sec->flags & SEC_CODE) == 0)
703 return TRUE;
704
705 /* If this is the first time we have been called for this section,
706 initialize the cooked size. */
707 if (sec->_cooked_size == 0)
708 sec->_cooked_size = sec->_raw_size;
709
710 symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
711
712 /* Get a copy of the native relocations. */
713 internal_relocs = (_bfd_elf32_link_read_relocs
714 (abfd, sec, (PTR) NULL, (Elf_Internal_Rela *) NULL,
715 link_info->keep_memory));
716 if (internal_relocs == NULL)
717 goto error_return;
718
719 if (sec != last_input_section)
720 last_reloc = NULL;
721
722 last_input_section = sec;
723
724 /* Walk through the relocs looking for relaxing opportunities. */
725 irelend = internal_relocs + sec->reloc_count;
726 for (irel = internal_relocs; irel < irelend; irel++)
727 {
728 bfd_vma symval;
729
730 /* Keep track of the previous reloc so that we can delete
731 some long jumps created by the compiler. */
732 if (irel != internal_relocs)
733 last_reloc = irel - 1;
734
735 if (ELF32_R_TYPE (irel->r_info) != R_H8_DIR24R8
736 && ELF32_R_TYPE (irel->r_info) != R_H8_PCREL16
737 && ELF32_R_TYPE (irel->r_info) != R_H8_DIR16A8
738 && ELF32_R_TYPE (irel->r_info) != R_H8_DIR24A8
739 && ELF32_R_TYPE (irel->r_info) != R_H8_DIR32A16)
740 continue;
741
742 /* Get the section contents if we haven't done so already. */
743 if (contents == NULL)
744 {
745 /* Get cached copy if it exists. */
746 if (elf_section_data (sec)->this_hdr.contents != NULL)
747 contents = elf_section_data (sec)->this_hdr.contents;
748 else
749 {
750 /* Go get them off disk. */
751 contents = (bfd_byte *) bfd_malloc (sec->_raw_size);
752 if (contents == NULL)
753 goto error_return;
754
755 if (! bfd_get_section_contents (abfd, sec, contents,
756 (file_ptr) 0, sec->_raw_size))
757 goto error_return;
758 }
759 }
760
761 /* Read this BFD's local symbols if we haven't done so already. */
762 if (isymbuf == NULL && symtab_hdr->sh_info != 0)
763 {
764 isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
765 if (isymbuf == NULL)
766 isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr,
767 symtab_hdr->sh_info, 0,
768 NULL, NULL, NULL);
769 if (isymbuf == NULL)
770 goto error_return;
771 }
772
773 /* Get the value of the symbol referred to by the reloc. */
774 if (ELF32_R_SYM (irel->r_info) < symtab_hdr->sh_info)
775 {
776 /* A local symbol. */
777 Elf_Internal_Sym *isym;
778 asection *sym_sec;
779
780 isym = isymbuf + ELF32_R_SYM (irel->r_info);
781 sym_sec = bfd_section_from_elf_index (abfd, isym->st_shndx);
782 symval = (isym->st_value
783 + sym_sec->output_section->vma
784 + sym_sec->output_offset);
785 }
786 else
787 {
788 unsigned long indx;
789 struct elf_link_hash_entry *h;
790
791 /* An external symbol. */
792 indx = ELF32_R_SYM (irel->r_info) - symtab_hdr->sh_info;
793 h = elf_sym_hashes (abfd)[indx];
794 BFD_ASSERT (h != NULL);
795 if (h->root.type != bfd_link_hash_defined
796 && h->root.type != bfd_link_hash_defweak)
797 {
798 /* This appears to be a reference to an undefined
799 symbol. Just ignore it--it will be caught by the
800 regular reloc processing. */
801 continue;
802 }
803
804 symval = (h->root.u.def.value
805 + h->root.u.def.section->output_section->vma
806 + h->root.u.def.section->output_offset);
807 }
808
809 /* For simplicity of coding, we are going to modify the section
810 contents, the section relocs, and the BFD symbol table. We
811 must tell the rest of the code not to free up this
812 information. It would be possible to instead create a table
813 of changes which have to be made, as is done in coff-mips.c;
814 that would be more work, but would require less memory when
815 the linker is run. */
816 switch (ELF32_R_TYPE (irel->r_info))
817 {
818 /* Try to turn a 24 bit absolute branch/call into an 8 bit
819 pc-relative branch/call. */
820 case R_H8_DIR24R8:
821 {
822 bfd_vma value = symval + irel->r_addend;
823 bfd_vma dot, gap;
824
825 /* Get the address of this instruction. */
826 dot = (sec->output_section->vma
827 + sec->output_offset + irel->r_offset - 1);
828
829 /* Compute the distance from this insn to the branch target. */
830 gap = value - dot;
831
832 /* If the distance is within -126..+130 inclusive, then we can
833 relax this jump. +130 is valid since the target will move
834 two bytes closer if we do relax this branch. */
835 if ((int) gap >= -126 && (int) gap <= 130)
836 {
837 unsigned char code;
838
839 /* Note that we've changed the relocs, section contents,
840 etc. */
841 elf_section_data (sec)->relocs = internal_relocs;
842 elf_section_data (sec)->this_hdr.contents = contents;
843 symtab_hdr->contents = (unsigned char *) isymbuf;
844
845 /* Get the instruction code being relaxed. */
846 code = bfd_get_8 (abfd, contents + irel->r_offset - 1);
847
848 /* If the previous instruction conditionally jumped around
849 this instruction, we may be able to reverse the condition
850 and redirect the previous instruction to the target of
851 this instruction.
852
853 Such sequences are used by the compiler to deal with
854 long conditional branches.
855
856 Only perform this optimisation for jumps (code 0x5a) not
857 subroutine calls, as otherwise it could transform:
858
859 mov.w r0,r0
860 beq .L1
861 jsr @_bar
862 .L1: rts
863 _bar: rts
864 into:
865 mov.w r0,r0
866 bne _bar
867 rts
868 _bar: rts
869
870 which changes the call (jsr) into a branch (bne). */
871 if (code == 0x5a
872 && (int) gap <= 130
873 && (int) gap >= -128
874 && last_reloc
875 && ELF32_R_TYPE (last_reloc->r_info) == R_H8_PCREL8
876 && ELF32_R_SYM (last_reloc->r_info) < symtab_hdr->sh_info)
877 {
878 bfd_vma last_value;
879 asection *last_sym_sec;
880 Elf_Internal_Sym *last_sym;
881
882 /* We will need to examine the symbol used by the
883 previous relocation. */
884
885 last_sym = isymbuf + ELF32_R_SYM (last_reloc->r_info);
886 last_sym_sec
887 = bfd_section_from_elf_index (abfd, last_sym->st_shndx);
888 last_value = (last_sym->st_value
889 + last_sym_sec->output_section->vma
890 + last_sym_sec->output_offset);
891
892 /* Verify that the previous relocation was for a
893 branch around this instruction and that no symbol
894 exists at the current location. */
895 if (last_value == dot + 4
896 && last_reloc->r_offset + 2 == irel->r_offset
897 && ! elf32_h8_symbol_address_p (abfd, sec, dot))
898 {
899 /* We can eliminate this jump. Twiddle the
900 previous relocation as necessary. */
901 irel->r_info
902 = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
903 ELF32_R_TYPE (R_H8_NONE));
904
905 last_reloc->r_info
906 = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
907 ELF32_R_TYPE (R_H8_PCREL8));
908 last_reloc->r_addend = irel->r_addend;
909
910 code = bfd_get_8 (abfd,
911 contents + last_reloc->r_offset - 1);
912 code ^= 1;
913 bfd_put_8 (abfd,
914 code,
915 contents + last_reloc->r_offset - 1);
916
917 /* Delete four bytes of data. */
918 if (!elf32_h8_relax_delete_bytes (abfd, sec,
919 irel->r_offset - 1,
920 4))
921 goto error_return;
922
923 *again = TRUE;
924 break;
925 }
926 }
927
928 if (code == 0x5e)
929 bfd_put_8 (abfd, 0x55, contents + irel->r_offset - 1);
930 else if (code == 0x5a)
931 bfd_put_8 (abfd, 0x40, contents + irel->r_offset - 1);
932 else
933 abort ();
934
935 /* Fix the relocation's type. */
936 irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
937 R_H8_PCREL8);
938
939 /* Delete two bytes of data. */
940 if (!elf32_h8_relax_delete_bytes (abfd, sec,
941 irel->r_offset + 1, 2))
942 goto error_return;
943
944 /* That will change things, so, we should relax again.
945 Note that this is not required, and it may be slow. */
946 *again = TRUE;
947 }
948 break;
949 }
950
951 /* Try to turn a 16bit pc-relative branch into a 8bit pc-relative
952 branch. */
953 case R_H8_PCREL16:
954 {
955 bfd_vma value = symval + irel->r_addend;
956 bfd_vma dot;
957 bfd_vma gap;
958
959 /* Get the address of this instruction. */
960 dot = (sec->output_section->vma
961 + sec->output_offset
962 + irel->r_offset - 2);
963
964 gap = value - dot;
965
966 /* If the distance is within -126..+130 inclusive, then we can
967 relax this jump. +130 is valid since the target will move
968 two bytes closer if we do relax this branch. */
969 if ((int) gap >= -126 && (int) gap <= 130)
970 {
971 unsigned char code;
972
973 /* Note that we've changed the relocs, section contents,
974 etc. */
975 elf_section_data (sec)->relocs = internal_relocs;
976 elf_section_data (sec)->this_hdr.contents = contents;
977 symtab_hdr->contents = (unsigned char *) isymbuf;
978
979 /* Get the opcode. */
980 code = bfd_get_8 (abfd, contents + irel->r_offset - 2);
981
982 if (code == 0x58)
983 {
984 /* bCC:16 -> bCC:8 */
985 /* Get the condition code from the original insn. */
986 code = bfd_get_8 (abfd, contents + irel->r_offset - 1);
987 code &= 0xf0;
988 code >>= 4;
989 code |= 0x40;
990 bfd_put_8 (abfd, code, contents + irel->r_offset - 2);
991 }
992 else if (code == 0x5c)
993 bfd_put_8 (abfd, 0x55, contents + irel->r_offset - 2);
994 else
995 abort ();
996
997 /* Fix the relocation's type. */
998 irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
999 R_H8_PCREL8);
1000 irel->r_offset--;
1001
1002 /* Delete two bytes of data. */
1003 if (!elf32_h8_relax_delete_bytes (abfd, sec,
1004 irel->r_offset + 1, 2))
1005 goto error_return;
1006
1007 /* That will change things, so, we should relax again.
1008 Note that this is not required, and it may be slow. */
1009 *again = TRUE;
1010 }
1011 break;
1012 }
1013
1014 /* This is a 16 bit absolute address in a "mov.b" insn, which may
1015 become an 8 bit absolute address if its in the right range. */
1016 case R_H8_DIR16A8:
1017 {
1018 bfd_vma value = symval + irel->r_addend;
1019
1020 if ((bfd_get_mach (abfd) == bfd_mach_h8300
1021 && value >= 0xff00
1022 && value <= 0xffff)
1023 || ((bfd_get_mach (abfd) == bfd_mach_h8300h
1024 || bfd_get_mach (abfd) == bfd_mach_h8300s)
1025 && value >= 0xffff00
1026 && value <= 0xffffff))
1027 {
1028 unsigned char code;
1029
1030 /* Note that we've changed the relocs, section contents,
1031 etc. */
1032 elf_section_data (sec)->relocs = internal_relocs;
1033 elf_section_data (sec)->this_hdr.contents = contents;
1034 symtab_hdr->contents = (unsigned char *) isymbuf;
1035
1036 /* Get the opcode. */
1037 code = bfd_get_8 (abfd, contents + irel->r_offset - 2);
1038
1039 /* Sanity check. */
1040 if (code != 0x6a)
1041 abort ();
1042
1043 code = bfd_get_8 (abfd, contents + irel->r_offset - 1);
1044
1045 if ((code & 0xf0) == 0x00)
1046 bfd_put_8 (abfd,
1047 (code & 0xf) | 0x20,
1048 contents + irel->r_offset - 2);
1049 else if ((code & 0xf0) == 0x80)
1050 bfd_put_8 (abfd,
1051 (code & 0xf) | 0x30,
1052 contents + irel->r_offset - 2);
1053 else
1054 abort ();
1055
1056 /* Fix the relocation's type. */
1057 irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
1058 R_H8_DIR8);
1059
1060 /* Delete two bytes of data. */
1061 if (!elf32_h8_relax_delete_bytes (abfd, sec,
1062 irel->r_offset + 1, 2))
1063 goto error_return;
1064
1065 /* That will change things, so, we should relax again.
1066 Note that this is not required, and it may be slow. */
1067 *again = TRUE;
1068 }
1069 break;
1070 }
1071
1072 /* This is a 24 bit absolute address in a "mov.b" insn, which may
1073 become an 8 bit absolute address if its in the right range. */
1074 case R_H8_DIR24A8:
1075 {
1076 bfd_vma value = symval + irel->r_addend;
1077
1078 if ((bfd_get_mach (abfd) == bfd_mach_h8300
1079 && value >= 0xff00
1080 && value <= 0xffff)
1081 || ((bfd_get_mach (abfd) == bfd_mach_h8300h
1082 || bfd_get_mach (abfd) == bfd_mach_h8300s)
1083 && value >= 0xffff00
1084 && value <= 0xffffff))
1085 {
1086 unsigned char code;
1087
1088 /* Note that we've changed the relocs, section contents,
1089 etc. */
1090 elf_section_data (sec)->relocs = internal_relocs;
1091 elf_section_data (sec)->this_hdr.contents = contents;
1092 symtab_hdr->contents = (unsigned char *) isymbuf;
1093
1094 /* Get the opcode. */
1095 code = bfd_get_8 (abfd, contents + irel->r_offset - 2);
1096
1097 /* Sanity check. */
1098 if (code != 0x6a)
1099 abort ();
1100
1101 code = bfd_get_8 (abfd, contents + irel->r_offset - 1);
1102
1103 if ((code & 0xf0) == 0x00)
1104 bfd_put_8 (abfd,
1105 (code & 0xf) | 0x20,
1106 contents + irel->r_offset - 2);
1107 else if ((code & 0xf0) == 0x80)
1108 bfd_put_8 (abfd,
1109 (code & 0xf) | 0x30,
1110 contents + irel->r_offset - 2);
1111 else
1112 abort ();
1113
1114 /* Fix the relocation's type. */
1115 irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
1116 R_H8_DIR8);
1117
1118 /* Delete two bytes of data. */
1119 if (!elf32_h8_relax_delete_bytes (abfd, sec, irel->r_offset, 2))
1120 goto error_return;
1121
1122 /* That will change things, so, we should relax again.
1123 Note that this is not required, and it may be slow. */
1124 *again = TRUE;
1125 }
1126 }
1127
1128 /* FALLTHRU */
1129
1130 /* This is a 24/32bit absolute address in a "mov" insn, which may
1131 become a 16bit absoulte address if it is in the right range. */
1132 case R_H8_DIR32A16:
1133 {
1134 bfd_vma value = symval + irel->r_addend;
1135
1136 if (value <= 0x7fff || value >= 0xff8000)
1137 {
1138 unsigned char code;
1139
1140 /* Note that we've changed the relocs, section contents,
1141 etc. */
1142 elf_section_data (sec)->relocs = internal_relocs;
1143 elf_section_data (sec)->this_hdr.contents = contents;
1144 symtab_hdr->contents = (unsigned char *) isymbuf;
1145
1146 /* Get the opcode. */
1147 code = bfd_get_8 (abfd, contents + irel->r_offset - 1);
1148
1149 /* We just need to turn off bit 0x20. */
1150 code &= ~0x20;
1151
1152 bfd_put_8 (abfd, code, contents + irel->r_offset - 1);
1153
1154 /* Fix the relocation's type. */
1155 irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
1156 R_H8_DIR16A8);
1157
1158 /* Delete two bytes of data. */
1159 if (!elf32_h8_relax_delete_bytes (abfd, sec,
1160 irel->r_offset + 1, 2))
1161 goto error_return;
1162
1163 /* That will change things, so, we should relax again.
1164 Note that this is not required, and it may be slow. */
1165 *again = TRUE;
1166 }
1167 break;
1168 }
1169
1170 default:
1171 break;
1172 }
1173 }
1174
1175 if (isymbuf != NULL
1176 && symtab_hdr->contents != (unsigned char *) isymbuf)
1177 {
1178 if (! link_info->keep_memory)
1179 free (isymbuf);
1180 else
1181 symtab_hdr->contents = (unsigned char *) isymbuf;
1182 }
1183
1184 if (contents != NULL
1185 && elf_section_data (sec)->this_hdr.contents != contents)
1186 {
1187 if (! link_info->keep_memory)
1188 free (contents);
1189 else
1190 {
1191 /* Cache the section contents for elf_link_input_bfd. */
1192 elf_section_data (sec)->this_hdr.contents = contents;
1193 }
1194 }
1195
1196 if (internal_relocs != NULL
1197 && elf_section_data (sec)->relocs != internal_relocs)
1198 free (internal_relocs);
1199
1200 return TRUE;
1201
1202 error_return:
1203 if (isymbuf != NULL
1204 && symtab_hdr->contents != (unsigned char *) isymbuf)
1205 free (isymbuf);
1206 if (contents != NULL
1207 && elf_section_data (sec)->this_hdr.contents != contents)
1208 free (contents);
1209 if (internal_relocs != NULL
1210 && elf_section_data (sec)->relocs != internal_relocs)
1211 free (internal_relocs);
1212 return FALSE;
1213}
1214
1215/* Delete some bytes from a section while relaxing. */
1216
1217static bfd_boolean
1218elf32_h8_relax_delete_bytes (abfd, sec, addr, count)
1219 bfd *abfd;
1220 asection *sec;
1221 bfd_vma addr;
1222 int count;
1223{
1224 Elf_Internal_Shdr *symtab_hdr;
1225 unsigned int sec_shndx;
1226 bfd_byte *contents;
1227 Elf_Internal_Rela *irel, *irelend;
1228 Elf_Internal_Rela *irelalign;
1229 Elf_Internal_Sym *isym;
1230 Elf_Internal_Sym *isymend;
1231 bfd_vma toaddr;
1232 struct elf_link_hash_entry **sym_hashes;
1233 struct elf_link_hash_entry **end_hashes;
1234 unsigned int symcount;
1235
1236 sec_shndx = _bfd_elf_section_from_bfd_section (abfd, sec);
1237
1238 contents = elf_section_data (sec)->this_hdr.contents;
1239
1240 /* The deletion must stop at the next ALIGN reloc for an aligment
1241 power larger than the number of bytes we are deleting. */
1242
1243 irelalign = NULL;
1244 toaddr = sec->_cooked_size;
1245
1246 irel = elf_section_data (sec)->relocs;
1247 irelend = irel + sec->reloc_count;
1248
1249 /* Actually delete the bytes. */
1250 memmove (contents + addr, contents + addr + count,
1251 (size_t) (toaddr - addr - count));
1252 sec->_cooked_size -= count;
1253
1254 /* Adjust all the relocs. */
1255 for (irel = elf_section_data (sec)->relocs; irel < irelend; irel++)
1256 {
1257 /* Get the new reloc address. */
1258 if ((irel->r_offset > addr
1259 && irel->r_offset < toaddr))
1260 irel->r_offset -= count;
1261 }
1262
1263 /* Adjust the local symbols defined in this section. */
1264 symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
1265 isym = (Elf_Internal_Sym *) symtab_hdr->contents;
1266 isymend = isym + symtab_hdr->sh_info;
1267 for (; isym < isymend; isym++)
1268 {
1269 if (isym->st_shndx == sec_shndx
1270 && isym->st_value > addr
1271 && isym->st_value < toaddr)
1272 isym->st_value -= count;
1273 }
1274
1275 /* Now adjust the global symbols defined in this section. */
1276 symcount = (symtab_hdr->sh_size / sizeof (Elf32_External_Sym)
1277 - symtab_hdr->sh_info);
1278 sym_hashes = elf_sym_hashes (abfd);
1279 end_hashes = sym_hashes + symcount;
1280 for (; sym_hashes < end_hashes; sym_hashes++)
1281 {
1282 struct elf_link_hash_entry *sym_hash = *sym_hashes;
1283 if ((sym_hash->root.type == bfd_link_hash_defined
1284 || sym_hash->root.type == bfd_link_hash_defweak)
1285 && sym_hash->root.u.def.section == sec
1286 && sym_hash->root.u.def.value > addr
1287 && sym_hash->root.u.def.value < toaddr)
1288 {
1289 sym_hash->root.u.def.value -= count;
1290 }
1291 }
1292
1293 return TRUE;
1294}
1295
1296/* Return TRUE if a symbol exists at the given address, else return
1297 FALSE. */
1298static bfd_boolean
1299elf32_h8_symbol_address_p (abfd, sec, addr)
1300 bfd *abfd;
1301 asection *sec;
1302 bfd_vma addr;
1303{
1304 Elf_Internal_Shdr *symtab_hdr;
1305 unsigned int sec_shndx;
1306 Elf_Internal_Sym *isym;
1307 Elf_Internal_Sym *isymend;
1308 struct elf_link_hash_entry **sym_hashes;
1309 struct elf_link_hash_entry **end_hashes;
1310 unsigned int symcount;
1311
1312 sec_shndx = _bfd_elf_section_from_bfd_section (abfd, sec);
1313
1314 /* Examine all the symbols. */
1315 symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
1316 isym = (Elf_Internal_Sym *) symtab_hdr->contents;
1317 isymend = isym + symtab_hdr->sh_info;
1318 for (; isym < isymend; isym++)
1319 {
1320 if (isym->st_shndx == sec_shndx
1321 && isym->st_value == addr)
1322 return TRUE;
1323 }
1324
1325 symcount = (symtab_hdr->sh_size / sizeof (Elf32_External_Sym)
1326 - symtab_hdr->sh_info);
1327 sym_hashes = elf_sym_hashes (abfd);
1328 end_hashes = sym_hashes + symcount;
1329 for (; sym_hashes < end_hashes; sym_hashes++)
1330 {
1331 struct elf_link_hash_entry *sym_hash = *sym_hashes;
1332 if ((sym_hash->root.type == bfd_link_hash_defined
1333 || sym_hash->root.type == bfd_link_hash_defweak)
1334 && sym_hash->root.u.def.section == sec
1335 && sym_hash->root.u.def.value == addr)
1336 return TRUE;
1337 }
1338
1339 return FALSE;
1340}
1341
1342/* This is a version of bfd_generic_get_relocated_section_contents
1343 which uses elf32_h8_relocate_section. */
1344
1345static bfd_byte *
1346elf32_h8_get_relocated_section_contents (output_bfd, link_info, link_order,
1347 data, relocateable, symbols)
1348 bfd *output_bfd;
1349 struct bfd_link_info *link_info;
1350 struct bfd_link_order *link_order;
1351 bfd_byte *data;
1352 bfd_boolean relocateable;
1353 asymbol **symbols;
1354{
1355 Elf_Internal_Shdr *symtab_hdr;
1356 asection *input_section = link_order->u.indirect.section;
1357 bfd *input_bfd = input_section->owner;
1358 asection **sections = NULL;
1359 Elf_Internal_Rela *internal_relocs = NULL;
1360 Elf_Internal_Sym *isymbuf = NULL;
1361
1362 /* We only need to handle the case of relaxing, or of having a
1363 particular set of section contents, specially. */
1364 if (relocateable
1365 || elf_section_data (input_section)->this_hdr.contents == NULL)
1366 return bfd_generic_get_relocated_section_contents (output_bfd, link_info,
1367 link_order, data,
1368 relocateable,
1369 symbols);
1370
1371 symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
1372
1373 memcpy (data, elf_section_data (input_section)->this_hdr.contents,
1374 (size_t) input_section->_raw_size);
1375
1376 if ((input_section->flags & SEC_RELOC) != 0
1377 && input_section->reloc_count > 0)
1378 {
1379 asection **secpp;
1380 Elf_Internal_Sym *isym, *isymend;
1381 bfd_size_type amt;
1382
1383 internal_relocs = (_bfd_elf32_link_read_relocs
1384 (input_bfd, input_section, (PTR) NULL,
1385 (Elf_Internal_Rela *) NULL, FALSE));
1386 if (internal_relocs == NULL)
1387 goto error_return;
1388
1389 if (symtab_hdr->sh_info != 0)
1390 {
1391 isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
1392 if (isymbuf == NULL)
1393 isymbuf = bfd_elf_get_elf_syms (input_bfd, symtab_hdr,
1394 symtab_hdr->sh_info, 0,
1395 NULL, NULL, NULL);
1396 if (isymbuf == NULL)
1397 goto error_return;
1398 }
1399
1400 amt = symtab_hdr->sh_info;
1401 amt *= sizeof (asection *);
1402 sections = (asection **) bfd_malloc (amt);
1403 if (sections == NULL && amt != 0)
1404 goto error_return;
1405
1406 isymend = isymbuf + symtab_hdr->sh_info;
1407 for (isym = isymbuf, secpp = sections; isym < isymend; ++isym, ++secpp)
1408 {
1409 asection *isec;
1410
1411 if (isym->st_shndx == SHN_UNDEF)
1412 isec = bfd_und_section_ptr;
1413 else if (isym->st_shndx == SHN_ABS)
1414 isec = bfd_abs_section_ptr;
1415 else if (isym->st_shndx == SHN_COMMON)
1416 isec = bfd_com_section_ptr;
1417 else
1418 isec = bfd_section_from_elf_index (input_bfd, isym->st_shndx);
1419
1420 *secpp = isec;
1421 }
1422
1423 if (! elf32_h8_relocate_section (output_bfd, link_info, input_bfd,
1424 input_section, data, internal_relocs,
1425 isymbuf, sections))
1426 goto error_return;
1427
1428 if (sections != NULL)
1429 free (sections);
1430 if (isymbuf != NULL
1431 && symtab_hdr->contents != (unsigned char *) isymbuf)
1432 free (isymbuf);
1433 if (elf_section_data (input_section)->relocs != internal_relocs)
1434 free (internal_relocs);
1435 }
1436
1437 return data;
1438
1439 error_return:
1440 if (sections != NULL)
1441 free (sections);
1442 if (isymbuf != NULL
1443 && symtab_hdr->contents != (unsigned char *) isymbuf)
1444 free (isymbuf);
1445 if (internal_relocs != NULL
1446 && elf_section_data (input_section)->relocs != internal_relocs)
1447 free (internal_relocs);
1448 return NULL;
1449}
1450
1451
1452#define TARGET_BIG_SYM bfd_elf32_h8300_vec
1453#define TARGET_BIG_NAME "elf32-h8300"
1454#define ELF_ARCH bfd_arch_h8300
1455#define ELF_MACHINE_CODE EM_H8_300
1456#define ELF_MAXPAGESIZE 0x1
1457#define bfd_elf32_bfd_reloc_type_lookup elf32_h8_reloc_type_lookup
1458#define elf_info_to_howto elf32_h8_info_to_howto
1459#define elf_info_to_howto_rel elf32_h8_info_to_howto_rel
1460
1461/* So we can set/examine bits in e_flags to get the specific
1462 H8 architecture in use. */
1463#define elf_backend_final_write_processing \
1464 elf32_h8_final_write_processing
1465#define elf_backend_object_p \
1466 elf32_h8_object_p
1467#define bfd_elf32_bfd_merge_private_bfd_data \
1468 elf32_h8_merge_private_bfd_data
1469
1470/* ??? when elf_backend_relocate_section is not defined, elf32-target.h
1471 defaults to using _bfd_generic_link_hash_table_create, but
1472 elflink.h:bfd_elf32_size_dynamic_sections uses
1473 dynobj = elf_hash_table (info)->dynobj;
1474 and thus requires an elf hash table. */
1475#define bfd_elf32_bfd_link_hash_table_create _bfd_elf_link_hash_table_create
1476
1477/* Use an H8 specific linker, not the ELF generic linker. */
1478#define elf_backend_relocate_section elf32_h8_relocate_section
1479#define elf_backend_rela_normal 1
1480
1481/* And relaxing stuff. */
1482#define bfd_elf32_bfd_relax_section elf32_h8_relax_section
1483#define bfd_elf32_bfd_get_relocated_section_contents \
1484 elf32_h8_get_relocated_section_contents
1485
1486
1487#include "elf32-target.h"
Note: See TracBrowser for help on using the repository browser.