This is the mail archive of the binutils@sources.redhat.com mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Add v850 linker relaxation


Hi Guys,

  I am applying the attached patch which adds linker relaxation to the
  v850 toolchain.  It also removes the redundant references to the
  v850ea architecture.  The patch was developed a while ago and we now
  have permission to release it to the free software community.

Cheers
        Nick

bfd/ChangeLog
2002-08-28  Catherine Moore  <clm@redhat.com>

	* elf32-v850.c (v850_elf_reloc_map):  Add new relocs.
	(v850-elf-reloc): Don't resolve pc relative relocs.
	(v850_elf_ignore_reloc): New routine.
	(v850_elf_final_link_relocate): Handle new relocs.
	(v850_elf_relax_delete_bytes ): New routine.
	(v850_elf_relax_section): New routine.
	(bfd_elf32_bfd_relax_section): Define.
	(HOWTO): New entries for new relocs.
	* reloc.c (BFD_RELOC_V850_LONGCALL): New reloc.
	(BFD_RELOC_V850_LONGJUMP): New reloc.
	(BFD_RELOC_V850_ALIGN): New reloc.
	* archures.c: Remove redundant v850ea architecture.
	* cpu-v850.c: Remove redundant v850ea support.
	* libbfd.h: Regenerate.
	* bfd-in2.h: Regenerated.
        
gas/ChangeLog
2000-08-28  Catherine Moore  <clm@redhat.com>

	* tc-v850.c (v850_relax): Declare.
	(v850_longcode): New routine.
	(v850_handle_align): New routine.
	(md_pseudo_table):  Add longcall and longjump.
	(md_parse_option): Check for relax option.
	(tc_gen_reloc):  Handle BFD_RELOC_V850_LONGCALL,
	BFD_RELOC_V850_LONGJUMP, and BFD_RELOC_V850_ALIGN.
	(md_apply_fix3): Likewise.
	(v850_force_relocation): Likewise.
	(v850_comm): Change the current section.
	(md_assemble):  Ensure that the	correct value is put in the
	fixup.
	(v850_sdata, v850_tdata, v850_zdata, v850_sbss, v850_tbss,
	v850_zbss, v850_rosdata, v850_rozdata): Fix section book keeping.
        Remove redundant v850ea support.
	* tc-v850.h (HANDLE_ALIGN): Define.
	(v850_handle_align): Declare.
	* doc/c-v850.c: Document -mrelax, .longcall and .longjump.

include/elf/ChangeLog
2002-08-28  Catherine Moore  <clm@redhat.com>

	* elf/v850.h (R_V850_LONGCALL, R_V850_ALIGN,
	R_V850_LONGJUMP): New relocations.

Index: bfd/archures.c
===================================================================
RCS file: /cvs/src/src/bfd/archures.c,v
retrieving revision 1.54
diff -c -3 -p -w -r1.54 archures.c
*** bfd/archures.c	28 Aug 2002 10:38:44 -0000	1.54
--- bfd/archures.c	29 Aug 2002 06:43:10 -0000
*************** DESCRIPTION
*** 236,242 ****
  .  bfd_arch_v850,      {* NEC V850 *}
  .#define bfd_mach_v850          0
  .#define bfd_mach_v850e 	'E'
- .#define bfd_mach_v850ea	'A'
  .  bfd_arch_arc,       {* ARC Cores *}
  .#define bfd_mach_arc_5         0
  .#define bfd_mach_arc_6         1
--- 236,241 ----

Index: bfd/cpu-v850.c
===================================================================
RCS file: /cvs/src/src/bfd/cpu-v850.c,v
retrieving revision 1.5
diff -c -3 -p -w -r1.5 cpu-v850.c
*** bfd/cpu-v850.c	19 Sep 2001 05:33:12 -0000	1.5
--- bfd/cpu-v850.c	29 Aug 2002 06:43:12 -0000
***************
*** 1,5 ****
  /* BFD support for the NEC V850 processor
!    Copyright 1996, 1997, 1998, 2000, 2001 Free Software Foundation, Inc.
  
  This file is part of BFD, the Binary File Descriptor library.
  
--- 1,5 ----
  /* BFD support for the NEC V850 processor
!    Copyright 1996, 1997, 1998, 2000, 2001, 2002 Free Software Foundation, Inc.
  
     This file is part of BFD, the Binary File Descriptor library.
  
*************** scan (info, string)
*** 67,73 ****
    switch (number)
      {
      case bfd_mach_v850e:  arch = bfd_arch_v850; break;
-     case bfd_mach_v850ea: arch = bfd_arch_v850; break;
      default:
        return false;
      }
--- 67,72 ----
*************** scan (info, string)
*** 89,96 ****
  
  static const bfd_arch_info_type arch_info_struct[] =
  {
!   N (bfd_mach_v850e,  "v850e",  false, & arch_info_struct[1]),
!   N (bfd_mach_v850ea, "v850ea", false, NULL)
  };
  
  #undef  NEXT
--- 88,94 ----
  
  static const bfd_arch_info_type arch_info_struct[] =
  {
!   N (bfd_mach_v850e,  "v850e",  false, NULL)
  };
  
  #undef  NEXT

Index: bfd/elf32-v850.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-v850.c,v
retrieving revision 1.24
diff -c -3 -p -w -r1.24 elf32-v850.c
*** bfd/elf32-v850.c	23 Jul 2002 12:29:32 -0000	1.24
--- bfd/elf32-v850.c	29 Aug 2002 06:43:12 -0000
*************** along with this program; if not, write t
*** 19,25 ****
  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
  
  /* XXX FIXME: This code is littered with 32bit int, 16bit short, 8bit char
!    dependencies.  As is the gas & simulator code or the v850.  */
  
  #include "bfd.h"
  #include "sysdep.h"
--- 19,25 ----
     Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
  
  /* XXX FIXME: This code is littered with 32bit int, 16bit short, 8bit char
!    dependencies.  As is the gas & simulator code for the v850.  */
  
  #include "bfd.h"
  #include "sysdep.h"
*************** static asection * v850_elf_gc_mark_hook
*** 87,92 ****
--- 87,98 ----
    PARAMS ((asection *, struct bfd_link_info *,
  	   Elf_Internal_Rela *, struct elf_link_hash_entry *,
  	   Elf_Internal_Sym *));
+ static bfd_reloc_status_type v850_elf_ignore_reloc
+   PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
+ static boolean v850_elf_relax_delete_bytes
+   PARAMS ((bfd *, asection *, bfd_vma, bfd_vma, int));
+ static boolean v850_elf_relax_section
+   PARAMS ((bfd *, asection *, struct bfd_link_info *, boolean *));
  
  /* Note: It is REQUIRED that the 'type' value of each entry
     in this array match the index of the entry in the array.  */
*************** static reloc_howto_type v850_elf_howto_t
*** 467,472 ****
--- 473,523 ----
           0,                     /* dst_mask */
           false),                /* pcrel_offset */
  
+   /* Indicates a .longcall pseudo-op.  The compiler will generate a .longcall
+      pseudo-op when it finds a function call which can be relaxed.  */
+   HOWTO (R_V850_LONGCALL,     /* type */
+        0,                     /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        32,                    /* bitsize */
+        true,                  /* pc_relative */
+        0,                     /* bitpos */
+        complain_overflow_signed, /* complain_on_overflow */
+        v850_elf_ignore_reloc, /* special_function */
+        "R_V850_LONGCALL",     /* name */
+        false,                 /* partial_inplace */
+        0,                     /* src_mask */
+        0,                     /* dst_mask */
+        true),                 /* pcrel_offset */
+ 
+   /* Indicates a .longjump pseudo-op.  The compiler will generate a
+      .longjump pseudo-op when it finds a branch which can be relaxed.  */
+   HOWTO (R_V850_LONGJUMP,     /* type */
+        0,                     /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        32,                    /* bitsize */
+        true,                  /* pc_relative */
+        0,                     /* bitpos */
+        complain_overflow_signed, /* complain_on_overflow */
+        v850_elf_ignore_reloc, /* special_function */
+        "R_V850_LONGJUMP",     /* name */
+        false,                 /* partial_inplace */
+        0,                     /* src_mask */
+        0,                     /* dst_mask */
+        true),                 /* pcrel_offset */
+ 
+   HOWTO (R_V850_ALIGN,        /* type */
+        0,                     /* rightshift */
+        1,                     /* size (0 = byte, 1 = short, 2 = long) */
+        0,                     /* bitsize */
+        false,                 /* pc_relative */
+        0,                     /* bitpos */
+        complain_overflow_unsigned, /* complain_on_overflow */
+        v850_elf_ignore_reloc, /* special_function */
+        "R_V850_ALIGN",        /* name */
+        false,                 /* partial_inplace */
+        0,                     /* src_mask */
+        0,                     /* dst_mask */
+        true),                 /* pcrel_offset */
  };
  
  /* Map BFD reloc types to V850 ELF reloc types.  */
*************** static const struct v850_elf_reloc_map v
*** 506,511 ****
--- 557,565 ----
    { BFD_RELOC_V850_CALLT_16_16_OFFSET,     R_V850_CALLT_16_16_OFFSET     },
    { BFD_RELOC_VTABLE_INHERIT,              R_V850_GNU_VTINHERIT          },
    { BFD_RELOC_VTABLE_ENTRY,                R_V850_GNU_VTENTRY            },
+   { BFD_RELOC_V850_LONGCALL,               R_V850_LONGCALL               },
+   { BFD_RELOC_V850_LONGJUMP,               R_V850_LONGJUMP               },
+   { BFD_RELOC_V850_ALIGN,                  R_V850_ALIGN                  },
  
  };
  
