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]

Consolidate .comm and .lcomm code


Removes some duplication of code by merging code that handles .comm and
.lcomm.  In the process, the generic code gets the better error checking
of obj-elf.c, eg. that the size of a common var doesn't exceed that
representable by arch_info->bits_per_address.  This does change some
error messages (sorry translators!) because it's not appropriate to
mention ".comm" when emitting an error for ".lcomm".

gas/ChangeLog
	* read.c: Remove unneeded prototypes.
	(s_comm): Split out code to..
	(s_comm_internal): ..here.  Tidy error returns.  Rearrange so that
	"name" from input line may be used in more places.  Merge code
	testing for valid size from elf_common.  Merge code from
	s_lcomm_internal.  Call comm_parse_extra.
	(bss_alloc): New function, split out of s_lcomm_internal and
	elf_common.
	(parse_align): Likewise.
	(s_lcomm_internal): Rewrite.
	(s_lcomm, s_lcomm_bytes): Use s_comm_internal.
	* read.h (bss_alloc, parse_align, s_comm_internal): Declare.
	* config/obj-elf.c (elf_common): Split out code to..
	(elf_common_parse): ..here.  Remove code common to s_comm_internal,
	parse_align and bss_alloc.  Rearrange and Tidy.
	* config/tc-alpha.h (TC_IMPLICIT_LCOMM_ALIGNMENT): Define.

Index: gas/read.c
===================================================================
RCS file: /cvs/src/src/gas/read.c,v
retrieving revision 1.71
diff -c -p -r1.71 read.c
*** gas/read.c	27 Nov 2003 19:14:41 -0000	1.71
--- gas/read.c	13 Dec 2003 02:53:13 -0000
*************** static int dwarf_file_string;
*** 214,235 ****
  #endif
  #endif
  
- static void cons_worker (int, int);
- static int scrub_from_string (char *, int);
  static void do_align (int, char *, int, int);
  static void s_align (int, int);
- static void s_lcomm_internal (int, int);
  static int hex_float (int, char *);
- static inline int sizeof_sleb128 (offsetT);
- static inline int sizeof_uleb128 (valueT);
- static inline int output_sleb128 (char *, offsetT);
- static inline int output_uleb128 (char *, valueT);
- static inline int output_big_sleb128 (char *, LITTLENUM_TYPE *, int);
- static inline int output_big_uleb128 (char *, LITTLENUM_TYPE *, int);
- static int output_big_leb128 (char *, LITTLENUM_TYPE *, int, int);
- static void do_org (segT, expressionS *, int);
- char *demand_copy_string (int *lenP);
- static segT get_segmented_expression (expressionS *expP);
  static segT get_known_segmented_expression (expressionS * expP);
  static void pobegin (void);
  static int get_line_sb (sb *);
--- 214,222 ----
*************** s_align_ptwo (int arg)
*** 1328,1343 ****
    s_align (arg, 0);
  }
  
! void
! s_comm (int ignore ATTRIBUTE_UNUSED)
  {
!   register char *name;
!   register char c;
!   register char *p;
!   offsetT temp;
!   register symbolS *symbolP;
    char *stop = NULL;
    char stopc;
  
    if (flag_mri)
      stop = mri_comment_field (&stopc);
--- 1315,1332 ----
    s_align (arg, 0);
  }
  
