bug-gnu-utils
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: as: .ifdef treats undefined symbols as defined


From: Nick Clifton
Subject: Re: as: .ifdef treats undefined symbols as defined
Date: 19 Jul 2002 12:36:56 +0100
User-agent: Gnus/5.0808 (Gnus v5.8.8) Emacs/21.1

Hi Miroslav,

> in the info file you describe:
> `.equiv SYMBOL, EXPRESSION'
> ===========================
>    The `.equiv' directive is like `.equ' and `.set', except that the
> assembler will signal an error if SYMBOL is already defined.
> 
>    Except for the contents of the error message, this is roughly
> equivalent to
>      .ifdef SYM
>      .err
>      .endif
>      .equ SYM,VAL
> 
> while in fact:
> 
> $ as << END
> jmp A
> .equiv A, .
> END
> 
> assembles ok, while
> 
> $ as << END
> jmp A
> .ifdef A
> .err
> .endif
> .equ A, .
> END
> 
> fails with:
> {standard input}: Assembler messages:
> {standard input}:3: Error: .err encountered
> 
> there is therefore a bug (a) in the info file, or (b) in the
> assembler

I believe that is: '(b) the asembler'.

> let's assume `foo SYMBOL' is a valid instruction:
> 
> then after assembling the following input:
>       .text
> A:
>       foo B
> B:
>       foo C
>       .end
> the symbols will be thus:
> A     undefined defined OR defined defined
> B     defined defined
> C     defined undefined
> D     undefined undefined
> where the first (un)defined means actually (un)mentioned

I prefer to think of this as:

        A defined
        B defined
        C referenced-but-not-defined
        D non-existent

But essentially you are correct.

> this patch makes .ifdef use the same test as .equiv (mostly)

>        initialize_cframe (&cframe);
> -      cframe.ignoring = cframe.dead_tree || !((symbolP != 0) ^ arg);
> +      /* modified to reflect the ``undefinedness'' test in `read.c'
> +     during handling of ``.equiv'' directive */
> +      cframe.ignoring = cframe.dead_tree
> +       || !( ((symbolP != 0) && S_IS_DEFINED (symbolP)
> +           && (S_GET_SEGMENT (symbolP) != reg_section)) ^ arg);
>        current_cframe = ((struct conditional_frame *)
>                       obstack_copy (&cond_obstack, &cframe,
>                                     sizeof (cframe)));

I agree that this patch fixes the problem.  I have applied it to the
sources and run some tests which do not show any regressions, so I
will be committing the change.

I will also add a patch to the documentation to clarify the behaviour
of .equiv and .ifdef.  I have not applied the patch to the new 2.13
branch yet, in case it turns out that there are problems with the
change.

Cheers
        Nick

2002-07-19  Miroslav Tichy <address@hidden>
            Nick Clifton  <address@hidden>

        * cond.c (s_ifdef): Treat a referenced but not yet defined
        symbol as if it were undefined, in exactly the same way as
        .equiv.

        * doc/as.texinfo: Document that .ifdef, .ifndef and .equiv
        consider referenced bug not yet defined symbols to be
        undefined.