*************** v850_elf_reloc (abfd, reloc, symbol, dat
*** 1297,1302 ****
--- 1351,1359 ----
    /* Work out which section the relocation is targetted at and the
       initial relocation command value.  */
  
+   if (reloc->howto->pc_relative == true)
+     return bfd_reloc_ok;
+ 
    /* Get symbol value.  (Common symbols are special.)  */
    if (bfd_is_com_section (symbol->section))
      relocation = 0;
*************** v850_elf_reloc (abfd, reloc, symbol, dat
*** 1336,1341 ****
--- 1393,1418 ----
    return bfd_reloc_ok;
  }
  
+ /* This function is used for relocs which are only used
+    for relaxing, which the linker should otherwise ignore.  */
+ 
+ static bfd_reloc_status_type
+ v850_elf_ignore_reloc (abfd, reloc_entry, symbol, data, input_section,
+                        output_bfd, error_message)
+      bfd *      abfd ATTRIBUTE_UNUSED;
+      arelent *  reloc_entry;
+      asymbol *  symbol ATTRIBUTE_UNUSED;
+      PTR        data ATTRIBUTE_UNUSED;
+      asection * input_section;
+      bfd *      output_bfd;
+      char **    error_message ATTRIBUTE_UNUSED;
+ {
+   if (output_bfd != NULL)
+     reloc_entry->address += input_section->output_offset;
+ 
+   return bfd_reloc_ok;
+ }
+ 
  static boolean
  v850_elf_is_local_label_name (abfd, name)
       bfd *         abfd ATTRIBUTE_UNUSED;
*************** v850_elf_final_link_relocate (howto, inp
*** 1500,1505 ****
--- 1577,1585 ----
      case R_V850_NONE:
      case R_V850_GNU_VTINHERIT:
      case R_V850_GNU_VTENTRY:
+     case R_V850_LONGCALL:
+     case R_V850_LONGJUMP:
+     case R_V850_ALIGN:
        return bfd_reloc_ok;
  
      default:
*************** v850_elf_object_p (abfd)
*** 1770,1776 ****
      default:
      case E_V850_ARCH:   (void) bfd_default_set_arch_mach (abfd, bfd_arch_v850, 0); break;
      case E_V850E_ARCH:  (void) bfd_default_set_arch_mach (abfd, bfd_arch_v850, bfd_mach_v850e); break;
-     case E_V850EA_ARCH: (void) bfd_default_set_arch_mach (abfd, bfd_arch_v850, bfd_mach_v850ea); break;
      }
    return true;
  }
--- 1850,1855 ----
*************** v850_elf_final_write_processing (abfd, l
*** 1789,1795 ****
      default:
      case 0: val = E_V850_ARCH; break;
      case bfd_mach_v850e:  val = E_V850E_ARCH; break;
-     case bfd_mach_v850ea: val = E_V850EA_ARCH;  break;
      }
  
    elf_elfheader (abfd)->e_flags &=~ EF_V850_ARCH;
--- 1868,1873 ----
*************** v850_elf_print_private_bfd_data (abfd, p
*** 1882,1888 ****
      default:
      case E_V850_ARCH: fprintf (file, _("v850 architecture")); break;
      case E_V850E_ARCH:  fprintf (file, _("v850e architecture")); break;
-     case E_V850EA_ARCH: fprintf (file, _("v850ea architecture")); break;
      }
  
    fputc ('\n', file);
--- 1960,1965 ----
*************** v850_elf_fake_sections (abfd, hdr, sec)
*** 2167,2172 ****
--- 2244,3182 ----
    return true;
  }
  
