Jim fixed the fixups for conditional and unconditional branches.
authorNick Clifton <nickc@redhat.com>
Sat, 11 Oct 1997 00:55:57 +0000 (00:55 +0000)
committerNick Clifton <nickc@redhat.com>
Sat, 11 Oct 1997 00:55:57 +0000 (00:55 +0000)
Added code to support the bss and common sections in thr ZDA and SDA areas.

gas/ChangeLog
gas/config/tc-v850.c
gas/config/tc-v850.h

index 50625af..cd3f555 100644 (file)
@@ -1,3 +1,26 @@
+Fri Oct 10 17:48:29 1997  Nick Clifton  <nickc@cygnus.com>
+
+       * config/tc-v850.c (md_relax_table): Add support for relaxing
+       unconditional branches.  This patch is courtesy of Jim Wilson. 
+       (md_convert_frag): Fix relaxing of branches.  This patch is
+       courtesy of Jim Wilson.
+       (md_assemble): Create different fixups for conditional and
+       unconditional branches.  This patch is courtesy of Jim Wilson.
+       (md_estimate_size_before_relax): Estimate size of variable part of
+       fixup based on whether it is for a conditional or an unconditional
+       branch.  This patch is courtesy of Jim Wilson.
+       (v850_sdata, v850_tdata, v850_zdata, v850_sbss, v850_tbss,
+       v850_zbss, v850_rosdata, v850_rozdata, v850_bss): Add call to
+       obj_elf_section_change_hook(). 
+       (v850_comm): New function.
+       (md_pseudo_table): Add new pseudo ops .zcomm, .scomm and .tcomm.
+       (md_begin): Add bss flag to seg_info of bss sections.
+
+       Add support for .scommon, .tcommon and .zcommon sections.
+
+       * config/tc-v850.h (ELF_TC_SPECIAL_SECTIONS): Add .scommon,
+       .zcommon, .tbss, .call_table_data and .call_table_text.
+
 Fri Oct 10 15:01:14 1997  Doug Evans  <dje@canuck.cygnus.com>
 
        * configure.in (sparc): Set DEFAULT_ARCH from correct target.
index 249c853..f4a9ea9 100644 (file)
 #include "subsegs.h"     
 #include "opcode/v850.h"
 
+#define AREA_ZDA 0
+#define AREA_SDA 1
+#define AREA_TDA 2
+
 /* sign-extend a 16-bit number */
 #define SEXT16(x)      ((((x) & 0xffff) ^ (~ 0x7fff)) + 0x8000)
 
@@ -69,9 +73,14 @@ const char EXP_CHARS[] = "eE";
 const char FLT_CHARS[] = "dD";
 \f
 
