[Top][All Lists]
[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}