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]

PATCH: Allow a global symbol set to common/undefined symbol


On Mon, Apr 25, 2005 at 11:43:34AM -0700, H. J. Lu wrote:
> On Mon, Apr 25, 2005 at 06:20:50PM +0200, Etienne Lorrain wrote:
> > --- Dave Korn <dave.korn@artimi.com> wrote:
> > > > >   asm volatile (" dataPS2 = %c0 ": : "i" (&MOUSE.data.PS2));
> > > 
> > >   IIUIC, all you want to do here is initialise an assembler-level variable
> > > with the address of MOUSE.data.PS2 at runtime, yes?  So why not make your
> > > life a load easier, and do it the other way round:
> > > void *dataPS2 = NULL;
> > 
> >   I do not think my method is that complex, not going through a variable
> >  pointer but just defining a symbol to write to. With your pointer I would
> >  have to read the content of the pointer and write to this address - and
> >  so save another register on the stack to store the address to write to
> >  in my interrupt treatment.
> >  This address is known at link time so there is no need to put it in
> >  a variable pointer.
> > 
> >   I can accept the argument of H.J. saying that the behaviour I am waiting
> >  is not guarantied - but I am sure it was working perfectly in my case,
> >  with binutils-2.15.
> >  The address is the same, the PS2 mouse is perfectly working in Gujin,
> >  and this field is only written under interrupt and only read in C.
> > 
> >   That is not a real problem for my application, I will initialise to
> >  get the MOUSE structure in BSS instead of COMMON.
> > 
> 
> "dataPS2 = MOUSE" !=  "dataPS2 = MOUSE + 4" when MOUSE is a common
> symbol. "dataPS2 = MOUSE" will create a copy of MOUSE and will create
> a symbol with value of "MOUSE + 4". Is that intentional? If yes, this
> patch will allow "dataPS2 = MOUSE + 4". Can we change "dataPS2 = MOUSE"
> to mean the value of MOUSE, not its copy?
> 

It is the difference between

        .comm   MOUSE,12,4
	dataPS2 = MOUSE + 4

and

	dataPS2 = MOUSE + 4
        .comm   MOUSE,12,4

The former will create a copy of common symbol and latter won't. But

	dataPS2 = MOUSE + 4
        .comm   MOUSE,12,4

will turn the local symbol dataPS2 into a gloal one. It has the same
problem as

http://sources.redhat.com/bugzilla/show_bug.cgi?id=857

This patch will fix PR 857 and allow

	.global dataPS2
	dataPS2 = MOUSE + 4
        .comm   MOUSE,12,4



H.J.
----
gas/

2005-04-25  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.

	PR 857
	* write.c (write_object_file): Report common symbol name when
	disallowing local symbol set to common symbol.
	(adjust_reloc_syms): Disallow local symbol set to undefined
	symbol.

gas/testsuite/

2005-04-25  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-25 12:18:11.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-25 09:24:04.000000000 -0700
+++ gas/read.c	2005-04-25 12:18:11.000000000 -0700
@@ -3301,6 +3301,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-25 12:18:11.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-04-20 11:12:17.000000000 -0700
+++ gas/write.c	2005-04-25 12:26:11.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;
 	  }
 
@@ -1927,9 +1935,15 @@ write_object_file (void)
              symbols.  */
 	  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));
+	      const char *name = S_GET_NAME (symp);
+	      if (S_IS_COMMON (symp)
+		  && strcmp (name, FAKE_LABEL_NAME)
+		  && (!S_IS_EXTERNAL (symp) || S_IS_LOCAL (symp)))
+		{
+		  expressionS *e = symbol_get_value_expression (symp);
+		  as_bad (_("Local symbol `%s' can't be equated to common symbol `%s'"),
+			  name, S_GET_NAME (e->X_add_symbol));
+		}
 	      symbol_remove (symp, &symbol_rootP, &symbol_lastP);
 	      continue;
 	    }


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