[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