! symbolS *
! s_comm_internal (int param,
! 		 symbolS *(*comm_parse_extra) (int, symbolS *, addressT))
  {
!   char *name;
!   char c;
!   char *p;
!   offsetT temp, size;
!   symbolS *symbolP = NULL;
    char *stop = NULL;
    char stopc;
+   expressionS exp;
  
    if (flag_mri)
      stop = mri_comment_field (&stopc);
*************** s_comm (int ignore ATTRIBUTE_UNUSED)
*** 1352,1426 ****
      {
        as_bad (_("expected symbol name"));
        discard_rest_of_line ();
!       return;
      }
  
    SKIP_WHITESPACE ();
  
!   if (*input_line_pointer != ',')
      {
!       *p = 0;
!       as_bad (_("expected comma after \"%s\""), name);
        *p = c;
        ignore_rest_of_line ();
!       if (flag_mri)
! 	mri_comment_end (stop, stopc);
!       return;
      }
! 
!   input_line_pointer++;		/* skip ',' */
! 
!   if ((temp = get_absolute_expression ()) < 0)
      {
!       as_warn (_(".COMMon length (%lu) out of range ignored"),
! 	       (unsigned long) temp);
        ignore_rest_of_line ();
!       if (flag_mri)
! 	mri_comment_end (stop, stopc);
!       return;
      }
  
-   *p = 0;
    symbolP = symbol_find_or_make (name);
-   *p = c;
- 
    if (S_IS_DEFINED (symbolP) && !S_IS_COMMON (symbolP))
      {
!       as_bad (_("symbol `%s' is already defined"),
! 	      S_GET_NAME (symbolP));
        ignore_rest_of_line ();
!       if (flag_mri)
! 	mri_comment_end (stop, stopc);
!       return;
      }
  
!   if (S_GET_VALUE (symbolP))
!     {
!       if (S_GET_VALUE (symbolP) != (valueT) temp)
! 	as_bad (_("length of .comm \"%s\" is already %ld; not changing to %ld"),
! 		S_GET_NAME (symbolP),
! 		(long) S_GET_VALUE (symbolP),
! 		(long) temp);
!     }
    else
      {
!       S_SET_VALUE (symbolP, (valueT) temp);
        S_SET_EXTERNAL (symbolP);
-     }
  #ifdef OBJ_VMS
!   {
!     extern int flag_one;
!     if (!temp || !flag_one)
!       S_GET_OTHER(symbolP) = const_flag;
!   }
! #endif /* not OBJ_VMS */
!   know (symbolP->sy_frag == &zero_address_frag);
  
    demand_empty_rest_of_line ();
! 
    if (flag_mri)
      mri_comment_end (stop, stopc);
! }				/* s_comm() */
  
  /* The MRI COMMON pseudo-op.  We handle this by creating a common
     symbol with the appropriate name.  We make s_space do the right
--- 1341,1423 ----
      {
        as_bad (_("expected symbol name"));
        discard_rest_of_line ();
!       goto out;
      }
  
    SKIP_WHITESPACE ();
  
!   /* Accept an optional comma after the name.  The comma used to be
!      required, but Irix 5 cc does not generate it for .lcomm.  */
!   if (*input_line_pointer == ',')
!     input_line_pointer++;
! 
!   *p = 0;
!   temp = get_absolute_expr (&exp);
!   size = temp;
! #ifdef BFD_ASSEMBLER
!   size &= ((offsetT) 2 << (stdoutput->arch_info->bits_per_address - 1)) - 1;
! #endif
!   if (exp.X_op == O_absent)
      {
!       as_bad (_("missing size expression"));
        *p = c;
        ignore_rest_of_line ();
!       goto out;
      }
!   else if (temp != size || !exp.X_unsigned)
      {
!       as_warn (_("size (%ld) out of range, ignored"), (long) temp);
!       *p = c;
        ignore_rest_of_line ();
!       goto out;
      }
  
    symbolP = symbol_find_or_make (name);
    if (S_IS_DEFINED (symbolP) && !S_IS_COMMON (symbolP))
      {
!       symbolP = NULL;
!       as_bad (_("symbol `%s' is already defined"), name);
!       *p = c;
        ignore_rest_of_line ();
!       goto out;
      }
  
!   size = S_GET_VALUE (symbolP);
!   if (size == 0)
!     size = temp;
!   else if (size != temp)
!     as_warn (_("size of \"%s\" is already %ld; not changing to %ld"),
! 	     name, (long) size, (long) temp);
! 
!   *p = c;
!   if (comm_parse_extra != NULL)
!     symbolP = (*comm_parse_extra) (param, symbolP, size);
    else
      {
!       S_SET_VALUE (symbolP, (valueT) size);
        S_SET_EXTERNAL (symbolP);
  #ifdef OBJ_VMS
!       {
! 	extern int flag_one;
! 	if (size == 0 || !flag_one)
! 	  S_GET_OTHER (symbolP) = const_flag;
!       }
! #endif
!     }
  
+   know (symbolP == NULL || symbolP->sy_frag == &zero_address_frag);
    demand_empty_rest_of_line ();
!  out:
    if (flag_mri)
      mri_comment_end (stop, stopc);