+ /* Delete some bytes from a section while relaxing.  */
+ 
+ static boolean
+ v850_elf_relax_delete_bytes (abfd, sec, addr, toaddr, count)
+      bfd *      abfd;
+      asection * sec;
+      bfd_vma    addr;
+      bfd_vma    toaddr;
+      int        count;
+ {
+   Elf_Internal_Shdr *		symtab_hdr;
+   Elf32_External_Sym *		extsyms;
+   Elf32_External_Sym *         	esym;
+   Elf32_External_Sym *         	esymend;
+   int 				index;
+   unsigned int 			sec_shndx;
+   bfd_byte *                   	contents;
+   Elf_Internal_Rela *          	irel;
+   Elf_Internal_Rela *          	irelend;
+   struct elf_link_hash_entry * 	sym_hash;
+   Elf_Internal_Shdr *           shndx_hdr;
+   Elf_External_Sym_Shndx *      shndx;
+ 
+   symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
+   extsyms = (Elf32_External_Sym *) symtab_hdr->contents;
+ 
+   sec_shndx = _bfd_elf_section_from_bfd_section (abfd, sec);
+ 
+   contents = elf_section_data (sec)->this_hdr.contents;
+ 
+   /* The deletion must stop at the next ALIGN reloc for an alignment
+      power larger than the number of bytes we are deleting.  */
+ 
+   /* Actually delete the bytes.  */
+ #if (DEBUG_RELAX & 2)
+   fprintf (stderr, "relax_delete: contents: sec: %s  %p .. %p %x\n",
+ 	   sec->name, addr, toaddr, count );
+ #endif
+   memmove (contents + addr, contents + addr + count,
+ 	   toaddr - addr - count);
+   memset (contents + toaddr-count, 0, count);
+ 
+   /* Adjust all the relocs.  */
+   irel = elf_section_data (sec)->relocs;
+   irelend = irel + sec->reloc_count;
+   shndx_hdr = &elf_tdata (abfd)->symtab_shndx_hdr;
+   shndx = (Elf_External_Sym_Shndx *) shndx_hdr->contents;
+ 
+   for (; irel < irelend; irel++)
+     {
+       bfd_vma raddr, paddr, symval;
+       Elf_Internal_Sym isym;
+ 
+       /* Get the new reloc address.  */
+       raddr = irel->r_offset;
+       if ((raddr >= (addr + count) && raddr < toaddr))
+ 	irel->r_offset -= count;	
+ 
+       if (raddr >= addr && raddr < addr + count)
+ 	{
+ 	  irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
+ 				       (int) R_V850_NONE);
+ 	  continue;
+ 	}
+       
+       if (ELF32_R_TYPE (irel->r_info) == (int) R_V850_ALIGN)
+ 	continue;
+ 
+       bfd_elf32_swap_symbol_in (abfd,
+ 				extsyms + ELF32_R_SYM (irel->r_info),
+ 				shndx ? shndx + ELF32_R_SYM (irel->r_info) : NULL,
+ 				& isym);
+       
+       if (isym.st_shndx != sec_shndx)
+ 	continue;
+ 
+       /* Get the value of the symbol referred to by the reloc.  */
+       if (ELF32_R_SYM (irel->r_info) < symtab_hdr->sh_info)
+ 	{
+ 	  symval = isym.st_value;
+ #if (DEBUG_RELAX & 2)
+ 	  {
+ 	    char * name = bfd_elf_string_from_elf_section
+ 	                   (abfd, symtab_hdr->sh_link, isym.st_name);
+ 	    fprintf (stderr,
+ 	       "relax_delete: local: sec: %s, sym: %s (%d), value: %x + %x + %x addend %x\n",
+ 	       sec->name, name, isym.st_name,
+ 	       sec->output_section->vma, sec->output_offset,
+ 	       isym.st_value, irel->r_addend);
+ 	  }
+ #endif
+ 	}
+       else
+ 	{
+ 	  unsigned long indx;
+ 	  struct elf_link_hash_entry * h;
+ 
+ 	  /* An external symbol.  */
+ 	  indx = ELF32_R_SYM (irel->r_info) - symtab_hdr->sh_info;
+ 
+ 	  h = elf_sym_hashes (abfd) [indx];
+ 	  BFD_ASSERT (h != NULL);
+ 
+ 	  symval = h->root.u.def.value;
+ #if (DEBUG_RELAX & 2)
+ 	  fprintf (stderr,
+ 		   "relax_delete: defined: sec: %s, name: %s, value: %x + %x + %x addend %x\n",
+ 		   sec->name, h->root.root.string, h->root.u.def.value,
+ 		   sec->output_section->vma, sec->output_offset, irel->r_addend);
+ #endif
+ 	}
+ 	      
+       paddr = symval + irel->r_addend;
+       
+       if ( (symval >= addr + count && symval < toaddr)
+ 	  && (paddr < addr + count || paddr >= toaddr))
+ 	irel->r_addend += count;
+       else if (    (symval < addr + count || symval >= toaddr)
+ 	        && (paddr >= addr + count && paddr < toaddr))
+ 	irel->r_addend -= count;
+     }
+ 
+   /* Adjust the local symbols defined in this section.  */
+   esym = extsyms;
+   esymend = esym + symtab_hdr->sh_info;
+ 
+   for (; esym < esymend; esym++, shndx = (shndx ? shndx + 1 : NULL))
+     {
+       Elf_Internal_Sym isym;
+ 
+       bfd_elf32_swap_symbol_in (abfd, esym, shndx, & isym);
+ 
+       if (isym.st_shndx == sec_shndx
+ 	  && isym.st_value >= addr + count
+ 	  && isym.st_value < toaddr)
+ 	{
+ 	  isym.st_value -= count;
+ 
+ 	  if (isym.st_value + isym.st_size >= toaddr)
+ 	    isym.st_size += count;	    
+ 	  
+ 	  bfd_elf32_swap_symbol_out (abfd, & isym, shndx, esym);
+ 	}
+       else if (isym.st_shndx == sec_shndx
+ 	       && isym.st_value < addr + count)
+ 	{
+ 	  if (isym.st_value+isym.st_size >= addr + count
+ 	      && isym.st_value+isym.st_size < toaddr)
+ 	    isym.st_size -= count;
+ 
+ 	  if (isym.st_value >= addr
+ 	      && isym.st_value <  addr + count)
+ 	    isym.st_value = addr;
+ 
+ 	  bfd_elf32_swap_symbol_out (abfd, & isym, shndx, esym);
+ 	}
+     }
+ 
+   /* Now adjust the global symbols defined in this section.  */
+   esym = extsyms + symtab_hdr->sh_info;
+   esymend = extsyms + (symtab_hdr->sh_size / sizeof (Elf32_External_Sym));
+ 
+   for (index = 0; esym < esymend; esym ++, index ++)
+     {
+       Elf_Internal_Sym isym;
+ 
+       bfd_elf32_swap_symbol_in (abfd, esym, shndx, & isym);
+       sym_hash = elf_sym_hashes (abfd) [index];
+ 
+       if (isym.st_shndx == sec_shndx
+ 	  && ((sym_hash)->root.type == bfd_link_hash_defined
+ 	      || (sym_hash)->root.type == bfd_link_hash_defweak)
+ 	  && (sym_hash)->root.u.def.section == sec
+ 	  && (sym_hash)->root.u.def.value >= addr + count
+ 	  && (sym_hash)->root.u.def.value < toaddr)
+ 	{
+ 	  if ((sym_hash)->root.u.def.value + isym.st_size >= toaddr)
+ 	    {
+ 	      isym.st_size += count;
+ 	      bfd_elf32_swap_symbol_out (abfd, & isym, shndx, esym);
+ 	    }
+ 
+ 	  (sym_hash)->root.u.def.value -= count;
+ 	}
+       else if (isym.st_shndx == sec_shndx
+ 	       && ((sym_hash)->root.type == bfd_link_hash_defined
+ 		   || (sym_hash)->root.type == bfd_link_hash_defweak)
+ 	       && (sym_hash)->root.u.def.section == sec
+ 	       && (sym_hash)->root.u.def.value < addr + count)
+ 	{
+ 	  if ((sym_hash)->root.u.def.value+isym.st_size >= addr + count
+ 	      && (sym_hash)->root.u.def.value+isym.st_size < toaddr)
+ 	    isym.st_size -= count;
+ 
+ 	  if ((sym_hash)->root.u.def.value >= addr
+ 	      && (sym_hash)->root.u.def.value < addr + count)
+ 	    (sym_hash)->root.u.def.value = addr;
+ 
+ 	  bfd_elf32_swap_symbol_out (abfd, & isym, shndx, esym);
+ 	}
+ 
+       if (shndx)
+ 	++ shndx;
+     }
+ 
+   return true;
+ }
+ 
+ #define NOP_OPCODE 	(0x0000)
+ #define MOVHI	    	0x0640				/* 4byte */ 
+ #define MOVHI_MASK  	0x07e0
+ #define MOVHI_R1(insn)	((insn) & 0x1f)			/* 4byte */ 
+ #define MOVHI_R2(insn)	((insn) >> 11)
+ #define MOVEA	    	0x0620				/* 2byte */
+ #define MOVEA_MASK  	0x07e0
+ #define MOVEA_R1(insn)	((insn) & 0x1f)
+ #define MOVEA_R2(insn)	((insn) >> 11)
+ #define JARL_4	    	0x00040780				/* 4byte */
+ #define JARL_4_MASK 	0xFFFF07FF
+ #define JARL_R2(insn)	(int)(((insn) & (~JARL_4_MASK)) >> 11)
+ #define ADD_I       	0x0240					/* 2byte */
+ #define ADD_I_MASK  	0x07e0
+ #define ADD_I5(insn)	((((insn) & 0x001f) << 11) >> 11)	/* 2byte */
+ #define ADD_R2(insn)	((insn) >> 11)
+ #define JMP_R	    	0x0060					/* 2byte */
+ #define JMP_R_MASK 	0xFFE0
+ #define JMP_R1(insn)	((insn) & 0x1f)
+ 
+ static boolean 
+ v850_elf_relax_section (abfd, sec, link_info, again)
+      bfd *			abfd;
+      asection *			sec;
+      struct bfd_link_info *	link_info;
+      boolean *			again;
+ {
+   Elf_Internal_Shdr *	    symtab_hdr;
+   Elf_Internal_Rela *	    internal_relocs;
+   Elf_Internal_Rela *	    free_relocs = NULL;
+   Elf_Internal_Rela *	    irel;
+   Elf_Internal_Rela *	    irelend;
+   Elf_Internal_Rela *	    irelalign = NULL;
+   bfd_byte *		    contents = NULL;
+   bfd_byte *		    free_contents = NULL;
+   Elf32_External_Sym *	    extsyms = NULL;
+   Elf32_External_Sym *	    free_extsyms = NULL;
+   bfd_vma 		    addr = 0;
+   bfd_vma		    toaddr;
+   int 			    align_pad_size = 0;
+   Elf_Internal_Shdr *       shndx_hdr = NULL;
+   Elf_External_Sym_Shndx *  shndx_buf = NULL;
+   
+   * again = false;
+ 
+   if (link_info->relocateable
+       || (sec->flags & SEC_RELOC) == 0
+       || sec->reloc_count == 0)
+     return true;
+ 
+   /* If this is the first time we have been called
+      for this section, initialize the cooked size.  */
+   if (sec->_cooked_size == 0)
+     sec->_cooked_size = sec->_raw_size;
+ 
+   symtab_hdr = & elf_tdata (abfd)->symtab_hdr;
+ 
+   internal_relocs = (_bfd_elf32_link_read_relocs
+ 		     (abfd, sec, (PTR) NULL, (Elf_Internal_Rela *) NULL,
+ 		      link_info->keep_memory));
+   if (internal_relocs == NULL)
+     goto error_return;
+   if (! link_info->keep_memory)
+     free_relocs = internal_relocs;
+ 
+   irelend = internal_relocs + sec->reloc_count;
+   
+   while (addr < sec->_cooked_size)
+     {
+       toaddr = sec->_cooked_size;
+ 
+       for (irel = internal_relocs; irel < irelend; irel ++)
+ 	if (ELF32_R_TYPE (irel->r_info) == (int) R_V850_ALIGN
+ 	    && irel->r_offset > addr
+ 	    && irel->r_offset < toaddr)
+ 	  toaddr = irel->r_offset;
+       
+ #ifdef DEBUG_RELAX
+       fprintf (stderr, "relax region 0x%x to 0x%x align pad %d\n",
+ 	       addr, toaddr, align_pad_size);
+ #endif
+       if (irelalign)
+ 	{
+ 	  bfd_vma alignto;
+ 	  bfd_vma alignmoveto;
+ 
+ 	  alignmoveto = BFD_ALIGN (addr - align_pad_size, 1 << irelalign->r_addend);
+ 	  alignto = BFD_ALIGN (addr, 1 << irelalign->r_addend);
+ 
+ 	  if (alignmoveto < alignto)
+ 	    {
+ 	      unsigned int i;
+ 
+ 	      align_pad_size = alignto - alignmoveto;
+ #ifdef DEBUG_RELAX
+ 	      fprintf (stderr, "relax move region 0x%x to 0x%x delete size 0x%x\n",
+ 		       alignmoveto, toaddr, align_pad_size);
+ #endif
+ 	      if (!v850_elf_relax_delete_bytes (abfd, sec, alignmoveto,
+ 						toaddr, align_pad_size))
+ 		goto error_return;		
+ 
+ 	      for (i  = BFD_ALIGN (toaddr - align_pad_size, 1);
+ 		   (i + 1) < toaddr; i += 2)
+ 		bfd_put_16 (abfd, NOP_OPCODE, contents + i);
+ 
+ 	      addr = alignmoveto;
+ 	    }
+ 	  else
+ 	    align_pad_size = 0;
+ 	}
+ 
+       for (irel = internal_relocs; irel < irelend; irel++)
+ 	{
+ 	  bfd_vma 	      laddr;
+ 	  bfd_vma	      addend;
+ 	  bfd_vma	      symval;
+ 	  int 		      insn[5];
+ 	  int 		      no_match = -1;
+ 	  Elf_Internal_Rela * hi_irelfn;
+ 	  Elf_Internal_Rela * lo_irelfn;
+ 	  Elf_Internal_Rela * irelcall;
+ 	  bfd_signed_vma      foff;
+ 
+ 	  if (! (irel->r_offset >= addr && irel->r_offset < toaddr
+ 		 && (ELF32_R_TYPE (irel->r_info) == (int) R_V850_LONGCALL
+ 		     || ELF32_R_TYPE (irel->r_info) == (int) R_V850_LONGJUMP)))
+ 	    continue;
+ 
+ #ifdef DEBUG_RELAX
+ 	  fprintf (stderr, "relax check r_info 0x%x r_offset 0x%x r_addend 0x%x\n",
+ 		   irel->r_info,
+ 		   irel->r_offset,
+ 		   irel->r_addend );
+ #endif
+ 
+ 	  /* Get the section contents.  */
+ 	  if (contents == NULL)
+ 	    {
+ 	      if (elf_section_data (sec)->this_hdr.contents != NULL)
+ 		contents = elf_section_data (sec)->this_hdr.contents;
+ 	      else
+ 		{
+ 		  contents = (bfd_byte *) bfd_malloc (sec->_raw_size);
+ 		  if (contents == NULL)
+ 		    goto error_return;
+ 
+ 		  free_contents = contents;
+ 
+ 		  if (! bfd_get_section_contents (abfd, sec, contents,
+ 						  (file_ptr) 0, sec->_raw_size))
+ 		    goto error_return;
+ 		}
+ 	    }
+ 
+ 	  /* Read this BFD's symbols if we haven't done so already.  */
+ 	  if (extsyms == NULL)
+ 	    {
+ 	      /* Get cached copy if it exists.  */
+ 	      if (symtab_hdr->contents != NULL)
+ 		extsyms = (Elf32_External_Sym *) symtab_hdr->contents;
+ 	      else
+ 		{
+ 		  /* Go get them off disk.  */
+ 		  bfd_size_type amt;
+ 
+ 		  amt = symtab_hdr->sh_info;
+ 		  amt *= sizeof (Elf32_External_Sym);
+ 		  extsyms = (Elf32_External_Sym *) bfd_malloc (amt);
+ 		  if (extsyms == NULL)
+ 		    goto error_return;
+ 		  free_extsyms = extsyms;
+ 		  if (bfd_seek (abfd, symtab_hdr->sh_offset, SEEK_SET) != 0
+ 		      || bfd_bread ((PTR) extsyms, amt, abfd) != amt)
+ 		    goto error_return;
+ 		}
+ 
+ 	      if (shndx_hdr->sh_size != 0)
+ 		{
+ 		  bfd_size_type amt;
+ 
+ 		  amt = symtab_hdr->sh_info;
+ 		  amt *= sizeof (Elf_External_Sym_Shndx);
+ 		  shndx_buf = (Elf_External_Sym_Shndx *) bfd_malloc (amt);
+ 		  if (shndx_buf == NULL)
+ 		    goto error_return;
+ 		  if (bfd_seek (abfd, shndx_hdr->sh_offset, SEEK_SET) != 0
+ 		      || bfd_bread ((PTR) shndx_buf, amt, abfd) != amt)
+ 		    goto error_return;
+ 		}
+ 	    }
+ 
+ 	  laddr = irel->r_offset;
+ 
+ 	  if (ELF32_R_TYPE (irel->r_info) == (int) R_V850_LONGCALL)
+ 	    {
+ 	      /* Check code for -mlong-calls output. */
+ 	      if (laddr + 16 <= (bfd_vma) sec->_raw_size)
+ 		{
+ 		  insn[0] = bfd_get_16 (abfd, contents + laddr);
+ 		  insn[1] = bfd_get_16 (abfd, contents + laddr + 4);
+ 		  insn[2] = bfd_get_32 (abfd, contents + laddr + 8);
+ 		  insn[3] = bfd_get_16 (abfd, contents + laddr + 12);
+ 		  insn[4] = bfd_get_16 (abfd, contents + laddr + 14);
+ 	  
+ 		  if ((insn[0] & MOVHI_MASK) != MOVHI
+ 		       || MOVHI_R1 (insn[0]) != 0)
+ 		    no_match = 0;
+ 
+ 		  if (no_match < 0
+ 		      && ((insn[1] & MOVEA_MASK) != MOVEA
+ 			   || MOVHI_R2 (insn[0]) != MOVEA_R1 (insn[1])))
+ 		    no_match = 1;
+ 
+ 		  if (no_match < 0
+ 		      && (insn[2] & JARL_4_MASK) != JARL_4)
+ 		    no_match = 2;
+ 
+ 		  if (no_match < 0
+ 		      && ((insn[3] & ADD_I_MASK) != ADD_I
+ 			   || ADD_I5 (insn[3]) != 4
+ 			   || JARL_R2 (insn[2]) != ADD_R2 (insn[3])))
+ 		    no_match = 3;
+ 
+ 		  if (no_match < 0
+ 		      && ((insn[4] & JMP_R_MASK) != JMP_R
+ 			   || MOVEA_R2 (insn[1]) != JMP_R1 (insn[4])))
+ 		    no_match = 4;
+ 		}
+ 	      else
+ 		{
+ 		  ((*_bfd_error_handler)
+ 		   ("%s: 0x%lx: warning: R_V850_LONGCALL points to unrecognized insns",
+ 		    bfd_get_filename (abfd), (unsigned long) irel->r_offset));
+ 
+ 		  continue;
+ 		}
+ 
+ 	      if (no_match >= 0)
+ 		{
+ 		  ((*_bfd_error_handler)
+ 		   ("%s: 0x%lx: warning: R_V850_LONGCALL points to unrecognized insn 0x%x",
+ 		    bfd_get_filename (abfd), (unsigned long) irel->r_offset+no_match, insn[no_match]));
+ 
+ 		  continue;
+ 		}      
+ 
+ 	      /* Get the reloc for the address from which the register is
+ 	         being loaded.  This reloc will tell us which function is
+ 	         actually being called.  */
+ 	      for (hi_irelfn = internal_relocs; hi_irelfn < irelend; hi_irelfn ++)
+ 		if (hi_irelfn->r_offset == laddr + 2
+ 		    && ELF32_R_TYPE (hi_irelfn->r_info) 
+ 		        == (int) R_V850_HI16_S)
+ 		  break;
+ 
+ 	      for (lo_irelfn = internal_relocs; lo_irelfn < irelend; lo_irelfn ++)
+ 		if (lo_irelfn->r_offset == laddr + 6
+ 		    && ELF32_R_TYPE (lo_irelfn->r_info)
+ 		        == (int) R_V850_LO16)
+ 		  break;
+ 
+ 	      for (irelcall = internal_relocs; irelcall < irelend; irelcall ++)
+ 		if (irelcall->r_offset == laddr + 8
+ 		    && ELF32_R_TYPE (irelcall->r_info)
+                         == (int) R_V850_22_PCREL)
+ 		  break;
+ 
+ 	      if (   hi_irelfn == irelend
+ 		  || lo_irelfn == irelend
+ 		  || irelcall  == irelend)
+ 		{
+ 		  ((*_bfd_error_handler)
+ 		   ("%s: 0x%lx: warning: R_V850_LONGCALL points to unrecognized reloc",
+ 		    bfd_get_filename (abfd), (unsigned long) irel->r_offset ));
+ 
+ 		  continue;
+ 		}
+ 	
+ 	      if (ELF32_R_SYM (irelcall->r_info) < symtab_hdr->sh_info)
+ 		{
+ 		  unsigned int		   r_index;
+ 		  Elf_Internal_Sym         isym;
+ 		  asection *               sym_sec;
+ 		  Elf32_External_Sym *     esym;
+ 		  Elf_External_Sym_Shndx * shndx;
+ 
+ 		  /* A local symbol.  */
+ 		  r_index = ELF32_R_SYM (irelcall->r_info);
+ 		  esym = extsyms + r_index;
+ 		  shndx = shndx_buf + (shndx_buf ? r_index : 0);
+ 		  bfd_elf32_swap_symbol_in (abfd, esym, shndx, & isym);
+ 
+ 		  if (isym.st_shndx == SHN_UNDEF)
+ 		    sym_sec = bfd_und_section_ptr;
+ 		  else if (isym.st_shndx == SHN_ABS)
+ 		    sym_sec = bfd_abs_section_ptr;
+ 		  else if (isym.st_shndx == SHN_COMMON)
+ 		    sym_sec = bfd_com_section_ptr;
+ 		  else
+ 		    sym_sec = bfd_section_from_elf_index (abfd, isym.st_shndx);
+ 		  symval = isym.st_value;
+ 		}
+ 	      else
+ 		{
+ 		  unsigned long indx;
+ 		  struct elf_link_hash_entry * h;
+ 
+ 		  /* An external symbol.  */
+ 		  indx = ELF32_R_SYM (irelcall->r_info) - symtab_hdr->sh_info;
+ 		  h = elf_sym_hashes (abfd)[indx];
+ 		  BFD_ASSERT (h != NULL);
+ 
+ 		  if (   h->root.type != bfd_link_hash_defined
+ 		      && h->root.type != bfd_link_hash_defweak)
+ 		    /* This appears to be a reference to an undefined
+ 		       symbol.  Just ignore it--it will be caught by the
+ 		       regular reloc processing.  */
+ 		    continue;
+ 
+ 		  symval = h->root.u.def.value;
+ 		}
+ 
+ 	      if (symval + irelcall->r_addend != irelcall->r_offset + 4)
+ 		{
+ 		  ((*_bfd_error_handler)
+ 		   ("%s: 0x%lx: warning: R_V850_LONGCALL points to unrecognized reloc 0x%lx",
+ 		    bfd_get_filename (abfd), (unsigned long) irel->r_offset, irelcall->r_offset ));
+ 
+ 		  continue;
+ 		}
+ 
+ 	      /* Get the value of the symbol referred to by the reloc.  */
+ 	      if (ELF32_R_SYM (hi_irelfn->r_info) < symtab_hdr->sh_info)
+ 		{
+ 		  unsigned int		   r_index;
+ 		  Elf_Internal_Sym         isym;
+ 		  asection *               sym_sec;
+ 		  Elf32_External_Sym *     esym;
+ 		  Elf_External_Sym_Shndx * shndx;
+ 
+ 		  /* A local symbol.  */
+ 		  r_index = ELF32_R_SYM (irel->r_info);
+ 		  esym = extsyms + r_index;
+ 		  shndx = shndx_buf + (shndx_buf ? r_index : 0);
+ 		  bfd_elf32_swap_symbol_in (abfd, esym, shndx, & isym);
+           
+ 		  if (isym.st_shndx == SHN_UNDEF)
+ 		    sym_sec = bfd_und_section_ptr;
+ 		  else if (isym.st_shndx == SHN_ABS)
+ 		    sym_sec = bfd_abs_section_ptr;
+ 		  else if (isym.st_shndx == SHN_COMMON)
+ 		    sym_sec = bfd_com_section_ptr;
+ 		  else
+ 		    sym_sec = bfd_section_from_elf_index (abfd, isym.st_shndx);
+ 		  symval = (isym.st_value
+ 			    + sym_sec->output_section->vma
+ 			    + sym_sec->output_offset);
+ 		}
+ 	      else
+ 		{
+ 		  unsigned long indx;
+ 		  struct elf_link_hash_entry * h;
+ 
+ 		  /* An external symbol.  */
+ 		  indx = ELF32_R_SYM (irel->r_info) - symtab_hdr->sh_info;
+ 		  h = elf_sym_hashes (abfd)[indx];
+ 		  BFD_ASSERT (h != NULL);
+ 
+ 		  if (   h->root.type != bfd_link_hash_defined
+ 		      && h->root.type != bfd_link_hash_defweak)
+ 		    /* This appears to be a reference to an undefined
+ 		       symbol.  Just ignore it--it will be caught by the
+ 		       regular reloc processing.  */
+ 		    continue;
+ 
+ 		  symval = (h->root.u.def.value
+ 			    + h->root.u.def.section->output_section->vma
+ 			    + h->root.u.def.section->output_offset);
+ 		}
+ 
+ 	      addend = irel->r_addend;
+ 
+ 	      foff = (symval + addend
+ 		      - (irel->r_offset
+ 			 + sec->output_section->vma
+ 			 + sec->output_offset
+ 			 + 4));
+ #ifdef DEBUG_RELAX
+ 	      fprintf (stderr, "relax longcall r_offset 0x%x ptr 0x%x symbol 0x%x addend 0x%x distance 0x%x\n",
+ 		       irel->r_offset,
+ 		       (irel->r_offset
+ 			+ sec->output_section->vma
+ 			+ sec->output_offset),
+ 		       symval, addend, foff);
+ #endif
+ 
+ 	      if (foff < -0x100000 || foff >= 0x100000)
+ 		/* After all that work, we can't shorten this function call.  */
+ 		continue;
+ 
+ 	      /* For simplicity of coding, we are going to modify the section
+ 	         contents, the section relocs, and the BFD symbol table.  We
+ 	         must tell the rest of the code not to free up this
+ 	         information.  It would be possible to instead create a table
+ 	         of changes which have to be made, as is done in coff-mips.c;
+ 	         that would be more work, but would require less memory when
+ 	         the linker is run.  */
+ 	      elf_section_data (sec)->relocs = internal_relocs;
+ 	      free_relocs = NULL;
+ 
+ 	      elf_section_data (sec)->this_hdr.contents = contents;
+ 	      free_contents = NULL;
+ 
+ 	      symtab_hdr->contents = (bfd_byte *) extsyms;
+ 	      free_extsyms = NULL;
+       
+ 	      /* Replace the long call with a jarl.  */
+ 	      irel->r_info = ELF32_R_INFO (ELF32_R_SYM (hi_irelfn->r_info), R_V850_22_PCREL);
+ 
+ 	      addend = 0;
+ 
+ 	      if (ELF32_R_SYM (hi_irelfn->r_info) < symtab_hdr->sh_info)
+ 		/* If this needs to be changed because of future relaxing,
+ 		   it will be handled here like other internal IND12W
+ 		   relocs.  */
+ 		bfd_put_32 (abfd,
+ 			    0x00000780 | (JARL_R2 (insn[2])<<11) | ((addend << 16) & 0xffff) | ((addend >> 16) & 0xf),
+ 			    contents + irel->r_offset);
+ 	      else
+ 		/* We can't fully resolve this yet, because the external
+ 		   symbol value may be changed by future relaxing.
+ 		   We let the final link phase handle it.  */
+ 		bfd_put_32 (abfd, 0x00000780 | (JARL_R2 (insn[2])<<11),
+ 			    contents + irel->r_offset);
+ 
+ 	      hi_irelfn->r_info = 
+ 		ELF32_R_INFO (ELF32_R_SYM (hi_irelfn->r_info), R_V850_NONE);
+ 	      lo_irelfn->r_info =
+ 		ELF32_R_INFO (ELF32_R_SYM (lo_irelfn->r_info), R_V850_NONE);
+ 	      irelcall->r_info =
+ 		ELF32_R_INFO (ELF32_R_SYM (irelcall->r_info), R_V850_NONE);
+ 
+ 	      if (! v850_elf_relax_delete_bytes (abfd, sec,
+ 						 irel->r_offset + 4, toaddr, 12))
+ 		goto error_return;
+ 
+ 	      align_pad_size += 12;
+ 	    }
+ 	  else if (ELF32_R_TYPE (irel->r_info) == (int) R_V850_LONGJUMP)
+ 	    {
+ 	      /* Check code for -mlong-jumps output.  */
+ 	      if (laddr + 10 <= (bfd_vma) sec->_raw_size)
+ 		{
+ 		  insn[0] = bfd_get_16 (abfd, contents + laddr);
+ 		  insn[1] = bfd_get_16 (abfd, contents + laddr + 4);
+ 		  insn[2] = bfd_get_16 (abfd, contents + laddr + 8);
+ 
+ 		  if ((insn[0] & MOVHI_MASK) != MOVHI
+ 		       || MOVHI_R1 (insn[0]) != 0)
+ 		    no_match = 0;
+ 
+ 		  if (no_match < 0
+ 		      && ((insn[1] & MOVEA_MASK) != MOVEA
+ 			   || MOVHI_R2 (insn[0]) != MOVEA_R1 (insn[1])))
+ 		    no_match = 1;
+ 
+ 		  if (no_match < 0
+ 		      && ((insn[2] & JMP_R_MASK) != JMP_R
+ 			   || MOVEA_R2 (insn[1]) != JMP_R1 (insn[2])))
+ 		    no_match = 4;
+ 		}
+ 	      else
+ 		{
+ 		  ((*_bfd_error_handler)
+ 		   ("%s: 0x%lx: warning: R_V850_LONGJUMP points to unrecognized insns",
+ 		    bfd_get_filename (abfd), (unsigned long) irel->r_offset));
+ 
+ 		  continue;
+ 		}
+ 
+ 	      if (no_match >= 0)
+ 		{
+ 		  ((*_bfd_error_handler)
+ 		   ("%s: 0x%lx: warning: R_V850_LONGJUMP points to unrecognized insn 0x%x",
+ 		    bfd_get_filename (abfd), (unsigned long) irel->r_offset+no_match, insn[no_match]));
+ 
+ 		  continue;
+ 		}
+ 
+ 	      /* Get the reloc for the address from which the register is
+ 	         being loaded.  This reloc will tell us which function is
+ 	         actually being called.  */
+ 	      for (hi_irelfn = internal_relocs; hi_irelfn < irelend; hi_irelfn ++)
+ 		if (hi_irelfn->r_offset == laddr + 2
+ 		    && ELF32_R_TYPE (hi_irelfn->r_info) == (int) R_V850_HI16_S) 
+ 		  break;
+ 
+ 	      for (lo_irelfn = internal_relocs; lo_irelfn < irelend; lo_irelfn ++)
+ 		if (lo_irelfn->r_offset == laddr + 6
+ 		    && ELF32_R_TYPE (lo_irelfn->r_info) == (int) R_V850_LO16)
+ 		  break;
+ 
+ 	      if (   hi_irelfn == irelend
+ 		  || lo_irelfn == irelend)
+ 		{
+ 		  ((*_bfd_error_handler)
+ 		   ("%s: 0x%lx: warning: R_V850_LONGJUMP points to unrecognized reloc",
+ 		    bfd_get_filename (abfd), (unsigned long) irel->r_offset ));
+ 
+ 		  continue;
+ 		}
+ 	
+ 	      /* Get the value of the symbol referred to by the reloc.  */
+ 	      if (ELF32_R_SYM (hi_irelfn->r_info) < symtab_hdr->sh_info)
+ 		{
+ 		  unsigned int		   r_index;
+ 		  Elf_Internal_Sym         isym;
+ 		  asection *               sym_sec;
+ 		  Elf32_External_Sym *     esym;
+ 		  Elf_External_Sym_Shndx * shndx;
+ 
+ 		  /* A local symbol.  */
+ 		  r_index = ELF32_R_SYM (irel->r_info);
+ 		  esym = extsyms + r_index;
+ 		  shndx = shndx_buf + (shndx_buf ? r_index : 0);
+ 		  bfd_elf32_swap_symbol_in (abfd, esym, shndx, & isym);
+ 	  
+ 		  if (isym.st_shndx == SHN_UNDEF)
+ 		    sym_sec = bfd_und_section_ptr;
+ 		  else if (isym.st_shndx == SHN_ABS)
+ 		    sym_sec = bfd_abs_section_ptr;
+ 		  else if (isym.st_shndx == SHN_COMMON)
+ 		    sym_sec = bfd_com_section_ptr;
+ 		  else
+ 		    sym_sec = bfd_section_from_elf_index (abfd, isym.st_shndx);
+ 		  symval = (isym.st_value
+ 			    + sym_sec->output_section->vma
+ 			    + sym_sec->output_offset);
+ #ifdef DEBUG_RELAX
+ 		  {
+ 		    char * name = bfd_elf_string_from_elf_section
+ 		      (abfd, symtab_hdr->sh_link, isym.st_name);
+ 
+ 		    fprintf (stderr, "relax long jump local: sec: %s, sym: %s (%d), value: %x + %x + %x addend %x\n",
+ 			     sym_sec->name, name, isym.st_name,
+ 			     sym_sec->output_section->vma, sym_sec->output_offset,
+ 			     isym.st_value, irel->r_addend);
+ 		  }
+ #endif
+ 		}
+ 	      else
+ 		{
+ 		  unsigned long indx;
+ 		  struct elf_link_hash_entry * h;
+ 
+ 		  /* An external symbol.  */
+ 		  indx = ELF32_R_SYM (irel->r_info) - symtab_hdr->sh_info;
+ 		  h = elf_sym_hashes (abfd)[indx];
+ 		  BFD_ASSERT (h != NULL);
+ 
+ 		  if (   h->root.type != bfd_link_hash_defined
+ 		      && h->root.type != bfd_link_hash_defweak)
+ 		    /* This appears to be a reference to an undefined
+ 		       symbol.  Just ignore it--it will be caught by the
+ 		       regular reloc processing.  */
+ 		    continue;
+ 
+ 		  symval = (h->root.u.def.value
+ 			    + h->root.u.def.section->output_section->vma
+ 			    + h->root.u.def.section->output_offset);
+ #ifdef DEBUG_RELAX
+ 		  fprintf (stderr,
+ 			   "relax longjump defined: sec: %s, name: %s, value: %x + %x + %x addend %x\n",
+ 			   sec->name, h->root.root.string, h->root.u.def.value,
+ 			   sec->output_section->vma, sec->output_offset, irel->r_addend);
+ #endif
+ 		}
+ 
+ 	      addend = irel->r_addend;
+ 
+ 	      foff = (symval + addend
+ 		      - (irel->r_offset
+ 			 + sec->output_section->vma
+ 			 + sec->output_offset
+ 			 + 4));
+ #ifdef DEBUG_RELAX
+ 	      fprintf (stderr, "relax longjump r_offset 0x%x ptr 0x%x symbol 0x%x addend 0x%x distance 0x%x\n",
+ 		       irel->r_offset,
+ 		       (irel->r_offset
+ 			+ sec->output_section->vma
+ 			+ sec->output_offset),
+ 		       symval, addend, foff);
+ #endif
+ 	      if (foff < -0x100000 || foff >= 0x100000)
+ 		/* After all that work, we can't shorten this function call.  */
+ 		continue;
+ 
+ 	      /* For simplicity of coding, we are going to modify the section
+ 	         contents, the section relocs, and the BFD symbol table.  We
+ 	         must tell the rest of the code not to free up this
+ 	         information.  It would be possible to instead create a table
+ 	         of changes which have to be made, as is done in coff-mips.c;
+ 	         that would be more work, but would require less memory when
+ 	         the linker is run.  */
+ 	      elf_section_data (sec)->relocs = internal_relocs;
+ 	      free_relocs = NULL;
+ 
+ 	      elf_section_data (sec)->this_hdr.contents = contents;
+ 	      free_contents = NULL;
+ 
+ 	      symtab_hdr->contents = (bfd_byte *) extsyms;
+ 	      free_extsyms = NULL;
+ 
+ 	      if (foff < -0x100 || foff >= 0x100)
+ 		{
+ 		  /* Replace the long jump with a jr.  */
+ 
+ 		  irel->r_info =
+ 			ELF32_R_INFO (ELF32_R_SYM (irel->r_info), R_V850_22_PCREL);
+   
+ 		  irel->r_addend = addend;
+ 		  addend = 0;
+ 
+ 		  if (ELF32_R_SYM (hi_irelfn->r_info) < symtab_hdr->sh_info)
+ 		    /* If this needs to be changed because of future relaxing,
+ 		       it will be handled here like other internal IND12W
+ 		       relocs.  */
+ 		    bfd_put_32 (abfd,
+ 				0x00000780 | ((addend << 15) & 0xffff0000) | ((addend >> 17) & 0xf),
+ 				contents + irel->r_offset);
+ 		  else
+ 		    /* We can't fully resolve this yet, because the external
+ 		       symbol value may be changed by future relaxing.
+ 		       We let the final link phase handle it.  */
+ 		    bfd_put_32 (abfd, 0x00000780, contents + irel->r_offset);
+ 
+ 		  hi_irelfn->r_info =
+ 			ELF32_R_INFO (ELF32_R_SYM (hi_irelfn->r_info), R_V850_NONE);
+ 		  lo_irelfn->r_info =
+ 			ELF32_R_INFO (ELF32_R_SYM (lo_irelfn->r_info), R_V850_NONE);
+ 		  if (!v850_elf_relax_delete_bytes (abfd, sec,
+ 						    irel->r_offset + 4, toaddr, 6))
+ 		    goto error_return;
+ 
+ 		  align_pad_size += 6;
+ 		}
+ 	      else
+ 		{
+ 		  /* Replace the long jump with a br.  */
+ 
+ 		  irel->r_info =
+ 			ELF32_R_INFO (ELF32_R_SYM (irel->r_info), R_V850_9_PCREL);
+ 
+ 		  irel->r_addend = addend;
+ 		  addend = 0;
+ 
+ 		  if (ELF32_R_SYM (hi_irelfn->r_info) < symtab_hdr->sh_info)
+ 		    /* If this needs to be changed because of future relaxing,
+ 		       it will be handled here like other internal IND12W
+ 		       relocs.  */
+ 		    bfd_put_16 (abfd,
+ 				0x0585 | ((addend << 10) & 0xf800) | ((addend << 3) & 0x0070),
+ 				contents + irel->r_offset);
+ 		  else
+ 		    /* We can't fully resolve this yet, because the external
+ 		       symbol value may be changed by future relaxing.
+ 		       We let the final link phase handle it.  */
+ 		    bfd_put_16 (abfd, 0x0585, contents + irel->r_offset);
+ 
+ 		  hi_irelfn->r_info =
+ 			ELF32_R_INFO (ELF32_R_SYM (hi_irelfn->r_info), R_V850_NONE);
+ 		  lo_irelfn->r_info =
+ 			ELF32_R_INFO (ELF32_R_SYM (lo_irelfn->r_info), R_V850_NONE);
+ 		  if (!v850_elf_relax_delete_bytes (abfd, sec,
+ 						    irel->r_offset + 2, toaddr, 8))
+ 		    goto error_return;
+ 
+ 		  align_pad_size += 8;
+ 		}
+ 	    }
+ 	}
+ 
+       irelalign = NULL;
+       for (irel = internal_relocs; irel < irelend; irel++)
+ 	{
+ 	  if (ELF32_R_TYPE (irel->r_info) == (int) R_V850_ALIGN
+ 	      && irel->r_offset == toaddr)
+ 	    {
+ 	      irel->r_offset -= align_pad_size;
+ 
+ 	      if (irelalign == NULL || irelalign->r_addend > irel->r_addend)
+ 		irelalign = irel;
+ 	    }
+ 	}
+ 
+       addr = toaddr;
+     }
+ 
+   if (!irelalign)
+     {
+ #ifdef DEBUG_RELAX
+       fprintf (stderr, "relax pad %d shorten %d -> %d\n",
+ 	       align_pad_size,
+ 	       sec->_cooked_size,
+ 	       sec->_cooked_size - align_pad_size);
+ #endif
+       sec->_cooked_size -= align_pad_size;
+     }
+ 
+   return true;
+ 
+  error_return:
+   if (free_relocs != NULL)
+     free (free_relocs);
+ 
+   if (free_contents != NULL)
+     free (free_contents);
+ 
+   if (free_extsyms != NULL)
+     free (free_extsyms);
+ 
+   return false;
+ }
+ 
  #define TARGET_LITTLE_SYM			bfd_elf32_v850_vec
  #define TARGET_LITTLE_NAME			"elf32-v850"
  #define ELF_ARCH				bfd_arch_v850
