From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 22720 invoked by alias); 15 Oct 2002 20:19:12 -0000 Mailing-List: contact binutils-help@sources.redhat.com; run by ezmlm Precedence: bulk List-Subscribe: List-Archive: List-Post: List-Help: , Sender: binutils-owner@sources.redhat.com Received: (qmail 22586 invoked from network); 15 Oct 2002 20:19:10 -0000 Received: from unknown (HELO web20003.mail.yahoo.com) (216.136.225.48) by sources.redhat.com with SMTP; 15 Oct 2002 20:19:10 -0000 Message-ID: <20021015201909.63573.qmail@web20003.mail.yahoo.com> Received: from [67.82.66.255] by web20003.mail.yahoo.com via HTTP; Tue, 15 Oct 2002 13:19:09 PDT Date: Tue, 15 Oct 2002 13:19:00 -0000 From: Kenny Simpson Subject: [BUG] runpath broken for .so's in ld To: binutils@sources.redhat.com MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii X-SW-Source: 2002-10/txt/msg00367.txt.bz2 The runpath of a shared object is not always being searched when linking an executable. The behavior I'm seeing is the following: I have an external library (libext1.so), which lives in ~/ext1. A shared library (libfoo.so) is created which links against libext.so and records a DT_RUNPATH for ~/ext1. Another shared library (libbar.so) is created with a DT_RUNPATH for some other directory (ext2/libext2.so). I attempt to create a binary (baz) that links against libfoo, and libbar. The link fails as libext1 cannot be found. Just to codify the above: mkdir ext1; mkdir ext2; dummy.c: /* empty */ main.c: int main() { return 0; } Makefile: ext1/libext1.so: dummy.c gcc -shared dummy.c -o $@ ext2/libext2.so: dummy.c gcc -shared dummy.c -o $@ libfoo.so: ext1/libext1.so gcc -shared -Lext1 -Wl,-rpath,ext1 -Wl,--enable-new-dtags -lext1 -o $@ libbar.so: ext2/libext2.so gcc -shared -Lext2 -Wl,-rpath,ext2 -Wl,--enable-new-dtags -lext2 -o $@ baz: main.c libbar.so libfoo.so gcc main.c -L. -Wl,-rpath,. -lfoo -lbar -o $@ make baz Looking at the source I see in elflink.h: /* When we see DT_RPATH before DT_RUNPATH, we have to clear runpath. Do _NOT_ bfd_release, as that frees all more recently bfd_alloc'd blocks as well. */ if (rpath && hash_table->runpath) hash_table->runpath = NULL; but this clears all the runpath info during a link as the hash table from the info is shared. In eelf_i386.c: rp = bfd_elf_get_runpath_list (output_bfd, &link_info); for (; !found && rp != NULL; rp = rp->next) { found = (rp->by == l->by && gldelf_i386_search_needed (rp->name, l->name, force)); With the runpath-clearing line commented out, my example works. With it, it fails with: warning: libext1.so, needed by ./libfoo.so, not found (try using -rpath, or -rpath-link) Peppering printf's in eelf_i386.c shows that it only sees the runpath entries from libbar.so. This is with binutils-2.13.90.0.10 on a Linux 2.4.18/glibc 2.2.5/P4 using gcc 2.95.2. Thanks, -Kenny __________________________________________________ Do you Yahoo!? Faith Hill - Exclusive Performances, Videos & More http://faith.yahoo.com