!   return symbolP;
! }
! 
! void
! s_comm (int ignore)
! {
!   s_comm_internal (ignore, NULL);
! }
  
  /* The MRI COMMON pseudo-op.  We handle this by creating a common
     symbol with the appropriate name.  We make s_space do the right
*************** s_linkonce (int ignore ATTRIBUTE_UNUSED)
*** 1917,1983 ****
    demand_empty_rest_of_line ();
  }
  
! static void
! s_lcomm_internal (/* 1 if this was a ".bss" directive, which may
! 		     require a 3rd argument (alignment); 0 if it was
! 		     an ".lcomm" (2 args only).  */
! 		  int needs_align,
! 		  /* 1 if the alignment value should be interpreted as
! 		     the byte boundary, rather than the power of 2.  */
! 		  int bytes_p)
  {
!   register char *name;
!   register char c;
!   register char *p;
!   register int temp;
!   register symbolS *symbolP;
    segT current_seg = now_seg;
    subsegT current_subseg = now_subseg;
-   const int max_alignment = 15;
-   int align = 0;
    segT bss_seg = bss_section;
  
-   name = input_line_pointer;
-   c = get_symbol_end ();
-   p = input_line_pointer;
-   *p = c;
- 
-   if (name == p)
-     {
-       as_bad (_("expected symbol name"));
-       discard_rest_of_line ();
-       return;
-     }
- 
-   SKIP_WHITESPACE ();
- 
-   /* Accept an optional comma after the name.  The comma used to be
-      required, but Irix 5 cc does not generate it.  */
-   if (*input_line_pointer == ',')
-     {
-       ++input_line_pointer;
-       SKIP_WHITESPACE ();
-     }
- 
-   if (is_end_of_line[(unsigned char) *input_line_pointer])
-     {
-       as_bad (_("missing size expression"));
-       return;
-     }
- 
-   if ((temp = get_absolute_expression ()) < 0)
-     {
-       as_warn (_("BSS length (%d) < 0 ignored"), temp);
-       ignore_rest_of_line ();
-       return;
-     }
- 
  #if defined (TC_MIPS) || defined (TC_ALPHA)
    if (OUTPUT_FLAVOR == bfd_target_ecoff_flavour
        || OUTPUT_FLAVOR == bfd_target_elf_flavour)
      {
        /* For MIPS and Alpha ECOFF or ELF, small objects are put in .sbss.  */
!       if ((unsigned) temp <= bfd_get_gp_size (stdoutput))
  	{
  	  bss_seg = subseg_new (".sbss", 1);
  	  seg_info (bss_seg)->bss = 1;
--- 1914,1933 ----
    demand_empty_rest_of_line ();
  }
  
! void
! bss_alloc (symbolS *symbolP, addressT size, int align)
  {
!   char *pfrag;
    segT current_seg = now_seg;
    subsegT current_subseg = now_subseg;
    segT bss_seg = bss_section;
  
  #if defined (TC_MIPS) || defined (TC_ALPHA)
    if (OUTPUT_FLAVOR == bfd_target_ecoff_flavour
        || OUTPUT_FLAVOR == bfd_target_elf_flavour)
      {
        /* For MIPS and Alpha ECOFF or ELF, small objects are put in .sbss.  */
!       if (size <= bfd_get_gp_size (stdoutput))
  	{
  	  bss_seg = subseg_new (".sbss", 1);
  	  seg_info (bss_seg)->bss = 1;
*************** s_lcomm_internal (/* 1 if this was a ".b
*** 1989,2135 ****
  	}
      }
  #endif
  
!   if (!needs_align)
      {
!       TC_IMPLICIT_LCOMM_ALIGNMENT (temp, align);
! 
!       /* Still zero unless TC_IMPLICIT_LCOMM_ALIGNMENT set it.  */
!       if (align)
! 	record_alignment (bss_seg, align);
      }
  
!   if (needs_align)
!     {
!       align = 0;
!       SKIP_WHITESPACE ();
  
!       if (*input_line_pointer != ',')
! 	{
! 	  as_bad (_("expected comma after size"));
! 	  ignore_rest_of_line ();
! 	  return;
! 	}
  
!       input_line_pointer++;
!       SKIP_WHITESPACE ();
  
!       if (is_end_of_line[(unsigned char) *input_line_pointer])
! 	{
! 	  as_bad (_("missing alignment"));
! 	  return;
! 	}
  
!       align = get_absolute_expression ();
  
!       if (bytes_p)
! 	{
! 	  /* Convert to a power of 2.  */
! 	  if (align != 0)
! 	    {
! 	      unsigned int i;
  
! 	      for (i = 0; (align & 1) == 0; align >>= 1, ++i)
! 		;
! 	      if (align != 1)
! 		as_bad (_("alignment not a power of 2"));
! 	      align = i;
! 	    }
! 	}
  
!       if (align > max_alignment)
! 	{
! 	  align = max_alignment;
! 	  as_warn (_("alignment too large; %d assumed"), align);
! 	}
!       else if (align < 0)
! 	{
! 	  align = 0;
! 	  as_warn (_("alignment negative; 0 assumed"));
! 	}
  
!       record_alignment (bss_seg, align);
      }
!   else
      {
!       /* Assume some objects may require alignment on some systems.  */
! #if defined (TC_ALPHA) && ! defined (VMS)
!       if (temp > 1)
  	{
! 	  align = ffs (temp) - 1;
! 	  if (temp % (1 << align))
! 	    abort ();
  	}
! #endif
      }
  
!   *p = 0;
!   symbolP = symbol_find_or_make (name);
!   *p = c;
! 
!   if (
! #if (defined (OBJ_AOUT) || defined (OBJ_MAYBE_AOUT) \
!      || defined (OBJ_BOUT) || defined (OBJ_MAYBE_BOUT))
! #ifdef BFD_ASSEMBLER
!       (OUTPUT_FLAVOR != bfd_target_aout_flavour
!        || (S_GET_OTHER (symbolP) == 0 && S_GET_DESC (symbolP) == 0)) &&
! #else
!       (S_GET_OTHER (symbolP) == 0 && S_GET_DESC (symbolP) == 0) &&
! #endif
! #endif
!       (S_GET_SEGMENT (symbolP) == bss_seg
!        || (!S_IS_DEFINED (symbolP) && S_GET_VALUE (symbolP) == 0)))
!     {
!       char *pfrag;
! 
!       subseg_set (bss_seg, 1);
! 
!       if (align)
! 	frag_align (align, 0, 0);
! 
!       /* Detach from old frag.  */
!       if (S_GET_SEGMENT (symbolP) == bss_seg)
! 	symbol_get_frag (symbolP)->fr_symbol = NULL;
! 
!       symbol_set_frag (symbolP, frag_now);
!       pfrag = frag_var (rs_org, 1, 1, (relax_substateT) 0, symbolP,
! 			(offsetT) temp, (char *) 0);
!       *pfrag = 0;
! 
!       S_SET_SEGMENT (symbolP, bss_seg);
  
! #ifdef OBJ_COFF
!       /* The symbol may already have been created with a preceding
! 	 ".globl" directive -- be careful not to step on storage class
! 	 in that case.  Otherwise, set it to static.  */
!       if (S_GET_STORAGE_CLASS (symbolP) != C_EXT)
! 	{
! 	  S_SET_STORAGE_CLASS (symbolP, C_STAT);
! 	}
! #endif /* OBJ_COFF */
  
! #ifdef S_SET_SIZE
!       S_SET_SIZE (symbolP, temp);
! #endif
      }
    else
!     as_bad (_("symbol `%s' is already defined"), S_GET_NAME (symbolP));
! 
!   subseg_set (current_seg, current_subseg);
  
!   demand_empty_rest_of_line ();
  }
  
  void
  s_lcomm (int needs_align)
  {
!   s_lcomm_internal (needs_align, 0);
  }
  
  void
  s_lcomm_bytes (int needs_align)
  {
!   s_lcomm_internal (needs_align, 1);
  }
  
  void
--- 1939,2056 ----
  	}
      }
  #endif
+   subseg_set (bss_seg, 1);
  
!   if (align)
      {
!       record_alignment (bss_seg, align);
!       frag_align (align, 0, 0);
      }
  
!   /* Detach from old frag.  */
!   if (S_GET_SEGMENT (symbolP) == bss_seg)
!     symbol_get_frag (symbolP)->fr_symbol = NULL;
  
!   symbol_set_frag (symbolP, frag_now);
!   pfrag = frag_var (rs_org, 1, 1, 0, symbolP, size, NULL);
!   *pfrag = 0;
  
! #ifdef S_SET_SIZE
!   S_SET_SIZE (symbolP, size);
! #endif
!   S_SET_SEGMENT (symbolP, bss_seg);
  
! #ifdef OBJ_COFF
!   /* The symbol may already have been created with a preceding
!      ".globl" directive -- be careful not to step on storage class
!      in that case.  Otherwise, set it to static.  */
!   if (S_GET_STORAGE_CLASS (symbolP) != C_EXT)
!     S_SET_STORAGE_CLASS (symbolP, C_STAT);
! #endif /* OBJ_COFF */
  
!   subseg_set (current_seg, current_subseg);
! }
  
