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]

Bug with merging COFF debug symbols


Hi guys,

I found a bug in the BFD version of gas in handling COFF debug symbols and 
common symbols, but I'm not quite sure what the right fix is.

The problem can be demonstrated with the following assembly code:
.def    ___attr_desc_type_node; .val    ___attr_desc_type_node; .scl    2;    
  .tag    _tree_node;     .size   100;    .type   031;    .endef
.comm ___attr_desc_type_node,4

This produces the nm output:

00000000 b .bss
00000000 d .data
00000000 t .text
00000004 C ___attr_desc_type_node
         U ___attr_desc_type_node
         U _tree_node

You can see that the debug symbol is never deleted.

coff_frob_symbol, used by BFD gas, uses this code:
  if (!SF_GET_DEBUG (symp))
    {
      symbolS *real;
      if (!SF_GET_LOCAL (symp)
	  && !SF_GET_STATICS (symp)
	  && (real = symbol_find_base (S_GET_NAME (symp), DO_NOT_STRIP))
	  && real != symp)
	{
	  c_symbol_merge (symp, real);
	  *punt = 1;
	}
      if (!S_IS_DEFINED (symp) && !SF_GET_LOCAL (symp))
	{
	  assert (S_GET_VALUE (symp) == 0);
	  /* XXX: The next function call prevents the debug symbol from being 
deleted upon return. */
	  S_SET_EXTERNAL (symp);
	}
      else if (S_GET_STORAGE_CLASS (symp) == C_NULL)
	{
	  if (S_GET_SEGMENT (symp) == text_section
	      && symp != seg_info (text_section)->sym)
	    S_SET_STORAGE_CLASS (symp, C_LABEL);
	  else
	    S_SET_STORAGE_CLASS (symp, C_STAT);
	}

yank_symbols, used by non-BFD gas, has very similiar code:

      if (!SF_GET_DEBUG (symbolP))
	{
	  /* Debug symbols do not need all this rubbish */
	  symbolS *real_symbolP;

	  /* L* and C_EFCN symbols never merge. */
	  if (!SF_GET_LOCAL (symbolP)
	      && !SF_GET_STATICS (symbolP)
	      && S_GET_STORAGE_CLASS (symbolP) != C_LABEL
	      && symbolP->sy_value.X_op == O_constant
	      && (real_symbolP = symbol_find_base (S_GET_NAME (symbolP), 
DO_NOT_STRIP))
	      && real_symbolP != symbolP)
	    {
	      /* FIXME-SOON: where do dups come from?
		 Maybe tag references before definitions? xoxorich. */
	      /* Move the debug data from the debug symbol to the
		 real symbol. Do NOT do the oposite (i.e. move from
		 real symbol to debug symbol and remove real symbol from the
		 list.) Because some pointers refer to the real symbol
		 whereas no pointers refer to the debug symbol. */
	      c_symbol_merge (symbolP, real_symbolP);
	      /* Replace the current symbol by the real one */
	      /* The symbols will never be the last or the first
		 because : 1st symbol is .file and 3 last symbols are
		 .text, .data, .bss */
	      symbol_remove (real_symbolP, &symbol_rootP, &symbol_lastP);
	      symbol_insert (real_symbolP, symbolP, &symbol_rootP, &symbol_lastP);
	      symbol_remove (symbolP, &symbol_rootP, &symbol_lastP);
	      symbolP = real_symbolP;
	    }			/* if not local but dup'd */

	  if (flag_readonly_data_in_text && (S_GET_SEGMENT (symbolP) == SEG_E1))
	    {
	      S_SET_SEGMENT (symbolP, SEG_E0);
	    }			/* push data into text */

	  resolve_symbol_value (symbolP, 1);

	  if (S_GET_STORAGE_CLASS (symbolP) == C_NULL)
	    {
	      if (!S_IS_DEFINED (symbolP) && !SF_GET_LOCAL (symbolP))
		{
		  S_SET_EXTERNAL (symbolP);
		}
	      else if (S_GET_SEGMENT (symbolP) == SEG_E0)
		{
		  S_SET_STORAGE_CLASS (symbolP, C_LABEL);
		}
	      else
		{
		  S_SET_STORAGE_CLASS (symbolP, C_STAT);
		}
	    }

If the code marked with 'XXX' in coff_frob_symbol is only executed if *punt 
is 0, then the debug symbol is deleted as it should be. But the problem could 
also be solved by making that section of code be executed if the 
storage_class is C_NULL like in yank_symbols.

I think the latter solution if the right way to go, if for no other reason 
that the code in yank_symbols has been working for years with COFF debug 
symbols and the code in coff_frob_symbol hasn't.

Mark


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