From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 1156 invoked by alias); 6 Apr 2005 08:12:03 -0000 Mailing-List: contact binutils-help@sources.redhat.com; run by ezmlm Precedence: bulk List-Subscribe: List-Archive: List-Post: List-Help: , Sender: binutils-owner@sources.redhat.com Received: (qmail 895 invoked from network); 6 Apr 2005 08:11:49 -0000 Received: from unknown (HELO gizmo10ps.bigpond.com) (144.140.71.20) by sourceware.org with SMTP; 6 Apr 2005 08:11:49 -0000 Received: (qmail 20640 invoked from network); 6 Apr 2005 08:11:46 -0000 Received: from unknown (HELO psmam12.bigpond.com) (144.135.25.103) by gizmo10ps.bigpond.com with SMTP; 6 Apr 2005 08:11:46 -0000 Received: from cpe-144-136-221-26.sa.bigpond.net.au ([144.136.221.26]) by psmam12.bigpond.com(MAM REL_3_4_2a 234/5197561) with SMTP id 5197561; Wed, 06 Apr 2005 18:11:46 +1000 Received: by bubble.modra.org (Postfix, from userid 500) id 3E98E18F6D1; Wed, 6 Apr 2005 17:41:46 +0930 Date: Wed, 06 Apr 2005 08:12:00 -0000 From: Alan Modra To: binutils@sources.redhat.com Cc: Ian Lance Taylor Subject: Fix PR gas/827 Message-ID: <20050406081146.GF29412@bubble.modra.org> Mail-Followup-To: binutils@sources.redhat.com, Ian Lance Taylor Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline User-Agent: Mutt/1.4i X-SW-Source: 2005-04/txt/msg00157.txt.bz2 http://sources.redhat.com/bugzilla/show_bug.cgi?id=827 shows a couple of interesting failures with assignment of simple expressions to syms. Lack of a reloc with .set y, 1 .set y, y+_undef .long y is due to y initially being set to an absolute symbol, then not having the section changed with the second assignment. Other parts of gas treat absolute symbols specially. Fixed by resetting the symbol section and frag back to that for a newly created symbol. I cured the symbol definition loop in .set x, _undef .set x, x+1 .long x by allowing x=x+1 to adjust X_add_number even for undefined symbols. I think this should be reasonably safe, but it does allow .set undef, undef+1 which has the curious result of an undefined symbol with a non-zero value. Hmm, I probably ought to disallow that. While poking at pseudo_set, I noticed that assignment to section symbols is only prevented when assigning some other symbol to the section symbol. This seemed odd to me, so I modified the code to give an error on any assignment to section symbols. Another oddity is special casing sym1 = sym2 + const for const == 0. When const != 0, the old code created an expression symbol, and I can't see the reason for that. Ian, do you know why this was done? PR gas/827 * symbols.c (symbol_X_add_number): New function. * symbols.h (symbol_X_add_number): Declare. * read.c (pseudo_set): Always check for assignment to section syms. Handle assignment of sym=sym+/-const specially. Don't special case exp.X_add_number non-zero. Set segment and frag of expression syms as for newly created syms. Index: gas/symbols.c =================================================================== RCS file: /cvs/src/src/gas/symbols.c,v retrieving revision 1.56 diff -u -p -r1.56 symbols.c --- gas/symbols.c 2 Mar 2005 00:11:30 -0000 1.56 +++ gas/symbols.c 6 Apr 2005 06:00:38 -0000 @@ -2022,6 +2022,19 @@ symbol_set_value_expression (symbolS *s, s->sy_value = *exp; } +/* Return a pointer to the X_add_number component of a symbol. */ + +valueT * +symbol_X_add_number (symbolS *s) +{ +#ifdef BFD_ASSEMBLER + if (LOCAL_SYMBOL_CHECK (s)) + return &((struct local_symbol *) s)->lsy_value; +#endif + + return &s->sy_value.X_add_number; +} + /* Set the value of SYM to the current position in the current segment. */ void Index: gas/symbols.h =================================================================== RCS file: /cvs/src/src/gas/symbols.h,v retrieving revision 1.16 diff -u -p -r1.16 symbols.h --- gas/symbols.h 8 Nov 2004 08:12:44 -0000 1.16 +++ gas/symbols.h 6 Apr 2005 06:00:38 -0000 @@ -1,6 +1,6 @@ /* symbols.h - Copyright 1987, 1990, 1992, 1993, 1994, 1995, 1997, 1999, 2000, 2001, - 2002, 2003, 2004 Free Software Foundation, Inc. + 2002, 2003, 2004, 2005 Free Software Foundation, Inc. This file is part of GAS, the GNU Assembler. @@ -175,6 +175,7 @@ extern symbolS *symbol_next (symbolS *); extern expressionS *symbol_get_value_expression (symbolS *); extern void symbol_set_value_expression (symbolS *, const expressionS *); +extern valueT *symbol_X_add_number (symbolS *); extern void symbol_set_value_now (symbolS *); extern void symbol_set_frag (symbolS *, fragS *); extern fragS *symbol_get_frag (symbolS *); Index: gas/read.c =================================================================== RCS file: /cvs/src/src/gas/read.c,v retrieving revision 1.94 diff -u -p -r1.94 read.c --- gas/read.c 1 Mar 2005 02:00:14 -0000 1.94 +++ gas/read.c 6 Apr 2005 07:59:48 -0000 @@ -3188,6 +3188,7 @@ void pseudo_set (symbolS *symbolP) { expressionS exp; + segT seg; #if (defined (OBJ_AOUT) || defined (OBJ_BOUT)) && ! defined (BFD_ASSEMBLER) int ext; #endif /* OBJ_AOUT or OBJ_BOUT */ @@ -3220,6 +3221,12 @@ pseudo_set (symbolS *symbolP) - S_GET_VALUE (exp.X_op_symbol)); } + if (symbol_section_p (symbolP)) + { + as_bad ("attempt to set value of section symbol"); + return; + } + switch (exp.X_op) { case O_illegal: @@ -3247,33 +3254,34 @@ pseudo_set (symbolS *symbolP) break; case O_symbol: - if (S_GET_SEGMENT (exp.X_add_symbol) == undefined_section - || exp.X_add_number != 0) - symbol_set_value_expression (symbolP, &exp); - else if (symbol_section_p (symbolP)) - as_bad ("attempt to set value of section symbol"); - else + if (symbolP == exp.X_add_symbol) + { + *symbol_X_add_number (symbolP) += exp.X_add_number; + break; + } + else if ((seg = S_GET_SEGMENT (exp.X_add_symbol)) != undefined_section) { symbolS *s = exp.X_add_symbol; - S_SET_SEGMENT (symbolP, S_GET_SEGMENT (s)); + S_SET_SEGMENT (symbolP, seg); #if (defined (OBJ_AOUT) || defined (OBJ_BOUT)) && ! defined (BFD_ASSEMBLER) if (ext) S_SET_EXTERNAL (symbolP); else S_CLEAR_EXTERNAL (symbolP); #endif /* OBJ_AOUT or OBJ_BOUT */ - S_SET_VALUE (symbolP, - exp.X_add_number + S_GET_VALUE (s)); + S_SET_VALUE (symbolP, exp.X_add_number + S_GET_VALUE (s)); symbol_set_frag (symbolP, symbol_get_frag (s)); copy_symbol_attributes (symbolP, s); + break; } - break; + /* Fall thru */ default: - /* The value is some complex expression. - FIXME: Should we set the segment to anything? */ + /* The value is some complex expression. */ symbol_set_value_expression (symbolP, &exp); + S_SET_SEGMENT (symbolP, undefined_section); + symbol_set_frag (symbolP, &zero_address_frag); break; } } -- Alan Modra IBM OzLabs - Linux Technology Centre