From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 2831 invoked by alias); 14 Dec 2008 17:40:01 -0000 Received: (qmail 2809 invoked by uid 22791); 14 Dec 2008 17:40:00 -0000 X-Spam-Check-By: sourceware.org Received: from mtagate5.de.ibm.com (HELO mtagate5.de.ibm.com) (195.212.29.154) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Sun, 14 Dec 2008 17:39:10 +0000 Received: from d12nrmr1607.megacenter.de.ibm.com (d12nrmr1607.megacenter.de.ibm.com [9.149.167.49]) by mtagate5.de.ibm.com (8.13.8/8.13.8) with ESMTP id mBEHbvxD236004 for ; Sun, 14 Dec 2008 17:37:57 GMT Received: from d12av02.megacenter.de.ibm.com (d12av02.megacenter.de.ibm.com [9.149.165.228]) by d12nrmr1607.megacenter.de.ibm.com (8.13.8/8.13.8/NCO v9.1) with ESMTP id mBEHbvgv3444936 for ; Sun, 14 Dec 2008 18:37:57 +0100 Received: from d12av02.megacenter.de.ibm.com (loopback [127.0.0.1]) by d12av02.megacenter.de.ibm.com (8.12.11.20060308/8.13.3) with ESMTP id mBEHbuMI021478 for ; Sun, 14 Dec 2008 18:37:56 +0100 Received: from tuxmaker.boeblingen.de.ibm.com (tuxmaker.boeblingen.de.ibm.com [9.152.85.9]) by d12av02.megacenter.de.ibm.com (8.12.11.20060308/8.12.11) with SMTP id mBEHbukM021475; Sun, 14 Dec 2008 18:37:56 +0100 Message-Id: <200812141737.mBEHbukM021475@d12av02.megacenter.de.ibm.com> Received: by tuxmaker.boeblingen.de.ibm.com (sSMTP sendmail emulation); Sun, 14 Dec 2008 18:37:56 +0100 Subject: Re: [RFC] solib for darwin To: gingold@adacore.com (Tristan Gingold) Date: Sun, 14 Dec 2008 17:40:00 -0000 From: "Ulrich Weigand" Cc: gdb-patches@sourceware.org In-Reply-To: from "Tristan Gingold" at Dec 11, 2008 02:12:00 PM MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org X-SW-Source: 2008-12/txt/msg00257.txt.bz2 Tristan Gingold wrote: > > Maybe you can have a look at my patch: > > http://sourceware.org/ml/gdb-patches/2008-09/msg00136.html > > and see whether this would solve your problem as well (or if we can > > come up with a joint approach to solve both problems). > > Ulrich, > > do you have any plan to commit this patch ? As I could base my patch > on it, that would be useful to continue the Darwin port integration. Sorry for the late reply. Thinking about it some more, I'd prefer to use something along your OBJF_KEEPBFD flag; I agree it doesn't really make sense to open a second BFD. The following patch combines the ops->bfd_open callback I need for the Cell debugger with the OBJF_KEEPBFD, and also extracts the bulk of the solib_bfd_open functionality into subroutines that might be re-used by target-specific implementations. Can you verify that this would also allow a Darwin implementation? Bye, Ulrich ChangeLog: * solist.h (struct target_so_ops): New member bfd_open. (solib_find): Add prototype. (solib_bfd_fopen): Add prototype. * solib.c (solib_find, solib_bfd_fopen): New functions, extracted from solib_bfd_open. (solib_bfd_open): Use ops->bfd_open override if present. Call solib_find and solib_bfd_open otherwise. * objfiles.h (OBJF_KEEPBFD): New define. * objfiles.c (free_objfile): Do not close BFD if OBJF_KEEPBFD objfile flag is set. * solib.c (symbol_add_stub): Do not allocate second BFD for shared library; use OBJF_KEEPBFD flag on solib objfile. diff -urNp gdb-orig/gdb/objfiles.c gdb-head/gdb/objfiles.c --- gdb-orig/gdb/objfiles.c 2008-12-06 20:28:59.000000000 +0100 +++ gdb-head/gdb/objfiles.c 2008-12-14 17:52:16.000000000 +0100 @@ -424,7 +424,7 @@ free_objfile (struct objfile *objfile) /* We always close the bfd. */ - if (objfile->obfd != NULL) + if (objfile->obfd != NULL && !(objfile->flags & OBJF_KEEPBFD)) { char *name = bfd_get_filename (objfile->obfd); if (!bfd_close (objfile->obfd)) diff -urNp gdb-orig/gdb/objfiles.h gdb-head/gdb/objfiles.h --- gdb-orig/gdb/objfiles.h 2008-12-06 20:28:59.000000000 +0100 +++ gdb-head/gdb/objfiles.h 2008-12-14 17:52:16.000000000 +0100 @@ -414,6 +414,12 @@ struct objfile #define OBJF_USERLOADED (1 << 3) /* User loaded */ +/* The bfd of this objfile is used outside of the objfile (eg by solib). + Do not try to free it. */ + +#define OBJF_KEEPBFD (1 << 4) /* Do not delete bfd */ + + /* The object file that the main symbol table was loaded from (e.g. the argument to the "symbol-file" or "file" command). */ diff -urNp gdb-orig/gdb/solib.c gdb-head/gdb/solib.c --- gdb-orig/gdb/solib.c 2008-12-06 20:28:59.000000000 +0100 +++ gdb-head/gdb/solib.c 2008-12-14 18:23:14.000000000 +0100 @@ -107,11 +107,11 @@ The search path for loading non-absolute GLOBAL FUNCTION - solib_bfd_open -- Find a shared library file and open BFD for it. + solib_find -- Find a shared library file. SYNOPSIS - struct bfd *solib_open (char *in_pathname); + char *solib_find (char *in_pathname, int *fd); DESCRIPTION @@ -138,17 +138,17 @@ The search path for loading non-absolute RETURNS - BFD file handle for opened solib; throws error on failure. */ + Full pathname of the shared library file, or NULL if not found. + (The pathname is malloc'ed; it needs to be freed by the caller.) + *FD is set to either -1 or an open file handle for the library. */ -bfd * -solib_bfd_open (char *in_pathname) +char * +solib_find (char *in_pathname, int *fd) { struct target_so_ops *ops = solib_ops (target_gdbarch); int found_file = -1; char *temp_pathname = NULL; - char *p = in_pathname; int gdb_sysroot_is_empty; - bfd *abfd; gdb_sysroot_is_empty = (gdb_sysroot == NULL || *gdb_sysroot == 0); @@ -173,24 +173,8 @@ solib_bfd_open (char *in_pathname) /* Handle remote files. */ if (remote_filename_p (temp_pathname)) { - temp_pathname = xstrdup (temp_pathname); - abfd = remote_bfd_open (temp_pathname, gnutarget); - if (!abfd) - { - make_cleanup (xfree, temp_pathname); - error (_("Could not open `%s' as an executable file: %s"), - temp_pathname, bfd_errmsg (bfd_get_error ())); - } - - if (!bfd_check_format (abfd, bfd_object)) - { - bfd_close (abfd); - make_cleanup (xfree, temp_pathname); - error (_("`%s': not in executable format: %s"), - temp_pathname, bfd_errmsg (bfd_get_error ())); - } - - return abfd; + *fd = -1; + return xstrdup (temp_pathname); } /* Now see if we can open it. */ @@ -253,29 +237,79 @@ solib_bfd_open (char *in_pathname) OPF_TRY_CWD_FIRST, in_pathname, O_RDONLY | O_BINARY, 0, &temp_pathname); - /* Done. If still not found, error. */ - if (found_file < 0) - perror_with_name (in_pathname); + *fd = found_file; + return temp_pathname; +} + +/* Open and return a BFD for the shared library PATHNAME. If FD is not -1, + it is used as file handle to open the file. Throws an error if the file + could not be opened. Handles both local and remote file access. + + PATHNAME must be malloc'ed by the caller. If successful, the new BFD's + name will point to it. If unsuccessful, PATHNAME will be freed and the + FD will be closed (unless FD was -1). */ + +bfd * +solib_bfd_fopen (char *pathname, int fd) +{ + bfd *abfd; + + if (remote_filename_p (pathname)) + { + gdb_assert (fd == -1); + abfd = remote_bfd_open (pathname, gnutarget); + } + else + { + abfd = bfd_fopen (pathname, gnutarget, FOPEN_RB, fd); + + if (abfd) + bfd_set_cacheable (abfd, 1); + else if (fd != -1) + close (fd); + } - /* Leave temp_pathname allocated. abfd->name will point to it. */ - abfd = bfd_fopen (temp_pathname, gnutarget, FOPEN_RB, found_file); if (!abfd) { - close (found_file); - make_cleanup (xfree, temp_pathname); + make_cleanup (xfree, pathname); error (_("Could not open `%s' as an executable file: %s"), - temp_pathname, bfd_errmsg (bfd_get_error ())); + pathname, bfd_errmsg (bfd_get_error ())); } + return abfd; +} + +/* Find shared library PATHNAME and open a BFD for it. */ + +bfd * +solib_bfd_open (char *pathname) +{ + struct target_so_ops *ops = solib_ops (target_gdbarch); + char *found_pathname; + int found_file; + bfd *abfd; + + /* Use target-specific override if present. */ + if (ops->bfd_open) + return ops->bfd_open (pathname); + + /* Search for shared library file. */ + found_pathname = solib_find (pathname, &found_file); + if (found_pathname == NULL) + perror_with_name (pathname); + + /* Open bfd for shared library. */ + abfd = solib_bfd_fopen (found_pathname, found_file); + + /* Check bfd format. */ if (!bfd_check_format (abfd, bfd_object)) { bfd_close (abfd); - make_cleanup (xfree, temp_pathname); + make_cleanup (xfree, found_pathname); error (_("`%s': not in executable format: %s"), - temp_pathname, bfd_errmsg (bfd_get_error ())); + found_pathname, bfd_errmsg (bfd_get_error ())); } - bfd_set_cacheable (abfd, 1); return abfd; } @@ -432,8 +466,8 @@ symbol_add_stub (void *arg) sap = build_section_addr_info_from_section_table (so->sections, so->sections_end); - so->objfile = symbol_file_add (so->so_name, so->from_tty, - sap, 0, OBJF_SHARED); + so->objfile = symbol_file_add_from_bfd (so->abfd, so->from_tty, + sap, 0, OBJF_SHARED | OBJF_KEEPBFD); free_section_addr_info (sap); return (1); diff -urNp gdb-orig/gdb/solist.h gdb-head/gdb/solist.h --- gdb-orig/gdb/solist.h 2008-12-06 20:28:59.000000000 +0100 +++ gdb-head/gdb/solist.h 2008-12-14 17:52:16.000000000 +0100 @@ -103,6 +103,9 @@ struct target_so_ops the run time loader */ int (*in_dynsym_resolve_code) (CORE_ADDR pc); + /* Find and open shared library binary file. */ + bfd *(*bfd_open) (char *pathname); + /* Extra hook for finding and opening a solib. Convenience function for remote debuggers finding host libs. */ int (*find_and_open_solib) (char *soname, @@ -126,6 +129,12 @@ void free_so (struct so_list *so); /* Return address of first so_list entry in master shared object list. */ struct so_list *master_so_list (void); +/* Find shared library binary file. */ +extern char *solib_find (char *in_pathname, int *fd); + +/* Open BFD for shared library file. */ +extern bfd *solib_bfd_fopen (char *pathname, int fd); + /* Find solib binary file and open it. */ extern bfd *solib_bfd_open (char *in_pathname); -- Dr. Ulrich Weigand GNU Toolchain for Linux on System z and Cell BE Ulrich.Weigand@de.ibm.com