From mboxrd@z Thu Jan 1 00:00:00 1970 From: hjl@lucon.org (H.J. Lu) To: drepper@ipd.info.uni-karlsruhe.de Cc: egcs@cygnus.com, gcc2@cygnus.com Subject: Re: the dynamic linker bug Date: Fri, 12 Dec 1997 01:52:00 -0000 Message-id: References: X-SW-Source: 1997-12/msg00714.html > > 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.