Back to index

cell-binutils  2.17cvs20070401
elf32-m32c.c
Go to the documentation of this file.
00001 /* M16C/M32C specific support for 32-bit ELF.
00002    Copyright (C) 2005, 2006, 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
00020 
00021 #include "bfd.h"
00022 #include "sysdep.h"
00023 #include "libbfd.h"
00024 #include "elf-bfd.h"
00025 #include "elf/m32c.h"
00026 #include "libiberty.h"
00027 
00028 /* Forward declarations.  */
00029 static reloc_howto_type * m32c_reloc_type_lookup
00030   (bfd *, bfd_reloc_code_real_type);
00031 static void m32c_info_to_howto_rela 
00032   (bfd *, arelent *, Elf_Internal_Rela *);
00033 static bfd_boolean m32c_elf_relocate_section 
00034   (bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *, Elf_Internal_Rela *, Elf_Internal_Sym *, asection **);
00035 static bfd_boolean m32c_elf_check_relocs
00036   (bfd *, struct bfd_link_info *, asection *, const Elf_Internal_Rela *);
00037 static bfd_boolean m32c_elf_relax_delete_bytes (bfd *, asection *, bfd_vma, int);
00038 #ifdef DEBUG
00039 char * m32c_get_reloc (long reloc);
00040 void dump_symtab (bfd *, void *, void *);
00041 #endif
00042 static bfd_boolean m32c_elf_relax_section
00043 (bfd *abfd, asection *sec, struct bfd_link_info *link_info, bfd_boolean *again);
00044 
00045 
00046 static reloc_howto_type m32c_elf_howto_table [] =
00047 {
00048   /* This reloc does nothing.  */
00049   HOWTO (R_M32C_NONE,              /* type */
00050         0,                  /* rightshift */
00051         0,                  /* size (0 = byte, 1 = short, 2 = long) */
00052         32,                 /* bitsize */
00053         FALSE,                     /* pc_relative */
00054         0,                  /* bitpos */
00055         complain_overflow_bitfield, /* complain_on_overflow */
00056         bfd_elf_generic_reloc,     /* special_function */
00057         "R_M32C_NONE",             /* name */
00058         FALSE,                     /* partial_inplace */
00059         0,                  /* src_mask */
00060         0,                  /* dst_mask */
00061         FALSE),             /* pcrel_offset */
00062 
00063   /* GCC intentionally overflows these next two in order to work
00064      around limitations in the addressing modes, so don't complain
00065      about overflow.  */
00066   HOWTO (R_M32C_16,         /* type */
00067         0,                  /* rightshift */
00068         1,                  /* size (0 = byte, 1 = short, 2 = long) */
00069         16,                 /* bitsize */
00070         FALSE,                     /* pc_relative */
00071         0,                  /* bitpos */
00072         complain_overflow_dont, /* complain_on_overflow */
00073         bfd_elf_generic_reloc,     /* special_function */
00074         "R_M32C_16",        /* name */
00075         FALSE,                     /* partial_inplace */
00076         0,                  /* src_mask */
00077         0xffff,             /* dst_mask */
00078         FALSE),             /* pcrel_offset */
00079 
00080   HOWTO (R_M32C_24,         /* type */
00081         0,                  /* rightshift */
00082         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00083         24,                 /* bitsize */
00084         FALSE,                     /* pc_relative */
00085         0,                  /* bitpos */
00086         complain_overflow_dont, /* complain_on_overflow */
00087         bfd_elf_generic_reloc,     /* special_function */
00088         "R_M32C_24",        /* name */
00089         FALSE,                     /* partial_inplace */
00090         0,                  /* src_mask */
00091         0xffffff,           /* dst_mask */
00092         FALSE),             /* pcrel_offset */
00093 
00094   HOWTO (R_M32C_32,         /* type */
00095         0,                  /* rightshift */
00096         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00097         32,                 /* bitsize */
00098         FALSE,                     /* pc_relative */
00099         0,                  /* bitpos */
00100         complain_overflow_bitfield, /* complain_on_overflow */
00101         bfd_elf_generic_reloc,     /* special_function */
00102         "R_M32C_32",        /* name */
00103         FALSE,                     /* partial_inplace */
00104         0,                  /* src_mask */
00105         0xffffffff,         /* dst_mask */
00106         FALSE),             /* pcrel_offset */
00107 
00108   HOWTO (R_M32C_8_PCREL,    /* type */
00109         0,                  /* rightshift */
00110         0,                  /* size (0 = byte, 1 = short, 2 = long) */
00111         8,                  /* bitsize */
00112         TRUE,               /* pc_relative */
00113         0,                  /* bitpos */
00114         complain_overflow_signed, /* complain_on_overflow */
00115         bfd_elf_generic_reloc,     /* special_function */
00116         "R_M32C_8_PCREL",   /* name */
00117         FALSE,                     /* partial_inplace */
00118         0,                  /* src_mask */
00119         0xff,               /* dst_mask */
00120         TRUE),              /* pcrel_offset */
00121 
00122   HOWTO (R_M32C_16_PCREL,   /* type */
00123         0,                  /* rightshift */
00124         1,                  /* size (0 = byte, 1 = short, 2 = long) */
00125         16,                 /* bitsize */
00126         TRUE,               /* pc_relative */
00127         0,                  /* bitpos */
00128         complain_overflow_signed, /* complain_on_overflow */
00129         bfd_elf_generic_reloc,     /* special_function */
00130         "R_M32C_16_PCREL",  /* name */
00131         FALSE,                     /* partial_inplace */
00132         0,                  /* src_mask */
00133         0xffff,                    /* dst_mask */
00134         TRUE),              /* pcrel_offset */
00135 
00136   HOWTO (R_M32C_8,          /* type */
00137         0,                  /* rightshift */
00138         0,                  /* size (0 = byte, 1 = short, 2 = long) */
00139         8,                  /* bitsize */
00140         FALSE,                     /* pc_relative */
00141         0,                  /* bitpos */
00142         complain_overflow_unsigned, /* complain_on_overflow */
00143         bfd_elf_generic_reloc,     /* special_function */
00144         "R_M32C_8",         /* name */
00145         FALSE,                     /* partial_inplace */
00146         0,                  /* src_mask */
00147         0xff,               /* dst_mask */
00148         FALSE),             /* pcrel_offset */
00149 
00150   HOWTO (R_M32C_LO16,              /* type */
00151         0,                  /* rightshift */
00152         1,                  /* size (0 = byte, 1 = short, 2 = long) */
00153         16,                 /* bitsize */
00154         FALSE,                     /* pc_relative */
00155         0,                  /* bitpos */
00156         complain_overflow_dont, /* complain_on_overflow */
00157         bfd_elf_generic_reloc,     /* special_function */
00158         "R_M32C_LO16",             /* name */
00159         FALSE,                     /* partial_inplace */
00160         0,                  /* src_mask */
00161         0xffff,             /* dst_mask */
00162         FALSE),             /* pcrel_offset */
00163 
00164   HOWTO (R_M32C_HI8,        /* type */
00165         0,                  /* rightshift */
00166         0,                  /* size (0 = byte, 1 = short, 2 = long) */
00167         8,                  /* bitsize */
00168         FALSE,                     /* pc_relative */
00169         0,                  /* bitpos */
00170         complain_overflow_dont, /* complain_on_overflow */
00171         bfd_elf_generic_reloc,     /* special_function */
00172         "R_M32C_HI8",              /* name */
00173         FALSE,                     /* partial_inplace */
00174         0,                  /* src_mask */
00175         0xff,               /* dst_mask */
00176         FALSE),             /* pcrel_offset */
00177 
00178   HOWTO (R_M32C_HI16,              /* type */
00179         0,                  /* rightshift */
00180         1,                  /* size (0 = byte, 1 = short, 2 = long) */
00181         16,                 /* bitsize */
00182         FALSE,                     /* pc_relative */
00183         0,                  /* bitpos */
00184         complain_overflow_dont, /* complain_on_overflow */
00185         bfd_elf_generic_reloc,     /* special_function */
00186         "R_M32C_HI16",             /* name */
00187         FALSE,                     /* partial_inplace */
00188         0,                  /* src_mask */
00189         0xffff,             /* dst_mask */
00190         FALSE),             /* pcrel_offset */
00191 
00192   HOWTO (R_M32C_RL_JUMP,    /* type */
00193         0,                  /* rightshift */
00194         0,                  /* size (0 = byte, 1 = short, 2 = long) */
00195         0,                  /* bitsize */
00196         FALSE,                     /* pc_relative */
00197         0,                  /* bitpos */
00198         complain_overflow_signed, /* complain_on_overflow */
00199         bfd_elf_generic_reloc,     /* special_function */
00200         "R_M32C_RL_JUMP",   /* name */
00201         FALSE,                     /* partial_inplace */
00202         0,                  /* src_mask */
00203         0,                  /* dst_mask */
00204         FALSE),             /* pcrel_offset */
00205 
00206   HOWTO (R_M32C_RL_1ADDR,   /* type */
00207         0,                  /* rightshift */
00208         0,                  /* size (0 = byte, 1 = short, 2 = long) */
00209         0,                  /* bitsize */
00210         FALSE,                     /* pc_relative */
00211         0,                  /* bitpos */
00212         complain_overflow_signed, /* complain_on_overflow */
00213         bfd_elf_generic_reloc,     /* special_function */
00214         "R_M32C_RL_1ADDR",  /* name */
00215         FALSE,                     /* partial_inplace */
00216         0,                  /* src_mask */
00217         0,                  /* dst_mask */
00218         FALSE),             /* pcrel_offset */
00219 
00220   HOWTO (R_M32C_RL_2ADDR,   /* type */
00221         0,                  /* rightshift */
00222         0,                  /* size (0 = byte, 1 = short, 2 = long) */
00223         0,                  /* bitsize */
00224         FALSE,                     /* pc_relative */
00225         0,                  /* bitpos */
00226         complain_overflow_signed, /* complain_on_overflow */
00227         bfd_elf_generic_reloc,     /* special_function */
00228         "R_M32C_RL_2ADDR",  /* name */
00229         FALSE,                     /* partial_inplace */
00230         0,                  /* src_mask */
00231         0,                  /* dst_mask */
00232         FALSE),             /* pcrel_offset */
00233 
00234 };
00235 
00236 /* Map BFD reloc types to M32C ELF reloc types.  */
00237 
00238 struct m32c_reloc_map
00239 {
00240   bfd_reloc_code_real_type bfd_reloc_val;
00241   unsigned int m32c_reloc_val;
00242 };
00243 
00244 static const struct m32c_reloc_map m32c_reloc_map [] =
00245 {
00246   { BFD_RELOC_NONE,         R_M32C_NONE },
00247   { BFD_RELOC_16,           R_M32C_16 },
00248   { BFD_RELOC_24,               R_M32C_24 },
00249   { BFD_RELOC_32,           R_M32C_32 },
00250   { BFD_RELOC_8_PCREL,          R_M32C_8_PCREL },
00251   { BFD_RELOC_16_PCREL,         R_M32C_16_PCREL },
00252   { BFD_RELOC_8,            R_M32C_8 },
00253   { BFD_RELOC_LO16,         R_M32C_LO16 },
00254   { BFD_RELOC_HI16,         R_M32C_HI16 },
00255   { BFD_RELOC_M32C_HI8,            R_M32C_HI8 },
00256   { BFD_RELOC_M32C_RL_JUMP, R_M32C_RL_JUMP },
00257   { BFD_RELOC_M32C_RL_1ADDR,       R_M32C_RL_1ADDR },
00258   { BFD_RELOC_M32C_RL_2ADDR,       R_M32C_RL_2ADDR }
00259 };
00260 
00261 static reloc_howto_type *
00262 m32c_reloc_type_lookup
00263     (bfd *                    abfd ATTRIBUTE_UNUSED,
00264      bfd_reloc_code_real_type code)
00265 {
00266   unsigned int i;
00267 
00268   for (i = ARRAY_SIZE (m32c_reloc_map); --i;)
00269     if (m32c_reloc_map [i].bfd_reloc_val == code)
00270       return & m32c_elf_howto_table [m32c_reloc_map[i].m32c_reloc_val];
00271   
00272   return NULL;
00273 }
00274 
00275 static reloc_howto_type *
00276 m32c_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED, const char *r_name)
00277 {
00278   unsigned int i;
00279 
00280   for (i = 0;
00281        i < sizeof (m32c_elf_howto_table) / sizeof (m32c_elf_howto_table[0]);
00282        i++)
00283     if (m32c_elf_howto_table[i].name != NULL
00284        && strcasecmp (m32c_elf_howto_table[i].name, r_name) == 0)
00285       return &m32c_elf_howto_table[i];
00286 
00287   return NULL;
00288 }
00289 
00290 /* Set the howto pointer for an M32C ELF reloc.  */
00291 
00292 static void
00293 m32c_info_to_howto_rela
00294     (bfd *               abfd ATTRIBUTE_UNUSED,
00295      arelent *           cache_ptr,
00296      Elf_Internal_Rela * dst)
00297 {
00298   unsigned int r_type;
00299 
00300   r_type = ELF32_R_TYPE (dst->r_info);
00301   BFD_ASSERT (r_type < (unsigned int) R_M32C_max);
00302   cache_ptr->howto = & m32c_elf_howto_table [r_type];
00303 }
00304 
00305 
00306 
00307 /* Relocate an M32C ELF section.
00308    There is some attempt to make this function usable for many architectures,
00309    both USE_REL and USE_RELA ['twould be nice if such a critter existed],
00310    if only to serve as a learning tool.
00311 
00312    The RELOCATE_SECTION function is called by the new ELF backend linker
00313    to handle the relocations for a section.
00314 
00315    The relocs are always passed as Rela structures; if the section
00316    actually uses Rel structures, the r_addend field will always be
00317    zero.
00318 
00319    This function is responsible for adjusting the section contents as
00320    necessary, and (if using Rela relocs and generating a relocatable
00321    output file) adjusting the reloc addend as necessary.
00322 
00323    This function does not have to worry about setting the reloc
00324    address or the reloc symbol index.
00325 
00326    LOCAL_SYMS is a pointer to the swapped in local symbols.
00327 
00328    LOCAL_SECTIONS is an array giving the section in the input file
00329    corresponding to the st_shndx field of each local symbol.
00330 
00331    The global hash table entry for the global symbols can be found
00332    via elf_sym_hashes (input_bfd).
00333 
00334    When generating relocatable output, this function must handle
00335    STB_LOCAL/STT_SECTION symbols specially.  The output symbol is
00336    going to be the section symbol corresponding to the output
00337    section, which means that the addend must be adjusted
00338    accordingly.  */
00339 
00340 static bfd_boolean
00341 m32c_elf_relocate_section
00342     (bfd *                   output_bfd ATTRIBUTE_UNUSED,
00343      struct bfd_link_info *  info,
00344      bfd *                   input_bfd,
00345      asection *              input_section,
00346      bfd_byte *              contents,
00347      Elf_Internal_Rela *     relocs,
00348      Elf_Internal_Sym *      local_syms,
00349      asection **             local_sections)
00350 {
00351   Elf_Internal_Shdr *           symtab_hdr;
00352   struct elf_link_hash_entry ** sym_hashes;
00353   Elf_Internal_Rela *           rel;
00354   Elf_Internal_Rela *           relend;
00355   bfd *dynobj;
00356   asection *splt;
00357 
00358   symtab_hdr = & elf_tdata (input_bfd)->symtab_hdr;
00359   sym_hashes = elf_sym_hashes (input_bfd);
00360   relend     = relocs + input_section->reloc_count;
00361 
00362   dynobj = elf_hash_table (info)->dynobj;
00363   splt = NULL;
00364   if (dynobj != NULL)
00365     splt = bfd_get_section_by_name (dynobj, ".plt");
00366 
00367   for (rel = relocs; rel < relend; rel ++)
00368     {
00369       reloc_howto_type *           howto;
00370       unsigned long                r_symndx;
00371       Elf_Internal_Sym *           sym;
00372       asection *                   sec;
00373       struct elf_link_hash_entry * h;
00374       bfd_vma                      relocation;
00375       bfd_reloc_status_type        r;
00376       const char *                 name = NULL;
00377       int                          r_type;
00378       
00379       r_type = ELF32_R_TYPE (rel->r_info);
00380 
00381       /* These are only used for relaxing; we don't actually relocate
00382         anything with them, so skip them.  */
00383       if (r_type == R_M32C_RL_JUMP
00384          || r_type == R_M32C_RL_1ADDR
00385          || r_type == R_M32C_RL_2ADDR)
00386        continue;
00387       
00388       r_symndx = ELF32_R_SYM (rel->r_info);
00389 
00390       howto  = m32c_elf_howto_table + ELF32_R_TYPE (rel->r_info);
00391       h      = NULL;
00392       sym    = NULL;
00393       sec    = NULL;
00394       relocation = 0;
00395 
00396       if (r_symndx < symtab_hdr->sh_info)
00397        {
00398          sym = local_syms + r_symndx;
00399          sec = local_sections [r_symndx];
00400          relocation = (sec->output_section->vma
00401                      + sec->output_offset
00402                      + sym->st_value);
00403          
00404          name = bfd_elf_string_from_elf_section
00405            (input_bfd, symtab_hdr->sh_link, sym->st_name);
00406          name = (sym->st_name == 0) ? bfd_section_name (input_bfd, sec) : name;
00407        }
00408       else
00409        {
00410          h = sym_hashes [r_symndx - symtab_hdr->sh_info];
00411          
00412          while (h->root.type == bfd_link_hash_indirect
00413                || h->root.type == bfd_link_hash_warning)
00414            h = (struct elf_link_hash_entry *) h->root.u.i.link;
00415 
00416          name = h->root.root.string;
00417          
00418          if (h->root.type == bfd_link_hash_defined
00419              || h->root.type == bfd_link_hash_defweak)
00420            {
00421              sec = h->root.u.def.section;
00422              relocation = (h->root.u.def.value
00423                          + sec->output_section->vma
00424                          + sec->output_offset);
00425            }
00426          else if (h->root.type == bfd_link_hash_undefweak)
00427            ;
00428          else if (!info->relocatable)
00429            {
00430              if (! ((*info->callbacks->undefined_symbol)
00431                    (info, h->root.root.string, input_bfd,
00432                     input_section, rel->r_offset, TRUE)))
00433               return FALSE;
00434            }
00435        }
00436 
00437       if (sec != NULL && elf_discarded_section (sec))
00438        {
00439          /* For relocs against symbols from removed linkonce sections,
00440             or sections discarded by a linker script, we just want the
00441             section contents zeroed.  Avoid any special processing.  */
00442          _bfd_clear_contents (howto, input_bfd, contents + rel->r_offset);
00443          rel->r_info = 0;
00444          rel->r_addend = 0;
00445          continue;
00446        }
00447 
00448       if (info->relocatable)
00449        {
00450          /* This is a relocatable link.  We don't have to change
00451              anything, unless the reloc is against a section symbol,
00452              in which case we have to adjust according to where the
00453              section symbol winds up in the output section.  */
00454          if (sym != NULL && ELF_ST_TYPE (sym->st_info) == STT_SECTION)
00455            rel->r_addend += sec->output_offset;
00456          continue;
00457        }
00458 
00459       switch (ELF32_R_TYPE (rel->r_info))
00460        {
00461        case R_M32C_16:
00462          {
00463            bfd_vma *plt_offset;
00464 
00465            if (h != NULL)
00466              plt_offset = &h->plt.offset;
00467            else
00468              plt_offset = elf_local_got_offsets (input_bfd) + r_symndx;
00469 
00470            /*     printf("%s: rel %x plt %d\n", h ? h->root.root.string : "(none)",
00471                   relocation, *plt_offset);*/
00472            if (relocation <= 0xffff)
00473              {
00474                /* If the symbol is in range for a 16-bit address, we should
00475                  have deallocated the plt entry in relax_section.  */
00476                BFD_ASSERT (*plt_offset == (bfd_vma) -1);
00477              }
00478            else
00479              {
00480               /* If the symbol is out of range for a 16-bit address,
00481                  we must have allocated a plt entry.  */
00482               BFD_ASSERT (*plt_offset != (bfd_vma) -1);
00483 
00484               /* If this is the first time we've processed this symbol,
00485                  fill in the plt entry with the correct symbol address.  */
00486               if ((*plt_offset & 1) == 0)
00487                 {
00488                   unsigned int x;
00489 
00490                   x = 0x000000fc;  /* jmpf */
00491                   x |= (relocation << 8) & 0xffffff00;
00492                   bfd_put_32 (input_bfd, x, splt->contents + *plt_offset);
00493                   *plt_offset |= 1;
00494                 }
00495 
00496               relocation = (splt->output_section->vma
00497                            + splt->output_offset
00498                            + (*plt_offset & -2));
00499               if (name)
00500               {
00501                 char *newname = bfd_malloc (strlen(name)+5);
00502                 strcpy (newname, name);
00503                 strcat(newname, ".plt");
00504                 _bfd_generic_link_add_one_symbol (info,
00505                                               input_bfd,
00506                                               newname,
00507                                               BSF_FUNCTION | BSF_WEAK,
00508                                               splt,
00509                                               (*plt_offset & -2),
00510                                               0,
00511                                               1,
00512                                               0,
00513                                               0);
00514               }
00515              }
00516          }
00517          break;
00518 
00519        case R_M32C_HI8:
00520        case R_M32C_HI16:
00521          relocation >>= 16;
00522          break;
00523        }
00524 
00525 #if 0
00526       printf ("relocate %s at %06lx relocation %06lx addend %ld  ",
00527              m32c_elf_howto_table[ELF32_R_TYPE(rel->r_info)].name,
00528              rel->r_offset + input_section->output_section->vma + input_section->output_offset,
00529              relocation, rel->r_addend);
00530       {
00531        int i;
00532        for (i=0; i<4; i++)
00533          printf (" %02x", contents[rel->r_offset+i]);
00534        printf ("\n");
00535       }
00536 #endif
00537       r = _bfd_final_link_relocate (howto, input_bfd, input_section,
00538                                     contents, rel->r_offset, relocation,
00539                                     rel->r_addend);
00540 
00541       if (r != bfd_reloc_ok)
00542        {
00543          const char * msg = (const char *) NULL;
00544 
00545          switch (r)
00546            {
00547            case bfd_reloc_overflow:
00548              r = info->callbacks->reloc_overflow
00549               (info, (h ? &h->root : NULL), name, howto->name, (bfd_vma) 0,
00550                input_bfd, input_section, rel->r_offset);
00551              break;
00552              
00553            case bfd_reloc_undefined:
00554              r = info->callbacks->undefined_symbol
00555               (info, name, input_bfd, input_section, rel->r_offset,
00556                TRUE);
00557              break;
00558              
00559            case bfd_reloc_outofrange:
00560              msg = _("internal error: out of range error");
00561              break;
00562 
00563            case bfd_reloc_notsupported:
00564              msg = _("internal error: unsupported relocation error");
00565              break;
00566 
00567            case bfd_reloc_dangerous:
00568              msg = _("internal error: dangerous relocation");
00569              break;
00570 
00571            default:
00572              msg = _("internal error: unknown error");
00573              break;
00574            }
00575 
00576          if (msg)
00577            r = info->callbacks->warning
00578              (info, msg, name, input_bfd, input_section, rel->r_offset);
00579 
00580          if (! r)
00581            return FALSE;
00582        }
00583     }
00584 
00585   return TRUE;
00586 }
00587 
00588 /* We support 16-bit pointers to code above 64k by generating a thunk
00589    below 64k containing a JMP instruction to the final address.  */
00590  
00591 static bfd_boolean
00592 m32c_elf_check_relocs
00593     (bfd *                     abfd,
00594      struct bfd_link_info *    info,
00595      asection *                sec,
00596      const Elf_Internal_Rela * relocs)
00597 {
00598   Elf_Internal_Shdr *           symtab_hdr;
00599   struct elf_link_hash_entry ** sym_hashes;
00600   struct elf_link_hash_entry ** sym_hashes_end;
00601   const Elf_Internal_Rela *     rel;
00602   const Elf_Internal_Rela *     rel_end;
00603   bfd_vma *local_plt_offsets;
00604   asection *splt;
00605   bfd *dynobj;
00606  
00607   if (info->relocatable)
00608     return TRUE;
00609  
00610   symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
00611   sym_hashes = elf_sym_hashes (abfd);
00612   local_plt_offsets = elf_local_got_offsets (abfd);
00613   splt = NULL;
00614   dynobj = elf_hash_table(info)->dynobj;
00615 
00616   sym_hashes_end = sym_hashes + symtab_hdr->sh_size/sizeof (Elf32_External_Sym);
00617   if (!elf_bad_symtab (abfd))
00618     sym_hashes_end -= symtab_hdr->sh_info;
00619  
00620   rel_end = relocs + sec->reloc_count;
00621   for (rel = relocs; rel < rel_end; rel++)
00622     {
00623       struct elf_link_hash_entry *h;
00624       unsigned long r_symndx;
00625       bfd_vma *offset;
00626  
00627       r_symndx = ELF32_R_SYM (rel->r_info);
00628       if (r_symndx < symtab_hdr->sh_info)
00629         h = NULL;
00630       else
00631        {
00632          h = sym_hashes[r_symndx - symtab_hdr->sh_info];
00633          while (h->root.type == bfd_link_hash_indirect
00634                || h->root.type == bfd_link_hash_warning)
00635            h = (struct elf_link_hash_entry *) h->root.u.i.link;
00636        }
00637  
00638       switch (ELF32_R_TYPE (rel->r_info))
00639         {
00640          /* This relocation describes a 16-bit pointer to a function.
00641             We may need to allocate a thunk in low memory; reserve memory
00642             for it now.  */
00643        case R_M32C_16:
00644          if (dynobj == NULL)
00645            elf_hash_table (info)->dynobj = dynobj = abfd;
00646          if (splt == NULL)
00647            {
00648              splt = bfd_get_section_by_name (dynobj, ".plt");
00649              if (splt == NULL)
00650               {
00651                 flagword flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS
00652                                 | SEC_IN_MEMORY | SEC_LINKER_CREATED
00653                                 | SEC_READONLY | SEC_CODE);
00654                 splt = bfd_make_section_with_flags (dynobj, ".plt", flags);
00655                 if (splt == NULL
00656                     || ! bfd_set_section_alignment (dynobj, splt, 1))
00657                   return FALSE;
00658               }
00659            }
00660 
00661          if (h != NULL)
00662            offset = &h->plt.offset;
00663          else
00664            {
00665              if (local_plt_offsets == NULL)
00666               {
00667                 size_t size;
00668                 unsigned int i;
00669 
00670                 size = symtab_hdr->sh_info * sizeof (bfd_vma);
00671                 local_plt_offsets = (bfd_vma *) bfd_alloc (abfd, size);
00672                 if (local_plt_offsets == NULL)
00673                   return FALSE;
00674                 elf_local_got_offsets (abfd) = local_plt_offsets;
00675 
00676                 for (i = 0; i < symtab_hdr->sh_info; i++)
00677                   local_plt_offsets[i] = (bfd_vma) -1;
00678               }
00679              offset = &local_plt_offsets[r_symndx];
00680            }
00681 
00682          if (*offset == (bfd_vma) -1)
00683            {
00684              *offset = splt->size;
00685              splt->size += 4;
00686            }
00687          break;
00688         }
00689     }
00690  
00691   return TRUE;
00692 }
00693 
00694 /* This must exist if dynobj is ever set.  */
00695 
00696 static bfd_boolean
00697 m32c_elf_finish_dynamic_sections (bfd *abfd ATTRIBUTE_UNUSED,
00698                                   struct bfd_link_info *info)
00699 {
00700   bfd *dynobj;
00701   asection *splt;
00702 
00703   /* As an extra sanity check, verify that all plt entries have
00704      been filled in.  */
00705 
00706   if ((dynobj = elf_hash_table (info)->dynobj) != NULL
00707       && (splt = bfd_get_section_by_name (dynobj, ".plt")) != NULL)
00708     {
00709       bfd_byte *contents = splt->contents;
00710       unsigned int i, size = splt->size;
00711       for (i = 0; i < size; i += 4)
00712        {
00713          unsigned int x = bfd_get_32 (dynobj, contents + i);
00714          BFD_ASSERT (x != 0);
00715        }
00716     }
00717 
00718   return TRUE;
00719 }
00720 
00721 static bfd_boolean
00722 m32c_elf_always_size_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
00723                                struct bfd_link_info *info)
00724 {
00725   bfd *dynobj;
00726   asection *splt;
00727 
00728   if (info->relocatable)
00729     return TRUE;
00730 
00731   dynobj = elf_hash_table (info)->dynobj;
00732   if (dynobj == NULL)
00733     return TRUE;
00734 
00735   splt = bfd_get_section_by_name (dynobj, ".plt");
00736   BFD_ASSERT (splt != NULL);
00737 
00738   splt->contents = (bfd_byte *) bfd_zalloc (dynobj, splt->size);
00739   if (splt->contents == NULL)
00740     return FALSE;
00741 
00742   return TRUE;
00743 }
00744 
00745 /* Function to set the ELF flag bits.  */
00746 
00747 static bfd_boolean
00748 m32c_elf_set_private_flags (bfd *abfd, flagword flags)
00749 {
00750   elf_elfheader (abfd)->e_flags = flags;
00751   elf_flags_init (abfd) = TRUE;
00752   return TRUE;
00753 }
00754 
00755 /* Merge backend specific data from an object file to the output
00756    object file when linking.  */
00757 
00758 static bfd_boolean
00759 m32c_elf_merge_private_bfd_data (bfd *ibfd, bfd *obfd)
00760 {
00761   flagword old_flags, old_partial;
00762   flagword new_flags, new_partial;
00763   bfd_boolean error = FALSE;
00764   char new_opt[80];
00765   char old_opt[80];
00766 
00767   new_opt[0] = old_opt[0] = '\0';
00768   new_flags = elf_elfheader (ibfd)->e_flags;
00769   old_flags = elf_elfheader (obfd)->e_flags;
00770 
00771 #ifdef DEBUG
00772   (*_bfd_error_handler) ("old_flags = 0x%.8lx, new_flags = 0x%.8lx, init = %s, filename = %s",
00773                       old_flags, new_flags, elf_flags_init (obfd) ? "yes" : "no",
00774                       bfd_get_filename (ibfd));
00775 #endif
00776 
00777   if (!elf_flags_init (obfd))
00778     {
00779       /* First call, no flags set.  */
00780       elf_flags_init (obfd) = TRUE;
00781       elf_elfheader (obfd)->e_flags = new_flags;
00782     }
00783 
00784   else if (new_flags == old_flags)
00785     /* Compatible flags are ok.     */
00786     ;
00787 
00788   else        /* Possibly incompatible flags.     */
00789     {
00790       /* Warn if different cpu is used (allow a specific cpu to override
00791         the generic cpu).  */
00792       new_partial = (new_flags & EF_M32C_CPU_MASK);
00793       old_partial = (old_flags & EF_M32C_CPU_MASK);
00794       if (new_partial == old_partial)
00795        ;
00796 
00797       else
00798        {
00799          switch (new_partial)
00800            {
00801            default:           strcat (new_opt, " -m16c");      break;
00802            case EF_M32C_CPU_M16C:  strcat (new_opt, " -m16c");  break;
00803            case EF_M32C_CPU_M32C:  strcat (new_opt, " -m32c");  break;
00804            }
00805 
00806          switch (old_partial)
00807            {
00808            default:           strcat (old_opt, " -m16c");      break;
00809            case EF_M32C_CPU_M16C:  strcat (old_opt, " -m16c");  break;
00810            case EF_M32C_CPU_M32C:  strcat (old_opt, " -m32c");  break;
00811            }
00812        }
00813       
00814       /* Print out any mismatches from above.  */
00815       if (new_opt[0])
00816        {
00817          error = TRUE;
00818          (*_bfd_error_handler)
00819            (_("%s: compiled with %s and linked with modules compiled with %s"),
00820             bfd_get_filename (ibfd), new_opt, old_opt);
00821        }
00822 
00823       new_flags &= ~ EF_M32C_ALL_FLAGS;
00824       old_flags &= ~ EF_M32C_ALL_FLAGS;
00825 
00826       /* Warn about any other mismatches.  */
00827       if (new_flags != old_flags)
00828        {
00829          error = TRUE;
00830          (*_bfd_error_handler)
00831            (_("%s: uses different e_flags (0x%lx) fields than previous modules (0x%lx)"),
00832             bfd_get_filename (ibfd), (long)new_flags, (long)old_flags);
00833        }
00834     }
00835 
00836   if (error)
00837     bfd_set_error (bfd_error_bad_value);
00838 
00839   return !error;
00840 }
00841 
00842 
00843 static bfd_boolean
00844 m32c_elf_print_private_bfd_data (bfd *abfd, PTR ptr)
00845 {
00846   FILE *file = (FILE *) ptr;
00847   flagword flags;
00848 
00849   BFD_ASSERT (abfd != NULL && ptr != NULL);
00850 
00851   /* Print normal ELF private data.  */
00852   _bfd_elf_print_private_bfd_data (abfd, ptr);
00853 
00854   flags = elf_elfheader (abfd)->e_flags;
00855   fprintf (file, _("private flags = 0x%lx:"), (long)flags);
00856 
00857   switch (flags & EF_M32C_CPU_MASK)
00858     {
00859     default:                                            break;
00860     case EF_M32C_CPU_M16C:  fprintf (file, " -m16c");   break;
00861     case EF_M32C_CPU_M32C:  fprintf (file, " -m32c");   break;
00862     }
00863 
00864   fputc ('\n', file);
00865   return TRUE;
00866 }
00867 
00868 /* Return the MACH for an e_flags value.  */
00869 
00870 static int
00871 elf32_m32c_machine (bfd *abfd)
00872 {
00873   switch (elf_elfheader (abfd)->e_flags & EF_M32C_CPU_MASK)
00874     {
00875     case EF_M32C_CPU_M16C:  return bfd_mach_m16c;
00876     case EF_M32C_CPU_M32C:         return bfd_mach_m32c;
00877     }
00878 
00879   return bfd_mach_m16c;
00880 }
00881 
00882 static bfd_boolean
00883 m32c_elf_object_p (bfd *abfd)
00884 {
00885   bfd_default_set_arch_mach (abfd, bfd_arch_m32c,
00886                           elf32_m32c_machine (abfd));
00887   return TRUE;
00888 }
00889  
00890 
00891 #ifdef DEBUG
00892 void
00893 dump_symtab (bfd * abfd, void *internal_syms, void *external_syms)
00894 {
00895   size_t locsymcount;
00896   Elf_Internal_Sym *isymbuf;
00897   Elf_Internal_Sym *isymend;
00898   Elf_Internal_Sym *isym;
00899   Elf_Internal_Shdr *symtab_hdr;
00900   bfd_boolean free_internal = 0, free_external = 0;
00901   char * st_info_str;
00902   char * st_info_stb_str;
00903   char * st_other_str;
00904   char * st_shndx_str;
00905 
00906   if (! internal_syms)
00907     {
00908       internal_syms = bfd_malloc (1000);
00909       free_internal = 1;
00910     }
00911   if (! external_syms)
00912     {
00913       external_syms = bfd_malloc (1000);
00914       free_external = 1;
00915     }
00916   
00917   symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
00918   locsymcount = symtab_hdr->sh_size / get_elf_backend_data(abfd)->s->sizeof_sym;
00919   if (free_internal)
00920     isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr,
00921                                 symtab_hdr->sh_info, 0,
00922                                 internal_syms, external_syms, NULL);
00923   else
00924     isymbuf = internal_syms;
00925   isymend = isymbuf + locsymcount;
00926 
00927   for (isym = isymbuf ; isym < isymend ; isym++)
00928     {
00929       switch (ELF_ST_TYPE (isym->st_info))
00930        {
00931        case STT_FUNC: st_info_str = "STT_FUNC";
00932        case STT_SECTION: st_info_str = "STT_SECTION";
00933        case STT_FILE: st_info_str = "STT_FILE";
00934        case STT_OBJECT: st_info_str = "STT_OBJECT";
00935        case STT_TLS: st_info_str = "STT_TLS";
00936        default: st_info_str = "";
00937        }
00938       switch (ELF_ST_BIND (isym->st_info))
00939        {
00940        case STB_LOCAL: st_info_stb_str = "STB_LOCAL";
00941        case STB_GLOBAL: st_info_stb_str = "STB_GLOBAL";
00942        default: st_info_stb_str = "";
00943        }
00944       switch (ELF_ST_VISIBILITY (isym->st_other))
00945        {
00946        case STV_DEFAULT: st_other_str = "STV_DEFAULT";
00947        case STV_INTERNAL: st_other_str = "STV_INTERNAL";
00948        case STV_PROTECTED: st_other_str = "STV_PROTECTED";
00949        default: st_other_str = "";
00950        }
00951       switch (isym->st_shndx)
00952        {
00953        case SHN_ABS: st_shndx_str = "SHN_ABS";
00954        case SHN_COMMON: st_shndx_str = "SHN_COMMON";
00955        case SHN_UNDEF: st_shndx_str = "SHN_UNDEF";
00956        default: st_shndx_str = "";
00957        }
00958       
00959       printf ("isym = %p st_value = %lx st_size = %lx st_name = (%lu) %s "
00960              "st_info = (%d) %s %s st_other = (%d) %s st_shndx = (%d) %s\n",
00961              isym, 
00962              (unsigned long) isym->st_value,
00963              (unsigned long) isym->st_size,
00964              isym->st_name,
00965              bfd_elf_string_from_elf_section (abfd, symtab_hdr->sh_link,
00966                                           isym->st_name),
00967              isym->st_info, st_info_str, st_info_stb_str,
00968              isym->st_other, st_other_str,
00969              isym->st_shndx, st_shndx_str);
00970     }
00971   if (free_internal)
00972     free (internal_syms);
00973   if (free_external)
00974     free (external_syms);
00975 }
00976 
00977 char *
00978 m32c_get_reloc (long reloc)
00979 {
00980   if (0 <= reloc && reloc < R_M32C_max)
00981     return m32c_elf_howto_table[reloc].name;
00982   else
00983     return "";
00984 }
00985 #endif /* DEBUG */
00986 
00987 /* Handle relaxing.  */
00988 
00989 /* A subroutine of m32c_elf_relax_section.  If the global symbol H
00990    is within the low 64k, remove any entry for it in the plt.  */
00991 
00992 struct relax_plt_data
00993 {
00994   asection *splt;
00995   bfd_boolean *again;
00996 };
00997 
00998 static bfd_boolean
00999 m32c_relax_plt_check (struct elf_link_hash_entry *h,
01000                       PTR xdata)
01001 {
01002   struct relax_plt_data *data = (struct relax_plt_data *) xdata;
01003 
01004   if (h->root.type == bfd_link_hash_warning)
01005     h = (struct elf_link_hash_entry *) h->root.u.i.link;
01006 
01007   if (h->plt.offset != (bfd_vma) -1)
01008     {
01009       bfd_vma address;
01010 
01011       if (h->root.type == bfd_link_hash_undefined
01012          || h->root.type == bfd_link_hash_undefweak)
01013        address = 0;
01014       else
01015        address = (h->root.u.def.section->output_section->vma
01016                  + h->root.u.def.section->output_offset
01017                  + h->root.u.def.value);
01018 
01019       if (address <= 0xffff)
01020        {
01021          h->plt.offset = -1;
01022          data->splt->size -= 4;
01023          *data->again = TRUE;
01024        }
01025     }
01026 
01027   return TRUE;
01028 }
01029 
01030 /* A subroutine of m32c_elf_relax_section.  If the global symbol H
01031    previously had a plt entry, give it a new entry offset.  */
01032 
01033 static bfd_boolean
01034 m32c_relax_plt_realloc (struct elf_link_hash_entry *h,
01035                         PTR xdata)
01036 {
01037   bfd_vma *entry = (bfd_vma *) xdata;
01038 
01039   if (h->root.type == bfd_link_hash_warning)
01040     h = (struct elf_link_hash_entry *) h->root.u.i.link;
01041 
01042   if (h->plt.offset != (bfd_vma) -1)
01043     {
01044       h->plt.offset = *entry;
01045       *entry += 4;
01046     }
01047 
01048   return TRUE;
01049 }
01050 
01051 static bfd_boolean
01052 m32c_elf_relax_plt_section (bfd *dynobj,
01053                             asection *splt,
01054                             struct bfd_link_info *info,
01055                             bfd_boolean *again)
01056 {
01057   struct relax_plt_data relax_plt_data;
01058   bfd *ibfd;
01059 
01060   /* Assume nothing changes.  */
01061   *again = FALSE;
01062 
01063   if (info->relocatable)
01064     return TRUE;
01065 
01066   /* We only relax the .plt section at the moment.  */
01067   if (dynobj != elf_hash_table (info)->dynobj
01068       || strcmp (splt->name, ".plt") != 0)
01069     return TRUE;
01070 
01071   /* Quick check for an empty plt.  */
01072   if (splt->size == 0)
01073     return TRUE;
01074 
01075   /* Map across all global symbols; see which ones happen to
01076      fall in the low 64k.  */
01077   relax_plt_data.splt = splt;
01078   relax_plt_data.again = again;
01079   elf_link_hash_traverse (elf_hash_table (info), m32c_relax_plt_check,
01080                        &relax_plt_data);
01081 
01082   /* Likewise for local symbols, though that's somewhat less convenient
01083      as we have to walk the list of input bfds and swap in symbol data.  */
01084   for (ibfd = info->input_bfds; ibfd ; ibfd = ibfd->link_next)
01085     {
01086       bfd_vma *local_plt_offsets = elf_local_got_offsets (ibfd);
01087       Elf_Internal_Shdr *symtab_hdr;
01088       Elf_Internal_Sym *isymbuf = NULL;
01089       unsigned int idx;
01090 
01091       if (! local_plt_offsets)
01092        continue;
01093 
01094       symtab_hdr = &elf_tdata (ibfd)->symtab_hdr;
01095       if (symtab_hdr->sh_info != 0)
01096        {
01097          isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
01098          if (isymbuf == NULL)
01099            isymbuf = bfd_elf_get_elf_syms (ibfd, symtab_hdr,
01100                                        symtab_hdr->sh_info, 0,
01101                                        NULL, NULL, NULL);
01102          if (isymbuf == NULL)
01103            return FALSE;
01104        }
01105 
01106       for (idx = 0; idx < symtab_hdr->sh_info; ++idx)
01107        {
01108          Elf_Internal_Sym *isym;
01109          asection *tsec;
01110          bfd_vma address;
01111 
01112          if (local_plt_offsets[idx] == (bfd_vma) -1)
01113            continue;
01114 
01115          isym = &isymbuf[idx];
01116          if (isym->st_shndx == SHN_UNDEF)
01117            continue;
01118          else if (isym->st_shndx == SHN_ABS)
01119            tsec = bfd_abs_section_ptr;
01120          else if (isym->st_shndx == SHN_COMMON)
01121            tsec = bfd_com_section_ptr;
01122          else
01123            tsec = bfd_section_from_elf_index (ibfd, isym->st_shndx);
01124 
01125          address = (tsec->output_section->vma
01126                    + tsec->output_offset
01127                    + isym->st_value);
01128          if (address <= 0xffff)
01129            {
01130              local_plt_offsets[idx] = -1;
01131              splt->size -= 4;
01132              *again = TRUE;
01133            }
01134        }
01135 
01136       if (isymbuf != NULL
01137          && symtab_hdr->contents != (unsigned char *) isymbuf)
01138        {
01139          if (! info->keep_memory)
01140            free (isymbuf);
01141          else
01142            {
01143              /* Cache the symbols for elf_link_input_bfd.  */
01144              symtab_hdr->contents = (unsigned char *) isymbuf;
01145            }
01146        }
01147     }
01148 
01149   /* If we changed anything, walk the symbols again to reallocate
01150      .plt entry addresses.  */
01151   if (*again && splt->size > 0)
01152     {
01153       bfd_vma entry = 0;
01154 
01155       elf_link_hash_traverse (elf_hash_table (info),
01156                            m32c_relax_plt_realloc, &entry);
01157 
01158       for (ibfd = info->input_bfds; ibfd ; ibfd = ibfd->link_next)
01159        {
01160          bfd_vma *local_plt_offsets = elf_local_got_offsets (ibfd);
01161          unsigned int nlocals = elf_tdata (ibfd)->symtab_hdr.sh_info;
01162          unsigned int idx;
01163 
01164          if (! local_plt_offsets)
01165            continue;
01166 
01167          for (idx = 0; idx < nlocals; ++idx)
01168            if (local_plt_offsets[idx] != (bfd_vma) -1)
01169              {
01170                local_plt_offsets[idx] = entry;
01171               entry += 4;
01172              }
01173        }
01174     }
01175 
01176   return TRUE;
01177 }
01178 
01179 static int
01180 compare_reloc (const void *e1, const void *e2)
01181 {
01182   const Elf_Internal_Rela *i1 = (const Elf_Internal_Rela *) e1;
01183   const Elf_Internal_Rela *i2 = (const Elf_Internal_Rela *) e2;
01184 
01185   if (i1->r_offset == i2->r_offset)
01186     return 0;
01187   else
01188     return i1->r_offset < i2->r_offset ? -1 : 1;
01189 }
01190 
01191 #define OFFSET_FOR_RELOC(rel) m32c_offset_for_reloc (abfd, rel, symtab_hdr, shndx_buf, intsyms)
01192 static bfd_vma
01193 m32c_offset_for_reloc (bfd *abfd,
01194                      Elf_Internal_Rela *rel,
01195                      Elf_Internal_Shdr *symtab_hdr,
01196                      Elf_External_Sym_Shndx *shndx_buf,
01197                      Elf_Internal_Sym *intsyms)
01198 {
01199   bfd_vma symval;
01200 
01201   /* Get the value of the symbol referred to by the reloc.  */
01202   if (ELF32_R_SYM (rel->r_info) < symtab_hdr->sh_info)
01203     {
01204       /* A local symbol.  */
01205       Elf_Internal_Sym *isym;
01206       Elf_External_Sym_Shndx *shndx;
01207       asection *ssec;
01208 
01209 
01210       isym = intsyms + ELF32_R_SYM (rel->r_info);
01211       ssec = bfd_section_from_elf_index (abfd, isym->st_shndx);
01212       shndx = shndx_buf + (shndx_buf ? ELF32_R_SYM (rel->r_info) : 0);
01213 
01214       symval = isym->st_value;
01215       if (ssec)
01216        symval += ssec->output_section->vma
01217          + ssec->output_offset;
01218     }
01219   else
01220     {
01221       unsigned long indx;
01222       struct elf_link_hash_entry *h;
01223 
01224       /* An external symbol.  */
01225       indx = ELF32_R_SYM (rel->r_info) - symtab_hdr->sh_info;
01226       h = elf_sym_hashes (abfd)[indx];
01227       BFD_ASSERT (h != NULL);
01228 
01229       if (h->root.type != bfd_link_hash_defined
01230          && h->root.type != bfd_link_hash_defweak)
01231        /* This appears to be a reference to an undefined
01232           symbol.  Just ignore it--it will be caught by the
01233           regular reloc processing.  */
01234        return 0;
01235 
01236       symval = (h->root.u.def.value
01237               + h->root.u.def.section->output_section->vma
01238               + h->root.u.def.section->output_offset);
01239     }
01240   return symval;
01241 }
01242 
01243 static int bytes_saved = 0;
01244 
01245 static int bytes_to_reloc[] = {
01246   R_M32C_NONE,
01247   R_M32C_8,
01248   R_M32C_16,
01249   R_M32C_24,
01250   R_M32C_32
01251 };
01252 
01253 /* What we use the bits in a relax reloc addend (R_M32C_RL_*) for.  */
01254 
01255 /* Mask for the number of relocs associated with this insn.  */
01256 #define RLA_RELOCS          0x0000000f
01257 /* Number of bytes gas emitted (before gas's relaxing) */
01258 #define RLA_NBYTES          0x00000ff0
01259 
01260 /* If the displacement is within the given range and the new encoding
01261    differs from the old encoding (the index), then the insn can be
01262    relaxed to the new encoding.  */
01263 typedef struct {
01264   int bytes;
01265   unsigned int max_disp;
01266   unsigned char new_encoding;
01267 } EncodingTable;
01268 
01269 static EncodingTable m16c_addr_encodings[] = {
01270   { 0,   0,  0 }, /* R0 */
01271   { 0,   0,  1 }, /* R1 */
01272   { 0,   0,  2 }, /* R2 */
01273   { 0,   0,  3 }, /* R3 */
01274   { 0,   0,  4 }, /* A0 */
01275   { 0,   0,  5 }, /* A1 */
01276   { 0,   0,  6 }, /* [A0] */
01277   { 0,   0,  7 }, /* [A1] */
01278   { 1,   0,  6 }, /* udsp:8[A0] */
01279   { 1,   0,  7 }, /* udsp:8[A1] */
01280   { 1,   0, 10 }, /* udsp:8[SB] */
01281   { 1,   0, 11 }, /* sdsp:8[FB] */
01282   { 2, 255,  8 }, /* udsp:16[A0] */
01283   { 2, 255,  9 }, /* udsp:16[A1] */
01284   { 2, 255, 10 }, /* udsp:16[SB] */
01285   { 2,   0, 15 }, /* abs:16 */
01286 };
01287 
01288 static EncodingTable m16c_jmpaddr_encodings[] = {
01289   { 0,   0,  0 }, /* R0 */
01290   { 0,   0,  1 }, /* R1 */
01291   { 0,   0,  2 }, /* R2 */
01292   { 0,   0,  3 }, /* R3 */
01293   { 0,   0,  4 }, /* A0 */
01294   { 0,   0,  5 }, /* A1 */
01295   { 0,   0,  6 }, /* [A0] */
01296   { 0,   0,  7 }, /* [A1] */
01297   { 1,   0,  6 }, /* udsp:8[A0] */
01298   { 1,   0,  7 }, /* udsp:8[A1] */
01299   { 1,   0, 10 }, /* udsp:8[SB] */
01300   { 1,   0, 11 }, /* sdsp:8[FB] */
01301   { 3, 255,  8 }, /* udsp:20[A0] */
01302   { 3, 255,  9 }, /* udsp:20[A1] */
01303   { 2, 255, 10 }, /* udsp:16[SB] */
01304   { 2,   0, 15 }, /* abs:16 */
01305 };
01306 
01307 static EncodingTable m32c_addr_encodings[] = {
01308   { 0,     0,  0 }, /* [A0] */
01309   { 0,     0,  1 }, /* [A1] */
01310   { 0,     0,  2 }, /* A0 */
01311   { 0,     0,  3 }, /* A1 */
01312   { 1,     0,  0 }, /* udsp:8[A0] */
01313   { 1,     0,  1 }, /* udsp:8[A1] */
01314   { 1,     0,  6 }, /* udsp:8[SB] */
01315   { 1,     0,  7 }, /* sdsp:8[FB] */
01316   { 2,   255,  4 }, /* udsp:16[A0] */
01317   { 2,   255,  5 }, /* udsp:16[A1] */
01318   { 2,   255,  6 }, /* udsp:16[SB] */
01319   { 2,   127,  7 }, /* sdsp:16[FB] */
01320   { 3, 65535, 8 }, /* udsp:24[A0] */
01321   { 3, 65535, 9 }, /* udsp:24[A1] */
01322   { 3, 65535, 15 }, /* abs24 */
01323   { 2,     0, 15 }, /* abs16 */
01324   { 0,     0, 16 }, /* R2 */
01325   { 0,     0, 17 }, /* R3 */
01326   { 0,     0, 18 }, /* R0 */
01327   { 0,     0, 19 }, /* R1 */
01328   { 0,     0, 20 }, /*  */
01329   { 0,     0, 21 }, /*  */
01330   { 0,     0, 22 }, /*  */
01331   { 0,     0, 23 }, /*  */
01332   { 0,     0, 24 }, /*  */
01333   { 0,     0, 25 }, /*  */
01334   { 0,     0, 26 }, /*  */
01335   { 0,     0, 27 }, /*  */
01336   { 0,     0, 28 }, /*  */
01337   { 0,     0, 29 }, /*  */
01338   { 0,     0, 30 }, /*  */
01339   { 0,     0, 31 }, /*  */
01340 };
01341 
01342 static bfd_boolean
01343 m32c_elf_relax_section
01344     (bfd *                  abfd,
01345      asection *             sec,
01346      struct bfd_link_info * link_info,
01347      bfd_boolean *          again)
01348 {
01349   Elf_Internal_Shdr *symtab_hdr;
01350   Elf_Internal_Shdr *shndx_hdr;
01351   Elf_Internal_Rela *internal_relocs;
01352   Elf_Internal_Rela *free_relocs = NULL;
01353   Elf_Internal_Rela *irel, *irelend, *srel;
01354   bfd_byte * contents = NULL;
01355   bfd_byte * free_contents = NULL;
01356   Elf_Internal_Sym *intsyms = NULL;
01357   Elf_Internal_Sym *free_intsyms = NULL;
01358   Elf_External_Sym_Shndx *shndx_buf = NULL;
01359   int machine;
01360 
01361   if (abfd == elf_hash_table (link_info)->dynobj
01362       && strcmp (sec->name, ".plt") == 0)
01363     return m32c_elf_relax_plt_section (abfd, sec, link_info, again);
01364 
01365   /* Assume nothing changes.  */
01366   *again = FALSE;
01367 
01368   machine = elf32_m32c_machine (abfd);
01369 
01370   /* We don't have to do anything for a relocatable link, if
01371      this section does not have relocs, or if this is not a
01372      code section.  */
01373   if (link_info->relocatable
01374       || (sec->flags & SEC_RELOC) == 0
01375       || sec->reloc_count == 0
01376       || (sec->flags & SEC_CODE) == 0)
01377     return TRUE;
01378 
01379   symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
01380   shndx_hdr = &elf_tdata (abfd)->symtab_shndx_hdr;
01381 
01382   /* Get the section contents.  */
01383   if (elf_section_data (sec)->this_hdr.contents != NULL)
01384     contents = elf_section_data (sec)->this_hdr.contents;
01385   /* Go get them off disk.  */
01386   else if (!bfd_malloc_and_get_section (abfd, sec, &contents))
01387     goto error_return;
01388 
01389   /* Read this BFD's symbols.  */
01390   /* Get cached copy if it exists.  */
01391   if (symtab_hdr->contents != NULL)
01392     {
01393       intsyms = (Elf_Internal_Sym *) symtab_hdr->contents;
01394     }
01395   else
01396     {
01397       intsyms = bfd_elf_get_elf_syms (abfd, symtab_hdr, symtab_hdr->sh_info, 0, NULL, NULL, NULL);
01398       symtab_hdr->contents = (bfd_byte *) intsyms;
01399     }
01400 
01401   if (shndx_hdr->sh_size != 0)
01402     {
01403       bfd_size_type amt;
01404 
01405       amt = symtab_hdr->sh_info;
01406       amt *= sizeof (Elf_External_Sym_Shndx);
01407       shndx_buf = (Elf_External_Sym_Shndx *) bfd_malloc (amt);
01408       if (shndx_buf == NULL)
01409        goto error_return;
01410       if (bfd_seek (abfd, shndx_hdr->sh_offset, SEEK_SET) != 0
01411          || bfd_bread ((PTR) shndx_buf, amt, abfd) != amt)
01412        goto error_return;
01413       shndx_hdr->contents = (bfd_byte *) shndx_buf;
01414     }
01415 
01416   /* Get a copy of the native relocations.  */
01417   internal_relocs = (_bfd_elf_link_read_relocs
01418                    (abfd, sec, (PTR) NULL, (Elf_Internal_Rela *) NULL,
01419                     link_info->keep_memory));
01420   if (internal_relocs == NULL)
01421     goto error_return;
01422   if (! link_info->keep_memory)
01423     free_relocs = internal_relocs;
01424 
01425   /* The RL_ relocs must be just before the operand relocs they go
01426      with, so we must sort them to guarantee this.  */
01427   qsort (internal_relocs, sec->reloc_count, sizeof (Elf_Internal_Rela),
01428          compare_reloc);
01429 
01430   /* Walk through them looking for relaxing opportunities.  */
01431   irelend = internal_relocs + sec->reloc_count;
01432 
01433   for (irel = internal_relocs; irel < irelend; irel++)
01434     {
01435       bfd_vma symval;
01436       unsigned char *insn, *gap, *einsn;
01437       bfd_vma pc;
01438       bfd_signed_vma pcrel;
01439       int relax_relocs;
01440       int gap_size;
01441       int new_type;
01442       int posn;
01443       int enc;
01444       EncodingTable *enctbl;
01445       EncodingTable *e;
01446 
01447       if (ELF32_R_TYPE(irel->r_info) != R_M32C_RL_JUMP
01448          && ELF32_R_TYPE(irel->r_info) != R_M32C_RL_1ADDR
01449          && ELF32_R_TYPE(irel->r_info) != R_M32C_RL_2ADDR)
01450        continue;
01451 
01452       srel = irel;
01453 
01454       /* There will always be room for the relaxed insn, since it is smaller
01455         than the one it would replace.  */
01456       BFD_ASSERT (irel->r_offset < sec->size);
01457 
01458       insn = contents + irel->r_offset;
01459       relax_relocs = irel->r_addend % 16;
01460 
01461       /* Ok, we only have three relocs we care about, and they're all
01462         fake.  The lower four bits of the addend is always the number
01463         of following relocs (hence the qsort above) that are assigned
01464         to this opcode.  The next 8 bits of the addend indicates the
01465         number of bytes in the insn.  We use the rest of them
01466         ourselves as flags for the more expensive operations (defines
01467         above).  The three relocs are:
01468 
01469         RL_JUMP: This marks all direct jump insns.  We check the
01470               displacement and replace them with shorter jumps if
01471               they're in range.  We also use this to find JMP.S
01472               insns and manually shorten them when we delete bytes.
01473               We have to decode these insns to figure out what to
01474               do.
01475 
01476         RL_1ADDR: This is a :G or :Q insn, which has a single
01477               "standard" operand.  We have to extract the type
01478               field, see if it's a wide displacement, then figure
01479               out if we can replace it with a narrow displacement.
01480               We don't have to decode these insns.
01481 
01482         RL_2ADDR: Similarly, but two "standard" operands.  Note that
01483               r_addend may still be 1, as standard operands don't
01484               always have displacements.  Gas shouldn't give us one
01485               with zero operands, but since we don't know which one
01486               has the displacement, we check them both anyway.
01487 
01488         These all point to the beginning of the insn itself, not the
01489         operands.
01490 
01491         Note that we only relax one step at a time, relying on the
01492         linker to call us repeatedly.  Thus, there is no code for
01493         JMP.A->JMP.B although that will happen in two steps.
01494         Likewise, for 2ADDR relaxes, we do one operand per cycle.
01495       */
01496 
01497       /* Get the value of the symbol referred to by the reloc.  Just
01498          in case this is the last reloc in the list, use the RL's
01499          addend to choose between this reloc (no addend) or the next
01500          (yes addend, which means at least one following reloc).  */
01501       srel = irel + (relax_relocs ? 1 : 0);
01502       symval = OFFSET_FOR_RELOC (srel);
01503 
01504       /* Setting gap_size nonzero is the flag which means "something
01505         shrunk".  */
01506       gap_size = 0;
01507       gap = NULL;
01508       new_type = ELF32_R_TYPE(srel->r_info);
01509 
01510       pc = sec->output_section->vma + sec->output_offset
01511        + srel->r_offset;
01512       pcrel = symval - pc + srel->r_addend;
01513 
01514       if (machine == bfd_mach_m16c)
01515        {
01516          /* R8C / M16C */
01517 
01518          switch (ELF32_R_TYPE(irel->r_info))
01519            {
01520 
01521            case R_M32C_RL_JUMP:
01522              switch (insn[0])
01523               {
01524               case 0xfe: /* jmp.b */
01525                 if (pcrel >= 2 && pcrel <= 9)
01526                   {
01527                     /* Relax JMP.B -> JMP.S.  We need to get rid of
01528                       the following reloc though. */
01529                     insn[0] = 0x60 | (pcrel - 2);
01530                     new_type = R_M32C_NONE;
01531                     irel->r_addend = 0x10;
01532                     gap_size = 1;
01533                     gap = insn + 1;
01534                   }
01535                 break;
01536 
01537               case 0xf4: /* jmp.w */
01538                 /* 128 is allowed because it will be one byte closer
01539                    after relaxing.  Likewise for all other pc-rel
01540                    jumps.  */
01541                 if (pcrel <= 128 && pcrel >= -128)
01542                   {
01543                     /* Relax JMP.W -> JMP.B */
01544                     insn[0] = 0xfe;
01545                     insn[1] = 0;
01546                     new_type = R_M32C_8_PCREL;
01547                     gap_size = 1;
01548                     gap = insn + 2;
01549                   }
01550                 break;
01551 
01552               case 0xfc: /* jmp.a */
01553                 if (pcrel <= 32768 && pcrel >= -32768)
01554                   {
01555                     /* Relax JMP.A -> JMP.W */
01556                     insn[0] = 0xf4;
01557                     insn[1] = 0;
01558                     insn[2] = 0;
01559                     new_type = R_M32C_16_PCREL;
01560                     gap_size = 1;
01561                     gap = insn + 3;
01562                   }
01563                 break;
01564 
01565               case 0xfd: /* jsr.a */
01566                 if (pcrel <= 32768 && pcrel >= -32768)
01567                   {
01568                     /* Relax JSR.A -> JSR.W */
01569                     insn[0] = 0xf5;
01570                     insn[1] = 0;
01571                     insn[2] = 0;
01572                     new_type = R_M32C_16_PCREL;
01573                     gap_size = 1;
01574                     gap = insn + 3;
01575                   }
01576                 break;
01577               }
01578              break;
01579 
01580            case R_M32C_RL_2ADDR:
01581              /* xxxx xxxx srce dest [src-disp] [dest-disp]*/
01582 
01583              enctbl = m16c_addr_encodings;
01584              posn = 2;
01585              enc = (insn[1] >> 4) & 0x0f;
01586              e = & enctbl[enc];
01587 
01588              if (srel->r_offset == irel->r_offset + posn
01589                 && e->new_encoding != enc
01590                 && symval <= e->max_disp)
01591               {
01592                 insn[1] &= 0x0f;
01593                 insn[1] |= e->new_encoding << 4;
01594                 gap_size = e->bytes - enctbl[e->new_encoding].bytes;
01595                 gap = insn + posn + enctbl[e->new_encoding].bytes;
01596                 new_type = bytes_to_reloc[enctbl[e->new_encoding].bytes];
01597                 break;
01598               }
01599              if (relax_relocs == 2)
01600               srel ++;
01601              posn += e->bytes;
01602 
01603              goto try_1addr_16;
01604 
01605            case R_M32C_RL_1ADDR:
01606              /* xxxx xxxx xxxx dest [disp] */
01607 
01608              enctbl = m16c_addr_encodings;
01609              posn = 2;
01610              
01611              /* Check the opcode for jumps.  We know it's safe to
01612                do this because all 2ADDR insns are at least two
01613                bytes long.  */
01614              enc = insn[0] * 256 + insn[1];
01615              enc &= 0xfff0;
01616              if (enc == 0x7d20
01617                 || enc == 0x7d00
01618                 || enc == 0x7d30
01619                 || enc == 0x7d10)
01620               {
01621                 enctbl = m16c_jmpaddr_encodings;
01622               }
01623 
01624            try_1addr_16:
01625              /* srel, posn, and enc must be set here.  */
01626 
01627              symval = OFFSET_FOR_RELOC (srel);
01628              enc = insn[1] & 0x0f;
01629              e = & enctbl[enc];
01630 
01631              if (srel->r_offset == irel->r_offset + posn
01632                 && e->new_encoding != enc
01633                 && symval <= e->max_disp)
01634               {
01635                 insn[1] &= 0xf0;
01636                 insn[1] |= e->new_encoding;
01637                 gap_size = e->bytes - enctbl[e->new_encoding].bytes;
01638                 gap = insn + posn + enctbl[e->new_encoding].bytes;
01639                 new_type = bytes_to_reloc[enctbl[e->new_encoding].bytes];
01640                 break;
01641               }
01642 
01643              break;
01644 
01645            } /* Ends switch (reloc type) for m16c.  */
01646        }
01647       else /* machine == bfd_mach_m32c */
01648        {
01649          /* M32CM / M32C */
01650 
01651          switch (ELF32_R_TYPE(irel->r_info))
01652            {
01653 
01654            case R_M32C_RL_JUMP:
01655              switch (insn[0])
01656               {
01657               case 0xbb: /* jmp.b */
01658                 if (pcrel >= 2 && pcrel <= 9)
01659                   {
01660                     int p = pcrel - 2;
01661                     /* Relax JMP.B -> JMP.S.  We need to get rid of
01662                       the following reloc though. */
01663                     insn[0] = 0x4a | ((p << 3) & 0x30) | (p & 1);
01664                     new_type = R_M32C_NONE;
01665                     irel->r_addend = 0x10;
01666                     gap_size = 1;
01667                     gap = insn + 1;
01668                   }
01669                 break;
01670 
01671               case 0xce: /* jmp.w */
01672                 if (pcrel <= 128 && pcrel >= -128)
01673                   {
01674                     /* Relax JMP.W -> JMP.B */
01675                     insn[0] = 0xbb;
01676                     insn[1] = 0;
01677                     new_type = R_M32C_8_PCREL;
01678                     gap_size = 1;
01679                     gap = insn + 2;
01680                   }
01681                 break;
01682 
01683               case 0xcc: /* jmp.a */
01684                 if (pcrel <= 32768 && pcrel >= -32768)
01685                   {
01686                     /* Relax JMP.A -> JMP.W */
01687                     insn[0] = 0xce;
01688                     insn[1] = 0;
01689                     insn[2] = 0;
01690                     new_type = R_M32C_16_PCREL;
01691                     gap_size = 1;
01692                     gap = insn + 3;
01693                   }
01694                 break;
01695 
01696               case 0xcd: /* jsr.a */
01697                 if (pcrel <= 32768 && pcrel >= -32768)
01698                   {
01699                     /* Relax JSR.A -> JSR.W */
01700                     insn[0] = 0xcf;
01701                     insn[1] = 0;
01702                     insn[2] = 0;
01703                     new_type = R_M32C_16_PCREL;
01704                     gap_size = 1;
01705                     gap = insn + 3;
01706                   }
01707                 break;
01708               }
01709              break;
01710 
01711            case R_M32C_RL_2ADDR:
01712              /* xSSS DDDx DDSS xxxx [src-disp] [dest-disp]*/
01713 
01714              einsn = insn;
01715              posn = 2;
01716              if (einsn[0] == 1)
01717               {
01718                 /* prefix; remove it as far as the RL reloc is concerned.  */
01719                 einsn ++;
01720                 posn ++;
01721               }
01722 
01723              enctbl = m32c_addr_encodings;
01724              enc = ((einsn[0] & 0x70) >> 2) | ((einsn[1] & 0x30) >> 4);
01725              e = & enctbl[enc];
01726 
01727              if (srel->r_offset == irel->r_offset + posn
01728                 && e->new_encoding != enc
01729                 && symval <= e->max_disp)
01730               {
01731                 einsn[0] &= 0x8f;
01732                 einsn[0] |= (e->new_encoding & 0x1c) << 2;
01733                 einsn[1] &= 0xcf;
01734                 einsn[1] |= (e->new_encoding & 0x03) << 4;
01735                 gap_size = e->bytes - enctbl[e->new_encoding].bytes;
01736                 gap = insn + posn + enctbl[e->new_encoding].bytes;
01737                 new_type = bytes_to_reloc[enctbl[e->new_encoding].bytes];
01738                 break;
01739               }
01740              if (relax_relocs == 2)
01741                 srel ++;
01742              posn += e->bytes;
01743 
01744              goto try_1addr_32;
01745 
01746            case R_M32C_RL_1ADDR:
01747              /* xxxx DDDx DDxx xxxx [disp] */
01748 
01749              einsn = insn;
01750              posn = 2;
01751              if (einsn[0] == 1)
01752               {
01753                 /* prefix; remove it as far as the RL reloc is concerned.  */
01754                 einsn ++;
01755                 posn ++;
01756               }
01757 
01758              enctbl = m32c_addr_encodings;
01759 
01760            try_1addr_32:
01761              /* srel, posn, and enc must be set here.  */
01762 
01763              symval = OFFSET_FOR_RELOC (srel);
01764              enc = ((einsn[0] & 0x0e) << 1) |  ((einsn[1] & 0xc0) >> 6);
01765              e = & enctbl[enc];
01766 
01767              if (srel->r_offset == irel->r_offset + posn
01768                 && e->new_encoding != enc
01769                 && symval <= e->max_disp)
01770               {
01771                 einsn[0] &= 0xf1;
01772                 einsn[0] |= (e->new_encoding & 0x1c) >> 1;
01773                 einsn[1] &= 0x3f;
01774                 einsn[1] |= (e->new_encoding & 0x03) << 6;
01775                 gap_size = e->bytes - enctbl[e->new_encoding].bytes;
01776                 gap = insn + posn + enctbl[e->new_encoding].bytes;
01777                 new_type = bytes_to_reloc[enctbl[e->new_encoding].bytes];
01778                 break;
01779               }
01780 
01781              break;
01782 
01783            } /* Ends switch (reloc type) for m32c.  */
01784        }
01785 
01786       if (gap_size == 0)
01787        continue;
01788 
01789       *again = TRUE;
01790 
01791       srel->r_info = ELF32_R_INFO (ELF32_R_SYM (srel->r_info), new_type);
01792 
01793       /* Note that we've changed the relocs, section contents, etc.  */
01794       elf_section_data (sec)->relocs = internal_relocs;
01795       free_relocs = NULL;
01796       
01797       elf_section_data (sec)->this_hdr.contents = contents;
01798       free_contents = NULL;
01799 
01800       symtab_hdr->contents = (bfd_byte *) intsyms;
01801       free_intsyms = NULL;
01802 
01803       bytes_saved += gap_size;
01804 
01805       if (! m32c_elf_relax_delete_bytes(abfd, sec, gap - contents, gap_size))
01806        goto error_return;
01807 
01808     } /* next relocation */
01809 
01810   if (free_relocs != NULL)
01811     {
01812       free (free_relocs);
01813       free_relocs = NULL;
01814     }
01815 
01816   if (free_contents != NULL)
01817     {
01818       if (! link_info->keep_memory)
01819        free (free_contents);
01820       /* Cache the section contents for elf_link_input_bfd.  */
01821       else
01822        elf_section_data (sec)->this_hdr.contents = contents;
01823 
01824       free_contents = NULL;
01825     }
01826 
01827   if (shndx_buf != NULL)
01828     {
01829       shndx_hdr->contents = NULL;
01830       free (shndx_buf);
01831     }
01832 
01833   if (free_intsyms != NULL)
01834     {
01835       if (! link_info->keep_memory)
01836        free (free_intsyms);
01837       /* Cache the symbols for elf_link_input_bfd.  */
01838       else
01839        {
01840        symtab_hdr->contents = NULL /* (unsigned char *) intsyms*/;
01841        }
01842 
01843       free_intsyms = NULL;
01844     }
01845 
01846   return TRUE;
01847 
01848  error_return:
01849   if (free_relocs != NULL)
01850     free (free_relocs);
01851   if (free_contents != NULL)
01852     free (free_contents);
01853   if (shndx_buf != NULL)
01854     {
01855       shndx_hdr->contents = NULL;
01856       free (shndx_buf);
01857     }
01858   if (free_intsyms != NULL)
01859     free (free_intsyms);
01860   return FALSE;
01861 }
01862 
01863 /* Delete some bytes from a section while relaxing.  */
01864 
01865 static bfd_boolean
01866 m32c_elf_relax_delete_bytes
01867  (bfd *      abfd,
01868   asection * sec,
01869   bfd_vma    addr,
01870   int        count)
01871 {
01872   Elf_Internal_Shdr *symtab_hdr;
01873   Elf_Internal_Shdr *shndx_hdr;
01874   int sec_shndx;
01875   bfd_byte *contents;
01876   Elf_Internal_Rela *irel;
01877   Elf_Internal_Rela *irelend;
01878   Elf_Internal_Rela *irelalign;
01879   bfd_vma toaddr;
01880   Elf_Internal_Sym *isym;
01881   Elf_Internal_Sym *isymend;
01882   Elf_Internal_Sym *intsyms;
01883   Elf_External_Sym_Shndx *shndx_buf;
01884   Elf_External_Sym_Shndx *shndx;
01885   struct elf_link_hash_entry ** sym_hashes;
01886   struct elf_link_hash_entry ** end_hashes;
01887   unsigned int                  symcount;
01888 
01889   contents   = elf_section_data (sec)->this_hdr.contents;
01890 
01891   /* The deletion must stop at the next ALIGN reloc for an aligment
01892      power larger than the number of bytes we are deleting.  */
01893   irelalign = NULL;
01894   toaddr = sec->size;
01895 
01896   irel = elf_section_data (sec)->relocs;
01897   irelend = irel + sec->reloc_count;
01898 
01899   /* Actually delete the bytes.  */
01900   memmove (contents + addr, contents + addr + count, (size_t) (toaddr - addr - count));
01901   sec->size -= count;
01902 
01903   /* Adjust all the relocs.  */
01904   for (irel = elf_section_data (sec)->relocs; irel < irelend; irel ++)
01905     {
01906       /* Get the new reloc address.  */
01907       if (irel->r_offset > addr && irel->r_offset < toaddr)
01908        irel->r_offset -= count;
01909 
01910       if (ELF32_R_TYPE(irel->r_info) == R_M32C_RL_JUMP
01911          && irel->r_addend == 0x10 /* one byte insn, no relocs */
01912          && irel->r_offset + 1 < addr
01913          && irel->r_offset + 7 > addr)
01914        {
01915          bfd_vma disp;
01916          unsigned char *insn = &contents[irel->r_offset];
01917          disp = *insn;
01918          /* This is a JMP.S, which we have to manually update. */
01919          if (elf32_m32c_machine (abfd) == bfd_mach_m16c)
01920            {
01921              if ((*insn & 0xf8) != 0x60)
01922               continue;
01923              disp = (disp & 7);
01924            }
01925          else
01926            {
01927              if ((*insn & 0xce) != 0x4a)
01928               continue;
01929              disp = ((disp & 0x30) >> 3) | (disp & 1);
01930            }
01931          if (irel->r_offset + disp + 2 >= addr+count)
01932            {
01933              disp -= count;
01934              if (elf32_m32c_machine (abfd) == bfd_mach_m16c)
01935               {
01936                 *insn = (*insn & 0xf8) | disp;
01937               }
01938              else
01939               {
01940                 *insn = (*insn & 0xce) | ((disp & 6) << 3) | (disp & 1);
01941               }
01942            }
01943        }
01944     }
01945 
01946   /* Adjust the local symbols defined in this section.  */
01947   symtab_hdr = & elf_tdata (abfd)->symtab_hdr;
01948   intsyms = (Elf_Internal_Sym *) symtab_hdr->contents;
01949   isym = intsyms;
01950   isymend = isym + symtab_hdr->sh_info;
01951 
01952   sec_shndx  = _bfd_elf_section_from_bfd_section (abfd, sec);
01953   shndx_hdr  = & elf_tdata (abfd)->symtab_shndx_hdr;
01954   shndx_buf  = (Elf_External_Sym_Shndx *) shndx_hdr->contents;
01955   shndx = shndx_buf;
01956 
01957   for (; isym < isymend; isym++, shndx = (shndx ? shndx + 1 : NULL))
01958     {
01959 
01960       if ((int) isym->st_shndx == sec_shndx
01961          && isym->st_value > addr
01962          && isym->st_value < toaddr)
01963        {
01964          isym->st_value -= count;
01965        }
01966     }
01967 
01968   /* Now adjust the global symbols defined in this section.  */
01969   symcount = (symtab_hdr->sh_size / sizeof (Elf32_External_Sym)
01970              - symtab_hdr->sh_info);
01971   sym_hashes = elf_sym_hashes (abfd);
01972   //  sym_hashes += symtab_hdr->sh_info;
01973   end_hashes = sym_hashes + symcount;
01974 
01975   for (; sym_hashes < end_hashes; sym_hashes ++)
01976     {
01977       struct elf_link_hash_entry * sym_hash = * sym_hashes;
01978 
01979       if (sym_hash &&
01980          (   sym_hash->root.type == bfd_link_hash_defined
01981           || sym_hash->root.type == bfd_link_hash_defweak)
01982          && sym_hash->root.u.def.section == sec
01983          && sym_hash->root.u.def.value > addr
01984          && sym_hash->root.u.def.value < toaddr)
01985        {
01986          sym_hash->root.u.def.value -= count;
01987        }
01988     }
01989 
01990   return TRUE;
01991 }
01992 
01993 
01994 #define ELF_ARCH            bfd_arch_m32c
01995 #define ELF_MACHINE_CODE    EM_M32C
01996 #define ELF_MAXPAGESIZE            0x1000
01997 
01998 #if 0
01999 #define TARGET_BIG_SYM             bfd_elf32_m32c_vec
02000 #define TARGET_BIG_NAME            "elf32-m32c"
02001 #else
02002 #define TARGET_LITTLE_SYM          bfd_elf32_m32c_vec
02003 #define TARGET_LITTLE_NAME         "elf32-m32c"
02004 #endif
02005 
02006 #define elf_info_to_howto_rel                    NULL
02007 #define elf_info_to_howto                 m32c_info_to_howto_rela
02008 #define elf_backend_object_p                     m32c_elf_object_p
02009 #define elf_backend_relocate_section             m32c_elf_relocate_section
02010 #define elf_backend_check_relocs                m32c_elf_check_relocs
02011 #define elf_backend_object_p                     m32c_elf_object_p
02012 #define elf_symbol_leading_char                 ('_')
02013 #define elf_backend_always_size_sections \
02014   m32c_elf_always_size_sections
02015 #define elf_backend_finish_dynamic_sections \
02016   m32c_elf_finish_dynamic_sections
02017 
02018 #define elf_backend_can_gc_sections              1
02019 
02020 #define bfd_elf32_bfd_reloc_type_lookup          m32c_reloc_type_lookup
02021 #define bfd_elf32_bfd_reloc_name_lookup   m32c_reloc_name_lookup
02022 #define bfd_elf32_bfd_relax_section              m32c_elf_relax_section
02023 #define bfd_elf32_bfd_set_private_flags          m32c_elf_set_private_flags
02024 #define bfd_elf32_bfd_merge_private_bfd_data     m32c_elf_merge_private_bfd_data
02025 #define bfd_elf32_bfd_print_private_bfd_data     m32c_elf_print_private_bfd_data
02026 
02027 #include "elf32-target.h"