This is the mail archive of the gdb-patches@sources.redhat.com 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]

[PATCH RFA] solib-svr4.c patch for dynamic executables


The patch below is based on some patches from Ulrich Drepper that
were previously posted to this and other forums.

These patches make it possible to debug executables (on Linux and
other SVR4-like systems) in which the program is loaded at an address
different than the one given by the executable's symbolic information.

As indicated in the comments in the patch, it is likely that this code
will only be useful for debugging dynamic linkers since the code makes
sure that there is no .interp section prior to attempting to do any
relocations.  (Though I suppose it's possible that it would work on a
statically linked binary which ended up being relocated for some
reason also.)

I was hoping to arrive at a more generic solution, but after working
on some similar functionality for AIX5, I've concluded that the
mechanisms for determining which sections need to be relocated and by
how much is very much target dependent.  When I compare the code
below with the code that I wrote for AIX5, there seems to be very
little in common aside from the bit about allocating an array
of section_offset structs and then later calling objfile_relocate()
with section_offsets filled in as appropriate.

Anyway... I've done some limited testing of the patch below on
Linux/x86 (Red Hat 6.2 and 7.0) with /lib/ld-linux.so.2 and it
works for me; it's even possible to rerun the program again.
(I wish I could get the dynamic linker to load at a different
locations on subsequent runs; I think this should work, but have
been unable to test it.)  Also, I've asked Ulrich to test these
changes (who better?) and he reports that they work fine for him.

Finally, I've run the gdb testsuite on Linux/x86 and see no
regressions.  (However, someone's changes in the last couple of days
has made the number of FAILs creep up to 16 from 14 on my machine.)

Okay to commit?

	Changes based on patch from Ulrich Drepper:
	* solib-svr4.c (svr4_relocate_main_executable): New function.
	(svr4_solib_create_inferior_hook):  Call
	svr4_relocate_main_executable.

Index: solib-svr4.c
===================================================================
RCS file: /cvs/src/src/gdb/solib-svr4.c,v
retrieving revision 1.2
diff -u -p -r1.2 solib-svr4.c
--- solib-svr4.c	2000/10/30 23:31:17	1.2
+++ solib-svr4.c	2000/11/03 23:22:03
@@ -1437,6 +1437,54 @@ svr4_special_symbol_handling (void)
 #endif /* !SVR4_SHARED_LIBS */
 }
 
+/* Relocate the main executable.  This function should be called
+   upon stopping the inferior process at the entry point to the
+   program.  The entry point from BFD is compared to the PC and
+   if they are different, the main executable is relocated by
+   the proper amount.  
+   
+   This code is somewhat naive in that it assumes that each
+   section needs to be relocated by the same amount.
+
+   Also, as written it will only attempt to relocate executables
+   which lack interpreter sections.   It seems likely that only
+   dynamic linker executables will get relocated.  */
+
+static void
+svr4_relocate_main_executable (void)
+{
+  asection *interp_sect;
+  CORE_ADDR pc = read_pc ();
+
+  interp_sect = bfd_get_section_by_name (exec_bfd, ".interp");
+  if (interp_sect == NULL && bfd_get_start_address (exec_bfd) != pc)
+    {
+      struct cleanup *old_chain;
+      struct section_offsets *new_offsets;
+      int i, changed;
+      CORE_ADDR displacement;
+
+      displacement = pc - bfd_get_start_address (exec_bfd);
+      changed = 0;
+
+      new_offsets = xcalloc (sizeof (struct section_offsets),
+			     symfile_objfile->num_sections);
+      old_chain = make_cleanup (free, new_offsets);
+
+      for (i = 0; i < symfile_objfile->num_sections; i++)
+	{
+	  if (displacement != ANOFFSET (symfile_objfile->section_offsets, i))
+	    changed = 1;
+	  new_offsets->offsets[i] = displacement;
+	}
+
+      if (changed)
+	objfile_relocate (symfile_objfile, new_offsets);
+
+      do_cleanups (old_chain);
+    }
+}
+
 /*
 
    GLOBAL FUNCTION
@@ -1489,9 +1537,12 @@ svr4_special_symbol_handling (void)
    Also, what if child has exit()ed?  Must exit loop somehow.
  */
 
-void
+static void
 svr4_solib_create_inferior_hook (void)
 {
+  /* Relocate the main executable if necessary.  */
+  svr4_relocate_main_executable ();
+
   /* If we are using the BKPT_AT_SYMBOL code, then we don't need the base
      yet.  In fact, in the case of a SunOS4 executable being run on
      Solaris, we can't get it yet.  current_sos will get it when it needs


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