This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[rfc] Shared libraries in static programs


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  <dan@codesourcery.com>

	* 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);


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]