Consolidate .comm and .lcomm code
Alan Modra
amodra@bigpond.net.au
Sat Dec 13 08:13:00 GMT 2003
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
More information about the Binutils
mailing list