This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


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

Re: the dynamic linker bug


> 
> Hi,
> 
> I describe here what I found out.  I cannot produce a small test case
> but I can compare two assembler outputs and explain the context with
> the sources.  All this is on ix86.  At then end of the mail is the
> preprocessed source.  You have to run
> 
> 	gcc /tmp/dl-reloc.i -Wall -c -O3 -g -momit-leaf-frame-pointer -mpentium  -fPIC -fno-common -o dl-reloc.o
> 
> 
> I tried to remove the -Wall but this changes the result!!!!!
> 
> 
> The critical part of the code is compiled using the current CVS egcs
> version (ok, the CVS version as of yesterday):
> 
> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>  2d7:   89 45 b0        movl   %eax,0xffffffb0(%ebp)
>  2da:   83 bd 50 ff ff  cmpl   $0x0,0xffffff50(%ebp)
>  2df:   ff 00 
>  2e1:   74 35           je     318 <_dl_relocate_object+0x318>
>  2e3:   8b 8d 50 ff ff  movl   0xffffff50(%ebp),%ecx
>  2e8:   ff 
>  2e9:   83 79 04 00     cmpl   $0x0,0x4(%ecx)
>  2ed:   74 29           je     318 <_dl_relocate_object+0x318>
>  2ef:   52              pushl  %edx
>  2f0:   51              pushl  %ecx
>  2f1:   8b 7d c8        movl   0xffffffc8(%ebp),%edi
>  2f4:   8b 57 fc        movl   0xfffffffc(%edi),%edx
>  2f7:   8b 02           movl   (%edx),%eax
>  2f9:   8b 40 04        movl   0x4(%eax),%eax
>  2fc:   50              pushl  %eax
>  2fd:   8b 42 04        movl   0x4(%edx),%eax
>  300:   50              pushl  %eax
>  301:   8d 45 e8        leal   0xffffffe8(%ebp),%eax
>  304:   50              pushl  %eax
>  305:   8b 45 e8        movl   0xffffffe8(%ebp),%eax
>  308:   8b 00           movl   (%eax),%eax
>  30a:   03 47 f8        addl   0xfffffff8(%edi),%eax
>  30d:   50              pushl  %eax
>  30e:   e8 fc ff ff ff  call   30f <_dl_relocate_object+0x30f>
> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> 
> Using an older version 2.90.15 I get:
> 
> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>  2d7:   89 45 b0        movl   %eax,0xffffffb0(%ebp)
>  2da:   83 bd 50 ff ff  cmpl   $0x0,0xffffff50(%ebp)
>  2df:   ff 00 
>  2e1:   74 35           je     318 <_dl_relocate_object+0x318>
>  2e3:   8b 8d 50 ff ff  movl   0xffffff50(%ebp),%ecx
>  2e8:   ff 
>  2e9:   83 79 04 00     cmpl   $0x0,0x4(%ecx)
>  2ed:   74 29           je     318 <_dl_relocate_object+0x318>
>  2ef:   52              pushl  %edx
>  2f0:   51              pushl  %ecx
>  2f1:   8b 7d c8        movl   0xffffffc8(%ebp),%edi
>  2f4:   8b 57 fc        movl   0xfffffffc(%edi),%edx
>  2f7:   8b 02           movl   (%edx),%eax
>  2f9:   8b 40 04        movl   0x4(%eax),%eax
>  2fc:   50              pushl  %eax
>  2fd:   8b 42 04        movl   0x4(%edx),%eax
>  300:   50              pushl  %eax
>  301:   8d 45 e8        leal   0xffffffe8(%ebp),%eax
>  304:   50              pushl  %eax
>  305:   8b 4d b0        movl   0xffffffb0(%ebp),%ecx
>  308:   8b 01           movl   (%ecx),%eax
>  30a:   03 47 f8        addl   0xfffffff8(%edi),%eax
>  30d:   50              pushl  %eax
>  30e:   e8 fc ff ff ff  call   30f <_dl_relocate_object+0x30f>
> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> 
> The critical instruction is at address 305.  You see the difference
> 
> wrong:		 305:   8b 45 e8        movl   0xffffffe8(%ebp),%eax
> 
> correct:	 305:   8b 4d b0        movl   0xffffffb0(%ebp),%ecx
> 
> 
> The other key location is 2d7 where is both pieces of code 0xffffffb0(%ebp)
> is initialized.
> 
> 
> Looking at the source code you'll see this implements the following
> (function elf_machine_rel, a bit reformatted):
> 
> 
>       const Elf32_Sym *const refsym = sym;
>       Elf32_Addr value = ((  version ) != ((void *)0)
> 			  && (  version )->hash != 0
>     ? _dl_lookup_versioned_symbol (strtab + (* &sym )->st_name,
> 			           ( &sym ), scope, l->l_name,
>                                    (  version ), (  (( reloc->r_info ) & 0xff)  ))
>     : _dl_lookup_symbol (strtab + (* &sym )->st_name, ( &sym ), scope,
>                          l->l_name, (  (( reloc->r_info ) & 0xff)  ))) ;
> 
> 
> The call is too `_dl_lookup_versioned_symbol' ad the parameter we are
> dealing with is the first which is computed as
> 
> 	strtab + (* &sym )->st_name
> 
> Please note that the second parameter is `&sym'.
> 
> Back to the assembler code: Obviously at address 30a the value of
> `strtab' is added.  The `st_name' element of `Elf32_Sym' is the first,
> i.e., the
> 
> 	movl   (%ecx),%eax
> 
> if the dereference of the pointer.  But this means the %ecx (or %eax
> in the wrong code, both solutions are equivalent here) has to be the
> pointer `sym'.  This value is loaded at address 305.
> 
> In the correct case it is loaded from 0xffffffb0(%ebp) which was
> initialized at address 2d7.
> 
> 
> But in the wrong case %eax is loaded from 0xffffffe8(%ebp).  Please
> note that this is the address which was pushed for the second
> parameter before.  The error is that at address 2d7 the value at
> address 0xffffffb0(%ebp) is initialized, as for the correct version.
> But this does not mean anything but that at address 305 uninitialized
> memory is read.
> 
> 
> So the problem is: why is at address 305 0xffffffe8(%ebp) read and not
> 0xffffffb0(%ebp)?
> 

That is one of 2 bugs. 16(%ebp), which is the third argument of
_dl_relocate_object (), is mixed up with -24(%ebp).


H.J.


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