Back to index

cell-binutils  2.17cvs20070401
elf-m10200.c
Go to the documentation of this file.
00001 /* Matsushita 10200 specific support for 32-bit ELF
00002    Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2007
00003    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 
00026 static reloc_howto_type *bfd_elf32_bfd_reloc_type_lookup
00027   PARAMS ((bfd *abfd, bfd_reloc_code_real_type code));
00028 static void mn10200_info_to_howto
00029   PARAMS ((bfd *, arelent *, Elf_Internal_Rela *));
00030 static bfd_boolean mn10200_elf_relax_delete_bytes
00031   PARAMS ((bfd *, asection *, bfd_vma, int));
00032 static bfd_boolean mn10200_elf_symbol_address_p
00033   PARAMS ((bfd *, asection *, Elf_Internal_Sym *, bfd_vma));
00034 static bfd_reloc_status_type mn10200_elf_final_link_relocate
00035   PARAMS ((reloc_howto_type *, bfd *, bfd *, asection *,
00036           bfd_byte *, bfd_vma, bfd_vma, bfd_vma,
00037           struct bfd_link_info *, asection *, int));
00038 static bfd_boolean mn10200_elf_relocate_section
00039   PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *,
00040           bfd_byte *, Elf_Internal_Rela *, Elf_Internal_Sym *,
00041           asection **));
00042 static bfd_boolean mn10200_elf_relax_section
00043   PARAMS ((bfd *, asection *, struct bfd_link_info *, bfd_boolean *));
00044 static bfd_byte * mn10200_elf_get_relocated_section_contents
00045   PARAMS ((bfd *, struct bfd_link_info *, struct bfd_link_order *,
00046           bfd_byte *, bfd_boolean, asymbol **));
00047 
00048 enum reloc_type {
00049   R_MN10200_NONE = 0,
00050   R_MN10200_32,
00051   R_MN10200_16,
00052   R_MN10200_8,
00053   R_MN10200_24,
00054   R_MN10200_PCREL8,
00055   R_MN10200_PCREL16,
00056   R_MN10200_PCREL24,
00057   R_MN10200_MAX
00058 };
00059 
00060 static reloc_howto_type elf_mn10200_howto_table[] = {
00061   /* Dummy relocation.  Does nothing.  */
00062   HOWTO (R_MN10200_NONE,
00063         0,
00064         2,
00065         16,
00066         FALSE,
00067         0,
00068         complain_overflow_bitfield,
00069         bfd_elf_generic_reloc,
00070         "R_MN10200_NONE",
00071         FALSE,
00072         0,
00073         0,
00074         FALSE),
00075   /* Standard 32 bit reloc.  */
00076   HOWTO (R_MN10200_32,
00077         0,
00078         2,
00079         32,
00080         FALSE,
00081         0,
00082         complain_overflow_bitfield,
00083         bfd_elf_generic_reloc,
00084         "R_MN10200_32",
00085         FALSE,
00086         0xffffffff,
00087         0xffffffff,
00088         FALSE),
00089   /* Standard 16 bit reloc.  */
00090   HOWTO (R_MN10200_16,
00091         0,
00092         1,
00093         16,
00094         FALSE,
00095         0,
00096         complain_overflow_bitfield,
00097         bfd_elf_generic_reloc,
00098         "R_MN10200_16",
00099         FALSE,
00100         0xffff,
00101         0xffff,
00102         FALSE),
00103   /* Standard 8 bit reloc.  */
00104   HOWTO (R_MN10200_8,
00105         0,
00106         0,
00107         8,
00108         FALSE,
00109         0,
00110         complain_overflow_bitfield,
00111         bfd_elf_generic_reloc,
00112         "R_MN10200_8",
00113         FALSE,
00114         0xff,
00115         0xff,
00116         FALSE),
00117   /* Standard 24 bit reloc.  */
00118   HOWTO (R_MN10200_24,
00119         0,
00120         2,
00121         24,
00122         FALSE,
00123         0,
00124         complain_overflow_bitfield,
00125         bfd_elf_generic_reloc,
00126         "R_MN10200_24",
00127         FALSE,
00128         0xffffff,
00129         0xffffff,
00130         FALSE),
00131   /* Simple 8 pc-relative reloc.  */
00132   HOWTO (R_MN10200_PCREL8,
00133         0,
00134         0,
00135         8,
00136         TRUE,
00137         0,
00138         complain_overflow_bitfield,
00139         bfd_elf_generic_reloc,
00140         "R_MN10200_PCREL8",
00141         FALSE,
00142         0xff,
00143         0xff,
00144         TRUE),
00145   /* Simple 16 pc-relative reloc.  */
00146   HOWTO (R_MN10200_PCREL16,
00147         0,
00148         1,
00149         16,
00150         TRUE,
00151         0,
00152         complain_overflow_bitfield,
00153         bfd_elf_generic_reloc,
00154         "R_MN10200_PCREL16",
00155         FALSE,
00156         0xffff,
00157         0xffff,
00158         TRUE),
00159   /* Simple 32bit pc-relative reloc with a 1 byte adjustment
00160      to get the pc-relative offset correct.  */
00161   HOWTO (R_MN10200_PCREL24,
00162         0,
00163         2,
00164         24,
00165         TRUE,
00166         0,
00167         complain_overflow_bitfield,
00168         bfd_elf_generic_reloc,
00169         "R_MN10200_PCREL24",
00170         FALSE,
00171         0xffffff,
00172         0xffffff,
00173         TRUE),
00174 };
00175 
00176 struct mn10200_reloc_map {
00177   bfd_reloc_code_real_type bfd_reloc_val;
00178   unsigned char elf_reloc_val;
00179 };
00180 
00181 static const struct mn10200_reloc_map mn10200_reloc_map[] = {
00182   { BFD_RELOC_NONE    , R_MN10200_NONE   , },
00183   { BFD_RELOC_32      , R_MN10200_32     , },
00184   { BFD_RELOC_16      , R_MN10200_16     , },
00185   { BFD_RELOC_8       , R_MN10200_8      , },
00186   { BFD_RELOC_24      , R_MN10200_24     , },
00187   { BFD_RELOC_8_PCREL , R_MN10200_PCREL8 , },
00188   { BFD_RELOC_16_PCREL, R_MN10200_PCREL16, },
00189   { BFD_RELOC_24_PCREL, R_MN10200_PCREL24, },
00190 };
00191 
00192 static reloc_howto_type *
00193 bfd_elf32_bfd_reloc_type_lookup (abfd, code)
00194      bfd *abfd ATTRIBUTE_UNUSED;
00195      bfd_reloc_code_real_type code;
00196 {
00197   unsigned int i;
00198 
00199   for (i = 0;
00200        i < sizeof (mn10200_reloc_map) / sizeof (struct mn10200_reloc_map);
00201        i++)
00202     {
00203       if (mn10200_reloc_map[i].bfd_reloc_val == code)
00204        return &elf_mn10200_howto_table[mn10200_reloc_map[i].elf_reloc_val];
00205     }
00206 
00207   return NULL;
00208 }
00209 
00210 static reloc_howto_type *
00211 bfd_elf32_bfd_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
00212                              const char *r_name)
00213 {
00214   unsigned int i;
00215 
00216   for (i = 0;
00217        i < (sizeof (elf_mn10200_howto_table)
00218            / sizeof (elf_mn10200_howto_table[0]));
00219        i++)
00220     if (elf_mn10200_howto_table[i].name != NULL
00221        && strcasecmp (elf_mn10200_howto_table[i].name, r_name) == 0)
00222       return &elf_mn10200_howto_table[i];
00223 
00224   return NULL;
00225 }
00226 
00227 /* Set the howto pointer for an MN10200 ELF reloc.  */
00228 
00229 static void
00230 mn10200_info_to_howto (abfd, cache_ptr, dst)
00231      bfd *abfd ATTRIBUTE_UNUSED;
00232      arelent *cache_ptr;
00233      Elf_Internal_Rela *dst;
00234 {
00235   unsigned int r_type;
00236 
00237   r_type = ELF32_R_TYPE (dst->r_info);
00238   BFD_ASSERT (r_type < (unsigned int) R_MN10200_MAX);
00239   cache_ptr->howto = &elf_mn10200_howto_table[r_type];
00240 }
00241 
00242 /* Perform a relocation as part of a final link.  */
00243 
00244 static bfd_reloc_status_type
00245 mn10200_elf_final_link_relocate (howto, input_bfd, output_bfd,
00246                              input_section, contents, offset, value,
00247                              addend, info, sym_sec, is_local)
00248      reloc_howto_type *howto;
00249      bfd *input_bfd;
00250      bfd *output_bfd ATTRIBUTE_UNUSED;
00251      asection *input_section;
00252      bfd_byte *contents;
00253      bfd_vma offset;
00254      bfd_vma value;
00255      bfd_vma addend;
00256      struct bfd_link_info *info ATTRIBUTE_UNUSED;
00257      asection *sym_sec ATTRIBUTE_UNUSED;
00258      int is_local ATTRIBUTE_UNUSED;
00259 {
00260   unsigned long r_type = howto->type;
00261   bfd_byte *hit_data = contents + offset;
00262 
00263   switch (r_type)
00264     {
00265 
00266     case R_MN10200_NONE:
00267       return bfd_reloc_ok;
00268 
00269     case R_MN10200_32:
00270       value += addend;
00271       bfd_put_32 (input_bfd, value, hit_data);
00272       return bfd_reloc_ok;
00273 
00274     case R_MN10200_16:
00275       value += addend;
00276 
00277       if ((long) value > 0x7fff || (long) value < -0x8000)
00278        return bfd_reloc_overflow;
00279 
00280       bfd_put_16 (input_bfd, value, hit_data);
00281       return bfd_reloc_ok;
00282 
00283     case R_MN10200_8:
00284       value += addend;
00285 
00286       if ((long) value > 0x7f || (long) value < -0x80)
00287        return bfd_reloc_overflow;
00288 
00289       bfd_put_8 (input_bfd, value, hit_data);
00290       return bfd_reloc_ok;
00291 
00292     case R_MN10200_24:
00293       value += addend;
00294 
00295       if ((long) value > 0x7fffff || (long) value < -0x800000)
00296        return bfd_reloc_overflow;
00297 
00298       value &= 0xffffff;
00299       value |= (bfd_get_32 (input_bfd, hit_data) & 0xff000000);
00300       bfd_put_32 (input_bfd, value, hit_data);
00301       return bfd_reloc_ok;
00302 
00303     case R_MN10200_PCREL8:
00304       value -= (input_section->output_section->vma
00305               + input_section->output_offset);
00306       value -= (offset + 1);
00307       value += addend;
00308 
00309       if ((long) value > 0xff || (long) value < -0x100)
00310        return bfd_reloc_overflow;
00311 
00312       bfd_put_8 (input_bfd, value, hit_data);
00313       return bfd_reloc_ok;
00314 
00315     case R_MN10200_PCREL16:
00316       value -= (input_section->output_section->vma
00317               + input_section->output_offset);
00318       value -= (offset + 2);
00319       value += addend;
00320 
00321       if ((long) value > 0xffff || (long) value < -0x10000)
00322        return bfd_reloc_overflow;
00323 
00324       bfd_put_16 (input_bfd, value, hit_data);
00325       return bfd_reloc_ok;
00326 
00327     case R_MN10200_PCREL24:
00328       value -= (input_section->output_section->vma
00329               + input_section->output_offset);
00330       value -= (offset + 3);
00331       value += addend;
00332 
00333       if ((long) value > 0xffffff || (long) value < -0x1000000)
00334        return bfd_reloc_overflow;
00335 
00336       value &= 0xffffff;
00337       value |= (bfd_get_32 (input_bfd, hit_data) & 0xff000000);
00338       bfd_put_32 (input_bfd, value, hit_data);
00339       return bfd_reloc_ok;
00340 
00341     default:
00342       return bfd_reloc_notsupported;
00343     }
00344 }
00345 
00346 /* Relocate an MN10200 ELF section.  */
00347 static bfd_boolean
00348 mn10200_elf_relocate_section (output_bfd, info, input_bfd, input_section,
00349                            contents, relocs, local_syms, local_sections)
00350      bfd *output_bfd;
00351      struct bfd_link_info *info;
00352      bfd *input_bfd;
00353      asection *input_section;
00354      bfd_byte *contents;
00355      Elf_Internal_Rela *relocs;
00356      Elf_Internal_Sym *local_syms;
00357      asection **local_sections;
00358 {
00359   Elf_Internal_Shdr *symtab_hdr;
00360   struct elf_link_hash_entry **sym_hashes;
00361   Elf_Internal_Rela *rel, *relend;
00362 
00363   symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
00364   sym_hashes = elf_sym_hashes (input_bfd);
00365 
00366   rel = relocs;
00367   relend = relocs + input_section->reloc_count;
00368   for (; rel < relend; rel++)
00369     {
00370       int r_type;
00371       reloc_howto_type *howto;
00372       unsigned long r_symndx;
00373       Elf_Internal_Sym *sym;
00374       asection *sec;
00375       struct elf_link_hash_entry *h;
00376       bfd_vma relocation;
00377       bfd_reloc_status_type r;
00378 
00379       r_symndx = ELF32_R_SYM (rel->r_info);
00380       r_type = ELF32_R_TYPE (rel->r_info);
00381       howto = elf_mn10200_howto_table + r_type;
00382 
00383       h = NULL;
00384       sym = NULL;
00385       sec = NULL;
00386       if (r_symndx < symtab_hdr->sh_info)
00387        {
00388          sym = local_syms + r_symndx;
00389          sec = local_sections[r_symndx];
00390          relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel);
00391        }
00392       else
00393        {
00394          bfd_boolean unresolved_reloc, warned;
00395 
00396          RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
00397                                r_symndx, symtab_hdr, sym_hashes,
00398                                h, sec, relocation,
00399                                unresolved_reloc, warned);
00400        }
00401 
00402       if (sec != NULL && elf_discarded_section (sec))
00403        {
00404          /* For relocs against symbols from removed linkonce sections,
00405             or sections discarded by a linker script, we just want the
00406             section contents zeroed.  Avoid any special processing.  */
00407          _bfd_clear_contents (howto, input_bfd, contents + rel->r_offset);
00408          rel->r_info = 0;
00409          rel->r_addend = 0;
00410          continue;
00411        }
00412 
00413       if (info->relocatable)
00414        continue;
00415 
00416       r = mn10200_elf_final_link_relocate (howto, input_bfd, output_bfd,
00417                                       input_section,
00418                                       contents, rel->r_offset,
00419                                       relocation, rel->r_addend,
00420                                       info, sec, h == NULL);
00421 
00422       if (r != bfd_reloc_ok)
00423        {
00424          const char *name;
00425          const char *msg = (const char *) 0;
00426 
00427          if (h != NULL)
00428            name = h->root.root.string;
00429          else
00430            {
00431              name = (bfd_elf_string_from_elf_section
00432                     (input_bfd, symtab_hdr->sh_link, sym->st_name));
00433              if (name == NULL || *name == '\0')
00434               name = bfd_section_name (input_bfd, sec);
00435            }
00436 
00437          switch (r)
00438            {
00439            case bfd_reloc_overflow:
00440              if (! ((*info->callbacks->reloc_overflow)
00441                    (info, (h ? &h->root : NULL), name, howto->name,
00442                     (bfd_vma) 0, input_bfd, input_section,
00443                     rel->r_offset)))
00444               return FALSE;
00445              break;
00446 
00447            case bfd_reloc_undefined:
00448              if (! ((*info->callbacks->undefined_symbol)
00449                    (info, name, input_bfd, input_section,
00450                     rel->r_offset, TRUE)))
00451               return FALSE;
00452              break;
00453 
00454            case bfd_reloc_outofrange:
00455              msg = _("internal error: out of range error");
00456              goto common_error;
00457 
00458            case bfd_reloc_notsupported:
00459              msg = _("internal error: unsupported relocation error");
00460              goto common_error;
00461 
00462            case bfd_reloc_dangerous:
00463              msg = _("internal error: dangerous error");
00464              goto common_error;
00465 
00466            default:
00467              msg = _("internal error: unknown error");
00468              /* fall through */
00469 
00470            common_error:
00471              if (!((*info->callbacks->warning)
00472                   (info, msg, name, input_bfd, input_section,
00473                    rel->r_offset)))
00474               return FALSE;
00475              break;
00476            }
00477        }
00478     }
00479 
00480   return TRUE;
00481 }
00482 
00483 /* This function handles relaxing for the mn10200.
00484 
00485    There are quite a few relaxing opportunities available on the mn10200:
00486 
00487        * jsr:24 -> jsr:16                                  2 bytes
00488 
00489        * jmp:24 -> jmp:16                                  2 bytes
00490        * jmp:16 -> bra:8                                   1 byte
00491 
00492               * If the previous instruction is a conditional branch
00493               around the jump/bra, we may be able to reverse its condition
00494               and change its target to the jump's target.  The jump/bra
00495               can then be deleted.                         2 bytes
00496 
00497        * mov abs24 -> mov abs16    2 byte savings
00498 
00499        * Most instructions which accept imm24 can relax to imm16  2 bytes
00500        - Most instructions which accept imm16 can relax to imm8   1 byte
00501 
00502        * Most instructions which accept d24 can relax to d16      2 bytes
00503        - Most instructions which accept d16 can relax to d8       1 byte
00504 
00505        abs24, imm24, d24 all look the same at the reloc level.  It
00506        might make the code simpler if we had different relocs for
00507        the various relaxable operand types.
00508 
00509        We don't handle imm16->imm8 or d16->d8 as they're very rare
00510        and somewhat more difficult to support.  */
00511 
00512 static bfd_boolean
00513 mn10200_elf_relax_section (abfd, sec, link_info, again)
00514      bfd *abfd;
00515      asection *sec;
00516      struct bfd_link_info *link_info;
00517      bfd_boolean *again;
00518 {
00519   Elf_Internal_Shdr *symtab_hdr;
00520   Elf_Internal_Rela *internal_relocs;
00521   Elf_Internal_Rela *irel, *irelend;
00522   bfd_byte *contents = NULL;
00523   Elf_Internal_Sym *isymbuf = NULL;
00524 
00525   /* Assume nothing changes.  */
00526   *again = FALSE;
00527 
00528   /* We don't have to do anything for a relocatable link, if
00529      this section does not have relocs, or if this is not a
00530      code section.  */
00531   if (link_info->relocatable
00532       || (sec->flags & SEC_RELOC) == 0
00533       || sec->reloc_count == 0
00534       || (sec->flags & SEC_CODE) == 0)
00535     return TRUE;
00536 
00537   symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
00538 
00539   /* Get a copy of the native relocations.  */
00540   internal_relocs = (_bfd_elf_link_read_relocs
00541                    (abfd, sec, (PTR) NULL, (Elf_Internal_Rela *) NULL,
00542                     link_info->keep_memory));
00543   if (internal_relocs == NULL)
00544     goto error_return;
00545 
00546   /* Walk through them looking for relaxing opportunities.  */
00547   irelend = internal_relocs + sec->reloc_count;
00548   for (irel = internal_relocs; irel < irelend; irel++)
00549     {
00550       bfd_vma symval;
00551 
00552       /* If this isn't something that can be relaxed, then ignore
00553         this reloc.  */
00554       if (ELF32_R_TYPE (irel->r_info) == (int) R_MN10200_NONE
00555          || ELF32_R_TYPE (irel->r_info) == (int) R_MN10200_8
00556          || ELF32_R_TYPE (irel->r_info) == (int) R_MN10200_MAX)
00557        continue;
00558 
00559       /* Get the section contents if we haven't done so already.  */
00560       if (contents == NULL)
00561        {
00562          /* Get cached copy if it exists.  */
00563          if (elf_section_data (sec)->this_hdr.contents != NULL)
00564            contents = elf_section_data (sec)->this_hdr.contents;
00565          else
00566            {
00567              /* Go get them off disk.  */
00568              if (!bfd_malloc_and_get_section (abfd, sec, &contents))
00569               goto error_return;
00570            }
00571        }
00572 
00573       /* Read this BFD's local symbols if we haven't done so already.  */
00574       if (isymbuf == NULL && symtab_hdr->sh_info != 0)
00575        {
00576          isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
00577          if (isymbuf == NULL)
00578            isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr,
00579                                        symtab_hdr->sh_info, 0,
00580                                        NULL, NULL, NULL);
00581          if (isymbuf == NULL)
00582            goto error_return;
00583        }
00584 
00585       /* Get the value of the symbol referred to by the reloc.  */
00586       if (ELF32_R_SYM (irel->r_info) < symtab_hdr->sh_info)
00587        {
00588          /* A local symbol.  */
00589          Elf_Internal_Sym *isym;
00590          asection *sym_sec;
00591 
00592          isym = isymbuf + ELF32_R_SYM (irel->r_info);
00593          if (isym->st_shndx == SHN_UNDEF)
00594            sym_sec = bfd_und_section_ptr;
00595          else if (isym->st_shndx == SHN_ABS)
00596            sym_sec = bfd_abs_section_ptr;
00597          else if (isym->st_shndx == SHN_COMMON)
00598            sym_sec = bfd_com_section_ptr;
00599          else
00600            sym_sec = bfd_section_from_elf_index (abfd, isym->st_shndx);
00601          symval = (isym->st_value
00602                   + sym_sec->output_section->vma
00603                   + sym_sec->output_offset);
00604        }
00605       else
00606        {
00607          unsigned long indx;
00608          struct elf_link_hash_entry *h;
00609 
00610          /* An external symbol.  */
00611          indx = ELF32_R_SYM (irel->r_info) - symtab_hdr->sh_info;
00612          h = elf_sym_hashes (abfd)[indx];
00613          BFD_ASSERT (h != NULL);
00614          if (h->root.type != bfd_link_hash_defined
00615              && h->root.type != bfd_link_hash_defweak)
00616            {
00617              /* This appears to be a reference to an undefined
00618                  symbol.  Just ignore it--it will be caught by the
00619                  regular reloc processing.  */
00620              continue;
00621            }
00622 
00623          symval = (h->root.u.def.value
00624                   + h->root.u.def.section->output_section->vma
00625                   + h->root.u.def.section->output_offset);
00626        }
00627 
00628       /* For simplicity of coding, we are going to modify the section
00629         contents, the section relocs, and the BFD symbol table.  We
00630         must tell the rest of the code not to free up this
00631         information.  It would be possible to instead create a table
00632         of changes which have to be made, as is done in coff-mips.c;
00633         that would be more work, but would require less memory when
00634         the linker is run.  */
00635 
00636       /* Try to turn a 24bit pc-relative branch/call into a 16bit pc-relative
00637         branch/call.  */
00638       if (ELF32_R_TYPE (irel->r_info) == (int) R_MN10200_PCREL24)
00639        {
00640          bfd_vma value = symval;
00641 
00642          /* Deal with pc-relative gunk.  */
00643          value -= (sec->output_section->vma + sec->output_offset);
00644          value -= (irel->r_offset + 3);
00645          value += irel->r_addend;
00646 
00647          /* See if the value will fit in 16 bits, note the high value is
00648             0x7fff + 2 as the target will be two bytes closer if we are
00649             able to relax.  */
00650          if ((long) value < 0x8001 && (long) value > -0x8000)
00651            {
00652              unsigned char code;
00653 
00654              /* Get the opcode.  */
00655              code = bfd_get_8 (abfd, contents + irel->r_offset - 1);
00656 
00657              if (code != 0xe0 && code != 0xe1)
00658               continue;
00659 
00660              /* Note that we've changed the relocs, section contents, etc.  */
00661              elf_section_data (sec)->relocs = internal_relocs;
00662              elf_section_data (sec)->this_hdr.contents = contents;
00663              symtab_hdr->contents = (unsigned char *) isymbuf;
00664 
00665              /* Fix the opcode.  */
00666              if (code == 0xe0)
00667               bfd_put_8 (abfd, 0xfc, contents + irel->r_offset - 2);
00668              else if (code == 0xe1)
00669               bfd_put_8 (abfd, 0xfd, contents + irel->r_offset - 2);
00670 
00671              /* Fix the relocation's type.  */
00672              irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
00673                                       R_MN10200_PCREL16);
00674 
00675              /* The opcode got shorter too, so we have to fix the offset.  */
00676              irel->r_offset -= 1;
00677 
00678              /* Delete two bytes of data.  */
00679              if (!mn10200_elf_relax_delete_bytes (abfd, sec,
00680                                              irel->r_offset + 1, 2))
00681               goto error_return;
00682 
00683              /* That will change things, so, we should relax again.
00684                Note that this is not required, and it may be slow.  */
00685              *again = TRUE;
00686            }
00687        }
00688 
00689       /* Try to turn a 16bit pc-relative branch into a 8bit pc-relative
00690         branch.  */
00691       if (ELF32_R_TYPE (irel->r_info) == (int) R_MN10200_PCREL16)
00692        {
00693          bfd_vma value = symval;
00694 
00695          /* Deal with pc-relative gunk.  */
00696          value -= (sec->output_section->vma + sec->output_offset);
00697          value -= (irel->r_offset + 2);
00698          value += irel->r_addend;
00699 
00700          /* See if the value will fit in 8 bits, note the high value is
00701             0x7f + 1 as the target will be one bytes closer if we are
00702             able to relax.  */
00703          if ((long) value < 0x80 && (long) value > -0x80)
00704            {
00705              unsigned char code;
00706 
00707              /* Get the opcode.  */
00708              code = bfd_get_8 (abfd, contents + irel->r_offset - 1);
00709 
00710              if (code != 0xfc)
00711               continue;
00712 
00713              /* Note that we've changed the relocs, section contents, etc.  */
00714              elf_section_data (sec)->relocs = internal_relocs;
00715              elf_section_data (sec)->this_hdr.contents = contents;
00716              symtab_hdr->contents = (unsigned char *) isymbuf;
00717 
00718              /* Fix the opcode.  */
00719              bfd_put_8 (abfd, 0xea, contents + irel->r_offset - 1);
00720 
00721              /* Fix the relocation's type.  */
00722              irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
00723                                       R_MN10200_PCREL8);
00724 
00725              /* Delete one byte of data.  */
00726              if (!mn10200_elf_relax_delete_bytes (abfd, sec,
00727                                              irel->r_offset + 1, 1))
00728               goto error_return;
00729 
00730              /* That will change things, so, we should relax again.
00731                Note that this is not required, and it may be slow.  */
00732              *again = TRUE;
00733            }
00734        }
00735 
00736       /* Try to eliminate an unconditional 8 bit pc-relative branch
00737         which immediately follows a conditional 8 bit pc-relative
00738         branch around the unconditional branch.
00739 
00740            original:        new:
00741            bCC lab1         bCC' lab2
00742            bra lab2
00743           lab1:             lab1:
00744 
00745         This happens when the bCC can't reach lab2 at assembly time,
00746         but due to other relaxations it can reach at link time.  */
00747       if (ELF32_R_TYPE (irel->r_info) == (int) R_MN10200_PCREL8)
00748        {
00749          Elf_Internal_Rela *nrel;
00750          bfd_vma value = symval;
00751          unsigned char code;
00752 
00753          /* Deal with pc-relative gunk.  */
00754          value -= (sec->output_section->vma + sec->output_offset);
00755          value -= (irel->r_offset + 1);
00756          value += irel->r_addend;
00757 
00758          /* Do nothing if this reloc is the last byte in the section.  */
00759          if (irel->r_offset == sec->size)
00760            continue;
00761 
00762          /* See if the next instruction is an unconditional pc-relative
00763             branch, more often than not this test will fail, so we
00764             test it first to speed things up.  */
00765          code = bfd_get_8 (abfd, contents + irel->r_offset + 1);
00766          if (code != 0xea)
00767            continue;
00768 
00769          /* Also make sure the next relocation applies to the next
00770             instruction and that it's a pc-relative 8 bit branch.  */
00771          nrel = irel + 1;
00772          if (nrel == irelend
00773              || irel->r_offset + 2 != nrel->r_offset
00774              || ELF32_R_TYPE (nrel->r_info) != (int) R_MN10200_PCREL8)
00775            continue;
00776 
00777          /* Make sure our destination immediately follows the
00778             unconditional branch.  */
00779          if (symval != (sec->output_section->vma + sec->output_offset
00780                       + irel->r_offset + 3))
00781            continue;
00782 
00783          /* Now make sure we are a conditional branch.  This may not
00784             be necessary, but why take the chance.
00785 
00786             Note these checks assume that R_MN10200_PCREL8 relocs
00787             only occur on bCC and bCCx insns.  If they occured
00788             elsewhere, we'd need to know the start of this insn
00789             for this check to be accurate.  */
00790          code = bfd_get_8 (abfd, contents + irel->r_offset - 1);
00791          if (code != 0xe0 && code != 0xe1 && code != 0xe2
00792              && code != 0xe3 && code != 0xe4 && code != 0xe5
00793              && code != 0xe6 && code != 0xe7 && code != 0xe8
00794              && code != 0xe9 && code != 0xec && code != 0xed
00795              && code != 0xee && code != 0xef && code != 0xfc
00796              && code != 0xfd && code != 0xfe && code != 0xff)
00797            continue;
00798 
00799          /* We also have to be sure there is no symbol/label
00800             at the unconditional branch.  */
00801          if (mn10200_elf_symbol_address_p (abfd, sec, isymbuf,
00802                                        irel->r_offset + 1))
00803            continue;
00804 
00805          /* Note that we've changed the relocs, section contents, etc.  */
00806          elf_section_data (sec)->relocs = internal_relocs;
00807          elf_section_data (sec)->this_hdr.contents = contents;
00808          symtab_hdr->contents = (unsigned char *) isymbuf;
00809 
00810          /* Reverse the condition of the first branch.  */
00811          switch (code)
00812            {
00813            case 0xfc:
00814              code = 0xfd;
00815              break;
00816            case 0xfd:
00817              code = 0xfc;
00818              break;
00819            case 0xfe:
00820              code = 0xff;
00821              break;
00822            case 0xff:
00823              code = 0xfe;
00824              break;
00825            case 0xe8:
00826              code = 0xe9;
00827              break;
00828            case 0xe9:
00829              code = 0xe8;
00830              break;
00831            case 0xe0:
00832              code = 0xe2;
00833              break;
00834            case 0xe2:
00835              code = 0xe0;
00836              break;
00837            case 0xe3:
00838              code = 0xe1;
00839              break;
00840            case 0xe1:
00841              code = 0xe3;
00842              break;
00843            case 0xe4:
00844              code = 0xe6;
00845              break;
00846            case 0xe6:
00847              code = 0xe4;
00848              break;
00849            case 0xe7:
00850              code = 0xe5;
00851              break;
00852            case 0xe5:
00853              code = 0xe7;
00854              break;
00855            case 0xec:
00856              code = 0xed;
00857              break;
00858            case 0xed:
00859              code = 0xec;
00860              break;
00861            case 0xee:
00862              code = 0xef;
00863              break;
00864            case 0xef:
00865              code = 0xee;
00866              break;
00867            }
00868          bfd_put_8 (abfd, code, contents + irel->r_offset - 1);
00869 
00870          /* Set the reloc type and symbol for the first branch
00871             from the second branch.  */
00872          irel->r_info = nrel->r_info;
00873 
00874          /* Make the reloc for the second branch a null reloc.  */
00875          nrel->r_info = ELF32_R_INFO (ELF32_R_SYM (nrel->r_info),
00876                                    R_MN10200_NONE);
00877 
00878          /* Delete two bytes of data.  */
00879          if (!mn10200_elf_relax_delete_bytes (abfd, sec,
00880                                           irel->r_offset + 1, 2))
00881            goto error_return;
00882 
00883          /* That will change things, so, we should relax again.
00884             Note that this is not required, and it may be slow.  */
00885          *again = TRUE;
00886        }
00887 
00888       /* Try to turn a 24bit immediate, displacement or absolute address
00889         into a 16bit immediate, displacement or absolute address.  */
00890       if (ELF32_R_TYPE (irel->r_info) == (int) R_MN10200_24)
00891        {
00892          bfd_vma value = symval;
00893 
00894          /* See if the value will fit in 16 bits.
00895             We allow any 16bit match here.  We prune those we can't
00896             handle below.  */
00897          if ((long) value < 0x7fff && (long) value > -0x8000)
00898            {
00899              unsigned char code;
00900 
00901              /* All insns which have 24bit operands are 5 bytes long,
00902                the first byte will always be 0xf4, but we double check
00903                it just in case.  */
00904 
00905              /* Get the first opcode.  */
00906              code = bfd_get_8 (abfd, contents + irel->r_offset - 2);
00907 
00908              if (code != 0xf4)
00909               continue;
00910 
00911              /* Get the second opcode.  */
00912              code = bfd_get_8 (abfd, contents + irel->r_offset - 1);
00913 
00914              switch (code & 0xfc)
00915               {
00916               /* mov imm24,dn -> mov imm16,dn */
00917               case 0x70:
00918                 /* Not safe if the high bit is on as relaxing may
00919                    move the value out of high mem and thus not fit
00920                    in a signed 16bit value.  */
00921                 if (value & 0x8000)
00922                   continue;
00923 
00924                 /* Note that we've changed the relocation contents, etc.  */
00925                 elf_section_data (sec)->relocs = internal_relocs;
00926                 elf_section_data (sec)->this_hdr.contents = contents;
00927                 symtab_hdr->contents = (unsigned char *) isymbuf;
00928 
00929                 /* Fix the opcode.  */
00930                 bfd_put_8 (abfd, 0xf8 + (code & 0x03),
00931                           contents + irel->r_offset - 2);
00932 
00933                 /* Fix the relocation's type.  */
00934                 irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
00935                                           R_MN10200_16);
00936 
00937                 /* The opcode got shorter too, so we have to fix the
00938                    offset.  */
00939                 irel->r_offset -= 1;
00940 
00941                 /* Delete two bytes of data.  */
00942                 if (!mn10200_elf_relax_delete_bytes (abfd, sec,
00943                                                  irel->r_offset + 1, 2))
00944                   goto error_return;
00945 
00946                 /* That will change things, so, we should relax again.
00947                    Note that this is not required, and it may be slow.  */
00948                 *again = TRUE;
00949                 break;
00950 
00951               /* mov imm24,an -> mov imm16,an
00952                  cmp imm24,an -> cmp imm16,an
00953                  mov (abs24),dn -> mov (abs16),dn
00954                  mov dn,(abs24) -> mov dn,(abs16)
00955                  movb dn,(abs24) -> movb dn,(abs16)
00956                  movbu (abs24),dn -> movbu (abs16),dn */
00957               case 0x74:
00958               case 0x7c:
00959               case 0xc0:
00960               case 0x40:
00961               case 0x44:
00962               case 0xc8:
00963                 /* Note that we've changed the relocation contents, etc.  */
00964                 elf_section_data (sec)->relocs = internal_relocs;
00965                 elf_section_data (sec)->this_hdr.contents = contents;
00966                 symtab_hdr->contents = (unsigned char *) isymbuf;
00967 
00968                 if ((code & 0xfc) == 0x74)
00969                   code = 0xdc + (code & 0x03);
00970                 else if ((code & 0xfc) == 0x7c)
00971                   code = 0xec + (code & 0x03);
00972                 else if ((code & 0xfc) == 0xc0)
00973                   code = 0xc8 + (code & 0x03);
00974                 else if ((code & 0xfc) == 0x40)
00975                   code = 0xc0 + (code & 0x03);
00976                 else if ((code & 0xfc) == 0x44)
00977                   code = 0xc4 + (code & 0x03);
00978                 else if ((code & 0xfc) == 0xc8)
00979                   code = 0xcc + (code & 0x03);
00980 
00981                 /* Fix the opcode.  */
00982                 bfd_put_8 (abfd, code, contents + irel->r_offset - 2);
00983 
00984                 /* Fix the relocation's type.  */
00985                 irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
00986                                           R_MN10200_16);
00987 
00988                 /* The opcode got shorter too, so we have to fix the
00989                    offset.  */
00990                 irel->r_offset -= 1;
00991 
00992                 /* Delete two bytes of data.  */
00993                 if (!mn10200_elf_relax_delete_bytes (abfd, sec,
00994                                                  irel->r_offset + 1, 2))
00995                   goto error_return;
00996 
00997                 /* That will change things, so, we should relax again.
00998                    Note that this is not required, and it may be slow.  */
00999                 *again = TRUE;
01000                 break;
01001 
01002               /* cmp imm24,dn -> cmp imm16,dn
01003                  mov (abs24),an -> mov (abs16),an
01004                  mov an,(abs24) -> mov an,(abs16)
01005                  add imm24,dn -> add imm16,dn
01006                  add imm24,an -> add imm16,an
01007                  sub imm24,dn -> sub imm16,dn
01008                  sub imm24,an -> sub imm16,an
01009                  And all d24->d16 in memory ops.  */
01010               case 0x78:
01011               case 0xd0:
01012               case 0x50:
01013               case 0x60:
01014               case 0x64:
01015               case 0x68:
01016               case 0x6c:
01017               case 0x80:
01018               case 0xf0:
01019               case 0x00:
01020               case 0x10:
01021               case 0xb0:
01022               case 0x30:
01023               case 0xa0:
01024               case 0x20:
01025               case 0x90:
01026                 /* Not safe if the high bit is on as relaxing may
01027                    move the value out of high mem and thus not fit
01028                    in a signed 16bit value.  */
01029                 if (((code & 0xfc) == 0x78
01030                      || (code & 0xfc) == 0x60
01031                      || (code & 0xfc) == 0x64
01032                      || (code & 0xfc) == 0x68
01033                      || (code & 0xfc) == 0x6c
01034                      || (code & 0xfc) == 0x80
01035                      || (code & 0xfc) == 0xf0
01036                      || (code & 0xfc) == 0x00
01037                      || (code & 0xfc) == 0x10
01038                      || (code & 0xfc) == 0xb0
01039                      || (code & 0xfc) == 0x30
01040                      || (code & 0xfc) == 0xa0
01041                      || (code & 0xfc) == 0x20
01042                      || (code & 0xfc) == 0x90)
01043                     && (value & 0x8000) != 0)
01044                   continue;
01045 
01046                 /* Note that we've changed the relocation contents, etc.  */
01047                 elf_section_data (sec)->relocs = internal_relocs;
01048                 elf_section_data (sec)->this_hdr.contents = contents;
01049                 symtab_hdr->contents = (unsigned char *) isymbuf;
01050 
01051                 /* Fix the opcode.  */
01052                 bfd_put_8 (abfd, 0xf7, contents + irel->r_offset - 2);
01053 
01054                 if ((code & 0xfc) == 0x78)
01055                   code = 0x48 + (code & 0x03);
01056                 else if ((code & 0xfc) == 0xd0)
01057                   code = 0x30 + (code & 0x03);
01058                 else if ((code & 0xfc) == 0x50)
01059                   code = 0x20 + (code & 0x03);
01060                 else if ((code & 0xfc) == 0x60)
01061                   code = 0x18 + (code & 0x03);
01062                 else if ((code & 0xfc) == 0x64)
01063                   code = 0x08 + (code & 0x03);
01064                 else if ((code & 0xfc) == 0x68)
01065                   code = 0x1c + (code & 0x03);
01066                 else if ((code & 0xfc) == 0x6c)
01067                   code = 0x0c + (code & 0x03);
01068                 else if ((code & 0xfc) == 0x80)
01069                   code = 0xc0 + (code & 0x07);
01070                 else if ((code & 0xfc) == 0xf0)
01071                   code = 0xb0 + (code & 0x07);
01072                 else if ((code & 0xfc) == 0x00)
01073                   code = 0x80 + (code & 0x07);
01074                 else if ((code & 0xfc) == 0x10)
01075                   code = 0xa0 + (code & 0x07);
01076                 else if ((code & 0xfc) == 0xb0)
01077                   code = 0x70 + (code & 0x07);
01078                 else if ((code & 0xfc) == 0x30)
01079                   code = 0x60 + (code & 0x07);
01080                 else if ((code & 0xfc) == 0xa0)
01081                   code = 0xd0 + (code & 0x07);
01082                 else if ((code & 0xfc) == 0x20)
01083                   code = 0x90 + (code & 0x07);
01084                 else if ((code & 0xfc) == 0x90)
01085                   code = 0x50 + (code & 0x07);
01086 
01087                 bfd_put_8 (abfd, code, contents + irel->r_offset - 1);
01088 
01089                 /* Fix the relocation's type.  */
01090                 irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
01091                                           R_MN10200_16);
01092 
01093                 /* Delete one bytes of data.  */
01094                 if (!mn10200_elf_relax_delete_bytes (abfd, sec,
01095                                                  irel->r_offset + 2, 1))
01096                   goto error_return;
01097 
01098                 /* That will change things, so, we should relax again.
01099                    Note that this is not required, and it may be slow.  */
01100                 *again = TRUE;
01101                 break;
01102 
01103               /* movb (abs24),dn ->movbu (abs16),dn extxb bn */
01104               case 0xc4:
01105                 /* Note that we've changed the reldection contents, etc.  */
01106                 elf_section_data (sec)->relocs = internal_relocs;
01107                 elf_section_data (sec)->this_hdr.contents = contents;
01108                 symtab_hdr->contents = (unsigned char *) isymbuf;
01109 
01110                 bfd_put_8 (abfd, 0xcc + (code & 0x03),
01111                           contents + irel->r_offset - 2);
01112 
01113                 bfd_put_8 (abfd, 0xb8 + (code & 0x03),
01114                           contents + irel->r_offset - 1);
01115 
01116                 /* Fix the relocation's type.  */
01117                 irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
01118                                           R_MN10200_16);
01119 
01120                 /* The reloc will be applied one byte in front of its
01121                    current location.  */
01122                 irel->r_offset -= 1;
01123 
01124                 /* Delete one bytes of data.  */
01125                 if (!mn10200_elf_relax_delete_bytes (abfd, sec,
01126                                                  irel->r_offset + 2, 1))
01127                   goto error_return;
01128 
01129                 /* That will change things, so, we should relax again.
01130                    Note that this is not required, and it may be slow.  */
01131                 *again = TRUE;
01132                 break;
01133               }
01134            }
01135        }
01136     }
01137 
01138   if (isymbuf != NULL
01139       && symtab_hdr->contents != (unsigned char *) isymbuf)
01140     {
01141       if (! link_info->keep_memory)
01142        free (isymbuf);
01143       else
01144        {
01145          /* Cache the symbols for elf_link_input_bfd.  */
01146          symtab_hdr->contents = (unsigned char *) isymbuf;
01147        }
01148     }
01149 
01150   if (contents != NULL
01151       && elf_section_data (sec)->this_hdr.contents != contents)
01152     {
01153       if (! link_info->keep_memory)
01154        free (contents);
01155       else
01156        {
01157          /* Cache the section contents for elf_link_input_bfd.  */
01158          elf_section_data (sec)->this_hdr.contents = contents;
01159        }
01160     }
01161 
01162   if (internal_relocs != NULL
01163       && elf_section_data (sec)->relocs != internal_relocs)
01164     free (internal_relocs);
01165 
01166   return TRUE;
01167 
01168  error_return:
01169   if (isymbuf != NULL
01170       && symtab_hdr->contents != (unsigned char *) isymbuf)
01171     free (isymbuf);
01172   if (contents != NULL
01173       && elf_section_data (sec)->this_hdr.contents != contents)
01174     free (contents);
01175   if (internal_relocs != NULL
01176       && elf_section_data (sec)->relocs != internal_relocs)
01177     free (internal_relocs);
01178 
01179   return FALSE;
01180 }
01181 
01182 /* Delete some bytes from a section while relaxing.  */
01183 
01184 static bfd_boolean
01185 mn10200_elf_relax_delete_bytes (abfd, sec, addr, count)
01186      bfd *abfd;
01187      asection *sec;
01188      bfd_vma addr;
01189      int count;
01190 {
01191   Elf_Internal_Shdr *symtab_hdr;
01192   unsigned int sec_shndx;
01193   bfd_byte *contents;
01194   Elf_Internal_Rela *irel, *irelend;
01195   Elf_Internal_Rela *irelalign;
01196   bfd_vma toaddr;
01197   Elf_Internal_Sym *isym;
01198   Elf_Internal_Sym *isymend;
01199   struct elf_link_hash_entry **sym_hashes;
01200   struct elf_link_hash_entry **end_hashes;
01201   unsigned int symcount;
01202 
01203   sec_shndx = _bfd_elf_section_from_bfd_section (abfd, sec);
01204 
01205   contents = elf_section_data (sec)->this_hdr.contents;
01206 
01207   /* The deletion must stop at the next ALIGN reloc for an aligment
01208      power larger than the number of bytes we are deleting.  */
01209 
01210   irelalign = NULL;
01211   toaddr = sec->size;
01212 
01213   irel = elf_section_data (sec)->relocs;
01214   irelend = irel + sec->reloc_count;
01215 
01216   /* Actually delete the bytes.  */
01217   memmove (contents + addr, contents + addr + count,
01218           (size_t) (toaddr - addr - count));
01219   sec->size -= count;
01220 
01221   /* Adjust all the relocs.  */
01222   for (irel = elf_section_data (sec)->relocs; irel < irelend; irel++)
01223     {
01224       /* Get the new reloc address.  */
01225       if ((irel->r_offset > addr
01226           && irel->r_offset < toaddr))
01227        irel->r_offset -= count;
01228     }
01229 
01230   /* Adjust the local symbols defined in this section.  */
01231   symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
01232   isym = (Elf_Internal_Sym *) symtab_hdr->contents;
01233   for (isymend = isym + symtab_hdr->sh_info; isym < isymend; isym++)
01234     {
01235       if (isym->st_shndx == sec_shndx
01236          && isym->st_value > addr
01237          && isym->st_value < toaddr)
01238        isym->st_value -= count;
01239     }
01240 
01241   /* Now adjust the global symbols defined in this section.  */
01242   symcount = (symtab_hdr->sh_size / sizeof (Elf32_External_Sym)
01243              - symtab_hdr->sh_info);
01244   sym_hashes = elf_sym_hashes (abfd);
01245   end_hashes = sym_hashes + symcount;
01246   for (; sym_hashes < end_hashes; sym_hashes++)
01247     {
01248       struct elf_link_hash_entry *sym_hash = *sym_hashes;
01249       if ((sym_hash->root.type == bfd_link_hash_defined
01250           || sym_hash->root.type == bfd_link_hash_defweak)
01251          && sym_hash->root.u.def.section == sec
01252          && sym_hash->root.u.def.value > addr
01253          && sym_hash->root.u.def.value < toaddr)
01254        {
01255          sym_hash->root.u.def.value -= count;
01256        }
01257     }
01258 
01259   return TRUE;
01260 }
01261 
01262 /* Return TRUE if a symbol exists at the given address, else return
01263    FALSE.  */
01264 static bfd_boolean
01265 mn10200_elf_symbol_address_p (abfd, sec, isym, addr)
01266      bfd *abfd;
01267      asection *sec;
01268      Elf_Internal_Sym *isym;
01269      bfd_vma addr;
01270 {
01271   Elf_Internal_Shdr *symtab_hdr;
01272   unsigned int sec_shndx;
01273   Elf_Internal_Sym *isymend;
01274   struct elf_link_hash_entry **sym_hashes;
01275   struct elf_link_hash_entry **end_hashes;
01276   unsigned int symcount;
01277 
01278   sec_shndx = _bfd_elf_section_from_bfd_section (abfd, sec);
01279 
01280   /* Examine all the local symbols.  */
01281   symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
01282   for (isymend = isym + symtab_hdr->sh_info; isym < isymend; isym++)
01283     {
01284       if (isym->st_shndx == sec_shndx
01285          && isym->st_value == addr)
01286        return TRUE;
01287     }
01288 
01289   symcount = (symtab_hdr->sh_size / sizeof (Elf32_External_Sym)
01290              - symtab_hdr->sh_info);
01291   sym_hashes = elf_sym_hashes (abfd);
01292   end_hashes = sym_hashes + symcount;
01293   for (; sym_hashes < end_hashes; sym_hashes++)
01294     {
01295       struct elf_link_hash_entry *sym_hash = *sym_hashes;
01296       if ((sym_hash->root.type == bfd_link_hash_defined
01297           || sym_hash->root.type == bfd_link_hash_defweak)
01298          && sym_hash->root.u.def.section == sec
01299          && sym_hash->root.u.def.value == addr)
01300        return TRUE;
01301     }
01302 
01303   return FALSE;
01304 }
01305 
01306 /* This is a version of bfd_generic_get_relocated_section_contents
01307    which uses mn10200_elf_relocate_section.  */
01308 
01309 static bfd_byte *
01310 mn10200_elf_get_relocated_section_contents (output_bfd, link_info, link_order,
01311                                        data, relocatable, symbols)
01312      bfd *output_bfd;
01313      struct bfd_link_info *link_info;
01314      struct bfd_link_order *link_order;
01315      bfd_byte *data;
01316      bfd_boolean relocatable;
01317      asymbol **symbols;
01318 {
01319   Elf_Internal_Shdr *symtab_hdr;
01320   asection *input_section = link_order->u.indirect.section;
01321   bfd *input_bfd = input_section->owner;
01322   asection **sections = NULL;
01323   Elf_Internal_Rela *internal_relocs = NULL;
01324   Elf_Internal_Sym *isymbuf = NULL;
01325 
01326   /* We only need to handle the case of relaxing, or of having a
01327      particular set of section contents, specially.  */
01328   if (relocatable
01329       || elf_section_data (input_section)->this_hdr.contents == NULL)
01330     return bfd_generic_get_relocated_section_contents (output_bfd, link_info,
01331                                                  link_order, data,
01332                                                  relocatable,
01333                                                  symbols);
01334 
01335   symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
01336 
01337   memcpy (data, elf_section_data (input_section)->this_hdr.contents,
01338          (size_t) input_section->size);
01339 
01340   if ((input_section->flags & SEC_RELOC) != 0
01341       && input_section->reloc_count > 0)
01342     {
01343       Elf_Internal_Sym *isym;
01344       Elf_Internal_Sym *isymend;
01345       asection **secpp;
01346       bfd_size_type amt;
01347 
01348       internal_relocs = (_bfd_elf_link_read_relocs
01349                       (input_bfd, input_section, (PTR) NULL,
01350                        (Elf_Internal_Rela *) NULL, FALSE));
01351       if (internal_relocs == NULL)
01352        goto error_return;
01353 
01354       if (symtab_hdr->sh_info != 0)
01355        {
01356          isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
01357          if (isymbuf == NULL)
01358            isymbuf = bfd_elf_get_elf_syms (input_bfd, symtab_hdr,
01359                                        symtab_hdr->sh_info, 0,
01360                                        NULL, NULL, NULL);
01361          if (isymbuf == NULL)
01362            goto error_return;
01363        }
01364 
01365       amt = symtab_hdr->sh_info;
01366       amt *= sizeof (asection *);
01367       sections = (asection **) bfd_malloc (amt);
01368       if (sections == NULL && amt != 0)
01369        goto error_return;
01370 
01371       isymend = isymbuf + symtab_hdr->sh_info;
01372       for (isym = isymbuf, secpp = sections; isym < isymend; ++isym, ++secpp)
01373        {
01374          asection *isec;
01375 
01376          if (isym->st_shndx == SHN_UNDEF)
01377            isec = bfd_und_section_ptr;
01378          else if (isym->st_shndx == SHN_ABS)
01379            isec = bfd_abs_section_ptr;
01380          else if (isym->st_shndx == SHN_COMMON)
01381            isec = bfd_com_section_ptr;
01382          else
01383            isec = bfd_section_from_elf_index (input_bfd, isym->st_shndx);
01384 
01385          *secpp = isec;
01386        }
01387 
01388       if (! mn10200_elf_relocate_section (output_bfd, link_info, input_bfd,
01389                                  input_section, data, internal_relocs,
01390                                  isymbuf, sections))
01391        goto error_return;
01392 
01393       if (sections != NULL)
01394        free (sections);
01395       if (isymbuf != NULL
01396          && symtab_hdr->contents != (unsigned char *) isymbuf)
01397        free (isymbuf);
01398       if (elf_section_data (input_section)->relocs != internal_relocs)
01399        free (internal_relocs);
01400     }
01401 
01402   return data;
01403 
01404  error_return:
01405   if (sections != NULL)
01406     free (sections);
01407   if (isymbuf != NULL
01408       && symtab_hdr->contents != (unsigned char *) isymbuf)
01409     free (isymbuf);
01410   if (internal_relocs != NULL
01411       && elf_section_data (input_section)->relocs != internal_relocs)
01412     free (internal_relocs);
01413   return NULL;
01414 }
01415 
01416 #define TARGET_LITTLE_SYM   bfd_elf32_mn10200_vec
01417 #define TARGET_LITTLE_NAME  "elf32-mn10200"
01418 #define ELF_ARCH            bfd_arch_mn10200
01419 #define ELF_MACHINE_CODE    EM_MN10200
01420 #define ELF_MACHINE_ALT1    EM_CYGNUS_MN10200
01421 #define ELF_MAXPAGESIZE            0x1000
01422 
01423 #define elf_backend_rela_normal 1
01424 #define elf_info_to_howto   mn10200_info_to_howto
01425 #define elf_info_to_howto_rel      0
01426 #define elf_backend_relocate_section mn10200_elf_relocate_section
01427 #define bfd_elf32_bfd_relax_section       mn10200_elf_relax_section
01428 #define bfd_elf32_bfd_get_relocated_section_contents \
01429                             mn10200_elf_get_relocated_section_contents
01430 
01431 #define elf_symbol_leading_char '_'
01432 
01433 #include "elf32-target.h"