Index: gas/cond.c
===================================================================
RCS file: /cvs/src/src/gas/cond.c,v
retrieving revision 1.11
diff -c -3 -p -w -r1.11 cond.c
*** gas/cond.c  1 Aug 2001 01:44:25 -0000       1.11
--- gas/cond.c  19 Jul 2002 11:28:35 -0000
*************** static char *get_mri_string PARAMS ((int
*** 60,74 ****
  
  static struct conditional_frame *current_cframe = NULL;
  
  void
! s_ifdef (arg)
!      int arg;
  {
    /* Points to name of symbol.  */
!   register char *name;
    /* Points to symbol.  */
!   register symbolS *symbolP;
    struct conditional_frame cframe;
  
    /* Leading whitespace is part of operand.  */
    SKIP_WHITESPACE ();
--- 60,78 ----
  
  static struct conditional_frame *current_cframe = NULL;
  
+ /* Performs the .ifdef (test_defined == 1) and
+    the .ifndef (test_defined == 0) pseudo op.  */
+ 
  void
! s_ifdef (test_defined)
!      int test_defined;
  {
    /* Points to name of symbol.  */
!   char *name;
    /* Points to symbol.  */
!   symbolS *symbolP;
    struct conditional_frame cframe;
+   char c;
  
    /* Leading whitespace is part of operand.  */
    SKIP_WHITESPACE ();
*************** s_ifdef (arg)
*** 79,95 ****
        as_bad (_("invalid identifier for \".ifdef\""));
        obstack_1grow (&cond_obstack, 0);
        ignore_rest_of_line ();
      }
-   else
-     {
-       char c;
  
        c = get_symbol_end ();
        symbolP = symbol_find (name);
        *input_line_pointer = c;
  
        initialize_cframe (&cframe);
!       cframe.ignoring = cframe.dead_tree || !((symbolP != 0) ^ arg);
        current_cframe = ((struct conditional_frame *)
                        obstack_copy (&cond_obstack, &cframe,
                                      sizeof (cframe)));
--- 83,114 ----
        as_bad (_("invalid identifier for \".ifdef\""));
        obstack_1grow (&cond_obstack, 0);
        ignore_rest_of_line ();
+       return;
      }
  
    c = get_symbol_end ();
    symbolP = symbol_find (name);
    *input_line_pointer = c;
  
    initialize_cframe (&cframe);
!   
!   if (cframe.dead_tree)
!     cframe.ignoring = 1;
!   else
!     {
!       int is_defined;
! 
!       /* Use the same definition of 'defined' as .equiv so that a symbol
!        which has been referenced but not yet given a value/address is
!        considered to be undefined.  */
!       is_defined =
!       symbolP != NULL
!       && S_IS_DEFINED (symbolP)
!       && S_GET_SEGMENT (symbolP) != reg_section;
! 
!       cframe.ignoring = ! (test_defined ^ is_defined);
!     }
! 
    current_cframe = ((struct conditional_frame *)
                    obstack_copy (&cond_obstack, &cframe,
                                  sizeof (cframe)));
*************** s_ifdef (arg)
*** 101,107 ****
        listing_list (2);
  
        demand_empty_rest_of_line ();
-     }                         /* if a valid identifyer name */
  }
  
  void
--- 120,125 ----

Index: gas/doc/as.texinfo
===================================================================
RCS file: /cvs/src/src/gas/doc/as.texinfo,v
retrieving revision 1.67
diff -c -3 -p -w -r1.67 as.texinfo
*** gas/doc/as.texinfo  19 Jul 2002 07:52:39 -0000      1.67
--- gas/doc/as.texinfo  19 Jul 2002 11:28:39 -0000
*************** The syntax for @code{equ} on the HPPA is
*** 4074,4080 ****
  @section @code{.equiv @var{symbol}, @var{expression}}
  @cindex @code{equiv} directive
  The @code{.equiv} directive is like @code{.equ} and @code{.set}, except that
! the assembler will signal an error if @var{symbol} is already defined.
  
  Except for the contents of the error message, this is roughly equivalent to 
  @smallexample
--- 4074,4082 ----
  @section @code{.equiv @var{symbol}, @var{expression}}
  @cindex @code{equiv} directive
  The @code{.equiv} directive is like @code{.equ} and @code{.set}, except that
! the assembler will signal an error if @var{symbol} is already defined.  Note a
! symbol which has been referenced but not actually defined is considered to be
! undefined.
  
  Except for the contents of the error message, this is roughly equivalent to 
  @smallexample
*************** The following variants of @code{.if} are
*** 4273,4279 ****
  @cindex @code{ifdef} directive
  @item .ifdef @var{symbol}
  Assembles the following section of code if the specified @var{symbol}
! has been defined.
  
  @cindex @code{ifc} directive
  @item .ifc @var{string1},@var{string2}
--- 4275,4282 ----
  @cindex @code{ifdef} directive
  @item .ifdef @var{symbol}
  Assembles the following section of code if the specified @var{symbol}
! has been defined.  Note a symbol which has been referenced but not yet defined
! is considered to be undefined.
  
  @cindex @code{ifc} directive
  @item .ifc @var{string1},@var{string2}
*************** following section of code if the two str
*** 4319,4325 ****
  @item .ifndef @var{symbol}
  @itemx .ifnotdef @var{symbol}
  Assembles the following section of code if the specified @var{symbol}
! has not been defined.  Both spelling variants are equivalent.
  
  @cindex @code{ifne} directive
  @item .ifne @var{absolute expression}
--- 4322,4329 ----
  @item .ifndef @var{symbol}
  @itemx .ifnotdef @var{symbol}
  Assembles the following section of code if the specified @var{symbol}
! has not been defined.  Both spelling variants are equivalent.  Note a symbol
! which has been referenced but not yet defined is considered to be undefined.
  
  @cindex @code{ifne} directive
  @item .ifne @var{absolute expression}




reply via email to

[Prev in Thread] Current Thread [Next in Thread]