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]
Other format: [Raw text]

GCC-4.1.0 size optimization bug for MIPS architecture...


Greetings.

I have discovered what appears to be an optimization bug with '-Os'
in GCC-4.1.0 for the MIPS architecture. It appears that functions
which are declared as 'inline' are being ignored and instead turned
into to function calls which is breaking the dynamic linker loader
for uClibc on MIPS. I apologize for not being able to provide a
simpler test case, but I did my best to isolate the issue. I have
placed a tarball at:

http://www.realitydiluted.com/nptl-uclibc/gcc-4.1.0-size-optimization-error.tar.bz2


that contains the source as well as the object files and final loader binary for both the '-O1' and '-Os' cases. Hopefully that will aide in discovering the problem.

First, compiling with '-O1' WORKS. My toolchain is binutils-2.16.1,
latest GCC-4.1.0 from head of CVS and latest snapshot of uClibc.
Compiling the loader with '-Os' results in a dynamic linker that
immediately segfaults.

Two isolated cases appear with the inlined functions on lines 179
and 193 of the 'dl-startup.c' file below.

   167		/* Check the ELF header to make sure everything looks ok.  */
   168		if (!header || header->e_ident[EI_CLASS] != ELFCLASS32 ||
   169				header->e_ident[EI_VERSION] != EV_CURRENT
   170				/* Do not use an inline _dl_strncmp here or some arches
   171				* will blow chunks, i.e. those that need to relocate all
   172				* string constants... */
   173				|| header->e_ident[EI_MAG0] != ELFMAG0
   174				|| header->e_ident[EI_MAG1] != ELFMAG1
   175				|| header->e_ident[EI_MAG2] != ELFMAG2
   176				|| header->e_ident[EI_MAG3] != ELFMAG3)
   177		{
   178			SEND_STDERR("Invalid ELF header\n");
** 179			_dl_exit(0);
   180		}
   181		SEND_STDERR_DEBUG("ELF header=");
   182		SEND_ADDRESS_STDERR_DEBUG(load_addr, 1);
   183	
   184	
   185		/* Locate the global offset table.  Since this code must be PIC
   186		 * we can take advantage of the magic offset register, if we
   187		 * happen to know what that is for this architecture.  If not,
   188		 * we can always read stuff out of the ELF file to find it... */
   189		got = elf_machine_dynamic();
   190		dpnt = (Elf32_Dyn *) (got + load_addr);
   191		SEND_STDERR_DEBUG("First Dynamic section entry=");
   192		SEND_ADDRESS_STDERR_DEBUG(dpnt, 1);
** 193		_dl_memset(tpnt, 0, sizeof(struct elf_resolve));
   194		tpnt->loadaddr = load_addr;

In the '-O1' case, the functions are inlined as expected and the dynamic
linker functions as expected. When compiled with '-Os', the functions
are not inlined. Instead, they become normal function calls. Below is a snippet of the dissassembly with astericks (*) beside the function
calls.


...
			header->e_ident[EI_VERSION] != EV_CURRENT
			/* Do not use an inline _dl_strncmp here or some arches
			* will blow chunks, i.e. those that need to relocate all
			* string constants... */
			|| header->e_ident[EI_MAG0] != ELFMAG0
			|| header->e_ident[EI_MAG1] != ELFMAG1
			|| header->e_ident[EI_MAG2] != ELFMAG2
			|| header->e_ident[EI_MAG3] != ELFMAG3)
	{
		SEND_STDERR("Invalid ELF header\n");
		_dl_exit(0);
    5214:	8f998018 	lw	t9,-32744(gp)
    5218:	27390e20 	addiu	t9,t9,3616
*** 521c:	0320f809 	jalr	t9
    5220:	00002021 	move	a0,zero
    5224:	8fbc0018 	lw	gp,24(sp)
	}
	SEND_STDERR_DEBUG("ELF header=");
	SEND_ADDRESS_STDERR_DEBUG(load_addr, 1);


/* Locate the global offset table. Since this code must be PIC * we can take advantage of the magic offset register, if we * happen to know what that is for this architecture. If not, * we can always read stuff out of the ELF file to find it... */ got = elf_machine_dynamic(); dpnt = (Elf32_Dyn *) (got + load_addr); SEND_STDERR_DEBUG("First Dynamic section entry="); SEND_ADDRESS_STDERR_DEBUG(dpnt, 1); _dl_memset(tpnt, 0, sizeof(struct elf_resolve)); 5228: 8f998018 lw t9,-32744(gp) 522c: 8f828010 lw v0,-32752(gp) 5230: 27b00098 addiu s0,sp,152 5234: 02002021 move a0,s0 5238: 00002821 move a1,zero 523c: 240600e4 li a2,228 5240: 27391194 addiu t9,t9,4500 *** 5244: 0320f809 jalr t9 5248: 00528821 addu s1,v0,s2 524c: 3c037000 lui v1,0x7000 ...

The segfault occurs immediately after 0x5244 due to an invalid value
being stored in t9. This appears to occur because of the gp being
written with a bogus value at 0x5224. Does anyone have some insight
into what is going on that is causing this erroneous behavior? Thanks.

-Steve


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