This is the mail archive of the
binutils@sources.redhat.com
mailing list for the binutils project.
Re: PATCH: PR 857: Disallow local symbol set to undefined symbol
- From: "H. J. Lu" <hjl at lucon dot org>
- To: binutils at sources dot redhat dot com
- Date: Tue, 19 Apr 2005 16:24:02 -0700
- Subject: Re: PATCH: PR 857: Disallow local symbol set to undefined symbol
- References: <20050419212105.GA20885@lucon.org>
On Tue, Apr 19, 2005 at 02:21:05PM -0700, H. J. Lu wrote:
> We shouldn't allow local symbol set to undefined symbol. Also we
> don't allow
>
> .set bar,foo
> .comm foo,4,4
>
> But allow
>
> .comm foo,4,4
> .set bar,foo
>
> This patch fixes those bugs.
>
>
> H.J.
> ----
> 2005-04-19 H.J. Lu <hongjiu.lu@intel.com>
>
> * read.c (pseudo_set): Disallow symbol set to common symbol.
>
> * write.c (write_object_file): Report common symbol name when
> disallowing symbol set to common symbol. Call S_IS_EXTERNAL
> instead of S_IS_EXTERN.
>
> PR 857
> * write.c (adjust_reloc_syms): Disallow local symbol set to
> undefined symbol.
>
We need to allow fake label set to undefined symbol. Make `x' and `y'
global makes no difference in the output. It just makes people aware
that `x' and `y' won't be local.
H.J.
---
gas/
2005-04-19 H.J. Lu <hongjiu.lu@intel.com>
* config/obj-multi.h (FAKE_LABEL_NAME): Defined.
* read.c (pseudo_set): Disallow symbol set to common symbol.
* write.c (write_object_file): Report common symbol name when
disallowing symbol set to common symbol. Call S_IS_EXTERNAL
instead of S_IS_EXTERN.
PR 857
* write.c (adjust_reloc_syms): Disallow local symbol set to
undefined symbol.
gas/testsuite/
2005-04-19 H.J. Lu <hongjiu.lu@intel.com>
* gas/all/assign.s: Make `x' and `y' global.
--- gas/config/obj-multi.h.set 2005-03-03 09:21:24.000000000 -0800
+++ gas/config/obj-multi.h 2005-04-19 15:38:38.000000000 -0700
@@ -146,6 +146,8 @@
#define EMIT_SECTION_SYMBOLS (this_format->emit_section_symbols)
+#define FAKE_LABEL_NAME (this_emulation->fake_label_name)
+
#ifdef OBJ_MAYBE_ELF
/* We need OBJ_SYMFIELD_TYPE so that symbol_get_obj is defined in symbol.c
We also need various STAB defines for stab.c */
--- gas/read.c.set 2005-04-11 08:54:47.000000000 -0700
+++ gas/read.c 2005-04-19 14:47:23.000000000 -0700
@@ -3299,6 +3299,10 @@ pseudo_set (symbolS *symbolP)
{
symbolS *s = exp.X_add_symbol;
+ if (S_IS_COMMON (s))
+ as_bad (_("`%s' can't be equated to common symbol '%s'"),
+ S_GET_NAME (symbolP), S_GET_NAME (s));
+
S_SET_SEGMENT (symbolP, seg);
S_SET_VALUE (symbolP, exp.X_add_number + S_GET_VALUE (s));
symbol_set_frag (symbolP, symbol_get_frag (s));
--- gas/testsuite/gas/all/assign.s.set 2005-04-15 08:44:24.000000000 -0700
+++ gas/testsuite/gas/all/assign.s 2005-04-19 15:00:33.000000000 -0700
@@ -1,7 +1,9 @@
+ .global x
x = zzz
x = x+1
.long x
+ .global y
y = 1
y = y+zzz
.long y
--- gas/write.c.set 2005-03-03 09:21:19.000000000 -0800
+++ gas/write.c 2005-04-19 15:55:26.000000000 -0700
@@ -787,12 +787,20 @@ adjust_reloc_syms (bfd *abfd ATTRIBUTE_U
if (fixp->fx_subsy != NULL)
resolve_symbol_value (fixp->fx_subsy);
- /* If this symbol is equated to an undefined symbol, convert
- the fixup to being against that symbol. */
+ /* If this symbol is equated to an undefined or common symbol,
+ convert the fixup to being against that symbol. */
if (symbol_equated_reloc_p (sym))
{
+ symbolS *new_sym
+ = symbol_get_value_expression (sym)->X_add_symbol;
+ const char *name = S_GET_NAME (sym);
+ if (!S_IS_COMMON (new_sym)
+ && strcmp (name, FAKE_LABEL_NAME)
+ && (!S_IS_EXTERNAL (sym) || S_IS_LOCAL (sym)))
+ as_bad (_("Local symbol `%s' can't be equated to undefined symbol `%s'"),
+ name, S_GET_NAME (new_sym));
fixp->fx_offset += symbol_get_value_expression (sym)->X_add_number;
- sym = symbol_get_value_expression (sym)->X_add_symbol;
+ sym = new_sym;
fixp->fx_addsy = sym;
}
@@ -1928,8 +1936,12 @@ write_object_file (void)
if (symbol_equated_reloc_p (symp))
{
if (S_IS_COMMON (symp))
- as_bad (_("`%s' can't be equated to common symbol"),
- S_GET_NAME (symp));
+ {
+ symbolS *c
+ = symbol_get_value_expression (symp)->X_add_symbol;
+ as_bad (_("`%s' can't be equated to common symbol `%s'"),
+ S_GET_NAME (symp), S_GET_NAME (c));
+ }
symbol_remove (symp, &symbol_rootP, &symbol_lastP);
continue;
}
@@ -1956,10 +1968,10 @@ write_object_file (void)
if (symp == abs_section_sym
|| (! EMIT_SECTION_SYMBOLS
&& symbol_section_p (symp))
- /* Note that S_IS_EXTERN and S_IS_LOCAL are not always
+ /* Note that S_IS_EXTERNAL and S_IS_LOCAL are not always
opposites. Sometimes the former checks flags and the
latter examines the name... */
- || (!S_IS_EXTERN (symp)
+ || (!S_IS_EXTERNAL (symp)
&& (punt || S_IS_LOCAL (symp))
&& ! symbol_used_in_reloc_p (symp)))
{