*************** v850_elf_fake_sections (abfd, hdr, sec)
*** 2198,2203 ****
--- 3208,3214 ----
  #define bfd_elf32_bfd_merge_private_bfd_data 	v850_elf_merge_private_bfd_data
  #define bfd_elf32_bfd_set_private_flags		v850_elf_set_private_flags
  #define bfd_elf32_bfd_print_private_bfd_data	v850_elf_print_private_bfd_data
+ #define bfd_elf32_bfd_relax_section		v850_elf_relax_section
  
  #define elf_symbol_leading_char			'_'
  
Index: bfd/reloc.c
===================================================================
RCS file: /cvs/src/src/bfd/reloc.c,v
retrieving revision 1.64
diff -c -3 -p -w -r1.64 reloc.c
*** bfd/reloc.c	13 Aug 2002 20:08:49 -0000	1.64
--- bfd/reloc.c	29 Aug 2002 06:43:13 -0000
*************** ENUM
*** 2788,2795 ****
    BFD_RELOC_V850_CALLT_16_16_OFFSET
  ENUMDOC
    This is a 16 bit offset from the call table base pointer.
! COMMENT
! 
  ENUM
    BFD_RELOC_MN10300_32_PCREL
  ENUMDOC
--- 2788,2806 ----
    BFD_RELOC_V850_CALLT_16_16_OFFSET
  ENUMDOC
    This is a 16 bit offset from the call table base pointer.