-const relax_typeS md_relax_table[] = {
-  {0xff, -0x100, 2, 1},
+const relax_typeS md_relax_table[] =
+{
+  /* Conditional branches.  */
+  {0xff,     -0x100,    2, 1},
   {0x1fffff, -0x200000, 6, 0},
+  /* Unconditional branches.  */
+  {0xff,     -0x100,    2, 3},
+  {0x1fffff, -0x200000, 4, 0},
 };
 
 
@@ -83,6 +92,9 @@ static segT tbss_section = NULL;
 static segT zbss_section = NULL;
 static segT rosdata_section = NULL;
 static segT rozdata_section = NULL;
+static segT scommon_section = NULL;
+static segT tcommon_section = NULL;
+static segT zcommon_section = NULL;
 /* start-sanitize-v850e */
 static segT call_table_data_section = NULL;
 static segT call_table_text_section = NULL;
@@ -109,14 +121,18 @@ static int fc;
 void
 v850_sdata (int ignore)
 {
-  subseg_set (sdata_section, (subsegT) get_absolute_expression ());
+  obj_elf_section_change_hook();
   
+  subseg_set (sdata_section, (subsegT) get_absolute_expression ());
+
   demand_empty_rest_of_line ();
 }
 
 void
 v850_tdata (int ignore)
 {
+  obj_elf_section_change_hook();
+  
   subseg_set (tdata_section, (subsegT) get_absolute_expression ());
   
   demand_empty_rest_of_line ();
@@ -125,6 +141,8 @@ v850_tdata (int ignore)
 void
 v850_zdata (int ignore)
 {
+  obj_elf_section_change_hook();
+  
   subseg_set (zdata_section, (subsegT) get_absolute_expression ());
   
   demand_empty_rest_of_line ();
@@ -133,6 +151,8 @@ v850_zdata (int ignore)
 void
 v850_sbss (int ignore)
 {
+  obj_elf_section_change_hook();
+  
   subseg_set (sbss_section, (subsegT) get_absolute_expression ());
   
   demand_empty_rest_of_line ();
@@ -141,6 +161,8 @@ v850_sbss (int ignore)
 void
 v850_tbss (int ignore)
 {
+  obj_elf_section_change_hook();
+  
   subseg_set (tbss_section, (subsegT) get_absolute_expression ());
   
   demand_empty_rest_of_line ();
@@ -149,6 +171,8 @@ v850_tbss (int ignore)
 void
 v850_zbss (int ignore)
 {
+  obj_elf_section_change_hook();
+  
   subseg_set (zbss_section, (subsegT) get_absolute_expression ());
   
   demand_empty_rest_of_line ();
@@ -157,6 +181,8 @@ v850_zbss (int ignore)
 void
 v850_rosdata (int ignore)
 {
+  obj_elf_section_change_hook();
+  
   subseg_set (rosdata_section, (subsegT) get_absolute_expression ());
   
   demand_empty_rest_of_line ();
@@ -165,6 +191,8 @@ v850_rosdata (int ignore)
 void
 v850_rozdata (int ignore)
 {
+  obj_elf_section_change_hook();
+  
   subseg_set (rozdata_section, (subsegT) get_absolute_expression ());
   
   demand_empty_rest_of_line ();
@@ -174,6 +202,8 @@ v850_rozdata (int ignore)
 void
 v850_call_table_data (int ignore)
 {
+  obj_elf_section_change_hook();
+  
   subseg_set (call_table_data_section, (subsegT) get_absolute_expression ());
   
   demand_empty_rest_of_line ();
@@ -182,30 +212,14 @@ v850_call_table_data (int ignore)
 void
 v850_call_table_text (int ignore)
 {
+  obj_elf_section_change_hook();
+  
   subseg_set (call_table_text_section, (subsegT) get_absolute_expression ());
   
   demand_empty_rest_of_line ();
 }
 /* end-sanitize-v850e */
 
-static void
-v850_section (int arg)
-{
-  char   saved_c;
-  char * ptr;
-  
-  for (ptr = input_line_pointer; * ptr != '\n' && * ptr != 0; ptr ++)
-    if (* ptr == ',' && ptr[1] == '.')
-      break;
-
-  saved_c = * ptr;
-  * ptr = ';';
-  
-  obj_elf_section (arg);
-
-  * ptr = saved_c;
-}
-
 void
 v850_bss (int ignore)
 {
@@ -214,7 +228,7 @@ v850_bss (int ignore)
   obj_elf_section_change_hook();
   
   subseg_set (bss_section, (subsegT) temp);
-  
+   
   demand_empty_rest_of_line ();
 }
 
@@ -231,6 +245,225 @@ v850_offset (int ignore)
   demand_empty_rest_of_line ();
 }
 
+/* Copied from obj_elf_common() in gas/config/obj-elf.c */
+static void
+v850_comm (area)
+     int area;
+{
+  char *    name;
+  char      c;
+  char *    p;
+  int       temp;
+  int       size;
+  symbolS * symbolP;
+  int       have_align;
+
+  name = input_line_pointer;
+  c = get_symbol_end ();
+  /* just after name is now '\0' */
+  p = input_line_pointer;
+  *p = c;
+  SKIP_WHITESPACE ();
+  if (*input_line_pointer != ',')
+    {
+      as_bad ("Expected comma after symbol-name");
+      ignore_rest_of_line ();
+      return;
+    }
+  input_line_pointer++;                /* skip ',' */
+  if ((temp = get_absolute_expression ()) < 0)
+    {
+      as_bad (".COMMon length (%d.) <0! Ignored.", temp);
+      ignore_rest_of_line ();
+      return;
+    }
+  size = temp;
+  *p = 0;
+  symbolP = symbol_find_or_make (name);
+  *p = c;
+  if (S_IS_DEFINED (symbolP) && ! S_IS_COMMON (symbolP))
+    {
+      as_bad ("Ignoring attempt to re-define symbol");
+      ignore_rest_of_line ();
+      return;
+    }
+  if (S_GET_VALUE (symbolP) != 0)
+    {
+      if (S_GET_VALUE (symbolP) != size)
+       {
+         as_warn ("Length of .comm \"%s\" is already %ld. Not changed to %d.",
+                  S_GET_NAME (symbolP), (long) S_GET_VALUE (symbolP), size);
+       }
+    }
+  know (symbolP->sy_frag == &zero_address_frag);
+  if (*input_line_pointer != ',')
+    have_align = 0;
+  else
+    {
+      have_align = 1;
+      input_line_pointer++;
+      SKIP_WHITESPACE ();
+    }
+  if (! have_align || *input_line_pointer != '"')
+    {
+      if (! have_align)
+       temp = 0;
+      else
+       {
+         temp = get_absolute_expression ();
+         if (temp < 0)
+           {
+             temp = 0;
+             as_warn ("Common alignment negative; 0 assumed");
+           }
+       }
+      if (symbolP->local)
+       {
+         segT   old_sec;
+         int    old_subsec;
+         char * pfrag;
+         int    align;
+
+       /* allocate_bss: */
+         old_sec = now_seg;
+         old_subsec = now_subseg;
+         if (temp)
+           {
+             /* convert to a power of 2 alignment */
+             for (align = 0; (temp & 1) == 0; temp >>= 1, ++align);
+             if (temp != 1)
+               {
+                 as_bad ("Common alignment not a power of 2");
+                 ignore_rest_of_line ();
+                 return;
+               }
+           }
+         else
+           align = 0;
+         switch (area)
+           {
+           case AREA_SDA:
+             record_alignment (sbss_section, align);
+             obj_elf_section_change_hook();
+             subseg_set (sbss_section, 0);
+             break;
+
+           case AREA_ZDA:
+             record_alignment (zbss_section, align);
+             obj_elf_section_change_hook();
+             subseg_set (zbss_section, 0);
+             break;
+
+           case AREA_TDA:
+             record_alignment (tbss_section, align);
+             obj_elf_section_change_hook();
+             subseg_set (tbss_section, 0);
+             break;
+
+           default:
+             abort();
+           }
+         
+         if (align)
+           frag_align (align, 0, 0);
+
+         switch (area)
+           {
+           case AREA_SDA:
+             if (S_GET_SEGMENT (symbolP) == sbss_section)
+               symbolP->sy_frag->fr_symbol = 0;
+             break;
+
+           case AREA_ZDA:
+             if (S_GET_SEGMENT (symbolP) == zbss_section)
+               symbolP->sy_frag->fr_symbol = 0;
+             break;
+
+           case AREA_TDA:
+             if (S_GET_SEGMENT (symbolP) == tbss_section)
+               symbolP->sy_frag->fr_symbol = 0;
+             break;
+
+           default:
+             abort();
+           }
+         
+         symbolP->sy_frag = frag_now;
+         pfrag = frag_var (rs_org, 1, 1, (relax_substateT) 0, symbolP,
+                           (offsetT) size, (char *) 0);
+         *pfrag = 0;
+         S_SET_SIZE (symbolP, size);
+         
+         switch (area)
+           {
+           case AREA_SDA: S_SET_SEGMENT (symbolP, sbss_section); break;
+           case AREA_ZDA: S_SET_SEGMENT (symbolP, zbss_section); break;
+           case AREA_TDA: S_SET_SEGMENT (symbolP, tbss_section); break;
+           default:
+             abort();
+           }
+           
+         S_CLEAR_EXTERNAL (symbolP);
+         obj_elf_section_change_hook();
+         subseg_set (old_sec, old_subsec);
+       }
+      else
+       {
+       allocate_common:
+         S_SET_VALUE (symbolP, (valueT) size);
+         S_SET_ALIGN (symbolP, temp);
+         S_SET_EXTERNAL (symbolP);
+         
+         switch (area)
+           {
+           case AREA_SDA: S_SET_SEGMENT (symbolP, scommon_section); break;
+           case AREA_ZDA: S_SET_SEGMENT (symbolP, zcommon_section); break;
+           case AREA_TDA: S_SET_SEGMENT (symbolP, tcommon_section); break;
+           default:
+             abort();
+           }
+       }
+    }
+  else
+    {
+      input_line_pointer++;
+      /* @@ Some use the dot, some don't.  Can we get some consistency??  */
+      if (*input_line_pointer == '.')
+       input_line_pointer++;
+      /* @@ Some say data, some say bss.  */
+      if (strncmp (input_line_pointer, "bss\"", 4)
+         && strncmp (input_line_pointer, "data\"", 5))
+       {
+         while (*--input_line_pointer != '"')
+           ;
+         input_line_pointer--;
+         goto bad_common_segment;
+       }
+      while (*input_line_pointer++ != '"')
+       ;
+      goto allocate_common;
+    }
+
+  symbolP->bsym->flags |= BSF_OBJECT;
+
+  demand_empty_rest_of_line ();
+  return;
+
+  {
+  bad_common_segment:
+    p = input_line_pointer;
+    while (*p && *p != '\n')
+      p++;
+    c = *p;
+    *p = '\0';
+    as_bad ("bad .common segment %s", input_line_pointer + 1);
+    *p = c;
+    input_line_pointer = p;
+    ignore_rest_of_line ();
+    return;
+  }
+}
+
 void
 set_machine (int number)
 {
@@ -260,8 +493,10 @@ const pseudo_typeS md_pseudo_table[] =
   {"rozdata", v850_rozdata, 0},
   {"bss",     v850_bss,     0},
   {"offset",  v850_offset,  0},
-  {"section", v850_section, 0},
   {"word",    cons,         4},
+  {"zcomm",   v850_comm,    AREA_ZDA},
+  {"scomm",   v850_comm,    AREA_SDA},
+  {"tcomm",   v850_comm,    AREA_TDA},
   {"v850",    set_machine,  0},
 /* start-sanitize-v850e */
   {"call_table_data", v850_call_table_data, 0},
@@ -324,6 +559,7 @@ static const struct reg_name pre_defined_registers[] =
 static const struct reg_name system_registers[] = 
 {
 /* start-sanitize-v850e */
+
   { "ctbp",  20 },
   { "ctpc",  16 },
   { "ctpsw", 17 },
@@ -580,9 +816,10 @@ skip_white_space (void)
  *     insn                is the partially constructed instruction.
  *     operand             is the operand being inserted.
  *
- * out: True if the parse completed successfully, False otherwise.
- *      If the parse completes the correct bit fields in the
- *      instruction will be filled in.
+ * out: NULL if the parse completed successfully, otherwise a
+ *      pointer to an error message is returned.  If the parse
+ *      completes the correct bit fields in the instruction
+ *      will be filled in.
  *
  * Parses register lists with the syntax:
  *
@@ -627,7 +864,7 @@ parse_register_list
   skip_white_space();
 
   /* If the expression starts with a curly brace it is a register list.
-     Otherwise it is a constant expression ,whoes bits indicate which
+     Otherwise it is a constant expressionwhoes bits indicate which
      registers are to be included in the list.  */
   
   if (* input_line_pointer != '{')
@@ -919,32 +1156,47 @@ md_convert_frag (abfd, sec, fragP)
   fragS *    fragP;
 {
   subseg_change (sec, 0);
-  if (fragP->fr_subtype == 0)
+  
+  /* In range conditional or unconditional branch.  */
+  if (fragP->fr_subtype == 0 || fragP->fr_subtype == 2)
     {
       fix_new (fragP, fragP->fr_fix, 2, fragP->fr_symbol,
               fragP->fr_offset, 1, BFD_RELOC_UNUSED + (int)fragP->fr_opcode);
       fragP->fr_var = 0;
       fragP->fr_fix += 2;
     }
+  /* Out of range conditional branch.  Emit a branch around a jump.  */
   else if (fragP->fr_subtype == 1)
     {
+      unsigned char *buffer = 
+       (unsigned char *) (fragP->fr_fix + fragP->fr_literal);
+
       /* Reverse the condition of the first branch.  */
-      fragP->fr_literal[0] &= 0xf7;
+      buffer[0] ^= 0x08;
       /* Mask off all the displacement bits.  */
-      fragP->fr_literal[0] &= 0x8f;
-      fragP->fr_literal[1] &= 0x07;
+      buffer[0] &= 0x8f;
+      buffer[1] &= 0x07;
       /* Now set the displacement bits so that we branch
         around the unconditional branch.  */
-      fragP->fr_literal[0] |= 0x30;
+      buffer[0] |= 0x30;
 
       /* Now create the unconditional branch + fixup to the final
         target.  */
-      md_number_to_chars (&fragP->fr_literal[2], 0x00000780, 4);
+      md_number_to_chars (buffer + 2, 0x00000780, 4);
       fix_new (fragP, fragP->fr_fix + 2, 4, fragP->fr_symbol,
               fragP->fr_offset, 1, BFD_RELOC_UNUSED + (int)fragP->fr_opcode + 1);
       fragP->fr_var = 0;
       fragP->fr_fix += 6;
     }
+  /* Out of range unconditional branch.  Emit a jump.  */
+  else if (fragP->fr_subtype == 3)
+    {
+      md_number_to_chars (fragP->fr_fix + fragP->fr_literal, 0x00000780, 4);
+      fix_new (fragP, fragP->fr_fix, 4, fragP->fr_symbol,
+              fragP->fr_offset, 1, BFD_RELOC_UNUSED + (int)fragP->fr_opcode + 1);
+      fragP->fr_var = 0;
+      fragP->fr_fix += 4;
+    }
   else
     abort ();
 }
@@ -1029,12 +1281,15 @@ md_begin ()
   
   sbss_section = subseg_new (".sbss", 0);
   bfd_set_section_flags (stdoutput, sbss_section, applicable & SEC_ALLOC);
+  seg_info (sbss_section)->bss = 1;
   
   tbss_section = subseg_new (".tbss", 0);
   bfd_set_section_flags (stdoutput, tbss_section, applicable & SEC_ALLOC);
+  seg_info (tbss_section)->bss = 1;
   
   zbss_section = subseg_new (".zbss", 0);
   bfd_set_section_flags (stdoutput, zbss_section, applicable & SEC_ALLOC);
+  seg_info (zbss_section)->bss = 1;
   
   rosdata_section = subseg_new (".rosdata", 0);
   bfd_set_section_flags (stdoutput, rosdata_section, applicable & (SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_READONLY));
@@ -1042,6 +1297,12 @@ md_begin ()
   rozdata_section = subseg_new (".rozdata", 0);
   bfd_set_section_flags (stdoutput, rozdata_section, applicable & (SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_READONLY));
 
+  scommon_section = subseg_new (".scommon", 0);
+  bfd_set_section_flags (stdoutput, scommon_section, applicable & (SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_DATA | SEC_HAS_CONTENTS | SEC_IS_COMMON));
+
+  zcommon_section = subseg_new (".zcommon", 0);
+  bfd_set_section_flags (stdoutput, zcommon_section, applicable & (SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_DATA | SEC_HAS_CONTENTS | SEC_IS_COMMON));
+
 /* start-sanitize-v850e */
   call_table_data_section = subseg_new (".call_table_data", 0);
   bfd_set_section_flags (stdoutput, call_table_data_section, applicable & (SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_DATA | SEC_HAS_CONTENTS));
@@ -1162,7 +1423,7 @@ v850_reloc_prefix (const struct v850_operand * operand)
   CHECK_ ("tdaoff", handle_tdaoff (operand));
 
 /* start-sanitize-v850e */
-  CHECK_ ("hilo", BFD_RELOC_32);
+  CHECK_ ("hilo",   BFD_RELOC_32);
   CHECK_ ("ctoff",  handle_ctoff (operand));
 /* end-sanitize-v850e */
   
@@ -1193,7 +1454,7 @@ md_assemble (str)
   unsigned                  extra_data_len;
   unsigned long             extra_data;
   char *                   saved_input_line_pointer;
-  
+
   /* Get the opcode.  */
   for (s = str; *s != '\0' && ! isspace (*s); s++)
     continue;
@@ -1491,7 +1752,7 @@ md_assemble (str)
              if (errmsg)
                goto error;
              
-/* fprintf (stderr, "insn: %x, operand %d, op: %d, add_number: %d\n", insn, opindex_ptr - opcode->operands, ex.X_op, ex.X_add_number ); */
+/* fprintf (stderr, " insn: %x, operand %d, op: %d, add_number: %d\n", insn, opindex_ptr - opcode->operands, ex.X_op, ex.X_add_number); */
 
              switch (ex.X_op) 
                {
@@ -1564,22 +1825,35 @@ md_assemble (str)
 
   input_line_pointer = str;
 
-  /* Write out the instruction.
-
-     Four byte insns have an opcode with the two high bits on.  */ 
+  /* Write out the instruction. */
+  
   if (relaxable && fc > 0)
     {
-      f = frag_var (rs_machine_dependent, 6, 4, 0,
-                   fixups[0].exp.X_add_symbol,
-                   fixups[0].exp.X_add_number,
-                   (char *)fixups[0].opindex);
       insn_size = 2;
-      md_number_to_chars (f, insn, insn_size);
-      md_number_to_chars (f + 2, 0, 4);
       fc = 0;
+
+      if (!strcmp (opcode->name, "br"))
+       {
+         f = frag_var (rs_machine_dependent, 4, 2, 2,
+                       fixups[0].exp.X_add_symbol,
+                       fixups[0].exp.X_add_number,
+                       (char *)fixups[0].opindex);
+         md_number_to_chars (f, insn, insn_size);
+         md_number_to_chars (f + 2, 0, 2);
+       }
+      else
+       {
+         f = frag_var (rs_machine_dependent, 6, 4, 0,
+                       fixups[0].exp.X_add_symbol,
+                       fixups[0].exp.X_add_number,
+                       (char *)fixups[0].opindex);
+         md_number_to_chars (f, insn, insn_size);
+         md_number_to_chars (f + 2, 0, 4);
+       }
     }
   else 
     {
+      /* Four byte insns have an opcode with the two high bits on.  */
       if ((insn & 0x0600) == 0x0600)
        insn_size = 4;
       else
@@ -1708,7 +1982,12 @@ md_estimate_size_before_relax (fragp, seg)
      fragS * fragp;
      asection * seg;
 {
-  fragp->fr_var = 4;
+  if (fragp->fr_subtype == 0)
+    fragp->fr_var = 4;
+  else if (fragp->fr_subtype == 2)
+    fragp->fr_var = 2;
+  else
+    abort ();
   return 2;
 } 
 
@@ -1806,6 +2085,7 @@ md_apply_fix3 (fixp, valuep, seg)
     {
       /* We still have to insert the value into memory!  */
       where = fixp->fx_frag->fr_literal + fixp->fx_where;
+
       if (fixp->fx_size == 1)
        *where = value & 0xff;
       else if (fixp->fx_size == 2)
index 449777a..ddbb2e6 100644 (file)
 /* The target BFD format.  */
 #define TARGET_FORMAT          "elf32-v850"
 
-/* The target BFD machine number.  */
-#define TARGET_MACHINE                 0
-/* start-sanitize-v850e */
-#undef  TARGET_MACHINE
-#define TARGET_MACHINE                 bfd_mach_v850e
-/* end-sanitize-v850e */
-/* start-sanitize-v850eq */
-#undef  TARGET_MACHINE
-#define TARGET_MACHINE                 bfd_mach_v850eq
-/* end-sanitize-v850eq */
-
-/* The target processor mask.  */
-#define TARGET_PROCESSOR       PROCESSOR_V850
-/* start-sanitize-v850e */
-#undef  TARGET_PROCESSOR
-#define TARGET_PROCESSOR       PROCESSOR_V850E
-/* end-sanitize-v850e */
-/* start-sanitize-v850eq */
-#undef  TARGET_PROCESSOR
-#define TARGET_PROCESSOR       PROCESSOR_V850EQ
-/* end-sanitize-v850eq */
-
 
 #define MD_APPLY_FIX3
 #define md_operand(x)
@@ -87,8 +65,13 @@ extern const struct relax_type md_relax_table[];
   { ".sdata",  SHT_PROGBITS,   SHF_ALLOC + SHF_WRITE + SHF_V850_GPREL  }, \
   { ".sbss",   SHT_NOBITS,     SHF_ALLOC + SHF_WRITE + SHF_V850_GPREL  }, \
   { ".rosdata",        SHT_PROGBITS,   SHF_ALLOC +             SHF_V850_GPREL  }, \
+  { ".scommon",        SHT_NOBITS,     SHF_ALLOC + SHF_WRITE + SHF_V850_GPREL  }, \
   { ".tdata",  SHT_PROGBITS,   SHF_ALLOC + SHF_WRITE + SHF_V850_EPREL  }, \
+  { ".tbss",   SHT_NOBITS,     SHF_ALLOC + SHF_WRITE + SHF_V850_EPREL  }, \
   { ".zdata",  SHT_PROGBITS,   SHF_ALLOC + SHF_WRITE + SHF_V850_R0REL  }, \
   { ".rozdata",        SHT_PROGBITS,   SHF_ALLOC +             SHF_V850_R0REL  }, \
-  { ".zbss",   SHT_NOBITS,     SHF_ALLOC + SHF_WRITE + SHF_V850_R0REL  },
+  { ".zcommon",        SHT_NOBITS,     SHF_ALLOC + SHF_WRITE + SHF_V850_R0REL  }, \
+  { ".zbss",   SHT_NOBITS,     SHF_ALLOC + SHF_WRITE + SHF_V850_R0REL  }, \
+  { ".call_table_data",        SHT_PROGBITS,   SHF_ALLOC + SHF_WRITE },           \
+  { ".call_table_text",        SHT_PROGBITS,   SHF_ALLOC + SHF_WRITE + SHF_EXECINSTR },