[uClibc]crashing ldd [was: problems linking libz]

Tom Grennan tgrennan at ayrnetworks.com
Wed May 22 23:55:39 UTC 2002


Tom Grennan wrote on Mon, May 20, 2002 at 04:45:05PM -0700:
>Erik Andersen wrote on Fri, May 10, 2002 at 11:51:33PM -0600:
>>On Fri May 10, 2002 at 08:05:01PM -0700, Todd Sundsted wrote:
>>> I have been fighting with this problem for the last several days.  I am trying
>>> to link a simple program with a version of libz.so that I built with uClibc but
>>> I can't get the linker to pick up my version of libz.so -- it insists on
>>> picking up the version installed in /lib.
>>
>>Hmm.  You might want to take a look at how I compile things
>>with buildroot.  I just added a makefile for building zlib 
>>vs uClibc for you
>>    http://www.uclibc.org/cgi-bin/cvsweb/buildroot/
>>
>> -Erik
>
>I could't get uClibc to build and link with libz.so correctly using the
>above guide.  The following is with uClibc-0.9.11.tar.bz2 and
>zlib-1.1.4.tar.gz compiled/running on RH7.1.
>
>Note that the uClibc version of ldd crashes.  I'll trace this unless
>someone else is already investigating.
>

Here is what I found with the crashing ldd:

Breakpoint 2, elf_find_dynamic (key=15, dynp=0x400187d0, ehdr=0x40017000, return_val=0) at ldd.c:87
87              const Elf32_Addr tx_reloc = pt_text->p_vaddr - pt_text->p_offset;
(gdb) print *pt_text $3 = {p_type = 1, p_offset = 0, p_vaddr = 134512640, p_paddr = 134512640, p_filesz = 5925, p_memsz = 5925, p_flags = 5, p_align = 4096}
(gdb) print /x *pt_text
$4 = {p_type = 0x1, p_offset = 0x0, p_vaddr = 0x8048000, p_paddr = 0x8048000, p_filesz = 0x1725, p_memsz = 0x1725, p_flags = 0x5, p_align = 0x1000}
(gdb) s
89              for (; DT_NULL!=dynp->d_tag; ++dynp) {
(gdb) s
90                  if (dynp->d_tag == key) {
(gdb) print *dynp
$6 = {d_tag = 1, d_un = {d_val = 16, d_ptr = 16}}
(gdb) s
    ...
90                  if (dynp->d_tag == key) {
(gdb) s
91                      if (return_val == 1)
(gdb) s
94                          return (void *)(dynp->d_un.d_val - tx_reloc + (char *)ehdr );
(gdb) print key
$7 = 15
(gdb) print *dynp
$8 = {d_tag = 15, d_un = {d_val = 270, d_ptr = 270}}
(gdb) print /x (dynp->d_un.d_val - tx_reloc + (char*)ehdr)
$9 = 0x37fcf10e
(gdb) print (char*)(dynp->d_un.d_val - tx_reloc + (char*)ehdr)
$10 = 0x37fcf10e <Address 0x37fcf10e out of bounds>

This is called from locate_library_file():

	/* The ABI specifies that RPATH is searched first, so do that now.  */
	path = (char *)elf_find_dynamic(DT_RPATH, dynamic, ehdr, 0);

I don't know what hosed the RPATH dynamic section header but the comment
in elf.h says that this is deprecated anyway.

Qualifying the result like this at least avoids the seg fault:

        if (path > (char*)ehdr) {
vs.
        if (path) {

Quite a hack but seems safer with with mmap files anyway.

BTW, the buffer allocation within this function could be optimised as:


        static char *buf;
...
        /* We need some elbow room here.  Make some room...*/
        if (!buf) {
                buf = malloc(1024);
                if (!buf) {
                        fprintf(stderr, "Out of memory!\n");
                        exit(EXIT_FAILURE);
                }
        }


-- 
TomG

PS I still don't have the zlib shared library working with uclibc.
   Anyone resolve this yet?




More information about the uClibc mailing list