! ENUM
!   BFD_RELOC_V850_LONGCALL
! ENUMDOC
!   Used for relaxing indirect function calls.
! ENUM
!   BFD_RELOC_V850_LONGJUMP
! ENUMDOC
!   Used for relaxing indirect jumps.
! ENUM
!   BFD_RELOC_V850_ALIGN
! ENUMDOC
!   Used to maintain alignment whilst relaxing.
  ENUM
    BFD_RELOC_MN10300_32_PCREL
  ENUMDOC

Index: gas/config/tc-v850.c
===================================================================
RCS file: /cvs/src/src/gas/config/tc-v850.c,v
retrieving revision 1.24
diff -c -3 -p -w -r1.24 tc-v850.c
*** gas/config/tc-v850.c	20 Aug 2002 23:49:27 -0000	1.24
--- gas/config/tc-v850.c	29 Aug 2002 06:43:17 -0000
*************** const relax_typeS md_relax_table[] = {
*** 78,83 ****
--- 78,85 ----
    {0x1fffff, -0x200000, 4, 0},
  };
  
+ static int  v850_relax = 0;
+ 
  /* Fixups.  */
  #define MAX_INSN_FIXUPS (5)
  struct v850_fixup {
*************** v850_comm (area)
*** 394,400 ****
--- 396,408 ----
  	}
        else
  	{
+           segT   old_sec;
+           int    old_subsec;
+ 
  	allocate_common:
+           old_sec = now_seg;
+           old_subsec = now_subseg;
+ 
  	  S_SET_VALUE (symbolP, (valueT) size);
  	  S_SET_ALIGN (symbolP, temp);
  	  S_SET_EXTERNAL (symbolP);
*************** v850_comm (area)
*** 411,416 ****
--- 419,427 ----
  	    default:
  	      abort ();
  	    }
