This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Re: the dynamic linker bug
- To: drepper at ipd dot info dot uni-karlsruhe dot de
- Subject: Re: the dynamic linker bug
- From: hjl at lucon dot org (H.J. Lu)
- Date: Thu, 11 Dec 1997 23:57:10 -0800 (PST)
- Cc: egcs at cygnus dot com, gcc2 at cygnus dot com
- Reply-To: egcs at cygnus dot com
>
> 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.