This is the mail archive of the
binutils@sources.redhat.com
mailing list for the binutils project.
COFF debug symbol bug
- To: binutils at sources dot redhat dot com
- Subject: COFF debug symbol bug
- From: "Mark E." <snowball3 at bigfoot dot com>
- Date: Sat, 16 Jun 2001 16:37:58 -0400
Greetings to those familiar with COFF internals,
This error occurs with *-*-msdosdjgpp and Binutils 2.11. Someone on the
djgpp mailing list encountered a problem linking a program with COFF debug
info that linked fine without the debug info. Here's a simple example:
x.c:
void var(void)
{
return;
}
int main()
{
static int var;
return 0;
}
.file "x.c"
gcc2_compiled.:
___gnu_compiled_c:
.text
.p2align 2
.def _var; .val _var; .scl 2; .type 041; .endef
.globl _var
_var:
.def .bf; .val .; .scl 101; .line 2; .endef
pushl %ebp
movl %esp,%ebp
.ln 2
jmp L2
.ln 3
.p2align 4,,7
L2:
movl %ebp,%esp
popl %ebp
ret
.def .ef; .val .; .scl 101; .line 3; .endef
.def _var; .val .; .scl -1; .endef
.lcomm _var.6,4
.p2align 2
.def _main; .val _main; .scl 2; .type 044; .endef
.globl _main
_main:
.def .bf; .val .; .scl 101; .line 7; .endef
pushl %ebp
movl %esp,%ebp
.ln 2
.def _var; .val _var.6; .scl 3; .type 04; .endef
.ln 4
xorl %eax,%eax
jmp L3
.ln 5
.p2align 4,,7
L3:
movl %ebp,%esp
popl %ebp
ret
.def .ef; .val .; .scl 101; .line 5; .endef
.def _main; .val .; .scl -1; .endef
When compiled into an object file, nm shows the problem:
0000000c t .bf
00000000 t .bf
00000020 b .bss
00000020 d .data
00000017 t .ef
00000009 t .ef
00000000 t .text
00000000 t ___gnu_compiled_c
0000000c T _main
00000000 t _var
00000020 b _var.6
00000000 t gcc2_compiled.
_var is global symbol, but it has been turned into a static symbol. Tracing
through the code, it turns out that the symbols:
.def _var; .val _var; .scl 2; .type 041; .endef
and
.def _var; .val _var.6; .scl 3; .type 04; .endef
are merged before the object file is written out.
The symbols are merged in obj_frob_symbol in obj_coff, about line 1175:
if (!SF_GET_DEBUG (symp))
{
symbolS *real;
if (!SF_GET_LOCAL (symp)
&& !SF_GET_STATICS (symp)
&& S_GET_STORAGE_CLASS (symp) != C_LABEL
&& symbol_constant_p(symp)
&& (real = symbol_find_base (S_GET_NAME (symp), DO_NOT_STRIP))
&& real != symp)
{
c_symbol_merge (symp, real);
*punt = 1;
return;
}
It turns out that 'symbol_constant_p' always returns true because the value
of the symbol in the .val expression is evaluated before coff_frob_symbol is
called which means the expression has been turned into a constant.
Thus it would seem that symbol_constant_p will no longer work since in my
testing so far it always returns true. I'm exploring an additional test to
skip the merge if the storage class isn't C_NULL, but I don't know if that's
the best solution.
Suggestions on solving the problem?
Mark