+ 
+ 	  obj_elf_section_change_hook ();
+ 	  subseg_set (old_sec, old_subsec);
  	}
      }
    else
*************** set_machine (number)
*** 468,477 ****
      {
      case 0:               processor_mask = PROCESSOR_V850;   break;
      case bfd_mach_v850e:  processor_mask = PROCESSOR_V850E;  break;
-     case bfd_mach_v850ea: processor_mask = PROCESSOR_V850EA; break;
      }
  }
  
  /* The target specific pseudo-ops which we support.  */
  const pseudo_typeS md_pseudo_table[] = {
    { "sdata",		v850_seg,		SDATA_SECTION		},
--- 479,523 ----
      {
      case 0:               processor_mask = PROCESSOR_V850;   break;
      case bfd_mach_v850e:  processor_mask = PROCESSOR_V850E;  break;
      }
  }
  
+ static void v850_longcode PARAMS ((int));
+ 
+ static void
+ v850_longcode (type)
+      int type;
+ {
+   expressionS ex;
+ 
+   if (! v850_relax)
+     {
+       if (type == 1)
+ 	as_warn (".longcall pseudo-op seen when not relaxing");
+       else
+ 	as_warn (".longjump pseudo-op seen when not relaxing");	
+     }
+ 
+   expression (&ex);
+ 
+   if (ex.X_op != O_symbol || ex.X_add_number != 0)
+     {
+       as_bad ("bad .longcall format");
+       ignore_rest_of_line ();
+ 
+       return;
+     }
+ 
+   if (type == 1) 
+     fix_new_exp (frag_now, frag_now_fix (), 4, & ex, 1,
+ 		 BFD_RELOC_V850_LONGCALL);
+   else
+     fix_new_exp (frag_now, frag_now_fix (), 4, & ex, 1,
+ 		 BFD_RELOC_V850_LONGJUMP);
+ 
+   demand_empty_rest_of_line ();
+ }
+ 
  /* The target specific pseudo-ops which we support.  */
  const pseudo_typeS md_pseudo_table[] = {
    { "sdata",		v850_seg,		SDATA_SECTION		},
*************** const pseudo_typeS md_pseudo_table[] = {
*** 492,500 ****
    { "call_table_data",	v850_seg,		CALL_TABLE_DATA_SECTION	},
    { "call_table_text",	v850_seg,		CALL_TABLE_TEXT_SECTION	},
    { "v850e",		set_machine,		bfd_mach_v850e		},
-   { "v850ea",		set_machine,		bfd_mach_v850ea 	},
    { "file", (void (*) PARAMS ((int))) dwarf2_directive_file, 0 },
    { "loc",		dwarf2_directive_loc,	0			},
    { NULL,		NULL,			0			}
  };
  
--- 538,547 ----
    { "call_table_data",	v850_seg,		CALL_TABLE_DATA_SECTION	},
    { "call_table_text",	v850_seg,		CALL_TABLE_TEXT_SECTION	},
    { "v850e",		set_machine,		bfd_mach_v850e		},
    { "file", (void (*) PARAMS ((int))) dwarf2_directive_file, 0 },
    { "loc",		dwarf2_directive_loc,	0			},
+   { "longcall",         v850_longcode,          1                       },
+   { "longjump",         v850_longcode,          2                       },
    { NULL,		NULL,			0			}
  };
  