! offsetT
! parse_align (int align_bytes)
! {
!   expressionS exp;
!   addressT align;
  
!   SKIP_WHITESPACE ();
!   if (*input_line_pointer != ',')
!     {
!     no_align:
!       as_bad (_("expected alignment after size"));
!       ignore_rest_of_line ();
!       return -1;
!     }
  
!   input_line_pointer++;
!   SKIP_WHITESPACE ();
  
!   align = get_absolute_expr (&exp);
!   if (exp.X_op == O_absent)
!     goto no_align;
! 
!   if (!exp.X_unsigned)
!     {
!       as_warn (_("alignment negative; 0 assumed"));
!       align = 0;
      }
! 
!   if (align_bytes && align != 0)
      {
!       /* convert to a power of 2 alignment */
!       unsigned int alignp2 = 0;
!       while ((align & 1) == 0)
! 	align >>= 1, ++alignp2;
!       if (align != 1)
  	{
! 	  as_bad (_("alignment not a power of 2"));
! 	  ignore_rest_of_line ();
! 	  return -1;
  	}
!       align = alignp2;
      }
+   return align;
+ }
  
! /* Called from s_comm_internal after symbol name and size have been
!    parsed.  NEEDS_ALIGN is 0 if it was an ".lcomm" (2 args only),
!    1 if this was a ".bss" directive which has a 3rd argument
!    (alignment as a power of 2), or 2 if this was a ".bss" directive
!    with alignment in bytes.  */
  
