From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 15029 invoked by alias); 12 Apr 2007 22:10:34 -0000 Received: (qmail 15021 invoked by uid 22791); 12 Apr 2007 22:10:33 -0000 X-Spam-Check-By: sourceware.org Received: from return.false.org (HELO return.false.org) (66.207.162.98) by sourceware.org (qpsmtpd/0.31) with ESMTP; Thu, 12 Apr 2007 23:10:29 +0100 Received: from return.false.org (localhost [127.0.0.1]) by return.false.org (Postfix) with ESMTP id 767764B267; Thu, 12 Apr 2007 17:10:27 -0500 (CDT) Received: from caradoc.them.org (dsl093-172-095.pit1.dsl.speakeasy.net [66.93.172.95]) by return.false.org (Postfix) with ESMTP id 0A44E4B262; Thu, 12 Apr 2007 17:10:27 -0500 (CDT) Received: from drow by caradoc.them.org with local (Exim 4.63) (envelope-from ) id 1Hc7Un-0002VW-JM; Thu, 12 Apr 2007 18:10:25 -0400 Date: Thu, 12 Apr 2007 22:10:00 -0000 From: Daniel Jacobowitz To: gdb-patches@sourceware.org, Kevin Buettner Subject: [rfc] Shared libraries in static programs Message-ID: <20070412221025.GA2848@caradoc.them.org> Mail-Followup-To: gdb-patches@sourceware.org, Kevin Buettner MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline User-Agent: Mutt/1.5.15 (2007-04-09) X-IsSubscribed: yes 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: 2007-04/txt/msg00181.txt.bz2 Glibc has a complicated mechanism where a static executable may include a chunk of libdl, for dlopen. If this gets used, then it initializes _r_debug just like normal. There are three differences: - There's no .dynamic, so we can't use DT_DEBUG. - We shouldn't skip the first thing on the list, because the executable is not dynamic and therefore is not on the list. - _dl_debug_state might be in exec_bfd, so we should set a breakpoint there if we can. This patch, lightly tested, lets me get at the shared library I was trying to debug. Does it look OK? -- Daniel Jacobowitz CodeSourcery 2007-04-12 Daniel Jacobowitz * solib-svr4.c (IGNORE_FIRST_LINK_MAP_ENTRY): Do not ignore the first entry for static executables. (breakpoint_addr): Delete unused variable. (elf_locate_base): Search for _r_debug in static executables. (enable_break): Do not set breakpoint_addr. Scan solib_break_names also. Index: solib-svr4.c =================================================================== RCS file: /cvs/src/src/gdb/solib-svr4.c,v retrieving revision 1.63 diff -u -p -r1.63 solib-svr4.c --- solib-svr4.c 10 Apr 2007 11:51:17 -0000 1.63 +++ solib-svr4.c 12 Apr 2007 22:09:00 -0000 @@ -239,12 +239,16 @@ IGNORE_FIRST_LINK_MAP_ENTRY (struct so_l { struct link_map_offsets *lmo = svr4_fetch_link_map_offsets (); + /* Assume that everything is a library if the dynamic loader was loaded + late by a static executable. */ + if (bfd_get_section_by_name (exec_bfd, ".dynamic") == NULL) + return 0; + return extract_typed_address (so->lm_info->lm + lmo->l_prev_offset, builtin_type_void_data_ptr) == 0; } static CORE_ADDR debug_base; /* Base of dynamic linker structures */ -static CORE_ADDR breakpoint_addr; /* Address where end bkpt is set */ /* Validity flag for debug_loader_offset. */ static int debug_loader_offset_p; @@ -387,7 +391,18 @@ elf_locate_base (void) /* Find the start address of the .dynamic section. */ dyninfo_sect = bfd_get_section_by_name (exec_bfd, ".dynamic"); if (dyninfo_sect == NULL) - return 0; + { + /* This may be a static executable. Look for the symbol + conventionally named _r_debug, as a last resort. */ + struct minimal_symbol *msymbol; + + msymbol = lookup_minimal_symbol ("_r_debug", NULL, symfile_objfile); + if (msymbol != NULL) + return SYMBOL_VALUE_ADDRESS (msymbol); + else + return 0; + } + dyninfo_addr = bfd_section_vma (exec_bfd, dyninfo_sect); /* Read in .dynamic section, silently ignore errors. */ @@ -1111,10 +1126,19 @@ enable_break (void) "and track explicitly loaded dynamic code.")); } - /* Scan through the list of symbols, trying to look up the symbol and - set a breakpoint there. Terminate loop when we/if we succeed. */ + /* Scan through the lists of symbols, trying to look up the symbol and + set a breakpoint there. Terminate loop when we/if we succeed. */ + + for (bkpt_namep = solib_break_names; *bkpt_namep != NULL; bkpt_namep++) + { + msymbol = lookup_minimal_symbol (*bkpt_namep, NULL, symfile_objfile); + if ((msymbol != NULL) && (SYMBOL_VALUE_ADDRESS (msymbol) != 0)) + { + create_solib_event_breakpoint (SYMBOL_VALUE_ADDRESS (msymbol)); + return 1; + } + } - breakpoint_addr = 0; for (bkpt_namep = bkpt_names; *bkpt_namep != NULL; bkpt_namep++) { msymbol = lookup_minimal_symbol (*bkpt_namep, NULL, symfile_objfile);