*************** md_show_usage (stream)
*** 1103,1110 ****
    fprintf (stream, _("  -mwarn-unsigned-overflow  Warn if unsigned immediate values overflow\n"));
    fprintf (stream, _("  -mv850                    The code is targeted at the v850\n"));
    fprintf (stream, _("  -mv850e                   The code is targeted at the v850e\n"));
-   fprintf (stream, _("  -mv850ea                  The code is targeted at the v850ea\n"));
    fprintf (stream, _("  -mv850any                 The code is generic, despite any processor specific instructions\n"));
  }
  
  int
--- 1150,1158 ----
    fprintf (stream, _("  -mwarn-unsigned-overflow  Warn if unsigned immediate values overflow\n"));
    fprintf (stream, _("  -mv850                    The code is targeted at the v850\n"));
    fprintf (stream, _("  -mv850e                   The code is targeted at the v850e\n"));
    fprintf (stream, _("  -mv850any                 The code is generic, despite any processor specific instructions\n"));
+   fprintf (stream, _("  -mrelax                   Enable relaxation\n"));
+   
  }
  
  int
*************** md_parse_option (c, arg)
*** 1138,1156 ****
        machine = bfd_mach_v850e;
        processor_mask = PROCESSOR_V850E;
      }
-   else if (strcmp (arg, "v850ea") == 0)
-     {
-       machine = bfd_mach_v850ea;
-       processor_mask = PROCESSOR_V850EA;
-     }
    else if (strcmp (arg, "v850any") == 0)
      {
        /* Tell the world that this is for any v850 chip.  */
        machine = 0;
  
        /* But support instructions for the extended versions.  */
!       processor_mask = PROCESSOR_V850EA;
      }
    else
      {
        /* xgettext:c-format  */
--- 1186,1201 ----
        machine = bfd_mach_v850e;
        processor_mask = PROCESSOR_V850E;
      }
    else if (strcmp (arg, "v850any") == 0)
      {
        /* Tell the world that this is for any v850 chip.  */
        machine = 0;
  
        /* But support instructions for the extended versions.  */
!       processor_mask = PROCESSOR_V850E;
      }
