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