From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 19547 invoked by alias); 2 Jun 2006 16:26:14 -0000 Received: (qmail 19533 invoked by uid 22791); 2 Jun 2006 16:26:12 -0000 X-Spam-Check-By: sourceware.org Received: from omta01sl.mx.bigpond.com (HELO omta01sl.mx.bigpond.com) (144.140.92.153) by sourceware.org (qpsmtpd/0.31) with ESMTP; Fri, 02 Jun 2006 16:25:48 +0000 Received: from grove.modra.org ([144.136.172.108]) by omta01sl.mx.bigpond.com with ESMTP id <20060602162544.VGCT19512.omta01sl.mx.bigpond.com@grove.modra.org>; Fri, 2 Jun 2006 16:25:44 +0000 Received: by bubble.grove.modra.org (Postfix, from userid 500) id 5C3E61E3F81; Sat, 3 Jun 2006 01:55:44 +0930 (CST) Date: Fri, 02 Jun 2006 16:43:00 -0000 From: Alan Modra To: Jakub Jelinek Cc: binutils@sources.redhat.com Subject: Re: [PATCH] Fix DT_NEEDED search with --as-needed libraries (PR ld/2721) Message-ID: <20060602162544.GG26009@bubble.grove.modra.org> Mail-Followup-To: Jakub Jelinek , binutils@sources.redhat.com References: <20060601150907.GD3823@sunsite.mff.cuni.cz> <20060602051344.GC26009@bubble.grove.modra.org> <20060602084938.GE3823@sunsite.mff.cuni.cz> <20060602140800.GE26009@bubble.grove.modra.org> <20060602145054.GG3823@sunsite.mff.cuni.cz> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20060602145054.GG3823@sunsite.mff.cuni.cz> User-Agent: Mutt/1.4i X-IsSubscribed: yes Mailing-List: contact binutils-help@sourceware.org; run by ezmlm Precedence: bulk List-Subscribe: List-Archive: List-Post: List-Help: , Sender: binutils-owner@sourceware.org X-SW-Source: 2006-06/txt/msg00027.txt.bz2 On Fri, Jun 02, 2006 at 04:50:54PM +0200, Jakub Jelinek wrote: > Does (bfd_elf_get_dyn_lib_class (s->the_bfd) & DYN_AS_NEEDED) != 0 imply > s->as_needed? Yes. > Can we rely on at most one DYN_AS_NEEDED library matching? Otherwise > it changes from first as needed library wins to last as needed library wins. Sigh. I suppose we might have two matching as-needed libs. That needs fixing. > Also, if there is some ->the_bfd == NULL library, we'll keep searching, no > matter if it is global_found->as_needed or not. Hmm, to get global_found->the_bfd NULL, you'd need to specify a linker script on the command line that looked like a soname. ie. You've found a bug in check_needed. It ought to only look at entries with both s->filename and s->the_bfd, I think. > Can we rely on global_found->filename != NULL? Yes. This is getting way too late for me to post patches, but here goes. * emultempl/elf32.em (global_found): Make it a pointer. (stat_needed, try_needed): Adjust. (check_needed): Don't skip non-loaded as-needed entries. Only consider entries with both filename and the_bfd non-null. (after_open): Try loading non-loaded as-needed libs to satisfy DT_NEEDED libs. Index: ld/emultempl/elf32.em =================================================================== RCS file: /cvs/src/src/ld/emultempl/elf32.em,v retrieving revision 1.165 diff -u -p -r1.165 elf32.em --- ld/emultempl/elf32.em 30 May 2006 16:45:32 -0000 1.165 +++ ld/emultempl/elf32.em 2 Jun 2006 16:20:18 -0000 @@ -148,7 +148,7 @@ cat >>e${EMULATION_NAME}.c <the_bfd == NULL) return; - if (s->as_needed - && (bfd_elf_get_dyn_lib_class (s->the_bfd) & DYN_AS_NEEDED) != 0) + + /* If this input file was an as-needed entry, and wasn't found to be + needed at the stage it was linked, then don't say we have loaded it. */ + if ((bfd_elf_get_dyn_lib_class (s->the_bfd) & DYN_AS_NEEDED) != 0) return; if (bfd_stat (s->the_bfd, &st) != 0) @@ -254,7 +256,7 @@ gld${EMULATION_NAME}_stat_needed (lang_i && st.st_ino == global_stat.st_ino && st.st_ino != 0) { - global_found = TRUE; + global_found = s; return; } @@ -398,9 +400,9 @@ cat >>e${EMULATION_NAME}.c <>e${EMULATION_NAME}.c <the_bfd) + & DYN_AS_NEEDED) == 0) return; - /* If this input file was an as-needed entry, and wasn't found to be - needed at the stage it was linked, then don't say we have loaded it. */ - if (s->as_needed - && (s->the_bfd == NULL - || (bfd_elf_get_dyn_lib_class (s->the_bfd) & DYN_AS_NEEDED) != 0)) + if (s->filename == NULL || s->the_bfd == NULL) + return; + + /* Don't look for a second non-loaded as-needed lib. */ + if (global_found != NULL + && (bfd_elf_get_dyn_lib_class (s->the_bfd) & DYN_AS_NEEDED) != 0) return; - if (s->filename != NULL) + if (strcmp (s->filename, global_needed->name) == 0) { - const char *f; + global_found = s; + return; + } - if (strcmp (s->filename, global_needed->name) == 0) + if (s->search_dirs_flag) + { + const char *f = strrchr (s->filename, '/'); + if (f != NULL + && strcmp (f + 1, global_needed->name) == 0) { - global_found = TRUE; + global_found = s; return; } - - if (s->search_dirs_flag) - { - f = strrchr (s->filename, '/'); - if (f != NULL - && strcmp (f + 1, global_needed->name) == 0) - { - global_found = TRUE; - return; - } - } } - if (s->the_bfd != NULL) + soname = bfd_elf_get_dt_soname (s->the_bfd); + if (soname != NULL + && strcmp (soname, global_needed->name) == 0) { - const char *soname; - - soname = bfd_elf_get_dt_soname (s->the_bfd); - if (soname != NULL - && strcmp (soname, global_needed->name) == 0) - { - global_found = TRUE; - return; - } + global_found = s; + return; } } @@ -904,9 +902,11 @@ gld${EMULATION_NAME}_after_open (void) /* See if this file was included in the link explicitly. */ global_needed = l; - global_found = FALSE; + global_found = NULL; lang_for_each_input_file (gld${EMULATION_NAME}_check_needed); - if (global_found) + if (global_found != NULL + && (bfd_elf_get_dyn_lib_class (global_found->the_bfd) + & DYN_AS_NEEDED) == 0) continue; n.by = l->by; @@ -915,6 +915,13 @@ gld${EMULATION_NAME}_after_open (void) if (trace_file_tries) info_msg (_("%s needed by %B\n"), l->name, l->by); + if (global_found != NULL) + { + nn.name = global_found->filename; + if (gld${EMULATION_NAME}_try_needed (&nn, TRUE)) + continue; + } + /* We need to find this file and include the symbol table. We want to search for the file in the same way that the dynamic linker will search. That means that we want to use -- Alan Modra IBM OzLabs - Linux Technology Centre