! static symbolS *
! s_lcomm_internal (int needs_align, symbolS *symbolP, addressT size)
! {
!   addressT align = 0;
  
!   if (needs_align)
!     {
!       align = parse_align (needs_align - 1);
!       if (align == (addressT) -1)
! 	return NULL;
      }
    else
!     /* Assume some objects may require alignment on some systems.  */
!     TC_IMPLICIT_LCOMM_ALIGNMENT (size, align);
  
!   bss_alloc (symbolP, size, align);
!   return symbolP;
  }
  
  void
  s_lcomm (int needs_align)
  {
!   s_comm_internal (needs_align, s_lcomm_internal);
  }
  
  void
  s_lcomm_bytes (int needs_align)
  {
!   s_comm_internal (needs_align * 2, s_lcomm_internal);
  }
  
  void
Index: gas/read.h
===================================================================
RCS file: /cvs/src/src/gas/read.h,v
retrieving revision 1.19
diff -c -p -r1.19 read.h
*** gas/read.h	27 Nov 2003 19:14:41 -0000	1.19
--- gas/read.h	13 Dec 2003 02:53:13 -0000
*************** extern void generate_lineno_debug (void)
*** 139,144 ****
--- 139,147 ----
  extern void s_abort (int) ATTRIBUTE_NORETURN;
  extern void s_align_bytes (int arg);
  extern void s_align_ptwo (int);
+ extern void bss_alloc (symbolS *, addressT, int);
+ extern offsetT parse_align (int);
+ extern symbolS *s_comm_internal (int, symbolS *(*) (int, symbolS *, addressT));
  extern void s_app_file_string (char *);
  extern void s_app_file (int);
  extern void s_app_line (int);
Index: gas/config/obj-elf.c
===================================================================
RCS file: /cvs/src/src/gas/config/obj-elf.c,v
retrieving revision 1.76
diff -c -p -r1.76 obj-elf.c
*** gas/config/obj-elf.c	3 Dec 2003 03:20:13 -0000	1.76
--- gas/config/obj-elf.c	13 Dec 2003 02:53:14 -0000
*************** static void adjust_stab_sections PARAMS 
*** 63,69 ****
  static void build_group_lists PARAMS ((bfd *, asection *, PTR));
  static int elf_separate_stab_sections PARAMS ((void));
  static void elf_init_stab_section PARAMS ((segT));
