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]

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



The way this patch decides whether or not to relocate the main
executable seems questionable to me.  It looks like we're basing our
decision on conditions which are suggestive, but not definitive.

We should look at the ABI to see what rules `exec' follows to decide
whether to relocate the main executable, and then make GDB use the
same rules.

At the very least, the test for the ".interp" section should be
explained.



Kevin Buettner <kevinb@cygnus.com> writes:

> 
> 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]