Back to index

cell-binutils  2.17cvs20070401
elf32-v850.c
Go to the documentation of this file.
00001 /* V850-specific support for 32-bit ELF
00002    Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
00003    2006, 2007 Free Software Foundation, Inc.
00004 
00005    This file is part of BFD, the Binary File Descriptor library.
00006 
00007    This program is free software; you can redistribute it and/or modify
00008    it under the terms of the GNU General Public License as published by
00009    the Free Software Foundation; either version 2 of the License, or
00010    (at your option) any later version.
00011 
00012    This program is distributed in the hope that it will be useful,
00013    but WITHOUT ANY WARRANTY; without even the implied warranty of
00014    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015    GNU General Public License for more details.
00016 
00017    You should have received a copy of the GNU General Public License
00018    along with this program; if not, write to the Free Software
00019    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
00020    MA 02110-1301, USA.  */
00021 
00022 /* XXX FIXME: This code is littered with 32bit int, 16bit short, 8bit char
00023    dependencies.  As is the gas & simulator code for the v850.  */
00024 
00025 #include "bfd.h"
00026 #include "sysdep.h"
00027 #include "bfdlink.h"
00028 #include "libbfd.h"
00029 #include "elf-bfd.h"
00030 #include "elf/v850.h"
00031 #include "libiberty.h"
00032 
00033 /* Sign-extend a 24-bit number.  */
00034 #define SEXT24(x)    ((((x) & 0xffffff) ^ 0x800000) - 0x800000)
00035 
00036 static reloc_howto_type v850_elf_howto_table[];
00037 
00038 /* Look through the relocs for a section during the first phase, and
00039    allocate space in the global offset table or procedure linkage
00040    table.  */
00041 
00042 static bfd_boolean
00043 v850_elf_check_relocs (bfd *abfd,
00044                      struct bfd_link_info *info,
00045                      asection *sec,
00046                      const Elf_Internal_Rela *relocs)
00047 {
00048   bfd_boolean ret = TRUE;
00049   bfd *dynobj;
00050   Elf_Internal_Shdr *symtab_hdr;
00051   struct elf_link_hash_entry **sym_hashes;
00052   const Elf_Internal_Rela *rel;
00053   const Elf_Internal_Rela *rel_end;
00054   asection *sreloc;
00055   enum v850_reloc_type r_type;
00056   int other = 0;
00057   const char *common = NULL;
00058 
00059   if (info->relocatable)
00060     return TRUE;
00061 
00062 #ifdef DEBUG
00063   _bfd_error_handler ("v850_elf_check_relocs called for section %A in %B",
00064                     sec, abfd);
00065 #endif
00066 
00067   dynobj = elf_hash_table (info)->dynobj;
00068   symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
00069   sym_hashes = elf_sym_hashes (abfd);
00070   sreloc = NULL;
00071 
00072   rel_end = relocs + sec->reloc_count;
00073   for (rel = relocs; rel < rel_end; rel++)
00074     {
00075       unsigned long r_symndx;
00076       struct elf_link_hash_entry *h;
00077 
00078       r_symndx = ELF32_R_SYM (rel->r_info);
00079       if (r_symndx < symtab_hdr->sh_info)
00080        h = NULL;
00081       else
00082        {
00083          h = sym_hashes[r_symndx - symtab_hdr->sh_info];
00084          while (h->root.type == bfd_link_hash_indirect
00085                || h->root.type == bfd_link_hash_warning)
00086            h = (struct elf_link_hash_entry *) h->root.u.i.link;
00087        }
00088 
00089       r_type = (enum v850_reloc_type) ELF32_R_TYPE (rel->r_info);
00090       switch (r_type)
00091        {
00092        default:
00093        case R_V850_NONE:
00094        case R_V850_9_PCREL:
00095        case R_V850_22_PCREL:
00096        case R_V850_HI16_S:
00097        case R_V850_HI16:
00098        case R_V850_LO16:
00099        case R_V850_LO16_SPLIT_OFFSET:
00100        case R_V850_ABS32:
00101        case R_V850_REL32:
00102        case R_V850_16:
00103        case R_V850_8:
00104        case R_V850_CALLT_6_7_OFFSET:
00105        case R_V850_CALLT_16_16_OFFSET:
00106          break;
00107 
00108         /* This relocation describes the C++ object vtable hierarchy.
00109            Reconstruct it for later use during GC.  */
00110         case R_V850_GNU_VTINHERIT:
00111           if (!bfd_elf_gc_record_vtinherit (abfd, sec, h, rel->r_offset))
00112             return FALSE;
00113           break;
00114 
00115         /* This relocation describes which C++ vtable entries
00116           are actually used.  Record for later use during GC.  */
00117         case R_V850_GNU_VTENTRY:
00118           if (!bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend))
00119             return FALSE;
00120           break;
00121 
00122        case R_V850_SDA_16_16_SPLIT_OFFSET:
00123        case R_V850_SDA_16_16_OFFSET:
00124        case R_V850_SDA_15_16_OFFSET:
00125          other = V850_OTHER_SDA;
00126          common = ".scommon";
00127          goto small_data_common;
00128 
00129        case R_V850_ZDA_16_16_SPLIT_OFFSET:
00130        case R_V850_ZDA_16_16_OFFSET:
00131        case R_V850_ZDA_15_16_OFFSET:
00132          other = V850_OTHER_ZDA;
00133          common = ".zcommon";
00134          goto small_data_common;
00135 
00136        case R_V850_TDA_4_5_OFFSET:
00137        case R_V850_TDA_4_4_OFFSET:
00138        case R_V850_TDA_6_8_OFFSET:
00139        case R_V850_TDA_7_8_OFFSET:
00140        case R_V850_TDA_7_7_OFFSET:
00141        case R_V850_TDA_16_16_OFFSET:
00142          other = V850_OTHER_TDA;
00143          common = ".tcommon";
00144          /* fall through */
00145 
00146 #define V850_OTHER_MASK (V850_OTHER_TDA | V850_OTHER_SDA | V850_OTHER_ZDA)
00147 
00148        small_data_common:
00149          if (h)
00150            {
00151              /* Flag which type of relocation was used.  */
00152              h->other |= other;
00153              if ((h->other & V850_OTHER_MASK) != (other & V850_OTHER_MASK)
00154                 && (h->other & V850_OTHER_ERROR) == 0)
00155               {
00156                 const char * msg;
00157                 static char  buff[200]; /* XXX */
00158 
00159                 switch (h->other & V850_OTHER_MASK)
00160                   {
00161                   default:
00162                     msg = _("Variable `%s' cannot occupy in multiple small data regions");
00163                     break;
00164                   case V850_OTHER_SDA | V850_OTHER_ZDA | V850_OTHER_TDA:
00165                     msg = _("Variable `%s' can only be in one of the small, zero, and tiny data regions");
00166                     break;
00167                   case V850_OTHER_SDA | V850_OTHER_ZDA:
00168                     msg = _("Variable `%s' cannot be in both small and zero data regions simultaneously");
00169                     break;
00170                   case V850_OTHER_SDA | V850_OTHER_TDA:
00171                     msg = _("Variable `%s' cannot be in both small and tiny data regions simultaneously");
00172                     break;
00173                   case V850_OTHER_ZDA | V850_OTHER_TDA:
00174                     msg = _("Variable `%s' cannot be in both zero and tiny data regions simultaneously");
00175                     break;
00176                   }
00177 
00178                 sprintf (buff, msg, h->root.root.string);
00179                 info->callbacks->warning (info, buff, h->root.root.string,
00180                                        abfd, h->root.u.def.section,
00181                                        (bfd_vma) 0);
00182 
00183                 bfd_set_error (bfd_error_bad_value);
00184                 h->other |= V850_OTHER_ERROR;
00185                 ret = FALSE;
00186               }
00187            }
00188 
00189          if (h && h->root.type == bfd_link_hash_common
00190              && h->root.u.c.p
00191              && !strcmp (bfd_get_section_name (abfd, h->root.u.c.p->section), "COMMON"))
00192            {
00193              asection * section;
00194 
00195              section = h->root.u.c.p->section = bfd_make_section_old_way (abfd, common);
00196              section->flags |= SEC_IS_COMMON;
00197            }
00198 
00199 #ifdef DEBUG
00200          fprintf (stderr, "v850_elf_check_relocs, found %s relocation for %s%s\n",
00201                  v850_elf_howto_table[ (int)r_type ].name,
00202                  (h && h->root.root.string) ? h->root.root.string : "<unknown>",
00203                  (h->root.type == bfd_link_hash_common) ? ", symbol is common" : "");
00204 #endif
00205          break;
00206        }
00207     }
00208 
00209   return ret;
00210 }
00211 
00212 /* In the old version, when an entry was checked out from the table,
00213    it was deleted.  This produced an error if the entry was needed
00214    more than once, as the second attempted retry failed.
00215 
00216    In the current version, the entry is not deleted, instead we set
00217    the field 'found' to TRUE.  If a second lookup matches the same
00218    entry, then we know that the hi16s reloc has already been updated
00219    and does not need to be updated a second time.
00220 
00221    TODO - TOFIX: If it is possible that we need to restore 2 different
00222    addresses from the same table entry, where the first generates an
00223    overflow, whilst the second do not, then this code will fail.  */
00224 
00225 typedef struct hi16s_location
00226 {
00227   bfd_vma                 addend;
00228   bfd_byte *              address;
00229   unsigned long           counter;
00230   bfd_boolean             found;
00231   struct hi16s_location * next;
00232 }
00233 hi16s_location;
00234 
00235 static hi16s_location * previous_hi16s;
00236 static hi16s_location * free_hi16s;
00237 static unsigned long    hi16s_counter;
00238 
00239 static void
00240 remember_hi16s_reloc (bfd *abfd, bfd_vma addend, bfd_byte *address)
00241 {
00242   hi16s_location * entry = NULL;
00243   bfd_size_type amt = sizeof (* free_hi16s);
00244 
00245   /* Find a free structure.  */
00246   if (free_hi16s == NULL)
00247     free_hi16s = bfd_zalloc (abfd, amt);
00248 
00249   entry      = free_hi16s;
00250   free_hi16s = free_hi16s->next;
00251 
00252   entry->addend  = addend;
00253   entry->address = address;
00254   entry->counter = hi16s_counter ++;
00255   entry->found   = FALSE;
00256   entry->next    = previous_hi16s;
00257   previous_hi16s = entry;
00258 
00259   /* Cope with wrap around of our counter.  */
00260   if (hi16s_counter == 0)
00261     {
00262       /* XXX: Assume that all counter entries differ only in their low 16 bits.  */
00263       for (entry = previous_hi16s; entry != NULL; entry = entry->next)
00264        entry->counter &= 0xffff;
00265 
00266       hi16s_counter = 0x10000;
00267     }
00268 }
00269 
00270 static bfd_byte *
00271 find_remembered_hi16s_reloc (bfd_vma addend, bfd_boolean *already_found)
00272 {
00273   hi16s_location *match = NULL;
00274   hi16s_location *entry;
00275   hi16s_location *previous = NULL;
00276   hi16s_location *prev;
00277   bfd_byte *addr;
00278 
00279   /* Search the table.  Record the most recent entry that matches.  */
00280   for (entry = previous_hi16s; entry; entry = entry->next)
00281     {
00282       if (entry->addend == addend
00283          && (match == NULL || match->counter < entry->counter))
00284        {
00285          previous = prev;
00286          match    = entry;
00287        }
00288 
00289       prev = entry;
00290     }
00291 
00292   if (match == NULL)
00293     return NULL;
00294 
00295   /* Extract the address.  */
00296   addr = match->address;
00297 
00298   /* Remember if this entry has already been used before.  */
00299   if (already_found)
00300     * already_found = match->found;
00301 
00302   /* Note that this entry has now been used.  */
00303   match->found = TRUE;
00304 
00305   return addr;
00306 }
00307 
00308 /* Calculate the final operand value for a R_V850_LO16 or
00309    R_V850_LO16_SPLIT_OFFSET.  *INSN is the current operand value and
00310    ADDEND is the sum of the relocation symbol and offset.  Store the
00311    operand value in *INSN and return true on success.
00312 
00313    The assembler has already done some of this: If the value stored in
00314    the instruction has its 15th bit set, (counting from zero) then the
00315    assembler will have added 1 to the value stored in the associated
00316    HI16S reloc.  So for example, these relocations:
00317 
00318        movhi hi( fred ), r0, r1
00319        movea lo( fred ), r1, r1
00320 
00321    will store 0 in the value fields for the MOVHI and MOVEA instructions
00322    and addend will be the address of fred, but for these instructions:
00323 
00324        movhi hi( fred + 0x123456), r0, r1
00325        movea lo( fred + 0x123456), r1, r1
00326 
00327    the value stored in the MOVHI instruction will be 0x12 and the value
00328    stored in the MOVEA instruction will be 0x3456.  If however the
00329    instructions were:
00330 
00331        movhi hi( fred + 0x10ffff), r0, r1
00332        movea lo( fred + 0x10ffff), r1, r1
00333 
00334    then the value stored in the MOVHI instruction would be 0x11 (not
00335    0x10) and the value stored in the MOVEA instruction would be 0xffff.
00336    Thus (assuming for the moment that the addend is 0), at run time the
00337    MOVHI instruction loads 0x110000 into r1, then the MOVEA instruction
00338    adds 0xffffffff (sign extension!) producing 0x10ffff.  Similarly if
00339    the instructions were:
00340 
00341        movhi hi( fred - 1), r0, r1
00342        movea lo( fred - 1), r1, r1
00343 
00344    then 0 is stored in the MOVHI instruction and -1 is stored in the
00345    MOVEA instruction.
00346 
00347    Overflow can occur if the addition of the value stored in the
00348    instruction plus the addend sets the 15th bit when before it was clear.
00349    This is because the 15th bit will be sign extended into the high part,
00350    thus reducing its value by one, but since the 15th bit was originally
00351    clear, the assembler will not have added 1 to the previous HI16S reloc
00352    to compensate for this effect.  For example:
00353 
00354       movhi hi( fred + 0x123456), r0, r1
00355       movea lo( fred + 0x123456), r1, r1
00356 
00357    The value stored in HI16S reloc is 0x12, the value stored in the LO16
00358    reloc is 0x3456.  If we assume that the address of fred is 0x00007000
00359    then the relocations become:
00360 
00361      HI16S: 0x0012 + (0x00007000 >> 16)    = 0x12
00362      LO16:  0x3456 + (0x00007000 & 0xffff) = 0xa456
00363 
00364    but when the instructions are executed, the MOVEA instruction's value
00365    is signed extended, so the sum becomes:
00366 
00367        0x00120000
00368       + 0xffffa456
00369       ------------
00370        0x0011a456    but 'fred + 0x123456' = 0x0012a456
00371 
00372    Note that if the 15th bit was set in the value stored in the LO16
00373    reloc, then we do not have to do anything:
00374 
00375       movhi hi( fred + 0x10ffff), r0, r1
00376       movea lo( fred + 0x10ffff), r1, r1
00377 
00378       HI16S:  0x0011 + (0x00007000 >> 16)    = 0x11
00379       LO16:   0xffff + (0x00007000 & 0xffff) = 0x6fff
00380 
00381        0x00110000
00382       + 0x00006fff
00383       ------------
00384        0x00116fff  = fred + 0x10ffff = 0x7000 + 0x10ffff
00385 
00386    Overflow can also occur if the computation carries into the 16th bit
00387    and it also results in the 15th bit having the same value as the 15th
00388    bit of the original value.   What happens is that the HI16S reloc
00389    will have already examined the 15th bit of the original value and
00390    added 1 to the high part if the bit is set.  This compensates for the
00391    sign extension of 15th bit of the result of the computation.  But now
00392    there is a carry into the 16th bit, and this has not been allowed for.
00393 
00394    So, for example if fred is at address 0xf000:
00395 
00396      movhi hi( fred + 0xffff), r0, r1    [bit 15 of the offset is set]
00397      movea lo( fred + 0xffff), r1, r1
00398 
00399      HI16S: 0x0001 + (0x0000f000 >> 16)    = 0x0001
00400      LO16:  0xffff + (0x0000f000 & 0xffff) = 0xefff   (carry into bit 16 is lost)
00401 
00402        0x00010000
00403      + 0xffffefff
00404      ------------
00405        0x0000efff   but 'fred + 0xffff' = 0x0001efff
00406 
00407    Similarly, if the 15th bit remains clear, but overflow occurs into
00408    the 16th bit then (assuming the address of fred is 0xf000):
00409 
00410      movhi hi( fred + 0x7000), r0, r1    [bit 15 of the offset is clear]
00411      movea lo( fred + 0x7000), r1, r1
00412 
00413      HI16S: 0x0000 + (0x0000f000 >> 16)    = 0x0000
00414      LO16:  0x7000 + (0x0000f000 & 0xffff) = 0x6fff  (carry into bit 16 is lost)
00415 
00416        0x00000000
00417      + 0x00006fff
00418      ------------
00419        0x00006fff   but 'fred + 0x7000' = 0x00016fff
00420 
00421    Note - there is no need to change anything if a carry occurs, and the
00422    15th bit changes its value from being set to being clear, as the HI16S
00423    reloc will have already added in 1 to the high part for us:
00424 
00425      movhi hi( fred + 0xffff), r0, r1     [bit 15 of the offset is set]
00426      movea lo( fred + 0xffff), r1, r1
00427 
00428      HI16S: 0x0001 + (0x00007000 >> 16)
00429      LO16:  0xffff + (0x00007000 & 0xffff) = 0x6fff  (carry into bit 16 is lost)
00430 
00431        0x00010000
00432      + 0x00006fff   (bit 15 not set, so the top half is zero)
00433      ------------
00434        0x00016fff   which is right (assuming that fred is at 0x7000)
00435 
00436    but if the 15th bit goes from being clear to being set, then we must
00437    once again handle overflow:
00438 
00439      movhi hi( fred + 0x7000), r0, r1     [bit 15 of the offset is clear]
00440      movea lo( fred + 0x7000), r1, r1
00441 
00442      HI16S: 0x0000 + (0x0000ffff >> 16)
00443      LO16:  0x7000 + (0x0000ffff & 0xffff) = 0x6fff  (carry into bit 16)
00444 
00445        0x00000000
00446      + 0x00006fff   (bit 15 not set, so the top half is zero)
00447      ------------
00448        0x00006fff   which is wrong (assuming that fred is at 0xffff).  */
00449 
00450 static bfd_boolean
00451 v850_elf_perform_lo16_relocation (bfd *abfd, unsigned long *insn,
00452                               unsigned long addend)
00453 {
00454 #define BIT15_SET(x) ((x) & 0x8000)
00455 #define OVERFLOWS(a,i) ((((a) & 0xffff) + (i)) > 0xffff)
00456 
00457   if ((BIT15_SET (*insn + addend) && ! BIT15_SET (addend))
00458       || (OVERFLOWS (addend, *insn)
00459          && ((! BIT15_SET (*insn)) || (BIT15_SET (addend)))))
00460     {
00461       bfd_boolean already_updated;
00462       bfd_byte *hi16s_address = find_remembered_hi16s_reloc
00463        (addend, & already_updated);
00464 
00465       /* Amend the matching HI16_S relocation.  */
00466       if (hi16s_address != NULL)
00467        {
00468          if (! already_updated)
00469            {
00470              unsigned long hi_insn = bfd_get_16 (abfd, hi16s_address);
00471              hi_insn += 1;
00472              bfd_put_16 (abfd, hi_insn, hi16s_address);
00473            }
00474        }
00475       else
00476        {
00477          fprintf (stderr, _("FAILED to find previous HI16 reloc\n"));
00478          return FALSE;
00479        }
00480     }
00481 #undef OVERFLOWS
00482 #undef BIT15_SET
00483 
00484   /* Do not complain if value has top bit set, as this has been
00485      anticipated.  */
00486   *insn = (*insn + addend) & 0xffff;
00487   return TRUE;
00488 }
00489 
00490 /* FIXME:  The code here probably ought to be removed and the code in reloc.c
00491    allowed to do its stuff instead.  At least for most of the relocs, anyway.  */
00492 
00493 static bfd_reloc_status_type
00494 v850_elf_perform_relocation (bfd *abfd,
00495                           unsigned int r_type,
00496                           bfd_vma addend,
00497                           bfd_byte *address)
00498 {
00499   unsigned long insn;
00500   unsigned long result;
00501   bfd_signed_vma saddend = (bfd_signed_vma) addend;
00502 
00503   switch (r_type)
00504     {
00505     default:
00506       return bfd_reloc_notsupported;
00507 
00508     case R_V850_REL32:
00509     case R_V850_ABS32:
00510       bfd_put_32 (abfd, addend, address);
00511       return bfd_reloc_ok;
00512 
00513     case R_V850_22_PCREL:
00514       if (saddend > 0x1fffff || saddend < -0x200000)
00515        return bfd_reloc_overflow;
00516 
00517       if ((addend % 2) != 0)
00518        return bfd_reloc_dangerous;
00519 
00520       insn  = bfd_get_32 (abfd, address);
00521       insn &= ~0xfffe003f;
00522       insn |= (((addend & 0xfffe) << 16) | ((addend & 0x3f0000) >> 16));
00523       bfd_put_32 (abfd, (bfd_vma) insn, address);
00524       return bfd_reloc_ok;
00525 
00526     case R_V850_9_PCREL:
00527       if (saddend > 0xff || saddend < -0x100)
00528        return bfd_reloc_overflow;
00529 
00530       if ((addend % 2) != 0)
00531        return bfd_reloc_dangerous;
00532 
00533       insn  = bfd_get_16 (abfd, address);
00534       insn &= ~ 0xf870;
00535       insn |= ((addend & 0x1f0) << 7) | ((addend & 0x0e) << 3);
00536       break;
00537 
00538     case R_V850_HI16:
00539       addend += (bfd_get_16 (abfd, address) << 16);
00540       addend = (addend >> 16);
00541       insn = addend;
00542       break;
00543 
00544     case R_V850_HI16_S:
00545       /* Remember where this relocation took place.  */
00546       remember_hi16s_reloc (abfd, addend, address);
00547 
00548       addend += (bfd_get_16 (abfd, address) << 16);
00549       addend = (addend >> 16) + ((addend & 0x8000) != 0);
00550 
00551       /* This relocation cannot overflow.  */
00552       if (addend > 0x7fff)
00553        addend = 0;
00554 
00555       insn = addend;
00556       break;
00557 
00558     case R_V850_LO16:
00559       insn = bfd_get_16 (abfd, address);
00560       if (! v850_elf_perform_lo16_relocation (abfd, &insn, addend))
00561        return bfd_reloc_overflow;
00562       break;
00563 
00564     case R_V850_8:
00565       addend += (char) bfd_get_8 (abfd, address);
00566 
00567       saddend = (bfd_signed_vma) addend;
00568 
00569       if (saddend > 0x7f || saddend < -0x80)
00570        return bfd_reloc_overflow;
00571 
00572       bfd_put_8 (abfd, addend, address);
00573       return bfd_reloc_ok;
00574 
00575     case R_V850_CALLT_16_16_OFFSET:
00576       addend += bfd_get_16 (abfd, address);
00577 
00578       saddend = (bfd_signed_vma) addend;
00579 
00580       if (saddend > 0xffff || saddend < 0)
00581        return bfd_reloc_overflow;
00582 
00583       insn = addend;
00584       break;
00585 
00586     case R_V850_16:
00587     case R_V850_SDA_16_16_OFFSET:
00588     case R_V850_ZDA_16_16_OFFSET:
00589     case R_V850_TDA_16_16_OFFSET:
00590       addend += bfd_get_16 (abfd, address);
00591 
00592       saddend = (bfd_signed_vma) addend;
00593 
00594       if (saddend > 0x7fff || saddend < -0x8000)
00595        return bfd_reloc_overflow;
00596 
00597       insn = addend;
00598       break;
00599 
00600     case R_V850_SDA_15_16_OFFSET:
00601     case R_V850_ZDA_15_16_OFFSET:
00602       insn = bfd_get_16 (abfd, address);
00603       addend += (insn & 0xfffe);
00604 
00605       saddend = (bfd_signed_vma) addend;
00606 
00607       if (saddend > 0x7ffe || saddend < -0x8000)
00608        return bfd_reloc_overflow;
00609 
00610       if (addend & 1)
00611         return bfd_reloc_dangerous;
00612 
00613       insn = (addend &~ (bfd_vma) 1) | (insn & 1);
00614       break;
00615 
00616     case R_V850_TDA_6_8_OFFSET:
00617       insn = bfd_get_16 (abfd, address);
00618       addend += ((insn & 0x7e) << 1);
00619 
00620       saddend = (bfd_signed_vma) addend;
00621 
00622       if (saddend > 0xfc || saddend < 0)
00623        return bfd_reloc_overflow;
00624 
00625       if (addend & 3)
00626        return bfd_reloc_dangerous;
00627 
00628       insn &= 0xff81;
00629       insn |= (addend >> 1);
00630       break;
00631 
00632     case R_V850_TDA_7_8_OFFSET:
00633       insn = bfd_get_16 (abfd, address);
00634       addend += ((insn & 0x7f) << 1);
00635 
00636       saddend = (bfd_signed_vma) addend;
00637 
00638       if (saddend > 0xfe || saddend < 0)
00639        return bfd_reloc_overflow;
00640 
00641       if (addend & 1)
00642        return bfd_reloc_dangerous;
00643 
00644       insn &= 0xff80;
00645       insn |= (addend >> 1);
00646       break;
00647 
00648     case R_V850_TDA_7_7_OFFSET:
00649       insn = bfd_get_16 (abfd, address);
00650       addend += insn & 0x7f;
00651 
00652       saddend = (bfd_signed_vma) addend;
00653 
00654       if (saddend > 0x7f || saddend < 0)
00655        return bfd_reloc_overflow;
00656 
00657       insn &= 0xff80;
00658       insn |= addend;
00659       break;
00660 
00661     case R_V850_TDA_4_5_OFFSET:
00662       insn = bfd_get_16 (abfd, address);
00663       addend += ((insn & 0xf) << 1);
00664 
00665       saddend = (bfd_signed_vma) addend;
00666 
00667       if (saddend > 0x1e || saddend < 0)
00668        return bfd_reloc_overflow;
00669 
00670       if (addend & 1)
00671        return bfd_reloc_dangerous;
00672 
00673       insn &= 0xfff0;
00674       insn |= (addend >> 1);
00675       break;
00676 
00677     case R_V850_TDA_4_4_OFFSET:
00678       insn = bfd_get_16 (abfd, address);
00679       addend += insn & 0xf;
00680 
00681       saddend = (bfd_signed_vma) addend;
00682 
00683       if (saddend > 0xf || saddend < 0)
00684        return bfd_reloc_overflow;
00685 
00686       insn &= 0xfff0;
00687       insn |= addend;
00688       break;
00689 
00690     case R_V850_LO16_SPLIT_OFFSET:
00691       insn = bfd_get_32 (abfd, address);
00692       result = ((insn & 0xfffe0000) >> 16) | ((insn & 0x20) >> 5);
00693       if (! v850_elf_perform_lo16_relocation (abfd, &result, addend))
00694        return bfd_reloc_overflow;
00695       insn = (((result << 16) & 0xfffe0000)
00696              | ((result << 5) & 0x20)
00697              | (insn & ~0xfffe0020));
00698       bfd_put_32 (abfd, insn, address);
00699       return bfd_reloc_ok;
00700 
00701     case R_V850_ZDA_16_16_SPLIT_OFFSET:
00702     case R_V850_SDA_16_16_SPLIT_OFFSET:
00703       insn = bfd_get_32 (abfd, address);
00704       addend += ((insn & 0xfffe0000) >> 16) + ((insn & 0x20) >> 5);
00705 
00706       saddend = (bfd_signed_vma) addend;
00707 
00708       if (saddend > 0x7fff || saddend < -0x8000)
00709        return bfd_reloc_overflow;
00710 
00711       insn &= 0x0001ffdf;
00712       insn |= (addend & 1) << 5;
00713       insn |= (addend &~ (bfd_vma) 1) << 16;
00714 
00715       bfd_put_32 (abfd, (bfd_vma) insn, address);
00716       return bfd_reloc_ok;
00717 
00718     case R_V850_CALLT_6_7_OFFSET:
00719       insn = bfd_get_16 (abfd, address);
00720       addend += ((insn & 0x3f) << 1);
00721 
00722       saddend = (bfd_signed_vma) addend;
00723 
00724       if (saddend > 0x7e || saddend < 0)
00725        return bfd_reloc_overflow;
00726 
00727       if (addend & 1)
00728        return bfd_reloc_dangerous;
00729 
00730       insn &= 0xff80;
00731       insn |= (addend >> 1);
00732       break;
00733 
00734     case R_V850_GNU_VTINHERIT:
00735     case R_V850_GNU_VTENTRY:
00736       return bfd_reloc_ok;
00737 
00738     }
00739 
00740   bfd_put_16 (abfd, (bfd_vma) insn, address);
00741   return bfd_reloc_ok;
00742 }
00743 
00744 /* Insert the addend into the instruction.  */
00745 
00746 static bfd_reloc_status_type
00747 v850_elf_reloc (bfd *abfd ATTRIBUTE_UNUSED,
00748               arelent *reloc,
00749               asymbol *symbol,
00750               void * data ATTRIBUTE_UNUSED,
00751               asection *isection,
00752               bfd *obfd,
00753               char **err ATTRIBUTE_UNUSED)
00754 {
00755   long relocation;
00756 
00757   /* If there is an output BFD,
00758      and the symbol is not a section name (which is only defined at final link time),
00759      and either we are not putting the addend into the instruction
00760       or the addend is zero, so there is nothing to add into the instruction
00761      then just fixup the address and return.  */
00762   if (obfd != NULL
00763       && (symbol->flags & BSF_SECTION_SYM) == 0
00764       && (! reloc->howto->partial_inplace
00765          || reloc->addend == 0))
00766     {
00767       reloc->address += isection->output_offset;
00768       return bfd_reloc_ok;
00769     }
00770 
00771   /* Catch relocs involving undefined symbols.  */
00772   if (bfd_is_und_section (symbol->section)
00773       && (symbol->flags & BSF_WEAK) == 0
00774       && obfd == NULL)
00775     return bfd_reloc_undefined;
00776 
00777   /* We handle final linking of some relocs ourselves.  */
00778 
00779   /* Is the address of the relocation really within the section?  */
00780   if (reloc->address > bfd_get_section_limit (abfd, isection))
00781     return bfd_reloc_outofrange;
00782 
00783   /* Work out which section the relocation is targeted at and the
00784      initial relocation command value.  */
00785 
00786   if (reloc->howto->pc_relative)
00787     return bfd_reloc_ok;
00788 
00789   /* Get symbol value.  (Common symbols are special.)  */
00790   if (bfd_is_com_section (symbol->section))
00791     relocation = 0;
00792   else
00793     relocation = symbol->value;
00794 
00795   /* Convert input-section-relative symbol value to absolute + addend.  */
00796   relocation += symbol->section->output_section->vma;
00797   relocation += symbol->section->output_offset;
00798   relocation += reloc->addend;
00799 
00800   reloc->addend = relocation;
00801   return bfd_reloc_ok;
00802 }
00803 
00804 /* This function is used for relocs which are only used
00805    for relaxing, which the linker should otherwise ignore.  */
00806 
00807 static bfd_reloc_status_type
00808 v850_elf_ignore_reloc (bfd *abfd ATTRIBUTE_UNUSED,
00809                      arelent *reloc_entry,
00810                      asymbol *symbol ATTRIBUTE_UNUSED,
00811                      void * data ATTRIBUTE_UNUSED,
00812                      asection *input_section,
00813                      bfd *output_bfd,
00814                      char **error_message ATTRIBUTE_UNUSED)
00815 {
00816   if (output_bfd != NULL)
00817     reloc_entry->address += input_section->output_offset;
00818 
00819   return bfd_reloc_ok;
00820 }
00821 /* Note: It is REQUIRED that the 'type' value of each entry
00822    in this array match the index of the entry in the array.  */
00823 static reloc_howto_type v850_elf_howto_table[] =
00824 {
00825   /* This reloc does nothing.  */
00826   HOWTO (R_V850_NONE,                     /* Type.  */
00827         0,                         /* Rightshift.  */
00828         2,                         /* Size (0 = byte, 1 = short, 2 = long).  */
00829         32,                        /* Bitsize.  */
00830         FALSE,                            /* PC_relative.  */
00831         0,                         /* Bitpos.  */
00832         complain_overflow_bitfield,       /* Complain_on_overflow.  */
00833         bfd_elf_generic_reloc,            /* Special_function.  */
00834         "R_V850_NONE",                    /* Name.  */
00835         FALSE,                            /* Partial_inplace.  */
00836         0,                         /* Src_mask.  */
00837         0,                         /* Dst_mask.  */
00838         FALSE),                    /* PCrel_offset.  */
00839 
00840   /* A PC relative 9 bit branch.  */
00841   HOWTO (R_V850_9_PCREL,           /* Type.  */
00842         2,                         /* Rightshift.  */
00843         2,                         /* Size (0 = byte, 1 = short, 2 = long).  */
00844         26,                        /* Bitsize.  */
00845         TRUE,                      /* PC_relative.  */
00846         0,                         /* Bitpos.  */
00847         complain_overflow_bitfield,       /* Complain_on_overflow.  */
00848         v850_elf_reloc,            /* Special_function.  */
00849         "R_V850_9_PCREL",          /* Name.  */
00850         FALSE,                            /* Partial_inplace.  */
00851         0x00ffffff,                /* Src_mask.  */
00852         0x00ffffff,                /* Dst_mask.  */
00853         TRUE),                            /* PCrel_offset.  */
00854 
00855   /* A PC relative 22 bit branch.  */
00856   HOWTO (R_V850_22_PCREL,          /* Type.  */
00857         2,                         /* Rightshift.  */
00858         2,                         /* Size (0 = byte, 1 = short, 2 = long).  */
00859         22,                        /* Bitsize.  */
00860         TRUE,                      /* PC_relative.  */
00861         7,                         /* Bitpos.  */
00862         complain_overflow_signed,  /* Complain_on_overflow.  */
00863         v850_elf_reloc,            /* Special_function.  */
00864         "R_V850_22_PCREL",         /* Name.  */
00865         FALSE,                            /* Partial_inplace.  */
00866         0x07ffff80,                /* Src_mask.  */
00867         0x07ffff80,                /* Dst_mask.  */
00868         TRUE),                            /* PCrel_offset.  */
00869 
00870   /* High 16 bits of symbol value.  */
00871   HOWTO (R_V850_HI16_S,                   /* Type.  */
00872         0,                         /* Rightshift.  */
00873         1,                         /* Size (0 = byte, 1 = short, 2 = long).  */
00874         16,                        /* Bitsize.  */
00875         FALSE,                            /* PC_relative.  */
00876         0,                         /* Bitpos.  */
00877         complain_overflow_dont,    /* Complain_on_overflow.  */
00878         v850_elf_reloc,            /* Special_function.  */
00879         "R_V850_HI16_S",           /* Name.  */
00880         FALSE,                            /* Partial_inplace.  */
00881         0xffff,                    /* Src_mask.  */
00882         0xffff,                    /* Dst_mask.  */
00883         FALSE),                    /* PCrel_offset.  */
00884 
00885   /* High 16 bits of symbol value.  */
00886   HOWTO (R_V850_HI16,                     /* Type.  */
00887         0,                         /* Rightshift.  */
00888         1,                         /* Size (0 = byte, 1 = short, 2 = long).  */
00889         16,                        /* Bitsize.  */
00890         FALSE,                            /* PC_relative.  */
00891         0,                         /* Bitpos.  */
00892         complain_overflow_dont,    /* Complain_on_overflow.  */
00893         v850_elf_reloc,            /* Special_function.  */
00894         "R_V850_HI16",                    /* Name.  */
00895         FALSE,                            /* Partial_inplace.  */
00896         0xffff,                    /* Src_mask.  */
00897         0xffff,                    /* Dst_mask.  */
00898         FALSE),                    /* PCrel_offset.  */
00899 
00900   /* Low 16 bits of symbol value.  */
00901   HOWTO (R_V850_LO16,                     /* Type.  */
00902         0,                         /* Rightshift.  */
00903         1,                         /* Size (0 = byte, 1 = short, 2 = long).  */
00904         16,                        /* Bitsize.  */
00905         FALSE,                            /* PC_relative.  */
00906         0,                         /* Bitpos.  */
00907         complain_overflow_dont,    /* Complain_on_overflow.  */
00908         v850_elf_reloc,            /* Special_function.  */
00909         "R_V850_LO16",                    /* Name.  */
00910         FALSE,                            /* Partial_inplace.  */
00911         0xffff,                    /* Src_mask.  */
00912         0xffff,                    /* Dst_mask.  */
00913         FALSE),                    /* PCrel_offset.  */
00914 
00915   /* Simple 32bit reloc.  */
00916   HOWTO (R_V850_ABS32,                    /* Type.  */
00917         0,                         /* Rightshift.  */
00918         2,                         /* Size (0 = byte, 1 = short, 2 = long).  */
00919         32,                        /* Bitsize.  */
00920         FALSE,                            /* PC_relative.  */
00921         0,                         /* Bitpos.  */
00922         complain_overflow_dont,    /* Complain_on_overflow.  */
00923         v850_elf_reloc,            /* Special_function.  */
00924         "R_V850_ABS32",            /* Name.  */
00925         FALSE,                            /* Partial_inplace.  */
00926         0xffffffff,                /* Src_mask.  */
00927         0xffffffff,                /* Dst_mask.  */
00928         FALSE),                    /* PCrel_offset.  */
00929 
00930   /* Simple 16bit reloc.  */
00931   HOWTO (R_V850_16,                /* Type.  */
00932         0,                         /* Rightshift.  */
00933         1,                         /* Size (0 = byte, 1 = short, 2 = long).  */
00934         16,                        /* Bitsize.  */
00935         FALSE,                            /* PC_relative.  */
00936         0,                         /* Bitpos.  */
00937         complain_overflow_dont,    /* Complain_on_overflow.  */
00938         bfd_elf_generic_reloc,            /* Special_function.  */
00939         "R_V850_16",               /* Name.  */
00940         FALSE,                            /* Partial_inplace.  */
00941         0xffff,                    /* Src_mask.  */
00942         0xffff,                    /* Dst_mask.  */
00943         FALSE),                    /* PCrel_offset.  */
00944 
00945   /* Simple 8bit reloc.      */
00946   HOWTO (R_V850_8,                 /* Type.  */
00947         0,                         /* Rightshift.  */
00948         0,                         /* Size (0 = byte, 1 = short, 2 = long).  */
00949         8,                         /* Bitsize.  */
00950         FALSE,                            /* PC_relative.  */
00951         0,                         /* Bitpos.  */
00952         complain_overflow_dont,    /* Complain_on_overflow.  */
00953         bfd_elf_generic_reloc,            /* Special_function.  */
00954         "R_V850_8",                /* Name.  */
00955         FALSE,                            /* Partial_inplace.  */
00956         0xff,                      /* Src_mask.  */
00957         0xff,                      /* Dst_mask.  */
00958         FALSE),                    /* PCrel_offset.  */
00959 
00960   /* 16 bit offset from the short data area pointer.  */
00961   HOWTO (R_V850_SDA_16_16_OFFSET,  /* Type.  */
00962         0,                         /* Rightshift.  */
00963         1,                         /* Size (0 = byte, 1 = short, 2 = long).  */
00964         16,                        /* Bitsize.  */
00965         FALSE,                            /* PC_relative.  */
00966         0,                         /* Bitpos.  */
00967         complain_overflow_dont,    /* Complain_on_overflow.  */
00968         v850_elf_reloc,            /* Special_function.  */
00969         "R_V850_SDA_16_16_OFFSET", /* Name.  */
00970         FALSE,                            /* Partial_inplace.  */
00971         0xffff,                    /* Src_mask.  */
00972         0xffff,                    /* Dst_mask.  */
00973         FALSE),                    /* PCrel_offset.  */
00974 
00975   /* 15 bit offset from the short data area pointer.  */
00976   HOWTO (R_V850_SDA_15_16_OFFSET,  /* Type.  */
00977         1,                         /* Rightshift.  */
00978         1,                         /* Size (0 = byte, 1 = short, 2 = long).  */
00979         16,                        /* Bitsize.  */
00980         FALSE,                            /* PC_relative.  */
00981         1,                         /* Bitpos.  */
00982         complain_overflow_dont,    /* Complain_on_overflow.  */
00983         v850_elf_reloc,            /* Special_function.  */
00984         "R_V850_SDA_15_16_OFFSET", /* Name.  */
00985         FALSE,                            /* Partial_inplace.  */
00986         0xfffe,                    /* Src_mask.  */
00987         0xfffe,                    /* Dst_mask.  */
00988         FALSE),                    /* PCrel_offset.  */
00989 
00990   /* 16 bit offset from the zero data area pointer.  */
00991   HOWTO (R_V850_ZDA_16_16_OFFSET,  /* Type.  */
00992         0,                         /* Rightshift.  */
00993         1,                         /* Size (0 = byte, 1 = short, 2 = long).  */
00994         16,                        /* Bitsize.  */
00995         FALSE,                            /* PC_relative.  */
00996         0,                         /* Bitpos.  */
00997         complain_overflow_dont,    /* Complain_on_overflow.  */
00998         v850_elf_reloc,            /* Special_function.  */
00999         "R_V850_ZDA_16_16_OFFSET", /* Name.  */
01000         FALSE,                            /* Partial_inplace.  */
01001         0xffff,                    /* Src_mask.  */
01002         0xffff,                    /* Dst_mask.  */
01003         FALSE),                    /* PCrel_offset.  */
01004 
01005   /* 15 bit offset from the zero data area pointer.  */
01006   HOWTO (R_V850_ZDA_15_16_OFFSET,  /* Type.  */
01007         1,                         /* Rightshift.  */
01008         1,                         /* Size (0 = byte, 1 = short, 2 = long).  */
01009         16,                        /* Bitsize.  */
01010         FALSE,                            /* PC_relative.  */
01011         1,                         /* Bitpos.  */
01012         complain_overflow_dont,    /* Complain_on_overflow.  */
01013         v850_elf_reloc,            /* Special_function.  */
01014         "R_V850_ZDA_15_16_OFFSET", /* Name.  */
01015         FALSE,                            /* Partial_inplace.  */
01016         0xfffe,                    /* Src_mask.  */
01017         0xfffe,                    /* Dst_mask.  */
01018         FALSE),                    /* PCrel_offset.  */
01019 
01020   /* 6 bit offset from the tiny data area pointer.  */
01021   HOWTO (R_V850_TDA_6_8_OFFSET,           /* Type.  */
01022         2,                         /* Rightshift.  */
01023         1,                         /* Size (0 = byte, 1 = short, 2 = long).  */
01024         8,                         /* Bitsize.  */
01025         FALSE,                            /* PC_relative.  */
01026         1,                         /* Bitpos.  */
01027         complain_overflow_dont,    /* Complain_on_overflow.  */
01028         v850_elf_reloc,            /* Special_function.  */
01029         "R_V850_TDA_6_8_OFFSET",   /* Name.  */
01030         FALSE,                            /* Partial_inplace.  */
01031         0x7e,                      /* Src_mask.  */
01032         0x7e,                      /* Dst_mask.  */
01033         FALSE),                    /* PCrel_offset.  */
01034 
01035   /* 8 bit offset from the tiny data area pointer.  */
01036   HOWTO (R_V850_TDA_7_8_OFFSET,           /* Type.  */
01037         1,                         /* Rightshift.  */
01038         1,                         /* Size (0 = byte, 1 = short, 2 = long).  */
01039         8,                         /* Bitsize.  */
01040         FALSE,                            /* PC_relative.  */
01041         0,                         /* Bitpos.  */
01042         complain_overflow_dont,    /* Complain_on_overflow.  */
01043         v850_elf_reloc,            /* Special_function.  */
01044         "R_V850_TDA_7_8_OFFSET",   /* Name.  */
01045         FALSE,                            /* Partial_inplace.  */
01046         0x7f,                      /* Src_mask.  */
01047         0x7f,                      /* Dst_mask.  */
01048         FALSE),                    /* PCrel_offset.  */
01049 
01050   /* 7 bit offset from the tiny data area pointer.  */
01051   HOWTO (R_V850_TDA_7_7_OFFSET,           /* Type.  */
01052         0,                         /* Rightshift.  */
01053         1,                         /* Size (0 = byte, 1 = short, 2 = long).  */
01054         7,                         /* Bitsize.  */
01055         FALSE,                            /* PC_relative.  */
01056         0,                         /* Bitpos.  */
01057         complain_overflow_dont,    /* Complain_on_overflow.  */
01058         v850_elf_reloc,            /* Special_function.  */
01059         "R_V850_TDA_7_7_OFFSET",   /* Name.  */
01060         FALSE,                            /* Partial_inplace.  */
01061         0x7f,                      /* Src_mask.  */
01062         0x7f,                      /* Dst_mask.  */
01063         FALSE),                    /* PCrel_offset.  */
01064 
01065   /* 16 bit offset from the tiny data area pointer!  */
01066   HOWTO (R_V850_TDA_16_16_OFFSET,  /* Type.  */
01067         0,                         /* Rightshift.  */
01068         1,                         /* Size (0 = byte, 1 = short, 2 = long).  */
01069         16,                        /* Bitsize.  */
01070         FALSE,                            /* PC_relative.  */
01071         0,                         /* Bitpos.  */
01072         complain_overflow_dont,    /* Complain_on_overflow.  */
01073         v850_elf_reloc,            /* Special_function.  */
01074         "R_V850_TDA_16_16_OFFSET", /* Name.  */
01075         FALSE,                            /* Partial_inplace.  */
01076         0xffff,                    /* Src_mask.  */
01077         0xfff,                            /* Dst_mask.  */
01078         FALSE),                    /* PCrel_offset.  */
01079 
01080   /* 5 bit offset from the tiny data area pointer.  */
01081   HOWTO (R_V850_TDA_4_5_OFFSET,           /* Type.  */
01082         1,                         /* Rightshift.  */
01083         1,                         /* Size (0 = byte, 1 = short, 2 = long).  */
01084         5,                         /* Bitsize.  */
01085         FALSE,                            /* PC_relative.  */
01086         0,                         /* Bitpos.  */
01087         complain_overflow_dont,    /* Complain_on_overflow.  */
01088         v850_elf_reloc,            /* Special_function.  */
01089         "R_V850_TDA_4_5_OFFSET",   /* Name.  */
01090         FALSE,                            /* Partial_inplace.  */
01091         0x0f,                      /* Src_mask.  */
01092         0x0f,                      /* Dst_mask.  */
01093         FALSE),                    /* PCrel_offset.  */
01094 
01095   /* 4 bit offset from the tiny data area pointer.  */
01096   HOWTO (R_V850_TDA_4_4_OFFSET,           /* Type.  */
01097         0,                         /* Rightshift.  */
01098         1,                         /* Size (0 = byte, 1 = short, 2 = long).  */
01099         4,                         /* Bitsize.  */
01100         FALSE,                            /* PC_relative.  */
01101         0,                         /* Bitpos.  */
01102         complain_overflow_dont,    /* Complain_on_overflow.  */
01103         v850_elf_reloc,            /* Special_function.  */
01104         "R_V850_TDA_4_4_OFFSET",   /* Name.  */
01105         FALSE,                            /* Partial_inplace.  */
01106         0x0f,                      /* Src_mask.  */
01107         0x0f,                      /* Dst_mask.  */
01108         FALSE),                    /* PCrel_offset.  */
01109 
01110   /* 16 bit offset from the short data area pointer.  */
01111   HOWTO (R_V850_SDA_16_16_SPLIT_OFFSET,   /* Type.  */
01112         0,                         /* Rightshift.  */
01113         2,                         /* Size (0 = byte, 1 = short, 2 = long).  */
01114         16,                        /* Bitsize.  */
01115         FALSE,                            /* PC_relative.  */
01116         0,                         /* Bitpos.  */
01117         complain_overflow_dont,    /* Complain_on_overflow.  */
01118         v850_elf_reloc,            /* Special_function.  */
01119         "R_V850_SDA_16_16_SPLIT_OFFSET",/* Name.  */
01120         FALSE,                            /* Partial_inplace.  */
01121         0xfffe0020,                /* Src_mask.  */
01122         0xfffe0020,                /* Dst_mask.  */
01123         FALSE),                    /* PCrel_offset.  */
01124 
01125   /* 16 bit offset from the zero data area pointer.  */
01126   HOWTO (R_V850_ZDA_16_16_SPLIT_OFFSET,   /* Type.  */
01127         0,                         /* Rightshift.  */
01128         2,                         /* Size (0 = byte, 1 = short, 2 = long).  */
01129         16,                        /* Bitsize.  */
01130         FALSE,                            /* PC_relative.  */
01131         0,                         /* Bitpos.  */
01132         complain_overflow_dont,    /* Complain_on_overflow.  */
01133         v850_elf_reloc,            /* Special_function.  */
01134         "R_V850_ZDA_16_16_SPLIT_OFFSET",/* Name.  */
01135         FALSE,                            /* Partial_inplace.  */
01136         0xfffe0020,                /* Src_mask.  */
01137         0xfffe0020,                /* Dst_mask.  */
01138         FALSE),                    /* PCrel_offset.  */
01139 
01140   /* 6 bit offset from the call table base pointer.  */
01141   HOWTO (R_V850_CALLT_6_7_OFFSET,  /* Type.  */
01142         0,                         /* Rightshift.  */
01143         1,                         /* Size (0 = byte, 1 = short, 2 = long).  */
01144         7,                         /* Bitsize.  */
01145         FALSE,                            /* PC_relative.  */
01146         0,                         /* Bitpos.  */
01147         complain_overflow_dont,    /* Complain_on_overflow.  */
01148         v850_elf_reloc,            /* Special_function.  */
01149         "R_V850_CALLT_6_7_OFFSET", /* Name.  */
01150         FALSE,                            /* Partial_inplace.  */
01151         0x3f,                      /* Src_mask.  */
01152         0x3f,                      /* Dst_mask.  */
01153         FALSE),                    /* PCrel_offset.  */
01154 
01155   /* 16 bit offset from the call table base pointer.  */
01156   HOWTO (R_V850_CALLT_16_16_OFFSET,       /* Type.  */
01157         0,                         /* Rightshift.  */
01158         1,                         /* Size (0 = byte, 1 = short, 2 = long).  */
01159         16,                        /* Bitsize.  */
01160         FALSE,                            /* PC_relative.  */
01161         0,                         /* Bitpos.  */
01162         complain_overflow_dont,    /* Complain_on_overflow.  */
01163         v850_elf_reloc,            /* Special_function.  */
01164         "R_V850_CALLT_16_16_OFFSET",      /* Name.  */
01165         FALSE,                            /* Partial_inplace.  */
01166         0xffff,                    /* Src_mask.  */
01167         0xffff,                    /* Dst_mask.  */
01168         FALSE),                    /* PCrel_offset.  */
01169 
01170   /* GNU extension to record C++ vtable hierarchy */
01171   HOWTO (R_V850_GNU_VTINHERIT, /* Type.  */
01172          0,                     /* Rightshift.  */
01173          2,                     /* Size (0 = byte, 1 = short, 2 = long).  */
01174          0,                     /* Bitsize.  */
01175          FALSE,                 /* PC_relative.  */
01176          0,                     /* Bitpos.  */
01177          complain_overflow_dont, /* Complain_on_overflow.  */
01178          NULL,                  /* Special_function.  */
01179          "R_V850_GNU_VTINHERIT", /* Name.  */
01180          FALSE,                 /* Partial_inplace.  */
01181          0,                     /* Src_mask.  */
01182          0,                     /* Dst_mask.  */
01183          FALSE),                /* PCrel_offset.  */
01184 
01185   /* GNU extension to record C++ vtable member usage */
01186   HOWTO (R_V850_GNU_VTENTRY,     /* Type.  */
01187          0,                     /* Rightshift.  */
01188          2,                     /* Size (0 = byte, 1 = short, 2 = long).  */
01189          0,                     /* Bitsize.  */
01190          FALSE,                 /* PC_relative.  */
01191          0,                     /* Bitpos.  */
01192          complain_overflow_dont, /* Complain_on_overflow.  */
01193          _bfd_elf_rel_vtable_reloc_fn,  /* Special_function.  */
01194          "R_V850_GNU_VTENTRY",   /* Name.  */
01195          FALSE,                 /* Partial_inplace.  */
01196          0,                     /* Src_mask.  */
01197          0,                     /* Dst_mask.  */
01198          FALSE),                /* PCrel_offset.  */
01199 
01200   /* Indicates a .longcall pseudo-op.  The compiler will generate a .longcall
01201      pseudo-op when it finds a function call which can be relaxed.  */
01202   HOWTO (R_V850_LONGCALL,     /* Type.  */
01203        0,                     /* Rightshift.  */
01204        2,                     /* Size (0 = byte, 1 = short, 2 = long).  */
01205        32,                    /* Bitsize.  */
01206        TRUE,                  /* PC_relative.  */
01207        0,                     /* Bitpos.  */
01208        complain_overflow_signed, /* Complain_on_overflow.  */
01209        v850_elf_ignore_reloc, /* Special_function.  */
01210        "R_V850_LONGCALL",     /* Name.  */
01211        FALSE,                 /* Partial_inplace.  */
01212        0,                     /* Src_mask.  */
01213        0,                     /* Dst_mask.  */
01214        TRUE),                 /* PCrel_offset.  */
01215 
01216   /* Indicates a .longjump pseudo-op.  The compiler will generate a
01217      .longjump pseudo-op when it finds a branch which can be relaxed.  */
01218   HOWTO (R_V850_LONGJUMP,     /* Type.  */
01219        0,                     /* Rightshift.  */
01220        2,                     /* Size (0 = byte, 1 = short, 2 = long).  */
01221        32,                    /* Bitsize.  */
01222        TRUE,                  /* PC_relative.  */
01223        0,                     /* Bitpos.  */
01224        complain_overflow_signed, /* Complain_on_overflow.  */
01225        v850_elf_ignore_reloc, /* Special_function.  */
01226        "R_V850_LONGJUMP",     /* Name.  */
01227        FALSE,                 /* Partial_inplace.  */
01228        0,                     /* Src_mask.  */
01229        0,                     /* Dst_mask.  */
01230        TRUE),                 /* PCrel_offset.  */
01231 
01232   HOWTO (R_V850_ALIGN,        /* Type.  */
01233        0,                     /* Rightshift.  */
01234        1,                     /* Size (0 = byte, 1 = short, 2 = long).  */
01235        0,                     /* Bitsize.  */
01236        FALSE,                 /* PC_relative.  */
01237        0,                     /* Bitpos.  */
01238        complain_overflow_unsigned, /* Complain_on_overflow.  */
01239        v850_elf_ignore_reloc, /* Special_function.  */
01240        "R_V850_ALIGN",        /* Name.  */
01241        FALSE,                 /* Partial_inplace.  */
01242        0,                     /* Src_mask.  */
01243        0,                     /* Dst_mask.  */
01244        TRUE),                 /* PCrel_offset.  */
01245   
01246   /* Simple pc-relative 32bit reloc.  */
01247   HOWTO (R_V850_REL32,                    /* Type.  */
01248         0,                         /* Rightshift.  */
01249         2,                         /* Size (0 = byte, 1 = short, 2 = long).  */
01250         32,                        /* Bitsize.  */
01251         TRUE,                      /* PC_relative.  */
01252         0,                         /* Bitpos.  */
01253         complain_overflow_dont,    /* Complain_on_overflow.  */
01254         v850_elf_reloc,            /* Special_function.  */
01255         "R_V850_REL32",            /* Name.  */
01256         FALSE,                            /* Partial_inplace.  */
01257         0xffffffff,                /* Src_mask.  */
01258         0xffffffff,                /* Dst_mask.  */
01259         FALSE),                    /* PCrel_offset.  */
01260 
01261   /* An ld.bu version of R_V850_LO16.  */
01262   HOWTO (R_V850_LO16_SPLIT_OFFSET, /* Type.  */
01263         0,                         /* Rightshift.  */
01264         2,                         /* Size (0 = byte, 1 = short, 2 = long).  */
01265         16,                        /* Bitsize.  */
01266         FALSE,                            /* PC_relative.  */
01267         0,                         /* Bitpos.  */
01268         complain_overflow_dont,    /* Complain_on_overflow.  */
01269         v850_elf_reloc,            /* Special_function.  */
01270         "R_V850_LO16_SPLIT_OFFSET",       /* Name.  */
01271         FALSE,                            /* Partial_inplace.  */
01272         0xfffe0020,                /* Src_mask.  */
01273         0xfffe0020,                /* Dst_mask.  */
01274         FALSE),                    /* PCrel_offset.  */
01275 };
01276 
01277 /* Map BFD reloc types to V850 ELF reloc types.  */
01278 
01279 struct v850_elf_reloc_map
01280 {
01281   /* BFD_RELOC_V850_CALLT_16_16_OFFSET is 258, which will not fix in an
01282      unsigned char.  */
01283   bfd_reloc_code_real_type bfd_reloc_val;
01284   unsigned int elf_reloc_val;
01285 };
01286 
01287 static const struct v850_elf_reloc_map v850_elf_reloc_map[] =
01288 {
01289   { BFD_RELOC_NONE,                    R_V850_NONE                   },
01290   { BFD_RELOC_V850_9_PCREL,            R_V850_9_PCREL                },
01291   { BFD_RELOC_V850_22_PCREL,                  R_V850_22_PCREL               },
01292   { BFD_RELOC_HI16_S,                         R_V850_HI16_S                 },
01293   { BFD_RELOC_HI16,                    R_V850_HI16                   },
01294   { BFD_RELOC_LO16,                    R_V850_LO16                   },
01295   { BFD_RELOC_32,                      R_V850_ABS32                  },
01296   { BFD_RELOC_32_PCREL,                       R_V850_REL32                  },
01297   { BFD_RELOC_16,                      R_V850_16                     },
01298   { BFD_RELOC_8,                       R_V850_8                      },
01299   { BFD_RELOC_V850_SDA_16_16_OFFSET,       R_V850_SDA_16_16_OFFSET       },
01300   { BFD_RELOC_V850_SDA_15_16_OFFSET,       R_V850_SDA_15_16_OFFSET       },
01301   { BFD_RELOC_V850_ZDA_16_16_OFFSET,       R_V850_ZDA_16_16_OFFSET       },
01302   { BFD_RELOC_V850_ZDA_15_16_OFFSET,       R_V850_ZDA_15_16_OFFSET       },
01303   { BFD_RELOC_V850_TDA_6_8_OFFSET,         R_V850_TDA_6_8_OFFSET         },
01304   { BFD_RELOC_V850_TDA_7_8_OFFSET,         R_V850_TDA_7_8_OFFSET         },
01305   { BFD_RELOC_V850_TDA_7_7_OFFSET,         R_V850_TDA_7_7_OFFSET         },
01306   { BFD_RELOC_V850_TDA_16_16_OFFSET,       R_V850_TDA_16_16_OFFSET       },
01307   { BFD_RELOC_V850_TDA_4_5_OFFSET,         R_V850_TDA_4_5_OFFSET         },
01308   { BFD_RELOC_V850_TDA_4_4_OFFSET,         R_V850_TDA_4_4_OFFSET         },
01309   { BFD_RELOC_V850_LO16_SPLIT_OFFSET,      R_V850_LO16_SPLIT_OFFSET      },
01310   { BFD_RELOC_V850_SDA_16_16_SPLIT_OFFSET, R_V850_SDA_16_16_SPLIT_OFFSET },
01311   { BFD_RELOC_V850_ZDA_16_16_SPLIT_OFFSET, R_V850_ZDA_16_16_SPLIT_OFFSET },
01312   { BFD_RELOC_V850_CALLT_6_7_OFFSET,       R_V850_CALLT_6_7_OFFSET       },
01313   { BFD_RELOC_V850_CALLT_16_16_OFFSET,     R_V850_CALLT_16_16_OFFSET     },
01314   { BFD_RELOC_VTABLE_INHERIT,              R_V850_GNU_VTINHERIT          },
01315   { BFD_RELOC_VTABLE_ENTRY,                R_V850_GNU_VTENTRY            },
01316   { BFD_RELOC_V850_LONGCALL,               R_V850_LONGCALL               },
01317   { BFD_RELOC_V850_LONGJUMP,               R_V850_LONGJUMP               },
01318   { BFD_RELOC_V850_ALIGN,                  R_V850_ALIGN                  },
01319 
01320 };
01321 
01322 /* Map a bfd relocation into the appropriate howto structure.  */
01323 
01324 static reloc_howto_type *
01325 v850_elf_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
01326                          bfd_reloc_code_real_type code)
01327 {
01328   unsigned int i;
01329 
01330   for (i = ARRAY_SIZE (v850_elf_reloc_map); i --;)
01331     if (v850_elf_reloc_map[i].bfd_reloc_val == code)
01332       {
01333        unsigned int elf_reloc_val = v850_elf_reloc_map[i].elf_reloc_val;
01334 
01335        BFD_ASSERT (v850_elf_howto_table[elf_reloc_val].type == elf_reloc_val);
01336 
01337        return v850_elf_howto_table + elf_reloc_val;
01338       }
01339 
01340   return NULL;
01341 }
01342 
01343 static reloc_howto_type *
01344 v850_elf_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
01345                          const char *r_name)
01346 {
01347   unsigned int i;
01348 
01349   for (i = 0;
01350        i < sizeof (v850_elf_howto_table) / sizeof (v850_elf_howto_table[0]);
01351        i++)
01352     if (v850_elf_howto_table[i].name != NULL
01353        && strcasecmp (v850_elf_howto_table[i].name, r_name) == 0)
01354       return &v850_elf_howto_table[i];
01355 
01356   return NULL;
01357 }
01358 
01359 /* Set the howto pointer for an V850 ELF reloc.  */
01360 
01361 static void
01362 v850_elf_info_to_howto_rel (bfd *abfd ATTRIBUTE_UNUSED,
01363                          arelent *cache_ptr,
01364                          Elf_Internal_Rela *dst)
01365 {
01366   unsigned int r_type;
01367 
01368   r_type = ELF32_R_TYPE (dst->r_info);
01369   BFD_ASSERT (r_type < (unsigned int) R_V850_max);
01370   cache_ptr->howto = &v850_elf_howto_table[r_type];
01371 }
01372 
01373 /* Set the howto pointer for a V850 ELF reloc (type RELA).  */
01374 
01375 static void
01376 v850_elf_info_to_howto_rela (bfd *abfd ATTRIBUTE_UNUSED,
01377                           arelent * cache_ptr,
01378                           Elf_Internal_Rela *dst)
01379 {
01380   unsigned int r_type;
01381 
01382   r_type = ELF32_R_TYPE (dst->r_info);
01383   BFD_ASSERT (r_type < (unsigned int) R_V850_max);
01384   cache_ptr->howto = &v850_elf_howto_table[r_type];
01385 }
01386 
01387 static bfd_boolean
01388 v850_elf_is_local_label_name (bfd *abfd ATTRIBUTE_UNUSED, const char *name)
01389 {
01390   return (   (name[0] == '.' && (name[1] == 'L' || name[1] == '.'))
01391          || (name[0] == '_' &&  name[1] == '.' && name[2] == 'L' && name[3] == '_'));
01392 }
01393 
01394 /* We overload some of the bfd_reloc error codes for own purposes.  */
01395 #define bfd_reloc_gp_not_found            bfd_reloc_other
01396 #define bfd_reloc_ep_not_found            bfd_reloc_continue
01397 #define bfd_reloc_ctbp_not_found   (bfd_reloc_dangerous + 1)
01398 
01399 /* Perform a relocation as part of a final link.  */
01400 
01401 static bfd_reloc_status_type
01402 v850_elf_final_link_relocate (reloc_howto_type *howto,
01403                            bfd *input_bfd,
01404                            bfd *output_bfd ATTRIBUTE_UNUSED,
01405                            asection *input_section,
01406                            bfd_byte *contents,
01407                            bfd_vma offset,
01408                            bfd_vma value,
01409                            bfd_vma addend,
01410                            struct bfd_link_info *info,
01411                            asection *sym_sec,
01412                            int is_local ATTRIBUTE_UNUSED)
01413 {
01414   unsigned int r_type = howto->type;
01415   bfd_byte *hit_data = contents + offset;
01416 
01417   /* Adjust the value according to the relocation.  */
01418   switch (r_type)
01419     {
01420     case R_V850_9_PCREL:
01421       value -= (input_section->output_section->vma
01422               + input_section->output_offset);
01423       value -= offset;
01424       break;
01425 
01426     case R_V850_22_PCREL:
01427       value -= (input_section->output_section->vma
01428               + input_section->output_offset
01429               + offset);
01430 
01431       /* If the sign extension will corrupt the value then we have overflowed.  */
01432       if (((value & 0xff000000) != 0x0) && ((value & 0xff000000) != 0xff000000))
01433        return bfd_reloc_overflow;
01434 
01435       /* Only the bottom 24 bits of the PC are valid.  */
01436       value = SEXT24 (value);
01437       break;
01438 
01439     case R_V850_REL32:
01440       value -= (input_section->output_section->vma
01441               + input_section->output_offset
01442               + offset);
01443       break;
01444 
01445     case R_V850_HI16_S:
01446     case R_V850_HI16:
01447     case R_V850_LO16:
01448     case R_V850_LO16_SPLIT_OFFSET:
01449     case R_V850_16:
01450     case R_V850_ABS32:
01451     case R_V850_8:
01452       break;
01453 
01454     case R_V850_ZDA_15_16_OFFSET:
01455     case R_V850_ZDA_16_16_OFFSET:
01456     case R_V850_ZDA_16_16_SPLIT_OFFSET:
01457       if (sym_sec == NULL)
01458        return bfd_reloc_undefined;
01459 
01460       value -= sym_sec->output_section->vma;
01461       break;
01462 
01463     case R_V850_SDA_15_16_OFFSET:
01464     case R_V850_SDA_16_16_OFFSET:
01465     case R_V850_SDA_16_16_SPLIT_OFFSET:
01466       {
01467        unsigned long                gp;
01468        struct bfd_link_hash_entry * h;
01469 
01470        if (sym_sec == NULL)
01471          return bfd_reloc_undefined;
01472 
01473        /* Get the value of __gp.  */
01474        h = bfd_link_hash_lookup (info->hash, "__gp", FALSE, FALSE, TRUE);
01475        if (h == NULL
01476            || h->type != bfd_link_hash_defined)
01477          return bfd_reloc_gp_not_found;
01478 
01479        gp = (h->u.def.value
01480              + h->u.def.section->output_section->vma
01481              + h->u.def.section->output_offset);
01482 
01483        value -= sym_sec->output_section->vma;
01484        value -= (gp - sym_sec->output_section->vma);
01485       }
01486     break;
01487 
01488     case R_V850_TDA_4_4_OFFSET:
01489     case R_V850_TDA_4_5_OFFSET:
01490     case R_V850_TDA_16_16_OFFSET:
01491     case R_V850_TDA_7_7_OFFSET:
01492     case R_V850_TDA_7_8_OFFSET:
01493     case R_V850_TDA_6_8_OFFSET:
01494       {
01495        unsigned long                ep;
01496        struct bfd_link_hash_entry * h;
01497 
01498        /* Get the value of __ep.  */
01499        h = bfd_link_hash_lookup (info->hash, "__ep", FALSE, FALSE, TRUE);
01500        if (h == NULL
01501            || h->type != bfd_link_hash_defined)
01502          return bfd_reloc_ep_not_found;
01503 
01504        ep = (h->u.def.value
01505              + h->u.def.section->output_section->vma
01506              + h->u.def.section->output_offset);
01507 
01508        value -= ep;
01509       }
01510     break;
01511 
01512     case R_V850_CALLT_6_7_OFFSET:
01513       {
01514        unsigned long                ctbp;
01515        struct bfd_link_hash_entry * h;
01516 
01517        /* Get the value of __ctbp.  */
01518        h = bfd_link_hash_lookup (info->hash, "__ctbp", FALSE, FALSE, TRUE);
01519        if (h == NULL
01520            || h->type != bfd_link_hash_defined)
01521          return bfd_reloc_ctbp_not_found;
01522 
01523        ctbp = (h->u.def.value
01524              + h->u.def.section->output_section->vma
01525              + h->u.def.section->output_offset);
01526        value -= ctbp;
01527       }
01528     break;
01529 
01530     case R_V850_CALLT_16_16_OFFSET:
01531       {
01532        unsigned long                ctbp;
01533        struct bfd_link_hash_entry * h;
01534 
01535        if (sym_sec == NULL)
01536          return bfd_reloc_undefined;
01537 
01538        /* Get the value of __ctbp.  */
01539        h = bfd_link_hash_lookup (info->hash, "__ctbp", FALSE, FALSE, TRUE);
01540        if (h == NULL
01541            || h->type != bfd_link_hash_defined)
01542          return bfd_reloc_ctbp_not_found;
01543 
01544        ctbp = (h->u.def.value
01545              + h->u.def.section->output_section->vma
01546              + h->u.def.section->output_offset);
01547 
01548        value -= sym_sec->output_section->vma;
01549        value -= (ctbp - sym_sec->output_section->vma);
01550       }
01551     break;
01552 
01553     case R_V850_NONE:
01554     case R_V850_GNU_VTINHERIT:
01555     case R_V850_GNU_VTENTRY:
01556     case R_V850_LONGCALL:
01557     case R_V850_LONGJUMP:
01558     case R_V850_ALIGN:
01559       return bfd_reloc_ok;
01560 
01561     default:
01562       return bfd_reloc_notsupported;
01563     }
01564 
01565   /* Perform the relocation.  */
01566   return v850_elf_perform_relocation (input_bfd, r_type, value + addend, hit_data);
01567 }
01568 
01569 /* Relocate an V850 ELF section.  */
01570 
01571 static bfd_boolean
01572 v850_elf_relocate_section (bfd *output_bfd,
01573                         struct bfd_link_info *info,
01574                         bfd *input_bfd,
01575                         asection *input_section,
01576                         bfd_byte *contents,
01577                         Elf_Internal_Rela *relocs,
01578                         Elf_Internal_Sym *local_syms,
01579                         asection **local_sections)
01580 {
01581   Elf_Internal_Shdr *symtab_hdr;
01582   struct elf_link_hash_entry **sym_hashes;
01583   Elf_Internal_Rela *rel;
01584   Elf_Internal_Rela *relend;
01585 
01586   symtab_hdr = & elf_tdata (input_bfd)->symtab_hdr;
01587   sym_hashes = elf_sym_hashes (input_bfd);
01588 
01589   /* Reset the list of remembered HI16S relocs to empty.  */
01590   free_hi16s     = previous_hi16s;
01591   previous_hi16s = NULL;
01592   hi16s_counter  = 0;
01593 
01594   rel    = relocs;
01595   relend = relocs + input_section->reloc_count;
01596   for (; rel < relend; rel++)
01597     {
01598       int r_type;
01599       reloc_howto_type *howto;
01600       unsigned long r_symndx;
01601       Elf_Internal_Sym *sym;
01602       asection *sec;
01603       struct elf_link_hash_entry *h;
01604       bfd_vma relocation;
01605       bfd_reloc_status_type r;
01606 
01607       r_symndx = ELF32_R_SYM (rel->r_info);
01608       r_type   = ELF32_R_TYPE (rel->r_info);
01609 
01610       if (r_type == R_V850_GNU_VTENTRY
01611           || r_type == R_V850_GNU_VTINHERIT)
01612         continue;
01613 
01614       howto = v850_elf_howto_table + r_type;
01615       h = NULL;
01616       sym = NULL;
01617       sec = NULL;
01618       if (r_symndx < symtab_hdr->sh_info)
01619        {
01620          sym = local_syms + r_symndx;
01621          sec = local_sections[r_symndx];
01622          relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel);
01623        }
01624       else
01625        {
01626          bfd_boolean unresolved_reloc, warned;
01627 
01628          /* Note - this check is delayed until now as it is possible and
01629             valid to have a file without any symbols but with relocs that
01630             can be processed.  */
01631          if (sym_hashes == NULL)
01632            {
01633              info->callbacks->warning
01634               (info, "no hash table available",
01635                NULL, input_bfd, input_section, (bfd_vma) 0);
01636 
01637              return FALSE;
01638            }
01639 
01640          RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
01641                                r_symndx, symtab_hdr, sym_hashes,
01642                                h, sec, relocation,
01643                                unresolved_reloc, warned);
01644        }
01645 
01646       if (sec != NULL && elf_discarded_section (sec))
01647        {
01648          /* For relocs against symbols from removed linkonce sections,
01649             or sections discarded by a linker script, we just want the
01650             section contents zeroed.  Avoid any special processing.  */
01651          _bfd_clear_contents (howto, input_bfd, contents + rel->r_offset);
01652          rel->r_info = 0;
01653          rel->r_addend = 0;
01654          continue;
01655        }
01656 
01657       if (info->relocatable)
01658        continue;
01659 
01660       /* FIXME: We should use the addend, but the COFF relocations don't.  */
01661       r = v850_elf_final_link_relocate (howto, input_bfd, output_bfd,
01662                                    input_section,
01663                                    contents, rel->r_offset,
01664                                    relocation, rel->r_addend,
01665                                    info, sec, h == NULL);
01666 
01667       if (r != bfd_reloc_ok)
01668        {
01669          const char * name;
01670          const char * msg = NULL;
01671 
01672          if (h != NULL)
01673            name = h->root.root.string;
01674          else
01675            {
01676              name = (bfd_elf_string_from_elf_section
01677                     (input_bfd, symtab_hdr->sh_link, sym->st_name));
01678              if (name == NULL || *name == '\0')
01679               name = bfd_section_name (input_bfd, sec);
01680            }
01681 
01682          switch (r)
01683            {
01684            case bfd_reloc_overflow:
01685              if (! ((*info->callbacks->reloc_overflow)
01686                    (info, (h ? &h->root : NULL), name, howto->name,
01687                     (bfd_vma) 0, input_bfd, input_section,
01688                     rel->r_offset)))
01689               return FALSE;
01690              break;
01691 
01692            case bfd_reloc_undefined:
01693              if (! ((*info->callbacks->undefined_symbol)
01694                    (info, name, input_bfd, input_section,
01695                     rel->r_offset, TRUE)))
01696               return FALSE;
01697              break;
01698 
01699            case bfd_reloc_outofrange:
01700              msg = _("internal error: out of range error");
01701              goto common_error;
01702 
01703            case bfd_reloc_notsupported:
01704              msg = _("internal error: unsupported relocation error");
01705              goto common_error;
01706 
01707            case bfd_reloc_dangerous:
01708              msg = _("internal error: dangerous relocation");
01709              goto common_error;
01710 
01711            case bfd_reloc_gp_not_found:
01712              msg = _("could not locate special linker symbol __gp");
01713              goto common_error;
01714 
01715            case bfd_reloc_ep_not_found:
01716              msg = _("could not locate special linker symbol __ep");
01717              goto common_error;
01718 
01719            case bfd_reloc_ctbp_not_found:
01720              msg = _("could not locate special linker symbol __ctbp");
01721              goto common_error;
01722 
01723            default:
01724              msg = _("internal error: unknown error");
01725              /* fall through */
01726 
01727            common_error:
01728              if (!((*info->callbacks->warning)
01729                   (info, msg, name, input_bfd, input_section,
01730                    rel->r_offset)))
01731               return FALSE;
01732              break;
01733            }
01734        }
01735     }
01736 
01737   return TRUE;
01738 }
01739 
01740 static asection *
01741 v850_elf_gc_mark_hook (asection *sec,
01742                      struct bfd_link_info *info,
01743                      Elf_Internal_Rela *rel,
01744                      struct elf_link_hash_entry *h,
01745                      Elf_Internal_Sym *sym)
01746 {
01747   if (h != NULL)
01748     switch (ELF32_R_TYPE (rel->r_info))
01749       {
01750       case R_V850_GNU_VTINHERIT:
01751       case R_V850_GNU_VTENTRY:
01752        return NULL;
01753       }
01754 
01755   return _bfd_elf_gc_mark_hook (sec, info, rel, h, sym);
01756 }
01757 
01758 /* Set the right machine number.  */
01759 
01760 static bfd_boolean
01761 v850_elf_object_p (bfd *abfd)
01762 {
01763   switch (elf_elfheader (abfd)->e_flags & EF_V850_ARCH)
01764     {
01765     default:
01766     case E_V850_ARCH:
01767       bfd_default_set_arch_mach (abfd, bfd_arch_v850, bfd_mach_v850);
01768       break;
01769     case E_V850E_ARCH:
01770       bfd_default_set_arch_mach (abfd, bfd_arch_v850, bfd_mach_v850e);
01771       break;
01772     case E_V850E1_ARCH:
01773       bfd_default_set_arch_mach (abfd, bfd_arch_v850, bfd_mach_v850e1);
01774       break;
01775     }
01776   return TRUE;
01777 }
01778 
01779 /* Store the machine number in the flags field.  */
01780 
01781 static void
01782 v850_elf_final_write_processing (bfd *abfd,
01783                              bfd_boolean linker ATTRIBUTE_UNUSED)
01784 {
01785   unsigned long val;
01786 
01787   switch (bfd_get_mach (abfd))
01788     {
01789     default:
01790     case bfd_mach_v850:   val = E_V850_ARCH; break;
01791     case bfd_mach_v850e:  val = E_V850E_ARCH; break;
01792     case bfd_mach_v850e1: val = E_V850E1_ARCH; break;
01793     }
01794 
01795   elf_elfheader (abfd)->e_flags &=~ EF_V850_ARCH;
01796   elf_elfheader (abfd)->e_flags |= val;
01797 }
01798 
01799 /* Function to keep V850 specific file flags.  */
01800 
01801 static bfd_boolean
01802 v850_elf_set_private_flags (bfd *abfd, flagword flags)
01803 {
01804   BFD_ASSERT (!elf_flags_init (abfd)
01805              || elf_elfheader (abfd)->e_flags == flags);
01806 
01807   elf_elfheader (abfd)->e_flags = flags;
01808   elf_flags_init (abfd) = TRUE;
01809   return TRUE;
01810 }
01811 
01812 /* Merge backend specific data from an object file
01813    to the output object file when linking.  */
01814 
01815 static bfd_boolean
01816 v850_elf_merge_private_bfd_data (bfd *ibfd, bfd *obfd)
01817 {
01818   flagword out_flags;
01819   flagword in_flags;
01820 
01821   if (   bfd_get_flavour (ibfd) != bfd_target_elf_flavour
01822       || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
01823     return TRUE;
01824 
01825   in_flags = elf_elfheader (ibfd)->e_flags;
01826   out_flags = elf_elfheader (obfd)->e_flags;
01827 
01828   if (! elf_flags_init (obfd))
01829     {
01830       /* If the input is the default architecture then do not
01831         bother setting the flags for the output architecture,
01832         instead allow future merges to do this.  If no future
01833         merges ever set these flags then they will retain their
01834         unitialised values, which surprise surprise, correspond
01835         to the default values.  */
01836       if (bfd_get_arch_info (ibfd)->the_default)
01837        return TRUE;
01838 
01839       elf_flags_init (obfd) = TRUE;
01840       elf_elfheader (obfd)->e_flags = in_flags;
01841 
01842       if (bfd_get_arch (obfd) == bfd_get_arch (ibfd)
01843          && bfd_get_arch_info (obfd)->the_default)
01844        return bfd_set_arch_mach (obfd, bfd_get_arch (ibfd), bfd_get_mach (ibfd));
01845 
01846       return TRUE;
01847     }
01848 
01849   /* Check flag compatibility.  */
01850   if (in_flags == out_flags)
01851     return TRUE;
01852 
01853   if ((in_flags & EF_V850_ARCH) != (out_flags & EF_V850_ARCH)
01854       && (in_flags & EF_V850_ARCH) != E_V850_ARCH)
01855     {
01856       /* Allow v850e1 binaries to be linked with v850e binaries.
01857         Set the output binary to v850e.  */
01858       if ((in_flags & EF_V850_ARCH) == E_V850E1_ARCH
01859          && (out_flags & EF_V850_ARCH) == E_V850E_ARCH)
01860        return TRUE;
01861 
01862       if ((in_flags & EF_V850_ARCH) == E_V850E_ARCH
01863          && (out_flags & EF_V850_ARCH) == E_V850E1_ARCH)
01864        {
01865          elf_elfheader (obfd)->e_flags =
01866            ((out_flags & ~ EF_V850_ARCH) | E_V850E_ARCH);
01867          return TRUE;
01868        }
01869 
01870       _bfd_error_handler (_("%B: Architecture mismatch with previous modules"),
01871                        ibfd);
01872     }
01873 
01874   return TRUE;
01875 }
01876 
01877 /* Display the flags field.  */
01878 
01879 static bfd_boolean
01880 v850_elf_print_private_bfd_data (bfd *abfd, void * ptr)
01881 {
01882   FILE * file = (FILE *) ptr;
01883 
01884   BFD_ASSERT (abfd != NULL && ptr != NULL);
01885 
01886   _bfd_elf_print_private_bfd_data (abfd, ptr);
01887 
01888   /* xgettext:c-format */
01889   fprintf (file, _("private flags = %lx: "), elf_elfheader (abfd)->e_flags);
01890 
01891   switch (elf_elfheader (abfd)->e_flags & EF_V850_ARCH)
01892     {
01893     default:
01894     case E_V850_ARCH: fprintf (file, _("v850 architecture")); break;
01895     case E_V850E_ARCH: fprintf (file, _("v850e architecture")); break;
01896     case E_V850E1_ARCH: fprintf (file, _("v850e1 architecture")); break;
01897     }
01898 
01899   fputc ('\n', file);
01900 
01901   return TRUE;
01902 }
01903 
01904 /* V850 ELF uses four common sections.  One is the usual one, and the
01905    others are for (small) objects in one of the special data areas:
01906    small, tiny and zero.  All the objects are kept together, and then
01907    referenced via the gp register, the ep register or the r0 register
01908    respectively, which yields smaller, faster assembler code.  This
01909    approach is copied from elf32-mips.c.  */
01910 
01911 static asection  v850_elf_scom_section;
01912 static asymbol   v850_elf_scom_symbol;
01913 static asymbol * v850_elf_scom_symbol_ptr;
01914 static asection  v850_elf_tcom_section;
01915 static asymbol   v850_elf_tcom_symbol;
01916 static asymbol * v850_elf_tcom_symbol_ptr;
01917 static asection  v850_elf_zcom_section;
01918 static asymbol   v850_elf_zcom_symbol;
01919 static asymbol * v850_elf_zcom_symbol_ptr;
01920 
01921 /* Given a BFD section, try to locate the
01922    corresponding ELF section index.  */
01923 
01924 static bfd_boolean
01925 v850_elf_section_from_bfd_section (bfd *abfd ATTRIBUTE_UNUSED,
01926                                asection *sec,
01927                                int *retval)
01928 {
01929   if (strcmp (bfd_get_section_name (abfd, sec), ".scommon") == 0)
01930     *retval = SHN_V850_SCOMMON;
01931   else if (strcmp (bfd_get_section_name (abfd, sec), ".tcommon") == 0)
01932     *retval = SHN_V850_TCOMMON;
01933   else if (strcmp (bfd_get_section_name (abfd, sec), ".zcommon") == 0)
01934     *retval = SHN_V850_ZCOMMON;
01935   else
01936     return FALSE;
01937 
01938   return TRUE;
01939 }
01940 
01941 /* Handle the special V850 section numbers that a symbol may use.  */
01942 
01943 static void
01944 v850_elf_symbol_processing (bfd *abfd, asymbol *asym)
01945 {
01946   elf_symbol_type * elfsym = (elf_symbol_type *) asym;
01947   unsigned int indx;
01948 
01949   indx = elfsym->internal_elf_sym.st_shndx;
01950 
01951   /* If the section index is an "ordinary" index, then it may
01952      refer to a v850 specific section created by the assembler.
01953      Check the section's type and change the index it matches.
01954 
01955      FIXME: Should we alter the st_shndx field as well ?  */
01956 
01957   if (indx < elf_numsections (abfd))
01958     switch (elf_elfsections(abfd)[indx]->sh_type)
01959       {
01960       case SHT_V850_SCOMMON:
01961        indx = SHN_V850_SCOMMON;
01962        break;
01963 
01964       case SHT_V850_TCOMMON:
01965        indx = SHN_V850_TCOMMON;
01966        break;
01967 
01968       case SHT_V850_ZCOMMON:
01969        indx = SHN_V850_ZCOMMON;
01970        break;
01971 
01972       default:
01973        break;
01974       }
01975 
01976   switch (indx)
01977     {
01978     case SHN_V850_SCOMMON:
01979       if (v850_elf_scom_section.name == NULL)
01980        {
01981          /* Initialize the small common section.  */
01982          v850_elf_scom_section.name           = ".scommon";
01983          v850_elf_scom_section.flags          = SEC_IS_COMMON | SEC_ALLOC | SEC_DATA;
01984          v850_elf_scom_section.output_section = & v850_elf_scom_section;
01985          v850_elf_scom_section.symbol         = & v850_elf_scom_symbol;
01986          v850_elf_scom_section.symbol_ptr_ptr = & v850_elf_scom_symbol_ptr;
01987          v850_elf_scom_symbol.name            = ".scommon";
01988          v850_elf_scom_symbol.flags           = BSF_SECTION_SYM;
01989          v850_elf_scom_symbol.section         = & v850_elf_scom_section;
01990          v850_elf_scom_symbol_ptr             = & v850_elf_scom_symbol;
01991        }
01992       asym->section = & v850_elf_scom_section;
01993       asym->value = elfsym->internal_elf_sym.st_size;
01994       break;
01995 
01996     case SHN_V850_TCOMMON:
01997       if (v850_elf_tcom_section.name == NULL)
01998        {
01999          /* Initialize the tcommon section.  */
02000          v850_elf_tcom_section.name           = ".tcommon";
02001          v850_elf_tcom_section.flags          = SEC_IS_COMMON;
02002          v850_elf_tcom_section.output_section = & v850_elf_tcom_section;
02003          v850_elf_tcom_section.symbol         = & v850_elf_tcom_symbol;
02004          v850_elf_tcom_section.symbol_ptr_ptr = & v850_elf_tcom_symbol_ptr;
02005          v850_elf_tcom_symbol.name            = ".tcommon";
02006          v850_elf_tcom_symbol.flags           = BSF_SECTION_SYM;
02007          v850_elf_tcom_symbol.section         = & v850_elf_tcom_section;
02008          v850_elf_tcom_symbol_ptr             = & v850_elf_tcom_symbol;
02009        }
02010       asym->section = & v850_elf_tcom_section;
02011       asym->value = elfsym->internal_elf_sym.st_size;
02012       break;
02013 
02014     case SHN_V850_ZCOMMON:
02015       if (v850_elf_zcom_section.name == NULL)
02016        {
02017          /* Initialize the zcommon section.  */
02018          v850_elf_zcom_section.name           = ".zcommon";
02019          v850_elf_zcom_section.flags          = SEC_IS_COMMON;
02020          v850_elf_zcom_section.output_section = & v850_elf_zcom_section;
02021          v850_elf_zcom_section.symbol         = & v850_elf_zcom_symbol;
02022          v850_elf_zcom_section.symbol_ptr_ptr = & v850_elf_zcom_symbol_ptr;
02023          v850_elf_zcom_symbol.name            = ".zcommon";
02024          v850_elf_zcom_symbol.flags           = BSF_SECTION_SYM;
02025          v850_elf_zcom_symbol.section         = & v850_elf_zcom_section;
02026          v850_elf_zcom_symbol_ptr             = & v850_elf_zcom_symbol;
02027        }
02028       asym->section = & v850_elf_zcom_section;
02029       asym->value = elfsym->internal_elf_sym.st_size;
02030       break;
02031     }
02032 }
02033 
02034 /* Hook called by the linker routine which adds symbols from an object
02035    file.  We must handle the special v850 section numbers here.  */
02036 
02037 static bfd_boolean
02038 v850_elf_add_symbol_hook (bfd *abfd,
02039                        struct bfd_link_info *info ATTRIBUTE_UNUSED,
02040                        Elf_Internal_Sym *sym,
02041                        const char **namep ATTRIBUTE_UNUSED,
02042                        flagword *flagsp ATTRIBUTE_UNUSED,
02043                        asection **secp,
02044                        bfd_vma *valp)
02045 {
02046   unsigned int indx = sym->st_shndx;
02047 
02048   /* If the section index is an "ordinary" index, then it may
02049      refer to a v850 specific section created by the assembler.
02050      Check the section's type and change the index it matches.
02051 
02052      FIXME: Should we alter the st_shndx field as well ?  */
02053 
02054   if (indx < elf_numsections (abfd))
02055     switch (elf_elfsections(abfd)[indx]->sh_type)
02056       {
02057       case SHT_V850_SCOMMON:
02058        indx = SHN_V850_SCOMMON;
02059        break;
02060 
02061       case SHT_V850_TCOMMON:
02062        indx = SHN_V850_TCOMMON;
02063        break;
02064 
02065       case SHT_V850_ZCOMMON:
02066        indx = SHN_V850_ZCOMMON;
02067        break;
02068 
02069       default:
02070        break;
02071       }
02072 
02073   switch (indx)
02074     {
02075     case SHN_V850_SCOMMON:
02076       *secp = bfd_make_section_old_way (abfd, ".scommon");
02077       (*secp)->flags |= SEC_IS_COMMON;
02078       *valp = sym->st_size;
02079       break;
02080 
02081     case SHN_V850_TCOMMON:
02082       *secp = bfd_make_section_old_way (abfd, ".tcommon");
02083       (*secp)->flags |= SEC_IS_COMMON;
02084       *valp = sym->st_size;
02085       break;
02086 
02087     case SHN_V850_ZCOMMON:
02088       *secp = bfd_make_section_old_way (abfd, ".zcommon");
02089       (*secp)->flags |= SEC_IS_COMMON;
02090       *valp = sym->st_size;
02091       break;
02092     }
02093 
02094   return TRUE;
02095 }
02096 
02097 static bfd_boolean
02098 v850_elf_link_output_symbol_hook (struct bfd_link_info *info ATTRIBUTE_UNUSED,
02099                               const char *name ATTRIBUTE_UNUSED,
02100                               Elf_Internal_Sym *sym,
02101                               asection *input_sec,
02102                               struct elf_link_hash_entry *h ATTRIBUTE_UNUSED)
02103 {
02104   /* If we see a common symbol, which implies a relocatable link, then
02105      if a symbol was in a special common section in an input file, mark
02106      it as a special common in the output file.  */
02107 
02108   if (sym->st_shndx == SHN_COMMON)
02109     {
02110       if (strcmp (input_sec->name, ".scommon") == 0)
02111        sym->st_shndx = SHN_V850_SCOMMON;
02112       else if (strcmp (input_sec->name, ".tcommon") == 0)
02113        sym->st_shndx = SHN_V850_TCOMMON;
02114       else if (strcmp (input_sec->name, ".zcommon") == 0)
02115        sym->st_shndx = SHN_V850_ZCOMMON;
02116     }
02117 
02118   /* The price we pay for using h->other unused bits as flags in the
02119      linker is cleaning up after ourselves.  */
02120 
02121   sym->st_other &= ~(V850_OTHER_SDA | V850_OTHER_ZDA | V850_OTHER_TDA
02122                    | V850_OTHER_ERROR);
02123 
02124   return TRUE;
02125 }
02126 
02127 static bfd_boolean
02128 v850_elf_section_from_shdr (bfd *abfd,
02129                          Elf_Internal_Shdr *hdr,
02130                          const char *name,
02131                          int shindex)
02132 {
02133   /* There ought to be a place to keep ELF backend specific flags, but
02134      at the moment there isn't one.  We just keep track of the
02135      sections by their name, instead.  */
02136 
02137   if (! _bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex))
02138     return FALSE;
02139 
02140   switch (hdr->sh_type)
02141     {
02142     case SHT_V850_SCOMMON:
02143     case SHT_V850_TCOMMON:
02144     case SHT_V850_ZCOMMON:
02145       if (! bfd_set_section_flags (abfd, hdr->bfd_section,
02146                                (bfd_get_section_flags (abfd,
02147                                                     hdr->bfd_section)
02148                                 | SEC_IS_COMMON)))
02149        return FALSE;
02150     }
02151 
02152   return TRUE;
02153 }
02154 
02155 /* Set the correct type for a V850 ELF section.  We do this
02156    by the section name, which is a hack, but ought to work.  */
02157 
02158 static bfd_boolean
02159 v850_elf_fake_sections (bfd *abfd ATTRIBUTE_UNUSED,
02160                      Elf_Internal_Shdr *hdr,
02161                      asection *sec)
02162 {
02163   const char * name;
02164 
02165   name = bfd_get_section_name (abfd, sec);
02166 
02167   if (strcmp (name, ".scommon") == 0)
02168     hdr->sh_type = SHT_V850_SCOMMON;
02169   else if (strcmp (name, ".tcommon") == 0)
02170     hdr->sh_type = SHT_V850_TCOMMON;
02171   else if (strcmp (name, ".zcommon") == 0)
02172     hdr->sh_type = SHT_V850_ZCOMMON;
02173 
02174   return TRUE;
02175 }
02176 
02177 /* Delete some bytes from a section while relaxing.  */
02178 
02179 static bfd_boolean
02180 v850_elf_relax_delete_bytes (bfd *abfd,
02181                           asection *sec,
02182                           bfd_vma addr,
02183                           bfd_vma toaddr,
02184                           int count)
02185 {
02186   Elf_Internal_Shdr *symtab_hdr;
02187   Elf32_External_Sym *extsyms;
02188   Elf32_External_Sym *esym;
02189   Elf32_External_Sym *esymend;
02190   int index;
02191   unsigned int sec_shndx;
02192   bfd_byte *contents;
02193   Elf_Internal_Rela *irel;
02194   Elf_Internal_Rela *irelend;
02195   struct elf_link_hash_entry *sym_hash;
02196   Elf_Internal_Shdr *shndx_hdr;
02197   Elf_External_Sym_Shndx *shndx;
02198 
02199   symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
02200   extsyms = (Elf32_External_Sym *) symtab_hdr->contents;
02201 
02202   sec_shndx = _bfd_elf_section_from_bfd_section (abfd, sec);
02203 
02204   contents = elf_section_data (sec)->this_hdr.contents;
02205 
02206   /* The deletion must stop at the next ALIGN reloc for an alignment
02207      power larger than the number of bytes we are deleting.  */
02208 
02209   /* Actually delete the bytes.  */
02210 #if (DEBUG_RELAX & 2)
02211   fprintf (stderr, "relax_delete: contents: sec: %s  %p .. %p %x\n",
02212           sec->name, addr, toaddr, count );
02213 #endif
02214   memmove (contents + addr, contents + addr + count,
02215           toaddr - addr - count);
02216   memset (contents + toaddr-count, 0, count);
02217 
02218   /* Adjust all the relocs.  */
02219   irel = elf_section_data (sec)->relocs;
02220   irelend = irel + sec->reloc_count;
02221   shndx_hdr = &elf_tdata (abfd)->symtab_shndx_hdr;
02222   shndx = (Elf_External_Sym_Shndx *) shndx_hdr->contents;
02223 
02224   for (; irel < irelend; irel++)
02225     {
02226       bfd_vma raddr, paddr, symval;
02227       Elf_Internal_Sym isym;
02228 
02229       /* Get the new reloc address.  */
02230       raddr = irel->r_offset;
02231       if ((raddr >= (addr + count) && raddr < toaddr))
02232        irel->r_offset -= count;
02233 
02234       if (raddr >= addr && raddr < addr + count)
02235        {
02236          irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
02237                                    (int) R_V850_NONE);
02238          continue;
02239        }
02240 
02241       if (ELF32_R_TYPE (irel->r_info) == (int) R_V850_ALIGN)
02242        continue;
02243 
02244       bfd_elf32_swap_symbol_in (abfd,
02245                             extsyms + ELF32_R_SYM (irel->r_info),
02246                             shndx ? shndx + ELF32_R_SYM (irel->r_info) : NULL,
02247                             & isym);
02248 
02249       if (isym.st_shndx != sec_shndx)
02250        continue;
02251 
02252       /* Get the value of the symbol referred to by the reloc.  */
02253       if (ELF32_R_SYM (irel->r_info) < symtab_hdr->sh_info)
02254        {
02255          symval = isym.st_value;
02256 #if (DEBUG_RELAX & 2)
02257          {
02258            char * name = bfd_elf_string_from_elf_section
02259                           (abfd, symtab_hdr->sh_link, isym.st_name);
02260            fprintf (stderr,
02261               "relax_delete: local: sec: %s, sym: %s (%d), value: %x + %x + %x addend %x\n",
02262               sec->name, name, isym.st_name,
02263               sec->output_section->vma, sec->output_offset,
02264               isym.st_value, irel->r_addend);
02265          }
02266 #endif
02267        }
02268       else
02269        {
02270          unsigned long indx;
02271          struct elf_link_hash_entry * h;
02272 
02273          /* An external symbol.  */
02274          indx = ELF32_R_SYM (irel->r_info) - symtab_hdr->sh_info;
02275 
02276          h = elf_sym_hashes (abfd) [indx];
02277          BFD_ASSERT (h != NULL);
02278 
02279          symval = h->root.u.def.value;
02280 #if (DEBUG_RELAX & 2)
02281          fprintf (stderr,
02282                  "relax_delete: defined: sec: %s, name: %s, value: %x + %x + %x addend %x\n",
02283                  sec->name, h->root.root.string, h->root.u.def.value,
02284                  sec->output_section->vma, sec->output_offset, irel->r_addend);
02285 #endif
02286        }
02287 
02288       paddr = symval + irel->r_addend;
02289 
02290       if ( (symval >= addr + count && symval < toaddr)
02291          && (paddr < addr + count || paddr >= toaddr))
02292        irel->r_addend += count;
02293       else if (    (symval < addr + count || symval >= toaddr)
02294                && (paddr >= addr + count && paddr < toaddr))
02295        irel->r_addend -= count;
02296     }
02297 
02298   /* Adjust the local symbols defined in this section.  */
02299   esym = extsyms;
02300   esymend = esym + symtab_hdr->sh_info;
02301 
02302   for (; esym < esymend; esym++, shndx = (shndx ? shndx + 1 : NULL))
02303     {
02304       Elf_Internal_Sym isym;
02305 
02306       bfd_elf32_swap_symbol_in (abfd, esym, shndx, & isym);
02307 
02308       if (isym.st_shndx == sec_shndx
02309          && isym.st_value >= addr + count
02310          && isym.st_value < toaddr)
02311        {
02312          isym.st_value -= count;
02313 
02314          if (isym.st_value + isym.st_size >= toaddr)
02315            isym.st_size += count;
02316 
02317          bfd_elf32_swap_symbol_out (abfd, & isym, esym, shndx);
02318        }
02319       else if (isym.st_shndx == sec_shndx
02320               && isym.st_value < addr + count)
02321        {
02322          if (isym.st_value+isym.st_size >= addr + count
02323              && isym.st_value+isym.st_size < toaddr)
02324            isym.st_size -= count;
02325 
02326          if (isym.st_value >= addr
02327              && isym.st_value <  addr + count)
02328            isym.st_value = addr;
02329 
02330          bfd_elf32_swap_symbol_out (abfd, & isym, esym, shndx);
02331        }
02332     }
02333 
02334   /* Now adjust the global symbols defined in this section.  */
02335   esym = extsyms + symtab_hdr->sh_info;
02336   esymend = extsyms + (symtab_hdr->sh_size / sizeof (Elf32_External_Sym));
02337 
02338   for (index = 0; esym < esymend; esym ++, index ++)
02339     {
02340       Elf_Internal_Sym isym;
02341 
02342       bfd_elf32_swap_symbol_in (abfd, esym, shndx, & isym);
02343       sym_hash = elf_sym_hashes (abfd) [index];
02344 
02345       if (isym.st_shndx == sec_shndx
02346          && ((sym_hash)->root.type == bfd_link_hash_defined
02347              || (sym_hash)->root.type == bfd_link_hash_defweak)
02348          && (sym_hash)->root.u.def.section == sec
02349          && (sym_hash)->root.u.def.value >= addr + count
02350          && (sym_hash)->root.u.def.value < toaddr)
02351        {
02352          if ((sym_hash)->root.u.def.value + isym.st_size >= toaddr)
02353            {
02354              isym.st_size += count;
02355              bfd_elf32_swap_symbol_out (abfd, & isym, esym, shndx);
02356            }
02357 
02358          (sym_hash)->root.u.def.value -= count;
02359        }
02360       else if (isym.st_shndx == sec_shndx
02361               && ((sym_hash)->root.type == bfd_link_hash_defined
02362                  || (sym_hash)->root.type == bfd_link_hash_defweak)
02363               && (sym_hash)->root.u.def.section == sec
02364               && (sym_hash)->root.u.def.value < addr + count)
02365        {
02366          if ((sym_hash)->root.u.def.value+isym.st_size >= addr + count
02367              && (sym_hash)->root.u.def.value+isym.st_size < toaddr)
02368            isym.st_size -= count;
02369 
02370          if ((sym_hash)->root.u.def.value >= addr
02371              && (sym_hash)->root.u.def.value < addr + count)
02372            (sym_hash)->root.u.def.value = addr;
02373 
02374          bfd_elf32_swap_symbol_out (abfd, & isym, esym, shndx);
02375        }
02376 
02377       if (shndx)
02378        ++ shndx;
02379     }
02380 
02381   return TRUE;
02382 }
02383 
02384 #define NOP_OPCODE   (0x0000)
02385 #define MOVHI        0x0640                      /* 4byte */
02386 #define MOVHI_MASK   0x07e0
02387 #define MOVHI_R1(insn)      ((insn) & 0x1f)                    /* 4byte */
02388 #define MOVHI_R2(insn)      ((insn) >> 11)
02389 #define MOVEA        0x0620                      /* 2byte */
02390 #define MOVEA_MASK   0x07e0
02391 #define MOVEA_R1(insn)      ((insn) & 0x1f)
02392 #define MOVEA_R2(insn)      ((insn) >> 11)
02393 #define JARL_4              0x00040780                         /* 4byte */
02394 #define JARL_4_MASK  0xFFFF07FF
02395 #define JARL_R2(insn)       (int)(((insn) & (~JARL_4_MASK)) >> 11)
02396 #define ADD_I        0x0240                             /* 2byte */
02397 #define ADD_I_MASK   0x07e0
02398 #define ADD_I5(insn) ((((insn) & 0x001f) << 11) >> 11)  /* 2byte */
02399 #define ADD_R2(insn) ((insn) >> 11)
02400 #define JMP_R        0x0060                             /* 2byte */
02401 #define JMP_R_MASK   0xFFE0
02402 #define JMP_R1(insn) ((insn) & 0x1f)
02403 
02404 static bfd_boolean
02405 v850_elf_relax_section (bfd *abfd,
02406                      asection *sec,
02407                      struct bfd_link_info *link_info,
02408                      bfd_boolean *again)
02409 {
02410   Elf_Internal_Shdr *symtab_hdr;
02411   Elf_Internal_Rela *internal_relocs;
02412   Elf_Internal_Rela *irel;
02413   Elf_Internal_Rela *irelend;
02414   Elf_Internal_Rela *irelalign = NULL;
02415   Elf_Internal_Sym *isymbuf = NULL;
02416   bfd_byte *contents = NULL;
02417   bfd_vma addr = 0;
02418   bfd_vma toaddr;
02419   int align_pad_size = 0;
02420   bfd_boolean result = TRUE;
02421 
02422   *again = FALSE;
02423 
02424   if (link_info->relocatable
02425       || (sec->flags & SEC_RELOC) == 0
02426       || sec->reloc_count == 0)
02427     return TRUE;
02428 
02429   symtab_hdr = & elf_tdata (abfd)->symtab_hdr;
02430 
02431   internal_relocs = (_bfd_elf_link_read_relocs
02432                    (abfd, sec, NULL, NULL, link_info->keep_memory));
02433   if (internal_relocs == NULL)
02434     goto error_return;
02435 
02436   irelend = internal_relocs + sec->reloc_count;
02437 
02438   while (addr < sec->size)
02439     {
02440       toaddr = sec->size;
02441 
02442       for (irel = internal_relocs; irel < irelend; irel ++)
02443        if (ELF32_R_TYPE (irel->r_info) == (int) R_V850_ALIGN
02444            && irel->r_offset > addr
02445            && irel->r_offset < toaddr)
02446          toaddr = irel->r_offset;
02447 
02448 #ifdef DEBUG_RELAX
02449       fprintf (stderr, "relax region 0x%x to 0x%x align pad %d\n",
02450               addr, toaddr, align_pad_size);
02451 #endif
02452       if (irelalign)
02453        {
02454          bfd_vma alignto;
02455          bfd_vma alignmoveto;
02456 
02457          alignmoveto = BFD_ALIGN (addr - align_pad_size, 1 << irelalign->r_addend);
02458          alignto = BFD_ALIGN (addr, 1 << irelalign->r_addend);
02459 
02460          if (alignmoveto < alignto)
02461            {
02462              unsigned int i;
02463 
02464              align_pad_size = alignto - alignmoveto;
02465 #ifdef DEBUG_RELAX
02466              fprintf (stderr, "relax move region 0x%x to 0x%x delete size 0x%x\n",
02467                      alignmoveto, toaddr, align_pad_size);
02468 #endif
02469              if (!v850_elf_relax_delete_bytes (abfd, sec, alignmoveto,
02470                                           toaddr, align_pad_size))
02471               goto error_return;
02472 
02473              for (i  = BFD_ALIGN (toaddr - align_pad_size, 1);
02474                  (i + 1) < toaddr; i += 2)
02475               bfd_put_16 (abfd, NOP_OPCODE, contents + i);
02476 
02477              addr = alignmoveto;
02478            }
02479          else
02480            align_pad_size = 0;
02481        }
02482 
02483       for (irel = internal_relocs; irel < irelend; irel++)
02484        {
02485          bfd_vma laddr;
02486          bfd_vma addend;
02487          bfd_vma symval;
02488          int insn[5];
02489          int no_match = -1;
02490          Elf_Internal_Rela *hi_irelfn;
02491          Elf_Internal_Rela *lo_irelfn;
02492          Elf_Internal_Rela *irelcall;
02493          bfd_signed_vma foff;
02494 
02495          if (! (irel->r_offset >= addr && irel->r_offset < toaddr
02496                && (ELF32_R_TYPE (irel->r_info) == (int) R_V850_LONGCALL
02497                    || ELF32_R_TYPE (irel->r_info) == (int) R_V850_LONGJUMP)))
02498            continue;
02499 
02500 #ifdef DEBUG_RELAX
02501          fprintf (stderr, "relax check r_info 0x%x r_offset 0x%x r_addend 0x%x\n",
02502                  irel->r_info,
02503                  irel->r_offset,
02504                  irel->r_addend );
02505 #endif
02506 
02507          /* Get the section contents.  */
02508          if (contents == NULL)
02509            {
02510              if (elf_section_data (sec)->this_hdr.contents != NULL)
02511               contents = elf_section_data (sec)->this_hdr.contents;
02512              else
02513               {
02514                 if (! bfd_malloc_and_get_section (abfd, sec, &contents))
02515                   goto error_return;
02516               }
02517            }
02518 
02519          /* Read this BFD's local symbols if we haven't done so already.  */
02520          if (isymbuf == NULL && symtab_hdr->sh_info != 0)
02521            {
02522              isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
02523              if (isymbuf == NULL)
02524               isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr,
02525                                           symtab_hdr->sh_info, 0,
02526                                           NULL, NULL, NULL);
02527              if (isymbuf == NULL)
02528               goto error_return;
02529            }
02530 
02531          laddr = irel->r_offset;
02532 
02533          if (ELF32_R_TYPE (irel->r_info) == (int) R_V850_LONGCALL)
02534            {
02535              /* Check code for -mlong-calls output. */
02536              if (laddr + 16 <= (bfd_vma) sec->size)
02537               {
02538                 insn[0] = bfd_get_16 (abfd, contents + laddr);
02539                 insn[1] = bfd_get_16 (abfd, contents + laddr + 4);
02540                 insn[2] = bfd_get_32 (abfd, contents + laddr + 8);
02541                 insn[3] = bfd_get_16 (abfd, contents + laddr + 12);
02542                 insn[4] = bfd_get_16 (abfd, contents + laddr + 14);
02543 
02544                 if ((insn[0] & MOVHI_MASK) != MOVHI
02545                      || MOVHI_R1 (insn[0]) != 0)
02546                   no_match = 0;
02547 
02548                 if (no_match < 0
02549                     && ((insn[1] & MOVEA_MASK) != MOVEA
02550                         || MOVHI_R2 (insn[0]) != MOVEA_R1 (insn[1])))
02551                   no_match = 1;
02552 
02553                 if (no_match < 0
02554                     && (insn[2] & JARL_4_MASK) != JARL_4)
02555                   no_match = 2;
02556 
02557                 if (no_match < 0
02558                     && ((insn[3] & ADD_I_MASK) != ADD_I
02559                         || ADD_I5 (insn[3]) != 4
02560                         || JARL_R2 (insn[2]) != ADD_R2 (insn[3])))
02561                   no_match = 3;
02562 
02563                 if (no_match < 0
02564                     && ((insn[4] & JMP_R_MASK) != JMP_R
02565                         || MOVEA_R2 (insn[1]) != JMP_R1 (insn[4])))
02566                   no_match = 4;
02567               }
02568              else
02569               {
02570                 ((*_bfd_error_handler)
02571                  ("%s: 0x%lx: warning: R_V850_LONGCALL points to unrecognized insns",
02572                   bfd_get_filename (abfd), (unsigned long) irel->r_offset));
02573 
02574                 continue;
02575               }
02576 
02577              if (no_match >= 0)
02578               {
02579                 ((*_bfd_error_handler)
02580                  ("%s: 0x%lx: warning: R_V850_LONGCALL points to unrecognized insn 0x%x",
02581                   bfd_get_filename (abfd), (unsigned long) irel->r_offset+no_match, insn[no_match]));
02582 
02583                 continue;
02584               }
02585 
02586              /* Get the reloc for the address from which the register is
02587                 being loaded.  This reloc will tell us which function is
02588                 actually being called.  */
02589              for (hi_irelfn = internal_relocs; hi_irelfn < irelend; hi_irelfn ++)
02590               if (hi_irelfn->r_offset == laddr + 2
02591                   && ELF32_R_TYPE (hi_irelfn->r_info)
02592                       == (int) R_V850_HI16_S)
02593                 break;
02594 
02595              for (lo_irelfn = internal_relocs; lo_irelfn < irelend; lo_irelfn ++)
02596               if (lo_irelfn->r_offset == laddr + 6
02597                   && ELF32_R_TYPE (lo_irelfn->r_info)
02598                       == (int) R_V850_LO16)
02599                 break;
02600 
02601              for (irelcall = internal_relocs; irelcall < irelend; irelcall ++)
02602               if (irelcall->r_offset == laddr + 8
02603                   && ELF32_R_TYPE (irelcall->r_info)
02604                         == (int) R_V850_22_PCREL)
02605                 break;
02606 
02607              if (   hi_irelfn == irelend
02608                 || lo_irelfn == irelend
02609                 || irelcall  == irelend)
02610               {
02611                 ((*_bfd_error_handler)
02612                  ("%s: 0x%lx: warning: R_V850_LONGCALL points to unrecognized reloc",
02613                   bfd_get_filename (abfd), (unsigned long) irel->r_offset ));
02614 
02615                 continue;
02616               }
02617 
02618              if (ELF32_R_SYM (irelcall->r_info) < symtab_hdr->sh_info)
02619               {
02620                 Elf_Internal_Sym *  isym;
02621 
02622                 /* A local symbol.  */
02623                 isym = isymbuf + ELF32_R_SYM (irelcall->r_info);
02624 
02625                 symval = isym->st_value;
02626               }
02627              else
02628               {
02629                 unsigned long indx;
02630                 struct elf_link_hash_entry * h;
02631 
02632                 /* An external symbol.  */
02633                 indx = ELF32_R_SYM (irelcall->r_info) - symtab_hdr->sh_info;
02634                 h = elf_sym_hashes (abfd)[indx];
02635                 BFD_ASSERT (h != NULL);
02636 
02637                 if (   h->root.type != bfd_link_hash_defined
02638                     && h->root.type != bfd_link_hash_defweak)
02639                   /* This appears to be a reference to an undefined
02640                      symbol.  Just ignore it--it will be caught by the
02641                      regular reloc processing.  */
02642                   continue;
02643 
02644                 symval = h->root.u.def.value;
02645               }
02646 
02647              if (symval + irelcall->r_addend != irelcall->r_offset + 4)
02648               {
02649                 ((*_bfd_error_handler)
02650                  ("%s: 0x%lx: warning: R_V850_LONGCALL points to unrecognized reloc 0x%lx",
02651                   bfd_get_filename (abfd), (unsigned long) irel->r_offset, irelcall->r_offset ));
02652 
02653                 continue;
02654               }
02655 
02656              /* Get the value of the symbol referred to by the reloc.  */
02657              if (ELF32_R_SYM (hi_irelfn->r_info) < symtab_hdr->sh_info)
02658               {
02659                 Elf_Internal_Sym *isym;
02660                 asection *sym_sec;
02661 
02662                 /* A local symbol.  */
02663                 isym = isymbuf + ELF32_R_SYM (hi_irelfn->r_info);
02664 
02665                 if (isym->st_shndx == SHN_UNDEF)
02666                   sym_sec = bfd_und_section_ptr;
02667                 else if (isym->st_shndx == SHN_ABS)
02668                   sym_sec = bfd_abs_section_ptr;
02669                 else if (isym->st_shndx == SHN_COMMON)
02670                   sym_sec = bfd_com_section_ptr;
02671                 else
02672                   sym_sec = bfd_section_from_elf_index (abfd, isym->st_shndx);
02673                 symval = (isym->st_value
02674                          + sym_sec->output_section->vma
02675                          + sym_sec->output_offset);
02676               }
02677              else
02678               {
02679                 unsigned long indx;
02680                 struct elf_link_hash_entry *h;
02681 
02682                 /* An external symbol.  */
02683                 indx = ELF32_R_SYM (hi_irelfn->r_info) - symtab_hdr->sh_info;
02684                 h = elf_sym_hashes (abfd)[indx];
02685                 BFD_ASSERT (h != NULL);
02686 
02687                 if (   h->root.type != bfd_link_hash_defined
02688                     && h->root.type != bfd_link_hash_defweak)
02689                   /* This appears to be a reference to an undefined
02690                      symbol.  Just ignore it--it will be caught by the
02691                      regular reloc processing.  */
02692                   continue;
02693 
02694                 symval = (h->root.u.def.value
02695                          + h->root.u.def.section->output_section->vma
02696                          + h->root.u.def.section->output_offset);
02697               }
02698 
02699              addend = irel->r_addend;
02700 
02701              foff = (symval + addend
02702                     - (irel->r_offset
02703                       + sec->output_section->vma
02704                       + sec->output_offset
02705                       + 4));
02706 #ifdef DEBUG_RELAX
02707              fprintf (stderr, "relax longcall r_offset 0x%x ptr 0x%x symbol 0x%x addend 0x%x distance 0x%x\n",
02708                      irel->r_offset,
02709                      (irel->r_offset
02710                      + sec->output_section->vma
02711                      + sec->output_offset),
02712                      symval, addend, foff);
02713 #endif
02714 
02715              if (foff < -0x100000 || foff >= 0x100000)
02716               /* After all that work, we can't shorten this function call.  */
02717               continue;
02718 
02719              /* For simplicity of coding, we are going to modify the section
02720                 contents, the section relocs, and the BFD symbol table.  We
02721                 must tell the rest of the code not to free up this
02722                 information.  It would be possible to instead create a table
02723                 of changes which have to be made, as is done in coff-mips.c;
02724                 that would be more work, but would require less memory when
02725                 the linker is run.  */
02726              elf_section_data (sec)->relocs = internal_relocs;
02727              elf_section_data (sec)->this_hdr.contents = contents;
02728              symtab_hdr->contents = (bfd_byte *) isymbuf;
02729 
02730              /* Replace the long call with a jarl.  */
02731              irel->r_info = ELF32_R_INFO (ELF32_R_SYM (hi_irelfn->r_info), R_V850_22_PCREL);
02732 
02733              addend = 0;
02734 
02735              if (ELF32_R_SYM (hi_irelfn->r_info) < symtab_hdr->sh_info)
02736               /* If this needs to be changed because of future relaxing,
02737                  it will be handled here like other internal IND12W
02738                  relocs.  */
02739               bfd_put_32 (abfd,
02740                          0x00000780 | (JARL_R2 (insn[2])<<11) | ((addend << 16) & 0xffff) | ((addend >> 16) & 0xf),
02741                          contents + irel->r_offset);
02742              else
02743               /* We can't fully resolve this yet, because the external
02744                  symbol value may be changed by future relaxing.
02745                  We let the final link phase handle it.  */
02746               bfd_put_32 (abfd, 0x00000780 | (JARL_R2 (insn[2])<<11),
02747                          contents + irel->r_offset);
02748 
02749              hi_irelfn->r_info =
02750               ELF32_R_INFO (ELF32_R_SYM (hi_irelfn->r_info), R_V850_NONE);
02751              lo_irelfn->r_info =
02752               ELF32_R_INFO (ELF32_R_SYM (lo_irelfn->r_info), R_V850_NONE);
02753              irelcall->r_info =
02754               ELF32_R_INFO (ELF32_R_SYM (irelcall->r_info), R_V850_NONE);
02755 
02756              if (! v850_elf_relax_delete_bytes (abfd, sec,
02757                                            irel->r_offset + 4, toaddr, 12))
02758               goto error_return;
02759 
02760              align_pad_size += 12;
02761            }
02762          else if (ELF32_R_TYPE (irel->r_info) == (int) R_V850_LONGJUMP)
02763            {
02764              /* Check code for -mlong-jumps output.  */
02765              if (laddr + 10 <= (bfd_vma) sec->size)
02766               {
02767                 insn[0] = bfd_get_16 (abfd, contents + laddr);
02768                 insn[1] = bfd_get_16 (abfd, contents + laddr + 4);
02769                 insn[2] = bfd_get_16 (abfd, contents + laddr + 8);
02770 
02771                 if ((insn[0] & MOVHI_MASK) != MOVHI
02772                      || MOVHI_R1 (insn[0]) != 0)
02773                   no_match = 0;
02774 
02775                 if (no_match < 0
02776                     && ((insn[1] & MOVEA_MASK) != MOVEA
02777                         || MOVHI_R2 (insn[0]) != MOVEA_R1 (insn[1])))
02778                   no_match = 1;
02779 
02780                 if (no_match < 0
02781                     && ((insn[2] & JMP_R_MASK) != JMP_R
02782                         || MOVEA_R2 (insn[1]) != JMP_R1 (insn[2])))
02783                   no_match = 4;
02784               }
02785              else
02786               {
02787                 ((*_bfd_error_handler)
02788                  ("%s: 0x%lx: warning: R_V850_LONGJUMP points to unrecognized insns",
02789                   bfd_get_filename (abfd), (unsigned long) irel->r_offset));
02790 
02791                 continue;
02792               }
02793 
02794              if (no_match >= 0)
02795               {
02796                 ((*_bfd_error_handler)
02797                  ("%s: 0x%lx: warning: R_V850_LONGJUMP points to unrecognized insn 0x%x",
02798                   bfd_get_filename (abfd), (unsigned long) irel->r_offset+no_match, insn[no_match]));
02799 
02800                 continue;
02801               }
02802 
02803              /* Get the reloc for the address from which the register is
02804                 being loaded.  This reloc will tell us which function is
02805                 actually being called.  */
02806              for (hi_irelfn = internal_relocs; hi_irelfn < irelend; hi_irelfn ++)
02807               if (hi_irelfn->r_offset == laddr + 2
02808                   && ELF32_R_TYPE (hi_irelfn->r_info) == (int) R_V850_HI16_S)
02809                 break;
02810 
02811              for (lo_irelfn = internal_relocs; lo_irelfn < irelend; lo_irelfn ++)
02812               if (lo_irelfn->r_offset == laddr + 6
02813                   && ELF32_R_TYPE (lo_irelfn->r_info) == (int) R_V850_LO16)
02814                 break;
02815 
02816              if (   hi_irelfn == irelend
02817                 || lo_irelfn == irelend)
02818               {
02819                 ((*_bfd_error_handler)
02820                  ("%s: 0x%lx: warning: R_V850_LONGJUMP points to unrecognized reloc",
02821                   bfd_get_filename (abfd), (unsigned long) irel->r_offset ));
02822 
02823                 continue;
02824               }
02825 
02826              /* Get the value of the symbol referred to by the reloc.  */
02827              if (ELF32_R_SYM (hi_irelfn->r_info) < symtab_hdr->sh_info)
02828               {
02829                 Elf_Internal_Sym *  isym;
02830                 asection *          sym_sec;
02831 
02832                 /* A local symbol.  */
02833                 isym = isymbuf + ELF32_R_SYM (hi_irelfn->r_info);
02834 
02835                 if (isym->st_shndx == SHN_UNDEF)
02836                   sym_sec = bfd_und_section_ptr;
02837                 else if (isym->st_shndx == SHN_ABS)
02838                   sym_sec = bfd_abs_section_ptr;
02839                 else if (isym->st_shndx == SHN_COMMON)
02840                   sym_sec = bfd_com_section_ptr;
02841                 else
02842                   sym_sec = bfd_section_from_elf_index (abfd, isym->st_shndx);
02843                 symval = (isym->st_value
02844                          + sym_sec->output_section->vma
02845                          + sym_sec->output_offset);
02846 #ifdef DEBUG_RELAX
02847                 {
02848                   char * name = bfd_elf_string_from_elf_section
02849                     (abfd, symtab_hdr->sh_link, isym->st_name);
02850 
02851                   fprintf (stderr, "relax long jump local: sec: %s, sym: %s (%d), value: %x + %x + %x addend %x\n",
02852                           sym_sec->name, name, isym->st_name,
02853                           sym_sec->output_section->vma,
02854                           sym_sec->output_offset,
02855                           isym->st_value, irel->r_addend);
02856                 }
02857 #endif
02858               }
02859              else
02860               {
02861                 unsigned long indx;
02862                 struct elf_link_hash_entry * h;
02863 
02864                 /* An external symbol.  */
02865                 indx = ELF32_R_SYM (irel->r_info) - symtab_hdr->sh_info;
02866                 h = elf_sym_hashes (abfd)[indx];
02867                 BFD_ASSERT (h != NULL);
02868 
02869                 if (   h->root.type != bfd_link_hash_defined
02870                     && h->root.type != bfd_link_hash_defweak)
02871                   /* This appears to be a reference to an undefined
02872                      symbol.  Just ignore it--it will be caught by the
02873                      regular reloc processing.  */
02874                   continue;
02875 
02876                 symval = (h->root.u.def.value
02877                          + h->root.u.def.section->output_section->vma
02878                          + h->root.u.def.section->output_offset);
02879 #ifdef DEBUG_RELAX
02880                 fprintf (stderr,
02881                         "relax longjump defined: sec: %s, name: %s, value: %x + %x + %x addend %x\n",
02882                         sec->name, h->root.root.string, h->root.u.def.value,
02883                         sec->output_section->vma, sec->output_offset, irel->r_addend);
02884 #endif
02885               }
02886 
02887              addend = irel->r_addend;
02888 
02889              foff = (symval + addend
02890                     - (irel->r_offset
02891                       + sec->output_section->vma
02892                       + sec->output_offset
02893                       + 4));
02894 #ifdef DEBUG_RELAX
02895              fprintf (stderr, "relax longjump r_offset 0x%x ptr 0x%x symbol 0x%x addend 0x%x distance 0x%x\n",
02896                      irel->r_offset,
02897                      (irel->r_offset
02898                      + sec->output_section->vma
02899                      + sec->output_offset),
02900                      symval, addend, foff);
02901 #endif
02902              if (foff < -0x100000 || foff >= 0x100000)
02903               /* After all that work, we can't shorten this function call.  */
02904               continue;
02905 
02906              /* For simplicity of coding, we are going to modify the section
02907                 contents, the section relocs, and the BFD symbol table.  We
02908                 must tell the rest of the code not to free up this
02909                 information.  It would be possible to instead create a table
02910                 of changes which have to be made, as is done in coff-mips.c;
02911                 that would be more work, but would require less memory when
02912                 the linker is run.  */
02913              elf_section_data (sec)->relocs = internal_relocs;
02914              elf_section_data (sec)->this_hdr.contents = contents;
02915              symtab_hdr->contents = (bfd_byte *) isymbuf;
02916 
02917              if (foff < -0x100 || foff >= 0x100)
02918               {
02919                 /* Replace the long jump with a jr.  */
02920 
02921                 irel->r_info =
02922                   ELF32_R_INFO (ELF32_R_SYM (irel->r_info), R_V850_22_PCREL);
02923 
02924                 irel->r_addend = addend;
02925                 addend = 0;
02926 
02927                 if (ELF32_R_SYM (hi_irelfn->r_info) < symtab_hdr->sh_info)
02928                   /* If this needs to be changed because of future relaxing,
02929                      it will be handled here like other internal IND12W
02930                      relocs.  */
02931                   bfd_put_32 (abfd,
02932                             0x00000780 | ((addend << 15) & 0xffff0000) | ((addend >> 17) & 0xf),
02933                             contents + irel->r_offset);
02934                 else
02935                   /* We can't fully resolve this yet, because the external
02936                      symbol value may be changed by future relaxing.
02937                      We let the final link phase handle it.  */
02938                   bfd_put_32 (abfd, 0x00000780, contents + irel->r_offset);
02939 
02940                 hi_irelfn->r_info =
02941                      ELF32_R_INFO (ELF32_R_SYM (hi_irelfn->r_info), R_V850_NONE);
02942                 lo_irelfn->r_info =
02943                      ELF32_R_INFO (ELF32_R_SYM (lo_irelfn->r_info), R_V850_NONE);
02944                 if (!v850_elf_relax_delete_bytes (abfd, sec,
02945                                               irel->r_offset + 4, toaddr, 6))
02946                   goto error_return;
02947 
02948                 align_pad_size += 6;
02949               }
02950              else
02951               {
02952                 /* Replace the long jump with a br.  */
02953 
02954                 irel->r_info =
02955                      ELF32_R_INFO (ELF32_R_SYM (irel->r_info), R_V850_9_PCREL);
02956 
02957                 irel->r_addend = addend;
02958                 addend = 0;
02959 
02960                 if (ELF32_R_SYM (hi_irelfn->r_info) < symtab_hdr->sh_info)
02961                   /* If this needs to be changed because of future relaxing,
02962                      it will be handled here like other internal IND12W
02963                      relocs.  */
02964                   bfd_put_16 (abfd,
02965                             0x0585 | ((addend << 10) & 0xf800) | ((addend << 3) & 0x0070),
02966                             contents + irel->r_offset);
02967                 else
02968                   /* We can't fully resolve this yet, because the external
02969                      symbol value may be changed by future relaxing.
02970                      We let the final link phase handle it.  */
02971                   bfd_put_16 (abfd, 0x0585, contents + irel->r_offset);
02972 
02973                 hi_irelfn->r_info =
02974                      ELF32_R_INFO (ELF32_R_SYM (hi_irelfn->r_info), R_V850_NONE);
02975                 lo_irelfn->r_info =
02976                      ELF32_R_INFO (ELF32_R_SYM (lo_irelfn->r_info), R_V850_NONE);
02977                 if (!v850_elf_relax_delete_bytes (abfd, sec,
02978                                               irel->r_offset + 2, toaddr, 8))
02979                   goto error_return;
02980 
02981                 align_pad_size += 8;
02982               }
02983            }
02984        }
02985 
02986       irelalign = NULL;
02987       for (irel = internal_relocs; irel < irelend; irel++)
02988        {
02989          if (ELF32_R_TYPE (irel->r_info) == (int) R_V850_ALIGN
02990              && irel->r_offset == toaddr)
02991            {
02992              irel->r_offset -= align_pad_size;
02993 
02994              if (irelalign == NULL || irelalign->r_addend > irel->r_addend)
02995               irelalign = irel;
02996            }
02997        }
02998 
02999       addr = toaddr;
03000     }
03001 
03002   if (!irelalign)
03003     {
03004 #ifdef DEBUG_RELAX
03005       fprintf (stderr, "relax pad %d shorten %d -> %d\n",
03006               align_pad_size,
03007               sec->size,
03008               sec->size - align_pad_size);
03009 #endif
03010       sec->size -= align_pad_size;
03011     }
03012 
03013  finish:
03014   if (internal_relocs != NULL
03015       && elf_section_data (sec)->relocs != internal_relocs)
03016     free (internal_relocs);
03017 
03018   if (contents != NULL
03019       && elf_section_data (sec)->this_hdr.contents != (unsigned char *) contents)
03020     free (contents);
03021 
03022   if (isymbuf != NULL
03023       && symtab_hdr->contents != (bfd_byte *) isymbuf)
03024     free (isymbuf);
03025 
03026   return result;
03027 
03028  error_return:
03029   result = FALSE;
03030   goto finish;
03031 }
03032 
03033 static const struct bfd_elf_special_section v850_elf_special_sections[] =
03034 {
03035   { STRING_COMMA_LEN (".call_table_data"), 0, SHT_PROGBITS,     (SHF_ALLOC + SHF_WRITE) },
03036   { STRING_COMMA_LEN (".call_table_text"), 0, SHT_PROGBITS,     (SHF_ALLOC + SHF_WRITE
03037                                                          + SHF_EXECINSTR) },
03038   { STRING_COMMA_LEN (".rosdata"),        -2, SHT_PROGBITS,     (SHF_ALLOC
03039                                                          + SHF_V850_GPREL) },
03040   { STRING_COMMA_LEN (".rozdata"),        -2, SHT_PROGBITS,     (SHF_ALLOC
03041                                                          + SHF_V850_R0REL) },
03042   { STRING_COMMA_LEN (".sbss"),           -2, SHT_NOBITS,       (SHF_ALLOC + SHF_WRITE
03043                                                          + SHF_V850_GPREL) },
03044   { STRING_COMMA_LEN (".scommon"),        -2, SHT_V850_SCOMMON, (SHF_ALLOC + SHF_WRITE
03045                                                          + SHF_V850_GPREL) },
03046   { STRING_COMMA_LEN (".sdata"),          -2, SHT_PROGBITS,     (SHF_ALLOC + SHF_WRITE
03047                                                          + SHF_V850_GPREL) },
03048   { STRING_COMMA_LEN (".tbss"),           -2, SHT_NOBITS,       (SHF_ALLOC + SHF_WRITE
03049                                                          + SHF_V850_EPREL) },
03050   { STRING_COMMA_LEN (".tcommon"),        -2, SHT_V850_TCOMMON, (SHF_ALLOC + SHF_WRITE
03051                                                          + SHF_V850_R0REL) },
03052   { STRING_COMMA_LEN (".tdata"),          -2, SHT_PROGBITS,     (SHF_ALLOC + SHF_WRITE
03053                                                          + SHF_V850_EPREL) },
03054   { STRING_COMMA_LEN (".zbss"),           -2, SHT_NOBITS,       (SHF_ALLOC + SHF_WRITE
03055                                                          + SHF_V850_R0REL) },
03056   { STRING_COMMA_LEN (".zcommon"),        -2, SHT_V850_ZCOMMON, (SHF_ALLOC + SHF_WRITE
03057                                                          + SHF_V850_R0REL) },
03058   { STRING_COMMA_LEN (".zdata"),          -2, SHT_PROGBITS,     (SHF_ALLOC + SHF_WRITE
03059                                                          + SHF_V850_R0REL) },
03060   { NULL,                     0,           0, 0,                0 }
03061 };
03062 
03063 #define TARGET_LITTLE_SYM                 bfd_elf32_v850_vec
03064 #define TARGET_LITTLE_NAME                "elf32-v850"
03065 #define ELF_ARCH                          bfd_arch_v850
03066 #define ELF_MACHINE_CODE                  EM_V850
03067 #define ELF_MACHINE_ALT1                  EM_CYGNUS_V850
03068 #define ELF_MACHINE_ALT2                  EM_V800 /* This is the value used by the GreenHills toolchain.  */
03069 #define ELF_MAXPAGESIZE                          0x1000
03070 
03071 #define elf_info_to_howto                 v850_elf_info_to_howto_rela
03072 #define elf_info_to_howto_rel                    v850_elf_info_to_howto_rel
03073 
03074 #define elf_backend_check_relocs          v850_elf_check_relocs
03075 #define elf_backend_relocate_section      v850_elf_relocate_section
03076 #define elf_backend_object_p                     v850_elf_object_p
03077 #define elf_backend_final_write_processing       v850_elf_final_write_processing
03078 #define elf_backend_section_from_bfd_section     v850_elf_section_from_bfd_section
03079 #define elf_backend_symbol_processing            v850_elf_symbol_processing
03080 #define elf_backend_add_symbol_hook              v850_elf_add_symbol_hook
03081 #define elf_backend_link_output_symbol_hook      v850_elf_link_output_symbol_hook
03082 #define elf_backend_section_from_shdr            v850_elf_section_from_shdr
03083 #define elf_backend_fake_sections         v850_elf_fake_sections
03084 #define elf_backend_gc_mark_hook                v850_elf_gc_mark_hook
03085 #define elf_backend_special_sections             v850_elf_special_sections
03086 
03087 #define elf_backend_can_gc_sections 1
03088 #define elf_backend_rela_normal 1
03089 
03090 #define bfd_elf32_bfd_is_local_label_name v850_elf_is_local_label_name
03091 #define bfd_elf32_bfd_reloc_type_lookup          v850_elf_reloc_type_lookup
03092 #define bfd_elf32_bfd_reloc_name_lookup   v850_elf_reloc_name_lookup
03093 #define bfd_elf32_bfd_merge_private_bfd_data     v850_elf_merge_private_bfd_data
03094 #define bfd_elf32_bfd_set_private_flags          v850_elf_set_private_flags
03095 #define bfd_elf32_bfd_print_private_bfd_data     v850_elf_print_private_bfd_data
03096 #define bfd_elf32_bfd_relax_section              v850_elf_relax_section
03097 
03098 #define elf_symbol_leading_char                  '_'
03099 
03100 #include "elf32-target.h"