- static symbolS *elf_common PARAMS ((int));
  
  #ifdef NEED_ECOFF_DEBUG
  static bfd_boolean elf_get_extr PARAMS ((asymbol *, EXTR *));
--- 63,68 ----
*************** elf_file_symbol (s)
*** 287,471 ****
  #endif
  }
  
  static symbolS *
! elf_common (is_common)
!      int is_common;
  {
!   char *name;
!   char c;
!   char *p;
!   offsetT temp, size, sign;
!   symbolS *symbolP;
!   int have_align;
!   expressionS exp;
  
!   if (flag_mri && is_common)
      {
!       s_mri_common (0);
!       return NULL;
!     }
  
-   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 NULL;
-     }
-   input_line_pointer++;		/* skip ',' */
-   temp = get_absolute_expr (&exp);
-   sign = (offsetT) 1 << (stdoutput->arch_info->bits_per_address - 1);
-   size = temp & ((sign << 1) - 1);
-   if (temp != size || !exp.X_unsigned)
-     {
-       as_bad (_(".COMMon length (%ld) out of range, ignored."), (long) temp);
-       ignore_rest_of_line ();
-       return NULL;
-     }
-   *p = 0;
-   symbolP = symbol_find_or_make (name);
-   *p = c;
-   if (S_IS_DEFINED (symbolP) && ! S_IS_COMMON (symbolP))
-     {
-       as_bad (_("symbol `%s' is already defined"), S_GET_NAME (symbolP));
-       ignore_rest_of_line ();
-       return NULL;
-     }
-   if (S_GET_VALUE (symbolP) != 0)
-     {
-       if (S_GET_VALUE (symbolP) != (valueT) size)
- 	{
- 	  as_warn (_("length of .comm \"%s\" is already %ld; not changed to %ld"),
- 		   S_GET_NAME (symbolP), (long) S_GET_VALUE (symbolP),
- 		   (long) 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_expr (&exp);
! 	  if (!exp.X_unsigned)
! 	    {
! 	      temp = 0;
! 	      as_warn (_("common alignment negative; 0 assumed"));
! 	    }
! 	}
!       if (symbol_get_obj (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 NULL;
! 		}
  	    }
! 	  else
! 	    align = 0;
! 	  record_alignment (bss_section, align);
! 	  subseg_set (bss_section, 0);
! 	  if (align)
! 	    frag_align (align, 0, 0);
! 	  if (S_GET_SEGMENT (symbolP) == bss_section)
! 	    symbol_get_frag (symbolP)->fr_symbol = 0;
! 	  symbol_set_frag (symbolP, frag_now);
! 	  pfrag = frag_var (rs_org, 1, 1, (relax_substateT) 0, symbolP,
! 			    (offsetT) size, (char *) 0);
! 	  *pfrag = 0;
! 	  S_SET_SIZE (symbolP, size);
! 	  S_SET_SEGMENT (symbolP, bss_section);
! 	  S_CLEAR_EXTERNAL (symbolP);
! 	  subseg_set (old_sec, old_subsec);
  	}
        else
  	{
! 	allocate_common:
! 	  S_SET_VALUE (symbolP, (valueT) size);
! 	  S_SET_ALIGN (symbolP, temp);
! 	  S_SET_EXTERNAL (symbolP);
! 	  S_SET_SEGMENT (symbolP, bfd_com_section_ptr);
  	}
      }
    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;
      }
  
    symbol_get_bfdsym (symbolP)->flags |= BSF_OBJECT;
  
-   demand_empty_rest_of_line ();
    return symbolP;
- 
-   {
-   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 NULL;
-   }
  }
  
  void
  obj_elf_common (is_common)
       int is_common;
  {
!   elf_common (is_common);
  }
  
  static void
  obj_elf_tls_common (ignore)
       int ignore ATTRIBUTE_UNUSED;
  {
!   symbolS *symbolP = elf_common (0);
  
    if (symbolP)
      symbol_get_bfdsym (symbolP)->flags |= BSF_THREAD_LOCAL;
--- 286,381 ----
  #endif
  }
  
