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