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]

COFF debug symbol bug


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



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