Back to index

cell-binutils  2.17cvs20070401
elf32-h8300.c
Go to the documentation of this file.
00001 /* BFD back-end for Renesas H8/300 ELF binaries.
00002    Copyright 1993, 1995, 1998, 1999, 2001, 2002, 2003, 2004, 2005, 2006,
00003    2007 Free Software Foundation, Inc.
00004 
00005    This file is part of BFD, the Binary File Descriptor library.
00006 
00007    This program is free software; you can redistribute it and/or modify
00008    it under the terms of the GNU General Public License as published by
00009    the Free Software Foundation; either version 2 of the License, or
00010    (at your option) any later version.
00011 
00012    This program is distributed in the hope that it will be useful,
00013    but WITHOUT ANY WARRANTY; without even the implied warranty of
00014    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015    GNU General Public License for more details.
00016 
00017    You should have received a copy of the GNU General Public License
00018    along with this program; if not, write to the Free Software
00019    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.  */
00020 
00021 #include "bfd.h"
00022 #include "sysdep.h"
00023 #include "libbfd.h"
00024 #include "elf-bfd.h"
00025 #include "elf/h8.h"
00026 
00027 static reloc_howto_type *elf32_h8_reloc_type_lookup
00028   (bfd *abfd, bfd_reloc_code_real_type code);
00029 static void elf32_h8_info_to_howto
00030   (bfd *, arelent *, Elf_Internal_Rela *);
00031 static void elf32_h8_info_to_howto_rel
00032   (bfd *, arelent *, Elf_Internal_Rela *);
00033 static unsigned long elf32_h8_mach (flagword);
00034 static void elf32_h8_final_write_processing (bfd *, bfd_boolean);
00035 static bfd_boolean elf32_h8_object_p (bfd *);
00036 static bfd_boolean elf32_h8_merge_private_bfd_data (bfd *, bfd *);
00037 static bfd_boolean elf32_h8_relax_section
00038   (bfd *, asection *, struct bfd_link_info *, bfd_boolean *);
00039 static bfd_boolean elf32_h8_relax_delete_bytes
00040   (bfd *, asection *, bfd_vma, int);
00041 static bfd_boolean elf32_h8_symbol_address_p (bfd *, asection *, bfd_vma);
00042 static bfd_byte *elf32_h8_get_relocated_section_contents
00043   (bfd *, struct bfd_link_info *, struct bfd_link_order *,
00044    bfd_byte *, bfd_boolean, asymbol **);
00045 static bfd_reloc_status_type elf32_h8_final_link_relocate
00046   (unsigned long, bfd *, bfd *, asection *,
00047    bfd_byte *, bfd_vma, bfd_vma, bfd_vma,
00048    struct bfd_link_info *, asection *, int);
00049 static bfd_boolean elf32_h8_relocate_section
00050   (bfd *, struct bfd_link_info *, bfd *, asection *,
00051    bfd_byte *, Elf_Internal_Rela *,
00052    Elf_Internal_Sym *, asection **);
00053 static bfd_reloc_status_type special
00054   (bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **);
00055 
00056 /* This does not include any relocation information, but should be
00057    good enough for GDB or objdump to read the file.  */
00058 
00059 static reloc_howto_type h8_elf_howto_table[] = {
00060 #define R_H8_NONE_X 0
00061   HOWTO (R_H8_NONE,         /* type */
00062         0,                  /* rightshift */
00063         0,                  /* size (0 = byte, 1 = short, 2 = long) */
00064         0,                  /* bitsize */
00065         FALSE,                     /* pc_relative */
00066         0,                  /* bitpos */
00067         complain_overflow_dont,/* complain_on_overflow */
00068         special,            /* special_function */
00069         "R_H8_NONE",        /* name */
00070         FALSE,                     /* partial_inplace */
00071         0,                  /* src_mask */
00072         0,                  /* dst_mask */
00073         FALSE),             /* pcrel_offset */
00074 #define R_H8_DIR32_X (R_H8_NONE_X + 1)
00075   HOWTO (R_H8_DIR32,        /* type */
00076         0,                  /* rightshift */
00077         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00078         32,                 /* bitsize */
00079         FALSE,                     /* pc_relative */
00080         0,                  /* bitpos */
00081         complain_overflow_dont,/* complain_on_overflow */
00082         special,            /* special_function */
00083         "R_H8_DIR32",              /* name */
00084         FALSE,                     /* partial_inplace */
00085         0,                  /* src_mask */
00086         0xffffffff,         /* dst_mask */
00087         FALSE),             /* pcrel_offset */
00088 #define R_H8_DIR16_X (R_H8_DIR32_X + 1)
00089   HOWTO (R_H8_DIR16,        /* type */
00090         0,                  /* rightshift */
00091         1,                  /* size (0 = byte, 1 = short, 2 = long) */
00092         16,                 /* bitsize */
00093         FALSE,                     /* pc_relative */
00094         0,                  /* bitpos */
00095         complain_overflow_dont,/* complain_on_overflow */
00096         special,            /* special_function */
00097         "R_H8_DIR16",              /* name */
00098         FALSE,                     /* partial_inplace */
00099         0,                  /* src_mask */
00100         0x0000ffff,         /* dst_mask */
00101         FALSE),             /* pcrel_offset */
00102 #define R_H8_DIR8_X (R_H8_DIR16_X + 1)
00103   HOWTO (R_H8_DIR8,         /* type */
00104         0,                  /* rightshift */
00105         0,                  /* size (0 = byte, 1 = short, 2 = long) */
00106         8,                  /* bitsize */
00107         FALSE,                     /* pc_relative */
00108         0,                  /* bitpos */
00109         complain_overflow_dont,/* complain_on_overflow */
00110         special,            /* special_function */
00111         "R_H8_DIR8",        /* name */
00112         FALSE,                     /* partial_inplace */
00113         0,                  /* src_mask */
00114         0x000000ff,         /* dst_mask */
00115         FALSE),             /* pcrel_offset */
00116 #define R_H8_DIR16A8_X (R_H8_DIR8_X + 1)
00117   HOWTO (R_H8_DIR16A8,             /* type */
00118         0,                  /* rightshift */
00119         1,                  /* size (0 = byte, 1 = short, 2 = long) */
00120         16,                 /* bitsize */
00121         FALSE,                     /* pc_relative */
00122         0,                  /* bitpos */
00123         complain_overflow_bitfield, /* complain_on_overflow */
00124         special,            /* special_function */
00125         "R_H8_DIR16A8",     /* name */
00126         FALSE,                     /* partial_inplace */
00127         0,                  /* src_mask */
00128         0x0000ffff,         /* dst_mask */
00129         FALSE),             /* pcrel_offset */
00130 #define R_H8_DIR16R8_X (R_H8_DIR16A8_X + 1)
00131   HOWTO (R_H8_DIR16R8,             /* type */
00132         0,                  /* rightshift */
00133         1,                  /* size (0 = byte, 1 = short, 2 = long) */
00134         16,                 /* bitsize */
00135         FALSE,                     /* pc_relative */
00136         0,                  /* bitpos */
00137         complain_overflow_bitfield, /* complain_on_overflow */
00138         special,            /* special_function */
00139         "R_H8_DIR16R8",     /* name */
00140         FALSE,                     /* partial_inplace */
00141         0,                  /* src_mask */
00142         0x0000ffff,         /* dst_mask */
00143         FALSE),             /* pcrel_offset */
00144 #define R_H8_DIR24A8_X (R_H8_DIR16R8_X + 1)
00145   HOWTO (R_H8_DIR24A8,             /* type */
00146         0,                  /* rightshift */
00147         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00148         24,                 /* bitsize */
00149         FALSE,                     /* pc_relative */
00150         0,                  /* bitpos */
00151         complain_overflow_bitfield, /* complain_on_overflow */
00152         special,            /* special_function */
00153         "R_H8_DIR24A8",     /* name */
00154         TRUE,               /* partial_inplace */
00155         0xff000000,         /* src_mask */
00156         0x00ffffff,         /* dst_mask */
00157         FALSE),             /* pcrel_offset */
00158 #define R_H8_DIR24R8_X (R_H8_DIR24A8_X + 1)
00159   HOWTO (R_H8_DIR24R8,             /* type */
00160         0,                  /* rightshift */
00161         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00162         24,                 /* bitsize */
00163         FALSE,                     /* pc_relative */
00164         0,                  /* bitpos */
00165         complain_overflow_bitfield, /* complain_on_overflow */
00166         special,            /* special_function */
00167         "R_H8_DIR24R8",     /* name */
00168         TRUE,               /* partial_inplace */
00169         0xff000000,         /* src_mask */
00170         0x00ffffff,         /* dst_mask */
00171         FALSE),             /* pcrel_offset */
00172 #define R_H8_DIR32A16_X (R_H8_DIR24R8_X + 1)
00173   HOWTO (R_H8_DIR32A16,            /* type */
00174         0,                  /* rightshift */
00175         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00176         32,                 /* bitsize */
00177         FALSE,                     /* pc_relative */
00178         0,                  /* bitpos */
00179         complain_overflow_dont,/* complain_on_overflow */
00180         special,            /* special_function */
00181         "R_H8_DIR32A16",    /* name */
00182         FALSE,                     /* partial_inplace */
00183         0,                  /* src_mask */
00184         0xffffffff,         /* dst_mask */
00185         FALSE),             /* pcrel_offset */
00186 #define R_H8_PCREL16_X (R_H8_DIR32A16_X + 1)
00187   HOWTO (R_H8_PCREL16,             /* type */
00188         0,                  /* rightshift */
00189         1,                  /* size (0 = byte, 1 = short, 2 = long) */
00190         16,                 /* bitsize */
00191         TRUE,               /* pc_relative */
00192         0,                  /* bitpos */
00193         complain_overflow_signed,/* complain_on_overflow */
00194         special,            /* special_function */
00195         "R_H8_PCREL16",     /* name */
00196         FALSE,                     /* partial_inplace */
00197         0xffff,             /* src_mask */
00198         0xffff,             /* dst_mask */
00199         TRUE),                     /* pcrel_offset */
00200 #define R_H8_PCREL8_X (R_H8_PCREL16_X + 1)
00201   HOWTO (R_H8_PCREL8,              /* type */
00202         0,                  /* rightshift */
00203         0,                  /* size (0 = byte, 1 = short, 2 = long) */
00204         8,                  /* bitsize */
00205         TRUE,               /* pc_relative */
00206         0,                  /* bitpos */
00207         complain_overflow_signed,/* complain_on_overflow */
00208         special,            /* special_function */
00209         "R_H8_PCREL8",             /* name */
00210         FALSE,                     /* partial_inplace */
00211         0xff,               /* src_mask */
00212         0xff,               /* dst_mask */
00213         TRUE),                     /* pcrel_offset */
00214 };
00215 
00216 /* This structure is used to map BFD reloc codes to H8 ELF relocs.  */
00217 
00218 struct elf_reloc_map {
00219   bfd_reloc_code_real_type bfd_reloc_val;
00220   unsigned char howto_index;
00221 };
00222 
00223 /* An array mapping BFD reloc codes to H8 ELF relocs.  */
00224 
00225 static const struct elf_reloc_map h8_reloc_map[] = {
00226   { BFD_RELOC_NONE, R_H8_NONE_X },
00227   { BFD_RELOC_32, R_H8_DIR32_X },
00228   { BFD_RELOC_16, R_H8_DIR16_X },
00229   { BFD_RELOC_8, R_H8_DIR8_X },
00230   { BFD_RELOC_H8_DIR16A8, R_H8_DIR16A8_X },
00231   { BFD_RELOC_H8_DIR16R8, R_H8_DIR16R8_X },
00232   { BFD_RELOC_H8_DIR24A8, R_H8_DIR24A8_X },
00233   { BFD_RELOC_H8_DIR24R8, R_H8_DIR24R8_X },
00234   { BFD_RELOC_H8_DIR32A16, R_H8_DIR32A16_X },
00235   { BFD_RELOC_16_PCREL, R_H8_PCREL16_X },
00236   { BFD_RELOC_8_PCREL, R_H8_PCREL8_X },
00237 };
00238 
00239 
00240 static reloc_howto_type *
00241 elf32_h8_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
00242                          bfd_reloc_code_real_type code)
00243 {
00244   unsigned int i;
00245 
00246   for (i = 0; i < sizeof (h8_reloc_map) / sizeof (struct elf_reloc_map); i++)
00247     {
00248       if (h8_reloc_map[i].bfd_reloc_val == code)
00249        return &h8_elf_howto_table[(int) h8_reloc_map[i].howto_index];
00250     }
00251   return NULL;
00252 }
00253 
00254 static reloc_howto_type *
00255 elf32_h8_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
00256                          const char *r_name)
00257 {
00258   unsigned int i;
00259 
00260   for (i = 0;
00261        i < sizeof (h8_elf_howto_table) / sizeof (h8_elf_howto_table[0]);
00262        i++)
00263     if (h8_elf_howto_table[i].name != NULL
00264        && strcasecmp (h8_elf_howto_table[i].name, r_name) == 0)
00265       return &h8_elf_howto_table[i];
00266 
00267   return NULL;
00268 }
00269 
00270 static void
00271 elf32_h8_info_to_howto (bfd *abfd ATTRIBUTE_UNUSED, arelent *bfd_reloc,
00272                      Elf_Internal_Rela *elf_reloc)
00273 {
00274   unsigned int r;
00275   unsigned int i;
00276 
00277   r = ELF32_R_TYPE (elf_reloc->r_info);
00278   for (i = 0; i < sizeof (h8_elf_howto_table) / sizeof (reloc_howto_type); i++)
00279     if (h8_elf_howto_table[i].type == r)
00280       {
00281        bfd_reloc->howto = &h8_elf_howto_table[i];
00282        return;
00283       }
00284   abort ();
00285 }
00286 
00287 static void
00288 elf32_h8_info_to_howto_rel (bfd *abfd ATTRIBUTE_UNUSED, arelent *bfd_reloc,
00289                          Elf_Internal_Rela *elf_reloc ATTRIBUTE_UNUSED)
00290 {
00291   unsigned int r;
00292 
00293   abort ();
00294   r = ELF32_R_TYPE (elf_reloc->r_info);
00295   bfd_reloc->howto = &h8_elf_howto_table[r];
00296 }
00297 
00298 /* Special handling for H8/300 relocs.
00299    We only come here for pcrel stuff and return normally if not an -r link.
00300    When doing -r, we can't do any arithmetic for the pcrel stuff, because
00301    we support relaxing on the H8/300 series chips.  */
00302 static bfd_reloc_status_type
00303 special (bfd *abfd ATTRIBUTE_UNUSED,
00304         arelent *reloc_entry ATTRIBUTE_UNUSED,
00305         asymbol *symbol ATTRIBUTE_UNUSED,
00306         PTR data ATTRIBUTE_UNUSED,
00307         asection *input_section ATTRIBUTE_UNUSED,
00308         bfd *output_bfd,
00309         char **error_message ATTRIBUTE_UNUSED)
00310 {
00311   if (output_bfd == (bfd *) NULL)
00312     return bfd_reloc_continue;
00313 
00314   /* Adjust the reloc address to that in the output section.  */
00315   reloc_entry->address += input_section->output_offset;
00316   return bfd_reloc_ok;
00317 }
00318 
00319 /* Perform a relocation as part of a final link.  */
00320 static bfd_reloc_status_type
00321 elf32_h8_final_link_relocate (unsigned long r_type, bfd *input_bfd,
00322                            bfd *output_bfd ATTRIBUTE_UNUSED,
00323                            asection *input_section ATTRIBUTE_UNUSED,
00324                            bfd_byte *contents, bfd_vma offset,
00325                            bfd_vma value, bfd_vma addend,
00326                            struct bfd_link_info *info ATTRIBUTE_UNUSED,
00327                            asection *sym_sec ATTRIBUTE_UNUSED,
00328                            int is_local ATTRIBUTE_UNUSED)
00329 {
00330   bfd_byte *hit_data = contents + offset;
00331 
00332   switch (r_type)
00333     {
00334     case R_H8_NONE:
00335       return bfd_reloc_ok;
00336 
00337     case R_H8_DIR32:
00338     case R_H8_DIR32A16:
00339     case R_H8_DIR24A8:
00340       value += addend;
00341       bfd_put_32 (input_bfd, value, hit_data);
00342       return bfd_reloc_ok;
00343 
00344     case R_H8_DIR16:
00345     case R_H8_DIR16A8:
00346     case R_H8_DIR16R8:
00347       value += addend;
00348       bfd_put_16 (input_bfd, value, hit_data);
00349       return bfd_reloc_ok;
00350 
00351     /* AKA R_RELBYTE */
00352     case R_H8_DIR8:
00353       value += addend;
00354 
00355       bfd_put_8 (input_bfd, value, hit_data);
00356       return bfd_reloc_ok;
00357 
00358     case R_H8_DIR24R8:
00359       value += addend;
00360 
00361       /* HIT_DATA is the address for the first byte for the relocated
00362         value.  Subtract 1 so that we can manipulate the data in 32-bit
00363         hunks.  */
00364       hit_data--;
00365 
00366       /* Clear out the top byte in value.  */
00367       value &= 0xffffff;
00368 
00369       /* Retrieve the type byte for value from the section contents.  */
00370       value |= (bfd_get_32 (input_bfd, hit_data) & 0xff000000);
00371 
00372       /* Now scribble it out in one 32-bit hunk.  */
00373       bfd_put_32 (input_bfd, value, hit_data);
00374       return bfd_reloc_ok;
00375 
00376     case R_H8_PCREL16:
00377       value -= (input_section->output_section->vma
00378               + input_section->output_offset);
00379       value -= offset;
00380       value += addend;
00381 
00382       /* The value is relative to the start of the instruction,
00383         not the relocation offset.  Subtract 2 to account for
00384         this minor issue.  */
00385       value -= 2;
00386 
00387       bfd_put_16 (input_bfd, value, hit_data);
00388       return bfd_reloc_ok;
00389 
00390     case R_H8_PCREL8:
00391       value -= (input_section->output_section->vma
00392               + input_section->output_offset);
00393       value -= offset;
00394       value += addend;
00395 
00396       /* The value is relative to the start of the instruction,
00397         not the relocation offset.  Subtract 1 to account for
00398         this minor issue.  */
00399       value -= 1;
00400 
00401       bfd_put_8 (input_bfd, value, hit_data);
00402       return bfd_reloc_ok;
00403 
00404     default:
00405       return bfd_reloc_notsupported;
00406     }
00407 }
00408 
00409 /* Relocate an H8 ELF section.  */
00410 static bfd_boolean
00411 elf32_h8_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
00412                         bfd *input_bfd, asection *input_section,
00413                         bfd_byte *contents, Elf_Internal_Rela *relocs,
00414                         Elf_Internal_Sym *local_syms,
00415                         asection **local_sections)
00416 {
00417   Elf_Internal_Shdr *symtab_hdr;
00418   struct elf_link_hash_entry **sym_hashes;
00419   Elf_Internal_Rela *rel, *relend;
00420 
00421   symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
00422   sym_hashes = elf_sym_hashes (input_bfd);
00423 
00424   rel = relocs;
00425   relend = relocs + input_section->reloc_count;
00426   for (; rel < relend; rel++)
00427     {
00428       unsigned int r_type;
00429       unsigned long r_symndx;
00430       Elf_Internal_Sym *sym;
00431       asection *sec;
00432       struct elf_link_hash_entry *h;
00433       bfd_vma relocation;
00434       bfd_reloc_status_type r;
00435       arelent bfd_reloc;
00436       reloc_howto_type *howto;
00437 
00438       elf32_h8_info_to_howto (input_bfd, &bfd_reloc, rel);
00439       howto = bfd_reloc.howto;
00440 
00441       r_symndx = ELF32_R_SYM (rel->r_info);
00442       r_type = ELF32_R_TYPE (rel->r_info);
00443       h = NULL;
00444       sym = NULL;
00445       sec = NULL;
00446       if (r_symndx < symtab_hdr->sh_info)
00447        {
00448          sym = local_syms + r_symndx;
00449          sec = local_sections[r_symndx];
00450          relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel);
00451        }
00452       else
00453        {
00454          bfd_boolean unresolved_reloc, warned;
00455 
00456          RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
00457                                r_symndx, symtab_hdr, sym_hashes,
00458                                h, sec, relocation,
00459                                unresolved_reloc, warned);
00460        }
00461 
00462       if (sec != NULL && elf_discarded_section (sec))
00463        {
00464          /* For relocs against symbols from removed linkonce sections,
00465             or sections discarded by a linker script, we just want the
00466             section contents zeroed.  Avoid any special processing.  */
00467          _bfd_clear_contents (howto, input_bfd, contents + rel->r_offset);
00468          rel->r_info = 0;
00469          rel->r_addend = 0;
00470          continue;
00471        }
00472 
00473       if (info->relocatable)
00474        continue;
00475 
00476       r = elf32_h8_final_link_relocate (r_type, input_bfd, output_bfd,
00477                                    input_section,
00478                                    contents, rel->r_offset,
00479                                    relocation, rel->r_addend,
00480                                    info, sec, h == NULL);
00481 
00482       if (r != bfd_reloc_ok)
00483        {
00484          const char *name;
00485          const char *msg = (const char *) 0;
00486 
00487          if (h != NULL)
00488            name = h->root.root.string;
00489          else
00490            {
00491              name = (bfd_elf_string_from_elf_section
00492                     (input_bfd, symtab_hdr->sh_link, sym->st_name));
00493              if (name == NULL || *name == '\0')
00494               name = bfd_section_name (input_bfd, sec);
00495            }
00496 
00497          switch (r)
00498            {
00499            case bfd_reloc_overflow:
00500              if (! ((*info->callbacks->reloc_overflow)
00501                    (info, (h ? &h->root : NULL), name, howto->name,
00502                     (bfd_vma) 0, input_bfd, input_section,
00503                     rel->r_offset)))
00504               return FALSE;
00505              break;
00506 
00507            case bfd_reloc_undefined:
00508              if (! ((*info->callbacks->undefined_symbol)
00509                    (info, name, input_bfd, input_section,
00510                     rel->r_offset, TRUE)))
00511               return FALSE;
00512              break;
00513 
00514            case bfd_reloc_outofrange:
00515              msg = _("internal error: out of range error");
00516              goto common_error;
00517 
00518            case bfd_reloc_notsupported:
00519              msg = _("internal error: unsupported relocation error");
00520              goto common_error;
00521 
00522            case bfd_reloc_dangerous:
00523              msg = _("internal error: dangerous error");
00524              goto common_error;
00525 
00526            default:
00527              msg = _("internal error: unknown error");
00528              /* fall through */
00529 
00530            common_error:
00531              if (!((*info->callbacks->warning)
00532                   (info, msg, name, input_bfd, input_section,
00533                    rel->r_offset)))
00534               return FALSE;
00535              break;
00536            }
00537        }
00538     }
00539 
00540   return TRUE;
00541 }
00542 
00543 /* Object files encode the specific H8 model they were compiled
00544    for in the ELF flags field.
00545 
00546    Examine that field and return the proper BFD machine type for
00547    the object file.  */
00548 static unsigned long
00549 elf32_h8_mach (flagword flags)
00550 {
00551   switch (flags & EF_H8_MACH)
00552     {
00553     case E_H8_MACH_H8300:
00554     default:
00555       return bfd_mach_h8300;
00556 
00557     case E_H8_MACH_H8300H:
00558       return bfd_mach_h8300h;
00559 
00560     case E_H8_MACH_H8300S:
00561       return bfd_mach_h8300s;
00562 
00563     case E_H8_MACH_H8300HN:
00564       return bfd_mach_h8300hn;
00565 
00566     case E_H8_MACH_H8300SN:
00567       return bfd_mach_h8300sn;
00568 
00569     case E_H8_MACH_H8300SX:
00570       return bfd_mach_h8300sx;
00571 
00572     case E_H8_MACH_H8300SXN:
00573       return bfd_mach_h8300sxn;
00574     }
00575 }
00576 
00577 /* The final processing done just before writing out a H8 ELF object
00578    file.  We use this opportunity to encode the BFD machine type
00579    into the flags field in the object file.  */
00580 
00581 static void
00582 elf32_h8_final_write_processing (bfd *abfd,
00583                              bfd_boolean linker ATTRIBUTE_UNUSED)
00584 {
00585   unsigned long val;
00586 
00587   switch (bfd_get_mach (abfd))
00588     {
00589     default:
00590     case bfd_mach_h8300:
00591       val = E_H8_MACH_H8300;
00592       break;
00593 
00594     case bfd_mach_h8300h:
00595       val = E_H8_MACH_H8300H;
00596       break;
00597 
00598     case bfd_mach_h8300s:
00599       val = E_H8_MACH_H8300S;
00600       break;
00601 
00602     case bfd_mach_h8300hn:
00603       val = E_H8_MACH_H8300HN;
00604       break;
00605 
00606     case bfd_mach_h8300sn:
00607       val = E_H8_MACH_H8300SN;
00608       break;
00609 
00610     case bfd_mach_h8300sx:
00611       val = E_H8_MACH_H8300SX;
00612       break;
00613 
00614     case bfd_mach_h8300sxn:
00615       val = E_H8_MACH_H8300SXN;
00616       break;
00617     }
00618 
00619   elf_elfheader (abfd)->e_flags &= ~ (EF_H8_MACH);
00620   elf_elfheader (abfd)->e_flags |= val;
00621 }
00622 
00623 /* Return nonzero if ABFD represents a valid H8 ELF object file; also
00624    record the encoded machine type found in the ELF flags.  */
00625 
00626 static bfd_boolean
00627 elf32_h8_object_p (bfd *abfd)
00628 {
00629   bfd_default_set_arch_mach (abfd, bfd_arch_h8300,
00630                           elf32_h8_mach (elf_elfheader (abfd)->e_flags));
00631   return TRUE;
00632 }
00633 
00634 /* Merge backend specific data from an object file to the output
00635    object file when linking.  The only data we need to copy at this
00636    time is the architecture/machine information.  */
00637 
00638 static bfd_boolean
00639 elf32_h8_merge_private_bfd_data (bfd *ibfd, bfd *obfd)
00640 {
00641   if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
00642       || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
00643     return TRUE;
00644 
00645   if (bfd_get_arch (obfd) == bfd_get_arch (ibfd)
00646       && bfd_get_mach (obfd) < bfd_get_mach (ibfd))
00647     {
00648       if (! bfd_set_arch_mach (obfd, bfd_get_arch (ibfd),
00649                             bfd_get_mach (ibfd)))
00650        return FALSE;
00651     }
00652 
00653   return TRUE;
00654 }
00655 
00656 /* This function handles relaxing for the H8..
00657 
00658    There are a few relaxing opportunities available on the H8:
00659 
00660      jmp/jsr:24    ->    bra/bsr:8        2 bytes
00661      The jmp may be completely eliminated if the previous insn is a
00662      conditional branch to the insn after the jump.  In that case
00663      we invert the branch and delete the jump and save 4 bytes.
00664 
00665      bCC:16          ->    bCC:8                  2 bytes
00666      bsr:16          ->    bsr:8                  2 bytes
00667 
00668      bset:16       ->    bset:8                 2 bytes
00669      bset:24/32           ->    bset:8                 4 bytes
00670      (also applicable to other bit manipulation instructions)
00671 
00672      mov.b:16      ->    mov.b:8                2 bytes
00673      mov.b:24/32     ->    mov.b:8                4 bytes
00674 
00675      bset:24/32           ->    bset:16                2 bytes
00676      (also applicable to other bit manipulation instructions)
00677 
00678      mov.[bwl]:24/32 ->    mov.[bwl]:16           2 bytes */
00679 
00680 static bfd_boolean
00681 elf32_h8_relax_section (bfd *abfd, asection *sec,
00682                      struct bfd_link_info *link_info, bfd_boolean *again)
00683 {
00684   Elf_Internal_Shdr *symtab_hdr;
00685   Elf_Internal_Rela *internal_relocs;
00686   Elf_Internal_Rela *irel, *irelend;
00687   bfd_byte *contents = NULL;
00688   Elf_Internal_Sym *isymbuf = NULL;
00689   static asection *last_input_section = NULL;
00690   static Elf_Internal_Rela *last_reloc = NULL;
00691 
00692   /* Assume nothing changes.  */
00693   *again = FALSE;
00694 
00695   /* We don't have to do anything for a relocatable link, if
00696      this section does not have relocs, or if this is not a
00697      code section.  */
00698   if (link_info->relocatable
00699       || (sec->flags & SEC_RELOC) == 0
00700       || sec->reloc_count == 0
00701       || (sec->flags & SEC_CODE) == 0)
00702     return TRUE;
00703 
00704   symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
00705 
00706   /* Get a copy of the native relocations.  */
00707   internal_relocs = (_bfd_elf_link_read_relocs
00708                    (abfd, sec, (PTR) NULL, (Elf_Internal_Rela *) NULL,
00709                     link_info->keep_memory));
00710   if (internal_relocs == NULL)
00711     goto error_return;
00712 
00713   if (sec != last_input_section)
00714     last_reloc = NULL;
00715 
00716   last_input_section = sec;
00717 
00718   /* Walk through the relocs looking for relaxing opportunities.  */
00719   irelend = internal_relocs + sec->reloc_count;
00720   for (irel = internal_relocs; irel < irelend; irel++)
00721     {
00722       bfd_vma symval;
00723 
00724       /* Keep track of the previous reloc so that we can delete
00725         some long jumps created by the compiler.  */
00726       if (irel != internal_relocs)
00727        last_reloc = irel - 1;
00728 
00729       if (ELF32_R_TYPE (irel->r_info) != R_H8_DIR24R8
00730          && ELF32_R_TYPE (irel->r_info) != R_H8_PCREL16
00731          && ELF32_R_TYPE (irel->r_info) != R_H8_DIR16A8
00732          && ELF32_R_TYPE (irel->r_info) != R_H8_DIR24A8
00733          && ELF32_R_TYPE (irel->r_info) != R_H8_DIR32A16)
00734        continue;
00735 
00736       /* Get the section contents if we haven't done so already.  */
00737       if (contents == NULL)
00738        {
00739          /* Get cached copy if it exists.  */
00740          if (elf_section_data (sec)->this_hdr.contents != NULL)
00741            contents = elf_section_data (sec)->this_hdr.contents;
00742          else
00743            {
00744              /* Go get them off disk.  */
00745              if (!bfd_malloc_and_get_section (abfd, sec, &contents))
00746               goto error_return;
00747            }
00748        }
00749 
00750       /* Read this BFD's local symbols if we haven't done so already.  */
00751       if (isymbuf == NULL && symtab_hdr->sh_info != 0)
00752        {
00753          isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
00754          if (isymbuf == NULL)
00755            isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr,
00756                                        symtab_hdr->sh_info, 0,
00757                                        NULL, NULL, NULL);
00758          if (isymbuf == NULL)
00759            goto error_return;
00760        }
00761 
00762       /* Get the value of the symbol referred to by the reloc.  */
00763       if (ELF32_R_SYM (irel->r_info) < symtab_hdr->sh_info)
00764        {
00765          /* A local symbol.  */
00766          Elf_Internal_Sym *isym;
00767          asection *sym_sec;
00768 
00769          isym = isymbuf + ELF32_R_SYM (irel->r_info);
00770          sym_sec = bfd_section_from_elf_index (abfd, isym->st_shndx);
00771          symval = isym->st_value;
00772          /* If the reloc is absolute, it will not have
00773             a symbol or section associated with it.  */
00774          if (sym_sec)
00775            symval += sym_sec->output_section->vma
00776              + sym_sec->output_offset;
00777        }
00778       else
00779        {
00780          unsigned long indx;
00781          struct elf_link_hash_entry *h;
00782 
00783          /* An external symbol.  */
00784          indx = ELF32_R_SYM (irel->r_info) - symtab_hdr->sh_info;
00785          h = elf_sym_hashes (abfd)[indx];
00786          BFD_ASSERT (h != NULL);
00787          if (h->root.type != bfd_link_hash_defined
00788              && h->root.type != bfd_link_hash_defweak)
00789            {
00790              /* This appears to be a reference to an undefined
00791                  symbol.  Just ignore it--it will be caught by the
00792                  regular reloc processing.  */
00793              continue;
00794            }
00795 
00796          symval = (h->root.u.def.value
00797                   + h->root.u.def.section->output_section->vma
00798                   + h->root.u.def.section->output_offset);
00799        }
00800 
00801       /* For simplicity of coding, we are going to modify the section
00802         contents, the section relocs, and the BFD symbol table.  We
00803         must tell the rest of the code not to free up this
00804         information.  It would be possible to instead create a table
00805         of changes which have to be made, as is done in coff-mips.c;
00806         that would be more work, but would require less memory when
00807         the linker is run.  */
00808       switch (ELF32_R_TYPE (irel->r_info))
00809        {
00810         /* Try to turn a 24-bit absolute branch/call into an 8-bit
00811           pc-relative branch/call.  */
00812        case R_H8_DIR24R8:
00813          {
00814            bfd_vma value = symval + irel->r_addend;
00815            bfd_vma dot, gap;
00816 
00817            /* Get the address of this instruction.  */
00818            dot = (sec->output_section->vma
00819                  + sec->output_offset + irel->r_offset - 1);
00820 
00821            /* Compute the distance from this insn to the branch target.  */
00822            gap = value - dot;
00823 
00824            /* If the distance is within -126..+130 inclusive, then we can
00825               relax this jump.  +130 is valid since the target will move
00826               two bytes closer if we do relax this branch.  */
00827            if ((int) gap >= -126 && (int) gap <= 130)
00828              {
00829               unsigned char code;
00830 
00831               /* Note that we've changed the relocs, section contents,
00832                  etc.  */
00833               elf_section_data (sec)->relocs = internal_relocs;
00834               elf_section_data (sec)->this_hdr.contents = contents;
00835               symtab_hdr->contents = (unsigned char *) isymbuf;
00836 
00837               /* Get the instruction code being relaxed.  */
00838               code = bfd_get_8 (abfd, contents + irel->r_offset - 1);
00839 
00840               /* If the previous instruction conditionally jumped around
00841                  this instruction, we may be able to reverse the condition
00842                  and redirect the previous instruction to the target of
00843                  this instruction.
00844 
00845                  Such sequences are used by the compiler to deal with
00846                  long conditional branches.
00847 
00848                  Only perform this optimisation for jumps (code 0x5a) not
00849                  subroutine calls, as otherwise it could transform:
00850 
00851                                   mov.w   r0,r0
00852                                   beq     .L1
00853                                  jsr     @_bar
00854                             .L1:   rts
00855                             _bar:  rts
00856                  into:
00857                                   mov.w   r0,r0
00858                                   bne     _bar
00859                                   rts
00860                            _bar:  rts
00861 
00862                  which changes the call (jsr) into a branch (bne).  */
00863               if (code == 0x5a
00864                   && (int) gap <= 130
00865                   && (int) gap >= -128
00866                   && last_reloc
00867                   && ELF32_R_TYPE (last_reloc->r_info) == R_H8_PCREL8
00868                   && ELF32_R_SYM (last_reloc->r_info) < symtab_hdr->sh_info)
00869                 {
00870                   bfd_vma last_value;
00871                   asection *last_sym_sec;
00872                   Elf_Internal_Sym *last_sym;
00873 
00874                   /* We will need to examine the symbol used by the
00875                      previous relocation.  */
00876 
00877                   last_sym = isymbuf + ELF32_R_SYM (last_reloc->r_info);
00878                   last_sym_sec
00879                     = bfd_section_from_elf_index (abfd, last_sym->st_shndx);
00880                   last_value = (last_sym->st_value
00881                               + last_sym_sec->output_section->vma
00882                               + last_sym_sec->output_offset);
00883 
00884                   /* Verify that the previous relocation was for a
00885                      branch around this instruction and that no symbol
00886                      exists at the current location.  */
00887                   if (last_value == dot + 4
00888                      && last_reloc->r_offset + 2 == irel->r_offset
00889                      && ! elf32_h8_symbol_address_p (abfd, sec, dot))
00890                     {
00891                      /* We can eliminate this jump.  Twiddle the
00892                         previous relocation as necessary.  */
00893                      irel->r_info
00894                        = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
00895                                      ELF32_R_TYPE (R_H8_NONE));
00896 
00897                      last_reloc->r_info
00898                        = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
00899                                      ELF32_R_TYPE (R_H8_PCREL8));
00900                      last_reloc->r_addend = irel->r_addend;
00901 
00902                      code = bfd_get_8 (abfd,
00903                                      contents + last_reloc->r_offset - 1);
00904                      code ^= 1;
00905                      bfd_put_8 (abfd,
00906                                code,
00907                      contents + last_reloc->r_offset - 1);
00908 
00909                      /* Delete four bytes of data.  */
00910                      if (!elf32_h8_relax_delete_bytes (abfd, sec,
00911                                                    irel->r_offset - 1,
00912                                                    4))
00913                        goto error_return;
00914 
00915                      *again = TRUE;
00916                      break;
00917                     }
00918                 }
00919 
00920               if (code == 0x5e)
00921                 /* This is jsr.  */
00922                 bfd_put_8 (abfd, 0x55, contents + irel->r_offset - 1);
00923               else if (code == 0x5a)
00924                 /* This is jmp.  */
00925                 bfd_put_8 (abfd, 0x40, contents + irel->r_offset - 1);
00926               else
00927                 abort ();
00928 
00929               /* Fix the relocation's type.  */
00930               irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
00931                                         R_H8_PCREL8);
00932 
00933               /* Delete two bytes of data.  */
00934               if (!elf32_h8_relax_delete_bytes (abfd, sec,
00935                                             irel->r_offset + 1, 2))
00936                 goto error_return;
00937 
00938               /* That will change things, so, we should relax again.
00939                  Note that this is not required, and it may be slow.  */
00940               *again = TRUE;
00941              }
00942            break;
00943          }
00944 
00945        /* Try to turn a 16-bit pc-relative branch into a 8-bit pc-relative
00946           branch.  */
00947        case R_H8_PCREL16:
00948          {
00949            bfd_vma value = symval + irel->r_addend;
00950            bfd_vma dot;
00951            bfd_vma gap;
00952 
00953            /* Get the address of this instruction.  */
00954            dot = (sec->output_section->vma
00955                  + sec->output_offset
00956                  + irel->r_offset - 2);
00957 
00958            gap = value - dot;
00959 
00960            /* If the distance is within -126..+130 inclusive, then we can
00961               relax this jump.  +130 is valid since the target will move
00962               two bytes closer if we do relax this branch.  */
00963            if ((int) gap >= -126 && (int) gap <= 130)
00964              {
00965               unsigned char code;
00966 
00967               /* Note that we've changed the relocs, section contents,
00968                  etc.  */
00969               elf_section_data (sec)->relocs = internal_relocs;
00970               elf_section_data (sec)->this_hdr.contents = contents;
00971               symtab_hdr->contents = (unsigned char *) isymbuf;
00972 
00973               /* Get the opcode.  */
00974               code = bfd_get_8 (abfd, contents + irel->r_offset - 2);
00975 
00976               if (code == 0x58)
00977                 {
00978                   /* bCC:16 -> bCC:8 */
00979                   /* Get the second byte of the original insn, which
00980                      contains the condition code.  */
00981                   code = bfd_get_8 (abfd, contents + irel->r_offset - 1);
00982 
00983                   /* Compute the fisrt byte of the relaxed
00984                      instruction.  The original sequence 0x58 0xX0
00985                      is relaxed to 0x4X, where X represents the
00986                      condition code.  */
00987                   code &= 0xf0;
00988                   code >>= 4;
00989                   code |= 0x40;
00990                   bfd_put_8 (abfd, code, contents + irel->r_offset - 2);
00991                 }
00992               else if (code == 0x5c)
00993                 /* This is bsr.  */
00994                 bfd_put_8 (abfd, 0x55, contents + irel->r_offset - 2);
00995               else
00996                 abort ();
00997 
00998               /* Fix the relocation's type.  */
00999               irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
01000                                         R_H8_PCREL8);
01001               irel->r_offset--;
01002 
01003               /* Delete two bytes of data.  */
01004               if (!elf32_h8_relax_delete_bytes (abfd, sec,
01005                                             irel->r_offset + 1, 2))
01006                 goto error_return;
01007 
01008               /* That will change things, so, we should relax again.
01009                  Note that this is not required, and it may be slow.  */
01010               *again = TRUE;
01011              }
01012            break;
01013          }
01014 
01015        /* This is a 16-bit absolute address in one of the following
01016           instructions:
01017 
01018             "band", "bclr", "biand", "bild", "bior", "bist", "bixor",
01019             "bld", "bnot", "bor", "bset", "bst", "btst", "bxor", and
01020             "mov.b"
01021 
01022           We may relax this into an 8-bit absolute address if it's in
01023           the right range.  */
01024        case R_H8_DIR16A8:
01025          {
01026            bfd_vma value;
01027 
01028            value = bfd_h8300_pad_address (abfd, symval + irel->r_addend);
01029            if (value >= 0xffffff00u)
01030              {
01031               unsigned char code;
01032               unsigned char temp_code;
01033 
01034               /* Note that we've changed the relocs, section contents,
01035                  etc.  */
01036               elf_section_data (sec)->relocs = internal_relocs;
01037               elf_section_data (sec)->this_hdr.contents = contents;
01038               symtab_hdr->contents = (unsigned char *) isymbuf;
01039 
01040               /* Get the opcode.  */
01041               code = bfd_get_8 (abfd, contents + irel->r_offset - 2);
01042 
01043               /* All instructions with R_H8_DIR16A8 start with
01044                  0x6a.  */
01045               if (code != 0x6a)
01046                 abort ();
01047 
01048               temp_code = code = bfd_get_8 (abfd, contents + irel->r_offset - 1);
01049               /* If this is a mov.b instruction, clear the lower
01050                  nibble, which contains the source/destination
01051                  register number.  */
01052               if ((temp_code & 0x10) != 0x10)
01053                 temp_code &= 0xf0;
01054 
01055               switch (temp_code)
01056                 {
01057                 case 0x00:
01058                   /* This is mov.b @aa:16,Rd.  */
01059                   bfd_put_8 (abfd, (code & 0xf) | 0x20,
01060                             contents + irel->r_offset - 2);
01061                   break;
01062                 case 0x80:
01063                   /* This is mov.b Rs,@aa:16.  */
01064                   bfd_put_8 (abfd, (code & 0xf) | 0x30,
01065                             contents + irel->r_offset - 2);
01066                   break;
01067                 case 0x18:
01068                   /* This is a bit-maniputation instruction that
01069                      stores one bit into memory, one of "bclr",
01070                      "bist", "bnot", "bset", and "bst".  */
01071                   bfd_put_8 (abfd, 0x7f, contents + irel->r_offset - 2);
01072                   break;
01073                 case 0x10:
01074                   /* This is a bit-maniputation instruction that
01075                      loads one bit from memory, one of "band",
01076                      "biand", "bild", "bior", "bixor", "bld", "bor",
01077                      "btst", and "bxor".  */
01078                   bfd_put_8 (abfd, 0x7e, contents + irel->r_offset - 2);
01079                   break;
01080                 default:
01081                   abort ();
01082                 }
01083 
01084               /* Fix the relocation's type.  */
01085               irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
01086                                         R_H8_DIR8);
01087 
01088               /* Move the relocation.  */
01089               irel->r_offset--;
01090 
01091               /* Delete two bytes of data.  */
01092               if (!elf32_h8_relax_delete_bytes (abfd, sec,
01093                                             irel->r_offset + 1, 2))
01094                 goto error_return;
01095 
01096               /* That will change things, so, we should relax again.
01097                  Note that this is not required, and it may be slow.  */
01098               *again = TRUE;
01099              }
01100            break;
01101          }
01102 
01103        /* This is a 24-bit absolute address in one of the following
01104           instructions:
01105 
01106             "band", "bclr", "biand", "bild", "bior", "bist", "bixor",
01107             "bld", "bnot", "bor", "bset", "bst", "btst", "bxor", and
01108             "mov.b"
01109 
01110           We may relax this into an 8-bit absolute address if it's in
01111           the right range.  */
01112        case R_H8_DIR24A8:
01113          {
01114            bfd_vma value;
01115 
01116            value = bfd_h8300_pad_address (abfd, symval + irel->r_addend);
01117            if (value >= 0xffffff00u)
01118              {
01119               unsigned char code;
01120               unsigned char temp_code;
01121 
01122               /* Note that we've changed the relocs, section contents,
01123                  etc.  */
01124               elf_section_data (sec)->relocs = internal_relocs;
01125               elf_section_data (sec)->this_hdr.contents = contents;
01126               symtab_hdr->contents = (unsigned char *) isymbuf;
01127 
01128               /* Get the opcode.  */
01129               code = bfd_get_8 (abfd, contents + irel->r_offset - 2);
01130 
01131               /* All instructions with R_H8_DIR24A8 start with
01132                  0x6a.  */
01133               if (code != 0x6a)
01134                 abort ();
01135 
01136               temp_code = code = bfd_get_8 (abfd, contents + irel->r_offset - 1);
01137 
01138               /* If this is a mov.b instruction, clear the lower
01139                  nibble, which contains the source/destination
01140                  register number.  */
01141               if ((temp_code & 0x30) != 0x30)
01142                 temp_code &= 0xf0;
01143 
01144               switch (temp_code)
01145                 {
01146                 case 0x20:
01147                   /* This is mov.b @aa:24/32,Rd.  */
01148                   bfd_put_8 (abfd, (code & 0xf) | 0x20,
01149                             contents + irel->r_offset - 2);
01150                   break;
01151                 case 0xa0:
01152                   /* This is mov.b Rs,@aa:24/32.  */
01153                   bfd_put_8 (abfd, (code & 0xf) | 0x30,
01154                             contents + irel->r_offset - 2);
01155                   break;
01156                 case 0x38:
01157                   /* This is a bit-maniputation instruction that
01158                      stores one bit into memory, one of "bclr",
01159                      "bist", "bnot", "bset", and "bst".  */
01160                   bfd_put_8 (abfd, 0x7f, contents + irel->r_offset - 2);
01161                   break;
01162                 case 0x30:
01163                   /* This is a bit-maniputation instruction that
01164                      loads one bit from memory, one of "band",
01165                      "biand", "bild", "bior", "bixor", "bld", "bor",
01166                      "btst", and "bxor".  */
01167                   bfd_put_8 (abfd, 0x7e, contents + irel->r_offset - 2);
01168                   break;
01169                 default:
01170                   abort();
01171                 }
01172 
01173               /* Fix the relocation's type.  */
01174               irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
01175                                         R_H8_DIR8);
01176               irel->r_offset--;
01177 
01178               /* Delete two bytes of data.  */
01179               if (!elf32_h8_relax_delete_bytes (abfd, sec,
01180                                             irel->r_offset + 1, 4))
01181                 goto error_return;
01182 
01183               /* That will change things, so, we should relax again.
01184                  Note that this is not required, and it may be slow.  */
01185               *again = TRUE;
01186               break;
01187              }
01188          }
01189 
01190          /* Fall through.  */
01191 
01192          /* This is a 24-/32-bit absolute address in one of the
01193             following instructions:
01194 
01195               "band", "bclr", "biand", "bild", "bior", "bist",
01196               "bixor", "bld", "bnot", "bor", "bset", "bst", "btst",
01197               "bxor", "ldc.w", "stc.w" and "mov.[bwl]"
01198 
01199             We may relax this into an 16-bit absolute address if it's
01200             in the right range.  */
01201        case R_H8_DIR32A16:
01202          {
01203            bfd_vma value;
01204 
01205            value = bfd_h8300_pad_address (abfd, symval + irel->r_addend);
01206            if (value <= 0x7fff || value >= 0xffff8000u)
01207              {
01208               unsigned char code;
01209 
01210               /* Note that we've changed the relocs, section contents,
01211                  etc.  */
01212               elf_section_data (sec)->relocs = internal_relocs;
01213               elf_section_data (sec)->this_hdr.contents = contents;
01214               symtab_hdr->contents = (unsigned char *) isymbuf;
01215 
01216               /* Get the opcode.  */
01217               code = bfd_get_8 (abfd, contents + irel->r_offset - 1);
01218 
01219               /* Fix the opcode.  For all the instructions that
01220                  belong to this relaxation, we simply need to turn
01221                  off bit 0x20 in the previous byte.  */
01222               code &= ~0x20;
01223 
01224               bfd_put_8 (abfd, code, contents + irel->r_offset - 1);
01225 
01226               /* Fix the relocation's type.  */
01227               irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
01228                                         R_H8_DIR16);
01229 
01230               /* Delete two bytes of data.  */
01231               if (!elf32_h8_relax_delete_bytes (abfd, sec,
01232                                             irel->r_offset + 1, 2))
01233                 goto error_return;
01234 
01235               /* That will change things, so, we should relax again.
01236                  Note that this is not required, and it may be slow.  */
01237               *again = TRUE;
01238              }
01239            break;
01240          }
01241 
01242        default:
01243          break;
01244        }
01245     }
01246 
01247   if (isymbuf != NULL
01248       && symtab_hdr->contents != (unsigned char *) isymbuf)
01249     {
01250       if (! link_info->keep_memory)
01251        free (isymbuf);
01252       else
01253        symtab_hdr->contents = (unsigned char *) isymbuf;
01254     }
01255 
01256   if (contents != NULL
01257       && elf_section_data (sec)->this_hdr.contents != contents)
01258     {
01259       if (! link_info->keep_memory)
01260        free (contents);
01261       else
01262        {
01263          /* Cache the section contents for elf_link_input_bfd.  */
01264          elf_section_data (sec)->this_hdr.contents = contents;
01265        }
01266     }
01267 
01268   if (internal_relocs != NULL
01269       && elf_section_data (sec)->relocs != internal_relocs)
01270     free (internal_relocs);
01271 
01272   return TRUE;
01273 
01274  error_return:
01275   if (isymbuf != NULL
01276       && symtab_hdr->contents != (unsigned char *) isymbuf)
01277     free (isymbuf);
01278   if (contents != NULL
01279       && elf_section_data (sec)->this_hdr.contents != contents)
01280     free (contents);
01281   if (internal_relocs != NULL
01282       && elf_section_data (sec)->relocs != internal_relocs)
01283     free (internal_relocs);
01284   return FALSE;
01285 }
01286 
01287 /* Delete some bytes from a section while relaxing.  */
01288 
01289 static bfd_boolean
01290 elf32_h8_relax_delete_bytes (bfd *abfd, asection *sec, bfd_vma addr, int count)
01291 {
01292   Elf_Internal_Shdr *symtab_hdr;
01293   unsigned int sec_shndx;
01294   bfd_byte *contents;
01295   Elf_Internal_Rela *irel, *irelend;
01296   Elf_Internal_Rela *irelalign;
01297   Elf_Internal_Sym *isym;
01298   Elf_Internal_Sym *isymend;
01299   bfd_vma toaddr;
01300   struct elf_link_hash_entry **sym_hashes;
01301   struct elf_link_hash_entry **end_hashes;
01302   unsigned int symcount;
01303 
01304   sec_shndx = _bfd_elf_section_from_bfd_section (abfd, sec);
01305 
01306   contents = elf_section_data (sec)->this_hdr.contents;
01307 
01308   /* The deletion must stop at the next ALIGN reloc for an aligment
01309      power larger than the number of bytes we are deleting.  */
01310 
01311   irelalign = NULL;
01312   toaddr = sec->size;
01313 
01314   irel = elf_section_data (sec)->relocs;
01315   irelend = irel + sec->reloc_count;
01316 
01317   /* Actually delete the bytes.  */
01318   memmove (contents + addr, contents + addr + count,
01319           (size_t) (toaddr - addr - count));
01320   sec->size -= count;
01321 
01322   /* Adjust all the relocs.  */
01323   for (irel = elf_section_data (sec)->relocs; irel < irelend; irel++)
01324     {
01325       /* Get the new reloc address.  */
01326       if ((irel->r_offset > addr
01327           && irel->r_offset < toaddr))
01328        irel->r_offset -= count;
01329     }
01330 
01331   /* Adjust the local symbols defined in this section.  */
01332   symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
01333   isym = (Elf_Internal_Sym *) symtab_hdr->contents;
01334   isymend = isym + symtab_hdr->sh_info;
01335   for (; isym < isymend; isym++)
01336     {
01337       if (isym->st_shndx == sec_shndx
01338          && isym->st_value > addr
01339          && isym->st_value < toaddr)
01340        isym->st_value -= count;
01341     }
01342 
01343   /* Now adjust the global symbols defined in this section.  */
01344   symcount = (symtab_hdr->sh_size / sizeof (Elf32_External_Sym)
01345              - symtab_hdr->sh_info);
01346   sym_hashes = elf_sym_hashes (abfd);
01347   end_hashes = sym_hashes + symcount;
01348   for (; sym_hashes < end_hashes; sym_hashes++)
01349     {
01350       struct elf_link_hash_entry *sym_hash = *sym_hashes;
01351       if ((sym_hash->root.type == bfd_link_hash_defined
01352           || sym_hash->root.type == bfd_link_hash_defweak)
01353          && sym_hash->root.u.def.section == sec
01354          && sym_hash->root.u.def.value > addr
01355          && sym_hash->root.u.def.value < toaddr)
01356        {
01357          sym_hash->root.u.def.value -= count;
01358        }
01359     }
01360 
01361   return TRUE;
01362 }
01363 
01364 /* Return TRUE if a symbol exists at the given address, else return
01365    FALSE.  */
01366 static bfd_boolean
01367 elf32_h8_symbol_address_p (bfd *abfd, asection *sec, bfd_vma addr)
01368 {
01369   Elf_Internal_Shdr *symtab_hdr;
01370   unsigned int sec_shndx;
01371   Elf_Internal_Sym *isym;
01372   Elf_Internal_Sym *isymend;
01373   struct elf_link_hash_entry **sym_hashes;
01374   struct elf_link_hash_entry **end_hashes;
01375   unsigned int symcount;
01376 
01377   sec_shndx = _bfd_elf_section_from_bfd_section (abfd, sec);
01378 
01379   /* Examine all the symbols.  */
01380   symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
01381   isym = (Elf_Internal_Sym *) symtab_hdr->contents;
01382   isymend = isym + symtab_hdr->sh_info;
01383   for (; isym < isymend; isym++)
01384     {
01385       if (isym->st_shndx == sec_shndx
01386          && isym->st_value == addr)
01387        return TRUE;
01388     }
01389 
01390   symcount = (symtab_hdr->sh_size / sizeof (Elf32_External_Sym)
01391              - symtab_hdr->sh_info);
01392   sym_hashes = elf_sym_hashes (abfd);
01393   end_hashes = sym_hashes + symcount;
01394   for (; sym_hashes < end_hashes; sym_hashes++)
01395     {
01396       struct elf_link_hash_entry *sym_hash = *sym_hashes;
01397       if ((sym_hash->root.type == bfd_link_hash_defined
01398           || sym_hash->root.type == bfd_link_hash_defweak)
01399          && sym_hash->root.u.def.section == sec
01400          && sym_hash->root.u.def.value == addr)
01401        return TRUE;
01402     }
01403 
01404   return FALSE;
01405 }
01406 
01407 /* This is a version of bfd_generic_get_relocated_section_contents
01408    which uses elf32_h8_relocate_section.  */
01409 
01410 static bfd_byte *
01411 elf32_h8_get_relocated_section_contents (bfd *output_bfd,
01412                                     struct bfd_link_info *link_info,
01413                                     struct bfd_link_order *link_order,
01414                                     bfd_byte *data,
01415                                     bfd_boolean relocatable,
01416                                     asymbol **symbols)
01417 {
01418   Elf_Internal_Shdr *symtab_hdr;
01419   asection *input_section = link_order->u.indirect.section;
01420   bfd *input_bfd = input_section->owner;
01421   asection **sections = NULL;
01422   Elf_Internal_Rela *internal_relocs = NULL;
01423   Elf_Internal_Sym *isymbuf = NULL;
01424 
01425   /* We only need to handle the case of relaxing, or of having a
01426      particular set of section contents, specially.  */
01427   if (relocatable
01428       || elf_section_data (input_section)->this_hdr.contents == NULL)
01429     return bfd_generic_get_relocated_section_contents (output_bfd, link_info,
01430                                                  link_order, data,
01431                                                  relocatable,
01432                                                  symbols);
01433 
01434   symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
01435 
01436   memcpy (data, elf_section_data (input_section)->this_hdr.contents,
01437          (size_t) input_section->size);
01438 
01439   if ((input_section->flags & SEC_RELOC) != 0
01440       && input_section->reloc_count > 0)
01441     {
01442       asection **secpp;
01443       Elf_Internal_Sym *isym, *isymend;
01444       bfd_size_type amt;
01445 
01446       internal_relocs = (_bfd_elf_link_read_relocs
01447                       (input_bfd, input_section, (PTR) NULL,
01448                        (Elf_Internal_Rela *) NULL, FALSE));
01449       if (internal_relocs == NULL)
01450        goto error_return;
01451 
01452       if (symtab_hdr->sh_info != 0)
01453        {
01454          isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
01455          if (isymbuf == NULL)
01456            isymbuf = bfd_elf_get_elf_syms (input_bfd, symtab_hdr,
01457                                        symtab_hdr->sh_info, 0,
01458                                        NULL, NULL, NULL);
01459          if (isymbuf == NULL)
01460            goto error_return;
01461        }
01462 
01463       amt = symtab_hdr->sh_info;
01464       amt *= sizeof (asection *);
01465       sections = (asection **) bfd_malloc (amt);
01466       if (sections == NULL && amt != 0)
01467        goto error_return;
01468 
01469       isymend = isymbuf + symtab_hdr->sh_info;
01470       for (isym = isymbuf, secpp = sections; isym < isymend; ++isym, ++secpp)
01471        {
01472          asection *isec;
01473 
01474          if (isym->st_shndx == SHN_UNDEF)
01475            isec = bfd_und_section_ptr;
01476          else if (isym->st_shndx == SHN_ABS)
01477            isec = bfd_abs_section_ptr;
01478          else if (isym->st_shndx == SHN_COMMON)
01479            isec = bfd_com_section_ptr;
01480          else
01481            isec = bfd_section_from_elf_index (input_bfd, isym->st_shndx);
01482 
01483          *secpp = isec;
01484        }
01485 
01486       if (! elf32_h8_relocate_section (output_bfd, link_info, input_bfd,
01487                                    input_section, data, internal_relocs,
01488                                    isymbuf, sections))
01489        goto error_return;
01490 
01491       if (sections != NULL)
01492        free (sections);
01493       if (isymbuf != NULL
01494          && symtab_hdr->contents != (unsigned char *) isymbuf)
01495        free (isymbuf);
01496       if (elf_section_data (input_section)->relocs != internal_relocs)
01497        free (internal_relocs);
01498     }
01499 
01500   return data;
01501 
01502  error_return:
01503   if (sections != NULL)
01504     free (sections);
01505   if (isymbuf != NULL
01506       && symtab_hdr->contents != (unsigned char *) isymbuf)
01507     free (isymbuf);
01508   if (internal_relocs != NULL
01509       && elf_section_data (input_section)->relocs != internal_relocs)
01510     free (internal_relocs);
01511   return NULL;
01512 }
01513 
01514 
01515 #define TARGET_BIG_SYM                    bfd_elf32_h8300_vec
01516 #define TARGET_BIG_NAME                   "elf32-h8300"
01517 #define ELF_ARCH                   bfd_arch_h8300
01518 #define ELF_MACHINE_CODE           EM_H8_300
01519 #define ELF_MAXPAGESIZE                   0x1
01520 #define bfd_elf32_bfd_reloc_type_lookup elf32_h8_reloc_type_lookup
01521 #define bfd_elf32_bfd_reloc_name_lookup elf32_h8_reloc_name_lookup
01522 #define elf_info_to_howto          elf32_h8_info_to_howto
01523 #define elf_info_to_howto_rel             elf32_h8_info_to_howto_rel
01524 
01525 /* So we can set/examine bits in e_flags to get the specific
01526    H8 architecture in use.  */
01527 #define elf_backend_final_write_processing \
01528   elf32_h8_final_write_processing
01529 #define elf_backend_object_p \
01530   elf32_h8_object_p
01531 #define bfd_elf32_bfd_merge_private_bfd_data \
01532   elf32_h8_merge_private_bfd_data
01533 
01534 /* ??? when elf_backend_relocate_section is not defined, elf32-target.h
01535    defaults to using _bfd_generic_link_hash_table_create, but
01536    bfd_elf_size_dynamic_sections uses
01537    dynobj = elf_hash_table (info)->dynobj;
01538    and thus requires an elf hash table.  */
01539 #define bfd_elf32_bfd_link_hash_table_create _bfd_elf_link_hash_table_create
01540 
01541 /* Use an H8 specific linker, not the ELF generic linker.  */
01542 #define elf_backend_relocate_section elf32_h8_relocate_section
01543 #define elf_backend_rela_normal           1
01544 #define elf_backend_can_gc_sections       1
01545 
01546 /* And relaxing stuff.  */
01547 #define bfd_elf32_bfd_relax_section     elf32_h8_relax_section
01548 #define bfd_elf32_bfd_get_relocated_section_contents \
01549                                 elf32_h8_get_relocated_section_contents
01550 
01551 
01552 #include "elf32-target.h"