Subject: Problems with linker
From: "Graeme Campbell" <[email-masked]>
To: [email-masked]
Date: Fri, 18 Aug 2000 13:56:08 +1200 (NZT)

I am a newbie to using cygwin and GCC, but have found generally the tools  
to be excellent.  

I have recently however found some problems with the linker producing  
corrupt images, and crashing. I am using GCC-2.92.2-1, which worked fine  
with the linker created from binutils-19990818.  We produce an image used  
in an embedded system by linking together a number of modules in a  
incremental link using the -r option, which are then linked to the final image. 
The target hardware is PPC, using ELF and DWARF2 debugging.  The  
problem with the original linker was that it tended to stack dump if it could  
not resolve some symbols in the final link. 

The linker in the next two releases of binutils (binutils-20000625 and binutils- 
20000722-1 ) produced corrupt images, but would tell us which symbols  
were unresolved.   

I investigated the corruption using GDB on the linker, and found two  
separate problems in the routine gldelf32ppc_place_orphan in the file  
eelf32ppc.c, which is automatically generated from the template file 
elf32.em. 

The first problem is that special data sections we use ( created with the  
__attribute__ ((section ("special"))) keywords, were being set to zero size in 
 the incremental link.   

I fixed that by adding an extra test for a relocatable link in the following line 

    if (place->stmt == NULL  || link_info.relocateable) 
	{ 
	  /* Put the new statement list right at the head.  */ 
	  *add.tail = place->os->header.next; 
	  place->os->header.next = add.head; 
	} 
      else 
	{ 
	  /* Put it after the last orphan statement we added.  */ 
	  *add.tail = *place->stmt; 
	  *place->stmt = add.head; 
	} 

Then I found that the .sbss section variables were also being set to zero  
size.  This I fixed by adding an extra test for a relocateable link and putting 
both .sbss and .bss into the .data section.  Note .bss was already being put  
into the .data section 

  if (s->flags & SEC_EXCLUDE) 
    return false; 
  else if ((s->flags & SEC_ALLOC) == 0) 
    place = NULL; 
  else if ((s->flags & SEC_LOAD) != 0 
	   && strncmp (secname, ".note", 4) == 0 
	   && HAVE_SECTION (hold_interp, ".interp")) 
    place = &hold_interp; 
  else if ((s->flags & SEC_HAS_CONTENTS) == 0 
	   && link_info.relocateable	    
	   && HAVE_SECTION (hold_data, ".data")) 
    	place = &hold_data; 
  else if ((s->flags & SEC_HAS_CONTENTS) == 0 
	   && HAVE_SECTION (hold_bss, ".bss")) 
   	place = &hold_bss; 

My changes work in our environment, but may well work for completely the  
wrong reasons, or not be the correct way to fix the problem. 

One further problem I also investigated was a stack dump due to a divide by  
zero error. This was found to be due to the linker trying to determine the line 
 number of an unresolved symbol in the link and dividing by zero.  This  
occurs in the file bfd/dwarf2.c routine decode_line_info, where it divides by  
lh.line_range.  

Graeme Campbell 

--
Want to unsubscribe from this list?
Send a message to [email-masked]