+ /* Called from read.c:s_comm after we've parsed .comm symbol, size.
+    Parse a possible alignment value.  */
+ 
  static symbolS *
! elf_common_parse (int ignore ATTRIBUTE_UNUSED, symbolS *symbolP, addressT size)
  {
!   addressT align = 0;
!   int is_local = symbol_get_obj (symbolP)->local;
  
!   if (*input_line_pointer == ',')
      {
!       char *save = input_line_pointer;
  
        input_line_pointer++;
        SKIP_WHITESPACE ();
! 
!       if (*input_line_pointer == '"')
  	{
! 	  /* For sparc.  Accept .common symbol, length, "bss"  */
! 	  input_line_pointer++;
! 	  /* Some use the dot, some don't.  */
! 	  if (*input_line_pointer == '.')
! 	    input_line_pointer++;
! 	  /* Some say data, some say bss.  */
! 	  if (strncmp (input_line_pointer, "bss\"", 4) == 0)
! 	    input_line_pointer += 4;
! 	  else if (strncmp (input_line_pointer, "data\"", 5) == 0)
! 	    input_line_pointer += 5;
! 	  else
  	    {
! 	      char *p = input_line_pointer;
! 	      char c;
! 
! 	      while (*--p != '"')
! 		;
! 	      while (!is_end_of_line[(unsigned char) *input_line_pointer])
! 		if (*input_line_pointer++ == '"')
! 		  break;
! 	      c = *input_line_pointer;
! 	      *input_line_pointer = '\0';
! 	      as_bad (_("bad .common segment %s"), p);
! 	      *input_line_pointer = c;
! 	      ignore_rest_of_line ();
! 	      return NULL;
  	    }
! 	  /* ??? Don't ask me why these are always global.  */
! 	  is_local = 0;
  	}
        else
  	{
! 	  input_line_pointer = save;
! 	  align = parse_align (is_local);
! 	  if (align == (addressT) -1)
! 	    return NULL;
  	}
      }
+ 
+   if (is_local)
+     {
+       bss_alloc (symbolP, size, align);
+       S_CLEAR_EXTERNAL (symbolP);
+     }
    else
      {
!       S_SET_VALUE (symbolP, size);
!       S_SET_ALIGN (symbolP, align);
!       S_SET_EXTERNAL (symbolP);
!       S_SET_SEGMENT (symbolP, bfd_com_section_ptr);
      }
  
    symbol_get_bfdsym (symbolP)->flags |= BSF_OBJECT;
  
    return symbolP;
  }
  
  void
  obj_elf_common (is_common)
       int is_common;
  {
!   if (flag_mri && is_common)
!     s_mri_common (0);
!   else
!     s_comm_internal (0, elf_common_parse);
  }
  
  static void
  obj_elf_tls_common (ignore)
       int ignore ATTRIBUTE_UNUSED;
  {
!   symbolS *symbolP = s_comm_internal (0, elf_common_parse);
  
    if (symbolP)
      symbol_get_bfdsym (symbolP)->flags |= BSF_THREAD_LOCAL;
Index: gas/config/tc-alpha.h
===================================================================
RCS file: /cvs/src/src/gas/config/tc-alpha.h,v
retrieving revision 1.20
diff -c -p -r1.20 tc-alpha.h
*** gas/config/tc-alpha.h	21 Nov 2003 00:24:40 -0000	1.20
--- gas/config/tc-alpha.h	13 Dec 2003 02:53:18 -0000
*************** extern valueT alpha_gp_value;
*** 80,85 ****
--- 80,100 ----
  	: BFD_RELOC_ALPHA_LINKAGE);
  #endif
  
+ #ifndef VMS
+ #define TC_IMPLICIT_LCOMM_ALIGNMENT(size, align) \
+   do							\
+     {							\
+       align = 0;					\
+       if (size > 1)					\
+ 	{						\
+ 	  addressT temp = 1;				\
+ 	  while ((size & temp) == 0)			\
+ 	    ++align, temp <<= 1;			\
+ 	}						\
+     }							\
+   while (0)
+ #endif
+ 
  #define md_number_to_chars		number_to_chars_littleendian
  
  extern int tc_get_register PARAMS ((int frame));

-- 
Alan Modra
IBM OzLabs - Linux Technology Centre


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