+   else if (strcmp (arg, "relax") == 0)
+     v850_relax = 1;
    else
      {
        /* xgettext:c-format  */
*************** void
*** 1275,1291 ****
  md_begin ()
  {
    char *prev_name = "";
!   register const struct v850_opcode *op;
  
!   if (strncmp (TARGET_CPU, "v850ea", 6) == 0)
!     {
!       if (machine == -1)
! 	machine = bfd_mach_v850ea;
! 
!       if (processor_mask == -1)
! 	processor_mask = PROCESSOR_V850EA;
!     }
!   else if (strncmp (TARGET_CPU, "v850e", 5) == 0)
      {
        if (machine == -1)
  	machine = bfd_mach_v850e;
--- 1320,1328 ----
  md_begin ()
  {
    char *prev_name = "";
!   const struct v850_opcode *op;
  
!   if (strncmp (TARGET_CPU, "v850e", 5) == 0)
      {
        if (machine == -1)
  	machine = bfd_mach_v850e;
*************** md_assemble (str)
*** 1750,1757 ****
  
  		      extra_data_after_insn = true;
  		      extra_data_len        = 4;
! 		      extra_data            = ex.X_add_number;
! 		      ex.X_add_number       = 0;
  		      break;
  
  		    default:
--- 1787,1793 ----
  
  		      extra_data_after_insn = true;
  		      extra_data_len        = 4;
! 		      extra_data            = 0;
  		      break;
  
  		    default:
*************** tc_gen_reloc (seg, fixp)
*** 2215,2226 ****
--- 2251,2282 ----
    if (fixp->fx_r_type == BFD_RELOC_VTABLE_ENTRY
        || fixp->fx_r_type == BFD_RELOC_VTABLE_INHERIT)
      reloc->addend = fixp->fx_offset;
+   else if (   fixp->fx_r_type == BFD_RELOC_V850_LONGCALL
+ 	   || fixp->fx_r_type == BFD_RELOC_V850_LONGJUMP
+            || fixp->fx_r_type == BFD_RELOC_V850_ALIGN)
+     reloc->addend = fixp->fx_offset;
    else
      reloc->addend = fixp->fx_addnumber;
  
    return reloc;
  }
  
+ void
+ v850_handle_align (frag)
+      fragS * frag;
+ {
+   if (v850_relax
+       && frag->fr_type == rs_align
+       && frag->fr_address + frag->fr_fix > 0
+       && frag->fr_offset > 1
+       && now_seg != bss_section
+       && now_seg != v850_seg_table[SBSS_SECTION].s
+       && now_seg != v850_seg_table[TBSS_SECTION].s
+       && now_seg != v850_seg_table[ZBSS_SECTION].s)
+     fix_new (frag, frag->fr_fix, 2, & abs_symbol, frag->fr_offset, 0,
+            BFD_RELOC_V850_ALIGN);
+ }
+ 
  /* Return current size of variable part of frag.  */
  
  int
*************** md_apply_fix3 (fixP, valueP, seg)
*** 2261,2266 ****
--- 2317,2324 ----
    char *where;
  
    if (fixP->fx_r_type == BFD_RELOC_VTABLE_INHERIT
+       || fixP->fx_r_type == BFD_RELOC_V850_LONGCALL
+       || fixP->fx_r_type == BFD_RELOC_V850_LONGJUMP
        || fixP->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
      {
        fixP->fx_done = 0;
*************** md_apply_fix3 (fixP, valueP, seg)
*** 2268,2277 ****
      }
  
    if (fixP->fx_addsy == (symbolS *) NULL)
      fixP->fx_done = 1;
  
    else if (fixP->fx_pcrel)
!     ;
  
    else
      {
--- 2326,2336 ----
      }
  
    if (fixP->fx_addsy == (symbolS *) NULL)
+     fixP->fx_addnumber = value,
      fixP->fx_done = 1;
  
    else if (fixP->fx_pcrel)
!     fixP->fx_addnumber = fixP->fx_offset;
  
    else
      {
*************** md_apply_fix3 (fixP, valueP, seg)
*** 2287,2292 ****
--- 2346,2352 ----
  			    _("expression too complex"));
  	    }
  	}
+       fixP->fx_addnumber = value;
      }
  
    if ((int) fixP->fx_r_type >= (int) BFD_RELOC_UNUSED)
*************** md_apply_fix3 (fixP, valueP, seg)
*** 2345,2352 ****
        else if (fixP->fx_size == 4)
  	bfd_putl32 (value, (unsigned char *) where);
      }
- 
-   fixP->fx_addnumber = value;
  }
  
  /* Parse a cons expression.  We have to handle hi(), lo(), etc
--- 2405,2410 ----
*************** v850_force_relocation (fixP)
*** 2428,2433 ****
--- 2486,2503 ----
  
    if (fixP->fx_r_type == BFD_RELOC_VTABLE_INHERIT
        || fixP->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
+     return 1;
+ 
+   if (   fixP->fx_r_type == BFD_RELOC_V850_LONGCALL
+       || fixP->fx_r_type == BFD_RELOC_V850_LONGJUMP)
+     return 1;
+ 
+   if (v850_relax
+       && (fixP->fx_pcrel
+         || fixP->fx_r_type == BFD_RELOC_V850_ALIGN
+         || fixP->fx_r_type == BFD_RELOC_V850_22_PCREL
+         || fixP->fx_r_type == BFD_RELOC_V850_9_PCREL
+         || fixP->fx_r_type >= BFD_RELOC_UNUSED))
      return 1;
  
    return 0;

Index: gas/config/tc-v850.h
===================================================================
RCS file: /cvs/src/src/gas/config/tc-v850.h,v
retrieving revision 1.11
diff -c -3 -p -w -r1.11 tc-v850.h
*** gas/config/tc-v850.h	25 May 2002 12:53:29 -0000	1.11
--- gas/config/tc-v850.h	29 Aug 2002 06:43:17 -0000
*************** extern void cons_fix_new_v850 PARAMS ((f
*** 70,75 ****
--- 70,80 ----
  #define TC_GENERIC_RELAX_TABLE md_relax_table
  extern const struct relax_type md_relax_table[];
  
+ /* When relaxing, we need to generate
+    relocations for alignment directives.  */
+ #define HANDLE_ALIGN(frag) v850_handle_align (frag)
+ extern void v850_handle_align PARAMS ((fragS *));
+ 
  /* This section must be in the small data area (pointed to by GP).  */
  #define SHF_V850_GPREL		0x10000000
  /* This section must be in the tiny data area (pointed to by EP).  */

Index: gas/doc/c-v850.texi
===================================================================
RCS file: /cvs/src/src/gas/doc/c-v850.texi,v
retrieving revision 1.2
diff -c -3 -p -w -r1.2 c-v850.texi
*** gas/doc/c-v850.texi	8 Mar 2001 23:24:26 -0000	1.2
--- gas/doc/c-v850.texi	29 Aug 2002 06:43:17 -0000
*************** routines used by the code produced by GC
*** 62,67 ****
--- 62,75 ----
  architecture, together with support routines only used by the V850E
  architecture.
  
+ @cindex @code{-mrelax} command line option, V850
+ @item -mrelax
+ Enables relaxation.  This allows the .longcall and .longjump pseudo
+ ops to be used in the assembler source code.  These ops label sections
+ of code which are either a long function call or a long branch.  The
+ assembler will then flag these sections of code and the linker will
+ attempt to relax them.
+ 
  @end table
  
  
*************** example:
*** 354,363 ****
  will put the call the function whoes address is held in the call table
  at the location labeled 'table_func1'.
  
  @end table
  
  
  For information on the V850 instruction set, see @cite{V850
  Family 32-/16-Bit single-Chip Microcontroller Architecture Manual} from NEC.
  Ltd.
- 
--- 362,384 ----
  will put the call the function whoes address is held in the call table
  at the location labeled 'table_func1'.
  
+ @cindex @code{longcall} pseudo-op, V850
+ @item .longcall @code{name}
+ Indicates that the following sequence of instructions is a long call
+ to function @code{name}.  The linker will attempt to shorten this call
+ sequence if @code{name} is within a 22bit offset of the call.  Only
+ valid if the @code{-mrelax} command line switch has been enabled.
+ 
+ @cindex @code{longjump} pseudo-op, V850
+ @item .longjump @code{name}
+ Indicates that the following sequence of instructions is a long jump
+ to label @code{name}.  The linker will attempt to shorten this code
+ sequence if @code{name} is within a 22bit offset of the jump.  Only
+ valid if the @code{-mrelax} command line switch has been enabled.
+ 
  @end table
  
  
  For information on the V850 instruction set, see @cite{V850
  Family 32-/16-Bit single-Chip Microcontroller Architecture Manual} from NEC.
  Ltd.

Index: include/elf/v850.h
===================================================================
RCS file: /cvs/src/src/include/elf/v850.h,v
retrieving revision 1.5
diff -c -3 -p -w -r1.5 v850.h
*** include/elf/v850.h	14 Mar 2001 02:27:44 -0000	1.5
--- include/elf/v850.h	29 Aug 2002 06:43:18 -0000
***************
*** 1,5 ****
  /* V850 ELF support for BFD.
!    Copyright 1997, 1998, 2000 Free Software Foundation, Inc.
     Created by Michael Meissner, Cygnus Support <meissner@cygnus.com>
  
  This file is part of BFD, the Binary File Descriptor library.
--- 1,5 ----
  /* V850 ELF support for BFD.
!    Copyright 1997, 1998, 2000, 2002 Free Software Foundation, Inc.
     Created by Michael Meissner, Cygnus Support <meissner@cygnus.com>
  
     This file is part of BFD, the Binary File Descriptor library.
*************** Foundation, Inc., 59 Temple Place - Suit
*** 35,52 ****
  /* v850e code.  */
  #define E_V850E_ARCH		0x10000000
  
- /* v850ea code.  */
- #define E_V850EA_ARCH		0x20000000
  
  
! /* Flags for the st_other field */
! #define V850_OTHER_SDA		0x01	/* symbol had SDA relocations */
! #define V850_OTHER_ZDA		0x02	/* symbol had ZDA relocations */
! #define V850_OTHER_TDA		0x04	/* symbol had TDA relocations */
! #define V850_OTHER_TDA_BYTE	0x08	/* symbol had TDA byte relocations */
! #define V850_OTHER_ERROR	0x80	/* symbol had an error reported */
! 
! /* V850 relocations */
  #include "elf/reloc-macros.h"
  
  START_RELOC_NUMBERS (v850_reloc_type)
--- 35,49 ----
  /* v850e code.  */
  #define E_V850E_ARCH		0x10000000
  
  
+ /* Flags for the st_other field.  */
+ #define V850_OTHER_SDA		0x01	/* Symbol had SDA relocations.  */
+ #define V850_OTHER_ZDA		0x02	/* Symbol had ZDA relocations.  */
+ #define V850_OTHER_TDA		0x04	/* Symbol had TDA relocations.  */
+ #define V850_OTHER_TDA_BYTE	0x08	/* Symbol had TDA byte relocations.  */
+ #define V850_OTHER_ERROR	0x80	/* Symbol had an error reported.  */
  
! /* V850 relocations.  */
  #include "elf/reloc-macros.h"
  
  START_RELOC_NUMBERS (v850_reloc_type)
*************** START_RELOC_NUMBERS (v850_reloc_type)
*** 75,80 ****
--- 72,80 ----
       RELOC_NUMBER( R_V850_CALLT_16_16_OFFSET, 22)	/* For callt */
       RELOC_NUMBER (R_V850_GNU_VTINHERIT, 23)
       RELOC_NUMBER (R_V850_GNU_VTENTRY, 24)
+      RELOC_NUMBER (R_V850_LONGCALL, 25)
+      RELOC_NUMBER (R_V850_LONGJUMP, 26)
+      RELOC_NUMBER (R_V850_ALIGN, 27)
  END_RELOC_NUMBERS (R_V850_max)
  
  
*************** END_RELOC_NUMBERS (R_V850_max)
*** 102,107 ****
  
  /* Section contains the .scommon data.  */
  #define SHT_V850_ZCOMMON	0x70000002
- 
  
  #endif /* _ELF_V850_H */
--- 102,106 ----

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]